summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap1
-rw-r--r--Documentation/ABI/stable/thermal-notification4
-rw-r--r--Documentation/ABI/testing/pstore35
-rw-r--r--Documentation/ABI/testing/sysfs-bus-rbd83
-rw-r--r--Documentation/ABI/testing/sysfs-class-net-batman-adv14
-rw-r--r--Documentation/ABI/testing/sysfs-class-net-mesh69
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-kone16
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus108
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra18
-rw-r--r--Documentation/ABI/testing/sysfs-fs-pstore7
-rw-r--r--Documentation/ABI/testing/sysfs-platform-asus-laptop16
-rw-r--r--Documentation/ABI/testing/sysfs-platform-eeepc-wmi10
-rw-r--r--Documentation/DocBook/80211.tmpl70
-rw-r--r--Documentation/DocBook/device-drivers.tmpl4
-rw-r--r--Documentation/DocBook/v4l/func-ioctl.xml5
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml4
-rw-r--r--Documentation/IPMI.txt27
-rw-r--r--Documentation/Makefile2
-rw-r--r--Documentation/accounting/getdelays.c1
-rw-r--r--Documentation/acpi/apei/output_format.txt122
-rw-r--r--Documentation/arm/00-INDEX2
-rw-r--r--Documentation/arm/OMAP/omap_pm25
-rw-r--r--Documentation/arm/swp_emulation27
-rw-r--r--Documentation/cgroups/blkio-controller.txt27
-rw-r--r--Documentation/coccinelle.txt4
-rw-r--r--Documentation/dontdiff26
-rw-r--r--Documentation/driver-model/interface.txt129
-rw-r--r--Documentation/dvb/lmedm04.txt2
-rw-r--r--Documentation/feature-removal-schedule.txt60
-rw-r--r--Documentation/filesystems/Locking251
-rw-r--r--Documentation/filesystems/dentry-locking.txt174
-rw-r--r--Documentation/filesystems/path-lookup.txt294
-rw-r--r--Documentation/filesystems/porting66
-rw-r--r--Documentation/filesystems/vfs.txt96
-rw-r--r--Documentation/hwmon/adm92402
-rw-r--r--Documentation/hwmon/ads78282
-rw-r--r--Documentation/hwmon/ds62023
-rw-r--r--Documentation/hwmon/sysfs-interface40
-rw-r--r--Documentation/hwmon/w83627hf22
-rw-r--r--Documentation/hwmon/w837932
-rw-r--r--Documentation/i2c/muxes/gpio-i2cmux65
-rw-r--r--Documentation/input/cma3000_d0x.txt115
-rw-r--r--Documentation/input/multi-touch-protocol.txt53
-rw-r--r--Documentation/ioctl/ioctl-number.txt6
-rw-r--r--Documentation/kbuild/kbuild.txt8
-rw-r--r--Documentation/kbuild/kconfig-language.txt7
-rw-r--r--Documentation/kernel-docs.txt27
-rw-r--r--Documentation/kernel-parameters.txt18
-rw-r--r--Documentation/kvm/api.txt178
-rw-r--r--Documentation/kvm/cpuid.txt3
-rw-r--r--Documentation/kvm/msr.txt36
-rw-r--r--Documentation/lguest/lguest.c73
-rw-r--r--Documentation/lguest/lguest.txt5
-rw-r--r--Documentation/make/headers_install.txt5
-rw-r--r--Documentation/networking/LICENSE.qlcnic327
-rw-r--r--Documentation/networking/batman-adv.txt240
-rw-r--r--Documentation/networking/dccp.txt20
-rw-r--r--Documentation/networking/e100.txt19
-rw-r--r--Documentation/networking/e1000.txt16
-rw-r--r--Documentation/networking/e1000e.txt52
-rw-r--r--Documentation/networking/igb.txt35
-rw-r--r--Documentation/networking/igbvf.txt6
-rw-r--r--Documentation/networking/ip-sysctl.txt28
-rw-r--r--Documentation/networking/ixgb.txt10
-rw-r--r--Documentation/networking/ixgbe.txt213
-rw-r--r--Documentation/networking/ixgbevf.txt4
-rw-r--r--Documentation/networking/stmmac.txt48
-rw-r--r--Documentation/power/runtime_pm.txt4
-rw-r--r--Documentation/powerpc/booting-without-of.txt4
-rw-r--r--Documentation/powerpc/dts-bindings/4xx/cpm.txt52
-rw-r--r--Documentation/scsi/ChangeLog.megaraid_sas22
-rw-r--r--Documentation/scsi/scsi_mid_low_api.txt59
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt12
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt1
-rw-r--r--Documentation/thermal/sysfs-api.txt12
-rw-r--r--Documentation/trace/postprocess/trace-vmscan-postprocess.pl11
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx6
-rw-r--r--Documentation/video4linux/CARDLIST.saa71342
-rw-r--r--Documentation/video4linux/Makefile8
-rw-r--r--Documentation/video4linux/README.cpia191
-rw-r--r--Documentation/video4linux/Zoran74
-rw-r--r--Documentation/video4linux/bttv/Cards4
-rw-r--r--Documentation/video4linux/gspca.txt1
-rw-r--r--Documentation/video4linux/meye.txt10
-rw-r--r--Documentation/video4linux/v4lgrab.c201
-rw-r--r--Documentation/video4linux/videobuf7
-rw-r--r--MAINTAINERS111
-rw-r--r--Makefile3
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/arm/Kconfig142
-rw-r--r--arch/arm/Kconfig.debug4
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boot/Makefile5
-rw-r--r--arch/arm/boot/bootp/init.S2
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-shmobile.S53
-rw-r--r--arch/arm/boot/compressed/head.S13
-rw-r--r--arch/arm/common/Kconfig4
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/dmabounce.c16
-rw-r--r--arch/arm/common/gic.c107
-rw-r--r--arch/arm/common/it8152.c1
-rw-r--r--arch/arm/common/timer-sp.c (renamed from arch/arm/plat-versatile/timer-sp.c)8
-rw-r--r--arch/arm/configs/ag5evm_defconfig83
-rw-r--r--arch/arm/configs/ams_delta_defconfig121
-rw-r--r--arch/arm/configs/at91rm9200_defconfig341
-rw-r--r--arch/arm/configs/at91rm9200dk_defconfig72
-rw-r--r--arch/arm/configs/at91rm9200ek_defconfig73
-rw-r--r--arch/arm/configs/ateb9200_defconfig131
-rw-r--r--arch/arm/configs/carmeva_defconfig47
-rw-r--r--arch/arm/configs/cpuat91_defconfig112
-rw-r--r--arch/arm/configs/csb337_defconfig104
-rw-r--r--arch/arm/configs/csb637_defconfig98
-rw-r--r--arch/arm/configs/ecbat91_defconfig99
-rw-r--r--arch/arm/configs/htcherald_defconfig73
-rw-r--r--arch/arm/configs/kafa_defconfig61
-rw-r--r--arch/arm/configs/kb9202_defconfig127
-rw-r--r--arch/arm/configs/mackerel_defconfig138
-rw-r--r--arch/arm/configs/mx3_defconfig1
-rw-r--r--arch/arm/configs/n770_defconfig138
-rw-r--r--arch/arm/configs/omap1_defconfig286
-rw-r--r--arch/arm/configs/omap_generic_1510_defconfig84
-rw-r--r--arch/arm/configs/omap_generic_1610_defconfig87
-rw-r--r--arch/arm/configs/omap_generic_1710_defconfig75
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig109
-rw-r--r--arch/arm/configs/omap_innovator_1510_defconfig102
-rw-r--r--arch/arm/configs/omap_innovator_1610_defconfig58
-rw-r--r--arch/arm/configs/omap_osk_5912_defconfig87
-rw-r--r--arch/arm/configs/omap_perseus2_730_defconfig65
-rw-r--r--arch/arm/configs/onearm_defconfig80
-rw-r--r--arch/arm/configs/palmte_defconfig48
-rw-r--r--arch/arm/configs/palmtt_defconfig56
-rw-r--r--arch/arm/configs/palmz71_defconfig53
-rw-r--r--arch/arm/configs/picotux200_defconfig242
-rw-r--r--arch/arm/configs/sx1_defconfig110
-rw-r--r--arch/arm/configs/yl9200_defconfig137
-rw-r--r--arch/arm/include/asm/assembler.h35
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/clkdev.h22
-rw-r--r--arch/arm/include/asm/dma-mapping.h93
-rw-r--r--arch/arm/include/asm/domain.h31
-rw-r--r--arch/arm/include/asm/elf.h2
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S44
-rw-r--r--arch/arm/include/asm/futex.h9
-rw-r--r--arch/arm/include/asm/hardirq.h18
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h12
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-gic.S75
-rw-r--r--arch/arm/include/asm/hardware/gic.h7
-rw-r--r--arch/arm/include/asm/hardware/it8152.h1
-rw-r--r--arch/arm/include/asm/hardware/timer-sp.h (renamed from arch/arm/plat-versatile/include/plat/timer-sp.h)0
-rw-r--r--arch/arm/include/asm/highmem.h3
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h4
-rw-r--r--arch/arm/include/asm/io.h13
-rw-r--r--arch/arm/include/asm/kexec.h18
-rw-r--r--arch/arm/include/asm/localtimer.h12
-rw-r--r--arch/arm/include/asm/mach/arch.h9
-rw-r--r--arch/arm/include/asm/mach/irq.h8
-rw-r--r--arch/arm/include/asm/mach/time.h1
-rw-r--r--arch/arm/include/asm/module.h15
-rw-r--r--arch/arm/include/asm/page.h6
-rw-r--r--arch/arm/include/asm/pgalloc.h52
-rw-r--r--arch/arm/include/asm/pgtable.h321
-rw-r--r--arch/arm/include/asm/sched_clock.h118
-rw-r--r--arch/arm/include/asm/sizes.h6
-rw-r--r--arch/arm/include/asm/smp.h17
-rw-r--r--arch/arm/include/asm/smp_mpidr.h17
-rw-r--r--arch/arm/include/asm/smp_twd.h1
-rw-r--r--arch/arm/include/asm/system.h13
-rw-r--r--arch/arm/include/asm/tlb.h1
-rw-r--r--arch/arm/include/asm/traps.h25
-rw-r--r--arch/arm/include/asm/uaccess.h16
-rw-r--r--arch/arm/kernel/Makefile9
-rw-r--r--arch/arm/kernel/entry-armv.S58
-rw-r--r--arch/arm/kernel/entry-common.S208
-rw-r--r--arch/arm/kernel/entry-header.S19
-rw-r--r--arch/arm/kernel/fiq.c10
-rw-r--r--arch/arm/kernel/ftrace.c103
-rw-r--r--arch/arm/kernel/head.S57
-rw-r--r--arch/arm/kernel/hw_breakpoint.c543
-rw-r--r--arch/arm/kernel/irq.c34
-rw-r--r--arch/arm/kernel/iwmmxt.S55
-rw-r--r--arch/arm/kernel/machine_kexec.c30
-rw-r--r--arch/arm/kernel/module.c109
-rw-r--r--arch/arm/kernel/perf_event.c2466
-rw-r--r--arch/arm/kernel/perf_event_v6.c672
-rw-r--r--arch/arm/kernel/perf_event_v7.c906
-rw-r--r--arch/arm/kernel/perf_event_xscale.c807
-rw-r--r--arch/arm/kernel/pj4-cp0.c94
-rw-r--r--arch/arm/kernel/ptrace.c4
-rw-r--r--arch/arm/kernel/relocate_kernel.S2
-rw-r--r--arch/arm/kernel/sched_clock.c69
-rw-r--r--arch/arm/kernel/setup.c37
-rw-r--r--arch/arm/kernel/smp.c449
-rw-r--r--arch/arm/kernel/smp_tlb.c139
-rw-r--r--arch/arm/kernel/smp_twd.c17
-rw-r--r--arch/arm/kernel/swp_emulate.c267
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c26
-rw-r--r--arch/arm/kernel/vmlinux.lds.S2
-rw-r--r--arch/arm/lib/getuser.S13
-rw-r--r--arch/arm/lib/putuser.S29
-rw-r--r--arch/arm/lib/uaccess.S83
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c7
-rw-r--r--arch/arm/mach-at91/Makefile6
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c45
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c4
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c4
-rw-r--r--arch/arm/mach-at91/board-1arm.c26
-rw-r--r--arch/arm/mach-at91/board-kafa.c21
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c98
-rw-r--r--arch/arm/mach-at91/board-picotux200.c53
-rw-r--r--arch/arm/mach-at91/board-rm9200dk.c (renamed from arch/arm/mach-at91/board-dk.c)4
-rw-r--r--arch/arm/mach-at91/board-rm9200ek.c (renamed from arch/arm/mach-at91/board-ek.c)4
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c82
-rw-r--r--arch/arm/mach-at91/board-yl-9200.c2
-rw-r--r--arch/arm/mach-at91/clock.c2
-rw-r--r--arch/arm/mach-at91/include/mach/board.h6
-rw-r--r--arch/arm/mach-at91/include/mach/stamp9g20.h7
-rw-r--r--arch/arm/mach-bcmring/clock.c3
-rw-r--r--arch/arm/mach-bcmring/core.c16
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig1
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c54
-rw-r--r--arch/arm/mach-cns3xxx/core.c7
-rw-r--r--arch/arm/mach-cns3xxx/core.h3
-rw-r--r--arch/arm/mach-cns3xxx/devices.c1
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/cns3xxx.h2
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/entry-macro.S66
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/pm.h23
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c2
-rw-r--r--arch/arm/mach-cns3xxx/pm.c23
-rw-r--r--arch/arm/mach-davinci/Kconfig19
-rw-r--r--arch/arm/mach-davinci/aemif.c2
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c339
-rw-r--r--arch/arm/mach-davinci/clock.c4
-rw-r--r--arch/arm/mach-davinci/clock.h2
-rw-r--r--arch/arm/mach-davinci/da850.c75
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c15
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h7
-rw-r--r--arch/arm/mach-davinci/include/mach/io.h4
-rw-r--r--arch/arm/mach-davinci/psc.c13
-rw-r--r--arch/arm/mach-davinci/time.c31
-rw-r--r--arch/arm/mach-davinci/tnetv107x.c23
-rw-r--r--arch/arm/mach-dove/Kconfig6
-rw-r--r--arch/arm/mach-dove/Makefile3
-rw-r--r--arch/arm/mach-dove/cm-a510.c95
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h9
-rw-r--r--arch/arm/mach-dove/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-dove/mpp.c212
-rw-r--r--arch/arm/mach-dove/mpp.h220
-rw-r--r--arch/arm/mach-ep93xx/clock.c2
-rw-r--r--arch/arm/mach-imx/Kconfig138
-rw-r--r--arch/arm/mach-imx/Makefile8
-rw-r--r--arch/arm/mach-imx/Makefile.boot4
-rw-r--r--arch/arm/mach-imx/clock-imx1.c3
-rw-r--r--arch/arm/mach-imx/clock-imx21.c4
-rw-r--r--arch/arm/mach-imx/clock-imx25.c (renamed from arch/arm/mach-mx25/clock.c)5
-rw-r--r--arch/arm/mach-imx/clock-imx27.c26
-rw-r--r--arch/arm/mach-imx/cpu-imx27.c14
-rw-r--r--arch/arm/mach-imx/devices-imx21.h24
-rw-r--r--arch/arm/mach-imx/devices-imx25.h (renamed from arch/arm/mach-mx25/devices-imx25.h)51
-rw-r--r--arch/arm/mach-imx/devices-imx27.h35
-rw-r--r--arch/arm/mach-imx/devices.c553
-rw-r--r--arch/arm/mach-imx/devices.h29
-rw-r--r--arch/arm/mach-imx/dma-v1.c4
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c17
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c (renamed from arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c)10
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c21
-rw-r--r--arch/arm/mach-imx/mach-eukrea_cpuimx25.c (renamed from arch/arm/mach-mx25/mach-cpuimx25.c)19
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c12
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c1
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c1
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c20
-rw-r--r--arch/arm/mach-imx/mach-mx25_3ds.c (renamed from arch/arm/mach-mx25/mach-mx25_3ds.c)34
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c160
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c17
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c11
-rw-r--r--arch/arm/mach-imx/mach-pca100.c33
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c12
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c1
-rw-r--r--arch/arm/mach-imx/mm-imx1.c7
-rw-r--r--arch/arm/mach-imx/mm-imx21.c21
-rw-r--r--arch/arm/mach-imx/mm-imx25.c (renamed from arch/arm/mach-mx25/mm.c)27
-rw-r--r--arch/arm/mach-imx/mm-imx27.c21
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c12
-rw-r--r--arch/arm/mach-imx/pm-imx27.c3
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/core.c3
-rw-r--r--arch/arm/mach-integrator/impd1.c3
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c4
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c5
-rw-r--r--arch/arm/mach-iop13xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h6
-rw-r--r--arch/arm/mach-iop32x/include/mach/io.h4
-rw-r--r--arch/arm/mach-iop33x/include/mach/io.h4
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c35
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-kirkwood/Kconfig12
-rw-r--r--arch/arm/mach-kirkwood/include/mach/io.h4
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/ts219-setup.c16
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c9
-rw-r--r--arch/arm/mach-ks8695/Kconfig1
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h8
-rw-r--r--arch/arm/mach-lpc32xx/clock.c3
-rw-r--r--arch/arm/mach-lpc32xx/timer.c5
-rw-r--r--arch/arm/mach-mmp/Kconfig22
-rw-r--r--arch/arm/mach-mmp/Makefile1
-rw-r--r--arch/arm/mach-mmp/brownstone.c204
-rw-r--r--arch/arm/mach-mmp/clock.h2
-rw-r--r--arch/arm/mach-mmp/flint.c2
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-mmp2.h338
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h22
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apmu.h2
-rw-r--r--arch/arm/mach-mmp/jasper.c35
-rw-r--r--arch/arm/mach-mmp/mmp2.c36
-rw-r--r--arch/arm/mach-mmp/pxa910.c2
-rw-r--r--arch/arm/mach-mmp/time.c39
-rw-r--r--arch/arm/mach-msm/Kconfig10
-rw-r--r--arch/arm/mach-msm/Makefile5
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c20
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c7
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c19
-rw-r--r--arch/arm/mach-msm/board-trout-gpio.c8
-rw-r--r--arch/arm/mach-msm/board-trout-panel.c297
-rw-r--r--arch/arm/mach-msm/clock.c15
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c69
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c72
-rw-r--r--arch/arm/mach-msm/devices-msm8x60-iommu.c243
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c71
-rw-r--r--arch/arm/mach-msm/devices.h6
-rw-r--r--arch/arm/mach-msm/gpio-v2.c426
-rw-r--r--arch/arm/mach-msm/include/mach/iommu.h15
-rw-r--r--arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h22
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x60.h7
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x30.h3
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x60.h3
-rw-r--r--arch/arm/mach-msm/include/mach/smp.h4
-rw-r--r--arch/arm/mach-msm/io.c1
-rw-r--r--arch/arm/mach-msm/iommu.c146
-rw-r--r--arch/arm/mach-msm/iommu_dev.c4
-rw-r--r--arch/arm/mach-msm/sirc.c3
-rw-r--r--arch/arm/mach-msm/smd.c17
-rw-r--r--arch/arm/mach-msm/smd_debug.c2
-rw-r--r--arch/arm/mach-msm/timer.c5
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h2
-rw-r--r--arch/arm/mach-mx25/Kconfig34
-rw-r--r--arch/arm/mach-mx25/Makefile5
-rw-r--r--arch/arm/mach-mx25/Makefile.boot3
-rw-r--r--arch/arm/mach-mx25/devices.c308
-rw-r--r--arch/arm/mach-mx25/devices.h13
-rw-r--r--arch/arm/mach-mx3/Kconfig84
-rw-r--r--arch/arm/mach-mx3/Makefile7
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c6
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c5
-rw-r--r--arch/arm/mach-mx3/cpu.c31
-rw-r--r--arch/arm/mach-mx3/devices-imx31.h27
-rw-r--r--arch/arm/mach-mx3/devices-imx35.h41
-rw-r--r--arch/arm/mach-mx3/devices.c271
-rw-r--r--arch/arm/mach-mx3/devices.h10
-rw-r--r--arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c4
-rw-r--r--arch/arm/mach-mx3/mach-armadillo5x0.c14
-rw-r--r--arch/arm/mach-mx3/mach-cpuimx35.c22
-rw-r--r--arch/arm/mach-mx3/mach-kzm_arm11_01.c6
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c124
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c9
-rw-r--r--arch/arm/mach-mx3/mach-mx31lite.c5
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c20
-rw-r--r--arch/arm/mach-mx3/mach-mx35_3ds.c40
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c23
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c48
-rw-r--r--arch/arm/mach-mx3/mm.c84
-rw-r--r--arch/arm/mach-mx3/mx31lilly-db.c5
-rw-r--r--arch/arm/mach-mx3/mx31lite-db.c8
-rw-r--r--arch/arm/mach-mx3/mx31moboard-devboard.c20
-rw-r--r--arch/arm/mach-mx3/mx31moboard-marxbot.c21
-rw-r--r--arch/arm/mach-mx3/mx31moboard-smartbot.c16
-rw-r--r--arch/arm/mach-mx5/Kconfig63
-rw-r--r--arch/arm/mach-mx5/Makefile5
-rw-r--r--arch/arm/mach-mx5/Makefile.boot12
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51.c32
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51sd.c68
-rw-r--r--arch/arm/mach-mx5/board-mx50_rdp.c197
-rw-r--r--arch/arm/mach-mx5/board-mx51_3ds.c9
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c101
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c247
-rw-r--r--arch/arm/mach-mx5/board-mx53_evk.c84
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c (renamed from arch/arm/mach-mx5/clock-mx51.c)298
-rw-r--r--arch/arm/mach-mx5/cpu.c118
-rw-r--r--arch/arm/mach-mx5/crm_regs.h10
-rw-r--r--arch/arm/mach-mx5/devices-imx51.h11
-rw-r--r--arch/arm/mach-mx5/devices-imx53.h13
-rw-r--r--arch/arm/mach-mx5/devices-mx50.h26
-rw-r--r--arch/arm/mach-mx5/devices.c51
-rw-r--r--arch/arm/mach-mx5/devices.h2
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c26
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c17
-rw-r--r--arch/arm/mach-mx5/mm-mx50.c59
-rw-r--r--arch/arm/mach-mx5/mm.c75
-rw-r--r--arch/arm/mach-mxc91231/clock.c2
-rw-r--r--arch/arm/mach-mxc91231/mm.c53
-rw-r--r--arch/arm/mach-mxs/Kconfig34
-rw-r--r--arch/arm/mach-mxs/Makefile10
-rw-r--r--arch/arm/mach-mxs/Makefile.boot1
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c526
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c734
-rw-r--r--arch/arm/mach-mxs/clock.c200
-rw-r--r--arch/arm/mach-mxs/devices-mx23.h16
-rw-r--r--arch/arm/mach-mxs/devices-mx28.h20
-rw-r--r--arch/arm/mach-mxs/devices.c75
-rw-r--r--arch/arm/mach-mxs/devices/Kconfig5
-rw-r--r--arch/arm/mach-mxs/devices/Makefile2
-rw-r--r--arch/arm/mach-mxs/devices/platform-duart.c48
-rw-r--r--arch/arm/mach-mxs/devices/platform-fec.c50
-rw-r--r--arch/arm/mach-mxs/gpio.c325
-rw-r--r--arch/arm/mach-mxs/gpio.h34
-rw-r--r--arch/arm/mach-mxs/icoll.c81
-rw-r--r--arch/arm/mach-mxs/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-mxs/include/mach/clock.h64
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h31
-rw-r--r--arch/arm/mach-mxs/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h46
-rw-r--r--arch/arm/mach-mxs/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-mxs/include/mach/gpio.h35
-rw-r--r--arch/arm/mach-mxs/include/mach/hardware.h29
-rw-r--r--arch/arm/mach-mxs/include/mach/io.h22
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux-mx23.h355
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux-mx28.h537
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux.h165
-rw-r--r--arch/arm/mach-mxs/include/mach/irqs.h32
-rw-r--r--arch/arm/mach-mxs/include/mach/memory.h24
-rw-r--r--arch/arm/mach-mxs/include/mach/mx23.h145
-rw-r--r--arch/arm/mach-mxs/include/mach/mx28.h188
-rw-r--r--arch/arm/mach-mxs/include/mach/mxs.h105
-rw-r--r--arch/arm/mach-mxs/include/mach/system.h27
-rw-r--r--arch/arm/mach-mxs/include/mach/timex.h21
-rw-r--r--arch/arm/mach-mxs/include/mach/uncompress.h76
-rw-r--r--arch/arm/mach-mxs/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-mxs/iomux.c101
-rw-r--r--arch/arm/mach-mxs/mach-mx23evk.c57
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c138
-rw-r--r--arch/arm/mach-mxs/mm-mx23.c45
-rw-r--r--arch/arm/mach-mxs/mm-mx28.c45
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx23.h455
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx28.h663
-rw-r--r--arch/arm/mach-mxs/system.c137
-rw-r--r--arch/arm/mach-mxs/timer.c296
-rw-r--r--arch/arm/mach-netx/time.c5
-rw-r--r--arch/arm/mach-nomadik/clock.c2
-rw-r--r--arch/arm/mach-ns9xxx/time-ns9360.c6
-rw-r--r--arch/arm/mach-nuc93x/clock.h2
-rw-r--r--arch/arm/mach-omap1/Kconfig11
-rw-r--r--arch/arm/mach-omap1/Makefile12
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c137
-rw-r--r--arch/arm/mach-omap1/board-fsample.c89
-rw-r--r--arch/arm/mach-omap1/board-h2.c79
-rw-r--r--arch/arm/mach-omap1/board-h3.c97
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c102
-rw-r--r--arch/arm/mach-omap1/board-innovator.c32
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c30
-rw-r--r--arch/arm/mach-omap1/board-osk.c27
-rw-r--r--arch/arm/mach-omap1/board-palmte.c29
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c28
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c31
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c91
-rw-r--r--arch/arm/mach-omap1/board-sx1.c58
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c7
-rw-r--r--arch/arm/mach-omap1/clock.c2
-rw-r--r--arch/arm/mach-omap1/clock_data.c27
-rw-r--r--arch/arm/mach-omap1/devices.c4
-rw-r--r--arch/arm/mach-omap1/dma.c390
-rw-r--r--arch/arm/mach-omap1/flash.c1
-rw-r--r--arch/arm/mach-omap1/fpga.c10
-rw-r--r--arch/arm/mach-omap1/gpio15xx.c99
-rw-r--r--arch/arm/mach-omap1/gpio16xx.c200
-rw-r--r--arch/arm/mach-omap1/gpio7xx.c262
-rw-r--r--arch/arm/mach-omap1/include/mach/entry-macro.S27
-rw-r--r--arch/arm/mach-omap1/io.c39
-rw-r--r--arch/arm/mach-omap1/irq.c5
-rw-r--r--arch/arm/mach-omap1/lcd_dma.c3
-rw-r--r--arch/arm/mach-omap1/leds.c3
-rw-r--r--arch/arm/mach-omap1/mailbox.c5
-rw-r--r--arch/arm/mach-omap1/mcbsp.c5
-rw-r--r--arch/arm/mach-omap1/mux.c2
-rw-r--r--arch/arm/mach-omap1/pm.c3
-rw-r--r--arch/arm/mach-omap1/pm_bus.c4
-rw-r--r--arch/arm/mach-omap1/serial.c11
-rw-r--r--arch/arm/mach-omap1/time.c7
-rw-r--r--arch/arm/mach-omap2/Kconfig34
-rw-r--r--arch/arm/mach-omap2/Makefile83
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c8
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c6
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c8
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c45
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c116
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c7
-rw-r--r--arch/arm/mach-omap2/board-apollon.c10
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c15
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c4
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c14
-rw-r--r--arch/arm/mach-omap2/board-generic.c3
-rw-r--r--arch/arm/mach-omap2/board-h4.c71
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c124
-rw-r--r--arch/arm/mach-omap2/board-igep0030.c7
-rw-r--r--arch/arm/mach-omap2/board-ldp.c8
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c70
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c8
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c42
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c8
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c22
-rw-r--r--arch/arm/mach-omap2/board-overo.c8
-rw-r--r--arch/arm/mach-omap2/board-rm680.c187
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c77
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c9
-rw-r--r--arch/arm/mach-omap2/board-rx51.c10
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c4
-rw-r--r--arch/arm/mach-omap2/board-zoom.c (renamed from arch/arm/mach-omap2/board-zoom3.c)102
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c117
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c12
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c10
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_osc.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_sys.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c14
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c1
-rw-r--r--arch/arm/mach-omap2/clock.c6
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c14
-rw-r--r--arch/arm/mach-omap2/clock2430.c2
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c14
-rw-r--r--arch/arm/mach-omap2/clock34xx.c2
-rw-r--r--arch/arm/mach-omap2/clock3517.c2
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c6
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c230
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c690
-rw-r--r--arch/arm/mach-omap2/clockdomain.c220
-rw-r--r--arch/arm/mach-omap2/clockdomain.h (renamed from arch/arm/plat-omap/include/plat/clockdomain.h)40
-rw-r--r--arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c (renamed from arch/arm/mach-omap2/clockdomains.h)109
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c (renamed from arch/arm/mach-omap2/clockdomains44xx.h)169
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h11
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h13
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h3
-rw-r--r--arch/arm/mach-omap2/cm.c68
-rw-r--r--arch/arm/mach-omap2/cm.h137
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h261
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h508
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c471
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h147
-rw-r--r--arch/arm/mach-omap2/cm44xx.c52
-rw-r--r--arch/arm/mach-omap2/cm44xx.h668
-rw-r--r--arch/arm/mach-omap2/cm4xxx.c62
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c214
-rw-r--r--arch/arm/mach-omap2/cminst44xx.h31
-rw-r--r--arch/arm/mach-omap2/control.c133
-rw-r--r--arch/arm/mach-omap2/control.h42
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c40
-rw-r--r--arch/arm/mach-omap2/devices.c108
-rw-r--r--arch/arm/mach-omap2/dma.c297
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c59
-rw-r--r--arch/arm/mach-omap2/dsp.c23
-rw-r--r--arch/arm/mach-omap2/gpio.c104
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c2
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c19
-rw-r--r--arch/arm/mach-omap2/gpmc.c12
-rw-r--r--arch/arm/mach-omap2/include/mach/entry-macro.S137
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h1
-rw-r--r--arch/arm/mach-omap2/io.c143
-rw-r--r--arch/arm/mach-omap2/irq.c5
-rw-r--r--arch/arm/mach-omap2/mailbox.c19
-rw-r--r--arch/arm/mach-omap2/mux.c525
-rw-r--r--arch/arm/mach-omap2/mux.h154
-rw-r--r--arch/arm/mach-omap2/mux2420.c10
-rw-r--r--arch/arm/mach-omap2/mux2430.c10
-rw-r--r--arch/arm/mach-omap2/mux34xx.c9
-rw-r--r--arch/arm/mach-omap2/mux44xx.c1625
-rw-r--r--arch/arm/mach-omap2/mux44xx.h298
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c14
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c10
-rw-r--r--arch/arm/mach-omap2/omap-smp.c68
-rw-r--r--arch/arm/mach-omap2/omap4-common.c41
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c483
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c465
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c519
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c870
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c1514
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h72
-rw-r--r--arch/arm/mach-omap2/omap_twl.c277
-rw-r--r--arch/arm/mach-omap2/opp.c93
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c107
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c57
-rw-r--r--arch/arm/mach-omap2/pm-debug.c55
-rw-r--r--arch/arm/mach-omap2/pm.c144
-rw-r--r--arch/arm/mach-omap2/pm.h59
-rw-r--r--arch/arm/mach-omap2/pm24xx.c240
-rw-r--r--arch/arm/mach-omap2/pm34xx.c263
-rw-r--r--arch/arm/mach-omap2/pm44xx.c18
-rw-r--r--arch/arm/mach-omap2/powerdomain-common.c110
-rw-r--r--arch/arm/mach-omap2/powerdomain.c441
-rw-r--r--arch/arm/mach-omap2/powerdomain.h (renamed from arch/arm/plat-omap/include/plat/powerdomain.h)84
-rw-r--r--arch/arm/mach-omap2/powerdomain2xxx_3xxx.c242
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c225
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c (renamed from arch/arm/mach-omap2/powerdomains.h)84
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h22
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c (renamed from arch/arm/mach-omap2/powerdomains24xx.h)48
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c (renamed from arch/arm/mach-omap2/powerdomains34xx.h)56
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c (renamed from arch/arm/mach-omap2/powerdomains44xx.h)92
-rw-r--r--arch/arm/mach-omap2/prcm-common.h96
-rw-r--r--arch/arm/mach-omap2/prcm.c556
-rw-r--r--arch/arm/mach-omap2/prcm44xx.h42
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.c45
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.h104
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h2
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h11
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h2
-rw-r--r--arch/arm/mach-omap2/prm.h369
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c64
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h367
-rw-r--r--arch/arm/mach-omap2/prm44xx.c81
-rw-r--r--arch/arm/mach-omap2/prm44xx.h766
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c66
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h25
-rw-r--r--arch/arm/mach-omap2/scrm44xx.h175
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.c (renamed from arch/arm/mach-omap2/board-rx51-sdram.c)102
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.h12
-rw-r--r--arch/arm/mach-omap2/sdrc.c2
-rw-r--r--arch/arm/mach-omap2/sdrc.h1
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c6
-rw-r--r--arch/arm/mach-omap2/serial.c69
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S836
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c59
-rw-r--r--arch/arm/mach-omap2/smartreflex.c1029
-rw-r--r--arch/arm/mach-omap2/sr_device.c146
-rw-r--r--arch/arm/mach-omap2/sram242x.S10
-rw-r--r--arch/arm/mach-omap2/sram243x.S10
-rw-r--r--arch/arm/mach-omap2/sram34xx.S8
-rw-r--r--arch/arm/mach-omap2/timer-gp.c8
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c5
-rw-r--r--arch/arm/mach-omap2/voltage.c1571
-rw-r--r--arch/arm/mach-omap2/wd_timer.c54
-rw-r--r--arch/arm/mach-omap2/wd_timer.h17
-rw-r--r--arch/arm/mach-orion5x/Kconfig7
-rw-r--r--arch/arm/mach-orion5x/Makefile1
-rw-r--r--arch/arm/mach-orion5x/include/mach/io.h4
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c327
-rw-r--r--arch/arm/mach-pnx4008/clock.c3
-rw-r--r--arch/arm/mach-pxa/Kconfig26
-rw-r--r--arch/arm/mach-pxa/Makefile10
-rw-r--r--arch/arm/mach-pxa/balloon3.c59
-rw-r--r--arch/arm/mach-pxa/capc7117.c2
-rw-r--r--arch/arm/mach-pxa/clock-pxa2xx.c64
-rw-r--r--arch/arm/mach-pxa/clock-pxa3xx.c218
-rw-r--r--arch/arm/mach-pxa/clock.c29
-rw-r--r--arch/arm/mach-pxa/clock.h49
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c26
-rw-r--r--arch/arm/mach-pxa/cm-x300.c2
-rw-r--r--arch/arm/mach-pxa/colibri-evalboard.c (renamed from arch/arm/mach-pxa/colibri-pxa270-evalboard.c)96
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270-income.c47
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c108
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c73
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c139
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c49
-rw-r--r--arch/arm/mach-pxa/corgi.c6
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c10
-rw-r--r--arch/arm/mach-pxa/csb726.c9
-rw-r--r--arch/arm/mach-pxa/devices.c247
-rw-r--r--arch/arm/mach-pxa/em-x270.c4
-rw-r--r--arch/arm/mach-pxa/eseries.c12
-rw-r--r--arch/arm/mach-pxa/ezx.c12
-rw-r--r--arch/arm/mach-pxa/generic.c48
-rw-r--r--arch/arm/mach-pxa/generic.h11
-rw-r--r--arch/arm/mach-pxa/gumstix.c2
-rw-r--r--arch/arm/mach-pxa/h5000.c11
-rw-r--r--arch/arm/mach-pxa/himalaya.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c2
-rw-r--r--arch/arm/mach-pxa/icontrol.c2
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/addr-map.h48
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h6
-rw-r--r--arch/arm/mach-pxa/include/mach/colibri.h14
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h47
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h48
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-regs.h66
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-regs.h9
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-intc.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/smemc.h74
-rw-r--r--arch/arm/mach-pxa/irq.c129
-rw-r--r--arch/arm/mach-pxa/littleton.c2
-rw-r--r--arch/arm/mach-pxa/lpd270.c5
-rw-r--r--arch/arm/mach-pxa/lubbock.c5
-rw-r--r--arch/arm/mach-pxa/magician.c2
-rw-r--r--arch/arm/mach-pxa/mainstone.c5
-rw-r--r--arch/arm/mach-pxa/mioa701.c2
-rw-r--r--arch/arm/mach-pxa/mp900.c2
-rw-r--r--arch/arm/mach-pxa/palmld.c2
-rw-r--r--arch/arm/mach-pxa/palmt5.c2
-rw-r--r--arch/arm/mach-pxa/palmtc.c190
-rw-r--r--arch/arm/mach-pxa/palmte2.c2
-rw-r--r--arch/arm/mach-pxa/palmtreo.c4
-rw-r--r--arch/arm/mach-pxa/palmtx.c5
-rw-r--r--arch/arm/mach-pxa/palmz72.c2
-rw-r--r--arch/arm/mach-pxa/pcm027.c2
-rw-r--r--arch/arm/mach-pxa/poodle.c2
-rw-r--r--arch/arm/mach-pxa/pxa25x.c86
-rw-r--r--arch/arm/mach-pxa/pxa27x.c102
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c234
-rw-r--r--arch/arm/mach-pxa/pxa930.c2
-rw-r--r--arch/arm/mach-pxa/pxa95x.c308
-rw-r--r--arch/arm/mach-pxa/raumfeld.c11
-rw-r--r--arch/arm/mach-pxa/saar.c2
-rw-r--r--arch/arm/mach-pxa/saarb.c114
-rw-r--r--arch/arm/mach-pxa/sleep.S6
-rw-r--r--arch/arm/mach-pxa/smemc.c51
-rw-r--r--arch/arm/mach-pxa/spitz.c13
-rw-r--r--arch/arm/mach-pxa/stargate2.c7
-rw-r--r--arch/arm/mach-pxa/tavorevb.c2
-rw-r--r--arch/arm/mach-pxa/tavorevb3.c2
-rw-r--r--arch/arm/mach-pxa/time.c35
-rw-r--r--arch/arm/mach-pxa/tosa.c9
-rw-r--r--arch/arm/mach-pxa/trizeps4.c5
-rw-r--r--arch/arm/mach-pxa/viper.c2
-rw-r--r--arch/arm/mach-pxa/vpac270.c2
-rw-r--r--arch/arm/mach-pxa/xcep.c7
-rw-r--r--arch/arm/mach-pxa/z2.c2
-rw-r--r--arch/arm/mach-pxa/zeus.c10
-rw-r--r--arch/arm/mach-pxa/zylonite.c2
-rw-r--r--arch/arm/mach-realview/core.c18
-rw-r--r--arch/arm/mach-realview/core.h1
-rw-r--r--arch/arm/mach-realview/headsmp.S1
-rw-r--r--arch/arm/mach-realview/hotplug.c44
-rw-r--r--arch/arm/mach-realview/include/mach/entry-macro.S65
-rw-r--r--arch/arm/mach-realview/include/mach/smp.h5
-rw-r--r--arch/arm/mach-realview/platsmp.c116
-rw-r--r--arch/arm/mach-realview/realview_eb.c14
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c11
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c10
-rw-r--r--arch/arm/mach-realview/realview_pba8.c6
-rw-r--r--arch/arm/mach-realview/realview_pbx.c13
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2412/Kconfig11
-rw-r--r--arch/arm/mach-s3c2412/Makefile3
-rw-r--r--arch/arm/mach-s3c2412/irq.c50
-rw-r--r--arch/arm/mach-s3c2416/Kconfig4
-rw-r--r--arch/arm/mach-s3c2416/irq.c76
-rw-r--r--arch/arm/mach-s3c2440/Kconfig4
-rw-r--r--arch/arm/mach-s3c2440/irq.c18
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c11
-rw-r--r--arch/arm/mach-s3c2440/s3c2442.c14
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-irq.c18
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/irq.c95
-rw-r--r--arch/arm/mach-s3c64xx/clock.c2
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c75
-rw-r--r--arch/arm/mach-s3c64xx/dma.c1
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c37
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c44
-rw-r--r--arch/arm/mach-s5p6442/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c10
-rw-r--r--arch/arm/mach-s5p6442/setup-i2c0.c5
-rw-r--r--arch/arm/mach-s5p64x0/Makefile4
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c8
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c20
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c144
-rw-r--r--arch/arm/mach-s5p64x0/gpiolib.c (renamed from arch/arm/mach-s5p64x0/gpio.c)221
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h5
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-gpio.h57
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c1
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c1
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c56
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c2
-rw-r--r--arch/arm/mach-s5pv210/Kconfig2
-rw-r--r--arch/arm/mach-s5pv210/clock.c16
-rw-r--r--arch/arm/mach-s5pv210/cpu.c5
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c58
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h5
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c1
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c139
-rw-r--r--arch/arm/mach-s5pv310/Kconfig16
-rw-r--r--arch/arm/mach-s5pv310/Makefile6
-rw-r--r--arch/arm/mach-s5pv310/clock.c58
-rw-r--r--arch/arm/mach-s5pv310/cpu.c27
-rw-r--r--arch/arm/mach-s5pv310/cpufreq.c580
-rw-r--r--arch/arm/mach-s5pv310/dev-audio.c364
-rw-r--r--arch/arm/mach-s5pv310/dev-pd.c139
-rw-r--r--arch/arm/mach-s5pv310/dma.c168
-rw-r--r--arch/arm/mach-s5pv310/hotplug.c44
-rw-r--r--arch/arm/mach-s5pv310/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h19
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h31
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-clock.h80
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-mem.h23
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-pmu.h30
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-srom.h50
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h7
-rw-r--r--arch/arm/mach-s5pv310/irq-combiner.c32
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c55
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c51
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c51
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c80
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c68
-rw-r--r--arch/arm/mach-s5pv310/time.c6
-rw-r--r--arch/arm/mach-sa1100/Kconfig10
-rw-r--r--arch/arm/mach-sa1100/Makefile3
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c51
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c57
-rw-r--r--arch/arm/mach-sa1100/generic.c64
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h8
-rw-r--r--arch/arm/mach-sa1100/include/mach/nanoengine.h52
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c119
-rw-r--r--arch/arm/mach-sa1100/pci-nanoengine.c284
-rw-r--r--arch/arm/mach-sa1100/simpad.c7
-rw-r--r--arch/arm/mach-sa1100/time.c36
-rw-r--r--arch/arm/mach-shmobile/Kconfig33
-rw-r--r--arch/arm/mach-shmobile/Makefile15
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c314
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c16
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c595
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c356
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h8
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro-gic.S89
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro-intc.S61
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S30
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-ap4evb.txt87
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h5
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h467
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot.h20
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot_macros.h65
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c267
-rw-r--r--arch/arm/mach-shmobile/pfc-sh73a0.c2746
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c10
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c412
-rw-r--r--arch/arm/mach-tcc8k/clock.c3
-rw-r--r--arch/arm/mach-tcc8k/time.c5
-rw-r--r--arch/arm/mach-tegra/clock.c2
-rw-r--r--arch/arm/mach-tegra/clock.h2
-rw-r--r--arch/arm/mach-tegra/hotplug.c44
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S4
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S66
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h12
-rw-r--r--arch/arm/mach-tegra/irq.c4
-rw-r--r--arch/arm/mach-tegra/platsmp.c35
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c3
-rw-r--r--arch/arm/mach-tegra/timer.c31
-rw-r--r--arch/arm/mach-u300/clock.c2
-rw-r--r--arch/arm/mach-u300/timer.c22
-rw-r--r--arch/arm/mach-ux500/Makefile14
-rw-r--r--arch/arm/mach-ux500/board-mop500-keypads.c229
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c79
-rw-r--r--arch/arm/mach-ux500/board-mop500.c228
-rw-r--r--arch/arm/mach-ux500/board-mop500.h9
-rw-r--r--arch/arm/mach-ux500/board-u5500-sdi.c49
-rw-r--r--arch/arm/mach-ux500/board-u5500.c19
-rw-r--r--arch/arm/mach-ux500/clock.c368
-rw-r--r--arch/arm/mach-ux500/clock.h4
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c38
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c58
-rw-r--r--arch/arm/mach-ux500/cpu.c17
-rw-r--r--arch/arm/mach-ux500/cpufreq.c211
-rw-r--r--arch/arm/mach-ux500/devices-common.c145
-rw-r--r--arch/arm/mach-ux500/devices-common.h82
-rw-r--r--arch/arm/mach-ux500/devices-db5500.c46
-rw-r--r--arch/arm/mach-ux500/devices-db5500.h66
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c169
-rw-r--r--arch/arm/mach-ux500/devices-db8500.h98
-rw-r--r--arch/arm/mach-ux500/devices.c63
-rw-r--r--arch/arm/mach-ux500/dma-db5500.c120
-rw-r--r--arch/arm/mach-ux500/headsmp.S1
-rw-r--r--arch/arm/mach-ux500/hotplug.c18
-rw-r--r--arch/arm/mach-ux500/include/mach/db5500-regs.h4
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h3
-rw-r--r--arch/arm/mach-ux500/include/mach/devices.h17
-rw-r--r--arch/arm/mach-ux500/include/mach/entry-macro.S68
-rw-r--r--arch/arm/mach-ux500/include/mach/gpio.h38
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-board-mop500.h28
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h44
-rw-r--r--arch/arm/mach-ux500/include/mach/mbox-db5500.h (renamed from arch/arm/mach-ux500/include/mach/mbox.h)0
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu-defs.h30
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu-regs.h15
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu.h15
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h7
-rw-r--r--arch/arm/mach-ux500/include/mach/smp.h5
-rw-r--r--arch/arm/mach-ux500/include/mach/uncompress.h23
-rw-r--r--arch/arm/mach-ux500/mbox-db5500.c (renamed from arch/arm/mach-ux500/mbox.c)2
-rw-r--r--arch/arm/mach-ux500/modem-irq-db5500.c (renamed from arch/arm/mach-ux500/modem_irq.c)0
-rw-r--r--arch/arm/mach-ux500/platsmp.c77
-rw-r--r--arch/arm/mach-ux500/prcmu.c179
-rw-r--r--arch/arm/mach-versatile/Kconfig1
-rw-r--r--arch/arm/mach-versatile/core.c15
-rw-r--r--arch/arm/mach-vexpress/Makefile1
-rw-r--r--arch/arm/mach-vexpress/core.h2
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c12
-rw-r--r--arch/arm/mach-vexpress/headsmp.S1
-rw-r--r--arch/arm/mach-vexpress/hotplug.c128
-rw-r--r--arch/arm/mach-vexpress/include/mach/entry-macro.S62
-rw-r--r--arch/arm/mach-vexpress/include/mach/smp.h5
-rw-r--r--arch/arm/mach-vexpress/platsmp.c76
-rw-r--r--arch/arm/mach-vexpress/v2m.c8
-rw-r--r--arch/arm/mach-w90x900/clock.h2
-rw-r--r--arch/arm/mach-w90x900/time.c5
-rw-r--r--arch/arm/mm/Kconfig45
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c37
-rw-r--r--arch/arm/mm/cache-v6.S28
-rw-r--r--arch/arm/mm/cache-v7.S27
-rw-r--r--arch/arm/mm/cache-xsc3l2.c57
-rw-r--r--arch/arm/mm/dma-mapping.c46
-rw-r--r--arch/arm/mm/fault-armv.c9
-rw-r--r--arch/arm/mm/fault.c31
-rw-r--r--arch/arm/mm/flush.c7
-rw-r--r--arch/arm/mm/highmem.c87
-rw-r--r--arch/arm/mm/idmap.c90
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/mm.h4
-rw-r--r--arch/arm/mm/mmu.c90
-rw-r--r--arch/arm/mm/pgd.c57
-rw-r--r--arch/arm/mm/proc-macros.S59
-rw-r--r--arch/arm/mm/proc-v7.S31
-rw-r--r--arch/arm/mm/proc-xscale.S4
-rw-r--r--arch/arm/plat-iop/time.c30
-rw-r--r--arch/arm/plat-mxc/Kconfig15
-rw-r--r--arch/arm/plat-mxc/Makefile5
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c4
-rw-r--r--arch/arm/plat-mxc/avic.c (renamed from arch/arm/plat-mxc/irq.c)32
-rw-r--r--arch/arm/plat-mxc/cpufreq.c1
-rw-r--r--arch/arm/plat-mxc/devices.c23
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig54
-rw-r--r--arch/arm/plat-mxc/devices/Makefile16
-rw-r--r--arch/arm/plat-mxc/devices/platform-esdhc.c71
-rw-r--r--arch/arm/plat-mxc/devices/platform-fec.c8
-rw-r--r--arch/arm/plat-mxc/devices/platform-flexcan.c48
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-dma.c127
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-fb.c52
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-i2c.c16
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-keypad.c62
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-ssi.c17
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-uart.c38
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx2-wdt.c68
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx21-hcd.c41
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx_udc.c75
-rw-r--r--arch/arm/plat-mxc/devices/platform-imxdi_rtc.c41
-rw-r--r--arch/arm/plat-mxc/devices/platform-mx1-camera.c42
-rw-r--r--arch/arm/plat-mxc/devices/platform-mx2-camera.c64
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-ehci.c69
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-mmc.c72
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_nand.c10
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_pwm.c60
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_rnga.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_w1.c50
-rw-r--r--arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c74
-rw-r--r--arch/arm/plat-mxc/devices/platform-spi_imx.c16
-rw-r--r--arch/arm/plat-mxc/ehci.c77
-rw-r--r--arch/arm/plat-mxc/epit.c5
-rw-r--r--arch/arm/plat-mxc/gpio.c114
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h9
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S23
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h174
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S14
-rw-r--r--arch/arm/plat-mxc/include/mach/gpio.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h94
-rw-r--r--arch/arm/plat-mxc/include/mach/imxfb.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx50.h977
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h1898
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx53.h323
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v3.h64
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1.h155
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h50
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h46
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h105
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2x.h149
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h87
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h51
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h198
-rw-r--r--arch/arm/plat-mxc/include/mach/mx50.h285
-rw-r--r--arch/arm/plat-mxc/include/mach/mx51.h73
-rw-r--r--arch/arm/plat-mxc/include/mach/mx53.h353
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h42
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc91231.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_ehci.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/sdma.h46
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h8
-rw-r--r--arch/arm/plat-mxc/iomux-v3.c31
-rw-r--r--arch/arm/plat-mxc/irq-common.c60
-rw-r--r--arch/arm/plat-mxc/irq-common.h29
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S2
-rw-r--r--arch/arm/plat-mxc/system.c10
-rw-r--r--arch/arm/plat-mxc/time.c5
-rw-r--r--arch/arm/plat-mxc/tzic.c46
-rw-r--r--arch/arm/plat-nomadik/Kconfig1
-rw-r--r--arch/arm/plat-nomadik/gpio.c52
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h70
-rw-r--r--arch/arm/plat-nomadik/timer.c80
-rw-r--r--arch/arm/plat-omap/Kconfig39
-rw-r--r--arch/arm/plat-omap/counter_32k.c48
-rw-r--r--arch/arm/plat-omap/devices.c40
-rw-r--r--arch/arm/plat-omap/dma.c695
-rw-r--r--arch/arm/plat-omap/gpio.c670
-rw-r--r--arch/arm/plat-omap/i2c.c128
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h22
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h16
-rw-r--r--arch/arm/plat-omap/include/plat/common.h2
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h232
-rw-r--r--arch/arm/plat-omap/include/plat/fpga.h4
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h48
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc.h9
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h13
-rw-r--r--arch/arm/plat-omap/include/plat/io.h9
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h5
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-omap/include/plat/keypad.h35
-rw-r--r--arch/arm/plat-omap/include/plat/l4_3xxx.h24
-rw-r--r--arch/arm/plat-omap/include/plat/mailbox.h8
-rw-r--r--arch/arm/plat-omap/include/plat/memory.h8
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h39
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h14
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h73
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h20
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h5
-rw-r--r--arch/arm/plat-omap/include/plat/smartreflex.h245
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h5
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h11
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h3
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h146
-rw-r--r--arch/arm/plat-omap/io.c58
-rw-r--r--arch/arm/plat-omap/iommu.c24
-rw-r--r--arch/arm/plat-omap/iovmm.c81
-rw-r--r--arch/arm/plat-omap/mailbox.c130
-rw-r--r--arch/arm/plat-omap/mcbsp.c26
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c78
-rw-r--r--arch/arm/plat-omap/omap_device.c28
-rw-r--r--arch/arm/plat-omap/sram.c16
-rw-r--r--arch/arm/plat-orion/time.c50
-rw-r--r--arch/arm/plat-pxa/Makefile1
-rw-r--r--arch/arm/plat-pxa/include/plat/mfp.h4
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig2
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c8
-rw-r--r--arch/arm/plat-s3c24xx/devs.c19
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h4
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c244x.h7
-rw-r--r--arch/arm/plat-s3c24xx/irq-pm.c9
-rw-r--r--arch/arm/plat-s3c24xx/irq.c182
-rw-r--r--arch/arm/plat-s5p/Kconfig10
-rw-r--r--arch/arm/plat-s5p/Makefile2
-rw-r--r--arch/arm/plat-s5p/cpu.c5
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/include/plat/csis.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h1
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-s5p/irq-eint.c86
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c50
-rw-r--r--arch/arm/plat-s5p/irq-pm.c6
-rw-r--r--arch/arm/plat-samsung/Kconfig8
-rw-r--r--arch/arm/plat-samsung/Makefile5
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c25
-rw-r--r--arch/arm/plat-samsung/gpio-config.c47
-rw-r--r--arch/arm/plat-samsung/gpiolib.c7
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h24
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h4
-rw-r--r--arch/arm/plat-samsung/irq-uart.c40
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c26
-rw-r--r--arch/arm/plat-samsung/pd.c95
-rw-r--r--arch/arm/plat-samsung/pm.c6
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h2
-rw-r--r--arch/arm/plat-spear/include/plat/keyboard.h141
-rw-r--r--arch/arm/plat-spear/time.c6
-rw-r--r--arch/arm/plat-stmp3xxx/clock.c2
-rw-r--r--arch/arm/plat-stmp3xxx/timer.c5
-rw-r--r--arch/arm/plat-versatile/Makefile5
-rw-r--r--arch/arm/plat-versatile/include/plat/sched_clock.h6
-rw-r--r--arch/arm/plat-versatile/sched-clock.c51
-rw-r--r--arch/arm/tools/mach-types183
-rw-r--r--arch/arm/vfp/vfphw.S1
-rw-r--r--arch/arm/vfp/vfpmodule.c24
-rw-r--r--arch/blackfin/configs/BF561-EZKIT-SMP_defconfig113
-rw-r--r--arch/blackfin/include/asm/bfin_dma.h91
-rw-r--r--arch/blackfin/include/asm/bfin_serial.h263
-rw-r--r--arch/blackfin/include/asm/dma.h37
-rw-r--r--arch/blackfin/include/asm/io.h268
-rw-r--r--arch/blackfin/include/mach-common/ports-a.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-b.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-c.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-d.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-e.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-f.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-g.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-h.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-i.h25
-rw-r--r--arch/blackfin/include/mach-common/ports-j.h25
-rw-r--r--arch/blackfin/mach-bf518/dma.c2
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h73
-rw-r--r--arch/blackfin/mach-bf518/include/mach/blackfin.h68
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF512.h1038
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF514.h5
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF516.h5
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF518.h5
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h1061
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF512.h1388
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF51x_base.h1495
-rw-r--r--arch/blackfin/mach-bf518/include/mach/gpio.h4
-rw-r--r--arch/blackfin/mach-bf527/boards/ad7160eval.c1
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c1
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c1
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c1
-rw-r--r--arch/blackfin/mach-bf527/dma.c2
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h73
-rw-r--r--arch/blackfin/mach-bf527/include/mach/blackfin.h48
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF522.h1092
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF525.h7
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF527.h7
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h1113
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF522.h1393
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF525.h2
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF527.h2
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF52x_base.h1506
-rw-r--r--arch/blackfin/mach-bf527/include/mach/gpio.h4
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c15
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c9
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c20
-rw-r--r--arch/blackfin/mach-bf533/dma.c2
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h74
-rw-r--r--arch/blackfin/mach-bf533/include/mach/blackfin.h30
-rw-r--r--arch/blackfin/mach-bf533/include/mach/cdefBF532.h63
-rw-r--r--arch/blackfin/mach-bf533/include/mach/defBF532.h128
-rw-r--r--arch/blackfin/mach-bf533/include/mach/fio_flag.h55
-rw-r--r--arch/blackfin/mach-bf533/include/mach/gpio.h2
-rw-r--r--arch/blackfin/mach-bf537/dma.c2
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h72
-rw-r--r--arch/blackfin/mach-bf537/include/mach/blackfin.h38
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF534.h27
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF537.h5
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF534.h111
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF537.h5
-rw-r--r--arch/blackfin/mach-bf537/include/mach/gpio.h4
-rw-r--r--arch/blackfin/mach-bf538/dma.c18
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h73
-rw-r--r--arch/blackfin/mach-bf538/include/mach/blackfin.h37
-rw-r--r--arch/blackfin/mach-bf538/include/mach/cdefBF538.h504
-rw-r--r--arch/blackfin/mach-bf538/include/mach/cdefBF539.h8
-rw-r--r--arch/blackfin/mach-bf538/include/mach/defBF538.h1825
-rw-r--r--arch/blackfin/mach-bf538/include/mach/defBF539.h2095
-rw-r--r--arch/blackfin/mach-bf538/include/mach/gpio.h5
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c1
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c1
-rw-r--r--arch/blackfin/mach-bf548/dma.c2
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial.h16
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h60
-rw-r--r--arch/blackfin/mach-bf548/include/mach/blackfin.h70
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF542.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF544.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF547.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF548.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF549.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h23
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF542.h7
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF544.h7
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF547.h7
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF548.h7
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF549.h7
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF54x_base.h321
-rw-r--r--arch/blackfin/mach-bf548/include/mach/gpio.h11
-rw-r--r--arch/blackfin/mach-bf561/dma.c18
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial.h14
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h74
-rw-r--r--arch/blackfin/mach-bf561/include/mach/blackfin.h26
-rw-r--r--arch/blackfin/mach-bf561/include/mach/cdefBF561.h503
-rw-r--r--arch/blackfin/mach-bf561/include/mach/defBF561.h408
-rw-r--r--arch/blackfin/mach-bf561/include/mach/gpio.h2
-rw-r--r--arch/blackfin/mach-bf561/smp.c4
-rw-r--r--arch/ia64/include/asm/io.h5
-rw-r--r--arch/ia64/include/asm/kvm_host.h4
-rw-r--r--arch/ia64/kernel/irq_ia64.c2
-rw-r--r--arch/ia64/kernel/perfmon.c9
-rw-r--r--arch/ia64/kernel/smp.c13
-rw-r--r--arch/ia64/kernel/time.c2
-rw-r--r--arch/ia64/kvm/kvm-ia64.c30
-rw-r--r--arch/m68k/include/asm/cacheflush_no.h95
-rw-r--r--arch/m68k/include/asm/coldfire.h2
-rw-r--r--arch/m68k/include/asm/entry_no.h59
-rw-r--r--arch/m68k/include/asm/gpio.h2
-rw-r--r--arch/m68k/include/asm/io_no.h1
-rw-r--r--arch/m68k/include/asm/m5206sim.h14
-rw-r--r--arch/m68k/include/asm/m520xsim.h17
-rw-r--r--arch/m68k/include/asm/m523xsim.h11
-rw-r--r--arch/m68k/include/asm/m5249sim.h10
-rw-r--r--arch/m68k/include/asm/m5272sim.h8
-rw-r--r--arch/m68k/include/asm/m527xsim.h10
-rw-r--r--arch/m68k/include/asm/m528xsim.h11
-rw-r--r--arch/m68k/include/asm/m52xxacr.h94
-rw-r--r--arch/m68k/include/asm/m5307sim.h43
-rw-r--r--arch/m68k/include/asm/m532xsim.h33
-rw-r--r--arch/m68k/include/asm/m53xxacr.h101
-rw-r--r--arch/m68k/include/asm/m5407sim.h42
-rw-r--r--arch/m68k/include/asm/m54xxacr.h97
-rw-r--r--arch/m68k/include/asm/m54xxgpt.h (renamed from arch/m68k/include/asm/m548xgpt.h)10
-rw-r--r--arch/m68k/include/asm/m54xxsim.h (renamed from arch/m68k/include/asm/m548xsim.h)23
-rw-r--r--arch/m68k/include/asm/mcfcache.h150
-rw-r--r--arch/m68k/include/asm/mcfsim.h4
-rw-r--r--arch/m68k/include/asm/mcfuart.h45
-rw-r--r--arch/m68k/include/asm/processor.h13
-rw-r--r--arch/m68k/include/asm/sun3_pgtable.h5
-rw-r--r--arch/m68knommu/Kconfig99
-rw-r--r--arch/m68knommu/Makefile14
-rw-r--r--arch/m68knommu/kernel/setup.c72
-rw-r--r--arch/m68knommu/mm/Makefile2
-rw-r--r--arch/m68knommu/mm/fault.c57
-rw-r--r--arch/m68knommu/mm/kmap.c9
-rw-r--r--arch/m68knommu/mm/memory.c33
-rw-r--r--arch/m68knommu/platform/54xx/Makefile (renamed from arch/m68knommu/platform/548x/Makefile)0
-rw-r--r--arch/m68knommu/platform/54xx/config.c (renamed from arch/m68knommu/platform/548x/config.c)32
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile4
-rw-r--r--arch/m68knommu/platform/coldfire/cache.c48
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S56
-rw-r--r--arch/m68knommu/platform/coldfire/head.S26
-rw-r--r--arch/microblaze/Makefile2
-rw-r--r--arch/microblaze/include/asm/pvr.h185
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c1
-rw-r--r--arch/microblaze/kernel/entry.S46
-rw-r--r--arch/microblaze/kernel/exceptions.c3
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S9
-rw-r--r--arch/microblaze/kernel/prom.c4
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S16
-rw-r--r--arch/microblaze/lib/memmove.c2
-rw-r--r--arch/microblaze/lib/muldi3.S121
-rw-r--r--arch/microblaze/lib/muldi3.c60
-rw-r--r--arch/mips/Kconfig42
-rw-r--r--arch/mips/alchemy/common/platform.c2
-rw-r--r--arch/mips/alchemy/devboards/prom.c5
-rw-r--r--arch/mips/ar7/clock.c9
-rw-r--r--arch/mips/ar7/time.c3
-rw-r--r--arch/mips/bcm47xx/setup.c153
-rw-r--r--arch/mips/include/asm/cpu-info.h1
-rw-r--r--arch/mips/include/asm/cpu.h4
-rw-r--r--arch/mips/include/asm/elf.h8
-rw-r--r--arch/mips/include/asm/inst.h14
-rw-r--r--arch/mips/include/asm/io.h12
-rw-r--r--arch/mips/include/asm/jump_label.h48
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h3
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/nvram.h7
-rw-r--r--arch/mips/include/asm/mips_machine.h54
-rw-r--r--arch/mips/include/asm/mmu_context.h8
-rw-r--r--arch/mips/include/asm/uasm.h7
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c4
-rw-r--r--arch/mips/jz4740/platform.c2
-rw-r--r--arch/mips/jz4740/prom.c2
-rw-r--r--arch/mips/kernel/Makefile3
-rw-r--r--arch/mips/kernel/cevt-r4k.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c9
-rw-r--r--arch/mips/kernel/jump_label.c54
-rw-r--r--arch/mips/kernel/linux32.c13
-rw-r--r--arch/mips/kernel/mips_machine.c86
-rw-r--r--arch/mips/kernel/module.c5
-rw-r--r--arch/mips/kernel/proc.c9
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/mips/kernel/prom.c2
-rw-r--r--arch/mips/kernel/smp-mt.c2
-rw-r--r--arch/mips/kernel/traps.c46
-rw-r--r--arch/mips/kernel/vmlinux.lds.S7
-rw-r--r--arch/mips/kernel/vpe.c14
-rw-r--r--arch/mips/lib/memset.S4
-rw-r--r--arch/mips/loongson/common/env.c4
-rw-r--r--arch/mips/math-emu/cp1emu.c116
-rw-r--r--arch/mips/mm/dma-default.c4
-rw-r--r--arch/mips/mm/sc-mips.c4
-rw-r--r--arch/mips/mm/tlbex.c590
-rw-r--r--arch/mips/mm/uasm.c56
-rw-r--r--arch/mips/pmc-sierra/yosemite/py-console.c12
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c3
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--arch/mips/txx9/generic/pci.c7
-rw-r--r--arch/mn10300/include/asm/syscall.h117
-rw-r--r--arch/mn10300/kernel/gdb-io-serial.c3
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c3
-rw-r--r--arch/mn10300/kernel/gdb-stub.c3
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/time.c10
-rw-r--r--arch/parisc/kernel/irq.c7
-rw-r--r--arch/parisc/kernel/signal.c9
-rw-r--r--arch/powerpc/Kconfig16
-rw-r--r--arch/powerpc/boot/dts/canyonlands.dts31
-rw-r--r--arch/powerpc/boot/dts/kilauea.dts9
-rw-r--r--arch/powerpc/boot/dts/mpc8308_p1m.dts8
-rw-r--r--arch/powerpc/boot/dts/mpc8308rdb.dts8
-rw-r--r--arch/powerpc/configs/40x/kilauea_defconfig5
-rw-r--r--arch/powerpc/configs/44x/canyonlands_defconfig3
-rw-r--r--arch/powerpc/include/asm/bitops.h9
-rw-r--r--arch/powerpc/include/asm/cputable.h9
-rw-r--r--arch/powerpc/include/asm/cputhreads.h15
-rw-r--r--arch/powerpc/include/asm/device.h6
-rw-r--r--arch/powerpc/include/asm/firmware.h3
-rw-r--r--arch/powerpc/include/asm/hvcall.h4
-rw-r--r--arch/powerpc/include/asm/lppaca.h5
-rw-r--r--arch/powerpc/include/asm/machdep.h6
-rw-r--r--arch/powerpc/include/asm/mmzone.h5
-rw-r--r--arch/powerpc/include/asm/nvram.h52
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h8
-rw-r--r--arch/powerpc/include/asm/processor.h2
-rw-r--r--arch/powerpc/include/asm/prom.h2
-rw-r--r--arch/powerpc/include/asm/topology.h10
-rw-r--r--arch/powerpc/include/asm/vdso_datapage.h2
-rw-r--r--arch/powerpc/kernel/Makefile9
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/cputable.c22
-rw-r--r--arch/powerpc/kernel/crash_dump.c33
-rw-r--r--arch/powerpc/kernel/dma-iommu.c2
-rw-r--r--arch/powerpc/kernel/entry_32.S1
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S1
-rw-r--r--arch/powerpc/kernel/fpu.S1
-rw-r--r--arch/powerpc/kernel/head_40x.S1
-rw-r--r--arch/powerpc/kernel/head_44x.S1
-rw-r--r--arch/powerpc/kernel/head_64.S7
-rw-r--r--arch/powerpc/kernel/head_8xx.S1
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S1
-rw-r--r--arch/powerpc/kernel/iommu.c14
-rw-r--r--arch/powerpc/kernel/misc.S5
-rw-r--r--arch/powerpc/kernel/misc_32.S1
-rw-r--r--arch/powerpc/kernel/misc_64.S1
-rw-r--r--arch/powerpc/kernel/nvram_64.c481
-rw-r--r--arch/powerpc/kernel/pci_64.c3
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c7
-rw-r--r--arch/powerpc/kernel/ppc_save_regs.S1
-rw-r--r--arch/powerpc/kernel/ptrace.c22
-rw-r--r--arch/powerpc/kernel/ptrace32.c7
-rw-r--r--arch/powerpc/kernel/rtas.c3
-rw-r--r--arch/powerpc/kernel/setup_64.c4
-rw-r--r--arch/powerpc/kernel/smp.c19
-rw-r--r--arch/powerpc/kernel/time.c2
-rw-r--r--arch/powerpc/kernel/vector.S1
-rw-r--r--arch/powerpc/kernel/vio.c15
-rw-r--r--arch/powerpc/kvm/book3s.c4
-rw-r--r--arch/powerpc/kvm/powerpc.c20
-rw-r--r--arch/powerpc/lib/Makefile2
-rw-r--r--arch/powerpc/lib/hweight_64.S110
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c12
-rw-r--r--arch/powerpc/mm/numa.c303
-rw-r--r--arch/powerpc/mm/pgtable_32.c3
-rw-r--r--arch/powerpc/mm/pgtable_64.c2
-rw-r--r--arch/powerpc/platforms/44x/Makefile5
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c1
-rw-r--r--arch/powerpc/platforms/Kconfig7
-rw-r--r--arch/powerpc/platforms/cell/beat_iommu.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c18
-rw-r--r--arch/powerpc/platforms/cell/spufs/lscsa_alloc.c3
-rw-r--r--arch/powerpc/platforms/chrp/time.c4
-rw-r--r--arch/powerpc/platforms/iseries/mf.c62
-rw-r--r--arch/powerpc/platforms/pasemi/iommu.c19
-rw-r--r--arch/powerpc/platforms/powermac/setup.c9
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig10
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c1
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S1
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c49
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c12
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c205
-rw-r--r--arch/powerpc/platforms/pseries/pseries_energy.c326
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c9
-rw-r--r--arch/powerpc/sysdev/mpc8xxx_gpio.c75
-rw-r--r--arch/powerpc/sysdev/ppc4xx_cpm.c346
-rw-r--r--arch/powerpc/sysdev/tsi108_dev.c8
-rw-r--r--arch/s390/Kconfig131
-rw-r--r--arch/s390/Kconfig.debug6
-rw-r--r--arch/s390/defconfig152
-rw-r--r--arch/s390/hypfs/Makefile2
-rw-r--r--arch/s390/hypfs/hypfs.h33
-rw-r--r--arch/s390/hypfs/hypfs_dbfs.c116
-rw-r--r--arch/s390/hypfs/hypfs_diag.c82
-rw-r--r--arch/s390/hypfs/hypfs_vm.c62
-rw-r--r--arch/s390/hypfs/inode.c18
-rw-r--r--arch/s390/include/asm/ccwdev.h2
-rw-r--r--arch/s390/include/asm/cputime.h2
-rw-r--r--arch/s390/include/asm/dasd.h3
-rw-r--r--arch/s390/include/asm/ftrace.h11
-rw-r--r--arch/s390/include/asm/hardirq.h16
-rw-r--r--arch/s390/include/asm/irq.h34
-rw-r--r--arch/s390/include/asm/kprobes.h20
-rw-r--r--arch/s390/include/asm/mutex.h2
-rw-r--r--arch/s390/include/asm/processor.h4
-rw-r--r--arch/s390/include/asm/ptrace.h52
-rw-r--r--arch/s390/include/asm/qdio.h1
-rw-r--r--arch/s390/include/asm/qeth.h51
-rw-r--r--arch/s390/include/asm/s390_ext.h29
-rw-r--r--arch/s390/include/asm/smp.h3
-rw-r--r--arch/s390/include/asm/system.h4
-rw-r--r--arch/s390/include/asm/thread_info.h10
-rw-r--r--arch/s390/include/asm/timex.h20
-rw-r--r--arch/s390/kernel/asm-offsets.c14
-rw-r--r--arch/s390/kernel/compat_ptrace.h53
-rw-r--r--arch/s390/kernel/entry.S274
-rw-r--r--arch/s390/kernel/entry.h2
-rw-r--r--arch/s390/kernel/entry64.S73
-rw-r--r--arch/s390/kernel/ftrace.c236
-rw-r--r--arch/s390/kernel/irq.c41
-rw-r--r--arch/s390/kernel/kprobes.c470
-rw-r--r--arch/s390/kernel/mcount.S32
-rw-r--r--arch/s390/kernel/mcount64.S29
-rw-r--r--arch/s390/kernel/nmi.c3
-rw-r--r--arch/s390/kernel/process.c21
-rw-r--r--arch/s390/kernel/processor.c20
-rw-r--r--arch/s390/kernel/ptrace.c306
-rw-r--r--arch/s390/kernel/s390_ext.c125
-rw-r--r--arch/s390/kernel/signal.c2
-rw-r--r--arch/s390/kernel/smp.c47
-rw-r--r--arch/s390/kernel/time.c6
-rw-r--r--arch/s390/kernel/traps.c15
-rw-r--r--arch/s390/kernel/vtime.c25
-rw-r--r--arch/s390/kvm/Kconfig7
-rw-r--r--arch/s390/kvm/kvm-s390.c23
-rw-r--r--arch/s390/lib/delay.c2
-rw-r--r--arch/s390/mm/fault.c35
-rw-r--r--arch/sh/Kconfig25
-rw-r--r--arch/sh/boards/board-secureedge5410.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c34
-rw-r--r--arch/sh/boards/mach-highlander/setup.c2
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c37
-rw-r--r--arch/sh/boards/mach-sdk7786/Makefile2
-rw-r--r--arch/sh/boards/mach-sdk7786/nmi.c83
-rw-r--r--arch/sh/boards/mach-sdk7786/setup.c1
-rw-r--r--arch/sh/boards/mach-se/7206/irq.c2
-rw-r--r--arch/sh/boards/mach-se/7206/setup.c6
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c52
-rw-r--r--arch/sh/boards/mach-se/board-se7619.c6
-rw-r--r--arch/sh/drivers/pci/pci.c3
-rw-r--r--arch/sh/include/asm/cacheflush.h2
-rw-r--r--arch/sh/include/asm/clkdev.h38
-rw-r--r--arch/sh/include/asm/io.h345
-rw-r--r--arch/sh/include/asm/io_generic.h25
-rw-r--r--arch/sh/include/asm/machvec.h21
-rw-r--r--arch/sh/include/asm/unaligned-sh4a.h164
-rw-r--r--arch/sh/include/asm/unistd_32.h3
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7724.h3
-rw-r--r--arch/sh/include/mach-common/mach/romimage.h2
-rw-r--r--arch/sh/include/mach-ecovec24/mach/romimage.h2
-rw-r--r--arch/sh/include/mach-kfr2r09/mach/romimage.h2
-rw-r--r--arch/sh/include/mach-sdk7786/mach/fpga.h8
-rw-r--r--arch/sh/kernel/Makefile8
-rw-r--r--arch/sh/kernel/clkdev.c171
-rw-r--r--arch/sh/kernel/cpu/Makefile2
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c2
-rw-r--r--arch/sh/kernel/cpu/clock.c16
-rw-r--r--arch/sh/kernel/cpu/proc.c148
-rw-r--r--arch/sh/kernel/cpu/sh2/clock-sh7619.c22
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c20
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c21
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7206.c20
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c46
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c2
-rw-r--r--arch/sh/kernel/io_generic.c180
-rw-r--r--arch/sh/kernel/iomap.c165
-rw-r--r--arch/sh/kernel/ioport.c43
-rw-r--r--arch/sh/kernel/machvec.c22
-rw-r--r--arch/sh/kernel/setup.c144
-rw-r--r--arch/sh/kernel/syscalls_32.S1
-rw-r--r--arch/sh/mm/cache-sh4.c4
-rw-r--r--arch/sh/mm/cache-sh7705.c2
-rw-r--r--arch/sh/mm/cache.c14
-rw-r--r--arch/sh/mm/kmap.c2
-rw-r--r--arch/sparc/include/asm/openprom.h2
-rw-r--r--arch/sparc/include/asm/oplib_32.h77
-rw-r--r--arch/sparc/include/asm/oplib_64.h50
-rw-r--r--arch/sparc/kernel/leon_kernel.c4
-rw-r--r--arch/sparc/prom/Makefile3
-rw-r--r--arch/sparc/prom/console_32.c68
-rw-r--r--arch/sparc/prom/console_64.c83
-rw-r--r--arch/sparc/prom/devmap.c53
-rw-r--r--arch/sparc/prom/devops_32.c87
-rw-r--r--arch/sparc/prom/devops_64.c67
-rw-r--r--arch/sparc/prom/init_64.c3
-rw-r--r--arch/sparc/prom/misc_64.c16
-rw-r--r--arch/sparc/prom/mp.c78
-rw-r--r--arch/sparc/prom/palloc.c43
-rw-r--r--arch/sparc/prom/printf.c35
-rw-r--r--arch/sparc/prom/tree_32.c60
-rw-r--r--arch/sparc/prom/tree_64.c18
-rw-r--r--arch/tile/include/asm/signal.h2
-rw-r--r--arch/tile/kernel/compat_signal.c6
-rw-r--r--arch/tile/kernel/intvec_32.S24
-rw-r--r--arch/tile/kernel/process.c8
-rw-r--r--arch/tile/kernel/signal.c10
-rw-r--r--arch/x86/boot/compressed/misc.c2
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S1832
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c540
-rw-r--r--arch/x86/crypto/ghash-clmulni-intel_glue.c1
-rw-r--r--arch/x86/include/asm/e820.h3
-rw-r--r--arch/x86/include/asm/kvm_emulate.h35
-rw-r--r--arch/x86/include/asm/kvm_host.h101
-rw-r--r--arch/x86/include/asm/kvm_para.h24
-rw-r--r--arch/x86/include/asm/pvclock.h1
-rw-r--r--arch/x86/include/asm/svm.h57
-rw-r--r--arch/x86/include/asm/traps.h1
-rw-r--r--arch/x86/include/asm/vmx.h15
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/apic/apic.c8
-rw-r--r--arch/x86/kernel/apic/io_apic.c4
-rw-r--r--arch/x86/kernel/apic/probe_64.c7
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c13
-rw-r--r--arch/x86/kernel/entry_32.S10
-rw-r--r--arch/x86/kernel/entry_64.S3
-rw-r--r--arch/x86/kernel/head_32.S16
-rw-r--r--arch/x86/kernel/hpet.c26
-rw-r--r--arch/x86/kernel/kvm.c317
-rw-r--r--arch/x86/kernel/kvmclock.c13
-rw-r--r--arch/x86/kernel/microcode_intel.c16
-rw-r--r--arch/x86/kernel/pvclock.c5
-rw-r--r--arch/x86/kernel/resource.c48
-rw-r--r--arch/x86/kernel/setup.c18
-rw-r--r--arch/x86/kernel/xsave.c3
-rw-r--r--arch/x86/kvm/Kconfig1
-rw-r--r--arch/x86/kvm/Makefile3
-rw-r--r--arch/x86/kvm/emulate.c367
-rw-r--r--arch/x86/kvm/i8259.c2
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h22
-rw-r--r--arch/x86/kvm/lapic.c3
-rw-r--r--arch/x86/kvm/mmu.c254
-rw-r--r--arch/x86/kvm/mmu_audit.c39
-rw-r--r--arch/x86/kvm/paging_tmpl.h147
-rw-r--r--arch/x86/kvm/svm.c861
-rw-r--r--arch/x86/kvm/trace.h17
-rw-r--r--arch/x86/kvm/vmx.c161
-rw-r--r--arch/x86/kvm/x86.c476
-rw-r--r--arch/x86/kvm/x86.h5
-rw-r--r--arch/x86/lguest/boot.c18
-rw-r--r--arch/x86/lguest/i386_head.S105
-rw-r--r--arch/x86/oprofile/op_model_amd.c24
-rw-r--r--arch/x86/pci/i386.c18
-rw-r--r--arch/x86/pci/irq.c3
-rw-r--r--arch/x86/pci/xen.c27
-rw-r--r--arch/x86/vdso/Makefile4
-rw-r--r--arch/x86/xen/enlighten.c4
-rw-r--r--arch/x86/xen/mmu.c2
-rw-r--r--arch/x86/xen/platform-pci-unplug.c2
-rw-r--r--arch/x86/xen/setup.c41
-rw-r--r--arch/x86/xen/suspend.c1
-rw-r--r--arch/x86/xen/time.c2
-rw-r--r--arch/x86/xen/xen-ops.h2
-rw-r--r--arch/xtensa/Kconfig17
-rw-r--r--arch/xtensa/Makefile5
-rw-r--r--arch/xtensa/boot/Makefile1
-rw-r--r--arch/xtensa/include/asm/coprocessor.h9
-rw-r--r--arch/xtensa/include/asm/io.h40
-rw-r--r--arch/xtensa/include/asm/irq.h7
-rw-r--r--arch/xtensa/include/asm/serial.h12
-rw-r--r--arch/xtensa/kernel/Makefile4
-rw-r--r--arch/xtensa/kernel/time.c2
-rw-r--r--arch/xtensa/platforms/xtavnet/Makefile10
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/hardware.h85
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/lcd.h22
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/serial.h1
-rw-r--r--arch/xtensa/platforms/xtavnet/lcd.c79
-rw-r--r--arch/xtensa/platforms/xtavnet/setup.c269
-rw-r--r--block/blk-cgroup.c4
-rw-r--r--block/blk-core.c14
-rw-r--r--block/blk-ioc.c5
-rw-r--r--block/blk-map.c5
-rw-r--r--block/blk-merge.c6
-rw-r--r--block/blk-settings.c51
-rw-r--r--block/blk-sysfs.c2
-rw-r--r--block/blk-throttle.c39
-rw-r--r--block/bsg.c8
-rw-r--r--block/cfq-iosched.c62
-rw-r--r--block/genhd.c548
-rw-r--r--block/ioctl.c5
-rw-r--r--crypto/Kconfig34
-rw-r--r--crypto/Makefile17
-rw-r--r--crypto/af_alg.c483
-rw-r--r--crypto/algif_hash.c319
-rw-r--r--crypto/algif_skcipher.c632
-rw-r--r--crypto/authenc.c22
-rw-r--r--crypto/cast5.c74
-rw-r--r--crypto/crypto_wq.c3
-rw-r--r--crypto/deflate.c3
-rw-r--r--crypto/eseqiv.c18
-rw-r--r--crypto/gcm.c19
-rw-r--r--crypto/pcrypt.c3
-rw-r--r--crypto/rmd128.c3
-rw-r--r--crypto/rmd160.c3
-rw-r--r--crypto/rmd256.c3
-rw-r--r--crypto/rmd320.c3
-rw-r--r--crypto/shash.c8
-rw-r--r--crypto/tcrypt.c11
-rw-r--r--crypto/testmgr.c24
-rw-r--r--crypto/testmgr.h361
-rw-r--r--crypto/zlib.c3
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/acpi/Kconfig11
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c46
-rw-r--r--drivers/acpi/acpi_ipmi.c525
-rw-r--r--drivers/acpi/acpica/Makefile2
-rw-r--r--drivers/acpi/acpica/acevents.h21
-rw-r--r--drivers/acpi/acpica/acglobal.h7
-rw-r--r--drivers/acpi/acpica/achware.h2
-rw-r--r--drivers/acpi/acpica/aclocal.h13
-rw-r--r--drivers/acpi/acpica/evevent.c12
-rw-r--r--drivers/acpi/acpica/evgpe.c265
-rw-r--r--drivers/acpi/acpica/evgpeblk.c33
-rw-r--r--drivers/acpi/acpica/evgpeinit.c28
-rw-r--r--drivers/acpi/acpica/evgpeutil.c39
-rw-r--r--drivers/acpi/acpica/evxface.c77
-rw-r--r--drivers/acpi/acpica/evxfevnt.c600
-rw-r--r--drivers/acpi/acpica/evxfgpe.c669
-rw-r--r--drivers/acpi/acpica/hwgpe.c32
-rw-r--r--drivers/acpi/acpica/utglobal.c3
-rw-r--r--drivers/acpi/apei/Kconfig1
-rw-r--r--drivers/acpi/apei/apei-internal.h2
-rw-r--r--drivers/acpi/apei/cper.c311
-rw-r--r--drivers/acpi/apei/erst.c170
-rw-r--r--drivers/acpi/apei/ghes.c25
-rw-r--r--drivers/acpi/apei/hest.c10
-rw-r--r--drivers/acpi/bus.c153
-rw-r--r--drivers/acpi/dock.c2
-rw-r--r--drivers/acpi/ec.c6
-rw-r--r--drivers/acpi/fan.c27
-rw-r--r--drivers/acpi/internal.h5
-rw-r--r--drivers/acpi/osl.c119
-rw-r--r--drivers/acpi/power.c102
-rw-r--r--drivers/acpi/processor_thermal.c9
-rw-r--r--drivers/acpi/scan.c128
-rw-r--r--drivers/acpi/sleep.c12
-rw-r--r--drivers/acpi/sysfs.c19
-rw-r--r--drivers/acpi/thermal.c5
-rw-r--r--drivers/acpi/wakeup.c4
-rw-r--r--drivers/amba/bus.c39
-rw-r--r--drivers/ata/Kconfig30
-rw-r--r--drivers/ata/Makefile3
-rw-r--r--drivers/ata/acard-ahci.c528
-rw-r--r--drivers/ata/ahci.h3
-rw-r--r--drivers/ata/libahci.c11
-rw-r--r--drivers/ata/libata-core.c24
-rw-r--r--drivers/ata/libata-eh.c17
-rw-r--r--drivers/ata/libata-scsi.c60
-rw-r--r--drivers/ata/libata-sff.c7
-rw-r--r--drivers/ata/pata_cs5536.c20
-rw-r--r--drivers/atm/adummy.c2
-rw-r--r--drivers/atm/ambassador.c3
-rw-r--r--drivers/atm/atmtcp.c7
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/fore200e.c16
-rw-r--r--drivers/atm/he.c2
-rw-r--r--drivers/atm/horizon.c3
-rw-r--r--drivers/atm/idt77252.c3
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/atm/lanai.c9
-rw-r--r--drivers/atm/nicstar.c3
-rw-r--r--drivers/atm/solos-pci.c8
-rw-r--r--drivers/atm/zatm.c2
-rw-r--r--drivers/base/core.c41
-rw-r--r--drivers/block/aoe/aoecmd.c6
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/drbd/drbd_int.h2
-rw-r--r--drivers/block/drbd/drbd_main.c7
-rw-r--r--drivers/block/drbd/drbd_nl.c103
-rw-r--r--drivers/block/drbd/drbd_receiver.c14
-rw-r--r--drivers/block/drbd/drbd_req.h3
-rw-r--r--drivers/block/drbd/drbd_worker.c10
-rw-r--r--drivers/block/loop.c6
-rw-r--r--drivers/block/pktcdvd.c22
-rw-r--r--drivers/block/rbd.c748
-rw-r--r--drivers/block/xen-blkfront.c2
-rw-r--r--drivers/bluetooth/ath3k.c4
-rw-r--r--drivers/bluetooth/btusb.c12
-rw-r--r--drivers/bluetooth/hci_ldisc.c6
-rw-r--r--drivers/cdrom/cdrom.c56
-rw-r--r--drivers/char/agp/intel-gtt.c17
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c27
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c23
-rw-r--r--drivers/char/ramoops.c12
-rw-r--r--drivers/char/raw.c14
-rw-r--r--drivers/clk/Kconfig4
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clkdev.c (renamed from arch/arm/common/clkdev.c)13
-rw-r--r--drivers/clocksource/sh_cmt.c17
-rw-r--r--drivers/connector/connector.c1
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c2
-rw-r--r--drivers/crypto/mv_cesa.c2
-rw-r--r--drivers/crypto/omap-aes.c260
-rw-r--r--drivers/crypto/omap-sham.c374
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/Makefile4
-rw-r--r--drivers/dma/at_hdmac.c2
-rw-r--r--drivers/dma/fsldma.c10
-rw-r--r--drivers/dma/fsldma.h9
-rw-r--r--drivers/dma/imx-dma.c2
-rw-r--r--drivers/dma/imx-sdma.c178
-rw-r--r--drivers/dma/intel_mid_dma.c41
-rw-r--r--drivers/dma/ioat/Makefile2
-rw-r--r--drivers/dma/mpc512x_dma.c187
-rw-r--r--drivers/dma/mv_xor.c2
-rw-r--r--drivers/dma/pch_dma.c15
-rw-r--r--drivers/dma/ppc4xx/adma.c5
-rw-r--r--drivers/dma/shdma.c133
-rw-r--r--drivers/dma/shdma.h1
-rw-r--r--drivers/edac/amd64_edac.c2
-rw-r--r--drivers/edac/edac_core.h6
-rw-r--r--drivers/edac/edac_mc.c10
-rw-r--r--drivers/firewire/Kconfig2
-rw-r--r--drivers/firewire/core-cdev.c7
-rw-r--r--drivers/firewire/core-transaction.c58
-rw-r--r--drivers/firewire/core.h4
-rw-r--r--drivers/firewire/net.c47
-rw-r--r--drivers/firewire/nosy.c3
-rw-r--r--drivers/firewire/ohci.c719
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/cs5535-gpio.c27
-rw-r--r--drivers/gpio/gpiolib.c3
-rw-r--r--drivers/gpio/rdc321x-gpio.c2
-rw-r--r--drivers/gpio/tc35892-gpio.c389
-rw-r--r--drivers/gpio/tc3589x-gpio.c389
-rw-r--r--drivers/gpio/wm8994-gpio.c24
-rw-r--r--drivers/gpu/drm/drm_crtc.c10
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c17
-rw-r--r--drivers/gpu/drm/drm_irq.c21
-rw-r--r--drivers/gpu/drm/i915/dvo_ch7017.c2
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c26
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c525
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h11
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c40
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c34
-rw-r--r--drivers/gpu/drm/i915/intel_display.c104
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c208
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c117
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c49
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h5
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c94
-rw-r--r--drivers/gpu/drm/radeon/atom.c1
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c7
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c27
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
-rw-r--r--drivers/gpu/drm/radeon/r600.c27
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c9
-rw-r--r--drivers/gpu/drm/radeon/r600_reg.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c34
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c19
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c13
-rw-r--r--drivers/hid/Kconfig20
-rw-r--r--drivers/hid/Makefile14
-rw-r--r--drivers/hid/hid-3m-pct.c38
-rw-r--r--drivers/hid/hid-a4tech.c6
-rw-r--r--drivers/hid/hid-apple.c63
-rw-r--r--drivers/hid/hid-axff.c14
-rw-r--r--drivers/hid/hid-belkin.c4
-rw-r--r--drivers/hid/hid-cando.c2
-rw-r--r--drivers/hid/hid-cherry.c3
-rw-r--r--drivers/hid/hid-core.c123
-rw-r--r--drivers/hid/hid-cypress.c4
-rw-r--r--drivers/hid/hid-debug.c4
-rw-r--r--drivers/hid/hid-drff.c14
-rw-r--r--drivers/hid/hid-egalax.c135
-rw-r--r--drivers/hid/hid-elecom.c3
-rw-r--r--drivers/hid/hid-emsff.c161
-rw-r--r--drivers/hid/hid-gaff.c13
-rw-r--r--drivers/hid/hid-ids.h14
-rw-r--r--drivers/hid/hid-input.c39
-rw-r--r--drivers/hid/hid-kye.c4
-rw-r--r--drivers/hid/hid-lg.c15
-rw-r--r--drivers/hid/hid-lg2ff.c9
-rw-r--r--drivers/hid/hid-lg3ff.c9
-rw-r--r--drivers/hid/hid-lg4ff.c9
-rw-r--r--drivers/hid/hid-lgff.c8
-rw-r--r--drivers/hid/hid-magicmouse.c20
-rw-r--r--drivers/hid/hid-microsoft.c7
-rw-r--r--drivers/hid/hid-monterey.c3
-rw-r--r--drivers/hid/hid-mosart.c22
-rw-r--r--drivers/hid/hid-ntrig.c9
-rw-r--r--drivers/hid/hid-ortek.c3
-rw-r--r--drivers/hid/hid-petalynx.c7
-rw-r--r--drivers/hid/hid-picolcd.c58
-rw-r--r--drivers/hid/hid-pl.c16
-rw-r--r--drivers/hid/hid-prodikeys.c27
-rw-r--r--drivers/hid/hid-quanta.c2
-rw-r--r--drivers/hid/hid-roccat-kone.c404
-rw-r--r--drivers/hid/hid-roccat-kone.h19
-rw-r--r--drivers/hid/hid-roccat-koneplus.c837
-rw-r--r--drivers/hid/hid-roccat-koneplus.h224
-rw-r--r--drivers/hid/hid-roccat-pyra.c411
-rw-r--r--drivers/hid/hid-roccat-pyra.h23
-rw-r--r--drivers/hid/hid-roccat.c53
-rw-r--r--drivers/hid/hid-roccat.h5
-rw-r--r--drivers/hid/hid-samsung.c8
-rw-r--r--drivers/hid/hid-sjoy.c16
-rw-r--r--drivers/hid/hid-sony.c11
-rw-r--r--drivers/hid/hid-stantum.c2
-rw-r--r--drivers/hid/hid-sunplus.c3
-rw-r--r--drivers/hid/hid-tmff.c29
-rw-r--r--drivers/hid/hid-topseed.c1
-rw-r--r--drivers/hid/hid-wacom.c28
-rw-r--r--drivers/hid/hid-zpff.c11
-rw-r--r--drivers/hid/hid-zydacron.c11
-rw-r--r--drivers/hid/hidraw.c36
-rw-r--r--drivers/hid/usbhid/Makefile6
-rw-r--r--drivers/hid/usbhid/hid-core.c105
-rw-r--r--drivers/hid/usbhid/hid-pidff.c164
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hid/usbhid/hiddev.c241
-rw-r--r--drivers/hid/usbhid/usbhid.h1
-rw-r--r--drivers/hid/usbhid/usbkbd.c24
-rw-r--r--drivers/hwmon/Kconfig14
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/abituguru.c36
-rw-r--r--drivers/hwmon/abituguru3.c45
-rw-r--r--drivers/hwmon/adm1026.c20
-rw-r--r--drivers/hwmon/adm9240.c32
-rw-r--r--drivers/hwmon/ads7828.c4
-rw-r--r--drivers/hwmon/adt7470.c4
-rw-r--r--drivers/hwmon/applesmc.c1632
-rw-r--r--drivers/hwmon/asb100.c9
-rw-r--r--drivers/hwmon/asus_atk0110.c7
-rw-r--r--drivers/hwmon/coretemp.c11
-rw-r--r--drivers/hwmon/dme1737.c12
-rw-r--r--drivers/hwmon/ds620.c370
-rw-r--r--drivers/hwmon/emc1403.c16
-rw-r--r--drivers/hwmon/f71805f.c29
-rw-r--r--drivers/hwmon/f71882fg.c23
-rw-r--r--drivers/hwmon/fschmd.c5
-rw-r--r--drivers/hwmon/hp_accel.c13
-rw-r--r--drivers/hwmon/hwmon-vid.c11
-rw-r--r--drivers/hwmon/hwmon.c4
-rw-r--r--drivers/hwmon/ibmaem.c4
-rw-r--r--drivers/hwmon/it87.c91
-rw-r--r--drivers/hwmon/lis3lv02d.c23
-rw-r--r--drivers/hwmon/lm70.c5
-rw-r--r--drivers/hwmon/lm78.c14
-rw-r--r--drivers/hwmon/lm95241.c495
-rw-r--r--drivers/hwmon/ltc4215.c4
-rw-r--r--drivers/hwmon/pc87360.c53
-rw-r--r--drivers/hwmon/pc87427.c26
-rw-r--r--drivers/hwmon/pcf8591.c5
-rw-r--r--drivers/hwmon/pkgtemp.c7
-rw-r--r--drivers/hwmon/s3c-hwmon.c2
-rw-r--r--drivers/hwmon/sis5595.c10
-rw-r--r--drivers/hwmon/smsc47b397.c13
-rw-r--r--drivers/hwmon/smsc47m1.c31
-rw-r--r--drivers/hwmon/via-cputemp.c35
-rw-r--r--drivers/hwmon/via686a.c24
-rw-r--r--drivers/hwmon/vt1211.c30
-rw-r--r--drivers/hwmon/vt8231.c10
-rw-r--r--drivers/hwmon/w83627ehf.c23
-rw-r--r--drivers/hwmon/w83627hf.c17
-rw-r--r--drivers/hwmon/w83781d.c29
-rw-r--r--drivers/hwmon/w83792d.c44
-rw-r--r--drivers/hwmon/w83793.c38
-rw-r--r--drivers/hwmon/w83795.c4
-rw-r--r--drivers/i2c/Kconfig3
-rw-r--r--drivers/i2c/algos/Kconfig14
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c31
-rw-r--r--drivers/i2c/busses/Kconfig8
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-eg20t.c900
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-intel-mid.c2
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c6
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.h2
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c45
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c2
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c6
-rw-r--r--drivers/i2c/busses/i2c-ocores.c145
-rw-r--r--drivers/i2c/busses/i2c-omap.c83
-rw-r--r--drivers/i2c/muxes/Kconfig12
-rw-r--r--drivers/i2c/muxes/Makefile1
-rw-r--r--drivers/i2c/muxes/gpio-i2cmux.c184
-rw-r--r--drivers/idle/intel_idle.c20
-rw-r--r--drivers/infiniband/core/addr.c14
-rw-r--r--drivers/infiniband/core/ud_header.c30
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c99
-rw-r--r--drivers/infiniband/core/uverbs_marshall.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c8
-rw-r--r--drivers/infiniband/hw/mlx4/main.c10
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c10
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/Kconfig1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h12
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c51
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c62
-rw-r--r--drivers/input/Makefile2
-rw-r--r--drivers/input/apm-power.c14
-rw-r--r--drivers/input/evbug.c18
-rw-r--r--drivers/input/evdev.c132
-rw-r--r--drivers/input/ff-core.c11
-rw-r--r--drivers/input/ff-memless.c31
-rw-r--r--drivers/input/gameport/gameport.c152
-rw-r--r--drivers/input/input-mt.c170
-rw-r--r--drivers/input/input-polldev.c5
-rw-r--r--drivers/input/input.c91
-rw-r--r--drivers/input/joydev.c4
-rw-r--r--drivers/input/joystick/iforce/Makefile15
-rw-r--r--drivers/input/joystick/turbografx.c1
-rw-r--r--drivers/input/joystick/xpad.c123
-rw-r--r--drivers/input/keyboard/Kconfig45
-rw-r--r--drivers/input/keyboard/Makefile3
-rw-r--r--drivers/input/keyboard/gpio_keys_polled.c261
-rw-r--r--drivers/input/keyboard/omap-keypad.c41
-rw-r--r--drivers/input/keyboard/spear-keyboard.c344
-rw-r--r--drivers/input/keyboard/tc3589x-keypad.c472
-rw-r--r--drivers/input/keyboard/tca6416-keypad.c13
-rw-r--r--drivers/input/misc/Kconfig42
-rw-r--r--drivers/input/misc/Makefile3
-rw-r--r--drivers/input/misc/cma3000_d0x.c398
-rw-r--r--drivers/input/misc/cma3000_d0x.h42
-rw-r--r--drivers/input/misc/cma3000_d0x_i2c.c143
-rw-r--r--drivers/input/misc/pcf8574_keypad.c19
-rw-r--r--drivers/input/misc/uinput.c8
-rw-r--r--drivers/input/mouse/bcm5974.c40
-rw-r--r--drivers/input/mouse/hgpk.c695
-rw-r--r--drivers/input/mouse/hgpk.h31
-rw-r--r--drivers/input/mouse/psmouse-base.c1
-rw-r--r--drivers/input/mouse/synaptics.c129
-rw-r--r--drivers/input/mouse/synaptics.h6
-rw-r--r--drivers/input/mousedev.c10
-rw-r--r--drivers/input/serio/Kconfig1
-rw-r--r--drivers/input/serio/ams_delta_serio.c1
-rw-r--r--drivers/input/serio/ct82c710.c8
-rw-r--r--drivers/input/serio/gscps2.c2
-rw-r--r--drivers/input/serio/hil_mlc.c5
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c18
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h37
-rw-r--r--drivers/input/serio/i8042.c92
-rw-r--r--drivers/input/serio/i8042.h14
-rw-r--r--drivers/input/serio/ps2mult.c2
-rw-r--r--drivers/input/serio/serio.c155
-rw-r--r--drivers/input/tablet/wacom.h1
-rw-r--r--drivers/input/tablet/wacom_wac.c45
-rw-r--r--drivers/input/tablet/wacom_wac.h4
-rw-r--r--drivers/input/touchscreen/Kconfig22
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/bu21013_ts.c2
-rw-r--r--drivers/input/touchscreen/qt602240_ts.c21
-rw-r--r--drivers/input/touchscreen/st1232.c274
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c1
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c71
-rw-r--r--drivers/input/xen-kbdfront.c10
-rw-r--r--drivers/isdn/gigaset/capi.c1
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNinfineon.c4
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c2
-rw-r--r--drivers/isdn/hisax/avm_pci.c2
-rw-r--r--drivers/isdn/hisax/callc.c4
-rw-r--r--drivers/isdn/hisax/config.c2
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c4
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c2
-rw-r--r--drivers/isdn/hisax/hfc_pci.c4
-rw-r--r--drivers/isdn/hisax/hfc_sx.c6
-rw-r--r--drivers/isdn/hisax/hisax.h2
-rw-r--r--drivers/isdn/hisax/ipacx.c2
-rw-r--r--drivers/isdn/hisax/isar.c15
-rw-r--r--drivers/isdn/hisax/isdnl1.h1
-rw-r--r--drivers/isdn/hisax/isdnl3.c2
-rw-r--r--drivers/isdn/hisax/netjet.c10
-rw-r--r--drivers/isdn/hisax/st5481_d.c6
-rw-r--r--drivers/isdn/i4l/isdn_concap.c2
-rw-r--r--drivers/isdn/i4l/isdn_net.c20
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c26
-rw-r--r--drivers/isdn/mISDN/layer1.c10
-rw-r--r--drivers/isdn/mISDN/layer2.c12
-rw-r--r--drivers/isdn/mISDN/tei.c23
-rw-r--r--drivers/leds/Kconfig50
-rw-r--r--drivers/leds/led-class.c2
-rw-r--r--drivers/lguest/page_tables.c2
-rw-r--r--drivers/lguest/x86/core.c4
-rw-r--r--drivers/macintosh/Kconfig1
-rw-r--r--drivers/macintosh/mac_hid.c8
-rw-r--r--drivers/macintosh/macio_asic.c7
-rw-r--r--drivers/macintosh/therm_pm72.c30
-rw-r--r--drivers/md/dm-crypt.c13
-rw-r--r--drivers/md/dm-ioctl.c103
-rw-r--r--drivers/md/dm-kcopyd.c2
-rw-r--r--drivers/md/dm-log-userspace-base.c10
-rw-r--r--drivers/md/dm-mpath.c12
-rw-r--r--drivers/md/dm-raid1.c12
-rw-r--r--drivers/md/dm-table.c30
-rw-r--r--drivers/md/dm.c18
-rw-r--r--drivers/md/md.c58
-rw-r--r--drivers/md/raid10.c2
-rw-r--r--drivers/media/IR/ir-functions.c356
-rw-r--r--drivers/media/IR/ir-keytable.c710
-rw-r--r--drivers/media/IR/ir-sysfs.c362
-rw-r--r--drivers/media/IR/keymaps/rc-tbs-nec.c73
-rw-r--r--drivers/media/IR/keymaps/rc-tt-1500.c82
-rw-r--r--drivers/media/IR/rc-map.c107
-rw-r--r--drivers/media/Kconfig53
-rw-r--r--drivers/media/Makefile2
-rw-r--r--drivers/media/common/saa7146_hlp.c8
-rw-r--r--drivers/media/common/saa7146_video.c48
-rw-r--r--drivers/media/common/tuners/Kconfig8
-rw-r--r--drivers/media/common/tuners/max2165.c10
-rw-r--r--drivers/media/dvb/dm1105/Kconfig3
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c44
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c4
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c6
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c16
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c16
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.h4
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c22
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c4
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.c13
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c6
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c62
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c146
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c16
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c14
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c103
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h28
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c54
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c28
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h8
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c329
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c24
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c18
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c16
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c12
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c12
-rw-r--r--drivers/media/dvb/frontends/Kconfig15
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/af9013.c2
-rw-r--r--drivers/media/dvb/frontends/atbm8830.c8
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c51
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h2
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c10
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c10
-rw-r--r--drivers/media/dvb/frontends/ix2505v.c2
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c11
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.c615
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.h52
-rw-r--r--drivers/media/dvb/frontends/s921.c548
-rw-r--r--drivers/media/dvb/frontends/s921.h47
-rw-r--r--drivers/media/dvb/frontends/s921_core.c216
-rw-r--r--drivers/media/dvb/frontends/s921_core.h114
-rw-r--r--drivers/media/dvb/frontends/s921_module.c192
-rw-r--r--drivers/media/dvb/frontends/s921_module.h49
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c2
-rw-r--r--drivers/media/dvb/frontends/stb6100.c198
-rw-r--r--drivers/media/dvb/frontends/stv090x.c6
-rw-r--r--drivers/media/dvb/mantis/Kconfig2
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c2
-rw-r--r--drivers/media/dvb/mantis/hopper_vp3028.c6
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_common.h4
-rw-r--r--drivers/media/dvb/mantis/mantis_dvb.c17
-rw-r--r--drivers/media/dvb/mantis/mantis_input.c76
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.h2
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1033.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1034.c10
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1041.c6
-rw-r--r--drivers/media/dvb/mantis/mantis_vp2033.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_vp2040.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_vp3030.c8
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c5
-rw-r--r--drivers/media/dvb/siano/Kconfig2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c2
-rw-r--r--drivers/media/dvb/siano/smsir.c52
-rw-r--r--drivers/media/dvb/siano/smsir.h5
-rw-r--r--drivers/media/dvb/siano/smsusb.c9
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c54
-rw-r--r--drivers/media/radio/Kconfig16
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-aimslab.c16
-rw-r--r--drivers/media/radio/radio-aztech.c6
-rw-r--r--drivers/media/radio/radio-cadet.c12
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c6
-rw-r--r--drivers/media/radio/radio-gemtek.c14
-rw-r--r--drivers/media/radio/radio-maestro.c14
-rw-r--r--drivers/media/radio/radio-maxiradio.c2
-rw-r--r--drivers/media/radio/radio-miropcm20.c6
-rw-r--r--drivers/media/radio/radio-rtrack2.c10
-rw-r--r--drivers/media/radio/radio-sf16fmi.c7
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c11
-rw-r--r--drivers/media/radio/radio-si4713.c5
-rw-r--r--drivers/media/radio/radio-tea5764.c49
-rw-r--r--drivers/media/radio/radio-terratec.c8
-rw-r--r--drivers/media/radio/radio-timb.c5
-rw-r--r--drivers/media/radio/radio-trust.c18
-rw-r--r--drivers/media/radio/radio-typhoon.c16
-rw-r--r--drivers/media/radio/radio-wl1273.c2330
-rw-r--r--drivers/media/radio/radio-zoltrix.c30
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h1
-rw-r--r--drivers/media/radio/si4713-i2c.c74
-rw-r--r--drivers/media/radio/si4713-i2c.h5
-rw-r--r--drivers/media/rc/Kconfig (renamed from drivers/media/IR/Kconfig)70
-rw-r--r--drivers/media/rc/Makefile (renamed from drivers/media/IR/Makefile)8
-rw-r--r--drivers/media/rc/ene_ir.c (renamed from drivers/media/IR/ene_ir.c)131
-rw-r--r--drivers/media/rc/ene_ir.h (renamed from drivers/media/IR/ene_ir.h)3
-rw-r--r--drivers/media/rc/imon.c (renamed from drivers/media/IR/imon.c)107
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c (renamed from drivers/media/IR/ir-jvc-decoder.c)17
-rw-r--r--drivers/media/rc/ir-lirc-codec.c (renamed from drivers/media/IR/ir-lirc-codec.c)132
-rw-r--r--drivers/media/rc/ir-nec-decoder.c (renamed from drivers/media/IR/ir-nec-decoder.c)27
-rw-r--r--drivers/media/rc/ir-raw.c (renamed from drivers/media/IR/ir-raw-event.c)197
-rw-r--r--drivers/media/rc/ir-rc5-decoder.c (renamed from drivers/media/IR/ir-rc5-decoder.c)17
-rw-r--r--drivers/media/rc/ir-rc5-sz-decoder.c (renamed from drivers/media/IR/ir-rc5-sz-decoder.c)17
-rw-r--r--drivers/media/rc/ir-rc6-decoder.c (renamed from drivers/media/IR/ir-rc6-decoder.c)21
-rw-r--r--drivers/media/rc/ir-sony-decoder.c (renamed from drivers/media/IR/ir-sony-decoder.c)15
-rw-r--r--drivers/media/rc/keymaps/Kconfig (renamed from drivers/media/IR/keymaps/Kconfig)2
-rw-r--r--drivers/media/rc/keymaps/Makefile (renamed from drivers/media/IR/keymaps/Makefile)2
-rw-r--r--drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c (renamed from drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-alink-dtu-m.c (renamed from drivers/media/IR/keymaps/rc-alink-dtu-m.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-anysee.c (renamed from drivers/media/IR/keymaps/rc-anysee.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-apac-viewcomp.c (renamed from drivers/media/IR/keymaps/rc-apac-viewcomp.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-asus-pc39.c (renamed from drivers/media/IR/keymaps/rc-asus-pc39.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c (renamed from drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-a16d.c (renamed from drivers/media/IR/keymaps/rc-avermedia-a16d.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-cardbus.c (renamed from drivers/media/IR/keymaps/rc-avermedia-cardbus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-dvbt.c (renamed from drivers/media/IR/keymaps/rc-avermedia-dvbt.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c (renamed from drivers/media/IR/keymaps/rc-avermedia-m135a.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c (renamed from drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-rm-ks.c (renamed from drivers/media/IR/keymaps/rc-avermedia-rm-ks.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia.c (renamed from drivers/media/IR/keymaps/rc-avermedia.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avertv-303.c (renamed from drivers/media/IR/keymaps/rc-avertv-303.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c (renamed from drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-behold-columbus.c (renamed from drivers/media/IR/keymaps/rc-behold-columbus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c (renamed from drivers/media/IR/keymaps/rc-behold.c)78
-rw-r--r--drivers/media/rc/keymaps/rc-budget-ci-old.c (renamed from drivers/media/IR/keymaps/rc-budget-ci-old.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy-1400.c (renamed from drivers/media/IR/keymaps/rc-cinergy-1400.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy.c (renamed from drivers/media/IR/keymaps/rc-cinergy.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-nec.c (renamed from drivers/media/IR/keymaps/rc-dib0700-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-rc5.c (renamed from drivers/media/IR/keymaps/rc-dib0700-rc5.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c (renamed from drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-digittrade.c (renamed from drivers/media/IR/keymaps/rc-digittrade.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dm1105-nec.c (renamed from drivers/media/IR/keymaps/rc-dm1105-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c (renamed from drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c (renamed from drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-em-terratec.c (renamed from drivers/media/IR/keymaps/rc-em-terratec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv-fm53.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv-fm53.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv2.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv2.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-evga-indtube.c (renamed from drivers/media/IR/keymaps/rc-evga-indtube.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-eztv.c (renamed from drivers/media/IR/keymaps/rc-eztv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-flydvb.c (renamed from drivers/media/IR/keymaps/rc-flydvb.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-flyvideo.c (renamed from drivers/media/IR/keymaps/rc-flyvideo.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-fusionhdtv-mce.c (renamed from drivers/media/IR/keymaps/rc-fusionhdtv-mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-gadmei-rm008z.c (renamed from drivers/media/IR/keymaps/rc-gadmei-rm008z.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c (renamed from drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-gotview7135.c (renamed from drivers/media/IR/keymaps/rc-gotview7135.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge-new.c (renamed from drivers/media/IR/keymaps/rc-hauppauge-new.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-imon-mce.c (renamed from drivers/media/IR/keymaps/rc-imon-mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-imon-pad.c (renamed from drivers/media/IR/keymaps/rc-imon-pad.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-iodata-bctv7e.c (renamed from drivers/media/IR/keymaps/rc-iodata-bctv7e.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kaiomy.c (renamed from drivers/media/IR/keymaps/rc-kaiomy.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-315u.c (renamed from drivers/media/IR/keymaps/rc-kworld-315u.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c (renamed from drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-leadtek-y04g0051.c (renamed from drivers/media/IR/keymaps/rc-leadtek-y04g0051.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-lirc.c (renamed from drivers/media/IR/keymaps/rc-lirc.c)12
-rw-r--r--drivers/media/rc/keymaps/rc-lme2510.c (renamed from drivers/media/IR/keymaps/rc-lme2510.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-manli.c (renamed from drivers/media/IR/keymaps/rc-manli.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-digivox-ii.c (renamed from drivers/media/IR/keymaps/rc-msi-digivox-ii.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-digivox-iii.c (renamed from drivers/media/IR/keymaps/rc-msi-digivox-iii.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c (renamed from drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere.c (renamed from drivers/media/IR/keymaps/rc-msi-tvanywhere.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c (renamed from drivers/media/IR/keymaps/rc-nebula.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c (renamed from drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-norwood.c (renamed from drivers/media/IR/keymaps/rc-norwood.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-npgtech.c (renamed from drivers/media/IR/keymaps/rc-npgtech.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pctv-sedna.c (renamed from drivers/media/IR/keymaps/rc-pctv-sedna.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-color.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-color.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-grey.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-grey.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-002t.c77
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-mk12.c (renamed from drivers/media/IR/keymaps/rc-pixelview-mk12.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-new.c (renamed from drivers/media/IR/keymaps/rc-pixelview-new.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview.c (renamed from drivers/media/IR/keymaps/rc-pixelview.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-powercolor-real-angel.c (renamed from drivers/media/IR/keymaps/rc-powercolor-real-angel.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-proteus-2309.c (renamed from drivers/media/IR/keymaps/rc-proteus-2309.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-purpletv.c (renamed from drivers/media/IR/keymaps/rc-purpletv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pv951.c (renamed from drivers/media/IR/keymaps/rc-pv951.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c (renamed from drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c)48
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-tv.c (renamed from drivers/media/IR/keymaps/rc-rc5-tv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-rc6-mce.c (renamed from drivers/media/IR/keymaps/rc-rc6-mce.c)31
-rw-r--r--drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c (renamed from drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-streamzap.c (renamed from drivers/media/IR/keymaps/rc-streamzap.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tbs-nec.c75
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c (renamed from drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-slim.c (renamed from drivers/media/IR/keymaps/rc-terratec-slim.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tevii-nec.c (renamed from drivers/media/IR/keymaps/rc-tevii-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-total-media-in-hand.c (renamed from drivers/media/IR/keymaps/rc-total-media-in-hand.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-trekstor.c (renamed from drivers/media/IR/keymaps/rc-trekstor.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tt-1500.c82
-rw-r--r--drivers/media/rc/keymaps/rc-twinhan1027.c (renamed from drivers/media/IR/keymaps/rc-twinhan1027.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-m1f.c92
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-s350.c (renamed from drivers/media/IR/keymaps/rc-videomate-s350.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-tv-pvr.c (renamed from drivers/media/IR/keymaps/rc-videomate-tv-pvr.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c (renamed from drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c (renamed from drivers/media/IR/keymaps/rc-winfast.c)10
-rw-r--r--drivers/media/rc/lirc_dev.c (renamed from drivers/media/IR/lirc_dev.c)37
-rw-r--r--drivers/media/rc/mceusb.c (renamed from drivers/media/IR/mceusb.c)266
-rw-r--r--drivers/media/rc/nuvoton-cir.c (renamed from drivers/media/IR/nuvoton-cir.c)104
-rw-r--r--drivers/media/rc/nuvoton-cir.h (renamed from drivers/media/IR/nuvoton-cir.h)3
-rw-r--r--drivers/media/rc/rc-core-priv.h (renamed from drivers/media/IR/ir-core-priv.h)34
-rw-r--r--drivers/media/rc/rc-loopback.c260
-rw-r--r--drivers/media/rc/rc-main.c1135
-rw-r--r--drivers/media/rc/streamzap.c (renamed from drivers/media/IR/streamzap.c)88
-rw-r--r--drivers/media/rc/winbond-cir.c (renamed from drivers/input/misc/winbond-cir.c)886
-rw-r--r--drivers/media/video/Kconfig38
-rw-r--r--drivers/media/video/Makefile12
-rw-r--r--drivers/media/video/arv.c2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--drivers/media/video/au0828/au0828-video.c118
-rw-r--r--drivers/media/video/au0828/au0828.h6
-rw-r--r--drivers/media/video/bt8xx/Kconfig4
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c22
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c165
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c238
-rw-r--r--drivers/media/video/bt8xx/bttv.h1
-rw-r--r--drivers/media/video/bt8xx/bttvp.h34
-rw-r--r--drivers/media/video/bw-qcam.c2
-rw-r--r--drivers/media/video/c-qcam.c2
-rw-r--r--drivers/media/video/cafe_ccic.c14
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c38
-rw-r--r--drivers/media/video/cx18/Kconfig3
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c8
-rw-r--r--drivers/media/video/cx18/cx18-cards.c64
-rw-r--r--drivers/media/video/cx18/cx18-controls.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c11
-rw-r--r--drivers/media/video/cx18/cx18-driver.h13
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c64
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c10
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c47
-rw-r--r--drivers/media/video/cx18/cx18-streams.h3
-rw-r--r--drivers/media/video/cx231xx/Kconfig19
-rw-r--r--drivers/media/video/cx231xx/Makefile5
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c7
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c69
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c12
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c40
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c112
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c12
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h26
-rw-r--r--drivers/media/video/cx2341x.c8
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c35
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c70
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c37
-rw-r--r--drivers/media/video/cx23885/cx23885.h6
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c19
-rw-r--r--drivers/media/video/cx25840/cx25840-ir.c2
-rw-r--r--drivers/media/video/cx88/Kconfig3
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c99
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c18
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c8
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c1
-rw-r--r--drivers/media/video/cx88/cx88-input.c282
-rw-r--r--drivers/media/video/cx88/cx88-video.c46
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c1
-rw-r--r--drivers/media/video/cx88/cx88.h6
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c3
-rw-r--r--drivers/media/video/davinci/vpif_capture.c1
-rw-r--r--drivers/media/video/davinci/vpif_display.c2
-rw-r--r--drivers/media/video/em28xx/Kconfig5
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c94
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c16
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c78
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c32
-rw-r--r--drivers/media/video/em28xx/em28xx.h4
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c3
-rw-r--r--drivers/media/video/fsl-viu.c28
-rw-r--r--drivers/media/video/gspca/cpia1.c12
-rw-r--r--drivers/media/video/gspca/gspca.c64
-rw-r--r--drivers/media/video/gspca/gspca.h4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c2
-rw-r--r--drivers/media/video/gspca/ov519.c1683
-rw-r--r--drivers/media/video/gspca/ov534.c14
-rw-r--r--drivers/media/video/gspca/ov534_9.c1
-rw-r--r--drivers/media/video/gspca/pac207.c4
-rw-r--r--drivers/media/video/gspca/pac7302.c2
-rw-r--r--drivers/media/video/gspca/pac7311.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c141
-rw-r--r--drivers/media/video/gspca/sonixb.c236
-rw-r--r--drivers/media/video/gspca/sonixj.c434
-rw-r--r--drivers/media/video/gspca/spca561.c2
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/sq930x.c28
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c57
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h11
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c18
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h3
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h4
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c291
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.h13
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h9
-rw-r--r--drivers/media/video/gspca/t613.c2
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c74
-rw-r--r--drivers/media/video/gspca/w996Xcf.c325
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c194
-rw-r--r--drivers/media/video/gspca/zc3xx.c292
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c53
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h6
-rw-r--r--drivers/media/video/hexium_gemini.c18
-rw-r--r--drivers/media/video/hexium_orion.c18
-rw-r--r--drivers/media/video/imx074.c1
-rw-r--r--drivers/media/video/ir-kbd-i2c.c76
-rw-r--r--drivers/media/video/ivtv/Kconfig3
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c28
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c65
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c115
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h5
-rw-r--r--drivers/media/video/mem2mem_testdev.c21
-rw-r--r--drivers/media/video/meye.c14
-rw-r--r--drivers/media/video/mt9m001.c1
-rw-r--r--drivers/media/video/mt9m111.c1
-rw-r--r--drivers/media/video/mt9t031.c1
-rw-r--r--drivers/media/video/mt9v022.c1
-rw-r--r--drivers/media/video/mx1_camera.c7
-rw-r--r--drivers/media/video/mx2_camera.c5
-rw-r--r--drivers/media/video/mx3_camera.c5
-rw-r--r--drivers/media/video/mxb.c20
-rw-r--r--drivers/media/video/omap/omap_vout.c1
-rw-r--r--drivers/media/video/omap1_camera.c4
-rw-r--r--drivers/media/video/ov2640.c1205
-rw-r--r--drivers/media/video/ov772x.c17
-rw-r--r--drivers/media/video/ov9640.c19
-rw-r--r--drivers/media/video/pms.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c4
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c7
-rw-r--r--drivers/media/video/pwc/pwc-if.c68
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c30
-rw-r--r--drivers/media/video/pwc/pwc.h1
-rw-r--r--drivers/media/video/pxa_camera.c2
-rw-r--r--drivers/media/video/rj54n1cb0c.c1
-rw-r--r--drivers/media/video/s2255drv.c43
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c53
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c56
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h24
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h3
-rw-r--r--drivers/media/video/saa6588.c14
-rw-r--r--drivers/media/video/saa7115.c11
-rw-r--r--drivers/media/video/saa7134/Kconfig2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c156
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c69
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c435
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c12
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c26
-rw-r--r--drivers/media/video/saa7134/saa7134.h26
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c123
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c92
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c16
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c40
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c33
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c12
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c4
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c37
-rw-r--r--drivers/media/video/saa7164/saa7164.h17
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c4
-rw-r--r--drivers/media/video/sh_vou.c15
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c3
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h4
-rw-r--r--drivers/media/video/soc_camera.c139
-rw-r--r--drivers/media/video/sr030pc30.c2
-rw-r--r--drivers/media/video/stk-webcam.c148
-rw-r--r--drivers/media/video/tea6415c.c2
-rw-r--r--drivers/media/video/timblogiw.c893
-rw-r--r--drivers/media/video/tlg2300/Kconfig4
-rw-r--r--drivers/media/video/usbvideo/Kconfig45
-rw-r--r--drivers/media/video/usbvideo/Makefile4
-rw-r--r--drivers/media/video/usbvideo/ibmcam.c3977
-rw-r--r--drivers/media/video/usbvideo/konicawc.c992
-rw-r--r--drivers/media/video/usbvideo/ultracam.c685
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c1860
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c1635
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c61
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c625
-rw-r--r--drivers/media/video/usbvision/usbvision.h267
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c48
-rw-r--r--drivers/media/video/uvc/uvc_queue.c133
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c192
-rw-r--r--drivers/media/video/uvc/uvc_video.c3
-rw-r--r--drivers/media/video/uvc/uvcvideo.h10
-rw-r--r--drivers/media/video/v4l1-compat.c1277
-rw-r--r--drivers/media/video/v4l2-common.c21
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c326
-rw-r--r--drivers/media/video/v4l2-ctrls.c55
-rw-r--r--drivers/media/video/v4l2-dev.c69
-rw-r--r--drivers/media/video/v4l2-device.c1
-rw-r--r--drivers/media/video/v4l2-ioctl.c86
-rw-r--r--drivers/media/video/via-camera.c15
-rw-r--r--drivers/media/video/videobuf-core.c30
-rw-r--r--drivers/media/video/videobuf-dma-sg.c34
-rw-r--r--drivers/media/video/vino.c7
-rw-r--r--drivers/media/video/vivi.c12
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/wm8775.c104
-rw-r--r--drivers/media/video/zoran/zoran.h107
-rw-r--r--drivers/media/video/zoran/zoran_card.c7
-rw-r--r--drivers/media/video/zoran/zoran_device.c2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c327
-rw-r--r--drivers/mfd/Kconfig16
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/ab8500-core.c2
-rw-r--r--drivers/mfd/tc35892.c345
-rw-r--r--drivers/mfd/tc3589x.c422
-rw-r--r--drivers/mfd/timberdale.c61
-rw-r--r--drivers/mfd/timberdale.h2
-rw-r--r--drivers/mfd/wl1273-core.c148
-rw-r--r--drivers/mfd/wm831x-core.c8
-rw-r--r--drivers/mfd/wm8994-core.c93
-rw-r--r--drivers/mmc/host/Kconfig6
-rw-r--r--drivers/mmc/host/mmci.c207
-rw-r--r--drivers/mmc/host/mmci.h9
-rw-r--r--drivers/mmc/host/msm_sdcc.c139
-rw-r--r--drivers/mmc/host/msm_sdcc.h8
-rw-r--r--drivers/mmc/host/sh_mmcif.c449
-rw-r--r--drivers/mtd/Kconfig19
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c54
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c94
-rw-r--r--drivers/mtd/chips/cfi_util.c2
-rw-r--r--drivers/mtd/chips/fwh_lock.h2
-rw-r--r--drivers/mtd/devices/block2mtd.c10
-rw-r--r--drivers/mtd/devices/m25p80.c33
-rw-r--r--drivers/mtd/devices/sst25l.c4
-rw-r--r--drivers/mtd/maps/amd76xrom.c7
-rw-r--r--drivers/mtd/maps/bcm963xx-flash.c5
-rw-r--r--drivers/mtd/maps/ck804xrom.c7
-rw-r--r--drivers/mtd/maps/esb2rom.c9
-rw-r--r--drivers/mtd/maps/ichxrom.c9
-rw-r--r--drivers/mtd/maps/physmap_of.c4
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c2
-rw-r--r--drivers/mtd/maps/scx200_docflash.c5
-rw-r--r--drivers/mtd/maps/tqm8xxl.c2
-rw-r--r--drivers/mtd/mtdchar.c12
-rw-r--r--drivers/mtd/mtdpart.c10
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c2
-rw-r--r--drivers/mtd/nand/fsmc_nand.c89
-rw-r--r--drivers/mtd/nand/jz4740_nand.c57
-rw-r--r--drivers/mtd/nand/mxc_nand.c2
-rw-r--r--drivers/mtd/nand/nand_base.c11
-rw-r--r--drivers/mtd/nand/nand_bbt.c3
-rw-r--r--drivers/mtd/nand/nandsim.c39
-rw-r--r--drivers/mtd/nand/omap2.c1
-rw-r--r--drivers/mtd/nand/pasemi_nand.c2
-rw-r--r--drivers/mtd/onenand/omap2.c15
-rw-r--r--drivers/mtd/onenand/onenand_base.c51
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c6
-rw-r--r--drivers/mtd/onenand/samsung.c7
-rw-r--r--drivers/mtd/ubi/io.c37
-rw-r--r--drivers/mtd/ubi/scan.c4
-rw-r--r--drivers/mtd/ubi/vtbl.c6
-rw-r--r--drivers/net/3c501.c4
-rw-r--r--drivers/net/3c503.c4
-rw-r--r--drivers/net/3c507.c6
-rw-r--r--drivers/net/3c515.c2
-rw-r--r--drivers/net/3c527.c6
-rw-r--r--drivers/net/8139too.c3
-rw-r--r--drivers/net/82596.c2
-rw-r--r--drivers/net/Kconfig256
-rw-r--r--drivers/net/Space.c5
-rw-r--r--drivers/net/arm/am79c961a.c9
-rw-r--r--drivers/net/arm/w90p910_ether.c2
-rw-r--r--drivers/net/at1700.c8
-rw-r--r--drivers/net/atarilance.c2
-rw-r--r--drivers/net/atl1c/atl1c_main.c41
-rw-r--r--drivers/net/atl1e/atl1e_main.c2
-rw-r--r--drivers/net/atlx/atl1.c12
-rw-r--r--drivers/net/atlx/atl2.c4
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/ax88796.c8
-rw-r--r--drivers/net/b44.c11
-rw-r--r--drivers/net/bcm63xx_enet.c2
-rw-r--r--drivers/net/benet/be.h41
-rw-r--r--drivers/net/benet/be_cmds.c146
-rw-r--r--drivers/net/benet/be_cmds.h42
-rw-r--r--drivers/net/benet/be_ethtool.c4
-rw-r--r--drivers/net/benet/be_hw.h39
-rw-r--r--drivers/net/benet/be_main.c254
-rw-r--r--drivers/net/bna/bfa_defs.h22
-rw-r--r--drivers/net/bna/bfa_defs_mfg_comm.h22
-rw-r--r--drivers/net/bna/bfa_ioc.c1219
-rw-r--r--drivers/net/bna/bfa_ioc.h49
-rw-r--r--drivers/net/bna/bfa_ioc_ct.c102
-rw-r--r--drivers/net/bna/bfi_ctreg.h41
-rw-r--r--drivers/net/bna/bna.h6
-rw-r--r--drivers/net/bna/bna_ctrl.c377
-rw-r--r--drivers/net/bna/bna_txrx.c44
-rw-r--r--drivers/net/bna/bna_types.h11
-rw-r--r--drivers/net/bna/bnad.c427
-rw-r--r--drivers/net/bna/bnad.h31
-rw-r--r--drivers/net/bna/bnad_ethtool.c8
-rw-r--r--drivers/net/bnx2.c121
-rw-r--r--drivers/net/bnx2.h2
-rw-r--r--drivers/net/bnx2x/Makefile2
-rw-r--r--drivers/net/bnx2x/bnx2x.h165
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c197
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h73
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.c2118
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.h196
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c357
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h327
-rw-r--r--drivers/net/bnx2x/bnx2x_init_ops.h4
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c666
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h56
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c700
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h52
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c13
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.h2
-rw-r--r--drivers/net/bonding/Makefile2
-rw-r--r--drivers/net/bonding/bond_3ad.c3
-rw-r--r--drivers/net/bonding/bond_alb.c36
-rw-r--r--drivers/net/bonding/bond_alb.h38
-rw-r--r--drivers/net/bonding/bond_debugfs.c146
-rw-r--r--drivers/net/bonding/bond_ipv6.c7
-rw-r--r--drivers/net/bonding/bond_main.c89
-rw-r--r--drivers/net/bonding/bonding.h27
-rw-r--r--drivers/net/caif/caif_shm_u5500.c4
-rw-r--r--drivers/net/caif/caif_shmcore.c2
-rw-r--r--drivers/net/can/Kconfig21
-rw-r--r--drivers/net/can/Makefile1
-rw-r--r--drivers/net/can/janz-ican3.c9
-rw-r--r--drivers/net/can/mscan/mscan.c2
-rw-r--r--drivers/net/can/pch_can.c1350
-rw-r--r--drivers/net/can/sja1000/plx_pci.c2
-rw-r--r--drivers/net/can/sja1000/sja1000_of_platform.c8
-rw-r--r--drivers/net/can/slcan.c756
-rw-r--r--drivers/net/cassini.c6
-rw-r--r--drivers/net/chelsio/sge.c10
-rw-r--r--drivers/net/cnic.c755
-rw-r--r--drivers/net/cnic.h27
-rw-r--r--drivers/net/cnic_defs.h2095
-rw-r--r--drivers/net/cnic_if.h26
-rw-r--r--drivers/net/cris/eth_v10.c34
-rw-r--r--drivers/net/cxgb3/ael1002.c24
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c6
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c6
-rw-r--r--drivers/net/cxgb3/t3_hw.c2
-rw-r--r--drivers/net/cxgb4/cxgb4.h4
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c140
-rw-r--r--drivers/net/cxgb4/sge.c22
-rw-r--r--drivers/net/cxgb4/t4_hw.c95
-rw-r--r--drivers/net/cxgb4/t4fw_api.h1
-rw-r--r--drivers/net/cxgb4vf/adapter.h2
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c47
-rw-r--r--drivers/net/cxgb4vf/sge.c9
-rw-r--r--drivers/net/cxgb4vf/t4vf_hw.c7
-rw-r--r--drivers/net/depca.c2
-rw-r--r--drivers/net/dm9000.c2
-rw-r--r--drivers/net/e1000/e1000_hw.c20
-rw-r--r--drivers/net/e1000/e1000_main.c18
-rw-r--r--drivers/net/e1000/e1000_param.c13
-rw-r--r--drivers/net/e1000e/82571.c189
-rw-r--r--drivers/net/e1000e/defines.h9
-rw-r--r--drivers/net/e1000e/e1000.h4
-rw-r--r--drivers/net/e1000e/es2lan.c8
-rw-r--r--drivers/net/e1000e/ethtool.c147
-rw-r--r--drivers/net/e1000e/ich8lan.c23
-rw-r--r--drivers/net/e1000e/lib.c141
-rw-r--r--drivers/net/e1000e/netdev.c107
-rw-r--r--drivers/net/e1000e/param.c2
-rw-r--r--drivers/net/e1000e/phy.c50
-rw-r--r--drivers/net/e2100.c2
-rw-r--r--drivers/net/eepro.c11
-rw-r--r--drivers/net/eexpress.c2
-rw-r--r--drivers/net/ehea/ehea.h15
-rw-r--r--drivers/net/ehea/ehea_ethtool.c34
-rw-r--r--drivers/net/ehea/ehea_main.c440
-rw-r--r--drivers/net/ehea/ehea_phyp.c40
-rw-r--r--drivers/net/ehea/ehea_qmr.c89
-rw-r--r--drivers/net/enic/enic.h6
-rw-r--r--drivers/net/enic/enic_main.c250
-rw-r--r--drivers/net/enic/enic_res.h1
-rw-r--r--drivers/net/enic/vnic_vic.h31
-rw-r--r--drivers/net/epic100.c4
-rw-r--r--drivers/net/ethoc.c160
-rw-r--r--drivers/net/fec_mpc52xx.c19
-rw-r--r--drivers/net/forcedeth.c1134
-rw-r--r--drivers/net/gianfar.c10
-rw-r--r--drivers/net/hamachi.c4
-rw-r--r--drivers/net/hp.c6
-rw-r--r--drivers/net/ibm_newemac/core.c2
-rw-r--r--drivers/net/ibmveth.c7
-rw-r--r--drivers/net/ifb.c48
-rw-r--r--drivers/net/igb/e1000_82575.c37
-rw-r--r--drivers/net/igb/e1000_82575.h5
-rw-r--r--drivers/net/igb/e1000_defines.h7
-rw-r--r--drivers/net/igb/e1000_hw.h6
-rw-r--r--drivers/net/igb/e1000_nvm.c93
-rw-r--r--drivers/net/igb/e1000_nvm.h2
-rw-r--r--drivers/net/igb/e1000_phy.c11
-rw-r--r--drivers/net/igb/e1000_regs.h1
-rw-r--r--drivers/net/igb/igb.h1
-rw-r--r--drivers/net/igb/igb_main.c100
-rw-r--r--drivers/net/igbvf/Makefile2
-rw-r--r--drivers/net/igbvf/defines.h2
-rw-r--r--drivers/net/igbvf/ethtool.c9
-rw-r--r--drivers/net/igbvf/igbvf.h4
-rw-r--r--drivers/net/igbvf/mbx.c2
-rw-r--r--drivers/net/igbvf/mbx.h2
-rw-r--r--drivers/net/igbvf/netdev.c33
-rw-r--r--drivers/net/igbvf/regs.h2
-rw-r--r--drivers/net/igbvf/vf.c6
-rw-r--r--drivers/net/igbvf/vf.h4
-rw-r--r--drivers/net/irda/act200l-sir.c2
-rw-r--r--drivers/net/irda/bfin_sir.h2
-rw-r--r--drivers/net/irda/donauboe.c4
-rw-r--r--drivers/net/irda/mcs7780.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c2
-rw-r--r--drivers/net/iseries_veth.c27
-rw-r--r--drivers/net/ixgb/ixgb_main.c61
-rw-r--r--drivers/net/ixgb/ixgb_param.c21
-rw-r--r--drivers/net/ixgbe/Makefile2
-rw-r--r--drivers/net/ixgbe/ixgbe.h122
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c58
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c138
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c256
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h10
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.c17
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.h3
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c55
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c297
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c15
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c2088
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.c42
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c52
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h5
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c57
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h45
-rw-r--r--drivers/net/ixgbe/ixgbe_x540.c724
-rw-r--r--drivers/net/ixgbevf/Makefile2
-rw-r--r--drivers/net/ixgbevf/defines.h3
-rw-r--r--drivers/net/ixgbevf/ethtool.c18
-rw-r--r--drivers/net/ixgbevf/ixgbevf.h6
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c27
-rw-r--r--drivers/net/ixgbevf/mbx.c2
-rw-r--r--drivers/net/ixgbevf/mbx.h2
-rw-r--r--drivers/net/ixgbevf/regs.h2
-rw-r--r--drivers/net/ixgbevf/vf.c8
-rw-r--r--drivers/net/ixgbevf/vf.h3
-rw-r--r--drivers/net/jme.c20
-rw-r--r--drivers/net/ks8851.c33
-rw-r--r--drivers/net/ksz884x.c22
-rw-r--r--drivers/net/lance.c2
-rw-r--r--drivers/net/lib82596.c2
-rw-r--r--drivers/net/lib8390.c24
-rw-r--r--drivers/net/ll_temac_main.c4
-rw-r--r--drivers/net/macvlan.c113
-rw-r--r--drivers/net/macvtap.c3
-rw-r--r--drivers/net/mlx4/fw.c4
-rw-r--r--drivers/net/mv643xx_eth.c9
-rw-r--r--drivers/net/myri10ge/myri10ge.c8
-rw-r--r--drivers/net/ne-h8300.c12
-rw-r--r--drivers/net/netxen/netxen_nic.h5
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c26
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c21
-rw-r--r--drivers/net/netxen/netxen_nic_init.c7
-rw-r--r--drivers/net/netxen/netxen_nic_main.c12
-rw-r--r--drivers/net/ni52.c4
-rw-r--r--drivers/net/ni65.c4
-rw-r--r--drivers/net/niu.c4
-rw-r--r--drivers/net/pch_gbe/pch_gbe_ethtool.c19
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c12
-rw-r--r--drivers/net/pcmcia/axnet_cs.c19
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c2
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c1
-rw-r--r--drivers/net/phy/Kconfig2
-rw-r--r--drivers/net/phy/icplus.c59
-rw-r--r--drivers/net/phy/phy.c4
-rw-r--r--drivers/net/ppp_generic.c21
-rw-r--r--drivers/net/pppoe.c2
-rw-r--r--drivers/net/pptp.c5
-rw-r--r--drivers/net/pxa168_eth.c9
-rw-r--r--drivers/net/qla3xxx.c8
-rw-r--r--drivers/net/qlcnic/qlcnic.h43
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c28
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c157
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h27
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c91
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c123
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c89
-rw-r--r--drivers/net/qlge/qlge.h5
-rw-r--r--drivers/net/qlge/qlge_dbg.c21
-rw-r--r--drivers/net/qlge/qlge_ethtool.c19
-rw-r--r--drivers/net/qlge/qlge_main.c22
-rw-r--r--drivers/net/qlge/qlge_mpi.c14
-rw-r--r--drivers/net/r8169.c1662
-rw-r--r--drivers/net/s2io.c79
-rw-r--r--drivers/net/s2io.h9
-rw-r--r--drivers/net/sc92031.c3
-rw-r--r--drivers/net/sfc/efx.c81
-rw-r--r--drivers/net/sfc/efx.h7
-rw-r--r--drivers/net/sfc/ethtool.c168
-rw-r--r--drivers/net/sfc/falcon.c208
-rw-r--r--drivers/net/sfc/falcon_boards.c120
-rw-r--r--drivers/net/sfc/falcon_xmac.c14
-rw-r--r--drivers/net/sfc/filter.c255
-rw-r--r--drivers/net/sfc/filter.h149
-rw-r--r--drivers/net/sfc/io.h153
-rw-r--r--drivers/net/sfc/mcdi.c3
-rw-r--r--drivers/net/sfc/mcdi_phy.c1
-rw-r--r--drivers/net/sfc/mdio_10g.c1
-rw-r--r--drivers/net/sfc/mtd.c98
-rw-r--r--drivers/net/sfc/net_driver.h89
-rw-r--r--drivers/net/sfc/nic.c96
-rw-r--r--drivers/net/sfc/nic.h12
-rw-r--r--drivers/net/sfc/qt202x_phy.c6
-rw-r--r--drivers/net/sfc/rx.c30
-rw-r--r--drivers/net/sfc/siena.c10
-rw-r--r--drivers/net/sfc/spi.h5
-rw-r--r--drivers/net/sfc/tenxpress.c2
-rw-r--r--drivers/net/sfc/tx.c122
-rw-r--r--drivers/net/sh_eth.c245
-rw-r--r--drivers/net/sh_eth.h1
-rw-r--r--drivers/net/sis190.c3
-rw-r--r--drivers/net/skfp/skfddi.c2
-rw-r--r--drivers/net/skfp/smt.c4
-rw-r--r--drivers/net/skge.c54
-rw-r--r--drivers/net/sky2.c157
-rw-r--r--drivers/net/sky2.h42
-rw-r--r--drivers/net/smc-ultra.c8
-rw-r--r--drivers/net/starfire.c2
-rw-r--r--drivers/net/stmmac/stmmac.h40
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c16
-rw-r--r--drivers/net/stmmac/stmmac_main.c271
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c8
-rw-r--r--drivers/net/sundance.c27
-rw-r--r--drivers/net/sungem.c14
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/sunlance.c10
-rw-r--r--drivers/net/tehuti.c4
-rw-r--r--drivers/net/tg3.c424
-rw-r--r--drivers/net/tg3.h42
-rw-r--r--drivers/net/tokenring/ibmtr.c5
-rw-r--r--drivers/net/tulip/de2104x.c18
-rw-r--r--drivers/net/tulip/dmfe.c6
-rw-r--r--drivers/net/tulip/tulip_core.c15
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/typhoon.c1
-rw-r--r--drivers/net/usb/Kconfig19
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/asix.c4
-rw-r--r--drivers/net/usb/cdc_ether.c4
-rw-r--r--drivers/net/usb/cdc_ncm.c1213
-rw-r--r--drivers/net/usb/hso.c44
-rw-r--r--drivers/net/usb/ipheth.c2
-rw-r--r--drivers/net/usb/mcs7830.c14
-rw-r--r--drivers/net/usb/pegasus.c4
-rw-r--r--drivers/net/usb/sierra_net.c5
-rw-r--r--drivers/net/usb/smsc95xx.c7
-rw-r--r--drivers/net/usb/usbnet.c48
-rw-r--r--drivers/net/veth.c4
-rw-r--r--drivers/net/via-rhine.c326
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c965
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c174
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h73
-rw-r--r--drivers/net/vxge/vxge-config.c3604
-rw-r--r--drivers/net/vxge/vxge-config.h169
-rw-r--r--drivers/net/vxge/vxge-ethtool.c112
-rw-r--r--drivers/net/vxge/vxge-main.c1106
-rw-r--r--drivers/net/vxge/vxge-main.h86
-rw-r--r--drivers/net/vxge/vxge-reg.h33
-rw-r--r--drivers/net/vxge/vxge-traffic.c775
-rw-r--r--drivers/net/vxge/vxge-traffic.h49
-rw-r--r--drivers/net/vxge/vxge-version.h33
-rw-r--r--drivers/net/wan/dscc4.c6
-rw-r--r--drivers/net/wan/hd64572.c5
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wd.c2
-rw-r--r--drivers/net/wimax/i2400m/driver.c96
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h19
-rw-r--r--drivers/net/wimax/i2400m/sdio.c1
-rw-r--r--drivers/net/wimax/i2400m/usb.c1
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/airo.c20
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c6
-rw-r--r--drivers/net/wireless/ath/ath.h111
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig18
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c219
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c40
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h292
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c28
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c1574
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h7
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c34
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c24
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c180
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c139
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c409
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c11
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c774
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c327
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c571
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c754
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c696
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c1221
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h1169
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c107
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c305
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c220
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c144
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h104
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c605
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c3201
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h82
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c289
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c123
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c166
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c344
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h78
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h943
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h72
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c132
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c59
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c83
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c225
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h90
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c302
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c295
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c370
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c236
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h38
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c342
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c120
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c656
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c301
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h81
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c172
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c211
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c601
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c110
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c96
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c120
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h36
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c32
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c856
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c3
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h13
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c56
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c22
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c27
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h24
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c82
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c58
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
-rw-r--r--drivers/net/wireless/ath/debug.c15
-rw-r--r--drivers/net/wireless/ath/debug.h90
-rw-r--r--drivers/net/wireless/ath/key.c39
-rw-r--r--drivers/net/wireless/ath/main.c20
-rw-r--r--drivers/net/wireless/ath/regd.c8
-rw-r--r--drivers/net/wireless/atmel.c6
-rw-r--r--drivers/net/wireless/b43/Kconfig13
-rw-r--r--drivers/net/wireless/b43/Makefile8
-rw-r--r--drivers/net/wireless/b43/b43.h21
-rw-r--r--drivers/net/wireless/b43/dma.c5
-rw-r--r--drivers/net/wireless/b43/main.c68
-rw-r--r--drivers/net/wireless/b43/phy_common.c22
-rw-r--r--drivers/net/wireless/b43/phy_common.h8
-rw-r--r--drivers/net/wireless/b43/phy_n.c594
-rw-r--r--drivers/net/wireless/b43/phy_n.h2
-rw-r--r--drivers/net/wireless/b43/radio_2055.c502
-rw-r--r--drivers/net/wireless/b43/radio_2056.c9062
-rw-r--r--drivers/net/wireless/b43/radio_2056.h1084
-rw-r--r--drivers/net/wireless/b43/rfkill.c19
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c228
-rw-r--r--drivers/net/wireless/b43legacy/main.c47
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c1
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c97
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c369
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c140
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c465
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c230
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c373
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c136
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c642
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c160
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c614
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c971
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h96
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h91
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c662
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.h79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c190
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c88
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c2
-rw-r--r--drivers/net/wireless/libertas/cfg.c9
-rw-r--r--drivers/net/wireless/libertas/cmd.c8
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c1
-rw-r--r--drivers/net/wireless/libertas/if_spi.c3
-rw-r--r--drivers/net/wireless/libertas/if_usb.c13
-rw-r--r--drivers/net/wireless/libertas/main.c5
-rw-r--r--drivers/net/wireless/libertas/rx.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwl8k.c670
-rw-r--r--drivers/net/wireless/orinoco/main.c18
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c14
-rw-r--r--drivers/net/wireless/orinoco/scan.c8
-rw-r--r--drivers/net/wireless/orinoco/scan.h1
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c14
-rw-r--r--drivers/net/wireless/orinoco/wext.c12
-rw-r--r--drivers/net/wireless/p54/p54usb.c8
-rw-r--r--drivers/net/wireless/ray_cs.c18
-rw-r--r--drivers/net/wireless/rndis_wlan.c402
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig72
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c144
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c150
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c98
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h218
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c223
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c215
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c363
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h114
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c15
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c104
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c61
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c15
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c270
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h74
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c305
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c185
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h64
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c107
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h38
-rw-r--r--drivers/net/wireless/rtl818x/Makefile9
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/Makefile5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c (renamed from drivers/net/wireless/rtl818x/rtl8180_dev.c)8
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/grf5101.c (renamed from drivers/net/wireless/rtl818x/rtl8180_grf5101.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/grf5101.h (renamed from drivers/net/wireless/rtl818x/rtl8180_grf5101.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/max2820.c (renamed from drivers/net/wireless/rtl818x/rtl8180_max2820.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/max2820.h (renamed from drivers/net/wireless/rtl818x/rtl8180_max2820.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8180.h (renamed from drivers/net/wireless/rtl818x/rtl8180.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225.c (renamed from drivers/net/wireless/rtl818x/rtl8180_rtl8225.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225.h (renamed from drivers/net/wireless/rtl818x/rtl8180_rtl8225.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/sa2400.c (renamed from drivers/net/wireless/rtl818x/rtl8180_sa2400.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/sa2400.h (renamed from drivers/net/wireless/rtl818x/rtl8180_sa2400.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/Makefile5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c (renamed from drivers/net/wireless/rtl818x/rtl8187_dev.c)146
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.c (renamed from drivers/net/wireless/rtl818x/rtl8187_leds.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.h (renamed from drivers/net/wireless/rtl818x/rtl8187_leds.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.c (renamed from drivers/net/wireless/rtl818x/rtl8187_rfkill.c)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.h (renamed from drivers/net/wireless/rtl818x/rtl8187_rfkill.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8187.h (renamed from drivers/net/wireless/rtl818x/rtl8187.h)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.c (renamed from drivers/net/wireless/rtl818x/rtl8187_rtl8225.c)24
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.h (renamed from drivers/net/wireless/rtl818x/rtl8187_rtl8225.h)0
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig15
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile13
-rw-r--r--drivers/net/wireless/rtlwifi/base.c956
-rw-r--r--drivers/net/wireless/rtlwifi/base.h120
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c291
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h53
-rw-r--r--drivers/net/wireless/rtlwifi/core.c1029
-rw-r--r--drivers/net/wireless/rtlwifi/core.h42
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c50
-rw-r--r--drivers/net/wireless/rtlwifi/debug.h212
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c1189
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h124
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c1945
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h302
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c493
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c329
-rw-r--r--drivers/net/wireless/rtlwifi/rc.h40
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c400
-rw-r--r--drivers/net/wireless/rtlwifi/regd.h61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/Makefile12
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h257
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.c1473
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.h196
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/fw.c804
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/fw.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2162
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.h57
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.c144
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c2676
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.h237
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h2065
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.c523
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h44
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c282
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.c1224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c1031
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h714
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1532
-rw-r--r--drivers/net/wireless/wl1251/boot.c1
-rw-r--r--drivers/net/wireless/wl1251/main.c15
-rw-r--r--drivers/net/wireless/wl1251/sdio.c103
-rw-r--r--drivers/net/wireless/wl1251/spi.c9
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h1
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig64
-rw-r--r--drivers/net/wireless/wl12xx/Makefile22
-rw-r--r--drivers/net/wireless/wl12xx/acx.c (renamed from drivers/net/wireless/wl12xx/wl1271_acx.c)99
-rw-r--r--drivers/net/wireless/wl12xx/acx.h (renamed from drivers/net/wireless/wl12xx/wl1271_acx.h)108
-rw-r--r--drivers/net/wireless/wl12xx/boot.c (renamed from drivers/net/wireless/wl12xx/wl1271_boot.c)38
-rw-r--r--drivers/net/wireless/wl12xx/boot.h (renamed from drivers/net/wireless/wl12xx/wl1271_boot.h)3
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c (renamed from drivers/net/wireless/wl12xx/wl1271_cmd.c)81
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h (renamed from drivers/net/wireless/wl12xx/wl1271_cmd.h)58
-rw-r--r--drivers/net/wireless/wl12xx/conf.h (renamed from drivers/net/wireless/wl12xx/wl1271_conf.h)4
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c480
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h (renamed from drivers/net/wireless/wl12xx/wl1271_debugfs.h)6
-rw-r--r--drivers/net/wireless/wl12xx/event.c (renamed from drivers/net/wireless/wl12xx/wl1271_event.c)14
-rw-r--r--drivers/net/wireless/wl12xx/event.h (renamed from drivers/net/wireless/wl12xx/wl1271_event.h)4
-rw-r--r--drivers/net/wireless/wl12xx/ini.h (renamed from drivers/net/wireless/wl12xx/wl1271_ini.h)4
-rw-r--r--drivers/net/wireless/wl12xx/init.c (renamed from drivers/net/wireless/wl12xx/wl1271_init.c)23
-rw-r--r--drivers/net/wireless/wl12xx/init.h (renamed from drivers/net/wireless/wl12xx/wl1271_init.h)6
-rw-r--r--drivers/net/wireless/wl12xx/io.c (renamed from drivers/net/wireless/wl12xx/wl1271_io.c)5
-rw-r--r--drivers/net/wireless/wl12xx/io.h (renamed from drivers/net/wireless/wl12xx/wl1271_io.h)6
-rw-r--r--drivers/net/wireless/wl12xx/main.c (renamed from drivers/net/wireless/wl12xx/wl1271_main.c)494
-rw-r--r--drivers/net/wireless/wl12xx/ps.c (renamed from drivers/net/wireless/wl12xx/wl1271_ps.c)6
-rw-r--r--drivers/net/wireless/wl12xx/ps.h (renamed from drivers/net/wireless/wl12xx/wl1271_ps.h)8
-rw-r--r--drivers/net/wireless/wl12xx/reg.h (renamed from drivers/net/wireless/wl12xx/wl1271_reg.h)0
-rw-r--r--drivers/net/wireless/wl12xx/rx.c (renamed from drivers/net/wireless/wl12xx/wl1271_rx.c)38
-rw-r--r--drivers/net/wireless/wl12xx/rx.h (renamed from drivers/net/wireless/wl12xx/wl1271_rx.h)6
-rw-r--r--drivers/net/wireless/wl12xx/scan.c (renamed from drivers/net/wireless/wl12xx/wl1271_scan.c)17
-rw-r--r--drivers/net/wireless/wl12xx/scan.h (renamed from drivers/net/wireless/wl12xx/wl1271_scan.h)6
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c (renamed from drivers/net/wireless/wl12xx/wl1271_sdio.c)4
-rw-r--r--drivers/net/wireless/wl12xx/sdio_test.c520
-rw-r--r--drivers/net/wireless/wl12xx/spi.c (renamed from drivers/net/wireless/wl12xx/wl1271_spi.c)6
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c (renamed from drivers/net/wireless/wl12xx/wl1271_testmode.c)18
-rw-r--r--drivers/net/wireless/wl12xx/testmode.h (renamed from drivers/net/wireless/wl12xx/wl1271_testmode.h)4
-rw-r--r--drivers/net/wireless/wl12xx/tx.c (renamed from drivers/net/wireless/wl12xx/wl1271_tx.c)196
-rw-r--r--drivers/net/wireless/wl12xx/tx.h (renamed from drivers/net/wireless/wl12xx/wl1271_tx.h)7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c583
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h (renamed from drivers/net/wireless/wl12xx/wl1271.h)150
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h17
-rw-r--r--drivers/net/wireless/zd1201.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/net/xen-netfront.c4
-rw-r--r--drivers/net/xilinx_emaclite.c36
-rw-r--r--drivers/net/yellowfin.c4
-rw-r--r--drivers/net/znet.c2
-rw-r--r--drivers/of/address.c54
-rw-r--r--drivers/of/of_i2c.c2
-rw-r--r--drivers/parisc/dino.c1
-rw-r--r--drivers/parisc/eisa.c3
-rw-r--r--drivers/parisc/gsc.c3
-rw-r--r--drivers/parisc/iosapic.c8
-rw-r--r--drivers/parisc/led.c17
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/pci/bus.c81
-rw-r--r--drivers/pci/dmar.c5
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c3
-rw-r--r--drivers/pci/msi.c5
-rw-r--r--drivers/pci/msi.h6
-rw-r--r--drivers/pci/pci-acpi.c1
-rw-r--r--drivers/pci/pci-driver.c5
-rw-r--r--drivers/pci/pci-stub.c7
-rw-r--r--drivers/pci/pci.c7
-rw-r--r--drivers/pci/pcie/aspm.c21
-rw-r--r--drivers/pci/pcie/pme.c27
-rw-r--r--drivers/pci/pcie/portdrv.h2
-rw-r--r--drivers/pci/pcie/portdrv_core.c25
-rw-r--r--drivers/pci/pcie/portdrv_pci.c37
-rw-r--r--drivers/pci/quirks.c26
-rw-r--r--drivers/pcmcia/Kconfig3
-rw-r--r--drivers/pcmcia/Makefile5
-rw-r--r--drivers/pcmcia/pxa2xx_balloon3.c11
-rw-r--r--drivers/pcmcia/pxa2xx_base.c64
-rw-r--r--drivers/pcmcia/pxa2xx_colibri.c229
-rw-r--r--drivers/pcmcia/sa1100_generic.c3
-rw-r--r--drivers/pcmcia/sa1100_generic.h1
-rw-r--r--drivers/pcmcia/sa1100_nanoengine.c219
-rw-r--r--drivers/pcmcia/soc_common.c129
-rw-r--r--drivers/pcmcia/soc_common.h3
-rw-r--r--drivers/platform/x86/asus-laptop.c97
-rw-r--r--drivers/platform/x86/eeepc-wmi.c4
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c4
-rw-r--r--drivers/platform/x86/hp-wmi.c2
-rw-r--r--drivers/platform/x86/ibm_rtl.c34
-rw-r--r--drivers/platform/x86/intel_ips.c36
-rw-r--r--drivers/platform/x86/intel_ips.h21
-rw-r--r--drivers/platform/x86/msi-wmi.c16
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c1
-rw-r--r--drivers/platform/x86/toshiba_acpi.c1
-rw-r--r--drivers/platform/x86/wmi.c2
-rw-r--r--drivers/pnp/Makefile6
-rw-r--r--drivers/pnp/core.c7
-rw-r--r--drivers/pnp/isapnp/Makefile6
-rw-r--r--drivers/pnp/pnpacpi/Makefile3
-rw-r--r--drivers/pnp/pnpacpi/core.c2
-rw-r--r--drivers/pnp/pnpbios/Makefile5
-rw-r--r--drivers/power/Kconfig10
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/collie_battery.c13
-rw-r--r--drivers/power/ds2760_battery.c2
-rw-r--r--drivers/power/gpio-charger.c188
-rw-r--r--drivers/power/intel_mid_battery.c2
-rw-r--r--drivers/power/isp1704_charger.c201
-rw-r--r--drivers/power/jz4740-battery.c13
-rw-r--r--drivers/power/power_supply_core.c6
-rw-r--r--drivers/power/s3c_adc_battery.c12
-rw-r--r--drivers/power/tosa_battery.c13
-rw-r--r--drivers/power/wm97xx_battery.c4
-rw-r--r--drivers/power/z2_battery.c6
-rw-r--r--drivers/ps3/Makefile2
-rw-r--r--drivers/regulator/core.c30
-rw-r--r--drivers/regulator/mc13783-regulator.c4
-rw-r--r--drivers/regulator/tps6586x-regulator.c33
-rw-r--r--drivers/regulator/twl-regulator.c6
-rw-r--r--drivers/regulator/wm8994-regulator.c23
-rw-r--r--drivers/rtc/rtc-cmos.c3
-rw-r--r--drivers/rtc/rtc-rs5c372.c2
-rw-r--r--drivers/rtc/rtc-sa1100.c161
-rw-r--r--drivers/s390/block/Kconfig24
-rw-r--r--drivers/s390/block/dasd.c314
-rw-r--r--drivers/s390/block/dasd_3990_erp.c16
-rw-r--r--drivers/s390/block/dasd_devmap.c155
-rw-r--r--drivers/s390/block/dasd_diag.c3
-rw-r--r--drivers/s390/block/dasd_eckd.c664
-rw-r--r--drivers/s390/block/dasd_eckd.h17
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/block/dasd_erp.c3
-rw-r--r--drivers/s390/block/dasd_fba.c21
-rw-r--r--drivers/s390/block/dasd_genhd.c2
-rw-r--r--drivers/s390/block/dasd_int.h35
-rw-r--r--drivers/s390/char/Kconfig69
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.c18
-rw-r--r--drivers/s390/char/sclp_config.c1
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/vmur.c2
-rw-r--r--drivers/s390/cio/ccwgroup.c78
-rw-r--r--drivers/s390/cio/chsc.c19
-rw-r--r--drivers/s390/cio/chsc.h18
-rw-r--r--drivers/s390/cio/css.c10
-rw-r--r--drivers/s390/cio/device_ops.c40
-rw-r--r--drivers/s390/cio/itcw.c62
-rw-r--r--drivers/s390/cio/qdio.h31
-rw-r--r--drivers/s390/cio/qdio_debug.c1
-rw-r--r--drivers/s390/cio/qdio_main.c177
-rw-r--r--drivers/s390/cio/qdio_setup.c20
-rw-r--r--drivers/s390/cio/qdio_thinint.c56
-rw-r--r--drivers/s390/crypto/ap_bus.c67
-rw-r--r--drivers/s390/crypto/ap_bus.h2
-rw-r--r--drivers/s390/crypto/zcrypt_api.c12
-rw-r--r--drivers/s390/crypto/zcrypt_api.h1
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c82
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.h25
-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.c17
-rw-r--r--drivers/s390/kvm/kvm_virtio.c3
-rw-r--r--drivers/s390/net/Kconfig51
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/ctcm_main.c2
-rw-r--r--drivers/s390/net/lcs.c12
-rw-r--r--drivers/s390/net/qeth_core_main.c4
-rw-r--r--drivers/s390/net/qeth_core_mpc.h2
-rw-r--r--drivers/s390/net/qeth_core_sys.c2
-rw-r--r--drivers/s390/net/qeth_l2_main.c11
-rw-r--r--drivers/s390/net/qeth_l3_main.c245
-rw-r--r--drivers/s390/scsi/zfcp_aux.c9
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c14
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c8
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c1177
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h497
-rw-r--r--drivers/s390/scsi/zfcp_erp.c152
-rw-r--r--drivers/s390/scsi/zfcp_ext.h52
-rw-r--r--drivers/s390/scsi/zfcp_fc.c20
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c124
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c12
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c50
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c9
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c3
-rw-r--r--drivers/scsi/be2iscsi/be_main.c5
-rw-r--r--drivers/scsi/bfa/Makefile4
-rw-r--r--drivers/scsi/bfa/bfa.h36
-rw-r--r--drivers/scsi/bfa/bfa_cb_ioim.h169
-rw-r--r--drivers/scsi/bfa/bfa_core.c373
-rw-r--r--drivers/scsi/bfa/bfa_cs.h96
-rw-r--r--drivers/scsi/bfa/bfa_defs.h6
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h8
-rw-r--r--drivers/scsi/bfa/bfa_drv.c107
-rw-r--r--drivers/scsi/bfa/bfa_fc.h633
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.c109
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.h30
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c698
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.h188
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c210
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h124
-rw-r--r--drivers/scsi/bfa/bfa_fcs_fcpim.c36
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c400
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c236
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c3
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c5
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c755
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h44
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c97
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c120
-rw-r--r--drivers/scsi/bfa/bfa_modules.h3
-rw-r--r--drivers/scsi/bfa/bfa_os_inc.h143
-rw-r--r--drivers/scsi/bfa/bfa_plog.h4
-rw-r--r--drivers/scsi/bfa/bfa_port.c37
-rw-r--r--drivers/scsi/bfa/bfa_port.h1
-rw-r--r--drivers/scsi/bfa/bfa_svc.c774
-rw-r--r--drivers/scsi/bfa/bfa_svc.h63
-rw-r--r--drivers/scsi/bfa/bfad.c46
-rw-r--r--drivers/scsi/bfa/bfad_attr.c18
-rw-r--r--drivers/scsi/bfa/bfad_debugfs.c46
-rw-r--r--drivers/scsi/bfa/bfad_drv.h47
-rw-r--r--drivers/scsi/bfa/bfad_im.c80
-rw-r--r--drivers/scsi/bfa/bfad_im.h16
-rw-r--r--drivers/scsi/bfa/bfi.h8
-rw-r--r--drivers/scsi/bfa/bfi_cbreg.h1
-rw-r--r--drivers/scsi/bfa/bfi_ctreg.h41
-rw-r--r--drivers/scsi/bfa/bfi_ms.h66
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_constants.h3
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_hsi.h3
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h15
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c110
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c108
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c148
-rw-r--r--drivers/scsi/bnx2i/bnx2i_sysfs.c3
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh.c11
-rw-r--r--drivers/scsi/fcoe/fcoe.c4
-rw-r--r--drivers/scsi/fcoe/libfcoe.c300
-rw-r--r--drivers/scsi/gdth.c4
-rw-r--r--drivers/scsi/gdth_proc.c16
-rw-r--r--drivers/scsi/hpsa.c19
-rw-r--r--drivers/scsi/hpsa.h1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c28
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h2
-rw-r--r--drivers/scsi/ipr.c64
-rw-r--r--drivers/scsi/ipr.h2
-rw-r--r--drivers/scsi/libfc/fc_exch.c48
-rw-r--r--drivers/scsi/libfc/fc_fcp.c147
-rw-r--r--drivers/scsi/libfc/fc_libfc.h16
-rw-r--r--drivers/scsi/libfc/fc_lport.c16
-rw-r--r--drivers/scsi/libfc/fc_rport.c3
-rw-r--r--drivers/scsi/libiscsi.c64
-rw-r--r--drivers/scsi/libsas/sas_port.c18
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c3
-rw-r--r--drivers/scsi/lpfc/lpfc.h26
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c104
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c65
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h19
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c48
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h19
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c327
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c239
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h222
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h292
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c1062
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c76
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c82
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c663
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h58
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c10
-rw-r--r--drivers/scsi/megaraid/Makefile2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h78
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c (renamed from drivers/scsi/megaraid/megaraid_sas.c)777
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fp.c516
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c2248
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h695
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h9
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h20
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_history.txt3
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h9
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h8
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h6
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_sas.h9
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h49
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c199
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h27
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c343
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c185
-rw-r--r--drivers/scsi/osd/osd_initiator.c4
-rw-r--r--drivers/scsi/pmcraid.c11
-rw-r--r--drivers/scsi/pmcraid.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h8
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c89
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c67
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c218
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c66
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_inline.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c9
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c22
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c62
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.h6
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c30
-rw-r--r--drivers/scsi/qla4xxx/ql4_version.h4
-rw-r--r--drivers/scsi/scsi_debug.c1
-rw-r--r--drivers/scsi/scsi_error.c87
-rw-r--r--drivers/scsi/scsi_lib.c26
-rw-r--r--drivers/scsi/scsi_sysfs.c6
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c1
-rw-r--r--drivers/scsi/sd.c109
-rw-r--r--drivers/scsi/sr.c174
-rw-r--r--drivers/scsi/sr.h3
-rw-r--r--drivers/scsi/sr_ioctl.c2
-rw-r--r--drivers/scsi/st.c7
-rw-r--r--drivers/serial/8250.c28
-rw-r--r--drivers/serial/amba-pl011.c592
-rw-r--r--drivers/serial/kgdboc.c3
-rw-r--r--drivers/serial/mfd.c24
-rw-r--r--drivers/serial/msm_serial.c2
-rw-r--r--drivers/serial/omap-serial.c40
-rw-r--r--drivers/serial/sh-sci.h7
-rw-r--r--drivers/sh/intc/core.c1
-rw-r--r--drivers/spi/atmel_spi.c6
-rw-r--r--drivers/spi/coldfire_qspi.c2
-rw-r--r--drivers/spi/dw_spi.c5
-rw-r--r--drivers/spi/mpc52xx_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c39
-rw-r--r--drivers/spi/spi.c3
-rw-r--r--drivers/spi/spi_fsl_espi.c35
-rw-r--r--drivers/ssb/main.c30
-rw-r--r--drivers/ssb/pci.c96
-rw-r--r--drivers/ssb/pcihost_wrapper.c7
-rw-r--r--drivers/ssb/scan.c4
-rw-r--r--drivers/staging/Kconfig6
-rw-r--r--drivers/staging/Makefile5
-rw-r--r--drivers/staging/asus_oled/asus_oled.c8
-rw-r--r--drivers/staging/autofs/root.c2
-rw-r--r--drivers/staging/batman-adv/hard-interface.c19
-rw-r--r--drivers/staging/batman-adv/soft-interface.c14
-rw-r--r--drivers/staging/brcm80211/README8
-rw-r--r--drivers/staging/brcm80211/TODO2
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c4
-rw-r--r--drivers/staging/cpia/Kconfig39
-rw-r--r--drivers/staging/cpia/Makefile5
-rw-r--r--drivers/staging/cpia/TODO8
-rw-r--r--drivers/staging/cpia/cpia.c4028
-rw-r--r--drivers/staging/cpia/cpia.h432
-rw-r--r--drivers/staging/cpia/cpia_pp.c869
-rw-r--r--drivers/staging/cpia/cpia_usb.c640
-rw-r--r--drivers/staging/cx25821/Kconfig4
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c71
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c66
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c2
-rw-r--r--drivers/staging/cx25821/cx25821-core.c191
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c19
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c7
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c63
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c90
-rw-r--r--drivers/staging/cx25821/cx25821-video.c123
-rw-r--r--drivers/staging/cx25821/cx25821-video.h17
-rw-r--r--drivers/staging/cx25821/cx25821.h9
-rw-r--r--drivers/staging/dabusb/Kconfig14
-rw-r--r--drivers/staging/dabusb/Makefile2
-rw-r--r--drivers/staging/dabusb/TODO5
-rw-r--r--drivers/staging/dabusb/dabusb.c (renamed from drivers/media/video/dabusb.c)0
-rw-r--r--drivers/staging/dabusb/dabusb.h (renamed from drivers/media/video/dabusb.h)0
-rw-r--r--drivers/staging/dt3155v4l/dt3155v4l.c3
-rw-r--r--drivers/staging/easycap/easycap.h1
-rw-r--r--drivers/staging/frontier/tranzport.c2
-rw-r--r--drivers/staging/go7007/Kconfig4
-rw-r--r--drivers/staging/go7007/go7007-driver.c2
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c2
-rw-r--r--drivers/staging/intel_sst/intel_sst_stream_encoded.c2
-rw-r--r--drivers/staging/line6/control.c204
-rw-r--r--drivers/staging/line6/midi.c4
-rw-r--r--drivers/staging/line6/pcm.c4
-rw-r--r--drivers/staging/line6/pod.c32
-rw-r--r--drivers/staging/line6/toneport.c4
-rw-r--r--drivers/staging/line6/variax.c12
-rw-r--r--drivers/staging/lirc/Kconfig29
-rw-r--r--drivers/staging/lirc/Makefile1
-rw-r--r--drivers/staging/lirc/TODO.lirc_i2c3
-rw-r--r--drivers/staging/lirc/TODO.lirc_zilog13
-rw-r--r--drivers/staging/lirc/lirc_i2c.c536
-rw-r--r--drivers/staging/lirc/lirc_zilog.c48
-rw-r--r--drivers/staging/pohmelfs/inode.c9
-rw-r--r--drivers/staging/pohmelfs/path_entry.c17
-rw-r--r--drivers/staging/quickstart/quickstart.c10
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c1
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c30
-rw-r--r--drivers/staging/rtl8712/usb_halinit.c2
-rw-r--r--drivers/staging/samsung-laptop/samsung-laptop.c2
-rw-r--r--drivers/staging/se401/Kconfig13
-rw-r--r--drivers/staging/se401/Makefile1
-rw-r--r--drivers/staging/se401/TODO5
-rw-r--r--drivers/staging/se401/se401.c (renamed from drivers/media/video/se401.c)0
-rw-r--r--drivers/staging/se401/se401.h (renamed from drivers/media/video/se401.h)2
-rw-r--r--drivers/staging/se401/videodev.h (renamed from include/linux/videodev.h)22
-rw-r--r--drivers/staging/sm7xx/smtcfb.c2
-rw-r--r--drivers/staging/smbfs/cache.c16
-rw-r--r--drivers/staging/smbfs/dir.c34
-rw-r--r--drivers/staging/smbfs/inode.c9
-rw-r--r--drivers/staging/speakup/fakekey.c1
-rw-r--r--drivers/staging/speakup/kobjects.c9
-rw-r--r--drivers/staging/speakup/main.c33
-rw-r--r--drivers/staging/spectra/ffsport.c2
-rw-r--r--drivers/staging/stradis/Kconfig7
-rw-r--r--drivers/staging/stradis/Makefile3
-rw-r--r--drivers/staging/stradis/TODO6
-rw-r--r--drivers/staging/stradis/stradis.c2222
-rw-r--r--drivers/staging/tidspbridge/core/_tiomap.h15
-rw-r--r--drivers/staging/tm6000/Kconfig2
-rw-r--r--drivers/staging/tm6000/TODO2
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c52
-rw-r--r--drivers/staging/tm6000/tm6000-core.c29
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c39
-rw-r--r--drivers/staging/tm6000/tm6000-input.c287
-rw-r--r--drivers/staging/tm6000/tm6000-video.c17
-rw-r--r--drivers/staging/tm6000/tm6000.h3
-rw-r--r--drivers/staging/udlfb/udlfb.c2
-rw-r--r--drivers/staging/usbip/vhci_hcd.c14
-rw-r--r--drivers/staging/usbvideo/Kconfig15
-rw-r--r--drivers/staging/usbvideo/Makefile2
-rw-r--r--drivers/staging/usbvideo/TODO5
-rw-r--r--drivers/staging/usbvideo/usbvideo.c (renamed from drivers/media/video/usbvideo/usbvideo.c)0
-rw-r--r--drivers/staging/usbvideo/usbvideo.h (renamed from drivers/media/video/usbvideo/usbvideo.h)2
-rw-r--r--drivers/staging/usbvideo/vicam.c (renamed from drivers/media/video/usbvideo/vicam.c)2
-rw-r--r--drivers/staging/usbvideo/videodev.h318
-rw-r--r--drivers/staging/winbond/sysdef.h3
-rw-r--r--drivers/staging/zram/zram_drv.c6
-rw-r--r--drivers/staging/zram/zram_sysfs.c4
-rw-r--r--drivers/thermal/thermal_sys.c120
-rw-r--r--drivers/tty/n_gsm.c6
-rw-r--r--drivers/tty/tty_io.c13
-rw-r--r--drivers/tty/tty_ldisc.c2
-rw-r--r--drivers/uio/uio.c2
-rw-r--r--drivers/uio/uio_cif.c2
-rw-r--r--drivers/uio/uio_netx.c2
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/atm/ueagle-atm.c22
-rw-r--r--drivers/usb/atm/usbatm.c15
-rw-r--r--drivers/usb/core/Kconfig12
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/inode.c12
-rw-r--r--drivers/usb/gadget/composite.c18
-rw-r--r--drivers/usb/gadget/fsl_mxc_udc.c4
-rw-r--r--drivers/usb/gadget/storage_common.c7
-rw-r--r--drivers/usb/host/Kconfig15
-rw-r--r--drivers/usb/host/ehci-cns3xxx.c171
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/ehci-mxc.c44
-rw-r--r--drivers/usb/host/ehci-pci.c12
-rw-r--r--drivers/usb/host/ohci-cns3xxx.c165
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/xhci-hub.c7
-rw-r--r--drivers/usb/host/xhci-mem.c169
-rw-r--r--drivers/usb/host/xhci.c18
-rw-r--r--drivers/usb/host/xhci.h26
-rw-r--r--drivers/usb/misc/uss720.c4
-rw-r--r--drivers/usb/misc/yurex.c1
-rw-r--r--drivers/usb/musb/musb_core.c3
-rw-r--r--drivers/usb/musb/musb_gadget.c124
-rw-r--r--drivers/usb/serial/ftdi_sio.c3
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h9
-rw-r--r--drivers/usb/serial/usb-serial.c3
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/vhost/net.c9
-rw-r--r--drivers/vhost/test.c320
-rw-r--r--drivers/vhost/test.h7
-rw-r--r--drivers/vhost/vhost.c44
-rw-r--r--drivers/vhost/vhost.h2
-rw-r--r--drivers/video/Kconfig10
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/da8xx-fb.c14
-rw-r--r--drivers/video/fbcmap.c1
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/geode/lxfb.h4
-rw-r--r--drivers/video/geode/lxfb_ops.c20
-rw-r--r--drivers/video/imxfb.c9
-rw-r--r--drivers/video/modedb.c1
-rw-r--r--drivers/video/omap/Kconfig4
-rw-r--r--drivers/video/omap2/vram.c4
-rw-r--r--drivers/video/pxa3xx-gcu.c772
-rw-r--r--drivers/video/pxa3xx-gcu.h38
-rw-r--r--drivers/video/sh_mobile_hdmi.c17
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c30
-rw-r--r--drivers/watchdog/Kconfig3
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c42
-rw-r--r--drivers/watchdog/gef_wdt.c1
-rw-r--r--drivers/watchdog/iTCO_wdt.c8
-rw-r--r--drivers/watchdog/imx2_wdt.c2
-rw-r--r--drivers/watchdog/rdc321x_wdt.c2
-rw-r--r--drivers/xen/balloon.c12
-rw-r--r--drivers/xen/events.c109
-rw-r--r--drivers/xen/manage.c1
-rw-r--r--firmware/Makefile10
-rw-r--r--firmware/WHENCE4
-rw-r--r--firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex (renamed from firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex)5429
-rw-r--r--firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex (renamed from firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex)5412
-rw-r--r--firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex9476
-rw-r--r--firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex9483
-rw-r--r--firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex13178
-rw-r--r--firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex13181
-rw-r--r--firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex15442
-rw-r--r--firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex15456
-rw-r--r--fs/9p/Kconfig5
-rw-r--r--fs/9p/Makefile1
-rw-r--r--fs/9p/acl.c4
-rw-r--r--fs/9p/v9fs.h36
-rw-r--r--fs/9p/vfs_dentry.c4
-rw-r--r--fs/9p/vfs_inode.c883
-rw-r--r--fs/9p/vfs_inode_dotl.c880
-rw-r--r--fs/9p/xattr.c2
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/Makefile1
-rw-r--r--fs/adfs/dir.c13
-rw-r--r--fs/adfs/super.c11
-rw-r--r--fs/affs/amigaffs.c4
-rw-r--r--fs/affs/namei.c68
-rw-r--r--fs/affs/super.c11
-rw-r--r--fs/afs/dir.c6
-rw-r--r--fs/afs/super.c10
-rw-r--r--fs/anon_inodes.c6
-rw-r--r--fs/autofs4/autofs_i.h21
-rw-r--r--fs/autofs4/expire.c141
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/root.c90
-rw-r--r--fs/autofs4/waitq.c23
-rw-r--r--fs/befs/linuxvfs.c10
-rw-r--r--fs/bfs/inode.c9
-rw-r--r--fs/bio-integrity.c7
-rw-r--r--fs/block_dev.c750
-rw-r--r--fs/btrfs/acl.c19
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/disk-io.c11
-rw-r--r--fs/btrfs/export.c6
-rw-r--r--fs/btrfs/extent-tree.c75
-rw-r--r--fs/btrfs/file.c92
-rw-r--r--fs/btrfs/free-space-cache.c12
-rw-r--r--fs/btrfs/inode.c38
-rw-r--r--fs/btrfs/ioctl.c56
-rw-r--r--fs/btrfs/ioctl.h14
-rw-r--r--fs/btrfs/orphan.c6
-rw-r--r--fs/btrfs/super.c2
-rw-r--r--fs/btrfs/volumes.c48
-rw-r--r--fs/btrfs/volumes.h4
-rw-r--r--fs/ceph/Makefile23
-rw-r--r--fs/ceph/debugfs.c9
-rw-r--r--fs/ceph/dir.c48
-rw-r--r--fs/ceph/export.c2
-rw-r--r--fs/ceph/file.c39
-rw-r--r--fs/ceph/inode.c31
-rw-r--r--fs/ceph/ioctl.h2
-rw-r--r--fs/ceph/locks.c94
-rw-r--r--fs/ceph/mds_client.c89
-rw-r--r--fs/ceph/mds_client.h33
-rw-r--r--fs/ceph/super.c13
-rw-r--r--fs/ceph/super.h2
-rw-r--r--fs/char_dev.c2
-rw-r--r--fs/cifs/Kconfig8
-rw-r--r--fs/cifs/Makefile4
-rw-r--r--fs/cifs/README9
-rw-r--r--fs/cifs/cache.c16
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifs_spnego.c10
-rw-r--r--fs/cifs/cifsacl.c51
-rw-r--r--fs/cifs/cifsacl.h4
-rw-r--r--fs/cifs/cifsfs.c29
-rw-r--r--fs/cifs/cifsglob.h17
-rw-r--r--fs/cifs/cifsproto.h11
-rw-r--r--fs/cifs/cifssmb.c183
-rw-r--r--fs/cifs/connect.c468
-rw-r--r--fs/cifs/dir.c76
-rw-r--r--fs/cifs/dns_resolve.c2
-rw-r--r--fs/cifs/file.c241
-rw-r--r--fs/cifs/fscache.c12
-rw-r--r--fs/cifs/inode.c71
-rw-r--r--fs/cifs/link.c4
-rw-r--r--fs/cifs/readdir.c47
-rw-r--r--fs/cifs/sess.c33
-rw-r--r--fs/cifs/transport.c2
-rw-r--r--fs/cifs/xattr.c55
-rw-r--r--fs/coda/cache.c4
-rw-r--r--fs/coda/dir.c8
-rw-r--r--fs/coda/inode.c9
-rw-r--r--fs/compat.c28
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--fs/configfs/configfs_internal.h4
-rw-r--r--fs/configfs/dir.c13
-rw-r--r--fs/configfs/inode.c8
-rw-r--r--fs/dcache.c1388
-rw-r--r--fs/dlm/lowcomms.c63
-rw-r--r--fs/ecryptfs/crypto.c30
-rw-r--r--fs/ecryptfs/dentry.c15
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h5
-rw-r--r--fs/ecryptfs/file.c28
-rw-r--r--fs/ecryptfs/inode.c40
-rw-r--r--fs/ecryptfs/keystore.c26
-rw-r--r--fs/ecryptfs/kthread.c19
-rw-r--r--fs/ecryptfs/main.c16
-rw-r--r--fs/ecryptfs/mmap.c35
-rw-r--r--fs/ecryptfs/super.c12
-rw-r--r--fs/efs/super.c9
-rw-r--r--fs/exec.c41
-rw-r--r--fs/exofs/super.c9
-rw-r--r--fs/exportfs/expfs.c14
-rw-r--r--fs/ext2/acl.c11
-rw-r--r--fs/ext2/acl.h8
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext2/namei.c4
-rw-r--r--fs/ext2/super.c9
-rw-r--r--fs/ext2/xattr.c10
-rw-r--r--fs/ext3/acl.c11
-rw-r--r--fs/ext3/acl.h8
-rw-r--r--fs/ext3/file.c2
-rw-r--r--fs/ext3/namei.c4
-rw-r--r--fs/ext3/super.c21
-rw-r--r--fs/ext3/xattr.c2
-rw-r--r--fs/ext4/acl.c11
-rw-r--r--fs/ext4/acl.h4
-rw-r--r--fs/ext4/dir.c54
-rw-r--r--fs/ext4/ext4.h49
-rw-r--r--fs/ext4/file.c2
-rw-r--r--fs/ext4/inode.c26
-rw-r--r--fs/ext4/mballoc.c32
-rw-r--r--fs/ext4/migrate.c2
-rw-r--r--fs/ext4/namei.c43
-rw-r--r--fs/ext4/page-io.c7
-rw-r--r--fs/ext4/resize.c5
-rw-r--r--fs/ext4/super.c300
-rw-r--r--fs/ext4/xattr.c28
-rw-r--r--fs/fat/inode.c13
-rw-r--r--fs/fat/namei_msdos.c23
-rw-r--r--fs/fat/namei_vfat.c63
-rw-r--r--fs/filesystems.c3
-rw-r--r--fs/freevxfs/vxfs_inode.c9
-rw-r--r--fs/fs_struct.c36
-rw-r--r--fs/fuse/dev.c156
-rw-r--r--fs/fuse/dir.c62
-rw-r--r--fs/fuse/file.c130
-rw-r--r--fs/fuse/fuse_i.h27
-rw-r--r--fs/fuse/inode.c43
-rw-r--r--fs/generic_acl.c20
-rw-r--r--fs/gfs2/bmap.c11
-rw-r--r--fs/gfs2/dentry.c5
-rw-r--r--fs/gfs2/export.c4
-rw-r--r--fs/gfs2/glock.c71
-rw-r--r--fs/gfs2/glock.h28
-rw-r--r--fs/gfs2/glops.c1
-rw-r--r--fs/gfs2/incore.h12
-rw-r--r--fs/gfs2/inode.c9
-rw-r--r--fs/gfs2/lock_dlm.c15
-rw-r--r--fs/gfs2/ops_fstype.c10
-rw-r--r--fs/gfs2/ops_inode.c20
-rw-r--r--fs/gfs2/quota.c13
-rw-r--r--fs/gfs2/rgrp.c57
-rw-r--r--fs/gfs2/rgrp.h1
-rw-r--r--fs/gfs2/super.c9
-rw-r--r--fs/gfs2/xattr.c23
-rw-r--r--fs/hfs/dir.c2
-rw-r--r--fs/hfs/hfs_fs.h8
-rw-r--r--fs/hfs/string.c17
-rw-r--r--fs/hfs/super.c11
-rw-r--r--fs/hfsplus/bfind.c6
-rw-r--r--fs/hfsplus/bitmap.c3
-rw-r--r--fs/hfsplus/bnode.c70
-rw-r--r--fs/hfsplus/brec.c28
-rw-r--r--fs/hfsplus/btree.c33
-rw-r--r--fs/hfsplus/catalog.c85
-rw-r--r--fs/hfsplus/dir.c39
-rw-r--r--fs/hfsplus/extents.c96
-rw-r--r--fs/hfsplus/hfsplus_fs.h130
-rw-r--r--fs/hfsplus/hfsplus_raw.h3
-rw-r--r--fs/hfsplus/inode.c89
-rw-r--r--fs/hfsplus/ioctl.c6
-rw-r--r--fs/hfsplus/options.c44
-rw-r--r--fs/hfsplus/part_tbl.c129
-rw-r--r--fs/hfsplus/super.c142
-rw-r--r--fs/hfsplus/unicode.c56
-rw-r--r--fs/hfsplus/wrapper.c178
-rw-r--r--fs/hostfs/hostfs_kern.c37
-rw-r--r--fs/hpfs/dentry.c27
-rw-r--r--fs/hpfs/super.c9
-rw-r--r--fs/hppfs/hppfs.c9
-rw-r--r--fs/hugetlbfs/inode.c9
-rw-r--r--fs/inode.c50
-rw-r--r--fs/internal.h1
-rw-r--r--fs/isofs/inode.c131
-rw-r--r--fs/isofs/namei.c5
-rw-r--r--fs/jbd2/journal.c14
-rw-r--r--fs/jbd2/recovery.c2
-rw-r--r--fs/jbd2/transaction.c6
-rw-r--r--fs/jffs2/build.c5
-rw-r--r--fs/jffs2/jffs2_fs_sb.h2
-rw-r--r--fs/jffs2/super.c9
-rw-r--r--fs/jffs2/xattr.c12
-rw-r--r--fs/jfs/jfs_logmgr.c17
-rw-r--r--fs/jfs/namei.c61
-rw-r--r--fs/jfs/super.c12
-rw-r--r--fs/libfs.c63
-rw-r--r--fs/lockd/Makefile6
-rw-r--r--fs/lockd/clnt4xdr.c605
-rw-r--r--fs/lockd/clntlock.c4
-rw-r--r--fs/lockd/clntproc.c18
-rw-r--r--fs/lockd/clntxdr.c627
-rw-r--r--fs/lockd/host.c409
-rw-r--r--fs/lockd/mon.c110
-rw-r--r--fs/lockd/svc4proc.c20
-rw-r--r--fs/lockd/svclock.c34
-rw-r--r--fs/lockd/svcproc.c28
-rw-r--r--fs/lockd/xdr.c287
-rw-r--r--fs/lockd/xdr4.c255
-rw-r--r--fs/locks.c2
-rw-r--r--fs/logfs/dev_bdev.c7
-rw-r--r--fs/logfs/inode.c9
-rw-r--r--fs/logfs/journal.c2
-rw-r--r--fs/logfs/readwrite.c3
-rw-r--r--fs/minix/inode.c9
-rw-r--r--fs/minix/namei.c2
-rw-r--r--fs/namei.c940
-rw-r--r--fs/namespace.c271
-rw-r--r--fs/ncpfs/dir.c84
-rw-r--r--fs/ncpfs/inode.c11
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--fs/ncpfs/ncplib_kernel.h16
-rw-r--r--fs/nfs/dir.c127
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/getroot.c10
-rw-r--r--fs/nfs/idmap.c2
-rw-r--r--fs/nfs/inode.c10
-rw-r--r--fs/nfs/internal.h11
-rw-r--r--fs/nfs/mount_clnt.c87
-rw-r--r--fs/nfs/namespace.c17
-rw-r--r--fs/nfs/nfs2xdr.c1297
-rw-r--r--fs/nfs/nfs3xdr.c2822
-rw-r--r--fs/nfs/nfs4_fs.h8
-rw-r--r--fs/nfs/nfs4proc.c94
-rw-r--r--fs/nfs/nfs4xdr.c1401
-rw-r--r--fs/nfs/pagelist.c11
-rw-r--r--fs/nfs/proc.c5
-rw-r--r--fs/nfs/read.c1
-rw-r--r--fs/nfs/super.c22
-rw-r--r--fs/nfs/unlink.c4
-rw-r--r--fs/nfs/write.c3
-rw-r--r--fs/nfsd/nfs3proc.c8
-rw-r--r--fs/nfsd/nfs3xdr.c6
-rw-r--r--fs/nfsd/nfs4callback.c697
-rw-r--r--fs/nfsd/nfs4proc.c50
-rw-r--r--fs/nfsd/nfs4recover.c1
-rw-r--r--fs/nfsd/nfs4state.c60
-rw-r--r--fs/nfsd/nfs4xdr.c58
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nfsd/nfsproc.c5
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/vfs.c14
-rw-r--r--fs/nfsd/xdr4.h26
-rw-r--r--fs/nilfs2/bmap.c47
-rw-r--r--fs/nilfs2/btnode.c3
-rw-r--r--fs/nilfs2/dir.c3
-rw-r--r--fs/nilfs2/file.c1
-rw-r--r--fs/nilfs2/gcinode.c9
-rw-r--r--fs/nilfs2/ifile.c11
-rw-r--r--fs/nilfs2/inode.c180
-rw-r--r--fs/nilfs2/ioctl.c24
-rw-r--r--fs/nilfs2/mdt.c32
-rw-r--r--fs/nilfs2/namei.c1
-rw-r--r--fs/nilfs2/nilfs.h13
-rw-r--r--fs/nilfs2/page.c86
-rw-r--r--fs/nilfs2/page.h3
-rw-r--r--fs/nilfs2/recovery.c2
-rw-r--r--fs/nilfs2/sb.h8
-rw-r--r--fs/nilfs2/segment.c43
-rw-r--r--fs/nilfs2/super.c49
-rw-r--r--fs/nilfs2/the_nilfs.c6
-rw-r--r--fs/nilfs2/the_nilfs.h3
-rw-r--r--fs/notify/fanotify/fanotify.c6
-rw-r--r--fs/notify/fanotify/fanotify_user.c81
-rw-r--r--fs/notify/fsnotify.c8
-rw-r--r--fs/notify/inotify/inotify_user.c1
-rw-r--r--fs/ntfs/inode.c9
-rw-r--r--fs/ocfs2/Kconfig2
-rw-r--r--fs/ocfs2/alloc.c3
-rw-r--r--fs/ocfs2/aops.c66
-rw-r--r--fs/ocfs2/aops.h23
-rw-r--r--fs/ocfs2/cluster/heartbeat.c262
-rw-r--r--fs/ocfs2/cluster/masklog.c3
-rw-r--r--fs/ocfs2/cluster/masklog.h15
-rw-r--r--fs/ocfs2/cluster/netdebug.c253
-rw-r--r--fs/ocfs2/cluster/tcp.c143
-rw-r--r--fs/ocfs2/cluster/tcp_internal.h33
-rw-r--r--fs/ocfs2/dcache.c11
-rw-r--r--fs/ocfs2/dir.c4
-rw-r--r--fs/ocfs2/dlm/dlmast.c76
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h86
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c200
-rw-r--r--fs/ocfs2/dlm/dlmdebug.h5
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c12
-rw-r--r--fs/ocfs2/dlm/dlmlock.c3
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c40
-rw-r--r--fs/ocfs2/dlm/dlmthread.c132
-rw-r--r--fs/ocfs2/dlmfs/dlmfs.c9
-rw-r--r--fs/ocfs2/export.c4
-rw-r--r--fs/ocfs2/file.c15
-rw-r--r--fs/ocfs2/namei.c15
-rw-r--r--fs/ocfs2/ocfs2.h11
-rw-r--r--fs/ocfs2/ocfs2_fs.h2
-rw-r--r--fs/ocfs2/stack_user.c2
-rw-r--r--fs/ocfs2/super.c9
-rw-r--r--fs/openpromfs/inode.c9
-rw-r--r--fs/partitions/check.c98
-rw-r--r--fs/pipe.c12
-rw-r--r--fs/pnode.c4
-rw-r--r--fs/proc/base.c16
-rw-r--r--fs/proc/generic.c4
-rw-r--r--fs/proc/inode.c9
-rw-r--r--fs/proc/proc_sysctl.c23
-rw-r--r--fs/proc/vmcore.c2
-rw-r--r--fs/pstore/Kconfig13
-rw-r--r--fs/pstore/Makefile7
-rw-r--r--fs/pstore/inode.c280
-rw-r--r--fs/pstore/internal.h7
-rw-r--r--fs/pstore/platform.c202
-rw-r--r--fs/qnx4/inode.c9
-rw-r--r--fs/reiserfs/journal.c21
-rw-r--r--fs/reiserfs/super.c9
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/reiserfs/xattr_acl.c6
-rw-r--r--fs/romfs/super.c9
-rw-r--r--fs/splice.c43
-rw-r--r--fs/squashfs/super.c9
-rw-r--r--fs/super.c24
-rw-r--r--fs/sysfs/dir.c22
-rw-r--r--fs/sysv/inode.c9
-rw-r--r--fs/sysv/namei.c5
-rw-r--r--fs/sysv/super.c2
-rw-r--r--fs/ubifs/super.c10
-rw-r--r--fs/udf/balloc.c3
-rw-r--r--fs/udf/dir.c5
-rw-r--r--fs/udf/file.c11
-rw-r--r--fs/udf/ialloc.c21
-rw-r--r--fs/udf/inode.c51
-rw-r--r--fs/udf/namei.c101
-rw-r--r--fs/udf/partition.c27
-rw-r--r--fs/udf/super.c76
-rw-r--r--fs/udf/symlink.c12
-rw-r--r--fs/udf/udf_i.h13
-rw-r--r--fs/udf/udf_sb.h22
-rw-r--r--fs/udf/udfdecl.h4
-rw-r--r--fs/ufs/super.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c519
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h16
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c35
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c12
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h29
-rw-r--r--fs/xfs/xfs_acl.h4
-rw-r--r--fs/xfs/xfs_alloc.c351
-rw-r--r--fs/xfs/xfs_bmap.c85
-rw-r--r--fs/xfs/xfs_bmap.h5
-rw-r--r--fs/xfs/xfs_buf_item.h11
-rw-r--r--fs/xfs/xfs_dfrag.c13
-rw-r--r--fs/xfs/xfs_error.c3
-rw-r--r--fs/xfs/xfs_error.h5
-rw-r--r--fs/xfs/xfs_iget.c13
-rw-r--r--fs/xfs/xfs_inode_item.c31
-rw-r--r--fs/xfs/xfs_iomap.c149
-rw-r--r--fs/xfs/xfs_iomap.h27
-rw-r--r--fs/xfs/xfs_log_priv.h6
-rw-r--r--fs/xfs/xfs_log_recover.c585
-rw-r--r--fs/xfs/xfs_rename.c1
-rw-r--r--include/acpi/acpi_bus.h5
-rw-r--r--include/acpi/acpixf.h20
-rw-r--r--include/acpi/actypes.h52
-rw-r--r--include/acpi/video.h5
-rw-r--r--include/asm-generic/io.h30
-rw-r--r--include/crypto/if_alg.h92
-rw-r--r--include/crypto/scatterwalk.h15
-rw-r--r--include/drm/i915_drm.h2
-rw-r--r--include/linux/Kbuild11
-rw-r--r--include/linux/acpi.h2
-rw-r--r--include/linux/amba/bus.h8
-rw-r--r--include/linux/amba/serial.h22
-rw-r--r--include/linux/atmdev.h6
-rw-r--r--include/linux/average.h30
-rw-r--r--include/linux/binfmts.h5
-rw-r--r--include/linux/bit_spinlock.h4
-rw-r--r--include/linux/bitops.h11
-rw-r--r--include/linux/blkdev.h14
-rw-r--r--include/linux/bootmem.h2
-rw-r--r--include/linux/cdrom.h6
-rw-r--r--include/linux/ceph/ceph_fs.h16
-rw-r--r--include/linux/ceph/libceph.h6
-rw-r--r--include/linux/ceph/messenger.h5
-rw-r--r--include/linux/clkdev.h36
-rw-r--r--include/linux/cnt32_to_63.h20
-rw-r--r--include/linux/cper.h86
-rw-r--r--include/linux/cpu.h5
-rw-r--r--include/linux/crash_dump.h9
-rw-r--r--include/linux/dcache.h243
-rw-r--r--include/linux/dcbnl.h184
-rw-r--r--include/linux/dccp.h23
-rw-r--r--include/linux/device.h1
-rw-r--r--include/linux/dm-ioctl.h12
-rw-r--r--include/linux/dmaengine.h13
-rw-r--r--include/linux/ethtool.h4
-rw-r--r--include/linux/fanotify.h10
-rw-r--r--include/linux/filter.h56
-rw-r--r--include/linux/firewire.h2
-rw-r--r--include/linux/fs.h90
-rw-r--r--include/linux/fs_struct.h3
-rw-r--r--include/linux/fsnotify.h5
-rw-r--r--include/linux/fsnotify_backend.h13
-rw-r--r--include/linux/fuse.h26
-rw-r--r--include/linux/generic_acl.h1
-rw-r--r--include/linux/genhd.h20
-rw-r--r--include/linux/gfp.h4
-rw-r--r--include/linux/gpio-i2cmux.h38
-rw-r--r--include/linux/gpio_keys.h2
-rw-r--r--include/linux/hid.h75
-rw-r--r--include/linux/i2c-omap.h5
-rw-r--r--include/linux/ieee80211.h30
-rw-r--r--include/linux/if_alg.h40
-rw-r--r--include/linux/if_bridge.h4
-rw-r--r--include/linux/if_link.h28
-rw-r--r--include/linux/if_macvlan.h34
-rw-r--r--include/linux/igmp.h18
-rw-r--r--include/linux/inetdevice.h15
-rw-r--r--include/linux/input.h71
-rw-r--r--include/linux/input/cma3000.h59
-rw-r--r--include/linux/input/matrix_keypad.h2
-rw-r--r--include/linux/input/mt.h57
-rw-r--r--include/linux/ioport.h2
-rw-r--r--include/linux/ipmi.h38
-rw-r--r--include/linux/ipmi_smi.h8
-rw-r--r--include/linux/ipv6.h2
-rw-r--r--include/linux/jhash.h183
-rw-r--r--include/linux/kthread.h45
-rw-r--r--include/linux/kvm.h1
-rw-r--r--include/linux/kvm_host.h101
-rw-r--r--include/linux/kvm_types.h7
-rw-r--r--include/linux/libata.h6
-rw-r--r--include/linux/list_bl.h141
-rw-r--r--include/linux/lockd/debug.h10
-rw-r--r--include/linux/lockd/lockd.h6
-rw-r--r--include/linux/magic.h2
-rw-r--r--include/linux/mdio.h5
-rw-r--r--include/linux/memory_hotplug.h6
-rw-r--r--include/linux/mfd/tc35892.h136
-rw-r--r--include/linux/mfd/tc3589x.h195
-rw-r--r--include/linux/mfd/wl1273-core.h288
-rw-r--r--include/linux/mfd/wm8994/core.h8
-rw-r--r--include/linux/mfd/wm8994/pdata.h19
-rw-r--r--include/linux/mfd/wm8994/registers.h302
-rw-r--r--include/linux/mm.h5
-rw-r--r--include/linux/mmc/sh_mmcif.h60
-rw-r--r--include/linux/mount.h53
-rw-r--r--include/linux/mtd/cfi.h3
-rw-r--r--include/linux/mtd/fsmc.h26
-rw-r--r--include/linux/mtd/nand.h2
-rw-r--r--include/linux/mtd/onenand.h12
-rw-r--r--include/linux/mtd/partitions.h2
-rw-r--r--include/linux/mutex.h4
-rw-r--r--include/linux/namei.h16
-rw-r--r--include/linux/ncp_fs.h4
-rw-r--r--include/linux/netdevice.h89
-rw-r--r--include/linux/netfilter.h2
-rw-r--r--include/linux/netlink.h2
-rw-r--r--include/linux/nfs3.h3
-rw-r--r--include/linux/nfs4.h3
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/nfs_page.h1
-rw-r--r--include/linux/nfs_xdr.h3
-rw-r--r--include/linux/nl80211.h188
-rw-r--r--include/linux/node.h5
-rw-r--r--include/linux/of_address.h6
-rw-r--r--include/linux/path.h2
-rw-r--r--include/linux/pci-aspm.h5
-rw-r--r--include/linux/pci.h8
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/pci_regs.h10
-rw-r--r--include/linux/perf_event.h1
-rw-r--r--include/linux/pm_runtime.h3
-rw-r--r--include/linux/posix_acl.h19
-rw-r--r--include/linux/power/gpio-charger.h41
-rw-r--r--include/linux/pstore.h60
-rw-r--r--include/linux/rculist_bl.h128
-rw-r--r--include/linux/rfkill.h31
-rw-r--r--include/linux/s3c_adc_battery.h1
-rw-r--r--include/linux/sched.h2
-rw-r--r--include/linux/security.h8
-rw-r--r--include/linux/seqlock.h80
-rw-r--r--include/linux/serial_reg.h19
-rw-r--r--include/linux/skbuff.h13
-rw-r--r--include/linux/slab.h2
-rw-r--r--include/linux/snmp.h1
-rw-r--r--include/linux/socket.h5
-rw-r--r--include/linux/ssb/ssb.h4
-rw-r--r--include/linux/ssb/ssb_driver_gige.h17
-rw-r--r--include/linux/ssb/ssb_regs.h40
-rw-r--r--include/linux/stmmac.h6
-rw-r--r--include/linux/sunrpc/auth.h8
-rw-r--r--include/linux/sunrpc/cache.h3
-rw-r--r--include/linux/sunrpc/clnt.h4
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/sunrpc/svc_xprt.h1
-rw-r--r--include/linux/sunrpc/xdr.h10
-rw-r--r--include/linux/taskstats.h3
-rw-r--r--include/linux/thermal.h47
-rw-r--r--include/linux/tipc.h18
-rw-r--r--include/linux/tipc_config.h76
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/uinput.h1
-rw-r--r--include/linux/uio_driver.h2
-rw-r--r--include/linux/unaligned/packed_struct.h6
-rw-r--r--include/linux/usb.h4
-rw-r--r--include/linux/usb/usbnet.h6
-rw-r--r--include/linux/video_output.h15
-rw-r--r--include/linux/vmalloc.h2
-rw-r--r--include/linux/wl12xx.h8
-rw-r--r--include/linux/xfrm.h1
-rw-r--r--include/media/bt819.h5
-rw-r--r--include/media/cx2341x.h2
-rw-r--r--include/media/ir-common.h107
-rw-r--r--include/media/ir-core.h214
-rw-r--r--include/media/ir-kbd-i2c.h13
-rw-r--r--include/media/lirc_dev.h6
-rw-r--r--include/media/ovcamchip.h90
-rw-r--r--include/media/rc-core.h220
-rw-r--r--include/media/rc-map.h44
-rw-r--r--include/media/saa6588.h (renamed from include/media/rds.h)18
-rw-r--r--include/media/saa7146.h2
-rw-r--r--include/media/si4713.h3
-rw-r--r--include/media/soc_camera.h5
-rw-r--r--include/media/timb_radio.h1
-rw-r--r--include/media/timb_video.h33
-rw-r--r--include/media/v4l2-chip-ident.h1
-rw-r--r--include/media/v4l2-common.h22
-rw-r--r--include/media/v4l2-ctrls.h4
-rw-r--r--include/media/v4l2-device.h2
-rw-r--r--include/media/v4l2-ioctl.h22
-rw-r--r--include/media/videobuf-core.h8
-rw-r--r--include/media/wm8775.h3
-rw-r--r--include/net/addrconf.h2
-rw-r--r--include/net/bluetooth/bluetooth.h1
-rw-r--r--include/net/bluetooth/hci.h20
-rw-r--r--include/net/bluetooth/hci_core.h23
-rw-r--r--include/net/bluetooth/l2cap.h22
-rw-r--r--include/net/bluetooth/mgmt.h87
-rw-r--r--include/net/bluetooth/rfcomm.h18
-rw-r--r--include/net/bluetooth/sco.h20
-rw-r--r--include/net/caif/cfctrl.h2
-rw-r--r--include/net/cfg80211.h171
-rw-r--r--include/net/dcbevent.h31
-rw-r--r--include/net/dcbnl.h28
-rw-r--r--include/net/dn_dev.h27
-rw-r--r--include/net/dn_route.h10
-rw-r--r--include/net/dst.h68
-rw-r--r--include/net/dst_ops.h2
-rw-r--r--include/net/flow.h3
-rw-r--r--include/net/if_inet6.h3
-rw-r--r--include/net/inet6_connection_sock.h3
-rw-r--r--include/net/inet_connection_sock.h3
-rw-r--r--include/net/inet_sock.h7
-rw-r--r--include/net/inet_timewait_sock.h20
-rw-r--r--include/net/inetpeer.h32
-rw-r--r--include/net/ip.h10
-rw-r--r--include/net/ip6_fib.h2
-rw-r--r--include/net/ip6_route.h23
-rw-r--r--include/net/mac80211.h134
-rw-r--r--include/net/ndisc.h3
-rw-r--r--include/net/neighbour.h10
-rw-r--r--include/net/netlink.h21
-rw-r--r--include/net/netns/generic.h2
-rw-r--r--include/net/pkt_cls.h4
-rw-r--r--include/net/regulatory.h7
-rw-r--r--include/net/route.h37
-rw-r--r--include/net/rtnetlink.h35
-rw-r--r--include/net/sch_generic.h7
-rw-r--r--include/net/scm.h5
-rw-r--r--include/net/sctp/command.h3
-rw-r--r--include/net/sctp/constants.h14
-rw-r--r--include/net/sctp/structs.h2
-rw-r--r--include/net/snmp.h4
-rw-r--r--include/net/sock.h104
-rw-r--r--include/net/tcp.h22
-rw-r--r--include/net/timewait_sock.h8
-rw-r--r--include/net/tipc/tipc.h186
-rw-r--r--include/net/tipc/tipc_bearer.h138
-rw-r--r--include/net/tipc/tipc_msg.h207
-rw-r--r--include/net/tipc/tipc_port.h101
-rw-r--r--include/net/x25.h2
-rw-r--r--include/net/xfrm.h7
-rw-r--r--include/scsi/iscsi_if.h1
-rw-r--r--include/scsi/libfc.h10
-rw-r--r--include/scsi/libfcoe.h8
-rw-r--r--include/scsi/libiscsi.h4
-rw-r--r--include/scsi/libsas.h2
-rw-r--r--include/scsi/scsi.h29
-rw-r--r--include/sound/alc5623.h15
-rw-r--r--include/sound/asound.h3
-rw-r--r--include/sound/hdsp.h1
-rw-r--r--include/sound/minors.h4
-rw-r--r--include/sound/pcm.h1
-rw-r--r--include/sound/soc-dai.h4
-rw-r--r--include/sound/soc-dapm.h99
-rw-r--r--include/sound/soc.h116
-rw-r--r--include/trace/events/asoc.h235
-rw-r--r--include/trace/events/block.h6
-rw-r--r--include/trace/events/kvm.h121
-rw-r--r--include/xen/events.h7
-rw-r--r--include/xen/interface/io/ring.h11
-rw-r--r--include/xen/interface/physdev.h10
-rw-r--r--init/do_mounts.c2
-rw-r--r--ipc/mqueue.c9
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/cgroup.c54
-rw-r--r--kernel/exit.c9
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/irq/proc.c2
-rw-r--r--kernel/kthread.c11
-rw-r--r--kernel/mutex.c2
-rw-r--r--kernel/perf_event.c37
-rw-r--r--kernel/power/hibernate.c22
-rw-r--r--kernel/power/suspend.c5
-rw-r--r--kernel/power/swap.c60
-rw-r--r--kernel/power/user.c4
-rw-r--r--kernel/printk.c4
-rw-r--r--kernel/resource.c104
-rw-r--r--kernel/sched.c290
-rw-r--r--kernel/taskstats.c57
-rw-r--r--kernel/time/clocksource.c1
-rw-r--r--kernel/timer.c8
-rw-r--r--kernel/trace/blktrace.c12
-rw-r--r--kernel/trace/ring_buffer.c9
-rw-r--r--kernel/trace/trace.c10
-rw-r--r--kernel/user.c1
-rw-r--r--kernel/watchdog.c3
-rw-r--r--kernel/workqueue.c7
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/Makefile2
-rw-r--r--lib/average.c61
-rw-r--r--lib/nlattr.c22
-rw-r--r--mm/compaction.c1
-rw-r--r--mm/filemap.c11
-rw-r--r--mm/hugetlb.c3
-rw-r--r--mm/ksm.c7
-rw-r--r--mm/memcontrol.c19
-rw-r--r--mm/memory-failure.c8
-rw-r--r--mm/memory.c31
-rw-r--r--mm/memory_hotplug.c31
-rw-r--r--mm/mempolicy.c3
-rw-r--r--mm/migrate.c2
-rw-r--r--mm/mmap.c16
-rw-r--r--mm/nommu.c28
-rw-r--r--mm/page-writeback.c2
-rw-r--r--mm/page_alloc.c19
-rw-r--r--mm/percpu.c2
-rw-r--r--mm/shmem.c23
-rw-r--r--mm/slab.c32
-rw-r--r--mm/slob.c5
-rw-r--r--mm/slub.c44
-rw-r--r--mm/swapfile.c7
-rw-r--r--mm/truncate.c4
-rw-r--r--mm/util.c21
-rw-r--r--mm/vmalloc.c28
-rw-r--r--mm/vmscan.c7
-rw-r--r--mm/vmstat.c4
-rw-r--r--net/8021q/vlan.c13
-rw-r--r--net/8021q/vlan.h22
-rw-r--r--net/8021q/vlan_core.c4
-rw-r--r--net/8021q/vlan_dev.c197
-rw-r--r--net/8021q/vlan_netlink.c20
-rw-r--r--net/8021q/vlanproc.c5
-rw-r--r--net/9p/protocol.c33
-rw-r--r--net/Kconfig6
-rw-r--r--net/Makefile1
-rw-r--r--net/atm/atm_sysfs.c3
-rw-r--r--net/atm/br2684.c2
-rw-r--r--net/atm/clip.c3
-rw-r--r--net/atm/lec.c3
-rw-r--r--net/atm/mpc.c2
-rw-r--r--net/atm/resources.c7
-rw-r--r--net/atm/resources.h2
-rw-r--r--net/batman-adv/Kconfig25
-rw-r--r--net/batman-adv/Makefile39
-rw-r--r--net/batman-adv/aggregation.c273
-rw-r--r--net/batman-adv/aggregation.h43
-rw-r--r--net/batman-adv/bat_debugfs.c360
-rw-r--r--net/batman-adv/bat_debugfs.h33
-rw-r--r--net/batman-adv/bat_sysfs.c593
-rw-r--r--net/batman-adv/bat_sysfs.h42
-rw-r--r--net/batman-adv/bitarray.c201
-rw-r--r--net/batman-adv/bitarray.h44
-rw-r--r--net/batman-adv/gateway_client.c477
-rw-r--r--net/batman-adv/gateway_client.h36
-rw-r--r--net/batman-adv/gateway_common.c177
-rw-r--r--net/batman-adv/gateway_common.h38
-rw-r--r--net/batman-adv/hard-interface.c651
-rw-r--r--net/batman-adv/hard-interface.h53
-rw-r--r--net/batman-adv/hash.c62
-rw-r--r--net/batman-adv/hash.h176
-rw-r--r--net/batman-adv/icmp_socket.c356
-rw-r--r--net/batman-adv/icmp_socket.h34
-rw-r--r--net/batman-adv/main.c187
-rw-r--r--net/batman-adv/main.h183
-rw-r--r--net/batman-adv/originator.c564
-rw-r--r--net/batman-adv/originator.h64
-rw-r--r--net/batman-adv/packet.h136
-rw-r--r--net/batman-adv/ring_buffer.c52
-rw-r--r--net/batman-adv/ring_buffer.h28
-rw-r--r--net/batman-adv/routing.c1397
-rw-r--r--net/batman-adv/routing.h48
-rw-r--r--net/batman-adv/send.c585
-rw-r--r--net/batman-adv/send.h41
-rw-r--r--net/batman-adv/soft-interface.c697
-rw-r--r--net/batman-adv/soft-interface.h35
-rw-r--r--net/batman-adv/translation-table.c534
-rw-r--r--net/batman-adv/translation-table.h45
-rw-r--r--net/batman-adv/types.h271
-rw-r--r--net/batman-adv/unicast.c343
-rw-r--r--net/batman-adv/unicast.h35
-rw-r--r--net/batman-adv/vis.c949
-rw-r--r--net/batman-adv/vis.h37
-rw-r--r--net/bluetooth/Makefile2
-rw-r--r--net/bluetooth/bnep/core.c1
-rw-r--r--net/bluetooth/cmtp/core.c1
-rw-r--r--net/bluetooth/hci_conn.c23
-rw-r--r--net/bluetooth/hci_core.c83
-rw-r--r--net/bluetooth/hci_event.c210
-rw-r--r--net/bluetooth/hci_sock.c67
-rw-r--r--net/bluetooth/hidp/core.c2
-rw-r--r--net/bluetooth/l2cap.c102
-rw-r--r--net/bluetooth/mgmt.c308
-rw-r--r--net/bluetooth/rfcomm/core.c9
-rw-r--r--net/bluetooth/rfcomm/sock.c24
-rw-r--r--net/bluetooth/rfcomm/tty.c28
-rw-r--r--net/bluetooth/sco.c28
-rw-r--r--net/bridge/br.c4
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_fdb.c15
-rw-r--r--net/bridge/br_forward.c4
-rw-r--r--net/bridge/br_if.c7
-rw-r--r--net/bridge/br_input.c10
-rw-r--r--net/bridge/br_multicast.c118
-rw-r--r--net/bridge/br_netfilter.c49
-rw-r--r--net/bridge/br_netlink.c10
-rw-r--r--net/bridge/br_notify.c6
-rw-r--r--net/bridge/br_private.h21
-rw-r--r--net/bridge/br_stp_bpdu.c10
-rw-r--r--net/bridge/br_stp_if.c2
-rw-r--r--net/bridge/netfilter/ebtable_broute.c3
-rw-r--r--net/bridge/netfilter/ebtables.c13
-rw-r--r--net/caif/Makefile8
-rw-r--r--net/can/Makefile6
-rw-r--r--net/can/bcm.c4
-rw-r--r--net/ceph/Makefile2
-rw-r--r--net/ceph/ceph_hash.c3
-rw-r--r--net/ceph/messenger.c54
-rw-r--r--net/ceph/osdmap.c4
-rw-r--r--net/ceph/pagevec.c15
-rw-r--r--net/core/datagram.c2
-rw-r--r--net/core/dev.c383
-rw-r--r--net/core/ethtool.c21
-rw-r--r--net/core/fib_rules.c3
-rw-r--r--net/core/filter.c533
-rw-r--r--net/core/neighbour.c1
-rw-r--r--net/core/net-sysfs.c430
-rw-r--r--net/core/net-sysfs.h4
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/core/pktgen.c44
-rw-r--r--net/core/request_sock.c1
-rw-r--r--net/core/rtnetlink.c166
-rw-r--r--net/core/scm.c10
-rw-r--r--net/core/skbuff.c36
-rw-r--r--net/core/sock.c64
-rw-r--r--net/core/timestamping.c10
-rw-r--r--net/dcb/Makefile2
-rw-r--r--net/dcb/dcbevent.c40
-rw-r--r--net/dcb/dcbnl.c429
-rw-r--r--net/dccp/Makefile4
-rw-r--r--net/dccp/ackvec.c616
-rw-r--r--net/dccp/ackvec.h151
-rw-r--r--net/dccp/ccids/ccid2.c143
-rw-r--r--net/dccp/ccids/ccid2.h2
-rw-r--r--net/dccp/dccp.h32
-rw-r--r--net/dccp/input.c33
-rw-r--r--net/dccp/ipv4.c13
-rw-r--r--net/dccp/options.c100
-rw-r--r--net/dccp/output.c22
-rw-r--r--net/dccp/proto.c71
-rw-r--r--net/dccp/qpolicy.c137
-rw-r--r--net/decnet/af_decnet.c6
-rw-r--r--net/decnet/dn_dev.c100
-rw-r--r--net/decnet/dn_fib.c6
-rw-r--r--net/decnet/dn_neigh.c2
-rw-r--r--net/decnet/dn_route.c137
-rw-r--r--net/decnet/dn_rules.c2
-rw-r--r--net/dns_resolver/Makefile2
-rw-r--r--net/econet/Makefile2
-rw-r--r--net/econet/af_econet.c12
-rw-r--r--net/ieee802154/af_ieee802154.c6
-rw-r--r--net/ipv4/af_inet.c18
-rw-r--r--net/ipv4/arp.c31
-rw-r--r--net/ipv4/devinet.c97
-rw-r--r--net/ipv4/esp4.c32
-rw-r--r--net/ipv4/fib_frontend.c44
-rw-r--r--net/ipv4/fib_semantics.c8
-rw-r--r--net/ipv4/icmp.c32
-rw-r--r--net/ipv4/igmp.c282
-rw-r--r--net/ipv4/inet_connection_sock.c22
-rw-r--r--net/ipv4/inetpeer.c167
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/ip_gre.c52
-rw-r--r--net/ipv4/ip_output.c28
-rw-r--r--net/ipv4/ipconfig.c32
-rw-r--r--net/ipv4/ipip.c21
-rw-r--r--net/ipv4/ipmr.c20
-rw-r--r--net/ipv4/netfilter.c8
-rw-r--r--net/ipv4/netfilter/Makefile6
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/proc.c1
-rw-r--r--net/ipv4/raw.c7
-rw-r--r--net/ipv4/route.c267
-rw-r--r--net/ipv4/syncookies.c15
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
-rw-r--r--net/ipv4/tcp.c16
-rw-r--r--net/ipv4/tcp_input.c51
-rw-r--r--net/ipv4/tcp_ipv4.c78
-rw-r--r--net/ipv4/tcp_minisocks.c65
-rw-r--r--net/ipv4/tcp_output.c79
-rw-r--r--net/ipv4/tcp_probe.c4
-rw-r--r--net/ipv4/udp.c19
-rw-r--r--net/ipv4/udplite.c1
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c2
-rw-r--r--net/ipv4/xfrm4_policy.c47
-rw-r--r--net/ipv6/addrconf.c123
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/esp6.c32
-rw-r--r--net/ipv6/inet6_connection_sock.c54
-rw-r--r--net/ipv6/ip6_output.c12
-rw-r--r--net/ipv6/ip6_tunnel.c9
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/mcast.c77
-rw-r--r--net/ipv6/ndisc.c29
-rw-r--r--net/ipv6/netfilter.c6
-rw-r--r--net/ipv6/netfilter/Makefile4
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c2
-rw-r--r--net/ipv6/reassembly.c36
-rw-r--r--net/ipv6/route.c163
-rw-r--r--net/ipv6/sit.c17
-rw-r--r--net/ipv6/tcp_ipv6.c151
-rw-r--r--net/ipv6/udp.c11
-rw-r--r--net/ipv6/udplite.c1
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c3
-rw-r--r--net/ipv6/xfrm6_output.c16
-rw-r--r--net/irda/af_irda.c18
-rw-r--r--net/irda/ircomm/Makefile4
-rw-r--r--net/irda/irlan/Makefile2
-rw-r--r--net/irda/irnet/Makefile2
-rw-r--r--net/iucv/iucv.c2
-rw-r--r--net/l2tp/l2tp_ip.c18
-rw-r--r--net/lapb/Makefile2
-rw-r--r--net/llc/af_llc.c11
-rw-r--r--net/mac80211/Kconfig3
-rw-r--r--net/mac80211/aes_ccm.c3
-rw-r--r--net/mac80211/aes_cmac.c3
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c7
-rw-r--r--net/mac80211/cfg.c231
-rw-r--r--net/mac80211/debugfs.c60
-rw-r--r--net/mac80211/debugfs.h2
-rw-r--r--net/mac80211/debugfs_key.c56
-rw-r--r--net/mac80211/debugfs_key.h8
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/debugfs_sta.c57
-rw-r--r--net/mac80211/driver-ops.h39
-rw-r--r--net/mac80211/driver-trace.h71
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/ieee80211_i.h65
-rw-r--r--net/mac80211/iface.c45
-rw-r--r--net/mac80211/key.c98
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/led.c186
-rw-r--r--net/mac80211/led.h45
-rw-r--r--net/mac80211/main.c25
-rw-r--r--net/mac80211/mesh.c88
-rw-r--r--net/mac80211/mesh.h45
-rw-r--r--net/mac80211/mesh_hwmp.c9
-rw-r--r--net/mac80211/mesh_pathtbl.c7
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/mlme.c227
-rw-r--r--net/mac80211/rate.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c21
-rw-r--r--net/mac80211/rx.c195
-rw-r--r--net/mac80211/sta_info.c19
-rw-r--r--net/mac80211/sta_info.h37
-rw-r--r--net/mac80211/status.c51
-rw-r--r--net/mac80211/tx.c88
-rw-r--r--net/mac80211/util.c43
-rw-r--r--net/mac80211/wme.c31
-rw-r--r--net/mac80211/work.c32
-rw-r--r--net/netfilter/core.c6
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c6
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c42
-rw-r--r--net/netfilter/xt_TEE.c12
-rw-r--r--net/netlabel/netlabel_cipso_v4.h1
-rw-r--r--net/netlabel/netlabel_mgmt.h1
-rw-r--r--net/netlabel/netlabel_unlabeled.h1
-rw-r--r--net/packet/af_packet.c156
-rw-r--r--net/phonet/Makefile4
-rw-r--r--net/rds/Makefile8
-rw-r--r--net/rfkill/core.c14
-rw-r--r--net/rxrpc/Makefile4
-rw-r--r--net/rxrpc/ar-peer.c10
-rw-r--r--net/sched/sch_generic.c41
-rw-r--r--net/sched/sch_red.c1
-rw-r--r--net/sched/sch_sfq.c291
-rw-r--r--net/sched/sch_teql.c3
-rw-r--r--net/sctp/socket.c12
-rw-r--r--net/socket.c50
-rw-r--r--net/sunrpc/auth.c28
-rw-r--r--net/sunrpc/auth_gss/Makefile4
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c44
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/cache.c54
-rw-r--r--net/sunrpc/clnt.c21
-rw-r--r--net/sunrpc/rpc_pipe.c16
-rw-r--r--net/sunrpc/rpcb_clnt.c147
-rw-r--r--net/sunrpc/svc.c3
-rw-r--r--net/sunrpc/svc_xprt.c102
-rw-r--r--net/sunrpc/svcauth.c1
-rw-r--r--net/sunrpc/svcauth_unix.c17
-rw-r--r--net/sunrpc/svcsock.c10
-rw-r--r--net/tipc/Kconfig35
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/addr.c10
-rw-r--r--net/tipc/addr.h25
-rw-r--r--net/tipc/bcast.c50
-rw-r--r--net/tipc/bcast.h1
-rw-r--r--net/tipc/bearer.c22
-rw-r--r--net/tipc/bearer.h71
-rw-r--r--net/tipc/cluster.c557
-rw-r--r--net/tipc/cluster.h92
-rw-r--r--net/tipc/config.c118
-rw-r--r--net/tipc/config.h1
-rw-r--r--net/tipc/core.c101
-rw-r--r--net/tipc/core.h76
-rw-r--r--net/tipc/discover.c14
-rw-r--r--net/tipc/discover.h2
-rw-r--r--net/tipc/eth_media.c15
-rw-r--r--net/tipc/handler.c2
-rw-r--r--net/tipc/link.c383
-rw-r--r--net/tipc/link.h10
-rw-r--r--net/tipc/log.c (renamed from net/tipc/dbg.c)111
-rw-r--r--net/tipc/log.h (renamed from net/tipc/dbg.h)6
-rw-r--r--net/tipc/msg.c75
-rw-r--r--net/tipc/msg.h185
-rw-r--r--net/tipc/name_distr.c47
-rw-r--r--net/tipc/name_table.c60
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c72
-rw-r--r--net/tipc/net.h14
-rw-r--r--net/tipc/node.c301
-rw-r--r--net/tipc/node.h27
-rw-r--r--net/tipc/node_subscr.c2
-rw-r--r--net/tipc/port.c170
-rw-r--r--net/tipc/port.h137
-rw-r--r--net/tipc/ref.c8
-rw-r--r--net/tipc/socket.c155
-rw-r--r--net/tipc/subscr.c38
-rw-r--r--net/tipc/user_reg.c264
-rw-r--r--net/tipc/user_reg.h48
-rw-r--r--net/tipc/zone.c162
-rw-r--r--net/tipc/zone.h70
-rw-r--r--net/unix/af_unix.c34
-rw-r--r--net/wanrouter/Makefile2
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c33
-rw-r--r--net/wireless/core.h18
-rw-r--r--net/wireless/lib80211.c8
-rw-r--r--net/wireless/lib80211_crypt_tkip.c16
-rw-r--r--net/wireless/mesh.c142
-rw-r--r--net/wireless/mlme.c43
-rw-r--r--net/wireless/nl80211.c612
-rw-r--r--net/wireless/nl80211.h10
-rw-r--r--net/wireless/reg.c262
-rw-r--r--net/wireless/scan.c11
-rw-r--r--net/wireless/util.c15
-rw-r--r--net/wireless/wext-compat.c8
-rw-r--r--net/wireless/wext-core.c10
-rw-r--r--net/x25/af_x25.c95
-rw-r--r--net/x25/x25_link.c9
-rw-r--r--net/xfrm/xfrm_policy.c20
-rw-r--r--net/xfrm/xfrm_state.c2
-rw-r--r--net/xfrm/xfrm_user.c19
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/basic/fixdep.c119
-rwxr-xr-xscripts/checksyscalls.sh4
-rw-r--r--scripts/coccinelle/misc/doubleinit.cocci6
-rw-r--r--scripts/coccinelle/null/deref_null.cocci39
-rwxr-xr-xscripts/config13
-rw-r--r--scripts/genksyms/parse.c_shipped2
-rw-r--r--scripts/genksyms/parse.y2
-rwxr-xr-xscripts/headers.sh2
-rw-r--r--scripts/headers_check.pl6
-rw-r--r--scripts/headers_install.pl7
-rw-r--r--scripts/kconfig/conf.c2
-rw-r--r--scripts/kconfig/confdata.c27
-rw-r--r--scripts/kconfig/expr.c44
-rw-r--r--scripts/kconfig/expr.h4
-rw-r--r--scripts/kconfig/lkc.h8
-rw-r--r--scripts/kconfig/menu.c40
-rw-r--r--scripts/kconfig/nconf.c2
-rw-r--r--scripts/kconfig/symbol.c8
-rw-r--r--scripts/kconfig/zconf.gperf1
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped122
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped570
-rw-r--r--scripts/kconfig/zconf.y21
-rwxr-xr-xscripts/kernel-doc102
-rw-r--r--scripts/mod/modpost.c3
-rw-r--r--scripts/package/builddeb72
-rw-r--r--scripts/recordmcount.c7
-rw-r--r--scripts/recordmcount.h7
-rwxr-xr-xscripts/tags.sh6
-rw-r--r--security/integrity/ima/ima_policy.c2
-rw-r--r--security/keys/request_key.c1
-rw-r--r--security/security.c9
-rw-r--r--security/selinux/hooks.c12
-rw-r--r--security/selinux/selinuxfs.c16
-rw-r--r--security/tomoyo/realpath.c1
-rw-r--r--sound/ac97_bus.c4
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/aoa/core/gpio-feature.c7
-rw-r--r--sound/aoa/core/gpio-pmf.c7
-rw-r--r--sound/core/oss/pcm_oss.c19
-rw-r--r--sound/core/pcm_lib.c32
-rw-r--r--sound/core/pcm_native.c3
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c18
-rw-r--r--sound/core/timer.c7
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/i2c/other/ak4113.c5
-rw-r--r--sound/i2c/other/ak4114.c5
-rw-r--r--sound/oss/soundcard.c4
-rw-r--r--sound/pci/Kconfig19
-rw-r--r--sound/pci/ac97/ac97_codec.c6
-rw-r--r--sound/pci/azt3328.c406
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c7
-rw-r--r--sound/pci/hda/hda_codec.c57
-rw-r--r--sound/pci/hda/hda_eld.c24
-rw-r--r--sound/pci/hda/hda_intel.c11
-rw-r--r--sound/pci/hda/patch_conexant.c109
-rw-r--r--sound/pci/hda/patch_hdmi.c44
-rw-r--r--sound/pci/hda/patch_realtek.c389
-rw-r--r--sound/pci/hda/patch_sigmatel.c10
-rw-r--r--sound/pci/hda/patch_via.c3
-rw-r--r--sound/pci/ice1712/delta.c49
-rw-r--r--sound/pci/ice1712/delta.h11
-rw-r--r--sound/pci/oxygen/Makefile2
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c133
-rw-r--r--sound/pci/oxygen/oxygen.h4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c24
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c55
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c14
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c70
-rw-r--r--sound/pci/oxygen/xonar_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c234
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c73
-rw-r--r--sound/pci/rme9652/hdsp.c538
-rw-r--r--sound/soc/Kconfig17
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c12
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c18
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c14
-rw-r--r--sound/soc/au1x/db1200.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c1
-rw-r--r--sound/soc/codecs/88pm860x-codec.c30
-rw-r--r--sound/soc/codecs/Kconfig17
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad1836.c7
-rw-r--r--sound/soc/codecs/ad193x.c8
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ak4535.c20
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c11
-rw-r--r--sound/soc/codecs/alc5623.c1117
-rw-r--r--sound/soc/codecs/alc5623.h161
-rw-r--r--sound/soc/codecs/cq93vc.c4
-rw-r--r--sound/soc/codecs/cs4270.c1
-rw-r--r--sound/soc/codecs/cs42l51.c7
-rw-r--r--sound/soc/codecs/cx20442.c16
-rw-r--r--sound/soc/codecs/da7210.c2
-rw-r--r--sound/soc/codecs/jz4740.c11
-rw-r--r--sound/soc/codecs/max98088.c23
-rw-r--r--sound/soc/codecs/ssm2602.c10
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tlv320aic23.c10
-rw-r--r--sound/soc/codecs/tlv320aic26.c5
-rw-r--r--sound/soc/codecs/tlv320aic3x.c71
-rw-r--r--sound/soc/codecs/tlv320dac33.c73
-rw-r--r--sound/soc/codecs/tpa6130a2.c100
-rw-r--r--sound/soc/codecs/tpa6130a2.h1
-rw-r--r--sound/soc/codecs/twl4030.c56
-rw-r--r--sound/soc/codecs/twl6040.c855
-rw-r--r--sound/soc/codecs/twl6040.h8
-rw-r--r--sound/soc/codecs/uda134x.c3
-rw-r--r--sound/soc/codecs/uda1380.c15
-rw-r--r--sound/soc/codecs/wl1273.c3
-rw-r--r--sound/soc/codecs/wm2000.c6
-rw-r--r--sound/soc/codecs/wm8350.c105
-rw-r--r--sound/soc/codecs/wm8400.c12
-rw-r--r--sound/soc/codecs/wm8510.c12
-rw-r--r--sound/soc/codecs/wm8523.c21
-rw-r--r--sound/soc/codecs/wm8580.c33
-rw-r--r--sound/soc/codecs/wm8711.c11
-rw-r--r--sound/soc/codecs/wm8728.c12
-rw-r--r--sound/soc/codecs/wm8731.c104
-rw-r--r--sound/soc/codecs/wm8737.c754
-rw-r--r--sound/soc/codecs/wm8737.h322
-rw-r--r--sound/soc/codecs/wm8741.c20
-rw-r--r--sound/soc/codecs/wm8750.c13
-rw-r--r--sound/soc/codecs/wm8753.c275
-rw-r--r--sound/soc/codecs/wm8770.c749
-rw-r--r--sound/soc/codecs/wm8770.h51
-rw-r--r--sound/soc/codecs/wm8776.c10
-rw-r--r--sound/soc/codecs/wm8804.c7
-rw-r--r--sound/soc/codecs/wm8900.c13
-rw-r--r--sound/soc/codecs/wm8903.c222
-rw-r--r--sound/soc/codecs/wm8903.h25
-rw-r--r--sound/soc/codecs/wm8904.c76
-rw-r--r--sound/soc/codecs/wm8940.c9
-rw-r--r--sound/soc/codecs/wm8955.c46
-rw-r--r--sound/soc/codecs/wm8960.c33
-rw-r--r--sound/soc/codecs/wm8961.c13
-rw-r--r--sound/soc/codecs/wm8962.c88
-rw-r--r--sound/soc/codecs/wm8971.c31
-rw-r--r--sound/soc/codecs/wm8974.c13
-rw-r--r--sound/soc/codecs/wm8978.c13
-rw-r--r--sound/soc/codecs/wm8985.c12
-rw-r--r--sound/soc/codecs/wm8988.c11
-rw-r--r--sound/soc/codecs/wm8990.c12
-rw-r--r--sound/soc/codecs/wm8993.c21
-rw-r--r--sound/soc/codecs/wm8994-tables.c3147
-rw-r--r--sound/soc/codecs/wm8994.c2544
-rw-r--r--sound/soc/codecs/wm8994.h14
-rw-r--r--sound/soc/codecs/wm8995.c1818
-rw-r--r--sound/soc/codecs/wm8995.h4269
-rw-r--r--sound/soc/codecs/wm9081.c16
-rw-r--r--sound/soc/codecs/wm9090.c36
-rw-r--r--sound/soc/codecs/wm9705.c7
-rw-r--r--sound/soc/codecs/wm9712.c10
-rw-r--r--sound/soc/codecs/wm9713.c9
-rw-r--r--sound/soc/codecs/wm_hubs.c110
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c22
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c4
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/ep93xx/snappercl15.c6
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c1
-rw-r--r--sound/soc/fsl/p1022_ds.c1
-rw-r--r--sound/soc/imx/eukrea-tlv320.c1
-rw-r--r--sound/soc/imx/imx-ssi.c4
-rw-r--r--sound/soc/imx/phycore-ac97.c1
-rw-r--r--sound/soc/imx/wm1133-ev1.c8
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c1
-rw-r--r--sound/soc/jz4740/qi_lb60.c14
-rw-r--r--sound/soc/kirkwood/Kconfig11
-rw-r--r--sound/soc/kirkwood/Makefile2
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c141
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c15
-rw-r--r--sound/soc/nuc900/nuc900-audio.c1
-rw-r--r--sound/soc/nuc900/nuc900-audio.h2
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c11
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/am3517evm.c14
-rw-r--r--sound/soc/omap/ams-delta.c82
-rw-r--r--sound/soc/omap/igep0020.c1
-rw-r--r--sound/soc/omap/n810.c43
-rw-r--r--sound/soc/omap/omap2evm.c1
-rw-r--r--sound/soc/omap/omap3beagle.c1
-rw-r--r--sound/soc/omap/omap3evm.c1
-rw-r--r--sound/soc/omap/omap3pandora.c45
-rw-r--r--sound/soc/omap/osk5912.c14
-rw-r--r--sound/soc/omap/overo.c1
-rw-r--r--sound/soc/omap/rx51.c26
-rw-r--r--sound/soc/omap/sdp3430.c44
-rw-r--r--sound/soc/omap/sdp4430.c57
-rw-r--r--sound/soc/omap/zoom2.c36
-rw-r--r--sound/soc/pxa/corgi.c52
-rw-r--r--sound/soc/pxa/e740_wm9705.c30
-rw-r--r--sound/soc/pxa/e750_wm9705.c30
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c1
-rw-r--r--sound/soc/pxa/magician.c36
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c18
-rw-r--r--sound/soc/pxa/palm27x.c34
-rw-r--r--sound/soc/pxa/poodle.c26
-rw-r--r--sound/soc/pxa/raumfeld.c1
-rw-r--r--sound/soc/pxa/saarb.c18
-rw-r--r--sound/soc/pxa/spitz.c70
-rw-r--r--sound/soc/pxa/tavorevb3.c18
-rw-r--r--sound/soc/pxa/tosa.c38
-rw-r--r--sound/soc/pxa/z2.c16
-rw-r--r--sound/soc/pxa/zylonite.c12
-rw-r--r--sound/soc/s3c24xx/Kconfig171
-rw-r--r--sound/soc/s3c24xx/Makefile55
-rw-r--r--sound/soc/s3c24xx/aquila_wm8994.c295
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c230
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c242
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h41
-rw-r--r--sound/soc/s6000/s6000-i2s.c2
-rw-r--r--sound/soc/s6000/s6000-pcm.c2
-rw-r--r--sound/soc/s6000/s6105-ipcam.c43
-rw-r--r--sound/soc/samsung/Kconfig171
-rw-r--r--sound/soc/samsung/Makefile55
-rw-r--r--sound/soc/samsung/ac97.c (renamed from sound/soc/s3c24xx/s3c-ac97.c)22
-rw-r--r--sound/soc/samsung/ac97.h (renamed from sound/soc/s3c24xx/s3c-ac97.h)8
-rw-r--r--sound/soc/samsung/dma.c (renamed from sound/soc/s3c24xx/s3c-dma.c)134
-rw-r--r--sound/soc/samsung/dma.h (renamed from sound/soc/s3c24xx/s3c-dma.h)2
-rw-r--r--sound/soc/samsung/goni_wm8994.c (renamed from sound/soc/s3c24xx/goni_wm8994.c)66
-rw-r--r--sound/soc/samsung/h1940_uda1380.c296
-rw-r--r--sound/soc/samsung/i2s.c1258
-rw-r--r--sound/soc/samsung/i2s.h29
-rw-r--r--sound/soc/samsung/jive_wm8750.c (renamed from sound/soc/s3c24xx/jive_wm8750.c)26
-rw-r--r--sound/soc/samsung/lm4857.h (renamed from sound/soc/s3c24xx/lm4857.h)0
-rw-r--r--sound/soc/samsung/ln2440sbc_alc650.c (renamed from sound/soc/s3c24xx/ln2440sbc_alc650.c)9
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_gta02_wm8753.c)72
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_wm8753.c)130
-rw-r--r--sound/soc/samsung/pcm.c (renamed from sound/soc/s3c24xx/s3c-pcm.c)6
-rw-r--r--sound/soc/samsung/pcm.h (renamed from sound/soc/s3c24xx/s3c-pcm.h)2
-rw-r--r--sound/soc/samsung/regs-i2s-v2.h (renamed from sound/soc/s3c24xx/regs-i2s-v2.h)0
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c (renamed from sound/soc/s3c24xx/rx1950_uda1380.c)16
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c (renamed from sound/soc/s3c24xx/s3c-i2s-v2.c)4
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h (renamed from sound/soc/s3c24xx/s3c-i2s-v2.h)2
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c (renamed from sound/soc/s3c24xx/s3c2412-i2s.c)4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.h (renamed from sound/soc/s3c24xx/s3c2412-i2s.h)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c (renamed from sound/soc/s3c24xx/s3c24xx-i2s.c)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.h (renamed from sound/soc/s3c24xx/s3c24xx-i2s.h)0
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec.c)5
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.h (renamed from sound/soc/s3c24xx/s3c24xx_simtec.h)2
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_hermes.c)22
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c)22
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c (renamed from sound/soc/s3c24xx/s3c24xx_uda134x.c)5
-rw-r--r--sound/soc/samsung/smartq_wm8987.c (renamed from sound/soc/s3c24xx/smartq_wm8987.c)64
-rw-r--r--sound/soc/samsung/smdk2443_wm9710.c (renamed from sound/soc/s3c24xx/smdk2443_wm9710.c)9
-rw-r--r--sound/soc/samsung/smdk_spdif.c (renamed from sound/soc/s3c24xx/smdk_spdif.c)21
-rw-r--r--sound/soc/samsung/smdk_wm8580.c (renamed from sound/soc/s3c24xx/smdk64xx_wm8580.c)174
-rw-r--r--sound/soc/samsung/smdk_wm8994.c176
-rw-r--r--sound/soc/samsung/smdk_wm9713.c (renamed from sound/soc/s3c24xx/smdk_wm9713.c)26
-rw-r--r--sound/soc/samsung/spdif.c (renamed from sound/soc/s3c24xx/spdif.c)4
-rw-r--r--sound/soc/samsung/spdif.h (renamed from sound/soc/s3c24xx/spdif.h)2
-rw-r--r--sound/soc/sh/Kconfig4
-rw-r--r--sound/soc/sh/fsi-ak4642.c140
-rw-r--r--sound/soc/sh/fsi-da7210.c2
-rw-r--r--sound/soc/sh/fsi.c273
-rw-r--r--sound/soc/sh/migor.c6
-rw-r--r--sound/soc/sh/sh7760-ac97.c3
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_dai.c2
-rw-r--r--sound/soc/sh/siu_pcm.c2
-rw-r--r--sound/soc/soc-cache.c1065
-rw-r--r--sound/soc/soc-core.c571
-rw-r--r--sound/soc/soc-dapm.c861
-rw-r--r--sound/soc/soc-jack.c31
-rw-r--r--tools/perf/arch/s390/Makefile4
-rw-r--r--tools/perf/arch/s390/util/dwarf-regs.c22
-rw-r--r--tools/perf/builtin-buildid-list.c3
-rw-r--r--tools/perf/builtin-probe.c5
-rw-r--r--tools/perf/builtin-record.c6
-rw-r--r--tools/perf/util/header.c21
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/probe-event.c15
-rw-r--r--tools/perf/util/probe-finder.c85
-rw-r--r--tools/perf/util/string.c2
-rw-r--r--tools/perf/util/symbol.c63
-rw-r--r--tools/perf/util/symbol.h2
-rw-r--r--tools/virtio/Makefile12
-rw-r--r--tools/virtio/linux/device.h2
-rw-r--r--tools/virtio/linux/slab.h2
-rw-r--r--tools/virtio/linux/virtio.h223
-rw-r--r--tools/virtio/vhost_test/Makefile2
-rw-r--r--tools/virtio/vhost_test/vhost_test.c1
-rw-r--r--tools/virtio/virtio_test.c248
-rw-r--r--usr/gen_init_cpio.c20
-rw-r--r--usr/initramfs_data.S5
-rw-r--r--virt/kvm/Kconfig3
-rw-r--r--virt/kvm/assigned-dev.c125
-rw-r--r--virt/kvm/async_pf.c216
-rw-r--r--virt/kvm/async_pf.h36
-rw-r--r--virt/kvm/eventfd.c91
-rw-r--r--virt/kvm/irq_comm.c7
-rw-r--r--virt/kvm/kvm_main.c342
4950 files changed, 327056 insertions, 182362 deletions
diff --git a/.mailmap b/.mailmap
index a62e6a84fd1e..581fd39193a2 100644
--- a/.mailmap
+++ b/.mailmap
@@ -105,3 +105,4 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Uwe Kleine-König <ukl@pengutronix.de>
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+Takashi YOSHII <takashi.yoshii.zj@renesas.com>
diff --git a/Documentation/ABI/stable/thermal-notification b/Documentation/ABI/stable/thermal-notification
new file mode 100644
index 000000000000..9723e8b7aeb3
--- /dev/null
+++ b/Documentation/ABI/stable/thermal-notification
@@ -0,0 +1,4 @@
+What: A notification mechanism for thermal related events
+Description:
+ This interface enables notification for thermal related events.
+ The notification is in the form of a netlink event.
diff --git a/Documentation/ABI/testing/pstore b/Documentation/ABI/testing/pstore
new file mode 100644
index 000000000000..f1fb2a004264
--- /dev/null
+++ b/Documentation/ABI/testing/pstore
@@ -0,0 +1,35 @@
+Where: /dev/pstore/...
+Date: January 2011
+Kernel Version: 2.6.38
+Contact: tony.luck@intel.com
+Description: Generic interface to platform dependent persistent storage.
+
+ Platforms that provide a mechanism to preserve some data
+ across system reboots can register with this driver to
+ provide a generic interface to show records captured in
+ the dying moments. In the case of a panic the last part
+ of the console log is captured, but other interesting
+ data can also be saved.
+
+ # mount -t pstore - /dev/pstore
+
+ $ ls -l /dev/pstore
+ total 0
+ -r--r--r-- 1 root root 7896 Nov 30 15:38 dmesg-erst-1
+
+ Different users of this interface will result in different
+ filename prefixes. Currently two are defined:
+
+ "dmesg" - saved console log
+ "mce" - architecture dependent data from fatal h/w error
+
+ Once the information in a file has been read, removing
+ the file will signal to the underlying persistent storage
+ device that it can reclaim the space for later re-use.
+
+ $ rm /dev/pstore/dmesg-erst-1
+
+ The expectation is that all files in /dev/pstore
+ will be saved elsewhere and erased from persistent store
+ soon after boot to free up space ready for the next
+ catastrophe.
diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
new file mode 100644
index 000000000000..90a87e2a572b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-rbd
@@ -0,0 +1,83 @@
+What: /sys/bus/rbd/
+Date: November 2010
+Contact: Yehuda Sadeh <yehuda@hq.newdream.net>,
+ Sage Weil <sage@newdream.net>
+Description:
+
+Being used for adding and removing rbd block devices.
+
+Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
+
+ $ echo "192.168.0.1 name=admin rbd foo" > /sys/bus/rbd/add
+
+The snapshot name can be "-" or omitted to map the image read/write. A <dev-id>
+will be assigned for any registered block device. If snapshot is used, it will
+be mapped read-only.
+
+Removal of a device:
+
+ $ echo <dev-id> > /sys/bus/rbd/remove
+
+Entries under /sys/bus/rbd/devices/<dev-id>/
+--------------------------------------------
+
+client_id
+
+ The ceph unique client id that was assigned for this specific session.
+
+major
+
+ The block device major number.
+
+name
+
+ The name of the rbd image.
+
+pool
+
+ The pool where this rbd image resides. The pool-name pair is unique
+ per rados system.
+
+size
+
+ The size (in bytes) of the mapped block device.
+
+refresh
+
+ Writing to this file will reread the image header data and set
+ all relevant datastructures accordingly.
+
+current_snap
+
+ The current snapshot for which the device is mapped.
+
+create_snap
+
+ Create a snapshot:
+
+ $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
+
+rollback_snap
+
+ Rolls back data to the specified snapshot. This goes over the entire
+ list of rados blocks and sends a rollback command to each.
+
+ $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_rollback
+
+snap_*
+
+ A directory per each snapshot
+
+
+Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
+-------------------------------------------------------------
+
+id
+
+ The rados internal snapshot id assigned for this snapshot
+
+size
+
+ The size of the image when this snapshot was taken.
+
+
diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv
new file mode 100644
index 000000000000..38dd762def4b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv
@@ -0,0 +1,14 @@
+
+What: /sys/class/net/<iface>/batman-adv/mesh_iface
+Date: May 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ The /sys/class/net/<iface>/batman-adv/mesh_iface file
+ displays the batman mesh interface this <iface>
+ currently is associated with.
+
+What: /sys/class/net/<iface>/batman-adv/iface_status
+Date: May 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Indicates the status of <iface> as it is seen by batman.
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
new file mode 100644
index 000000000000..748fe1701d25
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -0,0 +1,69 @@
+
+What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
+Date: May 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Indicates whether the batman protocol messages of the
+ mesh <mesh_iface> shall be aggregated or not.
+
+What: /sys/class/net/<mesh_iface>/mesh/bonding
+Date: June 2010
+Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Description:
+ Indicates whether the data traffic going through the
+ mesh will be sent using multiple interfaces at the
+ same time (if available).
+
+What: /sys/class/net/<mesh_iface>/mesh/fragmentation
+Date: October 2010
+Contact: Andreas Langer <an.langer@gmx.de>
+Description:
+ Indicates whether the data traffic going through the
+ mesh will be fragmented or silently discarded if the
+ packet size exceeds the outgoing interface MTU.
+
+What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
+Date: October 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Defines the bandwidth which is propagated by this
+ node if gw_mode was set to 'server'.
+
+What: /sys/class/net/<mesh_iface>/mesh/gw_mode
+Date: October 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Defines the state of the gateway features. Can be
+ either 'off', 'client' or 'server'.
+
+What: /sys/class/net/<mesh_iface>/mesh/gw_sel_class
+Date: October 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Defines the selection criteria this node will use
+ to choose a gateway if gw_mode was set to 'client'.
+
+What: /sys/class/net/<mesh_iface>/mesh/orig_interval
+Date: May 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Defines the interval in milliseconds in which batman
+ sends its protocol messages.
+
+What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
+Date: Oct 2010
+Contact: Linus Lüssing <linus.luessing@web.de>
+Description:
+ Defines the penalty which will be applied to an
+ originator message's tq-field on every hop.
+
+What: /sys/class/net/<mesh_iface>/mesh/vis_mode
+Date: May 2010
+Contact: Marek Lindner <lindner_marek@yahoo.de>
+Description:
+ Each batman node only maintains information about its
+ own local neighborhood, therefore generating graphs
+ showing the topology of the entire mesh is not easily
+ feasible without having a central instance to collect
+ the local topologies from all nodes. This file allows
+ to activate the collecting (server) mode.
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
index 063bda7fe707..698b8081c473 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
@@ -1,4 +1,4 @@
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_dpi
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/actual_dpi
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: It is possible to switch the dpi setting of the mouse with the
@@ -17,13 +17,13 @@ Description: It is possible to switch the dpi setting of the mouse with the
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/actual_profile
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the number of the actual profile.
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/firmware_version
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the raw integer version number of the
@@ -33,7 +33,7 @@ Description: When read, this file returns the raw integer version number of the
left. E.g. a returned value of 138 means 1.38
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/profile[1-5]
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store 5 profiles which can be switched by the
@@ -48,7 +48,7 @@ Description: The mouse can store 5 profiles which can be switched by the
stored in the profile doesn't need to fit the number of the
store.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/settings
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the settings stored in the mouse.
@@ -58,7 +58,7 @@ Description: When read, this file returns the settings stored in the mouse.
The data has to be 36 bytes long. The mouse will reject invalid
data.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/startup_profile
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The integer value of this attribute ranges from 1 to 5.
@@ -67,7 +67,7 @@ Description: The integer value of this attribute ranges from 1 to 5.
When written, this file sets the number of the startup profile
and the mouse activates this profile immediately.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/tcu
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/tcu
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse has a "Tracking Control Unit" which lets the user
@@ -78,7 +78,7 @@ Description: The mouse has a "Tracking Control Unit" which lets the user
Writing 1 in this file will start the calibration which takes
around 6 seconds to complete and activates the TCU.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/weight
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/weight
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can be equipped with one of four supplied weights
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
new file mode 100644
index 000000000000..0f9f30eb1742
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
@@ -0,0 +1,108 @@
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: When read, this file returns the number of the actual profile in
+ range 0-4.
+ This file is readonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: When read, this file returns the raw integer version number of the
+ firmware reported by the mouse. Using the integer value eases
+ further usage in other programs. To receive the real version
+ number the decimal point has to be shifted 2 positions to the
+ left. E.g. a returned value of 121 means 1.21
+ This file is readonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse can store a macro with max 500 key/button strokes
+ internally.
+ When written, this file lets one set the sequence for a specific
+ button for a specific profile. Button and profile numbers are
+ included in written data. The data has to be 2082 bytes long.
+ This file is writeonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_buttons
+Date: August 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse can store 5 profiles which can be switched by the
+ press of a button. A profile is split in settings and buttons.
+ profile_buttons holds informations about button layout.
+ When written, this file lets one write the respective profile
+ buttons back to the mouse. The data has to be 77 bytes long.
+ The mouse will reject invalid data.
+ Which profile to write is determined by the profile number
+ contained in the data.
+ This file is writeonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons
+Date: August 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse can store 5 profiles which can be switched by the
+ press of a button. A profile is split in settings and buttons.
+ profile_buttons holds informations about button layout.
+ When read, these files return the respective profile buttons.
+ The returned data is 77 bytes in size.
+ This file is readonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse can store 5 profiles which can be switched by the
+ press of a button. A profile is split in settings and buttons.
+ profile_settings holds informations like resolution, sensitivity
+ and light effects.
+ When written, this file lets one write the respective profile
+ settings back to the mouse. The data has to be 43 bytes long.
+ The mouse will reject invalid data.
+ Which profile to write is determined by the profile number
+ contained in the data.
+ This file is writeonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings
+Date: August 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse can store 5 profiles which can be switched by the
+ press of a button. A profile is split in settings and buttons.
+ profile_settings holds informations like resolution, sensitivity
+ and light effects.
+ When read, these files return the respective profile settings.
+ The returned data is 43 bytes in size.
+ This file is readonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The mouse has a tracking- and a distance-control-unit. These
+ can be activated/deactivated and the lift-off distance can be
+ set. The data has to be 6 bytes long.
+ This file is writeonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: The integer value of this attribute ranges from 0-4.
+ When read, this attribute returns the number of the profile
+ that's active when the mouse is powered on.
+ When written, this file sets the number of the startup profile
+ and the mouse activates this profile immediately.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: When written a calibration process for the tracking control unit
+ can be initiated/cancelled.
+ The data has to be 3 bytes long.
+ This file is writeonly.
+
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image
+Date: October 2010
+Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
+Description: When read the mouse returns a 30x30 pixel image of the
+ sampled underground. This works only in the course of a
+ calibration process initiated with tcu.
+ The returned data is 1028 bytes in size.
+ This file is readonly.
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
index ad1125b02ff4..1c37b823f142 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
@@ -1,4 +1,4 @@
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_cpi
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: It is possible to switch the cpi setting of the mouse with the
@@ -14,14 +14,14 @@ Description: It is possible to switch the cpi setting of the mouse with the
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the number of the actual profile in
range 0-4.
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the raw integer version number of the
@@ -31,7 +31,7 @@ Description: When read, this file returns the raw integer version number of the
left. E.g. a returned value of 138 means 1.38
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_settings
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store 5 profiles which can be switched by the
@@ -45,7 +45,7 @@ Description: The mouse can store 5 profiles which can be switched by the
contained in the data.
This file is writeonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_settings
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store 5 profiles which can be switched by the
@@ -56,7 +56,7 @@ Description: The mouse can store 5 profiles which can be switched by the
The returned data is 13 bytes in size.
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_buttons
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store 5 profiles which can be switched by the
@@ -69,7 +69,7 @@ Description: The mouse can store 5 profiles which can be switched by the
contained in the data.
This file is writeonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_buttons
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store 5 profiles which can be switched by the
@@ -79,7 +79,7 @@ Description: The mouse can store 5 profiles which can be switched by the
The returned data is 19 bytes in size.
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The integer value of this attribute ranges from 0-4.
@@ -87,7 +87,7 @@ Description: The integer value of this attribute ranges from 0-4.
that's active when the mouse is powered on.
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
+What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the settings stored in the mouse.
diff --git a/Documentation/ABI/testing/sysfs-fs-pstore b/Documentation/ABI/testing/sysfs-fs-pstore
new file mode 100644
index 000000000000..8e659d854805
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-fs-pstore
@@ -0,0 +1,7 @@
+What: /sys/fs/pstore/kmsg_bytes
+Date: January 2011
+Kernel Version: 2.6.38
+Contact: "Tony Luck" <tony.luck@intel.com>
+Description:
+ Controls amount of console log that will be saved
+ to persistent store on oops/panic.
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-laptop b/Documentation/ABI/testing/sysfs-platform-asus-laptop
index 1d775390e856..41ff8ae4dee0 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-laptop
+++ b/Documentation/ABI/testing/sysfs-platform-asus-laptop
@@ -47,6 +47,20 @@ Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
- Control the bluetooth device. 1 means on, 0 means off.
+ Control the wlan device. 1 means on, 0 means off.
This may control the led, the device or both.
Users: Lapsus
+
+What: /sys/devices/platform/asus_laptop/wimax
+Date: October 2010
+KernelVersion: 2.6.37
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Control the wimax device. 1 means on, 0 means off.
+
+What: /sys/devices/platform/asus_laptop/wwan
+Date: October 2010
+KernelVersion: 2.6.37
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Control the wwan (3G) device. 1 means on, 0 means off.
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
new file mode 100644
index 000000000000..e4b5fef5fadd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
@@ -0,0 +1,10 @@
+What: /sys/devices/platform/eeepc-wmi/cpufv
+Date: Oct 2010
+KernelVersion: 2.6.37
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Change CPU clock configuration (write-only).
+ There are three available clock configuration:
+ * 0 -> Super Performance Mode
+ * 1 -> High Performance Mode
+ * 2 -> Power Saving Mode
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 19a1210c2530..03641a08e275 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -146,6 +146,7 @@
!Finclude/net/cfg80211.h cfg80211_rx_mgmt
!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status
!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify
+!Finclude/net/cfg80211.h cfg80211_cqm_pktloss_notify
!Finclude/net/cfg80211.h cfg80211_michael_mic_failure
</chapter>
<chapter>
@@ -332,10 +333,16 @@
<title>functions/definitions</title>
!Finclude/net/mac80211.h ieee80211_rx_status
!Finclude/net/mac80211.h mac80211_rx_flags
+!Finclude/net/mac80211.h mac80211_tx_control_flags
+!Finclude/net/mac80211.h mac80211_rate_control_flags
+!Finclude/net/mac80211.h ieee80211_tx_rate
!Finclude/net/mac80211.h ieee80211_tx_info
+!Finclude/net/mac80211.h ieee80211_tx_info_clear_status
!Finclude/net/mac80211.h ieee80211_rx
+!Finclude/net/mac80211.h ieee80211_rx_ni
!Finclude/net/mac80211.h ieee80211_rx_irqsafe
!Finclude/net/mac80211.h ieee80211_tx_status
+!Finclude/net/mac80211.h ieee80211_tx_status_ni
!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
!Finclude/net/mac80211.h ieee80211_rts_get
!Finclude/net/mac80211.h ieee80211_rts_duration
@@ -346,6 +353,7 @@
!Finclude/net/mac80211.h ieee80211_stop_queue
!Finclude/net/mac80211.h ieee80211_wake_queues
!Finclude/net/mac80211.h ieee80211_stop_queues
+!Finclude/net/mac80211.h ieee80211_queue_stopped
</sect1>
</chapter>
@@ -354,6 +362,13 @@
!Pinclude/net/mac80211.h Frame filtering
!Finclude/net/mac80211.h ieee80211_filter_flags
</chapter>
+
+ <chapter id="workqueue">
+ <title>The mac80211 workqueue</title>
+!Pinclude/net/mac80211.h mac80211 workqueue
+!Finclude/net/mac80211.h ieee80211_queue_work
+!Finclude/net/mac80211.h ieee80211_queue_delayed_work
+ </chapter>
</part>
<part id="advanced">
@@ -374,6 +389,9 @@
!Finclude/net/mac80211.h set_key_cmd
!Finclude/net/mac80211.h ieee80211_key_conf
!Finclude/net/mac80211.h ieee80211_key_flags
+!Finclude/net/mac80211.h ieee80211_tkip_key_type
+!Finclude/net/mac80211.h ieee80211_get_tkip_key
+!Finclude/net/mac80211.h ieee80211_key_removed
</chapter>
<chapter id="powersave">
@@ -417,6 +435,18 @@
supported by mac80211, add notes about supporting hw crypto
with it.
</para>
+!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces
+!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces_atomic
+ </chapter>
+
+ <chapter id="station-handling">
+ <title>Station handling</title>
+ <para>TODO</para>
+!Finclude/net/mac80211.h ieee80211_sta
+!Finclude/net/mac80211.h sta_notify_cmd
+!Finclude/net/mac80211.h ieee80211_find_sta
+!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
+!Finclude/net/mac80211.h ieee80211_sta_block_awake
</chapter>
<chapter id="hardware-scan-offload">
@@ -424,6 +454,28 @@
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_scan_completed
</chapter>
+
+ <chapter id="aggregation">
+ <title>Aggregation</title>
+ <sect1>
+ <title>TX A-MPDU aggregation</title>
+!Pnet/mac80211/agg-tx.c TX A-MPDU aggregation
+!Cnet/mac80211/agg-tx.c
+ </sect1>
+ <sect1>
+ <title>RX A-MPDU aggregation</title>
+!Pnet/mac80211/agg-rx.c RX A-MPDU aggregation
+!Cnet/mac80211/agg-rx.c
+ </sect1>
+!Finclude/net/mac80211.h ieee80211_ampdu_mlme_action
+ </chapter>
+
+ <chapter id="smps">
+ <title>Spatial Multiplexing Powersave (SMPS)</title>
+!Pinclude/net/mac80211.h Spatial multiplexing power save
+!Finclude/net/mac80211.h ieee80211_request_smps
+!Finclude/net/mac80211.h ieee80211_smps_mode
+ </chapter>
</part>
<part id="rate-control">
@@ -435,9 +487,16 @@
interface and how it relates to mac80211 and drivers.
</para>
</partintro>
- <chapter id="dummy">
- <title>dummy chapter</title>
+ <chapter id="ratecontrol-api">
+ <title>Rate Control API</title>
<para>TBD</para>
+!Finclude/net/mac80211.h ieee80211_start_tx_ba_session
+!Finclude/net/mac80211.h ieee80211_start_tx_ba_cb_irqsafe
+!Finclude/net/mac80211.h ieee80211_stop_tx_ba_session
+!Finclude/net/mac80211.h ieee80211_stop_tx_ba_cb_irqsafe
+!Finclude/net/mac80211.h rate_control_changed
+!Finclude/net/mac80211.h ieee80211_tx_rate_control
+!Finclude/net/mac80211.h rate_control_send_low
</chapter>
</part>
@@ -485,6 +544,13 @@
</sect1>
</chapter>
+ <chapter id="aggregation-internals">
+ <title>Aggregation</title>
+!Fnet/mac80211/sta_info.h sta_ampdu_mlme
+!Fnet/mac80211/sta_info.h tid_ampdu_tx
+!Fnet/mac80211/sta_info.h tid_ampdu_rx
+ </chapter>
+
<chapter id="synchronisation">
<title>Synchronisation</title>
<para>TBD</para>
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 22edcbb9ddaf..35447e081736 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -304,6 +304,10 @@ X!Idrivers/video/console/fonts.c
!Edrivers/input/ff-core.c
!Edrivers/input/ff-memless.c
</sect1>
+ <sect1><title>Multitouch Library</title>
+!Iinclude/linux/input/mt.h
+!Edrivers/input/input-mt.c
+ </sect1>
<sect1><title>Polled input devices</title>
!Iinclude/linux/input-polldev.h
!Edrivers/input/input-polldev.c
diff --git a/Documentation/DocBook/v4l/func-ioctl.xml b/Documentation/DocBook/v4l/func-ioctl.xml
index 00f9690e1c28..b60fd37a6295 100644
--- a/Documentation/DocBook/v4l/func-ioctl.xml
+++ b/Documentation/DocBook/v4l/func-ioctl.xml
@@ -34,8 +34,7 @@
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
- <para>V4L2 ioctl request code as defined in the <link
-linkend="videodev">videodev.h</link> header file, for example
+ <para>V4L2 ioctl request code as defined in the <filename>videodev2.h</filename> header file, for example
VIDIOC_QUERYCAP.</para>
</listitem>
</varlistentry>
@@ -57,7 +56,7 @@ file descriptor. An ioctl <parameter>request</parameter> has encoded
in it whether the argument is an input, output or read/write
parameter, and the size of the argument <parameter>argp</parameter> in
bytes. Macros and defines specifying V4L2 ioctl requests are located
-in the <link linkend="videodev">videodev.h</link> header file.
+in the <filename>videodev2.h</filename> header file.
Applications should use their own copy, not include the version in the
kernel sources on the system they compile on. All V4L2 ioctl requests,
their respective function and parameters are specified in <xref
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index d7c467187095..cfffc88d7383 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -142,8 +142,8 @@ leftmost pixel of the second row from the top, and so on. The last row
has just as many pad bytes after it as the other rows.</para>
<para>In V4L2 each format has an identifier which looks like
-<constant>PIX_FMT_XXX</constant>, defined in the <link
-linkend="videodev">videodev.h</link> header file. These identifiers
+<constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename>
+header file. These identifiers
represent <link linkend="v4l2-fourcc">four character codes</link>
which are also listed below, however they are not the same as those
used in the Windows world.</para>
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 69dd29ed824e..b2bea15137d2 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -533,6 +533,33 @@ completion during sending a panic event.
Other Pieces
------------
+Get the detailed info related with the IPMI device
+--------------------------------------------------
+
+Some users need more detailed information about a device, like where
+the address came from or the raw base device for the IPMI interface.
+You can use the IPMI smi_watcher to catch the IPMI interfaces as they
+come or go, and to grab the information, you can use the function
+ipmi_get_smi_info(), which returns the following structure:
+
+struct ipmi_smi_info {
+ enum ipmi_addr_src addr_src;
+ struct device *dev;
+ union {
+ struct {
+ void *acpi_handle;
+ } acpi_info;
+ } addr_info;
+};
+
+Currently special info for only for SI_ACPI address sources is
+returned. Others may be added as necessary.
+
+Note that the dev pointer is included in the above structure, and
+assuming ipmi_smi_get_info returns success, you must call put_device
+on the dev pointer.
+
+
Watchdog
--------
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 6fc7ea1d1f9d..9b4bc5c76f33 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
- pcmcia/ spi/ timers/ video4linux/ vm/ watchdog/src/
+ pcmcia/ spi/ timers/ vm/ watchdog/src/
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index a2976a6de033..e9c77788a39d 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -516,6 +516,7 @@ int main(int argc, char *argv[])
default:
fprintf(stderr, "Unknown nla_type %d\n",
na->nla_type);
+ case TASKSTATS_TYPE_NULL:
break;
}
na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
diff --git a/Documentation/acpi/apei/output_format.txt b/Documentation/acpi/apei/output_format.txt
new file mode 100644
index 000000000000..9146952c612a
--- /dev/null
+++ b/Documentation/acpi/apei/output_format.txt
@@ -0,0 +1,122 @@
+ APEI output format
+ ~~~~~~~~~~~~~~~~~~
+
+APEI uses printk as hardware error reporting interface, the output
+format is as follow.
+
+<error record> :=
+APEI generic hardware error status
+severity: <integer>, <severity string>
+section: <integer>, severity: <integer>, <severity string>
+flags: <integer>
+<section flags strings>
+fru_id: <uuid string>
+fru_text: <string>
+section_type: <section type string>
+<section data>
+
+<severity string>* := recoverable | fatal | corrected | info
+
+<section flags strings># :=
+[primary][, containment warning][, reset][, threshold exceeded]\
+[, resource not accessible][, latent error]
+
+<section type string> := generic processor error | memory error | \
+PCIe error | unknown, <uuid string>
+
+<section data> :=
+<generic processor section data> | <memory section data> | \
+<pcie section data> | <null>
+
+<generic processor section data> :=
+[processor_type: <integer>, <proc type string>]
+[processor_isa: <integer>, <proc isa string>]
+[error_type: <integer>
+<proc error type strings>]
+[operation: <integer>, <proc operation string>]
+[flags: <integer>
+<proc flags strings>]
+[level: <integer>]
+[version_info: <integer>]
+[processor_id: <integer>]
+[target_address: <integer>]
+[requestor_id: <integer>]
+[responder_id: <integer>]
+[IP: <integer>]
+
+<proc type string>* := IA32/X64 | IA64
+
+<proc isa string>* := IA32 | IA64 | X64
+
+<processor error type strings># :=
+[cache error][, TLB error][, bus error][, micro-architectural error]
+
+<proc operation string>* := unknown or generic | data read | data write | \
+instruction execution
+
+<proc flags strings># :=
+[restartable][, precise IP][, overflow][, corrected]
+
+<memory section data> :=
+[error_status: <integer>]
+[physical_address: <integer>]
+[physical_address_mask: <integer>]
+[node: <integer>]
+[card: <integer>]
+[module: <integer>]
+[bank: <integer>]
+[device: <integer>]
+[row: <integer>]
+[column: <integer>]
+[bit_position: <integer>]
+[requestor_id: <integer>]
+[responder_id: <integer>]
+[target_id: <integer>]
+[error_type: <integer>, <mem error type string>]
+
+<mem error type string>* :=
+unknown | no error | single-bit ECC | multi-bit ECC | \
+single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
+target abort | parity error | watchdog timeout | invalid address | \
+mirror Broken | memory sparing | scrub corrected error | \
+scrub uncorrected error
+
+<pcie section data> :=
+[port_type: <integer>, <pcie port type string>]
+[version: <integer>.<integer>]
+[command: <integer>, status: <integer>]
+[device_id: <integer>:<integer>:<integer>.<integer>
+slot: <integer>
+secondary_bus: <integer>
+vendor_id: <integer>, device_id: <integer>
+class_code: <integer>]
+[serial number: <integer>, <integer>]
+[bridge: secondary_status: <integer>, control: <integer>]
+
+<pcie port type string>* := PCIe end point | legacy PCI end point | \
+unknown | unknown | root port | upstream switch port | \
+downstream switch port | PCIe to PCI/PCI-X bridge | \
+PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
+root complex event collector
+
+Where, [] designate corresponding content is optional
+
+All <field string> description with * has the following format:
+
+field: <integer>, <field string>
+
+Where value of <integer> should be the position of "string" in <field
+string> description. Otherwise, <field string> will be "unknown".
+
+All <field strings> description with # has the following format:
+
+field: <integer>
+<field strings>
+
+Where each string in <fields strings> corresponding to one set bit of
+<integer>. The bit position is the position of "string" in <field
+strings> description.
+
+For more detailed explanation of every field, please refer to UEFI
+specification version 2.3 or later, section Appendix N: Common
+Platform Error Record.
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index ecf7d04bca26..91c24a1e8a9e 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -34,3 +34,5 @@ memory.txt
- description of the virtual memory layout
nwfpe/
- NWFPE floating point emulator documentation
+swp_emulation
+ - SWP/SWPB emulation handler/logging description
diff --git a/Documentation/arm/OMAP/omap_pm b/Documentation/arm/OMAP/omap_pm
index 5389440aade3..9012bb039094 100644
--- a/Documentation/arm/OMAP/omap_pm
+++ b/Documentation/arm/OMAP/omap_pm
@@ -127,3 +127,28 @@ implementation needs:
10. (*pdata->cpu_set_freq)(unsigned long f)
11. (*pdata->cpu_get_freq)(void)
+
+Customizing OPP for platform
+============================
+Defining CONFIG_PM should enable OPP layer for the silicon
+and the registration of OPP table should take place automatically.
+However, in special cases, the default OPP table may need to be
+tweaked, for e.g.:
+ * enable default OPPs which are disabled by default, but which
+ could be enabled on a platform
+ * Disable an unsupported OPP on the platform
+ * Define and add a custom opp table entry
+in these cases, the board file needs to do additional steps as follows:
+arch/arm/mach-omapx/board-xyz.c
+ #include "pm.h"
+ ....
+ static void __init omap_xyz_init_irq(void)
+ {
+ ....
+ /* Initialize the default table */
+ omapx_opp_init();
+ /* Do customization to the defaults */
+ ....
+ }
+NOTE: omapx_opp_init will be omap3_opp_init or as required
+based on the omap family.
diff --git a/Documentation/arm/swp_emulation b/Documentation/arm/swp_emulation
new file mode 100644
index 000000000000..af903d22fd93
--- /dev/null
+++ b/Documentation/arm/swp_emulation
@@ -0,0 +1,27 @@
+Software emulation of deprecated SWP instruction (CONFIG_SWP_EMULATE)
+---------------------------------------------------------------------
+
+ARMv6 architecture deprecates use of the SWP/SWPB instructions, and recommeds
+moving to the load-locked/store-conditional instructions LDREX and STREX.
+
+ARMv7 multiprocessing extensions introduce the ability to disable these
+instructions, triggering an undefined instruction exception when executed.
+Trapped instructions are emulated using an LDREX/STREX or LDREXB/STREXB
+sequence. If a memory access fault (an abort) occurs, a segmentation fault is
+signalled to the triggering process.
+
+/proc/cpu/swp_emulation holds some statistics/information, including the PID of
+the last process to trigger the emulation to be invocated. For example:
+---
+Emulated SWP: 12
+Emulated SWPB: 0
+Aborted SWP{B}: 1
+Last process: 314
+---
+
+NOTE: when accessing uncached shared regions, LDREX/STREX rely on an external
+transaction monitoring block called a global monitor to maintain update
+atomicity. If your system does not implement a global monitor, this option can
+cause programs that perform SWP operations to uncached memory to deadlock, as
+the STREX operation will always fail.
+
diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt
index d6da611f8f63..4ed7b5ceeed2 100644
--- a/Documentation/cgroups/blkio-controller.txt
+++ b/Documentation/cgroups/blkio-controller.txt
@@ -89,6 +89,33 @@ Throttling/Upper Limit policy
Limits for writes can be put using blkio.write_bps_device file.
+Hierarchical Cgroups
+====================
+- Currently none of the IO control policy supports hierarhical groups. But
+ cgroup interface does allow creation of hierarhical cgroups and internally
+ IO policies treat them as flat hierarchy.
+
+ So this patch will allow creation of cgroup hierarhcy but at the backend
+ everything will be treated as flat. So if somebody created a hierarchy like
+ as follows.
+
+ root
+ / \
+ test1 test2
+ |
+ test3
+
+ CFQ and throttling will practically treat all groups at same level.
+
+ pivot
+ / | \ \
+ root test1 test2 test3
+
+ Down the line we can implement hierarchical accounting/control support
+ and also introduce a new cgroup file "use_hierarchy" which will control
+ whether cgroup hierarchy is viewed as flat or hierarchical by the policy..
+ This is how memory controller also has implemented the things.
+
Various user visible config options
===================================
CONFIG_BLK_CGROUP
diff --git a/Documentation/coccinelle.txt b/Documentation/coccinelle.txt
index 4a276ea7001c..96b690348ba1 100644
--- a/Documentation/coccinelle.txt
+++ b/Documentation/coccinelle.txt
@@ -36,6 +36,10 @@ as a regular user, and install it with
sudo make install
+The semantic patches in the kernel will work best with Coccinelle version
+0.2.4 or later. Using earlier versions may incur some parse errors in the
+semantic patch code, but any results that are obtained should still be
+correct.
Using Coccinelle on the Linux kernel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index d9bcffd59433..470d3dba1a69 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -62,6 +62,10 @@ aic7*reg_print.c*
aic7*seq.h*
aicasm
aicdb.h*
+altivec1.c
+altivec2.c
+altivec4.c
+altivec8.c
asm-offsets.h
asm_offsets.h
autoconf.h*
@@ -76,6 +80,7 @@ btfixupprep
build
bvmlinux
bzImage*
+capflags.c
classlist.h*
comp*.log
compile.h*
@@ -94,6 +99,7 @@ devlist.h*
docproc
elf2ecoff
elfconfig.h*
+evergreen_reg_safe.h
fixdep
flask.h
fore200e_mkfirm
@@ -108,9 +114,16 @@ genksyms
*_gray256.c
ihex2fw
ikconfig.h*
+inat-tables.c
initramfs_data.cpio
initramfs_data.cpio.gz
initramfs_list
+int16.c
+int1.c
+int2.c
+int32.c
+int4.c
+int8.c
kallsyms
kconfig
keywords.c
@@ -140,6 +153,7 @@ mkprep
mktables
mktree
modpost
+modules.builtin
modules.order
modversions.h*
ncscope.*
@@ -153,14 +167,23 @@ pca200e.bin
pca200e_ecd.bin2
piggy.gz
piggyback
+piggy.S
pnmtologo
ppc_defs.h*
pss_boot.h
qconf
+r100_reg_safe.h
+r200_reg_safe.h
+r300_reg_safe.h
+r420_reg_safe.h
+r600_reg_safe.h
raid6altivec*.c
raid6int*.c
raid6tables.c
relocs
+rn50_reg_safe.h
+rs600_reg_safe.h
+rv515_reg_safe.h
series
setup
setup.bin
@@ -169,6 +192,7 @@ sImage
sm_tbl*
split-include
syscalltab.h
+tables.c
tags
tftpboot.img
timeconst.h
@@ -190,6 +214,7 @@ vmlinux
vmlinux-*
vmlinux.aout
vmlinux.lds
+voffset.h
vsyscall.lds
vsyscall_32.lds
wanxlfw.inc
@@ -200,3 +225,4 @@ wakeup.elf
wakeup.lds
zImage*
zconf.hash.c
+zoffset.h
diff --git a/Documentation/driver-model/interface.txt b/Documentation/driver-model/interface.txt
deleted file mode 100644
index c66912bfe866..000000000000
--- a/Documentation/driver-model/interface.txt
+++ /dev/null
@@ -1,129 +0,0 @@
-
-Device Interfaces
-
-Introduction
-~~~~~~~~~~~~
-
-Device interfaces are the logical interfaces of device classes that correlate
-directly to userspace interfaces, like device nodes.
-
-Each device class may have multiple interfaces through which you can
-access the same device. An input device may support the mouse interface,
-the 'evdev' interface, and the touchscreen interface. A SCSI disk would
-support the disk interface, the SCSI generic interface, and possibly a raw
-device interface.
-
-Device interfaces are registered with the class they belong to. As devices
-are added to the class, they are added to each interface registered with
-the class. The interface is responsible for determining whether the device
-supports the interface or not.
-
-
-Programming Interface
-~~~~~~~~~~~~~~~~~~~~~
-
-struct device_interface {
- char * name;
- rwlock_t lock;
- u32 devnum;
- struct device_class * devclass;
-
- struct list_head node;
- struct driver_dir_entry dir;
-
- int (*add_device)(struct device *);
- int (*add_device)(struct intf_data *);
-};
-
-int interface_register(struct device_interface *);
-void interface_unregister(struct device_interface *);
-
-
-An interface must specify the device class it belongs to. It is added
-to that class's list of interfaces on registration.
-
-
-Interfaces can be added to a device class at any time. Whenever it is
-added, each device in the class is passed to the interface's
-add_device callback. When an interface is removed, each device is
-removed from the interface.
-
-
-Devices
-~~~~~~~
-Once a device is added to a device class, it is added to each
-interface that is registered with the device class. The class
-is expected to place a class-specific data structure in
-struct device::class_data. The interface can use that (along with
-other fields of struct device) to determine whether or not the driver
-and/or device support that particular interface.
-
-
-Data
-~~~~
-
-struct intf_data {
- struct list_head node;
- struct device_interface * intf;
- struct device * dev;
- u32 intf_num;
-};
-
-int interface_add_data(struct interface_data *);
-
-The interface is responsible for allocating and initializing a struct
-intf_data and calling interface_add_data() to add it to the device's list
-of interfaces it belongs to. This list will be iterated over when the device
-is removed from the class (instead of all possible interfaces for a class).
-This structure should probably be embedded in whatever per-device data
-structure the interface is allocating anyway.
-
-Devices are enumerated within the interface. This happens in interface_add_data()
-and the enumerated value is stored in the struct intf_data for that device.
-
-sysfs
-~~~~~
-Each interface is given a directory in the directory of the device
-class it belongs to:
-
-Interfaces get a directory in the class's directory as well:
-
- class/
- `-- input
- |-- devices
- |-- drivers
- |-- mouse
- `-- evdev
-
-When a device is added to the interface, a symlink is created that points
-to the device's directory in the physical hierarchy:
-
- class/
- `-- input
- |-- devices
- | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
- |-- drivers
- | `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
- |-- mouse
- | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
- `-- evdev
- `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-
-
-Future Plans
-~~~~~~~~~~~~
-A device interface is correlated directly with a userspace interface
-for a device, specifically a device node. For instance, a SCSI disk
-exposes at least two interfaces to userspace: the standard SCSI disk
-interface and the SCSI generic interface. It might also export a raw
-device interface.
-
-Many interfaces have a major number associated with them and each
-device gets a minor number. Or, multiple interfaces might share one
-major number, and each will receive a range of minor numbers (like in
-the case of input devices).
-
-These major and minor numbers could be stored in the interface
-structure. Major and minor allocations could happen when the interface
-is registered with the class, or via a helper function.
-
diff --git a/Documentation/dvb/lmedm04.txt b/Documentation/dvb/lmedm04.txt
index e175784b89bf..641886504201 100644
--- a/Documentation/dvb/lmedm04.txt
+++ b/Documentation/dvb/lmedm04.txt
@@ -46,7 +46,7 @@ and run
Other LG firmware can be extracted manually from US280D.sys
only found in windows/system32/driver.
-dd if=US280D.sys ibs=1 skip=42616 count=3668 of=dvb-usb-lme2510-lg.fw
+dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
for DM04 LME2510C (LG Tuner)
---------------------------
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 6c2f55e05f13..b5d3535bbd87 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -97,36 +97,38 @@ Who: Pavel Machek <pavel@ucw.cz>
---------------------------
-What: Video4Linux API 1 ioctls and from Video devices.
-When: kernel 2.6.38
-Files: include/linux/videodev.h
-Check: include/linux/videodev.h
-Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
- series. The old API have lots of drawbacks and don't provide enough
- means to work with all video and audio standards. The newer API is
- already available on the main drivers and should be used instead.
- Newer drivers should use v4l_compat_translate_ioctl function to handle
- old calls, replacing to newer ones.
- Decoder iocts are using internally to allow video drivers to
- communicate with video decoders. This should also be improved to allow
- V4L2 calls being translated into compatible internal ioctls.
- Compatibility ioctls will be provided, for a while, via
- v4l1-compat module.
-Who: Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
What: Video4Linux obsolete drivers using V4L1 API
-When: kernel 2.6.38
-Files: drivers/staging/cpia/* drivers/staging/stradis/*
-Check: drivers/staging/cpia/cpia.c drivers/staging/stradis/stradis.c
+When: kernel 2.6.39
+Files: drivers/staging/se401/* drivers/staging/usbvideo/*
+Check: drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
Why: There are some drivers still using V4L1 API, despite all efforts we've done
to migrate. Those drivers are for obsolete hardware that the old maintainer
didn't care (or not have the hardware anymore), and that no other developer
could find any hardware to buy. They probably have no practical usage today,
and people with such old hardware could probably keep using an older version
- of the kernel. Those drivers will be moved to staging on 2.6.37 and, if nobody
- care enough to port and test them with V4L2 API, they'll be removed on 2.6.38.
+ of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
+ cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
+Who: Mauro Carvalho Chehab <mchehab@infradead.org>
+
+---------------------------
+
+What: Video4Linux: Remove obsolete ioctl's
+When: kernel 2.6.39
+Files: include/media/videodev2.h
+Why: Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
+ type of R/W arguments. They were fixed, but the old ioctl names are
+ still there, maintained to avoid breaking binary compatibility:
+ #define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
+ #define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
+ #define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
+ #define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
+ #define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
+ #define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
+ There's no sense on preserving those forever, as it is very doubtful
+ that someone would try to use a such old binary with a modern kernel.
+ Removing them will allow us to remove some magic done at the V4L ioctl
+ handler.
+
Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
@@ -564,3 +566,13 @@ Why: This field is deprecated. I2C device drivers shouldn't change their
Who: Jean Delvare <khali@linux-fr.org>
----------------------------
+
+What: Legacy, non-standard chassis intrusion detection interface.
+When: June 2011
+Why: The adm9240, w83792d and w83793 hardware monitoring drivers have
+ legacy interfaces for chassis intrusion detection. A standard
+ interface has been added to each driver, so the legacy interface
+ can be removed.
+Who: Jean Delvare <khali@linux-fr.org>
+
+----------------------------
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index a91f30890011..a3a50aaba438 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -9,23 +9,27 @@ be able to use diff(1).
--------------------------- dentry_operations --------------------------
prototypes:
- int (*d_revalidate)(struct dentry *, int);
- int (*d_hash) (struct dentry *, struct qstr *);
- int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
+ int (*d_revalidate)(struct dentry *, struct nameidata *);
+ int (*d_revalidate_rcu)(struct dentry *, struct nameidata *);
+ int (*d_hash)(const struct dentry *, const struct inode *,
+ struct qstr *);
+ int (*d_compare)(const struct dentry *, const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
locking rules:
- none have BKL
- dcache_lock rename_lock ->d_lock may block
-d_revalidate: no no no yes
-d_hash no no no yes
-d_compare: no yes no no
-d_delete: yes no yes no
-d_release: no no no yes
-d_iput: no no no yes
+ rename_lock ->d_lock may block rcu-walk
+d_revalidate: no no yes no
+d_revalidate_rcu:no no yes (ref-walk) maybe
+d_hash no no no maybe
+d_compare: yes no no maybe
+d_delete: no yes no no
+d_release: no no yes no
+d_iput: no no yes no
d_dname: no no no no
--------------------------- inode_operations ---------------------------
@@ -42,18 +46,25 @@ ata *);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char __user *,int);
- int (*follow_link) (struct dentry *, struct nameidata *);
+ void * (*follow_link) (struct dentry *, struct nameidata *);
+ void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int, struct nameidata *);
+ int (*permission) (struct inode *, int);
+ int (*permission_rcu) (struct inode *, int, unsigned int);
+ int (*check_acl)(struct inode *, int);
+ int (*check_acl_rcu)(struct inode *, int, unsigned int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
+ void (*truncate_range)(struct inode *, loff_t, loff_t);
+ long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len);
+ int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
locking rules:
- all may block, none have BKL
+ all may block
i_mutex(inode)
lookup: yes
create: yes
@@ -66,19 +77,25 @@ rmdir: yes (both) (see below)
rename: yes (all) (see below)
readlink: no
follow_link: no
+put_link: no
truncate: yes (see below)
setattr: yes
permission: no
+permission_rcu: no (may not block if called in rcu-walk mode)
+check_acl: no
getattr: no
setxattr: yes
getxattr: no
listxattr: no
removexattr: yes
+truncate_range: yes
+fallocate: no
+fiemap: no
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
->truncate() is never called directly - it's a callback, not a
-method. It's called by vmtruncate() - library function normally used by
+method. It's called by vmtruncate() - deprecated library function used by
->setattr(). Locking information above applies to that call (i.e. is
inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
passed).
@@ -91,7 +108,7 @@ prototypes:
struct inode *(*alloc_inode)(struct super_block *sb);
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);
int (*drop_inode) (struct inode *);
void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
@@ -105,10 +122,11 @@ prototypes:
int (*show_options)(struct seq_file *, struct vfsmount *);
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
+ int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
+ int (*trim_fs) (struct super_block *, struct fstrim_range *);
locking rules:
All may block [not true, see below]
- None have BKL
s_umount
alloc_inode:
destroy_inode:
@@ -127,6 +145,8 @@ umount_begin: no
show_options: no (namespace_sem)
quota_read: no (see below)
quota_write: no (see below)
+bdev_try_to_free_page: no (see below)
+trim_fs: no
->statfs() has s_umount (shared) when called by ustat(2) (native or
compat), but that's an accident of bad API; s_umount is used to pin
@@ -139,19 +159,25 @@ be the only ones operating on the quota file by the quota code (via
dqio_sem) (unless an admin really wants to screw up something and
writes to quota files with quotas on). For other details about locking
see also dquot_operations section.
+->bdev_try_to_free_page is called from the ->releasepage handler of
+the block device inode. See there for more details.
--------------------------- file_system_type ---------------------------
prototypes:
int (*get_sb) (struct file_system_type *, int,
const char *, void *, struct vfsmount *);
+ struct dentry *(*mount) (struct file_system_type *, int,
+ const char *, void *);
void (*kill_sb) (struct super_block *);
locking rules:
- may block BKL
-get_sb yes no
-kill_sb yes no
+ may block
+get_sb yes
+mount yes
+kill_sb yes
->get_sb() returns error or 0 with locked superblock attached to the vfsmount
(exclusive on ->s_umount).
+->mount() returns ERR_PTR or the root dentry.
->kill_sb() takes a write-locked superblock, does all shutdown work on it,
unlocks and drops the reference.
@@ -173,28 +199,38 @@ prototypes:
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
+ void (*freepage)(struct page *);
int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
- int (*launder_page) (struct page *);
+ int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **,
+ unsigned long *);
+ int (*migratepage)(struct address_space *, struct page *, struct page *);
+ int (*launder_page)(struct page *);
+ int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long);
+ int (*error_remove_page)(struct address_space *, struct page *);
locking rules:
- All except set_page_dirty may block
-
- BKL PageLocked(page) i_mutex
-writepage: no yes, unlocks (see below)
-readpage: no yes, unlocks
-sync_page: no maybe
-writepages: no
-set_page_dirty no no
-readpages: no
-write_begin: no locks the page yes
-write_end: no yes, unlocks yes
-perform_write: no n/a yes
-bmap: no
-invalidatepage: no yes
-releasepage: no yes
-direct_IO: no
-launder_page: no yes
+ All except set_page_dirty and freepage may block
+
+ PageLocked(page) i_mutex
+writepage: yes, unlocks (see below)
+readpage: yes, unlocks
+sync_page: maybe
+writepages:
+set_page_dirty no
+readpages:
+write_begin: locks the page yes
+write_end: yes, unlocks yes
+bmap:
+invalidatepage: yes
+releasepage: yes
+freepage: yes
+direct_IO:
+get_xip_mem: maybe
+migratepage: yes (both)
+launder_page: yes
+is_partially_uptodate: yes
+error_remove_page: yes
->write_begin(), ->write_end(), ->sync_page() and ->readpage()
may be called from the request handler (/dev/loop).
@@ -274,9 +310,8 @@ under spinlock (it cannot block) and is sometimes called with the page
not locked.
->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
-filesystems and by the swapper. The latter will eventually go away. All
-instances do not actually need the BKL. Please, keep it that way and don't
-breed new callers.
+filesystems and by the swapper. The latter will eventually go away. Please,
+keep it that way and don't breed new callers.
->invalidatepage() is called when the filesystem must attempt to drop
some or all of the buffers from the page when it is being truncated. It
@@ -288,53 +323,46 @@ buffers from the page in preparation for freeing it. It returns zero to
indicate that the buffers are (or may be) freeable. If ->releasepage is zero,
the kernel assumes that the fs has no private interest in the buffers.
+ ->freepage() is called when the kernel is done dropping the page
+from the page cache.
+
->launder_page() may be called prior to releasing a page if
it is still found to be dirty. It returns zero if the page was successfully
cleaned, or an error value if not. Note that in order to prevent the page
getting mapped back in and redirtied, it needs to be kept locked
across the entire operation.
- Note: currently almost all instances of address_space methods are
-using BKL for internal serialization and that's one of the worst sources
-of contention. Normally they are calling library functions (in fs/buffer.c)
-and pass foo_get_block() as a callback (on local block-based filesystems,
-indeed). BKL is not needed for library stuff and is usually taken by
-foo_get_block(). It's an overkill, since block bitmaps can be protected by
-internal fs locking and real critical areas are much smaller than the areas
-filesystems protect now.
-
----------------------- file_lock_operations ------------------------------
prototypes:
- void (*fl_insert)(struct file_lock *); /* lock insertion callback */
- void (*fl_remove)(struct file_lock *); /* lock removal callback */
void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
void (*fl_release_private)(struct file_lock *);
locking rules:
- BKL may block
-fl_insert: yes no
-fl_remove: yes no
-fl_copy_lock: yes no
-fl_release_private: yes yes
+ file_lock_lock may block
+fl_copy_lock: yes no
+fl_release_private: maybe no
----------------------- lock_manager_operations ---------------------------
prototypes:
int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
void (*fl_notify)(struct file_lock *); /* unblock callback */
+ int (*fl_grant)(struct file_lock *, struct file_lock *, int);
void (*fl_release_private)(struct file_lock *);
void (*fl_break)(struct file_lock *); /* break_lease callback */
+ int (*fl_mylease)(struct file_lock *, struct file_lock *);
+ int (*fl_change)(struct file_lock **, int);
locking rules:
- BKL may block
-fl_compare_owner: yes no
-fl_notify: yes no
-fl_release_private: yes yes
-fl_break: yes no
-
- Currently only NFSD and NLM provide instances of this class. None of the
-them block. If you have out-of-tree instances - please, show up. Locking
-in that area will change.
+ file_lock_lock may block
+fl_compare_owner: yes no
+fl_notify: yes no
+fl_grant: no no
+fl_release_private: maybe no
+fl_break: yes no
+fl_mylease: yes no
+fl_change yes no
+
--------------------------- buffer_head -----------------------------------
prototypes:
void (*b_end_io)(struct buffer_head *bh, int uptodate);
@@ -359,17 +387,17 @@ prototypes:
void (*swap_slot_free_notify) (struct block_device *, unsigned long);
locking rules:
- BKL bd_mutex
-open: no yes
-release: no yes
-ioctl: no no
-compat_ioctl: no no
-direct_access: no no
-media_changed: no no
-unlock_native_capacity: no no
-revalidate_disk: no no
-getgeo: no no
-swap_slot_free_notify: no no (see below)
+ bd_mutex
+open: yes
+release: yes
+ioctl: no
+compat_ioctl: no
+direct_access: no
+media_changed: no
+unlock_native_capacity: no
+revalidate_disk: no
+getgeo: no
+swap_slot_free_notify: no (see below)
media_changed, unlock_native_capacity and revalidate_disk are called only from
check_disk_change().
@@ -408,34 +436,21 @@ prototypes:
unsigned long (*get_unmapped_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
+ int (*flock) (struct file *, int, struct file_lock *);
+ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *,
+ size_t, unsigned int);
+ ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *,
+ size_t, unsigned int);
+ int (*setlease)(struct file *, long, struct file_lock **);
};
locking rules:
- All may block.
- BKL
-llseek: no (see below)
-read: no
-aio_read: no
-write: no
-aio_write: no
-readdir: no
-poll: no
-unlocked_ioctl: no
-compat_ioctl: no
-mmap: no
-open: no
-flush: no
-release: no
-fsync: no (see below)
-aio_fsync: no
-fasync: no
-lock: yes
-readv: no
-writev: no
-sendfile: no
-sendpage: no
-get_unmapped_area: no
-check_flags: no
+ All may block except for ->setlease.
+ No VFS locks held on entry except for ->fsync and ->setlease.
+
+->fsync() has i_mutex on inode.
+
+->setlease has the file_list_lock held and must not sleep.
->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you
@@ -445,17 +460,10 @@ mutex or just to use i_size_read() instead.
Note: this does not protect the file->f_pos against concurrent modifications
since this is something the userspace has to take care about.
-Note: ext2_release() was *the* source of contention on fs-intensive
-loads and dropping BKL on ->release() helps to get rid of that (we still
-grab BKL for cases when we close a file that had been opened r/w, but that
-can and should be done using the internal locking with smaller critical areas).
-Current worst offender is ext2_get_block()...
-
-->fasync() is called without BKL protection, and is responsible for
-maintaining the FASYNC bit in filp->f_flags. Most instances call
-fasync_helper(), which does that maintenance, so it's not normally
-something one needs to worry about. Return values > 0 will be mapped to
-zero in the VFS layer.
+->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags.
+Most instances call fasync_helper(), which does that maintenance, so it's
+not normally something one needs to worry about. Return values > 0 will be
+mapped to zero in the VFS layer.
->readdir() and ->ioctl() on directories must be changed. Ideally we would
move ->readdir() to inode_operations and use a separate method for directory
@@ -466,8 +474,6 @@ components. And there are other reasons why the current interface is a mess...
->read on directories probably must go away - we should just enforce -EISDIR
in sys_read() and friends.
-->fsync() has i_mutex on inode.
-
--------------------------- dquot_operations -------------------------------
prototypes:
int (*write_dquot) (struct dquot *);
@@ -502,12 +508,12 @@ prototypes:
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
locking rules:
- BKL mmap_sem PageLocked(page)
-open: no yes
-close: no yes
-fault: no yes can return with page locked
-page_mkwrite: no yes can return with page locked
-access: no yes
+ mmap_sem PageLocked(page)
+open: yes
+close: yes
+fault: yes can return with page locked
+page_mkwrite: yes can return with page locked
+access: yes
->fault() is called when a previously not present pte is about
to be faulted in. The filesystem must find and return the page associated
@@ -534,6 +540,3 @@ VM_IO | VM_PFNMAP VMAs.
(if you break something or notice that it is broken and do not fix it yourself
- at least put it here)
-
-ipc/shm.c::shm_delete() - may need BKL.
-->read() and ->write() in many drivers are (probably) missing BKL.
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt
deleted file mode 100644
index 79334ed5daa7..000000000000
--- a/Documentation/filesystems/dentry-locking.txt
+++ /dev/null
@@ -1,174 +0,0 @@
-RCU-based dcache locking model
-==============================
-
-On many workloads, the most common operation on dcache is to look up a
-dentry, given a parent dentry and the name of the child. Typically,
-for every open(), stat() etc., the dentry corresponding to the
-pathname will be looked up by walking the tree starting with the first
-component of the pathname and using that dentry along with the next
-component to look up the next level and so on. Since it is a frequent
-operation for workloads like multiuser environments and web servers,
-it is important to optimize this path.
-
-Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus in
-every component during path look-up. Since 2.5.10 onwards, fast-walk
-algorithm changed this by holding the dcache_lock at the beginning and
-walking as many cached path component dentries as possible. This
-significantly decreases the number of acquisition of
-dcache_lock. However it also increases the lock hold time
-significantly and affects performance in large SMP machines. Since
-2.5.62 kernel, dcache has been using a new locking model that uses RCU
-to make dcache look-up lock-free.
-
-The current dcache locking model is not very different from the
-existing dcache locking model. Prior to 2.5.62 kernel, dcache_lock
-protected the hash chain, d_child, d_alias, d_lru lists as well as
-d_inode and several other things like mount look-up. RCU-based changes
-affect only the way the hash chain is protected. For everything else
-the dcache_lock must be taken for both traversing as well as
-updating. The hash chain updates too take the dcache_lock. The
-significant change is the way d_lookup traverses the hash chain, it
-doesn't acquire the dcache_lock for this and rely on RCU to ensure
-that the dentry has not been *freed*.
-
-
-Dcache locking details
-======================
-
-For many multi-user workloads, open() and stat() on files are very
-frequently occurring operations. Both involve walking of path names to
-find the dentry corresponding to the concerned file. In 2.4 kernel,
-dcache_lock was held during look-up of each path component. Contention
-and cache-line bouncing of this global lock caused significant
-scalability problems. With the introduction of RCU in Linux kernel,
-this was worked around by making the look-up of path components during
-path walking lock-free.
-
-
-Safe lock-free look-up of dcache hash table
-===========================================
-
-Dcache is a complex data structure with the hash table entries also
-linked together in other lists. In 2.4 kernel, dcache_lock protected
-all the lists. We applied RCU only on hash chain walking. The rest of
-the lists are still protected by dcache_lock. Some of the important
-changes are :
-
-1. The deletion from hash chain is done using hlist_del_rcu() macro
- which doesn't initialize next pointer of the deleted dentry and
- this allows us to walk safely lock-free while a deletion is
- happening.
-
-2. Insertion of a dentry into the hash table is done using
- hlist_add_head_rcu() which take care of ordering the writes - the
- writes to the dentry must be visible before the dentry is
- inserted. This works in conjunction with hlist_for_each_rcu(),
- which has since been replaced by hlist_for_each_entry_rcu(), while
- walking the hash chain. The only requirement is that all
- initialization to the dentry must be done before
- hlist_add_head_rcu() since we don't have dcache_lock protection
- while traversing the hash chain. This isn't different from the
- existing code.
-
-3. The dentry looked up without holding dcache_lock by cannot be
- returned for walking if it is unhashed. It then may have a NULL
- d_inode or other bogosity since RCU doesn't protect the other
- fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
- indicate unhashed dentries and use this in conjunction with a
- per-dentry lock (d_lock). Once looked up without the dcache_lock,
- we acquire the per-dentry lock (d_lock) and check if the dentry is
- unhashed. If so, the look-up is failed. If not, the reference count
- of the dentry is increased and the dentry is returned.
-
-4. Once a dentry is looked up, it must be ensured during the path walk
- for that component it doesn't go away. In pre-2.5.10 code, this was
- done holding a reference to the dentry. dcache_rcu does the same.
- In some sense, dcache_rcu path walking looks like the pre-2.5.10
- version.
-
-5. All dentry hash chain updates must take the dcache_lock as well as
- the per-dentry lock in that order. dput() does this to ensure that
- a dentry that has just been looked up in another CPU doesn't get
- deleted before dget() can be done on it.
-
-6. There are several ways to do reference counting of RCU protected
- objects. One such example is in ipv4 route cache where deferred
- freeing (using call_rcu()) is done as soon as the reference count
- goes to zero. This cannot be done in the case of dentries because
- tearing down of dentries require blocking (dentry_iput()) which
- isn't supported from RCU callbacks. Instead, tearing down of
- dentries happen synchronously in dput(), but actual freeing happens
- later when RCU grace period is over. This allows safe lock-free
- walking of the hash chains, but a matched dentry may have been
- partially torn down. The checking of DCACHE_UNHASHED flag with
- d_lock held detects such dentries and prevents them from being
- returned from look-up.
-
-
-Maintaining POSIX rename semantics
-==================================
-
-Since look-up of dentries is lock-free, it can race against a
-concurrent rename operation. For example, during rename of file A to
-B, look-up of either A or B must succeed. So, if look-up of B happens
-after A has been removed from the hash chain but not added to the new
-hash chain, it may fail. Also, a comparison while the name is being
-written concurrently by a rename may result in false positive matches
-violating rename semantics. Issues related to race with rename are
-handled as described below :
-
-1. Look-up can be done in two ways - d_lookup() which is safe from
- simultaneous renames and __d_lookup() which is not. If
- __d_lookup() fails, it must be followed up by a d_lookup() to
- correctly determine whether a dentry is in the hash table or
- not. d_lookup() protects look-ups using a sequence lock
- (rename_lock).
-
-2. The name associated with a dentry (d_name) may be changed if a
- rename is allowed to happen simultaneously. To avoid memcmp() in
- __d_lookup() go out of bounds due to a rename and false positive
- comparison, the name comparison is done while holding the
- per-dentry lock. This prevents concurrent renames during this
- operation.
-
-3. Hash table walking during look-up may move to a different bucket as
- the current dentry is moved to a different bucket due to rename.
- But we use hlists in dcache hash table and they are
- null-terminated. So, even if a dentry moves to a different bucket,
- hash chain walk will terminate. [with a list_head list, it may not
- since termination is when the list_head in the original bucket is
- reached]. Since we redo the d_parent check and compare name while
- holding d_lock, lock-free look-up will not race against d_move().
-
-4. There can be a theoretical race when a dentry keeps coming back to
- original bucket due to double moves. Due to this look-up may
- consider that it has never moved and can end up in a infinite loop.
- But this is not any worse that theoretical livelocks we already
- have in the kernel.
-
-
-Important guidelines for filesystem developers related to dcache_rcu
-====================================================================
-
-1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
- don't change. Only dcache internal implementation changes. However
- filesystems *must not* delete from the dentry hash chains directly
- using the list macros like allowed earlier. They must use dcache
- APIs like d_drop() or __d_drop() depending on the situation.
-
-2. d_flags is now protected by a per-dentry lock (d_lock). All access
- to d_flags must be protected by it.
-
-3. For a hashed dentry, checking of d_count needs to be protected by
- d_lock.
-
-
-Papers and other documentation on dcache locking
-================================================
-
-1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
-
-2. http://lse.sourceforge.net/locking/dcache/dcache.html
-
-
-
diff --git a/Documentation/filesystems/path-lookup.txt b/Documentation/filesystems/path-lookup.txt
new file mode 100644
index 000000000000..fbafc0f98d38
--- /dev/null
+++ b/Documentation/filesystems/path-lookup.txt
@@ -0,0 +1,294 @@
+Path walking and name lookup locking
+====================================
+
+Path resolution is finding a dentry or parent dentry corresponding to a path
+name, by performing a path walk. Typically, for every open(), stat() etc., the
+path name will be resolved. Paths are resolved by walking the tree starting
+with the first component of the pathname, and using that dentry along with the
+next component to look up the next level and so on.
+
+Since it is a frequent operation for workloads like multiuser environments and
+web servers, it is important to optimize this code.
+
+Path walking synchronisation history:
+Prior to 2.5.10, dcache_lock was acquired in d_lookup (dcache hash lookup) and
+thus in every component during path look-up. Since 2.5.10 onwards, fast-walk
+algorithm changed this by holding the dcache_lock at the beginning and walking
+as many cached path component dentries as possible. This significantly
+decreases the number of acquisition of dcache_lock. However it also increases
+the lock hold time significantly and affects performance in large SMP machines.
+Since 2.5.62 kernel, dcache has been using a new locking model that uses RCU to
+make dcache look-up lock-free.
+
+All the above algorithms required taking a lock and reference count on the
+dentry that was looked up, so that may be used as the basis for walking the
+next path element. This is inefficient and unscalable. It is inefficient
+because of the locks and atomic operations required for every dentry element
+slows things down. It is not scalable because many parallel applications that
+are path-walk intensive tend to do path lookups starting from a common dentry
+(usually, the root "/" or current working directory). So contention on these
+common path elements causes lock and cacheline queueing.
+
+Since 2.6.38, RCU is used to make a significant part of the entire path walk
+(including dcache look-up) completely "store-free" (so, no locks, atomics, or
+even stores into cachelines of common dentries). This is known as rcu-walk
+path walking.
+
+Path walking overview
+=====================
+
+A name string specifies a start (root directory, cwd, fd-relative) and a
+sequence of elements (directory entry names), which together refer to a path in
+the namespace. The elements are strings seperated by '/'.
+
+Name lookups will want to find a particular path that a name string refers to
+(usually the path of the final element, or parent of final element). This is
+done by taking the path given by the name's starting point (which we know in
+advance -- eg. current->fs->cwd) as the first parent of the lookup. Then
+iteratively for each name element, look up the child of the current parent with
+the given name and if it is not the final entry, make it the parent for the
+next lookup.
+
+The parent must of course be a directory, and we must have appropriate
+permissions on the parent inode to be able to walk into it.
+
+Making the child a parent for the next lookup requires more checks and
+procedures. Symlinks essentially substitute the symlink name for the target
+name in the name string, and require some recursive path walking. Mount points
+must be followed into, switching from the mount point path to the root of the
+particular mounted vfsmount.
+
+Path walking then must, broadly, do several particular things:
+- perform dcache name lookups on (parent, name element) tuples;
+- find the start point of the walk;
+- perform permissions and validity checks on inodes;
+- traverse mount points;
+- traverse symlinks;
+- lookup and create missing parts of the path on demand.
+
+Safe store-free look-up of dcache hash table
+============================================
+
+Dcache name lookup
+------------------
+In order to lookup a dcache (parent, name) tuple, we take a hash on the tuple
+and use that to select a bucket in the dcache-hash table. The list of entries
+in that bucket is then walked, and we do a full comparison of each entry
+against our (parent, name) tuple.
+
+The hash lists are RCU protected, so list walking is not serialised with
+concurrent updates (insertion, deletion from the hash). This is a standard RCU
+list application with the exception of renames, which will be covered below.
+
+Parent and name members of a dentry, as well as its membership in the dcache
+hash, and its inode are protected by the per-dentry d_lock spinlock. A
+reference is taken on the dentry (while the fields are verified under d_lock),
+and this stabilises its d_inode pointer and the inode it points to. This gives
+a stable point to perform the next step of our path walk against.
+
+These members are also protected by d_seq seqlock, although this offers
+read-only protection and no durability of results so care must be taken when
+using d_seq for synchronisation (see below).
+
+Renames
+-------
+Back to the rename case. In usual RCU protected lists, the only operations that
+will happen to an object is insertion, and then eventually removal from the
+list. The object will not be reused until an RCU grace period is complete.
+This ensures the RCU list traversal primitives can run over the object without
+problems (see RCU documentation for how this works).
+
+However when a dentry is renamed, its hash value can change, requiring it to be
+moved to a new hash list. Allocating and inserting a new alias would be
+expensive and also problematic for directory dentries. Latency would be far to
+high to wait for a grace period after removing the dentry and before inserting
+it in the new hash bucket. So what is done is to insert the dentry into the
+new list immediately.
+
+However, when the dentry's list pointers are updated to point to objects in the
+new list before waiting for a grace period, this can result in a concurrent RCU
+lookup of the old list veering off into the new (incorrect) list and missing
+the remaining dentries on the list.
+
+There is no fundamental problem with walking down the wrong list, because the
+dentry comparisons will never match. However it is fatal to miss a matching
+dentry. So a seqlock is used to detect when a rename has occurred, and so the
+lookup can be retried.
+
+ 1 2 3
+ +---+ +---+ +---+
+hlist-->| N-+->| N-+->| N-+->
+head <--+-P |<-+-P |<-+-P |
+ +---+ +---+ +---+
+
+Rename of dentry 2 may require it deleted from the above list, and inserted
+into a new list. Deleting 2 gives the following list.
+
+ 1 3
+ +---+ +---+ (don't worry, the longer pointers do not
+hlist-->| N-+-------->| N-+-> impose a measurable performance overhead
+head <--+-P |<--------+-P | on modern CPUs)
+ +---+ +---+
+ ^ 2 ^
+ | +---+ |
+ | | N-+----+
+ +----+-P |
+ +---+
+
+This is a standard RCU-list deletion, which leaves the deleted object's
+pointers intact, so a concurrent list walker that is currently looking at
+object 2 will correctly continue to object 3 when it is time to traverse the
+next object.
+
+However, when inserting object 2 onto a new list, we end up with this:
+
+ 1 3
+ +---+ +---+
+hlist-->| N-+-------->| N-+->
+head <--+-P |<--------+-P |
+ +---+ +---+
+ 2
+ +---+
+ | N-+---->
+ <----+-P |
+ +---+
+
+Because we didn't wait for a grace period, there may be a concurrent lookup
+still at 2. Now when it follows 2's 'next' pointer, it will walk off into
+another list without ever having checked object 3.
+
+A related, but distinctly different, issue is that of rename atomicity versus
+lookup operations. If a file is renamed from 'A' to 'B', a lookup must only
+find either 'A' or 'B'. So if a lookup of 'A' returns NULL, a subsequent lookup
+of 'B' must succeed (note the reverse is not true).
+
+Between deleting the dentry from the old hash list, and inserting it on the new
+hash list, a lookup may find neither 'A' nor 'B' matching the dentry. The same
+rename seqlock is also used to cover this race in much the same way, by
+retrying a negative lookup result if a rename was in progress.
+
+Seqcount based lookups
+----------------------
+In refcount based dcache lookups, d_lock is used to serialise access to
+the dentry, stabilising it while comparing its name and parent and then
+taking a reference count (the reference count then gives a stable place to
+start the next part of the path walk from).
+
+So in rcu-walk mode, we want to do path walking without taking locks or
+reference counts. So d_seq is used to take a coherent snapshot of what the
+dentry looks like (its name, parent, and inode). That snapshot is then used
+to start the next part of the path walk. When loading our coherent snapshot
+under d_seq, care must be taken to load the members up-front, and use those
+loaded pointers rather than reloading from the dentry later on (otherwise
+we'd have interesting things like d_inode going NULL underneath us).
+
+Also important is to avoid performing any destructive operations (pretty much:
+no non-atomic stores to shared data), and to recheck the seqcount when we are
+"done" with the operation. Retry or abort if the seqcount does not match.
+Avoiding destructive or changing operations means we can easily unwind from
+failure.
+
+What this means is that a caller, provided they are holding RCU lock to
+protect the dentry object from disappearing, can perform a seqcount based
+lookup which does not increment the refcount on the dentry or write to
+it in any way. This returned dentry can be used for subsequent operations,
+provided that d_seq is rechecked after that operation is complete.
+
+RCU-walk path walking design
+============================
+
+Path walking code has two distinct modes, ref-walk and rcu-walk. ref-walk
+is the traditional[*] way of performing dcache lookups using d_lock to
+serialise concurrent modifications to the dentry and take a reference count
+on it. ref-walk is simple and obvious, and may sleep, take locks, etc while
+path walking is operating on each dentry. rcu-walk uses seqcount based
+dentry lookups and can perform lookup of intermediate elements without
+performing any stores to shared data in the dentry or inode. rcu-walk can
+not be applied to all cases, eg. if the filesystem must sleep or perform
+non trivial operations, rcu-walk must be switched to ref-walk.
+
+[*] RCU is still used for the dentry hash lookup, but not the full path walk.
+
+Where ref-walk uses a stable, refcounted ``parent'' to walk the remaining
+path string, rcu-walk uses a d_seq protected snapshot. When looking up a
+child from its parent snapshot, we open d_seq critical section on the child
+before closing d_seq critical section on the parent. This gives an interlocking
+ladder of snapshots to walk down.
+
+It is, in some sense, a bit of a house of cards. If the seqcount check of the
+parent snapshot fails, the house comes down, because we had closed the
+d_seq section on the grandparent, so we have nothing to stand on. In that case,
+the path walk must be restarted (which we do in ref-walk mode, to avoid live
+locks). It is costly to have a failed walk like this, but fortunately, the
+further toward the root we go, the less frequently changes tend to happen.
+
+When we reach a point where sleeping is required, or a filesystem callout is
+required, then instead of starting the walk again, we attempt to drop out of
+rcu-walk mode into ref-walk mode at the point we have reached. That is, we
+take a lock on the dentry, then recheck its d_seq count under lock (to ensure
+we got the right thing), and then its refcount is elevated. This way, we have
+a stable, referenced dentry as-in ref-walk.
+
+The overall design for rcu-walk is like this:
+* LOOKUP_RCU is set in nd->flags, which distinguishes rcu-walk from ref-walk.
+* Take the RCU lock for the entire path walk, starting with the acquiring
+ of the starting path (eg. root/cwd/fd-path). So now dentry refcounts are
+ not required for dentry persistence.
+* synchronize_rcu is called when unregistering a filesystem, so we can
+ access d_ops and i_ops during rcu-walk.
+* Similarly take the vfsmount lock for the entire path walk. So now mnt
+ refcounts are not required for persistence. Also we are free to perform mount
+ lookups, and to assume dentry mount points and mount roots are stable up and
+ down the path.
+* Have a per-dentry seqlock to protect the dentry name, parent, and inode,
+ so we can load this tuple atomically, and also check whether any of its
+ members have changed.
+* Dentry lookups (based on parent, candidate string tuple) recheck the parent
+ sequence after the child is found in case anything changed in the parent
+ during the path walk.
+* inode is also RCU protected so we can load d_inode and use the inode for
+ limited things.
+* i_mode, i_uid, i_gid can be tested for exec permissions during path walk.
+* i_op can be loaded.
+
+When we reach the destination dentry, we lock it, recheck lookup sequence,
+and increment its refcount and mountpoint refcount. RCU and vfsmount locks
+are dropped. This is termed "dropping rcu-walk" (see nameidata_drop_rcu group
+of functions). If the dentry seqcount does not match, we can not drop rcu-walk
+gracefully at the current point in the lokup, so instead return -ECHILD (for
+want of a better errno). This signals the path walking code to re-do the entire
+lookup with a ref-walk.
+
+Aside from the final dentry, there are other situations that may be encountered
+where we cannot continue rcu-walk. In that case, we drop rcu-walk (ie. take a
+reference on the last good dentry) and continue with a ref-walk. Again, if we
+can drop rcu-walk gracefully, we return -ECHILD and do the whole lookup using
+ref-walk. But it is very important that we can continue with ref-walk for most
+cases, particularly to avoid the overhead of double lookups, and to gain the
+scalability advantages on common path elements (like cwd and root).
+
+The cases where rcu-walk cannot continue are:
+* NULL dentry (ie. any uncached path element)
+* Following links
+
+It may be possible eventually to make following links rcu-walk aware.
+
+Uncached path elements will always require dropping to ref-walk mode, at the
+very least because i_mutex needs to be grabbed, and objects allocated.
+
+Final note:
+"store-free" path walking is not strictly store free. We take vfsmount lock
+and refcounts (both of which can be made per-cpu), and we also store to the
+stack (which is essentially CPU-local), and we also have to take locks and
+refcount on final dentry.
+
+But the point is that shared data, where practically possible, is not locked
+or stored into.
+
+
+Papers and other documentation on dcache locking
+================================================
+
+1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
+
+2. http://lse.sourceforge.net/locking/dcache/dcache.html
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index b12c89538680..f342d36ecb1c 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -216,7 +216,6 @@ had ->revalidate()) add calls in ->follow_link()/->readlink().
->d_parent changes are not protected by BKL anymore. Read access is safe
if at least one of the following is true:
* filesystem has no cross-directory rename()
- * dcache_lock is held
* we know that parent had been locked (e.g. we are looking at
->d_parent of ->lookup() argument).
* we are called from ->rename().
@@ -318,3 +317,68 @@ if it's zero is not *and* *never* *had* *been* enough. Final unlink() and iput(
may happen while the inode is in the middle of ->write_inode(); e.g. if you blindly
free the on-disk inode, you may end up doing that while ->write_inode() is writing
to it.
+
+---
+[mandatory]
+
+ .d_delete() now only advises the dcache as to whether or not to cache
+unreferenced dentries, and is now only called when the dentry refcount goes to
+0. Even on 0 refcount transition, it must be able to tolerate being called 0,
+1, or more times (eg. constant, idempotent).
+
+---
+[mandatory]
+
+ .d_compare() calling convention and locking rules are significantly
+changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
+look at examples of other filesystems) for guidance.
+
+---
+[mandatory]
+
+ .d_hash() calling convention and locking rules are significantly
+changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
+look at examples of other filesystems) for guidance.
+
+---
+[mandatory]
+ dcache_lock is gone, replaced by fine grained locks. See fs/dcache.c
+for details of what locks to replace dcache_lock with in order to protect
+particular things. Most of the time, a filesystem only needs ->d_lock, which
+protects *all* the dcache state of a given dentry.
+
+--
+[mandatory]
+
+ Filesystems must RCU-free their inodes, if they can have been accessed
+via rcu-walk path walk (basically, if the file can have had a path name in the
+vfs namespace).
+
+ i_dentry and i_rcu share storage in a union, and the vfs expects
+i_dentry to be reinitialized before it is freed, so an:
+
+ INIT_LIST_HEAD(&inode->i_dentry);
+
+must be done in the RCU callback.
+
+--
+[recommended]
+ vfs now tries to do path walking in "rcu-walk mode", which avoids
+atomic operations and scalability hazards on dentries and inodes (see
+Documentation/filesystems/path-walk.txt). d_hash and d_compare changes (above)
+are examples of the changes required to support this. For more complex
+filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so
+no changes are required to the filesystem. However, this is costly and loses
+the benefits of rcu-walk mode.
+
+ d_revalidate is a callback that is made on every path element (if
+the filesystem provides it), which requires dropping out of rcu-walk mode. If
+you can run all or substantial number of cases of d_revalidate without blocking
+or storing to the dentry or inodes, d_revalidate_rcu can be used, with care (see
+Documentation/filesystems/vfs.txt and existing users).
+
+ permission and check_acl are inode permission checks that are called
+on many or all directory inodes on the way down a path walk (to check for
+exec permission). If you can run all, or a substantial number of cases of
+these without blocking or storing to the inodes, permission_rcu or
+check_acl_rcu can be used, with care.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index ed7e5efc06d8..2d6ee85b43c9 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -325,7 +325,10 @@ struct inode_operations {
void * (*follow_link) (struct dentry *, struct nameidata *);
void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int, struct nameidata *);
+ int (*permission) (struct inode *, int);
+ int (*permission_rcu) (struct inode *, int, unsigned int);
+ int (*check_acl)(struct inode *, int);
+ int (*check_acl_rcu)(struct inode *, int, unsigned int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -414,6 +417,15 @@ otherwise noted.
permission: called by the VFS to check for access rights on a POSIX-like
filesystem.
+ permission_rcu: same as permission, but may be called in rcu-walk
+ mode (flags & IPERM_RCU). If in rcu-walk mode, the filesystem
+ must check the permission without blocking or storing to the
+ inode.
+
+ If a situation is encountered that rcu-walk cannot handle, return
+ -ECHILD and it will be called again in ref-walk mode. Filesystem
+ should only define at most one of permission or permission_rcu.
+
setattr: called by the VFS to set attributes for a file. This method
is called by chmod(2) and related system calls.
@@ -534,6 +546,7 @@ struct address_space_operations {
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
+ void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -660,11 +673,10 @@ struct address_space_operations {
releasepage: releasepage is called on PagePrivate pages to indicate
that the page should be freed if possible. ->releasepage
should remove any private data from the page and clear the
- PagePrivate flag. It may also remove the page from the
- address_space. If this fails for some reason, it may indicate
- failure with a 0 return value.
- This is used in two distinct though related cases. The first
- is when the VM finds a clean page with no active users and
+ PagePrivate flag. If releasepage() fails for some reason, it must
+ indicate failure with a 0 return value.
+ releasepage() is used in two distinct though related cases. The
+ first is when the VM finds a clean page with no active users and
wants to make it a free page. If ->releasepage succeeds, the
page will be removed from the address_space and become free.
@@ -679,6 +691,12 @@ struct address_space_operations {
need to ensure this. Possibly it can clear the PageUptodate
bit if it cannot free private data yet.
+ freepage: freepage is called once the page is no longer visible in
+ the page cache in order to allow the cleanup of any private
+ data. Since it may be called by the memory reclaimer, it
+ should not assume that the original address_space mapping still
+ exists, and it should not block.
+
direct_IO: called by the generic read/write routines to perform
direct_IO - that is IO requests which bypass the page cache
and transfer data directly between the storage and the
@@ -841,9 +859,13 @@ defined:
struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *);
- int (*d_hash) (struct dentry *, struct qstr *);
- int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
- int (*d_delete)(struct dentry *);
+ int (*d_revalidate_rcu)(struct dentry *, struct nameidata *);
+ int (*d_hash)(const struct dentry *, const struct inode *,
+ struct qstr *);
+ int (*d_compare)(const struct dentry *, const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
+ int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
@@ -854,13 +876,46 @@ struct dentry_operations {
dcache. Most filesystems leave this as NULL, because all their
dentries in the dcache are valid
- d_hash: called when the VFS adds a dentry to the hash table
+ d_revalidate_rcu: same as d_revalidate, but may be called in rcu-walk
+ mode (nd->flags & LOOKUP_RCU). If in rcu-walk mode, the filesystem
+ must revalidate the dentry without blocking or storing to the
+ dentry, d_parent and d_inode should not be used without care (because
+ they can go NULL), instead nd->inode should be used.
+
+ If a situation is encountered that rcu-walk cannot handle, return
+ -ECHILD and it will be called again in ref-walk mode. Filesystem
+ should only define at most one of d_revalidate or d_revalidate_rcu.
+
+ d_hash: called when the VFS adds a dentry to the hash table. The first
+ dentry passed to d_hash is the parent directory that the name is
+ to be hashed into. The inode is the dentry's inode.
+
+ Same locking and synchronisation rules as d_compare regarding
+ what is safe to dereference etc.
+
+ d_compare: called to compare a dentry name with a given name. The first
+ dentry is the parent of the dentry to be compared, the second is
+ the parent's inode, then the dentry and inode (may be NULL) of the
+ child dentry. len and name string are properties of the dentry to be
+ compared. qstr is the name to compare it with.
+
+ Must be constant and idempotent, and should not take locks if
+ possible, and should not or store into the dentry or inodes.
+ Should not dereference pointers outside the dentry or inodes without
+ lots of care (eg. d_parent, d_inode, d_name should not be used).
+
+ However, our vfsmount is pinned, and RCU held, so the dentries and
+ inodes won't disappear, neither will our sb or filesystem module.
+ ->i_sb and ->d_sb may be used.
- d_compare: called when a dentry should be compared with another
+ It is a tricky calling convention because it needs to be called under
+ "rcu-walk", ie. without any locks or references on things.
- d_delete: called when the last reference to a dentry is
- deleted. This means no-one is using the dentry, however it is
- still valid and in the dcache
+ d_delete: called when the last reference to a dentry is dropped and the
+ dcache is deciding whether or not to cache it. Return 1 to delete
+ immediately, or 0 to cache the dentry. Default is NULL which means to
+ always cache a reachable dentry. d_delete must be constant and
+ idempotent.
d_release: called when a dentry is really deallocated
@@ -904,14 +959,11 @@ manipulate dentries:
the usage count)
dput: close a handle for a dentry (decrements the usage count). If
- the usage count drops to 0, the "d_delete" method is called
- and the dentry is placed on the unused list if the dentry is
- still in its parents hash list. Putting the dentry on the
- unused list just means that if the system needs some RAM, it
- goes through the unused list of dentries and deallocates them.
- If the dentry has already been unhashed and the usage count
- drops to 0, in this case the dentry is deallocated after the
- "d_delete" method is called
+ the usage count drops to 0, and the dentry is still in its
+ parent's hash, the "d_delete" method is called to check whether
+ it should be cached. If it should not be cached, or if the dentry
+ is not hashed, it is deleted. Otherwise cached dentries are put
+ into an LRU list to be reclaimed on memory shortage.
d_drop: this unhashes a dentry from its parents hash list. A
subsequent call to dput() will deallocate the dentry if its
diff --git a/Documentation/hwmon/adm9240 b/Documentation/hwmon/adm9240
index 2c6f1fed4618..36e8ec6aa868 100644
--- a/Documentation/hwmon/adm9240
+++ b/Documentation/hwmon/adm9240
@@ -155,7 +155,7 @@ connected to a normally open switch.
The ADM9240 provides an internal open drain on this line, and may output
a 20 ms active low pulse to reset an external Chassis Intrusion latch.
-Clear the CI latch by writing value 1 to the sysfs chassis_clear file.
+Clear the CI latch by writing value 0 to the sysfs intrusion0_alarm file.
Alarm flags reported as 16-bit word
diff --git a/Documentation/hwmon/ads7828 b/Documentation/hwmon/ads7828
index 75bc4beaf447..2bbebe6f771f 100644
--- a/Documentation/hwmon/ads7828
+++ b/Documentation/hwmon/ads7828
@@ -9,7 +9,7 @@ Supported chips:
http://focus.ti.com/lit/ds/symlink/ads7828.pdf
Authors:
- Steve Hardy <steve@linuxrealtime.co.uk>
+ Steve Hardy <shardy@redhat.com>
Module Parameters
-----------------
diff --git a/Documentation/hwmon/ds620 b/Documentation/hwmon/ds620
new file mode 100644
index 000000000000..824d01d703da
--- /dev/null
+++ b/Documentation/hwmon/ds620
@@ -0,0 +1,23 @@
+Kernel driver ds620
+===================
+
+Supported chips:
+ * Dallas Semiconductor DS620
+ Prefix: 'ds620'
+ Addresses scanned: I2C 0x48 - 0x4f
+ Datasheet: Publicly available at the Dallas Semiconductor website
+ http://www.dalsemi.com/
+
+Authors:
+ Roland Stigge <stigge@antcom.de>
+ based on ds1621.c by
+ Christian W. Zuckschwerdt <zany@triq.net>
+
+Description
+-----------
+
+The DS620 is a (one instance) digital thermometer and thermostat. It has both
+high and low temperature limits which can be user defined (i.e. programmed
+into non-volatile on-chip registers). Temperature range is -55 degree Celsius
+to +125. Between 0 and 70 degree Celsius, accuracy is 0.5 Kelvin. The value
+returned via sysfs displays post decimal positions.
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 645699010551..5997b5efc1cb 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -384,10 +384,20 @@ curr[1-*]_min Current min value.
Unit: milliampere
RW
+curr[1-*]_lcrit Current critical low value
+ Unit: milliampere
+ RW
+
+curr[1-*]_crit Current critical high value.
+ Unit: milliampere
+ RW
+
curr[1-*]_input Current input value
Unit: milliampere
RO
+Also see the Alarms section for status flags associated with currents.
+
*********
* Power *
*********
@@ -450,13 +460,6 @@ power[1-*]_accuracy Accuracy of the power meter.
Unit: Percent
RO
-power[1-*]_alarm 1 if the system is drawing more power than the
- cap allows; 0 otherwise. A poll notification is
- sent to this file when the power use exceeds the
- cap. This file only appears if the cap is known
- to be enforced by hardware.
- RO
-
power[1-*]_cap If power use rises above this limit, the
system should take action to reduce power use.
A poll notification is sent to this file if the
@@ -479,6 +482,20 @@ power[1-*]_cap_min Minimum cap that can be set.
Unit: microWatt
RO
+power[1-*]_max Maximum power.
+ Unit: microWatt
+ RW
+
+power[1-*]_crit Critical maximum power.
+ If power rises to or above this limit, the
+ system is expected take drastic action to reduce
+ power consumption, such as a system shutdown or
+ a forced powerdown of some devices.
+ Unit: microWatt
+ RW
+
+Also see the Alarms section for status flags associated with power readings.
+
**********
* Energy *
**********
@@ -501,6 +518,7 @@ implementation.
in[0-*]_alarm
curr[1-*]_alarm
+power[1-*]_alarm
fan[1-*]_alarm
temp[1-*]_alarm
Channel alarm
@@ -512,12 +530,20 @@ OR
in[0-*]_min_alarm
in[0-*]_max_alarm
+in[0-*]_lcrit_alarm
+in[0-*]_crit_alarm
curr[1-*]_min_alarm
curr[1-*]_max_alarm
+curr[1-*]_lcrit_alarm
+curr[1-*]_crit_alarm
+power[1-*]_cap_alarm
+power[1-*]_max_alarm
+power[1-*]_crit_alarm
fan[1-*]_min_alarm
fan[1-*]_max_alarm
temp[1-*]_min_alarm
temp[1-*]_max_alarm
+temp[1-*]_lcrit_alarm
temp[1-*]_crit_alarm
temp[1-*]_emergency_alarm
Limit alarm
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf
index fb145e5e722a..8432e1118173 100644
--- a/Documentation/hwmon/w83627hf
+++ b/Documentation/hwmon/w83627hf
@@ -91,3 +91,25 @@ isaset -y -f 0x2e 0xaa
The above sequence assumes a Super-I/O config space at 0x2e/0x2f, but
0x4e/0x4f is also possible.
+
+Voltage pin mapping
+-------------------
+
+Here is a summary of the voltage pin mapping for the W83627THF. This
+can be useful to convert data provided by board manufacturers into
+working libsensors configuration statements.
+
+ W83627THF |
+ Pin | Name | Register | Sysfs attribute
+-----------------------------------------------------
+ 100 | CPUVCORE | 20h | in0
+ 99 | VIN0 | 21h | in1
+ 98 | VIN1 | 22h | in2
+ 97 | VIN2 | 24h | in4
+ 114 | AVCC | 23h | in3
+ 61 | 5VSB | 50h (bank 5) | in7
+ 74 | VBAT | 51h (bank 5) | in8
+
+For other supported devices, you'll have to take the hard path and
+look up the information in the datasheet yourself (and then add it
+to this document please.)
diff --git a/Documentation/hwmon/w83793 b/Documentation/hwmon/w83793
index 51171a83165b..6cc5f639b721 100644
--- a/Documentation/hwmon/w83793
+++ b/Documentation/hwmon/w83793
@@ -92,7 +92,7 @@ This driver implements support for Winbond W83793G/W83793R chips.
* Chassis
If the case open alarm triggers, it will stay in this state unless cleared
- by any write to the sysfs file "chassis".
+ by writing 0 to the sysfs file "intrusion0_alarm".
* VID and VRM
The VRM version is detected automatically, don't modify the it unless you
diff --git a/Documentation/i2c/muxes/gpio-i2cmux b/Documentation/i2c/muxes/gpio-i2cmux
new file mode 100644
index 000000000000..811cd78d4cdc
--- /dev/null
+++ b/Documentation/i2c/muxes/gpio-i2cmux
@@ -0,0 +1,65 @@
+Kernel driver gpio-i2cmux
+
+Author: Peter Korsgaard <peter.korsgaard@barco.com>
+
+Description
+-----------
+
+gpio-i2cmux is an i2c mux driver providing access to I2C bus segments
+from a master I2C bus and a hardware MUX controlled through GPIO pins.
+
+E.G.:
+
+ ---------- ---------- Bus segment 1 - - - - -
+ | | SCL/SDA | |-------------- | |
+ | |------------| |
+ | | | | Bus segment 2 | |
+ | Linux | GPIO 1..N | MUX |--------------- Devices
+ | |------------| | | |
+ | | | | Bus segment M
+ | | | |---------------| |
+ ---------- ---------- - - - - -
+
+SCL/SDA of the master I2C bus is multiplexed to bus segment 1..M
+according to the settings of the GPIO pins 1..N.
+
+Usage
+-----
+
+gpio-i2cmux uses the platform bus, so you need to provide a struct
+platform_device with the platform_data pointing to a struct
+gpio_i2cmux_platform_data with the I2C adapter number of the master
+bus, the number of bus segments to create and the GPIO pins used
+to control it. See include/linux/gpio-i2cmux.h for details.
+
+E.G. something like this for a MUX providing 4 bus segments
+controlled through 3 GPIO pins:
+
+#include <linux/gpio-i2cmux.h>
+#include <linux/platform_device.h>
+
+static const unsigned myboard_gpiomux_gpios[] = {
+ AT91_PIN_PC26, AT91_PIN_PC25, AT91_PIN_PC24
+};
+
+static const unsigned myboard_gpiomux_values[] = {
+ 0, 1, 2, 3
+};
+
+static struct gpio_i2cmux_platform_data myboard_i2cmux_data = {
+ .parent = 1,
+ .base_nr = 2, /* optional */
+ .values = myboard_gpiomux_values,
+ .n_values = ARRAY_SIZE(myboard_gpiomux_values),
+ .gpios = myboard_gpiomux_gpios,
+ .n_gpios = ARRAY_SIZE(myboard_gpiomux_gpios),
+ .idle = 4, /* optional */
+};
+
+static struct platform_device myboard_i2cmux = {
+ .name = "gpio-i2cmux",
+ .id = 0,
+ .dev = {
+ .platform_data = &myboard_i2cmux_data,
+ },
+};
diff --git a/Documentation/input/cma3000_d0x.txt b/Documentation/input/cma3000_d0x.txt
new file mode 100644
index 000000000000..29d088db4afd
--- /dev/null
+++ b/Documentation/input/cma3000_d0x.txt
@@ -0,0 +1,115 @@
+Kernel driver for CMA3000-D0x
+============================
+
+Supported chips:
+* VTI CMA3000-D0x
+Datasheet:
+ CMA3000-D0X Product Family Specification 8281000A.02.pdf
+ <http://www.vti.fi/en/>
+
+Author: Hemanth V <hemanthv@ti.com>
+
+
+Description
+-----------
+CMA3000 Tri-axis accelerometer supports Motion detect, Measurement and
+Free fall modes.
+
+Motion Detect Mode: Its the low power mode where interrupts are generated only
+when motion exceeds the defined thresholds.
+
+Measurement Mode: This mode is used to read the acceleration data on X,Y,Z
+axis and supports 400, 100, 40 Hz sample frequency.
+
+Free fall Mode: This mode is intended to save system resources.
+
+Threshold values: Chip supports defining threshold values for above modes
+which includes time and g value. Refer product specifications for more details.
+
+CMA3000 chip supports mutually exclusive I2C and SPI interfaces for
+communication, currently the driver supports I2C based communication only.
+Initial configuration for bus mode is set in non volatile memory and can later
+be modified through bus interface command.
+
+Driver reports acceleration data through input subsystem. It generates ABS_MISC
+event with value 1 when free fall is detected.
+
+Platform data need to be configured for initial default values.
+
+Platform Data
+-------------
+fuzz_x: Noise on X Axis
+
+fuzz_y: Noise on Y Axis
+
+fuzz_z: Noise on Z Axis
+
+g_range: G range in milli g i.e 2000 or 8000
+
+mode: Default Operating mode
+
+mdthr: Motion detect g range threshold value
+
+mdfftmr: Motion detect and free fall time threshold value
+
+ffthr: Free fall g range threshold value
+
+Input Interface
+--------------
+Input driver version is 1.0.0
+Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
+Input device name: "cma3000-accelerometer"
+Supported events:
+ Event type 0 (Sync)
+ Event type 3 (Absolute)
+ Event code 0 (X)
+ Value 47
+ Min -8000
+ Max 8000
+ Fuzz 200
+ Event code 1 (Y)
+ Value -28
+ Min -8000
+ Max 8000
+ Fuzz 200
+ Event code 2 (Z)
+ Value 905
+ Min -8000
+ Max 8000
+ Fuzz 200
+ Event code 40 (Misc)
+ Value 0
+ Min 0
+ Max 1
+ Event type 4 (Misc)
+
+
+Register/Platform parameters Description
+----------------------------------------
+
+mode:
+ 0: power down mode
+ 1: 100 Hz Measurement mode
+ 2: 400 Hz Measurement mode
+ 3: 40 Hz Measurement mode
+ 4: Motion Detect mode (default)
+ 5: 100 Hz Free fall mode
+ 6: 40 Hz Free fall mode
+ 7: Power off mode
+
+grange:
+ 2000: 2000 mg or 2G Range
+ 8000: 8000 mg or 8G Range
+
+mdthr:
+ X: X * 71mg (8G Range)
+ X: X * 18mg (2G Range)
+
+mdfftmr:
+ X: (X & 0x70) * 100 ms (MDTMR)
+ (X & 0x0F) * 2.5 ms (FFTMR 400 Hz)
+ (X & 0x0F) * 10 ms (FFTMR 100 Hz)
+
+ffthr:
+ X: (X >> 2) * 18mg (2G Range)
+ X: (X & 0x0F) * 71 mg (8G Range)
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index bdcba154b83e..71536e78406f 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -1,6 +1,6 @@
Multi-touch (MT) Protocol
-------------------------
- Copyright (C) 2009 Henrik Rydberg <rydberg@euromail.se>
+ Copyright (C) 2009-2010 Henrik Rydberg <rydberg@euromail.se>
Introduction
@@ -161,19 +161,24 @@ against the glass. The inner region will increase, and in general, the
ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than
unity, is related to the contact pressure. For pressure-based devices,
ABS_MT_PRESSURE may be used to provide the pressure on the contact area
-instead.
+instead. Devices capable of contact hovering can use ABS_MT_DISTANCE to
+indicate the distance between the contact and the surface.
In addition to the MAJOR parameters, the oval shape of the contact can be
described by adding the MINOR parameters, such that MAJOR and MINOR are the
major and minor axis of an ellipse. Finally, the orientation of the oval
shape can be describe with the ORIENTATION parameter.
+For type A devices, further specification of the touch shape is possible
+via ABS_MT_BLOB_ID.
+
The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
-contact or a pen or something else. Devices with more granular information
-may specify general shapes as blobs, i.e., as a sequence of rectangular
-shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices
-that currently support it, the ABS_MT_TRACKING_ID event may be used to
-report contact tracking from hardware [5].
+finger or a pen or something else. Finally, the ABS_MT_TRACKING_ID event
+may be used to track identified contacts over time [5].
+
+In the type B protocol, ABS_MT_TOOL_TYPE and ABS_MT_TRACKING_ID are
+implicitly handled by input core; drivers should instead call
+input_mt_report_slot_state().
Event Semantics
@@ -213,6 +218,12 @@ The pressure, in arbitrary units, on the contact area. May be used instead
of TOUCH and WIDTH for pressure-based devices or any device with a spatial
signal intensity distribution.
+ABS_MT_DISTANCE
+
+The distance, in surface units, between the contact and the surface. Zero
+distance means the contact is touching the surface. A positive number means
+the contact is hovering above the surface.
+
ABS_MT_ORIENTATION
The orientation of the ellipse. The value should describe a signed quarter
@@ -240,21 +251,24 @@ ABS_MT_TOOL_TYPE
The type of approaching tool. A lot of kernel drivers cannot distinguish
between different tool types, such as a finger or a pen. In such cases, the
event should be omitted. The protocol currently supports MT_TOOL_FINGER and
-MT_TOOL_PEN [2].
+MT_TOOL_PEN [2]. For type B devices, this event is handled by input core;
+drivers should instead use input_mt_report_slot_state().
ABS_MT_BLOB_ID
The BLOB_ID groups several packets together into one arbitrarily shaped
-contact. This is a low-level anonymous grouping for type A devices, and
+contact. The sequence of points forms a polygon which defines the shape of
+the contact. This is a low-level anonymous grouping for type A devices, and
should not be confused with the high-level trackingID [5]. Most type A
devices do not have blob capability, so drivers can safely omit this event.
ABS_MT_TRACKING_ID
The TRACKING_ID identifies an initiated contact throughout its life cycle
-[5]. This event is mandatory for type B devices. The value range of the
-TRACKING_ID should be large enough to ensure unique identification of a
-contact maintained over an extended period of time.
+[5]. The value range of the TRACKING_ID should be large enough to ensure
+unique identification of a contact maintained over an extended period of
+time. For type B devices, this event is handled by input core; drivers
+should instead use input_mt_report_slot_state().
Event Computation
@@ -301,18 +315,19 @@ and with ORIENTATION, one can detect twisting of fingers.
Notes
-----
-In order to stay compatible with existing applications, the data
-reported in a finger packet must not be recognized as single-touch
-events. In addition, all finger data must bypass input filtering,
-since subsequent events of the same type refer to different fingers.
+In order to stay compatible with existing applications, the data reported
+in a finger packet must not be recognized as single-touch events.
+
+For type A devices, all finger data bypasses input filtering, since
+subsequent events of the same type refer to different fingers.
-The first kernel driver to utilize the MT protocol is the bcm5974 driver,
-where examples can be found.
+For example usage of the type A protocol, see the bcm5974 driver. For
+example usage of the type B protocol, see the hid-egalax driver.
[1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the
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] Multitouch X driver project: http://bitmath.org/code/multitouch/.
+[3] The mtdev project: http://bitmath.org/code/mtdev/.
[4] See the section on event computation.
[5] See the section on finger tracking.
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 63ffd78824d8..d6a63c7b4478 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -155,7 +155,6 @@ Code Seq#(hex) Include File Comments
'Q' all linux/soundcard.h
'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict!
-'R' 01-0F media/rds.h conflict!
'R' C0-DF net/bluetooth/rfcomm.h
'S' all linux/cdrom.h conflict!
'S' 80-81 scsi/scsi_ioctl.h conflict!
@@ -194,7 +193,6 @@ Code Seq#(hex) Include File Comments
<http://lrcwww.epfl.ch/>
'b' 00-FF conflict! bit3 vme host bridge
<mailto:natalia@nikhefk.nikhef.nl>
-'b' 00-0F media/bt819.h conflict!
'c' all linux/cm4000_cs.h conflict!
'c' 00-7F linux/comstats.h conflict!
'c' 00-7F linux/coda.h conflict!
@@ -260,14 +258,11 @@ Code Seq#(hex) Include File Comments
't' 80-8F linux/isdn_ppp.h
't' 90 linux/toshiba.h
'u' 00-1F linux/smb_fs.h gone
-'v' all linux/videodev.h conflict!
'v' 00-1F linux/ext2_fs.h conflict!
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
-'v' C0-CF drivers/media/video/ov511.h conflict!
'v' C0-DF media/pwc-ioctl.h conflict!
'v' C0-FF linux/meye.h conflict!
-'v' C0-CF drivers/media/video/zoran/zoran.h conflict!
'v' D0-DF drivers/media/video/cpia2/cpia2dev.h conflict!
'w' all CERN SCI driver
'y' 00-1F packet based user level communications
@@ -278,7 +273,6 @@ Code Seq#(hex) Include File Comments
<mailto:oe@port.de>
'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
0x80 00-1F linux/fb.h
-0x88 00-3F media/ovcamchip.h
0x89 00-06 arch/x86/include/asm/sockios.h
0x89 0B-DF linux/sockios.h
0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range
diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt
index 1e5165aa9e4e..4a990317b84a 100644
--- a/Documentation/kbuild/kbuild.txt
+++ b/Documentation/kbuild/kbuild.txt
@@ -73,6 +73,14 @@ Specify the output directory when building the kernel.
The output directory can also be specified using "O=...".
Setting "O=..." takes precedence over KBUILD_OUTPUT.
+KBUILD_DEBARCH
+--------------------------------------------------
+For the deb-pkg target, allows overriding the normal heuristics deployed by
+deb-pkg. Normally deb-pkg attempts to guess the right architecture based on
+the UTS_MACHINE variable, and on some architectures also the kernel config.
+The value of KBUILD_DEBARCH is assumed (not checked) to be a valid Debian
+architecture.
+
ARCH
--------------------------------------------------
Set ARCH to the architecture to be built.
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 2fe93ca7c77c..b507d61fd41c 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -112,7 +112,6 @@ applicable everywhere (see syntax).
(no prompts anywhere) and for symbols with no dependencies.
That will limit the usefulness but on the other hand avoid
the illegal configurations all over.
- kconfig should one day warn about such things.
- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
This allows to limit the range of possible input values for int
@@ -268,7 +267,7 @@ separate list of options.
choices:
- "choice"
+ "choice" [symbol]
<choice options>
<choice block>
"endchoice"
@@ -282,6 +281,10 @@ single driver can be compiled/loaded into the kernel, but all drivers
can be compiled as modules.
A choice accepts another option "optional", which allows to set the
choice to 'n' and no entry needs to be selected.
+If no [symbol] is associated with a choice, then you can not have multiple
+definitions of that choice. If a [symbol] is associated to the choice,
+then you may define the same choice (ie. with the same entries) in another
+place.
comment:
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index 715eaaf1519d..9a8674629a07 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -537,7 +537,7 @@
Notes: Further information in
http://www.oreilly.com/catalog/linuxdrive2/
- * Title: "Linux Device Drivers, 3nd Edition"
+ * Title: "Linux Device Drivers, 3rd Edition"
Authors: Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman
Publisher: O'Reilly & Associates.
Date: 2005.
@@ -592,14 +592,6 @@
Pages: 600.
ISBN: 0-13-101908-2
- * Title: "The Design and Implementation of the 4.4 BSD UNIX
- Operating System"
- Author: Marshall Kirk McKusick, Keith Bostic, Michael J. Karels,
- John S. Quarterman.
- Publisher: Addison-Wesley.
- Date: 1996.
- ISBN: 0-201-54979-4
-
* Title: "Programming for the real world - POSIX.4"
Author: Bill O. Gallmeister.
Publisher: O'Reilly & Associates, Inc..
@@ -610,28 +602,13 @@
POSIX. Good reference.
* Title: "UNIX Systems for Modern Architectures: Symmetric
- Multiprocesssing and Caching for Kernel Programmers"
+ Multiprocessing and Caching for Kernel Programmers"
Author: Curt Schimmel.
Publisher: Addison Wesley.
Date: June, 1994.
Pages: 432.
ISBN: 0-201-63338-8
- * Title: "The Design and Implementation of the 4.3 BSD UNIX
- Operating System"
- Author: Samuel J. Leffler, Marshall Kirk McKusick, Michael J.
- Karels, John S. Quarterman.
- Publisher: Addison-Wesley.
- Date: 1989 (reprinted with corrections on October, 1990).
- ISBN: 0-201-06196-1
-
- * Title: "The Design of the UNIX Operating System"
- Author: Maurice J. Bach.
- Publisher: Prentice Hall.
- Date: 1986.
- Pages: 471.
- ISBN: 0-13-201757-1
-
MISCELLANEOUS:
* Name: linux/Documentation
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index cdd2a6e8a3b7..96288c1c909b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -403,6 +403,10 @@ and is between 256 and 4096 characters. It is defined in the file
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
+ bulk_remove=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for flushing multiple hpte entries
+ at a time.
+
c101= [NET] Moxa C101 synchronous serial card
cachesize= [BUGS=X86-32] Override level 2 CPU cache size detection.
@@ -1490,6 +1494,10 @@ and is between 256 and 4096 characters. It is defined in the file
mtdparts= [MTD]
See drivers/mtd/cmdlinepart.c.
+ multitce=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for updating multiple TCE entries
+ at a time.
+
onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration
Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
@@ -1707,6 +1715,9 @@ and is between 256 and 4096 characters. It is defined in the file
no-kvmclock [X86,KVM] Disable paravirtualized KVM clock driver
+ no-kvmapf [X86,KVM] Disable paravirtualized asynchronous page
+ fault handling.
+
nolapic [X86-32,APIC] Do not enable or use the local APIC.
nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
@@ -1759,7 +1770,7 @@ and is between 256 and 4096 characters. It is defined in the file
nousb [USB] Disable the USB subsystem
- nowatchdog [KNL] Disable the lockup detector.
+ nowatchdog [KNL] Disable the lockup detector (NMI watchdog).
nowb [ARM]
@@ -2175,11 +2186,6 @@ and is between 256 and 4096 characters. It is defined in the file
reset_devices [KNL] Force drivers to reset the underlying device
during initialization.
- resource_alloc_from_bottom
- Allocate new resources from the beginning of available
- space, not the end. If you need to use this, please
- report a bug.
-
resume= [SWSUSP]
Specify the partition device for software suspend
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index b336266bea5e..e1a92977833e 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -1085,6 +1085,184 @@ of 4 instructions that make up a hypercall.
If any additional field gets added to this structure later on, a bit for that
additional piece of information will be set in the flags bitmap.
+4.47 KVM_ASSIGN_PCI_DEVICE
+
+Capability: KVM_CAP_DEVICE_ASSIGNMENT
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_pci_dev (in)
+Returns: 0 on success, -1 on error
+
+Assigns a host PCI device to the VM.
+
+struct kvm_assigned_pci_dev {
+ __u32 assigned_dev_id;
+ __u32 busnr;
+ __u32 devfn;
+ __u32 flags;
+ __u32 segnr;
+ union {
+ __u32 reserved[11];
+ };
+};
+
+The PCI device is specified by the triple segnr, busnr, and devfn.
+Identification in succeeding service requests is done via assigned_dev_id. The
+following flags are specified:
+
+/* Depends on KVM_CAP_IOMMU */
+#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
+
+4.48 KVM_DEASSIGN_PCI_DEVICE
+
+Capability: KVM_CAP_DEVICE_DEASSIGNMENT
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_pci_dev (in)
+Returns: 0 on success, -1 on error
+
+Ends PCI device assignment, releasing all associated resources.
+
+See KVM_CAP_DEVICE_ASSIGNMENT for the data structure. Only assigned_dev_id is
+used in kvm_assigned_pci_dev to identify the device.
+
+4.49 KVM_ASSIGN_DEV_IRQ
+
+Capability: KVM_CAP_ASSIGN_DEV_IRQ
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_irq (in)
+Returns: 0 on success, -1 on error
+
+Assigns an IRQ to a passed-through device.
+
+struct kvm_assigned_irq {
+ __u32 assigned_dev_id;
+ __u32 host_irq;
+ __u32 guest_irq;
+ __u32 flags;
+ union {
+ struct {
+ __u32 addr_lo;
+ __u32 addr_hi;
+ __u32 data;
+ } guest_msi;
+ __u32 reserved[12];
+ };
+};
+
+The following flags are defined:
+
+#define KVM_DEV_IRQ_HOST_INTX (1 << 0)
+#define KVM_DEV_IRQ_HOST_MSI (1 << 1)
+#define KVM_DEV_IRQ_HOST_MSIX (1 << 2)
+
+#define KVM_DEV_IRQ_GUEST_INTX (1 << 8)
+#define KVM_DEV_IRQ_GUEST_MSI (1 << 9)
+#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10)
+
+It is not valid to specify multiple types per host or guest IRQ. However, the
+IRQ type of host and guest can differ or can even be null.
+
+4.50 KVM_DEASSIGN_DEV_IRQ
+
+Capability: KVM_CAP_ASSIGN_DEV_IRQ
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_irq (in)
+Returns: 0 on success, -1 on error
+
+Ends an IRQ assignment to a passed-through device.
+
+See KVM_ASSIGN_DEV_IRQ for the data structure. The target device is specified
+by assigned_dev_id, flags must correspond to the IRQ type specified on
+KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
+
+4.51 KVM_SET_GSI_ROUTING
+
+Capability: KVM_CAP_IRQ_ROUTING
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_irq_routing (in)
+Returns: 0 on success, -1 on error
+
+Sets the GSI routing table entries, overwriting any previously set entries.
+
+struct kvm_irq_routing {
+ __u32 nr;
+ __u32 flags;
+ struct kvm_irq_routing_entry entries[0];
+};
+
+No flags are specified so far, the corresponding field must be set to zero.
+
+struct kvm_irq_routing_entry {
+ __u32 gsi;
+ __u32 type;
+ __u32 flags;
+ __u32 pad;
+ union {
+ struct kvm_irq_routing_irqchip irqchip;
+ struct kvm_irq_routing_msi msi;
+ __u32 pad[8];
+ } u;
+};
+
+/* gsi routing entry types */
+#define KVM_IRQ_ROUTING_IRQCHIP 1
+#define KVM_IRQ_ROUTING_MSI 2
+
+No flags are specified so far, the corresponding field must be set to zero.
+
+struct kvm_irq_routing_irqchip {
+ __u32 irqchip;
+ __u32 pin;
+};
+
+struct kvm_irq_routing_msi {
+ __u32 address_lo;
+ __u32 address_hi;
+ __u32 data;
+ __u32 pad;
+};
+
+4.52 KVM_ASSIGN_SET_MSIX_NR
+
+Capability: KVM_CAP_DEVICE_MSIX
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_msix_nr (in)
+Returns: 0 on success, -1 on error
+
+Set the number of MSI-X interrupts for an assigned device. This service can
+only be called once in the lifetime of an assigned device.
+
+struct kvm_assigned_msix_nr {
+ __u32 assigned_dev_id;
+ __u16 entry_nr;
+ __u16 padding;
+};
+
+#define KVM_MAX_MSIX_PER_DEV 256
+
+4.53 KVM_ASSIGN_SET_MSIX_ENTRY
+
+Capability: KVM_CAP_DEVICE_MSIX
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_msix_entry (in)
+Returns: 0 on success, -1 on error
+
+Specifies the routing of an MSI-X assigned device interrupt to a GSI. Setting
+the GSI vector to zero means disabling the interrupt.
+
+struct kvm_assigned_msix_entry {
+ __u32 assigned_dev_id;
+ __u32 gsi;
+ __u16 entry; /* The index of entry in the MSI-X table */
+ __u16 padding[3];
+};
+
5. The kvm_run structure
Application code obtains a pointer to the kvm_run structure by
diff --git a/Documentation/kvm/cpuid.txt b/Documentation/kvm/cpuid.txt
index 14a12ea92b7f..882068538c9c 100644
--- a/Documentation/kvm/cpuid.txt
+++ b/Documentation/kvm/cpuid.txt
@@ -36,6 +36,9 @@ KVM_FEATURE_MMU_OP || 2 || deprecated.
KVM_FEATURE_CLOCKSOURCE2 || 3 || kvmclock available at msrs
|| || 0x4b564d00 and 0x4b564d01
------------------------------------------------------------------------------
+KVM_FEATURE_ASYNC_PF || 4 || async pf can be enabled by
+ || || writing to msr 0x4b564d02
+------------------------------------------------------------------------------
KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side
|| || per-cpu warps are expected in
|| || kvmclock.
diff --git a/Documentation/kvm/msr.txt b/Documentation/kvm/msr.txt
index 8ddcfe84c09a..d079aed27e03 100644
--- a/Documentation/kvm/msr.txt
+++ b/Documentation/kvm/msr.txt
@@ -3,7 +3,6 @@ Glauber Costa <glommer@redhat.com>, Red Hat Inc, 2010
=====================================================
KVM makes use of some custom MSRs to service some requests.
-At present, this facility is only used by kvmclock.
Custom MSRs have a range reserved for them, that goes from
0x4b564d00 to 0x4b564dff. There are MSRs outside this area,
@@ -151,3 +150,38 @@ MSR_KVM_SYSTEM_TIME: 0x12
return PRESENT;
} else
return NON_PRESENT;
+
+MSR_KVM_ASYNC_PF_EN: 0x4b564d02
+ data: Bits 63-6 hold 64-byte aligned physical address of a
+ 64 byte memory area which must be in guest RAM and must be
+ zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1
+ when asynchronous page faults are enabled on the vcpu 0 when
+ disabled. Bit 2 is 1 if asynchronous page faults can be injected
+ when vcpu is in cpl == 0.
+
+ First 4 byte of 64 byte memory location will be written to by
+ the hypervisor at the time of asynchronous page fault (APF)
+ injection to indicate type of asynchronous page fault. Value
+ of 1 means that the page referred to by the page fault is not
+ present. Value 2 means that the page is now available. Disabling
+ interrupt inhibits APFs. Guest must not enable interrupt
+ before the reason is read, or it may be overwritten by another
+ APF. Since APF uses the same exception vector as regular page
+ fault guest must reset the reason to 0 before it does
+ something that can generate normal page fault. If during page
+ fault APF reason is 0 it means that this is regular page
+ fault.
+
+ During delivery of type 1 APF cr2 contains a token that will
+ be used to notify a guest when missing page becomes
+ available. When page becomes available type 2 APF is sent with
+ cr2 set to the token associated with the page. There is special
+ kind of token 0xffffffff which tells vcpu that it should wake
+ up all processes waiting for APFs and no individual type 2 APFs
+ will be sent.
+
+ If APF is disabled while there are outstanding APFs, they will
+ not be delivered.
+
+ Currently type 2 APF will be always delivered on the same vcpu as
+ type 1 was, but guest should not rely on that.
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index dc73bc54cc4e..d9da7e148538 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -39,6 +39,9 @@
#include <limits.h>
#include <stddef.h>
#include <signal.h>
+#include <pwd.h>
+#include <grp.h>
+
#include <linux/virtio_config.h>
#include <linux/virtio_net.h>
#include <linux/virtio_blk.h>
@@ -298,20 +301,27 @@ static void *map_zeroed_pages(unsigned int num)
/*
* We use a private mapping (ie. if we write to the page, it will be
- * copied).
+ * copied). We allocate an extra two pages PROT_NONE to act as guard
+ * pages against read/write attempts that exceed allocated space.
*/
- addr = mmap(NULL, getpagesize() * num,
- PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
+ addr = mmap(NULL, getpagesize() * (num+2),
+ PROT_NONE, MAP_PRIVATE, fd, 0);
+
if (addr == MAP_FAILED)
err(1, "Mmapping %u pages of /dev/zero", num);
+ if (mprotect(addr + getpagesize(), getpagesize() * num,
+ PROT_READ|PROT_WRITE) == -1)
+ err(1, "mprotect rw %u pages failed", num);
+
/*
* One neat mmap feature is that you can close the fd, and it
* stays mapped.
*/
close(fd);
- return addr;
+ /* Return address after PROT_NONE page */
+ return addr + getpagesize();
}
/* Get some more pages for a device. */
@@ -343,7 +353,7 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
* done to it. This allows us to share untouched memory between
* Guests.
*/
- if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC,
+ if (mmap(addr, len, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
return;
@@ -573,10 +583,10 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
unsigned int line)
{
/*
- * We have to separately check addr and addr+size, because size could
- * be huge and addr + size might wrap around.
+ * Check if the requested address and size exceeds the allocated memory,
+ * or addr + size wraps around.
*/
- if (addr >= guest_limit || addr + size >= guest_limit)
+ if ((addr + size) > guest_limit || (addr + size) < addr)
errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
/*
* We return a pointer for the caller's convenience, now we know it's
@@ -1872,6 +1882,8 @@ static struct option opts[] = {
{ "block", 1, NULL, 'b' },
{ "rng", 0, NULL, 'r' },
{ "initrd", 1, NULL, 'i' },
+ { "username", 1, NULL, 'u' },
+ { "chroot", 1, NULL, 'c' },
{ NULL },
};
static void usage(void)
@@ -1894,6 +1906,12 @@ int main(int argc, char *argv[])
/* If they specify an initrd file to load. */
const char *initrd_name = NULL;
+ /* Password structure for initgroups/setres[gu]id */
+ struct passwd *user_details = NULL;
+
+ /* Directory to chroot to */
+ char *chroot_path = NULL;
+
/* Save the args: we "reboot" by execing ourselves again. */
main_args = argv;
@@ -1950,6 +1968,14 @@ int main(int argc, char *argv[])
case 'i':
initrd_name = optarg;
break;
+ case 'u':
+ user_details = getpwnam(optarg);
+ if (!user_details)
+ err(1, "getpwnam failed, incorrect username?");
+ break;
+ case 'c':
+ chroot_path = optarg;
+ break;
default:
warnx("Unknown argument %s", argv[optind]);
usage();
@@ -2021,6 +2047,37 @@ int main(int argc, char *argv[])
/* If we exit via err(), this kills all the threads, restores tty. */
atexit(cleanup_devices);
+ /* If requested, chroot to a directory */
+ if (chroot_path) {
+ if (chroot(chroot_path) != 0)
+ err(1, "chroot(\"%s\") failed", chroot_path);
+
+ if (chdir("/") != 0)
+ err(1, "chdir(\"/\") failed");
+
+ verbose("chroot done\n");
+ }
+
+ /* If requested, drop privileges */
+ if (user_details) {
+ uid_t u;
+ gid_t g;
+
+ u = user_details->pw_uid;
+ g = user_details->pw_gid;
+
+ if (initgroups(user_details->pw_name, g) != 0)
+ err(1, "initgroups failed");
+
+ if (setresgid(g, g, g) != 0)
+ err(1, "setresgid failed");
+
+ if (setresuid(u, u, u) != 0)
+ err(1, "setresuid failed");
+
+ verbose("Dropping privileges completed\n");
+ }
+
/* Finally, run the Guest. This doesn't return. */
run_guest();
}
diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt
index efb3a6a045a2..ed5fdbe90ccb 100644
--- a/Documentation/lguest/lguest.txt
+++ b/Documentation/lguest/lguest.txt
@@ -114,6 +114,11 @@ Running Lguest:
See http://linux-net.osdl.org/index.php/Bridge for general information
on how to get bridging working.
+- Random number generation. Using the --rng option will provide a
+ /dev/hwrng in the guest that will read from the host's /dev/random.
+ Use this option in conjunction with rng-tools (see ../hw_random.txt)
+ to provide entropy to the guest kernel's /dev/random.
+
There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
Good luck!
diff --git a/Documentation/make/headers_install.txt b/Documentation/make/headers_install.txt
index f2481cabffcb..951eb9f1e040 100644
--- a/Documentation/make/headers_install.txt
+++ b/Documentation/make/headers_install.txt
@@ -39,8 +39,9 @@ INSTALL_HDR_PATH indicates where to install the headers. It defaults to
The command "make headers_install_all" exports headers for all architectures
simultaneously. (This is mostly of interest to distribution maintainers,
who create an architecture-independent tarball from the resulting include
-directory.) Remember to provide the appropriate linux/asm directory via "mv"
-or "ln -s" before building a C library with headers exported this way.
+directory.) You also can use HDR_ARCH_LIST to specify list of architectures.
+Remember to provide the appropriate linux/asm directory via "mv" or "ln -s"
+before building a C library with headers exported this way.
The kernel header export infrastructure is maintained by David Woodhouse
<dwmw2@infradead.org>.
diff --git a/Documentation/networking/LICENSE.qlcnic b/Documentation/networking/LICENSE.qlcnic
new file mode 100644
index 000000000000..29ad4b106420
--- /dev/null
+++ b/Documentation/networking/LICENSE.qlcnic
@@ -0,0 +1,327 @@
+Copyright (c) 2009-2010 QLogic Corporation
+QLogic Linux qlcnic NIC Driver
+
+This program includes a device driver for Linux 2.6 that may be
+distributed with QLogic hardware specific firmware binary file.
+You may modify and redistribute the device driver code under the
+GNU General Public License (a copy of which is attached hereto as
+Exhibit A) published by the Free Software Foundation (version 2).
+
+You may redistribute the hardware specific firmware binary file
+under the following terms:
+
+ 1. Redistribution of source code (only if applicable),
+ must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistribution 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. The name of QLogic Corporation may not be used to
+ endorse or promote products derived from this software
+ without specific prior written permission
+
+REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
+THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
+CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
+OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
+TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
+ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
+COMBINATION WITH THIS PROGRAM.
+
+
+EXHIBIT A
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
new file mode 100644
index 000000000000..77f0cdd5b0dd
--- /dev/null
+++ b/Documentation/networking/batman-adv.txt
@@ -0,0 +1,240 @@
+[state: 21-11-2010]
+
+BATMAN-ADV
+----------
+
+Batman advanced is a new approach to wireless networking which
+does no longer operate on the IP basis. Unlike the batman daemon,
+which exchanges information using UDP packets and sets routing
+tables, batman-advanced operates on ISO/OSI Layer 2 only and uses
+and routes (or better: bridges) Ethernet Frames. It emulates a
+virtual network switch of all nodes participating. Therefore all
+nodes appear to be link local, thus all higher operating proto-
+cols won't be affected by any changes within the network. You can
+run almost any protocol above batman advanced, prominent examples
+are: IPv4, IPv6, DHCP, IPX.
+
+Batman advanced was implemented as a Linux kernel driver to re-
+duce the overhead to a minimum. It does not depend on any (other)
+network driver, and can be used on wifi as well as ethernet lan,
+vpn, etc ... (anything with ethernet-style layer 2).
+
+CONFIGURATION
+-------------
+
+Load the batman-adv module into your kernel:
+
+# insmod batman-adv.ko
+
+The module is now waiting for activation. You must add some in-
+terfaces on which batman can operate. After loading the module
+batman advanced will scan your systems interfaces to search for
+compatible interfaces. Once found, it will create subfolders in
+the /sys directories of each supported interface, e.g.
+
+# ls /sys/class/net/eth0/batman_adv/
+# iface_status mesh_iface
+
+If an interface does not have the "batman_adv" subfolder it prob-
+ably is not supported. Not supported interfaces are: loopback,
+non-ethernet and batman's own interfaces.
+
+Note: After the module was loaded it will continuously watch for
+new interfaces to verify the compatibility. There is no need to
+reload the module if you plug your USB wifi adapter into your ma-
+chine after batman advanced was initially loaded.
+
+To activate a given interface simply write "bat0" into its
+"mesh_iface" file inside the batman_adv subfolder:
+
+# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface
+
+Repeat this step for all interfaces you wish to add. Now batman
+starts using/broadcasting on this/these interface(s).
+
+By reading the "iface_status" file you can check its status:
+
+# cat /sys/class/net/eth0/batman_adv/iface_status
+# active
+
+To deactivate an interface you have to write "none" into its
+"mesh_iface" file:
+
+# echo none > /sys/class/net/eth0/batman_adv/mesh_iface
+
+
+All mesh wide settings can be found in batman's own interface
+folder:
+
+# ls /sys/class/net/bat0/mesh/
+# aggregated_ogms bonding fragmentation orig_interval
+# vis_mode
+
+
+There is a special folder for debugging informations:
+
+# ls /sys/kernel/debug/batman_adv/bat0/
+# originators socket transtable_global transtable_local
+# vis_data
+
+
+Some of the files contain all sort of status information regard-
+ing the mesh network. For example, you can view the table of
+originators (mesh participants) with:
+
+# cat /sys/kernel/debug/batman_adv/bat0/originators
+
+Other files allow to change batman's behaviour to better fit your
+requirements. For instance, you can check the current originator
+interval (value in milliseconds which determines how often batman
+sends its broadcast packets):
+
+# cat /sys/class/net/bat0/mesh/orig_interval
+# 1000
+
+and also change its value:
+
+# echo 3000 > /sys/class/net/bat0/mesh/orig_interval
+
+In very mobile scenarios, you might want to adjust the originator
+interval to a lower value. This will make the mesh more respon-
+sive to topology changes, but will also increase the overhead.
+
+
+USAGE
+-----
+
+To make use of your newly created mesh, batman advanced provides
+a new interface "bat0" which you should use from this point on.
+All interfaces added to batman advanced are not relevant any
+longer because batman handles them for you. Basically, one "hands
+over" the data by using the batman interface and batman will make
+sure it reaches its destination.
+
+The "bat0" interface can be used like any other regular inter-
+face. It needs an IP address which can be either statically con-
+figured or dynamically (by using DHCP or similar services):
+
+# NodeA: ifconfig bat0 192.168.0.1
+# NodeB: ifconfig bat0 192.168.0.2
+# NodeB: ping 192.168.0.1
+
+Note: In order to avoid problems remove all IP addresses previ-
+ously assigned to interfaces now used by batman advanced, e.g.
+
+# ifconfig eth0 0.0.0.0
+
+
+VISUALIZATION
+-------------
+
+If you want topology visualization, at least one mesh node must
+be configured as VIS-server:
+
+# echo "server" > /sys/class/net/bat0/mesh/vis_mode
+
+Each node is either configured as "server" or as "client" (de-
+fault: "client"). Clients send their topology data to the server
+next to them, and server synchronize with other servers. If there
+is no server configured (default) within the mesh, no topology
+information will be transmitted. With these "synchronizing
+servers", there can be 1 or more vis servers sharing the same (or
+at least very similar) data.
+
+When configured as server, you can get a topology snapshot of
+your mesh:
+
+# cat /sys/kernel/debug/batman_adv/bat0/vis_data
+
+This raw output is intended to be easily parsable and convertable
+with other tools. Have a look at the batctl README if you want a
+vis output in dot or json format for instance and how those out-
+puts could then be visualised in an image.
+
+The raw format consists of comma separated values per entry where
+each entry is giving information about a certain source inter-
+face. Each entry can/has to have the following values:
+-> "mac" - mac address of an originator's source interface
+ (each line begins with it)
+-> "TQ mac value" - src mac's link quality towards mac address
+ of a neighbor originator's interface which
+ is being used for routing
+-> "HNA mac" - HNA announced by source mac
+-> "PRIMARY" - this is a primary interface
+-> "SEC mac" - secondary mac address of source
+ (requires preceding PRIMARY)
+
+The TQ value has a range from 4 to 255 with 255 being the best.
+The HNA entries are showing which hosts are connected to the mesh
+via bat0 or being bridged into the mesh network. The PRIMARY/SEC
+values are only applied on primary 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 com-
+mands: 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 some-
+times necessary to see more detail debug messages. This must be
+enabled when compiling the batman-adv module. When building bat-
+man-adv as part of kernel, use "make menuconfig" and enable the
+option "B.A.T.M.A.N. debugging".
+
+Those additional debug messages can be accessed using a special
+file in debugfs
+
+# cat /sys/kernel/debug/batman_adv/bat0/log
+
+The additional debug output is by default disabled. It can be en-
+abled during run time. Following log_levels are defined:
+
+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
+
+The debug output can be changed at runtime using the file
+/sys/class/net/bat0/mesh/log_level. e.g.
+
+# echo 2 > /sys/class/net/bat0/mesh/log_level
+
+will enable debug messages for when routes or HNAs change.
+
+
+BATCTL
+------
+
+As batman advanced operates on layer 2 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).
+
+batctl is available on http://www.open-mesh.org/
+
+
+CONTACT
+-------
+
+Please send us comments, experiences, questions, anything :)
+
+IRC: #batman on irc.freenode.org
+Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org
+ (optional subscription at
+ https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
+
+You can also contact the Authors:
+
+Marek Lindner <lindner_marek@yahoo.de>
+Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
index 271d524a4c8d..b395ca6a49f2 100644
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -47,6 +47,26 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree
Socket options
==============
+DCCP_SOCKOPT_QPOLICY_ID sets the dequeuing policy for outgoing packets. It takes
+a policy ID as argument and can only be set before the connection (i.e. changes
+during an established connection are not supported). Currently, two policies are
+defined: the "simple" policy (DCCPQ_POLICY_SIMPLE), which does nothing special,
+and a priority-based variant (DCCPQ_POLICY_PRIO). The latter allows to pass an
+u32 priority value as ancillary data to sendmsg(), where higher numbers indicate
+a higher packet priority (similar to SO_PRIORITY). This ancillary data needs to
+be formatted using a cmsg(3) message header filled in as follows:
+ cmsg->cmsg_level = SOL_DCCP;
+ cmsg->cmsg_type = DCCP_SCM_PRIORITY;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); /* or CMSG_LEN(4) */
+
+DCCP_SOCKOPT_QPOLICY_TXQLEN sets the maximum length of the output queue. A zero
+value is always interpreted as unbounded queue length. If different from zero,
+the interpretation of this parameter depends on the current dequeuing policy
+(see above): the "simple" policy will enforce a fixed queue size by returning
+EAGAIN, whereas the "prio" policy enforces a fixed queue length by dropping the
+lowest-priority packet first. The default value for this parameter is
+initialised from /proc/sys/net/dccp/default/tx_qlen.
+
DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
the socket will fall back to 0 (which means that no meaningful service code
diff --git a/Documentation/networking/e100.txt b/Documentation/networking/e100.txt
index 944aa55e79f8..162f323a7a1f 100644
--- a/Documentation/networking/e100.txt
+++ b/Documentation/networking/e100.txt
@@ -72,7 +72,7 @@ Tx Descriptors: Number of transmit descriptors. A transmit descriptor is a data
ethtool -G eth? tx n, where n is the number of desired tx descriptors.
Speed/Duplex: The driver auto-negotiates the link speed and duplex settings by
- default. Ethtool can be used as follows to force speed/duplex.
+ default. The ethtool utility can be used as follows to force speed/duplex.
ethtool -s eth? autoneg off speed {10|100} duplex {full|half}
@@ -126,30 +126,21 @@ Additional Configurations
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information. Ethtool
+ diagnostics, as well as displaying statistical information. The ethtool
version 1.6 or later is required for this functionality.
The latest release of ethtool can be found from
- http://sourceforge.net/projects/gkernel.
-
- NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support
- for a more complete ethtool feature set can be enabled by upgrading
- ethtool to ethtool-1.8.1.
-
+ http://ftp.kernel.org/pub/software/network/ethtool/
Enabling Wake on LAN* (WoL)
---------------------------
- WoL is provided through the Ethtool* utility. Ethtool is included with Red
- Hat* 8.0. For other Linux distributions, download and install Ethtool from
- the following website: http://sourceforge.net/projects/gkernel.
-
- For instructions on enabling WoL with Ethtool, refer to the Ethtool man page.
+ WoL is provided through the ethtool* utility. For instructions on enabling
+ WoL with ethtool, refer to the ethtool man page.
WoL will be enabled on the system during the next shut down or reboot. For
this driver version, in order to enable WoL, the e100 driver must be
loaded when shutting down or rebooting the system.
-
NAPI
----
diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
index d9271e74e488..71ca95855671 100644
--- a/Documentation/networking/e1000.txt
+++ b/Documentation/networking/e1000.txt
@@ -79,7 +79,7 @@ InterruptThrottleRate
---------------------
(not supported on Intel(R) 82542, 82543 or 82544-based adapters)
Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative,
- 4=simplified balancing)
+ 4=simplified balancing)
Default Value: 3
The driver can limit the amount of interrupts per second that the adapter
@@ -124,8 +124,8 @@ InterruptThrottleRate is set to mode 1. In this mode, which operates
the same as mode 3, the InterruptThrottleRate will be increased stepwise to
70000 for traffic in class "Lowest latency".
-In simplified mode the interrupt rate is based on the ratio of Tx and
-Rx traffic. If the bytes per second rate is approximately equal, the
+In simplified mode the interrupt rate is based on the ratio of TX and
+RX traffic. If the bytes per second rate is approximately equal, the
interrupt rate will drop as low as 2000 interrupts per second. If the
traffic is mostly transmit or mostly receive, the interrupt rate could
be as high as 8000.
@@ -245,7 +245,7 @@ NOTE: Depending on the available system resources, the request for a
TxDescriptorStep
----------------
Valid Range: 1 (use every Tx Descriptor)
- 4 (use every 4th Tx Descriptor)
+ 4 (use every 4th Tx Descriptor)
Default Value: 1 (use every Tx Descriptor)
@@ -312,7 +312,7 @@ Valid Range: 0-xxxxxxx (0=off)
Default Value: 256
Usage: insmod e1000.ko copybreak=128
-Driver copies all packets below or equaling this size to a fresh Rx
+Driver copies all packets below or equaling this size to a fresh RX
buffer before handing it up the stack.
This parameter is different than other parameters, in that it is a
@@ -431,15 +431,15 @@ Additional Configurations
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information. Ethtool
+ diagnostics, as well as displaying statistical information. The ethtool
version 1.6 or later is required for this functionality.
The latest release of ethtool can be found from
- http://sourceforge.net/projects/gkernel.
+ http://ftp.kernel.org/pub/software/network/ethtool/
Enabling Wake on LAN* (WoL)
---------------------------
- WoL is configured through the Ethtool* utility.
+ WoL is configured through the ethtool* utility.
WoL will be enabled on the system during the next shut down or reboot.
For this driver version, in order to enable WoL, the e1000 driver must be
diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt
index 6aa048badf32..97b5ba942ebf 100644
--- a/Documentation/networking/e1000e.txt
+++ b/Documentation/networking/e1000e.txt
@@ -1,5 +1,5 @@
Linux* Driver for Intel(R) Network Connection
-===============================================================
+=============================================
Intel Gigabit Linux driver.
Copyright(c) 1999 - 2010 Intel Corporation.
@@ -61,6 +61,12 @@ per second, even if more packets have come in. This reduces interrupt
load on the system and can lower CPU utilization under heavy load,
but will increase latency as packets are not processed as quickly.
+The default behaviour of the driver previously assumed a static
+InterruptThrottleRate value of 8000, providing a good fallback value for
+all traffic types, but lacking in small packet performance and latency.
+The hardware can handle many more small packets per second however, and
+for this reason an adaptive interrupt moderation algorithm was implemented.
+
The driver has two adaptive modes (setting 1 or 3) in which
it dynamically adjusts the InterruptThrottleRate value based on the traffic
that it receives. After determining the type of incoming traffic in the last
@@ -86,8 +92,8 @@ InterruptThrottleRate is set to mode 1. In this mode, which operates
the same as mode 3, the InterruptThrottleRate will be increased stepwise to
70000 for traffic in class "Lowest latency".
-In simplified mode the interrupt rate is based on the ratio of Tx and
-Rx traffic. If the bytes per second rate is approximately equal the
+In simplified mode the interrupt rate is based on the ratio of TX and
+RX traffic. If the bytes per second rate is approximately equal, the
interrupt rate will drop as low as 2000 interrupts per second. If the
traffic is mostly transmit or mostly receive, the interrupt rate could
be as high as 8000.
@@ -177,7 +183,7 @@ Copybreak
Valid Range: 0-xxxxxxx (0=off)
Default Value: 256
-Driver copies all packets below or equaling this size to a fresh Rx
+Driver copies all packets below or equaling this size to a fresh RX
buffer before handing it up the stack.
This parameter is different than other parameters, in that it is a
@@ -223,17 +229,17 @@ loading or enabling the driver, try disabling this feature.
WriteProtectNVM
---------------
-Valid Range: 0-1
-Default Value: 1 (enabled)
-
-Set the hardware to ignore all write/erase cycles to the GbE region in the
-ICHx NVM (non-volatile memory). This feature can be disabled by the
-WriteProtectNVM module parameter (enabled by default) only after a hardware
-reset, but the machine must be power cycled before trying to enable writes.
-
-Note: the kernel boot option iomem=relaxed may need to be set if the kernel
-config option CONFIG_STRICT_DEVMEM=y, if the root user wants to write the
-NVM from user space via ethtool.
+Valid Range: 0,1
+Default Value: 1
+
+If set to 1, configure the hardware to ignore all write/erase cycles to the
+GbE region in the ICHx NVM (in order to prevent accidental corruption of the
+NVM). This feature can be disabled by setting the parameter to 0 during initial
+driver load.
+NOTE: The machine must be power cycled (full off/on) when enabling NVM writes
+via setting the parameter to zero. Once the NVM has been locked (via the
+parameter at 1 when the driver loads) it cannot be unlocked except via power
+cycle.
Additional Configurations
=========================
@@ -259,32 +265,30 @@ Additional Configurations
- Some adapters limit Jumbo Frames sized packets to a maximum of
4096 bytes and some adapters do not support Jumbo Frames.
-
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
diagnostics, as well as displaying statistical information. We
- strongly recommend downloading the latest version of Ethtool at:
+ strongly recommend downloading the latest version of ethtool at:
- http://sourceforge.net/projects/gkernel.
+ http://ftp.kernel.org/pub/software/network/ethtool/
Speed and Duplex
----------------
- Speed and Duplex are configured through the Ethtool* utility. For
- instructions, refer to the Ethtool man page.
+ Speed and Duplex are configured through the ethtool* utility. For
+ instructions, refer to the ethtool man page.
Enabling Wake on LAN* (WoL)
---------------------------
- WoL is configured through the Ethtool* utility. For instructions on
- enabling WoL with Ethtool, refer to the Ethtool man page.
+ WoL is configured through the ethtool* utility. For instructions on
+ enabling WoL with ethtool, refer to the ethtool man page.
WoL will be enabled on the system during the next shut down or reboot.
For this driver version, in order to enable WoL, the e1000e driver must be
loaded when shutting down or rebooting the system.
In most cases Wake On LAN is only supported on port A for multiple port
- adapters. To verify if a port supports Wake on LAN run ethtool eth<X>.
-
+ adapters. To verify if a port supports Wake on Lan run ethtool eth<X>.
Support
=======
diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt
index ab2d71831892..98953c0d5342 100644
--- a/Documentation/networking/igb.txt
+++ b/Documentation/networking/igb.txt
@@ -36,6 +36,7 @@ Default Value: 0
This parameter adds support for SR-IOV. It causes the driver to spawn up to
max_vfs worth of virtual function.
+
Additional Configurations
=========================
@@ -60,15 +61,16 @@ Additional Configurations
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information.
+ diagnostics, as well as displaying statistical information. The latest
+ version of ethtool can be found at:
- http://sourceforge.net/projects/gkernel.
+ http://ftp.kernel.org/pub/software/network/ethtool/
Enabling Wake on LAN* (WoL)
---------------------------
- WoL is configured through the Ethtool* utility.
+ WoL is configured through the ethtool* utility.
- For instructions on enabling WoL with Ethtool, refer to the Ethtool man page.
+ For instructions on enabling WoL with ethtool, refer to the ethtool man page.
WoL will be enabled on the system during the next shut down or reboot.
For this driver version, in order to enable WoL, the igb driver must be
@@ -91,31 +93,6 @@ Additional Configurations
REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not
found, the system will fallback to MSI or to Legacy interrupts.
- LRO
- ---
- Large Receive Offload (LRO) is a technique for increasing inbound throughput
- of high-bandwidth network connections by reducing CPU overhead. It works by
- aggregating multiple incoming packets from a single stream into a larger
- buffer before they are passed higher up the networking stack, thus reducing
- the number of packets that have to be processed. LRO combines multiple
- Ethernet frames into a single receive in the stack, thereby potentially
- decreasing CPU utilization for receives.
-
- NOTE: You need to have inet_lro enabled via either the CONFIG_INET_LRO or
- CONFIG_INET_LRO_MODULE kernel config option. Additionally, if
- CONFIG_INET_LRO_MODULE is used, the inet_lro module needs to be loaded
- before the igb driver.
-
- You can verify that the driver is using LRO by looking at these counters in
- Ethtool:
-
- lro_aggregated - count of total packets that were combined
- lro_flushed - counts the number of packets flushed out of LRO
- lro_no_desc - counts the number of times an LRO descriptor was not available
- for the LRO packet
-
- NOTE: IPv6 and UDP are not supported by LRO.
-
Support
=======
diff --git a/Documentation/networking/igbvf.txt b/Documentation/networking/igbvf.txt
index 056028138d9c..cbfe4ee65533 100644
--- a/Documentation/networking/igbvf.txt
+++ b/Documentation/networking/igbvf.txt
@@ -58,9 +58,11 @@ Additional Configurations
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information.
+ diagnostics, as well as displaying statistical information. The ethtool
+ version 3.0 or later is required for this functionality, although we
+ strongly recommend downloading the latest version at:
- http://sourceforge.net/projects/gkernel.
+ http://ftp.kernel.org/pub/software/network/ethtool/
Support
=======
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 3c5e465296e1..d99940dcfc44 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -11,7 +11,9 @@ ip_forward - BOOLEAN
for routers)
ip_default_ttl - INTEGER
- default 64
+ Default value of TTL field (Time To Live) for outgoing (but not
+ forwarded) IP packets. Should be between 1 and 255 inclusive.
+ Default: 64 (as recommended by RFC1700)
ip_no_pmtu_disc - BOOLEAN
Disable Path MTU Discovery.
@@ -708,10 +710,28 @@ igmp_max_memberships - INTEGER
Change the maximum number of multicast groups we can subscribe to.
Default: 20
-conf/interface/* changes special settings per interface (where "interface" is
- the name of your network interface)
-conf/all/* is special, changes the settings for all interfaces
+ Theoretical maximum value is bounded by having to send a membership
+ report in a single datagram (i.e. the report can't span multiple
+ datagrams, or risk confusing the switch and leaving groups you don't
+ intend to).
+ The number of supported groups 'M' is bounded by the number of group
+ report entries you can fit into a single datagram of 65535 bytes.
+
+ M = 65536-sizeof (ip header)/(sizeof(Group record))
+
+ Group records are variable length, with a minimum of 12 bytes.
+ So net.ipv4.igmp_max_memberships should not be set higher than:
+
+ (65536-24) / 12 = 5459
+
+ The value 5459 assumes no IP header options, so in practice
+ this number may be lower.
+
+ conf/interface/* changes special settings per interface (where
+ "interface" is the name of your network interface)
+
+ conf/all/* is special, changes the settings for all interfaces
log_martians - BOOLEAN
Log packets with impossible addresses to kernel log.
diff --git a/Documentation/networking/ixgb.txt b/Documentation/networking/ixgb.txt
index a0d0ffb5e584..e196f16df313 100644
--- a/Documentation/networking/ixgb.txt
+++ b/Documentation/networking/ixgb.txt
@@ -309,15 +309,15 @@ Additional Configurations
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information. Ethtool
+ diagnostics, as well as displaying statistical information. The ethtool
version 1.6 or later is required for this functionality.
The latest release of ethtool can be found from
- http://sourceforge.net/projects/gkernel
+ http://ftp.kernel.org/pub/software/network/ethtool/
- NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support
- for a more complete ethtool feature set can be enabled by upgrading
- to the latest version.
+ NOTE: The ethtool version 1.6 only supports a limited set of ethtool options.
+ Support for a more complete ethtool feature set can be enabled by
+ upgrading to the latest version.
NAPI
diff --git a/Documentation/networking/ixgbe.txt b/Documentation/networking/ixgbe.txt
index eeb68685c788..af77ed3c4172 100644
--- a/Documentation/networking/ixgbe.txt
+++ b/Documentation/networking/ixgbe.txt
@@ -1,107 +1,126 @@
Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection
========================================================================
-March 10, 2009
-
+Intel Gigabit Linux driver.
+Copyright(c) 1999 - 2010 Intel Corporation.
Contents
========
-- In This Release
- Identifying Your Adapter
-- Building and Installation
- Additional Configurations
+- Performance Tuning
+- Known Issues
- Support
+Identifying Your Adapter
+========================
+The driver in this release is compatible with 82598 and 82599-based Intel
+Network Connections.
-In This Release
-===============
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
-This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI
-Express Intel(R) Network Connection. This driver includes support for
-Itanium(R)2-based systems.
+ http://support.intel.com/support/network/sb/CS-012904.htm
-For questions related to hardware requirements, refer to the documentation
-supplied with your 10 Gigabit adapter. All hardware requirements listed apply
-to use with Linux.
+SFP+ Devices with Pluggable Optics
+----------------------------------
-The following features are available in this kernel:
- - Native VLANs
- - Channel Bonding (teaming)
- - SNMP
- - Generic Receive Offload
- - Data Center Bridging
+82599-BASED ADAPTERS
-Channel Bonding documentation can be found in the Linux kernel source:
-/Documentation/networking/bonding.txt
+NOTES: If your 82599-based Intel(R) Network Adapter came with Intel optics, or
+is an Intel(R) Ethernet Server Adapter X520-2, then it only supports Intel
+optics and/or the direct attach cables listed below.
-Ethtool, lspci, and ifconfig can be used to display device and driver
-specific information.
+When 82599-based SFP+ devices are connected back to back, they should be set to
+the same Speed setting via ethtool. Results may vary if you mix speed settings.
+82598-based adapters support all passive direct attach cables that comply
+with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach
+cables are not supported.
+Supplier Type Part Numbers
-Identifying Your Adapter
-========================
+SR Modules
+Intel DUAL RATE 1G/10G SFP+ SR (bailed) FTLX8571D3BCV-IT
+Intel DUAL RATE 1G/10G SFP+ SR (bailed) AFBR-703SDDZ-IN1
+Intel DUAL RATE 1G/10G SFP+ SR (bailed) AFBR-703SDZ-IN2
+LR Modules
+Intel DUAL RATE 1G/10G SFP+ LR (bailed) FTLX1471D3BCV-IT
+Intel DUAL RATE 1G/10G SFP+ LR (bailed) AFCT-701SDDZ-IN1
+Intel DUAL RATE 1G/10G SFP+ LR (bailed) AFCT-701SDZ-IN2
-This driver supports devices based on the 82598 controller and the 82599
-controller.
+The following is a list of 3rd party SFP+ modules and direct attach cables that
+have received some testing. Not all modules are applicable to all devices.
-For specific information on identifying which adapter you have, please visit:
+Supplier Type Part Numbers
- http://support.intel.com/support/network/sb/CS-008441.htm
+Finisar SFP+ SR bailed, 10g single rate FTLX8571D3BCL
+Avago SFP+ SR bailed, 10g single rate AFBR-700SDZ
+Finisar SFP+ LR bailed, 10g single rate FTLX1471D3BCL
+Finisar DUAL RATE 1G/10G SFP+ SR (No Bail) FTLX8571D3QCV-IT
+Avago DUAL RATE 1G/10G SFP+ SR (No Bail) AFBR-703SDZ-IN1
+Finisar DUAL RATE 1G/10G SFP+ LR (No Bail) FTLX1471D3QCV-IT
+Avago DUAL RATE 1G/10G SFP+ LR (No Bail) AFCT-701SDZ-IN1
+Finistar 1000BASE-T SFP FCLF8522P2BTL
+Avago 1000BASE-T SFP ABCU-5710RZ
-Building and Installation
-=========================
+82599-based adapters support all passive and active limiting direct attach
+cables that comply with SFF-8431 v4.1 and SFF-8472 v10.4 specifications.
-select m for "Intel(R) 10GbE PCI Express adapters support" located at:
- Location:
- -> Device Drivers
- -> Network device support (NETDEVICES [=y])
- -> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
+Laser turns off for SFP+ when ifconfig down
+-------------------------------------------
+"ifconfig down" turns off the laser for 82599-based SFP+ fiber adapters.
+"ifconfig up" turns on the later.
-1. make modules & make modules_install
-2. Load the module:
+82598-BASED ADAPTERS
-# modprobe ixgbe
+NOTES for 82598-Based Adapters:
+- Intel(R) Network Adapters that support removable optical modules only support
+ their original module type (i.e., the Intel(R) 10 Gigabit SR Dual Port
+ Express Module only supports SR optical modules). If you plug in a different
+ type of module, the driver will not load.
+- Hot Swapping/hot plugging optical modules is not supported.
+- Only single speed, 10 gigabit modules are supported.
+- LAN on Motherboard (LOMs) may support DA, SR, or LR modules. Other module
+ types are not supported. Please see your system documentation for details.
- The insmod command can be used if the full
- path to the driver module is specified. For example:
+The following is a list of 3rd party SFP+ modules and direct attach cables that
+have received some testing. Not all modules are applicable to all devices.
- insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgbe/ixgbe.ko
+Supplier Type Part Numbers
- With 2.6 based kernels also make sure that older ixgbe drivers are
- removed from the kernel, before loading the new module:
+Finisar SFP+ SR bailed, 10g single rate FTLX8571D3BCL
+Avago SFP+ SR bailed, 10g single rate AFBR-700SDZ
+Finisar SFP+ LR bailed, 10g single rate FTLX1471D3BCL
- rmmod ixgbe; modprobe ixgbe
+82598-based adapters support all passive direct attach cables that comply
+with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach
+cables are not supported.
-3. Assign an IP address to the interface by entering the following, where
- x is the interface number:
- ifconfig ethx <IP_address>
+Flow Control
+------------
+Ethernet Flow Control (IEEE 802.3x) can be configured with ethtool to enable
+receiving and transmitting pause frames for ixgbe. When TX is enabled, PAUSE
+frames are generated when the receive packet buffer crosses a predefined
+threshold. When rx is enabled, the transmit unit will halt for the time delay
+specified when a PAUSE frame is received.
-4. Verify that the interface works. Enter the following, where <IP_address>
- is the IP address for another machine on the same subnet as the interface
- that is being tested:
+Flow Control is enabled by default. If you want to disable a flow control
+capable link partner, use ethtool:
- ping <IP_address>
+ ethtool -A eth? autoneg off RX off TX off
+NOTE: For 82598 backplane cards entering 1 gig mode, flow control default
+behavior is changed to off. Flow control in 1 gig mode on these devices can
+lead to Tx hangs.
Additional Configurations
=========================
- Viewing Link Messages
- ---------------------
- Link messages will not be displayed to the console if the distribution is
- restricting system messages. In order to see network driver link messages on
- your console, set dmesg to eight by entering the following:
-
- dmesg -n 8
-
- NOTE: This setting is not saved across reboots.
-
-
Jumbo Frames
------------
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
@@ -123,13 +142,8 @@ Additional Configurations
other protocols besides TCP. It's also safe to use with configurations that
are problematic for LRO, namely bridging and iSCSI.
- GRO is enabled by default in the driver. Future versions of ethtool will
- support disabling and re-enabling GRO on the fly.
-
-
Data Center Bridging, aka DCB
-----------------------------
-
DCB is a configuration Quality of Service implementation in hardware.
It uses the VLAN priority tag (802.1p) to filter traffic. That means
that there are 8 different priorities that traffic can be filtered into.
@@ -163,24 +177,71 @@ Additional Configurations
http://e1000.sf.net
-
Ethtool
-------
The driver utilizes the ethtool interface for driver configuration and
- diagnostics, as well as displaying statistical information. Ethtool
- version 3.0 or later is required for this functionality.
+ diagnostics, as well as displaying statistical information. The latest
+ ethtool version is required for this functionality.
The latest release of ethtool can be found from
- http://sourceforge.net/projects/gkernel.
+ http://ftp.kernel.org/pub/software/network/ethtool/
-
- NAPI
+ FCoE
----
+ This release of the ixgbe driver contains new code to enable users to use
+ Fiber Channel over Ethernet (FCoE) and Data Center Bridging (DCB)
+ functionality that is supported by the 82598-based hardware. This code has
+ no default effect on the regular driver operation, and configuring DCB and
+ FCoE is outside the scope of this driver README. Refer to
+ http://www.open-fcoe.org/ for FCoE project information and contact
+ e1000-eedc@lists.sourceforge.net for DCB information.
+
+ MAC and VLAN anti-spoofing feature
+ ----------------------------------
+ When a malicious driver attempts to send a spoofed packet, it is dropped by
+ the hardware and not transmitted. An interrupt is sent to the PF driver
+ notifying it of the spoof attempt.
+
+ When a spoofed packet is detected the PF driver will send the following
+ message to the system log (displayed by the "dmesg" command):
+
+ Spoof event(s) detected on VF (n)
+
+ Where n=the VF that attempted to do the spoofing.
+
+
+Performance Tuning
+==================
+
+An excellent article on performance tuning can be found at:
+
+http://www.redhat.com/promo/summit/2008/downloads/pdf/Thursday/Mark_Wagner.pdf
+
+
+Known Issues
+============
+
+ Enabling SR-IOV in a 32-bit Microsoft* Windows* Server 2008 Guest OS using
+ Intel (R) 82576-based GbE or Intel (R) 82599-based 10GbE controller under KVM
+ -----------------------------------------------------------------------------
+ KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This
+ includes traditional PCIe devices, as well as SR-IOV-capable devices using
+ Intel 82576-based and 82599-based controllers.
+
+ While direct assignment of a PCIe device or an SR-IOV Virtual Function (VF)
+ to a Linux-based VM running 2.6.32 or later kernel works fine, there is a
+ known issue with Microsoft Windows Server 2008 VM that results in a "yellow
+ bang" error. This problem is within the KVM VMM itself, not the Intel driver,
+ or the SR-IOV logic of the VMM, but rather that KVM emulates an older CPU
+ model for the guests, and this older CPU model does not support MSI-X
+ interrupts, which is a requirement for Intel SR-IOV.
- NAPI (Rx polling mode) is supported in the ixgbe driver. NAPI is enabled
- by default in the driver.
+ If you wish to use the Intel 82576 or 82599-based controllers in SR-IOV mode
+ with KVM and a Microsoft Windows Server 2008 guest try the following
+ workaround. The workaround is to tell KVM to emulate a different model of CPU
+ when using qemu to create the KVM guest:
- See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
+ "-cpu qemu64,model=13"
Support
diff --git a/Documentation/networking/ixgbevf.txt b/Documentation/networking/ixgbevf.txt
index 21dd5d15b6b4..5a91a41fa946 100644
--- a/Documentation/networking/ixgbevf.txt
+++ b/Documentation/networking/ixgbevf.txt
@@ -35,10 +35,6 @@ Driver ID Guide at:
Known Issues/Troubleshooting
============================
- Unloading Physical Function (PF) Driver Causes System Reboots When VM is
- Running and VF is Loaded on the VM
- ------------------------------------------------------------------------
- Do not unload the PF driver (ixgbe) while VFs are assigned to guests.
Support
=======
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 7ee770b5ef5f..80a7a3454902 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -7,7 +7,7 @@ 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).
+(7xxx SoCs). Other platforms start using it i.e. ARM SPEAr.
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
@@ -95,9 +95,14 @@ 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;
+ int bus_id;
+ int pbl;
+ int clk_csr;
+ int has_gmac;
+ int enh_desc;
+ int tx_coe;
+ int bugged_jumbo;
+ int pmt;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void (*bus_setup)(unsigned long ioaddr);
#ifdef CONFIG_STM_DRIVERS
@@ -114,6 +119,12 @@ Where:
registers (on STM platforms);
- has_gmac: GMAC core is on board (get it at run-time in the next step);
- bus_id: bus identifier.
+- tx_coe: core is able to perform the tx csum in HW.
+- enh_desc: if sets the MAC will use the enhanced descriptor structure.
+- clk_csr: CSR Clock range selection.
+- bugged_jumbo: some HWs are not able to perform the csum in HW for
+ over-sized frames due to limited buffer sizes. Setting this
+ flag the csum will be done in SW on JUMBO frames.
struct plat_stmmacphy_data {
int bus_id;
@@ -131,13 +142,28 @@ Where:
- interface: physical MII interface mode;
- phy_reset: hook to reset HW function.
+SOURCES:
+- Kconfig
+- Makefile
+- stmmac_main.c: main network device driver;
+- stmmac_mdio.c: mdio functions;
+- stmmac_ethtool.c: ethtool support;
+- stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts
+ Only tested on ST40 platforms based.
+- stmmac.h: private driver structure;
+- common.h: common definitions and VFTs;
+- descs.h: descriptor structure definitions;
+- dwmac1000_core.c: GMAC core functions;
+- dwmac1000_dma.c: dma functions for the GMAC chip;
+- dwmac1000.h: specific header file for the GMAC;
+- dwmac100_core: MAC 100 core and dma code;
+- dwmac100_dma.c: dma funtions for the MAC chip;
+- dwmac1000.h: specific header file for the MAC;
+- dwmac_lib.c: generic DMA functions shared among chips
+- enh_desc.c: functions for handling enhanced descriptors
+- norm_desc.c: functions for handling normal descriptors
+
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.
+- XGMAC controller is not supported.
- Review the timer optimisation code to use an embedded device that seems to be
available in new chip generations.
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 489e9bacd165..41cc7b30d7dd 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
zero)
bool pm_runtime_suspended(struct device *dev);
- - return true if the device's runtime PM status is 'suspended', or false
- otherwise
+ - return true if the device's runtime PM status is 'suspended' and its
+ 'power.disable_depth' field is equal to zero, or false otherwise
void pm_runtime_allow(struct device *dev);
- set the power.runtime_auto flag for the device and decrease its usage
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 302db5da49b3..3272ed59dec7 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -131,7 +131,7 @@ order to avoid the degeneration that had become the ppc32 kernel entry
point and the way a new platform should be added to the kernel. The
legacy iSeries platform breaks those rules as it predates this scheme,
but no new board support will be accepted in the main tree that
-doesn't follows them properly. In addition, since the advent of the
+doesn't follow them properly. In addition, since the advent of the
arch/powerpc merged architecture for ppc32 and ppc64, new 32-bit
platforms and 32-bit platforms which move into arch/powerpc will be
required to use these rules as well.
@@ -1025,7 +1025,7 @@ dtc source code can be found at
WARNING: This version is still in early development stage; the
resulting device-tree "blobs" have not yet been validated with the
-kernel. The current generated bloc lacks a useful reserve map (it will
+kernel. The current generated block lacks a useful reserve map (it will
be fixed to generate an empty one, it's up to the bootloader to fill
it up) among others. The error handling needs work, bugs are lurking,
etc...
diff --git a/Documentation/powerpc/dts-bindings/4xx/cpm.txt b/Documentation/powerpc/dts-bindings/4xx/cpm.txt
new file mode 100644
index 000000000000..ee459806d35e
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/4xx/cpm.txt
@@ -0,0 +1,52 @@
+PPC4xx Clock Power Management (CPM) node
+
+Required properties:
+ - compatible : compatible list, currently only "ibm,cpm"
+ - dcr-access-method : "native"
+ - dcr-reg : < DCR register range >
+
+Optional properties:
+ - er-offset : All 4xx SoCs with a CPM controller have
+ one of two different order for the CPM
+ registers. Some have the CPM registers
+ in the following order (ER,FR,SR). The
+ others have them in the following order
+ (SR,ER,FR). For the second case set
+ er-offset = <1>.
+ - unused-units : specifier consist of one cell. For each
+ bit in the cell, the corresponding bit
+ in CPM will be set to turn off unused
+ devices.
+ - idle-doze : specifier consist of one cell. For each
+ bit in the cell, the corresponding bit
+ in CPM will be set to turn off unused
+ devices. This is usually just CPM[CPU].
+ - standby : specifier consist of one cell. For each
+ bit in the cell, the corresponding bit
+ in CPM will be set on standby and
+ restored on resume.
+ - suspend : specifier consist of one cell. For each
+ bit in the cell, the corresponding bit
+ in CPM will be set on suspend (mem) and
+ restored on resume. Note, for standby
+ and suspend the corresponding bits can
+ be different or the same. Usually for
+ standby only class 2 and 3 units are set.
+ However, the interface does not care.
+ If they are the same, the additional
+ power saving will be seeing if support
+ is available to put the DDR in self
+ refresh mode and any additional power
+ saving techniques for the specific SoC.
+
+Example:
+ CPM0: cpm {
+ compatible = "ibm,cpm";
+ dcr-access-method = "native";
+ dcr-reg = <0x160 0x003>;
+ er-offset = <0>;
+ unused-units = <0x00000100>;
+ idle-doze = <0x02000000>;
+ standby = <0xfeff0000>;
+ suspend = <0xfeff791d>;
+};
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas
index 00301ed9c371..b64d10d221ec 100644
--- a/Documentation/scsi/ChangeLog.megaraid_sas
+++ b/Documentation/scsi/ChangeLog.megaraid_sas
@@ -1,3 +1,25 @@
+Release Date : Tues. Dec 14, 2010 17:00:00 PST 2010 -
+ (emaild-id:megaraidlinux@lsi.com)
+ Adam Radford
+Current Version : 00.00.05.29-rc1
+Old Version : 00.00.04.31-rc1
+ 1. Rename megaraid_sas.c to megaraid_sas_base.c.
+ 2. Update GPL headers.
+ 3. Add MSI-X support and 'msix_disable' module parameter.
+ 4. Use lowest memory bar (for SR-IOV VF support).
+ 5. Add struct megasas_instance_temlate changes, and change all code to use
+ new instance entries:
+
+ irqreturn_t (*service_isr )(int irq, void *devp);
+ void (*tasklet)(unsigned long);
+ u32 (*init_adapter)(struct megasas_instance *);
+ u32 (*build_and_issue_cmd) (struct megasas_instance *,
+ struct scsi_cmnd *);
+ void (*issue_dcmd) (struct megasas_instance *instance,
+ struct megasas_cmd *cmd);
+
+ 6. Add code to support MegaRAID 9265/9285 controllers device id (0x5b).
+-------------------------------------------------------------------------------
1 Release Date : Thur. May 03, 2010 09:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 570ef2b3d79b..df322c103466 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -1044,9 +1044,9 @@ Details:
/**
- * queuecommand - queue scsi command, invoke 'done' on completion
+ * queuecommand - queue scsi command, invoke scp->scsi_done on completion
+ * @shost: pointer to the scsi host object
* @scp: pointer to scsi command object
- * @done: function pointer to be invoked on completion
*
* Returns 0 on success.
*
@@ -1074,42 +1074,45 @@ Details:
*
* Other types of errors that are detected immediately may be
* flagged by setting scp->result to an appropriate value,
- * invoking the 'done' callback, and then returning 0 from this
- * function. If the command is not performed immediately (and the
- * LLD is starting (or will start) the given command) then this
- * function should place 0 in scp->result and return 0.
+ * invoking the scp->scsi_done callback, and then returning 0
+ * from this function. If the command is not performed
+ * immediately (and the LLD is starting (or will start) the given
+ * command) then this function should place 0 in scp->result and
+ * return 0.
*
* Command ownership. If the driver returns zero, it owns the
- * command and must take responsibility for ensuring the 'done'
- * callback is executed. Note: the driver may call done before
- * returning zero, but after it has called done, it may not
- * return any value other than zero. If the driver makes a
- * non-zero return, it must not execute the command's done
- * callback at any time.
- *
- * Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
- * and is expected to be held on return.
+ * command and must take responsibility for ensuring the
+ * scp->scsi_done callback is executed. Note: the driver may
+ * call scp->scsi_done before returning zero, but after it has
+ * called scp->scsi_done, it may not return any value other than
+ * zero. If the driver makes a non-zero return, it must not
+ * execute the command's scsi_done callback at any time.
+ *
+ * Locks: up to and including 2.6.36, struct Scsi_Host::host_lock
+ * held on entry (with "irqsave") and is expected to be
+ * held on return. From 2.6.37 onwards, queuecommand is
+ * called without any locks held.
*
* Calling context: in interrupt (soft irq) or process context
*
- * Notes: This function should be relatively fast. Normally it will
- * not wait for IO to complete. Hence the 'done' callback is invoked
- * (often directly from an interrupt service routine) some time after
- * this function has returned. In some cases (e.g. pseudo adapter
- * drivers that manufacture the response to a SCSI INQUIRY)
- * the 'done' callback may be invoked before this function returns.
- * If the 'done' callback is not invoked within a certain period
- * the SCSI mid level will commence error processing.
- * If a status of CHECK CONDITION is placed in "result" when the
- * 'done' callback is invoked, then the LLD driver should
- * perform autosense and fill in the struct scsi_cmnd::sense_buffer
+ * Notes: This function should be relatively fast. Normally it
+ * will not wait for IO to complete. Hence the scp->scsi_done
+ * callback is invoked (often directly from an interrupt service
+ * routine) some time after this function has returned. In some
+ * cases (e.g. pseudo adapter drivers that manufacture the
+ * response to a SCSI INQUIRY) the scp->scsi_done callback may be
+ * invoked before this function returns. If the scp->scsi_done
+ * callback is not invoked within a certain period the SCSI mid
+ * level will commence error processing. If a status of CHECK
+ * CONDITION is placed in "result" when the scp->scsi_done
+ * callback is invoked, then the LLD driver should perform
+ * autosense and fill in the struct scsi_cmnd::sense_buffer
* array. The scsi_cmnd::sense_buffer array is zeroed prior to
* the mid level queuing a command to an LLD.
*
* Defined in: LLD
**/
- int queuecommand(struct scsi_cmnd * scp,
- void (*done)(struct scsi_cmnd *))
+ int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp)
/**
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index d0eb696d32e8..7124340038ea 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -974,13 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
See hdspm.txt for details.
- Module snd-hifier
- -----------------
-
- Module for the MediaTek/TempoTec HiFier Fantasia sound card.
-
- This module supports autoprobe and multiple cards.
-
Module snd-ice1712
------------------
@@ -1531,15 +1524,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-oxygen
-----------------
- Module for sound cards based on the C-Media CMI8788 chip:
+ Module for sound cards based on the C-Media CMI8787/8788 chip:
* Asound A-8788
* AuzenTech X-Meridian
* Bgears b-Enspirer
* Club3D Theatron DTS
* HT-Omega Claro (plus)
* HT-Omega Claro halo (XT)
+ * Kuroutoshikou CMI8787-HG2PCI
* Razer Barracuda AC-1
* Sondigo Inferno
+ * TempoTec HiFier Fantasia
+ * TempoTec HiFier Serenade
This module supports autoprobe and multiple cards.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 37c6aad5e590..16ae4300c747 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -149,7 +149,6 @@ ALC882/883/885/888/889
acer-aspire-7730g Acer Aspire 7730G
acer-aspire-8930g Acer Aspire 8930G
medion Medion Laptops
- medion-md2 Medion MD2
targa-dig Targa/MSI
targa-2ch-dig Targa/MSI with 2-channel
targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index cb3d15bc1aeb..b61e46f449aa 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -278,3 +278,15 @@ method, the sys I/F structure will be built like this:
|---name: acpitz
|---temp1_input: 37000
|---temp1_crit: 100000
+
+4. Event Notification
+
+The framework includes a simple notification mechanism, in the form of a
+netlink event. Netlink socket initialization is done during the _init_
+of the framework. Drivers which intend to use the notification mechanism
+just need to call generate_netlink_event() with two arguments viz
+(originator, event). Typically the originator will be an integer assigned
+to a thermal_zone_device when it registers itself with the framework. The
+event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
+THERMAL_DEV_FAULT}. Notification can be sent when the current temperature
+crosses any of the configured thresholds.
diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
index b3e73ddb1567..12cecc83cd91 100644
--- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
+++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
@@ -373,9 +373,18 @@ EVENT_PROCESS:
print " $regex_lru_isolate/o\n";
next;
}
+ my $isolate_mode = $1;
my $nr_scanned = $4;
my $nr_contig_dirty = $7;
- $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
+
+ # To closer match vmstat scanning statistics, only count isolate_both
+ # and isolate_inactive as scanning. isolate_active is rotation
+ # isolate_inactive == 0
+ # isolate_active == 1
+ # isolate_both == 2
+ if ($isolate_mode != 1) {
+ $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
+ }
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
$details = $5;
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index ac2616a62fc3..31b485723bc5 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
- 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
+ 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868,eb1a:2875]
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
@@ -9,7 +9,7 @@
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
- 11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
+ 11 -> Terratec Hybrid XS (em2880)
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
@@ -53,7 +53,7 @@
52 -> DNT DA2 Hybrid (em2881)
53 -> Pinnacle Hybrid Pro (em2881)
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
- 55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e]
+ 55 -> Terratec Cinnergy Hybrid T USB XS (em2882) (em2882) [0ccd:005e,0ccd:0042]
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 8d9afc7d8014..6b4c72d8862d 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -180,3 +180,5 @@
179 -> Beholder BeholdTV A7 [5ace:7090]
180 -> Avermedia PCI M733A [1461:4155,1461:4255]
181 -> TechoTrend TT-budget T-3000 [13c2:2804]
+182 -> Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid [17de:b136]
+183 -> Compro VideoMate Vista M1F [185b:c900]
diff --git a/Documentation/video4linux/Makefile b/Documentation/video4linux/Makefile
deleted file mode 100644
index 1ed0e98d057d..000000000000
--- a/Documentation/video4linux/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# kbuild trick to avoid linker error. Can be omitted if a module is built.
-obj- := dummy.o
-
-# List of programs to build
-hostprogs-y := v4lgrab
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/video4linux/README.cpia b/Documentation/video4linux/README.cpia
deleted file mode 100644
index 8a747fee661f..000000000000
--- a/Documentation/video4linux/README.cpia
+++ /dev/null
@@ -1,191 +0,0 @@
-This is a driver for the CPiA PPC2 driven parallel connected
-Camera. For example the Creative WebcamII is CPiA driven.
-
- ) [1]Peter Pregler, Linz 2000, published under the [2]GNU GPL
-
----------------------------------------------------------------------------
-
-USAGE:
-
-General:
-========
-
-1) Make sure you have created the video devices (/dev/video*):
-
-- if you have a recent MAKEDEV do a 'cd /dev;./MAKEDEV video'
-- otherwise do a:
-
-cd /dev
-mknod video0 c 81 0
-ln -s video0 video
-
-2) Compile the kernel (see below for the list of options to use),
- configure your parport and reboot.
-
-3) If all worked well you should get messages similar
- to the following (your versions may be different) on the console:
-
-V4L-Driver for Vision CPiA based cameras v0.7.4
-parport0: read2 timeout.
-parport0: Multimedia device, VLSI Vision Ltd PPC2
-Parallel port driver for Vision CPiA based camera
- CPIA Version: 1.20 (2.0)
- CPIA PnP-ID: 0553:0002:0100
- VP-Version: 1.0 0100
- 1 camera(s) found
-
-
-As modules:
-===========
-
-Make sure you have selected the following kernel options (you can
-select all stuff as modules):
-
-The cpia-stuff is in the section 'Character devices -> Video For Linux'.
-
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_FIFO=y
-CONFIG_PARPORT_1284=y
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_PP=m
-
-For autoloading of all those modules you need to tell module-init-tools
-some stuff. Add the following line to your module-init-tools config-file
-(e.g. /etc/modprobe.conf or wherever your distribution does store that
-stuff):
-
-options parport_pc io=0x378 irq=7 dma=3
-alias char-major-81 cpia_pp
-
-The first line tells the dma/irq channels to use. Those _must_ match
-the settings of your BIOS. Do NOT simply use the values above. See
-Documentation/parport.txt for more information about this. The second
-line associates the video-device file with the driver. Of cause you
-can also load the modules once upon boot (usually done in /etc/modules).
-
-Linked into the kernel:
-=======================
-
-Make sure you have selected the following kernel options. Note that
-you cannot compile the parport-stuff as modules and the cpia-driver
-statically (the other way round is okay though).
-
-The cpia-stuff is in the section 'Character devices -> Video For Linux'.
-
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_FIFO=y
-CONFIG_PARPORT_1284=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_CPIA=y
-CONFIG_VIDEO_CPIA_PP=y
-
-To use DMA/irq you will need to tell the kernel upon boot time the
-hardware configuration of the parport. You can give the boot-parameter
-at the LILO-prompt or specify it in lilo.conf. I use the following
-append-line in lilo.conf:
-
- append="parport=0x378,7,3"
-
-See Documentation/parport.txt for more information about the
-configuration of the parport and the values given above. Do not simply
-use the values given above.
-
----------------------------------------------------------------------------
-FEATURES:
-
-- mmap/read v4l-interface (but no overlay)
-- image formats: CIF/QCIF, SIF/QSIF, various others used by isabel;
- note: all sizes except CIF/QCIF are implemented by clipping, i.e.
- pixels are not uploaded from the camera
-- palettes: VIDEO_PALETTE_GRAY, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB555,
- VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32, VIDEO_PALETTE_YUYV,
- VIDEO_PALETTE_UYVY, VIDEO_PALETTE_YUV422
-- state information (color balance, exposure, ...) is preserved between
- device opens
-- complete control over camera via proc-interface (_all_ camera settings are
- supported), there is also a python-gtk application available for this [3]
-- works under SMP (but the driver is completely serialized and synchronous)
- so you get no benefit from SMP, but at least it does not crash your box
-- might work for non-Intel architecture, let us know about this
-
----------------------------------------------------------------------------
-TESTED APPLICATIONS:
-
-- a simple test application based on Xt is available at [3]
-- another test-application based on gqcam-0.4 (uses GTK)
-- gqcam-0.6 should work
-- xawtv-3.x (also the webcam software)
-- xawtv-2.46
-- w3cam (cgi-interface and vidcat, e.g. you may try out 'vidcat |xv
- -maxpect -root -quit +noresetroot -rmode 5 -')
-- vic, the MBONE video conferencing tool (version 2.8ucl4-1)
-- isabel 3R4beta (barely working, but AFAICT all the problems are on
- their side)
-- camserv-0.40
-
-See [3] for pointers to v4l-applications.
-
----------------------------------------------------------------------------
-KNOWN PROBLEMS:
-
-- some applications do not handle the image format correctly, you will
- see strange horizontal stripes instead of a nice picture -> make sure
- your application does use a supported image size or queries the driver
- for the actually used size (reason behind this: the camera cannot
- provide any image format, so if size NxM is requested the driver will
- use a format to the closest fitting N1xM1, the application should now
- query for this granted size, most applications do not).
-- all the todo ;)
-- if there is not enough light and the picture is too dark try to
- adjust the SetSensorFPS setting, automatic frame rate adjustment
- has its price
-- do not try out isabel 3R4beta (built 135), you will be disappointed
-
----------------------------------------------------------------------------
-TODO:
-
-- multiple camera support (struct camera or something) - This should work,
- but hasn't been tested yet.
-- architecture independence?
-- SMP-safe asynchronous mmap interface
-- nibble mode for old parport interfaces
-- streaming capture, this should give a performance gain
-
----------------------------------------------------------------------------
-IMPLEMENTATION NOTES:
-
-The camera can act in two modes, streaming or grabbing. Right now a
-polling grab-scheme is used. Maybe interrupt driven streaming will be
-used for a asynchronous mmap interface in the next major release of the
-driver. This might give a better frame rate.
-
----------------------------------------------------------------------------
-THANKS (in no particular order):
-
-- Scott J. Bertin <sbertin@mindspring.com> for cleanups, the proc-filesystem
- and much more
-- Henry Bruce <whb@vvl.co.uk> for providing developers information about
- the CPiA chip, I wish all companies would treat Linux as seriously
-- Karoly Erdei <Karoly.Erdei@risc.uni-linz.ac.at> and RISC-Linz for being
- my boss ;) resp. my employer and for providing me the hardware and
- allow me to devote some working time to this project
-- Manuel J. Petit de Gabriel <mpetit@dit.upm.es> for providing help
- with Isabel (http://isabel.dit.upm.es/)
-- Bas Huisman <bhuism@cs.utwente.nl> for writing the initial parport code
-- Jarl Totland <Jarl.Totland@bdc.no> for setting up the mailing list
- and maintaining the web-server[3]
-- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
- 1.02 firmware
-- special kudos to all the tester whose machines crashed and/or
- will crash. :)
-
----------------------------------------------------------------------------
-REFERENCES
-
- 1. http://www.risc.uni-linz.ac.at/
- mailto:Peter_Pregler@email.com
- 2. see the file COPYING in the top directory of the kernel tree
- 3. http://webcam.sourceforge.net/
diff --git a/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran
index 00e3f9267814..699b60e070d2 100644
--- a/Documentation/video4linux/Zoran
+++ b/Documentation/video4linux/Zoran
@@ -322,76 +322,11 @@ your IRQs and make sure the card has its own interrupts.
4. Programming interface
-This driver conforms to video4linux and video4linux2, both can be used to
-use the driver. Since video4linux didn't provide adequate calls to fully
-use the cards' features, we've introduced several programming extensions,
-which are currently officially accepted in the 2.4.x branch of the kernel.
-These extensions are known as the v4l/mjpeg extensions. See zoran.h for
-details (structs/ioctls).
-
-Information - video4linux:
-http://linux.bytesex.org/v4l2/API.html
-Documentation/video4linux/API.html
-/usr/include/linux/videodev.h
-
-Information - video4linux/mjpeg extensions:
-./zoran.h
-(also see below)
-
-Information - video4linux2:
-http://linuxtv.org
-http://v4l2spec.bytesex.org/
-/usr/include/linux/videodev2.h
-
-More information on the video4linux/mjpeg extensions, by Serguei
-Miridonovi and Rainer Johanni:
---
-The ioctls for that interface are as follows:
-
-BUZIOC_G_PARAMS
-BUZIOC_S_PARAMS
-
-Get and set the parameters of the buz. The user should always do a
-BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
-settings, change what he likes and then make a BUZIOC_S_PARAMS call.
-
-BUZIOC_REQBUFS
-
-Before being able to capture/playback, the user has to request
-the buffers he is wanting to use. Fill the structure
-zoran_requestbuffers with the size (recommended: 256*1024) and
-the number (recommended 32 up to 256). There are no such restrictions
-as for the Video for Linux buffers, you should LEAVE SUFFICIENT
-MEMORY for your system however, else strange things will happen ....
-On return, the zoran_requestbuffers structure contains number and
-size of the actually allocated buffers.
-You should use these numbers for doing a mmap of the buffers
-into the user space.
-The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
-maps the MJPEG buffer instead of the V4L buffers.
-
-BUZIOC_QBUF_CAPT
-BUZIOC_QBUF_PLAY
-
-Queue a buffer for capture or playback. The first call also starts
-streaming capture. When streaming capture is going on, you may
-only queue further buffers or issue syncs until streaming
-capture is switched off again with a argument of -1 to
-a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
-
-BUZIOC_SYNC
-
-Issue this ioctl when all buffers are queued. This ioctl will
-block until the first buffer becomes free for saving its
-data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
-
-BUZIOC_G_STATUS
-
-Get the status of the input lines (video source connected/norm).
+This driver conforms to video4linux2. Support for V4L1 and for the custom
+zoran ioctls has been removed in kernel 2.6.38.
For programming example, please, look at lavrec.c and lavplay.c code in
-lavtools-1.2p2 package (URL: http://www.cicese.mx/)
-and the 'examples' directory in the original Buz driver distribution.
+the MJPEG-tools (http://mjpeg.sf.net/).
Additional notes for software developers:
@@ -402,9 +337,6 @@ Additional notes for software developers:
standard is "more constant" for current country than geometry
settings of a variety of TV capture cards which may work in ITU or
square pixel format.
---
-Please note that lavplay/lavrec are also included in the MJPEG-tools
-(http://mjpeg.sf.net/).
===========================
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index 12217fc49725..db833ced2cb8 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -464,10 +464,6 @@ Siemens
-------
Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
-Stradis
--------
- SDM275,SDM250,SDM026,SDM025 (SAA7146, IBMMPEG2): MPEG2 decoder only
-
Powercolor
----------
MTV878
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 6a562eeeb4cd..261776e0c5e1 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -366,6 +366,7 @@ t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
pac207 2001:f115 D-Link DSB-C120
sq905c 2770:9050 Disney pix micro (CIF)
+sq905c 2770:9051 Lego Bionicle
sq905c 2770:9052 Disney pix micro 2 (VGA)
sq905c 2770:905c All 11 known cameras with this ID
sq905 2770:9120 All 24 known cameras with this ID
diff --git a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt
index bf3af5fe558f..34e2842c70ae 100644
--- a/Documentation/video4linux/meye.txt
+++ b/Documentation/video4linux/meye.txt
@@ -45,8 +45,6 @@ module argument syntax (<param>=<value> when passing the option to the
module or meye.<param>=<value> on the kernel boot line when meye is
statically linked into the kernel). Those options are:
- forcev4l1: force use of V4L1 API instead of V4L2
-
gbuffers: number of capture buffers, default is 2 (32 max)
gbufsize: size of each capture buffer, default is 614400
@@ -79,9 +77,8 @@ Usage:
Private API:
------------
- The driver supports frame grabbing with the video4linux API
- (either v4l1 or v4l2), so all video4linux tools (like xawtv)
- should work with this driver.
+ The driver supports frame grabbing with the video4linux API,
+ so all video4linux tools (like xawtv) should work with this driver.
Besides the video4linux interface, the driver has a private interface
for accessing the Motion Eye extended parameters (camera sharpness,
@@ -123,7 +120,4 @@ Private API:
Bugs / Todo:
------------
- - the driver could be much cleaned up by removing the v4l1 support.
- However, this means all v4l1-only applications will stop working.
-
- 'motioneye' still uses the meye private v4l1 API extensions.
diff --git a/Documentation/video4linux/v4lgrab.c b/Documentation/video4linux/v4lgrab.c
deleted file mode 100644
index c8ded175796e..000000000000
--- a/Documentation/video4linux/v4lgrab.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Simple Video4Linux image grabber. */
-/*
- * Video4Linux Driver Test/Example Framegrabbing Program
- *
- * Compile with:
- * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
- * Use as:
- * v4lgrab >image.ppm
- *
- * Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
- * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
- * with minor modifications (Dave Forrest, drf5n@virginia.edu).
- *
- *
- * For some cameras you may need to pre-load libv4l to perform
- * the necessary decompression, e.g.:
- *
- * export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
- * ./v4lgrab >image.ppm
- *
- * see http://hansdegoede.livejournal.com/3636.html for details.
- *
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-
-#include <linux/types.h>
-#include <linux/videodev.h>
-
-#define VIDEO_DEV "/dev/video0"
-
-/* Stole this from tvset.c */
-
-#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
-{ \
- switch (format) \
- { \
- case VIDEO_PALETTE_GREY: \
- switch (depth) \
- { \
- case 4: \
- case 6: \
- case 8: \
- (r) = (g) = (b) = (*buf++ << 8);\
- break; \
- \
- case 16: \
- (r) = (g) = (b) = \
- *((unsigned short *) buf); \
- buf += 2; \
- break; \
- } \
- break; \
- \
- \
- case VIDEO_PALETTE_RGB565: \
- { \
- unsigned short tmp = *(unsigned short *)buf; \
- (r) = tmp&0xF800; \
- (g) = (tmp<<5)&0xFC00; \
- (b) = (tmp<<11)&0xF800; \
- buf += 2; \
- } \
- break; \
- \
- case VIDEO_PALETTE_RGB555: \
- (r) = (buf[0]&0xF8)<<8; \
- (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
- (b) = ((buf[1] << 2 ) & 0xF8)<<8; \
- buf += 2; \
- break; \
- \
- case VIDEO_PALETTE_RGB24: \
- (r) = buf[0] << 8; (g) = buf[1] << 8; \
- (b) = buf[2] << 8; \
- buf += 3; \
- break; \
- \
- default: \
- fprintf(stderr, \
- "Format %d not yet supported\n", \
- format); \
- } \
-}
-
-static int get_brightness_adj(unsigned char *image, long size, int *brightness) {
- long i, tot = 0;
- for (i=0;i<size*3;i++)
- tot += image[i];
- *brightness = (128 - tot/(size*3))/3;
- return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130);
-}
-
-int main(int argc, char ** argv)
-{
- int fd = open(VIDEO_DEV, O_RDONLY), f;
- struct video_capability cap;
- struct video_window win;
- struct video_picture vpic;
-
- unsigned char *buffer, *src;
- int bpp = 24, r = 0, g = 0, b = 0;
- unsigned int i, src_depth = 16;
-
- if (fd < 0) {
- perror(VIDEO_DEV);
- exit(1);
- }
-
- if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
- perror("VIDIOGCAP");
- fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
- close(fd);
- exit(1);
- }
-
- if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
- perror("VIDIOCGWIN");
- close(fd);
- exit(1);
- }
-
- if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
- perror("VIDIOCGPICT");
- close(fd);
- exit(1);
- }
-
- if (cap.type & VID_TYPE_MONOCHROME) {
- vpic.depth=8;
- vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */
- if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
- vpic.depth=6;
- if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
- vpic.depth=4;
- if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
- fprintf(stderr, "Unable to find a supported capture format.\n");
- close(fd);
- exit(1);
- }
- }
- }
- } else {
- vpic.depth=24;
- vpic.palette=VIDEO_PALETTE_RGB24;
-
- if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
- vpic.palette=VIDEO_PALETTE_RGB565;
- vpic.depth=16;
-
- if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
- vpic.palette=VIDEO_PALETTE_RGB555;
- vpic.depth=15;
-
- if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
- fprintf(stderr, "Unable to find a supported capture format.\n");
- return -1;
- }
- }
- }
- }
-
- buffer = malloc(win.width * win.height * bpp);
- if (!buffer) {
- fprintf(stderr, "Out of memory.\n");
- exit(1);
- }
-
- do {
- int newbright;
- read(fd, buffer, win.width * win.height * bpp);
- f = get_brightness_adj(buffer, win.width * win.height, &newbright);
- if (f) {
- vpic.brightness += (newbright << 8);
- if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
- perror("VIDIOSPICT");
- break;
- }
- }
- } while (f);
-
- fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);
-
- src = buffer;
-
- for (i = 0; i < win.width * win.height; i++) {
- READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
- fputc(r>>8, stdout);
- fputc(g>>8, stdout);
- fputc(b>>8, stdout);
- }
-
- close(fd);
- return 0;
-}
diff --git a/Documentation/video4linux/videobuf b/Documentation/video4linux/videobuf
index 17a1f9abf260..1d00d7f15b8f 100644
--- a/Documentation/video4linux/videobuf
+++ b/Documentation/video4linux/videobuf
@@ -247,8 +247,6 @@ calls. The relevant helper functions are:
int nonblocking);
int videobuf_streamon(struct videobuf_queue *q);
int videobuf_streamoff(struct videobuf_queue *q);
- int videobuf_cgmbuf(struct videobuf_queue *q, struct video_mbuf *mbuf,
- int count);
So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
vidioc_reqbufs() callback which, in turn, usually only needs to locate the
@@ -258,10 +256,7 @@ boilerplate in a lot of V4L2 drivers.
The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
complex, of course, since they will also need to deal with starting and
-stopping the capture engine. videobuf_cgmbuf(), called from the driver's
-vidiocgmbuf() function, only exists if the V4L1 compatibility module has
-been selected with CONFIG_VIDEO_V4L1_COMPAT, so its use must be surrounded
-with #ifdef directives.
+stopping the capture engine.
Buffer allocation
diff --git a/MAINTAINERS b/MAINTAINERS
index b3be8b3d0437..fed77c41e1a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -166,9 +166,8 @@ F: drivers/serial/8250*
F: include/linux/serial_8250.h
8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
-M: Paul Gortmaker <p_gortmaker@yahoo.com>
L: netdev@vger.kernel.org
-S: Maintained
+S: Orphan / Obsolete
F: drivers/net/*8390*
F: drivers/net/ax88796.c
@@ -405,7 +404,7 @@ S: Supported
F: drivers/usb/gadget/amd5536udc.*
AMD GEODE PROCESSOR/CHIPSET SUPPORT
-P: Jordan Crouse
+P: Andres Salomon <dilinger@queued.net>
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
@@ -559,14 +558,14 @@ W: http://maxim.org.za/at91_26.html
S: Maintained
ARM/BCMRING ARM ARCHITECTURE
-M: Leo Chen <leochen@broadcom.com>
+M: Jiandong Zheng <jdzheng@broadcom.com>
M: Scott Branden <sbranden@broadcom.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-bcmring
ARM/BCMRING MTD NAND DRIVER
-M: Leo Chen <leochen@broadcom.com>
+M: Jiandong Zheng <jdzheng@broadcom.com>
M: Scott Branden <sbranden@broadcom.com>
L: linux-mtd@lists.infradead.org
S: Maintained
@@ -792,11 +791,14 @@ S: Maintained
ARM/NOMADIK ARCHITECTURE
M: Alessandro Rubini <rubini@unipv.it>
+M: Linus Walleij <linus.walleij@stericsson.com>
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/
+F: drivers/i2c/busses/i2c-nomadik.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
M: Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -815,7 +817,7 @@ F: drivers/mmc/host/msm_sdcc.c
F: drivers/mmc/host/msm_sdcc.h
F: drivers/serial/msm_serial.h
F: drivers/serial/msm_serial.c
-T: git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+T: git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
S: Maintained
ARM/TOSA MACHINE SUPPORT
@@ -998,12 +1000,24 @@ F: drivers/i2c/busses/i2c-stu300.c
F: drivers/rtc/rtc-coh901331.c
F: drivers/watchdog/coh901327_wdt.c
F: drivers/dma/coh901318*
+F: drivers/mfd/ab3100*
+F: drivers/rtc/rtc-ab3100.c
+F: drivers/rtc/rtc-coh901331.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
-ARM/U8500 ARM ARCHITECTURE
+ARM/Ux500 ARM ARCHITECTURE
M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+M: Linus Walleij <linus.walleij@stericsson.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-ux500/
+F: drivers/dma/ste_dma40*
+F: drivers/mfd/ab3550*
+F: drivers/mfd/abx500*
+F: drivers/mfd/ab8500*
+F: drivers/mfd/stmpe*
+F: drivers/rtc/rtc-ab8500.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/VFP SUPPORT
M: Russell King <linux@arm.linux.org.uk>
@@ -1080,6 +1094,12 @@ S: Supported
F: Documentation/aoe/
F: drivers/block/aoe/
+ATHEROS ATH GENERIC UTILITIES
+M: "Luis R. Rodriguez" <lrodriguez@atheros.com>
+L: linux-wireless@vger.kernel.org
+S: Supported
+F: drivers/net/wireless/ath/*
+
ATHEROS ATH5K WIRELESS DRIVER
M: Jiri Slaby <jirislaby@gmail.com>
M: Nick Kossifidis <mickflemm@gmail.com>
@@ -1258,6 +1278,15 @@ S: Maintained
F: drivers/video/backlight/
F: include/linux/backlight.h
+BATMAN ADVANCED
+M: Marek Lindner <lindner_marek@yahoo.de>
+M: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+M: Sven Eckelmann <sven@narfation.org>
+L: b.a.t.m.a.n@lists.open-mesh.org
+W: http://www.open-mesh.org/
+S: Maintained
+F: net/batman-adv/
+
BAYCOM/HDLCDRV DRIVERS FOR AX.25
M: Thomas Sailer <t.sailer@alumni.ethz.ch>
L: linux-hams@vger.kernel.org
@@ -2060,7 +2089,7 @@ F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
M: Greg Kroah-Hartman <gregkh@suse.de>
-T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
S: Supported
F: Documentation/kobject.txt
F: drivers/base/
@@ -2080,7 +2109,7 @@ F: include/drm/
INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
M: Chris Wilson <chris@chris-wilson.co.uk>
-L: intel-gfx@lists.freedesktop.org
+L: intel-gfx@lists.freedesktop.org (subscribers-only)
L: dri-devel@lists.freedesktop.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel.git
S: Supported
@@ -2579,6 +2608,14 @@ S: Supported
F: drivers/i2c/busses/i2c-gpio.c
F: include/linux/i2c-gpio.h
+GENERIC GPIO I2C MULTIPLEXER DRIVER
+M: Peter Korsgaard <peter.korsgaard@barco.com>
+L: linux-i2c@vger.kernel.org
+S: Supported
+F: drivers/i2c/muxes/gpio-i2cmux.c
+F: include/linux/gpio-i2cmux.h
+F: Documentation/i2c/muxes/gpio-i2cmux
+
GENERIC HDLC (WAN) DRIVERS
M: Krzysztof Halasa <khc@pm.waw.pl>
W: http://www.kernel.org/pub/linux/utils/net/hdlc/
@@ -3032,8 +3069,10 @@ F: drivers/input/
INPUT MULTITOUCH (MT) PROTOCOL
M: Henrik Rydberg <rydberg@euromail.se>
L: linux-input@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git
S: Maintained
F: Documentation/input/multi-touch-protocol.txt
+F: drivers/input/input-mt.c
K: \b(ABS|SYN)_MT_
INTEL IDLE DRIVER
@@ -3120,6 +3159,8 @@ M: Alex Duyck <alexander.h.duyck@intel.com>
M: John Ronciak <john.ronciak@intel.com>
L: e1000-devel@lists.sourceforge.net
W: http://e1000.sourceforge.net/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next-2.6.git
S: Supported
F: Documentation/networking/e100.txt
F: Documentation/networking/e1000.txt
@@ -4064,9 +4105,8 @@ F: drivers/scsi/NCR_D700.*
NETEFFECT IWARP RNIC DRIVER (IW_NES)
M: Faisal Latif <faisal.latif@intel.com>
-M: Chien Tung <chien.tin.tung@intel.com>
L: linux-rdma@vger.kernel.org
-W: http://www.neteffect.com
+W: http://www.intel.com/Products/Server/Adapters/Server-Cluster/Server-Cluster-overview.htm
S: Supported
F: drivers/infiniband/hw/nes/
@@ -4232,6 +4272,7 @@ NILFS2 FILESYSTEM
M: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
L: linux-nilfs@vger.kernel.org
W: http://www.nilfs.org/en/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2.git
S: Supported
F: Documentation/filesystems/nilfs2.txt
F: fs/nilfs2/
@@ -4329,6 +4370,20 @@ M: Deepak Saxena <dsaxena@plexity.net>
S: Maintained
F: drivers/char/hw_random/omap-rng.c
+OMAP HWMOD SUPPORT
+M: Benoît Cousson <b-cousson@ti.com>
+M: Paul Walmsley <paul@pwsan.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/mach-omap2/omap_hwmod.c
+F: arch/arm/plat-omap/include/plat/omap_hwmod.h
+
+OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
+M: Benoît Cousson <b-cousson@ti.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+
OMAP USB SUPPORT
M: Felipe Balbi <balbi@ti.com>
M: David Brownell <dbrownell@users.sourceforge.net>
@@ -4591,7 +4646,7 @@ F: drivers/pcmcia/
F: include/pcmcia/
PCNET32 NETWORK DRIVER
-M: Don Fry <pcnet32@verizon.net>
+M: Don Fry <pcnet32@frontier.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/pcnet32.c
@@ -5038,7 +5093,7 @@ L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
-F: drivers/net/wireless/rtl818x/rtl8180*
+F: drivers/net/wireless/rtl818x/rtl8180/
RTL8187 WIRELESS DRIVER
M: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
@@ -5048,7 +5103,17 @@ L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
-F: drivers/net/wireless/rtl818x/rtl8187*
+F: drivers/net/wireless/rtl818x/rtl8187/
+
+RTL8192CE WIRELESS DRIVER
+M: Larry Finger <Larry.Finger@lwfinger.net>
+M: Chaoming Li <chaoming_li@realsil.com.cn>
+L: linux-wireless@vger.kernel.org
+W: http://linuxwireless.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S: Maintained
+F: drivers/net/wireless/rtlwifi/
+F: drivers/net/wireless/rtlwifi/rtl8192ce/
S3 SAVAGE FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
@@ -5126,7 +5191,7 @@ SAMSUNG AUDIO (ASoC) DRIVERS
M: Jassi Brar <jassi.brar@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
-F: sound/soc/s3c24xx
+F: sound/soc/samsung
TLG2300 VIDEO4LINUX-2 DRIVER
M: Huang Shijie <shijie8@gmail.com>
@@ -5698,12 +5763,6 @@ M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
F: drivers/net/starfire*
-STRADIS MPEG-2 DECODER DRIVER
-M: Nathan Laredo <laredo@gnu.org>
-W: http://www.stradis.com/
-S: Maintained
-F: drivers/media/video/stradis.c
-
SUN3/3X
M: Sam Creasey <sammy@sammy.net>
W: http://sammy.net/sun3/
@@ -5933,7 +5992,6 @@ F: include/linux/tty.h
TULIP NETWORK DRIVERS
M: Grant Grundler <grundler@parisc-linux.org>
-M: Kyle McMartin <kyle@mcmartin.ca>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/tulip/
@@ -6585,6 +6643,15 @@ F: include/linux/mfd/wm8400*
F: include/sound/wm????.h
F: sound/soc/codecs/wm*
+WORKQUEUE
+M: Tejun Heo <tj@kernel.org>
+L: linux-kernel@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+S: Maintained
+F: include/linux/workqueue.h
+F: kernel/workqueue.c
+F: Documentation/workqueue.txt
+
X.25 NETWORK LAYER
M: Andrew Hendry <andrew.hendry@gmail.com>
L: linux-x25@vger.kernel.org
diff --git a/Makefile b/Makefile
index 9e3c89030f5c..b37fe372503c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 37
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc8
NAME = Flesh-Eating Bats with Fangs
# *DOCUMENTATION*
@@ -224,6 +224,7 @@ ifeq ($(ARCH),m68knommu)
endif
KCONFIG_CONFIG ?= .config
+export KCONFIG_CONFIG
# SHELL used by kbuild
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
diff --git a/arch/Kconfig b/arch/Kconfig
index 8bf0fa652eb6..f78c2be4242b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -175,4 +175,7 @@ config HAVE_PERF_EVENTS_NMI
config HAVE_ARCH_JUMP_LABEL
bool
+config HAVE_ARCH_MUTEX_CPU_RELAX
+ bool
+
source "kernel/gcov/Kconfig"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e75c4a2..e9a7343a5aa9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
bool
default y
select HAVE_AOUT
+ select HAVE_DMA_API_DEBUG
select HAVE_IDE
select HAVE_MEMBLOCK
select RTC_LIB
@@ -9,11 +10,12 @@ config ARM
select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_KGDB
- select HAVE_KPROBES if (!XIP_KERNEL)
+ select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL)
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
+ select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO
@@ -23,6 +25,7 @@ config ARM
select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
+ select HAVE_C_RECORDMCOUNT
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -34,9 +37,15 @@ config ARM
config HAVE_PWM
bool
+config MIGHT_HAVE_PCI
+ bool
+
config SYS_SUPPORTS_APM_EMULATION
bool
+config HAVE_SCHED_CLOCK
+ bool
+
config GENERIC_GPIO
bool
@@ -221,7 +230,7 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARM_AMBA
select ARCH_HAS_CPUFREQ
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ICST
select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE
@@ -231,7 +240,8 @@ config ARCH_INTEGRATOR
config ARCH_REALVIEW
bool "ARM Ltd. RealView family"
select ARM_AMBA
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
+ select HAVE_SCHED_CLOCK
select ICST
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -245,7 +255,8 @@ config ARCH_VERSATILE
bool "ARM Ltd. Versatile family"
select ARM_AMBA
select ARM_VIC
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
+ select HAVE_SCHED_CLOCK
select ICST
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -259,9 +270,10 @@ config ARCH_VEXPRESS
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
select ARM_TIMER_SP804
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select HAVE_CLK
+ select HAVE_SCHED_CLOCK
select ICST
select PLAT_VERSATILE
help
@@ -280,7 +292,7 @@ config ARCH_BCMRING
depends on MMU
select CPU_V6
select ARM_AMBA
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
help
@@ -298,6 +310,7 @@ config ARCH_CNS3XXX
select CPU_V6
select GENERIC_CLOCKEVENTS
select ARM_GIC
+ select MIGHT_HAVE_PCI
select PCI_DOMAINS if PCI
help
Support for Cavium Networks CNS3XXX platform.
@@ -327,7 +340,7 @@ config ARCH_EP93XX
select CPU_ARM920T
select ARM_AMBA
select ARM_VIC
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_USES_GETTIMEOFFSET
@@ -347,14 +360,22 @@ config ARCH_MXC
bool "Freescale MXC/iMX-based"
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
help
Support for Freescale MXC/iMX-based family of processors
+config ARCH_MXS
+ bool "Freescale MXS-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLKDEV
+ help
+ Support for Freescale MXS-based family of processors
+
config ARCH_STMP3XXX
bool "Freescale STMP3xxx"
select CPU_ARM926T
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select USB_ARCH_HAS_EHCI
@@ -433,6 +454,8 @@ config ARCH_IXP4XX
select CPU_XSCALE
select GENERIC_GPIO
select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select MIGHT_HAVE_PCI
select DMABOUNCE if PCI
help
Support for Intel's IXP4XX (XScale) family of processors.
@@ -472,7 +495,7 @@ config ARCH_LPC32XX
select HAVE_IDE
select ARM_AMBA
select USB_ARCH_HAS_OHCI
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
@@ -506,8 +529,9 @@ config ARCH_MMP
bool "Marvell PXA168/910/MMP2"
depends on MMU
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select PLAT_PXA
select SPARSE_IRQ
@@ -539,7 +563,7 @@ config ARCH_W90X900
bool "Nuvoton W90X900 CPU"
select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
help
Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -553,7 +577,7 @@ config ARCH_W90X900
config ARCH_NUC93X
bool "Nuvoton NUC93X CPU"
select CPU_ARM926T
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
help
Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
low-power and high performance MPEG-4/JPEG multimedia controller chip.
@@ -564,7 +588,8 @@ config ARCH_TEGRA
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select HAVE_CLK
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
+ select HAVE_SCHED_CLOCK
select ARCH_HAS_BARRIERS if CACHE_L2X0
select ARCH_HAS_CPUFREQ
help
@@ -574,7 +599,7 @@ config ARCH_TEGRA
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
select CPU_ARM926T
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ARCH_USES_GETTIMEOFFSET
help
This enables support for Philips PNX4008 mobile platform.
@@ -584,9 +609,10 @@ config ARCH_PXA
depends on MMU
select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select PLAT_PXA
select SPARSE_IRQ
@@ -606,9 +632,14 @@ config ARCH_MSM
(clock and power control, etc).
config ARCH_SHMOBILE
- bool "Renesas SH-Mobile"
+ bool "Renesas SH-Mobile / R-Mobile"
+ select HAVE_CLK
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select NO_IOPORT
+ select SPARSE_IRQ
help
- Support for Renesas's SH-Mobile ARM platforms
+ Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
config ARCH_RPC
bool "RiscPC"
@@ -635,6 +666,7 @@ config ARCH_SA1100
select CPU_FREQ
select GENERIC_CLOCKEVENTS
select HAVE_CLK
+ select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select ARCH_REQUIRE_GPIOLIB
help
@@ -738,6 +770,7 @@ config ARCH_S5PV310
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
+ select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
@@ -761,7 +794,7 @@ config ARCH_TCC_926
bool "Telechips TCC ARM926-based systems"
select CPU_ARM926T
select HAVE_CLK
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
help
Support for Telechips TCC ARM926-based systems.
@@ -781,11 +814,12 @@ config ARCH_U300
bool "ST-Ericsson U300 Series"
depends on MMU
select CPU_ARM926T
+ select HAVE_SCHED_CLOCK
select HAVE_TCM
select ARM_AMBA
select ARM_VIC
select GENERIC_CLOCKEVENTS
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_GPIO
help
Support for ST-Ericsson U300 series mobile platforms.
@@ -795,8 +829,9 @@ config ARCH_U8500
select CPU_V7
select ARM_AMBA
select GENERIC_CLOCKEVENTS
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_CPUFREQ
help
Support for ST-Ericsson's Ux500 architecture
@@ -805,7 +840,7 @@ config ARCH_NOMADIK
select ARM_AMBA
select ARM_VIC
select CPU_ARM926T
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
help
@@ -817,7 +852,7 @@ config ARCH_DAVINCI
select ARCH_REQUIRE_GPIOLIB
select ZONE_DMA
select HAVE_IDE
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_ALLOCATOR
select ARCH_HAS_HOLES_MEMORYMODEL
help
@@ -829,6 +864,7 @@ config ARCH_OMAP
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
select ARCH_HAS_HOLES_MEMORYMODEL
help
Support for TI's OMAP platform (OMAP1/2/3/4).
@@ -837,7 +873,7 @@ config PLAT_SPEAR
bool "ST SPEAr"
select ARM_AMBA
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select HAVE_CLK
help
@@ -902,6 +938,8 @@ source "arch/arm/mach-mv78xx0/Kconfig"
source "arch/arm/plat-mxc/Kconfig"
+source "arch/arm/mach-mxs/Kconfig"
+
source "arch/arm/mach-netx/Kconfig"
source "arch/arm/mach-nomadik/Kconfig"
@@ -982,9 +1020,11 @@ config ARCH_ACORN
config PLAT_IOP
bool
select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
config PLAT_ORION
bool
+ select HAVE_SCHED_CLOCK
config PLAT_PXA
bool
@@ -999,8 +1039,8 @@ source arch/arm/mm/Kconfig
config IWMMXT
bool "Enable iWMMXt support"
- depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
- default y if PXA27x || PXA3xx || ARCH_MMP
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
+ default y if PXA27x || PXA3xx || PXA95x || ARCH_MMP
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
@@ -1017,6 +1057,11 @@ config CPU_HAS_PMU
default y
bool
+config MULTI_IRQ_HANDLER
+ bool
+ help
+ Allow each machine to specify it's own IRQ handler at run time.
+
if !MMU
source "arch/arm/Kconfig-nommu"
endif
@@ -1164,7 +1209,7 @@ config ISA_DMA_API
bool
config PCI
- bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX
+ bool "PCI support" if MIGHT_HAVE_PCI
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
@@ -1175,6 +1220,12 @@ config PCI_DOMAINS
bool
depends on PCI
+config PCI_NANOENGINE
+ bool "BSE nanoEngine PCI support"
+ depends on SA1100_NANOENGINE
+ help
+ Enable PCI on the BSE nanoEngine board.
+
config PCI_SYSCALL
def_bool PCI
@@ -1205,10 +1256,11 @@ config SMP
depends on EXPERIMENTAL
depends on GENERIC_CLOCKEVENTS
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
- MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
- ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
+ ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
+ ARCH_MSM_SCORPIONMP
select USE_GENERIC_SMP_HELPERS
- select HAVE_ARM_SCU
+ select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1229,7 +1281,7 @@ config SMP
config SMP_ON_UP
bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
depends on EXPERIMENTAL
- depends on SMP && !XIP && !THUMB2_KERNEL
+ depends on SMP && !XIP
default y
help
SMP kernels contain instructions which fail on non-SMP processors.
@@ -1248,6 +1300,7 @@ config HAVE_ARM_SCU
config HAVE_ARM_TWD
bool
depends on SMP
+ select TICK_ONESHOT
help
This options enables support for the ARM timer and watchdog unit
@@ -1283,6 +1336,7 @@ config NR_CPUS
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && HOTPLUG && EXPERIMENTAL
+ depends on !ARCH_MSM
help
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu.
@@ -1291,7 +1345,7 @@ config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP
default y
- select HAVE_ARM_TWD
+ select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
@@ -1310,8 +1364,8 @@ config HZ
default 100
config THUMB2_KERNEL
- bool "Compile the kernel in Thumb-2 mode"
- depends on CPU_V7 && EXPERIMENTAL
+ bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
+ depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
select AEABI
select ARM_ASM_UNIFIED
help
@@ -1524,6 +1578,7 @@ config SECCOMP
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
@@ -1650,6 +1705,19 @@ config ATAGS_PROC
Should the atags used to boot the kernel be exported in an "atags"
file in procfs. Useful with kexec.
+config CRASH_DUMP
+ bool "Build kdump crash kernel (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Generate crash dump after being started by kexec. This should
+ be normally only set in special crash dump kernels which are
+ loaded in the main kernel with kexec-tools into a specially
+ reserved region and then later executed after a crash by
+ kdump/kexec. The crash dump kernel must be compiled to a
+ memory address not used by the main kernel
+
+ For more details see Documentation/kdump/kdump.txt
+
config AUTO_ZRELADDR
bool "Auto calculation of the decompressed kernel image address"
depends on !ZBOOT_ROM && !ARCH_U300
@@ -1707,7 +1775,7 @@ config CPU_FREQ_S3C
Internal configuration node for common cpufreq on Samsung SoC
config CPU_FREQ_S3C24XX
- bool "CPUfreq driver for Samsung S3C24XX series CPUs"
+ bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
select CPU_FREQ_S3C
help
@@ -1719,7 +1787,7 @@ config CPU_FREQ_S3C24XX
If in doubt, say N.
config CPU_FREQ_S3C24XX_PLL
- bool "Support CPUfreq changing of PLL frequency"
+ bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
help
Compile in support for changing the PLL frequency from the
@@ -1759,7 +1827,7 @@ comment "At least one emulation must be selected"
config FPE_NWFPE
bool "NWFPE math emulation"
- depends on !AEABI || OABI_COMPAT
+ depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
---help---
Say Y to include the NWFPE floating point emulator in the kernel.
This is necessary to run most binaries. Linux does not currently
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 2fd0b99afc4b..494224a9b459 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -23,7 +23,7 @@ config STRICT_DEVMEM
config FRAME_POINTER
bool
depends on !THUMB2_KERNEL
- default y if !ARM_UNWIND
+ default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER
help
If you say N here, the resulting kernel will be slightly smaller and
faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
@@ -31,7 +31,7 @@ config FRAME_POINTER
reported is severely limited.
config ARM_UNWIND
- bool "Enable stack unwinding support"
+ bool "Enable stack unwinding support (EXPERIMENTAL)"
depends on AEABI && EXPERIMENTAL
default y
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index b87aed028eef..c22c1adfedd6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -154,10 +154,11 @@ machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
machine-$(CONFIG_ARCH_MX1) := imx
machine-$(CONFIG_ARCH_MX2) := imx
-machine-$(CONFIG_ARCH_MX25) := mx25
+machine-$(CONFIG_ARCH_MX25) := imx
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
+machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 4a590f4113e2..4d26f2c52a75 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -70,12 +70,7 @@ else
$(obj)/uImage: LOADADDR=$(ZRELADDR)
endif
-ifeq ($(CONFIG_THUMB2_KERNEL),y)
-# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
-$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
-else
$(obj)/uImage: STARTADDR=$(LOADADDR)
-endif
$(obj)/uImage: $(obj)/zImage FORCE
$(call if_changed,uimage)
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
index 8b0de41c3dcb..78b508075161 100644
--- a/arch/arm/boot/bootp/init.S
+++ b/arch/arm/boot/bootp/init.S
@@ -73,6 +73,8 @@ move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
.size _start, . - _start
+ .align
+
.type data,#object
data: .word initrd_start @ source initrd address
.word initrd_phys @ destination initrd address
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 65a7c1c588a9..0a8f748e506a 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -45,6 +45,10 @@ else
endif
endif
+ifeq ($(CONFIG_ARCH_SHMOBILE),y)
+OBJS += head-shmobile.o
+endif
+
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
new file mode 100644
index 000000000000..30973b76e6ae
--- /dev/null
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -0,0 +1,53 @@
+/*
+ * The head-file for SH-Mobile ARM platforms
+ *
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Simon Horman <horms@verge.net.au>
+ *
+ * This program is free software; 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
+ */
+
+#ifdef CONFIG_ZBOOT_ROM
+
+ .section ".start", "ax"
+
+ /* load board-specific initialization code */
+#include <mach/zboot.h>
+
+ b 1f
+__atags:@ tag #1
+ .long 12 @ tag->hdr.size = tag_size(tag_core);
+ .long 0x54410001 @ tag->hdr.tag = ATAG_CORE;
+ .long 0 @ tag->u.core.flags = 0;
+ .long 0 @ tag->u.core.pagesize = 0;
+ .long 0 @ tag->u.core.rootdev = 0;
+ @ tag #2
+ .long 8 @ tag->hdr.size = tag_size(tag_mem32);
+ .long 0x54410002 @ tag->hdr.tag = ATAG_MEM;
+ .long CONFIG_MEMORY_SIZE @ tag->u.mem.size = CONFIG_MEMORY_SIZE;
+ .long CONFIG_MEMORY_START @ @ tag->u.mem.start = CONFIG_MEMORY_START;
+ @ tag #3
+ .long 0 @ tag->hdr.size = 0
+ .long 0 @ tag->hdr.tag = ATAG_NONE;
+1:
+
+ /* Set board ID necessary for boot */
+ ldr r7, 1f @ Set machine type register
+ adr r8, __atags @ Set atag register
+ b 2f
+
+1 : .long MACH_TYPE
+2 :
+
+#endif /* CONFIG_ZBOOT_ROM */
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9be21ba648cd..7193884ed8b0 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -125,9 +125,13 @@ wait: mrc p14, 0, pc, c0, c1, 0
* sort out different calling conventions
*/
.align
+ .arm @ Always enter in ARM state
start:
.type start,#function
- .rept 8
+ THUMB( adr r12, BSYM(1f) )
+ THUMB( bx r12 )
+ THUMB( .rept 6 )
+ ARM( .rept 8 )
mov r0, r0
.endr
@@ -135,6 +139,7 @@ start:
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
+ THUMB( .thumb )
1: mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer
@@ -174,7 +179,8 @@ not_angel:
ldr sp, [r0, #28]
#ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address
- and r4, pc, #0xf8000000
+ mov r4, pc
+ and r4, r4, #0xf8000000
add r4, r4, #TEXT_OFFSET
#else
ldr r4, =zreladdr
@@ -445,7 +451,8 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
*/
mov r1, #0x1e
orr r1, r1, #3 << 10
- mov r2, pc, lsr #20
+ mov r2, pc
+ mov r2, r2, lsr #20
orr r1, r1, r2, lsl #20
add r0, r3, r2, lsl #2
str r1, [r0], #4
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 0a34c8186924..778655f0257a 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -37,7 +37,3 @@ config SHARP_PARAM
config SHARP_SCOOP
bool
-
-config COMMON_CLKDEV
- bool
- select HAVE_CLK
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e6e8664a9413..e7521bca2c35 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o
+obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index cc0a932bbea9..e5681636626f 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -328,7 +328,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
* substitute the safe buffer for the unsafe one.
* (basically move the buffer from an unsafe area to a safe one)
*/
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir)
{
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -338,7 +338,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
return map_single(dev, ptr, size, dir);
}
-EXPORT_SYMBOL(dma_map_single);
+EXPORT_SYMBOL(__dma_map_single);
/*
* see if a mapped address was really a "safe" buffer and if so, copy
@@ -346,7 +346,7 @@ EXPORT_SYMBOL(dma_map_single);
* the safe buffer. (basically return things back to the way they
* should be)
*/
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -354,9 +354,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
unmap_single(dev, dma_addr, size, dir);
}
-EXPORT_SYMBOL(dma_unmap_single);
+EXPORT_SYMBOL(__dma_unmap_single);
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
+dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
@@ -372,7 +372,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
return map_single(dev, page_address(page) + offset, size, dir);
}
-EXPORT_SYMBOL(dma_map_page);
+EXPORT_SYMBOL(__dma_map_page);
/*
* see if a mapped address was really a "safe" buffer and if so, copy
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(dma_map_page);
* the safe buffer. (basically return things back to the way they
* should be)
*/
-void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -388,7 +388,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
unmap_single(dev, dma_addr, size, dir);
}
-EXPORT_SYMBOL(dma_unmap_page);
+EXPORT_SYMBOL(__dma_unmap_page);
int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
unsigned long off, size_t sz, enum dma_data_direction dir)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 772f95f1aecd..0b89ef001330 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -35,6 +35,9 @@
static DEFINE_SPINLOCK(irq_controller_lock);
+/* Address of GIC 0 CPU interface */
+void __iomem *gic_cpu_base_addr __read_mostly;
+
struct gic_chip_data {
unsigned int irq_offset;
void __iomem *dist_base;
@@ -45,7 +48,7 @@ struct gic_chip_data {
#define MAX_GIC_NR 1
#endif
-static struct gic_chip_data gic_data[MAX_GIC_NR];
+static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
static inline void __iomem *gic_dist_base(unsigned int irq)
{
@@ -146,9 +149,15 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
unsigned int shift = (irq % 4) * 8;
unsigned int cpu = cpumask_first(mask_val);
u32 val;
+ struct irq_desc *desc;
spin_lock(&irq_controller_lock);
- irq_desc[irq].node = cpu;
+ desc = irq_to_desc(irq);
+ if (desc == NULL) {
+ spin_unlock(&irq_controller_lock);
+ return -EINVAL;
+ }
+ desc->node = cpu;
val = readl(reg) & ~(0xff << shift);
val |= 1 << (cpu + shift);
writel(val, reg);
@@ -207,68 +216,65 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
set_irq_chained_handler(irq, gic_handle_cascade_irq);
}
-void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
- unsigned int irq_start)
+static void __init gic_dist_init(struct gic_chip_data *gic,
+ unsigned int irq_start)
{
- unsigned int max_irq, i;
+ unsigned int gic_irqs, irq_limit, i;
+ void __iomem *base = gic->dist_base;
u32 cpumask = 1 << smp_processor_id();
- if (gic_nr >= MAX_GIC_NR)
- BUG();
-
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;
- gic_data[gic_nr].dist_base = base;
- gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
-
writel(0, base + GIC_DIST_CTRL);
/*
* Find out how many interrupts are supported.
- */
- max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
- max_irq = (max_irq + 1) * 32;
-
- /*
* The GIC only supports up to 1020 interrupt sources.
- * Limit this to either the architected maximum, or the
- * platform maximum.
*/
- if (max_irq > max(1020, NR_IRQS))
- max_irq = max(1020, NR_IRQS);
+ gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
/*
* Set all global interrupts to be level triggered, active low.
*/
- for (i = 32; i < max_irq; i += 16)
+ for (i = 32; i < gic_irqs; i += 16)
writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
/*
* Set all global interrupts to this CPU only.
*/
- for (i = 32; i < max_irq; i += 4)
+ for (i = 32; i < gic_irqs; i += 4)
writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
/*
* Set priority on all global interrupts.
*/
- for (i = 32; i < max_irq; i += 4)
+ for (i = 32; i < gic_irqs; i += 4)
writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
/*
* Disable all interrupts. Leave the PPI and SGIs alone
* as these enables are banked registers.
*/
- for (i = 32; i < max_irq; i += 32)
+ for (i = 32; i < gic_irqs; i += 32)
writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
/*
+ * Limit number of interrupts registered to the platform maximum
+ */
+ irq_limit = gic->irq_offset + gic_irqs;
+ if (WARN_ON(irq_limit > NR_IRQS))
+ irq_limit = NR_IRQS;
+
+ /*
* Setup the Linux IRQ subsystem.
*/
- for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
+ for (i = irq_start; i < irq_limit; i++) {
set_irq_chip(i, &gic_chip);
- set_irq_chip_data(i, &gic_data[gic_nr]);
+ set_irq_chip_data(i, gic);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
@@ -276,19 +282,12 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
writel(1, base + GIC_DIST_CTRL);
}
-void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
+static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
- void __iomem *dist_base;
+ void __iomem *dist_base = gic->dist_base;
+ void __iomem *base = gic->cpu_base;
int i;
- if (gic_nr >= MAX_GIC_NR)
- BUG();
-
- dist_base = gic_data[gic_nr].dist_base;
- BUG_ON(!dist_base);
-
- gic_data[gic_nr].cpu_base = base;
-
/*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
@@ -306,6 +305,42 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
writel(1, base + GIC_CPU_CTRL);
}
+void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ void __iomem *dist_base, void __iomem *cpu_base)
+{
+ struct gic_chip_data *gic;
+
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic = &gic_data[gic_nr];
+ gic->dist_base = dist_base;
+ gic->cpu_base = cpu_base;
+ gic->irq_offset = (irq_start - 1) & ~31;
+
+ if (gic_nr == 0)
+ gic_cpu_base_addr = cpu_base;
+
+ gic_dist_init(gic, irq_start);
+ gic_cpu_init(gic);
+}
+
+void __cpuinit gic_secondary_init(unsigned int gic_nr)
+{
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic_cpu_init(&gic_data[gic_nr]);
+}
+
+void __cpuinit gic_enable_ppi(unsigned int irq)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ irq_to_desc(irq)->status |= IRQ_NOPROBE;
+ gic_unmask_irq(irq);
+ local_irq_restore(flags);
+}
+
#ifdef CONFIG_SMP
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 1bec96e85196..42ff90b46dfb 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
return pci_scan_bus(nr, &it8152_ops, sys);
}
+EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/common/timer-sp.c
index fb0d1c299718..6ef3342153b9 100644
--- a/arch/arm/plat-versatile/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/plat-versatile/timer-sp.c
+ * linux/arch/arm/common/timer-sp.c
*
* Copyright (C) 1999 - 2003 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
@@ -26,8 +26,6 @@
#include <asm/hardware/arm_timer.h>
-#include <plat/timer-sp.h>
-
/*
* These timers are currently always setup to be clocked at 1MHz.
*/
@@ -46,7 +44,6 @@ static struct clocksource clocksource_sp804 = {
.rating = 200,
.read = sp804_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -63,8 +60,7 @@ void __init sp804_clocksource_init(void __iomem *base)
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
clksrc_base + TIMER_CTRL);
- cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift);
- clocksource_register(cs);
+ clocksource_register_khz(cs, TIMER_FREQ_KHZ);
}
diff --git a/arch/arm/configs/ag5evm_defconfig b/arch/arm/configs/ag5evm_defconfig
new file mode 100644
index 000000000000..2b9cf56db363
--- /dev/null
+++ b/arch/arm/configs/ag5evm_defconfig
@@ -0,0 +1,83 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+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_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_AG5EVM=y
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty0 console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_FTRACE is not set
diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig
deleted file mode 100644
index 75de45e949b9..000000000000
--- a/arch/arm/configs/ams_delta_defconfig
+++ /dev/null
@@ -1,121 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_TREE_PREEMPT_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_LBDAF is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_MBOX_FWK=m
-CONFIG_MACH_AMS_DELTA=y
-CONFIG_OMAP_ARM_150MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=/dev/ram0 initrd=0x11c00000,4M"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-# CONFIG_SUSPEND is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IPV6=y
-# CONFIG_FW_LOADER is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_AMS_DELTA=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_USB_CATC=y
-CONFIG_USB_KAWETH=y
-CONFIG_USB_PEGASUS=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_OMAP=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_OMAP=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_6x11=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_AMS_DELTA=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_AMS_DELTA=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_NFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
diff --git a/arch/arm/configs/at91rm9200_defconfig b/arch/arm/configs/at91rm9200_defconfig
new file mode 100644
index 000000000000..38cb7c985426
--- /dev/null
+++ b/arch/arm/configs/at91rm9200_defconfig
@@ -0,0 +1,341 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_MACH_ONEARM=y
+CONFIG_ARCH_AT91RM9200DK=y
+CONFIG_MACH_AT91RM9200EK=y
+CONFIG_MACH_CSB337=y
+CONFIG_MACH_CSB637=y
+CONFIG_MACH_CARMEVA=y
+CONFIG_MACH_ATEB9200=y
+CONFIG_MACH_KB9200=y
+CONFIG_MACH_PICOTUX2XX=y
+CONFIG_MACH_KAFA=y
+CONFIG_MACH_ECBAT91=y
+CONFIG_MACH_YL9200=y
+CONFIG_MACH_CPUAT91=y
+CONFIG_MACH_ECO920=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_AT91_CF=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_EEPROM_LEGACY=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_PHYLIB=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91RM9200_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_MCT_U232=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_REISERFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+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=y
+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=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
deleted file mode 100644
index 4438e64f3bfb..000000000000
--- a/arch/arm/configs/at91rm9200dk_defconfig
+++ /dev/null
@@ -1,72 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_ECO920=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
deleted file mode 100644
index ccd517c64bc7..000000000000
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ /dev/null
@@ -1,73 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_AT91RM9200EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_S1D13XXX=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
deleted file mode 100644
index 1b0e9a1689bb..000000000000
--- a/arch/arm/configs/ateb9200_defconfig
+++ /dev/null
@@ -1,131 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ATEB9200=y
-CONFIG_PCCARD=m
-CONFIG_AT91_CF=m
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_GL620A=y
-CONFIG_USB_NET_PLUSB=y
-CONFIG_USB_NET_RNDIS_HOST=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_USB_HID=m
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_GADGET=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-CONFIG_REISERFS_FS=m
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRC16=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig
deleted file mode 100644
index ac64dbd8a49c..000000000000
--- a/arch/arm/configs/carmeva_defconfig
+++ /dev/null
@@ -1,47 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_HOTPLUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CARMEVA=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_DNOTIFY is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig
deleted file mode 100644
index 022aeb55b676..000000000000
--- a/arch/arm/configs/cpuat91_defconfig
+++ /dev/null
@@ -1,112 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CPUAT91=y
-CONFIG_AT91_TIMER_HZ=100
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=y
-CONFIG_MINIX_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
deleted file mode 100644
index a24c448840c4..000000000000
--- a/arch/arm/configs/csb337_defconfig
+++ /dev/null
@@ -1,104 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB337=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
-# CONFIG_RTC_INTF_SYSFS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
deleted file mode 100644
index 98552adac5fb..000000000000
--- a/arch/arm/configs/csb637_defconfig
+++ /dev/null
@@ -1,98 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB637=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig
deleted file mode 100644
index 6bb6abdcea8c..000000000000
--- a/arch/arm/configs/ecbat91_defconfig
+++ /dev/null
@@ -1,99 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ECBAT91=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="rootfstype=reiserfs root=/dev/mmcblk0p1 console=ttyS0,115200n8 rootdelay=1"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IPV6 is not set
-CONFIG_CFG80211=y
-CONFIG_MAC80211=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/htcherald_defconfig b/arch/arm/configs/htcherald_defconfig
deleted file mode 100644
index edfa1c0daab0..000000000000
--- a/arch/arm/configs/htcherald_defconfig
+++ /dev/null
@@ -1,73 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_ARCH_OMAP850=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_MACH_HERALD=y
-CONFIG_OMAP_ARM_195MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-CONFIG_CPU_ARM925T=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 ip=dhcp"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=m
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-# CONFIG_USB_ETH_RNDIS is not set
-CONFIG_MMC=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_ZLIB=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
deleted file mode 100644
index 896dbe00dc6e..000000000000
--- a/arch/arm/configs/kafa_defconfig
+++ /dev/null
@@ -1,61 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KAFA=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20800000,10M root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
deleted file mode 100644
index 9f906a85f5c2..000000000000
--- a/arch/arm/configs/kb9202_defconfig
+++ /dev/null
@@ -1,127 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_AUDIT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KB9200=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x10000000
-CONFIG_ZBOOT_ROM_BSS=0x20040000
-CONFIG_CMDLINE="noinitrd root=/dev/mtdblock0 rootfstype=jffs2 mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_ATMEL_TCLIB=y
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_GENERIC is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/mackerel_defconfig b/arch/arm/configs/mackerel_defconfig
new file mode 100644
index 000000000000..306a2e2d3622
--- /dev/null
+++ b/arch/arm/configs/mackerel_defconfig
@@ -0,0 +1,138 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# 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_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH7372=y
+CONFIG_MACH_MACKEREL=y
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_FORCE_MAX_ZONEORDER=15
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+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_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_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig
index f0c339fd5d21..e648ea3429be 100644
--- a/arch/arm/configs/mx3_defconfig
+++ b/arch/arm/configs/mx3_defconfig
@@ -84,6 +84,7 @@ CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IMX=y
+CONFIG_SPI=y
CONFIG_W1=y
CONFIG_W1_MASTER_MXC=y
CONFIG_W1_SLAVE_THERM=y
diff --git a/arch/arm/configs/n770_defconfig b/arch/arm/configs/n770_defconfig
deleted file mode 100644
index 993e94df5d0e..000000000000
--- a/arch/arm/configs/n770_defconfig
+++ /dev/null
@@ -1,138 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_OMAP_MUX is not set
-CONFIG_OMAP_MBOX_FWK=y
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_OMAP_DM_TIMER=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_NOKIA770=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-CONFIG_OMAP_ARM_216MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 time"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_HIDP=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CONNECTOR=y
-# CONFIG_PROC_EVENTS is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_SCSI=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-CONFIG_NETDEVICES=y
-CONFIG_TUN=y
-CONFIG_NET_ETHERNET=y
-CONFIG_USB_USBNET=y
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_PPP=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=y
-CONFIG_I2C_OMAP=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP_UWIRE=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_OMAP=y
-CONFIG_FB_OMAP_LCDC_EXTERNAL=y
-CONFIG_FB_OMAP_LCDC_HWA742=y
-CONFIG_FB_OMAP_MANUAL_UPDATE=y
-CONFIG_FB_OMAP_LCD_MIPID=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-CONFIG_SND_DUMMY=y
-CONFIG_SND_USB_AUDIO=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OTG=y
-# CONFIG_USB_OTG_WHITELIST is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_PL2303=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_SECURITY=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
new file mode 100644
index 000000000000..a350cc6bfe6a
--- /dev/null
+++ b/arch/arm/configs/omap1_defconfig
@@ -0,0 +1,286 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_SHMEM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLOB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_OMAP=y
+CONFIG_ARCH_OMAP1=y
+CONFIG_OMAP_RESET_CLOCKS=y
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MBOX_FWK=y
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_DM_TIMER=y
+CONFIG_ARCH_OMAP730=y
+CONFIG_ARCH_OMAP850=y
+CONFIG_ARCH_OMAP16XX=y
+CONFIG_MACH_OMAP_INNOVATOR=y
+CONFIG_MACH_OMAP_H2=y
+CONFIG_MACH_OMAP_H3=y
+CONFIG_MACH_OMAP_HTCWIZARD=y
+CONFIG_MACH_HERALD=y
+CONFIG_MACH_OMAP_OSK=y
+CONFIG_MACH_OMAP_PERSEUS2=y
+CONFIG_MACH_OMAP_FSAMPLE=y
+CONFIG_MACH_VOICEBLUE=y
+CONFIG_MACH_OMAP_PALMTE=y
+CONFIG_MACH_OMAP_PALMZ71=y
+CONFIG_MACH_OMAP_PALMTT=y
+CONFIG_MACH_SX1=y
+CONFIG_MACH_NOKIA770=y
+CONFIG_MACH_AMS_DELTA=y
+CONFIG_MACH_OMAP_GENERIC=y
+CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
+CONFIG_OMAP_ARM_216MHZ=y
+CONFIG_OMAP_ARM_195MHZ=y
+CONFIG_OMAP_ARM_192MHZ=y
+CONFIG_OMAP_ARM_182MHZ=y
+CONFIG_OMAP_ARM_168MHZ=y
+# CONFIG_OMAP_ARM_60MHZ is not set
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_OMAP_CF=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 rootfstype=jffs2"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
+CONFIG_NETFILTER=y
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_HIDP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_CONNECTOR=y
+# CONFIG_PROC_EVENTS is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_NAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_USB_CATC=y
+CONFIG_USB_KAWETH=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_RTL8150=y
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_OMAP_UWIRE=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_VIRTUAL=y
+CONFIG_FB_OMAP=y
+CONFIG_FB_OMAP_LCDC_EXTERNAL=y
+CONFIG_FB_OMAP_LCDC_HWA742=y
+CONFIG_FB_OMAP_MANUAL_UPDATE=y
+CONFIG_FB_OMAP_LCD_MIPID=y
+CONFIG_FB_OMAP_BOOTLOADER_INIT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_DUMMY=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_TEST=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_OMAP=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_OMAP=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=866
+CONFIG_FAT_DEFAULT_IOCHARSET="koi8-r"
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/omap_generic_1510_defconfig b/arch/arm/configs/omap_generic_1510_defconfig
deleted file mode 100644
index 0e42ba4ede9d..000000000000
--- a/arch/arm/configs/omap_generic_1510_defconfig
+++ /dev/null
@@ -1,84 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_ARM_168MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS2,115200 root=0803 ro init=/bin/sh"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/omap_generic_1610_defconfig b/arch/arm/configs/omap_generic_1610_defconfig
deleted file mode 100644
index 5e536cf0f9f7..000000000000
--- a/arch/arm/configs/omap_generic_1610_defconfig
+++ /dev/null
@@ -1,87 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_ARM_192MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS2,115200 root=0803 ro init=/bin/sh"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/omap_generic_1710_defconfig b/arch/arm/configs/omap_generic_1710_defconfig
deleted file mode 100644
index c0867b1d9815..000000000000
--- a/arch/arm/configs/omap_generic_1710_defconfig
+++ /dev/null
@@ -1,75 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-# CONFIG_OMAP_MUX is not set
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_ARM_192MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=tty0 console=ttyS2,115200 root=0801"
-CONFIG_FPE_NWFPE=y
-CONFIG_ARTHUR=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_ALI_M5632=y
-# CONFIG_USB_BELKIN is not set
-# CONFIG_USB_ARMLINUX is not set
-CONFIG_PPP=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_SECURITY=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
deleted file mode 100644
index e2de2aa17e62..000000000000
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ /dev/null
@@ -1,109 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_OMAP_DM_TIMER=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_H2=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=/dev/ram0 rw initrd=0x10600000,8M ramdisk_size=8192"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEBUG_DRIVER=y
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=3
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_PPP=y
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=y
-CONFIG_I2C_OMAP=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP_UWIRE=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OTG=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_TEST=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/omap_innovator_1510_defconfig b/arch/arm/configs/omap_innovator_1510_defconfig
deleted file mode 100644
index 265af2669ede..000000000000
--- a/arch/arm/configs/omap_innovator_1510_defconfig
+++ /dev/null
@@ -1,102 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_MACH_OMAP_INNOVATOR=y
-CONFIG_OMAP_ARM_168MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200n8 root=/dev/nfs ip=bootp noinitrd"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/omap_innovator_1610_defconfig b/arch/arm/configs/omap_innovator_1610_defconfig
deleted file mode 100644
index cc7fbf84ddd9..000000000000
--- a/arch/arm/configs/omap_innovator_1610_defconfig
+++ /dev/null
@@ -1,58 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_INNOVATOR=y
-CONFIG_OMAP_ARM_192MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_CPU_DCACHE_WRITETHROUGH=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=tty0 console=ttyS0,115200 initrd=0x10200000,8M root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
diff --git a/arch/arm/configs/omap_osk_5912_defconfig b/arch/arm/configs/omap_osk_5912_defconfig
deleted file mode 100644
index 9105de7661f9..000000000000
--- a/arch/arm/configs/omap_osk_5912_defconfig
+++ /dev/null
@@ -1,87 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_32K_TIMER=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_OSK=y
-CONFIG_OMAP_ARM_192MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_OMAP_CF=y
-CONFIG_NO_HZ=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x10400000,8M root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_ISO8859_1=m
diff --git a/arch/arm/configs/omap_perseus2_730_defconfig b/arch/arm/configs/omap_perseus2_730_defconfig
deleted file mode 100644
index aa777e624e23..000000000000
--- a/arch/arm/configs/omap_perseus2_730_defconfig
+++ /dev/null
@@ -1,65 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_ARCH_OMAP730=y
-# CONFIG_ARCH_OMAP15XX is not set
-CONFIG_MACH_OMAP_PERSEUS2=y
-CONFIG_OMAP_ARM_182MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 ip=dhcp"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_NAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_VIRTUAL=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
deleted file mode 100644
index 1579857aeeaa..000000000000
--- a/arch/arm/configs/onearm_defconfig
+++ /dev/null
@@ -1,80 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ONEARM=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/palmte_defconfig b/arch/arm/configs/palmte_defconfig
deleted file mode 100644
index 828d7cb9e667..000000000000
--- a/arch/arm/configs/palmte_defconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_MACH_OMAP_PALMTE=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_OMAP=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=850
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/palmtt_defconfig b/arch/arm/configs/palmtt_defconfig
deleted file mode 100644
index 31d02c48a3d9..000000000000
--- a/arch/arm/configs/palmtt_defconfig
+++ /dev/null
@@ -1,56 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_MACH_OMAP_PALMTT=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rw init=/init"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SPI=y
-CONFIG_SPI_OMAP_UWIRE=y
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_OMAP=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/palmz71_defconfig b/arch/arm/configs/palmz71_defconfig
deleted file mode 100644
index c478db6f5192..000000000000
--- a/arch/arm/configs/palmz71_defconfig
+++ /dev/null
@@ -1,53 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-z71"
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_MACH_OMAP_PALMZ71=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
-CONFIG_SPI=y
-CONFIG_SPI_OMAP_UWIRE=y
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_OMAP=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig
deleted file mode 100644
index 4c9afa478d57..000000000000
--- a/arch/arm/configs/picotux200_defconfig
+++ /dev/null
@@ -1,242 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=m
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_PICOTUX2XX=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
-CONFIG_FW_LOADER=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_EEPROM_LEGACY=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_NETDEVICES=y
-CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-CONFIG_HWMON=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=m
-CONFIG_HID=m
-CONFIG_USB=m
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_MMC=m
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=m
-CONFIG_RTC_DRV_AT91RM9200=m
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=m
-CONFIG_SMB_FS=m
-CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_AMIGA_PARTITION=y
-CONFIG_NLS_DEFAULT="utf-8"
-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_DEBUG_KERNEL=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_LL=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/sx1_defconfig b/arch/arm/configs/sx1_defconfig
deleted file mode 100644
index 20a861877a33..000000000000
--- a/arch/arm/configs/sx1_defconfig
+++ /dev/null
@@ -1,110 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
-# CONFIG_SHMEM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLOB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_MBOX_FWK=y
-CONFIG_MACH_SX1=y
-CONFIG_OMAP_ARM_168MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_FW_LOADER is not set
-CONFIG_CONNECTOR=y
-# CONFIG_PROC_EVENTS is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=2
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_OMAP=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_OMAP=y
-CONFIG_FB_OMAP_BOOTLOADER_INIT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_MMC=y
-CONFIG_MMC_OMAP=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=866
-CONFIG_FAT_DEFAULT_IOCHARSET="koi8-r"
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_866=y
-CONFIG_NLS_CODEPAGE_1251=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_5=y
-CONFIG_NLS_KOI8_R=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/yl9200_defconfig b/arch/arm/configs/yl9200_defconfig
deleted file mode 100644
index 30c537f61089..000000000000
--- a/arch/arm/configs/yl9200_defconfig
+++ /dev/null
@@ -1,137 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_YL9200=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=3
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_SPI=y
-CONFIG_SPI_DEBUG=y
-CONFIG_SPI_ATMEL=y
-CONFIG_FB=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_DISPLAY_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_M66592=y
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=1
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_DEBUG_KOBJECT=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 749bb6622404..bc2d2d75f706 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -18,6 +18,7 @@
#endif
#include <asm/ptrace.h>
+#include <asm/domain.h>
/*
* Endian independent macros for shifting bytes within registers.
@@ -157,16 +158,24 @@
#ifdef CONFIG_SMP
#define ALT_SMP(instr...) \
9998: instr
+/*
+ * Note: if you get assembler errors from ALT_UP() when building with
+ * CONFIG_THUMB2_KERNEL, you almost certainly need to use
+ * ALT_SMP( W(instr) ... )
+ */
#define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\
- instr ;\
+9997: instr ;\
+ .if . - 9997b != 4 ;\
+ .error "ALT_UP() content must assemble to exactly 4 bytes";\
+ .endif ;\
.popsection
#define ALT_UP_B(label) \
.equ up_b_offset, label - 9998b ;\
.pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\
- b . + up_b_offset ;\
+ W(b) . + up_b_offset ;\
.popsection
#else
#define ALT_SMP(instr...)
@@ -177,16 +186,24 @@
/*
* SMP data memory barrier
*/
- .macro smp_dmb
+ .macro smp_dmb mode
#ifdef CONFIG_SMP
#if __LINUX_ARM_ARCH__ >= 7
+ .ifeqs "\mode","arm"
ALT_SMP(dmb)
+ .else
+ ALT_SMP(W(dmb))
+ .endif
#elif __LINUX_ARM_ARCH__ == 6
ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
#else
#error Incompatible SMP platform
#endif
+ .ifeqs "\mode","arm"
ALT_UP(nop)
+ .else
+ ALT_UP(W(nop))
+ .endif
#endif
.endm
@@ -206,12 +223,12 @@
*/
#ifdef CONFIG_THUMB2_KERNEL
- .macro usraccoff, instr, reg, ptr, inc, off, cond, abort
+ .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
9999:
.if \inc == 1
- \instr\cond\()bt \reg, [\ptr, #\off]
+ \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
.elseif \inc == 4
- \instr\cond\()t \reg, [\ptr, #\off]
+ \instr\cond\()\t\().w \reg, [\ptr, #\off]
.else
.error "Unsupported inc macro argument"
.endif
@@ -246,13 +263,13 @@
#else /* !CONFIG_THUMB2_KERNEL */
- .macro usracc, instr, reg, ptr, inc, cond, rept, abort
+ .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
.rept \rept
9999:
.if \inc == 1
- \instr\cond\()bt \reg, [\ptr], #\inc
+ \instr\cond\()b\()\t \reg, [\ptr], #\inc
.elseif \inc == 4
- \instr\cond\()t \reg, [\ptr], #\inc
+ \instr\cond\()\t \reg, [\ptr], #\inc
.else
.error "Unsupported inc macro argument"
.endif
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 9d6122096fbe..75fe66bc02b4 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -23,4 +23,6 @@
#define ARCH_SLAB_MINALIGN 8
#endif
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+
#endif
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
index b56c1389b6fa..765d33222369 100644
--- a/arch/arm/include/asm/clkdev.h
+++ b/arch/arm/include/asm/clkdev.h
@@ -12,23 +12,13 @@
#ifndef __ASM_CLKDEV_H
#define __ASM_CLKDEV_H
-struct clk;
-struct device;
+#include <linux/slab.h>
-struct clk_lookup {
- struct list_head node;
- const char *dev_id;
- const char *con_id;
- struct clk *clk;
-};
+#include <mach/clkdev.h>
-struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
- const char *dev_fmt, ...);
-
-void clkdev_add(struct clk_lookup *cl);
-void clkdev_drop(struct clk_lookup *cl);
-
-void clkdev_add_table(struct clk_lookup *, size_t);
-int clk_add_alias(const char *, const char *, char *, struct device *);
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index c568da7dcae4..4fff837363ed 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,24 +5,29 @@
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
#include <asm-generic/dma-coherent.h>
#include <asm/memory.h>
+#ifdef __arch_page_to_dma
+#error Please update to __arch_pfn_to_dma
+#endif
+
/*
- * page_to_dma/dma_to_virt/virt_to_dma are architecture private functions
- * used internally by the DMA-mapping API to provide DMA addresses. They
- * must not be used by drivers.
+ * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
+ * functions used internally by the DMA-mapping API to provide DMA
+ * addresses. They must not be used by drivers.
*/
-#ifndef __arch_page_to_dma
-static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+#ifndef __arch_pfn_to_dma
+static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{
- return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+ return (dma_addr_t)__pfn_to_bus(pfn);
}
-static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
+static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{
- return pfn_to_page(__bus_to_pfn(addr));
+ return __bus_to_pfn(addr);
}
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -35,14 +40,14 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
}
#else
-static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{
- return __arch_page_to_dma(dev, page);
+ return __arch_pfn_to_dma(dev, pfn);
}
-static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
+static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{
- return __arch_dma_to_page(dev, addr);
+ return __arch_dma_to_pfn(dev, addr);
}
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -293,13 +298,13 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
/*
* The DMA API, implemented by dmabounce.c. See below for descriptions.
*/
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
enum dma_data_direction);
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
-extern dma_addr_t dma_map_page(struct device *, struct page *,
+extern dma_addr_t __dma_map_page(struct device *, struct page *,
unsigned long, size_t, enum dma_data_direction);
-extern void dma_unmap_page(struct device *, dma_addr_t, size_t,
+extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
/*
@@ -323,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
}
+static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_single_cpu_to_dev(cpu_addr, size, dir);
+ return virt_to_dma(dev, cpu_addr);
+}
+
+static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
+static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
+}
+
+static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
+ handle & ~PAGE_MASK, size, dir);
+}
+#endif /* CONFIG_DMABOUNCE */
+
/**
* dma_map_single - map a single buffer for streaming DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -340,11 +373,16 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir)
{
+ dma_addr_t addr;
+
BUG_ON(!valid_dma_direction(dir));
- __dma_single_cpu_to_dev(cpu_addr, size, dir);
+ addr = __dma_map_single(dev, cpu_addr, size, dir);
+ debug_dma_map_page(dev, virt_to_page(cpu_addr),
+ (unsigned long)cpu_addr & ~PAGE_MASK, size,
+ dir, addr, true);
- return virt_to_dma(dev, cpu_addr);
+ return addr;
}
/**
@@ -364,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
+ dma_addr_t addr;
+
BUG_ON(!valid_dma_direction(dir));
- __dma_page_cpu_to_dev(page, offset, size, dir);
+ addr = __dma_map_page(dev, page, offset, size, dir);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, false);
- return page_to_dma(dev, page) + offset;
+ return addr;
}
/**
@@ -388,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
+ debug_dma_unmap_page(dev, handle, size, dir, true);
+ __dma_unmap_single(dev, handle, size, dir);
}
/**
@@ -408,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- __dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
- size, dir);
+ debug_dma_unmap_page(dev, handle, size, dir, false);
+ __dma_unmap_page(dev, handle, size, dir);
}
-#endif /* CONFIG_DMABOUNCE */
/**
* dma_sync_single_range_for_cpu
@@ -437,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
{
BUG_ON(!valid_dma_direction(dir));
+ debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
+
if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
return;
@@ -449,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
{
BUG_ON(!valid_dma_direction(dir));
+ debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
+
if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
return;
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index cc7ef4080711..af18ceaacf5d 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -45,13 +45,17 @@
*/
#define DOMAIN_NOACCESS 0
#define DOMAIN_CLIENT 1
+#ifdef CONFIG_CPU_USE_DOMAINS
#define DOMAIN_MANAGER 3
+#else
+#define DOMAIN_MANAGER 1
+#endif
#define domain_val(dom,type) ((type) << (2*(dom)))
#ifndef __ASSEMBLY__
-#ifdef CONFIG_MMU
+#ifdef CONFIG_CPU_USE_DOMAINS
#define set_domain(x) \
do { \
__asm__ __volatile__( \
@@ -74,5 +78,28 @@
#define modify_domain(dom,type) do { } while (0)
#endif
+/*
+ * Generate the T (user) versions of the LDR/STR and related
+ * instructions (inline assembly)
+ */
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define T(instr) #instr "t"
+#else
+#define T(instr) #instr
#endif
-#endif /* !__ASSEMBLY__ */
+
+#else /* __ASSEMBLY__ */
+
+/*
+ * Generate the T (user) versions of the LDR/STR and related
+ * instructions
+ */
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define T(instr) instr ## t
+#else
+#define T(instr) instr
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* !__ASM_PROC_DOMAIN_H */
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 8bb66bca2e3e..c3cd8755e648 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -99,6 +99,8 @@ struct elf32_hdr;
extern int elf_check_arch(const struct elf32_hdr *);
#define elf_check_arch elf_check_arch
+#define vmcore_elf64_check_arch(x) (0)
+
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)
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
new file mode 100644
index 000000000000..ec0bbf79c71f
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -0,0 +1,44 @@
+/*
+ * Interrupt handling. Preserves r7, r8, r9
+ */
+ .macro arch_irq_handler_default
+ get_irqnr_preamble r5, lr
+1: get_irqnr_and_base r0, r6, r5, lr
+ movne r1, sp
+ @
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ @
+ adrne lr, BSYM(1b)
+ bne asm_do_IRQ
+
+#ifdef CONFIG_SMP
+ /*
+ * XXX
+ *
+ * this macro assumes that irqstat (r6) and base (r5) are
+ * preserved from get_irqnr_and_base above
+ */
+ ALT_SMP(test_for_ipi r0, r6, r5, lr)
+ ALT_UP_B(9997f)
+ movne r1, sp
+ adrne lr, BSYM(1b)
+ bne do_IPI
+
+#ifdef CONFIG_LOCAL_TIMERS
+ test_for_ltirq r0, r6, r5, lr
+ movne r0, sp
+ adrne lr, BSYM(1b)
+ bne do_local_timer
+#endif
+#endif
+9997:
+ .endm
+
+ .macro arch_irq_handler, symbol_name
+ .align 5
+ .global \symbol_name
+\symbol_name:
+ mov r4, lr
+ arch_irq_handler_default
+ mov pc, r4
+ .endm
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 540a044153a5..b33fe7065b38 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -13,12 +13,13 @@
#include <linux/preempt.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
+#include <asm/domain.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile__( \
- "1: ldrt %1, [%2]\n" \
+ "1: " T(ldr) " %1, [%2]\n" \
" " insn "\n" \
- "2: strt %0, [%2]\n" \
+ "2: " T(str) " %0, [%2]\n" \
" mov %0, #0\n" \
"3:\n" \
" .pushsection __ex_table,\"a\"\n" \
@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
pagefault_disable(); /* implies preempt_disable() */
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
- "1: ldrt %0, [%3]\n"
+ "1: " T(ldr) " %0, [%3]\n"
" teq %0, %1\n"
" it eq @ explicit IT needed for the 2b label\n"
- "2: streqt %2, [%3]\n"
+ "2: " T(streq) " %2, [%3]\n"
"3:\n"
" .pushsection __ex_table,\"a\"\n"
" .align 3\n"
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 6d7485aff955..89ad1805e579 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,13 +5,31 @@
#include <linux/threads.h>
#include <asm/irq.h>
+#define NR_IPI 5
+
typedef struct {
unsigned int __softirq_pending;
+#ifdef CONFIG_LOCAL_TIMERS
unsigned int local_timer_irqs;
+#endif
+#ifdef CONFIG_SMP
+ unsigned int ipi_irqs[NR_IPI];
+#endif
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
+#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
+
+#ifdef CONFIG_SMP
+u64 smp_irq_stat_cpu(unsigned int cpu);
+#else
+#define smp_irq_stat_cpu(cpu) 0
+#endif
+
+#define arch_irq_stat_cpu smp_irq_stat_cpu
+
#if NR_IRQS > 512
#define HARDIRQ_BITS 10
#elif NR_IRQS > 256
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index cc42d5fdee17..5aeec1e1735c 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -59,7 +59,17 @@
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
-#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
+
+#define L2X0_AUX_CTRL_MASK 0xc0000fff
+#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
+#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
+#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
+#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
+#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
+#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
+#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
+#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
new file mode 100644
index 000000000000..c115b82fe80a
--- /dev/null
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/hardware/entry-macro-gic.S
+ *
+ * Low-level IRQ helper macros for GIC
+ *
+ * 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/gic.h>
+
+#ifndef HAVE_GET_IRQNR_PREAMBLE
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =gic_cpu_base_addr
+ ldr \base, [\base]
+ .endm
+#endif
+
+/*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ /* bits 12-10 = src CPU, 9-0 = int # */
+
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+ .endm
+
+/* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+/* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 7f34333bb545..84557d321001 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -33,10 +33,13 @@
#define GIC_DIST_SOFTINT 0xf00
#ifndef __ASSEMBLY__
-void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
-void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
+extern void __iomem *gic_cpu_base_addr;
+
+void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+void gic_secondary_init(unsigned int);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+void gic_enable_ppi(unsigned int);
#endif
#endif
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
index 21fa272301f8..b2f95c72287c 100644
--- a/arch/arm/include/asm/hardware/it8152.h
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -76,6 +76,7 @@ extern unsigned long it8152_base_address;
IT8152_PD_IRQ(0) Audio controller (ACR)
*/
#define IT8152_IRQ(x) (IRQ_BOARD_START + (x))
+#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40)
/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
#define IT8152_LD_IRQ_COUNT 9
diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 21e75e30d497..21e75e30d497 100644
--- a/arch/arm/plat-versatile/include/plat/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 1fc684e70ab6..7080e2c8fa62 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -25,9 +25,6 @@ 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.
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index 4d8ae9d67abe..f389b2704d82 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -20,8 +20,8 @@ struct arch_hw_breakpoint_ctrl {
struct arch_hw_breakpoint {
u32 address;
u32 trigger;
- struct perf_event *suspended_wp;
- struct arch_hw_breakpoint_ctrl ctrl;
+ struct arch_hw_breakpoint_ctrl step_ctrl;
+ struct arch_hw_breakpoint_ctrl ctrl;
};
static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 815efa2d4e07..20e0f7c9e03e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -241,18 +241,15 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
*
*/
#ifndef __arch_ioremap
-#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
-#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
-#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
-#define ioremap_wc(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_WC)
-#define iounmap(cookie) __iounmap(cookie)
-#else
+#define __arch_ioremap __arm_ioremap
+#define __arch_iounmap __iounmap
+#endif
+
#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC)
-#define iounmap(cookie) __arch_iounmap(cookie)
-#endif
+#define iounmap __arch_iounmap
/*
* io{read,write}{8,16,32} macros
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index 8ec9ef5c3c7b..c0094d8edae4 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -33,10 +33,20 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
if (oldregs) {
memcpy(newregs, oldregs, sizeof(*newregs));
} else {
- __asm__ __volatile__ ("stmia %0, {r0 - r15}"
- : : "r" (&newregs->ARM_r0));
- __asm__ __volatile__ ("mrs %0, cpsr"
- : "=r" (newregs->ARM_cpsr));
+ __asm__ __volatile__ (
+ "stmia %[regs_base], {r0-r12}\n\t"
+ "mov %[_ARM_sp], sp\n\t"
+ "str lr, %[_ARM_lr]\n\t"
+ "adr %[_ARM_pc], 1f\n\t"
+ "mrs %[_ARM_cpsr], cpsr\n\t"
+ "1:"
+ : [_ARM_pc] "=r" (newregs->ARM_pc),
+ [_ARM_cpsr] "=r" (newregs->ARM_cpsr),
+ [_ARM_sp] "=r" (newregs->ARM_sp),
+ [_ARM_lr] "=o" (newregs->ARM_lr)
+ : [regs_base] "r" (&newregs->ARM_r0)
+ : "memory"
+ );
}
}
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 50c7e7cfd670..6bc63ab498ce 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -30,7 +30,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
#include "smp_twd.h"
#define local_timer_ack() twd_timer_ack()
-#define local_timer_stop() twd_timer_stop()
#else
@@ -40,11 +39,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
*/
int local_timer_ack(void);
-/*
- * Stop a local timer interrupt.
- */
-void local_timer_stop(void);
-
#endif
/*
@@ -52,12 +46,6 @@ void local_timer_stop(void);
*/
void local_timer_setup(struct clock_event_device *);
-#else
-
-static inline void local_timer_stop(void)
-{
-}
-
#endif
#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index d97a964207fa..3a0893a76a3b 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,12 +37,21 @@ struct machine_desc {
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
+ void (*init_early)(void);
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ void (*handle_irq)(struct pt_regs *);
+#endif
};
/*
+ * Current machine - only accessible during boot.
+ */
+extern struct machine_desc *machine_desc;
+
+/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index ce3eee9fe26c..22ac140edd9e 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,10 +17,12 @@ struct seq_file;
/*
* This is internal. Do not use it.
*/
-extern unsigned int arch_nr_irqs;
-extern void (*init_arch_irq)(void);
extern void init_FIQ(void);
-extern int show_fiq_list(struct seq_file *, void *);
+extern int show_fiq_list(struct seq_file *, int);
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+extern void (*handle_arch_irq)(struct pt_regs *);
+#endif
/*
* This is for easy migration, but should be changed in the source
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 35d408f6dccf..883f6be5117a 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -43,7 +43,6 @@ struct sys_timer {
#endif
};
-extern struct sys_timer *system_timer;
extern void timer_tick(void);
#endif
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index cbb0bc295d2b..12c8e680cbff 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -8,11 +8,6 @@
struct unwind_table;
#ifdef CONFIG_ARM_UNWIND
-struct arm_unwind_mapping {
- Elf_Shdr *unw_sec;
- Elf_Shdr *sec_text;
- struct unwind_table *unwind;
-};
enum {
ARM_SEC_INIT,
ARM_SEC_DEVINIT,
@@ -21,13 +16,13 @@ enum {
ARM_SEC_DEVEXIT,
ARM_SEC_MAX,
};
+#endif
+
struct mod_arch_specific {
- struct arm_unwind_mapping map[ARM_SEC_MAX];
-};
-#else
-struct mod_arch_specific {
-};
+#ifdef CONFIG_ARM_UNWIND
+ struct unwind_table *unwind[ARM_SEC_MAX];
#endif
+};
/*
* Include the ARM architecture version.
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index a485ac3c8696..f51a69595f6e 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern void copy_page(void *to, const void *from);
+typedef unsigned long pteval_t;
+
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
-typedef struct { unsigned long pte; } pte_t;
+typedef struct { pteval_t pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd[2]; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
/*
* .. while these make it easier on the compiler
*/
-typedef unsigned long pte_t;
+typedef pteval_t pte_t;
typedef unsigned long pmd_t;
typedef unsigned long pgd_t[2];
typedef unsigned long pgprot_t;
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index b12cc98bbe04..f2118fdd9d4f 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -28,16 +28,18 @@
*/
#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(mm, pmd) do { } while (0)
-#define pgd_populate(mm,pmd,pte) BUG()
+#define pud_populate(mm,pmd,pte) BUG()
-extern pgd_t *get_pgd_slow(struct mm_struct *mm);
-extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
-
-#define pgd_alloc(mm) get_pgd_slow(mm)
-#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+static inline void clean_pte_table(pte_t *pte)
+{
+ clean_dcache_area(pte + PTE_HWTABLE_PTRS, PTE_HWTABLE_SIZE);
+}
+
/*
* Allocate one PTE table.
*
@@ -45,14 +47,14 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
* into one table thus:
*
* +------------+
- * | h/w pt 0 |
- * +------------+
- * | h/w pt 1 |
- * +------------+
* | Linux pt 0 |
* +------------+
* | Linux pt 1 |
* +------------+
+ * | h/w pt 0 |
+ * +------------+
+ * | h/w pt 1 |
+ * +------------+
*/
static inline pte_t *
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
@@ -60,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
pte_t *pte;
pte = (pte_t *)__get_free_page(PGALLOC_GFP);
- if (pte) {
- clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
- pte += PTRS_PER_PTE;
- }
+ if (pte)
+ clean_pte_table(pte);
return pte;
}
@@ -79,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
pte = alloc_pages(PGALLOC_GFP, 0);
#endif
if (pte) {
- if (!PageHighMem(pte)) {
- void *page = page_address(pte);
- clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
- }
+ if (!PageHighMem(pte))
+ clean_pte_table(page_address(pte));
pgtable_page_ctor(pte);
}
@@ -94,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
*/
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
- if (pte) {
- pte -= PTRS_PER_PTE;
+ if (pte)
free_page((unsigned long)pte);
- }
}
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
@@ -106,8 +102,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
__free_page(pte);
}
-static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
+static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
+ unsigned long prot)
{
+ unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
pmdp[0] = __pmd(pmdval);
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
flush_pmd_entry(pmdp);
@@ -122,20 +120,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
- unsigned long pte_ptr = (unsigned long)ptep;
-
/*
- * The pmd must be loaded with the physical
- * address of the PTE table
+ * The pmd must be loaded with the physical address of the PTE table
*/
- pte_ptr -= PTRS_PER_PTE * sizeof(void *);
- __pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
+ __pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);
}
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
- __pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
+ __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
}
#define pmd_pgtable(pmd) pmd_page(pmd)
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 53d1d5deb111..0a8dad013367 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -10,15 +10,17 @@
#ifndef _ASMARM_PGTABLE_H
#define _ASMARM_PGTABLE_H
-#include <asm-generic/4level-fixup.h>
+#include <linux/const.h>
#include <asm/proc-fns.h>
#ifndef CONFIG_MMU
+#include <asm-generic/4level-fixup.h>
#include "pgtable-nommu.h"
#else
+#include <asm-generic/pgtable-nopud.h>
#include <asm/memory.h>
#include <mach/vmalloc.h>
#include <asm/pgtable-hwdef.h>
@@ -54,7 +56,7 @@
* Therefore, we tweak the implementation slightly - we tell Linux that we
* have 2048 entries in the first level, each of which is 8 bytes (iow, two
* hardware pointers to the second level.) The second level contains two
- * hardware PTE tables arranged contiguously, followed by Linux versions
+ * hardware PTE tables arranged contiguously, preceded by Linux versions
* which contain the state information Linux needs. We, therefore, end up
* with 512 entries in the "PTE" level.
*
@@ -62,15 +64,15 @@
*
* pgd pte
* | |
- * +--------+ +0
- * | |-----> +------------+ +0
+ * +--------+
+ * | | +------------+ +0
+ * +- - - - + | Linux pt 0 |
+ * | | +------------+ +1024
+ * +--------+ +0 | Linux pt 1 |
+ * | |-----> +------------+ +2048
* +- - - - + +4 | h/w pt 0 |
- * | |-----> +------------+ +1024
+ * | |-----> +------------+ +3072
* +--------+ +8 | h/w pt 1 |
- * | | +------------+ +2048
- * +- - - - + | Linux pt 0 |
- * | | +------------+ +3072
- * +--------+ | Linux pt 1 |
* | | +------------+ +4096
*
* See L_PTE_xxx below for definitions of bits in the "Linux pt", and
@@ -102,6 +104,10 @@
#define PTRS_PER_PMD 1
#define PTRS_PER_PGD 2048
+#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
+#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
+
/*
* PMD_SHIFT determines the size of the area a second-level page table can map
* PGDIR_SHIFT determines what a third-level page table entry can map
@@ -112,13 +118,13 @@
#define LIBRARY_TEXT_START 0x0c000000
#ifndef __ASSEMBLY__
-extern void __pte_error(const char *file, int line, unsigned long val);
-extern void __pmd_error(const char *file, int line, unsigned long val);
-extern void __pgd_error(const char *file, int line, unsigned long val);
+extern void __pte_error(const char *file, int line, pte_t);
+extern void __pmd_error(const char *file, int line, pmd_t);
+extern void __pgd_error(const char *file, int line, pgd_t);
-#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
-#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
-#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
+#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
+#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
+#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
#endif /* !__ASSEMBLY__ */
#define PMD_SIZE (1UL << PMD_SHIFT)
@@ -133,8 +139,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
*/
#define FIRST_USER_ADDRESS PAGE_SIZE
-#define FIRST_USER_PGD_NR 1
-#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
/*
* section address mask and size definitions.
@@ -161,30 +166,30 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
* The PTE table pointer refers to the hardware entries; the "Linux"
* entries are stored 1024 bytes below.
*/
-#define L_PTE_PRESENT (1 << 0)
-#define L_PTE_YOUNG (1 << 1)
-#define L_PTE_FILE (1 << 2) /* only when !PRESENT */
-#define L_PTE_DIRTY (1 << 6)
-#define L_PTE_WRITE (1 << 7)
-#define L_PTE_USER (1 << 8)
-#define L_PTE_EXEC (1 << 9)
-#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */
+#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
+#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
+#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
+#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
+#define L_PTE_USER (_AT(pteval_t, 1) << 8)
+#define L_PTE_XN (_AT(pteval_t, 1) << 9)
+#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
/*
* These are the memory types, defined to be compatible with
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
*/
-#define L_PTE_MT_UNCACHED (0x00 << 2) /* 0000 */
-#define L_PTE_MT_BUFFERABLE (0x01 << 2) /* 0001 */
-#define L_PTE_MT_WRITETHROUGH (0x02 << 2) /* 0010 */
-#define L_PTE_MT_WRITEBACK (0x03 << 2) /* 0011 */
-#define L_PTE_MT_MINICACHE (0x06 << 2) /* 0110 (sa1100, xscale) */
-#define L_PTE_MT_WRITEALLOC (0x07 << 2) /* 0111 */
-#define L_PTE_MT_DEV_SHARED (0x04 << 2) /* 0100 */
-#define L_PTE_MT_DEV_NONSHARED (0x0c << 2) /* 1100 */
-#define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 */
-#define L_PTE_MT_DEV_CACHED (0x0b << 2) /* 1011 */
-#define L_PTE_MT_MASK (0x0f << 2)
+#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
+#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
+#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
+#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
+#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
+#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
+#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
+#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
+#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
#ifndef __ASSEMBLY__
@@ -201,23 +206,44 @@ extern pgprot_t pgprot_kernel;
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
-#define PAGE_NONE pgprot_user
-#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
-#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
-#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER)
-#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
-#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER)
-#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
-#define PAGE_KERNEL pgprot_kernel
-#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC)
-
-#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT)
-#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
-#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
-#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
-#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
-#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
-#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
+#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
+#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
+#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
+#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
+#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
+#define PAGE_KERNEL_EXEC pgprot_kernel
+
+#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
+#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
+#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
+
+#define __pgprot_modify(prot,mask,bits) \
+ __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
+
+#define pgprot_noncached(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
+
+#define pgprot_writecombine(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
+
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#else
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+#endif
#endif /* __ASSEMBLY__ */
@@ -255,26 +281,87 @@ extern pgprot_t pgprot_kernel;
extern struct page *empty_zero_page;
#define ZERO_PAGE(vaddr) (empty_zero_page)
-#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
-#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
-#define pte_none(pte) (!pte_val(pte))
-#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
-#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
-#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
+
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
+
+/*
+ * The "pud_xxx()" functions here are trivial when the pmd is folded into
+ * the pud: the pud entry is never bad, always exists, and can't be set or
+ * cleared.
+ */
+#define pud_none(pud) (0)
+#define pud_bad(pud) (0)
+#define pud_present(pud) (1)
+#define pud_clear(pudp) do { } while (0)
+#define set_pud(pud,pudp) do { } while (0)
+
+
+/* Find an entry in the second-level page table.. */
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+ return (pmd_t *)pud;
+}
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_present(pmd) (pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+
+#define copy_pmd(pmdpd,pmdps) \
+ do { \
+ pmdpd[0] = pmdps[0]; \
+ pmdpd[1] = pmdps[1]; \
+ flush_pmd_entry(pmdpd); \
+ } while (0)
+
+#define pmd_clear(pmdp) \
+ do { \
+ pmdp[0] = __pmd(0); \
+ pmdp[1] = __pmd(0); \
+ clean_pmd_entry(pmdp); \
+ } while (0)
+
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+{
+ return __va(pmd_val(pmd) & PAGE_MASK);
+}
+
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
+
+/* we don't need complex calculations here as the pmd is folded into the pgd */
+#define pmd_addr_end(addr,end) (end)
-#define pte_offset_map(dir,addr) (__pte_map(dir) + __pte_index(addr))
-#define pte_unmap(pte) __pte_unmap(pte)
#ifndef CONFIG_HIGHPTE
-#define __pte_map(dir) pmd_page_vaddr(*(dir))
+#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
#define __pte_unmap(pte) do { } while (0)
#else
-#define __pte_map(dir) ((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE)
-#define __pte_unmap(pte) kunmap_atomic((pte - PTRS_PER_PTE))
+#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
+#define __pte_unmap(pte) kunmap_atomic(pte)
#endif
+#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
+
+#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
+#define pte_unmap(pte) __pte_unmap(pte)
+
+#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define pte_page(pte) pfn_to_page(pte_pfn(pte))
+#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
+
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
#if __LINUX_ARM_ARCH__ < 6
static inline void __sync_icache_dcache(pte_t pteval)
@@ -295,15 +382,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
}
}
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
+#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
-#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
+#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
-#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
+#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
#define pte_special(pte) (0)
#define pte_present_user(pte) \
@@ -313,8 +397,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
-PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
-PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
+PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
+PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
@@ -322,101 +406,13 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
-#define __pgprot_modify(prot,mask,bits) \
- __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
-
-/*
- * Mark the prot value as uncacheable and unbufferable.
- */
-#define pgprot_noncached(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
-#define pgprot_writecombine(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
-#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
-#define pgprot_dmacoherent(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
-#define __HAVE_PHYS_MEM_ACCESS_PROT
-struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
- unsigned long size, pgprot_t vma_prot);
-#else
-#define pgprot_dmacoherent(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
-#endif
-
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_present(pmd) (pmd_val(pmd))
-#define pmd_bad(pmd) (pmd_val(pmd) & 2)
-
-#define copy_pmd(pmdpd,pmdps) \
- do { \
- pmdpd[0] = pmdps[0]; \
- pmdpd[1] = pmdps[1]; \
- flush_pmd_entry(pmdpd); \
- } while (0)
-
-#define pmd_clear(pmdp) \
- do { \
- pmdp[0] = __pmd(0); \
- pmdp[1] = __pmd(0); \
- clean_pmd_entry(pmdp); \
- } while (0)
-
-static inline pte_t *pmd_page_vaddr(pmd_t pmd)
-{
- unsigned long ptr;
-
- ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
- ptr += PTRS_PER_PTE * sizeof(void *);
-
- return __va(ptr);
-}
-
-#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
-
-/* we don't need complex calculations here as the pmd is folded into the pgd */
-#define pmd_addr_end(addr,end) (end)
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
-
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-#define pgd_none(pgd) (0)
-#define pgd_bad(pgd) (0)
-#define pgd_present(pgd) (1)
-#define pgd_clear(pgdp) do { } while (0)
-#define set_pgd(pgd,pgdp) do { } while (0)
-
-/* to find an entry in a page-table-directory */
-#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
-
-#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
-
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, addr) ((pmd_t *)(dir))
-
-/* Find an entry in the third-level page table.. */
-#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER;
+ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte;
}
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
/*
* Encode and decode a swap entry. Swap entries are stored in the Linux
* page tables as follows:
@@ -481,6 +477,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgtable_cache_init() do { } while (0)
+void identity_mapping_add(pgd_t *, unsigned long, unsigned long);
+void identity_mapping_del(pgd_t *, unsigned long, unsigned long);
+
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
new file mode 100644
index 000000000000..a84628be1a7b
--- /dev/null
+++ b/arch/arm/include/asm/sched_clock.h
@@ -0,0 +1,118 @@
+/*
+ * sched_clock.h: support for extending counters to full 64-bit ns counter
+ *
+ * This program is free software; you can 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_SCHED_CLOCK
+#define ASM_SCHED_CLOCK
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct clock_data {
+ u64 epoch_ns;
+ u32 epoch_cyc;
+ u32 epoch_cyc_copy;
+ u32 mult;
+ u32 shift;
+};
+
+#define DEFINE_CLOCK_DATA(name) struct clock_data name
+
+static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
+{
+ return (cyc * mult) >> shift;
+}
+
+/*
+ * Atomically update the sched_clock epoch. Your update callback will
+ * be called from a timer before the counter wraps - read the current
+ * counter value, and call this function to safely move the epochs
+ * forward. Only use this from the update callback.
+ */
+static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask)
+{
+ unsigned long flags;
+ u64 ns = cd->epoch_ns +
+ cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift);
+
+ /*
+ * Write epoch_cyc and epoch_ns in a way that the update is
+ * detectable in cyc_to_fixed_sched_clock().
+ */
+ raw_local_irq_save(flags);
+ cd->epoch_cyc = cyc;
+ smp_wmb();
+ cd->epoch_ns = ns;
+ smp_wmb();
+ cd->epoch_cyc_copy = cyc;
+ raw_local_irq_restore(flags);
+}
+
+/*
+ * If your clock rate is known at compile time, using this will allow
+ * you to optimize the mult/shift loads away. This is paired with
+ * init_fixed_sched_clock() to ensure that your mult/shift are correct.
+ */
+static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd,
+ u32 cyc, u32 mask, u32 mult, u32 shift)
+{
+ u64 epoch_ns;
+ u32 epoch_cyc;
+
+ /*
+ * Load the epoch_cyc and epoch_ns atomically. We do this by
+ * ensuring that we always write epoch_cyc, epoch_ns and
+ * epoch_cyc_copy in strict order, and read them in strict order.
+ * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
+ * the middle of an update, and we should repeat the load.
+ */
+ do {
+ epoch_cyc = cd->epoch_cyc;
+ smp_rmb();
+ epoch_ns = cd->epoch_ns;
+ smp_rmb();
+ } while (epoch_cyc != cd->epoch_cyc_copy);
+
+ return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift);
+}
+
+/*
+ * Otherwise, you need to use this, which will obtain the mult/shift
+ * from the clock_data structure. Use init_sched_clock() with this.
+ */
+static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
+ u32 cyc, u32 mask)
+{
+ return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift);
+}
+
+/*
+ * Initialize the clock data - calculate the appropriate multiplier
+ * and shift. Also setup a timer to ensure that the epoch is refreshed
+ * at the appropriate time interval, which will call your update
+ * handler.
+ */
+void init_sched_clock(struct clock_data *, void (*)(void),
+ unsigned int, unsigned long);
+
+/*
+ * Use this initialization function rather than init_sched_clock() if
+ * you're using cyc_to_fixed_sched_clock, which will warn if your
+ * constants are incorrect.
+ */
+static inline void init_fixed_sched_clock(struct clock_data *cd,
+ void (*update)(void), unsigned int bits, unsigned long rate,
+ u32 mult, u32 shift)
+{
+ init_sched_clock(cd, update, bits, rate);
+ if (cd->mult != mult || cd->shift != shift) {
+ pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n"
+ "sched_clock: fix multiply/shift to avoid scheduler hiccups\n",
+ mult, shift, cd->mult, cd->shift);
+ }
+}
+
+#endif
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index 4fc1565e4f93..316bb2b2be3d 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -13,9 +13,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
/* Size definitions
* Copyright (C) ARM Limited 1998. All rights reserved.
*/
@@ -25,6 +22,9 @@
/* handy sizes */
#define SZ_16 0x00000010
+#define SZ_32 0x00000020
+#define SZ_64 0x00000040
+#define SZ_128 0x00000080
#define SZ_256 0x00000100
#define SZ_512 0x00000200
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 3d05190797cb..96ed521f2408 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -33,27 +33,23 @@ struct seq_file;
/*
* generate IPI list text
*/
-extern void show_ipi_list(struct seq_file *p);
+extern void show_ipi_list(struct seq_file *, int);
/*
* Called from assembly code, this handles an IPI.
*/
-asmlinkage void do_IPI(struct pt_regs *regs);
+asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
/*
* Setup the set of possible CPUs (via set_cpu_possible)
*/
extern void smp_init_cpus(void);
-/*
- * Move global data into per-processor storage.
- */
-extern void smp_store_cpu_info(unsigned int cpuid);
/*
* Raise an IPI cross call on CPUs in callmap.
*/
-extern void smp_cross_call(const struct cpumask *mask);
+extern void smp_cross_call(const struct cpumask *mask, int ipi);
/*
* Boot a secondary CPU, and assign it the specified idle task.
@@ -73,6 +69,11 @@ asmlinkage void secondary_start_kernel(void);
extern void platform_secondary_init(unsigned int cpu);
/*
+ * Initialize cpu_possible map, and enable coherency
+ */
+extern void platform_smp_prepare_cpus(unsigned int);
+
+/*
* Initial data for bringing up a secondary CPU.
*/
struct secondary_data {
@@ -97,6 +98,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
/*
* show local interrupt info
*/
-extern void show_local_irqs(struct seq_file *);
+extern void show_local_irqs(struct seq_file *, int);
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/smp_mpidr.h b/arch/arm/include/asm/smp_mpidr.h
deleted file mode 100644
index 6a9307d64900..000000000000
--- a/arch/arm/include/asm/smp_mpidr.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ASMARM_SMP_MIDR_H
-#define ASMARM_SMP_MIDR_H
-
-#define hard_smp_processor_id() \
- ({ \
- unsigned int cpunum; \
- __asm__("\n" \
- "1: mrc p15, 0, %0, c0, c0, 5\n" \
- " .pushsection \".alt.smp.init\", \"a\"\n"\
- " .long 1b\n" \
- " mov %0, #0\n" \
- " .popsection" \
- : "=r" (cpunum)); \
- cpunum &= 0x0F; \
- })
-
-#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index 634f357be6bb..fed9981fba08 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -22,7 +22,6 @@ struct clock_event_device;
extern void __iomem *twd_base;
-void twd_timer_stop(void);
int twd_timer_ack(void);
void twd_timer_setup(struct clock_event_device *);
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 1120f18a6b17..97f6d60297d5 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -63,6 +63,11 @@
#include <asm/outercache.h>
#define __exception __attribute__((section(".exception.text")))
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#define __exception_irq_entry __irq_entry
+#else
+#define __exception_irq_entry __exception
+#endif
struct thread_info;
struct task_struct;
@@ -119,6 +124,13 @@ extern unsigned int user_debug;
#define vectors_high() (0)
#endif
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
+#define sev() __asm__ __volatile__ ("sev" : : : "memory")
+#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
+#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#endif
+
#if __LINUX_ARM_ARCH__ >= 7
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
@@ -150,6 +162,7 @@ extern unsigned int user_debug;
#define rmb() dmb()
#define wmb() mb()
#else
+#include <asm/memory.h>
#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index f41a6f57cd12..a116bef20cbe 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -104,6 +104,7 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep)
#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
#define tlb_migrate_finish(mm) do { } while (0)
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 491960bf4260..1b960d5ef6a5 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -15,16 +15,37 @@ struct undef_hook {
void register_undef_hook(struct undef_hook *hook);
void unregister_undef_hook(struct undef_hook *hook);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+ extern char __irqentry_text_start[];
+ extern char __irqentry_text_end[];
+
+ return ptr >= (unsigned long)&__irqentry_text_start &&
+ ptr < (unsigned long)&__irqentry_text_end;
+}
+#else
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+ return 0;
+}
+#endif
+
static inline int in_exception_text(unsigned long ptr)
{
extern char __exception_text_start[];
extern char __exception_text_end[];
+ int in;
- return ptr >= (unsigned long)&__exception_text_start &&
- ptr < (unsigned long)&__exception_text_end;
+ in = ptr >= (unsigned long)&__exception_text_start &&
+ ptr < (unsigned long)&__exception_text_end;
+
+ return in ? : __in_irqentry_text(ptr);
}
extern void __init early_trap_init(void);
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
+extern void *vectors_page;
+
#endif
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 33e4a48fe103..b293616a1a1a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -227,7 +227,7 @@ do { \
#define __get_user_asm_byte(x,addr,err) \
__asm__ __volatile__( \
- "1: ldrbt %1,[%2]\n" \
+ "1: " T(ldrb) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -263,7 +263,7 @@ do { \
#define __get_user_asm_word(x,addr,err) \
__asm__ __volatile__( \
- "1: ldrt %1,[%2]\n" \
+ "1: " T(ldr) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -308,7 +308,7 @@ do { \
#define __put_user_asm_byte(x,__pu_addr,err) \
__asm__ __volatile__( \
- "1: strbt %1,[%2]\n" \
+ "1: " T(strb) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -341,7 +341,7 @@ do { \
#define __put_user_asm_word(x,__pu_addr,err) \
__asm__ __volatile__( \
- "1: strt %1,[%2]\n" \
+ "1: " T(str) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -366,10 +366,10 @@ do { \
#define __put_user_asm_dword(x,__pu_addr,err) \
__asm__ __volatile__( \
- ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \
- ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \
- THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \
- THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \
+ ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \
+ ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \
+ THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \
+ THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \
"3:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5b9b268f4fbb..185ee822c935 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -5,7 +5,7 @@
CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
-ifdef CONFIG_DYNAMIC_FTRACE
+ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
endif
@@ -29,10 +29,12 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
-obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
+obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
obj-$(CONFIG_ATAGS_PROC) += atags.o
@@ -42,6 +44,8 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
+CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
@@ -50,6 +54,7 @@ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
+obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index c09e3573c5de..2b46fea36c9f 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -25,42 +25,22 @@
#include <asm/tls.h>
#include "entry-header.S"
+#include <asm/entry-macro-multi.S>
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro irq_handler
- get_irqnr_preamble r5, lr
-1: get_irqnr_and_base r0, r6, r5, lr
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- adrne lr, BSYM(1b)
- bne asm_do_IRQ
-
-#ifdef CONFIG_SMP
- /*
- * XXX
- *
- * this macro assumes that irqstat (r6) and base (r5) are
- * preserved from get_irqnr_and_base above
- */
- ALT_SMP(test_for_ipi r0, r6, r5, lr)
- ALT_UP_B(9997f)
- movne r0, sp
- adrne lr, BSYM(1b)
- bne do_IPI
-
-#ifdef CONFIG_LOCAL_TIMERS
- test_for_ltirq r0, r6, r5, lr
- movne r0, sp
- adrne lr, BSYM(1b)
- bne do_local_timer
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ ldr r5, =handle_arch_irq
+ mov r0, sp
+ ldr r5, [r5]
+ adr lr, BSYM(9997f)
+ teq r5, #0
+ movne pc, r5
#endif
+ arch_irq_handler_default
9997:
-#endif
-
.endm
#ifdef CONFIG_KPROBES
@@ -198,6 +178,7 @@ __dabt_svc:
@
@ set desired IRQ state, then call main handler
@
+ debug_entry r1
msr cpsr_c, r9
mov r2, sp
bl do_DataAbort
@@ -324,6 +305,7 @@ __pabt_svc:
#else
bl CPU_PABORT_HANDLER
#endif
+ debug_entry r1
msr cpsr_c, r9 @ Maybe enable interrupts
mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
@@ -439,6 +421,7 @@ __dabt_usr:
@
@ IRQs on, then call the main handler
@
+ debug_entry r1
enable_irq
mov r2, sp
adr lr, BSYM(ret_from_exception)
@@ -703,6 +686,7 @@ __pabt_usr:
#else
bl CPU_PABORT_HANDLER
#endif
+ debug_entry r1
enable_irq @ Enable interrupts
mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
@@ -735,7 +719,7 @@ ENTRY(__switch_to)
THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
THUMB( str sp, [ip], #4 )
THUMB( str lr, [ip], #4 )
-#ifdef CONFIG_MMU
+#ifdef CONFIG_CPU_USE_DOMAINS
ldr r6, [r2, #TI_CPU_DOMAIN]
#endif
set_tls r3, r4, r5
@@ -744,7 +728,7 @@ ENTRY(__switch_to)
ldr r8, =__stack_chk_guard
ldr r7, [r7, #TSK_STACK_CANARY]
#endif
-#ifdef CONFIG_MMU
+#ifdef CONFIG_CPU_USE_DOMAINS
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif
mov r5, r0
@@ -842,7 +826,7 @@ __kuser_helper_start:
*/
__kuser_memory_barrier: @ 0xffff0fa0
- smp_dmb
+ smp_dmb arm
usr_ret lr
.align 5
@@ -911,7 +895,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
* A special ghost syscall is used for that (see traps.c).
*/
stmfd sp!, {r7, lr}
- ldr r7, =1f @ it's 20 bits
+ ldr r7, 1f @ it's 20 bits
swi __ARM_NR_cmpxchg
ldmfd sp!, {r7, pc}
1: .word __ARM_NR_cmpxchg
@@ -959,7 +943,7 @@ kuser_cmpxchg_fixup:
#else
- smp_dmb
+ smp_dmb arm
1: ldrex r3, [r2]
subs r3, r3, r0
strexeq r3, r1, [r2]
@@ -1245,3 +1229,9 @@ cr_alignment:
.space 4
cr_no_alignment:
.space 4
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ .globl handle_arch_irq
+handle_arch_irq:
+ .space 4
+#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8bfa98757cd2..1e7b04a40a31 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -29,6 +29,9 @@ ret_fast_syscall:
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
bne fast_work_pending
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@@ -65,6 +68,9 @@ ret_slow_syscall:
tst r1, #_TIF_WORK_MASK
bne work_pending
no_work_pending:
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@@ -141,98 +147,170 @@ ENDPROC(ret_from_fork)
#endif
#endif
-#ifdef CONFIG_DYNAMIC_FTRACE
-ENTRY(__gnu_mcount_nc)
- mov ip, lr
- ldmia sp!, {lr}
- mov pc, ip
-ENDPROC(__gnu_mcount_nc)
+.macro __mcount suffix
+ mcount_enter
+ ldr r0, =ftrace_trace_function
+ ldr r2, [r0]
+ adr r0, .Lftrace_stub
+ cmp r0, r2
+ bne 1f
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ ldr r1, =ftrace_graph_return
+ ldr r2, [r1]
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+
+ ldr r1, =ftrace_graph_entry
+ ldr r2, [r1]
+ ldr r0, =ftrace_graph_entry_stub
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+#endif
-ENTRY(ftrace_caller)
- stmdb sp!, {r0-r3, lr}
- mov r0, lr
+ mcount_exit
+
+1: mcount_get_lr r1 @ lr of instrumented func
+ mov r0, lr @ instrumented function
sub r0, r0, #MCOUNT_INSN_SIZE
- ldr r1, [sp, #20]
+ adr lr, BSYM(2f)
+ mov pc, r2
+2: mcount_exit
+.endm
+
+.macro __ftrace_caller suffix
+ mcount_enter
- .global ftrace_call
-ftrace_call:
+ mcount_get_lr r1 @ lr of instrumented func
+ mov r0, lr @ instrumented function
+ sub r0, r0, #MCOUNT_INSN_SIZE
+
+ .globl ftrace_call\suffix
+ftrace_call\suffix:
bl ftrace_stub
- ldmia sp!, {r0-r3, ip, lr}
- mov pc, ip
-ENDPROC(ftrace_caller)
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl ftrace_graph_call\suffix
+ftrace_graph_call\suffix:
+ mov r0, r0
+#endif
+
+ mcount_exit
+.endm
+
+.macro __ftrace_graph_caller
+ sub r0, fp, #4 @ &lr of instrumented routine (&parent)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ @ called from __ftrace_caller, saved in mcount_enter
+ ldr r1, [sp, #16] @ instrumented routine (func)
+#else
+ @ called from __mcount, untouched in lr
+ mov r1, lr @ instrumented routine (func)
+#endif
+ sub r1, r1, #MCOUNT_INSN_SIZE
+ mov r2, fp @ frame pointer
+ bl prepare_ftrace_return
+ mcount_exit
+.endm
#ifdef CONFIG_OLD_MCOUNT
+/*
+ * mcount
+ */
+
+.macro mcount_enter
+ stmdb sp!, {r0-r3, lr}
+.endm
+
+.macro mcount_get_lr reg
+ ldr \reg, [fp, #-4]
+.endm
+
+.macro mcount_exit
+ ldr lr, [fp, #-4]
+ ldmia sp!, {r0-r3, pc}
+.endm
+
ENTRY(mcount)
+#ifdef CONFIG_DYNAMIC_FTRACE
stmdb sp!, {lr}
ldr lr, [fp, #-4]
ldmia sp!, {pc}
+#else
+ __mcount _old
+#endif
ENDPROC(mcount)
+#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(ftrace_caller_old)
- stmdb sp!, {r0-r3, lr}
- ldr r1, [fp, #-4]
- mov r0, lr
- sub r0, r0, #MCOUNT_INSN_SIZE
-
- .globl ftrace_call_old
-ftrace_call_old:
- bl ftrace_stub
- ldr lr, [fp, #-4] @ restore lr
- ldmia sp!, {r0-r3, pc}
+ __ftrace_caller _old
ENDPROC(ftrace_caller_old)
#endif
-#else
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller_old)
+ __ftrace_graph_caller
+ENDPROC(ftrace_graph_caller_old)
+#endif
-ENTRY(__gnu_mcount_nc)
+.purgem mcount_enter
+.purgem mcount_get_lr
+.purgem mcount_exit
+#endif
+
+/*
+ * __gnu_mcount_nc
+ */
+
+.macro mcount_enter
stmdb sp!, {r0-r3, lr}
- ldr r0, =ftrace_trace_function
- ldr r2, [r0]
- adr r0, .Lftrace_stub
- cmp r0, r2
- bne gnu_trace
+.endm
+
+.macro mcount_get_lr reg
+ ldr \reg, [sp, #20]
+.endm
+
+.macro mcount_exit
ldmia sp!, {r0-r3, ip, lr}
mov pc, ip
+.endm
-gnu_trace:
- ldr r1, [sp, #20] @ lr of instrumented routine
- mov r0, lr
- sub r0, r0, #MCOUNT_INSN_SIZE
- adr lr, BSYM(1f)
- mov pc, r2
-1:
- ldmia sp!, {r0-r3, ip, lr}
+ENTRY(__gnu_mcount_nc)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ mov ip, lr
+ ldmia sp!, {lr}
mov pc, ip
+#else
+ __mcount
+#endif
ENDPROC(__gnu_mcount_nc)
-#ifdef CONFIG_OLD_MCOUNT
-/*
- * This is under an ifdef in order to force link-time errors for people trying
- * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
- * mcount.
- */
-ENTRY(mcount)
- stmdb sp!, {r0-r3, lr}
- ldr r0, =ftrace_trace_function
- ldr r2, [r0]
- adr r0, ftrace_stub
- cmp r0, r2
- bne trace
- ldr lr, [fp, #-4] @ restore lr
- ldmia sp!, {r0-r3, pc}
+#ifdef CONFIG_DYNAMIC_FTRACE
+ENTRY(ftrace_caller)
+ __ftrace_caller
+ENDPROC(ftrace_caller)
+#endif
-trace:
- ldr r1, [fp, #-4] @ lr of instrumented routine
- mov r0, lr
- sub r0, r0, #MCOUNT_INSN_SIZE
- mov lr, pc
- mov pc, r2
- ldr lr, [fp, #-4] @ restore lr
- ldmia sp!, {r0-r3, pc}
-ENDPROC(mcount)
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+ __ftrace_graph_caller
+ENDPROC(ftrace_graph_caller)
#endif
-#endif /* CONFIG_DYNAMIC_FTRACE */
+.purgem mcount_enter
+.purgem mcount_get_lr
+.purgem mcount_exit
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl return_to_handler
+return_to_handler:
+ stmdb sp!, {r0-r3}
+ mov r0, fp @ frame pointer
+ bl ftrace_return_to_handler
+ mov lr, r0 @ r0 has real ret addr
+ ldmia sp!, {r0-r3}
+ mov pc, lr
+#endif
ENTRY(ftrace_stub)
.Lftrace_stub:
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index d93f976fb389..ae9464900168 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -165,6 +165,25 @@
.endm
#endif /* !CONFIG_THUMB2_KERNEL */
+ @
+ @ Debug exceptions are taken as prefetch or data aborts.
+ @ We must disable preemption during the handler so that
+ @ we can access the debug registers safely.
+ @
+ .macro debug_entry, fsr
+#if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT)
+ ldr r4, =0x40f @ mask out fsr.fs
+ and r5, r4, \fsr
+ cmp r5, #2 @ debug exception
+ bne 1f
+ get_thread_info r10
+ ldr r6, [r10, #TI_PREEMPT] @ get preempt count
+ add r11, r6, #1 @ increment it
+ str r11, [r10, #TI_PREEMPT]
+1:
+#endif
+ .endm
+
/*
* These are the registers used in the syscall handler, and allow us to
* have in theory up to 7 arguments to a function - r0 to r6.
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 6ff7919613d7..e72dc34eea1c 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -45,6 +45,7 @@
#include <asm/fiq.h>
#include <asm/irq.h>
#include <asm/system.h>
+#include <asm/traps.h>
static unsigned long no_fiq_insn;
@@ -67,17 +68,22 @@ static struct fiq_handler default_owner = {
static struct fiq_handler *current_fiq = &default_owner;
-int show_fiq_list(struct seq_file *p, void *v)
+int show_fiq_list(struct seq_file *p, int prec)
{
if (current_fiq != &default_owner)
- seq_printf(p, "FIQ: %s\n", current_fiq->name);
+ seq_printf(p, "%*s: %s\n", prec, "FIQ",
+ current_fiq->name);
return 0;
}
void set_fiq_handler(void *start, unsigned int length)
{
+#if defined(CONFIG_CPU_USE_DOMAINS)
memcpy((void *)0xffff001c, start, length);
+#else
+ memcpy(vectors_page + 0x1c, start, length);
+#endif
flush_icache_range(0xffff001c, 0xffff001c + length);
if (!vectors_high())
flush_icache_range(0x1c, 0x1c + length);
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 971ac8c36ea7..c0062ad1e847 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -24,6 +24,7 @@
#define NOP 0xe8bd4000 /* pop {lr} */
#endif
+#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_OLD_MCOUNT
#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
@@ -59,9 +60,9 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
}
#endif
-/* construct a branch (BL) instruction to addr */
#ifdef CONFIG_THUMB2_KERNEL
-static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
+ bool link)
{
unsigned long s, j1, j2, i1, i2, imm10, imm11;
unsigned long first, second;
@@ -83,15 +84,22 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
j2 = (!i2) ^ s;
first = 0xf000 | (s << 10) | imm10;
- second = 0xd000 | (j1 << 13) | (j2 << 11) | imm11;
+ second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
+ if (link)
+ second |= 1 << 14;
return (second << 16) | first;
}
#else
-static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
+ bool link)
{
+ unsigned long opcode = 0xea000000;
long offset;
+ if (link)
+ opcode |= 1 << 24;
+
offset = (long)addr - (long)(pc + 8);
if (unlikely(offset < -33554432 || offset > 33554428)) {
/* Can't generate branches that far (from ARM ARM). Ftrace
@@ -103,10 +111,15 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
offset = (offset >> 2) & 0x00ffffff;
- return 0xeb000000 | offset;
+ return opcode | offset;
}
#endif
+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+{
+ return ftrace_gen_branch(pc, addr, true);
+}
+
static int ftrace_modify_code(unsigned long pc, unsigned long old,
unsigned long new)
{
@@ -193,3 +206,83 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void 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;
+ unsigned long old;
+ int err;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ old = *parent;
+ *parent = return_hooker;
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer);
+ if (err == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern unsigned long ftrace_graph_call;
+extern unsigned long ftrace_graph_call_old;
+extern void ftrace_graph_caller_old(void);
+
+static int __ftrace_modify_caller(unsigned long *callsite,
+ void (*func) (void), bool enable)
+{
+ unsigned long caller_fn = (unsigned long) func;
+ unsigned long pc = (unsigned long) callsite;
+ unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
+ unsigned long nop = 0xe1a00000; /* mov r0, r0 */
+ unsigned long old = enable ? nop : branch;
+ unsigned long new = enable ? branch : nop;
+
+ return ftrace_modify_code(pc, old, new);
+}
+
+static int ftrace_modify_graph_caller(bool enable)
+{
+ int ret;
+
+ ret = __ftrace_modify_caller(&ftrace_graph_call,
+ ftrace_graph_caller,
+ enable);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (!ret)
+ ret = __ftrace_modify_caller(&ftrace_graph_call_old,
+ ftrace_graph_caller_old,
+ enable);
+#endif
+
+ return ret;
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_graph_caller(true);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_graph_caller(false);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index dd6b369ac69c..f17d9a09e8fb 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -85,10 +85,17 @@ ENTRY(stext)
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
+ THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p @ yes, error 'p'
bl __lookup_machine_type @ r5=machinfo
movs r8, r5 @ invalid machine (r5=0)?
+ THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_a @ yes, error 'a'
+
+ /*
+ * r1 = machine no, r2 = atags,
+ * r8 = machinfo, r9 = cpuid, r10 = procinfo
+ */
bl __vet_atags
#ifdef CONFIG_SMP_ON_UP
bl __fixup_smp
@@ -262,6 +269,7 @@ __create_page_tables:
mov pc, lr
ENDPROC(__create_page_tables)
.ltorg
+ .align
__enable_mmu_loc:
.long .
.long __enable_mmu
@@ -282,6 +290,7 @@ ENTRY(secondary_startup)
bl __lookup_processor_type
movs r10, r5 @ invalid processor?
moveq r0, #'p' @ yes, error 'p'
+ THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p
/*
@@ -308,6 +317,8 @@ ENTRY(__secondary_switched)
b secondary_start_kernel
ENDPROC(__secondary_switched)
+ .align
+
.type __secondary_data, %object
__secondary_data:
.long .
@@ -381,19 +392,19 @@ ENDPROC(__turn_mmu_on)
#ifdef CONFIG_SMP_ON_UP
__fixup_smp:
- mov r7, #0x00070000
- orr r6, r7, #0xff000000 @ mask 0xff070000
- orr r7, r7, #0x41000000 @ val 0x41070000
- and r0, r9, r6
- teq r0, r7 @ ARM CPU and ARMv6/v7?
+ mov r4, #0x00070000
+ orr r3, r4, #0xff000000 @ mask 0xff070000
+ orr r4, r4, #0x41000000 @ val 0x41070000
+ and r0, r9, r3
+ teq r0, r4 @ ARM CPU and ARMv6/v7?
bne __fixup_smp_on_up @ no, assume UP
- orr r6, r6, #0x0000ff00
- orr r6, r6, #0x000000f0 @ mask 0xff07fff0
- orr r7, r7, #0x0000b000
- orr r7, r7, #0x00000020 @ val 0x4107b020
- and r0, r9, r6
- teq r0, r7 @ ARM 11MPCore?
+ orr r3, r3, #0x0000ff00
+ orr r3, r3, #0x000000f0 @ mask 0xff07fff0
+ orr r4, r4, #0x0000b000
+ orr r4, r4, #0x00000020 @ val 0x4107b020
+ and r0, r9, r3
+ teq r0, r4 @ ARM 11MPCore?
moveq pc, lr @ yes, assume SMP
mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
@@ -402,17 +413,25 @@ __fixup_smp:
__fixup_smp_on_up:
adr r0, 1f
- ldmia r0, {r3, r6, r7}
+ ldmia r0, {r3 - r5}
sub r3, r0, r3
- add r6, r6, r3
- add r7, r7, r3
-2: cmp r6, r7
- ldmia r6!, {r0, r4}
- strlo r4, [r0, r3]
- blo 2b
- mov pc, lr
+ add r4, r4, r3
+ add r5, r5, r3
+2: cmp r4, r5
+ movhs pc, lr
+ ldmia r4!, {r0, r6}
+ ARM( str r6, [r0, r3] )
+ THUMB( add r0, r0, r3 )
+#ifdef __ARMEB__
+ THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
+#endif
+ THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
+ THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
+ THUMB( strh r6, [r0] )
+ b 2b
ENDPROC(__fixup_smp)
+ .align
1: .word .
.word __smpalt_begin
.word __smpalt_end
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 21e3a4ab3b8c..c9f3f0467570 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -24,6 +24,7 @@
#define pr_fmt(fmt) "hw-breakpoint: " fmt
#include <linux/errno.h>
+#include <linux/hardirq.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <linux/smp.h>
@@ -44,6 +45,7 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
/* Number of BRP/WRP registers on this CPU. */
static int core_num_brps;
+static int core_num_reserved_brps;
static int core_num_wrps;
/* Debug architecture version. */
@@ -52,87 +54,6 @@ static u8 debug_arch;
/* Maximum supported watchpoint length. */
static u8 max_watchpoint_len;
-/* Determine number of BRP registers available. */
-static int get_num_brps(void)
-{
- u32 didr;
- ARM_DBG_READ(c0, 0, didr);
- return ((didr >> 24) & 0xf) + 1;
-}
-
-/* Determine number of WRP registers available. */
-static int get_num_wrps(void)
-{
- /*
- * FIXME: When a watchpoint fires, the only way to work out which
- * watchpoint it was is by disassembling the faulting instruction
- * and working out the address of the memory access.
- *
- * Furthermore, we can only do this if the watchpoint was precise
- * since imprecise watchpoints prevent us from calculating register
- * based addresses.
- *
- * For the time being, we only report 1 watchpoint register so we
- * always know which watchpoint fired. In the future we can either
- * add a disassembler and address generation emulator, or we can
- * insert a check to see if the DFAR is set on watchpoint exception
- * entry [the ARM ARM states that the DFAR is UNKNOWN, but
- * experience shows that it is set on some implementations].
- */
-
-#if 0
- u32 didr, wrps;
- ARM_DBG_READ(c0, 0, didr);
- return ((didr >> 28) & 0xf) + 1;
-#endif
-
- return 1;
-}
-
-int hw_breakpoint_slots(int type)
-{
- /*
- * We can be called early, so don't rely on
- * our static variables being initialised.
- */
- switch (type) {
- case TYPE_INST:
- return get_num_brps();
- case TYPE_DATA:
- return get_num_wrps();
- default:
- pr_warning("unknown slot type: %d\n", type);
- return 0;
- }
-}
-
-/* Determine debug architecture. */
-static u8 get_debug_arch(void)
-{
- u32 didr;
-
- /* Do we implement the extended CPUID interface? */
- if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
- pr_warning("CPUID feature registers not supported. "
- "Assuming v6 debug is present.\n");
- return ARM_DEBUG_ARCH_V6;
- }
-
- ARM_DBG_READ(c0, 0, didr);
- return (didr >> 16) & 0xf;
-}
-
-/* Does this core support mismatch breakpoints? */
-static int core_has_mismatch_bps(void)
-{
- return debug_arch >= ARM_DEBUG_ARCH_V7_ECP14 && core_num_brps > 1;
-}
-
-u8 arch_get_debug_arch(void)
-{
- return debug_arch;
-}
-
#define READ_WB_REG_CASE(OP2, M, VAL) \
case ((OP2 << 4) + M): \
ARM_DBG_READ(c ## M, OP2, VAL); \
@@ -210,6 +131,94 @@ static void write_wb_reg(int n, u32 val)
isb();
}
+/* Determine debug architecture. */
+static u8 get_debug_arch(void)
+{
+ u32 didr;
+
+ /* Do we implement the extended CPUID interface? */
+ if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
+ pr_warning("CPUID feature registers not supported. "
+ "Assuming v6 debug is present.\n");
+ return ARM_DEBUG_ARCH_V6;
+ }
+
+ ARM_DBG_READ(c0, 0, didr);
+ return (didr >> 16) & 0xf;
+}
+
+u8 arch_get_debug_arch(void)
+{
+ return debug_arch;
+}
+
+/* Determine number of BRP register available. */
+static int get_num_brp_resources(void)
+{
+ u32 didr;
+ ARM_DBG_READ(c0, 0, didr);
+ return ((didr >> 24) & 0xf) + 1;
+}
+
+/* Does this core support mismatch breakpoints? */
+static int core_has_mismatch_brps(void)
+{
+ return (get_debug_arch() >= ARM_DEBUG_ARCH_V7_ECP14 &&
+ get_num_brp_resources() > 1);
+}
+
+/* Determine number of usable WRPs available. */
+static int get_num_wrps(void)
+{
+ /*
+ * FIXME: When a watchpoint fires, the only way to work out which
+ * watchpoint it was is by disassembling the faulting instruction
+ * and working out the address of the memory access.
+ *
+ * Furthermore, we can only do this if the watchpoint was precise
+ * since imprecise watchpoints prevent us from calculating register
+ * based addresses.
+ *
+ * Providing we have more than 1 breakpoint register, we only report
+ * a single watchpoint register for the time being. This way, we always
+ * know which watchpoint fired. In the future we can either add a
+ * disassembler and address generation emulator, or we can insert a
+ * check to see if the DFAR is set on watchpoint exception entry
+ * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
+ * that it is set on some implementations].
+ */
+
+#if 0
+ int wrps;
+ u32 didr;
+ ARM_DBG_READ(c0, 0, didr);
+ wrps = ((didr >> 28) & 0xf) + 1;
+#endif
+ int wrps = 1;
+
+ if (core_has_mismatch_brps() && wrps >= get_num_brp_resources())
+ wrps = get_num_brp_resources() - 1;
+
+ return wrps;
+}
+
+/* We reserve one breakpoint for each watchpoint. */
+static int get_num_reserved_brps(void)
+{
+ if (core_has_mismatch_brps())
+ return get_num_wrps();
+ return 0;
+}
+
+/* Determine number of usable BRPs available. */
+static int get_num_brps(void)
+{
+ int brps = get_num_brp_resources();
+ if (core_has_mismatch_brps())
+ brps -= get_num_reserved_brps();
+ return brps;
+}
+
/*
* In order to access the breakpoint/watchpoint control registers,
* we must be running in debug monitor mode. Unfortunately, we can
@@ -230,8 +239,12 @@ static int enable_monitor_mode(void)
goto out;
}
+ /* If monitor mode is already enabled, just return. */
+ if (dscr & ARM_DSCR_MDBGEN)
+ goto out;
+
/* Write to the corresponding DSCR. */
- switch (debug_arch) {
+ switch (get_debug_arch()) {
case ARM_DEBUG_ARCH_V6:
case ARM_DEBUG_ARCH_V6_1:
ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
@@ -246,15 +259,30 @@ static int enable_monitor_mode(void)
/* Check that the write made it through. */
ARM_DBG_READ(c1, 0, dscr);
- if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN),
- "failed to enable monitor mode.")) {
+ if (!(dscr & ARM_DSCR_MDBGEN))
ret = -EPERM;
- }
out:
return ret;
}
+int hw_breakpoint_slots(int type)
+{
+ /*
+ * We can be called early, so don't rely on
+ * our static variables being initialised.
+ */
+ switch (type) {
+ case TYPE_INST:
+ return get_num_brps();
+ case TYPE_DATA:
+ return get_num_wrps();
+ default:
+ pr_warning("unknown slot type: %d\n", type);
+ return 0;
+ }
+}
+
/*
* Check if 8-bit byte-address select is available.
* This clobbers WRP 0.
@@ -268,9 +296,6 @@ static u8 get_max_wp_len(void)
if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14)
goto out;
- if (enable_monitor_mode())
- goto out;
-
memset(&ctrl, 0, sizeof(ctrl));
ctrl.len = ARM_BREAKPOINT_LEN_8;
ctrl_reg = encode_ctrl_reg(ctrl);
@@ -290,23 +315,6 @@ u8 arch_get_max_wp_len(void)
}
/*
- * Handler for reactivating a suspended watchpoint when the single
- * step `mismatch' breakpoint is triggered.
- */
-static void wp_single_step_handler(struct perf_event *bp, int unused,
- struct perf_sample_data *data,
- struct pt_regs *regs)
-{
- perf_event_enable(counter_arch_bp(bp)->suspended_wp);
- unregister_hw_breakpoint(bp);
-}
-
-static int bp_is_single_step(struct perf_event *bp)
-{
- return bp->overflow_handler == wp_single_step_handler;
-}
-
-/*
* Install a perf counter breakpoint.
*/
int arch_install_hw_breakpoint(struct perf_event *bp)
@@ -314,30 +322,41 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
struct perf_event **slot, **slots;
int i, max_slots, ctrl_base, val_base, ret = 0;
+ u32 addr, ctrl;
/* Ensure that we are in monitor mode and halting mode is disabled. */
ret = enable_monitor_mode();
if (ret)
goto out;
+ addr = info->address;
+ ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
+
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
/* Breakpoint */
ctrl_base = ARM_BASE_BCR;
val_base = ARM_BASE_BVR;
- slots = __get_cpu_var(bp_on_reg);
- max_slots = core_num_brps - 1;
-
- if (bp_is_single_step(bp)) {
- info->ctrl.mismatch = 1;
- i = max_slots;
- slots[i] = bp;
- goto setup;
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps;
+ if (info->step_ctrl.enabled) {
+ /* Override the breakpoint data with the step data. */
+ addr = info->trigger & ~0x3;
+ ctrl = encode_ctrl_reg(info->step_ctrl);
}
} else {
/* Watchpoint */
- ctrl_base = ARM_BASE_WCR;
- val_base = ARM_BASE_WVR;
- slots = __get_cpu_var(wp_on_reg);
+ if (info->step_ctrl.enabled) {
+ /* Install into the reserved breakpoint region. */
+ ctrl_base = ARM_BASE_BCR + core_num_brps;
+ val_base = ARM_BASE_BVR + core_num_brps;
+ /* Override the watchpoint data with the step data. */
+ addr = info->trigger & ~0x3;
+ ctrl = encode_ctrl_reg(info->step_ctrl);
+ } else {
+ ctrl_base = ARM_BASE_WCR;
+ val_base = ARM_BASE_WVR;
+ }
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
max_slots = core_num_wrps;
}
@@ -355,12 +374,11 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
goto out;
}
-setup:
/* Setup the address register. */
- write_wb_reg(val_base + i, info->address);
+ write_wb_reg(val_base + i, addr);
/* Setup the control register. */
- write_wb_reg(ctrl_base + i, encode_ctrl_reg(info->ctrl) | 0x1);
+ write_wb_reg(ctrl_base + i, ctrl);
out:
return ret;
@@ -375,18 +393,15 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
/* Breakpoint */
base = ARM_BASE_BCR;
- slots = __get_cpu_var(bp_on_reg);
- max_slots = core_num_brps - 1;
-
- if (bp_is_single_step(bp)) {
- i = max_slots;
- slots[i] = NULL;
- goto reset;
- }
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps;
} else {
/* Watchpoint */
- base = ARM_BASE_WCR;
- slots = __get_cpu_var(wp_on_reg);
+ if (info->step_ctrl.enabled)
+ base = ARM_BASE_BCR + core_num_brps;
+ else
+ base = ARM_BASE_WCR;
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
max_slots = core_num_wrps;
}
@@ -403,7 +418,6 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
return;
-reset:
/* Reset the control register. */
write_wb_reg(base + i, 0);
}
@@ -537,12 +551,23 @@ static int arch_build_bp_info(struct perf_event *bp)
return -EINVAL;
}
+ /*
+ * Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes.
+ * Watchpoints can be of length 1, 2, 4 or 8 bytes if supported
+ * by the hardware and must be aligned to the appropriate number of
+ * bytes.
+ */
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
+ info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
+ info->ctrl.len != ARM_BREAKPOINT_LEN_4)
+ return -EINVAL;
+
/* Address */
info->address = bp->attr.bp_addr;
/* Privilege */
info->ctrl.privilege = ARM_BREAKPOINT_USER;
- if (arch_check_bp_in_kernelspace(bp) && !bp_is_single_step(bp))
+ if (arch_check_bp_in_kernelspace(bp))
info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
/* Enabled? */
@@ -561,7 +586,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
{
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
int ret = 0;
- u32 bytelen, max_len, offset, alignment_mask = 0x3;
+ u32 offset, alignment_mask = 0x3;
/* Build the arch_hw_breakpoint. */
ret = arch_build_bp_info(bp);
@@ -571,84 +596,85 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
/* Check address alignment. */
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
alignment_mask = 0x7;
- if (info->address & alignment_mask) {
- /*
- * Try to fix the alignment. This may result in a length
- * that is too large, so we must check for that.
- */
- bytelen = get_hbp_len(info->ctrl.len);
- max_len = info->ctrl.type == ARM_BREAKPOINT_EXECUTE ? 4 :
- max_watchpoint_len;
-
- if (max_len >= 8)
- offset = info->address & 0x7;
- else
- offset = info->address & 0x3;
-
- if (bytelen > (1 << ((max_len - (offset + 1)) >> 1))) {
- ret = -EFBIG;
- goto out;
- }
-
- info->ctrl.len <<= offset;
- info->address &= ~offset;
-
- pr_debug("breakpoint alignment fixup: length = 0x%x, "
- "address = 0x%x\n", info->ctrl.len, info->address);
+ offset = info->address & alignment_mask;
+ switch (offset) {
+ case 0:
+ /* Aligned */
+ break;
+ case 1:
+ /* Allow single byte watchpoint. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
+ break;
+ case 2:
+ /* Allow halfword watchpoints and breakpoints. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
}
+ info->address &= ~alignment_mask;
+ info->ctrl.len <<= offset;
+
/*
* Currently we rely on an overflow handler to take
* care of single-stepping the breakpoint when it fires.
* In the case of userspace breakpoints on a core with V7 debug,
- * we can use the mismatch feature as a poor-man's hardware single-step.
+ * we can use the mismatch feature as a poor-man's hardware
+ * single-step, but this only works for per-task breakpoints.
*/
if (WARN_ONCE(!bp->overflow_handler &&
- (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_bps()),
+ (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
+ || !bp->hw.bp_target),
"overflow handler required but none found")) {
ret = -EINVAL;
- goto out;
}
out:
return ret;
}
-static void update_mismatch_flag(int idx, int flag)
+/*
+ * Enable/disable single-stepping over the breakpoint bp at address addr.
+ */
+static void enable_single_step(struct perf_event *bp, u32 addr)
{
- struct perf_event *bp = __get_cpu_var(bp_on_reg[idx]);
- struct arch_hw_breakpoint *info;
-
- if (bp == NULL)
- return;
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
- info = counter_arch_bp(bp);
+ arch_uninstall_hw_breakpoint(bp);
+ info->step_ctrl.mismatch = 1;
+ info->step_ctrl.len = ARM_BREAKPOINT_LEN_4;
+ info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE;
+ info->step_ctrl.privilege = info->ctrl.privilege;
+ info->step_ctrl.enabled = 1;
+ info->trigger = addr;
+ arch_install_hw_breakpoint(bp);
+}
- /* Update the mismatch field to enter/exit `single-step' mode */
- if (!bp->overflow_handler && info->ctrl.mismatch != flag) {
- info->ctrl.mismatch = flag;
- write_wb_reg(ARM_BASE_BCR + idx, encode_ctrl_reg(info->ctrl) | 0x1);
- }
+static void disable_single_step(struct perf_event *bp)
+{
+ arch_uninstall_hw_breakpoint(bp);
+ counter_arch_bp(bp)->step_ctrl.enabled = 0;
+ arch_install_hw_breakpoint(bp);
}
static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
{
int i;
- struct perf_event *bp, **slots = __get_cpu_var(wp_on_reg);
+ struct perf_event *wp, **slots;
struct arch_hw_breakpoint *info;
- struct perf_event_attr attr;
+
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
/* Without a disassembler, we can only handle 1 watchpoint. */
BUG_ON(core_num_wrps > 1);
- hw_breakpoint_init(&attr);
- attr.bp_addr = regs->ARM_pc & ~0x3;
- attr.bp_len = HW_BREAKPOINT_LEN_4;
- attr.bp_type = HW_BREAKPOINT_X;
-
for (i = 0; i < core_num_wrps; ++i) {
rcu_read_lock();
- if (slots[i] == NULL) {
+ wp = slots[i];
+
+ if (wp == NULL) {
rcu_read_unlock();
continue;
}
@@ -658,24 +684,51 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
* single watchpoint, we can set the trigger to the lowest
* possible faulting address.
*/
- info = counter_arch_bp(slots[i]);
- info->trigger = slots[i]->attr.bp_addr;
+ info = counter_arch_bp(wp);
+ info->trigger = wp->attr.bp_addr;
pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
- perf_bp_event(slots[i], regs);
+ perf_bp_event(wp, regs);
/*
* If no overflow handler is present, insert a temporary
* mismatch breakpoint so we can single-step over the
* watchpoint trigger.
*/
- if (!slots[i]->overflow_handler) {
- bp = register_user_hw_breakpoint(&attr,
- wp_single_step_handler,
- current);
- counter_arch_bp(bp)->suspended_wp = slots[i];
- perf_event_disable(slots[i]);
- }
+ if (!wp->overflow_handler)
+ enable_single_step(wp, instruction_pointer(regs));
+
+ rcu_read_unlock();
+ }
+}
+static void watchpoint_single_step_handler(unsigned long pc)
+{
+ int i;
+ struct perf_event *wp, **slots;
+ struct arch_hw_breakpoint *info;
+
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
+
+ for (i = 0; i < core_num_reserved_brps; ++i) {
+ rcu_read_lock();
+
+ wp = slots[i];
+
+ if (wp == NULL)
+ goto unlock;
+
+ info = counter_arch_bp(wp);
+ if (!info->step_ctrl.enabled)
+ goto unlock;
+
+ /*
+ * Restore the original watchpoint if we've completed the
+ * single-step.
+ */
+ if (info->trigger != pc)
+ disable_single_step(wp);
+
+unlock:
rcu_read_unlock();
}
}
@@ -683,62 +736,69 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
{
int i;
- int mismatch;
u32 ctrl_reg, val, addr;
- struct perf_event *bp, **slots = __get_cpu_var(bp_on_reg);
+ struct perf_event *bp, **slots;
struct arch_hw_breakpoint *info;
struct arch_hw_breakpoint_ctrl ctrl;
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+
/* The exception entry code places the amended lr in the PC. */
addr = regs->ARM_pc;
+ /* Check the currently installed breakpoints first. */
for (i = 0; i < core_num_brps; ++i) {
rcu_read_lock();
bp = slots[i];
- if (bp == NULL) {
- rcu_read_unlock();
- continue;
- }
+ if (bp == NULL)
+ goto unlock;
- mismatch = 0;
+ info = counter_arch_bp(bp);
/* Check if the breakpoint value matches. */
val = read_wb_reg(ARM_BASE_BVR + i);
if (val != (addr & ~0x3))
- goto unlock;
+ goto mismatch;
/* Possible match, check the byte address select to confirm. */
ctrl_reg = read_wb_reg(ARM_BASE_BCR + i);
decode_ctrl_reg(ctrl_reg, &ctrl);
if ((1 << (addr & 0x3)) & ctrl.len) {
- mismatch = 1;
- info = counter_arch_bp(bp);
info->trigger = addr;
- }
-
-unlock:
- if ((mismatch && !info->ctrl.mismatch) || bp_is_single_step(bp)) {
pr_debug("breakpoint fired: address = 0x%x\n", addr);
perf_bp_event(bp, regs);
+ if (!bp->overflow_handler)
+ enable_single_step(bp, addr);
+ goto unlock;
}
- update_mismatch_flag(i, mismatch);
+mismatch:
+ /* If we're stepping a breakpoint, it can now be restored. */
+ if (info->step_ctrl.enabled)
+ disable_single_step(bp);
+unlock:
rcu_read_unlock();
}
+
+ /* Handle any pending watchpoint single-step breakpoints. */
+ watchpoint_single_step_handler(addr);
}
/*
* Called from either the Data Abort Handler [watchpoint] or the
- * Prefetch Abort Handler [breakpoint].
+ * Prefetch Abort Handler [breakpoint] with preemption disabled.
*/
static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
{
- int ret = 1; /* Unhandled fault. */
+ int ret = 0;
u32 dscr;
+ /* We must be called with preemption disabled. */
+ WARN_ON(preemptible());
+
/* We only handle watchpoints and hardware breakpoints. */
ARM_DBG_READ(c1, 0, dscr);
@@ -753,25 +813,47 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
watchpoint_handler(addr, regs);
break;
default:
- goto out;
+ ret = 1; /* Unhandled fault. */
}
- ret = 0;
-out:
+ /*
+ * Re-enable preemption after it was disabled in the
+ * low-level exception handling code.
+ */
+ preempt_enable();
+
return ret;
}
/*
* One-time initialisation.
*/
-static void __init reset_ctrl_regs(void *unused)
+static void reset_ctrl_regs(void *unused)
{
int i;
+ /*
+ * v7 debug contains save and restore registers so that debug state
+ * can be maintained across low-power modes without leaving
+ * the debug logic powered up. It is IMPLEMENTATION DEFINED whether
+ * we can write to the debug registers out of reset, so we must
+ * unlock the OS Lock Access Register to avoid taking undefined
+ * instruction exceptions later on.
+ */
+ if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
+ /*
+ * Unconditionally clear the lock by writing a value
+ * other than 0xC5ACCE55 to the access register.
+ */
+ asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
+ isb();
+ }
+
if (enable_monitor_mode())
return;
- for (i = 0; i < core_num_brps; ++i) {
+ /* We must also reset any reserved registers. */
+ for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) {
write_wb_reg(ARM_BASE_BCR + i, 0UL);
write_wb_reg(ARM_BASE_BVR + i, 0UL);
}
@@ -782,45 +864,57 @@ static void __init reset_ctrl_regs(void *unused)
}
}
+static int __cpuinit dbg_reset_notify(struct notifier_block *self,
+ unsigned long action, void *cpu)
+{
+ if (action == CPU_ONLINE)
+ smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata dbg_reset_nb = {
+ .notifier_call = dbg_reset_notify,
+};
+
static int __init arch_hw_breakpoint_init(void)
{
- int ret = 0;
u32 dscr;
debug_arch = get_debug_arch();
if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) {
pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
- ret = -ENODEV;
- goto out;
+ return 0;
}
/* Determine how many BRPs/WRPs are available. */
core_num_brps = get_num_brps();
+ core_num_reserved_brps = get_num_reserved_brps();
core_num_wrps = get_num_wrps();
pr_info("found %d breakpoint and %d watchpoint registers.\n",
- core_num_brps, core_num_wrps);
+ core_num_brps + core_num_reserved_brps, core_num_wrps);
- if (core_has_mismatch_bps())
- pr_info("1 breakpoint reserved for watchpoint single-step.\n");
+ if (core_num_reserved_brps)
+ pr_info("%d breakpoint(s) reserved for watchpoint "
+ "single-step.\n", core_num_reserved_brps);
ARM_DBG_READ(c1, 0, dscr);
if (dscr & ARM_DSCR_HDBGEN) {
pr_warning("halting debug mode enabled. Assuming maximum "
"watchpoint size of 4 bytes.");
} else {
- /* Work out the maximum supported watchpoint length. */
- max_watchpoint_len = get_max_wp_len();
- pr_info("maximum watchpoint size is %u bytes.\n",
- max_watchpoint_len);
-
/*
* Reset the breakpoint resources. We assume that a halting
* debugger will leave the world in a nice state for us.
*/
smp_call_function(reset_ctrl_regs, NULL, 1);
reset_ctrl_regs(NULL);
+
+ /* Work out the maximum supported watchpoint length. */
+ max_watchpoint_len = get_max_wp_len();
+ pr_info("maximum watchpoint size is %u bytes.\n",
+ max_watchpoint_len);
}
/* Register debug fault handler. */
@@ -829,8 +923,9 @@ static int __init arch_hw_breakpoint_init(void)
hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
"breakpoint debug exception");
-out:
- return ret;
+ /* Register hotplug notifier. */
+ register_cpu_notifier(&dbg_reset_nb);
+ return 0;
}
arch_initcall(arch_hw_breakpoint_init);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 36ad3be4692a..8135438b8818 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -35,8 +35,10 @@
#include <linux/list.h>
#include <linux/kallsyms.h>
#include <linux/proc_fs.h>
+#include <linux/ftrace.h>
#include <asm/system.h>
+#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
@@ -47,8 +49,6 @@
#define irq_finish(irq) do { } while (0)
#endif
-unsigned int arch_nr_irqs;
-void (*init_arch_irq)(void) __initdata = NULL;
unsigned long irq_err_count;
int show_interrupts(struct seq_file *p, void *v)
@@ -57,11 +57,20 @@ int show_interrupts(struct seq_file *p, void *v)
struct irq_desc *desc;
struct irqaction * action;
unsigned long flags;
+ int prec, n;
+
+ for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
+ n *= 10;
+
+#ifdef CONFIG_SMP
+ if (prec < 4)
+ prec = 4;
+#endif
if (i == 0) {
char cpuname[12];
- seq_printf(p, " ");
+ seq_printf(p, "%*s ", prec, "");
for_each_present_cpu(cpu) {
sprintf(cpuname, "CPU%d", cpu);
seq_printf(p, " %10s", cpuname);
@@ -76,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (!action)
goto unlock;
- seq_printf(p, "%3d: ", i);
+ seq_printf(p, "%*d: ", prec, i);
for_each_present_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %10s", desc->chip->name ? : "-");
@@ -89,13 +98,15 @@ unlock:
raw_spin_unlock_irqrestore(&desc->lock, flags);
} else if (i == nr_irqs) {
#ifdef CONFIG_FIQ
- show_fiq_list(p, v);
+ show_fiq_list(p, prec);
#endif
#ifdef CONFIG_SMP
- show_ipi_list(p);
- show_local_irqs(p);
+ show_ipi_list(p, prec);
+#endif
+#ifdef CONFIG_LOCAL_TIMERS
+ show_local_irqs(p, prec);
#endif
- seq_printf(p, "Err: %10lu\n", irq_err_count);
+ seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
}
return 0;
}
@@ -105,7 +116,8 @@ unlock:
* come via this function. Instead, they should provide their
* own 'handler'
*/
-asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage void __exception_irq_entry
+asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
@@ -154,13 +166,13 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
void __init init_IRQ(void)
{
- init_arch_irq();
+ machine_desc->init_irq();
}
#ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void)
{
- nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
+ nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
return nr_irqs;
}
#endif
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index b63b528f22a6..7fa3bb0d2397 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -19,6 +19,14 @@
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
+#if defined(CONFIG_CPU_PJ4)
+#define PJ4(code...) code
+#define XSC(code...)
+#else
+#define PJ4(code...)
+#define XSC(code...) code
+#endif
+
#define MMX_WR0 (0x00)
#define MMX_WR1 (0x08)
#define MMX_WR2 (0x10)
@@ -58,11 +66,17 @@
ENTRY(iwmmxt_task_enable)
- mrc p15, 0, r2, c15, c1, 0
- tst r2, #0x3 @ CP0 and CP1 accessible?
+ XSC(mrc p15, 0, r2, c15, c1, 0)
+ PJ4(mrc p15, 0, r2, c1, c0, 2)
+ @ CP0 and CP1 accessible?
+ XSC(tst r2, #0x3)
+ PJ4(tst r2, #0xf)
movne pc, lr @ if so no business here
- orr r2, r2, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r2, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(orr r2, r2, #0x3)
+ XSC(mcr p15, 0, r2, c15, c1, 0)
+ PJ4(orr r2, r2, #0xf)
+ PJ4(mcr p15, 0, r2, c1, c0, 2)
ldr r3, =concan_owner
add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
@@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable)
teqne r1, r2 @ or specified one?
bne 1f @ no: quit
- mrc p15, 0, r4, c15, c1, 0
- orr r4, r4, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r4, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r4, c15, c1, 0)
+ XSC(orr r4, r4, #0xf)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
+ PJ4(mrc p15, 0, r4, c1, c0, 2)
+ PJ4(orr r4, r4, #0x3)
+ PJ4(mcr p15, 0, r4, c1, c0, 2)
+
mov r0, #0 @ nothing to load
str r0, [r3] @ no more current owner
mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait
bl concan_save
- bic r4, r4, #0x3 @ disable access to CP0 and CP1
- mcr p15, 0, r4, c15, c1, 0
+ @ disable access to CP0 and CP1
+ XSC(bic r4, r4, #0x3)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
+ PJ4(bic r4, r4, #0xf)
+ PJ4(mcr p15, 0, r4, c1, c0, 2)
+
mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait
@@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore)
*/
ENTRY(iwmmxt_task_switch)
- mrc p15, 0, r1, c15, c1, 0
- tst r1, #0x3 @ CP0 and CP1 accessible?
+ XSC(mrc p15, 0, r1, c15, c1, 0)
+ PJ4(mrc p15, 0, r1, c1, c0, 2)
+ @ CP0 and CP1 accessible?
+ XSC(tst r1, #0x3)
+ PJ4(tst r1, #0xf)
bne 1f @ yes: block them for next task
ldr r2, =concan_owner
@@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch)
teq r2, r3 @ next task owns it?
movne pc, lr @ no: leave Concan disabled
-1: eor r1, r1, #3 @ flip Concan access
- mcr p15, 0, r1, c15, c1, 0
+1: @ flip Conan access
+ XSC(eor r1, r1, #0x3)
+ XSC(mcr p15, 0, r1, c15, c1, 0)
+ PJ4(eor r1, r1, #0xf)
+ PJ4(mcr p15, 0, r1, c1, c0, 2)
mrc p15, 0, r1, c2, c0, 0
sub pc, lr, r1, lsr #32 @ cpwait and return
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 3a8fd5140d7a..30ead135ff5f 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -23,6 +23,8 @@ extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
extern unsigned long kexec_boot_atags;
+static atomic_t waiting_for_crash_ipi;
+
/*
* Provide a dummy crash_notes definition while crash dump arrives to arm.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -37,9 +39,37 @@ void machine_kexec_cleanup(struct kimage *image)
{
}
+void machine_crash_nonpanic_core(void *unused)
+{
+ struct pt_regs regs;
+
+ crash_setup_regs(&regs, NULL);
+ printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
+ smp_processor_id());
+ crash_save_cpu(&regs, smp_processor_id());
+ flush_cache_all();
+
+ atomic_dec(&waiting_for_crash_ipi);
+ while (1)
+ cpu_relax();
+}
+
void machine_crash_shutdown(struct pt_regs *regs)
{
+ unsigned long msecs;
+
local_irq_disable();
+
+ atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+ smp_call_function(machine_crash_nonpanic_core, NULL, false);
+ msecs = 1000; /* Wait at most a second for the other cpus to stop */
+ while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+ mdelay(1);
+ msecs--;
+ }
+ if (atomic_read(&waiting_for_crash_ipi) > 0)
+ printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
+
crash_save_cpu(regs, smp_processor_id());
printk(KERN_INFO "Loading crashdump kernel...\n");
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d9bd786ce23d..0c1bb68ff4a8 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -67,35 +67,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
char *secstrings,
struct module *mod)
{
-#ifdef CONFIG_ARM_UNWIND
- Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
- struct arm_unwind_mapping *maps = mod->arch.map;
-
- for (s = sechdrs; s < sechdrs_end; s++) {
- char const *secname = secstrings + s->sh_name;
-
- if (strcmp(".ARM.exidx.init.text", secname) == 0)
- maps[ARM_SEC_INIT].unw_sec = s;
- else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
- maps[ARM_SEC_DEVINIT].unw_sec = s;
- else if (strcmp(".ARM.exidx", secname) == 0)
- maps[ARM_SEC_CORE].unw_sec = s;
- else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
- maps[ARM_SEC_EXIT].unw_sec = s;
- else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
- maps[ARM_SEC_DEVEXIT].unw_sec = s;
- else if (strcmp(".init.text", secname) == 0)
- maps[ARM_SEC_INIT].sec_text = s;
- else if (strcmp(".devinit.text", secname) == 0)
- maps[ARM_SEC_DEVINIT].sec_text = s;
- else if (strcmp(".text", secname) == 0)
- maps[ARM_SEC_CORE].sec_text = s;
- else if (strcmp(".exit.text", secname) == 0)
- maps[ARM_SEC_EXIT].sec_text = s;
- else if (strcmp(".devexit.text", secname) == 0)
- maps[ARM_SEC_DEVEXIT].sec_text = s;
- }
-#endif
return 0;
}
@@ -300,41 +271,69 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
return -ENOEXEC;
}
-#ifdef CONFIG_ARM_UNWIND
-static void register_unwind_tables(struct module *mod)
+struct mod_unwind_map {
+ const Elf_Shdr *unw_sec;
+ const Elf_Shdr *txt_sec;
+};
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ struct module *mod)
{
+#ifdef CONFIG_ARM_UNWIND
+ const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+ struct mod_unwind_map maps[ARM_SEC_MAX];
int i;
- for (i = 0; i < ARM_SEC_MAX; ++i) {
- struct arm_unwind_mapping *map = &mod->arch.map[i];
- if (map->unw_sec && map->sec_text)
- map->unwind = unwind_table_add(map->unw_sec->sh_addr,
- map->unw_sec->sh_size,
- map->sec_text->sh_addr,
- map->sec_text->sh_size);
+
+ memset(maps, 0, sizeof(maps));
+
+ for (s = sechdrs; s < sechdrs_end; s++) {
+ const char *secname = secstrs + s->sh_name;
+
+ if (!(s->sh_flags & SHF_ALLOC))
+ continue;
+
+ if (strcmp(".ARM.exidx.init.text", secname) == 0)
+ maps[ARM_SEC_INIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx", secname) == 0)
+ maps[ARM_SEC_CORE].unw_sec = s;
+ else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].unw_sec = s;
+ else if (strcmp(".init.text", secname) == 0)
+ maps[ARM_SEC_INIT].txt_sec = s;
+ else if (strcmp(".devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].txt_sec = s;
+ else if (strcmp(".text", secname) == 0)
+ maps[ARM_SEC_CORE].txt_sec = s;
+ else if (strcmp(".exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].txt_sec = s;
+ else if (strcmp(".devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].txt_sec = s;
}
-}
-static void unregister_unwind_tables(struct module *mod)
-{
- int i = ARM_SEC_MAX;
- while (--i >= 0)
- unwind_table_del(mod->arch.map[i].unwind);
-}
-#else
-static inline void register_unwind_tables(struct module *mod) { }
-static inline void unregister_unwind_tables(struct module *mod) { }
+ for (i = 0; i < ARM_SEC_MAX; i++)
+ if (maps[i].unw_sec && maps[i].txt_sec)
+ mod->arch.unwind[i] =
+ unwind_table_add(maps[i].unw_sec->sh_addr,
+ maps[i].unw_sec->sh_size,
+ maps[i].txt_sec->sh_addr,
+ maps[i].txt_sec->sh_size);
#endif
-
-int
-module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
- struct module *module)
-{
- register_unwind_tables(module);
return 0;
}
void
module_arch_cleanup(struct module *mod)
{
- unregister_unwind_tables(mod);
+#ifdef CONFIG_ARM_UNWIND
+ int i;
+
+ for (i = 0; i < ARM_SEC_MAX; i++)
+ if (mod->arch.unwind[i])
+ unwind_table_del(mod->arch.unwind[i]);
+#endif
}
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 07a50357492a..624e2a5de2b3 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -4,9 +4,7 @@
* ARM performance counter support.
*
* Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
- *
- * ARMv7 support: Jean Pihet <jpihet@mvista.com>
- * 2010 (c) MontaVista Software, LLC.
+ * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
*
* This code is based on the sparc64 perf event code, which is in turn based
* on the x86 code. Callchain code is based on the ARM OProfile backtrace
@@ -34,7 +32,7 @@ static struct platform_device *pmu_device;
* Hardware lock to serialize accesses to PMU registers. Needed for the
* read/modify/write sequences.
*/
-DEFINE_SPINLOCK(pmu_lock);
+static DEFINE_RAW_SPINLOCK(pmu_lock);
/*
* ARMv6 supports a maximum of 3 events, starting from index 1. If we add
@@ -67,31 +65,25 @@ struct cpu_hw_events {
*/
unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
};
-DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
-
-/* PMU names. */
-static const char *arm_pmu_names[] = {
- [ARM_PERF_PMU_ID_XSCALE1] = "xscale1",
- [ARM_PERF_PMU_ID_XSCALE2] = "xscale2",
- [ARM_PERF_PMU_ID_V6] = "v6",
- [ARM_PERF_PMU_ID_V6MP] = "v6mpcore",
- [ARM_PERF_PMU_ID_CA8] = "ARMv7 Cortex-A8",
- [ARM_PERF_PMU_ID_CA9] = "ARMv7 Cortex-A9",
-};
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
struct arm_pmu {
enum arm_perf_pmu_ids id;
+ const char *name;
irqreturn_t (*handle_irq)(int irq_num, void *dev);
void (*enable)(struct hw_perf_event *evt, int idx);
void (*disable)(struct hw_perf_event *evt, int idx);
- int (*event_map)(int evt);
- u64 (*raw_event)(u64);
int (*get_event_idx)(struct cpu_hw_events *cpuc,
struct hw_perf_event *hwc);
u32 (*read_counter)(int idx);
void (*write_counter)(int idx, u32 val);
void (*start)(void);
void (*stop)(void);
+ const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+ const unsigned (*event_map)[PERF_COUNT_HW_MAX];
+ u32 raw_event_mask;
int num_events;
u64 max_period;
};
@@ -136,10 +128,6 @@ EXPORT_SYMBOL_GPL(perf_num_counters);
#define CACHE_OP_UNSUPPORTED 0xFFFF
-static unsigned armpmu_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-
static int
armpmu_map_cache_event(u64 config)
{
@@ -157,7 +145,7 @@ armpmu_map_cache_event(u64 config)
if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
return -EINVAL;
- ret = (int)armpmu_perf_cache_map[cache_type][cache_op][cache_result];
+ ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result];
if (ret == CACHE_OP_UNSUPPORTED)
return -ENOENT;
@@ -166,6 +154,19 @@ armpmu_map_cache_event(u64 config)
}
static int
+armpmu_map_event(u64 config)
+{
+ int mapping = (*armpmu->event_map)[config];
+ return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping;
+}
+
+static int
+armpmu_map_raw_event(u64 config)
+{
+ return (int)(config & armpmu->raw_event_mask);
+}
+
+static int
armpmu_event_set_period(struct perf_event *event,
struct hw_perf_event *hwc,
int idx)
@@ -458,11 +459,11 @@ __hw_perf_event_init(struct perf_event *event)
/* Decode the generic type into an ARM event identifier. */
if (PERF_TYPE_HARDWARE == event->attr.type) {
- mapping = armpmu->event_map(event->attr.config);
+ mapping = armpmu_map_event(event->attr.config);
} else if (PERF_TYPE_HW_CACHE == event->attr.type) {
mapping = armpmu_map_cache_event(event->attr.config);
} else if (PERF_TYPE_RAW == event->attr.type) {
- mapping = armpmu->raw_event(event->attr.config);
+ mapping = armpmu_map_raw_event(event->attr.config);
} else {
pr_debug("event type %x not supported\n", event->attr.type);
return -EOPNOTSUPP;
@@ -603,2366 +604,10 @@ static struct pmu pmu = {
.read = armpmu_read,
};
-/*
- * ARMv6 Performance counter handling code.
- *
- * ARMv6 has 2 configurable performance counters and a single cycle counter.
- * They all share a single reset bit but can be written to zero so we can use
- * that for a reset.
- *
- * The counters can't be individually enabled or disabled so when we remove
- * one event and replace it with another we could get spurious counts from the
- * wrong event. However, we can take advantage of the fact that the
- * performance counters can export events to the event bus, and the event bus
- * itself can be monitored. This requires that we *don't* export the events to
- * the event bus. The procedure for disabling a configurable counter is:
- * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
- * effectively stops the counter from counting.
- * - disable the counter's interrupt generation (each counter has it's
- * own interrupt enable bit).
- * Once stopped, the counter value can be written as 0 to reset.
- *
- * To enable a counter:
- * - enable the counter's interrupt generation.
- * - set the new event type.
- *
- * Note: the dedicated cycle counter only counts cycles and can't be
- * enabled/disabled independently of the others. When we want to disable the
- * cycle counter, we have to just disable the interrupt reporting and start
- * ignoring that counter. When re-enabling, we have to reset the value and
- * enable the interrupt.
- */
-
-enum armv6_perf_types {
- ARMV6_PERFCTR_ICACHE_MISS = 0x0,
- ARMV6_PERFCTR_IBUF_STALL = 0x1,
- ARMV6_PERFCTR_DDEP_STALL = 0x2,
- ARMV6_PERFCTR_ITLB_MISS = 0x3,
- ARMV6_PERFCTR_DTLB_MISS = 0x4,
- ARMV6_PERFCTR_BR_EXEC = 0x5,
- ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
- ARMV6_PERFCTR_INSTR_EXEC = 0x7,
- ARMV6_PERFCTR_DCACHE_HIT = 0x9,
- ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
- ARMV6_PERFCTR_DCACHE_MISS = 0xB,
- ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
- ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
- ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
- ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
- ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
- ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
- ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
- ARMV6_PERFCTR_NOP = 0x20,
-};
-
-enum armv6_counters {
- ARMV6_CYCLE_COUNTER = 1,
- ARMV6_COUNTER0,
- ARMV6_COUNTER1,
-};
-
-/*
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
- [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
- [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
-};
-
-static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- /*
- * The performance counters don't differentiate between read
- * and write accesses/misses so this isn't strictly correct,
- * but it's the best we can do. Writes and reads get
- * combined.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- /*
- * The ARM performance counters can count micro DTLB misses,
- * micro ITLB misses and main TLB misses. There isn't an event
- * for TLB misses, so use the micro misses here and if users
- * want the main TLB misses they can use a raw counter.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-enum armv6mpcore_perf_types {
- ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
- ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
- ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
- ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
- ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
- ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
- ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
- ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
- ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
- ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
- ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
- ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
- ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
- ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
- ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
- ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
- ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
- ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
- ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
- ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
-};
-
-/*
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
- [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
- [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
-};
-
-static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
- [C(RESULT_MISS)] =
- ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] =
- ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
- [C(RESULT_MISS)] =
- ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- /*
- * The ARM performance counters can count micro DTLB misses,
- * micro ITLB misses and main TLB misses. There isn't an event
- * for TLB misses, so use the micro misses here and if users
- * want the main TLB misses they can use a raw counter.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-static inline unsigned long
-armv6_pmcr_read(void)
-{
- u32 val;
- asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
- return val;
-}
-
-static inline void
-armv6_pmcr_write(unsigned long val)
-{
- asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
-}
-
-#define ARMV6_PMCR_ENABLE (1 << 0)
-#define ARMV6_PMCR_CTR01_RESET (1 << 1)
-#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
-#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
-#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
-#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
-#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
-#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
-#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
-#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
-#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
-#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
-#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
-#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
-
-#define ARMV6_PMCR_OVERFLOWED_MASK \
- (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
- ARMV6_PMCR_CCOUNT_OVERFLOW)
-
-static inline int
-armv6_pmcr_has_overflowed(unsigned long pmcr)
-{
- return (pmcr & ARMV6_PMCR_OVERFLOWED_MASK);
-}
-
-static inline int
-armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
- enum armv6_counters counter)
-{
- int ret = 0;
-
- if (ARMV6_CYCLE_COUNTER == counter)
- ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
- else if (ARMV6_COUNTER0 == counter)
- ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
- else if (ARMV6_COUNTER1 == counter)
- ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-
- return ret;
-}
-
-static inline u32
-armv6pmu_read_counter(int counter)
-{
- unsigned long value = 0;
-
- if (ARMV6_CYCLE_COUNTER == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
- else if (ARMV6_COUNTER0 == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
- else if (ARMV6_COUNTER1 == counter)
- asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-
- return value;
-}
-
-static inline void
-armv6pmu_write_counter(int counter,
- u32 value)
-{
- if (ARMV6_CYCLE_COUNTER == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
- else if (ARMV6_COUNTER0 == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
- else if (ARMV6_COUNTER1 == counter)
- asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
- else
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
-}
-
-void
-armv6pmu_enable_event(struct hw_perf_event *hwc,
- int idx)
-{
- unsigned long val, mask, evt, flags;
-
- if (ARMV6_CYCLE_COUNTER == idx) {
- mask = 0;
- evt = ARMV6_PMCR_CCOUNT_IEN;
- } else if (ARMV6_COUNTER0 == idx) {
- mask = ARMV6_PMCR_EVT_COUNT0_MASK;
- evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
- ARMV6_PMCR_COUNT0_IEN;
- } else if (ARMV6_COUNTER1 == idx) {
- mask = ARMV6_PMCR_EVT_COUNT1_MASK;
- evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
- ARMV6_PMCR_COUNT1_IEN;
- } else {
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- /*
- * Mask out the current event and set the counter to count the event
- * that we're interested in.
- */
- spin_lock_irqsave(&pmu_lock, flags);
- val = armv6_pmcr_read();
- val &= ~mask;
- val |= evt;
- armv6_pmcr_write(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static irqreturn_t
-armv6pmu_handle_irq(int irq_num,
- void *dev)
-{
- unsigned long pmcr = armv6_pmcr_read();
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct pt_regs *regs;
- int idx;
-
- if (!armv6_pmcr_has_overflowed(pmcr))
- return IRQ_NONE;
-
- regs = get_irq_regs();
-
- /*
- * The interrupts are cleared by writing the overflow flags back to
- * the control register. All of the other bits don't have any effect
- * if they are rewritten, so write the whole value back.
- */
- armv6_pmcr_write(pmcr);
-
- perf_sample_data_init(&data, 0);
-
- cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx <= armpmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- /*
- * We have a single interrupt for all counters. Check that
- * each counter has overflowed before we process it.
- */
- if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
- data.period = event->hw.last_period;
- if (!armpmu_event_set_period(event, hwc, idx))
- continue;
-
- if (perf_event_overflow(event, 0, &data, regs))
- armpmu->disable(hwc, idx);
- }
-
- /*
- * Handle the pending perf events.
- *
- * Note: this call *must* be run with interrupts disabled. For
- * platforms that can have the PMU interrupts raised as an NMI, this
- * will not work.
- */
- irq_work_run();
-
- return IRQ_HANDLED;
-}
-
-static void
-armv6pmu_start(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = armv6_pmcr_read();
- val |= ARMV6_PMCR_ENABLE;
- armv6_pmcr_write(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-void
-armv6pmu_stop(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = armv6_pmcr_read();
- val &= ~ARMV6_PMCR_ENABLE;
- armv6_pmcr_write(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static inline int
-armv6pmu_event_map(int config)
-{
- int mapping = armv6_perf_map[config];
- if (HW_OP_UNSUPPORTED == mapping)
- mapping = -EOPNOTSUPP;
- return mapping;
-}
-
-static inline int
-armv6mpcore_pmu_event_map(int config)
-{
- int mapping = armv6mpcore_perf_map[config];
- if (HW_OP_UNSUPPORTED == mapping)
- mapping = -EOPNOTSUPP;
- return mapping;
-}
-
-static u64
-armv6pmu_raw_event(u64 config)
-{
- return config & 0xff;
-}
-
-static int
-armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
- struct hw_perf_event *event)
-{
- /* Always place a cycle counter into the cycle counter. */
- if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
- if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return ARMV6_CYCLE_COUNTER;
- } else {
- /*
- * For anything other than a cycle counter, try and use
- * counter0 and counter1.
- */
- if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) {
- return ARMV6_COUNTER1;
- }
-
- if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) {
- return ARMV6_COUNTER0;
- }
-
- /* The counters are all in use. */
- return -EAGAIN;
- }
-}
-
-static void
-armv6pmu_disable_event(struct hw_perf_event *hwc,
- int idx)
-{
- unsigned long val, mask, evt, flags;
-
- if (ARMV6_CYCLE_COUNTER == idx) {
- mask = ARMV6_PMCR_CCOUNT_IEN;
- evt = 0;
- } else if (ARMV6_COUNTER0 == idx) {
- mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
- evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
- } else if (ARMV6_COUNTER1 == idx) {
- mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
- evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
- } else {
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- /*
- * Mask out the current event and set the counter to count the number
- * of ETM bus signal assertion cycles. The external reporting should
- * be disabled and so this should never increment.
- */
- spin_lock_irqsave(&pmu_lock, flags);
- val = armv6_pmcr_read();
- val &= ~mask;
- val |= evt;
- armv6_pmcr_write(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void
-armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
- int idx)
-{
- unsigned long val, mask, flags, evt = 0;
-
- if (ARMV6_CYCLE_COUNTER == idx) {
- mask = ARMV6_PMCR_CCOUNT_IEN;
- } else if (ARMV6_COUNTER0 == idx) {
- mask = ARMV6_PMCR_COUNT0_IEN;
- } else if (ARMV6_COUNTER1 == idx) {
- mask = ARMV6_PMCR_COUNT1_IEN;
- } else {
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- /*
- * Unlike UP ARMv6, we don't have a way of stopping the counters. We
- * simply disable the interrupt reporting.
- */
- spin_lock_irqsave(&pmu_lock, flags);
- val = armv6_pmcr_read();
- val &= ~mask;
- val |= evt;
- armv6_pmcr_write(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static const struct arm_pmu armv6pmu = {
- .id = ARM_PERF_PMU_ID_V6,
- .handle_irq = armv6pmu_handle_irq,
- .enable = armv6pmu_enable_event,
- .disable = armv6pmu_disable_event,
- .event_map = armv6pmu_event_map,
- .raw_event = armv6pmu_raw_event,
- .read_counter = armv6pmu_read_counter,
- .write_counter = armv6pmu_write_counter,
- .get_event_idx = armv6pmu_get_event_idx,
- .start = armv6pmu_start,
- .stop = armv6pmu_stop,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-/*
- * ARMv6mpcore is almost identical to single core ARMv6 with the exception
- * that some of the events have different enumerations and that there is no
- * *hack* to stop the programmable counters. To stop the counters we simply
- * disable the interrupt reporting and update the event. When unthrottling we
- * reset the period and enable the interrupt reporting.
- */
-static const struct arm_pmu armv6mpcore_pmu = {
- .id = ARM_PERF_PMU_ID_V6MP,
- .handle_irq = armv6pmu_handle_irq,
- .enable = armv6pmu_enable_event,
- .disable = armv6mpcore_pmu_disable_event,
- .event_map = armv6mpcore_pmu_event_map,
- .raw_event = armv6pmu_raw_event,
- .read_counter = armv6pmu_read_counter,
- .write_counter = armv6pmu_write_counter,
- .get_event_idx = armv6pmu_get_event_idx,
- .start = armv6pmu_start,
- .stop = armv6pmu_stop,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-/*
- * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
- *
- * Copied from ARMv6 code, with the low level code inspired
- * by the ARMv7 Oprofile code.
- *
- * Cortex-A8 has up to 4 configurable performance counters and
- * a single cycle counter.
- * Cortex-A9 has up to 31 configurable performance counters and
- * a single cycle counter.
- *
- * All counters can be enabled/disabled and IRQ masked separately. The cycle
- * counter and all 4 performance counters together can be reset separately.
- */
-
-/* Common ARMv7 event types */
-enum armv7_perf_types {
- ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
- ARMV7_PERFCTR_IFETCH_MISS = 0x01,
- ARMV7_PERFCTR_ITLB_MISS = 0x02,
- ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
- ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
- ARMV7_PERFCTR_DTLB_REFILL = 0x05,
- ARMV7_PERFCTR_DREAD = 0x06,
- ARMV7_PERFCTR_DWRITE = 0x07,
-
- ARMV7_PERFCTR_EXC_TAKEN = 0x09,
- ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
- ARMV7_PERFCTR_CID_WRITE = 0x0B,
- /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
- * It counts:
- * - all branch instructions,
- * - instructions that explicitly write the PC,
- * - exception generating instructions.
- */
- ARMV7_PERFCTR_PC_WRITE = 0x0C,
- ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
- ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
- ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
- ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
-
- ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
-
- ARMV7_PERFCTR_CPU_CYCLES = 0xFF
-};
-
-/* ARMv7 Cortex-A8 specific event types */
-enum armv7_a8_perf_types {
- ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
-
- ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
-
- ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
- ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
- ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
- ARMV7_PERFCTR_L2_ACCESS = 0x43,
- ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
- ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
- ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
- ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
- ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
- ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
- ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
- ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
- ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
- ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
- ARMV7_PERFCTR_L2_NEON = 0x4E,
- ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
- ARMV7_PERFCTR_L1_INST = 0x50,
- ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
- ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
- ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
- ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
- ARMV7_PERFCTR_OP_EXECUTED = 0x55,
- ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
- ARMV7_PERFCTR_CYCLES_INST = 0x57,
- ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
- ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
- ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
-
- ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
- ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
- ARMV7_PERFCTR_PMU_EVENTS = 0x72,
-};
-
-/* ARMv7 Cortex-A9 specific event types */
-enum armv7_a9_perf_types {
- ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
- ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
- ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
-
- ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
- ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
-
- ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
- ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
- ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
- ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
- ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
- ARMV7_PERFCTR_DATA_EVICTION = 0x65,
- ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
- ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
- ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
-
- ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
-
- ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
- ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
- ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
- ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
- ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
-
- ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
- ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
- ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
- ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
- ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
- ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
- ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
-
- ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
- ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
-
- ARMV7_PERFCTR_ISB_INST = 0x90,
- ARMV7_PERFCTR_DSB_INST = 0x91,
- ARMV7_PERFCTR_DMB_INST = 0x92,
- ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
-
- ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
- ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
- ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
- ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
- ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
- ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
-};
-
-/*
- * Cortex-A8 HW events mapping
- *
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
-};
-
-static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- /*
- * The performance counters don't differentiate between read
- * and write accesses/misses so this isn't strictly correct,
- * but it's the best we can do. Writes and reads get
- * combined.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
- [C(RESULT_MISS)]
- = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
- [C(RESULT_MISS)]
- = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-/*
- * Cortex-A9 HW events mapping
- */
-static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] =
- ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
-};
-
-static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- /*
- * The performance counters don't differentiate between read
- * and write accesses/misses so this isn't strictly correct,
- * but it's the best we can do. Writes and reads get
- * combined.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
- [C(RESULT_MISS)]
- = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
- [C(RESULT_MISS)]
- = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-/*
- * Perf Events counters
- */
-enum armv7_counters {
- ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
- ARMV7_COUNTER0 = 2, /* First event counter */
-};
-
-/*
- * The cycle counter is ARMV7_CYCLE_COUNTER.
- * The first event counter is ARMV7_COUNTER0.
- * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
- */
-#define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
-
-/*
- * ARMv7 low level PMNC access
- */
-
-/*
- * Per-CPU PMNC: config reg
- */
-#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
-#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
-#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
-#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
-#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
-#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
-#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
-#define ARMV7_PMNC_N_MASK 0x1f
-#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
-
-/*
- * Available counters
- */
-#define ARMV7_CNT0 0 /* First event counter */
-#define ARMV7_CCNT 31 /* Cycle counter */
-
-/* Perf Event to low level counters mapping */
-#define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
-
-/*
- * CNTENS: counters enable reg
- */
-#define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
-#define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
-
-/*
- * CNTENC: counters disable reg
- */
-#define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
-#define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
-
-/*
- * INTENS: counters overflow interrupt enable reg
- */
-#define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
-#define ARMV7_INTENS_C (1 << ARMV7_CCNT)
-
-/*
- * INTENC: counters overflow interrupt disable reg
- */
-#define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
-#define ARMV7_INTENC_C (1 << ARMV7_CCNT)
-
-/*
- * EVTSEL: Event selection reg
- */
-#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
-
-/*
- * SELECT: Counter selection reg
- */
-#define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
-
-/*
- * FLAG: counters overflow flag status reg
- */
-#define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
-#define ARMV7_FLAG_C (1 << ARMV7_CCNT)
-#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
-#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
-
-static inline unsigned long armv7_pmnc_read(void)
-{
- u32 val;
- asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
- return val;
-}
-
-static inline void armv7_pmnc_write(unsigned long val)
-{
- val &= ARMV7_PMNC_MASK;
- asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
-}
-
-static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
-{
- return pmnc & ARMV7_OVERFLOWED_MASK;
-}
-
-static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
- enum armv7_counters counter)
-{
- int ret = 0;
-
- if (counter == ARMV7_CYCLE_COUNTER)
- ret = pmnc & ARMV7_FLAG_C;
- else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
- ret = pmnc & ARMV7_FLAG_P(counter);
- else
- pr_err("CPU%u checking wrong counter %d overflow status\n",
- smp_processor_id(), counter);
-
- return ret;
-}
-
-static inline int armv7_pmnc_select_counter(unsigned int idx)
-{
- u32 val;
-
- if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
- pr_err("CPU%u selecting wrong PMNC counter"
- " %d\n", smp_processor_id(), idx);
- return -1;
- }
-
- val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
- asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
-
- return idx;
-}
-
-static inline u32 armv7pmu_read_counter(int idx)
-{
- unsigned long value = 0;
-
- if (idx == ARMV7_CYCLE_COUNTER)
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
- else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
- if (armv7_pmnc_select_counter(idx) == idx)
- asm volatile("mrc p15, 0, %0, c9, c13, 2"
- : "=r" (value));
- } else
- pr_err("CPU%u reading wrong counter %d\n",
- smp_processor_id(), idx);
-
- return value;
-}
-
-static inline void armv7pmu_write_counter(int idx, u32 value)
-{
- if (idx == ARMV7_CYCLE_COUNTER)
- asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
- else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
- if (armv7_pmnc_select_counter(idx) == idx)
- asm volatile("mcr p15, 0, %0, c9, c13, 2"
- : : "r" (value));
- } else
- pr_err("CPU%u writing wrong counter %d\n",
- smp_processor_id(), idx);
-}
-
-static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
-{
- if (armv7_pmnc_select_counter(idx) == idx) {
- val &= ARMV7_EVTSEL_MASK;
- asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
- }
-}
-
-static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
-{
- u32 val;
-
- if ((idx != ARMV7_CYCLE_COUNTER) &&
- ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
- pr_err("CPU%u enabling wrong PMNC counter"
- " %d\n", smp_processor_id(), idx);
- return -1;
- }
-
- if (idx == ARMV7_CYCLE_COUNTER)
- val = ARMV7_CNTENS_C;
- else
- val = ARMV7_CNTENS_P(idx);
-
- asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
-
- return idx;
-}
-
-static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
-{
- u32 val;
-
-
- if ((idx != ARMV7_CYCLE_COUNTER) &&
- ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
- pr_err("CPU%u disabling wrong PMNC counter"
- " %d\n", smp_processor_id(), idx);
- return -1;
- }
-
- if (idx == ARMV7_CYCLE_COUNTER)
- val = ARMV7_CNTENC_C;
- else
- val = ARMV7_CNTENC_P(idx);
-
- asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
-
- return idx;
-}
-
-static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
-{
- u32 val;
-
- if ((idx != ARMV7_CYCLE_COUNTER) &&
- ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
- pr_err("CPU%u enabling wrong PMNC counter"
- " interrupt enable %d\n", smp_processor_id(), idx);
- return -1;
- }
-
- if (idx == ARMV7_CYCLE_COUNTER)
- val = ARMV7_INTENS_C;
- else
- val = ARMV7_INTENS_P(idx);
-
- asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
-
- return idx;
-}
-
-static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
-{
- u32 val;
-
- if ((idx != ARMV7_CYCLE_COUNTER) &&
- ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
- pr_err("CPU%u disabling wrong PMNC counter"
- " interrupt enable %d\n", smp_processor_id(), idx);
- return -1;
- }
-
- if (idx == ARMV7_CYCLE_COUNTER)
- val = ARMV7_INTENC_C;
- else
- val = ARMV7_INTENC_P(idx);
-
- asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
-
- return idx;
-}
-
-static inline u32 armv7_pmnc_getreset_flags(void)
-{
- u32 val;
-
- /* Read */
- asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-
- /* Write to clear flags */
- val &= ARMV7_FLAG_MASK;
- asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
-
- return val;
-}
-
-#ifdef DEBUG
-static void armv7_pmnc_dump_regs(void)
-{
- u32 val;
- unsigned int cnt;
-
- printk(KERN_INFO "PMNC registers dump:\n");
-
- asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
- printk(KERN_INFO "PMNC =0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
- printk(KERN_INFO "CNTENS=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
- printk(KERN_INFO "INTENS=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
- printk(KERN_INFO "FLAGS =0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
- printk(KERN_INFO "SELECT=0x%08x\n", val);
-
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
- printk(KERN_INFO "CCNT =0x%08x\n", val);
-
- for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
- armv7_pmnc_select_counter(cnt);
- asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
- printk(KERN_INFO "CNT[%d] count =0x%08x\n",
- cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
- asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
- printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
- cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
- }
-}
-#endif
-
-void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long flags;
-
- /*
- * Enable counter and interrupt, and set the counter to count
- * the event that we're interested in.
- */
- spin_lock_irqsave(&pmu_lock, flags);
-
- /*
- * Disable counter
- */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Set event (if destined for PMNx counters)
- * We don't need to set the event if it's a cycle count
- */
- if (idx != ARMV7_CYCLE_COUNTER)
- armv7_pmnc_write_evtsel(idx, hwc->config_base);
-
- /*
- * Enable interrupt for this counter
- */
- armv7_pmnc_enable_intens(idx);
-
- /*
- * Enable counter
- */
- armv7_pmnc_enable_counter(idx);
-
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long flags;
-
- /*
- * Disable counter and interrupt
- */
- spin_lock_irqsave(&pmu_lock, flags);
-
- /*
- * Disable counter
- */
- armv7_pmnc_disable_counter(idx);
-
- /*
- * Disable interrupt for this counter
- */
- armv7_pmnc_disable_intens(idx);
-
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
-{
- unsigned long pmnc;
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct pt_regs *regs;
- int idx;
-
- /*
- * Get and reset the IRQ flags
- */
- pmnc = armv7_pmnc_getreset_flags();
-
- /*
- * Did an overflow occur?
- */
- if (!armv7_pmnc_has_overflowed(pmnc))
- return IRQ_NONE;
-
- /*
- * Handle the counter(s) overflow(s)
- */
- regs = get_irq_regs();
-
- perf_sample_data_init(&data, 0);
-
- cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx <= armpmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- /*
- * We have a single interrupt for all counters. Check that
- * each counter has overflowed before we process it.
- */
- if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
- data.period = event->hw.last_period;
- if (!armpmu_event_set_period(event, hwc, idx))
- continue;
-
- if (perf_event_overflow(event, 0, &data, regs))
- armpmu->disable(hwc, idx);
- }
-
- /*
- * Handle the pending perf events.
- *
- * Note: this call *must* be run with interrupts disabled. For
- * platforms that can have the PMU interrupts raised as an NMI, this
- * will not work.
- */
- irq_work_run();
-
- return IRQ_HANDLED;
-}
-
-static void armv7pmu_start(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pmu_lock, flags);
- /* Enable all counters */
- armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void armv7pmu_stop(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pmu_lock, flags);
- /* Disable all counters */
- armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static inline int armv7_a8_pmu_event_map(int config)
-{
- int mapping = armv7_a8_perf_map[config];
- if (HW_OP_UNSUPPORTED == mapping)
- mapping = -EOPNOTSUPP;
- return mapping;
-}
-
-static inline int armv7_a9_pmu_event_map(int config)
-{
- int mapping = armv7_a9_perf_map[config];
- if (HW_OP_UNSUPPORTED == mapping)
- mapping = -EOPNOTSUPP;
- return mapping;
-}
-
-static u64 armv7pmu_raw_event(u64 config)
-{
- return config & 0xff;
-}
-
-static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
- struct hw_perf_event *event)
-{
- int idx;
-
- /* Always place a cycle counter into the cycle counter. */
- if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
- if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return ARMV7_CYCLE_COUNTER;
- } else {
- /*
- * For anything other than a cycle counter, try and use
- * the events counters
- */
- for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
- if (!test_and_set_bit(idx, cpuc->used_mask))
- return idx;
- }
-
- /* The counters are all in use. */
- return -EAGAIN;
- }
-}
-
-static struct arm_pmu armv7pmu = {
- .handle_irq = armv7pmu_handle_irq,
- .enable = armv7pmu_enable_event,
- .disable = armv7pmu_disable_event,
- .raw_event = armv7pmu_raw_event,
- .read_counter = armv7pmu_read_counter,
- .write_counter = armv7pmu_write_counter,
- .get_event_idx = armv7pmu_get_event_idx,
- .start = armv7pmu_start,
- .stop = armv7pmu_stop,
- .max_period = (1LLU << 32) - 1,
-};
-
-static u32 __init armv7_reset_read_pmnc(void)
-{
- u32 nb_cnt;
-
- /* Initialize & Reset PMNC: C and P bits */
- armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
-
- /* Read the nb of CNTx counters supported from PMNC */
- nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
-
- /* Add the CPU cycles counter and return */
- return nb_cnt + 1;
-}
-
-/*
- * ARMv5 [xscale] Performance counter handling code.
- *
- * Based on xscale OProfile code.
- *
- * There are two variants of the xscale PMU that we support:
- * - xscale1pmu: 2 event counters and a cycle counter
- * - xscale2pmu: 4 event counters and a cycle counter
- * The two variants share event definitions, but have different
- * PMU structures.
- */
-
-enum xscale_perf_types {
- XSCALE_PERFCTR_ICACHE_MISS = 0x00,
- XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
- XSCALE_PERFCTR_DATA_STALL = 0x02,
- XSCALE_PERFCTR_ITLB_MISS = 0x03,
- XSCALE_PERFCTR_DTLB_MISS = 0x04,
- XSCALE_PERFCTR_BRANCH = 0x05,
- XSCALE_PERFCTR_BRANCH_MISS = 0x06,
- XSCALE_PERFCTR_INSTRUCTION = 0x07,
- XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
- XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
- XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
- XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
- XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
- XSCALE_PERFCTR_PC_CHANGED = 0x0D,
- XSCALE_PERFCTR_BCU_REQUEST = 0x10,
- XSCALE_PERFCTR_BCU_FULL = 0x11,
- XSCALE_PERFCTR_BCU_DRAIN = 0x12,
- XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
- XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
- XSCALE_PERFCTR_RMW = 0x16,
- /* XSCALE_PERFCTR_CCNT is not hardware defined */
- XSCALE_PERFCTR_CCNT = 0xFE,
- XSCALE_PERFCTR_UNUSED = 0xFF,
-};
-
-enum xscale_counters {
- XSCALE_CYCLE_COUNTER = 1,
- XSCALE_COUNTER0,
- XSCALE_COUNTER1,
- XSCALE_COUNTER2,
- XSCALE_COUNTER3,
-};
-
-static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
- [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
- [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
- [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
- [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
-};
-
-static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-#define XSCALE_PMU_ENABLE 0x001
-#define XSCALE_PMN_RESET 0x002
-#define XSCALE_CCNT_RESET 0x004
-#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
-#define XSCALE_PMU_CNT64 0x008
-
-static inline int
-xscalepmu_event_map(int config)
-{
- int mapping = xscale_perf_map[config];
- if (HW_OP_UNSUPPORTED == mapping)
- mapping = -EOPNOTSUPP;
- return mapping;
-}
-
-static u64
-xscalepmu_raw_event(u64 config)
-{
- return config & 0xff;
-}
-
-#define XSCALE1_OVERFLOWED_MASK 0x700
-#define XSCALE1_CCOUNT_OVERFLOW 0x400
-#define XSCALE1_COUNT0_OVERFLOW 0x100
-#define XSCALE1_COUNT1_OVERFLOW 0x200
-#define XSCALE1_CCOUNT_INT_EN 0x040
-#define XSCALE1_COUNT0_INT_EN 0x010
-#define XSCALE1_COUNT1_INT_EN 0x020
-#define XSCALE1_COUNT0_EVT_SHFT 12
-#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
-#define XSCALE1_COUNT1_EVT_SHFT 20
-#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
-
-static inline u32
-xscale1pmu_read_pmnc(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale1pmu_write_pmnc(u32 val)
-{
- /* upper 4bits and 7, 11 are write-as-0 */
- val &= 0xffff77f;
- asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
-}
-
-static inline int
-xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
- enum xscale_counters counter)
-{
- int ret = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
- break;
- case XSCALE_COUNTER0:
- ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
- break;
- case XSCALE_COUNTER1:
- ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
- }
-
- return ret;
-}
-
-static irqreturn_t
-xscale1pmu_handle_irq(int irq_num, void *dev)
-{
- unsigned long pmnc;
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct pt_regs *regs;
- int idx;
-
- /*
- * NOTE: there's an A stepping erratum that states if an overflow
- * bit already exists and another occurs, the previous
- * Overflow bit gets cleared. There's no workaround.
- * Fixed in B stepping or later.
- */
- pmnc = xscale1pmu_read_pmnc();
-
- /*
- * Write the value back to clear the overflow flags. Overflow
- * flags remain in pmnc for use below. We also disable the PMU
- * while we process the interrupt.
- */
- xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
-
- if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
- return IRQ_NONE;
-
- regs = get_irq_regs();
-
- perf_sample_data_init(&data, 0);
-
- cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx <= armpmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
- data.period = event->hw.last_period;
- if (!armpmu_event_set_period(event, hwc, idx))
- continue;
-
- if (perf_event_overflow(event, 0, &data, regs))
- armpmu->disable(hwc, idx);
- }
-
- irq_work_run();
-
- /*
- * Re-enable the PMU.
- */
- pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(pmnc);
-
- return IRQ_HANDLED;
-}
-
-static void
-xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long val, mask, evt, flags;
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- mask = 0;
- evt = XSCALE1_CCOUNT_INT_EN;
- break;
- case XSCALE_COUNTER0:
- mask = XSCALE1_COUNT0_EVT_MASK;
- evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
- XSCALE1_COUNT0_INT_EN;
- break;
- case XSCALE_COUNTER1:
- mask = XSCALE1_COUNT1_EVT_MASK;
- evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
- XSCALE1_COUNT1_INT_EN;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale1pmu_read_pmnc();
- val &= ~mask;
- val |= evt;
- xscale1pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void
-xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long val, mask, evt, flags;
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- mask = XSCALE1_CCOUNT_INT_EN;
- evt = 0;
- break;
- case XSCALE_COUNTER0:
- mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
- evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
- break;
- case XSCALE_COUNTER1:
- mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
- evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale1pmu_read_pmnc();
- val &= ~mask;
- val |= evt;
- xscale1pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static int
-xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
- struct hw_perf_event *event)
-{
- if (XSCALE_PERFCTR_CCNT == event->config_base) {
- if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
- return -EAGAIN;
-
- return XSCALE_CYCLE_COUNTER;
- } else {
- if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) {
- return XSCALE_COUNTER1;
- }
-
- if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) {
- return XSCALE_COUNTER0;
- }
-
- return -EAGAIN;
- }
-}
-
-static void
-xscale1pmu_start(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale1pmu_read_pmnc();
- val |= XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void
-xscale1pmu_stop(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale1pmu_read_pmnc();
- val &= ~XSCALE_PMU_ENABLE;
- xscale1pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static inline u32
-xscale1pmu_read_counter(int counter)
-{
- u32 val = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
- break;
- }
-
- return val;
-}
-
-static inline void
-xscale1pmu_write_counter(int counter, u32 val)
-{
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
- break;
- }
-}
-
-static const struct arm_pmu xscale1pmu = {
- .id = ARM_PERF_PMU_ID_XSCALE1,
- .handle_irq = xscale1pmu_handle_irq,
- .enable = xscale1pmu_enable_event,
- .disable = xscale1pmu_disable_event,
- .event_map = xscalepmu_event_map,
- .raw_event = xscalepmu_raw_event,
- .read_counter = xscale1pmu_read_counter,
- .write_counter = xscale1pmu_write_counter,
- .get_event_idx = xscale1pmu_get_event_idx,
- .start = xscale1pmu_start,
- .stop = xscale1pmu_stop,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-#define XSCALE2_OVERFLOWED_MASK 0x01f
-#define XSCALE2_CCOUNT_OVERFLOW 0x001
-#define XSCALE2_COUNT0_OVERFLOW 0x002
-#define XSCALE2_COUNT1_OVERFLOW 0x004
-#define XSCALE2_COUNT2_OVERFLOW 0x008
-#define XSCALE2_COUNT3_OVERFLOW 0x010
-#define XSCALE2_CCOUNT_INT_EN 0x001
-#define XSCALE2_COUNT0_INT_EN 0x002
-#define XSCALE2_COUNT1_INT_EN 0x004
-#define XSCALE2_COUNT2_INT_EN 0x008
-#define XSCALE2_COUNT3_INT_EN 0x010
-#define XSCALE2_COUNT0_EVT_SHFT 0
-#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
-#define XSCALE2_COUNT1_EVT_SHFT 8
-#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
-#define XSCALE2_COUNT2_EVT_SHFT 16
-#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
-#define XSCALE2_COUNT3_EVT_SHFT 24
-#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
-
-static inline u32
-xscale2pmu_read_pmnc(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
- /* bits 1-2 and 4-23 are read-unpredictable */
- return val & 0xff000009;
-}
-
-static inline void
-xscale2pmu_write_pmnc(u32 val)
-{
- /* bits 4-23 are write-as-0, 24-31 are write ignored */
- val &= 0xf;
- asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
-}
-
-static inline u32
-xscale2pmu_read_overflow_flags(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale2pmu_write_overflow_flags(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
-}
-
-static inline u32
-xscale2pmu_read_event_select(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
- return val;
-}
-
-static inline void
-xscale2pmu_write_event_select(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
-}
-
-static inline u32
-xscale2pmu_read_int_enable(void)
-{
- u32 val;
- asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
- return val;
-}
-
-static void
-xscale2pmu_write_int_enable(u32 val)
-{
- asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
-}
-
-static inline int
-xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
- enum xscale_counters counter)
-{
- int ret = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
- break;
- case XSCALE_COUNTER0:
- ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
- break;
- case XSCALE_COUNTER1:
- ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
- break;
- case XSCALE_COUNTER2:
- ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
- break;
- case XSCALE_COUNTER3:
- ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", counter);
- }
-
- return ret;
-}
-
-static irqreturn_t
-xscale2pmu_handle_irq(int irq_num, void *dev)
-{
- unsigned long pmnc, of_flags;
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct pt_regs *regs;
- int idx;
-
- /* Disable the PMU. */
- pmnc = xscale2pmu_read_pmnc();
- xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
-
- /* Check the overflow flag register. */
- of_flags = xscale2pmu_read_overflow_flags();
- if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
- return IRQ_NONE;
-
- /* Clear the overflow bits. */
- xscale2pmu_write_overflow_flags(of_flags);
-
- regs = get_irq_regs();
-
- perf_sample_data_init(&data, 0);
-
- cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx <= armpmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
- continue;
-
- hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
- data.period = event->hw.last_period;
- if (!armpmu_event_set_period(event, hwc, idx))
- continue;
-
- if (perf_event_overflow(event, 0, &data, regs))
- armpmu->disable(hwc, idx);
- }
-
- irq_work_run();
-
- /*
- * Re-enable the PMU.
- */
- pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(pmnc);
-
- return IRQ_HANDLED;
-}
-
-static void
-xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long flags, ien, evtsel;
-
- ien = xscale2pmu_read_int_enable();
- evtsel = xscale2pmu_read_event_select();
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- ien |= XSCALE2_CCOUNT_INT_EN;
- break;
- case XSCALE_COUNTER0:
- ien |= XSCALE2_COUNT0_INT_EN;
- evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
- break;
- case XSCALE_COUNTER1:
- ien |= XSCALE2_COUNT1_INT_EN;
- evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
- break;
- case XSCALE_COUNTER2:
- ien |= XSCALE2_COUNT2_INT_EN;
- evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
- break;
- case XSCALE_COUNTER3:
- ien |= XSCALE2_COUNT3_INT_EN;
- evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
- evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- spin_lock_irqsave(&pmu_lock, flags);
- xscale2pmu_write_event_select(evtsel);
- xscale2pmu_write_int_enable(ien);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void
-xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
- unsigned long flags, ien, evtsel;
-
- ien = xscale2pmu_read_int_enable();
- evtsel = xscale2pmu_read_event_select();
-
- switch (idx) {
- case XSCALE_CYCLE_COUNTER:
- ien &= ~XSCALE2_CCOUNT_INT_EN;
- break;
- case XSCALE_COUNTER0:
- ien &= ~XSCALE2_COUNT0_INT_EN;
- evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
- break;
- case XSCALE_COUNTER1:
- ien &= ~XSCALE2_COUNT1_INT_EN;
- evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
- break;
- case XSCALE_COUNTER2:
- ien &= ~XSCALE2_COUNT2_INT_EN;
- evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
- break;
- case XSCALE_COUNTER3:
- ien &= ~XSCALE2_COUNT3_INT_EN;
- evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
- evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
- break;
- default:
- WARN_ONCE(1, "invalid counter number (%d)\n", idx);
- return;
- }
-
- spin_lock_irqsave(&pmu_lock, flags);
- xscale2pmu_write_event_select(evtsel);
- xscale2pmu_write_int_enable(ien);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static int
-xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
- struct hw_perf_event *event)
-{
- int idx = xscale1pmu_get_event_idx(cpuc, event);
- if (idx >= 0)
- goto out;
-
- if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
- idx = XSCALE_COUNTER3;
- else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
- idx = XSCALE_COUNTER2;
-out:
- return idx;
-}
-
-static void
-xscale2pmu_start(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
- val |= XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static void
-xscale2pmu_stop(void)
-{
- unsigned long flags, val;
-
- spin_lock_irqsave(&pmu_lock, flags);
- val = xscale2pmu_read_pmnc();
- val &= ~XSCALE_PMU_ENABLE;
- xscale2pmu_write_pmnc(val);
- spin_unlock_irqrestore(&pmu_lock, flags);
-}
-
-static inline u32
-xscale2pmu_read_counter(int counter)
-{
- u32 val = 0;
-
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER2:
- asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
- break;
- case XSCALE_COUNTER3:
- asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
- break;
- }
-
- return val;
-}
-
-static inline void
-xscale2pmu_write_counter(int counter, u32 val)
-{
- switch (counter) {
- case XSCALE_CYCLE_COUNTER:
- asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER0:
- asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER1:
- asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER2:
- asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
- break;
- case XSCALE_COUNTER3:
- asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
- break;
- }
-}
-
-static const struct arm_pmu xscale2pmu = {
- .id = ARM_PERF_PMU_ID_XSCALE2,
- .handle_irq = xscale2pmu_handle_irq,
- .enable = xscale2pmu_enable_event,
- .disable = xscale2pmu_disable_event,
- .event_map = xscalepmu_event_map,
- .raw_event = xscalepmu_raw_event,
- .read_counter = xscale2pmu_read_counter,
- .write_counter = xscale2pmu_write_counter,
- .get_event_idx = xscale2pmu_get_event_idx,
- .start = xscale2pmu_start,
- .stop = xscale2pmu_stop,
- .num_events = 5,
- .max_period = (1LLU << 32) - 1,
-};
+/* Include the PMU-specific implementations. */
+#include "perf_event_xscale.c"
+#include "perf_event_v6.c"
+#include "perf_event_v7.c"
static int __init
init_hw_perf_events(void)
@@ -2977,37 +622,16 @@ init_hw_perf_events(void)
case 0xB360: /* ARM1136 */
case 0xB560: /* ARM1156 */
case 0xB760: /* ARM1176 */
- armpmu = &armv6pmu;
- memcpy(armpmu_perf_cache_map, armv6_perf_cache_map,
- sizeof(armv6_perf_cache_map));
+ armpmu = armv6pmu_init();
break;
case 0xB020: /* ARM11mpcore */
- armpmu = &armv6mpcore_pmu;
- memcpy(armpmu_perf_cache_map,
- armv6mpcore_perf_cache_map,
- sizeof(armv6mpcore_perf_cache_map));
+ armpmu = armv6mpcore_pmu_init();
break;
case 0xC080: /* Cortex-A8 */
- armv7pmu.id = ARM_PERF_PMU_ID_CA8;
- memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
- sizeof(armv7_a8_perf_cache_map));
- armv7pmu.event_map = armv7_a8_pmu_event_map;
- armpmu = &armv7pmu;
-
- /* Reset PMNC and read the nb of CNTx counters
- supported */
- armv7pmu.num_events = armv7_reset_read_pmnc();
+ armpmu = armv7_a8_pmu_init();
break;
case 0xC090: /* Cortex-A9 */
- armv7pmu.id = ARM_PERF_PMU_ID_CA9;
- memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
- sizeof(armv7_a9_perf_cache_map));
- armv7pmu.event_map = armv7_a9_pmu_event_map;
- armpmu = &armv7pmu;
-
- /* Reset PMNC and read the nb of CNTx counters
- supported */
- armv7pmu.num_events = armv7_reset_read_pmnc();
+ armpmu = armv7_a9_pmu_init();
break;
}
/* Intel CPUs [xscale]. */
@@ -3015,21 +639,17 @@ init_hw_perf_events(void)
part_number = (cpuid >> 13) & 0x7;
switch (part_number) {
case 1:
- armpmu = &xscale1pmu;
- memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
- sizeof(xscale_perf_cache_map));
+ armpmu = xscale1pmu_init();
break;
case 2:
- armpmu = &xscale2pmu;
- memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
- sizeof(xscale_perf_cache_map));
+ armpmu = xscale2pmu_init();
break;
}
}
if (armpmu) {
pr_info("enabled with %s PMU driver, %d counters available\n",
- arm_pmu_names[armpmu->id], armpmu->num_events);
+ armpmu->name, armpmu->num_events);
} else {
pr_info("no hardware support available\n");
}
@@ -3053,17 +673,17 @@ arch_initcall(init_hw_perf_events);
* This code has been adapted from the ARM OProfile support.
*/
struct frame_tail {
- struct frame_tail *fp;
- unsigned long sp;
- unsigned long lr;
+ struct frame_tail __user *fp;
+ unsigned long sp;
+ unsigned long lr;
} __attribute__((packed));
/*
* Get the return address for a single stackframe and return a pointer to the
* next frame tail.
*/
-static struct frame_tail *
-user_backtrace(struct frame_tail *tail,
+static struct frame_tail __user *
+user_backtrace(struct frame_tail __user *tail,
struct perf_callchain_entry *entry)
{
struct frame_tail buftail;
@@ -3089,10 +709,10 @@ user_backtrace(struct frame_tail *tail,
void
perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
- struct frame_tail *tail;
+ struct frame_tail __user *tail;
- tail = (struct frame_tail *)regs->ARM_fp - 1;
+ tail = (struct frame_tail __user *)regs->ARM_fp - 1;
while (tail && !((unsigned long)tail & 0x3))
tail = user_backtrace(tail, entry);
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
new file mode 100644
index 000000000000..c058bfc8532b
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -0,0 +1,672 @@
+/*
+ * ARMv6 Performance counter handling code.
+ *
+ * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
+ *
+ * ARMv6 has 2 configurable performance counters and a single cycle counter.
+ * They all share a single reset bit but can be written to zero so we can use
+ * that for a reset.
+ *
+ * The counters can't be individually enabled or disabled so when we remove
+ * one event and replace it with another we could get spurious counts from the
+ * wrong event. However, we can take advantage of the fact that the
+ * performance counters can export events to the event bus, and the event bus
+ * itself can be monitored. This requires that we *don't* export the events to
+ * the event bus. The procedure for disabling a configurable counter is:
+ * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
+ * effectively stops the counter from counting.
+ * - disable the counter's interrupt generation (each counter has it's
+ * own interrupt enable bit).
+ * Once stopped, the counter value can be written as 0 to reset.
+ *
+ * To enable a counter:
+ * - enable the counter's interrupt generation.
+ * - set the new event type.
+ *
+ * Note: the dedicated cycle counter only counts cycles and can't be
+ * enabled/disabled independently of the others. When we want to disable the
+ * cycle counter, we have to just disable the interrupt reporting and start
+ * ignoring that counter. When re-enabling, we have to reset the value and
+ * enable the interrupt.
+ */
+
+#ifdef CONFIG_CPU_V6
+enum armv6_perf_types {
+ ARMV6_PERFCTR_ICACHE_MISS = 0x0,
+ ARMV6_PERFCTR_IBUF_STALL = 0x1,
+ ARMV6_PERFCTR_DDEP_STALL = 0x2,
+ ARMV6_PERFCTR_ITLB_MISS = 0x3,
+ ARMV6_PERFCTR_DTLB_MISS = 0x4,
+ ARMV6_PERFCTR_BR_EXEC = 0x5,
+ ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
+ ARMV6_PERFCTR_INSTR_EXEC = 0x7,
+ ARMV6_PERFCTR_DCACHE_HIT = 0x9,
+ ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
+ ARMV6_PERFCTR_DCACHE_MISS = 0xB,
+ ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
+ ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
+ ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
+ ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
+ ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
+ ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
+ ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
+ ARMV6_PERFCTR_NOP = 0x20,
+};
+
+enum armv6_counters {
+ ARMV6_CYCLE_COUNTER = 1,
+ ARMV6_COUNTER0,
+ ARMV6_COUNTER1,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ /*
+ * The ARM performance counters can count micro DTLB misses,
+ * micro ITLB misses and main TLB misses. There isn't an event
+ * for TLB misses, so use the micro misses here and if users
+ * want the main TLB misses they can use a raw counter.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+enum armv6mpcore_perf_types {
+ ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
+ ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
+ ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
+ ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
+ ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
+ ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
+ ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
+ ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
+ ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
+ ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
+ ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
+ ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
+ ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
+ ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
+ ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
+ ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
+ ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
+ ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
+ ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
+ ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
+ [C(RESULT_MISS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
+ [C(RESULT_MISS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ /*
+ * The ARM performance counters can count micro DTLB misses,
+ * micro ITLB misses and main TLB misses. There isn't an event
+ * for TLB misses, so use the micro misses here and if users
+ * want the main TLB misses they can use a raw counter.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+static inline unsigned long
+armv6_pmcr_read(void)
+{
+ u32 val;
+ asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
+ return val;
+}
+
+static inline void
+armv6_pmcr_write(unsigned long val)
+{
+ asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
+}
+
+#define ARMV6_PMCR_ENABLE (1 << 0)
+#define ARMV6_PMCR_CTR01_RESET (1 << 1)
+#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
+#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
+#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
+#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
+#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
+#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
+#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
+#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
+#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
+#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
+#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
+#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
+
+#define ARMV6_PMCR_OVERFLOWED_MASK \
+ (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
+ ARMV6_PMCR_CCOUNT_OVERFLOW)
+
+static inline int
+armv6_pmcr_has_overflowed(unsigned long pmcr)
+{
+ return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
+}
+
+static inline int
+armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
+ enum armv6_counters counter)
+{
+ int ret = 0;
+
+ if (ARMV6_CYCLE_COUNTER == counter)
+ ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
+ else if (ARMV6_COUNTER0 == counter)
+ ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
+ else if (ARMV6_COUNTER1 == counter)
+ ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+ return ret;
+}
+
+static inline u32
+armv6pmu_read_counter(int counter)
+{
+ unsigned long value = 0;
+
+ if (ARMV6_CYCLE_COUNTER == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
+ else if (ARMV6_COUNTER0 == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
+ else if (ARMV6_COUNTER1 == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+ return value;
+}
+
+static inline void
+armv6pmu_write_counter(int counter,
+ u32 value)
+{
+ if (ARMV6_CYCLE_COUNTER == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
+ else if (ARMV6_COUNTER0 == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
+ else if (ARMV6_COUNTER1 == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+}
+
+static void
+armv6pmu_enable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = 0;
+ evt = ARMV6_PMCR_CCOUNT_IEN;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_EVT_COUNT0_MASK;
+ evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
+ ARMV6_PMCR_COUNT0_IEN;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_EVT_COUNT1_MASK;
+ evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
+ ARMV6_PMCR_COUNT1_IEN;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Mask out the current event and set the counter to count the event
+ * that we're interested in.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t
+armv6pmu_handle_irq(int irq_num,
+ void *dev)
+{
+ unsigned long pmcr = armv6_pmcr_read();
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ if (!armv6_pmcr_has_overflowed(pmcr))
+ return IRQ_NONE;
+
+ regs = get_irq_regs();
+
+ /*
+ * The interrupts are cleared by writing the overflow flags back to
+ * the control register. All of the other bits don't have any effect
+ * if they are rewritten, so write the whole value back.
+ */
+ armv6_pmcr_write(pmcr);
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ /*
+ * We have a single interrupt for all counters. Check that
+ * each counter has overflowed before we process it.
+ */
+ if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ /*
+ * Handle the pending perf events.
+ *
+ * Note: this call *must* be run with interrupts disabled. For
+ * platforms that can have the PMU interrupts raised as an NMI, this
+ * will not work.
+ */
+ irq_work_run();
+
+ return IRQ_HANDLED;
+}
+
+static void
+armv6pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val |= ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ /* Always place a cycle counter into the cycle counter. */
+ if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
+ if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return ARMV6_CYCLE_COUNTER;
+ } else {
+ /*
+ * For anything other than a cycle counter, try and use
+ * counter0 and counter1.
+ */
+ if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
+ return ARMV6_COUNTER1;
+
+ if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
+ return ARMV6_COUNTER0;
+
+ /* The counters are all in use. */
+ return -EAGAIN;
+ }
+}
+
+static void
+armv6pmu_disable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = ARMV6_PMCR_CCOUNT_IEN;
+ evt = 0;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
+ evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
+ evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Mask out the current event and set the counter to count the number
+ * of ETM bus signal assertion cycles. The external reporting should
+ * be disabled and so this should never increment.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, flags, evt = 0;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = ARMV6_PMCR_CCOUNT_IEN;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_COUNT0_IEN;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_COUNT1_IEN;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Unlike UP ARMv6, we don't have a way of stopping the counters. We
+ * simply disable the interrupt reporting.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static const struct arm_pmu armv6pmu = {
+ .id = ARM_PERF_PMU_ID_V6,
+ .name = "v6",
+ .handle_irq = armv6pmu_handle_irq,
+ .enable = armv6pmu_enable_event,
+ .disable = armv6pmu_disable_event,
+ .read_counter = armv6pmu_read_counter,
+ .write_counter = armv6pmu_write_counter,
+ .get_event_idx = armv6pmu_get_event_idx,
+ .start = armv6pmu_start,
+ .stop = armv6pmu_stop,
+ .cache_map = &armv6_perf_cache_map,
+ .event_map = &armv6_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init armv6pmu_init(void)
+{
+ return &armv6pmu;
+}
+
+/*
+ * ARMv6mpcore is almost identical to single core ARMv6 with the exception
+ * that some of the events have different enumerations and that there is no
+ * *hack* to stop the programmable counters. To stop the counters we simply
+ * disable the interrupt reporting and update the event. When unthrottling we
+ * reset the period and enable the interrupt reporting.
+ */
+static const struct arm_pmu armv6mpcore_pmu = {
+ .id = ARM_PERF_PMU_ID_V6MP,
+ .name = "v6mpcore",
+ .handle_irq = armv6pmu_handle_irq,
+ .enable = armv6pmu_enable_event,
+ .disable = armv6mpcore_pmu_disable_event,
+ .read_counter = armv6pmu_read_counter,
+ .write_counter = armv6pmu_write_counter,
+ .get_event_idx = armv6pmu_get_event_idx,
+ .start = armv6pmu_start,
+ .stop = armv6pmu_stop,
+ .cache_map = &armv6mpcore_perf_cache_map,
+ .event_map = &armv6mpcore_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
+{
+ return &armv6mpcore_pmu;
+}
+#else
+static const struct arm_pmu *__init armv6pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_V6 */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
new file mode 100644
index 000000000000..2e1402556fa0
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -0,0 +1,906 @@
+/*
+ * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
+ *
+ * ARMv7 support: Jean Pihet <jpihet@mvista.com>
+ * 2010 (c) MontaVista Software, LLC.
+ *
+ * Copied from ARMv6 code, with the low level code inspired
+ * by the ARMv7 Oprofile code.
+ *
+ * Cortex-A8 has up to 4 configurable performance counters and
+ * a single cycle counter.
+ * Cortex-A9 has up to 31 configurable performance counters and
+ * a single cycle counter.
+ *
+ * All counters can be enabled/disabled and IRQ masked separately. The cycle
+ * counter and all 4 performance counters together can be reset separately.
+ */
+
+#ifdef CONFIG_CPU_V7
+/* Common ARMv7 event types */
+enum armv7_perf_types {
+ ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
+ ARMV7_PERFCTR_IFETCH_MISS = 0x01,
+ ARMV7_PERFCTR_ITLB_MISS = 0x02,
+ ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
+ ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
+ ARMV7_PERFCTR_DTLB_REFILL = 0x05,
+ ARMV7_PERFCTR_DREAD = 0x06,
+ ARMV7_PERFCTR_DWRITE = 0x07,
+
+ ARMV7_PERFCTR_EXC_TAKEN = 0x09,
+ ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
+ ARMV7_PERFCTR_CID_WRITE = 0x0B,
+ /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+ * It counts:
+ * - all branch instructions,
+ * - instructions that explicitly write the PC,
+ * - exception generating instructions.
+ */
+ ARMV7_PERFCTR_PC_WRITE = 0x0C,
+ ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
+ ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
+ ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
+ ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
+
+ ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
+
+ ARMV7_PERFCTR_CPU_CYCLES = 0xFF
+};
+
+/* ARMv7 Cortex-A8 specific event types */
+enum armv7_a8_perf_types {
+ ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
+
+ ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
+
+ ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
+ ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
+ ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
+ ARMV7_PERFCTR_L2_ACCESS = 0x43,
+ ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
+ ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
+ ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
+ ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
+ ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
+ ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
+ ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
+ ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
+ ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
+ ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
+ ARMV7_PERFCTR_L2_NEON = 0x4E,
+ ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
+ ARMV7_PERFCTR_L1_INST = 0x50,
+ ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
+ ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
+ ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
+ ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
+ ARMV7_PERFCTR_OP_EXECUTED = 0x55,
+ ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
+ ARMV7_PERFCTR_CYCLES_INST = 0x57,
+ ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
+ ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
+ ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
+
+ ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
+ ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
+ ARMV7_PERFCTR_PMU_EVENTS = 0x72,
+};
+
+/* ARMv7 Cortex-A9 specific event types */
+enum armv7_a9_perf_types {
+ ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
+ ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
+ ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
+
+ ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
+ ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
+
+ ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
+ ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
+ ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
+ ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
+ ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
+ ARMV7_PERFCTR_DATA_EVICTION = 0x65,
+ ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
+ ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
+ ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
+
+ ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
+
+ ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
+ ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
+ ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
+ ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
+ ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
+
+ ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
+ ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
+ ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
+ ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
+ ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
+ ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
+ ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
+
+ ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
+ ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
+
+ ARMV7_PERFCTR_ISB_INST = 0x90,
+ ARMV7_PERFCTR_DSB_INST = 0x91,
+ ARMV7_PERFCTR_DMB_INST = 0x92,
+ ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
+
+ ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
+ ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
+ ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
+ ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
+ ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
+ ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
+};
+
+/*
+ * Cortex-A8 HW events mapping
+ *
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ /*
+ * Only ITLB misses and DTLB refills are supported.
+ * If users want the DTLB refills misses a raw counter
+ * must be used.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
+ * Cortex-A9 HW events mapping
+ */
+static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] =
+ ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ /*
+ * Only ITLB misses and DTLB refills are supported.
+ * If users want the DTLB refills misses a raw counter
+ * must be used.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
+ * Perf Events counters
+ */
+enum armv7_counters {
+ ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
+ ARMV7_COUNTER0 = 2, /* First event counter */
+};
+
+/*
+ * The cycle counter is ARMV7_CYCLE_COUNTER.
+ * The first event counter is ARMV7_COUNTER0.
+ * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
+ */
+#define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
+
+/*
+ * ARMv7 low level PMNC access
+ */
+
+/*
+ * Per-CPU PMNC: config reg
+ */
+#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
+#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
+#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
+#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
+#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
+#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
+#define ARMV7_PMNC_N_MASK 0x1f
+#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
+
+/*
+ * Available counters
+ */
+#define ARMV7_CNT0 0 /* First event counter */
+#define ARMV7_CCNT 31 /* Cycle counter */
+
+/* Perf Event to low level counters mapping */
+#define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
+
+/*
+ * CNTENS: counters enable reg
+ */
+#define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
+
+/*
+ * CNTENC: counters disable reg
+ */
+#define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
+
+/*
+ * INTENS: counters overflow interrupt enable reg
+ */
+#define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENS_C (1 << ARMV7_CCNT)
+
+/*
+ * INTENC: counters overflow interrupt disable reg
+ */
+#define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENC_C (1 << ARMV7_CCNT)
+
+/*
+ * EVTSEL: Event selection reg
+ */
+#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
+
+/*
+ * SELECT: Counter selection reg
+ */
+#define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_FLAG_C (1 << ARMV7_CCNT)
+#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
+#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
+
+static inline unsigned long armv7_pmnc_read(void)
+{
+ u32 val;
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
+ return val;
+}
+
+static inline void armv7_pmnc_write(unsigned long val)
+{
+ val &= ARMV7_PMNC_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
+}
+
+static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
+{
+ return pmnc & ARMV7_OVERFLOWED_MASK;
+}
+
+static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
+ enum armv7_counters counter)
+{
+ int ret = 0;
+
+ if (counter == ARMV7_CYCLE_COUNTER)
+ ret = pmnc & ARMV7_FLAG_C;
+ else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
+ ret = pmnc & ARMV7_FLAG_P(counter);
+ else
+ pr_err("CPU%u checking wrong counter %d overflow status\n",
+ smp_processor_id(), counter);
+
+ return ret;
+}
+
+static inline int armv7_pmnc_select_counter(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
+ pr_err("CPU%u selecting wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7pmu_read_counter(int idx)
+{
+ unsigned long value = 0;
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
+ else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+ if (armv7_pmnc_select_counter(idx) == idx)
+ asm volatile("mrc p15, 0, %0, c9, c13, 2"
+ : "=r" (value));
+ } else
+ pr_err("CPU%u reading wrong counter %d\n",
+ smp_processor_id(), idx);
+
+ return value;
+}
+
+static inline void armv7pmu_write_counter(int idx, u32 value)
+{
+ if (idx == ARMV7_CYCLE_COUNTER)
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
+ else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+ if (armv7_pmnc_select_counter(idx) == idx)
+ asm volatile("mcr p15, 0, %0, c9, c13, 2"
+ : : "r" (value));
+ } else
+ pr_err("CPU%u writing wrong counter %d\n",
+ smp_processor_id(), idx);
+}
+
+static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
+{
+ if (armv7_pmnc_select_counter(idx) == idx) {
+ val &= ARMV7_EVTSEL_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+ }
+}
+
+static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u enabling wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_CNTENS_C;
+ else
+ val = ARMV7_CNTENS_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
+{
+ u32 val;
+
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u disabling wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_CNTENC_C;
+ else
+ val = ARMV7_CNTENC_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u enabling wrong PMNC counter"
+ " interrupt enable %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_INTENS_C;
+ else
+ val = ARMV7_INTENS_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u disabling wrong PMNC counter"
+ " interrupt enable %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_INTENC_C;
+ else
+ val = ARMV7_INTENC_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_getreset_flags(void)
+{
+ u32 val;
+
+ /* Read */
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+
+ /* Write to clear flags */
+ val &= ARMV7_FLAG_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
+
+ return val;
+}
+
+#ifdef DEBUG
+static void armv7_pmnc_dump_regs(void)
+{
+ u32 val;
+ unsigned int cnt;
+
+ printk(KERN_INFO "PMNC registers dump:\n");
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+ printk(KERN_INFO "PMNC =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+ printk(KERN_INFO "CNTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+ printk(KERN_INFO "INTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+ printk(KERN_INFO "FLAGS =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+ printk(KERN_INFO "SELECT=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+ printk(KERN_INFO "CCNT =0x%08x\n", val);
+
+ for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
+ armv7_pmnc_select_counter(cnt);
+ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+ printk(KERN_INFO "CNT[%d] count =0x%08x\n",
+ cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+ asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+ printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
+ cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+ }
+}
+#endif
+
+static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags;
+
+ /*
+ * Enable counter and interrupt, and set the counter to count
+ * the event that we're interested in.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Set event (if destined for PMNx counters)
+ * We don't need to set the event if it's a cycle count
+ */
+ if (idx != ARMV7_CYCLE_COUNTER)
+ armv7_pmnc_write_evtsel(idx, hwc->config_base);
+
+ /*
+ * Enable interrupt for this counter
+ */
+ armv7_pmnc_enable_intens(idx);
+
+ /*
+ * Enable counter
+ */
+ armv7_pmnc_enable_counter(idx);
+
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags;
+
+ /*
+ * Disable counter and interrupt
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Disable interrupt for this counter
+ */
+ armv7_pmnc_disable_intens(idx);
+
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /*
+ * Get and reset the IRQ flags
+ */
+ pmnc = armv7_pmnc_getreset_flags();
+
+ /*
+ * Did an overflow occur?
+ */
+ if (!armv7_pmnc_has_overflowed(pmnc))
+ return IRQ_NONE;
+
+ /*
+ * Handle the counter(s) overflow(s)
+ */
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ /*
+ * We have a single interrupt for all counters. Check that
+ * each counter has overflowed before we process it.
+ */
+ if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ /*
+ * Handle the pending perf events.
+ *
+ * Note: this call *must* be run with interrupts disabled. For
+ * platforms that can have the PMU interrupts raised as an NMI, this
+ * will not work.
+ */
+ irq_work_run();
+
+ return IRQ_HANDLED;
+}
+
+static void armv7pmu_start(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ /* Enable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_stop(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ /* Disable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ int idx;
+
+ /* Always place a cycle counter into the cycle counter. */
+ if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
+ if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return ARMV7_CYCLE_COUNTER;
+ } else {
+ /*
+ * For anything other than a cycle counter, try and use
+ * the events counters
+ */
+ for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
+ if (!test_and_set_bit(idx, cpuc->used_mask))
+ return idx;
+ }
+
+ /* The counters are all in use. */
+ return -EAGAIN;
+ }
+}
+
+static struct arm_pmu armv7pmu = {
+ .handle_irq = armv7pmu_handle_irq,
+ .enable = armv7pmu_enable_event,
+ .disable = armv7pmu_disable_event,
+ .read_counter = armv7pmu_read_counter,
+ .write_counter = armv7pmu_write_counter,
+ .get_event_idx = armv7pmu_get_event_idx,
+ .start = armv7pmu_start,
+ .stop = armv7pmu_stop,
+ .raw_event_mask = 0xFF,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static u32 __init armv7_reset_read_pmnc(void)
+{
+ u32 nb_cnt;
+
+ /* Initialize & Reset PMNC: C and P bits */
+ armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+
+ /* Read the nb of CNTx counters supported from PMNC */
+ nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
+
+ /* Add the CPU cycles counter and return */
+ return nb_cnt + 1;
+}
+
+static const struct arm_pmu *__init armv7_a8_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA8;
+ armv7pmu.name = "ARMv7 Cortex-A8";
+ armv7pmu.cache_map = &armv7_a8_perf_cache_map;
+ armv7pmu.event_map = &armv7_a8_perf_map;
+ armv7pmu.num_events = armv7_reset_read_pmnc();
+ return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a9_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA9;
+ armv7pmu.name = "ARMv7 Cortex-A9";
+ armv7pmu.cache_map = &armv7_a9_perf_cache_map;
+ armv7pmu.event_map = &armv7_a9_perf_map;
+ armv7pmu.num_events = armv7_reset_read_pmnc();
+ return &armv7pmu;
+}
+#else
+static const struct arm_pmu *__init armv7_a8_pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a9_pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
new file mode 100644
index 000000000000..28cd3b025bc3
--- /dev/null
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -0,0 +1,807 @@
+/*
+ * ARMv5 [xscale] Performance counter handling code.
+ *
+ * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com>
+ *
+ * Based on the previous xscale OProfile code.
+ *
+ * There are two variants of the xscale PMU that we support:
+ * - xscale1pmu: 2 event counters and a cycle counter
+ * - xscale2pmu: 4 event counters and a cycle counter
+ * The two variants share event definitions, but have different
+ * PMU structures.
+ */
+
+#ifdef CONFIG_CPU_XSCALE
+enum xscale_perf_types {
+ XSCALE_PERFCTR_ICACHE_MISS = 0x00,
+ XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
+ XSCALE_PERFCTR_DATA_STALL = 0x02,
+ XSCALE_PERFCTR_ITLB_MISS = 0x03,
+ XSCALE_PERFCTR_DTLB_MISS = 0x04,
+ XSCALE_PERFCTR_BRANCH = 0x05,
+ XSCALE_PERFCTR_BRANCH_MISS = 0x06,
+ XSCALE_PERFCTR_INSTRUCTION = 0x07,
+ XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
+ XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
+ XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
+ XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
+ XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
+ XSCALE_PERFCTR_PC_CHANGED = 0x0D,
+ XSCALE_PERFCTR_BCU_REQUEST = 0x10,
+ XSCALE_PERFCTR_BCU_FULL = 0x11,
+ XSCALE_PERFCTR_BCU_DRAIN = 0x12,
+ XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
+ XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
+ XSCALE_PERFCTR_RMW = 0x16,
+ /* XSCALE_PERFCTR_CCNT is not hardware defined */
+ XSCALE_PERFCTR_CCNT = 0xFE,
+ XSCALE_PERFCTR_UNUSED = 0xFF,
+};
+
+enum xscale_counters {
+ XSCALE_CYCLE_COUNTER = 1,
+ XSCALE_COUNTER0,
+ XSCALE_COUNTER1,
+ XSCALE_COUNTER2,
+ XSCALE_COUNTER3,
+};
+
+static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
+ [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
+ [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+#define XSCALE_PMU_ENABLE 0x001
+#define XSCALE_PMN_RESET 0x002
+#define XSCALE_CCNT_RESET 0x004
+#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
+#define XSCALE_PMU_CNT64 0x008
+
+#define XSCALE1_OVERFLOWED_MASK 0x700
+#define XSCALE1_CCOUNT_OVERFLOW 0x400
+#define XSCALE1_COUNT0_OVERFLOW 0x100
+#define XSCALE1_COUNT1_OVERFLOW 0x200
+#define XSCALE1_CCOUNT_INT_EN 0x040
+#define XSCALE1_COUNT0_INT_EN 0x010
+#define XSCALE1_COUNT1_INT_EN 0x020
+#define XSCALE1_COUNT0_EVT_SHFT 12
+#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
+#define XSCALE1_COUNT1_EVT_SHFT 20
+#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
+
+static inline u32
+xscale1pmu_read_pmnc(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale1pmu_write_pmnc(u32 val)
+{
+ /* upper 4bits and 7, 11 are write-as-0 */
+ val &= 0xffff77f;
+ asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static inline int
+xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
+ enum xscale_counters counter)
+{
+ int ret = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
+ break;
+ case XSCALE_COUNTER0:
+ ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
+ break;
+ case XSCALE_COUNTER1:
+ ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+ }
+
+ return ret;
+}
+
+static irqreturn_t
+xscale1pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /*
+ * NOTE: there's an A stepping erratum that states if an overflow
+ * bit already exists and another occurs, the previous
+ * Overflow bit gets cleared. There's no workaround.
+ * Fixed in B stepping or later.
+ */
+ pmnc = xscale1pmu_read_pmnc();
+
+ /*
+ * Write the value back to clear the overflow flags. Overflow
+ * flags remain in pmnc for use below. We also disable the PMU
+ * while we process the interrupt.
+ */
+ xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+ if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
+ return IRQ_NONE;
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ irq_work_run();
+
+ /*
+ * Re-enable the PMU.
+ */
+ pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(pmnc);
+
+ return IRQ_HANDLED;
+}
+
+static void
+xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ mask = 0;
+ evt = XSCALE1_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ mask = XSCALE1_COUNT0_EVT_MASK;
+ evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
+ XSCALE1_COUNT0_INT_EN;
+ break;
+ case XSCALE_COUNTER1:
+ mask = XSCALE1_COUNT1_EVT_MASK;
+ evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
+ XSCALE1_COUNT1_INT_EN;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ mask = XSCALE1_CCOUNT_INT_EN;
+ evt = 0;
+ break;
+ case XSCALE_COUNTER0:
+ mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
+ evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
+ evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ if (XSCALE_PERFCTR_CCNT == event->config_base) {
+ if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return XSCALE_CYCLE_COUNTER;
+ } else {
+ if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
+ return XSCALE_COUNTER1;
+
+ if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
+ return XSCALE_COUNTER0;
+
+ return -EAGAIN;
+ }
+}
+
+static void
+xscale1pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val |= XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale1pmu_read_counter(int counter)
+{
+ u32 val = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
+ break;
+ }
+
+ return val;
+}
+
+static inline void
+xscale1pmu_write_counter(int counter, u32 val)
+{
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
+ break;
+ }
+}
+
+static const struct arm_pmu xscale1pmu = {
+ .id = ARM_PERF_PMU_ID_XSCALE1,
+ .name = "xscale1",
+ .handle_irq = xscale1pmu_handle_irq,
+ .enable = xscale1pmu_enable_event,
+ .disable = xscale1pmu_disable_event,
+ .read_counter = xscale1pmu_read_counter,
+ .write_counter = xscale1pmu_write_counter,
+ .get_event_idx = xscale1pmu_get_event_idx,
+ .start = xscale1pmu_start,
+ .stop = xscale1pmu_stop,
+ .cache_map = &xscale_perf_cache_map,
+ .event_map = &xscale_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init xscale1pmu_init(void)
+{
+ return &xscale1pmu;
+}
+
+#define XSCALE2_OVERFLOWED_MASK 0x01f
+#define XSCALE2_CCOUNT_OVERFLOW 0x001
+#define XSCALE2_COUNT0_OVERFLOW 0x002
+#define XSCALE2_COUNT1_OVERFLOW 0x004
+#define XSCALE2_COUNT2_OVERFLOW 0x008
+#define XSCALE2_COUNT3_OVERFLOW 0x010
+#define XSCALE2_CCOUNT_INT_EN 0x001
+#define XSCALE2_COUNT0_INT_EN 0x002
+#define XSCALE2_COUNT1_INT_EN 0x004
+#define XSCALE2_COUNT2_INT_EN 0x008
+#define XSCALE2_COUNT3_INT_EN 0x010
+#define XSCALE2_COUNT0_EVT_SHFT 0
+#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
+#define XSCALE2_COUNT1_EVT_SHFT 8
+#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
+#define XSCALE2_COUNT2_EVT_SHFT 16
+#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
+#define XSCALE2_COUNT3_EVT_SHFT 24
+#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
+
+static inline u32
+xscale2pmu_read_pmnc(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
+ /* bits 1-2 and 4-23 are read-unpredictable */
+ return val & 0xff000009;
+}
+
+static inline void
+xscale2pmu_write_pmnc(u32 val)
+{
+ /* bits 4-23 are write-as-0, 24-31 are write ignored */
+ val &= 0xf;
+ asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_overflow_flags(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale2pmu_write_overflow_flags(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_event_select(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale2pmu_write_event_select(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
+}
+
+static inline u32
+xscale2pmu_read_int_enable(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
+ return val;
+}
+
+static void
+xscale2pmu_write_int_enable(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
+}
+
+static inline int
+xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
+ enum xscale_counters counter)
+{
+ int ret = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
+ break;
+ case XSCALE_COUNTER0:
+ ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
+ break;
+ case XSCALE_COUNTER1:
+ ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
+ break;
+ case XSCALE_COUNTER2:
+ ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
+ break;
+ case XSCALE_COUNTER3:
+ ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+ }
+
+ return ret;
+}
+
+static irqreturn_t
+xscale2pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc, of_flags;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /* Disable the PMU. */
+ pmnc = xscale2pmu_read_pmnc();
+ xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+ /* Check the overflow flag register. */
+ of_flags = xscale2pmu_read_overflow_flags();
+ if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
+ return IRQ_NONE;
+
+ /* Clear the overflow bits. */
+ xscale2pmu_write_overflow_flags(of_flags);
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ irq_work_run();
+
+ /*
+ * Re-enable the PMU.
+ */
+ pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(pmnc);
+
+ return IRQ_HANDLED;
+}
+
+static void
+xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags, ien, evtsel;
+
+ ien = xscale2pmu_read_int_enable();
+ evtsel = xscale2pmu_read_event_select();
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ ien |= XSCALE2_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ ien |= XSCALE2_COUNT0_INT_EN;
+ evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ ien |= XSCALE2_COUNT1_INT_EN;
+ evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER2:
+ ien |= XSCALE2_COUNT2_INT_EN;
+ evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER3:
+ ien |= XSCALE2_COUNT3_INT_EN;
+ evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags, ien, evtsel;
+
+ ien = xscale2pmu_read_int_enable();
+ evtsel = xscale2pmu_read_event_select();
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ ien &= ~XSCALE2_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ ien &= ~XSCALE2_COUNT0_INT_EN;
+ evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ ien &= ~XSCALE2_COUNT1_INT_EN;
+ evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER2:
+ ien &= ~XSCALE2_COUNT2_INT_EN;
+ evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER3:
+ ien &= ~XSCALE2_COUNT3_INT_EN;
+ evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ int idx = xscale1pmu_get_event_idx(cpuc, event);
+ if (idx >= 0)
+ goto out;
+
+ if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
+ idx = XSCALE_COUNTER3;
+ else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
+ idx = XSCALE_COUNTER2;
+out:
+ return idx;
+}
+
+static void
+xscale2pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
+ val |= XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale2pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale2pmu_read_counter(int counter)
+{
+ u32 val = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER2:
+ asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER3:
+ asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
+ break;
+ }
+
+ return val;
+}
+
+static inline void
+xscale2pmu_write_counter(int counter, u32 val)
+{
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER2:
+ asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER3:
+ asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
+ break;
+ }
+}
+
+static const struct arm_pmu xscale2pmu = {
+ .id = ARM_PERF_PMU_ID_XSCALE2,
+ .name = "xscale2",
+ .handle_irq = xscale2pmu_handle_irq,
+ .enable = xscale2pmu_enable_event,
+ .disable = xscale2pmu_disable_event,
+ .read_counter = xscale2pmu_read_counter,
+ .write_counter = xscale2pmu_write_counter,
+ .get_event_idx = xscale2pmu_get_event_idx,
+ .start = xscale2pmu_start,
+ .stop = xscale2pmu_stop,
+ .cache_map = &xscale_perf_cache_map,
+ .event_map = &xscale_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 5,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init xscale2pmu_init(void)
+{
+ return &xscale2pmu;
+}
+#else
+static const struct arm_pmu *__init xscale1pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init xscale2pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
new file mode 100644
index 000000000000..a4b1b0748fd3
--- /dev/null
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/kernel/pj4-cp0.c
+ *
+ * PJ4 iWMMXt coprocessor context switching and handling
+ *
+ * Copyright (c) 2010 Marvell International 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 <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/thread_notify.h>
+
+static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = t;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ /*
+ * flush_thread() zeroes thread->fpstate, so no need
+ * to do anything here.
+ *
+ * FALLTHROUGH: Ensure we don't try to overwrite our newly
+ * initialised state information on the first fault.
+ */
+
+ case THREAD_NOTIFY_EXIT:
+ iwmmxt_task_release(thread);
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ iwmmxt_task_switch(thread);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block iwmmxt_notifier_block = {
+ .notifier_call = iwmmxt_do,
+};
+
+
+static u32 __init pj4_cp_access_read(void)
+{
+ u32 value;
+
+ __asm__ __volatile__ (
+ "mrc p15, 0, %0, c1, c0, 2\n\t"
+ : "=r" (value));
+ return value;
+}
+
+static void __init pj4_cp_access_write(u32 value)
+{
+ u32 temp;
+
+ __asm__ __volatile__ (
+ "mcr p15, 0, %1, c1, c0, 2\n\t"
+ "mrc p15, 0, %0, c1, c0, 2\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4\n\t"
+ : "=r" (temp) : "r" (value));
+}
+
+
+/*
+ * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
+ * switch code handle iWMMXt context switching.
+ */
+static int __init pj4_cp0_init(void)
+{
+ u32 cp_access;
+
+ cp_access = pj4_cp_access_read() & ~0xf;
+ pj4_cp_access_write(cp_access);
+
+ printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
+ elf_hwcap |= HWCAP_IWMMXT;
+ thread_register_notifier(&iwmmxt_notifier_block);
+
+ return 0;
+}
+
+late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 3e97483abcf0..19c6816db61e 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -1060,8 +1060,8 @@ static int ptrace_sethbpregs(struct task_struct *tsk, long num,
goto out;
if ((gen_type & implied_type) != gen_type) {
- ret = -EINVAL;
- goto out;
+ ret = -EINVAL;
+ goto out;
}
attr.bp_len = gen_len;
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index fd26f8d65151..9cf4cbf8f95b 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -59,6 +59,8 @@ relocate_new_kernel:
ldr r2,kexec_boot_atags
mov pc,lr
+ .align
+
.globl kexec_start_address
kexec_start_address:
.long 0x0
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
new file mode 100644
index 000000000000..2cdcc9287c74
--- /dev/null
+++ b/arch/arm/kernel/sched_clock.c
@@ -0,0 +1,69 @@
+/*
+ * sched_clock.c: support for extending counters to full 64-bit ns counter
+ *
+ * This program is free software; you can 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/clocksource.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+
+#include <asm/sched_clock.h>
+
+static void sched_clock_poll(unsigned long wrap_ticks);
+static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
+static void (*sched_clock_update_fn)(void);
+
+static void sched_clock_poll(unsigned long wrap_ticks)
+{
+ mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
+ sched_clock_update_fn();
+}
+
+void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
+ unsigned int clock_bits, unsigned long rate)
+{
+ unsigned long r, w;
+ u64 res, wrap;
+ char r_unit;
+
+ sched_clock_update_fn = update;
+
+ /* calculate the mult/shift to convert counter ticks to ns. */
+ clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 60);
+
+ r = rate;
+ if (r >= 4000000) {
+ r /= 1000000;
+ r_unit = 'M';
+ } else {
+ r /= 1000;
+ r_unit = 'k';
+ }
+
+ /* calculate how many ns until we wrap */
+ wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
+ do_div(wrap, NSEC_PER_MSEC);
+ w = wrap;
+
+ /* calculate the ns resolution of this counter */
+ res = cyc_to_ns(1ULL, cd->mult, cd->shift);
+ pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
+ clock_bits, r, r_unit, res, w);
+
+ /*
+ * Start the timer to keep sched_clock() properly updated and
+ * sets the initial epoch.
+ */
+ sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
+ sched_clock_poll(sched_clock_timer.data);
+
+ /*
+ * Ensure that sched_clock() starts off at 0ns
+ */
+ cd->epoch_ns = 0;
+}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 336f14e0e5c2..3455ad33de4c 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -75,9 +75,9 @@ extern void reboot_setup(char *str);
unsigned int processor_id;
EXPORT_SYMBOL(processor_id);
-unsigned int __machine_arch_type;
+unsigned int __machine_arch_type __read_mostly;
EXPORT_SYMBOL(__machine_arch_type);
-unsigned int cacheid;
+unsigned int cacheid __read_mostly;
EXPORT_SYMBOL(cacheid);
unsigned int __atags_pointer __initdata;
@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low);
unsigned int system_serial_high;
EXPORT_SYMBOL(system_serial_high);
-unsigned int elf_hwcap;
+unsigned int elf_hwcap __read_mostly;
EXPORT_SYMBOL(elf_hwcap);
#ifdef MULTI_CPU
-struct processor processor;
+struct processor processor __read_mostly;
#endif
#ifdef MULTI_TLB
-struct cpu_tlb_fns cpu_tlb;
+struct cpu_tlb_fns cpu_tlb __read_mostly;
#endif
#ifdef MULTI_USER
-struct cpu_user_fns cpu_user;
+struct cpu_user_fns cpu_user __read_mostly;
#endif
#ifdef MULTI_CACHE
-struct cpu_cache_fns cpu_cache;
+struct cpu_cache_fns cpu_cache __read_mostly;
#endif
#ifdef CONFIG_OUTER_CACHE
-struct outer_cache_fns outer_cache;
+struct outer_cache_fns outer_cache __read_mostly;
EXPORT_SYMBOL(outer_cache);
#endif
@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform);
static const char *cpu_name;
static const char *machine_name;
static char __initdata cmd_line[COMMAND_LINE_SIZE];
+struct machine_desc *machine_desc __initdata;
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -708,13 +709,11 @@ static struct init_tags {
{ 0, ATAG_NONE }
};
-static void (*init_machine)(void) __initdata;
-
static int __init customize_machine(void)
{
/* customizes platform devices, or adds new ones */
- if (init_machine)
- init_machine();
+ if (machine_desc->init_machine)
+ machine_desc->init_machine();
return 0;
}
arch_initcall(customize_machine);
@@ -809,6 +808,7 @@ void __init setup_arch(char **cmdline_p)
setup_processor();
mdesc = setup_machine(machine_arch_type);
+ machine_desc = mdesc;
machine_name = mdesc->name;
if (mdesc->soft_reboot)
@@ -868,13 +868,9 @@ void __init setup_arch(char **cmdline_p)
cpu_init();
tcm_init();
- /*
- * Set up various architecture-specific pointers
- */
- arch_nr_irqs = mdesc->nr_irqs;
- init_arch_irq = mdesc->init_irq;
- system_timer = mdesc->timer;
- init_machine = mdesc->init_machine;
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ handle_arch_irq = mdesc->handle_irq;
+#endif
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
@@ -884,6 +880,9 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
early_trap_init();
+
+ if (mdesc->init_early)
+ mdesc->init_early();
}
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8c1959590252..4539ebcb089f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -16,6 +16,7 @@
#include <linux/cache.h>
#include <linux/profile.h>
#include <linux/errno.h>
+#include <linux/ftrace.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/cpu.h>
@@ -24,6 +25,7 @@
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/clockchips.h>
+#include <linux/completion.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -37,7 +39,6 @@
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
-#include <asm/smp_plat.h>
/*
* as from 2.5, kernels no longer have an init_tasks structure
@@ -46,64 +47,14 @@
*/
struct secondary_data secondary_data;
-/*
- * structures for inter-processor calls
- * - A collection of single bit ipi messages.
- */
-struct ipi_data {
- spinlock_t lock;
- unsigned long ipi_count;
- unsigned long bits;
-};
-
-static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
- .lock = SPIN_LOCK_UNLOCKED,
-};
-
enum ipi_msg_type {
- IPI_TIMER,
+ IPI_TIMER = 2,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
IPI_CPU_STOP,
};
-static inline void identity_mapping_add(pgd_t *pgd, unsigned long start,
- unsigned long end)
-{
- unsigned long addr, prot;
- pmd_t *pmd;
-
- prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
- if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
- prot |= PMD_BIT4;
-
- for (addr = start & PGDIR_MASK; addr < end;) {
- pmd = pmd_offset(pgd + pgd_index(addr), addr);
- pmd[0] = __pmd(addr | prot);
- addr += SECTION_SIZE;
- pmd[1] = __pmd(addr | prot);
- addr += SECTION_SIZE;
- flush_pmd_entry(pmd);
- outer_clean_range(__pa(pmd), __pa(pmd + 1));
- }
-}
-
-static inline void identity_mapping_del(pgd_t *pgd, unsigned long start,
- unsigned long end)
-{
- unsigned long addr;
- pmd_t *pmd;
-
- for (addr = start & PGDIR_MASK; addr < end; addr += PGDIR_SIZE) {
- pmd = pmd_offset(pgd + pgd_index(addr), addr);
- pmd[0] = __pmd(0);
- pmd[1] = __pmd(0);
- clean_pmd_entry(pmd);
- outer_clean_range(__pa(pmd), __pa(pmd + 1));
- }
-}
-
int __cpuinit __cpu_up(unsigned int cpu)
{
struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
@@ -177,8 +128,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
barrier();
}
- if (!cpu_online(cpu))
+ if (!cpu_online(cpu)) {
+ pr_crit("CPU%u: failed to come online\n", cpu);
ret = -EIO;
+ }
+ } else {
+ pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
}
secondary_data.stack = NULL;
@@ -194,18 +149,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
pgd_free(&init_mm, pgd);
- if (ret) {
- printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
-
- /*
- * FIXME: We need to clean up the new idle thread. --rmk
- */
- }
-
return ret;
}
#ifdef CONFIG_HOTPLUG_CPU
+static void percpu_timer_stop(void);
+
/*
* __cpu_disable runs on the processor to be shutdown.
*/
@@ -233,7 +182,7 @@ int __cpu_disable(void)
/*
* Stop the local timer for this CPU.
*/
- local_timer_stop();
+ percpu_timer_stop();
/*
* Flush user cache and TLB mappings, and then remove this CPU
@@ -252,12 +201,20 @@ int __cpu_disable(void)
return 0;
}
+static DECLARE_COMPLETION(cpu_died);
+
/*
* called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out.
*/
void __cpu_die(unsigned int cpu)
{
+ if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
+ pr_err("CPU%u: cpu didn't die\n", cpu);
+ return;
+ }
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+
if (!platform_cpu_kill(cpu))
printk("CPU%u: unable to kill\n", cpu);
}
@@ -274,12 +231,17 @@ void __ref cpu_die(void)
{
unsigned int cpu = smp_processor_id();
- local_irq_disable();
idle_task_exit();
+ local_irq_disable();
+ mb();
+
+ /* Tell __cpu_die() that this CPU is now safe to dispose of */
+ complete(&cpu_died);
+
/*
* actual CPU shutdown procedure is at least platform (if not
- * CPU) specific
+ * CPU) specific.
*/
platform_cpu_die(cpu);
@@ -289,6 +251,7 @@ void __ref cpu_die(void)
* to be repeated to undo the effects of taking the CPU offline.
*/
__asm__("mov sp, %0\n"
+ " mov fp, #0\n"
" b secondary_start_kernel"
:
: "r" (task_stack_page(current) + THREAD_SIZE - 8));
@@ -296,6 +259,17 @@ void __ref cpu_die(void)
#endif /* CONFIG_HOTPLUG_CPU */
/*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+ */
+static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+{
+ struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
+
+ cpu_info->loops_per_jiffy = loops_per_jiffy;
+}
+
+/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
@@ -310,7 +284,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
- atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
cpumask_set_cpu(cpu, mm_cpumask(mm));
@@ -320,6 +293,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
cpu_init();
preempt_disable();
+ trace_hardirqs_off();
/*
* Give the platform a chance to do its own initialisation.
@@ -353,17 +327,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
cpu_idle();
}
-/*
- * Called by both boot and secondaries to move global data into
- * per-processor storage.
- */
-void __cpuinit smp_store_cpu_info(unsigned int cpuid)
-{
- struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
-
- cpu_info->loops_per_jiffy = loops_per_jiffy;
-}
-
void __init smp_cpus_done(unsigned int max_cpus)
{
int cpu;
@@ -386,61 +349,80 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current;
}
-static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg)
+void __init smp_prepare_cpus(unsigned int max_cpus)
{
- unsigned long flags;
- unsigned int cpu;
+ unsigned int ncores = num_possible_cpus();
- local_irq_save(flags);
-
- for_each_cpu(cpu, mask) {
- struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
-
- spin_lock(&ipi->lock);
- ipi->bits |= 1 << msg;
- spin_unlock(&ipi->lock);
- }
+ smp_store_cpu_info(smp_processor_id());
/*
- * Call the platform specific cross-CPU call function.
+ * are we trying to boot more cores than exist?
*/
- smp_cross_call(mask);
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+
+ if (max_cpus > 1) {
+ /*
+ * Enable the local timer or broadcast device for the
+ * boot CPU, but only if we have more than one CPU.
+ */
+ percpu_timer_setup();
- local_irq_restore(flags);
+ /*
+ * Initialise the SCU if there are more than one CPU
+ * and let them know where to start.
+ */
+ platform_smp_prepare_cpus(max_cpus);
+ }
}
void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
- send_ipi_message(mask, IPI_CALL_FUNC);
+ smp_cross_call(mask, IPI_CALL_FUNC);
}
void arch_send_call_function_single_ipi(int cpu)
{
- send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
}
-void show_ipi_list(struct seq_file *p)
+static const char *ipi_types[NR_IPI] = {
+#define S(x,s) [x - IPI_TIMER] = s
+ S(IPI_TIMER, "Timer broadcast interrupts"),
+ S(IPI_RESCHEDULE, "Rescheduling interrupts"),
+ S(IPI_CALL_FUNC, "Function call interrupts"),
+ S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
+ S(IPI_CPU_STOP, "CPU stop interrupts"),
+};
+
+void show_ipi_list(struct seq_file *p, int prec)
{
- unsigned int cpu;
+ unsigned int cpu, i;
- seq_puts(p, "IPI:");
+ for (i = 0; i < NR_IPI; i++) {
+ seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
- for_each_present_cpu(cpu)
- seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ",
+ __get_irq_stat(cpu, ipi_irqs[i]));
- seq_putc(p, '\n');
+ seq_printf(p, " %s\n", ipi_types[i]);
+ }
}
-void show_local_irqs(struct seq_file *p)
+u64 smp_irq_stat_cpu(unsigned int cpu)
{
- unsigned int cpu;
+ u64 sum = 0;
+ int i;
- seq_printf(p, "LOC: ");
+ for (i = 0; i < NR_IPI; i++)
+ sum += __get_irq_stat(cpu, ipi_irqs[i]);
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
+#ifdef CONFIG_LOCAL_TIMERS
+ sum += __get_irq_stat(cpu, local_timer_irqs);
+#endif
- seq_putc(p, '\n');
+ return sum;
}
/*
@@ -457,24 +439,36 @@ static void ipi_timer(void)
}
#ifdef CONFIG_LOCAL_TIMERS
-asmlinkage void __exception do_local_timer(struct pt_regs *regs)
+asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
int cpu = smp_processor_id();
if (local_timer_ack()) {
- irq_stat[cpu].local_timer_irqs++;
+ __inc_irq_stat(cpu, local_timer_irqs);
ipi_timer();
}
set_irq_regs(old_regs);
}
+
+void show_local_irqs(struct seq_file *p, int prec)
+{
+ unsigned int cpu;
+
+ seq_printf(p, "%*s: ", prec, "LOC");
+
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
+
+ seq_printf(p, " Local timer interrupts\n");
+}
#endif
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
static void smp_timer_broadcast(const struct cpumask *mask)
{
- send_ipi_message(mask, IPI_TIMER);
+ smp_cross_call(mask, IPI_TIMER);
}
#else
#define smp_timer_broadcast NULL
@@ -511,6 +505,21 @@ void __cpuinit percpu_timer_setup(void)
local_timer_setup(evt);
}
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The generic clock events code purposely does not stop the local timer
+ * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
+ * manually here.
+ */
+static void percpu_timer_stop(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+}
+#endif
+
static DEFINE_SPINLOCK(stop_lock);
/*
@@ -537,216 +546,76 @@ static void ipi_cpu_stop(unsigned int cpu)
/*
* Main handler for inter-processor interrupts
- *
- * For ARM, the ipimask now only identifies a single
- * category of IPI (Bit 1 IPIs have been replaced by a
- * different mechanism):
- *
- * Bit 0 - Inter-processor function call
*/
-asmlinkage void __exception do_IPI(struct pt_regs *regs)
+asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
{
unsigned int cpu = smp_processor_id();
- struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
struct pt_regs *old_regs = set_irq_regs(regs);
- ipi->ipi_count++;
-
- for (;;) {
- unsigned long msgs;
-
- spin_lock(&ipi->lock);
- msgs = ipi->bits;
- ipi->bits = 0;
- spin_unlock(&ipi->lock);
+ if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
+ __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
- if (!msgs)
- break;
-
- do {
- unsigned nextmsg;
-
- nextmsg = msgs & -msgs;
- msgs &= ~nextmsg;
- nextmsg = ffz(~nextmsg);
-
- switch (nextmsg) {
- case IPI_TIMER:
- ipi_timer();
- break;
+ switch (ipinr) {
+ case IPI_TIMER:
+ ipi_timer();
+ break;
- case IPI_RESCHEDULE:
- /*
- * nothing more to do - eveything is
- * done on the interrupt return path
- */
- break;
+ case IPI_RESCHEDULE:
+ /*
+ * nothing more to do - eveything is
+ * done on the interrupt return path
+ */
+ break;
- case IPI_CALL_FUNC:
- generic_smp_call_function_interrupt();
- break;
+ case IPI_CALL_FUNC:
+ generic_smp_call_function_interrupt();
+ break;
- case IPI_CALL_FUNC_SINGLE:
- generic_smp_call_function_single_interrupt();
- break;
+ case IPI_CALL_FUNC_SINGLE:
+ generic_smp_call_function_single_interrupt();
+ break;
- case IPI_CPU_STOP:
- ipi_cpu_stop(cpu);
- break;
+ case IPI_CPU_STOP:
+ ipi_cpu_stop(cpu);
+ break;
- default:
- printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
- cpu, nextmsg);
- break;
- }
- } while (msgs);
+ default:
+ printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
+ cpu, ipinr);
+ break;
}
-
set_irq_regs(old_regs);
}
void smp_send_reschedule(int cpu)
{
- send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
+ smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}
void smp_send_stop(void)
{
- cpumask_t mask = cpu_online_map;
- cpu_clear(smp_processor_id(), mask);
- if (!cpus_empty(mask))
- send_ipi_message(&mask, IPI_CPU_STOP);
-}
+ unsigned long timeout;
-/*
- * not supported here
- */
-int setup_profiling_timer(unsigned int multiplier)
-{
- return -EINVAL;
-}
+ if (num_online_cpus() > 1) {
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), mask);
-static void
-on_each_cpu_mask(void (*func)(void *), void *info, int wait,
- const struct cpumask *mask)
-{
- preempt_disable();
+ smp_cross_call(&mask, IPI_CPU_STOP);
+ }
- smp_call_function_many(mask, func, info, wait);
- if (cpumask_test_cpu(smp_processor_id(), mask))
- func(info);
+ /* Wait up to one second for other CPUs to stop */
+ timeout = USEC_PER_SEC;
+ while (num_online_cpus() > 1 && timeout--)
+ udelay(1);
- preempt_enable();
+ if (num_online_cpus() > 1)
+ pr_warning("SMP: failed to stop secondary CPUs\n");
}
-/**********************************************************************/
-
/*
- * TLB operations
+ * not supported here
*/
-struct tlb_args {
- struct vm_area_struct *ta_vma;
- unsigned long ta_start;
- unsigned long ta_end;
-};
-
-static inline void ipi_flush_tlb_all(void *ignored)
-{
- local_flush_tlb_all();
-}
-
-static inline void ipi_flush_tlb_mm(void *arg)
-{
- struct mm_struct *mm = (struct mm_struct *)arg;
-
- local_flush_tlb_mm(mm);
-}
-
-static inline void ipi_flush_tlb_page(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_page(ta->ta_vma, ta->ta_start);
-}
-
-static inline void ipi_flush_tlb_kernel_page(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_kernel_page(ta->ta_start);
-}
-
-static inline void ipi_flush_tlb_range(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
-}
-
-static inline void ipi_flush_tlb_kernel_range(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
-}
-
-void flush_tlb_all(void)
-{
- if (tlb_ops_need_broadcast())
- on_each_cpu(ipi_flush_tlb_all, NULL, 1);
- else
- local_flush_tlb_all();
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
- if (tlb_ops_need_broadcast())
- on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
- else
- local_flush_tlb_mm(mm);
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
-{
- if (tlb_ops_need_broadcast()) {
- struct tlb_args ta;
- ta.ta_vma = vma;
- ta.ta_start = uaddr;
- on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
- } else
- local_flush_tlb_page(vma, uaddr);
-}
-
-void flush_tlb_kernel_page(unsigned long kaddr)
-{
- if (tlb_ops_need_broadcast()) {
- struct tlb_args ta;
- ta.ta_start = kaddr;
- on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
- } else
- local_flush_tlb_kernel_page(kaddr);
-}
-
-void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- if (tlb_ops_need_broadcast()) {
- struct tlb_args ta;
- ta.ta_vma = vma;
- ta.ta_start = start;
- ta.ta_end = end;
- on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
- } else
- local_flush_tlb_range(vma, start, end);
-}
-
-void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+int setup_profiling_timer(unsigned int multiplier)
{
- if (tlb_ops_need_broadcast()) {
- struct tlb_args ta;
- ta.ta_start = start;
- ta.ta_end = end;
- on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
- } else
- local_flush_tlb_kernel_range(start, end);
+ return -EINVAL;
}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
new file mode 100644
index 000000000000..7dcb35285be7
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/kernel/smp_tlb.c
+ *
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/preempt.h>
+#include <linux/smp.h>
+
+#include <asm/smp_plat.h>
+#include <asm/tlbflush.h>
+
+static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
+ const struct cpumask *mask)
+{
+ preempt_disable();
+
+ smp_call_function_many(mask, func, info, wait);
+ if (cpumask_test_cpu(smp_processor_id(), mask))
+ func(info);
+
+ preempt_enable();
+}
+
+/**********************************************************************/
+
+/*
+ * TLB operations
+ */
+struct tlb_args {
+ struct vm_area_struct *ta_vma;
+ unsigned long ta_start;
+ unsigned long ta_end;
+};
+
+static inline void ipi_flush_tlb_all(void *ignored)
+{
+ local_flush_tlb_all();
+}
+
+static inline void ipi_flush_tlb_mm(void *arg)
+{
+ struct mm_struct *mm = (struct mm_struct *)arg;
+
+ local_flush_tlb_mm(mm);
+}
+
+static inline void ipi_flush_tlb_page(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_page(ta->ta_vma, ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_kernel_page(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_kernel_page(ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_range(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+
+static inline void ipi_flush_tlb_kernel_range(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
+}
+
+void flush_tlb_all(void)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+ else
+ local_flush_tlb_all();
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
+ else
+ local_flush_tlb_mm(mm);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_vma = vma;
+ ta.ta_start = uaddr;
+ on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
+ } else
+ local_flush_tlb_page(vma, uaddr);
+}
+
+void flush_tlb_kernel_page(unsigned long kaddr)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_start = kaddr;
+ on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
+ } else
+ local_flush_tlb_kernel_page(kaddr);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_vma = vma;
+ ta.ta_start = start;
+ ta.ta_end = end;
+ on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
+ } else
+ local_flush_tlb_range(vma, start, end);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_start = start;
+ ta.ta_end = end;
+ on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
+ } else
+ local_flush_tlb_kernel_range(start, end);
+}
+
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 35882fbf37f9..dd790745b3ef 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -127,8 +127,6 @@ static void __cpuinit twd_calibrate_rate(void)
*/
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
- unsigned long flags;
-
twd_calibrate_rate();
clk->name = "local_timer";
@@ -143,20 +141,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
/* Make sure our local interrupt controller has this enabled */
- local_irq_save(flags);
- irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
- get_irq_chip(clk->irq)->unmask(clk->irq);
- local_irq_restore(flags);
+ gic_enable_ppi(clk->irq);
clockevents_register_device(clk);
}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * take a local timer down
- */
-void twd_timer_stop(void)
-{
- __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
-}
-#endif
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 000000000000..7a5760922914
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,267 @@
+/*
+ * linux/arch/arm/kernel/swp_emulate.c
+ *
+ * Copyright (C) 2009 ARM Limited
+ * __user_* functions adapted from include/asm/uaccess.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.
+ *
+ * Implements emulation of the SWP/SWPB instructions using load-exclusive and
+ * store-exclusive for processors that have them disabled (or future ones that
+ * might not implement them).
+ *
+ * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
+ * Where: Rt = destination
+ * Rt2 = source
+ * Rn = address
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/perf_event.h>
+
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+/*
+ * Error-checking SWP macros implemented using ldrex{b}/strex{b}
+ */
+#define __user_swpX_asm(data, addr, res, temp, B) \
+ __asm__ __volatile__( \
+ " mov %2, %1\n" \
+ "0: ldrex"B" %1, [%3]\n" \
+ "1: strex"B" %0, %2, [%3]\n" \
+ " cmp %0, #0\n" \
+ " movne %0, %4\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %5\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 0b, 3b\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "=&r" (res), "+r" (data), "=&r" (temp) \
+ : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
+ : "cc", "memory")
+
+#define __user_swp_asm(data, addr, res, temp) \
+ __user_swpX_asm(data, addr, res, temp, "")
+#define __user_swpb_asm(data, addr, res, temp) \
+ __user_swpX_asm(data, addr, res, temp, "b")
+
+/*
+ * Macros/defines for extracting register numbers from instruction.
+ */
+#define EXTRACT_REG_NUM(instruction, offset) \
+ (((instruction) & (0xf << (offset))) >> (offset))
+#define RN_OFFSET 16
+#define RT_OFFSET 12
+#define RT2_OFFSET 0
+/*
+ * Bit 22 of the instruction encoding distinguishes between
+ * the SWP and SWPB variants (bit set means SWPB).
+ */
+#define TYPE_SWPB (1 << 22)
+
+static unsigned long swpcounter;
+static unsigned long swpbcounter;
+static unsigned long abtcounter;
+static pid_t previous_pid;
+
+#ifdef CONFIG_PROC_FS
+static int proc_read_status(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *p = page;
+ int len;
+
+ p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
+ p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
+ p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
+ if (previous_pid != 0)
+ p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
+
+ len = (p - page) - off;
+ if (len < 0)
+ len = 0;
+
+ *eof = (len <= count) ? 1 : 0;
+ *start = page + off;
+
+ return len;
+}
+#endif
+
+/*
+ * Set up process info to signal segmentation fault - called on access error.
+ */
+static void set_segfault(struct pt_regs *regs, unsigned long addr)
+{
+ siginfo_t info;
+
+ if (find_vma(current->mm, addr) == NULL)
+ info.si_code = SEGV_MAPERR;
+ else
+ info.si_code = SEGV_ACCERR;
+
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_addr = (void *) instruction_pointer(regs);
+
+ pr_debug("SWP{B} emulation: access caused memory abort!\n");
+ arm_notify_die("Illegal memory access", regs, &info, 0, 0);
+
+ abtcounter++;
+}
+
+static int emulate_swpX(unsigned int address, unsigned int *data,
+ unsigned int type)
+{
+ unsigned int res = 0;
+
+ if ((type != TYPE_SWPB) && (address & 0x3)) {
+ /* SWP to unaligned address not permitted */
+ pr_debug("SWP instruction on unaligned pointer!\n");
+ return -EFAULT;
+ }
+
+ while (1) {
+ unsigned long temp;
+
+ /*
+ * Barrier required between accessing protected resource and
+ * releasing a lock for it. Legacy code might not have done
+ * this, and we cannot determine that this is not the case
+ * being emulated, so insert always.
+ */
+ smp_mb();
+
+ if (type == TYPE_SWPB)
+ __user_swpb_asm(*data, address, res, temp);
+ else
+ __user_swp_asm(*data, address, res, temp);
+
+ if (likely(res != -EAGAIN) || signal_pending(current))
+ break;
+
+ cond_resched();
+ }
+
+ if (res == 0) {
+ /*
+ * Barrier also required between aquiring a lock for a
+ * protected resource and accessing the resource. Inserted for
+ * same reason as above.
+ */
+ smp_mb();
+
+ if (type == TYPE_SWPB)
+ swpbcounter++;
+ else
+ swpcounter++;
+ }
+
+ return res;
+}
+
+/*
+ * swp_handler logs the id of calling process, dissects the instruction, sanity
+ * checks the memory location, calls emulate_swpX for the actual operation and
+ * deals with fixup/error handling before returning
+ */
+static int swp_handler(struct pt_regs *regs, unsigned int instr)
+{
+ unsigned int address, destreg, data, type;
+ unsigned int res = 0;
+
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
+
+ if (current->pid != previous_pid) {
+ pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
+ current->comm, (unsigned long)current->pid);
+ previous_pid = current->pid;
+ }
+
+ address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
+ data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
+ destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
+
+ type = instr & TYPE_SWPB;
+
+ pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
+ EXTRACT_REG_NUM(instr, RN_OFFSET), address,
+ destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
+
+ /* Check access in reasonable access range for both SWP and SWPB */
+ if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
+ pr_debug("SWP{B} emulation: access to %p not allowed!\n",
+ (void *)address);
+ res = -EFAULT;
+ } else {
+ res = emulate_swpX(address, &data, type);
+ }
+
+ if (res == 0) {
+ /*
+ * On successful emulation, revert the adjustment to the PC
+ * made in kernel/traps.c in order to resume execution at the
+ * instruction following the SWP{B}.
+ */
+ regs->ARM_pc += 4;
+ regs->uregs[destreg] = data;
+ } else if (res == -EFAULT) {
+ /*
+ * Memory errors do not mean emulation failed.
+ * Set up signal info to return SEGV, then return OK
+ */
+ set_segfault(regs, address);
+ }
+
+ return 0;
+}
+
+/*
+ * Only emulate SWP/SWPB executed in ARM state/User mode.
+ * The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
+ */
+static struct undef_hook swp_hook = {
+ .instr_mask = 0x0fb00ff0,
+ .instr_val = 0x01000090,
+ .cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
+ .cpsr_val = USR_MODE,
+ .fn = swp_handler
+};
+
+/*
+ * Register handler and create status file in /proc/cpu
+ * Invoked as late_initcall, since not needed before init spawned.
+ */
+static int __init swp_emulation_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *res;
+
+ res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
+
+ if (!res)
+ return -ENOMEM;
+
+ res->read_proc = proc_read_status;
+#endif /* CONFIG_PROC_FS */
+
+ printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
+ register_undef_hook(&swp_hook);
+
+ return 0;
+}
+
+late_initcall(swp_emulation_init);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 38c261f9951c..f1e2eb19a67d 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -30,12 +30,13 @@
#include <asm/leds.h>
#include <asm/thread_info.h>
#include <asm/stacktrace.h>
+#include <asm/mach/arch.h>
#include <asm/mach/time.h>
/*
* Our system timer.
*/
-struct sys_timer *system_timer;
+static struct sys_timer *system_timer;
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
/* this needs a better home */
@@ -160,6 +161,7 @@ device_initcall(timer_init_sysfs);
void __init time_init(void)
{
+ system_timer = machine_desc->timer;
system_timer->init();
}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 446aee97436f..ee57640ba2bb 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -37,6 +37,8 @@
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
+void *vectors_page;
+
#ifdef CONFIG_DEBUG_USER
unsigned int user_debug;
@@ -708,19 +710,19 @@ void __readwrite_bug(const char *fn)
}
EXPORT_SYMBOL(__readwrite_bug);
-void __pte_error(const char *file, int line, unsigned long val)
+void __pte_error(const char *file, int line, pte_t pte)
{
- printk("%s:%d: bad pte %08lx.\n", file, line, val);
+ printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte));
}
-void __pmd_error(const char *file, int line, unsigned long val)
+void __pmd_error(const char *file, int line, pmd_t pmd)
{
- printk("%s:%d: bad pmd %08lx.\n", file, line, val);
+ printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd));
}
-void __pgd_error(const char *file, int line, unsigned long val)
+void __pgd_error(const char *file, int line, pgd_t pgd)
{
- printk("%s:%d: bad pgd %08lx.\n", file, line, val);
+ printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd));
}
asmlinkage void __div0(void)
@@ -756,7 +758,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
void __init early_trap_init(void)
{
+#if defined(CONFIG_CPU_USE_DOMAINS)
unsigned long vectors = CONFIG_VECTORS_BASE;
+#else
+ unsigned long vectors = (unsigned long)vectors_page;
+#endif
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -780,10 +786,10 @@ void __init early_trap_init(void)
* Copy signal return handlers into the vector page, and
* set sigreturn to be a pointer to these.
*/
- memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
- sizeof(sigreturn_codes));
- memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
- sizeof(syscall_restart_code));
+ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
+ sigreturn_codes, sizeof(sigreturn_codes));
+ memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
+ syscall_restart_code, sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index cead8893b46b..86b66f3f2031 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -101,6 +101,7 @@ SECTIONS
__exception_text_start = .;
*(.exception.text)
__exception_text_end = .;
+ IRQENTRY_TEXT
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
@@ -167,6 +168,7 @@ SECTIONS
NOSAVE_DATA
CACHELINE_ALIGNED_DATA(32)
+ READ_MOSTLY_DATA(32)
/*
* The exception fixup table (might need resorting at runtime)
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index b1631a7dbe75..1b049cd7a49a 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -28,20 +28,21 @@
*/
#include <linux/linkage.h>
#include <asm/errno.h>
+#include <asm/domain.h>
ENTRY(__get_user_1)
-1: ldrbt r2, [r0]
+1: T(ldrb) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__get_user_1)
ENTRY(__get_user_2)
#ifdef CONFIG_THUMB2_KERNEL
-2: ldrbt r2, [r0]
-3: ldrbt r3, [r0, #1]
+2: T(ldrb) r2, [r0]
+3: T(ldrb) r3, [r0, #1]
#else
-2: ldrbt r2, [r0], #1
-3: ldrbt r3, [r0]
+2: T(ldrb) r2, [r0], #1
+3: T(ldrb) r3, [r0]
#endif
#ifndef __ARMEB__
orr r2, r2, r3, lsl #8
@@ -53,7 +54,7 @@ ENTRY(__get_user_2)
ENDPROC(__get_user_2)
ENTRY(__get_user_4)
-4: ldrt r2, [r0]
+4: T(ldr) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__get_user_4)
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 5a01a23c6c06..c023fc11e86c 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -28,9 +28,10 @@
*/
#include <linux/linkage.h>
#include <asm/errno.h>
+#include <asm/domain.h>
ENTRY(__put_user_1)
-1: strbt r2, [r0]
+1: T(strb) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__put_user_1)
@@ -39,19 +40,19 @@ ENTRY(__put_user_2)
mov ip, r2, lsr #8
#ifdef CONFIG_THUMB2_KERNEL
#ifndef __ARMEB__
-2: strbt r2, [r0]
-3: strbt ip, [r0, #1]
+2: T(strb) r2, [r0]
+3: T(strb) ip, [r0, #1]
#else
-2: strbt ip, [r0]
-3: strbt r2, [r0, #1]
+2: T(strb) ip, [r0]
+3: T(strb) r2, [r0, #1]
#endif
#else /* !CONFIG_THUMB2_KERNEL */
#ifndef __ARMEB__
-2: strbt r2, [r0], #1
-3: strbt ip, [r0]
+2: T(strb) r2, [r0], #1
+3: T(strb) ip, [r0]
#else
-2: strbt ip, [r0], #1
-3: strbt r2, [r0]
+2: T(strb) ip, [r0], #1
+3: T(strb) r2, [r0]
#endif
#endif /* CONFIG_THUMB2_KERNEL */
mov r0, #0
@@ -59,18 +60,18 @@ ENTRY(__put_user_2)
ENDPROC(__put_user_2)
ENTRY(__put_user_4)
-4: strt r2, [r0]
+4: T(str) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__put_user_4)
ENTRY(__put_user_8)
#ifdef CONFIG_THUMB2_KERNEL
-5: strt r2, [r0]
-6: strt r3, [r0, #4]
+5: T(str) r2, [r0]
+6: T(str) r3, [r0, #4]
#else
-5: strt r2, [r0], #4
-6: strt r3, [r0]
+5: T(str) r2, [r0], #4
+6: T(str) r3, [r0]
#endif
mov r0, #0
mov pc, lr
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index fee9f6f88adb..d0ece2aeb70d 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -14,6 +14,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
+#include <asm/domain.h>
.text
@@ -31,11 +32,11 @@
rsb ip, ip, #4
cmp ip, #2
ldrb r3, [r1], #1
-USER( strbt r3, [r0], #1) @ May fault
+USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( strgebt r3, [r0], #1) @ May fault
+USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( strgtbt r3, [r0], #1) @ May fault
+USER( T(strgtb) r3, [r0], #1) @ May fault
sub r2, r2, ip
b .Lc2u_dest_aligned
@@ -58,7 +59,7 @@ ENTRY(__copy_to_user)
addmi ip, r2, #4
bmi .Lc2u_0nowords
ldr r3, [r1], #4
-USER( strt r3, [r0], #4) @ May fault
+USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault
stmneia r0!, {r3 - r4} @ Shouldnt fault
tst ip, #4
ldrne r3, [r1], #4
- strnet r3, [r0], #4 @ Shouldnt fault
+ T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_0fupi
.Lc2u_0nowords: teq ip, #0
beq .Lc2u_finished
.Lc2u_nowords: cmp ip, #2
ldrb r3, [r1], #1
-USER( strbt r3, [r0], #1) @ May fault
+USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( strgebt r3, [r0], #1) @ May fault
+USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( strgtbt r3, [r0], #1) @ May fault
+USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_not_enough:
@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #8
ldr r7, [r1], #4
orr r3, r3, r7, push #24
-USER( strt r3, [r0], #4) @ May fault
+USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #8
ldrne r7, [r1], #4
orrne r3, r3, r7, push #24
- strnet r3, [r0], #4 @ Shouldnt fault
+ T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_1fupi
.Lc2u_1nowords: mov r3, r7, get_byte_1
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) @ May fault
+USER( T(strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_2
-USER( strgebt r3, [r0], #1) @ May fault
+USER( T(strgeb) r3, [r0], #1) @ May fault
movgt r3, r7, get_byte_3
-USER( strgtbt r3, [r0], #1) @ May fault
+USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_2fupi: subs r2, r2, #4
@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #16
ldr r7, [r1], #4
orr r3, r3, r7, push #16
-USER( strt r3, [r0], #4) @ May fault
+USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #16
ldrne r7, [r1], #4
orrne r3, r3, r7, push #16
- strnet r3, [r0], #4 @ Shouldnt fault
+ T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_2fupi
.Lc2u_2nowords: mov r3, r7, get_byte_2
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) @ May fault
+USER( T(strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_3
-USER( strgebt r3, [r0], #1) @ May fault
+USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0
-USER( strgtbt r3, [r0], #1) @ May fault
+USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_3fupi: subs r2, r2, #4
@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #24
ldr r7, [r1], #4
orr r3, r3, r7, push #8
-USER( strt r3, [r0], #4) @ May fault
+USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #24
ldrne r7, [r1], #4
orrne r3, r3, r7, push #8
- strnet r3, [r0], #4 @ Shouldnt fault
+ T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_3fupi
.Lc2u_3nowords: mov r3, r7, get_byte_3
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) @ May fault
+USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( strgebt r3, [r0], #1) @ May fault
+USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0
-USER( strgtbt r3, [r0], #1) @ May fault
+USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
ENDPROC(__copy_to_user)
@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user)
.Lcfu_dest_not_aligned:
rsb ip, ip, #4
cmp ip, #2
-USER( ldrbt r3, [r1], #1) @ May fault
+USER( T(ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( ldrgebt r3, [r1], #1) @ May fault
+USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #1) @ May fault
+USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
sub r2, r2, ip
b .Lcfu_dest_aligned
@@ -321,7 +322,7 @@ ENTRY(__copy_from_user)
.Lcfu_0fupi: subs r2, r2, #4
addmi ip, r2, #4
bmi .Lcfu_0nowords
-USER( ldrt r3, [r1], #4)
+USER( T(ldr) r3, [r1], #4)
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4)
ldmneia r1!, {r3 - r4} @ Shouldnt fault
stmneia r0!, {r3 - r4}
tst ip, #4
- ldrnet r3, [r1], #4 @ Shouldnt fault
+ T(ldrne) r3, [r1], #4 @ Shouldnt fault
strne r3, [r0], #4
ands ip, ip, #3
beq .Lcfu_0fupi
.Lcfu_0nowords: teq ip, #0
beq .Lcfu_finished
.Lcfu_nowords: cmp ip, #2
-USER( ldrbt r3, [r1], #1) @ May fault
+USER( T(ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( ldrgebt r3, [r1], #1) @ May fault
+USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #1) @ May fault
+USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
.Lcfu_src_not_aligned:
bic r1, r1, #3
-USER( ldrt r7, [r1], #4) @ May fault
+USER( T(ldr) r7, [r1], #4) @ May fault
cmp ip, #2
bgt .Lcfu_3fupi
beq .Lcfu_2fupi
@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault
addmi ip, r2, #4
bmi .Lcfu_1nowords
mov r3, r7, pull #8
-USER( ldrt r7, [r1], #4) @ May fault
+USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #24
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #8
-USER( ldrnet r7, [r1], #4) @ May fault
+USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #24
strne r3, [r0], #4
ands ip, ip, #3
@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
addmi ip, r2, #4
bmi .Lcfu_2nowords
mov r3, r7, pull #16
-USER( ldrt r7, [r1], #4) @ May fault
+USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #16
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #16
-USER( ldrnet r7, [r1], #4) @ May fault
+USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #16
strne r3, [r0], #4
ands ip, ip, #3
@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
strb r3, [r0], #1
movge r3, r7, get_byte_3
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #0) @ May fault
+USER( T(ldrgtb) r3, [r1], #0) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault
addmi ip, r2, #4
bmi .Lcfu_3nowords
mov r3, r7, pull #24
-USER( ldrt r7, [r1], #4) @ May fault
+USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #8
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #24
-USER( ldrnet r7, [r1], #4) @ May fault
+USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #8
strne r3, [r0], #4
ands ip, ip, #3
@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault
beq .Lcfu_finished
cmp ip, #2
strb r3, [r0], #1
-USER( ldrgebt r3, [r1], #1) @ May fault
+USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #1) @ May fault
+USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
ENDPROC(__copy_from_user)
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index e2d2f2cd0c4f..8b9b13649f81 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
+ pud_t *pud;
spinlock_t *ptl;
pgd = pgd_offset(current->mm, addr);
if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
return 0;
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ if (unlikely(pud_none(*pud) || pud_bad(*pud)))
+ return 0;
+
+ pmd = pmd_offset(pud, addr);
if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
return 0;
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 821eb842795f..d13add71f72a 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -24,8 +24,8 @@ obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
# AT91RM9200 board-specific support
obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
-obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o
-obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o
+obj-$(CONFIG_ARCH_AT91RM9200DK) += board-rm9200dk.o
+obj-$(CONFIG_MACH_AT91RM9200EK) += board-rm9200ek.o
obj-$(CONFIG_MACH_CSB337) += board-csb337.o
obj-$(CONFIG_MACH_CSB637) += board-csb637.o
obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o
@@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
-obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o
+obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
# AT91SAM9260/AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 9338825cfcd7..7b539228e0ef 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -1106,51 +1106,6 @@ static inline void configure_usart3_pins(unsigned pins)
static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init __deprecated at91_init_serial(struct at91_uart_config *config)
-{
- int i;
-
- /* Fill in list of supported UARTs */
- for (i = 0; i < config->nr_tty; i++) {
- switch (config->tty_map[i]) {
- case 0:
- configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91rm9200_uart0_device;
- at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
- break;
- case 1:
- configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
- at91_uarts[i] = &at91rm9200_uart1_device;
- at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
- break;
- case 2:
- configure_usart2_pins(0);
- at91_uarts[i] = &at91rm9200_uart2_device;
- at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
- break;
- case 3:
- configure_usart3_pins(0);
- at91_uarts[i] = &at91rm9200_uart3_device;
- at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
- break;
- case 4:
- configure_dbgu_pins();
- at91_uarts[i] = &at91rm9200_dbgu_device;
- at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart");
- break;
- default:
- continue;
- }
- at91_uarts[i]->id = i; /* update ID number to mapped ID */
- }
-
- /* Set serial console device */
- if (config->console_tty < ATMEL_MAX_UART)
- atmel_default_console_device = at91_uarts[config->console_tty];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 2500f41d8d2d..1dd69c85dfec 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -101,7 +101,6 @@ static struct clocksource clk32k = {
.rating = 150,
.read = read_clk32k,
.mask = CLOCKSOURCE_MASK(20),
- .shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -201,8 +200,7 @@ void __init at91rm9200_timer_init(void)
clockevents_register_device(&clkevt);
/* register clocksource */
- clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift);
- clocksource_register(&clk32k);
+ clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
}
struct sys_timer at91rm9200_timer = {
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 608a63240b64..4ba85499fa97 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -51,7 +51,6 @@ static struct clocksource pit_clk = {
.name = "pit",
.rating = 175,
.read = read_pit_clk,
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -163,10 +162,9 @@ static void __init at91sam926x_pit_init(void)
* Register clocksource. The high order bits of PIV are unused,
* so this isn't a 32-bit counter unless we get clockevent irqs.
*/
- pit_clk.mult = clocksource_hz2mult(pit_rate, pit_clk.shift);
bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
pit_clk.mask = CLOCKSOURCE_MASK(bits);
- clocksource_register(&pit_clk);
+ clocksource_register_hz(&pit_clk, pit_rate);
/* Set up irq handler */
setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq);
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
index 46bdc82d3fbf..8a3fc84847c1 100644
--- a/arch/arm/mach-at91/board-1arm.c
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -39,24 +39,24 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata onearm_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 3,
- .tty_map = { 4, 0, 1, -1, -1 }, /* ttyS0, ..., ttyS4 */
-};
-
static void __init onearm_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
at91rm9200_initialize(18432000, AT91RM9200_PQFP);
- /* Setup the serial ports and console */
- at91_init_serial(&onearm_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init onearm_init_irq(void)
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index c0ce79d431a0..d2e1f4ec1fcc 100644
--- a/arch/arm/mach-at91/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -39,17 +39,6 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata kafa_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 0, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init kafa_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
@@ -58,8 +47,14 @@ static void __init kafa_map_io(void)
/* Set up the LEDs */
at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
- /* Setup the serial ports and console */
- at91_init_serial(&kafa_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init kafa_init_irq(void)
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
index bba5a560e02b..feb65787c30b 100644
--- a/arch/arm/mach-at91/board-pcontrol-g20.c
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -31,6 +31,7 @@
#include <mach/board.h>
#include <mach/at91sam9_smc.h>
+#include <mach/stamp9g20.h>
#include "sam9_smc.h"
#include "generic.h"
@@ -38,11 +39,7 @@
static void __init pcontrol_g20_map_io(void)
{
- /* Initialize processor: 18.432 MHz crystal */
- at91sam9260_initialize(18432000);
-
- /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
- at91_register_uart(0, 0, 0);
+ stamp9g20_map_io();
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */
at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
@@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void)
/* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */
at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
-
- /* set serial console to ttyS0 (ie, DBGU) */
- at91_set_serial_console(0);
}
@@ -66,38 +60,6 @@ static void __init init_irq(void)
}
-/*
- * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
- */
-static struct atmel_nand_data __initdata nand_data = {
- .ale = 21,
- .cle = 22,
- .rdy_pin = AT91_PIN_PC13,
- .enable_pin = AT91_PIN_PC14,
-};
-
-/*
- * Bus timings; unit = 7.57ns
- */
-static struct sam9_smc_config __initdata nand_smc_config = {
- .ncs_read_setup = 0,
- .nrd_setup = 2,
- .ncs_write_setup = 0,
- .nwe_setup = 2,
-
- .ncs_read_pulse = 4,
- .nrd_pulse = 4,
- .ncs_write_pulse = 4,
- .nwe_pulse = 4,
-
- .read_cycle = 7,
- .write_cycle = 7,
-
- .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
- | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
- .tdf_cycles = 3,
-};
-
static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
.ncs_read_setup = 16,
.nrd_setup = 18,
@@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
.tdf_cycles = 1,
} };
-static void __init add_device_nand(void)
-{
- /* configure chip-select 3 (NAND) */
- sam9_smc_configure(3, &nand_smc_config);
- at91_add_device_nand(&nand_data);
-}
-
-
static void __init add_device_pcontrol(void)
{
/* configure chip-select 4 (IO compatible to 8051 X4 ) */
@@ -156,23 +110,6 @@ static void __init add_device_pcontrol(void)
/*
- * MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata mmc_data = {
- .slot[0] = {
- .bus_width = 4,
- },
-};
-#else
-static struct at91_mmc_data __initdata mmc_data = {
- .wire4 = 1,
-};
-#endif
-
-
-/*
* USB Host port
*/
static struct at91_usbh_data __initdata usbh_data = {
@@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = {
};
-/*
- * Dallas 1-Wire DS2431
- */
-static struct w1_gpio_platform_data w1_gpio_pdata = {
- .pin = AT91_PIN_PA29,
- .is_open_drain = 1,
-};
-
-static struct platform_device w1_device = {
- .name = "w1-gpio",
- .id = -1,
- .dev.platform_data = &w1_gpio_pdata,
-};
-
-static void add_wire1(void)
-{
- at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
- at91_set_multi_drive(w1_gpio_pdata.pin, 1);
- platform_device_register(&w1_device);
-}
-
-
static void __init pcontrol_g20_board_init(void)
{
- at91_add_device_serial();
- add_device_nand();
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
- at91_add_device_mci(0, &mmc_data);
-#else
- at91_add_device_mmc(0, &mmc_data);
-#endif
+ stamp9g20_board_init();
at91_add_device_usbh(&usbh_data);
at91_add_device_eth(&macb_data);
at91_add_device_i2c(pcontrol_g20_i2c_devices,
ARRAY_SIZE(pcontrol_g20_i2c_devices));
- add_wire1();
add_device_pcontrol();
at91_add_device_spi(pcontrol_g20_spi_devices,
ARRAY_SIZE(pcontrol_g20_spi_devices));
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index 9d833bbc592d..55dad3a46547 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -43,24 +43,21 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata picotux200_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init picotux200_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
at91rm9200_initialize(18432000, AT91RM9200_BGA);
- /* Setup the serial ports and console */
- at91_init_serial(&picotux200_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init picotux200_init_irq(void)
@@ -77,11 +74,6 @@ static struct at91_usbh_data __initdata picotux200_usbh_data = {
.ports = 1,
};
-// static struct at91_udc_data __initdata picotux200_udc_data = {
-// .vbus_pin = AT91_PIN_PD4,
-// .pullup_pin = AT91_PIN_PD5,
-// };
-
static struct at91_mmc_data __initdata picotux200_mmc_data = {
.det_pin = AT91_PIN_PB27,
.slot_b = 0,
@@ -89,21 +81,6 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = {
.wp_pin = AT91_PIN_PA17,
};
-// static struct spi_board_info picotux200_spi_devices[] = {
-// { /* DataFlash chip */
-// .modalias = "mtd_dataflash",
-// .chip_select = 0,
-// .max_speed_hz = 15 * 1000 * 1000,
-// },
-// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-// { /* DataFlash card */
-// .modalias = "mtd_dataflash",
-// .chip_select = 3,
-// .max_speed_hz = 15 * 1000 * 1000,
-// },
-// #endif
-// };
-
#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0
#define PICOTUX200_FLASH_SIZE SZ_4M
@@ -135,21 +112,11 @@ static void __init picotux200_board_init(void)
at91_add_device_eth(&picotux200_eth_data);
/* USB Host */
at91_add_device_usbh(&picotux200_usbh_data);
- /* USB Device */
- // at91_add_device_udc(&picotux200_udc_data);
- // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
/* I2C */
at91_add_device_i2c(NULL, 0);
- /* SPI */
- // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
- /* DataFlash card */
- at91_set_gpio_output(AT91_PIN_PB22, 0);
-#else
/* MMC */
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
at91_add_device_mmc(0, &picotux200_mmc_data);
-#endif
/* NOR Flash */
platform_device_register(&picotux200_flash);
}
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-rm9200dk.c
index e14f0e165680..4c1047c8200d 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-rm9200dk.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-at91/board-dk.c
+ * linux/arch/arm/mach-at91/board-rm9200dk.c
*
* Copyright (C) 2005 SAN People
*
@@ -91,10 +91,12 @@ static struct at91_cf_data __initdata dk_cf_data = {
// .vcc_pin = ... always powered
};
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
static struct at91_mmc_data __initdata dk_mmc_data = {
.slot_b = 0,
.wire4 = 1,
};
+#endif
static struct spi_board_info dk_spi_devices[] = {
{ /* DataFlash chip */
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-rm9200ek.c
index 56e92c4bbc2a..9df1be8818c0 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-rm9200ek.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-at91/board-ek.c
+ * linux/arch/arm/mach-at91/board-rm9200ek.c
*
* Copyright (C) 2005 SAN People
*
@@ -84,12 +84,14 @@ static struct at91_udc_data __initdata ek_udc_data = {
.pullup_pin = AT91_PIN_PD5,
};
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
static struct at91_mmc_data __initdata ek_mmc_data = {
.det_pin = AT91_PIN_PB27,
.slot_b = 0,
.wire4 = 1,
.wp_pin = AT91_PIN_PA17,
};
+#endif
static struct spi_board_info ek_spi_devices[] = {
{ /* DataFlash chip */
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 5206eef4a67e..f8902b118960 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -32,7 +32,7 @@
#include "generic.h"
-static void __init portuxg20_map_io(void)
+void __init stamp9g20_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
at91sam9260_initialize(18432000);
@@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void)
/* DGBU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init stamp9g20evb_map_io(void)
+{
+ stamp9g20_map_io();
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR
+ | ATMEL_UART_DCD | ATMEL_UART_RI);
+}
+
+static void __init portuxg20_map_io(void)
+{
+ stamp9g20_map_io();
+
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
| ATMEL_UART_DTR | ATMEL_UART_DSR
@@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void)
/* USART5 on ttyS6. (Rx, Tx only) */
at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
-
- /* set serial console to ttyS0 (ie, DBGU) */
- at91_set_serial_console(0);
-}
-
-static void __init stamp9g20_map_io(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- at91sam9260_initialize(18432000);
-
- /* DGBU on ttyS0. (Rx & Tx only) */
- at91_register_uart(0, 0, 0);
-
- /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
- at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
- | ATMEL_UART_DTR | ATMEL_UART_DSR
- | ATMEL_UART_DCD | ATMEL_UART_RI);
-
- /* set serial console to ttyS0 (ie, DBGU) */
- at91_set_serial_console(0);
}
static void __init init_irq(void)
@@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = {
.pullup_pin = 0, /* pull-up driven by UDC */
};
-static struct at91_udc_data __initdata stamp9g20_udc_data = {
+static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
.vbus_pin = AT91_PIN_PA22,
.pullup_pin = 0, /* pull-up driven by UDC */
};
@@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = {
}
};
-static struct gpio_led stamp9g20_leds[] = {
+static struct gpio_led stamp9g20evb_leds[] = {
{
.name = "D8",
.gpio = AT91_PIN_PB18,
@@ -250,7 +248,7 @@ void add_w1(void)
}
-static void __init generic_board_init(void)
+void __init stamp9g20_board_init(void)
{
/* Serial */
at91_add_device_serial();
@@ -262,34 +260,40 @@ static void __init generic_board_init(void)
#else
at91_add_device_mmc(0, &mmc_data);
#endif
- /* USB Host */
- at91_add_device_usbh(&usbh_data);
- /* Ethernet */
- at91_add_device_eth(&macb_data);
- /* I2C */
- at91_add_device_i2c(NULL, 0);
/* W1 */
add_w1();
}
static void __init portuxg20_board_init(void)
{
- generic_board_init();
- /* SPI */
- at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+ stamp9g20_board_init();
+ /* USB Host */
+ at91_add_device_usbh(&usbh_data);
/* USB Device */
at91_add_device_udc(&portuxg20_udc_data);
+ /* Ethernet */
+ at91_add_device_eth(&macb_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
/* LEDs */
at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
}
-static void __init stamp9g20_board_init(void)
+static void __init stamp9g20evb_board_init(void)
{
- generic_board_init();
+ stamp9g20_board_init();
+ /* USB Host */
+ at91_add_device_usbh(&usbh_data);
/* USB Device */
- at91_add_device_udc(&stamp9g20_udc_data);
+ at91_add_device_udc(&stamp9g20evb_udc_data);
+ /* Ethernet */
+ at91_add_device_eth(&macb_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
/* LEDs */
- at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
+ at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
}
MACHINE_START(PORTUXG20, "taskit PortuxG20")
@@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20")
/* Maintainer: taskit GmbH */
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
- .map_io = stamp9g20_map_io,
+ .map_io = stamp9g20evb_map_io,
.init_irq = init_irq,
- .init_machine = stamp9g20_board_init,
+ .init_machine = stamp9g20evb_board_init,
MACHINE_END
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
index 89df00a9d2f7..e0f0080eb639 100644
--- a/arch/arm/mach-at91/board-yl-9200.c
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -387,7 +387,7 @@ static struct spi_board_info yl9200_spi_devices[] = {
* EPSON S1D13806 FB (discontinued chip)
* EPSON S1D13506 FB
*/
-#if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
+#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE)
#include <video/s1d13xxxfb.h>
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 7525cee3983f..9113da6845f1 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
/* Now set uhpck values */
uhpck.parent = &utmi_clk;
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
- uhpck.rate_hz = utmi_clk.parent->rate_hz;
+ uhpck.rate_hz = utmi_clk.rate_hz;
uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
}
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 58528aa9c8a8..2b499eb343a1 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -137,13 +137,7 @@ extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_de
extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins);
extern void __init at91_set_serial_console(unsigned portnr);
-struct at91_uart_config {
- unsigned short console_tty; /* tty number of serial console */
- unsigned short nr_tty; /* number of serial tty's */
- short tty_map[]; /* map UART to tty number */
-};
extern struct platform_device *atmel_default_console_device;
-extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
struct atmel_uart_data {
short use_dma_tx; /* use transmit DMA? */
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h
new file mode 100644
index 000000000000..6120f9c46d59
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/stamp9g20.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_STAMP9G20_H
+#define __MACH_STAMP9G20_H
+
+void stamp9g20_map_io(void);
+void stamp9g20_board_init(void);
+
+#endif
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
index 14bafc38f2dc..ad237a42d265 100644
--- a/arch/arm/mach-bcmring/clock.c
+++ b/arch/arm/mach-bcmring/clock.c
@@ -21,13 +21,12 @@
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
+#include <linux/clkdev.h>
#include <mach/csp/hw_cfg.h>
#include <mach/csp/chipcHw_def.h>
#include <mach/csp/chipcHw_reg.h>
#include <mach/csp/chipcHw_inline.h>
-#include <asm/clkdev.h>
-
#include "clock.h"
#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index d3f959e92b2d..8fc2035759fb 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -30,10 +30,10 @@
#include <linux/amba/bus.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/clkdev.h>
#include <mach/csp/mm_addr.h>
#include <mach/hardware.h>
-#include <asm/clkdev.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/hardware/arm_timer.h>
@@ -294,7 +294,6 @@ static struct clocksource clocksource_bcmring_timer1 = {
.rating = 200,
.read = bcmring_get_cycles_timer1,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -303,7 +302,6 @@ static struct clocksource clocksource_bcmring_timer3 = {
.rating = 100,
.read = bcmring_get_cycles_timer3,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -316,10 +314,8 @@ static int __init bcmring_clocksource_init(void)
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
TIMER1_VA_BASE + TIMER_CTRL);
- clocksource_bcmring_timer1.mult =
- clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000,
- clocksource_bcmring_timer1.shift);
- clocksource_register(&clocksource_bcmring_timer1);
+ clocksource_register_khz(&clocksource_bcmring_timer1,
+ TIMER1_FREQUENCY_MHZ * 1000);
/* setup timer3 as free-running clocksource */
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
@@ -328,10 +324,8 @@ static int __init bcmring_clocksource_init(void)
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
TIMER3_VA_BASE + TIMER_CTRL);
- clocksource_bcmring_timer3.mult =
- clocksource_khz2mult(TIMER3_FREQUENCY_KHZ,
- clocksource_bcmring_timer3.shift);
- clocksource_register(&clocksource_bcmring_timer3);
+ clocksource_register_khz(&clocksource_bcmring_timer3,
+ TIMER3_FREQUENCY_KHZ);
return 0;
}
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
index 9ebfcc46feb1..29b13f249aa9 100644
--- a/arch/arm/mach-cns3xxx/Kconfig
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -3,6 +3,7 @@ menu "CNS3XXX platform type"
config MACH_CNS3420VB
bool "Support for CNS3420 Validation Board"
+ select MIGHT_HAVE_PCI
help
Include support for the Cavium Networks CNS3420 MPCore Platform
Baseboard.
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
index 90fe9ab8591d..08e5c8759502 100644
--- a/arch/arm/mach-cns3xxx/cns3420vb.c
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/io.h>
+#include <linux/dma-mapping.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
@@ -108,10 +109,63 @@ static void __init cns3420_early_serial_setup(void)
}
/*
+ * USB
+ */
+static struct resource cns3xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_BASE,
+ .end = CNS3XXX_USB_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_EHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ehci_device = {
+ .name = "cns3xxx-ehci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
+ .resource = cns3xxx_usb_ehci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ehci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource cns3xxx_usb_ohci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_OHCI_BASE,
+ .end = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ohci_device = {
+ .name = "cns3xxx-ohci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
+ .resource = cns3xxx_usb_ohci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/*
* Initialization
*/
static struct platform_device *cns3420_pdevs[] __initdata = {
&cns3420_nor_pdev,
+ &cns3xxx_usb_ehci_device,
+ &cns3xxx_usb_ohci_device,
};
static void __init cns3420_init(void)
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
index 9ca4d581016f..da30078a80c1 100644
--- a/arch/arm/mach-cns3xxx/core.c
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -69,13 +69,10 @@ void __init cns3xxx_map_io(void)
}
/* used by entry-macro.S */
-void __iomem *gic_cpu_base_addr;
-
void __init cns3xxx_init_irq(void)
{
- gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
- gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
+ __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
}
void cns3xxx_power_off(void)
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
index 6b33ec11346e..ffeb3a8b73ba 100644
--- a/arch/arm/mach-cns3xxx/core.h
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -11,13 +11,10 @@
#ifndef __CNS3XXX_CORE_H
#define __CNS3XXX_CORE_H
-extern void __iomem *gic_cpu_base_addr;
extern struct sys_timer cns3xxx_timer;
void __init cns3xxx_map_io(void);
void __init cns3xxx_init_irq(void);
void cns3xxx_power_off(void);
-void cns3xxx_pwr_power_up(unsigned int block);
-void cns3xxx_pwr_power_down(unsigned int block);
#endif /* __CNS3XXX_CORE_H */
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c
index 50b4d31c27c0..79d1fb02c23f 100644
--- a/arch/arm/mach-cns3xxx/devices.c
+++ b/arch/arm/mach-cns3xxx/devices.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <mach/cns3xxx.h>
#include <mach/irqs.h>
+#include <mach/pm.h>
#include "core.h"
#include "devices.h"
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
index 6dbce13771ca..191c8e57f289 100644
--- a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
+++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
@@ -165,7 +165,6 @@
#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000
#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */
-#define CNS3XXX_USB_BASE_VIRT 0xFFF16000
#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */
#define CNS3XXX_SATA2_SIZE SZ_16M
@@ -184,7 +183,6 @@
#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000
#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */
-#define CNS3XXX_USB_OHCI_BASE_VIRT 0xFFF1C000
#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */
#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
index 5e1c5545680f..6bd83ed90afe 100644
--- a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
+++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
@@ -9,74 +9,10 @@
*/
#include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =gic_cpu_base_addr
- ldr \base, [\base]
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an interrupt if it's
- * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
- *
- * A simple read from the controller will tell us the number of the highest
- * priority enabled interrupt. We then just need to check whether it is in the
- * valid range for an IRQ (30-1020 inclusive).
- */
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
- ldr \tmp, =1021
-
- bic \irqnr, \irqstat, #0x1c00
-
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
-
- .endm
-
- /* We assume that irqstat (the raw value of the IRQ acknowledge
- * register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of interrupt on the
- * controller, since this requires the original irqstat value which
- * we won't easily be able to recreate later.
- */
-
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base are preserved.. */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
diff --git a/arch/arm/mach-cns3xxx/include/mach/pm.h b/arch/arm/mach-cns3xxx/include/mach/pm.h
new file mode 100644
index 000000000000..6eae7f764d1d
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/pm.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CNS3XXX_PM_H
+#define __CNS3XXX_PM_H
+
+#include <asm/atomic.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block);
+void cns3xxx_pwr_clk_dis(unsigned int block);
+void cns3xxx_pwr_power_up(unsigned int block);
+void cns3xxx_pwr_power_down(unsigned int block);
+
+extern atomic_t usb_pwr_ref;
+
+#endif /* __CNS3XXX_PM_H */
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
index 38088c36936c..78defd71a829 100644
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -369,7 +369,7 @@ static int __init cns3xxx_pcie_init(void)
{
int i;
- hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS,
+ hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
"imprecise external abort");
for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
index 38e44706feab..5e579552aa54 100644
--- a/arch/arm/mach-cns3xxx/pm.c
+++ b/arch/arm/mach-cns3xxx/pm.c
@@ -6,10 +6,14 @@
* published by the Free Software Foundation.
*/
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <asm/atomic.h>
#include <mach/system.h>
#include <mach/cns3xxx.h>
+#include <mach/pm.h>
void cns3xxx_pwr_clk_en(unsigned int block)
{
@@ -18,6 +22,16 @@ void cns3xxx_pwr_clk_en(unsigned int block)
reg |= (block & PM_CLK_GATE_REG_MASK);
__raw_writel(reg, PM_CLK_GATE_REG);
}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_en);
+
+void cns3xxx_pwr_clk_dis(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_CLK_GATE_REG);
+
+ reg &= ~(block & PM_CLK_GATE_REG_MASK);
+ __raw_writel(reg, PM_CLK_GATE_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_dis);
void cns3xxx_pwr_power_up(unsigned int block)
{
@@ -29,6 +43,7 @@ void cns3xxx_pwr_power_up(unsigned int block)
/* Wait for 300us for the PLL output clock locked. */
udelay(300);
};
+EXPORT_SYMBOL(cns3xxx_pwr_power_up);
void cns3xxx_pwr_power_down(unsigned int block)
{
@@ -38,6 +53,7 @@ void cns3xxx_pwr_power_down(unsigned int block)
reg |= (block & CNS3XXX_PWR_PLL_ALL);
__raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
};
+EXPORT_SYMBOL(cns3xxx_pwr_power_down);
static void cns3xxx_pwr_soft_rst_force(unsigned int block)
{
@@ -51,11 +67,13 @@ static void cns3xxx_pwr_soft_rst_force(unsigned int block)
reg &= ~(block & PM_SOFT_RST_REG_MASK);
} else {
reg &= ~(block & PM_SOFT_RST_REG_MASK);
+ __raw_writel(reg, PM_SOFT_RST_REG);
reg |= (block & PM_SOFT_RST_REG_MASK);
}
__raw_writel(reg, PM_SOFT_RST_REG);
}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst_force);
void cns3xxx_pwr_soft_rst(unsigned int block)
{
@@ -69,6 +87,7 @@ void cns3xxx_pwr_soft_rst(unsigned int block)
}
cns3xxx_pwr_soft_rst_force(block);
}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst);
void arch_reset(char mode, const char *cmd)
{
@@ -99,3 +118,7 @@ int cns3xxx_cpu_clock(void)
return cpu;
}
+EXPORT_SYMBOL(cns3xxx_cpu_clock);
+
+atomic_t usb_pwr_ref = ATOMIC_INIT(0);
+EXPORT_SYMBOL(usb_pwr_ref);
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index b77b860b36d7..32f147998cd9 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -61,6 +61,8 @@ config MACH_DAVINCI_EVM
bool "TI DM644x EVM"
default ARCH_DAVINCI_DM644x
depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Configure this option to specify the whether the board used
for development is a DM644x EVM
@@ -68,6 +70,8 @@ config MACH_DAVINCI_EVM
config MACH_SFFSDR
bool "Lyrtech SFFSDR"
depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Say Y here to select the Lyrtech Small Form Factor
Software Defined Radio (SFFSDR) board.
@@ -99,6 +103,8 @@ config MACH_DAVINCI_DM6467_EVM
default ARCH_DAVINCI_DM646x
depends on ARCH_DAVINCI_DM646x
select MACH_DAVINCI_DM6467TEVM
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Configure this option to specify the whether the board used
for development is a DM6467 EVM
@@ -110,6 +116,8 @@ config MACH_DAVINCI_DM365_EVM
bool "TI DM365 EVM"
default ARCH_DAVINCI_DM365
depends on ARCH_DAVINCI_DM365
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Configure this option to specify whether the board used
for development is a DM365 EVM
@@ -119,6 +127,8 @@ config MACH_DAVINCI_DA830_EVM
default ARCH_DAVINCI_DA830
depends on ARCH_DAVINCI_DA830
select GPIO_PCF857X
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
@@ -148,7 +158,6 @@ config MACH_DAVINCI_DA850_EVM
bool "TI DA850/OMAP-L138/AM18x Reference Platform"
default ARCH_DAVINCI_DA850
depends on ARCH_DAVINCI_DA850
- select GPIO_PCA953X
help
Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module.
@@ -178,6 +187,12 @@ config DA850_UI_RMII
endchoice
+config GPIO_PCA953X
+ default MACH_DAVINCI_DA850_EVM
+
+config KEYBOARD_GPIO_POLLED
+ default MACH_DAVINCI_DA850_EVM
+
config MACH_TNETV107X
bool "TI TNETV107X Reference Platform"
default ARCH_DAVINCI_TNETV107X
@@ -188,6 +203,8 @@ config MACH_TNETV107X
config MACH_MITYOMAPL138
bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
depends on ARCH_DAVINCI_DA850
+ select MISC_DEVICES
+ select EEPROM_AT24
help
Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
System on Module. Information on this SoM may be found at
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
index 9c3f500fc12f..1ce70a91f2e9 100644
--- a/arch/arm/mach-davinci/aemif.c
+++ b/arch/arm/mach-davinci/aemif.c
@@ -90,7 +90,7 @@ int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
void __iomem *base, unsigned cs)
{
unsigned set, val;
- unsigned ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
unsigned offset = A1CR_OFFSET + cs * 4;
struct clk *aemif_clk;
unsigned long clkrate;
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index c6e11c682e4c..b01fb2ab944a 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -17,8 +17,10 @@
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/i2c/pca953x.h>
+#include <linux/input.h>
#include <linux/mfd/tps6507x.h>
#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -266,34 +268,115 @@ static inline void da850_evm_setup_emac_rmii(int rmii_sel)
struct davinci_soc_info *soc_info = &davinci_soc_info;
soc_info->emac_pdata->rmii_en = 1;
- gpio_set_value(rmii_sel, 0);
+ gpio_set_value_cansleep(rmii_sel, 0);
}
#else
static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
#endif
+
+#define DA850_KEYS_DEBOUNCE_MS 10
+/*
+ * At 200ms polling interval it is possible to miss an
+ * event by tapping very lightly on the push button but most
+ * pushes do result in an event; longer intervals require the
+ * user to hold the button whereas shorter intervals require
+ * more CPU time for polling.
+ */
+#define DA850_GPIO_KEYS_POLL_MS 200
+
+enum da850_evm_ui_exp_pins {
+ DA850_EVM_UI_EXP_SEL_C = 5,
+ DA850_EVM_UI_EXP_SEL_B,
+ DA850_EVM_UI_EXP_SEL_A,
+ DA850_EVM_UI_EXP_PB8,
+ DA850_EVM_UI_EXP_PB7,
+ DA850_EVM_UI_EXP_PB6,
+ DA850_EVM_UI_EXP_PB5,
+ DA850_EVM_UI_EXP_PB4,
+ DA850_EVM_UI_EXP_PB3,
+ DA850_EVM_UI_EXP_PB2,
+ DA850_EVM_UI_EXP_PB1,
+};
+
+static const char const *da850_evm_ui_exp[] = {
+ [DA850_EVM_UI_EXP_SEL_C] = "sel_c",
+ [DA850_EVM_UI_EXP_SEL_B] = "sel_b",
+ [DA850_EVM_UI_EXP_SEL_A] = "sel_a",
+ [DA850_EVM_UI_EXP_PB8] = "pb8",
+ [DA850_EVM_UI_EXP_PB7] = "pb7",
+ [DA850_EVM_UI_EXP_PB6] = "pb6",
+ [DA850_EVM_UI_EXP_PB5] = "pb5",
+ [DA850_EVM_UI_EXP_PB4] = "pb4",
+ [DA850_EVM_UI_EXP_PB3] = "pb3",
+ [DA850_EVM_UI_EXP_PB2] = "pb2",
+ [DA850_EVM_UI_EXP_PB1] = "pb1",
+};
+
+#define DA850_N_UI_PB 8
+
+static struct gpio_keys_button da850_evm_ui_keys[] = {
+ [0 ... DA850_N_UI_PB - 1] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
+ .buttons = da850_evm_ui_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_ui_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 0,
+ .dev = {
+ .platform_data = &da850_evm_ui_keys_pdata
+ },
+};
+
+static void da850_evm_ui_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ for (i = 0; i < DA850_N_UI_PB; i++) {
+ button = &da850_evm_ui_keys[i];
+ button->code = KEY_F8 - i;
+ button->desc = (char *)
+ da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
+ button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
+ }
+}
+
static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
unsigned ngpio, void *c)
{
int sel_a, sel_b, sel_c, ret;
- sel_a = gpio + 7;
- sel_b = gpio + 6;
- sel_c = gpio + 5;
+ sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
+ sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
+ sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
- ret = gpio_request(sel_a, "sel_a");
+ ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_a);
goto exp_setup_sela_fail;
}
- ret = gpio_request(sel_b, "sel_b");
+ ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_b);
goto exp_setup_selb_fail;
}
- ret = gpio_request(sel_c, "sel_c");
+ ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
if (ret) {
pr_warning("Cannot open UI expander pin %d\n", sel_c);
goto exp_setup_selc_fail;
@@ -304,6 +387,13 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
gpio_direction_output(sel_b, 1);
gpio_direction_output(sel_c, 1);
+ da850_evm_ui_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_ui_keys_device);
+ if (ret) {
+ pr_warning("Could not register UI GPIO expander push-buttons");
+ goto exp_setup_keys_fail;
+ }
+
ui_card_detected = 1;
pr_info("DA850/OMAP-L138 EVM UI card detected\n");
@@ -313,6 +403,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
return 0;
+exp_setup_keys_fail:
+ gpio_free(sel_c);
exp_setup_selc_fail:
gpio_free(sel_b);
exp_setup_selb_fail:
@@ -324,14 +416,192 @@ exp_setup_sela_fail:
static int da850_evm_ui_expander_teardown(struct i2c_client *client,
unsigned gpio, unsigned ngpio, void *c)
{
+ platform_device_unregister(&da850_evm_ui_keys_device);
+
/* deselect all functionalities */
- gpio_set_value(gpio + 5, 1);
- gpio_set_value(gpio + 6, 1);
- gpio_set_value(gpio + 7, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1);
+
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
+
+ return 0;
+}
+
+/* assign the baseboard expander's GPIOs after the UI board's */
+#define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp)
+#define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS)
+
+enum da850_evm_bb_exp_pins {
+ DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0,
+ DA850_EVM_BB_EXP_SW_RST,
+ DA850_EVM_BB_EXP_TP_23,
+ DA850_EVM_BB_EXP_TP_22,
+ DA850_EVM_BB_EXP_TP_21,
+ DA850_EVM_BB_EXP_USER_PB1,
+ DA850_EVM_BB_EXP_USER_LED2,
+ DA850_EVM_BB_EXP_USER_LED1,
+ DA850_EVM_BB_EXP_USER_SW1,
+ DA850_EVM_BB_EXP_USER_SW2,
+ DA850_EVM_BB_EXP_USER_SW3,
+ DA850_EVM_BB_EXP_USER_SW4,
+ DA850_EVM_BB_EXP_USER_SW5,
+ DA850_EVM_BB_EXP_USER_SW6,
+ DA850_EVM_BB_EXP_USER_SW7,
+ DA850_EVM_BB_EXP_USER_SW8
+};
+
+static const char const *da850_evm_bb_exp[] = {
+ [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en",
+ [DA850_EVM_BB_EXP_SW_RST] = "sw_rst",
+ [DA850_EVM_BB_EXP_TP_23] = "tp_23",
+ [DA850_EVM_BB_EXP_TP_22] = "tp_22",
+ [DA850_EVM_BB_EXP_TP_21] = "tp_21",
+ [DA850_EVM_BB_EXP_USER_PB1] = "user_pb1",
+ [DA850_EVM_BB_EXP_USER_LED2] = "user_led2",
+ [DA850_EVM_BB_EXP_USER_LED1] = "user_led1",
+ [DA850_EVM_BB_EXP_USER_SW1] = "user_sw1",
+ [DA850_EVM_BB_EXP_USER_SW2] = "user_sw2",
+ [DA850_EVM_BB_EXP_USER_SW3] = "user_sw3",
+ [DA850_EVM_BB_EXP_USER_SW4] = "user_sw4",
+ [DA850_EVM_BB_EXP_USER_SW5] = "user_sw5",
+ [DA850_EVM_BB_EXP_USER_SW6] = "user_sw6",
+ [DA850_EVM_BB_EXP_USER_SW7] = "user_sw7",
+ [DA850_EVM_BB_EXP_USER_SW8] = "user_sw8",
+};
+
+#define DA850_N_BB_USER_SW 8
+
+static struct gpio_keys_button da850_evm_bb_keys[] = {
+ [0] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = KEY_PROG1,
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+ [1 ... DA850_N_BB_USER_SW] = {
+ .type = EV_SW,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = {
+ .buttons = da850_evm_bb_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_bb_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_bb_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 1,
+ .dev = {
+ .platform_data = &da850_evm_bb_keys_pdata
+ },
+};
+
+static void da850_evm_bb_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ button = &da850_evm_bb_keys[0];
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1;
+
+ for (i = 0; i < DA850_N_BB_USER_SW; i++) {
+ button = &da850_evm_bb_keys[i + 1];
+ button->code = SW_LID + i;
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i;
+ }
+}
- gpio_free(gpio + 5);
- gpio_free(gpio + 6);
- gpio_free(gpio + 7);
+#define DA850_N_BB_USER_LED 2
+
+static struct gpio_led da850_evm_bb_leds[] = {
+ [0 ... DA850_N_BB_USER_LED - 1] = {
+ .active_low = 1,
+ .gpio = -1, /* assigned at runtime */
+ .name = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_led_platform_data da850_evm_bb_leds_pdata = {
+ .leds = da850_evm_bb_leds,
+ .num_leds = ARRAY_SIZE(da850_evm_bb_leds),
+};
+
+static struct platform_device da850_evm_bb_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_evm_bb_leds_pdata
+ }
+};
+
+static void da850_evm_bb_leds_init(unsigned gpio)
+{
+ int i;
+ struct gpio_led *led;
+
+ for (i = 0; i < DA850_N_BB_USER_LED; i++) {
+ led = &da850_evm_bb_leds[i];
+
+ led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i;
+ led->name =
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i];
+ }
+}
+
+static int da850_evm_bb_expander_setup(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio,
+ void *c)
+{
+ int ret;
+
+ /*
+ * Register the switches and pushbutton on the baseboard as a gpio-keys
+ * device.
+ */
+ da850_evm_bb_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_keys_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander keys");
+ goto io_exp_setup_sw_fail;
+ }
+
+ da850_evm_bb_leds_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_leds_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander LEDS");
+ goto io_exp_setup_leds_fail;
+ }
+
+ return 0;
+
+io_exp_setup_leds_fail:
+ platform_device_unregister(&da850_evm_bb_keys_device);
+io_exp_setup_sw_fail:
+ return ret;
+}
+
+static int da850_evm_bb_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
+{
+ platform_device_unregister(&da850_evm_bb_leds_device);
+ platform_device_unregister(&da850_evm_bb_keys_device);
return 0;
}
@@ -340,6 +610,14 @@ static struct pca953x_platform_data da850_evm_ui_expander_info = {
.gpio_base = DAVINCI_N_GPIO,
.setup = da850_evm_ui_expander_setup,
.teardown = da850_evm_ui_expander_teardown,
+ .names = da850_evm_ui_exp,
+};
+
+static struct pca953x_platform_data da850_evm_bb_expander_info = {
+ .gpio_base = DA850_BB_EXPANDER_GPIO_BASE,
+ .setup = da850_evm_bb_expander_setup,
+ .teardown = da850_evm_bb_expander_teardown,
+ .names = da850_evm_bb_exp,
};
static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
@@ -350,6 +628,10 @@ static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
I2C_BOARD_INFO("tca6416", 0x20),
.platform_data = &da850_evm_ui_expander_info,
},
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &da850_evm_bb_expander_info,
+ },
};
static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
@@ -540,7 +822,7 @@ static struct regulator_init_data tps65070_regulator_data[] = {
{
.constraints = {
.min_uV = 950000,
- .max_uV = 1320000,
+ .max_uV = 1350000,
.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS),
.boot_on = 1,
@@ -591,7 +873,7 @@ static struct tps6507x_board tps_board = {
.tps6507x_ts_init_data = &tps6507x_touchscreen_data,
};
-static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
+static struct i2c_board_info __initdata da850_evm_tps65070_info[] = {
{
I2C_BOARD_INFO("tps6507x", 0x48),
.platform_data = &tps_board,
@@ -600,8 +882,8 @@ static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
static int __init pmic_tps65070_init(void)
{
- return i2c_register_board_info(1, da850evm_tps65070_info,
- ARRAY_SIZE(da850evm_tps65070_info));
+ return i2c_register_board_info(1, da850_evm_tps65070_info,
+ ARRAY_SIZE(da850_evm_tps65070_info));
}
static const short da850_evm_lcdc_pins[] = {
@@ -736,6 +1018,27 @@ static struct edma_rsv_info *da850_edma_rsv[2] = {
&da850_edma_cc1_rsv,
};
+#ifdef CONFIG_CPU_FREQ
+static __init int da850_evm_init_cpufreq(void)
+{
+ switch (system_rev & 0xF) {
+ case 3:
+ da850_max_speed = 456000;
+ break;
+ case 2:
+ da850_max_speed = 408000;
+ break;
+ case 1:
+ da850_max_speed = 372000;
+ break;
+ }
+
+ return da850_register_cpufreq("pll0_sysclk3");
+}
+#else
+static __init int da850_evm_init_cpufreq(void) { return 0; }
+#endif
+
static __init void da850_evm_init(void)
{
int ret;
@@ -836,7 +1139,7 @@ static __init void da850_evm_init(void)
if (ret)
pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
- ret = da850_register_cpufreq("pll0_sysclk3");
+ ret = da850_evm_init_cpufreq();
if (ret)
pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
ret);
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 01ba080433db..e4e3af179f02 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -336,7 +336,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
ratio--;
}
- if (ratio > PLLDIV_RATIO_MASK)
+ if (ratio > pll->div_ratio_mask)
return -EINVAL;
do {
@@ -344,7 +344,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
} while (v & PLLSTAT_GOSTAT);
v = __raw_readl(pll->base + clk->div_reg);
- v &= ~PLLDIV_RATIO_MASK;
+ v &= ~pll->div_ratio_mask;
v |= ratio | PLLDIV_EN;
__raw_writel(v, pll->base + clk->div_reg);
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 11099980b58b..0dd22031ec62 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -68,7 +68,7 @@
#ifndef __ASSEMBLER__
#include <linux/list.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#define PLLSTAT_GOSTAT BIT(0)
#define PLLCMD_GOSET BIT(0)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 63916b902760..78b5ae29ae40 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -830,8 +830,7 @@ static void da850_set_async3_src(int pllnum)
* According to the TRM, minimum PLLM results in maximum power savings.
* The OPP definitions below should keep the PLLM as low as possible.
*
- * The output of the PLLM must be between 400 to 600 MHz.
- * This rules out prediv of anything but divide-by-one for 24Mhz OSC input.
+ * The output of the PLLM must be between 300 to 600 MHz.
*/
struct da850_opp {
unsigned int freq; /* in KHz */
@@ -842,6 +841,33 @@ struct da850_opp {
unsigned int cvdd_max; /* in uV */
};
+static const struct da850_opp da850_opp_456 = {
+ .freq = 456000,
+ .prediv = 1,
+ .mult = 19,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_408 = {
+ .freq = 408000,
+ .prediv = 1,
+ .mult = 17,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_372 = {
+ .freq = 372000,
+ .prediv = 2,
+ .mult = 31,
+ .postdiv = 1,
+ .cvdd_min = 1200000,
+ .cvdd_max = 1320000,
+};
+
static const struct da850_opp da850_opp_300 = {
.freq = 300000,
.prediv = 1,
@@ -876,6 +902,9 @@ static const struct da850_opp da850_opp_96 = {
}
static struct cpufreq_frequency_table da850_freq_table[] = {
+ OPP(456),
+ OPP(408),
+ OPP(372),
OPP(300),
OPP(200),
OPP(96),
@@ -886,6 +915,19 @@ static struct cpufreq_frequency_table da850_freq_table[] = {
};
#ifdef CONFIG_REGULATOR
+static int da850_set_voltage(unsigned int index);
+static int da850_regulator_init(void);
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+ .freq_table = da850_freq_table,
+#ifdef CONFIG_REGULATOR
+ .init = da850_regulator_init,
+ .set_voltage = da850_set_voltage,
+#endif
+};
+
+#ifdef CONFIG_REGULATOR
static struct regulator *cvdd;
static int da850_set_voltage(unsigned int index)
@@ -895,7 +937,7 @@ static int da850_set_voltage(unsigned int index)
if (!cvdd)
return -ENODEV;
- opp = (struct da850_opp *) da850_freq_table[index].index;
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
}
@@ -912,14 +954,6 @@ static int da850_regulator_init(void)
}
#endif
-static struct davinci_cpufreq_config cpufreq_info = {
- .freq_table = &da850_freq_table[0],
-#ifdef CONFIG_REGULATOR
- .init = da850_regulator_init,
- .set_voltage = da850_set_voltage,
-#endif
-};
-
static struct platform_device da850_cpufreq_device = {
.name = "cpufreq-davinci",
.dev = {
@@ -928,12 +962,22 @@ static struct platform_device da850_cpufreq_device = {
.id = -1,
};
+unsigned int da850_max_speed = 300000;
+
int __init da850_register_cpufreq(char *async_clk)
{
+ int i;
+
/* cpufreq driver can help keep an "async" clock constant */
if (async_clk)
clk_add_alias("async", da850_cpufreq_device.name,
async_clk, NULL);
+ for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
+ if (da850_freq_table[i].frequency <= da850_max_speed) {
+ cpufreq_info.freq_table = &da850_freq_table[i];
+ break;
+ }
+ }
return platform_device_register(&da850_cpufreq_device);
}
@@ -942,17 +986,18 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
int i, ret = 0, diff;
unsigned int best = (unsigned int) -1;
+ struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
rate /= 1000; /* convert to kHz */
- for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
- diff = da850_freq_table[i].frequency - rate;
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ diff = table[i].frequency - rate;
if (diff < 0)
diff = -diff;
if (diff < best) {
best = diff;
- ret = da850_freq_table[i].frequency;
+ ret = table[i].frequency;
}
}
@@ -973,7 +1018,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
struct pll_data *pll = clk->pll_data;
int ret;
- opp = (struct da850_opp *) da850_freq_table[index].index;
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
prediv = opp->prediv;
mult = opp->mult;
postdiv = opp->postdiv;
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
index c9a86d8130d1..85503debda51 100644
--- a/arch/arm/mach-davinci/devices-tnetv107x.c
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -344,7 +344,20 @@ static struct platform_device tsc_device = {
void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
{
- int i;
+ int i, error;
+ struct clk *tsc_clk;
+
+ /*
+ * The reset defaults for tnetv107x tsc clock divider is set too high.
+ * This forces the clock down to a range that allows the ADC to
+ * complete sample conversion in time.
+ */
+ tsc_clk = clk_get(NULL, "sys_tsc_clk");
+ if (tsc_clk) {
+ error = clk_set_rate(tsc_clk, 5000000);
+ WARN_ON(error < 0);
+ clk_put(tsc_clk);
+ }
platform_device_register(&edma_device);
platform_device_register(&tnetv107x_wdt_device);
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 4247b3f53b33..e7f952066527 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -28,6 +28,13 @@ extern void __iomem *da8xx_syscfg0_base;
extern void __iomem *da8xx_syscfg1_base;
/*
+ * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade
+ * (than the regular 300Mhz variant), the board code should set this up
+ * with the supported speed before calling da850_register_cpufreq().
+ */
+extern unsigned int da850_max_speed;
+
+/*
* The cp_intc interrupt controller for the da8xx isn't in the same
* chunk of physical memory space as the other registers (like it is
* on the davincis) so it needs to be mapped separately. It will be
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
index 62b0a90309ad..d1b954955c12 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -22,8 +22,8 @@
#define __mem_isa(a) (a)
#ifndef __ASSEMBLER__
-#define __arch_ioremap(p, s, t) davinci_ioremap(p, s, t)
-#define __arch_iounmap(v) davinci_iounmap(v)
+#define __arch_ioremap davinci_ioremap
+#define __arch_iounmap davinci_iounmap
void __iomem *davinci_ioremap(unsigned long phys, size_t size,
unsigned int type);
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index 1b15dbd0a77b..a41580400701 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -83,21 +83,16 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
pdctl1 = __raw_readl(psc_base + PDCTL1);
pdctl1 |= 0x100;
__raw_writel(pdctl1, psc_base + PDCTL1);
-
- do {
- ptstat = __raw_readl(psc_base +
- PTSTAT);
- } while (!(((ptstat >> domain) & 1) == 0));
} else {
ptcmd = 1 << domain;
__raw_writel(ptcmd, psc_base + PTCMD);
-
- do {
- ptstat = __raw_readl(psc_base + PTSTAT);
- } while (!(((ptstat >> domain) & 1) == 0));
}
do {
+ ptstat = __raw_readl(psc_base + PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+
+ do {
mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 0f21c36e65dd..e1969ce904dc 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -272,15 +272,35 @@ static cycle_t read_cycles(struct clocksource *cs)
return (cycles_t)timer32_read(t);
}
+/*
+ * Kernel assumes that sched_clock can be called early but may not have
+ * things ready yet.
+ */
+static cycle_t read_dummy(struct clocksource *cs)
+{
+ return 0;
+}
+
+
static struct clocksource clocksource_davinci = {
.rating = 300,
- .read = read_cycles,
+ .read = read_dummy,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
/*
+ * Overwrite weak default sched_clock with something more precise
+ */
+unsigned long long notrace sched_clock(void)
+{
+ const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
+
+ return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
+ clocksource_davinci.shift);
+}
+
+/*
* clockevent
*/
static int davinci_set_next_event(unsigned long cycles,
@@ -377,11 +397,10 @@ static void __init davinci_timer_init(void)
davinci_clock_tick_rate = clk_get_rate(timer_clk);
/* setup clocksource */
+ clocksource_davinci.read = read_cycles;
clocksource_davinci.name = id_to_name[clocksource_id];
- clocksource_davinci.mult =
- clocksource_khz2mult(davinci_clock_tick_rate/1000,
- clocksource_davinci.shift);
- if (clocksource_register(&clocksource_davinci))
+ if (clocksource_register_hz(&clocksource_davinci,
+ davinci_clock_tick_rate))
printk(err, clocksource_davinci.name);
/* setup clockevent */
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
index daeae06430b9..6fcdecec8d8c 100644
--- a/arch/arm/mach-davinci/tnetv107x.c
+++ b/arch/arm/mach-davinci/tnetv107x.c
@@ -131,12 +131,13 @@ define_pll_clk(tdm, 1, 0x0ff, 0x200);
define_pll_clk(eth, 2, 0x0ff, 0x400);
/* Level 2 - divided outputs from the PLLs */
-#define define_pll_div_clk(pll, cname, div) \
- static struct clk pll##_##cname##_clk = { \
- .name = #pll "_" #cname "_clk",\
- .parent = &pll_##pll##_clk, \
- .flags = CLK_PLL, \
- .div_reg = PLLDIV##div, \
+#define define_pll_div_clk(pll, cname, div) \
+ static struct clk pll##_##cname##_clk = { \
+ .name = #pll "_" #cname "_clk", \
+ .parent = &pll_##pll##_clk, \
+ .flags = CLK_PLL, \
+ .div_reg = PLLDIV##div, \
+ .set_rate = davinci_set_sysclk_rate, \
}
define_pll_div_clk(sys, arm1176, 1);
@@ -192,6 +193,7 @@ lpsc_clk_enabled(system, sys_half_clk, SYSTEM);
lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST);
lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST);
lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM);
+lpsc_clk_enabled(timer1, sys_half_clk, TIMER1);
lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE);
lpsc_clk(ethss, eth_125mhz_clk, ETHSS);
@@ -205,16 +207,15 @@ lpsc_clk(mdio, sys_half_clk, MDIO);
lpsc_clk(sdio0, sys_half_clk, SDIO0);
lpsc_clk(sdio1, sys_half_clk, SDIO1);
lpsc_clk(timer0, sys_half_clk, TIMER0);
-lpsc_clk(timer1, sys_half_clk, TIMER1);
lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP);
lpsc_clk(ssp, sys_half_clk, SSP);
lpsc_clk(tdm0, tdm_0_clk, TDM0);
lpsc_clk(tdm1, tdm_1_clk, TDM1);
lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ);
lpsc_clk(mcdma, sys_half_clk, MCDMA);
-lpsc_clk(usb0, sys_half_clk, USB0);
-lpsc_clk(usb1, sys_half_clk, USB1);
lpsc_clk(usbss, sys_half_clk, USBSS);
+lpsc_clk(usb0, clk_usbss, USB0);
+lpsc_clk(usb1, clk_usbss, USB1);
lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII);
lpsc_clk(imcop, sys_dsp_clk, IMCOP);
lpsc_clk(spare, sys_half_clk, SPARE);
@@ -281,7 +282,9 @@ static struct clk_lookup clks[] = {
CLK(NULL, "clk_tdm0", &clk_tdm0),
CLK(NULL, "clk_vlynq", &clk_vlynq),
CLK(NULL, "clk_mcdma", &clk_mcdma),
+ CLK(NULL, "clk_usbss", &clk_usbss),
CLK(NULL, "clk_usb0", &clk_usb0),
+ CLK(NULL, "clk_usb1", &clk_usb1),
CLK(NULL, "clk_tdm1", &clk_tdm1),
CLK(NULL, "clk_debugss", &clk_debugss),
CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii),
@@ -289,8 +292,6 @@ static struct clk_lookup clks[] = {
CLK(NULL, "clk_imcop", &clk_imcop),
CLK(NULL, "clk_spare", &clk_spare),
CLK("davinci_mmc.1", NULL, &clk_sdio1),
- CLK(NULL, "clk_usb1", &clk_usb1),
- CLK(NULL, "clk_usbss", &clk_usbss),
CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
CLK(NULL, NULL, NULL),
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index 3b9a32ace909..a4ed3900912a 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -9,6 +9,12 @@ config MACH_DOVE_DB
Say 'Y' here if you want your kernel to support the
Marvell DB-MV88AP510 Development Board.
+ config MACH_CM_A510
+ bool "CompuLab CM-A510 Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ CompuLab CM-A510 Board.
+
endmenu
endif
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile
index 7ab3be53f642..fa0f01856060 100644
--- a/arch/arm/mach-dove/Makefile
+++ b/arch/arm/mach-dove/Makefile
@@ -1,3 +1,4 @@
-obj-y += common.o addr-map.o irq.o pcie.o
+obj-y += common.o addr-map.o irq.o pcie.o mpp.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
+obj-$(CONFIG_MACH_CM_A510) += cm-a510.o
diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c
new file mode 100644
index 000000000000..96e0e94e5fa9
--- /dev/null
+++ b/arch/arm/mach-dove/cm-a510.c
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/mach-dove/cm-a510.c
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Konstantin Sinyuk <kostyas@compulab.co.il>
+ *
+ * Based on Marvell DB-MV88AP510-BP Development 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/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dove.h>
+
+#include "common.h"
+
+static struct mv643xx_eth_platform_data cm_a510_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static struct mv_sata_platform_data cm_a510_sata_data = {
+ .n_ports = 1,
+};
+
+/*
+ * SPI Devices:
+ * SPI0: 1M Flash Winbond w25q32bv
+ */
+static const struct flash_platform_data cm_a510_spi_flash_data = {
+ .type = "w25q32bv",
+};
+
+static struct spi_board_info __initdata cm_a510_spi_flash_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &cm_a510_spi_flash_data,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static int __init cm_a510_pci_init(void)
+{
+ if (machine_is_cm_a510())
+ dove_pcie_init(1, 1);
+
+ return 0;
+}
+
+subsys_initcall(cm_a510_pci_init);
+
+/* Board Init */
+static void __init cm_a510_init(void)
+{
+ /*
+ * Basic Dove setup. Needs to be called early.
+ */
+ dove_init();
+
+ dove_ge00_init(&cm_a510_ge00_data);
+ dove_ehci0_init();
+ dove_ehci1_init();
+ dove_sata_init(&cm_a510_sata_data);
+ dove_sdio0_init();
+ dove_sdio1_init();
+ dove_spi0_init();
+ dove_spi1_init();
+ dove_uart0_init();
+ dove_uart1_init();
+ dove_i2c_init();
+ spi_register_board_info(cm_a510_spi_flash_info,
+ ARRAY_SIZE(cm_a510_spi_flash_info));
+}
+
+MACHINE_START(CM_A510, "Compulab CM-A510 Board")
+ .boot_params = 0x00000100,
+ .init_machine = cm_a510_init,
+ .map_io = dove_map_io,
+ .init_irq = dove_init_irq,
+ .timer = &dove_timer,
+MACHINE_END
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
index f6a08397f046..27b414578f2e 100644
--- a/arch/arm/mach-dove/include/mach/dove.h
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -131,14 +131,21 @@
#define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014)
#define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018)
#define DOVE_GPIO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_GPIO2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe8400)
#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
#define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1)
#define DOVE_NAND_GPIO_EN (1 << 0)
#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40)
-
+#define DOVE_SPI_GPIO_SEL (1 << 5)
+#define DOVE_UART1_GPIO_SEL (1 << 4)
+#define DOVE_AU1_GPIO_SEL (1 << 3)
+#define DOVE_CAM_GPIO_SEL (1 << 2)
+#define DOVE_SD1_GPIO_SEL (1 << 1)
+#define DOVE_SD0_GPIO_SEL (1 << 0)
/* Power Management */
#define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000)
+#define DOVE_PMU_SIG_CTRL (DOVE_PMU_VIRT_BASE + 0x802c)
/* Real Time Clock */
#define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500)
diff --git a/arch/arm/mach-dove/include/mach/gpio.h b/arch/arm/mach-dove/include/mach/gpio.h
index 0ee70ff39e11..340bb7af529d 100644
--- a/arch/arm/mach-dove/include/mach/gpio.h
+++ b/arch/arm/mach-dove/include/mach/gpio.h
@@ -14,12 +14,14 @@
#include <plat/gpio.h>
#include <asm-generic/gpio.h> /* cansleep wrappers */
-#define GPIO_MAX 64
+#define GPIO_MAX 72
#define GPIO_BASE_LO (DOVE_GPIO_VIRT_BASE + 0x00)
#define GPIO_BASE_HI (DOVE_GPIO_VIRT_BASE + 0x20)
-#define GPIO_BASE(pin) ((pin < 32) ? GPIO_BASE_LO : GPIO_BASE_HI)
+#define GPIO_BASE(pin) ((pin < 32) ? GPIO_BASE_LO : \
+ ((pin < 64) ? GPIO_BASE_HI : \
+ DOVE_GPIO2_VIRT_BASE))
#define GPIO_OUT(pin) (GPIO_BASE(pin) + 0x00)
#define GPIO_IO_CONF(pin) (GPIO_BASE(pin) + 0x04)
diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c
new file mode 100644
index 000000000000..71db2bdf2f28
--- /dev/null
+++ b/arch/arm/mach-dove/mpp.c
@@ -0,0 +1,212 @@
+/*
+ * arch/arm/mach-dove/mpp.c
+ *
+ * MPP functions for Marvell Dove 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/dove.h>
+
+#include "mpp.h"
+
+#define MPP_NR_REGS 4
+#define MPP_CTRL(i) ((i) == 3 ? \
+ DOVE_MPP_CTRL4_VIRT_BASE : \
+ DOVE_MPP_VIRT_BASE + (i) * 4)
+#define PMU_SIG_REGS 2
+#define PMU_SIG_CTRL(i) (DOVE_PMU_SIG_CTRL + (i) * 4)
+
+struct dove_mpp_grp {
+ int start;
+ int end;
+};
+
+static struct dove_mpp_grp dove_mpp_grp[] = {
+ [MPP_24_39] = {
+ .start = 24,
+ .end = 39,
+ },
+ [MPP_40_45] = {
+ .start = 40,
+ .end = 45,
+ },
+ [MPP_46_51] = {
+ .start = 40,
+ .end = 45,
+ },
+ [MPP_58_61] = {
+ .start = 58,
+ .end = 61,
+ },
+ [MPP_62_63] = {
+ .start = 62,
+ .end = 63,
+ },
+};
+
+static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
+{
+ int i;
+
+ for (i = start; i <= end; i++)
+ orion_gpio_set_valid(i, gpio_mode);
+}
+
+static void dove_mpp_dump_regs(void)
+{
+#ifdef DEBUG
+ int i;
+
+ pr_debug("MPP_CTRL regs:");
+ for (i = 0; i < MPP_NR_REGS; i++)
+ printk(" %08x", readl(MPP_CTRL(i)));
+ printk("\n");
+
+ pr_debug("PMU_SIG_CTRL regs:");
+ for (i = 0; i < PMU_SIG_REGS; i++)
+ printk(" %08x", readl(PMU_SIG_CTRL(i)));
+ printk("\n");
+
+ pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL));
+ pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
+#endif
+}
+
+static void dove_mpp_cfg_nfc(int sel)
+{
+ u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+
+ mpp_gen_cfg &= ~0x1;
+ mpp_gen_cfg |= sel;
+ writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
+
+ dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
+}
+
+static void dove_mpp_cfg_au1(int sel)
+{
+ u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
+ u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+ u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
+ ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
+ mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
+ global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
+
+ if (!sel || sel == 0x2)
+ dove_mpp_gpio_mode(52, 57, 0);
+ else
+ dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
+
+ if (sel & 0x1) {
+ global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
+ dove_mpp_gpio_mode(56, 57, 0);
+ }
+ if (sel & 0x2) {
+ mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
+ dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
+ }
+ if (sel & 0x4) {
+ ssp_ctrl1 |= DOVE_SSP_ON_AU1;
+ dove_mpp_gpio_mode(52, 55, 0);
+ }
+ if (sel & 0x8)
+ mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
+
+ writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
+ writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
+ writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
+ writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
+}
+
+static void dove_mpp_conf_grp(int num, int sel, u32 *mpp_ctrl)
+{
+ int start = dove_mpp_grp[num].start;
+ int end = dove_mpp_grp[num].end;
+ int gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
+
+ *mpp_ctrl &= ~(0x1 << num);
+ *mpp_ctrl |= sel << num;
+
+ dove_mpp_gpio_mode(start, end, gpio_mode);
+}
+
+void __init dove_mpp_conf(unsigned int *mpp_list)
+{
+ u32 mpp_ctrl[MPP_NR_REGS];
+ u32 pmu_mpp_ctrl = 0;
+ u32 pmu_sig_ctrl[PMU_SIG_REGS];
+ int i;
+
+ /* Initialize gpiolib. */
+ orion_gpio_init();
+
+ for (i = 0; i < MPP_NR_REGS; i++)
+ mpp_ctrl[i] = readl(MPP_CTRL(i));
+
+ for (i = 0; i < PMU_SIG_REGS; i++)
+ pmu_sig_ctrl[i] = readl(PMU_SIG_CTRL(i));
+
+ pmu_mpp_ctrl = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+
+ dove_mpp_dump_regs();
+
+ for ( ; *mpp_list != MPP_END; mpp_list++) {
+ unsigned int num = MPP_NUM(*mpp_list);
+ unsigned int sel = MPP_SEL(*mpp_list);
+ int shift, gpio_mode;
+
+ if (num > MPP_MAX) {
+ pr_err("dove: invalid MPP number (%u)\n", num);
+ continue;
+ }
+
+ if (*mpp_list & MPP_NFC_MASK) {
+ dove_mpp_cfg_nfc(sel);
+ continue;
+ }
+
+ if (*mpp_list & MPP_AU1_MASK) {
+ dove_mpp_cfg_au1(sel);
+ continue;
+ }
+
+ if (*mpp_list & MPP_GRP_MASK) {
+ dove_mpp_conf_grp(num, sel, &mpp_ctrl[3]);
+ continue;
+ }
+
+ shift = (num & 7) << 2;
+ if (*mpp_list & MPP_PMU_MASK) {
+ pmu_mpp_ctrl |= (0x1 << num);
+ pmu_sig_ctrl[num / 8] &= ~(0xf << shift);
+ pmu_sig_ctrl[num / 8] |= 0xf << shift;
+ gpio_mode = 0;
+ } else {
+ mpp_ctrl[num / 8] &= ~(0xf << shift);
+ mpp_ctrl[num / 8] |= sel << shift;
+ gpio_mode = GPIO_OUTPUT_OK | GPIO_INPUT_OK;
+ }
+
+ orion_gpio_set_valid(num, gpio_mode);
+ }
+
+ for (i = 0; i < MPP_NR_REGS; i++)
+ writel(mpp_ctrl[i], MPP_CTRL(i));
+
+ for (i = 0; i < PMU_SIG_REGS; i++)
+ writel(pmu_sig_ctrl[i], PMU_SIG_CTRL(i));
+
+ writel(pmu_mpp_ctrl, DOVE_PMU_MPP_GENERAL_CTRL);
+
+ dove_mpp_dump_regs();
+}
diff --git a/arch/arm/mach-dove/mpp.h b/arch/arm/mach-dove/mpp.h
new file mode 100644
index 000000000000..2a43ce413b15
--- /dev/null
+++ b/arch/arm/mach-dove/mpp.h
@@ -0,0 +1,220 @@
+#ifndef __ARCH_DOVE_MPP_CODED_H
+#define __ARCH_DOVE_MPP_CODED_H
+
+#define MPP(_num, _mode, _pmu, _grp, _au1, _nfc) ( \
+/* MPP/group number */ ((_num) & 0xff) | \
+/* MPP select value */ (((_mode) & 0xf) << 8) | \
+/* MPP PMU */ ((!!(_pmu)) << 12) | \
+/* group flag */ ((!!(_grp)) << 13) | \
+/* AU1 flag */ ((!!(_au1)) << 14) | \
+/* NFCE flag */ ((!!(_nfc)) << 15))
+
+#define MPP_MAX 71
+
+#define MPP_NUM(x) ((x) & 0xff)
+#define MPP_SEL(x) (((x) >> 8) & 0xf)
+
+#define MPP_PMU_MASK MPP(0, 0x0, 1, 0, 0, 0)
+#define MPP_GRP_MASK MPP(0, 0x0, 0, 1, 0, 0)
+#define MPP_AU1_MASK MPP(0, 0x0, 0, 0, 1, 0)
+#define MPP_NFC_MASK MPP(0, 0x0, 0, 0, 0, 1)
+
+#define MPP_END MPP(0xff, 0xf, 1, 1, 1, 1)
+
+#define MPP_PMU_DRIVE_0 0x1
+#define MPP_PMU_DRIVE_1 0x2
+#define MPP_PMU_SDI 0x3
+#define MPP_PMU_CPU_PWRDWN 0x4
+#define MPP_PMU_STBY_PWRDWN 0x5
+#define MPP_PMU_CORE_PWR_GOOD 0x8
+#define MPP_PMU_BAT_FAULT 0xa
+#define MPP_PMU_EXT0_WU 0xb
+#define MPP_PMU_EXT1_WU 0xc
+#define MPP_PMU_EXT2_WU 0xd
+#define MPP_PMU_BLINK 0xe
+#define MPP_PMU(_num, _mode) MPP((_num), MPP_PMU_##_mode, 1, 0, 0, 0)
+
+#define MPP_PIN(_num, _mode) MPP((_num), (_mode), 0, 0, 0, 0)
+#define MPP_GRP(_grp, _mode) MPP((_grp), (_mode), 0, 1, 0, 0)
+#define MPP_GRP_AU1(_mode) MPP(0, (_mode), 0, 0, 1, 0)
+#define MPP_GRP_NFC(_mode) MPP(0, (_mode), 0, 0, 0, 1)
+
+#define MPP0_GPIO0 MPP_PIN(0, 0x0)
+#define MPP0_UA2_RTSn MPP_PIN(0, 0x2)
+#define MPP0_SDIO0_CD MPP_PIN(0, 0x3)
+#define MPP0_LCD0_PWM MPP_PIN(0, 0xf)
+
+#define MPP1_GPIO1 MPP_PIN(1, 0x0)
+#define MPP1_UA2_CTSn MPP_PIN(1, 0x2)
+#define MPP1_SDIO0_WP MPP_PIN(1, 0x3)
+#define MPP1_LCD1_PWM MPP_PIN(1, 0xf)
+
+#define MPP2_GPIO2 MPP_PIN(2, 0x0)
+#define MPP2_SATA_PRESENT MPP_PIN(2, 0x1)
+#define MPP2_UA2_TXD MPP_PIN(2, 0x2)
+#define MPP2_SDIO0_BUS_POWER MPP_PIN(2, 0x3)
+#define MPP2_UA_RTSn1 MPP_PIN(2, 0x4)
+
+#define MPP3_GPIO3 MPP_PIN(3, 0x0)
+#define MPP3_SATA_ACT MPP_PIN(3, 0x1)
+#define MPP3_UA2_RXD MPP_PIN(3, 0x2)
+#define MPP3_SDIO0_LED_CTRL MPP_PIN(3, 0x3)
+#define MPP3_UA_CTSn1 MPP_PIN(3, 0x4)
+#define MPP3_SPI_LCD_CS1 MPP_PIN(3, 0xf)
+
+#define MPP4_GPIO4 MPP_PIN(4, 0x0)
+#define MPP4_UA3_RTSn MPP_PIN(4, 0x2)
+#define MPP4_SDIO1_CD MPP_PIN(4, 0x3)
+#define MPP4_SPI_1_MISO MPP_PIN(4, 0x4)
+
+#define MPP5_GPIO5 MPP_PIN(5, 0x0)
+#define MPP5_UA3_CTSn MPP_PIN(5, 0x2)
+#define MPP5_SDIO1_WP MPP_PIN(5, 0x3)
+#define MPP5_SPI_1_CS MPP_PIN(5, 0x4)
+
+#define MPP6_GPIO6 MPP_PIN(6, 0x0)
+#define MPP6_UA3_TXD MPP_PIN(6, 0x2)
+#define MPP6_SDIO1_BUS_POWER MPP_PIN(6, 0x3)
+#define MPP6_SPI_1_MOSI MPP_PIN(6, 0x4)
+
+#define MPP7_GPIO7 MPP_PIN(7, 0x0)
+#define MPP7_UA3_RXD MPP_PIN(7, 0x2)
+#define MPP7_SDIO1_LED_CTRL MPP_PIN(7, 0x3)
+#define MPP7_SPI_1_SCK MPP_PIN(7, 0x4)
+
+#define MPP8_GPIO8 MPP_PIN(8, 0x0)
+#define MPP8_WD_RST_OUT MPP_PIN(8, 0x1)
+
+#define MPP9_GPIO9 MPP_PIN(9, 0x0)
+#define MPP9_PEX1_CLKREQn MPP_PIN(9, 0x5)
+
+#define MPP10_GPIO10 MPP_PIN(10, 0x0)
+#define MPP10_SSP_SCLK MPP_PIN(10, 0x5)
+
+#define MPP11_GPIO11 MPP_PIN(11, 0x0)
+#define MPP11_SATA_PRESENT MPP_PIN(11, 0x1)
+#define MPP11_SATA_ACT MPP_PIN(11, 0x2)
+#define MPP11_SDIO0_LED_CTRL MPP_PIN(11, 0x3)
+#define MPP11_SDIO1_LED_CTRL MPP_PIN(11, 0x4)
+#define MPP11_PEX0_CLKREQn MPP_PIN(11, 0x5)
+
+#define MPP12_GPIO12 MPP_PIN(12, 0x0)
+#define MPP12_SATA_ACT MPP_PIN(12, 0x1)
+#define MPP12_UA2_RTSn MPP_PIN(12, 0x2)
+#define MPP12_AD0_I2S_EXT_MCLK MPP_PIN(12, 0x3)
+#define MPP12_SDIO1_CD MPP_PIN(12, 0x4)
+
+#define MPP13_GPIO13 MPP_PIN(13, 0x0)
+#define MPP13_UA2_CTSn MPP_PIN(13, 0x2)
+#define MPP13_AD1_I2S_EXT_MCLK MPP_PIN(13, 0x3)
+#define MPP13_SDIO1WP MPP_PIN(13, 0x4)
+#define MPP13_SSP_EXTCLK MPP_PIN(13, 0x5)
+
+#define MPP14_GPIO14 MPP_PIN(14, 0x0)
+#define MPP14_UA2_TXD MPP_PIN(14, 0x2)
+#define MPP14_SDIO1_BUS_POWER MPP_PIN(14, 0x4)
+#define MPP14_SSP_RXD MPP_PIN(14, 0x5)
+
+#define MPP15_GPIO15 MPP_PIN(15, 0x0)
+#define MPP15_UA2_RXD MPP_PIN(15, 0x2)
+#define MPP15_SDIO1_LED_CTRL MPP_PIN(15, 0x4)
+#define MPP15_SSP_SFRM MPP_PIN(15, 0x5)
+
+#define MPP16_GPIO16 MPP_PIN(16, 0x0)
+#define MPP16_UA3_RTSn MPP_PIN(16, 0x2)
+#define MPP16_SDIO0_CD MPP_PIN(16, 0x3)
+#define MPP16_SPI_LCD_CS1 MPP_PIN(16, 0x4)
+#define MPP16_AC97_SDATA_IN1 MPP_PIN(16, 0x5)
+
+#define MPP17_GPIO17 MPP_PIN(17, 0x0)
+#define MPP17_AC97_SYSCLK_OUT MPP_PIN(17, 0x1)
+#define MPP17_UA3_CTSn MPP_PIN(17, 0x2)
+#define MPP17_SDIO0_WP MPP_PIN(17, 0x3)
+#define MPP17_TW_SDA2 MPP_PIN(17, 0x4)
+#define MPP17_AC97_SDATA_IN2 MPP_PIN(17, 0x5)
+
+#define MPP18_GPIO18 MPP_PIN(18, 0x0)
+#define MPP18_UA3_TXD MPP_PIN(18, 0x2)
+#define MPP18_SDIO0_BUS_POWER MPP_PIN(18, 0x3)
+#define MPP18_LCD0_PWM MPP_PIN(18, 0x4)
+#define MPP18_AC_SDATA_IN3 MPP_PIN(18, 0x5)
+
+#define MPP19_GPIO19 MPP_PIN(19, 0x0)
+#define MPP19_UA3_RXD MPP_PIN(19, 0x2)
+#define MPP19_SDIO0_LED_CTRL MPP_PIN(19, 0x3)
+#define MPP19_TW_SCK2 MPP_PIN(19, 0x4)
+
+#define MPP20_GPIO20 MPP_PIN(20, 0x0)
+#define MPP20_AC97_SYSCLK_OUT MPP_PIN(20, 0x1)
+#define MPP20_SPI_LCD_MISO MPP_PIN(20, 0x2)
+#define MPP20_SDIO1_CD MPP_PIN(20, 0x3)
+#define MPP20_SDIO0_CD MPP_PIN(20, 0x5)
+#define MPP20_SPI_1_MISO MPP_PIN(20, 0x6)
+
+#define MPP21_GPIO21 MPP_PIN(21, 0x0)
+#define MPP21_UA1_RTSn MPP_PIN(21, 0x1)
+#define MPP21_SPI_LCD_CS0 MPP_PIN(21, 0x2)
+#define MPP21_SDIO1_WP MPP_PIN(21, 0x3)
+#define MPP21_SSP_SFRM MPP_PIN(21, 0x4)
+#define MPP21_SDIO0_WP MPP_PIN(21, 0x5)
+#define MPP21_SPI_1_CS MPP_PIN(21, 0x6)
+
+#define MPP22_GPIO22 MPP_PIN(22, 0x0)
+#define MPP22_UA1_CTSn MPP_PIN(22, 0x1)
+#define MPP22_SPI_LCD_MOSI MPP_PIN(22, 0x2)
+#define MPP22_SDIO1_BUS_POWER MPP_PIN(22, 0x3)
+#define MPP22_SSP_TXD MPP_PIN(22, 0x4)
+#define MPP22_SDIO0_BUS_POWER MPP_PIN(22, 0x5)
+#define MPP22_SPI_1_MOSI MPP_PIN(22, 0x6)
+
+#define MPP23_GPIO23 MPP_PIN(23, 0x0)
+#define MPP23_SPI_LCD_SCK MPP_PIN(23, 0x2)
+#define MPP23_SDIO1_LED_CTRL MPP_PIN(23, 0x3)
+#define MPP23_SSP_SCLK MPP_PIN(23, 0x4)
+#define MPP23_SDIO0_LED_CTRL MPP_PIN(23, 0x5)
+#define MPP23_SPI_1_SCK MPP_PIN(23, 0x6)
+
+/* for MPP groups _num is a group index */
+enum dove_mpp_grp_idx {
+ MPP_24_39 = 2,
+ MPP_40_45 = 0,
+ MPP_46_51 = 1,
+ MPP_58_61 = 5,
+ MPP_62_63 = 4,
+};
+
+#define MPP24_39_GPIO MPP_GRP(MPP_24_39, 0x1)
+#define MPP24_39_CAM MPP_GRP(MPP_24_39, 0x0)
+
+#define MPP40_45_GPIO MPP_GRP(MPP_40_45, 0x1)
+#define MPP40_45_SD0 MPP_GRP(MPP_40_45, 0x0)
+
+#define MPP46_51_GPIO MPP_GRP(MPP_46_51, 0x1)
+#define MPP46_51_SD1 MPP_GRP(MPP_46_51, 0x0)
+
+#define MPP58_61_GPIO MPP_GRP(MPP_58_61, 0x1)
+#define MPP58_61_SPI MPP_GRP(MPP_58_61, 0x0)
+
+#define MPP62_63_GPIO MPP_GRP(MPP_62_63, 0x1)
+#define MPP62_63_UA1 MPP_GRP(MPP_62_63, 0x0)
+
+/* The MPP[64:71] control differs from other groups */
+#define MPP64_71_GPO MPP_GRP_NFC(0x1)
+#define MPP64_71_NFC MPP_GRP_NFC(0x0)
+
+/*
+ * The MPP[52:57] functionality is encoded by 4 bits in different
+ * registers. The _num field in this case encodes those bits in
+ * correspodence with Table 135 of 88AP510 Functional specification
+ */
+#define MPP52_57_AU1 MPP_GRP_AU1(0x0)
+#define MPP52_57_AU1_GPIO57 MPP_GRP_AU1(0x2)
+#define MPP52_57_GPIO MPP_GRP_AU1(0xa)
+#define MPP52_57_TW_GPIO MPP_GRP_AU1(0xb)
+#define MPP52_57_AU1_SSP MPP_GRP_AU1(0xc)
+#define MPP52_57_SSP_GPIO MPP_GRP_AU1(0xe)
+#define MPP52_57_SSP_TW MPP_GRP_AU1(0xf)
+
+void dove_mpp_conf(unsigned int *mpp_list);
+
+#endif /* __ARCH_DOVE_MPP_CODED_H */
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index ef06c66a6f16..ca4de7105097 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -19,10 +19,10 @@
#include <linux/string.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <linux/clkdev.h>
#include <mach/hardware.h>
-#include <asm/clkdev.h>
#include <asm/div64.h>
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 197f9e241cff..17d2e608a214 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,13 +1,37 @@
config IMX_HAVE_DMA_V1
bool
-if ARCH_MX1
-
config SOC_IMX1
+ bool
select CPU_ARM920T
select IMX_HAVE_DMA_V1
select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+config SOC_IMX21
+ bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+config SOC_IMX25
bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_MXC_IOMUX_V3
+ select MXC_AVIC
+
+config SOC_IMX27
+ bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+if ARCH_MX1
comment "MX1 platforms:"
config MACH_MXLADS
@@ -31,33 +55,17 @@ endif
if ARCH_MX2
-config SOC_IMX21
- select CPU_ARM926T
- select ARCH_MXC_AUDMUX_V1
- select IMX_HAVE_DMA_V1
- select IMX_HAVE_IOMUX_V1
- bool
-
-config SOC_IMX27
- select CPU_ARM926T
- select ARCH_MXC_AUDMUX_V1
- select IMX_HAVE_DMA_V1
- select IMX_HAVE_IOMUX_V1
- bool
-
choice
prompt "CPUs:"
default MACH_MX21
config MACH_MX21
bool "i.MX21 support"
- select SOC_IMX21
help
This enables support for Freescale's MX2 based i.MX21 processor.
config MACH_MX27
bool "i.MX27 support"
- select SOC_IMX27
help
This enables support for Freescale's MX2 based i.MX27 processor.
@@ -71,7 +79,10 @@ comment "MX21 platforms:"
config MACH_MX21ADS
bool "MX21ADS platform"
+ select SOC_IMX21
+ select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for MX21ADS platform. This includes specific
@@ -79,24 +90,79 @@ config MACH_MX21ADS
endif
+if ARCH_MX25
+
+comment "MX25 platforms:"
+
+config MACH_MX25_3DS
+ bool "Support MX25PDK (3DS) Platform"
+ select SOC_IMX25
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMXDI_RTC
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+
+config MACH_EUKREA_CPUIMX25
+ bool "Support Eukrea CPUIMX25 Platform"
+ select SOC_IMX25
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMXDI_RTC
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_ULPI if USB_ULPI
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX25
+ default MACH_EUKREA_MBIMXSD25_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD25_BASEBOARD
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+endif
+
if MACH_MX27
comment "MX27 platforms:"
config MACH_MX27ADS
bool "MX27ADS platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
help
Include support for MX27ADS platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCM038
bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
@@ -109,8 +175,9 @@ choice
default MACH_PCM970_BASEBOARD
config MACH_PCM970_BASEBOARD
- prompt "PHYTEC PCM970 development board"
- bool
+ bool "PHYTEC PCM970 development board"
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_MXC_MMC
help
This adds board specific devices that can be found on Phytec's
PCM970 evaluation board.
@@ -119,9 +186,14 @@ endchoice
config MACH_CPUIMX27
bool "Eukrea CPUIMX27 module"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
select MXC_ULPI if USB_ULPI
help
Include support for Eukrea CPUIMX27 platform. This includes
@@ -130,6 +202,7 @@ config MACH_CPUIMX27
config MACH_EUKREA_CPUIMX27_USESDHC2
bool "CPUIMX27 integrates SDHC2 module"
depends on MACH_CPUIMX27
+ select IMX_HAVE_PLATFORM_MXC_MMC
help
This adds support for the internal SDHC2 used on CPUIMX27
for wifi or eMMC.
@@ -148,8 +221,11 @@ choice
config MACH_EUKREA_MBIMX27_BASEBOARD
bool "Eukrea MBIMX27 development board"
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_SPI_IMX
help
This adds board specific devices that can be found on Eukrea's
@@ -159,15 +235,26 @@ endchoice
config MACH_MX27_3DS
bool "MX27PDK platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
help
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
config MACH_IMX27_VISSTRIM_M10
bool "Vista Silicon i.MX27 Visstrim_m10"
+ select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
help
Include support for Visstrim_m10 platform and its different variants.
This includes specific configurations for the board and its
@@ -175,6 +262,7 @@ config MACH_IMX27_VISSTRIM_M10
config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
+ select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for MX27 LITEKIT platform. This includes specific
@@ -182,10 +270,17 @@ config MACH_IMX27LITE
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
@@ -194,8 +289,11 @@ config MACH_PCA100
config MACH_MXT_TD60
bool "Maxtrack i-MXT TD60"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for i-MXT (aka td60) platform. This
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 5582692bb176..77100bf26153 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -4,13 +4,13 @@
# Object file lists.
-obj-y := devices.o
-
obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
+obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o
+
obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
@@ -22,6 +22,10 @@ obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
+obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
+
obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 7988a85cf07d..3953d60bff0b 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -6,6 +6,10 @@ zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
+zreladdr-$(CONFIG_ARCH_MX25) := 0x80008000
+params_phys-$(CONFIG_ARCH_MX25) := 0x80000100
+initrd_phys-$(CONFIG_ARCH_MX25) := 0x80800000
+
zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
index daca30b2d5b1..3938a563b280 100644
--- a/arch/arm/mach-imx/clock-imx1.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -22,8 +22,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
index cf15ea516a72..bf30a8c7ce6f 100644
--- a/arch/arm/mach-imx/clock-imx21.c
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -21,11 +21,11 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
-#include <asm/clkdev.h>
#include <asm/div64.h>
#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
@@ -1185,7 +1185,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "brom", brom_clk)
_REGISTER_CLOCK(NULL, "emma", emma_clk[0])
_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
- _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-imx/clock-imx25.c
index 9e4a5578c2fb..daa0165b6772 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -21,8 +21,7 @@
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
@@ -296,7 +295,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
- _REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 98a25bada783..583f2515c1d5 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -21,8 +21,8 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/div64.h>
#include <mach/clock.h>
@@ -125,7 +125,7 @@ static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
if (clk->parent == parent)
return 0;
- if (mx27_revision() >= CHIP_REV_2_0) {
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
if (parent == &mpll_main1_clk) {
cscr |= CCM_CSCR_ARM_SRC;
} else {
@@ -174,7 +174,7 @@ static int set_rate_cpu(struct clk *clk, unsigned long rate)
div--;
reg = __raw_readl(CCM_CSCR);
- if (mx27_revision() >= CHIP_REV_2_0) {
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
reg &= ~(3 << 12);
reg |= div << 12;
reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
@@ -244,7 +244,7 @@ static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
parent_rate = clk_get_rate(clk->parent);
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
pdf += 4; /* MX27 TO2+ */
else
pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
@@ -269,7 +269,7 @@ static unsigned long get_rate_nfc(struct clk *clk)
parent_rate = clk_get_rate(clk->parent);
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
else
nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
@@ -284,7 +284,7 @@ static unsigned long get_rate_vpu(struct clk *clk)
parent_rate = clk_get_rate(clk->parent);
- if (mx27_revision() >= CHIP_REV_2_0) {
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
vpu_pdf += 4;
} else {
@@ -347,7 +347,7 @@ static unsigned long get_rate_mpll_main(struct clk *clk)
* clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
* clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
*/
- if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1)
return 2UL * parent_rate / 3UL;
return parent_rate;
@@ -365,7 +365,7 @@ static unsigned long get_rate_spll(struct clk *clk)
/* On TO2 we have to write the value back. Otherwise we
* read 0 from this register the next time.
*/
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
__raw_writel(reg, CCM_SPCTL0);
return mxc_decode_pll(reg, rate);
@@ -376,7 +376,7 @@ static unsigned long get_rate_cpu(struct clk *clk)
u32 div;
unsigned long rate;
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
else
div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
@@ -389,7 +389,7 @@ static unsigned long get_rate_ahb(struct clk *clk)
{
unsigned long rate, bclk_pdf;
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
else
bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
@@ -402,7 +402,7 @@ static unsigned long get_rate_ipg(struct clk *clk)
{
unsigned long rate, ipg_pdf;
- if (mx27_revision() >= CHIP_REV_2_0)
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
return clk_get_rate(clk->parent);
else
ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
@@ -667,7 +667,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
_REGISTER_CLOCK(NULL, "ata", ata_clk)
_REGISTER_CLOCK(NULL, "mstick", mstick_clk)
- _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
@@ -683,7 +683,7 @@ static void __init to2_adjust_clocks(void)
{
unsigned long cscr = __raw_readl(CCM_CSCR);
- if (mx27_revision() >= CHIP_REV_2_0) {
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
if (cscr & CCM_CSCR_ARM_SRC)
cpu_clk.parent = &mpll_main1_clk;
diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
index d8d3b2d84dc5..3b117be37bd2 100644
--- a/arch/arm/mach-imx/cpu-imx27.c
+++ b/arch/arm/mach-imx/cpu-imx27.c
@@ -42,7 +42,19 @@ static void query_silicon_parameter(void)
val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR
+ SYS_CHIP_ID));
- cpu_silicon_rev = (int)(val >> 28);
+ switch (val >> 28) {
+ case 0:
+ cpu_silicon_rev = IMX_CHIP_REVISION_1_0;
+ break;
+ case 1:
+ cpu_silicon_rev = IMX_CHIP_REVISION_2_0;
+ break;
+ case 2:
+ cpu_silicon_rev = IMX_CHIP_REVISION_2_1;
+ break;
+ default:
+ cpu_silicon_rev = IMX_CHIP_REVISION_UNKNOWN;
+ }
cpu_partnumber = (int)((val >> 12) & 0xFFFF);
}
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
index d189039749b0..16744d2d9b81 100644
--- a/arch/arm/mach-imx/devices-imx21.h
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -9,10 +9,26 @@
#include <mach/mx21.h>
#include <mach/devices-common.h>
+extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data __initconst;
+#define imx21_add_imx21_hcd(pdata) \
+ imx_add_imx21_hcd(&imx21_imx21_hcd_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst;
+#define imx21_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx21_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx21_imx_fb_data __initconst;
+#define imx21_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx21_imx_fb_data, pdata)
+
extern const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst;
#define imx21_add_imx_i2c(pdata) \
imx_add_imx_i2c(&imx21_imx_i2c_data, pdata)
+extern const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst;
+#define imx21_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx21_imx_keypad_data, pdata)
+
extern const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst;
#define imx21_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata)
@@ -25,10 +41,18 @@ extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst;
#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata)
#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata)
+extern const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst;
+#define imx21_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx21_mxc_mmc_data[id], pdata)
+
extern const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst;
#define imx21_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx21_mxc_nand_data, pdata)
+extern const struct imx_mxc_w1_data imx21_mxc_w1_data __initconst;
+#define imx21_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx21_mxc_w1_data)
+
extern const struct imx_spi_imx_data imx21_cspi_data[] __initconst;
#define imx21_add_cspi(id, pdata) \
imx_add_spi_imx(&imx21_cspi_data[id], pdata)
diff --git a/arch/arm/mach-mx25/devices-imx25.h b/arch/arm/mach-imx/devices-imx25.h
index d94d282fa676..bde33caf1b90 100644
--- a/arch/arm/mach-mx25/devices-imx25.h
+++ b/arch/arm/mach-imx/devices-imx25.h
@@ -13,10 +13,27 @@ extern const struct imx_fec_data imx25_fec_data __initconst;
#define imx25_add_fec(pdata) \
imx_add_fec(&imx25_fec_data, pdata)
-#define imx25_add_flexcan0(pdata) \
- imx_add_flexcan(0, MX25_CAN1_BASE_ADDR, SZ_16K, MX25_INT_CAN1, pdata)
-#define imx25_add_flexcan1(pdata) \
- imx_add_flexcan(1, MX25_CAN2_BASE_ADDR, SZ_16K, MX25_INT_CAN2, pdata)
+extern const struct imx_flexcan_data imx25_flexcan_data[] __initconst;
+#define imx25_add_flexcan(id, pdata) \
+ imx_add_flexcan(&imx25_flexcan_data[id], pdata)
+#define imx25_add_flexcan0(pdata) imx25_add_flexcan(0, pdata)
+#define imx25_add_flexcan1(pdata) imx25_add_flexcan(1, pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst;
+#define imx25_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx25_fsl_usb2_udc_data, pdata)
+
+extern struct imx_imxdi_rtc_data imx25_imxdi_rtc_data __initconst;
+#define imx25_add_imxdi_rtc(pdata) \
+ imx_add_imxdi_rtc(&imx25_imxdi_rtc_data)
+
+extern const struct imx_imx2_wdt_data imx25_imx2_wdt_data __initconst;
+#define imx25_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx25_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx25_imx_fb_data __initconst;
+#define imx25_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx25_imx_fb_data, pdata)
extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst;
#define imx25_add_imx_i2c(id, pdata) \
@@ -25,6 +42,10 @@ extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst;
#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata)
#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata)
+extern const struct imx_imx_keypad_data imx25_imx_keypad_data __initconst;
+#define imx25_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx25_imx_keypad_data, pdata)
+
extern const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst;
#define imx25_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
@@ -38,17 +59,29 @@ extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst;
#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata)
#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata)
+extern const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst;
+#define imx25_add_mx2_camera(pdata) \
+ imx_add_mx2_camera(&imx25_mx2_camera_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst;
+#define imx25_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx25_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data __initconst;
+#define imx25_add_mxc_ehci_hs(pdata) \
+ imx_add_mxc_ehci(&imx25_mxc_ehci_hs_data, pdata)
+
extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst;
#define imx25_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
+extern const struct imx_sdhci_esdhc_imx_data
+imx25_sdhci_esdhc_imx_data[] __initconst;
+#define imx25_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx25_sdhci_esdhc_imx_data[id], pdata)
+
extern const struct imx_spi_imx_data imx25_cspi_data[] __initconst;
#define imx25_add_spi_imx(id, pdata) \
- imx_add_spi_imx(&imx25_cspi_data[id], pdata)
+ imx_add_spi_imx(&imx25_spi_imx_data[id], pdata)
#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
-
-extern const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst;
-#define imx25_add_esdhc(id, pdata) \
- imx_add_esdhc(&imx25_esdhc_data[id], pdata)
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
index 7011690364f2..f1272d4b5a33 100644
--- a/arch/arm/mach-imx/devices-imx27.h
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -13,10 +13,26 @@ extern const struct imx_fec_data imx27_fec_data __initconst;
#define imx27_add_fec(pdata) \
imx_add_fec(&imx27_fec_data, pdata)
+extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst;
+#define imx27_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx27_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst;
+#define imx27_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx27_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx27_imx_fb_data __initconst;
+#define imx27_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx27_imx_fb_data, pdata)
+
extern const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst;
#define imx27_add_imx_i2c(id, pdata) \
imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata)
+extern const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst;
+#define imx27_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx27_imx_keypad_data, pdata)
+
extern const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst;
#define imx27_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata)
@@ -31,10 +47,29 @@ extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst;
#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata)
#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata)
+extern const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst;
+#define imx27_add_mx2_camera(pdata) \
+ imx_add_mx2_camera(&imx27_mx2_camera_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst;
+#define imx27_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx27_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[] __initconst;
+#define imx27_add_mxc_ehci_hs(id, pdata) \
+ imx_add_mxc_ehci(&imx27_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst;
+#define imx27_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx27_mxc_mmc_data[id], pdata)
+
extern const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst;
#define imx27_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx27_mxc_nand_data, pdata)
+extern const struct imx_mxc_w1_data imx27_mxc_w1_data __initconst;
+#define imx27_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx27_mxc_w1_data)
+
extern const struct imx_spi_imx_data imx27_cspi_data[] __initconst;
#define imx27_add_cspi(id, pdata) \
imx_add_spi_imx(&imx27_cspi_data[id], pdata)
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
deleted file mode 100644
index fba5047de8b1..000000000000
--- a/arch/arm/mach-imx/devices.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Author: MontaVista Software, Inc.
- * <source@mvista.com>
- *
- * Based on the OMAP devices.c
- *
- * 2005 (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.
- *
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
- * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- * Copyright (c) 2008 Darius Augulis <darius.augulis@teltonika.lt>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/dma-mapping.h>
-#include <linux/serial.h>
-
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/mmc.h>
-
-#include "devices.h"
-
-#if defined(CONFIG_ARCH_MX1)
-static struct resource imx1_camera_resources[] = {
- {
- .start = 0x00224000,
- .end = 0x00224010,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX1_CSI_INT,
- .end = MX1_CSI_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 imx1_camera_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device imx1_camera_device = {
- .name = "mx1-camera",
- .id = 0, /* This is used to put cameras on this interface */
- .dev = {
- .dma_mask = &imx1_camera_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = imx1_camera_resources,
- .num_resources = ARRAY_SIZE(imx1_camera_resources),
-};
-
-static struct resource imx_rtc_resources[] = {
- {
- .start = 0x00204000,
- .end = 0x00204024,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX1_RTC_INT,
- .end = MX1_RTC_INT,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_RTC_SAMINT,
- .end = MX1_RTC_SAMINT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_rtc_device = {
- .name = "rtc-imx",
- .id = 0,
- .resource = imx_rtc_resources,
- .num_resources = ARRAY_SIZE(imx_rtc_resources),
-};
-
-static struct resource imx_wdt_resources[] = {
- {
- .start = 0x00201000,
- .end = 0x00201008,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX1_WDT_INT,
- .end = MX1_WDT_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_wdt_device = {
- .name = "imx-wdt",
- .id = 0,
- .resource = imx_wdt_resources,
- .num_resources = ARRAY_SIZE(imx_wdt_resources),
-};
-
-static struct resource imx_usb_resources[] = {
- {
- .start = 0x00212000,
- .end = 0x00212148,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX1_USBD_INT0,
- .end = MX1_USBD_INT0,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT1,
- .end = MX1_USBD_INT1,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT2,
- .end = MX1_USBD_INT2,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT3,
- .end = MX1_USBD_INT3,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT4,
- .end = MX1_USBD_INT4,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT5,
- .end = MX1_USBD_INT5,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = MX1_USBD_INT6,
- .end = MX1_USBD_INT6,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_usb_device = {
- .name = "imx_udc",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_usb_resources),
- .resource = imx_usb_resources,
-};
-
-/* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
- {
- .chip.label = "gpio-0",
- .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
- .irq = MX1_GPIO_INT_PORTA,
- .virtual_irq_start = MXC_GPIO_IRQ_START,
- }, {
- .chip.label = "gpio-1",
- .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x100),
- .irq = MX1_GPIO_INT_PORTB,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
- }, {
- .chip.label = "gpio-2",
- .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x200),
- .irq = MX1_GPIO_INT_PORTC,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
- }, {
- .chip.label = "gpio-3",
- .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x300),
- .irq = MX1_GPIO_INT_PORTD,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
- }
-};
-
-int __init imx1_register_gpios(void)
-{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
-}
-#endif
-
-#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
-
-#ifdef CONFIG_MACH_MX27
-static struct resource mx27_camera_resources[] = {
- {
- .start = MX27_CSI_BASE_ADDR,
- .end = MX27_CSI_BASE_ADDR + 0x1f,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_EMMA_PRP_BASE_ADDR,
- .end = MX27_EMMA_PRP_BASE_ADDR + 0x1f,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_CSI,
- .end = MX27_INT_CSI,
- .flags = IORESOURCE_IRQ,
- },{
- .start = MX27_INT_EMMAPRP,
- .end = MX27_INT_EMMAPRP,
- .flags = IORESOURCE_IRQ,
- },
-};
-struct platform_device mx27_camera_device = {
- .name = "mx2-camera",
- .id = 0,
- .num_resources = ARRAY_SIZE(mx27_camera_resources),
- .resource = mx27_camera_resources,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- },
-};
-#endif
-
-/*
- * General Purpose Timer
- * - i.MX21: 3 timers
- * - i.MX27: 6 timers
- */
-#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, \
- }
-
-/* 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
-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
-
-/* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */
-static struct resource mxc_wdt_resources[] = {
- {
- .start = MX2x_WDOG_BASE_ADDR,
- .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device mxc_wdt = {
- .name = "imx2-wdt",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_wdt_resources),
- .resource = mxc_wdt_resources,
-};
-
-static struct resource mxc_w1_master_resources[] = {
- {
- .start = MX2x_OWIRE_BASE_ADDR,
- .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device mxc_w1_master_device = {
- .name = "mxc_w1",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
- .resource = mxc_w1_master_resources,
-};
-
-/*
- * lcdc:
- * - i.MX1: the basic controller
- * - i.MX21: to be checked
- * - i.MX27: like i.MX1, with slightly variations
- */
-static struct resource mxc_fb[] = {
- {
- .start = MX2x_LCDC_BASE_ADDR,
- .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_LCDC,
- .end = MX2x_INT_LCDC,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-/* mxc lcd driver */
-struct platform_device mxc_fb_device = {
- .name = "imx-fb",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_fb),
- .resource = mxc_fb,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-static struct resource mxc_pwm_resources[] = {
- {
- .start = MX2x_PWM_BASE_ADDR,
- .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_PWM,
- .end = MX2x_INT_PWM,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_pwm_device = {
- .name = "mxc_pwm",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_pwm_resources),
- .resource = mxc_pwm_resources,
-};
-
-#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, \
- }
-
-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 = MX27_USBOTG_BASE_ADDR,
- .end = MX27_USBOTG_BASE_ADDR + 0x1ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_USB3,
- .end = MX27_INT_USB3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 otg_dmamask = DMA_BIT_MASK(32);
-
-/* OTG gadget device */
-struct platform_device mxc_otg_udc_device = {
- .name = "fsl-usb2-udc",
- .id = -1,
- .dev = {
- .dma_mask = &otg_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = otg_resources,
- .num_resources = ARRAY_SIZE(otg_resources),
-};
-
-/* OTG host */
-struct platform_device mxc_otg_host = {
- .name = "mxc-ehci",
- .id = 0,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .dma_mask = &otg_dmamask,
- },
- .resource = otg_resources,
- .num_resources = ARRAY_SIZE(otg_resources),
-};
-
-/* USB host 1 */
-
-static u64 usbh1_dmamask = DMA_BIT_MASK(32);
-
-static struct resource mxc_usbh1_resources[] = {
- {
- .start = MX27_USBOTG_BASE_ADDR + 0x200,
- .end = MX27_USBOTG_BASE_ADDR + 0x3ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_USB1,
- .end = MX27_INT_USB1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_usbh1 = {
- .name = "mxc-ehci",
- .id = 1,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .dma_mask = &usbh1_dmamask,
- },
- .resource = mxc_usbh1_resources,
- .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
-};
-
-/* USB host 2 */
-static u64 usbh2_dmamask = DMA_BIT_MASK(32);
-
-static struct resource mxc_usbh2_resources[] = {
- {
- .start = MX27_USBOTG_BASE_ADDR + 0x400,
- .end = MX27_USBOTG_BASE_ADDR + 0x5ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_USB2,
- .end = MX27_INT_USB2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_usbh2 = {
- .name = "mxc-ehci",
- .id = 2,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .dma_mask = &usbh2_dmamask,
- },
- .resource = mxc_usbh2_resources,
- .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
-};
-#endif
-
-/* GPIO port description */
-#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);
-
-int __init imx21_register_gpios(void)
-{
- return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
-}
-#endif
-
-#ifdef CONFIG_MACH_MX27
-DEFINE_MXC_GPIO_PORTS(MX27, imx27);
-
-int __init imx27_register_gpios(void)
-{
- return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
-}
-#endif
-
-#ifdef CONFIG_MACH_MX21
-static struct resource mx21_usbhc_resources[] = {
- {
- .start = MX21_USBOTG_BASE_ADDR,
- .end = MX21_USBOTG_BASE_ADDR + SZ_8K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX21_INT_USBHOST,
- .end = MX21_INT_USBHOST,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mx21_usbhc_device = {
- .name = "imx21-hcd",
- .id = 0,
- .dev = {
- .dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(mx21_usbhc_resources),
- .resource = mx21_usbhc_resources,
-};
-#endif
-
-static struct resource imx_kpp_resources[] = {
- {
- .start = MX2x_KPP_BASE_ADDR,
- .end = MX2x_KPP_BASE_ADDR + 0xf,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX2x_INT_KPP,
- .end = MX2x_INT_KPP,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_kpp_device = {
- .name = "imx-keypad",
- .id = -1,
- .num_resources = ARRAY_SIZE(imx_kpp_resources),
- .resource = imx_kpp_resources,
-};
-
-#endif
diff --git a/arch/arm/mach-imx/devices.h b/arch/arm/mach-imx/devices.h
deleted file mode 100644
index 807f02a031c9..000000000000
--- a/arch/arm/mach-imx/devices.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifdef CONFIG_ARCH_MX1
-extern struct platform_device imx1_camera_device;
-extern struct platform_device imx_rtc_device;
-extern struct platform_device imx_wdt_device;
-extern struct platform_device imx_usb_device;
-#endif
-
-#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
-extern struct platform_device mxc_gpt1;
-extern struct platform_device mxc_gpt2;
-#ifdef CONFIG_MACH_MX27
-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_w1_master_device;
-extern struct platform_device mxc_fb_device;
-extern struct platform_device mxc_pwm_device;
-extern struct platform_device mxc_sdhc_device0;
-extern struct platform_device mxc_sdhc_device1;
-extern struct platform_device mxc_otg_udc_device;
-extern struct platform_device mx27_camera_device;
-extern struct platform_device mxc_otg_host;
-extern struct platform_device mxc_usbh1;
-extern struct platform_device mxc_usbh2;
-extern struct platform_device mx21_usbhc_device;
-extern struct platform_device imx_kpp_device;
-#endif
diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c
index 3e8c47c63bac..e9f1769b49f5 100644
--- a/arch/arm/mach-imx/dma-v1.c
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -818,9 +818,11 @@ static int __init imx_dma_init(void)
imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
else
#endif
- BUG();
+ return 0;
dma_clk = clk_get(NULL, "dma");
+ if (IS_ERR(dma_clk))
+ return PTR_ERR(dma_clk);
clk_enable(dma_clk);
/* reset DMA module */
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index 7e1e9dc2c8fc..275c8589d797 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -26,20 +26,16 @@
#include <linux/spi/ads7846.h>
#include <linux/backlight.h>
#include <video/platform_lcd.h>
-#include <linux/input/matrix_keypad.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/iomux-mx27.h>
-#include <mach/imxfb.h>
#include <mach/hardware.h>
-#include <mach/mmc.h>
#include <mach/spi.h>
#include <mach/audmux.h>
#include "devices-imx27.h"
-#include "devices.h"
static const int eukrea_mbimx27_pins[] __initconst = {
/* UART2 */
@@ -111,7 +107,8 @@ static const uint32_t eukrea_mbimx27_keymap[] = {
KEY(1, 1, KEY_LEFT),
};
-static struct matrix_keymap_data eukrea_mbimx27_keymap_data = {
+static const struct matrix_keymap_data
+eukrea_mbimx27_keymap_data __initconst = {
.keymap = eukrea_mbimx27_keymap,
.keymap_size = ARRAY_SIZE(eukrea_mbimx27_keymap),
};
@@ -196,7 +193,7 @@ static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
},
};
-static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
+static const struct imx_fb_platform_data eukrea_mbimx27_fb_data __initconst = {
.mode = eukrea_mbimx27_modes,
.num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
@@ -300,7 +297,7 @@ static struct platform_device *platform_devices[] __initdata = {
&leds_gpio,
};
-static struct imxmmc_platform_data sdhc_pdata = {
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
.dat3_card_detect = 1,
};
@@ -345,8 +342,8 @@ void __init eukrea_mbimx27_baseboard_init(void)
imx27_add_imx_uart3(&uart_pdata);
#endif
- mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
+ imx27_add_imx_fb(&eukrea_mbimx27_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc_pdata);
i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
@@ -380,7 +377,7 @@ void __init eukrea_mbimx27_baseboard_init(void)
gpio_request(GPIO_PORTA | 25, "lcd_enable");
platform_device_register(&eukrea_mbimx27_lcd_powerdev);
- mxc_register_device(&imx_kpp_device, &eukrea_mbimx27_keymap_data);
+ imx27_add_imx_keypad(&eukrea_mbimx27_keymap_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index e765ac5d9a08..cb705c28de02 100644
--- a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -33,13 +33,11 @@
#include <asm/mach/arch.h>
#include <mach/mx25.h>
#include <mach/imx-uart.h>
-#include <mach/imxfb.h>
#include <mach/audmux.h>
#include "devices-imx25.h"
-#include "devices.h"
-static struct pad_desc eukrea_mbimxsd_pads[] = {
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
/* LCD */
MX25_PAD_LD0__LD0,
MX25_PAD_LD1__LD1,
@@ -151,7 +149,7 @@ static struct imx_fb_videomode eukrea_mximxsd_modes[] = {
},
};
-static struct imx_fb_platform_data eukrea_mximxsd_fb_pdata = {
+static const struct imx_fb_platform_data eukrea_mximxsd_fb_pdata __initconst = {
.mode = eukrea_mximxsd_modes,
.num_modes = ARRAY_SIZE(eukrea_mximxsd_modes),
.pwmr = 0x00A903FF,
@@ -273,11 +271,11 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
#endif
imx25_add_imx_uart1(&uart_pdata);
- mxc_register_device(&mx25_fb_device, &eukrea_mximxsd_fb_pdata);
+ imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
imx25_add_flexcan1(NULL);
- imx25_add_esdhc(0, NULL);
+ imx25_add_sdhci_esdhc_imx(0, NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 745ee60fb068..6cf04da2456a 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -28,7 +28,6 @@
#include <linux/serial_8250.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -40,11 +39,9 @@
#include <mach/hardware.h>
#include <mach/iomux-mx27.h>
#include <mach/mxc_nand.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx27.h"
-#include "devices.h"
static const int eukrea_cpuimx27_pins[] __initconst = {
/* UART1 */
@@ -157,8 +154,6 @@ cpuimx27_nand_board_info __initconst = {
static struct platform_device *platform_devices[] __initdata = {
&eukrea_cpuimx27_nor_mtd_device,
- &mxc_wdt,
- &mxc_w1_master_device,
};
static const struct imxi2c_platform_data cpuimx27_i2c1_data __initconst = {
@@ -215,18 +210,18 @@ static struct platform_device serial_device = {
#endif
#if defined(CONFIG_USB_ULPI)
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
#endif
-static struct fsl_usb2_platform_data otg_device_pdata = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
@@ -262,10 +257,12 @@ static void __init eukrea_cpuimx27_init(void)
imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
/* SDHC2 can be used for Wifi */
- mxc_register_device(&mxc_sdhc_device1, NULL);
+ imx27_add_mxc_mmc(1, NULL);
#endif
#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
/* in which case UART4 is also used for Bluetooth */
@@ -281,16 +278,16 @@ static void __init eukrea_cpuimx27_init(void)
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_otg_host, &otg_pdata);
+ imx27_add_mxc_ehci_otg(&otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
#endif
if (!otg_mode_host)
- mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
eukrea_mbimx27_baseboard_init();
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
index f6f9ad60c25e..eb395aba9237 100644
--- a/arch/arm/mach-mx25/mach-cpuimx25.c
+++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
@@ -26,7 +26,6 @@
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
#include <mach/eukrea-baseboards.h>
#include <mach/hardware.h>
@@ -39,17 +38,15 @@
#include <mach/mx25.h>
#include <mach/mxc_nand.h>
#include <mach/imxfb.h>
-#include <mach/mxc_ehci.h>
#include <mach/iomux-mx25.h>
#include "devices-imx25.h"
-#include "devices.h"
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct pad_desc eukrea_cpuimx25_pads[] = {
+static iomux_v3_cfg_t eukrea_cpuimx25_pads[] = {
/* FEC - RMII */
MX25_PAD_FEC_MDC__FEC_MDC,
MX25_PAD_FEC_MDIO__FEC_MDIO,
@@ -87,18 +84,18 @@ static struct i2c_board_info eukrea_cpuimx25_i2c_devices[] = {
},
};
-static struct mxc_usbh_platform_data otg_pdata = {
+static const struct mxc_usbh_platform_data otg_pdata __initconst = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
.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 = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
};
@@ -126,7 +123,7 @@ static void __init eukrea_cpuimx25_init(void)
imx25_add_imx_uart0(&uart_pdata);
imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
- mxc_register_device(&mx25_rtc_device, NULL);
+ imx25_add_imxdi_rtc(NULL);
imx25_add_fec(&mx25_fec_pdata);
i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
@@ -134,11 +131,11 @@ static void __init eukrea_cpuimx25_init(void)
imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data);
if (otg_mode_host)
- mxc_register_device(&mxc_otg, &otg_pdata);
+ imx25_add_mxc_ehci_otg(&otg_pdata);
else
- mxc_register_device(&otg_udc_device, &otg_device_pdata);
+ imx25_add_fsl_usb2_udc(&otg_device_pdata);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx25_add_mxc_ehci_hs(&usbh2_pdata);
#ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD
eukrea_mbimxsd25_baseboard_init();
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 59716fab586d..40a3666ea632 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -34,12 +34,9 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/common.h>
-#include <mach/mmc.h>
#include <mach/iomux.h>
-#include <mach/mxc_ehci.h>
#include "devices-imx27.h"
-#include "devices.h"
#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
#define SDHC1_IRQ IRQ_GPIOB(25)
@@ -156,7 +153,7 @@ static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
free_irq(SDHC1_IRQ, data);
}
-static struct imxmmc_platform_data visstrim_m10_sdhc_pdata = {
+static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = {
.init = visstrim_m10_sdhc1_init,
.exit = visstrim_m10_sdhc1_exit,
};
@@ -216,7 +213,8 @@ static int otg_phy_init(struct platform_device *pdev)
return 0;
}
-static struct mxc_usbh_platform_data visstrim_m10_usbotg_pdata = {
+static const struct mxc_usbh_platform_data
+visstrim_m10_usbotg_pdata __initconst = {
.init = otg_phy_init,
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED,
@@ -237,8 +235,8 @@ static void __init visstrim_m10_board_init(void)
ARRAY_SIZE(visstrim_m10_i2c_devices));
imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
- mxc_register_device(&mxc_sdhc_device0, &visstrim_m10_sdhc_pdata);
- mxc_register_device(&mxc_otg_host, &visstrim_m10_usbotg_pdata);
+ imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
+ imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
index bbdbc75127d3..3a1202e47212 100644
--- a/arch/arm/mach-imx/mach-imx27lite.c
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -25,7 +25,6 @@
#include <mach/iomux-mx27.h>
#include "devices-imx27.h"
-#include "devices.h"
static const int mx27lite_pins[] __initconst = {
/* UART1 */
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
index 6187ce9ba7d5..1f446e5eb636 100644
--- a/arch/arm/mach-imx/mach-mx1ads.c
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -30,7 +30,6 @@
#include <mach/irqs.h>
#include "devices-imx1.h"
-#include "devices.h"
static const int mx1ads_pins[] __initconst = {
/* UART1 */
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index e1282e9f50ff..0a372577c2ac 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -24,13 +24,10 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <mach/imxfb.h>
#include <mach/iomux-mx21.h>
#include <mach/mxc_nand.h>
-#include <mach/mmc.h>
#include "devices-imx21.h"
-#include "devices.h"
/*
* Memory-mapped I/O on MX21ADS base board
@@ -213,7 +210,7 @@ static struct imx_fb_videomode mx21ads_modes[] = {
},
};
-static struct imx_fb_platform_data mx21ads_fb_data = {
+static const struct imx_fb_platform_data mx21ads_fb_data __initconst = {
.mode = mx21ads_modes,
.num_modes = ARRAY_SIZE(mx21ads_modes),
@@ -233,15 +230,8 @@ static int mx21ads_sdhc_get_ro(struct device *dev)
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,
+ return 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)
@@ -249,7 +239,7 @@ static void mx21ads_sdhc_exit(struct device *dev, void *data)
free_irq(IRQ_GPIOD(25), data);
}
-static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
+static const struct imxmmc_platform_data mx21ads_sdhc_pdata __initconst = {
.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
.get_ro = mx21ads_sdhc_get_ro,
.init = mx21ads_sdhc_init,
@@ -296,8 +286,8 @@ static void __init mx21ads_board_init(void)
imx21_add_imx_uart0(&uart_pdata_rts);
imx21_add_imx_uart2(&uart_pdata_norts);
imx21_add_imx_uart3(&uart_pdata_rts);
- mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
+ imx21_add_imx_fb(&mx21ads_fb_data);
+ imx21_add_mxc_mmc(0, &mx21ads_sdhc_pdata);
imx21_add_mxc_nand(&mx21ads_nand_board_info);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
diff --git a/arch/arm/mach-mx25/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c
index f8be1eb0c062..aa76cfd9f348 100644
--- a/arch/arm/mach-mx25/mach-mx25_3ds.c
+++ b/arch/arm/mach-imx/mach-mx25_3ds.c
@@ -30,6 +30,7 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/usb/otg.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -39,17 +40,15 @@
#include <asm/mach/map.h>
#include <mach/common.h>
#include <mach/mx25.h>
-#include <mach/imxfb.h>
#include <mach/iomux-mx25.h>
#include "devices-imx25.h"
-#include "devices.h"
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct pad_desc mx25pdk_pads[] = {
+static iomux_v3_cfg_t mx25pdk_pads[] = {
MX25_PAD_FEC_MDC__FEC_MDC,
MX25_PAD_FEC_MDIO__FEC_MDIO,
MX25_PAD_FEC_TDATA0__FEC_TDATA0,
@@ -107,7 +106,7 @@ static struct pad_desc mx25pdk_pads[] = {
};
static const struct fec_platform_data mx25_fec_pdata __initconst = {
- .phy = PHY_INTERFACE_MODE_RMII,
+ .phy = PHY_INTERFACE_MODE_RMII,
};
#define FEC_ENABLE_GPIO 35
@@ -154,7 +153,7 @@ static struct imx_fb_videomode mx25pdk_modes[] = {
},
};
-static struct imx_fb_platform_data mx25pdk_fb_pdata = {
+static const struct imx_fb_platform_data mx25pdk_fb_pdata __initconst = {
.mode = mx25pdk_modes,
.num_modes = ARRAY_SIZE(mx25pdk_modes),
.pwmr = 0x00A903FF,
@@ -181,28 +180,39 @@ static const uint32_t mx25pdk_keymap[] = {
KEY(3, 3, KEY_POWER),
};
-static struct matrix_keymap_data mx25pdk_keymap_data = {
+static const struct matrix_keymap_data mx25pdk_keymap_data __initdata = {
.keymap = mx25pdk_keymap,
.keymap_size = ARRAY_SIZE(mx25pdk_keymap),
};
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
+ .portsc = MXC_EHCI_MODE_SERIAL,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
static void __init mx25pdk_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
ARRAY_SIZE(mx25pdk_pads));
imx25_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxc_usbh2, NULL);
+ imx25_add_fsl_usb2_udc(&otg_device_pdata);
+ imx25_add_mxc_ehci_hs(&usbh2_pdata);
imx25_add_mxc_nand(&mx25pdk_nand_board_info);
- mxc_register_device(&mx25_rtc_device, NULL);
- mxc_register_device(&mx25_fb_device, &mx25pdk_fb_pdata);
- mxc_register_device(&mxc_wdt, NULL);
+ imx25_add_imxdi_rtc(NULL);
+ imx25_add_imx_fb(&mx25pdk_fb_pdata);
+ imx25_add_imx2_wdt(NULL);
mx25pdk_fec_reset();
imx25_add_fec(&mx25_fec_pdata);
- mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
+ imx25_add_imx_keypad(&mx25pdk_keymap_data);
- imx25_add_esdhc(0, NULL);
+ imx25_add_sdhci_esdhc_imx(0, NULL);
}
static void __init mx25pdk_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 84a5ba03f1ba..6fd0f8f6deb6 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -22,20 +22,27 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <linux/input/matrix_keypad.h>
#include <linux/irq.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.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/iomux-mx27.h>
-#include <mach/mmc.h>
+#include <mach/ulpi.h>
#include "devices-imx27.h"
-#include "devices.h"
#define SD1_EN_GPIO (GPIO_PORTB + 25)
+#define OTG_PHY_RESET_GPIO (GPIO_PORTB + 23)
+#define SPI2_SS0 (GPIO_PORTD + 21)
static const int mx27pdk_pins[] __initconst = {
/* UART1 */
@@ -70,6 +77,24 @@ static const int mx27pdk_pins[] __initconst = {
PE22_PF_SD1_CMD,
PE23_PF_SD1_CLK,
SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
+ /* OTG */
+ OTG_PHY_RESET_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,
+ /* CSPI2 */
+ PD22_PF_CSPI2_SCLK,
+ PD23_PF_CSPI2_MISO,
+ PD24_PF_CSPI2_MOSI,
};
static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -92,7 +117,7 @@ static const uint32_t mx27_3ds_keymap[] = {
KEY(2, 3, KEY_F10),
};
-static struct matrix_keymap_data mx27_3ds_keymap_data = {
+static const struct matrix_keymap_data mx27_3ds_keymap_data __initconst = {
.keymap = mx27_3ds_keymap,
.keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
};
@@ -109,7 +134,7 @@ static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
free_irq(IRQ_GPIOB(26), data);
}
-static struct imxmmc_platform_data sdhc1_pdata = {
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
.init = mx27_3ds_sdhc1_init,
.exit = mx27_3ds_sdhc1_exit,
};
@@ -121,6 +146,111 @@ static void mx27_3ds_sdhc1_enable_level_translator(void)
gpio_direction_output(SD1_EN_GPIO, 1);
}
+
+static int otg_phy_init(void)
+{
+ gpio_request(OTG_PHY_RESET_GPIO, "usb-otg-reset");
+ gpio_direction_output(OTG_PHY_RESET_GPIO, 0);
+ mdelay(1);
+ gpio_set_value(OTG_PHY_RESET_GPIO, 1);
+ return 0;
+}
+
+#if defined(CONFIG_USB_ULPI)
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init mx27_3ds_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=", mx27_3ds_otg_mode);
+
+/* Regulators */
+static struct regulator_consumer_supply vmmc1_consumers[] = {
+ REGULATOR_SUPPLY("lcd_2v8", NULL),
+};
+
+static struct regulator_init_data vmmc1_init = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
+ .consumer_supplies = vmmc1_consumers,
+};
+
+static struct regulator_consumer_supply vgen_consumers[] = {
+ REGULATOR_SUPPLY("vdd_lcdio", NULL),
+};
+
+static struct regulator_init_data vgen_init = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
+ .consumer_supplies = vgen_consumers,
+};
+
+static struct mc13783_regulator_init_data mx27_3ds_regulators[] = {
+ {
+ .id = MC13783_REGU_VMMC1,
+ .init_data = &vmmc1_init,
+ }, {
+ .id = MC13783_REGU_VGEN,
+ .init_data = &vgen_init,
+ },
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+ .regulators = mx27_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
+ .flags = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi2_internal_chipselect[] = {SPI2_SS0};
+
+static const struct spi_imx_master spi2_pdata __initconst = {
+ .chipselect = spi2_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi2_internal_chipselect),
+};
+
+static struct spi_board_info mx27_3ds_spi_devs[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0, /* SS0 */
+ .platform_data = &mc13783_pdata,
+ .irq = IRQ_GPIOC(14),
+ .mode = SPI_CS_HIGH,
+ },
+};
+
+
static void __init mx27pdk_init(void)
{
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
@@ -128,8 +258,24 @@ static void __init mx27pdk_init(void)
mx27_3ds_sdhc1_enable_level_translator();
imx27_add_imx_uart0(&uart_pdata);
imx27_add_fec(NULL);
- mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
- mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+ imx27_add_imx_keypad(&mx27_3ds_keymap_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
+ imx27_add_imx2_wdt(NULL);
+ otg_phy_init();
+#if defined(CONFIG_USB_ULPI)
+ if (otg_mode_host) {
+ otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+
+ imx27_add_mxc_ehci_otg(&otg_pdata);
+ }
+#endif
+ if (!otg_mode_host)
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
+
+ imx27_add_spi_imx1(&spi2_pdata);
+ spi_register_board_info(mx27_3ds_spi_devs,
+ ARRAY_SIZE(mx27_3ds_spi_devs));
}
static void __init mx27pdk_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index a1e4bc573afc..b832f960fec4 100644
--- a/arch/arm/mach-imx/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -30,11 +30,8 @@
#include <mach/gpio.h>
#include <mach/iomux-mx27.h>
#include <mach/mxc_nand.h>
-#include <mach/imxfb.h>
-#include <mach/mmc.h>
#include "devices-imx27.h"
-#include "devices.h"
/*
* Base address of PBC controller, CS4
@@ -228,7 +225,7 @@ static struct imx_fb_videomode mx27ads_modes[] = {
},
};
-static struct imx_fb_platform_data mx27ads_fb_data = {
+static const struct imx_fb_platform_data mx27ads_fb_data __initconst = {
.mode = mx27ads_modes,
.num_modes = ARRAY_SIZE(mx27ads_modes),
@@ -272,19 +269,18 @@ static void mx27ads_sdhc2_exit(struct device *dev, void *data)
free_irq(IRQ_GPIOB(7), data);
}
-static struct imxmmc_platform_data sdhc1_pdata = {
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
.init = mx27ads_sdhc1_init,
.exit = mx27ads_sdhc1_exit,
};
-static struct imxmmc_platform_data sdhc2_pdata = {
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
.init = mx27ads_sdhc2_init,
.exit = mx27ads_sdhc2_exit,
};
static struct platform_device *platform_devices[] __initdata = {
&mx27ads_nor_mtd_device,
- &mxc_w1_master_device,
};
static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -308,12 +304,13 @@ static void __init mx27ads_board_init(void)
i2c_register_board_info(1, mx27ads_i2c_devices,
ARRAY_SIZE(mx27ads_i2c_devices));
imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
- mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
- mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
+ imx27_add_imx_fb(&mx27ads_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
+ imx27_add_mxc_mmc(1, &sdhc2_pdata);
imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_mxc_w1(NULL);
}
static void __init mx27ads_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
index 38d3a4ae17c7..4ce71b0401db 100644
--- a/arch/arm/mach-imx/mach-mxt_td60.c
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -31,11 +31,8 @@
#include <mach/iomux-mx27.h>
#include <mach/mxc_nand.h>
#include <linux/i2c/pca953x.h>
-#include <mach/imxfb.h>
-#include <mach/mmc.h>
#include "devices-imx27.h"
-#include "devices.h"
static const int mxt_td60_pins[] __initconst = {
/* UART0 */
@@ -196,7 +193,7 @@ static struct imx_fb_videomode mxt_td60_modes[] = {
},
};
-static struct imx_fb_platform_data mxt_td60_fb_data = {
+static const struct imx_fb_platform_data mxt_td60_fb_data __initconst = {
.mode = mxt_td60_modes,
.num_modes = ARRAY_SIZE(mxt_td60_modes),
@@ -226,7 +223,7 @@ static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
free_irq(IRQ_GPIOF(8), data);
}
-static struct imxmmc_platform_data sdhc1_pdata = {
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
.init = mxt_td60_sdhc1_init,
.exit = mxt_td60_sdhc1_exit,
};
@@ -253,8 +250,8 @@ static void __init mxt_td60_board_init(void)
imx27_add_imx_i2c(0, &mxt_td60_i2c0_data);
imx27_add_imx_i2c(1, &mxt_td60_i2c1_data);
- mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+ imx27_add_imx_fb(&mxt_td60_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
imx27_add_fec(NULL);
}
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index 8c720d44602a..cccc0a0a9c72 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -29,7 +29,6 @@
#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>
@@ -40,13 +39,9 @@
#include <mach/audmux.h>
#include <mach/mxc_nand.h>
#include <mach/irqs.h>
-#include <mach/mmc.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
-#include <mach/imxfb.h>
#include "devices-imx27.h"
-#include "devices.h"
#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
@@ -171,11 +166,6 @@ pca100_nand_board_info __initconst = {
.hw_ecc = 1,
};
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_w1_master_device,
- &mxc_wdt,
-};
-
static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -274,7 +264,7 @@ static void pca100_sdhc2_exit(struct device *dev, void *data)
free_irq(IRQ_GPIOC(29), data);
}
-static struct imxmmc_platform_data sdhc_pdata = {
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
.init = pca100_sdhc2_init,
.exit = pca100_sdhc2_exit,
};
@@ -286,7 +276,7 @@ static int otg_phy_init(struct platform_device *pdev)
return 0;
}
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
.init = otg_phy_init,
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
@@ -298,14 +288,14 @@ static int usbh2_phy_init(struct platform_device *pdev)
return 0;
}
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.init = usbh2_phy_init,
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
#endif
-static struct fsl_usb2_platform_data otg_device_pdata = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
@@ -355,7 +345,7 @@ static struct imx_fb_videomode pca100_fb_modes[] = {
},
};
-static struct imx_fb_platform_data pca100_fb_data = {
+static const struct imx_fb_platform_data pca100_fb_data __initconst = {
.mode = pca100_fb_modes,
.num_modes = ARRAY_SIZE(pca100_fb_modes),
@@ -389,7 +379,7 @@ static void __init pca100_init(void)
imx27_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
+ imx27_add_mxc_mmc(1, &sdhc_pdata);
imx27_add_mxc_nand(&pca100_nand_board_info);
@@ -417,23 +407,24 @@ static void __init pca100_init(void)
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_otg_host, &otg_pdata);
+ imx27_add_mxc_ehci_otg(&otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx27_add_mxc_ehci_hs(2, &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);
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
}
- mxc_register_device(&mxc_fb_device, &pca100_fb_data);
+ imx27_add_imx_fb(&pca100_fb_data);
imx27_add_fec(NULL);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
}
static void __init pca100_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 49a97ce07426..f667a262dfc1 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -37,11 +37,9 @@
#include <mach/hardware.h>
#include <mach/iomux-mx27.h>
#include <mach/mxc_nand.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx27.h"
-#include "devices.h"
static const int pcm038_pins[] __initconst = {
/* UART1 */
@@ -172,9 +170,7 @@ pcm038_nand_board_info __initconst = {
static struct platform_device *platform_devices[] __initdata = {
&pcm038_nor_mtd_device,
- &mxc_w1_master_device,
&pcm038_sram_mtd_device,
- &mxc_wdt,
};
/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
@@ -214,7 +210,7 @@ static const struct spi_imx_master pcm038_spi0_data __initconst = {
static struct regulator_consumer_supply sdhc1_consumers[] = {
{
- .dev = &mxc_sdhc_device1.dev,
+ .dev_name = "mxc-mmc.1",
.supply = "sdhc_vcc",
},
};
@@ -285,7 +281,7 @@ static struct spi_board_info pcm038_spi_board_info[] __initdata = {
}
};
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
};
@@ -322,10 +318,12 @@ static void __init pcm038_init(void)
spi_register_board_info(pcm038_spi_board_info,
ARRAY_SIZE(pcm038_spi_board_info));
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
imx27_add_fec(NULL);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
#ifdef CONFIG_MACH_PCM970_BASEBOARD
pcm970_baseboard_init();
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
index 1fbdd3faa7ab..eae878f306c6 100644
--- a/arch/arm/mach-imx/mach-scb9328.c
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -25,7 +25,6 @@
#include <mach/iomux-mx1.h>
#include "devices-imx1.h"
-#include "devices.h"
/*
* This scb9328 has a 32MiB flash
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 9be92b96dc89..729ae0915af8 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -25,12 +25,7 @@
#include <mach/hardware.h>
static struct map_desc imx_io_desc[] __initdata = {
- {
- .virtual = MX1_IO_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MX1_IO_BASE_ADDR),
- .length = MX1_IO_SIZE,
- .type = MT_DEVICE
- }
+ imx_map_entry(MX1, IO, MT_DEVICE),
};
void __init mx1_map_io(void)
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 12faeeaa0a97..e728af81d1b1 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -35,33 +35,18 @@ static struct map_desc imx21_io_desc[] __initdata = {
* - 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
- },
+ imx_map_entry(MX21, AIPI, 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
- },
+ imx_map_entry(MX21, SAHB1, 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
- },
+ imx_map_entry(MX21, X_MEMC, MT_DEVICE),
};
/*
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-imx/mm-imx25.c
index bb677111fb0f..2edec6ce8fe7 100644
--- a/arch/arm/mach-mx25/mm.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -30,25 +30,12 @@
/*
* This table defines static virtual address mappings for I/O regions.
- * These are the mappings common across all MX3 boards.
+ * These are the mappings common across all MX25 boards.
*/
-static struct map_desc mxc_io_desc[] __initdata = {
- {
- .virtual = MX25_AVIC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MX25_AVIC_BASE_ADDR),
- .length = MX25_AVIC_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = MX25_AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MX25_AIPS1_BASE_ADDR),
- .length = MX25_AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = MX25_AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MX25_AIPS2_BASE_ADDR),
- .length = MX25_AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
+static struct map_desc mx25_io_desc[] __initdata = {
+ imx_map_entry(MX25, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX25, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX25, AIPS2, MT_DEVICE_NONSHARED),
};
/*
@@ -62,14 +49,14 @@ void __init mx25_map_io(void)
mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+ iotable_init(mx25_io_desc, ARRAY_SIZE(mx25_io_desc));
}
int imx25_register_gpios(void);
void __init mx25_init_irq(void)
{
- mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT);
+ mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
imx25_register_gpios();
}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index a24622957ff2..374e48b7a412 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -35,33 +35,18 @@ static struct map_desc imx27_io_desc[] __initdata = {
* - 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
- },
+ imx_map_entry(MX27, AIPI, 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
- },
+ imx_map_entry(MX27, SAHB1, 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
- },
+ imx_map_entry(MX27, X_MEMC, MT_DEVICE),
};
/*
diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
index 9110d9cca7a2..99afbc3f43a3 100644
--- a/arch/arm/mach-imx/pcm970-baseboard.c
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
@@ -25,11 +25,9 @@
#include <mach/common.h>
#include <mach/iomux-mx27.h>
-#include <mach/imxfb.h>
#include <mach/hardware.h>
-#include <mach/mmc.h>
-#include "devices.h"
+#include "devices-imx27.h"
static const int pcm970_pins[] __initconst = {
/* SDHC */
@@ -119,7 +117,7 @@ static void pcm970_sdhc2_exit(struct device *dev, void *data)
gpio_free(GPIO_PORTC + 28);
}
-static struct imxmmc_platform_data sdhc_pdata = {
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
.get_ro = pcm970_sdhc2_get_ro,
.init = pcm970_sdhc2_init,
.exit = pcm970_sdhc2_exit,
@@ -179,7 +177,7 @@ static struct imx_fb_videomode pcm970_modes[] = {
},
};
-static struct imx_fb_platform_data pcm038_fb_data = {
+static const struct imx_fb_platform_data pcm038_fb_data __initconst = {
.mode = pcm970_modes,
.num_modes = ARRAY_SIZE(pcm970_modes),
@@ -226,8 +224,8 @@ void __init pcm970_baseboard_init(void)
mxc_gpio_setup_multiple_pins(pcm970_pins, ARRAY_SIZE(pcm970_pins),
"PCM970");
- mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+ imx27_add_imx_fb(&pcm038_fb_data);
mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
- mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
+ imx27_add_mxc_mmc(1, &sdhc_pdata);
platform_device_register(&pcm970_sja1000);
}
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
index afc17ce0bb54..6bf81ceea137 100644
--- a/arch/arm/mach-imx/pm-imx27.c
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -39,6 +39,9 @@ static struct platform_suspend_ops mx27_suspend_ops = {
static int __init mx27_pm_init(void)
{
+ if (!cpu_is_mx27())
+ return 0;
+
suspend_set_ops(&mx27_suspend_ops);
return 0;
}
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 27db275b367c..769b0f10c834 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -4,6 +4,7 @@ menu "Integrator Options"
config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms"
+ select MIGHT_HAVE_PCI
help
Include support for the ARM(R) Integrator/AP and
Integrator/PP2 platforms.
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8f4fb6d638f7..b8e884b450da 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -21,9 +21,8 @@
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index fd684bf205e5..5db574f8ae3f 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -22,9 +22,8 @@
#include <linux/amba/clcd.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
#include <asm/hardware/icst.h>
#include <mach/lm.h>
#include <mach/impd1.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 548208f11179..2774df8021dc 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -372,7 +372,6 @@ static struct clocksource clocksource_timersp = {
.rating = 200,
.read = timersp_read,
.mask = CLOCKSOURCE_MASK(16),
- .shift = 16,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -390,8 +389,7 @@ static void integrator_clocksource_init(u32 khz)
writel(ctrl, base + TIMER_CTRL);
writel(0xffff, base + TIMER_LOAD);
- cs->mult = clocksource_khz2mult(khz, cs->shift);
- clocksource_register(cs);
+ clocksource_register_khz(cs, khz);
}
static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 6258c90d020c..85e48a5f77b9 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -21,9 +21,8 @@
#include <linux/amba/mmci.h>
#include <linux/io.h>
#include <linux/gfp.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include <asm/irq.h>
@@ -41,7 +40,7 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
#include "common.h"
diff --git a/arch/arm/mach-iop13xx/include/mach/io.h b/arch/arm/mach-iop13xx/include/mach/io.h
index a6e0f9e6ddcf..dffb234bb967 100644
--- a/arch/arm/mach-iop13xx/include/mach/io.h
+++ b/arch/arm/mach-iop13xx/include/mach/io.h
@@ -35,7 +35,7 @@ extern u32 iop13xx_atux_mem_base;
extern size_t iop13xx_atue_mem_size;
extern size_t iop13xx_atux_mem_size;
-#define __arch_ioremap(a, s, f) __iop13xx_ioremap(a, s, f)
-#define __arch_iounmap(a) __iop13xx_iounmap(a)
+#define __arch_ioremap __iop13xx_ioremap
+#define __arch_iounmap __iop13xx_iounmap
#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 7415e4338651..3ad455318868 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -58,13 +58,13 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
__dma; \
})
-#define __arch_page_to_dma(dev, page) \
+#define __arch_pfn_to_dma(dev, pfn) \
({ \
/* __is_lbus_virt() can never be true for RAM pages */ \
- (dma_addr_t)page_to_phys(page); \
+ (dma_addr_t)__pfn_to_phys(pfn); \
})
-#define __arch_dma_to_page(dev, addr) phys_to_page(addr)
+#define __arch_dma_to_pfn(dev, addr) __phys_to_pfn(addr)
#endif /* CONFIG_ARCH_IOP13XX */
#endif /* !ASSEMBLY */
diff --git a/arch/arm/mach-iop32x/include/mach/io.h b/arch/arm/mach-iop32x/include/mach/io.h
index 339e5854728b..059c783ce0b2 100644
--- a/arch/arm/mach-iop32x/include/mach/io.h
+++ b/arch/arm/mach-iop32x/include/mach/io.h
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#define __mem_pci(a) (a)
-#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
-#define __arch_iounmap(a) __iop3xx_iounmap(a)
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
#endif
diff --git a/arch/arm/mach-iop33x/include/mach/io.h b/arch/arm/mach-iop33x/include/mach/io.h
index e99a7ed6d050..39e893e97c21 100644
--- a/arch/arm/mach-iop33x/include/mach/io.h
+++ b/arch/arm/mach-iop33x/include/mach/io.h
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#define __mem_pci(a) (a)
-#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
-#define __arch_iounmap(a) __iop3xx_iounmap(a)
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/io.h b/arch/arm/mach-ixp23xx/include/mach/io.h
index fd9ef8e519f7..a1749d0fd896 100644
--- a/arch/arm/mach-ixp23xx/include/mach/io.h
+++ b/arch/arm/mach-ixp23xx/include/mach/io.h
@@ -45,8 +45,8 @@ ixp23xx_iounmap(void __iomem *addr)
__iounmap(addr);
}
-#define __arch_ioremap(a,s,f) ixp23xx_ioremap(a,s,f)
-#define __arch_iounmap(a) ixp23xx_iounmap(a)
+#define __arch_ioremap ixp23xx_ioremap
+#define __arch_iounmap ixp23xx_iounmap
#endif
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 24498a932ba6..a54b3db80366 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);
-
+EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 0bce09799d18..4dbfcbb9163c 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -35,6 +35,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
+#include <asm/sched_clock.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
@@ -399,6 +400,23 @@ void __init ixp4xx_sys_init(void)
}
/*
+ * sched_clock()
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = *IXP4XX_OSTS;
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace ixp4xx_update_sched_clock(void)
+{
+ u32 cyc = *IXP4XX_OSTS;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/*
* clocksource
*/
static cycle_t ixp4xx_get_cycles(struct clocksource *cs)
@@ -411,7 +429,6 @@ static struct clocksource clocksource_ixp4xx = {
.rating = 200,
.read = ixp4xx_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -419,21 +436,9 @@ unsigned long ixp4xx_timer_freq = FREQ;
EXPORT_SYMBOL(ixp4xx_timer_freq);
static void __init ixp4xx_clocksource_init(void)
{
- clocksource_ixp4xx.mult =
- clocksource_hz2mult(ixp4xx_timer_freq,
- clocksource_ixp4xx.shift);
- clocksource_register(&clocksource_ixp4xx);
-}
-
-/*
- * sched_clock()
- */
-unsigned long long sched_clock(void)
-{
- cycle_t cyc = ixp4xx_get_cycles(NULL);
- struct clocksource *cs = &clocksource_ixp4xx;
+ init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
- return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+ clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq);
}
/*
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
index de274a1f19d7..57b5410c31f4 100644
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -74,8 +74,8 @@ static inline void __indirect_iounmap(void __iomem *addr)
__iounmap(addr);
}
-#define __arch_ioremap(a, s, f) __indirect_ioremap(a, s, f)
-#define __arch_iounmap(a) __indirect_iounmap(a)
+#define __arch_ioremap __indirect_ioremap
+#define __arch_iounmap __indirect_iounmap
#define writeb(v, p) __indirect_writeb(v, p)
#define writew(v, p) __indirect_writew(v, p)
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 34106335c728..7fc603b46891 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -45,18 +45,18 @@ config MACH_GURUPLUG
Marvell GuruPlug Reference Board.
config MACH_TS219
- bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
+ bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
help
Say 'Y' here if you want your kernel to support the
- QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS
- devices.
+ QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and
+ TS-219P+ Turbo NAS devices.
config MACH_TS41X
- bool "QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS"
+ bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS"
help
Say 'Y' here if you want your kernel to support the
- QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
- devices.
+ QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo
+ NAS devices.
config MACH_DOCKSTAR
bool "Seagate FreeAgent DockStar"
diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h
index 44e8be04f259..1aaddc364f2e 100644
--- a/arch/arm/mach-kirkwood/include/mach/io.h
+++ b/arch/arm/mach-kirkwood/include/mach/io.h
@@ -42,8 +42,8 @@ __arch_iounmap(void __iomem *addr)
__iounmap(addr);
}
-#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m)
-#define __arch_iounmap(a) __arch_iounmap(a)
+#define __arch_ioremap __arch_ioremap
+#define __arch_iounmap __arch_iounmap
#define __io(a) __io(a)
#define __mem_pci(a) (a)
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index c9d77fad10ab..cfcca4174e25 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -171,7 +171,7 @@ static void __init openrd_init(void)
kirkwood_i2c_init();
- if (machine_is_openrd_client()) {
+ if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
i2c_register_board_info(0, i2c_board_info,
ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init();
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index 6710bd7773b8..dc999c4c5806 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -80,15 +80,19 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = {
MPP11_UART0_RXD,
MPP13_UART1_TXD, /* PIC controller */
MPP14_UART1_RXD, /* PIC controller */
- MPP15_GPIO, /* USB Copy button */
- MPP16_GPIO, /* Reset button */
+ MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */
+ MPP16_GPIO, /* Reset button (on devices with 88F6281) */
MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
+ MPP37_GPIO, /* Reset button (on devices with 88F6282) */
+ MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */
MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */
0
};
static void __init qnap_ts219_init(void)
{
+ u32 dev, rev;
+
/*
* Basic setup. Needs to be called early.
*/
@@ -100,6 +104,14 @@ static void __init qnap_ts219_init(void)
qnap_tsx1x_register_flash();
kirkwood_i2c_init();
i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID) {
+ qnap_ts219_buttons[0].gpio = 43; /* USB Copy button */
+ qnap_ts219_buttons[1].gpio = 37; /* Reset button */
+ qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
+ }
+
kirkwood_ge00_init(&qnap_ts219_ge00_data);
kirkwood_sata_init(&qnap_ts219_sata_data);
kirkwood_ehci_init();
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index 3587a281d993..9a44029915e2 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -119,6 +119,8 @@ static unsigned int qnap_ts41x_mpp_config[] __initdata = {
static void __init qnap_ts41x_init(void)
{
+ u32 dev, rev;
+
/*
* Basic setup. Needs to be called early.
*/
@@ -130,8 +132,15 @@ static void __init qnap_ts41x_init(void)
qnap_tsx1x_register_flash();
kirkwood_i2c_init();
i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1);
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID) {
+ qnap_ts41x_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
+ qnap_ts41x_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1);
+ }
kirkwood_ge00_init(&qnap_ts41x_ge00_data);
kirkwood_ge01_init(&qnap_ts41x_ge01_data);
+
kirkwood_sata_init(&qnap_ts41x_sata_data);
kirkwood_ehci_init();
platform_device_register(&qnap_ts41x_button_device);
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
index fe0c82e30b2d..f5c39a8c2b00 100644
--- a/arch/arm/mach-ks8695/Kconfig
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -4,6 +4,7 @@ menu "Kendin/Micrel KS8695 Implementations"
config MACH_KS8695
bool "KS8695 development board"
+ select MIGHT_HAVE_PCI
help
Say 'Y' here if you want your kernel to run on the original
Kendin-Micrel KS8695 development board.
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index ffa19aae6e05..bace9a681adc 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -35,17 +35,17 @@ extern struct bus_type platform_bus_type;
__phys_to_virt(x) : __bus_to_virt(x)); })
#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
(dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
-#define __arch_page_to_dma(dev, x) \
- ({ dma_addr_t __dma = page_to_phys(page); \
+#define __arch_pfn_to_dma(dev, pfn) \
+ ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
if (!is_lbus_device(dev)) \
__dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
__dma; })
-#define __arch_dma_to_page(dev, x) \
+#define __arch_dma_to_pfn(dev, x) \
({ dma_addr_t __dma = x; \
if (!is_lbus_device(dev)) \
__dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \
- phys_to_page(__dma); \
+ __phys_to_pfn(__dma); \
})
#endif
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 32d63796430a..da0e6498110a 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -90,10 +90,9 @@
#include <linux/clk.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
+#include <linux/clkdev.h>
#include <mach/hardware.h>
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
#include <mach/platform.h>
#include "clock.h"
#include "common.h"
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
index 630dd4a74b26..6162ac308c20 100644
--- a/arch/arm/mach-lpc32xx/timer.c
+++ b/arch/arm/mach-lpc32xx/timer.c
@@ -38,7 +38,6 @@ static cycle_t lpc32xx_clksrc_read(struct clocksource *cs)
static struct clocksource lpc32xx_clksrc = {
.name = "lpc32xx_clksrc",
- .shift = 24,
.rating = 300,
.read = lpc32xx_clksrc_read,
.mask = CLOCKSOURCE_MASK(32),
@@ -171,9 +170,7 @@ static void __init lpc32xx_timer_init(void)
__raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
__raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
- lpc32xx_clksrc.mult = clocksource_hz2mult(clkrate,
- lpc32xx_clksrc.shift);
- clocksource_register(&lpc32xx_clksrc);
+ clocksource_register_hz(&lpc32xx_clksrc, clkrate);
}
struct sys_timer lpc32xx_timer = {
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 0711d3b620ad..67793a690272 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -37,25 +37,38 @@ config MACH_TTC_DKB
Say 'Y' here if you want to support the Marvell PXA910-based
TTC_DKB Development Board.
+config MACH_BROWNSTONE
+ bool "Marvell's Brownstone Development Platform"
+ depends on !CPU_MOHAWK
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-based
+ Brown Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv7 architecture.
+
config MACH_FLINT
bool "Marvell's Flint Development Platform"
+ depends on !CPU_MOHAWK
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.
+ ARMv7 architecture.
config MACH_MARVELL_JASPER
bool "Marvell's Jasper Development Platform"
+ depends on !CPU_MOHAWK
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.
+ ARMv7 architecture.
config MACH_TETON_BGA
bool "Marvell's PXA168 Teton BGA Development Board"
@@ -80,8 +93,7 @@ config CPU_PXA910
config CPU_MMP2
bool
- select CPU_V6
- select CPU_32v6K
+ select CPU_PJ4
help
- Select code specific to MMP2. MMP2 is ARMv6 compatible.
+ Select code specific to MMP2. MMP2 is ARMv7 compatible.
endif
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 751cdbf733c8..5c68382141af 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -15,6 +15,7 @@ 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_BROWNSTONE) += brownstone.o
obj-$(CONFIG_MACH_FLINT) += flint.o
obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
new file mode 100644
index 000000000000..7bb78fd5a2a6
--- /dev/null
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -0,0 +1,204 @@
+/*
+ * linux/arch/arm/mach-mmp/brownstone.c
+ *
+ * Support for the Marvell Brownstone 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 <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8925.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 <mach/irqs.h>
+
+#include "common.h"
+
+#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40)
+
+#define GPIO_5V_ENABLE (89)
+
+static unsigned long brownstone_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,
+
+ /* PMIC */
+ PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+
+ /* MMC0 */
+ GPIO131_MMC1_DAT3 | MFP_PULL_HIGH,
+ GPIO132_MMC1_DAT2 | MFP_PULL_HIGH,
+ GPIO133_MMC1_DAT1 | MFP_PULL_HIGH,
+ GPIO134_MMC1_DAT0 | MFP_PULL_HIGH,
+ GPIO136_MMC1_CMD | MFP_PULL_HIGH,
+ GPIO139_MMC1_CLK,
+ GPIO140_MMC1_CD | MFP_PULL_LOW,
+ GPIO141_MMC1_WP | MFP_PULL_LOW,
+
+ /* MMC1 */
+ GPIO37_MMC2_DAT3 | MFP_PULL_HIGH,
+ GPIO38_MMC2_DAT2 | MFP_PULL_HIGH,
+ GPIO39_MMC2_DAT1 | MFP_PULL_HIGH,
+ GPIO40_MMC2_DAT0 | MFP_PULL_HIGH,
+ GPIO41_MMC2_CMD | MFP_PULL_HIGH,
+ GPIO42_MMC2_CLK,
+
+ /* MMC2 */
+ GPIO165_MMC3_DAT7 | MFP_PULL_HIGH,
+ GPIO162_MMC3_DAT6 | MFP_PULL_HIGH,
+ GPIO166_MMC3_DAT5 | MFP_PULL_HIGH,
+ GPIO163_MMC3_DAT4 | MFP_PULL_HIGH,
+ GPIO167_MMC3_DAT3 | MFP_PULL_HIGH,
+ GPIO164_MMC3_DAT2 | MFP_PULL_HIGH,
+ GPIO168_MMC3_DAT1 | MFP_PULL_HIGH,
+ GPIO111_MMC3_DAT0 | MFP_PULL_HIGH,
+ GPIO112_MMC3_CMD | MFP_PULL_HIGH,
+ GPIO151_MMC3_CLK,
+
+ /* 5V regulator */
+ GPIO89_GPIO,
+};
+
+static struct regulator_consumer_supply max8649_supply[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data max8649_init_data = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 1150000,
+ .max_uV = 1280000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8649_supply[0],
+};
+
+static struct max8649_platform_data brownstone_max8649_info = {
+ .mode = 2, /* VID1 = 1, VID0 = 0 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8649_init_data,
+};
+
+static struct regulator_consumer_supply brownstone_v_5vp_supplies[] = {
+ REGULATOR_SUPPLY("v_5vp", NULL),
+};
+
+static struct regulator_init_data brownstone_v_5vp_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(brownstone_v_5vp_supplies),
+ .consumer_supplies = brownstone_v_5vp_supplies,
+};
+
+static struct fixed_voltage_config brownstone_v_5vp = {
+ .supply_name = "v_5vp",
+ .microvolts = 5000000,
+ .gpio = GPIO_5V_ENABLE,
+ .enable_high = 1,
+ .enabled_at_boot = 1,
+ .init_data = &brownstone_v_5vp_data,
+};
+
+static struct platform_device brownstone_v_5vp_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &brownstone_v_5vp,
+ },
+};
+
+static struct max8925_platform_data brownstone_max8925_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+static struct i2c_board_info brownstone_twsi1_info[] = {
+ [0] = {
+ .type = "max8649",
+ .addr = 0x60,
+ .platform_data = &brownstone_max8649_info,
+ },
+ [1] = {
+ .type = "max8925",
+ .addr = 0x3c,
+ .irq = IRQ_MMP2_PMIC,
+ .platform_data = &brownstone_max8925_info,
+ },
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
+ .max_speed = 25000000,
+};
+
+static void __init brownstone_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(3);
+ mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
+ mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+
+ /* enable 5v regulator */
+ platform_device_register(&brownstone_v_5vp_device);
+}
+
+MACHINE_START(BROWNSTONE, "Brownstone Development Platform")
+ /* Maintainer: Haojian Zhuang <haojian.zhuang@marvell.com> */
+ .map_io = mmp_map_io,
+ .nr_irqs = BROWNSTONE_NR_IRQS,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = brownstone_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 016ae94691c0..9b027d7491f5 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -6,7 +6,7 @@
* published by the Free Software Foundation.
*/
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
struct clkops {
void (*enable)(struct clk *);
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index bdeb6db4d49a..c4fd806b15b4 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -47,7 +47,7 @@ static unsigned long flint_pin_config[] __initdata = {
GPIO113_SMC_RDY,
/*Ethernet*/
- GPIO155_GPIO155,
+ GPIO155_GPIO,
/* DFI */
GPIO168_DFI_D0,
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
index 761c2dacc079..117e30366087 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
@@ -9,175 +9,175 @@
#define MFP_DRIVE_FAST (0x8 << 13)
/* GPIO */
-#define GPIO0_GPIO0 MFP_CFG(GPIO0, AF0)
-#define GPIO1_GPIO1 MFP_CFG(GPIO1, AF0)
-#define GPIO2_GPIO2 MFP_CFG(GPIO2, AF0)
-#define GPIO3_GPIO3 MFP_CFG(GPIO3, AF0)
-#define GPIO4_GPIO4 MFP_CFG(GPIO4, AF0)
-#define GPIO5_GPIO5 MFP_CFG(GPIO5, AF0)
-#define GPIO6_GPIO6 MFP_CFG(GPIO6, AF0)
-#define GPIO7_GPIO7 MFP_CFG(GPIO7, AF0)
-#define GPIO8_GPIO8 MFP_CFG(GPIO8, AF0)
-#define GPIO9_GPIO9 MFP_CFG(GPIO9, AF0)
-#define GPIO10_GPIO10 MFP_CFG(GPIO10, AF0)
-#define GPIO11_GPIO11 MFP_CFG(GPIO11, AF0)
-#define GPIO12_GPIO12 MFP_CFG(GPIO12, AF0)
-#define GPIO13_GPIO13 MFP_CFG(GPIO13, AF0)
-#define GPIO14_GPIO14 MFP_CFG(GPIO14, AF0)
-#define GPIO15_GPIO15 MFP_CFG(GPIO15, AF0)
-#define GPIO16_GPIO16 MFP_CFG(GPIO16, AF0)
-#define GPIO17_GPIO17 MFP_CFG(GPIO17, AF0)
-#define GPIO18_GPIO18 MFP_CFG(GPIO18, AF0)
-#define GPIO19_GPIO19 MFP_CFG(GPIO19, AF0)
-#define GPIO20_GPIO20 MFP_CFG(GPIO20, AF0)
-#define GPIO21_GPIO21 MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO22 MFP_CFG(GPIO22, AF0)
-#define GPIO23_GPIO23 MFP_CFG(GPIO23, AF0)
-#define GPIO24_GPIO24 MFP_CFG(GPIO24, AF0)
-#define GPIO25_GPIO25 MFP_CFG(GPIO25, AF0)
-#define GPIO26_GPIO26 MFP_CFG(GPIO26, AF0)
-#define GPIO27_GPIO27 MFP_CFG(GPIO27, AF0)
-#define GPIO28_GPIO28 MFP_CFG(GPIO28, AF0)
-#define GPIO29_GPIO29 MFP_CFG(GPIO29, AF0)
-#define GPIO30_GPIO30 MFP_CFG(GPIO30, AF0)
-#define GPIO31_GPIO31 MFP_CFG(GPIO31, AF0)
-#define GPIO32_GPIO32 MFP_CFG(GPIO32, AF0)
-#define GPIO33_GPIO33 MFP_CFG(GPIO33, AF0)
-#define GPIO34_GPIO34 MFP_CFG(GPIO34, AF0)
-#define GPIO35_GPIO35 MFP_CFG(GPIO35, AF0)
-#define GPIO36_GPIO36 MFP_CFG(GPIO36, AF0)
-#define GPIO37_GPIO37 MFP_CFG(GPIO37, AF0)
-#define GPIO38_GPIO38 MFP_CFG(GPIO38, AF0)
-#define GPIO39_GPIO39 MFP_CFG(GPIO39, AF0)
-#define GPIO40_GPIO40 MFP_CFG(GPIO40, AF0)
-#define GPIO41_GPIO41 MFP_CFG(GPIO41, AF0)
-#define GPIO42_GPIO42 MFP_CFG(GPIO42, AF0)
-#define GPIO43_GPIO43 MFP_CFG(GPIO43, AF0)
-#define GPIO44_GPIO44 MFP_CFG(GPIO44, AF0)
-#define GPIO45_GPIO45 MFP_CFG(GPIO45, AF0)
-#define GPIO46_GPIO46 MFP_CFG(GPIO46, AF0)
-#define GPIO47_GPIO47 MFP_CFG(GPIO47, AF0)
-#define GPIO48_GPIO48 MFP_CFG(GPIO48, AF0)
-#define GPIO49_GPIO49 MFP_CFG(GPIO49, AF0)
-#define GPIO50_GPIO50 MFP_CFG(GPIO50, AF0)
-#define GPIO51_GPIO51 MFP_CFG(GPIO51, AF0)
-#define GPIO52_GPIO52 MFP_CFG(GPIO52, AF0)
-#define GPIO53_GPIO53 MFP_CFG(GPIO53, AF0)
-#define GPIO54_GPIO54 MFP_CFG(GPIO54, 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)
-#define GPIO59_GPIO59 MFP_CFG(GPIO59, AF0)
-#define GPIO60_GPIO60 MFP_CFG(GPIO60, AF0)
-#define GPIO61_GPIO61 MFP_CFG(GPIO61, AF0)
-#define GPIO62_GPIO62 MFP_CFG(GPIO62, AF0)
-#define GPIO63_GPIO63 MFP_CFG(GPIO63, AF0)
-#define GPIO64_GPIO64 MFP_CFG(GPIO64, AF0)
-#define GPIO65_GPIO65 MFP_CFG(GPIO65, AF0)
-#define GPIO66_GPIO66 MFP_CFG(GPIO66, AF0)
-#define GPIO67_GPIO67 MFP_CFG(GPIO67, AF0)
-#define GPIO68_GPIO68 MFP_CFG(GPIO68, AF0)
-#define GPIO69_GPIO69 MFP_CFG(GPIO69, AF0)
-#define GPIO70_GPIO70 MFP_CFG(GPIO70, AF0)
-#define GPIO71_GPIO71 MFP_CFG(GPIO71, AF0)
-#define GPIO72_GPIO72 MFP_CFG(GPIO72, AF0)
-#define GPIO73_GPIO73 MFP_CFG(GPIO73, AF0)
-#define GPIO74_GPIO74 MFP_CFG(GPIO74, AF0)
-#define GPIO75_GPIO75 MFP_CFG(GPIO75, AF0)
-#define GPIO76_GPIO76 MFP_CFG(GPIO76, AF0)
-#define GPIO77_GPIO77 MFP_CFG(GPIO77, AF0)
-#define GPIO78_GPIO78 MFP_CFG(GPIO78, AF0)
-#define GPIO79_GPIO79 MFP_CFG(GPIO79, AF0)
-#define GPIO80_GPIO80 MFP_CFG(GPIO80, AF0)
-#define GPIO81_GPIO81 MFP_CFG(GPIO81, AF0)
-#define GPIO82_GPIO82 MFP_CFG(GPIO82, AF0)
-#define GPIO83_GPIO83 MFP_CFG(GPIO83, AF0)
-#define GPIO84_GPIO84 MFP_CFG(GPIO84, AF0)
-#define GPIO85_GPIO85 MFP_CFG(GPIO85, AF0)
-#define GPIO86_GPIO86 MFP_CFG(GPIO86, AF0)
-#define GPIO87_GPIO87 MFP_CFG(GPIO87, AF0)
-#define GPIO88_GPIO88 MFP_CFG(GPIO88, AF0)
-#define GPIO89_GPIO89 MFP_CFG(GPIO89, AF0)
-#define GPIO90_GPIO90 MFP_CFG(GPIO90, AF0)
-#define GPIO91_GPIO91 MFP_CFG(GPIO91, AF0)
-#define GPIO92_GPIO92 MFP_CFG(GPIO92, AF0)
-#define GPIO93_GPIO93 MFP_CFG(GPIO93, AF0)
-#define GPIO94_GPIO94 MFP_CFG(GPIO94, AF0)
-#define GPIO95_GPIO95 MFP_CFG(GPIO95, AF0)
-#define GPIO96_GPIO96 MFP_CFG(GPIO96, AF0)
-#define GPIO97_GPIO97 MFP_CFG(GPIO97, AF0)
-#define GPIO98_GPIO98 MFP_CFG(GPIO98, AF0)
-#define GPIO99_GPIO99 MFP_CFG(GPIO99, AF0)
-#define GPIO100_GPIO100 MFP_CFG(GPIO100, AF0)
-#define GPIO101_GPIO101 MFP_CFG(GPIO101, AF0)
-#define GPIO102_GPIO102 MFP_CFG(GPIO102, AF1)
-#define GPIO103_GPIO103 MFP_CFG(GPIO103, AF1)
-#define GPIO104_GPIO104 MFP_CFG(GPIO104, AF1)
-#define GPIO105_GPIO105 MFP_CFG(GPIO105, AF1)
-#define GPIO106_GPIO106 MFP_CFG(GPIO106, AF1)
-#define GPIO107_GPIO107 MFP_CFG(GPIO107, AF1)
-#define GPIO108_GPIO108 MFP_CFG(GPIO108, AF1)
-#define GPIO109_GPIO109 MFP_CFG(GPIO109, AF1)
-#define GPIO110_GPIO110 MFP_CFG(GPIO110, AF1)
-#define GPIO111_GPIO111 MFP_CFG(GPIO111, AF1)
-#define GPIO112_GPIO112 MFP_CFG(GPIO112, AF1)
-#define GPIO113_GPIO113 MFP_CFG(GPIO113, AF1)
-#define GPIO114_GPIO114 MFP_CFG(GPIO114, AF0)
-#define GPIO115_GPIO115 MFP_CFG(GPIO115, AF0)
-#define GPIO116_GPIO116 MFP_CFG(GPIO116, AF0)
-#define GPIO117_GPIO117 MFP_CFG(GPIO117, AF0)
-#define GPIO118_GPIO118 MFP_CFG(GPIO118, AF0)
-#define GPIO119_GPIO119 MFP_CFG(GPIO119, AF0)
-#define GPIO120_GPIO120 MFP_CFG(GPIO120, AF0)
-#define GPIO121_GPIO121 MFP_CFG(GPIO121, AF0)
-#define GPIO122_GPIO122 MFP_CFG(GPIO122, AF0)
-#define GPIO123_GPIO123 MFP_CFG(GPIO123, AF0)
-#define GPIO124_GPIO124 MFP_CFG(GPIO124, AF0)
-#define GPIO125_GPIO125 MFP_CFG(GPIO125, AF0)
-#define GPIO126_GPIO126 MFP_CFG(GPIO126, AF0)
-#define GPIO127_GPIO127 MFP_CFG(GPIO127, AF0)
-#define GPIO128_GPIO128 MFP_CFG(GPIO128, AF0)
-#define GPIO129_GPIO129 MFP_CFG(GPIO129, AF0)
-#define GPIO130_GPIO130 MFP_CFG(GPIO130, AF0)
-#define GPIO131_GPIO131 MFP_CFG(GPIO131, AF0)
-#define GPIO132_GPIO132 MFP_CFG(GPIO132, AF0)
-#define GPIO133_GPIO133 MFP_CFG(GPIO133, AF0)
-#define GPIO134_GPIO134 MFP_CFG(GPIO134, AF0)
-#define GPIO135_GPIO135 MFP_CFG(GPIO135, AF0)
-#define GPIO136_GPIO136 MFP_CFG(GPIO136, AF0)
-#define GPIO137_GPIO137 MFP_CFG(GPIO137, AF0)
-#define GPIO138_GPIO138 MFP_CFG(GPIO138, AF0)
-#define GPIO139_GPIO139 MFP_CFG(GPIO139, AF0)
-#define GPIO140_GPIO140 MFP_CFG(GPIO140, AF0)
-#define GPIO141_GPIO141 MFP_CFG(GPIO141, AF0)
-#define GPIO142_GPIO142 MFP_CFG(GPIO142, AF1)
-#define GPIO143_GPIO143 MFP_CFG(GPIO143, AF1)
-#define GPIO144_GPIO144 MFP_CFG(GPIO144, AF1)
-#define GPIO145_GPIO145 MFP_CFG(GPIO145, AF1)
-#define GPIO146_GPIO146 MFP_CFG(GPIO146, AF1)
-#define GPIO147_GPIO147 MFP_CFG(GPIO147, AF1)
-#define GPIO148_GPIO148 MFP_CFG(GPIO148, AF1)
-#define GPIO149_GPIO149 MFP_CFG(GPIO149, AF1)
-#define GPIO150_GPIO150 MFP_CFG(GPIO150, AF1)
-#define GPIO151_GPIO151 MFP_CFG(GPIO151, AF1)
-#define GPIO152_GPIO152 MFP_CFG(GPIO152, AF1)
-#define GPIO153_GPIO153 MFP_CFG(GPIO153, AF1)
-#define GPIO154_GPIO154 MFP_CFG(GPIO154, AF1)
-#define GPIO155_GPIO155 MFP_CFG(GPIO155, AF1)
-#define GPIO156_GPIO156 MFP_CFG(GPIO156, AF1)
-#define GPIO157_GPIO157 MFP_CFG(GPIO157, AF1)
-#define GPIO158_GPIO158 MFP_CFG(GPIO158, AF1)
-#define GPIO159_GPIO159 MFP_CFG(GPIO159, AF1)
-#define GPIO160_GPIO160 MFP_CFG(GPIO160, AF1)
-#define GPIO161_GPIO161 MFP_CFG(GPIO161, AF1)
-#define GPIO162_GPIO162 MFP_CFG(GPIO162, AF1)
-#define GPIO163_GPIO163 MFP_CFG(GPIO163, AF1)
-#define GPIO164_GPIO164 MFP_CFG(GPIO164, AF1)
-#define GPIO165_GPIO165 MFP_CFG(GPIO165, AF1)
-#define GPIO166_GPIO166 MFP_CFG(GPIO166, AF1)
-#define GPIO167_GPIO167 MFP_CFG(GPIO167, AF1)
-#define GPIO168_GPIO168 MFP_CFG(GPIO168, AF1)
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF1)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF1)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF1)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF1)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF1)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF1)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF1)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF1)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF1)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF1)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF1)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF1)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO MFP_CFG(GPIO127, AF0)
+#define GPIO128_GPIO MFP_CFG(GPIO128, AF0)
+#define GPIO129_GPIO MFP_CFG(GPIO129, AF0)
+#define GPIO130_GPIO MFP_CFG(GPIO130, AF0)
+#define GPIO131_GPIO MFP_CFG(GPIO131, AF0)
+#define GPIO132_GPIO MFP_CFG(GPIO132, AF0)
+#define GPIO133_GPIO MFP_CFG(GPIO133, AF0)
+#define GPIO134_GPIO MFP_CFG(GPIO134, AF0)
+#define GPIO135_GPIO MFP_CFG(GPIO135, AF0)
+#define GPIO136_GPIO MFP_CFG(GPIO136, AF0)
+#define GPIO137_GPIO MFP_CFG(GPIO137, AF0)
+#define GPIO138_GPIO MFP_CFG(GPIO138, AF0)
+#define GPIO139_GPIO MFP_CFG(GPIO139, AF0)
+#define GPIO140_GPIO MFP_CFG(GPIO140, AF0)
+#define GPIO141_GPIO MFP_CFG(GPIO141, AF0)
+#define GPIO142_GPIO MFP_CFG(GPIO142, AF1)
+#define GPIO143_GPIO MFP_CFG(GPIO143, AF1)
+#define GPIO144_GPIO MFP_CFG(GPIO144, AF1)
+#define GPIO145_GPIO MFP_CFG(GPIO145, AF1)
+#define GPIO146_GPIO MFP_CFG(GPIO146, AF1)
+#define GPIO147_GPIO MFP_CFG(GPIO147, AF1)
+#define GPIO148_GPIO MFP_CFG(GPIO148, AF1)
+#define GPIO149_GPIO MFP_CFG(GPIO149, AF1)
+#define GPIO150_GPIO MFP_CFG(GPIO150, AF1)
+#define GPIO151_GPIO MFP_CFG(GPIO151, AF1)
+#define GPIO152_GPIO MFP_CFG(GPIO152, AF1)
+#define GPIO153_GPIO MFP_CFG(GPIO153, AF1)
+#define GPIO154_GPIO MFP_CFG(GPIO154, AF1)
+#define GPIO155_GPIO MFP_CFG(GPIO155, AF1)
+#define GPIO156_GPIO MFP_CFG(GPIO156, AF1)
+#define GPIO157_GPIO MFP_CFG(GPIO157, AF1)
+#define GPIO158_GPIO MFP_CFG(GPIO158, AF1)
+#define GPIO159_GPIO MFP_CFG(GPIO159, AF1)
+#define GPIO160_GPIO MFP_CFG(GPIO160, AF1)
+#define GPIO161_GPIO MFP_CFG(GPIO161, AF1)
+#define GPIO162_GPIO MFP_CFG(GPIO162, AF1)
+#define GPIO163_GPIO MFP_CFG(GPIO163, AF1)
+#define GPIO164_GPIO MFP_CFG(GPIO164, AF1)
+#define GPIO165_GPIO MFP_CFG(GPIO165, AF1)
+#define GPIO166_GPIO MFP_CFG(GPIO166, AF1)
+#define GPIO167_GPIO MFP_CFG(GPIO167, AF1)
+#define GPIO168_GPIO MFP_CFG(GPIO168, AF1)
/* DFI */
#define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0)
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
index dbba6e8a60c4..4aec493640b4 100644
--- a/arch/arm/mach-mmp/include/mach/mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -1,6 +1,8 @@
#ifndef __ASM_MACH_MMP2_H
#define __ASM_MACH_MMP2_H
+#include <plat/sdhci.h>
+
struct sys_timer;
extern struct sys_timer mmp2_timer;
@@ -22,6 +24,10 @@ 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;
+extern struct pxa_device_desc mmp2_device_sdh0;
+extern struct pxa_device_desc mmp2_device_sdh1;
+extern struct pxa_device_desc mmp2_device_sdh2;
+extern struct pxa_device_desc mmp2_device_sdh3;
static inline int mmp2_add_uart(int id)
{
@@ -63,5 +69,21 @@ static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
return pxa_register_device(d, data, sizeof(*data));
}
+static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 0: d = &mmp2_device_sdh0; break;
+ case 1: d = &mmp2_device_sdh1; break;
+ case 2: d = &mmp2_device_sdh2; break;
+ case 3: d = &mmp2_device_sdh3; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
#endif /* __ASM_MACH_MMP2_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index ac4702357a6e..f7011ef70bf5 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -27,6 +27,8 @@
#define APMU_DMA APMU_REG(0x064)
#define APMU_GEU APMU_REG(0x068)
#define APMU_BUS APMU_REG(0x06c)
+#define APMU_SDH2 APMU_REG(0x0e8)
+#define APMU_SDH3 APMU_REG(0x0ec)
#define APMU_FNCLK_EN (1 << 4)
#define APMU_AXICLK_EN (1 << 3)
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index 2a684fa50773..24172a0aad59 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -67,6 +67,36 @@ static unsigned long jasper_pin_config[] __initdata = {
/* PMIC */
PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+
+ /* MMC1 */
+ GPIO131_MMC1_DAT3,
+ GPIO132_MMC1_DAT2,
+ GPIO133_MMC1_DAT1,
+ GPIO134_MMC1_DAT0,
+ GPIO136_MMC1_CMD,
+ GPIO139_MMC1_CLK,
+ GPIO140_MMC1_CD,
+ GPIO141_MMC1_WP,
+
+ /* MMC2 */
+ GPIO37_MMC2_DAT3,
+ GPIO38_MMC2_DAT2,
+ GPIO39_MMC2_DAT1,
+ GPIO40_MMC2_DAT0,
+ GPIO41_MMC2_CMD,
+ GPIO42_MMC2_CLK,
+
+ /* MMC3 */
+ GPIO165_MMC3_DAT7,
+ GPIO162_MMC3_DAT6,
+ GPIO166_MMC3_DAT5,
+ GPIO163_MMC3_DAT4,
+ GPIO167_MMC3_DAT3,
+ GPIO164_MMC3_DAT2,
+ GPIO168_MMC3_DAT1,
+ GPIO111_MMC3_DAT0,
+ GPIO112_MMC3_CMD,
+ GPIO151_MMC3_CLK,
};
static struct regulator_consumer_supply max8649_supply[] = {
@@ -123,6 +153,10 @@ static struct i2c_board_info jasper_twsi1_info[] = {
},
};
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
+ .max_speed = 25000000,
+};
+
static void __init jasper_init(void)
{
mfp_config(ARRAY_AND_SIZE(jasper_pin_config));
@@ -131,6 +165,7 @@ static void __init jasper_init(void)
mmp2_add_uart(1);
mmp2_add_uart(3);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info));
+ mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
regulator_has_full_constraints();
}
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index daf3993349f8..8e6c3ac7f7c1 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -115,6 +115,29 @@ void __init mmp2_init_irq(void)
mmp2_init_gpio();
}
+static void sdhc_clk_enable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = __raw_readl(clk->clk_rst);
+ clk_rst |= clk->enable_val;
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+static void sdhc_clk_disable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = __raw_readl(clk->clk_rst);
+ clk_rst &= ~clk->enable_val;
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+struct clkops sdhc_clk_ops = {
+ .enable = sdhc_clk_enable,
+ .disable = sdhc_clk_disable,
+};
+
/* APB peripheral clocks */
static APBC_CLK(uart1, MMP2_UART1, 1, 26000000);
static APBC_CLK(uart2, MMP2_UART2, 1, 26000000);
@@ -126,9 +149,12 @@ 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 APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh1, SDH1, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH2, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH3, 0x1b, 200000000, &sdhc_clk_ops);
static struct clk_lookup mmp2_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -142,6 +168,10 @@ static struct clk_lookup mmp2_clkregs[] = {
INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_sdh0, "sdhci-pxa.0", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh1, "sdhci-pxa.1", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh2, "sdhci-pxa.2", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh3, "sdhci-pxa.3", "PXA-SDHCLK"),
};
static int __init mmp2_init(void)
@@ -192,4 +222,8 @@ 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);
+MMP2_DEVICE(sdh0, "sdhci-pxa", 0, MMC, 0xd4280000, 0x120);
+MMP2_DEVICE(sdh1, "sdhci-pxa", 1, MMC2, 0xd4280800, 0x120);
+MMP2_DEVICE(sdh2, "sdhci-pxa", 2, MMC3, 0xd4281000, 0x120);
+MMP2_DEVICE(sdh3, "sdhci-pxa", 3, MMC4, 0xd4281800, 0x120);
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 46f2d69bef3c..8f92ccd26edf 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -111,6 +111,7 @@ static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(u2o, USB, 0x1b, 480000000);
/* device and clock bindings */
static struct clk_lookup pxa910_clkregs[] = {
@@ -123,6 +124,7 @@ static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
};
static int __init pxa910_init(void)
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 66528193f939..aeb9ae23e6ce 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -26,8 +26,8 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/sched.h>
-#include <linux/cnt32_to_63.h>
+#include <asm/sched_clock.h>
#include <mach/addr-map.h>
#include <mach/regs-timers.h>
#include <mach/regs-apbc.h>
@@ -42,23 +42,7 @@
#define MAX_DELTA (0xfffffffe)
#define MIN_DELTA (16)
-#define TCR2NS_SCALE_FACTOR 10
-
-static unsigned long tcr2ns_scale;
-
-static void __init set_tcr2ns_scale(unsigned long tcr_rate)
-{
- unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR;
- do_div(v, tcr_rate);
- tcr2ns_scale = v;
- /*
- * We want an even value to automatically clear the top bit
- * returned by cnt32_to_63() without an additional run time
- * instruction. So if the LSB is 1 then round it up.
- */
- if (tcr2ns_scale & 1)
- tcr2ns_scale++;
-}
+static DEFINE_CLOCK_DATA(cd);
/*
* FIXME: the timer needs some delay to stablize the counter capture
@@ -75,10 +59,16 @@ static inline uint32_t timer_read(void)
return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0));
}
-unsigned long long sched_clock(void)
+unsigned long long notrace sched_clock(void)
{
- unsigned long long v = cnt32_to_63(timer_read());
- return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR;
+ u32 cyc = timer_read();
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mmp_update_sched_clock(void)
+{
+ u32 cyc = timer_read();
+ update_sched_clock(&cd, cyc, (u32)~0);
}
static irqreturn_t timer_interrupt(int irq, void *dev_id)
@@ -146,7 +136,6 @@ static cycle_t clksrc_read(struct clocksource *cs)
static struct clocksource cksrc = {
.name = "clocksource",
- .shift = 20,
.rating = 200,
.read = clksrc_read,
.mask = CLOCKSOURCE_MASK(32),
@@ -186,17 +175,15 @@ void __init timer_init(int irq)
{
timer_config();
- set_tcr2ns_scale(CLOCK_TICK_RATE);
+ init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE);
ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt);
ckevt.cpumask = cpumask_of(0);
- cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift);
-
setup_irq(irq, &timer_irq);
- clocksource_register(&cksrc);
+ clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
clockevents_register_device(&ckevt);
}
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index dbbcfeb919db..fae931ac2e56 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -44,11 +44,14 @@ config ARCH_MSM8X60
select CPU_V7
select MSM_V2_TLMM
select MSM_GPIOMUX
+ select IOMMU_API
endchoice
config MSM_SOC_REV_A
bool
+config ARCH_MSM_SCORPIONMP
+ bool
config ARCH_MSM_ARM11
bool
@@ -122,6 +125,10 @@ config MACH_MSM8X60_FFA
endmenu
+config IOMMU_PGTABLES_L2
+ def_bool y
+ depends on ARCH_MSM8X60 && MMU && SMP && CPU_DCACHE_DISABLE=n
+
config MSM_DEBUG_UART
int
default 1 if MSM_DEBUG_UART1
@@ -162,4 +169,7 @@ config MSM_GPIOMUX
config MSM_V2_TLMM
bool
+
+config IOMMU_API
+ bool
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b5a7b07a44f5..59646bbd6195 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
+obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
@@ -28,6 +29,8 @@ obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
-ifndef CONFIG_MSM_V2_TLMM
+ifdef CONFIG_MSM_V2_TLMM
+obj-y += gpio-v2.o
+else
obj-y += gpio.o
endif
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 05241df3f9b6..6f3b9735e970 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/smsc911x.h>
+#include <linux/usb/msm_hsusb.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -39,11 +40,26 @@
extern struct sys_timer msm_timer;
+static int hsusb_phy_init_seq[] = {
+ 0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */
+ 0x02, 0x36, /* Disable CDR Auto Reset feature */
+ -1
+};
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+ .phy_init_seq = hsusb_phy_init_seq,
+ .mode = USB_PERIPHERAL,
+ .otg_control = OTG_PHY_CONTROL,
+};
+
static struct platform_device *devices[] __initdata = {
#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
&msm_device_uart2,
#endif
&msm_device_smd,
+ &msm_device_otg,
+ &msm_device_hsusb,
+ &msm_device_hsusb_host,
};
static void __init msm7x30_init_irq(void)
@@ -53,6 +69,10 @@ static void __init msm7x30_init_irq(void)
static void __init msm7x30_init(void)
{
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_hsusb.dev.parent = &msm_device_otg.dev;
+ msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
+
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 7486a681cc71..9b5eb2b4ae1b 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -28,8 +28,6 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
-void __iomem *gic_cpu_base_addr;
-
unsigned long clk_get_max_axi_khz(void)
{
return 0;
@@ -44,9 +42,8 @@ static void __init msm8x60_init_irq(void)
{
unsigned int i;
- gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START);
- gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE;
- gic_cpu_init(0, MSM_QGIC_CPU_BASE);
+ gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+ (void *)MSM_QGIC_CPU_BASE);
/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index ed2af4ad97ed..2e8391307f55 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -20,6 +20,7 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/usb/msm_hsusb.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -74,9 +75,24 @@ static int __init msm_init_smc91x(void)
}
module_init(msm_init_smc91x);
+static int hsusb_phy_init_seq[] = {
+ 0x08, 0x31, /* Increase HS Driver Amplitude */
+ 0x20, 0x32, /* Enable and set Pre-Emphasis Depth to 10% */
+ -1
+};
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+ .phy_init_seq = hsusb_phy_init_seq,
+ .mode = USB_PERIPHERAL,
+ .otg_control = OTG_PHY_CONTROL,
+};
+
static struct platform_device *devices[] __initdata = {
&msm_device_uart3,
&msm_device_smd,
+ &msm_device_otg,
+ &msm_device_hsusb,
+ &msm_device_hsusb_host,
};
static void __init qsd8x50_map_io(void)
@@ -93,6 +109,9 @@ static void __init qsd8x50_init_irq(void)
static void __init qsd8x50_init(void)
{
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_hsusb.dev.parent = &msm_device_otg.dev;
+ msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c
index c50f3afc3134..f8c09ef6666f 100644
--- a/arch/arm/mach-msm/board-trout-gpio.c
+++ b/arch/arm/mach-msm/board-trout-gpio.c
@@ -72,6 +72,13 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip,
return 0;
}
+static int trout_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
+
+ return TROUT_GPIO_TO_INT(offset + chip->base);
+}
+
#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
{ \
.chip = { \
@@ -80,6 +87,7 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip,
.direction_output = msm_gpiolib_direction_output, \
.get = msm_gpiolib_get, \
.set = msm_gpiolib_set, \
+ .to_irq = trout_gpio_to_irq, \
.base = base_gpio, \
.ngpio = 8, \
}, \
diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c
new file mode 100644
index 000000000000..729bb49a44ca
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-panel.c
@@ -0,0 +1,297 @@
+/* linux/arch/arm/mach-msm/board-trout-mddi.c
+** Author: Brian Swetland <swetland@google.com>
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/mach-types.h>
+
+#include <mach/msm_fb.h>
+#include <mach/vreg.h>
+
+#include "board-trout.h"
+#include "proc_comm.h"
+#include "devices.h"
+
+#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255
+
+#define MDDI_CLIENT_CORE_BASE 0x108000
+#define LCD_CONTROL_BLOCK_BASE 0x110000
+#define SPI_BLOCK_BASE 0x120000
+#define I2C_BLOCK_BASE 0x130000
+#define PWM_BLOCK_BASE 0x140000
+#define GPIO_BLOCK_BASE 0x150000
+#define SYSTEM_BLOCK1_BASE 0x160000
+#define SYSTEM_BLOCK2_BASE 0x170000
+
+
+#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
+#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)
+#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
+
+#define V_VDDE2E_VDD2_GPIO 0
+#define MDDI_RST_N 82
+
+#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
+#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
+#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
+#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
+#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
+#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
+#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
+#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
+#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
+#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
+#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
+#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
+#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
+#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
+#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
+#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
+#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
+#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
+#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
+#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
+#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
+#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
+
+#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
+#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
+#define START (LCD_CONTROL_BLOCK_BASE|0x08)
+#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
+#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
+#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
+#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
+#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
+#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
+#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
+#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
+#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
+#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
+#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
+#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
+#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
+#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
+#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
+#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
+#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
+#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
+#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
+#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
+#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
+#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
+#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
+#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
+#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
+#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
+#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
+#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
+#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
+#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
+#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
+#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
+
+#define SSICTL (SPI_BLOCK_BASE|0x00)
+#define SSITIME (SPI_BLOCK_BASE|0x04)
+#define SSITX (SPI_BLOCK_BASE|0x08)
+#define SSIRX (SPI_BLOCK_BASE|0x0C)
+#define SSIINTC (SPI_BLOCK_BASE|0x10)
+#define SSIINTS (SPI_BLOCK_BASE|0x14)
+#define SSIDBG1 (SPI_BLOCK_BASE|0x18)
+#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
+#define SSIID (SPI_BLOCK_BASE|0x20)
+
+#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
+#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
+#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
+#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
+#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
+
+#define GPIODATA (GPIO_BLOCK_BASE|0x00)
+#define GPIODIR (GPIO_BLOCK_BASE|0x04)
+#define GPIOIS (GPIO_BLOCK_BASE|0x08)
+#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
+#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
+#define GPIOIE (GPIO_BLOCK_BASE|0x14)
+#define GPIORIS (GPIO_BLOCK_BASE|0x18)
+#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
+#define GPIOIC (GPIO_BLOCK_BASE|0x20)
+#define GPIOOMS (GPIO_BLOCK_BASE|0x24)
+#define GPIOPC (GPIO_BLOCK_BASE|0x28)
+#define GPIOID (GPIO_BLOCK_BASE|0x30)
+
+#define SPI_WRITE(reg, val) \
+ { SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
+ { 0, 5 },
+
+#define SPI_WRITE1(reg) \
+ { SSITX, (reg) & 0xff }, \
+ { 0, 5 },
+
+struct mddi_table {
+ uint32_t reg;
+ uint32_t value;
+};
+static struct mddi_table mddi_toshiba_init_table[] = {
+ { DPSET0, 0x09e90046 },
+ { DPSET1, 0x00000118 },
+ { DPSUS, 0x00000000 },
+ { DPRUN, 0x00000001 },
+ { 1, 14 }, /* msleep 14 */
+ { SYSCKENA, 0x00000001 },
+ { CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */
+
+ { GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
+ { GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */
+ { GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */
+ { GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */
+ { WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */
+
+ { GPIOIBE, 0x000003FF },
+ { GPIOIS, 0x00000000 },
+ { GPIOIC, 0x000003FF },
+ { GPIOIE, 0x00000000 },
+
+ { GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
+ { 1, 1 }, /* msleep 1 */
+ { GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
+ { DRAMPWR, 0x00000001 }, /* eDRAM power */
+};
+
+#define GPIOSEL_VWAKEINT (1U << 0)
+#define INTMASK_VWAKEOUT (1U << 0)
+
+
+static struct clk *gp_clk;
+static int trout_new_backlight = 1;
+static struct vreg *vreg_mddi_1v5;
+static struct vreg *vreg_lcm_2v85;
+
+static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,
+ struct mddi_table *table, size_t count)
+{
+ int i;
+ for (i = 0; i < count; i++) {
+ uint32_t reg = table[i].reg;
+ uint32_t value = table[i].value;
+
+ if (reg == 0)
+ udelay(value);
+ else if (reg == 1)
+ msleep(value);
+ else
+ client_data->remote_write(client_data, value, reg);
+ }
+}
+
+static int trout_mddi_toshiba_client_init(
+ struct msm_mddi_bridge_platform_data *bridge_data,
+ struct msm_mddi_client_data *client_data)
+{
+ int panel_id;
+
+ client_data->auto_hibernate(client_data, 0);
+ trout_process_mddi_table(client_data, mddi_toshiba_init_table,
+ ARRAY_SIZE(mddi_toshiba_init_table));
+ client_data->auto_hibernate(client_data, 1);
+ panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
+ if (panel_id > 1) {
+ printk(KERN_WARNING "unknown panel id at mddi_enable\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int trout_mddi_toshiba_client_uninit(
+ struct msm_mddi_bridge_platform_data *bridge_data,
+ struct msm_mddi_client_data *client_data)
+{
+ return 0;
+}
+
+static struct resource resources_msm_fb[] = {
+ {
+ .start = MSM_FB_BASE,
+ .end = MSM_FB_BASE + MSM_FB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct msm_mddi_bridge_platform_data toshiba_client_data = {
+ .init = trout_mddi_toshiba_client_init,
+ .uninit = trout_mddi_toshiba_client_uninit,
+ .fb_data = {
+ .xres = 320,
+ .yres = 480,
+ .width = 45,
+ .height = 67,
+ .output_format = 0,
+ },
+};
+
+static struct msm_mddi_platform_data mddi_pdata = {
+ .clk_rate = 122880000,
+ .fb_resource = resources_msm_fb,
+ .num_clients = 1,
+ .client_platform_data = {
+ {
+ .product_id = (0xd263 << 16 | 0),
+ .name = "mddi_c_d263_0000",
+ .id = 0,
+ .client_data = &toshiba_client_data,
+ .clk_rate = 0,
+ },
+ },
+};
+
+int __init trout_init_panel(void)
+{
+ int rc;
+
+ if (!machine_is_trout())
+ return 0;
+ vreg_mddi_1v5 = vreg_get(0, "gp2");
+ if (IS_ERR(vreg_mddi_1v5))
+ return PTR_ERR(vreg_mddi_1v5);
+ vreg_lcm_2v85 = vreg_get(0, "gp4");
+ if (IS_ERR(vreg_lcm_2v85))
+ return PTR_ERR(vreg_lcm_2v85);
+
+ trout_new_backlight = system_rev >= 5;
+ if (trout_new_backlight) {
+ uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,
+ GPIO_NO_PULL, GPIO_8MA);
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
+ } else {
+ uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
+ GPIO_NO_PULL, GPIO_8MA);
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
+
+ gp_clk = clk_get(NULL, "gp_clk");
+ if (IS_ERR(gp_clk)) {
+ printk(KERN_ERR "trout_init_panel: could not get gp"
+ "clock\n");
+ gp_clk = NULL;
+ }
+ rc = clk_set_rate(gp_clk, 19200000);
+ if (rc)
+ printk(KERN_ERR "trout_init_panel: set clock rate "
+ "failed\n");
+ }
+
+ rc = platform_device_register(&msm_device_mdp);
+ if (rc)
+ return rc;
+ msm_device_mddi0.dev.platform_data = &mddi_pdata;
+ return platform_device_register(&msm_device_mddi0);
+}
+
+device_initcall(trout_init_panel);
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c57210f4f06a..2069bfaa3a26 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -120,6 +120,21 @@ EXPORT_SYMBOL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ int ret;
+ if (clk->flags & CLKFLAG_MAX) {
+ ret = clk->ops->set_max_rate(clk->id, rate);
+ if (ret)
+ return ret;
+ }
+ if (clk->flags & CLKFLAG_MIN) {
+ ret = clk->ops->set_min_rate(clk->id, rate);
+ if (ret)
+ return ret;
+ }
+
+ if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN)
+ return ret;
+
return clk->ops->set_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
index 4e8c0bcdc92d..fb548a8a21db 100644
--- a/arch/arm/mach-msm/devices-msm7x00.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -347,6 +347,73 @@ int __init msm_add_sdcc(unsigned int controller,
return platform_device_register(pdev);
}
+static struct resource resources_mddi0[] = {
+ {
+ .start = MSM_PMDH_PHYS,
+ .end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MDDI_PRI,
+ .end = INT_MDDI_PRI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource resources_mddi1[] = {
+ {
+ .start = MSM_EMDH_PHYS,
+ .end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MDDI_EXT,
+ .end = INT_MDDI_EXT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_mddi0 = {
+ .name = "msm_mddi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_mddi0),
+ .resource = resources_mddi0,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_mddi1 = {
+ .name = "msm_mddi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_mddi1),
+ .resource = resources_mddi1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_mdp[] = {
+ {
+ .start = MSM_MDP_PHYS,
+ .end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1,
+ .name = "mdp",
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = INT_MDP,
+ .end = INT_MDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_mdp = {
+ .name = "msm_mdp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_mdp),
+ .resource = resources_mdp,
+};
+
struct clk msm_clocks_7x01a[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
@@ -364,7 +431,7 @@ struct clk msm_clocks_7x01a[] = {
CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
- CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ),
+ CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF),
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 7fcf2e3b7698..4e9a0ab3e937 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -56,6 +56,77 @@ struct platform_device msm_device_smd = {
.id = -1,
};
+static struct resource resources_otg[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_otg = {
+ .name = "msm_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_otg),
+ .resource = resources_otg,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_hsusb[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb = {
+ .name = "msm_hsusb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb),
+ .resource = resources_hsusb,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static u64 dma_mask = 0xffffffffULL;
+static struct resource resources_hsusb_host[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb_host = {
+ .name = "msm_hsusb_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb_host),
+ .resource = resources_hsusb_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffffULL,
+ },
+};
+
struct clk msm_clocks_7x30[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
@@ -107,6 +178,7 @@ struct clk msm_clocks_7x30[] = {
CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
+ CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF),
diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c
index 89b9d4437e92..f9e7bd34ec59 100644
--- a/arch/arm/mach-msm/devices-msm8x60-iommu.c
+++ b/arch/arm/mach-msm/devices-msm8x60-iommu.c
@@ -254,60 +254,86 @@ static struct resource msm_iommu_gfx2d0_resources[] = {
},
};
+static struct resource msm_iommu_gfx2d1_resources[] = {
+ {
+ .start = MSM_IOMMU_GFX2D1_PHYS,
+ .end = MSM_IOMMU_GFX2D1_PHYS + MSM_IOMMU_GFX2D1_SIZE - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct platform_device msm_root_iommu_dev = {
.name = "msm_iommu",
.id = -1,
};
-static struct msm_iommu_dev jpegd_smmu = {
+static struct msm_iommu_dev jpegd_iommu = {
.name = "jpegd",
.clk_rate = -1
};
-static struct msm_iommu_dev vpe_smmu = {
+static struct msm_iommu_dev vpe_iommu = {
.name = "vpe"
};
-static struct msm_iommu_dev mdp0_smmu = {
+static struct msm_iommu_dev mdp0_iommu = {
.name = "mdp0"
};
-static struct msm_iommu_dev mdp1_smmu = {
+static struct msm_iommu_dev mdp1_iommu = {
.name = "mdp1"
};
-static struct msm_iommu_dev rot_smmu = {
+static struct msm_iommu_dev rot_iommu = {
.name = "rot"
};
-static struct msm_iommu_dev ijpeg_smmu = {
+static struct msm_iommu_dev ijpeg_iommu = {
.name = "ijpeg"
};
-static struct msm_iommu_dev vfe_smmu = {
+static struct msm_iommu_dev vfe_iommu = {
.name = "vfe",
.clk_rate = -1
};
-static struct msm_iommu_dev vcodec_a_smmu = {
+static struct msm_iommu_dev vcodec_a_iommu = {
.name = "vcodec_a"
};
-static struct msm_iommu_dev vcodec_b_smmu = {
+static struct msm_iommu_dev vcodec_b_iommu = {
.name = "vcodec_b"
};
-static struct msm_iommu_dev gfx3d_smmu = {
+static struct msm_iommu_dev gfx3d_iommu = {
.name = "gfx3d",
.clk_rate = 27000000
};
-static struct msm_iommu_dev gfx2d0_smmu = {
+static struct msm_iommu_dev gfx2d0_iommu = {
.name = "gfx2d0",
.clk_rate = 27000000
};
-static struct platform_device msm_device_smmu_jpegd = {
+static struct msm_iommu_dev gfx2d1_iommu = {
+ .name = "gfx2d1",
+ .clk_rate = 27000000
+};
+
+static struct platform_device msm_device_iommu_jpegd = {
.name = "msm_iommu",
.id = 0,
.dev = {
@@ -317,7 +343,7 @@ static struct platform_device msm_device_smmu_jpegd = {
.resource = msm_iommu_jpegd_resources,
};
-static struct platform_device msm_device_smmu_vpe = {
+static struct platform_device msm_device_iommu_vpe = {
.name = "msm_iommu",
.id = 1,
.dev = {
@@ -327,7 +353,7 @@ static struct platform_device msm_device_smmu_vpe = {
.resource = msm_iommu_vpe_resources,
};
-static struct platform_device msm_device_smmu_mdp0 = {
+static struct platform_device msm_device_iommu_mdp0 = {
.name = "msm_iommu",
.id = 2,
.dev = {
@@ -337,7 +363,7 @@ static struct platform_device msm_device_smmu_mdp0 = {
.resource = msm_iommu_mdp0_resources,
};
-static struct platform_device msm_device_smmu_mdp1 = {
+static struct platform_device msm_device_iommu_mdp1 = {
.name = "msm_iommu",
.id = 3,
.dev = {
@@ -347,7 +373,7 @@ static struct platform_device msm_device_smmu_mdp1 = {
.resource = msm_iommu_mdp1_resources,
};
-static struct platform_device msm_device_smmu_rot = {
+static struct platform_device msm_device_iommu_rot = {
.name = "msm_iommu",
.id = 4,
.dev = {
@@ -357,7 +383,7 @@ static struct platform_device msm_device_smmu_rot = {
.resource = msm_iommu_rot_resources,
};
-static struct platform_device msm_device_smmu_ijpeg = {
+static struct platform_device msm_device_iommu_ijpeg = {
.name = "msm_iommu",
.id = 5,
.dev = {
@@ -367,7 +393,7 @@ static struct platform_device msm_device_smmu_ijpeg = {
.resource = msm_iommu_ijpeg_resources,
};
-static struct platform_device msm_device_smmu_vfe = {
+static struct platform_device msm_device_iommu_vfe = {
.name = "msm_iommu",
.id = 6,
.dev = {
@@ -377,7 +403,7 @@ static struct platform_device msm_device_smmu_vfe = {
.resource = msm_iommu_vfe_resources,
};
-static struct platform_device msm_device_smmu_vcodec_a = {
+static struct platform_device msm_device_iommu_vcodec_a = {
.name = "msm_iommu",
.id = 7,
.dev = {
@@ -387,7 +413,7 @@ static struct platform_device msm_device_smmu_vcodec_a = {
.resource = msm_iommu_vcodec_a_resources,
};
-static struct platform_device msm_device_smmu_vcodec_b = {
+static struct platform_device msm_device_iommu_vcodec_b = {
.name = "msm_iommu",
.id = 8,
.dev = {
@@ -397,7 +423,7 @@ static struct platform_device msm_device_smmu_vcodec_b = {
.resource = msm_iommu_vcodec_b_resources,
};
-static struct platform_device msm_device_smmu_gfx3d = {
+static struct platform_device msm_device_iommu_gfx3d = {
.name = "msm_iommu",
.id = 9,
.dev = {
@@ -407,7 +433,7 @@ static struct platform_device msm_device_smmu_gfx3d = {
.resource = msm_iommu_gfx3d_resources,
};
-static struct platform_device msm_device_smmu_gfx2d0 = {
+static struct platform_device msm_device_iommu_gfx2d0 = {
.name = "msm_iommu",
.id = 10,
.dev = {
@@ -417,6 +443,16 @@ static struct platform_device msm_device_smmu_gfx2d0 = {
.resource = msm_iommu_gfx2d0_resources,
};
+struct platform_device msm_device_iommu_gfx2d1 = {
+ .name = "msm_iommu",
+ .id = 11,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources),
+ .resource = msm_iommu_gfx2d1_resources,
+};
+
static struct msm_iommu_ctx_dev jpegd_src_ctx = {
.name = "jpegd_src",
.num = 0,
@@ -519,41 +555,36 @@ static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
.mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
};
-static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = {
- .name = "gfx3d_rbpa",
+static struct msm_iommu_ctx_dev gfx3d_user_ctx = {
+ .name = "gfx3d_user",
.num = 0,
- .mids = {-1}
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
};
-static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = {
- .name = "gfx3d_cpvgttc",
+static struct msm_iommu_ctx_dev gfx3d_priv_ctx = {
+ .name = "gfx3d_priv",
.num = 1,
- .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
-};
-
-static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = {
- .name = "gfx3d_smmu",
- .num = 2,
- .mids = {8, 9, 10, 11, 12, -1}
+ .mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, -1}
};
-static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = {
- .name = "gfx2d0_pixv1_smmu",
+static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
+ .name = "gfx2d0_2d0",
.num = 0,
- .mids = {0, 3, 4, -1}
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
};
-static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = {
- .name = "gfx2d0_texv3_smmu",
- .num = 1,
- .mids = {1, 6, 7, -1}
+static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = {
+ .name = "gfx2d1_2d1",
+ .num = 0,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
};
static struct platform_device msm_device_jpegd_src_ctx = {
.name = "msm_iommu_ctx",
.id = 0,
.dev = {
- .parent = &msm_device_smmu_jpegd.dev,
+ .parent = &msm_device_iommu_jpegd.dev,
},
};
@@ -561,7 +592,7 @@ static struct platform_device msm_device_jpegd_dst_ctx = {
.name = "msm_iommu_ctx",
.id = 1,
.dev = {
- .parent = &msm_device_smmu_jpegd.dev,
+ .parent = &msm_device_iommu_jpegd.dev,
},
};
@@ -569,7 +600,7 @@ static struct platform_device msm_device_vpe_src_ctx = {
.name = "msm_iommu_ctx",
.id = 2,
.dev = {
- .parent = &msm_device_smmu_vpe.dev,
+ .parent = &msm_device_iommu_vpe.dev,
},
};
@@ -577,7 +608,7 @@ static struct platform_device msm_device_vpe_dst_ctx = {
.name = "msm_iommu_ctx",
.id = 3,
.dev = {
- .parent = &msm_device_smmu_vpe.dev,
+ .parent = &msm_device_iommu_vpe.dev,
},
};
@@ -585,7 +616,7 @@ static struct platform_device msm_device_mdp_vg1_ctx = {
.name = "msm_iommu_ctx",
.id = 4,
.dev = {
- .parent = &msm_device_smmu_mdp0.dev,
+ .parent = &msm_device_iommu_mdp0.dev,
},
};
@@ -593,7 +624,7 @@ static struct platform_device msm_device_mdp_rgb1_ctx = {
.name = "msm_iommu_ctx",
.id = 5,
.dev = {
- .parent = &msm_device_smmu_mdp0.dev,
+ .parent = &msm_device_iommu_mdp0.dev,
},
};
@@ -601,7 +632,7 @@ static struct platform_device msm_device_mdp_vg2_ctx = {
.name = "msm_iommu_ctx",
.id = 6,
.dev = {
- .parent = &msm_device_smmu_mdp1.dev,
+ .parent = &msm_device_iommu_mdp1.dev,
},
};
@@ -609,7 +640,7 @@ static struct platform_device msm_device_mdp_rgb2_ctx = {
.name = "msm_iommu_ctx",
.id = 7,
.dev = {
- .parent = &msm_device_smmu_mdp1.dev,
+ .parent = &msm_device_iommu_mdp1.dev,
},
};
@@ -617,7 +648,7 @@ static struct platform_device msm_device_rot_src_ctx = {
.name = "msm_iommu_ctx",
.id = 8,
.dev = {
- .parent = &msm_device_smmu_rot.dev,
+ .parent = &msm_device_iommu_rot.dev,
},
};
@@ -625,7 +656,7 @@ static struct platform_device msm_device_rot_dst_ctx = {
.name = "msm_iommu_ctx",
.id = 9,
.dev = {
- .parent = &msm_device_smmu_rot.dev,
+ .parent = &msm_device_iommu_rot.dev,
},
};
@@ -633,7 +664,7 @@ static struct platform_device msm_device_ijpeg_src_ctx = {
.name = "msm_iommu_ctx",
.id = 10,
.dev = {
- .parent = &msm_device_smmu_ijpeg.dev,
+ .parent = &msm_device_iommu_ijpeg.dev,
},
};
@@ -641,7 +672,7 @@ static struct platform_device msm_device_ijpeg_dst_ctx = {
.name = "msm_iommu_ctx",
.id = 11,
.dev = {
- .parent = &msm_device_smmu_ijpeg.dev,
+ .parent = &msm_device_iommu_ijpeg.dev,
},
};
@@ -649,7 +680,7 @@ static struct platform_device msm_device_vfe_imgwr_ctx = {
.name = "msm_iommu_ctx",
.id = 12,
.dev = {
- .parent = &msm_device_smmu_vfe.dev,
+ .parent = &msm_device_iommu_vfe.dev,
},
};
@@ -657,7 +688,7 @@ static struct platform_device msm_device_vfe_misc_ctx = {
.name = "msm_iommu_ctx",
.id = 13,
.dev = {
- .parent = &msm_device_smmu_vfe.dev,
+ .parent = &msm_device_iommu_vfe.dev,
},
};
@@ -665,7 +696,7 @@ static struct platform_device msm_device_vcodec_a_stream_ctx = {
.name = "msm_iommu_ctx",
.id = 14,
.dev = {
- .parent = &msm_device_smmu_vcodec_a.dev,
+ .parent = &msm_device_iommu_vcodec_a.dev,
},
};
@@ -673,7 +704,7 @@ static struct platform_device msm_device_vcodec_a_mm1_ctx = {
.name = "msm_iommu_ctx",
.id = 15,
.dev = {
- .parent = &msm_device_smmu_vcodec_a.dev,
+ .parent = &msm_device_iommu_vcodec_a.dev,
},
};
@@ -681,76 +712,70 @@ static struct platform_device msm_device_vcodec_b_mm2_ctx = {
.name = "msm_iommu_ctx",
.id = 16,
.dev = {
- .parent = &msm_device_smmu_vcodec_b.dev,
+ .parent = &msm_device_iommu_vcodec_b.dev,
},
};
-static struct platform_device msm_device_gfx3d_rbpa_ctx = {
+static struct platform_device msm_device_gfx3d_user_ctx = {
.name = "msm_iommu_ctx",
.id = 17,
.dev = {
- .parent = &msm_device_smmu_gfx3d.dev,
+ .parent = &msm_device_iommu_gfx3d.dev,
},
};
-static struct platform_device msm_device_gfx3d_cpvgttc_ctx = {
+static struct platform_device msm_device_gfx3d_priv_ctx = {
.name = "msm_iommu_ctx",
.id = 18,
.dev = {
- .parent = &msm_device_smmu_gfx3d.dev,
+ .parent = &msm_device_iommu_gfx3d.dev,
},
};
-static struct platform_device msm_device_gfx3d_smmu_ctx = {
+static struct platform_device msm_device_gfx2d0_2d0_ctx = {
.name = "msm_iommu_ctx",
.id = 19,
.dev = {
- .parent = &msm_device_smmu_gfx3d.dev,
+ .parent = &msm_device_iommu_gfx2d0.dev,
},
};
-static struct platform_device msm_device_gfx2d0_pixv1_ctx = {
+static struct platform_device msm_device_gfx2d1_2d1_ctx = {
.name = "msm_iommu_ctx",
.id = 20,
.dev = {
- .parent = &msm_device_smmu_gfx2d0.dev,
- },
-};
-
-static struct platform_device msm_device_gfx2d0_texv3_ctx = {
- .name = "msm_iommu_ctx",
- .id = 21,
- .dev = {
- .parent = &msm_device_smmu_gfx2d0.dev,
+ .parent = &msm_device_iommu_gfx2d1.dev,
},
};
static struct platform_device *msm_iommu_devs[] = {
- &msm_device_smmu_jpegd,
- &msm_device_smmu_vpe,
- &msm_device_smmu_mdp0,
- &msm_device_smmu_mdp1,
- &msm_device_smmu_rot,
- &msm_device_smmu_ijpeg,
- &msm_device_smmu_vfe,
- &msm_device_smmu_vcodec_a,
- &msm_device_smmu_vcodec_b,
- &msm_device_smmu_gfx3d,
- &msm_device_smmu_gfx2d0,
+ &msm_device_iommu_jpegd,
+ &msm_device_iommu_vpe,
+ &msm_device_iommu_mdp0,
+ &msm_device_iommu_mdp1,
+ &msm_device_iommu_rot,
+ &msm_device_iommu_ijpeg,
+ &msm_device_iommu_vfe,
+ &msm_device_iommu_vcodec_a,
+ &msm_device_iommu_vcodec_b,
+ &msm_device_iommu_gfx3d,
+ &msm_device_iommu_gfx2d0,
+ &msm_device_iommu_gfx2d1,
};
static struct msm_iommu_dev *msm_iommu_data[] = {
- &jpegd_smmu,
- &vpe_smmu,
- &mdp0_smmu,
- &mdp1_smmu,
- &rot_smmu,
- &ijpeg_smmu,
- &vfe_smmu,
- &vcodec_a_smmu,
- &vcodec_b_smmu,
- &gfx3d_smmu,
- &gfx2d0_smmu,
+ &jpegd_iommu,
+ &vpe_iommu,
+ &mdp0_iommu,
+ &mdp1_iommu,
+ &rot_iommu,
+ &ijpeg_iommu,
+ &vfe_iommu,
+ &vcodec_a_iommu,
+ &vcodec_b_iommu,
+ &gfx3d_iommu,
+ &gfx2d0_iommu,
+ &gfx2d1_iommu,
};
static struct platform_device *msm_iommu_ctx_devs[] = {
@@ -771,11 +796,10 @@ static struct platform_device *msm_iommu_ctx_devs[] = {
&msm_device_vcodec_a_stream_ctx,
&msm_device_vcodec_a_mm1_ctx,
&msm_device_vcodec_b_mm2_ctx,
- &msm_device_gfx3d_rbpa_ctx,
- &msm_device_gfx3d_cpvgttc_ctx,
- &msm_device_gfx3d_smmu_ctx,
- &msm_device_gfx2d0_pixv1_ctx,
- &msm_device_gfx2d0_texv3_ctx,
+ &msm_device_gfx3d_user_ctx,
+ &msm_device_gfx3d_priv_ctx,
+ &msm_device_gfx2d0_2d0_ctx,
+ &msm_device_gfx2d1_2d1_ctx,
};
static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
@@ -796,14 +820,13 @@ static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
&vcodec_a_stream_ctx,
&vcodec_a_mm1_ctx,
&vcodec_b_mm2_ctx,
- &gfx3d_rbpa_ctx,
- &gfx3d_cpvgttc_ctx,
- &gfx3d_smmu_ctx,
- &gfx2d0_pixv1_ctx,
- &gfx2d0_texv3_ctx,
+ &gfx3d_user_ctx,
+ &gfx3d_priv_ctx,
+ &gfx2d0_2d0_ctx,
+ &gfx2d1_2d1_ctx,
};
-static int msm8x60_iommu_init(void)
+static int __init msm8x60_iommu_init(void)
{
int ret, i;
@@ -826,7 +849,7 @@ static int msm8x60_iommu_init(void)
ret = platform_device_register(msm_iommu_devs[i]);
if (ret != 0) {
- pr_err("platform_device_register smmu failed, "
+ pr_err("platform_device_register iommu failed, "
"i = %d\n", i);
goto failure_unwind;
}
@@ -837,7 +860,7 @@ static int msm8x60_iommu_init(void)
msm_iommu_ctx_data[i],
sizeof(*msm_iommu_ctx_devs[i]));
if (ret != 0) {
- pr_err("platform_device_add_data smmu failed, "
+ pr_err("platform_device_add_data iommu failed, "
"i = %d\n", i);
goto failure_unwind2;
}
@@ -863,7 +886,7 @@ failure:
return ret;
}
-static void msm8x60_iommu_exit(void)
+static void __exit msm8x60_iommu_exit(void)
{
int i;
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 6fe67c5d1ae0..a4b798f20ccb 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -53,6 +53,77 @@ struct platform_device msm_device_smd = {
.id = -1,
};
+static struct resource resources_otg[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_otg = {
+ .name = "msm_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_otg),
+ .resource = resources_otg,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_hsusb[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb = {
+ .name = "msm_hsusb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb),
+ .resource = resources_hsusb,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static u64 dma_mask = 0xffffffffULL;
+static struct resource resources_hsusb_host[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb_host = {
+ .name = "msm_hsusb_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb_host),
+ .resource = resources_hsusb_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffffULL,
+ },
+};
+
struct clk msm_clocks_8x50[] = {
CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 568443e76423..87c70bfce2bd 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -28,6 +28,8 @@ extern struct platform_device msm_device_sdc3;
extern struct platform_device msm_device_sdc4;
extern struct platform_device msm_device_hsusb;
+extern struct platform_device msm_device_otg;
+extern struct platform_device msm_device_hsusb_host;
extern struct platform_device msm_device_i2c;
@@ -35,6 +37,10 @@ extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_nand;
+extern struct platform_device msm_device_mddi0;
+extern struct platform_device msm_device_mddi1;
+extern struct platform_device msm_device_mdp;
+
extern struct clk msm_clocks_7x01a[];
extern unsigned msm_num_clocks_7x01a;
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c
new file mode 100644
index 000000000000..0de19ec74e34
--- /dev/null
+++ b/arch/arm/mach-msm/gpio-v2.c
@@ -0,0 +1,426 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <mach/msm_iomap.h>
+#include "gpiomux.h"
+
+/* Bits of interest in the GPIO_IN_OUT register.
+ */
+enum {
+ GPIO_IN = 0,
+ GPIO_OUT = 1
+};
+
+/* Bits of interest in the GPIO_INTR_STATUS register.
+ */
+enum {
+ INTR_STATUS = 0,
+};
+
+/* Bits of interest in the GPIO_CFG register.
+ */
+enum {
+ GPIO_OE = 9,
+};
+
+/* Bits of interest in the GPIO_INTR_CFG register.
+ * When a GPIO triggers, two separate decisions are made, controlled
+ * by two separate flags.
+ *
+ * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
+ * register for that GPIO will be updated to reflect the triggering of that
+ * gpio. If this bit is 0, this register will not be updated.
+ * - Second, INTR_ENABLE controls whether an interrupt is triggered.
+ *
+ * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
+ * can be triggered but the status register will not reflect it.
+ */
+enum {
+ INTR_ENABLE = 0,
+ INTR_POL_CTL = 1,
+ INTR_DECT_CTL = 2,
+ INTR_RAW_STATUS_EN = 3,
+};
+
+/* Codes of interest in GPIO_INTR_CFG_SU.
+ */
+enum {
+ TARGET_PROC_SCORPION = 4,
+ TARGET_PROC_NONE = 7,
+};
+
+
+#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
+#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
+#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
+#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
+#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
+
+/**
+ * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
+ *
+ * @enabled_irqs: a bitmap used to optimize the summary-irq handler. By
+ * keeping track of which gpios are unmasked as irq sources, we avoid
+ * having to do readl calls on hundreds of iomapped registers each time
+ * the summary interrupt fires in order to locate the active interrupts.
+ *
+ * @wake_irqs: a bitmap for tracking which interrupt lines are enabled
+ * as wakeup sources. When the device is suspended, interrupts which are
+ * not wakeup sources are disabled.
+ *
+ * @dual_edge_irqs: a bitmap used to track which irqs are configured
+ * as dual-edge, as this is not supported by the hardware and requires
+ * some special handling in the driver.
+ */
+struct msm_gpio_dev {
+ struct gpio_chip gpio_chip;
+ DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
+ DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
+ DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
+};
+
+static DEFINE_SPINLOCK(tlmm_lock);
+
+static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
+{
+ return container_of(chip, struct msm_gpio_dev, gpio_chip);
+}
+
+static inline void set_gpio_bits(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) | n, reg);
+}
+
+static inline void clear_gpio_bits(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) & ~n, reg);
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN);
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset));
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset,
+ int val)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ msm_gpio_set(chip, offset, val);
+ set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ msm_gpiomux_put(chip->base + offset);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
+{
+ return irq - MSM_GPIO_TO_INT(chip->base);
+}
+
+static struct msm_gpio_dev msm_gpio = {
+ .gpio_chip = {
+ .base = 0,
+ .ngpio = NR_GPIO_IRQS,
+ .direction_input = msm_gpio_direction_input,
+ .direction_output = msm_gpio_direction_output,
+ .get = msm_gpio_get,
+ .set = msm_gpio_set,
+ .to_irq = msm_gpio_to_irq,
+ .request = msm_gpio_request,
+ .free = msm_gpio_free,
+ },
+};
+
+/* For dual-edge interrupts in software, since the hardware has no
+ * such support:
+ *
+ * At appropriate moments, this function may be called to flip the polarity
+ * settings of both-edge irq lines to try and catch the next edge.
+ *
+ * The attempt is considered successful if:
+ * - the status bit goes high, indicating that an edge was caught, or
+ * - the input value of the gpio doesn't change during the attempt.
+ * If the value changes twice during the process, that would cause the first
+ * test to fail but would force the second, as two opposite
+ * transitions would cause a detection no matter the polarity setting.
+ *
+ * The do-loop tries to sledge-hammer closed the timing hole between
+ * the initial value-read and the polarity-write - if the line value changes
+ * during that window, an interrupt is lost, the new polarity setting is
+ * incorrect, and the first success test will fail, causing a retry.
+ *
+ * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c.
+ */
+static void msm_gpio_update_dual_edge_pos(unsigned gpio)
+{
+ int loop_limit = 100;
+ unsigned val, val2, intstat;
+
+ do {
+ val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
+ if (val)
+ clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
+ else
+ set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
+ val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
+ intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS);
+ if (intstat || val == val2)
+ return;
+ } while (loop_limit-- > 0);
+ pr_err("dual-edge irq failed to stabilize, "
+ "interrupts dropped. %#08x != %#08x\n",
+ val, val2);
+}
+
+static void msm_gpio_irq_ack(unsigned int irq)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+
+ writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
+ if (test_bit(gpio, msm_gpio.dual_edge_irqs))
+ msm_gpio_update_dual_edge_pos(gpio);
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
+ clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+ __clear_bit(gpio, msm_gpio.enabled_irqs);
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ __set_bit(gpio, msm_gpio.enabled_irqs);
+ set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+ writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ unsigned long irq_flags;
+ uint32_t bits;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+
+ bits = readl(GPIO_INTR_CFG(gpio));
+
+ if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+ bits |= BIT(INTR_DECT_CTL);
+ irq_desc[irq].handle_irq = handle_edge_irq;
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ __set_bit(gpio, msm_gpio.dual_edge_irqs);
+ else
+ __clear_bit(gpio, msm_gpio.dual_edge_irqs);
+ } else {
+ bits &= ~BIT(INTR_DECT_CTL);
+ irq_desc[irq].handle_irq = handle_level_irq;
+ __clear_bit(gpio, msm_gpio.dual_edge_irqs);
+ }
+
+ if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+ bits |= BIT(INTR_POL_CTL);
+ else
+ bits &= ~BIT(INTR_POL_CTL);
+
+ writel(bits, GPIO_INTR_CFG(gpio));
+
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ msm_gpio_update_dual_edge_pos(gpio);
+
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+
+ return 0;
+}
+
+/*
+ * When the summary IRQ is raised, any number of GPIO lines may be high.
+ * It is the job of the summary handler to find all those GPIO lines
+ * which have been set as summary IRQ lines and which are triggered,
+ * and to call their interrupt handlers.
+ */
+static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long i;
+
+ for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
+ i < NR_GPIO_IRQS;
+ i = find_next_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS, i + 1)) {
+ if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
+ generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
+ i));
+ }
+ desc->chip->ack(irq);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+
+ if (on) {
+ if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
+ set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+ set_bit(gpio, msm_gpio.wake_irqs);
+ } else {
+ clear_bit(gpio, msm_gpio.wake_irqs);
+ if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
+ set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+ }
+
+ return 0;
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msmgpio",
+ .mask = msm_gpio_irq_mask,
+ .unmask = msm_gpio_irq_unmask,
+ .ack = msm_gpio_irq_ack,
+ .set_type = msm_gpio_irq_set_type,
+ .set_wake = msm_gpio_irq_set_wake,
+};
+
+static int __devinit msm_gpio_probe(struct platform_device *dev)
+{
+ int i, irq, ret;
+
+ bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
+ bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
+ bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
+ msm_gpio.gpio_chip.label = dev->name;
+ ret = gpiochip_add(&msm_gpio.gpio_chip);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
+ irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
+ set_irq_chip(irq, &msm_gpio_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ set_irq_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
+ msm_summary_irq_handler);
+ return 0;
+}
+
+static int __devexit msm_gpio_remove(struct platform_device *dev)
+{
+ int ret = gpiochip_remove(&msm_gpio.gpio_chip);
+
+ if (ret < 0)
+ return ret;
+
+ set_irq_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+
+ return 0;
+}
+
+static struct platform_driver msm_gpio_driver = {
+ .probe = msm_gpio_probe,
+ .remove = __devexit_p(msm_gpio_remove),
+ .driver = {
+ .name = "msmgpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_device msm_device_gpio = {
+ .name = "msmgpio",
+ .id = -1,
+};
+
+static int __init msm_gpio_init(void)
+{
+ int rc;
+
+ rc = platform_driver_register(&msm_gpio_driver);
+ if (!rc) {
+ rc = platform_device_register(&msm_device_gpio);
+ if (rc)
+ platform_driver_unregister(&msm_gpio_driver);
+ }
+
+ return rc;
+}
+
+static void __exit msm_gpio_exit(void)
+{
+ platform_device_unregister(&msm_device_gpio);
+ platform_driver_unregister(&msm_gpio_driver);
+}
+
+postcore_initcall(msm_gpio_init);
+module_exit(msm_gpio_exit);
+
+MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
+MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:msmgpio");
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 218ef5732a24..296c0f10f230 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -20,13 +20,26 @@
#include <linux/interrupt.h>
+/* Sharability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NON_SH 0x0
+#define MSM_IOMMU_ATTR_SH 0x4
+
+/* Cacheability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NONCACHED 0x0
+#define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1
+#define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2
+#define MSM_IOMMU_ATTR_CACHED_WT 0x3
+
+/* Mask for the cache policy attribute */
+#define MSM_IOMMU_CP_MASK 0x03
+
/* Maximum number of Machine IDs that we are allowing to be mapped to the same
* context bank. The number of MIDs mapped to the same CB does not affect
* performance, but there is a practical limit on how many distinct MIDs may
* be present. These mappings are typically determined at design time and are
* not expected to change at run time.
*/
-#define MAX_NUM_MIDS 16
+#define MAX_NUM_MIDS 32
/**
* struct msm_iommu_dev - a single IOMMU hardware instance
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index f9386d3a2f77..c2c3da9444f4 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -54,6 +54,7 @@ do { \
#define NUM_FL_PTE 4096
#define NUM_SL_PTE 256
+#define NUM_TEX_CLASS 8
/* First-level page table bits */
#define FL_BASE_MASK 0xFFFFFC00
@@ -63,6 +64,9 @@ do { \
#define FL_AP_WRITE (1 << 10)
#define FL_AP_READ (1 << 11)
#define FL_SHARED (1 << 16)
+#define FL_BUFFERABLE (1 << 2)
+#define FL_CACHEABLE (1 << 3)
+#define FL_TEX0 (1 << 12)
#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20)
/* Second-level page table bits */
@@ -73,8 +77,20 @@ do { \
#define SL_AP0 (1 << 4)
#define SL_AP1 (2 << 4)
#define SL_SHARED (1 << 10)
+#define SL_BUFFERABLE (1 << 2)
+#define SL_CACHEABLE (1 << 3)
+#define SL_TEX0 (1 << 6)
#define SL_OFFSET(va) (((va) & 0xFF000) >> 12)
+/* Memory type and cache policy attributes */
+#define MT_SO 0
+#define MT_DEV 1
+#define MT_NORMAL 2
+#define CP_NONCACHED 0
+#define CP_WB_WA 1
+#define CP_WT 2
+#define CP_WB_NWA 3
+
/* Global register setters / getters */
#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
@@ -706,7 +722,9 @@ do { \
#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
-
+#define NMRR_ICP(nmrr, n) (((nmrr) & (3 << ((n) * 2))) >> ((n) * 2))
+#define NMRR_OCP(nmrr, n) (((nmrr) & (3 << ((n) * 2 + 16))) >> \
+ ((n) * 2 + 16))
/* PAR */
#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT)
@@ -750,6 +768,8 @@ do { \
#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
+#define PRRR_NOS(prrr, n) ((prrr) & (1 << ((n) + 24)) ? 1 : 0)
+#define PRRR_MT(prrr, n) ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2)))
/* RESUME */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
index 36074cfc9ad2..f65841c74c0b 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x60.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -237,7 +237,12 @@
#define GSBI11_QUP_IRQ (GIC_SPI_START + 194)
#define INT_UART12DM_IRQ (GIC_SPI_START + 195)
#define GSBI12_QUP_IRQ (GIC_SPI_START + 196)
-/*SPI 197 to 216 arent used in 8x60*/
+
+/*SPI 197 to 209 arent used in 8x60*/
+#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210)
+#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211)
+
+/*SPI 212 to 216 arent used in 8x60*/
#define SMPSS_SPARE_1 (GIC_SPI_START + 217)
#define SMPSS_SPARE_2 (GIC_SPI_START + 218)
#define SMPSS_SPARE_3 (GIC_SPI_START + 219)
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index 8a00c2defbc1..0fd7b68ca114 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -119,4 +119,7 @@
#define MSM_AD5_PHYS 0xA7000000
#define MSM_AD5_SIZE (SZ_1M*13)
+#define MSM_HSUSB_PHYS 0xA3600000
+#define MSM_HSUSB_SIZE SZ_1K
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 45bab50e3ee6..7c43a9bff1a9 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -98,4 +98,7 @@
#define MSM_IOMMU_GFX2D0_PHYS 0x07D00000
#define MSM_IOMMU_GFX2D0_SIZE SZ_1M
+#define MSM_IOMMU_GFX2D1_PHYS 0x07E00000
+#define MSM_IOMMU_GFX2D1_SIZE SZ_1M
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h
index 3ff7bf5e679e..a95f7b9efe31 100644
--- a/arch/arm/mach-msm/include/mach/smp.h
+++ b/arch/arm/mach-msm/include/mach/smp.h
@@ -31,9 +31,9 @@
#include <asm/hardware/gic.h>
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index d36b61074146..f912d7bf1889 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -163,3 +163,4 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
return __arm_ioremap_caller(phys_addr, size, mtype,
__builtin_return_address(0));
}
+EXPORT_SYMBOL(__msm_ioremap);
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index f71747db3bee..e2d58e4cb0d7 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -33,6 +33,16 @@
#include <mach/iommu_hw-8xxx.h>
#include <mach/iommu.h>
+#define MRC(reg, processor, op1, crn, crm, op2) \
+__asm__ __volatile__ ( \
+" mrc " #processor "," #op1 ", %0," #crn "," #crm "," #op2 "\n" \
+: "=r" (reg))
+
+#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
+#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
+
+static int msm_iommu_tex_class[4];
+
DEFINE_SPINLOCK(msm_iommu_lock);
struct msm_priv {
@@ -40,23 +50,26 @@ struct msm_priv {
struct list_head list_attached;
};
-static void __flush_iotlb(struct iommu_domain *domain)
+static int __flush_iotlb(struct iommu_domain *domain)
{
struct msm_priv *priv = domain->priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
-
+ int ret = 0;
#ifndef CONFIG_IOMMU_PGTABLES_L2
unsigned long *fl_table = priv->pgtable;
int i;
- dmac_flush_range(fl_table, fl_table + SZ_16K);
+ if (!list_empty(&priv->list_attached)) {
+ dmac_flush_range(fl_table, fl_table + SZ_16K);
- for (i = 0; i < NUM_FL_PTE; i++)
- if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
- void *sl_table = __va(fl_table[i] & FL_BASE_MASK);
- dmac_flush_range(sl_table, sl_table + SZ_4K);
- }
+ for (i = 0; i < NUM_FL_PTE; i++)
+ if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
+ void *sl_table = __va(fl_table[i] &
+ FL_BASE_MASK);
+ dmac_flush_range(sl_table, sl_table + SZ_4K);
+ }
+ }
#endif
list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
@@ -66,6 +79,8 @@ static void __flush_iotlb(struct iommu_domain *domain)
iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
}
+
+ return ret;
}
static void __reset_context(void __iomem *base, int ctx)
@@ -95,6 +110,7 @@ static void __reset_context(void __iomem *base, int ctx)
static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
{
+ unsigned int prrr, nmrr;
__reset_context(base, ctx);
/* Set up HTW mode */
@@ -127,11 +143,11 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
/* Turn on TEX Remap */
SET_TRE(base, ctx, 1);
- /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume
- * TEX class 0 for everything until attributes are properly worked out
- */
- SET_PRRR(base, ctx, 0);
- SET_NMRR(base, ctx, 0);
+ /* Set TEX remap attributes */
+ RCP15_PRRR(prrr);
+ RCP15_NMRR(nmrr);
+ SET_PRRR(base, ctx, prrr);
+ SET_NMRR(base, ctx, nmrr);
/* Turn on BFB prefetch */
SET_BFBDFE(base, ctx, 1);
@@ -238,6 +254,11 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
goto fail;
}
+ if (!list_empty(&ctx_drvdata->attached_elm)) {
+ ret = -EBUSY;
+ goto fail;
+ }
+
list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
if (tmp_drvdata == ctx_drvdata) {
ret = -EBUSY;
@@ -248,7 +269,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
__pa(priv->pgtable));
list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
- __flush_iotlb(domain);
+ ret = __flush_iotlb(domain);
fail:
spin_unlock_irqrestore(&msm_iommu_lock, flags);
@@ -263,6 +284,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
unsigned long flags;
+ int ret;
spin_lock_irqsave(&msm_iommu_lock, flags);
priv = domain->priv;
@@ -277,7 +299,10 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
goto fail;
- __flush_iotlb(domain);
+ ret = __flush_iotlb(domain);
+ if (ret)
+ goto fail;
+
__reset_context(iommu_drvdata->base, ctx_dev->num);
list_del_init(&ctx_drvdata->attached_elm);
@@ -296,12 +321,21 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
unsigned long *sl_table;
unsigned long *sl_pte;
unsigned long sl_offset;
+ unsigned int pgprot;
size_t len = 0x1000UL << order;
- int ret = 0;
+ int ret = 0, tex, sh;
spin_lock_irqsave(&msm_iommu_lock, flags);
- priv = domain->priv;
+ sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
+ tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
+
+ if (tex < 0 || tex > NUM_TEX_CLASS - 1) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv = domain->priv;
if (!priv) {
ret = -EINVAL;
goto fail;
@@ -322,6 +356,18 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
goto fail;
}
+ if (len == SZ_16M || len == SZ_1M) {
+ pgprot = sh ? FL_SHARED : 0;
+ pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
+ pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
+ pgprot |= tex & 0x04 ? FL_TEX0 : 0;
+ } else {
+ pgprot = sh ? SL_SHARED : 0;
+ pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
+ pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
+ pgprot |= tex & 0x04 ? SL_TEX0 : 0;
+ }
+
fl_offset = FL_OFFSET(va); /* Upper 12 bits */
fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
@@ -330,17 +376,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
for (i = 0; i < 16; i++)
*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
- FL_SHARED;
+ FL_SHARED | pgprot;
}
if (len == SZ_1M)
*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
- FL_TYPE_SECT | FL_SHARED;
+ FL_TYPE_SECT | FL_SHARED | pgprot;
/* Need a 2nd level table */
if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) {
unsigned long *sl;
- sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
+ sl = (unsigned long *) __get_free_pages(GFP_ATOMIC,
get_order(SZ_4K));
if (!sl) {
@@ -360,17 +406,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
if (len == SZ_4K)
*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
- SL_SHARED | SL_TYPE_SMALL;
+ SL_SHARED | SL_TYPE_SMALL | pgprot;
if (len == SZ_64K) {
int i;
for (i = 0; i < 16; i++)
*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
- SL_AP1 | SL_SHARED | SL_TYPE_LARGE;
+ SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
}
- __flush_iotlb(domain);
+ ret = __flush_iotlb(domain);
fail:
spin_unlock_irqrestore(&msm_iommu_lock, flags);
return ret;
@@ -455,7 +501,7 @@ static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
}
}
- __flush_iotlb(domain);
+ ret = __flush_iotlb(domain);
fail:
spin_unlock_irqrestore(&msm_iommu_lock, flags);
return ret;
@@ -490,9 +536,6 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
SET_CTX_TLBIALL(base, ctx, 0);
SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT);
- if (GET_FAULT(base, ctx))
- goto fail;
-
par = GET_PAR(base, ctx);
/* We are dealing with a supersection */
@@ -501,6 +544,9 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
else /* Upper 20 bits from PAR, lower 12 from VA */
ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+ if (GET_FAULT(base, ctx))
+ ret = 0;
+
fail:
spin_unlock_irqrestore(&msm_iommu_lock, flags);
return ret;
@@ -543,8 +589,8 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
{
struct msm_iommu_drvdata *drvdata = dev_id;
void __iomem *base;
- unsigned int fsr = 0;
- int ncb = 0, i = 0;
+ unsigned int fsr;
+ int ncb, i;
spin_lock(&msm_iommu_lock);
@@ -555,7 +601,6 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
base = drvdata->base;
- pr_err("===== WOAH! =====\n");
pr_err("Unexpected IOMMU page fault!\n");
pr_err("base = %08x\n", (unsigned int) base);
@@ -585,8 +630,47 @@ static struct iommu_ops msm_iommu_ops = {
.domain_has_cap = msm_iommu_domain_has_cap
};
-static int msm_iommu_init(void)
+static int __init get_tex_class(int icp, int ocp, int mt, int nos)
+{
+ int i = 0;
+ unsigned int prrr = 0;
+ unsigned int nmrr = 0;
+ int c_icp, c_ocp, c_mt, c_nos;
+
+ RCP15_PRRR(prrr);
+ RCP15_NMRR(nmrr);
+
+ for (i = 0; i < NUM_TEX_CLASS; i++) {
+ c_nos = PRRR_NOS(prrr, i);
+ c_mt = PRRR_MT(prrr, i);
+ c_icp = NMRR_ICP(nmrr, i);
+ c_ocp = NMRR_OCP(nmrr, i);
+
+ if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+static void __init setup_iommu_tex_classes(void)
+{
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
+ get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
+ get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
+ get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
+ get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
+}
+
+static int __init msm_iommu_init(void)
{
+ setup_iommu_tex_classes();
register_iommu(&msm_iommu_ops);
return 0;
}
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 9019cee2907b..b83c73b41fd1 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -346,7 +346,7 @@ static struct platform_driver msm_iommu_ctx_driver = {
.remove = msm_iommu_ctx_remove,
};
-static int msm_iommu_driver_init(void)
+static int __init msm_iommu_driver_init(void)
{
int ret;
ret = platform_driver_register(&msm_iommu_driver);
@@ -365,7 +365,7 @@ error:
return ret;
}
-static void msm_iommu_driver_exit(void)
+static void __exit msm_iommu_driver_exit(void)
{
platform_driver_unregister(&msm_iommu_ctx_driver);
platform_driver_unregister(&msm_iommu_driver);
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
index b0794524ba6e..152eefda3ce6 100644
--- a/arch/arm/mach-msm/sirc.c
+++ b/arch/arm/mach-msm/sirc.c
@@ -40,9 +40,6 @@ static struct sirc_cascade_regs sirc_reg_table[] = {
}
};
-static unsigned int save_type;
-static unsigned int save_polarity;
-
/* Mask off the given interrupt. Keep the int_enable mask in sync with
the enable reg, so it can be restored after power collapse. */
static void sirc_irq_mask(unsigned int irq)
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index f07dc7c738f0..657be73297db 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -14,6 +14,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/fs.h>
@@ -89,7 +91,7 @@ static void smd_diag(void)
x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
if (x != 0) {
x[SZ_DIAG_ERR_MSG - 1] = 0;
- pr_info("smem: DIAG '%s'\n", x);
+ pr_debug("DIAG '%s'\n", x);
}
}
@@ -312,7 +314,7 @@ static void smd_state_change(struct smd_channel *ch,
{
ch->last_state = next;
- pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
+ pr_debug("ch %d %d -> %d\n", ch->n, last, next);
switch (next) {
case SMD_SS_OPENING:
@@ -601,7 +603,7 @@ static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
ch->pdev.name = ch->name;
ch->pdev.id = -1;
- pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
+ pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
ch->n, ch->fifo_size, ch->name);
mutex_lock(&smd_creation_mutex);
@@ -621,7 +623,7 @@ static void smd_channel_probe_worker(struct work_struct *work)
shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
if (!shared) {
- pr_err("smd: cannot find allocation table\n");
+ pr_err("cannot find allocation table\n");
return;
}
for (n = 0; n < 64; n++) {
@@ -725,8 +727,6 @@ int smd_close(smd_channel_t *ch)
{
unsigned long flags;
- pr_info("smd_close(%p)\n", ch);
-
if (ch == 0)
return -1;
@@ -939,7 +939,6 @@ int smsm_set_sleep_duration(uint32_t delay)
int smd_core_init(void)
{
int r;
- pr_info("smd_core_init()\n");
/* wait for essential items to be initialized */
for (;;) {
@@ -992,15 +991,11 @@ int smd_core_init(void)
smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
#endif
- pr_info("smd_core_init() done\n");
-
return 0;
}
static int __devinit msm_smd_probe(struct platform_device *pdev)
{
- pr_info("smd_init()\n");
-
/*
* If we haven't waited for the ARM9 to boot up till now,
* then we need to wait here. Otherwise this should just
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index f91c3b7bc655..8736afff82f3 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -270,8 +270,10 @@ void smsm_print_sleep_info(void)
{
unsigned long flags;
uint32_t *ptr;
+#ifndef CONFIG_ARCH_MSM_SCORPION
struct tramp_gpio_smem *gpio;
struct smsm_interrupt_info *int_info;
+#endif
spin_lock_irqsave(&smem_lock, flags);
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 950100f19d07..595be7fea31a 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -137,7 +137,6 @@ static struct msm_clock msm_clocks[] = {
.rating = 200,
.read = msm_gpt_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 17,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
},
.irq = {
@@ -164,7 +163,6 @@ static struct msm_clock msm_clocks[] = {
.rating = 300,
.read = msm_dgt_read,
.mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
- .shift = 24 - MSM_DGT_SHIFT,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
},
.irq = {
@@ -205,8 +203,7 @@ static void __init msm_timer_init(void)
ce->min_delta_ns = clockevent_delta2ns(4, ce);
ce->cpumask = cpumask_of(0);
- cs->mult = clocksource_hz2mult(clock->freq, cs->shift);
- res = clocksource_register(cs);
+ res = clocksource_register_hz(cs, clock->freq);
if (res)
printk(KERN_ERR "msm_timer_init: clocksource_register "
"failed for %s\n", cs->name);
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index 788bdace1304..3eff39921d4d 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -65,7 +65,7 @@
*/
#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000)
#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500)
-#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1700)
+#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1570)
#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000)
#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000)
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
deleted file mode 100644
index 38ca09a5df9d..000000000000
--- a/arch/arm/mach-mx25/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
-if ARCH_MX25
-
-comment "MX25 platforms:"
-
-config MACH_MX25_3DS
- bool "Support MX25PDK (3DS) Platform"
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_ESDHC
-
-config MACH_EUKREA_CPUIMX25
- bool "Support Eukrea CPUIMX25 Platform"
- select IMX_HAVE_PLATFORM_IMX_I2C
- select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_FLEXCAN
- select IMX_HAVE_PLATFORM_ESDHC
- select MXC_ULPI if USB_ULPI
-
-choice
- prompt "Baseboard"
- depends on MACH_EUKREA_CPUIMX25
- default MACH_EUKREA_MBIMXSD25_BASEBOARD
-
-config MACH_EUKREA_MBIMXSD25_BASEBOARD
- bool "Eukrea MBIMXSD development board"
- select IMX_HAVE_PLATFORM_IMX_SSI
- help
- This adds board specific devices that can be found on Eukrea's
- MBIMXSD evaluation board.
-
-endchoice
-
-endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
deleted file mode 100644
index d9e46ce00a4e..000000000000
--- a/arch/arm/mach-mx25/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-y := mm.o devices.o
-obj-$(CONFIG_ARCH_MX25) += clock.o
-obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-cpuimx25.o
-obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd-baseboard.o
diff --git a/arch/arm/mach-mx25/Makefile.boot b/arch/arm/mach-mx25/Makefile.boot
deleted file mode 100644
index e1dd366f836b..000000000000
--- a/arch/arm/mach-mx25/Makefile.boot
+++ /dev/null
@@ -1,3 +0,0 @@
- zreladdr-y := 0x80008000
-params_phys-y := 0x80000100
-initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
deleted file mode 100644
index 1d0eb3e85941..000000000000
--- a/arch/arm/mach-mx25/devices.c
+++ /dev/null
@@ -1,308 +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/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <mach/mx25.h>
-#include <mach/irqs.h>
-
-static u64 otg_dmamask = DMA_BIT_MASK(32);
-
-static struct resource mxc_otg_resources[] = {
- {
- .start = MX25_OTG_BASE_ADDR,
- .end = MX25_OTG_BASE_ADDR + 0x1ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 37,
- .end = 37,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_otg = {
- .name = "mxc-ehci",
- .id = 0,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- .dma_mask = &otg_dmamask,
- },
- .resource = mxc_otg_resources,
- .num_resources = ARRAY_SIZE(mxc_otg_resources),
-};
-
-/* OTG gadget device */
-struct platform_device otg_udc_device = {
- .name = "fsl-usb2-udc",
- .id = -1,
- .dev = {
- .dma_mask = &otg_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .resource = mxc_otg_resources,
- .num_resources = ARRAY_SIZE(mxc_otg_resources),
-};
-
-static u64 usbh2_dmamask = DMA_BIT_MASK(32);
-
-static struct resource mxc_usbh2_resources[] = {
- {
- .start = MX25_OTG_BASE_ADDR + 0x400,
- .end = MX25_OTG_BASE_ADDR + 0x5ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 35,
- .end = 35,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_usbh2 = {
- .name = "mxc-ehci",
- .id = 1,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- .dma_mask = &usbh2_dmamask,
- },
- .resource = mxc_usbh2_resources,
- .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
-};
-
-static struct resource mxc_pwm_resources0[] = {
- {
- .start = 0x53fe0000,
- .end = 0x53fe3fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 26,
- .end = 26,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_pwm_device0 = {
- .name = "mxc_pwm",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_pwm_resources0),
- .resource = mxc_pwm_resources0,
-};
-
-static struct resource mxc_pwm_resources1[] = {
- {
- .start = 0x53fa0000,
- .end = 0x53fa3fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 36,
- .end = 36,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_pwm_device1 = {
- .name = "mxc_pwm",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_pwm_resources1),
- .resource = mxc_pwm_resources1,
-};
-
-static struct resource mxc_pwm_resources2[] = {
- {
- .start = 0x53fa8000,
- .end = 0x53fabfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 41,
- .end = 41,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_pwm_device2 = {
- .name = "mxc_pwm",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_pwm_resources2),
- .resource = mxc_pwm_resources2,
-};
-
-static struct resource mxc_keypad_resources[] = {
- {
- .start = 0x43fa8000,
- .end = 0x43fabfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 24,
- .end = 24,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_keypad_device = {
- .name = "mxc-keypad",
- .id = -1,
- .num_resources = ARRAY_SIZE(mxc_keypad_resources),
- .resource = mxc_keypad_resources,
-};
-
-static struct resource mxc_pwm_resources3[] = {
- {
- .start = 0x53fc8000,
- .end = 0x53fcbfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 42,
- .end = 42,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_pwm_device3 = {
- .name = "mxc_pwm",
- .id = 3,
- .num_resources = ARRAY_SIZE(mxc_pwm_resources3),
- .resource = mxc_pwm_resources3,
-};
-
-static struct mxc_gpio_port imx_gpio_ports[] = {
- {
- .chip.label = "gpio-0",
- .base = (void __iomem *)MX25_GPIO1_BASE_ADDR_VIRT,
- .irq = 52,
- .virtual_irq_start = MXC_GPIO_IRQ_START,
- }, {
- .chip.label = "gpio-1",
- .base = (void __iomem *)MX25_GPIO2_BASE_ADDR_VIRT,
- .irq = 51,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
- }, {
- .chip.label = "gpio-2",
- .base = (void __iomem *)MX25_GPIO3_BASE_ADDR_VIRT,
- .irq = 16,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
- }, {
- .chip.label = "gpio-3",
- .base = (void __iomem *)MX25_GPIO4_BASE_ADDR_VIRT,
- .irq = 23,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
- }
-};
-
-int __init imx25_register_gpios(void)
-{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
-}
-
-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,
- },
-};
-
-static struct resource mxc_wdt_resources[] = {
- {
- .start = MX25_WDOG_BASE_ADDR,
- .end = MX25_WDOG_BASE_ADDR + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device mxc_wdt = {
- .name = "imx2-wdt",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_wdt_resources),
- .resource = mxc_wdt_resources,
-};
-
-static struct resource mx25_kpp_resources[] = {
- {
- .start = MX25_KPP_BASE_ADDR,
- .end = MX25_KPP_BASE_ADDR + 0xf,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX25_INT_KPP,
- .end = MX25_INT_KPP,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mx25_kpp_device = {
- .name = "imx-keypad",
- .id = -1,
- .num_resources = ARRAY_SIZE(mx25_kpp_resources),
- .resource = mx25_kpp_resources,
-};
-
-static struct resource mx25_csi_resources[] = {
- {
- .start = MX25_CSI_BASE_ADDR,
- .end = MX25_CSI_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX25_INT_CSI,
- .flags = IORESOURCE_IRQ
- },
-};
-
-struct platform_device mx25_csi_device = {
- .name = "mx2-camera",
- .id = 0,
- .num_resources = ARRAY_SIZE(mx25_csi_resources),
- .resource = mx25_csi_resources,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- },
-};
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
deleted file mode 100644
index 7b70a43c3a4b..000000000000
--- a/arch/arm/mach-mx25/devices.h
+++ /dev/null
@@ -1,13 +0,0 @@
-extern struct platform_device mxc_otg;
-extern struct platform_device otg_udc_device;
-extern struct platform_device mxc_usbh2;
-extern struct platform_device mxc_pwm_device0;
-extern struct platform_device mxc_pwm_device1;
-extern struct platform_device mxc_pwm_device2;
-extern struct platform_device mxc_pwm_device3;
-extern struct platform_device mxc_keypad_device;
-extern struct platform_device mx25_rtc_device;
-extern struct platform_device mx25_fb_device;
-extern struct platform_device mxc_wdt;
-extern struct platform_device mx25_kpp_device;
-extern struct platform_device mx25_csi_device;
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 5000ac1f93e3..0717f887cba0 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -1,21 +1,35 @@
if ARCH_MX3
+# ARCH_MX31 and ARCH_MX35 are left for compatibility
+# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
+# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
+# more sensible) names are used: SOC_IMX31 and SOC_IMX35
config ARCH_MX31
- select ARCH_HAS_RNGA
- select ARCH_MXC_AUDMUX_V2
bool
config ARCH_MX35
bool
+
+config SOC_IMX31
+ bool
+ select IMX_HAVE_PLATFORM_MXC_RNGA
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_MX31
+ select MXC_AVIC
+
+config SOC_IMX35
+ bool
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select HAVE_EPIT
+ select ARCH_MX35
+ select MXC_AVIC
comment "MX3 platforms:"
config MACH_MX31ADS
bool "Support MX31ADS platforms"
- select ARCH_MX31
+ select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
@@ -37,10 +51,15 @@ config MACH_MX31ADS_WM1133_EV1
config MACH_PCM037
bool "Support Phytec pcm037 (i.MX31) platforms"
- select ARCH_MX31
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm037 platform. This includes
@@ -57,9 +76,12 @@ config MACH_PCM037_EET
config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
- select ARCH_MX31
+ select SOC_IMX31
select MXC_ULPI if USB_ULPI
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
help
@@ -68,11 +90,16 @@ config MACH_MX31LITE
config MACH_MX31_3DS
bool "Support MX31PDK (3DS)"
- select ARCH_MX31
+ select SOC_IMX31
select MXC_DEBUG_BOARD
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
help
Include support for MX31PDK (3DS) platform. This includes specific
configurations for the board and its peripherals.
@@ -88,9 +115,12 @@ config MACH_MX31_3DS_MXC_NAND_USE_BBT
config MACH_MX31MOBOARD
bool "Support mx31moboard platforms (EPFL Mobots group)"
- select ARCH_MX31
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
@@ -99,8 +129,10 @@ config MACH_MX31MOBOARD
config MACH_MX31LILLY
bool "Support MX31 LILLY-1131 platforms (INCO startec)"
- select ARCH_MX31
+ select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
@@ -109,7 +141,7 @@ config MACH_MX31LILLY
config MACH_QONG
bool "Support Dave/DENX QongEVB-LITE platform"
- select ARCH_MX31
+ select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for Dave/DENX QongEVB-LITE platform. This includes
@@ -117,13 +149,16 @@ config MACH_QONG
config MACH_PCM043
bool "Support Phytec pcm043 (i.MX35) platforms"
- select ARCH_MX35
+ select SOC_IMX35
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_FLEXCAN
- select IMX_HAVE_PLATFORM_ESDHC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm043 platform. This includes
@@ -131,9 +166,11 @@ config MACH_PCM043
config MACH_ARMADILLO5X0
bool "Support Atmark Armadillo-500 Development Base Board"
- select ARCH_MX31
+ select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
select MXC_ULPI if USB_ULPI
help
@@ -142,19 +179,21 @@ config MACH_ARMADILLO5X0
config MACH_MX35_3DS
bool "Support MX35PDK platform"
- select ARCH_MX35
+ select SOC_IMX35
select MXC_DEBUG_BOARD
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_ESDHC
- default n
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
help
Include support for MX35PDK platform. This includes specific
configurations for the board and its peripherals.
config MACH_KZM_ARM11_01
bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
- select ARCH_MX31
+ select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for KZM-ARM11-01. This includes specific
@@ -162,12 +201,15 @@ config MACH_KZM_ARM11_01
config MACH_EUKREA_CPUIMX35
bool "Support Eukrea CPUIMX35 Platform"
- select ARCH_MX35
- select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX35
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
- select IMX_HAVE_PLATFORM_FLEXCAN
- select IMX_HAVE_PLATFORM_ESDHC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select MXC_ULPI if USB_ULPI
help
Include support for Eukrea CPUIMX35 platform. This includes
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 8a182d0a3fcf..8db13294ad27 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -5,17 +5,14 @@
# Object file lists.
obj-y := mm.o devices.o cpu.o
-CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
-CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
-obj-$(CONFIG_ARCH_MX31) += clock-imx31.o iomux-imx31.o
-obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
+obj-$(CONFIG_SOC_IMX31) += clock-imx31.o iomux-imx31.o
+obj-$(CONFIG_SOC_IMX35) += clock-imx35.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
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
index 109e98f323e0..d423cac8cab7 100644
--- a/arch/arm/mach-mx3/clock-imx31.c
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -23,8 +23,8 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/div64.h>
#include <mach/clock.h>
@@ -530,7 +530,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx31-cspi.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("imx2-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
_REGISTER_CLOCK(NULL, "epit", epit1_clk)
_REGISTER_CLOCK(NULL, "epit", epit2_clk)
@@ -615,7 +615,7 @@ int __init mx31_clocks_init(unsigned long fref)
mx31_read_cpu_rev();
- if (mx31_revision() >= MX31_CHIP_REV_2_0) {
+ if (mx31_revision() >= IMX_CHIP_REVISION_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;
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 61e4a318980a..448a038cd1ec 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -21,8 +21,7 @@
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
@@ -495,7 +494,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
- _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
_REGISTER_CLOCK(NULL, "max", max_clk)
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
_REGISTER_CLOCK(NULL, "csi", csi_clk)
diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c
index d00a75457812..d1d339576fdf 100644
--- a/arch/arm/mach-mx3/cpu.c
+++ b/arch/arm/mach-mx3/cpu.c
@@ -25,15 +25,15 @@ struct mx3_cpu_type {
};
static struct mx3_cpu_type mx31_cpu_type[] __initdata = {
- { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = MX3x_CHIP_REV_1_0 },
- { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
- { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 },
- { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
- { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 },
- { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
- { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 },
- { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
- { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 },
+ { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = IMX_CHIP_REVISION_1_0 },
+ { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 },
+ { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 },
};
void __init mx31_read_cpu_rev(void)
@@ -53,6 +53,8 @@ void __init mx31_read_cpu_rev(void)
return;
}
+ mx31_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+
printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
}
@@ -62,22 +64,25 @@ EXPORT_SYMBOL(mx35_cpu_rev);
void __init mx35_read_cpu_rev(void)
{
u32 rev;
- char *srev = "unknown";
+ char *srev;
rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
switch (rev) {
case 0x00:
- mx35_cpu_rev = MX3x_CHIP_REV_1_0;
+ mx35_cpu_rev = IMX_CHIP_REVISION_1_0;
srev = "1.0";
break;
case 0x10:
- mx35_cpu_rev = MX3x_CHIP_REV_2_0;
+ mx35_cpu_rev = IMX_CHIP_REVISION_2_0;
srev = "2.0";
break;
case 0x11:
- mx35_cpu_rev = MX3x_CHIP_REV_2_1;
+ mx35_cpu_rev = IMX_CHIP_REVISION_2_1;
srev = "2.1";
break;
+ default:
+ mx35_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+ srev = "unknown";
}
printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
diff --git a/arch/arm/mach-mx3/devices-imx31.h b/arch/arm/mach-mx3/devices-imx31.h
index de9598590eba..40f4e848a671 100644
--- a/arch/arm/mach-mx3/devices-imx31.h
+++ b/arch/arm/mach-mx3/devices-imx31.h
@@ -9,6 +9,14 @@
#include <mach/mx31.h>
#include <mach/devices-common.h>
+extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst;
+#define imx31_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst;
+#define imx31_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx31_imx2_wdt_data)
+
extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst;
#define imx31_add_imx_i2c(id, pdata) \
imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
@@ -16,6 +24,10 @@ extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst;
#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata)
#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata)
+extern const struct imx_imx_keypad_data imx31_imx_keypad_data __initconst;
+#define imx31_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx31_imx_keypad_data, pdata)
+
extern const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst;
#define imx31_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
@@ -29,10 +41,25 @@ extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst;
#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata)
#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata)
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data __initconst;
+#define imx31_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[] __initconst;
+#define imx31_add_mxc_ehci_hs(id, pdata) \
+ imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst;
+#define imx31_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata)
+
extern const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst;
#define imx31_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
+extern const struct imx_mxc_w1_data imx31_mxc_w1_data __initconst;
+#define imx31_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx31_mxc_w1_data)
+
extern const struct imx_spi_imx_data imx31_cspi_data[] __initconst;
#define imx31_add_cspi(id, pdata) \
imx_add_spi_imx(&imx31_cspi_data[id], pdata)
diff --git a/arch/arm/mach-mx3/devices-imx35.h b/arch/arm/mach-mx3/devices-imx35.h
index 5eb917b638d0..677b18aa7ae6 100644
--- a/arch/arm/mach-mx3/devices-imx35.h
+++ b/arch/arm/mach-mx3/devices-imx35.h
@@ -13,10 +13,19 @@ extern const struct imx_fec_data imx35_fec_data __initconst;
#define imx35_add_fec(pdata) \
imx_add_fec(&imx35_fec_data, pdata)
-#define imx35_add_flexcan0(pdata) \
- imx_add_flexcan(0, MX35_CAN1_BASE_ADDR, SZ_16K, MX35_INT_CAN1, pdata)
-#define imx35_add_flexcan1(pdata) \
- imx_add_flexcan(1, MX35_CAN2_BASE_ADDR, SZ_16K, MX35_INT_CAN2, pdata)
+extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst;
+#define imx35_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_flexcan_data imx35_flexcan_data[] __initconst;
+#define imx35_add_flexcan(id, pdata) \
+ imx_add_flexcan(&imx35_flexcan_data[id], pdata)
+#define imx35_add_flexcan0(pdata) imx35_add_flexcan(0, pdata)
+#define imx35_add_flexcan1(pdata) imx35_add_flexcan(1, pdata)
+
+extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst;
+#define imx35_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx35_imx2_wdt_data)
extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst;
#define imx35_add_imx_i2c(id, pdata) \
@@ -25,6 +34,10 @@ extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst;
#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata)
#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata)
+extern const struct imx_imx_keypad_data imx35_imx_keypad_data __initconst;
+#define imx31_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx35_imx_keypad_data, pdata)
+
extern const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst;
#define imx35_add_imx_ssi(id, pdata) \
imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
@@ -36,16 +49,28 @@ extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst;
#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata)
#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata)
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data __initconst;
+#define imx35_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data __initconst;
+#define imx35_add_mxc_ehci_hs(pdata) \
+ imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata)
+
extern const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst;
#define imx35_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
+extern const struct imx_mxc_w1_data imx35_mxc_w1_data __initconst;
+#define imx35_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx35_mxc_w1_data)
+
+extern const struct imx_sdhci_esdhc_imx_data
+imx35_sdhci_esdhc_imx_data[] __initconst;
+#define imx35_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata)
+
extern const struct imx_spi_imx_data imx35_cspi_data[] __initconst;
#define imx35_add_cspi(id, pdata) \
imx_add_spi_imx(&imx35_cspi_data[id], pdata)
#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata)
#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata)
-
-extern const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst;
-#define imx35_add_esdhc(id, pdata) \
- imx_add_esdhc(&imx35_esdhc_data[id], pdata)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index d4da9496089a..b6672db788fb 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -29,120 +29,25 @@
#include "devices.h"
-/* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
- {
- .chip.label = "gpio-0",
- .base = IO_ADDRESS(GPIO1_BASE_ADDR),
- .irq = MXC_INT_GPIO1,
- .virtual_irq_start = MXC_GPIO_IRQ_START,
- }, {
- .chip.label = "gpio-1",
- .base = IO_ADDRESS(GPIO2_BASE_ADDR),
- .irq = MXC_INT_GPIO2,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
- }, {
- .chip.label = "gpio-2",
- .base = IO_ADDRESS(GPIO3_BASE_ADDR),
- .irq = MXC_INT_GPIO3,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
- }
-};
-
-int __init imx3x_register_gpios(void)
-{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
-}
-
-static struct resource mxc_w1_master_resources[] = {
- {
- .start = OWIRE_BASE_ADDR,
- .end = OWIRE_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device mxc_w1_master_device = {
- .name = "mxc_w1",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
- .resource = mxc_w1_master_resources,
-};
-
-#ifdef CONFIG_ARCH_MX31
-static struct resource mxcsdhc0_resources[] = {
- {
- .start = MX31_MMC_SDHC1_BASE_ADDR,
- .end = MX31_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX31_INT_MMC_SDHC1,
- .end = MX31_INT_MMC_SDHC1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource mxcsdhc1_resources[] = {
- {
- .start = MX31_MMC_SDHC2_BASE_ADDR,
- .end = MX31_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX31_INT_MMC_SDHC2,
- .end = MX31_INT_MMC_SDHC2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxcsdhc_device0 = {
- .name = "mxc-mmc",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxcsdhc0_resources),
- .resource = mxcsdhc0_resources,
-};
-
-struct platform_device mxcsdhc_device1 = {
- .name = "mxc-mmc",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
- .resource = mxcsdhc1_resources,
-};
-
-static struct resource rnga_resources[] = {
- {
- .start = RNGA_BASE_ADDR,
- .end = RNGA_BASE_ADDR + 0x28,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device mxc_rnga_device = {
- .name = "mxc_rnga",
- .id = -1,
- .num_resources = 1,
- .resource = rnga_resources,
-};
-#endif /* CONFIG_ARCH_MX31 */
-
/* i.MX31 Image Processing Unit */
/* The resource order is important! */
static struct resource mx3_ipu_rsrc[] = {
{
- .start = IPU_CTRL_BASE_ADDR,
- .end = IPU_CTRL_BASE_ADDR + 0x5F,
+ .start = MX3x_IPU_CTRL_BASE_ADDR,
+ .end = MX3x_IPU_CTRL_BASE_ADDR + 0x5F,
.flags = IORESOURCE_MEM,
}, {
- .start = IPU_CTRL_BASE_ADDR + 0x88,
- .end = IPU_CTRL_BASE_ADDR + 0xB3,
+ .start = MX3x_IPU_CTRL_BASE_ADDR + 0x88,
+ .end = MX3x_IPU_CTRL_BASE_ADDR + 0xB3,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_IPU_SYN,
- .end = MXC_INT_IPU_SYN,
+ .start = MX3x_INT_IPU_SYN,
+ .end = MX3x_INT_IPU_SYN,
.flags = IORESOURCE_IRQ,
}, {
- .start = MXC_INT_IPU_ERR,
- .end = MXC_INT_IPU_ERR,
+ .start = MX3x_INT_IPU_ERR,
+ .end = MX3x_INT_IPU_ERR,
.flags = IORESOURCE_IRQ,
},
};
@@ -156,8 +61,8 @@ struct platform_device mx3_ipu = {
static struct resource fb_resources[] = {
{
- .start = IPU_CTRL_BASE_ADDR + 0xB4,
- .end = IPU_CTRL_BASE_ADDR + 0x1BF,
+ .start = MX3x_IPU_CTRL_BASE_ADDR + 0xB4,
+ .end = MX3x_IPU_CTRL_BASE_ADDR + 0x1BF,
.flags = IORESOURCE_MEM,
},
};
@@ -174,8 +79,8 @@ struct platform_device mx3_fb = {
static struct resource camera_resources[] = {
{
- .start = IPU_CTRL_BASE_ADDR + 0x60,
- .end = IPU_CTRL_BASE_ADDR + 0x87,
+ .start = MX3x_IPU_CTRL_BASE_ADDR + 0x60,
+ .end = MX3x_IPU_CTRL_BASE_ADDR + 0x87,
.flags = IORESOURCE_MEM,
},
};
@@ -190,110 +95,6 @@ struct platform_device mx3_camera = {
},
};
-static struct resource otg_resources[] = {
- {
- .start = MX31_OTG_BASE_ADDR,
- .end = MX31_OTG_BASE_ADDR + 0x1ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_USB3,
- .end = MXC_INT_USB3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 otg_dmamask = DMA_BIT_MASK(32);
-
-/* OTG gadget device */
-struct platform_device mxc_otg_udc_device = {
- .name = "fsl-usb2-udc",
- .id = -1,
- .dev = {
- .dma_mask = &otg_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = otg_resources,
- .num_resources = ARRAY_SIZE(otg_resources),
-};
-
-/* OTG host */
-struct platform_device mxc_otg_host = {
- .name = "mxc-ehci",
- .id = 0,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- .dma_mask = &otg_dmamask,
- },
- .resource = otg_resources,
- .num_resources = ARRAY_SIZE(otg_resources),
-};
-
-/* USB host 1 */
-
-static u64 usbh1_dmamask = ~(u32)0;
-
-static struct resource mxc_usbh1_resources[] = {
- {
- .start = MX31_OTG_BASE_ADDR + 0x200,
- .end = MX31_OTG_BASE_ADDR + 0x3ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_USB1,
- .end = MXC_INT_USB1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_usbh1 = {
- .name = "mxc-ehci",
- .id = 1,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- .dma_mask = &usbh1_dmamask,
- },
- .resource = mxc_usbh1_resources,
- .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
-};
-
-/* USB host 2 */
-static u64 usbh2_dmamask = ~(u32)0;
-
-static struct resource mxc_usbh2_resources[] = {
- {
- .start = MX31_OTG_BASE_ADDR + 0x400,
- .end = MX31_OTG_BASE_ADDR + 0x5ff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_USB2,
- .end = MXC_INT_USB2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_usbh2 = {
- .name = "mxc-ehci",
- .id = 2,
- .dev = {
- .coherent_dma_mask = 0xffffffff,
- .dma_mask = &usbh2_dmamask,
- },
- .resource = mxc_usbh2_resources,
- .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
-};
-
-static struct resource imx_wdt_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device imx_wdt_device0 = {
- .name = "imx2-wdt",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_wdt_resources),
- .resource = imx_wdt_resources,
-};
-
static struct resource imx_rtc_resources[] = {
{
.start = MX31_RTC_BASE_ADDR,
@@ -312,51 +113,3 @@ struct platform_device imx_rtc_device0 = {
.num_resources = ARRAY_SIZE(imx_rtc_resources),
.resource = imx_rtc_resources,
};
-
-static struct resource imx_kpp_resources[] = {
- {
- .start = MX3x_KPP_BASE_ADDR,
- .end = MX3x_KPP_BASE_ADDR + 0xf,
- .flags = IORESOURCE_MEM
- }, {
- .start = MX3x_INT_KPP,
- .end = MX3x_INT_KPP,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_kpp_device = {
- .name = "imx-keypad",
- .id = -1,
- .num_resources = ARRAY_SIZE(imx_kpp_resources),
- .resource = imx_kpp_resources,
-};
-
-static int __init mx3_devices_init(void)
-{
-#if defined(CONFIG_ARCH_MX31)
- if (cpu_is_mx31()) {
- imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
- imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
- mxc_register_device(&mxc_rnga_device, NULL);
- }
-#endif
-#if defined(CONFIG_ARCH_MX35)
- if (cpu_is_mx35()) {
- otg_resources[0].start = MX35_OTG_BASE_ADDR;
- otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff;
- otg_resources[1].start = MXC_INT_USBOTG;
- otg_resources[1].end = MXC_INT_USBOTG;
- mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400;
- mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
- mxc_usbh1_resources[1].start = MXC_INT_USBHS;
- mxc_usbh1_resources[1].end = MXC_INT_USBHS;
- imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
- imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
- }
-#endif
-
- return 0;
-}
-
-subsys_initcall(mx3_devices_init);
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 585f814473d5..121962c568d1 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -1,14 +1,4 @@
-extern struct platform_device mxc_w1_master_device;
extern struct platform_device mx3_ipu;
extern struct platform_device mx3_fb;
extern struct platform_device mx3_camera;
-extern struct platform_device mxcsdhc_device0;
-extern struct platform_device mxcsdhc_device1;
-extern struct platform_device mxc_otg_udc_device;
-extern struct platform_device mxc_otg_host;
-extern struct platform_device mxc_usbh1;
-extern struct platform_device mxc_usbh2;
-extern struct platform_device mxc_rnga_device;
-extern struct platform_device imx_wdt_device0;
extern struct platform_device imx_rtc_device0;
-extern struct platform_device imx_kpp_device;
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
index 1abc10d52922..14a5ffc939ad 100644
--- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
@@ -111,7 +111,7 @@ static struct mx3fb_platform_data mx3fb_pdata = {
.num_modes = ARRAY_SIZE(fb_modedb),
};
-static struct pad_desc eukrea_mbimxsd_pads[] = {
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
/* LCD */
MX35_PAD_LD0__IPU_DISPB_DAT_0,
MX35_PAD_LD1__IPU_DISPB_DAT_1,
@@ -289,7 +289,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
imx35_add_flexcan1(NULL);
- imx35_add_esdhc(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c
index aaa30fe18f85..28b6f414b5d5 100644
--- a/arch/arm/mach-mx3/mach-armadillo5x0.c
+++ b/arch/arm/mach-mx3/mach-armadillo5x0.c
@@ -49,10 +49,8 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
-#include <mach/mmc.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx31.h"
@@ -245,13 +243,13 @@ h2_free_cs:
return err;
}
-static struct mxc_usbh_platform_data usbotg_pdata = {
+static struct mxc_usbh_platform_data usbotg_pdata __initdata = {
.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 = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.init = usbh2_init,
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
@@ -453,7 +451,7 @@ static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
}
-static struct imxmmc_platform_data sdhc_pdata = {
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
.get_ro = armadillo5x0_sdhc1_get_ro,
.init = armadillo5x0_sdhc1_init,
.exit = armadillo5x0_sdhc1_exit,
@@ -520,7 +518,7 @@ static void __init armadillo5x0_init(void)
gpio_direction_input(MX31_PIN_GPIO1_0);
/* Register SDHC */
- mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+ imx31_add_mxc_mmc(0, &sdhc_pdata);
/* Register FB */
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
@@ -555,8 +553,8 @@ static void __init armadillo5x0_init(void)
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_otg_host, &usbotg_pdata);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx31_add_mxc_ehci_otg(&usbotg_pdata);
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
#endif
}
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
index 9fde873f5889..26ae90f02582 100644
--- a/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -30,7 +30,6 @@
#include <linux/i2c/tsc2007.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
#include <linux/i2c-gpio.h>
#include <asm/mach-types.h>
@@ -43,7 +42,6 @@
#include <mach/common.h>
#include <mach/iomux-mx35.h>
#include <mach/mxc_nand.h>
-#include <mach/mxc_ehci.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -74,11 +72,7 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
},
};
-static struct platform_device *devices[] __initdata = {
- &imx_wdt_device0,
-};
-
-static struct pad_desc eukrea_cpuimx35_pads[] = {
+static iomux_v3_cfg_t eukrea_cpuimx35_pads[] = {
/* UART1 */
MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS,
@@ -117,18 +111,18 @@ static const struct mxc_nand_platform_data
.flash_bbt = 1,
};
-static struct mxc_usbh_platform_data __maybe_unused otg_pdata = {
+static const struct mxc_usbh_platform_data otg_pdata __initconst = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data __maybe_unused usbh1_pdata = {
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
.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 = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
.workaround = FLS_USB2_WORKAROUND_ENGCM09152,
@@ -158,7 +152,7 @@ static void __init mxc_board_init(void)
ARRAY_SIZE(eukrea_cpuimx35_pads));
imx35_add_fec(NULL);
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx35_add_imx2_wdt(NULL);
imx35_add_imx_uart0(&uart_pdata);
imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
@@ -168,11 +162,11 @@ static void __init mxc_board_init(void)
imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
if (otg_mode_host)
- mxc_register_device(&mxc_otg_host, &otg_pdata);
+ imx35_add_mxc_ehci_otg(&otg_pdata);
else
- mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ imx35_add_fsl_usb2_udc(&otg_device_pdata);
- mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+ imx35_add_mxc_ehci_hs(&usbh1_pdata);
#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD
eukrea_mbimxsd35_baseboard_init();
diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
index 042cd5655e17..a5f3eb24e4d5 100644
--- a/arch/arm/mach-mx3/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
@@ -41,9 +41,9 @@
#include "devices-imx31.h"
#include "devices.h"
-#define KZM_ARM11_IO_ADDRESS(x) ( \
- IMX_IO_ADDRESS(x, MX31_CS4) ?: \
- IMX_IO_ADDRESS(x, MX31_CS5) ?: \
+#define KZM_ARM11_IO_ADDRESS(x) (IOMEM( \
+ IMX_IO_P2V_MODULE(x, MX31_CS4) ?: \
+ IMX_IO_P2V_MODULE(x, MX31_CS5)) ?: \
MX31_IO_ADDRESS(x))
/*
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 0ad9e7821082..4e516b49a901 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -22,8 +22,8 @@
#include <linux/mfd/mc13783.h>
#include <linux/spi/spi.h>
#include <linux/regulator/machine.h>
-#include <linux/fsl_devices.h>
-#include <linux/input/matrix_keypad.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -34,6 +34,7 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/3ds_debugboard.h>
+#include <mach/ulpi.h>
#include "devices-imx31.h"
#include "devices.h"
@@ -84,6 +85,21 @@ static int mx31_3ds_pins[] = {
MX31_PIN_KEY_COL1_KEY_COL1,
MX31_PIN_KEY_COL2_KEY_COL2,
MX31_PIN_KEY_COL3_KEY_COL3,
+ /* 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_PC_VS2, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1),
+ /* USB Host2 reset */
+ IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO),
};
/*
@@ -102,7 +118,7 @@ static const uint32_t mx31_3ds_keymap[] = {
KEY(2, 3, KEY_F10),
};
-static struct matrix_keymap_data mx31_3ds_keymap_data = {
+static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = {
.keymap = mx31_3ds_keymap,
.keymap_size = ARRAY_SIZE(mx31_3ds_keymap),
};
@@ -115,6 +131,13 @@ static struct regulator_init_data pwgtx_init = {
},
};
+static struct regulator_init_data gpo_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. */
@@ -122,6 +145,13 @@ static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
}, {
.id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
.init_data = &pwgtx_init,
+ }, {
+
+ .id = MC13783_REGU_GPO1, /* Turn on 1.8V */
+ .init_data = &gpo_init,
+ }, {
+ .id = MC13783_REGU_GPO3, /* Turn on 3.3V */
+ .init_data = &gpo_init,
},
};
@@ -129,7 +159,7 @@ static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
static struct mc13783_platform_data mc13783_pdata __initdata = {
.regulators = mx31_3ds_regulators,
.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
- .flags = MC13783_USE_REGULATOR,
+ .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
};
/* SPI */
@@ -175,6 +205,7 @@ mx31_3ds_nand_board_info __initconst = {
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
+#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP)
static int mx31_3ds_usbotg_init(void)
{
@@ -214,11 +245,77 @@ usbotg_free_reset:
return err;
}
-static struct fsl_usb2_platform_data usbotg_pdata = {
+static int mx31_3ds_host2_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_PC_VS2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG);
+
+ err = gpio_request(USBH2_RST_B, "usbh2-reset");
+ if (err) {
+ pr_err("Failed to request the USB Host 2 reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBH2_RST_B, 0);
+ if (err) {
+ pr_err("Failed to drive the USB Host 2 reset gpio\n");
+ goto usbotg_free_reset;
+ }
+
+ mdelay(1);
+ gpio_set_value(USBH2_RST_B, 1);
+ return 0;
+
+usbotg_free_reset:
+ gpio_free(USBH2_RST_B);
+ return err;
+}
+
+#if defined(CONFIG_USB_ULPI)
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = mx31_3ds_host2_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+#endif
+
+static const struct fsl_usb2_platform_data usbotg_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
+static int otg_mode_host;
+
+static int __init mx31_3ds_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=", mx31_3ds_otg_mode);
+
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -246,14 +343,27 @@ static void __init mxc_board_init(void)
spi_register_board_info(mx31_3ds_spi_devs,
ARRAY_SIZE(mx31_3ds_spi_devs));
- mxc_register_device(&imx_kpp_device, &mx31_3ds_keymap_data);
+ imx31_add_imx_keypad(&mx31_3ds_keymap_data);
mx31_3ds_usbotg_init();
- mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
+#if defined(CONFIG_USB_ULPI)
+ if (otg_mode_host) {
+ otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+
+ imx31_add_mxc_ehci_otg(&otg_pdata);
+ }
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+#endif
+ if (!otg_mode_host)
+ imx31_add_fsl_usb2_udc(&usbotg_pdata);
if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
printk(KERN_WARNING "Init of the debug board failed, all "
"devices on the debug board are unusable.\n");
+ imx31_add_imx2_wdt(NULL);
}
static void __init mx31_3ds_timer_init(void)
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
index 42f47faa6fd6..2c595483f356 100644
--- a/arch/arm/mach-mx3/mach-mx31lilly.c
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -42,7 +42,6 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lilly.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx31.h"
@@ -230,13 +229,13 @@ static struct mxc_usbh_platform_data usbotg_pdata = {
.flags = MXC_EHCI_POWER_PINS_ENABLED,
};
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
.init = usbh1_init,
.portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
};
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.init = usbh2_init,
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED,
@@ -249,8 +248,8 @@ static void lilly1131_usb_init(void)
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_usbh1, &usbh1_pdata);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
}
#else
diff --git a/arch/arm/mach-mx3/mach-mx31lite.c b/arch/arm/mach-mx3/mach-mx31lite.c
index b93895814cdf..9e64c66396e0 100644
--- a/arch/arm/mach-mx3/mach-mx31lite.c
+++ b/arch/arm/mach-mx3/mach-mx31lite.c
@@ -40,7 +40,6 @@
#include <mach/board-mx31lite.h>
#include <mach/iomux-mx3.h>
#include <mach/irqs.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx31.h"
@@ -171,7 +170,7 @@ static int usbh2_init(struct platform_device *pdev)
return 0;
}
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.init = usbh2_init,
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED,
@@ -258,7 +257,7 @@ static void __init mxc_board_init(void)
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
#endif
/* SMSC9117 IRQ pin */
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index eb5f426df224..203d21a510aa 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -40,8 +40,6 @@
#include <mach/hardware.h>
#include <mach/iomux-mx3.h>
#include <mach/ipu.h>
-#include <mach/mmc.h>
-#include <mach/mxc_ehci.h>
#include <mach/mx3_camera.h>
#include <mach/spi.h>
#include <mach/ulpi.h>
@@ -170,11 +168,11 @@ static const struct spi_imx_master moboard_spi1_pdata __initconst = {
static struct regulator_consumer_supply sdhc_consumers[] = {
{
- .dev = &mxcsdhc_device0.dev,
+ .dev_name = "mxc-mmc.0",
.supply = "sdhc0_vcc",
},
{
- .dev = &mxcsdhc_device1.dev,
+ .dev_name = "mxc-mmc.1",
.supply = "sdhc1_vcc",
},
};
@@ -345,7 +343,7 @@ static void moboard_sdhc1_exit(struct device *dev, void *data)
gpio_free(SDHC1_CD);
}
-static struct imxmmc_platform_data sdhc1_pdata = {
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
.get_ro = moboard_sdhc1_get_ro,
.init = moboard_sdhc1_init,
.exit = moboard_sdhc1_exit,
@@ -404,17 +402,23 @@ static void usb_xcvr_reset(void)
#if defined(CONFIG_USB_ULPI)
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED,
};
static int __init moboard_usbh2_init(void)
{
+ struct platform_device *pdev;
+
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
#else
static inline int moboard_usbh2_init(void) { return 0; }
@@ -520,7 +524,7 @@ static void __init mxc_board_init(void)
spi_register_board_info(moboard_spi_board_info,
ARRAY_SIZE(moboard_spi_board_info));
- mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
+ imx31_add_mxc_mmc(0, &sdhc1_pdata);
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
diff --git a/arch/arm/mach-mx3/mach-mx35_3ds.c b/arch/arm/mach-mx3/mach-mx35_3ds.c
index b66a75aa2e88..b1963f257c20 100644
--- a/arch/arm/mach-mx3/mach-mx35_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx35_3ds.c
@@ -26,7 +26,7 @@
#include <linux/platform_device.h>
#include <linux/memory.h>
#include <linux/gpio.h>
-#include <linux/fsl_devices.h>
+#include <linux/usb/otg.h>
#include <linux/mtd/physmap.h>
@@ -40,7 +40,6 @@
#include <mach/iomux-mx35.h>
#include <mach/irqs.h>
#include <mach/3ds_debugboard.h>
-#include <mach/mxc_ehci.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -81,7 +80,7 @@ static struct platform_device *devices[] __initdata = {
&mx35pdk_flash,
};
-static struct pad_desc mx35pdk_pads[] = {
+static iomux_v3_cfg_t mx35pdk_pads[] = {
/* UART1 */
MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS,
@@ -122,18 +121,38 @@ static struct pad_desc mx35pdk_pads[] = {
};
/* OTG config */
-static struct fsl_usb2_platform_data usb_otg_pdata = {
+static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI_WIDE,
};
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .portsc = MXC_EHCI_MODE_UTMI,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
/* USB HOST config */
-static struct mxc_usbh_platform_data usb_host_pdata = {
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
.portsc = MXC_EHCI_MODE_SERIAL,
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI |
MXC_EHCI_INTERNAL_PHY,
};
+static int otg_mode_host;
+
+static int __init mx35_3ds_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=", mx35_3ds_otg_mode);
+
/*
* Board specific initialization.
*/
@@ -142,16 +161,21 @@ static void __init mxc_board_init(void)
mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
imx35_add_fec(NULL);
+ imx35_add_imx2_wdt(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxc_otg_udc_device, &usb_otg_pdata);
+ if (otg_mode_host)
+ imx35_add_mxc_ehci_otg(&otg_pdata);
+
+ imx35_add_mxc_ehci_hs(&usb_host_pdata);
- mxc_register_device(&mxc_usbh1, &usb_host_pdata);
+ if (!otg_mode_host)
+ imx35_add_fsl_usb2_udc(&usb_otg_pdata);
imx35_add_mxc_nand(&mx35pdk_nand_board_info);
- imx35_add_esdhc(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, NULL);
if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
pr_warn("Init of the debugboard failed, all "
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c
index 2ff3f661a48e..b752f6bc20a2 100644
--- a/arch/arm/mach-mx3/mach-pcm037.c
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -27,7 +27,6 @@
#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>
@@ -43,10 +42,8 @@
#include <mach/hardware.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_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx31.h"
@@ -399,7 +396,7 @@ static void pcm970_sdhc1_exit(struct device *dev, void *data)
gpio_free(SDHC1_GPIO_WP);
}
-static struct imxmmc_platform_data sdhc_pdata = {
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
#ifdef PCM970_SDHC_RW_SWITCH
.get_ro = pcm970_sdhc1_get_ro,
#endif
@@ -441,7 +438,6 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size)
static struct platform_device *devices[] __initdata = {
&pcm037_flash,
&pcm037_sram_device,
- &imx_wdt_device0,
&pcm037_mt9t031,
&pcm037_mt9v022,
};
@@ -538,18 +534,18 @@ static struct platform_device pcm970_sja1000 = {
};
#if defined(CONFIG_USB_ULPI)
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh2_pdata = {
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
#endif
-static struct fsl_usb2_platform_data otg_device_pdata = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
@@ -607,12 +603,13 @@ static void __init mxc_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx31_add_imx2_wdt(NULL);
imx31_add_imx_uart0(&uart_pdata);
/* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */
imx31_add_imx_uart1(&uart_pdata);
imx31_add_imx_uart2(&uart_pdata);
- mxc_register_device(&mxc_w1_master_device, NULL);
+ imx31_add_mxc_w1(NULL);
/* LAN9217 IRQ pin */
ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
@@ -632,7 +629,7 @@ static void __init mxc_board_init(void)
imx31_add_imx_i2c2(&pcm037_i2c2_data);
imx31_add_mxc_nand(&pcm037_nand_board_info);
- mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+ imx31_add_mxc_mmc(0, &sdhc_pdata);
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
mxc_register_device(&mx3_fb, &mx3fb_pdata);
@@ -654,16 +651,16 @@ static void __init mxc_board_init(void)
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_otg_host, &otg_pdata);
+ imx31_add_mxc_ehci_otg(&otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
#endif
if (!otg_mode_host)
- mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ imx31_add_fsl_usb2_udc(&otg_device_pdata);
}
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index 4e1de87995d4..bcf83fc7e701 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -27,7 +27,6 @@
#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>
@@ -39,7 +38,6 @@
#include <mach/iomux-mx35.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
@@ -140,10 +138,9 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
static struct platform_device *devices[] __initdata = {
&pcm043_flash,
- &imx_wdt_device0,
};
-static struct pad_desc pcm043_pads[] = {
+static iomux_v3_cfg_t pcm043_pads[] = {
/* UART1 */
MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_RTS1__UART1_RTS,
@@ -230,8 +227,8 @@ static struct pad_desc pcm043_pads[] = {
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;
+ iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
int ret;
ret = gpio_request(AC97_GPIO_TXFS, "SSI");
@@ -240,7 +237,7 @@ static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
return;
}
- mxc_iomux_v3_setup_pad(&txfs_gpio);
+ mxc_iomux_v3_setup_pad(txfs_gpio);
/* warm reset */
gpio_direction_output(AC97_GPIO_TXFS, 1);
@@ -248,16 +245,16 @@ static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
gpio_set_value(AC97_GPIO_TXFS, 0);
gpio_free(AC97_GPIO_TXFS);
- mxc_iomux_v3_setup_pad(&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;
+ iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+ iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28;
+ iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
+ iomux_v3_cfg_t reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0;
int ret;
ret = gpio_request(AC97_GPIO_TXFS, "SSI");
@@ -272,9 +269,9 @@ static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
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);
+ 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);
@@ -284,8 +281,8 @@ static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
udelay(10);
gpio_direction_output(AC97_GPIO_RESET, 1);
- mxc_iomux_v3_setup_pad(&txd);
- mxc_iomux_v3_setup_pad(&txfs);
+ mxc_iomux_v3_setup_pad(txd);
+ mxc_iomux_v3_setup_pad(txfs);
gpio_free(AC97_GPIO_RESET);
err3:
@@ -311,19 +308,19 @@ pcm037_nand_board_info __initconst = {
};
#if defined(CONFIG_USB_ULPI)
-static struct mxc_usbh_platform_data otg_pdata = {
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
.portsc = MXC_EHCI_MODE_SERIAL,
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
MXC_EHCI_IPPUE_DOWN,
};
#endif
-static struct fsl_usb2_platform_data otg_device_pdata = {
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
};
@@ -364,6 +361,7 @@ static void __init mxc_board_init(void)
imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx35_add_imx2_wdt(NULL);
imx35_add_imx_uart0(&uart_pdata);
imx35_add_mxc_nand(&pcm037_nand_board_info);
@@ -386,16 +384,16 @@ static void __init mxc_board_init(void)
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- mxc_register_device(&mxc_otg_host, &otg_pdata);
+ imx35_add_mxc_ehci_otg(&otg_pdata);
}
- mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+ imx35_add_mxc_ehci_hs(&usbh1_pdata);
#endif
if (!otg_mode_host)
- mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ imx35_add_fsl_usb2_udc(&otg_device_pdata);
imx35_add_flexcan1(NULL);
- imx35_add_esdhc(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, NULL);
}
static void __init pcm043_timer_init(void)
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index b4ffc531a82c..47118f760244 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -36,40 +36,16 @@
* @ingroup Memory
*/
-/*!
- * This table defines static virtual address mappings for I/O regions.
- * These are the mappings common across all MX3 boards.
- */
-static struct map_desc mxc_io_desc[] __initdata = {
- {
- .virtual = X_MEMC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
- .length = X_MEMC_SIZE,
- .type = MT_DEVICE
- }, {
- .virtual = AVIC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AVIC_BASE_ADDR),
- .length = AVIC_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = SPBA0_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
- .length = SPBA0_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
+#ifdef CONFIG_SOC_IMX31
+static struct map_desc mx31_io_desc[] __initdata = {
+ imx_map_entry(MX31, X_MEMC, MT_DEVICE),
+ imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
};
-/*!
+/*
* 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.
@@ -77,34 +53,44 @@ static struct map_desc mxc_io_desc[] __initdata = {
void __init mx31_map_io(void)
{
mxc_set_cpu_type(MXC_CPU_MX31);
- mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
+ mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+ iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
}
-#ifdef CONFIG_ARCH_MX35
-void __init mx35_map_io(void)
+int imx31_register_gpios(void);
+void __init mx31_init_irq(void)
{
- mxc_set_cpu_type(MXC_CPU_MX35);
- mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR));
- mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
-
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+ mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
+ imx31_register_gpios();
}
-#endif
-
-int imx3x_register_gpios(void);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+static struct map_desc mx35_io_desc[] __initdata = {
+ imx_map_entry(MX35, X_MEMC, MT_DEVICE),
+ imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
+};
-void __init mx31_init_irq(void)
+void __init mx35_map_io(void)
{
- mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
- imx3x_register_gpios();
+ mxc_set_cpu_type(MXC_CPU_MX35);
+ mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+
+ iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
}
+int imx35_register_gpios(void);
void __init mx35_init_irq(void)
{
- mx31_init_irq();
+ mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+ imx35_register_gpios();
}
+#endif /* ifdef CONFIG_SOC_IMX35 */
#ifdef CONFIG_CACHE_L2X0
static int mxc_init_l2x0(void)
@@ -129,7 +115,7 @@ static int mxc_init_l2x0(void)
pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
}
- l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
+ l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
if (IS_ERR(l2x0_base)) {
printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
PTR_ERR(l2x0_base));
diff --git a/arch/arm/mach-mx3/mx31lilly-db.c b/arch/arm/mach-mx3/mx31lilly-db.c
index 827fd3c80201..8f1a38ebf5c8 100644
--- a/arch/arm/mach-mx3/mx31lilly-db.c
+++ b/arch/arm/mach-mx3/mx31lilly-db.c
@@ -34,7 +34,6 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lilly.h>
-#include <mach/mmc.h>
#include <mach/mx3fb.h>
#include <mach/ipu.h>
@@ -158,7 +157,7 @@ static void mxc_mmc1_exit(struct device *dev, void *data)
free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
}
-static struct imxmmc_platform_data mmc_pdata = {
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
.get_ro = mxc_mmc1_get_ro,
.init = mxc_mmc1_init,
.exit = mxc_mmc1_exit,
@@ -216,7 +215,7 @@ void __init mx31lilly_db_init(void)
imx31_add_imx_uart0(&uart_pdata);
imx31_add_imx_uart1(&uart_pdata);
imx31_add_imx_uart2(&uart_pdata);
- mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
+ imx31_add_mxc_mmc(0, &mmc_pdata);
mx31lilly_init_fb();
}
diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c
index 7b0e74e275ba..3124ea837ac7 100644
--- a/arch/arm/mach-mx3/mx31lite-db.c
+++ b/arch/arm/mach-mx3/mx31lite-db.c
@@ -35,7 +35,6 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lite.h>
-#include <mach/mmc.h>
#include "devices-imx31.h"
#include "devices.h"
@@ -142,7 +141,7 @@ static void mxc_mmc1_exit(struct device *dev, void *data)
free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
}
-static struct imxmmc_platform_data mmc_pdata = {
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
.get_ro = mxc_mmc1_get_ro,
.init = mxc_mmc1_init,
.exit = mxc_mmc1_exit,
@@ -197,10 +196,9 @@ void __init mx31lite_db_init(void)
ARRAY_SIZE(litekit_db_board_pins),
"development board pins");
imx31_add_imx_uart0(&uart_pdata);
- mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
+ imx31_add_mxc_mmc(0, &mmc_pdata);
imx31_add_spi_imx0(&spi0_pdata);
platform_device_register(&litekit_led_device);
- mxc_register_device(&imx_wdt_device0, NULL);
+ imx31_add_imx2_wdt(NULL);
mxc_register_device(&imx_rtc_device0, NULL);
}
-
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
index fc395a7a8599..94a0b9e4b7f3 100644
--- a/arch/arm/mach-mx3/mx31moboard-devboard.c
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -18,15 +18,12 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
-#include <linux/fsl_devices.h>
#include <linux/usb/otg.h>
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/hardware.h>
-#include <mach/mmc.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices-imx31.h"
@@ -103,7 +100,7 @@ static void devboard_sdhc2_exit(struct device *dev, void *data)
gpio_free(SDHC2_CD);
}
-static struct imxmmc_platform_data sdhc2_pdata = {
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
.get_ro = devboard_sdhc2_get_ro,
.init = devboard_sdhc2_init,
.exit = devboard_sdhc2_exit,
@@ -187,7 +184,7 @@ static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
return 0;
}
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
.init = devboard_usbh1_hw_init,
.portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
@@ -196,6 +193,7 @@ static struct mxc_usbh_platform_data usbh1_pdata = {
static int __init devboard_usbh1_init(void)
{
struct otg_transceiver *otg;
+ struct platform_device *pdev;
otg = kzalloc(sizeof(*otg), GFP_KERNEL);
if (!otg)
@@ -207,11 +205,15 @@ static int __init devboard_usbh1_init(void)
usbh1_pdata.otg = otg;
- return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
-static struct fsl_usb2_platform_data usb_pdata = {
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
@@ -228,11 +230,11 @@ void __init mx31moboard_devboard_init(void)
imx31_add_imx_uart1(&uart_pdata);
- mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+ imx31_add_mxc_mmc(1, &sdhc2_pdata);
devboard_init_sel_gpios();
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ imx31_add_fsl_usb2_udc(&usb_pdata);
devboard_usbh1_init();
}
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 18069cb7d068..f449a97ae1a2 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -21,7 +21,6 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/types.h>
-#include <linux/fsl_devices.h>
#include <linux/usb/otg.h>
@@ -29,12 +28,11 @@
#include <mach/hardware.h>
#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
-#include <mach/mmc.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <media/soc_camera.h>
+#include "devices-imx31.h"
#include "devices.h"
static unsigned int marxbot_pins[] = {
@@ -116,7 +114,7 @@ static void marxbot_sdhc2_exit(struct device *dev, void *data)
gpio_free(SDHC2_CD);
}
-static struct imxmmc_platform_data sdhc2_pdata = {
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
.get_ro = marxbot_sdhc2_get_ro,
.init = marxbot_sdhc2_init,
.exit = marxbot_sdhc2_exit,
@@ -302,7 +300,7 @@ static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
return 0;
}
-static struct mxc_usbh_platform_data usbh1_pdata = {
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
.init = marxbot_usbh1_hw_init,
.portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
@@ -311,6 +309,7 @@ static struct mxc_usbh_platform_data usbh1_pdata = {
static int __init marxbot_usbh1_init(void)
{
struct otg_transceiver *otg;
+ struct platform_device *pdev;
otg = kzalloc(sizeof(*otg), GFP_KERNEL);
if (!otg)
@@ -322,10 +321,14 @@ static int __init marxbot_usbh1_init(void)
usbh1_pdata.otg = otg;
- return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
-static struct fsl_usb2_platform_data usb_pdata = {
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
@@ -344,7 +347,7 @@ void __init mx31moboard_marxbot_init(void)
dspics_resets_init();
- mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+ imx31_add_mxc_mmc(1, &sdhc2_pdata);
spi_register_board_info(marxbot_spi_board_info,
ARRAY_SIZE(marxbot_spi_board_info));
@@ -357,7 +360,7 @@ void __init mx31moboard_marxbot_init(void)
gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ imx31_add_fsl_usb2_udc(&usb_pdata);
marxbot_usbh1_init();
}
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c
index 04760a53005a..bbec3c82264a 100644
--- a/arch/arm/mach-mx3/mx31moboard-smartbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c
@@ -19,7 +19,6 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/types.h>
-#include <linux/fsl_devices.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
@@ -28,7 +27,6 @@
#include <mach/hardware.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31moboard.h>
-#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <media/soc_camera.h>
@@ -118,24 +116,30 @@ static int __init smartbot_cam_init(void)
return 0;
}
-static struct fsl_usb2_platform_data usb_pdata = {
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
#if defined(CONFIG_USB_ULPI)
-static struct mxc_usbh_platform_data otg_host_pdata = {
+static struct mxc_usbh_platform_data otg_host_pdata __initdata = {
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED,
};
static int __init smartbot_otg_host_init(void)
{
+ struct platform_device *pdev;
+
otg_host_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- return mxc_register_device(&mxc_otg_host, &otg_host_pdata);
+ pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
#else
static inline int smartbot_otg_host_init(void) { return 0; }
@@ -182,7 +186,7 @@ void __init mx31moboard_smartbot_init(int board)
switch (board) {
case MX31SMARTBOT:
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ imx31_add_fsl_usb2_udc(&usb_pdata);
break;
case MX31EYEBOT:
smartbot_otg_host_init();
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 3ec910a7a182..55254b6e9460 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -1,20 +1,47 @@
if ARCH_MX5
+# ARCH_MX51 and ARCH_MX50 are left for compatibility
+
+config ARCH_MX50
+ bool
config ARCH_MX51
bool
- default y
+
+config ARCH_MX53
+ bool
+
+config SOC_IMX50
+ bool
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_HAS_CPUFREQ
+ select ARCH_MX50
+
+config SOC_IMX51
+ bool
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select ARCH_HAS_CPUFREQ
+ select ARCH_MX51
+
+config SOC_IMX53
+ bool
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MX53
comment "MX5 platforms:"
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_ESDHC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for MX51 Babbage platform, also known as MX51EVK in
u-boot. This includes specific configurations for the board and its
@@ -22,7 +49,9 @@ config MACH_MX51_BABBAGE
config MACH_MX51_3DS
bool "Support MX51PDK (3DS)"
+ select SOC_IMX51
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_DEBUG_BOARD
help
@@ -31,6 +60,7 @@ config MACH_MX51_3DS
config MACH_EUKREA_CPUIMX51
bool "Support Eukrea CPUIMX51 module"
+ select SOC_IMX51
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_NAND
@@ -47,7 +77,7 @@ choice
config MACH_EUKREA_MBIMX51_BASEBOARD
prompt "Eukrea MBIMX51 development board"
bool
- select IMX_HAVE_PLATFORM_ESDHC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
help
This adds board specific devices that can be found on Eukrea's
MBIMX51 evaluation board.
@@ -56,6 +86,7 @@ endchoice
config MACH_EUKREA_CPUIMX51SD
bool "Support Eukrea CPUIMX51SD module"
+ select SOC_IMX51
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_SPI_IMX
select IMX_HAVE_PLATFORM_IMX_UART
@@ -72,7 +103,7 @@ choice
config MACH_EUKREA_MBIMXSD51_BASEBOARD
prompt "Eukrea MBIMXSD development board"
bool
- select IMX_HAVE_PLATFORM_ESDHC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
help
This adds board specific devices that can be found on Eukrea's
MBIMXSD evaluation board.
@@ -81,9 +112,33 @@ endchoice
config MACH_MX51_EFIKAMX
bool "Support MX51 Genesi Efika MX nettop"
+ select SOC_IMX51
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for Genesi Efika MX nettop. This includes specific
configurations for the board and its peripherals.
+config MACH_MX53_EVK
+ bool "Support MX53 EVK platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for MX53 EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+
+config MACH_MX50_RDP
+ bool "Support MX50 reference design platform"
+ depends on BROKEN
+ select SOC_IMX50
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for MX50 reference design platform (RDP) board. 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
index 462f177eddfe..0c398baf11fe 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -3,13 +3,16 @@
#
# Object file lists.
-obj-y := cpu.o mm.o clock-mx51.o devices.o
+obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o
+obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
+obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o
obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o
obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
+obj-$(CONFIG_MACH_MX50_RDP) += board-mx50_rdp.o
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
index 9939a19d99a1..e928be1b6757 100644
--- a/arch/arm/mach-mx5/Makefile.boot
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -1,3 +1,9 @@
- zreladdr-y := 0x90008000
-params_phys-y := 0x90000100
-initrd_phys-y := 0x90800000
+ zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000
+params_phys-$(CONFIG_ARCH_MX50) := 0x70000100
+initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000
+ zreladdr-$(CONFIG_ARCH_MX51) := 0x90008000
+params_phys-$(CONFIG_ARCH_MX51) := 0x90000100
+initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
+ zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000
+params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
+initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
index 6a9792fd0a76..f8652ef25f85 100644
--- a/arch/arm/mach-mx5/board-cpuimx51.c
+++ b/arch/arm/mach-mx5/board-cpuimx51.c
@@ -40,11 +40,11 @@
#include "devices-imx51.h"
#include "devices.h"
-#define CPUIMX51_USBH1_STP (0*32 + 27)
-#define CPUIMX51_QUARTA_GPIO (2*32 + 28)
-#define CPUIMX51_QUARTB_GPIO (2*32 + 25)
-#define CPUIMX51_QUARTC_GPIO (2*32 + 26)
-#define CPUIMX51_QUARTD_GPIO (2*32 + 27)
+#define CPUIMX51_USBH1_STP IMX_GPIO_NR(1, 27)
+#define CPUIMX51_QUARTA_GPIO IMX_GPIO_NR(3, 28)
+#define CPUIMX51_QUARTB_GPIO IMX_GPIO_NR(3, 25)
+#define CPUIMX51_QUARTC_GPIO IMX_GPIO_NR(3, 26)
+#define CPUIMX51_QUARTD_GPIO IMX_GPIO_NR(3, 27)
#define CPUIMX51_QUARTA_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO)
#define CPUIMX51_QUARTB_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO)
#define CPUIMX51_QUARTC_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO)
@@ -113,7 +113,7 @@ static struct platform_device *devices[] __initdata = {
#endif
};
-static struct pad_desc eukrea_cpuimx51_pads[] = {
+static iomux_v3_cfg_t eukrea_cpuimx51_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
MX51_PAD_UART1_TXD__UART1_TXD,
@@ -121,15 +121,15 @@ static struct pad_desc eukrea_cpuimx51_pads[] = {
MX51_PAD_UART1_CTS__UART1_CTS,
/* I2C2 */
- MX51_PAD_GPIO_1_2__I2C2_SCL,
- MX51_PAD_GPIO_1_3__I2C2_SDA,
- MX51_PAD_NANDF_D10__GPIO_3_30,
+ MX51_PAD_GPIO1_2__I2C2_SCL,
+ MX51_PAD_GPIO1_3__I2C2_SDA,
+ MX51_PAD_NANDF_D10__GPIO3_30,
/* QUART IRQ */
- MX51_PAD_NANDF_D15__GPIO_3_25,
- MX51_PAD_NANDF_D14__GPIO_3_26,
- MX51_PAD_NANDF_D13__GPIO_3_27,
- MX51_PAD_NANDF_D12__GPIO_3_28,
+ MX51_PAD_NANDF_D15__GPIO3_25,
+ MX51_PAD_NANDF_D14__GPIO3_26,
+ MX51_PAD_NANDF_D13__GPIO3_27,
+ MX51_PAD_NANDF_D12__GPIO3_28,
/* USB HOST1 */
MX51_PAD_USBH1_CLK__USBH1_CLK,
@@ -178,6 +178,8 @@ static int initialize_otg_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* Set the PHY clock to 19.2MHz */
@@ -196,6 +198,8 @@ static int initialize_usbh1_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* The clock for the USBH1 ULPI port will come externally from the PHY. */
@@ -292,7 +296,7 @@ static struct sys_timer mxc_timer = {
MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")
/* Maintainer: Eric Bénard <eric@eukrea.com> */
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
.init_machine = eukrea_cpuimx51_init,
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index 4b3a6119c5fb..ad931895d8b6 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -43,19 +43,19 @@
#include "devices-imx51.h"
#include "devices.h"
-#define USBH1_RST (1*32 + 28)
-#define ETH_RST (1*32 + 31)
-#define TSC2007_IRQGPIO (2*32 + 12)
-#define CAN_IRQGPIO (0*32 + 1)
-#define CAN_RST (3*32 + 15)
-#define CAN_NCS (3*32 + 24)
-#define CAN_RXOBF (0*32 + 4)
-#define CAN_RX1BF (0*32 + 6)
-#define CAN_TXORTS (0*32 + 7)
-#define CAN_TX1RTS (0*32 + 8)
-#define CAN_TX2RTS (0*32 + 9)
-#define I2C_SCL (3*32 + 16)
-#define I2C_SDA (3*32 + 17)
+#define USBH1_RST IMX_GPIO_NR(2, 28)
+#define ETH_RST IMX_GPIO_NR(2, 31)
+#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 12)
+#define CAN_IRQGPIO IMX_GPIO_NR(1, 1)
+#define CAN_RST IMX_GPIO_NR(4, 15)
+#define CAN_NCS IMX_GPIO_NR(4, 24)
+#define CAN_RXOBF IMX_GPIO_NR(1, 4)
+#define CAN_RX1BF IMX_GPIO_NR(1, 6)
+#define CAN_TXORTS IMX_GPIO_NR(1, 7)
+#define CAN_TX1RTS IMX_GPIO_NR(1, 8)
+#define CAN_TX2RTS IMX_GPIO_NR(1, 9)
+#define I2C_SCL IMX_GPIO_NR(4, 16)
+#define I2C_SDA IMX_GPIO_NR(4, 17)
/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET 0x10
@@ -65,10 +65,7 @@
#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
#define MX51_USB_PLL_DIV_24_MHZ 0x02
-#define CPUIMX51SD_GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, \
- MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
-
-static struct pad_desc eukrea_cpuimx51sd_pads[] = {
+static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
MX51_PAD_UART1_TXD__UART1_TXD,
@@ -88,30 +85,33 @@ static struct pad_desc eukrea_cpuimx51sd_pads[] = {
MX51_PAD_USBH1_DATA6__USBH1_DATA6,
MX51_PAD_USBH1_DATA7__USBH1_DATA7,
MX51_PAD_USBH1_STP__USBH1_STP,
- MX51_PAD_EIM_CS3__GPIO_2_28, /* PHY nRESET */
+ MX51_PAD_EIM_CS3__GPIO2_28, /* PHY nRESET */
/* FEC */
- MX51_PAD_EIM_DTACK__GPIO_2_31, /* PHY nRESET */
+ MX51_PAD_EIM_DTACK__GPIO2_31, /* PHY nRESET */
/* HSI2C */
- MX51_PAD_I2C1_CLK__GPIO_4_16,
- MX51_PAD_I2C1_DAT__GPIO_4_17,
+ MX51_PAD_I2C1_CLK__GPIO4_16,
+ MX51_PAD_I2C1_DAT__GPIO4_17,
/* CAN */
MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
- MX51_PAD_CSPI1_SS0__GPIO_4_24, /* nCS */
- MX51_PAD_CSI2_PIXCLK__GPIO_4_15, /* nReset */
- MX51_PAD_GPIO_1_1__GPIO_1_1, /* IRQ */
- MX51_PAD_GPIO_1_4__GPIO_1_4, /* Control signals */
- MX51_PAD_GPIO_1_6__GPIO_1_6,
- MX51_PAD_GPIO_1_7__GPIO_1_7,
- MX51_PAD_GPIO_1_8__GPIO_1_8,
- MX51_PAD_GPIO_1_9__GPIO_1_9,
+ MX51_PAD_CSPI1_SS0__GPIO4_24, /* nCS */
+ MX51_PAD_CSI2_PIXCLK__GPIO4_15, /* nReset */
+ MX51_PAD_GPIO1_1__GPIO1_1, /* IRQ */
+ MX51_PAD_GPIO1_4__GPIO1_4, /* Control signals */
+ MX51_PAD_GPIO1_6__GPIO1_6,
+ MX51_PAD_GPIO1_7__GPIO1_7,
+ MX51_PAD_GPIO1_8__GPIO1_8,
+ MX51_PAD_GPIO1_9__GPIO1_9,
/* Touchscreen */
- CPUIMX51SD_GPIO_3_12, /* IRQ */
+ /* IRQ */
+ _MX51_PAD_CSI1_D8__GPIO3_12 | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
};
static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -157,6 +157,8 @@ static int initialize_otg_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* Set the PHY clock to 19.2MHz */
@@ -175,6 +177,8 @@ static int initialize_usbh1_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* The clock for the USBH1 ULPI port will come from the PHY. */
@@ -243,7 +247,7 @@ static struct spi_board_info cpuimx51sd_spi_device[] = {
.mode = SPI_MODE_0,
.chip_select = 0,
.platform_data = &mcp251x_info,
- .irq = gpio_to_irq(0 * 32 + 1)
+ .irq = gpio_to_irq(CAN_IRQGPIO)
},
};
@@ -323,7 +327,7 @@ static struct sys_timer mxc_timer = {
MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
/* Maintainer: Eric Bénard <eric@eukrea.com> */
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
.init_machine = eukrea_cpuimx51sd_init,
diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
new file mode 100644
index 000000000000..fd32e4c450e8
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx50_rdp.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx50.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-mx50.h"
+
+static iomux_v3_cfg_t mx50_rdp_pads[] __initdata = {
+ /* SD1 */
+ MX50_PAD_ECSPI2_SS0__GPIO_4_19,
+ MX50_PAD_EIM_CRE__GPIO_1_27,
+ MX50_PAD_SD1_CMD__SD1_CMD,
+
+ MX50_PAD_SD1_CLK__SD1_CLK,
+ MX50_PAD_SD1_D0__SD1_D0,
+ MX50_PAD_SD1_D1__SD1_D1,
+ MX50_PAD_SD1_D2__SD1_D2,
+ MX50_PAD_SD1_D3__SD1_D3,
+
+ /* SD2 */
+ MX50_PAD_SD2_CD__GPIO_5_17,
+ MX50_PAD_SD2_WP__GPIO_5_16,
+ MX50_PAD_SD2_CMD__SD2_CMD,
+ MX50_PAD_SD2_CLK__SD2_CLK,
+ MX50_PAD_SD2_D0__SD2_D0,
+ MX50_PAD_SD2_D1__SD2_D1,
+ MX50_PAD_SD2_D2__SD2_D2,
+ MX50_PAD_SD2_D3__SD2_D3,
+ MX50_PAD_SD2_D4__SD2_D4,
+ MX50_PAD_SD2_D5__SD2_D5,
+ MX50_PAD_SD2_D6__SD2_D6,
+ MX50_PAD_SD2_D7__SD2_D7,
+
+ /* SD3 */
+ MX50_PAD_SD3_CMD__SD3_CMD,
+ MX50_PAD_SD3_CLK__SD3_CLK,
+ MX50_PAD_SD3_D0__SD3_D0,
+ MX50_PAD_SD3_D1__SD3_D1,
+ MX50_PAD_SD3_D2__SD3_D2,
+ MX50_PAD_SD3_D3__SD3_D3,
+ MX50_PAD_SD3_D4__SD3_D4,
+ MX50_PAD_SD3_D5__SD3_D5,
+ MX50_PAD_SD3_D6__SD3_D6,
+ MX50_PAD_SD3_D7__SD3_D7,
+
+ /* PWR_INT */
+ MX50_PAD_ECSPI2_MISO__GPIO_4_18,
+
+ /* UART pad setting */
+ MX50_PAD_UART1_TXD__UART1_TXD,
+ MX50_PAD_UART1_RXD__UART1_RXD,
+ MX50_PAD_UART1_RTS__UART1_RTS,
+ MX50_PAD_UART2_TXD__UART2_TXD,
+ MX50_PAD_UART2_RXD__UART2_RXD,
+ MX50_PAD_UART2_CTS__UART2_CTS,
+ MX50_PAD_UART2_RTS__UART2_RTS,
+
+ MX50_PAD_I2C1_SCL__I2C1_SCL,
+ MX50_PAD_I2C1_SDA__I2C1_SDA,
+ MX50_PAD_I2C2_SCL__I2C2_SCL,
+ MX50_PAD_I2C2_SDA__I2C2_SDA,
+
+ MX50_PAD_EPITO__USBH1_PWR,
+ /* Need to comment below line if
+ * one needs to debug owire.
+ */
+ MX50_PAD_OWIRE__USBH1_OC,
+ /* using gpio to control otg pwr */
+ MX50_PAD_PWM2__GPIO_6_25,
+ MX50_PAD_I2C3_SCL__USBOTG_OC,
+
+ MX50_PAD_SSI_RXC__FEC_MDIO,
+ MX50_PAD_SSI_RXC__FEC_MDIO,
+ MX50_PAD_DISP_D0__FEC_TXCLK,
+ MX50_PAD_DISP_D1__FEC_RX_ER,
+ MX50_PAD_DISP_D2__FEC_RX_DV,
+ MX50_PAD_DISP_D3__FEC_RXD1,
+ MX50_PAD_DISP_D4__FEC_RXD0,
+ MX50_PAD_DISP_D5__FEC_TX_EN,
+ MX50_PAD_DISP_D6__FEC_TXD1,
+ MX50_PAD_DISP_D7__FEC_TXD0,
+ MX50_PAD_SSI_RXFS__FEC_MDC,
+ MX50_PAD_I2C3_SDA__GPIO_6_23,
+ MX50_PAD_ECSPI1_SCLK__GPIO_4_12,
+
+ MX50_PAD_CSPI_SS0__CSPI_SS0,
+ MX50_PAD_ECSPI1_MOSI__CSPI_SS1,
+ MX50_PAD_CSPI_MOSI__CSPI_MOSI,
+ MX50_PAD_CSPI_MISO__CSPI_MISO,
+
+ /* SGTL500_OSC_EN */
+ MX50_PAD_UART1_CTS__GPIO_6_8,
+
+ /* SGTL_AMP_SHDN */
+ MX50_PAD_UART3_RXD__GPIO_6_15,
+
+ /* Keypad */
+ MX50_PAD_KEY_COL0__KEY_COL0,
+ MX50_PAD_KEY_ROW0__KEY_ROW0,
+ MX50_PAD_KEY_COL1__KEY_COL1,
+ MX50_PAD_KEY_ROW1__KEY_ROW1,
+ MX50_PAD_KEY_COL2__KEY_COL2,
+ MX50_PAD_KEY_ROW2__KEY_ROW2,
+ MX50_PAD_KEY_COL3__KEY_COL3,
+ MX50_PAD_KEY_ROW3__KEY_ROW3,
+ MX50_PAD_EIM_DA0__KEY_COL4,
+ MX50_PAD_EIM_DA1__KEY_ROW4,
+ MX50_PAD_EIM_DA2__KEY_COL5,
+ MX50_PAD_EIM_DA3__KEY_ROW5,
+ MX50_PAD_EIM_DA4__KEY_COL6,
+ MX50_PAD_EIM_DA5__KEY_ROW6,
+ MX50_PAD_EIM_DA6__KEY_COL7,
+ MX50_PAD_EIM_DA7__KEY_ROW7,
+ /*EIM pads */
+ MX50_PAD_EIM_DA8__GPIO_1_8,
+ MX50_PAD_EIM_DA9__GPIO_1_9,
+ MX50_PAD_EIM_DA10__GPIO_1_10,
+ MX50_PAD_EIM_DA11__GPIO_1_11,
+ MX50_PAD_EIM_DA12__GPIO_1_12,
+ MX50_PAD_EIM_DA13__GPIO_1_13,
+ MX50_PAD_EIM_DA14__GPIO_1_14,
+ MX50_PAD_EIM_DA15__GPIO_1_15,
+ MX50_PAD_EIM_CS2__GPIO_1_16,
+ MX50_PAD_EIM_CS1__GPIO_1_17,
+ MX50_PAD_EIM_CS0__GPIO_1_18,
+ MX50_PAD_EIM_EB0__GPIO_1_19,
+ MX50_PAD_EIM_EB1__GPIO_1_20,
+ MX50_PAD_EIM_WAIT__GPIO_1_21,
+ MX50_PAD_EIM_BCLK__GPIO_1_22,
+ MX50_PAD_EIM_RDY__GPIO_1_23,
+ MX50_PAD_EIM_OE__GPIO_1_24,
+};
+
+/* Serial ports */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx50_rdp_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads,
+ ARRAY_SIZE(mx50_rdp_pads));
+
+ imx50_add_imx_uart(0, &uart_pdata);
+ imx50_add_imx_uart(1, &uart_pdata);
+}
+
+static void __init mx50_rdp_timer_init(void)
+{
+ mx50_clocks_init(32768, 24000000, 22579200);
+}
+
+static struct sys_timer mx50_rdp_timer = {
+ .init = mx50_rdp_timer_init,
+};
+
+MACHINE_START(MX50_RDP, "Freescale MX50 Reference Design Platform")
+ .map_io = mx50_map_io,
+ .init_irq = mx50_init_irq,
+ .init_machine = mx50_rdp_board_init,
+ .timer = &mx50_rdp_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
index 79ce8dcf3cda..e42bd2eb034e 100644
--- a/arch/arm/mach-mx5/board-mx51_3ds.c
+++ b/arch/arm/mach-mx5/board-mx51_3ds.c
@@ -30,7 +30,7 @@
#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
#define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28)
-static struct pad_desc mx51_3ds_pads[] = {
+static iomux_v3_cfg_t mx51_3ds_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
MX51_PAD_UART1_TXD__UART1_TXD,
@@ -50,7 +50,7 @@ static struct pad_desc mx51_3ds_pads[] = {
MX51_PAD_EIM_D27__UART3_RTS,
/* CPLD PARENT IRQ PIN */
- MX51_PAD_GPIO_1_6__GPIO_1_6,
+ MX51_PAD_GPIO1_6__GPIO1_6,
/* KPP */
MX51_PAD_KEY_ROW0__KEY_ROW0,
@@ -68,7 +68,7 @@ static struct pad_desc mx51_3ds_pads[] = {
MX51_PAD_NANDF_RB2__ECSPI2_SCLK,
MX51_PAD_NANDF_RB3__ECSPI2_MISO,
MX51_PAD_NANDF_D15__ECSPI2_MOSI,
- MX51_PAD_NANDF_D12__GPIO_3_28,
+ MX51_PAD_NANDF_D12__GPIO3_28,
};
/* Serial ports */
@@ -172,6 +172,7 @@ static void __init mxc_board_init(void)
printk(KERN_WARNING "Init of the debugboard failed, all "
"devices on the board are unusable.\n");
+ imx51_add_sdhci_esdhc_imx(0, NULL);
mxc_init_keypad();
}
@@ -186,7 +187,7 @@ static struct sys_timer mxc_timer = {
MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
/* Maintainer: Freescale Semiconductor, Inc. */
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
.map_io = mx51_map_io,
.init_irq = mx51_init_irq,
.init_machine = mxc_board_init,
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index acbe30df2e69..1d231e84107c 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -20,6 +20,8 @@
#include <linux/fec.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
#include <mach/common.h>
#include <mach/hardware.h>
@@ -36,11 +38,13 @@
#include "devices.h"
#include "cpu_op-mx51.h"
-#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
-#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
-#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */
-#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */
-#define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */
+#define BABBAGE_USB_HUB_RESET IMX_GPIO_NR(1, 7)
+#define BABBAGE_USBH1_STP IMX_GPIO_NR(1, 27)
+#define BABBAGE_PHY_RESET IMX_GPIO_NR(2, 5)
+#define BABBAGE_FEC_PHY_RESET IMX_GPIO_NR(2, 14)
+#define BABBAGE_POWER_KEY IMX_GPIO_NR(2, 21)
+#define BABBAGE_ECSPI1_CS0 IMX_GPIO_NR(4, 24)
+#define BABBAGE_ECSPI1_CS1 IMX_GPIO_NR(4, 25)
/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET 0x10
@@ -65,7 +69,7 @@ static const struct gpio_keys_platform_data imx_button_data __initconst = {
.nbuttons = ARRAY_SIZE(babbage_buttons),
};
-static struct pad_desc mx51babbage_pads[] = {
+static iomux_v3_cfg_t mx51babbage_pads[] = {
/* UART1 */
MX51_PAD_UART1_RXD__UART1_RXD,
MX51_PAD_UART1_TXD__UART1_TXD,
@@ -91,8 +95,8 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_KEY_COL5__I2C2_SDA,
/* HSI2C */
- MX51_PAD_I2C1_CLK__HSI2C_CLK,
- MX51_PAD_I2C1_DAT__HSI2C_DAT,
+ MX51_PAD_I2C1_CLK__I2C1_CLK,
+ MX51_PAD_I2C1_DAT__I2C1_DAT,
/* USB HOST1 */
MX51_PAD_USBH1_CLK__USBH1_CLK,
@@ -108,29 +112,29 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_USBH1_DATA7__USBH1_DATA7,
/* USB HUB reset line*/
- MX51_PAD_GPIO_1_7__GPIO_1_7,
+ MX51_PAD_GPIO1_7__GPIO1_7,
/* FEC */
MX51_PAD_EIM_EB2__FEC_MDIO,
- MX51_PAD_EIM_EB3__FEC_RDAT1,
- MX51_PAD_EIM_CS2__FEC_RDAT2,
- MX51_PAD_EIM_CS3__FEC_RDAT3,
+ MX51_PAD_EIM_EB3__FEC_RDATA1,
+ MX51_PAD_EIM_CS2__FEC_RDATA2,
+ MX51_PAD_EIM_CS3__FEC_RDATA3,
MX51_PAD_EIM_CS4__FEC_RX_ER,
MX51_PAD_EIM_CS5__FEC_CRS,
MX51_PAD_NANDF_RB2__FEC_COL,
- MX51_PAD_NANDF_RB3__FEC_RXCLK,
- MX51_PAD_NANDF_RB6__FEC_RDAT0,
- MX51_PAD_NANDF_RB7__FEC_TDAT0,
+ MX51_PAD_NANDF_RB3__FEC_RX_CLK,
+ MX51_PAD_NANDF_D9__FEC_RDATA0,
+ MX51_PAD_NANDF_D8__FEC_TDATA0,
MX51_PAD_NANDF_CS2__FEC_TX_ER,
MX51_PAD_NANDF_CS3__FEC_MDC,
- MX51_PAD_NANDF_CS4__FEC_TDAT1,
- MX51_PAD_NANDF_CS5__FEC_TDAT2,
- MX51_PAD_NANDF_CS6__FEC_TDAT3,
+ MX51_PAD_NANDF_CS4__FEC_TDATA1,
+ MX51_PAD_NANDF_CS5__FEC_TDATA2,
+ MX51_PAD_NANDF_CS6__FEC_TDATA3,
MX51_PAD_NANDF_CS7__FEC_TX_EN,
MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
/* FEC PHY reset line */
- MX51_PAD_EIM_A20__GPIO_2_14,
+ MX51_PAD_EIM_A20__GPIO2_14,
/* SD 1 */
MX51_PAD_SD1_CMD__SD1_CMD,
@@ -147,6 +151,13 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_SD2_DATA1__SD2_DATA1,
MX51_PAD_SD2_DATA2__SD2_DATA2,
MX51_PAD_SD2_DATA3__SD2_DATA3,
+
+ /* eCSPI1 */
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+ MX51_PAD_CSPI1_SS0__GPIO4_24,
+ MX51_PAD_CSPI1_SS1__GPIO4_25,
};
/* Serial ports */
@@ -177,12 +188,12 @@ static struct imxi2c_platform_data babbage_hsi2c_data = {
static int gpio_usbh1_active(void)
{
- struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27;
- struct pad_desc phyreset_gpio = MX51_PAD_EIM_D21__GPIO_2_5;
+ iomux_v3_cfg_t usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO1_27;
+ iomux_v3_cfg_t phyreset_gpio = MX51_PAD_EIM_D21__GPIO2_5;
int ret;
/* Set USBH1_STP to GPIO and toggle it */
- mxc_iomux_v3_setup_pad(&usbh1stp_gpio);
+ mxc_iomux_v3_setup_pad(usbh1stp_gpio);
ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp");
if (ret) {
@@ -195,7 +206,7 @@ static int gpio_usbh1_active(void)
gpio_free(BABBAGE_USBH1_STP);
/* De-assert USB PHY RESETB */
- mxc_iomux_v3_setup_pad(&phyreset_gpio);
+ mxc_iomux_v3_setup_pad(phyreset_gpio);
ret = gpio_request(BABBAGE_PHY_RESET, "phy_reset");
if (ret) {
@@ -251,6 +262,8 @@ static int initialize_otg_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* Set the PHY clock to 19.2MHz */
@@ -269,6 +282,8 @@ static int initialize_usbh1_port(struct platform_device *pdev)
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
/* The clock for the USBH1 ULPI port will come externally from the PHY. */
@@ -310,13 +325,35 @@ static int __init babbage_otg_mode(char *options)
}
__setup("otg_mode=", babbage_otg_mode);
+static struct spi_board_info mx51_babbage_spi_board_info[] __initdata = {
+ {
+ .modalias = "mtd_dataflash",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,
+ },
+};
+
+static int mx51_babbage_spi_cs[] = {
+ BABBAGE_ECSPI1_CS0,
+ BABBAGE_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = {
+ .chipselect = mx51_babbage_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_babbage_spi_cs),
+};
+
/*
* Board specific initialization.
*/
static void __init mxc_board_init(void)
{
- struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
- struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21;
+ iomux_v3_cfg_t usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+ iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 |
+ MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP);
#if defined(CONFIG_CPU_FREQ_IMX)
get_cpu_op = mx51_get_cpu_op;
@@ -328,8 +365,7 @@ static void __init mxc_board_init(void)
imx51_add_fec(NULL);
/* Set the PAD settings for the pwr key. */
- power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
- mxc_iomux_v3_setup_pad(&power_key);
+ mxc_iomux_v3_setup_pad(power_key);
imx51_add_gpio_keys(&imx_button_data);
imx51_add_imx_i2c(0, &babbage_i2c_data);
@@ -346,11 +382,16 @@ static void __init mxc_board_init(void)
gpio_usbh1_active();
mxc_register_device(&mxc_usbh1_device, &usbh1_config);
/* setback USBH1_STP to be function */
- mxc_iomux_v3_setup_pad(&usbh1stp);
+ mxc_iomux_v3_setup_pad(usbh1stp);
babbage_usbhub_reset();
- imx51_add_esdhc(0, NULL);
- imx51_add_esdhc(1, NULL);
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+ imx51_add_sdhci_esdhc_imx(1, NULL);
+
+ spi_register_board_info(mx51_babbage_spi_board_info,
+ ARRAY_SIZE(mx51_babbage_spi_board_info));
+ imx51_add_ecspi(0, &mx51_babbage_spi_pdata);
+ imx51_add_imx2_wdt(0, NULL);
}
static void __init mx51_babbage_timer_init(void)
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c
index 6e623bda3ee7..b7946f8e8d40 100644
--- a/arch/arm/mach-mx5/board-mx51_efikamx.c
+++ b/arch/arm/mach-mx5/board-mx51_efikamx.c
@@ -18,9 +18,13 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/fsl_devices.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
#include <mach/common.h>
#include <mach/hardware.h>
@@ -39,12 +43,81 @@
#define MX51_USB_PLL_DIV_24_MHZ 0x01
-static struct pad_desc mx51efikamx_pads[] = {
+#define EFIKAMX_PCBID0 IMX_GPIO_NR(3, 16)
+#define EFIKAMX_PCBID1 IMX_GPIO_NR(3, 17)
+#define EFIKAMX_PCBID2 IMX_GPIO_NR(3, 11)
+
+#define EFIKAMX_BLUE_LED IMX_GPIO_NR(3, 13)
+#define EFIKAMX_GREEN_LED IMX_GPIO_NR(3, 14)
+#define EFIKAMX_RED_LED IMX_GPIO_NR(3, 15)
+
+#define EFIKAMX_POWER_KEY IMX_GPIO_NR(2, 31)
+
+#define EFIKAMX_SPI_CS0 IMX_GPIO_NR(4, 24)
+#define EFIKAMX_SPI_CS1 IMX_GPIO_NR(4, 25)
+
+/* board 1.1 doesn't have same reset gpio */
+#define EFIKAMX_RESET1_1 IMX_GPIO_NR(3, 2)
+#define EFIKAMX_RESET IMX_GPIO_NR(1, 4)
+
+/* the pci ids pin have pull up. they're driven low according to board id */
+#define MX51_PAD_PCBID0 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PCBID1 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PCBID2 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE)
+
+static iomux_v3_cfg_t mx51efikamx_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,
+ /* board id */
+ MX51_PAD_PCBID0,
+ MX51_PAD_PCBID1,
+ MX51_PAD_PCBID2,
+
+ /* SD 1 */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SD 2 */
+ MX51_PAD_SD2_CMD__SD2_CMD,
+ MX51_PAD_SD2_CLK__SD2_CLK,
+ MX51_PAD_SD2_DATA0__SD2_DATA0,
+ MX51_PAD_SD2_DATA1__SD2_DATA1,
+ MX51_PAD_SD2_DATA2__SD2_DATA2,
+ MX51_PAD_SD2_DATA3__SD2_DATA3,
+
+ /* SD/MMC WP/CD */
+ MX51_PAD_GPIO1_0__SD1_CD,
+ MX51_PAD_GPIO1_1__SD1_WP,
+ MX51_PAD_GPIO1_7__SD2_WP,
+ MX51_PAD_GPIO1_8__SD2_CD,
+
+ /* leds */
+ MX51_PAD_CSI1_D9__GPIO3_13,
+ MX51_PAD_CSI1_VSYNC__GPIO3_14,
+ MX51_PAD_CSI1_HSYNC__GPIO3_15,
+
+ /* power key */
+ MX51_PAD_PWRKEY,
+
+ /* spi */
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_SS0__GPIO4_24,
+ MX51_PAD_CSPI1_SS1__GPIO4_25,
+ MX51_PAD_CSPI1_RDY__ECSPI1_RDY,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+
+ /* reset */
+ MX51_PAD_DI1_PIN13__GPIO3_2,
+ MX51_PAD_GPIO1_4__GPIO1_4,
};
/* Serial ports */
@@ -75,6 +148,8 @@ static int initialize_otg_port(struct platform_device *pdev)
void __iomem *usb_base;
void __iomem *usbother_base;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET);
/* Set the PHY clock to 19.2MHz */
@@ -92,12 +167,182 @@ static struct mxc_usbh_platform_data dr_utmi_config = {
.flags = MXC_EHCI_INTERNAL_PHY,
};
+/* PCBID2 PCBID1 PCBID0 STATE
+ 1 1 1 ER1:rev1.1
+ 1 1 0 ER2:rev1.2
+ 1 0 1 ER3:rev1.3
+ 1 0 0 ER4:rev1.4
+*/
+static void __init mx51_efikamx_board_id(void)
+{
+ int id;
+
+ /* things are taking time to settle */
+ msleep(150);
+
+ gpio_request(EFIKAMX_PCBID0, "pcbid0");
+ gpio_direction_input(EFIKAMX_PCBID0);
+ gpio_request(EFIKAMX_PCBID1, "pcbid1");
+ gpio_direction_input(EFIKAMX_PCBID1);
+ gpio_request(EFIKAMX_PCBID2, "pcbid2");
+ gpio_direction_input(EFIKAMX_PCBID2);
+
+ id = gpio_get_value(EFIKAMX_PCBID0);
+ id |= gpio_get_value(EFIKAMX_PCBID1) << 1;
+ id |= gpio_get_value(EFIKAMX_PCBID2) << 2;
+
+ switch (id) {
+ case 7:
+ system_rev = 0x11;
+ break;
+ case 6:
+ system_rev = 0x12;
+ break;
+ case 5:
+ system_rev = 0x13;
+ break;
+ case 4:
+ system_rev = 0x14;
+ break;
+ default:
+ system_rev = 0x10;
+ break;
+ }
+
+ if ((system_rev == 0x10)
+ || (system_rev == 0x12)
+ || (system_rev == 0x14)) {
+ printk(KERN_WARNING
+ "EfikaMX: Unsupported board revision 1.%u!\n",
+ system_rev & 0xf);
+ }
+}
+
+static struct gpio_led mx51_efikamx_leds[] = {
+ {
+ .name = "efikamx:green",
+ .default_trigger = "default-on",
+ .gpio = EFIKAMX_GREEN_LED,
+ },
+ {
+ .name = "efikamx:red",
+ .default_trigger = "ide-disk",
+ .gpio = EFIKAMX_RED_LED,
+ },
+ {
+ .name = "efikamx:blue",
+ .default_trigger = "mmc0",
+ .gpio = EFIKAMX_BLUE_LED,
+ },
+};
+
+static struct gpio_led_platform_data mx51_efikamx_leds_data = {
+ .leds = mx51_efikamx_leds,
+ .num_leds = ARRAY_SIZE(mx51_efikamx_leds),
+};
+
+static struct platform_device mx51_efikamx_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mx51_efikamx_leds_data,
+ },
+};
+
+static struct gpio_keys_button mx51_efikamx_powerkey[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = EFIKAMX_POWER_KEY,
+ .type = EV_PWR,
+ .desc = "Power Button (CM)",
+ .wakeup = 1,
+ .debounce_interval = 10, /* ms */
+ },
+};
+
+static const struct gpio_keys_platform_data mx51_efikamx_powerkey_data __initconst = {
+ .buttons = mx51_efikamx_powerkey,
+ .nbuttons = ARRAY_SIZE(mx51_efikamx_powerkey),
+};
+
+static struct mtd_partition mx51_efikamx_spi_nor_partitions[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_256K,
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ },
+};
+
+static struct flash_platform_data mx51_efikamx_spi_flash_data = {
+ .name = "spi_flash",
+ .parts = mx51_efikamx_spi_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mx51_efikamx_spi_nor_partitions),
+ .type = "sst25vf032b",
+};
+
+static struct spi_board_info mx51_efikamx_spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &mx51_efikamx_spi_flash_data,
+ .irq = -1,
+ },
+};
+
+static int mx51_efikamx_spi_cs[] = {
+ EFIKAMX_SPI_CS0,
+ EFIKAMX_SPI_CS1,
+};
+
+static const struct spi_imx_master mx51_efikamx_spi_pdata __initconst = {
+ .chipselect = mx51_efikamx_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_efikamx_spi_cs),
+};
+
+void mx51_efikamx_reset(void)
+{
+ if (system_rev == 0x11)
+ gpio_direction_output(EFIKAMX_RESET1_1, 0);
+ else
+ gpio_direction_output(EFIKAMX_RESET, 0);
+}
+
static void __init mxc_board_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
ARRAY_SIZE(mx51efikamx_pads));
+ mx51_efikamx_board_id();
mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
mxc_init_imx_uart();
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+
+ /* on < 1.2 boards both SD controllers are used */
+ if (system_rev < 0x12) {
+ imx51_add_sdhci_esdhc_imx(1, NULL);
+ mx51_efikamx_leds[2].default_trigger = "mmc1";
+ }
+
+ platform_device_register(&mx51_efikamx_leds_device);
+ imx51_add_gpio_keys(&mx51_efikamx_powerkey_data);
+
+ spi_register_board_info(mx51_efikamx_spi_board_info,
+ ARRAY_SIZE(mx51_efikamx_spi_board_info));
+ imx51_add_ecspi(0, &mx51_efikamx_spi_pdata);
+
+ if (system_rev == 0x11) {
+ gpio_request(EFIKAMX_RESET1_1, "reset");
+ gpio_direction_output(EFIKAMX_RESET1_1, 1);
+ } else {
+ gpio_request(EFIKAMX_RESET, "reset");
+ gpio_direction_output(EFIKAMX_RESET, 1);
+ }
}
static void __init mx51_efikamx_timer_init(void)
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
new file mode 100644
index 000000000000..fa97d0d5dd05
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.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 <mach/imx-uart.h>
+#include <mach/iomux-mx53.h>
+
+#include "crm_regs.h"
+#include "devices-imx53.h"
+
+static iomux_v3_cfg_t mx53_evk_pads[] = {
+ MX53_PAD_CSI0_D10__UART1_TXD,
+ MX53_PAD_CSI0_D11__UART1_RXD,
+ MX53_PAD_ATA_DIOW__UART1_TXD,
+ MX53_PAD_ATA_DMACK__UART1_RXD,
+
+ MX53_PAD_ATA_BUFFER_EN__UART2_RXD,
+ MX53_PAD_ATA_DMARQ__UART2_TXD,
+ MX53_PAD_ATA_DIOR__UART2_RTS,
+ MX53_PAD_ATA_INTRQ__UART2_CTS,
+
+ MX53_PAD_ATA_CS_0__UART3_TXD,
+ MX53_PAD_ATA_CS_1__UART3_RXD,
+ MX53_PAD_ATA_DA_1__UART3_CTS,
+ MX53_PAD_ATA_DA_2__UART3_RTS,
+};
+
+static const struct imxuart_platform_data mx53_evk_uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mx53_evk_init_uart(void)
+{
+ imx53_add_imx_uart(0, &mx53_evk_uart_pdata);
+ imx53_add_imx_uart(1, &mx53_evk_uart_pdata);
+ imx53_add_imx_uart(2, &mx53_evk_uart_pdata);
+}
+
+static void __init mx53_evk_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
+ ARRAY_SIZE(mx53_evk_pads));
+ mx53_evk_init_uart();
+}
+
+static void __init mx53_evk_timer_init(void)
+{
+ mx53_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx53_evk_timer = {
+ .init = mx53_evk_timer_init,
+};
+
+MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board")
+ .map_io = mx53_map_io,
+ .init_irq = mx53_init_irq,
+ .init_machine = mx53_evk_board_init,
+ .timer = &mx53_evk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 8ac36d882927..785e1a336183 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -14,8 +14,8 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/div64.h>
#include <mach/hardware.h>
@@ -33,11 +33,15 @@ 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 mx53_pll4_sw_clk;
static struct clk lp_apm_clk;
static struct clk periph_apm_clk;
static struct clk ahb_clk;
static struct clk ipg_clk;
static struct clk usboh3_clk;
+static struct clk emi_fast_clk;
+static struct clk ipu_clk;
+static struct clk mipi_hsc1_clk;
#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
@@ -123,7 +127,7 @@ static inline u32 _get_mux(struct clk *parent, struct clk *m0,
return -EINVAL;
}
-static inline void __iomem *_get_pll_base(struct clk *pll)
+static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
{
if (pll == &pll1_main_clk)
return MX51_DPLL1_BASE;
@@ -137,6 +141,30 @@ static inline void __iomem *_get_pll_base(struct clk *pll)
return NULL;
}
+static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return MX53_DPLL1_BASE;
+ else if (pll == &pll2_sw_clk)
+ return MX53_DPLL2_BASE;
+ else if (pll == &pll3_sw_clk)
+ return MX53_DPLL3_BASE;
+ else if (pll == &mx53_pll4_sw_clk)
+ return MX53_DPLL4_BASE;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (cpu_is_mx51())
+ return _mx51_get_pll_base(pll);
+ else
+ return _mx53_get_pll_base(pll);
+}
+
static unsigned long clk_pll_get_rate(struct clk *clk)
{
long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
@@ -514,7 +542,10 @@ static int _clk_max_enable(struct clk *clk)
/* Handshake with MAX when LPM is entered. */
reg = __raw_readl(MXC_CCM_CLPCR);
- reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ if (cpu_is_mx51())
+ reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ else if (cpu_is_mx53())
+ reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
__raw_writel(reg, MXC_CCM_CLPCR);
return 0;
@@ -528,7 +559,10 @@ static void _clk_max_disable(struct clk *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;
+ if (cpu_is_mx51())
+ reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ else if (cpu_is_mx53())
+ reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
__raw_writel(reg, MXC_CCM_CLPCR);
}
@@ -679,6 +713,19 @@ static unsigned long clk_emi_slow_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / div;
}
+static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
+ MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
+ rate = clk_get_rate(clk->parent) / div;
+
+ return rate;
+}
+
/* External high frequency clock */
static struct clk ckih_clk = {
.get_rate = get_high_reference_clock_rate,
@@ -739,6 +786,14 @@ static struct clk pll3_sw_clk = {
.disable = _clk_pll_disable,
};
+/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
+static struct clk mx53_pll4_sw_clk = {
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
/* Low-power Audio Playback Mode clock */
static struct clk lp_apm_clk = {
.parent = &osc_clk,
@@ -763,6 +818,12 @@ static struct clk ahb_clk = {
.round_rate = _clk_ahb_round_rate,
};
+static struct clk iim_clk = {
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+};
+
/* Main IP interface clock for access to registers */
static struct clk ipg_clk = {
.parent = &ahb_clk,
@@ -810,6 +871,10 @@ static struct clk kpp_clk = {
.id = 0,
};
+static struct clk dummy_clk = {
+ .id = 0,
+};
+
static struct clk emi_slow_clk = {
.parent = &pll2_sw_clk,
.enable_reg = MXC_CCM_CCGR5,
@@ -819,6 +884,109 @@ static struct clk emi_slow_clk = {
.get_rate = clk_emi_slow_get_rate,
};
+static int clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+
+ /* Enable handshake with IPU when certain clock rates are changed */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Enable handshake with IPU when LPM is entered */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable(clk);
+
+ /* Disable handshake with IPU whe dividers are changed */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Disable handshake with IPU when LPM is entered */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk ahbmux1_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk ipu_sec_clk = {
+ .parent = &emi_fast_clk,
+ .secondary = &ahbmux1_clk,
+};
+
+static struct clk ddr_hf_clk = {
+ .parent = &pll1_sw_clk,
+ .get_rate = _clk_ddr_hf_get_rate,
+};
+
+static struct clk ddr_clk = {
+ .parent = &ddr_hf_clk,
+};
+
+/* clock definitions for MIPI HSC unit which has been removed
+ * from documentation, but not from hardware
+ */
+static int _clk_hsc_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_hsc_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable(clk);
+ /* No handshake with HSC as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk mipi_hsp_clk = {
+ .parent = &ipu_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_hsc_enable,
+ .disable = _clk_hsc_disable,
+ .secondary = &mipi_hsc1_clk,
+};
+
#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
static struct clk name = { \
.id = i, \
@@ -927,6 +1095,41 @@ static struct clk usboh3_clk = {
.parent = &pll2_sw_clk,
.get_rate = clk_usboh3_get_rate,
.set_parent = clk_usboh3_set_parent,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+};
+
+static struct clk usb_ahb_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+};
+
+static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+
+ if (parent == &pll3_sw_clk)
+ reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk usb_phy1_clk = {
+ .parent = &pll3_sw_clk,
+ .set_parent = clk_usb_phy1_set_parent,
+ .enable = _clk_ccgr_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_ccgr_disable,
};
/* eCSPI */
@@ -1013,6 +1216,10 @@ DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
NULL, NULL, &ipg_clk, NULL);
DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
+DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
/* eCSPI */
DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
@@ -1046,6 +1253,23 @@ DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
+DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
+DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
+
+/* IPU */
+DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
+
+DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
+ NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
+ &ddr_clk, NULL);
+
+DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, &pll3_sw_clk, NULL);
+DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &pll3_sw_clk, NULL);
+
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
@@ -1053,7 +1277,7 @@ DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
.clk = &c, \
},
-static struct clk_lookup lookups[] = {
+static struct clk_lookup mx51_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)
@@ -1063,15 +1287,19 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
_REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
_REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
_REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
_REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
_REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
_REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
_REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
@@ -1082,6 +1310,22 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
_REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
+ _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
+ _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
+ _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+};
+
+static struct clk_lookup mx53_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)
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
};
static void clk_tree_init(void)
@@ -1114,14 +1358,22 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
ckih2_reference = ckih2;
oscillator_reference = osc;
- for (i = 0; i < ARRAY_SIZE(lookups); i++)
- clkdev_add(&lookups[i]);
+ for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
+ clkdev_add(&mx51_lookups[i]);
clk_tree_init();
+ clk_set_parent(&uart_root_clk, &pll3_sw_clk);
clk_enable(&cpu_clk);
clk_enable(&main_bus_clk);
+ clk_enable(&iim_clk);
+ mx51_revision();
+ clk_disable(&iim_clk);
+
+ /* move usb_phy_clk to 24MHz */
+ clk_set_parent(&usb_phy1_clk, &osc_clk);
+
/* set the usboh3_clk parent to pll2_sw_clk */
clk_set_parent(&usboh3_clk, &pll2_sw_clk);
@@ -1138,3 +1390,31 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
MX51_MXC_INT_GPT);
return 0;
}
+
+int __init mx53_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(mx53_lookups); i++)
+ clkdev_add(&mx53_lookups[i]);
+
+ clk_tree_init();
+
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ clk_enable(&iim_clk);
+ mx53_revision();
+ clk_disable(&iim_clk);
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+ MX53_INT_GPT);
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
index eaacb6e9b5d0..d40671da4372 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-mx5/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2010 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
@@ -20,37 +20,18 @@
static int cpu_silicon_rev = -1;
-#define SI_REV 0x48
+#define IIM_SREV 0x24
-static void query_silicon_parameter(void)
+static int get_mx51_srev(void)
{
- void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
- u32 rev;
+ void __iomem *iim_base = MX51_IO_ADDRESS(MX51_IIM_BASE_ADDR);
+ u32 rev = readl(iim_base + IIM_SREV) & 0xff;
- 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);
+ if (rev == 0x0)
+ return IMX_CHIP_REVISION_2_0;
+ else if (rev == 0x10)
+ return IMX_CHIP_REVISION_3_0;
+ return 0;
}
/*
@@ -64,7 +45,7 @@ int mx51_revision(void)
return -EINVAL;
if (cpu_silicon_rev == -1)
- query_silicon_parameter();
+ cpu_silicon_rev = get_mx51_srev();
return cpu_silicon_rev;
}
@@ -79,7 +60,10 @@ EXPORT_SYMBOL(mx51_revision);
*/
static int __init mx51_neon_fixup(void)
{
- if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) {
+ if (!cpu_is_mx51())
+ return 0;
+
+ if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) {
elf_hwcap &= ~HWCAP_NEON;
pr_info("Turning off NEON support, detected broken NEON implementation\n");
}
@@ -89,29 +73,65 @@ static int __init mx51_neon_fixup(void)
late_initcall(mx51_neon_fixup);
#endif
+static int get_mx53_srev(void)
+{
+ void __iomem *iim_base = MX51_IO_ADDRESS(MX53_IIM_BASE_ADDR);
+ u32 rev = readl(iim_base + IIM_SREV) & 0xff;
+
+ if (rev == 0x0)
+ return IMX_CHIP_REVISION_1_0;
+ else if (rev == 0x10)
+ return IMX_CHIP_REVISION_2_0;
+ return 0;
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx53
+ */
+int mx53_revision(void)
+{
+ if (!cpu_is_mx53())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = get_mx53_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx53_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);
+ if (cpu_is_mx51() || cpu_is_mx53()) {
+ if (cpu_is_mx51())
+ base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
+ else
+ base = MX53_IO_ADDRESS(MX53_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);
+
+ if (cpu_is_mx51())
+ base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
+ else
+ base = MX53_IO_ADDRESS(MX53_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;
}
diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
index c776b9af0624..b462c22f53d8 100644
--- a/arch/arm/mach-mx5/crm_regs.h
+++ b/arch/arm/mach-mx5/crm_regs.h
@@ -18,6 +18,13 @@
#define MX51_CORTEXA8_BASE MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR)
#define MX51_GPC_BASE MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR)
+/*MX53*/
+#define MX53_CCM_BASE MX53_IO_ADDRESS(MX53_CCM_BASE_ADDR)
+#define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR)
+#define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR)
+#define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR)
+#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR)
+
/* PLL Register Offsets */
#define MXC_PLL_DP_CTL 0x00
#define MXC_PLL_DP_CONFIG 0x04
@@ -380,7 +387,8 @@
/* 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 MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21)
+#define MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 25)
#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)
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
index 8c50cb5d05f5..6302e4670000 100644
--- a/arch/arm/mach-mx5/devices-imx51.h
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -31,6 +31,11 @@ extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst;
#define imx51_add_mxc_nand(pdata) \
imx_add_mxc_nand(&imx51_mxc_nand_data, pdata)
+extern const struct imx_sdhci_esdhc_imx_data
+imx51_sdhci_esdhc_imx_data[] __initconst;
+#define imx51_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx51_sdhci_esdhc_imx_data[id], pdata)
+
extern const struct imx_spi_imx_data imx51_cspi_data __initconst;
#define imx51_add_cspi(pdata) \
imx_add_spi_imx(&imx51_cspi_data, pdata)
@@ -39,6 +44,6 @@ extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst;
#define imx51_add_ecspi(id, pdata) \
imx_add_spi_imx(&imx51_ecspi_data[id], pdata)
-extern const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst;
-#define imx51_add_esdhc(id, pdata) \
- imx_add_esdhc(&imx51_esdhc_data[id], pdata)
+extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[] __initconst;
+#define imx51_add_imx2_wdt(id, pdata) \
+ imx_add_imx2_wdt(&imx51_imx2_wdt_data[id])
diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h
new file mode 100644
index 000000000000..9d0ec2507fa6
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx53.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx53.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst;
+#define imx53_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx53_imx_uart_data[id], pdata)
diff --git a/arch/arm/mach-mx5/devices-mx50.h b/arch/arm/mach-mx5/devices-mx50.h
new file mode 100644
index 000000000000..98ab07468a0e
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-mx50.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mx50.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst;
+#define imx50_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx50_imx_uart_data[id], pdata)
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 4c7be87a7c9d..1bda5cb339dc 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -97,19 +97,27 @@ struct platform_device mxc_usbh1_device = {
},
};
-static struct resource mxc_wdt_resources[] = {
+static struct resource usbh2_resources[] = {
{
- .start = MX51_WDOG_BASE_ADDR,
- .end = MX51_WDOG_BASE_ADDR + SZ_16K - 1,
+ .start = MX51_OTG_BASE_ADDR + 0x400,
+ .end = MX51_OTG_BASE_ADDR + 0x400 + 0x1ff,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = MX51_MXC_INT_USB_H2,
+ .flags = IORESOURCE_IRQ,
+ },
};
-struct platform_device mxc_wdt = {
- .name = "imx2-wdt",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_wdt_resources),
- .resource = mxc_wdt_resources,
+struct platform_device mxc_usbh2_device = {
+ .name = "mxc-ehci",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(usbh2_resources),
+ .resource = usbh2_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
};
static struct resource mxc_kpp_resources[] = {
@@ -160,9 +168,36 @@ static struct mxc_gpio_port mxc_gpio_ports[] = {
.irq_high = MX51_MXC_INT_GPIO4_HIGH,
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
},
+ {
+ .chip.label = "gpio-4",
+ .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
+ .irq = MX53_INT_GPIO5_LOW,
+ .irq_high = MX53_INT_GPIO5_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
+ },
+ {
+ .chip.label = "gpio-5",
+ .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
+ .irq = MX53_INT_GPIO6_LOW,
+ .irq_high = MX53_INT_GPIO6_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
+ },
+ {
+ .chip.label = "gpio-6",
+ .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
+ .irq = MX53_INT_GPIO7_LOW,
+ .irq_high = MX53_INT_GPIO7_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
+ },
};
int __init imx51_register_gpios(void)
{
+ return mxc_gpio_init(mxc_gpio_ports, 4);
+}
+
+int __init imx53_register_gpios(void)
+{
return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
}
+
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
index af1d07c0bbc1..16891aa3573c 100644
--- a/arch/arm/mach-mx5/devices.h
+++ b/arch/arm/mach-mx5/devices.h
@@ -1,6 +1,6 @@
extern struct platform_device mxc_usbdr_host_device;
extern struct platform_device mxc_usbh1_device;
+extern struct platform_device mxc_usbh2_device;
extern struct platform_device mxc_usbdr_udc_device;
-extern struct platform_device mxc_wdt;
extern struct platform_device mxc_hsi2c_device;
extern struct platform_device mxc_keypad_device;
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
index a2e6e8c39d25..c96d018ff8a2 100644
--- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
@@ -33,12 +33,12 @@
#include "devices-imx51.h"
#include "devices.h"
-#define MBIMX51_TSC2007_GPIO (2*32 + 30)
+#define MBIMX51_TSC2007_GPIO IMX_GPIO_NR(3, 30)
#define MBIMX51_TSC2007_IRQ (MXC_INTERNAL_IRQS + MBIMX51_TSC2007_GPIO)
-#define MBIMX51_LED0 (2*32 + 5)
-#define MBIMX51_LED1 (2*32 + 6)
-#define MBIMX51_LED2 (2*32 + 7)
-#define MBIMX51_LED3 (2*32 + 8)
+#define MBIMX51_LED0 IMX_GPIO_NR(3, 5)
+#define MBIMX51_LED1 IMX_GPIO_NR(3, 6)
+#define MBIMX51_LED2 IMX_GPIO_NR(3, 7)
+#define MBIMX51_LED3 IMX_GPIO_NR(3, 8)
static struct gpio_led mbimx51_leds[] = {
{
@@ -84,7 +84,7 @@ static struct platform_device *devices[] __initdata = {
&mbimx51_leds_gpio,
};
-static struct pad_desc mbimx51_pads[] = {
+static iomux_v3_cfg_t mbimx51_pads[] = {
/* UART2 */
MX51_PAD_UART2_RXD__UART2_RXD,
MX51_PAD_UART2_TXD__UART2_TXD,
@@ -96,13 +96,13 @@ static struct pad_desc mbimx51_pads[] = {
MX51_PAD_KEY_COL5__UART3_CTS,
/* TSC2007 IRQ */
- MX51_PAD_NANDF_D10__GPIO_3_30,
+ MX51_PAD_NANDF_D10__GPIO3_30,
/* LEDS */
- MX51_PAD_DISPB2_SER_DIN__GPIO_3_5,
- MX51_PAD_DISPB2_SER_DIO__GPIO_3_6,
- MX51_PAD_DISPB2_SER_CLK__GPIO_3_7,
- MX51_PAD_DISPB2_SER_RS__GPIO_3_8,
+ MX51_PAD_DISPB2_SER_DIN__GPIO3_5,
+ MX51_PAD_DISPB2_SER_DIO__GPIO3_6,
+ MX51_PAD_DISPB2_SER_CLK__GPIO3_7,
+ MX51_PAD_DISPB2_SER_RS__GPIO3_8,
/* KPP */
MX51_PAD_KEY_ROW0__KEY_ROW0,
@@ -217,6 +217,6 @@ void __init eukrea_mbimx51_baseboard_init(void)
i2c_register_board_info(1, mbimx51_i2c_devices,
ARRAY_SIZE(mbimx51_i2c_devices));
- imx51_add_esdhc(0, NULL);
- imx51_add_esdhc(1, NULL);
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+ imx51_add_sdhci_esdhc_imx(1, NULL);
}
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index 2b48f5190830..c372a4373691 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -45,14 +45,13 @@
#include "devices-imx51.h"
#include "devices.h"
-#define MBIMXSD_GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, \
- MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
-
-static struct pad_desc eukrea_mbimxsd_pads[] = {
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
/* LED */
- MX51_PAD_NANDF_D10__GPIO_3_30,
+ MX51_PAD_NANDF_D10__GPIO3_30,
/* SWITCH */
- MBIMXSD_GPIO_3_31,
+ _MX51_PAD_NANDF_D9__GPIO3_31 | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
/* UART2 */
MX51_PAD_UART2_RXD__UART2_RXD,
MX51_PAD_UART2_TXD__UART2_TXD,
@@ -70,8 +69,8 @@ static struct pad_desc eukrea_mbimxsd_pads[] = {
MX51_PAD_SD1_DATA3__SD1_DATA3,
};
-#define GPIO_LED1 (2 * 32 + 30)
-#define GPIO_SWITCH1 (2 * 32 + 31)
+#define GPIO_LED1 IMX_GPIO_NR(3, 30)
+#define GPIO_SWITCH1 IMX_GPIO_NR(3, 31)
static struct gpio_led eukrea_mbimxsd_leds[] = {
{
@@ -149,7 +148,7 @@ void __init eukrea_mbimxsd51_baseboard_init(void)
imx51_add_imx_uart(1, NULL);
imx51_add_imx_uart(2, &uart_pdata);
- imx51_add_esdhc(0, NULL);
+ imx51_add_sdhci_esdhc_imx(0, NULL);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c
new file mode 100644
index 000000000000..8c6540e58390
--- /dev/null
+++ b/arch/arm/mach-mx5/mm-mx50.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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 MX50 memory map.
+ */
+static struct map_desc mx50_io_desc[] __initdata = {
+ imx_map_entry(MX50, TZIC, MT_DEVICE),
+ imx_map_entry(MX50, SPBA0, MT_DEVICE),
+ imx_map_entry(MX50, AIPS1, MT_DEVICE),
+ imx_map_entry(MX50, AIPS2, 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 mx50_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX50);
+ mxc_iomux_v3_init(MX50_IO_ADDRESS(MX50_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
+ iotable_init(mx50_io_desc, ARRAY_SIZE(mx50_io_desc));
+}
+
+int imx50_register_gpios(void);
+
+void __init mx50_init_irq(void)
+{
+ tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
+ imx50_register_gpios();
+}
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index bc3f30db8d9a..457f9f95204b 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2010 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
@@ -23,33 +23,21 @@
/*
* 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
- },
+static struct map_desc mx51_io_desc[] __initdata = {
+ imx_map_entry(MX51, IRAM, MT_DEVICE),
+ imx_map_entry(MX51, DEBUG, MT_DEVICE),
+ imx_map_entry(MX51, AIPS1, MT_DEVICE),
+ imx_map_entry(MX51, SPBA0, MT_DEVICE),
+ imx_map_entry(MX51, AIPS2, MT_DEVICE),
+};
+
+/*
+ * Define the MX53 memory map.
+ */
+static struct map_desc mx53_io_desc[] __initdata = {
+ imx_map_entry(MX53, AIPS1, MT_DEVICE),
+ imx_map_entry(MX53, SPBA0, MT_DEVICE),
+ imx_map_entry(MX53, AIPS2, MT_DEVICE),
};
/*
@@ -61,8 +49,16 @@ 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));
+ mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
+ iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc));
+}
+
+void __init mx53_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX53);
+ mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG_BASE_ADDR));
+ iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc));
}
int imx51_register_gpios(void);
@@ -72,7 +68,7 @@ void __init mx51_init_irq(void)
unsigned long tzic_addr;
void __iomem *tzic_virt;
- if (mx51_revision() < MX51_CHIP_REV_2_0)
+ if (mx51_revision() < IMX_CHIP_REVISION_2_0)
tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
else
tzic_addr = MX51_TZIC_BASE_ADDR;
@@ -84,3 +80,20 @@ void __init mx51_init_irq(void)
tzic_init_irq(tzic_virt);
imx51_register_gpios();
}
+
+int imx53_register_gpios(void);
+
+void __init mx53_init_irq(void)
+{
+ unsigned long tzic_addr;
+ void __iomem *tzic_virt;
+
+ tzic_addr = MX53_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);
+ imx53_register_gpios();
+}
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c
index 5c85075d8a56..9fab505f1eb1 100644
--- a/arch/arm/mach-mxc91231/clock.c
+++ b/arch/arm/mach-mxc91231/clock.c
@@ -2,12 +2,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
-#include <asm/clkdev.h>
#include <asm/bug.h>
#include <asm/div64.h>
diff --git a/arch/arm/mach-mxc91231/mm.c b/arch/arm/mach-mxc91231/mm.c
index aeccfd755fee..7652c301da88 100644
--- a/arch/arm/mach-mxc91231/mm.c
+++ b/arch/arm/mach-mxc91231/mm.c
@@ -27,48 +27,15 @@
/*
* This structure defines the MXC memory map.
*/
-static struct map_desc mxc_io_desc[] __initdata = {
- {
- .virtual = MXC91231_L2CC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_L2CC_BASE_ADDR),
- .length = MXC91231_L2CC_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_X_MEMC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_X_MEMC_BASE_ADDR),
- .length = MXC91231_X_MEMC_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_ROMP_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_ROMP_BASE_ADDR),
- .length = MXC91231_ROMP_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_AVIC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_AVIC_BASE_ADDR),
- .length = MXC91231_AVIC_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_AIPS1_BASE_ADDR),
- .length = MXC91231_AIPS1_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_SPBA0_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_SPBA0_BASE_ADDR),
- .length = MXC91231_SPBA0_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_SPBA1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_SPBA1_BASE_ADDR),
- .length = MXC91231_SPBA1_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = MXC91231_AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MXC91231_AIPS2_BASE_ADDR),
- .length = MXC91231_AIPS2_SIZE,
- .type = MT_DEVICE,
- },
+static struct map_desc mxc91231_io_desc[] __initdata = {
+ imx_map_entry(MXC91231, L2CC, MT_DEVICE),
+ imx_map_entry(MXC91231, X_MEMC, MT_DEVICE),
+ imx_map_entry(MXC91231, ROMP, MT_DEVICE),
+ imx_map_entry(MXC91231, AVIC, MT_DEVICE),
+ imx_map_entry(MXC91231, AIPS1, MT_DEVICE),
+ imx_map_entry(MXC91231, SPBA0, MT_DEVICE),
+ imx_map_entry(MXC91231, SPBA1, MT_DEVICE),
+ imx_map_entry(MXC91231, AIPS2, MT_DEVICE),
};
/*
@@ -80,7 +47,7 @@ void __init mxc91231_map_io(void)
{
mxc_set_cpu_type(MXC_CPU_MXC91231);
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+ iotable_init(mxc91231_io_desc, ARRAY_SIZE(mxc91231_io_desc));
}
int mxc91231_register_gpios(void);
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 000000000000..c4ac7b415195
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+ bool
+ select CPU_ARM926T
+
+config SOC_IMX28
+ bool
+ select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+ bool "Support MX23EVK Platform"
+ select SOC_IMX23
+ select MXS_HAVE_PLATFORM_DUART
+ default y
+ help
+ Include support for MX23EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+ bool "Support MX28EVK Platform"
+ select SOC_IMX28
+ select MXS_HAVE_PLATFORM_DUART
+ select MXS_HAVE_PLATFORM_FEC
+ default y
+ help
+ Include support for MX28EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 000000000000..39d3f9c2a841
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,10 @@
+# Common support
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 000000000000..eb541e0291da
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x40008000
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 000000000000..8f5a19ab558c
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT 8
+
+static int _raw_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ }
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+ return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+ .get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+ /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+ * and is incorrect (excessive). Per definition of the PLLCTRL0
+ * POWER field, waiting at least 10us.
+ */
+ udelay(10);
+
+ return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+ .get_rate = pll_clk_get_rate,
+ .enable = pll_clk_enable,
+ .disable = pll_clk_disable,
+ .parent = &ref_xtal_clk,
+};
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ unsigned long parent_rate; \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
+ div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
+ parent_rate = clk_get_rate(clk->parent); \
+ \
+ return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#define _DEFINE_CLOCK_REF(name, er, es) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
+ .get_rate = name##_get_rate, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = &pll_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+ /* ref_xtal_clk is implemented as the only parent */
+ return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+ return clk->parent->get_rate(clk->parent) / 750;
+}
+
+#define _CLK_GET_RATE(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ if (clk->parent == &ref_xtal_clk) \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
+ BP_CLKCTRL_##rs##_DIV_XTAL; \
+ else \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
+ BP_CLKCTRL_##rs##_DIV_##rs; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#define _CLK_GET_RATE_STUB(name) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ return clk_get_rate(clk->parent); \
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, bm_busy, div_max, d, f, div, frac;
+ unsigned long diff, parent_rate, calc_rate;
+ int i;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &ref_xtal_clk) {
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div == 0 || div > div_max)
+ return -EINVAL;
+ } else {
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+ rate >>= PARENT_RATE_SHIFT;
+ parent_rate >>= PARENT_RATE_SHIFT;
+ diff = parent_rate;
+ div = frac = 1;
+ for (d = 1; d <= div_max; d++) {
+ f = parent_rate * 18 / d / rate;
+ if ((parent_rate * 18 / d) % rate)
+ f++;
+ if (f < 18 || f > 35)
+ continue;
+
+ calc_rate = parent_rate * 18 / f / d;
+ if (calc_rate > rate)
+ continue;
+
+ if (rate - calc_rate < diff) {
+ frac = f;
+ div = d;
+ diff = rate - calc_rate;
+ }
+
+ if (diff == 0)
+ break;
+ }
+
+ if (diff == parent_rate)
+ return -EINVAL;
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+ reg |= frac;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ }
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_CPU) & bm_busy))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define _CLK_SET_RATE(name, dr) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div_max, div; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg | (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#define _CLK_SET_RATE_STUB(name) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ return -EINVAL; \
+}
+
+_CLK_SET_RATE_STUB(emi_clk)
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) { \
+ __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
+ HW_CLKCTRL_CLKSEQ_TOG); \
+ clk->parent = parent; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#define _CLK_SET_PARENT_STUB(name) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) \
+ return -EINVAL; \
+ else \
+ return 0; \
+}
+
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+ .get_rate = cpu_clk_get_rate,
+ .set_rate = cpu_clk_set_rate,
+ .set_parent = cpu_clk_set_parent,
+ .parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+ .get_rate = hbus_clk_get_rate,
+ .parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+ .get_rate = xbus_clk_get_rate,
+ .set_rate = xbus_clk_set_rate,
+ .parent = &ref_xtal_clk,
+};
+
+static struct clk rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_##es, \
+ .get_rate = name##_get_rate, \
+ .set_rate = name##_set_rate, \
+ .set_parent = name##_set_parent, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = p, \
+ }
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "audio", audio_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+};
+
+static int clk_misc_init(void)
+{
+ u32 reg;
+ int i;
+
+ /* Fix up parent per register setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+ cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+ &ref_xtal_clk : &ref_cpu_clk;
+ emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+ &ref_xtal_clk : &ref_emi_clk;
+ ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+ &ref_xtal_clk : &ref_io_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_io_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+ &ref_xtal_clk : &ref_pix_clk;
+
+ /* Use int div over frac when both are available */
+ __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+ reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+ reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+ reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+ reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+ /*
+ * Set safe hbus clock divider. A divider of 3 ensure that
+ * the Vddd voltage required for the cpu clock is sufficiently
+ * high for the hbus clock.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+ reg &= BM_CLKCTRL_HBUS_DIV;
+ reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Gate off cpu clock in WFI for power saving */
+ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+ return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 000000000000..74e2103c6011
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx28.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT 8
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ }
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+ return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+ .get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+ return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g) \
+static int name##_enable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ udelay(10); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ \
+ return 0; \
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g) \
+static void name##_disable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name) \
+ static struct clk name = { \
+ .get_rate = name##_get_rate, \
+ .enable = name##_enable, \
+ .disable = name##_disable, \
+ .parent = &ref_xtal_clk, \
+ }
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ unsigned long parent_rate; \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
+ div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
+ parent_rate = clk_get_rate(clk->parent); \
+ \
+ return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
+ .get_rate = name##_get_rate, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = &pll0_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+ /* ref_xtal_clk is implemented as the only parent */
+ return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+ return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ if (clk->parent == &ref_xtal_clk) \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
+ BP_CLKCTRL_##rs##_DIV_XTAL; \
+ else \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
+ BP_CLKCTRL_##rs##_DIV_##rs; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ if (clk == &saif0_clk || clk == &saif1_clk) \
+ return clk_get_rate(clk->parent) >> 16 * div; \
+ else \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+
+#define _CLK_GET_RATE_STUB(name) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ return clk_get_rate(clk->parent); \
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+_CLK_GET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV 0
+#define BP_CLKCTRL_CPU_DIV 0
+#define BM_CLKCTRL_CPU_BUSY 0
+
+#define _CLK_SET_RATE(name, dr, fr, fs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, bm_busy, div_max, d, f, div, frac; \
+ unsigned long diff, parent_rate, calc_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ bm_busy = BM_CLKCTRL_##dr##_BUSY; \
+ \
+ if (clk->parent == &ref_xtal_clk) { \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
+ BP_CLKCTRL_CPU_DIV_XTAL; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
+ } \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ } else { \
+ rate >>= PARENT_RATE_SHIFT; \
+ parent_rate >>= PARENT_RATE_SHIFT; \
+ diff = parent_rate; \
+ div = frac = 1; \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
+ BP_CLKCTRL_CPU_DIV_CPU; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
+ } \
+ for (d = 1; d <= div_max; d++) { \
+ f = parent_rate * 18 / d / rate; \
+ if ((parent_rate * 18 / d) % rate) \
+ f++; \
+ if (f < 18 || f > 35) \
+ continue; \
+ \
+ calc_rate = parent_rate * 18 / f / d; \
+ if (calc_rate > rate) \
+ continue; \
+ \
+ if (rate - calc_rate < diff) { \
+ frac = f; \
+ div = d; \
+ diff = rate - calc_rate; \
+ } \
+ \
+ if (diff == 0) \
+ break; \
+ } \
+ \
+ if (diff == parent_rate) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
+ reg |= frac; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ } \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ if (clk == &cpu_clk) { \
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
+ } else { \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg | (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & bm_busy)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div_max, div; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg | (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u16 div; \
+ u32 reg; \
+ u64 lrate; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ if (rate > parent_rate) \
+ return -EINVAL; \
+ \
+ lrate = (u64)rate << 16; \
+ do_div(lrate, parent_rate); \
+ div = (u16)lrate; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ reg &= ~BM_CLKCTRL_##rs##_DIV; \
+ reg |= div << BP_CLKCTRL_##rs##_DIV; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ return -EINVAL; \
+}
+
+_CLK_SET_RATE_STUB(emi_clk)
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+_CLK_SET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) { \
+ __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
+ HW_CLKCTRL_CLKSEQ_TOG); \
+ clk->parent = parent; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) \
+ return -EINVAL; \
+ else \
+ return 0; \
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+ .get_rate = cpu_clk_get_rate,
+ .set_rate = cpu_clk_set_rate,
+ .set_parent = cpu_clk_set_parent,
+ .parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+ .get_rate = hbus_clk_get_rate,
+ .parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+ .get_rate = xbus_clk_get_rate,
+ .set_rate = xbus_clk_set_rate,
+ .parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+ .get_rate = lradc_clk_get_rate,
+ .parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 16,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_##es, \
+ .get_rate = name##_get_rate, \
+ .set_rate = name##_set_rate, \
+ .set_parent = name##_set_parent, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = p, \
+ }
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("pll2", NULL, pll2_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "can0", can0_clk)
+ _REGISTER_CLOCK(NULL, "can1", can1_clk)
+ _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+ _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+ _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+ u32 reg;
+ int i;
+
+ /* Fix up parent per register setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+ cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+ &ref_xtal_clk : &ref_cpu_clk;
+ emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+ &ref_xtal_clk : &ref_emi_clk;
+ ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+ &ref_xtal_clk : &ref_pix_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_gpmi_clk;
+ saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+ &ref_xtal_clk : &pll0_clk;
+ saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+ &ref_xtal_clk : &pll0_clk;
+
+ /* Use int div over frac when both are available */
+ __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+ reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+ reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+ reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+ reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+ reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+ reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+ reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+ /* SAIF has to use frac div for functional operation */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+ reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+ reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+ /*
+ * Set safe hbus clock divider. A divider of 3 ensure that
+ * the Vddd voltage required for the cpu clock is sufficiently
+ * high for the hbus clock.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+ reg &= BM_CLKCTRL_HBUS_DIV;
+ reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Gate off cpu clock in WFI for power saving */
+ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+ /* Extra fec clock setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+ reg &= ~BM_CLKCTRL_ENET_SLEEP;
+ reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+ return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 000000000000..e7d2269cf70e
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,200 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 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.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+ WARN_ON(!clk->usecount);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ if (clk->usecount)
+ clk_enable(parent);
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ mutex_unlock(&clocks_mutex);
+
+ if (clk->usecount)
+ clk_disable(old);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 000000000000..d0f49fc0abb5
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx23_duart_data __initconst;
+#define mx23_add_duart() \
+ mxs_add_duart(&mx23_duart_data)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 000000000000..00b736c434ba
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx28_duart_data __initconst;
+#define mx28_add_duart() \
+ mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+ mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 000000000000..6b60f02ca2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 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/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 000000000000..a35a2dc55395
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+ bool
+
+config MXS_HAVE_PLATFORM_FEC
+ bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 000000000000..4b5266a3e6d9
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
diff --git a/arch/arm/mach-mxs/devices/platform-duart.c b/arch/arm/mach-mxs/devices/platform-duart.c
new file mode 100644
index 000000000000..2fe0df5b0aad
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-duart.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_duart_data_entry(soc) \
+ { \
+ .iobase = soc ## _DUART_BASE_ADDR, \
+ .irq = soc ## _INT_DUART, \
+ }
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_duart_data mx23_duart_data __initconst =
+ mxs_duart_data_entry(MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_duart_data mx28_duart_data __initconst =
+ mxs_duart_data_entry(MX28);
+#endif
+
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_duart_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("mxs-duart", 0, res, ARRAY_SIZE(res),
+ NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 000000000000..c08168cf3dec
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
+ .irq = soc ## _INT_ENET_MAC ## _id, \
+ }
+
+#define mxs_fec_data_entry(soc, _id) \
+ [_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id) \
+ mxs_fec_data_entry(MX28, _id)
+ mx28_fec_data_entry(0),
+ mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("fec", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 000000000000..d7ad7a61366d
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,325 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE 0x0
+#define GPIO_INT_LOW_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_HIGH_LEV 0x3
+#define GPIO_INT_LEV_MASK (1 << 0)
+#define GPIO_INT_POL_MASK (1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id));
+}
+
+static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable) {
+ __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id));
+ } else {
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ }
+}
+
+static void mxs_gpio_ack_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void mxs_gpio_mask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void mxs_gpio_unmask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int mxs_gpio_set_irq_type(u32 irq, u32 type)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 pin_mask = 1 << (gpio & 31);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ void __iomem *pin_addr;
+ int edge;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set level or edge */
+ pin_addr = port->base + PINCTRL_IRQLEV(port->id);
+ if (edge & GPIO_INT_LEV_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_addr);
+
+ /* set polarity */
+ pin_addr = port->base + PINCTRL_IRQPOL(port->id);
+ if (edge & GPIO_INT_POL_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_addr);
+
+ clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+ __raw_readl(port->base + PINCTRL_IRQEN(port->id));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int mxs_gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 gpio_idx = gpio & 0x1f;
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .ack = mxs_gpio_ack_irq,
+ .mask = mxs_gpio_mask_irq,
+ .unmask = mxs_gpio_unmask_irq,
+ .set_type = mxs_gpio_set_irq_type,
+ .set_wake = mxs_gpio_set_wake_irq,
+};
+
+static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
+
+ if (dir)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_addr);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
+
+ if (value)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_addr);
+}
+
+static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ return port->virtual_irq_start + offset;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ mxs_set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxs_gpio_set(chip, offset, value);
+ mxs_set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+ int i, j;
+
+ /* save for local usage */
+ mxs_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ pr_info("MXS GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i));
+ __raw_writel(0, port[i].base + PINCTRL_IRQEN(i));
+
+ /* clear address has to be used to clear IRQSTAT bits */
+ __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));
+
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* setup one handler for each entry */
+ set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ set_irq_data(port[i].irq, &port[i]);
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxs_gpio_direction_input;
+ port[i].chip.direction_output = mxs_gpio_direction_output;
+ port[i].chip.get = mxs_gpio_get;
+ port[i].chip.set = mxs_gpio_set;
+ port[i].chip.to_irq = mxs_gpio_to_irq;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+
+ /* its a serious configuration bug when it fails */
+ BUG_ON(gpiochip_add(&port[i].chip) < 0);
+ }
+
+ return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .id = _id, \
+ .irq = soc ## _INT_GPIO ## _id, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _PINCTRL ## _BASE_ADDR), \
+ .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_REGISTER_FUNCTION(prefix) \
+int __init prefix ## _register_gpios(void) \
+{ \
+ return mxs_gpio_init(prefix ## _gpio_ports, \
+ ARRAY_SIZE(prefix ## _gpio_ports)); \
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX23, 0),
+ DEFINE_MXS_GPIO_PORT(MX23, 1),
+ DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX28, 0),
+ DEFINE_MXS_GPIO_PORT(MX28, 1),
+ DEFINE_MXS_GPIO_PORT(MX28, 2),
+ DEFINE_MXS_GPIO_PORT(MX28, 3),
+ DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 000000000000..005bb06630b1
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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 __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+struct mxs_gpio_port {
+ void __iomem *base;
+ int id;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 000000000000..5dd43ba70058
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR 0x0000
+#define HW_ICOLL_LEVELACK 0x0010
+#define HW_ICOLL_CTRL 0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
+
+static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
+
+static void icoll_ack_irq(unsigned int irq)
+{
+ /*
+ * The Interrupt Collector is able to prioritize irqs.
+ * Currently only level 0 is used. So acking can use
+ * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+ */
+ __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+ icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+ .ack = icoll_ack_irq,
+ .mask = icoll_mask_irq,
+ .unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void)
+{
+ int i;
+
+ /*
+ * Interrupt Collector reset, which initializes the priority
+ * for each irq to level 0.
+ */
+ mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxs_icoll_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 000000000000..3a8f2e3a6309
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 000000000000..041e276d8a32
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-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 __MACH_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Secondary clock to enable/disable with this clock */
+ struct clk *secondary;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 000000000000..59133eb3cc96
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_timer_init(struct clk *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 000000000000..79650a1ad78d
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 000000000000..3da48d4d3273
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return mxs_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
+
+/* duart */
+struct mxs_duart_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata);
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 000000000000..9f0da12e657a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mxs.h>
+
+#define MXS_ICOLL_VBASE MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR)
+#define HW_ICOLL_STAT_OFFSET 0x70
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #HW_ICOLL_STAT_OFFSET]
+ cmp \irqnr, #0x7F
+ strne \irqnr, [\base]
+ moveqs \irqnr, #0
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =MXS_ICOLL_VBASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 000000000000..828ccccb6aad
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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 __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#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
+
+#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 000000000000..53e89a09bf0d
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,29 @@
+/*
+ * 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 __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 000000000000..289b7227e072
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 000000000000..94e5dd83cdb8
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX
+ */
+/* MUXSEL_0 */
+#define MX23_PAD_GPMI_D00__GPMI_D00 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D01__GPMI_D01 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D02__GPMI_D02 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D03__GPMI_D03 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D04__GPMI_D04 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D05__GPMI_D05 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D06__GPMI_D06 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D07__GPMI_D07 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D08__GPMI_D08 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D09__GPMI_D09 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D10__GPMI_D10 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D11__GPMI_D11 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D12__GPMI_D12 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D13__GPMI_D13 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D14__GPMI_D14 MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D15__GPMI_D15 MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CLE__GPMI_CLE MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_ALE__GPMI_ALE MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE2N__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY0__GPMI_RDY0 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY1__GPMI_RDY1 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY2__GPMI_RDY2 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY3__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_WPN__GPMI_WPN MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_WRN__GPMI_WRN MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDN__GPMI_RDN MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_CTS__AUART1_CTS MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_RTS__AUART1_RTS MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_RX__AUART1_RX MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_TX__AUART1_TX MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_0)
+#define MX23_PAD_I2C_SCL__I2C_SCL MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_0)
+#define MX23_PAD_I2C_SDA__I2C_SDA MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_0)
+
+#define MX23_PAD_LCD_D00__LCD_D00 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D01__LCD_D01 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D02__LCD_D02 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D03__LCD_D03 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D04__LCD_D04 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D05__LCD_D05 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D06__LCD_D06 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D07__LCD_D07 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D08__LCD_D08 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D09__LCD_D09 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D10__LCD_D10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D11__LCD_D11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D12__LCD_D12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D13__LCD_D13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D14__LCD_D14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D15__LCD_D15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D16__LCD_D16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D17__LCD_D17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_RESET__LCD_RESET MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_RS__LCD_RS MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_WR__LCD_WR MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_CS__LCD_CS MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_DOTCK__LCD_DOTCK MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_ENABLE__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_HSYNC__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_VSYNC__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_0)
+#define MX23_PAD_PWM0__PWM0 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_0)
+#define MX23_PAD_PWM1__PWM1 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_0)
+#define MX23_PAD_PWM2__PWM2 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_0)
+#define MX23_PAD_PWM3__PWM3 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_0)
+#define MX23_PAD_PWM4__PWM4 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_0)
+
+#define MX23_PAD_SSP1_CMD__SSP1_CMD MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DETECT__SSP1_DETECT MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA0__SSP1_DATA0 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA1__SSP1_DATA1 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA2__SSP1_DATA2 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA3__SSP1_DATA3 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_SCK__SSP1_SCK MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_0)
+#define MX23_PAD_ROTARYA__ROTARYA MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_0)
+#define MX23_PAD_ROTARYB__ROTARYB MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A00__EMI_A00 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A01__EMI_A01 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A02__EMI_A02 MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A03__EMI_A03 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A04__EMI_A04 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A05__EMI_A05 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A06__EMI_A06 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A07__EMI_A07 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A08__EMI_A08 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A09__EMI_A09 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A10__EMI_A10 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A11__EMI_A11 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A12__EMI_A12 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_BA0__EMI_BA0 MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_BA1__EMI_BA1 MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CASN__EMI_CASN MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CE0N__EMI_CE0N MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CE1N__EMI_CE1N MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE1N__GPMI_CE1N MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE0N__GPMI_CE0N MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CKE__EMI_CKE MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_RASN__EMI_RASN MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_WEN__EMI_WEN MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_0)
+
+#define MX23_PAD_EMI_D00__EMI_D00 MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D01__EMI_D01 MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D02__EMI_D02 MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D03__EMI_D03 MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D04__EMI_D04 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D05__EMI_D05 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D06__EMI_D06 MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D07__EMI_D07 MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D08__EMI_D08 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D09__EMI_D09 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D10__EMI_D10 MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D11__EMI_D11 MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D12__EMI_D12 MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D13__EMI_D13 MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D14__EMI_D14 MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D15__EMI_D15 MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQM0__EMI_DQM0 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQM1__EMI_DQM1 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQS0__EMI_DQS0 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQS1__EMI_DQS1 MXS_IOMUX_PAD_NAKED(3, 19, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CLK__EMI_CLK MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CLKN__EMI_CLKN MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_0)
+
+/* MUXSEL_1 */
+#define MX23_PAD_GPMI_D00__LCD_D8 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D01__LCD_D9 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D02__LCD_D10 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D03__LCD_D11 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D04__LCD_D12 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D05__LCD_D13 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D06__LCD_D14 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D07__LCD_D15 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D08__LCD_D18 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D09__LCD_D19 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D10__LCD_D20 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D11__LCD_D21 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D12__LCD_D22 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D13__LCD_D23 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D14__AUART2_RX MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D15__AUART2_TX MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_CLE__LCD_D16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_ALE__LCD_D17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_CE2N__ATA_A2 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_RTS__IR_CLK MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_RX__IR_RX MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_TX__IR_TX MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_1)
+#define MX23_PAD_I2C_SCL__GPMI_RDY2 MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_1)
+#define MX23_PAD_I2C_SDA__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_1)
+
+#define MX23_PAD_LCD_D00__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D01__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D02__ETM_DA10 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D03__ETM_DA11 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D04__ETM_DA12 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D05__ETM_DA13 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D06__ETM_DA14 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D07__ETM_DA15 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D08__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D09__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D10__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D11__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D12__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D13__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D14__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D15__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_RESET__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_RS__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_DOTCK__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_ENABLE__I2C_SCL MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_HSYNC__I2C_SDA MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_VSYNC__LCD_BUSY MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_1)
+#define MX23_PAD_PWM0__ROTARYA MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_1)
+#define MX23_PAD_PWM1__ROTARYB MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_1)
+#define MX23_PAD_PWM2__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_1)
+#define MX23_PAD_PWM3__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_1)
+#define MX23_PAD_PWM4__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_1)
+
+#define MX23_PAD_SSP1_DETECT__GPMI_CE3N MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_1)
+#define MX23_PAD_SSP1_DATA1__I2C_SCL MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_1)
+#define MX23_PAD_SSP1_DATA2__I2C_SDA MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_1)
+#define MX23_PAD_ROTARYA__AUART2_RTS MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_1)
+#define MX23_PAD_ROTARYB__AUART2_CTS MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_1)
+
+/* MUXSEL_2 */
+#define MX23_PAD_GPMI_D00__SSP2_DATA0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D01__SSP2_DATA1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D02__SSP2_DATA2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D03__SSP2_DATA3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D04__SSP2_DATA4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D05__SSP2_DATA5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D06__SSP2_DATA6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D07__SSP2_DATA7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D08__SSP1_DATA4 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D09__SSP1_DATA5 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D10__SSP1_DATA6 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D11__SSP1_DATA7 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D15__GPMI_CE3N MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_RDY0__SSP2_DETECT MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_RDY1__SSP2_CMD MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_WRN__SSP2_SCK MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_CTS__SSP1_DATA4 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_RTS__SSP1_DATA5 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_RX__SSP1_DATA6 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_TX__SSP1_DATA7 MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_2)
+#define MX23_PAD_I2C_SCL__AUART1_TX MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_2)
+#define MX23_PAD_I2C_SDA__AUART1_RX MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_2)
+
+#define MX23_PAD_LCD_D08__SAIF2_SDATA0 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D09__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D11__SAIF_LRCLK MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D12__SAIF2_SDATA1 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D13__SAIF2_SDATA2 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D14__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D15__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D16__SAIF_ALT_BITCLK MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_RESET__GPMI_CE3N MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_2)
+#define MX23_PAD_PWM0__DUART_RX MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_2)
+#define MX23_PAD_PWM1__DUART_TX MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_2)
+#define MX23_PAD_PWM3__AUART1_CTS MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_2)
+#define MX23_PAD_PWM4__AUART1_RTS MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_2)
+
+#define MX23_PAD_SSP1_CMD__JTAG_TDO MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DETECT__USB_OTG_ID MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA0__JTAG_TDI MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA1__JTAG_TCLK MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA2__JTAG_RTCK MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA3__JTAG_TMS MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_SCK__JTAG_TRST MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_2)
+#define MX23_PAD_ROTARYA__SPDIF MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_2)
+#define MX23_PAD_ROTARYB__GPMI_CE3N MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_2)
+
+/* MUXSEL_GPIO */
+#define MX23_PAD_GPMI_D00__GPO_0_0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D01__GPO_0_1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D02__GPO_0_2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D03__GPO_0_3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D04__GPO_0_4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D05__GPO_0_5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D06__GPO_0_6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D07__GPO_0_7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D08__GPO_0_8 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D09__GPO_0_9 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D10__GPO_0_10 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D11__GPO_0_11 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D12__GPO_0_12 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D13__GPO_0_13 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D14__GPO_0_14 MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D15__GPO_0_15 MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CLE__GPO_0_16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_ALE__GPO_0_17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE2N__GPO_0_18 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY0__GPO_0_19 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY1__GPO_0_20 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY2__GPO_0_21 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY3__GPO_0_22 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WPN__GPO_0_23 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WRN__GPO_0_24 MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDN__GPO_0_25 MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_CTS__GPO_0_26 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RTS__GPO_0_27 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RX__GPO_0_28 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_TX__GPO_0_29 MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SCL__GPO_0_30 MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SDA__GPO_0_31 MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
+
+#define MX23_PAD_LCD_D00__GPO_1_0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D01__GPO_1_1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D02__GPO_1_2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D03__GPO_1_3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D04__GPO_1_4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D05__GPO_1_5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D06__GPO_1_6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D07__GPO_1_7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D08__GPO_1_8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D09__GPO_1_9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D10__GPO_1_10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D11__GPO_1_11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D12__GPO_1_12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D13__GPO_1_13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D14__GPO_1_14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D15__GPO_1_15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D16__GPO_1_16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D17__GPO_1_17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RESET__GPO_1_18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RS__GPO_1_19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_WR__GPO_1_20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_CS__GPO_1_21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_DOTCK__GPO_1_22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_ENABLE__GPO_1_23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_HSYNC__GPO_1_24 MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_VSYNC__GPO_1_25 MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM0__GPO_1_26 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM1__GPO_1_27 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM2__GPO_1_28 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM3__GPO_1_29 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM4__GPO_1_30 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+
+#define MX23_PAD_SSP1_CMD__GPO_2_0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DETECT__GPO_2_1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA0__GPO_2_2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA1__GPO_2_3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA2__GPO_2_4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA3__GPO_2_5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_SCK__GPO_2_6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYA__GPO_2_7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYB__GPO_2_8 MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A00__GPO_2_9 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A01__GPO_2_10 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A02__GPO_2_11 MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A03__GPO_2_12 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A04__GPO_2_13 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A05__GPO_2_14 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A06__GPO_2_15 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A07__GPO_2_16 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A08__GPO_2_17 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A09__GPO_2_18 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A10__GPO_2_19 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A11__GPO_2_20 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A12__GPO_2_21 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA0__GPO_2_22 MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA1__GPO_2_23 MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CASN__GPO_2_24 MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE0N__GPO_2_25 MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE1N__GPO_2_26 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE1N__GPO_2_27 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE0N__GPO_2_28 MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CKE__GPO_2_29 MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_RASN__GPO_2_30 MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_WEN__GPO_2_31 MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 000000000000..f50fefd10520
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX
+ */
+/* MUXSEL_0 */
+#define MX28_PAD_GPMI_D00__GPMI_D0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D01__GPMI_D1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D02__GPMI_D2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D03__GPMI_D3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D04__GPMI_D4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D05__GPMI_D5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D06__GPMI_D6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D07__GPMI_D7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDN__GPMI_RDN MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_WRN__GPMI_WRN MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_ALE__GPMI_ALE MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CLE__GPMI_CLE MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_0)
+
+#define MX28_PAD_LCD_D00__LCD_D0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D01__LCD_D1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D02__LCD_D2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D03__LCD_D3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D04__LCD_D4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D05__LCD_D5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D06__LCD_D6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D07__LCD_D7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D08__LCD_D8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D09__LCD_D9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D10__LCD_D10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D11__LCD_D11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D12__LCD_D12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D13__LCD_D13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D14__LCD_D14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D15__LCD_D15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D16__LCD_D16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D17__LCD_D17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D18__LCD_D18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D19__LCD_D19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D20__LCD_D20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D21__LCD_D21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D22__LCD_D22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D23__LCD_D23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RD_E__LCD_RD_E MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RS__LCD_RS MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_CS__LCD_CS MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 31, PAD_MUXSEL_0)
+
+#define MX28_PAD_SSP0_DATA0__SSP0_D0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA1__SSP0_D1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA2__SSP0_D2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA3__SSP0_D3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA4__SSP0_D4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA5__SSP0_D5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA6__SSP0_D6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA7__SSP0_D7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_CMD__SSP0_CMD MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_SCK__SSP0_SCK MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_SCK__SSP1_SCK MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_CMD__SSP1_CMD MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_DATA0__SSP1_D0 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_DATA3__SSP1_D3 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SCK__SSP2_SCK MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_MISO__SSP2_D0 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS0__SSP2_D3 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS1__SSP2_D4 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS2__SSP2_D5 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_SCK__SSP3_SCK MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_MISO__SSP3_D0 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_SS0__SSP3_D3 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_0)
+
+#define MX28_PAD_AUART0_RX__AUART0_RX MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_TX__AUART0_TX MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_CTS__AUART0_CTS MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_RTS__AUART0_RTS MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_RX__AUART1_RX MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_TX__AUART1_TX MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_CTS__AUART1_CTS MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_RTS__AUART1_RTS MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_RX__AUART2_RX MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_TX__AUART2_TX MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_CTS__AUART2_CTS MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_RTS__AUART2_RTS MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_RX__AUART3_RX MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_TX__AUART3_TX MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_CTS__AUART3_CTS MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_RTS__AUART3_RTS MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_0)
+#define MX28_PAD_PWM0__PWM_0 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_0)
+#define MX28_PAD_PWM1__PWM_1 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_0)
+#define MX28_PAD_PWM2__PWM_2 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_0)
+#define MX28_PAD_I2C0_SCL__I2C0_SCL MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_0)
+#define MX28_PAD_I2C0_SDA__I2C0_SDA MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_0)
+#define MX28_PAD_SPDIF__SPDIF_TX MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_0)
+#define MX28_PAD_PWM3__PWM_3 MXS_IOMUX_PAD_NAKED(3, 28, PAD_MUXSEL_0)
+#define MX28_PAD_PWM4__PWM_4 MXS_IOMUX_PAD_NAKED(3, 29, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RESET__LCD_RESET MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_0)
+
+#define MX28_PAD_ENET0_MDC__ENET0_MDC MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_COL__ENET0_COL MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_CRS__ENET0_CRS MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_0)
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET MXS_IOMUX_PAD_NAKED(4, 16, PAD_MUXSEL_0)
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK MXS_IOMUX_PAD_NAKED(4, 20, PAD_MUXSEL_0)
+
+#define MX28_PAD_EMI_D00__EMI_DATA0 MXS_IOMUX_PAD_NAKED(5, 0, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D01__EMI_DATA1 MXS_IOMUX_PAD_NAKED(5, 1, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D02__EMI_DATA2 MXS_IOMUX_PAD_NAKED(5, 2, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D03__EMI_DATA3 MXS_IOMUX_PAD_NAKED(5, 3, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D04__EMI_DATA4 MXS_IOMUX_PAD_NAKED(5, 4, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D05__EMI_DATA5 MXS_IOMUX_PAD_NAKED(5, 5, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D06__EMI_DATA6 MXS_IOMUX_PAD_NAKED(5, 6, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D07__EMI_DATA7 MXS_IOMUX_PAD_NAKED(5, 7, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D08__EMI_DATA8 MXS_IOMUX_PAD_NAKED(5, 8, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D09__EMI_DATA9 MXS_IOMUX_PAD_NAKED(5, 9, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D10__EMI_DATA10 MXS_IOMUX_PAD_NAKED(5, 10, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D11__EMI_DATA11 MXS_IOMUX_PAD_NAKED(5, 11, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D12__EMI_DATA12 MXS_IOMUX_PAD_NAKED(5, 12, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D13__EMI_DATA13 MXS_IOMUX_PAD_NAKED(5, 13, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D14__EMI_DATA14 MXS_IOMUX_PAD_NAKED(5, 14, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D15__EMI_DATA15 MXS_IOMUX_PAD_NAKED(5, 15, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_ODT0__EMI_ODT0 MXS_IOMUX_PAD_NAKED(5, 16, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQM0__EMI_DQM0 MXS_IOMUX_PAD_NAKED(5, 17, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_ODT1__EMI_ODT1 MXS_IOMUX_PAD_NAKED(5, 18, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQM1__EMI_DQM1 MXS_IOMUX_PAD_NAKED(5, 19, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK MXS_IOMUX_PAD_NAKED(5, 20, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CLK__EMI_CLK MXS_IOMUX_PAD_NAKED(5, 21, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQS0__EMI_DQS0 MXS_IOMUX_PAD_NAKED(5, 22, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQS1__EMI_DQS1 MXS_IOMUX_PAD_NAKED(5, 23, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN MXS_IOMUX_PAD_NAKED(5, 26, PAD_MUXSEL_0)
+
+#define MX28_PAD_EMI_A00__EMI_ADDR0 MXS_IOMUX_PAD_NAKED(6, 0, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A01__EMI_ADDR1 MXS_IOMUX_PAD_NAKED(6, 1, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A02__EMI_ADDR2 MXS_IOMUX_PAD_NAKED(6, 2, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A03__EMI_ADDR3 MXS_IOMUX_PAD_NAKED(6, 3, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A04__EMI_ADDR4 MXS_IOMUX_PAD_NAKED(6, 4, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A05__EMI_ADDR5 MXS_IOMUX_PAD_NAKED(6, 5, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A06__EMI_ADDR6 MXS_IOMUX_PAD_NAKED(6, 6, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A07__EMI_ADDR7 MXS_IOMUX_PAD_NAKED(6, 7, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A08__EMI_ADDR8 MXS_IOMUX_PAD_NAKED(6, 8, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A09__EMI_ADDR9 MXS_IOMUX_PAD_NAKED(6, 9, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A10__EMI_ADDR10 MXS_IOMUX_PAD_NAKED(6, 10, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A11__EMI_ADDR11 MXS_IOMUX_PAD_NAKED(6, 11, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A12__EMI_ADDR12 MXS_IOMUX_PAD_NAKED(6, 12, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A13__EMI_ADDR13 MXS_IOMUX_PAD_NAKED(6, 13, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A14__EMI_ADDR14 MXS_IOMUX_PAD_NAKED(6, 14, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA0__EMI_BA0 MXS_IOMUX_PAD_NAKED(6, 16, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA1__EMI_BA1 MXS_IOMUX_PAD_NAKED(6, 17, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA2__EMI_BA2 MXS_IOMUX_PAD_NAKED(6, 18, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CASN__EMI_CASN MXS_IOMUX_PAD_NAKED(6, 19, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_RASN__EMI_RASN MXS_IOMUX_PAD_NAKED(6, 20, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_WEN__EMI_WEN MXS_IOMUX_PAD_NAKED(6, 21, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CE0N__EMI_CE0N MXS_IOMUX_PAD_NAKED(6, 22, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CE1N__EMI_CE1N MXS_IOMUX_PAD_NAKED(6, 23, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CKE__EMI_CKE MXS_IOMUX_PAD_NAKED(6, 24, PAD_MUXSEL_0)
+
+/* MUXSEL_1 */
+#define MX28_PAD_GPMI_D00__SSP1_D0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D01__SSP1_D1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D02__SSP1_D2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D03__SSP1_D3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D04__SSP1_D4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D05__SSP1_D5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D06__SSP1_D6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D07__SSP1_D7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE0N__SSP3_D0 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE1N__SSP3_D3 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE2N__CAN1_TX MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE3N__CAN1_RX MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY2__CAN0_TX MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY3__CAN0_RX MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDN__SSP3_SCK MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_WRN__SSP1_SCK MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_ALE__SSP3_D1 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CLE__SSP3_D2 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_1)
+
+#define MX28_PAD_LCD_D03__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D04__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D08__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D09__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RS__LCD_DOTCLK MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_CS__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_1)
+
+#define MX28_PAD_SSP0_DATA4__SSP2_D0 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA5__SSP2_D3 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_SCK__SSP2_D1 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_CMD__SSP2_D2 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_DATA0__SSP2_D6 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_DATA3__SSP2_D7 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SCK__AUART2_RX MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_MOSI__AUART2_TX MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_MISO__AUART3_RX MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS0__AUART3_TX MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS1__SSP2_D1 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS2__SSP2_D2 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_SCK__AUART4_TX MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_MOSI__AUART4_RX MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_MISO__AUART4_RTS MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_SS0__AUART4_CTS MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_1)
+
+#define MX28_PAD_AUART0_RX__I2C0_SCL MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_TX__I2C0_SDA MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_CTS__AUART4_RX MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_RTS__AUART4_TX MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_RTS__USB0_ID MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_RX__SSP3_D1 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_TX__SSP3_D2 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_CTS__I2C1_SCL MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_RTS__I2C1_SDA MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_RX__CAN0_TX MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_TX__CAN0_RX MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_CTS__CAN1_TX MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_RTS__CAN1_RX MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_1)
+#define MX28_PAD_PWM0__I2C1_SCL MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_1)
+#define MX28_PAD_PWM1__I2C1_SDA MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_1)
+#define MX28_PAD_PWM2__USB0_ID MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_MCLK__PWM_3 MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_LRCLK__PWM_4 MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_BITCLK__PWM_5 MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_SDATA0__PWM_6 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_1)
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_1)
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF1_SDATA0__PWM_7 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RESET__LCD_VSYNC MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_1)
+
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5 MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_1)
+
+/* MUXSEL_2 */
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY0__USB0_ID MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_ALE__SSP3_D4 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_CLE__SSP3_D5 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_LCD_D00__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D01__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D02__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D03__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D04__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D05__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D06__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D07__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D08__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D09__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D10__ETM_DA10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D11__ETM_DA11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D12__ETM_DA12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D13__ETM_DA13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D14__ETM_DA14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D15__ETM_DA15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D16__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D17__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D18__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D19__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D20__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D21__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D22__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D23__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_RD_E__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_2)
+
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_AUART0_RX__DUART_CTS MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_TX__DUART_RTS MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_CTS__DUART_RX MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_RTS__DUART_TX MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_RX__PWM_0 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_TX__PWM_1 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_RX__SSP3_D4 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_TX__SSP3_D5 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_2)
+#define MX28_PAD_PWM0__DUART_RX MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_2)
+#define MX28_PAD_PWM1__DUART_TX MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_2)
+#define MX28_PAD_PWM2__USB1_OVERCURRENT MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_2)
+#define MX28_PAD_I2C0_SCL__DUART_RX MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_2)
+#define MX28_PAD_I2C0_SDA__DUART_TX MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_2)
+#define MX28_PAD_SPDIF__ENET1_RX_ER MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_2)
+
+/* MUXSEL_GPIO */
+#define MX28_PAD_GPMI_D00__GPIO_0_0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D01__GPIO_0_1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D02__GPIO_0_2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D03__GPIO_0_3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D04__GPIO_0_4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D05__GPIO_0_5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D06__GPIO_0_6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D07__GPIO_0_7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDN__GPIO_0_24 MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_WRN__GPIO_0_25 MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_ALE__GPIO_0_26 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CLE__GPIO_0_27 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_LCD_D00__GPIO_1_0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D01__GPIO_1_1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D02__GPIO_1_2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D03__GPIO_1_3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D04__GPIO_1_4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D05__GPIO_1_5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D06__GPIO_1_6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D07__GPIO_1_7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D08__GPIO_1_8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D09__GPIO_1_9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D10__GPIO_1_10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D11__GPIO_1_11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D12__GPIO_1_12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D13__GPIO_1_13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D14__GPIO_1_14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D15__GPIO_1_15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D16__GPIO_1_16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D17__GPIO_1_17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D18__GPIO_1_18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D19__GPIO_1_19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D20__GPIO_1_20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D21__GPIO_1_21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D22__GPIO_1_22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D23__GPIO_1_23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RD_E__GPIO_1_24 MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25 MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RS__GPIO_1_26 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_CS__GPIO_1_27 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31 MXS_IOMUX_PAD_NAKED(1, 31, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_CMD__GPIO_2_8 MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_SCK__GPIO_2_10 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_SCK__GPIO_2_12 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_CMD__GPIO_2_13 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SCK__GPIO_2_16 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_MISO__GPIO_2_18 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS0__GPIO_2_19 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS1__GPIO_2_20 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS2__GPIO_2_21 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_SCK__GPIO_2_24 MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25 MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_MISO__GPIO_2_26 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_SS0__GPIO_2_27 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_AUART0_RX__GPIO_3_0 MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_TX__GPIO_3_1 MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_CTS__GPIO_3_2 MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_RTS__GPIO_3_3 MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_RX__GPIO_3_4 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_TX__GPIO_3_5 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_CTS__GPIO_3_6 MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_RTS__GPIO_3_7 MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_RX__GPIO_3_8 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_TX__GPIO_3_9 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_CTS__GPIO_3_10 MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_RTS__GPIO_3_11 MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_RX__GPIO_3_12 MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_TX__GPIO_3_13 MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_CTS__GPIO_3_14 MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_RTS__GPIO_3_15 MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM0__GPIO_3_16 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM1__GPIO_3_17 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM2__GPIO_3_18 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20 MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21 MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22 MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_I2C0_SCL__GPIO_3_24 MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_I2C0_SDA__GPIO_3_25 MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SPDIF__GPIO_3_27 MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM3__GPIO_3_28 MXS_IOMUX_PAD_NAKED(3, 28, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM4__GPIO_3_29 MXS_IOMUX_PAD_NAKED(3, 29, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RESET__GPIO_3_30 MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_ENET0_MDC__GPIO_4_0 MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1 MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2 MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5 MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6 MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_COL__GPIO_4_14 MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_CRS__GPIO_4_15 MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET_CLK__GPIO_4_16 MXS_IOMUX_PAD_NAKED(4, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20 MXS_IOMUX_PAD_NAKED(4, 20, PAD_MUXSEL_GPIO)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 000000000000..fe558e3c5a9a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+/*
+ * IOMUX/PAD Bit field definitions
+ *
+ * PAD_BANK: 0..2 (3)
+ * PAD_PIN: 3..7 (5)
+ * PAD_MUXSEL: 8..9 (2)
+ * PAD_MA: 10..11 (2)
+ * PAD_MA_VALID: 12 (1)
+ * PAD_VOL: 13 (1)
+ * PAD_VOL_VALID: 14 (1)
+ * PAD_PULL: 15 (1)
+ * PAD_PULL_VALID: 16 (1)
+ * RESERVED: 17..31 (15)
+ */
+typedef u32 iomux_cfg_t;
+
+#define MXS_PAD_BANK_SHIFT 0
+#define MXS_PAD_BANK_MASK ((iomux_cfg_t)0x7 << MXS_PAD_BANK_SHIFT)
+#define MXS_PAD_PIN_SHIFT 3
+#define MXS_PAD_PIN_MASK ((iomux_cfg_t)0x1f << MXS_PAD_PIN_SHIFT)
+#define MXS_PAD_MUXSEL_SHIFT 8
+#define MXS_PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MUXSEL_SHIFT)
+#define MXS_PAD_MA_SHIFT 10
+#define MXS_PAD_MA_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MA_SHIFT)
+#define MXS_PAD_MA_VALID_SHIFT 12
+#define MXS_PAD_MA_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_MA_VALID_SHIFT)
+#define MXS_PAD_VOL_SHIFT 13
+#define MXS_PAD_VOL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_SHIFT)
+#define MXS_PAD_VOL_VALID_SHIFT 14
+#define MXS_PAD_VOL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_VALID_SHIFT)
+#define MXS_PAD_PULL_SHIFT 15
+#define MXS_PAD_PULL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_SHIFT)
+#define MXS_PAD_PULL_VALID_SHIFT 16
+#define MXS_PAD_PULL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_VALID_SHIFT)
+
+#define PAD_MUXSEL_0 0
+#define PAD_MUXSEL_1 1
+#define PAD_MUXSEL_2 2
+#define PAD_MUXSEL_GPIO 3
+
+#define PAD_4MA 0
+#define PAD_8MA 1
+#define PAD_12MA 2
+#define PAD_16MA 3
+
+#define PAD_1V8 0
+#define PAD_3V3 1
+
+#define PAD_NOPULL 0
+#define PAD_PULLUP 1
+
+#define MXS_PAD_4MA ((PAD_4MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_8MA ((PAD_8MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_12MA ((PAD_12MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_16MA ((PAD_16MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+
+#define MXS_PAD_1V8 ((PAD_1V8 << MXS_PAD_VOL_SHIFT) | \
+ MXS_PAD_VOL_VALID_MASK)
+#define MXS_PAD_3V3 ((PAD_3V3 << MXS_PAD_VOL_SHIFT) | \
+ MXS_PAD_VOL_VALID_MASK)
+
+#define MXS_PAD_NOPULL ((PAD_NOPULL << MXS_PAD_PULL_SHIFT) | \
+ MXS_PAD_PULL_VALID_MASK)
+#define MXS_PAD_PULLUP ((PAD_PULLUP << MXS_PAD_PULL_SHIFT) | \
+ MXS_PAD_PULL_VALID_MASK)
+
+#define MXS_IOMUX_PAD(_bank, _pin, _muxsel, _ma, _vol, _pull) \
+ (((iomux_cfg_t)(_bank) << MXS_PAD_BANK_SHIFT) | \
+ ((iomux_cfg_t)(_pin) << MXS_PAD_PIN_SHIFT) | \
+ ((iomux_cfg_t)(_muxsel) << MXS_PAD_MUXSEL_SHIFT) | \
+ ((iomux_cfg_t)(_ma) << MXS_PAD_MA_SHIFT) | \
+ ((iomux_cfg_t)(_vol) << MXS_PAD_VOL_SHIFT) | \
+ ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT))
+
+/*
+ * A pad becomes naked, when none of mA, vol or pull
+ * validity bits is set.
+ */
+#define MXS_IOMUX_PAD_NAKED(_bank, _pin, _muxsel) \
+ MXS_IOMUX_PAD(_bank, _pin, _muxsel, 0, 0, 0)
+
+static inline unsigned int PAD_BANK(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_BANK_MASK) >> MXS_PAD_BANK_SHIFT;
+}
+
+static inline unsigned int PAD_PIN(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PIN_MASK) >> MXS_PAD_PIN_SHIFT;
+}
+
+static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MUXSEL_MASK) >> MXS_PAD_MUXSEL_SHIFT;
+}
+
+static inline unsigned int PAD_MA(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MA_MASK) >> MXS_PAD_MA_SHIFT;
+}
+
+static inline unsigned int PAD_MA_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MA_VALID_MASK) >> MXS_PAD_MA_VALID_SHIFT;
+}
+
+static inline unsigned int PAD_VOL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_VOL_MASK) >> MXS_PAD_VOL_SHIFT;
+}
+
+static inline unsigned int PAD_VOL_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_VOL_VALID_MASK) >> MXS_PAD_VOL_VALID_SHIFT;
+}
+
+static inline unsigned int PAD_PULL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PULL_MASK) >> MXS_PAD_PULL_SHIFT;
+}
+
+static inline unsigned int PAD_PULL_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PULL_VALID_MASK) >> MXS_PAD_PULL_VALID_SHIFT;
+}
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad);
+
+/*
+ * configures multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 000000000000..f771039b814a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 000000000000..b5420a5c2d4b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 000000000000..9edd02ec8e30
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_UARTAPP_TX_DMA 23
+#define MX23_INT_UARTAPP_INTERNAL 24
+#define MX23_INT_UARTAPP_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_UARTAPP2_TX_DMA 58
+#define MX23_INT_UARTAPP2_INTERNAL 59
+#define MX23_INT_UARTAPP2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 000000000000..0716745267ad
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR 0x00000000
+#define MX28_OCRAM_SIZE SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR 0x80000000
+#define MX28_IO_SIZE SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR (MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR (MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR (MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT 0
+#define MX28_INT_VDDD_BRNOUT 1
+#define MX28_INT_VDDIO_BRNOUT 2
+#define MX28_INT_VDDA_BRNOUT 3
+#define MX28_INT_VDD5V_DROOP 4
+#define MX28_INT_DCDC4P2_BRNOUT 5
+#define MX28_INT_VDD5V 6
+#define MX28_INT_CAN0 8
+#define MX28_INT_CAN1 9
+#define MX28_INT_LRADC_TOUCH 10
+#define MX28_INT_HSADC 13
+#define MX28_INT_IRADC_THRESH0 14
+#define MX28_INT_IRADC_THRESH1 15
+#define MX28_INT_LRADC_CH0 16
+#define MX28_INT_LRADC_CH1 17
+#define MX28_INT_LRADC_CH2 18
+#define MX28_INT_LRADC_CH3 19
+#define MX28_INT_LRADC_CH4 20
+#define MX28_INT_LRADC_CH5 21
+#define MX28_INT_LRADC_CH6 22
+#define MX28_INT_LRADC_CH7 23
+#define MX28_INT_LRADC_BUTTON0 24
+#define MX28_INT_LRADC_BUTTON1 25
+#define MX28_INT_PERFMON 27
+#define MX28_INT_RTC_1MSEC 28
+#define MX28_INT_RTC_ALARM 29
+#define MX28_INT_COMMS 31
+#define MX28_INT_EMI_ERR 32
+#define MX28_INT_LCDIF 38
+#define MX28_INT_PXP 39
+#define MX28_INT_BCH 41
+#define MX28_INT_GPMI 42
+#define MX28_INT_SPDIF_ERROR 45
+#define MX28_INT_DUART 47
+#define MX28_INT_TIMER0 48
+#define MX28_INT_TIMER1 49
+#define MX28_INT_TIMER2 50
+#define MX28_INT_TIMER3 51
+#define MX28_INT_DCP_VMI 52
+#define MX28_INT_DCP 53
+#define MX28_INT_DCP_SECURE 54
+#define MX28_INT_SAIF1 58
+#define MX28_INT_SAIF0 59
+#define MX28_INT_SPDIF_DMA 66
+#define MX28_INT_I2C0_DMA 68
+#define MX28_INT_I2C1_DMA 69
+#define MX28_INT_AUART0_RX_DMA 70
+#define MX28_INT_AUART0_TX_DMA 71
+#define MX28_INT_AUART1_RX_DMA 72
+#define MX28_INT_AUART1_TX_DMA 73
+#define MX28_INT_AUART2_RX_DMA 74
+#define MX28_INT_AUART2_TX_DMA 75
+#define MX28_INT_AUART3_RX_DMA 76
+#define MX28_INT_AUART3_TX_DMA 77
+#define MX28_INT_AUART4_RX_DMA 78
+#define MX28_INT_AUART4_TX_DMA 79
+#define MX28_INT_SAIF0_DMA 80
+#define MX28_INT_SAIF1_DMA 81
+#define MX28_INT_SSP0_DMA 82
+#define MX28_INT_SSP1_DMA 83
+#define MX28_INT_SSP2_DMA 84
+#define MX28_INT_SSP3_DMA 85
+#define MX28_INT_LCDIF_DMA 86
+#define MX28_INT_HSADC_DMA 87
+#define MX28_INT_GPMI_DMA 88
+#define MX28_INT_DIGCTL_DEBUG_TRAP 89
+#define MX28_INT_USB1 92
+#define MX28_INT_USB0 93
+#define MX28_INT_USB1_WAKEUP 94
+#define MX28_INT_USB0_WAKEUP 95
+#define MX28_INT_SSP0 96
+#define MX28_INT_SSP1 97
+#define MX28_INT_SSP2 98
+#define MX28_INT_SSP3 99
+#define MX28_INT_ENET_SWI 100
+#define MX28_INT_ENET_MAC0 101
+#define MX28_INT_ENET_MAC1 102
+#define MX28_INT_ENET_MAC0_1588 103
+#define MX28_INT_ENET_MAC1_1588 104
+#define MX28_INT_I2C1_ERROR 110
+#define MX28_INT_I2C0_ERROR 111
+#define MX28_INT_AUART0 112
+#define MX28_INT_AUART1 113
+#define MX28_INT_AUART2 114
+#define MX28_INT_AUART3 115
+#define MX28_INT_AUART4 116
+#define MX28_INT_GPIO4 123
+#define MX28_INT_GPIO3 124
+#define MX28_INT_GPIO2 125
+#define MX28_INT_GPIO1 126
+#define MX28_INT_GPIO0 127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 000000000000..f186c08c2911
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+/*
+ * MXS CPU types
+ */
+#define cpu_is_mx23() (machine_is_mx23evk())
+#define cpu_is_mx28() (machine_is_mx28evk())
+
+/*
+ * IO addresses common to MXS-based
+ */
+#define MXS_IO_BASE_ADDR 0x80000000
+#define MXS_IO_SIZE SZ_1M
+
+#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
+#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
+#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
+#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
+#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
+#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
+#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
+#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
+#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
+#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
+#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
+#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
+#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
+#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
+#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
+#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
+#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
+#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
+#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
+#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
+#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
+#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
+#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
+#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf50fffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 7) + \
+ (((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+#ifndef __ASSEMBLER__
+static inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_SET_ADDR);
+}
+
+static inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
+
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
+#endif
+
+#endif /* __MACH_MXS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 000000000000..0e428239b433
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 000000000000..734ce8984a64
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE 32000 /* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 000000000000..a005e76f34f9
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@minirl.com)
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#include <asm/mach-types.h>
+
+static unsigned long mxs_duart_base;
+
+#define MXS_DUART(x) (*(volatile unsigned long *)(mxs_duart_base + (x)))
+
+#define MXS_DUART_DR 0x00
+#define MXS_DUART_FR 0x18
+#define MXS_DUART_FR_TXFE (1 << 7)
+#define MXS_DUART_CR 0x30
+#define MXS_DUART_CR_UARTEN (1 << 0)
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If it's not, the output is
+ * simply discarded.
+ */
+
+static void putc(int ch)
+{
+ if (!mxs_duart_base)
+ return;
+ if (!(MXS_DUART(MXS_DUART_CR) & MXS_DUART_CR_UARTEN))
+ return;
+
+ while (!(MXS_DUART(MXS_DUART_FR) & MXS_DUART_FR_TXFE))
+ barrier();
+
+ MXS_DUART(MXS_DUART_DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR 0x80070000
+#define MX28_DUART_BASE_ADDR 0x80074000
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX23EVK:
+ mxs_duart_base = MX23_DUART_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX28EVK:
+ mxs_duart_base = MX28_DUART_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 000000000000..103b0165ed0b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 000000000000..0e804e2f11f4
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.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
+ * 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/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mxs.h>
+#include <mach/iomux.h>
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+ u32 reg, ofs, bp, bm;
+ void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
+
+ /* muxsel */
+ ofs = 0x100;
+ ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+ bp = PAD_PIN(pad) % 16 * 2;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MUXSEL(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+
+ /* drive */
+ ofs = cpu_is_mx23() ? 0x200 : 0x300;
+ ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+ /* mA */
+ if (PAD_MA_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MA(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+ }
+ /* vol */
+ if (PAD_VOL_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4 + 2;
+ if (PAD_VOL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, iomux_base + ofs);
+ }
+
+ /* pull */
+ if (PAD_PULL_VALID(pad)) {
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ if (PAD_PULL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, iomux_base + ofs);
+ }
+
+ return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+ const iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 000000000000..aa0640052f58
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+static const iomux_cfg_t mx23evk_pads[] __initconst = {
+ /* duart */
+ MX23_PAD_PWM0__DUART_RX | MXS_PAD_4MA,
+ MX23_PAD_PWM1__DUART_TX | MXS_PAD_4MA,
+};
+
+static void __init mx23evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+ mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+ .init = mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = mx23evk_init,
+ .timer = &mx23evk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 000000000000..d162e95910f3
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+static const iomux_cfg_t mx28evk_pads[] __initconst = {
+ /* duart */
+ MX28_PAD_PWM0__DUART_RX |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_PWM1__DUART_TX |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+ /* fec0 */
+ MX28_PAD_ENET0_MDC__ENET0_MDC |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_MDIO__ENET0_MDIO |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD0__ENET0_RXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD1__ENET0_RXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD0__ENET0_TXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD1__ENET0_TXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET_CLK__CLKCTRL_ENET |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ /* phy power line */
+ MX28_PAD_SSP1_DATA3__GPIO_2_15 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* phy reset line */
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* fec */
+static void __init mx28evk_fec_reset(void)
+{
+ int ret;
+ struct clk *clk;
+
+ /* Enable fec phy clock */
+ clk = clk_get_sys("pll2", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ /* Power up fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ /* Reset fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ mdelay(1);
+ gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+ mx28_add_duart();
+
+ mx28evk_fec_reset();
+ mx28_add_fec(0, &mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+ mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+ .init = mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 000000000000..5148cd64a6b7
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 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/mx23.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+ mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX23, IO, 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 mx23_map_io(void)
+{
+ iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+ icoll_init_irq();
+ mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 000000000000..7e4cea32ebc6
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 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/mx28.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX28, IO, 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 mx28_map_io(void)
+{
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq();
+ mx28_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 000000000000..dbc04747b691
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2 0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU (0x00000020)
+#define HW_CLKCTRL_CPU_SET (0x00000024)
+#define HW_CLKCTRL_CPU_CLR (0x00000028)
+#define HW_CLKCTRL_CPU_TOG (0x0000002c)
+
+#define BP_CLKCTRL_CPU_RSRVD5 30
+#define BM_CLKCTRL_CPU_RSRVD5 0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+ (((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4 0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3 13
+#define BM_CLKCTRL_CPU_RSRVD3 0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v) \
+ (((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2 0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1 6
+#define BM_CLKCTRL_CPU_RSRVD1 0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS (0x00000030)
+#define HW_CLKCTRL_HBUS_SET (0x00000034)
+#define HW_CLKCTRL_HBUS_CLR (0x00000038)
+#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4 30
+#define BM_CLKCTRL_HBUS_RSRVD4 0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+ (((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2 0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1 6
+#define BM_CLKCTRL_HBUS_RSRVD1 0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS (0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 11
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL (0x00000050)
+#define HW_CLKCTRL_XTAL_SET (0x00000054)
+#define HW_CLKCTRL_XTAL_CLR (0x00000058)
+#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1 2
+#define BM_CLKCTRL_XTAL_RSRVD1 0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v) \
+ (((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_PIX (0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE 31
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2 0x40000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1 13
+#define BM_CLKCTRL_PIX_RSRVD1 0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v) \
+ (((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP (0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE 31
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1 10
+#define BM_CLKCTRL_SSP_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI (0x00000080)
+
+#define BP_CLKCTRL_GPMI_CLKGATE 31
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2 0x40000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1 11
+#define BM_CLKCTRL_GPMI_RSRVD1 0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF (0x00000090)
+
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD 0
+#define BM_CLKCTRL_SPDIF_RSRVD 0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI (0x000000a0)
+
+#define BP_CLKCTRL_EMI_CLKGATE 31
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3 18
+#define BM_CLKCTRL_EMI_RSRVD3 0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v) \
+ (((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2 12
+#define BM_CLKCTRL_EMI_RSRVD2 0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v) \
+ (((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1 6
+#define BM_CLKCTRL_EMI_RSRVD1 0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_IR (0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_RSRVD3 0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_RSRVD2 25
+#define BM_CLKCTRL_IR_RSRVD2 0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v) \
+ (((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1 10
+#define BM_CLKCTRL_IR_RSRVD1 0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF (0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1 17
+#define BM_CLKCTRL_SAIF_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV (0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+#define BP_CLKCTRL_TV_RSRVD 0
+#define BM_CLKCTRL_TV_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM (0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 7
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC (0x000000f0)
+#define HW_CLKCTRL_FRAC_SET (0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO 31
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x00000100)
+#define HW_CLKCTRL_FRAC1_SET (0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1 0
+#define BM_CLKCTRL_FRAC1_RSRVD1 0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ (0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+
+#define HW_CLKCTRL_RESET (0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD 2
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x00000130)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD 0
+#define BM_CLKCTRL_STATUS_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION (0x00000140)
+
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 000000000000..661df18755f7
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2009-2010 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_H__
+
+#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1 0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6 0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1 0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3 0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2 0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1 0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU (0x00000050)
+#define HW_CLKCTRL_CPU_SET (0x00000054)
+#define HW_CLKCTRL_CPU_CLR (0x00000058)
+#define HW_CLKCTRL_CPU_TOG (0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5 30
+#define BM_CLKCTRL_CPU_RSRVD5 0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+ (((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4 0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3 13
+#define BM_CLKCTRL_CPU_RSRVD3 0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v) \
+ (((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2 0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1 6
+#define BM_CLKCTRL_CPU_RSRVD1 0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS (0x00000060)
+#define HW_CLKCTRL_HBUS_SET (0x00000064)
+#define HW_CLKCTRL_HBUS_CLR (0x00000068)
+#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2 0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1 6
+#define BM_CLKCTRL_HBUS_RSRVD1 0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS (0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 12
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL (0x00000080)
+#define HW_CLKCTRL_XTAL_SET (0x00000084)
+#define HW_CLKCTRL_XTAL_CLR (0x00000088)
+#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2 27
+#define BM_CLKCTRL_XTAL_RSRVD2 0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v) \
+ (((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1 2
+#define BM_CLKCTRL_XTAL_RSRVD1 0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v) \
+ (((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0 (0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE 31
+#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP0_BUSY 0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1 10
+#define BM_CLKCTRL_SSP0_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP0_DIV 0
+#define BM_CLKCTRL_SSP0_DIV 0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1 (0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE 31
+#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP1_BUSY 0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1 10
+#define BM_CLKCTRL_SSP1_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP1_DIV 0
+#define BM_CLKCTRL_SSP1_DIV 0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2 (0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE 31
+#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP2_BUSY 0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1 10
+#define BM_CLKCTRL_SSP2_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP2_DIV 0
+#define BM_CLKCTRL_SSP2_DIV 0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3 (0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE 31
+#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP3_BUSY 0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1 10
+#define BM_CLKCTRL_SSP3_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP3_DIV 0
+#define BM_CLKCTRL_SSP3_DIV 0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI (0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE 31
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2 0x40000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1 11
+#define BM_CLKCTRL_GPMI_RSRVD1 0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF (0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE 31
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD 0
+#define BM_CLKCTRL_SPDIF_RSRVD 0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI (0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE 31
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3 18
+#define BM_CLKCTRL_EMI_RSRVD3 0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v) \
+ (((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2 12
+#define BM_CLKCTRL_EMI_RSRVD2 0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v) \
+ (((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1 6
+#define BM_CLKCTRL_EMI_RSRVD1 0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0 (0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE 31
+#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1 17
+#define BM_CLKCTRL_SAIF0_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF0_DIV 0
+#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1 (0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE 31
+#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1 17
+#define BM_CLKCTRL_SAIF1_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF1_DIV 0
+#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1 14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1 0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v) \
+ (((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV 0
+#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM (0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 8
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET (0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP 0x80000000
+#define BP_CLKCTRL_ENET_DISABLE 30
+#define BM_CLKCTRL_ENET_DISABLE 0x40000000
+#define BM_CLKCTRL_ENET_STATUS 0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1 0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME 21
+#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY 0x08000000
+#define BP_CLKCTRL_ENET_DIV 21
+#define BM_CLKCTRL_ENET_DIV 0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL 19
+#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v) \
+ (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0 0
+#define BM_CLKCTRL_ENET_RSRVD0 0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v) \
+ (((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC (0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2 0x80000000
+#define BM_CLKCTRL_HSADC_RESETB 0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV 28
+#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v) \
+ (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1 0
+#define BM_CLKCTRL_HSADC_RSRVD1 0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN (0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2 0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1 0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1 0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0 (0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC 24
+#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC 16
+#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC 8
+#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC 0
+#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2 24
+#define BM_CLKCTRL_FRAC1_RSRVD2 0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC 0
+#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ (0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0 19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+ (((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2 0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
+
+#define HW_CLKCTRL_RESET (0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD 6
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD 0
+#define BM_CLKCTRL_STATUS_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION (0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX28_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 000000000000..9343d7edd4f6
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#define MX23_CLKCTRL_RESET_OFFSET 0x120
+#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
+#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *mxs_clkctrl_reset_addr;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ /* reset the chip */
+ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);
+
+ pr_err("Failed to assert the chip reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+static int __init mxs_arch_reset_init(void)
+{
+ struct clk *clk;
+
+ mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +
+ (cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :
+ MX28_CLKCTRL_RESET_OFFSET);
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ return 0;
+}
+core_initcall(mxs_arch_reset_init);
+
+/*
+ * Clear the bit and poll it cleared. This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+ int timeout = 0x400;
+
+ /* clear the bit */
+ __mxs_clrl(mask, addr);
+
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+
+ /* poll the bit becoming clear */
+ while ((__raw_readl(addr) & mask) && --timeout)
+ /* nothing */;
+
+ return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ int ret;
+ int timeout = 0x400;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear CLKGATE */
+ __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
+
+ /* set SFTRST to reset the block */
+ __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
+ udelay(1);
+
+ /* poll CLKGATE becoming set */
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (unlikely(!timeout))
+ goto error;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear and poll CLKGATE */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+ if (unlikely(ret))
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 000000000000..13647f301860
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timrot 0 and 1, while MX23
+ * uses 0 and 2.
+ */
+
+#define MX23_TIMROT_VERSION_OFFSET 0x0a0
+#define MX28_TIMROT_VERSION_OFFSET 0x120
+#define BP_TIMROT_MAJOR_VERSION 24
+#define BV_TIMROT_VERSION_1 0x01
+#define BV_TIMROT_VERSION_2 0x02
+#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
+
+/*
+ * There are 4 registers for each timrotv2 instance, and 2 registers
+ * for each timrotv1. So address step 0x40 in macros below strides
+ * one instance of timrotv2 while two instances of timrotv1.
+ *
+ * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
+ * on MX28 while timrot2 on MX23.
+ */
+/* common between v1 and v2 */
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+/* v1 only */
+#define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40)
+/* v2 only */
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
+
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+
+static struct clock_event_device mxs_clockevent_device;
+static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *mxs_timrot_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
+static u32 timrot_major_version;
+
+static inline void timrot_irq_disable(void)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+ return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
+ & 0xffff0000) >> 16);
+}
+
+static cycle_t timrotv2_get_cycles(struct clocksource *cs)
+{
+ return ~__raw_readl(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
+
+ return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
+
+ return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .dev_id = &mxs_clockevent_device,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] const = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != mxs_clockevent_mode) {
+ /* Set event time into the furthest future */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ pr_info("%s: changing mode from %s to %s\n", __func__,
+ clock_event_mode_label[mxs_clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ mxs_clockevent_mode = mode;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_err("%s: Periodic mode is not implemented\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ timrot_irq_enable();
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device mxs_clockevent_device = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrotv2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ mxs_clockevent_device.mult =
+ div_sc(c, NSEC_PER_SEC, mxs_clockevent_device.shift);
+ mxs_clockevent_device.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
+ mxs_clockevent_device.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &mxs_clockevent_device);
+ mxs_clockevent_device.min_delta_ns =
+ clockevent_delta2ns(0xf, &mxs_clockevent_device);
+ } else {
+ mxs_clockevent_device.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &mxs_clockevent_device);
+ mxs_clockevent_device.min_delta_ns =
+ clockevent_delta2ns(0xf, &mxs_clockevent_device);
+ }
+
+ clockevents_register_device(&mxs_clockevent_device);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrotv2_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1()) {
+ clocksource_mxs.read = timrotv1_get_cycles;
+ clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+ }
+
+ clocksource_register_hz(&clocksource_mxs, c);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk, int irq)
+{
+ clk_enable(timer_clk);
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
+
+ /* get timrot version */
+ timrot_major_version = __raw_readl(mxs_timrot_base +
+ (cpu_is_mx23() ? MX23_TIMROT_VERSION_OFFSET :
+ MX28_TIMROT_VERSION_OFFSET));
+ timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
+
+ /* one for clock_event */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+
+ /* another for clocksource */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
+
+ /* set clocksource timer fixed count to the maximum */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 82801dbf0579..f12f22d09b6c 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -114,7 +114,6 @@ static struct clocksource clocksource_netx = {
.rating = 200,
.read = netx_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -151,9 +150,7 @@ static void __init netx_timer_init(void)
writel(NETX_GPIO_COUNTER_CTRL_RUN,
NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
- clocksource_netx.mult =
- clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
- clocksource_register(&clocksource_netx);
+ clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE);
netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
netx_clockevent.shift);
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index 89f793adf776..48a59f24e10c 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -7,7 +7,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/clk.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include "clock.h"
/*
diff --git a/arch/arm/mach-ns9xxx/time-ns9360.c b/arch/arm/mach-ns9xxx/time-ns9360.c
index 77281260358a..9ca32f55728b 100644
--- a/arch/arm/mach-ns9xxx/time-ns9360.c
+++ b/arch/arm/mach-ns9xxx/time-ns9360.c
@@ -35,7 +35,6 @@ static struct clocksource ns9360_clocksource = {
.rating = 300,
.read = ns9360_clocksource_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -148,10 +147,7 @@ static void __init ns9360_timer_init(void)
__raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
- ns9360_clocksource.mult = clocksource_hz2mult(ns9360_cpuclock(),
- ns9360_clocksource.shift);
-
- clocksource_register(&ns9360_clocksource);
+ clocksource_register_hz(&ns9360_clocksource, ns9360_cpuclock());
latch = SH_DIV(ns9360_cpuclock(), HZ, 0);
diff --git a/arch/arm/mach-nuc93x/clock.h b/arch/arm/mach-nuc93x/clock.h
index 18e51be4816f..4de1f1da9dc5 100644
--- a/arch/arm/mach-nuc93x/clock.h
+++ b/arch/arm/mach-nuc93x/clock.h
@@ -10,7 +10,7 @@
* the Free Software Foundation; either version 2 of the License.
*/
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
void nuc93x_clk_enable(struct clk *clk, int enable);
void clks_register(struct clk_lookup *clks, size_t num);
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 5f6496375404..8d2f2daba0c0 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -152,20 +152,11 @@ config MACH_NOKIA770
config MACH_AMS_DELTA
bool "Amstrad E3 (Delta)"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ select FIQ
help
Support for the Amstrad E3 (codename Delta) videophone. Say Y here
if you have such a device.
-config AMS_DELTA_FIQ
- bool "Fast Interrupt Request (FIQ) support for the E3"
- depends on MACH_AMS_DELTA
- select FIQ
- help
- Provide a FIQ handler for the E3.
- This allows for fast handling of interrupts generated
- by the clock line of the E3 mailboard (or a PS/2 keyboard)
- connected to the GPIO based external keyboard port.
-
config MACH_OMAP_GENERIC
bool "Generic OMAP board"
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 9a304d854e33..6ee19504845f 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
+obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o dma.o
obj-y += clock.o clock_data.o opp_data.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
@@ -39,8 +39,8 @@ obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o
obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o
obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
-obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
-obj-$(CONFIG_AMS_DELTA_FIQ) += ams-delta-fiq.o ams-delta-fiq-handler.o
+obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o ams-delta-fiq.o \
+ ams-delta-fiq-handler.o
obj-$(CONFIG_MACH_SX1) += board-sx1.o board-sx1-mmc.o
obj-$(CONFIG_MACH_HERALD) += board-htcherald.o
@@ -49,6 +49,12 @@ ifeq ($(CONFIG_ARCH_OMAP15XX),y)
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
endif
+# GPIO
+obj-$(CONFIG_ARCH_OMAP730) += gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP850) += gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP15XX) += gpio15xx.o
+obj-$(CONFIG_ARCH_OMAP16XX) += gpio16xx.o
+
# LEDs support
led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_H3) += leds-h2p2-debug.o
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 1d4163b9f0b7..bd0495a9ac3b 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -28,6 +28,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <plat/io.h>
#include <plat/board-ams-delta.h>
#include <mach/gpio.h>
#include <plat/keypad.h>
@@ -42,84 +43,82 @@
static u8 ams_delta_latch1_reg;
static u16 ams_delta_latch2_reg;
-static int ams_delta_keymap[] = {
+static const unsigned int ams_delta_keymap[] = {
KEY(0, 0, KEY_F1), /* Advert */
- KEY(3, 0, KEY_COFFEE), /* Games */
- KEY(2, 0, KEY_QUESTION), /* Directory */
- KEY(3, 2, KEY_CONNECT), /* Internet */
- KEY(2, 1, KEY_SHOP), /* Services */
+ KEY(0, 3, KEY_COFFEE), /* Games */
+ KEY(0, 2, KEY_QUESTION), /* Directory */
+ KEY(2, 3, KEY_CONNECT), /* Internet */
+ KEY(1, 2, KEY_SHOP), /* Services */
KEY(1, 1, KEY_PHONE), /* VoiceMail */
- KEY(1, 0, KEY_DELETE), /* Delete */
+ KEY(0, 1, KEY_DELETE), /* Delete */
KEY(2, 2, KEY_PLAY), /* Play */
- KEY(0, 1, KEY_PAGEUP), /* Up */
- KEY(3, 1, KEY_PAGEDOWN), /* Down */
- KEY(0, 2, KEY_EMAIL), /* ReadEmail */
- KEY(1, 2, KEY_STOP), /* Stop */
+ KEY(1, 0, KEY_PAGEUP), /* Up */
+ KEY(1, 3, KEY_PAGEDOWN), /* Down */
+ KEY(2, 0, KEY_EMAIL), /* ReadEmail */
+ KEY(2, 1, KEY_STOP), /* Stop */
/* Numeric keypad portion */
- KEY(7, 0, KEY_KP1),
- KEY(6, 0, KEY_KP2),
- KEY(5, 0, KEY_KP3),
- KEY(7, 1, KEY_KP4),
- KEY(6, 1, KEY_KP5),
- KEY(5, 1, KEY_KP6),
- KEY(7, 2, KEY_KP7),
- KEY(6, 2, KEY_KP8),
- KEY(5, 2, KEY_KP9),
- KEY(6, 3, KEY_KP0),
- KEY(7, 3, KEY_KPASTERISK),
- KEY(5, 3, KEY_KPDOT), /* # key */
- KEY(2, 7, KEY_NUMLOCK), /* Mute */
- KEY(1, 7, KEY_KPMINUS), /* Recall */
- KEY(1, 6, KEY_KPPLUS), /* Redial */
- KEY(6, 7, KEY_KPSLASH), /* Handsfree */
- KEY(0, 6, KEY_ENTER), /* Video */
-
- KEY(4, 7, KEY_CAMERA), /* Photo */
-
- KEY(4, 0, KEY_F2), /* Home */
- KEY(4, 1, KEY_F3), /* Office */
- KEY(4, 2, KEY_F4), /* Mobile */
+ KEY(0, 7, KEY_KP1),
+ KEY(0, 6, KEY_KP2),
+ KEY(0, 5, KEY_KP3),
+ KEY(1, 7, KEY_KP4),
+ KEY(1, 6, KEY_KP5),
+ KEY(1, 5, KEY_KP6),
+ KEY(2, 7, KEY_KP7),
+ KEY(2, 6, KEY_KP8),
+ KEY(2, 5, KEY_KP9),
+ KEY(3, 6, KEY_KP0),
+ KEY(3, 7, KEY_KPASTERISK),
+ KEY(3, 5, KEY_KPDOT), /* # key */
+ KEY(7, 2, KEY_NUMLOCK), /* Mute */
+ KEY(7, 1, KEY_KPMINUS), /* Recall */
+ KEY(6, 1, KEY_KPPLUS), /* Redial */
+ KEY(7, 6, KEY_KPSLASH), /* Handsfree */
+ KEY(6, 0, KEY_ENTER), /* Video */
+
+ KEY(7, 4, KEY_CAMERA), /* Photo */
+
+ KEY(0, 4, KEY_F2), /* Home */
+ KEY(1, 4, KEY_F3), /* Office */
+ KEY(2, 4, KEY_F4), /* Mobile */
KEY(7, 7, KEY_F5), /* SMS */
- KEY(5, 7, KEY_F6), /* Email */
+ KEY(7, 5, KEY_F6), /* Email */
/* QWERTY portion of keypad */
- KEY(4, 3, KEY_Q),
+ KEY(3, 4, KEY_Q),
KEY(3, 3, KEY_W),
- KEY(2, 3, KEY_E),
- KEY(1, 3, KEY_R),
- KEY(0, 3, KEY_T),
- KEY(7, 4, KEY_Y),
- KEY(6, 4, KEY_U),
- KEY(5, 4, KEY_I),
+ KEY(3, 2, KEY_E),
+ KEY(3, 1, KEY_R),
+ KEY(3, 0, KEY_T),
+ KEY(4, 7, KEY_Y),
+ KEY(4, 6, KEY_U),
+ KEY(4, 5, KEY_I),
KEY(4, 4, KEY_O),
- KEY(3, 4, KEY_P),
+ KEY(4, 3, KEY_P),
- KEY(2, 4, KEY_A),
- KEY(1, 4, KEY_S),
- KEY(0, 4, KEY_D),
- KEY(7, 5, KEY_F),
- KEY(6, 5, KEY_G),
+ KEY(4, 2, KEY_A),
+ KEY(4, 1, KEY_S),
+ KEY(4, 0, KEY_D),
+ KEY(5, 7, KEY_F),
+ KEY(5, 6, KEY_G),
KEY(5, 5, KEY_H),
- KEY(4, 5, KEY_J),
- KEY(3, 5, KEY_K),
- KEY(2, 5, KEY_L),
+ KEY(5, 4, KEY_J),
+ KEY(5, 3, KEY_K),
+ KEY(5, 2, KEY_L),
- KEY(1, 5, KEY_Z),
- KEY(0, 5, KEY_X),
- KEY(7, 6, KEY_C),
+ KEY(5, 1, KEY_Z),
+ KEY(5, 0, KEY_X),
+ KEY(6, 7, KEY_C),
KEY(6, 6, KEY_V),
- KEY(5, 6, KEY_B),
- KEY(4, 6, KEY_N),
- KEY(3, 6, KEY_M),
- KEY(2, 6, KEY_SPACE),
+ KEY(6, 5, KEY_B),
+ KEY(6, 4, KEY_N),
+ KEY(6, 3, KEY_M),
+ KEY(6, 2, KEY_SPACE),
- KEY(0, 7, KEY_LEFTSHIFT), /* Vol up */
- KEY(3, 7, KEY_LEFTCTRL), /* Vol down */
-
- 0
+ KEY(7, 0, KEY_LEFTSHIFT), /* Vol up */
+ KEY(7, 3, KEY_LEFTCTRL), /* Vol down */
};
void ams_delta_latch1_write(u8 mask, u8 value)
@@ -140,7 +139,6 @@ static void __init ams_delta_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
}
static struct map_desc ams_delta_io_desc[] __initdata = {
@@ -189,11 +187,15 @@ static struct resource ams_delta_kp_resources[] = {
},
};
+static const struct matrix_keymap_data ams_delta_keymap_data = {
+ .keymap = ams_delta_keymap,
+ .keymap_size = ARRAY_SIZE(ams_delta_keymap),
+};
+
static struct omap_kp_platform_data ams_delta_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = ams_delta_keymap,
- .keymapsize = ARRAY_SIZE(ams_delta_keymap),
+ .keymap_data = &ams_delta_keymap_data,
.delay = 9,
};
@@ -307,16 +309,14 @@ static void __init ams_delta_init(void)
#endif
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
-#ifdef CONFIG_AMS_DELTA_FIQ
ams_delta_init_fiq();
-#endif
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
}
static struct plat_serial8250_port ams_delta_modem_ports[] = {
{
- .membase = (void *) AMS_DELTA_MODEM_VIRT,
+ .membase = IOMEM(AMS_DELTA_MODEM_VIRT),
.mapbase = AMS_DELTA_MODEM_PHYS,
.irq = -EINVAL, /* changed later */
.flags = UPF_BOOT_AUTOCONF,
@@ -340,6 +340,9 @@ static int __init ams_delta_modem_init(void)
{
int err;
+ if (!machine_is_ams_delta())
+ return -ENODEV;
+
omap_cfg_reg(M14_1510_GPIO2);
ams_delta_modem_ports[0].irq =
gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 149fdd32e127..0efb9dbae44c 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -69,36 +69,35 @@
#define fsample_cpld_clear(bit) \
fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
-static int fsample_keymap[] = {
- KEY(0,0,KEY_UP),
- KEY(0,1,KEY_RIGHT),
- KEY(0,2,KEY_LEFT),
- KEY(0,3,KEY_DOWN),
- KEY(0,4,KEY_ENTER),
- KEY(1,0,KEY_F10),
- KEY(1,1,KEY_SEND),
- KEY(1,2,KEY_END),
- KEY(1,3,KEY_VOLUMEDOWN),
- KEY(1,4,KEY_VOLUMEUP),
- KEY(1,5,KEY_RECORD),
- KEY(2,0,KEY_F9),
- KEY(2,1,KEY_3),
- KEY(2,2,KEY_6),
- KEY(2,3,KEY_9),
- KEY(2,4,KEY_KPDOT),
- KEY(3,0,KEY_BACK),
- KEY(3,1,KEY_2),
- KEY(3,2,KEY_5),
- KEY(3,3,KEY_8),
- KEY(3,4,KEY_0),
- KEY(3,5,KEY_KPSLASH),
- KEY(4,0,KEY_HOME),
- KEY(4,1,KEY_1),
- KEY(4,2,KEY_4),
- KEY(4,3,KEY_7),
- KEY(4,4,KEY_KPASTERISK),
- KEY(4,5,KEY_POWER),
- 0
+static const unsigned int fsample_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_LEFT),
+ KEY(3, 0, KEY_DOWN),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_F10),
+ KEY(1, 1, KEY_SEND),
+ KEY(2, 1, KEY_END),
+ KEY(3, 1, KEY_VOLUMEDOWN),
+ KEY(4, 1, KEY_VOLUMEUP),
+ KEY(5, 1, KEY_RECORD),
+ KEY(0, 2, KEY_F9),
+ KEY(1, 2, KEY_3),
+ KEY(2, 2, KEY_6),
+ KEY(3, 2, KEY_9),
+ KEY(4, 2, KEY_KPDOT),
+ KEY(0, 3, KEY_BACK),
+ KEY(1, 3, KEY_2),
+ KEY(2, 3, KEY_5),
+ KEY(3, 3, KEY_8),
+ KEY(4, 3, KEY_0),
+ KEY(5, 3, KEY_KPSLASH),
+ KEY(0, 4, KEY_HOME),
+ KEY(1, 4, KEY_1),
+ KEY(2, 4, KEY_4),
+ KEY(3, 4, KEY_7),
+ KEY(4, 4, KEY_KPASTERISK),
+ KEY(5, 4, KEY_POWER),
};
static struct smc91x_platdata smc91x_info = {
@@ -120,6 +119,15 @@ static struct resource smc91x_resources[] = {
},
};
+static void __init fsample_init_smc91x(void)
+{
+ fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+ H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+}
+
static struct mtd_partition nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -244,11 +252,15 @@ static struct resource kp_resources[] = {
},
};
+static const struct matrix_keymap_data fsample_keymap_data = {
+ .keymap = fsample_keymap,
+ .keymap_size = ARRAY_SIZE(fsample_keymap),
+};
+
static struct omap_kp_platform_data kp_data = {
.rows = 8,
.cols = 8,
- .keymap = fsample_keymap,
- .keymapsize = ARRAY_SIZE(fsample_keymap),
+ .keymap_data = &fsample_keymap_data,
.delay = 4,
};
@@ -285,6 +297,8 @@ static struct omap_board_config_kernel fsample_config[] = {
static void __init omap_fsample_init(void)
{
+ fsample_init_smc91x();
+
if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0)
BUG();
gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN);
@@ -312,21 +326,10 @@ static void __init omap_fsample_init(void)
omap_register_i2c_bus(1, 100, NULL, 0);
}
-static void __init fsample_init_smc91x(void)
-{
- fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
- mdelay(50);
- fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
- H2P2_DBG_FPGA_LAN_RESET);
- mdelay(50);
-}
-
static void __init omap_fsample_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
- fsample_init_smc91x();
}
/* Only FPGA needs to be mapped here. All others are done with ioremap */
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 197adb49dc5a..28b84aa9bdba 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -52,43 +52,42 @@
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define OMAP1610_ETHR_START 0x04000300
-static int h2_keymap[] = {
+static const unsigned int h2_keymap[] = {
KEY(0, 0, KEY_LEFT),
- KEY(0, 1, KEY_RIGHT),
- KEY(0, 2, KEY_3),
- KEY(0, 3, KEY_F10),
- KEY(0, 4, KEY_F5),
- KEY(0, 5, KEY_9),
- KEY(1, 0, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_3),
+ KEY(3, 0, KEY_F10),
+ KEY(4, 0, KEY_F5),
+ KEY(5, 0, KEY_9),
+ KEY(0, 1, KEY_DOWN),
KEY(1, 1, KEY_UP),
- KEY(1, 2, KEY_2),
- KEY(1, 3, KEY_F9),
- KEY(1, 4, KEY_F7),
- KEY(1, 5, KEY_0),
- KEY(2, 0, KEY_ENTER),
- KEY(2, 1, KEY_6),
+ KEY(2, 1, KEY_2),
+ KEY(3, 1, KEY_F9),
+ KEY(4, 1, KEY_F7),
+ KEY(5, 1, KEY_0),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_6),
KEY(2, 2, KEY_1),
- KEY(2, 3, KEY_F2),
- KEY(2, 4, KEY_F6),
- KEY(2, 5, KEY_HOME),
- KEY(3, 0, KEY_8),
- KEY(3, 1, KEY_5),
- KEY(3, 2, KEY_F12),
+ KEY(3, 2, KEY_F2),
+ KEY(4, 2, KEY_F6),
+ KEY(5, 2, KEY_HOME),
+ KEY(0, 3, KEY_8),
+ KEY(1, 3, KEY_5),
+ KEY(2, 3, KEY_F12),
KEY(3, 3, KEY_F3),
- KEY(3, 4, KEY_F8),
- KEY(3, 5, KEY_END),
- KEY(4, 0, KEY_7),
- KEY(4, 1, KEY_4),
- KEY(4, 2, KEY_F11),
- KEY(4, 3, KEY_F1),
+ KEY(4, 3, KEY_F8),
+ KEY(5, 3, KEY_END),
+ KEY(0, 4, KEY_7),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_F11),
+ KEY(3, 4, KEY_F1),
KEY(4, 4, KEY_F4),
- KEY(4, 5, KEY_ESC),
- KEY(5, 0, KEY_F13),
- KEY(5, 1, KEY_F14),
- KEY(5, 2, KEY_F15),
- KEY(5, 3, KEY_F16),
- KEY(5, 4, KEY_SLEEP),
- 0
+ KEY(5, 4, KEY_ESC),
+ KEY(0, 5, KEY_F13),
+ KEY(1, 5, KEY_F14),
+ KEY(2, 5, KEY_F15),
+ KEY(3, 5, KEY_F16),
+ KEY(4, 5, KEY_SLEEP),
};
static struct mtd_partition h2_nor_partitions[] = {
@@ -270,14 +269,18 @@ static struct resource h2_kp_resources[] = {
},
};
+static const struct matrix_keymap_data h2_keymap_data = {
+ .keymap = h2_keymap,
+ .keymap_size = ARRAY_SIZE(h2_keymap),
+};
+
static struct omap_kp_platform_data h2_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = h2_keymap,
- .keymapsize = ARRAY_SIZE(h2_keymap),
- .rep = 1,
+ .keymap_data = &h2_keymap_data,
+ .rep = true,
.delay = 9,
- .dbounce = 1,
+ .dbounce = true,
};
static struct platform_device h2_kp_device = {
@@ -374,8 +377,6 @@ static void __init h2_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
- h2_init_smc91x();
}
static struct omap_usb_config h2_usb_config __initdata = {
@@ -403,6 +404,8 @@ static struct omap_board_config_kernel h2_config[] __initdata = {
static void __init h2_init(void)
{
+ h2_init_smc91x();
+
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
* notice whether a NAND chip is enabled at probe time.
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 9126e3e37b4a..dbc8b8d882ba 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -56,43 +56,42 @@
#define H3_TS_GPIO 48
-static int h3_keymap[] = {
+static const unsigned int h3_keymap[] = {
KEY(0, 0, KEY_LEFT),
- KEY(0, 1, KEY_RIGHT),
- KEY(0, 2, KEY_3),
- KEY(0, 3, KEY_F10),
- KEY(0, 4, KEY_F5),
- KEY(0, 5, KEY_9),
- KEY(1, 0, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_3),
+ KEY(3, 0, KEY_F10),
+ KEY(4, 0, KEY_F5),
+ KEY(5, 0, KEY_9),
+ KEY(0, 1, KEY_DOWN),
KEY(1, 1, KEY_UP),
- KEY(1, 2, KEY_2),
- KEY(1, 3, KEY_F9),
- KEY(1, 4, KEY_F7),
- KEY(1, 5, KEY_0),
- KEY(2, 0, KEY_ENTER),
- KEY(2, 1, KEY_6),
+ KEY(2, 1, KEY_2),
+ KEY(3, 1, KEY_F9),
+ KEY(4, 1, KEY_F7),
+ KEY(5, 1, KEY_0),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_6),
KEY(2, 2, KEY_1),
- KEY(2, 3, KEY_F2),
- KEY(2, 4, KEY_F6),
- KEY(2, 5, KEY_HOME),
- KEY(3, 0, KEY_8),
- KEY(3, 1, KEY_5),
- KEY(3, 2, KEY_F12),
+ KEY(3, 2, KEY_F2),
+ KEY(4, 2, KEY_F6),
+ KEY(5, 2, KEY_HOME),
+ KEY(0, 3, KEY_8),
+ KEY(1, 3, KEY_5),
+ KEY(2, 3, KEY_F12),
KEY(3, 3, KEY_F3),
- KEY(3, 4, KEY_F8),
- KEY(3, 5, KEY_END),
- KEY(4, 0, KEY_7),
- KEY(4, 1, KEY_4),
- KEY(4, 2, KEY_F11),
- KEY(4, 3, KEY_F1),
+ KEY(4, 3, KEY_F8),
+ KEY(5, 3, KEY_END),
+ KEY(0, 4, KEY_7),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_F11),
+ KEY(3, 4, KEY_F1),
KEY(4, 4, KEY_F4),
- KEY(4, 5, KEY_ESC),
- KEY(5, 0, KEY_F13),
- KEY(5, 1, KEY_F14),
- KEY(5, 2, KEY_F15),
- KEY(5, 3, KEY_F16),
- KEY(5, 4, KEY_SLEEP),
- 0
+ KEY(5, 4, KEY_ESC),
+ KEY(0, 5, KEY_F13),
+ KEY(1, 5, KEY_F14),
+ KEY(2, 5, KEY_F15),
+ KEY(3, 5, KEY_F16),
+ KEY(4, 5, KEY_SLEEP),
};
@@ -264,6 +263,15 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
+static void __init h3_init_smc91x(void)
+{
+ omap_cfg_reg(W15_1710_GPIO40);
+ if (gpio_request(40, "SMC91x irq") < 0) {
+ printk("Error requesting gpio 40 for smc91x irq\n");
+ return;
+ }
+}
+
#define GPTIMER_BASE 0xFFFB1400
#define GPTIMER_REGS(x) (0xFFFB1400 + (x * 0x800))
#define GPTIMER_REGS_SIZE 0x46
@@ -296,14 +304,18 @@ static struct resource h3_kp_resources[] = {
},
};
+static const struct matrix_keymap_data h3_keymap_data = {
+ .keymap = h3_keymap,
+ .keymap_size = ARRAY_SIZE(h3_keymap),
+};
+
static struct omap_kp_platform_data h3_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = h3_keymap,
- .keymapsize = ARRAY_SIZE(h3_keymap),
- .rep = 1,
+ .keymap_data = &h3_keymap_data,
+ .rep = true,
.delay = 9,
- .dbounce = 1,
+ .dbounce = true,
};
static struct platform_device h3_kp_device = {
@@ -376,6 +388,8 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = {
static void __init h3_init(void)
{
+ h3_init_smc91x();
+
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
* notice whether a NAND chip is enabled at probe time.
@@ -422,21 +436,10 @@ static void __init h3_init(void)
h3_mmc_init();
}
-static void __init h3_init_smc91x(void)
-{
- omap_cfg_reg(W15_1710_GPIO40);
- if (gpio_request(40, "SMC91x irq") < 0) {
- printk("Error requesting gpio 40 for smc91x irq\n");
- return;
- }
-}
-
static void __init h3_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
- h3_init_smc91x();
}
static void __init h3_map_io(void)
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 071af3e47789..f2c5c585bc83 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -180,64 +180,68 @@
/* Keyboard definition */
-static int htc_herald_keymap[] = {
+static const unsigned int htc_herald_keymap[] = {
KEY(0, 0, KEY_RECORD), /* Mail button */
- KEY(0, 1, KEY_CAMERA), /* Camera */
- KEY(0, 2, KEY_PHONE), /* Send key */
- KEY(0, 3, KEY_VOLUMEUP), /* Volume up */
- KEY(0, 4, KEY_F2), /* Right bar (landscape) */
- KEY(0, 5, KEY_MAIL), /* Win key (portrait) */
- KEY(0, 6, KEY_DIRECTORY), /* Right bar (protrait) */
- KEY(1, 0, KEY_LEFTCTRL), /* Windows key */
+ KEY(1, 0, KEY_CAMERA), /* Camera */
+ KEY(2, 0, KEY_PHONE), /* Send key */
+ KEY(3, 0, KEY_VOLUMEUP), /* Volume up */
+ KEY(4, 0, KEY_F2), /* Right bar (landscape) */
+ KEY(5, 0, KEY_MAIL), /* Win key (portrait) */
+ KEY(6, 0, KEY_DIRECTORY), /* Right bar (protrait) */
+ KEY(0, 1, KEY_LEFTCTRL), /* Windows key */
KEY(1, 1, KEY_COMMA),
- KEY(1, 2, KEY_M),
- KEY(1, 3, KEY_K),
- KEY(1, 4, KEY_SLASH), /* OK key */
- KEY(1, 5, KEY_I),
- KEY(1, 6, KEY_U),
- KEY(2, 0, KEY_LEFTALT),
- KEY(2, 1, KEY_TAB),
+ KEY(2, 1, KEY_M),
+ KEY(3, 1, KEY_K),
+ KEY(4, 1, KEY_SLASH), /* OK key */
+ KEY(5, 1, KEY_I),
+ KEY(6, 1, KEY_U),
+ KEY(0, 2, KEY_LEFTALT),
+ KEY(1, 2, KEY_TAB),
KEY(2, 2, KEY_N),
- KEY(2, 3, KEY_J),
- KEY(2, 4, KEY_ENTER),
- KEY(2, 5, KEY_H),
- KEY(2, 6, KEY_Y),
- KEY(3, 0, KEY_SPACE),
- KEY(3, 1, KEY_L),
- KEY(3, 2, KEY_B),
+ KEY(3, 2, KEY_J),
+ KEY(4, 2, KEY_ENTER),
+ KEY(5, 2, KEY_H),
+ KEY(6, 2, KEY_Y),
+ KEY(0, 3, KEY_SPACE),
+ KEY(1, 3, KEY_L),
+ KEY(2, 3, KEY_B),
KEY(3, 3, KEY_V),
- KEY(3, 4, KEY_BACKSPACE),
- KEY(3, 5, KEY_G),
- KEY(3, 6, KEY_T),
- KEY(4, 0, KEY_CAPSLOCK), /* Shift */
- KEY(4, 1, KEY_C),
- KEY(4, 2, KEY_F),
- KEY(4, 3, KEY_R),
+ KEY(4, 3, KEY_BACKSPACE),
+ KEY(5, 3, KEY_G),
+ KEY(6, 3, KEY_T),
+ KEY(0, 4, KEY_CAPSLOCK), /* Shift */
+ KEY(1, 4, KEY_C),
+ KEY(2, 4, KEY_F),
+ KEY(3, 4, KEY_R),
KEY(4, 4, KEY_O),
- KEY(4, 5, KEY_E),
- KEY(4, 6, KEY_D),
- KEY(5, 0, KEY_X),
- KEY(5, 1, KEY_Z),
- KEY(5, 2, KEY_S),
- KEY(5, 3, KEY_W),
- KEY(5, 4, KEY_P),
+ KEY(5, 4, KEY_E),
+ KEY(6, 4, KEY_D),
+ KEY(0, 5, KEY_X),
+ KEY(1, 5, KEY_Z),
+ KEY(2, 5, KEY_S),
+ KEY(3, 5, KEY_W),
+ KEY(4, 5, KEY_P),
KEY(5, 5, KEY_Q),
- KEY(5, 6, KEY_A),
- KEY(6, 0, KEY_CONNECT), /* Voice button */
- KEY(6, 2, KEY_CANCEL), /* End key */
- KEY(6, 3, KEY_VOLUMEDOWN), /* Volume down */
- KEY(6, 4, KEY_F1), /* Left bar (landscape) */
- KEY(6, 5, KEY_WWW), /* OK button (portrait) */
+ KEY(6, 5, KEY_A),
+ KEY(0, 6, KEY_CONNECT), /* Voice button */
+ KEY(2, 6, KEY_CANCEL), /* End key */
+ KEY(3, 6, KEY_VOLUMEDOWN), /* Volume down */
+ KEY(4, 6, KEY_F1), /* Left bar (landscape) */
+ KEY(5, 6, KEY_WWW), /* OK button (portrait) */
KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
- 0
};
-struct omap_kp_platform_data htcherald_kp_data = {
+static const struct matrix_keymap_data htc_herald_keymap_data = {
+ .keymap = htc_herald_keymap,
+ .keymap_size = ARRAY_SIZE(htc_herald_keymap),
+};
+
+static struct omap_kp_platform_data htcherald_kp_data = {
.rows = 7,
.cols = 7,
.delay = 20,
- .rep = 1,
- .keymap = htc_herald_keymap,
+ .rep = true,
+ .keymap_data = &htc_herald_keymap_data,
};
static struct resource kp_resources[] = {
@@ -278,7 +282,7 @@ static struct gpio_keys_button herald_gpio_keys_table[] = {
static struct gpio_keys_platform_data herald_gpio_keys_data = {
.buttons = herald_gpio_keys_table,
.nbuttons = ARRAY_SIZE(herald_gpio_keys_table),
- .rep = 1,
+ .rep = true,
};
static struct platform_device herald_gpiokeys_device = {
@@ -439,7 +443,7 @@ static const struct ads7846_platform_data htcherald_ts_platform_data = {
.keep_vref_on = 1,
.x_plate_ohms = 496,
.gpio_pendown = HTCHERALD_GPIO_TS,
- .pressure_max = 100000,
+ .pressure_max = 10000,
.pressure_min = 5000,
.x_min = 528,
.x_max = 3760,
@@ -577,8 +581,6 @@ static void __init htcherald_init(void)
printk(KERN_INFO "HTC Herald init.\n");
/* Do board initialization before we register all the devices */
- omap_gpio_init();
-
omap_board_config = htcherald_config;
omap_board_config_size = ARRAY_SIZE(htcherald_config);
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index dc2b86fd66c1..a36e6742bf9b 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -44,17 +44,16 @@
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define INNOVATOR1610_ETHR_START 0x04000300
-static int innovator_keymap[] = {
+static const unsigned int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
- KEY(0, 3, KEY_DOWN),
+ KEY(3, 0, KEY_DOWN),
KEY(1, 1, KEY_F2),
- KEY(1, 2, KEY_RIGHT),
- KEY(2, 0, KEY_F3),
- KEY(2, 1, KEY_F4),
+ KEY(2, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_F3),
+ KEY(1, 2, KEY_F4),
KEY(2, 2, KEY_UP),
- KEY(3, 2, KEY_ENTER),
+ KEY(2, 3, KEY_ENTER),
KEY(3, 3, KEY_LEFT),
- 0
};
static struct mtd_partition innovator_partitions[] = {
@@ -126,11 +125,15 @@ static struct resource innovator_kp_resources[] = {
},
};
+static const struct matrix_keymap_data innovator_keymap_data = {
+ .keymap = innovator_keymap,
+ .keymap_size = ARRAY_SIZE(innovator_keymap),
+};
+
static struct omap_kp_platform_data innovator_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = innovator_keymap,
- .keymapsize = ARRAY_SIZE(innovator_keymap),
+ .keymap_data = &innovator_keymap_data,
.delay = 4,
};
@@ -290,13 +293,6 @@ static void __init innovator_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
-#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap1510()) {
- omap1510_fpga_init_irq();
- }
-#endif
- innovator_init_smc91x();
}
#ifdef CONFIG_ARCH_OMAP15XX
@@ -387,6 +383,10 @@ static struct omap_board_config_kernel innovator_config[] = {
static void __init innovator_init(void)
{
+ if (cpu_is_omap1510())
+ omap1510_fpga_init_irq();
+ innovator_init_smc91x();
+
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
unsigned char reg;
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index aa8375b2a0a3..d21f09dc78f4 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -54,19 +54,18 @@ static void __init omap_nokia770_init_irq(void)
omap_init_irq();
}
-static int nokia770_keymap[] = {
- KEY(0, 1, GROUP_0 | KEY_UP),
- KEY(0, 2, GROUP_1 | KEY_F5),
- KEY(1, 0, GROUP_0 | KEY_LEFT),
+static const unsigned int nokia770_keymap[] = {
+ KEY(1, 0, GROUP_0 | KEY_UP),
+ KEY(2, 0, GROUP_1 | KEY_F5),
+ KEY(0, 1, GROUP_0 | KEY_LEFT),
KEY(1, 1, GROUP_0 | KEY_ENTER),
- KEY(1, 2, GROUP_0 | KEY_RIGHT),
- KEY(2, 0, GROUP_1 | KEY_ESC),
- KEY(2, 1, GROUP_0 | KEY_DOWN),
+ KEY(2, 1, GROUP_0 | KEY_RIGHT),
+ KEY(0, 2, GROUP_1 | KEY_ESC),
+ KEY(1, 2, GROUP_0 | KEY_DOWN),
KEY(2, 2, GROUP_1 | KEY_F4),
- KEY(3, 0, GROUP_2 | KEY_F7),
- KEY(3, 1, GROUP_2 | KEY_F8),
- KEY(3, 2, GROUP_2 | KEY_F6),
- 0
+ KEY(0, 3, GROUP_2 | KEY_F7),
+ KEY(1, 3, GROUP_2 | KEY_F8),
+ KEY(2, 3, GROUP_2 | KEY_F6),
};
static struct resource nokia770_kp_resources[] = {
@@ -77,11 +76,15 @@ static struct resource nokia770_kp_resources[] = {
},
};
+static const struct matrix_keymap_data nokia770_keymap_data = {
+ .keymap = nokia770_keymap,
+ .keymap_size = ARRAY_SIZE(nokia770_keymap),
+};
+
static struct omap_kp_platform_data nokia770_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = nokia770_keymap,
- .keymapsize = ARRAY_SIZE(nokia770_keymap),
+ .keymap_data = &nokia770_keymap_data,
.delay = 4,
};
@@ -246,7 +249,6 @@ static void __init omap_nokia770_init(void)
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
spi_register_board_info(nokia770_spi_board_info,
ARRAY_SIZE(nokia770_spi_board_info));
- omap_gpio_init();
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
hwa742_dev_init();
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index e9dd79149a8e..7c5e2112c776 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -283,9 +283,6 @@ static void __init osk_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
- osk_init_smc91x();
- osk_init_cf();
}
static struct omap_usb_config osk_usb_config __initdata = {
@@ -341,25 +338,28 @@ static struct i2c_board_info __initdata mistral_i2c_board_info[] = {
*/
};
-static const int osk_keymap[] = {
+static const unsigned int osk_keymap[] = {
/* KEY(col, row, code) */
KEY(0, 0, KEY_F1), /* SW4 */
- KEY(0, 3, KEY_UP), /* (sw2/up) */
+ KEY(3, 0, KEY_UP), /* (sw2/up) */
KEY(1, 1, KEY_LEFTCTRL), /* SW5 */
- KEY(1, 2, KEY_LEFT), /* (sw2/left) */
- KEY(2, 0, KEY_SPACE), /* SW3 */
- KEY(2, 1, KEY_ESC), /* SW6 */
+ KEY(2, 1, KEY_LEFT), /* (sw2/left) */
+ KEY(0, 2, KEY_SPACE), /* SW3 */
+ KEY(1, 2, KEY_ESC), /* SW6 */
KEY(2, 2, KEY_DOWN), /* (sw2/down) */
- KEY(3, 2, KEY_ENTER), /* (sw2/select) */
+ KEY(2, 3, KEY_ENTER), /* (sw2/select) */
KEY(3, 3, KEY_RIGHT), /* (sw2/right) */
- 0
+};
+
+static const struct matrix_keymap_data osk_keymap_data = {
+ .keymap = osk_keymap,
+ .keymap_size = ARRAY_SIZE(osk_keymap),
};
static struct omap_kp_platform_data osk_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = (int *) osk_keymap,
- .keymapsize = ARRAY_SIZE(osk_keymap),
+ .keymap_data = &osk_keymap_data,
.delay = 9,
};
@@ -541,6 +541,9 @@ static void __init osk_init(void)
{
u32 l;
+ osk_init_smc91x();
+ osk_init_cf();
+
/* Workaround for wrong CS3 (NOR flash) timing
* There are some U-Boot versions out there which configure
* wrong CS3 memory timings. This mainly leads to CRC
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index f32738b1eb6b..fb51ce6123d8 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -63,28 +63,31 @@ static void __init omap_palmte_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
}
-static const int palmte_keymap[] = {
+static const unsigned int palmte_keymap[] = {
KEY(0, 0, KEY_F1), /* Calendar */
- KEY(0, 1, KEY_F2), /* Contacts */
- KEY(0, 2, KEY_F3), /* Tasks List */
- KEY(0, 3, KEY_F4), /* Note Pad */
- KEY(0, 4, KEY_POWER),
- KEY(1, 0, KEY_LEFT),
+ KEY(1, 0, KEY_F2), /* Contacts */
+ KEY(2, 0, KEY_F3), /* Tasks List */
+ KEY(3, 0, KEY_F4), /* Note Pad */
+ KEY(4, 0, KEY_POWER),
+ KEY(0, 1, KEY_LEFT),
KEY(1, 1, KEY_DOWN),
- KEY(1, 2, KEY_UP),
- KEY(1, 3, KEY_RIGHT),
- KEY(1, 4, KEY_ENTER),
- 0,
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(4, 1, KEY_ENTER),
+};
+
+static const struct matrix_keymap_data palmte_keymap_data = {
+ .keymap = palmte_keymap,
+ .keymap_size = ARRAY_SIZE(palmte_keymap),
};
static struct omap_kp_platform_data palmte_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = (int *) palmte_keymap,
- .rep = 1,
+ .keymap_data = &palmte_keymap_data,
+ .rep = true,
.delay = 12,
};
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index ed1400a67f75..f04f2d36e7d3 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -51,19 +51,18 @@
#define PALMTT_MMC_WP_GPIO 8
#define PALMTT_HDQ_GPIO 11
-static int palmtt_keymap[] = {
+static const unsigned int palmtt_keymap[] = {
KEY(0, 0, KEY_ESC),
- KEY(0, 1, KEY_SPACE),
- KEY(0, 2, KEY_LEFTCTRL),
- KEY(0, 3, KEY_TAB),
- KEY(0, 4, KEY_ENTER),
- KEY(1, 0, KEY_LEFT),
+ KEY(1, 0, KEY_SPACE),
+ KEY(2, 0, KEY_LEFTCTRL),
+ KEY(3, 0, KEY_TAB),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_LEFT),
KEY(1, 1, KEY_DOWN),
- KEY(1, 2, KEY_UP),
- KEY(1, 3, KEY_RIGHT),
- KEY(2, 0, KEY_SLEEP),
- KEY(2, 4, KEY_Y),
- 0
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_SLEEP),
+ KEY(4, 2, KEY_Y),
};
static struct mtd_partition palmtt_partitions[] = {
@@ -136,10 +135,15 @@ static struct resource palmtt_kp_resources[] = {
},
};
+static const struct matrix_keymap_data palmtt_keymap_data = {
+ .keymap = palmtt_keymap,
+ .keymap_size = ARRAY_SIZE(palmtt_keymap),
+};
+
static struct omap_kp_platform_data palmtt_kp_data = {
.rows = 6,
.cols = 3,
- .keymap = palmtt_keymap,
+ .keymap_data = &palmtt_keymap_data,
};
static struct platform_device palmtt_kp_device = {
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index d7a245cef9a4..d7bbbe721a75 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -62,29 +62,32 @@ omap_palmz71_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
}
-static int palmz71_keymap[] = {
+static const unsigned int palmz71_keymap[] = {
KEY(0, 0, KEY_F1),
- KEY(0, 1, KEY_F2),
- KEY(0, 2, KEY_F3),
- KEY(0, 3, KEY_F4),
- KEY(0, 4, KEY_POWER),
- KEY(1, 0, KEY_LEFT),
+ KEY(1, 0, KEY_F2),
+ KEY(2, 0, KEY_F3),
+ KEY(3, 0, KEY_F4),
+ KEY(4, 0, KEY_POWER),
+ KEY(0, 1, KEY_LEFT),
KEY(1, 1, KEY_DOWN),
- KEY(1, 2, KEY_UP),
- KEY(1, 3, KEY_RIGHT),
- KEY(1, 4, KEY_ENTER),
- KEY(2, 0, KEY_CAMERA),
- 0,
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(4, 1, KEY_ENTER),
+ KEY(0, 2, KEY_CAMERA),
+};
+
+static const struct matrix_keymap_data palmz71_keymap_data = {
+ .keymap = palmz71_keymap,
+ .keymap_size = ARRAY_SIZE(palmz71_keymap),
};
static struct omap_kp_platform_data palmz71_kp_data = {
.rows = 8,
.cols = 8,
- .keymap = palmz71_keymap,
- .rep = 1,
+ .keymap_data = &palmz71_keymap_data,
+ .rep = true,
.delay = 80,
};
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index a8d16a255c18..3c8ee8489458 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -36,36 +36,35 @@
#include <plat/common.h>
#include <plat/board.h>
-static int p2_keymap[] = {
- KEY(0,0,KEY_UP),
- KEY(0,1,KEY_RIGHT),
- KEY(0,2,KEY_LEFT),
- KEY(0,3,KEY_DOWN),
- KEY(0,4,KEY_ENTER),
- KEY(1,0,KEY_F10),
- KEY(1,1,KEY_SEND),
- KEY(1,2,KEY_END),
- KEY(1,3,KEY_VOLUMEDOWN),
- KEY(1,4,KEY_VOLUMEUP),
- KEY(1,5,KEY_RECORD),
- KEY(2,0,KEY_F9),
- KEY(2,1,KEY_3),
- KEY(2,2,KEY_6),
- KEY(2,3,KEY_9),
- KEY(2,4,KEY_KPDOT),
- KEY(3,0,KEY_BACK),
- KEY(3,1,KEY_2),
- KEY(3,2,KEY_5),
- KEY(3,3,KEY_8),
- KEY(3,4,KEY_0),
- KEY(3,5,KEY_KPSLASH),
- KEY(4,0,KEY_HOME),
- KEY(4,1,KEY_1),
- KEY(4,2,KEY_4),
- KEY(4,3,KEY_7),
- KEY(4,4,KEY_KPASTERISK),
- KEY(4,5,KEY_POWER),
- 0
+static const unsigned int p2_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_LEFT),
+ KEY(3, 0, KEY_DOWN),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_F10),
+ KEY(1, 1, KEY_SEND),
+ KEY(2, 1, KEY_END),
+ KEY(3, 1, KEY_VOLUMEDOWN),
+ KEY(4, 1, KEY_VOLUMEUP),
+ KEY(5, 1, KEY_RECORD),
+ KEY(0, 2, KEY_F9),
+ KEY(1, 2, KEY_3),
+ KEY(2, 2, KEY_6),
+ KEY(3, 2, KEY_9),
+ KEY(4, 2, KEY_KPDOT),
+ KEY(0, 3, KEY_BACK),
+ KEY(1, 3, KEY_2),
+ KEY(2, 3, KEY_5),
+ KEY(3, 3, KEY_8),
+ KEY(4, 3, KEY_0),
+ KEY(5, 3, KEY_KPSLASH),
+ KEY(0, 4, KEY_HOME),
+ KEY(1, 4, KEY_1),
+ KEY(2, 4, KEY_4),
+ KEY(3, 4, KEY_7),
+ KEY(4, 4, KEY_KPASTERISK),
+ KEY(5, 4, KEY_POWER),
};
static struct smc91x_platdata smc91x_info = {
@@ -211,13 +210,17 @@ static struct resource kp_resources[] = {
},
};
+static const struct matrix_keymap_data p2_keymap_data = {
+ .keymap = p2_keymap,
+ .keymap_size = ARRAY_SIZE(p2_keymap),
+};
+
static struct omap_kp_platform_data kp_data = {
.rows = 8,
.cols = 8,
- .keymap = p2_keymap,
- .keymapsize = ARRAY_SIZE(p2_keymap),
+ .keymap_data = &p2_keymap_data,
.delay = 4,
- .dbounce = 1,
+ .dbounce = true,
};
static struct platform_device kp_device = {
@@ -251,8 +254,19 @@ static struct omap_board_config_kernel perseus2_config[] __initdata = {
{ OMAP_TAG_LCD, &perseus2_lcd_config },
};
+static void __init perseus2_init_smc91x(void)
+{
+ fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+ H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+}
+
static void __init omap_perseus2_init(void)
{
+ perseus2_init_smc91x();
+
if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
BUG();
gpio_direction_input(P2_NAND_RB_GPIO_PIN);
@@ -280,21 +294,10 @@ static void __init omap_perseus2_init(void)
omap_register_i2c_bus(1, 100, NULL, 0);
}
-static void __init perseus2_init_smc91x(void)
-{
- fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
- mdelay(50);
- fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
- H2P2_DBG_FPGA_LAN_RESET);
- mdelay(50);
-}
-
static void __init omap_perseus2_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
- perseus2_init_smc91x();
}
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_perseus2_io_desc[] __initdata = {
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index d25f59e5a773..d41fe2d0616a 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -164,36 +164,35 @@ EXPORT_SYMBOL(sx1_setusbpower);
/*----------- Keypad -------------------------*/
-static int sx1_keymap[] = {
- KEY(5, 3, GROUP_0 | 117), /* camera Qt::Key_F17 */
- KEY(0, 4, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
- KEY(1, 4, GROUP_2 | 114), /* voice memo */
- KEY(2, 4, GROUP_3 | 114), /* voice memo */
+static const unsigned int sx1_keymap[] = {
+ KEY(3, 5, GROUP_0 | 117), /* camera Qt::Key_F17 */
+ KEY(4, 0, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
+ KEY(4, 1, GROUP_2 | 114), /* voice memo */
+ KEY(4, 2, GROUP_3 | 114), /* voice memo */
KEY(0, 0, GROUP_1 | KEY_F12), /* red button Qt::Key_Hangup */
- KEY(4, 3, GROUP_1 | KEY_LEFT),
- KEY(2, 3, GROUP_1 | KEY_DOWN),
- KEY(1, 3, GROUP_1 | KEY_RIGHT),
- KEY(0, 3, GROUP_1 | KEY_UP),
+ KEY(3, 4, GROUP_1 | KEY_LEFT),
+ KEY(3, 2, GROUP_1 | KEY_DOWN),
+ KEY(3, 1, GROUP_1 | KEY_RIGHT),
+ KEY(3, 0, GROUP_1 | KEY_UP),
KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
- KEY(5, 0, GROUP_1 | KEY_1),
- KEY(4, 0, GROUP_1 | KEY_2),
- KEY(3, 0, GROUP_1 | KEY_3),
- KEY(3, 4, GROUP_1 | KEY_4),
+ KEY(0, 5, GROUP_1 | KEY_1),
+ KEY(0, 4, GROUP_1 | KEY_2),
+ KEY(0, 3, GROUP_1 | KEY_3),
+ KEY(4, 3, GROUP_1 | KEY_4),
KEY(4, 4, GROUP_1 | KEY_5),
- KEY(5, 4, GROUP_1 | KEY_KPASTERISK),/* "*" */
- KEY(4, 1, GROUP_1 | KEY_6),
- KEY(5, 1, GROUP_1 | KEY_7),
- KEY(3, 1, GROUP_1 | KEY_8),
- KEY(3, 2, GROUP_1 | KEY_9),
- KEY(5, 2, GROUP_1 | KEY_0),
- KEY(4, 2, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
- KEY(0, 1, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */
- KEY(1, 2, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */
+ KEY(4, 5, GROUP_1 | KEY_KPASTERISK),/* "*" */
+ KEY(1, 4, GROUP_1 | KEY_6),
+ KEY(1, 5, GROUP_1 | KEY_7),
+ KEY(1, 3, GROUP_1 | KEY_8),
+ KEY(2, 3, GROUP_1 | KEY_9),
+ KEY(2, 5, GROUP_1 | KEY_0),
+ KEY(2, 4, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
+ KEY(1, 0, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */
+ KEY(2, 1, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */
KEY(2, 2, GROUP_1 | KEY_F8), /* right soft Qt::Key_Back */
- KEY(2, 1, GROUP_1 | KEY_LEFTSHIFT), /* shift */
+ KEY(1, 2, GROUP_1 | KEY_LEFTSHIFT), /* shift */
KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
- KEY(0, 2, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */
- 0
+ KEY(2, 0, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */
};
static struct resource sx1_kp_resources[] = {
@@ -204,11 +203,15 @@ static struct resource sx1_kp_resources[] = {
},
};
+static const struct matrix_keymap_data sx1_keymap_data = {
+ .keymap = sx1_keymap,
+ .keymap_size = ARRAY_SIZE(sx1_keymap),
+};
+
static struct omap_kp_platform_data sx1_kp_data = {
.rows = 6,
.cols = 6,
- .keymap = sx1_keymap,
- .keymapsize = ARRAY_SIZE(sx1_keymap),
+ .keymap_data = &sx1_keymap_data,
.delay = 80,
};
@@ -409,7 +412,6 @@ static void __init omap_sx1_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
}
/*----------------------------------------*/
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index f5992c239bcd..815a69ce821d 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -83,6 +83,9 @@ static struct platform_device serial_device = {
static int __init ext_uart_init(void)
{
+ if (!machine_is_voiceblue())
+ return -ENODEV;
+
return platform_device_register(&serial_device);
}
arch_initcall(ext_uart_init);
@@ -158,7 +161,6 @@ static void __init voiceblue_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
- omap_gpio_init();
}
static void __init voiceblue_init(void)
@@ -236,6 +238,9 @@ static struct notifier_block panic_block = {
static int __init voiceblue_setup(void)
{
+ if (!machine_is_voiceblue())
+ return -ENODEV;
+
/* Setup panic notifier */
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index b8c7fb9d7921..84ef70476b51 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -17,9 +17,9 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
#include <asm/mach-types.h>
-#include <asm/clkdev.h>
#include <plat/cpu.h>
#include <plat/usb.h>
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
index af54114b8f08..92400b9eb69f 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -143,7 +143,7 @@ static struct arm_idlect1_clk armper_ck = {
* activation. [ GPIO code for 1510 ]
*/
static struct clk arm_gpio_ck = {
- .name = "arm_gpio_ck",
+ .name = "ick",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = ENABLE_ON_INIT,
@@ -684,7 +684,7 @@ static struct omap_clk omap_clks[] = {
CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX),
CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
- CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310),
+ CLK("omap_gpio.0", "ick", &arm_gpio_ck, CK_1510 | CK_310),
CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310),
@@ -736,9 +736,9 @@ static struct omap_clk omap_clks[] = {
CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX),
/* Virtual clocks */
CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
- CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX),
- CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX),
- CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX),
+ CLK("omap_i2c.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK("omap_i2c.1", "ick", &i2c_ick, CK_16XX),
+ CLK("omap_i2c.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX),
CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX),
CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX),
CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX),
@@ -823,12 +823,10 @@ int __init omap1_clk_init(void)
crystal_type = info->system_clock_type;
}
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
- ck_ref.rate = 13000000;
-#elif defined(CONFIG_ARCH_OMAP16XX)
- if (crystal_type == 2)
+ if (cpu_is_omap7xx())
+ ck_ref.rate = 13000000;
+ if (cpu_is_omap16xx() && crystal_type == 2)
ck_ref.rate = 19200000;
-#endif
pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: "
"0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
@@ -883,10 +881,11 @@ int __init omap1_clk_init(void)
ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
-#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
- /* Select slicer output as OMAP input clock */
- omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, OMAP7XX_PCC_UPLD_CTRL);
-#endif
+ if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
+ /* Select slicer output as OMAP input clock */
+ omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
+ OMAP7XX_PCC_UPLD_CTRL);
+ }
/* Amstrad Delta wants BCLK high when inactive */
if (machine_is_ams_delta())
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index e7f9ee63dce5..b0f4c231595f 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/spi/spi.h>
+#include <mach/camera.h>
#include <mach/hardware.h>
#include <asm/mach/map.h>
@@ -287,6 +288,9 @@ static inline void omap_init_audio(void) {}
*/
static int __init omap1_init_devices(void)
{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
new file mode 100644
index 000000000000..d8559344c6e2
--- /dev/null
+++ b/arch/arm/mach-omap1/dma.c
@@ -0,0 +1,390 @@
+/*
+ * OMAP1/OMAP7xx - specific DMA driver
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into platform driver
+ * - G, Manjunath Kondaiah <manjugk@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/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/irqs.h>
+
+#define OMAP1_DMA_BASE (0xfffed800)
+#define OMAP1_LOGICAL_DMA_CH_COUNT 17
+#define OMAP1_DMA_STRIDE 0x40
+
+static u32 errata;
+static u32 enable_1510_mode;
+static u8 dma_stride;
+static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
+
+static u16 reg_map[] = {
+ [GCR] = 0x400,
+ [GSCR] = 0x404,
+ [GRST1] = 0x408,
+ [HW_ID] = 0x442,
+ [PCH2_ID] = 0x444,
+ [PCH0_ID] = 0x446,
+ [PCH1_ID] = 0x448,
+ [PCHG_ID] = 0x44a,
+ [PCHD_ID] = 0x44c,
+ [CAPS_0] = 0x44e,
+ [CAPS_1] = 0x452,
+ [CAPS_2] = 0x456,
+ [CAPS_3] = 0x458,
+ [CAPS_4] = 0x45a,
+ [PCH2_SR] = 0x460,
+ [PCH0_SR] = 0x480,
+ [PCH1_SR] = 0x482,
+ [PCHD_SR] = 0x4c0,
+
+ /* Common Registers */
+ [CSDP] = 0x00,
+ [CCR] = 0x02,
+ [CICR] = 0x04,
+ [CSR] = 0x06,
+ [CEN] = 0x10,
+ [CFN] = 0x12,
+ [CSFI] = 0x14,
+ [CSEI] = 0x16,
+ [CPC] = 0x18, /* 15xx only */
+ [CSAC] = 0x18,
+ [CDAC] = 0x1a,
+ [CDEI] = 0x1c,
+ [CDFI] = 0x1e,
+ [CLNK_CTRL] = 0x28,
+
+ /* Channel specific register offsets */
+ [CSSA] = 0x08,
+ [CDSA] = 0x0c,
+ [COLOR] = 0x20,
+ [CCR2] = 0x24,
+ [LCH_CTRL] = 0x2a,
+};
+
+static struct resource res[] __initdata = {
+ [0] = {
+ .start = OMAP1_DMA_BASE,
+ .end = OMAP1_DMA_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "0",
+ .start = INT_DMA_CH0_6,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "1",
+ .start = INT_DMA_CH1_7,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = "2",
+ .start = INT_DMA_CH2_8,
+ .flags = IORESOURCE_IRQ,
+ },
+ [4] = {
+ .name = "3",
+ .start = INT_DMA_CH3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [5] = {
+ .name = "4",
+ .start = INT_DMA_CH4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [6] = {
+ .name = "5",
+ .start = INT_DMA_CH5,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* Handled in lcd_dma.c */
+ [7] = {
+ .name = "6",
+ .start = INT_1610_DMA_CH6,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* irq's for omap16xx and omap7xx */
+ [8] = {
+ .name = "7",
+ .start = INT_1610_DMA_CH7,
+ .flags = IORESOURCE_IRQ,
+ },
+ [9] = {
+ .name = "8",
+ .start = INT_1610_DMA_CH8,
+ .flags = IORESOURCE_IRQ,
+ },
+ [10] = {
+ .name = "9",
+ .start = INT_1610_DMA_CH9,
+ .flags = IORESOURCE_IRQ,
+ },
+ [11] = {
+ .name = "10",
+ .start = INT_1610_DMA_CH10,
+ .flags = IORESOURCE_IRQ,
+ },
+ [12] = {
+ .name = "11",
+ .start = INT_1610_DMA_CH11,
+ .flags = IORESOURCE_IRQ,
+ },
+ [13] = {
+ .name = "12",
+ .start = INT_1610_DMA_CH12,
+ .flags = IORESOURCE_IRQ,
+ },
+ [14] = {
+ .name = "13",
+ .start = INT_1610_DMA_CH13,
+ .flags = IORESOURCE_IRQ,
+ },
+ [15] = {
+ .name = "14",
+ .start = INT_1610_DMA_CH14,
+ .flags = IORESOURCE_IRQ,
+ },
+ [16] = {
+ .name = "15",
+ .start = INT_1610_DMA_CH15,
+ .flags = IORESOURCE_IRQ,
+ },
+ [17] = {
+ .name = "16",
+ .start = INT_DMA_LCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ u8 stride;
+ u32 offset;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+
+ __raw_writew(val, dma_base + offset);
+ if ((reg > CLNK_CTRL && reg < CCEN) ||
+ (reg > PCHD_ID && reg < CAPS_2)) {
+ u32 offset2 = reg_map[reg] + 2 + (stride * lch);
+ __raw_writew(val >> 16, dma_base + offset2);
+ }
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ u8 stride;
+ u32 offset, val;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+
+ val = __raw_readw(dma_base + offset);
+ if ((reg > CLNK_CTRL && reg < CCEN) ||
+ (reg > PCHD_ID && reg < CAPS_2)) {
+ u16 upper;
+ u32 offset2 = reg_map[reg] + 2 + (stride * lch);
+ upper = __raw_readw(dma_base + offset2);
+ val |= (upper << 16);
+ }
+ return val;
+}
+
+static void omap1_clear_lch_regs(int lch)
+{
+ int i = dma_common_ch_start;
+
+ for (; i <= dma_common_ch_end; i += 1)
+ dma_write(0, i, lch);
+}
+
+static void omap1_clear_dma(int lch)
+{
+ u32 l;
+
+ l = dma_read(CCR, lch);
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR, lch);
+
+ /* Clear pending interrupts */
+ l = dma_read(CSR, lch);
+}
+
+static void omap1_show_dma_caps(void)
+{
+ if (enable_1510_mode) {
+ printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
+ } else {
+ u16 w;
+ printk(KERN_INFO "OMAP DMA hardware version %d\n",
+ dma_read(HW_ID, 0));
+ printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
+ dma_read(CAPS_0, 0), dma_read(CAPS_1, 0),
+ dma_read(CAPS_2, 0), dma_read(CAPS_3, 0),
+ dma_read(CAPS_4, 0));
+
+ /* Disable OMAP 3.0/3.1 compatibility mode. */
+ w = dma_read(GSCR, 0);
+ w |= 1 << 3;
+ dma_write(w, GSCR, 0);
+ }
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx())
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ return errata;
+}
+
+static int __init omap1_system_dma_init(void)
+{
+ struct omap_system_dma_plat_info *p;
+ struct omap_dma_dev_attr *d;
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_alloc("omap_dma_system", 0);
+ if (!pdev) {
+ pr_err("%s: Unable to device alloc for dma\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ dma_base = ioremap(res[0].start, resource_size(&res[0]));
+ if (!dma_base) {
+ pr_err("%s: Unable to ioremap\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_device_del;
+ }
+
+ p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+ if (!p) {
+ dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
+ __func__, pdev->name);
+ ret = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
+ if (!d) {
+ dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
+ __func__, pdev->name);
+ ret = -ENOMEM;
+ goto exit_release_p;
+ }
+
+ d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
+
+ /* Valid attributes for omap1 plus processors */
+ if (cpu_is_omap15xx())
+ d->dev_caps = ENABLE_1510_MODE;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+ d->dev_caps |= SRC_PORT;
+ d->dev_caps |= DST_PORT;
+ d->dev_caps |= SRC_INDEX;
+ d->dev_caps |= DST_INDEX;
+ d->dev_caps |= IS_BURST_ONLY4;
+ d->dev_caps |= CLEAR_CSR_ON_READ;
+ d->dev_caps |= IS_WORD_16;
+
+
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+ if (!d->chan) {
+ dev_err(&pdev->dev, "%s: Memory allocation failed"
+ "for d->chan!!!\n", __func__);
+ goto exit_release_d;
+ }
+
+ if (cpu_is_omap15xx())
+ d->chan_count = 9;
+ else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+ if (!(d->dev_caps & ENABLE_1510_MODE))
+ d->chan_count = 16;
+ else
+ d->chan_count = 9;
+ }
+
+ p->dma_attr = d;
+
+ p->show_dma_caps = omap1_show_dma_caps;
+ p->clear_lch_regs = omap1_clear_lch_regs;
+ p->clear_dma = omap1_clear_dma;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+ p->disable_irq_lch = NULL;
+
+ p->errata = configure_dma_errata();
+
+ ret = platform_device_add_data(pdev, p, sizeof(*p));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_release_chan;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_release_chan;
+ }
+
+ dma_stride = OMAP1_DMA_STRIDE;
+ dma_common_ch_start = CPC;
+ dma_common_ch_end = COLOR;
+
+ return ret;
+
+exit_release_chan:
+ kfree(d->chan);
+exit_release_d:
+ kfree(d);
+exit_release_p:
+ kfree(p);
+exit_device_put:
+ platform_device_put(pdev);
+exit_device_del:
+ platform_device_del(pdev);
+
+ return ret;
+}
+arch_initcall(omap1_system_dma_init);
diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c
index 0b07a78eeaa7..acd161666408 100644
--- a/arch/arm/mach-omap1/flash.c
+++ b/arch/arm/mach-omap1/flash.c
@@ -11,6 +11,7 @@
#include <plat/io.h>
#include <plat/tc.h>
+#include <plat/flash.h>
void omap1_set_vpp(struct map_info *map, int enable)
{
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 5cfce1636da0..8780e75cdc3d 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -143,7 +143,7 @@ static struct irq_chip omap_fpga_irq = {
*/
void omap1510_fpga_init_irq(void)
{
- int i;
+ int i, res;
__raw_writeb(0, OMAP1510_FPGA_IMR_LO);
__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
@@ -177,10 +177,12 @@ void omap1510_fpga_init_irq(void)
* NOTE: For general GPIO/MPUIO access and interrupts, please see
* gpio.[ch]
*/
- gpio_request(13, "FPGA irq");
+ res = gpio_request(13, "FPGA irq");
+ if (res) {
+ pr_err("%s failed to get gpio\n", __func__);
+ return;
+ }
gpio_direction_input(13);
set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
}
-
-EXPORT_SYMBOL(omap1510_fpga_init_irq);
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
new file mode 100644
index 000000000000..04c4b04cf54e
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -0,0 +1,99 @@
+/*
+ * OMAP15xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+#define OMAP1510_GPIO_BASE 0xFFFCE000
+
+/* gpio1 */
+static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 16,
+ .bank_stride = 1,
+};
+
+static struct __initdata platform_device omap15xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap15xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources),
+ .resource = omap15xx_mpu_gpio_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap15xx_gpio_resources[] = {
+ {
+ .start = OMAP1510_GPIO_BASE,
+ .end = OMAP1510_GPIO_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_1510,
+ .bank_width = 16,
+};
+
+static struct __initdata platform_device omap15xx_gpio = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap15xx_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap15xx_gpio_resources),
+ .resource = omap15xx_gpio_resources,
+};
+
+/*
+ * omap15xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap15xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap15xx_gpio_init(void)
+{
+ if (!cpu_is_omap15xx())
+ return -EINVAL;
+
+ platform_device_register(&omap15xx_mpu_gpio);
+ platform_device_register(&omap15xx_gpio);
+
+ gpio_bank_count = 2;
+ return 0;
+}
+postcore_initcall(omap15xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
new file mode 100644
index 000000000000..5dd0d4c82b24
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -0,0 +1,200 @@
+/*
+ * OMAP16xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1610_GPIO1_BASE 0xfffbe400
+#define OMAP1610_GPIO2_BASE 0xfffbec00
+#define OMAP1610_GPIO3_BASE 0xfffbb400
+#define OMAP1610_GPIO4_BASE 0xfffbbc00
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+
+/* mpu gpio */
+static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 16,
+ .bank_stride = 1,
+};
+
+static struct __initdata platform_device omap16xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap16xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
+ .resource = omap16xx_mpu_gpio_resources,
+};
+
+/* gpio1 */
+static struct __initdata resource omap16xx_gpio1_resources[] = {
+ {
+ .start = OMAP1610_GPIO1_BASE,
+ .end = OMAP1610_GPIO1_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct __initdata platform_device omap16xx_gpio1 = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap16xx_gpio1_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
+ .resource = omap16xx_gpio1_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap16xx_gpio2_resources[] = {
+ {
+ .start = OMAP1610_GPIO2_BASE,
+ .end = OMAP1610_GPIO2_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 16,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct __initdata platform_device omap16xx_gpio2 = {
+ .name = "omap_gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &omap16xx_gpio2_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
+ .resource = omap16xx_gpio2_resources,
+};
+
+/* gpio3 */
+static struct __initdata resource omap16xx_gpio3_resources[] = {
+ {
+ .start = OMAP1610_GPIO3_BASE,
+ .end = OMAP1610_GPIO3_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 32,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct __initdata platform_device omap16xx_gpio3 = {
+ .name = "omap_gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &omap16xx_gpio3_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
+ .resource = omap16xx_gpio3_resources,
+};
+
+/* gpio4 */
+static struct __initdata resource omap16xx_gpio4_resources[] = {
+ {
+ .start = OMAP1610_GPIO4_BASE,
+ .end = OMAP1610_GPIO4_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 48,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct __initdata platform_device omap16xx_gpio4 = {
+ .name = "omap_gpio",
+ .id = 4,
+ .dev = {
+ .platform_data = &omap16xx_gpio4_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
+ .resource = omap16xx_gpio4_resources,
+};
+
+static struct __initdata platform_device * omap16xx_gpio_dev[] = {
+ &omap16xx_mpu_gpio,
+ &omap16xx_gpio1,
+ &omap16xx_gpio2,
+ &omap16xx_gpio3,
+ &omap16xx_gpio4,
+};
+
+/*
+ * omap16xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap16xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap16xx_gpio_init(void)
+{
+ int i;
+
+ if (!cpu_is_omap16xx())
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++)
+ platform_device_register(omap16xx_gpio_dev[i]);
+
+ gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
+
+ return 0;
+}
+postcore_initcall(omap16xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
new file mode 100644
index 000000000000..1204c8b871af
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -0,0 +1,262 @@
+/*
+ * OMAP7xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP7XX_GPIO1_BASE 0xfffbc000
+#define OMAP7XX_GPIO2_BASE 0xfffbc800
+#define OMAP7XX_GPIO3_BASE 0xfffbd000
+#define OMAP7XX_GPIO4_BASE 0xfffbd800
+#define OMAP7XX_GPIO5_BASE 0xfffbe000
+#define OMAP7XX_GPIO6_BASE 0xfffbe800
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+
+/* mpu gpio */
+static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 32,
+ .bank_stride = 2,
+};
+
+static struct __initdata platform_device omap7xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap7xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources),
+ .resource = omap7xx_mpu_gpio_resources,
+};
+
+/* gpio1 */
+static struct __initdata resource omap7xx_gpio1_resources[] = {
+ {
+ .start = OMAP7XX_GPIO1_BASE,
+ .end = OMAP7XX_GPIO1_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio1 = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap7xx_gpio1_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio1_resources),
+ .resource = omap7xx_gpio1_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap7xx_gpio2_resources[] = {
+ {
+ .start = OMAP7XX_GPIO2_BASE,
+ .end = OMAP7XX_GPIO2_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 32,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio2 = {
+ .name = "omap_gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &omap7xx_gpio2_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio2_resources),
+ .resource = omap7xx_gpio2_resources,
+};
+
+/* gpio3 */
+static struct __initdata resource omap7xx_gpio3_resources[] = {
+ {
+ .start = OMAP7XX_GPIO3_BASE,
+ .end = OMAP7XX_GPIO3_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 64,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio3 = {
+ .name = "omap_gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &omap7xx_gpio3_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio3_resources),
+ .resource = omap7xx_gpio3_resources,
+};
+
+/* gpio4 */
+static struct __initdata resource omap7xx_gpio4_resources[] = {
+ {
+ .start = OMAP7XX_GPIO4_BASE,
+ .end = OMAP7XX_GPIO4_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 96,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio4 = {
+ .name = "omap_gpio",
+ .id = 4,
+ .dev = {
+ .platform_data = &omap7xx_gpio4_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio4_resources),
+ .resource = omap7xx_gpio4_resources,
+};
+
+/* gpio5 */
+static struct __initdata resource omap7xx_gpio5_resources[] = {
+ {
+ .start = OMAP7XX_GPIO5_BASE,
+ .end = OMAP7XX_GPIO5_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 128,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio5 = {
+ .name = "omap_gpio",
+ .id = 5,
+ .dev = {
+ .platform_data = &omap7xx_gpio5_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio5_resources),
+ .resource = omap7xx_gpio5_resources,
+};
+
+/* gpio6 */
+static struct __initdata resource omap7xx_gpio6_resources[] = {
+ {
+ .start = OMAP7XX_GPIO6_BASE,
+ .end = OMAP7XX_GPIO6_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 160,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct __initdata platform_device omap7xx_gpio6 = {
+ .name = "omap_gpio",
+ .id = 6,
+ .dev = {
+ .platform_data = &omap7xx_gpio6_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio6_resources),
+ .resource = omap7xx_gpio6_resources,
+};
+
+static struct __initdata platform_device * omap7xx_gpio_dev[] = {
+ &omap7xx_mpu_gpio,
+ &omap7xx_gpio1,
+ &omap7xx_gpio2,
+ &omap7xx_gpio3,
+ &omap7xx_gpio4,
+ &omap7xx_gpio5,
+ &omap7xx_gpio6,
+};
+
+/*
+ * omap7xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap7xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap7xx_gpio_init(void)
+{
+ int i;
+
+ if (!cpu_is_omap7xx())
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++)
+ platform_device_register(omap7xx_gpio_dev[i]);
+
+ gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
+
+ return 0;
+}
+postcore_initcall(omap7xx_gpio_init);
diff --git a/arch/arm/mach-omap1/include/mach/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S
index df9060edda28..c9be6d4d83e2 100644
--- a/arch/arm/mach-omap1/include/mach/entry-macro.S
+++ b/arch/arm/mach-omap1/include/mach/entry-macro.S
@@ -14,18 +14,17 @@
#include <mach/irqs.h>
#include <asm/hardware/gic.h>
-#if (defined(CONFIG_ARCH_OMAP730)||defined(CONFIG_ARCH_OMAP850)) && \
- (defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
-#error "FIXME: OMAP7XX doesn't support multiple-OMAP"
-#elif defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-#define INT_IH2_IRQ INT_7XX_IH2_IRQ
-#elif defined(CONFIG_ARCH_OMAP15XX)
-#define INT_IH2_IRQ INT_1510_IH2_IRQ
-#elif defined(CONFIG_ARCH_OMAP16XX)
-#define INT_IH2_IRQ INT_1610_IH2_IRQ
-#else
-#warning "IH2 IRQ defaulted"
-#define INT_IH2_IRQ INT_1510_IH2_IRQ
+/*
+ * We use __glue to avoid errors with multiple definitions of
+ * .globl omap_irq_flags as it's included from entry-armv.S but not
+ * from entry-common.S.
+ */
+#ifdef __glue
+ .pushsection .data
+ .globl omap_irq_flags
+omap_irq_flags:
+ .word 0
+ .popsection
#endif
.macro disable_fiq
@@ -47,9 +46,11 @@
beq 1510f
ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
+ ldr \tmp, =omap_irq_flags @ irq flags address
+ ldr \tmp, [\tmp, #0] @ irq flags value
cmp \irqnr, #0
ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
- cmpeq \irqnr, #INT_IH2_IRQ
+ cmpeq \irqnr, \tmp
ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
addeqs \irqnr, \irqnr, #32
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 0ce3fec2d257..870886a29594 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -142,3 +142,42 @@ void __init omap1_init_common_hw(void)
omap1_mux_init();
}
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+u8 omap_readb(u32 pa)
+{
+ return __raw_readb(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readb);
+
+u16 omap_readw(u32 pa)
+{
+ return __raw_readw(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readw);
+
+u32 omap_readl(u32 pa)
+{
+ return __raw_readl(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readl);
+
+void omap_writeb(u8 v, u32 pa)
+{
+ __raw_writeb(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writeb);
+
+void omap_writew(u16 v, u32 pa)
+{
+ __raw_writew(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writew);
+
+void omap_writel(u32 v, u32 pa)
+{
+ __raw_writel(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index db913c34d1fe..6bddbc869f4c 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -176,26 +176,31 @@ static struct irq_chip omap_irq_chip = {
void __init omap_init_irq(void)
{
+ extern unsigned int omap_irq_flags;
int i, j;
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
if (cpu_is_omap7xx()) {
+ omap_irq_flags = INT_7XX_IH2_IRQ;
irq_banks = omap7xx_irq_banks;
irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
}
#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap1510_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
}
if (cpu_is_omap310()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap310_irq_banks;
irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
}
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
if (cpu_is_omap16xx()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap1610_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
}
diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c
index 3be11af687bb..c9088d85da04 100644
--- a/arch/arm/mach-omap1/lcd_dma.c
+++ b/arch/arm/mach-omap1/lcd_dma.c
@@ -424,6 +424,9 @@ static int __init omap_init_lcd_dma(void)
{
int r;
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
if (cpu_is_omap16xx()) {
u16 w;
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
index 277f356d4cd0..22eb11dde9e7 100644
--- a/arch/arm/mach-omap1/leds.c
+++ b/arch/arm/mach-omap1/leds.c
@@ -17,6 +17,9 @@
static int __init
omap_leds_init(void)
{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
index 1a85a421007f..c0e1f48aa119 100644
--- a/arch/arm/mach-omap1/mailbox.c
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -133,19 +133,18 @@ static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
},
};
-struct omap_mbox mbox_dsp_info = {
+static struct omap_mbox mbox_dsp_info = {
.name = "dsp",
.ops = &omap1_mbox_ops,
.priv = &omap1_mbox_dsp_priv,
};
-struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
+static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
static int __devinit omap1_mbox_probe(struct platform_device *pdev)
{
struct resource *mem;
int ret;
- int i;
struct omap_mbox **list;
list = omap1_mboxes;
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index b3a796a6da03..820973666f34 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -174,8 +174,11 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
#define OMAP16XX_MCBSP_REG_NUM 0
#endif
-int __init omap1_mcbsp_init(void)
+static int __init omap1_mcbsp_init(void)
{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
if (cpu_is_omap7xx()) {
omap_mcbsp_count = OMAP7XX_MCBSP_PDATA_SZ;
omap_mcbsp_cache_size = OMAP7XX_MCBSP_REG_NUM * sizeof(u16);
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 7835add00344..5fdef7a34828 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -343,7 +343,7 @@ MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0)
#define OMAP1XXX_PINS_SZ 0
#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
-int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
+static int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
{
static DEFINE_SPINLOCK(mux_spin_lock);
unsigned long flags;
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index b1d3f9fade23..0cca23a85175 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -661,6 +661,9 @@ static int __init omap_pm_init(void)
int error;
#endif
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
printk("Power Management for TI OMAP.\n");
/*
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
index 8b66392be745..6588c22b8a64 100644
--- a/arch/arm/mach-omap1/pm_bus.c
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -48,7 +48,6 @@ static int omap1_pm_runtime_suspend(struct device *dev)
static int omap1_pm_runtime_resume(struct device *dev)
{
- int ret = 0;
struct clk *iclk, *fclk;
dev_dbg(dev, "%s\n", __func__);
@@ -73,6 +72,9 @@ static int __init omap1_pm_runtime_init(void)
const struct dev_pm_ops *pm;
struct dev_pm_ops *omap_pm;
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
pm = platform_bus_get_pm_ops();
if (!pm) {
pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index b78d0749f13d..550ca9d9991d 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -27,6 +27,8 @@
#include <mach/gpio.h>
#include <plat/fpga.h>
+#include "pm.h"
+
static struct clk * uart1_ck;
static struct clk * uart2_ck;
static struct clk * uart3_ck;
@@ -52,9 +54,11 @@ static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
*/
static void __init omap_serial_reset(struct plat_serial8250_port *p)
{
- omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */
+ omap_serial_outp(p, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_DISABLE); /* disable UART */
omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */
- omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */
+ omap_serial_outp(p, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_16X_MODE); /* enable UART */
if (!cpu_is_omap15xx()) {
omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
@@ -254,6 +258,9 @@ late_initcall(omap_serial_wakeup_init);
static int __init omap_init(void)
{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
return platform_device_register(&serial_device);
}
arch_initcall(omap_init);
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 1be6a214d88d..ed7a61ff916a 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -52,6 +52,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
+#include <plat/common.h>
#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE
#define OMAP_MPU_TIMER_OFFSET 0x100
@@ -208,7 +209,6 @@ static struct clocksource clocksource_mpu = {
.rating = 300,
.read = mpu_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -217,13 +217,10 @@ static void __init omap_init_clocksource(unsigned long rate)
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
- clocksource_mpu.mult
- = clocksource_khz2mult(rate/1000, clocksource_mpu.shift);
-
setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
omap_mpu_timer_start(1, ~0, 1);
- if (clocksource_register(&clocksource_mpu))
+ if (clocksource_register_hz(&clocksource_mpu, rate))
printk(err, clocksource_mpu.name);
}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index ab784bfde908..3e8c9e859f98 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -15,7 +15,7 @@ config ARCH_OMAP2PLUS_TYPICAL
select SERIAL_OMAP_CONSOLE
select I2C
select I2C_OMAP
- select MFD
+ select MFD_SUPPORT
select MENELAUS if ARCH_OMAP2
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
@@ -35,6 +35,8 @@ config ARCH_OMAP3
select CPU_V7
select USB_ARCH_HAS_EHCI
select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
config ARCH_OMAP4
bool "TI OMAP4"
@@ -44,6 +46,8 @@ config ARCH_OMAP4
select ARM_GIC
select PL310_ERRATA_588369
select ARM_ERRATA_720789
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
comment "OMAP Core Type"
depends on ARCH_OMAP2
@@ -85,6 +89,12 @@ config OMAP_PACKAGE_CUS
config OMAP_PACKAGE_CBP
bool
+config OMAP_PACKAGE_CBL
+ bool
+
+config OMAP_PACKAGE_CBS
+ bool
+
comment "OMAP Board Type"
depends on ARCH_OMAP2PLUS
@@ -128,7 +138,6 @@ config MACH_DEVKIT8000
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
- select OMAP_MUX
config MACH_OMAP_LDP
bool "OMAP3 LDP board"
@@ -174,11 +183,17 @@ config MACH_OMAP3517EVM
default y
select OMAP_PACKAGE_CBB
+config MACH_CRANEBOARD
+ bool "AM3517/05 CRANE board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+
config MACH_OMAP3_PANDORA
bool "OMAP3 Pandora"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
+ select REGULATOR_FIXED_VOLTAGE
config MACH_OMAP3_TOUCHBOOK
bool "OMAP3 Touch Book"
@@ -210,6 +225,12 @@ config MACH_NOKIA_N8X0
select MACH_NOKIA_N810
select MACH_NOKIA_N810_WIMAX
+config MACH_NOKIA_RM680
+ bool "Nokia RM-680 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
config MACH_NOKIA_RX51
bool "Nokia RX-51 board"
depends on ARCH_OMAP3
@@ -224,6 +245,7 @@ config MACH_OMAP_ZOOM2
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
@@ -233,20 +255,19 @@ config MACH_OMAP_ZOOM3
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE
config MACH_CM_T35
bool "CompuLab CM-T35 module"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
- select OMAP_MUX
config MACH_CM_T3517
bool "CompuLab CM-T3517 module"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
- select OMAP_MUX
config MACH_IGEP0020
bool "IGEP v2 board"
@@ -265,7 +286,6 @@ config MACH_SBC3530
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
- select OMAP_MUX
config MACH_OMAP_3630SDP
bool "OMAP3630 SDP board"
@@ -277,11 +297,15 @@ config MACH_OMAP_4430SDP
bool "OMAP 4430 SDP board"
default y
depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
config MACH_OMAP4_PANDA
bool "OMAP4 Panda Board"
default y
depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
config OMAP3_EMU
bool "OMAP3 debugging peripherals"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 60e51bcf53bd..4ab82f6f15b1 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,30 +4,31 @@
# Common support
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
- common.o
+ common.o gpio.o dma.o wd_timer.o
-omap-2-3-common = irq.o sdrc.o prm2xxx_3xxx.o
+omap-2-3-common = irq.o sdrc.o
hwmod-common = omap_hwmod.o \
omap_hwmod_common_data.o
-prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o \
- clockdomain.o clkt_dpll.o \
- clkt_clksel.o
+ clkt_dpll.o clkt_clksel.o
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o
-AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a
-AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec)
# Functions loaded to SRAM
obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
@@ -42,18 +43,29 @@ AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
obj-$(CONFIG_ARCH_OMAP2420) += mux2420.o
obj-$(CONFIG_ARCH_OMAP2430) += mux2430.o
obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
# SMS/SDRC
obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
+# OPP table initialization
+ifeq ($(CONFIG_PM_OPP),y)
+obj-y += opp.o
+obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
+endif
+
# Power Management
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \
+ cpuidle34xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
+obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
@@ -65,10 +77,36 @@ endif
endif
# PRCM
-obj-$(CONFIG_ARCH_OMAP2) += cm.o
-obj-$(CONFIG_ARCH_OMAP3) += cm.o
-obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o
-
+obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
+# will be removed once the OMAP4 part of the codebase is converted to
+# use OMAP4-specific PRCM functions.
+obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
+ cm44xx.o prcm_mpu44xx.o \
+ prminst44xx.o
+
+# OMAP powerdomain framework
+powerdomain-common += powerdomain.o powerdomain-common.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains2xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains3xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
+ powerdomain44xx.o \
+ powerdomains44xx_data.o
+
+# PRCM clockdomain control
+obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
+ clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
+ clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
+ clockdomains44xx_data.o
# Clock framework
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
clkt2xxx_sys.o \
@@ -139,17 +177,20 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
hsmmc.o \
board-flash.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
+obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
+ sdram-nokia.o \
+ hsmmc.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
- board-rx51-sdram.o \
+ sdram-nokia.o \
board-rx51-peripherals.o \
board-rx51-video.o \
hsmmc.o
-obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
board-zoom-peripherals.o \
board-flash.o \
hsmmc.o \
board-zoom-debugboard.o
-obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom3.o \
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
board-zoom-peripherals.o \
board-flash.o \
hsmmc.o \
@@ -174,6 +215,8 @@ obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \
obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
+obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
+
obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \
hsmmc.o
# Platform specific device init code
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index b527f8d187ad..e0661777f599 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -135,7 +135,7 @@ static inline void board_smc91x_init(void)
#endif
-static struct omap_board_config_kernel sdp2430_config[] = {
+static struct omap_board_config_kernel sdp2430_config[] __initdata = {
{OMAP_TAG_LCD, &sdp2430_lcd_config},
};
@@ -143,9 +143,9 @@ static void __init omap_2430sdp_init_irq(void)
{
omap_board_config = sdp2430_config;
omap_board_config_size = ARRAY_SIZE(sdp2430_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
}
static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
@@ -218,8 +218,6 @@ static struct omap_usb_config sdp2430_usb_config __initdata = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init omap_2430sdp_init(void)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 4e3742c512b8..3b39ef1a680a 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -326,9 +326,9 @@ static void __init omap_3430sdp_init_irq(void)
omap_board_config = sdp3430_config;
omap_board_config_size = ARRAY_SIZE(sdp3430_config);
omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
- omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL);
omap_init_irq();
- omap_gpio_init();
}
static int sdp3430_batt_table[] = {
@@ -663,8 +663,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
/*
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index bbcf580fa097..5d41dbe059a3 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -73,18 +73,16 @@ static void __init omap_sdp_init_irq(void)
{
omap_board_config = sdp_config;
omap_board_config_size = ARRAY_SIZE(sdp_config);
- omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
- h8mbx00u0mer0em_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
/*
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index df5a425a49d1..1cb208b6e626 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -23,6 +23,7 @@
#include <linux/gpio_keys.h>
#include <linux/regulator/machine.h>
#include <linux/leds.h>
+#include <linux/leds_pwm.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
@@ -35,6 +36,7 @@
#include <plat/usb.h>
#include <plat/mmc.h>
+#include "mux.h"
#include "hsmmc.h"
#include "timer-gp.h"
#include "control.h"
@@ -96,6 +98,28 @@ static struct gpio_led_platform_data sdp4430_led_data = {
.num_leds = ARRAY_SIZE(sdp4430_gpio_leds),
};
+static struct led_pwm sdp4430_pwm_leds[] = {
+ {
+ .name = "omap4:green:chrg",
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .pwm_period_ns = 7812500,
+ },
+};
+
+static struct led_pwm_platform_data sdp4430_pwm_data = {
+ .num_leds = ARRAY_SIZE(sdp4430_pwm_leds),
+ .leds = sdp4430_pwm_leds,
+};
+
+static struct platform_device sdp4430_leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_pwm_data,
+ },
+};
+
static int omap_prox_activate(struct device *dev)
{
gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
@@ -203,6 +227,7 @@ static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
&sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
+ &sdp4430_leds_pwm,
};
static struct omap_lcd_config sdp4430_lcd_config __initdata = {
@@ -217,12 +242,12 @@ static void __init omap_4430sdp_init_irq(void)
{
omap_board_config = sdp4430_config;
omap_board_config_size = ARRAY_SIZE(sdp4430_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(1);
#endif
gic_init_irq();
- omap_gpio_init();
}
static struct omap_musb_board_data musb_board_data = {
@@ -464,6 +489,9 @@ static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
{
I2C_BOARD_INFO("tmp105", 0x48),
},
+ {
+ I2C_BOARD_INFO("bh1780", 0x29),
+ },
};
static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
{
@@ -505,9 +533,22 @@ static void __init omap_sfh7741prox_init(void)
}
}
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init omap_4430sdp_init(void)
{
int status;
+ int package = OMAP_PACKAGE_CBS;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, package);
omap4_i2c_init();
omap_sfh7741prox_init();
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
new file mode 100644
index 000000000000..71acb5ab281c
--- /dev/null
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -0,0 +1,116 @@
+/*
+ * Support for AM3517/05 Craneboard
+ * http://www.mistralsolutions.com/products/craneboard.php
+ *
+ * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com>
+ * Author: R.Srinath <srinath@mistralsolutions.com>
+ *
+ * Based on mach-omap2/board-am3517evm.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define GPIO_USB_POWER 35
+#define GPIO_USB_NRESET 38
+
+
+/* Board initialization */
+static struct omap_board_config_kernel am3517_crane_config[] __initdata = {
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
+static void __init am3517_crane_init_irq(void)
+{
+ omap_board_config = am3517_crane_config;
+ omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
+
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+ omap_init_irq();
+}
+
+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_UNKNOWN,
+ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = GPIO_USB_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void __init am3517_crane_init(void)
+{
+ int ret;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+
+ /* Configure GPIO for EHCI port */
+ if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
+ GPIO_USB_NRESET);
+ return;
+ }
+
+ if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_POWER %d\n",
+ GPIO_USB_POWER);
+ return;
+ }
+
+ ret = gpio_request(GPIO_USB_POWER, "usb_ehci_enable");
+ if (ret < 0) {
+ pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
+ return;
+ }
+
+ ret = gpio_direction_output(GPIO_USB_POWER, 1);
+ if (ret < 0) {
+ gpio_free(GPIO_USB_POWER);
+ pr_err("Unable to initialize EHCI power\n");
+ return;
+ }
+
+ usb_ehci_init(&ehci_pdata);
+}
+
+MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
+ .init_irq = am3517_crane_init_irq,
+ .init_machine = am3517_crane_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 07399505312b..bc1562648020 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -389,10 +389,9 @@ static void __init am3517_evm_init_irq(void)
{
omap_board_config = am3517_evm_config;
omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
-
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
}
static struct omap_musb_board_data musb_board_data = {
@@ -442,8 +441,6 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 2c6db1aaeb29..9f55b68687f7 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -270,7 +270,7 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
.ctrl_name = "internal",
};
-static struct omap_board_config_kernel apollon_config[] = {
+static struct omap_board_config_kernel apollon_config[] __initdata = {
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
@@ -278,10 +278,9 @@ static void __init omap_apollon_init_irq(void)
{
omap_board_config = apollon_config;
omap_board_config_size = ARRAY_SIZE(apollon_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
- apollon_init_smc91x();
}
static void __init apollon_led_init(void)
@@ -314,8 +313,6 @@ static void __init apollon_usb_init(void)
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init omap_apollon_init(void)
@@ -324,6 +321,7 @@ static void __init omap_apollon_init(void)
omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+ apollon_init_smc91x();
apollon_led_init();
apollon_flash_init();
apollon_usb_init();
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 63f764e2af3f..486a3de5f401 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -600,8 +600,8 @@ static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6,
+ .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7,
.reset_gpio_port[2] = -EINVAL
};
@@ -630,12 +630,6 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
cm_t35_vmmc1_supply.dev = mmc[0].dev;
cm_t35_vsim_supply.dev = mmc[0].dev;
- /* setup USB with proper PHY reset GPIOs */
- ehci_pdata.reset_gpio_port[0] = gpio + 6;
- ehci_pdata.reset_gpio_port[1] = gpio + 7;
-
- usb_ehci_init(&ehci_pdata);
-
return 0;
}
@@ -683,10 +677,10 @@ static void __init cm_t35_init_irq(void)
omap_board_config = cm_t35_config;
omap_board_config_size = ARRAY_SIZE(cm_t35_config);
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
static struct omap_board_mux board_mux[] __initdata = {
@@ -805,6 +799,7 @@ static void __init cm_t35_init(void)
cm_t35_init_display();
usb_musb_init(&musb_board_data);
+ usb_ehci_init(&ehci_pdata);
}
MACHINE_START(CM_T35, "Compulab CM-T35")
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 1dd303e9a267..5b0c77732dfc 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -248,9 +248,9 @@ static void __init cm_t3517_init_irq(void)
omap_board_config = cm_t3517_config;
omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
}
static struct omap_board_mux board_mux[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 53ac762518bd..451e7ff08b18 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -118,27 +118,27 @@ static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 1);
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
return 0;
}
static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
{
if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 0);
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
}
static int devkit8000_panel_enable_dvi(struct omap_dss_device *dssdev)
{
if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 1);
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
return 0;
}
static void devkit8000_panel_disable_dvi(struct omap_dss_device *dssdev)
{
if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 0);
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
}
static struct regulator_consumer_supply devkit8000_vmmc1_supply =
@@ -444,13 +444,13 @@ static struct platform_device keys_gpio = {
static void __init devkit8000_init_irq(void)
{
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
- omap_gpio_init();
}
static void __init devkit8000_ads7846_init(void)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index b1c2c9a11c38..0e3d81e09f89 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -37,7 +37,8 @@ static void __init omap_generic_init_irq(void)
{
omap_board_config = generic_config;
omap_board_config_size = ARRAY_SIZE(generic_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
}
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 929993b4bf26..25cc9dad4b02 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -51,38 +51,37 @@
static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
-static int h4_keymap[] = {
+static const unsigned int h4_keymap[] = {
KEY(0, 0, KEY_LEFT),
- KEY(0, 1, KEY_RIGHT),
- KEY(0, 2, KEY_A),
- KEY(0, 3, KEY_B),
- KEY(0, 4, KEY_C),
- KEY(1, 0, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_A),
+ KEY(3, 0, KEY_B),
+ KEY(4, 0, KEY_C),
+ KEY(0, 1, KEY_DOWN),
KEY(1, 1, KEY_UP),
- KEY(1, 2, KEY_E),
- KEY(1, 3, KEY_F),
- KEY(1, 4, KEY_G),
- KEY(2, 0, KEY_ENTER),
- KEY(2, 1, KEY_I),
+ KEY(2, 1, KEY_E),
+ KEY(3, 1, KEY_F),
+ KEY(4, 1, KEY_G),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_I),
KEY(2, 2, KEY_J),
- KEY(2, 3, KEY_K),
- KEY(2, 4, KEY_3),
- KEY(3, 0, KEY_M),
- KEY(3, 1, KEY_N),
- KEY(3, 2, KEY_O),
+ KEY(3, 2, KEY_K),
+ KEY(4, 2, KEY_3),
+ KEY(0, 3, KEY_M),
+ KEY(1, 3, KEY_N),
+ KEY(2, 3, KEY_O),
KEY(3, 3, KEY_P),
- KEY(3, 4, KEY_Q),
- KEY(4, 0, KEY_R),
- KEY(4, 1, KEY_4),
- KEY(4, 2, KEY_T),
- KEY(4, 3, KEY_U),
+ KEY(4, 3, KEY_Q),
+ KEY(0, 4, KEY_R),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_T),
+ KEY(3, 4, KEY_U),
KEY(4, 4, KEY_ENTER),
- KEY(5, 0, KEY_V),
- KEY(5, 1, KEY_W),
- KEY(5, 2, KEY_L),
- KEY(5, 3, KEY_S),
- KEY(5, 4, KEY_ENTER),
- 0
+ KEY(0, 5, KEY_V),
+ KEY(1, 5, KEY_W),
+ KEY(2, 5, KEY_L),
+ KEY(3, 5, KEY_S),
+ KEY(4, 5, KEY_ENTER),
};
static struct mtd_partition h4_partitions[] = {
@@ -136,12 +135,16 @@ static struct platform_device h4_flash_device = {
.resource = &h4_flash_resource,
};
+static const struct matrix_keymap_data h4_keymap_data = {
+ .keymap = h4_keymap,
+ .keymap_size = ARRAY_SIZE(h4_keymap),
+};
+
static struct omap_kp_platform_data h4_kp_data = {
.rows = 6,
.cols = 7,
- .keymap = h4_keymap,
- .keymapsize = ARRAY_SIZE(h4_keymap),
- .rep = 1,
+ .keymap_data = &h4_keymap_data,
+ .rep = true,
.row_gpios = row_gpios,
.col_gpios = col_gpios,
};
@@ -283,7 +286,7 @@ static struct omap_usb_config h4_usb_config __initdata = {
.hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
};
-static struct omap_board_config_kernel h4_config[] = {
+static struct omap_board_config_kernel h4_config[] __initdata = {
{ OMAP_TAG_LCD, &h4_lcd_config },
};
@@ -291,9 +294,9 @@ static void __init omap_h4_init_irq(void)
{
omap_board_config = h4_config;
omap_board_config_size = ARRAY_SIZE(h4_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
h4_init_flash();
}
@@ -321,8 +324,6 @@ static struct i2c_board_info __initdata h4_i2c_board_info[] = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init omap_h4_init(void)
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 5e035a58b809..0afa3011db0f 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
#include <linux/i2c/twl.h>
#include <linux/mmc/host.h>
@@ -136,16 +137,9 @@ static struct mtd_partition igep2_onenand_partitions[] = {
},
};
-static int igep2_onenand_setup(void __iomem *onenand_base, int freq)
-{
- /* nothing is required to be setup for onenand as of now */
- return 0;
-}
-
static struct omap_onenand_platform_data igep2_onenand_data = {
.parts = igep2_onenand_partitions,
.nr_parts = ARRAY_SIZE(igep2_onenand_partitions),
- .onenand_setup = igep2_onenand_setup,
.dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
};
@@ -159,35 +153,34 @@ static struct platform_device igep2_onenand_device = {
static void __init igep2_flash_init(void)
{
- u8 cs = 0;
- u8 onenandcs = GPMC_CS_NUM + 1;
+ u8 cs = 0;
+ u8 onenandcs = GPMC_CS_NUM + 1;
- while (cs < GPMC_CS_NUM) {
- u32 ret = 0;
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ u32 ret;
ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
/* Check if NAND/oneNAND is configured */
if ((ret & 0xC00) == 0x800)
/* NAND found */
- pr_err("IGEP v2: Unsupported NAND found\n");
+ pr_err("IGEP2: Unsupported NAND found\n");
else {
ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
if ((ret & 0x3F) == (ONENAND_MAP >> 24))
/* ONENAND found */
onenandcs = cs;
}
- cs++;
}
+
if (onenandcs > GPMC_CS_NUM) {
- pr_err("IGEP v2: Unable to find configuration in GPMC\n");
+ pr_err("IGEP2: Unable to find configuration in GPMC\n");
return;
}
- if (onenandcs < GPMC_CS_NUM) {
- igep2_onenand_data.cs = onenandcs;
- if (platform_device_register(&igep2_onenand_device) < 0)
- pr_err("IGEP v2: Unable to register OneNAND device\n");
- }
+ igep2_onenand_data.cs = onenandcs;
+
+ if (platform_device_register(&igep2_onenand_device) < 0)
+ pr_err("IGEP2: Unable to register OneNAND device\n");
}
#else
@@ -254,12 +247,8 @@ static inline void __init igep2_init_smsc911x(void)
static inline void __init igep2_init_smsc911x(void) { }
#endif
-static struct omap_board_config_kernel igep2_config[] __initdata = {
-};
-
-static struct regulator_consumer_supply igep2_vmmc1_supply = {
- .supply = "vmmc",
-};
+static struct regulator_consumer_supply igep2_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0");
/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
static struct regulator_init_data igep2_vmmc1 = {
@@ -276,6 +265,52 @@ static struct regulator_init_data igep2_vmmc1 = {
.consumer_supplies = &igep2_vmmc1_supply,
};
+static struct regulator_consumer_supply igep2_vio_supply =
+ REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1");
+
+static struct regulator_init_data igep2_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep2_vio_supply,
+};
+
+static struct regulator_consumer_supply igep2_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
+
+static struct regulator_init_data igep2_vmmc2 = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep2_vmmc2_supply,
+};
+
+static struct fixed_voltage_config igep2_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 1,
+ .init_data = &igep2_vmmc2,
+};
+
+static struct platform_device igep2_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &igep2_vwlan,
+ },
+};
+
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
@@ -317,6 +352,7 @@ static struct gpio_led igep2_gpio_leds[] = {
.name = "gpio-led:green:d1",
.default_trigger = "heartbeat",
.gpio = -EINVAL, /* gets replaced */
+ .active_low = 1,
},
};
@@ -342,24 +378,21 @@ static void __init igep2_leds_init(void)
static inline void igep2_leds_init(void)
{
if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
+ (gpio_direction_output(IGEP2_GPIO_LED0_RED, 0) == 0))
gpio_export(IGEP2_GPIO_LED0_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
- } else
+ else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
+ (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 0) == 0))
gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
- gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
- } else
+ else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
+ (gpio_direction_output(IGEP2_GPIO_LED1_RED, 0) == 0))
gpio_export(IGEP2_GPIO_LED1_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
- } else
+ else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
}
@@ -373,12 +406,6 @@ static int igep2_twl_gpio_setup(struct device *dev,
omap2_hsmmc_init(mmc);
/*
- * link regulators to MMC adapters ... we "know" the
- * regulators will be set up only *after* we return.
- */
- igep2_vmmc1_supply.dev = mmc[0].dev;
-
- /*
* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
@@ -397,10 +424,9 @@ static int igep2_twl_gpio_setup(struct device *dev,
/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
- && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
+ && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0))
gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
- gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
- } else
+ else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
#else
igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -489,15 +515,15 @@ static void __init igep2_display_init(void)
static struct platform_device *igep2_devices[] __initdata = {
&igep2_dss_device,
+ &igep2_vwlan_device,
};
static void __init igep2_init_irq(void)
{
- omap_board_config = igep2_config;
- omap_board_config_size = ARRAY_SIZE(igep2_config);
- omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(m65kxxxxam_sdrc_params,
+ m65kxxxxam_sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
static struct twl4030_codec_audio_data igep2_audio_data = {
@@ -519,7 +545,7 @@ static struct twl4030_platform_data igep2_twldata = {
.gpio = &igep2_twl4030_gpio_pdata,
.vmmc1 = &igep2_vmmc1,
.vpll2 = &igep2_vpll2,
-
+ .vio = &igep2_vio,
};
static struct i2c_board_info __initdata igep2_i2c1_boardinfo[] = {
@@ -577,8 +603,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c
index 22b0b253e16b..bcccd68f1856 100644
--- a/arch/arm/mach-omap2/board-igep0030.c
+++ b/arch/arm/mach-omap2/board-igep0030.c
@@ -289,9 +289,10 @@ static struct twl4030_usb_data igep3_twl4030_usb_data = {
static void __init igep3_init_irq(void)
{
- omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(m65kxxxxam_sdrc_params,
+ m65kxxxxam_sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
static struct twl4030_platform_data igep3_twl4030_pdata = {
@@ -366,8 +367,6 @@ void __init igep3_wifi_bt_init(void) {}
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init igep3_init(void)
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 001fd9713f39..e5dc74875f9d 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -292,10 +292,9 @@ static void __init omap_ldp_init_irq(void)
{
omap_board_config = ldp_config;
omap_board_config_size = ARRAY_SIZE(ldp_config);
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
- ldp_init_smsc911x();
}
static struct twl4030_usb_data ldp_usb_data = {
@@ -381,8 +380,6 @@ static struct platform_device *ldp_devices[] __initdata = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
@@ -426,6 +423,7 @@ static struct mtd_partition ldp_nand_partitions[] = {
static void __init omap_ldp_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ ldp_init_smsc911x();
omap_i2c_init();
platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
ts_gpio = 54;
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index e823c7042ab3..147d9005f320 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -184,23 +184,15 @@ static struct mtd_partition onenand_partitions[] = {
},
};
-static struct omap_onenand_platform_data board_onenand_data = {
- .cs = 0,
- .gpio_irq = 26,
- .parts = onenand_partitions,
- .nr_parts = ARRAY_SIZE(onenand_partitions),
- .flags = ONENAND_SYNC_READ,
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 26,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READ,
+ }
};
-
-static void __init n8x0_onenand_init(void)
-{
- gpmc_onenand_init(&board_onenand_data);
-}
-
-#else
-
-static void __init n8x0_onenand_init(void) {}
-
#endif
#if defined(CONFIG_MENELAUS) && \
@@ -639,9 +631,9 @@ static void __init n8x0_map_io(void)
static void __init n8x0_init_irq(void)
{
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
}
#ifdef CONFIG_OMAP_MUX
@@ -653,8 +645,43 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP2420_MUX(EAC_AC_DOUT, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ {
+ .name = "uart3_rx_irrx.uart3_rx_irrx",
+ .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+ .enable = OMAP_MUX_MODE0,
+ .idle = OMAP_MUX_MODE3 /* Mux as GPIO for idle */
+ },
+};
+
+static inline void board_serial_init(void)
+{
+ struct omap_board_data bdata;
+
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+
+ bdata.id = 0;
+ omap_serial_init_port(&bdata);
+
+ bdata.id = 1;
+ omap_serial_init_port(&bdata);
+
+ bdata.id = 2;
+ bdata.pads = serial2_pads;
+ bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
+ omap_serial_init_port(&bdata);
+}
+
#else
-#define board_mux NULL
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+
#endif
static void __init n8x0_init_machine(void)
@@ -669,9 +696,8 @@ static void __init n8x0_init_machine(void)
if (machine_is_nokia_n810())
i2c_register_board_info(2, n810_i2c_board_info_2,
ARRAY_SIZE(n810_i2c_board_info_2));
-
- omap_serial_init();
- n8x0_onenand_init();
+ board_serial_init();
+ gpmc_onenand_init(board_onenand_data);
n8x0_mmc_init();
n8x0_usb_init();
}
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 14f42240ae79..6c127605942f 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -484,13 +484,13 @@ static struct platform_device keys_gpio = {
static void __init omap3_beagle_init_irq(void)
{
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
- omap_gpio_init();
}
static struct platform_device *omap3_beagle_devices[] __initdata = {
@@ -548,8 +548,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b04365c6bb10..3de8d9b8ec76 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -623,9 +623,9 @@ static void __init omap3_evm_init_irq(void)
{
omap_board_config = omap3_evm_config;
omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
omap_init_irq();
- omap_gpio_init();
}
static struct platform_device *omap3_evm_devices[] __initdata = {
@@ -654,8 +654,6 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 5f7d2c1e7ef5..15e4b08e99ba 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -197,17 +197,15 @@ static inline void __init board_smsc911x_init(void)
static void __init omap3logic_init_irq(void)
{
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
omap_init_irq();
- omap_gpio_init();
}
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init omap3logic_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 89ed1be2d62e..0b34beded11f 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -293,7 +293,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
},
{
.mmc = 3,
- .caps = MMC_CAP_4_BIT_DATA,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.init_card = pandora_wl1251_init_card,
@@ -636,37 +636,19 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
static void __init omap3pandora_init_irq(void)
{
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
- omap_gpio_init();
-}
-
-static void pandora_wl1251_set_power(bool enable)
-{
- /*
- * Keep power always on until wl1251_sdio driver learns to re-init
- * the chip after powering it down and back up.
- */
}
-static struct wl12xx_platform_data pandora_wl1251_pdata = {
- .set_power = pandora_wl1251_set_power,
- .use_eeprom = true,
-};
-
-static struct platform_device pandora_wl1251_data = {
- .name = "wl1251_data",
- .id = -1,
- .dev = {
- .platform_data = &pandora_wl1251_pdata,
- },
-};
-
-static void pandora_wl1251_init(void)
+static void __init pandora_wl1251_init(void)
{
+ struct wl12xx_platform_data pandora_wl1251_pdata;
int ret;
+ memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+
ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq");
if (ret < 0)
goto fail;
@@ -679,6 +661,11 @@ static void pandora_wl1251_init(void)
if (pandora_wl1251_pdata.irq < 0)
goto fail_irq;
+ pandora_wl1251_pdata.use_eeprom = true;
+ ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+ if (ret < 0)
+ goto fail_irq;
+
return;
fail_irq:
@@ -691,7 +678,6 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_leds_gpio,
&pandora_keys_gpio,
&pandora_dss_device,
- &pandora_wl1251_data,
&pandora_vwlan_device,
};
@@ -711,8 +697,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index f25272125413..9df9d9367608 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -584,12 +584,12 @@ static void __init omap3_stalker_init_irq(void)
{
omap_board_config = omap3_stalker_config;
omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
omap_init_irq();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
- omap_gpio_init();
}
static struct platform_device *omap3_stalker_devices[] __initdata = {
@@ -616,8 +616,6 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
{.reg_offset = OMAP_MUX_TERMINATOR},
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 41104bb8774c..db1f74fe6c4f 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -413,8 +413,6 @@ static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static void __init omap3_touchbook_init_irq(void)
@@ -422,13 +420,13 @@ static void __init omap3_touchbook_init_irq(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_board_config = omap3_touchbook_config;
omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
#ifdef CONFIG_OMAP_32K_TIMER
omap2_gp_clockevent_set_gptimer(12);
#endif
- omap_gpio_init();
}
static struct platform_device *omap3_touchbook_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1ecd0a6cefb7..b43e3ff9adec 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -40,6 +40,7 @@
#include "hsmmc.h"
#include "control.h"
+#include "mux.h"
#define GPIO_HUB_POWER 1
#define GPIO_HUB_NRESET 62
@@ -76,9 +77,9 @@ static struct platform_device *panda_devices[] __initdata = {
static void __init omap4_panda_init_irq(void)
{
- omap2_init_common_hw(NULL, NULL);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
gic_init_irq();
- omap_gpio_init();
}
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
@@ -142,6 +143,7 @@ static struct omap2_hsmmc_info mmc[] = {
.mmc = 1,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
},
{} /* Terminator */
};
@@ -368,8 +370,23 @@ static int __init omap4_panda_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init omap4_panda_init(void)
{
+ int package = OMAP_PACKAGE_CBS;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, package);
+
omap4_panda_i2c_init();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
omap_serial_init();
@@ -391,6 +408,7 @@ static void __init omap4_panda_map_io(void)
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */
.boot_params = 0x80000100,
+ .reserve = omap_reserve,
.map_io = omap4_panda_map_io,
.init_irq = omap4_panda_init_irq,
.init_machine = omap4_panda_init,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 7053bc0b46db..cb26e5d8268d 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -413,10 +413,10 @@ static void __init overo_init_irq(void)
{
omap_board_config = overo_config;
omap_board_config_size = ARRAY_SIZE(overo_config);
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
static struct platform_device *overo_devices[] __initdata = {
@@ -438,8 +438,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
new file mode 100644
index 000000000000..cb77be7ac44f
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -0,0 +1,187 @@
+/*
+ * Board support file for Nokia RM-680.
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/i2c.h>
+#include <plat/mmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc.h>
+#include <plat/common.h>
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-nokia.h"
+
+static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"),
+};
+
+/* Fixed regulator for internal eMMC */
+static struct regulator_init_data rm680_vemmc = {
+ .constraints = {
+ .name = "rm680_vemmc",
+ .min_uV = 2900000,
+ .max_uV = 2900000,
+ .apply_uV = 1,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS
+ | REGULATOR_CHANGE_MODE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers),
+ .consumer_supplies = rm680_vemmc_consumers,
+};
+
+static struct fixed_voltage_config rm680_vemmc_config = {
+ .supply_name = "VEMMC",
+ .microvolts = 2900000,
+ .gpio = 157,
+ .startup_delay = 150,
+ .enable_high = 1,
+ .init_data = &rm680_vemmc,
+};
+
+static struct platform_device rm680_vemmc_device = {
+ .name = "reg-fixed-voltage",
+ .dev = {
+ .platform_data = &rm680_vemmc_config,
+ },
+};
+
+static struct platform_device *rm680_peripherals_devices[] __initdata = {
+ &rm680_vemmc_device,
+};
+
+/* TWL */
+static struct twl4030_gpio_platform_data rm680_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pullups = BIT(0),
+ .pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15),
+};
+
+static struct twl4030_usb_data rm680_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_platform_data rm680_twl_data = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+ .gpio = &rm680_gpio_data,
+ .usb = &rm680_usb_data,
+ /* add rest of the children here */
+};
+
+static struct i2c_board_info __initdata rm680_twl_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("twl5031", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &rm680_twl_data,
+ },
+};
+
+static void __init rm680_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2900, rm680_twl_i2c_board_info,
+ ARRAY_SIZE(rm680_twl_i2c_board_info));
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .gpio_irq = 65,
+ .flags = ONENAND_SYNC_READWRITE,
+ }
+};
+#endif
+
+/* eMMC */
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ { /* Terminator */ }
+};
+
+static void __init rm680_peripherals_init(void)
+{
+ platform_add_devices(rm680_peripherals_devices,
+ ARRAY_SIZE(rm680_peripherals_devices));
+ rm680_i2c_init();
+ gpmc_onenand_init(board_onenand_data);
+ omap2_hsmmc_init(mmc);
+}
+
+static void __init rm680_init_irq(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap2_init_common_infrastructure();
+ sdrc_params = nokia_get_sdram_timings();
+ omap2_init_common_devices(sdrc_params, sdrc_params);
+ omap_init_irq();
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct omap_musb_board_data rm680_musb_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_PERIPHERAL,
+ .power = 100,
+};
+
+static void __init rm680_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ usb_musb_init(&rm680_musb_data);
+ rm680_peripherals_init();
+}
+
+static void __init rm680_map_io(void)
+{
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+}
+
+MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
+ .boot_params = 0x80000100,
+ .map_io = rm680_map_io,
+ .reserve = omap_reserve,
+ .init_irq = rm680_init_irq,
+ .init_machine = rm680_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 3fec4d62a91a..e75e240cad67 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -23,7 +23,6 @@
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/mmc/host.h>
-#include <sound/tlv320aic3x.h>
#include <plat/mcspi.h>
#include <plat/board.h>
@@ -293,6 +292,8 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
+static struct omap_mux_partition *partition;
+
/*
* Current flows to eMMC when eMMC is off and the data lines are pulled up,
* so pull them down. N.B. we pull 8 lines because we are using 8 lines.
@@ -300,9 +301,9 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
{
if (power_on)
- omap_mux_write_array(rx51_mmc2_on_mux);
+ omap_mux_write_array(partition, rx51_mmc2_on_mux);
else
- omap_mux_write_array(rx51_mmc2_off_mux);
+ omap_mux_write_array(partition, rx51_mmc2_off_mux);
}
static struct omap2_hsmmc_info mmc[] __initdata = {
@@ -342,6 +343,8 @@ static struct regulator_consumer_supply rx51_vmmc2_supplies[] = {
/* tlv320aic3x analog supplies */
REGULATOR_SUPPLY("AVDD", "2-0018"),
REGULATOR_SUPPLY("DRVDD", "2-0018"),
+ REGULATOR_SUPPLY("AVDD", "2-0019"),
+ REGULATOR_SUPPLY("DRVDD", "2-0019"),
/* tpa6130a2 */
REGULATOR_SUPPLY("Vdd", "2-0060"),
/* Keep vmmc as last item. It is not iterated for newer boards */
@@ -352,19 +355,16 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = {
/* tlv320aic3x digital supplies */
REGULATOR_SUPPLY("IOVDD", "2-0018"),
REGULATOR_SUPPLY("DVDD", "2-0018"),
+ REGULATOR_SUPPLY("IOVDD", "2-0019"),
+ REGULATOR_SUPPLY("DVDD", "2-0019"),
};
-#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
-extern struct platform_device rx51_display_device;
-#endif
-
static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
-#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
- {
- .supply = "vdds_sdi",
- .dev = &rx51_display_device.dev,
- },
-#endif
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+};
+
+static struct regulator_consumer_supply rx51_vdac_supply[] = {
+ REGULATOR_SUPPLY("vdda_dac", "omapdss"),
};
static struct regulator_init_data rx51_vaux1 = {
@@ -484,14 +484,17 @@ static struct regulator_init_data rx51_vsim = {
static struct regulator_init_data rx51_vdac = {
.constraints = {
+ .name = "VDAC",
.min_uV = 1800000,
.max_uV = 1800000,
+ .apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = rx51_vdac_supply,
};
static struct regulator_init_data rx51_vio = {
@@ -717,7 +720,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
.vio = &rx51_vio,
};
-static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata = {
+static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
.id = TPA6130A2,
.power_gpio = 98,
};
@@ -742,11 +745,19 @@ static struct aic3x_pdata rx51_aic3x_data = {
.gpio_reset = 60,
};
+static struct aic3x_pdata rx51_aic3x_data2 = {
+ .gpio_reset = 60,
+};
+
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
{
I2C_BOARD_INFO("tlv320aic3x", 0x18),
.platform_data = &rx51_aic3x_data,
},
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x19),
+ .platform_data = &rx51_aic3x_data2,
+ },
#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
{
I2C_BOARD_INFO("tsl2563", 0x29),
@@ -815,25 +826,15 @@ static struct mtd_partition onenand_partitions[] = {
},
};
-static struct omap_onenand_platform_data board_onenand_data = {
- .cs = 0,
- .gpio_irq = 65,
- .parts = onenand_partitions,
- .nr_parts = ARRAY_SIZE(onenand_partitions),
- .flags = ONENAND_SYNC_READWRITE,
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 65,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READWRITE,
+ }
};
-
-static void __init board_onenand_init(void)
-{
- gpmc_onenand_init(&board_onenand_data);
-}
-
-#else
-
-static inline void board_onenand_init(void)
-{
-}
-
#endif
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
@@ -916,13 +917,17 @@ error:
void __init rx51_peripherals_init(void)
{
rx51_i2c_init();
- board_onenand_init();
+ gpmc_onenand_init(board_onenand_data);
board_smc91x_init();
rx51_add_gpio_keys();
rx51_init_wl1251();
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
- omap2_hsmmc_init(mmc);
+
+ partition = omap_mux_get("core");
+ if (partition)
+ omap2_hsmmc_init(mmc);
+
platform_device_register(&rx51_charger_device);
}
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index 85503fed4e13..acd670054d9a 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -14,7 +14,6 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/mm.h>
-
#include <asm/mach-types.h>
#include <plat/display.h>
#include <plat/vram.h>
@@ -49,8 +48,16 @@ static struct omap_dss_device rx51_lcd_device = {
.platform_disable = rx51_lcd_disable,
};
+static struct omap_dss_device rx51_tv_device = {
+ .name = "tv",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .driver_name = "venc",
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+};
+
static struct omap_dss_device *rx51_dss_devices[] = {
&rx51_lcd_device,
+ &rx51_tv_device,
};
static struct omap_dss_board_info rx51_dss_board_info = {
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 36f2cf4efd57..f53fc551c58f 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -32,10 +32,10 @@
#include "mux.h"
#include "pm.h"
+#include "sdram-nokia.h"
#define RX51_GPIO_SLEEP_IND 162
-struct omap_sdrc_params *rx51_get_sdram_timings(void);
extern void rx51_video_mem_init(void);
static struct gpio_led gpio_leds[] = {
@@ -105,10 +105,10 @@ static void __init rx51_init_irq(void)
omap_board_config = rx51_config;
omap_board_config_size = ARRAY_SIZE(rx51_config);
omap3_pm_init_cpuidle(rx51_cpuidle_params);
- sdrc_params = rx51_get_sdram_timings();
- omap2_init_common_hw(sdrc_params, sdrc_params);
+ omap2_init_common_infrastructure();
+ sdrc_params = nokia_get_sdram_timings();
+ omap2_init_common_devices(sdrc_params, sdrc_params);
omap_init_irq();
- omap_gpio_init();
}
extern void __init rx51_peripherals_init(void);
@@ -117,8 +117,6 @@ extern void __init rx51_peripherals_init(void);
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
-#else
-#define board_mux NULL
#endif
static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 86c9b2102952..3fbd0edd712e 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -196,7 +196,7 @@ struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
.board_ref_clock = 1,
};
-static struct omap2_hsmmc_info mmc[] __initdata = {
+static struct omap2_hsmmc_info mmc[] = {
{
.name = "external",
.mmc = 1,
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "wl1271",
.mmc = 3,
- .caps = MMC_CAP_4_BIT_DATA,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
.nonremovable = true,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom.c
index 5adde12c0395..e041c537ea37 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -1,6 +1,9 @@
/*
- * Copyright (C) 2009 Texas Instruments Inc.
+ * Copyright (C) 2009-2010 Texas Instruments Inc.
+ * Mikkel Christensen <mlc@ti.com>
+ * Felipe Balbi <balbi@ti.com>
*
+ * Modified from mach-omap2/board-ldp.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
@@ -12,22 +15,55 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/board-zoom.h>
-
#include <plat/common.h>
#include <plat/board.h>
#include <plat/usb.h>
+#include <mach/board-zoom.h>
+
#include "board-flash.h"
#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
-static struct omap_board_config_kernel zoom_config[] __initdata = {
+#define ZOOM3_EHCI_RESET_GPIO 64
+
+static void __init omap_zoom_init_irq(void)
+{
+ omap2_init_common_infrastructure();
+ if (machine_is_omap_zoom2())
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ else if (machine_is_omap_zoom3())
+ omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+
+ omap_init_irq();
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 162 */
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN POWER ENABLE - GPIO 101 */
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC3 CMD */
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 CLK */
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 DAT[0-3] */
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
};
+#endif
static struct mtd_partition zoom_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
@@ -70,59 +106,41 @@ static struct mtd_partition zoom_nand_partitions[] = {
},
};
-static void __init omap_zoom_init_irq(void)
-{
- omap_board_config = zoom_config;
- omap_board_config_size = ARRAY_SIZE(zoom_config);
- omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
- h8mbx00u0mer0em_sdrc_params);
- omap_init_irq();
- omap_gpio_init();
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* WLAN IRQ - GPIO 162 */
- OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN POWER ENABLE - GPIO 101 */
- OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* WLAN SDIO: MMC3 CMD */
- OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC3 CLK */
- OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC3 DAT[0-3] */
- OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define board_mux NULL
-#endif
-
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,
.phy_reset = true,
.reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 64,
+ .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO,
.reset_gpio_port[2] = -EINVAL,
};
static void __init omap_zoom_init(void)
{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
- zoom_peripherals_init();
+ if (machine_is_omap_zoom2()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ } else if (machine_is_omap_zoom3()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
+ usb_ehci_init(&ehci_pdata);
+ }
+
board_nand_init(zoom_nand_partitions,
- ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS);
+ ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS);
zoom_debugboard_init();
-
- omap_mux_init_gpio(64, OMAP_PIN_OUTPUT);
- usb_ehci_init(&ehci_pdata);
+ zoom_peripherals_init();
}
+MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_zoom_init_irq,
+ .init_machine = omap_zoom_init,
+ .timer = &omap_timer,
+MACHINE_END
+
MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
.boot_params = 0x80000100,
.map_io = omap3_map_io,
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
deleted file mode 100644
index 2992a9f3a585..000000000000
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments Inc.
- * Mikkel Christensen <mlc@ti.com>
- *
- * Modified from mach-omap2/board-ldp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include <plat/common.h>
-#include <plat/board.h>
-
-#include <mach/board-zoom.h>
-
-#include "board-flash.h"
-#include "mux.h"
-#include "sdram-micron-mt46h32m32lf-6.h"
-
-static void __init omap_zoom2_init_irq(void)
-{
- omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
- omap_init_irq();
- omap_gpio_init();
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* WLAN IRQ - GPIO 162 */
- OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN POWER ENABLE - GPIO 101 */
- OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* WLAN SDIO: MMC3 CMD */
- OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC3 CLK */
- OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC3 DAT[0-3] */
- OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define board_mux NULL
-#endif
-
-static struct mtd_partition zoom_nand_partitions[] = {
- /* All the partition sizes are listed in terms of NAND block size */
- {
- .name = "X-Loader-NAND",
- .offset = 0,
- .size = 4 * (64 * 2048), /* 512KB, 0x80000 */
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "U-Boot-NAND",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
- .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "Boot Env-NAND",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
- .size = 2 * (64 * 2048), /* 256KB, 0x40000 */
- },
- {
- .name = "Kernel-NAND",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/
- .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */
- },
- {
- .name = "system",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */
- .size = 3328 * (64 * 2048), /* 416M, 0x1A000000 */
- },
- {
- .name = "userdata",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C000000*/
- .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
- },
- {
- .name = "cache",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E000000*/
- .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
- },
-};
-
-static void __init omap_zoom2_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- zoom_peripherals_init();
- board_nand_init(zoom_nand_partitions,
- ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS);
- zoom_debugboard_init();
-}
-
-MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
- .boot_params = 0x80000100,
- .map_io = omap3_map_io,
- .reserve = omap_reserve,
- .init_irq = omap_zoom2_init_irq,
- .init_machine = omap_zoom2_init,
- .timer = &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index 66e01acfd585..f51cffd1fc53 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -26,7 +26,7 @@
#include "clock.h"
#include "clock2xxx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
@@ -49,14 +49,14 @@ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
- cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
if ((cval & apll_mask) == apll_mask)
return 0; /* apll already enabled */
cval &= ~apll_mask;
cval |= apll_mask;
- cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
OMAP24XX_CM_IDLEST_VAL, clk->name);
@@ -83,9 +83,9 @@ static void omap2_clk_apll_disable(struct clk *clk)
{
u32 cval;
- cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
- cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
}
/* Public data */
@@ -106,7 +106,7 @@ u32 omap2xxx_get_apll_clkin(void)
{
u32 aplls, srate = 0;
- aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+ aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
aplls &= OMAP24XX_APLLS_CLKIN_MASK;
aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index 019048434f13..4ae439222085 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -32,7 +32,7 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
@@ -54,7 +54,7 @@ unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
core_clk = omap2_get_dpll_rate(clk);
- v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
v &= OMAP24XX_CORE_CLK_SRC_MASK;
if (v == CORE_CLK_SRC_32K)
@@ -73,7 +73,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
{
u32 high, low, core_clk_src;
- core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
@@ -111,7 +111,7 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
const struct dpll_data *dd;
cur_rate = omap2xxx_clk_get_core_rate(dclk);
- mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
if ((rate == (cur_rate / 2)) && (mult == 2)) {
@@ -136,7 +136,7 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
dd->div1_mask);
div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
- tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
if (rate > low) {
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c
index 2167be84a5bc..df7b80506483 100644
--- a/arch/arm/mach-omap2/clkt2xxx_osc.c
+++ b/arch/arm/mach-omap2/clkt2xxx_osc.c
@@ -27,7 +27,7 @@
#include "clock.h"
#include "clock2xxx.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
static int omap2_enable_osc_ck(struct clk *clk)
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c
index 822b5a79f457..8693cfdac49a 100644
--- a/arch/arm/mach-omap2/clkt2xxx_sys.c
+++ b/arch/arm/mach-omap2/clkt2xxx_sys.c
@@ -26,7 +26,7 @@
#include "clock.h"
#include "clock2xxx.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
void __iomem *prcm_clksrc_ctrl;
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index aef62918aaf0..39f9d5a58d0c 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -40,7 +40,7 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
const struct prcm_config *curr_prcm_set;
@@ -133,21 +133,21 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
done_rate = CORE_CLK_SRC_DPLL;
/* MPU divider */
- cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
/* dsp + iva1 div(2420), iva2.1(2430) */
- cm_write_mod_reg(prcm->cm_clksel_dsp,
+ omap2_cm_write_mod_reg(prcm->cm_clksel_dsp,
OMAP24XX_DSP_MOD, CM_CLKSEL);
- cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+ omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
/* Major subsystem dividers */
- tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
- cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+ tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+ omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
CM_CLKSEL1);
if (cpu_is_omap2430())
- cm_write_mod_reg(prcm->cm_clksel_mdm,
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mdm,
OMAP2430_MDM_MOD, CM_CLKSEL);
/* x2 to enter omap2xxx_sdrc_init_params() */
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index 6ce512e902c6..337392c3f549 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -24,7 +24,6 @@
#include <plat/clock.h>
#include "clock.h"
-#include "cm.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index b5babf5440e4..2a2f15213add 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -24,14 +24,12 @@
#include <linux/bitops.h>
#include <plat/clock.h>
-#include <plat/clockdomain.h>
+#include "clockdomain.h"
#include <plat/cpu.h>
#include <plat/prcm.h>
#include "clock.h"
-#include "prm.h"
-#include "prm-regbits-24xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index a535c7a2a62a..896584e3c4ab 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -49,7 +49,6 @@
/* DPLL Type and DCO Selection Flags */
#define DPLL_J_TYPE 0x1
-#define DPLL_NO_DCO_SEL 0x2
int omap2_clk_enable(struct clk *clk);
void omap2_clk_disable(struct clk *clk);
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 21f856252ad8..ed1295f5046e 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -22,8 +22,8 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "prm.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
@@ -812,7 +812,7 @@ static struct clk dss2_fck = { /* Alt clk used in power management */
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_CLKSEL_DSS2_MASK,
.clksel = dss2_fck_clksel,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk dss_54m_fck = { /* Alt clk used in power management */
@@ -1862,10 +1862,10 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "eac_fck", &eac_fck, CK_242X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_242X),
- CLK("i2c_omap.1", "ick", &i2c1_ick, CK_242X),
- CLK("i2c_omap.1", "fck", &i2c1_fck, CK_242X),
- CLK("i2c_omap.2", "ick", &i2c2_ick, CK_242X),
- CLK("i2c_omap.2", "fck", &i2c2_fck, CK_242X),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_242X),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_242X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_242X),
CLK(NULL, "sdma_ick", &sdma_ick, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c
index 44d0cccc51a9..d87bc9cb2a36 100644
--- a/arch/arm/mach-omap2/clock2430.c
+++ b/arch/arm/mach-omap2/clock2430.c
@@ -25,7 +25,7 @@
#include "clock.h"
#include "clock2xxx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
/**
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index e32afcbdfb88..38341a71c6f8 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -22,8 +22,8 @@
#include "clock.h"
#include "clock2xxx.h"
#include "opp2xxx.h"
-#include "prm.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
@@ -800,7 +800,7 @@ static struct clk dss2_fck = { /* Alt clk used in power management */
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_CLKSEL_DSS2_MASK,
.clksel = dss2_fck_clksel,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
};
static struct clk dss_54m_fck = { /* Alt clk used in power management */
@@ -1969,10 +1969,10 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "fac_fck", &fac_fck, CK_243X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X),
- CLK("i2c_omap.1", "ick", &i2c1_ick, CK_243X),
- CLK("i2c_omap.1", "fck", &i2chs1_fck, CK_243X),
- CLK("i2c_omap.2", "ick", &i2c2_ick, CK_243X),
- CLK("i2c_omap.2", "fck", &i2chs2_fck, CK_243X),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X),
+ CLK("omap_i2c.1", "fck", &i2chs1_fck, CK_243X),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X),
+ CLK("omap_i2c.2", "fck", &i2chs2_fck, CK_243X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_243X),
CLK(NULL, "sdma_ick", &sdma_ick, CK_243X),
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 6febd5f11e85..287abc480924 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -25,7 +25,7 @@
#include "clock.h"
#include "clock34xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
/**
diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c
index b496a9305e1c..74116a3cf099 100644
--- a/arch/arm/mach-omap2/clock3517.c
+++ b/arch/arm/mach-omap2/clock3517.c
@@ -25,7 +25,7 @@
#include "clock.h"
#include "clock3517.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
/*
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
index a447c4d2c28a..e9f66b6dec18 100644
--- a/arch/arm/mach-omap2/clock3xxx.c
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -25,9 +25,9 @@
#include "clock.h"
#include "clock3xxx.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
/*
@@ -94,7 +94,7 @@ static int __init omap3xxx_clk_arch_init(void)
ret = omap2_clk_switch_mpurate_at_boot("dpll1_ck");
if (!ret)
- omap2_clk_print_new_rates("osc_sys_ck", "arm_fck", "core_ck");
+ omap2_clk_print_new_rates("osc_sys_ck", "core_ck", "arm_fck");
return ret;
}
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index d85ecd5aebfd..9ab817e6c300 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -28,9 +28,9 @@
#include "clock36xx.h"
#include "clock3517.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
#include "control.h"
@@ -120,7 +120,7 @@ static const struct clksel_rate osc_sys_13m_rates[] = {
};
static const struct clksel_rate osc_sys_16_8m_rates[] = {
- { .div = 1, .val = 5, .flags = RATE_IN_3430ES2PLUS },
+ { .div = 1, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
{ .div = 0 }
};
@@ -452,35 +452,35 @@ static struct clk dpll3_x2_ck = {
static const struct clksel_rate div31_dpll3_rates[] = {
{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
- { .div = 3, .val = 3, .flags = RATE_IN_3430ES2PLUS },
- { .div = 4, .val = 4, .flags = RATE_IN_3430ES2PLUS },
- { .div = 5, .val = 5, .flags = RATE_IN_3430ES2PLUS },
- { .div = 6, .val = 6, .flags = RATE_IN_3430ES2PLUS },
- { .div = 7, .val = 7, .flags = RATE_IN_3430ES2PLUS },
- { .div = 8, .val = 8, .flags = RATE_IN_3430ES2PLUS },
- { .div = 9, .val = 9, .flags = RATE_IN_3430ES2PLUS },
- { .div = 10, .val = 10, .flags = RATE_IN_3430ES2PLUS },
- { .div = 11, .val = 11, .flags = RATE_IN_3430ES2PLUS },
- { .div = 12, .val = 12, .flags = RATE_IN_3430ES2PLUS },
- { .div = 13, .val = 13, .flags = RATE_IN_3430ES2PLUS },
- { .div = 14, .val = 14, .flags = RATE_IN_3430ES2PLUS },
- { .div = 15, .val = 15, .flags = RATE_IN_3430ES2PLUS },
- { .div = 16, .val = 16, .flags = RATE_IN_3430ES2PLUS },
- { .div = 17, .val = 17, .flags = RATE_IN_3430ES2PLUS },
- { .div = 18, .val = 18, .flags = RATE_IN_3430ES2PLUS },
- { .div = 19, .val = 19, .flags = RATE_IN_3430ES2PLUS },
- { .div = 20, .val = 20, .flags = RATE_IN_3430ES2PLUS },
- { .div = 21, .val = 21, .flags = RATE_IN_3430ES2PLUS },
- { .div = 22, .val = 22, .flags = RATE_IN_3430ES2PLUS },
- { .div = 23, .val = 23, .flags = RATE_IN_3430ES2PLUS },
- { .div = 24, .val = 24, .flags = RATE_IN_3430ES2PLUS },
- { .div = 25, .val = 25, .flags = RATE_IN_3430ES2PLUS },
- { .div = 26, .val = 26, .flags = RATE_IN_3430ES2PLUS },
- { .div = 27, .val = 27, .flags = RATE_IN_3430ES2PLUS },
- { .div = 28, .val = 28, .flags = RATE_IN_3430ES2PLUS },
- { .div = 29, .val = 29, .flags = RATE_IN_3430ES2PLUS },
- { .div = 30, .val = 30, .flags = RATE_IN_3430ES2PLUS },
- { .div = 31, .val = 31, .flags = RATE_IN_3430ES2PLUS },
+ { .div = 3, .val = 3, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 7, .val = 7, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 10, .val = 10, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 11, .val = 11, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 13, .val = 13, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 14, .val = 14, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 15, .val = 15, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 17, .val = 17, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 18, .val = 18, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 19, .val = 19, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 20, .val = 20, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 21, .val = 21, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 22, .val = 22, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 23, .val = 23, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 24, .val = 24, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 25, .val = 25, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 26, .val = 26, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 27, .val = 27, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 28, .val = 28, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 29, .val = 29, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 30, .val = 30, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 31, .val = 31, .flags = RATE_IN_3430ES2PLUS_36XX },
{ .div = 0 },
};
@@ -602,6 +602,8 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
.autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
.idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
.idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
+ .dco_mask = OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
+ .sddiv_mask = OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
.min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
@@ -1558,6 +1560,7 @@ static struct clk mcspi4_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
.recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
};
static struct clk mcspi3_fck = {
@@ -1567,6 +1570,7 @@ static struct clk mcspi3_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
.recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
};
static struct clk mcspi2_fck = {
@@ -1576,6 +1580,7 @@ static struct clk mcspi2_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
.recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
};
static struct clk mcspi1_fck = {
@@ -1585,6 +1590,7 @@ static struct clk mcspi1_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
.recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
};
static struct clk uart2_fck = {
@@ -3044,6 +3050,7 @@ static struct clk sr1_fck = {
.parent = &sys_ck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_SR1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -3054,6 +3061,7 @@ static struct clk sr2_fck = {
.parent = &sys_ck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_SR2_SHIFT,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -3201,7 +3209,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_3XXX),
CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_3XXX),
CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_3XXX),
- CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2 | CK_AM35XX),
+ CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX),
CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_3XXX),
CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
@@ -3218,8 +3226,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX),
CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_3XXX),
CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
- CLK(NULL, "dpll2_ck", &dpll2_ck, CK_343X),
- CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck, CK_343X),
+ CLK(NULL, "dpll2_ck", &dpll2_ck, CK_34XX | CK_36XX),
+ CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck, CK_34XX | CK_36XX),
CLK(NULL, "dpll3_ck", &dpll3_ck, CK_3XXX),
CLK(NULL, "core_ck", &core_ck, CK_3XXX),
CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck, CK_3XXX),
@@ -3248,8 +3256,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_3XXX),
CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
- CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2 | CK_AM35XX),
+ CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
CLK(NULL, "sys_clkout2", &sys_clkout2, CK_3XXX),
CLK(NULL, "corex2_fck", &corex2_fck, CK_3XXX),
@@ -3257,8 +3265,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "mpu_ck", &mpu_ck, CK_3XXX),
CLK(NULL, "arm_fck", &arm_fck, CK_3XXX),
CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
- CLK(NULL, "dpll2_fck", &dpll2_fck, CK_343X),
- CLK(NULL, "iva2_ck", &iva2_ck, CK_343X),
+ CLK(NULL, "dpll2_fck", &dpll2_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "iva2_ck", &iva2_ck, CK_34XX | CK_36XX),
CLK(NULL, "l3_ick", &l3_ick, CK_3XXX),
CLK(NULL, "l4_ick", &l4_ick, CK_3XXX),
CLK(NULL, "rm_ick", &rm_ick, CK_3XXX),
@@ -3267,27 +3275,27 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "gfx_l3_ick", &gfx_l3_ick, CK_3430ES1),
CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck, CK_3430ES1),
CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck, CK_3430ES1),
- CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2 | CK_3517),
- CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2 | CK_3517),
+ CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2PLUS | CK_3517 | CK_36XX),
+ CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2PLUS | CK_3517 | CK_36XX),
CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
- CLK(NULL, "modem_fck", &modem_fck, CK_343X),
- CLK(NULL, "sad2d_ick", &sad2d_ick, CK_343X),
- CLK(NULL, "mad2d_ick", &mad2d_ick, CK_343X),
+ CLK(NULL, "modem_fck", &modem_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sad2d_ick", &sad2d_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "mad2d_ick", &mad2d_ick, CK_34XX | CK_36XX),
CLK(NULL, "gpt10_fck", &gpt10_fck, CK_3XXX),
CLK(NULL, "gpt11_fck", &gpt11_fck, CK_3XXX),
- CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX),
+ CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
- CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2 | CK_AM35XX),
+ CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_3XXX),
- CLK(NULL, "mspro_fck", &mspro_fck, CK_343X),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX),
CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_3XXX),
- CLK("i2c_omap.3", "fck", &i2c3_fck, CK_3XXX),
- CLK("i2c_omap.2", "fck", &i2c2_fck, CK_3XXX),
- CLK("i2c_omap.1", "fck", &i2c1_fck, CK_3XXX),
+ CLK("omap_i2c.3", "fck", &i2c3_fck, CK_3XXX),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_3XXX),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_3XXX),
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_3XXX),
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_3XXX),
CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX),
@@ -3301,34 +3309,34 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX),
CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX),
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1),
- CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2),
+ CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1),
- CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2),
+ CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "core_l3_ick", &core_l3_ick, CK_3XXX),
CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es1, CK_3430ES1),
- CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es2, CK_3430ES2),
+ CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_3XXX),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_3XXX),
- CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X),
- CLK(NULL, "pka_ick", &pka_ick, CK_343X),
+ CLK(NULL, "security_l3_ick", &security_l3_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX),
CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
- CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX),
- CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "icr_ick", &icr_ick, CK_343X),
- CLK("omap-aes", "ick", &aes2_ick, CK_343X),
- CLK("omap-sham", "ick", &sha12_ick, CK_343X),
- CLK(NULL, "des2_ick", &des2_ick, CK_343X),
+ CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
+ CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
+ CLK("omap-sham", "ick", &sha12_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "des2_ick", &des2_ick, CK_34XX | CK_36XX),
CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_3XXX),
CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_3XXX),
- CLK(NULL, "mspro_ick", &mspro_ick, CK_343X),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_34XX | CK_36XX),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_3XXX),
CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_3XXX),
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_3XXX),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_3XXX),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_3XXX),
- CLK("i2c_omap.3", "ick", &i2c3_ick, CK_3XXX),
- CLK("i2c_omap.2", "ick", &i2c2_ick, CK_3XXX),
- CLK("i2c_omap.1", "ick", &i2c1_ick, CK_3XXX),
+ CLK("omap_i2c.3", "ick", &i2c3_ick, CK_3XXX),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_3XXX),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_3XXX),
CLK(NULL, "uart2_ick", &uart2_ick, CK_3XXX),
CLK(NULL, "uart1_ick", &uart1_ick, CK_3XXX),
CLK(NULL, "gpt11_ick", &gpt11_ick, CK_3XXX),
@@ -3336,37 +3344,37 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_3XXX),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_3XXX),
CLK(NULL, "fac_ick", &fac_ick, CK_3430ES1),
- CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_34XX | CK_36XX),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_3XXX),
- CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_34XX | CK_36XX),
CLK(NULL, "ssi_ick", &ssi_ick_3430es1, CK_3430ES1),
- CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2),
+ CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1),
- CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X),
- CLK(NULL, "aes1_ick", &aes1_ick, CK_343X),
- CLK("omap_rng", "ick", &rng_ick, CK_343X),
- CLK(NULL, "sha11_ick", &sha11_ick, CK_343X),
- CLK(NULL, "des1_ick", &des1_ick, CK_343X),
+ CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_34XX | CK_36XX),
+ CLK(NULL, "aes1_ick", &aes1_ick, CK_34XX | CK_36XX),
+ CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
- CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2 | CK_AM35XX),
+ CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX),
CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX),
CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX),
CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1),
- CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "cam_mclk", &cam_mclk, CK_343X),
- CLK(NULL, "cam_ick", &cam_ick, CK_343X),
- CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X),
- CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2 | CK_AM35XX),
- CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2),
+ CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
+ CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX),
CLK("omap_wdt", "fck", &wdt2_fck, CK_3XXX),
- CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_343X),
- CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2),
+ CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX),
CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_3XXX),
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_3XXX),
@@ -3424,9 +3432,9 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "atclk_fck", &atclk_fck, CK_3XXX),
CLK(NULL, "traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
CLK(NULL, "traceclk_fck", &traceclk_fck, CK_3XXX),
- CLK(NULL, "sr1_fck", &sr1_fck, CK_343X),
- CLK(NULL, "sr2_fck", &sr2_fck, CK_343X),
- CLK(NULL, "sr_l4_ick", &sr_l4_ick, CK_343X),
+ CLK(NULL, "sr1_fck", &sr1_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sr2_fck", &sr2_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sr_l4_ick", &sr_l4_ick, CK_34XX | CK_36XX),
CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_3XXX),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_3XXX),
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_3XXX),
@@ -3447,38 +3455,37 @@ static struct omap_clk omap3xxx_clks[] = {
int __init omap3xxx_clk_init(void)
{
struct omap_clk *c;
- u32 cpu_clkflg = CK_3XXX;
+ u32 cpu_clkflg = 0;
if (cpu_is_omap3517()) {
- cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS;
- cpu_clkflg |= CK_3517;
+ cpu_mask = RATE_IN_34XX;
+ cpu_clkflg = CK_3517;
} else if (cpu_is_omap3505()) {
- cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS;
- cpu_clkflg |= CK_3505;
+ cpu_mask = RATE_IN_34XX;
+ cpu_clkflg = CK_3505;
+ } else if (cpu_is_omap3630()) {
+ cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
+ cpu_clkflg = CK_36XX;
} else if (cpu_is_omap34xx()) {
- cpu_mask = RATE_IN_3XXX;
- cpu_clkflg |= CK_343X;
-
- /*
- * Update this if there are further clock changes between ES2
- * and production parts
- */
if (omap_rev() == OMAP3430_REV_ES1_0) {
- /* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
- cpu_clkflg |= CK_3430ES1;
+ cpu_mask = RATE_IN_3430ES1;
+ cpu_clkflg = CK_3430ES1;
} else {
- cpu_mask |= RATE_IN_3430ES2PLUS;
- cpu_clkflg |= CK_3430ES2;
+ /*
+ * Assume that anything that we haven't matched yet
+ * has 3430ES2-type clocks.
+ */
+ cpu_mask = RATE_IN_3430ES2PLUS;
+ cpu_clkflg = CK_3430ES2PLUS;
}
+ } else {
+ WARN(1, "clock: could not identify OMAP3 variant\n");
}
if (omap3_has_192mhz_clk())
omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
if (cpu_is_omap3630()) {
- cpu_mask |= RATE_IN_36XX;
- cpu_clkflg |= CK_36XX;
-
/*
* XXX This type of dynamic rewriting of the clock tree is
* deprecated and should be revised soon.
@@ -3525,10 +3532,9 @@ int __init omap3xxx_clk_init(void)
recalculate_root_clocks();
- printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
- "%ld.%01ld/%ld/%ld MHz\n",
- (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
- (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
+ pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
+ (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
+ (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
/*
* Only enable those clocks we will need, let the drivers
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 1599836ba3d9..c426adccad06 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -30,11 +30,18 @@
#include "clock.h"
#include "clock44xx.h"
-#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
#include "cm-regbits-44xx.h"
-#include "prm.h"
+#include "prm44xx.h"
+#include "prm44xx.h"
#include "prm-regbits-44xx.h"
#include "control.h"
+#include "scrm44xx.h"
+
+/* OMAP4 modulemode control */
+#define OMAP4430_MODULEMODE_HWCTRL 0
+#define OMAP4430_MODULEMODE_SWCTRL 1
/* Root clocks */
@@ -47,7 +54,9 @@ static struct clk extalt_clkin_ck = {
static struct clk pad_clks_ck = {
.name = "pad_clks_ck",
.rate = 12000000,
- .ops = &clkops_null,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CLKSEL_ABE,
+ .enable_bit = OMAP4430_PAD_CLKS_GATE_SHIFT,
};
static struct clk pad_slimbus_core_clks_ck = {
@@ -65,7 +74,9 @@ static struct clk secure_32k_clk_src_ck = {
static struct clk slimbus_clk = {
.name = "slimbus_clk",
.rate = 12000000,
- .ops = &clkops_null,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CLKSEL_ABE,
+ .enable_bit = OMAP4430_SLIMBUS_CLK_GATE_SHIFT,
};
static struct clk sys_32k_ck = {
@@ -265,18 +276,71 @@ static struct clk dpll_abe_ck = {
.set_rate = &omap3_noncore_dpll_set_rate,
};
+static struct clk dpll_abe_x2_ck = {
+ .name = "dpll_abe_x2_ck",
+ .parent = &dpll_abe_ck,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate div31_1to31_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 3, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 4, .flags = RATE_IN_4430 },
+ { .div = 5, .val = 5, .flags = RATE_IN_4430 },
+ { .div = 6, .val = 6, .flags = RATE_IN_4430 },
+ { .div = 7, .val = 7, .flags = RATE_IN_4430 },
+ { .div = 8, .val = 8, .flags = RATE_IN_4430 },
+ { .div = 9, .val = 9, .flags = RATE_IN_4430 },
+ { .div = 10, .val = 10, .flags = RATE_IN_4430 },
+ { .div = 11, .val = 11, .flags = RATE_IN_4430 },
+ { .div = 12, .val = 12, .flags = RATE_IN_4430 },
+ { .div = 13, .val = 13, .flags = RATE_IN_4430 },
+ { .div = 14, .val = 14, .flags = RATE_IN_4430 },
+ { .div = 15, .val = 15, .flags = RATE_IN_4430 },
+ { .div = 16, .val = 16, .flags = RATE_IN_4430 },
+ { .div = 17, .val = 17, .flags = RATE_IN_4430 },
+ { .div = 18, .val = 18, .flags = RATE_IN_4430 },
+ { .div = 19, .val = 19, .flags = RATE_IN_4430 },
+ { .div = 20, .val = 20, .flags = RATE_IN_4430 },
+ { .div = 21, .val = 21, .flags = RATE_IN_4430 },
+ { .div = 22, .val = 22, .flags = RATE_IN_4430 },
+ { .div = 23, .val = 23, .flags = RATE_IN_4430 },
+ { .div = 24, .val = 24, .flags = RATE_IN_4430 },
+ { .div = 25, .val = 25, .flags = RATE_IN_4430 },
+ { .div = 26, .val = 26, .flags = RATE_IN_4430 },
+ { .div = 27, .val = 27, .flags = RATE_IN_4430 },
+ { .div = 28, .val = 28, .flags = RATE_IN_4430 },
+ { .div = 29, .val = 29, .flags = RATE_IN_4430 },
+ { .div = 30, .val = 30, .flags = RATE_IN_4430 },
+ { .div = 31, .val = 31, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel dpll_abe_m2x2_div[] = {
+ { .parent = &dpll_abe_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
static struct clk dpll_abe_m2x2_ck = {
.name = "dpll_abe_m2x2_ck",
- .parent = &dpll_abe_ck,
+ .parent = &dpll_abe_x2_ck,
+ .clksel = dpll_abe_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
};
static struct clk abe_24m_fclk = {
.name = "abe_24m_fclk",
.parent = &dpll_abe_m2x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 8,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel_rate div3_1to4_rates[] = {
@@ -326,50 +390,10 @@ static struct clk aess_fclk = {
.set_rate = &omap2_clksel_set_rate,
};
-static const struct clksel_rate div31_1to31_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_4430 },
- { .div = 2, .val = 2, .flags = RATE_IN_4430 },
- { .div = 3, .val = 3, .flags = RATE_IN_4430 },
- { .div = 4, .val = 4, .flags = RATE_IN_4430 },
- { .div = 5, .val = 5, .flags = RATE_IN_4430 },
- { .div = 6, .val = 6, .flags = RATE_IN_4430 },
- { .div = 7, .val = 7, .flags = RATE_IN_4430 },
- { .div = 8, .val = 8, .flags = RATE_IN_4430 },
- { .div = 9, .val = 9, .flags = RATE_IN_4430 },
- { .div = 10, .val = 10, .flags = RATE_IN_4430 },
- { .div = 11, .val = 11, .flags = RATE_IN_4430 },
- { .div = 12, .val = 12, .flags = RATE_IN_4430 },
- { .div = 13, .val = 13, .flags = RATE_IN_4430 },
- { .div = 14, .val = 14, .flags = RATE_IN_4430 },
- { .div = 15, .val = 15, .flags = RATE_IN_4430 },
- { .div = 16, .val = 16, .flags = RATE_IN_4430 },
- { .div = 17, .val = 17, .flags = RATE_IN_4430 },
- { .div = 18, .val = 18, .flags = RATE_IN_4430 },
- { .div = 19, .val = 19, .flags = RATE_IN_4430 },
- { .div = 20, .val = 20, .flags = RATE_IN_4430 },
- { .div = 21, .val = 21, .flags = RATE_IN_4430 },
- { .div = 22, .val = 22, .flags = RATE_IN_4430 },
- { .div = 23, .val = 23, .flags = RATE_IN_4430 },
- { .div = 24, .val = 24, .flags = RATE_IN_4430 },
- { .div = 25, .val = 25, .flags = RATE_IN_4430 },
- { .div = 26, .val = 26, .flags = RATE_IN_4430 },
- { .div = 27, .val = 27, .flags = RATE_IN_4430 },
- { .div = 28, .val = 28, .flags = RATE_IN_4430 },
- { .div = 29, .val = 29, .flags = RATE_IN_4430 },
- { .div = 30, .val = 30, .flags = RATE_IN_4430 },
- { .div = 31, .val = 31, .flags = RATE_IN_4430 },
- { .div = 0 },
-};
-
-static const struct clksel dpll_abe_m3_div[] = {
- { .parent = &dpll_abe_ck, .rates = div31_1to31_rates },
- { .parent = NULL },
-};
-
-static struct clk dpll_abe_m3_ck = {
- .name = "dpll_abe_m3_ck",
- .parent = &dpll_abe_ck,
- .clksel = dpll_abe_m3_div,
+static struct clk dpll_abe_m3x2_ck = {
+ .name = "dpll_abe_m3x2_ck",
+ .parent = &dpll_abe_x2_ck,
+ .clksel = dpll_abe_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_ABE,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
.ops = &clkops_null,
@@ -380,7 +404,7 @@ static struct clk dpll_abe_m3_ck = {
static const struct clksel core_hsd_byp_clk_mux_sel[] = {
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
- { .parent = &dpll_abe_m3_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_abe_m3x2_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
@@ -424,15 +448,22 @@ static struct clk dpll_core_ck = {
.recalc = &omap3_dpll_recalc,
};
-static const struct clksel dpll_core_m6_div[] = {
- { .parent = &dpll_core_ck, .rates = div31_1to31_rates },
+static struct clk dpll_core_x2_ck = {
+ .name = "dpll_core_x2_ck",
+ .parent = &dpll_core_ck,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_core_m6x2_div[] = {
+ { .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
{ .parent = NULL },
};
-static struct clk dpll_core_m6_ck = {
- .name = "dpll_core_m6_ck",
- .parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+static struct clk dpll_core_m6x2_ck = {
+ .name = "dpll_core_m6x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M6_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
.ops = &clkops_null,
@@ -443,7 +474,7 @@ static struct clk dpll_core_m6_ck = {
static const struct clksel dbgclk_mux_sel[] = {
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
- { .parent = &dpll_core_m6_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
@@ -454,10 +485,15 @@ static struct clk dbgclk_mux_ck = {
.recalc = &followparent_recalc,
};
+static const struct clksel dpll_core_m2_div[] = {
+ { .parent = &dpll_core_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
static struct clk dpll_core_m2_ck = {
.name = "dpll_core_m2_ck",
.parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+ .clksel = dpll_core_m2_div,
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_CORE,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_null,
@@ -470,13 +506,14 @@ static struct clk ddrphy_ck = {
.name = "ddrphy_ck",
.parent = &dpll_core_m2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
};
-static struct clk dpll_core_m5_ck = {
- .name = "dpll_core_m5_ck",
- .parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+static struct clk dpll_core_m5x2_ck = {
+ .name = "dpll_core_m5x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_null,
@@ -486,13 +523,13 @@ static struct clk dpll_core_m5_ck = {
};
static const struct clksel div_core_div[] = {
- { .parent = &dpll_core_m5_ck, .rates = div2_1to2_rates },
+ { .parent = &dpll_core_m5x2_ck, .rates = div2_1to2_rates },
{ .parent = NULL },
};
static struct clk div_core_ck = {
.name = "div_core_ck",
- .parent = &dpll_core_m5_ck,
+ .parent = &dpll_core_m5x2_ck,
.clksel = div_core_div,
.clksel_reg = OMAP4430_CM_CLKSEL_CORE,
.clksel_mask = OMAP4430_CLKSEL_CORE_MASK,
@@ -511,13 +548,13 @@ static const struct clksel_rate div4_1to8_rates[] = {
};
static const struct clksel div_iva_hs_clk_div[] = {
- { .parent = &dpll_core_m5_ck, .rates = div4_1to8_rates },
+ { .parent = &dpll_core_m5x2_ck, .rates = div4_1to8_rates },
{ .parent = NULL },
};
static struct clk div_iva_hs_clk = {
.name = "div_iva_hs_clk",
- .parent = &dpll_core_m5_ck,
+ .parent = &dpll_core_m5x2_ck,
.clksel = div_iva_hs_clk_div,
.clksel_reg = OMAP4430_CM_BYPCLK_DPLL_IVA,
.clksel_mask = OMAP4430_CLKSEL_0_1_MASK,
@@ -529,7 +566,7 @@ static struct clk div_iva_hs_clk = {
static struct clk div_mpu_hs_clk = {
.name = "div_mpu_hs_clk",
- .parent = &dpll_core_m5_ck,
+ .parent = &dpll_core_m5x2_ck,
.clksel = div_iva_hs_clk_div,
.clksel_reg = OMAP4430_CM_BYPCLK_DPLL_MPU,
.clksel_mask = OMAP4430_CLKSEL_0_1_MASK,
@@ -539,10 +576,10 @@ static struct clk div_mpu_hs_clk = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_core_m4_ck = {
- .name = "dpll_core_m4_ck",
- .parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+static struct clk dpll_core_m4x2_ck = {
+ .name = "dpll_core_m4x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_null,
@@ -553,15 +590,21 @@ static struct clk dpll_core_m4_ck = {
static struct clk dll_clk_div_ck = {
.name = "dll_clk_div_ck",
- .parent = &dpll_core_m4_ck,
+ .parent = &dpll_core_m4x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel dpll_abe_m2_div[] = {
+ { .parent = &dpll_abe_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
};
static struct clk dpll_abe_m2_ck = {
.name = "dpll_abe_m2_ck",
.parent = &dpll_abe_ck,
- .clksel = dpll_abe_m3_div,
+ .clksel = dpll_abe_m2_div,
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_null,
@@ -570,22 +613,24 @@ static struct clk dpll_abe_m2_ck = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_core_m3_ck = {
- .name = "dpll_core_m3_ck",
- .parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+static struct clk dpll_core_m3x2_ck = {
+ .name = "dpll_core_m3x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
- .ops = &clkops_null,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
+ .enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
.recalc = &omap2_clksel_recalc,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_core_m7_ck = {
- .name = "dpll_core_m7_ck",
- .parent = &dpll_core_ck,
- .clksel = dpll_core_m6_div,
+static struct clk dpll_core_m7x2_ck = {
+ .name = "dpll_core_m7x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
.clksel_reg = OMAP4430_CM_DIV_M7_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
.ops = &clkops_null,
@@ -603,8 +648,12 @@ static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
static struct clk iva_hsd_byp_clk_mux_ck = {
.name = "iva_hsd_byp_clk_mux_ck",
.parent = &sys_clkin_ck,
+ .clksel = iva_hsd_byp_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_IVA,
+ .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
};
/* DPLL_IVA */
@@ -638,15 +687,22 @@ static struct clk dpll_iva_ck = {
.set_rate = &omap3_noncore_dpll_set_rate,
};
-static const struct clksel dpll_iva_m4_div[] = {
- { .parent = &dpll_iva_ck, .rates = div31_1to31_rates },
+static struct clk dpll_iva_x2_ck = {
+ .name = "dpll_iva_x2_ck",
+ .parent = &dpll_iva_ck,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_iva_m4x2_div[] = {
+ { .parent = &dpll_iva_x2_ck, .rates = div31_1to31_rates },
{ .parent = NULL },
};
-static struct clk dpll_iva_m4_ck = {
- .name = "dpll_iva_m4_ck",
- .parent = &dpll_iva_ck,
- .clksel = dpll_iva_m4_div,
+static struct clk dpll_iva_m4x2_ck = {
+ .name = "dpll_iva_m4x2_ck",
+ .parent = &dpll_iva_x2_ck,
+ .clksel = dpll_iva_m4x2_div,
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_IVA,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_null,
@@ -655,10 +711,10 @@ static struct clk dpll_iva_m4_ck = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_iva_m5_ck = {
- .name = "dpll_iva_m5_ck",
- .parent = &dpll_iva_ck,
- .clksel = dpll_iva_m4_div,
+static struct clk dpll_iva_m5x2_ck = {
+ .name = "dpll_iva_m5x2_ck",
+ .parent = &dpll_iva_x2_ck,
+ .clksel = dpll_iva_m4x2_div,
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_IVA,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_null,
@@ -717,9 +773,10 @@ static struct clk dpll_mpu_m2_ck = {
static struct clk per_hs_clk_div_ck = {
.name = "per_hs_clk_div_ck",
- .parent = &dpll_abe_m3_ck,
+ .parent = &dpll_abe_m3x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel per_hsd_byp_clk_mux_sel[] = {
@@ -787,29 +844,48 @@ static struct clk dpll_per_m2_ck = {
.set_rate = &omap2_clksel_set_rate,
};
+static struct clk dpll_per_x2_ck = {
+ .name = "dpll_per_x2_ck",
+ .parent = &dpll_per_ck,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_per_m2x2_div[] = {
+ { .parent = &dpll_per_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
static struct clk dpll_per_m2x2_ck = {
.name = "dpll_per_m2x2_ck",
- .parent = &dpll_per_ck,
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_per_m3_ck = {
- .name = "dpll_per_m3_ck",
- .parent = &dpll_per_ck,
- .clksel = dpll_per_m2_div,
+static struct clk dpll_per_m3x2_ck = {
+ .name = "dpll_per_m3x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
- .ops = &clkops_null,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
+ .enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
.recalc = &omap2_clksel_recalc,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_per_m4_ck = {
- .name = "dpll_per_m4_ck",
- .parent = &dpll_per_ck,
- .clksel = dpll_per_m2_div,
+static struct clk dpll_per_m4x2_ck = {
+ .name = "dpll_per_m4x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_null,
@@ -818,10 +894,10 @@ static struct clk dpll_per_m4_ck = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_per_m5_ck = {
- .name = "dpll_per_m5_ck",
- .parent = &dpll_per_ck,
- .clksel = dpll_per_m2_div,
+static struct clk dpll_per_m5x2_ck = {
+ .name = "dpll_per_m5x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_null,
@@ -830,10 +906,10 @@ static struct clk dpll_per_m5_ck = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_per_m6_ck = {
- .name = "dpll_per_m6_ck",
- .parent = &dpll_per_ck,
- .clksel = dpll_per_m2_div,
+static struct clk dpll_per_m6x2_ck = {
+ .name = "dpll_per_m6x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M6_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
.ops = &clkops_null,
@@ -842,10 +918,10 @@ static struct clk dpll_per_m6_ck = {
.set_rate = &omap2_clksel_set_rate,
};
-static struct clk dpll_per_m7_ck = {
- .name = "dpll_per_m7_ck",
- .parent = &dpll_per_ck,
- .clksel = dpll_per_m2_div,
+static struct clk dpll_per_m7x2_ck = {
+ .name = "dpll_per_m7x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M7_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
.ops = &clkops_null,
@@ -868,6 +944,7 @@ static struct dpll_data dpll_unipro_dd = {
.enable_mask = OMAP4430_DPLL_EN_MASK,
.autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
.idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .sddiv_mask = OMAP4430_DPLL_SD_DIV_MASK,
.max_multiplier = OMAP4430_MAX_DPLL_MULT,
.max_divider = OMAP4430_MAX_DPLL_DIV,
.min_divider = 1,
@@ -885,14 +962,21 @@ static struct clk dpll_unipro_ck = {
.set_rate = &omap3_noncore_dpll_set_rate,
};
+static struct clk dpll_unipro_x2_ck = {
+ .name = "dpll_unipro_x2_ck",
+ .parent = &dpll_unipro_ck,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
static const struct clksel dpll_unipro_m2x2_div[] = {
- { .parent = &dpll_unipro_ck, .rates = div31_1to31_rates },
+ { .parent = &dpll_unipro_x2_ck, .rates = div31_1to31_rates },
{ .parent = NULL },
};
static struct clk dpll_unipro_m2x2_ck = {
.name = "dpll_unipro_m2x2_ck",
- .parent = &dpll_unipro_ck,
+ .parent = &dpll_unipro_x2_ck,
.clksel = dpll_unipro_m2x2_div,
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_UNIPRO,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
@@ -904,16 +988,17 @@ static struct clk dpll_unipro_m2x2_ck = {
static struct clk usb_hs_clk_div_ck = {
.name = "usb_hs_clk_div_ck",
- .parent = &dpll_abe_m3_ck,
+ .parent = &dpll_abe_m3x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 3,
+ .recalc = &omap_fixed_divisor_recalc,
};
/* DPLL_USB */
static struct dpll_data dpll_usb_dd = {
.mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB,
.clk_bypass = &usb_hs_clk_div_ck,
- .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL,
+ .flags = DPLL_J_TYPE,
.clk_ref = &sys_clkin_ck,
.control_reg = OMAP4430_CM_CLKMODE_DPLL_USB,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
@@ -967,7 +1052,7 @@ static struct clk dpll_usb_m2_ck = {
static const struct clksel ducati_clk_mux_sel[] = {
{ .parent = &div_core_ck, .rates = div_1_0_rates },
- { .parent = &dpll_per_m6_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_per_m6x2_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
@@ -986,21 +1071,24 @@ static struct clk func_12m_fclk = {
.name = "func_12m_fclk",
.parent = &dpll_per_m2x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 16,
+ .recalc = &omap_fixed_divisor_recalc,
};
static struct clk func_24m_clk = {
.name = "func_24m_clk",
.parent = &dpll_per_m2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
};
static struct clk func_24mc_fclk = {
.name = "func_24mc_fclk",
.parent = &dpll_per_m2x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 8,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel_rate div2_4to8_rates[] = {
@@ -1030,7 +1118,8 @@ static struct clk func_48mc_fclk = {
.name = "func_48mc_fclk",
.parent = &dpll_per_m2x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel_rate div2_2to4_rates[] = {
@@ -1040,13 +1129,13 @@ static const struct clksel_rate div2_2to4_rates[] = {
};
static const struct clksel func_64m_fclk_div[] = {
- { .parent = &dpll_per_m4_ck, .rates = div2_2to4_rates },
+ { .parent = &dpll_per_m4x2_ck, .rates = div2_2to4_rates },
{ .parent = NULL },
};
static struct clk func_64m_fclk = {
.name = "func_64m_fclk",
- .parent = &dpll_per_m4_ck,
+ .parent = &dpll_per_m4x2_ck,
.clksel = func_64m_fclk_div,
.clksel_reg = OMAP4430_CM_SCALE_FCLK,
.clksel_mask = OMAP4430_SCALE_FCLK_MASK,
@@ -1147,7 +1236,8 @@ static struct clk lp_clk_div_ck = {
.name = "lp_clk_div_ck",
.parent = &dpll_abe_m2x2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 16,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel l4_wkup_clk_mux_sel[] = {
@@ -1215,12 +1305,13 @@ static struct clk per_abe_24m_fclk = {
.name = "per_abe_24m_fclk",
.parent = &dpll_abe_m2_ck,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
};
static const struct clksel pmd_stm_clock_mux_sel[] = {
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
- { .parent = &dpll_core_m6_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
{ .parent = &tie_low_clock_ck, .rates = div_1_2_rates },
{ .parent = NULL },
};
@@ -1354,7 +1445,7 @@ static struct clk dsp_fck = {
.enable_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "tesla_clkdm",
- .parent = &dpll_iva_m4_ck,
+ .parent = &dpll_iva_m4x2_ck,
.recalc = &followparent_recalc,
};
@@ -1384,7 +1475,7 @@ static struct clk dss_dss_clk = {
.enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
.enable_bit = OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
.clkdm_name = "l3_dss_clkdm",
- .parent = &dpll_per_m5_ck,
+ .parent = &dpll_per_m5x2_ck,
.recalc = &followparent_recalc,
};
@@ -1441,14 +1532,14 @@ static struct clk emif2_fck = {
};
static const struct clksel fdif_fclk_div[] = {
- { .parent = &dpll_per_m4_ck, .rates = div3_1to4_rates },
+ { .parent = &dpll_per_m4x2_ck, .rates = div3_1to4_rates },
{ .parent = NULL },
};
/* Merged fdif_fclk into fdif */
static struct clk fdif_fck = {
.name = "fdif_fck",
- .parent = &dpll_per_m4_ck,
+ .parent = &dpll_per_m4x2_ck,
.clksel = fdif_fclk_div,
.clksel_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_FCLK_MASK,
@@ -1602,15 +1693,15 @@ static struct clk gpmc_ick = {
};
static const struct clksel sgx_clk_mux_sel[] = {
- { .parent = &dpll_core_m7_ck, .rates = div_1_0_rates },
- { .parent = &dpll_per_m7_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },
{ .parent = NULL },
};
/* Merged sgx_clk_mux into gpu */
static struct clk gpu_fck = {
.name = "gpu_fck",
- .parent = &dpll_core_m7_ck,
+ .parent = &dpll_core_m7x2_ck,
.clksel = sgx_clk_mux_sel,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
@@ -1729,7 +1820,7 @@ static struct clk iva_fck = {
.enable_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "ivahd_clkdm",
- .parent = &dpll_iva_m5_ck,
+ .parent = &dpll_iva_m5x2_ck,
.recalc = &followparent_recalc,
};
@@ -1749,6 +1840,7 @@ static struct clk l3_instr_ick = {
.enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
.parent = &l3_div_ck,
.recalc = &followparent_recalc,
};
@@ -1759,6 +1851,7 @@ static struct clk l3_main_3_ick = {
.enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
.parent = &l3_div_ck,
.recalc = &followparent_recalc,
};
@@ -2063,6 +2156,7 @@ static struct clk ocp_wp_noc_ick = {
.enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
.parent = &l3_div_ck,
.recalc = &followparent_recalc,
};
@@ -2093,7 +2187,7 @@ static struct clk sl2if_ick = {
.enable_reg = OMAP4430_CM_IVAHD_SL2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
.clkdm_name = "ivahd_clkdm",
- .parent = &dpll_iva_m5_ck,
+ .parent = &dpll_iva_m5x2_ck,
.recalc = &followparent_recalc,
};
@@ -2438,36 +2532,6 @@ static struct clk usb_host_fs_fck = {
.recalc = &followparent_recalc,
};
-static struct clk usb_host_hs_utmi_p3_clk = {
- .name = "usb_host_hs_utmi_p3_clk",
- .ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
- .clkdm_name = "l3_init_clkdm",
- .parent = &init_60m_fclk,
- .recalc = &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic60m_p1_clk = {
- .name = "usb_host_hs_hsic60m_p1_clk",
- .ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
- .clkdm_name = "l3_init_clkdm",
- .parent = &init_60m_fclk,
- .recalc = &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic60m_p2_clk = {
- .name = "usb_host_hs_hsic60m_p2_clk",
- .ops = &clkops_omap2_dflt,
- .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
- .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
- .clkdm_name = "l3_init_clkdm",
- .parent = &init_60m_fclk,
- .recalc = &followparent_recalc,
-};
-
static const struct clksel utmi_p1_gfclk_sel[] = {
{ .parent = &init_60m_fclk, .rates = div_1_0_rates },
{ .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
@@ -2522,6 +2586,16 @@ static struct clk usb_host_hs_utmi_p2_clk = {
.recalc = &followparent_recalc,
};
+static struct clk usb_host_hs_utmi_p3_clk = {
+ .name = "usb_host_hs_utmi_p3_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
static struct clk usb_host_hs_hsic480m_p1_clk = {
.name = "usb_host_hs_hsic480m_p1_clk",
.ops = &clkops_omap2_dflt,
@@ -2532,6 +2606,26 @@ static struct clk usb_host_hs_hsic480m_p1_clk = {
.recalc = &followparent_recalc,
};
+static struct clk usb_host_hs_hsic60m_p1_clk = {
+ .name = "usb_host_hs_hsic60m_p1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_hsic60m_p2_clk = {
+ .name = "usb_host_hs_hsic60m_p2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
static struct clk usb_host_hs_hsic480m_p2_clk = {
.name = "usb_host_hs_hsic480m_p2_clk",
.ops = &clkops_omap2_dflt,
@@ -2656,13 +2750,13 @@ static const struct clksel_rate div2_14to18_rates[] = {
};
static const struct clksel usim_fclk_div[] = {
- { .parent = &dpll_per_m4_ck, .rates = div2_14to18_rates },
+ { .parent = &dpll_per_m4x2_ck, .rates = div2_14to18_rates },
{ .parent = NULL },
};
static struct clk usim_ck = {
.name = "usim_ck",
- .parent = &dpll_per_m4_ck,
+ .parent = &dpll_per_m4x2_ck,
.clksel = usim_fclk_div,
.clksel_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
.clksel_mask = OMAP4430_CLKSEL_DIV_MASK,
@@ -2747,6 +2841,168 @@ static struct clk trace_clk_div_ck = {
.set_rate = &omap2_clksel_set_rate,
};
+/* SCRM aux clk nodes */
+
+static const struct clksel auxclk_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk0_ck = {
+ .name = "auxclk0_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK0,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK0,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk1_ck = {
+ .name = "auxclk1_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK1,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK1,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk2_ck = {
+ .name = "auxclk2_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK2,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK2,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+static struct clk auxclk3_ck = {
+ .name = "auxclk3_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK3,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK3,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk4_ck = {
+ .name = "auxclk4_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK4,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK4,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk5_ck = {
+ .name = "auxclk5_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK5,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK5,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static const struct clksel auxclkreq_sel[] = {
+ { .parent = &auxclk0_ck, .rates = div_1_0_rates },
+ { .parent = &auxclk1_ck, .rates = div_1_1_rates },
+ { .parent = &auxclk2_ck, .rates = div_1_2_rates },
+ { .parent = &auxclk3_ck, .rates = div_1_3_rates },
+ { .parent = &auxclk4_ck, .rates = div_1_4_rates },
+ { .parent = &auxclk5_ck, .rates = div_1_5_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclkreq0_ck = {
+ .name = "auxclkreq0_ck",
+ .parent = &auxclk0_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ0,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq1_ck = {
+ .name = "auxclkreq1_ck",
+ .parent = &auxclk1_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ1,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq2_ck = {
+ .name = "auxclkreq2_ck",
+ .parent = &auxclk2_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ2,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq3_ck = {
+ .name = "auxclkreq3_ck",
+ .parent = &auxclk3_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ3,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq4_ck = {
+ .name = "auxclkreq4_ck",
+ .parent = &auxclk4_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ4,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq5_ck = {
+ .name = "auxclkreq5_ck",
+ .parent = &auxclk5_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ5,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
/*
* clkdev
*/
@@ -2774,43 +3030,48 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "abe_dpll_bypass_clk_mux_ck", &abe_dpll_bypass_clk_mux_ck, CK_443X),
CLK(NULL, "abe_dpll_refclk_mux_ck", &abe_dpll_refclk_mux_ck, CK_443X),
CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_443X),
+ CLK(NULL, "dpll_abe_x2_ck", &dpll_abe_x2_ck, CK_443X),
CLK(NULL, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, CK_443X),
CLK(NULL, "abe_24m_fclk", &abe_24m_fclk, CK_443X),
CLK(NULL, "abe_clk", &abe_clk, CK_443X),
CLK(NULL, "aess_fclk", &aess_fclk, CK_443X),
- CLK(NULL, "dpll_abe_m3_ck", &dpll_abe_m3_ck, CK_443X),
+ CLK(NULL, "dpll_abe_m3x2_ck", &dpll_abe_m3x2_ck, CK_443X),
CLK(NULL, "core_hsd_byp_clk_mux_ck", &core_hsd_byp_clk_mux_ck, CK_443X),
CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_443X),
- CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_443X),
+ CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_443X),
+ CLK(NULL, "dpll_core_m6x2_ck", &dpll_core_m6x2_ck, CK_443X),
CLK(NULL, "dbgclk_mux_ck", &dbgclk_mux_ck, CK_443X),
CLK(NULL, "dpll_core_m2_ck", &dpll_core_m2_ck, CK_443X),
CLK(NULL, "ddrphy_ck", &ddrphy_ck, CK_443X),
- CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_443X),
+ CLK(NULL, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, CK_443X),
CLK(NULL, "div_core_ck", &div_core_ck, CK_443X),
CLK(NULL, "div_iva_hs_clk", &div_iva_hs_clk, CK_443X),
CLK(NULL, "div_mpu_hs_clk", &div_mpu_hs_clk, CK_443X),
- CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck, CK_443X),
+ CLK(NULL, "dpll_core_m4x2_ck", &dpll_core_m4x2_ck, CK_443X),
CLK(NULL, "dll_clk_div_ck", &dll_clk_div_ck, CK_443X),
CLK(NULL, "dpll_abe_m2_ck", &dpll_abe_m2_ck, CK_443X),
- CLK(NULL, "dpll_core_m3_ck", &dpll_core_m3_ck, CK_443X),
- CLK(NULL, "dpll_core_m7_ck", &dpll_core_m7_ck, CK_443X),
+ CLK(NULL, "dpll_core_m3x2_ck", &dpll_core_m3x2_ck, CK_443X),
+ CLK(NULL, "dpll_core_m7x2_ck", &dpll_core_m7x2_ck, CK_443X),
CLK(NULL, "iva_hsd_byp_clk_mux_ck", &iva_hsd_byp_clk_mux_ck, CK_443X),
CLK(NULL, "dpll_iva_ck", &dpll_iva_ck, CK_443X),
- CLK(NULL, "dpll_iva_m4_ck", &dpll_iva_m4_ck, CK_443X),
- CLK(NULL, "dpll_iva_m5_ck", &dpll_iva_m5_ck, CK_443X),
+ CLK(NULL, "dpll_iva_x2_ck", &dpll_iva_x2_ck, CK_443X),
+ CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_443X),
+ CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_443X),
CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X),
CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X),
CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_443X),
CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_443X),
CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_443X),
CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_443X),
+ CLK(NULL, "dpll_per_x2_ck", &dpll_per_x2_ck, CK_443X),
CLK(NULL, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, CK_443X),
- CLK(NULL, "dpll_per_m3_ck", &dpll_per_m3_ck, CK_443X),
- CLK(NULL, "dpll_per_m4_ck", &dpll_per_m4_ck, CK_443X),
- CLK(NULL, "dpll_per_m5_ck", &dpll_per_m5_ck, CK_443X),
- CLK(NULL, "dpll_per_m6_ck", &dpll_per_m6_ck, CK_443X),
- CLK(NULL, "dpll_per_m7_ck", &dpll_per_m7_ck, CK_443X),
+ CLK(NULL, "dpll_per_m3x2_ck", &dpll_per_m3x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m6x2_ck", &dpll_per_m6x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m7x2_ck", &dpll_per_m7x2_ck, CK_443X),
CLK(NULL, "dpll_unipro_ck", &dpll_unipro_ck, CK_443X),
+ CLK(NULL, "dpll_unipro_x2_ck", &dpll_unipro_x2_ck, CK_443X),
CLK(NULL, "dpll_unipro_m2x2_ck", &dpll_unipro_m2x2_ck, CK_443X),
CLK(NULL, "usb_hs_clk_div_ck", &usb_hs_clk_div_ck, CK_443X),
CLK(NULL, "dpll_usb_ck", &dpll_usb_ck, CK_443X),
@@ -2856,26 +3117,26 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
CLK(NULL, "fdif_fck", &fdif_fck, CK_443X),
CLK(NULL, "fpka_fck", &fpka_fck, CK_443X),
- CLK(NULL, "gpio1_dbck", &gpio1_dbclk, CK_443X),
+ CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X),
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X),
- CLK(NULL, "gpio2_dbck", &gpio2_dbclk, CK_443X),
+ CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X),
CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X),
- CLK(NULL, "gpio3_dbck", &gpio3_dbclk, CK_443X),
+ CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X),
CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X),
- CLK(NULL, "gpio4_dbck", &gpio4_dbclk, CK_443X),
+ CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X),
CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X),
- CLK(NULL, "gpio5_dbck", &gpio5_dbclk, CK_443X),
+ CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X),
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X),
- CLK(NULL, "gpio6_dbck", &gpio6_dbclk, CK_443X),
+ CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X),
CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X),
CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X),
CLK(NULL, "gpu_fck", &gpu_fck, CK_443X),
CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_443X),
CLK(NULL, "hsi_fck", &hsi_fck, CK_443X),
- CLK("i2c_omap.1", "fck", &i2c1_fck, CK_443X),
- CLK("i2c_omap.2", "fck", &i2c2_fck, CK_443X),
- CLK("i2c_omap.3", "fck", &i2c3_fck, CK_443X),
- CLK("i2c_omap.4", "fck", &i2c4_fck, CK_443X),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_443X),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_443X),
+ CLK("omap_i2c.3", "fck", &i2c3_fck, CK_443X),
+ CLK("omap_i2c.4", "fck", &i2c4_fck, CK_443X),
CLK(NULL, "ipu_fck", &ipu_fck, CK_443X),
CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X),
CLK(NULL, "iss_fck", &iss_fck, CK_443X),
@@ -2937,14 +3198,14 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
- CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X),
- CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
CLK(NULL, "usb_host_hs_utmi_p2_clk", &usb_host_hs_utmi_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X),
CLK(NULL, "usb_host_hs_hsic480m_p1_clk", &usb_host_hs_hsic480m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
@@ -2960,6 +3221,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
CLK(NULL, "usim_fck", &usim_fck, CK_443X),
CLK("omap_wdt", "fck", &wd_timer2_fck, CK_443X),
+ CLK(NULL, "mailboxes_ick", &dummy_ck, CK_443X),
CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X),
CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X),
CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_443X),
@@ -2975,10 +3237,10 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "gpt9_ick", &dummy_ck, CK_443X),
CLK(NULL, "gpt10_ick", &dummy_ck, CK_443X),
CLK(NULL, "gpt11_ick", &dummy_ck, CK_443X),
- CLK("i2c_omap.1", "ick", &dummy_ck, CK_443X),
- CLK("i2c_omap.2", "ick", &dummy_ck, CK_443X),
- CLK("i2c_omap.3", "ick", &dummy_ck, CK_443X),
- CLK("i2c_omap.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.4", "ick", &dummy_ck, CK_443X),
CLK("mmci-omap-hs.0", "ick", &dummy_ck, CK_443X),
CLK("mmci-omap-hs.1", "ick", &dummy_ck, CK_443X),
CLK("mmci-omap-hs.2", "ick", &dummy_ck, CK_443X),
@@ -2997,6 +3259,18 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
+ CLK(NULL, "auxclk0_ck", &auxclk0_ck, CK_443X),
+ CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_443X),
+ CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_443X),
+ CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_443X),
+ CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_443X),
+ CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X),
+ CLK(NULL, "auxclkreq0_ck", &auxclkreq0_ck, CK_443X),
+ CLK(NULL, "auxclkreq1_ck", &auxclkreq1_ck, CK_443X),
+ CLK(NULL, "auxclkreq2_ck", &auxclkreq2_ck, CK_443X),
+ CLK(NULL, "auxclkreq3_ck", &auxclkreq3_ck, CK_443X),
+ CLK(NULL, "auxclkreq4_ck", &auxclkreq4_ck, CK_443X),
+ CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X),
};
int __init omap4xxx_clk_init(void)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 6fb61b1a0d46..e20b98636ab4 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -13,7 +13,6 @@
*/
#undef DEBUG
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
@@ -27,13 +26,16 @@
#include <linux/bitops.h>
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cminst44xx.h"
+#include "prcm44xx.h"
#include <plat/clock.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
#include <plat/prcm.h>
/* clkdm_list contains all registered struct clockdomains */
@@ -141,6 +143,9 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
* clockdomain is in hardware-supervised mode. Meant to be called
* once at clockdomain layer initialization, since these should remain
* fixed for a particular architecture. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
*/
static void _autodep_lookup(struct clkdm_autodep *autodep)
{
@@ -168,6 +173,9 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)
* Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
* in hardware-supervised mode. Meant to be called from clock framework
* when a clock inside clockdomain 'clkdm' is enabled. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
*/
static void _clkdm_add_autodeps(struct clockdomain *clkdm)
{
@@ -199,6 +207,9 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
* Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
* in hardware-supervised mode. Meant to be called from clock framework
* when a clock inside clockdomain 'clkdm' is disabled. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
*/
static void _clkdm_del_autodeps(struct clockdomain *clkdm)
{
@@ -223,39 +234,56 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
}
}
-/*
- * _omap2_clkdm_set_hwsup - set the hwsup idle transition bit
+/**
+ * _enable_hwsup - place a clockdomain into hardware-supervised idle
* @clkdm: struct clockdomain *
- * @enable: int 0 to disable, 1 to enable
*
- * Internal helper for actually switching the bit that controls hwsup
- * idle transitions for clkdm.
+ * Place the clockdomain into hardware-supervised idle mode. No return
+ * value.
+ *
+ * XXX Should this return an error if the clockdomain does not support
+ * hardware-supervised idle mode?
*/
-static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
+static void _enable_hwsup(struct clockdomain *clkdm)
{
- u32 bits, v;
-
- if (cpu_is_omap24xx()) {
- if (enable)
- bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
- else
- bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
- } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- if (enable)
- bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
- else
- bits = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
- } else {
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap44xx())
+ return omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+ else
BUG();
- }
-
- bits = bits << __ffs(clkdm->clktrctrl_mask);
-
- v = __raw_readl(clkdm->clkstctrl_reg);
- v &= ~(clkdm->clktrctrl_mask);
- v |= bits;
- __raw_writel(v, clkdm->clkstctrl_reg);
+}
+/**
+ * _disable_hwsup - place a clockdomain into software-supervised idle
+ * @clkdm: struct clockdomain *
+ *
+ * Place the clockdomain @clkdm into software-supervised idle mode.
+ * No return value.
+ *
+ * XXX Should this return an error if the clockdomain does not support
+ * software-supervised idle mode?
+ */
+static void _disable_hwsup(struct clockdomain *clkdm)
+{
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap44xx())
+ return omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+ else
+ BUG();
}
/* Public functions */
@@ -409,7 +437,7 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: hardware will wake up %s when %s wakes "
"up\n", clkdm1->name, clkdm2->name);
- prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
}
@@ -444,7 +472,7 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: hardware will no longer wake up %s "
"after %s wakes up\n", clkdm1->name, clkdm2->name);
- prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
}
@@ -480,7 +508,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
}
/* XXX It's faster to return the atomic wkdep_usecount */
- return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
(1 << clkdm2->dep_bit));
}
@@ -514,7 +542,7 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
atomic_set(&cd->wkdep_usecount, 0);
}
- prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
return 0;
}
@@ -553,7 +581,7 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: will prevent %s from sleeping if %s "
"is active\n", clkdm1->name, clkdm2->name);
- cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
clkdm1->pwrdm.ptr->prcm_offs,
OMAP3430_CM_SLEEPDEP);
}
@@ -596,7 +624,7 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
"sleeping if %s is active\n", clkdm1->name,
clkdm2->name);
- cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
clkdm1->pwrdm.ptr->prcm_offs,
OMAP3430_CM_SLEEPDEP);
}
@@ -639,7 +667,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
}
/* XXX It's faster to return the atomic sleepdep_usecount */
- return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
OMAP3430_CM_SLEEPDEP,
(1 << clkdm2->dep_bit));
}
@@ -677,35 +705,13 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
atomic_set(&cd->sleepdep_usecount, 0);
}
- prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
OMAP3430_CM_SLEEPDEP);
return 0;
}
/**
- * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode
- * @clkdm: struct clkdm * of a clockdomain
- *
- * Return the clockdomain @clkdm current state transition mode from the
- * corresponding domain CM_CLKSTCTRL register. Returns -EINVAL if @clkdm
- * is NULL or the current mode upon success.
- */
-static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
-{
- u32 v;
-
- if (!clkdm)
- return -EINVAL;
-
- v = __raw_readl(clkdm->clkstctrl_reg);
- v &= clkdm->clktrctrl_mask;
- v >>= __ffs(clkdm->clktrctrl_mask);
-
- return v;
-}
-
-/**
* omap2_clkdm_sleep - force clockdomain sleep transition
* @clkdm: struct clockdomain *
*
@@ -729,18 +735,19 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
- cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
- } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ } else if (cpu_is_omap34xx()) {
+
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
- u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
- __ffs(clkdm->clktrctrl_mask));
+ } else if (cpu_is_omap44xx()) {
- u32 v = __raw_readl(clkdm->clkstctrl_reg);
- v &= ~(clkdm->clktrctrl_mask);
- v |= bits;
- __raw_writel(v, clkdm->clkstctrl_reg);
+ omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
} else {
BUG();
@@ -773,18 +780,19 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
- cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
- } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ } else if (cpu_is_omap34xx()) {
- u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
- __ffs(clkdm->clktrctrl_mask));
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
- u32 v = __raw_readl(clkdm->clkstctrl_reg);
- v &= ~(clkdm->clktrctrl_mask);
- v |= bits;
- __raw_writel(v, clkdm->clkstctrl_reg);
+ } else if (cpu_is_omap44xx()) {
+
+ omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
} else {
BUG();
@@ -829,7 +837,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
_clkdm_add_autodeps(clkdm);
}
- _omap2_clkdm_set_hwsup(clkdm, 1);
+ _enable_hwsup(clkdm);
pwrdm_clkdm_state_switch(clkdm);
}
@@ -857,7 +865,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
clkdm->name);
- _omap2_clkdm_set_hwsup(clkdm, 0);
+ _disable_hwsup(clkdm);
/*
* XXX This should be removed once TI adds wakeup/sleep
@@ -891,7 +899,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
*/
int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
{
- int v;
+ bool hwsup = false;
/*
* XXX Rewrite this code to maintain a list of enabled
@@ -909,17 +917,27 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
clk->name);
- if (!clkdm->clkstctrl_reg)
- return 0;
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- v = omap2_clkdm_clktrctrl_read(clkdm);
+ if (!clkdm->clktrctrl_mask)
+ return 0;
- if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
- (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ } else if (cpu_is_omap44xx()) {
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+
+ }
+
+ if (hwsup) {
/* Disable HW transitions when we are changing deps */
- _omap2_clkdm_set_hwsup(clkdm, 0);
+ _disable_hwsup(clkdm);
_clkdm_add_autodeps(clkdm);
- _omap2_clkdm_set_hwsup(clkdm, 1);
+ _enable_hwsup(clkdm);
} else {
omap2_clkdm_wakeup(clkdm);
}
@@ -946,7 +964,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
*/
int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{
- int v;
+ bool hwsup = false;
/*
* XXX Rewrite this code to maintain a list of enabled
@@ -971,17 +989,27 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
clk->name);
- if (!clkdm->clkstctrl_reg)
- return 0;
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- v = omap2_clkdm_clktrctrl_read(clkdm);
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ } else if (cpu_is_omap44xx()) {
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs);
+
+ }
- if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
- (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+ if (hwsup) {
/* Disable HW transitions when we are changing deps */
- _omap2_clkdm_set_hwsup(clkdm, 0);
+ _disable_hwsup(clkdm);
_clkdm_del_autodeps(clkdm);
- _omap2_clkdm_set_hwsup(clkdm, 1);
+ _enable_hwsup(clkdm);
} else {
omap2_clkdm_sleep(clkdm);
}
diff --git a/arch/arm/plat-omap/include/plat/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index ba0a6c07c0fe..de3faa20b46b 100644
--- a/arch/arm/plat-omap/include/plat/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -4,19 +4,21 @@
* OMAP2/3 clockdomain framework functions
*
* Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
*
- * Written by Paul Walmsley
+ * Paul Walmsley
*
* This program is free software; you can 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_OMAP_CLOCKDOMAIN_H
-#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
-#include <plat/powerdomain.h>
+#include <linux/init.h>
+
+#include "powerdomain.h"
#include <plat/clock.h>
#include <plat/cpu.h>
@@ -30,16 +32,6 @@
#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
-/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
-#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
-#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
-
-/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
-#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0
-#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1
-#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
-#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
-
/**
* struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
* @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
@@ -90,11 +82,20 @@ struct clkdm_dep {
* @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
* @flags: Clockdomain capability flags
* @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
+ * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers
+ * @cm_inst: (OMAP4 only) CM instance register offset
+ * @clkdm_offs: (OMAP4 only) CM clockdomain register offset
* @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
* @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
* @omap_chip: OMAP chip types that this clockdomain is valid on
* @usecount: Usecount tracking
* @node: list_head to link all clockdomains together
+ *
+ * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only)
+ * @cm_inst should be a macro ending in _INST from the OMAP4 CM instance
+ * definitions (OMAP4 only)
+ * @clkdm_offs should be a macro ending in _CDOFFS from the OMAP4 CM instance
+ * definitions (OMAP4 only)
*/
struct clockdomain {
const char *name;
@@ -102,10 +103,14 @@ struct clockdomain {
const char *name;
struct powerdomain *ptr;
} pwrdm;
- void __iomem *clkstctrl_reg;
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
const u16 clktrctrl_mask;
+#endif
const u8 flags;
const u8 dep_bit;
+ const u8 prcm_partition;
+ const s16 cm_inst;
+ const u16 clkdm_offs;
struct clkdm_dep *wkdep_srcs;
struct clkdm_dep *sleepdep_srcs;
const struct omap_chip_id omap_chip;
@@ -138,4 +143,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm);
int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+extern void __init omap2_clockdomains_init(void);
+extern void __init omap44xx_clockdomains_init(void);
+
#endif
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index 8fc19ff2cd89..e4a7133ea3b3 100644
--- a/arch/arm/mach-omap2/clockdomains.h
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -4,7 +4,7 @@
* Copyright (C) 2008-2009 Texas Instruments, Inc.
* Copyright (C) 2008-2010 Nokia Corporation
*
- * Written by Paul Walmsley and Jouni Högander
+ * Paul Walmsley, Jouni Högander
*
* This file contains clockdomains and clockdomain wakeup/sleep
* dependencies for the OMAP2/3 chips. Some notes:
@@ -32,12 +32,17 @@
* from the Power domain framework
*/
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
+#include <linux/kernel.h>
+#include <linux/io.h>
-#include <plat/clockdomain.h>
-#include "cm.h"
-#include "prm.h"
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
/*
* Clockdomain dependencies for wkdeps/sleepdeps
@@ -84,8 +89,6 @@ static struct clkdm_dep gfx_sgx_wkdeps[] = {
/* 24XX-specific possible dependencies */
-#ifdef CONFIG_ARCH_OMAP2
-
/* Wakeup dependency source arrays */
/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
@@ -165,8 +168,6 @@ static struct clkdm_dep core_24xx_wkdeps[] = {
{ NULL },
};
-#endif
-
/* 2430-specific possible wakeup dependencies */
@@ -425,8 +426,6 @@ static struct clkdm_dep gfx_sgx_sleepdeps[] = {
* sys_clkout/sys_clkout2.
*/
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-
/* This is an implicit clockdomain - it is never defined as such in TRM */
static struct clockdomain wkup_clkdm = {
.name = "wkup_clkdm",
@@ -447,8 +446,6 @@ static struct clockdomain cm_clkdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
-#endif
-
/*
* 2420-only clockdomains
*/
@@ -459,7 +456,6 @@ static struct clockdomain mpu_2420_clkdm = {
.name = "mpu_clkdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = mpu_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -469,8 +465,6 @@ static struct clockdomain iva1_2420_clkdm = {
.name = "iva1_clkdm",
.pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
.wkdep_srcs = dsp_24xx_wkdeps,
.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
@@ -481,8 +475,6 @@ static struct clockdomain dsp_2420_clkdm = {
.name = "dsp_clkdm",
.pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
- OMAP2_CM_CLKSTCTRL),
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
@@ -491,7 +483,6 @@ static struct clockdomain gfx_2420_clkdm = {
.name = "gfx_clkdm",
.pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = gfx_sgx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -501,7 +492,6 @@ static struct clockdomain core_l3_2420_clkdm = {
.name = "core_l3_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = core_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -511,7 +501,6 @@ static struct clockdomain core_l4_2420_clkdm = {
.name = "core_l4_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = core_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -521,7 +510,6 @@ static struct clockdomain dss_2420_clkdm = {
.name = "dss_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
@@ -539,8 +527,6 @@ static struct clockdomain mpu_2430_clkdm = {
.name = "mpu_clkdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(MPU_MOD,
- OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = mpu_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -551,8 +537,6 @@ static struct clockdomain mdm_clkdm = {
.name = "mdm_clkdm",
.pwrdm = { .name = "mdm_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP2430_MDM_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
.wkdep_srcs = mdm_2430_wkdeps,
.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
@@ -563,8 +547,6 @@ static struct clockdomain dsp_2430_clkdm = {
.name = "dsp_clkdm",
.pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP24XX_DSP_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
.wkdep_srcs = dsp_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
@@ -575,7 +557,6 @@ static struct clockdomain gfx_2430_clkdm = {
.name = "gfx_clkdm",
.pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = gfx_sgx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -590,7 +571,6 @@ static struct clockdomain core_l3_2430_clkdm = {
.name = "core_l3_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP24XX_EN_CORE_SHIFT,
.wkdep_srcs = core_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
@@ -606,7 +586,6 @@ static struct clockdomain core_l4_2430_clkdm = {
.name = "core_l4_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP24XX_EN_CORE_SHIFT,
.wkdep_srcs = core_24xx_wkdeps,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
@@ -617,7 +596,6 @@ static struct clockdomain dss_2430_clkdm = {
.name = "dss_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
@@ -635,7 +613,6 @@ static struct clockdomain mpu_3xxx_clkdm = {
.name = "mpu_clkdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_EN_MPU_SHIFT,
.wkdep_srcs = mpu_3xxx_wkdeps,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
@@ -646,8 +623,6 @@ static struct clockdomain neon_clkdm = {
.name = "neon_clkdm",
.pwrdm = { .name = "neon_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_NEON_MOD,
- OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = neon_wkdeps,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -657,8 +632,6 @@ static struct clockdomain iva2_clkdm = {
.name = "iva2_clkdm",
.pwrdm = { .name = "iva2_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
.wkdep_srcs = iva2_wkdeps,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
@@ -669,7 +642,6 @@ static struct clockdomain gfx_3430es1_clkdm = {
.name = "gfx_clkdm",
.pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = gfx_sgx_wkdeps,
.sleepdep_srcs = gfx_sgx_sleepdeps,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
@@ -680,8 +652,6 @@ static struct clockdomain sgx_clkdm = {
.name = "sgx_clkdm",
.pwrdm = { .name = "sgx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_SGX_MOD,
- OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = gfx_sgx_wkdeps,
.sleepdep_srcs = gfx_sgx_sleepdeps,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
@@ -699,7 +669,6 @@ static struct clockdomain d2d_clkdm = {
.name = "d2d_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
@@ -713,7 +682,6 @@ static struct clockdomain core_l3_3xxx_clkdm = {
.name = "core_l3_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_EN_CORE_SHIFT,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -728,7 +696,6 @@ static struct clockdomain core_l4_3xxx_clkdm = {
.name = "core_l4_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_EN_CORE_SHIFT,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -739,8 +706,6 @@ static struct clockdomain dss_3xxx_clkdm = {
.name = "dss_clkdm",
.pwrdm = { .name = "dss_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
.wkdep_srcs = dss_wkdeps,
.sleepdep_srcs = dss_sleepdeps,
@@ -752,8 +717,6 @@ static struct clockdomain cam_clkdm = {
.name = "cam_clkdm",
.pwrdm = { .name = "cam_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD,
- OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = cam_wkdeps,
.sleepdep_srcs = cam_sleepdeps,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
@@ -764,8 +727,6 @@ static struct clockdomain usbhost_clkdm = {
.name = "usbhost_clkdm",
.pwrdm = { .name = "usbhost_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD,
- OMAP2_CM_CLKSTCTRL),
.wkdep_srcs = usbhost_wkdeps,
.sleepdep_srcs = usbhost_sleepdeps,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
@@ -776,8 +737,6 @@ static struct clockdomain per_clkdm = {
.name = "per_clkdm",
.pwrdm = { .name = "per_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD,
- OMAP2_CM_CLKSTCTRL),
.dep_bit = OMAP3430_EN_PER_SHIFT,
.wkdep_srcs = per_wkdeps,
.sleepdep_srcs = per_sleepdeps,
@@ -793,8 +752,6 @@ static struct clockdomain emu_clkdm = {
.name = "emu_clkdm",
.pwrdm = { .name = "emu_pwrdm" },
.flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
- .clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_EMU_MOD,
- OMAP2_CM_CLKSTCTRL),
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
@@ -831,8 +788,6 @@ static struct clockdomain dpll5_clkdm = {
#endif /* CONFIG_ARCH_OMAP3 */
-#include "clockdomains44xx.h"
-
/*
* Clockdomain hwsup dependencies (OMAP3 only)
*/
@@ -851,17 +806,10 @@ static struct clkdm_autodep clkdm_autodeps[] = {
}
};
-/*
- * List of clockdomain pointers per platform
- */
-
-static struct clockdomain *clockdomains_omap[] = {
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+static struct clockdomain *clockdomains_omap2[] __initdata = {
&wkup_clkdm,
&cm_clkdm,
&prm_clkdm,
-#endif
#ifdef CONFIG_ARCH_OMAP2420
&mpu_2420_clkdm,
@@ -903,35 +851,10 @@ static struct clockdomain *clockdomains_omap[] = {
&dpll4_clkdm,
&dpll5_clkdm,
#endif
-
-#ifdef CONFIG_ARCH_OMAP4
- &l4_cefuse_44xx_clkdm,
- &l4_cfg_44xx_clkdm,
- &tesla_44xx_clkdm,
- &l3_gfx_44xx_clkdm,
- &ivahd_44xx_clkdm,
- &l4_secure_44xx_clkdm,
- &l4_per_44xx_clkdm,
- &abe_44xx_clkdm,
- &l3_instr_44xx_clkdm,
- &l3_init_44xx_clkdm,
- &mpuss_44xx_clkdm,
- &mpu0_44xx_clkdm,
- &mpu1_44xx_clkdm,
- &l3_emif_44xx_clkdm,
- &l4_ao_44xx_clkdm,
- &ducati_44xx_clkdm,
- &l3_2_44xx_clkdm,
- &l3_1_44xx_clkdm,
- &l3_d2d_44xx_clkdm,
- &iss_44xx_clkdm,
- &l3_dss_44xx_clkdm,
- &l4_wkup_44xx_clkdm,
- &emu_sys_44xx_clkdm,
- &l3_dma_44xx_clkdm,
-#endif
-
NULL,
};
-#endif
+void __init omap2_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap2, clkdm_autodeps);
+}
diff --git a/arch/arm/mach-omap2/clockdomains44xx.h b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 7e5ba0f67925..51920fc7fc52 100644
--- a/arch/arm/mach-omap2/clockdomains44xx.h
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -23,18 +23,27 @@
* -> Populate the Sleep/Wakeup dependencies for the domains
*/
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
+#include <linux/kernel.h>
+#include <linux/io.h>
-#include <plat/clockdomain.h>
+#include "clockdomain.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu44xx.h"
-#if defined(CONFIG_ARCH_OMAP4)
static struct clockdomain l4_cefuse_44xx_clkdm = {
.name = "l4_cefuse_clkdm",
.pwrdm = { .name = "cefuse_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_CEFUSE_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CEFUSE_INST,
+ .clkdm_offs = OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -42,8 +51,9 @@ static struct clockdomain l4_cefuse_44xx_clkdm = {
static struct clockdomain l4_cfg_44xx_clkdm = {
.name = "l4_cfg_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L4CFG_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -51,8 +61,9 @@ static struct clockdomain l4_cfg_44xx_clkdm = {
static struct clockdomain tesla_44xx_clkdm = {
.name = "tesla_clkdm",
.pwrdm = { .name = "tesla_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_TESLA_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_TESLA_INST,
+ .clkdm_offs = OMAP4430_CM1_TESLA_TESLA_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -60,8 +71,9 @@ static struct clockdomain tesla_44xx_clkdm = {
static struct clockdomain l3_gfx_44xx_clkdm = {
.name = "l3_gfx_clkdm",
.pwrdm = { .name = "gfx_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_GFX_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_GFX_INST,
+ .clkdm_offs = OMAP4430_CM2_GFX_GFX_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -69,8 +81,9 @@ static struct clockdomain l3_gfx_44xx_clkdm = {
static struct clockdomain ivahd_44xx_clkdm = {
.name = "ivahd_clkdm",
.pwrdm = { .name = "ivahd_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_IVAHD_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_IVAHD_INST,
+ .clkdm_offs = OMAP4430_CM2_IVAHD_IVAHD_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -78,8 +91,9 @@ static struct clockdomain ivahd_44xx_clkdm = {
static struct clockdomain l4_secure_44xx_clkdm = {
.name = "l4_secure_clkdm",
.pwrdm = { .name = "l4per_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L4SEC_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L4PER_INST,
+ .clkdm_offs = OMAP4430_CM2_L4PER_L4SEC_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -87,8 +101,9 @@ static struct clockdomain l4_secure_44xx_clkdm = {
static struct clockdomain l4_per_44xx_clkdm = {
.name = "l4_per_clkdm",
.pwrdm = { .name = "l4per_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L4PER_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L4PER_INST,
+ .clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -96,8 +111,9 @@ static struct clockdomain l4_per_44xx_clkdm = {
static struct clockdomain abe_44xx_clkdm = {
.name = "abe_clkdm",
.pwrdm = { .name = "abe_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM1_ABE_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_ABE_INST,
+ .clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -105,16 +121,18 @@ static struct clockdomain abe_44xx_clkdm = {
static struct clockdomain l3_instr_44xx_clkdm = {
.name = "l3_instr_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L3INSTR_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3INSTR_CDOFFS,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_init_44xx_clkdm = {
.name = "l3_init_clkdm",
.pwrdm = { .name = "l3init_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L3INIT_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L3INIT_INST,
+ .clkdm_offs = OMAP4430_CM2_L3INIT_L3INIT_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -122,8 +140,9 @@ static struct clockdomain l3_init_44xx_clkdm = {
static struct clockdomain mpuss_44xx_clkdm = {
.name = "mpuss_clkdm",
.pwrdm = { .name = "mpu_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_MPU_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_MPU_INST,
+ .clkdm_offs = OMAP4430_CM1_MPU_MPU_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -131,8 +150,9 @@ static struct clockdomain mpuss_44xx_clkdm = {
static struct clockdomain mpu0_44xx_clkdm = {
.name = "mpu0_clkdm",
.pwrdm = { .name = "cpu0_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_CPU0_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP4430_PRCM_MPU_CPU0_INST,
+ .clkdm_offs = OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -140,8 +160,9 @@ static struct clockdomain mpu0_44xx_clkdm = {
static struct clockdomain mpu1_44xx_clkdm = {
.name = "mpu1_clkdm",
.pwrdm = { .name = "cpu1_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_CPU1_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP4430_PRCM_MPU_CPU1_INST,
+ .clkdm_offs = OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -149,8 +170,9 @@ static struct clockdomain mpu1_44xx_clkdm = {
static struct clockdomain l3_emif_44xx_clkdm = {
.name = "l3_emif_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_MEMIF_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -158,8 +180,9 @@ static struct clockdomain l3_emif_44xx_clkdm = {
static struct clockdomain l4_ao_44xx_clkdm = {
.name = "l4_ao_clkdm",
.pwrdm = { .name = "always_on_core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_ALWON_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_ALWAYS_ON_INST,
+ .clkdm_offs = OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -167,8 +190,9 @@ static struct clockdomain l4_ao_44xx_clkdm = {
static struct clockdomain ducati_44xx_clkdm = {
.name = "ducati_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_DUCATI_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_DUCATI_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -176,8 +200,9 @@ static struct clockdomain ducati_44xx_clkdm = {
static struct clockdomain l3_2_44xx_clkdm = {
.name = "l3_2_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L3_2_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -185,8 +210,9 @@ static struct clockdomain l3_2_44xx_clkdm = {
static struct clockdomain l3_1_44xx_clkdm = {
.name = "l3_1_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_L3_1_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -194,8 +220,9 @@ static struct clockdomain l3_1_44xx_clkdm = {
static struct clockdomain l3_d2d_44xx_clkdm = {
.name = "l3_d2d_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_D2D_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_D2D_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -203,8 +230,9 @@ static struct clockdomain l3_d2d_44xx_clkdm = {
static struct clockdomain iss_44xx_clkdm = {
.name = "iss_clkdm",
.pwrdm = { .name = "cam_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_CAM_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CAM_INST,
+ .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -212,8 +240,9 @@ static struct clockdomain iss_44xx_clkdm = {
static struct clockdomain l3_dss_44xx_clkdm = {
.name = "l3_dss_clkdm",
.pwrdm = { .name = "dss_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_DSS_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_DSS_INST,
+ .clkdm_offs = OMAP4430_CM2_DSS_DSS_CDOFFS,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -221,8 +250,9 @@ static struct clockdomain l3_dss_44xx_clkdm = {
static struct clockdomain l4_wkup_44xx_clkdm = {
.name = "l4_wkup_clkdm",
.pwrdm = { .name = "wkup_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_WKUP_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .cm_inst = OMAP4430_PRM_WKUP_CM_INST,
+ .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -230,8 +260,9 @@ static struct clockdomain l4_wkup_44xx_clkdm = {
static struct clockdomain emu_sys_44xx_clkdm = {
.name = "emu_sys_clkdm",
.pwrdm = { .name = "emu_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_EMU_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .cm_inst = OMAP4430_PRM_EMU_CM_INST,
+ .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
@@ -239,12 +270,42 @@ static struct clockdomain emu_sys_44xx_clkdm = {
static struct clockdomain l3_dma_44xx_clkdm = {
.name = "l3_dma_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .clkstctrl_reg = OMAP4430_CM_SDMA_CLKSTCTRL,
- .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_SDMA_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
-#endif
+static struct clockdomain *clockdomains_omap44xx[] __initdata = {
+ &l4_cefuse_44xx_clkdm,
+ &l4_cfg_44xx_clkdm,
+ &tesla_44xx_clkdm,
+ &l3_gfx_44xx_clkdm,
+ &ivahd_44xx_clkdm,
+ &l4_secure_44xx_clkdm,
+ &l4_per_44xx_clkdm,
+ &abe_44xx_clkdm,
+ &l3_instr_44xx_clkdm,
+ &l3_init_44xx_clkdm,
+ &mpuss_44xx_clkdm,
+ &mpu0_44xx_clkdm,
+ &mpu1_44xx_clkdm,
+ &l3_emif_44xx_clkdm,
+ &l4_ao_44xx_clkdm,
+ &ducati_44xx_clkdm,
+ &l3_2_44xx_clkdm,
+ &l3_1_44xx_clkdm,
+ &l3_d2d_44xx_clkdm,
+ &iss_44xx_clkdm,
+ &l3_dss_44xx_clkdm,
+ &l4_wkup_44xx_clkdm,
+ &emu_sys_44xx_clkdm,
+ &l3_dma_44xx_clkdm,
+ NULL,
+};
-#endif
+void __init omap44xx_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap44xx, NULL);
+}
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
index da51cc3ed7eb..d70660e82fe6 100644
--- a/arch/arm/mach-omap2/cm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -14,8 +14,6 @@
* published by the Free Software Foundation.
*/
-#include "cm.h"
-
/* Bits shared between registers */
/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */
@@ -126,8 +124,12 @@
#define OMAP24XX_ST_HDQ_MASK (1 << 23)
#define OMAP2420_ST_I2C2_SHIFT 20
#define OMAP2420_ST_I2C2_MASK (1 << 20)
+#define OMAP2430_ST_I2CHS1_SHIFT 19
+#define OMAP2430_ST_I2CHS1_MASK (1 << 19)
#define OMAP2420_ST_I2C1_SHIFT 19
#define OMAP2420_ST_I2C1_MASK (1 << 19)
+#define OMAP2430_ST_I2CHS2_SHIFT 20
+#define OMAP2430_ST_I2CHS2_MASK (1 << 20)
#define OMAP24XX_ST_MCBSP2_SHIFT 16
#define OMAP24XX_ST_MCBSP2_MASK (1 << 16)
#define OMAP24XX_ST_MCBSP1_SHIFT 15
@@ -432,4 +434,9 @@
#define OMAP2430_AUTOSTATE_MDM_SHIFT 0
#define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0)
+/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
+
+
#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 4f959a7d881c..b91275908f33 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -14,8 +14,6 @@
* published by the Free Software Foundation.
*/
-#include "cm.h"
-
/* Bits shared between registers */
/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */
@@ -800,4 +798,15 @@
#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT 0
#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK (1 << 0)
+/*
+ *
+ */
+
+/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
+#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1
+#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
+#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
+
+
#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h
index 0b72be433776..9d47a05b17b4 100644
--- a/arch/arm/mach-omap2/cm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -22,9 +22,6 @@
#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H
#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H
-#include "cm.h"
-
-
/*
* Used by CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP,
* CM_TESLA_DYNAMICDEP
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
deleted file mode 100644
index 721c3b66740a..000000000000
--- a/arch/arm/mach-omap2/cm.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * OMAP2/3 CM module functions
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can 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/types.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/atomic.h>
-
-#include <plat/common.h>
-
-#include "cm.h"
-#include "cm-regbits-24xx.h"
-#include "cm-regbits-34xx.h"
-
-static const u8 cm_idlest_offs[] = {
- CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
-};
-
-/**
- * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
- * @prcm_mod: PRCM module offset
- * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
- * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
- *
- * XXX document
- */
-int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
-{
- int ena = 0, i = 0;
- u8 cm_idlest_reg;
- u32 mask;
-
- if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
- return -EINVAL;
-
- cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
-
- mask = 1 << idlest_shift;
-
- if (cpu_is_omap24xx())
- ena = mask;
- else if (cpu_is_omap34xx())
- ena = 0;
- else
- BUG();
-
- /* XXX should be OMAP2 CM */
- omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
- MAX_MODULE_READY_TIME, i);
-
- return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
-}
-
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index a02ca30423dc..a7bc096bd407 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -1,8 +1,5 @@
-#ifndef __ARCH_ASM_MACH_OMAP2_CM_H
-#define __ARCH_ASM_MACH_OMAP2_CM_H
-
/*
- * OMAP2/3 Clock Management (CM) register definitions
+ * OMAP2+ Clock Management prototypes
*
* Copyright (C) 2007-2009 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
@@ -13,136 +10,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
-#include "prcm-common.h"
-
-#define OMAP2420_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
-#define OMAP2430_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
-#define OMAP34XX_CM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
-#define OMAP44XX_CM1_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP4430_CM1_BASE + (module) + (reg))
-#define OMAP44XX_CM2_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE + (module) + (reg))
-
-#include "cm44xx.h"
-
-/*
- * Architecture-specific global CM registers
- * Use cm_{read,write}_reg() with these registers.
- * These registers appear once per CM module.
- */
-
-#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
-#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
-
-#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
-
-/*
- * Module specific CM registers from CM_BASE + domain offset
- * Use cm_{read,write}_mod_reg() with these registers.
- * These register offsets generally appear in more than one PRCM submodule.
- */
-
-/* Common between 24xx and 34xx */
-
-#define CM_FCLKEN 0x0000
-#define CM_FCLKEN1 CM_FCLKEN
-#define CM_CLKEN CM_FCLKEN
-#define CM_ICLKEN 0x0010
-#define CM_ICLKEN1 CM_ICLKEN
-#define CM_ICLKEN2 0x0014
-#define CM_ICLKEN3 0x0018
-#define CM_IDLEST 0x0020
-#define CM_IDLEST1 CM_IDLEST
-#define CM_IDLEST2 0x0024
-#define CM_AUTOIDLE 0x0030
-#define CM_AUTOIDLE1 CM_AUTOIDLE
-#define CM_AUTOIDLE2 0x0034
-#define CM_AUTOIDLE3 0x0038
-#define CM_CLKSEL 0x0040
-#define CM_CLKSEL1 CM_CLKSEL
-#define CM_CLKSEL2 0x0044
-#define OMAP2_CM_CLKSTCTRL 0x0048
-#define OMAP4_CM_CLKSTCTRL 0x0000
-
-
-/* Architecture-specific registers */
-
-#define OMAP24XX_CM_FCLKEN2 0x0004
-#define OMAP24XX_CM_ICLKEN4 0x001c
-#define OMAP24XX_CM_AUTOIDLE4 0x003c
-
-#define OMAP2430_CM_IDLEST3 0x0028
-
-#define OMAP3430_CM_CLKEN_PLL 0x0004
-#define OMAP3430ES2_CM_CLKEN2 0x0004
-#define OMAP3430ES2_CM_FCLKEN3 0x0008
-#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
-#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
-#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
-#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
-#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
-#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
-#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
-#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
-#define OMAP3430_CM_CLKSTST 0x004c
-#define OMAP3430ES2_CM_CLKSEL4 0x004c
-#define OMAP3430ES2_CM_CLKSEL5 0x0050
-#define OMAP3430_CM_CLKSEL2_EMU 0x0050
-#define OMAP3430_CM_CLKSEL3_EMU 0x0054
-
-/* CM2.CEFUSE_CM2 register offsets */
-
-/* OMAP4 modulemode control */
-#define OMAP4430_MODULEMODE_HWCTRL 0
-#define OMAP4430_MODULEMODE_SWCTRL 1
-
-/* Clock management domain register get/set */
-
-#ifndef __ASSEMBLER__
-
-extern u32 cm_read_mod_reg(s16 module, u16 idx);
-extern void cm_write_mod_reg(u32 val, s16 module, u16 idx);
-extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-
-extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
- u8 idlest_shift);
-extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
-
-static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return cm_rmw_mod_reg_bits(bits, bits, module, idx);
-}
-
-static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
-}
-
-#endif
-
-/* CM register bits shared between 24XX and 3430 */
-
-/* CM_CLKSEL_GFX */
-#define OMAP_CLKSEL_GFX_SHIFT 0
-#define OMAP_CLKSEL_GFX_MASK (0x7 << 0)
-
-/* CM_ICLKEN_GFX */
-#define OMAP_EN_GFX_SHIFT 0
-#define OMAP_EN_GFX_MASK (1 << 0)
-
-/* CM_IDLEST_GFX */
-#define OMAP_ST_GFX_MASK (1 << 0)
-
-
-/* CM_IDLEST indicator */
-#define OMAP24XX_CM_IDLEST_VAL 0
-#define OMAP34XX_CM_IDLEST_VAL 1
+#ifndef __ARCH_ASM_MACH_OMAP2_CM_H
+#define __ARCH_ASM_MACH_OMAP2_CM_H
/*
* MAX_MODULE_READY_TIME: max duration in microseconds to wait for the
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
new file mode 100644
index 000000000000..e2d7a56b2ad6
--- /dev/null
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -0,0 +1,261 @@
+/*
+ * OMAP44xx CM1 instance offset macros
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
+
+/* CM1 base address */
+#define OMAP4430_CM1_BASE 0x4a004000
+
+#define OMAP44XX_CM1_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_CM1_BASE + (inst) + (reg))
+
+/* CM1 instances */
+#define OMAP4430_CM1_OCP_SOCKET_INST 0x0000
+#define OMAP4430_CM1_CKGEN_INST 0x0100
+#define OMAP4430_CM1_MPU_INST 0x0300
+#define OMAP4430_CM1_TESLA_INST 0x0400
+#define OMAP4430_CM1_ABE_INST 0x0500
+#define OMAP4430_CM1_RESTORE_INST 0x0e00
+#define OMAP4430_CM1_INSTR_INST 0x0f00
+
+/* CM1 clockdomain register offsets (from instance start) */
+#define OMAP4430_CM1_ABE_ABE_CDOFFS 0x0000
+#define OMAP4430_CM1_MPU_MPU_CDOFFS 0x0000
+#define OMAP4430_CM1_TESLA_TESLA_CDOFFS 0x0000
+
+/* CM1 */
+
+/* CM1.OCP_SOCKET_CM1 register offsets */
+#define OMAP4_REVISION_CM1_OFFSET 0x0000
+#define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0000)
+#define OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0040)
+
+/* CM1.CKGEN_CM1 register offsets */
+#define OMAP4_CM_CLKSEL_CORE_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0000)
+#define OMAP4_CM_CLKSEL_ABE_OFFSET 0x0008
+#define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0008)
+#define OMAP4_CM_DLL_CTRL_OFFSET 0x0010
+#define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0010)
+#define OMAP4_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020
+#define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0020)
+#define OMAP4_CM_IDLEST_DPLL_CORE_OFFSET 0x0024
+#define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0024)
+#define OMAP4_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0028)
+#define OMAP4_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c
+#define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x002c)
+#define OMAP4_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030
+#define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0030)
+#define OMAP4_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034
+#define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0034)
+#define OMAP4_CM_DIV_M4_DPLL_CORE_OFFSET 0x0038
+#define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0038)
+#define OMAP4_CM_DIV_M5_DPLL_CORE_OFFSET 0x003c
+#define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x003c)
+#define OMAP4_CM_DIV_M6_DPLL_CORE_OFFSET 0x0040
+#define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0040)
+#define OMAP4_CM_DIV_M7_DPLL_CORE_OFFSET 0x0044
+#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0044)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0048)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x004c)
+#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050
+#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0050)
+#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
+#define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0060)
+#define OMAP4_CM_IDLEST_DPLL_MPU_OFFSET 0x0064
+#define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0064)
+#define OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068
+#define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0068)
+#define OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c
+#define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x006c)
+#define OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070
+#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0070)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0088)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x008c)
+#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
+#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x009c)
+#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
+#define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a0)
+#define OMAP4_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4
+#define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a4)
+#define OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8
+#define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a8)
+#define OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac
+#define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ac)
+#define OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET 0x00b8
+#define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00b8)
+#define OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET 0x00bc
+#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00bc)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00c8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00cc)
+#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
+#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00dc)
+#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
+#define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e0)
+#define OMAP4_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4
+#define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e4)
+#define OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8
+#define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e8)
+#define OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec
+#define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ec)
+#define OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0
+#define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f0)
+#define OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4
+#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f4)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0108)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x010c)
+#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120
+#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0120)
+#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124
+#define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0124)
+#define OMAP4_CM_AUTOIDLE_DPLL_DDRPHY_OFFSET 0x0128
+#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0128)
+#define OMAP4_CM_CLKSEL_DPLL_DDRPHY_OFFSET 0x012c
+#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x012c)
+#define OMAP4_CM_DIV_M2_DPLL_DDRPHY_OFFSET 0x0130
+#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0130)
+#define OMAP4_CM_DIV_M4_DPLL_DDRPHY_OFFSET 0x0138
+#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0138)
+#define OMAP4_CM_DIV_M5_DPLL_DDRPHY_OFFSET 0x013c
+#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x013c)
+#define OMAP4_CM_DIV_M6_DPLL_DDRPHY_OFFSET 0x0140
+#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0140)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0148)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x014c)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0160)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0164)
+#define OMAP4_CM_DYN_DEP_PRESCAL_OFFSET 0x0170
+#define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0170)
+#define OMAP4_CM_RESTORE_ST_OFFSET 0x0180
+#define OMAP4430_CM_RESTORE_ST OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0180)
+
+/* CM1.MPU_CM1 register offsets */
+#define OMAP4_CM_MPU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0000)
+#define OMAP4_CM_MPU_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0004)
+#define OMAP4_CM_MPU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0008)
+#define OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0020)
+
+/* CM1.TESLA_CM1 register offsets */
+#define OMAP4_CM_TESLA_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0000)
+#define OMAP4_CM_TESLA_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0004)
+#define OMAP4_CM_TESLA_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0008)
+#define OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0020)
+
+/* CM1.ABE_CM1 register offsets */
+#define OMAP4_CM1_ABE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0000)
+#define OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0020)
+#define OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0028)
+#define OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0030)
+#define OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0038)
+#define OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0040)
+#define OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048
+#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0048)
+#define OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050
+#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0050)
+#define OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0058)
+#define OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0060)
+#define OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0068)
+#define OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET 0x0070
+#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0070)
+#define OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0078)
+#define OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0080)
+#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)
+
+/* CM1.RESTORE_CM1 register offsets */
+#define OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0000)
+#define OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0004)
+#define OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0008)
+#define OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x000c)
+#define OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0010)
+#define OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0014)
+#define OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0018)
+#define OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x001c)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0020)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0024)
+#define OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0028)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x002c)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0030)
+#define OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0034)
+#define OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0038)
+#define OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x003c)
+#define OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_DYN_DEP_PRESCAL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0040)
+
+/* Function prototypes */
+extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
new file mode 100644
index 000000000000..aa4745044065
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -0,0 +1,508 @@
+/*
+ * OMAP44xx CM2 instance offset macros
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
+
+/* CM2 base address */
+#define OMAP4430_CM2_BASE 0x4a008000
+
+#define OMAP44XX_CM2_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE + (inst) + (reg))
+
+/* CM2 instances */
+#define OMAP4430_CM2_OCP_SOCKET_INST 0x0000
+#define OMAP4430_CM2_CKGEN_INST 0x0100
+#define OMAP4430_CM2_ALWAYS_ON_INST 0x0600
+#define OMAP4430_CM2_CORE_INST 0x0700
+#define OMAP4430_CM2_IVAHD_INST 0x0f00
+#define OMAP4430_CM2_CAM_INST 0x1000
+#define OMAP4430_CM2_DSS_INST 0x1100
+#define OMAP4430_CM2_GFX_INST 0x1200
+#define OMAP4430_CM2_L3INIT_INST 0x1300
+#define OMAP4430_CM2_L4PER_INST 0x1400
+#define OMAP4430_CM2_CEFUSE_INST 0x1600
+#define OMAP4430_CM2_RESTORE_INST 0x1e00
+#define OMAP4430_CM2_INSTR_INST 0x1f00
+
+/* CM2 clockdomain register offsets (from instance start) */
+#define OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS 0x0000
+#define OMAP4430_CM2_CORE_L3_1_CDOFFS 0x0000
+#define OMAP4430_CM2_CORE_L3_2_CDOFFS 0x0100
+#define OMAP4430_CM2_CORE_DUCATI_CDOFFS 0x0200
+#define OMAP4430_CM2_CORE_SDMA_CDOFFS 0x0300
+#define OMAP4430_CM2_CORE_MEMIF_CDOFFS 0x0400
+#define OMAP4430_CM2_CORE_D2D_CDOFFS 0x0500
+#define OMAP4430_CM2_CORE_L4CFG_CDOFFS 0x0600
+#define OMAP4430_CM2_CORE_L3INSTR_CDOFFS 0x0700
+#define OMAP4430_CM2_IVAHD_IVAHD_CDOFFS 0x0000
+#define OMAP4430_CM2_CAM_CAM_CDOFFS 0x0000
+#define OMAP4430_CM2_DSS_DSS_CDOFFS 0x0000
+#define OMAP4430_CM2_GFX_GFX_CDOFFS 0x0000
+#define OMAP4430_CM2_L3INIT_L3INIT_CDOFFS 0x0000
+#define OMAP4430_CM2_L4PER_L4PER_CDOFFS 0x0000
+#define OMAP4430_CM2_L4PER_L4SEC_CDOFFS 0x0180
+#define OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS 0x0000
+
+
+/* CM2 */
+
+/* CM2.OCP_SOCKET_CM2 register offsets */
+#define OMAP4_REVISION_CM2_OFFSET 0x0000
+#define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0000)
+#define OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0040)
+
+/* CM2.CKGEN_CM2 register offsets */
+#define OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0000)
+#define OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004
+#define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0004)
+#define OMAP4_CM_SCALE_FCLK_OFFSET 0x0008
+#define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0008)
+#define OMAP4_CM_CORE_DVFS_PERF1_OFFSET 0x0010
+#define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0010)
+#define OMAP4_CM_CORE_DVFS_PERF2_OFFSET 0x0014
+#define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0014)
+#define OMAP4_CM_CORE_DVFS_PERF3_OFFSET 0x0018
+#define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0018)
+#define OMAP4_CM_CORE_DVFS_PERF4_OFFSET 0x001c
+#define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x001c)
+#define OMAP4_CM_CORE_DVFS_CURRENT_OFFSET 0x0024
+#define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0024)
+#define OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET 0x0028
+#define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0028)
+#define OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET 0x002c
+#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x002c)
+#define OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET 0x0030
+#define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0030)
+#define OMAP4_CM_IVA_DVFS_CURRENT_OFFSET 0x0038
+#define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0038)
+#define OMAP4_CM_CLKMODE_DPLL_PER_OFFSET 0x0040
+#define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0040)
+#define OMAP4_CM_IDLEST_DPLL_PER_OFFSET 0x0044
+#define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0044)
+#define OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048
+#define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0048)
+#define OMAP4_CM_CLKSEL_DPLL_PER_OFFSET 0x004c
+#define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x004c)
+#define OMAP4_CM_DIV_M2_DPLL_PER_OFFSET 0x0050
+#define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0050)
+#define OMAP4_CM_DIV_M3_DPLL_PER_OFFSET 0x0054
+#define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0054)
+#define OMAP4_CM_DIV_M4_DPLL_PER_OFFSET 0x0058
+#define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0058)
+#define OMAP4_CM_DIV_M5_DPLL_PER_OFFSET 0x005c
+#define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x005c)
+#define OMAP4_CM_DIV_M6_DPLL_PER_OFFSET 0x0060
+#define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0060)
+#define OMAP4_CM_DIV_M7_DPLL_PER_OFFSET 0x0064
+#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0064)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0068)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_PER_OFFSET 0x006c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x006c)
+#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
+#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0080)
+#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084
+#define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0084)
+#define OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088
+#define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0088)
+#define OMAP4_CM_CLKSEL_DPLL_USB_OFFSET 0x008c
+#define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x008c)
+#define OMAP4_CM_DIV_M2_DPLL_USB_OFFSET 0x0090
+#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0090)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00a8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_USB_OFFSET 0x00ac
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ac)
+#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4
+#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00b4)
+#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0
+#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c0)
+#define OMAP4_CM_IDLEST_DPLL_UNIPRO_OFFSET 0x00c4
+#define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c4)
+#define OMAP4_CM_AUTOIDLE_DPLL_UNIPRO_OFFSET 0x00c8
+#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c8)
+#define OMAP4_CM_CLKSEL_DPLL_UNIPRO_OFFSET 0x00cc
+#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00cc)
+#define OMAP4_CM_DIV_M2_DPLL_UNIPRO_OFFSET 0x00d0
+#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00d0)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00e8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ec)
+
+/* CM2.ALWAYS_ON_CM2 register offsets */
+#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0000)
+#define OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0020)
+#define OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0028)
+#define OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0030)
+#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0038)
+#define OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_ALWON_USBPHY_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0040)
+
+/* CM2.CORE_CM2 register offsets */
+#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0000)
+#define OMAP4_CM_L3_1_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0008)
+#define OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0020)
+#define OMAP4_CM_L3_2_CLKSTCTRL_OFFSET 0x0100
+#define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0100)
+#define OMAP4_CM_L3_2_DYNAMICDEP_OFFSET 0x0108
+#define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0108)
+#define OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET 0x0120
+#define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0120)
+#define OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET 0x0128
+#define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0128)
+#define OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET 0x0130
+#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0130)
+#define OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET 0x0200
+#define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0200)
+#define OMAP4_CM_DUCATI_STATICDEP_OFFSET 0x0204
+#define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0204)
+#define OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET 0x0208
+#define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0208)
+#define OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET 0x0220
+#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0220)
+#define OMAP4_CM_SDMA_CLKSTCTRL_OFFSET 0x0300
+#define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0300)
+#define OMAP4_CM_SDMA_STATICDEP_OFFSET 0x0304
+#define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0304)
+#define OMAP4_CM_SDMA_DYNAMICDEP_OFFSET 0x0308
+#define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0308)
+#define OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET 0x0320
+#define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0320)
+#define OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET 0x0400
+#define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0400)
+#define OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET 0x0420
+#define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0420)
+#define OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET 0x0428
+#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0428)
+#define OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET 0x0430
+#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0430)
+#define OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET 0x0438
+#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0438)
+#define OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET 0x0440
+#define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0440)
+#define OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET 0x0450
+#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0450)
+#define OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET 0x0458
+#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0458)
+#define OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET 0x0460
+#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0460)
+#define OMAP4_CM_D2D_CLKSTCTRL_OFFSET 0x0500
+#define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0500)
+#define OMAP4_CM_D2D_STATICDEP_OFFSET 0x0504
+#define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0504)
+#define OMAP4_CM_D2D_DYNAMICDEP_OFFSET 0x0508
+#define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0508)
+#define OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET 0x0520
+#define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0520)
+#define OMAP4_CM_D2D_INSTEM_ICR_CLKCTRL_OFFSET 0x0528
+#define OMAP4430_CM_D2D_INSTEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0528)
+#define OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET 0x0530
+#define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0530)
+#define OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600
+#define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0600)
+#define OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608
+#define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0608)
+#define OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620
+#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0620)
+#define OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET 0x0628
+#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0628)
+#define OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630
+#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0630)
+#define OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638
+#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0638)
+#define OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700
+#define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0700)
+#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET 0x0720
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0720)
+#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0728)
+#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET 0x0740
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0740)
+
+/* CM2.IVAHD_CM2 register offsets */
+#define OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0000)
+#define OMAP4_CM_IVAHD_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0004)
+#define OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0008)
+#define OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0020)
+#define OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0028)
+
+/* CM2.CAM_CM2 register offsets */
+#define OMAP4_CM_CAM_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0000)
+#define OMAP4_CM_CAM_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0004)
+#define OMAP4_CM_CAM_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0008)
+#define OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0020)
+#define OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0028)
+
+/* CM2.DSS_CM2 register offsets */
+#define OMAP4_CM_DSS_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0000)
+#define OMAP4_CM_DSS_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0004)
+#define OMAP4_CM_DSS_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0008)
+#define OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0020)
+#define OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0028)
+
+/* CM2.GFX_CM2 register offsets */
+#define OMAP4_CM_GFX_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0000)
+#define OMAP4_CM_GFX_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0004)
+#define OMAP4_CM_GFX_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0008)
+#define OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0020)
+
+/* CM2.L3INIT_CM2 register offsets */
+#define OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0000)
+#define OMAP4_CM_L3INIT_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0004)
+#define OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0008)
+#define OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0028)
+#define OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0030)
+#define OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0038)
+#define OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0040)
+#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0058)
+#define OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0060)
+#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0068)
+#define OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0078)
+#define OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0080)
+#define OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0088)
+#define OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET 0x0090
+#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0090)
+#define OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET 0x0098
+#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0098)
+#define OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET 0x00a8
+#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00a8)
+#define OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET 0x00c0
+#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c0)
+#define OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET 0x00c8
+#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c8)
+#define OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET 0x00d0
+#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00d0)
+#define OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET 0x00e0
+#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00e0)
+
+/* CM2.L4PER_CM2 register offsets */
+#define OMAP4_CM_L4PER_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0000)
+#define OMAP4_CM_L4PER_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0008)
+#define OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0020)
+#define OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0028)
+#define OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0030)
+#define OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0038)
+#define OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0040)
+#define OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET 0x0048
+#define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0048)
+#define OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET 0x0050
+#define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0050)
+#define OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0058)
+#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0060)
+#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0068)
+#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0070)
+#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0078)
+#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0080)
+#define OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0088)
+#define OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET 0x0090
+#define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0090)
+#define OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET 0x0098
+#define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0098)
+#define OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0
+#define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a0)
+#define OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8
+#define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a8)
+#define OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0
+#define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b0)
+#define OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8
+#define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b8)
+#define OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET 0x00c0
+#define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00c0)
+#define OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET 0x00d0
+#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d0)
+#define OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET 0x00d8
+#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d8)
+#define OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET 0x00e0
+#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e0)
+#define OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET 0x00e8
+#define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e8)
+#define OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0
+#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f0)
+#define OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8
+#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f8)
+#define OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100
+#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0100)
+#define OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108
+#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0108)
+#define OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET 0x0120
+#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0120)
+#define OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET 0x0128
+#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0128)
+#define OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET 0x0130
+#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0130)
+#define OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET 0x0138
+#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0138)
+#define OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140
+#define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0140)
+#define OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148
+#define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0148)
+#define OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150
+#define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0150)
+#define OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158
+#define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0158)
+#define OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET 0x0160
+#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0160)
+#define OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0168
+#define OMAP4430_CM_L4PER_I2C5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0168)
+#define OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180
+#define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0180)
+#define OMAP4_CM_L4SEC_STATICDEP_OFFSET 0x0184
+#define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0184)
+#define OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188
+#define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0188)
+#define OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0
+#define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a0)
+#define OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8
+#define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a8)
+#define OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0
+#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b0)
+#define OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET 0x01b8
+#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b8)
+#define OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0
+#define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c0)
+#define OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8
+#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c8)
+#define OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET 0x01d8
+#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01d8)
+
+/* CM2.CEFUSE_CM2 register offsets */
+#define OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0000)
+#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)
+
+/* CM2.RESTORE_CM2 register offsets */
+#define OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0000)
+#define OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0004)
+#define OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0008)
+#define OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x000c)
+#define OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0010)
+#define OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0014)
+#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0018)
+#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x001c)
+#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0020)
+#define OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0024)
+#define OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_D2D_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0028)
+#define OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_L3_1_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x002c)
+#define OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_L3_2_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0030)
+#define OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_D2D_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0034)
+#define OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_L4CFG_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0038)
+#define OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_L4PER_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x003c)
+#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0040)
+#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_RESTORE_OFFSET 0x0044
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0044)
+#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_RESTORE_OFFSET 0x0048
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0048)
+#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_RESTORE_OFFSET 0x004c
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x004c)
+#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_RESTORE_OFFSET 0x0050
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0050)
+#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET 0x0054
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0054)
+#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET 0x0058
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0058)
+#define OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET 0x005c
+#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x005c)
+
+/* Function prototypes */
+extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
new file mode 100644
index 000000000000..96954aa48671
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -0,0 +1,471 @@
+/*
+ * OMAP2/3 CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+static const u8 cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+};
+
+u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(cm_base + module + idx);
+}
+
+void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, cm_base + module + idx);
+}
+
+/* Read-modify-write a register in a CM module. Caller must lock */
+u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_cm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+
+u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+/*
+ *
+ */
+
+static void _write_clktrctrl(u8 c, s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= ~mask;
+ v |= c << __ffs(mask);
+ omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
+}
+
+bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+ u32 v;
+ bool ret = 0;
+
+ BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ if (cpu_is_omap24xx())
+ ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+ else
+ ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+
+ return ret;
+}
+
+void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
+}
+
+
+/*
+ *
+ */
+
+/**
+ * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * XXX document
+ */
+int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
+
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
+ return -EINVAL;
+
+ cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+
+ if (cpu_is_omap24xx())
+ ena = mask;
+ else if (cpu_is_omap34xx())
+ ena = 0;
+ else
+ BUG();
+
+ omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/*
+ * Context save/restore code - OMAP3 only
+ */
+#ifdef CONFIG_ARCH_OMAP3
+struct omap3_cm_regs {
+ u32 iva2_cm_clksel1;
+ u32 iva2_cm_clksel2;
+ u32 cm_sysconfig;
+ u32 sgx_cm_clksel;
+ u32 dss_cm_clksel;
+ u32 cam_cm_clksel;
+ u32 per_cm_clksel;
+ u32 emu_cm_clksel;
+ u32 emu_cm_clkstctrl;
+ u32 pll_cm_autoidle2;
+ u32 pll_cm_clksel4;
+ u32 pll_cm_clksel5;
+ u32 pll_cm_clken2;
+ u32 cm_polctrl;
+ u32 iva2_cm_fclken;
+ u32 iva2_cm_clken_pll;
+ u32 core_cm_fclken1;
+ u32 core_cm_fclken3;
+ u32 sgx_cm_fclken;
+ u32 wkup_cm_fclken;
+ u32 dss_cm_fclken;
+ u32 cam_cm_fclken;
+ u32 per_cm_fclken;
+ u32 usbhost_cm_fclken;
+ u32 core_cm_iclken1;
+ u32 core_cm_iclken2;
+ u32 core_cm_iclken3;
+ u32 sgx_cm_iclken;
+ u32 wkup_cm_iclken;
+ u32 dss_cm_iclken;
+ u32 cam_cm_iclken;
+ u32 per_cm_iclken;
+ u32 usbhost_cm_iclken;
+ u32 iva2_cm_autoidle2;
+ u32 mpu_cm_autoidle2;
+ u32 iva2_cm_clkstctrl;
+ u32 mpu_cm_clkstctrl;
+ u32 core_cm_clkstctrl;
+ u32 sgx_cm_clkstctrl;
+ u32 dss_cm_clkstctrl;
+ u32 cam_cm_clkstctrl;
+ u32 per_cm_clkstctrl;
+ u32 neon_cm_clkstctrl;
+ u32 usbhost_cm_clkstctrl;
+ u32 core_cm_autoidle1;
+ u32 core_cm_autoidle2;
+ u32 core_cm_autoidle3;
+ u32 wkup_cm_autoidle;
+ u32 dss_cm_autoidle;
+ u32 cam_cm_autoidle;
+ u32 per_cm_autoidle;
+ u32 usbhost_cm_autoidle;
+ u32 sgx_cm_sleepdep;
+ u32 dss_cm_sleepdep;
+ u32 cam_cm_sleepdep;
+ u32 per_cm_sleepdep;
+ u32 usbhost_cm_sleepdep;
+ u32 cm_clkout_ctrl;
+};
+
+static struct omap3_cm_regs cm_context;
+
+void omap3_cm_save_context(void)
+{
+ cm_context.iva2_cm_clksel1 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ cm_context.iva2_cm_clksel2 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
+ cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
+ cm_context.sgx_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
+ cm_context.dss_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
+ cm_context.cam_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
+ cm_context.per_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
+ cm_context.emu_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
+ cm_context.emu_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.pll_cm_autoidle2 =
+ omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
+ cm_context.pll_cm_clksel4 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
+ cm_context.pll_cm_clksel5 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
+ cm_context.pll_cm_clken2 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
+ cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
+ cm_context.iva2_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
+ cm_context.iva2_cm_clken_pll =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
+ cm_context.core_cm_fclken1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ cm_context.core_cm_fclken3 =
+ omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
+ cm_context.sgx_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
+ cm_context.wkup_cm_fclken =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
+ cm_context.dss_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
+ cm_context.cam_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
+ cm_context.per_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
+ cm_context.usbhost_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ cm_context.core_cm_iclken1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
+ cm_context.core_cm_iclken2 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
+ cm_context.core_cm_iclken3 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
+ cm_context.sgx_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
+ cm_context.wkup_cm_iclken =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
+ cm_context.dss_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
+ cm_context.cam_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
+ cm_context.per_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
+ cm_context.usbhost_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ cm_context.iva2_cm_autoidle2 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
+ cm_context.mpu_cm_autoidle2 =
+ omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
+ cm_context.iva2_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.mpu_cm_clkstctrl =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_clkstctrl =
+ omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.sgx_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.dss_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.cam_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.per_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.neon_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.usbhost_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_autoidle1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
+ cm_context.core_cm_autoidle2 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
+ cm_context.core_cm_autoidle3 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
+ cm_context.wkup_cm_autoidle =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
+ cm_context.dss_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
+ cm_context.cam_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
+ cm_context.per_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ cm_context.usbhost_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ cm_context.sgx_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_context.dss_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.cam_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.per_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.usbhost_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_context.cm_clkout_ctrl =
+ omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
+ OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+
+void omap3_cm_restore_context(void)
+{
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
+ CM_CLKSEL1);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
+ CM_CLKSEL2);
+ __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
+ CM_CLKSEL1);
+ omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL4);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL5);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
+ OMAP3430ES2_CM_CLKEN2);
+ __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
+ OMAP3430_CM_CLKEN_PLL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
+ CM_FCLKEN1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
+ OMAP3430ES2_CM_FCLKEN3);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
+ OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
+ CM_ICLKEN1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
+ CM_ICLKEN2);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
+ CM_ICLKEN3);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
+ OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
+ OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
+ CM_AUTOIDLE1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
+ CM_AUTOIDLE3);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
+ OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
+ OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
+ OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
new file mode 100644
index 000000000000..5e9ea5bd60b9
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -0,0 +1,147 @@
+/*
+ * OMAP2/3 Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 CM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
+
+#include "prcm-common.h"
+
+#define OMAP2420_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+#define OMAP2430_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+#define OMAP34XX_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global CM registers
+ * Use cm_{read,write}_reg() with these registers.
+ * These registers appear once per CM module.
+ */
+
+#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
+#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
+
+#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* Common between OMAP2 and OMAP3 */
+
+#define CM_FCLKEN 0x0000
+#define CM_FCLKEN1 CM_FCLKEN
+#define CM_CLKEN CM_FCLKEN
+#define CM_ICLKEN 0x0010
+#define CM_ICLKEN1 CM_ICLKEN
+#define CM_ICLKEN2 0x0014
+#define CM_ICLKEN3 0x0018
+#define CM_IDLEST 0x0020
+#define CM_IDLEST1 CM_IDLEST
+#define CM_IDLEST2 0x0024
+#define CM_AUTOIDLE 0x0030
+#define CM_AUTOIDLE1 CM_AUTOIDLE
+#define CM_AUTOIDLE2 0x0034
+#define CM_AUTOIDLE3 0x0038
+#define CM_CLKSEL 0x0040
+#define CM_CLKSEL1 CM_CLKSEL
+#define CM_CLKSEL2 0x0044
+#define OMAP2_CM_CLKSTCTRL 0x0048
+
+/* OMAP2-specific register offsets */
+
+#define OMAP24XX_CM_FCLKEN2 0x0004
+#define OMAP24XX_CM_ICLKEN4 0x001c
+#define OMAP24XX_CM_AUTOIDLE4 0x003c
+
+#define OMAP2430_CM_IDLEST3 0x0028
+
+/* OMAP3-specific register offsets */
+
+#define OMAP3430_CM_CLKEN_PLL 0x0004
+#define OMAP3430ES2_CM_CLKEN2 0x0004
+#define OMAP3430ES2_CM_FCLKEN3 0x0008
+#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
+#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
+#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
+#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
+#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
+#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
+#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
+#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
+#define OMAP3430_CM_CLKSTST 0x004c
+#define OMAP3430ES2_CM_CLKSEL4 0x004c
+#define OMAP3430ES2_CM_CLKSEL5 0x0050
+#define OMAP3430_CM_CLKSEL2_EMU 0x0050
+#define OMAP3430_CM_CLKSEL3_EMU 0x0054
+
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP24XX_CM_IDLEST_VAL 0
+#define OMAP34XX_CM_IDLEST_VAL 1
+
+
+/* Clock management domain register get/set */
+
+#ifndef __ASSEMBLER__
+
+extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx);
+extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+
+extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+ u8 idlest_shift);
+extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+
+extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+
+extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+
+#endif
+
+/* CM register bits shared between 24XX and 3430 */
+
+/* CM_CLKSEL_GFX */
+#define OMAP_CLKSEL_GFX_SHIFT 0
+#define OMAP_CLKSEL_GFX_MASK (0x7 << 0)
+
+/* CM_ICLKEN_GFX */
+#define OMAP_EN_GFX_SHIFT 0
+#define OMAP_EN_GFX_MASK (1 << 0)
+
+/* CM_IDLEST_GFX */
+#define OMAP_ST_GFX_MASK (1 << 0)
+
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+extern void omap3_cm_save_context(void);
+extern void omap3_cm_restore_context(void);
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
new file mode 100644
index 000000000000..e96f53ea01a1
--- /dev/null
+++ b/arch/arm/mach-omap2/cm44xx.c
@@ -0,0 +1,52 @@
+/*
+ * OMAP4 CM1, CM2 module low-level functions
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These functions are intended to be used only by the cminst44xx.c file.
+ * XXX Perhaps we should just move them there and make them static.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm-regbits-44xx.h"
+
+/* CM1 hardware module low-level functions */
+
+/* Read a register in CM1 */
+u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_CM1_REGADDR(inst, reg));
+}
+
+/* Write into a register in CM1 */
+void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_CM1_REGADDR(inst, reg));
+}
+
+/* Read a register in CM2 */
+u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_CM2_REGADDR(inst, reg));
+}
+
+/* Write into a register in CM2 */
+void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
+}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 3c35a87cb90c..48fc3f426fbd 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -1,667 +1,31 @@
/*
- * OMAP44xx CM1 & CM2 instance offset macros
+ * OMAP4 Clock Management (CM) definitions
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
- * Copyright (C) 2009-2010 Nokia Corporation
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
*
- * Paul Walmsley (paul@pwsan.com)
- * Rajendra Nayak (rnayak@ti.com)
- * Benoit Cousson (b-cousson@ti.com)
- *
- * This file is automatically generated from the OMAP hardware databases.
- * We respectfully ask that any modifications to this file be coordinated
- * with the public linux-omap@vger.kernel.org mailing list and the
- * authors above to ensure that the autogeneration scripts are kept
- * up-to-date with the file contents.
+ * Written by Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *
+ * OMAP4 has two separate CM blocks, CM1 and CM2. This file contains
+ * macros and function prototypes that are applicable to both.
*/
+#ifndef __ARCH_ASM_MACH_OMAP2_CM44XX_H
+#define __ARCH_ASM_MACH_OMAP2_CM44XX_H
-#ifndef __ARCH_ARM_MACH_OMAP2_CM44XX_H
-#define __ARCH_ARM_MACH_OMAP2_CM44XX_H
-
-
-/* CM1 */
-
-/* CM1.OCP_SOCKET_CM1 register offsets */
-#define OMAP4_REVISION_CM1_OFFSET 0x0000
-#define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0000)
-#define OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0040)
-
-/* CM1.CKGEN_CM1 register offsets */
-#define OMAP4_CM_CLKSEL_CORE_OFFSET 0x0000
-#define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0000)
-#define OMAP4_CM_CLKSEL_ABE_OFFSET 0x0008
-#define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0008)
-#define OMAP4_CM_DLL_CTRL_OFFSET 0x0010
-#define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0010)
-#define OMAP4_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020
-#define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0020)
-#define OMAP4_CM_IDLEST_DPLL_CORE_OFFSET 0x0024
-#define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0024)
-#define OMAP4_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028
-#define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0028)
-#define OMAP4_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c
-#define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x002c)
-#define OMAP4_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030
-#define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0030)
-#define OMAP4_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034
-#define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0034)
-#define OMAP4_CM_DIV_M4_DPLL_CORE_OFFSET 0x0038
-#define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0038)
-#define OMAP4_CM_DIV_M5_DPLL_CORE_OFFSET 0x003c
-#define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x003c)
-#define OMAP4_CM_DIV_M6_DPLL_CORE_OFFSET 0x0040
-#define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0040)
-#define OMAP4_CM_DIV_M7_DPLL_CORE_OFFSET 0x0044
-#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0044)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0048)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x004c)
-#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050
-#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0050)
-#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
-#define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0060)
-#define OMAP4_CM_IDLEST_DPLL_MPU_OFFSET 0x0064
-#define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0064)
-#define OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068
-#define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0068)
-#define OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c
-#define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x006c)
-#define OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070
-#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0070)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0088)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x008c)
-#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
-#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x009c)
-#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
-#define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a0)
-#define OMAP4_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4
-#define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a4)
-#define OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8
-#define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a8)
-#define OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac
-#define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ac)
-#define OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET 0x00b8
-#define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00b8)
-#define OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET 0x00bc
-#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00bc)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00c8)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00cc)
-#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
-#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00dc)
-#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
-#define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e0)
-#define OMAP4_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4
-#define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e4)
-#define OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8
-#define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e8)
-#define OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec
-#define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ec)
-#define OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0
-#define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f0)
-#define OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4
-#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f4)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0108)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x010c)
-#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120
-#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0120)
-#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124
-#define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0124)
-#define OMAP4_CM_AUTOIDLE_DPLL_DDRPHY_OFFSET 0x0128
-#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0128)
-#define OMAP4_CM_CLKSEL_DPLL_DDRPHY_OFFSET 0x012c
-#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x012c)
-#define OMAP4_CM_DIV_M2_DPLL_DDRPHY_OFFSET 0x0130
-#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0130)
-#define OMAP4_CM_DIV_M4_DPLL_DDRPHY_OFFSET 0x0138
-#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0138)
-#define OMAP4_CM_DIV_M5_DPLL_DDRPHY_OFFSET 0x013c
-#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x013c)
-#define OMAP4_CM_DIV_M6_DPLL_DDRPHY_OFFSET 0x0140
-#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0140)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0148)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x014c)
-#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
-#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0160)
-#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
-#define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0164)
-#define OMAP4_CM_DYN_DEP_PRESCAL_OFFSET 0x0170
-#define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0170)
-#define OMAP4_CM_RESTORE_ST_OFFSET 0x0180
-#define OMAP4430_CM_RESTORE_ST OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0180)
-
-/* CM1.MPU_CM1 register offsets */
-#define OMAP4_CM_MPU_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0000)
-#define OMAP4_CM_MPU_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0004)
-#define OMAP4_CM_MPU_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0008)
-#define OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0020)
-
-/* CM1.TESLA_CM1 register offsets */
-#define OMAP4_CM_TESLA_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0000)
-#define OMAP4_CM_TESLA_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0004)
-#define OMAP4_CM_TESLA_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0008)
-#define OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0020)
-
-/* CM1.ABE_CM1 register offsets */
-#define OMAP4_CM1_ABE_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0000)
-#define OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0020)
-#define OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0028)
-#define OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET 0x0030
-#define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0030)
-#define OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET 0x0038
-#define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0038)
-#define OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0040)
-#define OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048
-#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0048)
-#define OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050
-#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0050)
-#define OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058
-#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0058)
-#define OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET 0x0060
-#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0060)
-#define OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET 0x0068
-#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0068)
-#define OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET 0x0070
-#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0070)
-#define OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET 0x0078
-#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0078)
-#define OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET 0x0080
-#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0080)
-#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088
-#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0088)
-
-/* CM1.RESTORE_CM1 register offsets */
-#define OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET 0x0000
-#define OMAP4430_CM_CLKSEL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0000)
-#define OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET 0x0004
-#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0004)
-#define OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET 0x0008
-#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0008)
-#define OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET 0x000c
-#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x000c)
-#define OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET 0x0010
-#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0010)
-#define OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET 0x0014
-#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0014)
-#define OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET 0x0018
-#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0018)
-#define OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET 0x001c
-#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x001c)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET 0x0020
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0020)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0024)
-#define OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET 0x0028
-#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0028)
-#define OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET 0x002c
-#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x002c)
-#define OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET 0x0030
-#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0030)
-#define OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET 0x0034
-#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0034)
-#define OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET 0x0038
-#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0038)
-#define OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET 0x003c
-#define OMAP4430_CM_CM1_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x003c)
-#define OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET 0x0040
-#define OMAP4430_CM_DYN_DEP_PRESCAL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0040)
-
-/* CM2 */
-
-/* CM2.OCP_SOCKET_CM2 register offsets */
-#define OMAP4_REVISION_CM2_OFFSET 0x0000
-#define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0000)
-#define OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0040)
-
-/* CM2.CKGEN_CM2 register offsets */
-#define OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET 0x0000
-#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0000)
-#define OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004
-#define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0004)
-#define OMAP4_CM_SCALE_FCLK_OFFSET 0x0008
-#define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0008)
-#define OMAP4_CM_CORE_DVFS_PERF1_OFFSET 0x0010
-#define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0010)
-#define OMAP4_CM_CORE_DVFS_PERF2_OFFSET 0x0014
-#define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0014)
-#define OMAP4_CM_CORE_DVFS_PERF3_OFFSET 0x0018
-#define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0018)
-#define OMAP4_CM_CORE_DVFS_PERF4_OFFSET 0x001c
-#define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x001c)
-#define OMAP4_CM_CORE_DVFS_CURRENT_OFFSET 0x0024
-#define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0024)
-#define OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET 0x0028
-#define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0028)
-#define OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET 0x002c
-#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x002c)
-#define OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET 0x0030
-#define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0030)
-#define OMAP4_CM_IVA_DVFS_CURRENT_OFFSET 0x0038
-#define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0038)
-#define OMAP4_CM_CLKMODE_DPLL_PER_OFFSET 0x0040
-#define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0040)
-#define OMAP4_CM_IDLEST_DPLL_PER_OFFSET 0x0044
-#define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0044)
-#define OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048
-#define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0048)
-#define OMAP4_CM_CLKSEL_DPLL_PER_OFFSET 0x004c
-#define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x004c)
-#define OMAP4_CM_DIV_M2_DPLL_PER_OFFSET 0x0050
-#define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0050)
-#define OMAP4_CM_DIV_M3_DPLL_PER_OFFSET 0x0054
-#define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0054)
-#define OMAP4_CM_DIV_M4_DPLL_PER_OFFSET 0x0058
-#define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0058)
-#define OMAP4_CM_DIV_M5_DPLL_PER_OFFSET 0x005c
-#define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x005c)
-#define OMAP4_CM_DIV_M6_DPLL_PER_OFFSET 0x0060
-#define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0060)
-#define OMAP4_CM_DIV_M7_DPLL_PER_OFFSET 0x0064
-#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0064)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0068)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x006c)
-#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
-#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0080)
-#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084
-#define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0084)
-#define OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088
-#define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0088)
-#define OMAP4_CM_CLKSEL_DPLL_USB_OFFSET 0x008c
-#define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x008c)
-#define OMAP4_CM_DIV_M2_DPLL_USB_OFFSET 0x0090
-#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0090)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00a8)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ac)
-#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4
-#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00b4)
-#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0
-#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c0)
-#define OMAP4_CM_IDLEST_DPLL_UNIPRO_OFFSET 0x00c4
-#define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c4)
-#define OMAP4_CM_AUTOIDLE_DPLL_UNIPRO_OFFSET 0x00c8
-#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c8)
-#define OMAP4_CM_CLKSEL_DPLL_UNIPRO_OFFSET 0x00cc
-#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00cc)
-#define OMAP4_CM_DIV_M2_DPLL_UNIPRO_OFFSET 0x00d0
-#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00d0)
-#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8
-#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00e8)
-#define OMAP4_CM_SSC_MODFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
-#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ec)
-
-/* CM2.ALWAYS_ON_CM2 register offsets */
-#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0000)
-#define OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0020)
-#define OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0028)
-#define OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET 0x0030
-#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0030)
-#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038
-#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0038)
-#define OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_ALWON_USBPHY_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0040)
-
-/* CM2.CORE_CM2 register offsets */
-#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0000)
-#define OMAP4_CM_L3_1_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0008)
-#define OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0020)
-#define OMAP4_CM_L3_2_CLKSTCTRL_OFFSET 0x0100
-#define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0100)
-#define OMAP4_CM_L3_2_DYNAMICDEP_OFFSET 0x0108
-#define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0108)
-#define OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET 0x0120
-#define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0120)
-#define OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET 0x0128
-#define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0128)
-#define OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET 0x0130
-#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0130)
-#define OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET 0x0200
-#define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0200)
-#define OMAP4_CM_DUCATI_STATICDEP_OFFSET 0x0204
-#define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0204)
-#define OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET 0x0208
-#define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0208)
-#define OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET 0x0220
-#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0220)
-#define OMAP4_CM_SDMA_CLKSTCTRL_OFFSET 0x0300
-#define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0300)
-#define OMAP4_CM_SDMA_STATICDEP_OFFSET 0x0304
-#define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0304)
-#define OMAP4_CM_SDMA_DYNAMICDEP_OFFSET 0x0308
-#define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0308)
-#define OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET 0x0320
-#define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0320)
-#define OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET 0x0400
-#define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0400)
-#define OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET 0x0420
-#define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0420)
-#define OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET 0x0428
-#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0428)
-#define OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET 0x0430
-#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0430)
-#define OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET 0x0438
-#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0438)
-#define OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET 0x0440
-#define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0440)
-#define OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET 0x0450
-#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0450)
-#define OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET 0x0458
-#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0458)
-#define OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET 0x0460
-#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0460)
-#define OMAP4_CM_D2D_CLKSTCTRL_OFFSET 0x0500
-#define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0500)
-#define OMAP4_CM_D2D_STATICDEP_OFFSET 0x0504
-#define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0504)
-#define OMAP4_CM_D2D_DYNAMICDEP_OFFSET 0x0508
-#define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0508)
-#define OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET 0x0520
-#define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0520)
-#define OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET 0x0528
-#define OMAP4430_CM_D2D_MODEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0528)
-#define OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET 0x0530
-#define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0530)
-#define OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600
-#define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0600)
-#define OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608
-#define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0608)
-#define OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620
-#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0620)
-#define OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET 0x0628
-#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0628)
-#define OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630
-#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0630)
-#define OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638
-#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0638)
-#define OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700
-#define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0700)
-#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET 0x0720
-#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0720)
-#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728
-#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0728)
-#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET 0x0740
-#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0740)
-
-/* CM2.IVAHD_CM2 register offsets */
-#define OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0000)
-#define OMAP4_CM_IVAHD_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0004)
-#define OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0008)
-#define OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0020)
-#define OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0028)
-
-/* CM2.CAM_CM2 register offsets */
-#define OMAP4_CM_CAM_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0000)
-#define OMAP4_CM_CAM_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0004)
-#define OMAP4_CM_CAM_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0008)
-#define OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0020)
-#define OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0028)
-
-/* CM2.DSS_CM2 register offsets */
-#define OMAP4_CM_DSS_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0000)
-#define OMAP4_CM_DSS_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0004)
-#define OMAP4_CM_DSS_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0008)
-#define OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0020)
-#define OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0028)
-/* CM2.GFX_CM2 register offsets */
-#define OMAP4_CM_GFX_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0000)
-#define OMAP4_CM_GFX_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0004)
-#define OMAP4_CM_GFX_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0008)
-#define OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0020)
+#include "prcm-common.h"
+#include "cm.h"
-/* CM2.L3INIT_CM2 register offsets */
-#define OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0000)
-#define OMAP4_CM_L3INIT_STATICDEP_OFFSET 0x0004
-#define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0004)
-#define OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0008)
-#define OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0028)
-#define OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030
-#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0030)
-#define OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038
-#define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0038)
-#define OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0040)
-#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET 0x0058
-#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0058)
-#define OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET 0x0060
-#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0060)
-#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET 0x0068
-#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0068)
-#define OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET 0x0078
-#define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0078)
-#define OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET 0x0080
-#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0080)
-#define OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088
-#define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0088)
-#define OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET 0x0090
-#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0090)
-#define OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET 0x0098
-#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0098)
-#define OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET 0x00a8
-#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00a8)
-#define OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET 0x00c0
-#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c0)
-#define OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET 0x00c8
-#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c8)
-#define OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET 0x00d0
-#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00d0)
-#define OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET 0x00e0
-#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00e0)
+#define OMAP4_CM_CLKSTCTRL 0x0000
-/* CM2.L4PER_CM2 register offsets */
-#define OMAP4_CM_L4PER_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0000)
-#define OMAP4_CM_L4PER_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0008)
-#define OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0020)
-#define OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0028)
-#define OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET 0x0030
-#define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0030)
-#define OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET 0x0038
-#define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0038)
-#define OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0040)
-#define OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET 0x0048
-#define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0048)
-#define OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET 0x0050
-#define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0050)
-#define OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058
-#define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0058)
-#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060
-#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0060)
-#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068
-#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0068)
-#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070
-#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0070)
-#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078
-#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0078)
-#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080
-#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0080)
-#define OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088
-#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0088)
-#define OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET 0x0090
-#define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0090)
-#define OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET 0x0098
-#define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0098)
-#define OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0
-#define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a0)
-#define OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8
-#define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a8)
-#define OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0
-#define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b0)
-#define OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8
-#define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b8)
-#define OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET 0x00c0
-#define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00c0)
-#define OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET 0x00d0
-#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d0)
-#define OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET 0x00d8
-#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d8)
-#define OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET 0x00e0
-#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e0)
-#define OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET 0x00e8
-#define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e8)
-#define OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0
-#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f0)
-#define OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8
-#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f8)
-#define OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100
-#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0100)
-#define OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108
-#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0108)
-#define OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET 0x0120
-#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0120)
-#define OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET 0x0128
-#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0128)
-#define OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET 0x0130
-#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0130)
-#define OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET 0x0138
-#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0138)
-#define OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140
-#define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0140)
-#define OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148
-#define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0148)
-#define OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150
-#define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0150)
-#define OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158
-#define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0158)
-#define OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET 0x0160
-#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0160)
-#define OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0168
-#define OMAP4430_CM_L4PER_I2C5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0168)
-#define OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180
-#define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0180)
-#define OMAP4_CM_L4SEC_STATICDEP_OFFSET 0x0184
-#define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0184)
-#define OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188
-#define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0188)
-#define OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0
-#define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a0)
-#define OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8
-#define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a8)
-#define OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0
-#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b0)
-#define OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET 0x01b8
-#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b8)
-#define OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0
-#define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c0)
-#define OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8
-#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c8)
-#define OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET 0x01d8
-#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01d8)
+/* Function prototypes */
+# ifndef __ASSEMBLER__
-/* CM2.CEFUSE_CM2 register offsets */
-#define OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0000)
-#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0020)
+extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
-/* CM2.RESTORE_CM2 register offsets */
-#define OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET 0x0000
-#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0000)
-#define OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET 0x0004
-#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0004)
-#define OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET 0x0008
-#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0008)
-#define OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET 0x000c
-#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x000c)
-#define OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET 0x0010
-#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0010)
-#define OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET 0x0014
-#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0014)
-#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET 0x0018
-#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0018)
-#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET 0x001c
-#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x001c)
-#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET 0x0020
-#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0020)
-#define OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET 0x0024
-#define OMAP4430_CM_CM2_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0024)
-#define OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET 0x0028
-#define OMAP4430_CM_D2D_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0028)
-#define OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET 0x002c
-#define OMAP4430_CM_L3_1_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x002c)
-#define OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET 0x0030
-#define OMAP4430_CM_L3_2_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0030)
-#define OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET 0x0034
-#define OMAP4430_CM_D2D_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0034)
-#define OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET 0x0038
-#define OMAP4430_CM_L4CFG_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0038)
-#define OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET 0x003c
-#define OMAP4430_CM_L4PER_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x003c)
-#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_RESTORE_OFFSET 0x0040
-#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0040)
-#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_RESTORE_OFFSET 0x0044
-#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0044)
-#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_RESTORE_OFFSET 0x0048
-#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0048)
-#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_RESTORE_OFFSET 0x004c
-#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x004c)
-#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_RESTORE_OFFSET 0x0050
-#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0050)
-#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET 0x0054
-#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0054)
-#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET 0x0058
-#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0058)
-#define OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET 0x005c
-#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x005c)
+# endif
#endif
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
deleted file mode 100644
index f8a660a1a4a6..000000000000
--- a/arch/arm/mach-omap2/cm4xxx.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * OMAP4 CM module functions
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can 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/types.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/atomic.h>
-
-#include <plat/common.h>
-
-#include "cm.h"
-#include "cm-regbits-44xx.h"
-
-/**
- * omap4_cm_wait_module_ready - wait for a module to be in 'func' state
- * @clkctrl_reg: CLKCTRL module address
- *
- * Wait for the module IDLEST to be functional. If the idle state is in any
- * the non functional state (trans, idle or disabled), module and thus the
- * sysconfig cannot be accessed and will probably lead to an "imprecise
- * external abort"
- *
- * Module idle state:
- * 0x0 func: Module is fully functional, including OCP
- * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
- * abortion
- * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
- * using separate functional clock
- * 0x3 disabled: Module is disabled and cannot be accessed
- *
- */
-int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
-{
- int i = 0;
-
- if (!clkctrl_reg)
- return 0;
-
- omap_test_timeout((
- ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
- (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
- OMAP4430_IDLEST_SHIFT) == 0x2)),
- MAX_MODULE_READY_TIME, i);
-
- return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
-}
-
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
new file mode 100644
index 000000000000..c04bbbea17a5
--- /dev/null
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -0,0 +1,214 @@
+/*
+ * OMAP4 CM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 needed since CM instances can be in the PRM, PRCM_MPU, CM1,
+ * or CM2 hardware modules. For example, the EMU_CM CM instance is in
+ * the PRM hardware module. What a mess...
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm44xx.h"
+#include "cminst44xx.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prm44xx.h"
+#include "prcm_mpu44xx.h"
+
+static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
+ [OMAP4430_INVALID_PRCM_PARTITION] = 0,
+ [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
+ [OMAP4430_CM1_PARTITION] = OMAP4430_CM1_BASE,
+ [OMAP4430_CM2_PARTITION] = OMAP4430_CM2_BASE,
+ [OMAP4430_SCRM_PARTITION] = 0,
+ [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
+};
+
+/* Read a register in a CM instance */
+u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx));
+}
+
+/* Write into a register in a CM instance */
+void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ __raw_writel(val, OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx));
+}
+
+/* Read-modify-write a register in CM1. Caller must lock */
+u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
+ s16 idx)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, idx);
+ v &= ~mask;
+ v |= bits;
+ omap4_cminst_write_inst_reg(v, part, inst, idx);
+
+ return v;
+}
+
+/*
+ *
+ */
+
+/**
+ * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield
+ * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted)
+ * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * @c must be the unshifted value for CLKTRCTRL - i.e., this function
+ * will handle the shift itself.
+ */
+static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+ v &= ~OMAP4430_CLKTRCTRL_MASK;
+ v |= c << OMAP4430_CLKTRCTRL_SHIFT;
+ omap4_cminst_write_inst_reg(v, part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+}
+
+/**
+ * omap4_cminst_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode?
+ * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs)
+ * is in hardware-supervised idle mode, or 0 otherwise.
+ */
+bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+ v &= OMAP4430_CLKTRCTRL_MASK;
+ v >>= OMAP4430_CLKTRCTRL_SHIFT;
+
+ return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false;
+}
+
+/**
+ * omap4_cminst_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
+ * hardware-supervised idle mode. No return value.
+ */
+void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
+ * software-supervised idle mode, i.e., controlled manually by the
+ * Linux OMAP clockdomain code. No return value.
+ */
+void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into idle
+ * No return value.
+ */
+void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle,
+ * waking it up. No return value.
+ */
+void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap4_cm_wait_module_ready - wait for a module to be in 'func' state
+ * @clkctrl_reg: CLKCTRL module address
+ *
+ * Wait for the module IDLEST to be functional. If the idle state is in any
+ * the non functional state (trans, idle or disabled), module and thus the
+ * sysconfig cannot be accessed and will probably lead to an "imprecise
+ * external abort"
+ *
+ * Module idle state:
+ * 0x0 func: Module is fully functional, including OCP
+ * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
+ * abortion
+ * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
+ * using separate functional clock
+ * 0x3 disabled: Module is disabled and cannot be accessed
+ *
+ */
+int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
+{
+ int i = 0;
+
+ if (!clkctrl_reg)
+ return 0;
+
+ omap_test_timeout((
+ ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
+ (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
+ OMAP4430_IDLEST_SHIFT) == 0x2)),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
new file mode 100644
index 000000000000..a6abd0a8cb82
--- /dev/null
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -0,0 +1,31 @@
+/*
+ * OMAP4 Clock Management (CM) function prototypes
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
+#define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
+
+extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
+
+/*
+ * In an ideal world, we would not export these low-level functions,
+ * but this will probably take some time to fix properly
+ */
+extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx);
+extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
+extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
+ s16 inst, s16 idx);
+
+extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
+
+#endif
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 1fa3294b6048..695279419020 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -20,12 +20,16 @@
#include "cm-regbits-34xx.h"
#include "prm-regbits-34xx.h"
-#include "cm.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
#include "sdrc.h"
#include "pm.h"
#include "control.h"
+/* Used by omap3_ctrl_save_padconf() */
+#define START_PADCONF_SAVE 0x2
+#define PADCONF_SAVE_DONE 0x1
+
static void __iomem *omap2_ctrl_base;
static void __iomem *omap4_ctrl_pad_base;
@@ -134,6 +138,7 @@ struct omap3_control_regs {
u32 sramldo4;
u32 sramldo5;
u32 csi;
+ u32 padconf_sys_nirq;
};
static struct omap3_control_regs control_context;
@@ -209,6 +214,37 @@ void omap4_ctrl_pad_writel(u32 val, u16 offset)
__raw_writel(val, OMAP4_CTRL_PAD_REGADDR(offset));
}
+#ifdef CONFIG_ARCH_OMAP3
+
+/**
+ * omap3_ctrl_write_boot_mode - set scratchpad boot mode for the next boot
+ * @bootmode: 8-bit value to pass to some boot code
+ *
+ * Set the bootmode in the scratchpad RAM. This is used after the
+ * system restarts. Not sure what actually uses this - it may be the
+ * bootloader, rather than the boot ROM - contrary to the preserved
+ * comment below. No return value.
+ */
+void omap3_ctrl_write_boot_mode(u8 bootmode)
+{
+ u32 l;
+
+ l = ('B' << 24) | ('M' << 16) | bootmode;
+
+ /*
+ * 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,
+ * cf. OMAP34xx TRM, Initialization / Software Booting
+ * Configuration.
+ *
+ * XXX This should use some omap_ctrl_writel()-type function
+ */
+ __raw_writel(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4));
+}
+
+#endif
+
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
/*
* Clears the scratchpad contents in case of cold boot-
@@ -220,13 +256,13 @@ void omap3_clear_scratchpad_contents(void)
void __iomem *v_addr;
u32 offset = 0;
v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
- if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
+ if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
OMAP3430_GLOBAL_COLD_RST_MASK) {
for ( ; offset <= max_offset; offset += 0x4)
__raw_writel(0x0, (v_addr + offset));
- prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
- OMAP3430_GR_MOD,
- OMAP3_PRM_RSTST_OFFSET);
+ omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_RSTST_OFFSET);
}
}
@@ -239,9 +275,19 @@ void omap3_save_scratchpad_contents(void)
struct omap3_scratchpad_prcm_block prcm_block_contents;
struct omap3_scratchpad_sdrc_block sdrc_block_contents;
- /* Populate the Scratchpad contents */
+ /*
+ * Populate the Scratchpad contents
+ *
+ * The "get_*restore_pointer" functions are used to provide a
+ * physical restore address where the ROM code jumps while waking
+ * up from MPU OFF/OSWR state.
+ * The restore pointer is stored into the scratchpad.
+ */
scratchpad_contents.boot_config_ptr = 0x0;
- if (omap_rev() != OMAP3430_REV_ES3_0 &&
+ if (cpu_is_omap3630())
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(get_omap3630_restore_pointer());
+ else if (omap_rev() != OMAP3430_REV_ES3_0 &&
omap_rev() != OMAP3430_REV_ES3_1)
scratchpad_contents.public_restore_ptr =
virt_to_phys(get_restore_pointer());
@@ -258,32 +304,34 @@ void omap3_save_scratchpad_contents(void)
scratchpad_contents.sdrc_block_offset = 0x64;
/* Populate the PRCM block contents */
- prcm_block_contents.prm_clksrc_ctrl = prm_read_mod_reg(OMAP3430_GR_MOD,
- OMAP3_PRM_CLKSRC_CTRL_OFFSET);
- prcm_block_contents.prm_clksel = prm_read_mod_reg(OMAP3430_CCR_MOD,
- OMAP3_PRM_CLKSEL_OFFSET);
+ prcm_block_contents.prm_clksrc_ctrl =
+ omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+ prcm_block_contents.prm_clksel =
+ omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
+ OMAP3_PRM_CLKSEL_OFFSET);
prcm_block_contents.cm_clksel_core =
- cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
+ omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
prcm_block_contents.cm_clksel_wkup =
- cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
prcm_block_contents.cm_clken_pll =
- cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
prcm_block_contents.cm_autoidle_pll =
- cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
prcm_block_contents.cm_clksel1_pll =
- cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
prcm_block_contents.cm_clksel2_pll =
- cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
prcm_block_contents.cm_clksel3_pll =
- cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
prcm_block_contents.cm_clken_pll_mpu =
- cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
prcm_block_contents.cm_autoidle_pll_mpu =
- cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
prcm_block_contents.cm_clksel1_pll_mpu =
- cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
prcm_block_contents.cm_clksel2_pll_mpu =
- cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
prcm_block_contents.prcm_block_size = 0x0;
/* Populate the SDRC block contents */
@@ -416,6 +464,8 @@ void omap3_control_save_context(void)
control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4);
control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5);
control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI);
+ control_context.padconf_sys_nirq =
+ omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
return;
}
@@ -472,6 +522,43 @@ void omap3_control_restore_context(void)
omap_ctrl_writel(control_context.sramldo4, OMAP343X_CONTROL_SRAMLDO4);
omap_ctrl_writel(control_context.sramldo5, OMAP343X_CONTROL_SRAMLDO5);
omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI);
+ omap_ctrl_writel(control_context.padconf_sys_nirq,
+ OMAP343X_CONTROL_PADCONF_SYSNIRQ);
return;
}
+
+void omap3630_ctrl_disable_rta(void)
+{
+ if (!cpu_is_omap3630())
+ return;
+ omap_ctrl_writel(OMAP36XX_RTA_DISABLE, OMAP36XX_CONTROL_MEM_RTA_CTRL);
+}
+
+/**
+ * omap3_ctrl_save_padconf - save padconf registers to scratchpad RAM
+ *
+ * Tell the SCM to start saving the padconf registers, then wait for
+ * the process to complete. Returns 0 unconditionally, although it
+ * should also eventually be able to return -ETIMEDOUT, if the save
+ * does not complete.
+ *
+ * XXX This function is missing a timeout. What should it be?
+ */
+int omap3_ctrl_save_padconf(void)
+{
+ u32 cpo;
+
+ /* Save the padconf registers */
+ cpo = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
+ cpo |= START_PADCONF_SAVE;
+ omap_ctrl_writel(cpo, OMAP343X_CONTROL_PADCONF_OFF);
+
+ /* wait for the save to complete */
+ while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
+ & PADCONF_SAVE_DONE))
+ udelay(1);
+
+ return 0;
+}
+
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index b6c6b7c450b3..f0629ae04102 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -148,6 +148,15 @@
#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)
#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)
#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c)
+#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124)
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c)
+#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \
@@ -164,6 +173,26 @@
#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)
#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4)
+/* OMAP3630 only CONTROL_GENERAL register offsets */
+#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C)
+
+/* OMAP44xx control efuse offsets */
+#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C
+#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
+#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232
+#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235
+#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240
+#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243
+#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246
+#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
+
/* AM35XX only CONTROL_GENERAL register offsets */
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
@@ -204,6 +233,10 @@
#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
+/* 36xx-only RTA - Retention till Accesss control registers and bits */
+#define OMAP36XX_CONTROL_MEM_RTA_CTRL 0x40C
+#define OMAP36XX_RTA_DISABLE 0x0
+
/* 34xx D2D idle-related pins, handled by PM core */
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
@@ -270,6 +303,8 @@
#define OMAP343X_SCRATCHPAD_ROM (OMAP343X_CTRL_BASE + 0x860)
#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
+#define OMAP343X_SCRATCHPAD_REGADDR(reg) OMAP2_L4_IO_ADDRESS(\
+ OMAP343X_SCRATCHPAD + reg)
/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */
#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0
@@ -309,7 +344,7 @@
#define FEAT_SGX_NONE 2
#define OMAP3_IVA_SHIFT 12
-#define OMAP3_IVA_MASK (1 << OMAP3_SGX_SHIFT)
+#define OMAP3_IVA_MASK (1 << OMAP3_IVA_SHIFT)
#define FEAT_IVA 0
#define FEAT_IVA_NONE 1
@@ -347,10 +382,13 @@ extern void omap3_save_scratchpad_contents(void);
extern void omap3_clear_scratchpad_contents(void);
extern u32 *get_restore_pointer(void);
extern u32 *get_es3_restore_pointer(void);
+extern u32 *get_omap3630_restore_pointer(void);
extern u32 omap3_arm_context[128];
extern void omap3_control_save_context(void);
extern void omap3_control_restore_context(void);
-
+extern void omap3_ctrl_write_boot_mode(u8 bootmode);
+extern void omap3630_ctrl_disable_rta(void);
+extern int omap3_ctrl_save_padconf(void);
#else
#define omap_ctrl_base_get() 0
#define omap_ctrl_readb(x) 0
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 0d50b45d041c..f3e043fe5eb8 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -27,8 +27,8 @@
#include <plat/prcm.h>
#include <plat/irqs.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
#include <plat/serial.h>
#include "pm.h"
@@ -293,25 +293,26 @@ select_state:
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
/**
- * omap3_cpuidle_update_states - Update the cpuidle states.
+ * omap3_cpuidle_update_states() - Update the cpuidle states
+ * @mpu_deepest_state: Enable states upto and including this for mpu domain
+ * @core_deepest_state: Enable states upto and including this for core domain
*
- * Currently, this function toggles the validity of idle states based upon
- * the flag 'enable_off_mode'. When the flag is set all states are valid.
- * Else, states leading to OFF state set to be invalid.
+ * This goes through the list of states available and enables and disables the
+ * validity of C states based on deepest state that can be achieved for the
+ * variable domain
*/
-void omap3_cpuidle_update_states(void)
+void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
{
int i;
for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
struct omap3_processor_cx *cx = &omap3_power_states[i];
- if (enable_off_mode) {
+ if ((cx->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state)) {
cx->valid = 1;
} else {
- if ((cx->mpu_state == PWRDM_POWER_OFF) ||
- (cx->core_state == PWRDM_POWER_OFF))
- cx->valid = 0;
+ cx->valid = 0;
}
}
}
@@ -452,6 +453,18 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
CPUIDLE_FLAG_CHECK_BM;
+
+ /*
+ * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+ * enable OFF mode in a stable form for previous revisions.
+ * we disable C7 state as a result.
+ */
+ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
+ omap3_power_states[OMAP3_STATE_C7].valid = 0;
+ cpuidle_params_table[OMAP3_STATE_C7].valid = 0;
+ WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n",
+ __func__);
+ }
}
struct cpuidle_driver omap3_idle_driver = {
@@ -504,7 +517,10 @@ int __init omap3_idle_init(void)
return -EINVAL;
dev->state_count = count;
- omap3_cpuidle_update_states();
+ if (enable_off_mode)
+ omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
+ else
+ omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
if (cpuidle_register_device(dev)) {
printk(KERN_ERR "%s: CPUidle register device failed\n",
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 5a0c148e23bc..381f4eb92352 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -638,6 +638,7 @@ static struct platform_device dummy_pdev = {
static void __init omap_hsmmc_reset(void)
{
u32 i, nr_controllers;
+ struct clk *iclk, *fclk;
if (cpu_is_omap242x())
return;
@@ -647,7 +648,6 @@ static void __init omap_hsmmc_reset(void)
for (i = 0; i < nr_controllers; i++) {
u32 v, base = 0;
- struct clk *iclk, *fclk;
struct device *dev = &dummy_pdev.dev;
switch (i) {
@@ -678,19 +678,16 @@ static void __init omap_hsmmc_reset(void)
dummy_pdev.id = i;
dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
iclk = clk_get(dev, "ick");
- if (iclk && clk_enable(iclk))
- iclk = NULL;
+ if (IS_ERR(iclk))
+ goto err1;
+ if (clk_enable(iclk))
+ goto err2;
fclk = clk_get(dev, "fck");
- if (fclk && clk_enable(fclk))
- fclk = NULL;
-
- if (!iclk || !fclk) {
- printk(KERN_WARNING
- "%s: Unable to enable clocks for MMC%d, "
- "cannot reset.\n", __func__, i);
- break;
- }
+ if (IS_ERR(fclk))
+ goto err3;
+ if (clk_enable(fclk))
+ goto err4;
omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
v = omap_readl(base + MMCHS_SYSSTATUS);
@@ -698,15 +695,22 @@ static void __init omap_hsmmc_reset(void)
MMCHS_SYSSTATUS_RESETDONE))
cpu_relax();
- if (fclk) {
- clk_disable(fclk);
- clk_put(fclk);
- }
- if (iclk) {
- clk_disable(iclk);
- clk_put(iclk);
- }
+ clk_disable(fclk);
+ clk_put(fclk);
+ clk_disable(iclk);
+ clk_put(iclk);
}
+ return;
+
+err4:
+ clk_put(fclk);
+err3:
+ clk_disable(iclk);
+err2:
+ clk_put(iclk);
+err1:
+ printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, "
+ "cannot reset.\n", __func__, i);
}
#else
static inline void omap_hsmmc_reset(void) {}
@@ -951,72 +955,12 @@ static inline void omap_init_vout(void) {}
/*-------------------------------------------------------------------------*/
-/*
- * Inorder to avoid any assumptions from bootloader regarding WDT
- * settings, WDT module is reset during init. This enables the watchdog
- * timer. Hence it is required to disable the watchdog after the WDT reset
- * during init. Otherwise the system would reboot as per the default
- * watchdog timer registers settings.
- */
-#define OMAP_WDT_WPS (0x34)
-#define OMAP_WDT_SPR (0x48)
-
-static int omap2_disable_wdt(struct omap_hwmod *oh, void *unused)
-{
- void __iomem *base;
- int ret;
-
- if (!oh) {
- pr_err("%s: Could not look up wdtimer_hwmod\n", __func__);
- return -EINVAL;
- }
-
- base = omap_hwmod_get_mpu_rt_va(oh);
- if (!base) {
- pr_err("%s: Could not get the base address for %s\n",
- oh->name, __func__);
- return -EINVAL;
- }
-
- /* Enable the clocks before accessing the WDT registers */
- ret = omap_hwmod_enable(oh);
- if (ret) {
- pr_err("%s: Could not enable clocks for %s\n",
- oh->name, __func__);
- return ret;
- }
-
- /* sequence required to disable watchdog */
- __raw_writel(0xAAAA, base + OMAP_WDT_SPR);
- while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
- cpu_relax();
-
- __raw_writel(0x5555, base + OMAP_WDT_SPR);
- while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
- cpu_relax();
-
- ret = omap_hwmod_idle(oh);
- if (ret)
- pr_err("%s: Could not disable clocks for %s\n",
- oh->name, __func__);
-
- return ret;
-}
-
-static void __init omap_disable_wdt(void)
-{
- if (cpu_class_is_omap2())
- omap_hwmod_for_each_by_class("wd_timer",
- omap2_disable_wdt, NULL);
- return;
-}
-
static int __init omap2_init_devices(void)
{
- /* please keep these calls, and their implementations above,
+ /*
+ * please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- omap_disable_wdt();
omap_hsmmc_reset();
omap_init_audio();
omap_init_camera();
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
new file mode 100644
index 000000000000..d2f15f5cfd36
--- /dev/null
+++ b/arch/arm/mach-omap2/dma.c
@@ -0,0 +1,297 @@
+/*
+ * OMAP2+ DMA driver
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into platform driver
+ * - G, Manjunath Kondaiah <manjugk@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/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/dma.h>
+
+#define OMAP2_DMA_STRIDE 0x60
+
+static u32 errata;
+static u8 dma_stride;
+
+static struct omap_dma_dev_attr *d;
+
+static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
+
+static u16 reg_map[] = {
+ [REVISION] = 0x00,
+ [GCR] = 0x78,
+ [IRQSTATUS_L0] = 0x08,
+ [IRQSTATUS_L1] = 0x0c,
+ [IRQSTATUS_L2] = 0x10,
+ [IRQSTATUS_L3] = 0x14,
+ [IRQENABLE_L0] = 0x18,
+ [IRQENABLE_L1] = 0x1c,
+ [IRQENABLE_L2] = 0x20,
+ [IRQENABLE_L3] = 0x24,
+ [SYSSTATUS] = 0x28,
+ [OCP_SYSCONFIG] = 0x2c,
+ [CAPS_0] = 0x64,
+ [CAPS_2] = 0x6c,
+ [CAPS_3] = 0x70,
+ [CAPS_4] = 0x74,
+
+ /* Common register offsets */
+ [CCR] = 0x80,
+ [CLNK_CTRL] = 0x84,
+ [CICR] = 0x88,
+ [CSR] = 0x8c,
+ [CSDP] = 0x90,
+ [CEN] = 0x94,
+ [CFN] = 0x98,
+ [CSEI] = 0xa4,
+ [CSFI] = 0xa8,
+ [CDEI] = 0xac,
+ [CDFI] = 0xb0,
+ [CSAC] = 0xb4,
+ [CDAC] = 0xb8,
+
+ /* Channel specific register offsets */
+ [CSSA] = 0x9c,
+ [CDSA] = 0xa0,
+ [CCEN] = 0xbc,
+ [CCFN] = 0xc0,
+ [COLOR] = 0xc4,
+
+ /* OMAP4 specific registers */
+ [CDP] = 0xd0,
+ [CNDP] = 0xd4,
+ [CCDN] = 0xd8,
+};
+
+static struct omap_device_pm_latency omap2_dma_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ u8 stride;
+ u32 offset;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+ __raw_writel(val, dma_base + offset);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ u8 stride;
+ u32 offset, val;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+ val = __raw_readl(dma_base + offset);
+ return val;
+}
+
+static inline void omap2_disable_irq_lch(int lch)
+{
+ u32 val;
+
+ val = dma_read(IRQENABLE_L0, lch);
+ val &= ~(1 << lch);
+ dma_write(val, IRQENABLE_L0, lch);
+}
+
+static void omap2_clear_dma(int lch)
+{
+ int i = dma_common_ch_start;
+
+ for (; i <= dma_common_ch_end; i += 1)
+ dma_write(0, i, lch);
+}
+
+static void omap2_show_dma_caps(void)
+{
+ u8 revision = dma_read(REVISION, 0) & 0xff;
+ printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
+ revision >> 4, revision & 0xf);
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Errata applicable for OMAP2430ES1.0 and all omap2420
+ *
+ * I.
+ * Erratum ID: Not Available
+ * Inter Frame DMA buffering issue DMA will wrongly
+ * buffer elements if packing and bursting is enabled. This might
+ * result in data gets stalled in FIFO at the end of the block.
+ * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+ * guarantee no data will stay in the DMA FIFO in case inter frame
+ * buffering occurs
+ *
+ * II.
+ * Erratum ID: Not Available
+ * DMA may hang when several channels are used in parallel
+ * In the following configuration, DMA channel hanging can occur:
+ * a. Channel i, hardware synchronized, is enabled
+ * b. Another channel (Channel x), software synchronized, is enabled.
+ * c. Channel i is disabled before end of transfer
+ * d. Channel i is reenabled.
+ * e. Steps 1 to 4 are repeated a certain number of times.
+ * f. A third channel (Channel y), software synchronized, is enabled.
+ * Channel x and Channel y may hang immediately after step 'f'.
+ * Workaround:
+ * For any channel used - make sure NextLCH_ID is set to the value j.
+ */
+ if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+ (omap_type() == OMAP2430_REV_ES1_0))) {
+
+ SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
+ SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+ }
+
+ /*
+ * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled
+ * after a transaction error.
+ * Workaround: SW should explicitely disable the channel.
+ */
+ if (cpu_class_is_omap2())
+ SET_DMA_ERRATA(DMA_ERRATA_i378);
+
+ /*
+ * Erratum ID: i541: sDMA FIFO draining does not finish
+ * If sDMA channel is disabled on the fly, sDMA enters standby even
+ * through FIFO Drain is still in progress
+ * Workaround: Put sDMA in NoStandby more before a logical channel is
+ * disabled, then put it back to SmartStandby right after the channel
+ * finishes FIFO draining.
+ */
+ if (cpu_is_omap34xx())
+ SET_DMA_ERRATA(DMA_ERRATA_i541);
+
+ /*
+ * Erratum ID: i88 : Special programming model needed to disable DMA
+ * before end of block.
+ * Workaround: software must ensure that the DMA is configured in No
+ * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
+ */
+ if (omap_type() == OMAP3430_REV_ES1_0)
+ SET_DMA_ERRATA(DMA_ERRATA_i88);
+
+ /*
+ * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ /*
+ * Erratum ID: Not Available
+ * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
+ * after secure sram context save and restore.
+ * Work around: Hence we need to manually clear those IRQs to avoid
+ * spurious interrupts. This affects only secure devices.
+ */
+ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ SET_DMA_ERRATA(DMA_ROMCODE_BUG);
+
+ return errata;
+}
+
+/* One time initializations */
+static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
+{
+ struct omap_device *od;
+ struct omap_system_dma_plat_info *p;
+ struct resource *mem;
+ char *name = "omap_dma_system";
+
+ dma_stride = OMAP2_DMA_STRIDE;
+ dma_common_ch_start = CSDP;
+ if (cpu_is_omap3630() || cpu_is_omap4430())
+ dma_common_ch_end = CCDN;
+ else
+ dma_common_ch_end = CCFN;
+
+ p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+ if (!p) {
+ pr_err("%s: Unable to allocate pdata for %s:%s\n",
+ __func__, name, oh->name);
+ return -ENOMEM;
+ }
+
+ p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+ p->disable_irq_lch = omap2_disable_irq_lch;
+ p->show_dma_caps = omap2_show_dma_caps;
+ p->clear_dma = omap2_clear_dma;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+
+ p->clear_lch_regs = NULL;
+
+ p->errata = configure_dma_errata();
+
+ od = omap_device_build(name, 0, oh, p, sizeof(*p),
+ omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
+ kfree(p);
+ if (IS_ERR(od)) {
+ pr_err("%s: Cant build omap_device for %s:%s.\n",
+ __func__, name, oh->name);
+ return IS_ERR(od);
+ }
+
+ mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
+ }
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ d = oh->dev_attr;
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+
+ if (!d->chan) {
+ dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int __init omap2_system_dma_init(void)
+{
+ return omap_hwmod_for_each_by_class("dma",
+ omap2_system_dma_init_dev, NULL);
+}
+arch_initcall(omap2_system_dma_init);
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index ed8d330522f1..f77022be783d 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -26,15 +26,13 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/bitops.h>
+#include <linux/clkdev.h>
#include <plat/cpu.h>
#include <plat/clock.h>
-#include <asm/clkdev.h>
#include "clock.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
@@ -225,10 +223,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
}
/**
- * lookup_dco_sddiv - Set j-type DPLL4 compensation variables
+ * _lookup_dco - Lookup DCO used by j-type DPLL
* @clk: pointer to a DPLL struct clk
* @dco: digital control oscillator selector
- * @sd_div: target sigma-delta divider
* @m: DPLL multiplier to set
* @n: DPLL divider to set
*
@@ -237,11 +234,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
* XXX This code is not needed for 3430/AM35xx; can it be optimized
* out in non-multi-OMAP builds for those chips?
*/
-static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
- u8 n)
+static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
{
- unsigned long fint, clkinp, sd; /* watch out for overflow */
- int mod1, mod2;
+ unsigned long fint, clkinp; /* watch out for overflow */
clkinp = clk->parent->rate;
fint = (clkinp / n) * m;
@@ -250,6 +245,27 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
*dco = 2;
else
*dco = 4;
+}
+
+/**
+ * _lookup_sddiv - Calculate sigma delta divider for j-type DPLL
+ * @clk: pointer to a DPLL struct clk
+ * @sd_div: target sigma-delta divider
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ *
+ * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
+ *
+ * XXX This code is not needed for 3430/AM35xx; can it be optimized
+ * out in non-multi-OMAP builds for those chips?
+ */
+static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
+{
+ unsigned long clkinp, sd; /* watch out for overflow */
+ int mod1, mod2;
+
+ clkinp = clk->parent->rate;
+
/*
* target sigma-delta to near 250MHz
* sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
@@ -278,6 +294,7 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
{
struct dpll_data *dd = clk->dpll_data;
+ u8 dco, sd_div;
u32 v;
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
@@ -300,18 +317,16 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
v |= m << __ffs(dd->mult_mask);
v |= (n - 1) << __ffs(dd->div1_mask);
- /*
- * XXX This code is not needed for 3430/AM35XX; can it be optimized
- * out in non-multi-OMAP builds for those chips?
- */
- if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) {
- u8 dco, sd_div;
- lookup_dco_sddiv(clk, &dco, &sd_div, m, n);
- /* XXX This probably will need revision for OMAP4 */
- v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK
- | OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
- v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK);
- v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
+ /* Configure dco and sd_div for dplls that have these fields */
+ if (dd->dco_mask) {
+ _lookup_dco(clk, &dco, m, n);
+ v &= ~(dd->dco_mask);
+ v |= dco << __ffs(dd->dco_mask);
+ }
+ if (dd->sddiv_mask) {
+ _lookup_sddiv(clk, &sd_div, m, n);
+ v &= ~(dd->sddiv_mask);
+ v |= sd_div << __ffs(dd->sddiv_mask);
}
__raw_writel(v, dd->mult_div1_reg);
diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c
index 6feeeae6c21b..911cd2e68d46 100644
--- a/arch/arm/mach-omap2/dsp.c
+++ b/arch/arm/mach-omap2/dsp.c
@@ -11,9 +11,16 @@
* published by the Free Software Foundation.
*/
+/*
+ * XXX The function pointers to the PRM/CM functions are incorrect and
+ * should be removed. No device driver should be changing PRM/CM bits
+ * directly; that's a layering violation -- those bits are the responsibility
+ * of the OMAP PM core code.
+ */
+
#include <linux/platform_device.h>
-#include "prm.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
#ifdef CONFIG_BRIDGE_DVFS
#include <plat/omap-pm.h>
#endif
@@ -31,12 +38,12 @@ static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
.cpu_set_freq = omap_pm_cpu_set_freq,
.cpu_get_freq = omap_pm_cpu_get_freq,
#endif
- .dsp_prm_read = prm_read_mod_reg,
- .dsp_prm_write = prm_write_mod_reg,
- .dsp_prm_rmw_bits = prm_rmw_mod_reg_bits,
- .dsp_cm_read = cm_read_mod_reg,
- .dsp_cm_write = cm_write_mod_reg,
- .dsp_cm_rmw_bits = cm_rmw_mod_reg_bits,
+ .dsp_prm_read = omap2_prm_read_mod_reg,
+ .dsp_prm_write = omap2_prm_write_mod_reg,
+ .dsp_prm_rmw_bits = omap2_prm_rmw_mod_reg_bits,
+ .dsp_cm_read = omap2_cm_read_mod_reg,
+ .dsp_cm_write = omap2_cm_write_mod_reg,
+ .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits,
};
static int __init omap_dsp_init(void)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
new file mode 100644
index 000000000000..413de18c1d2b
--- /dev/null
+++ b/arch/arm/mach-omap2/gpio.c
@@ -0,0 +1,104 @@
+/*
+ * OMAP2+ specific gpio initialization
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct omap_device_pm_latency omap_gpio_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
+{
+ struct omap_device *od;
+ struct omap_gpio_platform_data *pdata;
+ struct omap_gpio_dev_attr *dev_attr;
+ char *name = "omap_gpio";
+ int id;
+
+ /*
+ * extract the device id from name field available in the
+ * hwmod database and use the same for constructing ids for
+ * gpio devices.
+ * CAUTION: Make sure the name in the hwmod database does
+ * not change. If changed, make corresponding change here
+ * or make use of static variable mechanism to handle this.
+ */
+ sscanf(oh->name, "gpio%d", &id);
+
+ pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("gpio%d: Memory allocation failed\n", id);
+ return -ENOMEM;
+ }
+
+ dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
+ pdata->bank_width = dev_attr->bank_width;
+ pdata->dbck_flag = dev_attr->dbck_flag;
+ pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
+
+ switch (oh->class->rev) {
+ case 0:
+ case 1:
+ pdata->bank_type = METHOD_GPIO_24XX;
+ break;
+ case 2:
+ pdata->bank_type = METHOD_GPIO_44XX;
+ break;
+ default:
+ WARN(1, "Invalid gpio bank_type\n");
+ kfree(pdata);
+ return -EINVAL;
+ }
+
+ od = omap_device_build(name, id - 1, oh, pdata,
+ sizeof(*pdata), omap_gpio_latency,
+ ARRAY_SIZE(omap_gpio_latency),
+ false);
+ kfree(pdata);
+
+ if (IS_ERR(od)) {
+ WARN(1, "Cant build omap_device for %s:%s.\n",
+ name, oh->name);
+ return PTR_ERR(od);
+ }
+
+ gpio_bank_count++;
+ return 0;
+}
+
+/*
+ * gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence gpio_init is a postcore_initcall.
+ */
+static int __init omap2_gpio_init(void)
+{
+ return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init,
+ NULL);
+}
+postcore_initcall(omap2_gpio_init);
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 722209601927..2bb29c160702 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -41,7 +41,7 @@ static int omap2_nand_gpmc_retime(void)
return 0;
memset(&t, 0, sizeof(t));
- t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
+ t.sync_clk = gpmc_nand_data->gpmc_t->sync_clk;
t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
t.adv_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->adv_on);
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 7bb69220adfa..3a7d25fb00ef 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -173,8 +173,17 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
}
switch (freq) {
+ case 104:
+ min_gpmc_clk_period = 9600; /* 104 MHz */
+ t_ces = 3;
+ t_avds = 4;
+ t_avdh = 2;
+ t_ach = 3;
+ t_aavdh = 6;
+ t_rdyo = 9;
+ break;
case 83:
- min_gpmc_clk_period = 12; /* 83 MHz */
+ min_gpmc_clk_period = 12000; /* 83 MHz */
t_ces = 5;
t_avds = 4;
t_avdh = 2;
@@ -183,7 +192,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
t_rdyo = 9;
break;
case 66:
- min_gpmc_clk_period = 15; /* 66 MHz */
+ min_gpmc_clk_period = 15000; /* 66 MHz */
t_ces = 6;
t_avds = 5;
t_avdh = 2;
@@ -192,7 +201,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
t_rdyo = 11;
break;
default:
- min_gpmc_clk_period = 18; /* 54 MHz */
+ min_gpmc_clk_period = 18500; /* 54 MHz */
t_ces = 7;
t_avds = 7;
t_avdh = 7;
@@ -271,8 +280,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
t.wr_cycle = t.rd_cycle;
if (cpu_is_omap34xx()) {
t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
- gpmc_ns_to_ticks(min_gpmc_clk_period +
- t_rdyo));
+ gpmc_ps_to_ticks(min_gpmc_clk_period +
+ t_rdyo * 1000));
t.wr_access = t.access;
}
} else {
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index f46933bc9373..1b7b3e7d02f7 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -168,6 +168,16 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
return (time_ns * 1000 + tick_ps - 1) / tick_ps;
}
+unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ps + tick_ps - 1) / tick_ps;
+}
+
unsigned int gpmc_ticks_to_ns(unsigned int ticks)
{
return ticks * gpmc_get_fclk_period() / 1000;
@@ -235,7 +245,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
int div;
u32 l;
- l = sync_clk * 1000 + (gpmc_get_fclk_period() - 1);
+ l = sync_clk + (gpmc_get_fclk_period() - 1);
div = l / gpmc_get_fclk_period();
if (div > 4)
return -1;
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
index 06e64e1fc28a..befa321c4c13 100644
--- a/arch/arm/mach-omap2/include/mach/entry-macro.S
+++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
@@ -38,41 +38,27 @@
*/
#ifdef MULTI_OMAP2
+
+/*
+ * We use __glue to avoid errors with multiple definitions of
+ * .globl omap_irq_base as it's included from entry-armv.S but not
+ * from entry-common.S.
+ */
+#ifdef __glue
.pushsection .data
-omap_irq_base: .word 0
+ .globl omap_irq_base
+omap_irq_base:
+ .word 0
.popsection
+#endif
- /* Configure the interrupt base on the first interrupt */
+ /*
+ * Configure the interrupt base on the first interrupt.
+ * See also omap_irq_base_init for setting omap_irq_base.
+ */
.macro get_irqnr_preamble, base, tmp
-9:
ldr \base, =omap_irq_base @ irq base address
ldr \base, [\base, #0] @ irq base value
- cmp \base, #0 @ already configured?
- bne 9997f @ nothing to do
-
- mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision
- and \tmp, \tmp, #0x000f0000 @ only check architecture
- 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
- cmp \tmp, #0x00000080 @ cortex A-8?
- beq 3400f @ found A-8 so it's omap34xx
- cmp \tmp, #0x00000090 @ cortex A-9?
- beq 4400f @ found A-9 so it's omap44xx
-2400: ldr \base, =OMAP2_IRQ_BASE
- ldr \tmp, =omap_irq_base
- str \base, [\tmp, #0]
- b 9b
-3400: ldr \base, =OMAP3_IRQ_BASE
- ldr \tmp, =omap_irq_base
- str \base, [\tmp, #0]
- b 9b
-4400: ldr \base, =OMAP4_IRQ_BASE
- ldr \tmp, =omap_irq_base
- str \base, [\tmp, #0]
- b 9b
-9997:
.endm
/* Check the pending interrupts. Note that base already set */
@@ -105,6 +91,35 @@ omap_irq_base: .word 0
9999:
.endm
+#ifdef CONFIG_SMP
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt
+ * on the controller, since this requires the original irqstat
+ * value which we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ it cc
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ it cs
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ itt eq
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+#endif /* CONFIG_SMP */
#else /* MULTI_OMAP2 */
@@ -141,74 +156,16 @@ omap_irq_base: .word 0
#ifdef CONFIG_ARCH_OMAP4
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
.macro get_irqnr_preamble, base, tmp
ldr \base, =OMAP4_IRQ_BASE
.endm
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an
- * interrupt if it's between 30 and 1020. The test_for_ipi
- * routine below will pick up on IPIs.
- * A simple read from the controller will tell us the number
- * of the highest priority enabled interrupt.
- * We then just need to check whether it is in the
- * valid range for an IRQ (30-1020 inclusive).
- */
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base, #GIC_CPU_INTACK]
-
- ldr \tmp, =1021
-
- bic \irqnr, \irqstat, #0x1c00
-
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
- .endm
#endif
-#endif /* MULTI_OMAP2 */
-
-#ifdef CONFIG_SMP
- /* We assume that irqstat (the raw value of the IRQ acknowledge
- * register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of interrupt
- * on the controller, since this requires the original irqstat
- * value which we won't easily be able to recreate later.
- */
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- it cc
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- it cs
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base are preserved */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- itt eq
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
-#endif /* CONFIG_SMP */
+#endif /* MULTI_OMAP2 */
.macro irq_prio_table
.endm
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index 2744dfee1ff4..5b0270b28934 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -24,7 +24,6 @@
extern void __iomem *l2cache_base;
#endif
-extern void __iomem *gic_cpu_base_addr;
extern void __iomem *gic_dist_base_addr;
extern void __init gic_init_irq(void);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 40562ddd3ee4..e66687b0b9de 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -39,13 +39,11 @@
#include "io.h"
#include <plat/omap-pm.h>
-#include <plat/powerdomain.h>
-#include "powerdomains.h"
-
-#include <plat/clockdomain.h>
-#include "clockdomains.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
#include <plat/omap_hwmod.h>
+#include <plat/multi.h>
/*
* The machine specific code may provide the extra mapping besides the
@@ -297,7 +295,7 @@ static int __init _omap2_init_reprogram_sdrc(void)
return 0;
dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
- if (!dpll3_m2_ck)
+ if (IS_ERR(dpll3_m2_ck))
return -EINVAL;
rate = clk_get_rate(dpll3_m2_ck);
@@ -311,24 +309,81 @@ static int __init _omap2_init_reprogram_sdrc(void)
return v;
}
-void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
- struct omap_sdrc_params *sdrc_cs1)
+static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
+{
+ return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
+}
+
+/*
+ * Initialize asm_irq_base for entry-macro.S
+ */
+static inline void omap_irq_base_init(void)
+{
+ extern void __iomem *omap_irq_base;
+
+#ifdef MULTI_OMAP2
+ if (cpu_is_omap24xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE);
+ else if (cpu_is_omap34xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE);
+ else if (cpu_is_omap44xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE);
+ else
+ pr_err("Could not initialize omap_irq_base\n");
+#endif
+}
+
+void __init omap2_init_common_infrastructure(void)
{
- u8 skip_setup_idle = 0;
+ u8 postsetup_state;
- pwrdm_init(powerdomains_omap);
- clkdm_init(clockdomains_omap, clkdm_autodeps);
- if (cpu_is_omap242x())
+ if (cpu_is_omap242x()) {
+ omap2xxx_powerdomains_init();
+ omap2_clockdomains_init();
omap2420_hwmod_init();
- else if (cpu_is_omap243x())
+ } else if (cpu_is_omap243x()) {
+ omap2xxx_powerdomains_init();
+ omap2_clockdomains_init();
omap2430_hwmod_init();
- else if (cpu_is_omap34xx())
+ } else if (cpu_is_omap34xx()) {
+ omap3xxx_powerdomains_init();
+ omap2_clockdomains_init();
omap3xxx_hwmod_init();
- else if (cpu_is_omap44xx())
+ } else if (cpu_is_omap44xx()) {
+ omap44xx_powerdomains_init();
+ omap44xx_clockdomains_init();
omap44xx_hwmod_init();
+ } else {
+ pr_err("Could not init hwmod data - unknown SoC\n");
+ }
+
+ /* Set the default postsetup state for all hwmods */
+#ifdef CONFIG_PM_RUNTIME
+ postsetup_state = _HWMOD_STATE_IDLE;
+#else
+ postsetup_state = _HWMOD_STATE_ENABLED;
+#endif
+ omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
+
+ /*
+ * Set the default postsetup state for unusual modules (like
+ * MPU WDT).
+ *
+ * The postsetup_state is not actually used until
+ * omap_hwmod_late_init(), so boards that desire full watchdog
+ * coverage of kernel initialization can reprogram the
+ * postsetup_state between the calls to
+ * omap2_init_common_infra() and omap2_init_common_devices().
+ *
+ * XXX ideally we could detect whether the MPU WDT was currently
+ * enabled here and make this conditional
+ */
+ postsetup_state = _HWMOD_STATE_DISABLED;
+ omap_hwmod_for_each_by_class("wd_timer",
+ _set_hwmod_postsetup_state,
+ &postsetup_state);
- /* The OPP tables have to be registered before a clk init */
- omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
+ omap_pm_if_early_init();
if (cpu_is_omap2420())
omap2420_clk_init();
@@ -339,17 +394,61 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
else if (cpu_is_omap44xx())
omap4xxx_clk_init();
else
- pr_err("Could not init clock framework - unknown CPU\n");
+ pr_err("Could not init clock framework - unknown SoC\n");
+}
+void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1)
+{
omap_serial_early_init();
-#ifndef CONFIG_PM_RUNTIME
- skip_setup_idle = 1;
-#endif
- omap_hwmod_late_init(skip_setup_idle);
+ omap_hwmod_late_init();
+
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc();
}
gpmc_init();
+
+ omap_irq_base_init();
+}
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+u8 omap_readb(u32 pa)
+{
+ return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readb);
+
+u16 omap_readw(u32 pa)
+{
+ return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readw);
+
+u32 omap_readl(u32 pa)
+{
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readl);
+
+void omap_writeb(u8 v, u32 pa)
+{
+ __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writeb);
+
+void omap_writew(u16 v, u32 pa)
+{
+ __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writew);
+
+void omap_writel(u32 v, u32 pa)
+{
+ __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
}
+EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 32eeabe9d2ab..85bf8ca95fd3 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -284,7 +284,10 @@ void omap3_intc_suspend(void)
void omap3_intc_prepare_idle(void)
{
- /* Disable autoidle as it can stall interrupt controller */
+ /*
+ * Disable autoidle as it can stall interrupt controller,
+ * cf. errata ID i540 for 3430 (all revisions up to 3.1.x)
+ */
intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
}
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 40ddecab93a9..394413dc7deb 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -281,7 +281,7 @@ static struct omap_mbox_ops omap2_mbox_ops = {
/* FIXME: the following structs should be filled automatically by the user id */
-#if defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_ARCH_OMAP2420)
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2)
/* DSP */
static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
.tx_fifo = {
@@ -306,7 +306,7 @@ struct omap_mbox mbox_dsp_info = {
};
#endif
-#if defined(CONFIG_ARCH_OMAP3430)
+#if defined(CONFIG_ARCH_OMAP3)
struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL };
#endif
@@ -394,15 +394,19 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
if (false)
;
-#if defined(CONFIG_ARCH_OMAP3430)
- else if (cpu_is_omap3430()) {
+#if defined(CONFIG_ARCH_OMAP3)
+ else if (cpu_is_omap34xx()) {
list = omap3_mboxes;
list[0]->irq = platform_get_irq_byname(pdev, "dsp");
}
#endif
-#if defined(CONFIG_ARCH_OMAP2420)
- else if (cpu_is_omap2420()) {
+#if defined(CONFIG_ARCH_OMAP2)
+ else if (cpu_is_omap2430()) {
+ list = omap2_mboxes;
+
+ list[0]->irq = platform_get_irq_byname(pdev, "dsp");
+ } else if (cpu_is_omap2420()) {
list = omap2_mboxes;
list[0]->irq = platform_get_irq_byname(pdev, "dsp");
@@ -432,9 +436,8 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
iounmap(mbox_base);
return ret;
}
- return 0;
- return ret;
+ return 0;
}
static int __devexit omap2_mbox_remove(struct platform_device *pdev)
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 074536ae401f..17bd6394d224 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -1,9 +1,9 @@
/*
* linux/arch/arm/mach-omap2/mux.c
*
- * OMAP2 and OMAP3 pin multiplexing configurations
+ * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
*
- * Copyright (C) 2004 - 2008 Texas Instruments Inc.
+ * Copyright (C) 2004 - 2010 Texas Instruments Inc.
* Copyright (C) 2003 - 2008 Nokia Corporation
*
* Written by Tony Lindgren
@@ -35,65 +35,79 @@
#include <asm/system.h>
+#include <plat/omap_hwmod.h>
+
#include "control.h"
#include "mux.h"
#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
#define OMAP_MUX_BASE_SZ 0x5ca
-#define MUXABLE_GPIO_MODE3 BIT(0)
struct omap_mux_entry {
struct omap_mux mux;
struct list_head node;
};
-static unsigned long mux_phys;
-static void __iomem *mux_base;
-static u8 omap_mux_flags;
+static LIST_HEAD(mux_partitions);
+static DEFINE_MUTEX(muxmode_mutex);
+
+struct omap_mux_partition *omap_mux_get(const char *name)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ if (!strcmp(name, partition->name))
+ return partition;
+ }
+
+ return NULL;
+}
-u16 omap_mux_read(u16 reg)
+u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
{
- if (cpu_is_omap24xx())
- return __raw_readb(mux_base + reg);
+ if (partition->flags & OMAP_MUX_REG_8BIT)
+ return __raw_readb(partition->base + reg);
else
- return __raw_readw(mux_base + reg);
+ return __raw_readw(partition->base + reg);
}
-void omap_mux_write(u16 val, u16 reg)
+void omap_mux_write(struct omap_mux_partition *partition, u16 val,
+ u16 reg)
{
- if (cpu_is_omap24xx())
- __raw_writeb(val, mux_base + reg);
+ if (partition->flags & OMAP_MUX_REG_8BIT)
+ __raw_writeb(val, partition->base + reg);
else
- __raw_writew(val, mux_base + reg);
+ __raw_writew(val, partition->base + reg);
}
-void omap_mux_write_array(struct omap_board_mux *board_mux)
+void omap_mux_write_array(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
{
- while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
- omap_mux_write(board_mux->value, board_mux->reg_offset);
+ while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
+ omap_mux_write(partition, board_mux->value,
+ board_mux->reg_offset);
board_mux++;
}
}
-static LIST_HEAD(muxmodes);
-static DEFINE_MUTEX(muxmode_mutex);
-
#ifdef CONFIG_OMAP_MUX
static char *omap_mux_options;
-int __init omap_mux_init_gpio(int gpio, int val)
+static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
+ int gpio, int val)
{
struct omap_mux_entry *e;
struct omap_mux *gpio_mux = NULL;
u16 old_mode;
u16 mux_mode;
int found = 0;
+ struct list_head *muxmodes = &partition->muxmodes;
if (!gpio)
return -EINVAL;
- list_for_each_entry(e, &muxmodes, node) {
+ list_for_each_entry(e, muxmodes, node) {
struct omap_mux *m = &e->mux;
if (gpio == m->gpio) {
gpio_mux = m;
@@ -102,34 +116,52 @@ int __init omap_mux_init_gpio(int gpio, int val)
}
if (found == 0) {
- printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
+ pr_err("%s: Could not set gpio%i\n", __func__, gpio);
return -ENODEV;
}
if (found > 1) {
- printk(KERN_INFO "mux: Multiple gpio paths (%d) for gpio%i\n",
- found, gpio);
+ pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
+ found, gpio);
return -EINVAL;
}
- old_mode = omap_mux_read(gpio_mux->reg_offset);
+ old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
- if (omap_mux_flags & MUXABLE_GPIO_MODE3)
+ if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
mux_mode |= OMAP_MUX_MODE3;
else
mux_mode |= OMAP_MUX_MODE4;
- printk(KERN_DEBUG "mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n",
- gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
- omap_mux_write(mux_mode, gpio_mux->reg_offset);
+ pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
+ gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
+ omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
return 0;
}
-int __init omap_mux_init_signal(const char *muxname, int val)
+int __init omap_mux_init_gpio(int gpio, int val)
+{
+ struct omap_mux_partition *partition;
+ int ret;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ ret = _omap_mux_init_gpio(partition, gpio, val);
+ if (!ret)
+ return ret;
+ }
+
+ return -ENODEV;
+}
+
+static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
+ const char *muxname,
+ struct omap_mux **found_mux)
{
+ struct omap_mux *mux = NULL;
struct omap_mux_entry *e;
const char *mode_name;
- int found = 0, mode0_len = 0;
+ int found = 0, found_mode, mode0_len = 0;
+ struct list_head *muxmodes = &partition->muxmodes;
mode_name = strchr(muxname, '.');
if (mode_name) {
@@ -139,51 +171,200 @@ int __init omap_mux_init_signal(const char *muxname, int val)
mode_name = muxname;
}
- list_for_each_entry(e, &muxmodes, node) {
- struct omap_mux *m = &e->mux;
- char *m0_entry = m->muxnames[0];
+ list_for_each_entry(e, muxmodes, node) {
+ char *m0_entry;
int i;
+ mux = &e->mux;
+ m0_entry = mux->muxnames[0];
+
/* First check for full name in mode0.muxmode format */
if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
continue;
/* Then check for muxmode only */
for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
- char *mode_cur = m->muxnames[i];
+ char *mode_cur = mux->muxnames[i];
if (!mode_cur)
continue;
if (!strcmp(mode_name, mode_cur)) {
- u16 old_mode;
- u16 mux_mode;
-
- old_mode = omap_mux_read(m->reg_offset);
- mux_mode = val | i;
- printk(KERN_DEBUG "mux: Setting signal "
- "%s.%s 0x%04x -> 0x%04x\n",
- m0_entry, muxname, old_mode, mux_mode);
- omap_mux_write(mux_mode, m->reg_offset);
+ *found_mux = mux;
found++;
+ found_mode = i;
}
}
}
- if (found == 1)
- return 0;
+ if (found == 1) {
+ return found_mode;
+ }
if (found > 1) {
- printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n",
- found, muxname);
+ pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
+ found, muxname);
return -EINVAL;
}
- printk(KERN_ERR "mux: Could not set signal %s\n", muxname);
+ pr_err("%s: Could not find signal %s\n", __func__, muxname);
return -ENODEV;
}
+static int __init
+omap_mux_get_by_name(const char *muxname,
+ struct omap_mux_partition **found_partition,
+ struct omap_mux **found_mux)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct omap_mux *mux = NULL;
+ int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
+ if (mux_mode < 0)
+ continue;
+
+ *found_partition = partition;
+ *found_mux = mux;
+
+ return mux_mode;
+ }
+
+ return -ENODEV;
+}
+
+int __init omap_mux_init_signal(const char *muxname, int val)
+{
+ struct omap_mux_partition *partition = NULL;
+ struct omap_mux *mux = NULL;
+ u16 old_mode;
+ int mux_mode;
+
+ mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
+ if (mux_mode < 0)
+ return mux_mode;
+
+ old_mode = omap_mux_read(partition, mux->reg_offset);
+ mux_mode |= val;
+ pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
+ __func__, muxname, old_mode, mux_mode);
+ omap_mux_write(partition, mux_mode, mux->reg_offset);
+
+ return 0;
+}
+
+struct omap_hwmod_mux_info * __init
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+ struct omap_hwmod_mux_info *hmux;
+ int i;
+
+ if (!bpads || nr_pads < 1)
+ return NULL;
+
+ hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
+ if (!hmux)
+ goto err1;
+
+ hmux->nr_pads = nr_pads;
+
+ hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
+ nr_pads, GFP_KERNEL);
+ if (!hmux->pads)
+ goto err2;
+
+ for (i = 0; i < hmux->nr_pads; i++) {
+ struct omap_mux_partition *partition;
+ struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
+ struct omap_mux *mux;
+ int mux_mode;
+
+ mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
+ if (mux_mode < 0)
+ goto err3;
+ if (!pad->partition)
+ pad->partition = partition;
+ if (!pad->mux)
+ pad->mux = mux;
+
+ pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
+ if (!pad->name) {
+ int j;
+
+ for (j = i - 1; j >= 0; j--)
+ kfree(hmux->pads[j].name);
+ goto err3;
+ }
+ strcpy(pad->name, bpad->name);
+
+ pad->flags = bpad->flags;
+ pad->enable = bpad->enable;
+ pad->idle = bpad->idle;
+ pad->off = bpad->off;
+ pr_debug("%s: Initialized %s\n", __func__, pad->name);
+ }
+
+ return hmux;
+
+err3:
+ kfree(hmux->pads);
+err2:
+ kfree(hmux);
+err1:
+ pr_err("%s: Could not allocate device mux entry\n", __func__);
+
+ return NULL;
+}
+
+/* Assumes the calling function takes care of locking */
+void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
+{
+ int i;
+
+ for (i = 0; i < hmux->nr_pads; i++) {
+ struct omap_device_pad *pad = &hmux->pads[i];
+ int flags, val = -EINVAL;
+
+ flags = pad->flags;
+
+ switch (state) {
+ case _HWMOD_STATE_ENABLED:
+ if (flags & OMAP_DEVICE_PAD_ENABLED)
+ break;
+ flags |= OMAP_DEVICE_PAD_ENABLED;
+ val = pad->enable;
+ pr_debug("%s: Enabling %s %x\n", __func__,
+ pad->name, val);
+ break;
+ case _HWMOD_STATE_IDLE:
+ if (!(flags & OMAP_DEVICE_PAD_REMUX))
+ break;
+ flags &= ~OMAP_DEVICE_PAD_ENABLED;
+ val = pad->idle;
+ pr_debug("%s: Idling %s %x\n", __func__,
+ pad->name, val);
+ break;
+ case _HWMOD_STATE_DISABLED:
+ default:
+ /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
+ if (flags & OMAP_DEVICE_PAD_REMUX)
+ val = pad->off;
+ else
+ val = OMAP_MUX_MODE7;
+ flags &= ~OMAP_DEVICE_PAD_ENABLED;
+ pr_debug("%s: Disabling %s %x\n", __func__,
+ pad->name, val);
+ };
+
+ if (val >= 0) {
+ omap_mux_write(pad->partition, val,
+ pad->mux->reg_offset);
+ pad->flags = flags;
+ }
+ }
+}
+
#ifdef CONFIG_DEBUG_FS
#define OMAP_MUX_MAX_NR_FLAGS 10
@@ -248,13 +429,15 @@ static inline void omap_mux_decode(struct seq_file *s, u16 val)
} while (i-- > 0);
}
-#define OMAP_MUX_DEFNAME_LEN 16
+#define OMAP_MUX_DEFNAME_LEN 32
static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
{
+ struct omap_mux_partition *partition = s->private;
struct omap_mux_entry *e;
+ u8 omap_gen = omap_rev() >> 28;
- list_for_each_entry(e, &muxmodes, node) {
+ list_for_each_entry(e, &partition->muxmodes, node) {
struct omap_mux *m = &e->mux;
char m0_def[OMAP_MUX_DEFNAME_LEN];
char *m0_name = m->muxnames[0];
@@ -272,11 +455,16 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
}
m0_def[i] = toupper(m0_name[i]);
}
- val = omap_mux_read(m->reg_offset);
+ val = omap_mux_read(partition, m->reg_offset);
mode = val & OMAP_MUX_MODE7;
-
- seq_printf(s, "OMAP%i_MUX(%s, ",
- cpu_is_omap34xx() ? 3 : 0, m0_def);
+ if (mode != 0)
+ seq_printf(s, "/* %s */\n", m->muxnames[mode]);
+
+ /*
+ * XXX: Might be revisited to support differences accross
+ * same OMAP generation.
+ */
+ seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
omap_mux_decode(s, val);
seq_printf(s, "),\n");
}
@@ -286,7 +474,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
{
- return single_open(file, omap_mux_dbg_board_show, &inode->i_private);
+ return single_open(file, omap_mux_dbg_board_show, inode->i_private);
}
static const struct file_operations omap_mux_dbg_board_fops = {
@@ -296,19 +484,43 @@ static const struct file_operations omap_mux_dbg_board_fops = {
.release = single_release,
};
+static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct list_head *muxmodes = &partition->muxmodes;
+ struct omap_mux_entry *e;
+
+ list_for_each_entry(e, muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+
+ if (m == mux)
+ return partition;
+ }
+ }
+
+ return NULL;
+}
+
static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
{
struct omap_mux *m = s->private;
+ struct omap_mux_partition *partition;
const char *none = "NA";
u16 val;
int mode;
- val = omap_mux_read(m->reg_offset);
+ partition = omap_mux_get_partition(m);
+ if (!partition)
+ return 0;
+
+ val = omap_mux_read(partition, m->reg_offset);
mode = val & OMAP_MUX_MODE7;
- seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n",
+ seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
m->muxnames[0], m->muxnames[mode],
- mux_phys + m->reg_offset, m->reg_offset, val,
+ partition->phys + m->reg_offset, m->reg_offset, val,
m->balls[0] ? m->balls[0] : none,
m->balls[1] ? m->balls[1] : none);
seq_printf(s, "mode: ");
@@ -330,14 +542,15 @@ static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
#define OMAP_MUX_MAX_ARG_CHAR 7
static ssize_t omap_mux_dbg_signal_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
{
char buf[OMAP_MUX_MAX_ARG_CHAR];
struct seq_file *seqf;
struct omap_mux *m;
unsigned long val;
int buf_size, ret;
+ struct omap_mux_partition *partition;
if (count > OMAP_MUX_MAX_ARG_CHAR)
return -EINVAL;
@@ -358,7 +571,11 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file,
seqf = file->private_data;
m = seqf->private;
- omap_mux_write((u16)val, m->reg_offset);
+ partition = omap_mux_get_partition(m);
+ if (!partition)
+ return -ENODEV;
+
+ omap_mux_write(partition, (u16)val, m->reg_offset);
*ppos += count;
return count;
@@ -379,22 +596,38 @@ static const struct file_operations omap_mux_dbg_signal_fops = {
static struct dentry *mux_dbg_dir;
-static void __init omap_mux_dbg_init(void)
+static void __init omap_mux_dbg_create_entry(
+ struct omap_mux_partition *partition,
+ struct dentry *mux_dbg_dir)
{
struct omap_mux_entry *e;
+ list_for_each_entry(e, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+
+ (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
+ m, &omap_mux_dbg_signal_fops);
+ }
+}
+
+static void __init omap_mux_dbg_init(void)
+{
+ struct omap_mux_partition *partition;
+ static struct dentry *mux_dbg_board_dir;
+
mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
if (!mux_dbg_dir)
return;
- (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir,
- NULL, &omap_mux_dbg_board_fops);
-
- list_for_each_entry(e, &muxmodes, node) {
- struct omap_mux *m = &e->mux;
+ mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
+ if (!mux_dbg_board_dir)
+ return;
- (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
- m, &omap_mux_dbg_signal_fops);
+ list_for_each_entry(partition, &mux_partitions, node) {
+ omap_mux_dbg_create_entry(partition, mux_dbg_dir);
+ (void)debugfs_create_file(partition->name, S_IRUGO,
+ mux_dbg_board_dir, partition,
+ &omap_mux_dbg_board_fops);
}
}
@@ -421,23 +654,25 @@ static void __init omap_mux_free_names(struct omap_mux *m)
/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
static int __init omap_mux_late_init(void)
{
- struct omap_mux_entry *e, *tmp;
+ struct omap_mux_partition *partition;
- list_for_each_entry_safe(e, tmp, &muxmodes, node) {
- struct omap_mux *m = &e->mux;
- u16 mode = omap_mux_read(m->reg_offset);
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct omap_mux_entry *e, *tmp;
+ list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+ u16 mode = omap_mux_read(partition, m->reg_offset);
- if (OMAP_MODE_GPIO(mode))
- continue;
+ if (OMAP_MODE_GPIO(mode))
+ continue;
#ifndef CONFIG_DEBUG_FS
- mutex_lock(&muxmode_mutex);
- list_del(&e->node);
- mutex_unlock(&muxmode_mutex);
- omap_mux_free_names(m);
- kfree(m);
+ mutex_lock(&muxmode_mutex);
+ list_del(&e->node);
+ mutex_unlock(&muxmode_mutex);
+ omap_mux_free_names(m);
+ kfree(m);
#endif
-
+ }
}
omap_mux_dbg_init();
@@ -462,8 +697,8 @@ static void __init omap_mux_package_fixup(struct omap_mux *p,
s++;
}
if (!found)
- printk(KERN_ERR "mux: Unknown entry offset 0x%x\n",
- p->reg_offset);
+ pr_err("%s: Unknown entry offset 0x%x\n", __func__,
+ p->reg_offset);
p++;
}
}
@@ -487,8 +722,8 @@ static void __init omap_mux_package_init_balls(struct omap_ball *b,
s++;
}
if (!found)
- printk(KERN_ERR "mux: Unknown ball offset 0x%x\n",
- b->reg_offset);
+ pr_err("%s: Unknown ball offset 0x%x\n", __func__,
+ b->reg_offset);
b++;
}
}
@@ -554,7 +789,7 @@ static void __init omap_mux_set_cmdline_signals(void)
}
static int __init omap_mux_copy_names(struct omap_mux *src,
- struct omap_mux *dst)
+ struct omap_mux *dst)
{
int i;
@@ -592,51 +827,63 @@ free:
#endif /* CONFIG_OMAP_MUX */
-static u16 omap_mux_get_by_gpio(int gpio)
+static struct omap_mux *omap_mux_get_by_gpio(
+ struct omap_mux_partition *partition,
+ int gpio)
{
struct omap_mux_entry *e;
- u16 offset = OMAP_MUX_TERMINATOR;
+ struct omap_mux *ret = NULL;
- list_for_each_entry(e, &muxmodes, node) {
+ list_for_each_entry(e, &partition->muxmodes, node) {
struct omap_mux *m = &e->mux;
if (m->gpio == gpio) {
- offset = m->reg_offset;
+ ret = m;
break;
}
}
- return offset;
+ return ret;
}
/* Needed for dynamic muxing of GPIO pins for off-idle */
u16 omap_mux_get_gpio(int gpio)
{
- u16 offset;
+ struct omap_mux_partition *partition;
+ struct omap_mux *m;
- offset = omap_mux_get_by_gpio(gpio);
- if (offset == OMAP_MUX_TERMINATOR) {
- printk(KERN_ERR "mux: Could not get gpio%i\n", gpio);
- return offset;
+ list_for_each_entry(partition, &mux_partitions, node) {
+ m = omap_mux_get_by_gpio(partition, gpio);
+ if (m)
+ return omap_mux_read(partition, m->reg_offset);
}
- return omap_mux_read(offset);
+ if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
+ pr_err("%s: Could not get gpio%i\n", __func__, gpio);
+
+ return OMAP_MUX_TERMINATOR;
}
/* Needed for dynamic muxing of GPIO pins for off-idle */
void omap_mux_set_gpio(u16 val, int gpio)
{
- u16 offset;
+ struct omap_mux_partition *partition;
+ struct omap_mux *m = NULL;
- offset = omap_mux_get_by_gpio(gpio);
- if (offset == OMAP_MUX_TERMINATOR) {
- printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
- return;
+ list_for_each_entry(partition, &mux_partitions, node) {
+ m = omap_mux_get_by_gpio(partition, gpio);
+ if (m) {
+ omap_mux_write(partition, val, m->reg_offset);
+ return;
+ }
}
- omap_mux_write(val, offset);
+ if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
+ pr_err("%s: Could not set gpio%i\n", __func__, gpio);
}
-static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
+static struct omap_mux * __init omap_mux_list_add(
+ struct omap_mux_partition *partition,
+ struct omap_mux *src)
{
struct omap_mux_entry *entry;
struct omap_mux *m;
@@ -656,7 +903,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
#endif
mutex_lock(&muxmode_mutex);
- list_add_tail(&entry->node, &muxmodes);
+ list_add_tail(&entry->node, &partition->muxmodes);
mutex_unlock(&muxmode_mutex);
return m;
@@ -667,7 +914,8 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
* the GPIO to mux offset mapping that is needed for dynamic muxing
* of GPIO pins for off-idle.
*/
-static void __init omap_mux_init_list(struct omap_mux *superset)
+static void __init omap_mux_init_list(struct omap_mux_partition *partition,
+ struct omap_mux *superset)
{
while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
struct omap_mux *entry;
@@ -679,15 +927,16 @@ static void __init omap_mux_init_list(struct omap_mux *superset)
}
#else
/* Skip pins that are not muxed as GPIO by bootloader */
- if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
+ if (!OMAP_MODE_GPIO(omap_mux_read(partition,
+ superset->reg_offset))) {
superset++;
continue;
}
#endif
- entry = omap_mux_list_add(superset);
+ entry = omap_mux_list_add(partition, superset);
if (!entry) {
- printk(KERN_ERR "mux: Could not add entry\n");
+ pr_err("%s: Could not add entry\n", __func__);
return;
}
superset++;
@@ -706,10 +955,11 @@ static void omap_mux_init_package(struct omap_mux *superset,
omap_mux_package_init_balls(package_balls, superset);
}
-static void omap_mux_init_signals(struct omap_board_mux *board_mux)
+static void omap_mux_init_signals(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
{
omap_mux_set_cmdline_signals();
- omap_mux_write_array(board_mux);
+ omap_mux_write_array(partition, board_mux);
}
#else
@@ -720,34 +970,49 @@ static void omap_mux_init_package(struct omap_mux *superset,
{
}
-static void omap_mux_init_signals(struct omap_board_mux *board_mux)
+static void omap_mux_init_signals(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
{
}
#endif
-int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
- struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_board_mux *board_mux,
- struct omap_ball *package_balls)
-{
- if (mux_base)
- return -EBUSY;
+static u32 mux_partitions_cnt;
- mux_phys = mux_pbase;
- mux_base = ioremap(mux_pbase, mux_size);
- if (!mux_base) {
- printk(KERN_ERR "mux: Could not ioremap\n");
+int __init omap_mux_init(const char *name, u32 flags,
+ u32 mux_pbase, u32 mux_size,
+ struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_board_mux *board_mux,
+ struct omap_ball *package_balls)
+{
+ struct omap_mux_partition *partition;
+
+ partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
+ if (!partition)
+ return -ENOMEM;
+
+ partition->name = name;
+ partition->flags = flags;
+ partition->size = mux_size;
+ partition->phys = mux_pbase;
+ partition->base = ioremap(mux_pbase, mux_size);
+ if (!partition->base) {
+ pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
+ __func__, partition->phys);
return -ENODEV;
}
- if (cpu_is_omap24xx())
- omap_mux_flags = MUXABLE_GPIO_MODE3;
+ INIT_LIST_HEAD(&partition->muxmodes);
+
+ list_add_tail(&partition->node, &mux_partitions);
+ mux_partitions_cnt++;
+ pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
+ mux_partitions_cnt, partition->name, partition->flags);
omap_mux_init_package(superset, package_subset, package_balls);
- omap_mux_init_list(superset);
- omap_mux_init_signals(board_mux);
+ omap_mux_init_list(partition, superset);
+ omap_mux_init_signals(partition, board_mux);
return 0;
}
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 350c04f27383..a4ab17a737a6 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Nokia
- * Copyright (C) 2009 Texas Instruments
+ * Copyright (C) 2009-2010 Texas Instruments
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -10,6 +10,7 @@
#include "mux2420.h"
#include "mux2430.h"
#include "mux34xx.h"
+#include "mux44xx.h"
#define OMAP_MUX_TERMINATOR 0xffff
@@ -37,6 +38,9 @@
#define OMAP_OFF_PULL_UP (1 << 13)
#define OMAP_WAKEUP_EN (1 << 14)
+/* 44xx specific mux bit defines */
+#define OMAP_WAKEUP_EVENT (1 << 15)
+
/* Active pin states */
#define OMAP_PIN_OUTPUT 0
#define OMAP_PIN_INPUT OMAP_INPUT_EN
@@ -56,8 +60,10 @@
#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
-/* Flags for omap_mux_init */
+/* Flags for omapX_mux_init */
#define OMAP_PACKAGE_MASK 0xffff
+#define OMAP_PACKAGE_CBS 8 /* 547-pin 0.40 0.40 */
+#define OMAP_PACKAGE_CBL 7 /* 547-pin 0.40 0.40 */
#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */
#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */
#define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */
@@ -66,14 +72,61 @@
#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */
-#define OMAP_MUX_NR_MODES 8 /* Available modes */
-#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
+#define OMAP_MUX_NR_MODES 8 /* Available modes */
+#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
+
+/*
+ * omap_mux_init flags definition:
+ *
+ * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
+ * The default value is 16 bits.
+ * OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.
+ * The default is mode4.
+ */
+#define OMAP_MUX_REG_8BIT (1 << 0)
+#define OMAP_MUX_GPIO_IN_MODE3 (1 << 1)
+
+/**
+ * struct omap_board_data - board specific device data
+ * @id: instance id
+ * @flags: additional flags for platform init code
+ * @pads: array of device specific pads
+ * @pads_cnt: ARRAY_SIZE() of pads
+ */
+struct omap_board_data {
+ int id;
+ u32 flags;
+ struct omap_device_pad *pads;
+ int pads_cnt;
+};
+
+/**
+ * struct mux_partition - contain partition related information
+ * @name: name of the current partition
+ * @flags: flags specific to this partition
+ * @phys: physical address
+ * @size: partition size
+ * @base: virtual address after ioremap
+ * @muxmodes: list of nodes that belong to a partition
+ * @node: list node for the partitions linked list
+ */
+struct omap_mux_partition {
+ const char *name;
+ u32 flags;
+ u32 phys;
+ u32 size;
+ void __iomem *base;
+ struct list_head muxmodes;
+ struct list_head node;
+};
/**
* struct omap_mux - data for omap mux register offset and it's value
* @reg_offset: mux register offset from the mux base
* @gpio: GPIO number
* @muxnames: available signal modes for a ball
+ * @balls: available balls on the package
+ * @partition: mux partition
*/
struct omap_mux {
u16 reg_offset;
@@ -106,6 +159,34 @@ struct omap_board_mux {
u16 value;
};
+#define OMAP_DEVICE_PAD_ENABLED BIT(7) /* Not needed for board-*.c */
+#define OMAP_DEVICE_PAD_REMUX BIT(1) /* Dynamically remux a pad,
+ needs enable, idle and off
+ values */
+#define OMAP_DEVICE_PAD_WAKEUP BIT(0) /* Pad is wake-up capable */
+
+/**
+ * struct omap_device_pad - device specific pad configuration
+ * @name: signal name
+ * @flags: pad specific runtime flags
+ * @enable: runtime value for a pad
+ * @idle: idle value for a pad
+ * @off: off value for a pad, defaults to safe mode
+ * @partition: mux partition
+ * @mux: mux register
+ */
+struct omap_device_pad {
+ char *name;
+ u8 flags;
+ u16 enable;
+ u16 idle;
+ u16 off;
+ struct omap_mux_partition *partition;
+ struct omap_mux *mux;
+};
+
+struct omap_hwmod_mux_info;
+
#if defined(CONFIG_OMAP_MUX)
/**
@@ -122,6 +203,23 @@ int omap_mux_init_gpio(int gpio, int val);
*/
int omap_mux_init_signal(const char *muxname, int val);
+/**
+ * omap_hwmod_mux_init - initialize hwmod specific mux data
+ * @bpads: Board specific device signal names
+ * @nr_pads: Number of signal names for the device
+ */
+extern struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
+
+/**
+ * omap_hwmod_mux - omap hwmod specific pin muxing
+ * @hmux: Pads for a hwmod
+ * @state: Desired _HWMOD_STATE
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
+
#else
static inline int omap_mux_init_gpio(int gpio, int val)
@@ -133,6 +231,18 @@ static inline int omap_mux_init_signal(char *muxname, int val)
return 0;
}
+static inline struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+ return NULL;
+}
+
+static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
+{
+}
+
+static struct omap_board_mux *board_mux __initdata __maybe_unused;
+
#endif
/**
@@ -151,28 +261,39 @@ u16 omap_mux_get_gpio(int gpio);
void omap_mux_set_gpio(u16 val, int gpio);
/**
+ * omap_mux_get() - get a mux partition by name
+ * @name: Name of the mux partition
+ *
+ */
+struct omap_mux_partition *omap_mux_get(const char *name);
+
+/**
* omap_mux_read() - read mux register
+ * @partition: Mux partition
* @mux_offset: Offset of the mux register
*
*/
-u16 omap_mux_read(u16 mux_offset);
+u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset);
/**
* omap_mux_write() - write mux register
+ * @partition: Mux partition
* @val: New mux register value
* @mux_offset: Offset of the mux register
*
* This should be only needed for dynamic remuxing of non-gpio signals.
*/
-void omap_mux_write(u16 val, u16 mux_offset);
+void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset);
/**
* omap_mux_write_array() - write an array of mux registers
+ * @partition: Mux partition
* @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR
*
* This should be only needed for dynamic remuxing of non-gpio signals.
*/
-void omap_mux_write_array(struct omap_board_mux *board_mux);
+void omap_mux_write_array(struct omap_mux_partition *p,
+ struct omap_board_mux *board_mux);
/**
* omap2420_mux_init() - initialize mux system with board specific set
@@ -196,10 +317,19 @@ int omap2430_mux_init(struct omap_board_mux *board_mux, int flags);
int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
/**
+ * omap4_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap4_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
* omap_mux_init - private mux init function, do not call
*/
-int omap_mux_init(u32 mux_pbase, u32 mux_size,
- struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_board_mux *board_mux,
- struct omap_ball *package_balls);
+int omap_mux_init(const char *name, u32 flags,
+ u32 mux_pbase, u32 mux_size,
+ struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_board_mux *board_mux,
+ struct omap_ball *package_balls);
+
diff --git a/arch/arm/mach-omap2/mux2420.c b/arch/arm/mach-omap2/mux2420.c
index 414af5434456..cf6de0971c6c 100644
--- a/arch/arm/mach-omap2/mux2420.c
+++ b/arch/arm/mach-omap2/mux2420.c
@@ -678,11 +678,13 @@ int __init omap2420_mux_init(struct omap_board_mux *board_subset, int flags)
case OMAP_PACKAGE_ZAF:
/* REVISIT: Please add data */
default:
- pr_warning("mux: No ball data available for omap2420 package\n");
+ pr_warning("%s: No ball data available for omap2420 package\n",
+ __func__);
}
- return omap_mux_init(OMAP2420_CONTROL_PADCONF_MUX_PBASE,
+ return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
+ OMAP2420_CONTROL_PADCONF_MUX_PBASE,
OMAP2420_CONTROL_PADCONF_MUX_SIZE,
- omap2420_muxmodes, NULL, board_subset,
- package_balls);
+ omap2420_muxmodes, NULL, board_subset,
+ package_balls);
}
diff --git a/arch/arm/mach-omap2/mux2430.c b/arch/arm/mach-omap2/mux2430.c
index 84d2c5a7ecd7..4185f92553db 100644
--- a/arch/arm/mach-omap2/mux2430.c
+++ b/arch/arm/mach-omap2/mux2430.c
@@ -781,11 +781,13 @@ int __init omap2430_mux_init(struct omap_board_mux *board_subset, int flags)
package_balls = omap2430_pop_ball;
break;
default:
- pr_warning("mux: No ball data available for omap2420 package\n");
+ pr_warning("%s: No ball data available for omap2420 package\n",
+ __func__);
}
- return omap_mux_init(OMAP2430_CONTROL_PADCONF_MUX_PBASE,
+ return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
+ OMAP2430_CONTROL_PADCONF_MUX_PBASE,
OMAP2430_CONTROL_PADCONF_MUX_SIZE,
- omap2430_muxmodes, NULL, board_subset,
- package_balls);
+ omap2430_muxmodes, NULL, board_subset,
+ package_balls);
}
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
index 574e54ea3ab7..440c98e9a510 100644
--- a/arch/arm/mach-omap2/mux34xx.c
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -2049,12 +2049,13 @@ int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
package_balls = omap36xx_cbp_ball;
break;
default:
- printk(KERN_ERR "mux: Unknown omap package, mux disabled\n");
+ pr_err("%s Unknown omap package, mux disabled\n", __func__);
return -EINVAL;
}
- return omap_mux_init(OMAP3_CONTROL_PADCONF_MUX_PBASE,
+ return omap_mux_init("core", 0,
+ OMAP3_CONTROL_PADCONF_MUX_PBASE,
OMAP3_CONTROL_PADCONF_MUX_SIZE,
- omap3_muxmodes, package_subset, board_subset,
- package_balls);
+ omap3_muxmodes, package_subset, board_subset,
+ package_balls);
}
diff --git a/arch/arm/mach-omap2/mux44xx.c b/arch/arm/mach-omap2/mux44xx.c
new file mode 100644
index 000000000000..980f11d45c79
--- /dev/null
+++ b/arch/arm/mach-omap2/mux44xx.c
@@ -0,0 +1,1625 @@
+/*
+ * OMAP44xx ES1.0 pin mux definition
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * - Based on mux34xx.c done by Tony Lindgren <tony@atomide.com>
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP4_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap4 ES1.0
+ */
+static struct omap_mux __initdata omap4_core_muxmodes[] = {
+ _OMAP4_MUXENTRY(GPMC_AD0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD1, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD2, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD3, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD4, 0, "gpmc_ad4", "sdmmc2_dat4",
+ "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD5, 0, "gpmc_ad5", "sdmmc2_dat5",
+ "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD6, 0, "gpmc_ad6", "sdmmc2_dat6",
+ "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD7, 0, "gpmc_ad7", "sdmmc2_dat7",
+ "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
+ "gpio_32", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
+ "gpio_33", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
+ "gpio_34", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
+ "gpio_35", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
+ "gpio_36", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
+ "gpio_37", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
+ "gpio_38", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
+ "gpio_39", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
+ "gpio_40", "venc_656_data0", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A17, 41, "gpmc_a17", "kpd_row5", "c2c_datain1",
+ "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A18, 42, "gpmc_a18", "kpd_row6", "c2c_datain2",
+ "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A19, 43, "gpmc_a19", "kpd_row7", "c2c_datain3",
+ "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A20, 44, "gpmc_a20", "kpd_col4", "c2c_datain4",
+ "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A21, 45, "gpmc_a21", "kpd_col5", "c2c_datain5",
+ "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A22, 46, "gpmc_a22", "kpd_col6", "c2c_datain6",
+ "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A23, 47, "gpmc_a23", "kpd_col7", "c2c_datain7",
+ "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", NULL, "c2c_clkout0",
+ "gpio_48", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A25, 49, "gpmc_a25", NULL, "c2c_clkout1",
+ "gpio_49", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS0, 50, "gpmc_ncs0", NULL, NULL, "gpio_50",
+ "sys_ndmareq0", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NCS1, 51, "gpmc_ncs1", NULL, "c2c_dataout6",
+ "gpio_51", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", NULL, "c2c_dataout7",
+ "gpio_52", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS3, 53, "gpmc_ncs3", "gpmc_dir",
+ "c2c_dataout4", "gpio_53", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NWP, 54, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54",
+ "sys_ndmareq1", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
+ "sys_ndmareq2", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
+ "gpio_56", "sys_ndmareq3", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NOE, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NWE, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE0_CLE, 59, "gpmc_nbe0_cle", "dsi2_te0", NULL,
+ "gpio_59", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE1, 60, "gpmc_nbe1", NULL, "c2c_dataout5",
+ "gpio_60", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_WAIT0, 61, "gpmc_wait0", "dsi2_te1", NULL,
+ "gpio_61", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_WAIT1, 62, "gpmc_wait1", NULL, "c2c_dataout2",
+ "gpio_62", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA11, 100, "c2c_data11", "usbc1_icusb_txen",
+ "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA12, 101, "c2c_data12", "dsi1_te0",
+ "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA13, 102, "c2c_data13", "dsi1_te1",
+ "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA14, 103, "c2c_data14", "dsi2_te0",
+ "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA15, 104, "c2c_data15", "dsi2_te1",
+ "c2c_dataout1", "gpio_104", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_HPD, 63, "hdmi_hpd", NULL, NULL, "gpio_63", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_CEC, 64, "hdmi_cec", NULL, NULL, "gpio_64", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SCL, 65, "hdmi_ddc_scl", NULL, NULL,
+ "gpio_65", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SDA, 66, "hdmi_ddc_sda", NULL, NULL,
+ "gpio_66", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX1, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY1, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX2, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY2, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX3, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY3, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX4, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY4, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX1, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY1, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_SHUTTER, 81, "cam_shutter", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_STROBE, 82, "cam_strobe", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_GLOBALRESET, 83, "cam_globalreset", NULL, NULL,
+ "gpio_83", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_CLK, 84, "usbb1_ulpitll_clk",
+ "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk",
+ NULL, "hw_dbg20", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_STP, 85, "usbb1_ulpitll_stp",
+ "hsi1_cadata", "mcbsp4_clkr", "gpio_85",
+ "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DIR, 86, "usbb1_ulpitll_dir",
+ "hsi1_caflag", "mcbsp4_fsr", "gpio_86",
+ "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_NXT, 87, "usbb1_ulpitll_nxt",
+ "hsi1_acready", "mcbsp4_fsx", "gpio_87",
+ "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
+ "hsi1_acwake", "mcbsp4_clkx", "gpio_88",
+ "usbb1_ulpiphy_dat0", "usbb1_mm_rxrcv", "hw_dbg24",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
+ "hsi1_acdata", "mcbsp4_dx", "gpio_89",
+ "usbb1_ulpiphy_dat1", "usbb1_mm_txse0", "hw_dbg25",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
+ "hsi1_acflag", "mcbsp4_dr", "gpio_90",
+ "usbb1_ulpiphy_dat2", "usbb1_mm_txdat", "hw_dbg26",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
+ "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
+ "usbb1_mm_txen", "hw_dbg27", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT4, 92, "usbb1_ulpitll_dat4",
+ "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92",
+ "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT5, 93, "usbb1_ulpitll_dat5",
+ "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93",
+ "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT6, 94, "usbb1_ulpitll_dat6",
+ "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94",
+ "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT7, 95, "usbb1_ulpitll_dat7",
+ "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95",
+ "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_DATA, 96, "usbb1_hsic_data", NULL, NULL,
+ "gpio_96", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_STROBE, 97, "usbb1_hsic_strobe", NULL,
+ NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DP, 98, "usbc1_icusb_dp", NULL, NULL,
+ "gpio_98", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DM, 99, "usbc1_icusb_dm", NULL, NULL,
+ "gpio_99", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CLK, 100, "sdmmc1_clk", NULL, "dpm_emu19",
+ "gpio_100", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CMD, 101, "sdmmc1_cmd", NULL, "uart1_rx",
+ "gpio_101", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT0, 102, "sdmmc1_dat0", NULL, "dpm_emu18",
+ "gpio_102", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT1, 103, "sdmmc1_dat1", NULL, "dpm_emu17",
+ "gpio_103", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT2, 104, "sdmmc1_dat2", NULL, "dpm_emu16",
+ "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT3, 105, "sdmmc1_dat3", NULL, "dpm_emu15",
+ "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT4, 106, "sdmmc1_dat4", NULL, NULL,
+ "gpio_106", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT5, 107, "sdmmc1_dat5", NULL, NULL,
+ "gpio_107", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT6, 108, "sdmmc1_dat6", NULL, NULL,
+ "gpio_108", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT7, 109, "sdmmc1_dat7", NULL, NULL,
+ "gpio_109", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_CLKX, 110, "abe_mcbsp2_clkx", "mcspi2_clk",
+ "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm",
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DR, 111, "abe_mcbsp2_dr", "mcspi2_somi",
+ "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DX, 112, "abe_mcbsp2_dx", "mcspi2_simo",
+ "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_FSX, 113, "abe_mcbsp2_fsx", "mcspi2_cs0",
+ "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_CLKX, 114, "abe_mcbsp1_clkx",
+ "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DR, 115, "abe_mcbsp1_dr",
+ "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DX, 116, "abe_mcbsp1_dx", "sdmmc3_dat2",
+ "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_FSX, 117, "abe_mcbsp1_fsx", "sdmmc3_dat3",
+ "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_UL_DATA, 0, "abe_pdm_ul_data",
+ "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_DL_DATA, 0, "abe_pdm_dl_data",
+ "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_FRAME, 0, "abe_pdm_frame", "abe_mcbsp3_clkx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_LB_CLK, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_CLKS, 118, "abe_clks", NULL, NULL, "gpio_118",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
+ "gpio_119", "usbb2_mm_txse0", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
+ "gpio_120", "usbb2_mm_txdat", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
+ NULL, "gpio_121", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
+ "abe_dmic_clk2", "gpio_122", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_CTS, 123, "uart2_cts", "sdmmc3_clk", NULL,
+ "gpio_123", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RTS, 124, "uart2_rts", "sdmmc3_cmd", NULL,
+ "gpio_124", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RX, 125, "uart2_rx", "sdmmc3_dat0", NULL,
+ "gpio_125", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_TX, 126, "uart2_tx", "sdmmc3_dat1", NULL,
+ "gpio_126", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDQ_SIO, 127, "hdq_sio", "i2c3_sccb", "i2c2_sccb",
+ "gpio_127", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C1_SCL, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C1_SDA, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C2_SCL, 128, "i2c2_scl", "uart1_rx", NULL,
+ "gpio_128", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C2_SDA, 129, "i2c2_sda", "uart1_tx", NULL,
+ "gpio_129", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SCL, 130, "i2c3_scl", NULL, NULL, "gpio_130",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SDA, 131, "i2c3_sda", NULL, NULL, "gpio_131",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SCL, 132, "i2c4_scl", NULL, NULL, "gpio_132",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SDA, 133, "i2c4_sda", NULL, NULL, "gpio_133",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CLK, 134, "mcspi1_clk", NULL, NULL, "gpio_134",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SOMI, 135, "mcspi1_somi", NULL, NULL,
+ "gpio_135", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SIMO, 136, "mcspi1_simo", NULL, NULL,
+ "gpio_136", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS0, 137, "mcspi1_cs0", NULL, NULL, "gpio_137",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS1, 138, "mcspi1_cs1", "uart1_rx", NULL,
+ "gpio_138", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS2, 139, "mcspi1_cs2", "uart1_cts",
+ "slimbus2_clock", "gpio_139", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS3, 140, "mcspi1_cs3", "uart1_rts",
+ "slimbus2_data", "gpio_140", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_CTS_RCTX, 141, "uart3_cts_rctx", "uart1_tx",
+ NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RTS_SD, 142, "uart3_rts_sd", NULL, NULL,
+ "gpio_142", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RX_IRRX, 143, "uart3_rx_irrx",
+ "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_TX_IRTX, 144, "uart3_tx_irtx",
+ "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
+ "usbc1_icusb_dp", "gpio_145", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
+ "usbc1_icusb_dm", "gpio_146", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
+ "usbc1_icusb_rcv", "gpio_147", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
+ "usbc1_icusb_txen", "gpio_148", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
+ "gpio_149", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
+ "gpio_150", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk", NULL,
+ "gpio_151", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd", NULL,
+ "gpio_152", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0", NULL,
+ "gpio_153", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3", NULL,
+ "gpio_154", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", NULL,
+ "gpio_155", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", NULL,
+ "gpio_156", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_CLK, 157, "usbb2_ulpitll_clk",
+ "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157",
+ "hsi2_cawake", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
+ "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
+ "hsi2_cadata", "dispc2_data23", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
+ "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
+ "hsi2_caflag", "dispc2_data22", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
+ "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
+ "hsi2_acready", "dispc2_data21", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
+ "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
+ "hsi2_acwake", "dispc2_data20", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
+ "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
+ "hsi2_acdata", "dispc2_data19", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
+ "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
+ "hsi2_acflag", "dispc2_data18", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
+ "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
+ "hsi2_caready", "dispc2_data15", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
+ "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
+ "mcspi3_somi", "dispc2_data14", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
+ "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
+ "mcspi3_cs0", "dispc2_data13", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
+ "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
+ "mcspi3_simo", "dispc2_data12", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
+ "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
+ "mcspi3_clk", "dispc2_data11", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_DATA, 169, "usbb2_hsic_data", NULL, NULL,
+ "gpio_169", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_STROBE, 170, "usbb2_hsic_strobe", NULL,
+ NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX0, 171, "unipro_tx0", "kpd_col0", NULL,
+ "gpio_171", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY0, 172, "unipro_ty0", "kpd_col1", NULL,
+ "gpio_172", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX1, 173, "unipro_tx1", "kpd_col2", NULL,
+ "gpio_173", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY1, 174, "unipro_ty1", "kpd_col3", NULL,
+ "gpio_174", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX2, 0, "unipro_tx2", "kpd_col4", NULL,
+ "gpio_0", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY2, 1, "unipro_ty2", "kpd_col5", NULL,
+ "gpio_1", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX0, 0, "unipro_rx0", "kpd_row0", NULL,
+ "gpi_175", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY0, 0, "unipro_ry0", "kpd_row1", NULL,
+ "gpi_176", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX1, 0, "unipro_rx1", "kpd_row2", NULL,
+ "gpi_177", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY1, 0, "unipro_ry1", "kpd_row3", NULL,
+ "gpi_178", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX2, 0, "unipro_rx2", "kpd_row4", NULL,
+ "gpi_2", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY2, 0, "unipro_ry2", "kpd_row5", NULL,
+ "gpi_3", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_CE, 0, "usba0_otg_ce", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(USBA0_OTG_DP, 179, "usba0_otg_dp", "uart3_rx_irrx",
+ "uart2_rx", "gpio_179", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_DM, 180, "usba0_otg_dm", "uart3_tx_irtx",
+ "uart2_tx", "gpio_180", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK1_OUT, 181, "fref_clk1_out", NULL, NULL,
+ "gpio_181", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK2_OUT, 182, "fref_clk2_out", NULL, NULL,
+ "gpio_182", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ1, 0, "sys_nirq1", NULL, NULL, NULL, NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ2, 183, "sys_nirq2", NULL, NULL, "gpio_183",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT0, 184, "sys_boot0", NULL, NULL, "gpio_184",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT1, 185, "sys_boot1", NULL, NULL, "gpio_185",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT2, 186, "sys_boot2", NULL, NULL, "gpio_186",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT3, 187, "sys_boot3", NULL, NULL, "gpio_187",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT4, 188, "sys_boot4", NULL, NULL, "gpio_188",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT5, 189, "sys_boot5", NULL, NULL, "gpio_189",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU0, 11, "dpm_emu0", NULL, NULL, "gpio_11", NULL,
+ NULL, "hw_dbg0", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU1, 12, "dpm_emu1", NULL, NULL, "gpio_12", NULL,
+ NULL, "hw_dbg1", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
+ "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
+ "gpio_14", NULL, "dispc2_data10", "hw_dbg3",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
+ "gpio_15", NULL, "dispc2_data9", "hw_dbg4",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
+ "gpio_16", "rfbi_te_vsync0", "dispc2_data16",
+ "hw_dbg5", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
+ "uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
+ "dispc2_data17", "hw_dbg6", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
+ "uart3_rx_irrx", "gpio_18", "rfbi_cs0",
+ "dispc2_hsync", "hw_dbg7", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
+ "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
+ "hw_dbg8", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
+ "uart3_cts_rctx", "gpio_20", "rfbi_we",
+ "dispc2_vsync", "hw_dbg9", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
+ NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
+ NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
+ "hw_dbg11", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
+ NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
+ "hw_dbg12", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
+ NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
+ "hw_dbg13", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
+ "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
+ "hw_dbg14", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
+ NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
+ "hw_dbg15", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
+ "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
+ "hw_dbg16", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
+ "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
+ "hw_dbg17", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
+ "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
+ "hw_dbg18", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
+ "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
+ "hw_dbg19", "reserved"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBL package
+ * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBL)
+struct omap_ball __initdata omap4_core_cbl_ball[] = {
+ _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
+ _OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
+ _OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA11, "d23", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA12, "a24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA13, "b24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA14, "c24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA15, "d24", NULL),
+ _OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
+ _OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
+ _OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
+ _OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
+ _OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
+ _OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
+ _OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
+ _OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
+ _OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
+ _OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
+ _OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
+ _OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
+ _OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
+ _OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
+ _OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
+ _OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
+ _OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
+ _OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
+ _OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
+ _OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
+ _OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
+ _OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX0, "g26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY0, "g25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX1, "h26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY1, "h25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX2, "j27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY2, "h27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX0, "j26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY0, "j25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX1, "k26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY1, "k25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX2, "l27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY2, "k27", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_core_cbl_ball NULL
+#endif
+
+/*
+ * Superset of all mux modes for omap4 ES2.0
+ */
+static struct omap_mux __initdata omap4_es2_core_muxmodes[] = {
+ _OMAP4_MUXENTRY(GPMC_AD0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD1, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD2, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD3, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD4, 0, "gpmc_ad4", "sdmmc2_dat4",
+ "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD5, 0, "gpmc_ad5", "sdmmc2_dat5",
+ "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD6, 0, "gpmc_ad6", "sdmmc2_dat6",
+ "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD7, 0, "gpmc_ad7", "sdmmc2_dat7",
+ "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
+ "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
+ "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
+ "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
+ "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
+ "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
+ "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
+ "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
+ "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
+ "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A17, 41, "gpmc_a17", "kpd_row5", "c2c_datain1",
+ "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A18, 42, "gpmc_a18", "kpd_row6", "c2c_datain2",
+ "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A19, 43, "gpmc_a19", "kpd_row7", "c2c_datain3",
+ "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A20, 44, "gpmc_a20", "kpd_col4", "c2c_datain4",
+ "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A21, 45, "gpmc_a21", "kpd_col5", "c2c_datain5",
+ "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A22, 46, "gpmc_a22", "kpd_col6", "c2c_datain6",
+ "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A23, 47, "gpmc_a23", "kpd_col7", "c2c_datain7",
+ "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", "kpd_col8", "c2c_clkout0",
+ "gpio_48", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A25, 49, "gpmc_a25", NULL, "c2c_clkout1",
+ "gpio_49", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS0, 50, "gpmc_ncs0", NULL, NULL, "gpio_50",
+ "sys_ndmareq0", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NCS1, 51, "gpmc_ncs1", NULL, "c2c_dataout6",
+ "gpio_51", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", "kpd_row8",
+ "c2c_dataout7", "gpio_52", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS3, 53, "gpmc_ncs3", "gpmc_dir",
+ "c2c_dataout4", "gpio_53", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NWP, 54, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54",
+ "sys_ndmareq1", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
+ "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
+ "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NOE, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NWE, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE0_CLE, 59, "gpmc_nbe0_cle", "dsi2_te0", NULL,
+ "gpio_59", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE1, 60, "gpmc_nbe1", NULL, "c2c_dataout5",
+ "gpio_60", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_WAIT0, 61, "gpmc_wait0", "dsi2_te1", NULL,
+ "gpio_61", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_WAIT1, 62, "gpmc_wait1", NULL, "c2c_dataout2",
+ "gpio_62", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_WAIT2, 100, "gpmc_wait2", "usbc1_icusb_txen",
+ "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS4, 101, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0",
+ "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS5, 102, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1",
+ "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS6, 103, "gpmc_ncs6", "dsi2_te0",
+ "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS7, 104, "gpmc_ncs7", "dsi2_te1",
+ "c2c_dataout1", "gpio_104", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_HPD, 63, "hdmi_hpd", NULL, NULL, "gpio_63", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_CEC, 64, "hdmi_cec", NULL, NULL, "gpio_64", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SCL, 65, "hdmi_ddc_scl", NULL, NULL,
+ "gpio_65", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SDA, 66, "hdmi_ddc_sda", NULL, NULL,
+ "gpio_66", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX1, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY1, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX2, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY2, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX3, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY3, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX4, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY4, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX1, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY1, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_SHUTTER, 81, "cam_shutter", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_STROBE, 82, "cam_strobe", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_GLOBALRESET, 83, "cam_globalreset", NULL, NULL,
+ "gpio_83", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_CLK, 84, "usbb1_ulpitll_clk",
+ "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk",
+ NULL, "hw_dbg20", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_STP, 85, "usbb1_ulpitll_stp",
+ "hsi1_cadata", "mcbsp4_clkr", "gpio_85",
+ "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DIR, 86, "usbb1_ulpitll_dir",
+ "hsi1_caflag", "mcbsp4_fsr", "gpio_86",
+ "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_NXT, 87, "usbb1_ulpitll_nxt",
+ "hsi1_acready", "mcbsp4_fsx", "gpio_87",
+ "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
+ "hsi1_acwake", "mcbsp4_clkx", "gpio_88",
+ "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
+ "hsi1_acdata", "mcbsp4_dx", "gpio_89",
+ "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
+ "hsi1_acflag", "mcbsp4_dr", "gpio_90",
+ "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
+ "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
+ "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT4, 92, "usbb1_ulpitll_dat4",
+ "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92",
+ "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT5, 93, "usbb1_ulpitll_dat5",
+ "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93",
+ "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT6, 94, "usbb1_ulpitll_dat6",
+ "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94",
+ "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT7, 95, "usbb1_ulpitll_dat7",
+ "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95",
+ "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_DATA, 96, "usbb1_hsic_data", NULL, NULL,
+ "gpio_96", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_STROBE, 97, "usbb1_hsic_strobe", NULL,
+ NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DP, 98, "usbc1_icusb_dp", NULL, NULL,
+ "gpio_98", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DM, 99, "usbc1_icusb_dm", NULL, NULL,
+ "gpio_99", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CLK, 100, "sdmmc1_clk", NULL, "dpm_emu19",
+ "gpio_100", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CMD, 101, "sdmmc1_cmd", NULL, "uart1_rx",
+ "gpio_101", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT0, 102, "sdmmc1_dat0", NULL, "dpm_emu18",
+ "gpio_102", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT1, 103, "sdmmc1_dat1", NULL, "dpm_emu17",
+ "gpio_103", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT2, 104, "sdmmc1_dat2", NULL, "dpm_emu16",
+ "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT3, 105, "sdmmc1_dat3", NULL, "dpm_emu15",
+ "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT4, 106, "sdmmc1_dat4", NULL, NULL,
+ "gpio_106", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT5, 107, "sdmmc1_dat5", NULL, NULL,
+ "gpio_107", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT6, 108, "sdmmc1_dat6", NULL, NULL,
+ "gpio_108", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT7, 109, "sdmmc1_dat7", NULL, NULL,
+ "gpio_109", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_CLKX, 110, "abe_mcbsp2_clkx", "mcspi2_clk",
+ "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm",
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DR, 111, "abe_mcbsp2_dr", "mcspi2_somi",
+ "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DX, 112, "abe_mcbsp2_dx", "mcspi2_simo",
+ "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_FSX, 113, "abe_mcbsp2_fsx", "mcspi2_cs0",
+ "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_CLKX, 114, "abe_mcbsp1_clkx",
+ "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DR, 115, "abe_mcbsp1_dr",
+ "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DX, 116, "abe_mcbsp1_dx", "sdmmc3_dat2",
+ "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_FSX, 117, "abe_mcbsp1_fsx", "sdmmc3_dat3",
+ "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_UL_DATA, 0, "abe_pdm_ul_data",
+ "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_DL_DATA, 0, "abe_pdm_dl_data",
+ "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_FRAME, 0, "abe_pdm_frame", "abe_mcbsp3_clkx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_LB_CLK, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_CLKS, 118, "abe_clks", NULL, NULL, "gpio_118",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
+ "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
+ "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
+ "abe_mcasp_axr", "gpio_121", NULL,
+ "dmtimer11_pwm_evt", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
+ "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_CTS, 123, "uart2_cts", "sdmmc3_clk", NULL,
+ "gpio_123", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RTS, 124, "uart2_rts", "sdmmc3_cmd", NULL,
+ "gpio_124", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RX, 125, "uart2_rx", "sdmmc3_dat0", NULL,
+ "gpio_125", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_TX, 126, "uart2_tx", "sdmmc3_dat1", NULL,
+ "gpio_126", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDQ_SIO, 127, "hdq_sio", "i2c3_sccb", "i2c2_sccb",
+ "gpio_127", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C1_SCL, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C1_SDA, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C2_SCL, 128, "i2c2_scl", "uart1_rx", NULL,
+ "gpio_128", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C2_SDA, 129, "i2c2_sda", "uart1_tx", NULL,
+ "gpio_129", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SCL, 130, "i2c3_scl", NULL, NULL, "gpio_130",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SDA, 131, "i2c3_sda", NULL, NULL, "gpio_131",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SCL, 132, "i2c4_scl", NULL, NULL, "gpio_132",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SDA, 133, "i2c4_sda", NULL, NULL, "gpio_133",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CLK, 134, "mcspi1_clk", NULL, NULL, "gpio_134",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SOMI, 135, "mcspi1_somi", NULL, NULL,
+ "gpio_135", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SIMO, 136, "mcspi1_simo", NULL, NULL,
+ "gpio_136", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS0, 137, "mcspi1_cs0", NULL, NULL, "gpio_137",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS1, 138, "mcspi1_cs1", "uart1_rx", NULL,
+ "gpio_138", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS2, 139, "mcspi1_cs2", "uart1_cts",
+ "slimbus2_clock", "gpio_139", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS3, 140, "mcspi1_cs3", "uart1_rts",
+ "slimbus2_data", "gpio_140", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_CTS_RCTX, 141, "uart3_cts_rctx", "uart1_tx",
+ NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RTS_SD, 142, "uart3_rts_sd", NULL, NULL,
+ "gpio_142", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RX_IRRX, 143, "uart3_rx_irrx",
+ "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_TX_IRTX, 144, "uart3_tx_irtx",
+ "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
+ "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
+ "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
+ "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
+ "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
+ "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
+ "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk",
+ "kpd_col6", "gpio_151", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd",
+ "kpd_col7", "gpio_152", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0",
+ "kpd_row6", "gpio_153", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3",
+ "kpd_row7", "gpio_154", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", "kpd_row8",
+ "gpio_155", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", "kpd_col8",
+ "gpio_156", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_CLK, 157, "usbb2_ulpitll_clk",
+ "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157",
+ "hsi2_cawake", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
+ "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
+ "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
+ "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
+ "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
+ "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
+ "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
+ "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
+ "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
+ "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
+ "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
+ "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
+ "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
+ "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
+ "hsi2_caready", "dispc2_data15", "rfbi_data15",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
+ "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
+ "mcspi3_somi", "dispc2_data14", "rfbi_data14",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
+ "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
+ "mcspi3_cs0", "dispc2_data13", "rfbi_data13",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
+ "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
+ "mcspi3_simo", "dispc2_data12", "rfbi_data12",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
+ "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
+ "mcspi3_clk", "dispc2_data11", "rfbi_data11",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_DATA, 169, "usbb2_hsic_data", NULL, NULL,
+ "gpio_169", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_STROBE, 170, "usbb2_hsic_strobe", NULL,
+ NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL3, 171, "kpd_col3", "kpd_col0", NULL,
+ "gpio_171", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL4, 172, "kpd_col4", "kpd_col1", NULL,
+ "gpio_172", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL5, 173, "kpd_col5", "kpd_col2", NULL,
+ "gpio_173", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL0, 174, "kpd_col0", "kpd_col3", NULL,
+ "gpio_174", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL1, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL2, 1, "kpd_col2", "kpd_col5", NULL, "gpio_1",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW3, 175, "kpd_row3", "kpd_row0", NULL,
+ "gpio_175", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW4, 176, "kpd_row4", "kpd_row1", NULL,
+ "gpio_176", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW5, 177, "kpd_row5", "kpd_row2", NULL,
+ "gpio_177", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW0, 178, "kpd_row0", "kpd_row3", NULL,
+ "gpio_178", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW1, 2, "kpd_row1", "kpd_row4", NULL, "gpio_2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW2, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_CE, 0, "usba0_otg_ce", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(USBA0_OTG_DP, 0, "usba0_otg_dp", "uart3_rx_irrx",
+ "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_DM, 0, "usba0_otg_dm", "uart3_tx_irtx",
+ "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK1_OUT, 181, "fref_clk1_out", NULL, NULL,
+ "gpio_181", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK2_OUT, 182, "fref_clk2_out", NULL, NULL,
+ "gpio_182", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ1, 0, "sys_nirq1", NULL, NULL, NULL, NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ2, 183, "sys_nirq2", NULL, NULL, "gpio_183",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT0, 184, "sys_boot0", NULL, NULL, "gpio_184",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT1, 185, "sys_boot1", NULL, NULL, "gpio_185",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT2, 186, "sys_boot2", NULL, NULL, "gpio_186",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT3, 187, "sys_boot3", NULL, NULL, "gpio_187",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT4, 188, "sys_boot4", NULL, NULL, "gpio_188",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT5, 189, "sys_boot5", NULL, NULL, "gpio_189",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU0, 11, "dpm_emu0", NULL, NULL, "gpio_11", NULL,
+ NULL, "hw_dbg0", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU1, 12, "dpm_emu1", NULL, NULL, "gpio_12", NULL,
+ NULL, "hw_dbg1", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
+ "gpio_13", NULL, "dispc2_fid", "hw_dbg2",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
+ "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
+ "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
+ "gpio_16", "rfbi_te_vsync0", "dispc2_data16",
+ "hw_dbg5", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
+ "uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
+ "dispc2_data17", "hw_dbg6", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
+ "uart3_rx_irrx", "gpio_18", "rfbi_cs0",
+ "dispc2_hsync", "hw_dbg7", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
+ "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
+ "hw_dbg8", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
+ "uart3_cts_rctx", "gpio_20", "rfbi_we",
+ "dispc2_vsync", "hw_dbg9", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
+ NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
+ NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
+ "hw_dbg11", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
+ NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
+ "hw_dbg12", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
+ NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
+ "hw_dbg13", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
+ "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
+ "hw_dbg14", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
+ NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
+ "hw_dbg15", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
+ "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
+ "hw_dbg16", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
+ "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
+ "hw_dbg17", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
+ "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
+ "hw_dbg18", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
+ "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
+ "hw_dbg19", "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBS package
+ * 547-pin CBL ES2.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBS)
+struct omap_ball __initdata omap4_core_cbs_ball[] = {
+ _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
+ _OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
+ _OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT2, "d23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS4, "a24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS5, "b24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS6, "c24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS7, "d24", NULL),
+ _OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
+ _OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
+ _OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
+ _OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
+ _OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
+ _OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
+ _OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
+ _OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
+ _OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
+ _OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
+ _OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
+ _OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
+ _OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
+ _OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
+ _OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
+ _OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
+ _OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
+ _OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
+ _OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
+ _OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
+ _OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
+ _OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
+ _OMAP4_BALLENTRY(KPD_COL3, "g26", NULL),
+ _OMAP4_BALLENTRY(KPD_COL4, "g25", NULL),
+ _OMAP4_BALLENTRY(KPD_COL5, "h26", NULL),
+ _OMAP4_BALLENTRY(KPD_COL0, "h25", NULL),
+ _OMAP4_BALLENTRY(KPD_COL1, "j27", NULL),
+ _OMAP4_BALLENTRY(KPD_COL2, "h27", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW3, "j26", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW4, "j25", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW5, "k26", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW0, "k25", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW1, "l27", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW2, "k27", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_core_cbs_ball NULL
+#endif
+
+/*
+ * Superset of all mux modes for omap4
+ */
+static struct omap_mux __initdata omap4_wkup_muxmodes[] = {
+ _OMAP4_MUXENTRY(SIM_IO, 0, "sim_io", NULL, NULL, "gpio_wk0", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_CLK, 1, "sim_clk", NULL, NULL, "gpio_wk1", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_RESET, 2, "sim_reset", NULL, NULL, "gpio_wk2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_CD, 3, "sim_cd", NULL, NULL, "gpio_wk3", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_PWRCTRL, 4, "sim_pwrctrl", NULL, NULL, "gpio_wk4",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SR_SCL, 0, "sr_scl", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(SR_SDA, 0, "sr_sda", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_XTAL_IN, 0, "fref_xtal_in", NULL, NULL, NULL,
+ "c2c_wakereqin", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_SLICER_IN, 0, "fref_slicer_in", NULL, NULL,
+ "gpi_wk5", "c2c_wakereqin", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK_IOREQ, 0, "fref_clk_ioreq", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_CLK0_OUT, 6, "fref_clk0_out", "fref_clk1_req",
+ "sys_drm_msecure", "gpio_wk6", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK3_REQ, 30, "fref_clk3_req", "fref_clk1_req",
+ "sys_drm_msecure", "gpio_wk30", "c2c_wakereqin", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK3_OUT, 31, "fref_clk3_out", "fref_clk2_req",
+ "sys_secure_indicator", "gpio_wk31", "c2c_wakereqout",
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK4_REQ, 7, "fref_clk4_req", "fref_clk5_out",
+ NULL, "gpio_wk7", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_CLK4_OUT, 8, "fref_clk4_out", NULL, NULL,
+ "gpio_wk8", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_32K, 0, "sys_32k", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_NRESPWRON, 0, "sys_nrespwron", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_NRESWARM, 0, "sys_nreswarm", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_PWR_REQ, 0, "sys_pwr_req", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_PWRON_RESET_OUT, 29, "sys_pwron_reset_out", NULL,
+ NULL, "gpio_wk29", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_BOOT6, 9, "sys_boot6", "dpm_emu18", NULL,
+ "gpio_wk9", "c2c_wakereqout", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT7, 10, "sys_boot7", "dpm_emu19", NULL,
+ "gpio_wk10", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_NTRST, 0, "jtag_ntrst", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TCK, 0, "jtag_tck", NULL, NULL, NULL, NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_RTCK, 0, "jtag_rtck", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TMS_TMSC, 0, "jtag_tms_tmsc", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_TDI, 0, "jtag_tdi", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TDO, 0, "jtag_tdo", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBL & CBS package - wakeup partition
+ * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBL)
+struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
+ _OMAP4_BALLENTRY(SIM_IO, "h4", NULL),
+ _OMAP4_BALLENTRY(SIM_CLK, "j2", NULL),
+ _OMAP4_BALLENTRY(SIM_RESET, "g2", NULL),
+ _OMAP4_BALLENTRY(SIM_CD, "j1", NULL),
+ _OMAP4_BALLENTRY(SIM_PWRCTRL, "k1", NULL),
+ _OMAP4_BALLENTRY(SR_SCL, "ag9", NULL),
+ _OMAP4_BALLENTRY(SR_SDA, "af9", NULL),
+ _OMAP4_BALLENTRY(FREF_XTAL_IN, "ah6", NULL),
+ _OMAP4_BALLENTRY(FREF_SLICER_IN, "ag8", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK_IOREQ, "ad1", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK0_OUT, "ad2", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK3_REQ, "ad3", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK3_OUT, "ad4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK4_REQ, "ac2", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK4_OUT, "ac3", NULL),
+ _OMAP4_BALLENTRY(SYS_32K, "ag7", NULL),
+ _OMAP4_BALLENTRY(SYS_NRESPWRON, "ae7", NULL),
+ _OMAP4_BALLENTRY(SYS_NRESWARM, "af7", NULL),
+ _OMAP4_BALLENTRY(SYS_PWR_REQ, "ah7", NULL),
+ _OMAP4_BALLENTRY(SYS_PWRON_RESET_OUT, "ag6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT6, "af8", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT7, "ae8", NULL),
+ _OMAP4_BALLENTRY(JTAG_NTRST, "ah2", NULL),
+ _OMAP4_BALLENTRY(JTAG_TCK, "ag1", NULL),
+ _OMAP4_BALLENTRY(JTAG_RTCK, "ae3", NULL),
+ _OMAP4_BALLENTRY(JTAG_TMS_TMSC, "ah1", NULL),
+ _OMAP4_BALLENTRY(JTAG_TDI, "ae1", NULL),
+ _OMAP4_BALLENTRY(JTAG_TDO, "ae2", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_wkup_cbl_cbs_ball NULL
+#endif
+
+int __init omap4_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_ball *package_balls_core;
+ struct omap_ball *package_balls_wkup = omap4_wkup_cbl_cbs_ball;
+ struct omap_mux *core_muxmodes;
+ int ret;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_CBL:
+ pr_debug("%s: OMAP4430 ES1.0 -> OMAP_PACKAGE_CBL\n", __func__);
+ package_balls_core = omap4_core_cbl_ball;
+ core_muxmodes = omap4_core_muxmodes;
+ break;
+ case OMAP_PACKAGE_CBS:
+ pr_debug("%s: OMAP4430 ES2.X -> OMAP_PACKAGE_CBS\n", __func__);
+ package_balls_core = omap4_core_cbs_ball;
+ core_muxmodes = omap4_es2_core_muxmodes;
+ break;
+ default:
+ pr_err("%s: Unknown omap package, mux disabled\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = omap_mux_init("core",
+ OMAP_MUX_GPIO_IN_MODE3,
+ OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE,
+ OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE,
+ core_muxmodes, NULL, board_subset,
+ package_balls_core);
+ if (ret)
+ return ret;
+
+ ret = omap_mux_init("wkup",
+ OMAP_MUX_GPIO_IN_MODE3,
+ OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE,
+ OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE,
+ omap4_wkup_muxmodes, NULL, board_subset,
+ package_balls_wkup);
+
+ return ret;
+}
+
diff --git a/arch/arm/mach-omap2/mux44xx.h b/arch/arm/mach-omap2/mux44xx.h
new file mode 100644
index 000000000000..c635026cd7e9
--- /dev/null
+++ b/arch/arm/mach-omap2/mux44xx.h
@@ -0,0 +1,298 @@
+/*
+ * OMAP44xx MUX registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can 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 __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
+
+#define OMAP4_MUX(M0, mux_value) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/* ctrl_module_pad_core base address */
+#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE 0x4a100000
+
+/* ctrl_module_pad_core registers offset */
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET 0x0040
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD1_OFFSET 0x0042
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD2_OFFSET 0x0044
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD3_OFFSET 0x0046
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD4_OFFSET 0x0048
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD5_OFFSET 0x004a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD6_OFFSET 0x004c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD7_OFFSET 0x004e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD8_OFFSET 0x0050
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD9_OFFSET 0x0052
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD10_OFFSET 0x0054
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD11_OFFSET 0x0056
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD12_OFFSET 0x0058
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD13_OFFSET 0x005a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD14_OFFSET 0x005c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD15_OFFSET 0x005e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A16_OFFSET 0x0060
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A17_OFFSET 0x0062
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A18_OFFSET 0x0064
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A19_OFFSET 0x0066
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A20_OFFSET 0x0068
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A21_OFFSET 0x006a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A22_OFFSET 0x006c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A23_OFFSET 0x006e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A24_OFFSET 0x0070
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A25_OFFSET 0x0072
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS0_OFFSET 0x0074
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS1_OFFSET 0x0076
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS2_OFFSET 0x0078
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS3_OFFSET 0x007a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NWP_OFFSET 0x007c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_CLK_OFFSET 0x007e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NADV_ALE_OFFSET 0x0080
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NOE_OFFSET 0x0082
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NWE_OFFSET 0x0084
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE0_CLE_OFFSET 0x0086
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE1_OFFSET 0x0088
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT0_OFFSET 0x008a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT1_OFFSET 0x008c
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA11_OFFSET 0x008e
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA12_OFFSET 0x0090
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA13_OFFSET 0x0092
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA14_OFFSET 0x0094
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA15_OFFSET 0x0096
+#define OMAP4_CTRL_MODULE_PAD_HDMI_HPD_OFFSET 0x0098
+#define OMAP4_CTRL_MODULE_PAD_HDMI_CEC_OFFSET 0x009a
+#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SCL_OFFSET 0x009c
+#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SDA_OFFSET 0x009e
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX0_OFFSET 0x00a0
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY0_OFFSET 0x00a2
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX1_OFFSET 0x00a4
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY1_OFFSET 0x00a6
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX2_OFFSET 0x00a8
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY2_OFFSET 0x00aa
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX3_OFFSET 0x00ac
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY3_OFFSET 0x00ae
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX4_OFFSET 0x00b0
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY4_OFFSET 0x00b2
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DX0_OFFSET 0x00b4
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DY0_OFFSET 0x00b6
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DX1_OFFSET 0x00b8
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DY1_OFFSET 0x00ba
+#define OMAP4_CTRL_MODULE_PAD_CAM_SHUTTER_OFFSET 0x00bc
+#define OMAP4_CTRL_MODULE_PAD_CAM_STROBE_OFFSET 0x00be
+#define OMAP4_CTRL_MODULE_PAD_CAM_GLOBALRESET_OFFSET 0x00c0
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_CLK_OFFSET 0x00c2
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_STP_OFFSET 0x00c4
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DIR_OFFSET 0x00c6
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_NXT_OFFSET 0x00c8
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT0_OFFSET 0x00ca
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT1_OFFSET 0x00cc
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT2_OFFSET 0x00ce
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT3_OFFSET 0x00d0
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT4_OFFSET 0x00d2
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT5_OFFSET 0x00d4
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT6_OFFSET 0x00d6
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT7_OFFSET 0x00d8
+#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_DATA_OFFSET 0x00da
+#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_STROBE_OFFSET 0x00dc
+#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DP_OFFSET 0x00de
+#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DM_OFFSET 0x00e0
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CLK_OFFSET 0x00e2
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CMD_OFFSET 0x00e4
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT0_OFFSET 0x00e6
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT1_OFFSET 0x00e8
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT2_OFFSET 0x00ea
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT3_OFFSET 0x00ec
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT4_OFFSET 0x00ee
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT5_OFFSET 0x00f0
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT6_OFFSET 0x00f2
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT7_OFFSET 0x00f4
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_CLKX_OFFSET 0x00f6
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DR_OFFSET 0x00f8
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DX_OFFSET 0x00fa
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_FSX_OFFSET 0x00fc
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_CLKX_OFFSET 0x00fe
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DR_OFFSET 0x0100
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DX_OFFSET 0x0102
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_FSX_OFFSET 0x0104
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_UL_DATA_OFFSET 0x0106
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_DL_DATA_OFFSET 0x0108
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_FRAME_OFFSET 0x010a
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_LB_CLK_OFFSET 0x010c
+#define OMAP4_CTRL_MODULE_PAD_ABE_CLKS_OFFSET 0x010e
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_CLK1_OFFSET 0x0110
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN1_OFFSET 0x0112
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN2_OFFSET 0x0114
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN3_OFFSET 0x0116
+#define OMAP4_CTRL_MODULE_PAD_UART2_CTS_OFFSET 0x0118
+#define OMAP4_CTRL_MODULE_PAD_UART2_RTS_OFFSET 0x011a
+#define OMAP4_CTRL_MODULE_PAD_UART2_RX_OFFSET 0x011c
+#define OMAP4_CTRL_MODULE_PAD_UART2_TX_OFFSET 0x011e
+#define OMAP4_CTRL_MODULE_PAD_HDQ_SIO_OFFSET 0x0120
+#define OMAP4_CTRL_MODULE_PAD_I2C1_SCL_OFFSET 0x0122
+#define OMAP4_CTRL_MODULE_PAD_I2C1_SDA_OFFSET 0x0124
+#define OMAP4_CTRL_MODULE_PAD_I2C2_SCL_OFFSET 0x0126
+#define OMAP4_CTRL_MODULE_PAD_I2C2_SDA_OFFSET 0x0128
+#define OMAP4_CTRL_MODULE_PAD_I2C3_SCL_OFFSET 0x012a
+#define OMAP4_CTRL_MODULE_PAD_I2C3_SDA_OFFSET 0x012c
+#define OMAP4_CTRL_MODULE_PAD_I2C4_SCL_OFFSET 0x012e
+#define OMAP4_CTRL_MODULE_PAD_I2C4_SDA_OFFSET 0x0130
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CLK_OFFSET 0x0132
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SOMI_OFFSET 0x0134
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SIMO_OFFSET 0x0136
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS0_OFFSET 0x0138
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS1_OFFSET 0x013a
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS2_OFFSET 0x013c
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS3_OFFSET 0x013e
+#define OMAP4_CTRL_MODULE_PAD_UART3_CTS_RCTX_OFFSET 0x0140
+#define OMAP4_CTRL_MODULE_PAD_UART3_RTS_SD_OFFSET 0x0142
+#define OMAP4_CTRL_MODULE_PAD_UART3_RX_IRRX_OFFSET 0x0144
+#define OMAP4_CTRL_MODULE_PAD_UART3_TX_IRTX_OFFSET 0x0146
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CLK_OFFSET 0x0148
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CMD_OFFSET 0x014a
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT0_OFFSET 0x014c
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT1_OFFSET 0x014e
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT2_OFFSET 0x0150
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT3_OFFSET 0x0152
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CLK_OFFSET 0x0154
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SIMO_OFFSET 0x0156
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SOMI_OFFSET 0x0158
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CS0_OFFSET 0x015a
+#define OMAP4_CTRL_MODULE_PAD_UART4_RX_OFFSET 0x015c
+#define OMAP4_CTRL_MODULE_PAD_UART4_TX_OFFSET 0x015e
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_CLK_OFFSET 0x0160
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_STP_OFFSET 0x0162
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DIR_OFFSET 0x0164
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_NXT_OFFSET 0x0166
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT0_OFFSET 0x0168
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT1_OFFSET 0x016a
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT2_OFFSET 0x016c
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT3_OFFSET 0x016e
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT4_OFFSET 0x0170
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT5_OFFSET 0x0172
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT6_OFFSET 0x0174
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT7_OFFSET 0x0176
+#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_DATA_OFFSET 0x0178
+#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_STROBE_OFFSET 0x017a
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX0_OFFSET 0x017c
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY0_OFFSET 0x017e
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX1_OFFSET 0x0180
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY1_OFFSET 0x0182
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX2_OFFSET 0x0184
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY2_OFFSET 0x0186
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX0_OFFSET 0x0188
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY0_OFFSET 0x018a
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX1_OFFSET 0x018c
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY1_OFFSET 0x018e
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX2_OFFSET 0x0190
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY2_OFFSET 0x0192
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_CE_OFFSET 0x0194
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DP_OFFSET 0x0196
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DM_OFFSET 0x0198
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK1_OUT_OFFSET 0x019a
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK2_OUT_OFFSET 0x019c
+#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ1_OFFSET 0x019e
+#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ2_OFFSET 0x01a0
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT0_OFFSET 0x01a2
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT1_OFFSET 0x01a4
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT2_OFFSET 0x01a6
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT3_OFFSET 0x01a8
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT4_OFFSET 0x01aa
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT5_OFFSET 0x01ac
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU0_OFFSET 0x01ae
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU1_OFFSET 0x01b0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU2_OFFSET 0x01b2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU3_OFFSET 0x01b4
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU4_OFFSET 0x01b6
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU5_OFFSET 0x01b8
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU6_OFFSET 0x01ba
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU7_OFFSET 0x01bc
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU8_OFFSET 0x01be
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU9_OFFSET 0x01c0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU10_OFFSET 0x01c2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU11_OFFSET 0x01c4
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU12_OFFSET 0x01c6
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU13_OFFSET 0x01c8
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU14_OFFSET 0x01ca
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU15_OFFSET 0x01cc
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU16_OFFSET 0x01ce
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU17_OFFSET 0x01d0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU18_OFFSET 0x01d2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET 0x01d4
+
+/* ES2.0 only */
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT2_OFFSET 0x008e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS4_OFFSET 0x0090
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS5_OFFSET 0x0092
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS6_OFFSET 0x0094
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS7_OFFSET 0x0096
+
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL3_OFFSET 0x017c
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL4_OFFSET 0x017e
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL5_OFFSET 0x0180
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL0_OFFSET 0x0182
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL1_OFFSET 0x0184
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL2_OFFSET 0x0186
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW3_OFFSET 0x0188
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW4_OFFSET 0x018a
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW5_OFFSET 0x018c
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW0_OFFSET 0x018e
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW1_OFFSET 0x0190
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW2_OFFSET 0x0192
+
+
+#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE \
+ (OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET \
+ - OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET + 2)
+
+/* ctrl_module_pad_wkup base address */
+#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE 0x4a31e000
+
+/* ctrl_module_pad_wkup registers offset */
+#define OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET 0x0040
+#define OMAP4_CTRL_MODULE_PAD_SIM_CLK_OFFSET 0x0042
+#define OMAP4_CTRL_MODULE_PAD_SIM_RESET_OFFSET 0x0044
+#define OMAP4_CTRL_MODULE_PAD_SIM_CD_OFFSET 0x0046
+#define OMAP4_CTRL_MODULE_PAD_SIM_PWRCTRL_OFFSET 0x0048
+#define OMAP4_CTRL_MODULE_PAD_SR_SCL_OFFSET 0x004a
+#define OMAP4_CTRL_MODULE_PAD_SR_SDA_OFFSET 0x004c
+#define OMAP4_CTRL_MODULE_PAD_FREF_XTAL_IN_OFFSET 0x004e
+#define OMAP4_CTRL_MODULE_PAD_FREF_SLICER_IN_OFFSET 0x0050
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK_IOREQ_OFFSET 0x0052
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK0_OUT_OFFSET 0x0054
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_REQ_OFFSET 0x0056
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_OUT_OFFSET 0x0058
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_REQ_OFFSET 0x005a
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_OUT_OFFSET 0x005c
+#define OMAP4_CTRL_MODULE_PAD_SYS_32K_OFFSET 0x005e
+#define OMAP4_CTRL_MODULE_PAD_SYS_NRESPWRON_OFFSET 0x0060
+#define OMAP4_CTRL_MODULE_PAD_SYS_NRESWARM_OFFSET 0x0062
+#define OMAP4_CTRL_MODULE_PAD_SYS_PWR_REQ_OFFSET 0x0064
+#define OMAP4_CTRL_MODULE_PAD_SYS_PWRON_RESET_OUT_OFFSET 0x0066
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT6_OFFSET 0x0068
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT7_OFFSET 0x006a
+#define OMAP4_CTRL_MODULE_PAD_JTAG_NTRST_OFFSET 0x006c
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TCK_OFFSET 0x006e
+#define OMAP4_CTRL_MODULE_PAD_JTAG_RTCK_OFFSET 0x0070
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TMS_TMSC_OFFSET 0x0072
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TDI_OFFSET 0x0074
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET 0x0076
+
+#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE \
+ (OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET \
+ - OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET + 2)
+
+#endif
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 6cee456ca542..4976b9393e49 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -17,16 +17,13 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/completion.h>
#include <asm/cacheflush.h>
#include <mach/omap4-common.h>
-static DECLARE_COMPLETION(cpu_killed);
-
int platform_cpu_kill(unsigned int cpu)
{
- return wait_for_completion_timeout(&cpu_killed, 5000);
+ return 1;
}
/*
@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- pr_crit("platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
- pr_notice("CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
flush_cache_all();
dsb();
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index f5a1aad1a5c0..3fc5dc7233da 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -33,9 +33,11 @@ static struct iommu_device omap3_devices[] = {
.name = "isp",
.nr_tlb_entries = 8,
.clk_name = "cam_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
},
},
-#if defined(CONFIG_MPU_BRIDGE_IOMMU)
+#if defined(CONFIG_OMAP_IOMMU_IVA2)
{
.base = 0x5d000000,
.irq = 28,
@@ -43,6 +45,8 @@ static struct iommu_device omap3_devices[] = {
.name = "iva2",
.nr_tlb_entries = 32,
.clk_name = "iva2_ck",
+ .da_start = 0x11000000,
+ .da_end = 0xFFFFF000,
},
},
#endif
@@ -64,6 +68,8 @@ static struct iommu_device omap4_devices[] = {
.name = "ducati",
.nr_tlb_entries = 32,
.clk_name = "ducati_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
},
},
#if defined(CONFIG_MPU_TESLA_IOMMU)
@@ -74,6 +80,8 @@ static struct iommu_device omap4_devices[] = {
.name = "tesla",
.nr_tlb_entries = 32,
.clk_name = "tesla_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
},
},
#endif
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 9e9f70e18e3c..b66cfe8bc464 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -21,7 +21,6 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
@@ -29,28 +28,16 @@
/* SCU base address */
static void __iomem *scu_base;
-/*
- * Use SCU config register to count number of cores
- */
-static inline unsigned int get_core_count(void)
-{
- if (scu_base)
- return scu_get_core_count(scu_base);
- return 1;
-}
-
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* If any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_secondary_init(0);
/*
* Synchronise with the boot thread.
@@ -76,7 +63,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all();
smp_wmb();
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
/*
* Now the secondary core is starting up let it run its
@@ -118,25 +105,9 @@ void __init smp_init_cpus(void)
scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
BUG_ON(!scu_base);
- ncores = get_core_count();
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-void __init smp_prepare_cpus(unsigned int max_cpus)
-{
- unsigned int ncores = get_core_count();
- unsigned int cpu = smp_processor_id();
- int i;
+ ncores = scu_get_core_count(scu_base);
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "OMAP4: strange core count of 0? Default to 1\n");
- ncores = 1;
- }
-
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"OMAP4: no. of cores (%d) greater than configured "
@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
ncores, NR_CPUS);
ncores = NR_CPUS;
}
- smp_store_cpu_info(cpu);
- /*
- * are we trying to boot more cores than exist?
- */
- if (max_cpus > ncores)
- max_cpus = ncores;
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
/*
* Initialise the present map, which describes the set of CPUs
@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
- if (max_cpus > 1) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
-
- /*
- * Initialise the SCU and wake up the secondary core using
- * wakeup_secondary().
- */
- scu_enable(scu_base);
- wakeup_secondary();
- }
+ /*
+ * Initialise the SCU and wake up the secondary core using
+ * wakeup_secondary().
+ */
+ scu_enable(scu_base);
+ wakeup_secondary();
}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 2f895553e6a8..19268647ce36 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -26,21 +26,22 @@
void __iomem *l2cache_base;
#endif
-void __iomem *gic_cpu_base_addr;
void __iomem *gic_dist_base_addr;
void __init gic_init_irq(void)
{
+ void __iomem *gic_cpu_base;
+
/* Static mapping, never released */
gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
BUG_ON(!gic_dist_base_addr);
- gic_dist_init(0, gic_dist_base_addr, 29);
/* Static mapping, never released */
- gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
- BUG_ON(!gic_cpu_base_addr);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
+ BUG_ON(!gic_cpu_base);
+
+ gic_init(0, 29, gic_dist_base_addr, gic_cpu_base);
}
#ifdef CONFIG_CACHE_L2X0
@@ -53,6 +54,8 @@ static void omap4_l2x0_disable(void)
static int __init omap_l2_cache_init(void)
{
+ u32 aux_ctrl = 0;
+
/*
* To avoid code running on other OMAPs in
* multi-omap builds
@@ -64,18 +67,32 @@ static int __init omap_l2_cache_init(void)
l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
BUG_ON(!l2cache_base);
- /* Enable PL310 L2 Cache controller */
- omap_smc1(0x102, 0x1);
-
/*
* 16-way associativity, parity disabled
* Way size - 32KB (es1.0)
* Way size - 64KB (es2.0 +)
*/
- if (omap_rev() == OMAP4430_REV_ES1_0)
- l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
- else
- l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff);
+ aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
+ (0x1 << 25) |
+ (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
+ (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
+
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
+ } else {
+ aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+ (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
+ (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
+ }
+ if (omap_rev() != OMAP4430_REV_ES1_0)
+ omap_smc1(0x109, aux_ctrl);
+
+ /* Enable PL310 L2 Cache controller */
+ omap_smc1(0x102, 0x1);
+
+ l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
/*
* Override default outer_cache.disable with a OMAP4
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5a30658444d0..e282e35769fd 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -116,7 +116,6 @@
* - Open Core Protocol Specification 2.2
*
* To do:
- * - pin mux handling
* - handle IO mapping
* - bus throughput & module latency measurement code
*
@@ -135,17 +134,21 @@
#include <linux/err.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <plat/common.h>
#include <plat/cpu.h>
-#include <plat/clockdomain.h>
-#include <plat/powerdomain.h>
+#include "clockdomain.h"
+#include "powerdomain.h"
#include <plat/clock.h>
#include <plat/omap_hwmod.h>
#include <plat/prcm.h>
-#include "cm.h"
-#include "prm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm44xx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "mux.h"
/* Maximum microseconds to wait for OMAP module to softreset */
#define MAX_MODULE_SOFTRESET_WAIT 10000
@@ -156,8 +159,6 @@
/* omap_hwmod_list contains all registered struct omap_hwmods */
static LIST_HEAD(omap_hwmod_list);
-static DEFINE_MUTEX(omap_hwmod_mutex);
-
/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
static struct omap_hwmod *mpu_oh;
@@ -209,10 +210,9 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
/* XXX ensure module interface clock is up */
- if (oh->_sysc_cache != v) {
- oh->_sysc_cache = v;
- omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
- }
+ /* Module might have lost context, always update cache and register */
+ oh->_sysc_cache = v;
+ omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
}
/**
@@ -388,12 +388,13 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
* Allow the hardware module @oh to send wakeups. Returns -EINVAL
* upon error or 0 upon success.
*/
-static int _enable_wakeup(struct omap_hwmod *oh)
+static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
{
- u32 v, wakeup_mask;
+ u32 wakeup_mask;
if (!oh->class->sysc ||
- !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
return -EINVAL;
if (!oh->class->sysc->sysc_fields) {
@@ -403,9 +404,10 @@ static int _enable_wakeup(struct omap_hwmod *oh)
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
- v = oh->_sysc_cache;
- v |= wakeup_mask;
- _write_sysconfig(v, oh);
+ *v |= wakeup_mask;
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
@@ -421,12 +423,13 @@ static int _enable_wakeup(struct omap_hwmod *oh)
* Prevent the hardware module @oh to send wakeups. Returns -EINVAL
* upon error or 0 upon success.
*/
-static int _disable_wakeup(struct omap_hwmod *oh)
+static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
{
- u32 v, wakeup_mask;
+ u32 wakeup_mask;
if (!oh->class->sysc ||
- !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
return -EINVAL;
if (!oh->class->sysc->sysc_fields) {
@@ -436,9 +439,10 @@ static int _disable_wakeup(struct omap_hwmod *oh)
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
- v = oh->_sysc_cache;
- v &= ~wakeup_mask;
- _write_sysconfig(v, oh);
+ *v &= ~wakeup_mask;
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
@@ -675,7 +679,7 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)
* Returns the array index of the OCP slave port that the MPU
* addresses the device on, or -EINVAL upon error or not found.
*/
-static int _find_mpu_port_index(struct omap_hwmod *oh)
+static int __init _find_mpu_port_index(struct omap_hwmod *oh)
{
int i;
int found = 0;
@@ -709,7 +713,7 @@ static int _find_mpu_port_index(struct omap_hwmod *oh)
* Return the virtual address of the base of the register target of
* device @oh, or NULL on error.
*/
-static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
+static void __iomem * __init _find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
{
struct omap_hwmod_ocp_if *os;
struct omap_hwmod_addr_space *mem;
@@ -786,11 +790,11 @@ static void _enable_sysc(struct omap_hwmod *oh)
(sf & SYSC_HAS_CLOCKACTIVITY))
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
- _write_sysconfig(v, oh);
-
/* If slave is in SMARTIDLE, also enable wakeup */
if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
- _enable_wakeup(oh);
+ _enable_wakeup(oh, &v);
+
+ _write_sysconfig(v, oh);
/*
* Set the autoidle bit only after setting the smartidle bit
@@ -836,6 +840,10 @@ static void _idle_sysc(struct omap_hwmod *oh)
_set_master_standbymode(oh, idlemode, &v);
}
+ /* If slave is in SMARTIDLE, also enable wakeup */
+ if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
+ _enable_wakeup(oh, &v);
+
_write_sysconfig(v, oh);
}
@@ -874,7 +882,6 @@ static void _shutdown_sysc(struct omap_hwmod *oh)
* @name: find an omap_hwmod by name
*
* Return a pointer to an omap_hwmod by name, or NULL if not found.
- * Caller must hold omap_hwmod_mutex.
*/
static struct omap_hwmod *_lookup(const char *name)
{
@@ -1089,7 +1096,7 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
}
/**
- * _reset - reset an omap_hwmod
+ * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
* @oh: struct omap_hwmod *
*
* Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
@@ -1098,12 +1105,13 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
* the module did not reset in time, or 0 upon success.
*
* In OMAP3 a specific SYSSTATUS register is used to get the reset status.
- * Starting in OMAP4, some IPs does not have SYSSTATUS register and instead
+ * Starting in OMAP4, some IPs do not have SYSSTATUS registers and instead
* use the SYSCONFIG softreset bit to provide the status.
*
- * Note that some IP like McBSP does have a reset control but no reset status.
+ * Note that some IP like McBSP do have reset control but don't have
+ * reset status.
*/
-static int _reset(struct omap_hwmod *oh)
+static int _ocp_softreset(struct omap_hwmod *oh)
{
u32 v;
int c = 0;
@@ -1124,7 +1132,7 @@ static int _reset(struct omap_hwmod *oh)
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_enable_optional_clocks(oh);
- pr_debug("omap_hwmod: %s: resetting\n", oh->name);
+ pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name);
v = oh->_sysc_cache;
ret = _set_softreset(oh, &v);
@@ -1164,17 +1172,41 @@ dis_opt_clks:
}
/**
- * _omap_hwmod_enable - enable an omap_hwmod
+ * _reset - reset an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Resets an omap_hwmod @oh. The default software reset mechanism for
+ * most OMAP IP blocks is triggered via the OCP_SYSCONFIG.SOFTRESET
+ * bit. However, some hwmods cannot be reset via this method: some
+ * are not targets and therefore have no OCP header registers to
+ * access; others (like the IVA) have idiosyncratic reset sequences.
+ * So for these relatively rare cases, custom reset code can be
+ * supplied in the struct omap_hwmod_class .reset function pointer.
+ * Passes along the return value from either _reset() or the custom
+ * reset function - these must return -EINVAL if the hwmod cannot be
+ * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
+ * the module did not reset in time, or 0 upon success.
+ */
+static int _reset(struct omap_hwmod *oh)
+{
+ int ret;
+
+ pr_debug("omap_hwmod: %s: resetting\n", oh->name);
+
+ ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh);
+
+ return ret;
+}
+
+/**
+ * _enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
*
* Enables an omap_hwmod @oh such that the MPU can access the hwmod's
- * register target. (This function has a full name --
- * _omap_hwmod_enable() rather than simply _enable() -- because it is
- * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
- * the hwmod is in the wrong state or passes along the return value of
- * _wait_target_ready().
+ * register target. Returns -EINVAL if the hwmod is in the wrong
+ * state or passes along the return value of _wait_target_ready().
*/
-int _omap_hwmod_enable(struct omap_hwmod *oh)
+static int _enable(struct omap_hwmod *oh)
{
int r;
@@ -1197,7 +1229,9 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
_deassert_hardreset(oh, oh->rst_lines[0].name);
- /* XXX mux balls */
+ /* Mux pins for device runtime if populated */
+ if (oh->mux)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
_add_initiator_dep(oh, mpu_oh);
_enable_clocks(oh);
@@ -1213,6 +1247,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
_enable_sysc(oh);
}
} else {
+ _disable_clocks(oh);
pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
oh->name, r);
}
@@ -1221,16 +1256,14 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
}
/**
- * _omap_hwmod_idle - idle an omap_hwmod
+ * _idle - idle an omap_hwmod
* @oh: struct omap_hwmod *
*
* Idles an omap_hwmod @oh. This should be called once the hwmod has
- * no further work. (This function has a full name --
- * _omap_hwmod_idle() rather than simply _idle() -- because it is
- * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
- * the hwmod is in the wrong state or returns 0.
+ * no further work. Returns -EINVAL if the hwmod is in the wrong
+ * state or returns 0.
*/
-int _omap_hwmod_idle(struct omap_hwmod *oh)
+static int _idle(struct omap_hwmod *oh)
{
if (oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: idle state can only be entered from "
@@ -1245,6 +1278,10 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
_del_initiator_dep(oh, mpu_oh);
_disable_clocks(oh);
+ /* Mux pins for device idle if populated */
+ if (oh->mux)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+
oh->_state = _HWMOD_STATE_IDLE;
return 0;
@@ -1261,6 +1298,9 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
*/
static int _shutdown(struct omap_hwmod *oh)
{
+ int ret;
+ u8 prev_state;
+
if (oh->_state != _HWMOD_STATE_IDLE &&
oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: disabled state can only be entered "
@@ -1270,6 +1310,18 @@ static int _shutdown(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: disabling\n", oh->name);
+ if (oh->class->pre_shutdown) {
+ prev_state = oh->_state;
+ if (oh->_state == _HWMOD_STATE_IDLE)
+ _enable(oh);
+ ret = oh->class->pre_shutdown(oh);
+ if (ret) {
+ if (prev_state == _HWMOD_STATE_IDLE)
+ _idle(oh);
+ return ret;
+ }
+ }
+
if (oh->class->sysc)
_shutdown_sysc(oh);
@@ -1288,7 +1340,9 @@ static int _shutdown(struct omap_hwmod *oh)
}
/* XXX Should this code also force-disable the optional clocks? */
- /* XXX mux any associated balls to safe mode */
+ /* Mux pins to safe mode or use populated off mode values */
+ if (oh->mux)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
oh->_state = _HWMOD_STATE_DISABLED;
@@ -1298,23 +1352,15 @@ static int _shutdown(struct omap_hwmod *oh)
/**
* _setup - do initial configuration of omap_hwmod
* @oh: struct omap_hwmod *
- * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
*
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
- * a system that will not call omap_hwmod_enable() to enable devices
- * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
- * is in the wrong state or returns 0.
+ * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the
+ * wrong state or returns 0.
*/
static int _setup(struct omap_hwmod *oh, void *data)
{
int i, r;
- u8 skip_setup_idle;
-
- if (!oh || !data)
- return -EINVAL;
-
- skip_setup_idle = *(u8 *)data;
+ u8 postsetup_state;
/* Set iclk autoidle mode */
if (oh->slaves_cnt > 0) {
@@ -1334,7 +1380,6 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
}
- mutex_init(&oh->_mutex);
oh->_state = _HWMOD_STATE_INITIALIZED;
/*
@@ -1347,7 +1392,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
return 0;
- r = _omap_hwmod_enable(oh);
+ r = _enable(oh);
if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
oh->name, oh->_state);
@@ -1359,7 +1404,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
/*
* OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
- * The _omap_hwmod_enable() function should be split to
+ * The _enable() function should be split to
* avoid the rewrite of the OCP_SYSCONFIG register.
*/
if (oh->class->sysc) {
@@ -1368,12 +1413,77 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
}
- if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
- _omap_hwmod_idle(oh);
+ postsetup_state = oh->_postsetup_state;
+ if (postsetup_state == _HWMOD_STATE_UNKNOWN)
+ postsetup_state = _HWMOD_STATE_ENABLED;
+
+ /*
+ * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
+ * it should be set by the core code as a runtime flag during startup
+ */
+ if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
+ (postsetup_state == _HWMOD_STATE_IDLE))
+ postsetup_state = _HWMOD_STATE_ENABLED;
+
+ if (postsetup_state == _HWMOD_STATE_IDLE)
+ _idle(oh);
+ else if (postsetup_state == _HWMOD_STATE_DISABLED)
+ _shutdown(oh);
+ else if (postsetup_state != _HWMOD_STATE_ENABLED)
+ WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
+ oh->name, postsetup_state);
return 0;
}
+/**
+ * _register - register a struct omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod
+ * already has been registered by the same name; -EINVAL if the
+ * omap_hwmod is in the wrong state, if @oh is NULL, if the
+ * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
+ * name, or if the omap_hwmod's class is missing a name; or 0 upon
+ * success.
+ *
+ * XXX The data should be copied into bootmem, so the original data
+ * should be marked __initdata and freed after init. This would allow
+ * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note
+ * that the copy process would be relatively complex due to the large number
+ * of substructures.
+ */
+static int __init _register(struct omap_hwmod *oh)
+{
+ int ret, ms_id;
+
+ if (!oh || !oh->name || !oh->class || !oh->class->name ||
+ (oh->_state != _HWMOD_STATE_UNKNOWN))
+ return -EINVAL;
+
+ pr_debug("omap_hwmod: %s: registering\n", oh->name);
+
+ if (_lookup(oh->name))
+ return -EEXIST;
+
+ ms_id = _find_mpu_port_index(oh);
+ if (!IS_ERR_VALUE(ms_id)) {
+ oh->_mpu_port_index = ms_id;
+ oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
+ } else {
+ oh->_int_flags |= _HWMOD_NO_MPU_PORT;
+ }
+
+ list_add_tail(&oh->node, &omap_hwmod_list);
+
+ spin_lock_init(&oh->_lock);
+
+ oh->_state = _HWMOD_STATE_REGISTERED;
+
+ ret = 0;
+
+ return ret;
+}
/* Public functions */
@@ -1427,59 +1537,6 @@ int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
}
/**
- * omap_hwmod_register - register a struct omap_hwmod
- * @oh: struct omap_hwmod *
- *
- * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod
- * already has been registered by the same name; -EINVAL if the
- * omap_hwmod is in the wrong state, if @oh is NULL, if the
- * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
- * name, or if the omap_hwmod's class is missing a name; or 0 upon
- * success.
- *
- * XXX The data should be copied into bootmem, so the original data
- * should be marked __initdata and freed after init. This would allow
- * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note
- * that the copy process would be relatively complex due to the large number
- * of substructures.
- */
-int omap_hwmod_register(struct omap_hwmod *oh)
-{
- int ret, ms_id;
-
- if (!oh || !oh->name || !oh->class || !oh->class->name ||
- (oh->_state != _HWMOD_STATE_UNKNOWN))
- return -EINVAL;
-
- mutex_lock(&omap_hwmod_mutex);
-
- pr_debug("omap_hwmod: %s: registering\n", oh->name);
-
- if (_lookup(oh->name)) {
- ret = -EEXIST;
- goto ohr_unlock;
- }
-
- ms_id = _find_mpu_port_index(oh);
- if (!IS_ERR_VALUE(ms_id)) {
- oh->_mpu_port_index = ms_id;
- oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
- } else {
- oh->_int_flags |= _HWMOD_NO_MPU_PORT;
- }
-
- list_add_tail(&oh->node, &omap_hwmod_list);
-
- oh->_state = _HWMOD_STATE_REGISTERED;
-
- ret = 0;
-
-ohr_unlock:
- mutex_unlock(&omap_hwmod_mutex);
- return ret;
-}
-
-/**
* omap_hwmod_lookup - look up a registered omap_hwmod by name
* @name: name of the omap_hwmod to look up
*
@@ -1493,9 +1550,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
if (!name)
return NULL;
- mutex_lock(&omap_hwmod_mutex);
oh = _lookup(name);
- mutex_unlock(&omap_hwmod_mutex);
return oh;
}
@@ -1521,13 +1576,11 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
if (!fn)
return -EINVAL;
- mutex_lock(&omap_hwmod_mutex);
list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
ret = (*fn)(temp_oh, data);
if (ret)
break;
}
- mutex_unlock(&omap_hwmod_mutex);
return ret;
}
@@ -1542,7 +1595,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
* listed in @ohs that are valid for this chip. Returns -EINVAL if
* omap_hwmod_init() has already been called or 0 otherwise.
*/
-int omap_hwmod_init(struct omap_hwmod **ohs)
+int __init omap_hwmod_init(struct omap_hwmod **ohs)
{
struct omap_hwmod *oh;
int r;
@@ -1558,8 +1611,8 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
oh = *ohs;
while (oh) {
if (omap_chip_is(oh->omap_chip)) {
- r = omap_hwmod_register(oh);
- WARN(r, "omap_hwmod: %s: omap_hwmod_register returned "
+ r = _register(oh);
+ WARN(r, "omap_hwmod: %s: _register returned "
"%d\n", oh->name, r);
}
oh = *++ohs;
@@ -1570,13 +1623,12 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
/**
* omap_hwmod_late_init - do some post-clock framework initialization
- * @skip_setup_idle: if 1, do not idle hwmods in _setup()
*
* Must be called after omap2_clk_init(). Resolves the struct clk names
* to struct clk pointers for each registered omap_hwmod. Also calls
* _setup() on each hwmod. Returns 0.
*/
-int omap_hwmod_late_init(u8 skip_setup_idle)
+int omap_hwmod_late_init(void)
{
int r;
@@ -1588,36 +1640,7 @@ int omap_hwmod_late_init(u8 skip_setup_idle)
WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
MPU_INITIATOR_NAME);
- if (skip_setup_idle)
- pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
-
- omap_hwmod_for_each(_setup, &skip_setup_idle);
-
- return 0;
-}
-
-/**
- * omap_hwmod_unregister - unregister an omap_hwmod
- * @oh: struct omap_hwmod *
- *
- * Unregisters a previously-registered omap_hwmod @oh. There's probably
- * no use case for this, so it is likely to be removed in a later version.
- *
- * XXX Free all of the bootmem-allocated structures here when that is
- * implemented. Make it clear that core code is the only code that is
- * expected to unregister modules.
- */
-int omap_hwmod_unregister(struct omap_hwmod *oh)
-{
- if (!oh)
- return -EINVAL;
-
- pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
-
- mutex_lock(&omap_hwmod_mutex);
- iounmap(oh->_mpu_rt_va);
- list_del(&oh->node);
- mutex_unlock(&omap_hwmod_mutex);
+ omap_hwmod_for_each(_setup, NULL);
return 0;
}
@@ -1632,18 +1655,18 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
int omap_hwmod_enable(struct omap_hwmod *oh)
{
int r;
+ unsigned long flags;
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
- r = _omap_hwmod_enable(oh);
- mutex_unlock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
+ r = _enable(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return r;
}
-
/**
* omap_hwmod_idle - idle an omap_hwmod
* @oh: struct omap_hwmod *
@@ -1653,12 +1676,14 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
*/
int omap_hwmod_idle(struct omap_hwmod *oh)
{
+ unsigned long flags;
+
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
- _omap_hwmod_idle(oh);
- mutex_unlock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
+ _idle(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -1673,12 +1698,14 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
*/
int omap_hwmod_shutdown(struct omap_hwmod *oh)
{
+ unsigned long flags;
+
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
_shutdown(oh);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -1691,9 +1718,11 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
*/
int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
{
- mutex_lock(&oh->_mutex);
+ unsigned long flags;
+
+ spin_lock_irqsave(&oh->_lock, flags);
_enable_clocks(oh);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -1706,9 +1735,11 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
*/
int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
{
- mutex_lock(&oh->_mutex);
+ unsigned long flags;
+
+ spin_lock_irqsave(&oh->_lock, flags);
_disable_clocks(oh);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -1752,13 +1783,14 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
int omap_hwmod_reset(struct omap_hwmod *oh)
{
int r;
+ unsigned long flags;
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
r = _reset(oh);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return r;
}
@@ -1955,13 +1987,18 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
*/
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
{
+ unsigned long flags;
+ u32 v;
+
if (!oh->class->sysc ||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;
- mutex_lock(&oh->_mutex);
- _enable_wakeup(oh);
- mutex_unlock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
+ v = oh->_sysc_cache;
+ _enable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -1980,13 +2017,18 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
*/
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
{
+ unsigned long flags;
+ u32 v;
+
if (!oh->class->sysc ||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;
- mutex_lock(&oh->_mutex);
- _disable_wakeup(oh);
- mutex_unlock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
+ v = oh->_sysc_cache;
+ _disable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
@@ -2006,13 +2048,14 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
{
int ret;
+ unsigned long flags;
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
ret = _assert_hardreset(oh, name);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return ret;
}
@@ -2032,13 +2075,14 @@ int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
{
int ret;
+ unsigned long flags;
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
ret = _deassert_hardreset(oh, name);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return ret;
}
@@ -2057,13 +2101,14 @@ int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
{
int ret;
+ unsigned long flags;
if (!oh)
return -EINVAL;
- mutex_lock(&oh->_mutex);
+ spin_lock_irqsave(&oh->_lock, flags);
ret = _read_hardreset(oh, name);
- mutex_unlock(&oh->_mutex);
+ spin_unlock_irqrestore(&oh->_lock, flags);
return ret;
}
@@ -2075,9 +2120,8 @@ int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
* @fn: callback function pointer to call for each hwmod in class @classname
* @user: arbitrary context data to pass to the callback function
*
- * For each omap_hwmod of class @classname, call @fn. Takes
- * omap_hwmod_mutex to prevent the hwmod list from changing during the
- * iteration. If the callback function returns something other than
+ * For each omap_hwmod of class @classname, call @fn.
+ * If the callback function returns something other than
* zero, the iterator is terminated, and the callback function's return
* value is passed back to the caller. Returns 0 upon success, -EINVAL
* if @classname or @fn are NULL, or passes back the error code from @fn.
@@ -2096,8 +2140,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
__func__, classname);
- mutex_lock(&omap_hwmod_mutex);
-
list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
if (!strcmp(temp_oh->class->name, classname)) {
pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
@@ -2108,8 +2150,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
}
}
- mutex_unlock(&omap_hwmod_mutex);
-
if (ret)
pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
__func__, ret);
@@ -2117,3 +2157,64 @@ int omap_hwmod_for_each_by_class(const char *classname,
return ret;
}
+/**
+ * omap_hwmod_set_postsetup_state - set the post-_setup() state for this hwmod
+ * @oh: struct omap_hwmod *
+ * @state: state that _setup() should leave the hwmod in
+ *
+ * Sets the hwmod state that @oh will enter at the end of _setup() (called by
+ * omap_hwmod_late_init()). Only valid to call between calls to
+ * omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or
+ * -EINVAL if there is a problem with the arguments or if the hwmod is
+ * in the wrong state.
+ */
+int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
+{
+ int ret;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (state != _HWMOD_STATE_DISABLED &&
+ state != _HWMOD_STATE_ENABLED &&
+ state != _HWMOD_STATE_IDLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+
+ if (oh->_state != _HWMOD_STATE_REGISTERED) {
+ ret = -EINVAL;
+ goto ohsps_unlock;
+ }
+
+ oh->_postsetup_state = state;
+ ret = 0;
+
+ohsps_unlock:
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_get_context_loss_count - get lost context count
+ * @oh: struct omap_hwmod *
+ *
+ * Query the powerdomain of of @oh to get the context loss
+ * count for this device.
+ *
+ * Returns the context loss count of the powerdomain assocated with @oh
+ * upon success, or zero if no powerdomain exists for @oh.
+ */
+u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
+{
+ struct powerdomain *pwrdm;
+ int ret = 0;
+
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ if (pwrdm)
+ ret = pwrdm_get_context_loss_count(pwrdm);
+
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index adf6e3632a2b..b85c630b64d6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -16,11 +16,14 @@
#include <plat/cpu.h>
#include <plat/dma.h>
#include <plat/serial.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
#include "omap_hwmod_common_data.h"
-#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+#include "wd_timer.h"
/*
* OMAP2420 hardware module integration data
@@ -36,6 +39,11 @@ static struct omap_hwmod omap2420_iva_hwmod;
static struct omap_hwmod omap2420_l3_main_hwmod;
static struct omap_hwmod omap2420_l4_core_hwmod;
static struct omap_hwmod omap2420_wd_timer2_hwmod;
+static struct omap_hwmod omap2420_gpio1_hwmod;
+static struct omap_hwmod omap2420_gpio2_hwmod;
+static struct omap_hwmod omap2420_gpio3_hwmod;
+static struct omap_hwmod omap2420_gpio4_hwmod;
+static struct omap_hwmod omap2420_dma_system_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -77,6 +85,8 @@ static struct omap_hwmod omap2420_l4_wkup_hwmod;
static struct omap_hwmod omap2420_uart1_hwmod;
static struct omap_hwmod omap2420_uart2_hwmod;
static struct omap_hwmod omap2420_uart3_hwmod;
+static struct omap_hwmod omap2420_i2c1_hwmod;
+static struct omap_hwmod omap2420_i2c2_hwmod;
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
@@ -139,6 +149,45 @@ static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap2420_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap2420_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_i2c1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap2420_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap2420_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_i2c2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
&omap2420_l3_main__l4_core,
@@ -150,6 +199,8 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
&omap2_l4_core__uart1,
&omap2_l4_core__uart2,
&omap2_l4_core__uart3,
+ &omap2420_l4_core__i2c1,
+ &omap2420_l4_core__i2c2
};
/* L4 CORE */
@@ -262,8 +313,9 @@ static struct omap_hwmod_class_sysconfig omap2420_wd_timer_sysc = {
};
static struct omap_hwmod_class omap2420_wd_timer_hwmod_class = {
- .name = "wd_timer",
- .sysc = &omap2420_wd_timer_sysc,
+ .name = "wd_timer",
+ .sysc = &omap2420_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
};
/* wd_timer2 */
@@ -418,6 +470,400 @@ static struct omap_hwmod omap2420_uart3_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SOFTRESET,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr;
+
+/* I2C1 */
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_i2c1_slaves[] = {
+ &omap2420_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap2420_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2420_EN_I2C1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2420_ST_I2C1_SHIFT,
+ },
+ },
+ .slaves = omap2420_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* I2C2 */
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_i2c2_slaves[] = {
+ &omap2420_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap2420_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2420_EN_I2C2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2420_ST_I2C2_SHIFT,
+ },
+ },
+ .slaves = omap2420_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap2420_gpio1_addr_space[] = {
+ {
+ .pa_start = 0x48018000,
+ .pa_end = 0x480181ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_addr_space omap2420_gpio2_addr_space[] = {
+ {
+ .pa_start = 0x4801a000,
+ .pa_end = 0x4801a1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_addr_space omap2420_gpio3_addr_space[] = {
+ {
+ .pa_start = 0x4801c000,
+ .pa_end = 0x4801c1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_addr_space omap2420_gpio4_addr_space[] = {
+ {
+ .pa_start = 0x4801e000,
+ .pa_end = 0x4801e1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap242x_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+static struct omap_hwmod_class omap242x_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap242x_gpio_sysc,
+ .rev = 0,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap242x_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = {
+ &omap2420_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2420_gpio1_hwmod = {
+ .name = "gpio1",
+ .mpu_irqs = omap242x_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio1_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap242x_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = {
+ &omap2420_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2420_gpio2_hwmod = {
+ .name = "gpio2",
+ .mpu_irqs = omap242x_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio2_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap242x_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = {
+ &omap2420_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2420_gpio3_hwmod = {
+ .name = "gpio3",
+ .mpu_irqs = omap242x_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio3_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap242x_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = {
+ &omap2420_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2420_gpio4_hwmod = {
+ .name = "gpio4",
+ .mpu_irqs = omap242x_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio4_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* system dma */
+static struct omap_hwmod_class_sysconfig omap2420_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap2420_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x4a0560ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = {
+ .master = &omap2420_dma_system_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_masters[] = {
+ &omap2420_dma_system__l3,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2420_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_slaves[] = {
+ &omap2420_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2420_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2420_dma_hwmod_class,
+ .mpu_irqs = omap2420_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dma_system_irqs),
+ .main_clk = "core_l3_ck",
+ .slaves = omap2420_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dma_system_slaves),
+ .masters = omap2420_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&omap2420_l3_main_hwmod,
&omap2420_l4_core_hwmod,
@@ -428,6 +874,17 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&omap2420_uart1_hwmod,
&omap2420_uart2_hwmod,
&omap2420_uart3_hwmod,
+ &omap2420_i2c1_hwmod,
+ &omap2420_i2c2_hwmod,
+
+ /* gpio class */
+ &omap2420_gpio1_hwmod,
+ &omap2420_gpio2_hwmod,
+ &omap2420_gpio3_hwmod,
+ &omap2420_gpio4_hwmod,
+
+ /* dma_system class*/
+ &omap2420_dma_system_hwmod,
NULL,
};
@@ -435,5 +892,3 @@ int __init omap2420_hwmod_init(void)
{
return omap_hwmod_init(omap2420_hwmods);
}
-
-
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 12d939e456cf..8ecfbcde13ba 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -16,11 +16,14 @@
#include <plat/cpu.h>
#include <plat/dma.h>
#include <plat/serial.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
#include "omap_hwmod_common_data.h"
#include "prm-regbits-24xx.h"
#include "cm-regbits-24xx.h"
+#include "wd_timer.h"
/*
* OMAP2430 hardware module integration data
@@ -36,6 +39,12 @@ static struct omap_hwmod omap2430_iva_hwmod;
static struct omap_hwmod omap2430_l3_main_hwmod;
static struct omap_hwmod omap2430_l4_core_hwmod;
static struct omap_hwmod omap2430_wd_timer2_hwmod;
+static struct omap_hwmod omap2430_gpio1_hwmod;
+static struct omap_hwmod omap2430_gpio2_hwmod;
+static struct omap_hwmod omap2430_gpio3_hwmod;
+static struct omap_hwmod omap2430_gpio4_hwmod;
+static struct omap_hwmod omap2430_gpio5_hwmod;
+static struct omap_hwmod omap2430_dma_system_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
@@ -77,6 +86,47 @@ static struct omap_hwmod omap2430_l4_wkup_hwmod;
static struct omap_hwmod omap2430_uart1_hwmod;
static struct omap_hwmod omap2430_uart2_hwmod;
static struct omap_hwmod omap2430_uart3_hwmod;
+static struct omap_hwmod omap2430_i2c1_hwmod;
+static struct omap_hwmod omap2430_i2c2_hwmod;
+
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap2430_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap2430_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_i2c1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap2430_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap2430_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_i2c2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -262,8 +312,9 @@ static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = {
};
static struct omap_hwmod_class omap2430_wd_timer_hwmod_class = {
- .name = "wd_timer",
- .sysc = &omap2430_wd_timer_sysc,
+ .name = "wd_timer",
+ .sysc = &omap2430_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
};
/* wd_timer2 */
@@ -418,6 +469,456 @@ static struct omap_hwmod omap2430_uart3_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+/* I2C1 */
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = {
+ &omap2430_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap2430_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2chs1_fck",
+ .prcm = {
+ .omap2 = {
+ /*
+ * NOTE: The CM_FCLKEN* and CM_ICLKEN* for
+ * I2CHS IP's do not follow the usual pattern.
+ * prcm_reg_id alone cannot be used to program
+ * the iclk and fclk. Needs to be handled using
+ * additonal flags when clk handling is moved
+ * to hwmod framework.
+ */
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_I2CHS1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT,
+ },
+ },
+ .slaves = omap2430_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* I2C2 */
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = {
+ &omap2430_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap2430_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2chs2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_I2CHS2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT,
+ },
+ },
+ .slaves = omap2430_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = {
+ {
+ .pa_start = 0x4900C000,
+ .pa_end = 0x4900C1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = {
+ {
+ .pa_start = 0x4900E000,
+ .pa_end = 0x4900E1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = {
+ {
+ .pa_start = 0x49010000,
+ .pa_end = 0x490101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = {
+ {
+ .pa_start = 0x49012000,
+ .pa_end = 0x490121ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> gpio5 */
+static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = {
+ {
+ .pa_start = 0x480B6000,
+ .pa_end = 0x480B61ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_gpio5_hwmod,
+ .clk = "gpio5_ick",
+ .addr = omap2430_gpio5_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio5_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+static struct omap_hwmod_class omap243x_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap243x_gpio_sysc,
+ .rev = 0,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = {
+ &omap2430_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2430_gpio1_hwmod = {
+ .name = "gpio1",
+ .mpu_irqs = omap243x_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio1_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = {
+ &omap2430_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2430_gpio2_hwmod = {
+ .name = "gpio2",
+ .mpu_irqs = omap243x_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio2_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = {
+ &omap2430_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2430_gpio3_hwmod = {
+ .name = "gpio3",
+ .mpu_irqs = omap243x_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio3_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = {
+ &omap2430_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2430_gpio4_hwmod = {
+ .name = "gpio4",
+ .mpu_irqs = omap243x_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio4_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio5 */
+static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = {
+ { .irq = 33 }, /* INT_24XX_GPIO_BANK5 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = {
+ &omap2430_l4_core__gpio5,
+};
+
+static struct omap_hwmod omap2430_gpio5_hwmod = {
+ .name = "gpio5",
+ .mpu_irqs = omap243x_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs),
+ .main_clk = "gpio5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 2,
+ .module_bit = OMAP2430_EN_GPIO5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio5_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* dma_system */
+static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap2430_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x4a0560ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = {
+ .master = &omap2430_dma_system_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_masters[] = {
+ &omap2430_dma_system__l3,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2430_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_slaves[] = {
+ &omap2430_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2430_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2430_dma_hwmod_class,
+ .mpu_irqs = omap2430_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dma_system_irqs),
+ .main_clk = "core_l3_ck",
+ .slaves = omap2430_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dma_system_slaves),
+ .masters = omap2430_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_l3_main_hwmod,
&omap2430_l4_core_hwmod,
@@ -428,6 +929,18 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_uart1_hwmod,
&omap2430_uart2_hwmod,
&omap2430_uart3_hwmod,
+ &omap2430_i2c1_hwmod,
+ &omap2430_i2c2_hwmod,
+
+ /* gpio class */
+ &omap2430_gpio1_hwmod,
+ &omap2430_gpio2_hwmod,
+ &omap2430_gpio3_hwmod,
+ &omap2430_gpio4_hwmod,
+ &omap2430_gpio5_hwmod,
+
+ /* dma_system class*/
+ &omap2430_dma_system_hwmod,
NULL,
};
@@ -435,5 +948,3 @@ int __init omap2430_hwmod_init(void)
{
return omap_hwmod_init(omap2430_hwmods);
}
-
-
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index cb97ecf0a3f6..8d8181334f86 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -18,11 +18,16 @@
#include <plat/cpu.h>
#include <plat/dma.h>
#include <plat/serial.h>
+#include <plat/l4_3xxx.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
+#include <plat/smartreflex.h>
#include "omap_hwmod_common_data.h"
#include "prm-regbits-34xx.h"
#include "cm-regbits-34xx.h"
+#include "wd_timer.h"
/*
* OMAP3xxx hardware module integration data
@@ -39,6 +44,19 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod;
static struct omap_hwmod omap3xxx_l4_core_hwmod;
static struct omap_hwmod omap3xxx_l4_per_hwmod;
static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
+static struct omap_hwmod omap3xxx_i2c1_hwmod;
+static struct omap_hwmod omap3xxx_i2c2_hwmod;
+static struct omap_hwmod omap3xxx_i2c3_hwmod;
+static struct omap_hwmod omap3xxx_gpio1_hwmod;
+static struct omap_hwmod omap3xxx_gpio2_hwmod;
+static struct omap_hwmod omap3xxx_gpio3_hwmod;
+static struct omap_hwmod omap3xxx_gpio4_hwmod;
+static struct omap_hwmod omap3xxx_gpio5_hwmod;
+static struct omap_hwmod omap3xxx_gpio6_hwmod;
+static struct omap_hwmod omap34xx_sr1_hwmod;
+static struct omap_hwmod omap34xx_sr2_hwmod;
+
+static struct omap_hwmod omap3xxx_dma_system_hwmod;
/* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -169,9 +187,125 @@ static struct omap_hwmod_ocp_if omap3_l4_per__uart4 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap3xxx_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c1_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C1_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap3xxx_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c2_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C2_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C3 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c3_addr_space[] = {
+ {
+ .pa_start = 0x48060000,
+ .pa_end = 0x48060000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c3_hwmod,
+ .clk = "i2c3_ick",
+ .addr = omap3xxx_i2c3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c3_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C3_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
+ {
+ .pa_start = OMAP34XX_SR1_BASE,
+ .pa_end = OMAP34XX_SR1_BASE + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr1_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3_sr1_addr_space),
+ .user = OCP_USER_MPU,
+};
+
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = {
+ {
+ .pa_start = OMAP34XX_SR2_BASE,
+ .pa_end = OMAP34XX_SR2_BASE + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr2_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3_sr2_addr_space),
+ .user = OCP_USER_MPU,
+};
+
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
&omap3xxx_l3_main__l4_core,
+ &omap3_l4_core__sr1,
+ &omap3_l4_core__sr2,
};
/* Master interfaces on the L4_CORE interconnect */
@@ -179,6 +313,9 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
&omap3xxx_l4_core__l4_wkup,
&omap3_l4_core__uart1,
&omap3_l4_core__uart2,
+ &omap3_l4_core__i2c1,
+ &omap3_l4_core__i2c2,
+ &omap3_l4_core__i2c3,
};
/* L4 CORE */
@@ -315,9 +452,22 @@ static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = {
.sysc_fields = &omap_hwmod_sysc_type1,
};
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = {
- .name = "wd_timer",
- .sysc = &omap3xxx_wd_timer_sysc,
+ .name = "wd_timer",
+ .sysc = &omap3xxx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
};
/* wd_timer2 */
@@ -509,6 +659,703 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+/* I2C1 */
+
+static struct omap_i2c_dev_attr i2c1_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = {
+ &omap3_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap3xxx_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c1_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* I2C2 */
+
+static struct omap_i2c_dev_attr i2c2_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = {
+ &omap3_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap3xxx_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* I2C3 */
+
+static struct omap_i2c_dev_attr i2c3_dev_attr = {
+ .fifo_depth = 64, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = {
+ { .irq = INT_34XX_I2C3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP34XX_DMA_I2C3_TX },
+ { .name = "rx", .dma_req = OMAP34XX_DMA_I2C3_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = {
+ &omap3_l4_core__i2c3,
+};
+
+static struct omap_hwmod omap3xxx_i2c3_hwmod = {
+ .name = "i2c3",
+ .mpu_irqs = i2c3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c3_mpu_irqs),
+ .sdma_reqs = i2c3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c3_sdma_reqs),
+ .main_clk = "i2c3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c3_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c3_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = {
+ {
+ .pa_start = 0x48310000,
+ .pa_end = 0x483101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_gpio1_hwmod,
+ .addr = omap3xxx_gpio1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = {
+ {
+ .pa_start = 0x49050000,
+ .pa_end = 0x490501ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio2_hwmod,
+ .addr = omap3xxx_gpio2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = {
+ {
+ .pa_start = 0x49052000,
+ .pa_end = 0x490521ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio3_hwmod,
+ .addr = omap3xxx_gpio3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
+ {
+ .pa_start = 0x49054000,
+ .pa_end = 0x490541ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio4_hwmod,
+ .addr = omap3xxx_gpio4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = {
+ {
+ .pa_start = 0x49056000,
+ .pa_end = 0x490561ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio5_hwmod,
+ .addr = omap3xxx_gpio5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = {
+ {
+ .pa_start = 0x49058000,
+ .pa_end = 0x490581ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio6_hwmod,
+ .addr = omap3xxx_gpio6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap3xxx_gpio_sysc,
+ .rev = 1,
+};
+
+/* gpio_dev_attr*/
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap3xxx_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_34XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = {
+ &omap3xxx_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap3xxx_gpio1_hwmod = {
+ .name = "gpio1",
+ .mpu_irqs = omap3xxx_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs),
+ .main_clk = "gpio1_ick",
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio1_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap3xxx_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_34XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = {
+ &omap3xxx_l4_per__gpio2,
+};
+
+static struct omap_hwmod omap3xxx_gpio2_hwmod = {
+ .name = "gpio2",
+ .mpu_irqs = omap3xxx_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs),
+ .main_clk = "gpio2_ick",
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO2_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio2_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap3xxx_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_34XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = {
+ &omap3xxx_l4_per__gpio3,
+};
+
+static struct omap_hwmod omap3xxx_gpio3_hwmod = {
+ .name = "gpio3",
+ .mpu_irqs = omap3xxx_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs),
+ .main_clk = "gpio3_ick",
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO3_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio3_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap3xxx_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_34XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = {
+ &omap3xxx_l4_per__gpio4,
+};
+
+static struct omap_hwmod omap3xxx_gpio4_hwmod = {
+ .name = "gpio4",
+ .mpu_irqs = omap3xxx_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs),
+ .main_clk = "gpio4_ick",
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO4_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio4_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio5 */
+static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = {
+ { .irq = 33 }, /* INT_34XX_GPIO_BANK5 */
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = {
+ &omap3xxx_l4_per__gpio5,
+};
+
+static struct omap_hwmod omap3xxx_gpio5_hwmod = {
+ .name = "gpio5",
+ .mpu_irqs = omap3xxx_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs),
+ .main_clk = "gpio5_ick",
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO5_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO5_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio5_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio6 */
+static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = {
+ { .irq = 34 }, /* INT_34XX_GPIO_BANK6 */
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = {
+ &omap3xxx_l4_per__gpio6,
+};
+
+static struct omap_hwmod omap3xxx_gpio6_hwmod = {
+ .name = "gpio6",
+ .mpu_irqs = omap3xxx_gpio6_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs),
+ .main_clk = "gpio6_ick",
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO6_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO6_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio6_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap3xxx_dma_system__l3 = {
+ .master = &omap3xxx_dma_system_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap3xxx_dma_sysc,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x4a0560ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_masters[] = {
+ &omap3xxx_dma_system__l3,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dma_system_hwmod,
+ .clk = "core_l4_ick",
+ .addr = omap3xxx_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_slaves[] = {
+ &omap3xxx_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap3xxx_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap3xxx_dma_hwmod_class,
+ .mpu_irqs = omap3xxx_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dma_system_irqs),
+ .main_clk = "core_l3_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_ST_SDMA_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_SDMA_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dma_system_slaves),
+ .masters = omap3xxx_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* SR common */
+static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = {
+ .clkact_shift = 20,
+};
+
+static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
+ .sysc_offs = 0x24,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap34xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap34xx_sr_sysc,
+ .rev = 1,
+};
+
+static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = {
+ .sidle_shift = 24,
+ .enwkup_shift = 26
+};
+
+static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
+ .sysc_offs = 0x38,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_NO_CACHE),
+ .sysc_fields = &omap36xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap36xx_sr_sysc,
+ .rev = 2,
+};
+
+/* SR1 */
+static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
+ &omap3_l4_core__sr1,
+};
+
+static struct omap_hwmod omap34xx_sr1_hwmod = {
+ .name = "sr1_hwmod",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
+ },
+ },
+ .slaves = omap3_sr1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0 |
+ CHIP_IS_OMAP3430ES3_1),
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr1_hwmod = {
+ .name = "sr1_hwmod",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
+ },
+ },
+ .slaves = omap3_sr1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
+/* SR2 */
+static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
+ &omap3_l4_core__sr2,
+};
+
+static struct omap_hwmod omap34xx_sr2_hwmod = {
+ .name = "sr2_hwmod",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
+ },
+ },
+ .slaves = omap3_sr2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0 |
+ CHIP_IS_OMAP3430ES3_1),
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr2_hwmod = {
+ .name = "sr2_hwmod",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
+ },
+ },
+ .slaves = omap3_sr2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_l3_main_hwmod,
&omap3xxx_l4_core_hwmod,
@@ -521,6 +1368,25 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_uart2_hwmod,
&omap3xxx_uart3_hwmod,
&omap3xxx_uart4_hwmod,
+ &omap3xxx_i2c1_hwmod,
+ &omap3xxx_i2c2_hwmod,
+ &omap3xxx_i2c3_hwmod,
+ &omap34xx_sr1_hwmod,
+ &omap34xx_sr2_hwmod,
+ &omap36xx_sr1_hwmod,
+ &omap36xx_sr2_hwmod,
+
+
+ /* gpio class */
+ &omap3xxx_gpio1_hwmod,
+ &omap3xxx_gpio2_hwmod,
+ &omap3xxx_gpio3_hwmod,
+ &omap3xxx_gpio4_hwmod,
+ &omap3xxx_gpio5_hwmod,
+ &omap3xxx_gpio6_hwmod,
+
+ /* dma_system class*/
+ &omap3xxx_dma_system_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 7274db4de487..c2806bd11fbf 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -22,11 +22,16 @@
#include <plat/omap_hwmod.h>
#include <plat/cpu.h>
+#include <plat/gpio.h>
+#include <plat/dma.h>
#include "omap_hwmod_common_data.h"
-#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prm44xx.h"
#include "prm-regbits-44xx.h"
+#include "wd_timer.h"
/* Base offset for all OMAP4 interrupts external to MPUSS */
#define OMAP44XX_IRQ_GIC_START 32
@@ -35,8 +40,11 @@
#define OMAP44XX_DMA_REQ_START 1
/* Backward references (IPs with Bus Master capability) */
+static struct omap_hwmod omap44xx_dma_system_hwmod;
static struct omap_hwmod omap44xx_dmm_hwmod;
+static struct omap_hwmod omap44xx_dsp_hwmod;
static struct omap_hwmod omap44xx_emif_fw_hwmod;
+static struct omap_hwmod omap44xx_iva_hwmod;
static struct omap_hwmod omap44xx_l3_instr_hwmod;
static struct omap_hwmod omap44xx_l3_main_1_hwmod;
static struct omap_hwmod omap44xx_l3_main_2_hwmod;
@@ -58,7 +66,7 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod;
* instance(s): dmm
*/
static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
- .name = "dmm",
+ .name = "dmm",
};
/* dmm interface data */
@@ -67,7 +75,15 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
.master = &omap44xx_l3_main_1_hwmod,
.slave = &omap44xx_dmm_hwmod,
.clk = "l3_div_ck",
- .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dmm_addrs[] = {
+ {
+ .pa_start = 0x4e000000,
+ .pa_end = 0x4e0007ff,
+ .flags = ADDR_TYPE_RT
+ },
};
/* mpu -> dmm */
@@ -75,7 +91,9 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
.master = &omap44xx_mpu_hwmod,
.slave = &omap44xx_dmm_hwmod,
.clk = "l3_div_ck",
- .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .addr = omap44xx_dmm_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dmm_addrs),
+ .user = OCP_USER_MPU,
};
/* dmm slave ports */
@@ -103,7 +121,7 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
* instance(s): emif_fw
*/
static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
- .name = "emif_fw",
+ .name = "emif_fw",
};
/* emif_fw interface data */
@@ -115,12 +133,22 @@ static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_addr_space omap44xx_emif_fw_addrs[] = {
+ {
+ .pa_start = 0x4a20c000,
+ .pa_end = 0x4a20c0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
/* l4_cfg -> emif_fw */
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = {
.master = &omap44xx_l4_cfg_hwmod,
.slave = &omap44xx_emif_fw_hwmod,
.clk = "l4_div_ck",
- .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .addr = omap44xx_emif_fw_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_emif_fw_addrs),
+ .user = OCP_USER_MPU,
};
/* emif_fw slave ports */
@@ -142,10 +170,18 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = {
* instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
*/
static struct omap_hwmod_class omap44xx_l3_hwmod_class = {
- .name = "l3",
+ .name = "l3",
};
/* l3_instr interface data */
+/* iva -> l3_instr */
+static struct omap_hwmod_ocp_if omap44xx_iva__l3_instr = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_l3_instr_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l3_main_3 -> l3_instr */
static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = {
.master = &omap44xx_l3_main_3_hwmod,
@@ -156,6 +192,7 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = {
/* l3_instr slave ports */
static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = {
+ &omap44xx_iva__l3_instr,
&omap44xx_l3_main_3__l3_instr,
};
@@ -167,6 +204,15 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
+/* l3_main_1 interface data */
+/* dsp -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l3_main_2 -> l3_main_1 */
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = {
.master = &omap44xx_l3_main_2_hwmod,
@@ -193,6 +239,7 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
/* l3_main_1 slave ports */
static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
+ &omap44xx_dsp__l3_main_1,
&omap44xx_l3_main_2__l3_main_1,
&omap44xx_l4_cfg__l3_main_1,
&omap44xx_mpu__l3_main_1,
@@ -207,6 +254,22 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
};
/* l3_main_2 interface data */
+/* dma_system -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
+ .master = &omap44xx_dma_system_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iva -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l3_main_1 -> l3_main_2 */
static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
.master = &omap44xx_l3_main_1_hwmod,
@@ -225,6 +288,8 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
/* l3_main_2 slave ports */
static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
+ &omap44xx_dma_system__l3_main_2,
+ &omap44xx_iva__l3_main_2,
&omap44xx_l3_main_1__l3_main_2,
&omap44xx_l4_cfg__l3_main_2,
};
@@ -282,10 +347,18 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
* instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
*/
static struct omap_hwmod_class omap44xx_l4_hwmod_class = {
- .name = "l4",
+ .name = "l4",
};
/* l4_abe interface data */
+/* dsp -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "ocp_abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l3_main_1 -> l4_abe */
static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = {
.master = &omap44xx_l3_main_1_hwmod,
@@ -304,6 +377,7 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = {
/* l4_abe slave ports */
static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = {
+ &omap44xx_dsp__l4_abe,
&omap44xx_l3_main_1__l4_abe,
&omap44xx_mpu__l4_abe,
};
@@ -387,7 +461,7 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
* instance(s): mpu_private
*/
static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
- .name = "mpu_bus",
+ .name = "mpu_bus",
};
/* mpu_private interface data */
@@ -413,12 +487,960 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
};
/*
+ * Modules omap_hwmod structures
+ *
+ * The following IPs are excluded for the moment because:
+ * - They do not need an explicit SW control using omap_hwmod API.
+ * - They still need to be validated with the driver
+ * properly adapted to omap_hwmod / omap_device
+ *
+ * aess
+ * bandgap
+ * c2c
+ * c2c_target_fw
+ * cm_core
+ * cm_core_aon
+ * counter_32k
+ * ctrl_module_core
+ * ctrl_module_pad_core
+ * ctrl_module_pad_wkup
+ * ctrl_module_wkup
+ * debugss
+ * dmic
+ * dss
+ * dss_dispc
+ * dss_dsi1
+ * dss_dsi2
+ * dss_hdmi
+ * dss_rfbi
+ * dss_venc
+ * efuse_ctrl_cust
+ * efuse_ctrl_std
+ * elm
+ * emif1
+ * emif2
+ * fdif
+ * gpmc
+ * gpu
+ * hdq1w
+ * hsi
+ * ipu
+ * iss
+ * kbd
+ * mailbox
+ * mcasp
+ * mcbsp1
+ * mcbsp2
+ * mcbsp3
+ * mcbsp4
+ * mcpdm
+ * mcspi1
+ * mcspi2
+ * mcspi3
+ * mcspi4
+ * mmc1
+ * mmc2
+ * mmc3
+ * mmc4
+ * mmc5
+ * mpu_c0
+ * mpu_c1
+ * ocmc_ram
+ * ocp2scp_usb_phy
+ * ocp_wp_noc
+ * prcm
+ * prcm_mpu
+ * prm
+ * scrm
+ * sl2if
+ * slimbus1
+ * slimbus2
+ * spinlock
+ * timer1
+ * timer10
+ * timer11
+ * timer2
+ * timer3
+ * timer4
+ * timer5
+ * timer6
+ * timer7
+ * timer8
+ * timer9
+ * usb_host_fs
+ * usb_host_hs
+ * usb_otg_hs
+ * usb_phy_cm
+ * usb_tll_hs
+ * usim
+ */
+
+/*
+ * 'dma' class
+ * dma controller for data exchange between memory to memory (i.e. internal or
+ * external memory) and gp peripherals to memory or memory to gp peripherals
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap44xx_dma_sysc,
+};
+
+/* dma dev_attr */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap44xx_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 + OMAP44XX_IRQ_GIC_START },
+ { .name = "1", .irq = 13 + OMAP44XX_IRQ_GIC_START },
+ { .name = "2", .irq = 14 + OMAP44XX_IRQ_GIC_START },
+ { .name = "3", .irq = 15 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = {
+ &omap44xx_dma_system__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x4a056000,
+ .pa_end = 0x4a0560ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dma_system = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_dma_system_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_slaves[] = {
+ &omap44xx_l4_cfg__dma_system,
+};
+
+static struct omap_hwmod omap44xx_dma_system_hwmod = {
+ .name = "dma_system",
+ .class = &omap44xx_dma_hwmod_class,
+ .mpu_irqs = omap44xx_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dma_system_irqs),
+ .main_clk = "l3_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+ .slaves = omap44xx_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dma_system_slaves),
+ .masters = omap44xx_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dma_system_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dsp' class
+ * dsp sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_dsp_hwmod_class = {
+ .name = "dsp",
+};
+
+/* dsp */
+static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
+ { .irq = 28 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_dsp_c0_resets[] = {
+ { .name = "dsp", .rst_shift = 0 },
+};
+
+/* dsp -> iva */
+static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_iva_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+};
+
+/* dsp master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dsp_masters[] = {
+ &omap44xx_dsp__l3_main_1,
+ &omap44xx_dsp__l4_abe,
+ &omap44xx_dsp__iva,
+};
+
+/* l4_cfg -> dsp */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_dsp_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dsp slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dsp_slaves[] = {
+ &omap44xx_l4_cfg__dsp,
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
+ .name = "dsp_c0",
+ .class = &omap44xx_dsp_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_dsp_c0_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_c0_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct omap_hwmod omap44xx_dsp_hwmod = {
+ .name = "dsp",
+ .class = &omap44xx_dsp_hwmod_class,
+ .mpu_irqs = omap44xx_dsp_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dsp_irqs),
+ .rst_lines = omap44xx_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets),
+ .main_clk = "dsp_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+ .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ },
+ },
+ .slaves = omap44xx_dsp_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dsp_slaves),
+ .masters = omap44xx_dsp_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dsp_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0114,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap44xx_gpio_sysc,
+ .rev = 2,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod omap44xx_gpio1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = {
+ { .irq = 29 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = {
+ {
+ .pa_start = 0x4a310000,
+ .pa_end = 0x4a3101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_gpio1_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_gpio1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = {
+ &omap44xx_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &omap44xx_gpio_hwmod_class,
+ .mpu_irqs = omap44xx_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs),
+ .main_clk = "gpio1_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio2 */
+static struct omap_hwmod omap44xx_gpio2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = {
+ { .irq = 30 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = {
+ {
+ .pa_start = 0x48055000,
+ .pa_end = 0x480551ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = {
+ &omap44xx_l4_per__gpio2,
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs),
+ .main_clk = "gpio2_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio3 */
+static struct omap_hwmod omap44xx_gpio3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = {
+ { .irq = 31 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = {
+ {
+ .pa_start = 0x48057000,
+ .pa_end = 0x480571ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = {
+ &omap44xx_l4_per__gpio3,
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio3_hwmod = {
+ .name = "gpio3",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio3_irqs),
+ .main_clk = "gpio3_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio4 */
+static struct omap_hwmod omap44xx_gpio4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = {
+ { .irq = 32 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = {
+ {
+ .pa_start = 0x48059000,
+ .pa_end = 0x480591ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = {
+ &omap44xx_l4_per__gpio4,
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio4_hwmod = {
+ .name = "gpio4",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio4_irqs),
+ .main_clk = "gpio4_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio5 */
+static struct omap_hwmod omap44xx_gpio5_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = {
+ { .irq = 33 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = {
+ {
+ .pa_start = 0x4805b000,
+ .pa_end = 0x4805b1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio5_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio5 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = {
+ &omap44xx_l4_per__gpio5,
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio5_hwmod = {
+ .name = "gpio5",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio5_irqs),
+ .main_clk = "gpio5_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio6 */
+static struct omap_hwmod omap44xx_gpio6_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = {
+ { .irq = 34 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = {
+ {
+ .pa_start = 0x4805d000,
+ .pa_end = 0x4805d1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio6_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio6 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = {
+ &omap44xx_l4_per__gpio6,
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio6_hwmod = {
+ .name = "gpio6",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio6_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio6_irqs),
+ .main_clk = "gpio6_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'i2c' class
+ * multimaster high-speed i2c controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = {
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0090,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_i2c_hwmod_class = {
+ .name = "i2c",
+ .sysc = &omap44xx_i2c_sysc,
+};
+
+/* i2c1 */
+static struct omap_hwmod omap44xx_i2c1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = {
+ { .irq = 56 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x480700ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = {
+ &omap44xx_l4_per__i2c1,
+};
+
+static struct omap_hwmod omap44xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs),
+ .sdma_reqs = omap44xx_i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c2 */
+static struct omap_hwmod omap44xx_i2c2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = {
+ { .irq = 57 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x480720ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = {
+ &omap44xx_l4_per__i2c2,
+};
+
+static struct omap_hwmod omap44xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs),
+ .sdma_reqs = omap44xx_i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c3 */
+static struct omap_hwmod omap44xx_i2c3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = {
+ { .irq = 61 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = {
+ {
+ .pa_start = 0x48060000,
+ .pa_end = 0x480600ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = {
+ &omap44xx_l4_per__i2c3,
+};
+
+static struct omap_hwmod omap44xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs),
+ .sdma_reqs = omap44xx_i2c3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c3_sdma_reqs),
+ .main_clk = "i2c3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c4 */
+static struct omap_hwmod omap44xx_i2c4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = {
+ { .irq = 62 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = {
+ {
+ .pa_start = 0x48350000,
+ .pa_end = 0x483500ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = {
+ &omap44xx_l4_per__i2c4,
+};
+
+static struct omap_hwmod omap44xx_i2c4_hwmod = {
+ .name = "i2c4",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs),
+ .sdma_reqs = omap44xx_i2c4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c4_sdma_reqs),
+ .main_clk = "i2c4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'iva' class
+ * multi-standard video encoder/decoder hardware accelerator
+ */
+
+static struct omap_hwmod_class omap44xx_iva_hwmod_class = {
+ .name = "iva",
+};
+
+/* iva */
+static struct omap_hwmod_irq_info omap44xx_iva_irqs[] = {
+ { .name = "sync_1", .irq = 103 + OMAP44XX_IRQ_GIC_START },
+ { .name = "sync_0", .irq = 104 + OMAP44XX_IRQ_GIC_START },
+ { .name = "mailbox_0", .irq = 107 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_resets[] = {
+ { .name = "logic", .rst_shift = 2 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_seq0_resets[] = {
+ { .name = "seq0", .rst_shift = 0 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_seq1_resets[] = {
+ { .name = "seq1", .rst_shift = 1 },
+};
+
+/* iva master ports */
+static struct omap_hwmod_ocp_if *omap44xx_iva_masters[] = {
+ &omap44xx_iva__l3_main_2,
+ &omap44xx_iva__l3_instr,
+};
+
+static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = {
+ {
+ .pa_start = 0x5a000000,
+ .pa_end = 0x5a07ffff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> iva */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_iva_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_iva_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_iva_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* iva slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = {
+ &omap44xx_dsp__iva,
+ &omap44xx_l3_main_2__iva,
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
+ .name = "iva_seq0",
+ .class = &omap44xx_iva_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_iva_seq0_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
+ .name = "iva_seq1",
+ .class = &omap44xx_iva_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_iva_seq1_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct omap_hwmod omap44xx_iva_hwmod = {
+ .name = "iva",
+ .class = &omap44xx_iva_hwmod_class,
+ .mpu_irqs = omap44xx_iva_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iva_irqs),
+ .rst_lines = omap44xx_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets),
+ .main_clk = "iva_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .slaves = omap44xx_iva_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves),
+ .masters = omap44xx_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
* 'mpu' class
* mpu sub-system
*/
static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
- .name = "mpu",
+ .name = "mpu",
};
/* mpu */
@@ -453,58 +1475,189 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
};
/*
- * 'wd_timer' class
- * 32-bit watchdog upward counter that generates a pulse on the reset pin on
- * overflow condition
+ * 'smartreflex' class
+ * smartreflex module (monitor silicon performance and outputs a measure of
+ * performance error)
*/
-static struct omap_hwmod_class_sysconfig omap44xx_wd_timer_sysc = {
- .rev_offs = 0x0000,
- .sysc_offs = 0x0010,
- .syss_offs = 0x0014,
- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE |
- SYSC_HAS_SOFTRESET),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
- .sysc_fields = &omap_hwmod_sysc_type1,
+/* The IP is not compliant to type1 / type2 scheme */
+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
+ .sidle_shift = 24,
+ .enwkup_shift = 26,
};
-/*
- * 'uart' class
- * universal asynchronous receiver/transmitter (uart)
- */
+static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
+ .sysc_offs = 0x0038,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type_smartreflex,
+};
-static struct omap_hwmod_class_sysconfig omap44xx_uart_sysc = {
- .rev_offs = 0x0050,
- .sysc_offs = 0x0054,
- .syss_offs = 0x0058,
- .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
- .sysc_fields = &omap_hwmod_sysc_type1,
+static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap44xx_smartreflex_sysc,
+ .rev = 2,
};
-static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = {
- .name = "wd_timer",
- .sysc = &omap44xx_wd_timer_sysc,
+/* smartreflex_core */
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
+ { .irq = 19 + OMAP44XX_IRQ_GIC_START },
};
-/* wd_timer2 */
-static struct omap_hwmod omap44xx_wd_timer2_hwmod;
-static struct omap_hwmod_irq_info omap44xx_wd_timer2_irqs[] = {
- { .irq = 80 + OMAP44XX_IRQ_GIC_START },
+static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
+ {
+ .pa_start = 0x4a0dd000,
+ .pa_end = 0x4a0dd03f,
+ .flags = ADDR_TYPE_RT
+ },
};
-static struct omap_hwmod_addr_space omap44xx_wd_timer2_addrs[] = {
+/* l4_cfg -> smartreflex_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_core_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_core slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_core,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_core_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
+ .main_clk = "smartreflex_core_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* smartreflex_iva */
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
+ { .irq = 102 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
{
- .pa_start = 0x4a314000,
- .pa_end = 0x4a31407f,
+ .pa_start = 0x4a0db000,
+ .pa_end = 0x4a0db03f,
.flags = ADDR_TYPE_RT
},
};
+/* l4_cfg -> smartreflex_iva */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_iva_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_iva_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_iva slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_iva,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
+ .name = "smartreflex_iva",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_iva_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
+ .main_clk = "smartreflex_iva_fck",
+ .vdd_name = "iva",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_iva_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* smartreflex_mpu */
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
+ { .irq = 18 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
+ {
+ .pa_start = 0x4a0d9000,
+ .pa_end = 0x4a0d903f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_mpu */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_mpu_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_mpu_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_mpu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_mpu,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
+ .name = "smartreflex_mpu",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
+ .main_clk = "smartreflex_mpu_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_mpu_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'uart' class
+ * universal asynchronous receiver/transmitter (uart)
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_uart_sysc = {
+ .rev_offs = 0x0050,
+ .sysc_offs = 0x0054,
+ .syss_offs = 0x0058,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
static struct omap_hwmod_class omap44xx_uart_hwmod_class = {
- .name = "uart",
- .sysc = &omap44xx_uart_sysc,
+ .name = "uart",
+ .sysc = &omap44xx_uart_sysc,
};
/* uart1 */
@@ -578,51 +1731,6 @@ static struct omap_hwmod_addr_space omap44xx_uart2_addrs[] = {
},
};
-/* l4_wkup -> wd_timer2 */
-static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = {
- .master = &omap44xx_l4_wkup_hwmod,
- .slave = &omap44xx_wd_timer2_hwmod,
- .clk = "l4_wkup_clk_mux_ck",
- .addr = omap44xx_wd_timer2_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer2_addrs),
- .user = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* wd_timer2 slave ports */
-static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = {
- &omap44xx_l4_wkup__wd_timer2,
-};
-
-static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
- .name = "wd_timer2",
- .class = &omap44xx_wd_timer_hwmod_class,
- .mpu_irqs = omap44xx_wd_timer2_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer2_irqs),
- .main_clk = "wd_timer2_fck",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
- },
- },
- .slaves = omap44xx_wd_timer2_slaves,
- .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
-/* wd_timer3 */
-static struct omap_hwmod omap44xx_wd_timer3_hwmod;
-static struct omap_hwmod_irq_info omap44xx_wd_timer3_irqs[] = {
- { .irq = 36 + OMAP44XX_IRQ_GIC_START },
-};
-
-static struct omap_hwmod_addr_space omap44xx_wd_timer3_addrs[] = {
- {
- .pa_start = 0x40130000,
- .pa_end = 0x4013007f,
- .flags = ADDR_TYPE_RT
- },
-};
-
/* l4_per -> uart2 */
static struct omap_hwmod_ocp_if omap44xx_l4_per__uart2 = {
.master = &omap44xx_l4_per_hwmod,
@@ -675,25 +1783,6 @@ static struct omap_hwmod_addr_space omap44xx_uart3_addrs[] = {
},
};
-/* l4_abe -> wd_timer3 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3 = {
- .master = &omap44xx_l4_abe_hwmod,
- .slave = &omap44xx_wd_timer3_hwmod,
- .clk = "ocp_abe_iclk",
- .addr = omap44xx_wd_timer3_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_addrs),
- .user = OCP_USER_MPU,
-};
-
-/* l4_abe -> wd_timer3 (dma) */
-static struct omap_hwmod_addr_space omap44xx_wd_timer3_dma_addrs[] = {
- {
- .pa_start = 0x49030000,
- .pa_end = 0x4903007f,
- .flags = ADDR_TYPE_RT
- },
-};
-
/* l4_per -> uart3 */
static struct omap_hwmod_ocp_if omap44xx_l4_per__uart3 = {
.master = &omap44xx_l4_per_hwmod,
@@ -747,37 +1836,6 @@ static struct omap_hwmod_addr_space omap44xx_uart4_addrs[] = {
},
};
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = {
- .master = &omap44xx_l4_abe_hwmod,
- .slave = &omap44xx_wd_timer3_hwmod,
- .clk = "ocp_abe_iclk",
- .addr = omap44xx_wd_timer3_dma_addrs,
- .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_dma_addrs),
- .user = OCP_USER_SDMA,
-};
-
-/* wd_timer3 slave ports */
-static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = {
- &omap44xx_l4_abe__wd_timer3,
- &omap44xx_l4_abe__wd_timer3_dma,
-};
-
-static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
- .name = "wd_timer3",
- .class = &omap44xx_wd_timer_hwmod_class,
- .mpu_irqs = omap44xx_wd_timer3_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer3_irqs),
- .main_clk = "wd_timer3_fck",
- .prcm = {
- .omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
- },
- },
- .slaves = omap44xx_wd_timer3_slaves,
- .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-};
-
/* l4_per -> uart4 */
static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = {
.master = &omap44xx_l4_per_hwmod,
@@ -811,35 +1869,205 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap44xx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap44xx_wd_timer2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer2_irqs[] = {
+ { .irq = 80 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x4a314000,
+ .pa_end = 0x4a31407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_wd_timer2_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* wd_timer2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = {
+ &omap44xx_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer2_irqs),
+ .main_clk = "wd_timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* wd_timer3 */
+static struct omap_hwmod omap44xx_wd_timer3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer3_irqs[] = {
+ { .irq = 36 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_addrs[] = {
+ {
+ .pa_start = 0x40130000,
+ .pa_end = 0x4013007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> wd_timer3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_dma_addrs[] = {
+ {
+ .pa_start = 0x49030000,
+ .pa_end = 0x4903007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> wd_timer3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* wd_timer3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = {
+ &omap44xx_l4_abe__wd_timer3,
+ &omap44xx_l4_abe__wd_timer3_dma,
+};
+
+static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
+ .name = "wd_timer3",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer3_irqs),
+ .main_clk = "wd_timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
+
/* dmm class */
&omap44xx_dmm_hwmod,
+
/* emif_fw class */
&omap44xx_emif_fw_hwmod,
+
/* l3 class */
&omap44xx_l3_instr_hwmod,
&omap44xx_l3_main_1_hwmod,
&omap44xx_l3_main_2_hwmod,
&omap44xx_l3_main_3_hwmod,
+
/* l4 class */
&omap44xx_l4_abe_hwmod,
&omap44xx_l4_cfg_hwmod,
&omap44xx_l4_per_hwmod,
&omap44xx_l4_wkup_hwmod,
+
/* mpu_bus class */
&omap44xx_mpu_private_hwmod,
+ /* dma class */
+ &omap44xx_dma_system_hwmod,
+
+ /* dsp class */
+ &omap44xx_dsp_hwmod,
+ &omap44xx_dsp_c0_hwmod,
+
+ /* gpio class */
+ &omap44xx_gpio1_hwmod,
+ &omap44xx_gpio2_hwmod,
+ &omap44xx_gpio3_hwmod,
+ &omap44xx_gpio4_hwmod,
+ &omap44xx_gpio5_hwmod,
+ &omap44xx_gpio6_hwmod,
+
+ /* i2c class */
+ &omap44xx_i2c1_hwmod,
+ &omap44xx_i2c2_hwmod,
+ &omap44xx_i2c3_hwmod,
+ &omap44xx_i2c4_hwmod,
+
+ /* iva class */
+ &omap44xx_iva_hwmod,
+ &omap44xx_iva_seq0_hwmod,
+ &omap44xx_iva_seq1_hwmod,
+
/* mpu class */
&omap44xx_mpu_hwmod,
- /* wd_timer class */
- &omap44xx_wd_timer2_hwmod,
- &omap44xx_wd_timer3_hwmod,
+
+ /* smartreflex class */
+ &omap44xx_smartreflex_core_hwmod,
+ &omap44xx_smartreflex_iva_hwmod,
+ &omap44xx_smartreflex_mpu_hwmod,
/* uart class */
&omap44xx_uart1_hwmod,
&omap44xx_uart2_hwmod,
&omap44xx_uart3_hwmod,
&omap44xx_uart4_hwmod,
+
+ /* wd_timer class */
+ &omap44xx_wd_timer2_hwmod,
+ &omap44xx_wd_timer3_hwmod,
+
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
new file mode 100644
index 000000000000..46ac27dd6c84
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -0,0 +1,72 @@
+/*
+ * OMAP SoC specific OPP Data helpers
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
+
+#include <plat/omap_hwmod.h>
+
+/*
+ * *BIG FAT WARNING*:
+ * USE the following ONLY in opp data initialization common to an SoC.
+ * DO NOT USE these in board files/pm core etc.
+ */
+
+/**
+ * struct omap_opp_def - OMAP OPP Definition
+ * @hwmod_name: Name of the hwmod for this domain
+ * @freq: Frequency in hertz corresponding to this OPP
+ * @u_volt: Nominal voltage in microvolts corresponding to this OPP
+ * @default_available: True/false - is this OPP available by default
+ *
+ * OMAP SOCs have a standard set of tuples consisting of frequency and voltage
+ * pairs that the device will support per voltage domain. This is called
+ * Operating Points or OPP. The actual definitions of OMAP Operating Points
+ * varies over silicon within the same family of devices. For a specific
+ * domain, you can have a set of {frequency, voltage} pairs and this is denoted
+ * by an array of omap_opp_def. As the kernel boots and more information is
+ * available, a set of these are activated based on the precise nature of
+ * device the kernel boots up on. It is interesting to remember that each IP
+ * which belongs to a voltage domain may define their own set of OPPs on top
+ * of this - but this is handled by the appropriate driver.
+ */
+struct omap_opp_def {
+ char *hwmod_name;
+
+ unsigned long freq;
+ unsigned long u_volt;
+
+ bool default_available;
+};
+
+/*
+ * Initialization wrapper used to define an OPP for OMAP variants.
+ */
+#define OPP_INITIALIZER(_hwmod_name, _enabled, _freq, _uv) \
+{ \
+ .hwmod_name = _hwmod_name, \
+ .default_available = _enabled, \
+ .freq = _freq, \
+ .u_volt = _uv, \
+}
+
+/* Use this to initialize the default table */
+extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
+ u32 opp_def_size);
+
+#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
new file mode 100644
index 000000000000..15f8c6c1bb0f
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -0,0 +1,277 @@
+/**
+ * OMAP and TWL PMIC specific intializations.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated.
+ * Thara Gopinath
+ * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Nishanth Menon
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/i2c/twl.h>
+
+#include <plat/voltage.h>
+
+#define OMAP3_SRI2C_SLAVE_ADDR 0x12
+#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
+#define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01
+#define OMAP3_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP3_VP_VSTEPMIN_VSTEPMIN 0x1
+#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
+
+#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
+#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
+#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
+#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
+#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
+#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
+#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
+
+#define OMAP4_SRI2C_SLAVE_ADDR 0x12
+#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
+
+#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
+#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
+
+static bool is_offset_valid;
+static u8 smps_offset;
+
+#define REG_SMPS_OFFSET 0xE0
+
+unsigned long twl4030_vsel_to_uv(const u8 vsel)
+{
+ return (((vsel * 125) + 6000)) * 100;
+}
+
+u8 twl4030_uv_to_vsel(unsigned long uv)
+{
+ return DIV_ROUND_UP(uv - 600000, 12500);
+}
+
+unsigned long twl6030_vsel_to_uv(const u8 vsel)
+{
+ /*
+ * In TWL6030 depending on the value of SMPS_OFFSET
+ * efuse register the voltage range supported in
+ * standard mode can be either between 0.6V - 1.3V or
+ * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
+ * is programmed to all 0's where as starting from
+ * TWL6030 ES1.1 the efuse is programmed to 1
+ */
+ if (!is_offset_valid) {
+ twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
+ REG_SMPS_OFFSET);
+ is_offset_valid = true;
+ }
+
+ /*
+ * There is no specific formula for voltage to vsel
+ * conversion above 1.3V. There are special hardcoded
+ * values for voltages above 1.3V. Currently we are
+ * hardcoding only for 1.35 V which is used for 1GH OPP for
+ * OMAP4430.
+ */
+ if (vsel == 0x3A)
+ return 1350000;
+
+ if (smps_offset & 0x8)
+ return ((((vsel - 1) * 125) + 7000)) * 100;
+ else
+ return ((((vsel - 1) * 125) + 6000)) * 100;
+}
+
+u8 twl6030_uv_to_vsel(unsigned long uv)
+{
+ /*
+ * In TWL6030 depending on the value of SMPS_OFFSET
+ * efuse register the voltage range supported in
+ * standard mode can be either between 0.6V - 1.3V or
+ * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
+ * is programmed to all 0's where as starting from
+ * TWL6030 ES1.1 the efuse is programmed to 1
+ */
+ if (!is_offset_valid) {
+ twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
+ REG_SMPS_OFFSET);
+ is_offset_valid = true;
+ }
+
+ /*
+ * There is no specific formula for voltage to vsel
+ * conversion above 1.3V. There are special hardcoded
+ * values for voltages above 1.3V. Currently we are
+ * hardcoding only for 1.35 V which is used for 1GH OPP for
+ * OMAP4430.
+ */
+ if (uv == 1350000)
+ return 0x3A;
+
+ if (smps_offset & 0x8)
+ return DIV_ROUND_UP(uv - 700000, 12500) + 1;
+ else
+ return DIV_ROUND_UP(uv - 600000, 12500) + 1;
+}
+
+static struct omap_volt_pmic_info omap3_mpu_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1200000,
+ .onlp_volt = 1000000,
+ .ret_volt = 975000,
+ .off_volt = 600000,
+ .volt_setup_time = 0xfff,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap3_core_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1200000,
+ .onlp_volt = 1000000,
+ .ret_volt = 975000,
+ .off_volt = 600000,
+ .volt_setup_time = 0xfff,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_mpu_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1350000,
+ .onlp_volt = 1350000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_iva_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1100000,
+ .onlp_volt = 1100000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_core_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1100000,
+ .onlp_volt = 1100000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+int __init omap4_twl_init(void)
+{
+ struct voltagedomain *voltdm;
+
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ voltdm = omap_voltage_domain_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("iva");
+ omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
+
+ return 0;
+}
+
+int __init omap3_twl_init(void)
+{
+ struct voltagedomain *voltdm;
+
+ if (!cpu_is_omap34xx())
+ return -ENODEV;
+
+ if (cpu_is_omap3630()) {
+ omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
+ omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
+ omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
+ omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+ }
+
+ voltdm = omap_voltage_domain_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
new file mode 100644
index 000000000000..ab8b35b780b5
--- /dev/null
+++ b/arch/arm/mach-omap2/opp.c
@@ -0,0 +1,93 @@
+/*
+ * OMAP SoC specific OPP wrapper function
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/opp.h>
+
+#include <plat/omap_device.h>
+
+#include "omap_opp_data.h"
+
+/* Temp variable to allow multiple calls */
+static u8 __initdata omap_table_init;
+
+/**
+ * omap_init_opp_table() - Initialize opp table as per the CPU type
+ * @opp_def: opp default list for this silicon
+ * @opp_def_size: number of opp entries for this silicon
+ *
+ * Register the initial OPP table with the OPP library based on the CPU
+ * type. This is meant to be used only by SoC specific registration.
+ */
+int __init omap_init_opp_table(struct omap_opp_def *opp_def,
+ u32 opp_def_size)
+{
+ int i, r;
+
+ if (!opp_def || !opp_def_size) {
+ pr_err("%s: invalid params!\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Initialize only if not already initialized even if the previous
+ * call failed, because, no reason we'd succeed again.
+ */
+ if (omap_table_init)
+ return -EEXIST;
+ omap_table_init = 1;
+
+ /* Lets now register with OPP library */
+ for (i = 0; i < opp_def_size; i++) {
+ struct omap_hwmod *oh;
+ struct device *dev;
+
+ if (!opp_def->hwmod_name) {
+ pr_err("%s: NULL name of omap_hwmod, failing [%d].\n",
+ __func__, i);
+ return -EINVAL;
+ }
+ oh = omap_hwmod_lookup(opp_def->hwmod_name);
+ if (!oh || !oh->od) {
+ pr_warn("%s: no hwmod or odev for %s, [%d] "
+ "cannot add OPPs.\n", __func__,
+ opp_def->hwmod_name, i);
+ return -EINVAL;
+ }
+ dev = &oh->od->pdev.dev;
+
+ r = opp_add(dev, opp_def->freq, opp_def->u_volt);
+ if (r) {
+ dev_err(dev, "%s: add OPP %ld failed for %s [%d] "
+ "result=%d\n",
+ __func__, opp_def->freq,
+ opp_def->hwmod_name, i, r);
+ } else {
+ if (!opp_def->default_available)
+ r = opp_disable(dev, opp_def->freq);
+ if (r)
+ dev_err(dev, "%s: disable %ld failed for %s "
+ "[%d] result=%d\n",
+ __func__, opp_def->freq,
+ opp_def->hwmod_name, i, r);
+ }
+ opp_def++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
new file mode 100644
index 000000000000..0486fce8a92c
--- /dev/null
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -0,0 +1,107 @@
+/*
+ * OMAP3 OPP table definitions.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+
+#include <plat/cpu.h>
+
+#include "omap_opp_data.h"
+
+static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
+ /* MPU OPP1 */
+ OPP_INITIALIZER("mpu", true, 125000000, 975000),
+ /* MPU OPP2 */
+ OPP_INITIALIZER("mpu", true, 250000000, 1075000),
+ /* MPU OPP3 */
+ OPP_INITIALIZER("mpu", true, 500000000, 1200000),
+ /* MPU OPP4 */
+ OPP_INITIALIZER("mpu", true, 550000000, 1270000),
+ /* MPU OPP5 */
+ OPP_INITIALIZER("mpu", true, 600000000, 1350000),
+
+ /*
+ * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
+ * almost the same than the one at 83MHz thus providing very little
+ * gain for the power point of view. In term of energy it will even
+ * increase the consumption due to the very negative performance
+ * impact that frequency will do to the MPU and the whole system in
+ * general.
+ */
+ OPP_INITIALIZER("l3_main", false, 41500000, 975000),
+ /* L3 OPP2 */
+ OPP_INITIALIZER("l3_main", true, 83000000, 1050000),
+ /* L3 OPP3 */
+ OPP_INITIALIZER("l3_main", true, 166000000, 1150000),
+
+ /* DSP OPP1 */
+ OPP_INITIALIZER("iva", true, 90000000, 975000),
+ /* DSP OPP2 */
+ OPP_INITIALIZER("iva", true, 180000000, 1075000),
+ /* DSP OPP3 */
+ OPP_INITIALIZER("iva", true, 360000000, 1200000),
+ /* DSP OPP4 */
+ OPP_INITIALIZER("iva", true, 400000000, 1270000),
+ /* DSP OPP5 */
+ OPP_INITIALIZER("iva", true, 430000000, 1350000),
+};
+
+static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", true, 300000000, 1012500),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", true, 600000000, 1200000),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", false, 800000000, 1325000),
+ /* MPU OPP4 - OPP-SB */
+ OPP_INITIALIZER("mpu", false, 1000000000, 1375000),
+
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main", true, 100000000, 1000000),
+ /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
+ OPP_INITIALIZER("l3_main", true, 200000000, 1200000),
+
+ /* DSP OPP1 - OPP50 */
+ OPP_INITIALIZER("iva", true, 260000000, 1012500),
+ /* DSP OPP2 - OPP100 */
+ OPP_INITIALIZER("iva", true, 520000000, 1200000),
+ /* DSP OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("iva", false, 660000000, 1325000),
+ /* DSP OPP4 - OPP-SB */
+ OPP_INITIALIZER("iva", false, 800000000, 1375000),
+};
+
+/**
+ * omap3_opp_init() - initialize omap3 opp table
+ */
+static int __init omap3_opp_init(void)
+{
+ int r = -ENODEV;
+
+ if (!cpu_is_omap34xx())
+ return r;
+
+ if (cpu_is_omap3630())
+ r = omap_init_opp_table(omap36xx_opp_def_list,
+ ARRAY_SIZE(omap36xx_opp_def_list));
+ else
+ r = omap_init_opp_table(omap34xx_opp_def_list,
+ ARRAY_SIZE(omap34xx_opp_def_list));
+
+ return r;
+}
+device_initcall(omap3_opp_init);
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
new file mode 100644
index 000000000000..a11fa566d8ee
--- /dev/null
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -0,0 +1,57 @@
+/*
+ * OMAP4 OPP table definitions.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Thara Gopinath
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+
+#include <plat/cpu.h>
+
+#include "omap_opp_data.h"
+
+static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", true, 300000000, 1100000),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", true, 600000000, 1200000),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", false, 800000000, 1260000),
+ /* MPU OPP4 - OPP-SB */
+ OPP_INITIALIZER("mpu", false, 1008000000, 1350000),
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main_1", true, 100000000, 930000),
+ /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
+ OPP_INITIALIZER("l3_main_1", true, 200000000, 1100000),
+ /* TODO: add IVA, DSP, aess, fdif, gpu */
+};
+
+/**
+ * omap4_opp_init() - initialize omap4 opp table
+ */
+static int __init omap4_opp_init(void)
+{
+ int r = -ENODEV;
+
+ if (!cpu_is_omap44xx())
+ return r;
+
+ r = omap_init_opp_table(omap44xx_opp_def_list,
+ ARRAY_SIZE(omap44xx_opp_def_list));
+
+ return r;
+}
+device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 5e81517a7af2..125f56591fb5 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -29,12 +29,13 @@
#include <plat/clock.h>
#include <plat/board.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
#include <plat/dmtimer.h>
+#include <plat/omap-pm.h>
-#include "prm.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
#include "pm.h"
int omap2_pm_debug;
@@ -45,10 +46,10 @@ u32 wakeup_timer_milliseconds;
#define DUMP_PRM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
- regs[reg_count++].val = prm_read_mod_reg(mod, reg)
+ regs[reg_count++].val = omap2_prm_read_mod_reg(mod, reg)
#define DUMP_CM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
- regs[reg_count++].val = cm_read_mod_reg(mod, reg)
+ regs[reg_count++].val = omap2_cm_read_mod_reg(mod, reg)
#define DUMP_PRM_REG(reg) \
regs[reg_count].name = #reg; \
regs[reg_count++].val = __raw_readl(reg)
@@ -161,6 +162,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
}
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+ u32 tick_rate, cycles;
+
+ if (!seconds && !milliseconds)
+ return;
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+ cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+ omap_dm_timer_stop(gptimer_wakeup);
+ omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+ pr_info("PM: Resume timer in %u.%03u secs"
+ " (%d ticks at %d ticks/sec.)\n",
+ seconds, milliseconds, cycles, tick_rate);
+}
+
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -311,10 +329,10 @@ static void pm_dbg_regset_store(u32 *ptr)
for (j = pm_dbg_reg_modules[i].low;
j <= pm_dbg_reg_modules[i].high; j += 4) {
if (pm_dbg_reg_modules[i].type == MOD_CM)
- val = cm_read_mod_reg(
+ val = omap2_cm_read_mod_reg(
pm_dbg_reg_modules[i].offset, j);
else
- val = prm_read_mod_reg(
+ val = omap2_prm_read_mod_reg(
pm_dbg_reg_modules[i].offset, j);
*(ptr++) = val;
}
@@ -354,23 +372,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
pwrdm->timer = t;
}
-void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
- u32 tick_rate, cycles;
-
- if (!seconds && !milliseconds)
- return;
-
- tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
- cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
- omap_dm_timer_stop(gptimer_wakeup);
- omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
- pr_info("PM: Resume timer in %u.%03u secs"
- " (%d ticks at %d ticks/sec.)\n",
- seconds, milliseconds, cycles, tick_rate);
-}
-
static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
@@ -581,6 +582,10 @@ static int option_set(void *data, u64 val)
*option = val;
if (option == &enable_off_mode) {
+ if (val)
+ omap_pm_enable_off_mode();
+ else
+ omap_pm_disable_off_mode();
if (cpu_is_omap34xx())
omap3_pm_off_mode_enable(val);
}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 59ca03b0e691..d5a102c71989 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -13,13 +13,16 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/err.h>
+#include <linux/opp.h>
#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#include <plat/common.h>
+#include <plat/voltage.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "pm.h"
static struct omap_device_pm_latency *pm_lats;
@@ -89,10 +92,13 @@ static void omap2_init_processor_devices(void)
}
}
+/* Types of sleep_switch used in omap_set_pwrdm_state */
+#define FORCEWAKEUP_SWITCH 0
+#define LOWPOWERSTATE_SWITCH 1
+
/*
* This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported. Function is assuming that clkdm doesn't have
- * hw_sup mode enabled.
+ * RET are supported.
*/
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
{
@@ -114,9 +120,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
return ret;
if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
- omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = 1;
- pwrdm_wait_transition(pwrdm);
+ if ((pwrdm_read_pwrst(pwrdm) > state) &&
+ (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+ sleep_switch = LOWPOWERSTATE_SWITCH;
+ } else {
+ omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ sleep_switch = FORCEWAKEUP_SWITCH;
+ }
}
ret = pwrdm_set_next_pwrst(pwrdm, state);
@@ -126,16 +137,106 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
goto err;
}
- if (sleep_switch) {
- omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- pwrdm_wait_transition(pwrdm);
- pwrdm_state_switch(pwrdm);
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+ if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
+ omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+ break;
+ case LOWPOWERSTATE_SWITCH:
+ pwrdm_set_lowpwrstchange(pwrdm);
+ break;
+ default:
+ return ret;
}
+ pwrdm_wait_transition(pwrdm);
+ pwrdm_state_switch(pwrdm);
err:
return ret;
}
+/*
+ * This API is to be called during init to put the various voltage
+ * domains to the voltage as per the opp table. Typically we boot up
+ * at the nominal voltage. So this function finds out the rate of
+ * the clock associated with the voltage domain, finds out the correct
+ * opp entry and puts the voltage domain to the voltage specifies
+ * in the opp entry
+ */
+static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
+ struct device *dev)
+{
+ struct voltagedomain *voltdm;
+ struct clk *clk;
+ struct opp *opp;
+ unsigned long freq, bootup_volt;
+
+ if (!vdd_name || !clk_name || !dev) {
+ printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
+ goto exit;
+ }
+
+ voltdm = omap_voltage_domain_lookup(vdd_name);
+ if (IS_ERR(voltdm)) {
+ printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ clk = clk_get(NULL, clk_name);
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "%s: unable to get clk %s\n",
+ __func__, clk_name);
+ goto exit;
+ }
+
+ freq = clk->rate;
+ clk_put(clk);
+
+ opp = opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp)) {
+ printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ bootup_volt = opp_get_voltage(opp);
+ if (!bootup_volt) {
+ printk(KERN_ERR "%s: unable to find voltage corresponding"
+ "to the bootup OPP for vdd_%s\n", __func__, vdd_name);
+ goto exit;
+ }
+
+ omap_voltage_scale_vdd(voltdm, bootup_volt);
+ return 0;
+
+exit:
+ printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n",
+ __func__, vdd_name);
+ return -EINVAL;
+}
+
+static void __init omap3_init_voltages(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev);
+ omap2_set_init_voltage("core", "l3_ick", l3_dev);
+}
+
+static void __init omap4_init_voltages(void)
+{
+ if (!cpu_is_omap44xx())
+ return;
+
+ omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
+ omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
+ omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
+}
+
static int __init omap2_common_pm_init(void)
{
omap2_init_processor_devices();
@@ -143,5 +244,24 @@ static int __init omap2_common_pm_init(void)
return 0;
}
-device_initcall(omap2_common_pm_init);
+postcore_initcall(omap2_common_pm_init);
+
+static int __init omap2_common_pm_late_init(void)
+{
+ /* Init the OMAP TWL parameters */
+ omap3_twl_init();
+ omap4_twl_init();
+
+ /* Init the voltage layer */
+ omap_voltage_late_init();
+ /* Initialize the voltages */
+ omap3_init_voltages();
+ omap4_init_voltages();
+
+ /* Smartreflex device init */
+ omap_devinit_smartreflex();
+
+ return 0;
+}
+late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 0d75bfd1fdbe..1c1b0ab5b978 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -11,7 +11,9 @@
#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
#define __ARCH_ARM_MACH_OMAP2_PM_H
-#include <plat/powerdomain.h>
+#include <linux/err.h>
+
+#include "powerdomain.h"
extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
@@ -20,6 +22,20 @@ extern int omap3_can_sleep(void);
extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_idle_init(void);
+#if defined(CONFIG_PM_OPP)
+extern int omap3_opp_init(void);
+extern int omap4_opp_init(void);
+#else
+static inline int omap3_opp_init(void)
+{
+ return -EINVAL;
+}
+static inline int omap4_opp_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
struct cpuidle_params {
u8 valid;
u32 sleep_latency;
@@ -58,7 +74,7 @@ extern u32 sleep_while_idle;
#endif
#if defined(CONFIG_CPU_IDLE)
-extern void omap3_cpuidle_update_states(void);
+extern void omap3_cpuidle_update_states(u32, u32);
#endif
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
@@ -80,9 +96,46 @@ extern void save_secure_ram_context(u32 *addr);
extern void omap3_save_scratchpad_contents(void);
extern unsigned int omap24xx_idle_loop_suspend_sz;
-extern unsigned int omap34xx_suspend_sz;
extern unsigned int save_secure_ram_context_sz;
extern unsigned int omap24xx_cpu_suspend_sz;
extern unsigned int omap34xx_cpu_suspend_sz;
+#define PM_RTA_ERRATUM_i608 (1 << 0)
+#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1)
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+extern u16 pm34xx_errata;
+#define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id))
+extern void enable_omap3630_toggle_l2_on_restore(void);
+#else
+#define IS_PM34XX_ERRATUM(id) 0
+static inline void enable_omap3630_toggle_l2_on_restore(void) { }
+#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+extern int omap_devinit_smartreflex(void);
+extern void omap_enable_smartreflex_on_init(void);
+#else
+static inline int omap_devinit_smartreflex(void)
+{
+ return -EINVAL;
+}
+
+static inline void omap_enable_smartreflex_on_init(void) {}
+#endif
+
+#ifdef CONFIG_TWL4030_CORE
+extern int omap3_twl_init(void);
+extern int omap4_twl_init(void);
+#else
+static inline int omap3_twl_init(void)
+{
+ return -EINVAL;
+}
+static inline int omap4_twl_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index c85923e56b85..dac2d1d9987d 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -42,16 +42,29 @@
#include <plat/dma.h>
#include <plat/board.h>
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
#include "sdrc.h"
#include "pm.h"
#include "control.h"
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
+
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
static void (*omap2_sram_idle)(void);
static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
@@ -66,8 +79,8 @@ static int omap2_fclks_active(void)
{
u32 f1, f2;
- f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
- f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
/* Ignore UART clocks. These are handled by UART core (serial.c) */
f1 &= ~(OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_UART2_MASK);
@@ -92,9 +105,9 @@ static void omap2_enter_full_retention(void)
/* Clear old wake-up events */
/* REVISIT: These write to reserved bits? */
- prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
- prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
- prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
/*
* Set MPU powerdomain's next power state to RETENTION;
@@ -107,7 +120,7 @@ static void omap2_enter_full_retention(void)
l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
- omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);
+ omap2_gpio_prepare_for_idle(0);
if (omap2_pm_debug) {
omap2_pm_dump(0, 0, 0);
@@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void)
goto no_sleep;
/* Block console output in case it is on one of the OMAP UARTs */
- if (try_acquire_console_sem())
- goto no_sleep;
+ if (!is_suspending())
+ if (try_acquire_console_sem())
+ goto no_sleep;
omap_uart_prepare_idle(0);
omap_uart_prepare_idle(1);
@@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void)
omap_uart_resume_idle(1);
omap_uart_resume_idle(0);
- release_console_sem();
+ if (!is_suspending())
+ release_console_sem();
no_sleep:
if (omap2_pm_debug) {
@@ -152,30 +167,30 @@ no_sleep:
clk_enable(osc_ck);
/* clear CORE wake-up events */
- prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
- prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
/* wakeup domain events - bit 1: GPT1, bit5 GPIO */
- prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);
+ omap2_prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);
/* MPU domain wake events */
- l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+ l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
if (l & 0x01)
- prm_write_mod_reg(0x01, OCP_MOD,
+ omap2_prm_write_mod_reg(0x01, OCP_MOD,
OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
if (l & 0x20)
- prm_write_mod_reg(0x20, OCP_MOD,
+ omap2_prm_write_mod_reg(0x20, OCP_MOD,
OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
/* Mask future PRCM-to-MPU interrupts */
- prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+ omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
}
static int omap2_i2c_active(void)
{
u32 l;
- l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK);
}
@@ -186,13 +201,13 @@ static int omap2_allow_mpu_retention(void)
u32 l;
/* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
- l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
return 0;
/* Check for UART3. */
- l = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
if (l & OMAP24XX_EN_UART3_MASK)
return 0;
if (sti_console_enabled)
@@ -215,18 +230,18 @@ static void omap2_enter_mpu_retention(void)
* it is in retention mode. */
if (omap2_allow_mpu_retention()) {
/* REVISIT: These write to reserved bits? */
- prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
- prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
- prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
/* Try to enter MPU retention */
- prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
+ omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
OMAP_LOGICRETSTATE_MASK,
MPU_MOD, OMAP2_PM_PWSTCTRL);
} else {
/* Block MPU retention */
- prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD,
+ omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD,
OMAP2_PM_PWSTCTRL);
only_idle = 1;
}
@@ -284,10 +299,11 @@ out:
local_irq_enable();
}
-static int omap2_pm_prepare(void)
+#ifdef CONFIG_SUSPEND
+static int omap2_pm_begin(suspend_state_t state)
{
- /* We cannot sleep in idle until we have resumed */
disable_hlt();
+ suspend_state = state;
return 0;
}
@@ -295,9 +311,9 @@ static int omap2_pm_suspend(void)
{
u32 wken_wkup, mir1;
- wken_wkup = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+ wken_wkup = omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
wken_wkup &= ~OMAP24XX_EN_GPT1_MASK;
- prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
+ omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
/* Mask GPT1 */
mir1 = omap_readl(0x480fe0a4);
@@ -307,7 +323,7 @@ static int omap2_pm_suspend(void)
omap2_enter_full_retention();
omap_writel(mir1, 0x480fe0a4);
- prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
+ omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
return 0;
}
@@ -328,17 +344,21 @@ static int omap2_pm_enter(suspend_state_t state)
return ret;
}
-static void omap2_pm_finish(void)
+static void omap2_pm_end(void)
{
+ suspend_state = PM_SUSPEND_ON;
enable_hlt();
}
static struct platform_suspend_ops omap_pm_ops = {
- .prepare = omap2_pm_prepare,
+ .begin = omap2_pm_begin,
.enter = omap2_pm_enter,
- .finish = omap2_pm_finish,
+ .end = omap2_pm_end,
.valid = suspend_valid_only_mem,
};
+#else
+static const struct platform_suspend_ops __initdata omap_pm_ops;
+#endif /* CONFIG_SUSPEND */
/* XXX This function should be shareable between OMAP2xxx and OMAP3 */
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
@@ -360,7 +380,7 @@ static void __init prcm_setup_regs(void)
struct powerdomain *pwrdm;
/* Enable autoidle */
- prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
+ omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
OMAP2_PRCM_SYSCONFIG_OFFSET);
/*
@@ -399,87 +419,87 @@ static void __init prcm_setup_regs(void)
clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
/* Enable clock autoidle for all domains */
- cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK |
- OMAP24XX_AUTO_MAILBOXES_MASK |
- OMAP24XX_AUTO_WDT4_MASK |
- OMAP2420_AUTO_WDT3_MASK |
- OMAP24XX_AUTO_MSPRO_MASK |
- OMAP2420_AUTO_MMC_MASK |
- OMAP24XX_AUTO_FAC_MASK |
- OMAP2420_AUTO_EAC_MASK |
- OMAP24XX_AUTO_HDQ_MASK |
- OMAP24XX_AUTO_UART2_MASK |
- OMAP24XX_AUTO_UART1_MASK |
- OMAP24XX_AUTO_I2C2_MASK |
- OMAP24XX_AUTO_I2C1_MASK |
- OMAP24XX_AUTO_MCSPI2_MASK |
- OMAP24XX_AUTO_MCSPI1_MASK |
- OMAP24XX_AUTO_MCBSP2_MASK |
- OMAP24XX_AUTO_MCBSP1_MASK |
- OMAP24XX_AUTO_GPT12_MASK |
- OMAP24XX_AUTO_GPT11_MASK |
- OMAP24XX_AUTO_GPT10_MASK |
- OMAP24XX_AUTO_GPT9_MASK |
- OMAP24XX_AUTO_GPT8_MASK |
- OMAP24XX_AUTO_GPT7_MASK |
- OMAP24XX_AUTO_GPT6_MASK |
- OMAP24XX_AUTO_GPT5_MASK |
- OMAP24XX_AUTO_GPT4_MASK |
- OMAP24XX_AUTO_GPT3_MASK |
- OMAP24XX_AUTO_GPT2_MASK |
- OMAP2420_AUTO_VLYNQ_MASK |
- OMAP24XX_AUTO_DSS_MASK,
- CORE_MOD, CM_AUTOIDLE1);
- cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK |
- OMAP24XX_AUTO_SSI_MASK |
- OMAP24XX_AUTO_USB_MASK,
- CORE_MOD, CM_AUTOIDLE2);
- cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK |
- OMAP24XX_AUTO_GPMC_MASK |
- OMAP24XX_AUTO_SDMA_MASK,
- CORE_MOD, CM_AUTOIDLE3);
- cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK |
- OMAP24XX_AUTO_AES_MASK |
- OMAP24XX_AUTO_RNG_MASK |
- OMAP24XX_AUTO_SHA_MASK |
- OMAP24XX_AUTO_DES_MASK,
- CORE_MOD, OMAP24XX_CM_AUTOIDLE4);
-
- cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
- CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK |
+ OMAP24XX_AUTO_MAILBOXES_MASK |
+ OMAP24XX_AUTO_WDT4_MASK |
+ OMAP2420_AUTO_WDT3_MASK |
+ OMAP24XX_AUTO_MSPRO_MASK |
+ OMAP2420_AUTO_MMC_MASK |
+ OMAP24XX_AUTO_FAC_MASK |
+ OMAP2420_AUTO_EAC_MASK |
+ OMAP24XX_AUTO_HDQ_MASK |
+ OMAP24XX_AUTO_UART2_MASK |
+ OMAP24XX_AUTO_UART1_MASK |
+ OMAP24XX_AUTO_I2C2_MASK |
+ OMAP24XX_AUTO_I2C1_MASK |
+ OMAP24XX_AUTO_MCSPI2_MASK |
+ OMAP24XX_AUTO_MCSPI1_MASK |
+ OMAP24XX_AUTO_MCBSP2_MASK |
+ OMAP24XX_AUTO_MCBSP1_MASK |
+ OMAP24XX_AUTO_GPT12_MASK |
+ OMAP24XX_AUTO_GPT11_MASK |
+ OMAP24XX_AUTO_GPT10_MASK |
+ OMAP24XX_AUTO_GPT9_MASK |
+ OMAP24XX_AUTO_GPT8_MASK |
+ OMAP24XX_AUTO_GPT7_MASK |
+ OMAP24XX_AUTO_GPT6_MASK |
+ OMAP24XX_AUTO_GPT5_MASK |
+ OMAP24XX_AUTO_GPT4_MASK |
+ OMAP24XX_AUTO_GPT3_MASK |
+ OMAP24XX_AUTO_GPT2_MASK |
+ OMAP2420_AUTO_VLYNQ_MASK |
+ OMAP24XX_AUTO_DSS_MASK,
+ CORE_MOD, CM_AUTOIDLE1);
+ omap2_cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK |
+ OMAP24XX_AUTO_SSI_MASK |
+ OMAP24XX_AUTO_USB_MASK,
+ CORE_MOD, CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK |
+ OMAP24XX_AUTO_GPMC_MASK |
+ OMAP24XX_AUTO_SDMA_MASK,
+ CORE_MOD, CM_AUTOIDLE3);
+ omap2_cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK |
+ OMAP24XX_AUTO_AES_MASK |
+ OMAP24XX_AUTO_RNG_MASK |
+ OMAP24XX_AUTO_SHA_MASK |
+ OMAP24XX_AUTO_DES_MASK,
+ CORE_MOD, OMAP24XX_CM_AUTOIDLE4);
+
+ omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
+ CM_AUTOIDLE);
/* Put DPLL and both APLLs into autoidle mode */
- cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
- (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
- (0x03 << OMAP24XX_AUTO_54M_SHIFT),
- PLL_MOD, CM_AUTOIDLE);
-
- cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
- OMAP24XX_AUTO_WDT1_MASK |
- OMAP24XX_AUTO_MPU_WDT_MASK |
- OMAP24XX_AUTO_GPIOS_MASK |
- OMAP24XX_AUTO_32KSYNC_MASK |
- OMAP24XX_AUTO_GPT1_MASK,
- WKUP_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
+ (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
+ (0x03 << OMAP24XX_AUTO_54M_SHIFT),
+ PLL_MOD, CM_AUTOIDLE);
+
+ omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
+ OMAP24XX_AUTO_WDT1_MASK |
+ OMAP24XX_AUTO_MPU_WDT_MASK |
+ OMAP24XX_AUTO_GPIOS_MASK |
+ OMAP24XX_AUTO_32KSYNC_MASK |
+ OMAP24XX_AUTO_GPT1_MASK,
+ WKUP_MOD, CM_AUTOIDLE);
/* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
* stabilisation */
- prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
- OMAP2_PRCM_CLKSSETUP_OFFSET);
+ omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP2_PRCM_CLKSSETUP_OFFSET);
/* Configure automatic voltage transition */
- prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
- OMAP2_PRCM_VOLTSETUP_OFFSET);
- prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK |
- (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
- OMAP24XX_MEMRETCTRL_MASK |
- (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
- (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
- OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET);
+ omap2_prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP2_PRCM_VOLTSETUP_OFFSET);
+ omap2_prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK |
+ (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
+ OMAP24XX_MEMRETCTRL_MASK |
+ (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
+ (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
+ OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET);
/* Enable wake-up events */
- prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK,
- WKUP_MOD, PM_WKEN);
+ omap2_prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK,
+ WKUP_MOD, PM_WKEN);
}
static int __init omap2_pm_init(void)
@@ -490,7 +510,7 @@ static int __init omap2_pm_init(void)
return -ENODEV;
printk(KERN_INFO "Power Management for OMAP2 initializing\n");
- l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
+ l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
/* Look up important powerdomains */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ec8a04b7473..5b323f28da2d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -31,8 +31,8 @@
#include <linux/console.h>
#include <plat/sram.h>
-#include <plat/clockdomain.h>
-#include <plat/powerdomain.h>
+#include "clockdomain.h"
+#include "powerdomain.h"
#include <plat/serial.h>
#include <plat/sdrc.h>
#include <plat/prcm.h>
@@ -41,20 +41,36 @@
#include <asm/tlbflush.h>
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
#include "prm-regbits-34xx.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "pm.h"
#include "sdrc.h"
#include "control.h"
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
+
/* Scratchpad offsets */
#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8
+/* pm34xx errata defined in pm.h */
+u16 pm34xx_errata;
+
struct power_state {
struct powerdomain *pwrdm;
u32 next_state;
@@ -89,12 +105,12 @@ static void omap3_enable_io_chain(void)
int timeout = 0;
if (omap_rev() >= OMAP3430_REV_ES3_1) {
- prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
PM_WKEN);
/* Do a readback to assure write has been done */
- prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
- while (!(prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+ while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
OMAP3430_ST_IO_CHAIN_MASK)) {
timeout++;
if (timeout > 1000) {
@@ -102,7 +118,7 @@ static void omap3_enable_io_chain(void)
"activation failed.\n");
return;
}
- prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
WKUP_MOD, PM_WKEN);
}
}
@@ -111,26 +127,17 @@ static void omap3_enable_io_chain(void)
static void omap3_disable_io_chain(void)
{
if (omap_rev() >= OMAP3430_REV_ES3_1)
- prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
PM_WKEN);
}
static void omap3_core_save_context(void)
{
- u32 control_padconf_off;
-
- /* Save the padconf registers */
- control_padconf_off = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
- control_padconf_off |= START_PADCONF_SAVE;
- omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF);
- /* wait for the save to complete */
- while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
- & PADCONF_SAVE_DONE))
- udelay(1);
+ omap3_ctrl_save_padconf();
/*
* Force write last pad into memory, as this can fail in some
- * cases according to erratas 1.157, 1.185
+ * cases according to errata 1.157, 1.185
*/
omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
@@ -205,27 +212,27 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
int c = 0;
- wkst = prm_read_mod_reg(module, wkst_off);
- wkst &= prm_read_mod_reg(module, grpsel_off);
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
+ wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
if (wkst) {
- iclk = cm_read_mod_reg(module, iclk_off);
- fclk = cm_read_mod_reg(module, fclk_off);
+ iclk = omap2_cm_read_mod_reg(module, iclk_off);
+ fclk = omap2_cm_read_mod_reg(module, fclk_off);
while (wkst) {
clken = wkst;
- cm_set_mod_reg_bits(clken, module, iclk_off);
+ omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
/*
* For USBHOST, we don't know whether HOST1 or
* HOST2 woke us up, so enable both f-clocks
*/
if (module == OMAP3430ES2_USBHOST_MOD)
clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
- cm_set_mod_reg_bits(clken, module, fclk_off);
- prm_write_mod_reg(wkst, module, wkst_off);
- wkst = prm_read_mod_reg(module, wkst_off);
+ omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
+ omap2_prm_write_mod_reg(wkst, module, wkst_off);
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
c++;
}
- cm_write_mod_reg(iclk, module, iclk_off);
- cm_write_mod_reg(fclk, module, fclk_off);
+ omap2_cm_write_mod_reg(iclk, module, iclk_off);
+ omap2_cm_write_mod_reg(fclk, module, fclk_off);
}
return c;
@@ -268,9 +275,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
u32 irqenable_mpu, irqstatus_mpu;
int c = 0;
- irqenable_mpu = prm_read_mod_reg(OCP_MOD,
+ irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
OMAP3_PRM_IRQENABLE_MPU_OFFSET);
- irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
+ irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
irqstatus_mpu &= irqenable_mpu;
@@ -291,10 +298,10 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
"no code to handle it (%08x)\n", irqstatus_mpu);
}
- prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
+ omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
- irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
+ irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
irqstatus_mpu &= irqenable_mpu;
@@ -344,6 +351,7 @@ void omap_sram_idle(void)
int mpu_next_state = PWRDM_POWER_ON;
int per_next_state = PWRDM_POWER_ON;
int core_next_state = PWRDM_POWER_ON;
+ int per_going_off;
int core_prev_state, per_prev_state;
u32 sdrc_pwr = 0;
@@ -382,21 +390,23 @@ void omap_sram_idle(void)
if (omap3_has_io_wakeup() &&
(per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)) {
- prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
/* Block console output in case it is on one of the OMAP UARTs */
- if (per_next_state < PWRDM_POWER_ON ||
- core_next_state < PWRDM_POWER_ON)
- if (try_acquire_console_sem())
- goto console_still_active;
+ if (!is_suspending())
+ if (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)
+ if (try_acquire_console_sem())
+ goto console_still_active;
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
+ per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
omap_uart_prepare_idle(2);
omap_uart_prepare_idle(3);
- omap2_gpio_prepare_for_idle(per_next_state);
+ omap2_gpio_prepare_for_idle(per_going_off);
if (per_next_state == PWRDM_POWER_OFF)
omap3_per_save_context();
}
@@ -407,7 +417,7 @@ void omap_sram_idle(void)
omap_uart_prepare_idle(1);
if (core_next_state == PWRDM_POWER_OFF) {
omap3_core_save_context();
- omap3_prcm_save_context();
+ omap3_cm_save_context();
}
}
@@ -416,7 +426,7 @@ void omap_sram_idle(void)
/*
* On EMU/HS devices ROM code restores a SRDC value
* from scratchpad which has automatic self refresh on timeout
- * of AUTO_CNT = 1 enabled. This takes care of errata 1.142.
+ * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
* Hence store/restore the SDRC_POWER register here.
*/
if (omap_rev() >= OMAP3430_REV_ES3_0 &&
@@ -447,14 +457,14 @@ void omap_sram_idle(void)
core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
if (core_prev_state == PWRDM_POWER_OFF) {
omap3_core_restore_context();
- omap3_prcm_restore_context();
+ omap3_cm_restore_context();
omap3_sram_restore_context();
omap2_sms_restore_context();
}
omap_uart_resume_idle(0);
omap_uart_resume_idle(1);
if (core_next_state == PWRDM_POWER_OFF)
- prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
+ omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
OMAP3430_GR_MOD,
OMAP3_PRM_VOLTCTRL_OFFSET);
}
@@ -470,14 +480,16 @@ void omap_sram_idle(void)
omap_uart_resume_idle(3);
}
- release_console_sem();
+ if (!is_suspending())
+ release_console_sem();
console_still_active:
/* Disable IO-PAD and IO-CHAIN wakeup */
if (omap3_has_io_wakeup() &&
(per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)) {
- prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
omap3_disable_io_chain();
}
@@ -514,14 +526,6 @@ out:
}
#ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state;
-
-static int omap3_pm_prepare(void)
-{
- disable_hlt();
- return 0;
-}
-
static int omap3_pm_suspend(void)
{
struct power_state *pwrst;
@@ -584,14 +588,10 @@ static int omap3_pm_enter(suspend_state_t unused)
return ret;
}
-static void omap3_pm_finish(void)
-{
- enable_hlt();
-}
-
/* Hooks to enable / disable UART interrupts during suspend */
static int omap3_pm_begin(suspend_state_t state)
{
+ disable_hlt();
suspend_state = state;
omap_uart_enable_irqs(0);
return 0;
@@ -601,15 +601,14 @@ static void omap3_pm_end(void)
{
suspend_state = PM_SUSPEND_ON;
omap_uart_enable_irqs(1);
+ enable_hlt();
return;
}
static struct platform_suspend_ops omap_pm_ops = {
.begin = omap3_pm_begin,
.end = omap3_pm_end,
- .prepare = omap3_pm_prepare,
.enter = omap3_pm_enter,
- .finish = omap3_pm_finish,
.valid = suspend_valid_only_mem,
};
#endif /* CONFIG_SUSPEND */
@@ -628,21 +627,21 @@ static struct platform_suspend_ops omap_pm_ops = {
static void __init omap3_iva_idle(void)
{
/* ensure IVA2 clock is disabled */
- cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
/* if no clock activity, nothing else to do */
- if (!(cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
+ if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
OMAP3430_CLKACTIVITY_IVA2_MASK))
return;
/* Reset IVA2 */
- prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
+ omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
OMAP3430_RST2_IVA2_MASK |
OMAP3430_RST3_IVA2_MASK,
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
/* Enable IVA2 clock */
- cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
+ omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
OMAP3430_IVA2_MOD, CM_FCLKEN);
/* Set IVA2 boot mode to 'idle' */
@@ -650,13 +649,13 @@ static void __init omap3_iva_idle(void)
OMAP343X_CONTROL_IVA2_BOOTMOD);
/* Un-reset IVA2 */
- prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+ omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
/* Disable IVA2 clock */
- cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
/* Reset IVA2 */
- prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
+ omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
OMAP3430_RST2_IVA2_MASK |
OMAP3430_RST3_IVA2_MASK,
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
@@ -680,10 +679,10 @@ static void __init omap3_d2d_idle(void)
omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
/* reset modem */
- prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
+ omap2_prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK,
CORE_MOD, OMAP2_RM_RSTCTRL);
- prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
}
static void __init prcm_setup_regs(void)
@@ -698,23 +697,23 @@ static void __init prcm_setup_regs(void)
/* XXX Reset all wkdeps. This should be done when initializing
* powerdomains */
- prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
- prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
- prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
- prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
- prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
- prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
if (omap_rev() > OMAP3430_REV_ES1_0) {
- prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
- prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
} else
- prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
+ omap2_prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
/*
* Enable interface clock autoidle for all modules.
* Note that in the long run this should be done by clockfw
*/
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_MODEM_MASK |
OMAP3430ES2_AUTO_MMC3_MASK |
OMAP3430ES2_AUTO_ICR_MASK |
@@ -747,7 +746,7 @@ static void __init prcm_setup_regs(void)
OMAP3430_AUTO_SSI_MASK,
CORE_MOD, CM_AUTOIDLE1);
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_PKA_MASK |
OMAP3430_AUTO_AES1_MASK |
OMAP3430_AUTO_RNG_MASK |
@@ -756,13 +755,13 @@ static void __init prcm_setup_regs(void)
CORE_MOD, CM_AUTOIDLE2);
if (omap_rev() > OMAP3430_REV_ES1_0) {
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_MAD2D_MASK |
OMAP3430ES2_AUTO_USBTLL_MASK,
CORE_MOD, CM_AUTOIDLE3);
}
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_WDT2_MASK |
OMAP3430_AUTO_WDT1_MASK |
OMAP3430_AUTO_GPIO1_MASK |
@@ -771,17 +770,17 @@ static void __init prcm_setup_regs(void)
OMAP3430_AUTO_GPT1_MASK,
WKUP_MOD, CM_AUTOIDLE);
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_DSS_MASK,
OMAP3430_DSS_MOD,
CM_AUTOIDLE);
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430_AUTO_CAM_MASK,
OMAP3430_CAM_MOD,
CM_AUTOIDLE);
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
omap3630_auto_uart4_mask |
OMAP3430_AUTO_GPIO6_MASK |
OMAP3430_AUTO_GPIO5_MASK |
@@ -805,7 +804,7 @@ static void __init prcm_setup_regs(void)
CM_AUTOIDLE);
if (omap_rev() > OMAP3430_REV_ES1_0) {
- cm_write_mod_reg(
+ omap2_cm_write_mod_reg(
OMAP3430ES2_AUTO_USBHOST_MASK,
OMAP3430ES2_USBHOST_MOD,
CM_AUTOIDLE);
@@ -817,16 +816,16 @@ static void __init prcm_setup_regs(void)
* Set all plls to autoidle. This is needed until autoidle is
* enabled by clockfw
*/
- cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
+ omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
- cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
+ omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
MPU_MOD,
CM_AUTOIDLE2);
- cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
+ omap2_cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
(1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
PLL_MOD,
CM_AUTOIDLE);
- cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
+ omap2_cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
PLL_MOD,
CM_AUTOIDLE2);
@@ -835,31 +834,31 @@ static void __init prcm_setup_regs(void)
* sys_clkreq. In the long run clock framework should
* take care of this.
*/
- prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
+ omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
1 << OMAP_AUTOEXTCLKMODE_SHIFT,
OMAP3430_GR_MOD,
OMAP3_PRM_CLKSRC_CTRL_OFFSET);
/* setup wakup source */
- prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK |
+ omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK |
OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK,
WKUP_MOD, PM_WKEN);
/* No need to write EN_IO, that is always enabled */
- prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK |
+ omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK |
OMAP3430_GRPSEL_GPT1_MASK |
OMAP3430_GRPSEL_GPT12_MASK,
WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
/* For some reason IO doesn't generate wakeup event even if
* it is selected to mpu wakeup goup */
- prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
+ omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
/* Enable PM_WKEN to support DSS LPR */
- prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
+ omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
OMAP3430_DSS_MOD, PM_WKEN);
/* Enable wakeups in PER */
- prm_write_mod_reg(omap3630_en_uart4_mask |
+ omap2_prm_write_mod_reg(omap3630_en_uart4_mask |
OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK |
OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK |
@@ -867,7 +866,7 @@ static void __init prcm_setup_regs(void)
OMAP3430_EN_MCBSP4_MASK,
OMAP3430_PER_MOD, PM_WKEN);
/* and allow them to wake up MPU */
- prm_write_mod_reg(omap3630_grpsel_uart4_mask |
+ omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask |
OMAP3430_GRPSEL_GPIO2_MASK |
OMAP3430_GRPSEL_GPIO3_MASK |
OMAP3430_GRPSEL_GPIO4_MASK |
@@ -880,22 +879,22 @@ static void __init prcm_setup_regs(void)
OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
/* Don't attach IVA interrupts */
- prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
- prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
- prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
- prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+ omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+ omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
/* Clear any pending 'reset' flags */
- prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
- prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
/* Clear any pending PRCM interrupts */
- prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
omap3_iva_idle();
omap3_d2d_idle();
@@ -912,12 +911,29 @@ void omap3_pm_off_mode_enable(int enable)
state = PWRDM_POWER_RET;
#ifdef CONFIG_CPU_IDLE
- omap3_cpuidle_update_states();
+ /*
+ * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+ * enable OFF mode in a stable form for previous revisions, restrict
+ * instead to RET
+ */
+ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
+ omap3_cpuidle_update_states(state, PWRDM_POWER_RET);
+ else
+ omap3_cpuidle_update_states(state, state);
#endif
list_for_each_entry(pwrst, &pwrst_list, node) {
- pwrst->next_state = state;
- omap_set_pwrdm_state(pwrst->pwrdm, state);
+ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
+ pwrst->pwrdm == core_pwrdm &&
+ state == PWRDM_POWER_OFF) {
+ pwrst->next_state = PWRDM_POWER_RET;
+ WARN_ONCE(1,
+ "%s: Core OFF disabled due to errata i583\n",
+ __func__);
+ } else {
+ pwrst->next_state = state;
+ }
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
}
}
@@ -989,6 +1005,17 @@ void omap_push_sram_idle(void)
save_secure_ram_context_sz);
}
+static void __init pm_errata_configure(void)
+{
+ if (cpu_is_omap3630()) {
+ pm34xx_errata |= PM_RTA_ERRATUM_i608;
+ /* Enable the l2 cache toggling in sleep logic */
+ enable_omap3630_toggle_l2_on_restore();
+ if (omap_rev() < OMAP3630_REV_ES1_2)
+ pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583;
+ }
+}
+
static int __init omap3_pm_init(void)
{
struct power_state *pwrst, *tmp;
@@ -998,6 +1025,8 @@ static int __init omap3_pm_init(void)
if (!cpu_is_omap34xx())
return -ENODEV;
+ pm_errata_configure();
+
printk(KERN_ERR "Power Management for TI OMAP3.\n");
/* XXX prcm_setup_regs needs to be before enabling hw
@@ -1045,6 +1074,14 @@ static int __init omap3_pm_init(void)
pm_idle = omap3_pm_idle;
omap3_idle_init();
+ /*
+ * RTA is disabled during initialization as per erratum i608
+ * it is safer to disable RTA by the bootloader, but we would like
+ * to be doubly sure here and prevent any mishaps.
+ */
+ if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608))
+ omap3630_ctrl_disable_rta();
+
clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
omap3_secure_ram_storage =
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 54544b4fc76b..e9f4862c4de4 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -16,7 +16,7 @@
#include <linux/err.h>
#include <linux/slab.h>
-#include <plat/powerdomain.h>
+#include "powerdomain.h"
#include <mach/omap4-common.h>
struct power_state {
@@ -31,12 +31,6 @@ struct power_state {
static LIST_HEAD(pwrst_list);
#ifdef CONFIG_SUSPEND
-static int omap4_pm_prepare(void)
-{
- disable_hlt();
- return 0;
-}
-
static int omap4_pm_suspend(void)
{
do_wfi();
@@ -59,28 +53,22 @@ static int omap4_pm_enter(suspend_state_t suspend_state)
return ret;
}
-static void omap4_pm_finish(void)
-{
- enable_hlt();
- return;
-}
-
static int omap4_pm_begin(suspend_state_t state)
{
+ disable_hlt();
return 0;
}
static void omap4_pm_end(void)
{
+ enable_hlt();
return;
}
static struct platform_suspend_ops omap_pm_ops = {
.begin = omap4_pm_begin,
.end = omap4_pm_end,
- .prepare = omap4_pm_prepare,
.enter = omap4_pm_enter,
- .finish = omap4_pm_finish,
.valid = suspend_valid_only_mem,
};
#endif /* CONFIG_SUSPEND */
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
new file mode 100644
index 000000000000..171fccd208c7
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -0,0 +1,110 @@
+/*
+ * linux/arch/arm/mach-omap2/powerdomain-common.c
+ * Contains common powerdomain framework functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include "pm.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+
+/*
+ * OMAP3 and OMAP4 specific register bit initialisations
+ * Notice that the names here are not according to each power
+ * domain but the bit mapping used applies to all of them
+ */
+/* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */
+#define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK
+#define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK
+#define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK
+#define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK
+#define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK
+
+/* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */
+#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK
+#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK
+#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK
+#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK
+#define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK
+
+/* OMAP3 and OMAP4 Memory Status bits */
+#define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK
+#define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK
+#define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK
+#define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK
+#define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK
+
+/* Common Internal functions used across OMAP rev's*/
+u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_ONSTATE_MASK;
+ case 1:
+ return OMAP_MEM1_ONSTATE_MASK;
+ case 2:
+ return OMAP_MEM2_ONSTATE_MASK;
+ case 3:
+ return OMAP_MEM3_ONSTATE_MASK;
+ case 4:
+ return OMAP_MEM4_ONSTATE_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_RETSTATE_MASK;
+ case 1:
+ return OMAP_MEM1_RETSTATE_MASK;
+ case 2:
+ return OMAP_MEM2_RETSTATE_MASK;
+ case 3:
+ return OMAP_MEM3_RETSTATE_MASK;
+ case 4:
+ return OMAP_MEM4_RETSTATE_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_STATEST_MASK;
+ case 1:
+ return OMAP_MEM1_STATEST_MASK;
+ case 2:
+ return OMAP_MEM2_STATEST_MASK;
+ case 3:
+ return OMAP_MEM3_STATEST_MASK;
+ case 4:
+ return OMAP_MEM4_STATEST_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 6527ec30dc17..eaed0df16699 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -15,27 +15,19 @@
#undef DEBUG
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/atomic.h>
-
-#include "cm.h"
-#include "cm-regbits-34xx.h"
-#include "cm-regbits-44xx.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
-#include "prm-regbits-44xx.h"
+#include <linux/string.h>
+#include "cm2xxx_3xxx.h"
+#include "prcm44xx.h"
+#include "cm44xx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
#include <plat/cpu.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
#include <plat/prcm.h>
#include "pm.h"
@@ -45,41 +37,12 @@ enum {
PWRDM_STATE_PREV,
};
-/* Variable holding value of the CPU dependent PWRSTCTRL Register Offset */
-static u16 pwrstctrl_reg_offs;
-
-/* Variable holding value of the CPU dependent PWRSTST Register Offset */
-static u16 pwrstst_reg_offs;
-
-/* OMAP3 and OMAP4 specific register bit initialisations
- * Notice that the names here are not according to each power
- * domain but the bit mapping used applies to all of them
- */
-
-/* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */
-#define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK
-#define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK
-#define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK
-#define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK
-#define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK
-
-/* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */
-#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK
-#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK
-#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK
-#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK
-#define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK
-
-/* OMAP3 and OMAP4 Memory Status bits */
-#define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK
-#define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK
-#define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK
-#define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK
-#define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK
/* pwrdm_list contains all registered struct powerdomains */
static LIST_HEAD(pwrdm_list);
+static struct pwrdm_ops *arch_pwrdm;
+
/* Private functions */
static struct powerdomain *_pwrdm_lookup(const char *name)
@@ -110,12 +73,19 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
{
int i;
- if (!pwrdm)
+ if (!pwrdm || !pwrdm->name)
return -EINVAL;
if (!omap_chip_is(pwrdm->omap_chip))
return -EINVAL;
+ if (cpu_is_omap44xx() &&
+ pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
+ pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
+ pwrdm->name);
+ return -EINVAL;
+ }
+
if (_pwrdm_lookup(pwrdm->name))
return -EEXIST;
@@ -211,6 +181,7 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
/**
* pwrdm_init - set up the powerdomain layer
* @pwrdm_list: array of struct powerdomain pointers to register
+ * @custom_funcs: func pointers for arch specfic implementations
*
* Loop through the array of powerdomains @pwrdm_list, registering all
* that are available on the current CPU. If pwrdm_list is supplied
@@ -218,21 +189,14 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
* registered. No return value. XXX pwrdm_list is not really a
* "list"; it is an array. Rename appropriately.
*/
-void pwrdm_init(struct powerdomain **pwrdm_list)
+void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
{
struct powerdomain **p = NULL;
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
- pwrstst_reg_offs = OMAP2_PM_PWSTST;
- } else if (cpu_is_omap44xx()) {
- pwrstctrl_reg_offs = OMAP4_PM_PWSTCTRL;
- pwrstst_reg_offs = OMAP4_PM_PWSTST;
- } else {
- printk(KERN_ERR "Power Domain struct not supported for " \
- "this CPU\n");
- return;
- }
+ if (!custom_funcs)
+ WARN(1, "powerdomain: No custom pwrdm functions registered\n");
+ else
+ arch_pwrdm = custom_funcs;
if (pwrdm_list) {
for (p = pwrdm_list; *p; p++)
@@ -431,6 +395,8 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
*/
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
@@ -440,11 +406,10 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
pwrdm->name, pwrst);
- prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
- (pwrst << OMAP_POWERSTATE_SHIFT),
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst)
+ ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
- return 0;
+ return ret;
}
/**
@@ -457,11 +422,15 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
*/
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- return prm_read_mod_bits_shift(pwrdm->prcm_offs,
- pwrstctrl_reg_offs, OMAP_POWERSTATE_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
+ ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
+
+ return ret;
}
/**
@@ -474,11 +443,15 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_read_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- return prm_read_mod_bits_shift(pwrdm->prcm_offs,
- pwrstst_reg_offs, OMAP_POWERSTATEST_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
+ ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
+
+ return ret;
}
/**
@@ -491,11 +464,15 @@ int pwrdm_read_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
- OMAP3430_LASTPOWERSTATEENTERED_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
+
+ return ret;
}
/**
@@ -511,7 +488,7 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
{
- u32 v;
+ int ret = -EINVAL;
if (!pwrdm)
return -EINVAL;
@@ -522,17 +499,10 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
pwrdm->name, pwrst);
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
- prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
+ ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
- return 0;
+ return ret;
}
/**
@@ -552,7 +522,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
*/
int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
{
- u32 m;
+ int ret = -EINVAL;
if (!pwrdm)
return -EINVAL;
@@ -566,37 +536,10 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
pr_debug("powerdomain: setting next memory powerstate for domain %s "
"bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- switch (bank) {
- case 0:
- m = OMAP_MEM0_ONSTATE_MASK;
- break;
- case 1:
- m = OMAP_MEM1_ONSTATE_MASK;
- break;
- case 2:
- m = OMAP_MEM2_ONSTATE_MASK;
- break;
- case 3:
- m = OMAP_MEM3_ONSTATE_MASK;
- break;
- case 4:
- m = OMAP_MEM4_ONSTATE_MASK;
- break;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
+ ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
- prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
-
- return 0;
+ return ret;
}
/**
@@ -617,7 +560,7 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
*/
int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
{
- u32 m;
+ int ret = -EINVAL;
if (!pwrdm)
return -EINVAL;
@@ -631,37 +574,10 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
pr_debug("powerdomain: setting next memory powerstate for domain %s "
"bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- switch (bank) {
- case 0:
- m = OMAP_MEM0_RETSTATE_MASK;
- break;
- case 1:
- m = OMAP_MEM1_RETSTATE_MASK;
- break;
- case 2:
- m = OMAP_MEM2_RETSTATE_MASK;
- break;
- case 3:
- m = OMAP_MEM3_RETSTATE_MASK;
- break;
- case 4:
- m = OMAP_MEM4_RETSTATE_MASK;
- break;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
-
- prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
- pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
+ ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
- return 0;
+ return ret;
}
/**
@@ -675,11 +591,15 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
*/
int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstst_reg_offs,
- OMAP3430_LOGICSTATEST_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
+ ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
+
+ return ret;
}
/**
@@ -692,17 +612,15 @@ int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
- OMAP3430_LASTLOGICSTATEENTERED_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
+
+ return ret;
}
/**
@@ -715,17 +633,15 @@ int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstctrl_reg_offs,
- OMAP3430_LOGICSTATEST_MASK);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
+ ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
+
+ return ret;
}
/**
@@ -740,46 +656,21 @@ int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
*/
int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
{
- u32 m;
+ int ret = -EINVAL;
if (!pwrdm)
- return -EINVAL;
+ return ret;
if (pwrdm->banks < (bank + 1))
- return -EEXIST;
+ return ret;
if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
bank = 1;
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- switch (bank) {
- case 0:
- m = OMAP_MEM0_STATEST_MASK;
- break;
- case 1:
- m = OMAP_MEM1_STATEST_MASK;
- break;
- case 2:
- m = OMAP_MEM2_STATEST_MASK;
- break;
- case 3:
- m = OMAP_MEM3_STATEST_MASK;
- break;
- case 4:
- m = OMAP_MEM4_STATEST_MASK;
- break;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
+ ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
- return prm_read_mod_bits_shift(pwrdm->prcm_offs,
- pwrstst_reg_offs, m);
+ return ret;
}
/**
@@ -795,43 +686,21 @@ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
*/
int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
{
- u32 m;
+ int ret = -EINVAL;
if (!pwrdm)
- return -EINVAL;
+ return ret;
if (pwrdm->banks < (bank + 1))
- return -EEXIST;
+ return ret;
if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
bank = 1;
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- switch (bank) {
- case 0:
- m = OMAP3430_LASTMEM1STATEENTERED_MASK;
- break;
- case 1:
- m = OMAP3430_LASTMEM2STATEENTERED_MASK;
- break;
- case 2:
- m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
- break;
- case 3:
- m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
- break;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
- return prm_read_mod_bits_shift(pwrdm->prcm_offs,
- OMAP3430_PM_PREPWSTST, m);
+ return ret;
}
/**
@@ -846,43 +715,18 @@ int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
*/
int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
{
- u32 m;
+ int ret = -EINVAL;
if (!pwrdm)
- return -EINVAL;
+ return ret;
if (pwrdm->banks < (bank + 1))
- return -EEXIST;
+ return ret;
- /*
- * The register bit names below may not correspond to the
- * actual names of the bits in each powerdomain's register,
- * but the type of value returned is the same for each
- * powerdomain.
- */
- switch (bank) {
- case 0:
- m = OMAP_MEM0_RETSTATE_MASK;
- break;
- case 1:
- m = OMAP_MEM1_RETSTATE_MASK;
- break;
- case 2:
- m = OMAP_MEM2_RETSTATE_MASK;
- break;
- case 3:
- m = OMAP_MEM3_RETSTATE_MASK;
- break;
- case 4:
- m = OMAP_MEM4_RETSTATE_MASK;
- break;
- default:
- WARN_ON(1); /* should never happen */
- return -EEXIST;
- }
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
+ ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
- return prm_read_mod_bits_shift(pwrdm->prcm_offs,
- pwrstctrl_reg_offs, m);
+ return ret;
}
/**
@@ -896,8 +740,10 @@ int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
*/
int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
- return -EINVAL;
+ return ret;
/*
* XXX should get the powerdomain's current state here;
@@ -907,9 +753,10 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
pr_debug("powerdomain: clearing previous power state reg for %s\n",
pwrdm->name);
- prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
+ ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
- return 0;
+ return ret;
}
/**
@@ -925,19 +772,21 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
*/
int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
- return -EINVAL;
+ return ret;
if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
- return -EINVAL;
+ return ret;
pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
pwrdm->name);
- prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
+ ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
- return 0;
+ return ret;
}
/**
@@ -953,19 +802,21 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
*/
int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
- return -EINVAL;
+ return ret;
if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
- return -EINVAL;
+ return ret;
pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
pwrdm->name);
- prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
+ ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
- return 0;
+ return ret;
}
/**
@@ -992,6 +843,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
*/
int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
{
+ int ret = -EINVAL;
+
if (!pwrdm)
return -EINVAL;
@@ -1001,11 +854,10 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
pwrdm->name);
- prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
- (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
- pwrdm->prcm_offs, pwrstctrl_reg_offs);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
+ ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
- return 0;
+ return ret;
}
/**
@@ -1020,32 +872,15 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
*/
int pwrdm_wait_transition(struct powerdomain *pwrdm)
{
- u32 c = 0;
+ int ret = -EINVAL;
if (!pwrdm)
return -EINVAL;
- /*
- * REVISIT: pwrdm_wait_transition() may be better implemented
- * via a callback and a periodic timer check -- how long do we expect
- * powerdomain transitions to take?
- */
-
- /* XXX Is this udelay() value meaningful? */
- while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) &
- OMAP_INTRANSITION_MASK) &&
- (c++ < PWRDM_TRANSITION_BAILOUT))
- udelay(1);
-
- if (c > PWRDM_TRANSITION_BAILOUT) {
- printk(KERN_ERR "powerdomain: waited too long for "
- "powerdomain %s to complete transition\n", pwrdm->name);
- return -EAGAIN;
- }
-
- pr_debug("powerdomain: completed transition in %d loops\n", c);
+ if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
+ ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
- return 0;
+ return ret;
}
int pwrdm_state_switch(struct powerdomain *pwrdm)
@@ -1075,3 +910,31 @@ int pwrdm_post_transition(void)
return 0;
}
+/**
+ * pwrdm_get_context_loss_count - get powerdomain's context loss count
+ * @pwrdm: struct powerdomain * to wait for
+ *
+ * Context loss count is the sum of powerdomain off-mode counter, the
+ * logic off counter and the per-bank memory off counter. Returns 0
+ * (and WARNs) upon error, otherwise, returns the context loss count.
+ */
+u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
+{
+ int i, count;
+
+ if (!pwrdm) {
+ WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
+ return 0;
+ }
+
+ count = pwrdm->state_counter[PWRDM_POWER_OFF];
+ count += pwrdm->ret_logic_off_counter;
+
+ for (i = 0; i < pwrdm->banks; i++)
+ count += pwrdm->ret_mem_off_counter[i];
+
+ pr_debug("powerdomain: %s: context loss count = %u\n",
+ pwrdm->name, count);
+
+ return count;
+}
diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 9ca420dcd2f8..c66431edfeb7 100644
--- a/arch/arm/plat-omap/include/plat/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -1,27 +1,29 @@
/*
- * OMAP2/3 powerdomain control
+ * OMAP2/3/4 powerdomain control
*
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
*
- * Written by Paul Walmsley
+ * Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *
+ * XXX This should be moved to the mach-omap2/ directory at the earliest
+ * opportunity.
*/
-#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN
-#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
+#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
#include <linux/types.h>
#include <linux/list.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <plat/cpu.h>
-
/* Powerdomain basic power states */
#define PWRDM_POWER_OFF 0x0
#define PWRDM_POWER_RET 0x1
@@ -81,6 +83,7 @@ struct powerdomain;
* @name: Powerdomain name
* @omap_chip: represents the OMAP chip types containing this pwrdm
* @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
* @pwrsts: Possible powerdomain power states
* @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
* @flags: Powerdomain flags
@@ -93,6 +96,8 @@ struct powerdomain;
* @state_counter:
* @timer:
* @state_timer:
+ *
+ * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
*/
struct powerdomain {
const char *name;
@@ -104,6 +109,7 @@ struct powerdomain {
const u8 banks;
const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+ const u8 prcm_partition;
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
struct list_head node;
int state;
@@ -117,8 +123,50 @@ struct powerdomain {
#endif
};
+/**
+ * struct pwrdm_ops - Arch specfic function implementations
+ * @pwrdm_set_next_pwrst: Set the target power state for a pd
+ * @pwrdm_read_next_pwrst: Read the target power state set for a pd
+ * @pwrdm_read_pwrst: Read the current power state of a pd
+ * @pwrdm_read_prev_pwrst: Read the prev power state entered by the pd
+ * @pwrdm_set_logic_retst: Set the logic state in RET for a pd
+ * @pwrdm_set_mem_onst: Set the Memory state in ON for a pd
+ * @pwrdm_set_mem_retst: Set the Memory state in RET for a pd
+ * @pwrdm_read_logic_pwrst: Read the current logic state of a pd
+ * @pwrdm_read_prev_logic_pwrst: Read the previous logic state entered by a pd
+ * @pwrdm_read_logic_retst: Read the logic state in RET for a pd
+ * @pwrdm_read_mem_pwrst: Read the current memory state of a pd
+ * @pwrdm_read_prev_mem_pwrst: Read the previous memory state entered by a pd
+ * @pwrdm_read_mem_retst: Read the memory state in RET for a pd
+ * @pwrdm_clear_all_prev_pwrst: Clear all previous power states logged for a pd
+ * @pwrdm_enable_hdwr_sar: Enable Hardware Save-Restore feature for the pd
+ * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd
+ * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep
+ * @pwrdm_wait_transition: Wait for a pd state transition to complete
+ */
+struct pwrdm_ops {
+ int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst);
+ int (*pwrdm_read_next_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_prev_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_set_logic_retst)(struct powerdomain *pwrdm, u8 pwrst);
+ int (*pwrdm_set_mem_onst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+ int (*pwrdm_set_mem_retst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+ int (*pwrdm_read_logic_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_prev_logic_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_logic_retst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_mem_pwrst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_read_prev_mem_pwrst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_read_mem_retst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_clear_all_prev_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_enable_hdwr_sar)(struct powerdomain *pwrdm);
+ int (*pwrdm_disable_hdwr_sar)(struct powerdomain *pwrdm);
+ int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
+ int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
+};
-void pwrdm_init(struct powerdomain **pwrdm_list);
+void pwrdm_fw_init(void);
+void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs);
struct powerdomain *pwrdm_lookup(const char *name);
@@ -163,5 +211,23 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
int pwrdm_pre_transition(void);
int pwrdm_post_transition(void);
int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
+u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+
+extern void omap2xxx_powerdomains_init(void);
+extern void omap3xxx_powerdomains_init(void);
+extern void omap44xx_powerdomains_init(void);
+
+extern struct pwrdm_ops omap2_pwrdm_operations;
+extern struct pwrdm_ops omap3_pwrdm_operations;
+extern struct pwrdm_ops omap4_pwrdm_operations;
+
+/* Common Internal functions used across OMAP rev's */
+extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank);
+extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank);
+extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
+
+extern struct powerdomain wkup_omap2_pwrdm;
+extern struct powerdomain gfx_omap2_pwrdm;
+
#endif
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
new file mode 100644
index 000000000000..d5233890370c
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
@@ -0,0 +1,242 @@
+/*
+ * OMAP2 and OMAP3 powerdomain control
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <plat/prcm.h>
+
+#include "powerdomain.h"
+#include "prm-regbits-34xx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
+
+
+/* Common functions across OMAP2 and OMAP3 */
+static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
+}
+
+static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
+}
+
+static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
+ m);
+}
+
+static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL, m);
+}
+
+static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
+ omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ printk(KERN_ERR "powerdomain: waited too long for "
+ "powerdomain %s to complete transition\n", pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+/* Applicable only for OMAP3. Not supported on OMAP2 */
+static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTPOWERSTATEENTERED_MASK);
+}
+
+static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTLOGICSTATEENTERED_MASK);
+}
+
+static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP3430_LASTMEM1STATEENTERED_MASK;
+ case 1:
+ return OMAP3430_LASTMEM2STATEENTERED_MASK;
+ case 2:
+ return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
+ case 3:
+ return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap3_get_mem_bank_lastmemst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST, m);
+}
+
+static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+ return 0;
+}
+
+static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(0,
+ 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+}
+
+static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ 0, pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+}
+
+struct pwrdm_ops omap2_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
+
+struct pwrdm_ops omap3_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
+ .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
+ .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
+ .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
new file mode 100644
index 000000000000..a7880af4b3d9
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -0,0 +1,225 @@
+/*
+ * OMAP4 powerdomain control
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include "powerdomain.h"
+#include <plat/prcm.h>
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-44xx.h"
+
+static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP_POWERSTATE_MASK;
+ v >>= OMAP_POWERSTATE_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP_POWERSTATEST_MASK;
+ v >>= OMAP_POWERSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
+ v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
+ (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTST);
+ return 0;
+}
+
+static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LOGICSTATEST_MASK;
+ v >>= OMAP4430_LOGICSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP4430_LOGICRETSTATE_MASK;
+ v >>= OMAP4430_LOGICRETSTATE_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ printk(KERN_ERR "powerdomain: waited too long for "
+ "powerdomain %s to complete transition\n", pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+struct pwrdm_ops omap4_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
+ .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
+ .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
+ .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
+ .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
+ .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
+};
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
index 105cbcaefd3b..5b4dd971320a 100644
--- a/arch/arm/mach-omap2/powerdomains.h
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -2,10 +2,9 @@
* OMAP2/3 common powerdomain definitions
*
* Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Nokia Corporation
*
- * Written by Paul Walmsley
- * Debugging and integration fixes by Jouni Högander
+ * Paul Walmsley, Jouni Högander
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,9 +17,6 @@
* Clock Domain Framework
*/
-#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS
-#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS
-
/*
* This file contains all of the powerdomains that have some element
* of software control for the OMAP24xx and OMAP34xx chips.
@@ -49,24 +45,18 @@
* address offset is different between the C55 and C64 DSPs.
*/
-#include <plat/powerdomain.h>
+#include "powerdomain.h"
#include "prcm-common.h"
#include "prm.h"
-#include "cm.h"
-#include "powerdomains24xx.h"
-#include "powerdomains34xx.h"
-#include "powerdomains44xx.h"
/* OMAP2/3-common powerdomains */
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-
/*
* The GFX powerdomain is not present on 3430ES2, but currently we do not
* have a macro to filter it out at compile-time.
*/
-static struct powerdomain gfx_omap2_pwrdm = {
+struct powerdomain gfx_omap2_pwrdm = {
.name = "gfx_pwrdm",
.prcm_offs = GFX_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
@@ -82,72 +72,8 @@ static struct powerdomain gfx_omap2_pwrdm = {
},
};
-static struct powerdomain wkup_omap2_pwrdm = {
+struct powerdomain wkup_omap2_pwrdm = {
.name = "wkup_pwrdm",
.prcm_offs = WKUP_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
-
-#endif
-
-
-/* As powerdomains are added or removed above, this list must also be changed */
-static struct powerdomain *powerdomains_omap[] __initdata = {
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
- &wkup_omap2_pwrdm,
- &gfx_omap2_pwrdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
- &dsp_pwrdm,
- &mpu_24xx_pwrdm,
- &core_24xx_pwrdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
- &mdm_pwrdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
- &iva2_pwrdm,
- &mpu_3xxx_pwrdm,
- &neon_pwrdm,
- &core_3xxx_pre_es3_1_pwrdm,
- &core_3xxx_es3_1_pwrdm,
- &cam_pwrdm,
- &dss_pwrdm,
- &per_pwrdm,
- &emu_pwrdm,
- &sgx_pwrdm,
- &usbhost_pwrdm,
- &dpll1_pwrdm,
- &dpll2_pwrdm,
- &dpll3_pwrdm,
- &dpll4_pwrdm,
- &dpll5_pwrdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
- &core_44xx_pwrdm,
- &gfx_44xx_pwrdm,
- &abe_44xx_pwrdm,
- &dss_44xx_pwrdm,
- &tesla_44xx_pwrdm,
- &wkup_44xx_pwrdm,
- &cpu0_44xx_pwrdm,
- &cpu1_44xx_pwrdm,
- &emu_44xx_pwrdm,
- &mpu_44xx_pwrdm,
- &ivahd_44xx_pwrdm,
- &cam_44xx_pwrdm,
- &l3init_44xx_pwrdm,
- &l4per_44xx_pwrdm,
- &always_on_core_44xx_pwrdm,
- &cefuse_44xx_pwrdm,
-#endif
- NULL
-};
-
-
-#endif
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h
new file mode 100644
index 000000000000..fa311669d53d
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h
@@ -0,0 +1,22 @@
+/*
+ * OMAP2/3 common powerdomains - prototypes
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H
+
+#include "powerdomain.h"
+
+extern struct powerdomain gfx_omap2_pwrdm;
+extern struct powerdomain wkup_omap2_pwrdm;
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains24xx.h b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index 775093add9b6..9b1a33500577 100644
--- a/arch/arm/mach-omap2/powerdomains24xx.h
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -1,37 +1,28 @@
/*
- * OMAP24XX powerdomain definitions
+ * OMAP2XXX powerdomain definitions
*
* Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Nokia Corporation
*
- * Written by Paul Walmsley
- * Debugging and integration fixes by Jouni Högander
+ * Paul Walmsley, Jouni Högander
*
* This program is free software; you can 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
-#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
+#include <linux/kernel.h>
+#include <linux/init.h>
-/*
- * N.B. If powerdomains are added or removed from this file, update
- * the array in mach-omap2/powerdomains.h.
- */
-
-#include <plat/powerdomain.h>
+#include "powerdomain.h"
+#include "powerdomains2xxx_3xxx_data.h"
#include "prcm-common.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
-#include "cm.h"
-#include "cm-regbits-24xx.h"
/* 24XX powerdomains and dependencies */
-#ifdef CONFIG_ARCH_OMAP2
-
/* Powerdomains */
static struct powerdomain dsp_pwrdm = {
@@ -82,9 +73,6 @@ static struct powerdomain core_24xx_pwrdm = {
},
};
-#endif /* CONFIG_ARCH_OMAP2 */
-
-
/*
* 2430-specific powerdomains
@@ -111,5 +99,25 @@ static struct powerdomain mdm_pwrdm = {
#endif /* CONFIG_ARCH_OMAP2430 */
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap2xxx[] __initdata = {
+ &wkup_omap2_pwrdm,
+ &gfx_omap2_pwrdm,
+
+#ifdef CONFIG_ARCH_OMAP2
+ &dsp_pwrdm,
+ &mpu_24xx_pwrdm,
+ &core_24xx_pwrdm,
#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+ &mdm_pwrdm,
+#endif
+ NULL
+};
+
+void __init omap2xxx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap2xxx, &omap2_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index fa904861668b..e1bec562625b 100644
--- a/arch/arm/mach-omap2/powerdomains34xx.h
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -4,28 +4,23 @@
* Copyright (C) 2007-2008 Texas Instruments, Inc.
* Copyright (C) 2007-2010 Nokia Corporation
*
- * Written by Paul Walmsley
- * Debugging and integration fixes by Jouni Högander
+ * Paul Walmsley, Jouni Högander
*
* This program is free software; you can 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
-#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
+#include <linux/kernel.h>
+#include <linux/init.h>
-/*
- * N.B. If powerdomains are added or removed from this file, update
- * the array in mach-omap2/powerdomains.h.
- */
-
-#include <plat/powerdomain.h>
+#include "powerdomain.h"
+#include "powerdomains2xxx_3xxx_data.h"
#include "prcm-common.h"
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
/*
@@ -80,6 +75,10 @@ static struct powerdomain mpu_3xxx_pwrdm = {
* 3430s upto ES3.0 and 3630ES1.0. Hence this feature
* needs to be disabled on these chips.
* Refer: 3430 errata ID i459 and 3630 errata ID i579
+ *
+ * Note: setting the SAR flag could help for errata ID i478
+ * which applies to 3430 <= ES3.1, but since the SAR feature
+ * is broken, do not use it.
*/
static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
.name = "core_pwrdm",
@@ -108,6 +107,10 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
CHIP_GE_OMAP3630ES1_1),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
+ /*
+ * Setting the SAR flag for errata ID i478 which applies
+ * to 3430 <= ES3.1
+ */
.flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
.banks = 2,
.pwrsts_mem_ret = {
@@ -252,8 +255,33 @@ static struct powerdomain dpll5_pwrdm = {
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap3xxx[] __initdata = {
-#endif /* CONFIG_ARCH_OMAP3 */
+ &wkup_omap2_pwrdm,
+ &gfx_omap2_pwrdm,
+ &iva2_pwrdm,
+ &mpu_3xxx_pwrdm,
+ &neon_pwrdm,
+ &core_3xxx_pre_es3_1_pwrdm,
+ &core_3xxx_es3_1_pwrdm,
+ &cam_pwrdm,
+ &dss_pwrdm,
+ &per_pwrdm,
+ &emu_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+ &dpll1_pwrdm,
+ &dpll2_pwrdm,
+ &dpll3_pwrdm,
+ &dpll4_pwrdm,
+ &dpll5_pwrdm,
+#endif
+ NULL
+};
-#endif
+void __init omap3xxx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap3xxx, &omap3_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/powerdomains44xx.h b/arch/arm/mach-omap2/powerdomains44xx_data.c
index 9c01b55d6102..26d7641076d7 100644
--- a/arch/arm/mach-omap2/powerdomains44xx.h
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -19,23 +19,22 @@
* published by the Free Software Foundation.
*/
-#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
-#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
+#include <linux/kernel.h>
+#include <linux/init.h>
-#include <plat/powerdomain.h>
+#include "powerdomain.h"
#include "prcm-common.h"
-#include "cm.h"
-#include "cm-regbits-44xx.h"
-#include "prm.h"
+#include "prcm44xx.h"
#include "prm-regbits-44xx.h"
-
-#if defined(CONFIG_ARCH_OMAP4)
+#include "prm44xx.h"
+#include "prcm_mpu44xx.h"
/* core_44xx_pwrdm: CORE power domain */
static struct powerdomain core_44xx_pwrdm = {
.name = "core_pwrdm",
- .prcm_offs = OMAP4430_PRM_CORE_MOD,
+ .prcm_offs = OMAP4430_PRM_CORE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
@@ -60,7 +59,8 @@ static struct powerdomain core_44xx_pwrdm = {
/* gfx_44xx_pwrdm: 3D accelerator power domain */
static struct powerdomain gfx_44xx_pwrdm = {
.name = "gfx_pwrdm",
- .prcm_offs = OMAP4430_PRM_GFX_MOD,
+ .prcm_offs = OMAP4430_PRM_GFX_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
@@ -76,7 +76,8 @@ static struct powerdomain gfx_44xx_pwrdm = {
/* abe_44xx_pwrdm: Audio back end power domain */
static struct powerdomain abe_44xx_pwrdm = {
.name = "abe_pwrdm",
- .prcm_offs = OMAP4430_PRM_ABE_MOD,
+ .prcm_offs = OMAP4430_PRM_ABE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRDM_POWER_OFF,
@@ -95,7 +96,8 @@ static struct powerdomain abe_44xx_pwrdm = {
/* dss_44xx_pwrdm: Display subsystem power domain */
static struct powerdomain dss_44xx_pwrdm = {
.name = "dss_pwrdm",
- .prcm_offs = OMAP4430_PRM_DSS_MOD,
+ .prcm_offs = OMAP4430_PRM_DSS_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
@@ -112,7 +114,8 @@ static struct powerdomain dss_44xx_pwrdm = {
/* tesla_44xx_pwrdm: Tesla processor power domain */
static struct powerdomain tesla_44xx_pwrdm = {
.name = "tesla_pwrdm",
- .prcm_offs = OMAP4430_PRM_TESLA_MOD,
+ .prcm_offs = OMAP4430_PRM_TESLA_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
@@ -133,7 +136,8 @@ static struct powerdomain tesla_44xx_pwrdm = {
/* wkup_44xx_pwrdm: Wake-up power domain */
static struct powerdomain wkup_44xx_pwrdm = {
.name = "wkup_pwrdm",
- .prcm_offs = OMAP4430_PRM_WKUP_MOD,
+ .prcm_offs = OMAP4430_PRM_WKUP_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_ON,
.banks = 1,
@@ -148,7 +152,8 @@ static struct powerdomain wkup_44xx_pwrdm = {
/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
static struct powerdomain cpu0_44xx_pwrdm = {
.name = "cpu0_pwrdm",
- .prcm_offs = OMAP4430_PRCM_MPU_CPU0_MOD,
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
@@ -164,7 +169,8 @@ static struct powerdomain cpu0_44xx_pwrdm = {
/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
static struct powerdomain cpu1_44xx_pwrdm = {
.name = "cpu1_pwrdm",
- .prcm_offs = OMAP4430_PRCM_MPU_CPU1_MOD,
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
@@ -180,7 +186,8 @@ static struct powerdomain cpu1_44xx_pwrdm = {
/* emu_44xx_pwrdm: Emulation power domain */
static struct powerdomain emu_44xx_pwrdm = {
.name = "emu_pwrdm",
- .prcm_offs = OMAP4430_PRM_EMU_MOD,
+ .prcm_offs = OMAP4430_PRM_EMU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
@@ -195,7 +202,8 @@ static struct powerdomain emu_44xx_pwrdm = {
/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
static struct powerdomain mpu_44xx_pwrdm = {
.name = "mpu_pwrdm",
- .prcm_offs = OMAP4430_PRM_MPU_MOD,
+ .prcm_offs = OMAP4430_PRM_MPU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
@@ -215,7 +223,8 @@ static struct powerdomain mpu_44xx_pwrdm = {
/* ivahd_44xx_pwrdm: IVA-HD power domain */
static struct powerdomain ivahd_44xx_pwrdm = {
.name = "ivahd_pwrdm",
- .prcm_offs = OMAP4430_PRM_IVAHD_MOD,
+ .prcm_offs = OMAP4430_PRM_IVAHD_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRDM_POWER_OFF,
@@ -238,7 +247,8 @@ static struct powerdomain ivahd_44xx_pwrdm = {
/* cam_44xx_pwrdm: Camera subsystem power domain */
static struct powerdomain cam_44xx_pwrdm = {
.name = "cam_pwrdm",
- .prcm_offs = OMAP4430_PRM_CAM_MOD,
+ .prcm_offs = OMAP4430_PRM_CAM_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
@@ -254,9 +264,10 @@ static struct powerdomain cam_44xx_pwrdm = {
/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */
static struct powerdomain l3init_44xx_pwrdm = {
.name = "l3init_pwrdm",
- .prcm_offs = OMAP4430_PRM_L3INIT_MOD,
+ .prcm_offs = OMAP4430_PRM_L3INIT_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -271,9 +282,10 @@ static struct powerdomain l3init_44xx_pwrdm = {
/* l4per_44xx_pwrdm: Target peripherals power domain */
static struct powerdomain l4per_44xx_pwrdm = {
.name = "l4per_pwrdm",
- .prcm_offs = OMAP4430_PRM_L4PER_MOD,
+ .prcm_offs = OMAP4430_PRM_L4PER_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 2,
.pwrsts_mem_ret = {
@@ -293,7 +305,8 @@ static struct powerdomain l4per_44xx_pwrdm = {
*/
static struct powerdomain always_on_core_44xx_pwrdm = {
.name = "always_on_core_pwrdm",
- .prcm_offs = OMAP4430_PRM_ALWAYS_ON_MOD,
+ .prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_ON,
};
@@ -301,7 +314,8 @@ static struct powerdomain always_on_core_44xx_pwrdm = {
/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
static struct powerdomain cefuse_44xx_pwrdm = {
.name = "cefuse_pwrdm",
- .prcm_offs = OMAP4430_PRM_CEFUSE_MOD,
+ .prcm_offs = OMAP4430_PRM_CEFUSE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
};
@@ -314,6 +328,28 @@ static struct powerdomain cefuse_44xx_pwrdm = {
* stdefuse
*/
-#endif
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap44xx[] __initdata = {
+ &core_44xx_pwrdm,
+ &gfx_44xx_pwrdm,
+ &abe_44xx_pwrdm,
+ &dss_44xx_pwrdm,
+ &tesla_44xx_pwrdm,
+ &wkup_44xx_pwrdm,
+ &cpu0_44xx_pwrdm,
+ &cpu1_44xx_pwrdm,
+ &emu_44xx_pwrdm,
+ &mpu_44xx_pwrdm,
+ &ivahd_44xx_pwrdm,
+ &cam_44xx_pwrdm,
+ &l3init_44xx_pwrdm,
+ &l4per_44xx_pwrdm,
+ &always_on_core_44xx_pwrdm,
+ &cefuse_44xx_pwrdm,
+ NULL
+};
-#endif
+void __init omap44xx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap44xx, &omap4_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 298a22a754e2..87486f559784 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -8,15 +8,12 @@
* Copyright (C) 2007-2009 Nokia Corporation
*
* Written by Paul Walmsley
- * OMAP4 defines in this file are automatically generated from the OMAP hardware
- * databases.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
/* Module offsets from both CM_BASE & PRM_BASE */
/*
@@ -51,75 +48,6 @@
#define OMAP3430_NEON_MOD 0xb00
#define OMAP3430ES2_USBHOST_MOD 0xc00
-#define BITS(n_bit) \
- (((1 << n_bit) - 1) | (1 << n_bit))
-
-#define BITFIELD(l_bit, u_bit) \
- (BITS(u_bit) & ~((BITS(l_bit)) >> 1))
-
-/* OMAP44XX specific module offsets */
-
-/* CM1 instances */
-
-#define OMAP4430_CM1_OCP_SOCKET_MOD 0x0000
-#define OMAP4430_CM1_CKGEN_MOD 0x0100
-#define OMAP4430_CM1_MPU_MOD 0x0300
-#define OMAP4430_CM1_TESLA_MOD 0x0400
-#define OMAP4430_CM1_ABE_MOD 0x0500
-#define OMAP4430_CM1_RESTORE_MOD 0x0e00
-#define OMAP4430_CM1_INSTR_MOD 0x0f00
-
-/* CM2 instances */
-
-#define OMAP4430_CM2_OCP_SOCKET_MOD 0x0000
-#define OMAP4430_CM2_CKGEN_MOD 0x0100
-#define OMAP4430_CM2_ALWAYS_ON_MOD 0x0600
-#define OMAP4430_CM2_CORE_MOD 0x0700
-#define OMAP4430_CM2_IVAHD_MOD 0x0f00
-#define OMAP4430_CM2_CAM_MOD 0x1000
-#define OMAP4430_CM2_DSS_MOD 0x1100
-#define OMAP4430_CM2_GFX_MOD 0x1200
-#define OMAP4430_CM2_L3INIT_MOD 0x1300
-#define OMAP4430_CM2_L4PER_MOD 0x1400
-#define OMAP4430_CM2_CEFUSE_MOD 0x1600
-#define OMAP4430_CM2_RESTORE_MOD 0x1e00
-#define OMAP4430_CM2_INSTR_MOD 0x1f00
-
-/* PRM instances */
-
-#define OMAP4430_PRM_OCP_SOCKET_MOD 0x0000
-#define OMAP4430_PRM_CKGEN_MOD 0x0100
-#define OMAP4430_PRM_MPU_MOD 0x0300
-#define OMAP4430_PRM_TESLA_MOD 0x0400
-#define OMAP4430_PRM_ABE_MOD 0x0500
-#define OMAP4430_PRM_ALWAYS_ON_MOD 0x0600
-#define OMAP4430_PRM_CORE_MOD 0x0700
-#define OMAP4430_PRM_IVAHD_MOD 0x0f00
-#define OMAP4430_PRM_CAM_MOD 0x1000
-#define OMAP4430_PRM_DSS_MOD 0x1100
-#define OMAP4430_PRM_GFX_MOD 0x1200
-#define OMAP4430_PRM_L3INIT_MOD 0x1300
-#define OMAP4430_PRM_L4PER_MOD 0x1400
-#define OMAP4430_PRM_CEFUSE_MOD 0x1600
-#define OMAP4430_PRM_WKUP_MOD 0x1700
-#define OMAP4430_PRM_WKUP_CM_MOD 0x1800
-#define OMAP4430_PRM_EMU_MOD 0x1900
-#define OMAP4430_PRM_EMU_CM_MOD 0x1a00
-#define OMAP4430_PRM_DEVICE_MOD 0x1b00
-#define OMAP4430_PRM_INSTR_MOD 0x1f00
-
-/* SCRM instances */
-
-#define OMAP4430_SCRM_SCRM_MOD 0x0000
-
-/* PRCM_MPU instances */
-
-#define OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_MOD 0x0000
-#define OMAP4430_PRCM_MPU_DEVICE_PRM_MOD 0x0200
-#define OMAP4430_PRCM_MPU_CPU0_MOD 0x0400
-#define OMAP4430_PRCM_MPU_CPU1_MOD 0x0800
-
-
/* 24XX register bits shared between CM & PRM registers */
/* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
@@ -243,13 +171,14 @@
#define OMAP24XX_EN_GPT1_MASK (1 << 0)
/* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS_SHIFT (1 << 2)
-#define OMAP24XX_ST_GPIOS_MASK 2
-#define OMAP24XX_ST_GPT1_SHIFT (1 << 0)
-#define OMAP24XX_ST_GPT1_MASK 0
+#define OMAP24XX_ST_GPIOS_SHIFT 2
+#define OMAP24XX_ST_GPIOS_MASK (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT 0
+#define OMAP24XX_ST_GPT1_MASK (1 << 0)
/* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM_SHIFT (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT 0
+#define OMAP2430_ST_MDM_MASK (1 << 0)
/* 3430 register bits shared between CM & PRM registers */
@@ -460,5 +389,18 @@
#define OMAP3430_EN_CORE_SHIFT 0
#define OMAP3430_EN_CORE_MASK (1 << 0)
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+# ifndef __ASSEMBLER__
+extern void __iomem *prm_base;
+extern void __iomem *cm_base;
+extern void __iomem *cm2_base;
+# endif
+
#endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index a51846e3a6fa..679bcd28576e 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -17,7 +17,8 @@
* 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/clk.h>
#include <linux/io.h>
@@ -29,105 +30,27 @@
#include "clock.h"
#include "clock2xxx.h"
-#include "cm.h"
-#include "prm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "prminst44xx.h"
#include "prm-regbits-24xx.h"
#include "prm-regbits-44xx.h"
#include "control.h"
-static void __iomem *prm_base;
-static void __iomem *cm_base;
-static void __iomem *cm2_base;
+void __iomem *prm_base;
+void __iomem *cm_base;
+void __iomem *cm2_base;
#define MAX_MODULE_ENABLE_WAIT 100000
-struct omap3_prcm_regs {
- u32 control_padconf_sys_nirq;
- u32 iva2_cm_clksel1;
- u32 iva2_cm_clksel2;
- u32 cm_sysconfig;
- u32 sgx_cm_clksel;
- u32 dss_cm_clksel;
- u32 cam_cm_clksel;
- u32 per_cm_clksel;
- u32 emu_cm_clksel;
- u32 emu_cm_clkstctrl;
- u32 pll_cm_autoidle2;
- u32 pll_cm_clksel4;
- u32 pll_cm_clksel5;
- u32 pll_cm_clken2;
- u32 cm_polctrl;
- u32 iva2_cm_fclken;
- u32 iva2_cm_clken_pll;
- u32 core_cm_fclken1;
- u32 core_cm_fclken3;
- u32 sgx_cm_fclken;
- u32 wkup_cm_fclken;
- u32 dss_cm_fclken;
- u32 cam_cm_fclken;
- u32 per_cm_fclken;
- u32 usbhost_cm_fclken;
- u32 core_cm_iclken1;
- u32 core_cm_iclken2;
- u32 core_cm_iclken3;
- u32 sgx_cm_iclken;
- u32 wkup_cm_iclken;
- u32 dss_cm_iclken;
- u32 cam_cm_iclken;
- u32 per_cm_iclken;
- u32 usbhost_cm_iclken;
- u32 iva2_cm_autiidle2;
- u32 mpu_cm_autoidle2;
- u32 iva2_cm_clkstctrl;
- u32 mpu_cm_clkstctrl;
- u32 core_cm_clkstctrl;
- u32 sgx_cm_clkstctrl;
- u32 dss_cm_clkstctrl;
- u32 cam_cm_clkstctrl;
- u32 per_cm_clkstctrl;
- u32 neon_cm_clkstctrl;
- u32 usbhost_cm_clkstctrl;
- u32 core_cm_autoidle1;
- u32 core_cm_autoidle2;
- u32 core_cm_autoidle3;
- u32 wkup_cm_autoidle;
- u32 dss_cm_autoidle;
- u32 cam_cm_autoidle;
- u32 per_cm_autoidle;
- u32 usbhost_cm_autoidle;
- u32 sgx_cm_sleepdep;
- u32 dss_cm_sleepdep;
- u32 cam_cm_sleepdep;
- u32 per_cm_sleepdep;
- u32 usbhost_cm_sleepdep;
- u32 cm_clkout_ctrl;
- u32 prm_clkout_ctrl;
- u32 sgx_pm_wkdep;
- u32 dss_pm_wkdep;
- u32 cam_pm_wkdep;
- u32 per_pm_wkdep;
- u32 neon_pm_wkdep;
- u32 usbhost_pm_wkdep;
- u32 core_pm_mpugrpsel1;
- u32 iva2_pm_ivagrpsel1;
- u32 core_pm_mpugrpsel3;
- u32 core_pm_ivagrpsel3;
- u32 wkup_pm_mpugrpsel;
- u32 wkup_pm_ivagrpsel;
- u32 per_pm_mpugrpsel;
- u32 per_pm_ivagrpsel;
- u32 wkup_pm_wken;
-};
-
-static 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())
- return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+ return omap2_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;
+ return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
return 0;
}
@@ -143,126 +66,46 @@ void omap_prcm_arch_reset(char mode, const char *cmd)
prcm_offs = WKUP_MOD;
} else if (cpu_is_omap34xx()) {
- u32 l;
-
prcm_offs = OMAP3430_GR_MOD;
- 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,
- * cf. OMAP34xx TRM, Initialization / Software Booting
- * Configuration. */
- omap_writel(l, OMAP343X_SCRATCHPAD + 4);
- } else if (cpu_is_omap44xx())
- prcm_offs = OMAP4430_PRM_DEVICE_MOD;
- else
+ omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
+ } else if (cpu_is_omap44xx()) {
+ omap4_prm_global_warm_sw_reset(); /* never returns */
+ } else {
WARN_ON(1);
+ }
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
- OMAP2_RM_RSTCTRL);
- if (cpu_is_omap44xx())
- prm_set_mod_reg_bits(OMAP4430_RST_GLOBAL_WARM_SW_MASK,
- prcm_offs, OMAP4_RM_RSTCTRL);
-}
-
-static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
-{
- BUG_ON(!base);
- return __raw_readl(base + module + reg);
-}
-
-static inline void __omap_prcm_write(u32 value, void __iomem *base,
- s16 module, u16 reg)
-{
- BUG_ON(!base);
- __raw_writel(value, base + module + reg);
-}
-
-/* Read a register in a PRM module */
-u32 prm_read_mod_reg(s16 module, u16 idx)
-{
- return __omap_prcm_read(prm_base, module, idx);
-}
-
-/* Write into a register in a PRM module */
-void prm_write_mod_reg(u32 val, s16 module, u16 idx)
-{
- __omap_prcm_write(val, prm_base, module, idx);
-}
-
-/* Read-modify-write a register in a PRM module. Caller must lock */
-u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
-{
- u32 v;
-
- v = prm_read_mod_reg(module, idx);
- v &= ~mask;
- v |= bits;
- prm_write_mod_reg(v, module, idx);
-
- return v;
-}
-
-/* Read a PRM register, AND it, and shift the result down to bit 0 */
-u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
-{
- u32 v;
-
- v = prm_read_mod_reg(domain, idx);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
-/* Read a PRM register, AND it, and shift the result down to bit 0 */
-u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
-{
- u32 v;
-
- v = __raw_readl(reg);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
-/* Read-modify-write a register in a PRM module. Caller must lock */
-u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
-{
- u32 v;
-
- v = __raw_readl(reg);
- v &= ~mask;
- v |= bits;
- __raw_writel(v, reg);
-
- return v;
-}
-/* Read a register in a CM module */
-u32 cm_read_mod_reg(s16 module, u16 idx)
-{
- return __omap_prcm_read(cm_base, module, idx);
-}
-
-/* Write into a register in a CM module */
-void cm_write_mod_reg(u32 val, s16 module, u16 idx)
-{
- __omap_prcm_write(val, cm_base, module, idx);
-}
-
-/* Read-modify-write a register in a CM module. Caller must lock */
-u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
-{
- u32 v;
-
- v = cm_read_mod_reg(module, idx);
- v &= ~mask;
- v |= bits;
- cm_write_mod_reg(v, module, idx);
-
- return v;
+ /*
+ * As per Errata i520, in some cases, user will not be able to
+ * access DDR memory after warm-reset.
+ * This situation occurs while the warm-reset happens during a read
+ * access to DDR memory. In that particular condition, DDR memory
+ * does not respond to a corrupted read command due to the warm
+ * reset occurrence but SDRC is waiting for read completion.
+ * SDRC is not sensitive to the warm reset, but the interconnect is
+ * reset on the fly, thus causing a misalignment between SDRC logic,
+ * interconnect logic and DDR memory state.
+ * WORKAROUND:
+ * Steps to perform before a Warm reset is trigged:
+ * 1. enable self-refresh on idle request
+ * 2. put SDRC in idle
+ * 3. wait until SDRC goes to idle
+ * 4. generate SW reset (Global SW reset)
+ *
+ * Steps to be performed after warm reset occurs (in bootloader):
+ * if HW warm reset is the source, apply below steps before any
+ * accesses to SDRAM:
+ * 1. Reset SMS and SDRC and wait till reset is complete
+ * 2. Re-initialize SMS, SDRC and memory
+ *
+ * NOTE: Above work around is required only if arch reset is implemented
+ * using Global SW reset(GLOBAL_SW_RST). DPLL3 reset does not need
+ * the WA since it resets SDRC as well as part of cold reset.
+ */
+
+ /* XXX should be moved to some OMAP2/3 specific code */
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
+ OMAP2_RM_RSTCTRL);
+ omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */
}
/**
@@ -274,6 +117,9 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
*
* Returns 1 if the module indicated readiness in time, or 0 if it
* failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
+ *
+ * XXX This function is deprecated. It should be removed once the
+ * hwmod conversion is complete.
*/
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
const char *name)
@@ -316,303 +162,3 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
WARN_ON(!cm2_base);
}
}
-
-#ifdef CONFIG_ARCH_OMAP3
-void omap3_prcm_save_context(void)
-{
- prcm_context.control_padconf_sys_nirq =
- omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
- prcm_context.iva2_cm_clksel1 =
- cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
- prcm_context.iva2_cm_clksel2 =
- cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
- prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
- prcm_context.sgx_cm_clksel =
- cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
- prcm_context.dss_cm_clksel =
- cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
- prcm_context.cam_cm_clksel =
- cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
- prcm_context.per_cm_clksel =
- cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
- prcm_context.emu_cm_clksel =
- cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
- prcm_context.emu_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.pll_cm_autoidle2 =
- cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
- prcm_context.pll_cm_clksel4 =
- cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
- prcm_context.pll_cm_clksel5 =
- cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
- prcm_context.pll_cm_clken2 =
- cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
- prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
- prcm_context.iva2_cm_fclken =
- cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
- prcm_context.iva2_cm_clken_pll = cm_read_mod_reg(OMAP3430_IVA2_MOD,
- OMAP3430_CM_CLKEN_PLL);
- prcm_context.core_cm_fclken1 =
- cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
- prcm_context.core_cm_fclken3 =
- cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
- prcm_context.sgx_cm_fclken =
- cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
- prcm_context.wkup_cm_fclken =
- cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
- prcm_context.dss_cm_fclken =
- cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
- prcm_context.cam_cm_fclken =
- cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
- prcm_context.per_cm_fclken =
- cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
- prcm_context.usbhost_cm_fclken =
- cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
- prcm_context.core_cm_iclken1 =
- cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
- prcm_context.core_cm_iclken2 =
- cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
- prcm_context.core_cm_iclken3 =
- cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
- prcm_context.sgx_cm_iclken =
- cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
- prcm_context.wkup_cm_iclken =
- cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
- prcm_context.dss_cm_iclken =
- cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
- prcm_context.cam_cm_iclken =
- cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
- prcm_context.per_cm_iclken =
- cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
- prcm_context.usbhost_cm_iclken =
- cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
- prcm_context.iva2_cm_autiidle2 =
- cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
- prcm_context.mpu_cm_autoidle2 =
- cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
- prcm_context.iva2_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.mpu_cm_clkstctrl =
- cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.core_cm_clkstctrl =
- cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.sgx_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
- OMAP2_CM_CLKSTCTRL);
- prcm_context.dss_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.cam_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.per_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.neon_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
- prcm_context.usbhost_cm_clkstctrl =
- cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
- OMAP2_CM_CLKSTCTRL);
- prcm_context.core_cm_autoidle1 =
- cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
- prcm_context.core_cm_autoidle2 =
- cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
- prcm_context.core_cm_autoidle3 =
- cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
- prcm_context.wkup_cm_autoidle =
- cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
- prcm_context.dss_cm_autoidle =
- cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
- prcm_context.cam_cm_autoidle =
- cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
- prcm_context.per_cm_autoidle =
- cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
- prcm_context.usbhost_cm_autoidle =
- cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
- prcm_context.sgx_cm_sleepdep =
- cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP);
- prcm_context.dss_cm_sleepdep =
- cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
- prcm_context.cam_cm_sleepdep =
- cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
- prcm_context.per_cm_sleepdep =
- cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
- prcm_context.usbhost_cm_sleepdep =
- cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
- prcm_context.cm_clkout_ctrl = cm_read_mod_reg(OMAP3430_CCR_MOD,
- OMAP3_CM_CLKOUT_CTRL_OFFSET);
- prcm_context.prm_clkout_ctrl = prm_read_mod_reg(OMAP3430_CCR_MOD,
- OMAP3_PRM_CLKOUT_CTRL_OFFSET);
- prcm_context.sgx_pm_wkdep =
- prm_read_mod_reg(OMAP3430ES2_SGX_MOD, PM_WKDEP);
- prcm_context.dss_pm_wkdep =
- prm_read_mod_reg(OMAP3430_DSS_MOD, PM_WKDEP);
- prcm_context.cam_pm_wkdep =
- prm_read_mod_reg(OMAP3430_CAM_MOD, PM_WKDEP);
- prcm_context.per_pm_wkdep =
- prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKDEP);
- prcm_context.neon_pm_wkdep =
- prm_read_mod_reg(OMAP3430_NEON_MOD, PM_WKDEP);
- prcm_context.usbhost_pm_wkdep =
- prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
- prcm_context.core_pm_mpugrpsel1 =
- prm_read_mod_reg(CORE_MOD, OMAP3430_PM_MPUGRPSEL1);
- prcm_context.iva2_pm_ivagrpsel1 =
- prm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_PM_IVAGRPSEL1);
- prcm_context.core_pm_mpugrpsel3 =
- prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3);
- prcm_context.core_pm_ivagrpsel3 =
- prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
- prcm_context.wkup_pm_mpugrpsel =
- prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
- prcm_context.wkup_pm_ivagrpsel =
- prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
- prcm_context.per_pm_mpugrpsel =
- prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
- prcm_context.per_pm_ivagrpsel =
- prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
- prcm_context.wkup_pm_wken = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
- return;
-}
-
-void omap3_prcm_restore_context(void)
-{
- omap_ctrl_writel(prcm_context.control_padconf_sys_nirq,
- OMAP343X_CONTROL_PADCONF_SYSNIRQ);
- cm_write_mod_reg(prcm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
- CM_CLKSEL1);
- cm_write_mod_reg(prcm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
- CM_CLKSEL2);
- __raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
- cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
- CM_CLKSEL);
- cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
- CM_CLKSEL);
- cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
- CM_CLKSEL);
- cm_write_mod_reg(prcm_context.per_cm_clksel, OMAP3430_PER_MOD,
- CM_CLKSEL);
- cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
- CM_CLKSEL1);
- cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
- CM_AUTOIDLE2);
- cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
- OMAP3430ES2_CM_CLKSEL4);
- cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
- OMAP3430ES2_CM_CLKSEL5);
- cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
- OMAP3430ES2_CM_CLKEN2);
- __raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
- cm_write_mod_reg(prcm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
- CM_FCLKEN);
- cm_write_mod_reg(prcm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
- OMAP3430_CM_CLKEN_PLL);
- cm_write_mod_reg(prcm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1);
- cm_write_mod_reg(prcm_context.core_cm_fclken3, CORE_MOD,
- OMAP3430ES2_CM_FCLKEN3);
- cm_write_mod_reg(prcm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
- CM_FCLKEN);
- cm_write_mod_reg(prcm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
- cm_write_mod_reg(prcm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
- CM_FCLKEN);
- cm_write_mod_reg(prcm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
- CM_FCLKEN);
- cm_write_mod_reg(prcm_context.per_cm_fclken, OMAP3430_PER_MOD,
- CM_FCLKEN);
- cm_write_mod_reg(prcm_context.usbhost_cm_fclken,
- OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
- cm_write_mod_reg(prcm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1);
- cm_write_mod_reg(prcm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2);
- cm_write_mod_reg(prcm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3);
- cm_write_mod_reg(prcm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
- CM_ICLKEN);
- cm_write_mod_reg(prcm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
- cm_write_mod_reg(prcm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
- CM_ICLKEN);
- cm_write_mod_reg(prcm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
- CM_ICLKEN);
- cm_write_mod_reg(prcm_context.per_cm_iclken, OMAP3430_PER_MOD,
- CM_ICLKEN);
- cm_write_mod_reg(prcm_context.usbhost_cm_iclken,
- OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
- cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
- CM_AUTOIDLE2);
- cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
- cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
- OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
- OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
- cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
- CM_AUTOIDLE1);
- cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
- CM_AUTOIDLE2);
- cm_write_mod_reg(prcm_context.core_cm_autoidle3, CORE_MOD,
- CM_AUTOIDLE3);
- cm_write_mod_reg(prcm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE);
- cm_write_mod_reg(prcm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
- CM_AUTOIDLE);
- cm_write_mod_reg(prcm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
- CM_AUTOIDLE);
- cm_write_mod_reg(prcm_context.per_cm_autoidle, OMAP3430_PER_MOD,
- CM_AUTOIDLE);
- cm_write_mod_reg(prcm_context.usbhost_cm_autoidle,
- OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
- cm_write_mod_reg(prcm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
- OMAP3430_CM_SLEEPDEP);
- cm_write_mod_reg(prcm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
- OMAP3430_CM_SLEEPDEP);
- cm_write_mod_reg(prcm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
- OMAP3430_CM_SLEEPDEP);
- cm_write_mod_reg(prcm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
- OMAP3430_CM_SLEEPDEP);
- cm_write_mod_reg(prcm_context.usbhost_cm_sleepdep,
- OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
- cm_write_mod_reg(prcm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
- OMAP3_CM_CLKOUT_CTRL_OFFSET);
- prm_write_mod_reg(prcm_context.prm_clkout_ctrl, OMAP3430_CCR_MOD,
- OMAP3_PRM_CLKOUT_CTRL_OFFSET);
- prm_write_mod_reg(prcm_context.sgx_pm_wkdep, OMAP3430ES2_SGX_MOD,
- PM_WKDEP);
- prm_write_mod_reg(prcm_context.dss_pm_wkdep, OMAP3430_DSS_MOD,
- PM_WKDEP);
- prm_write_mod_reg(prcm_context.cam_pm_wkdep, OMAP3430_CAM_MOD,
- PM_WKDEP);
- prm_write_mod_reg(prcm_context.per_pm_wkdep, OMAP3430_PER_MOD,
- PM_WKDEP);
- prm_write_mod_reg(prcm_context.neon_pm_wkdep, OMAP3430_NEON_MOD,
- PM_WKDEP);
- prm_write_mod_reg(prcm_context.usbhost_pm_wkdep,
- OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
- prm_write_mod_reg(prcm_context.core_pm_mpugrpsel1, CORE_MOD,
- OMAP3430_PM_MPUGRPSEL1);
- prm_write_mod_reg(prcm_context.iva2_pm_ivagrpsel1, OMAP3430_IVA2_MOD,
- OMAP3430_PM_IVAGRPSEL1);
- prm_write_mod_reg(prcm_context.core_pm_mpugrpsel3, CORE_MOD,
- OMAP3430ES2_PM_MPUGRPSEL3);
- prm_write_mod_reg(prcm_context.core_pm_ivagrpsel3, CORE_MOD,
- OMAP3430ES2_PM_IVAGRPSEL3);
- prm_write_mod_reg(prcm_context.wkup_pm_mpugrpsel, WKUP_MOD,
- OMAP3430_PM_MPUGRPSEL);
- prm_write_mod_reg(prcm_context.wkup_pm_ivagrpsel, WKUP_MOD,
- OMAP3430_PM_IVAGRPSEL);
- prm_write_mod_reg(prcm_context.per_pm_mpugrpsel, OMAP3430_PER_MOD,
- OMAP3430_PM_MPUGRPSEL);
- prm_write_mod_reg(prcm_context.per_pm_ivagrpsel, OMAP3430_PER_MOD,
- OMAP3430_PM_IVAGRPSEL);
- prm_write_mod_reg(prcm_context.wkup_pm_wken, WKUP_MOD, PM_WKEN);
- return;
-}
-#endif
diff --git a/arch/arm/mach-omap2/prcm44xx.h b/arch/arm/mach-omap2/prcm44xx.h
new file mode 100644
index 000000000000..7334ffb9d2c1
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm44xx.h
@@ -0,0 +1,42 @@
+/*
+ * OMAP4 PRCM definitions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains macros and functions that are common to all of
+ * the PRM/CM/PRCM blocks on the OMAP4 devices: PRM, CM1, CM2,
+ * PRCM_MPU, SCRM
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM44XX_H
+
+/*
+ * OMAP4 PRCM partition IDs
+ *
+ * The numbers and order are arbitrary, but 0 is reserved for the
+ * 'invalid' partition in case someone forgets to add a
+ * .prcm_partition field.
+ */
+#define OMAP4430_INVALID_PRCM_PARTITION 0
+#define OMAP4430_PRM_PARTITION 1
+#define OMAP4430_CM1_PARTITION 2
+#define OMAP4430_CM2_PARTITION 3
+#define OMAP4430_SCRM_PARTITION 4
+#define OMAP4430_PRCM_MPU_PARTITION 5
+
+/*
+ * OMAP4_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition
+ * IDs, plus one
+ */
+#define OMAP4_MAX_PRCM_PARTITIONS 6
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c
new file mode 100644
index 000000000000..171fe171a749
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.c
@@ -0,0 +1,45 @@
+/*
+ * OMAP4 PRCM_MPU module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "prcm_mpu44xx.h"
+#include "cm-regbits-44xx.h"
+
+/* PRCM_MPU low-level functions */
+
+u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_PRCM_MPU_REGADDR(inst, reg));
+}
+
+void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_PRCM_MPU_REGADDR(inst, reg));
+}
+
+u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
+{
+ u32 v;
+
+ v = omap4_prcm_mpu_read_inst_reg(inst, reg);
+ v &= ~mask;
+ v |= bits;
+ omap4_prcm_mpu_write_inst_reg(v, inst, reg);
+
+ return v;
+}
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h
new file mode 100644
index 000000000000..729a644ce852
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.h
@@ -0,0 +1,104 @@
+/*
+ * OMAP44xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
+
+#define OMAP4430_PRCM_MPU_BASE 0x48243000
+
+#define OMAP44XX_PRCM_MPU_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE + (inst) + (reg))
+
+/* PRCM_MPU instances */
+
+#define OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST 0x0000
+#define OMAP4430_PRCM_MPU_DEVICE_PRM_INST 0x0200
+#define OMAP4430_PRCM_MPU_CPU0_INST 0x0400
+#define OMAP4430_PRCM_MPU_CPU1_INST 0x0800
+
+/* PRCM_MPU clockdomain register offsets (from instance start) */
+#define OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS 0x0000
+#define OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS 0x0000
+
+
+/*
+ * PRCM_MPU
+ *
+ * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global)
+ * point of view the PRCM_MPU is a single entity. It shares the same
+ * programming model as the global PRCM and thus can be assimilate as two new
+ * MOD inside the PRCM
+ */
+
+/* PRCM_MPU.OCP_SOCKET_PRCM register offsets */
+#define OMAP4_REVISION_PRCM_OFFSET 0x0000
+#define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST, 0x0000)
+
+/* PRCM_MPU.DEVICE_PRM register offsets */
+#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000
+#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0000)
+#define OMAP4_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004
+#define OMAP4430_PRCM_MPU_PRM_PSCON_COUNT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0004)
+
+/* PRCM_MPU.CPU0 register offsets */
+#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0000)
+#define OMAP4_PM_CPU0_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0004)
+#define OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0008
+#define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0008)
+#define OMAP4_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x000c
+#define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x000c)
+#define OMAP4_RM_CPU0_CPU0_RSTST_OFFSET 0x0010
+#define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0010)
+#define OMAP4_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0014
+#define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0014)
+#define OMAP4_CM_CPU0_CLKSTCTRL_OFFSET 0x0018
+#define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0018)
+
+/* PRCM_MPU.CPU1 register offsets */
+#define OMAP4_PM_CPU1_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0000)
+#define OMAP4_PM_CPU1_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0004)
+#define OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0008
+#define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0008)
+#define OMAP4_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x000c
+#define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x000c)
+#define OMAP4_RM_CPU1_CPU1_RSTST_OFFSET 0x0010
+#define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0010)
+#define OMAP4_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0014
+#define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0014)
+#define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET 0x0018
+#define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0018)
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
+ s16 idx);
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h
index 0b188ffa710e..6ac966103f34 100644
--- a/arch/arm/mach-omap2/prm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -14,7 +14,7 @@
* published by the Free Software Foundation.
*/
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
/* Bits shared between registers */
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 9e63cb743a97..64c087af6a8b 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -1,6 +1,3 @@
-#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
-#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
-
/*
* OMAP3430 Power/Reset Management register bits
*
@@ -13,8 +10,11 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
+
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
/* Shared register bits */
@@ -101,8 +101,11 @@
#define OMAP3430_GRPSEL_MCSPI3_MASK (1 << 20)
#define OMAP3430_GRPSEL_MCSPI2_MASK (1 << 19)
#define OMAP3430_GRPSEL_MCSPI1_MASK (1 << 18)
+#define OMAP3430_GRPSEL_I2C3_SHIFT 17
#define OMAP3430_GRPSEL_I2C3_MASK (1 << 17)
+#define OMAP3430_GRPSEL_I2C2_SHIFT 16
#define OMAP3430_GRPSEL_I2C2_MASK (1 << 16)
+#define OMAP3430_GRPSEL_I2C1_SHIFT 15
#define OMAP3430_GRPSEL_I2C1_MASK (1 << 15)
#define OMAP3430_GRPSEL_UART2_MASK (1 << 14)
#define OMAP3430_GRPSEL_UART1_MASK (1 << 13)
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
index 25b19b610177..6d2776f6fc08 100644
--- a/arch/arm/mach-omap2/prm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -22,8 +22,6 @@
#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H
#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H
-#include "prm.h"
-
/*
* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 7be040b2fdab..39d562169d18 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -1,321 +1,20 @@
-#ifndef __ARCH_ARM_MACH_OMAP2_PRM_H
-#define __ARCH_ARM_MACH_OMAP2_PRM_H
-
/*
- * OMAP2/3 Power/Reset Management (PRM) register definitions
+ * OMAP2/3/4 Power/Reset Management (PRM) bitfield definitions
*
* Copyright (C) 2007-2009 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation
*
- * Written by Paul Walmsley
+ * Paul Walmsley
*
* This program is free software; you can 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 __ARCH_ARM_MACH_OMAP2_PRM_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_H
#include "prcm-common.h"
-#define OMAP2420_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
-#define OMAP2430_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
-#define OMAP34XX_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
-#define OMAP44XX_PRM_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (module) + (reg))
-#define OMAP44XX_PRCM_MPU_REGADDR(module, reg) \
- OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE + (module) + (reg))
-
-#include "prm44xx.h"
-
-/*
- * Architecture-specific global PRM registers
- * Use __raw_{read,write}l() with these registers.
- *
- * With a few exceptions, these are the register names beginning with
- * PRCM_* on 24xx, and PRM_* on 34xx. (The exceptions are the
- * IRQSTATUS and IRQENABLE bits.)
- *
- */
-
-#define OMAP2_PRCM_REVISION_OFFSET 0x0000
-#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
-#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
-
-#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
-#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
-#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
-
-#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
-#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
-#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
-#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
-#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
-#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
-#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
-#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
-#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
-#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
-#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
-#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
-#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
-#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
-#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
-#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
-#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
-#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
-#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
-
-#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
-
-#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
-
-#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
-#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
-#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
-#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
-#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
-#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
-#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
-#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
-#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
-#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
-
-#define OMAP3_PRM_REVISION_OFFSET 0x0004
-#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
-#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
-#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
-
-#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
-#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
-#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
-#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
-
-
-#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
-#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
-#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
-#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
-#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
-#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
-#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
-#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
-#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
-#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
-#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
-#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
-#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
-#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
-#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
-#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
-#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
-#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
-#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
-#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
-#define OMAP3_PRM_RSTST_OFFSET 0x0058
-#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
-#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
-#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
-#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
-#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
-#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
-#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
-#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
-#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
-#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
-#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
-#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
-#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
-#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
-#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
-#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
-#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
-#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
-#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
-#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
-#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
-#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
-#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
-#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
-#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
-#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
-#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
-#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
-#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
-#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
-#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
-#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
-#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
-#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
-#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
-#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
-#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
-#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
-#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
-#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
-#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
-
-#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
-#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
-#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
-#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
-
-/*
- * Module specific PRM registers from PRM_BASE + domain offset
- *
- * Use prm_{read,write}_mod_reg() with these registers.
- *
- * With a few exceptions, these are the register names beginning with
- * {PM,RM}_* on both architectures. (The exceptions are the IRQSTATUS
- * and IRQENABLE bits.)
- *
- */
-
-/* Registers appearing on both 24xx and 34xx */
-
-#define OMAP2_RM_RSTCTRL 0x0050
-#define OMAP2_RM_RSTTIME 0x0054
-#define OMAP2_RM_RSTST 0x0058
-#define OMAP2_PM_PWSTCTRL 0x00e0
-#define OMAP2_PM_PWSTST 0x00e4
-
-#define PM_WKEN 0x00a0
-#define PM_WKEN1 PM_WKEN
-#define PM_WKST 0x00b0
-#define PM_WKST1 PM_WKST
-#define PM_WKDEP 0x00c8
-#define PM_EVGENCTRL 0x00d4
-#define PM_EVGENONTIM 0x00d8
-#define PM_EVGENOFFTIM 0x00dc
-
-/* Omap2 specific registers */
-#define OMAP24XX_PM_WKEN2 0x00a4
-#define OMAP24XX_PM_WKST2 0x00b4
-
-#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
-#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
-#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
-#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
-
-/* Omap3 specific registers */
-#define OMAP3430ES2_PM_WKEN3 0x00f0
-#define OMAP3430ES2_PM_WKST3 0x00b8
-
-#define OMAP3430_PM_MPUGRPSEL 0x00a4
-#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
-#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
-
-#define OMAP3430_PM_IVAGRPSEL 0x00a8
-#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
-#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
-
-#define OMAP3430_PM_PREPWSTST 0x00e8
-
-#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
-#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
-
-/* Omap4 specific registers */
-#define OMAP4_RM_RSTCTRL 0x0000
-#define OMAP4_RM_RSTTIME 0x0004
-#define OMAP4_RM_RSTST 0x0008
-#define OMAP4_PM_PWSTCTRL 0x0000
-#define OMAP4_PM_PWSTST 0x0004
-
-
-#ifndef __ASSEMBLER__
-
-/* Power/reset management domain register get/set */
-extern u32 prm_read_mod_reg(s16 module, u16 idx);
-extern void prm_write_mod_reg(u32 val, s16 module, u16 idx);
-extern u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-
-/* Read-modify-write bits in a PRM register (by domain) */
-static inline u32 prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return prm_rmw_mod_reg_bits(bits, bits, module, idx);
-}
-
-static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
-{
- return prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
-}
-
-/* These omap2_ PRM functions apply to both OMAP2 and 3 */
-int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
-int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
-int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
-
-int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
-int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
-int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
-
-#endif
-
-/*
- * Bits common to specific registers
- *
- * The 3430 register and bit names are generally used,
- * since they tend to make more sense
- */
-
-/* PM_EVGENONTIM_MPU */
-/* Named PM_EVEGENONTIM_MPU on the 24XX */
-#define OMAP_ONTIMEVAL_SHIFT 0
-#define OMAP_ONTIMEVAL_MASK (0xffffffff << 0)
-
-/* PM_EVGENOFFTIM_MPU */
-/* Named PM_EVEGENOFFTIM_MPU on the 24XX */
-#define OMAP_OFFTIMEVAL_SHIFT 0
-#define OMAP_OFFTIMEVAL_MASK (0xffffffff << 0)
-
-/* PRM_CLKSETUP and PRCM_VOLTSETUP */
-/* Named PRCM_CLKSSETUP on the 24XX */
-#define OMAP_SETUP_TIME_SHIFT 0
-#define OMAP_SETUP_TIME_MASK (0xffff << 0)
-
-/* PRM_CLKSRC_CTRL */
-/* Named PRCM_CLKSRC_CTRL on the 24XX */
-#define OMAP_SYSCLKDIV_SHIFT 6
-#define OMAP_SYSCLKDIV_MASK (0x3 << 6)
-#define OMAP_AUTOEXTCLKMODE_SHIFT 3
-#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3)
-#define OMAP_SYSCLKSEL_SHIFT 0
-#define OMAP_SYSCLKSEL_MASK (0x3 << 0)
-
-/* PM_EVGENCTRL_MPU */
-#define OMAP_OFFLOADMODE_SHIFT 3
-#define OMAP_OFFLOADMODE_MASK (0x3 << 3)
-#define OMAP_ONLOADMODE_SHIFT 1
-#define OMAP_ONLOADMODE_MASK (0x3 << 1)
-#define OMAP_ENABLE_MASK (1 << 0)
-
-/* PRM_RSTTIME */
-/* Named RM_RSTTIME_WKUP on the 24xx */
-#define OMAP_RSTTIME2_SHIFT 8
-#define OMAP_RSTTIME2_MASK (0x1f << 8)
-#define OMAP_RSTTIME1_SHIFT 0
-#define OMAP_RSTTIME1_MASK (0xff << 0)
-
-/* PRM_RSTCTRL */
-/* Named RM_RSTCTRL_WKUP on the 24xx */
-/* 2420 calls RST_DPLL3 'RST_DPLL' */
-#define OMAP_RST_DPLL3_MASK (1 << 2)
-#define OMAP_RST_GS_MASK (1 << 1)
-
-
-/*
- * Bits common to module-shared registers
- *
- * Not all registers of a particular type support all of these bits -
- * check TRM if you are unsure
- */
-
/*
* 24XX: PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP
*
@@ -341,59 +40,6 @@ int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
#define OMAP_POWERSTATEST_MASK (0x3 << 0)
/*
- * 24XX: RM_RSTST_MPU and RM_RSTST_DSP - on 24XX, 'COREDOMAINWKUP_RST' is
- * called 'COREWKUP_RST'
- *
- * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS,
- * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON
- */
-#define OMAP_COREDOMAINWKUP_RST_MASK (1 << 3)
-
-/*
- * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP
- *
- * 2430: RM_RSTST_MDM
- *
- * 3430: RM_RSTST_CORE, RM_RSTST_EMU
- */
-#define OMAP_DOMAINWKUP_RST_MASK (1 << 2)
-
-/*
- * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP
- * On 24XX, 'GLOBALWARM_RST' is called 'GLOBALWMPU_RST'.
- *
- * 2430: RM_RSTST_MDM
- *
- * 3430: RM_RSTST_CORE, RM_RSTST_EMU
- */
-#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
-#define OMAP_GLOBALCOLD_RST_MASK (1 << 0)
-
-/*
- * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP
- * 2420 TRM sometimes uses "EN_WAKEUP" instead of "EN_WKUP"
- *
- * 2430: PM_WKDEP_MDM
- *
- * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM,
- * PM_WKDEP_PER
- */
-#define OMAP_EN_WKUP_SHIFT 4
-#define OMAP_EN_WKUP_MASK (1 << 4)
-
-/*
- * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
- * PM_PWSTCTRL_DSP
- *
- * 2430: PM_PWSTCTRL_MDM
- *
- * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
- * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER,
- * PM_PWSTCTRL_NEON
- */
-#define OMAP_LOGICRETSTATE_MASK (1 << 2)
-
-/*
* 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
* PM_PWSTCTRL_DSP, PM_PWSTST_MPU
*
@@ -407,11 +53,4 @@ int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
#define OMAP_POWERSTATE_MASK (0x3 << 0)
-/*
- * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
- * submodule to exit hardreset
- */
-#define MAX_MODULE_HARDRESET_WAIT 10000
-
-
#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 421771eee450..ec0362574b5e 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -12,18 +12,65 @@
*/
#include <linux/kernel.h>
-#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/io.h>
#include <plat/common.h>
#include <plat/cpu.h>
#include <plat/prcm.h>
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
#include "prm-regbits-34xx.h"
+u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(prm_base + module + idx);
+}
+
+void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, prm_base + module + idx);
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_prm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+
/**
* omap2_prm_is_hardreset_asserted - read the HW reset line state of
* submodules contained in the hwmod module
@@ -39,7 +86,7 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
return -EINVAL;
- return prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
+ return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
(1 << shift));
}
@@ -63,7 +110,7 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
return -EINVAL;
mask = 1 << shift;
- prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
+ omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
return 0;
}
@@ -93,18 +140,17 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
mask = 1 << shift;
/* Check the current status to avoid de-asserting the line twice */
- if (prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0)
+ if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0)
return -EEXIST;
/* Clear the reset status by writing 1 to the status bit */
- prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST);
+ omap2_prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST);
/* de-assert the reset control line */
- prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL);
+ omap2_prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL);
/* wait the status to be set */
- omap_test_timeout(prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
+ omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
mask),
MAX_MODULE_HARDRESET_WAIT, c);
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
-
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
new file mode 100644
index 000000000000..53d44f6e3736
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -0,0 +1,367 @@
+/*
+ * OMAP2/3 Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 PRM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The PRM on OMAP4 has a new register layout, and is handled
+ * in a separate file.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+
+#define OMAP2420_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
+#define OMAP2430_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
+#define OMAP34XX_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP2-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ *
+ */
+
+#define OMAP2_PRCM_REVISION_OFFSET 0x0000
+#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
+#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
+#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
+#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
+#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
+#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
+#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
+#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
+#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
+#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
+#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
+
+#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
+
+/*
+ * OMAP3-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ */
+
+#define OMAP3_PRM_REVISION_OFFSET 0x0004
+#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
+#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
+#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
+
+#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
+
+
+#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
+#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
+#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
+#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
+#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
+#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
+#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
+#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
+#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
+#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
+#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
+#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
+#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
+#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
+#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
+#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
+#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
+#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
+#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
+#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
+#define OMAP3_PRM_RSTST_OFFSET 0x0058
+#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
+#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
+#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
+#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
+#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
+#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
+#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
+#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
+#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
+#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
+#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
+#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
+#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
+#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
+#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
+#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
+#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
+#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
+#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
+#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
+#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
+#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
+#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
+#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
+#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
+#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
+#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
+#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
+#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
+#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
+#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
+#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
+#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
+#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
+#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
+#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
+#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
+#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
+#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
+#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
+
+#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
+#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
+#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific PRM register offsets from PRM_BASE + domain offset
+ *
+ * Use prm_{read,write}_mod_reg() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the
+ * IRQSTATUS and IRQENABLE bits.)
+ */
+
+/* Register offsets appearing on both OMAP2 and OMAP3 */
+
+#define OMAP2_RM_RSTCTRL 0x0050
+#define OMAP2_RM_RSTTIME 0x0054
+#define OMAP2_RM_RSTST 0x0058
+#define OMAP2_PM_PWSTCTRL 0x00e0
+#define OMAP2_PM_PWSTST 0x00e4
+
+#define PM_WKEN 0x00a0
+#define PM_WKEN1 PM_WKEN
+#define PM_WKST 0x00b0
+#define PM_WKST1 PM_WKST
+#define PM_WKDEP 0x00c8
+#define PM_EVGENCTRL 0x00d4
+#define PM_EVGENONTIM 0x00d8
+#define PM_EVGENOFFTIM 0x00dc
+
+/* OMAP2xxx specific register offsets */
+#define OMAP24XX_PM_WKEN2 0x00a4
+#define OMAP24XX_PM_WKST2 0x00b4
+
+#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
+#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
+#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
+#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
+
+/* OMAP3 specific register offsets */
+#define OMAP3430ES2_PM_WKEN3 0x00f0
+#define OMAP3430ES2_PM_WKST3 0x00b8
+
+#define OMAP3430_PM_MPUGRPSEL 0x00a4
+#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
+#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
+
+#define OMAP3430_PM_IVAGRPSEL 0x00a8
+#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
+#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
+
+#define OMAP3430_PM_PREPWSTST 0x00e8
+
+#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
+#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
+
+
+#ifndef __ASSEMBLER__
+
+/* Power/reset management domain register get/set */
+extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
+extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+
+/* These omap2_ PRM functions apply to both OMAP2 and 3 */
+extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
+extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
+extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
+
+#endif
+
+/*
+ * Bits common to specific registers
+ *
+ * The 3430 register and bit names are generally used,
+ * since they tend to make more sense
+ */
+
+/* PM_EVGENONTIM_MPU */
+/* Named PM_EVEGENONTIM_MPU on the 24XX */
+#define OMAP_ONTIMEVAL_SHIFT 0
+#define OMAP_ONTIMEVAL_MASK (0xffffffff << 0)
+
+/* PM_EVGENOFFTIM_MPU */
+/* Named PM_EVEGENOFFTIM_MPU on the 24XX */
+#define OMAP_OFFTIMEVAL_SHIFT 0
+#define OMAP_OFFTIMEVAL_MASK (0xffffffff << 0)
+
+/* PRM_CLKSETUP and PRCM_VOLTSETUP */
+/* Named PRCM_CLKSSETUP on the 24XX */
+#define OMAP_SETUP_TIME_SHIFT 0
+#define OMAP_SETUP_TIME_MASK (0xffff << 0)
+
+/* PRM_CLKSRC_CTRL */
+/* Named PRCM_CLKSRC_CTRL on the 24XX */
+#define OMAP_SYSCLKDIV_SHIFT 6
+#define OMAP_SYSCLKDIV_MASK (0x3 << 6)
+#define OMAP_AUTOEXTCLKMODE_SHIFT 3
+#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3)
+#define OMAP_SYSCLKSEL_SHIFT 0
+#define OMAP_SYSCLKSEL_MASK (0x3 << 0)
+
+/* PM_EVGENCTRL_MPU */
+#define OMAP_OFFLOADMODE_SHIFT 3
+#define OMAP_OFFLOADMODE_MASK (0x3 << 3)
+#define OMAP_ONLOADMODE_SHIFT 1
+#define OMAP_ONLOADMODE_MASK (0x3 << 1)
+#define OMAP_ENABLE_MASK (1 << 0)
+
+/* PRM_RSTTIME */
+/* Named RM_RSTTIME_WKUP on the 24xx */
+#define OMAP_RSTTIME2_SHIFT 8
+#define OMAP_RSTTIME2_MASK (0x1f << 8)
+#define OMAP_RSTTIME1_SHIFT 0
+#define OMAP_RSTTIME1_MASK (0xff << 0)
+
+/* PRM_RSTCTRL */
+/* Named RM_RSTCTRL_WKUP on the 24xx */
+/* 2420 calls RST_DPLL3 'RST_DPLL' */
+#define OMAP_RST_DPLL3_MASK (1 << 2)
+#define OMAP_RST_GS_MASK (1 << 1)
+
+
+/*
+ * Bits common to module-shared registers
+ *
+ * Not all registers of a particular type support all of these bits -
+ * check TRM if you are unsure
+ */
+
+/*
+ * 24XX: RM_RSTST_MPU and RM_RSTST_DSP - on 24XX, 'COREDOMAINWKUP_RST' is
+ * called 'COREWKUP_RST'
+ *
+ * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS,
+ * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON
+ */
+#define OMAP_COREDOMAINWKUP_RST_MASK (1 << 3)
+
+/*
+ * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP
+ *
+ * 2430: RM_RSTST_MDM
+ *
+ * 3430: RM_RSTST_CORE, RM_RSTST_EMU
+ */
+#define OMAP_DOMAINWKUP_RST_MASK (1 << 2)
+
+/*
+ * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP
+ * On 24XX, 'GLOBALWARM_RST' is called 'GLOBALWMPU_RST'.
+ *
+ * 2430: RM_RSTST_MDM
+ *
+ * 3430: RM_RSTST_CORE, RM_RSTST_EMU
+ */
+#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
+#define OMAP_GLOBALCOLD_RST_MASK (1 << 0)
+
+/*
+ * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP
+ * 2420 TRM sometimes uses "EN_WAKEUP" instead of "EN_WKUP"
+ *
+ * 2430: PM_WKDEP_MDM
+ *
+ * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM,
+ * PM_WKDEP_PER
+ */
+#define OMAP_EN_WKUP_SHIFT 4
+#define OMAP_EN_WKUP_MASK (1 << 4)
+
+/*
+ * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
+ * PM_PWSTCTRL_DSP
+ *
+ * 2430: PM_PWSTCTRL_MDM
+ *
+ * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
+ * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER,
+ * PM_PWSTCTRL_NEON
+ */
+#define OMAP_LOGICRETSTATE_MASK (1 << 2)
+
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index a1ff918d9bed..a2a04bfa9628 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -15,12 +15,13 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/io.h>
#include <plat/common.h>
#include <plat/cpu.h>
#include <plat/prcm.h>
-#include "prm.h"
+#include "prm44xx.h"
#include "prm-regbits-44xx.h"
/*
@@ -29,6 +30,70 @@
*/
#define OMAP4_RST_CTRL_ST_OFFSET 4
+/* PRM low-level functions */
+
+/* Read a register in a CM/PRM instance in the PRM module */
+u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_PRM_REGADDR(inst, reg));
+}
+
+/* Write into a register in a CM/PRM instance in the PRM module */
+void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_PRM_REGADDR(inst, reg));
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
+{
+ u32 v;
+
+ v = omap4_prm_read_inst_reg(inst, reg);
+ v &= ~mask;
+ v |= bits;
+ omap4_prm_write_inst_reg(v, inst, reg);
+
+ return v;
+}
+
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+/* XXX deprecated */
+u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+/* XXX deprecated */
+u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= ~mask;
+ v |= bits;
+ __raw_writel(v, reg);
+
+ return v;
+}
+
+u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 reg)
+{
+ return omap4_prm_rmw_inst_reg_bits(bits, bits, inst, reg);
+}
+
+u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
+{
+ return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
+}
+
/**
* omap4_prm_is_hardreset_asserted - read the HW reset line state of
* submodules contained in the hwmod module
@@ -114,3 +179,17 @@ int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
+void omap4_prm_global_warm_sw_reset(void)
+{
+ u32 v;
+
+ v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+ v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
+ omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+
+ /* OCP barrier */
+ v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+}
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 59839dbabd84..67a0d3feb3f6 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -17,736 +17,762 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
*/
#ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_H
#define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
+#include "prcm-common.h"
+#include "prm.h"
+
+#define OMAP4430_PRM_BASE 0x4a306000
+
+#define OMAP44XX_PRM_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define OMAP4430_PRM_OCP_SOCKET_INST 0x0000
+#define OMAP4430_PRM_CKGEN_INST 0x0100
+#define OMAP4430_PRM_MPU_INST 0x0300
+#define OMAP4430_PRM_TESLA_INST 0x0400
+#define OMAP4430_PRM_ABE_INST 0x0500
+#define OMAP4430_PRM_ALWAYS_ON_INST 0x0600
+#define OMAP4430_PRM_CORE_INST 0x0700
+#define OMAP4430_PRM_IVAHD_INST 0x0f00
+#define OMAP4430_PRM_CAM_INST 0x1000
+#define OMAP4430_PRM_DSS_INST 0x1100
+#define OMAP4430_PRM_GFX_INST 0x1200
+#define OMAP4430_PRM_L3INIT_INST 0x1300
+#define OMAP4430_PRM_L4PER_INST 0x1400
+#define OMAP4430_PRM_CEFUSE_INST 0x1600
+#define OMAP4430_PRM_WKUP_INST 0x1700
+#define OMAP4430_PRM_WKUP_CM_INST 0x1800
+#define OMAP4430_PRM_EMU_INST 0x1900
+#define OMAP4430_PRM_EMU_CM_INST 0x1a00
+#define OMAP4430_PRM_DEVICE_INST 0x1b00
+#define OMAP4430_PRM_INSTR_INST 0x1f00
+
+/* PRM clockdomain register offsets (from instance start) */
+#define OMAP4430_PRM_MPU_MPU_CDOFFS 0x0000
+#define OMAP4430_PRM_TESLA_TESLA_CDOFFS 0x0000
+#define OMAP4430_PRM_ABE_ABE_CDOFFS 0x0000
+#define OMAP4430_PRM_CORE_CORE_CDOFFS 0x0000
+#define OMAP4430_PRM_IVAHD_IVAHD_CDOFFS 0x0000
+#define OMAP4430_PRM_CAM_CAM_CDOFFS 0x0000
+#define OMAP4430_PRM_DSS_DSS_CDOFFS 0x0000
+#define OMAP4430_PRM_GFX_GFX_CDOFFS 0x0000
+#define OMAP4430_PRM_L3INIT_L3INIT_CDOFFS 0x0000
+#define OMAP4430_PRM_L4PER_L4PER_CDOFFS 0x0000
+#define OMAP4430_PRM_CEFUSE_CEFUSE_CDOFFS 0x0000
+#define OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS 0x0000
+#define OMAP4430_PRM_EMU_EMU_CDOFFS 0x0000
+#define OMAP4430_PRM_EMU_CM_EMU_CDOFFS 0x0000
+
+/* OMAP4 specific register offsets */
+#define OMAP4_RM_RSTCTRL 0x0000
+#define OMAP4_RM_RSTTIME 0x0004
+#define OMAP4_RM_RSTST 0x0008
+#define OMAP4_PM_PWSTCTRL 0x0000
+#define OMAP4_PM_PWSTST 0x0004
+
/* PRM */
/* PRM.OCP_SOCKET_PRM register offsets */
#define OMAP4_REVISION_PRM_OFFSET 0x0000
-#define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0000)
+#define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0000)
#define OMAP4_PRM_IRQSTATUS_MPU_OFFSET 0x0010
-#define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0010)
+#define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0010)
#define OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014
-#define OMAP4430_PRM_IRQSTATUS_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0014)
+#define OMAP4430_PRM_IRQSTATUS_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0014)
#define OMAP4_PRM_IRQENABLE_MPU_OFFSET 0x0018
-#define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0018)
+#define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0018)
#define OMAP4_PRM_IRQENABLE_MPU_2_OFFSET 0x001c
-#define OMAP4430_PRM_IRQENABLE_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x001c)
+#define OMAP4430_PRM_IRQENABLE_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x001c)
#define OMAP4_PRM_IRQSTATUS_DUCATI_OFFSET 0x0020
-#define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0020)
+#define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0020)
#define OMAP4_PRM_IRQENABLE_DUCATI_OFFSET 0x0028
-#define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0028)
+#define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0028)
#define OMAP4_PRM_IRQSTATUS_TESLA_OFFSET 0x0030
-#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0030)
+#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0030)
#define OMAP4_PRM_IRQENABLE_TESLA_OFFSET 0x0038
-#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0038)
+#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0038)
#define OMAP4_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0040)
+#define OMAP4430_CM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0040)
/* PRM.CKGEN_PRM register offsets */
#define OMAP4_CM_ABE_DSS_SYS_CLKSEL_OFFSET 0x0000
-#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0000)
+#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0000)
#define OMAP4_CM_L4_WKUP_CLKSEL_OFFSET 0x0008
-#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0008)
+#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0008)
#define OMAP4_CM_ABE_PLL_REF_CLKSEL_OFFSET 0x000c
-#define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x000c)
+#define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x000c)
#define OMAP4_CM_SYS_CLKSEL_OFFSET 0x0010
-#define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0010)
+#define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0010)
/* PRM.MPU_PRM register offsets */
#define OMAP4_PM_MPU_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0000)
+#define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0000)
#define OMAP4_PM_MPU_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0004)
+#define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0004)
#define OMAP4_RM_MPU_RSTST_OFFSET 0x0014
-#define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0014)
+#define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0014)
#define OMAP4_RM_MPU_MPU_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0024)
+#define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0024)
/* PRM.TESLA_PRM register offsets */
#define OMAP4_PM_TESLA_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0000)
+#define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0000)
#define OMAP4_PM_TESLA_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0004)
+#define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0004)
#define OMAP4_RM_TESLA_RSTCTRL_OFFSET 0x0010
-#define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0010)
+#define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0010)
#define OMAP4_RM_TESLA_RSTST_OFFSET 0x0014
-#define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0014)
+#define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0014)
#define OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0024)
+#define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0024)
/* PRM.ABE_PRM register offsets */
#define OMAP4_PM_ABE_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0000)
+#define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0000)
#define OMAP4_PM_ABE_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0004)
+#define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0004)
#define OMAP4_RM_ABE_AESS_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x002c)
+#define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x002c)
#define OMAP4_PM_ABE_PDM_WKDEP_OFFSET 0x0030
-#define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0030)
+#define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0030)
#define OMAP4_RM_ABE_PDM_CONTEXT_OFFSET 0x0034
-#define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0034)
+#define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0034)
#define OMAP4_PM_ABE_DMIC_WKDEP_OFFSET 0x0038
-#define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0038)
+#define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0038)
#define OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c
-#define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x003c)
+#define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x003c)
#define OMAP4_PM_ABE_MCASP_WKDEP_OFFSET 0x0040
-#define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0040)
+#define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0040)
#define OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044
-#define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0044)
+#define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0044)
#define OMAP4_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048
-#define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0048)
+#define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0048)
#define OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c
-#define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x004c)
+#define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x004c)
#define OMAP4_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050
-#define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0050)
+#define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0050)
#define OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054
-#define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0054)
+#define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0054)
#define OMAP4_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058
-#define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0058)
+#define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0058)
#define OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c
-#define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x005c)
+#define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x005c)
#define OMAP4_PM_ABE_SLIMBUS_WKDEP_OFFSET 0x0060
-#define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0060)
+#define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0060)
#define OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET 0x0064
-#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0064)
+#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0064)
#define OMAP4_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068
-#define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0068)
+#define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0068)
#define OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c
-#define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x006c)
+#define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x006c)
#define OMAP4_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070
-#define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0070)
+#define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0070)
#define OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074
-#define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0074)
+#define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0074)
#define OMAP4_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078
-#define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0078)
+#define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0078)
#define OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c
-#define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x007c)
+#define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x007c)
#define OMAP4_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080
-#define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0080)
+#define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0080)
#define OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084
-#define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0084)
+#define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0084)
#define OMAP4_PM_ABE_WDT3_WKDEP_OFFSET 0x0088
-#define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0088)
+#define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0088)
#define OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET 0x008c
-#define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x008c)
+#define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x008c)
/* PRM.ALWAYS_ON_PRM register offsets */
#define OMAP4_RM_ALWON_MDMINTC_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0024)
+#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0024)
#define OMAP4_PM_ALWON_SR_MPU_WKDEP_OFFSET 0x0028
-#define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0028)
+#define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0028)
#define OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x002c)
+#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x002c)
#define OMAP4_PM_ALWON_SR_IVA_WKDEP_OFFSET 0x0030
-#define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0030)
+#define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0030)
#define OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET 0x0034
-#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0034)
+#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0034)
#define OMAP4_PM_ALWON_SR_CORE_WKDEP_OFFSET 0x0038
-#define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0038)
+#define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0038)
#define OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET 0x003c
-#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x003c)
+#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x003c)
/* PRM.CORE_PRM register offsets */
#define OMAP4_PM_CORE_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0000)
+#define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0000)
#define OMAP4_PM_CORE_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0004)
+#define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0004)
#define OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0024)
+#define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0024)
#define OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET 0x0124
-#define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0124)
+#define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0124)
#define OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET 0x012c
-#define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x012c)
+#define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x012c)
#define OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET 0x0134
-#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0134)
+#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0134)
#define OMAP4_RM_DUCATI_RSTCTRL_OFFSET 0x0210
-#define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0210)
+#define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0210)
#define OMAP4_RM_DUCATI_RSTST_OFFSET 0x0214
-#define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0214)
+#define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0214)
#define OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET 0x0224
-#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0224)
+#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0224)
#define OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET 0x0324
-#define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0324)
+#define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0324)
#define OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET 0x0424
-#define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0424)
+#define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0424)
#define OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET 0x042c
-#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x042c)
+#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x042c)
#define OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET 0x0434
-#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0434)
+#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0434)
#define OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET 0x043c
-#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x043c)
+#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x043c)
#define OMAP4_RM_MEMIF_DLL_CONTEXT_OFFSET 0x0444
-#define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0444)
+#define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0444)
#define OMAP4_RM_MEMIF_EMIF_H1_CONTEXT_OFFSET 0x0454
-#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0454)
+#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0454)
#define OMAP4_RM_MEMIF_EMIF_H2_CONTEXT_OFFSET 0x045c
-#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x045c)
+#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x045c)
#define OMAP4_RM_MEMIF_DLL_H_CONTEXT_OFFSET 0x0464
-#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0464)
+#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0464)
#define OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET 0x0524
-#define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0524)
-#define OMAP4_RM_D2D_MODEM_ICR_CONTEXT_OFFSET 0x052c
-#define OMAP4430_RM_D2D_MODEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x052c)
+#define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0524)
+#define OMAP4_RM_D2D_INSTEM_ICR_CONTEXT_OFFSET 0x052c
+#define OMAP4430_RM_D2D_INSTEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x052c)
#define OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET 0x0534
-#define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0534)
+#define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0534)
#define OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624
-#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0624)
+#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0624)
#define OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET 0x062c
-#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x062c)
+#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x062c)
#define OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634
-#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0634)
+#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0634)
#define OMAP4_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c
-#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x063c)
+#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x063c)
#define OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET 0x0724
-#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0724)
+#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0724)
#define OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c
-#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x072c)
+#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x072c)
#define OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET 0x0744
-#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0744)
+#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0744)
/* PRM.IVAHD_PRM register offsets */
#define OMAP4_PM_IVAHD_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0000)
+#define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0000)
#define OMAP4_PM_IVAHD_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0004)
+#define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0004)
#define OMAP4_RM_IVAHD_RSTCTRL_OFFSET 0x0010
-#define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0010)
+#define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0010)
#define OMAP4_RM_IVAHD_RSTST_OFFSET 0x0014
-#define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0014)
+#define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0014)
#define OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0024)
+#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0024)
#define OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x002c)
+#define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x002c)
/* PRM.CAM_PRM register offsets */
#define OMAP4_PM_CAM_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0000)
+#define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0000)
#define OMAP4_PM_CAM_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0004)
+#define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0004)
#define OMAP4_RM_CAM_ISS_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0024)
+#define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0024)
#define OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x002c)
+#define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x002c)
/* PRM.DSS_PRM register offsets */
#define OMAP4_PM_DSS_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0000)
+#define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0000)
#define OMAP4_PM_DSS_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0004)
+#define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0004)
#define OMAP4_PM_DSS_DSS_WKDEP_OFFSET 0x0020
-#define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0020)
+#define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0020)
#define OMAP4_RM_DSS_DSS_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0024)
+#define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0024)
#define OMAP4_RM_DSS_DEISS_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x002c)
+#define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x002c)
/* PRM.GFX_PRM register offsets */
#define OMAP4_PM_GFX_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0000)
+#define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0000)
#define OMAP4_PM_GFX_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0004)
+#define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0004)
#define OMAP4_RM_GFX_GFX_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0024)
+#define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0024)
/* PRM.L3INIT_PRM register offsets */
#define OMAP4_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0000)
+#define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0000)
#define OMAP4_PM_L3INIT_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0004)
+#define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0004)
#define OMAP4_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028
-#define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0028)
+#define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0028)
#define OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x002c)
+#define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x002c)
#define OMAP4_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030
-#define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0030)
+#define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0030)
#define OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034
-#define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0034)
+#define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0034)
#define OMAP4_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038
-#define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0038)
+#define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0038)
#define OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c
-#define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x003c)
+#define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x003c)
#define OMAP4_PM_L3INIT_UNIPRO1_WKDEP_OFFSET 0x0040
-#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0040)
+#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0040)
#define OMAP4_RM_L3INIT_UNIPRO1_CONTEXT_OFFSET 0x0044
-#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0044)
+#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0044)
#define OMAP4_PM_L3INIT_USB_HOST_WKDEP_OFFSET 0x0058
-#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0058)
+#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0058)
#define OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET 0x005c
-#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x005c)
+#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x005c)
#define OMAP4_PM_L3INIT_USB_OTG_WKDEP_OFFSET 0x0060
-#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0060)
+#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0060)
#define OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET 0x0064
-#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0064)
+#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0064)
#define OMAP4_PM_L3INIT_USB_TLL_WKDEP_OFFSET 0x0068
-#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0068)
+#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0068)
#define OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET 0x006c
-#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x006c)
+#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x006c)
#define OMAP4_RM_L3INIT_P1500_CONTEXT_OFFSET 0x007c
-#define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x007c)
+#define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x007c)
#define OMAP4_RM_L3INIT_EMAC_CONTEXT_OFFSET 0x0084
-#define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0084)
+#define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0084)
#define OMAP4_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088
-#define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0088)
+#define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0088)
#define OMAP4_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c
-#define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x008c)
+#define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x008c)
#define OMAP4_RM_L3INIT_TPPSS_CONTEXT_OFFSET 0x0094
-#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0094)
+#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0094)
#define OMAP4_PM_L3INIT_PCIESS_WKDEP_OFFSET 0x0098
-#define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0098)
+#define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0098)
#define OMAP4_RM_L3INIT_PCIESS_CONTEXT_OFFSET 0x009c
-#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x009c)
+#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x009c)
#define OMAP4_RM_L3INIT_CCPTX_CONTEXT_OFFSET 0x00ac
-#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00ac)
+#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00ac)
#define OMAP4_PM_L3INIT_XHPI_WKDEP_OFFSET 0x00c0
-#define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c0)
+#define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c0)
#define OMAP4_RM_L3INIT_XHPI_CONTEXT_OFFSET 0x00c4
-#define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c4)
+#define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c4)
#define OMAP4_PM_L3INIT_MMC6_WKDEP_OFFSET 0x00c8
-#define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c8)
+#define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c8)
#define OMAP4_RM_L3INIT_MMC6_CONTEXT_OFFSET 0x00cc
-#define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00cc)
+#define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00cc)
#define OMAP4_PM_L3INIT_USB_HOST_FS_WKDEP_OFFSET 0x00d0
-#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d0)
+#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d0)
#define OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET 0x00d4
-#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d4)
+#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d4)
#define OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET 0x00e4
-#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00e4)
+#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00e4)
/* PRM.L4PER_PRM register offsets */
#define OMAP4_PM_L4PER_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0000)
+#define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0000)
#define OMAP4_PM_L4PER_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0004)
+#define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0004)
#define OMAP4_RM_L4PER_ADC_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0024)
+#define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0024)
#define OMAP4_PM_L4PER_DMTIMER10_WKDEP_OFFSET 0x0028
-#define OMAP4430_PM_L4PER_DMTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0028)
+#define OMAP4430_PM_L4PER_DMTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0028)
#define OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x002c)
+#define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x002c)
#define OMAP4_PM_L4PER_DMTIMER11_WKDEP_OFFSET 0x0030
-#define OMAP4430_PM_L4PER_DMTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0030)
+#define OMAP4430_PM_L4PER_DMTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0030)
#define OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET 0x0034
-#define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0034)
+#define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0034)
#define OMAP4_PM_L4PER_DMTIMER2_WKDEP_OFFSET 0x0038
-#define OMAP4430_PM_L4PER_DMTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0038)
+#define OMAP4430_PM_L4PER_DMTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0038)
#define OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET 0x003c
-#define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x003c)
+#define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x003c)
#define OMAP4_PM_L4PER_DMTIMER3_WKDEP_OFFSET 0x0040
-#define OMAP4430_PM_L4PER_DMTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0040)
+#define OMAP4430_PM_L4PER_DMTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0040)
#define OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET 0x0044
-#define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0044)
+#define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0044)
#define OMAP4_PM_L4PER_DMTIMER4_WKDEP_OFFSET 0x0048
-#define OMAP4430_PM_L4PER_DMTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0048)
+#define OMAP4430_PM_L4PER_DMTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0048)
#define OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET 0x004c
-#define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x004c)
+#define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x004c)
#define OMAP4_PM_L4PER_DMTIMER9_WKDEP_OFFSET 0x0050
-#define OMAP4430_PM_L4PER_DMTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0050)
+#define OMAP4430_PM_L4PER_DMTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0050)
#define OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET 0x0054
-#define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0054)
+#define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0054)
#define OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c
-#define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x005c)
+#define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x005c)
#define OMAP4_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060
-#define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0060)
+#define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0060)
#define OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064
-#define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0064)
+#define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0064)
#define OMAP4_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068
-#define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0068)
+#define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0068)
#define OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c
-#define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x006c)
+#define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x006c)
#define OMAP4_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070
-#define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0070)
+#define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0070)
#define OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074
-#define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0074)
+#define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0074)
#define OMAP4_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078
-#define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0078)
+#define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0078)
#define OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c
-#define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x007c)
+#define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x007c)
#define OMAP4_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080
-#define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0080)
+#define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0080)
#define OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084
-#define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0084)
+#define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0084)
#define OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c
-#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x008c)
+#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x008c)
#define OMAP4_PM_L4PER_HECC1_WKDEP_OFFSET 0x0090
-#define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0090)
+#define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0090)
#define OMAP4_RM_L4PER_HECC1_CONTEXT_OFFSET 0x0094
-#define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0094)
+#define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0094)
#define OMAP4_PM_L4PER_HECC2_WKDEP_OFFSET 0x0098
-#define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0098)
+#define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0098)
#define OMAP4_RM_L4PER_HECC2_CONTEXT_OFFSET 0x009c
-#define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x009c)
+#define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x009c)
#define OMAP4_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0
-#define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a0)
+#define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a0)
#define OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4
-#define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a4)
+#define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a4)
#define OMAP4_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8
-#define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a8)
+#define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a8)
#define OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac
-#define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ac)
+#define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ac)
#define OMAP4_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0
-#define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b0)
+#define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b0)
#define OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4
-#define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b4)
+#define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b4)
#define OMAP4_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8
-#define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b8)
+#define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b8)
#define OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc
-#define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00bc)
+#define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00bc)
#define OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x00c0
-#define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00c0)
+#define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00c0)
#define OMAP4_PM_L4PER_MCASP2_WKDEP_OFFSET 0x00d0
-#define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d0)
+#define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d0)
#define OMAP4_RM_L4PER_MCASP2_CONTEXT_OFFSET 0x00d4
-#define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d4)
+#define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d4)
#define OMAP4_PM_L4PER_MCASP3_WKDEP_OFFSET 0x00d8
-#define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d8)
+#define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d8)
#define OMAP4_RM_L4PER_MCASP3_CONTEXT_OFFSET 0x00dc
-#define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00dc)
+#define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00dc)
#define OMAP4_PM_L4PER_MCBSP4_WKDEP_OFFSET 0x00e0
-#define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e0)
+#define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e0)
#define OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET 0x00e4
-#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e4)
+#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e4)
#define OMAP4_RM_L4PER_MGATE_CONTEXT_OFFSET 0x00ec
-#define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ec)
+#define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ec)
#define OMAP4_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0
-#define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f0)
+#define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f0)
#define OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4
-#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f4)
+#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f4)
#define OMAP4_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8
-#define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f8)
+#define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f8)
#define OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc
-#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00fc)
+#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00fc)
#define OMAP4_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100
-#define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0100)
+#define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0100)
#define OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104
-#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0104)
+#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0104)
#define OMAP4_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108
-#define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0108)
+#define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0108)
#define OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c
-#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x010c)
+#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x010c)
#define OMAP4_PM_L4PER_MMCSD3_WKDEP_OFFSET 0x0120
-#define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0120)
+#define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0120)
#define OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET 0x0124
-#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0124)
+#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0124)
#define OMAP4_PM_L4PER_MMCSD4_WKDEP_OFFSET 0x0128
-#define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0128)
+#define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0128)
#define OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET 0x012c
-#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x012c)
+#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x012c)
#define OMAP4_RM_L4PER_MSPROHG_CONTEXT_OFFSET 0x0134
-#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0134)
+#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0134)
#define OMAP4_PM_L4PER_SLIMBUS2_WKDEP_OFFSET 0x0138
-#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0138)
+#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0138)
#define OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET 0x013c
-#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x013c)
+#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x013c)
#define OMAP4_PM_L4PER_UART1_WKDEP_OFFSET 0x0140
-#define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0140)
+#define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0140)
#define OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144
-#define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0144)
+#define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0144)
#define OMAP4_PM_L4PER_UART2_WKDEP_OFFSET 0x0148
-#define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0148)
+#define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0148)
#define OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c
-#define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x014c)
+#define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x014c)
#define OMAP4_PM_L4PER_UART3_WKDEP_OFFSET 0x0150
-#define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0150)
+#define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0150)
#define OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154
-#define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0154)
+#define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0154)
#define OMAP4_PM_L4PER_UART4_WKDEP_OFFSET 0x0158
-#define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0158)
+#define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0158)
#define OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c
-#define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x015c)
+#define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x015c)
#define OMAP4_PM_L4PER_MMCSD5_WKDEP_OFFSET 0x0160
-#define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0160)
+#define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0160)
#define OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET 0x0164
-#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0164)
+#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0164)
#define OMAP4_PM_L4PER_I2C5_WKDEP_OFFSET 0x0168
-#define OMAP4430_PM_L4PER_I2C5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0168)
+#define OMAP4430_PM_L4PER_I2C5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0168)
#define OMAP4_RM_L4PER_I2C5_CONTEXT_OFFSET 0x016c
-#define OMAP4430_RM_L4PER_I2C5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x016c)
+#define OMAP4430_RM_L4PER_I2C5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x016c)
#define OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4
-#define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01a4)
+#define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01a4)
#define OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac
-#define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01ac)
+#define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01ac)
#define OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4
-#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01b4)
+#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01b4)
#define OMAP4_RM_L4SEC_PKAEIP29_CONTEXT_OFFSET 0x01bc
-#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01bc)
+#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01bc)
#define OMAP4_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4
-#define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01c4)
+#define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01c4)
#define OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc
-#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01cc)
+#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01cc)
#define OMAP4_RM_L4SEC_CRYPTODMA_CONTEXT_OFFSET 0x01dc
-#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01dc)
+#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01dc)
/* PRM.CEFUSE_PRM register offsets */
#define OMAP4_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0000)
+#define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0000)
#define OMAP4_PM_CEFUSE_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0004)
+#define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0004)
#define OMAP4_RM_CEFUSE_CEFUSE_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0024)
+#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0024)
/* PRM.WKUP_PRM register offsets */
#define OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0024)
+#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0024)
#define OMAP4_RM_WKUP_WDT1_CONTEXT_OFFSET 0x002c
-#define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x002c)
+#define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x002c)
#define OMAP4_PM_WKUP_WDT2_WKDEP_OFFSET 0x0030
-#define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0030)
+#define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0030)
#define OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET 0x0034
-#define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0034)
+#define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0034)
#define OMAP4_PM_WKUP_GPIO1_WKDEP_OFFSET 0x0038
-#define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0038)
+#define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0038)
#define OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET 0x003c
-#define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x003c)
+#define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x003c)
#define OMAP4_PM_WKUP_TIMER1_WKDEP_OFFSET 0x0040
-#define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0040)
+#define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0040)
#define OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET 0x0044
-#define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0044)
+#define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0044)
#define OMAP4_PM_WKUP_TIMER12_WKDEP_OFFSET 0x0048
-#define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0048)
+#define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0048)
#define OMAP4_RM_WKUP_TIMER12_CONTEXT_OFFSET 0x004c
-#define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x004c)
+#define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x004c)
#define OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET 0x0054
-#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0054)
+#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0054)
#define OMAP4_PM_WKUP_USIM_WKDEP_OFFSET 0x0058
-#define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0058)
+#define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0058)
#define OMAP4_RM_WKUP_USIM_CONTEXT_OFFSET 0x005c
-#define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x005c)
+#define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x005c)
#define OMAP4_RM_WKUP_SARRAM_CONTEXT_OFFSET 0x0064
-#define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0064)
+#define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0064)
#define OMAP4_PM_WKUP_KEYBOARD_WKDEP_OFFSET 0x0078
-#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0078)
+#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0078)
#define OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET 0x007c
-#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x007c)
+#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x007c)
#define OMAP4_PM_WKUP_RTC_WKDEP_OFFSET 0x0080
-#define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0080)
+#define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0080)
#define OMAP4_RM_WKUP_RTC_CONTEXT_OFFSET 0x0084
-#define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0084)
+#define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0084)
/* PRM.WKUP_CM register offsets */
#define OMAP4_CM_WKUP_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_WKUP_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0000)
+#define OMAP4430_CM_WKUP_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0000)
#define OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0020)
+#define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0020)
#define OMAP4_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0028
-#define OMAP4430_CM_WKUP_WDT1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0028)
+#define OMAP4430_CM_WKUP_WDT1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0028)
#define OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET 0x0030
-#define OMAP4430_CM_WKUP_WDT2_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0030)
+#define OMAP4430_CM_WKUP_WDT2_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0030)
#define OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET 0x0038
-#define OMAP4430_CM_WKUP_GPIO1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0038)
+#define OMAP4430_CM_WKUP_GPIO1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0038)
#define OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0040
-#define OMAP4430_CM_WKUP_TIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0040)
+#define OMAP4430_CM_WKUP_TIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0040)
#define OMAP4_CM_WKUP_TIMER12_CLKCTRL_OFFSET 0x0048
-#define OMAP4430_CM_WKUP_TIMER12_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0048)
+#define OMAP4430_CM_WKUP_TIMER12_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0048)
#define OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0050
-#define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0050)
+#define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0050)
#define OMAP4_CM_WKUP_USIM_CLKCTRL_OFFSET 0x0058
-#define OMAP4430_CM_WKUP_USIM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0058)
+#define OMAP4430_CM_WKUP_USIM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0058)
#define OMAP4_CM_WKUP_SARRAM_CLKCTRL_OFFSET 0x0060
-#define OMAP4430_CM_WKUP_SARRAM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0060)
+#define OMAP4430_CM_WKUP_SARRAM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0060)
#define OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET 0x0078
-#define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0078)
+#define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0078)
#define OMAP4_CM_WKUP_RTC_CLKCTRL_OFFSET 0x0080
-#define OMAP4430_CM_WKUP_RTC_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0080)
+#define OMAP4430_CM_WKUP_RTC_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0080)
#define OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET 0x0088
-#define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0088)
+#define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0088)
/* PRM.EMU_PRM register offsets */
#define OMAP4_PM_EMU_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0000)
+#define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0000)
#define OMAP4_PM_EMU_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0004)
+#define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0004)
#define OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024
-#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0024)
+#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0024)
/* PRM.EMU_CM register offsets */
#define OMAP4_CM_EMU_CLKSTCTRL_OFFSET 0x0000
-#define OMAP4430_CM_EMU_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0000)
+#define OMAP4430_CM_EMU_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0000)
#define OMAP4_CM_EMU_DYNAMICDEP_OFFSET 0x0008
-#define OMAP4430_CM_EMU_DYNAMICDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0008)
+#define OMAP4430_CM_EMU_DYNAMICDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0008)
#define OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020
-#define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0020)
+#define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0020)
/* PRM.DEVICE_PRM register offsets */
#define OMAP4_PRM_RSTCTRL_OFFSET 0x0000
-#define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0000)
+#define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0000)
#define OMAP4_PRM_RSTST_OFFSET 0x0004
-#define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0004)
+#define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0004)
#define OMAP4_PRM_RSTTIME_OFFSET 0x0008
-#define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0008)
+#define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0008)
#define OMAP4_PRM_CLKREQCTRL_OFFSET 0x000c
-#define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x000c)
+#define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x000c)
#define OMAP4_PRM_VOLTCTRL_OFFSET 0x0010
-#define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0010)
+#define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0010)
#define OMAP4_PRM_PWRREQCTRL_OFFSET 0x0014
-#define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0014)
+#define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0014)
#define OMAP4_PRM_PSCON_COUNT_OFFSET 0x0018
-#define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0018)
+#define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0018)
#define OMAP4_PRM_IO_COUNT_OFFSET 0x001c
-#define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x001c)
+#define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x001c)
#define OMAP4_PRM_IO_PMCTRL_OFFSET 0x0020
-#define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0020)
+#define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0020)
#define OMAP4_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024
-#define OMAP4430_PRM_VOLTSETUP_WARMRESET OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0024)
+#define OMAP4430_PRM_VOLTSETUP_WARMRESET OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0024)
#define OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028
-#define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0028)
+#define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0028)
#define OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c
-#define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x002c)
+#define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x002c)
#define OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET 0x0030
-#define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0030)
+#define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0030)
#define OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034
-#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0034)
+#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0034)
#define OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038
-#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0038)
+#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0038)
#define OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET 0x003c
-#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x003c)
+#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x003c)
#define OMAP4_PRM_VP_CORE_CONFIG_OFFSET 0x0040
-#define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0040)
+#define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0040)
#define OMAP4_PRM_VP_CORE_STATUS_OFFSET 0x0044
-#define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0044)
+#define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0044)
#define OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048
-#define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0048)
+#define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0048)
#define OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c
-#define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x004c)
+#define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x004c)
#define OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050
-#define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0050)
+#define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0050)
#define OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054
-#define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0054)
+#define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0054)
#define OMAP4_PRM_VP_MPU_CONFIG_OFFSET 0x0058
-#define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0058)
+#define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0058)
#define OMAP4_PRM_VP_MPU_STATUS_OFFSET 0x005c
-#define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x005c)
+#define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x005c)
#define OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060
-#define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0060)
+#define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0060)
#define OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064
-#define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0064)
+#define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0064)
#define OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068
-#define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0068)
+#define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0068)
#define OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c
-#define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x006c)
+#define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x006c)
#define OMAP4_PRM_VP_IVA_CONFIG_OFFSET 0x0070
-#define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0070)
+#define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0070)
#define OMAP4_PRM_VP_IVA_STATUS_OFFSET 0x0074
-#define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0074)
+#define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0074)
#define OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET 0x0078
-#define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0078)
+#define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0078)
#define OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET 0x007c
-#define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x007c)
+#define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x007c)
#define OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET 0x0080
-#define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0080)
+#define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0080)
#define OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET 0x0084
-#define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0084)
+#define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0084)
#define OMAP4_PRM_VC_SMPS_SA_OFFSET 0x0088
-#define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0088)
+#define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0088)
#define OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET 0x008c
-#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x008c)
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x008c)
#define OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET 0x0090
-#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0090)
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0090)
#define OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094
-#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0094)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0094)
#define OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x0098
-#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0098)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0098)
#define OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET 0x009c
-#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x009c)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x009c)
#define OMAP4_PRM_VC_VAL_BYPASS_OFFSET 0x00a0
-#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a0)
+#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a0)
#define OMAP4_PRM_VC_CFG_CHANNEL_OFFSET 0x00a4
-#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a4)
-#define OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET 0x00a8
-#define OMAP4430_PRM_VC_CFG_I2C_MODE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a8)
+#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a4)
+#define OMAP4_PRM_VC_CFG_I2C_INSTE_OFFSET 0x00a8
+#define OMAP4430_PRM_VC_CFG_I2C_INSTE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a8)
#define OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET 0x00ac
-#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ac)
+#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ac)
#define OMAP4_PRM_SRAM_COUNT_OFFSET 0x00b0
-#define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b0)
+#define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b0)
#define OMAP4_PRM_SRAM_WKUP_SETUP_OFFSET 0x00b4
-#define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b4)
+#define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b4)
#define OMAP4_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x00b8
-#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b8)
+#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b8)
#define OMAP4_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x00bc
-#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00bc)
+#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00bc)
#define OMAP4_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x00c0
-#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c0)
+#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c0)
#define OMAP4_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x00c4
-#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c4)
+#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c4)
#define OMAP4_PRM_LDO_SRAM_IVA_SETUP_OFFSET 0x00c8
-#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c8)
+#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c8)
#define OMAP4_PRM_LDO_SRAM_IVA_CTRL_OFFSET 0x00cc
-#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00cc)
+#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00cc)
#define OMAP4_PRM_LDO_ABB_MPU_SETUP_OFFSET 0x00d0
-#define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d0)
+#define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d0)
#define OMAP4_PRM_LDO_ABB_MPU_CTRL_OFFSET 0x00d4
-#define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d4)
+#define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d4)
#define OMAP4_PRM_LDO_ABB_IVA_SETUP_OFFSET 0x00d8
-#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d8)
+#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d8)
#define OMAP4_PRM_LDO_ABB_IVA_CTRL_OFFSET 0x00dc
-#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00dc)
+#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00dc)
#define OMAP4_PRM_LDO_BANDGAP_SETUP_OFFSET 0x00e0
-#define OMAP4430_PRM_LDO_BANDGAP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e0)
+#define OMAP4430_PRM_LDO_BANDGAP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e0)
#define OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET 0x00e4
-#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e4)
+#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e4)
#define OMAP4_PRM_PHASE1_CNDP_OFFSET 0x00e8
-#define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e8)
+#define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e8)
#define OMAP4_PRM_PHASE2A_CNDP_OFFSET 0x00ec
-#define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ec)
+#define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ec)
#define OMAP4_PRM_PHASE2B_CNDP_OFFSET 0x00f0
-#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f0)
-#define OMAP4_PRM_MODEM_IF_CTRL_OFFSET 0x00f4
-#define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f4)
+#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f0)
+#define OMAP4_PRM_INSTEM_IF_CTRL_OFFSET 0x00f4
+#define OMAP4430_PRM_INSTEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f4)
#define OMAP4_PRM_VC_ERRST_OFFSET 0x00f8
-#define OMAP4430_PRM_VC_ERRST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f8)
+#define OMAP4430_PRM_VC_ERRST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f8)
-/*
- * PRCM_MPU
- *
- * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global)
- * point of view the PRCM_MPU is a single entity. It shares the same
- * programming model as the global PRCM and thus can be assimilate as two new
- * MOD inside the PRCM
- */
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+
+extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
+extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
+
+extern int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
+extern int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+
+extern void omap4_prm_global_warm_sw_reset(void);
+
+# endif
-/* PRCM_MPU.OCP_SOCKET_PRCM register offsets */
-#define OMAP4_REVISION_PRCM_OFFSET 0x0000
-#define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_MOD, 0x0000)
-
-/* PRCM_MPU.DEVICE_PRM register offsets */
-#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000
-#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0000)
-#define OMAP4_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004
-#define OMAP4430_PRCM_MPU_PRM_PSCON_COUNT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0004)
-
-/* PRCM_MPU.CPU0 register offsets */
-#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0000)
-#define OMAP4_PM_CPU0_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0004)
-#define OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0008
-#define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0008)
-#define OMAP4_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x000c
-#define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x000c)
-#define OMAP4_RM_CPU0_CPU0_RSTST_OFFSET 0x0010
-#define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0010)
-#define OMAP4_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0014
-#define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0014)
-#define OMAP4_CM_CPU0_CLKSTCTRL_OFFSET 0x0018
-#define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0018)
-
-/* PRCM_MPU.CPU1 register offsets */
-#define OMAP4_PM_CPU1_PWRSTCTRL_OFFSET 0x0000
-#define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0000)
-#define OMAP4_PM_CPU1_PWRSTST_OFFSET 0x0004
-#define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0004)
-#define OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0008
-#define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0008)
-#define OMAP4_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x000c
-#define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x000c)
-#define OMAP4_RM_CPU1_CPU1_RSTST_OFFSET 0x0010
-#define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0010)
-#define OMAP4_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0014
-#define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0014)
-#define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET 0x0018
-#define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0018)
#endif
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
new file mode 100644
index 000000000000..a30324297278
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -0,0 +1,66 @@
+/*
+ * OMAP4 PRM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu44xx.h"
+
+static u32 _prm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
+ [OMAP4430_INVALID_PRCM_PARTITION] = 0,
+ [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
+ [OMAP4430_CM1_PARTITION] = 0,
+ [OMAP4430_CM2_PARTITION] = 0,
+ [OMAP4430_SCRM_PARTITION] = 0,
+ [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
+};
+
+/* Read a register in a PRM instance */
+u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_prm_bases[part]);
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst +
+ idx));
+}
+
+/* Write into a register in a PRM instance */
+void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_prm_bases[part]);
+ __raw_writel(val, OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst + idx));
+}
+
+/* Read-modify-write a register in PRM. Caller must lock */
+u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
+ s16 idx)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(part, inst, idx);
+ v &= ~mask;
+ v |= bits;
+ omap4_prminst_write_inst_reg(v, part, inst, idx);
+
+ return v;
+}
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
new file mode 100644
index 000000000000..02dd66ddda8b
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -0,0 +1,25 @@
+/*
+ * OMAP4 Power/Reset Management (PRM) function prototypes
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can 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 __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
+#define __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
+
+/*
+ * In an ideal world, we would not export these low-level functions,
+ * but this will probably take some time to fix properly
+ */
+extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx);
+extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
+extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
+ s16 inst, s16 idx);
+
+extern void omap4_prm_global_warm_sw_reset(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/scrm44xx.h b/arch/arm/mach-omap2/scrm44xx.h
new file mode 100644
index 000000000000..701bf2d32949
--- /dev/null
+++ b/arch/arm/mach-omap2/scrm44xx.h
@@ -0,0 +1,175 @@
+/*
+ * OMAP44xx SCRM registers and bitfields
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can 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 __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H
+
+#define OMAP4_SCRM_BASE 0x4a30a000
+
+#define OMAP44XX_SCRM_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4_SCRM_BASE + (reg))
+
+/* Registers offset */
+#define OMAP4_SCRM_REVISION_SCRM_OFFSET 0x0000
+#define OMAP4_SCRM_REVISION_SCRM OMAP44XX_SCRM_REGADDR(0x0000)
+#define OMAP4_SCRM_CLKSETUPTIME_OFFSET 0x0100
+#define OMAP4_SCRM_CLKSETUPTIME OMAP44XX_SCRM_REGADDR(0x0100)
+#define OMAP4_SCRM_PMICSETUPTIME_OFFSET 0x0104
+#define OMAP4_SCRM_PMICSETUPTIME OMAP44XX_SCRM_REGADDR(0x0104)
+#define OMAP4_SCRM_ALTCLKSRC_OFFSET 0x0110
+#define OMAP4_SCRM_ALTCLKSRC OMAP44XX_SCRM_REGADDR(0x0110)
+#define OMAP4_SCRM_MODEMCLKM_OFFSET 0x0118
+#define OMAP4_SCRM_MODEMCLKM OMAP44XX_SCRM_REGADDR(0x0118)
+#define OMAP4_SCRM_D2DCLKM_OFFSET 0x011c
+#define OMAP4_SCRM_D2DCLKM OMAP44XX_SCRM_REGADDR(0x011c)
+#define OMAP4_SCRM_EXTCLKREQ_OFFSET 0x0200
+#define OMAP4_SCRM_EXTCLKREQ OMAP44XX_SCRM_REGADDR(0x0200)
+#define OMAP4_SCRM_ACCCLKREQ_OFFSET 0x0204
+#define OMAP4_SCRM_ACCCLKREQ OMAP44XX_SCRM_REGADDR(0x0204)
+#define OMAP4_SCRM_PWRREQ_OFFSET 0x0208
+#define OMAP4_SCRM_PWRREQ OMAP44XX_SCRM_REGADDR(0x0208)
+#define OMAP4_SCRM_AUXCLKREQ0_OFFSET 0x0210
+#define OMAP4_SCRM_AUXCLKREQ0 OMAP44XX_SCRM_REGADDR(0x0210)
+#define OMAP4_SCRM_AUXCLKREQ1_OFFSET 0x0214
+#define OMAP4_SCRM_AUXCLKREQ1 OMAP44XX_SCRM_REGADDR(0x0214)
+#define OMAP4_SCRM_AUXCLKREQ2_OFFSET 0x0218
+#define OMAP4_SCRM_AUXCLKREQ2 OMAP44XX_SCRM_REGADDR(0x0218)
+#define OMAP4_SCRM_AUXCLKREQ3_OFFSET 0x021c
+#define OMAP4_SCRM_AUXCLKREQ3 OMAP44XX_SCRM_REGADDR(0x021c)
+#define OMAP4_SCRM_AUXCLKREQ4_OFFSET 0x0220
+#define OMAP4_SCRM_AUXCLKREQ4 OMAP44XX_SCRM_REGADDR(0x0220)
+#define OMAP4_SCRM_AUXCLKREQ5_OFFSET 0x0224
+#define OMAP4_SCRM_AUXCLKREQ5 OMAP44XX_SCRM_REGADDR(0x0224)
+#define OMAP4_SCRM_D2DCLKREQ_OFFSET 0x0234
+#define OMAP4_SCRM_D2DCLKREQ OMAP44XX_SCRM_REGADDR(0x0234)
+#define OMAP4_SCRM_AUXCLK0_OFFSET 0x0310
+#define OMAP4_SCRM_AUXCLK0 OMAP44XX_SCRM_REGADDR(0x0310)
+#define OMAP4_SCRM_AUXCLK1_OFFSET 0x0314
+#define OMAP4_SCRM_AUXCLK1 OMAP44XX_SCRM_REGADDR(0x0314)
+#define OMAP4_SCRM_AUXCLK2_OFFSET 0x0318
+#define OMAP4_SCRM_AUXCLK2 OMAP44XX_SCRM_REGADDR(0x0318)
+#define OMAP4_SCRM_AUXCLK3_OFFSET 0x031c
+#define OMAP4_SCRM_AUXCLK3 OMAP44XX_SCRM_REGADDR(0x031c)
+#define OMAP4_SCRM_AUXCLK4_OFFSET 0x0320
+#define OMAP4_SCRM_AUXCLK4 OMAP44XX_SCRM_REGADDR(0x0320)
+#define OMAP4_SCRM_AUXCLK5_OFFSET 0x0324
+#define OMAP4_SCRM_AUXCLK5 OMAP44XX_SCRM_REGADDR(0x0324)
+#define OMAP4_SCRM_RSTTIME_OFFSET 0x0400
+#define OMAP4_SCRM_RSTTIME OMAP44XX_SCRM_REGADDR(0x0400)
+#define OMAP4_SCRM_MODEMRSTCTRL_OFFSET 0x0418
+#define OMAP4_SCRM_MODEMRSTCTRL OMAP44XX_SCRM_REGADDR(0x0418)
+#define OMAP4_SCRM_D2DRSTCTRL_OFFSET 0x041c
+#define OMAP4_SCRM_D2DRSTCTRL OMAP44XX_SCRM_REGADDR(0x041c)
+#define OMAP4_SCRM_EXTPWRONRSTCTRL_OFFSET 0x0420
+#define OMAP4_SCRM_EXTPWRONRSTCTRL OMAP44XX_SCRM_REGADDR(0x0420)
+#define OMAP4_SCRM_EXTWARMRSTST_OFFSET 0x0510
+#define OMAP4_SCRM_EXTWARMRSTST OMAP44XX_SCRM_REGADDR(0x0510)
+#define OMAP4_SCRM_APEWARMRSTST_OFFSET 0x0514
+#define OMAP4_SCRM_APEWARMRSTST OMAP44XX_SCRM_REGADDR(0x0514)
+#define OMAP4_SCRM_MODEMWARMRSTST_OFFSET 0x0518
+#define OMAP4_SCRM_MODEMWARMRSTST OMAP44XX_SCRM_REGADDR(0x0518)
+#define OMAP4_SCRM_D2DWARMRSTST_OFFSET 0x051c
+#define OMAP4_SCRM_D2DWARMRSTST OMAP44XX_SCRM_REGADDR(0x051c)
+
+/* Registers shifts and masks */
+
+/* REVISION_SCRM */
+#define OMAP4_REV_SHIFT 0
+#define OMAP4_REV_MASK (0xff << 0)
+
+/* CLKSETUPTIME */
+#define OMAP4_DOWNTIME_SHIFT 16
+#define OMAP4_DOWNTIME_MASK (0x3f << 16)
+#define OMAP4_SETUPTIME_SHIFT 0
+#define OMAP4_SETUPTIME_MASK (0xfff << 0)
+
+/* PMICSETUPTIME */
+#define OMAP4_WAKEUPTIME_SHIFT 16
+#define OMAP4_WAKEUPTIME_MASK (0x3f << 16)
+#define OMAP4_SLEEPTIME_SHIFT 0
+#define OMAP4_SLEEPTIME_MASK (0x3f << 0)
+
+/* ALTCLKSRC */
+#define OMAP4_ENABLE_EXT_SHIFT 3
+#define OMAP4_ENABLE_EXT_MASK (1 << 3)
+#define OMAP4_ENABLE_INT_SHIFT 2
+#define OMAP4_ENABLE_INT_MASK (1 << 2)
+#define OMAP4_ALTCLKSRC_MODE_SHIFT 0
+#define OMAP4_ALTCLKSRC_MODE_MASK (0x3 << 0)
+
+/* MODEMCLKM */
+#define OMAP4_CLK_32KHZ_SHIFT 0
+#define OMAP4_CLK_32KHZ_MASK (1 << 0)
+
+/* D2DCLKM */
+#define OMAP4_SYSCLK_SHIFT 1
+#define OMAP4_SYSCLK_MASK (1 << 1)
+
+/* EXTCLKREQ */
+#define OMAP4_POLARITY_SHIFT 0
+#define OMAP4_POLARITY_MASK (1 << 0)
+
+/* AUXCLKREQ0 */
+#define OMAP4_MAPPING_SHIFT 2
+#define OMAP4_MAPPING_MASK (0x7 << 2)
+#define OMAP4_ACCURACY_SHIFT 1
+#define OMAP4_ACCURACY_MASK (1 << 1)
+
+/* AUXCLK0 */
+#define OMAP4_CLKDIV_SHIFT 16
+#define OMAP4_CLKDIV_MASK (0xf << 16)
+#define OMAP4_DISABLECLK_SHIFT 9
+#define OMAP4_DISABLECLK_MASK (1 << 9)
+#define OMAP4_ENABLE_SHIFT 8
+#define OMAP4_ENABLE_MASK (1 << 8)
+#define OMAP4_SRCSELECT_SHIFT 1
+#define OMAP4_SRCSELECT_MASK (0x3 << 1)
+
+/* RSTTIME */
+#define OMAP4_RSTTIME_SHIFT 0
+#define OMAP4_RSTTIME_MASK (0xf << 0)
+
+/* MODEMRSTCTRL */
+#define OMAP4_WARMRST_SHIFT 1
+#define OMAP4_WARMRST_MASK (1 << 1)
+#define OMAP4_COLDRST_SHIFT 0
+#define OMAP4_COLDRST_MASK (1 << 0)
+
+/* EXTPWRONRSTCTRL */
+#define OMAP4_PWRONRST_SHIFT 1
+#define OMAP4_PWRONRST_MASK (1 << 1)
+#define OMAP4_ENABLE_EXTPWRONRSTCTRL_SHIFT 0
+#define OMAP4_ENABLE_EXTPWRONRSTCTRL_MASK (1 << 0)
+
+/* EXTWARMRSTST */
+#define OMAP4_EXTWARMRSTST_SHIFT 0
+#define OMAP4_EXTWARMRSTST_MASK (1 << 0)
+
+/* APEWARMRSTST */
+#define OMAP4_APEWARMRSTST_SHIFT 1
+#define OMAP4_APEWARMRSTST_MASK (1 << 1)
+
+/* MODEMWARMRSTST */
+#define OMAP4_MODEMWARMRSTST_SHIFT 2
+#define OMAP4_MODEMWARMRSTST_MASK (1 << 2)
+
+/* D2DWARMRSTST */
+#define OMAP4_D2DWARMRSTST_SHIFT 3
+#define OMAP4_D2DWARMRSTST_MASK (1 << 3)
+
+#endif
diff --git a/arch/arm/mach-omap2/board-rx51-sdram.c b/arch/arm/mach-omap2/sdram-nokia.c
index a43b2c5c838b..14caa228bc0d 100644
--- a/arch/arm/mach-omap2/board-rx51-sdram.c
+++ b/arch/arm/mach-omap2/sdram-nokia.c
@@ -1,7 +1,7 @@
/*
- * SDRC register values for RX51
+ * SDRC register values for Nokia boards
*
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2008, 2010 Nokia Corporation
*
* Lauri Leukkunen <lauri.leukkunen@nokia.com>
*
@@ -22,6 +22,7 @@
#include <plat/clock.h>
#include <plat/sdrc.h>
+#include "sdram-nokia.h"
/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */
struct sdram_timings {
@@ -43,9 +44,28 @@ struct sdram_timings {
u32 tWTR;
};
-static struct omap_sdrc_params rx51_sdrc_params[4];
+static const struct sdram_timings nokia_97dot6mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 30725,
+ .tDPL = 15362,
+ .tRRD = 10241,
+ .tRCD = 20483,
+ .tRP = 15362,
+ .tRAS = 40967,
+ .tRC = 56330,
+ .tRFC = 138266,
+ .tXSR = 204839,
+
+ .tREF = 7798,
+
+ .tXP = 2,
+ .tCKE = 4,
+ .tWTR = 2,
+ },
+};
-static const struct sdram_timings rx51_timings[] = {
+static const struct sdram_timings nokia_166mhz_timings[] = {
{
.casl = 3,
.tDAL = 33000,
@@ -66,6 +86,38 @@ static const struct sdram_timings rx51_timings[] = {
},
};
+static const struct sdram_timings nokia_195dot2mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 30725,
+ .tDPL = 15362,
+ .tRRD = 10241,
+ .tRCD = 20483,
+ .tRP = 15362,
+ .tRAS = 40967,
+ .tRC = 56330,
+ .tRFC = 138266,
+ .tXSR = 204839,
+
+ .tREF = 7752,
+
+ .tXP = 2,
+ .tCKE = 4,
+ .tWTR = 2,
+ },
+};
+
+static const struct {
+ long rate;
+ struct sdram_timings const *data;
+} nokia_timings[] = {
+ { 83000000, nokia_166mhz_timings },
+ { 97600000, nokia_97dot6mhz_timings },
+ { 166000000, nokia_166mhz_timings },
+ { 195200000, nokia_195dot2mhz_timings },
+};
+static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1];
+
static unsigned long sdrc_get_fclk_period(long rate)
{
/* In picoseconds */
@@ -110,12 +162,12 @@ static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
#ifdef DEBUG
#define SDRC_SET_ONE(reg, st, end, field, rate) \
if (set_sdrc_timing_regval((reg), (st), (end), \
- rx51_timings->field, (rate), #field) < 0) \
+ memory_timings->field, (rate), #field) < 0) \
err = -1;
#else
#define SDRC_SET_ONE(reg, st, end, field, rate) \
if (set_sdrc_timing_regval((reg), (st), (end), \
- rx51_timings->field) < 0) \
+ memory_timings->field) < 0) \
err = -1;
#endif
@@ -148,18 +200,19 @@ static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
#ifdef DEBUG
#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
if (set_sdrc_timing_regval_ps((reg), (st), (end), \
- rx51_timings->field, \
+ memory_timings->field, \
(rate), #field) < 0) \
err = -1;
#else
#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
if (set_sdrc_timing_regval_ps((reg), (st), (end), \
- rx51_timings->field, (rate)) < 0) \
+ memory_timings->field, (rate)) < 0) \
err = -1;
#endif
-static int sdrc_timings(int id, long rate)
+static int sdrc_timings(int id, long rate,
+ const struct sdram_timings *memory_timings)
{
u32 ticks_per_ms;
u32 rfr, l;
@@ -184,7 +237,7 @@ static int sdrc_timings(int id, long rate)
SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate);
ticks_per_ms = l3_rate;
- rfr = rx51_timings[0].tREF * ticks_per_ms / 1000000;
+ rfr = memory_timings[0].tREF * ticks_per_ms / 1000000;
if (rfr > 65535 + 50)
rfr = 65535;
else
@@ -197,25 +250,30 @@ static int sdrc_timings(int id, long rate)
l = rfr << 8;
rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */
- rx51_sdrc_params[id].rate = rate;
- rx51_sdrc_params[id].actim_ctrla = actim_ctrla;
- rx51_sdrc_params[id].actim_ctrlb = actim_ctrlb;
- rx51_sdrc_params[id].rfr_ctrl = rfr_ctrl;
- rx51_sdrc_params[id].mr = 0x32;
+ nokia_sdrc_params[id].rate = rate;
+ nokia_sdrc_params[id].actim_ctrla = actim_ctrla;
+ nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb;
+ nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl;
+ nokia_sdrc_params[id].mr = 0x32;
- rx51_sdrc_params[id + 1].rate = 0;
+ nokia_sdrc_params[id + 1].rate = 0;
return err;
}
-struct omap_sdrc_params *rx51_get_sdram_timings(void)
+struct omap_sdrc_params *nokia_get_sdram_timings(void)
{
- int err;
+ int err = 0;
+ int i;
- err = sdrc_timings(0, 41500000);
- err |= sdrc_timings(1, 83000000);
- err |= sdrc_timings(2, 166000000);
+ for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) {
+ err |= sdrc_timings(i, nokia_timings[i].rate,
+ nokia_timings[i].data);
+ if (err)
+ pr_err("%s: error with rate %ld: %d\n", __func__,
+ nokia_timings[i].rate, err);
+ }
- return &rx51_sdrc_params[0];
+ return err ? NULL : nokia_sdrc_params;
}
diff --git a/arch/arm/mach-omap2/sdram-nokia.h b/arch/arm/mach-omap2/sdram-nokia.h
new file mode 100644
index 000000000000..ee63da5f8df0
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-nokia.h
@@ -0,0 +1,12 @@
+/*
+ * SDRC register values for Nokia boards
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can 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 omap_sdrc_params *nokia_get_sdram_timings(void);
+
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 4c65f5628b39..da6f3a63b5d5 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -27,8 +27,6 @@
#include <plat/clock.h>
#include <plat/sram.h>
-#include "prm.h"
-
#include <plat/sdrc.h>
#include "sdrc.h"
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index 68f57bb67fc5..b3f83799e6cf 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -74,5 +74,4 @@ static inline u32 sms_read_reg(u16 reg)
*/
#define SDRC_MPURATE_LOOPS 96
-
#endif
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
index 0f4d27aef44d..ccdb010f169d 100644
--- a/arch/arm/mach-omap2/sdrc2xxx.c
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -28,7 +28,7 @@
#include <plat/clock.h>
#include <plat/sram.h>
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "clock.h"
#include <plat/sdrc.h>
#include "sdrc.h"
@@ -99,6 +99,10 @@ u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
m_type = omap2xxx_sdrc_get_type();
local_irq_save(flags);
+ /*
+ * XXX These calls should be abstracted out through a
+ * prm2xxx.c function
+ */
if (cpu_is_omap2420())
__raw_writel(0xffff, OMAP2420_PRCM_VOLTSETUP);
else
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index d17960a1be25..c64578853a8d 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -40,11 +40,12 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
-#include "prm.h"
+#include "prm2xxx_3xxx.h"
#include "pm.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
#include "control.h"
+#include "mux.h"
#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
#define UART_OMAP_WER 0x17 /* Wake-up enable register */
@@ -106,21 +107,16 @@ struct omap_uart_state {
static LIST_HEAD(uart_list);
static u8 num_uarts;
-/*
- * Since these idle/enable hooks are used in the idle path itself
- * which has interrupts disabled, use the non-locking versions of
- * the hwmod enable/disable functions.
- */
static int uart_idle_hwmod(struct omap_device *od)
{
- _omap_hwmod_idle(od->hwmods[0]);
+ omap_hwmod_idle(od->hwmods[0]);
return 0;
}
static int uart_enable_hwmod(struct omap_device *od)
{
- _omap_hwmod_enable(od->hwmods[0]);
+ omap_hwmod_enable(od->hwmods[0]);
return 0;
}
@@ -169,9 +165,9 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
static inline void __init omap_uart_reset(struct omap_uart_state *uart)
{
- serial_write_reg(uart, UART_OMAP_MDR1, 0x07);
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
serial_write_reg(uart, UART_OMAP_SCR, 0x08);
- serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
}
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
@@ -219,7 +215,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
return;
lcr = serial_read_reg(uart, UART_LCR);
- serial_write_reg(uart, UART_LCR, 0xBF);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
uart->dll = serial_read_reg(uart, UART_DLL);
uart->dlh = serial_read_reg(uart, UART_DLM);
serial_write_reg(uart, UART_LCR, lcr);
@@ -227,7 +223,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
uart->wer = serial_read_reg(uart, UART_OMAP_WER);
- serial_write_reg(uart, UART_LCR, 0x80);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
uart->mcr = serial_read_reg(uart, UART_MCR);
serial_write_reg(uart, UART_LCR, lcr);
@@ -247,32 +243,35 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
uart->context_valid = 0;
if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
- omap_uart_mdr1_errataset(uart, 0x07, 0xA0);
+ omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
else
- serial_write_reg(uart, UART_OMAP_MDR1, 0x7);
- serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
efr = serial_read_reg(uart, UART_EFR);
serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
serial_write_reg(uart, UART_IER, 0x0);
- serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
serial_write_reg(uart, UART_DLL, uart->dll);
serial_write_reg(uart, UART_DLM, uart->dlh);
serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
serial_write_reg(uart, UART_IER, uart->ier);
- serial_write_reg(uart, UART_LCR, 0x80);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
serial_write_reg(uart, UART_MCR, uart->mcr);
- serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
serial_write_reg(uart, UART_EFR, efr);
serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
serial_write_reg(uart, UART_OMAP_WER, uart->wer);
serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
+
if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
- omap_uart_mdr1_errataset(uart, 0x00, 0xA1);
+ omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
else
/* UART 16x mode */
- serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
+ serial_write_reg(uart, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_16X_MODE);
}
#else
static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
@@ -492,6 +491,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
u32 wk_mask = 0;
u32 padconf = 0;
+ /* XXX These PRM accesses do not belong here */
uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
switch (uart->num) {
@@ -695,16 +695,16 @@ void __init omap_serial_early_init(void)
/**
* omap_serial_init_port() - initialize single serial port
- * @port: serial port number (0-3)
+ * @bdata: port specific board data pointer
*
- * This function initialies serial driver for given @port only.
+ * This function initialies serial driver for given port only.
* Platforms can call this function instead of omap_serial_init()
* if they don't plan to use all available UARTs as serial ports.
*
* Don't mix calls to omap_serial_init_port() and omap_serial_init(),
* use only one of the two.
*/
-void __init omap_serial_init_port(int port)
+void __init omap_serial_init_port(struct omap_board_data *bdata)
{
struct omap_uart_state *uart;
struct omap_hwmod *oh;
@@ -722,13 +722,15 @@ void __init omap_serial_init_port(int port)
struct omap_uart_port_info omap_up;
#endif
- if (WARN_ON(port < 0))
+ if (WARN_ON(!bdata))
+ return;
+ if (WARN_ON(bdata->id < 0))
return;
- if (WARN_ON(port >= num_uarts))
+ if (WARN_ON(bdata->id >= num_uarts))
return;
list_for_each_entry(uart, &uart_list, node)
- if (port == uart->num)
+ if (bdata->id == uart->num)
break;
oh = uart->oh;
@@ -800,6 +802,8 @@ void __init omap_serial_init_port(int port)
WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
name, oh->name);
+ oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
+
uart->irq = oh->mpu_irqs[0].irq;
uart->regshift = 2;
uart->mapbase = oh->slaves[0]->addr->pa_start;
@@ -857,7 +861,14 @@ void __init omap_serial_init_port(int port)
void __init omap_serial_init(void)
{
struct omap_uart_state *uart;
+ struct omap_board_data bdata;
- list_for_each_entry(uart, &uart_list, node)
- omap_serial_init_port(uart->num);
+ list_for_each_entry(uart, &uart_list, node) {
+ bdata.id = uart->num;
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+ omap_serial_init_port(&bdata);
+
+ }
}
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 2fb205a7f285..98d8232808b8 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -1,6 +1,4 @@
/*
- * linux/arch/arm/mach-omap2/sleep.S
- *
* (C) Copyright 2007
* Texas Instruments
* Karthik Dasu <karthik-dp@ti.com>
@@ -26,28 +24,35 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <plat/sram.h>
#include <mach/io.h>
-#include "cm.h"
-#include "prm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
#include "sdrc.h"
#include "control.h"
-#define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
-
-#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
- OMAP3430_PM_PREPWSTST)
-#define PM_PREPWSTST_CORE_P 0x48306AE8
-#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
- OMAP3430_PM_PREPWSTST)
+/*
+ * Registers access definitions
+ */
+#define SDRC_SCRATCHPAD_SEM_OFFS 0xc
+#define SDRC_SCRATCHPAD_SEM_V OMAP343X_SCRATCHPAD_REGADDR\
+ (SDRC_SCRATCHPAD_SEM_OFFS)
+#define PM_PREPWSTST_CORE_P OMAP3430_PRM_BASE + CORE_MOD +\
+ OMAP3430_PM_PREPWSTST
#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
-#define SRAM_BASE_P 0x40200000
-#define CONTROL_STAT 0x480022F0
-#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
- * available */
-#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
- + SCRATCHPAD_MEM_OFFS)
+#define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST)
+#define SRAM_BASE_P OMAP3_SRAM_PA
+#define CONTROL_STAT OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS
+#define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE +\
+ OMAP36XX_CONTROL_MEM_RTA_CTRL)
+
+/* Move this as correct place is available */
+#define SCRATCHPAD_MEM_OFFS 0x310
+#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE +\
+ OMAP343X_CONTROL_MEM_WKUP +\
+ SCRATCHPAD_MEM_OFFS)
#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
#define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
#define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0)
@@ -59,48 +64,38 @@
#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
- .text
-/* Function to acquire the semaphore in scratchpad */
-ENTRY(lock_scratchpad_sem)
- stmfd sp!, {lr} @ save registers on stack
-wait_sem:
- mov r0,#1
- ldr r1, sdrc_scratchpad_sem
-wait_loop:
- ldr r2, [r1] @ load the lock value
- cmp r2, r0 @ is the lock free ?
- beq wait_loop @ not free...
- swp r2, r0, [r1] @ semaphore free so lock it and proceed
- cmp r2, r0 @ did we succeed ?
- beq wait_sem @ no - try again
- ldmfd sp!, {pc} @ restore regs and return
-sdrc_scratchpad_sem:
- .word SDRC_SCRATCHPAD_SEM_V
-ENTRY(lock_scratchpad_sem_sz)
- .word . - lock_scratchpad_sem
-
- .text
-/* Function to release the scratchpad semaphore */
-ENTRY(unlock_scratchpad_sem)
- stmfd sp!, {lr} @ save registers on stack
- ldr r3, sdrc_scratchpad_sem
- mov r2,#0
- str r2,[r3]
- ldmfd sp!, {pc} @ restore regs and return
-ENTRY(unlock_scratchpad_sem_sz)
- .word . - unlock_scratchpad_sem
+
+/*
+ * API functions
+ */
+
+/*
+ * The "get_*restore_pointer" functions are used to provide a
+ * physical restore address where the ROM code jumps while waking
+ * up from MPU OFF/OSWR state.
+ * The restore pointer is stored into the scratchpad.
+ */
.text
/* Function call to get the restore pointer for resume from OFF */
ENTRY(get_restore_pointer)
- stmfd sp!, {lr} @ save registers on stack
+ stmfd sp!, {lr} @ save registers on stack
adr r0, restore
- ldmfd sp!, {pc} @ restore regs and return
+ ldmfd sp!, {pc} @ restore regs and return
ENTRY(get_restore_pointer_sz)
- .word . - get_restore_pointer
+ .word . - get_restore_pointer
.text
-/* Function call to get the restore pointer for for ES3 to resume from OFF */
+/* Function call to get the restore pointer for 3630 resume from OFF */
+ENTRY(get_omap3630_restore_pointer)
+ stmfd sp!, {lr} @ save registers on stack
+ adr r0, restore_3630
+ ldmfd sp!, {pc} @ restore regs and return
+ENTRY(get_omap3630_restore_pointer_sz)
+ .word . - get_omap3630_restore_pointer
+
+ .text
+/* Function call to get the restore pointer for ES3 to resume from OFF */
ENTRY(get_es3_restore_pointer)
stmfd sp!, {lr} @ save registers on stack
adr r0, restore_es3
@@ -108,54 +103,23 @@ ENTRY(get_es3_restore_pointer)
ENTRY(get_es3_restore_pointer_sz)
.word . - get_es3_restore_pointer
-ENTRY(es3_sdrc_fix)
- ldr r4, sdrc_syscfg @ get config addr
- ldr r5, [r4] @ get value
- tst r5, #0x100 @ is part access blocked
- it eq
- biceq r5, r5, #0x100 @ clear bit if set
- str r5, [r4] @ write back change
- ldr r4, sdrc_mr_0 @ get config addr
- ldr r5, [r4] @ get value
- str r5, [r4] @ write back change
- ldr r4, sdrc_emr2_0 @ get config addr
- ldr r5, [r4] @ get value
- str r5, [r4] @ write back change
- ldr r4, sdrc_manual_0 @ get config addr
- mov r5, #0x2 @ autorefresh command
- str r5, [r4] @ kick off refreshes
- ldr r4, sdrc_mr_1 @ get config addr
- ldr r5, [r4] @ get value
- str r5, [r4] @ write back change
- ldr r4, sdrc_emr2_1 @ get config addr
- ldr r5, [r4] @ get value
- str r5, [r4] @ write back change
- ldr r4, sdrc_manual_1 @ get config addr
- mov r5, #0x2 @ autorefresh command
- str r5, [r4] @ kick off refreshes
- bx lr
-sdrc_syscfg:
- .word SDRC_SYSCONFIG_P
-sdrc_mr_0:
- .word SDRC_MR_0_P
-sdrc_emr2_0:
- .word SDRC_EMR2_0_P
-sdrc_manual_0:
- .word SDRC_MANUAL_0_P
-sdrc_mr_1:
- .word SDRC_MR_1_P
-sdrc_emr2_1:
- .word SDRC_EMR2_1_P
-sdrc_manual_1:
- .word SDRC_MANUAL_1_P
-ENTRY(es3_sdrc_fix_sz)
- .word . - es3_sdrc_fix
+ .text
+/*
+ * L2 cache needs to be toggled for stable OFF mode functionality on 3630.
+ * This function sets up a flag that will allow for this toggling to take
+ * place on 3630. Hopefully some version in the future may not need this.
+ */
+ENTRY(enable_omap3630_toggle_l2_on_restore)
+ stmfd sp!, {lr} @ save registers on stack
+ /* Setup so that we will disable and enable l2 */
+ mov r1, #0x1
+ str r1, l2dis_3630
+ ldmfd sp!, {pc} @ restore regs and return
+ .text
/* Function to call rom code to save secure ram context */
ENTRY(save_secure_ram_context)
stmfd sp!, {r1-r12, lr} @ save registers on stack
-save_secure_ram_debug:
- /* b save_secure_ram_debug */ @ enable to debug save code
adr r3, api_params @ r3 points to parameters
str r0, [r3,#0x4] @ r0 has sdram address
ldr r12, high_mask
@@ -185,35 +149,162 @@ ENTRY(save_secure_ram_context_sz)
.word . - save_secure_ram_context
/*
+ * ======================
+ * == Idle entry point ==
+ * ======================
+ */
+
+/*
* Forces OMAP into idle state
*
- * omap34xx_suspend() - This bit of code just executes the WFI
- * for normal idles.
+ * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed
+ * and executes the WFI instruction. Calling WFI effectively changes the
+ * power domains states to the desired target power states.
+ *
*
- * Note: This code get's copied to internal SRAM at boot. When the OMAP
- * wakes up it continues execution at the point it went to sleep.
+ * Notes:
+ * - this code gets copied to internal SRAM at boot and after wake-up
+ * from OFF mode. The execution pointer in SRAM is _omap_sram_idle.
+ * - when the OMAP wakes up it continues at different execution points
+ * depending on the low power mode (non-OFF vs OFF modes),
+ * cf. 'Resume path for xxx mode' comments.
*/
ENTRY(omap34xx_cpu_suspend)
- stmfd sp!, {r0-r12, lr} @ save registers on stack
-loop:
- /*b loop*/ @Enable to debug by stepping through code
- /* r0 contains restore pointer in sdram */
- /* r1 contains information about saving context */
- ldr r4, sdrc_power @ read the SDRC_POWER register
- ldr r5, [r4] @ read the contents of SDRC_POWER
- orr r5, r5, #0x40 @ enable self refresh on idle req
- str r5, [r4] @ write back to SDRC_POWER register
+ stmfd sp!, {r0-r12, lr} @ save registers on stack
+ /*
+ * r0 contains restore pointer in sdram
+ * r1 contains information about saving context:
+ * 0 - No context lost
+ * 1 - Only L1 and logic lost
+ * 2 - Only L2 lost
+ * 3 - Both L1 and L2 lost
+ */
+
+ /* Directly jump to WFI is the context save is not required */
cmp r1, #0x0
- /* If context save is required, do that and execute wfi */
- bne save_context_wfi
+ beq omap3_do_wfi
+
+ /* Otherwise fall through to the save context code */
+save_context_wfi:
+ mov r8, r0 @ Store SDRAM address in r8
+ mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
+ mov r4, #0x1 @ Number of parameters for restore call
+ stmia r8!, {r4-r5} @ Push parameters for restore call
+ mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
+ stmia r8!, {r4-r5} @ Push parameters for restore call
+
+ /* Check what that target sleep state is from r1 */
+ cmp r1, #0x2 @ Only L2 lost, no need to save context
+ beq clean_caches
+
+l1_logic_lost:
+ /* Store sp and spsr to SDRAM */
+ mov r4, sp
+ mrs r5, spsr
+ mov r6, lr
+ stmia r8!, {r4-r6}
+ /* Save all ARM registers */
+ /* Coprocessor access control register */
+ mrc p15, 0, r6, c1, c0, 2
+ stmia r8!, {r6}
+ /* TTBR0, TTBR1 and Translation table base control */
+ mrc p15, 0, r4, c2, c0, 0
+ mrc p15, 0, r5, c2, c0, 1
+ mrc p15, 0, r6, c2, c0, 2
+ stmia r8!, {r4-r6}
+ /*
+ * Domain access control register, data fault status register,
+ * and instruction fault status register
+ */
+ mrc p15, 0, r4, c3, c0, 0
+ mrc p15, 0, r5, c5, c0, 0
+ mrc p15, 0, r6, c5, c0, 1
+ stmia r8!, {r4-r6}
+ /*
+ * Data aux fault status register, instruction aux fault status,
+ * data fault address register and instruction fault address register
+ */
+ mrc p15, 0, r4, c5, c1, 0
+ mrc p15, 0, r5, c5, c1, 1
+ mrc p15, 0, r6, c6, c0, 0
+ mrc p15, 0, r7, c6, c0, 2
+ stmia r8!, {r4-r7}
+ /*
+ * user r/w thread and process ID, user r/o thread and process ID,
+ * priv only thread and process ID, cache size selection
+ */
+ mrc p15, 0, r4, c13, c0, 2
+ mrc p15, 0, r5, c13, c0, 3
+ mrc p15, 0, r6, c13, c0, 4
+ mrc p15, 2, r7, c0, c0, 0
+ stmia r8!, {r4-r7}
+ /* Data TLB lockdown, instruction TLB lockdown registers */
+ mrc p15, 0, r5, c10, c0, 0
+ mrc p15, 0, r6, c10, c0, 1
+ stmia r8!, {r5-r6}
+ /* Secure or non secure vector base address, FCSE PID, Context PID*/
+ mrc p15, 0, r4, c12, c0, 0
+ mrc p15, 0, r5, c13, c0, 0
+ mrc p15, 0, r6, c13, c0, 1
+ stmia r8!, {r4-r6}
+ /* Primary remap, normal remap registers */
+ mrc p15, 0, r4, c10, c2, 0
+ mrc p15, 0, r5, c10, c2, 1
+ stmia r8!,{r4-r5}
+
+ /* Store current cpsr*/
+ mrs r2, cpsr
+ stmia r8!, {r2}
+
+ mrc p15, 0, r4, c1, c0, 0
+ /* save control register */
+ stmia r8!, {r4}
+
+clean_caches:
+ /*
+ * Clean Data or unified cache to POU
+ * How to invalidate only L1 cache???? - #FIX_ME#
+ * mcr p15, 0, r11, c7, c11, 1
+ */
+ cmp r1, #0x1 @ Check whether L2 inval is required
+ beq omap3_do_wfi
+
+clean_l2:
+ /*
+ * jump out to kernel flush routine
+ * - reuse that code is better
+ * - it executes in a cached space so is faster than refetch per-block
+ * - should be faster and will change with kernel
+ * - 'might' have to copy address, load and jump to it
+ */
+ ldr r1, kernel_flush
+ mov lr, pc
+ bx r1
+
+omap3_do_wfi:
+ ldr r4, sdrc_power @ read the SDRC_POWER register
+ ldr r5, [r4] @ read the contents of SDRC_POWER
+ orr r5, r5, #0x40 @ enable self refresh on idle req
+ str r5, [r4] @ write back to SDRC_POWER register
+
/* Data memory barrier and Data sync barrier */
mov r1, #0
mcr p15, 0, r1, c7, c10, 4
mcr p15, 0, r1, c7, c10, 5
+/*
+ * ===================================
+ * == WFI instruction => Enter idle ==
+ * ===================================
+ */
wfi @ wait for interrupt
+/*
+ * ===================================
+ * == Resume path for non-OFF modes ==
+ * ===================================
+ */
nop
nop
nop
@@ -226,9 +317,30 @@ loop:
nop
bl wait_sdrc_ok
- ldmfd sp!, {r0-r12, pc} @ restore regs and return
+/*
+ * ===================================
+ * == Exit point from non-OFF modes ==
+ * ===================================
+ */
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+
+/*
+ * ==============================
+ * == Resume path for OFF mode ==
+ * ==============================
+ */
+
+/*
+ * The restore_* functions are called by the ROM code
+ * when back from WFI in OFF mode.
+ * Cf. the get_*restore_pointer functions.
+ *
+ * restore_es3: applies to 34xx >= ES3.0
+ * restore_3630: applies to 36xx
+ * restore: common code for 3xxx
+ */
restore_es3:
- /*b restore_es3*/ @ Enable to debug restore code
ldr r5, pm_prepwstst_core_p
ldr r4, [r5]
and r4, r4, #0x3
@@ -245,82 +357,117 @@ copy_to_sram:
bne copy_to_sram
ldr r1, sram_base
blx r1
+ b restore
+
+restore_3630:
+ ldr r1, pm_prepwstst_core_p
+ ldr r2, [r1]
+ and r2, r2, #0x3
+ cmp r2, #0x0 @ Check if previous power state of CORE is OFF
+ bne restore
+ /* Disable RTA before giving control */
+ ldr r1, control_mem_rta
+ mov r2, #OMAP36XX_RTA_DISABLE
+ str r2, [r1]
+
+ /* Fall through to common code for the remaining logic */
+
restore:
- /* b restore*/ @ Enable to debug restore code
- /* Check what was the reason for mpu reset and store the reason in r9*/
- /* 1 - Only L1 and logic lost */
- /* 2 - Only L2 lost - In this case, we wont be here */
- /* 3 - Both L1 and L2 lost */
- ldr r1, pm_pwstctrl_mpu
+ /*
+ * Check what was the reason for mpu reset and store the reason in r9:
+ * 0 - No context lost
+ * 1 - Only L1 and logic lost
+ * 2 - Only L2 lost - In this case, we wont be here
+ * 3 - Both L1 and L2 lost
+ */
+ ldr r1, pm_pwstctrl_mpu
ldr r2, [r1]
- and r2, r2, #0x3
- cmp r2, #0x0 @ Check if target power state was OFF or RET
- moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
+ and r2, r2, #0x3
+ cmp r2, #0x0 @ Check if target power state was OFF or RET
+ moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
bne logic_l1_restore
+
+ ldr r0, l2dis_3630
+ cmp r0, #0x1 @ should we disable L2 on 3630?
+ bne skipl2dis
+ mrc p15, 0, r0, c1, c0, 1
+ bic r0, r0, #2 @ disable L2 cache
+ mcr p15, 0, r0, c1, c0, 1
+skipl2dis:
ldr r0, control_stat
ldr r1, [r0]
and r1, #0x700
cmp r1, #0x300
beq l2_inv_gp
- mov r0, #40 @ set service ID for PPA
- mov r12, r0 @ copy secure Service ID in r12
- mov r1, #0 @ set task id for ROM code in r1
- mov r2, #4 @ set some flags in r2, r6
+ mov r0, #40 @ set service ID for PPA
+ mov r12, r0 @ copy secure Service ID in r12
+ mov r1, #0 @ set task id for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
adr r3, l2_inv_api_params @ r3 points to dummy parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
/* Write to Aux control register to set some bits */
- mov r0, #42 @ set service ID for PPA
- mov r12, r0 @ copy secure Service ID in r12
- mov r1, #0 @ set task id for ROM code in r1
- mov r2, #4 @ set some flags in r2, r6
+ mov r0, #42 @ set service ID for PPA
+ mov r12, r0 @ copy secure Service ID in r12
+ mov r1, #0 @ set task id for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
ldr r4, scratchpad_base
- ldr r3, [r4, #0xBC] @ r3 points to parameters
+ ldr r3, [r4, #0xBC] @ r3 points to parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
/* Restore L2 aux control register */
- @ set service ID for PPA
+ @ set service ID for PPA
mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
- mov r12, r0 @ copy service ID in r12
- mov r1, #0 @ set task ID for ROM code in r1
- mov r2, #4 @ set some flags in r2, r6
+ mov r12, r0 @ copy service ID in r12
+ mov r1, #0 @ set task ID for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
ldr r4, scratchpad_base
ldr r3, [r4, #0xBC]
- adds r3, r3, #8 @ r3 points to parameters
+ adds r3, r3, #8 @ r3 points to parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
#endif
b logic_l1_restore
+
l2_inv_api_params:
- .word 0x1, 0x00
+ .word 0x1, 0x00
l2_inv_gp:
/* Execute smi to invalidate L2 cache */
- mov r12, #0x1 @ set up to invalide L2
-smi: .word 0xE1600070 @ Call SMI monitor (smieq)
+ mov r12, #0x1 @ set up to invalidate L2
+ .word 0xE1600070 @ Call SMI monitor (smieq)
/* Write to Aux control register to set some bits */
ldr r4, scratchpad_base
ldr r3, [r4,#0xBC]
ldr r0, [r3,#4]
mov r12, #0x3
- .word 0xE1600070 @ Call SMI monitor (smieq)
+ .word 0xE1600070 @ Call SMI monitor (smieq)
ldr r4, scratchpad_base
ldr r3, [r4,#0xBC]
ldr r0, [r3,#12]
mov r12, #0x2
- .word 0xE1600070 @ Call SMI monitor (smieq)
+ .word 0xE1600070 @ Call SMI monitor (smieq)
logic_l1_restore:
+ ldr r1, l2dis_3630
+ cmp r1, #0x1 @ Test if L2 re-enable needed on 3630
+ bne skipl2reen
+ mrc p15, 0, r1, c1, c0, 1
+ orr r1, r1, #2 @ re-enable L2 cache
+ mcr p15, 0, r1, c1, c0, 1
+skipl2reen:
mov r1, #0
- /* Invalidate all instruction caches to PoU
- * and flush branch target cache */
+ /*
+ * Invalidate all instruction caches to PoU
+ * and flush branch target cache
+ */
mcr p15, 0, r1, c7, c5, 0
ldr r4, scratchpad_base
@@ -341,33 +488,33 @@ logic_l1_restore:
MCR p15, 0, r6, c2, c0, 1
/* Translation table base control register */
MCR p15, 0, r7, c2, c0, 2
- /*domain access Control Register */
+ /* Domain access Control Register */
MCR p15, 0, r8, c3, c0, 0
- /* data fault status Register */
+ /* Data fault status Register */
MCR p15, 0, r9, c5, c0, 0
- ldmia r3!,{r4-r8}
- /* instruction fault status Register */
+ ldmia r3!,{r4-r8}
+ /* Instruction fault status Register */
MCR p15, 0, r4, c5, c0, 1
- /*Data Auxiliary Fault Status Register */
+ /* Data Auxiliary Fault Status Register */
MCR p15, 0, r5, c5, c1, 0
- /*Instruction Auxiliary Fault Status Register*/
+ /* Instruction Auxiliary Fault Status Register*/
MCR p15, 0, r6, c5, c1, 1
- /*Data Fault Address Register */
+ /* Data Fault Address Register */
MCR p15, 0, r7, c6, c0, 0
- /*Instruction Fault Address Register*/
+ /* Instruction Fault Address Register*/
MCR p15, 0, r8, c6, c0, 2
- ldmia r3!,{r4-r7}
+ ldmia r3!,{r4-r7}
- /* user r/w thread and process ID */
+ /* User r/w thread and process ID */
MCR p15, 0, r4, c13, c0, 2
- /* user ro thread and process ID */
+ /* User ro thread and process ID */
MCR p15, 0, r5, c13, c0, 3
- /*Privileged only thread and process ID */
+ /* Privileged only thread and process ID */
MCR p15, 0, r6, c13, c0, 4
- /* cache size selection */
+ /* Cache size selection */
MCR p15, 2, r7, c0, c0, 0
- ldmia r3!,{r4-r8}
+ ldmia r3!,{r4-r8}
/* Data TLB lockdown registers */
MCR p15, 0, r4, c10, c0, 0
/* Instruction TLB lockdown registers */
@@ -379,26 +526,27 @@ logic_l1_restore:
/* Context PID */
MCR p15, 0, r8, c13, c0, 1
- ldmia r3!,{r4-r5}
- /* primary memory remap register */
+ ldmia r3!,{r4-r5}
+ /* Primary memory remap register */
MCR p15, 0, r4, c10, c2, 0
- /*normal memory remap register */
+ /* Normal memory remap register */
MCR p15, 0, r5, c10, c2, 1
/* Restore cpsr */
- ldmia r3!,{r4} /*load CPSR from SDRAM*/
- msr cpsr, r4 /*store cpsr */
+ ldmia r3!,{r4} @ load CPSR from SDRAM
+ msr cpsr, r4 @ store cpsr
/* Enabling MMU here */
- mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
- /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
+ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
+ /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
and r7, #0x7
cmp r7, #0x0
beq usettbr0
ttbr_error:
- /* More work needs to be done to support N[0:2] value other than 0
- * So looping here so that the error can be detected
- */
+ /*
+ * More work needs to be done to support N[0:2] value other than 0
+ * So looping here so that the error can be detected
+ */
b ttbr_error
usettbr0:
mrc p15, 0, r2, c2, c0, 0
@@ -406,21 +554,25 @@ usettbr0:
and r2, r5
mov r4, pc
ldr r5, table_index_mask
- and r4, r5 /* r4 = 31 to 20 bits of pc */
+ and r4, r5 @ r4 = 31 to 20 bits of pc
/* Extract the value to be written to table entry */
ldr r1, table_entry
- add r1, r1, r4 /* r1 has value to be written to table entry*/
+ /* r1 has the value to be written to table entry*/
+ add r1, r1, r4
/* Getting the address of table entry to modify */
lsr r4, #18
- add r2, r4 /* r2 has the location which needs to be modified */
+ /* r2 has the location which needs to be modified */
+ add r2, r4
/* Storing previous entry of location being modified */
ldr r5, scratchpad_base
ldr r4, [r2]
str r4, [r5, #0xC0]
/* Modify the table entry */
str r1, [r2]
- /* Storing address of entry being modified
- * - will be restored after enabling MMU */
+ /*
+ * Storing address of entry being modified
+ * - will be restored after enabling MMU
+ */
ldr r5, scratchpad_base
str r2, [r5, #0xC4]
@@ -429,8 +581,11 @@ usettbr0:
mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
- /* Restore control register but dont enable caches here*/
- /* Caches will be enabled after restoring MMU table entry */
+ /*
+ * Restore control register. This enables the MMU.
+ * The caches and prediction are not enabled here, they
+ * will be enabled after restoring the MMU table entry.
+ */
ldmia r3!, {r4}
/* Store previous value of control register in scratchpad */
str r4, [r5, #0xC8]
@@ -438,212 +593,144 @@ usettbr0:
and r4, r2
mcr p15, 0, r4, c1, c0, 0
- ldmfd sp!, {r0-r12, pc} @ restore regs and return
-save_context_wfi:
- /*b save_context_wfi*/ @ enable to debug save code
- mov r8, r0 /* Store SDRAM address in r8 */
- mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
- mov r4, #0x1 @ Number of parameters for restore call
- stmia r8!, {r4-r5} @ Push parameters for restore call
- mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
- stmia r8!, {r4-r5} @ Push parameters for restore call
- /* Check what that target sleep state is:stored in r1*/
- /* 1 - Only L1 and logic lost */
- /* 2 - Only L2 lost */
- /* 3 - Both L1 and L2 lost */
- cmp r1, #0x2 /* Only L2 lost */
- beq clean_l2
- cmp r1, #0x1 /* L2 retained */
- /* r9 stores whether to clean L2 or not*/
- moveq r9, #0x0 /* Dont Clean L2 */
- movne r9, #0x1 /* Clean L2 */
-l1_logic_lost:
- /* Store sp and spsr to SDRAM */
- mov r4, sp
- mrs r5, spsr
- mov r6, lr
- stmia r8!, {r4-r6}
- /* Save all ARM registers */
- /* Coprocessor access control register */
- mrc p15, 0, r6, c1, c0, 2
- stmia r8!, {r6}
- /* TTBR0, TTBR1 and Translation table base control */
- mrc p15, 0, r4, c2, c0, 0
- mrc p15, 0, r5, c2, c0, 1
- mrc p15, 0, r6, c2, c0, 2
- stmia r8!, {r4-r6}
- /* Domain access control register, data fault status register,
- and instruction fault status register */
- mrc p15, 0, r4, c3, c0, 0
- mrc p15, 0, r5, c5, c0, 0
- mrc p15, 0, r6, c5, c0, 1
- stmia r8!, {r4-r6}
- /* Data aux fault status register, instruction aux fault status,
- datat fault address register and instruction fault address register*/
- mrc p15, 0, r4, c5, c1, 0
- mrc p15, 0, r5, c5, c1, 1
- mrc p15, 0, r6, c6, c0, 0
- mrc p15, 0, r7, c6, c0, 2
- stmia r8!, {r4-r7}
- /* user r/w thread and process ID, user r/o thread and process ID,
- priv only thread and process ID, cache size selection */
- mrc p15, 0, r4, c13, c0, 2
- mrc p15, 0, r5, c13, c0, 3
- mrc p15, 0, r6, c13, c0, 4
- mrc p15, 2, r7, c0, c0, 0
- stmia r8!, {r4-r7}
- /* Data TLB lockdown, instruction TLB lockdown registers */
- mrc p15, 0, r5, c10, c0, 0
- mrc p15, 0, r6, c10, c0, 1
- stmia r8!, {r5-r6}
- /* Secure or non secure vector base address, FCSE PID, Context PID*/
- mrc p15, 0, r4, c12, c0, 0
- mrc p15, 0, r5, c13, c0, 0
- mrc p15, 0, r6, c13, c0, 1
- stmia r8!, {r4-r6}
- /* Primary remap, normal remap registers */
- mrc p15, 0, r4, c10, c2, 0
- mrc p15, 0, r5, c10, c2, 1
- stmia r8!,{r4-r5}
+/*
+ * ==============================
+ * == Exit point from OFF mode ==
+ * ==============================
+ */
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
- /* Store current cpsr*/
- mrs r2, cpsr
- stmia r8!, {r2}
- mrc p15, 0, r4, c1, c0, 0
- /* save control register */
- stmia r8!, {r4}
-clean_caches:
- /* Clean Data or unified cache to POU*/
- /* How to invalidate only L1 cache???? - #FIX_ME# */
- /* mcr p15, 0, r11, c7, c11, 1 */
- cmp r9, #1 /* Check whether L2 inval is required or not*/
- bne skip_l2_inval
-clean_l2:
- /* read clidr */
- mrc p15, 1, r0, c0, c0, 1
- /* extract loc from clidr */
- ands r3, r0, #0x7000000
- /* left align loc bit field */
- mov r3, r3, lsr #23
- /* if loc is 0, then no need to clean */
- beq finished
- /* start clean at cache level 0 */
- mov r10, #0
-loop1:
- /* work out 3x current cache level */
- add r2, r10, r10, lsr #1
- /* extract cache type bits from clidr*/
- mov r1, r0, lsr r2
- /* mask of the bits for current cache only */
- and r1, r1, #7
- /* see what cache we have at this level */
- cmp r1, #2
- /* skip if no cache, or just i-cache */
- blt skip
- /* select current cache level in cssr */
- mcr p15, 2, r10, c0, c0, 0
- /* isb to sych the new cssr&csidr */
- isb
- /* read the new csidr */
- mrc p15, 1, r1, c0, c0, 0
- /* extract the length of the cache lines */
- and r2, r1, #7
- /* add 4 (line length offset) */
- add r2, r2, #4
- ldr r4, assoc_mask
- /* find maximum number on the way size */
- ands r4, r4, r1, lsr #3
- /* find bit position of way size increment */
- clz r5, r4
- ldr r7, numset_mask
- /* extract max number of the index size*/
- ands r7, r7, r1, lsr #13
-loop2:
- mov r9, r4
- /* create working copy of max way size*/
-loop3:
- /* factor way and cache number into r11 */
- orr r11, r10, r9, lsl r5
- /* factor index number into r11 */
- orr r11, r11, r7, lsl r2
- /*clean & invalidate by set/way */
- mcr p15, 0, r11, c7, c10, 2
- /* decrement the way*/
- subs r9, r9, #1
- bge loop3
- /*decrement the index */
- subs r7, r7, #1
- bge loop2
-skip:
- add r10, r10, #2
- /* increment cache number */
- cmp r3, r10
- bgt loop1
-finished:
- /*swith back to cache level 0 */
- mov r10, #0
- /* select current cache level in cssr */
- mcr p15, 2, r10, c0, c0, 0
- isb
-skip_l2_inval:
- /* Data memory barrier and Data sync barrier */
- mov r1, #0
- mcr p15, 0, r1, c7, c10, 4
- mcr p15, 0, r1, c7, c10, 5
+/*
+ * Internal functions
+ */
- wfi @ wait for interrupt
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- bl wait_sdrc_ok
- /* restore regs and return */
- ldmfd sp!, {r0-r12, pc}
+/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
+ .text
+ENTRY(es3_sdrc_fix)
+ ldr r4, sdrc_syscfg @ get config addr
+ ldr r5, [r4] @ get value
+ tst r5, #0x100 @ is part access blocked
+ it eq
+ biceq r5, r5, #0x100 @ clear bit if set
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_mr_0 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_emr2_0 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_manual_0 @ get config addr
+ mov r5, #0x2 @ autorefresh command
+ str r5, [r4] @ kick off refreshes
+ ldr r4, sdrc_mr_1 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_emr2_1 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_manual_1 @ get config addr
+ mov r5, #0x2 @ autorefresh command
+ str r5, [r4] @ kick off refreshes
+ bx lr
+
+sdrc_syscfg:
+ .word SDRC_SYSCONFIG_P
+sdrc_mr_0:
+ .word SDRC_MR_0_P
+sdrc_emr2_0:
+ .word SDRC_EMR2_0_P
+sdrc_manual_0:
+ .word SDRC_MANUAL_0_P
+sdrc_mr_1:
+ .word SDRC_MR_1_P
+sdrc_emr2_1:
+ .word SDRC_EMR2_1_P
+sdrc_manual_1:
+ .word SDRC_MANUAL_1_P
+ENTRY(es3_sdrc_fix_sz)
+ .word . - es3_sdrc_fix
+
+/*
+ * This function implements the erratum ID i581 WA:
+ * SDRC state restore before accessing the SDRAM
+ *
+ * Only used at return from non-OFF mode. For OFF
+ * mode the ROM code configures the SDRC and
+ * the DPLL before calling the restore code directly
+ * from DDR.
+ */
/* Make sure SDRC accesses are ok */
wait_sdrc_ok:
- ldr r4, cm_idlest1_core
- ldr r5, [r4]
- and r5, r5, #0x2
- cmp r5, #0
- bne wait_sdrc_ok
- ldr r4, sdrc_power
- ldr r5, [r4]
- bic r5, r5, #0x40
- str r5, [r4]
+
+/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
+ ldr r4, cm_idlest_ckgen
+wait_dpll3_lock:
+ ldr r5, [r4]
+ tst r5, #1
+ beq wait_dpll3_lock
+
+ ldr r4, cm_idlest1_core
+wait_sdrc_ready:
+ ldr r5, [r4]
+ tst r5, #0x2
+ bne wait_sdrc_ready
+ /* allow DLL powerdown upon hw idle req */
+ ldr r4, sdrc_power
+ ldr r5, [r4]
+ bic r5, r5, #0x40
+ str r5, [r4]
+
+is_dll_in_lock_mode:
+ /* Is dll in lock mode? */
+ ldr r4, sdrc_dlla_ctrl
+ ldr r5, [r4]
+ tst r5, #0x4
+ bxne lr @ Return if locked
+ /* wait till dll locks */
+wait_dll_lock_timed:
+ ldr r4, wait_dll_lock_counter
+ add r4, r4, #1
+ str r4, wait_dll_lock_counter
+ ldr r4, sdrc_dlla_status
+ /* Wait 20uS for lock */
+ mov r6, #8
wait_dll_lock:
- /* Is dll in lock mode? */
- ldr r4, sdrc_dlla_ctrl
- ldr r5, [r4]
- tst r5, #0x4
- bxne lr
- /* wait till dll locks */
- ldr r4, sdrc_dlla_status
- ldr r5, [r4]
- and r5, r5, #0x4
- cmp r5, #0x4
- bne wait_dll_lock
- bx lr
+ subs r6, r6, #0x1
+ beq kick_dll
+ ldr r5, [r4]
+ and r5, r5, #0x4
+ cmp r5, #0x4
+ bne wait_dll_lock
+ bx lr @ Return when locked
+
+ /* disable/reenable DLL if not locked */
+kick_dll:
+ ldr r4, sdrc_dlla_ctrl
+ ldr r5, [r4]
+ mov r6, r5
+ bic r6, #(1<<3) @ disable dll
+ str r6, [r4]
+ dsb
+ orr r6, r6, #(1<<3) @ enable dll
+ str r6, [r4]
+ dsb
+ ldr r4, kick_counter
+ add r4, r4, #1
+ str r4, kick_counter
+ b wait_dll_lock_timed
cm_idlest1_core:
.word CM_IDLEST1_CORE_V
+cm_idlest_ckgen:
+ .word CM_IDLEST_CKGEN_V
sdrc_dlla_status:
.word SDRC_DLLA_STATUS_V
sdrc_dlla_ctrl:
.word SDRC_DLLA_CTRL_V
-pm_prepwstst_core:
- .word PM_PREPWSTST_CORE_V
pm_prepwstst_core_p:
.word PM_PREPWSTST_CORE_P
-pm_prepwstst_mpu:
- .word PM_PREPWSTST_MPU_V
pm_pwstctrl_mpu:
.word PM_PWSTCTRL_MPU_P
scratchpad_base:
@@ -651,13 +738,7 @@ scratchpad_base:
sram_base:
.word SRAM_BASE_P + 0x8000
sdrc_power:
- .word SDRC_POWER_V
-clk_stabilize_delay:
- .word 0x000001FF
-assoc_mask:
- .word 0x3ff
-numset_mask:
- .word 0x7fff
+ .word SDRC_POWER_V
ttbrbit_mask:
.word 0xFFFFC000
table_index_mask:
@@ -668,5 +749,20 @@ cache_pred_disable_mask:
.word 0xFFFFE7FB
control_stat:
.word CONTROL_STAT
+control_mem_rta:
+ .word CONTROL_MEM_RTA_CTRL
+kernel_flush:
+ .word v7_flush_dcache_all
+l2dis_3630:
+ .word 0
+ /*
+ * When exporting to userspace while the counters are in SRAM,
+ * these 2 words need to be at the end to facilitate retrival!
+ */
+kick_counter:
+ .word 0
+wait_dll_lock_counter:
+ .word 0
+
ENTRY(omap34xx_cpu_suspend_sz)
.word . - omap34xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
new file mode 100644
index 000000000000..60e70552b4c5
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -0,0 +1,59 @@
+/*
+ * Smart reflex Class 3 specific implementations
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@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 <plat/smartreflex.h>
+
+static int sr_class3_enable(struct voltagedomain *voltdm)
+{
+ unsigned long volt = omap_voltage_get_nom_volt(voltdm);
+
+ if (!volt) {
+ pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n",
+ __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ omap_vp_enable(voltdm);
+ return sr_enable(voltdm, volt);
+}
+
+static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
+{
+ omap_vp_disable(voltdm);
+ sr_disable(voltdm);
+ if (is_volt_reset)
+ omap_voltage_reset(voltdm);
+
+ return 0;
+}
+
+static int sr_class3_configure(struct voltagedomain *voltdm)
+{
+ return sr_configure_errgen(voltdm);
+}
+
+/* SR class3 structure */
+static struct omap_sr_class_data class3_data = {
+ .enable = sr_class3_enable,
+ .disable = sr_class3_disable,
+ .configure = sr_class3_configure,
+ .class_type = SR_CLASS3,
+};
+
+/* Smartreflex Class3 init API to be called from board file */
+static int __init sr_class3_init(void)
+{
+ pr_info("SmartReflex Class3 initialized\n");
+ return sr_register_class(&class3_data);
+}
+late_initcall(sr_class3_init);
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
new file mode 100644
index 000000000000..77ecebf3fae2
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -0,0 +1,1029 @@
+/*
+ * OMAP SmartReflex Voltage Control
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@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/interrupt.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+
+#include <plat/common.h>
+#include <plat/smartreflex.h>
+
+#include "pm.h"
+
+#define SMARTREFLEX_NAME_LEN 16
+#define NVALUE_NAME_LEN 40
+#define SR_DISABLE_TIMEOUT 200
+
+struct omap_sr {
+ int srid;
+ int ip_type;
+ int nvalue_count;
+ bool autocomp_active;
+ u32 clk_length;
+ u32 err_weight;
+ u32 err_minlimit;
+ u32 err_maxlimit;
+ u32 accum_data;
+ u32 senn_avgweight;
+ u32 senp_avgweight;
+ u32 senp_mod;
+ u32 senn_mod;
+ unsigned int irq;
+ void __iomem *base;
+ struct platform_device *pdev;
+ struct list_head node;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+};
+
+/* sr_list contains all the instances of smartreflex module */
+static LIST_HEAD(sr_list);
+
+static struct omap_sr_class_data *sr_class;
+static struct omap_sr_pmic_data *sr_pmic_data;
+
+static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
+{
+ __raw_writel(value, (sr->base + offset));
+}
+
+static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
+ u32 value)
+{
+ u32 reg_val;
+ u32 errconfig_offs = 0, errconfig_mask = 0;
+
+ reg_val = __raw_readl(sr->base + offset);
+ reg_val &= ~mask;
+
+ /*
+ * Smartreflex error config register is special as it contains
+ * certain status bits which if written a 1 into means a clear
+ * of those bits. So in order to make sure no accidental write of
+ * 1 happens to those status bits, do a clear of them in the read
+ * value. This mean this API doesn't rewrite values in these bits
+ * if they are currently set, but does allow the caller to write
+ * those bits.
+ */
+ if (sr->ip_type == SR_TYPE_V1) {
+ errconfig_offs = ERRCONFIG_V1;
+ errconfig_mask = ERRCONFIG_STATUS_V1_MASK;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ errconfig_offs = ERRCONFIG_V2;
+ errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2;
+ }
+
+ if (offset == errconfig_offs)
+ reg_val &= ~errconfig_mask;
+
+ reg_val |= value;
+
+ __raw_writel(reg_val, (sr->base + offset));
+}
+
+static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
+{
+ return __raw_readl(sr->base + offset);
+}
+
+static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr_info;
+
+ if (!voltdm) {
+ pr_err("%s: Null voltage domain passed!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ list_for_each_entry(sr_info, &sr_list, node) {
+ if (voltdm == sr_info->voltdm)
+ return sr_info;
+ }
+
+ return ERR_PTR(-ENODATA);
+}
+
+static irqreturn_t sr_interrupt(int irq, void *data)
+{
+ struct omap_sr *sr_info = (struct omap_sr *)data;
+ u32 status = 0;
+
+ if (sr_info->ip_type == SR_TYPE_V1) {
+ /* Read the status bits */
+ status = sr_read_reg(sr_info, ERRCONFIG_V1);
+
+ /* Clear them by writing back */
+ sr_write_reg(sr_info, ERRCONFIG_V1, status);
+ } else if (sr_info->ip_type == SR_TYPE_V2) {
+ /* Read the status bits */
+ sr_read_reg(sr_info, IRQSTATUS);
+
+ /* Clear them by writing back */
+ sr_write_reg(sr_info, IRQSTATUS, status);
+ }
+
+ if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
+ sr_class->notify(sr_info->voltdm, status);
+
+ return IRQ_HANDLED;
+}
+
+static void sr_set_clk_length(struct omap_sr *sr)
+{
+ struct clk *sys_ck;
+ u32 sys_clk_speed;
+
+ if (cpu_is_omap34xx())
+ sys_ck = clk_get(NULL, "sys_ck");
+ else
+ sys_ck = clk_get(NULL, "sys_clkin_ck");
+
+ if (IS_ERR(sys_ck)) {
+ dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
+ __func__);
+ return;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+
+ switch (sys_clk_speed) {
+ case 12000000:
+ sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
+ break;
+ case 13000000:
+ sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
+ break;
+ case 19200000:
+ sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
+ break;
+ case 26000000:
+ sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
+ break;
+ case 38400000:
+ sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
+ break;
+ default:
+ dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
+ __func__, sys_clk_speed);
+ break;
+ }
+}
+
+static void sr_set_regfields(struct omap_sr *sr)
+{
+ /*
+ * For time being these values are defined in smartreflex.h
+ * and populated during init. May be they can be moved to board
+ * file or pmic specific data structure. In that case these structure
+ * fields will have to be populated using the pdata or pmic structure.
+ */
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ sr->err_weight = OMAP3430_SR_ERRWEIGHT;
+ sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
+ sr->accum_data = OMAP3430_SR_ACCUMDATA;
+ if (!(strcmp(sr->voltdm->name, "mpu"))) {
+ sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
+ sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
+ } else {
+ sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
+ sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
+ }
+ }
+}
+
+static void sr_start_vddautocomp(struct omap_sr *sr)
+{
+ if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
+ dev_warn(&sr->pdev->dev,
+ "%s: smartreflex class driver not registered\n",
+ __func__);
+ return;
+ }
+
+ if (!sr_class->enable(sr->voltdm))
+ sr->autocomp_active = true;
+}
+
+static void sr_stop_vddautocomp(struct omap_sr *sr)
+{
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev,
+ "%s: smartreflex class driver not registered\n",
+ __func__);
+ return;
+ }
+
+ if (sr->autocomp_active) {
+ sr_class->disable(sr->voltdm, 1);
+ sr->autocomp_active = false;
+ }
+}
+
+/*
+ * This function handles the intializations which have to be done
+ * only when both sr device and class driver regiter has
+ * completed. This will be attempted to be called from both sr class
+ * driver register and sr device intializtion API's. Only one call
+ * will ultimately succeed.
+ *
+ * Currenly this function registers interrrupt handler for a particular SR
+ * if smartreflex class driver is already registered and has
+ * requested for interrupts and the SR interrupt line in present.
+ */
+static int sr_late_init(struct omap_sr *sr_info)
+{
+ char *name;
+ struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
+ struct resource *mem;
+ int ret = 0;
+
+ if (sr_class->class_type == SR_CLASS2 &&
+ sr_class->notify_flags && sr_info->irq) {
+
+ name = kzalloc(SMARTREFLEX_NAME_LEN + 1, GFP_KERNEL);
+ strcpy(name, "sr_");
+ strcat(name, sr_info->voltdm->name);
+ ret = request_irq(sr_info->irq, sr_interrupt,
+ 0, name, (void *)sr_info);
+ if (ret)
+ goto error;
+ }
+
+ if (pdata && pdata->enable_on_init)
+ sr_start_vddautocomp(sr_info);
+
+ return ret;
+
+error:
+ iounmap(sr_info->base);
+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ list_del(&sr_info->node);
+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
+ "interrupt handler. Smartreflex will"
+ "not function as desired\n", __func__);
+ kfree(sr_info);
+ return ret;
+}
+
+static void sr_v1_disable(struct omap_sr *sr)
+{
+ int timeout = 0;
+
+ /* Enable MCUDisableAcknowledge interrupt */
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
+
+ /* SRCONFIG - disable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+ /* Disable all other SR interrupts and clear the status */
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+ ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
+ (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+ ERRCONFIG_MCUBOUNDINTST |
+ ERRCONFIG_VPBOUNDINTST_V1));
+
+ /*
+ * Wait for SR to be disabled.
+ * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
+ */
+ omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
+ ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
+ timeout);
+
+ if (timeout >= SR_DISABLE_TIMEOUT)
+ dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
+ __func__);
+
+ /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+ sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
+ ERRCONFIG_MCUDISACKINTST);
+}
+
+static void sr_v2_disable(struct omap_sr *sr)
+{
+ int timeout = 0;
+
+ /* Enable MCUDisableAcknowledge interrupt */
+ sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
+
+ /* SRCONFIG - disable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+ /* Disable all other SR interrupts and clear the status */
+ sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
+ ERRCONFIG_VPBOUNDINTST_V2);
+ sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
+ IRQENABLE_MCUVALIDINT |
+ IRQENABLE_MCUBOUNDSINT));
+ sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
+ IRQSTATUS_MCVALIDINT |
+ IRQSTATUS_MCBOUNDSINT));
+
+ /*
+ * Wait for SR to be disabled.
+ * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
+ */
+ omap_test_timeout((sr_read_reg(sr, IRQSTATUS) &
+ IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
+ timeout);
+
+ if (timeout >= SR_DISABLE_TIMEOUT)
+ dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
+ __func__);
+
+ /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+ sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
+ sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
+}
+
+static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
+{
+ int i;
+
+ if (!sr->nvalue_table) {
+ dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
+ __func__);
+ return 0;
+ }
+
+ for (i = 0; i < sr->nvalue_count; i++) {
+ if (sr->nvalue_table[i].efuse_offs == efuse_offs)
+ return sr->nvalue_table[i].nvalue;
+ }
+
+ return 0;
+}
+
+/* Public Functions */
+
+/**
+ * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
+ * error generator module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the error generator module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module. Returns 0 on success and error value in case of failure.
+ */
+int sr_configure_errgen(struct voltagedomain *voltdm)
+{
+ u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en;
+ u32 vpboundint_st, senp_en = 0, senn_en = 0;
+ u8 senp_shift, senn_shift;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!sr->clk_length)
+ sr_set_clk_length(sr);
+
+ senp_en = sr->senp_mod;
+ senn_en = sr->senn_mod;
+
+ sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+ SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
+
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_config |= SRCONFIG_DELAYCTRL;
+ senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
+ errconfig_offs = ERRCONFIG_V1;
+ vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
+ vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
+ errconfig_offs = ERRCONFIG_V2;
+ vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
+ vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
+ } else {
+ dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+ "module without specifying the ip\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
+ sr_write_reg(sr, SRCONFIG, sr_config);
+ sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
+ (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
+ (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT);
+ sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
+ SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
+ sr_errconfig);
+
+ /* Enabling the interrupts if the ERROR module is used */
+ sr_modify_reg(sr, errconfig_offs,
+ vpboundint_en, (vpboundint_en | vpboundint_st));
+
+ return 0;
+}
+
+/**
+ * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
+ * minmaxavg module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the minmaxavg module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module. Returns 0 on success and error value in case of failure.
+ */
+int sr_configure_minmax(struct voltagedomain *voltdm)
+{
+ u32 sr_config, sr_avgwt;
+ u32 senp_en = 0, senn_en = 0;
+ u8 senp_shift, senn_shift;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!sr->clk_length)
+ sr_set_clk_length(sr);
+
+ senp_en = sr->senp_mod;
+ senn_en = sr->senn_mod;
+
+ sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+ SRCONFIG_SENENABLE |
+ (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
+
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_config |= SRCONFIG_DELAYCTRL;
+ senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
+ } else {
+ dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+ "module without specifying the ip\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
+ sr_write_reg(sr, SRCONFIG, sr_config);
+ sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
+ (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
+ sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
+
+ /*
+ * Enabling the interrupts if MINMAXAVG module is used.
+ * TODO: check if all the interrupts are mandatory
+ */
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+ ERRCONFIG_MCUBOUNDINTEN),
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
+ ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
+ ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ sr_write_reg(sr, IRQSTATUS,
+ IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
+ IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
+ sr_write_reg(sr, IRQENABLE_SET,
+ IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
+ IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
+ }
+
+ return 0;
+}
+
+/**
+ * sr_enable() - Enables the smartreflex module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ * @volt: The voltage at which the Voltage domain associated with
+ * the smartreflex module is operating at.
+ * This is required only to program the correct Ntarget value.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * enable a smartreflex module. Returns 0 on success. Returns error
+ * value if the voltage passed is wrong or if ntarget value is wrong.
+ */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
+{
+ u32 nvalue_reciprocal;
+ struct omap_volt_data *volt_data;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+ int ret;
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
+
+ if (IS_ERR(volt_data)) {
+ dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
+ "for nominal voltage %ld\n", __func__, volt);
+ return -ENODATA;
+ }
+
+ nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
+
+ if (!nvalue_reciprocal) {
+ dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n",
+ __func__, volt);
+ return -ENODATA;
+ }
+
+ /* errminlimit is opp dependent and hence linked to voltage */
+ sr->err_minlimit = volt_data->sr_errminlimit;
+
+ pm_runtime_get_sync(&sr->pdev->dev);
+
+ /* Check if SR is already enabled. If yes do nothing */
+ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
+ return 0;
+
+ /* Configure SR */
+ ret = sr_class->configure(voltdm);
+ if (ret)
+ return ret;
+
+ sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
+
+ /* SRCONFIG - enable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
+ return 0;
+}
+
+/**
+ * sr_disable() - Disables the smartreflex module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * disable a smartreflex module.
+ */
+void sr_disable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* Check if SR clocks are already disabled. If yes do nothing */
+ if (pm_runtime_suspended(&sr->pdev->dev))
+ return;
+
+ /*
+ * Disable SR if only it is indeed enabled. Else just
+ * disable the clocks.
+ */
+ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
+ if (sr->ip_type == SR_TYPE_V1)
+ sr_v1_disable(sr);
+ else if (sr->ip_type == SR_TYPE_V2)
+ sr_v2_disable(sr);
+ }
+
+ pm_runtime_put_sync(&sr->pdev->dev);
+}
+
+/**
+ * sr_register_class() - API to register a smartreflex class parameters.
+ * @class_data: The structure containing various sr class specific data.
+ *
+ * This API is to be called by the smartreflex class driver to register itself
+ * with the smartreflex driver during init. Returns 0 on success else the
+ * error value.
+ */
+int sr_register_class(struct omap_sr_class_data *class_data)
+{
+ struct omap_sr *sr_info;
+
+ if (!class_data) {
+ pr_warning("%s:, Smartreflex class data passed is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (sr_class) {
+ pr_warning("%s: Smartreflex class driver already registered\n",
+ __func__);
+ return -EBUSY;
+ }
+
+ sr_class = class_data;
+
+ /*
+ * Call into late init to do intializations that require
+ * both sr driver and sr class driver to be initiallized.
+ */
+ list_for_each_entry(sr_info, &sr_list, node)
+ sr_late_init(sr_info);
+
+ return 0;
+}
+
+/**
+ * omap_sr_enable() - API to enable SR clocks and to call into the
+ * registered smartreflex class enable API.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to enable
+ * a particular smartreflex module. This API will do the initial
+ * configurations to turn on the smartreflex module and in turn call
+ * into the registered smartreflex class enable API.
+ */
+void omap_sr_enable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->enable(voltdm);
+}
+
+/**
+ * omap_sr_disable() - API to disable SR without resetting the voltage
+ * processor voltage
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to disable
+ * a particular smartreflex module. This API will in turn call
+ * into the registered smartreflex class disable API. This API will tell
+ * the smartreflex class disable not to reset the VP voltage after
+ * disabling smartreflex.
+ */
+void omap_sr_disable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->disable(voltdm, 0);
+}
+
+/**
+ * omap_sr_disable_reset_volt() - API to disable SR and reset the
+ * voltage processor voltage
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to disable
+ * a particular smartreflex module. This API will in turn call
+ * into the registered smartreflex class disable API. This API will tell
+ * the smartreflex class disable to reset the VP voltage after
+ * disabling smartreflex.
+ */
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->disable(voltdm, 1);
+}
+
+/**
+ * omap_sr_register_pmic() - API to register pmic specific info.
+ * @pmic_data: The structure containing pmic specific data.
+ *
+ * This API is to be called from the PMIC specific code to register with
+ * smartreflex driver pmic specific info. Currently the only info required
+ * is the smartreflex init on the PMIC side.
+ */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
+{
+ if (!pmic_data) {
+ pr_warning("%s: Trying to register NULL PMIC data structure"
+ "with smartreflex\n", __func__);
+ return;
+ }
+
+ sr_pmic_data = pmic_data;
+}
+
+/* PM Debug Fs enteries to enable disable smartreflex. */
+static int omap_sr_autocomp_show(void *data, u64 *val)
+{
+ struct omap_sr *sr_info = (struct omap_sr *) data;
+
+ if (!sr_info) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, sr_info->voltdm->name);
+ return -EINVAL;
+ }
+
+ *val = sr_info->autocomp_active;
+
+ return 0;
+}
+
+static int omap_sr_autocomp_store(void *data, u64 val)
+{
+ struct omap_sr *sr_info = (struct omap_sr *) data;
+
+ if (!sr_info) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, sr_info->voltdm->name);
+ return -EINVAL;
+ }
+
+ /* Sanity check */
+ if (val && (val != 1)) {
+ pr_warning("%s: Invalid argument %lld\n", __func__, val);
+ return -EINVAL;
+ }
+
+ if (!val)
+ sr_stop_vddautocomp(sr_info);
+ else
+ sr_start_vddautocomp(sr_info);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
+ omap_sr_autocomp_store, "%llu\n");
+
+static int __init omap_sr_probe(struct platform_device *pdev)
+{
+ struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+ struct omap_sr_data *pdata = pdev->dev.platform_data;
+ struct resource *mem, *irq;
+ struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir;
+ struct omap_volt_data *volt_data;
+ int i, ret = 0;
+
+ if (!sr_info) {
+ dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+ ret = -ENODEV;
+ goto err_free_devinfo;
+ }
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ pm_runtime_enable(&pdev->dev);
+
+ sr_info->pdev = pdev;
+ sr_info->srid = pdev->id;
+ sr_info->voltdm = pdata->voltdm;
+ sr_info->nvalue_table = pdata->nvalue_table;
+ sr_info->nvalue_count = pdata->nvalue_count;
+ sr_info->senn_mod = pdata->senn_mod;
+ sr_info->senp_mod = pdata->senp_mod;
+ sr_info->autocomp_active = false;
+ sr_info->ip_type = pdata->ip_type;
+ sr_info->base = ioremap(mem->start, resource_size(mem));
+ if (!sr_info->base) {
+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+ ret = -ENOMEM;
+ goto err_release_region;
+ }
+
+ if (irq)
+ sr_info->irq = irq->start;
+
+ sr_set_clk_length(sr_info);
+ sr_set_regfields(sr_info);
+
+ list_add(&sr_info->node, &sr_list);
+
+ /*
+ * Call into late init to do intializations that require
+ * both sr driver and sr class driver to be initiallized.
+ */
+ if (sr_class) {
+ ret = sr_late_init(sr_info);
+ if (ret) {
+ pr_warning("%s: Error in SR late init\n", __func__);
+ return ret;
+ }
+ }
+
+ dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
+
+ /*
+ * If the voltage domain debugfs directory is not created, do
+ * not try to create rest of the debugfs entries.
+ */
+ vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
+ if (!vdd_dbg_dir)
+ return -EINVAL;
+
+ dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
+ if (IS_ERR(dbg_dir)) {
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
+ __func__);
+ return PTR_ERR(dbg_dir);
+ }
+
+ (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUGO, dbg_dir,
+ (void *)sr_info, &pm_sr_fops);
+ (void) debugfs_create_x32("errweight", S_IRUGO, dbg_dir,
+ &sr_info->err_weight);
+ (void) debugfs_create_x32("errmaxlimit", S_IRUGO, dbg_dir,
+ &sr_info->err_maxlimit);
+ (void) debugfs_create_x32("errminlimit", S_IRUGO, dbg_dir,
+ &sr_info->err_minlimit);
+
+ nvalue_dir = debugfs_create_dir("nvalue", dbg_dir);
+ if (IS_ERR(nvalue_dir)) {
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
+ "for n-values\n", __func__);
+ return PTR_ERR(nvalue_dir);
+ }
+
+ omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
+ if (!volt_data) {
+ dev_warn(&pdev->dev, "%s: No Voltage table for the"
+ " corresponding vdd vdd_%s. Cannot create debugfs"
+ "entries for n-values\n",
+ __func__, sr_info->voltdm->name);
+ return -ENODATA;
+ }
+
+ for (i = 0; i < sr_info->nvalue_count; i++) {
+ char *name;
+ char volt_name[32];
+
+ name = kzalloc(NVALUE_NAME_LEN + 1, GFP_KERNEL);
+ if (!name) {
+ dev_err(&pdev->dev, "%s: Unable to allocate memory"
+ " for n-value directory name\n", __func__);
+ return -ENOMEM;
+ }
+
+ strcpy(name, "volt_");
+ sprintf(volt_name, "%d", volt_data[i].volt_nominal);
+ strcat(name, volt_name);
+ (void) debugfs_create_x32(name, S_IRUGO | S_IWUGO, nvalue_dir,
+ &(sr_info->nvalue_table[i].nvalue));
+ }
+
+ return ret;
+
+err_release_region:
+ release_mem_region(mem->start, resource_size(mem));
+err_free_devinfo:
+ kfree(sr_info);
+
+ return ret;
+}
+
+static int __devexit omap_sr_remove(struct platform_device *pdev)
+{
+ struct omap_sr_data *pdata = pdev->dev.platform_data;
+ struct omap_sr *sr_info;
+ struct resource *mem;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_info = _sr_lookup(pdata->voltdm);
+ if (!sr_info) {
+ dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (sr_info->autocomp_active)
+ sr_stop_vddautocomp(sr_info);
+
+ list_del(&sr_info->node);
+ iounmap(sr_info->base);
+ kfree(sr_info);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ return 0;
+}
+
+static struct platform_driver smartreflex_driver = {
+ .remove = omap_sr_remove,
+ .driver = {
+ .name = "smartreflex",
+ },
+};
+
+static int __init sr_init(void)
+{
+ int ret = 0;
+
+ /*
+ * sr_init is a late init. If by then a pmic specific API is not
+ * registered either there is no need for anything to be done on
+ * the PMIC side or somebody has forgotten to register a PMIC
+ * handler. Warn for the second condition.
+ */
+ if (sr_pmic_data && sr_pmic_data->sr_pmic_init)
+ sr_pmic_data->sr_pmic_init();
+ else
+ pr_warning("%s: No PMIC hook to init smartreflex\n", __func__);
+
+ ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
+ if (ret) {
+ pr_err("%s: platform driver register failed for SR\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit sr_exit(void)
+{
+ platform_driver_unregister(&smartreflex_driver);
+}
+late_initcall(sr_init);
+module_exit(sr_exit);
+
+MODULE_DESCRIPTION("OMAP Smartreflex Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
new file mode 100644
index 000000000000..786d685c09a9
--- /dev/null
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -0,0 +1,146 @@
+/*
+ * OMAP3/OMAP4 smartreflex device file
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Based originally on code from smartreflex.c
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@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/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <plat/omap_device.h>
+#include <plat/smartreflex.h>
+#include <plat/voltage.h>
+
+#include "control.h"
+
+static bool sr_enable_on_init;
+
+static struct omap_device_pm_latency omap_sr_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
+ },
+};
+
+/* Read EFUSE values from control registers for OMAP3430 */
+static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
+ struct omap_sr_data *sr_data)
+{
+ struct omap_sr_nvalue_table *nvalue_table;
+ int i, count = 0;
+
+ while (volt_data[count].volt_nominal)
+ count++;
+
+ nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
+ GFP_KERNEL);
+
+ for (i = 0; i < count; i++) {
+ u32 v;
+ /*
+ * In OMAP4 the efuse registers are 24 bit aligned.
+ * A __raw_readl will fail for non-32 bit aligned address
+ * and hence the 8-bit read and shift.
+ */
+ if (cpu_is_omap44xx()) {
+ u16 offset = volt_data[i].sr_efuse_offs;
+
+ v = omap_ctrl_readb(offset) |
+ omap_ctrl_readb(offset + 1) << 8 |
+ omap_ctrl_readb(offset + 2) << 16;
+ } else {
+ v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
+ }
+
+ nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs;
+ nvalue_table[i].nvalue = v;
+ }
+
+ sr_data->nvalue_table = nvalue_table;
+ sr_data->nvalue_count = count;
+}
+
+static int sr_dev_init(struct omap_hwmod *oh, void *user)
+{
+ struct omap_sr_data *sr_data;
+ struct omap_device *od;
+ struct omap_volt_data *volt_data;
+ char *name = "smartreflex";
+ static int i;
+
+ sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);
+ if (!sr_data) {
+ pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n",
+ __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ if (!oh->vdd_name) {
+ pr_err("%s: No voltage domain specified for %s."
+ "Cannot initialize\n", __func__, oh->name);
+ goto exit;
+ }
+
+ sr_data->ip_type = oh->class->rev;
+ sr_data->senn_mod = 0x1;
+ sr_data->senp_mod = 0x1;
+
+ sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ if (IS_ERR(sr_data->voltdm)) {
+ pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
+ __func__, oh->vdd_name);
+ goto exit;
+ }
+
+ omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
+ if (!volt_data) {
+ pr_warning("%s: No Voltage table registerd fo VDD%d."
+ "Something really wrong\n\n", __func__, i + 1);
+ goto exit;
+ }
+
+ sr_set_nvalues(volt_data, sr_data);
+
+ sr_data->enable_on_init = sr_enable_on_init;
+
+ od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
+ omap_sr_latency,
+ ARRAY_SIZE(omap_sr_latency), 0);
+ if (IS_ERR(od))
+ pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
+ __func__, name, oh->name);
+exit:
+ i++;
+ kfree(sr_data);
+ return 0;
+}
+
+/*
+ * API to be called from board files to enable smartreflex
+ * autocompensation at init.
+ */
+void __init omap_enable_smartreflex_on_init(void)
+{
+ sr_enable_on_init = true;
+}
+
+int __init omap_devinit_smartreflex(void)
+{
+ return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
+}
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index 92e6e1a12af8..055310cc77de 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -21,14 +21,20 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/io.h>
#include <mach/hardware.h>
-#include "prm.h"
-#include "cm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
#include "sdrc.h"
.text
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index ab4973695c71..f9007580aea3 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -21,14 +21,20 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/io.h>
#include <mach/hardware.h>
-#include "prm.h"
-#include "cm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
#include "sdrc.h"
.text
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 3637274af5be..7f893a29d500 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -32,7 +32,7 @@
#include <mach/io.h>
#include "sdrc.h"
-#include "cm.h"
+#include "cm2xxx_3xxx.h"
.text
@@ -104,6 +104,12 @@
* touching the SDRAM. Until that time, users who know that their use case
* can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING
* option.
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
*/
ENTRY(omap3_sram_configure_core_dpll)
stmfd sp!, {r1-r12, lr} @ store regs to stack
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index e13c29eecf2b..4e48e786bec7 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -195,7 +195,6 @@ static struct clocksource clocksource_gpt = {
.rating = 300,
.read = clocksource_read_cycles,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -203,7 +202,7 @@ static struct clocksource clocksource_gpt = {
static void __init omap2_gp_clocksource_init(void)
{
static struct omap_dm_timer *gpt;
- u32 tick_rate, tick_period;
+ u32 tick_rate;
static char err1[] __initdata = KERN_ERR
"%s: failed to request dm-timer\n";
static char err2[] __initdata = KERN_ERR
@@ -216,13 +215,10 @@ static void __init omap2_gp_clocksource_init(void)
omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK);
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
- tick_period = (tick_rate / HZ) - 1;
omap_dm_timer_set_load_start(gpt, 1, 0);
- clocksource_gpt.mult =
- clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift);
- if (clocksource_register(&clocksource_gpt))
+ if (clocksource_register_hz(&clocksource_gpt, tick_rate))
printk(err2, clocksource_gpt.name);
}
#endif
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 64a0112b70a5..30f112bd3e4d 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -120,8 +120,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
/* GPMC_CLK rate = fclk rate / div */
- t.sync_clk = 12 /* 11.1 nsec */;
- tmp = (t.sync_clk * 1000 + fclk_ps - 1) / fclk_ps;
+ t.sync_clk = 11100 /* 11.1 nsec */;
+ tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
if (tmp > 4)
return -ERANGE;
if (tmp <= 0)
@@ -216,6 +216,7 @@ static struct resource tusb_resources[] = {
.flags = IORESOURCE_MEM,
},
{ /* IRQ */
+ .name = "mc",
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
new file mode 100644
index 000000000000..ed6079c94c57
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.c
@@ -0,0 +1,1571 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@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/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+
+#include <plat/common.h>
+#include <plat/voltage.h>
+
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "control.h"
+
+#define VP_IDLE_TIMEOUT 200
+#define VP_TRANXDONE_TIMEOUT 300
+#define VOLTAGE_DIR_SIZE 16
+
+/* Voltage processor register offsets */
+struct vp_reg_offs {
+ u8 vpconfig;
+ u8 vstepmin;
+ u8 vstepmax;
+ u8 vlimitto;
+ u8 vstatus;
+ u8 voltage;
+};
+
+/* Voltage Processor bit field values, shifts and masks */
+struct vp_reg_val {
+ /* PRM module */
+ u16 prm_mod;
+ /* VPx_VPCONFIG */
+ u32 vpconfig_erroroffset;
+ u16 vpconfig_errorgain;
+ u32 vpconfig_errorgain_mask;
+ u8 vpconfig_errorgain_shift;
+ u32 vpconfig_initvoltage_mask;
+ u8 vpconfig_initvoltage_shift;
+ u32 vpconfig_timeouten;
+ u32 vpconfig_initvdd;
+ u32 vpconfig_forceupdate;
+ u32 vpconfig_vpenable;
+ /* VPx_VSTEPMIN */
+ u8 vstepmin_stepmin;
+ u16 vstepmin_smpswaittimemin;
+ u8 vstepmin_stepmin_shift;
+ u8 vstepmin_smpswaittimemin_shift;
+ /* VPx_VSTEPMAX */
+ u8 vstepmax_stepmax;
+ u16 vstepmax_smpswaittimemax;
+ u8 vstepmax_stepmax_shift;
+ u8 vstepmax_smpswaittimemax_shift;
+ /* VPx_VLIMITTO */
+ u8 vlimitto_vddmin;
+ u8 vlimitto_vddmax;
+ u16 vlimitto_timeout;
+ u8 vlimitto_vddmin_shift;
+ u8 vlimitto_vddmax_shift;
+ u8 vlimitto_timeout_shift;
+ /* PRM_IRQSTATUS*/
+ u32 tranxdone_status;
+};
+
+/* Voltage controller registers and offsets */
+struct vc_reg_info {
+ /* PRM module */
+ u16 prm_mod;
+ /* VC register offsets */
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 bypass_val_reg;
+ u8 cmdval_reg;
+ u8 voltsetup_reg;
+ /*VC_SMPS_SA*/
+ u8 smps_sa_shift;
+ u32 smps_sa_mask;
+ /* VC_SMPS_VOL_RA */
+ u8 smps_volra_shift;
+ u32 smps_volra_mask;
+ /* VC_BYPASS_VAL */
+ u8 data_shift;
+ u8 slaveaddr_shift;
+ u8 regaddr_shift;
+ u32 valid;
+ /* VC_CMD_VAL */
+ u8 cmd_on_shift;
+ u8 cmd_onlp_shift;
+ u8 cmd_ret_shift;
+ u8 cmd_off_shift;
+ u32 cmd_on_mask;
+ /* PRM_VOLTSETUP */
+ u8 voltsetup_shift;
+ u32 voltsetup_mask;
+};
+
+/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data : voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
+ * @pmic_info : pmic specific parameters which should be populted by
+ * the pmic drivers.
+ * @vp_offs : structure containing the offsets for various
+ * vp registers
+ * @vp_reg : the register values, shifts, masks for various
+ * vp registers
+ * @vc_reg : structure containing various various vc registers,
+ * shifts, masks etc.
+ * @voltdm : pointer to the voltage domain structure
+ * @debug_dir : debug directory for this voltage domain.
+ * @curr_volt : current voltage for this vdd.
+ * @ocp_mod : The prm module for accessing the prm irqstatus reg.
+ * @prm_irqst_reg : prm irqstatus register.
+ * @vp_enabled : flag to keep track of whether vp is enabled or not
+ * @volt_scale : API to scale the voltage of the vdd.
+ */
+struct omap_vdd_info {
+ struct omap_volt_data *volt_data;
+ struct omap_volt_pmic_info *pmic_info;
+ struct vp_reg_offs vp_offs;
+ struct vp_reg_val vp_reg;
+ struct vc_reg_info vc_reg;
+ struct voltagedomain voltdm;
+ struct dentry *debug_dir;
+ u32 curr_volt;
+ u16 ocp_mod;
+ u8 prm_irqst_reg;
+ bool vp_enabled;
+ u32 (*read_reg) (u16 mod, u8 offset);
+ void (*write_reg) (u32 val, u16 mod, u8 offset);
+ int (*volt_scale) (struct omap_vdd_info *vdd,
+ unsigned long target_volt);
+};
+
+static struct omap_vdd_info *vdd_info;
+/*
+ * Number of scalable voltage domains.
+ */
+static int nr_scalable_vdd;
+
+/* OMAP3 VDD sturctures */
+static struct omap_vdd_info omap3_vdd_info[] = {
+ {
+ .vp_offs = {
+ .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "mpu",
+ },
+ },
+ {
+ .vp_offs = {
+ .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "core",
+ },
+ },
+};
+
+#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
+
+/* OMAP4 VDD sturctures */
+static struct omap_vdd_info omap4_vdd_info[] = {
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "mpu",
+ },
+ },
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "iva",
+ },
+ },
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "core",
+ },
+ },
+};
+
+#define OMAP4_NR_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)
+
+/*
+ * Structures containing OMAP3430/OMAP3630 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \
+{ \
+ .volt_nominal = _v_nom, \
+ .sr_efuse_offs = _efuse_offs, \
+ .sr_errminlimit = _errminlimit, \
+ .vp_errgain = _errgain \
+}
+
+/* VDD1 */
+static struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+static struct omap_volt_data omap34xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_volt_data omap36xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/*
+ * Structures containing OMAP4430 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct dentry *voltage_dir;
+
+/* Init function pointers */
+static void (*vc_init) (struct omap_vdd_info *vdd);
+static int (*vdd_data_configure) (struct omap_vdd_info *vdd);
+
+static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
+{
+ return omap2_prm_read_mod_reg(mod, offset);
+}
+
+static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)
+{
+ omap2_prm_write_mod_reg(val, mod, offset);
+}
+
+static u32 omap4_voltage_read_reg(u16 mod, u8 offset)
+{
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ mod, offset);
+}
+
+static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
+{
+ omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
+}
+
+/* Voltage debugfs support */
+static int vp_volt_debug_get(void *data, u64 *val)
+{
+ struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
+ u8 vsel;
+
+ if (!vdd) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
+ }
+
+ vsel = vdd->read_reg(vdd->vp_reg.prm_mod, vdd->vp_offs.voltage);
+ pr_notice("curr_vsel = %x\n", vsel);
+
+ if (!vdd->pmic_info->vsel_to_uv) {
+ pr_warning("PMIC function to convert vsel to voltage"
+ "in uV not registerd\n");
+ return -EINVAL;
+ }
+
+ *val = vdd->pmic_info->vsel_to_uv(vsel);
+ return 0;
+}
+
+static int nom_volt_debug_get(void *data, u64 *val)
+{
+ struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
+
+ if (!vdd) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
+ }
+
+ *val = omap_voltage_get_nom_volt(&vdd->voltdm);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
+ "%llu\n");
+static void vp_latch_vsel(struct omap_vdd_info *vdd)
+{
+ u32 vpconfig;
+ u16 mod;
+ unsigned long uvdc;
+ char vsel;
+
+ uvdc = omap_voltage_get_nom_volt(&vdd->voltdm);
+ if (!uvdc) {
+ pr_warning("%s: unable to find current voltage for vdd_%s\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+ pr_warning("%s: PMIC function to convert voltage in uV to"
+ " vsel not registered\n", __func__);
+ return;
+ }
+
+ mod = vdd->vp_reg.prm_mod;
+
+ vsel = vdd->pmic_info->uv_to_vsel(uvdc);
+
+ vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ vpconfig &= ~(vdd->vp_reg.vpconfig_initvoltage_mask |
+ vdd->vp_reg.vpconfig_initvdd);
+ vpconfig |= vsel << vdd->vp_reg.vpconfig_initvoltage_shift;
+
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ vdd->write_reg((vpconfig | vdd->vp_reg.vpconfig_initvdd), mod,
+ vdd->vp_offs.vpconfig);
+
+ /* Clear initVDD copy trigger bit */
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+}
+
+/* Generic voltage init functions */
+static void __init vp_init(struct omap_vdd_info *vdd)
+{
+ u32 vp_val;
+ u16 mod;
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ mod = vdd->vp_reg.prm_mod;
+
+ vp_val = vdd->vp_reg.vpconfig_erroroffset |
+ (vdd->vp_reg.vpconfig_errorgain <<
+ vdd->vp_reg.vpconfig_errorgain_shift) |
+ vdd->vp_reg.vpconfig_timeouten;
+ vdd->write_reg(vp_val, mod, vdd->vp_offs.vpconfig);
+
+ vp_val = ((vdd->vp_reg.vstepmin_smpswaittimemin <<
+ vdd->vp_reg.vstepmin_smpswaittimemin_shift) |
+ (vdd->vp_reg.vstepmin_stepmin <<
+ vdd->vp_reg.vstepmin_stepmin_shift));
+ vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmin);
+
+ vp_val = ((vdd->vp_reg.vstepmax_smpswaittimemax <<
+ vdd->vp_reg.vstepmax_smpswaittimemax_shift) |
+ (vdd->vp_reg.vstepmax_stepmax <<
+ vdd->vp_reg.vstepmax_stepmax_shift));
+ vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmax);
+
+ vp_val = ((vdd->vp_reg.vlimitto_vddmax <<
+ vdd->vp_reg.vlimitto_vddmax_shift) |
+ (vdd->vp_reg.vlimitto_vddmin <<
+ vdd->vp_reg.vlimitto_vddmin_shift) |
+ (vdd->vp_reg.vlimitto_timeout <<
+ vdd->vp_reg.vlimitto_timeout_shift));
+ vdd->write_reg(vp_val, mod, vdd->vp_offs.vlimitto);
+}
+
+static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
+{
+ char *name;
+
+ name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
+ if (!name) {
+ pr_warning("%s: Unable to allocate memory for debugfs"
+ " directory name for vdd_%s",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+ strcpy(name, "vdd_");
+ strcat(name, vdd->voltdm.name);
+
+ vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
+ if (IS_ERR(vdd->debug_dir)) {
+ pr_warning("%s: Unable to create debugfs directory for"
+ " vdd_%s\n", __func__, vdd->voltdm.name);
+ vdd->debug_dir = NULL;
+ return;
+ }
+
+ (void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vpconfig_errorgain));
+ (void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
+ vdd->debug_dir,
+ &(vdd->vp_reg.vstepmin_smpswaittimemin));
+ (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vstepmin_stepmin));
+ (void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
+ vdd->debug_dir,
+ &(vdd->vp_reg.vstepmax_smpswaittimemax));
+ (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vstepmax_stepmax));
+ (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vlimitto_vddmax));
+ (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vlimitto_vddmin));
+ (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_reg.vlimitto_timeout));
+ (void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
+ (void *) vdd, &vp_volt_debug_fops);
+ (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
+ vdd->debug_dir, (void *) vdd,
+ &nom_volt_debug_fops);
+}
+
+/* Voltage scale and accessory APIs */
+static int _pre_volt_scale(struct omap_vdd_info *vdd,
+ unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
+{
+ struct omap_volt_data *volt_data;
+ u32 vc_cmdval, vp_errgain_val;
+ u16 vp_mod, vc_mod;
+
+ /* Check if suffiecient pmic info is available for this vdd */
+ if (!vdd->pmic_info) {
+ pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ if (!vdd->pmic_info->uv_to_vsel) {
+ pr_err("%s: PMIC function to convert voltage in uV to"
+ "vsel not registered. Hence unable to scale voltage"
+ "for vdd_%s\n", __func__, vdd->voltdm.name);
+ return -ENODATA;
+ }
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ vp_mod = vdd->vp_reg.prm_mod;
+ vc_mod = vdd->vc_reg.prm_mod;
+
+ /* Get volt_data corresponding to target_volt */
+ volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
+ if (IS_ERR(volt_data))
+ volt_data = NULL;
+
+ *target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
+ *current_vsel = vdd->read_reg(vp_mod, vdd->vp_offs.voltage);
+
+ /* Setting the ON voltage to the new target voltage */
+ vc_cmdval = vdd->read_reg(vc_mod, vdd->vc_reg.cmdval_reg);
+ vc_cmdval &= ~vdd->vc_reg.cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vdd->vc_reg.cmd_on_shift);
+ vdd->write_reg(vc_cmdval, vc_mod, vdd->vc_reg.cmdval_reg);
+
+ /* Setting vp errorgain based on the voltage */
+ if (volt_data) {
+ vp_errgain_val = vdd->read_reg(vp_mod,
+ vdd->vp_offs.vpconfig);
+ vdd->vp_reg.vpconfig_errorgain = volt_data->vp_errgain;
+ vp_errgain_val &= ~vdd->vp_reg.vpconfig_errorgain_mask;
+ vp_errgain_val |= vdd->vp_reg.vpconfig_errorgain <<
+ vdd->vp_reg.vpconfig_errorgain_shift;
+ vdd->write_reg(vp_errgain_val, vp_mod,
+ vdd->vp_offs.vpconfig);
+ }
+
+ return 0;
+}
+
+static void _post_volt_scale(struct omap_vdd_info *vdd,
+ unsigned long target_volt, u8 target_vsel, u8 current_vsel)
+{
+ u32 smps_steps = 0, smps_delay = 0;
+
+ smps_steps = abs(target_vsel - current_vsel);
+ /* SMPS slew rate / step size. 2us added as buffer. */
+ smps_delay = ((smps_steps * vdd->pmic_info->step_size) /
+ vdd->pmic_info->slew_rate) + 2;
+ udelay(smps_delay);
+
+ vdd->curr_volt = target_volt;
+}
+
+/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
+static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt)
+{
+ u32 loop_cnt = 0, retries_cnt = 0;
+ u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
+ u16 mod;
+ u8 target_vsel, current_vsel;
+ int ret;
+
+ ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ mod = vdd->vc_reg.prm_mod;
+
+ vc_valid = vdd->vc_reg.valid;
+ vc_bypass_val_reg = vdd->vc_reg.bypass_val_reg;
+ vc_bypass_value = (target_vsel << vdd->vc_reg.data_shift) |
+ (vdd->pmic_info->pmic_reg <<
+ vdd->vc_reg.regaddr_shift) |
+ (vdd->pmic_info->i2c_slave_addr <<
+ vdd->vc_reg.slaveaddr_shift);
+
+ vdd->write_reg(vc_bypass_value, mod, vc_bypass_val_reg);
+ vdd->write_reg(vc_bypass_value | vc_valid, mod, vc_bypass_val_reg);
+
+ vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
+ /*
+ * Loop till the bypass command is acknowledged from the SMPS.
+ * NOTE: This is legacy code. The loop count and retry count needs
+ * to be revisited.
+ */
+ while (!(vc_bypass_value & vc_valid)) {
+ loop_cnt++;
+
+ if (retries_cnt > 10) {
+ pr_warning("%s: Retry count exceeded\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (loop_cnt > 50) {
+ retries_cnt++;
+ loop_cnt = 0;
+ udelay(10);
+ }
+ vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
+ }
+
+ _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
+ return 0;
+}
+
+/* VP force update method of voltage scaling */
+static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt)
+{
+ u32 vpconfig;
+ u16 mod, ocp_mod;
+ u8 target_vsel, current_vsel, prm_irqst_reg;
+ int ret, timeout = 0;
+
+ ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ mod = vdd->vp_reg.prm_mod;
+ ocp_mod = vdd->ocp_mod;
+ prm_irqst_reg = vdd->prm_irqst_reg;
+
+ /*
+ * Clear all pending TransactionDone interrupt/status. Typical latency
+ * is <3us
+ */
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vdd->write_reg(vdd->vp_reg.tranxdone_status,
+ ocp_mod, prm_irqst_reg);
+ if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
+ vdd->vp_reg.tranxdone_status))
+ break;
+ udelay(1);
+ }
+ if (timeout >= VP_TRANXDONE_TIMEOUT) {
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
+ "Voltage change aborted", __func__, vdd->voltdm.name);
+ return -ETIMEDOUT;
+ }
+
+ /* Configure for VP-Force Update */
+ vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ vpconfig &= ~(vdd->vp_reg.vpconfig_initvdd |
+ vdd->vp_reg.vpconfig_forceupdate |
+ vdd->vp_reg.vpconfig_initvoltage_mask);
+ vpconfig |= ((target_vsel <<
+ vdd->vp_reg.vpconfig_initvoltage_shift));
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ vpconfig |= vdd->vp_reg.vpconfig_initvdd;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ /* Force update of voltage */
+ vpconfig |= vdd->vp_reg.vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ /*
+ * Wait for TransactionDone. Typical latency is <200us.
+ * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+ */
+ timeout = 0;
+ omap_test_timeout((vdd->read_reg(ocp_mod, prm_irqst_reg) &
+ vdd->vp_reg.tranxdone_status),
+ VP_TRANXDONE_TIMEOUT, timeout);
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
+ "TRANXDONE never got set after the voltage update\n",
+ __func__, vdd->voltdm.name);
+
+ _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
+
+ /*
+ * Disable TransactionDone interrupt , clear all status, clear
+ * control registers
+ */
+ timeout = 0;
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vdd->write_reg(vdd->vp_reg.tranxdone_status,
+ ocp_mod, prm_irqst_reg);
+ if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
+ vdd->vp_reg.tranxdone_status))
+ break;
+ udelay(1);
+ }
+
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
+ "to clear the TRANXDONE status\n",
+ __func__, vdd->voltdm.name);
+
+ vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ /* Clear initVDD copy trigger bit */
+ vpconfig &= ~vdd->vp_reg.vpconfig_initvdd;;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ /* Clear force bit */
+ vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ return 0;
+}
+
+/* OMAP3 specific voltage init functions */
+
+/*
+ * Intializes the voltage controller registers with the PMIC and board
+ * specific parameters and voltage setup times for OMAP3.
+ */
+static void __init omap3_vc_init(struct omap_vdd_info *vdd)
+{
+ u32 vc_val;
+ u16 mod;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ static bool is_initialized;
+
+ if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+ pr_err("%s: PMIC info requried to configure vc for"
+ "vdd_%s not populated.Hence cannot initialize vc\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ mod = vdd->vc_reg.prm_mod;
+
+ /* Set up the SMPS_SA(i2c slave address in VC */
+ vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
+ vc_val &= ~vdd->vc_reg.smps_sa_mask;
+ vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
+
+ /* Setup the VOLRA(pmic reg addr) in VC */
+ vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
+ vc_val &= ~vdd->vc_reg.smps_volra_mask;
+ vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
+
+ /*Configure the setup times */
+ vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
+ vc_val &= ~vdd->vc_reg.voltsetup_mask;
+ vc_val |= vdd->pmic_info->volt_setup_time <<
+ vdd->vc_reg.voltsetup_shift;
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
+
+ /* Set up the on, inactive, retention and off voltage */
+ on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
+ onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
+ ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
+ off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
+ vc_val = ((on_vsel << vdd->vc_reg.cmd_on_shift) |
+ (onlp_vsel << vdd->vc_reg.cmd_onlp_shift) |
+ (ret_vsel << vdd->vc_reg.cmd_ret_shift) |
+ (off_vsel << vdd->vc_reg.cmd_off_shift));
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.cmdval_reg);
+
+ if (is_initialized)
+ return;
+
+ /* Generic VC parameters init */
+ vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, mod,
+ OMAP3_PRM_VC_CH_CONF_OFFSET);
+ vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
+ OMAP3_PRM_VC_I2C_CFG_OFFSET);
+ vdd->write_reg(OMAP3_CLKSETUP, mod, OMAP3_PRM_CLKSETUP_OFFSET);
+ vdd->write_reg(OMAP3_VOLTOFFSET, mod, OMAP3_PRM_VOLTOFFSET_OFFSET);
+ vdd->write_reg(OMAP3_VOLTSETUP2, mod, OMAP3_PRM_VOLTSETUP2_OFFSET);
+ is_initialized = true;
+}
+
+/* Sets up all the VDD related info for OMAP3 */
+static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
+{
+ struct clk *sys_ck;
+ u32 sys_clk_speed, timeout_val, waittime;
+
+ if (!vdd->pmic_info) {
+ pr_err("%s: PMIC info requried to configure vdd_%s not"
+ "populated.Hence cannot initialize vdd_%s\n",
+ __func__, vdd->voltdm.name, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ if (!strcmp(vdd->voltdm.name, "mpu")) {
+ if (cpu_is_omap3630())
+ vdd->volt_data = omap36xx_vddmpu_volt_data;
+ else
+ vdd->volt_data = omap34xx_vddmpu_volt_data;
+
+ vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
+ vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
+ vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT;
+ vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK;
+ vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA0_SHIFT;
+ vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA0_MASK;
+ vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT;
+ vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK;
+ } else if (!strcmp(vdd->voltdm.name, "core")) {
+ if (cpu_is_omap3630())
+ vdd->volt_data = omap36xx_vddcore_volt_data;
+ else
+ vdd->volt_data = omap34xx_vddcore_volt_data;
+
+ vdd->vp_reg.tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK;
+ vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET;
+ vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT;
+ vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK;
+ vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA1_SHIFT;
+ vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA1_MASK;
+ vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT;
+ vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK;
+ } else {
+ pr_warning("%s: vdd_%s does not exisit in OMAP3\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, "sys_ck");
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys clk to calculate"
+ "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+
+ /* Generic voltage parameters */
+ vdd->curr_volt = 1200000;
+ vdd->ocp_mod = OCP_MOD;
+ vdd->prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET;
+ vdd->read_reg = omap3_voltage_read_reg;
+ vdd->write_reg = omap3_voltage_write_reg;
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
+
+ /* VC parameters */
+ vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
+ vdd->vc_reg.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET;
+ vdd->vc_reg.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
+ vdd->vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
+ vdd->vc_reg.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
+ vdd->vc_reg.data_shift = OMAP3430_DATA_SHIFT;
+ vdd->vc_reg.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT;
+ vdd->vc_reg.regaddr_shift = OMAP3430_REGADDR_SHIFT;
+ vdd->vc_reg.valid = OMAP3430_VALID_MASK;
+ vdd->vc_reg.cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT;
+ vdd->vc_reg.cmd_on_mask = OMAP3430_VC_CMD_ON_MASK;
+ vdd->vc_reg.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT;
+ vdd->vc_reg.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT;
+ vdd->vc_reg.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT;
+
+ vdd->vp_reg.prm_mod = OMAP3430_GR_MOD;
+
+ /* VPCONFIG bit fields */
+ vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
+ OMAP3430_ERROROFFSET_SHIFT);
+ vdd->vp_reg.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK;
+ vdd->vp_reg.vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK;
+ vdd->vp_reg.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK;
+ vdd->vp_reg.vpconfig_initvdd = OMAP3430_INITVDD_MASK;
+ vdd->vp_reg.vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK;
+ vdd->vp_reg.vpconfig_vpenable = OMAP3430_VPENABLE_MASK;
+
+ /* VSTEPMIN VSTEPMAX bit fields */
+ waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
+ sys_clk_speed) / 1000;
+ vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
+ vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
+ vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
+ vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
+ vdd->vp_reg.vstepmin_smpswaittimemin_shift =
+ OMAP3430_SMPSWAITTIMEMIN_SHIFT;
+ vdd->vp_reg.vstepmax_smpswaittimemax_shift =
+ OMAP3430_SMPSWAITTIMEMAX_SHIFT;
+ vdd->vp_reg.vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT;
+ vdd->vp_reg.vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT;
+
+ /* VLIMITTO bit fields */
+ timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
+ vdd->vp_reg.vlimitto_timeout = timeout_val;
+ vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
+ vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
+ vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT;
+ vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT;
+ vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
+
+ return 0;
+}
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init(struct omap_vdd_info *vdd)
+{
+ u32 vc_val;
+ u16 mod;
+ static bool is_initialized;
+
+ if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+ pr_err("%s: PMIC info requried to configure vc for"
+ "vdd_%s not populated.Hence cannot initialize vc\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ mod = vdd->vc_reg.prm_mod;
+
+ /* Set up the SMPS_SA(i2c slave address in VC */
+ vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
+ vc_val &= ~vdd->vc_reg.smps_sa_mask;
+ vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
+
+ /* Setup the VOLRA(pmic reg addr) in VC */
+ vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
+ vc_val &= ~vdd->vc_reg.smps_volra_mask;
+ vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
+ vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
+
+ /* TODO: Configure setup times and CMD_VAL values*/
+
+ if (is_initialized)
+ return;
+
+ /* Generic VC parameters init */
+ vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
+ OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
+ OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
+ vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
+
+ vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
+ vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+
+ is_initialized = true;
+}
+
+/* Sets up all the VDD related info for OMAP4 */
+static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
+{
+ struct clk *sys_ck;
+ u32 sys_clk_speed, timeout_val, waittime;
+
+ if (!vdd->pmic_info) {
+ pr_err("%s: PMIC info requried to configure vdd_%s not"
+ "populated.Hence cannot initialize vdd_%s\n",
+ __func__, vdd->voltdm.name, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ if (!strcmp(vdd->voltdm.name, "mpu")) {
+ vdd->volt_data = omap44xx_vdd_mpu_volt_data;
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
+ vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
+ vdd->vc_reg.smps_sa_shift =
+ OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT;
+ vdd->vc_reg.smps_sa_mask =
+ OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK;
+ vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT;
+ vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK;
+ vdd->vc_reg.voltsetup_reg =
+ OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET;
+ vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
+ } else if (!strcmp(vdd->voltdm.name, "core")) {
+ vdd->volt_data = omap44xx_vdd_core_volt_data;
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
+ vdd->vc_reg.cmdval_reg =
+ OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
+ vdd->vc_reg.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT;
+ vdd->vc_reg.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK;
+ vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT;
+ vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK;
+ vdd->vc_reg.voltsetup_reg =
+ OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET;
+ vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
+ } else if (!strcmp(vdd->voltdm.name, "iva")) {
+ vdd->volt_data = omap44xx_vdd_iva_volt_data;
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
+ vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
+ vdd->vc_reg.smps_sa_shift =
+ OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT;
+ vdd->vc_reg.smps_sa_mask =
+ OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK;
+ vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT;
+ vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK;
+ vdd->vc_reg.voltsetup_reg =
+ OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET;
+ vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
+ } else {
+ pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, "sys_clkin_ck");
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys clk to calculate"
+ "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+
+ /* Generic voltage parameters */
+ vdd->curr_volt = 1200000;
+ vdd->ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+ vdd->read_reg = omap4_voltage_read_reg;
+ vdd->write_reg = omap4_voltage_write_reg;
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
+
+ /* VC parameters */
+ vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
+ vdd->vc_reg.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET;
+ vdd->vc_reg.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET;
+ vdd->vc_reg.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET;
+ vdd->vc_reg.data_shift = OMAP4430_DATA_SHIFT;
+ vdd->vc_reg.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT;
+ vdd->vc_reg.regaddr_shift = OMAP4430_REGADDR_SHIFT;
+ vdd->vc_reg.valid = OMAP4430_VALID_MASK;
+ vdd->vc_reg.cmd_on_shift = OMAP4430_ON_SHIFT;
+ vdd->vc_reg.cmd_on_mask = OMAP4430_ON_MASK;
+ vdd->vc_reg.cmd_onlp_shift = OMAP4430_ONLP_SHIFT;
+ vdd->vc_reg.cmd_ret_shift = OMAP4430_RET_SHIFT;
+ vdd->vc_reg.cmd_off_shift = OMAP4430_OFF_SHIFT;
+
+ vdd->vp_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
+
+ /* VPCONFIG bit fields */
+ vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
+ OMAP4430_ERROROFFSET_SHIFT);
+ vdd->vp_reg.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK;
+ vdd->vp_reg.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK;
+ vdd->vp_reg.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK;
+ vdd->vp_reg.vpconfig_initvdd = OMAP4430_INITVDD_MASK;
+ vdd->vp_reg.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK;
+ vdd->vp_reg.vpconfig_vpenable = OMAP4430_VPENABLE_MASK;
+
+ /* VSTEPMIN VSTEPMAX bit fields */
+ waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
+ sys_clk_speed) / 1000;
+ vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
+ vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
+ vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
+ vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
+ vdd->vp_reg.vstepmin_smpswaittimemin_shift =
+ OMAP4430_SMPSWAITTIMEMIN_SHIFT;
+ vdd->vp_reg.vstepmax_smpswaittimemax_shift =
+ OMAP4430_SMPSWAITTIMEMAX_SHIFT;
+ vdd->vp_reg.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT;
+ vdd->vp_reg.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT;
+
+ /* VLIMITTO bit fields */
+ timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
+ vdd->vp_reg.vlimitto_timeout = timeout_val;
+ vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
+ vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
+ vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
+ vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
+ vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
+
+ return 0;
+}
+
+/* Public functions */
+/**
+ * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
+ * @voltdm: pointer to the VDD for which current voltage info is needed
+ *
+ * API to get the current non-auto-compensated voltage for a VDD.
+ * Returns 0 in case of error else returns the current voltage for the VDD.
+ */
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ return vdd->curr_volt;
+}
+
+/**
+ * omap_vp_get_curr_volt() - API to get the current vp voltage.
+ * @voltdm: pointer to the VDD.
+ *
+ * This API returns the current voltage for the specified voltage processor
+ */
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u8 curr_vsel;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg) {
+ pr_err("%s: No read API for reading vdd_%s regs\n",
+ __func__, voltdm->name);
+ return 0;
+ }
+
+ curr_vsel = vdd->read_reg(vdd->vp_reg.prm_mod,
+ vdd->vp_offs.voltage);
+
+ if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
+ pr_warning("%s: PMIC function to convert vsel to voltage"
+ "in uV not registerd\n", __func__);
+ return 0;
+ }
+
+ return vdd->pmic_info->vsel_to_uv(curr_vsel);
+}
+
+/**
+ * omap_vp_enable() - API to enable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be enabled.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_enable(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u32 vpconfig;
+ u16 mod;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ mod = vdd->vp_reg.prm_mod;
+
+ /* If VP is already enabled, do nothing. Return */
+ if (vdd->vp_enabled)
+ return;
+
+ vp_latch_vsel(vdd);
+
+ /* Enable VP */
+ vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ vpconfig |= vdd->vp_reg.vpconfig_vpenable;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vdd->vp_enabled = true;
+}
+
+/**
+ * omap_vp_disable() - API to disable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be disabled.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_disable(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u32 vpconfig;
+ u16 mod;
+ int timeout;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ mod = vdd->vp_reg.prm_mod;
+
+ /* If VP is already disabled, do nothing. Return */
+ if (!vdd->vp_enabled) {
+ pr_warning("%s: Trying to disable VP for vdd_%s when"
+ "it is already disabled\n", __func__, voltdm->name);
+ return;
+ }
+
+ /* Disable VP */
+ vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ vpconfig &= ~vdd->vp_reg.vpconfig_vpenable;
+ vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+
+ /*
+ * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+ */
+ omap_test_timeout((vdd->read_reg(mod, vdd->vp_offs.vstatus)),
+ VP_IDLE_TIMEOUT, timeout);
+
+ if (timeout >= VP_IDLE_TIMEOUT)
+ pr_warning("%s: vdd_%s idle timedout\n",
+ __func__, voltdm->name);
+
+ vdd->vp_enabled = false;
+
+ return;
+}
+
+/**
+ * omap_voltage_scale_vdd() - API to scale voltage of a particular
+ * voltage domain.
+ * @voltdm: pointer to the VDD which is to be scaled.
+ * @target_volt: The target voltage of the voltage domain
+ *
+ * This API should be called by the kernel to do the voltage scaling
+ * for a particular voltage domain during dvfs or any other situation.
+ */
+int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ if (!vdd->volt_scale) {
+ pr_err("%s: No voltage scale API registered for vdd_%s\n",
+ __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ return vdd->volt_scale(vdd, target_volt);
+}
+
+/**
+ * omap_voltage_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the VDD whose voltage is to be reset.
+ *
+ * This API finds out the correct voltage the voltage domain is supposed
+ * to be at and resets the voltage to that level. Should be used expecially
+ * while disabling any voltage compensation modules.
+ */
+void omap_voltage_reset(struct voltagedomain *voltdm)
+{
+ unsigned long target_uvdc;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ target_uvdc = omap_voltage_get_nom_volt(voltdm);
+ if (!target_uvdc) {
+ pr_err("%s: unable to find current voltage for vdd_%s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ omap_voltage_scale_vdd(voltdm, target_uvdc);
+}
+
+/**
+ * omap_voltage_get_volttable() - API to get the voltage table associated with a
+ * particular voltage domain.
+ * @voltdm: pointer to the VDD for which the voltage table is required
+ * @volt_data: the voltage table for the particular vdd which is to be
+ * populated by this API
+ *
+ * This API populates the voltage table associated with a VDD into the
+ * passed parameter pointer. Returns the count of distinct voltages
+ * supported by this vdd.
+ *
+ */
+void omap_voltage_get_volttable(struct voltagedomain *voltdm,
+ struct omap_volt_data **volt_data)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ *volt_data = vdd->volt_data;
+}
+
+/**
+ * omap_voltage_get_voltdata() - API to get the voltage table entry for a
+ * particular voltage
+ * @voltdm: pointer to the VDD whose voltage table has to be searched
+ * @volt: the voltage to be searched in the voltage table
+ *
+ * This API searches through the voltage table for the required voltage
+ * domain and tries to find a matching entry for the passed voltage volt.
+ * If a matching entry is found volt_data is populated with that entry.
+ * This API searches only through the non-compensated voltages int the
+ * voltage table.
+ * Returns pointer to the voltage table entry corresponding to volt on
+ * sucess. Returns -ENODATA if no voltage table exisits for the passed voltage
+ * domain or if there is no matching entry.
+ */
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt)
+{
+ struct omap_vdd_info *vdd;
+ int i;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ if (!vdd->volt_data) {
+ pr_warning("%s: voltage table does not exist for vdd_%s\n",
+ __func__, voltdm->name);
+ return ERR_PTR(-ENODATA);
+ }
+
+ for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
+ if (vdd->volt_data[i].volt_nominal == volt)
+ return &vdd->volt_data[i];
+ }
+
+ pr_notice("%s: Unable to match the current voltage with the voltage"
+ "table for vdd_%s\n", __func__, voltdm->name);
+
+ return ERR_PTR(-ENODATA);
+}
+
+/**
+ * omap_voltage_register_pmic() - API to register PMIC specific data
+ * @voltdm: pointer to the VDD for which the PMIC specific data is
+ * to be registered
+ * @pmic_info: the structure containing pmic info
+ *
+ * This API is to be called by the SOC/PMIC file to specify the
+ * pmic specific info as present in omap_volt_pmic_info structure.
+ */
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ vdd->pmic_info = pmic_info;
+
+ return 0;
+}
+
+/**
+ * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
+ * corresponding to a voltage domain.
+ *
+ * @voltdm: pointer to the VDD whose debug directory is required.
+ *
+ * This API returns pointer to the debugfs directory corresponding
+ * to the voltage domain. Should be used by drivers requiring to
+ * add any debug entry for a particular voltage domain. Returns NULL
+ * in case of error.
+ */
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return NULL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ return vdd->debug_dir;
+}
+
+/**
+ * omap_change_voltscale_method() - API to change the voltage scaling method.
+ * @voltdm: pointer to the VDD whose voltage scaling method
+ * has to be changed.
+ * @voltscale_method: the method to be used for voltage scaling.
+ *
+ * This API can be used by the board files to change the method of voltage
+ * scaling between vpforceupdate and vcbypass. The parameter values are
+ * defined in voltage.h
+ */
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ switch (voltscale_method) {
+ case VOLTSCALE_VPFORCEUPDATE:
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ return;
+ case VOLTSCALE_VCBYPASS:
+ vdd->volt_scale = vc_bypass_scale_voltage;
+ return;
+ default:
+ pr_warning("%s: Trying to change the method of voltage scaling"
+ "to an unsupported one!\n", __func__);
+ }
+}
+
+/**
+ * omap_voltage_domain_lookup() - API to get the voltage domain pointer
+ * @name: Name of the voltage domain
+ *
+ * This API looks up in the global vdd_info struct for the
+ * existence of voltage domain <name>. If it exists, the API returns
+ * a pointer to the voltage domain structure corresponding to the
+ * VDD<name>. Else retuns error pointer.
+ */
+struct voltagedomain *omap_voltage_domain_lookup(char *name)
+{
+ int i;
+
+ if (!vdd_info) {
+ pr_err("%s: Voltage driver init not yet happened.Faulting!\n",
+ __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!name) {
+ pr_err("%s: No name to get the votage domain!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (i = 0; i < nr_scalable_vdd; i++) {
+ if (!(strcmp(name, vdd_info[i].voltdm.name)))
+ return &vdd_info[i].voltdm;
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+/**
+ * omap_voltage_late_init() - Init the various voltage parameters
+ *
+ * This API is to be called in the later stages of the
+ * system boot to init the voltage controller and
+ * voltage processors.
+ */
+int __init omap_voltage_late_init(void)
+{
+ int i;
+
+ if (!vdd_info) {
+ pr_err("%s: Voltage driver support not added\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ voltage_dir = debugfs_create_dir("voltage", NULL);
+ if (IS_ERR(voltage_dir))
+ pr_err("%s: Unable to create voltage debugfs main dir\n",
+ __func__);
+ for (i = 0; i < nr_scalable_vdd; i++) {
+ if (vdd_data_configure(&vdd_info[i]))
+ continue;
+ vc_init(&vdd_info[i]);
+ vp_init(&vdd_info[i]);
+ vdd_debugfs_init(&vdd_info[i]);
+ }
+
+ return 0;
+}
+
+/**
+ * omap_voltage_early_init()- Volatage driver early init
+ */
+static int __init omap_voltage_early_init(void)
+{
+ if (cpu_is_omap34xx()) {
+ vdd_info = omap3_vdd_info;
+ nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
+ vc_init = omap3_vc_init;
+ vdd_data_configure = omap3_vdd_data_configure;
+ } else if (cpu_is_omap44xx()) {
+ vdd_info = omap4_vdd_info;
+ nr_scalable_vdd = OMAP4_NR_SCALABLE_VDD;
+ vc_init = omap4_vc_init;
+ vdd_data_configure = omap4_vdd_data_configure;
+ } else {
+ pr_warning("%s: voltage driver support not added\n", __func__);
+ }
+
+ return 0;
+}
+core_initcall(omap_voltage_early_init);
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
new file mode 100644
index 000000000000..b0c4907ab3ca
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -0,0 +1,54 @@
+/*
+ * OMAP2+ MPU WD_TIMER-specific code
+ *
+ * This program is free software; you can redistribute it and/or 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/io.h>
+#include <linux/err.h>
+
+#include <plat/omap_hwmod.h>
+
+/*
+ * In order to avoid any assumptions from bootloader regarding WDT
+ * settings, WDT module is reset during init. This enables the watchdog
+ * timer. Hence it is required to disable the watchdog after the WDT reset
+ * during init. Otherwise the system would reboot as per the default
+ * watchdog timer registers settings.
+ */
+#define OMAP_WDT_WPS 0x34
+#define OMAP_WDT_SPR 0x48
+
+
+int omap2_wd_timer_disable(struct omap_hwmod *oh)
+{
+ void __iomem *base;
+
+ if (!oh) {
+ pr_err("%s: Could not look up wdtimer_hwmod\n", __func__);
+ return -EINVAL;
+ }
+
+ base = omap_hwmod_get_mpu_rt_va(oh);
+ if (!base) {
+ pr_err("%s: Could not get the base address for %s\n",
+ oh->name, __func__);
+ return -EINVAL;
+ }
+
+ /* sequence required to disable watchdog */
+ __raw_writel(0xAAAA, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ __raw_writel(0x5555, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/wd_timer.h b/arch/arm/mach-omap2/wd_timer.h
new file mode 100644
index 000000000000..e0054a2d5505
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.h
@@ -0,0 +1,17 @@
+/*
+ * OMAP2+ MPU WD_TIMER-specific function prototypes
+ *
+ * This program is free software; you can redistribute it and/or 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 __ARCH_ARM_MACH_OMAP2_WD_TIMER_H
+#define __ARCH_ARM_MACH_OMAP2_WD_TIMER_H
+
+#include <plat/omap_hwmod.h>
+
+extern int omap2_wd_timer_disable(struct omap_hwmod *oh);
+
+#endif
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index c897e03e413d..6604fc6ca58a 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -51,6 +51,13 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported.
+config MACH_LINKSTATION_LSCHL
+ bool "Buffalo Linkstation Live v3 (LS-CHL)"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation Live v3 (LS-CHL) platform.
+
config MACH_LINKSTATION_MINI
bool "Buffalo Linkstation Mini"
select I2C_BOARDINFO
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index eb6eabcb41e4..7f18cdacd487 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_LSCHL) += ls-chl-setup.o
diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h
index c47b033bd999..c5196101a237 100644
--- a/arch/arm/mach-orion5x/include/mach/io.h
+++ b/arch/arm/mach-orion5x/include/mach/io.h
@@ -38,8 +38,8 @@ __arch_iounmap(void __iomem *addr)
__iounmap(addr);
}
-#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m)
-#define __arch_iounmap(a) __arch_iounmap(a)
+#define __arch_ioremap __arch_ioremap
+#define __arch_iounmap __arch_iounmap
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
new file mode 100644
index 000000000000..20a9b66cbafa
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -0,0 +1,327 @@
+/*
+ * arch/arm/mach-orion5x/ls-chl-setup.c
+ *
+ * Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk>
+ *
+ * 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/gpio-fan.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-CHL Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LSCHL_NOR_BOOT_BASE 0xf4000000
+#define LSCHL_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data lschl_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource lschl_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LSCHL_NOR_BOOT_BASE,
+ .end = LSCHL_NOR_BOOT_BASE + LSCHL_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lschl_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lschl_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &lschl_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data lschl_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata lschl_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LSCHL_GPIO_LED_ALARM 2
+#define LSCHL_GPIO_LED_INFO 3
+#define LSCHL_GPIO_LED_FUNC 17
+#define LSCHL_GPIO_LED_PWR 0
+
+static struct gpio_led lschl_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LSCHL_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LSCHL_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LSCHL_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LSCHL_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data lschl_led_data = {
+ .leds = lschl_led_pins,
+ .num_leds = ARRAY_SIZE(lschl_led_pins),
+};
+
+static struct platform_device lschl_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &lschl_led_data,
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data lschl_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * LS-CHL specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the LS-CHL, 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 lschl_power_off(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+#define LSCHL_GPIO_USB_POWER 9
+#define LSCHL_GPIO_AUTO_POWER 17
+#define LSCHL_GPIO_POWER 18
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+#define LSCHL_GPIO_KEY_FUNC 15
+#define LSCHL_GPIO_KEY_POWER 8
+#define LSCHL_GPIO_KEY_AUTOPOWER 10
+#define LSCHL_SW_POWER 0x00
+#define LSCHL_SW_AUTOPOWER 0x01
+#define LSCHL_SW_FUNC 0x02
+
+static struct gpio_keys_button lschl_buttons[] = {
+ {
+ .type = EV_SW,
+ .code = LSCHL_SW_POWER,
+ .gpio = LSCHL_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSCHL_SW_AUTOPOWER,
+ .gpio = LSCHL_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSCHL_SW_FUNC,
+ .gpio = LSCHL_GPIO_KEY_FUNC,
+ .desc = "Function Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data lschl_button_data = {
+ .buttons = lschl_buttons,
+ .nbuttons = ARRAY_SIZE(lschl_buttons),
+};
+
+static struct platform_device lschl_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lschl_button_data,
+ },
+};
+
+#define LSCHL_GPIO_HDD_POWER 1
+
+/****************************************************************************
+ * GPIO Fan
+ ****************************************************************************/
+
+#define LSCHL_GPIO_FAN_LOW 16
+#define LSCHL_GPIO_FAN_HIGH 14
+#define LSCHL_GPIO_FAN_LOCK 6
+
+static struct gpio_fan_alarm lschl_alarm = {
+ .gpio = LSCHL_GPIO_FAN_LOCK,
+};
+
+static struct gpio_fan_speed lschl_speeds[] = {
+ {
+ .rpm = 0,
+ .ctrl_val = 3,
+ }, {
+ .rpm = 1500,
+ .ctrl_val = 2,
+ }, {
+ .rpm = 3250,
+ .ctrl_val = 1,
+ }, {
+ .rpm = 5000,
+ .ctrl_val = 0,
+ },
+};
+
+static int lschl_gpio_list[] = {
+ LSCHL_GPIO_FAN_HIGH, LSCHL_GPIO_FAN_LOW,
+};
+
+static struct gpio_fan_platform_data lschl_fan_data = {
+ .num_ctrl = ARRAY_SIZE(lschl_gpio_list),
+ .ctrl = lschl_gpio_list,
+ .alarm = &lschl_alarm,
+ .num_speed = ARRAY_SIZE(lschl_speeds),
+ .speed = lschl_speeds,
+};
+
+static struct platform_device lschl_fan_device = {
+ .name = "gpio-fan",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lschl_fan_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Data
+ ****************************************************************************/
+
+static struct orion5x_mpp_mode lschl_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* LED POWER */
+ { 1, MPP_GPIO }, /* HDD POWER */
+ { 2, MPP_GPIO }, /* LED ALARM */
+ { 3, MPP_GPIO }, /* LED INFO */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_GPIO }, /* FAN LOCK */
+ { 7, MPP_GPIO }, /* SW INIT */
+ { 8, MPP_GPIO }, /* SW POWER */
+ { 9, MPP_GPIO }, /* USB POWER */
+ { 10, MPP_GPIO }, /* SW AUTO POWER */
+ { 11, MPP_UNUSED },
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_GPIO }, /* FAN HIGH */
+ { 15, MPP_GPIO }, /* SW FUNC */
+ { 16, MPP_GPIO }, /* FAN LOW */
+ { 17, MPP_GPIO }, /* LED FUNC */
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
+};
+
+static void __init lschl_init(void)
+{
+ /*
+ * Setup basic Orion functions. Needs to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(lschl_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&lschl_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&lschl_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE,
+ LSCHL_NOR_BOOT_SIZE);
+ platform_device_register(&lschl_nor_flash);
+
+ platform_device_register(&lschl_leds);
+
+ platform_device_register(&lschl_button_device);
+
+ platform_device_register(&lschl_fan_device);
+
+ i2c_register_board_info(0, &lschl_i2c_rtc, 1);
+
+ /* usb power on */
+ gpio_set_value(LSCHL_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = lschl_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")
+ /* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */
+ .boot_params = 0x00000100,
+ .init_machine = lschl_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-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index 9d1975fa4d9f..a4a3819c96cb 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -21,8 +21,7 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/io.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/hardware.h>
#include <mach/clock.h>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index dd235ecc9d6c..2fc9f94cdd29 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -50,6 +50,10 @@ config MACH_SAAR
select PXA3xx
select CPU_PXA930
+config MACH_SAARB
+ bool "PXA955 Handheld Platform (aka SAARB)"
+ select CPU_PXA955
+
comment "Third Party Dev Platforms (sorted by vendor name)"
config ARCH_PXA_IDP
@@ -94,6 +98,7 @@ config MACH_ARMCORE
select PXA27x
select IWMMXT
select PXA25x
+ select MIGHT_HAVE_PCI
config MACH_EM_X270
bool "CompuLab EM-x270 platform"
@@ -232,10 +237,6 @@ config MACH_COLIBRI
bool "Toradex Colibri PXA270"
select PXA27x
-config MACH_COLIBRI_PXA270_EVALBOARD
- bool "Toradex Colibri Evaluation Carrier Board support (PXA270)"
- depends on MACH_COLIBRI
-
config MACH_COLIBRI_PXA270_INCOME
bool "Income s.r.o. PXA270 SBC"
depends on MACH_COLIBRI
@@ -253,6 +254,10 @@ config MACH_COLIBRI320
select PXA3xx
select CPU_PXA320
+config MACH_COLIBRI_EVALBOARD
+ bool "Toradex Colibri Evaluation Carrier Board support"
+ depends on MACH_COLIBRI || MACH_COLIBRI300 || MACH_COLIBRI320
+
config MACH_VPAC270
bool "Voipac PXA270"
select PXA27x
@@ -540,6 +545,7 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
+ select FB_W100
config MACH_E330
bool "Toshiba e330"
@@ -651,11 +657,17 @@ config CPU_PXA935
help
PXA935 (codename Tavor-P65)
-config CPU_PXA950
+config PXA95x
bool
- select CPU_PXA930
+ select CPU_PJ4
+ help
+ Select code specific to PXA95x variants
+
+config CPU_PXA955
+ bool
+ select PXA95x
help
- PXA950 (codename Tavor-PV2)
+ PXA950 (codename MG1)
config PXA_SHARP_C7xx
bool
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index e2f89c2c6f49..cc39d17b2e07 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -16,9 +16,10 @@ endif
# Generic drivers that other drivers may depend upon
# SoC-specific code
-obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o
-obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o
-obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
+obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o
+obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o
+obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
+obj-$(CONFIG_PXA95x) += mfp-pxa3xx.o clock-pxa3xx.o pxa95x.o smemc.o
obj-$(CONFIG_CPU_PXA300) += pxa300.o
obj-$(CONFIG_CPU_PXA320) += pxa320.o
obj-$(CONFIG_CPU_PXA930) += pxa930.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_MACH_LITTLETON) += littleton.o
obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o
obj-$(CONFIG_MACH_SAAR) += saar.o
+obj-$(CONFIG_MACH_SAARB) += saarb.o
# 3rd Party Dev Platforms
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
@@ -60,7 +62,7 @@ obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
obj-$(CONFIG_MACH_PCM027) += pcm027.o
obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o
-obj-$(CONFIG_MACH_COLIBRI_PXA270_EVALBOARD) += colibri-pxa270-evalboard.o
+obj-$(CONFIG_MACH_COLIBRI_EVALBOARD) += colibri-evalboard.o
obj-$(CONFIG_MACH_COLIBRI_PXA270_INCOME) += colibri-pxa270-income.o
obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o
obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index 21e188901935..ccb2d0cebcc3 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -567,27 +567,29 @@ static inline void balloon3_i2c_init(void) {}
* NAND
******************************************************************************/
#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
-static uint16_t balloon3_ctl =
- BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
- BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 |
- BALLOON3_NAND_CONTROL_FLWP;
-
static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
+ uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
if (ctrl & NAND_CTRL_CHANGE) {
if (ctrl & NAND_CLE)
- balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCLE;
+ balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLCLE;
else
- balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLCLE;
+ balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLCLE;
if (ctrl & NAND_ALE)
- balloon3_ctl |= BALLOON3_NAND_CONTROL_FLALE;
+ balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLALE;
else
- balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLALE;
-
- __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
+ balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLALE;
+
+ if (balloon3_ctl_clr)
+ __raw_writel(balloon3_ctl_clr,
+ BALLOON3_NAND_CONTROL_REG);
+ if (balloon3_ctl_set)
+ __raw_writel(balloon3_ctl_set,
+ BALLOON3_NAND_CONTROL_REG |
+ BALLOON3_FPGA_SETnCLR);
}
if (cmd != NAND_CMD_NONE)
@@ -599,28 +601,33 @@ static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
if (chip < 0 || chip > 3)
return;
- balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCE0 |
- BALLOON3_NAND_CONTROL_FLCE1 |
- BALLOON3_NAND_CONTROL_FLCE2 |
- BALLOON3_NAND_CONTROL_FLCE3;
+ /* Assert all nCE lines */
+ __raw_writew(
+ BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
+ BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3,
+ BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
/* Deassert correct nCE line */
- balloon3_ctl &= ~(BALLOON3_NAND_CONTROL_FLCE0 << chip);
+ __raw_writew(BALLOON3_NAND_CONTROL_FLCE0 << chip,
+ BALLOON3_NAND_CONTROL_REG);
+}
- __raw_writew(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
+static int balloon3_nand_dev_ready(struct mtd_info *mtd)
+{
+ return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
}
static int balloon3_nand_probe(struct platform_device *pdev)
{
- void __iomem *temp_map;
uint16_t ver;
int ret;
- __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, BALLOON3_NAND_CONTROL2_REG);
+ __raw_writew(BALLOON3_NAND_CONTROL2_16BIT,
+ BALLOON3_NAND_CONTROL2_REG | BALLOON3_FPGA_SETnCLR);
ver = __raw_readw(BALLOON3_FPGA_VER);
- if (ver > 0x0201)
- pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. "
+ if (ver < 0x4f08)
+ pr_warn("The FPGA code, version 0x%04x, is too old. "
"NAND support might be broken in this version!", ver);
/* Power up the NAND chips */
@@ -635,7 +642,11 @@ static int balloon3_nand_probe(struct platform_device *pdev)
gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1);
/* Deassert all nCE lines and write protect line */
- __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG);
+ __raw_writel(
+ BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
+ BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 |
+ BALLOON3_NAND_CONTROL_FLWP,
+ BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
return 0;
err2:
@@ -677,7 +688,7 @@ struct platform_nand_data balloon3_nand_pdata = {
},
.ctrl = {
.hwcontrol = 0,
- .dev_ready = 0,
+ .dev_ready = balloon3_nand_dev_ready,
.select_chip = balloon3_nand_select_chip,
.cmd_ctrl = balloon3_nand_cmd_ctl,
.probe = balloon3_nand_probe,
@@ -802,7 +813,7 @@ static struct map_desc balloon3_io_desc[] __initdata = {
static void __init balloon3_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc));
}
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index 4bd7a3cda48c..4284513f396a 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -149,7 +149,7 @@ static void __init capc7117_init(void)
MACHINE_START(CAPC7117,
"Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = capc7117_init
diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c
new file mode 100644
index 000000000000..1ce090448493
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa2xx.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/mach-pxa/clock-pxa2xx.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <mach/pxa2xx-regs.h>
+
+#include "clock.h"
+
+void clk_pxa2xx_cken_enable(struct clk *clk)
+{
+ CKEN |= 1 << clk->cken;
+}
+
+void clk_pxa2xx_cken_disable(struct clk *clk)
+{
+ CKEN &= ~(1 << clk->cken);
+}
+
+const struct clkops clk_pxa2xx_cken_ops = {
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
+};
+
+#ifdef CONFIG_PM
+static uint32_t saved_cken;
+
+static int pxa2xx_clock_suspend(struct sys_device *d, pm_message_t state)
+{
+ saved_cken = CKEN;
+ return 0;
+}
+
+static int pxa2xx_clock_resume(struct sys_device *d)
+{
+ CKEN = saved_cken;
+ return 0;
+}
+#else
+#define pxa2xx_clock_suspend NULL
+#define pxa2xx_clock_resume NULL
+#endif
+
+struct sysdev_class pxa2xx_clock_sysclass = {
+ .name = "pxa2xx-clock",
+ .suspend = pxa2xx_clock_suspend,
+ .resume = pxa2xx_clock_resume,
+};
+
+static int __init pxa2xx_clock_init(void)
+{
+ if (cpu_is_pxa2xx())
+ return sysdev_class_register(&pxa2xx_clock_sysclass);
+ return 0;
+}
+postcore_initcall(pxa2xx_clock_init);
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c
new file mode 100644
index 000000000000..1b08a34ab234
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa3xx.c
@@ -0,0 +1,218 @@
+/*
+ * linux/arch/arm/mach-pxa/clock-pxa3xx.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
+
+#include "clock.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK 13000000
+
+/* Ring Oscillator Clock: 60MHz */
+#define RO_CLK 60000000
+
+#define ACCR_D0CS (1 << 26)
+#define ACCR_PCCE (1 << 11)
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
+
+/*
+ * Get the clock frequency as reflected by CCSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa3xx_get_clk_frequency_khz(int info)
+{
+ unsigned long acsr, xclkcfg;
+ unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
+
+ /* Read XCLKCFG register turbo bit */
+ __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+ t = xclkcfg & 0x1;
+
+ acsr = ACSR;
+
+ xl = acsr & 0x1f;
+ xn = (acsr >> 8) & 0x7;
+ hss = (acsr >> 14) & 0x3;
+
+ XL = xl * BASE_CLK;
+ XN = xn * XL;
+
+ ro = acsr & ACCR_D0CS;
+
+ CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
+ HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ if (info) {
+ pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
+ RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
+ (ro) ? "" : "in");
+ pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
+ XL / 1000000, (XL % 1000000) / 10000, xl);
+ pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
+ XN / 1000000, (XN % 1000000) / 10000, xn,
+ (t) ? "" : "in");
+ pr_info("HSIO bus clock: %d.%02dMHz\n",
+ HSS / 1000000, (HSS % 1000000) / 10000);
+ }
+
+ return CLK / 1000;
+}
+
+/*
+ * Return the current AC97 clock frequency.
+ */
+static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk)
+{
+ unsigned long rate = 312000000;
+ unsigned long ac97_div;
+
+ ac97_div = AC97_DIV;
+
+ /* This may loose precision for some rates but won't for the
+ * standard 24.576MHz.
+ */
+ rate /= (ac97_div >> 12) & 0x7fff;
+ rate *= (ac97_div & 0xfff);
+
+ return rate;
+}
+
+/*
+ * Return the current HSIO bus clock frequency
+ */
+static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
+{
+ unsigned long acsr;
+ unsigned int hss, hsio_clk;
+
+ acsr = ACSR;
+
+ hss = (acsr >> 14) & 0x3;
+ hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ return hsio_clk;
+}
+
+/* crystal frequency to static memory controller multiplier (SMCFS) */
+static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
+static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 };
+
+static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk)
+{
+ unsigned long acsr = ACSR;
+ unsigned long memclkcfg = __raw_readl(MEMCLKCFG);
+ unsigned int smcfs = (acsr >> 23) & 0x7;
+
+ return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] /
+ df_clkdiv[(memclkcfg >> 16) & 0x3];
+}
+
+void clk_pxa3xx_cken_enable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ if (clk->cken < 32)
+ CKENA |= mask;
+ else
+ CKENB |= mask;
+}
+
+void clk_pxa3xx_cken_disable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ if (clk->cken < 32)
+ CKENA &= ~mask;
+ else
+ CKENB &= ~mask;
+}
+
+const struct clkops clk_pxa3xx_cken_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+};
+
+const struct clkops clk_pxa3xx_hsio_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_hsio_getrate,
+};
+
+const struct clkops clk_pxa3xx_ac97_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_ac97_getrate,
+};
+
+const struct clkops clk_pxa3xx_smemc_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_smemc_getrate,
+};
+
+static void clk_pout_enable(struct clk *clk)
+{
+ OSCC |= OSCC_PEN;
+}
+
+static void clk_pout_disable(struct clk *clk)
+{
+ OSCC &= ~OSCC_PEN;
+}
+
+const struct clkops clk_pxa3xx_pout_ops = {
+ .enable = clk_pout_enable,
+ .disable = clk_pout_disable,
+};
+
+#ifdef CONFIG_PM
+static uint32_t cken[2];
+static uint32_t accr;
+
+static int pxa3xx_clock_suspend(struct sys_device *d, pm_message_t state)
+{
+ cken[0] = CKENA;
+ cken[1] = CKENB;
+ accr = ACCR;
+ return 0;
+}
+
+static int pxa3xx_clock_resume(struct sys_device *d)
+{
+ ACCR = accr;
+ CKENA = cken[0];
+ CKENB = cken[1];
+ return 0;
+}
+#else
+#define pxa3xx_clock_suspend NULL
+#define pxa3xx_clock_resume NULL
+#endif
+
+struct sysdev_class pxa3xx_clock_sysclass = {
+ .name = "pxa3xx-clock",
+ .suspend = pxa3xx_clock_suspend,
+ .resume = pxa3xx_clock_resume,
+};
+
+static int __init pxa3xx_clock_init(void)
+{
+ if (cpu_is_pxa3xx() || cpu_is_pxa95x())
+ return sysdev_class_register(&pxa3xx_clock_sysclass);
+ return 0;
+}
+postcore_initcall(pxa3xx_clock_init);
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index abba0089a2ae..d5152220ce94 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -3,21 +3,11 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
-#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/hardware.h>
-
-#include "devices.h"
-#include "generic.h"
#include "clock.h"
static DEFINE_SPINLOCK(clocks_lock);
@@ -63,18 +53,19 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_rate);
-
-void clk_cken_enable(struct clk *clk)
+void clk_dummy_enable(struct clk *clk)
{
- CKEN |= 1 << clk->cken;
}
-void clk_cken_disable(struct clk *clk)
+void clk_dummy_disable(struct clk *clk)
{
- CKEN &= ~(1 << clk->cken);
}
-const struct clkops clk_cken_ops = {
- .enable = clk_cken_enable,
- .disable = clk_cken_disable,
+const struct clkops clk_dummy_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+};
+
+struct clk clk_dummy = {
+ .ops = &clk_dummy_ops,
};
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index d8488742b807..f9f349a21b54 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -1,4 +1,5 @@
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
+#include <linux/sysdev.h>
struct clkops {
void (*enable)(struct clk *);
@@ -14,6 +15,12 @@ struct clk {
unsigned int enabled;
};
+void clk_dummy_enable(struct clk *);
+void clk_dummy_disable(struct clk *);
+
+extern const struct clkops clk_dummy_ops;
+extern struct clk clk_dummy;
+
#define INIT_CLKREG(_clk,_devname,_conname) \
{ \
.clk = _clk, \
@@ -21,14 +28,6 @@ struct clk {
.con_id = _conname, \
}
-#define DEFINE_CKEN(_name, _cken, _rate, _delay) \
-struct clk clk_##_name = { \
- .ops = &clk_cken_ops, \
- .rate = _rate, \
- .cken = CKEN_##_cken, \
- .delay = _delay, \
- }
-
#define DEFINE_CK(_name, _cken, _ops) \
struct clk clk_##_name = { \
.ops = _ops, \
@@ -42,28 +41,38 @@ struct clk clk_##_name = { \
.delay = _delay, \
}
-extern const struct clkops clk_cken_ops;
-
-void clk_cken_enable(struct clk *clk);
-void clk_cken_disable(struct clk *clk);
-
-#ifdef CONFIG_PXA3xx
-#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \
+#define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay) \
struct clk clk_##_name = { \
- .ops = &clk_pxa3xx_cken_ops, \
+ .ops = &clk_pxa2xx_cken_ops, \
.rate = _rate, \
.cken = CKEN_##_cken, \
.delay = _delay, \
}
-#define DEFINE_PXA3_CK(_name, _cken, _ops) \
+extern const struct clkops clk_pxa2xx_cken_ops;
+
+void clk_pxa2xx_cken_enable(struct clk *clk);
+void clk_pxa2xx_cken_disable(struct clk *clk);
+
+extern struct sysdev_class pxa2xx_clock_sysclass;
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \
struct clk clk_##_name = { \
- .ops = _ops, \
+ .ops = &clk_pxa3xx_cken_ops, \
+ .rate = _rate, \
.cken = CKEN_##_cken, \
+ .delay = _delay, \
}
extern const struct clkops clk_pxa3xx_cken_ops;
+extern const struct clkops clk_pxa3xx_hsio_ops;
+extern const struct clkops clk_pxa3xx_ac97_ops;
+extern const struct clkops clk_pxa3xx_pout_ops;
+extern const struct clkops clk_pxa3xx_smemc_ops;
+
extern void clk_pxa3xx_cken_enable(struct clk *);
extern void clk_pxa3xx_cken_disable(struct clk *);
-#endif
+extern struct sysdev_class pxa3xx_clock_sysclass;
+#endif
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index d34b99febeb9..b734d8468168 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -24,6 +24,7 @@
#include <mach/pxa2xx-regs.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
+#include <mach/smemc.h>
#include <asm/hardware/it8152.h>
@@ -392,9 +393,9 @@ static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
cmx2xx_pci_suspend();
/* save MSC registers */
- sleep_save_msc[0] = MSC0;
- sleep_save_msc[1] = MSC1;
- sleep_save_msc[2] = MSC2;
+ sleep_save_msc[0] = __raw_readl(MSC0);
+ sleep_save_msc[1] = __raw_readl(MSC1);
+ sleep_save_msc[2] = __raw_readl(MSC2);
/* setup power saving mode registers */
PCFR = 0x0;
@@ -416,9 +417,9 @@ static int cmx2xx_resume(struct sys_device *dev)
cmx2xx_pci_resume();
/* restore MSC registers */
- MSC0 = sleep_save_msc[0];
- MSC1 = sleep_save_msc[1];
- MSC2 = sleep_save_msc[2];
+ __raw_writel(sleep_save_msc[0], MSC0);
+ __raw_writel(sleep_save_msc[1], MSC1);
+ __raw_writel(sleep_save_msc[2], MSC2);
return 0;
}
@@ -498,7 +499,12 @@ static struct map_desc cmx2xx_io_desc[] __initdata = {
static void __init cmx2xx_map_io(void)
{
- pxa_map_io();
+ if (cpu_is_pxa25x())
+ pxa25x_map_io();
+
+ if (cpu_is_pxa27x())
+ pxa27x_map_io();
+
iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc));
it8152_base_address = CMX2XX_IT8152_VIRT;
@@ -506,7 +512,11 @@ static void __init cmx2xx_map_io(void)
#else
static void __init cmx2xx_map_io(void)
{
- pxa_map_io();
+ if (cpu_is_pxa25x())
+ pxa25x_map_io();
+
+ if (cpu_is_pxa27x())
+ pxa27x_map_io();
}
#endif
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 922b1075b9de..7984268508b6 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -857,7 +857,7 @@ static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
MACHINE_START(CM_X300, "CM-X300 module")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = cm_x300_init,
diff --git a/arch/arm/mach-pxa/colibri-pxa270-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c
index 0f3b632c3b14..6b2c800a1133 100644
--- a/arch/arm/mach-pxa/colibri-pxa270-evalboard.c
+++ b/arch/arm/mach-pxa/colibri-evalboard.c
@@ -1,7 +1,7 @@
/*
- * linux/arch/arm/mach-pxa/colibri-pxa270-evalboard.c
+ * linux/arch/arm/mach-pxa/colibri-evalboard.c
*
- * Support for Toradex PXA270 based Colibri Evaluation Carrier Board
+ * Support for Toradex Colibri Evaluation Carrier Board
* Daniel Mack <daniel@caiaq.de>
* Marek Vasut <marek.vasut@gmail.com>
*
@@ -19,6 +19,7 @@
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/arch.h>
+#include <linux/i2c.h>
#include <mach/pxa27x.h>
#include <mach/colibri.h>
@@ -26,86 +27,95 @@
#include <mach/ohci.h>
#include <mach/pxa27x-udc.h>
+#include <plat/i2c.h>
+
#include "generic.h"
#include "devices.h"
/******************************************************************************
- * Pin configuration
- ******************************************************************************/
-static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
- GPIO112_MMC_CMD,
- GPIO0_GPIO, /* SD detect */
-
- /* FFUART */
- GPIO39_FFUART_TXD,
- GPIO34_FFUART_RXD,
-
- /* UHC */
- GPIO88_USBH1_PWR,
- GPIO89_USBH1_PEN,
- GPIO119_USBH2_PWR,
- GPIO120_USBH2_PEN,
-};
-
-/******************************************************************************
* SD/MMC card controller
******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
-static struct pxamci_platform_data colibri_pxa270_mci_platform_data = {
+static struct pxamci_platform_data colibri_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.gpio_power = -1,
- .gpio_card_detect = GPIO0_COLIBRI_PXA270_SD_DETECT,
.gpio_card_ro = -1,
.detect_delay_ms = 200,
};
-static void __init colibri_pxa270_mmc_init(void)
+static void __init colibri_mmc_init(void)
{
- pxa_set_mci_info(&colibri_pxa270_mci_platform_data);
+ if (machine_is_colibri()) /* PXA270 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO0_COLIBRI_PXA270_SD_DETECT;
+ if (machine_is_colibri300()) /* PXA300 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO39_COLIBRI_PXA300_SD_DETECT;
+ else /* PXA320 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO28_COLIBRI_PXA320_SD_DETECT;
+
+ pxa_set_mci_info(&colibri_mci_platform_data);
}
#else
-static inline void colibri_pxa270_mmc_init(void) {}
+static inline void colibri_mmc_init(void) {}
#endif
/******************************************************************************
* USB Host
******************************************************************************/
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static int colibri_pxa270_ohci_init(struct device *dev)
+static int colibri_ohci_init(struct device *dev)
{
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
return 0;
}
-static struct pxaohci_platform_data colibri_pxa270_ohci_info = {
+static struct pxaohci_platform_data colibri_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
- .flags = ENABLE_PORT1 | ENABLE_PORT2 |
+ .flags = ENABLE_PORT1 |
POWER_CONTROL_LOW | POWER_SENSE_LOW,
- .init = colibri_pxa270_ohci_init,
+ .init = colibri_ohci_init,
};
-static void __init colibri_pxa270_uhc_init(void)
+static void __init colibri_uhc_init(void)
{
- pxa_set_ohci_info(&colibri_pxa270_ohci_info);
+ /* Colibri PXA270 has two usb ports, TBA for 320 */
+ if (machine_is_colibri())
+ colibri_ohci_info.flags |= ENABLE_PORT2;
+
+ pxa_set_ohci_info(&colibri_ohci_info);
}
#else
-static inline void colibri_pxa270_uhc_init(void) {}
+static inline void colibri_uhc_init(void) {}
#endif
-void __init colibri_pxa270_evalboard_init(void)
+/******************************************************************************
+ * I2C RTC
+ ******************************************************************************/
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+static struct i2c_board_info __initdata colibri_i2c_devs[] = {
+ {
+ I2C_BOARD_INFO("m41t00", 0x68),
+ },
+};
+
+static void __init colibri_rtc_init(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(colibri_i2c_devs));
+}
+#else
+static inline void colibri_rtc_init(void) {}
+#endif
+
+void __init colibri_evalboard_init(void)
{
- pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_evalboard_pin_config));
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- colibri_pxa270_mmc_init();
- colibri_pxa270_uhc_init();
+ colibri_mmc_init();
+ colibri_uhc_init();
+ colibri_rtc_init();
}
-
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c
index 37f0f3ed7c61..07b62a096f17 100644
--- a/arch/arm/mach-pxa/colibri-pxa270-income.c
+++ b/arch/arm/mach-pxa/colibri-pxa270-income.c
@@ -46,52 +46,6 @@
#define GPIO113_INCOME_TS_IRQ (113)
/******************************************************************************
- * Pin configuration
- ******************************************************************************/
-static mfp_cfg_t income_pin_config[] __initdata = {
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
- GPIO112_MMC_CMD,
- GPIO0_GPIO, /* SD detect */
- GPIO1_GPIO, /* SD read-only */
-
- /* FFUART */
- GPIO39_FFUART_TXD,
- GPIO34_FFUART_RXD,
-
- /* BFUART */
- GPIO42_BTUART_RXD,
- GPIO43_BTUART_TXD,
- GPIO45_BTUART_RTS,
-
- /* STUART */
- GPIO46_STUART_RXD,
- GPIO47_STUART_TXD,
-
- /* UHC */
- GPIO88_USBH1_PWR,
- GPIO89_USBH1_PEN,
-
- /* LCD */
- GPIOxx_LCD_TFT_16BPP,
-
- /* PWM */
- GPIO16_PWM0_OUT,
-
- /* I2C */
- GPIO117_I2C_SCL,
- GPIO118_I2C_SDA,
-
- /* LED */
- GPIO54_GPIO, /* LED A */
- GPIO55_GPIO, /* LED B */
-};
-
-/******************************************************************************
* SD/MMC card controller
******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
@@ -257,7 +211,6 @@ static inline void income_pwm_init(void) {}
void __init colibri_pxa270_income_boardinit(void)
{
- pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config));
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index bc045100ec15..6fc5d328ba7f 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -33,6 +33,103 @@
#include "generic.h"
/******************************************************************************
+ * Evaluation board MFP
+ ******************************************************************************/
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO0_GPIO, /* SD detect */
+
+ /* FFUART */
+ GPIO39_FFUART_TXD,
+ GPIO34_FFUART_RXD,
+
+ /* UHC */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+ GPIO119_USBH2_PWR,
+ GPIO120_USBH2_PEN,
+
+ /* PCMCIA */
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO49_nPWE,
+ GPIO48_nPOE,
+ GPIO57_nIOIS16,
+ GPIO56_nPWAIT,
+ GPIO104_PSKTSEL,
+ GPIO53_GPIO, /* RESET */
+ GPIO83_GPIO, /* BVD1 */
+ GPIO82_GPIO, /* BVD2 */
+ GPIO1_GPIO, /* READY */
+ GPIO84_GPIO, /* DETECT */
+ GPIO107_GPIO, /* PPEN */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+#else
+static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {};
+#endif
+
+#ifdef CONFIG_MACH_COLIBRI_PXA270_INCOME
+static mfp_cfg_t income_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO0_GPIO, /* SD detect */
+ GPIO1_GPIO, /* SD read-only */
+
+ /* FFUART */
+ GPIO39_FFUART_TXD,
+ GPIO34_FFUART_RXD,
+
+ /* BFUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* UHC */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* LED */
+ GPIO54_GPIO, /* LED A */
+ GPIO55_GPIO, /* LED B */
+};
+#else
+static mfp_cfg_t income_pin_config[] __initdata = {};
+#endif
+
+/******************************************************************************
* Pin configuration
******************************************************************************/
static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = {
@@ -184,10 +281,13 @@ static void __init colibri_pxa270_init(void)
colibri_pxa270_tsc_init();
switch (colibri_pxa270_baseboard) {
- case COLIBRI_PXA270_EVALBOARD:
- colibri_pxa270_evalboard_init();
+ case COLIBRI_EVALBOARD:
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(
+ colibri_pxa270_evalboard_pin_config));
+ colibri_evalboard_init();
break;
case COLIBRI_PXA270_INCOME:
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config));
colibri_pxa270_income_boardinit();
break;
default:
@@ -209,7 +309,7 @@ static void __init colibri_pxa270_income_init(void)
MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa270_init,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
MACHINE_END
@@ -217,7 +317,7 @@ MACHINE_END
MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
.boot_params = 0xa0000100,
.init_machine = colibri_pxa270_income_init,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index a70b256591e6..fddb16d07eb0 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -31,9 +31,38 @@
#include "generic.h"
#include "devices.h"
+
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO7_MMC1_CLK,
+ GPIO14_MMC1_CMD,
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO39_GPIO, /* SD detect */
+
+ /* UHC */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+ GPIO77_USB_P3_1,
+ GPIO78_USB_P3_2,
+ GPIO79_USB_P3_3,
+ GPIO80_USB_P3_4,
+ GPIO81_USB_P3_5,
+ GPIO82_USB_P3_6,
+
+ /* I2C */
+ GPIO21_I2C_SCL,
+ GPIO22_I2C_SDA,
+};
+#else
+static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {};
+#endif
+
#if defined(CONFIG_AX88796)
#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO)
-
/*
* Asix AX88796 Ethernet
*/
@@ -80,35 +109,6 @@ static void __init colibri_pxa300_init_eth(void)
static inline void __init colibri_pxa300_init_eth(void) {}
#endif /* CONFIG_AX88796 */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static mfp_cfg_t colibri_pxa300_usb_pin_config[] __initdata = {
- GPIO0_2_USBH_PEN,
- GPIO1_2_USBH_PWR,
-};
-
-static struct pxaohci_platform_data colibri_pxa300_ohci_info = {
- .port_mode = PMM_GLOBAL_MODE,
- .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
-};
-
-void __init colibri_pxa300_init_ohci(void)
-{
- pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_usb_pin_config));
- pxa_set_ohci_info(&colibri_pxa300_ohci_info);
-}
-#else
-static inline void colibri_pxa300_init_ohci(void) {}
-#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
-
-static mfp_cfg_t colibri_pxa300_mmc_pin_config[] __initdata = {
- GPIO7_MMC1_CLK,
- GPIO14_MMC1_CMD,
- GPIO3_MMC1_DAT0,
- GPIO4_MMC1_DAT1,
- GPIO5_MMC1_DAT2,
- GPIO6_MMC1_DAT3,
-};
-
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = {
GPIO54_LCD_LDD_0,
@@ -171,24 +171,21 @@ static inline void colibri_pxa310_init_ac97(void) {}
void __init colibri_pxa300_init(void)
{
- pxa_set_ffuart_info(NULL);
- pxa_set_btuart_info(NULL);
- pxa_set_stuart_info(NULL);
-
colibri_pxa300_init_eth();
- colibri_pxa300_init_ohci();
colibri_pxa3xx_init_nand();
colibri_pxa300_init_lcd();
colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO));
colibri_pxa310_init_ac97();
- colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa300_mmc_pin_config),
- mfp_to_gpio(MFP_PIN_GPIO13));
+
+ /* Evalboard init */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_evalboard_pin_config));
+ colibri_evalboard_init();
}
MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa300_init,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index ca5f29e2e9cd..ff9ff5f4fc47 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -35,9 +35,72 @@
#include "generic.h"
#include "devices.h"
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO28_GPIO, /* SD detect */
+
+ /* UART 1 configuration (may be set by bootloader) */
+ GPIO99_UART1_CTS,
+ GPIO104_UART1_RTS,
+ GPIO97_UART1_RXD,
+ GPIO98_UART1_TXD,
+ GPIO101_UART1_DTR,
+ GPIO103_UART1_DSR,
+ GPIO100_UART1_DCD,
+ GPIO102_UART1_RI,
+
+ /* UART 2 configuration */
+ GPIO109_UART2_CTS,
+ GPIO112_UART2_RTS,
+ GPIO110_UART2_RXD,
+ GPIO111_UART2_TXD,
+
+ /* UART 3 configuration */
+ GPIO30_UART3_RXD,
+ GPIO31_UART3_TXD,
+
+ /* UHC */
+ GPIO2_2_USBH_PEN,
+ GPIO3_2_USBH_PWR,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* PCMCIA */
+ MFP_CFG(GPIO59, AF7), /* PRST ; AF7 to tristate */
+ MFP_CFG(GPIO61, AF7), /* PCE1 ; AF7 to tristate */
+ MFP_CFG(GPIO60, AF7), /* PCE2 ; AF7 to tristate */
+ MFP_CFG(GPIO62, AF7), /* PCD ; AF7 to tristate */
+ MFP_CFG(GPIO56, AF7), /* PSKTSEL ; AF7 to tristate */
+ GPIO27_GPIO, /* RDnWR ; input/tristate */
+ GPIO50_GPIO, /* PREG ; input/tristate */
+ GPIO2_RDY,
+ GPIO5_NPIOR,
+ GPIO6_NPIOW,
+ GPIO7_NPIOS16,
+ GPIO8_NPWAIT,
+ GPIO29_GPIO, /* PRDY (READY GPIO) */
+ GPIO57_GPIO, /* PPEN (POWER GPIO) */
+ GPIO81_GPIO, /* PCD (DETECT GPIO) */
+ GPIO77_GPIO, /* PRST (RESET GPIO) */
+ GPIO53_GPIO, /* PBVD1 */
+ GPIO79_GPIO, /* PBVD2 */
+ GPIO54_GPIO, /* POE */
+};
+#else
+static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {};
+#endif
+
#if defined(CONFIG_AX88796)
#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO)
-
/*
* Asix AX88796 Ethernet
*/
@@ -84,26 +147,6 @@ static void __init colibri_pxa320_init_eth(void)
static inline void __init colibri_pxa320_init_eth(void) {}
#endif /* CONFIG_AX88796 */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static mfp_cfg_t colibri_pxa320_usb_pin_config[] __initdata = {
- GPIO2_2_USBH_PEN,
- GPIO3_2_USBH_PWR,
-};
-
-static struct pxaohci_platform_data colibri_pxa320_ohci_info = {
- .port_mode = PMM_GLOBAL_MODE,
- .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
-};
-
-void __init colibri_pxa320_init_ohci(void)
-{
- pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_usb_pin_config));
- pxa_set_ohci_info(&colibri_pxa320_ohci_info);
-}
-#else
-static inline void colibri_pxa320_init_ohci(void) {}
-#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
-
#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = {
.gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96),
@@ -140,15 +183,6 @@ static void __init colibri_pxa320_init_udc(void)
static inline void colibri_pxa320_init_udc(void) {}
#endif
-static mfp_cfg_t colibri_pxa320_mmc_pin_config[] __initdata = {
- GPIO22_MMC1_CLK,
- GPIO23_MMC1_CMD,
- GPIO18_MMC1_DAT0,
- GPIO19_MMC1_DAT1,
- GPIO20_MMC1_DAT2,
- GPIO21_MMC1_DAT3
-};
-
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = {
GPIO6_2_LCD_LDD_0,
@@ -205,59 +239,24 @@ static inline void __init colibri_pxa320_init_ac97(void)
static inline void colibri_pxa320_init_ac97(void) {}
#endif
-/*
- * The following configuration is verified to work with the Toradex Orchid
- * carrier board
- */
-static mfp_cfg_t colibri_pxa320_uart_pin_config[] __initdata = {
- /* UART 1 configuration (may be set by bootloader) */
- GPIO99_UART1_CTS,
- GPIO104_UART1_RTS,
- GPIO97_UART1_RXD,
- GPIO98_UART1_TXD,
- GPIO101_UART1_DTR,
- GPIO103_UART1_DSR,
- GPIO100_UART1_DCD,
- GPIO102_UART1_RI,
-
- /* UART 2 configuration */
- GPIO109_UART2_CTS,
- GPIO112_UART2_RTS,
- GPIO110_UART2_RXD,
- GPIO111_UART2_TXD,
-
- /* UART 3 configuration */
- GPIO30_UART3_RXD,
- GPIO31_UART3_TXD,
-};
-
-static void __init colibri_pxa320_init_uart(void)
-{
- pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_uart_pin_config));
-}
-
void __init colibri_pxa320_init(void)
{
- pxa_set_ffuart_info(NULL);
- pxa_set_btuart_info(NULL);
- pxa_set_stuart_info(NULL);
-
colibri_pxa320_init_eth();
- colibri_pxa320_init_ohci();
colibri_pxa3xx_init_nand();
colibri_pxa320_init_lcd();
colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO));
colibri_pxa320_init_ac97();
- colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa320_mmc_pin_config),
- mfp_to_gpio(MFP_PIN_GPIO28));
- colibri_pxa320_init_uart();
colibri_pxa320_init_udc();
+
+ /* Evalboard init */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_evalboard_pin_config));
+ colibri_evalboard_init();
}
MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
.init_machine = colibri_pxa320_init,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 199afa2ae303..96b2d9fbfef0 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -64,55 +64,6 @@ void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data)
}
#endif
-#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
-static int mmc_detect_pin;
-
-static int colibri_pxa3xx_mci_init(struct device *dev,
- irq_handler_t colibri_mmc_detect_int,
- void *data)
-{
- int ret;
-
- ret = gpio_request(mmc_detect_pin, "mmc card detect");
- if (ret)
- return ret;
-
- gpio_direction_input(mmc_detect_pin);
- ret = request_irq(gpio_to_irq(mmc_detect_pin), colibri_mmc_detect_int,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "MMC card detect", data);
- if (ret) {
- gpio_free(mmc_detect_pin);
- return ret;
- }
-
- return 0;
-}
-
-static void colibri_pxa3xx_mci_exit(struct device *dev, void *data)
-{
- free_irq(mmc_detect_pin, data);
- gpio_free(gpio_to_irq(mmc_detect_pin));
-}
-
-static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
- .detect_delay_ms = 200,
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
- .init = colibri_pxa3xx_mci_init,
- .exit = colibri_pxa3xx_mci_exit,
- .gpio_card_detect = -1,
- .gpio_card_ro = -1,
- .gpio_power = -1,
-};
-
-void __init colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin)
-{
- pxa3xx_mfp_config(pins, len);
- mmc_detect_pin = detect_pin;
- pxa_set_mci_info(&colibri_pxa3xx_mci_platform_data);
-}
-#endif /* CONFIG_MMC_PXA || CONFIG_MMC_PXA_MODULE */
-
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static int lcd_bl_pin;
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 821229acabe6..9f3e5af0a0db 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -721,7 +721,7 @@ static void __init fixup_corgi(struct machine_desc *desc,
#ifdef CONFIG_MACH_CORGI
MACHINE_START(CORGI, "SHARP Corgi")
.fixup = fixup_corgi,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
@@ -731,7 +731,7 @@ MACHINE_END
#ifdef CONFIG_MACH_SHEPHERD
MACHINE_START(SHEPHERD, "SHARP Shepherd")
.fixup = fixup_corgi,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
@@ -741,7 +741,7 @@ MACHINE_END
#ifdef CONFIG_MACH_HUSKY
MACHINE_START(HUSKY, "SHARP Husky")
.fixup = fixup_corgi,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
index 58093d9e07be..6a7aeab42f6c 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -38,8 +38,10 @@
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
+#include <linux/io.h>
#include <mach/pxa2xx-regs.h>
+#include <mach/smemc.h>
#ifdef DEBUG
static unsigned int freq_debug;
@@ -242,7 +244,7 @@ static void pxa27x_guess_max_freq(void)
static void init_sdram_rows(void)
{
- uint32_t mdcnfg = MDCNFG;
+ uint32_t mdcnfg = __raw_readl(MDCNFG);
unsigned int drac2 = 0, drac0 = 0;
if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3))
@@ -331,8 +333,8 @@ static int pxa_set_target(struct cpufreq_policy *policy,
* we need to preset the smaller DRI before the change. If we're
* speeding up we need to set the larger DRI value after the change.
*/
- preset_mdrefr = postset_mdrefr = MDREFR;
- if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
+ preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR);
+ if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
preset_mdrefr |= mdrefr_dri(new_freq_mem);
}
@@ -370,7 +372,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
3: nop \n\
"
: "=&r" (unused)
- : "r" (&MDREFR), "r" (cclkcfg),
+ : "r" (MDREFR), "r" (cclkcfg),
"r" (preset_mdrefr), "r" (postset_mdrefr)
: "r4", "r5");
local_irq_restore(flags);
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 57cacaff194d..a305424a967d 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -27,6 +27,7 @@
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
#include <mach/audio.h>
+#include <mach/smemc.h>
#include "generic.h"
#include "devices.h"
@@ -255,9 +256,9 @@ static struct platform_device *devices[] __initdata = {
static void __init csb726_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config));
-/* MSC1 = 0x7ffc3ffc; *//* LAN9215/EXP_CS */
-/* MSC2 = 0x06697ff4; *//* none/SM501 */
- MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */
+/* __raw_writel(0x7ffc3ffc, MSC1); *//* LAN9215/EXP_CS */
+/* __raw_writel(0x06697ff4, MSC2); *//* none/SM501 */
+ __raw_writel((__raw_readl(MSC2) & ~0xffff) | 0x7ff4, MSC2); /* SM501 */
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
@@ -273,7 +274,7 @@ static void __init csb726_init(void)
MACHINE_START(CSB726, "Cogent CSB726")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = csb726_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index aaa1166df964..022c2fa4af04 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -342,27 +342,6 @@ struct platform_device pxa27x_device_i2c_power = {
};
#endif
-#ifdef CONFIG_PXA3xx
-static struct resource pxa3xx_resources_i2c_power[] = {
- {
- .start = 0x40f500c0,
- .end = 0x40f500d3,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IRQ_PWRI2C,
- .end = IRQ_PWRI2C,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device pxa3xx_device_i2c_power = {
- .name = "pxa3xx-pwri2c",
- .id = 1,
- .resource = pxa3xx_resources_i2c_power,
- .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power),
-};
-#endif
-
static struct resource pxai2s_resources[] = {
{
.start = 0x40400000,
@@ -633,30 +612,35 @@ struct platform_device pxa25x_device_assp = {
#endif /* CONFIG_PXA25x */
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-
-static struct resource pxa27x_resource_keypad[] = {
+static struct resource pxa27x_resource_camera[] = {
[0] = {
- .start = 0x41500000,
- .end = 0x4150004c,
+ .start = 0x50000000,
+ .end = 0x50000fff,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_KEYPAD,
- .end = IRQ_KEYPAD,
+ .start = IRQ_CAMERA,
+ .end = IRQ_CAMERA,
.flags = IORESOURCE_IRQ,
},
};
-struct platform_device pxa27x_device_keypad = {
- .name = "pxa27x-keypad",
- .id = -1,
- .resource = pxa27x_resource_keypad,
- .num_resources = ARRAY_SIZE(pxa27x_resource_keypad),
+static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32);
+
+static struct platform_device pxa27x_device_camera = {
+ .name = "pxa27x-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &pxa27x_dma_mask_camera,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxa27x_resource_camera),
+ .resource = pxa27x_resource_camera,
};
-void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
+void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
{
- pxa_register_device(&pxa27x_device_keypad, info);
+ pxa_register_device(&pxa27x_device_camera, info);
}
static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
@@ -689,6 +673,33 @@ void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
{
pxa_register_device(&pxa27x_device_ohci, info);
}
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+static struct resource pxa27x_resource_keypad[] = {
+ [0] = {
+ .start = 0x41500000,
+ .end = 0x4150004c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KEYPAD,
+ .end = IRQ_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_keypad = {
+ .name = "pxa27x-keypad",
+ .id = -1,
+ .resource = pxa27x_resource_keypad,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_keypad),
+};
+
+void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
+{
+ pxa_register_device(&pxa27x_device_keypad, info);
+}
static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
@@ -833,79 +844,9 @@ struct platform_device pxa27x_device_pwm1 = {
.resource = pxa27x_resource_pwm1,
.num_resources = ARRAY_SIZE(pxa27x_resource_pwm1),
};
-
-static struct resource pxa27x_resource_camera[] = {
- [0] = {
- .start = 0x50000000,
- .end = 0x50000fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_CAMERA,
- .end = IRQ_CAMERA,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32);
-
-static struct platform_device pxa27x_device_camera = {
- .name = "pxa27x-camera",
- .id = 0, /* This is used to put cameras on this interface */
- .dev = {
- .dma_mask = &pxa27x_dma_mask_camera,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(pxa27x_resource_camera),
- .resource = pxa27x_resource_camera,
-};
-
-void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
-{
- pxa_register_device(&pxa27x_device_camera, info);
-}
-#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x*/
#ifdef CONFIG_PXA3xx
-static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
-
-static struct resource pxa3xx_resource_ssp4[] = {
- [0] = {
- .start = 0x41a00000,
- .end = 0x41a0003f,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_SSP4,
- .end = IRQ_SSP4,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* DRCMR for RX */
- .start = 2,
- .end = 2,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- /* DRCMR for TX */
- .start = 3,
- .end = 3,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device pxa3xx_device_ssp4 = {
- /* PXA3xx SSP is basically equivalent to PXA27x */
- .name = "pxa27x-ssp",
- .id = 3,
- .dev = {
- .dma_mask = &pxa3xx_ssp4_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = pxa3xx_resource_ssp4,
- .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
-};
-
static struct resource pxa3xx_resources_mci2[] = {
[0] = {
.start = 0x42000000,
@@ -984,6 +925,54 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
pxa_register_device(&pxa3xx_device_mci3, info);
}
+static struct resource pxa3xx_resources_gcu[] = {
+ {
+ .start = 0x54000000,
+ .end = 0x54000fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_GCU,
+ .end = IRQ_GCU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device pxa3xx_device_gcu = {
+ .name = "pxa3xx-gcu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu),
+ .resource = pxa3xx_resources_gcu,
+ .dev = {
+ .dma_mask = &pxa3xx_gcu_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+#endif /* CONFIG_PXA3xx */
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+static struct resource pxa3xx_resources_i2c_power[] = {
+ {
+ .start = 0x40f500c0,
+ .end = 0x40f500d3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PWRI2C,
+ .end = IRQ_PWRI2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa3xx_device_i2c_power = {
+ .name = "pxa3xx-pwri2c",
+ .id = 1,
+ .resource = pxa3xx_resources_i2c_power,
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power),
+};
+
static struct resource pxa3xx_resources_nand[] = {
[0] = {
.start = 0x43100000,
@@ -1027,33 +1016,45 @@ void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info)
pxa_register_device(&pxa3xx_device_nand, info);
}
-static struct resource pxa3xx_resources_gcu[] = {
- {
- .start = 0x54000000,
- .end = 0x54000fff,
+static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa3xx_resource_ssp4[] = {
+ [0] = {
+ .start = 0x41a00000,
+ .end = 0x41a0003f,
.flags = IORESOURCE_MEM,
},
- {
- .start = IRQ_GCU,
- .end = IRQ_GCU,
+ [1] = {
+ .start = IRQ_SSP4,
+ .end = IRQ_SSP4,
.flags = IORESOURCE_IRQ,
},
+ [2] = {
+ /* DRCMR for RX */
+ .start = 2,
+ .end = 2,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 3,
+ .end = 3,
+ .flags = IORESOURCE_DMA,
+ },
};
-static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device pxa3xx_device_gcu = {
- .name = "pxa3xx-gcu",
- .id = -1,
- .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu),
- .resource = pxa3xx_resources_gcu,
+struct platform_device pxa3xx_device_ssp4 = {
+ /* PXA3xx SSP is basically equivalent to PXA27x */
+ .name = "pxa27x-ssp",
+ .id = 3,
.dev = {
- .dma_mask = &pxa3xx_gcu_dmamask,
- .coherent_dma_mask = 0xffffffff,
+ .dma_mask = &pxa3xx_ssp4_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
+ .resource = pxa3xx_resource_ssp4,
+ .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
};
-
-#endif /* CONFIG_PXA3xx */
+#endif /* CONFIG_PXA3xx || CONFIG_PXA95x */
/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
* See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index ed0dbfdb22ed..4cefd1d18afd 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -1300,7 +1300,7 @@ static void __init em_x270_init(void)
MACHINE_START(EM_X270, "Compulab EM-X270")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = em_x270_init,
@@ -1308,7 +1308,7 @@ MACHINE_END
MACHINE_START(EXEDA, "Compulab eXeda")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = em_x270_init,
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index b25690ccadc4..edca0a043293 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -181,7 +181,7 @@ static void __init e330_init(void)
MACHINE_START(E330, "Toshiba e330")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
@@ -230,7 +230,7 @@ static void __init e350_init(void)
MACHINE_START(E350, "Toshiba e350")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
@@ -352,7 +352,7 @@ static void __init e400_init(void)
MACHINE_START(E400, "Toshiba e400")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
@@ -540,7 +540,7 @@ static void __init e740_init(void)
MACHINE_START(E740, "Toshiba e740")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
@@ -731,7 +731,7 @@ static void __init e750_init(void)
MACHINE_START(E750, "Toshiba e750")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
@@ -926,7 +926,7 @@ static void __init e800_init(void)
MACHINE_START(E800, "Toshiba e800")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = ESERIES_NR_IRQS,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 142c711f4cda..87cec0abe5b0 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -798,7 +798,7 @@ static void __init a780_init(void)
MACHINE_START(EZX_A780, "Motorola EZX A780")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -863,7 +863,7 @@ static void __init e680_init(void)
MACHINE_START(EZX_E680, "Motorola EZX E680")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -928,7 +928,7 @@ static void __init a1200_init(void)
MACHINE_START(EZX_A1200, "Motorola EZX A1200")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -1118,7 +1118,7 @@ static void __init a910_init(void)
MACHINE_START(EZX_A910, "Motorola EZX A910")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -1183,7 +1183,7 @@ static void __init e6_init(void)
MACHINE_START(EZX_E6, "Motorola EZX E6")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -1222,7 +1222,7 @@ static void __init e2_init(void)
MACHINE_START(EZX_E2, "Motorola EZX E2")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = EZX_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 6451e9c3a93f..d6e15f71fc09 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -28,6 +28,8 @@
#include <mach/reset.h>
#include <mach/gpio.h>
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
#include "generic.h"
@@ -35,9 +37,10 @@ void clear_reset_status(unsigned int mask)
{
if (cpu_is_pxa2xx())
pxa2xx_clear_reset_status(mask);
-
- if (cpu_is_pxa3xx())
- pxa3xx_clear_reset_status(mask);
+ else {
+ /* RESET_STATUS_* has a 1:1 mapping with ARSR */
+ ARSR = mask;
+ }
}
unsigned long get_clock_tick_rate(void)
@@ -71,47 +74,17 @@ unsigned int get_clk_frequency_khz(int info)
EXPORT_SYMBOL(get_clk_frequency_khz);
/*
- * Return the current memory clock frequency in units of 10kHz
- */
-unsigned int get_memclk_frequency_10khz(void)
-{
- if (cpu_is_pxa25x())
- return pxa25x_get_memclk_frequency_10khz();
- else if (cpu_is_pxa27x())
- return pxa27x_get_memclk_frequency_10khz();
- return 0;
-}
-EXPORT_SYMBOL(get_memclk_frequency_10khz);
-
-/*
* Intel PXA2xx internal register mapping.
*
- * Note 1: not all PXA2xx variants implement all those addresses.
- *
- * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table
- * and cache flush area.
+ * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table
+ * and cache flush area.
*/
-static struct map_desc standard_io_desc[] __initdata = {
+static struct map_desc common_io_desc[] __initdata = {
{ /* Devs */
.virtual = 0xf2000000,
.pfn = __phys_to_pfn(0x40000000),
.length = 0x02000000,
.type = MT_DEVICE
- }, { /* Mem Ctl */
- .virtual = 0xf6000000,
- .pfn = __phys_to_pfn(0x48000000),
- .length = 0x00200000,
- .type = MT_DEVICE
- }, { /* Camera */
- .virtual = 0xfa000000,
- .pfn = __phys_to_pfn(0x50000000),
- .length = 0x00100000,
- .type = MT_DEVICE
- }, { /* IMem ctl */
- .virtual = 0xfe000000,
- .pfn = __phys_to_pfn(0x58000000),
- .length = 0x00100000,
- .type = MT_DEVICE
}, { /* UNCACHED_PHYS_0 */
.virtual = 0xff000000,
.pfn = __phys_to_pfn(0x00000000),
@@ -122,6 +95,5 @@ static struct map_desc standard_io_desc[] __initdata = {
void __init pxa_map_io(void)
{
- iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
- get_clk_frequency_khz(1);
+ iotable_init(ARRAY_AND_SIZE(common_io_desc));
}
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 4b1ad2769ed7..6205dc9a2b9d 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -20,7 +20,12 @@ extern void __init pxa26x_init_irq(void);
#endif
extern void __init pxa27x_init_irq(void);
extern void __init pxa3xx_init_irq(void);
+extern void __init pxa95x_init_irq(void);
+
extern void __init pxa_map_io(void);
+extern void __init pxa25x_map_io(void);
+extern void __init pxa27x_map_io(void);
+extern void __init pxa3xx_map_io(void);
extern unsigned int get_clk_frequency_khz(int info);
@@ -32,18 +37,14 @@ extern unsigned int get_clk_frequency_khz(int info);
#ifdef CONFIG_PXA25x
extern unsigned pxa25x_get_clk_frequency_khz(int);
-extern unsigned pxa25x_get_memclk_frequency_10khz(void);
#else
#define pxa25x_get_clk_frequency_khz(x) (0)
-#define pxa25x_get_memclk_frequency_10khz() (0)
#endif
#ifdef CONFIG_PXA27x
extern unsigned pxa27x_get_clk_frequency_khz(int);
-extern unsigned pxa27x_get_memclk_frequency_10khz(void);
#else
#define pxa27x_get_clk_frequency_khz(x) (0)
-#define pxa27x_get_memclk_frequency_10khz() (0)
#endif
#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
@@ -54,10 +55,8 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
#ifdef CONFIG_PXA3xx
extern unsigned pxa3xx_get_clk_frequency_khz(int);
-extern void pxa3xx_clear_reset_status(unsigned int);
#else
#define pxa3xx_get_clk_frequency_khz(x) (0)
-static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
#endif
extern struct sysdev_class pxa_irq_sysclass;
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index 1e2a9a13aec1..6fd319ea5284 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -225,7 +225,7 @@ static void __init gumstix_init(void)
MACHINE_START(GUMSTIX, "Gumstix")
.boot_params = 0xa0000100, /* match u-boot bi_boot_params */
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = gumstix_init,
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
index 7057a1f46db4..657db469de1f 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -32,6 +32,7 @@
#include <mach/pxa25x.h>
#include <mach/h5000.h>
#include <mach/udc.h>
+#include <mach/smemc.h>
#include "generic.h"
@@ -172,11 +173,11 @@ static unsigned long h5000_pin_config[] __initdata = {
static void fix_msc(void)
{
- MSC0 = 0x129c24f2;
- MSC1 = 0x7ff424fa;
- MSC2 = 0x7ff47ff4;
+ __raw_writel(0x129c24f2, MSC0);
+ __raw_writel(0x7ff424fa, MSC1);
+ __raw_writel(0x7ff47ff4, MSC2);
- MDREFR |= 0x02080000;
+ __raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR);
}
/*
@@ -202,7 +203,7 @@ static void __init h5000_init(void)
MACHINE_START(H5400, "HP iPAQ H5000")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = h5000_init,
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
index 01b7f07ebad2..e8603eba54bd 100644
--- a/arch/arm/mach-pxa/himalaya.c
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -160,7 +160,7 @@ static void __init himalaya_init(void)
MACHINE_START(HIMALAYA, "HTC Himalaya")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.init_machine = himalaya_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 76d93a25bab6..cacb21b7014d 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -871,7 +871,7 @@ static void __init hx4700_init(void)
MACHINE_START(H4700, "HP iPAQ HX4700")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = HX4700_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = hx4700_init,
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index d51ee3d25e70..ac6ee12e400e 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -192,7 +192,7 @@ static void __init icontrol_init(void)
MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = icontrol_init
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index e773dceeabc6..dd40e4a9291c 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -187,7 +187,7 @@ static struct map_desc idp_io_desc[] __initdata = {
static void __init idp_map_io(void)
{
- pxa_map_io();
+ pxa25x_map_io();
iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
}
diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h
new file mode 100644
index 000000000000..f4c03659168c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/addr-map.h
@@ -0,0 +1,48 @@
+#ifndef __ASM_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/*
+ * Chip Selects
+ */
+#define PXA_CS0_PHYS 0x00000000
+#define PXA_CS1_PHYS 0x04000000
+#define PXA_CS2_PHYS 0x08000000
+#define PXA_CS3_PHYS 0x0C000000
+#define PXA_CS4_PHYS 0x10000000
+#define PXA_CS5_PHYS 0x14000000
+
+#define PXA300_CS0_PHYS 0x00000000 /* PXA300/PXA310 _only_ */
+#define PXA300_CS1_PHYS 0x30000000 /* PXA300/PXA310 _only_ */
+#define PXA3xx_CS2_PHYS 0x10000000
+#define PXA3xx_CS3_PHYS 0x14000000
+
+/*
+ * Peripheral Bus
+ */
+#define PERIPH_PHYS 0x40000000
+#define PERIPH_VIRT 0xf2000000
+#define PERIPH_SIZE 0x02000000
+
+/*
+ * Static Memory Controller (w/ SDRAM controls on PXA25x/PXA27x)
+ */
+#define PXA2XX_SMEMC_PHYS 0x48000000
+#define PXA3XX_SMEMC_PHYS 0x4a000000
+#define SMEMC_VIRT 0xf6000000
+#define SMEMC_SIZE 0x00100000
+
+/*
+ * Dynamic Memory Controller (only on PXA3xx)
+ */
+#define DMEMC_PHYS 0x48100000
+#define DMEMC_VIRT 0xf6100000
+#define DMEMC_SIZE 0x00100000
+
+/*
+ * Internal Memory Controller (PXA27x and later)
+ */
+#define IMEMC_PHYS 0x58000000
+#define IMEMC_VIRT 0xfe000000
+#define IMEMC_SIZE 0x00100000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
index 561562b4360b..7074e76146c9 100644
--- a/arch/arm/mach-pxa/include/mach/balloon3.h
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -26,6 +26,8 @@ enum balloon3_features {
#define BALLOON3_FPGA_VIRT (0xf1000000) /* as per balloon2 */
#define BALLOON3_FPGA_LENGTH 0x01000000
+#define BALLOON3_FPGA_SETnCLR (0x1000)
+
/* FPGA / CPLD registers for CF socket */
#define BALLOON3_CF_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00e00008)
#define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008)
@@ -35,7 +37,7 @@ enum balloon3_features {
#define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000)
#define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000)
#define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
-#define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
+#define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
#define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
/* fpga/cpld interrupt control register */
@@ -174,7 +176,7 @@ enum balloon3_features {
#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
-#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 4)
+#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16)
extern int balloon3_has(enum balloon3_features feature);
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
index 58dada11054f..388a96f1ef93 100644
--- a/arch/arm/mach-pxa/include/mach/colibri.h
+++ b/arch/arm/mach-pxa/include/mach/colibri.h
@@ -9,14 +9,14 @@
*/
enum {
- COLIBRI_PXA270_EVALBOARD = 0,
+ COLIBRI_EVALBOARD = 0,
COLIBRI_PXA270_INCOME,
};
-#if defined(CONFIG_MACH_COLIBRI_PXA270_EVALBOARD)
-extern void colibri_pxa270_evalboard_init(void);
+#if defined(CONFIG_MACH_COLIBRI_EVALBOARD)
+extern void colibri_evalboard_init(void);
#else
-static inline void colibri_pxa270_evalboard_init(void) {}
+static inline void colibri_evalboard_init(void) {}
#endif
#if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME)
@@ -59,5 +59,11 @@ static inline void colibri_pxa3xx_init_nand(void) {}
#define GPIO0_COLIBRI_PXA270_SD_DETECT 0
#define GPIO113_COLIBRI_PXA270_TS_IRQ 113
+/* GPIO definitions for Colibri PXA300/310 */
+#define GPIO39_COLIBRI_PXA300_SD_DETECT 39
+
+/* GPIO definitions for Colibri PXA320 */
+#define GPIO28_COLIBRI_PXA320_SD_DETECT 28
+
#endif /* _COLIBRI_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index 814f1458a06a..6957ba56025b 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -13,6 +13,8 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
+#include <mach/addr-map.h>
+
/*
* Workarounds for at least 2 errata so far require this.
* The mapping is set in mach-pxa/generic.c.
@@ -193,14 +195,15 @@
#define __cpu_is_pxa935(id) (0)
#endif
-#ifdef CONFIG_CPU_PXA950
-#define __cpu_is_pxa950(id) \
- ({ \
+#ifdef CONFIG_CPU_PXA955
+#define __cpu_is_pxa955(id) \
+ ({ \
unsigned int _id = (id) >> 4 & 0xfff; \
- _id == 0x697; \
- })
+ _id == 0x581 || _id == 0xc08 \
+ || _id == 0xb76; \
+ })
#else
-#define __cpu_is_pxa950(id) (0)
+#define __cpu_is_pxa955(id) (0)
#endif
#define cpu_is_pxa210() \
@@ -253,16 +256,15 @@
__cpu_is_pxa935(read_cpuid_id()); \
})
-#define cpu_is_pxa950() \
+#define cpu_is_pxa955() \
({ \
- __cpu_is_pxa950(read_cpuid_id()); \
- })
+ __cpu_is_pxa955(read_cpuid_id()); \
+ })
/*
* CPUID Core Generation Bit
* <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
- * == 0x3 for pxa300/pxa310/pxa320
*/
#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
#define __cpu_is_pxa2xx(id) \
@@ -277,8 +279,10 @@
#ifdef CONFIG_PXA3xx
#define __cpu_is_pxa3xx(id) \
({ \
- unsigned int _id = (id) >> 13 & 0x7; \
- _id == 0x3; \
+ __cpu_is_pxa300(id) \
+ || __cpu_is_pxa310(id) \
+ || __cpu_is_pxa320(id) \
+ || __cpu_is_pxa93x(id); \
})
#else
#define __cpu_is_pxa3xx(id) (0)
@@ -287,13 +291,22 @@
#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
#define __cpu_is_pxa93x(id) \
({ \
- unsigned int _id = (id) >> 4 & 0xfff; \
- _id == 0x683 || _id == 0x693; \
+ __cpu_is_pxa930(id) \
+ || __cpu_is_pxa935(id); \
})
#else
#define __cpu_is_pxa93x(id) (0)
#endif
+#ifdef CONFIG_PXA95x
+#define __cpu_is_pxa95x(id) \
+ ({ \
+ __cpu_is_pxa955(id); \
+ })
+#else
+#define __cpu_is_pxa95x(id) (0)
+#endif
+
#define cpu_is_pxa2xx() \
({ \
__cpu_is_pxa2xx(read_cpuid_id()); \
@@ -308,6 +321,12 @@
({ \
__cpu_is_pxa93x(read_cpuid_id()); \
})
+
+#define cpu_is_pxa95x() \
+ ({ \
+ __cpu_is_pxa95x(read_cpuid_id()); \
+ })
+
/*
* return current memory and LCD clock frequency in units of 10kHz
*/
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index d372caa75dc7..a4285fc00878 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -21,16 +21,14 @@
#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x))
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
-#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */
-#define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI) */
+#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI,PXA27x) */
+#define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI,PXA27x) */
#define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */
-#define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt */
+#define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt (PXA27x) */
+#define IRQ_ACIPC0 PXA_IRQ(5) /* AP-CP Communication (PXA930) */
#define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */
-#endif
-
#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */
#define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */
#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
@@ -38,7 +36,8 @@
#define IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2-x] Edge Detect */
#define IRQ_USB PXA_IRQ(11) /* USB Service */
#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */
-#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */
+#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt (PXA27x) */
+#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request (PXA3xx) */
#define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */
#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request (PXA25x) */
#define IRQ_USIM PXA_IRQ(15) /* Smart Card interface interrupt (PXA27x) */
@@ -47,6 +46,7 @@
#define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */
#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */
#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */
+#define IRQ_ACIPC2 PXA_IRQ(19) /* AP-CP Communication (PXA930) */
#define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */
#define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */
#define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/
@@ -60,19 +60,17 @@
#define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */
#define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */
#define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */
-#endif
-
-#ifdef CONFIG_PXA3xx
-#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request */
#define IRQ_CIR PXA_IRQ(34) /* Consumer IR */
#define IRQ_COMM_WDT PXA_IRQ(35) /* Comm WDT interrupt */
#define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */
+#define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */
#define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */
-#define IRQ_GCU PXA_IRQ(39) /* Graphics Controller */
+#define IRQ_GCU PXA_IRQ(39) /* Graphics Controller (PXA3xx) */
+#define IRQ_ACIPC1 PXA_IRQ(40) /* AP-CP Communication (PXA930) */
#define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */
+#define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball (PXA930) */
#define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */
#define IRQ_NAND PXA_IRQ(45) /* NAND Controller */
#define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */
@@ -80,30 +78,14 @@
#define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */
#define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */
#define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */
-#endif
-#ifdef CONFIG_CPU_PXA935
#define IRQ_U2O PXA_IRQ(64) /* USB OTG 2.0 Controller (PXA935) */
#define IRQ_U2H PXA_IRQ(65) /* USB Host 2.0 Controller (PXA935) */
-
-#define IRQ_MMC3_PXA935 PXA_IRQ(72) /* MMC3 Controller (PXA935) */
-#define IRQ_MMC4_PXA935 PXA_IRQ(73) /* MMC4 Controller (PXA935) */
-#define IRQ_MMC5_PXA935 PXA_IRQ(74) /* MMC5 Controller (PXA935) */
-
+#define IRQ_PXA935_MMC0 PXA_IRQ(72) /* MMC0 Controller (PXA935) */
+#define IRQ_PXA935_MMC1 PXA_IRQ(73) /* MMC1 Controller (PXA935) */
+#define IRQ_PXA935_MMC2 PXA_IRQ(74) /* MMC2 Controller (PXA935) */
+#define IRQ_PXA955_MMC3 PXA_IRQ(75) /* MMC3 Controller (PXA955) */
#define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */
-#endif
-
-#ifdef CONFIG_CPU_PXA930
-#define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */
-#define IRQ_ACIPC0 PXA_IRQ(5)
-#define IRQ_ACIPC1 PXA_IRQ(40)
-#define IRQ_ACIPC2 PXA_IRQ(19)
-#define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball */
-#endif
-
-#ifdef CONFIG_CPU_PXA950
-#define IRQ_GC500 PXA_IRQ(70) /* Graphics Controller (PXA950) */
-#endif
#define PXA_GPIO_IRQ_BASE PXA_IRQ(96)
#define PXA_GPIO_IRQ_NUM (192)
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
index 4fcddd9cab76..ee6ced1cea7f 100644
--- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
@@ -17,72 +17,6 @@
#include <mach/hardware.h>
/*
- * PXA Chip selects
- */
-
-#define PXA_CS0_PHYS 0x00000000
-#define PXA_CS1_PHYS 0x04000000
-#define PXA_CS2_PHYS 0x08000000
-#define PXA_CS3_PHYS 0x0C000000
-#define PXA_CS4_PHYS 0x10000000
-#define PXA_CS5_PHYS 0x14000000
-
-/*
- * Memory controller
- */
-
-#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
-#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
-#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
-#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
-#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
-#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
-#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
-#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
-#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
-#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
-#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
-#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
-#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
-#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
-#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
-#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
-#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
-
-/*
- * More handy macros for PCMCIA
- *
- * Arg is socket number
- */
-#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */
-#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */
-#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */
-
-/* MECR register defines */
-#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
-#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
-
-#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
-#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
-#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
-#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */
-
-#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
-#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
-#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
-#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
-#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
-#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
-#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
-#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
-#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
-#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
-#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
-#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
-#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
-#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
-
-/*
* Power Manager
*/
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
index e91d63cfe811..e4fb4668c26e 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -16,15 +16,6 @@
#include <mach/hardware.h>
/*
- * Static Chip Selects
- */
-
-#define PXA300_CS0_PHYS (0x00000000) /* PXA300/PXA310 _only_ */
-#define PXA300_CS1_PHYS (0x30000000) /* PXA300/PXA310 _only_ */
-#define PXA3xx_CS2_PHYS (0x10000000)
-#define PXA3xx_CS3_PHYS (0x14000000)
-
-/*
* Oscillator Configuration Register (OSCC)
*/
#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */
diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h
index 68464ce1c1ea..662288eb6f95 100644
--- a/arch/arm/mach-pxa/include/mach/regs-intc.h
+++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
@@ -27,8 +27,4 @@
#define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */
#define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */
-#define IPR(x) __REG(0x40D0001C + (x < 32 ? (x << 2) \
- : (x < 64 ? (0x94 + ((x - 32) << 2)) \
- : (0x128 + ((x - 64) << 2)))))
-
#endif /* __ASM_MACH_REGS_INTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/smemc.h b/arch/arm/mach-pxa/include/mach/smemc.h
new file mode 100644
index 000000000000..654adc90c9a0
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/smemc.h
@@ -0,0 +1,74 @@
+/*
+ * Static memory controller register definitions for PXA CPUs
+ *
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SMEMC_REGS_H
+#define __SMEMC_REGS_H
+
+#define PXA2XX_SMEMC_BASE 0x48000000
+#define PXA3XX_SMEMC_BASE 0x4a000000
+#define SMEMC_VIRT 0xf6000000
+
+#define MDCNFG (SMEMC_VIRT + 0x00) /* SDRAM Configuration Register 0 */
+#define MDREFR (SMEMC_VIRT + 0x04) /* SDRAM Refresh Control Register */
+#define MSC0 (SMEMC_VIRT + 0x08) /* Static Memory Control Register 0 */
+#define MSC1 (SMEMC_VIRT + 0x0C) /* Static Memory Control Register 1 */
+#define MSC2 (SMEMC_VIRT + 0x10) /* Static Memory Control Register 2 */
+#define MECR (SMEMC_VIRT + 0x14) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
+#define SXLCR (SMEMC_VIRT + 0x18) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
+#define SXCNFG (SMEMC_VIRT + 0x1C) /* Synchronous Static Memory Control Register */
+#define SXMRS (SMEMC_VIRT + 0x24) /* MRS value to be written to Synchronous Flash or SMROM */
+#define MCMEM0 (SMEMC_VIRT + 0x28) /* Card interface Common Memory Space Socket 0 Timing */
+#define MCMEM1 (SMEMC_VIRT + 0x2C) /* Card interface Common Memory Space Socket 1 Timing */
+#define MCATT0 (SMEMC_VIRT + 0x30) /* Card interface Attribute Space Socket 0 Timing Configuration */
+#define MCATT1 (SMEMC_VIRT + 0x34) /* Card interface Attribute Space Socket 1 Timing Configuration */
+#define MCIO0 (SMEMC_VIRT + 0x38) /* Card interface I/O Space Socket 0 Timing Configuration */
+#define MCIO1 (SMEMC_VIRT + 0x3C) /* Card interface I/O Space Socket 1 Timing Configuration */
+#define MDMRS (SMEMC_VIRT + 0x40) /* MRS value to be written to SDRAM */
+#define BOOT_DEF (SMEMC_VIRT + 0x44) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+#define MEMCLKCFG (SMEMC_VIRT + 0x68) /* Clock Configuration */
+#define CSADRCFG0 (SMEMC_VIRT + 0x80) /* Address Configuration Register for CS0 */
+#define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */
+#define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */
+#define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */
+
+/*
+ * More handy macros for PCMCIA
+ *
+ * Arg is socket number
+ */
+#define MCMEM(s) (SMEMC_VIRT + 0x28 + ((s)<<2)) /* Card interface Common Memory Space Socket s Timing */
+#define MCATT(s) (SMEMC_VIRT + 0x30 + ((s)<<2)) /* Card interface Attribute Space Socket s Timing Configuration */
+#define MCIO(s) (SMEMC_VIRT + 0x38 + ((s)<<2)) /* Card interface I/O Space Socket s Timing Configuration */
+
+/* MECR register defines */
+#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
+#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
+
+#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
+#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
+#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
+#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */
+
+#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
+#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
+#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
+#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
+#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
+#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
+#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
+#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
+#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
+#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
+#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
+#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
+#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
+#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
+
+#endif
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 1beb40f692fc..54e91c9e71c8 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -16,20 +16,31 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <linux/irq.h>
#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
+#include <mach/irqs.h>
#include <mach/gpio.h>
-#include <mach/regs-intc.h>
#include "generic.h"
-#define MAX_INTERNAL_IRQS 128
+#define IRQ_BASE (void __iomem *)io_p2v(0x40d00000)
+
+#define ICIP (0x000)
+#define ICMR (0x004)
+#define ICLR (0x008)
+#define ICFR (0x00c)
+#define ICPR (0x010)
+#define ICCR (0x014)
+#define ICHP (0x018)
+#define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \
+ ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \
+ (0x144 + (((i) - 64) << 2)))
+#define IPR_VALID (1 << 31)
+#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
-#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
-#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
-#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
+#define MAX_INTERNAL_IRQS 128
/*
* This is for peripheral IRQs internal to the PXA chip.
@@ -37,14 +48,27 @@
static int pxa_internal_irq_nr;
+static inline int cpu_has_ipr(void)
+{
+ return !cpu_is_pxa25x();
+}
+
static void pxa_mask_irq(unsigned int irq)
{
- _ICMR(irq) &= ~(1 << IRQ_BIT(irq));
+ void __iomem *base = get_irq_chip_data(irq);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr &= ~(1 << IRQ_BIT(irq));
+ __raw_writel(icmr, base + ICMR);
}
static void pxa_unmask_irq(unsigned int irq)
{
- _ICMR(irq) |= 1 << IRQ_BIT(irq);
+ void __iomem *base = get_irq_chip_data(irq);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr |= 1 << IRQ_BIT(irq);
+ __raw_writel(icmr, base + ICMR);
}
static struct irq_chip pxa_internal_irq_chip = {
@@ -86,12 +110,16 @@ static void pxa_ack_low_gpio(unsigned int irq)
static void pxa_mask_low_gpio(unsigned int irq)
{
- ICMR &= ~(1 << (irq - PXA_IRQ(0)));
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ desc->chip->mask(irq);
}
static void pxa_unmask_low_gpio(unsigned int irq)
{
- ICMR |= 1 << (irq - PXA_IRQ(0));
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ desc->chip->unmask(irq);
}
static struct irq_chip pxa_low_gpio_chip = {
@@ -120,33 +148,45 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn)
pxa_low_gpio_chip.set_wake = fn;
}
+static inline void __iomem *irq_base(int i)
+{
+ static unsigned long phys_base[] = {
+ 0x40d00000,
+ 0x40d0009c,
+ 0x40d00130,
+ };
+
+ return (void __iomem *)io_p2v(phys_base[i >> 5]);
+}
+
void __init pxa_init_irq(int irq_nr, set_wake_t fn)
{
- int irq, i;
+ int irq, i, n;
BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
pxa_internal_irq_nr = irq_nr;
- for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
- _ICMR(irq) = 0; /* disable all IRQs */
- _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
- }
-
- /* initialize interrupt priority */
- if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
- for (i = 0; i < irq_nr; i++)
- IPR(i) = i | (1 << 31);
+ for (n = 0; n < irq_nr; n += 32) {
+ void __iomem *base = irq_base(n);
+
+ __raw_writel(0, base + ICMR); /* disable all IRQs */
+ __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */
+ for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
+ /* initialize interrupt priority */
+ if (cpu_has_ipr())
+ __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
+
+ irq = PXA_IRQ(i);
+ set_irq_chip(irq, &pxa_internal_irq_chip);
+ set_irq_chip_data(irq, base);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
}
/* only unmasked interrupts kick us out of idle */
- ICCR = 1;
-
- for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
- set_irq_chip(irq, &pxa_internal_irq_chip);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
+ __raw_writel(1, irq_base(0) + ICCR);
pxa_internal_irq_chip.set_wake = fn;
pxa_init_low_gpio_irq(fn);
@@ -158,16 +198,18 @@ static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
{
- int i, irq = PXA_IRQ(0);
+ int i;
- for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
- saved_icmr[i] = _ICMR(irq);
- _ICMR(irq) = 0;
+ for (i = 0; i < pxa_internal_irq_nr; i += 32) {
+ void __iomem *base = irq_base(i);
+
+ saved_icmr[i] = __raw_readl(base + ICMR);
+ __raw_writel(0, base + ICMR);
}
- if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+ if (cpu_has_ipr()) {
for (i = 0; i < pxa_internal_irq_nr; i++)
- saved_ipr[i] = IPR(i);
+ saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
}
return 0;
@@ -175,19 +217,20 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
static int pxa_irq_resume(struct sys_device *dev)
{
- int i, irq = PXA_IRQ(0);
+ int i;
- if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
- for (i = 0; i < pxa_internal_irq_nr; i++)
- IPR(i) = saved_ipr[i];
- }
+ for (i = 0; i < pxa_internal_irq_nr; i += 32) {
+ void __iomem *base = irq_base(i);
- for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
- _ICMR(irq) = saved_icmr[i];
- _ICLR(irq) = 0;
+ __raw_writel(saved_icmr[i], base + ICMR);
+ __raw_writel(0, base + ICLR);
}
- ICCR = 1;
+ if (!cpu_is_pxa25x())
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
+
+ __raw_writel(1, IRQ_BASE + ICCR);
return 0;
}
#else
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 41aa89e35772..719c260597e7 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -438,7 +438,7 @@ static void __init littleton_init(void)
MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.nr_irqs = LITTLETON_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 623af0232a54..8ab62a677807 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -46,6 +46,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
+#include <mach/smemc.h>
#include "generic.h"
#include "devices.h"
@@ -463,7 +464,7 @@ static void __init lpd270_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
+ lpd270_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
lpd270_flash_data[1].width = 4;
/*
@@ -495,7 +496,7 @@ static struct map_desc lpd270_io_desc[] __initdata = {
static void __init lpd270_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc));
/* for use I SRAM as framebuffer. */
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1499493cd070..d3375486c8cd 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -50,6 +50,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/pm.h>
+#include <mach/smemc.h>
#include "generic.h"
#include "clock.h"
@@ -525,7 +526,7 @@ static void __init lubbock_init(void)
pxa_set_ac97_info(NULL);
lubbock_flash_data[0].width = lubbock_flash_data[1].width =
- (BOOT_DEF & 1) ? 2 : 4;
+ (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
/* Compensate for the nROMBT switch which swaps the flash banks */
printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
flashboot?"Flash":"ROM", flashboot);
@@ -549,7 +550,7 @@ static struct map_desc lubbock_io_desc[] __initdata = {
static void __init lubbock_map_io(void)
{
- pxa_map_io();
+ pxa25x_map_io();
iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
PCFR |= PCFR_OPDE;
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 90663760307a..41198f0dc3ac 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -765,7 +765,7 @@ static void __init magician_init(void)
MACHINE_START(MAGICIAN, "HTC Magician")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = MAGICIAN_NR_IRQS,
.init_irq = pxa27x_init_irq,
.init_machine = magician_init,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a980a5c93e49..740c03590e3b 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -51,6 +51,7 @@
#include <mach/irda.h>
#include <mach/ohci.h>
#include <plat/pxa27x_keypad.h>
+#include <mach/smemc.h>
#include "generic.h"
#include "devices.h"
@@ -565,7 +566,7 @@ static void __init mainstone_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
+ mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
mst_flash_data[1].width = 4;
/* Compensate for SW7 which swaps the flash banks */
@@ -614,7 +615,7 @@ static struct map_desc mainstone_io_desc[] __initdata = {
static void __init mainstone_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
/* for use I SRAM as framebuffer. */
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index f5fb915e1315..faafea3542fb 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -819,7 +819,7 @@ static void mioa701_machine_exit(void)
MACHINE_START(MIOA701, "MIO A701")
.boot_params = 0xa0000100,
- .map_io = &pxa_map_io,
+ .map_io = &pxa27x_map_io,
.init_irq = &pxa27x_init_irq,
.init_machine = mioa701_machine_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 116167aaba68..59cce78aebd1 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -94,7 +94,7 @@ static void __init mp900c_init(void)
MACHINE_START(NEC_MP900, "MobilePro900/C")
.boot_params = 0xa0220100,
.timer = &pxa_timer,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.init_machine = mp900c_init,
MACHINE_END
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index ce092c521e6d..a6f898cbfac9 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -313,7 +313,7 @@ static struct map_desc palmld_io_desc[] __initdata = {
static void __init palmld_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
}
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 862da812cd10..df4d7d009fbb 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -203,7 +203,7 @@ static void __init palmt5_init(void)
MACHINE_START(PALMT5, "Palm Tungsten|T5")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.reserve = palmt5_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 2131d5860919..a09a2374697b 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -25,6 +25,7 @@
#include <linux/power_supply.h>
#include <linux/gpio_keys.h>
#include <linux/mtd/physmap.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,7 @@ static unsigned long palmtc_pin_config[] __initdata = {
/******************************************************************************
* SD/MMC card controller
******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static struct pxamci_platform_data palmtc_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.gpio_power = GPIO_NR_PALMTC_SD_POWER,
@@ -124,9 +126,18 @@ static struct pxamci_platform_data palmtc_mci_platform_data = {
.detect_delay_ms = 200,
};
+static void __init palmtc_mmc_init(void)
+{
+ pxa_set_mci_info(&palmtc_mci_platform_data);
+}
+#else
+static inline void palmtc_mmc_init(void) {}
+#endif
+
/******************************************************************************
* GPIO keys
******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button palmtc_pxa_buttons[] = {
{KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1},
};
@@ -144,9 +155,18 @@ static struct platform_device palmtc_pxa_keys = {
},
};
+static void __init palmtc_keys_init(void)
+{
+ platform_device_register(&palmtc_pxa_keys);
+}
+#else
+static inline void palmtc_keys_init(void) {}
+#endif
+
/******************************************************************************
* Backlight
******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
static int palmtc_backlight_init(struct device *dev)
{
int ret;
@@ -196,17 +216,35 @@ static struct platform_device palmtc_backlight = {
},
};
+static void __init palmtc_pwm_init(void)
+{
+ platform_device_register(&palmtc_backlight);
+}
+#else
+static inline void palmtc_pwm_init(void) {}
+#endif
+
/******************************************************************************
* IrDA
******************************************************************************/
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
static struct pxaficp_platform_data palmtc_ficp_platform_data = {
.gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE,
.transceiver_cap = IR_SIRMODE | IR_OFF,
};
+static void __init palmtc_irda_init(void)
+{
+ pxa_set_ficp_info(&palmtc_ficp_platform_data);
+}
+#else
+static inline void palmtc_irda_init(void) {}
+#endif
+
/******************************************************************************
* Keyboard
******************************************************************************/
+#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
static const uint32_t palmtc_matrix_keys[] = {
KEY(0, 0, KEY_F1),
KEY(0, 1, KEY_X),
@@ -290,27 +328,103 @@ static struct platform_device palmtc_keyboard = {
.platform_data = &palmtc_keypad_platform_data,
},
};
+static void __init palmtc_mkp_init(void)
+{
+ platform_device_register(&palmtc_keyboard);
+}
+#else
+static inline void palmtc_mkp_init(void) {}
+#endif
/******************************************************************************
* UDC
******************************************************************************/
-static struct pxa2xx_udc_mach_info palmtc_udc_info __initdata = {
+#if defined(CONFIG_USB_GADGET_PXA25X)||defined(CONFIG_USB_GADGET_PXA25X_MODULE)
+static struct gpio_vbus_mach_info palmtc_udc_info = {
.gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTC_USB_POWER,
};
+static struct platform_device palmtc_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_udc_info,
+ },
+};
+
+static void __init palmtc_udc_init(void)
+{
+ platform_device_register(&palmtc_gpio_vbus);
+};
+#else
+static inline void palmtc_udc_init(void) {}
+#endif
+
/******************************************************************************
* Touchscreen / Battery / GPIO-extender
******************************************************************************/
-static struct platform_device palmtc_ucb1400_core = {
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static struct platform_device palmtc_ucb1400_device = {
.name = "ucb1400_core",
.id = -1,
};
+static void __init palmtc_ts_init(void)
+{
+ pxa_set_ac97_info(NULL);
+ platform_device_register(&palmtc_ucb1400_device);
+}
+#else
+static inline void palmtc_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led palmtc_gpio_leds[] = {
+{
+ .name = "palmtc:green:user",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMTC_LED_POWER,
+ .active_low = 1,
+}, {
+ .name = "palmtc:vibra:vibra",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMTC_VIBRA_POWER,
+ .active_low = 1,
+}
+
+};
+
+static struct gpio_led_platform_data palmtc_gpio_led_info = {
+ .leds = palmtc_gpio_leds,
+ .num_leds = ARRAY_SIZE(palmtc_gpio_leds),
+};
+
+static struct platform_device palmtc_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_gpio_led_info,
+ }
+};
+
+static void __init palmtc_leds_init(void)
+{
+ platform_device_register(&palmtc_leds);
+}
+#else
+static inline void palmtc_leds_init(void) {}
+#endif
+
/******************************************************************************
* NOR Flash
******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct resource palmtc_flash_resource = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_16M - 1,
@@ -356,24 +470,33 @@ static struct platform_device palmtc_flash = {
},
};
+static void __init palmtc_nor_init(void)
+{
+ platform_device_register(&palmtc_flash);
+}
+#else
+static inline void palmtc_nor_init(void) {}
+#endif
+
/******************************************************************************
* Framebuffer
******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static struct pxafb_mode_info palmtc_lcd_modes[] = {
-{
- .pixclock = 115384,
- .xres = 320,
- .yres = 320,
- .bpp = 16,
-
- .left_margin = 27,
- .right_margin = 7,
- .upper_margin = 7,
- .lower_margin = 8,
-
- .hsync_len = 6,
- .vsync_len = 1,
-},
+ {
+ .pixclock = 115384,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 27,
+ .right_margin = 7,
+ .upper_margin = 7,
+ .lower_margin = 8,
+
+ .hsync_len = 6,
+ .vsync_len = 1,
+ },
};
static struct pxafb_mach_info palmtc_lcd_screen = {
@@ -382,17 +505,17 @@ static struct pxafb_mach_info palmtc_lcd_screen = {
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};
+static void __init palmtc_lcd_init(void)
+{
+ set_pxa_fb_info(&palmtc_lcd_screen);
+}
+#else
+static inline void palmtc_lcd_init(void) {}
+#endif
+
/******************************************************************************
* Machine init
******************************************************************************/
-static struct platform_device *devices[] __initdata = {
- &palmtc_backlight,
- &palmtc_ucb1400_core,
- &palmtc_keyboard,
- &palmtc_pxa_keys,
- &palmtc_flash,
-};
-
static void __init palmtc_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config));
@@ -402,18 +525,21 @@ static void __init palmtc_init(void)
pxa_set_stuart_info(NULL);
pxa_set_hwuart_info(NULL);
- set_pxa_fb_info(&palmtc_lcd_screen);
- pxa_set_mci_info(&palmtc_mci_platform_data);
- pxa_set_udc_info(&palmtc_udc_info);
- pxa_set_ac97_info(NULL);
- pxa_set_ficp_info(&palmtc_ficp_platform_data);
-
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ palmtc_mmc_init();
+ palmtc_keys_init();
+ palmtc_pwm_init();
+ palmtc_irda_init();
+ palmtc_mkp_init();
+ palmtc_udc_init();
+ palmtc_ts_init();
+ palmtc_nor_init();
+ palmtc_lcd_init();
+ palmtc_leds_init();
};
MACHINE_START(PALMTC, "Palm Tungsten|C")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = palmtc_init
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index a9dae7bc35d9..3f25014a136c 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -374,7 +374,7 @@ static void __init palmte2_init(void)
MACHINE_START(PALMTE2, "Palm Tungsten|E2")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
.init_machine = palmte2_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index 00e2d7ba84ed..8aadad55fbe4 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -442,7 +442,7 @@ static void __init centro_init(void)
MACHINE_START(TREO680, "Palm Treo 680")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.reserve = treo_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
@@ -451,7 +451,7 @@ MACHINE_END
MACHINE_START(CENTRO, "Palm Centro 685")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.reserve = treo_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index d2060a1d1d68..595f002066cc 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {}
/******************************************************************************
* NAND Flash
******************************************************************************/
-#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
@@ -333,7 +334,7 @@ static struct map_desc palmtx_io_desc[] __initdata = {
static void __init palmtx_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
}
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index af6203fbca9c..7bf4017326e3 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -280,7 +280,7 @@ static void __init palmz72_init(void)
MACHINE_START(PALMZ72, "Palm Zire72")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = palmz72_init
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index c77e8f30a439..8547c9abc40a 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -244,7 +244,7 @@ static void __init pcm027_init(void)
static void __init pcm027_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
/* initialize sleep mode regs (wake-up sources, etc) */
PGSR0 = 0x01308000;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 93a191c889df..8451790cb48d 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -466,7 +466,7 @@ static void __init fixup_poodle(struct machine_desc *desc,
MACHINE_START(POODLE, "SHARP Poodle")
.fixup = fixup_poodle,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index de53f2e4aa39..3f5241c84894 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -23,6 +23,7 @@
#include <linux/suspend.h>
#include <linux/sysdev.h>
+#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/gpio.h>
@@ -30,6 +31,7 @@
#include <mach/reset.h>
#include <mach/pm.h>
#include <mach/dma.h>
+#include <mach/smemc.h>
#include "generic.h"
#include "devices.h"
@@ -90,23 +92,21 @@ unsigned int pxa25x_get_clk_frequency_khz(int info)
return (turbo & 1) ? (N/1000) : (M/1000);
}
-/*
- * Return the current memory clock frequency in units of 10kHz
- */
-unsigned int pxa25x_get_memclk_frequency_10khz(void)
+static unsigned long clk_pxa25x_mem_getrate(struct clk *clk)
{
- return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
+ return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK;
}
-static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk)
-{
- return pxa25x_get_memclk_frequency_10khz() * 10000;
-}
+static const struct clkops clk_pxa25x_mem_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+ .getrate = clk_pxa25x_mem_getrate,
+};
static const struct clkops clk_pxa25x_lcd_ops = {
- .enable = clk_cken_enable,
- .disable = clk_cken_disable,
- .getrate = clk_pxa25x_lcd_getrate,
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
+ .getrate = clk_pxa25x_mem_getrate,
};
static unsigned long gpio12_config_32k[] = {
@@ -160,31 +160,30 @@ static const struct clkops clk_pxa25x_gpio11_ops = {
* 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
* 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
*/
-static DEFINE_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
-
-static struct clk_lookup pxa25x_hwuart_clkreg =
- INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
/*
* PXA 2xx clock declarations.
*/
+static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5);
+static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0);
+
static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops);
-static DEFINE_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
-static DEFINE_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
-static DEFINE_CKEN(pxa25x_stuart, STUART, 14745600, 1);
-static DEFINE_CKEN(pxa25x_usb, USB, 47923000, 5);
static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0);
static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0);
-static DEFINE_CKEN(pxa25x_mmc, MMC, 19169000, 0);
-static DEFINE_CKEN(pxa25x_i2c, I2C, 31949000, 0);
-static DEFINE_CKEN(pxa25x_ssp, SSP, 3686400, 0);
-static DEFINE_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
-static DEFINE_CKEN(pxa25x_assp, ASSP, 3686400, 0);
-static DEFINE_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
-static DEFINE_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
-static DEFINE_CKEN(pxa25x_ac97, AC97, 24576000, 0);
-static DEFINE_CKEN(pxa25x_i2s, I2S, 14745600, 0);
-static DEFINE_CKEN(pxa25x_ficp, FICP, 47923000, 0);
+static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0);
static struct clk_lookup pxa25x_clkregs[] = {
INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL),
@@ -205,8 +204,12 @@ static struct clk_lookup pxa25x_clkregs[] = {
INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"),
INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
+ INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
};
+static struct clk_lookup pxa25x_hwuart_clkreg =
+ INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
+
#ifdef CONFIG_PM
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
@@ -219,20 +222,17 @@ static struct clk_lookup pxa25x_clkregs[] = {
*/
enum {
SLEEP_SAVE_PSTR,
- SLEEP_SAVE_CKEN,
SLEEP_SAVE_COUNT
};
static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
{
- SAVE(CKEN);
SAVE(PSTR);
}
static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
{
- RESTORE(CKEN);
RESTORE(PSTR);
}
@@ -320,6 +320,22 @@ void __init pxa26x_init_irq(void)
}
#endif
+static struct map_desc pxa25x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init pxa25x_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc));
+ pxa25x_get_clk_frequency_khz(1);
+}
+
static struct platform_device *pxa25x_devices[] __initdata = {
&pxa25x_device_udc,
&pxa_device_pmu,
@@ -339,7 +355,9 @@ static struct sys_device pxa25x_sysdev[] = {
.cls = &pxa2xx_mfp_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
- },
+ }, {
+ .cls = &pxa2xx_clock_sysclass,
+ }
};
static int __init pxa25x_init(void)
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d1fbf29d561c..b2130b7a7b52 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -17,7 +17,9 @@
#include <linux/suspend.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/irqs.h>
@@ -27,6 +29,8 @@
#include <mach/ohci.h>
#include <mach/pm.h>
#include <mach/dma.h>
+#include <mach/smemc.h>
+
#include <plat/i2c.h>
#include "generic.h"
@@ -107,10 +111,9 @@ unsigned int pxa27x_get_clk_frequency_khz(int info)
}
/*
- * Return the current mem clock frequency in units of 10kHz as
- * reflected by CCCR[A], B, and L
+ * Return the current mem clock frequency as reflected by CCCR[A], B, and L
*/
-unsigned int pxa27x_get_memclk_frequency_10khz(void)
+static unsigned long clk_pxa27x_mem_getrate(struct clk *clk)
{
unsigned long ccsr, clkcfg;
unsigned int l, L, m, M;
@@ -129,9 +132,15 @@ unsigned int pxa27x_get_memclk_frequency_10khz(void)
L = l * BASE_CLK;
M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
- return (M / 10000);
+ return M;
}
+static const struct clkops clk_pxa27x_mem_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+ .getrate = clk_pxa27x_mem_getrate,
+};
+
/*
* Return the current LCD clock frequency in units of 10kHz as
*/
@@ -157,36 +166,38 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
}
static const struct clkops clk_pxa27x_lcd_ops = {
- .enable = clk_cken_enable,
- .disable = clk_cken_disable,
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
.getrate = clk_pxa27x_lcd_getrate,
};
+static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5);
+static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0);
+static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0);
+
static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops);
static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops);
-static DEFINE_CKEN(pxa27x_ffuart, FFUART, 14857000, 1);
-static DEFINE_CKEN(pxa27x_btuart, BTUART, 14857000, 1);
-static DEFINE_CKEN(pxa27x_stuart, STUART, 14857000, 1);
-static DEFINE_CKEN(pxa27x_i2s, I2S, 14682000, 0);
-static DEFINE_CKEN(pxa27x_i2c, I2C, 32842000, 0);
-static DEFINE_CKEN(pxa27x_usb, USB, 48000000, 5);
-static DEFINE_CKEN(pxa27x_mmc, MMC, 19500000, 0);
-static DEFINE_CKEN(pxa27x_ficp, FICP, 48000000, 0);
-static DEFINE_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0);
-static DEFINE_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0);
-static DEFINE_CKEN(pxa27x_keypad, KEYPAD, 32768, 0);
-static DEFINE_CKEN(pxa27x_ssp1, SSP1, 13000000, 0);
-static DEFINE_CKEN(pxa27x_ssp2, SSP2, 13000000, 0);
-static DEFINE_CKEN(pxa27x_ssp3, SSP3, 13000000, 0);
-static DEFINE_CKEN(pxa27x_pwm0, PWM0, 13000000, 0);
-static DEFINE_CKEN(pxa27x_pwm1, PWM1, 13000000, 0);
-static DEFINE_CKEN(pxa27x_ac97, AC97, 24576000, 0);
-static DEFINE_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0);
-static DEFINE_CKEN(pxa27x_msl, MSL, 48000000, 0);
-static DEFINE_CKEN(pxa27x_usim, USIM, 48000000, 0);
-static DEFINE_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0);
-static DEFINE_CKEN(pxa27x_im, IM, 0, 0);
-static DEFINE_CKEN(pxa27x_memc, MEMC, 0, 0);
+static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0);
static struct clk_lookup pxa27x_clkregs[] = {
INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL),
@@ -215,6 +226,7 @@ static struct clk_lookup pxa27x_clkregs[] = {
INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"),
INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
+ INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
};
#ifdef CONFIG_PM
@@ -246,7 +258,6 @@ int __init pxa27x_set_pwrmode(unsigned int mode)
*/
enum {
SLEEP_SAVE_PSTR,
- SLEEP_SAVE_CKEN,
SLEEP_SAVE_MDREFR,
SLEEP_SAVE_PCFR,
SLEEP_SAVE_COUNT
@@ -254,21 +265,19 @@ enum {
void pxa27x_cpu_pm_save(unsigned long *sleep_save)
{
- SAVE(MDREFR);
+ sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR);
SAVE(PCFR);
- SAVE(CKEN);
SAVE(PSTR);
}
void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
{
- RESTORE(MDREFR);
+ __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR);
RESTORE(PCFR);
PSSR = PSSR_RDH | PSSR_PH;
- RESTORE(CKEN);
RESTORE(PSTR);
}
@@ -370,6 +379,27 @@ void __init pxa27x_init_irq(void)
pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake);
}
+static struct map_desc pxa27x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ }, { /* IMem ctl */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0x58000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init pxa27x_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc));
+ pxa27x_get_clk_frequency_khz(1);
+}
+
/*
* device registration specific to PXA27x.
*/
@@ -405,7 +435,9 @@ static struct sys_device pxa27x_sysdev[] = {
.cls = &pxa2xx_mfp_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
- },
+ }, {
+ .cls = &pxa2xx_clock_sysclass,
+ }
};
static int __init pxa27x_init(void)
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index d1c747cdacf8..e14818f5d950 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -22,6 +22,7 @@
#include <linux/io.h>
#include <linux/sysdev.h>
+#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include <mach/pxa3xx-regs.h>
@@ -30,193 +31,16 @@
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/regs-intc.h>
+#include <mach/smemc.h>
#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
#include "clock.h"
-/* Crystal clock: 13MHz */
-#define BASE_CLK 13000000
-
-/* Ring Oscillator Clock: 60MHz */
-#define RO_CLK 60000000
-
-#define ACCR_D0CS (1 << 26)
-#define ACCR_PCCE (1 << 11)
-
#define PECR_IE(n) ((1 << ((n) * 2)) << 28)
#define PECR_IS(n) ((1 << ((n) * 2)) << 29)
-/* crystal frequency to static memory controller multiplier (SMCFS) */
-static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
-
-/* crystal frequency to HSIO bus frequency multiplier (HSS) */
-static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
-
-/*
- * Get the clock frequency as reflected by CCSR and the turbo flag.
- * We assume these values have been applied via a fcs.
- * If info is not 0 we also display the current settings.
- */
-unsigned int pxa3xx_get_clk_frequency_khz(int info)
-{
- unsigned long acsr, xclkcfg;
- unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
-
- /* Read XCLKCFG register turbo bit */
- __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
- t = xclkcfg & 0x1;
-
- acsr = ACSR;
-
- xl = acsr & 0x1f;
- xn = (acsr >> 8) & 0x7;
- hss = (acsr >> 14) & 0x3;
-
- XL = xl * BASE_CLK;
- XN = xn * XL;
-
- ro = acsr & ACCR_D0CS;
-
- CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
- HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
-
- if (info) {
- pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
- RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
- (ro) ? "" : "in");
- pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
- XL / 1000000, (XL % 1000000) / 10000, xl);
- pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
- XN / 1000000, (XN % 1000000) / 10000, xn,
- (t) ? "" : "in");
- pr_info("HSIO bus clock: %d.%02dMHz\n",
- HSS / 1000000, (HSS % 1000000) / 10000);
- }
-
- return CLK / 1000;
-}
-
-void pxa3xx_clear_reset_status(unsigned int mask)
-{
- /* RESET_STATUS_* has a 1:1 mapping with ARSR */
- ARSR = mask;
-}
-
-/*
- * Return the current AC97 clock frequency.
- */
-static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk)
-{
- unsigned long rate = 312000000;
- unsigned long ac97_div;
-
- ac97_div = AC97_DIV;
-
- /* This may loose precision for some rates but won't for the
- * standard 24.576MHz.
- */
- rate /= (ac97_div >> 12) & 0x7fff;
- rate *= (ac97_div & 0xfff);
-
- return rate;
-}
-
-/*
- * Return the current HSIO bus clock frequency
- */
-static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
-{
- unsigned long acsr;
- unsigned int hss, hsio_clk;
-
- acsr = ACSR;
-
- hss = (acsr >> 14) & 0x3;
- hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
-
- return hsio_clk;
-}
-
-void clk_pxa3xx_cken_enable(struct clk *clk)
-{
- unsigned long mask = 1ul << (clk->cken & 0x1f);
-
- if (clk->cken < 32)
- CKENA |= mask;
- else
- CKENB |= mask;
-}
-
-void clk_pxa3xx_cken_disable(struct clk *clk)
-{
- unsigned long mask = 1ul << (clk->cken & 0x1f);
-
- if (clk->cken < 32)
- CKENA &= ~mask;
- else
- CKENB &= ~mask;
-}
-
-const struct clkops clk_pxa3xx_cken_ops = {
- .enable = clk_pxa3xx_cken_enable,
- .disable = clk_pxa3xx_cken_disable,
-};
-
-static const struct clkops clk_pxa3xx_hsio_ops = {
- .enable = clk_pxa3xx_cken_enable,
- .disable = clk_pxa3xx_cken_disable,
- .getrate = clk_pxa3xx_hsio_getrate,
-};
-
-static const struct clkops clk_pxa3xx_ac97_ops = {
- .enable = clk_pxa3xx_cken_enable,
- .disable = clk_pxa3xx_cken_disable,
- .getrate = clk_pxa3xx_ac97_getrate,
-};
-
-static void clk_pout_enable(struct clk *clk)
-{
- OSCC |= OSCC_PEN;
-}
-
-static void clk_pout_disable(struct clk *clk)
-{
- OSCC &= ~OSCC_PEN;
-}
-
-static const struct clkops clk_pout_ops = {
- .enable = clk_pout_enable,
- .disable = clk_pout_disable,
-};
-
-static void clk_dummy_enable(struct clk *clk)
-{
-}
-
-static void clk_dummy_disable(struct clk *clk)
-{
-}
-
-static const struct clkops clk_dummy_ops = {
- .enable = clk_dummy_enable,
- .disable = clk_dummy_disable,
-};
-
-static struct clk clk_pxa3xx_pout = {
- .ops = &clk_pout_ops,
- .rate = 13000000,
- .delay = 70,
-};
-
-static struct clk clk_dummy = {
- .ops = &clk_dummy_ops,
-};
-
-static DEFINE_PXA3_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
-static DEFINE_PXA3_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops);
-static DEFINE_PXA3_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops);
static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
@@ -234,6 +58,12 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0);
static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0);
static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0);
+static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
+static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops);
+static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops);
+static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops);
+static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70);
+
static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
/* Power I2C clock is always on */
@@ -258,6 +88,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL),
INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
};
#ifdef CONFIG_PM
@@ -268,30 +99,6 @@ static struct clk_lookup pxa3xx_clkregs[] = {
static void __iomem *sram;
static unsigned long wakeup_src;
-#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
-#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
-
-enum { SLEEP_SAVE_CKENA,
- SLEEP_SAVE_CKENB,
- SLEEP_SAVE_ACCR,
-
- SLEEP_SAVE_COUNT,
-};
-
-static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
-{
- SAVE(CKENA);
- SAVE(CKENB);
- SAVE(ACCR);
-}
-
-static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save)
-{
- RESTORE(ACCR);
- RESTORE(CKENA);
- RESTORE(CKENB);
-}
-
/*
* Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic
* memory controller has to be reinitialised, so we place some code
@@ -390,9 +197,6 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state)
}
static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
- .save_count = SLEEP_SAVE_COUNT,
- .save = pxa3xx_cpu_pm_save,
- .restore = pxa3xx_cpu_pm_restore,
.valid = pxa3xx_cpu_pm_valid,
.enter = pxa3xx_cpu_pm_enter,
};
@@ -580,6 +384,22 @@ void __init pxa3xx_init_irq(void)
pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
}
+static struct map_desc pxa3xx_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ }
+};
+
+void __init pxa3xx_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc));
+ pxa3xx_get_clk_frequency_khz(1);
+}
+
/*
* device registration specific to PXA3xx.
*/
@@ -615,7 +435,9 @@ static struct sys_device pxa3xx_sysdev[] = {
.cls = &pxa3xx_mfp_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
- },
+ }, {
+ .cls = &pxa3xx_clock_sysclass,
+ }
};
static int __init pxa3xx_init(void)
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
index 7d29dd3af79d..8aeacf908784 100644
--- a/arch/arm/mach-pxa/pxa930.c
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
static int __init pxa930_init(void)
{
- if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
+ if (cpu_is_pxa93x()) {
mfp_init_base(io_p2v(MFPR_BASE));
mfp_init_addr(pxa930_mfp_addr_map);
}
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
new file mode 100644
index 000000000000..437980f72710
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -0,0 +1,308 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa95x.c
+ *
+ * code specific to PXA95x aka MGx
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/pxa930.h>
+#include <mach/reset.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/regs-intc.h>
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+static struct mfp_addr_map pxa95x_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR(GPIO0, 0x02e0),
+ MFP_ADDR(GPIO1, 0x02dc),
+ MFP_ADDR(GPIO2, 0x02e8),
+ MFP_ADDR(GPIO3, 0x02d8),
+ MFP_ADDR(GPIO4, 0x02e4),
+ MFP_ADDR(GPIO5, 0x02ec),
+ MFP_ADDR(GPIO6, 0x02f8),
+ MFP_ADDR(GPIO7, 0x02fc),
+ MFP_ADDR(GPIO8, 0x0300),
+ MFP_ADDR(GPIO9, 0x02d4),
+ MFP_ADDR(GPIO10, 0x02f4),
+ MFP_ADDR(GPIO11, 0x02f0),
+ MFP_ADDR(GPIO12, 0x0304),
+ MFP_ADDR(GPIO13, 0x0310),
+ MFP_ADDR(GPIO14, 0x0308),
+ MFP_ADDR(GPIO15, 0x030c),
+ MFP_ADDR(GPIO16, 0x04e8),
+ MFP_ADDR(GPIO17, 0x04f4),
+ MFP_ADDR(GPIO18, 0x04f8),
+ MFP_ADDR(GPIO19, 0x04fc),
+ MFP_ADDR(GPIO20, 0x0518),
+ MFP_ADDR(GPIO21, 0x051c),
+ MFP_ADDR(GPIO22, 0x04ec),
+ MFP_ADDR(GPIO23, 0x0500),
+ MFP_ADDR(GPIO24, 0x04f0),
+ MFP_ADDR(GPIO25, 0x0504),
+ MFP_ADDR(GPIO26, 0x0510),
+ MFP_ADDR(GPIO27, 0x0514),
+ MFP_ADDR(GPIO28, 0x0520),
+ MFP_ADDR(GPIO29, 0x0600),
+ MFP_ADDR(GPIO30, 0x0618),
+ MFP_ADDR(GPIO31, 0x0610),
+ MFP_ADDR(GPIO32, 0x060c),
+ MFP_ADDR(GPIO33, 0x061c),
+ MFP_ADDR(GPIO34, 0x0620),
+ MFP_ADDR(GPIO35, 0x0628),
+ MFP_ADDR(GPIO36, 0x062c),
+ MFP_ADDR(GPIO37, 0x0630),
+ MFP_ADDR(GPIO38, 0x0634),
+ MFP_ADDR(GPIO39, 0x0638),
+ MFP_ADDR(GPIO40, 0x063c),
+ MFP_ADDR(GPIO41, 0x0614),
+ MFP_ADDR(GPIO42, 0x0624),
+ MFP_ADDR(GPIO43, 0x0608),
+ MFP_ADDR(GPIO44, 0x0604),
+ MFP_ADDR(GPIO45, 0x050c),
+ MFP_ADDR(GPIO46, 0x0508),
+ MFP_ADDR(GPIO47, 0x02bc),
+ MFP_ADDR(GPIO48, 0x02b4),
+ MFP_ADDR(GPIO49, 0x02b8),
+ MFP_ADDR(GPIO50, 0x02c8),
+ MFP_ADDR(GPIO51, 0x02c0),
+ MFP_ADDR(GPIO52, 0x02c4),
+ MFP_ADDR(GPIO53, 0x02d0),
+ MFP_ADDR(GPIO54, 0x02cc),
+ MFP_ADDR(GPIO55, 0x029c),
+ MFP_ADDR(GPIO56, 0x02a0),
+ MFP_ADDR(GPIO57, 0x0294),
+ MFP_ADDR(GPIO58, 0x0298),
+ MFP_ADDR(GPIO59, 0x02a4),
+ MFP_ADDR(GPIO60, 0x02a8),
+ MFP_ADDR(GPIO61, 0x02b0),
+ MFP_ADDR(GPIO62, 0x02ac),
+ MFP_ADDR(GPIO63, 0x0640),
+ MFP_ADDR(GPIO64, 0x065c),
+ MFP_ADDR(GPIO65, 0x0648),
+ MFP_ADDR(GPIO66, 0x0644),
+ MFP_ADDR(GPIO67, 0x0674),
+ MFP_ADDR(GPIO68, 0x0658),
+ MFP_ADDR(GPIO69, 0x0654),
+ MFP_ADDR(GPIO70, 0x0660),
+ MFP_ADDR(GPIO71, 0x0668),
+ MFP_ADDR(GPIO72, 0x0664),
+ MFP_ADDR(GPIO73, 0x0650),
+ MFP_ADDR(GPIO74, 0x066c),
+ MFP_ADDR(GPIO75, 0x064c),
+ MFP_ADDR(GPIO76, 0x0670),
+ MFP_ADDR(GPIO77, 0x0678),
+ MFP_ADDR(GPIO78, 0x067c),
+ MFP_ADDR(GPIO79, 0x0694),
+ MFP_ADDR(GPIO80, 0x069c),
+ MFP_ADDR(GPIO81, 0x06a0),
+ MFP_ADDR(GPIO82, 0x06a4),
+ MFP_ADDR(GPIO83, 0x0698),
+ MFP_ADDR(GPIO84, 0x06bc),
+ MFP_ADDR(GPIO85, 0x06b4),
+ MFP_ADDR(GPIO86, 0x06b0),
+ MFP_ADDR(GPIO87, 0x06c0),
+ MFP_ADDR(GPIO88, 0x06c4),
+ MFP_ADDR(GPIO89, 0x06ac),
+ MFP_ADDR(GPIO90, 0x0680),
+ MFP_ADDR(GPIO91, 0x0684),
+ MFP_ADDR(GPIO92, 0x0688),
+ MFP_ADDR(GPIO93, 0x0690),
+ MFP_ADDR(GPIO94, 0x068c),
+ MFP_ADDR(GPIO95, 0x06a8),
+ MFP_ADDR(GPIO96, 0x06b8),
+ MFP_ADDR(GPIO97, 0x0410),
+ MFP_ADDR(GPIO98, 0x0418),
+ MFP_ADDR(GPIO99, 0x041c),
+ MFP_ADDR(GPIO100, 0x0414),
+ MFP_ADDR(GPIO101, 0x0408),
+ MFP_ADDR(GPIO102, 0x0324),
+ MFP_ADDR(GPIO103, 0x040c),
+ MFP_ADDR(GPIO104, 0x0400),
+ MFP_ADDR(GPIO105, 0x0328),
+ MFP_ADDR(GPIO106, 0x0404),
+
+ MFP_ADDR(GPIO159, 0x0524),
+ MFP_ADDR(GPIO163, 0x0534),
+ MFP_ADDR(GPIO167, 0x0544),
+ MFP_ADDR(GPIO168, 0x0548),
+ MFP_ADDR(GPIO169, 0x054c),
+ MFP_ADDR(GPIO170, 0x0550),
+ MFP_ADDR(GPIO171, 0x0554),
+ MFP_ADDR(GPIO172, 0x0558),
+ MFP_ADDR(GPIO173, 0x055c),
+
+ MFP_ADDR(nXCVREN, 0x0204),
+ MFP_ADDR(DF_CLE_nOE, 0x020c),
+ MFP_ADDR(DF_nADV1_ALE, 0x0218),
+ MFP_ADDR(DF_SCLK_E, 0x0214),
+ MFP_ADDR(DF_SCLK_S, 0x0210),
+ MFP_ADDR(nBE0, 0x021c),
+ MFP_ADDR(nBE1, 0x0220),
+ MFP_ADDR(DF_nADV2_ALE, 0x0224),
+ MFP_ADDR(DF_INT_RnB, 0x0228),
+ MFP_ADDR(DF_nCS0, 0x022c),
+ MFP_ADDR(DF_nCS1, 0x0230),
+ MFP_ADDR(nLUA, 0x0254),
+ MFP_ADDR(nLLA, 0x0258),
+ MFP_ADDR(DF_nWE, 0x0234),
+ MFP_ADDR(DF_nRE_nOE, 0x0238),
+ MFP_ADDR(DF_ADDR0, 0x024c),
+ MFP_ADDR(DF_ADDR1, 0x0250),
+ MFP_ADDR(DF_ADDR2, 0x025c),
+ MFP_ADDR(DF_ADDR3, 0x0260),
+ MFP_ADDR(DF_IO0, 0x023c),
+ MFP_ADDR(DF_IO1, 0x0240),
+ MFP_ADDR(DF_IO2, 0x0244),
+ MFP_ADDR(DF_IO3, 0x0248),
+ MFP_ADDR(DF_IO4, 0x0264),
+ MFP_ADDR(DF_IO5, 0x0268),
+ MFP_ADDR(DF_IO6, 0x026c),
+ MFP_ADDR(DF_IO7, 0x0270),
+ MFP_ADDR(DF_IO8, 0x0274),
+ MFP_ADDR(DF_IO9, 0x0278),
+ MFP_ADDR(DF_IO10, 0x027c),
+ MFP_ADDR(DF_IO11, 0x0280),
+ MFP_ADDR(DF_IO12, 0x0284),
+ MFP_ADDR(DF_IO13, 0x0288),
+ MFP_ADDR(DF_IO14, 0x028c),
+ MFP_ADDR(DF_IO15, 0x0290),
+
+ MFP_ADDR(GSIM_UIO, 0x0314),
+ MFP_ADDR(GSIM_UCLK, 0x0318),
+ MFP_ADDR(GSIM_UDET, 0x031c),
+ MFP_ADDR(GSIM_nURST, 0x0320),
+
+ MFP_ADDR(PMIC_INT, 0x06c8),
+
+ MFP_ADDR(RDY, 0x0200),
+
+ MFP_ADDR_END,
+};
+
+static DEFINE_CK(pxa95x_lcd, LCD, &clk_pxa3xx_hsio_ops);
+static DEFINE_CLK(pxa95x_pout, &clk_pxa3xx_pout_ops, 13000000, 70);
+static DEFINE_PXA3_CKEN(pxa95x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0);
+
+static struct clk_lookup pxa95x_clkregs[] = {
+ INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
+ /* Power I2C clock is always on */
+ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
+ INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-ir", "UARTCLK"),
+ INIT_CLKREG(&clk_pxa95x_i2c, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_keypad, "pxa27x-keypad", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp1, "pxa27x-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp2, "pxa27x-ssp.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp3, "pxa27x-ssp.2", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL),
+ INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
+};
+
+void __init pxa95x_init_irq(void)
+{
+ pxa_init_irq(96, NULL);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
+}
+
+/*
+ * device registration specific to PXA93x.
+ */
+
+void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+ &sa1100_device_rtc,
+ &pxa_device_rtc,
+ &pxa27x_device_ssp1,
+ &pxa27x_device_ssp2,
+ &pxa27x_device_ssp3,
+ &pxa3xx_device_ssp4,
+ &pxa27x_device_pwm0,
+ &pxa27x_device_pwm1,
+};
+
+static struct sys_device pxa95x_sysdev[] = {
+ {
+ .cls = &pxa_irq_sysclass,
+ }, {
+ .cls = &pxa_gpio_sysclass,
+ }, {
+ .cls = &pxa3xx_clock_sysclass,
+ }
+};
+
+static int __init pxa95x_init(void)
+{
+ int ret = 0, i;
+
+ if (cpu_is_pxa95x()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa95x_mfp_addr_map);
+
+ reset_status = ARSR;
+
+ /*
+ * clear RDH bit every time after reset
+ *
+ * Note: the last 3 bits DxS are write-1-to-clear so carefully
+ * preserve them here in case they will be referenced later
+ */
+ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+
+ clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs));
+
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(pxa95x_sysdev); i++) {
+ ret = sysdev_register(&pxa95x_sysdev[i]);
+ if (ret)
+ pr_err("failed to register sysdev[%d]\n", i);
+ }
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+postcore_initcall(pxa95x_init);
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 4121d03ea2c3..8361151be054 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -588,6 +588,9 @@ static struct pxafb_mach_info raumfeld_sharp_lcd_info = {
.num_modes = 1,
.video_mem_size = 0x400000,
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+#ifdef CONFIG_PXA3XX_GCU
+ .acceleration_enabled = 1,
+#endif
};
static void __init raumfeld_lcd_init(void)
@@ -616,6 +619,8 @@ static void __init raumfeld_lcd_init(void)
pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n");
else
gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
+
+ platform_device_register(&pxa3xx_device_gcu);
}
/**
@@ -1085,7 +1090,7 @@ static void __init raumfeld_speaker_init(void)
MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_controller_init,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
MACHINE_END
@@ -1095,7 +1100,7 @@ MACHINE_END
MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_connector_init,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
MACHINE_END
@@ -1105,7 +1110,7 @@ MACHINE_END
MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
.boot_params = RAUMFELD_SDRAM_BASE + 0x100,
.init_machine = raumfeld_speaker_init,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index ffa50e633ee6..c1ca8cb467fc 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -597,7 +597,7 @@ static void __init saar_init(void)
MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = saar_init,
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
new file mode 100644
index 000000000000..e497922f761a
--- /dev/null
+++ b/arch/arm/mach-pxa/saarb.c
@@ -0,0 +1,114 @@
+/*
+ * linux/arch/arm/mach-pxa/saarb.c
+ *
+ * Support for the Marvell Handheld Platform (aka SAARB)
+ *
+ * Copyright (C) 2007-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/i2c.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/mfp-pxa930.h>
+#include <mach/gpio.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+
+#define SAARB_NR_IRQS (IRQ_BOARD_START + 40)
+
+static struct pm860x_touch_pdata saarb_touch = {
+ .gpadc_prebias = 1,
+ .slot_cycle = 1,
+ .tsi_prebias = 6,
+ .pen_prebias = 16,
+ .pen_prechg = 2,
+ .res_x = 300,
+};
+
+static struct pm860x_backlight_pdata saarb_backlight[] = {
+ {
+ .id = PM8606_ID_BACKLIGHT,
+ .iset = PM8606_WLED_CURRENT(24),
+ .flags = PM8606_BACKLIGHT1,
+ },
+ {},
+};
+
+static struct pm860x_led_pdata saarb_led[] = {
+ {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_BLUE,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_BLUE,
+ },
+};
+
+static struct pm860x_platform_data saarb_pm8607_info = {
+ .touch = &saarb_touch,
+ .backlight = &saarb_backlight[0],
+ .led = &saarb_led[0],
+ .companion_addr = 0x10,
+ .irq_mode = 0,
+ .irq_base = IRQ_BOARD_START,
+
+ .i2c_port = GI2C_PORT,
+};
+
+static struct i2c_board_info saarb_i2c_info[] = {
+ {
+ .type = "88PM860x",
+ .addr = 0x34,
+ .platform_data = &saarb_pm8607_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+ },
+};
+
+static void __init saarb_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(saarb_i2c_info));
+}
+
+MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .nr_irqs = SAARB_NR_IRQS,
+ .init_irq = pxa95x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = saarb_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 52c30b01a671..c551da86baf6 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -14,7 +14,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>
-
+#include <mach/smemc.h>
#include <mach/pxa2xx-regs.h>
#define MDREFR_KDIV 0x200a4000 // all banks
@@ -353,8 +353,8 @@ resume_turn_on_mmu:
@ Let us ensure we jump to resume_after_mmu only when the mcr above
@ actually took effect. They call it the "cpwait" operation.
- mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15
- sub pc, r2, r1, lsr #32 @ jump to virtual addr
+ mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
+ sub pc, r2, r0, lsr #32 @ jump to virtual addr
nop
nop
nop
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
index d6f6904132a6..232b7316ec08 100644
--- a/arch/arm/mach-pxa/smemc.c
+++ b/arch/arm/mach-pxa/smemc.c
@@ -9,50 +9,37 @@
#include <linux/sysdev.h>
#include <mach/hardware.h>
-
-#define SMEMC_PHYS_BASE (0x4A000000)
-#define SMEMC_PHYS_SIZE (0x90)
-
-#define MSC0 (0x08) /* Static Memory Controller Register 0 */
-#define MSC1 (0x0C) /* Static Memory Controller Register 1 */
-#define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */
-#define MEMCLKCFG (0x68) /* Clock Configuration */
-#define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */
-#define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */
-#define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */
-#define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */
+#include <mach/smemc.h>
#ifdef CONFIG_PM
-static void __iomem *smemc_mmio_base;
-
static unsigned long msc[2];
static unsigned long sxcnfg, memclkcfg;
static unsigned long csadrcfg[4];
static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state)
{
- msc[0] = __raw_readl(smemc_mmio_base + MSC0);
- msc[1] = __raw_readl(smemc_mmio_base + MSC1);
- sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG);
- memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG);
- csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0);
- csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1);
- csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2);
- csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3);
+ msc[0] = __raw_readl(MSC0);
+ msc[1] = __raw_readl(MSC1);
+ sxcnfg = __raw_readl(SXCNFG);
+ memclkcfg = __raw_readl(MEMCLKCFG);
+ csadrcfg[0] = __raw_readl(CSADRCFG0);
+ csadrcfg[1] = __raw_readl(CSADRCFG1);
+ csadrcfg[2] = __raw_readl(CSADRCFG2);
+ csadrcfg[3] = __raw_readl(CSADRCFG3);
return 0;
}
static int pxa3xx_smemc_resume(struct sys_device *dev)
{
- __raw_writel(msc[0], smemc_mmio_base + MSC0);
- __raw_writel(msc[1], smemc_mmio_base + MSC1);
- __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG);
- __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG);
- __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0);
- __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1);
- __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2);
- __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3);
+ __raw_writel(msc[0], MSC0);
+ __raw_writel(msc[1], MSC1);
+ __raw_writel(sxcnfg, SXCNFG);
+ __raw_writel(memclkcfg, MEMCLKCFG);
+ __raw_writel(csadrcfg[0], CSADRCFG0);
+ __raw_writel(csadrcfg[1], CSADRCFG1);
+ __raw_writel(csadrcfg[2], CSADRCFG2);
+ __raw_writel(csadrcfg[3], CSADRCFG3);
return 0;
}
@@ -73,10 +60,6 @@ static int __init smemc_init(void)
int ret = 0;
if (cpu_is_pxa3xx()) {
- smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE);
- if (smemc_mmio_base == NULL)
- return -ENODEV;
-
ret = sysdev_class_register(&smemc_sysclass);
if (ret)
return ret;
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index f736119f1ebf..0499a69e7673 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -27,6 +27,7 @@
#include <linux/mtd/sharpsl.h>
#include <linux/input/matrix_keypad.h>
#include <linux/regulator/machine.h>
+#include <linux/io.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -44,6 +45,7 @@
#include <mach/pxa2xx_spi.h>
#include <mach/spitz.h>
#include <mach/sharpsl_pm.h>
+#include <mach/smemc.h>
#include <plat/i2c.h>
@@ -929,9 +931,10 @@ static void spitz_poweroff(void)
static void spitz_restart(char mode, const char *cmd)
{
+ uint32_t msc0 = __raw_readl(MSC0);
/* Bootloader magic for a reboot */
- if ((MSC0 & 0xffff0000) == 0x7ff00000)
- MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
+ if ((msc0 & 0xffff0000) == 0x7ff00000)
+ __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);
spitz_poweroff();
}
@@ -980,7 +983,7 @@ static void __init spitz_fixup(struct machine_desc *desc,
#ifdef CONFIG_MACH_SPITZ
MACHINE_START(SPITZ, "SHARP Spitz")
.fixup = spitz_fixup,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = spitz_init,
.timer = &pxa_timer,
@@ -990,7 +993,7 @@ MACHINE_END
#ifdef CONFIG_MACH_BORZOI
MACHINE_START(BORZOI, "SHARP Borzoi")
.fixup = spitz_fixup,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = spitz_init,
.timer = &pxa_timer,
@@ -1000,7 +1003,7 @@ MACHINE_END
#ifdef CONFIG_MACH_AKITA
MACHINE_START(AKITA, "SHARP Akita")
.fixup = spitz_fixup,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = spitz_init,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 738adc1773fd..3498a1423943 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -48,6 +48,7 @@
#include <mach/udc.h>
#include <mach/pxa2xx_spi.h>
#include <mach/pxa27x-udc.h>
+#include <mach/smemc.h>
#include <linux/spi/spi.h>
#include <linux/mfd/da903x.h>
@@ -976,7 +977,7 @@ static void __init stargate2_init(void)
{
/* This is probably a board specific hack as this must be set
prior to connecting the MFP stuff up. */
- MECR &= ~MECR_NOS;
+ __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR);
pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
@@ -998,7 +999,7 @@ static void __init stargate2_init(void)
#ifdef CONFIG_MACH_INTELMOTE2
MACHINE_START(INTELMOTE2, "IMOTE 2")
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = imote2_init,
@@ -1008,7 +1009,7 @@ MACHINE_END
#ifdef CONFIG_MACH_STARGATE2
MACHINE_START(STARGATE2, "Stargate 2")
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.nr_irqs = STARGATE_NR_IRQS,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 2ea7545273ad..9cecf8366db8 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -490,7 +490,7 @@ static void __init tavorevb_init(void)
MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = tavorevb_init,
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c
index dc3011697bbf..70191a9450eb 100644
--- a/arch/arm/mach-pxa/tavorevb3.c
+++ b/arch/arm/mach-pxa/tavorevb3.c
@@ -127,7 +127,7 @@ static void __init evb3_init(void)
MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.nr_irqs = TAVOREVB3_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 293e40aeaf29..e7f64d9b4f2d 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -17,11 +17,11 @@
#include <linux/interrupt.h>
#include <linux/clockchips.h>
#include <linux/sched.h>
-#include <linux/cnt32_to_63.h>
#include <asm/div64.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
#include <mach/regs-ost.h>
/*
@@ -32,29 +32,18 @@
* long as there is always less than 582 seconds between successive
* calls to sched_clock() which should always be the case in practice.
*/
+static DEFINE_CLOCK_DATA(cd);
-#define OSCR2NS_SCALE_FACTOR 10
-
-static unsigned long oscr2ns_scale;
-
-static void __init set_oscr2ns_scale(unsigned long oscr_rate)
+unsigned long long notrace sched_clock(void)
{
- unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
- do_div(v, oscr_rate);
- oscr2ns_scale = v;
- /*
- * We want an even value to automatically clear the top bit
- * returned by cnt32_to_63() without an additional run time
- * instruction. So if the LSB is 1 then round it up.
- */
- if (oscr2ns_scale & 1)
- oscr2ns_scale++;
+ u32 cyc = OSCR;
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
}
-unsigned long long sched_clock(void)
+static void notrace pxa_update_sched_clock(void)
{
- unsigned long long v = cnt32_to_63(OSCR);
- return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
+ u32 cyc = OSCR;
+ update_sched_clock(&cd, cyc, (u32)~0);
}
@@ -127,7 +116,6 @@ static struct clocksource cksrc_pxa_oscr0 = {
.rating = 200,
.read = pxa_read_oscr,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -145,7 +133,7 @@ static void __init pxa_timer_init(void)
OIER = 0;
OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
- set_oscr2ns_scale(clock_tick_rate);
+ init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
ckevt_pxa_osmr0.mult =
div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
@@ -155,12 +143,9 @@ static void __init pxa_timer_init(void)
clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
ckevt_pxa_osmr0.cpumask = cpumask_of(0);
- cksrc_pxa_oscr0.mult =
- clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
-
setup_irq(IRQ_OST0, &pxa_ost0_irq);
- clocksource_register(&cksrc_pxa_oscr0);
+ clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate);
clockevents_register_device(&ckevt_pxa_osmr0);
}
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 0ee1df49606d..57d61ee9b226 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -46,6 +46,7 @@
#include <mach/tosa_bt.h>
#include <mach/pxa2xx_spi.h>
#include <mach/audio.h>
+#include <mach/smemc.h>
#include <asm/mach/arch.h>
#include <mach/tosa.h>
@@ -893,9 +894,11 @@ static void tosa_poweroff(void)
static void tosa_restart(char mode, const char *cmd)
{
+ uint32_t msc0 = __raw_readl(MSC0);
+
/* Bootloader magic for a reboot */
- if((MSC0 & 0xffff0000) == 0x7ff00000)
- MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
+ if((msc0 & 0xffff0000) == 0x7ff00000)
+ __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);
tosa_poweroff();
}
@@ -953,7 +956,7 @@ static void __init fixup_tosa(struct machine_desc *desc,
MACHINE_START(TOSA, "SHARP Tosa")
.fixup = fixup_tosa,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.nr_irqs = TOSA_NR_IRQS,
.init_irq = pxa25x_init_irq,
.init_machine = tosa_init,
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 565d062f51d5..43fc9ca14594 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -47,6 +47,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
+#include <mach/smemc.h>
#include <plat/i2c.h>
#include "generic.h"
@@ -539,10 +540,10 @@ static void __init trizeps4_init(void)
static void __init trizeps4_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
- if ((MSC0 & 0x8) && (BOOT_DEF & 0x1)) {
+ if ((__raw_readl(MSC0) & 0x8) && (__raw_readl(BOOT_DEF) & 0x1)) {
/* if flash is 16 bit wide its a Trizeps4 WL */
__machine_arch_type = MACH_TYPE_TRIZEPS4WL;
trizeps4_flash_data[0].width = 2;
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 438fc9a5ed59..de69b203afa7 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -983,7 +983,7 @@ static struct map_desc viper_io_desc[] __initdata = {
static void __init viper_map_io(void)
{
- pxa_map_io();
+ pxa25x_map_io();
iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc));
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index f45ac0961778..b9b579715ff6 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -719,7 +719,7 @@ static void __init vpac270_init(void)
MACHINE_START(VPAC270, "Voipac PXA270")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = vpac270_init
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
index 3260ce73d327..51c0281c6e0a 100644
--- a/arch/arm/mach-pxa/xcep.c
+++ b/arch/arm/mach-pxa/xcep.c
@@ -31,6 +31,7 @@
#include <mach/hardware.h>
#include <mach/pxa2xx-regs.h>
#include <mach/mfp-pxa25x.h>
+#include <mach/smemc.h>
#include "generic.h"
@@ -172,9 +173,9 @@ static void __init xcep_init(void)
/* See Intel XScale Developer's Guide for details */
/* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */
- MSC1 = (MSC1 & 0xffff) | 0xD5540000;
+ __raw_writel((__raw_readl(MSC1) & 0xffff) | 0xD5540000, MSC1);
/* Set RDF and RDN to appropriate values (chip select 5 (fpga)) */
- MSC2 = (MSC2 & 0xffff) | 0x72A00000;
+ __raw_writel((__raw_readl(MSC2) & 0xffff) | 0x72A00000, MSC2);
platform_add_devices(ARRAY_AND_SIZE(devices));
pxa_set_i2c_info(&xcep_i2c_platform_data);
@@ -183,7 +184,7 @@ static void __init xcep_init(void)
MACHINE_START(XCEP, "Iskratel XCEP")
.boot_params = 0xa0000100,
.init_machine = xcep_init,
- .map_io = pxa_map_io,
+ .map_io = pxa25x_map_io,
.init_irq = pxa25x_init_irq,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index fefde9848d82..527c2a1ed310 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -704,7 +704,7 @@ static void __init z2_init(void)
MACHINE_START(ZIPIT2, "Zipit Z2")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa27x_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = z2_init,
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index dea46a2d089b..c87f2b35ee05 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -47,6 +47,7 @@
#include <mach/audio.h>
#include <mach/arcom-pcmcia.h>
#include <mach/zeus.h>
+#include <mach/smemc.h>
#include "generic.h"
@@ -823,13 +824,16 @@ static mfp_cfg_t zeus_pin_config[] __initdata = {
static void __init zeus_init(void)
{
u16 dm9000_msc = DM9K_MSC_VALUE;
+ u32 msc0, msc1;
system_rev = __raw_readw(ZEUS_CPLD_VERSION);
pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f));
/* Fix timings for dm9000s (CS1/CS2)*/
- MSC0 = (MSC0 & 0xffff) | (dm9000_msc << 16);
- MSC1 = (MSC1 & 0xffff0000) | dm9000_msc;
+ msc0 = __raw_readl(MSC0) & 0x0000ffff | (dm9000_msc << 16);
+ msc1 = __raw_readl(MSC1) & 0xffff0000 | dm9000_msc;
+ __raw_writel(msc0, MSC0);
+ __raw_writel(msc1, MSC1);
pm_power_off = zeus_power_off;
zeus_setup_apm();
@@ -883,7 +887,7 @@ static struct map_desc zeus_io_desc[] __initdata = {
static void __init zeus_map_io(void)
{
- pxa_map_io();
+ pxa27x_map_io();
iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc));
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 702f7a68e87d..a4c784aab764 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -423,7 +423,7 @@ static void __init zylonite_init(void)
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
.boot_params = 0xa0000100,
- .map_io = pxa_map_io,
+ .map_io = pxa3xx_map_io,
.nr_irqs = ZYLONITE_NR_IRQS,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 07c08151dfe6..1c6602cf50e4 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -30,8 +30,8 @@
#include <linux/ata_platform.h>
#include <linux/amba/mmci.h>
#include <linux/gfp.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -47,15 +47,13 @@
#include <asm/hardware/gic.h>
-#include <mach/clkdev.h>
#include <mach/platform.h>
#include <mach/irqs.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
-#include "core.h"
+#include <plat/sched_clock.h>
-/* used by entry-macro.S and platsmp.c */
-void __iomem *gic_cpu_base_addr;
+#include "core.h"
#ifdef CONFIG_ZONE_DMA
/*
@@ -658,6 +656,12 @@ void realview_leds_event(led_event_t ledevt)
#endif /* CONFIG_LEDS */
/*
+ * The sched_clock counter
+ */
+#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
+ REALVIEW_SYS_24MHz_OFFSET)
+
+/*
* Where is the timer (VA)?
*/
void __iomem *timer0_va_base;
@@ -672,6 +676,8 @@ void __init realview_timer_init(unsigned int timer_irq)
{
u32 val;
+ versatile_sched_clock_init(REFCOUNTER, 24000000);
+
/*
* set clock frequency:
* REALVIEW_REFCLK is 32KHz
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 781bca68a9fa..693239ddc39e 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -53,7 +53,6 @@ extern struct platform_device realview_i2c_device;
extern struct mmci_platform_data realview_mmc0_plat_data;
extern struct mmci_platform_data realview_mmc1_plat_data;
extern struct clcd_board clcd_plat_data;
-extern void __iomem *gic_cpu_base_addr;
extern void __iomem *timer0_va_base;
extern void __iomem *timer1_va_base;
extern void __iomem *timer2_va_base;
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S
index 4075473cf68a..b34be4554d40 100644
--- a/arch/arm/mach-realview/headsmp.S
+++ b/arch/arm/mach-realview/headsmp.S
@@ -35,5 +35,6 @@ pen: ldr r7, [r6]
*/
b secondary_startup
+ .align
1: .long .
.long pen_release
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index f95521a5e5ce..a87523d095e6 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -11,14 +11,11 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/completion.h>
#include <asm/cacheflush.h>
extern volatile int pen_release;
-static DECLARE_COMPLETION(cpu_killed);
-
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
@@ -34,10 +31,10 @@ static inline void cpu_enter_lowpower(void)
" bic %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n"
- " bic %0, %0, #0x04\n"
+ " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
- : "r" (0)
+ : "r" (0), "Ir" (CR_C)
: "cc");
}
@@ -46,17 +43,17 @@ static inline void cpu_leave_lowpower(void)
unsigned int v;
asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
- " orr %0, %0, #0x04\n"
+ " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
- :
+ : "Ir" (CR_C)
: "cc");
}
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{
/*
* there is no power-control hardware on this platform, so all
@@ -80,22 +77,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
}
/*
- * getting here, means that we have come out of WFI without
+ * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
- * The trouble is, letting people know about this is not really
- * possible, since we are currently running incoherently, and
- * therefore cannot safely call printk() or anything else
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
*/
-#ifdef DEBUG
- printk("CPU%u: spurious wakeup call\n", cpu);
-#endif
+ (*spurious)++;
}
}
int platform_cpu_kill(unsigned int cpu)
{
- return wait_for_completion_timeout(&cpu_killed, 5000);
+ return 1;
}
/*
@@ -105,30 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
-#ifdef DEBUG
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
-#endif
-
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
+ int spurious = 0;
/*
* we're ready for shutdown now, so do it
*/
cpu_enter_lowpower();
- platform_do_lowpower(cpu);
+ platform_do_lowpower(cpu, &spurious);
/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-realview/include/mach/entry-macro.S b/arch/arm/mach-realview/include/mach/entry-macro.S
index 340a5c276946..4071164aebaa 100644
--- a/arch/arm/mach-realview/include/mach/entry-macro.S
+++ b/arch/arm/mach-realview/include/mach/entry-macro.S
@@ -8,74 +8,11 @@
* warranty of any kind, whether express or implied.
*/
#include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =gic_cpu_base_addr
- ldr \base, [\base]
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an interrupt if it's
- * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
- *
- * A simple read from the controller will tell us the number of the highest
- * priority enabled interrupt. We then just need to check whether it is in the
- * valid range for an IRQ (30-1020 inclusive).
- */
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
- ldr \tmp, =1021
-
- bic \irqnr, \irqstat, #0x1c00
-
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
-
- .endm
-
- /* We assume that irqstat (the raw value of the IRQ acknowledge
- * register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of interrupt on the
- * controller, since this requires the original irqstat value which
- * we won't easily be able to recreate later.
- */
-
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base are preserved.. */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index d3cd265cb058..c8221b38ee7c 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -2,14 +2,13 @@
#define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 009265818d55..a22bf67f2f78 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -19,7 +19,6 @@
#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
-#include <asm/localtimer.h>
#include <asm/unified.h>
#include <mach/board-eb.h>
@@ -37,6 +36,19 @@ extern void realview_secondary_startup(void);
*/
volatile int __cpuinitdata pen_release = -1;
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
static void __iomem *scu_base_addr(void)
{
if (machine_is_realview_eb_mp())
@@ -50,33 +62,22 @@ static void __iomem *scu_base_addr(void)
return (void __iomem *)0;
}
-static inline unsigned int get_core_count(void)
-{
- void __iomem *scu_base = scu_base_addr();
- if (scu_base)
- return scu_get_core_count(scu_base);
- return 1;
-}
-
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
- pen_release = -1;
- smp_wmb();
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
@@ -103,20 +104,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
- pen_release = cpu;
- flush_cache_all();
+ write_pen_release(cpu);
/*
- * XXX
- *
- * This is a later addition to the booting protocol: the
- * bootMonitor now puts secondary cores into WFI, so
- * poke_milo() no longer gets the cores moving; we need
- * to send a soft interrupt to wake the secondary core.
- * Use smp_cross_call() for this, since there's little
- * point duplicating the code here
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
*/
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -136,48 +131,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0;
}
-static void __init poke_milo(void)
-{
- /* nobody is to be released from the pen yet */
- pen_release = -1;
-
- /*
- * Write the address of secondary startup into the system-wide flags
- * register. The BootMonitor waits for this register to become
- * non-zero.
- */
- __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
- __io_address(REALVIEW_SYS_FLAGSSET));
-
- mb();
-}
-
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
void __init smp_init_cpus(void)
{
- unsigned int i, ncores = get_core_count();
+ void __iomem *scu_base = scu_base_addr();
+ unsigned int i, ncores;
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-void __init smp_prepare_cpus(unsigned int max_cpus)
-{
- unsigned int ncores = get_core_count();
- unsigned int cpu = smp_processor_id();
- int i;
+ ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "Realview: strange CM count of 0? Default to 1\n");
-
- ncores = 1;
- }
-
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"Realview: no. of cores (%d) greater than configured "
@@ -186,13 +151,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
ncores = NR_CPUS;
}
- smp_store_cpu_info(cpu);
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
- /*
- * are we trying to boot more cores than exist?
- */
- if (max_cpus > ncores)
- max_cpus = ncores;
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
/*
* Initialise the present map, which describes the set of CPUs
@@ -201,21 +166,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
+ scu_enable(scu_base_addr());
+
/*
- * Initialise the SCU if there are more than one CPU and let
- * them know where to start. Note that, on modern versions of
- * MILO, the "poke" doesn't actually do anything until each
- * individual core is sent a soft interrupt to get it out of
- * WFI
+ * Write the address of secondary startup into the
+ * system-wide flags register. The BootMonitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
*/
- if (max_cpus > 1) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
-
- scu_enable(scu_base_addr());
- poke_milo();
- }
+ __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
+ __io_address(REALVIEW_SYS_FLAGSSET));
}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index f2697106f809..6ef5c5e528b2 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -364,21 +364,19 @@ static void __init gic_init_irq(void)
writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
/* core tile GIC, primary */
- gic_cpu_base_addr = __io_address(REALVIEW_EB11MP_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), 29);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
/* board GIC, secondary */
- gic_dist_init(1, __io_address(REALVIEW_EB_GIC_DIST_BASE), 64);
- gic_cpu_init(1, __io_address(REALVIEW_EB_GIC_CPU_BASE));
+ gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB_GIC_CPU_BASE));
gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
#endif
} else {
/* board GIC, primary */
- gic_cpu_base_addr = __io_address(REALVIEW_EB_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_EB_GIC_DIST_BASE), 29);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB_GIC_CPU_BASE));
}
}
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index a4125619d71b..cbdc97a5685f 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -304,13 +304,14 @@ static struct platform_device char_lcd_device = {
static void __init gic_init_irq(void)
{
/* ARM1176 DevChip GIC, primary */
- gic_cpu_base_addr = __io_address(REALVIEW_DC1176_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_DC1176_GIC_DIST_BASE), IRQ_DC1176_GIC_START);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, IRQ_DC1176_GIC_START,
+ __io_address(REALVIEW_DC1176_GIC_DIST_BASE),
+ __io_address(REALVIEW_DC1176_GIC_CPU_BASE));
/* board GIC, secondary */
- gic_dist_init(1, __io_address(REALVIEW_PB1176_GIC_DIST_BASE), IRQ_PB1176_GIC_START);
- gic_cpu_init(1, __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
+ gic_init(1, IRQ_PB1176_GIC_START,
+ __io_address(REALVIEW_PB1176_GIC_DIST_BASE),
+ __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1);
}
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 117b95b2ca15..8e8ab7d29a6a 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -309,13 +309,13 @@ static void __init gic_init_irq(void)
writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
/* ARM11MPCore test chip GIC, primary */
- gic_cpu_base_addr = __io_address(REALVIEW_TC11MP_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE), 29);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, 29, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_TC11MP_GIC_CPU_BASE));
/* board GIC, secondary */
- gic_dist_init(1, __io_address(REALVIEW_PB11MP_GIC_DIST_BASE), IRQ_PB11MP_GIC_START);
- gic_cpu_init(1, __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
+ gic_init(1, IRQ_PB11MP_GIC_START,
+ __io_address(REALVIEW_PB11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
}
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 929b8dc12e81..841118e3e118 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -273,9 +273,9 @@ static struct platform_device pmu_device = {
static void __init gic_init_irq(void)
{
/* ARM PB-A8 on-board GIC */
- gic_cpu_base_addr = __io_address(REALVIEW_PBA8_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_PBA8_GIC_DIST_BASE), IRQ_PBA8_GIC_START);
- gic_cpu_init(0, __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
+ gic_init(0, IRQ_PBA8_GIC_START,
+ __io_address(REALVIEW_PBA8_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
}
static void __init realview_pba8_timer_init(void)
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index b9f9e20031a7..02b755b009db 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -313,15 +313,12 @@ static void __init gic_init_irq(void)
{
/* ARM PBX on-board GIC */
if (core_tile_pbx11mp() || core_tile_pbxa9mp()) {
- gic_cpu_base_addr = __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
- 29);
- gic_cpu_init(0, __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
+ gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
} else {
- gic_cpu_base_addr = __io_address(REALVIEW_PBX_GIC_CPU_BASE);
- gic_dist_init(0, __io_address(REALVIEW_PBX_GIC_DIST_BASE),
- IRQ_PBX_GIC_START);
- gic_cpu_init(0, __io_address(REALVIEW_PBX_GIC_CPU_BASE));
+ gic_init(0, IRQ_PBX_GIC_START,
+ __io_address(REALVIEW_PBX_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBX_GIC_CPU_BASE));
}
}
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 217b102866d0..606cb6b1cc47 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -75,38 +75,38 @@ static unsigned char bast_pc104_irqmasks[] = {
static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
static void
-bast_pc104_mask(unsigned int irqno)
+bast_pc104_mask(struct irq_data *data)
{
unsigned long temp;
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
- temp &= ~bast_pc104_irqmasks[irqno];
+ temp &= ~bast_pc104_irqmasks[data->irq];
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}
static void
-bast_pc104_maskack(unsigned int irqno)
+bast_pc104_maskack(struct irq_data *data)
{
struct irq_desc *desc = irq_desc + IRQ_ISA;
- bast_pc104_mask(irqno);
- desc->chip->ack(IRQ_ISA);
+ bast_pc104_mask(data);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
}
static void
-bast_pc104_unmask(unsigned int irqno)
+bast_pc104_unmask(struct irq_data *data)
{
unsigned long temp;
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
- temp |= bast_pc104_irqmasks[irqno];
+ temp |= bast_pc104_irqmasks[data->irq];
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}
static struct irq_chip bast_pc104_chip = {
- .mask = bast_pc104_mask,
- .unmask = bast_pc104_unmask,
- .ack = bast_pc104_maskack
+ .irq_mask = bast_pc104_mask,
+ .irq_unmask = bast_pc104_unmask,
+ .irq_ack = bast_pc104_maskack
};
static void
@@ -123,7 +123,7 @@ bast_irq_pc104_demux(unsigned int irq,
/* ack if we get an irq with nothing (ie, startup) */
desc = irq_desc + IRQ_ISA;
- desc->chip->ack(IRQ_ISA);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
} else {
/* handle the IRQ */
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index d7ada8c7e41f..1a81fe12ccd7 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -387,7 +387,7 @@ static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c_device_usbgadget,
&h1940_device_leds,
&h1940_device_bluetooth,
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index cef6a65637bd..e82ab4aa7ab9 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -16,7 +16,7 @@ config CPU_S3C2412
config CPU_S3C2412_ONLY
bool
depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
- !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+ !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
!CPU_S3C2443 && CPU_S3C2412
default y if CPU_S3C2412
@@ -28,9 +28,16 @@ config S3C2412_DMA
config S3C2412_PM
bool
+ select S3C2412_PM_SLEEP
help
Internal config node to apply S3C2412 power management
+config S3C2412_PM_SLEEP
+ bool
+ help
+ Internal config node to apply sleep for S3C2412 power management.
+ Can be selected by another SoCs with similar sleep procedure.
+
# Note, the S3C2412 IOtiming support is in plat-s3c24xx
config S3C2412_CPUFREQ
@@ -52,7 +59,7 @@ config MACH_JIVE
Say Y here if you are using the Logitech Jive.
config MACH_JIVE_SHOW_BOOTLOADER
- bool "Allow access to bootloader partitions in MTD"
+ bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
depends on MACH_JIVE && EXPERIMENTAL
config MACH_SMDK2413
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index 530ec46cbaea..6c48a91ea39e 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o
obj-$(CONFIG_CPU_S3C2412) += clock.o
obj-$(CONFIG_CPU_S3C2412) += gpio.o
obj-$(CONFIG_S3C2412_DMA) += dma.o
-obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
+obj-$(CONFIG_S3C2412_PM) += pm.o
+obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
# Machine support
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index 6000ca9d1815..eddb52ba5b65 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -49,9 +49,9 @@
*/
static void
-s3c2412_irq_mask(unsigned int irqno)
+s3c2412_irq_mask(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
@@ -62,9 +62,9 @@ s3c2412_irq_mask(unsigned int irqno)
}
static inline void
-s3c2412_irq_ack(unsigned int irqno)
+s3c2412_irq_ack(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
__raw_writel(bitval, S3C2412_EINTPEND);
__raw_writel(bitval, S3C2410_SRCPND);
@@ -72,9 +72,9 @@ s3c2412_irq_ack(unsigned int irqno)
}
static inline void
-s3c2412_irq_maskack(unsigned int irqno)
+s3c2412_irq_maskack(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
@@ -89,9 +89,9 @@ s3c2412_irq_maskack(unsigned int irqno)
}
static void
-s3c2412_irq_unmask(unsigned int irqno)
+s3c2412_irq_unmask(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2412_EINTMASK);
@@ -102,11 +102,11 @@ s3c2412_irq_unmask(unsigned int irqno)
}
static struct irq_chip s3c2412_irq_eint0t4 = {
- .ack = s3c2412_irq_ack,
- .mask = s3c2412_irq_mask,
- .unmask = s3c2412_irq_unmask,
- .set_wake = s3c_irq_wake,
- .set_type = s3c_irqext_type,
+ .irq_ack = s3c2412_irq_ack,
+ .irq_mask = s3c2412_irq_mask,
+ .irq_unmask = s3c2412_irq_unmask,
+ .irq_set_wake = s3c_irq_wake,
+ .irq_set_type = s3c_irqext_type,
};
#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
@@ -132,29 +132,29 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
-static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+ s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
}
-static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
+ s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
}
-static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
+static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+ s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
}
static struct irq_chip s3c2412_irq_cfsdi = {
.name = "s3c2412-cfsdi",
- .ack = s3c2412_irq_cfsdi_ack,
- .mask = s3c2412_irq_cfsdi_mask,
- .unmask = s3c2412_irq_cfsdi_unmask,
+ .irq_ack = s3c2412_irq_cfsdi_ack,
+ .irq_mask = s3c2412_irq_cfsdi_mask,
+ .irq_unmask = s3c2412_irq_cfsdi_unmask,
};
-static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
+static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
{
unsigned long pwrcfg;
@@ -165,7 +165,7 @@ static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
__raw_writel(pwrcfg, S3C2412_PWRCFG);
- return s3c_irq_chip.set_wake(irqno, state);
+ return s3c_irq_chip.irq_set_wake(data, state);
}
static struct irq_chip s3c2412_irq_rtc_chip;
@@ -193,7 +193,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
/* change RTC IRQ's set wake method */
s3c2412_irq_rtc_chip = s3c_irq_chip;
- s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake;
+ s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index 87b9c9f003bd..df8d14974c90 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -27,6 +27,7 @@ config S3C2416_DMA
config S3C2416_PM
bool
+ select S3C2412_PM_SLEEP
help
Internal config node to apply S3C2416 power management
@@ -35,9 +36,12 @@ menu "S3C2416 Machines"
config MACH_SMDK2416
bool "SMDK2416"
select CPU_S3C2416
+ select MACH_SMDK
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
select S3C2416_PM if PM
help
Say Y here if you are using an SMDK2416
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 00174daf1526..680fe386aca5 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -77,28 +77,27 @@ static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
+static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
-static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
+static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+ s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
}
-static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
+static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static struct irq_chip s3c2416_irq_wdtac97 = {
- .mask = s3c2416_irq_wdtac97_mask,
- .unmask = s3c2416_irq_wdtac97_unmask,
- .ack = s3c2416_irq_wdtac97_ack,
+ .irq_mask = s3c2416_irq_wdtac97_mask,
+ .irq_unmask = s3c2416_irq_wdtac97_unmask,
+ .irq_ack = s3c2416_irq_wdtac97_ack,
};
-
/* LCD sub interrupts */
static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
@@ -109,28 +108,27 @@ static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-static void s3c2416_irq_lcd_mask(unsigned int irqno)
+static void s3c2416_irq_lcd_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+ s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
-static void s3c2416_irq_lcd_unmask(unsigned int irqno)
+static void s3c2416_irq_lcd_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_LCD);
+ s3c_irqsub_unmask(data->irq, INTMSK_LCD);
}
-static void s3c2416_irq_lcd_ack(unsigned int irqno)
+static void s3c2416_irq_lcd_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+ s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static struct irq_chip s3c2416_irq_lcd = {
- .mask = s3c2416_irq_lcd_mask,
- .unmask = s3c2416_irq_lcd_unmask,
- .ack = s3c2416_irq_lcd_ack,
+ .irq_mask = s3c2416_irq_lcd_mask,
+ .irq_unmask = s3c2416_irq_lcd_unmask,
+ .irq_ack = s3c2416_irq_lcd_ack,
};
-
/* DMA sub interrupts */
static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
@@ -142,28 +140,27 @@ static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-static void s3c2416_irq_dma_mask(unsigned int irqno)
+static void s3c2416_irq_dma_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+ s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
-static void s3c2416_irq_dma_unmask(unsigned int irqno)
+static void s3c2416_irq_dma_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_DMA);
+ s3c_irqsub_unmask(data->irq, INTMSK_DMA);
}
-static void s3c2416_irq_dma_ack(unsigned int irqno)
+static void s3c2416_irq_dma_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+ s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static struct irq_chip s3c2416_irq_dma = {
- .mask = s3c2416_irq_dma_mask,
- .unmask = s3c2416_irq_dma_unmask,
- .ack = s3c2416_irq_dma_ack,
+ .irq_mask = s3c2416_irq_dma_mask,
+ .irq_unmask = s3c2416_irq_dma_unmask,
+ .irq_ack = s3c2416_irq_dma_ack,
};
-
/* UART3 sub interrupts */
static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
@@ -174,28 +171,27 @@ static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-static void s3c2416_irq_uart3_mask(unsigned int irqno)
+static void s3c2416_irq_uart3_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+ s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
-static void s3c2416_irq_uart3_unmask(unsigned int irqno)
+static void s3c2416_irq_uart3_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_UART3);
+ s3c_irqsub_unmask(data->irq, INTMSK_UART3);
}
-static void s3c2416_irq_uart3_ack(unsigned int irqno)
+static void s3c2416_irq_uart3_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+ s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static struct irq_chip s3c2416_irq_uart3 = {
- .mask = s3c2416_irq_uart3_mask,
- .unmask = s3c2416_irq_uart3_unmask,
- .ack = s3c2416_irq_uart3_ack,
+ .irq_mask = s3c2416_irq_uart3_mask,
+ .irq_unmask = s3c2416_irq_uart3_unmask,
+ .irq_ack = s3c2416_irq_uart3_ack,
};
-
/* IRQ initialisation code */
static int __init s3c2416_add_sub(unsigned int base,
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index ff024a6c0f85..a0cb2581894f 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -18,6 +18,7 @@ config CPU_S3C2440
config CPU_S3C2442
bool
select CPU_ARM920T
+ select S3C_GPIO_PULL_DOWN
select S3C2410_CLOCK
select S3C2410_GPIO
select S3C2410_PM if PM
@@ -178,6 +179,9 @@ config MACH_MINI2440
bool "MINI2440 development board"
select CPU_S3C2440
select EEPROM_AT24
+ select NEW_LEDS
+ select LEDS_CLASS
+ select LEDS_TRIGGER
select LEDS_TRIGGER_BACKLIGHT
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 0c049b95c378..acad4428bef0 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -69,27 +69,27 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
static void
-s3c_irq_wdtac97_mask(unsigned int irqno)
+s3c_irq_wdtac97_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+ s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
}
static void
-s3c_irq_wdtac97_unmask(unsigned int irqno)
+s3c_irq_wdtac97_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_WDT);
+ s3c_irqsub_unmask(data->irq, INTMSK_WDT);
}
static void
-s3c_irq_wdtac97_ack(unsigned int irqno)
+s3c_irq_wdtac97_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+ s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
}
static struct irq_chip s3c_irq_wdtac97 = {
- .mask = s3c_irq_wdtac97_mask,
- .unmask = s3c_irq_wdtac97_unmask,
- .ack = s3c_irq_wdtac97_ack,
+ .irq_mask = s3c_irq_wdtac97_mask,
+ .irq_unmask = s3c_irq_wdtac97_unmask,
+ .irq_ack = s3c_irq_wdtac97_ack,
};
static int s3c2440_irq_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index e0622bbb6dfa..eab6ae50683c 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -692,7 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c_device_usbgadget,
&s3c_device_rtc,
&s3c_device_nand,
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index d50f3ae6173d..f7663f731ea0 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -46,9 +46,6 @@ int __init s3c2440_init(void)
{
printk("S3C2440: Initialising architecture\n");
- s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
- s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
-
/* change irq for watchdog */
s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
@@ -58,3 +55,11 @@ int __init s3c2440_init(void)
return sysdev_register(&s3c2440_sysdev);
}
+
+void __init s3c2440_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+}
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
index 188ad1e57dc0..ecf813546554 100644
--- a/arch/arm/mach-s3c2440/s3c2442.c
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mutex.h>
+#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/io.h>
@@ -43,6 +44,11 @@
#include <plat/clock.h>
#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
/* S3C2442 extended clock support */
@@ -163,3 +169,11 @@ int __init s3c2442_init(void)
return sysdev_register(&s3c2442_sysdev);
}
+
+void __init s3c2442_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down;
+}
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
index a75c0c2431ea..83daf4ece764 100644
--- a/arch/arm/mach-s3c2440/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
@@ -68,27 +68,27 @@ static void s3c_irq_demux_cam(unsigned int irq,
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
static void
-s3c_irq_cam_mask(unsigned int irqno)
+s3c_irq_cam_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+ s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
}
static void
-s3c_irq_cam_unmask(unsigned int irqno)
+s3c_irq_cam_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_CAM);
+ s3c_irqsub_unmask(data->irq, INTMSK_CAM);
}
static void
-s3c_irq_cam_ack(unsigned int irqno)
+s3c_irq_cam_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+ s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
}
static struct irq_chip s3c_irq_cam = {
- .mask = s3c_irq_cam_mask,
- .unmask = s3c_irq_cam_unmask,
- .ack = s3c_irq_cam_ack,
+ .irq_mask = s3c_irq_cam_mask,
+ .irq_unmask = s3c_irq_cam_unmask,
+ .irq_ack = s3c_irq_cam_ack,
};
static int s3c244x_irq_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 4fef723126fa..31babec90cec 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -5,6 +5,7 @@
config CPU_S3C2443
bool
depends on ARCH_S3C2410
+ select CPU_ARM920T
select S3C2443_DMA if S3C2410_DMA
select CPU_LLSERIAL_S3C2440
select SAMSUNG_CLKSRC
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 893424767ce1..c7820f9c1352 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -75,28 +75,27 @@ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
-static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+ s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
}
-static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
+static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static struct irq_chip s3c2443_irq_wdtac97 = {
- .mask = s3c2443_irq_wdtac97_mask,
- .unmask = s3c2443_irq_wdtac97_unmask,
- .ack = s3c2443_irq_wdtac97_ack,
+ .irq_mask = s3c2443_irq_wdtac97_mask,
+ .irq_unmask = s3c2443_irq_wdtac97_unmask,
+ .irq_ack = s3c2443_irq_wdtac97_ack,
};
-
/* LCD sub interrupts */
static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
@@ -107,28 +106,27 @@ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-static void s3c2443_irq_lcd_mask(unsigned int irqno)
+static void s3c2443_irq_lcd_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+ s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
-static void s3c2443_irq_lcd_unmask(unsigned int irqno)
+static void s3c2443_irq_lcd_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_LCD);
+ s3c_irqsub_unmask(data->irq, INTMSK_LCD);
}
-static void s3c2443_irq_lcd_ack(unsigned int irqno)
+static void s3c2443_irq_lcd_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+ s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static struct irq_chip s3c2443_irq_lcd = {
- .mask = s3c2443_irq_lcd_mask,
- .unmask = s3c2443_irq_lcd_unmask,
- .ack = s3c2443_irq_lcd_ack,
+ .irq_mask = s3c2443_irq_lcd_mask,
+ .irq_unmask = s3c2443_irq_lcd_unmask,
+ .irq_ack = s3c2443_irq_lcd_ack,
};
-
/* DMA sub interrupts */
static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
@@ -139,29 +137,27 @@ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(unsigned int irqno)
+static void s3c2443_irq_dma_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+ s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
-static void s3c2443_irq_dma_unmask(unsigned int irqno)
+static void s3c2443_irq_dma_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_DMA);
+ s3c_irqsub_unmask(data->irq, INTMSK_DMA);
}
-static void s3c2443_irq_dma_ack(unsigned int irqno)
+static void s3c2443_irq_dma_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+ s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static struct irq_chip s3c2443_irq_dma = {
- .mask = s3c2443_irq_dma_mask,
- .unmask = s3c2443_irq_dma_unmask,
- .ack = s3c2443_irq_dma_ack,
+ .irq_mask = s3c2443_irq_dma_mask,
+ .irq_unmask = s3c2443_irq_dma_unmask,
+ .irq_ack = s3c2443_irq_dma_ack,
};
-
/* UART3 sub interrupts */
static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
@@ -172,28 +168,27 @@ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-static void s3c2443_irq_uart3_mask(unsigned int irqno)
+static void s3c2443_irq_uart3_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+ s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
-static void s3c2443_irq_uart3_unmask(unsigned int irqno)
+static void s3c2443_irq_uart3_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_UART3);
+ s3c_irqsub_unmask(data->irq, INTMSK_UART3);
}
-static void s3c2443_irq_uart3_ack(unsigned int irqno)
+static void s3c2443_irq_uart3_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+ s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static struct irq_chip s3c2443_irq_uart3 = {
- .mask = s3c2443_irq_uart3_mask,
- .unmask = s3c2443_irq_uart3_unmask,
- .ack = s3c2443_irq_uart3_ack,
+ .irq_mask = s3c2443_irq_uart3_mask,
+ .irq_unmask = s3c2443_irq_uart3_unmask,
+ .irq_ack = s3c2443_irq_uart3_ack,
};
-
/* CAM sub interrupts */
static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
@@ -204,25 +199,25 @@ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-static void s3c2443_irq_cam_mask(unsigned int irqno)
+static void s3c2443_irq_cam_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
+ s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
}
-static void s3c2443_irq_cam_unmask(unsigned int irqno)
+static void s3c2443_irq_cam_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_CAM);
+ s3c_irqsub_unmask(data->irq, INTMSK_CAM);
}
-static void s3c2443_irq_cam_ack(unsigned int irqno)
+static void s3c2443_irq_cam_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
+ s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
}
static struct irq_chip s3c2443_irq_cam = {
- .mask = s3c2443_irq_cam_mask,
- .unmask = s3c2443_irq_cam_unmask,
- .ack = s3c2443_irq_cam_ack,
+ .irq_mask = s3c2443_irq_cam_mask,
+ .irq_unmask = s3c2443_irq_cam_unmask,
+ .irq_ack = s3c2443_irq_cam_ack,
};
/* IRQ initialisation code */
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 7e03f0ae2fc8..1c98d2ff2ed6 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = {
}, {
.clk = {
.name = "audio-bus",
- .id = -1, /* There's only one IISv4 port */
+ .id = 2,
.ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
.enable = s3c64xx_sclk_ctrl,
},
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 76426a32c013..cad67022fa25 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -22,7 +22,12 @@
#include <plat/audio.h>
#include <plat/gpio-cfg.h>
-static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
+static const char *rclksrc[] = {
+ [0] = "iis",
+ [1] = "audio-bus",
+};
+
+static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
@@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
case 1:
base = S3C64XX_GPE(0);
break;
+ case 2:
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
+ return 0;
default:
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
pdev->id);
@@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
return 0;
}
-static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
-{
- s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
-
- return 0;
-}
-
static struct resource s3c64xx_iis0_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS0,
@@ -72,17 +73,22 @@ static struct resource s3c64xx_iis0_resource[] = {
},
};
-static struct s3c_audio_pdata s3c_i2s0_pdata = {
- .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc,
+ },
+ },
};
struct platform_device s3c64xx_device_iis0 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
.resource = s3c64xx_iis0_resource,
.dev = {
- .platform_data = &s3c_i2s0_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iis0);
@@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = {
},
};
-static struct s3c_audio_pdata s3c_i2s1_pdata = {
- .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
-};
-
struct platform_device s3c64xx_device_iis1 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
.resource = s3c64xx_iis1_resource,
.dev = {
- .platform_data = &s3c_i2s1_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iis1);
@@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = {
},
};
-static struct s3c_audio_pdata s3c_i2sv4_pdata = {
- .cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
+static struct s3c_audio_pdata i2sv4_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
};
struct platform_device s3c64xx_device_iisv4 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
+ .name = "samsung-i2s",
+ .id = 2,
.num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
.resource = s3c64xx_iisv4_resource,
.dev = {
- .platform_data = &s3c_i2sv4_pdata,
+ .platform_data = &i2sv4_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iisv4);
@@ -288,7 +296,7 @@ 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",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
.resource = s3c64xx_ac97_resource,
@@ -307,16 +315,3 @@ void __init s3c64xx_ac97_setup_gpio(int num)
else
s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
}
-
-static u64 s3c_device_audio_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_pcm = {
- .name = "s3c24xx-pcm-audio",
- .id = -1,
- .dev = {
- .dma_mask = &s3c_device_audio_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-EXPORT_SYMBOL(s3c_device_pcm);
-
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
index e7d03ab41d80..d9aa072ecee3 100644
--- a/arch/arm/mach-s3c64xx/dma.c
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -212,6 +212,7 @@ static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
config = readl(chan->regs + PL080S_CH_CONFIG);
config |= PL080_CONFIG_ENABLE;
+ config &= ~PL080_CONFIG_HALT;
pr_debug("%s: writing config %08x\n", __func__, config);
writel(config, chan->regs + PL080S_CH_CONFIG);
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
index 5682d6a7f4af..2ead8189da74 100644
--- a/arch/arm/mach-s3c64xx/irq-eint.c
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -30,41 +30,41 @@
#include <plat/pm.h>
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
-#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
+#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
-static inline void s3c_irq_eint_mask(unsigned int irq)
+static inline void s3c_irq_eint_mask(struct irq_data *data)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
- mask |= eint_irq_to_bit(irq);
+ mask |= (u32)data->chip_data;
__raw_writel(mask, S3C64XX_EINT0MASK);
}
-static void s3c_irq_eint_unmask(unsigned int irq)
+static void s3c_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
- mask &= ~eint_irq_to_bit(irq);
+ mask &= ~((u32)data->chip_data);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
-static inline void s3c_irq_eint_ack(unsigned int irq)
+static inline void s3c_irq_eint_ack(struct irq_data *data)
{
- __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
+ __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
}
-static void s3c_irq_eint_maskack(unsigned int irq)
+static void s3c_irq_eint_maskack(struct irq_data *data)
{
/* compiler should in-line these */
- s3c_irq_eint_mask(irq);
- s3c_irq_eint_ack(irq);
+ s3c_irq_eint_mask(data);
+ s3c_irq_eint_ack(data);
}
-static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
- int offs = eint_offset(irq);
+ int offs = eint_offset(data->irq);
int pin, pin_val;
int shift;
u32 ctrl, mask;
@@ -140,12 +140,12 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
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,
+ .irq_mask = s3c_irq_eint_mask,
+ .irq_unmask = s3c_irq_eint_unmask,
+ .irq_mask_ack = s3c_irq_eint_maskack,
+ .irq_ack = s3c_irq_eint_ack,
+ .irq_set_type = s3c_irq_eint_set_type,
+ .irq_set_wake = s3c_irqext_wake,
};
/* s3c_irq_demux_eint
@@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void)
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
set_irq_chip(irq, &s3c_irq_eint);
+ set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq));
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 77488facfe4c..e85192a86fbe 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -283,7 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_ohci,
&s3c_device_usb_hsotg,
- &s3c_device_pcm,
+ &samsung_asoc_dma,
&s3c64xx_device_iisv4,
&samsung_device_keypad,
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index 3462197ff352..8719dc41fe32 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
base = S5P6442_GPC1(0);
break;
- case -1:
+ case 0:
base = S5P6442_GPC0(0);
break;
@@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
return 0;
}
-static struct s3c_audio_pdata s3c_i2s_pdata = {
+static const char *rclksrc_v35[] = {
+ [0] = "busclk",
+ [1] = "i2sclk",
+};
+
+static struct s3c_audio_pdata i2sv35_pdata = {
.cfg_gpio = s5p6442_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc_v35,
+ },
+ },
};
static struct resource s5p6442_iis0_resource[] = {
@@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
+ [3] = {
+ .start = DMACH_I2S0S_TX,
+ .end = DMACH_I2S0S_TX,
+ .flags = IORESOURCE_DMA,
+ },
};
struct platform_device s5p6442_device_iis0 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
+ .name = "samsung-i2s",
+ .id = 0,
.num_resources = ARRAY_SIZE(s5p6442_iis0_resource),
.resource = s5p6442_iis0_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv35_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "iis",
+ [1] = "sclk_audio",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5p6442_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc_v3,
+ },
},
};
@@ -93,12 +123,12 @@ static struct resource s5p6442_iis1_resource[] = {
};
struct platform_device s5p6442_device_iis1 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5p6442_iis1_resource),
.resource = s5p6442_iis1_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h
index 31fb2e68d527..203dd5a18bd5 100644
--- a/arch/arm/mach-s5p6442/include/mach/map.h
+++ b/arch/arm/mach-s5p6442/include/mach/map.h
@@ -28,6 +28,9 @@
#define S5P6442_PA_VIC1 (0xE4100000)
#define S5P6442_PA_VIC2 (0xE4200000)
+#define S5P6442_PA_SROMC (0xE7000000)
+#define S5P_PA_SROMC S5P6442_PA_SROMC
+
#define S5P6442_PA_MDMA 0xE8000000
#define S5P6442_PA_PDMA 0xE9000000
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
index 819fd80d00af..e69f137b0a39 100644
--- a/arch/arm/mach-s5p6442/mach-smdk6442.c
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/serial_core.h>
+#include <linux/i2c.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -25,6 +26,7 @@
#include <plat/s5p6442.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/iic.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -65,10 +67,15 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
};
static struct platform_device *smdk6442_devices[] __initdata = {
+ &s3c_device_i2c0,
&s5p6442_device_iis0,
&s3c_device_wdt,
};
+static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+};
+
static void __init smdk6442_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -78,6 +85,9 @@ static void __init smdk6442_map_io(void)
static void __init smdk6442_machine_init(void)
{
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, smdk6442_i2c_devs0,
+ ARRAY_SIZE(smdk6442_i2c_devs0));
platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
}
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c
index 662695dd7761..aad85656b0cc 100644
--- a/arch/arm/mach-s5p6442/setup-i2c0.c
+++ b/arch/arm/mach-s5p6442/setup-i2c0.c
@@ -14,12 +14,15 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/gpio.h>
struct platform_device; /* don't need the contents */
+#include <plat/gpio-cfg.h>
#include <plat/iic.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- /* Will be populated later */
+ s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index 2655829e6bf8..ae6bf6feba89 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -12,9 +12,9 @@ obj- :=
# Core support for S5P64X0 system
-obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
+obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o
obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o
-obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o
+obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
# machine support
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index e4883dc1c8d7..40137c6f0488 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = {
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 25),
}, {
- .name = "i2s_v40",
+ .name = "iis",
.id = 0,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
@@ -419,7 +419,7 @@ static struct clksrc_sources clkset_audio = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
- .name = "mmc_bus",
+ .name = "sclk_mmc",
.id = 0,
.ctrlbit = (1 << 24),
.enable = s5p64x0_sclk_ctrl,
@@ -429,7 +429,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
}, {
.clk = {
- .name = "mmc_bus",
+ .name = "sclk_mmc",
.id = 1,
.ctrlbit = (1 << 25),
.enable = s5p64x0_sclk_ctrl,
@@ -439,7 +439,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
}, {
.clk = {
- .name = "mmc_bus",
+ .name = "sclk_mmc",
.id = 2,
.ctrlbit = (1 << 26),
.enable = s5p64x0_sclk_ctrl,
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 7dbf3c968f53..3f5ac93c455e 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -231,6 +231,12 @@ static struct clk init_clocks_disable[] = {
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 5),
}, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
.name = "adc",
.id = -1,
.parent = &clk_pclk_low.clk,
@@ -256,11 +262,23 @@ static struct clk init_clocks_disable[] = {
.ctrlbit = (1 << 22),
}, {
.name = "iis",
- .id = -1,
+ .id = 0,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 26),
}, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "iis",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
.name = "i2c",
.id = 1,
.parent = &clk_pclk_low.clk,
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
index 396bacc0a39a..35f1f226dabb 100644
--- a/arch/arm/mach-s5p64x0/dev-audio.c
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -19,15 +19,19 @@
#include <mach/dma.h>
#include <mach/irqs.h>
+static const char *rclksrc[] = {
+ [0] = "iis",
+ [1] = "sclk_audio2",
+};
+
static int s5p6440_cfg_i2s(struct platform_device *pdev)
{
- /* configure GPIO for i2s port */
switch (pdev->id) {
- case -1:
- s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
- s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
+ case 0:
+ s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
break;
-
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
@@ -36,17 +40,58 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
return 0;
}
+static struct s3c_audio_pdata s5p6440_i2s_pdata = {
+ .cfg_gpio = s5p6440_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource s5p64x0_i2s0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_I2S,
+ .end = S5P64X0_PA_I2S + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_TX,
+ .end = DMACH_I2S0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_RX,
+ .end = DMACH_I2S0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6440_device_iis = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
+ .resource = s5p64x0_i2s0_resource,
+ .dev = {
+ .platform_data = &s5p6440_i2s_pdata,
+ },
+};
+
static int s5p6450_cfg_i2s(struct platform_device *pdev)
{
- /* configure GPIO for i2s port */
switch (pdev->id) {
- case -1:
- s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
+ case 0:
s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
-
break;
-
+ case 1:
+ s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
+ break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
@@ -55,47 +100,86 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
return 0;
}
-static struct s3c_audio_pdata s5p6440_i2s_pdata = {
- .cfg_gpio = s5p6440_cfg_i2s,
+static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
+ .cfg_gpio = s5p6450_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+struct platform_device s5p6450_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
+ .resource = s5p64x0_i2s0_resource,
+ .dev = {
+ .platform_data = &s5p6450_i2s0_pdata,
+ },
};
static struct s3c_audio_pdata s5p6450_i2s_pdata = {
.cfg_gpio = s5p6450_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc,
+ },
+ },
};
-static struct resource s5p64x0_iis0_resource[] = {
+static struct resource s5p6450_i2s1_resource[] = {
[0] = {
- .start = S5P64X0_PA_I2S,
- .end = S5P64X0_PA_I2S + 0x100 - 1,
+ .start = S5P6450_PA_I2S1,
+ .end = S5P6450_PA_I2S1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = DMACH_I2S0_TX,
- .end = DMACH_I2S0_TX,
+ .start = DMACH_I2S1_TX,
+ .end = DMACH_I2S1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
- .start = DMACH_I2S0_RX,
- .end = DMACH_I2S0_RX,
+ .start = DMACH_I2S1_RX,
+ .end = DMACH_I2S1_RX,
.flags = IORESOURCE_DMA,
},
};
-struct platform_device s5p6440_device_iis = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
- .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
- .resource = s5p64x0_iis0_resource,
+struct platform_device s5p6450_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p6450_i2s1_resource),
+ .resource = s5p6450_i2s1_resource,
.dev = {
- .platform_data = &s5p6440_i2s_pdata,
+ .platform_data = &s5p6450_i2s_pdata,
},
};
-struct platform_device s5p6450_device_iis0 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
- .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
- .resource = s5p64x0_iis0_resource,
+static struct resource s5p6450_i2s2_resource[] = {
+ [0] = {
+ .start = S5P6450_PA_I2S2,
+ .end = S5P6450_PA_I2S2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S2_TX,
+ .end = DMACH_I2S2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S2_RX,
+ .end = DMACH_I2S2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6450_device_iis2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5p6450_i2s2_resource),
+ .resource = s5p6450_i2s2_resource,
.dev = {
.platform_data = &s5p6450_i2s_pdata,
},
diff --git a/arch/arm/mach-s5p64x0/gpio.c b/arch/arm/mach-s5p64x0/gpiolib.c
index 39159dd5a29a..e7fb3b004e77 100644
--- a/arch/arm/mach-s5p64x0/gpio.c
+++ b/arch/arm/mach-s5p64x0/gpiolib.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s5p64x0/gpio.c
+/* linux/arch/arm/mach-s5p64x0/gpiolib.c
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -17,13 +17,12 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
-/* To be implemented S5P6450 GPIO */
-
/*
* S5P6440 GPIO bank summary:
*
@@ -40,6 +39,25 @@
* P 8 2Bit Yes 8
* R 15 4Bit[2] Yes 8
*
+ * S5P6450 GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 6 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * D 8 4Bit Yes None
+ * F 2 2Bit Yes None
+ * G 14 4Bit[2] Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * K 5 4Bit Yes None
+ * N 16 2Bit No IRQ_EINT
+ * P 11 2Bit Yes 8
+ * Q 14 2Bit Yes None
+ * R 15 4Bit[2] Yes None
+ * S 8 2Bit Yes None
+ *
* [1] BANKF pins 14,15 do not form part of the external interrupt sources
* [2] BANK has two control registers, GPxCON0 and GPxCON1
*/
@@ -190,7 +208,7 @@ static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
{
- .base = S5P6440_GPA_BASE,
+ .base = S5P64X0_GPA_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPA(0),
@@ -198,7 +216,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPA",
},
}, {
- .base = S5P6440_GPB_BASE,
+ .base = S5P64X0_GPB_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPB(0),
@@ -206,7 +224,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPB",
},
}, {
- .base = S5P6440_GPC_BASE,
+ .base = S5P64X0_GPC_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPC(0),
@@ -214,7 +232,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPC",
},
}, {
- .base = S5P6440_GPG_BASE,
+ .base = S5P64X0_GPG_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPG(0),
@@ -226,7 +244,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
{
- .base = S5P6440_GPH_BASE + 0x4,
+ .base = S5P64X0_GPH_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPH(0),
@@ -238,7 +256,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
{
- .base = S5P6440_GPR_BASE + 0x4,
+ .base = S5P64X0_GPR_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[2],
.chip = {
.base = S5P6440_GPR(0),
@@ -250,7 +268,7 @@ static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
{
- .base = S5P6440_GPF_BASE,
+ .base = S5P64X0_GPF_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPF(0),
@@ -258,7 +276,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPF",
},
}, {
- .base = S5P6440_GPI_BASE,
+ .base = S5P64X0_GPI_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPI(0),
@@ -266,7 +284,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPI",
},
}, {
- .base = S5P6440_GPJ_BASE,
+ .base = S5P64X0_GPJ_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPJ(0),
@@ -274,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPJ",
},
}, {
- .base = S5P6440_GPN_BASE,
+ .base = S5P64X0_GPN_BASE,
.config = &s5p64x0_gpio_cfgs[4],
.chip = {
.base = S5P6440_GPN(0),
@@ -282,7 +300,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPN",
},
}, {
- .base = S5P6440_GPP_BASE,
+ .base = S5P64X0_GPP_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPP(0),
@@ -292,6 +310,142 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
};
+static struct s3c_gpio_chip s5p6450_gpio_4bit[] = {
+ {
+ .base = S5P64X0_GPA_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPA(0),
+ .ngpio = S5P6450_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S5P64X0_GPB_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPB(0),
+ .ngpio = S5P6450_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S5P64X0_GPC_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPC(0),
+ .ngpio = S5P6450_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S5P6450_GPD_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPD(0),
+ .ngpio = S5P6450_GPIO_D_NR,
+ .label = "GPD",
+ },
+ }, {
+ .base = S5P6450_GPK_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPK(0),
+ .ngpio = S5P6450_GPIO_K_NR,
+ .label = "GPK",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_4bit2[] = {
+ {
+ .base = S5P64X0_GPG_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPG(0),
+ .ngpio = S5P6450_GPIO_G_NR,
+ .label = "GPG",
+ },
+ }, {
+ .base = S5P64X0_GPH_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPH(0),
+ .ngpio = S5P6450_GPIO_H_NR,
+ .label = "GPH",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_rbank_4bit2[] = {
+ {
+ .base = S5P64X0_GPR_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[2],
+ .chip = {
+ .base = S5P6450_GPR(0),
+ .ngpio = S5P6450_GPIO_R_NR,
+ .label = "GPR",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_2bit[] = {
+ {
+ .base = S5P64X0_GPF_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPF(0),
+ .ngpio = S5P6450_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S5P64X0_GPI_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6450_GPI(0),
+ .ngpio = S5P6450_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S5P64X0_GPJ_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6450_GPJ(0),
+ .ngpio = S5P6450_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S5P64X0_GPN_BASE,
+ .config = &s5p64x0_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6450_GPN(0),
+ .ngpio = S5P6450_GPIO_N_NR,
+ .label = "GPN",
+ },
+ }, {
+ .base = S5P64X0_GPP_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPP(0),
+ .ngpio = S5P6450_GPIO_P_NR,
+ .label = "GPP",
+ },
+ }, {
+ .base = S5P6450_GPQ_BASE,
+ .config = &s5p64x0_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6450_GPQ(0),
+ .ngpio = S5P6450_GPIO_Q_NR,
+ .label = "GPQ",
+ },
+ }, {
+ .base = S5P6450_GPS_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPS(0),
+ .ngpio = S5P6450_GPIO_S_NR,
+ .label = "GPS",
+ },
+ },
+};
+
void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
{
for (; nr_chips > 0; nr_chips--, chipcfg++) {
@@ -317,26 +471,41 @@ static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
}
}
-static int __init s5p6440_gpiolib_init(void)
+static int __init s5p64x0_gpiolib_init(void)
{
- struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
- int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
+ unsigned int chipid;
+
+ chipid = __raw_readl(S5P64X0_SYS_ID);
s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
ARRAY_SIZE(s5p64x0_gpio_cfgs));
- for (; nr_chips > 0; nr_chips--, chips++)
- s3c_gpiolib_add(chips);
+ if ((chipid & 0xff000) == 0x50000) {
+ samsung_gpiolib_add_2bit_chips(s5p6450_gpio_2bit,
+ ARRAY_SIZE(s5p6450_gpio_2bit));
+
+ samsung_gpiolib_add_4bit_chips(s5p6450_gpio_4bit,
+ ARRAY_SIZE(s5p6450_gpio_4bit));
- samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
- ARRAY_SIZE(s5p6440_gpio_4bit));
+ samsung_gpiolib_add_4bit2_chips(s5p6450_gpio_4bit2,
+ ARRAY_SIZE(s5p6450_gpio_4bit2));
- samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
- ARRAY_SIZE(s5p6440_gpio_4bit2));
+ s5p64x0_gpio_add_rbank_4bit2(s5p6450_gpio_rbank_4bit2,
+ ARRAY_SIZE(s5p6450_gpio_rbank_4bit2));
+ } else {
+ samsung_gpiolib_add_2bit_chips(s5p6440_gpio_2bit,
+ ARRAY_SIZE(s5p6440_gpio_2bit));
- s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
- ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
+ 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));
+
+ s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
+ ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
+ }
return 0;
}
-arch_initcall(s5p6440_gpiolib_init);
+core_initcall(s5p64x0_gpiolib_init);
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 31e534156e06..a9365e5ba614 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -29,6 +29,9 @@
#define S5P64X0_PA_VIC0 (0xE4000000)
#define S5P64X0_PA_VIC1 (0xE4100000)
+#define S5P64X0_PA_SROMC (0xE7000000)
+#define S5P_PA_SROMC S5P64X0_PA_SROMC
+
#define S5P64X0_PA_PDMA (0xE9000000)
#define S5P64X0_PA_TIMER (0xEA000000)
@@ -63,6 +66,8 @@
#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
#define S5P64X0_PA_I2S (0xF2000000)
+#define S5P6450_PA_I2S1 0xF2800000
+#define S5P6450_PA_I2S2 0xF2900000
#define S5P64X0_PA_PCM (0xF2100000)
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 85f448e20a8b..0953ef6b1c77 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -15,48 +15,23 @@
#include <mach/map.h>
-/* Will be implemented S5P6442 GPIOlib */
-
/* 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))
+#define S5P64X0_GPA_BASE (S5P_VA_GPIO + 0x0000)
+#define S5P64X0_GPB_BASE (S5P_VA_GPIO + 0x0020)
+#define S5P64X0_GPC_BASE (S5P_VA_GPIO + 0x0040)
+#define S5P64X0_GPF_BASE (S5P_VA_GPIO + 0x00A0)
+#define S5P64X0_GPG_BASE (S5P_VA_GPIO + 0x00C0)
+#define S5P64X0_GPH_BASE (S5P_VA_GPIO + 0x00E0)
+#define S5P64X0_GPI_BASE (S5P_VA_GPIO + 0x0100)
+#define S5P64X0_GPJ_BASE (S5P_VA_GPIO + 0x0120)
+#define S5P64X0_GPN_BASE (S5P_VA_GPIO + 0x0830)
+#define S5P64X0_GPP_BASE (S5P_VA_GPIO + 0x0160)
+#define S5P64X0_GPR_BASE (S5P_VA_GPIO + 0x0290)
+
+#define S5P6450_GPD_BASE (S5P_VA_GPIO + 0x0060)
+#define S5P6450_GPK_BASE (S5P_VA_GPIO + 0x0140)
+#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
+#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 87c3f03c618c..e9802755daeb 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -117,6 +117,7 @@ static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d609f5af2b98..b78f56292780 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -135,6 +135,7 @@ static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
};
static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
};
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index 564e195ec493..ab2d27172cbc 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
+ case 0: /* Dedicated pins */
+ break;
case 1:
s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
break;
-
case 2:
s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
break;
-
- case -1: /* Dedicated pins */
- break;
-
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
@@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
return 0;
}
-static struct s3c_audio_pdata s3c_i2s_pdata = {
+static const char *rclksrc_v5[] = {
+ [0] = "iis",
+ [1] = "i2sclkd2",
+};
+
+static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pc100_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc_v5,
+ },
+ },
};
static struct resource s5pc100_iis0_resource[] = {
@@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
+ [3] = {
+ .start = DMACH_I2S0S_TX,
+ .end = DMACH_I2S0S_TX,
+ .flags = IORESOURCE_DMA,
+ },
};
struct platform_device s5pc100_device_iis0 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
+ .name = "samsung-i2s",
+ .id = 0,
.num_resources = ARRAY_SIZE(s5pc100_iis0_resource),
.resource = s5pc100_iis0_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "iis",
+ [1] = "sclk_audio",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5pc100_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc_v3,
+ },
},
};
@@ -93,12 +121,12 @@ static struct resource s5pc100_iis1_resource[] = {
};
struct platform_device s5pc100_device_iis1 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5pc100_iis1_resource),
.resource = s5pc100_iis1_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
@@ -121,12 +149,12 @@ static struct resource s5pc100_iis2_resource[] = {
};
struct platform_device s5pc100_device_iis2 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5pc100_iis2_resource),
.resource = s5pc100_iis2_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
@@ -253,7 +281,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = {
static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pc100_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s5pc100_ac97_resource),
.resource = s5pc100_ac97_resource,
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 32e9cab5c864..328467b346aa 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -55,6 +55,8 @@
#define S5PC100_VA_VIC_OFFSET 0x10000
#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
+#define S5PC100_PA_SROMC (0xE7000000)
+#define S5P_PA_SROMC S5PC100_PA_SROMC
#define S5PC100_PA_ONENAND (0xE7100000)
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 18b405d514d6..dd192a27524d 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -96,6 +96,7 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
/* I2C0 */
static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("wm8580", 0x1b),},
};
/* I2C1 */
@@ -190,6 +191,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s3c_device_ts,
&s3c_device_wdt,
&smdkc100_lcd_powerdev,
+ &samsung_asoc_dma,
&s5pc100_device_iis0,
&samsung_device_keypad,
&s5pc100_device_ac97,
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 862f239a0fdb..53aabef1e9ce 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -118,6 +118,7 @@ menu "S5PV210 Machines"
config MACH_SMDKV210
bool "SMDKV210"
select CPU_S5PV210
+ select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
@@ -130,6 +131,7 @@ config MACH_SMDKV210
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_TS
+ select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_IDE
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 019c3a69b0e4..dab6ef3b6ca9 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = {
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1<<21),
}, {
- .name = "i2s_v50",
+ .name = "iis",
.id = 0,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1<<4),
}, {
- .name = "i2s_v32",
- .id = 0,
+ .name = "iis",
+ .id = 1,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 5),
}, {
- .name = "i2s_v32",
- .id = 1,
+ .name = "iis",
+ .id = 2,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 6),
@@ -525,6 +525,12 @@ static struct clk init_clocks[] = {
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 20),
+ }, {
+ .name = "sromc",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 26),
},
};
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 8eb480e201b0..61e6c24b90ac 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -81,11 +81,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.length = SZ_512K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S5P_VA_SROMC,
- .pfn = __phys_to_pfn(S5PV210_PA_SROMC),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(S5PV210_PA_DMC0),
.length = SZ_4K,
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 1303fcb12b51..8d58f1926241 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -19,22 +19,24 @@
#include <mach/dma.h>
#include <mach/irqs.h>
+static const char *rclksrc[] = {
+ [0] = "busclk",
+ [1] = "i2sclk",
+};
+
static int s5pv210_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
+ break;
case 1:
s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
break;
-
case 2:
s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
break;
-
- case -1:
- s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
- break;
-
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
@@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
return 0;
}
-static struct s3c_audio_pdata s3c_i2s_pdata = {
+static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pv210_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc,
+ },
+ },
};
static struct resource s5pv210_iis0_resource[] = {
@@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
+ [3] = {
+ .start = DMACH_I2S0S_TX,
+ .end = DMACH_I2S0S_TX,
+ .flags = IORESOURCE_DMA,
+ },
};
struct platform_device s5pv210_device_iis0 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
+ .name = "samsung-i2s",
+ .id = 0,
.num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
.resource = s5pv210_iis0_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "iis",
+ [1] = "audio-bus",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5pv210_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc_v3,
+ },
},
};
@@ -94,12 +122,12 @@ static struct resource s5pv210_iis1_resource[] = {
};
struct platform_device s5pv210_device_iis1 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
.resource = s5pv210_iis1_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
@@ -122,12 +150,12 @@ static struct resource s5pv210_iis2_resource[] = {
};
struct platform_device s5pv210_device_iis2 = {
- .name = "s3c64xx-iis",
+ .name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
.resource = s5pv210_iis2_resource,
.dev = {
- .platform_data = &s3c_i2s_pdata,
+ .platform_data = &i2sv3_pdata,
},
};
@@ -283,7 +311,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = {
static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv210_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s5pv210_ac97_resource),
.resource = s5pv210_ac97_resource,
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 119b95fdc3ce..26710b35ef87 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -65,7 +65,7 @@
#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_MIPI_CSIS S5P_IRQ_VIC1(29)
#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31)
@@ -132,5 +132,6 @@
#define IRQ_LCD_FIFO IRQ_LCD0
#define IRQ_LCD_VSYNC IRQ_LCD1
#define IRQ_LCD_SYSTEM IRQ_LCD2
+#define IRQ_MIPI_CSIS0 IRQ_MIPI_CSIS
#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
index 861d7fe11fc9..3611492ad681 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -16,6 +16,8 @@
#include <plat/map-base.h>
#include <plat/map-s5p.h>
+#define S5PV210_PA_SROM_BANK5 (0xA8000000)
+
#define S5PC110_PA_ONENAND (0xB0000000)
#define S5P_PA_ONENAND S5PC110_PA_ONENAND
@@ -60,6 +62,7 @@
#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#define S5PV210_PA_SROMC (0xE8000000)
+#define S5P_PA_SROMC S5PV210_PA_SROMC
#define S5PV210_PA_CFCON (0xE8200000)
@@ -107,6 +110,8 @@
#define S5PV210_PA_DMC0 (0xF0000000)
#define S5PV210_PA_DMC1 (0xF1400000)
+#define S5PV210_PA_MIPI_CSIS 0xFA600000
+
/* compatibiltiy defines. */
#define S3C_PA_UART S5PV210_PA_UART
#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
@@ -123,6 +128,7 @@
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
+#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
#define SAMSUNG_PA_ADC S5PV210_PA_ADC
#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index ebaabe021af9..4c45b74def5f 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -161,7 +161,7 @@
#define S5P_MDNIE_SEL S5P_CLKREG(0x7008)
#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_MIPI_DPHY_CONTROL S5P_CLKREG(0xE814)
#define S5P_IDLE_CFG_TL_MASK (3 << 30)
#define S5P_IDLE_CFG_TM_MASK (3 << 28)
@@ -195,9 +195,6 @@
#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
-/* MIPI */
-#define S5P_MIPI_DPHY_EN (3)
-
/* S5P_DAC_CONTROL */
#define S5P_DAC_ENABLE (1)
#define S5P_DAC_DISABLE (0)
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 28677caf3613..461aa035afc0 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = {
static struct max8998_platform_data aquila_max8998_pdata = {
.num_regulators = ARRAY_SIZE(aquila_regulators),
.regulators = aquila_regulators,
+ .buck1_set1 = S5PV210_GPH0(3),
+ .buck1_set2 = S5PV210_GPH0(4),
+ .buck2_set3 = S5PV210_GPH0(5),
+ .buck1_max_voltage1 = 1200000,
+ .buck1_max_voltage2 = 1200000,
+ .buck2_max_voltage = 1200000,
};
#endif
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index b1dcf964a768..e22d5112fd44 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = {
static struct max8998_platform_data goni_max8998_pdata = {
.num_regulators = ARRAY_SIZE(goni_regulators),
.regulators = goni_regulators,
+ .buck1_set1 = S5PV210_GPH0(3),
+ .buck1_set2 = S5PV210_GPH0(4),
+ .buck2_set3 = S5PV210_GPH0(5),
+ .buck1_max_voltage1 = 1200000,
+ .buck1_max_voltage2 = 1200000,
+ .buck2_max_voltage = 1200000,
};
#endif
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 5dd1681c069e..bb20a14da100 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -94,6 +94,7 @@ static struct platform_device *smdkc110_devices[] __initdata = {
static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 1fbc45b2a432..88e45223c8af 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -14,16 +14,25 @@
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
+#include <linux/dm9000.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/gpio-cfg.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -33,6 +42,7 @@
#include <plat/iic.h>
#include <plat/keypad.h>
#include <plat/pm.h>
+#include <plat/fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -102,12 +112,106 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
.cols = 8,
};
+static struct resource smdkv210_dm9000_resources[] = {
+ [0] = {
+ .start = S5PV210_PA_SROM_BANK5,
+ .end = S5PV210_PA_SROM_BANK5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S5PV210_PA_SROM_BANK5 + 2,
+ .end = S5PV210_PA_SROM_BANK5 + 2,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT(9),
+ .end = IRQ_EINT(9),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct dm9000_plat_data smdkv210_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+ .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
+};
+
+struct platform_device smdkv210_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkv210_dm9000_resources),
+ .resource = smdkv210_dm9000_resources,
+ .dev = {
+ .platform_data = &smdkv210_dm9000_platdata,
+ },
+};
+
+static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 1);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+
+ /* fire nRESET on power up */
+ gpio_request(S5PV210_GPH0(6), "GPH0");
+
+ gpio_direction_output(S5PV210_GPH0(6), 1);
+
+ gpio_set_value(S5PV210_GPH0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(S5PV210_GPH0(6), 1);
+ mdelay(10);
+
+ gpio_free(S5PV210_GPH0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 0);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkv210_lcd_lte480wv_data = {
+ .set_power = smdkv210_lte480wv_set_power,
+};
+
+static struct platform_device smdkv210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdkv210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
+ .win[0] = &smdkv210_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
static struct platform_device *smdkv210_devices[] __initdata = {
- &s5pv210_device_iis0,
- &s5pv210_device_ac97,
- &s5pv210_device_spdif,
&s3c_device_adc,
&s3c_device_cfcon,
+ &s3c_device_fb,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
@@ -115,14 +219,37 @@ static struct platform_device *smdkv210_devices[] __initdata = {
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_i2c2,
- &samsung_device_keypad,
&s3c_device_rtc,
&s3c_device_ts,
&s3c_device_wdt,
+ &s5pv210_device_ac97,
+ &s5pv210_device_iis0,
+ &s5pv210_device_spdif,
+ &samsung_device_keypad,
+ &smdkv210_dm9000,
+ &smdkv210_lcd_lte480wv,
};
+static void __init smdkv210_dm9000_init(void)
+{
+ unsigned int tmp;
+
+ gpio_request(S5PV210_MP01(5), "nCS5");
+ s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
+ gpio_free(S5PV210_MP01(5));
+
+ tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BC5);
+
+ tmp = __raw_readl(S5P_SROM_BW);
+ tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
+ tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BW);
+}
+
static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
@@ -150,6 +277,8 @@ static void __init smdkv210_machine_init(void)
{
s3c_pm_init();
+ smdkv210_dm9000_init();
+
samsung_keypad_set_platdata(&smdkv210_keypad_data);
s3c24xx_ts_set_platdata(&s3c_ts_platform);
@@ -165,6 +294,8 @@ static void __init smdkv210_machine_init(void)
s3c_ide_set_platdata(&smdkv210_ide_pdata);
+ s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
+
platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
}
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
index 1150b360f38c..b7aa3cd2198a 100644
--- a/arch/arm/mach-s5pv310/Kconfig
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -11,9 +11,15 @@ if ARCH_S5PV310
config CPU_S5PV310
bool
+ select S3C_PL330_DMA
help
Enable S5PV310 CPU support
+config S5PV310_DEV_PD
+ bool
+ help
+ Compile in platform device definitions for Power Domain
+
config S5PV310_SETUP_I2C1
bool
help
@@ -69,10 +75,13 @@ config MACH_SMDKC210
select CPU_S5PV310
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select S3C_DEV_I2C1
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
+ select S5PV310_DEV_PD
+ select S5PV310_SETUP_I2C1
select S5PV310_SETUP_SDHCI
help
Machine support for Samsung SMDKC210
@@ -82,6 +91,10 @@ config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board"
select CPU_S5PV310
select S5P_DEV_ONENAND
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S5PV310_SETUP_SDHCI
select S3C_DEV_I2C1
select S5PV310_SETUP_I2C1
help
@@ -97,10 +110,13 @@ config MACH_SMDKV310
select CPU_S5PV310
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select S3C_DEV_I2C1
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
+ select S5PV310_DEV_PD
+ select S5PV310_SETUP_I2C1
select S5PV310_SETUP_SDHCI
help
Machine support for Samsung SMDKV310
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
index 84afc64e7c01..651f1933e228 100644
--- a/arch/arm/mach-s5pv310/Makefile
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -13,7 +13,8 @@ obj- :=
# Core support for S5PV310 system
obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o
+obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
@@ -27,6 +28,9 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
# device support
+obj-y += dev-audio.o
+obj-$(CONFIG_S5PV310_DEV_PD) += dev-pd.o
+
obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
index 58c9d33f36fe..753fa4465876 100644
--- a/arch/arm/mach-s5pv310/clock.c
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -244,7 +244,7 @@ static struct clksrc_clk clk_mout_corebus = {
.id = -1,
},
.sources = &clkset_mout_corebus,
- .reg_src = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 },
+ .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
};
static struct clksrc_clk clk_sclk_dmc = {
@@ -253,7 +253,7 @@ static struct clksrc_clk clk_sclk_dmc = {
.id = -1,
.parent = &clk_mout_corebus.clk,
},
- .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 },
+ .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
};
static struct clksrc_clk clk_aclk_cored = {
@@ -262,7 +262,7 @@ static struct clksrc_clk clk_aclk_cored = {
.id = -1,
.parent = &clk_sclk_dmc.clk,
},
- .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 },
+ .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
};
static struct clksrc_clk clk_aclk_corep = {
@@ -271,7 +271,7 @@ static struct clksrc_clk clk_aclk_corep = {
.id = -1,
.parent = &clk_aclk_cored.clk,
},
- .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 },
+ .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
};
static struct clksrc_clk clk_aclk_acp = {
@@ -280,7 +280,7 @@ static struct clksrc_clk clk_aclk_acp = {
.id = -1,
.parent = &clk_mout_corebus.clk,
},
- .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 },
+ .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
};
static struct clksrc_clk clk_pclk_acp = {
@@ -289,7 +289,7 @@ static struct clksrc_clk clk_pclk_acp = {
.id = -1,
.parent = &clk_aclk_acp.clk,
},
- .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 },
+ .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
};
/* Core list of CMU_TOP side */
@@ -467,6 +467,16 @@ static struct clk init_clocks_disable[] = {
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 10),
}, {
+ .name = "pdma",
+ .id = 0,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "pdma",
+ .id = 1,
+ .enable = s5pv310_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
.name = "adc",
.id = -1,
.enable = s5pv310_clk_ip_peril_ctrl,
@@ -507,6 +517,26 @@ static struct clk init_clocks_disable[] = {
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 18),
}, {
+ .name = "iis",
+ .id = 0,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "iis",
+ .id = 1,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "iis",
+ .id = 2,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .enable = s5pv310_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
.name = "fimg2d",
.id = -1,
.enable = s5pv310_clk_ip_image_ctrl,
@@ -990,6 +1020,17 @@ static struct clksrc_clk *sysclks[] = {
&clk_dout_mmc4,
};
+static int xtal_rate;
+
+static unsigned long s5pv310_fout_apll_get_rate(struct clk *clk)
+{
+ return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
+}
+
+static struct clk_ops s5pv310_fout_apll_ops = {
+ .get_rate = s5pv310_fout_apll_get_rate,
+};
+
void __init_or_cpufreq s5pv310_setup_clocks(void)
{
struct clk *xtal_clk;
@@ -1013,6 +1054,9 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
BUG_ON(IS_ERR(xtal_clk));
xtal = clk_get_rate(xtal_clk);
+
+ xtal_rate = xtal;
+
clk_put(xtal_clk);
printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
@@ -1026,7 +1070,7 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
__raw_readl(S5P_VPLL_CON1), pll_4650);
- clk_fout_apll.rate = apll;
+ clk_fout_apll.ops = &s5pv310_fout_apll_ops;
clk_fout_mpll.rate = mpll;
clk_fout_epll.rate = epll;
clk_fout_vpll.rate = vpll;
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index 82ce4aa6d61a..0db0fb65bd70 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -24,8 +24,6 @@
#include <mach/regs-irq.h>
-void __iomem *gic_cpu_base_addr;
-
extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
unsigned int irq_start);
extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
@@ -43,6 +41,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.length = SZ_128K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_PMU,
+ .pfn = __phys_to_pfn(S5PV310_PA_PMU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S5P_VA_COMBINER_BASE,
.pfn = __phys_to_pfn(S5PV310_PA_COMBINER),
.length = SZ_4K,
@@ -73,6 +76,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.length = SZ_256,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(S5PV310_PA_DMC0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S3C_VA_UART,
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_512K,
@@ -122,11 +130,18 @@ void __init s5pv310_init_irq(void)
{
int irq;
- gic_cpu_base_addr = S5P_VA_GIC_CPU;
- gic_dist_init(0, S5P_VA_GIC_DIST, IRQ_LOCALTIMER);
- gic_cpu_init(0, S5P_VA_GIC_CPU);
+ gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+
+ /*
+ * From SPI(0) to SPI(39) and SPI(51), SPI(53) are
+ * connected to the interrupt combiner. These irqs
+ * should be initialized to support cascade interrupt.
+ */
+ if ((irq >= 40) && !(irq == 51) && !(irq == 53))
+ continue;
+
combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
COMBINER_IRQ(irq, 0));
combiner_cascade_irq(irq, IRQ_SPI(irq));
@@ -168,7 +183,7 @@ static int __init s5pv310_l2x0_cache_init(void)
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
S5P_VA_L2CC + L2X0_POWER_CTRL);
- l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
+ l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
return 0;
}
diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c
new file mode 100644
index 000000000000..b04cbc731128
--- /dev/null
+++ b/arch/arm/mach-s5pv310/cpufreq.c
@@ -0,0 +1,580 @@
+/* linux/arch/arm/mach-s5pv310/cpufreq.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - CPU frequency scaling 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/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+
+#include <plat/clock.h>
+#include <plat/pm.h>
+
+static struct clk *cpu_clk;
+static struct clk *moutcore;
+static struct clk *mout_mpll;
+static struct clk *mout_apll;
+
+#ifdef CONFIG_REGULATOR
+static struct regulator *arm_regulator;
+static struct regulator *int_regulator;
+#endif
+
+static struct cpufreq_freqs freqs;
+static unsigned int memtype;
+
+enum s5pv310_memory_type {
+ DDR2 = 4,
+ LPDDR2,
+ DDR3,
+};
+
+enum cpufreq_level_index {
+ L0, L1, L2, L3, CPUFREQ_LEVEL_END,
+};
+
+static struct cpufreq_frequency_table s5pv310_freq_table[] = {
+ {L0, 1000*1000},
+ {L1, 800*1000},
+ {L2, 400*1000},
+ {L3, 100*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
+ /*
+ * Clock divider value for following
+ * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
+ * DIVATB, DIVPCLK_DBG, DIVAPLL }
+ */
+
+ /* ARM L0: 1000MHz */
+ { 0, 3, 7, 3, 3, 0, 1 },
+
+ /* ARM L1: 800MHz */
+ { 0, 3, 7, 3, 3, 0, 1 },
+
+ /* ARM L2: 400MHz */
+ { 0, 1, 3, 1, 3, 0, 1 },
+
+ /* ARM L3: 100MHz */
+ { 0, 0, 1, 0, 3, 1, 1 },
+};
+
+static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVCOPY, DIVHPM }
+ */
+
+ /* ARM L0: 1000MHz */
+ { 3, 0 },
+
+ /* ARM L1: 800MHz */
+ { 3, 0 },
+
+ /* ARM L2: 400MHz */
+ { 3, 0 },
+
+ /* ARM L3: 100MHz */
+ { 3, 0 },
+};
+
+static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
+ /*
+ * Clock divider value for following
+ * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+ * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
+ */
+
+ /* DMC L0: 400MHz */
+ { 3, 1, 1, 1, 1, 1, 3, 1 },
+
+ /* DMC L1: 400MHz */
+ { 3, 1, 1, 1, 1, 1, 3, 1 },
+
+ /* DMC L2: 266.7MHz */
+ { 7, 1, 1, 2, 1, 1, 3, 1 },
+
+ /* DMC L3: 200MHz */
+ { 7, 1, 1, 3, 1, 1, 3, 1 },
+};
+
+static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
+ /*
+ * Clock divider value for following
+ * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
+ */
+
+ /* ACLK200 L0: 200MHz */
+ { 3, 7, 4, 5, 1 },
+
+ /* ACLK200 L1: 200MHz */
+ { 3, 7, 4, 5, 1 },
+
+ /* ACLK200 L2: 160MHz */
+ { 4, 7, 5, 7, 1 },
+
+ /* ACLK200 L3: 133.3MHz */
+ { 5, 7, 7, 7, 1 },
+};
+
+static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVGDL/R, DIVGPL/R }
+ */
+
+ /* ACLK_GDL/R L0: 200MHz */
+ { 3, 1 },
+
+ /* ACLK_GDL/R L1: 200MHz */
+ { 3, 1 },
+
+ /* ACLK_GDL/R L2: 160MHz */
+ { 4, 1 },
+
+ /* ACLK_GDL/R L3: 133.3MHz */
+ { 5, 1 },
+};
+
+struct cpufreq_voltage_table {
+ unsigned int index; /* any */
+ unsigned int arm_volt; /* uV */
+ unsigned int int_volt;
+};
+
+static struct cpufreq_voltage_table s5pv310_volt_table[CPUFREQ_LEVEL_END] = {
+ {
+ .index = L0,
+ .arm_volt = 1200000,
+ .int_volt = 1100000,
+ }, {
+ .index = L1,
+ .arm_volt = 1100000,
+ .int_volt = 1100000,
+ }, {
+ .index = L2,
+ .arm_volt = 1000000,
+ .int_volt = 1000000,
+ }, {
+ .index = L3,
+ .arm_volt = 900000,
+ .int_volt = 1000000,
+ },
+};
+
+static unsigned int s5pv310_apll_pms_table[CPUFREQ_LEVEL_END] = {
+ /* APLL FOUT L0: 1000MHz */
+ ((250 << 16) | (6 << 8) | 1),
+
+ /* APLL FOUT L1: 800MHz */
+ ((200 << 16) | (6 << 8) | 1),
+
+ /* APLL FOUT L2 : 400MHz */
+ ((200 << 16) | (6 << 8) | 2),
+
+ /* APLL FOUT L3: 100MHz */
+ ((200 << 16) | (6 << 8) | 4),
+};
+
+int s5pv310_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, s5pv310_freq_table);
+}
+
+unsigned int s5pv310_getspeed(unsigned int cpu)
+{
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+void s5pv310_set_clkdiv(unsigned int div_index)
+{
+ unsigned int tmp;
+
+ /* Change Divider - CPU0 */
+
+ tmp = __raw_readl(S5P_CLKDIV_CPU);
+
+ tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
+ S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
+ S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
+ S5P_CLKDIV_CPU0_APLL_MASK);
+
+ tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
+ (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
+ (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
+ (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
+ (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
+ (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
+ (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
+
+ __raw_writel(tmp, S5P_CLKDIV_CPU);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STATCPU);
+ } while (tmp & 0x1111111);
+
+ /* Change Divider - CPU1 */
+
+ tmp = __raw_readl(S5P_CLKDIV_CPU1);
+
+ tmp &= ~((0x7 << 4) | 0x7);
+
+ tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
+ (clkdiv_cpu1[div_index][1] << 0));
+
+ __raw_writel(tmp, S5P_CLKDIV_CPU1);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
+ } while (tmp & 0x11);
+
+ /* Change Divider - DMC0 */
+
+ tmp = __raw_readl(S5P_CLKDIV_DMC0);
+
+ tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
+ S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
+ S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
+ S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
+
+ tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
+ (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+ (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
+ (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
+ (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
+ (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
+ (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
+ (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
+
+ __raw_writel(tmp, S5P_CLKDIV_DMC0);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
+ } while (tmp & 0x11111111);
+
+ /* Change Divider - TOP */
+
+ tmp = __raw_readl(S5P_CLKDIV_TOP);
+
+ tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
+ S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
+ S5P_CLKDIV_TOP_ONENAND_MASK);
+
+ tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
+ (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
+ (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
+ (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
+ (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
+
+ __raw_writel(tmp, S5P_CLKDIV_TOP);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
+ } while (tmp & 0x11111);
+
+ /* Change Divider - LEFTBUS */
+
+ tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
+
+ tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - RIGHTBUS */
+
+ tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
+
+ tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
+
+ do {
+ tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
+ } while (tmp & 0x11);
+}
+
+static void s5pv310_set_apll(unsigned int index)
+{
+ unsigned int tmp;
+
+ /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
+ clk_set_parent(moutcore, mout_mpll);
+
+ do {
+ tmp = (__raw_readl(S5P_CLKMUX_STATCPU)
+ >> S5P_CLKSRC_CPU_MUXCORE_SHIFT);
+ tmp &= 0x7;
+ } while (tmp != 0x2);
+
+ /* 2. Set APLL Lock time */
+ __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK);
+
+ /* 3. Change PLL PMS values */
+ tmp = __raw_readl(S5P_APLL_CON0);
+ tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+ tmp |= s5pv310_apll_pms_table[index];
+ __raw_writel(tmp, S5P_APLL_CON0);
+
+ /* 4. wait_lock_time */
+ do {
+ tmp = __raw_readl(S5P_APLL_CON0);
+ } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT)));
+
+ /* 5. MUX_CORE_SEL = APLL */
+ clk_set_parent(moutcore, mout_apll);
+
+ do {
+ tmp = __raw_readl(S5P_CLKMUX_STATCPU);
+ tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK;
+ } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
+}
+
+static void s5pv310_set_frequency(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int tmp;
+
+ if (old_index > new_index) {
+ /* The frequency changing to L0 needs to change apll */
+ if (freqs.new == s5pv310_freq_table[L0].frequency) {
+ /* 1. Change the system clock divider values */
+ s5pv310_set_clkdiv(new_index);
+
+ /* 2. Change the apll m,p,s value */
+ s5pv310_set_apll(new_index);
+ } else {
+ /* 1. Change the system clock divider values */
+ s5pv310_set_clkdiv(new_index);
+
+ /* 2. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(S5P_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, S5P_APLL_CON0);
+ }
+ }
+
+ else if (old_index < new_index) {
+ /* The frequency changing from L0 needs to change apll */
+ if (freqs.old == s5pv310_freq_table[L0].frequency) {
+ /* 1. Change the apll m,p,s value */
+ s5pv310_set_apll(new_index);
+
+ /* 2. Change the system clock divider values */
+ s5pv310_set_clkdiv(new_index);
+ } else {
+ /* 1. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(S5P_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, S5P_APLL_CON0);
+
+ /* 2. Change the system clock divider values */
+ s5pv310_set_clkdiv(new_index);
+ }
+ }
+}
+
+static int s5pv310_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int index, old_index;
+ unsigned int arm_volt, int_volt;
+
+ freqs.old = s5pv310_getspeed(policy->cpu);
+
+ if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
+ freqs.old, relation, &old_index))
+ return -EINVAL;
+
+ if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ freqs.new = s5pv310_freq_table[index].frequency;
+ freqs.cpu = policy->cpu;
+
+ if (freqs.new == freqs.old)
+ return 0;
+
+ /* get the voltage value */
+ arm_volt = s5pv310_volt_table[index].arm_volt;
+ int_volt = s5pv310_volt_table[index].int_volt;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* control regulator */
+ if (freqs.new > freqs.old) {
+ /* Voltage up */
+#ifdef CONFIG_REGULATOR
+ regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
+ regulator_set_voltage(int_regulator, int_volt, int_volt);
+#endif
+ }
+
+ /* Clock Configuration Procedure */
+ s5pv310_set_frequency(old_index, index);
+
+ /* control regulator */
+ if (freqs.new < freqs.old) {
+ /* Voltage down */
+#ifdef CONFIG_REGULATOR
+ regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
+ regulator_set_voltage(int_regulator, int_volt, int_volt);
+#endif
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy,
+ pm_message_t pmsg)
+{
+ return 0;
+}
+
+static int s5pv310_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+#endif
+
+static int s5pv310_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ policy->cur = policy->min = policy->max = s5pv310_getspeed(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(s5pv310_freq_table, policy->cpu);
+
+ /* set the transition latency value */
+ policy->cpuinfo.transition_latency = 100000;
+
+ /*
+ * S5PV310 multi-core processors has 2 cores
+ * that the frequency cannot be set independently.
+ * Each cpu is bound to the same speed.
+ * So the affected cpu is all of the cpus.
+ */
+ cpumask_setall(policy->cpus);
+
+ return cpufreq_frequency_table_cpuinfo(policy, s5pv310_freq_table);
+}
+
+static struct cpufreq_driver s5pv310_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = s5pv310_verify_speed,
+ .target = s5pv310_target,
+ .get = s5pv310_getspeed,
+ .init = s5pv310_cpufreq_cpu_init,
+ .name = "s5pv310_cpufreq",
+#ifdef CONFIG_PM
+ .suspend = s5pv310_cpufreq_suspend,
+ .resume = s5pv310_cpufreq_resume,
+#endif
+};
+
+static int __init s5pv310_cpufreq_init(void)
+{
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ moutcore = clk_get(NULL, "moutcore");
+ if (IS_ERR(moutcore))
+ goto out;
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll))
+ goto out;
+
+ mout_apll = clk_get(NULL, "mout_apll");
+ if (IS_ERR(mout_apll))
+ goto out;
+
+#ifdef CONFIG_REGULATOR
+ arm_regulator = regulator_get(NULL, "vdd_arm");
+ if (IS_ERR(arm_regulator)) {
+ printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
+ goto out;
+ }
+
+ int_regulator = regulator_get(NULL, "vdd_int");
+ if (IS_ERR(int_regulator)) {
+ printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
+ goto out;
+ }
+#endif
+
+ /*
+ * Check DRAM type.
+ * Because DVFS level is different according to DRAM type.
+ */
+ memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
+ memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
+ memtype &= S5P_DMC0_MEMTYPE_MASK;
+
+ if ((memtype < DDR2) && (memtype > DDR3)) {
+ printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
+ goto out;
+ } else {
+ printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
+ }
+
+ return cpufreq_register_driver(&s5pv310_driver);
+
+out:
+ if (!IS_ERR(cpu_clk))
+ clk_put(cpu_clk);
+
+ if (!IS_ERR(moutcore))
+ clk_put(moutcore);
+
+ if (!IS_ERR(mout_mpll))
+ clk_put(mout_mpll);
+
+ if (!IS_ERR(mout_apll))
+ clk_put(mout_apll);
+
+#ifdef CONFIG_REGULATOR
+ if (!IS_ERR(arm_regulator))
+ regulator_put(arm_regulator);
+
+ if (!IS_ERR(int_regulator))
+ regulator_put(int_regulator);
+#endif
+
+ printk(KERN_ERR "%s: failed initialization\n", __func__);
+
+ return -EINVAL;
+}
+late_initcall(s5pv310_cpufreq_init);
diff --git a/arch/arm/mach-s5pv310/dev-audio.c b/arch/arm/mach-s5pv310/dev-audio.c
new file mode 100644
index 000000000000..a1964242f0fa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-audio.c
@@ -0,0 +1,364 @@
+/* linux/arch/arm/mach-s5pv310/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. 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/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static const char *rclksrc[] = {
+ [0] = "busclk",
+ [1] = "i2sclk",
+};
+
+static int s5pv310_cfg_i2s(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2));
+ break;
+ case 1:
+ s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4));
+ break;
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata i2sv5_pdata = {
+ .cfg_gpio = s5pv310_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource s5pv310_i2s0_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_I2S0,
+ .end = S5PV310_PA_I2S0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_TX,
+ .end = DMACH_I2S0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_RX,
+ .end = DMACH_I2S0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMACH_I2S0S_TX,
+ .end = DMACH_I2S0S_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5pv310_device_i2s0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv310_i2s0_resource),
+ .resource = s5pv310_i2s0_resource,
+ .dev = {
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "sclk_i2s",
+ [1] = "no_such_clock",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5pv310_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_NO_MUXPSR,
+ .src_clk = rclksrc_v3,
+ },
+ },
+};
+
+static struct resource s5pv310_i2s1_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_I2S1,
+ .end = S5PV310_PA_I2S1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S1_TX,
+ .end = DMACH_I2S1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S1_RX,
+ .end = DMACH_I2S1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5pv310_device_i2s1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv310_i2s1_resource),
+ .resource = s5pv310_i2s1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+static struct resource s5pv310_i2s2_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_I2S2,
+ .end = S5PV310_PA_I2S2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S2_TX,
+ .end = DMACH_I2S2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S2_RX,
+ .end = DMACH_I2S2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5pv310_device_i2s2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pv310_i2s2_resource),
+ .resource = s5pv310_i2s2_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3));
+ break;
+ case 1:
+ s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3));
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+ .cfg_gpio = s5pv310_pcm_cfg_gpio,
+};
+
+static struct resource s5pv310_pcm0_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_PCM0,
+ .end = S5PV310_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,
+ },
+};
+
+struct platform_device s5pv310_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv310_pcm0_resource),
+ .resource = s5pv310_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource s5pv310_pcm1_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_PCM1,
+ .end = S5PV310_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,
+ },
+};
+
+struct platform_device s5pv310_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv310_pcm1_resource),
+ .resource = s5pv310_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource s5pv310_pcm2_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_PCM2,
+ .end = S5PV310_PA_PCM2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM2_TX,
+ .end = DMACH_PCM2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM2_RX,
+ .end = DMACH_PCM2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5pv310_device_pcm2 = {
+ .name = "samsung-pcm",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pv310_pcm2_resource),
+ .resource = s5pv310_pcm2_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+/* AC97 Controller platform devices */
+
+static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource s5pv310_ac97_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_AC97,
+ .end = S5PV310_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 = {
+ .cfg_gpio = s5pv310_ac97_cfg_gpio,
+};
+
+static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv310_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pv310_ac97_resource),
+ .resource = s5pv310_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s5pv310_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* S/PDIF Controller platform_device */
+
+static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s5pv310_spdif_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_SPDIF,
+ .end = S5PV310_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+ .cfg_gpio = s5pv310_spdif_cfg_gpio,
+};
+
+static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv310_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pv310_spdif_resource),
+ .resource = s5pv310_spdif_resource,
+ .dev = {
+ .platform_data = &samsung_spdif_pdata,
+ .dma_mask = &s5pv310_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c
new file mode 100644
index 000000000000..58a50c2d0b67
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-pd.c
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-s5pv310/dev-pd.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - Power Domain 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/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/regs-pmu.h>
+
+#include <plat/pd.h>
+
+static int s5pv310_pd_enable(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ u32 timeout;
+
+ __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
+
+ /* Wait max 1ms */
+ timeout = 10;
+ while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
+ != S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ printk(KERN_ERR "Power domain %s enable failed.\n",
+ dev_name(dev));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ udelay(100);
+ }
+
+ return 0;
+}
+
+static int s5pv310_pd_disable(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ u32 timeout;
+
+ __raw_writel(0, pdata->base);
+
+ /* Wait max 1ms */
+ timeout = 10;
+ while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ printk(KERN_ERR "Power domain %s disable failed.\n",
+ dev_name(dev));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ udelay(100);
+ }
+
+ return 0;
+}
+
+struct platform_device s5pv310_device_pd[] = {
+ {
+ .name = "samsung-pd",
+ .id = 0,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_MFC_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 1,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_G3D_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 2,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_LCD0_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 3,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_LCD1_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 4,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_TV_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 5,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_CAM_CONF,
+ },
+ },
+ }, {
+ .name = "samsung-pd",
+ .id = 6,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .enable = s5pv310_pd_enable,
+ .disable = s5pv310_pd_disable,
+ .base = S5P_PMU_GPS_CONF,
+ },
+ },
+ },
+};
diff --git a/arch/arm/mach-s5pv310/dma.c b/arch/arm/mach-s5pv310/dma.c
new file mode 100644
index 000000000000..20066c7c9e56
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dma.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. 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 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/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5pv310_pdma0_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_PDMA0,
+ .end = S5PV310_PA_PDMA0 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA0,
+ .end = IRQ_PDMA0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv310_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM2_RX,
+ [3] = DMACH_PCM2_TX,
+ [4] = DMACH_MSM_REQ0,
+ [5] = DMACH_MSM_REQ2,
+ [6] = DMACH_SPI0_RX,
+ [7] = DMACH_SPI0_TX,
+ [8] = DMACH_SPI2_RX,
+ [9] = DMACH_SPI2_TX,
+ [10] = DMACH_I2S0S_TX,
+ [11] = DMACH_I2S0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S2_RX,
+ [14] = DMACH_I2S2_TX,
+ [15] = DMACH_UART0_RX,
+ [16] = DMACH_UART0_TX,
+ [17] = DMACH_UART2_RX,
+ [18] = DMACH_UART2_TX,
+ [19] = DMACH_UART4_RX,
+ [20] = DMACH_UART4_TX,
+ [21] = DMACH_SLIMBUS0_RX,
+ [22] = DMACH_SLIMBUS0_TX,
+ [23] = DMACH_SLIMBUS2_RX,
+ [24] = DMACH_SLIMBUS2_TX,
+ [25] = DMACH_SLIMBUS4_RX,
+ [26] = DMACH_SLIMBUS4_TX,
+ [27] = DMACH_AC97_MICIN,
+ [28] = DMACH_AC97_PCMIN,
+ [29] = DMACH_AC97_PCMOUT,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct platform_device s5pv310_device_pdma0 = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv310_pdma0_resource),
+ .resource = s5pv310_pdma0_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv310_pdma0_pdata,
+ },
+};
+
+static struct resource s5pv310_pdma1_resource[] = {
+ [0] = {
+ .start = S5PV310_PA_PDMA1,
+ .end = S5PV310_PA_PDMA1 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA1,
+ .end = IRQ_PDMA1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv310_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM1_RX,
+ [3] = DMACH_PCM1_TX,
+ [4] = DMACH_MSM_REQ1,
+ [5] = DMACH_MSM_REQ3,
+ [6] = DMACH_SPI1_RX,
+ [7] = DMACH_SPI1_TX,
+ [8] = DMACH_I2S0S_TX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S1_RX,
+ [12] = DMACH_I2S1_TX,
+ [13] = DMACH_UART0_RX,
+ [14] = DMACH_UART0_TX,
+ [15] = DMACH_UART1_RX,
+ [16] = DMACH_UART1_TX,
+ [17] = DMACH_UART3_RX,
+ [18] = DMACH_UART3_TX,
+ [19] = DMACH_SLIMBUS1_RX,
+ [20] = DMACH_SLIMBUS1_TX,
+ [21] = DMACH_SLIMBUS3_RX,
+ [22] = DMACH_SLIMBUS3_TX,
+ [23] = DMACH_SLIMBUS5_RX,
+ [24] = DMACH_SLIMBUS5_TX,
+ [25] = DMACH_SLIMBUS0AUX_RX,
+ [26] = DMACH_SLIMBUS0AUX_TX,
+ [27] = DMACH_SPDIF,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct platform_device s5pv310_device_pdma1 = {
+ .name = "s3c-pl330",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv310_pdma1_resource),
+ .resource = s5pv310_pdma1_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv310_pdma1_pdata,
+ },
+};
+
+static struct platform_device *s5pv310_dmacs[] __initdata = {
+ &s5pv310_device_pdma0,
+ &s5pv310_device_pdma1,
+};
+
+static int __init s5pv310_dma_init(void)
+{
+ platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs));
+
+ return 0;
+}
+arch_initcall(s5pv310_dma_init);
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
index 03652c3605f6..afa5392d9fc0 100644
--- a/arch/arm/mach-s5pv310/hotplug.c
+++ b/arch/arm/mach-s5pv310/hotplug.c
@@ -13,14 +13,11 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/completion.h>
#include <asm/cacheflush.h>
extern volatile int pen_release;
-static DECLARE_COMPLETION(cpu_killed);
-
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void)
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
- " bic %0, %0, #0x20\n"
+ " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
- : "r" (0)
+ : "r" (0), "Ir" (CR_C)
: "cc");
}
@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void)
asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n"
- " orr %0, %0, #0x04\n"
+ " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
- :
+ : "Ir" (CR_C)
: "cc");
}
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{
/*
* there is no power-control hardware on this platform, so all
@@ -83,22 +80,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
}
/*
- * getting here, means that we have come out of WFI without
+ * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
- * The trouble is, letting people know about this is not really
- * possible, since we are currently running incoherently, and
- * therefore cannot safely call printk() or anything else
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
*/
-#ifdef DEBUG
- printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
-#endif
+ (*spurious)++;
}
}
int platform_cpu_kill(unsigned int cpu)
{
- return wait_for_completion_timeout(&cpu_killed, 5000);
+ return 1;
}
/*
@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
-#ifdef DEBUG
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
-#endif
-
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
+ int spurious = 0;
/*
* we're ready for shutdown now, so do it
*/
cpu_enter_lowpower();
- platform_do_lowpower(cpu);
+ platform_do_lowpower(cpu, &spurious);
/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-s5pv310/include/mach/dma.h b/arch/arm/mach-s5pv310/include/mach/dma.h
new file mode 100644
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/dma.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 99e7dad8a85a..1dd130a34782 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -25,6 +25,8 @@
#define IRQ_SPI(x) S5P_IRQ(x+32)
+#define IRQ_MCT1 IRQ_SPI(35)
+
#define IRQ_EINT0 IRQ_SPI(40)
#define IRQ_EINT1 IRQ_SPI(41)
#define IRQ_EINT2 IRQ_SPI(42)
@@ -36,9 +38,8 @@
#define IRQ_JPEG IRQ_SPI(48)
#define IRQ_2D IRQ_SPI(49)
#define IRQ_PCIE IRQ_SPI(50)
-#define IRQ_SYSTEM_TIMER IRQ_SPI(51)
+#define IRQ_MCT0 IRQ_SPI(51)
#define IRQ_MFC IRQ_SPI(52)
-#define IRQ_WDT IRQ_SPI(53)
#define IRQ_AUDIO_SS IRQ_SPI(54)
#define IRQ_AC97 IRQ_SPI(55)
#define IRQ_SPDIF IRQ_SPI(56)
@@ -54,6 +55,9 @@
#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
+#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
+#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
+
#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
@@ -83,8 +87,13 @@
#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
+#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
+#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
+
#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
+#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
+
#define IRQ_EINT4 COMBINER_IRQ(37, 0)
#define IRQ_EINT5 COMBINER_IRQ(37, 1)
#define IRQ_EINT6 COMBINER_IRQ(37, 2)
@@ -101,7 +110,11 @@
#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
-#define MAX_COMBINER_NR 40
+#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
+
+#define IRQ_WDT COMBINER_IRQ(53, 0)
+
+#define MAX_COMBINER_NR 54
#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index 7acf4e77e92e..33bcff2a9568 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -39,11 +39,15 @@
#define S5PV310_PA_SYSCON (0x10010000)
#define S5P_PA_SYSCON S5PV310_PA_SYSCON
+#define S5PV310_PA_PMU (0x10020000)
+
#define S5PV310_PA_CMU (0x10030000)
#define S5PV310_PA_WATCHDOG (0x10060000)
#define S5PV310_PA_RTC (0x10070000)
+#define S5PV310_PA_DMC0 (0x10400000)
+
#define S5PV310_PA_COMBINER (0x10448000)
#define S5PV310_PA_COREPERI (0x10500000)
@@ -52,13 +56,38 @@
#define S5PV310_PA_GIC_DIST (0x10501000)
#define S5PV310_PA_L2CC (0x10502000)
+/* DMA */
+#define S5PV310_PA_MDMA 0x10810000
+#define S5PV310_PA_PDMA0 0x12680000
+#define S5PV310_PA_PDMA1 0x12690000
+
#define S5PV310_PA_GPIO1 (0x11400000)
#define S5PV310_PA_GPIO2 (0x11000000)
#define S5PV310_PA_GPIO3 (0x03860000)
+#define S5PV310_PA_MIPI_CSIS0 0x11880000
+#define S5PV310_PA_MIPI_CSIS1 0x11890000
+
#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define S5PV310_PA_SROMC (0x12570000)
+#define S5P_PA_SROMC S5PV310_PA_SROMC
+
+/* S/PDIF */
+#define S5PV310_PA_SPDIF 0xE1100000
+
+/* I2S */
+#define S5PV310_PA_I2S0 0x03830000
+#define S5PV310_PA_I2S1 0xE3100000
+#define S5PV310_PA_I2S2 0xE2A00000
+
+/* PCM */
+#define S5PV310_PA_PCM0 0x03840000
+#define S5PV310_PA_PCM1 0x13980000
+#define S5PV310_PA_PCM2 0x13990000
+
+/* AC97 */
+#define S5PV310_PA_AC97 0x139A0000
#define S5PV310_PA_UART (0x13800000)
@@ -95,5 +124,7 @@
#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
#define S3C_PA_RTC S5PV310_PA_RTC
#define S3C_PA_WDT S5PV310_PA_WATCHDOG
+#define S5P_PA_MIPI_CSIS0 S5PV310_PA_MIPI_CSIS0
+#define S5P_PA_MIPI_CSIS1 S5PV310_PA_MIPI_CSIS1
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
index f1028cad9788..b5c4ada1cff5 100644
--- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
@@ -19,6 +19,12 @@
#define S5P_INFORM0 S5P_CLKREG(0x800)
+#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
+#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
+
+#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
+#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
+
#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
@@ -58,6 +64,8 @@
#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
+#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
+
#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
@@ -66,8 +74,9 @@
#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
-#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
-#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
+#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
+#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
+#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
@@ -80,10 +89,77 @@
#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
+#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
+#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
+/* APLL_LOCK */
+#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
+
+/* APLL_CON0 */
+#define S5P_APLLCON0_ENABLE_SHIFT (31)
+#define S5P_APLLCON0_LOCKED_SHIFT (29)
+#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
+#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
+
+/* CLK_SRC_CPU */
+#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
+#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
+
+/* CLKDIV_CPU0 */
+#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
+#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
+#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
+#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
+#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
+#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
+#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
+#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
+#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
+#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
+#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
+#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
+#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
+#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
+
+/* CLKDIV_DMC0 */
+#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
+#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
+#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
+#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
+#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
+#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
+#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
+#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
+#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
+#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
+#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
+#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
+#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
+#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
+#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
+#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
+
+/* CLKDIV_TOP */
+#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
+#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
+#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
+#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
+#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
+#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
+#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
+
+/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
+#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
+#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
+#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
+#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
+
/* Compatibility defines */
#define S5P_EPLL_CON S5P_EPLL_CON0
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-mem.h b/arch/arm/mach-s5pv310/include/mach/regs-mem.h
new file mode 100644
index 000000000000..834227140eaa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-mem.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - SROMC and DMC 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_MEM_H
+#define __ASM_ARCH_REGS_MEM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_DMC0_MEMCON_OFFSET 0x04
+
+#define S5P_DMC0_MEMTYPE_SHIFT 8
+#define S5P_DMC0_MEMTYPE_MASK 0xF
+
+#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-pmu.h b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
new file mode 100644
index 000000000000..fb333d0f6073
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV310 - Power management unit 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_REGS_PMU_H
+#define __ASM_ARCH_REGS_PMU_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
+
+#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
+#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
+#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
+#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
+#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
+#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
+#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
+
+#define S5P_INT_LOCAL_PWR_EN 0x7
+
+#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-srom.h b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
deleted file mode 100644
index 1898b3e10550..000000000000
--- a/arch/arm/mach-s5pv310/include/mach/regs-srom.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * S5PV310 - SROMC 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_SROM_H
-#define __ASM_ARCH_REGS_SROM_H __FILE__
-
-#include <mach/map.h>
-
-#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
-
-#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
-#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
-#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
-#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
-#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
-
-/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
-
-#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
-#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
-#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
-#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
-
-#define S5PV310_SROM_BW__CS_MASK 0xf
-
-#define S5PV310_SROM_BW__NCS0__SHIFT 0
-#define S5PV310_SROM_BW__NCS1__SHIFT 4
-#define S5PV310_SROM_BW__NCS2__SHIFT 8
-#define S5PV310_SROM_BW__NCS3__SHIFT 12
-
-/* applies to same to BCS0 - BCS3 */
-
-#define S5PV310_SROM_BCX__PMC__SHIFT 0
-#define S5PV310_SROM_BCX__TACP__SHIFT 4
-#define S5PV310_SROM_BCX__TCAH__SHIFT 8
-#define S5PV310_SROM_BCX__TCOH__SHIFT 12
-#define S5PV310_SROM_BCX__TACC__SHIFT 16
-#define S5PV310_SROM_BCX__TCOS__SHIFT 24
-#define S5PV310_SROM_BCX__TACS__SHIFT 28
-
-#endif /* __ASM_ARCH_REGS_SROM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index b7ec252384f4..393ccbd52c4a 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,16 +7,13 @@
#define ASM_ARCH_SMP_H __FILE__
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
-
-extern void __iomem *gic_cpu_base_addr;
/*
* We use IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c
index c3f88c3faf6c..1ea4a9e83bbe 100644
--- a/arch/arm/mach-s5pv310/irq-combiner.c
+++ b/arch/arm/mach-s5pv310/irq-combiner.c
@@ -24,29 +24,32 @@ static DEFINE_SPINLOCK(irq_controller_lock);
struct combiner_chip_data {
unsigned int irq_offset;
+ unsigned int irq_mask;
void __iomem *base;
};
static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
-static inline void __iomem *combiner_base(unsigned int irq)
+static inline void __iomem *combiner_base(struct irq_data *data)
{
- struct combiner_chip_data *combiner_data = get_irq_chip_data(irq);
+ struct combiner_chip_data *combiner_data =
+ irq_data_get_irq_chip_data(data);
+
return combiner_data->base;
}
-static void combiner_mask_irq(unsigned int irq)
+static void combiner_mask_irq(struct irq_data *data)
{
- u32 mask = 1 << (irq % 32);
+ u32 mask = 1 << (data->irq % 32);
- __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_CLEAR);
+ __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
}
-static void combiner_unmask_irq(unsigned int irq)
+static void combiner_unmask_irq(struct irq_data *data)
{
- u32 mask = 1 << (irq % 32);
+ u32 mask = 1 << (data->irq % 32);
- __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_SET);
+ __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
}
static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
@@ -57,11 +60,12 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
unsigned long status;
/* primary controller ack'ing */
- chip->ack(irq);
+ chip->irq_ack(&desc->irq_data);
spin_lock(&irq_controller_lock);
status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
spin_unlock(&irq_controller_lock);
+ status &= chip_data->irq_mask;
if (status == 0)
goto out;
@@ -76,13 +80,13 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
out:
/* primary controller unmasking */
- chip->unmask(irq);
+ chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip combiner_chip = {
.name = "COMBINER",
- .mask = combiner_mask_irq,
- .unmask = combiner_unmask_irq,
+ .irq_mask = combiner_mask_irq,
+ .irq_unmask = combiner_unmask_irq,
};
void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
@@ -104,10 +108,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
combiner_data[combiner_nr].base = base;
combiner_data[combiner_nr].irq_offset = irq_start;
+ combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
/* Disable all interrupts */
- __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR);
+ __raw_writel(combiner_data[combiner_nr].irq_mask,
+ base + COMBINER_ENABLE_CLEAR);
/* Setup the Linux IRQ subsystem */
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
index 5877503e92c3..477bd9e97f0f 100644
--- a/arch/arm/mach-s5pv310/irq-eint.c
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -48,42 +48,43 @@ static unsigned int s5pv310_get_irq_nr(unsigned int number)
return ret;
}
-static inline void s5pv310_irq_eint_mask(unsigned int irq)
+static inline void s5pv310_irq_eint_mask(struct irq_data *data)
{
u32 mask;
spin_lock(&eint_lock);
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
- mask |= eint_irq_to_bit(irq);
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask |= eint_irq_to_bit(data->irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
spin_unlock(&eint_lock);
}
-static void s5pv310_irq_eint_unmask(unsigned int irq)
+static void s5pv310_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
spin_lock(&eint_lock);
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
- mask &= ~(eint_irq_to_bit(irq));
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask &= ~(eint_irq_to_bit(data->irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
spin_unlock(&eint_lock);
}
-static inline void s5pv310_irq_eint_ack(unsigned int irq)
+static inline void s5pv310_irq_eint_ack(struct irq_data *data)
{
- __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
}
-static void s5pv310_irq_eint_maskack(unsigned int irq)
+static void s5pv310_irq_eint_maskack(struct irq_data *data)
{
- s5pv310_irq_eint_mask(irq);
- s5pv310_irq_eint_ack(irq);
+ s5pv310_irq_eint_mask(data);
+ s5pv310_irq_eint_ack(data);
}
-static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
+static int s5pv310_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
- int offs = EINT_OFFSET(irq);
+ int offs = EINT_OFFSET(data->irq);
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
@@ -118,10 +119,10 @@ static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
mask = 0x7 << shift;
spin_lock(&eint_lock);
- ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
ctrl &= ~mask;
ctrl |= newvalue << shift;
- __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
spin_unlock(&eint_lock);
switch (offs) {
@@ -146,13 +147,13 @@ static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
static struct irq_chip s5pv310_irq_eint = {
.name = "s5pv310-eint",
- .mask = s5pv310_irq_eint_mask,
- .unmask = s5pv310_irq_eint_unmask,
- .mask_ack = s5pv310_irq_eint_maskack,
- .ack = s5pv310_irq_eint_ack,
- .set_type = s5pv310_irq_eint_set_type,
+ .irq_mask = s5pv310_irq_eint_mask,
+ .irq_unmask = s5pv310_irq_eint_unmask,
+ .irq_mask_ack = s5pv310_irq_eint_maskack,
+ .irq_ack = s5pv310_irq_eint_ack,
+ .irq_set_type = s5pv310_irq_eint_set_type,
#ifdef CONFIG_PM
- .set_wake = s3c_irqext_wake,
+ .irq_set_wake = s3c_irqext_wake,
#endif
};
@@ -192,14 +193,14 @@ static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
u32 *irq_data = get_irq_data(irq);
struct irq_chip *chip = get_irq_chip(irq);
- chip->mask(irq);
+ chip->irq_mask(&desc->irq_data);
- if (chip->ack)
- chip->ack(irq);
+ if (chip->irq_ack)
+ chip->irq_ack(&desc->irq_data);
generic_handle_irq(*irq_data);
- chip->unmask(irq);
+ chip->irq_unmask(&desc->irq_data);
}
int __init s5pv310_init_irq_eint(void)
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
index 2b8d4fc52d7c..9262966cd269 100644
--- a/arch/arm/mach-s5pv310/mach-smdkc210.c
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -14,18 +14,21 @@
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
+#include <linux/i2c.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
#include <mach/map.h>
-#include <mach/regs-srom.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -139,13 +142,27 @@ static struct platform_device smdkc210_smsc911x = {
},
};
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {I2C_BOARD_INFO("wm8994", 0x1a),},
+};
+
static struct platform_device *smdkc210_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
+ &s3c_device_i2c1,
&s3c_device_rtc,
&s3c_device_wdt,
+ &s5pv310_device_ac97,
+ &s5pv310_device_i2s0,
+ &s5pv310_device_pd[PD_MFC],
+ &s5pv310_device_pd[PD_G3D],
+ &s5pv310_device_pd[PD_LCD0],
+ &s5pv310_device_pd[PD_LCD1],
+ &s5pv310_device_pd[PD_CAM],
+ &s5pv310_device_pd[PD_TV],
+ &s5pv310_device_pd[PD_GPS],
&smdkc210_smsc911x,
};
@@ -154,23 +171,22 @@ static void __init smdkc210_smsc911x_init(void)
u32 cs1;
/* configure nCS1 width to 16 bits */
- cs1 = __raw_readl(S5PV310_SROM_BW) &
- ~(S5PV310_SROM_BW__CS_MASK <<
- S5PV310_SROM_BW__NCS1__SHIFT);
- cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
- (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
- (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
- S5PV310_SROM_BW__NCS1__SHIFT;
- __raw_writel(cs1, S5PV310_SROM_BW);
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
/* set timing for nCS1 suitable for ethernet chip */
- __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
- (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
- (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
- (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
}
static void __init smdkc210_map_io(void)
@@ -182,6 +198,9 @@ static void __init smdkc210_map_io(void)
static void __init smdkc210_machine_init(void)
{
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
smdkc210_smsc911x_init();
s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 35826d66632c..3eb029ca2073 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -14,18 +14,21 @@
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
+#include <linux/i2c.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
#include <mach/map.h>
-#include <mach/regs-srom.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -139,13 +142,27 @@ static struct platform_device smdkv310_smsc911x = {
},
};
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {I2C_BOARD_INFO("wm8994", 0x1a),},
+};
+
static struct platform_device *smdkv310_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
+ &s3c_device_i2c1,
&s3c_device_rtc,
&s3c_device_wdt,
+ &s5pv310_device_ac97,
+ &s5pv310_device_i2s0,
+ &s5pv310_device_pd[PD_MFC],
+ &s5pv310_device_pd[PD_G3D],
+ &s5pv310_device_pd[PD_LCD0],
+ &s5pv310_device_pd[PD_LCD1],
+ &s5pv310_device_pd[PD_CAM],
+ &s5pv310_device_pd[PD_TV],
+ &s5pv310_device_pd[PD_GPS],
&smdkv310_smsc911x,
};
@@ -154,23 +171,22 @@ static void __init smdkv310_smsc911x_init(void)
u32 cs1;
/* configure nCS1 width to 16 bits */
- cs1 = __raw_readl(S5PV310_SROM_BW) &
- ~(S5PV310_SROM_BW__CS_MASK <<
- S5PV310_SROM_BW__NCS1__SHIFT);
- cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
- (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
- (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
- S5PV310_SROM_BW__NCS1__SHIFT;
- __raw_writel(cs1, S5PV310_SROM_BW);
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
/* set timing for nCS1 suitable for ethernet chip */
- __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
- (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
- (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
- (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
- (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
}
static void __init smdkv310_map_io(void)
@@ -182,6 +198,9 @@ static void __init smdkv310_map_io(void)
static void __init smdkv310_machine_init(void)
{
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
smdkv310_smsc911x_init();
s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c
index 16d8fc00cafd..36bc3cf825e3 100644
--- a/arch/arm/mach-s5pv310/mach-universal_c210.c
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -13,6 +13,9 @@
#include <linux/i2c.h>
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mmc/host.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -21,6 +24,7 @@
#include <plat/s5pv310.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/sdhci.h>
#include <mach/map.h>
@@ -116,6 +120,73 @@ static struct platform_device universal_gpio_keys = {
},
};
+/* eMMC */
+static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
+ .max_width = 8,
+ .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE),
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply mmc0_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
+static struct regulator_init_data mmc0_fixed_voltage_init_data = {
+ .constraints = {
+ .name = "VMEM_VDD_2.8V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies),
+ .consumer_supplies = mmc0_supplies,
+};
+
+static struct fixed_voltage_config mmc0_fixed_voltage_config = {
+ .supply_name = "MASSMEMORY_EN",
+ .microvolts = 2800000,
+ .gpio = S5PV310_GPE1(3),
+ .enable_high = true,
+ .init_data = &mmc0_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc0_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &mmc0_fixed_voltage_config,
+ },
+};
+
+/* SD */
+static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE,
+ .ext_cd_gpio = S5PV310_GPX3(4), /* XEINT_28 */
+ .ext_cd_gpio_invert = 1,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* WiFi */
+static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE,
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+};
+
+static void __init universal_sdhci_init(void)
+{
+ s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
+ s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
+ s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
+}
+
/* I2C0 */
static struct i2c_board_info i2c0_devs[] __initdata = {
/* Camera, To be updated */
@@ -127,6 +198,13 @@ static struct i2c_board_info i2c1_devs[] __initdata = {
};
static struct platform_device *universal_devices[] __initdata = {
+ /* Samsung Platform Devices */
+ &mmc0_fixed_voltage,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+
+ /* Universal Devices */
&universal_gpio_keys,
&s5p_device_onenand,
};
@@ -140,6 +218,8 @@ static void __init universal_map_io(void)
static void __init universal_machine_init(void)
{
+ universal_sdhci_init();
+
i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
index d357c198edee..34093b069f67 100644
--- a/arch/arm/mach-s5pv310/platsmp.c
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -22,7 +22,6 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>
@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void);
volatile int __cpuinitdata pen_release = -1;
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
static void __iomem *scu_base_addr(void)
{
return (void __iomem *)(S5P_VA_SCU);
@@ -47,21 +59,18 @@ static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
- pen_release = -1;
- smp_wmb();
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
- pen_release = cpu;
- __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
- outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+ write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -130,13 +137,6 @@ void __init smp_init_cpus(void)
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "S5PV310: strange CM count of 0? Default to 1\n");
-
- ncores = 1;
- }
-
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"S5PV310: no. of cores (%d) greater than configured "
@@ -149,18 +149,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true);
}
-void __init smp_prepare_cpus(unsigned int max_cpus)
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- unsigned int ncores = num_possible_cpus();
- unsigned int cpu = smp_processor_id();
int i;
- smp_store_cpu_info(cpu);
-
- /* are we trying to boot more cores than exist? */
- if (max_cpus > ncores)
- max_cpus = ncores;
-
/*
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time.
@@ -168,25 +160,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
+ scu_enable(scu_base_addr());
+
/*
- * Initialise the SCU if there are more than one CPU and let
- * them know where to start.
+ * Write the address of secondary startup into the
+ * system-wide flags register. The boot monitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
*/
- if (max_cpus > 1) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
-
- scu_enable(scu_base_addr());
-
- /*
- * Write the address of secondary startup into the
- * system-wide flags register. The boot monitor waits
- * until it receives a soft interrupt, and then the
- * secondary CPU branches to this address.
- */
__raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
- }
}
diff --git a/arch/arm/mach-s5pv310/time.c b/arch/arm/mach-s5pv310/time.c
index 01b012ad1bfd..b262d4615331 100644
--- a/arch/arm/mach-s5pv310/time.c
+++ b/arch/arm/mach-s5pv310/time.c
@@ -211,7 +211,6 @@ struct clocksource pwm_clocksource = {
.rating = 250,
.read = s5pv310_pwm4_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS ,
};
@@ -230,10 +229,7 @@ static void __init s5pv310_clocksource_init(void)
s5pv310_pwm_init(4, ~0);
s5pv310_pwm_start(4, 1);
- pwm_clocksource.mult =
- clocksource_khz2mult(clock_rate/1000, pwm_clocksource.shift);
-
- if (clocksource_register(&pwm_clocksource))
+ if (clocksource_register_hz(&pwm_clocksource, clock_rate))
panic("%s: can't register clocksource\n", pwm_clocksource.name);
}
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 5da8c35aa0de..42625e4d949a 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -118,6 +118,16 @@ config SA1100_LART
(also known as the LART). See <http://www.lartmaker.nl/> for
information on the LART.
+config SA1100_NANOENGINE
+ bool "nanoEngine"
+ select CPU_FREQ_SA1110
+ select PCI
+ select PCI_NANOENGINE
+ help
+ Say Y here if you are using the Bright Star Engineering nanoEngine.
+ See <http://www.brightstareng.com/arm/nanoeng.htm> for information
+ on the BSE nanoEngine.
+
config SA1100_PLEB
bool "PLEB"
select CPU_FREQ_SA1100
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index 89349c1dd7a6..e697691eed28 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -37,6 +37,9 @@ obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
obj-$(CONFIG_SA1100_LART) += lart.o
led-$(CONFIG_SA1100_LART) += leds-lart.o
+obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
+obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o
+
obj-$(CONFIG_SA1100_PLEB) += pleb.o
obj-$(CONFIG_SA1100_SHANNON) += shannon.o
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index 96f7dc103b59..07d4e8ba3719 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -94,48 +94,47 @@
#include "generic.h"
-typedef struct {
+struct sa1100_dram_regs {
int speed;
u32 mdcnfg;
u32 mdcas0;
u32 mdcas1;
u32 mdcas2;
-} sa1100_dram_regs_t;
+};
static struct cpufreq_driver sa1100_driver;
-static sa1100_dram_regs_t sa1100_dram_settings[] =
-{
- /* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */
- { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */
- { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */
- { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */
- { 103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 103.2 MHz */
- { 118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 118.0 MHz */
- { 132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 132.7 MHz */
- { 147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff }, /* 147.5 MHz */
- { 162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff }, /* 162.2 MHz */
- { 176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff }, /* 176.9 MHz */
- { 191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff }, /* 191.7 MHz */
- { 206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 206.4 MHz */
- { 221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 221.2 MHz */
- { 235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1 }, /* 235.9 MHz */
- { 250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 250.7 MHz */
- { 265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 265.4 MHz */
- { 280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87 }, /* 280.2 MHz */
+static struct sa1100_dram_regs sa1100_dram_settings[] = {
+ /*speed, mdcnfg, mdcas0, mdcas1, mdcas2, clock freq */
+ { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 59.0 MHz */
+ { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 73.7 MHz */
+ { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 88.5 MHz */
+ {103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 103.2 MHz */
+ {118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff},/* 118.0 MHz */
+ {132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff},/* 132.7 MHz */
+ {147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff},/* 147.5 MHz */
+ {162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff},/* 162.2 MHz */
+ {176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff},/* 176.9 MHz */
+ {191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff},/* 191.7 MHz */
+ {206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 206.4 MHz */
+ {221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 221.2 MHz */
+ {235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1},/* 235.9 MHz */
+ {250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 250.7 MHz */
+ {265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 265.4 MHz */
+ {280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87},/* 280.2 MHz */
{ 0, 0, 0, 0, 0 } /* last entry */
};
static void sa1100_update_dram_timings(int current_speed, int new_speed)
{
- sa1100_dram_regs_t *settings = sa1100_dram_settings;
+ struct sa1100_dram_regs *settings = sa1100_dram_settings;
/* find speed */
while (settings->speed != 0) {
- if(new_speed == settings->speed)
+ if (new_speed == settings->speed)
break;
-
+
settings++;
}
@@ -149,7 +148,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
/* We're going FASTER, so first relax the memory
* timings before changing the core frequency
*/
-
+
/* Half the memory access clock */
MDCNFG |= MDCNFG_CDB2;
@@ -187,7 +186,7 @@ static int sa1100_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
new_ppcr = sa11x0_freq_to_ppcr(target_freq);
- switch(relation){
+ switch (relation) {
case CPUFREQ_RELATION_L:
if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
new_ppcr--;
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 7252874d328b..675bf8ef97e8 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -16,28 +16,24 @@
*
* The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
*/
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
-#include <mach/hardware.h>
#include <asm/cputype.h>
#include <asm/mach-types.h>
-#include <asm/system.h>
+
+#include <mach/hardware.h>
#include "generic.h"
#undef DEBUG
-static struct cpufreq_driver sa1110_driver;
-
struct sdram_params {
- const char name[16];
+ const char name[20];
u_char rows; /* bits */
u_char cas_latency; /* cycles */
u_char tck; /* clock cycle time (ns) */
@@ -107,6 +103,15 @@ static struct sdram_params sdram_tbl[] __initdata = {
.twr = 8,
.refresh = 64000,
.cas_latency = 3,
+ }, { /* Micron MT48LC8M16A2TG-75 */
+ .name = "MT48LC8M16A2TG-75",
+ .rows = 12,
+ .tck = 8,
+ .trcd = 20,
+ .trp = 20,
+ .twr = 8,
+ .refresh = 64000,
+ .cas_latency = 3,
},
};
@@ -180,11 +185,13 @@ sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
sd->mdrefr |= MDREFR_K1DB2;
/* initial number of '1's in MDCAS + 1 */
- set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz));
+ set_mdcas(sd->mdcas, sd_khz >= 62000,
+ ns_to_cycles(sdram->trcd, mem_khz));
#ifdef DEBUG
- printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
- sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]);
+ printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
+ sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
+ sd->mdcas[2]);
#endif
}
@@ -213,7 +220,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
#ifdef DEBUG
mdelay(250);
- printk("new dri value = %d\n", dri);
+ printk(KERN_DEBUG "new dri value = %d\n", dri);
#endif
sdram_set_refresh(dri);
@@ -232,7 +239,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
unsigned long flags;
unsigned int ppcr, unused;
- switch(relation){
+ switch (relation) {
case CPUFREQ_RELATION_L:
ppcr = sa11x0_freq_to_ppcr(target_freq);
if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
@@ -280,11 +287,10 @@ static int sa1110_target(struct cpufreq_policy *policy,
* We wait 20ms to be safe.
*/
sdram_set_refresh(2);
- if (!irqs_disabled()) {
+ if (!irqs_disabled())
msleep(20);
- } else {
+ else
mdelay(20);
- }
/*
* Reprogram the DRAM timings with interrupts disabled, and
@@ -295,7 +301,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
local_irq_save(flags);
asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
udelay(10);
- __asm__ __volatile__(" \n\
+ __asm__ __volatile__("\n\
b 2f \n\
.align 5 \n\
1: str %3, [%1, #0] @ MDCNFG \n\
@@ -336,7 +342,9 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
return 0;
}
-static struct cpufreq_driver sa1110_driver = {
+/* sa1110_driver needs __refdata because it must remain after init registers
+ * it with cpufreq_register_driver() */
+static struct cpufreq_driver sa1110_driver __refdata = {
.flags = CPUFREQ_STICKY,
.verify = sa11x0_verify_speed,
.target = sa1110_target,
@@ -349,7 +357,8 @@ static struct sdram_params *sa1110_find_sdram(const char *name)
{
struct sdram_params *sdram;
- for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl); sdram++)
+ for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
+ sdram++)
if (strcmp(name, sdram->name) == 0)
return sdram;
@@ -369,14 +378,14 @@ static int __init sa1110_clk_init(void)
if (!name[0]) {
if (machine_is_assabet())
name = "TC59SM716-CL3";
-
if (machine_is_pt_system3())
name = "K4S641632D";
-
if (machine_is_h3100())
name = "KM416S4030CT";
if (machine_is_jornada720())
- name = "K4S281632B-1H";
+ name = "K4S281632B-1H";
+ if (machine_is_nanoengine())
+ name = "MT48LC8M16A2TG-75";
}
sdram = sa1110_find_sdram(name);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3c1fcd696714..59d14f0fdcf8 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -16,9 +16,7 @@
#include <linux/pm.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
-#include <linux/sched.h> /* just for sched_clock() - funny that */
#include <linux/platform_device.h>
-#include <linux/cnt32_to_63.h>
#include <asm/div64.h>
#include <mach/hardware.h>
@@ -110,27 +108,6 @@ unsigned int sa11x0_getspeed(unsigned int cpu)
}
/*
- * This is the SA11x0 sched_clock implementation. This has
- * a resolution of 271ns, and a maximum value of 32025597s (370 days).
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 582 seconds between successive
- * calls to this function.
- *
- * ( * 1E9 / 3686400 => * 78125 / 288)
- */
-unsigned long long sched_clock(void)
-{
- unsigned long long v = cnt32_to_63(OSCR);
-
- /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
- v *= 78125<<1;
- do_div(v, 288<<1);
-
- return v;
-}
-
-/*
* Default power-off for SA1100
*/
static void sa1100_power_off(void)
@@ -163,10 +140,15 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
static struct resource sa11x0udc_resources[] = {
[0] = {
- .start = 0x80000000,
- .end = 0x8000ffff,
+ .start = __PREG(Ser0UDCCR),
+ .end = __PREG(Ser0UDCCR) + 0xffff,
.flags = IORESOURCE_MEM,
},
+ [1] = {
+ .start = IRQ_Ser0UDC,
+ .end = IRQ_Ser0UDC,
+ .flags = IORESOURCE_IRQ,
+ },
};
static u64 sa11x0udc_dma_mask = 0xffffffffUL;
@@ -184,10 +166,15 @@ static struct platform_device sa11x0udc_device = {
static struct resource sa11x0uart1_resources[] = {
[0] = {
- .start = 0x80010000,
- .end = 0x8001ffff,
+ .start = __PREG(Ser1UTCR0),
+ .end = __PREG(Ser1UTCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
+ [1] = {
+ .start = IRQ_Ser1UART,
+ .end = IRQ_Ser1UART,
+ .flags = IORESOURCE_IRQ,
+ },
};
static struct platform_device sa11x0uart1_device = {
@@ -199,10 +186,15 @@ static struct platform_device sa11x0uart1_device = {
static struct resource sa11x0uart3_resources[] = {
[0] = {
- .start = 0x80050000,
- .end = 0x8005ffff,
+ .start = __PREG(Ser3UTCR0),
+ .end = __PREG(Ser3UTCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
+ [1] = {
+ .start = IRQ_Ser3UART,
+ .end = IRQ_Ser3UART,
+ .flags = IORESOURCE_IRQ,
+ },
};
static struct platform_device sa11x0uart3_device = {
@@ -214,10 +206,15 @@ static struct platform_device sa11x0uart3_device = {
static struct resource sa11x0mcp_resources[] = {
[0] = {
- .start = 0x80060000,
- .end = 0x8006ffff,
+ .start = __PREG(Ser4MCCR0),
+ .end = __PREG(Ser4MCCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
+ [1] = {
+ .start = IRQ_Ser4MCP,
+ .end = IRQ_Ser4MCP,
+ .flags = IORESOURCE_IRQ,
+ },
};
static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -244,6 +241,11 @@ static struct resource sa11x0ssp_resources[] = {
.end = 0x8007ffff,
.flags = IORESOURCE_MEM,
},
+ [1] = {
+ .start = IRQ_Ser4SSP,
+ .end = IRQ_Ser4SSP,
+ .flags = IORESOURCE_IRQ,
+ },
};
static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index 99f5856d8de4..967ae7684390 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -76,4 +76,12 @@ static inline unsigned long get_clock_tick_rate(void)
#include "SA-1101.h"
#endif
+#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI)
+#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
+
+
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
new file mode 100644
index 000000000000..14f8382d0665
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/nanoengine.h
+ *
+ * This file contains the hardware specific definitions for nanoEngine.
+ * Only include this file from SA1100-specific files.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can 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_NANOENGINE_H
+#define __ASM_ARCH_NANOENGINE_H
+
+#include <mach/irqs.h>
+
+#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */
+#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */
+
+#define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0
+#define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11
+#define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12
+#define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13
+#define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14
+
+/*
+ * nanoEngine Memory Map:
+ *
+ * 0000.0000 - 003F.0000 - 4 MB Flash
+ * C000.0000 - C1FF.FFFF - 32 MB SDRAM
+ * 1860.0000 - 186F.FFFF - 1 MB Internal PCI Memory Read/Write
+ * 18A1.0000 - 18A1.FFFF - 64 KB Internal PCI Config Space
+ * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode
+ * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode
+ *
+ */
+
+#define NANO_PCI_MEM_RW_PHYS 0x18600000
+#define NANO_PCI_MEM_RW_VIRT 0xf1000000
+#define NANO_PCI_MEM_RW_SIZE SZ_1M
+#define NANO_PCI_CONFIG_SPACE_PHYS 0x18A10000
+#define NANO_PCI_CONFIG_SPACE_VIRT 0xf2000000
+#define NANO_PCI_CONFIG_SPACE_SIZE SZ_64K
+
+#endif
+
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
new file mode 100644
index 000000000000..72087f0658b7
--- /dev/null
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-sa1100/nanoengine.c
+ *
+ * Bright Star Engineering's nanoEngine board init code.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can 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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/root_dev.h>
+
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+
+#include "generic.h"
+
+/* Flash bank 0 */
+static struct mtd_partition nanoengine_partitions[] = {
+ {
+ .name = "nanoEngine boot firmware and parameter table",
+ .size = 0x00010000, /* 32K */
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel/initrd reserved",
+ .size = 0x002f0000,
+ .offset = 0x00010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "experimental filesystem allocation",
+ .size = 0x00100000,
+ .offset = 0x00300000,
+ .mask_flags = MTD_WRITEABLE,
+ }
+};
+
+static struct flash_platform_data nanoengine_flash_data = {
+ .map_name = "jedec_probe",
+ .parts = nanoengine_partitions,
+ .nr_parts = ARRAY_SIZE(nanoengine_partitions),
+};
+
+static struct resource nanoengine_flash_resources[] = {
+ {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SA1100_CS1_PHYS,
+ .end = SA1100_CS1_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct map_desc nanoengine_io_desc[] __initdata = {
+ {
+ /* System Registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, {
+ /* Internal PCI Memory Read/Write */
+ .virtual = NANO_PCI_MEM_RW_VIRT,
+ .pfn = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS),
+ .length = NANO_PCI_MEM_RW_SIZE,
+ .type = MT_DEVICE
+ }, {
+ /* Internal PCI Config Space */
+ .virtual = NANO_PCI_CONFIG_SPACE_VIRT,
+ .pfn = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS),
+ .length = NANO_PCI_CONFIG_SPACE_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init nanoengine_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc));
+
+ sa1100_register_uart(0, 1);
+ sa1100_register_uart(1, 2);
+ sa1100_register_uart(2, 3);
+ Ser1SDCR0 |= SDCR0_UART;
+ /* disable IRDA -- UART2 is used as a normal serial port */
+ Ser2UTCR4 = 0;
+ Ser2HSCR0 = 0;
+}
+
+static void __init nanoengine_init(void)
+{
+ sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
+ ARRAY_SIZE(nanoengine_flash_resources));
+}
+
+MACHINE_START(NANOENGINE, "BSE nanoEngine")
+ .boot_params = 0xc0000000,
+ .map_io = nanoengine_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = nanoengine_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
new file mode 100644
index 000000000000..fba7a913f12b
--- /dev/null
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/mach-sa1100/pci-nanoengine.c
+ *
+ * PCI functions for BSE nanoEngine PCI
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or 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/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <mach/nanoengine.h>
+
+static DEFINE_SPINLOCK(nano_lock);
+
+static int nanoengine_get_pci_address(struct pci_bus *bus,
+ unsigned int devfn, int where, unsigned long *address)
+{
+ int ret = PCIBIOS_DEVICE_NOT_FOUND;
+ unsigned int busnr = bus->number;
+
+ *address = NANO_PCI_CONFIG_SPACE_VIRT +
+ ((bus->number << 16) | (devfn << 8) | (where & ~3));
+
+ ret = (busnr > 255 || devfn > 255 || where > 255) ?
+ PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+ return ret;
+}
+
+static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ int ret;
+ unsigned long address;
+ unsigned long flags;
+ u32 v;
+
+ /* nanoEngine PCI bridge does not return -1 for a non-existing
+ * device. We must fake the answer. We know that the only valid
+ * device is device zero at bus 0, which is the network chip. */
+ if (bus->number != 0 || (devfn >> 3) != 0) {
+ v = -1;
+ nanoengine_get_pci_address(bus, devfn, where, &address);
+ goto exit_function;
+ }
+
+ spin_lock_irqsave(&nano_lock, flags);
+
+ ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
+ v = __raw_readl(address);
+
+ spin_unlock_irqrestore(&nano_lock, flags);
+
+ v >>= ((where & 3) * 8);
+ v &= (unsigned long)(-1) >> ((4 - size) * 8);
+
+exit_function:
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ int ret;
+ unsigned long address;
+ unsigned long flags;
+ unsigned shift;
+ u32 v;
+
+ shift = (where & 3) * 8;
+
+ spin_lock_irqsave(&nano_lock, flags);
+
+ ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
+ v = __raw_readl(address);
+ switch (size) {
+ case 1:
+ v &= ~(0xFF << shift);
+ v |= val << shift;
+ break;
+ case 2:
+ v &= ~(0xFFFF << shift);
+ v |= val << shift;
+ break;
+ case 4:
+ v = val;
+ break;
+ }
+ __raw_writel(v, address);
+
+ spin_unlock_irqrestore(&nano_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_nano_ops = {
+ .read = nanoengine_read_config,
+ .write = nanoengine_write_config,
+};
+
+static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return NANOENGINE_IRQ_GPIO_PCI;
+}
+
+struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
+}
+
+static struct resource pci_io_ports = {
+ .name = "PCI IO",
+ .start = 0x400,
+ .end = 0x7FF,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci_non_prefetchable_memory = {
+ .name = "PCI non-prefetchable",
+ .start = NANO_PCI_MEM_RW_PHYS,
+ /* nanoEngine documentation says there is a 1 Megabyte window here,
+ * but PCI reports just 128 + 8 kbytes. */
+ .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1,
+/* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it
+ * overlaps with previously defined memory.
+ *
+ * Here is what happens:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000)
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
+ *
+ * On the other hand, if we do not request the prefetchable memory resource,
+ * linux will alloc it first and the two non-prefetchable memory areas that
+ * are our real interest will not be mapped. So we choose to map it to an
+ * unused area. It gets recognized as expansion ROM, but becomes disabled.
+ *
+ * Here is what happens then:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref]
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
+
+# lspci -vv -s 0000:00:00.0
+00:00.0 Class 0200: Device 8086:1209 (rev 09)
+ Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
+ Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx-
+ Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes
+ Interrupt: pin A routed to IRQ 0
+ Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K]
+ Region 1: I/O ports at 0400 [size=64]
+ Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K]
+ [virtual] Expansion ROM at 78000000 [disabled] [size=1M]
+ Capabilities: [dc] Power Management version 2
+ Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
+ Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME-
+ Kernel driver in use: e100
+ Kernel modules: e100
+ *
+ */
+static struct resource pci_prefetchable_memory = {
+ .name = "PCI prefetchable",
+ .start = 0x78000000,
+ .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_nanoengine_setup_resources(struct resource **resource)
+{
+ if (request_resource(&ioport_resource, &pci_io_ports)) {
+ printk(KERN_ERR "PCI: unable to allocate io port region\n");
+ return -EBUSY;
+ }
+ if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) {
+ release_resource(&pci_io_ports);
+ printk(KERN_ERR "PCI: unable to allocate non prefetchable\n");
+ return -EBUSY;
+ }
+ if (request_resource(&iomem_resource, &pci_prefetchable_memory)) {
+ release_resource(&pci_io_ports);
+ release_resource(&pci_non_prefetchable_memory);
+ printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
+ return -EBUSY;
+ }
+ resource[0] = &pci_io_ports;
+ resource[1] = &pci_non_prefetchable_memory;
+ resource[2] = &pci_prefetchable_memory;
+
+ return 1;
+}
+
+int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ if (nr == 0) {
+ sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
+ sys->io_offset = 0x400;
+ ret = pci_nanoengine_setup_resources(sys->resource);
+ /* Enable alternate memory bus master mode, see
+ * "Intel StrongARM SA1110 Developer's Manual",
+ * section 10.8, "Alternate Memory Bus Master Mode". */
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+ GAFR |= GPIO_MBGNT | GPIO_MBREQ;
+ TUCR |= TUCR_MBGPIO;
+ }
+
+ return ret;
+}
+
+static struct hw_pci nanoengine_pci __initdata = {
+ .map_irq = pci_nanoengine_map_irq,
+ .nr_controllers = 1,
+ .scan = pci_nanoengine_scan_bus,
+ .setup = pci_nanoengine_setup,
+};
+
+static int __init nanoengine_pci_init(void)
+{
+ if (machine_is_nanoengine())
+ pci_common_init(&nanoengine_pci);
+ return 0;
+}
+
+subsys_initcall(nanoengine_pci_init);
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 27692d0ffbe8..cfb76077bd25 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -166,9 +166,6 @@ static void __init simpad_map_io(void)
PCFR = 0;
PSDR = 0;
- sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
- ARRAY_SIZE(simpad_flash_resources));
- sa11x0_register_mcp(&simpad_mcp_data);
}
static void simpad_power_off(void)
@@ -216,6 +213,10 @@ static int __init simpad_init(void)
pm_power_off = simpad_power_off;
+ sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
+ ARRAY_SIZE(simpad_flash_resources));
+ sa11x0_register_mcp(&simpad_mcp_data);
+
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if(ret)
printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 74b6e0e570b6..ae4f3d80416f 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -12,12 +12,39 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/sched.h> /* just for sched_clock() - funny that */
#include <linux/timex.h>
#include <linux/clockchips.h>
#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
#include <mach/hardware.h>
+/*
+ * This is the SA11x0 sched_clock implementation.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz,
+ * NSEC_PER_SEC, 60).
+ * This gives a resolution of about 271ns and a wrap period of about 19min.
+ */
+#define SC_MULT 2275555556u
+#define SC_SHIFT 23
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = OSCR;
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace sa1100_update_sched_clock(void)
+{
+ u32 cyc = OSCR;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
#define MIN_OSCR_DELTA 2
static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
@@ -81,7 +108,6 @@ static struct clocksource cksrc_sa1100_oscr = {
.rating = 200,
.read = sa1100_read_oscr,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -97,6 +123,9 @@ static void __init sa1100_timer_init(void)
OIER = 0; /* disable any timer interrupts */
OSSR = 0xf; /* clear status on all timers */
+ init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
+ 3686400, SC_MULT, SC_SHIFT);
+
ckevt_sa1100_osmr0.mult =
div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift);
ckevt_sa1100_osmr0.max_delta_ns =
@@ -105,12 +134,9 @@ static void __init sa1100_timer_init(void)
clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1;
ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
- cksrc_sa1100_oscr.mult =
- clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
-
setup_irq(IRQ_OST0, &sa1100_timer_irq);
- clocksource_register(&cksrc_sa1100_oscr);
+ clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE);
clockevents_register_device(&ckevt_sa1100_osmr0);
}
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 51dcd59eda6a..285dbbd4ad2c 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -5,26 +5,27 @@ comment "SH-Mobile System Type"
config ARCH_SH7367
bool "SH-Mobile G3 (SH7367)"
select CPU_V6
- select HAVE_CLK
- select COMMON_CLKDEV
select SH_CLK_CPG
- select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7377
bool "SH-Mobile G4 (SH7377)"
select CPU_V7
- select HAVE_CLK
- select COMMON_CLKDEV
select SH_CLK_CPG
- select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7372
bool "SH-Mobile AP4 (SH7372)"
select CPU_V7
- select HAVE_CLK
- select COMMON_CLKDEV
select SH_CLK_CPG
- select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+config ARCH_SH73A0
+ bool "SH-Mobile AG5 (R8A73A00)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
comment "SH-Mobile Board Type"
@@ -57,6 +58,15 @@ config AP4EVB_WVGA
endchoice
+config MACH_AG5EVM
+ bool "AG5EVM board"
+ depends on ARCH_SH73A0
+
+config MACH_MACKEREL
+ bool "mackerel board"
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
+
comment "SH-Mobile System Configuration"
menu "Memory configuration"
@@ -64,8 +74,8 @@ 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 "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
+ MACH_MACKEREL
default "0x00000000"
---help---
Tweak this only when porting to a new machine which does not
@@ -77,6 +87,7 @@ config MEMORY_SIZE
default "0x08000000" if MACH_G3EVM
default "0x08000000" if MACH_G4EVM
default "0x10000000" if MACH_AP4EVB
+ default "0x20000000" if MACH_AG5EVM
default "0x04000000"
help
This sets the default memory size assumed by your kernel. It can
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index ae416fe7daf2..ab100e4bddd6 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -9,14 +9,21 @@ obj-y := timer.o console.o clock.o pm_runtime.o
obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
+obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.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)
+pfc-y :=
+pfc-$(CONFIG_ARCH_SH7367) += pfc-sh7367.o
+pfc-$(CONFIG_ARCH_SH7377) += pfc-sh7377.o
+pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o
+pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o
# Board objects
obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
+obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
+obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
+
+# Framework support
+obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
new file mode 100644
index 000000000000..2f135923e2bd
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -0,0 +1,314 @@
+/*
+ * arch/arm/mach-shmobile/board-ag5evm.c
+ *
+ * Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com>
+ * Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_sci.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+
+#include <sound/sh_fsi.h>
+
+#include <mach/hardware.h>
+#include <mach/sh73a0.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/traps.h>
+
+static struct resource smsc9220_resources[] = {
+ [0] = {
+ .start = 0x14000000,
+ .end = 0x14000000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(33), /* PINT1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc9220_platdata = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc9220_platdata,
+ },
+ .resource = smsc9220_resources,
+ .num_resources = ARRAY_SIZE(smsc9220_resources),
+};
+
+static struct sh_keysc_info keysc_platdata = {
+ .mode = SH_KEYSC_MODE_6,
+ .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_SPACE, KEY_9, KEY_6, KEY_3, KEY_WAKEUP, KEY_RIGHT, \
+ KEY_COFFEE,
+ KEY_0, KEY_8, KEY_5, KEY_2, KEY_DOWN, KEY_ENTER, KEY_UP,
+ KEY_KPASTERISK, KEY_7, KEY_4, KEY_1, KEY_STOP, KEY_LEFT, \
+ KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b0098 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(71),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_platdata,
+ },
+};
+
+/* FSI A */
+static struct sh_fsi_platform_info fsi_info = {
+ .porta_flags = SH_FSI_OUT_SLAVE_MODE |
+ SH_FSI_IN_SLAVE_MODE |
+ SH_FSI_OFMT(I2S) |
+ SH_FSI_IFMT(I2S),
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xEC230000,
+ .end = 0xEC230400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(146),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xe6bd0000,
+ .end = 0xe6bd00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(141),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(140),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_platdata = {
+ .sup_pclk = 0,
+ .ocr = MMC_VDD_165_195,
+ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+};
+
+static struct platform_device mmc_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_platdata,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+static struct platform_device *ag5evm_devices[] __initdata = {
+ &eth_device,
+ &keysc_device,
+ &fsi_device,
+ &mmc_device,
+};
+
+static struct map_desc ag5evm_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 ag5evm_map_io(void)
+{
+ iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
+
+ /* setup early devices and console here as well */
+ sh73a0_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define PINTC_ADDR 0xe6900000
+#define PINTER0A (PINTC_ADDR + 0xa0)
+#define PINTCR0A (PINTC_ADDR + 0xb0)
+
+void __init ag5evm_init_irq(void)
+{
+ sh73a0_init_irq();
+
+ /* setup PINT: enable PINTA2 as active low */
+ __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A);
+ __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
+}
+
+static void __init ag5evm_init(void)
+{
+ sh73a0_pinmux_init();
+
+ /* enable SCIFA2 */
+ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
+ gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
+
+ /* enable KEYSC */
+ gpio_request(GPIO_FN_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN6_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN7_PU, NULL);
+ 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_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
+ gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
+ gpio_request(GPIO_FN_KEYOUT8, NULL);
+ gpio_request(GPIO_FN_PORT149_KEYOUT9, NULL);
+
+ /* enable I2C channel 2 and 3 */
+ gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL);
+ gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL);
+ gpio_request(GPIO_FN_PORT248_I2C_SCL3, NULL);
+ gpio_request(GPIO_FN_PORT249_I2C_SDA3, NULL);
+
+ /* enable MMCIF */
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+ gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_PORT208, NULL); /* Reset */
+ gpio_direction_output(GPIO_PORT208, 1);
+
+ /* enable SMSC911X */
+ gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
+ gpio_direction_input(GPIO_PORT144);
+ gpio_request(GPIO_PORT145, NULL); /* RESET */
+ gpio_direction_output(GPIO_PORT145, 1);
+
+ /* FSI A */
+ gpio_request(GPIO_FN_FSIACK, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
+#endif
+ sh73a0_add_standard_devices();
+ platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
+}
+
+static void __init ag5evm_timer_init(void)
+{
+ sh73a0_clock_init();
+ shmobile_timer.init();
+ return;
+}
+
+struct sys_timer ag5evm_timer = {
+ .init = ag5evm_timer_init,
+};
+
+MACHINE_START(AG5EVM, "ag5evm")
+ .map_io = ag5evm_map_io,
+ .init_irq = ag5evm_init_irq,
+ .init_machine = ag5evm_init,
+ .timer = &ag5evm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d440e5f456ad..e521c669ca9b 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -61,6 +61,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
+#include <asm/setup.h>
/*
* Address Interface BusWidth note
@@ -272,6 +273,15 @@ static struct resource sh_mmcif_resources[] = {
},
};
+static struct sh_mmcif_dma sh_mmcif_dma = {
+ .chan_priv_rx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ },
+ .chan_priv_tx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ },
+};
+
static struct sh_mmcif_plat_data sh_mmcif_plat = {
.sup_pclk = 0,
.ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -279,6 +289,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
MMC_CAP_8_BIT_DATA |
MMC_CAP_NEEDS_POLL,
.get_cd = slot_cn7_get_cd,
+ .dma = &sh_mmcif_dma,
};
static struct platform_device sh_mmcif_device = {
@@ -729,6 +740,10 @@ static struct platform_device fsi_device = {
},
};
+static struct platform_device fsi_ak4643_device = {
+ .name = "sh_fsi2_a_ak4643",
+};
+
static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
@@ -927,6 +942,7 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&sdhi1_device,
&usb1_host_device,
&fsi_device,
+ &fsi_ak4643_device,
&sh_mmcif_device,
&lcdc1_device,
&lcdc_device,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
new file mode 100644
index 000000000000..3e30a5250414
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -0,0 +1,595 @@
+/*
+ * mackerel board support
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on ap4evb
+ * 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/gpio.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/smsc911x.h>
+#include <linux/sh_intc.h>
+#include <linux/tca6416_keypad.h>
+#include <linux/usb/r8a66597.h>
+
+#include <video/sh_mobile_lcdc.h>
+
+#include <sound/sh_fsi.h>
+
+#include <mach/common.h>
+#include <mach/sh7372.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.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
+ */
+
+/*
+ * CPU mode
+ *
+ * SW4 | Boot Area| Master | Remarks
+ * 1 | 2 | 3 | 4 | 5 | 6 | 8 | | Processor|
+ * ----+-----+-----+-----+-----+-----+-----+----------+----------+--------------
+ * ON | ON | OFF | ON | ON | OFF | OFF | External | System | External ROM
+ * ON | ON | ON | ON | ON | OFF | OFF | External | System | ROM Debug
+ * ON | ON | X | ON | OFF | OFF | OFF | Built-in | System | ROM Debug
+ * X | OFF | X | X | X | X | OFF | Built-in | System | MaskROM
+ * OFF | X | X | X | X | X | OFF | Built-in | System | MaskROM
+ * X | X | X | OFF | X | X | OFF | Built-in | System | MaskROM
+ * OFF | ON | OFF | X | X | OFF | ON | External | System | Standalone
+ * ON | OFF | OFF | X | X | OFF | ON | External | Realtime | Standalone
+*/
+
+/*
+ * 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
+ */
+
+/*
+ * SMSC 9220
+ *
+ * SW1 SMSC 9220
+ * -----------------------
+ * ON access disable
+ * OFF access enable
+ */
+
+/*
+ * 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
+ */
+
+/*
+ * External interrupt pin settings
+ *
+ * IRQX | pin setting | device | level
+ * ------+--------------------+--------------------+-------
+ * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
+ * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
+ * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Tuch Panel | Low
+ * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
+ * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
+ * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
+ * IRQ22 | ICR4A.IRQ22SA=0011 | Sensor(AK8975) | High
+ */
+
+/*
+ * USB
+ *
+ * USB0 : CN22 : Function
+ * USB1 : CN31 : Function/Host *1
+ *
+ * J30 (for CN31) *1
+ * ----------+---------------+-------------
+ * 1-2 short | VBUS 5V | Host
+ * open | external VBUS | Function
+ *
+ * *1
+ * CN31 is used as Host in Linux.
+ */
+
+/*
+ * FIXME !!
+ *
+ * gpio_no_direction
+ * are quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_no_direction(u32 addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .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 */
+static struct resource smc911x_resources[] = {
+ {
+ .start = 0x14000000,
+ .end = 0x16000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x02c0) /* IRQ6A */,
+ .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,
+ },
+};
+
+/* LCDC */
+static struct fb_videomode mackerel_lcdc_modes[] = {
+ {
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .lcd_cfg = mackerel_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
+ .interface_type = RGB24,
+ .clock_divider = 2,
+ .flags = 0,
+ .lcd_size_cfg.width = 152,
+ .lcd_size_cfg.height = 91,
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000,
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/* USB1 (Host) */
+static void usb1_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on is supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
+ __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+ .on_chip = 1,
+ .port_power = usb1_host_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xE68B0000,
+ .end = 0xE68B00E6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb1_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb1_host_data,
+ },
+ .num_resources = ARRAY_SIZE(usb1_host_resources),
+ .resource = usb1_host_resources,
+};
+
+/* LED */
+static struct gpio_led mackerel_leds[] = {
+ {
+ .name = "led0",
+ .gpio = GPIO_PORT0,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led1",
+ .gpio = GPIO_PORT1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led2",
+ .gpio = GPIO_PORT2,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led3",
+ .gpio = GPIO_PORT159,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data mackerel_leds_pdata = {
+ .leds = mackerel_leds,
+ .num_leds = ARRAY_SIZE(mackerel_leds),
+};
+
+static struct platform_device leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &mackerel_leds_pdata,
+ },
+};
+
+/* FSI */
+#define IRQ_FSI evt2irq(0x1840)
+static struct sh_fsi_platform_info fsi_info = {
+ .porta_flags = SH_FSI_BRS_INV |
+ SH_FSI_OUT_SLAVE_MODE |
+ SH_FSI_IN_SLAVE_MODE |
+ SH_FSI_OFMT(PCM) |
+ SH_FSI_IFMT(PCM),
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C0400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct platform_device fsi_ak4643_device = {
+ .name = "sh_fsi2_a_ak4643",
+};
+
+static struct platform_device *mackerel_devices[] __initdata = {
+ &nor_flash_device,
+ &smc911x_device,
+ &lcdc_device,
+ &usb1_host_device,
+ &leds_device,
+ &fsi_device,
+ &fsi_ak4643_device,
+};
+
+/* Keypad Initialization */
+#define KEYPAD_BUTTON(ev_type, ev_code, act_low) \
+{ \
+ .type = ev_type, \
+ .code = ev_code, \
+ .active_low = act_low, \
+}
+
+#define KEYPAD_BUTTON_LOW(event_code) KEYPAD_BUTTON(EV_KEY, event_code, 1)
+
+static struct tca6416_button mackerel_gpio_keys[] = {
+ KEYPAD_BUTTON_LOW(KEY_HOME),
+ KEYPAD_BUTTON_LOW(KEY_MENU),
+ KEYPAD_BUTTON_LOW(KEY_BACK),
+ KEYPAD_BUTTON_LOW(KEY_POWER),
+};
+
+static struct tca6416_keys_platform_data mackerel_tca6416_keys_info = {
+ .buttons = mackerel_gpio_keys,
+ .nbuttons = ARRAY_SIZE(mackerel_gpio_keys),
+ .rep = 1,
+ .use_polling = 0,
+ .pinmask = 0x000F,
+};
+
+/* I2C */
+#define IRQ9 evt2irq(0x0320)
+
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4643", 0x13),
+ },
+ /* Keypad */
+ {
+ I2C_BOARD_INFO("tca6408-keys", 0x20),
+ .platform_data = &mackerel_tca6416_keys_info,
+ .irq = IRQ9,
+ },
+};
+
+#define IRQ21 evt2irq(0x32a0)
+
+static struct i2c_board_info i2c1_devices[] = {
+ /* Accelerometer */
+ {
+ I2C_BOARD_INFO("adxl34x", 0x53),
+ .irq = IRQ21,
+ },
+};
+
+static struct map_desc mackerel_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 mackerel_map_io(void)
+{
+ iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
+
+ /* setup early devices and console here as well */
+ sh7372_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define GPIO_PORT9CR 0xE6051009
+#define GPIO_PORT10CR 0xE605100A
+static void __init mackerel_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);
+
+ /* LCDC */
+ gpio_request(GPIO_FN_LCDD23, NULL);
+ gpio_request(GPIO_FN_LCDD22, NULL);
+ gpio_request(GPIO_FN_LCDD21, NULL);
+ gpio_request(GPIO_FN_LCDD20, NULL);
+ gpio_request(GPIO_FN_LCDD19, NULL);
+ gpio_request(GPIO_FN_LCDD18, NULL);
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+
+ gpio_request(GPIO_PORT31, NULL); /* backlight */
+ gpio_direction_output(GPIO_PORT31, 1);
+
+ gpio_request(GPIO_PORT151, NULL); /* LCDDON */
+ gpio_direction_output(GPIO_PORT151, 1);
+
+ /* USB enable */
+ gpio_request(GPIO_FN_VBUS0_1, NULL);
+ gpio_request(GPIO_FN_IDIN_1_18, NULL);
+ gpio_request(GPIO_FN_PWEN_1_115, NULL);
+ gpio_request(GPIO_FN_OVCN_1_114, NULL);
+ gpio_request(GPIO_FN_EXTLP_1, NULL);
+ gpio_request(GPIO_FN_OVCN2_1, NULL);
+
+ /* setup USB phy */
+ __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */
+
+ /* enable FSI2 port A (ak4643) */
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+ gpio_request(GPIO_PORT161, NULL);
+ gpio_direction_output(GPIO_PORT161, 0); /* slave */
+
+ gpio_request(GPIO_PORT9, NULL);
+ gpio_request(GPIO_PORT10, NULL);
+ gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+
+ intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
+
+ /* enable Keypad */
+ gpio_request(GPIO_FN_IRQ9_42, NULL);
+ set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
+
+ /* enable Accelerometer */
+ gpio_request(GPIO_FN_IRQ21, NULL);
+ set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
+
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+ i2c_register_board_info(1, i2c1_devices,
+ ARRAY_SIZE(i2c1_devices));
+
+ sh7372_add_standard_devices();
+
+ platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
+}
+
+static void __init mackerel_timer_init(void)
+{
+ sh7372_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer mackerel_timer = {
+ .init = mackerel_timer_init,
+};
+
+MACHINE_START(MACKEREL, "mackerel")
+ .map_io = mackerel_map_io,
+ .init_irq = sh7372_init_irq,
+ .init_machine = mackerel_init,
+ .timer = &mackerel_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index 9f78729098f2..6b186aefcbd6 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -20,8 +20,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
#include <mach/common.h>
-#include <asm/clkdev.h>
/* SH7367 registers */
#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 3aa026069435..d98deb497c2f 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -20,8 +20,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
#include <mach/common.h>
-#include <asm/clkdev.h>
/* SH7372 registers */
#define FRQCRA 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index f91395aeb9ab..95942466e63f 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -20,8 +20,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
#include <mach/common.h>
-#include <asm/clkdev.h>
/* SH7377 registers */
#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
new file mode 100644
index 000000000000..419581854a80
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -0,0 +1,356 @@
+/*
+ * sh73a0 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+
+#define FRQCRA 0xe6150000
+#define FRQCRB 0xe6150004
+#define FRQCRD 0xe61500e4
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define ZBCKCR 0xe6150010
+#define FLCKCR 0xe6150014
+#define SD0CKCR 0xe6150074
+#define SD1CKCR 0xe6150078
+#define SD2CKCR 0xe615007C
+#define FSIACKCR 0xe6150018
+#define FSIBCKCR 0xe6150090
+#define SUBCKCR 0xe6150080
+#define SPUACKCR 0xe6150084
+#define SPUVCKCR 0xe6150094
+#define MSUCKCR 0xe6150088
+#define HSICKCR 0xe615008C
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define DSITCKCR 0xe6150060
+#define DSI0PCKCR 0xe6150064
+#define DSI1PCKCR 0xe6150068
+#define DSI0PHYCR 0xe615006C
+#define DSI1PHYCR 0xe6150070
+#define PLLECR 0xe61500d0
+#define PLL0CR 0xe61500d8
+#define PLL1CR 0xe6150028
+#define PLL2CR 0xe615002c
+#define PLL3CR 0xe61500dc
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR4 0xe6150140
+#define SMSTPCR5 0xe6150144
+#define CKSCR 0xe61500c0
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh73a0_extal1_clk = {
+ .rate = 26000000,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh73a0_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extal1 by two */
+static struct clk extal1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh73a0_extal1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh73a0_extal2_clk,
+};
+
+static struct clk_ops main_clk_ops = {
+ .recalc = followparent_recalc,
+};
+
+/* Main clock */
+static struct clk main_clk = {
+ .ops = &main_clk_ops,
+};
+
+/* PLL0, PLL1, PLL2, PLL3 */
+static unsigned long pll_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLECR) & (1 << clk->enable_bit))
+ mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
+};
+
+static struct clk pll0_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL0CR,
+ .enable_bit = 0,
+};
+
+static struct clk pll1_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL1CR,
+ .enable_bit = 1,
+};
+
+static struct clk pll2_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL2CR,
+ .enable_bit = 2,
+};
+
+static struct clk pll3_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL3CR,
+ .enable_bit = 3,
+};
+
+/* Divide PLL1 by two */
+static struct clk pll1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pll1_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh73a0_extal1_clk,
+ &sh73a0_extal2_clk,
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &main_clk,
+ &pll0_clk,
+ &pll1_clk,
+ &pll2_clk,
+ &pll3_clk,
+ &pll1_div2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRB to update hardware setting */
+ value = __raw_readl(FRQCRB);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 0, 36, 48 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
+ DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
+ [DIV4_M3] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
+ [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
+ [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
+ [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
+ [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
+ [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
+ [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
+ DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
+ DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
+ DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
+ DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
+ DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
+ [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
+ [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
+ [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
+ [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
+ [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
+ [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
+ [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
+ [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
+ [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
+ [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
+ [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
+ [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
+ [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
+};
+
+enum { MSTP001,
+ MSTP125, MSTP116,
+ MSTP219,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP323, MSTP312,
+ MSTP411, MSTP410, MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
+ [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
+ [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+};
+
+void __init sh73a0_clock_init(void)
+{
+ int k, ret = 0;
+
+ /* detect main clock parent */
+ switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
+ case 0:
+ main_clk.parent = &sh73a0_extal1_clk;
+ break;
+ case 1:
+ main_clk.parent = &extal1_div2_clk;
+ break;
+ case 2:
+ main_clk.parent = &sh73a0_extal2_clk;
+ break;
+ case 3:
+ main_clk.parent = &extal2_div2_clk;
+ break;
+ }
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh73a0 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index efeef778a875..49ac8ebdc184 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -30,4 +30,12 @@ extern void sh7372_pinmux_init(void);
extern struct clk sh7372_extal1_clk;
extern struct clk sh7372_extal2_clk;
+extern void sh73a0_init_irq(void);
+extern void sh73a0_add_early_devices(void);
+extern void sh73a0_add_standard_devices(void);
+extern void sh73a0_clock_init(void);
+extern void sh73a0_pinmux_init(void);
+extern struct clk sh73a0_extal1_clk;
+extern struct clk sh73a0_extal2_clk;
+
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro-gic.S b/arch/arm/mach-shmobile/include/mach/entry-macro-gic.S
new file mode 100644
index 000000000000..50b1f16d54a2
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro-gic.S
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 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 <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =(0xf0000100)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an
+ * interrupt if it's between 30 and 1020. The test_for_ipi
+ * routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of
+ * the highest priority enabled interrupt. We then just need to
+ * check whether it is in the valid range for an IRQ (30-1020
+ * inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ /* bits 12-10 = src CPU, 9-0 = int # */
+
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+
+ .endm
+
+ /*
+ * We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S b/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S
new file mode 100644
index 000000000000..f428c4db2b60
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Magnus Damm
+ * 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/irqs.h>
+
+#define INTCA_BASE 0xe6980000
+#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
+#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
+#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
+#define INTLVLB_OFFS 0x00000034 /* previous priority level */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =INTCA_BASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ /* The single INTFLGA read access below results in the following:
+ *
+ * 1. INTLVLB is updated with old priority value from INTLVLA
+ * 2. Highest priority interrupt is accepted
+ * 3. INTLVLA is updated to contain priority of accepted interrupt
+ * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
+ */
+ ldr \irqnr, [\base, #INTFLGA_OFFS]
+
+ /* Restore INTLVLA with the value saved in INTLVLB.
+ * This is required to support interrupt priorities properly.
+ */
+ ldrb \tmp, [\base, #INTLVLB_OFFS]
+ strb \tmp, [\base, #INTLVLA_OFFS]
+
+ /* Handle invalid vector number case */
+ cmp \irqnr, #0
+ beq 1000f
+
+ /* Convert vector to irq number, same as the evt2irq() macro */
+ lsr \irqnr, \irqnr, #0x5
+ subs \irqnr, \irqnr, #16
+
+1000:
+ .endm
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
index a285d13c7416..26e401167605 100644
--- a/arch/arm/mach-shmobile/include/mach/entry-macro.S
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2010 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
@@ -14,26 +14,8 @@
* 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
+#if defined(CONFIG_ARM_GIC)
+#include <mach/entry-macro-gic.S>
+#else
+#include <mach/entry-macro-intc.S>
+#endif
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
new file mode 100644
index 000000000000..e3ebfa73956e
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
@@ -0,0 +1,87 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2010 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
+
+LIST "RWT Setting"
+EW 0xE6020004, 0xA500
+EW 0xE6030004, 0xA500
+
+DD 0x01001000, 0x01001000
+
+LIST "GPIO Setting"
+EB 0xE6051013, 0xA2
+
+LIST "CPG"
+ED 0xE6150080, 0x00000180
+ED 0xE61500C0, 0x00000002
+
+WAIT 1, 0xFE40009C
+
+LIST "FRQCR"
+ED 0xE6150000, 0x2D1305C3
+ED 0xE61500E0, 0x9E40358E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE61500E4, 0x00002000
+
+WAIT 1, 0xFE40009C
+
+LIST "PLL"
+ED 0xE6150028, 0x00004000
+
+WAIT 1, 0xFE40009C
+
+ED 0xE615002C, 0x93000040
+
+WAIT 1, 0xFE40009C
+
+LIST "BSC"
+ED 0xFEC10000, 0x00E0001B
+
+LIST "SBSC1"
+ED 0xFE400354, 0x01AD8000
+ED 0xFE400354, 0x01AD8001
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400008, 0xBCC90151
+ED 0xFE400040, 0x41774113
+ED 0xFE400044, 0x2712E229
+ED 0xFE400048, 0x20C18505
+ED 0xFE40004C, 0x00110209
+ED 0xFE400010, 0x00000087
+
+WAIT 10, 0xFE40009C
+
+ED 0xFE400084, 0x0000003F
+EB 0xFE500000, 0x00
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400084, 0x0000FF0A
+EB 0xFE500000, 0x00
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400084, 0x00002201
+EB 0xFE500000, 0x00
+ED 0xFE400084, 0x00000302
+EB 0xFE500000, 0x00
+EB 0xFE5C0000, 0x00
+ED 0xFE400008, 0xBCC90159
+ED 0xFE40008C, 0x88800004
+ED 0xFE400094, 0x00000004
+ED 0xFE400028, 0xA55A0032
+ED 0xFE40002C, 0xA55A000C
+ED 0xFE400020, 0xA55A2048
+ED 0xFE400008, 0xBCC90959
+
+LIST "Change CPGA setting"
+ED 0xE61500E0, 0x9E40352E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE6150354, 0x00000002
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index fa15b5f8a001..dcb714f4d75a 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -1,7 +1,10 @@
#ifndef __ASM_MACH_IRQS_H
#define __ASM_MACH_IRQS_H
-#define NR_IRQS 512
+#define NR_IRQS 1024
+
+/* GIC */
+#define gic_spi(nr) ((nr) + 32)
/* INTCA */
#define evt2irq(evt) (((evt) >> 5) - 16)
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index e4f9004e7103..5736efcca60c 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -455,6 +455,8 @@ enum {
SHDMA_SLAVE_SDHI1_TX,
SHDMA_SLAVE_SDHI2_RX,
SHDMA_SLAVE_SDHI2_TX,
+ SHDMA_SLAVE_MMCIF_RX,
+ SHDMA_SLAVE_MMCIF_TX,
};
extern struct clk sh7372_extal1_clk;
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
new file mode 100644
index 000000000000..ceb2cdc92bf9
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -0,0 +1,467 @@
+#ifndef __ASM_SH73A0_H__
+#define __ASM_SH73A0_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function and MSEL switch
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* Hardware manual Table 25-1 (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,
+ GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
+
+ GPIO_PORT270, GPIO_PORT271, GPIO_PORT272, GPIO_PORT273, GPIO_PORT274,
+ GPIO_PORT275, GPIO_PORT276, GPIO_PORT277, GPIO_PORT278, GPIO_PORT279,
+
+ GPIO_PORT280, GPIO_PORT281, GPIO_PORT282,
+
+ GPIO_PORT288, GPIO_PORT289,
+
+ GPIO_PORT290, GPIO_PORT291, GPIO_PORT292, GPIO_PORT293, GPIO_PORT294,
+ GPIO_PORT295, GPIO_PORT296, GPIO_PORT297, GPIO_PORT298, GPIO_PORT299,
+
+ GPIO_PORT300, GPIO_PORT301, GPIO_PORT302, GPIO_PORT303, GPIO_PORT304,
+ GPIO_PORT305, GPIO_PORT306, GPIO_PORT307, GPIO_PORT308, GPIO_PORT309,
+
+ /* Table 25-1 (Function 0-7) */
+ GPIO_FN_VBUS_0,
+ GPIO_FN_GPI0,
+ GPIO_FN_GPI1,
+ GPIO_FN_GPI2,
+ GPIO_FN_GPI3,
+ GPIO_FN_GPI4,
+ GPIO_FN_GPI5,
+ GPIO_FN_GPI6,
+ GPIO_FN_GPI7,
+ GPIO_FN_SCIFA7_RXD,
+ GPIO_FN_SCIFA7_CTS_,
+ GPIO_FN_GPO7, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_GPO6, GPIO_FN_MFG1_OUT2,
+ GPIO_FN_GPO5, GPIO_FN_SCIFA0_SCK, GPIO_FN_FSICOSLDT3, \
+ GPIO_FN_PORT16_VIO_CKOR,
+ GPIO_FN_SCIFA0_TXD,
+ GPIO_FN_SCIFA7_TXD,
+ GPIO_FN_SCIFA7_RTS_, GPIO_FN_PORT19_VIO_CKO2,
+ GPIO_FN_GPO0,
+ GPIO_FN_GPO1,
+ GPIO_FN_GPO2, GPIO_FN_STATUS0,
+ GPIO_FN_GPO3, GPIO_FN_STATUS1,
+ GPIO_FN_GPO4, GPIO_FN_STATUS2,
+ GPIO_FN_VINT,
+ GPIO_FN_TCKON,
+ GPIO_FN_XDVFS1, GPIO_FN_PORT27_I2C_SCL2, GPIO_FN_PORT27_I2C_SCL3, \
+ GPIO_FN_MFG0_OUT1, GPIO_FN_PORT27_IROUT,
+ GPIO_FN_XDVFS2, GPIO_FN_PORT28_I2C_SDA2, GPIO_FN_PORT28_I2C_SDA3, \
+ GPIO_FN_PORT28_TPU1TO1,
+ GPIO_FN_SIM_RST, GPIO_FN_PORT29_TPU1TO1,
+ GPIO_FN_SIM_CLK, GPIO_FN_PORT30_VIO_CKOR,
+ GPIO_FN_SIM_D, GPIO_FN_PORT31_IROUT,
+ GPIO_FN_SCIFA4_TXD,
+ GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_SCIFA4_RTS_,
+ GPIO_FN_SCIFA4_CTS_,
+ GPIO_FN_FSIBOBT, GPIO_FN_FSIBIBT,
+ GPIO_FN_FSIBOLR, GPIO_FN_FSIBILR,
+ GPIO_FN_FSIBOSLD,
+ GPIO_FN_FSIBISLD,
+ GPIO_FN_VACK,
+ GPIO_FN_XTAL1L,
+ GPIO_FN_SCIFA0_RTS_, GPIO_FN_FSICOSLDT2,
+ GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_SCIFA0_CTS_, GPIO_FN_FSICOSLDT1,
+ GPIO_FN_FSICOBT, GPIO_FN_FSICIBT, GPIO_FN_FSIDOBT, GPIO_FN_FSIDIBT,
+ GPIO_FN_FSICOLR, GPIO_FN_FSICILR, GPIO_FN_FSIDOLR, GPIO_FN_FSIDILR,
+ GPIO_FN_FSICOSLD, GPIO_FN_PORT47_FSICSPDIF,
+ GPIO_FN_FSICISLD, GPIO_FN_FSIDISLD,
+ GPIO_FN_FSIACK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT, \
+ GPIO_FN_FSIAOMC,
+ GPIO_FN_FSIAOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_FSIAILR,
+
+ GPIO_FN_FSIAOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_FSIAIBT,
+ GPIO_FN_FSIAOSLD, GPIO_FN_BBIF2_TXD2,
+ GPIO_FN_FSIASPDIF, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3, \
+ GPIO_FN_FSIBSPDIF, GPIO_FN_PORT53_FSICSPDIF,
+ GPIO_FN_FSIBCK, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2, \
+ GPIO_FN_FSIBOMC, GPIO_FN_FSICCK, GPIO_FN_FSICOMC,
+ GPIO_FN_FSIAISLD, GPIO_FN_TPU0TO0,
+ GPIO_FN_A0, GPIO_FN_BS_,
+ GPIO_FN_A12, GPIO_FN_PORT58_KEYOUT7, GPIO_FN_TPU4TO2,
+ GPIO_FN_A13, GPIO_FN_PORT59_KEYOUT6, GPIO_FN_TPU0TO1,
+ GPIO_FN_A14, GPIO_FN_KEYOUT5,
+ GPIO_FN_A15, GPIO_FN_KEYOUT4,
+ GPIO_FN_A16, GPIO_FN_KEYOUT3, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17, GPIO_FN_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18, GPIO_FN_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19, GPIO_FN_KEYOUT0, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20, GPIO_FN_KEYIN0, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21, GPIO_FN_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22, GPIO_FN_KEYIN2, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23, GPIO_FN_KEYIN3, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24, GPIO_FN_KEYIN4, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25, GPIO_FN_KEYIN5, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_KEYIN6,
+ GPIO_FN_KEYIN7,
+ 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,
+ GPIO_FN_CS4_,
+ GPIO_FN_CS5A_, GPIO_FN_PORT91_RDWR,
+ GPIO_FN_CS5B_, GPIO_FN_FCE1_,
+ GPIO_FN_CS6B_, GPIO_FN_DACK0,
+ GPIO_FN_FCE0_, GPIO_FN_CS6A_,
+ GPIO_FN_WAIT_, GPIO_FN_DREQ0,
+ GPIO_FN_RD__FSC,
+ GPIO_FN_WE0__FWE, GPIO_FN_RDWR_FWE,
+ GPIO_FN_WE1_,
+ GPIO_FN_FRB,
+ GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT_,
+ GPIO_FN_NBRST_,
+ GPIO_FN_BBIF2_TXD,
+ GPIO_FN_BBIF2_RXD,
+ GPIO_FN_BBIF2_SYNC,
+ GPIO_FN_BBIF2_SCK,
+ GPIO_FN_SCIFA3_CTS_, GPIO_FN_MFG3_IN2,
+ GPIO_FN_SCIFA3_RXD, GPIO_FN_MFG3_IN1,
+ GPIO_FN_BBIF1_SS2, GPIO_FN_SCIFA3_RTS_, GPIO_FN_MFG3_OUT1,
+ GPIO_FN_SCIFA3_TXD,
+ GPIO_FN_HSI_RX_DATA, GPIO_FN_BBIF1_RXD,
+ GPIO_FN_HSI_TX_WAKE, GPIO_FN_BBIF1_TSCK,
+ GPIO_FN_HSI_TX_DATA, GPIO_FN_BBIF1_TSYNC,
+ GPIO_FN_HSI_TX_READY, GPIO_FN_BBIF1_TXD,
+ GPIO_FN_HSI_RX_READY, GPIO_FN_BBIF1_RSCK, GPIO_FN_PORT115_I2C_SCL2, \
+ GPIO_FN_PORT115_I2C_SCL3,
+ GPIO_FN_HSI_RX_WAKE, GPIO_FN_BBIF1_RSYNC, GPIO_FN_PORT116_I2C_SDA2, \
+ GPIO_FN_PORT116_I2C_SDA3,
+ GPIO_FN_HSI_RX_FLAG, GPIO_FN_BBIF1_SS1, GPIO_FN_BBIF1_FLOW,
+ GPIO_FN_HSI_TX_FLAG,
+ GPIO_FN_VIO_VD, GPIO_FN_PORT128_LCD2VSYN, GPIO_FN_VIO2_VD, \
+ GPIO_FN_LCD2D0,
+
+ GPIO_FN_VIO_HD, GPIO_FN_PORT129_LCD2HSYN, GPIO_FN_PORT129_LCD2CS_, \
+ GPIO_FN_VIO2_HD, GPIO_FN_LCD2D1,
+ GPIO_FN_VIO_D0, GPIO_FN_PORT130_MSIOF2_RXD, GPIO_FN_LCD2D10,
+ GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT6, GPIO_FN_PORT131_MSIOF2_SS1, \
+ GPIO_FN_PORT131_KEYOUT11, GPIO_FN_LCD2D11,
+ GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT7, GPIO_FN_PORT132_MSIOF2_SS2, \
+ GPIO_FN_PORT132_KEYOUT10, GPIO_FN_LCD2D12,
+ GPIO_FN_VIO_D3, GPIO_FN_MSIOF2_TSYNC, GPIO_FN_LCD2D13,
+ GPIO_FN_VIO_D4, GPIO_FN_MSIOF2_TXD, GPIO_FN_LCD2D14,
+ GPIO_FN_VIO_D5, GPIO_FN_MSIOF2_TSCK, GPIO_FN_LCD2D15,
+ GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYOUT8, GPIO_FN_LCD2D16,
+ GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYOUT9, GPIO_FN_LCD2D17,
+ GPIO_FN_VIO_D8, GPIO_FN_PORT138_KEYOUT8, GPIO_FN_VIO2_D0, \
+ GPIO_FN_LCD2D6,
+ GPIO_FN_VIO_D9, GPIO_FN_PORT139_KEYOUT9, GPIO_FN_VIO2_D1, \
+ GPIO_FN_LCD2D7,
+ GPIO_FN_VIO_D10, GPIO_FN_TPU0TO2, GPIO_FN_VIO2_D2, GPIO_FN_LCD2D8,
+ GPIO_FN_VIO_D11, GPIO_FN_TPU0TO3, GPIO_FN_VIO2_D3, GPIO_FN_LCD2D9,
+ GPIO_FN_VIO_D12, GPIO_FN_PORT142_KEYOUT10, GPIO_FN_VIO2_D4, \
+ GPIO_FN_LCD2D2,
+ GPIO_FN_VIO_D13, GPIO_FN_PORT143_KEYOUT11, GPIO_FN_PORT143_KEYOUT6, \
+ GPIO_FN_VIO2_D5, GPIO_FN_LCD2D3,
+ GPIO_FN_VIO_D14, GPIO_FN_PORT144_KEYOUT7, GPIO_FN_VIO2_D6, \
+ GPIO_FN_LCD2D4,
+ GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_LCD2DISP, \
+ GPIO_FN_PORT145_LCD2RS, GPIO_FN_VIO2_D7, GPIO_FN_LCD2D5,
+ GPIO_FN_VIO_CLK, GPIO_FN_LCD2DCK, GPIO_FN_PORT146_LCD2WR_, \
+ GPIO_FN_VIO2_CLK, GPIO_FN_LCD2D18,
+ GPIO_FN_VIO_FIELD, GPIO_FN_LCD2RD_, GPIO_FN_VIO2_FIELD, GPIO_FN_LCD2D19,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_A27, GPIO_FN_PORT149_RDWR, GPIO_FN_MFG0_IN1, \
+ GPIO_FN_PORT149_KEYOUT9,
+ 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_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_SCIFA2_RTS1_, GPIO_FN_PORT156_MSIOF2_SS2,
+ GPIO_FN_SCIFA2_CTS1_, GPIO_FN_PORT157_MSIOF2_RXD,
+ 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_PORT161_SCIFB_CTS_, GPIO_FN_PORT161_SCIFA5_CTS_,
+ GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD,
+ GPIO_FN_PORT163_SCIFB_RTS_, GPIO_FN_PORT163_SCIFA5_RTS_, \
+ GPIO_FN_TPU3TO0,
+ GPIO_FN_LCDD0,
+ GPIO_FN_LCDD1, GPIO_FN_PORT193_SCIFA5_CTS_, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT194_SCIFA5_RTS_, GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT195_SCIFA5_RXD, GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT196_SCIFA5_TXD,
+ GPIO_FN_LCDD5, GPIO_FN_PORT197_SCIFA5_SCK, GPIO_FN_MFG2_OUT2, \
+ GPIO_FN_TPU2TO1,
+ GPIO_FN_LCDD6,
+ GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2,
+ GPIO_FN_LCDD8, GPIO_FN_D16,
+ GPIO_FN_LCDD9, GPIO_FN_D17,
+ GPIO_FN_LCDD10, GPIO_FN_D18,
+ GPIO_FN_LCDD11, GPIO_FN_D19,
+ GPIO_FN_LCDD12, GPIO_FN_D20,
+ GPIO_FN_LCDD13, GPIO_FN_D21,
+ GPIO_FN_LCDD14, GPIO_FN_D22,
+ GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_D23,
+ GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_D24,
+ GPIO_FN_LCDD17, 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_LCDRD_, GPIO_FN_DACK2, GPIO_FN_PORT217_LCD2RS, \
+ GPIO_FN_MSIOF0L_TSYNC, GPIO_FN_VIO2_FIELD3, GPIO_FN_PORT217_LCD2DISP,
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS_, GPIO_FN_LCDCS2_, GPIO_FN_DACK3, \
+ GPIO_FN_PORT218_VIO_CKOR,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_PORT219_LCD2WR_, \
+ GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK, GPIO_FN_VIO2_CLK3, \
+ GPIO_FN_LCD2DCK_2,
+ GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PORT221_LCD2CS_, \
+ GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD, GPIO_FN_VIO2_HD3, \
+ GPIO_FN_PORT221_LCD2HSYN,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN, \
+ GPIO_FN_MSIOF0L_TXD, GPIO_FN_VIO2_VD3, GPIO_FN_PORT222_LCD2VSYN,
+
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
+ GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, 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_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2_,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2_, GPIO_FN_VIO2_CLK2, \
+ GPIO_FN_LCD2D20,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_MFG1_IN2, GPIO_FN_VIO2_VD2, \
+ GPIO_FN_LCD2D21,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_PORT236_I2C_SDA2,
+ GPIO_FN_MSIOF1_MCK1, GPIO_FN_PORT237_I2C_SCL2,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_VIO2_FIELD2, GPIO_FN_LCD2D22,
+ GPIO_FN_MSIOF1_SS2, GPIO_FN_VIO2_HD2, GPIO_FN_LCD2D23,
+ 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_MSIOF2R_RXD,
+ GPIO_FN_PORT245_SCIFA5_RTS_, GPIO_FN_MFG2_IN2, \
+ GPIO_FN_PORT245_SCIFB_RTS_, GPIO_FN_MSIOF2R_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_I2C_SCL3, GPIO_FN_MSIOF2R_TSCK,
+ GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, \
+ GPIO_FN_PORT249_I2C_SDA3, GPIO_FN_MSIOF2R_TSYNC,
+ GPIO_FN_SDHICLK0,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0,
+ GPIO_FN_SDHID0_1,
+ GPIO_FN_SDHID0_2,
+ GPIO_FN_SDHID0_3,
+ GPIO_FN_SDHICMD0,
+ GPIO_FN_SDHIWP0,
+ GPIO_FN_SDHICLK1,
+ GPIO_FN_SDHID1_0, GPIO_FN_TS_SPSYNC2,
+ GPIO_FN_SDHID1_1, GPIO_FN_TS_SDAT2,
+ GPIO_FN_SDHID1_2, GPIO_FN_TS_SDEN2,
+ GPIO_FN_SDHID1_3, GPIO_FN_TS_SCK2,
+ GPIO_FN_SDHICMD1,
+ GPIO_FN_SDHICLK2,
+ GPIO_FN_SDHID2_0, GPIO_FN_TS_SPSYNC4,
+ GPIO_FN_SDHID2_1, GPIO_FN_TS_SDAT4,
+ GPIO_FN_SDHID2_2, GPIO_FN_TS_SDEN4,
+ GPIO_FN_SDHID2_3, GPIO_FN_TS_SCK4,
+ GPIO_FN_SDHICMD2,
+ GPIO_FN_MMCCLK0,
+ GPIO_FN_MMCD0_0,
+ GPIO_FN_MMCD0_1,
+ GPIO_FN_MMCD0_2,
+ GPIO_FN_MMCD0_3,
+ GPIO_FN_MMCD0_4, GPIO_FN_TS_SPSYNC5,
+ GPIO_FN_MMCD0_5, GPIO_FN_TS_SDAT5,
+ GPIO_FN_MMCD0_6, GPIO_FN_TS_SDEN5,
+ GPIO_FN_MMCD0_7, GPIO_FN_TS_SCK5,
+ GPIO_FN_MMCCMD0,
+ GPIO_FN_RESETOUTS_, GPIO_FN_EXTAL2OUT,
+ GPIO_FN_MCP_WAIT__MCP_FRB,
+ GPIO_FN_MCP_CKO, GPIO_FN_MMCCLK1,
+ GPIO_FN_MCP_D15_MCP_NAF15,
+ GPIO_FN_MCP_D14_MCP_NAF14,
+ GPIO_FN_MCP_D13_MCP_NAF13,
+ GPIO_FN_MCP_D12_MCP_NAF12,
+ GPIO_FN_MCP_D11_MCP_NAF11,
+ GPIO_FN_MCP_D10_MCP_NAF10,
+ GPIO_FN_MCP_D9_MCP_NAF9,
+ GPIO_FN_MCP_D8_MCP_NAF8, GPIO_FN_MMCCMD1,
+ GPIO_FN_MCP_D7_MCP_NAF7, GPIO_FN_MMCD1_7,
+
+ GPIO_FN_MCP_D6_MCP_NAF6, GPIO_FN_MMCD1_6,
+ GPIO_FN_MCP_D5_MCP_NAF5, GPIO_FN_MMCD1_5,
+ GPIO_FN_MCP_D4_MCP_NAF4, GPIO_FN_MMCD1_4,
+ GPIO_FN_MCP_D3_MCP_NAF3, GPIO_FN_MMCD1_3,
+ GPIO_FN_MCP_D2_MCP_NAF2, GPIO_FN_MMCD1_2,
+ GPIO_FN_MCP_D1_MCP_NAF1, GPIO_FN_MMCD1_1,
+ GPIO_FN_MCP_D0_MCP_NAF0, GPIO_FN_MMCD1_0,
+ GPIO_FN_MCP_NBRSTOUT_,
+ GPIO_FN_MCP_WE0__MCP_FWE, GPIO_FN_MCP_RDWR_MCP_FWE,
+
+ /* MSEL2 special case */
+ GPIO_FN_TSIF2_TS_XX1,
+ GPIO_FN_TSIF2_TS_XX2,
+ GPIO_FN_TSIF2_TS_XX3,
+ GPIO_FN_TSIF2_TS_XX4,
+ GPIO_FN_TSIF2_TS_XX5,
+ GPIO_FN_TSIF1_TS_XX1,
+ GPIO_FN_TSIF1_TS_XX2,
+ GPIO_FN_TSIF1_TS_XX3,
+ GPIO_FN_TSIF1_TS_XX4,
+ GPIO_FN_TSIF1_TS_XX5,
+ GPIO_FN_TSIF0_TS_XX1,
+ GPIO_FN_TSIF0_TS_XX2,
+ GPIO_FN_TSIF0_TS_XX3,
+ GPIO_FN_TSIF0_TS_XX4,
+ GPIO_FN_TSIF0_TS_XX5,
+ GPIO_FN_MST1_TS_XX1,
+ GPIO_FN_MST1_TS_XX2,
+ GPIO_FN_MST1_TS_XX3,
+ GPIO_FN_MST1_TS_XX4,
+ GPIO_FN_MST1_TS_XX5,
+ GPIO_FN_MST0_TS_XX1,
+ GPIO_FN_MST0_TS_XX2,
+ GPIO_FN_MST0_TS_XX3,
+ GPIO_FN_MST0_TS_XX4,
+ GPIO_FN_MST0_TS_XX5,
+
+ /* MSEL3 special cases */
+ GPIO_FN_SDHI0_VCCQ_MC0_ON,
+ GPIO_FN_SDHI0_VCCQ_MC0_OFF,
+ GPIO_FN_DEBUG_MON_VIO,
+ GPIO_FN_DEBUG_MON_LCDD,
+ GPIO_FN_LCDC_LCDC0,
+ GPIO_FN_LCDC_LCDC1,
+
+ /* MSEL4 special cases */
+ GPIO_FN_IRQ9_MEM_INT,
+ GPIO_FN_IRQ9_MCP_INT,
+ GPIO_FN_A11,
+ GPIO_FN_KEYOUT8,
+ GPIO_FN_TPU4TO3,
+ GPIO_FN_RESETA_N_PU_ON,
+ GPIO_FN_RESETA_N_PU_OFF,
+ GPIO_FN_EDBGREQ_PD,
+ GPIO_FN_EDBGREQ_PU,
+
+ /* Functions with pull-ups */
+ GPIO_FN_KEYIN0_PU,
+ GPIO_FN_KEYIN1_PU,
+ GPIO_FN_KEYIN2_PU,
+ GPIO_FN_KEYIN3_PU,
+ GPIO_FN_KEYIN4_PU,
+ GPIO_FN_KEYIN5_PU,
+ GPIO_FN_KEYIN6_PU,
+ GPIO_FN_KEYIN7_PU,
+ GPIO_FN_SDHID1_0_PU,
+ GPIO_FN_SDHID1_1_PU,
+ GPIO_FN_SDHID1_2_PU,
+ GPIO_FN_SDHID1_3_PU,
+ GPIO_FN_SDHICMD1_PU,
+ GPIO_FN_MMCCMD0_PU,
+ GPIO_FN_MMCCMD1_PU,
+ GPIO_FN_FSIACK_PU,
+ GPIO_FN_FSIAILR_PU,
+ GPIO_FN_FSIAIBT_PU,
+ GPIO_FN_FSIAISLD_PU,
+};
+
+#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
index 4aecf6e3a859..2b8fd8b942fe 100644
--- a/arch/arm/mach-shmobile/include/mach/vmalloc.h
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -2,6 +2,6 @@
#define __ASM_MACH_VMALLOC_H
/* Vmalloc at ... - 0xe5ffffff */
-#define VMALLOC_END 0xe6000000
+#define VMALLOC_END 0xe6000000UL
#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h
new file mode 100644
index 000000000000..3ad86b7708e9
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot.h
@@ -0,0 +1,20 @@
+#ifndef ZBOOT_H
+#define ZBOOT_H
+
+#include <asm/mach-types.h>
+#include <mach/zboot_macros.h>
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#define MACH_TYPE MACH_TYPE_AP4EVB
+#include "mach/head-ap4evb.txt"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* ZBOOT_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot_macros.h b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
new file mode 100644
index 000000000000..aa6111fbc989
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
@@ -0,0 +1,65 @@
+#ifndef __ZBOOT_MACRO_H
+#define __ZBOOT_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro ED, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STR r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro EW, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STRH r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro EB, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STRB r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro WAIT, time, reg
+ LDR r1, 1f
+ LDR r0, 2f
+ STR r0, [r1]
+10 :
+ LDR r0, [r1]
+ CMP r0, #0x00000000
+ BNE 10b
+ NOP
+ B 3f
+1 : .long \reg
+2 : .long \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro DD, start, end
+ LDR r1, 1f
+ B 2f
+1 : .long \start
+2 :
+.endm
+
+#endif /* __ZBOOT_MACRO_H */
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
new file mode 100644
index 000000000000..5af2be07c2b8
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -0,0 +1,267 @@
+/*
+ * sh73a0 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/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources INTCS */
+ PINTCS_PINT1, PINTCS_PINT2,
+ RTDMAC_0_DEI0, RTDMAC_0_DEI1, RTDMAC_0_DEI2, RTDMAC_0_DEI3,
+ CEU, MFI, BBIF2, VPU, TSIF1, _3DG_SGX543, _2DDMAC_2DDM0,
+ RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR,
+ KEYSC_KEY, VINT, MSIOF,
+ TMU0_TUNI00, TMU0_TUNI01, TMU0_TUNI02,
+ CMT0, TSIF0, CMT2, LMB, MSUG, MSU_MSU, MSU_MSU2,
+ CTI, RWDT0, ICB, PEP, ASA, JPU_JPEG, LCDC, LCRC,
+ RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
+ RTDMAC_3_DEI10, RTDMAC_3_DEI11,
+ FRC, GCU, LCDC1, CSIRX,
+ DSITX0_DSITX00, DSITX0_DSITX01,
+ SPU2_SPU0, SPU2_SPU1, FSI,
+ TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
+ TSIF2, CMT4, MFIS2, CPORTS2R, TSG, DMASCH1, SCUW,
+ VIO60, VIO61, CEU21, CSI21, DSITX1_DSITX10, DSITX1_DSITX11,
+ DISP, DSRV, EMUX2_EMUX20I, EMUX2_EMUX21I,
+ MSTIF0_MST00I, MSTIF0_MST01I, MSTIF1_MST10I, MSTIF1_MST11I,
+ SPUV,
+
+ /* interrupt groups INTCS */
+ RTDMAC_0, RTDMAC_1, RTDMAC_2, RTDMAC_3,
+ DSITX0, SPU2, TMU1, MSU,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ INTCS_VECT(PINTCS_PINT1, 0x0600), INTCS_VECT(PINTCS_PINT2, 0x0620),
+ INTCS_VECT(RTDMAC_0_DEI0, 0x0800), INTCS_VECT(RTDMAC_0_DEI1, 0x0820),
+ INTCS_VECT(RTDMAC_0_DEI2, 0x0840), INTCS_VECT(RTDMAC_0_DEI3, 0x0860),
+ INTCS_VECT(CEU, 0x0880), INTCS_VECT(MFI, 0x0900),
+ INTCS_VECT(BBIF2, 0x0960), INTCS_VECT(VPU, 0x0980),
+ INTCS_VECT(TSIF1, 0x09a0), INTCS_VECT(_3DG_SGX543, 0x09e0),
+ INTCS_VECT(_2DDMAC_2DDM0, 0x0a00),
+ INTCS_VECT(RTDMAC_1_DEI4, 0x0b80), INTCS_VECT(RTDMAC_1_DEI5, 0x0ba0),
+ INTCS_VECT(RTDMAC_1_DADERR, 0x0bc0),
+ INTCS_VECT(KEYSC_KEY, 0x0be0), INTCS_VECT(VINT, 0x0c80),
+ INTCS_VECT(MSIOF, 0x0d20),
+ INTCS_VECT(TMU0_TUNI00, 0x0e80), INTCS_VECT(TMU0_TUNI01, 0x0ea0),
+ INTCS_VECT(TMU0_TUNI02, 0x0ec0),
+ INTCS_VECT(CMT0, 0x0f00), INTCS_VECT(TSIF0, 0x0f20),
+ INTCS_VECT(CMT2, 0x0f40), INTCS_VECT(LMB, 0x0f60),
+ INTCS_VECT(MSUG, 0x0f80),
+ INTCS_VECT(MSU_MSU, 0x0fa0), INTCS_VECT(MSU_MSU2, 0x0fc0),
+ INTCS_VECT(CTI, 0x0400), INTCS_VECT(RWDT0, 0x0440),
+ INTCS_VECT(ICB, 0x0480), INTCS_VECT(PEP, 0x04a0),
+ INTCS_VECT(ASA, 0x04c0), INTCS_VECT(JPU_JPEG, 0x0560),
+ INTCS_VECT(LCDC, 0x0580), INTCS_VECT(LCRC, 0x05a0),
+ INTCS_VECT(RTDMAC_2_DEI6, 0x1300), INTCS_VECT(RTDMAC_2_DEI7, 0x1320),
+ INTCS_VECT(RTDMAC_2_DEI8, 0x1340), INTCS_VECT(RTDMAC_2_DEI9, 0x1360),
+ INTCS_VECT(RTDMAC_3_DEI10, 0x1380), INTCS_VECT(RTDMAC_3_DEI11, 0x13a0),
+ INTCS_VECT(FRC, 0x1700), INTCS_VECT(GCU, 0x1760),
+ INTCS_VECT(LCDC1, 0x1780), INTCS_VECT(CSIRX, 0x17a0),
+ INTCS_VECT(DSITX0_DSITX00, 0x17c0), INTCS_VECT(DSITX0_DSITX01, 0x17e0),
+ INTCS_VECT(SPU2_SPU0, 0x1800), INTCS_VECT(SPU2_SPU1, 0x1820),
+ INTCS_VECT(FSI, 0x1840),
+ INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
+ INTCS_VECT(TMU1_TUNI12, 0x1940),
+ INTCS_VECT(TSIF2, 0x1960), INTCS_VECT(CMT4, 0x1980),
+ INTCS_VECT(MFIS2, 0x1a00), INTCS_VECT(CPORTS2R, 0x1a20),
+ INTCS_VECT(TSG, 0x1ae0), INTCS_VECT(DMASCH1, 0x1b00),
+ INTCS_VECT(SCUW, 0x1b40),
+ INTCS_VECT(VIO60, 0x1b60), INTCS_VECT(VIO61, 0x1b80),
+ INTCS_VECT(CEU21, 0x1ba0), INTCS_VECT(CSI21, 0x1be0),
+ INTCS_VECT(DSITX1_DSITX10, 0x1c00), INTCS_VECT(DSITX1_DSITX11, 0x1c20),
+ INTCS_VECT(DISP, 0x1c40), INTCS_VECT(DSRV, 0x1c60),
+ INTCS_VECT(EMUX2_EMUX20I, 0x1c80), INTCS_VECT(EMUX2_EMUX21I, 0x1ca0),
+ INTCS_VECT(MSTIF0_MST00I, 0x1cc0), INTCS_VECT(MSTIF0_MST01I, 0x1ce0),
+ INTCS_VECT(MSTIF1_MST10I, 0x1d00), INTCS_VECT(MSTIF1_MST11I, 0x1d20),
+ INTCS_VECT(SPUV, 0x2300),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC_0, RTDMAC_0_DEI0, RTDMAC_0_DEI1,
+ RTDMAC_0_DEI2, RTDMAC_0_DEI3),
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI6, RTDMAC_2_DEI7,
+ RTDMAC_2_DEI8, RTDMAC_2_DEI9),
+ INTC_GROUP(RTDMAC_3, RTDMAC_3_DEI10, RTDMAC_3_DEI11),
+ INTC_GROUP(TMU1, TMU1_TUNI12, TMU1_TUNI11, TMU1_TUNI10),
+ INTC_GROUP(DSITX0, DSITX0_DSITX00, DSITX0_DSITX01),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(MSU, MSU_MSU, MSU_MSU2),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { 0, 0, 0, CEU,
+ 0, 0, 0, 0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { 0, 0, 0, VPU,
+ BBIF2, 0, 0, MFI } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { 0, 0, 0, _2DDMAC_2DDM0,
+ 0, ASA, PEP, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, 0, CTI,
+ JPU_JPEG, 0, LCRC, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { KEYSC_KEY, RTDMAC_1_DADERR, RTDMAC_1_DEI5, RTDMAC_1_DEI4,
+ RTDMAC_0_DEI3, RTDMAC_0_DEI2, RTDMAC_0_DEI1, RTDMAC_0_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ _3DG_SGX543, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU0_TUNI02, TMU0_TUNI01, TMU0_TUNI00,
+ 0, 0, 0, 0 } },
+ { 0xffd201a0, 0xffd201e0, 8, /* IMR8SA / IMCR8SA */
+ { 0, 0, 0, 0,
+ 0, MSU_MSU, MSU_MSU2, MSUG } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, RWDT0, CMT2, CMT0,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { 0, 0, 0, 0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xffd201b0, 0xffd201f0, 8, /* IMR12SA / IMCR12SA */
+ { 0, 0, 0, 0,
+ 0, 0, PINTCS_PINT2, PINTCS_PINT1 } },
+ { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
+ { RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
+ RTDMAC_3_DEI10, RTDMAC_3_DEI11, 0, 0 } },
+ { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
+ { FRC, 0, 0, GCU,
+ LCDC1, CSIRX, DSITX0_DSITX00, DSITX0_DSITX01 } },
+ { 0xffd50194, 0xffd501d4, 8, /* IMR5SA3 / IMCR5SA3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
+ { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, 0,
+ TSIF2, CMT4, 0, 0 } },
+ { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
+ { MFIS2, CPORTS2R, 0, 0,
+ 0, 0, 0, TSG } },
+ { 0xffd501a0, 0xffd501e0, 8, /* IMR8SA3 / IMCR8SA3 */
+ { DMASCH1, 0, SCUW, VIO60,
+ VIO61, CEU21, 0, CSI21 } },
+ { 0xffd501a4, 0xffd501e4, 8, /* IMR9SA3 / IMCR9SA3 */
+ { DSITX1_DSITX10, DSITX1_DSITX11, DISP, DSRV,
+ EMUX2_EMUX20I, EMUX2_EMUX21I, MSTIF0_MST00I, MSTIF0_MST01I } },
+ { 0xffd501a8, 0xffd501e8, 8, /* IMR10SA3 / IMCR10SA3 */
+ { MSTIF0_MST00I, MSTIF0_MST01I, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd60180, 0xffd601c0, 8, /* IMR0SA4 / IMCR0SA4 */
+ { SPUV, 0, 0, 0,
+ 0, 0, 0, 0 } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC_2DDM0, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
+ { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
+ { 0xffd2000c, 0, 16, 4, /* IPRDS */ { PINTCS_PINT1, PINTCS_PINT2,
+ 0, 0 } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_0, CEU, MFI, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { KEYSC_KEY, RTDMAC_1,
+ CMT2, CMT0 } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU0_TUNI00, TMU0_TUNI01,
+ TMU0_TUNI02, TSIF1 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { VINT, 0, 0, 0 } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, 0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX543, MSUG, MSU } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, ASA, LMB, PEP } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { 0, 0, 0, RWDT0 } },
+ { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC_2, 0, 0, 0 } },
+ { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC_3, 0, 0, 0 } },
+ { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { FRC, 0, 0, 0 } },
+ { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX0, 0 } },
+ { 0xffd50028, 0, 16, 4, /* IPRKS3 */ { SPU2, 0, FSI, 0 } },
+ { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, TSIF2 } },
+ { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, 0, 0, 0 } },
+ { 0xffd50038, 0, 16, 4, /* IPROS3 */ { MFIS2, CPORTS2R, 0, 0 } },
+ { 0xffd50040, 0, 16, 4, /* IPRQS3 */ { DMASCH1, 0, SCUW, VIO60 } },
+ { 0xffd50044, 0, 16, 4, /* IPRRS3 */ { VIO61, CEU21, 0, CSI21 } },
+ { 0xffd50048, 0, 16, 4, /* IPRSS3 */ { DSITX1_DSITX10, DSITX1_DSITX11,
+ DISP, DSRV } },
+ { 0xffd5004c, 0, 16, 4, /* IPRTS3 */ { EMUX2_EMUX20I, EMUX2_EMUX21I,
+ MSTIF0_MST00I, MSTIF0_MST01I } },
+ { 0xffd50050, 0, 16, 4, /* IPRUS3 */ { MSTIF1_MST10I, MSTIF1_MST11I,
+ 0, 0 } },
+ { 0xffd60000, 0, 16, 4, /* IPRAS4 */ { SPUV, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd201ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffd50000,
+ .end = 0xffd501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 0xffd60000,
+ .end = 0xffd601ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh73a0-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static struct irqaction sh73a0_intcs_cascade;
+
+static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
+{
+ unsigned int evtcodeas = ioread32((void __iomem *)dev_id);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+
+ return IRQ_HANDLED;
+}
+
+void __init sh73a0_init_irq(void)
+{
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ gic_dist_init(0, __io(0xf0001000), 29);
+ gic_cpu_init(0, __io(0xf0000100));
+
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ sh73a0_intcs_cascade.name = "INTCS cascade";
+ sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
+ sh73a0_intcs_cascade.dev_id = intevtsa;
+ setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
new file mode 100644
index 000000000000..3eed44eb98b4
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
@@ -0,0 +1,2746 @@
+/*
+ * sh73a0 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * 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/sh73a0.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 _310(fn, pfx, sfx) \
+ _10(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), \
+ _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), \
+ _10(fn, pfx##26, sfx), _10(fn, pfx##27, sfx), \
+ _1(fn, pfx##280, sfx), _1(fn, pfx##281, sfx), \
+ _1(fn, pfx##282, sfx), \
+ _1(fn, pfx##288, sfx), _1(fn, pfx##289, sfx), \
+ _10(fn, pfx##29, sfx), _10(fn, pfx##30, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_310(str) _310(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_310(DATA), /* PORT0_DATA -> PORT309_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_310(IN), /* PORT0_IN -> PORT309_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_310(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_310(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_310(OUT), /* PORT0_OUT -> PORT309_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_310(FN_IN), /* PORT0_FN_IN -> PORT309_FN_IN */
+ PORT_310(FN_OUT), /* PORT0_FN_OUT -> PORT309_FN_OUT */
+ PORT_310(FN0), /* PORT0_FN0 -> PORT309_FN0 */
+ PORT_310(FN1), /* PORT0_FN1 -> PORT309_FN1 */
+ PORT_310(FN2), /* PORT0_FN2 -> PORT309_FN2 */
+ PORT_310(FN3), /* PORT0_FN3 -> PORT309_FN3 */
+ PORT_310(FN4), /* PORT0_FN4 -> PORT309_FN4 */
+ PORT_310(FN5), /* PORT0_FN5 -> PORT309_FN5 */
+ PORT_310(FN6), /* PORT0_FN6 -> PORT309_FN6 */
+ PORT_310(FN7), /* PORT0_FN7 -> PORT309_FN7 */
+
+ MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
+ MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
+ MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1,
+ MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1,
+ MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1,
+ MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1,
+ MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1,
+ MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1,
+ MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1,
+ MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1,
+ MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1,
+ MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1,
+ MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1,
+ MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1,
+ MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_1,
+ MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1,
+ MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1,
+ MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1,
+ MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1,
+ MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1,
+ MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1,
+ MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1,
+ MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1,
+ MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1,
+ MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1,
+ MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1,
+ MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1,
+ MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1,
+ MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1,
+ MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1,
+ MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1,
+ MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1,
+ MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1,
+ MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1,
+ MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1,
+ MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Hardware manual Table 25-1 (Function 0-7) */
+ VBUS_0_MARK,
+ GPI0_MARK,
+ GPI1_MARK,
+ GPI2_MARK,
+ GPI3_MARK,
+ GPI4_MARK,
+ GPI5_MARK,
+ GPI6_MARK,
+ GPI7_MARK,
+ SCIFA7_RXD_MARK,
+ SCIFA7_CTS__MARK,
+ GPO7_MARK, MFG0_OUT2_MARK,
+ GPO6_MARK, MFG1_OUT2_MARK,
+ GPO5_MARK, SCIFA0_SCK_MARK, FSICOSLDT3_MARK, PORT16_VIO_CKOR_MARK,
+ SCIFA0_TXD_MARK,
+ SCIFA7_TXD_MARK,
+ SCIFA7_RTS__MARK, PORT19_VIO_CKO2_MARK,
+ GPO0_MARK,
+ GPO1_MARK,
+ GPO2_MARK, STATUS0_MARK,
+ GPO3_MARK, STATUS1_MARK,
+ GPO4_MARK, STATUS2_MARK,
+ VINT_MARK,
+ TCKON_MARK,
+ XDVFS1_MARK, PORT27_I2C_SCL2_MARK, PORT27_I2C_SCL3_MARK, \
+ MFG0_OUT1_MARK, PORT27_IROUT_MARK,
+ XDVFS2_MARK, PORT28_I2C_SDA2_MARK, PORT28_I2C_SDA3_MARK, \
+ PORT28_TPU1TO1_MARK,
+ SIM_RST_MARK, PORT29_TPU1TO1_MARK,
+ SIM_CLK_MARK, PORT30_VIO_CKOR_MARK,
+ SIM_D_MARK, PORT31_IROUT_MARK,
+ SCIFA4_TXD_MARK,
+ SCIFA4_RXD_MARK, XWUP_MARK,
+ SCIFA4_RTS__MARK,
+ SCIFA4_CTS__MARK,
+ FSIBOBT_MARK, FSIBIBT_MARK,
+ FSIBOLR_MARK, FSIBILR_MARK,
+ FSIBOSLD_MARK,
+ FSIBISLD_MARK,
+ VACK_MARK,
+ XTAL1L_MARK,
+ SCIFA0_RTS__MARK, FSICOSLDT2_MARK,
+ SCIFA0_RXD_MARK,
+ SCIFA0_CTS__MARK, FSICOSLDT1_MARK,
+ FSICOBT_MARK, FSICIBT_MARK, FSIDOBT_MARK, FSIDIBT_MARK,
+ FSICOLR_MARK, FSICILR_MARK, FSIDOLR_MARK, FSIDILR_MARK,
+ FSICOSLD_MARK, PORT47_FSICSPDIF_MARK,
+ FSICISLD_MARK, FSIDISLD_MARK,
+ FSIACK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK, FSIAOMC_MARK,
+ FSIAOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, FSIAILR_MARK,
+
+ FSIAOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, FSIAIBT_MARK,
+ FSIAOSLD_MARK, BBIF2_TXD2_MARK,
+ FSIASPDIF_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, FSIBSPDIF_MARK, \
+ PORT53_FSICSPDIF_MARK,
+ FSIBCK_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FSIBOMC_MARK, \
+ FSICCK_MARK, FSICOMC_MARK,
+ FSIAISLD_MARK, TPU0TO0_MARK,
+ A0_MARK, BS__MARK,
+ A12_MARK, PORT58_KEYOUT7_MARK, TPU4TO2_MARK,
+ A13_MARK, PORT59_KEYOUT6_MARK, TPU0TO1_MARK,
+ A14_MARK, KEYOUT5_MARK,
+ A15_MARK, KEYOUT4_MARK,
+ A16_MARK, KEYOUT3_MARK, MSIOF0_SS1_MARK,
+ A17_MARK, KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
+ A18_MARK, KEYOUT1_MARK, MSIOF0_TSCK_MARK,
+ A19_MARK, KEYOUT0_MARK, MSIOF0_TXD_MARK,
+ A20_MARK, KEYIN0_MARK, MSIOF0_RSCK_MARK,
+ A21_MARK, KEYIN1_MARK, MSIOF0_RSYNC_MARK,
+ A22_MARK, KEYIN2_MARK, MSIOF0_MCK0_MARK,
+ A23_MARK, KEYIN3_MARK, MSIOF0_MCK1_MARK,
+ A24_MARK, KEYIN4_MARK, MSIOF0_RXD_MARK,
+ A25_MARK, KEYIN5_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, KEYIN6_MARK,
+ KEYIN7_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,
+ CS4__MARK,
+ CS5A__MARK, PORT91_RDWR_MARK,
+ CS5B__MARK, FCE1__MARK,
+ CS6B__MARK, DACK0_MARK,
+ FCE0__MARK, CS6A__MARK,
+ WAIT__MARK, DREQ0_MARK,
+ RD__FSC_MARK,
+ WE0__FWE_MARK, RDWR_FWE_MARK,
+ WE1__MARK,
+ FRB_MARK,
+ CKO_MARK,
+ NBRSTOUT__MARK,
+ NBRST__MARK,
+ BBIF2_TXD_MARK,
+ BBIF2_RXD_MARK,
+ BBIF2_SYNC_MARK,
+ BBIF2_SCK_MARK,
+ SCIFA3_CTS__MARK, MFG3_IN2_MARK,
+ SCIFA3_RXD_MARK, MFG3_IN1_MARK,
+ BBIF1_SS2_MARK, SCIFA3_RTS__MARK, MFG3_OUT1_MARK,
+ SCIFA3_TXD_MARK,
+ HSI_RX_DATA_MARK, BBIF1_RXD_MARK,
+ HSI_TX_WAKE_MARK, BBIF1_TSCK_MARK,
+ HSI_TX_DATA_MARK, BBIF1_TSYNC_MARK,
+ HSI_TX_READY_MARK, BBIF1_TXD_MARK,
+ HSI_RX_READY_MARK, BBIF1_RSCK_MARK, PORT115_I2C_SCL2_MARK, \
+ PORT115_I2C_SCL3_MARK,
+ HSI_RX_WAKE_MARK, BBIF1_RSYNC_MARK, PORT116_I2C_SDA2_MARK, \
+ PORT116_I2C_SDA3_MARK,
+ HSI_RX_FLAG_MARK, BBIF1_SS1_MARK, BBIF1_FLOW_MARK,
+ HSI_TX_FLAG_MARK,
+ VIO_VD_MARK, PORT128_LCD2VSYN_MARK, VIO2_VD_MARK, LCD2D0_MARK,
+
+ VIO_HD_MARK, PORT129_LCD2HSYN_MARK, PORT129_LCD2CS__MARK, \
+ VIO2_HD_MARK, LCD2D1_MARK,
+ VIO_D0_MARK, PORT130_MSIOF2_RXD_MARK, LCD2D10_MARK,
+ VIO_D1_MARK, PORT131_KEYOUT6_MARK, PORT131_MSIOF2_SS1_MARK, \
+ PORT131_KEYOUT11_MARK, LCD2D11_MARK,
+ VIO_D2_MARK, PORT132_KEYOUT7_MARK, PORT132_MSIOF2_SS2_MARK, \
+ PORT132_KEYOUT10_MARK, LCD2D12_MARK,
+ VIO_D3_MARK, MSIOF2_TSYNC_MARK, LCD2D13_MARK,
+ VIO_D4_MARK, MSIOF2_TXD_MARK, LCD2D14_MARK,
+ VIO_D5_MARK, MSIOF2_TSCK_MARK, LCD2D15_MARK,
+ VIO_D6_MARK, PORT136_KEYOUT8_MARK, LCD2D16_MARK,
+ VIO_D7_MARK, PORT137_KEYOUT9_MARK, LCD2D17_MARK,
+ VIO_D8_MARK, PORT138_KEYOUT8_MARK, VIO2_D0_MARK, LCD2D6_MARK,
+ VIO_D9_MARK, PORT139_KEYOUT9_MARK, VIO2_D1_MARK, LCD2D7_MARK,
+ VIO_D10_MARK, TPU0TO2_MARK, VIO2_D2_MARK, LCD2D8_MARK,
+ VIO_D11_MARK, TPU0TO3_MARK, VIO2_D3_MARK, LCD2D9_MARK,
+ VIO_D12_MARK, PORT142_KEYOUT10_MARK, VIO2_D4_MARK, LCD2D2_MARK,
+ VIO_D13_MARK, PORT143_KEYOUT11_MARK, PORT143_KEYOUT6_MARK, \
+ VIO2_D5_MARK, LCD2D3_MARK,
+ VIO_D14_MARK, PORT144_KEYOUT7_MARK, VIO2_D6_MARK, LCD2D4_MARK,
+ VIO_D15_MARK, TPU1TO3_MARK, PORT145_LCD2DISP_MARK, \
+ PORT145_LCD2RS_MARK, VIO2_D7_MARK, LCD2D5_MARK,
+ VIO_CLK_MARK, LCD2DCK_MARK, PORT146_LCD2WR__MARK, VIO2_CLK_MARK, \
+ LCD2D18_MARK,
+ VIO_FIELD_MARK, LCD2RD__MARK, VIO2_FIELD_MARK, LCD2D19_MARK,
+ VIO_CKO_MARK,
+ A27_MARK, PORT149_RDWR_MARK, MFG0_IN1_MARK, PORT149_KEYOUT9_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,
+ SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
+ SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
+ SCIFA2_RTS1__MARK, PORT156_MSIOF2_SS2_MARK,
+ SCIFA2_CTS1__MARK, PORT157_MSIOF2_RXD_MARK,
+ 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,
+ PORT161_SCIFB_CTS__MARK, PORT161_SCIFA5_CTS__MARK,
+ PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK,
+ PORT163_SCIFB_RTS__MARK, PORT163_SCIFA5_RTS__MARK, TPU3TO0_MARK,
+ LCDD0_MARK,
+ LCDD1_MARK, PORT193_SCIFA5_CTS__MARK, BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT194_SCIFA5_RTS__MARK, BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT195_SCIFA5_RXD_MARK, BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT196_SCIFA5_TXD_MARK,
+ LCDD5_MARK, PORT197_SCIFA5_SCK_MARK, MFG2_OUT2_MARK, TPU2TO1_MARK,
+ LCDD6_MARK,
+ LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK,
+ LCDD8_MARK, D16_MARK,
+ LCDD9_MARK, D17_MARK,
+ LCDD10_MARK, D18_MARK,
+ LCDD11_MARK, D19_MARK,
+ LCDD12_MARK, D20_MARK,
+ LCDD13_MARK, D21_MARK,
+ LCDD14_MARK, D22_MARK,
+ LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, D23_MARK,
+ LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, D24_MARK,
+ LCDD17_MARK, D25_MARK,
+ LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK,
+ LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK,
+ LCDDCK_MARK, LCDWR__MARK,
+ LCDRD__MARK, DACK2_MARK, PORT217_LCD2RS_MARK, MSIOF0L_TSYNC_MARK, \
+ VIO2_FIELD3_MARK, PORT217_LCD2DISP_MARK,
+ LCDHSYN_MARK, LCDCS__MARK, LCDCS2__MARK, DACK3_MARK, \
+ PORT218_VIO_CKOR_MARK,
+ LCDDISP_MARK, LCDRS_MARK, PORT219_LCD2WR__MARK, DREQ3_MARK, \
+ MSIOF0L_TSCK_MARK, VIO2_CLK3_MARK, LCD2DCK_2_MARK,
+ LCDVSYN_MARK, LCDVSYN2_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, PORT221_LCD2CS__MARK, PWEN_MARK, \
+ MSIOF0L_RXD_MARK, VIO2_HD3_MARK, PORT221_LCD2HSYN_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK, \
+ VIO2_VD3_MARK, PORT222_LCD2VSYN_MARK,
+
+ SCIFA1_TXD_MARK, OVCN2_MARK,
+ EXTLP_MARK, SCIFA1_SCK_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,
+ MSIOF1_TSYNC_MARK, SCIFA2_CTS2__MARK,
+ MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK,
+ MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK,
+ MSIOF1_RSCK_MARK, SCIFA2_RTS2__MARK, VIO2_CLK2_MARK, LCD2D20_MARK,
+ MSIOF1_RSYNC_MARK, MFG1_IN2_MARK, VIO2_VD2_MARK, LCD2D21_MARK,
+ MSIOF1_MCK0_MARK, PORT236_I2C_SDA2_MARK,
+ MSIOF1_MCK1_MARK, PORT237_I2C_SCL2_MARK,
+ MSIOF1_SS1_MARK, VIO2_FIELD2_MARK, LCD2D22_MARK,
+ MSIOF1_SS2_MARK, VIO2_HD2_MARK, LCD2D23_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, \
+ MSIOF2R_RXD_MARK,
+ PORT245_SCIFA5_RTS__MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS__MARK, \
+ MSIOF2R_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_I2C_SCL3_MARK, MSIOF2R_TSCK_MARK,
+ PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_I2C_SDA3_MARK, \
+ MSIOF2R_TSYNC_MARK,
+ SDHICLK0_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK,
+ SDHID0_1_MARK,
+ SDHID0_2_MARK,
+ SDHID0_3_MARK,
+ SDHICMD0_MARK,
+ SDHIWP0_MARK,
+ SDHICLK1_MARK,
+ SDHID1_0_MARK, TS_SPSYNC2_MARK,
+ SDHID1_1_MARK, TS_SDAT2_MARK,
+ SDHID1_2_MARK, TS_SDEN2_MARK,
+ SDHID1_3_MARK, TS_SCK2_MARK,
+ SDHICMD1_MARK,
+ SDHICLK2_MARK,
+ SDHID2_0_MARK, TS_SPSYNC4_MARK,
+ SDHID2_1_MARK, TS_SDAT4_MARK,
+ SDHID2_2_MARK, TS_SDEN4_MARK,
+ SDHID2_3_MARK, TS_SCK4_MARK,
+ SDHICMD2_MARK,
+ MMCCLK0_MARK,
+ MMCD0_0_MARK,
+ MMCD0_1_MARK,
+ MMCD0_2_MARK,
+ MMCD0_3_MARK,
+ MMCD0_4_MARK, TS_SPSYNC5_MARK,
+ MMCD0_5_MARK, TS_SDAT5_MARK,
+ MMCD0_6_MARK, TS_SDEN5_MARK,
+ MMCD0_7_MARK, TS_SCK5_MARK,
+ MMCCMD0_MARK,
+ RESETOUTS__MARK, EXTAL2OUT_MARK,
+ MCP_WAIT__MCP_FRB_MARK,
+ MCP_CKO_MARK, MMCCLK1_MARK,
+ MCP_D15_MCP_NAF15_MARK,
+ MCP_D14_MCP_NAF14_MARK,
+ MCP_D13_MCP_NAF13_MARK,
+ MCP_D12_MCP_NAF12_MARK,
+ MCP_D11_MCP_NAF11_MARK,
+ MCP_D10_MCP_NAF10_MARK,
+ MCP_D9_MCP_NAF9_MARK,
+ MCP_D8_MCP_NAF8_MARK, MMCCMD1_MARK,
+ MCP_D7_MCP_NAF7_MARK, MMCD1_7_MARK,
+
+ MCP_D6_MCP_NAF6_MARK, MMCD1_6_MARK,
+ MCP_D5_MCP_NAF5_MARK, MMCD1_5_MARK,
+ MCP_D4_MCP_NAF4_MARK, MMCD1_4_MARK,
+ MCP_D3_MCP_NAF3_MARK, MMCD1_3_MARK,
+ MCP_D2_MCP_NAF2_MARK, MMCD1_2_MARK,
+ MCP_D1_MCP_NAF1_MARK, MMCD1_1_MARK,
+ MCP_D0_MCP_NAF0_MARK, MMCD1_0_MARK,
+ MCP_NBRSTOUT__MARK,
+ MCP_WE0__MCP_FWE_MARK, MCP_RDWR_MCP_FWE_MARK,
+
+ /* MSEL2 special cases */
+ TSIF2_TS_XX1_MARK,
+ TSIF2_TS_XX2_MARK,
+ TSIF2_TS_XX3_MARK,
+ TSIF2_TS_XX4_MARK,
+ TSIF2_TS_XX5_MARK,
+ TSIF1_TS_XX1_MARK,
+ TSIF1_TS_XX2_MARK,
+ TSIF1_TS_XX3_MARK,
+ TSIF1_TS_XX4_MARK,
+ TSIF1_TS_XX5_MARK,
+ TSIF0_TS_XX1_MARK,
+ TSIF0_TS_XX2_MARK,
+ TSIF0_TS_XX3_MARK,
+ TSIF0_TS_XX4_MARK,
+ TSIF0_TS_XX5_MARK,
+ MST1_TS_XX1_MARK,
+ MST1_TS_XX2_MARK,
+ MST1_TS_XX3_MARK,
+ MST1_TS_XX4_MARK,
+ MST1_TS_XX5_MARK,
+ MST0_TS_XX1_MARK,
+ MST0_TS_XX2_MARK,
+ MST0_TS_XX3_MARK,
+ MST0_TS_XX4_MARK,
+ MST0_TS_XX5_MARK,
+
+ /* MSEL3 special cases */
+ SDHI0_VCCQ_MC0_ON_MARK,
+ SDHI0_VCCQ_MC0_OFF_MARK,
+ DEBUG_MON_VIO_MARK,
+ DEBUG_MON_LCDD_MARK,
+ LCDC_LCDC0_MARK,
+ LCDC_LCDC1_MARK,
+
+ /* MSEL4 special cases */
+ IRQ9_MEM_INT_MARK,
+ IRQ9_MCP_INT_MARK,
+ A11_MARK,
+ KEYOUT8_MARK,
+ TPU4TO3_MARK,
+ RESETA_N_PU_ON_MARK,
+ RESETA_N_PU_OFF_MARK,
+ EDBGREQ_PD_MARK,
+ EDBGREQ_PU_MARK,
+
+ /* Functions with pull-ups */
+ KEYIN0_PU_MARK,
+ KEYIN1_PU_MARK,
+ KEYIN2_PU_MARK,
+ KEYIN3_PU_MARK,
+ KEYIN4_PU_MARK,
+ KEYIN5_PU_MARK,
+ KEYIN6_PU_MARK,
+ KEYIN7_PU_MARK,
+ SDHID1_0_PU_MARK,
+ SDHID1_1_PU_MARK,
+ SDHID1_2_PU_MARK,
+ SDHID1_3_PU_MARK,
+ SDHICMD1_PU_MARK,
+ MMCCMD0_PU_MARK,
+ MMCCMD1_PU_MARK,
+ FSIACK_PU_MARK,
+ FSIAILR_PU_MARK,
+ FSIAIBT_PU_MARK,
+ FSIAISLD_PU_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 */
+
+ /* Table 25-1 (I/O and Pull U/D) */
+ 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_PD(9),
+ PORT_DATA_I_PD(10),
+ PORT_DATA_I_PU_PD(11),
+ PORT_DATA_IO_PU_PD(12),
+ PORT_DATA_IO_PU_PD(13),
+ PORT_DATA_IO_PU_PD(14),
+ PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_IO_PD(16),
+ PORT_DATA_IO_PD(17),
+ PORT_DATA_IO_PU(18),
+ PORT_DATA_IO_PU(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_IO_PU(27),
+ PORT_DATA_IO_PU(28),
+ PORT_DATA_IO_PD(29),
+ PORT_DATA_IO_PD(30),
+ PORT_DATA_IO_PU(31),
+ PORT_DATA_IO_PD(32),
+ PORT_DATA_I_PU_PD(33),
+ PORT_DATA_IO_PD(34),
+ PORT_DATA_I_PU_PD(35),
+ PORT_DATA_IO_PD(36),
+ PORT_DATA_IO(37),
+ 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_PU_PD(43),
+ PORT_DATA_IO_PU_PD(44),
+ PORT_DATA_IO_PD(45),
+ PORT_DATA_IO_PD(46),
+ PORT_DATA_IO_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_PU_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),
+ 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_PU_PD(104),
+ PORT_DATA_I_PD(105),
+ PORT_DATA_I_PD(106),
+ PORT_DATA_I_PU_PD(107),
+ PORT_DATA_I_PU_PD(108),
+ PORT_DATA_IO_PD(109),
+ PORT_DATA_IO_PD(110),
+ PORT_DATA_IO_PU_PD(111),
+ PORT_DATA_IO_PU_PD(112),
+ PORT_DATA_IO_PU_PD(113),
+ PORT_DATA_IO_PD(114),
+ PORT_DATA_IO_PU(115),
+ PORT_DATA_IO_PU(116),
+ PORT_DATA_IO_PU_PD(117),
+ PORT_DATA_IO_PU_PD(118),
+ PORT_DATA_IO_PD(128),
+
+ PORT_DATA_IO_PD(129),
+ PORT_DATA_IO_PU_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_PU_PD(150),
+ PORT_DATA_IO_PU_PD(151),
+ PORT_DATA_IO_PU_PD(152),
+ PORT_DATA_IO_PD(153),
+ PORT_DATA_IO_PD(154),
+ PORT_DATA_I_PU_PD(155),
+ PORT_DATA_IO_PU_PD(156),
+ PORT_DATA_I_PD(157),
+ PORT_DATA_IO_PD(158),
+ 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_PU_PD(193),
+ PORT_DATA_IO_PD(194),
+ PORT_DATA_IO_PU_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_PU_PD(214),
+ PORT_DATA_IO_PU_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_PU_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_PU_PD(228),
+ PORT_DATA_I_PD(229),
+ PORT_DATA_IO(230),
+ PORT_DATA_IO_PU_PD(231),
+ PORT_DATA_IO_PU_PD(232),
+ PORT_DATA_I_PU_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),
+ 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_PU_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_PU_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),
+ PORT_DATA_IO_PU_PD(264),
+ PORT_DATA_IO_PU_PD(265),
+ PORT_DATA_IO_PU_PD(266),
+ PORT_DATA_IO_PU_PD(267),
+ PORT_DATA_IO_PU_PD(268),
+ PORT_DATA_IO_PU_PD(269),
+ PORT_DATA_IO_PU_PD(270),
+ PORT_DATA_IO_PU_PD(271),
+ PORT_DATA_IO_PU_PD(272),
+ PORT_DATA_IO_PU_PD(273),
+ PORT_DATA_IO_PU_PD(274),
+ PORT_DATA_IO_PU_PD(275),
+ PORT_DATA_IO_PU_PD(276),
+ PORT_DATA_IO_PU_PD(277),
+ PORT_DATA_IO_PU_PD(278),
+ PORT_DATA_IO_PU_PD(279),
+ PORT_DATA_IO_PU_PD(280),
+ PORT_DATA_O(281),
+ PORT_DATA_O(282),
+ PORT_DATA_I_PU(288),
+ PORT_DATA_IO_PU_PD(289),
+ PORT_DATA_IO_PU_PD(290),
+ PORT_DATA_IO_PU_PD(291),
+ PORT_DATA_IO_PU_PD(292),
+ PORT_DATA_IO_PU_PD(293),
+ PORT_DATA_IO_PU_PD(294),
+ PORT_DATA_IO_PU_PD(295),
+ PORT_DATA_IO_PU_PD(296),
+ PORT_DATA_IO_PU_PD(297),
+ PORT_DATA_IO_PU_PD(298),
+
+ PORT_DATA_IO_PU_PD(299),
+ PORT_DATA_IO_PU_PD(300),
+ PORT_DATA_IO_PU_PD(301),
+ PORT_DATA_IO_PU_PD(302),
+ PORT_DATA_IO_PU_PD(303),
+ PORT_DATA_IO_PU_PD(304),
+ PORT_DATA_IO_PU_PD(305),
+ PORT_DATA_O(306),
+ PORT_DATA_O(307),
+ PORT_DATA_I_PU(308),
+ PORT_DATA_O(309),
+
+ /* Table 25-1 (Function 0-7) */
+ PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
+ PINMUX_DATA(GPI0_MARK, PORT1_FN1),
+ PINMUX_DATA(GPI1_MARK, PORT2_FN1),
+ PINMUX_DATA(GPI2_MARK, PORT3_FN1),
+ PINMUX_DATA(GPI3_MARK, PORT4_FN1),
+ PINMUX_DATA(GPI4_MARK, PORT5_FN1),
+ PINMUX_DATA(GPI5_MARK, PORT6_FN1),
+ PINMUX_DATA(GPI6_MARK, PORT7_FN1),
+ PINMUX_DATA(GPI7_MARK, PORT8_FN1),
+ PINMUX_DATA(SCIFA7_RXD_MARK, PORT12_FN2),
+ PINMUX_DATA(SCIFA7_CTS__MARK, PORT13_FN2),
+ PINMUX_DATA(GPO7_MARK, PORT14_FN1), \
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT14_FN4),
+ PINMUX_DATA(GPO6_MARK, PORT15_FN1), \
+ PINMUX_DATA(MFG1_OUT2_MARK, PORT15_FN4),
+ PINMUX_DATA(GPO5_MARK, PORT16_FN1), \
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2), \
+ PINMUX_DATA(FSICOSLDT3_MARK, PORT16_FN3), \
+ PINMUX_DATA(PORT16_VIO_CKOR_MARK, PORT16_FN4),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
+ PINMUX_DATA(SCIFA7_TXD_MARK, PORT18_FN2),
+ PINMUX_DATA(SCIFA7_RTS__MARK, PORT19_FN2), \
+ PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
+ PINMUX_DATA(GPO0_MARK, PORT20_FN1),
+ PINMUX_DATA(GPO1_MARK, PORT21_FN1),
+ PINMUX_DATA(GPO2_MARK, PORT22_FN1), \
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(GPO3_MARK, PORT23_FN1), \
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(GPO4_MARK, PORT24_FN1), \
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(VINT_MARK, PORT25_FN1),
+ PINMUX_DATA(TCKON_MARK, PORT26_FN1),
+ PINMUX_DATA(XDVFS1_MARK, PORT27_FN1), \
+ PINMUX_DATA(PORT27_I2C_SCL2_MARK, PORT27_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT27_I2C_SCL3_MARK, PORT27_FN3, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT27_FN4), \
+ PINMUX_DATA(PORT27_IROUT_MARK, PORT27_FN7),
+ PINMUX_DATA(XDVFS2_MARK, PORT28_FN1), \
+ PINMUX_DATA(PORT28_I2C_SDA2_MARK, PORT28_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT28_I2C_SDA3_MARK, PORT28_FN3, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(PORT28_TPU1TO1_MARK, PORT28_FN7),
+ PINMUX_DATA(SIM_RST_MARK, PORT29_FN1), \
+ PINMUX_DATA(PORT29_TPU1TO1_MARK, PORT29_FN4),
+ PINMUX_DATA(SIM_CLK_MARK, PORT30_FN1), \
+ PINMUX_DATA(PORT30_VIO_CKOR_MARK, PORT30_FN4),
+ PINMUX_DATA(SIM_D_MARK, PORT31_FN1), \
+ PINMUX_DATA(PORT31_IROUT_MARK, PORT31_FN4),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2), \
+ PINMUX_DATA(XWUP_MARK, PORT33_FN3),
+ PINMUX_DATA(SCIFA4_RTS__MARK, PORT34_FN2),
+ PINMUX_DATA(SCIFA4_CTS__MARK, PORT35_FN2),
+ PINMUX_DATA(FSIBOBT_MARK, PORT36_FN1), \
+ PINMUX_DATA(FSIBIBT_MARK, PORT36_FN2),
+ PINMUX_DATA(FSIBOLR_MARK, PORT37_FN1), \
+ PINMUX_DATA(FSIBILR_MARK, PORT37_FN2),
+ PINMUX_DATA(FSIBOSLD_MARK, PORT38_FN1),
+ PINMUX_DATA(FSIBISLD_MARK, PORT39_FN1),
+ PINMUX_DATA(VACK_MARK, PORT40_FN1),
+ PINMUX_DATA(XTAL1L_MARK, PORT41_FN1),
+ PINMUX_DATA(SCIFA0_RTS__MARK, PORT42_FN2), \
+ PINMUX_DATA(FSICOSLDT2_MARK, PORT42_FN3),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
+ PINMUX_DATA(SCIFA0_CTS__MARK, PORT44_FN2), \
+ PINMUX_DATA(FSICOSLDT1_MARK, PORT44_FN3),
+ PINMUX_DATA(FSICOBT_MARK, PORT45_FN1), \
+ PINMUX_DATA(FSICIBT_MARK, PORT45_FN2), \
+ PINMUX_DATA(FSIDOBT_MARK, PORT45_FN3), \
+ PINMUX_DATA(FSIDIBT_MARK, PORT45_FN4),
+ PINMUX_DATA(FSICOLR_MARK, PORT46_FN1), \
+ PINMUX_DATA(FSICILR_MARK, PORT46_FN2), \
+ PINMUX_DATA(FSIDOLR_MARK, PORT46_FN3), \
+ PINMUX_DATA(FSIDILR_MARK, PORT46_FN4),
+ PINMUX_DATA(FSICOSLD_MARK, PORT47_FN1), \
+ PINMUX_DATA(PORT47_FSICSPDIF_MARK, PORT47_FN2),
+ PINMUX_DATA(FSICISLD_MARK, PORT48_FN1), \
+ PINMUX_DATA(FSIDISLD_MARK, PORT48_FN3),
+ PINMUX_DATA(FSIACK_MARK, PORT49_FN1), \
+ PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN4), \
+ PINMUX_DATA(FSIAOMC_MARK, PORT49_FN5),
+ PINMUX_DATA(FSIAOLR_MARK, PORT50_FN1), \
+ PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2), \
+ PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3), \
+ PINMUX_DATA(FSIAILR_MARK, PORT50_FN5),
+
+ PINMUX_DATA(FSIAOBT_MARK, PORT51_FN1), \
+ PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2), \
+ PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3), \
+ PINMUX_DATA(FSIAIBT_MARK, PORT51_FN5),
+ PINMUX_DATA(FSIAOSLD_MARK, PORT52_FN1), \
+ PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
+ PINMUX_DATA(FSIASPDIF_MARK, PORT53_FN1), \
+ PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3), \
+ PINMUX_DATA(FSIBSPDIF_MARK, PORT53_FN5), \
+ PINMUX_DATA(PORT53_FSICSPDIF_MARK, PORT53_FN6),
+ PINMUX_DATA(FSIBCK_MARK, PORT54_FN1), \
+ PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3), \
+ PINMUX_DATA(FSIBOMC_MARK, PORT54_FN5), \
+ PINMUX_DATA(FSICCK_MARK, PORT54_FN6), \
+ PINMUX_DATA(FSICOMC_MARK, PORT54_FN7),
+ PINMUX_DATA(FSIAISLD_MARK, PORT55_FN1), \
+ PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
+ PINMUX_DATA(A0_MARK, PORT57_FN1), \
+ PINMUX_DATA(BS__MARK, PORT57_FN2),
+ PINMUX_DATA(A12_MARK, PORT58_FN1), \
+ PINMUX_DATA(PORT58_KEYOUT7_MARK, PORT58_FN2), \
+ PINMUX_DATA(TPU4TO2_MARK, PORT58_FN4),
+ PINMUX_DATA(A13_MARK, PORT59_FN1), \
+ PINMUX_DATA(PORT59_KEYOUT6_MARK, PORT59_FN2), \
+ PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
+ PINMUX_DATA(A14_MARK, PORT60_FN1), \
+ PINMUX_DATA(KEYOUT5_MARK, PORT60_FN2),
+ PINMUX_DATA(A15_MARK, PORT61_FN1), \
+ PINMUX_DATA(KEYOUT4_MARK, PORT61_FN2),
+ PINMUX_DATA(A16_MARK, PORT62_FN1), \
+ PINMUX_DATA(KEYOUT3_MARK, PORT62_FN2), \
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A17_MARK, PORT63_FN1), \
+ PINMUX_DATA(KEYOUT2_MARK, PORT63_FN2), \
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A18_MARK, PORT64_FN1), \
+ PINMUX_DATA(KEYOUT1_MARK, PORT64_FN2), \
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A19_MARK, PORT65_FN1), \
+ PINMUX_DATA(KEYOUT0_MARK, PORT65_FN2), \
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A20_MARK, PORT66_FN1), \
+ PINMUX_DATA(KEYIN0_MARK, PORT66_FN2), \
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A21_MARK, PORT67_FN1), \
+ PINMUX_DATA(KEYIN1_MARK, PORT67_FN2), \
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A22_MARK, PORT68_FN1), \
+ PINMUX_DATA(KEYIN2_MARK, PORT68_FN2), \
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A23_MARK, PORT69_FN1), \
+ PINMUX_DATA(KEYIN3_MARK, PORT69_FN2), \
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A24_MARK, PORT70_FN1), \
+ PINMUX_DATA(KEYIN4_MARK, PORT70_FN2), \
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A25_MARK, PORT71_FN1), \
+ PINMUX_DATA(KEYIN5_MARK, PORT71_FN2), \
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A26_MARK, PORT72_FN1), \
+ PINMUX_DATA(KEYIN6_MARK, PORT72_FN2),
+ PINMUX_DATA(KEYIN7_MARK, PORT73_FN2),
+ PINMUX_DATA(D0_NAF0_MARK, PORT74_FN1),
+ PINMUX_DATA(D1_NAF1_MARK, PORT75_FN1),
+ PINMUX_DATA(D2_NAF2_MARK, PORT76_FN1),
+ PINMUX_DATA(D3_NAF3_MARK, PORT77_FN1),
+ PINMUX_DATA(D4_NAF4_MARK, PORT78_FN1),
+ PINMUX_DATA(D5_NAF5_MARK, PORT79_FN1),
+ PINMUX_DATA(D6_NAF6_MARK, PORT80_FN1),
+ PINMUX_DATA(D7_NAF7_MARK, PORT81_FN1),
+ PINMUX_DATA(D8_NAF8_MARK, PORT82_FN1),
+ PINMUX_DATA(D9_NAF9_MARK, PORT83_FN1),
+ PINMUX_DATA(D10_NAF10_MARK, PORT84_FN1),
+ PINMUX_DATA(D11_NAF11_MARK, PORT85_FN1),
+ PINMUX_DATA(D12_NAF12_MARK, PORT86_FN1),
+ PINMUX_DATA(D13_NAF13_MARK, PORT87_FN1),
+ PINMUX_DATA(D14_NAF14_MARK, PORT88_FN1),
+ PINMUX_DATA(D15_NAF15_MARK, PORT89_FN1),
+ PINMUX_DATA(CS4__MARK, PORT90_FN1),
+ PINMUX_DATA(CS5A__MARK, PORT91_FN1), \
+ PINMUX_DATA(PORT91_RDWR_MARK, PORT91_FN2),
+ PINMUX_DATA(CS5B__MARK, PORT92_FN1), \
+ PINMUX_DATA(FCE1__MARK, PORT92_FN2),
+ PINMUX_DATA(CS6B__MARK, PORT93_FN1), \
+ PINMUX_DATA(DACK0_MARK, PORT93_FN4),
+ PINMUX_DATA(FCE0__MARK, PORT94_FN1), \
+ PINMUX_DATA(CS6A__MARK, PORT94_FN2),
+ PINMUX_DATA(WAIT__MARK, PORT95_FN1), \
+ PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
+ PINMUX_DATA(RD__FSC_MARK, PORT96_FN1),
+ PINMUX_DATA(WE0__FWE_MARK, PORT97_FN1), \
+ PINMUX_DATA(RDWR_FWE_MARK, PORT97_FN2),
+ PINMUX_DATA(WE1__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(BBIF2_TXD_MARK, PORT103_FN3),
+ PINMUX_DATA(BBIF2_RXD_MARK, PORT104_FN3),
+ PINMUX_DATA(BBIF2_SYNC_MARK, PORT105_FN3),
+ PINMUX_DATA(BBIF2_SCK_MARK, PORT106_FN3),
+ PINMUX_DATA(SCIFA3_CTS__MARK, PORT107_FN3), \
+ PINMUX_DATA(MFG3_IN2_MARK, PORT107_FN4),
+ PINMUX_DATA(SCIFA3_RXD_MARK, PORT108_FN3), \
+ PINMUX_DATA(MFG3_IN1_MARK, PORT108_FN4),
+ PINMUX_DATA(BBIF1_SS2_MARK, PORT109_FN2), \
+ PINMUX_DATA(SCIFA3_RTS__MARK, PORT109_FN3), \
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT109_FN4),
+ PINMUX_DATA(SCIFA3_TXD_MARK, PORT110_FN3),
+ PINMUX_DATA(HSI_RX_DATA_MARK, PORT111_FN1), \
+ PINMUX_DATA(BBIF1_RXD_MARK, PORT111_FN3),
+ PINMUX_DATA(HSI_TX_WAKE_MARK, PORT112_FN1), \
+ PINMUX_DATA(BBIF1_TSCK_MARK, PORT112_FN3),
+ PINMUX_DATA(HSI_TX_DATA_MARK, PORT113_FN1), \
+ PINMUX_DATA(BBIF1_TSYNC_MARK, PORT113_FN3),
+ PINMUX_DATA(HSI_TX_READY_MARK, PORT114_FN1), \
+ PINMUX_DATA(BBIF1_TXD_MARK, PORT114_FN3),
+ PINMUX_DATA(HSI_RX_READY_MARK, PORT115_FN1), \
+ PINMUX_DATA(BBIF1_RSCK_MARK, PORT115_FN3), \
+ PINMUX_DATA(PORT115_I2C_SCL2_MARK, PORT115_FN5, MSEL2CR_MSEL17_1), \
+ PINMUX_DATA(PORT115_I2C_SCL3_MARK, PORT115_FN6, MSEL2CR_MSEL19_1),
+ PINMUX_DATA(HSI_RX_WAKE_MARK, PORT116_FN1), \
+ PINMUX_DATA(BBIF1_RSYNC_MARK, PORT116_FN3), \
+ PINMUX_DATA(PORT116_I2C_SDA2_MARK, PORT116_FN5, MSEL2CR_MSEL17_1), \
+ PINMUX_DATA(PORT116_I2C_SDA3_MARK, PORT116_FN6, MSEL2CR_MSEL19_1),
+ PINMUX_DATA(HSI_RX_FLAG_MARK, PORT117_FN1), \
+ PINMUX_DATA(BBIF1_SS1_MARK, PORT117_FN2), \
+ PINMUX_DATA(BBIF1_FLOW_MARK, PORT117_FN3),
+ PINMUX_DATA(HSI_TX_FLAG_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT128_FN1), \
+ PINMUX_DATA(PORT128_LCD2VSYN_MARK, PORT128_FN4, MSEL3CR_MSEL2_0), \
+ PINMUX_DATA(VIO2_VD_MARK, PORT128_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D0_MARK, PORT128_FN7),
+
+ PINMUX_DATA(VIO_HD_MARK, PORT129_FN1), \
+ PINMUX_DATA(PORT129_LCD2HSYN_MARK, PORT129_FN4), \
+ PINMUX_DATA(PORT129_LCD2CS__MARK, PORT129_FN5), \
+ PINMUX_DATA(VIO2_HD_MARK, PORT129_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D1_MARK, PORT129_FN7),
+ PINMUX_DATA(VIO_D0_MARK, PORT130_FN1), \
+ PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3, MSEL4CR_MSEL11_0,
+ MSEL4CR_MSEL10_1), \
+ PINMUX_DATA(LCD2D10_MARK, PORT130_FN7),
+ PINMUX_DATA(VIO_D1_MARK, PORT131_FN1), \
+ PINMUX_DATA(PORT131_KEYOUT6_MARK, PORT131_FN2), \
+ PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3), \
+ PINMUX_DATA(PORT131_KEYOUT11_MARK, PORT131_FN4), \
+ PINMUX_DATA(LCD2D11_MARK, PORT131_FN7),
+ PINMUX_DATA(VIO_D2_MARK, PORT132_FN1), \
+ PINMUX_DATA(PORT132_KEYOUT7_MARK, PORT132_FN2), \
+ PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3), \
+ PINMUX_DATA(PORT132_KEYOUT10_MARK, PORT132_FN4), \
+ PINMUX_DATA(LCD2D12_MARK, PORT132_FN7),
+ PINMUX_DATA(VIO_D3_MARK, PORT133_FN1), \
+ PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT133_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D13_MARK, PORT133_FN7),
+ PINMUX_DATA(VIO_D4_MARK, PORT134_FN1), \
+ PINMUX_DATA(MSIOF2_TXD_MARK, PORT134_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D14_MARK, PORT134_FN7),
+ PINMUX_DATA(VIO_D5_MARK, PORT135_FN1), \
+ PINMUX_DATA(MSIOF2_TSCK_MARK, PORT135_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D15_MARK, PORT135_FN7),
+ PINMUX_DATA(VIO_D6_MARK, PORT136_FN1), \
+ PINMUX_DATA(PORT136_KEYOUT8_MARK, PORT136_FN2), \
+ PINMUX_DATA(LCD2D16_MARK, PORT136_FN7),
+ PINMUX_DATA(VIO_D7_MARK, PORT137_FN1), \
+ PINMUX_DATA(PORT137_KEYOUT9_MARK, PORT137_FN2), \
+ PINMUX_DATA(LCD2D17_MARK, PORT137_FN7),
+ PINMUX_DATA(VIO_D8_MARK, PORT138_FN1), \
+ PINMUX_DATA(PORT138_KEYOUT8_MARK, PORT138_FN2), \
+ PINMUX_DATA(VIO2_D0_MARK, PORT138_FN6), \
+ PINMUX_DATA(LCD2D6_MARK, PORT138_FN7),
+ PINMUX_DATA(VIO_D9_MARK, PORT139_FN1), \
+ PINMUX_DATA(PORT139_KEYOUT9_MARK, PORT139_FN2), \
+ PINMUX_DATA(VIO2_D1_MARK, PORT139_FN6), \
+ PINMUX_DATA(LCD2D7_MARK, PORT139_FN7),
+ PINMUX_DATA(VIO_D10_MARK, PORT140_FN1), \
+ PINMUX_DATA(TPU0TO2_MARK, PORT140_FN4), \
+ PINMUX_DATA(VIO2_D2_MARK, PORT140_FN6), \
+ PINMUX_DATA(LCD2D8_MARK, PORT140_FN7),
+ PINMUX_DATA(VIO_D11_MARK, PORT141_FN1), \
+ PINMUX_DATA(TPU0TO3_MARK, PORT141_FN4), \
+ PINMUX_DATA(VIO2_D3_MARK, PORT141_FN6), \
+ PINMUX_DATA(LCD2D9_MARK, PORT141_FN7),
+ PINMUX_DATA(VIO_D12_MARK, PORT142_FN1), \
+ PINMUX_DATA(PORT142_KEYOUT10_MARK, PORT142_FN2), \
+ PINMUX_DATA(VIO2_D4_MARK, PORT142_FN6), \
+ PINMUX_DATA(LCD2D2_MARK, PORT142_FN7),
+ PINMUX_DATA(VIO_D13_MARK, PORT143_FN1), \
+ PINMUX_DATA(PORT143_KEYOUT11_MARK, PORT143_FN2), \
+ PINMUX_DATA(PORT143_KEYOUT6_MARK, PORT143_FN3), \
+ PINMUX_DATA(VIO2_D5_MARK, PORT143_FN6), \
+ PINMUX_DATA(LCD2D3_MARK, PORT143_FN7),
+ PINMUX_DATA(VIO_D14_MARK, PORT144_FN1), \
+ PINMUX_DATA(PORT144_KEYOUT7_MARK, PORT144_FN2), \
+ PINMUX_DATA(VIO2_D6_MARK, PORT144_FN6), \
+ PINMUX_DATA(LCD2D4_MARK, PORT144_FN7),
+ PINMUX_DATA(VIO_D15_MARK, PORT145_FN1), \
+ PINMUX_DATA(TPU1TO3_MARK, PORT145_FN3), \
+ PINMUX_DATA(PORT145_LCD2DISP_MARK, PORT145_FN4), \
+ PINMUX_DATA(PORT145_LCD2RS_MARK, PORT145_FN5), \
+ PINMUX_DATA(VIO2_D7_MARK, PORT145_FN6), \
+ PINMUX_DATA(LCD2D5_MARK, PORT145_FN7),
+ PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1), \
+ PINMUX_DATA(LCD2DCK_MARK, PORT146_FN4), \
+ PINMUX_DATA(PORT146_LCD2WR__MARK, PORT146_FN5), \
+ PINMUX_DATA(VIO2_CLK_MARK, PORT146_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D18_MARK, PORT146_FN7),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1), \
+ PINMUX_DATA(LCD2RD__MARK, PORT147_FN4), \
+ PINMUX_DATA(VIO2_FIELD_MARK, PORT147_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D19_MARK, PORT147_FN7),
+ PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
+ PINMUX_DATA(A27_MARK, PORT149_FN1), \
+ PINMUX_DATA(PORT149_RDWR_MARK, PORT149_FN2), \
+ PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3), \
+ PINMUX_DATA(PORT149_KEYOUT9_MARK, PORT149_FN4),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN3),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN4), \
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN5),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN4), \
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN5),
+ PINMUX_DATA(TPU1TO2_MARK, PORT153_FN3), \
+ PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN4), \
+ PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN5),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN5),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN5),
+ PINMUX_DATA(SCIFA2_RTS1__MARK, PORT156_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN5),
+ PINMUX_DATA(SCIFA2_CTS1__MARK, PORT157_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN5, MSEL4CR_MSEL11_0,
+ MSEL4CR_MSEL10_0),
+ PINMUX_DATA(DINT__MARK, PORT158_FN1), \
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(TS_SCK3_MARK, PORT158_FN4),
+ PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2, MSEL4CR_MSEL21_1), \
+ PINMUX_DATA(NMI_MARK, PORT159_FN3),
+ PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT161_SCIFB_CTS__MARK, PORT161_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT161_SCIFA5_CTS__MARK, PORT161_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT163_SCIFB_RTS__MARK, PORT163_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT163_SCIFA5_RTS__MARK, PORT163_FN2, MSEL4CR_MSEL21_1), \
+ PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
+ PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
+ PINMUX_DATA(LCDD1_MARK, PORT193_FN1), \
+ PINMUX_DATA(PORT193_SCIFA5_CTS__MARK, PORT193_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN5),
+ PINMUX_DATA(LCDD2_MARK, PORT194_FN1), \
+ PINMUX_DATA(PORT194_SCIFA5_RTS__MARK, PORT194_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN5),
+ PINMUX_DATA(LCDD3_MARK, PORT195_FN1), \
+ PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN5),
+ PINMUX_DATA(LCDD4_MARK, PORT196_FN1), \
+ PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1),
+ PINMUX_DATA(LCDD5_MARK, PORT197_FN1), \
+ PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN5), \
+ PINMUX_DATA(TPU2TO1_MARK, PORT197_FN7),
+ PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT199_FN1), \
+ PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2), \
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN5),
+ PINMUX_DATA(LCDD8_MARK, PORT200_FN1), \
+ PINMUX_DATA(D16_MARK, PORT200_FN6),
+ PINMUX_DATA(LCDD9_MARK, PORT201_FN1), \
+ PINMUX_DATA(D17_MARK, PORT201_FN6),
+ PINMUX_DATA(LCDD10_MARK, PORT202_FN1), \
+ PINMUX_DATA(D18_MARK, PORT202_FN6),
+ PINMUX_DATA(LCDD11_MARK, PORT203_FN1), \
+ PINMUX_DATA(D19_MARK, PORT203_FN6),
+ PINMUX_DATA(LCDD12_MARK, PORT204_FN1), \
+ PINMUX_DATA(D20_MARK, PORT204_FN6),
+ PINMUX_DATA(LCDD13_MARK, PORT205_FN1), \
+ PINMUX_DATA(D21_MARK, PORT205_FN6),
+ PINMUX_DATA(LCDD14_MARK, PORT206_FN1), \
+ PINMUX_DATA(D22_MARK, PORT206_FN6),
+ PINMUX_DATA(LCDD15_MARK, PORT207_FN1), \
+ PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D23_MARK, PORT207_FN6),
+ PINMUX_DATA(LCDD16_MARK, PORT208_FN1), \
+ PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D24_MARK, PORT208_FN6),
+ PINMUX_DATA(LCDD17_MARK, PORT209_FN1), \
+ PINMUX_DATA(D25_MARK, PORT209_FN6),
+ PINMUX_DATA(LCDD18_MARK, PORT210_FN1), \
+ PINMUX_DATA(DREQ2_MARK, PORT210_FN2), \
+ PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D26_MARK, PORT210_FN6),
+ PINMUX_DATA(LCDD19_MARK, PORT211_FN1), \
+ PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D27_MARK, PORT211_FN6),
+ PINMUX_DATA(LCDD20_MARK, PORT212_FN1), \
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2), \
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D28_MARK, PORT212_FN6),
+ PINMUX_DATA(LCDD21_MARK, PORT213_FN1), \
+ PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2), \
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D29_MARK, PORT213_FN6),
+ PINMUX_DATA(LCDD22_MARK, PORT214_FN1), \
+ PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2), \
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D30_MARK, PORT214_FN6),
+ PINMUX_DATA(LCDD23_MARK, PORT215_FN1), \
+ PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2), \
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D31_MARK, PORT215_FN6),
+ PINMUX_DATA(LCDDCK_MARK, PORT216_FN1), \
+ PINMUX_DATA(LCDWR__MARK, PORT216_FN2),
+ PINMUX_DATA(LCDRD__MARK, PORT217_FN1), \
+ PINMUX_DATA(DACK2_MARK, PORT217_FN2), \
+ PINMUX_DATA(PORT217_LCD2RS_MARK, PORT217_FN3), \
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_FIELD3_MARK, PORT217_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT217_LCD2DISP_MARK, PORT217_FN7),
+ 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(LCDDISP_MARK, PORT219_FN1), \
+ PINMUX_DATA(LCDRS_MARK, PORT219_FN2), \
+ PINMUX_DATA(PORT219_LCD2WR__MARK, PORT219_FN3), \
+ PINMUX_DATA(DREQ3_MARK, PORT219_FN4), \
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_CLK3_MARK, PORT219_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(LCD2DCK_2_MARK, PORT219_FN7),
+ PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1), \
+ PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
+ PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1), \
+ PINMUX_DATA(DREQ1_MARK, PORT221_FN2), \
+ PINMUX_DATA(PORT221_LCD2CS__MARK, PORT221_FN3), \
+ PINMUX_DATA(PWEN_MARK, PORT221_FN4), \
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_HD3_MARK, PORT221_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT221_LCD2HSYN_MARK, PORT221_FN7),
+ 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, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_VD3_MARK, PORT222_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT222_LCD2VSYN_MARK, PORT222_FN7, MSEL3CR_MSEL2_1),
+
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN2), \
+ PINMUX_DATA(OVCN2_MARK, PORT225_FN4),
+ PINMUX_DATA(EXTLP_MARK, PORT226_FN1), \
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2), \
+ PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN5),
+ PINMUX_DATA(SCIFA1_RTS__MARK, PORT227_FN2), \
+ PINMUX_DATA(IDIN_MARK, PORT227_FN4),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN2),
+ PINMUX_DATA(SCIFA1_CTS__MARK, PORT229_FN2), \
+ PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN3),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1), \
+ PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1), \
+ PINMUX_DATA(SCIFA2_CTS2__MARK, PORT231_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1), \
+ PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1), \
+ PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1), \
+ PINMUX_DATA(SCIFA2_RTS2__MARK, PORT234_FN2, MSEL3CR_MSEL9_1), \
+ PINMUX_DATA(VIO2_CLK2_MARK, PORT234_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D20_MARK, PORT234_FN7),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1), \
+ PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3), \
+ PINMUX_DATA(VIO2_VD2_MARK, PORT235_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D21_MARK, PORT235_FN7),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1), \
+ PINMUX_DATA(PORT236_I2C_SDA2_MARK, PORT236_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_0),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1), \
+ PINMUX_DATA(PORT237_I2C_SCL2_MARK, PORT237_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_0),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1), \
+ PINMUX_DATA(VIO2_FIELD2_MARK, PORT238_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D22_MARK, PORT238_FN7),
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1), \
+ PINMUX_DATA(VIO2_HD2_MARK, PORT239_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D23_MARK, PORT239_FN7),
+ PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
+ PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1, MSEL4CR_MSEL19_0), \
+ 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, MSEL4CR_MSEL19_0), \
+ PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN3),
+ PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1, MSEL4CR_MSEL19_0), \
+ PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT244_SCIFA5_CTS__MARK, PORT244_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2), \
+ PINMUX_DATA(PORT244_SCIFB_CTS__MARK, PORT244_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(MSIOF2R_RXD_MARK, PORT244_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT245_SCIFA5_RTS__MARK, PORT245_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2), \
+ PINMUX_DATA(PORT245_SCIFB_RTS__MARK, PORT245_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(MSIOF2R_TXD_MARK, PORT245_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2), \
+ PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
+ PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2), \
+ PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
+ PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2), \
+ PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4), \
+ PINMUX_DATA(PORT248_I2C_SCL3_MARK, PORT248_FN5, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MSIOF2R_TSCK_MARK, PORT248_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1), \
+ PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2), \
+ PINMUX_DATA(PORT249_I2C_SDA3_MARK, PORT249_FN5, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MSIOF2R_TSYNC_MARK, PORT249_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
+ PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
+ PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
+ PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
+ PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
+ PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
+ PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
+ PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
+ PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1), \
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
+ PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1), \
+ PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
+ PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1), \
+ PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
+ PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1), \
+ PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
+ PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
+ PINMUX_DATA(SDHICLK2_MARK, PORT264_FN1),
+ PINMUX_DATA(SDHID2_0_MARK, PORT265_FN1), \
+ PINMUX_DATA(TS_SPSYNC4_MARK, PORT265_FN3),
+ PINMUX_DATA(SDHID2_1_MARK, PORT266_FN1), \
+ PINMUX_DATA(TS_SDAT4_MARK, PORT266_FN3),
+ PINMUX_DATA(SDHID2_2_MARK, PORT267_FN1), \
+ PINMUX_DATA(TS_SDEN4_MARK, PORT267_FN3),
+ PINMUX_DATA(SDHID2_3_MARK, PORT268_FN1), \
+ PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3),
+ PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1),
+ PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3),
+ PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3),
+ PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3),
+ PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3),
+ PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \
+ PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2),
+ PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1),
+ PINMUX_DATA(MCP_CKO_MARK, PORT289_FN1), \
+ PINMUX_DATA(MMCCLK1_MARK, PORT289_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D15_MCP_NAF15_MARK, PORT290_FN1),
+ PINMUX_DATA(MCP_D14_MCP_NAF14_MARK, PORT291_FN1),
+ PINMUX_DATA(MCP_D13_MCP_NAF13_MARK, PORT292_FN1),
+ PINMUX_DATA(MCP_D12_MCP_NAF12_MARK, PORT293_FN1),
+ PINMUX_DATA(MCP_D11_MCP_NAF11_MARK, PORT294_FN1),
+ PINMUX_DATA(MCP_D10_MCP_NAF10_MARK, PORT295_FN1),
+ PINMUX_DATA(MCP_D9_MCP_NAF9_MARK, PORT296_FN1),
+ PINMUX_DATA(MCP_D8_MCP_NAF8_MARK, PORT297_FN1), \
+ PINMUX_DATA(MMCCMD1_MARK, PORT297_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D7_MCP_NAF7_MARK, PORT298_FN1), \
+ PINMUX_DATA(MMCD1_7_MARK, PORT298_FN2, MSEL4CR_MSEL15_1),
+
+ PINMUX_DATA(MCP_D6_MCP_NAF6_MARK, PORT299_FN1), \
+ PINMUX_DATA(MMCD1_6_MARK, PORT299_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D5_MCP_NAF5_MARK, PORT300_FN1), \
+ PINMUX_DATA(MMCD1_5_MARK, PORT300_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D4_MCP_NAF4_MARK, PORT301_FN1), \
+ PINMUX_DATA(MMCD1_4_MARK, PORT301_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D3_MCP_NAF3_MARK, PORT302_FN1), \
+ PINMUX_DATA(MMCD1_3_MARK, PORT302_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D2_MCP_NAF2_MARK, PORT303_FN1), \
+ PINMUX_DATA(MMCD1_2_MARK, PORT303_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D1_MCP_NAF1_MARK, PORT304_FN1), \
+ PINMUX_DATA(MMCD1_1_MARK, PORT304_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D0_MCP_NAF0_MARK, PORT305_FN1), \
+ PINMUX_DATA(MMCD1_0_MARK, PORT305_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_NBRSTOUT__MARK, PORT306_FN1),
+ PINMUX_DATA(MCP_WE0__MCP_FWE_MARK, PORT309_FN1), \
+ PINMUX_DATA(MCP_RDWR_MCP_FWE_MARK, PORT309_FN2),
+
+ /* MSEL2 special cases */
+ PINMUX_DATA(TSIF2_TS_XX1_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF2_TS_XX2_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_1),
+ PINMUX_DATA(TSIF2_TS_XX3_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF2_TS_XX4_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_1),
+ PINMUX_DATA(TSIF2_TS_XX5_MARK, MSEL2CR_MSEL14_1, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF1_TS_XX1_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF1_TS_XX2_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_1),
+ PINMUX_DATA(TSIF1_TS_XX3_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF1_TS_XX4_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_1),
+ PINMUX_DATA(TSIF1_TS_XX5_MARK, MSEL2CR_MSEL11_1, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF0_TS_XX1_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(TSIF0_TS_XX2_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_1),
+ PINMUX_DATA(TSIF0_TS_XX3_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(TSIF0_TS_XX4_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_1),
+ PINMUX_DATA(TSIF0_TS_XX5_MARK, MSEL2CR_MSEL8_1, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(MST1_TS_XX1_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST1_TS_XX2_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_1),
+ PINMUX_DATA(MST1_TS_XX3_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST1_TS_XX4_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_1),
+ PINMUX_DATA(MST1_TS_XX5_MARK, MSEL2CR_MSEL5_1, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST0_TS_XX1_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_0),
+ PINMUX_DATA(MST0_TS_XX2_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_1),
+ PINMUX_DATA(MST0_TS_XX3_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0),
+ PINMUX_DATA(MST0_TS_XX4_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_1),
+ PINMUX_DATA(MST0_TS_XX5_MARK, MSEL2CR_MSEL2_1, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_0),
+
+ /* MSEL3 special cases */
+ PINMUX_DATA(SDHI0_VCCQ_MC0_ON_MARK, MSEL3CR_MSEL28_1),
+ PINMUX_DATA(SDHI0_VCCQ_MC0_OFF_MARK, MSEL3CR_MSEL28_0),
+ PINMUX_DATA(DEBUG_MON_VIO_MARK, MSEL3CR_MSEL15_0),
+ PINMUX_DATA(DEBUG_MON_LCDD_MARK, MSEL3CR_MSEL15_1),
+ PINMUX_DATA(LCDC_LCDC0_MARK, MSEL3CR_MSEL6_0),
+ PINMUX_DATA(LCDC_LCDC1_MARK, MSEL3CR_MSEL6_1),
+
+ /* MSEL4 special cases */
+ PINMUX_DATA(IRQ9_MEM_INT_MARK, MSEL4CR_MSEL29_0),
+ PINMUX_DATA(IRQ9_MCP_INT_MARK, MSEL4CR_MSEL29_1),
+ PINMUX_DATA(A11_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_0),
+ PINMUX_DATA(KEYOUT8_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_1),
+ PINMUX_DATA(TPU4TO3_MARK, MSEL4CR_MSEL13_1, MSEL4CR_MSEL12_0),
+ PINMUX_DATA(RESETA_N_PU_ON_MARK, MSEL4CR_MSEL4_0),
+ PINMUX_DATA(RESETA_N_PU_OFF_MARK, MSEL4CR_MSEL4_1),
+ PINMUX_DATA(EDBGREQ_PD_MARK, MSEL4CR_MSEL1_0),
+ PINMUX_DATA(EDBGREQ_PU_MARK, MSEL4CR_MSEL1_1),
+
+ /* Functions with pull-ups */
+ PINMUX_DATA(KEYIN0_PU_MARK, PORT66_FN2, PORT66_IN_PU),
+ PINMUX_DATA(KEYIN1_PU_MARK, PORT67_FN2, PORT67_IN_PU),
+ PINMUX_DATA(KEYIN2_PU_MARK, PORT68_FN2, PORT68_IN_PU),
+ PINMUX_DATA(KEYIN3_PU_MARK, PORT69_FN2, PORT69_IN_PU),
+ PINMUX_DATA(KEYIN4_PU_MARK, PORT70_FN2, PORT70_IN_PU),
+ PINMUX_DATA(KEYIN5_PU_MARK, PORT71_FN2, PORT71_IN_PU),
+ PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU),
+ PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU),
+
+ PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_IN_PU, PORT259_FN1),
+ PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_IN_PU, PORT260_FN1),
+ PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_IN_PU, PORT261_FN1),
+ PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_IN_PU, PORT262_FN1),
+ PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_IN_PU, PORT263_FN1),
+
+ PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT279_IN_PU,
+ MSEL4CR_MSEL15_1),
+ PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
+ PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
+ PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU),
+ PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_310() _310(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_PORT_310(),
+
+ /* Table 25-1 (Functions 0-7) */
+ GPIO_FN(VBUS_0),
+ GPIO_FN(GPI0),
+ GPIO_FN(GPI1),
+ GPIO_FN(GPI2),
+ GPIO_FN(GPI3),
+ GPIO_FN(GPI4),
+ GPIO_FN(GPI5),
+ GPIO_FN(GPI6),
+ GPIO_FN(GPI7),
+ GPIO_FN(SCIFA7_RXD),
+ GPIO_FN(SCIFA7_CTS_),
+ GPIO_FN(GPO7), \
+ GPIO_FN(MFG0_OUT2),
+ GPIO_FN(GPO6), \
+ GPIO_FN(MFG1_OUT2),
+ GPIO_FN(GPO5), \
+ GPIO_FN(SCIFA0_SCK), \
+ GPIO_FN(FSICOSLDT3), \
+ GPIO_FN(PORT16_VIO_CKOR),
+ GPIO_FN(SCIFA0_TXD),
+ GPIO_FN(SCIFA7_TXD),
+ GPIO_FN(SCIFA7_RTS_), \
+ GPIO_FN(PORT19_VIO_CKO2),
+ GPIO_FN(GPO0),
+ GPIO_FN(GPO1),
+ GPIO_FN(GPO2), \
+ GPIO_FN(STATUS0),
+ GPIO_FN(GPO3), \
+ GPIO_FN(STATUS1),
+ GPIO_FN(GPO4), \
+ GPIO_FN(STATUS2),
+ GPIO_FN(VINT),
+ GPIO_FN(TCKON),
+ GPIO_FN(XDVFS1), \
+ GPIO_FN(PORT27_I2C_SCL2), \
+ GPIO_FN(PORT27_I2C_SCL3), \
+ GPIO_FN(MFG0_OUT1), \
+ GPIO_FN(PORT27_IROUT),
+ GPIO_FN(XDVFS2), \
+ GPIO_FN(PORT28_I2C_SDA2), \
+ GPIO_FN(PORT28_I2C_SDA3), \
+ GPIO_FN(PORT28_TPU1TO1),
+ GPIO_FN(SIM_RST), \
+ GPIO_FN(PORT29_TPU1TO1),
+ GPIO_FN(SIM_CLK), \
+ GPIO_FN(PORT30_VIO_CKOR),
+ GPIO_FN(SIM_D), \
+ GPIO_FN(PORT31_IROUT),
+ GPIO_FN(SCIFA4_TXD),
+ GPIO_FN(SCIFA4_RXD), \
+ GPIO_FN(XWUP),
+ GPIO_FN(SCIFA4_RTS_),
+ GPIO_FN(SCIFA4_CTS_),
+ GPIO_FN(FSIBOBT), \
+ GPIO_FN(FSIBIBT),
+ GPIO_FN(FSIBOLR), \
+ GPIO_FN(FSIBILR),
+ GPIO_FN(FSIBOSLD),
+ GPIO_FN(FSIBISLD),
+ GPIO_FN(VACK),
+ GPIO_FN(XTAL1L),
+ GPIO_FN(SCIFA0_RTS_), \
+ GPIO_FN(FSICOSLDT2),
+ GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(SCIFA0_CTS_), \
+ GPIO_FN(FSICOSLDT1),
+ GPIO_FN(FSICOBT), \
+ GPIO_FN(FSICIBT), \
+ GPIO_FN(FSIDOBT), \
+ GPIO_FN(FSIDIBT),
+ GPIO_FN(FSICOLR), \
+ GPIO_FN(FSICILR), \
+ GPIO_FN(FSIDOLR), \
+ GPIO_FN(FSIDILR),
+ GPIO_FN(FSICOSLD), \
+ GPIO_FN(PORT47_FSICSPDIF),
+ GPIO_FN(FSICISLD), \
+ GPIO_FN(FSIDISLD),
+ GPIO_FN(FSIACK), \
+ GPIO_FN(PORT49_IRDA_OUT), \
+ GPIO_FN(PORT49_IROUT), \
+ GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIAOLR), \
+ GPIO_FN(BBIF2_TSYNC2), \
+ GPIO_FN(TPU2TO2), \
+ GPIO_FN(FSIAILR),
+
+ GPIO_FN(FSIAOBT), \
+ GPIO_FN(BBIF2_TSCK2), \
+ GPIO_FN(TPU2TO3), \
+ GPIO_FN(FSIAIBT),
+ GPIO_FN(FSIAOSLD), \
+ GPIO_FN(BBIF2_TXD2),
+ GPIO_FN(FSIASPDIF), \
+ GPIO_FN(PORT53_IRDA_IN), \
+ GPIO_FN(TPU3TO3), \
+ GPIO_FN(FSIBSPDIF), \
+ GPIO_FN(PORT53_FSICSPDIF),
+ GPIO_FN(FSIBCK), \
+ GPIO_FN(PORT54_IRDA_FIRSEL), \
+ GPIO_FN(TPU3TO2), \
+ GPIO_FN(FSIBOMC), \
+ GPIO_FN(FSICCK), \
+ GPIO_FN(FSICOMC),
+ GPIO_FN(FSIAISLD), \
+ GPIO_FN(TPU0TO0),
+ GPIO_FN(A0), \
+ GPIO_FN(BS_),
+ GPIO_FN(A12), \
+ GPIO_FN(PORT58_KEYOUT7), \
+ GPIO_FN(TPU4TO2),
+ GPIO_FN(A13), \
+ GPIO_FN(PORT59_KEYOUT6), \
+ GPIO_FN(TPU0TO1),
+ GPIO_FN(A14), \
+ GPIO_FN(KEYOUT5),
+ GPIO_FN(A15), \
+ GPIO_FN(KEYOUT4),
+ GPIO_FN(A16), \
+ GPIO_FN(KEYOUT3), \
+ GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17), \
+ GPIO_FN(KEYOUT2), \
+ GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18), \
+ GPIO_FN(KEYOUT1), \
+ GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19), \
+ GPIO_FN(KEYOUT0), \
+ GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20), \
+ GPIO_FN(KEYIN0), \
+ GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21), \
+ GPIO_FN(KEYIN1), \
+ GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22), \
+ GPIO_FN(KEYIN2), \
+ GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23), \
+ GPIO_FN(KEYIN3), \
+ GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24), \
+ GPIO_FN(KEYIN4), \
+ GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25), \
+ GPIO_FN(KEYIN5), \
+ GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), \
+ GPIO_FN(KEYIN6),
+ GPIO_FN(KEYIN7),
+ 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),
+ GPIO_FN(CS4_),
+ GPIO_FN(CS5A_), \
+ GPIO_FN(PORT91_RDWR),
+ GPIO_FN(CS5B_), \
+ GPIO_FN(FCE1_),
+ GPIO_FN(CS6B_), \
+ GPIO_FN(DACK0),
+ GPIO_FN(FCE0_), \
+ GPIO_FN(CS6A_),
+ GPIO_FN(WAIT_), \
+ GPIO_FN(DREQ0),
+ GPIO_FN(RD__FSC),
+ GPIO_FN(WE0__FWE), \
+ GPIO_FN(RDWR_FWE),
+ GPIO_FN(WE1_),
+ GPIO_FN(FRB),
+ GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT_),
+ GPIO_FN(NBRST_),
+ GPIO_FN(BBIF2_TXD),
+ GPIO_FN(BBIF2_RXD),
+ GPIO_FN(BBIF2_SYNC),
+ GPIO_FN(BBIF2_SCK),
+ GPIO_FN(SCIFA3_CTS_), \
+ GPIO_FN(MFG3_IN2),
+ GPIO_FN(SCIFA3_RXD), \
+ GPIO_FN(MFG3_IN1),
+ GPIO_FN(BBIF1_SS2), \
+ GPIO_FN(SCIFA3_RTS_), \
+ GPIO_FN(MFG3_OUT1),
+ GPIO_FN(SCIFA3_TXD),
+ GPIO_FN(HSI_RX_DATA), \
+ GPIO_FN(BBIF1_RXD),
+ GPIO_FN(HSI_TX_WAKE), \
+ GPIO_FN(BBIF1_TSCK),
+ GPIO_FN(HSI_TX_DATA), \
+ GPIO_FN(BBIF1_TSYNC),
+ GPIO_FN(HSI_TX_READY), \
+ GPIO_FN(BBIF1_TXD),
+ GPIO_FN(HSI_RX_READY), \
+ GPIO_FN(BBIF1_RSCK), \
+ GPIO_FN(PORT115_I2C_SCL2), \
+ GPIO_FN(PORT115_I2C_SCL3),
+ GPIO_FN(HSI_RX_WAKE), \
+ GPIO_FN(BBIF1_RSYNC), \
+ GPIO_FN(PORT116_I2C_SDA2), \
+ GPIO_FN(PORT116_I2C_SDA3),
+ GPIO_FN(HSI_RX_FLAG), \
+ GPIO_FN(BBIF1_SS1), \
+ GPIO_FN(BBIF1_FLOW),
+ GPIO_FN(HSI_TX_FLAG),
+ GPIO_FN(VIO_VD), \
+ GPIO_FN(PORT128_LCD2VSYN), \
+ GPIO_FN(VIO2_VD), \
+ GPIO_FN(LCD2D0),
+
+ GPIO_FN(VIO_HD), \
+ GPIO_FN(PORT129_LCD2HSYN), \
+ GPIO_FN(PORT129_LCD2CS_), \
+ GPIO_FN(VIO2_HD), \
+ GPIO_FN(LCD2D1),
+ GPIO_FN(VIO_D0), \
+ GPIO_FN(PORT130_MSIOF2_RXD), \
+ GPIO_FN(LCD2D10),
+ GPIO_FN(VIO_D1), \
+ GPIO_FN(PORT131_KEYOUT6), \
+ GPIO_FN(PORT131_MSIOF2_SS1), \
+ GPIO_FN(PORT131_KEYOUT11), \
+ GPIO_FN(LCD2D11),
+ GPIO_FN(VIO_D2), \
+ GPIO_FN(PORT132_KEYOUT7), \
+ GPIO_FN(PORT132_MSIOF2_SS2), \
+ GPIO_FN(PORT132_KEYOUT10), \
+ GPIO_FN(LCD2D12),
+ GPIO_FN(VIO_D3), \
+ GPIO_FN(MSIOF2_TSYNC), \
+ GPIO_FN(LCD2D13),
+ GPIO_FN(VIO_D4), \
+ GPIO_FN(MSIOF2_TXD), \
+ GPIO_FN(LCD2D14),
+ GPIO_FN(VIO_D5), \
+ GPIO_FN(MSIOF2_TSCK), \
+ GPIO_FN(LCD2D15),
+ GPIO_FN(VIO_D6), \
+ GPIO_FN(PORT136_KEYOUT8), \
+ GPIO_FN(LCD2D16),
+ GPIO_FN(VIO_D7), \
+ GPIO_FN(PORT137_KEYOUT9), \
+ GPIO_FN(LCD2D17),
+ GPIO_FN(VIO_D8), \
+ GPIO_FN(PORT138_KEYOUT8), \
+ GPIO_FN(VIO2_D0), \
+ GPIO_FN(LCD2D6),
+ GPIO_FN(VIO_D9), \
+ GPIO_FN(PORT139_KEYOUT9), \
+ GPIO_FN(VIO2_D1), \
+ GPIO_FN(LCD2D7),
+ GPIO_FN(VIO_D10), \
+ GPIO_FN(TPU0TO2), \
+ GPIO_FN(VIO2_D2), \
+ GPIO_FN(LCD2D8),
+ GPIO_FN(VIO_D11), \
+ GPIO_FN(TPU0TO3), \
+ GPIO_FN(VIO2_D3), \
+ GPIO_FN(LCD2D9),
+ GPIO_FN(VIO_D12), \
+ GPIO_FN(PORT142_KEYOUT10), \
+ GPIO_FN(VIO2_D4), \
+ GPIO_FN(LCD2D2),
+ GPIO_FN(VIO_D13), \
+ GPIO_FN(PORT143_KEYOUT11), \
+ GPIO_FN(PORT143_KEYOUT6), \
+ GPIO_FN(VIO2_D5), \
+ GPIO_FN(LCD2D3),
+ GPIO_FN(VIO_D14), \
+ GPIO_FN(PORT144_KEYOUT7), \
+ GPIO_FN(VIO2_D6), \
+ GPIO_FN(LCD2D4),
+ GPIO_FN(VIO_D15), \
+ GPIO_FN(TPU1TO3), \
+ GPIO_FN(PORT145_LCD2DISP), \
+ GPIO_FN(PORT145_LCD2RS), \
+ GPIO_FN(VIO2_D7), \
+ GPIO_FN(LCD2D5),
+ GPIO_FN(VIO_CLK), \
+ GPIO_FN(LCD2DCK), \
+ GPIO_FN(PORT146_LCD2WR_), \
+ GPIO_FN(VIO2_CLK), \
+ GPIO_FN(LCD2D18),
+ GPIO_FN(VIO_FIELD), \
+ GPIO_FN(LCD2RD_), \
+ GPIO_FN(VIO2_FIELD), \
+ GPIO_FN(LCD2D19),
+ GPIO_FN(VIO_CKO),
+ GPIO_FN(A27), \
+ GPIO_FN(PORT149_RDWR), \
+ GPIO_FN(MFG0_IN1), \
+ GPIO_FN(PORT149_KEYOUT9),
+ 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(SCIFA2_TXD1), \
+ GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(SCIFA2_RXD1), \
+ GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(SCIFA2_RTS1_), \
+ GPIO_FN(PORT156_MSIOF2_SS2),
+ GPIO_FN(SCIFA2_CTS1_), \
+ GPIO_FN(PORT157_MSIOF2_RXD),
+ 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(PORT161_SCIFB_CTS_), \
+ GPIO_FN(PORT161_SCIFA5_CTS_),
+ GPIO_FN(PORT162_SCIFB_RXD), \
+ GPIO_FN(PORT162_SCIFA5_RXD),
+ GPIO_FN(PORT163_SCIFB_RTS_), \
+ GPIO_FN(PORT163_SCIFA5_RTS_), \
+ GPIO_FN(TPU3TO0),
+ GPIO_FN(LCDD0),
+ GPIO_FN(LCDD1), \
+ GPIO_FN(PORT193_SCIFA5_CTS_), \
+ GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), \
+ GPIO_FN(PORT194_SCIFA5_RTS_), \
+ GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), \
+ GPIO_FN(PORT195_SCIFA5_RXD), \
+ GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), \
+ GPIO_FN(PORT196_SCIFA5_TXD),
+ GPIO_FN(LCDD5), \
+ GPIO_FN(PORT197_SCIFA5_SCK), \
+ GPIO_FN(MFG2_OUT2), \
+ GPIO_FN(TPU2TO1),
+ GPIO_FN(LCDD6),
+ GPIO_FN(LCDD7), \
+ GPIO_FN(TPU4TO1), \
+ GPIO_FN(MFG4_OUT2),
+ GPIO_FN(LCDD8), \
+ GPIO_FN(D16),
+ GPIO_FN(LCDD9), \
+ GPIO_FN(D17),
+ GPIO_FN(LCDD10), \
+ GPIO_FN(D18),
+ GPIO_FN(LCDD11), \
+ GPIO_FN(D19),
+ GPIO_FN(LCDD12), \
+ GPIO_FN(D20),
+ GPIO_FN(LCDD13), \
+ GPIO_FN(D21),
+ GPIO_FN(LCDD14), \
+ GPIO_FN(D22),
+ GPIO_FN(LCDD15), \
+ GPIO_FN(PORT207_MSIOF0L_SS1), \
+ GPIO_FN(D23),
+ GPIO_FN(LCDD16), \
+ GPIO_FN(PORT208_MSIOF0L_SS2), \
+ GPIO_FN(D24),
+ GPIO_FN(LCDD17), \
+ 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(LCDRD_), \
+ GPIO_FN(DACK2), \
+ GPIO_FN(PORT217_LCD2RS), \
+ GPIO_FN(MSIOF0L_TSYNC), \
+ GPIO_FN(VIO2_FIELD3), \
+ GPIO_FN(PORT217_LCD2DISP),
+ GPIO_FN(LCDHSYN), \
+ GPIO_FN(LCDCS_), \
+ GPIO_FN(LCDCS2_), \
+ GPIO_FN(DACK3), \
+ GPIO_FN(PORT218_VIO_CKOR),
+ GPIO_FN(LCDDISP), \
+ GPIO_FN(LCDRS), \
+ GPIO_FN(PORT219_LCD2WR_), \
+ GPIO_FN(DREQ3), \
+ GPIO_FN(MSIOF0L_TSCK), \
+ GPIO_FN(VIO2_CLK3), \
+ GPIO_FN(LCD2DCK_2),
+ GPIO_FN(LCDVSYN), \
+ GPIO_FN(LCDVSYN2),
+ GPIO_FN(LCDLCLK), \
+ GPIO_FN(DREQ1), \
+ GPIO_FN(PORT221_LCD2CS_), \
+ GPIO_FN(PWEN), \
+ GPIO_FN(MSIOF0L_RXD), \
+ GPIO_FN(VIO2_HD3), \
+ GPIO_FN(PORT221_LCD2HSYN),
+ GPIO_FN(LCDDON), \
+ GPIO_FN(LCDDON2), \
+ GPIO_FN(DACK1), \
+ GPIO_FN(OVCN), \
+ GPIO_FN(MSIOF0L_TXD), \
+ GPIO_FN(VIO2_VD3), \
+ GPIO_FN(PORT222_LCD2VSYN),
+
+ GPIO_FN(SCIFA1_TXD), \
+ GPIO_FN(OVCN2),
+ GPIO_FN(EXTLP), \
+ GPIO_FN(SCIFA1_SCK), \
+ 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(MSIOF1_TSYNC), \
+ GPIO_FN(SCIFA2_CTS2_),
+ GPIO_FN(MSIOF1_TSCK), \
+ GPIO_FN(SCIFA2_SCK2),
+ GPIO_FN(MSIOF1_RXD), \
+ GPIO_FN(SCIFA2_RXD2),
+ GPIO_FN(MSIOF1_RSCK), \
+ GPIO_FN(SCIFA2_RTS2_), \
+ GPIO_FN(VIO2_CLK2), \
+ GPIO_FN(LCD2D20),
+ GPIO_FN(MSIOF1_RSYNC), \
+ GPIO_FN(MFG1_IN2), \
+ GPIO_FN(VIO2_VD2), \
+ GPIO_FN(LCD2D21),
+ GPIO_FN(MSIOF1_MCK0), \
+ GPIO_FN(PORT236_I2C_SDA2),
+ GPIO_FN(MSIOF1_MCK1), \
+ GPIO_FN(PORT237_I2C_SCL2),
+ GPIO_FN(MSIOF1_SS1), \
+ GPIO_FN(VIO2_FIELD2), \
+ GPIO_FN(LCD2D22),
+ GPIO_FN(MSIOF1_SS2), \
+ GPIO_FN(VIO2_HD2), \
+ GPIO_FN(LCD2D23),
+ 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(MSIOF2R_RXD),
+ GPIO_FN(PORT245_SCIFA5_RTS_), \
+ GPIO_FN(MFG2_IN2), \
+ GPIO_FN(PORT245_SCIFB_RTS_), \
+ GPIO_FN(MSIOF2R_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_I2C_SCL3), \
+ GPIO_FN(MSIOF2R_TSCK),
+ GPIO_FN(PORT249_IROUT), \
+ GPIO_FN(MFG4_IN1), \
+ GPIO_FN(PORT249_I2C_SDA3), \
+ GPIO_FN(MSIOF2R_TSYNC),
+ GPIO_FN(SDHICLK0),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0),
+ GPIO_FN(SDHID0_1),
+ GPIO_FN(SDHID0_2),
+ GPIO_FN(SDHID0_3),
+ GPIO_FN(SDHICMD0),
+ GPIO_FN(SDHIWP0),
+ GPIO_FN(SDHICLK1),
+ GPIO_FN(SDHID1_0), \
+ GPIO_FN(TS_SPSYNC2),
+ GPIO_FN(SDHID1_1), \
+ GPIO_FN(TS_SDAT2),
+ GPIO_FN(SDHID1_2), \
+ GPIO_FN(TS_SDEN2),
+ GPIO_FN(SDHID1_3), \
+ GPIO_FN(TS_SCK2),
+ GPIO_FN(SDHICMD1),
+ GPIO_FN(SDHICLK2),
+ GPIO_FN(SDHID2_0), \
+ GPIO_FN(TS_SPSYNC4),
+ GPIO_FN(SDHID2_1), \
+ GPIO_FN(TS_SDAT4),
+ GPIO_FN(SDHID2_2), \
+ GPIO_FN(TS_SDEN4),
+ GPIO_FN(SDHID2_3), \
+ GPIO_FN(TS_SCK4),
+ GPIO_FN(SDHICMD2),
+ GPIO_FN(MMCCLK0),
+ GPIO_FN(MMCD0_0),
+ GPIO_FN(MMCD0_1),
+ GPIO_FN(MMCD0_2),
+ GPIO_FN(MMCD0_3),
+ GPIO_FN(MMCD0_4), \
+ GPIO_FN(TS_SPSYNC5),
+ GPIO_FN(MMCD0_5), \
+ GPIO_FN(TS_SDAT5),
+ GPIO_FN(MMCD0_6), \
+ GPIO_FN(TS_SDEN5),
+ GPIO_FN(MMCD0_7), \
+ GPIO_FN(TS_SCK5),
+ GPIO_FN(MMCCMD0),
+ GPIO_FN(RESETOUTS_), \
+ GPIO_FN(EXTAL2OUT),
+ GPIO_FN(MCP_WAIT__MCP_FRB),
+ GPIO_FN(MCP_CKO), \
+ GPIO_FN(MMCCLK1),
+ GPIO_FN(MCP_D15_MCP_NAF15),
+ GPIO_FN(MCP_D14_MCP_NAF14),
+ GPIO_FN(MCP_D13_MCP_NAF13),
+ GPIO_FN(MCP_D12_MCP_NAF12),
+ GPIO_FN(MCP_D11_MCP_NAF11),
+ GPIO_FN(MCP_D10_MCP_NAF10),
+ GPIO_FN(MCP_D9_MCP_NAF9),
+ GPIO_FN(MCP_D8_MCP_NAF8), \
+ GPIO_FN(MMCCMD1),
+ GPIO_FN(MCP_D7_MCP_NAF7), \
+ GPIO_FN(MMCD1_7),
+
+ GPIO_FN(MCP_D6_MCP_NAF6), \
+ GPIO_FN(MMCD1_6),
+ GPIO_FN(MCP_D5_MCP_NAF5), \
+ GPIO_FN(MMCD1_5),
+ GPIO_FN(MCP_D4_MCP_NAF4), \
+ GPIO_FN(MMCD1_4),
+ GPIO_FN(MCP_D3_MCP_NAF3), \
+ GPIO_FN(MMCD1_3),
+ GPIO_FN(MCP_D2_MCP_NAF2), \
+ GPIO_FN(MMCD1_2),
+ GPIO_FN(MCP_D1_MCP_NAF1), \
+ GPIO_FN(MMCD1_1),
+ GPIO_FN(MCP_D0_MCP_NAF0), \
+ GPIO_FN(MMCD1_0),
+ GPIO_FN(MCP_NBRSTOUT_),
+ GPIO_FN(MCP_WE0__MCP_FWE), \
+ GPIO_FN(MCP_RDWR_MCP_FWE),
+
+ /* MSEL2 special cases */
+ GPIO_FN(TSIF2_TS_XX1),
+ GPIO_FN(TSIF2_TS_XX2),
+ GPIO_FN(TSIF2_TS_XX3),
+ GPIO_FN(TSIF2_TS_XX4),
+ GPIO_FN(TSIF2_TS_XX5),
+ GPIO_FN(TSIF1_TS_XX1),
+ GPIO_FN(TSIF1_TS_XX2),
+ GPIO_FN(TSIF1_TS_XX3),
+ GPIO_FN(TSIF1_TS_XX4),
+ GPIO_FN(TSIF1_TS_XX5),
+ GPIO_FN(TSIF0_TS_XX1),
+ GPIO_FN(TSIF0_TS_XX2),
+ GPIO_FN(TSIF0_TS_XX3),
+ GPIO_FN(TSIF0_TS_XX4),
+ GPIO_FN(TSIF0_TS_XX5),
+ GPIO_FN(MST1_TS_XX1),
+ GPIO_FN(MST1_TS_XX2),
+ GPIO_FN(MST1_TS_XX3),
+ GPIO_FN(MST1_TS_XX4),
+ GPIO_FN(MST1_TS_XX5),
+ GPIO_FN(MST0_TS_XX1),
+ GPIO_FN(MST0_TS_XX2),
+ GPIO_FN(MST0_TS_XX3),
+ GPIO_FN(MST0_TS_XX4),
+ GPIO_FN(MST0_TS_XX5),
+
+ /* MSEL3 special cases */
+ GPIO_FN(SDHI0_VCCQ_MC0_ON),
+ GPIO_FN(SDHI0_VCCQ_MC0_OFF),
+ GPIO_FN(DEBUG_MON_VIO),
+ GPIO_FN(DEBUG_MON_LCDD),
+ GPIO_FN(LCDC_LCDC0),
+ GPIO_FN(LCDC_LCDC1),
+
+ /* MSEL4 special cases */
+ GPIO_FN(IRQ9_MEM_INT),
+ GPIO_FN(IRQ9_MCP_INT),
+ GPIO_FN(A11),
+ GPIO_FN(KEYOUT8),
+ GPIO_FN(TPU4TO3),
+ GPIO_FN(RESETA_N_PU_ON),
+ GPIO_FN(RESETA_N_PU_OFF),
+ GPIO_FN(EDBGREQ_PD),
+ GPIO_FN(EDBGREQ_PU),
+
+ /* Functions with pull-ups */
+ GPIO_FN(KEYIN0_PU),
+ GPIO_FN(KEYIN1_PU),
+ GPIO_FN(KEYIN2_PU),
+ GPIO_FN(KEYIN3_PU),
+ GPIO_FN(KEYIN4_PU),
+ GPIO_FN(KEYIN5_PU),
+ GPIO_FN(KEYIN6_PU),
+ GPIO_FN(KEYIN7_PU),
+ GPIO_FN(SDHID1_0_PU),
+ GPIO_FN(SDHID1_1_PU),
+ GPIO_FN(SDHID1_2_PU),
+ GPIO_FN(SDHID1_3_PU),
+ GPIO_FN(SDHICMD1_PU),
+ GPIO_FN(MMCCMD0_PU),
+ GPIO_FN(MMCCMD1_PU),
+ GPIO_FN(FSIACK_PU),
+ GPIO_FN(FSIAILR_PU),
+ GPIO_FN(FSIAIBT_PU),
+ GPIO_FN(FSIAISLD_PU),
+};
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ 0, \
+ /*0001*/ PORT##nr##_OUT , \
+ /*0010*/ PORT##nr##_IN , 0, 0, 0, 0, 0, 0, 0, \
+ /*1010*/ PORT##nr##_IN_PD, 0, 0, 0, \
+ /*1110*/ PORT##nr##_IN_PU, 0, \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7, 0, 0, 0, 0, 0, 0, 0, 0 } \
+ }
+
+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, 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, 0xe605102e), /* PORT46CR */
+ PORTCR(47, 0xe605102f), /* PORT47CR */
+ PORTCR(48, 0xe6051030), /* PORT48CR */
+ PORTCR(49, 0xe6051031), /* PORT49CR */
+
+ PORTCR(50, 0xe6051032), /* PORT50CR */
+ PORTCR(51, 0xe6051033), /* PORT51CR */
+ PORTCR(52, 0xe6051034), /* PORT52CR */
+ PORTCR(53, 0xe6051035), /* PORT53CR */
+ PORTCR(54, 0xe6051036), /* PORT54CR */
+ PORTCR(55, 0xe6051037), /* PORT55CR */
+ PORTCR(56, 0xe6051038), /* PORT56CR */
+ PORTCR(57, 0xe6051039), /* PORT57CR */
+ PORTCR(58, 0xe605103a), /* PORT58CR */
+ PORTCR(59, 0xe605103b), /* PORT59CR */
+
+ PORTCR(60, 0xe605103c), /* PORT60CR */
+ PORTCR(61, 0xe605103d), /* PORT61CR */
+ PORTCR(62, 0xe605103e), /* PORT62CR */
+ PORTCR(63, 0xe605103f), /* PORT63CR */
+ PORTCR(64, 0xe6051040), /* PORT64CR */
+ PORTCR(65, 0xe6051041), /* PORT65CR */
+ PORTCR(66, 0xe6051042), /* PORT66CR */
+ PORTCR(67, 0xe6051043), /* PORT67CR */
+ PORTCR(68, 0xe6051044), /* PORT68CR */
+ PORTCR(69, 0xe6051045), /* PORT69CR */
+
+ PORTCR(70, 0xe6051046), /* PORT70CR */
+ PORTCR(71, 0xe6051047), /* PORT71CR */
+ PORTCR(72, 0xe6051048), /* PORT72CR */
+ PORTCR(73, 0xe6051049), /* PORT73CR */
+ PORTCR(74, 0xe605104a), /* PORT74CR */
+ PORTCR(75, 0xe605104b), /* PORT75CR */
+ PORTCR(76, 0xe605104c), /* PORT76CR */
+ PORTCR(77, 0xe605104d), /* PORT77CR */
+ PORTCR(78, 0xe605104e), /* PORT78CR */
+ PORTCR(79, 0xe605104f), /* PORT79CR */
+
+ PORTCR(80, 0xe6051050), /* PORT80CR */
+ PORTCR(81, 0xe6051051), /* PORT81CR */
+ PORTCR(82, 0xe6051052), /* PORT82CR */
+ PORTCR(83, 0xe6051053), /* PORT83CR */
+ PORTCR(84, 0xe6051054), /* PORT84CR */
+ PORTCR(85, 0xe6051055), /* PORT85CR */
+ PORTCR(86, 0xe6051056), /* PORT86CR */
+ PORTCR(87, 0xe6051057), /* 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, 0xe6052060), /* PORT96CR */
+ PORTCR(97, 0xe6052061), /* PORT97CR */
+ PORTCR(98, 0xe6052062), /* PORT98CR */
+ PORTCR(99, 0xe6052063), /* PORT99CR */
+
+ PORTCR(100, 0xe6052064), /* PORT100CR */
+ PORTCR(101, 0xe6052065), /* PORT101CR */
+ PORTCR(102, 0xe6052066), /* PORT102CR */
+ PORTCR(103, 0xe6052067), /* PORT103CR */
+ PORTCR(104, 0xe6052068), /* PORT104CR */
+ PORTCR(105, 0xe6052069), /* PORT105CR */
+ PORTCR(106, 0xe605206a), /* PORT106CR */
+ PORTCR(107, 0xe605206b), /* PORT107CR */
+ PORTCR(108, 0xe605206c), /* PORT108CR */
+ PORTCR(109, 0xe605206d), /* PORT109CR */
+
+ PORTCR(110, 0xe605206e), /* PORT110CR */
+ PORTCR(111, 0xe605206f), /* PORT111CR */
+ PORTCR(112, 0xe6052070), /* PORT112CR */
+ PORTCR(113, 0xe6052071), /* PORT113CR */
+ PORTCR(114, 0xe6052072), /* PORT114CR */
+ PORTCR(115, 0xe6052073), /* PORT115CR */
+ PORTCR(116, 0xe6052074), /* PORT116CR */
+ PORTCR(117, 0xe6052075), /* PORT117CR */
+ PORTCR(118, 0xe6052076), /* PORT118CR */
+
+ PORTCR(128, 0xe6052080), /* PORT128CR */
+ PORTCR(129, 0xe6052081), /* PORT129CR */
+
+ PORTCR(130, 0xe6052082), /* PORT130CR */
+ PORTCR(131, 0xe6052083), /* PORT131CR */
+ PORTCR(132, 0xe6052084), /* PORT132CR */
+ PORTCR(133, 0xe6052085), /* PORT133CR */
+ PORTCR(134, 0xe6052086), /* PORT134CR */
+ PORTCR(135, 0xe6052087), /* PORT135CR */
+ PORTCR(136, 0xe6052088), /* PORT136CR */
+ PORTCR(137, 0xe6052089), /* PORT137CR */
+ PORTCR(138, 0xe605208a), /* PORT138CR */
+ PORTCR(139, 0xe605208b), /* PORT139CR */
+
+ PORTCR(140, 0xe605208c), /* PORT140CR */
+ PORTCR(141, 0xe605208d), /* PORT141CR */
+ PORTCR(142, 0xe605208e), /* PORT142CR */
+ PORTCR(143, 0xe605208f), /* PORT143CR */
+ PORTCR(144, 0xe6052090), /* PORT144CR */
+ PORTCR(145, 0xe6052091), /* PORT145CR */
+ PORTCR(146, 0xe6052092), /* PORT146CR */
+ PORTCR(147, 0xe6052093), /* PORT147CR */
+ PORTCR(148, 0xe6052094), /* PORT148CR */
+ PORTCR(149, 0xe6052095), /* PORT149CR */
+
+ PORTCR(150, 0xe6052096), /* PORT150CR */
+ PORTCR(151, 0xe6052097), /* PORT151CR */
+ PORTCR(152, 0xe6052098), /* PORT152CR */
+ PORTCR(153, 0xe6052099), /* PORT153CR */
+ PORTCR(154, 0xe605209a), /* PORT154CR */
+ PORTCR(155, 0xe605209b), /* PORT155CR */
+ PORTCR(156, 0xe605209c), /* PORT156CR */
+ PORTCR(157, 0xe605209d), /* PORT157CR */
+ PORTCR(158, 0xe605209e), /* PORT158CR */
+ PORTCR(159, 0xe605209f), /* PORT159CR */
+
+ PORTCR(160, 0xe60520a0), /* PORT160CR */
+ PORTCR(161, 0xe60520a1), /* PORT161CR */
+ PORTCR(162, 0xe60520a2), /* PORT162CR */
+ PORTCR(163, 0xe60520a3), /* PORT163CR */
+ PORTCR(164, 0xe60520a4), /* 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, 0xe60530e0), /* PORT224CR */
+ PORTCR(225, 0xe60530e1), /* PORT225CR */
+ PORTCR(226, 0xe60530e2), /* PORT226CR */
+ PORTCR(227, 0xe60530e3), /* PORT227CR */
+ PORTCR(228, 0xe60530e4), /* PORT228CR */
+ PORTCR(229, 0xe60530e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60530e6), /* PORT230CR */
+ PORTCR(231, 0xe60530e7), /* PORT231CR */
+ PORTCR(232, 0xe60530e8), /* PORT232CR */
+ PORTCR(233, 0xe60530e9), /* PORT233CR */
+ PORTCR(234, 0xe60530ea), /* PORT234CR */
+ PORTCR(235, 0xe60530eb), /* 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 */
+ PORTCR(273, 0xe6053111), /* PORT273CR */
+ PORTCR(274, 0xe6053112), /* PORT274CR */
+ PORTCR(275, 0xe6053113), /* PORT275CR */
+ PORTCR(276, 0xe6053114), /* PORT276CR */
+ PORTCR(277, 0xe6053115), /* PORT277CR */
+ PORTCR(278, 0xe6053116), /* PORT278CR */
+ PORTCR(279, 0xe6053117), /* PORT279CR */
+
+ PORTCR(280, 0xe6053118), /* PORT280CR */
+ PORTCR(281, 0xe6053119), /* PORT281CR */
+ PORTCR(282, 0xe605311a), /* PORT282CR */
+
+ PORTCR(288, 0xe6052120), /* PORT288CR */
+ PORTCR(289, 0xe6052121), /* PORT289CR */
+
+ PORTCR(290, 0xe6052122), /* PORT290CR */
+ PORTCR(291, 0xe6052123), /* PORT291CR */
+ PORTCR(292, 0xe6052124), /* PORT292CR */
+ PORTCR(293, 0xe6052125), /* PORT293CR */
+ PORTCR(294, 0xe6052126), /* PORT294CR */
+ PORTCR(295, 0xe6052127), /* PORT295CR */
+ PORTCR(296, 0xe6052128), /* PORT296CR */
+ PORTCR(297, 0xe6052129), /* PORT297CR */
+ PORTCR(298, 0xe605212a), /* PORT298CR */
+ PORTCR(299, 0xe605212b), /* PORT299CR */
+
+ PORTCR(300, 0xe605212c), /* PORT300CR */
+ PORTCR(301, 0xe605212d), /* PORT301CR */
+ PORTCR(302, 0xe605212e), /* PORT302CR */
+ PORTCR(303, 0xe605212f), /* PORT303CR */
+ PORTCR(304, 0xe6052130), /* PORT304CR */
+ PORTCR(305, 0xe6052131), /* PORT305CR */
+ PORTCR(306, 0xe6052132), /* PORT306CR */
+ PORTCR(307, 0xe6052133), /* PORT307CR */
+ PORTCR(308, 0xe6052134), /* PORT308CR */
+ PORTCR(309, 0xe6052135), /* PORT309CR */
+
+ { PINMUX_CFG_REG("MSEL2CR", 0xe605801c, 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,
+ MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
+ MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
+ MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1,
+ MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1,
+ 0, 0,
+ MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1,
+ MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1,
+ MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1,
+ MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1,
+ MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1,
+ MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1,
+ MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1,
+ MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1,
+ MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1,
+ MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL3CR", 0xe6058020, 32, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_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,
+ MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1,
+ 0, 0,
+ MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1,
+ 0, 0,
+ 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL4CR", 0xe6058024, 32, 1) {
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1,
+ 0, 0,
+ MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1,
+ MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1,
+ MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1,
+ MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1,
+ 0, 0,
+ MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1,
+ MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1,
+ MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1,
+ MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1,
+ MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1,
+ MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1,
+ MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1,
+ 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("PORTD063_032DR", 0xe6055000, 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("PORTD095_064DR", 0xe6055004, 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("PORTR127_096DR", 0xe6056000, 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("PORTR159_128DR", 0xe6056004, 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", 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, 0,
+ 0, 0, 0, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe605600C, 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, PORT282_DATA, PORT281_DATA, PORT280_DATA,
+ PORT279_DATA, PORT278_DATA, PORT277_DATA, PORT276_DATA,
+ PORT275_DATA, PORT274_DATA, PORT273_DATA, 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 }
+ },
+ { PINMUX_DATA_REG("PORTR319_288DR", 0xe6056010, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, PORT309_DATA, PORT308_DATA,
+ PORT307_DATA, PORT306_DATA, PORT305_DATA, PORT304_DATA,
+ PORT303_DATA, PORT302_DATA, PORT301_DATA, PORT300_DATA,
+ PORT299_DATA, PORT298_DATA, PORT297_DATA, PORT296_DATA,
+ PORT295_DATA, PORT294_DATA, PORT293_DATA, PORT292_DATA,
+ PORT291_DATA, PORT290_DATA, PORT289_DATA, PORT288_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh73a0_pinmux_info = {
+ .name = "sh73a0_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_FSIAISLD_PU,
+
+ .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 sh73a0_pinmux_init(void)
+{
+ register_pinmux(&sh73a0_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 564a6d0be473..2e3e11ee7c43 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -416,6 +416,16 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
.addr = 0xe6870030,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ .addr = 0xe6bd0034,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xd1,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ .addr = 0xe6bd0034,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xd2,
},
};
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
new file mode 100644
index 000000000000..f1eff8b37bd6
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -0,0 +1,412 @@
+/*
+ * sh73a0 processor support
+ *
+ * Copyright (C) 2010 Takashi Yoshii
+ * 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_SCIFA,
+ .irqs = { gic_spi(72), gic_spi(72),
+ gic_spi(72), gic_spi(72) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(73), gic_spi(73),
+ gic_spi(73), gic_spi(73) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(74), gic_spi(74),
+ gic_spi(74), gic_spi(74) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(75), gic_spi(75),
+ gic_spi(75), gic_spi(75) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(78), gic_spi(78),
+ gic_spi(78), gic_spi(78) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(79), gic_spi(79),
+ gic_spi(79), gic_spi(79) },
+};
+
+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_SCIFA,
+ .irqs = { gic_spi(156), gic_spi(156),
+ gic_spi(156), gic_spi(156) },
+};
+
+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 = 0xe6cd0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(143), gic_spi(143),
+ gic_spi(143), gic_spi(143) },
+};
+
+static struct platform_device scif7_device = {
+ .name = "sh-sci",
+ .id = 7,
+ .dev = {
+ .platform_data = &scif7_platform_data,
+ },
+};
+
+static struct plat_sci_port scif8_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIFB,
+ .irqs = { gic_spi(80), gic_spi(80),
+ gic_spi(80), gic_spi(80) },
+};
+
+static struct platform_device scif8_device = {
+ .name = "sh-sci",
+ .id = 8,
+ .dev = {
+ .platform_data = &scif8_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(65),
+ .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),
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+ .name = "TMU00",
+ .channel_offset = 0x4,
+ .timer_bit = 0,
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+ [0] = {
+ .name = "TMU00",
+ .start = 0xfff60008,
+ .end = 0xfff60013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu00_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu00_platform_data,
+ },
+ .resource = tmu00_resources,
+ .num_resources = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+ .name = "TMU01",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+ [0] = {
+ .name = "TMU01",
+ .start = 0xfff60014,
+ .end = 0xfff6001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu01_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu01_platform_data,
+ },
+ .resource = tmu01_resources,
+ .num_resources = ARRAY_SIZE(tmu01_resources),
+};
+
+static struct resource i2c0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xe6820000,
+ .end = 0xe6820425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(167),
+ .end = gic_spi(170),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xe6822000,
+ .end = 0xe6822425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(51),
+ .end = gic_spi(54),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c2_resources[] = {
+ [0] = {
+ .name = "IIC2",
+ .start = 0xe6824000,
+ .end = 0xe6824425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(171),
+ .end = gic_spi(174),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c3_resources[] = {
+ [0] = {
+ .name = "IIC3",
+ .start = 0xe6826000,
+ .end = 0xe6826425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(183),
+ .end = gic_spi(186),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c4_resources[] = {
+ [0] = {
+ .name = "IIC4",
+ .start = 0xe6828000,
+ .end = 0xe6828425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(187),
+ .end = gic_spi(190),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0,
+ .resource = i2c0_resources,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+};
+
+static struct platform_device i2c1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1,
+ .resource = i2c1_resources,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+};
+
+static struct platform_device i2c2_device = {
+ .name = "i2c-sh_mobile",
+ .id = 2,
+ .resource = i2c2_resources,
+ .num_resources = ARRAY_SIZE(i2c2_resources),
+};
+
+static struct platform_device i2c3_device = {
+ .name = "i2c-sh_mobile",
+ .id = 3,
+ .resource = i2c3_resources,
+ .num_resources = ARRAY_SIZE(i2c3_resources),
+};
+
+static struct platform_device i2c4_device = {
+ .name = "i2c-sh_mobile",
+ .id = 4,
+ .resource = i2c4_resources,
+ .num_resources = ARRAY_SIZE(i2c4_resources),
+};
+
+static struct platform_device *sh73a0_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &scif8_device,
+ &cmt10_device,
+ &tmu00_device,
+ &tmu01_device,
+};
+
+static struct platform_device *sh73a0_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &i2c2_device,
+ &i2c3_device,
+ &i2c4_device,
+};
+
+void __init sh73a0_add_standard_devices(void)
+{
+ platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
+ platform_add_devices(sh73a0_late_devices,
+ ARRAY_SIZE(sh73a0_late_devices));
+}
+
+void __init sh73a0_add_early_devices(void)
+{
+ early_platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
+}
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
index ba32a15127ab..3970a9cdce26 100644
--- a/arch/arm/mach-tcc8k/clock.c
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -12,8 +12,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
index 78d06008841d..e0a8d609afe1 100644
--- a/arch/arm/mach-tcc8k/time.c
+++ b/arch/arm/mach-tcc8k/time.c
@@ -35,7 +35,6 @@ static struct clocksource clocksource_tcc = {
.rating = 200,
.read = tcc_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 28,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -103,9 +102,7 @@ static int __init tcc_clockevent_init(struct clk *clock)
{
unsigned int c = clk_get_rate(clock);
- clocksource_tcc.mult = clocksource_hz2mult(c,
- clocksource_tcc.shift);
- clocksource_register(&clocksource_tcc);
+ clocksource_register_hz(&clocksource_tcc, c);
clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
clockevent_tcc.shift);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index ae19f95585be..77948e0f4909 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/regulator/consumer.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include "clock.h"
#include "board.h"
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 94fd859770f1..083a4cfc6cf0 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -21,7 +21,7 @@
#define __MACH_TEGRA_CLOCK_H
#include <linux/list.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#define DIV_BUS (1 << 0)
#define DIV_U71 (1 << 1)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 8e7f115aa21e..a5cb1ce76ff2 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -11,12 +11,9 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/completion.h>
#include <asm/cacheflush.h>
-static DECLARE_COMPLETION(cpu_killed);
-
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
@@ -29,13 +26,13 @@ static inline void cpu_enter_lowpower(void)
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
- " bic %0, %0, #0x20\n"
+ " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
- : "r" (0)
+ : "r" (0), "Ir" (CR_C)
: "cc");
}
@@ -45,17 +42,17 @@ static inline void cpu_leave_lowpower(void)
asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n"
- " orr %0, %0, #0x04\n"
+ " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
- :
+ : "Ir" (CR_C)
: "cc");
}
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{
/*
* there is no power-control hardware on this platform, so all
@@ -79,22 +76,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
/*}*/
/*
- * getting here, means that we have come out of WFI without
+ * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
- * The trouble is, letting people know about this is not really
- * possible, since we are currently running incoherently, and
- * therefore cannot safely call printk() or anything else
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
*/
-#ifdef DEBUG
- printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
-#endif
+ (*spurious)++;
}
}
int platform_cpu_kill(unsigned int cpu)
{
- return wait_for_completion_timeout(&cpu_killed, 5000);
+ return 1;
}
/*
@@ -104,30 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
-#ifdef DEBUG
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
-#endif
-
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
+ int spurious = 0;
/*
* we're ready for shutdown now, so do it
*/
cpu_enter_lowpower();
- platform_do_lowpower(cpu);
+ platform_do_lowpower(cpu, &spurious);
/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 8ea3bffb4e00..a0e7c12868bd 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -21,8 +21,8 @@
#include <mach/io.h>
.macro addruart, rp, rv
- ldreq \rp, =IO_APB_PHYS @ physical
- ldrne \rv, =IO_APB_VIRT @ virtual
+ ldr \rp, =IO_APB_PHYS @ physical
+ ldr \rv, =IO_APB_VIRT @ virtual
#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
#error "A debug UART must be selected in the kernel config to use DEBUG_LL"
#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
index 2ba9e5c9d2f6..dd165c53889d 100644
--- a/arch/arm/mach-tegra/include/mach/entry-macro.S
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -16,8 +16,8 @@
#include <mach/io.h>
#if defined(CONFIG_ARM_GIC)
-
-#include <asm/hardware/gic.h>
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
/* Uses the GIC interrupt controller built into the cpu */
#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
@@ -32,68 +32,6 @@
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an interrupt
- * if it's between 30 and 1020. The test_for_ipi routine below will
- * pick up on IPIs.
- *
- * A simple read from the controller will tell us the number of the
- * highest priority enabled interrupt. We then just need to check
- * whether it is in the valid range for an IRQ (30-1020 inclusive).
- */
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- /* bits 12-10 = src CPU, 9-0 = int # */
- ldr \irqstat, [\base, #GIC_CPU_INTACK]
-
- ldr \tmp, =1021
-
- bic \irqnr, \irqstat, #0x1c00
-
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
-
- .endm
-
- /* We assume that irqstat (the raw value of the IRQ acknowledge
- * register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of interrupt on the
- * controller, since this requires the original irqstat value which
- * we won't easily be able to recreate later.
- */
-
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base are preserved.. */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
-
#else
/* legacy interrupt controller for AP16 */
.macro disable_fiq
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
index f0981b1ac59e..4cea2230c8dc 100644
--- a/arch/arm/mach-tegra/include/mach/io.h
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -65,8 +65,8 @@
#ifndef __ASSEMBLER__
-#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t)
-#define __arch_iounmap(v) tegra_iounmap(v)
+#define __arch_ioremap tegra_ioremap
+#define __arch_iounmap tegra_iounmap
void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
void tegra_iounmap(volatile void __iomem *addr);
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index e4a34a35a544..c8221b38ee7c 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -2,21 +2,13 @@
#define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
-{
- gic_raise_softirq(mask, 1);
-}
-
-/*
- * Do nothing on MPcore.
- */
-static inline void smp_cross_call_done(cpumask_t callmap)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 50a8dfb9a0cf..5407de01abf0 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -94,8 +94,8 @@ void __init tegra_init_irq(void)
writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS);
}
- gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
- gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+ gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+ IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
gic = get_irq_chip(29);
gic_unmask_irq = gic->unmask;
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 1c0fd92cab39..ec1f68924edf 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -22,7 +22,6 @@
#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <mach/iomap.h>
@@ -41,14 +40,12 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100);
+ gic_secondary_init(0);
/*
* Synchronise with the boot thread.
@@ -117,24 +114,20 @@ void __init smp_init_cpus(void)
{
unsigned int i, ncores = scu_get_core_count(scu_base);
+ if (ncores > NR_CPUS) {
+ printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
for (i = 0; i < ncores; i++)
cpu_set(i, cpu_possible_map);
}
-void __init smp_prepare_cpus(unsigned int max_cpus)
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- unsigned int ncores = scu_get_core_count(scu_base);
- unsigned int cpu = smp_processor_id();
int i;
- smp_store_cpu_info(cpu);
-
- /*
- * are we trying to boot more cores than exist?
- */
- if (max_cpus > ncores)
- max_cpus = ncores;
-
/*
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time.
@@ -142,15 +135,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
- /*
- * Initialise the SCU if there are more than one CPU and let
- * them know where to start. Note that, on modern versions of
- * MILO, the "poke" doesn't actually do anything until each
- * individual core is sent a soft interrupt to get it out of
- * WFI
- */
- if (max_cpus > 1) {
- percpu_timer_setup();
- scu_enable(scu_base);
- }
+ scu_enable(scu_base);
}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ae3b308e22a4..f0dae6d8ba52 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -24,8 +24,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/hrtimer.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <mach/iomap.h>
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 9057d6fd1d31..7b8ad1f98f44 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -18,6 +18,7 @@
*/
#include <linux/init.h>
+#include <linux/sched.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -25,10 +26,10 @@
#include <linux/clocksource.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/cnt32_to_63.h>
#include <asm/mach/time.h>
#include <asm/localtimer.h>
+#include <asm/sched_clock.h>
#include <mach/iomap.h>
#include <mach/irqs.h>
@@ -91,7 +92,7 @@ static void tegra_timer_set_mode(enum clock_event_mode mode,
static cycle_t tegra_clocksource_read(struct clocksource *cs)
{
- return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US));
+ return timer_readl(TIMERUS_CNTR_1US);
}
static struct clock_event_device tegra_clockevent = {
@@ -106,14 +107,29 @@ static struct clocksource tegra_clocksource = {
.name = "timer_us",
.rating = 300,
.read = tegra_clocksource_read,
- .mask = 0x7FFFFFFFFFFFFFFFULL,
+ .mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-unsigned long long sched_clock(void)
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 1us and a wrap period of about 1h11min.
+ */
+#define SC_MULT 4194304000u
+#define SC_SHIFT 22
+
+unsigned long long notrace sched_clock(void)
{
- return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource),
- tegra_clocksource.mult, tegra_clocksource.shift);
+ u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace tegra_update_sched_clock(void)
+{
+ u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+ update_sched_clock(&cd, cyc, (u32)~0);
}
static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
@@ -158,6 +174,9 @@ static void __init tegra_init_timer(void)
WARN(1, "Unknown clock rate");
}
+ init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
+ 1000000, SC_MULT, SC_SHIFT);
+
if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
printk(KERN_ERR "Failed to register clocksource\n");
BUG();
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 7458fc6df5c6..fabcc49abe80 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -25,8 +25,8 @@
#include <linux/timer.h>
#include <linux/io.h>
#include <linux/seq_file.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <mach/hardware.h>
#include <mach/syscon.h>
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 3fc4472719be..3ec58bd2d6e4 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -9,6 +9,7 @@
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/clockchips.h>
@@ -21,6 +22,7 @@
#include <mach/hardware.h>
/* Generic stuff */
+#include <asm/sched_clock.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
@@ -352,12 +354,18 @@ static struct clocksource clocksource_u300_1mhz = {
* this wraps around for now, since it is just a relative time
* stamp. (Inspired by OMAP implementation.)
*/
+static DEFINE_CLOCK_DATA(cd);
+
unsigned long long notrace sched_clock(void)
{
- return clocksource_cyc2ns(clocksource_u300_1mhz.read(
- &clocksource_u300_1mhz),
- clocksource_u300_1mhz.mult,
- clocksource_u300_1mhz.shift);
+ u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace u300_update_sched_clock(void)
+{
+ u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+ update_sched_clock(&cd, cyc, (u32)~0);
}
@@ -375,6 +383,8 @@ static void __init u300_timer_init(void)
clk_enable(clk);
rate = clk_get_rate(clk);
+ init_sched_clock(&cd, u300_update_sched_clock, 32, rate);
+
/*
* Disable the "OS" and "DD" timers - these are designed for Symbian!
* Example usage in cnh1601578 cpu subsystem pd_timer_app.c
@@ -412,9 +422,7 @@ static void __init u300_timer_init(void)
writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
- clocksource_calc_mult_shift(&clocksource_u300_1mhz,
- rate, APPTIMER_MIN_RANGE);
- if (clocksource_register(&clocksource_u300_1mhz))
+ if (clocksource_register_hz(&clocksource_u300_1mhz, rate))
printk(KERN_ERR "timer: failed to initialize clock "
"source %s\n", clocksource_u300_1mhz.name);
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 9e27a84433cb..12052e8e064c 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -2,14 +2,16 @@
# Makefile for the linux kernel, U8500 machine.
#
-obj-y := clock.o cpu.o devices.o
-obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o
+obj-y := clock.o cpu.o devices.o devices-common.o
+obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
-obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o
-obj-$(CONFIG_MACH_U5500) += board-u5500.o
+obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \
+ board-mop500-keypads.o
+obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o
-obj-$(CONFIG_U5500_MODEM_IRQ) += modem_irq.o
-obj-$(CONFIG_U5500_MBOX) += mbox.o
+obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o
+obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
diff --git a/arch/arm/mach-ux500/board-mop500-keypads.c b/arch/arm/mach-ux500/board-mop500-keypads.c
new file mode 100644
index 000000000000..70318c354d32
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-keypads.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Keypad layouts for various boards
+ */
+
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/stmpe.h>
+#include <linux/mfd/tc3589x.h>
+#include <linux/input/matrix_keypad.h>
+
+#include <plat/pincfg.h>
+#include <plat/ske.h>
+
+#include <mach/devices.h>
+#include <mach/hardware.h>
+
+#include "devices-db8500.h"
+#include "board-mop500.h"
+
+/* STMPE/SKE keypad use this key layout */
+static const unsigned int mop500_keymap[] = {
+ KEY(2, 5, KEY_END),
+ KEY(4, 1, KEY_POWER),
+ KEY(3, 5, KEY_VOLUMEDOWN),
+ KEY(1, 3, KEY_3),
+ KEY(5, 2, KEY_RIGHT),
+ KEY(5, 0, KEY_9),
+
+ KEY(0, 5, KEY_MENU),
+ KEY(7, 6, KEY_ENTER),
+ KEY(4, 5, KEY_0),
+ KEY(6, 7, KEY_2),
+ KEY(3, 4, KEY_UP),
+ KEY(3, 3, KEY_DOWN),
+
+ KEY(6, 4, KEY_SEND),
+ KEY(6, 2, KEY_BACK),
+ KEY(4, 2, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_1),
+ KEY(4, 3, KEY_LEFT),
+ KEY(3, 2, KEY_7),
+};
+
+static const struct matrix_keymap_data mop500_keymap_data = {
+ .keymap = mop500_keymap,
+ .keymap_size = ARRAY_SIZE(mop500_keymap),
+};
+
+/*
+ * Nomadik SKE keypad
+ */
+#define ROW_PIN_I0 164
+#define ROW_PIN_I1 163
+#define ROW_PIN_I2 162
+#define ROW_PIN_I3 161
+#define ROW_PIN_I4 156
+#define ROW_PIN_I5 155
+#define ROW_PIN_I6 154
+#define ROW_PIN_I7 153
+#define COL_PIN_O0 168
+#define COL_PIN_O1 167
+#define COL_PIN_O2 166
+#define COL_PIN_O3 165
+#define COL_PIN_O4 160
+#define COL_PIN_O5 159
+#define COL_PIN_O6 158
+#define COL_PIN_O7 157
+
+#define SKE_KPD_MAX_ROWS 8
+#define SKE_KPD_MAX_COLS 8
+
+static int ske_kp_rows[] = {
+ ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3,
+ ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7,
+};
+
+/*
+ * ske_set_gpio_row: request and set gpio rows
+ */
+static int ske_set_gpio_row(int gpio)
+{
+ int ret;
+
+ ret = gpio_request(gpio, "ske-kp");
+ if (ret < 0) {
+ pr_err("ske_set_gpio_row: gpio request failed\n");
+ return ret;
+ }
+
+ ret = gpio_direction_output(gpio, 1);
+ if (ret < 0) {
+ pr_err("ske_set_gpio_row: gpio direction failed\n");
+ gpio_free(gpio);
+ }
+
+ return ret;
+}
+
+/*
+ * ske_kp_init - enable the gpio configuration
+ */
+static int ske_kp_init(void)
+{
+ int ret, i;
+
+ for (i = 0; i < SKE_KPD_MAX_ROWS; i++) {
+ ret = ske_set_gpio_row(ske_kp_rows[i]);
+ if (ret < 0) {
+ pr_err("ske_kp_init: failed init\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static struct ske_keypad_platform_data ske_keypad_board = {
+ .init = ske_kp_init,
+ .keymap_data = &mop500_keymap_data,
+ .no_autorepeat = true,
+ .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */
+ .kcol = SKE_KPD_MAX_COLS,
+ .debounce_ms = 40, /* in millisecs */
+};
+
+/*
+ * STMPE1601
+ */
+static struct stmpe_keypad_platform_data stmpe1601_keypad_data = {
+ .debounce_ms = 64,
+ .scan_count = 8,
+ .no_autorepeat = true,
+ .keymap_data = &mop500_keymap_data,
+};
+
+static struct stmpe_platform_data stmpe1601_data = {
+ .id = 1,
+ .blocks = STMPE_BLOCK_KEYPAD,
+ .irq_trigger = IRQF_TRIGGER_FALLING,
+ .irq_base = MOP500_STMPE1601_IRQ(0),
+ .keypad = &stmpe1601_keypad_data,
+ .autosleep = true,
+ .autosleep_timeout = 1024,
+};
+
+static struct i2c_board_info mop500_i2c0_devices_stuib[] = {
+ {
+ I2C_BOARD_INFO("stmpe1601", 0x40),
+ .irq = NOMADIK_GPIO_TO_IRQ(218),
+ .platform_data = &stmpe1601_data,
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+/*
+ * TC35893
+ */
+
+static const unsigned int uib_keymap[] = {
+ KEY(3, 1, KEY_END),
+ KEY(4, 1, KEY_POWER),
+ KEY(6, 4, KEY_VOLUMEDOWN),
+ KEY(4, 2, KEY_EMAIL),
+ KEY(3, 3, KEY_RIGHT),
+ KEY(2, 5, KEY_BACKSPACE),
+
+ KEY(6, 7, KEY_MENU),
+ KEY(5, 0, KEY_ENTER),
+ KEY(4, 3, KEY_0),
+ KEY(3, 4, KEY_DOT),
+ KEY(5, 2, KEY_UP),
+ KEY(3, 5, KEY_DOWN),
+
+ KEY(4, 5, KEY_SEND),
+ KEY(0, 5, KEY_BACK),
+ KEY(6, 2, KEY_VOLUMEUP),
+ KEY(1, 3, KEY_SPACE),
+ KEY(7, 6, KEY_LEFT),
+ KEY(5, 5, KEY_SEARCH),
+};
+
+static struct matrix_keymap_data uib_keymap_data = {
+ .keymap = uib_keymap,
+ .keymap_size = ARRAY_SIZE(uib_keymap),
+};
+
+static struct tc3589x_keypad_platform_data tc35893_data = {
+ .krow = TC_KPD_ROWS,
+ .kcol = TC_KPD_COLUMNS,
+ .debounce_period = TC_KPD_DEBOUNCE_PERIOD,
+ .settle_time = TC_KPD_SETTLE_TIME,
+ .irqtype = IRQF_TRIGGER_FALLING,
+ .enable_wakeup = true,
+ .keymap_data = &uib_keymap_data,
+ .no_autorepeat = true,
+};
+
+static struct tc3589x_platform_data tc3589x_keypad_data = {
+ .block = TC3589x_BLOCK_KEYPAD,
+ .keypad = &tc35893_data,
+ .irq_base = MOP500_EGPIO_IRQ_BASE,
+};
+
+static struct i2c_board_info mop500_i2c0_devices_uib[] = {
+ {
+ I2C_BOARD_INFO("tc3589x", 0x44),
+ .platform_data = &tc3589x_keypad_data,
+ .irq = NOMADIK_GPIO_TO_IRQ(218),
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+void mop500_keypad_init(void)
+{
+ db8500_add_ske_keypad(&ske_keypad_board);
+
+ i2c_register_board_info(0, mop500_i2c0_devices_stuib,
+ ARRAY_SIZE(mop500_i2c0_devices_stuib));
+
+ i2c_register_board_info(0, mop500_i2c0_devices_uib,
+ ARRAY_SIZE(mop500_i2c0_devices_uib));
+
+}
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index bac995665b58..4b996676594e 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -16,10 +16,24 @@
#include <mach/devices.h>
#include <mach/hardware.h>
+#include "devices-db8500.h"
#include "pins-db8500.h"
#include "board-mop500.h"
static pin_cfg_t mop500_sdi_pins[] = {
+ /* SDI0 (MicroSD slot) */
+ GPIO18_MC0_CMDDIR,
+ GPIO19_MC0_DAT0DIR,
+ GPIO20_MC0_DAT2DIR,
+ GPIO21_MC0_DAT31DIR,
+ GPIO22_MC0_FBCLK,
+ GPIO23_MC0_CLK,
+ GPIO24_MC0_CMD,
+ GPIO25_MC0_DAT0,
+ GPIO26_MC0_DAT1,
+ GPIO27_MC0_DAT2,
+ GPIO28_MC0_DAT3,
+
/* SDI4 (on-board eMMC) */
GPIO197_MC4_DAT3,
GPIO198_MC4_DAT2,
@@ -50,6 +64,55 @@ static pin_cfg_t mop500_sdi2_pins[] = {
};
/*
+ * SDI 0 (MicroSD slot)
+ */
+
+/* MMCIPOWER bits */
+#define MCI_DATA2DIREN (1 << 2)
+#define MCI_CMDDIREN (1 << 3)
+#define MCI_DATA0DIREN (1 << 4)
+#define MCI_DATA31DIREN (1 << 5)
+#define MCI_FBCLKEN (1 << 7)
+
+static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
+ unsigned char power_mode)
+{
+ if (power_mode == MMC_POWER_UP)
+ gpio_set_value_cansleep(GPIO_SDMMC_EN, 1);
+ else if (power_mode == MMC_POWER_OFF)
+ gpio_set_value_cansleep(GPIO_SDMMC_EN, 0);
+
+ return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
+ MCI_DATA2DIREN | MCI_DATA31DIREN;
+}
+
+static struct mmci_platform_data mop500_sdi0_data = {
+ .vdd_handler = mop500_sdi0_vdd_handler,
+ .ocr_mask = MMC_VDD_29_30,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = GPIO_SDMMC_CD,
+ .gpio_wp = -1,
+};
+
+void mop500_sdi_tc35892_init(void)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN");
+ if (!ret)
+ ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL,
+ "GPIO_SDMMC_1V8_3V_SEL");
+ if (ret)
+ return;
+
+ gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1);
+ gpio_direction_output(GPIO_SDMMC_EN, 0);
+
+ db8500_add_sdi0(&mop500_sdi0_data);
+}
+
+/*
* SDI 2 (POP eMMC, not on DB8500ed)
*/
@@ -74,18 +137,24 @@ static struct mmci_platform_data mop500_sdi4_data = {
.gpio_wp = -1,
};
-void mop500_sdi_init(void)
+void __init mop500_sdi_init(void)
{
nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins));
- u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data;
- u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data;
+ /*
+ * sdi0 will finally be added when the TC35892 initializes and calls
+ * mop500_sdi_tc35892_init() above.
+ */
+ /* PoP:ed eMMC */
if (!cpu_is_u8500ed()) {
nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins));
- amba_device_register(&u8500_sdi2_device, &iomem_resource);
+ /* POP eMMC on v1.0 has problems with high speed */
+ if (!cpu_is_u8500v10())
+ mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
+ db8500_add_sdi2(&mop500_sdi2_data);
}
/* On-board eMMC */
- amba_device_register(&u8500_sdi4_device, &iomem_resource);
+ db8500_add_sdi4(&mop500_sdi4_data);
}
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index cac83a694880..a1c9ea1a66df 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -13,25 +13,26 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ab8500.h>
-#include <linux/input/matrix_keypad.h>
+#include <linux/mfd/tc3589x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <plat/pincfg.h>
#include <plat/i2c.h>
-#include <plat/ske.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
#include <mach/irqs.h>
+#include "devices-db8500.h"
#include "pins-db8500.h"
#include "board-mop500.h"
@@ -69,22 +70,12 @@ static pin_cfg_t mop500_pins[] = {
GPIO166_KP_O2,
GPIO167_KP_O1,
GPIO168_KP_O0,
-};
-static void ab4500_spi_cs_control(u32 command)
-{
- /* set the FRM signal, which is CS - TODO */
-}
+ /* GPIO_EXP_INT */
+ GPIO217_GPIO,
-struct pl022_config_chip ab4500_chip_info = {
- .com_mode = INTERRUPT_TRANSFER,
- .iface = SSP_INTERFACE_MOTOROLA_SPI,
- /* we can act as master only */
- .hierarchy = SSP_MASTER,
- .slave_tx_disable = 0,
- .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
- .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
- .cs_control = ab4500_spi_cs_control,
+ /* STMPE1601 IRQ */
+ GPIO218_GPIO | PIN_INPUT_PULLUP,
};
static struct ab8500_platform_data ab8500_platdata = {
@@ -93,9 +84,9 @@ static struct ab8500_platform_data ab8500_platdata = {
static struct resource ab8500_resources[] = {
[0] = {
- .start = IRQ_AB8500,
- .end = IRQ_AB8500,
- .flags = IORESOURCE_IRQ
+ .start = IRQ_DB8500_AB8500,
+ .end = IRQ_DB8500_AB8500,
+ .flags = IORESOURCE_IRQ
}
};
@@ -109,19 +100,6 @@ struct platform_device ab8500_device = {
.resource = ab8500_resources,
};
-static struct spi_board_info ab8500_spi_devices[] = {
- {
- .modalias = "ab8500-spi",
- .controller_data = &ab4500_chip_info,
- .platform_data = &ab8500_platdata,
- .max_speed_hz = 12000000,
- .bus_num = 0,
- .chip_select = 0,
- .mode = SPI_MODE_3,
- .irq = IRQ_DB8500_AB8500,
- },
-};
-
static struct pl022_ssp_controller ssp0_platform_data = {
.bus_id = 0,
/* pl022 not yet supports dma */
@@ -132,6 +110,34 @@ static struct pl022_ssp_controller ssp0_platform_data = {
.num_chipselect = 5,
};
+/*
+ * TC35892
+ */
+
+static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
+{
+ mop500_sdi_tc35892_init();
+}
+
+static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
+ .gpio_base = MOP500_EGPIO(0),
+ .setup = mop500_tc35892_init,
+};
+
+static struct tc3589x_platform_data mop500_tc35892_data = {
+ .block = TC3589x_BLOCK_GPIO,
+ .gpio = &mop500_tc35892_gpio_data,
+ .irq_base = MOP500_EGPIO_IRQ_BASE,
+};
+
+static struct i2c_board_info mop500_i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("tc3589x", 0x42),
+ .irq = NOMADIK_GPIO_TO_IRQ(217),
+ .platform_data = &mop500_tc35892_data,
+ },
+};
+
#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
static struct nmk_i2c_controller u8500_i2c##id##_data = { \
/* \
@@ -161,159 +167,49 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
-static struct amba_device *amba_devs[] __initdata = {
- &ux500_uart0_device,
- &ux500_uart1_device,
- &ux500_uart2_device,
- &u8500_ssp0_device,
-};
-
-static const unsigned int ux500_keymap[] = {
- KEY(2, 5, KEY_END),
- KEY(4, 1, KEY_POWER),
- KEY(3, 5, KEY_VOLUMEDOWN),
- KEY(1, 3, KEY_3),
- KEY(5, 2, KEY_RIGHT),
- KEY(5, 0, KEY_9),
-
- KEY(0, 5, KEY_MENU),
- KEY(7, 6, KEY_ENTER),
- KEY(4, 5, KEY_0),
- KEY(6, 7, KEY_2),
- KEY(3, 4, KEY_UP),
- KEY(3, 3, KEY_DOWN),
-
- KEY(6, 4, KEY_SEND),
- KEY(6, 2, KEY_BACK),
- KEY(4, 2, KEY_VOLUMEUP),
- KEY(5, 5, KEY_1),
- KEY(4, 3, KEY_LEFT),
- KEY(3, 2, KEY_7),
-};
-
-static const struct matrix_keymap_data ux500_keymap_data = {
- .keymap = ux500_keymap,
- .keymap_size = ARRAY_SIZE(ux500_keymap),
-};
+static void __init mop500_i2c_init(void)
+{
+ db8500_add_i2c0(&u8500_i2c0_data);
+ db8500_add_i2c1(&u8500_i2c1_data);
+ db8500_add_i2c2(&u8500_i2c2_data);
+ db8500_add_i2c3(&u8500_i2c3_data);
+}
-/*
- * Nomadik SKE keypad
- */
-#define ROW_PIN_I0 164
-#define ROW_PIN_I1 163
-#define ROW_PIN_I2 162
-#define ROW_PIN_I3 161
-#define ROW_PIN_I4 156
-#define ROW_PIN_I5 155
-#define ROW_PIN_I6 154
-#define ROW_PIN_I7 153
-#define COL_PIN_O0 168
-#define COL_PIN_O1 167
-#define COL_PIN_O2 166
-#define COL_PIN_O3 165
-#define COL_PIN_O4 160
-#define COL_PIN_O5 159
-#define COL_PIN_O6 158
-#define COL_PIN_O7 157
-
-#define SKE_KPD_MAX_ROWS 8
-#define SKE_KPD_MAX_COLS 8
-
-static int ske_kp_rows[] = {
- ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3,
- ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7,
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
};
-/*
- * ske_set_gpio_row: request and set gpio rows
- */
-static int ske_set_gpio_row(int gpio)
+static void __init mop500_spi_init(void)
{
- int ret;
-
- ret = gpio_request(gpio, "ske-kp");
- if (ret < 0) {
- pr_err("ske_set_gpio_row: gpio request failed\n");
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 1);
- if (ret < 0) {
- pr_err("ske_set_gpio_row: gpio direction failed\n");
- gpio_free(gpio);
- }
-
- return ret;
+ db8500_add_ssp0(&ssp0_platform_data);
}
-/*
- * ske_kp_init - enable the gpio configuration
- */
-static int ske_kp_init(void)
+static void __init mop500_uart_init(void)
{
- int ret, i;
-
- for (i = 0; i < SKE_KPD_MAX_ROWS; i++) {
- ret = ske_set_gpio_row(ske_kp_rows[i]);
- if (ret < 0) {
- pr_err("ske_kp_init: failed init\n");
- return ret;
- }
- }
-
- return 0;
+ db8500_add_uart0();
+ db8500_add_uart1();
+ db8500_add_uart2();
}
-static struct ske_keypad_platform_data ske_keypad_board = {
- .init = ske_kp_init,
- .keymap_data = &ux500_keymap_data,
- .no_autorepeat = true,
- .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */
- .kcol = SKE_KPD_MAX_COLS,
- .debounce_ms = 40, /* in millsecs */
-};
-
-
-
-/* add any platform devices here - TODO */
-static struct platform_device *platform_devs[] __initdata = {
- &u8500_i2c0_device,
- &ux500_i2c1_device,
- &ux500_i2c2_device,
- &ux500_i2c3_device,
- &ux500_ske_keypad_device,
-};
-
static void __init u8500_init_machine(void)
{
- int i;
-
u8500_init_devices();
nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins));
- u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
- ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
- ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
- ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;
- ux500_ske_keypad_device.dev.platform_data = &ske_keypad_board;
-
- u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;
-
- /* Register the active AMBA devices on this board */
- for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
- amba_device_register(amba_devs[i], &iomem_resource);
-
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+ mop500_i2c_init();
mop500_sdi_init();
+ mop500_spi_init();
+ mop500_uart_init();
+
+ mop500_keypad_init();
+
+ platform_device_register(&ab8500_device);
- /* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */
- if (cpu_is_u8500ed() || cpu_is_u8500v10())
- spi_register_board_info(ab8500_spi_devices,
- ARRAY_SIZE(ab8500_spi_devices));
- else /* If HW is v.1.1 or later use I2C to access AB8500 */
- platform_device_register(&ab8500_device);
+ i2c_register_board_info(0, mop500_i2c0_devices,
+ ARRAY_SIZE(mop500_i2c0_devices));
}
MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index 2d240322fa6f..3104ae2a02c2 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -7,6 +7,15 @@
#ifndef __BOARD_MOP500_H
#define __BOARD_MOP500_H
+#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x))
+
+/* GPIOs on the TC35892 expander */
+#define GPIO_SDMMC_CD MOP500_EGPIO(3)
+#define GPIO_SDMMC_EN MOP500_EGPIO(17)
+#define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18)
+
extern void mop500_sdi_init(void);
+extern void mop500_sdi_tc35892_init(void);
+extern void mop500_keypad_init(void);
#endif
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c
new file mode 100644
index 000000000000..54712acc0394
--- /dev/null
+++ b/arch/arm/mach-ux500/board-u5500-sdi.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Hanumath Prasad <ulf.hansson@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/amba/mmci.h>
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+
+#include <plat/pincfg.h>
+#include <mach/db5500-regs.h>
+#include <plat/ste_dma40.h>
+
+#include "pins-db5500.h"
+#include "devices-db5500.h"
+#include "ste-dma40-db5500.h"
+
+static pin_cfg_t u5500_sdi_pins[] = {
+ /* SDI0 (POP eMMC) */
+ GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW,
+};
+
+static struct mmci_platform_data u5500_sdi0_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .f_max = 50000000,
+ .capabilities = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+};
+
+void __init u5500_sdi_init(void)
+{
+ nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
+
+ db5500_add_sdi0(&u5500_sdi0_data);
+}
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index 1ca094a45e71..39d370c1f3b4 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/gpio.h>
+#include <linux/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -17,20 +18,24 @@
#include <mach/devices.h>
#include <mach/setup.h>
-static struct amba_device *amba_board_devs[] __initdata = {
- &ux500_uart0_device,
- &ux500_uart1_device,
- &ux500_uart2_device,
-};
+#include "devices-db5500.h"
+
+static void __init u5500_uart_init(void)
+{
+ db5500_add_uart0();
+ db5500_add_uart1();
+ db5500_add_uart2();
+}
static void __init u5500_init_machine(void)
{
u5500_init_devices();
- amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs));
+ u5500_sdi_init();
+ u5500_uart_init();
}
-MACHINE_START(U8500, "ST-Ericsson U5500 Platform")
+MACHINE_START(U5500, "ST-Ericsson U5500 Platform")
.boot_params = 0x00000100,
.map_io = u5500_map_io,
.init_irq = ux500_init_irq,
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 1675047daf20..ccff2dae167f 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -13,13 +13,18 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
-
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <plat/mtu.h>
#include <mach/hardware.h>
#include "clock.h"
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h> /* for copy_from_user */
+static LIST_HEAD(clk_list);
+#endif
+
#define PRCC_PCKEN 0x00
#define PRCC_PCKDIS 0x04
#define PRCC_KCKEN 0x08
@@ -133,7 +138,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
{
void __iomem *addr = __io_address(UX500_PRCMU_BASE)
+ PRCM_TCR;
- u32 tcr = readl(addr);
+ u32 tcr;
int mtu = (int) clk->data;
/*
* One of these is selected eventually
@@ -144,6 +149,14 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
unsigned long mturate;
unsigned long retclk;
+ /*
+ * On a startup, always conifgure the TCR to the doze mode;
+ * bootloaders do it for us. Do this in the kernel too.
+ */
+ writel(PRCM_TCR_DOZE_MODE, addr);
+
+ tcr = readl(addr);
+
/* Get the rate from the parent as a default */
if (clk->parent_periph)
mturate = clk_get_rate(clk->parent_periph);
@@ -153,45 +166,6 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
/* We need to be connected SOMEWHERE */
BUG();
- /*
- * Are we in doze mode?
- * In this mode the parent peripheral or the fixed 32768 Hz
- * clock is fed into the block.
- */
- if (!(tcr & PRCM_TCR_DOZE_MODE)) {
- /*
- * Here we're using the clock input from the APE ULP
- * clock domain. But first: are the timers stopped?
- */
- if (tcr & PRCM_TCR_STOPPED) {
- clk32k = 0;
- mturate = 0;
- } else {
- /* Else default mode: 0 and 2.4 MHz */
- clk32k = 0;
- if (cpu_is_u5500())
- /* DB5500 divides by 8 */
- mturate /= 8;
- else if (cpu_is_u8500ed()) {
- /*
- * This clocking setting must not be used
- * in the ED chip, it is simply not
- * connected anywhere!
- */
- mturate = 0;
- BUG();
- } else
- /*
- * In this mode the ulp38m4 clock is divided
- * by a factor 16, on the DB8500 typically
- * 38400000 / 16 ~ 2.4 MHz.
- * TODO: Replace the constant with a reference
- * to the ULP source once this is modeled.
- */
- mturate = 38400000 / 16;
- }
- }
-
/* Return the clock selected for this MTU */
if (tcr & (1 << mtu))
retclk = clk32k;
@@ -317,6 +291,7 @@ static struct clkops clk_prcc_ops = {
};
static struct clk clk_32khz = {
+ .name = "clk_32khz",
.rate = 32000,
};
@@ -366,94 +341,96 @@ static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
*/
/* Peripheral Cluster #1 */
-static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
-static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
-static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL);
-static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL);
-static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
+static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL);
+static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL);
+static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk);
-static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk);
-static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
-static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
-static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
-static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
+static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk);
+static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
+static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
/* Peripheral Cluster #2 */
static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL);
-static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL);
-static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL);
-static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL);
-static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk);
-static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk);
static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL);
-static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL);
-static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL);
-static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk);
static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL);
-static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL);
-static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL);
-static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL);
-static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk);
-static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL);
+static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk);
static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL);
-static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL);
-static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL);
-static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk);
/* Peripheral Cluster #3 */
-static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
-static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
-static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
-static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
-static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk);
-static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk);
-static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk);
-static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk);
-static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
+static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
+static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
+static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
+static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
/* Peripheral Cluster #4 is in the always on domain */
/* Peripheral Cluster #5 */
-static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
-static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk);
-static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL);
+static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
+static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL);
/* Peripheral Cluster #6 */
/* MTU ID in data */
static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1);
static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0);
-static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL);
-static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL);
-static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL);
-static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk);
-static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL);
-static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL);
-static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL);
-static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL);
-static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk);
-static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk);
+static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL);
+static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL);
+static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL);
+static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk);
+static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL);
+static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL);
+static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL);
+static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL);
+static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk);
/* Peripheral Cluster #7 */
-static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL);
+static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL);
/* MTU ID in data */
static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1);
static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0);
-static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL);
-static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL);
+static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL);
+static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL);
-static struct clk clk_dummy_apb_pclk;
+static struct clk clk_dummy_apb_pclk = {
+ .name = "apb_pclk",
+};
static struct clk_lookup u8500_common_clks[] = {
CLK(dummy_apb_pclk, NULL, "apb_pclk"),
@@ -554,7 +531,7 @@ static struct clk_lookup u8500_ed_clks[] = {
static struct clk_lookup u8500_v1_clks[] = {
/* Peripheral Cluster #1 */
- CLK(i2c4, "nmk-i2c.4", NULL),
+ CLK(i2c4, "nmk-i2c.4", NULL),
CLK(spi3_v1, "spi3", NULL),
CLK(msp1_v1, "msp1", NULL),
@@ -599,6 +576,183 @@ static struct clk_lookup u8500_v1_clks[] = {
CLK(uiccclk, "uicc", NULL),
};
+#ifdef CONFIG_DEBUG_FS
+/*
+ * debugfs support to trace clock tree hierarchy and attributes with
+ * powerdebug
+ */
+static struct dentry *clk_debugfs_root;
+
+void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num)
+{
+ while (num--) {
+ /* Check that the clock has not been already registered */
+ if (!(cl->clk->list.prev != cl->clk->list.next))
+ list_add_tail(&cl->clk->list, &clk_list);
+
+ cl++;
+ }
+}
+
+static ssize_t usecount_dbg_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
+{
+ struct clk *clk = file->f_dentry->d_inode->i_private;
+ char cusecount[128];
+ unsigned int len;
+
+ len = sprintf(cusecount, "%u\n", clk->enabled);
+ return simple_read_from_buffer(buf, size, off, cusecount, len);
+}
+
+static ssize_t rate_dbg_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
+{
+ struct clk *clk = file->f_dentry->d_inode->i_private;
+ char crate[128];
+ unsigned int rate;
+ unsigned int len;
+
+ rate = clk_get_rate(clk);
+ len = sprintf(crate, "%u\n", rate);
+ return simple_read_from_buffer(buf, size, off, crate, len);
+}
+
+static const struct file_operations usecount_fops = {
+ .read = usecount_dbg_read,
+};
+
+static const struct file_operations set_rate_fops = {
+ .read = rate_dbg_read,
+};
+
+static struct dentry *clk_debugfs_register_dir(struct clk *c,
+ struct dentry *p_dentry)
+{
+ struct dentry *d, *clk_d, *child, *child_tmp;
+ char s[255];
+ char *p = s;
+
+ if (c->name == NULL)
+ p += sprintf(p, "BUG");
+ else
+ p += sprintf(p, "%s", c->name);
+
+ clk_d = debugfs_create_dir(s, p_dentry);
+ if (!clk_d)
+ return NULL;
+
+ d = debugfs_create_file("usecount", S_IRUGO,
+ clk_d, c, &usecount_fops);
+ if (!d)
+ goto err_out;
+ d = debugfs_create_file("rate", S_IRUGO,
+ clk_d, c, &set_rate_fops);
+ if (!d)
+ goto err_out;
+ /*
+ * TODO : not currently available in ux500
+ * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags);
+ * if (!d)
+ * goto err_out;
+ */
+
+ return clk_d;
+
+err_out:
+ d = clk_d;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(clk_d);
+ return NULL;
+}
+
+static void clk_debugfs_remove_dir(struct dentry *cdentry)
+{
+ struct dentry *d, *child, *child_tmp;
+
+ d = cdentry;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(cdentry);
+ return ;
+}
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ struct clk *pa = c->parent_periph;
+ struct clk *bpa = c->parent_cluster;
+
+ if (!(bpa && !pa)) {
+ c->dent = clk_debugfs_register_dir(c,
+ pa ? pa->dent : clk_debugfs_root);
+ if (!c->dent)
+ return -ENOMEM;
+ }
+
+ if (bpa) {
+ c->dent_bus = clk_debugfs_register_dir(c,
+ bpa->dent_bus ? bpa->dent_bus : bpa->dent);
+ if ((!c->dent_bus) && (c->dent)) {
+ clk_debugfs_remove_dir(c->dent);
+ c->dent = NULL;
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent_periph;
+ struct clk *bpa = c->parent_cluster;
+
+ if (pa && (!pa->dent && !pa->dent_bus)) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (bpa && (!bpa->dent && !bpa->dent_bus)) {
+ err = clk_debugfs_register(bpa);
+ if (err)
+ return err;
+ }
+
+ if ((!c->dent) && (!c->dent_bus)) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clk_list, list) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+
+late_initcall(clk_debugfs_init);
+#endif /* defined(CONFIG_DEBUG_FS) */
+
int __init clk_init(void)
{
if (cpu_is_u8500ed()) {
@@ -609,7 +763,8 @@ int __init clk_init(void)
/* Clock tree for U5500 not implemented yet */
clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
- clk_per6clk.rate = 26000000;
+ clk_uartclk.rate = 36360000;
+ clk_sdmmcclk.rate = 99900000;
}
clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
@@ -618,5 +773,12 @@ int __init clk_init(void)
else
clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+#ifdef CONFIG_DEBUG_FS
+ clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
+ if (cpu_is_u8500ed())
+ clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
+ else
+ clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+#endif
return 0;
}
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
index a05802501527..074490705229 100644
--- a/arch/arm/mach-ux500/clock.h
+++ b/arch/arm/mach-ux500/clock.h
@@ -90,6 +90,10 @@ struct clk {
struct clk *parent_cluster;
struct clk *parent_periph;
+#if defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+ struct dentry *dent_bus; /* For visible tree hierarchy */
+#endif
};
#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
index 2f87075e9d6f..acc841e48de4 100644
--- a/arch/arm/mach-ux500/cpu-db5500.c
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -8,14 +8,19 @@
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/io.h>
+#include <linux/irq.h>
#include <asm/mach/map.h>
+#include <plat/gpio.h>
+
#include <mach/hardware.h>
#include <mach/devices.h>
#include <mach/setup.h>
#include <mach/irqs.h>
+#include "devices-db5500.h"
+
static struct map_desc u5500_io_desc[] __initdata = {
__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
@@ -110,19 +115,32 @@ static struct platform_device mbox2_device = {
};
static struct platform_device *u5500_platform_devs[] __initdata = {
- &u5500_gpio_devs[0],
- &u5500_gpio_devs[1],
- &u5500_gpio_devs[2],
- &u5500_gpio_devs[3],
- &u5500_gpio_devs[4],
- &u5500_gpio_devs[5],
- &u5500_gpio_devs[6],
- &u5500_gpio_devs[7],
&mbox0_device,
&mbox1_device,
&mbox2_device,
};
+static resource_size_t __initdata db5500_gpio_base[] = {
+ U5500_GPIOBANK0_BASE,
+ U5500_GPIOBANK1_BASE,
+ U5500_GPIOBANK2_BASE,
+ U5500_GPIOBANK3_BASE,
+ U5500_GPIOBANK4_BASE,
+ U5500_GPIOBANK5_BASE,
+ U5500_GPIOBANK6_BASE,
+ U5500_GPIOBANK7_BASE,
+};
+
+static void __init db5500_add_gpios(void)
+{
+ struct nmk_gpio_platform_data pdata = {
+ /* No custom data yet */
+ };
+
+ dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base),
+ IRQ_DB5500_GPIO0, &pdata);
+}
+
void __init u5500_map_io(void)
{
ux500_map_io();
@@ -132,7 +150,9 @@ void __init u5500_map_io(void)
void __init u5500_init_devices(void)
{
- ux500_init_devices();
+ db5500_add_gpios();
+ db5500_dma_init();
+ db5500_add_rtc();
platform_add_devices(u5500_platform_devs,
ARRAY_SIZE(u5500_platform_devs));
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 4acab7544b3c..c0f34a404c53 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -22,23 +22,15 @@
#include <mach/setup.h>
#include <mach/devices.h>
+#include "devices-db8500.h"
+
static struct platform_device *platform_devs[] __initdata = {
- &u8500_gpio_devs[0],
- &u8500_gpio_devs[1],
- &u8500_gpio_devs[2],
- &u8500_gpio_devs[3],
- &u8500_gpio_devs[4],
- &u8500_gpio_devs[5],
- &u8500_gpio_devs[6],
- &u8500_gpio_devs[7],
- &u8500_gpio_devs[8],
&u8500_dma40_device,
};
/* minimum static i/o mapping required to boot U8500 platforms */
static struct map_desc u8500_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
- __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
@@ -46,13 +38,18 @@ static struct map_desc u8500_io_desc[] __initdata = {
__MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
};
-static struct map_desc u8500ed_io_desc[] __initdata = {
+static struct map_desc u8500_ed_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K),
__IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K),
};
-static struct map_desc u8500v1_io_desc[] __initdata = {
+static struct map_desc u8500_v1_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K),
+};
+
+static struct map_desc u8500_v2_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
};
/*
@@ -125,14 +122,38 @@ void __init u8500_map_io(void)
iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
if (cpu_is_u8500ed())
- iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc));
- else
- iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc));
+ iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc));
+ else if (cpu_is_u8500v1())
+ iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
+ else if (cpu_is_u8500v2())
+ iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
/* Read out the ASIC ID as early as we can */
get_db8500_asic_id();
}
+static resource_size_t __initdata db8500_gpio_base[] = {
+ U8500_GPIOBANK0_BASE,
+ U8500_GPIOBANK1_BASE,
+ U8500_GPIOBANK2_BASE,
+ U8500_GPIOBANK3_BASE,
+ U8500_GPIOBANK4_BASE,
+ U8500_GPIOBANK5_BASE,
+ U8500_GPIOBANK6_BASE,
+ U8500_GPIOBANK7_BASE,
+ U8500_GPIOBANK8_BASE,
+};
+
+static void __init db8500_add_gpios(void)
+{
+ struct nmk_gpio_platform_data pdata = {
+ /* No custom data yet */
+ };
+
+ dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
+ IRQ_DB8500_GPIO0, &pdata);
+}
+
/*
* This function is called from the board init
*/
@@ -152,12 +173,13 @@ void __init u8500_init_devices(void)
else
pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");
- ux500_init_devices();
-
if (cpu_is_u8500ed())
dma40_u8500ed_fixup();
- /* Register the platform devices */
+ db8500_add_rtc();
+ db8500_add_gpios();
+
+ platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
return ;
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 608a1372b172..5730409c0f7d 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -6,7 +6,6 @@
*/
#include <linux/platform_device.h>
-#include <linux/amba/bus.h>
#include <linux/io.h>
#include <linux/clk.h>
@@ -20,6 +19,7 @@
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
+#include <mach/prcmu.h>
#include "clock.h"
@@ -45,29 +45,22 @@ static struct map_desc ux500_io_desc[] __initdata = {
__IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
};
-static struct amba_device *ux500_amba_devs[] __initdata = {
- &ux500_pl031_device,
-};
-
void __init ux500_map_io(void)
{
iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
}
-void __init ux500_init_devices(void)
-{
- amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs));
-}
-
void __init ux500_init_irq(void)
{
- gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
- gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+ gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
+ __io_address(UX500_GIC_CPU_BASE));
/*
* Init clocks here so that they are available for system timer
* initialization.
*/
+ if (cpu_is_u8500())
+ prcmu_early_init();
clk_init();
}
diff --git a/arch/arm/mach-ux500/cpufreq.c b/arch/arm/mach-ux500/cpufreq.c
new file mode 100644
index 000000000000..5c5b747f134d
--- /dev/null
+++ b/arch/arm/mach-ux500/cpufreq.c
@@ -0,0 +1,211 @@
+/*
+ * CPU frequency scaling for u8500
+ * Inspired by linux/arch/arm/mach-davinci/cpufreq.c
+ *
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Author: Martin Persson <martin.persson@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <mach/prcmu.h>
+#include <mach/prcmu-defs.h>
+
+#define DRIVER_NAME "cpufreq-u8500"
+#define CPUFREQ_NAME "u8500"
+
+static struct device *dev;
+
+static struct cpufreq_frequency_table freq_table[] = {
+ [0] = {
+ .index = 0,
+ .frequency = 200000,
+ },
+ [1] = {
+ .index = 1,
+ .frequency = 300000,
+ },
+ [2] = {
+ .index = 2,
+ .frequency = 600000,
+ },
+ [3] = {
+ /* Used for CPU_OPP_MAX, if available */
+ .index = 3,
+ .frequency = CPUFREQ_TABLE_END,
+ },
+ [4] = {
+ .index = 4,
+ .frequency = CPUFREQ_TABLE_END,
+ },
+};
+
+static enum prcmu_cpu_opp index2opp[] = {
+ CPU_OPP_EXT_CLK,
+ CPU_OPP_50,
+ CPU_OPP_100,
+ CPU_OPP_MAX
+};
+
+static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static int u8500_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned int index;
+ int ret = 0;
+
+ /*
+ * Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum.
+ */
+ if (target_freq < policy->cpuinfo.min_freq)
+ target_freq = policy->cpuinfo.min_freq;
+ if (target_freq > policy->cpuinfo.max_freq)
+ target_freq = policy->cpuinfo.max_freq;
+
+ ret = cpufreq_frequency_table_target(policy, freq_table,
+ target_freq, relation, &index);
+ if (ret < 0) {
+ dev_err(dev, "Could not look up next frequency\n");
+ return ret;
+ }
+
+ freqs.old = policy->cur;
+ freqs.new = freq_table[index].frequency;
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new) {
+ dev_dbg(dev, "Current and target frequencies are equal\n");
+ return 0;
+ }
+
+ dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ ret = prcmu_set_cpu_opp(index2opp[index]);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set OPP level\n");
+ return ret;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static unsigned int u8500_cpufreq_getspeed(unsigned int cpu)
+{
+ int i;
+
+ for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++)
+ ;
+ return freq_table[i].frequency;
+}
+
+static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy)
+{
+ int res;
+
+ BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table));
+
+ if (cpu_is_u8500v2()) {
+ freq_table[1].frequency = 400000;
+ freq_table[2].frequency = 800000;
+ if (prcmu_has_arm_maxopp())
+ freq_table[3].frequency = 1000000;
+ }
+
+ /* get policy fields based on the table */
+ res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!res)
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+ else {
+ dev_err(dev, "u8500-cpufreq : Failed to read policy table\n");
+ return res;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = u8500_cpufreq_getspeed(policy->cpu);
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ /*
+ * FIXME : Need to take time measurement across the target()
+ * function with no/some/all drivers in the notification
+ * list.
+ */
+ policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */
+
+ /* policy sharing between dual CPUs */
+ cpumask_copy(policy->cpus, &cpu_present_map);
+
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+
+ return res;
+}
+
+static struct freq_attr *u8500_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+static int u8500_cpu_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static struct cpufreq_driver u8500_driver = {
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_STICKY,
+ .verify = u8500_cpufreq_verify_speed,
+ .target = u8500_cpufreq_target,
+ .get = u8500_cpufreq_getspeed,
+ .init = u8500_cpu_init,
+ .exit = u8500_cpu_exit,
+ .name = CPUFREQ_NAME,
+ .attr = u8500_cpufreq_attr,
+};
+
+static int __init u8500_cpufreq_probe(struct platform_device *pdev)
+{
+ dev = &pdev->dev;
+ return cpufreq_register_driver(&u8500_driver);
+}
+
+static int __exit u8500_cpufreq_remove(struct platform_device *pdev)
+{
+ return cpufreq_unregister_driver(&u8500_driver);
+}
+
+static struct platform_driver u8500_cpufreq_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(u8500_cpufreq_remove),
+};
+
+static int __init u8500_cpufreq_init(void)
+{
+ return platform_driver_probe(&u8500_cpufreq_driver,
+ &u8500_cpufreq_probe);
+}
+
+device_initcall(u8500_cpufreq_init);
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
new file mode 100644
index 000000000000..fe69f5fac1bb
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+#include <plat/gpio.h>
+
+#include <mach/hardware.h>
+
+#include "devices-common.h"
+
+struct amba_device *
+dbx500_add_amba_device(const char *name, resource_size_t base,
+ int irq, void *pdata, unsigned int periphid)
+{
+ struct amba_device *dev;
+ int ret;
+
+ dev = kzalloc(sizeof *dev, GFP_KERNEL);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->dev.init_name = name;
+
+ dev->res.start = base;
+ dev->res.end = base + SZ_4K - 1;
+ dev->res.flags = IORESOURCE_MEM;
+
+ dev->dma_mask = DMA_BIT_MASK(32);
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ dev->irq[0] = irq;
+ dev->irq[1] = NO_IRQ;
+
+ dev->periphid = periphid;
+
+ dev->dev.platform_data = pdata;
+
+ ret = amba_device_register(dev, &iomem_resource);
+ if (ret) {
+ kfree(dev);
+ return ERR_PTR(ret);
+ }
+
+ return dev;
+}
+
+static struct platform_device *
+dbx500_add_platform_device(const char *name, int id, void *pdata,
+ struct resource *res, int resnum)
+{
+ struct platform_device *dev;
+ int ret;
+
+ dev = platform_device_alloc(name, id);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+
+ ret = platform_device_add_resources(dev, res, resnum);
+ if (ret)
+ goto out_free;
+
+ dev->dev.platform_data = pdata;
+
+ ret = platform_device_add(dev);
+ if (ret)
+ goto out_free;
+
+ return dev;
+
+out_free:
+ platform_device_put(dev);
+ return ERR_PTR(ret);
+}
+
+struct platform_device *
+dbx500_add_platform_device_4k1irq(const char *name, int id,
+ resource_size_t base,
+ int irq, void *pdata)
+{
+ struct resource resources[] = {
+ [0] = {
+ .start = base,
+ .end = base + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ return dbx500_add_platform_device(name, id, pdata, resources,
+ ARRAY_SIZE(resources));
+}
+
+static struct platform_device *
+dbx500_add_gpio(int id, resource_size_t addr, int irq,
+ struct nmk_gpio_platform_data *pdata)
+{
+ struct resource resources[] = {
+ {
+ .start = addr,
+ .end = addr + 127,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ return platform_device_register_resndata(NULL, "gpio", id,
+ resources, ARRAY_SIZE(resources),
+ pdata, sizeof(*pdata));
+}
+
+void dbx500_add_gpios(resource_size_t *base, int num, int irq,
+ struct nmk_gpio_platform_data *pdata)
+{
+ int first = 0;
+ int i;
+
+ for (i = 0; i < num; i++, first += 32, irq++) {
+ pdata->first_gpio = first;
+ pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
+
+ dbx500_add_gpio(i, base[i], irq, pdata);
+ }
+}
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
new file mode 100644
index 000000000000..cbadc117d2db
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_COMMON_H
+#define __DEVICES_COMMON_H
+
+extern struct amba_device *
+dbx500_add_amba_device(const char *name, resource_size_t base,
+ int irq, void *pdata, unsigned int periphid);
+
+extern struct platform_device *
+dbx500_add_platform_device_4k1irq(const char *name, int id,
+ resource_size_t base,
+ int irq, void *pdata);
+
+struct spi_master_cntlr;
+
+static inline struct amba_device *
+dbx500_add_msp_spi(const char *name, resource_size_t base, int irq,
+ struct spi_master_cntlr *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+static inline struct amba_device *
+dbx500_add_spi(const char *name, resource_size_t base, int irq,
+ struct spi_master_cntlr *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+struct mmci_platform_data;
+
+static inline struct amba_device *
+dbx500_add_sdi(const char *name, resource_size_t base, int irq,
+ struct mmci_platform_data *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+static inline struct amba_device *
+dbx500_add_uart(const char *name, resource_size_t base, int irq)
+{
+ return dbx500_add_amba_device(name, base, irq, NULL, 0);
+}
+
+struct nmk_i2c_controller;
+
+static inline struct platform_device *
+dbx500_add_i2c(int id, resource_size_t base, int irq,
+ struct nmk_i2c_controller *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq,
+ pdata);
+}
+
+struct msp_i2s_platform_data;
+
+static inline struct platform_device *
+dbx500_add_msp_i2s(int id, resource_size_t base, int irq,
+ struct msp_i2s_platform_data *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq,
+ pdata);
+}
+
+static inline struct amba_device *
+dbx500_add_rtc(resource_size_t base, int irq)
+{
+ return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0);
+}
+
+struct nmk_gpio_platform_data;
+
+void dbx500_add_gpios(resource_size_t *base, int num, int irq,
+ struct nmk_gpio_platform_data *pdata);
+
+#endif
diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c
deleted file mode 100644
index 33e5b56bebb6..000000000000
--- a/arch/arm/mach-ux500/devices-db5500.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <mach/devices.h>
-
-static struct nmk_gpio_platform_data u5500_gpio_data[] = {
- GPIO_DATA("GPIO-0-31", 0),
- GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */
- GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */
- GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */
- GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */
- GPIO_DATA("GPIO-160-191", 160),
- GPIO_DATA("GPIO-192-223", 192),
- GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */
-};
-
-static struct resource u5500_gpio_resources[] = {
- GPIO_RESOURCE(0),
- GPIO_RESOURCE(1),
- GPIO_RESOURCE(2),
- GPIO_RESOURCE(3),
- GPIO_RESOURCE(4),
- GPIO_RESOURCE(5),
- GPIO_RESOURCE(6),
- GPIO_RESOURCE(7),
-};
-
-struct platform_device u5500_gpio_devs[] = {
- GPIO_DEVICE(0),
- GPIO_DEVICE(1),
- GPIO_DEVICE(2),
- GPIO_DEVICE(3),
- GPIO_DEVICE(4),
- GPIO_DEVICE(5),
- GPIO_DEVICE(6),
- GPIO_DEVICE(7),
-};
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h
new file mode 100644
index 000000000000..c8d7901c1f2d
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db5500.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_DB5500_H
+#define __DEVICES_DB5500_H
+
+#include "devices-common.h"
+
+#define db5500_add_i2c1(pdata) \
+ dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
+#define db5500_add_i2c2(pdata) \
+ dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
+#define db5500_add_i2c3(pdata) \
+ dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
+
+#define db5500_add_msp0_i2s(pdata) \
+ dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_i2s(pdata) \
+ dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_i2s(pdata) \
+ dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+
+#define db5500_add_msp0_spi(pdata) \
+ dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(pdata) \
+ dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(pdata) \
+ dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+
+#define db5500_add_rtc() \
+ dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC);
+
+#define db5500_add_sdi0(pdata) \
+ dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata)
+#define db5500_add_sdi1(pdata) \
+ dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata)
+#define db5500_add_sdi2(pdata) \
+ dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata)
+#define db5500_add_sdi3(pdata) \
+ dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata)
+#define db5500_add_sdi4(pdata) \
+ dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata)
+
+#define db5500_add_spi0(pdata) \
+ dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata)
+#define db5500_add_spi1(pdata) \
+ dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata)
+#define db5500_add_spi2(pdata) \
+ dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata)
+#define db5500_add_spi3(pdata) \
+ dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata)
+
+#define db5500_add_uart0() \
+ dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0)
+#define db5500_add_uart1() \
+ dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1)
+#define db5500_add_uart2() \
+ dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2)
+#define db5500_add_uart3() \
+ dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3)
+
+#endif
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 4a94be3304b9..23c695d54977 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -19,173 +19,6 @@
#include "ste-dma40-db8500.h"
-static struct nmk_gpio_platform_data u8500_gpio_data[] = {
- GPIO_DATA("GPIO-0-31", 0),
- GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */
- GPIO_DATA("GPIO-64-95", 64),
- GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */
- GPIO_DATA("GPIO-128-159", 128),
- GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */
- GPIO_DATA("GPIO-192-223", 192),
- GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */
- GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */
-};
-
-static struct resource u8500_gpio_resources[] = {
- GPIO_RESOURCE(0),
- GPIO_RESOURCE(1),
- GPIO_RESOURCE(2),
- GPIO_RESOURCE(3),
- GPIO_RESOURCE(4),
- GPIO_RESOURCE(5),
- GPIO_RESOURCE(6),
- GPIO_RESOURCE(7),
- GPIO_RESOURCE(8),
-};
-
-struct platform_device u8500_gpio_devs[] = {
- GPIO_DEVICE(0),
- GPIO_DEVICE(1),
- GPIO_DEVICE(2),
- GPIO_DEVICE(3),
- GPIO_DEVICE(4),
- GPIO_DEVICE(5),
- GPIO_DEVICE(6),
- GPIO_DEVICE(7),
- GPIO_DEVICE(8),
-};
-
-struct amba_device u8500_ssp0_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "ssp0",
- },
- .res = {
- .start = U8500_SSP0_BASE,
- .end = U8500_SSP0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SSP0, NO_IRQ },
- /* ST-Ericsson modified id */
- .periphid = SSP_PER_ID,
-};
-
-static struct resource u8500_i2c0_resources[] = {
- [0] = {
- .start = U8500_I2C0_BASE,
- .end = U8500_I2C0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_DB8500_I2C0,
- .end = IRQ_DB8500_I2C0,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device u8500_i2c0_device = {
- .name = "nmk-i2c",
- .id = 0,
- .resource = u8500_i2c0_resources,
- .num_resources = ARRAY_SIZE(u8500_i2c0_resources),
-};
-
-static struct resource u8500_i2c4_resources[] = {
- [0] = {
- .start = U8500_I2C4_BASE,
- .end = U8500_I2C4_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_DB8500_I2C4,
- .end = IRQ_DB8500_I2C4,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device u8500_i2c4_device = {
- .name = "nmk-i2c",
- .id = 4,
- .resource = u8500_i2c4_resources,
- .num_resources = ARRAY_SIZE(u8500_i2c4_resources),
-};
-
-/*
- * SD/MMC
- */
-
-struct amba_device u8500_sdi0_device = {
- .dev = {
- .init_name = "sdi0",
- },
- .res = {
- .start = U8500_SDI0_BASE,
- .end = U8500_SDI0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC0, NO_IRQ},
-};
-
-struct amba_device u8500_sdi1_device = {
- .dev = {
- .init_name = "sdi1",
- },
- .res = {
- .start = U8500_SDI1_BASE,
- .end = U8500_SDI1_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC1, NO_IRQ},
-};
-
-struct amba_device u8500_sdi2_device = {
- .dev = {
- .init_name = "sdi2",
- },
- .res = {
- .start = U8500_SDI2_BASE,
- .end = U8500_SDI2_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC2, NO_IRQ},
-};
-
-struct amba_device u8500_sdi3_device = {
- .dev = {
- .init_name = "sdi3",
- },
- .res = {
- .start = U8500_SDI3_BASE,
- .end = U8500_SDI3_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC3, NO_IRQ},
-};
-
-struct amba_device u8500_sdi4_device = {
- .dev = {
- .init_name = "sdi4",
- },
- .res = {
- .start = U8500_SDI4_BASE,
- .end = U8500_SDI4_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC4, NO_IRQ},
-};
-
-struct amba_device u8500_sdi5_device = {
- .dev = {
- .init_name = "sdi5",
- },
- .res = {
- .start = U8500_SDI5_BASE,
- .end = U8500_SDI5_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DB8500_SDMMC5, NO_IRQ},
-};
-
static struct resource dma40_resources[] = {
[0] = {
.start = U8500_DMA_BASE,
@@ -295,7 +128,7 @@ struct resource keypad_resources[] = {
},
};
-struct platform_device ux500_ske_keypad_device = {
+struct platform_device u8500_ske_keypad_device = {
.name = "nmk-ske-keypad",
.id = -1,
.num_resources = ARRAY_SIZE(keypad_resources),
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h
new file mode 100644
index 000000000000..3a770c756979
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db8500.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_DB8500_H
+#define __DEVICES_DB8500_H
+
+#include "devices-common.h"
+
+struct ske_keypad_platform_data;
+struct pl022_ssp_controller;
+
+static inline struct platform_device *
+db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1,
+ U8500_SKE_BASE,
+ IRQ_DB8500_KB, pdata);
+}
+
+static inline struct amba_device *
+db8500_add_ssp(const char *name, resource_size_t base, int irq,
+ struct pl022_ssp_controller *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, SSP_PER_ID);
+}
+
+
+#define db8500_add_i2c0(pdata) \
+ dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
+#define db8500_add_i2c1(pdata) \
+ dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
+#define db8500_add_i2c2(pdata) \
+ dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
+#define db8500_add_i2c3(pdata) \
+ dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
+#define db8500_add_i2c4(pdata) \
+ dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
+
+#define db8500_add_msp0_i2s(pdata) \
+ dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_i2s(pdata) \
+ dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_i2s(pdata) \
+ dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_i2s(pdata) \
+ dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_msp0_spi(pdata) \
+ dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_spi(pdata) \
+ dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_spi(pdata) \
+ dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_spi(pdata) \
+ dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_rtc() \
+ dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC);
+
+#define db8500_add_sdi0(pdata) \
+ dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata)
+#define db8500_add_sdi1(pdata) \
+ dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata)
+#define db8500_add_sdi2(pdata) \
+ dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata)
+#define db8500_add_sdi3(pdata) \
+ dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata)
+#define db8500_add_sdi4(pdata) \
+ dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata)
+#define db8500_add_sdi5(pdata) \
+ dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata)
+
+#define db8500_add_ssp0(pdata) \
+ db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
+#define db8500_add_ssp1(pdata) \
+ db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
+
+#define db8500_add_spi0(pdata) \
+ dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata)
+#define db8500_add_spi1(pdata) \
+ dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata)
+#define db8500_add_spi2(pdata) \
+ dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata)
+#define db8500_add_spi3(pdata) \
+ dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata)
+
+#define db8500_add_uart0() \
+ dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0)
+#define db8500_add_uart1() \
+ dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1)
+#define db8500_add_uart2() \
+ dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2)
+
+#endif
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c
index 8a268893cb7f..ea0a2f92ca70 100644
--- a/arch/arm/mach-ux500/devices.c
+++ b/arch/arm/mach-ux500/devices.c
@@ -14,69 +14,6 @@
#include <mach/hardware.h>
#include <mach/setup.h>
-#define __MEM_4K_RESOURCE(x) \
- .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
-
-struct amba_device ux500_pl031_device = {
- .dev = {
- .init_name = "pl031",
- },
- .res = {
- .start = UX500_RTC_BASE,
- .end = UX500_RTC_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_RTC_RTT, NO_IRQ},
-};
-
-struct amba_device ux500_uart0_device = {
- .dev = { .init_name = "uart0" },
- __MEM_4K_RESOURCE(UX500_UART0_BASE),
- .irq = {IRQ_UART0, NO_IRQ},
-};
-
-struct amba_device ux500_uart1_device = {
- .dev = { .init_name = "uart1" },
- __MEM_4K_RESOURCE(UX500_UART1_BASE),
- .irq = {IRQ_UART1, NO_IRQ},
-};
-
-struct amba_device ux500_uart2_device = {
- .dev = { .init_name = "uart2" },
- __MEM_4K_RESOURCE(UX500_UART2_BASE),
- .irq = {IRQ_UART2, NO_IRQ},
-};
-
-#define UX500_I2C_RESOURCES(id, size) \
-static struct resource ux500_i2c##id##_resources[] = { \
- [0] = { \
- .start = UX500_I2C##id##_BASE, \
- .end = UX500_I2C##id##_BASE + size - 1, \
- .flags = IORESOURCE_MEM, \
- }, \
- [1] = { \
- .start = IRQ_I2C##id, \
- .end = IRQ_I2C##id, \
- .flags = IORESOURCE_IRQ \
- } \
-}
-
-UX500_I2C_RESOURCES(1, SZ_4K);
-UX500_I2C_RESOURCES(2, SZ_4K);
-UX500_I2C_RESOURCES(3, SZ_4K);
-
-#define UX500_I2C_PDEVICE(cid) \
-struct platform_device ux500_i2c##cid##_device = { \
- .name = "nmk-i2c", \
- .id = cid, \
- .num_resources = 2, \
- .resource = ux500_i2c##cid##_resources, \
-}
-
-UX500_I2C_PDEVICE(1);
-UX500_I2C_PDEVICE(2);
-UX500_I2C_PDEVICE(3);
-
void __init amba_add_devices(struct amba_device *devs[], int num)
{
int i;
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c
new file mode 100644
index 000000000000..32a061f8a95b
--- /dev/null
+++ b/arch/arm/mach-ux500/dma-db5500.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * Author: Rabin Vincent <rabinv.vincent@stericsson.com> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <plat/ste_dma40.h>
+#include <mach/setup.h>
+#include <mach/hardware.h>
+
+#include "ste-dma40-db5500.h"
+
+static struct resource dma40_resources[] = {
+ [0] = {
+ .start = U5500_DMA_BASE,
+ .end = U5500_DMA_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "base",
+ },
+ [1] = {
+ .start = U5500_DMA_LCPA_BASE,
+ .end = U5500_DMA_LCPA_BASE + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "lcpa",
+ },
+ [2] = {
+ .start = IRQ_DB5500_DMA,
+ .end = IRQ_DB5500_DMA,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+/* Default configuration for physical memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
+ .mode = STEDMA40_MODE_PHYSICAL,
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_PHY_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_PHY_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/* Default configuration for logical memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_log = {
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_LOG_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/*
+ * Mapping between soruce event lines and physical device address This was
+ * created assuming that the event line is tied to a device and therefore the
+ * address is constant, however this is not true for at least USB, and the
+ * values are just placeholders for USB. This table is preserved and used for
+ * now.
+ */
+static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = {
+ [DB5500_DMA_DEV24_SDMMC0_RX] = -1,
+};
+
+/* Mapping between destination event lines and physical device address */
+static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = {
+ [DB5500_DMA_DEV24_SDMMC0_TX] = -1,
+};
+
+static int dma40_memcpy_event[] = {
+ DB5500_DMA_MEMCPY_TX_1,
+ DB5500_DMA_MEMCPY_TX_2,
+ DB5500_DMA_MEMCPY_TX_3,
+ DB5500_DMA_MEMCPY_TX_4,
+ DB5500_DMA_MEMCPY_TX_5,
+};
+
+static struct stedma40_platform_data dma40_plat_data = {
+ .dev_len = ARRAY_SIZE(dma40_rx_map),
+ .dev_rx = dma40_rx_map,
+ .dev_tx = dma40_tx_map,
+ .memcpy = dma40_memcpy_event,
+ .memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
+ .memcpy_conf_phy = &dma40_memcpy_conf_phy,
+ .memcpy_conf_log = &dma40_memcpy_conf_log,
+ .disabled_channels = {-1},
+};
+
+static struct platform_device dma40_device = {
+ .dev = {
+ .platform_data = &dma40_plat_data,
+ },
+ .name = "dma40",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dma40_resources),
+ .resource = dma40_resources
+};
+
+void __init db5500_dma_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dma40_device);
+ if (ret)
+ dev_err(&dma40_device.dev, "unable to register device: %d\n", ret);
+
+}
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
index a6be2cdf2b2f..64fa451edcfd 100644
--- a/arch/arm/mach-ux500/headsmp.S
+++ b/arch/arm/mach-ux500/headsmp.S
@@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup)
ldmia r4, {r5, r6}
sub r4, r4, r5
add r6, r6, r4
- dsb
pen: ldr r7, [r6]
cmp r7, r0
bne pen
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index b782a03024be..dd8037ebccf8 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -11,14 +11,11 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/completion.h>
#include <asm/cacheflush.h>
extern volatile int pen_release;
-static DECLARE_COMPLETION(cpu_killed);
-
static inline void platform_do_lowpower(unsigned int cpu)
{
flush_cache_all();
@@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
int platform_cpu_kill(unsigned int cpu)
{
- return wait_for_completion_timeout(&cpu_killed, 5000);
+ return 1;
}
/*
@@ -48,19 +45,6 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
-#ifdef DEBUG
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
-#endif
-
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
-
/* directly enter low power state, skipping secure registers */
platform_do_lowpower(cpu);
}
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
index 3eafc0e24ba5..bd88c1e74060 100644
--- a/arch/arm/mach-ux500/include/mach/db5500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -114,4 +114,8 @@
#define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20)
#define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F)
+#define U5500_ESRAM_BASE 0x40000000
+#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000
+#define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET)
+
#endif
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index f07d0986409d..0fefb34c11e4 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -92,7 +92,8 @@
#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000)
#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
-#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x0f000)
+#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
+#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
/* per3 base addresses */
#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000)
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
index b91a4d1211a2..020b6369a30a 100644
--- a/arch/arm/mach-ux500/include/mach/devices.h
+++ b/arch/arm/mach-ux500/include/mach/devices.h
@@ -14,27 +14,10 @@ extern struct platform_device u5500_gpio_devs[];
extern struct platform_device u8500_gpio_devs[];
extern struct amba_device ux500_pl031_device;
-extern struct amba_device u8500_ssp0_device;
-extern struct amba_device ux500_uart0_device;
-extern struct amba_device ux500_uart1_device;
-extern struct amba_device ux500_uart2_device;
-extern struct platform_device ux500_i2c1_device;
-extern struct platform_device ux500_i2c2_device;
-extern struct platform_device ux500_i2c3_device;
-
-extern struct platform_device u8500_i2c0_device;
-extern struct platform_device u8500_i2c4_device;
extern struct platform_device u8500_dma40_device;
extern struct platform_device ux500_ske_keypad_device;
-extern struct amba_device u8500_sdi0_device;
-extern struct amba_device u8500_sdi1_device;
-extern struct amba_device u8500_sdi2_device;
-extern struct amba_device u8500_sdi3_device;
-extern struct amba_device u8500_sdi4_device;
-extern struct amba_device u8500_sdi5_device;
-
void dma40_u8500ed_fixup(void);
#endif
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S
index 60ea88db8283..a37f585a3ecb 100644
--- a/arch/arm/mach-ux500/include/mach/entry-macro.S
+++ b/arch/arm/mach-ux500/include/mach/entry-macro.S
@@ -11,7 +11,8 @@
* warranty of any kind, whether express or implied.
*/
#include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
.macro disable_fiq
.endm
@@ -22,68 +23,3 @@
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an
- * interrupt if it's between 30 and 1020. The test_for_ipi
- * routine below will pick up on IPIs.
- *
- * A simple read from the controller will tell us the number
- * of the highest priority enabled interrupt. We then just
- * need to check whether it is in the valid range for an
- * IRQ (30-1020 inclusive).
- */
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- /* bits 12-10 = src CPU, 9-0 = int # */
- ldr \irqstat, [\base, #GIC_CPU_INTACK]
-
- ldr \tmp, =1021
-
- bic \irqnr, \irqstat, #0x1c00
-
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
-
- .endm
-
- /* We assume that irqstat (the raw value of the IRQ
- * acknowledge register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of
- * interrupt on the controller, since this requires the
- * original irqstat value which we won't easily be able
- * to recreate later.
- */
-
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base
- * are preserved..
- */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h
index d548a622e7d2..3c4cd31ad9f7 100644
--- a/arch/arm/mach-ux500/include/mach/gpio.h
+++ b/arch/arm/mach-ux500/include/mach/gpio.h
@@ -9,42 +9,4 @@
#include <plat/gpio.h>
-#define __GPIO_RESOURCE(soc, block) \
- { \
- .start = soc##_GPIOBANK##block##_BASE, \
- .end = soc##_GPIOBANK##block##_BASE + 127, \
- .flags = IORESOURCE_MEM, \
- }, \
- { \
- .start = IRQ_GPIO##block, \
- .end = IRQ_GPIO##block, \
- .flags = IORESOURCE_IRQ, \
- }
-
-#define __GPIO_DEVICE(soc, block) \
- { \
- .name = "gpio", \
- .id = block, \
- .num_resources = 2, \
- .resource = &soc##_gpio_resources[block * 2], \
- .dev = { \
- .platform_data = &soc##_gpio_data[block], \
- }, \
- }
-
-#define GPIO_DATA(_name, first) \
- { \
- .name = _name, \
- .first_gpio = first, \
- .first_irq = NOMADIK_GPIO_TO_IRQ(first), \
- }
-
-#ifdef CONFIG_UX500_SOC_DB8500
-#define GPIO_RESOURCE(block) __GPIO_RESOURCE(U8500, block)
-#define GPIO_DEVICE(block) __GPIO_DEVICE(u8500, block)
-#elif defined(CONFIG_UX500_SOC_DB5500)
-#define GPIO_RESOURCE(block) __GPIO_RESOURCE(U5500, block)
-#define GPIO_DEVICE(block) __GPIO_DEVICE(u5500, block)
-#endif
-
#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 32e883a8f2a2..6295cc581355 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -142,6 +142,8 @@ static inline bool cpu_is_u5500(void)
#endif
}
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
#endif
#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
index cca4f705601e..7cdeb2af0ebb 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -8,12 +8,36 @@
#ifndef __MACH_IRQS_BOARD_MOP500_H
#define __MACH_IRQS_BOARD_MOP500_H
-#define AB8500_NR_IRQS 104
+/* Number of AB8500 irqs is taken from header file */
+#include <linux/mfd/ab8500.h>
#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
+ AB8500_NR_IRQS)
-#define MOP500_IRQ_END MOP500_AB8500_IRQ_END
+
+/* TC35892 */
+#define TC35892_NR_INTERNAL_IRQS 8
+#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
+#define TC35892_NR_GPIOS 24
+#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
+
+#define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS
+
+#define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END
+#define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \
+ + MOP500_EGPIO_NR_IRQS)
+/* STMPE1601 irqs */
+#define STMPE_NR_INTERNAL_IRQS 9
+#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
+#define STMPE_NR_GPIOS 24
+#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
+
+#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
+#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
+
+#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
+
+#define MOP500_IRQ_END MOP500_NR_IRQS
#if MOP500_IRQ_END > IRQ_BOARD_END
#undef IRQ_BOARD_END
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index 693aa57de88d..880ae45bc235 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -21,50 +21,6 @@
/* Interrupt numbers generic for shared peripheral */
#define IRQ_MTU0 (IRQ_SHPI_START + 4)
-#define IRQ_SPI2 (IRQ_SHPI_START + 6)
-#define IRQ_SPI0 (IRQ_SHPI_START + 8)
-#define IRQ_UART0 (IRQ_SHPI_START + 11)
-#define IRQ_I2C3 (IRQ_SHPI_START + 12)
-#define IRQ_SSP0 (IRQ_SHPI_START + 14)
-#define IRQ_MTU1 (IRQ_SHPI_START + 17)
-#define IRQ_RTC_RTT (IRQ_SHPI_START + 18)
-#define IRQ_UART1 (IRQ_SHPI_START + 19)
-#define IRQ_I2C0 (IRQ_SHPI_START + 21)
-#define IRQ_I2C1 (IRQ_SHPI_START + 22)
-#define IRQ_USBOTG (IRQ_SHPI_START + 23)
-#define IRQ_DMA (IRQ_SHPI_START + 25)
-#define IRQ_UART2 (IRQ_SHPI_START + 26)
-#define IRQ_HSIR_EXCEP (IRQ_SHPI_START + 29)
-#define IRQ_MSP0 (IRQ_SHPI_START + 31)
-#define IRQ_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32)
-#define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
-#define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
-#define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
-#define IRQ_AB8500 (IRQ_SHPI_START + 40)
-#define IRQ_PRCMU (IRQ_SHPI_START + 47)
-#define IRQ_DISP (IRQ_SHPI_START + 48)
-#define IRQ_SiPI3 (IRQ_SHPI_START + 49)
-#define IRQ_I2C4 (IRQ_SHPI_START + 51)
-#define IRQ_SSP1 (IRQ_SHPI_START + 52)
-#define IRQ_I2C2 (IRQ_SHPI_START + 55)
-#define IRQ_SDMMC0 (IRQ_SHPI_START + 60)
-#define IRQ_MSP1 (IRQ_SHPI_START + 62)
-#define IRQ_SPI1 (IRQ_SHPI_START + 96)
-#define IRQ_MSP2 (IRQ_SHPI_START + 98)
-#define IRQ_SDMMC4 (IRQ_SHPI_START + 99)
-#define IRQ_HSIRD0 (IRQ_SHPI_START + 104)
-#define IRQ_HSIRD1 (IRQ_SHPI_START + 105)
-#define IRQ_HSITD0 (IRQ_SHPI_START + 106)
-#define IRQ_HSITD1 (IRQ_SHPI_START + 107)
-#define IRQ_GPIO0 (IRQ_SHPI_START + 119)
-#define IRQ_GPIO1 (IRQ_SHPI_START + 120)
-#define IRQ_GPIO2 (IRQ_SHPI_START + 121)
-#define IRQ_GPIO3 (IRQ_SHPI_START + 122)
-#define IRQ_GPIO4 (IRQ_SHPI_START + 123)
-#define IRQ_GPIO5 (IRQ_SHPI_START + 124)
-#define IRQ_GPIO6 (IRQ_SHPI_START + 125)
-#define IRQ_GPIO7 (IRQ_SHPI_START + 126)
-#define IRQ_GPIO8 (IRQ_SHPI_START + 127)
/* There are 128 shared peripheral interrupts assigned to
* INTID[160:32]. The first 32 interrupts are reserved.
diff --git a/arch/arm/mach-ux500/include/mach/mbox.h b/arch/arm/mach-ux500/include/mach/mbox-db5500.h
index 7f9da4d2fbda..7f9da4d2fbda 100644
--- a/arch/arm/mach-ux500/include/mach/mbox.h
+++ b/arch/arm/mach-ux500/include/mach/mbox-db5500.h
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-defs.h b/arch/arm/mach-ux500/include/mach/prcmu-defs.h
new file mode 100644
index 000000000000..848ba64b561f
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/prcmu-defs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Author: Martin Persson <martin.persson@stericsson.com>
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * PRCM Unit definitions
+ */
+
+#ifndef __MACH_PRCMU_DEFS_H
+#define __MACH_PRCMU_DEFS_H
+
+enum prcmu_cpu_opp {
+ CPU_OPP_INIT = 0x00,
+ CPU_OPP_NO_CHANGE = 0x01,
+ CPU_OPP_100 = 0x02,
+ CPU_OPP_50 = 0x03,
+ CPU_OPP_MAX = 0x04,
+ CPU_OPP_EXT_CLK = 0x07
+};
+enum prcmu_ape_opp {
+ APE_OPP_NO_CHANGE = 0x00,
+ APE_OPP_100 = 0x02,
+ APE_OPP_50 = 0x03,
+};
+
+#endif /* __MACH_PRCMU_DEFS_H */
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
index 8885f39a6421..455467e88791 100644
--- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h
+++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
@@ -1,10 +1,15 @@
/*
- * Copyright (c) 2009 ST-Ericsson SA
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * PRCM Unit registers
*/
+
#ifndef __MACH_PRCMU_REGS_H
#define __MACH_PRCMU_REGS_H
@@ -88,4 +93,4 @@
/* Miscellaneous unit registers */
#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324)
-#endif /* __MACH_PRCMU__REGS_H */
+#endif /* __MACH_PRCMU_REGS_H */
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h
index 549843ff6dbe..c49e456162ef 100644
--- a/arch/arm/mach-ux500/include/mach/prcmu.h
+++ b/arch/arm/mach-ux500/include/mach/prcmu.h
@@ -2,14 +2,27 @@
* Copyright (C) STMicroelectronics 2009
* Copyright (C) ST-Ericsson SA 2010
*
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
+ *
* License Terms: GNU General Public License v2
*
- * PRCMU f/w APIs
+ * PRCM Unit f/w API
*/
#ifndef __MACH_PRCMU_H
#define __MACH_PRCMU_H
+#include <mach/prcmu-defs.h>
+void __init prcmu_early_init(void);
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+int prcmu_set_ape_opp(enum prcmu_ape_opp opp);
+int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp);
+int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
+ enum prcmu_cpu_opp cpu_opp);
+int prcmu_get_ape_opp(void);
+int prcmu_get_cpu_opp(void);
+bool prcmu_has_arm_maxopp(void);
#endif /* __MACH_PRCMU_H */
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index 54bbe648bf58..469877e0de90 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -18,14 +18,19 @@ extern void __init ux500_map_io(void);
extern void __init u5500_map_io(void);
extern void __init u8500_map_io(void);
-extern void __init ux500_init_devices(void);
extern void __init u5500_init_devices(void);
extern void __init u8500_init_devices(void);
extern void __init ux500_init_irq(void);
+
+extern void __init u5500_sdi_init(void);
+
+extern void __init db5500_dma_init(void);
+
/* We re-use nomadik_timer for this platform */
extern void nmdk_timer_init(void);
+struct amba_device;
extern void __init amba_add_devices(struct amba_device *devs[], int num);
struct sys_timer;
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index 197e8417375e..ca2b15b1b3b1 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,7 +10,6 @@
#define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
/* This is required to wakeup the secondary core */
extern void u8500_secondary_startup(void);
@@ -18,8 +17,8 @@ extern void u8500_secondary_startup(void);
/*
* We use IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h
index 0271ca0a83df..9a6614c6808e 100644
--- a/arch/arm/mach-ux500/include/mach/uncompress.h
+++ b/arch/arm/mach-ux500/include/mach/uncompress.h
@@ -19,38 +19,43 @@
#define __ASM_ARCH_UNCOMPRESS_H
#include <asm/setup.h>
+#include <asm/mach-types.h>
#include <linux/io.h>
+#include <linux/amba/serial.h>
#include <mach/hardware.h>
-#define U8500_UART_DR 0x80007000
-#define U8500_UART_LCRH 0x8000702c
-#define U8500_UART_CR 0x80007030
-#define U8500_UART_FR 0x80007018
+static u32 ux500_uart_base;
static void putc(const char c)
{
/* Do nothing if the UART is not enabled. */
- if (!(__raw_readb(U8500_UART_CR) & 0x1))
+ if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1))
return;
if (c == '\n')
putc('\r');
- while (__raw_readb(U8500_UART_FR) & (1 << 5))
+ while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 5))
barrier();
- __raw_writeb(c, U8500_UART_DR);
+ __raw_writeb(c, ux500_uart_base + UART01x_DR);
}
static void flush(void)
{
- if (!(__raw_readb(U8500_UART_CR) & 0x1))
+ if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1))
return;
- while (__raw_readb(U8500_UART_FR) & (1 << 3))
+ while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 3))
barrier();
}
static inline void arch_decomp_setup(void)
{
+ if (machine_is_u8500())
+ ux500_uart_base = U8500_UART2_BASE;
+ else if (machine_is_u5500())
+ ux500_uart_base = U5500_UART0_BASE;
+ else /* not much can be done to help here */
+ ux500_uart_base = U8500_UART2_BASE;
}
#define arch_decomp_wdog() /* nothing to do here */
diff --git a/arch/arm/mach-ux500/mbox.c b/arch/arm/mach-ux500/mbox-db5500.c
index 63435389c544..cbf15718fc3c 100644
--- a/arch/arm/mach-ux500/mbox.c
+++ b/arch/arm/mach-ux500/mbox-db5500.c
@@ -38,7 +38,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/completion.h>
-#include <mach/mbox.h>
+#include <mach/mbox-db5500.h>
#define MBOX_NAME "mbox"
diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem-irq-db5500.c
index 3187f8871169..3187f8871169 100644
--- a/arch/arm/mach-ux500/modem_irq.c
+++ b/arch/arm/mach-ux500/modem-irq-db5500.c
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 9e4c678de785..d77e76cb7edd 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -18,7 +18,6 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <mach/hardware.h>
@@ -26,31 +25,37 @@
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
-volatile int __cpuinitdata pen_release = -1;
+volatile int pen_release = -1;
-static unsigned int __init get_core_count(void)
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
{
- return scu_get_core_count(__io_address(UX500_SCU_BASE));
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+ gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
- pen_release = -1;
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
@@ -74,11 +79,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release.
*/
- pen_release = cpu;
- __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
- outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
+ write_pen_release(cpu);
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -97,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
static void __init wakeup_secondary(void)
{
- /* nobody is to be released from the pen yet */
- pen_release = -1;
-
/*
* write the address of secondary startup into the backup ram register
* at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
@@ -126,40 +126,26 @@ static void __init wakeup_secondary(void)
*/
void __init smp_init_cpus(void)
{
- unsigned int i, ncores = get_core_count();
+ unsigned int i, ncores;
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-void __init smp_prepare_cpus(unsigned int max_cpus)
-{
- unsigned int ncores = get_core_count();
- unsigned int cpu = smp_processor_id();
- int i;
+ ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "U8500: strange CM count of 0? Default to 1\n");
- ncores = 1;
- }
-
- if (ncores > num_possible_cpus()) {
+ if (ncores > NR_CPUS) {
printk(KERN_WARNING
"U8500: no. of cores (%d) greater than configured "
"maximum of %d - clipping\n",
- ncores, num_possible_cpus());
- ncores = num_possible_cpus();
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
}
- smp_store_cpu_info(cpu);
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
- /*
- * are we trying to boot more cores than exist?
- */
- if (max_cpus > ncores)
- max_cpus = ncores;
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
/*
* Initialise the present map, which describes the set of CPUs
@@ -168,13 +154,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
- if (max_cpus > 1) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
- scu_enable(__io_address(UX500_SCU_BASE));
- wakeup_secondary();
- }
+ scu_enable(__io_address(UX500_SCU_BASE));
+ wakeup_secondary();
}
diff --git a/arch/arm/mach-ux500/prcmu.c b/arch/arm/mach-ux500/prcmu.c
index 293274d1342a..c522d26ef348 100644
--- a/arch/arm/mach-ux500/prcmu.c
+++ b/arch/arm/mach-ux500/prcmu.c
@@ -1,10 +1,14 @@
/*
- * Copyright (C) ST Ericsson SA 2010
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License v2
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
*
- * U8500 PRCMU driver.
+ * U8500 PRCM Unit interface driver
+ *
*/
#include <linux/kernel.h>
#include <linux/module.h>
@@ -19,11 +23,26 @@
#include <mach/hardware.h>
#include <mach/prcmu-regs.h>
+#include <mach/prcmu-defs.h>
+
+/* Global var to runtime determine TCDM base for v2 or v1 */
+static __iomem void *tcdm_base;
+
+#define _MBOX_HEADER (tcdm_base + 0xFE8)
+#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0)
+
+#define REQ_MB1 (tcdm_base + 0xFD0)
+#define REQ_MB5 (tcdm_base + 0xE44)
-#define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE)
+#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0)
+#define REQ_MB1_APEOPP (REQ_MB1 + 0x1)
+#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2)
-#define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44)
-#define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4)
+#define ACK_MB1 (tcdm_base + 0xE04)
+#define ACK_MB5 (tcdm_base + 0xDF4)
+
+#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0)
+#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1)
#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
@@ -33,10 +52,33 @@
#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
#define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
-#define I2C_WRITE(slave) ((slave) << 1)
-#define I2C_READ(slave) (((slave) << 1) | BIT(0))
+#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4)
+#define PRCM_AVS_ISMODEENABLE 7
+#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE)
+
+#define I2C_WRITE(slave) \
+ (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
+#define I2C_READ(slave) \
+ (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0))
#define I2C_STOP_EN BIT(3)
+enum mb1_h {
+ MB1H_ARM_OPP = 1,
+ MB1H_APE_OPP,
+ MB1H_ARM_APE_OPP,
+};
+
+static struct {
+ struct mutex lock;
+ struct completion work;
+ struct {
+ u8 arm_opp;
+ u8 ape_opp;
+ u8 arm_status;
+ u8 ape_status;
+ } ack;
+} mb1_transfer;
+
enum ack_mb5_status {
I2C_WR_OK = 0x01,
I2C_RD_OK = 0x02,
@@ -145,6 +187,104 @@ unlock_and_return:
}
EXPORT_SYMBOL(prcmu_abb_write);
+static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp,
+ enum prcmu_cpu_opp cpu_opp)
+{
+ bool do_ape;
+ bool do_arm;
+ int err = 0;
+
+ do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP));
+ do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP));
+
+ mutex_lock(&mb1_transfer.lock);
+
+ while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+ cpu_relax();
+
+ writeb(0, MBOX_HEADER_REQ_MB0);
+ writeb(cpu_opp, REQ_MB1_ARMOPP);
+ writeb(ape_opp, REQ_MB1_APEOPP);
+ writeb(0, REQ_MB1_BOOSTOPP);
+ writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
+ wait_for_completion(&mb1_transfer.work);
+ if ((do_ape) && (mb1_transfer.ack.ape_status != 0))
+ err = -EIO;
+ if ((do_arm) && (mb1_transfer.ack.arm_status != 0))
+ err = -EIO;
+
+ mutex_unlock(&mb1_transfer.lock);
+
+ return err;
+}
+
+/**
+ * prcmu_set_ape_opp() - Set the OPP of the APE.
+ * @opp: The OPP to set.
+ *
+ * This function sets the OPP of the APE.
+ */
+int prcmu_set_ape_opp(enum prcmu_ape_opp opp)
+{
+ return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE);
+}
+EXPORT_SYMBOL(prcmu_set_ape_opp);
+
+/**
+ * prcmu_set_cpu_opp() - Set the OPP of the CPU.
+ * @opp: The OPP to set.
+ *
+ * This function sets the OPP of the CPU.
+ */
+int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp)
+{
+ return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp);
+}
+EXPORT_SYMBOL(prcmu_set_cpu_opp);
+
+/**
+ * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU.
+ * @ape_opp: The APE OPP to set.
+ * @cpu_opp: The CPU OPP to set.
+ *
+ * This function sets the OPPs of the APE and the CPU.
+ */
+int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
+ enum prcmu_cpu_opp cpu_opp)
+{
+ return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp);
+}
+EXPORT_SYMBOL(prcmu_set_ape_cpu_opps);
+
+/**
+ * prcmu_get_ape_opp() - Get the OPP of the APE.
+ *
+ * This function gets the OPP of the APE.
+ */
+enum prcmu_ape_opp prcmu_get_ape_opp(void)
+{
+ return readb(ACK_MB1_CURR_APEOPP);
+}
+EXPORT_SYMBOL(prcmu_get_ape_opp);
+
+/**
+ * prcmu_get_cpu_opp() - Get the OPP of the CPU.
+ *
+ * This function gets the OPP of the CPU. The OPP is specified in %%.
+ * PRCMU_OPP_EXT is a special OPP value, not specified in %%.
+ */
+int prcmu_get_cpu_opp(void)
+{
+ return readb(ACK_MB1_CURR_ARMOPP);
+}
+EXPORT_SYMBOL(prcmu_get_cpu_opp);
+
+bool prcmu_has_arm_maxopp(void)
+{
+ return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK)
+ == PRCM_AVS_ISMODEENABLE_MASK;
+}
+
static void read_mailbox_0(void)
{
writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
@@ -152,6 +292,9 @@ static void read_mailbox_0(void)
static void read_mailbox_1(void)
{
+ mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP);
+ mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP);
+ complete(&mb1_transfer.work);
writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
}
@@ -217,15 +360,35 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
+void __init prcmu_early_init(void)
+{
+ if (cpu_is_u8500v11() || cpu_is_u8500ed()) {
+ tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
+ } else if (cpu_is_u8500v2()) {
+ tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
+ } else {
+ pr_err("prcmu: Unsupported chip version\n");
+ BUG();
+ }
+}
+
static int __init prcmu_init(void)
{
+ if (cpu_is_u8500ed()) {
+ pr_err("prcmu: Unsupported chip version\n");
+ return 0;
+ }
+
+ mutex_init(&mb1_transfer.lock);
+ init_completion(&mb1_transfer.work);
mutex_init(&mb5_transfer.lock);
init_completion(&mb5_transfer.work);
/* Clean up the mailbox interrupts after pre-kernel code. */
writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
- return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL);
+ return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0,
+ "prcmu", NULL);
}
arch_initcall(prcmu_init);
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index c781f30c8368..3f7b5e9d83c5 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -4,6 +4,7 @@ menu "Versatile platform type"
config ARCH_VERSATILE_PB
bool "Support Versatile/PB platform"
select CPU_ARM926T
+ select MIGHT_HAVE_PCI
default y
help
Include support for the ARM(R) Versatile/PB platform.
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index e38acb0f89c8..13a83e45a33b 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -31,8 +31,8 @@
#include <linux/amba/pl022.h>
#include <linux/io.h>
#include <linux/gfp.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/leds.h>
@@ -46,10 +46,11 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <mach/platform.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
+
+#include <plat/sched_clock.h>
#include "core.h"
@@ -886,6 +887,12 @@ void __init versatile_init(void)
}
/*
+ * The sched_clock counter
+ */
+#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
+ VERSATILE_SYS_24MHz_OFFSET)
+
+/*
* Where is the timer (VA)?
*/
#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
@@ -900,6 +907,8 @@ static void __init versatile_timer_init(void)
{
u32 val;
+ versatile_sched_clock_init(REFCOUNTER, 24000000);
+
/*
* set clock frequency:
* VERSATILE_REFCLK is 32KHz
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 1b71b77ade22..2c0ac7de2814 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -5,4 +5,5 @@
obj-y := v2m.o
obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 57dd95ce41f9..362780d868de 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -22,5 +22,3 @@ struct map_desc;
void v2m_map_io(struct map_desc *tile, size_t num);
extern struct sys_timer v2m_timer;
-
-extern void __iomem *gic_cpu_base_addr;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index fd25ccd7272f..e628402b754c 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -8,8 +8,8 @@
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/pgtable.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
@@ -18,10 +18,9 @@
#include <asm/pmu.h>
#include <asm/smp_twd.h>
-#include <mach/clkdev.h>
#include <mach/ct-ca9x4.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -60,13 +59,10 @@ static void __init ct_ca9x4_map_io(void)
v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
}
-void __iomem *gic_cpu_base_addr;
-
static void __init ct_ca9x4_init_irq(void)
{
- gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU);
- gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29);
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
+ MMIO_P2V(A9_MPCORE_GIC_CPU));
}
#if 0
diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/mach-vexpress/headsmp.S
index 8a78ff68e1ee..7a3f0632947c 100644
--- a/arch/arm/mach-vexpress/headsmp.S
+++ b/arch/arm/mach-vexpress/headsmp.S
@@ -35,5 +35,6 @@ pen: ldr r7, [r6]
*/
b secondary_startup
+ .align
1: .long .
.long pen_release
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 000000000000..ea4cbfb90a66
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,128 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ "mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, %3\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+ /*
+ * there is no power-control hardware on this platform, so all
+ * we can do is put the core into WFI; this is safe as the calling
+ * code will have already disabled interrupts
+ */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S
index 20e9fb514f0a..73c11297509e 100644
--- a/arch/arm/mach-vexpress/include/mach/entry-macro.S
+++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S
@@ -1,67 +1,7 @@
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =gic_cpu_base_addr
- ldr \base, [\base]
- .endm
-
.macro arch_ret_to_user, tmp1, tmp2
.endm
-
- /*
- * The interrupt numbering scheme is defined in the
- * interrupt controller spec. To wit:
- *
- * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local. We allow 30 to be used for the watchdog.
- * 32-1020 are global
- * 1021-1022 are reserved
- * 1023 is "spurious" (no interrupt)
- *
- * For now, we ignore all local interrupts so only return an interrupt if it's
- * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
- *
- * A simple read from the controller will tell us the number of the highest
- * priority enabled interrupt. We then just need to check whether it is in the
- * valid range for an IRQ (30-1020 inclusive).
- */
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
- ldr \tmp, =1021
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #29
- cmpcc \irqnr, \irqnr
- cmpne \irqnr, \tmp
- cmpcs \irqnr, \irqnr
- .endm
-
- /* We assume that irqstat (the raw value of the IRQ acknowledge
- * register) is preserved from the macro above.
- * If there is an IPI, we immediately signal end of interrupt on the
- * controller, since this requires the original irqstat value which
- * we won't easily be able to recreate later.
- */
-
- .macro test_for_ipi, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- cmp \irqnr, #16
- strcc \irqstat, [\base, #GIC_CPU_EOI]
- cmpcs \irqnr, \irqnr
- .endm
-
- /* As above, this assumes that irqstat and base are preserved.. */
-
- .macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
- .endm
-
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 5a6da4fd247e..4c05e4a9713a 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,13 +2,12 @@
#define __MACH_SMP_H
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
/*
* We use IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 670970699ba9..b1687b6abe63 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -17,7 +17,6 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>
@@ -35,6 +34,19 @@ extern void vexpress_secondary_startup(void);
*/
volatile int __cpuinitdata pen_release = -1;
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
static void __iomem *scu_base_addr(void)
{
return MMIO_P2V(A9_MPCORE_SCU);
@@ -44,21 +56,18 @@ static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
- pen_release = -1;
- smp_wmb();
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
@@ -83,16 +92,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
- pen_release = cpu;
- __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
- outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+ write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -124,13 +131,6 @@ void __init smp_init_cpus(void)
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "vexpress: strange CM count of 0? Default to 1\n");
-
- ncores = 1;
- }
-
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"vexpress: no. of cores (%d) greater than configured "
@@ -143,20 +143,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true);
}
-void __init smp_prepare_cpus(unsigned int max_cpus)
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
- unsigned int ncores = num_possible_cpus();
- unsigned int cpu = smp_processor_id();
int i;
- smp_store_cpu_info(cpu);
-
- /*
- * are we trying to boot more cores than exist?
- */
- if (max_cpus > ncores)
- max_cpus = ncores;
-
/*
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time.
@@ -164,27 +154,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
+ scu_enable(scu_base_addr());
+
/*
- * Initialise the SCU if there are more than one CPU and let
- * them know where to start.
+ * Write the address of secondary startup into the
+ * system-wide flags register. The boot monitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
*/
- if (max_cpus > 1) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
-
- scu_enable(scu_base_addr());
-
- /*
- * Write the address of secondary startup into the
- * system-wide flags register. The boot monitor waits
- * until it receives a soft interrupt, and then the
- * secondary CPU branches to this address.
- */
- writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
- writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
- MMIO_P2V(V2M_SYS_FLAGSSET));
- }
+ writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
+ writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
+ MMIO_P2V(V2M_SYS_FLAGSSET));
}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 7eaa232180a5..a9ed3428a2fa 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -11,18 +11,18 @@
#include <linux/spinlock.h>
#include <linux/sysdev.h>
#include <linux/usb/isp1760.h>
+#include <linux/clkdev.h>
-#include <asm/clkdev.h>
#include <asm/sizes.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
-#include <mach/clkdev.h>
#include <mach/motherboard.h>
-#include <plat/timer-sp.h>
+#include <plat/sched_clock.h>
#include "core.h"
@@ -50,6 +50,8 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
static void __init v2m_timer_init(void)
{
+ versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
+
writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
index c56ddab3d912..b88a1b16b2e9 100644
--- a/arch/arm/mach-w90x900/clock.h
+++ b/arch/arm/mach-w90x900/clock.h
@@ -10,7 +10,7 @@
* the Free Software Foundation; either version 2 of the License.
*/
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
void nuc900_clk_enable(struct clk *clk, int enable);
void nuc900_subclk_enable(struct clk *clk, int enable);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index b80f769bc135..4b089cb930dc 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -153,7 +153,6 @@ static struct clocksource clocksource_nuc900 = {
.rating = 200,
.read = nuc900_get_cycles,
.mask = CLOCKSOURCE_MASK(TDR_SHIFT),
- .shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -176,9 +175,7 @@ static void __init nuc900_clocksource_init(void)
val |= (COUNTEN | PERIOD | PRESCALE);
__raw_writel(val, REG_TCSR1);
- clocksource_nuc900.mult =
- clocksource_khz2mult((rate / 1000), clocksource_nuc900.shift);
- clocksource_register(&clocksource_nuc900);
+ clocksource_register_hz(&clocksource_nuc900, rate);
}
static void __init nuc900_timer_init(void)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4414a01e1e8a..fcc1e628e050 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -382,6 +382,12 @@ config CPU_FEROCEON_OLD_ID
for which the CPU ID is equal to the ARM926 ID.
Relevant for Feroceon-1850 and early Feroceon-2850.
+# Marvell PJ4
+config CPU_PJ4
+ bool
+ select CPU_V7
+ select ARM_THUMBEE
+
# ARMv6
config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE
@@ -599,6 +605,14 @@ config CPU_CP15_MPU
help
Processor has the CP15 register, which has MPU related registers.
+config CPU_USE_DOMAINS
+ bool
+ depends on MMU
+ default y if !CPU_32v6K
+ help
+ This option enables or disables the use of domain switching
+ via the set_fs() function.
+
#
# CPU supports 36-bit I/O
#
@@ -628,6 +642,33 @@ config ARM_THUMBEE
Say Y here if you have a CPU with the ThumbEE extension and code to
make use of it. Say N for code that can run on CPUs without ThumbEE.
+config SWP_EMULATE
+ bool "Emulate SWP/SWPB instructions"
+ depends on CPU_V7
+ select HAVE_PROC_CPU if PROC_FS
+ default y if SMP
+ help
+ ARMv6 architecture deprecates use of the SWP/SWPB instructions.
+ ARMv7 multiprocessing extensions introduce the ability to disable
+ these instructions, triggering an undefined instruction exception
+ when executed. Say Y here to enable software emulation of these
+ instructions for userspace (not kernel) using LDREX/STREX.
+ Also creates /proc/cpu/swp_emulation for statistics.
+
+ In some older versions of glibc [<=2.8] SWP is used during futex
+ trylock() operations with the assumption that the code will not
+ be preempted. This invalid assumption may be more likely to fail
+ with SWP emulation enabled, leading to deadlock of the user
+ application.
+
+ NOTE: when accessing uncached shared regions, LDREX/STREX rely
+ on an external transaction monitoring block called a global
+ monitor to maintain update atomicity. If your system does not
+ implement a global monitor, this option can cause programs that
+ perform SWP operations to uncached memory to deadlock.
+
+ If unsure, say Y.
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
depends on ARCH_SUPPORTS_BIG_ENDIAN
@@ -772,7 +813,7 @@ config CACHE_L2X0
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
ARCH_NOMADIK || ARCH_OMAP4 || ARCH_S5PV310 || ARCH_TEGRA || \
- ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE
default y
select OUTER_CACHE
select OUTER_CACHE_SYNC
@@ -789,7 +830,7 @@ config CACHE_PL310
config CACHE_TAUROS2
bool "Enable the Tauros2 L2 cache controller"
- depends on (ARCH_DOVE || ARCH_MMP)
+ depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
default y
select OUTER_CACHE
help
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index d63b6c413758..00d74a04af3a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -5,8 +5,8 @@
obj-y := dma-mapping.o extable.o fault.o init.o \
iomap.o
-obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \
- pgd.o mmu.o vmregion.o
+obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
+ mmap.o pgd.o mmu.o vmregion.o
ifneq ($(CONFIG_MMU),y)
obj-y += nommu.o
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 6e77c042d8e9..e0b0e7a4ec68 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -13,13 +13,9 @@
*/
#include <linux/init.h>
+#include <linux/highmem.h>
#include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
#include <plat/cache-feroceon-l2.h>
-#include "mm.h"
/*
* Low-level cache maintenance operations.
@@ -39,27 +35,30 @@
* between which we don't want to be preempted.
*/
-static inline unsigned long l2_start_va(unsigned long paddr)
+static inline unsigned long l2_get_va(unsigned long paddr)
{
#ifdef CONFIG_HIGHMEM
/*
- * Let's do our own fixmap stuff in a minimal way here.
* Because range ops can't be done on physical addresses,
* we simply install a virtual mapping for it only for the
* TLB lookup to occur, hence no need to flush the untouched
- * memory mapping. This is protected with the disabling of
- * interrupts by the caller.
+ * memory mapping afterwards (note: a cache flush may happen
+ * in some circumstances depending on the path taken in kunmap_atomic).
*/
- unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
- unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
- local_flush_tlb_kernel_page(vaddr);
- return vaddr + (paddr & ~PAGE_MASK);
+ void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
+ return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
#else
return __phys_to_virt(paddr);
#endif
}
+static inline void l2_put_va(unsigned long vaddr)
+{
+#ifdef CONFIG_HIGHMEM
+ kunmap_atomic((void *)vaddr);
+#endif
+}
+
static inline void l2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
@@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
*/
BUG_ON((start ^ end) >> PAGE_SHIFT);
- raw_local_irq_save(flags);
- va_start = l2_start_va(start);
+ va_start = l2_get_va(start);
va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
+ l2_put_va(va_start);
}
static inline void l2_clean_inv_pa(unsigned long addr)
@@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
*/
BUG_ON((start ^ end) >> PAGE_SHIFT);
- raw_local_irq_save(flags);
- va_start = l2_start_va(start);
+ va_start = l2_get_va(start);
va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
+ l2_put_va(va_start);
}
static inline void l2_inv_all(void)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 99fa688dfadd..c96fa1b3f49f 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area)
* - end - virtual end address of region
*/
v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrb r2, [r0] @ read for ownership
+ strb r2, [r0] @ write for ownership
+#endif
tst r0, #D_CACHE_LINE_SIZE - 1
bic r0, r0, #D_CACHE_LINE_SIZE - 1
#ifdef HARVARD_CACHE
@@ -211,6 +215,10 @@ v6_dma_inv_range:
mcrne p15, 0, r0, c7, c11, 1 @ clean unified line
#endif
tst r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrneb r2, [r1, #-1] @ read for ownership
+ strneb r2, [r1, #-1] @ write for ownership
+#endif
bic r1, r1, #D_CACHE_LINE_SIZE - 1
#ifdef HARVARD_CACHE
mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line
@@ -218,10 +226,6 @@ v6_dma_inv_range:
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif
1:
-#ifdef CONFIG_DMA_CACHE_RWFO
- ldr r2, [r0] @ read for ownership
- str r2, [r0] @ write for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
#else
@@ -229,6 +233,10 @@ v6_dma_inv_range:
#endif
add r0, r0, #D_CACHE_LINE_SIZE
cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlo r2, [r0] @ read for ownership
+ strlo r2, [r0] @ write for ownership
+#endif
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
@@ -263,12 +271,12 @@ v6_dma_clean_range:
* - end - virtual end address of region
*/
ENTRY(v6_dma_flush_range)
- bic r0, r0, #D_CACHE_LINE_SIZE - 1
-1:
#ifdef CONFIG_DMA_CACHE_RWFO
- ldr r2, [r0] @ read for ownership
- str r2, [r0] @ write for ownership
+ ldrb r2, [r0] @ read for ownership
+ strb r2, [r0] @ write for ownership
#endif
+ bic r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
#else
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range)
#endif
add r0, r0, #D_CACHE_LINE_SIZE
cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlob r2, [r0] @ read for ownership
+ strlob r2, [r0] @ write for ownership
+#endif
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index a3ebf7a4f49b..6136e68ce953 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range)
UNWIND(.fnstart )
dcache_line_size r2, r3
sub r3, r2, #1
- bic r0, r0, r3
+ bic r12, r0, r3
1:
- USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification
+ USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification
+ add r12, r12, r2
+ cmp r12, r1
+ blo 1b
dsb
- USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line
- add r0, r0, r2
+ icache_line_size r2, r3
+ sub r3, r2, #1
+ bic r12, r0, r3
2:
- cmp r0, r1
- blo 1b
+ USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line
+ add r12, r12, r2
+ cmp r12, r1
+ blo 2b
+3:
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range)
* isn't mapped, just try the next page.
*/
9001:
- mov r0, r0, lsr #12
- mov r0, r0, lsl #12
- add r0, r0, #4096
- b 2b
+ mov r12, r12, lsr #12
+ mov r12, r12, lsl #12
+ add r12, r12, #4096
+ b 3b
UNWIND(.fnend )
ENDPROC(v7_coherent_kern_range)
ENDPROC(v7_coherent_user_range)
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index c3154928bccd..5a32020471e3 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -17,14 +17,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
+#include <linux/highmem.h>
#include <asm/system.h>
#include <asm/cputype.h>
#include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-#include "mm.h"
#define CR_L2 (1 << 26)
@@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void)
dsb();
}
+static inline void l2_unmap_va(unsigned long va)
+{
#ifdef CONFIG_HIGHMEM
-#define l2_map_save_flags(x) raw_local_save_flags(x)
-#define l2_map_restore_flags(x) raw_local_irq_restore(x)
-#else
-#define l2_map_save_flags(x) ((x) = 0)
-#define l2_map_restore_flags(x) ((void)(x))
+ if (va != -1)
+ kunmap_atomic((void *)va);
#endif
+}
-static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
- unsigned long flags)
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va)
{
#ifdef CONFIG_HIGHMEM
unsigned long va = prev_va & PAGE_MASK;
@@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
/*
* Switching to a new page. Because cache ops are
* using virtual addresses only, we must put a mapping
- * in place for it. We also enable interrupts for a
- * short while and disable them again to protect this
- * mapping.
+ * in place for it.
*/
- unsigned long idx;
- raw_local_irq_restore(flags);
- idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
- va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- raw_local_irq_restore(flags | PSR_I_BIT);
- set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
- local_flush_tlb_kernel_page(va);
+ l2_unmap_va(prev_va);
+ va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
}
return va + (pa_offset >> (32 - PAGE_SHIFT));
#else
@@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
if (start == 0 && end == -1ul) {
xsc3_l2_inv_all();
@@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
}
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
/*
* Clean and invalidate partial first cache line.
*/
if (start & (CACHE_LINE_SIZE - 1)) {
- vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags);
+ vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
start = (start | (CACHE_LINE_SIZE - 1)) + 1;
@@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
* Invalidate all full cache lines between 'start' and 'end'.
*/
while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_inv_mva(vaddr);
start += CACHE_LINE_SIZE;
}
@@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
* Clean and invalidate partial last cache line.
*/
if (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
start += CACHE_LINE_SIZE;
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
@@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void)
static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
{
- unsigned long vaddr, flags;
+ unsigned long vaddr;
if (start == 0 && end == -1ul) {
xsc3_l2_flush_all();
@@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
}
vaddr = -1; /* to force the first mapping */
- l2_map_save_flags(flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- vaddr = l2_map_va(start, vaddr, flags);
+ vaddr = l2_map_va(start, vaddr);
xsc3_l2_clean_mva(vaddr);
xsc3_l2_inv_mva(vaddr);
start += CACHE_LINE_SIZE;
}
- l2_map_restore_flags(flags);
+ l2_unmap_va(vaddr);
dsb();
}
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ac6a36142fcd..b5b673b9c118 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -148,6 +149,7 @@ static int __init consistent_init(void)
{
int ret = 0;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int i = 0;
@@ -155,7 +157,15 @@ static int __init consistent_init(void)
do {
pgd = pgd_offset(&init_mm, base);
- pmd = pmd_alloc(&init_mm, pgd, base);
+
+ pud = pud_alloc(&init_mm, pgd, base);
+ if (!pud) {
+ printk(KERN_ERR "%s: no pud tables\n", __func__);
+ ret = -ENOMEM;
+ break;
+ }
+
+ pmd = pmd_alloc(&init_mm, pud, base);
if (!pmd) {
printk(KERN_ERR "%s: no pmd tables\n", __func__);
ret = -ENOMEM;
@@ -311,7 +321,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
addr = page_address(page);
if (addr)
- *handle = page_to_dma(dev, page);
+ *handle = pfn_to_dma(dev, page_to_pfn(page));
return addr;
}
@@ -406,7 +416,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
if (!arch_is_coherent())
__dma_free_remap(cpu_addr, size);
- __dma_free_buffer(dma_to_page(dev, handle), size);
+ __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
}
EXPORT_SYMBOL(dma_free_coherent);
@@ -480,10 +490,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long 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);
+ /* unmapped pages might still be cached */
+ vaddr = kmap_atomic(page);
op(vaddr + offset, len, dir);
- kunmap_high_l1_vipt(page, saved_pte);
+ kunmap_atomic(vaddr);
}
} else {
vaddr = page_address(page) + offset;
@@ -554,17 +564,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
struct scatterlist *s;
int i, j;
+ BUG_ON(!valid_dma_direction(dir));
+
for_each_sg(sg, s, nents, i) {
- s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+ s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
s->length, dir);
if (dma_mapping_error(dev, s->dma_address))
goto bad_mapping;
}
+ debug_dma_map_sg(dev, sg, nents, nents, dir);
return nents;
bad_mapping:
for_each_sg(sg, s, i, j)
- dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
return 0;
}
EXPORT_SYMBOL(dma_map_sg);
@@ -585,8 +598,10 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
struct scatterlist *s;
int i;
+ debug_dma_unmap_sg(dev, sg, nents, dir);
+
for_each_sg(sg, s, nents, i)
- dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
}
EXPORT_SYMBOL(dma_unmap_sg);
@@ -611,6 +626,8 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
__dma_page_dev_to_cpu(sg_page(s), s->offset,
s->length, dir);
}
+
+ debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
}
EXPORT_SYMBOL(dma_sync_sg_for_cpu);
@@ -635,5 +652,16 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
__dma_page_cpu_to_dev(sg_page(s), s->offset,
s->length, dir);
}
+
+ debug_dma_sync_sg_for_device(dev, sg, nents, dir);
}
EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES 4096
+
+static int __init dma_debug_do_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ return 0;
+}
+core_initcall(dma_debug_do_init);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 83e59f870426..7cab79179421 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -26,7 +26,7 @@
#include "mm.h"
-static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
+static pteval_t shared_pte_mask = L_PTE_MT_BUFFERABLE;
#if __LINUX_ARM_ARCH__ < 6
/*
@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
{
spinlock_t *ptl;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int ret;
@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
if (pgd_none_or_clear_bad(pgd))
return 0;
- pmd = pmd_offset(pgd, address);
+ pud = pud_offset(pgd, address);
+ if (pud_none_or_clear_bad(pud))
+ return 0;
+
+ pmd = pmd_offset(pud, address);
if (pmd_none_or_clear_bad(pmd))
return 0;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 1e21e125fe3a..00e9bc76982d 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -79,6 +79,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
do {
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
@@ -90,7 +91,19 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
break;
}
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ if (PTRS_PER_PUD != 1)
+ printk(", *pud=%08lx", pud_val(*pud));
+
+ if (pud_none(*pud))
+ break;
+
+ if (pud_bad(*pud)) {
+ printk("(bad)");
+ break;
+ }
+
+ pmd = pmd_offset(pud, addr);
if (PTRS_PER_PMD != 1)
printk(", *pmd=%08lx", pmd_val(*pmd));
@@ -108,7 +121,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
pte = pte_offset_map(pmd, addr);
printk(", *pte=%08lx", pte_val(*pte));
- printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE]));
+ printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS]));
pte_unmap(pte);
} while(0);
@@ -388,6 +401,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
{
unsigned int index;
pgd_t *pgd, *pgd_k;
+ pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
if (addr < TASK_SIZE)
@@ -406,12 +420,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if (pgd_none(*pgd_k))
goto bad_area;
-
if (!pgd_present(*pgd))
set_pgd(pgd, *pgd_k);
- pmd_k = pmd_offset(pgd_k, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pud_k = pud_offset(pgd_k, addr);
+
+ if (pud_none(*pud_k))
+ goto bad_area;
+ if (!pud_present(*pud))
+ set_pud(pud, *pud_k);
+
+ pmd = pmd_offset(pud, addr);
+ pmd_k = pmd_offset(pud_k, addr);
/*
* On ARM one Linux PGD entry contains two hardware entries (see page
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 391ffae75098..c29f2839f1d2 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
@@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
__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);
+ /* unmapped pages might still be cached */
+ addr = kmap_atomic(page);
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
- kunmap_high_l1_vipt(page, saved_pte);
+ kunmap_atomic(addr);
}
}
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index c435fd9e1da9..807c0573abbe 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -140,90 +140,3 @@ 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;
- int *depth;
- unsigned long vaddr, flags;
- pte_t pte, *ptep;
-
- if (!in_interrupt())
- preempt_disable();
-
- cpu = smp_processor_id();
- depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
-
- 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);
-
- 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/idmap.c b/arch/arm/mm/idmap.c
new file mode 100644
index 000000000000..2be9139a4ef3
--- /dev/null
+++ b/arch/arm/mm/idmap.c
@@ -0,0 +1,90 @@
+#include <linux/kernel.h>
+
+#include <asm/cputype.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+ unsigned long prot)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+
+ addr = (addr & PMD_MASK) | prot;
+ pmd[0] = __pmd(addr);
+ addr += SECTION_SIZE;
+ pmd[1] = __pmd(addr);
+ flush_pmd_entry(pmd);
+}
+
+static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+ unsigned long prot)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ idmap_add_pmd(pud, addr, next, prot);
+ } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ unsigned long prot, next;
+
+ prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
+ if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+ prot |= PMD_BIT4;
+
+ pgd += pgd_index(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ idmap_add_pud(pgd, addr, next, prot);
+ } while (pgd++, addr = next, addr != end);
+}
+
+#ifdef CONFIG_SMP
+static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+ pmd_clear(pmd);
+}
+
+static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ idmap_del_pmd(pud, addr, next);
+ } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ unsigned long next;
+
+ pgd += pgd_index(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ idmap_del_pud(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+#endif
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages. This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+ /*
+ * 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".
+ */
+ identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
+ local_flush_tlb_all();
+}
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 55c17a6fb22f..ab506272b2d3 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -204,12 +204,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
- if (pfn_valid(pfn)) {
- printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n"
- "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
- "will fail in the next kernel release. Please fix your driver.\n");
- WARN_ON(1);
- }
+ if (WARN_ON(pfn_valid(pfn)))
+ return NULL;
type = get_mem_type(mtype);
if (!type)
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 6630620380a4..d2384106af9c 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -7,7 +7,7 @@ extern pmd_t *top_pmd;
static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
{
- return pmd_offset(pgd, virt);
+ return pmd_offset(pud_offset(pgd, virt), virt);
}
static inline pmd_t *pmd_off_k(unsigned long virt)
@@ -16,7 +16,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
}
struct mem_type {
- unsigned int prot_pte;
+ pteval_t prot_pte;
unsigned int prot_l1;
unsigned int prot_sect;
unsigned int domain;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 72ad3e1f56cf..e94888bc5cd3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -24,6 +24,7 @@
#include <asm/smp_plat.h>
#include <asm/tlb.h>
#include <asm/highmem.h>
+#include <asm/traps.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -62,7 +63,7 @@ struct cachepolicy {
const char policy[16];
unsigned int cr_mask;
unsigned int pmd;
- unsigned int pte;
+ pteval_t pte;
};
static struct cachepolicy cache_policies[] __initdata = {
@@ -190,7 +191,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
}
#endif
-#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE
+#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
static struct mem_type mem_types[] = {
@@ -235,19 +236,18 @@ static struct mem_type mem_types[] = {
},
[MT_LOW_VECTORS] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_EXEC,
+ L_PTE_RDONLY,
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_USER,
},
[MT_HIGH_VECTORS] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_USER | L_PTE_EXEC,
+ L_PTE_USER | L_PTE_RDONLY,
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_USER,
},
[MT_MEMORY] = {
- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE | L_PTE_EXEC,
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
@@ -258,21 +258,20 @@ static struct mem_type mem_types[] = {
},
[MT_MEMORY_NONCACHED] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+ L_PTE_MT_BUFFERABLE,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_DTCM] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE,
+ L_PTE_XN,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_ITCM] = {
- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE | L_PTE_EXEC,
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_KERNEL,
},
@@ -479,7 +478,7 @@ static void __init build_mem_type_table(void)
pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
- L_PTE_DIRTY | L_PTE_WRITE | kern_pgprot);
+ L_PTE_DIRTY | kern_pgprot);
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
@@ -535,7 +534,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
{
if (pmd_none(*pmd)) {
pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
- __pmd_populate(pmd, __pa(pte) | prot);
+ __pmd_populate(pmd, __pa(pte), prot);
}
BUG_ON(pmd_bad(*pmd));
return pte_offset_kernel(pmd, addr);
@@ -552,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
} while (pte++, addr += PAGE_SIZE, addr != end);
}
-static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
- unsigned long end, unsigned long phys,
+static void __init alloc_init_section(pud_t *pud, unsigned long addr,
+ unsigned long end, phys_addr_t phys,
const struct mem_type *type)
{
- pmd_t *pmd = pmd_offset(pgd, addr);
+ pmd_t *pmd = pmd_offset(pud, addr);
/*
* Try a section mapping - end, addr and phys must all be aligned
@@ -585,10 +584,24 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
}
}
+static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+ unsigned long phys, const struct mem_type *type)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ alloc_init_section(pud, addr, next, phys, type);
+ phys += next - addr;
+ } while (pud++, addr = next, addr != end);
+}
+
static void __init create_36bit_mapping(struct map_desc *md,
const struct mem_type *type)
{
- unsigned long phys, addr, length, end;
+ unsigned long addr, length, end;
+ phys_addr_t phys;
pgd_t *pgd;
addr = md->virtual;
@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
pgd = pgd_offset_k(addr);
end = addr + length;
do {
- pmd_t *pmd = pmd_offset(pgd, addr);
+ pud_t *pud = pud_offset(pgd, addr);
+ pmd_t *pmd = pmd_offset(pud, addr);
int i;
for (i = 0; i < 16; i++)
@@ -696,7 +710,7 @@ static void __init create_mapping(struct map_desc *md)
do {
unsigned long next = pgd_addr_end(addr, end);
- alloc_init_section(pgd, addr, next, phys, type);
+ alloc_init_pud(pgd, addr, next, phys, type);
phys += next - addr;
addr = next;
@@ -914,12 +928,11 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
{
struct map_desc map;
unsigned long addr;
- void *vectors;
/*
* Allocate the vector page early.
*/
- vectors = early_alloc(PAGE_SIZE);
+ vectors_page = early_alloc(PAGE_SIZE);
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -959,7 +972,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
* location (0xffff0000). If we aren't using high-vectors, also
* create a mapping at the low-vectors virtual address.
*/
- map.pfn = __phys_to_pfn(virt_to_phys(vectors));
+ map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
map.virtual = 0xffff0000;
map.length = PAGE_SIZE;
map.type = MT_HIGH_VECTORS;
@@ -1044,38 +1057,3 @@ void __init paging_init(struct machine_desc *mdesc)
empty_zero_page = virt_to_page(zero_page);
__flush_dcache_page(NULL, empty_zero_page);
}
-
-/*
- * In order to soft-boot, we need to insert a 1:1 mapping in place of
- * the user-mode pages. This will then ensure that we have predictable
- * results when turning the mmu off
- */
-void setup_mm_for_reboot(char mode)
-{
- unsigned long base_pmdval;
- pgd_t *pgd;
- int i;
-
- /*
- * 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())
- base_pmdval |= PMD_BIT4;
-
- for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
- unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
- pmd_t *pmd;
-
- pmd = pmd_off(pgd, i << PGDIR_SHIFT);
- pmd[0] = __pmd(pmdval);
- pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
- flush_pmd_entry(pmd);
- }
-
- local_flush_tlb_all();
-}
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 69bbfc6645a6..f7fafb1741f4 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -17,14 +17,13 @@
#include "mm.h"
-#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
-
/*
* need to get a 16k page for level 1
*/
-pgd_t *get_pgd_slow(struct mm_struct *mm)
+pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *new_pgd, *init_pgd;
+ pud_t *new_pud, *init_pud;
pmd_t *new_pmd, *init_pmd;
pte_t *new_pte, *init_pte;
@@ -32,14 +31,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!new_pgd)
goto no_pgd;
- memset(new_pgd, 0, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
+ memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
/*
* Copy over the kernel and IO PGD entries
*/
init_pgd = pgd_offset_k(0);
- memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
- (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+ memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
@@ -48,7 +47,11 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
* On ARM, first page must always be allocated since it
* contains the machine vectors.
*/
- new_pmd = pmd_alloc(mm, new_pgd, 0);
+ new_pud = pud_alloc(mm, new_pgd, 0);
+ if (!new_pud)
+ goto no_pud;
+
+ new_pmd = pmd_alloc(mm, new_pud, 0);
if (!new_pmd)
goto no_pmd;
@@ -56,7 +59,8 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!new_pte)
goto no_pte;
- init_pmd = pmd_offset(init_pgd, 0);
+ init_pud = pud_offset(init_pgd, 0);
+ init_pmd = pmd_offset(init_pud, 0);
init_pte = pte_offset_map(init_pmd, 0);
set_pte_ext(new_pte, *init_pte, 0);
pte_unmap(init_pte);
@@ -68,33 +72,44 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
no_pte:
pmd_free(mm, new_pmd);
no_pmd:
+ pud_free(mm, new_pud);
+no_pud:
free_pages((unsigned long)new_pgd, 2);
no_pgd:
return NULL;
}
-void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
+void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
{
+ pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pgtable_t pte;
- if (!pgd)
+ if (!pgd_base)
return;
- /* pgd is always present and good */
- pmd = pmd_off(pgd, 0);
- if (pmd_none(*pmd))
- goto free;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- goto free;
- }
+ pgd = pgd_base + pgd_index(0);
+ if (pgd_none_or_clear_bad(pgd))
+ goto no_pgd;
+
+ pud = pud_offset(pgd, 0);
+ if (pud_none_or_clear_bad(pud))
+ goto no_pud;
+
+ pmd = pmd_offset(pud, 0);
+ if (pmd_none_or_clear_bad(pmd))
+ goto no_pmd;
pte = pmd_pgtable(*pmd);
pmd_clear(pmd);
pte_free(mm, pte);
+no_pmd:
+ pud_clear(pud);
pmd_free(mm, pmd);
-free:
- free_pages((unsigned long) pgd, 2);
+no_pud:
+ pgd_clear(pgd);
+ pud_free(mm, pud);
+no_pgd:
+ free_pages((unsigned long) pgd_base, 2);
}
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7d63beaf9745..e32fa499194c 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -61,17 +61,27 @@
.endm
/*
- * cache_line_size - get the cache line size from the CSIDR register
- * (available on ARMv7+). It assumes that the CSSR register was configured
- * to access the L1 data cache CSIDR.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
*/
.macro dcache_line_size, reg, tmp
- mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR
- and \tmp, \tmp, #7 @ cache line size encoding
- mov \reg, #16 @ size offset
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ lsr \tmp, \tmp, #16
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
mov \reg, \reg, lsl \tmp @ actual cache line size
.endm
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+ .macro icache_line_size, reg, tmp
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
+ mov \reg, \reg, lsl \tmp @ actual cache line size
+ .endm
/*
* Sanity check the PTE configuration for the code below - which makes
@@ -81,7 +91,7 @@
#if L_PTE_SHARED != PTE_EXT_SHARED
#error PTE shared bit mismatch
#endif
-#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
+#if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
#error Invalid Linux PTE bit settings
#endif
@@ -99,6 +109,10 @@
* 110x 0 1 0 r/w r/o
* 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w
+ *
+ * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
+ * 110x 1 1 1 r/o r/o
+ * 11x0 1 1 1 r/o r/o
*/
.macro armv6_mt_table pfx
\pfx\()_mt_table:
@@ -121,7 +135,7 @@
.endm
.macro armv6_set_pte_ext pfx
- str r1, [r0], #-2048 @ linux version
+ str r1, [r0], #2048 @ linux version
bic r3, r1, #0x000003fc
bic r3, r3, #PTE_TYPE_MASK
@@ -132,17 +146,20 @@
and r2, r1, #L_PTE_MT_MASK
ldr r2, [ip, r2]
- tst r1, #L_PTE_WRITE
- tstne r1, #L_PTE_DIRTY
- orreq r3, r3, #PTE_EXT_APX
+ eor r1, r1, #L_PTE_DIRTY
+ tst r1, #L_PTE_DIRTY|L_PTE_RDONLY
+ orrne r3, r3, #PTE_EXT_APX
tst r1, #L_PTE_USER
orrne r3, r3, #PTE_EXT_AP1
+#ifdef CONFIG_CPU_USE_DOMAINS
+ @ allow kernel read/write access to read-only user pages
tstne r3, #PTE_EXT_APX
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
+#endif
- tst r1, #L_PTE_EXEC
- orreq r3, r3, #PTE_EXT_XN
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
orr r3, r3, r2
@@ -170,9 +187,9 @@
* 1111 0xff r/w r/w
*/
.macro armv3_set_pte_ext wc_disable=1
- str r1, [r0], #-2048 @ linux version
+ str r1, [r0], #2048 @ linux version
- eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+ eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
bic r2, r2, #PTE_TYPE_MASK
@@ -181,7 +198,7 @@
tst r3, #L_PTE_USER @ user?
orrne r2, r2, #PTE_SMALL_AP_URO_SRW
- tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty?
+ tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
@@ -193,7 +210,7 @@
bicne r2, r2, #PTE_BUFFERABLE
#endif
.endif
- str r2, [r0] @ hardware version
+ str r2, [r0] @ hardware version
.endm
@@ -213,9 +230,9 @@
* 1111 11 r/w r/w
*/
.macro xscale_set_pte_ext_prologue
- str r1, [r0], #-2048 @ linux version
+ str r1, [r0] @ linux version
- eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+ eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
orr r2, r2, #PTE_TYPE_EXT @ extended page
@@ -223,7 +240,7 @@
tst r3, #L_PTE_USER @ user?
orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
- tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty?
+ tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
@ combined with user -> user r/w
.endm
@@ -232,7 +249,7 @@
tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
movne r2, #0 @ no -> fault
- str r2, [r0] @ hardware version
+ str r2, [r0, #2048]! @ hardware version
mov ip, #0
mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
mcr p15, 0, ip, c7, c10, 4 @ data write barrier
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 53cbe2225153..b49fab21517c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
* Set a level 2 translation table entry.
*
* - ptep - pointer to level 2 translation table entry
- * (hardware version is stored at -1024 bytes)
+ * (hardware version is stored at +2048 bytes)
* - pte - PTE value to store
* - ext - value for extended PTE bits
*/
ENTRY(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU
- ARM( str r1, [r0], #-2048 ) @ linux version
- THUMB( str r1, [r0] ) @ linux version
- THUMB( sub r0, r0, #2048 )
+ str r1, [r0] @ linux version
bic r3, r1, #0x000003f0
bic r3, r3, #PTE_TYPE_MASK
@@ -142,23 +140,26 @@ ENTRY(cpu_v7_set_pte_ext)
tst r1, #1 << 4
orrne r3, r3, #PTE_EXT_TEX(1)
- tst r1, #L_PTE_WRITE
- tstne r1, #L_PTE_DIRTY
- orreq r3, r3, #PTE_EXT_APX
+ eor r1, r1, #L_PTE_DIRTY
+ tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
+ orrne r3, r3, #PTE_EXT_APX
tst r1, #L_PTE_USER
orrne r3, r3, #PTE_EXT_AP1
+#ifdef CONFIG_CPU_USE_DOMAINS
+ @ allow kernel read/write access to read-only user pages
tstne r3, #PTE_EXT_APX
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
+#endif
- tst r1, #L_PTE_EXEC
- orreq r3, r3, #PTE_EXT_XN
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
tst r1, #L_PTE_YOUNG
tstne r1, #L_PTE_PRESENT
moveq r3, #0
- str r3, [r0]
+ str r3, [r0, #2048]!
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
#endif
mov pc, lr
@@ -273,8 +274,6 @@ __v7_setup:
ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
- mov r10, #0x1f @ domains 0, 1 = manager
- mcr p15, 0, r10, c3, c0, 0 @ load domain access register
/*
* Memory region attributes with SCTLR.TRE=1
*
@@ -313,6 +312,10 @@ __v7_setup:
#ifdef CONFIG_CPU_ENDIAN_BE8
orr r6, r6, #1 << 25 @ big-endian page tables
#endif
+#ifdef CONFIG_SWP_EMULATE
+ orr r5, r5, #(1 << 10) @ set SW bit in "clear"
+ bic r6, r6, #(1 << 10) @ clear it in "mmuset"
+#endif
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, r0, r5 @ clear bits them
orr r0, r0, r6 @ set them
@@ -381,7 +384,7 @@ __v7_ca9mp_proc_info:
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __v7_ca9mp_setup
+ W(b) __v7_ca9mp_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
@@ -413,7 +416,7 @@ __v7_proc_info:
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __v7_setup
+ W(b) __v7_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 523408c0bb38..5a37c5e45c41 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
@
@ Erratum 40: must set memory to write-through for user read-only pages
@
- and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2)
- teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER
+ and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_RDONLY) & ~(4 << 2)
+ teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER | L_PTE_RDONLY
moveq r1, #L_PTE_MT_WRITETHROUGH
and r1, r1, #L_PTE_MT_MASK
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 85d3e55ca4a9..07f23bb42bed 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -17,12 +17,15 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <linux/timex.h>
+#include <linux/sched.h>
#include <linux/io.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <mach/hardware.h>
#include <asm/irq.h>
+#include <asm/sched_clock.h>
#include <asm/uaccess.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
@@ -36,7 +39,7 @@
/*
* IOP clocksource (free-running timer 1).
*/
-static cycle_t iop_clocksource_read(struct clocksource *unused)
+static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
{
return 0xffffffffu - read_tcr1();
}
@@ -49,15 +52,21 @@ static struct clocksource iop_clocksource = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
+static DEFINE_CLOCK_DATA(cd);
+
/*
* IOP sched_clock() implementation via its clocksource.
*/
-unsigned long long sched_clock(void)
+unsigned long long notrace sched_clock(void)
{
- cycle_t cyc = iop_clocksource_read(NULL);
- struct clocksource *cs = &iop_clocksource;
+ u32 cyc = 0xffffffffu - read_tcr1();
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
- return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+static void notrace iop_update_sched_clock(void)
+{
+ u32 cyc = 0xffffffffu - read_tcr1();
+ update_sched_clock(&cd, cyc, (u32)~0);
}
/*
@@ -87,6 +96,7 @@ static void iop_set_mode(enum clock_event_mode mode,
case CLOCK_EVT_MODE_PERIODIC:
write_tmr0(tmr & ~IOP_TMR_EN);
write_tcr0(ticks_per_jiffy - 1);
+ write_trr0(ticks_per_jiffy - 1);
tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
break;
case CLOCK_EVT_MODE_ONESHOT:
@@ -142,6 +152,8 @@ void __init iop_init_time(unsigned long tick_rate)
{
u32 timer_ctl;
+ init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate);
+
ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
iop_tick_rate = tick_rate;
@@ -152,6 +164,7 @@ void __init iop_init_time(unsigned long tick_rate)
* Set up interrupting clockevent timer 0.
*/
write_tmr0(timer_ctl & ~IOP_TMR_EN);
+ write_tisr(1);
setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
clockevents_calc_mult_shift(&iop_clockevent,
tick_rate, IOP_MIN_RANGE);
@@ -161,9 +174,6 @@ void __init iop_init_time(unsigned long tick_rate)
clockevent_delta2ns(0xf, &iop_clockevent);
iop_clockevent.cpumask = cpumask_of(0);
clockevents_register_device(&iop_clockevent);
- write_trr0(ticks_per_jiffy - 1);
- write_tcr0(ticks_per_jiffy - 1);
- write_tmr0(timer_ctl);
/*
* Set up free-running clocksource timer 1.
@@ -171,7 +181,5 @@ void __init iop_init_time(unsigned long tick_rate)
write_trr1(0xffffffff);
write_tcr1(0xffffffff);
write_tmr1(timer_ctl);
- clocksource_calc_mult_shift(&iop_clocksource, tick_rate,
- IOP_MIN_RANGE);
- clocksource_register(&iop_clocksource);
+ clocksource_register_hz(&iop_clocksource, tick_rate);
}
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 64e3a64520e0..389f21795015 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -21,10 +21,6 @@ config ARCH_MX2
config ARCH_MX25
bool "MX25-based"
- select CPU_ARM926T
- select ARCH_MXC_IOMUX_V3
- select HAVE_FB_IMX
- select ARCH_MXC_AUDMUX_V2
help
This enables support for systems based on the Freescale i.MX25 family
@@ -51,7 +47,6 @@ endchoice
source "arch/arm/mach-imx/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"
@@ -68,12 +63,10 @@ config MXC_IRQ_PRIOR
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.
+ bool
+
+config MXC_AVIC
+ bool
config MXC_PWM
tristate "Enable PWM driver"
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 372670952789..5fd20e96876c 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,10 +3,11 @@
#
# Common support
-obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
+obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o
-# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
+# MX51 uses the TZIC interrupt controller, older platforms use AVIC
obj-$(CONFIG_MXC_TZIC) += tzic.o
+obj-$(CONFIG_MXC_AVIC) += avic.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 0be1ac7f421b..175e3647bb27 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -209,7 +209,7 @@ static int mxc_audmux_v2_init(void)
audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
}
#endif
-#if defined(CONFIG_ARCH_MX25)
+#if defined(CONFIG_SOC_IMX25)
if (cpu_is_mx25()) {
audmux_clk = clk_get(NULL, "audmux");
if (IS_ERR(audmux_clk)) {
@@ -220,7 +220,7 @@ static int mxc_audmux_v2_init(void)
}
audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
}
-#endif
+#endif /* if defined(CONFIG_SOC_IMX25) */
audmux_debugfs_init();
return 0;
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/avic.c
index 7331f2ace5fe..9a4e8a22dd0a 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -24,6 +24,8 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
+#include "irq-common.h"
+
#define AVIC_INTCNTL 0x00 /* int control reg */
#define AVIC_NIMASK 0x04 /* int mask reg */
#define AVIC_INTENNUM 0x08 /* int enable number reg */
@@ -46,9 +48,9 @@
void __iomem *avic_base;
-int imx_irq_set_priority(unsigned char irq, unsigned char prio)
-{
#ifdef CONFIG_MXC_IRQ_PRIOR
+static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
+{
unsigned int temp;
unsigned int mask = 0x0F << irq % 8 * 4;
@@ -62,14 +64,11 @@ int imx_irq_set_priority(unsigned char irq, unsigned char prio)
__raw_writel(temp, avic_base + AVIC_NIPRIORITY(irq / 8));
return 0;
-#else
- return -ENOSYS;
-#endif
}
-EXPORT_SYMBOL(imx_irq_set_priority);
+#endif
#ifdef CONFIG_FIQ
-int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
+static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
{
unsigned int irqt;
@@ -87,7 +86,6 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
return 0;
}
-EXPORT_SYMBOL(mxc_set_irq_fiq);
#endif /* CONFIG_FIQ */
/* Disable interrupt number "irq" in the AVIC */
@@ -102,10 +100,18 @@ static void mxc_unmask_irq(unsigned int irq)
__raw_writel(irq, avic_base + AVIC_INTENNUM);
}
-static struct irq_chip mxc_avic_chip = {
- .ack = mxc_mask_irq,
- .mask = mxc_mask_irq,
- .unmask = mxc_unmask_irq,
+static struct mxc_irq_chip mxc_avic_chip = {
+ .base = {
+ .ack = mxc_mask_irq,
+ .mask = mxc_mask_irq,
+ .unmask = mxc_unmask_irq,
+ },
+#ifdef CONFIG_MXC_IRQ_PRIOR
+ .set_priority = avic_irq_set_priority,
+#endif
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = avic_set_irq_fiq,
+#endif
};
/*
@@ -133,7 +139,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
__raw_writel(0, avic_base + AVIC_INTTYPEH);
__raw_writel(0, avic_base + AVIC_INTTYPEL);
for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
- set_irq_chip(i, &mxc_avic_chip);
+ set_irq_chip(i, &mxc_avic_chip.base);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index 039538e68793..ce81481becf1 100644
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -144,7 +144,6 @@ static int __init mxc_cpufreq_init(struct cpufreq_policy *policy)
imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
policy->cur = clk_get_rate(cpu_clk) / 1000;
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
index 735776d84956..e9bcefe79a43 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/plat-mxc/devices.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -36,9 +37,10 @@ int __init mxc_register_device(struct platform_device *pdev, void *data)
return ret;
}
-struct platform_device *__init imx_add_platform_device(const char *name, int id,
+struct platform_device *__init imx_add_platform_device_dmamask(
+ const char *name, int id,
const struct resource *res, unsigned int num_resources,
- const void *data, size_t size_data)
+ const void *data, size_t size_data, u64 dmamask)
{
int ret = -ENOMEM;
struct platform_device *pdev;
@@ -47,6 +49,23 @@ struct platform_device *__init imx_add_platform_device(const char *name, int id,
if (!pdev)
goto err;
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
if (res) {
ret = platform_device_add_resources(pdev, res, num_resources);
if (ret)
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 9aa6f3ea9012..2537166468ac 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -1,29 +1,73 @@
-config IMX_HAVE_PLATFORM_ESDHC
- bool
-
config IMX_HAVE_PLATFORM_FEC
bool
- default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51
+ default y if ARCH_MX25 || SOC_IMX27 || SOC_IMX35 || SOC_IMX51
config IMX_HAVE_PLATFORM_FLEXCAN
select HAVE_CAN_FLEXCAN if CAN
bool
+config IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ bool
+
config IMX_HAVE_PLATFORM_GPIO_KEYS
bool
- default y if ARCH_MX51
+ default y if SOC_IMX51
+
+config IMX_HAVE_PLATFORM_IMX21_HCD
+ bool
+config IMX_HAVE_PLATFORM_IMX2_WDT
+ bool
+
+config IMX_HAVE_PLATFORM_IMXDI_RTC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_FB
+ bool
+ select HAVE_FB_IMX
+
config IMX_HAVE_PLATFORM_IMX_I2C
bool
+config IMX_HAVE_PLATFORM_IMX_KEYPAD
+ bool
+
config IMX_HAVE_PLATFORM_IMX_SSI
bool
config IMX_HAVE_PLATFORM_IMX_UART
bool
+config IMX_HAVE_PLATFORM_IMX_UDC
+ bool
+
+config IMX_HAVE_PLATFORM_MX1_CAMERA
+ bool
+
+config IMX_HAVE_PLATFORM_MX2_CAMERA
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_EHCI
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_MMC
+ bool
+
config IMX_HAVE_PLATFORM_MXC_NAND
bool
+config IMX_HAVE_PLATFORM_MXC_PWM
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_RNGA
+ bool
+ select ARCH_HAS_RNGA
+
+config IMX_HAVE_PLATFORM_MXC_W1
+ bool
+
+config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ bool
+
config IMX_HAVE_PLATFORM_SPI_IMX
bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 45aefeb283ba..75cd2ece9053 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,10 +1,24 @@
-obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
obj-y += platform-imx-dma.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FB) += platform-imx-fb.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD) += platform-imx-keypad.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UDC) += platform-imx_udc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MX1_CAMERA) += platform-mx1-camera.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_CAMERA) += platform-mx2-camera.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI) += platform-mxc-ehci.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_MMC) += platform-mxc-mmc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_PWM) += platform-mxc_pwm.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) += platform-mxc_rnga.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
diff --git a/arch/arm/plat-mxc/devices/platform-esdhc.c b/arch/arm/plat-mxc/devices/platform-esdhc.c
deleted file mode 100644
index 2605bfa0dfb0..000000000000
--- a/arch/arm/plat-mxc/devices/platform-esdhc.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation.
- */
-
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
-#include <mach/esdhc.h>
-
-#define imx_esdhc_imx_data_entry_single(soc, _id, hwid) \
- { \
- .id = _id, \
- .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \
- .irq = soc ## _INT_ESDHC ## hwid, \
- }
-
-#define imx_esdhc_imx_data_entry(soc, id, hwid) \
- [id] = imx_esdhc_imx_data_entry_single(soc, id, hwid)
-
-#ifdef CONFIG_ARCH_MX25
-const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst = {
-#define imx25_esdhc_data_entry(_id, _hwid) \
- imx_esdhc_imx_data_entry(MX25, _id, _hwid)
- imx25_esdhc_data_entry(0, 1),
- imx25_esdhc_data_entry(1, 2),
-};
-#endif /* ifdef CONFIG_ARCH_MX25 */
-
-#ifdef CONFIG_ARCH_MX35
-const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst = {
-#define imx35_esdhc_data_entry(_id, _hwid) \
- imx_esdhc_imx_data_entry(MX35, _id, _hwid)
- imx35_esdhc_data_entry(0, 1),
- imx35_esdhc_data_entry(1, 2),
- imx35_esdhc_data_entry(2, 3),
-};
-#endif /* ifdef CONFIG_ARCH_MX35 */
-
-#ifdef CONFIG_ARCH_MX51
-const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst = {
-#define imx51_esdhc_data_entry(_id, _hwid) \
- imx_esdhc_imx_data_entry(MX51, _id, _hwid)
- imx51_esdhc_data_entry(0, 1),
- imx51_esdhc_data_entry(1, 2),
- imx51_esdhc_data_entry(2, 3),
- imx51_esdhc_data_entry(3, 4),
-};
-#endif /* ifdef CONFIG_ARCH_MX51 */
-
-struct platform_device *__init imx_add_esdhc(
- const struct imx_esdhc_imx_data *data,
- const struct esdhc_platform_data *pdata)
-{
- struct resource res[] = {
- {
- .start = data->iobase,
- .end = data->iobase + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = data->irq,
- .end = data->irq,
- .flags = IORESOURCE_IRQ,
- },
- };
-
- return imx_add_platform_device("sdhci-esdhc-imx", data->id, res,
- ARRAY_SIZE(res), pdata, sizeof(*pdata));
-}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
index 11d087f4e219..269ec78aba77 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -16,22 +16,22 @@
.irq = soc ## _INT_FEC, \
}
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_fec_data imx25_fec_data __initconst =
imx_fec_data_entry_single(MX25);
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_fec_data imx27_fec_data __initconst =
imx_fec_data_entry_single(MX27);
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_fec_data imx35_fec_data __initconst =
imx_fec_data_entry_single(MX35);
#endif
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
const struct imx_fec_data imx51_fec_data __initconst =
imx_fec_data_entry_single(MX51);
#endif
diff --git a/arch/arm/plat-mxc/devices/platform-flexcan.c b/arch/arm/plat-mxc/devices/platform-flexcan.c
index 5e97a01f14f3..4e8497af2eb1 100644
--- a/arch/arm/plat-mxc/devices/platform-flexcan.c
+++ b/arch/arm/plat-mxc/devices/platform-flexcan.c
@@ -5,26 +5,54 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
-
+#include <mach/hardware.h>
#include <mach/devices-common.h>
-struct platform_device *__init imx_add_flexcan(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+#define imx_flexcan_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _CAN ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CAN ## _hwid, \
+ }
+
+#define imx_flexcan_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_flexcan_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_flexcan_data imx25_flexcan_data[] __initconst = {
+#define imx25_flexcan_data_entry(_id, _hwid) \
+ imx_flexcan_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_flexcan_data_entry(0, 1),
+ imx25_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_flexcan_data imx35_flexcan_data[] __initconst = {
+#define imx35_flexcan_data_entry(_id, _hwid) \
+ imx_flexcan_data_entry(MX35, _id, _hwid, SZ_16K)
+ imx35_flexcan_data_entry(0, 1),
+ imx35_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_flexcan(
+ const struct imx_flexcan_data *data,
const struct flexcan_platform_data *pdata)
{
struct resource res[] = {
{
- .start = iobase,
- .end = iobase + iosize - 1,
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = irq,
- .end = irq,
+ .start = data->irq,
+ .end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device("flexcan", id, res, ARRAY_SIZE(res),
- pdata, sizeof(*pdata));
+ return imx_add_platform_device("flexcan", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
new file mode 100644
index 000000000000..59c33f6e401c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fsl_usb2_udc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX35);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_fsl_usb2_udc(
+ const struct imx_fsl_usb2_udc_data *data,
+ const struct fsl_usb2_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("fsl-usb2-udc", -1,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
index 3a705c7877dd..33530d2d5ed1 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-dma.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
@@ -31,25 +31,25 @@ struct imx_imx_sdma_data {
}, \
}
-#ifdef CONFIG_ARCH_MX25
-const struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
+#ifdef CONFIG_SOC_IMX25
+struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0);
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
struct imx_imx_sdma_data imx31_imx_sdma_data __initdata =
imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0);
-#endif /* ifdef CONFIG_ARCH_MX31 */
+#endif /* ifdef CONFIG_SOC_IMX31 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
struct imx_imx_sdma_data imx35_imx_sdma_data __initdata =
imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0);
-#endif /* ifdef CONFIG_ARCH_MX35 */
+#endif /* ifdef CONFIG_SOC_IMX35 */
-#ifdef CONFIG_ARCH_MX51
-const struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
+#ifdef CONFIG_SOC_IMX51
+struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0);
-#endif /* ifdef CONFIG_ARCH_MX51 */
+#endif /* ifdef CONFIG_SOC_IMX51 */
static struct platform_device __init __maybe_unused *imx_add_imx_sdma(
const struct imx_imx_sdma_data *data)
@@ -76,6 +76,83 @@ static struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0);
}
+#ifdef CONFIG_ARCH_MX25
+static struct sdma_script_start_addrs addr_imx25_to1 = {
+ .ap_2_ap_addr = 729,
+ .uart_2_mcu_addr = 904,
+ .per_2_app_addr = 1255,
+ .mcu_2_app_addr = 834,
+ .uartsh_2_mcu_addr = 1120,
+ .per_2_shp_addr = 1329,
+ .mcu_2_shp_addr = 1048,
+ .ata_2_mcu_addr = 1560,
+ .mcu_2_ata_addr = 1479,
+ .app_2_per_addr = 1189,
+ .app_2_mcu_addr = 770,
+ .shp_2_per_addr = 1407,
+ .shp_2_mcu_addr = 979,
+};
+#endif
+
+#ifdef CONFIG_ARCH_MX31
+static struct sdma_script_start_addrs addr_imx31_to1 = {
+ .per_2_per_addr = 1677,
+};
+
+static struct sdma_script_start_addrs addr_imx31_to2 = {
+ .ap_2_ap_addr = 423,
+ .ap_2_bp_addr = 829,
+ .bp_2_ap_addr = 1029,
+};
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+static struct sdma_script_start_addrs addr_imx35_to1 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .uartsh_2_mcu_addr = 1183,
+ .per_2_shp_addr = 1033,
+ .mcu_2_shp_addr = 961,
+ .ata_2_mcu_addr = 1333,
+ .mcu_2_ata_addr = 1252,
+ .app_2_mcu_addr = 683,
+ .shp_2_per_addr = 1111,
+ .shp_2_mcu_addr = 892,
+};
+
+static struct sdma_script_start_addrs addr_imx35_to2 = {
+ .ap_2_ap_addr = 729,
+ .uart_2_mcu_addr = 904,
+ .per_2_app_addr = 1597,
+ .mcu_2_app_addr = 834,
+ .uartsh_2_mcu_addr = 1270,
+ .per_2_shp_addr = 1120,
+ .mcu_2_shp_addr = 1048,
+ .ata_2_mcu_addr = 1429,
+ .mcu_2_ata_addr = 1339,
+ .app_2_per_addr = 1531,
+ .app_2_mcu_addr = 770,
+ .shp_2_per_addr = 1198,
+ .shp_2_mcu_addr = 979,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+static struct sdma_script_start_addrs addr_imx51_to1 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .mcu_2_shp_addr = 961,
+ .ata_2_mcu_addr = 1473,
+ .mcu_2_ata_addr = 1392,
+ .app_2_per_addr = 1033,
+ .app_2_mcu_addr = 683,
+ .shp_2_per_addr = 1251,
+ .shp_2_mcu_addr = 892,
+};
+#endif
+
static int __init imxXX_add_imx_dma(void)
{
struct platform_device *ret;
@@ -86,30 +163,42 @@ static int __init imxXX_add_imx_dma(void)
else
#endif
-#if defined(CONFIG_ARCH_MX25)
- if (cpu_is_mx25())
+#if defined(CONFIG_SOC_IMX25)
+ if (cpu_is_mx25()) {
+ imx25_imx_sdma_data.pdata.script_addrs = &addr_imx25_to1;
ret = imx_add_imx_sdma(&imx25_imx_sdma_data);
- else
+ } else
#endif
-#if defined(CONFIG_ARCH_MX31)
+#if defined(CONFIG_SOC_IMX31)
if (cpu_is_mx31()) {
- imx31_imx_sdma_data.pdata.to_version = mx31_revision() >> 4;
+ int to_version = mx31_revision() >> 4;
+ imx31_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to1;
+ else
+ imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to2;
ret = imx_add_imx_sdma(&imx31_imx_sdma_data);
} else
#endif
-#if defined(CONFIG_ARCH_MX35)
+#if defined(CONFIG_SOC_IMX35)
if (cpu_is_mx35()) {
- imx35_imx_sdma_data.pdata.to_version = mx35_revision() >> 4;
+ int to_version = mx35_revision() >> 4;
+ imx35_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to1;
+ else
+ imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to2;
ret = imx_add_imx_sdma(&imx35_imx_sdma_data);
} else
#endif
#if defined(CONFIG_ARCH_MX51)
- if (cpu_is_mx51())
+ if (cpu_is_mx51()) {
+ imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51_to1;
ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
- else
+ } else
#endif
ret = ERR_PTR(-ENODEV);
diff --git a/arch/arm/plat-mxc/devices/platform-imx-fb.c b/arch/arm/plat-mxc/devices/platform-imx-fb.c
new file mode 100644
index 000000000000..6100a7d824dd
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-fb.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_fb_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _LCDC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_LCDC, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_fb_data imx21_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX21, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_fb_data imx25_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX25, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_fb_data imx27_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_imx_fb(
+ const struct imx_imx_fb_data *data,
+ const struct imx_fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("imx-fb", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
index 679588453aad..72ba880c75af 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-i2c.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
@@ -30,7 +30,7 @@ const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
#define imx25_imx_i2c_data_entry(_id, _hwid) \
imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K)
@@ -38,7 +38,7 @@ const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
imx25_imx_i2c_data_entry(1, 2),
imx25_imx_i2c_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
@@ -49,7 +49,7 @@ const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
#define imx31_imx_i2c_data_entry(_id, _hwid) \
imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K)
@@ -57,9 +57,9 @@ const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
imx31_imx_i2c_data_entry(1, 2),
imx31_imx_i2c_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX31 */
+#endif /* ifdef CONFIG_SOC_IMX31 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
#define imx35_imx_i2c_data_entry(_id, _hwid) \
imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K)
@@ -67,16 +67,16 @@ const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
imx35_imx_i2c_data_entry(1, 2),
imx35_imx_i2c_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX35 */
+#endif /* ifdef CONFIG_SOC_IMX35 */
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = {
#define imx51_imx_i2c_data_entry(_id, _hwid) \
imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K)
imx51_imx_i2c_data_entry(0, 1),
imx51_imx_i2c_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX51 */
+#endif /* ifdef CONFIG_SOC_IMX51 */
struct platform_device *__init imx_add_imx_i2c(
const struct imx_imx_i2c_data *data,
diff --git a/arch/arm/plat-mxc/devices/platform-imx-keypad.c b/arch/arm/plat-mxc/devices/platform-imx-keypad.c
new file mode 100644
index 000000000000..40238f0b8643
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-keypad.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_keypad_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _KPP_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_KPP, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX21, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_keypad_data imx25_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX25, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX27, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx_keypad_data imx31_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX31, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx_keypad_data imx35_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX35, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_imx_keypad(
+ const struct imx_imx_keypad_data *data,
+ const struct matrix_keymap_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-keypad", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
index 38a7a0b8f2f1..2569c8d8a2ef 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-ssi.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
@@ -30,14 +30,14 @@ const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX21 */
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = {
#define imx25_imx_ssi_data_entry(_id, _hwid) \
imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K)
imx25_imx_ssi_data_entry(0, 1),
imx25_imx_ssi_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
@@ -48,32 +48,33 @@ const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = {
#define imx31_imx_ssi_data_entry(_id, _hwid) \
imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K)
imx31_imx_ssi_data_entry(0, 1),
imx31_imx_ssi_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX31 */
+#endif /* ifdef CONFIG_SOC_IMX31 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = {
#define imx35_imx_ssi_data_entry(_id, _hwid) \
imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K)
imx35_imx_ssi_data_entry(0, 1),
imx35_imx_ssi_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX35 */
+#endif /* ifdef CONFIG_SOC_IMX35 */
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = {
#define imx51_imx_ssi_data_entry(_id, _hwid) \
imx_imx_ssi_data_entry(MX51, _id, _hwid, SZ_4K)
imx51_imx_ssi_data_entry(0, 1),
imx51_imx_ssi_data_entry(1, 2),
+ imx51_imx_ssi_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX51 */
+#endif /* ifdef CONFIG_SOC_IMX51 */
struct platform_device *__init imx_add_imx_ssi(
const struct imx_imx_ssi_data *data,
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
index 2039640adf27..3c854c2cc6dd 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-uart.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -47,7 +47,7 @@ const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = {
};
#endif
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
#define imx25_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K)
@@ -57,7 +57,7 @@ const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
imx25_imx_uart_data_entry(3, 4),
imx25_imx_uart_data_entry(4, 5),
};
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
@@ -72,7 +72,7 @@ const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = {
#define imx31_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K)
@@ -82,9 +82,9 @@ const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = {
imx31_imx_uart_data_entry(3, 4),
imx31_imx_uart_data_entry(4, 5),
};
-#endif /* ifdef CONFIG_ARCH_MX31 */
+#endif /* ifdef CONFIG_SOC_IMX31 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = {
#define imx35_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_16K)
@@ -92,9 +92,21 @@ const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = {
imx35_imx_uart_data_entry(1, 2),
imx35_imx_uart_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX35 */
+#endif /* ifdef CONFIG_SOC_IMX35 */
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX50
+const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst = {
+#define imx50_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX50, _id, _hwid, SZ_4K)
+ imx50_imx_uart_data_entry(0, 1),
+ imx50_imx_uart_data_entry(1, 2),
+ imx50_imx_uart_data_entry(2, 3),
+ imx50_imx_uart_data_entry(3, 4),
+ imx50_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = {
#define imx51_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX51, _id, _hwid, SZ_4K)
@@ -102,7 +114,17 @@ const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = {
imx51_imx_uart_data_entry(1, 2),
imx51_imx_uart_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX51 */
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst = {
+#define imx53_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX53, _id, _hwid, SZ_4K)
+ imx53_imx_uart_data_entry(0, 1),
+ imx53_imx_uart_data_entry(1, 2),
+ imx53_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
struct platform_device *__init imx_add_imx_uart_3irq(
const struct imx_imx_uart_3irq_data *data,
diff --git a/arch/arm/plat-mxc/devices/platform-imx2-wdt.c b/arch/arm/plat-mxc/devices/platform-imx2-wdt.c
new file mode 100644
index 000000000000..e0aec61177f4
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx2-wdt.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _WDOG ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ }
+#define imx_imx2_wdt_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx2_wdt_data imx25_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX25, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX31, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX35, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx2_wdt_data imx51_imx2_wdt_data[] __initconst = {
+#define imx51_imx2_wdt_data_entry(_id, _hwid) \
+ imx_imx2_wdt_data_entry(MX51, _id, _hwid, SZ_16K)
+ imx51_imx2_wdt_data_entry(0, 1),
+ imx51_imx2_wdt_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+struct platform_device *__init imx_add_imx2_wdt(
+ const struct imx_imx2_wdt_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ return imx_add_platform_device("imx2-wdt", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx21-hcd.c b/arch/arm/plat-mxc/devices/platform-imx21-hcd.c
new file mode 100644
index 000000000000..5770a42f33bf
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx21-hcd.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx21_hcd_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USBOTG_BASE_ADDR, \
+ .irq = soc ## _INT_USBHOST, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx21_hcd_data imx21_imx21_hcd_data __initconst =
+ imx_imx21_hcd_data_entry_single(MX21);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+struct platform_device *__init imx_add_imx21_hcd(
+ const struct imx_imx21_hcd_data *data,
+ const struct mx21_usbh_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("imx21-hcd", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_udc.c b/arch/arm/plat-mxc/devices/platform-imx_udc.c
new file mode 100644
index 000000000000..6fd675dfce14
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_udc.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_udc_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _USBD_BASE_ADDR, \
+ .iosize = _size, \
+ .irq0 = soc ## _INT_USBD0, \
+ .irq1 = soc ## _INT_USBD1, \
+ .irq2 = soc ## _INT_USBD2, \
+ .irq3 = soc ## _INT_USBD3, \
+ .irq4 = soc ## _INT_USBD4, \
+ .irq5 = soc ## _INT_USBD5, \
+ .irq6 = soc ## _INT_USBD6, \
+ }
+
+#define imx_imx_udc_data_entry(soc, _size) \
+ [_id] = imx_imx_udc_data_entry_single(soc, _size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_udc_data imx1_imx_udc_data __initconst =
+ imx_imx_udc_data_entry_single(MX1, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+struct platform_device *__init imx_add_imx_udc(
+ const struct imx_imx_udc_data *data,
+ const struct imxusb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq0,
+ .end = data->irq0,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq1,
+ .end = data->irq1,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq2,
+ .end = data->irq2,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq3,
+ .end = data->irq3,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq4,
+ .end = data->irq4,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq5,
+ .end = data->irq5,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq6,
+ .end = data->irq6,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx_udc", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
new file mode 100644
index 000000000000..10653cc8d1fa
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imxdi_rtc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _DRYICE_BASE_ADDR, \
+ .irq = soc ## _INT_DRYICE, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imxdi_rtc_data imx25_imxdi_rtc_data __initconst =
+ imx_imxdi_rtc_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+struct platform_device *__init imx_add_imxdi_rtc(
+ const struct imx_imxdi_rtc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imxdi_rtc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mx1-camera.c b/arch/arm/plat-mxc/devices/platform-mx1-camera.c
new file mode 100644
index 000000000000..edcc581a30a9
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mx1-camera.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mx1_camera_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _CSI ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CSI, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_mx1_camera_data imx1_mx1_camera_data __initconst =
+ imx_mx1_camera_data_entry_single(MX1, 10);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+struct platform_device *__init imx_add_mx1_camera(
+ const struct imx_mx1_camera_data *data,
+ const struct mx1_camera_pdata *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mx1-camera", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mx2-camera.c b/arch/arm/plat-mxc/devices/platform-mx2-camera.c
new file mode 100644
index 000000000000..b3f4828dc447
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mx2-camera.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mx2_camera_data_entry_single(soc) \
+ { \
+ .iobasecsi = soc ## _CSI_BASE_ADDR, \
+ .iosizecsi = SZ_4K, \
+ .irqcsi = soc ## _INT_CSI, \
+ }
+#define imx_mx2_camera_data_entry_single_emma(soc) \
+ { \
+ .iobasecsi = soc ## _CSI_BASE_ADDR, \
+ .iosizecsi = SZ_32, \
+ .irqcsi = soc ## _INT_CSI, \
+ .iobaseemmaprp = soc ## _EMMAPRP_BASE_ADDR, \
+ .iosizeemmaprp = SZ_32, \
+ .irqemmaprp = soc ## _INT_EMMAPRP, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst =
+ imx_mx2_camera_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst =
+ imx_mx2_camera_data_entry_single_emma(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_mx2_camera(
+ const struct imx_mx2_camera_data *data,
+ const struct mx2_camera_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobasecsi,
+ .end = data->iobasecsi + data->iosizecsi - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irqcsi,
+ .end = data->irqcsi,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->iobaseemmaprp,
+ .end = data->iobaseemmaprp + data->iosizeemmaprp - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irqemmaprp,
+ .end = data->irqemmaprp,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mx2-camera", 0,
+ res, data->iobaseemmaprp ? 4 : 2,
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
new file mode 100644
index 000000000000..cc488f4b6204
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_ehci_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _USB_ ## hs ## _BASE_ADDR, \
+ .irq = soc ## _INT_USB_ ## hs, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX25, 0, OTG);
+const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX25, 1, HS);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX27, 0, OTG);
+const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX27, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX27, 2, HS2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX31, 0, OTG);
+const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX31, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX31, 2, HS2),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX35, 0, OTG);
+const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX35, 1, HS);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_mxc_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct mxc_usbh_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mxc-ehci", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
new file mode 100644
index 000000000000..90d762f6f93b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _SDHC ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SDHC ## _hwid, \
+ .dmareq = soc ## _DMA_REQ_SDHC ## _hwid, \
+ }
+#define imx_mxc_mmc_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst = {
+#define imx21_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_mxc_mmc_data_entry(0, 1),
+ imx21_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst = {
+#define imx27_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_mxc_mmc_data_entry(0, 1),
+ imx27_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst = {
+#define imx31_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX31, _id, _hwid, SZ_16K)
+ imx31_mxc_mmc_data_entry(0, 1),
+ imx31_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+struct platform_device *__init imx_add_mxc_mmc(
+ const struct imx_mxc_mmc_data *data,
+ const struct imxmmc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->dmareq,
+ .end = data->dmareq,
+ .flags = IORESOURCE_DMA,
+ },
+ };
+ return imx_add_platform_device_dmamask("mxc-mmc", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
index 3fdcc32e3d67..1568f39fba8b 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -31,27 +31,27 @@ const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX21, SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX21 */
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX25, SZ_8K);
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX27, SZ_4K);
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX31, SZ_4K);
#endif
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst =
imx_mxc_nand_data_entry_single(MX35, SZ_8K);
#endif
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst =
imx_mxc_nandv3_data_entry_single(MX51, SZ_16K);
#endif
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_pwm.c b/arch/arm/plat-mxc/devices/platform-mxc_pwm.c
new file mode 100644
index 000000000000..3d8ebdba38ee
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_pwm.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _PWM ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_PWM ## _hwid, \
+ }
+#define imx_mxc_pwm_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_pwm_data imx21_mxc_pwm_data __initconst =
+ imx_mxc_pwm_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_pwm_data imx25_mxc_pwm_data[] __initconst = {
+#define imx25_mxc_pwm_data_entry(_id, _hwid) \
+ imx_mxc_pwm_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_mxc_pwm_data_entry(0, 1),
+ imx25_mxc_pwm_data_entry(1, 2),
+ imx25_mxc_pwm_data_entry(2, 3),
+ imx25_mxc_pwm_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_pwm_data imx27_mxc_pwm_data __initconst =
+ imx_mxc_pwm_data_entry_single(MX27, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_mxc_pwm(
+ const struct imx_mxc_pwm_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_pwm", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_rnga.c b/arch/arm/plat-mxc/devices/platform-mxc_rnga.c
new file mode 100644
index 000000000000..b4b7612b6e17
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_rnga.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct imx_mxc_rnga_data {
+ resource_size_t iobase;
+};
+
+#define imx_mxc_rnga_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _RNGA_BASE_ADDR, \
+ }
+
+#ifdef CONFIG_SOC_IMX31
+static const struct imx_mxc_rnga_data imx31_mxc_rnga_data __initconst =
+ imx_mxc_rnga_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+static struct platform_device *__init imx_add_mxc_rnga(
+ const struct imx_mxc_rnga_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ return imx_add_platform_device("mxc_rnga", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
+static int __init imxXX_add_mxc_rnga(void)
+{
+ struct platform_device *ret;
+
+#if defined(CONFIG_SOC_IMX31)
+ if (cpu_is_mx31())
+ ret = imx_add_mxc_rnga(&imx31_mxc_rnga_data);
+ else
+#endif /* if defined(CONFIG_SOC_IMX31) */
+ ret = ERR_PTR(-ENODEV);
+
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+}
+arch_initcall(imxXX_add_mxc_rnga);
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_w1.c b/arch/arm/plat-mxc/devices/platform-mxc_w1.c
new file mode 100644
index 000000000000..96fa5ea91fe8
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_w1.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_w1_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _OWIRE_BASE_ADDR, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_w1_data imx21_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX21);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_w1_data imx27_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_w1_data imx31_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_w1_data imx35_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX35);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_mxc_w1(
+ const struct imx_mxc_w1_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("mxc_w1", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
new file mode 100644
index 000000000000..b3525648a01d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/esdhc.h>
+
+#define imx_sdhci_esdhc_imx_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_ESDHC ## hwid, \
+ }
+
+#define imx_sdhci_esdhc_imx_data_entry(soc, id, hwid) \
+ [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, id, hwid)
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_sdhci_esdhc_imx_data
+imx25_sdhci_esdhc_imx_data[] __initconst = {
+#define imx25_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX25, _id, _hwid)
+ imx25_sdhci_esdhc_imx_data_entry(0, 1),
+ imx25_sdhci_esdhc_imx_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_sdhci_esdhc_imx_data
+imx35_sdhci_esdhc_imx_data[] __initconst = {
+#define imx35_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX35, _id, _hwid)
+ imx35_sdhci_esdhc_imx_data_entry(0, 1),
+ imx35_sdhci_esdhc_imx_data_entry(1, 2),
+ imx35_sdhci_esdhc_imx_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_sdhci_esdhc_imx_data
+imx51_sdhci_esdhc_imx_data[] __initconst = {
+#define imx51_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX51, _id, _hwid)
+ imx51_sdhci_esdhc_imx_data_entry(0, 1),
+ imx51_sdhci_esdhc_imx_data_entry(1, 2),
+ imx51_sdhci_esdhc_imx_data_entry(2, 3),
+ imx51_sdhci_esdhc_imx_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+struct platform_device *__init imx_add_sdhci_esdhc_imx(
+ const struct imx_sdhci_esdhc_imx_data *data,
+ const struct esdhc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("sdhci-esdhc-imx", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c
index 17f724c9452d..8ea49adcdfc1 100644
--- a/arch/arm/plat-mxc/devices/platform-spi_imx.c
+++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c
@@ -30,7 +30,7 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
};
#endif
-#ifdef CONFIG_ARCH_MX25
+#ifdef CONFIG_SOC_IMX25
const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
#define imx25_cspi_data_entry(_id, _hwid) \
imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K)
@@ -38,7 +38,7 @@ const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
imx25_cspi_data_entry(1, 2),
imx25_cspi_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX25 */
+#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
@@ -50,7 +50,7 @@ const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX27 */
-#ifdef CONFIG_ARCH_MX31
+#ifdef CONFIG_SOC_IMX31
const struct imx_spi_imx_data imx31_cspi_data[] __initconst = {
#define imx31_cspi_data_entry(_id, _hwid) \
imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K)
@@ -58,18 +58,18 @@ const struct imx_spi_imx_data imx31_cspi_data[] __initconst = {
imx31_cspi_data_entry(1, 2),
imx31_cspi_data_entry(2, 3),
};
-#endif /* ifdef CONFIG_ARCH_MX31 */
+#endif /* ifdef CONFIG_SOC_IMX31 */
-#ifdef CONFIG_ARCH_MX35
+#ifdef CONFIG_SOC_IMX35
const struct imx_spi_imx_data imx35_cspi_data[] __initconst = {
#define imx35_cspi_data_entry(_id, _hwid) \
imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K)
imx35_cspi_data_entry(0, 1),
imx35_cspi_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX35 */
+#endif /* ifdef CONFIG_SOC_IMX35 */
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
const struct imx_spi_imx_data imx51_cspi_data __initconst =
imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 0, , SZ_4K);
@@ -79,7 +79,7 @@ const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {
imx51_ecspi_data_entry(0, 1),
imx51_ecspi_data_entry(1, 2),
};
-#endif /* ifdef CONFIG_ARCH_MX51 */
+#endif /* ifdef CONFIG_SOC_IMX51 */
struct platform_device *__init imx_add_spi_imx(
const struct imx_spi_imx_data *data,
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 9915607683de..8772ce346a58 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -49,6 +49,7 @@
#define MXC_OTG_OFFSET 0
#define MXC_H1_OFFSET 0x200
+#define MXC_H2_OFFSET 0x400
/* USB_CTRL */
#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
@@ -61,6 +62,11 @@
#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
+/* USBH2CTRL */
+#define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
+#define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
+#define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
+
#define MXC_USBCMD_OFFSET 0x140
/* USBCMD */
@@ -69,9 +75,9 @@
int mxc_initialize_usb_hw(int port, unsigned int flags)
{
unsigned int v;
-#if defined(CONFIG_ARCH_MX25)
+#if defined(CONFIG_SOC_IMX25)
if (cpu_is_mx25()) {
- v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
+ v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
switch (port) {
@@ -108,14 +114,14 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
return -EINVAL;
}
- writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
+ writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
return 0;
}
-#endif /* CONFIG_ARCH_MX25 */
+#endif /* if defined(CONFIG_SOC_IMX25) */
#if defined(CONFIG_ARCH_MX3)
if (cpu_is_mx31()) {
- v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
+ v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
switch (port) {
@@ -153,13 +159,13 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
return -EINVAL;
}
- writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
+ writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
return 0;
}
if (cpu_is_mx35()) {
- v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+ v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
switch (port) {
@@ -196,7 +202,7 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
return -EINVAL;
}
- writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+ writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
return 0;
}
@@ -206,7 +212,7 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
/* On i.MX27 we can use the i.MX31 USBCTRL bits, they
* are identical
*/
- v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+ v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
switch (port) {
case 0: /* OTG port */
@@ -241,12 +247,12 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
default:
return -EINVAL;
}
- writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+ writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
return 0;
}
#endif /* CONFIG_MACH_MX27 */
-#ifdef CONFIG_ARCH_MX51
+#ifdef CONFIG_SOC_IMX51
if (cpu_is_mx51()) {
void __iomem *usb_base;
void __iomem *usbotg_base;
@@ -254,6 +260,10 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
int ret = 0;
usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base) {
+ printk(KERN_ERR "%s(): ioremap failed\n", __func__);
+ return -ENOMEM;
+ }
switch (port) {
case 0: /* OTG port */
@@ -262,6 +272,9 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
case 1: /* Host 1 port */
usbotg_base = usb_base + MXC_H1_OFFSET;
break;
+ case 2: /* Host 2 port */
+ usbotg_base = usb_base + MXC_H2_OFFSET;
+ break;
default:
printk(KERN_ERR"%s no such port %d\n", __func__, port);
ret = -ENOENT;
@@ -274,10 +287,13 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
if (flags & MXC_EHCI_INTERNAL_PHY) {
v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
- if (flags & MXC_EHCI_POWER_PINS_ENABLED)
- v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */
- else
- v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
+ /* OC/USBPWR is not used */
+ v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
+ } else {
+ /* OC/USBPWR is used */
+ v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
+ }
__raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
@@ -285,16 +301,23 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
else
v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v |= MXC_OTG_UCTRL_OPM_BIT;
+ else
+ v &= ~MXC_OTG_UCTRL_OPM_BIT;
__raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
}
break;
case 1: /* Host 1 */
/*Host ULPI */
v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
- if (flags & MXC_EHCI_WAKEUP_ENABLED)
- v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
- else
- v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
+ if (flags & MXC_EHCI_WAKEUP_ENABLED) {
+ /* HOST1 wakeup/ULPI intr enable */
+ v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
+ } else {
+ /* HOST1 wakeup/ULPI intr disable */
+ v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
+ }
if (flags & MXC_EHCI_POWER_PINS_ENABLED)
v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
@@ -315,6 +338,22 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
__raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
break;
+ case 2: /* Host 2 ULPI */
+ v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
+ if (flags & MXC_EHCI_WAKEUP_ENABLED) {
+ /* HOST1 wakeup/ULPI intr enable */
+ v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
+ } else {
+ /* HOST1 wakeup/ULPI intr disable */
+ v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
+ }
+
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
+ else
+ v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
+ __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
+ break;
}
error:
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
index ee9582f4972e..d69d343ff61f 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/plat-mxc/epit.c
@@ -93,7 +93,6 @@ static struct clocksource clocksource_epit = {
.rating = 200,
.read = epit_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -101,9 +100,7 @@ static int __init epit_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
- clocksource_epit.mult = clocksource_hz2mult(c,
- clocksource_epit.shift);
- clocksource_register(&clocksource_epit);
+ clocksource_register_hz(&clocksource_epit, c);
return 0;
}
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 9c3e36232b5b..bc2c7bc6f10a 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -175,7 +175,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
u32 irq_stat;
- struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
+ struct mxc_gpio_port *port = get_irq_data(irq);
irq_stat = __raw_readl(port->base + GPIO_ISR) &
__raw_readl(port->base + GPIO_IMR);
@@ -188,7 +188,7 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
int i;
u32 irq_msk, irq_stat;
- struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
+ struct mxc_gpio_port *port = get_irq_data(irq);
/* walk through all interrupt status registers */
for (i = 0; i < gpio_table_size; i++) {
@@ -349,3 +349,113 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
return 0;
}
+
+#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .irq = _irq, \
+ .irq_high = _irq_high, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _GPIO ## _hwid ## _BASE_ADDR), \
+ .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
+#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \
+ DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
+
+#define DEFINE_REGISTER_FUNCTION(prefix) \
+int __init prefix ## _register_gpios(void) \
+{ \
+ return mxc_gpio_init(prefix ## _gpio_ports, \
+ ARRAY_SIZE(prefix ## _gpio_ports)); \
+}
+
+#if defined(CONFIG_SOC_IMX1)
+static struct mxc_gpio_port imx1_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
+};
+
+DEFINE_REGISTER_FUNCTION(imx1)
+
+#endif /* if defined(CONFIG_SOC_IMX1) */
+
+#if defined(CONFIG_SOC_IMX21)
+static struct mxc_gpio_port imx21_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
+ DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
+ DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
+ DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
+ DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
+ DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
+};
+
+DEFINE_REGISTER_FUNCTION(imx21)
+
+#endif /* if defined(CONFIG_SOC_IMX21) */
+
+#if defined(CONFIG_SOC_IMX25)
+static struct mxc_gpio_port imx25_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
+};
+
+DEFINE_REGISTER_FUNCTION(imx25)
+
+#endif /* if defined(CONFIG_SOC_IMX25) */
+
+#if defined(CONFIG_SOC_IMX27)
+static struct mxc_gpio_port imx27_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
+ DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
+ DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
+ DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
+ DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
+ DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
+};
+
+DEFINE_REGISTER_FUNCTION(imx27)
+
+#endif /* if defined(CONFIG_SOC_IMX27) */
+
+#if defined(CONFIG_SOC_IMX31)
+static struct mxc_gpio_port imx31_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
+};
+
+DEFINE_REGISTER_FUNCTION(imx31)
+
+#endif /* if defined(CONFIG_SOC_IMX31) */
+
+#if defined(CONFIG_SOC_IMX35)
+static struct mxc_gpio_port imx35_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
+};
+
+DEFINE_REGISTER_FUNCTION(imx35)
+
+#endif /* if defined(CONFIG_SOC_IMX35) */
+
+#if defined(CONFIG_SOC_IMX50)
+static struct mxc_gpio_port imx50_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+};
+
+DEFINE_REGISTER_FUNCTION(imx50)
+
+#endif /* if defined(CONFIG_SOC_IMX50) */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 7a1e1f89ff09..aea2cd3b6d15 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -20,7 +20,9 @@ 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 mx50_map_io(void);
extern void mx51_map_io(void);
+extern void mx53_map_io(void);
extern void mxc91231_map_io(void);
extern void mxc_init_irq(void __iomem *);
extern void tzic_init_irq(void __iomem *);
@@ -30,7 +32,9 @@ 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 mx50_init_irq(void);
extern void mx51_init_irq(void);
+extern void mx53_init_irq(void);
extern void mxc91231_init_irq(void);
extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
@@ -42,6 +46,8 @@ 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 mx53_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);
@@ -50,5 +56,6 @@ extern void mxc_arch_reset_init(void __iomem *);
extern void mxc91231_power_off(void);
extern void mxc91231_arch_reset(int, const char *);
extern void mxc91231_prepare_idle(void);
-
+extern void mx51_efikamx_reset(void);
+extern int mx53_revision(void);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index d56213fb901b..3b3a37c25c56 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -10,58 +10,49 @@
* published by the Free Software Foundation.
*
*/
-#define IMX_NEEDS_DEPRECATED_SYMBOLS
+#include <mach/hardware.h>
#ifdef CONFIG_ARCH_MX1
-#include <mach/mx1.h>
-#define UART_PADDR UART1_BASE_ADDR
-#define UART_VADDR IO_ADDRESS(UART1_BASE_ADDR)
+#define UART_PADDR MX1_UART1_BASE_ADDR
#endif
#ifdef CONFIG_ARCH_MX25
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
-#include <mach/mx25.h>
#define UART_PADDR MX25_UART1_BASE_ADDR
-#define UART_VADDR MX25_AIPS1_IO_ADDRESS(MX25_UART1_BASE_ADDR)
#endif
#ifdef CONFIG_ARCH_MX2
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
-#include <mach/mx2x.h>
-#define UART_PADDR UART1_BASE_ADDR
-#define UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR)
+#define UART_PADDR MX2x_UART1_BASE_ADDR
#endif
#ifdef CONFIG_ARCH_MX3
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
-#include <mach/mx3x.h>
-#define UART_PADDR UART1_BASE_ADDR
-#define UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+#define UART_PADDR MX3x_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_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
#endif
+
+#define UART_VADDR IMX_IO_ADDRESS(UART_PADDR)
+
.macro addruart, rp, rv
ldr \rp, =UART_PADDR @ physical
ldr \rv, =UART_VADDR @ virtual
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8c6896fd1e5f..8658c9caa650 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -10,9 +10,19 @@
#include <linux/platform_device.h>
#include <linux/init.h>
-struct platform_device *imx_add_platform_device(const char *name, int id,
+struct platform_device *imx_add_platform_device_dmamask(
+ const char *name, int id,
const struct resource *res, unsigned int num_resources,
- const void *data, size_t size_data);
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *imx_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return imx_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
#include <linux/fec.h>
struct imx_fec_data {
@@ -24,15 +34,63 @@ struct platform_device *__init imx_add_fec(
const struct fec_platform_data *pdata);
#include <linux/can/platform/flexcan.h>
-struct platform_device *__init imx_add_flexcan(int id,
- resource_size_t iobase, resource_size_t iosize,
- resource_size_t irq,
+struct imx_flexcan_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_flexcan(
+ const struct imx_flexcan_data *data,
const struct flexcan_platform_data *pdata);
+#include <linux/fsl_devices.h>
+struct imx_fsl_usb2_udc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fsl_usb2_udc(
+ const struct imx_fsl_usb2_udc_data *data,
+ const struct fsl_usb2_platform_data *pdata);
+
#include <linux/gpio_keys.h>
struct platform_device *__init imx_add_gpio_keys(
const struct gpio_keys_platform_data *pdata);
+#include <mach/mx21-usbhost.h>
+struct imx_imx21_hcd_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx21_hcd(
+ const struct imx_imx21_hcd_data *data,
+ const struct mx21_usbh_platform_data *pdata);
+
+struct imx_imx2_wdt_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+};
+struct platform_device *__init imx_add_imx2_wdt(
+ const struct imx_imx2_wdt_data *data);
+
+struct imx_imxdi_rtc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imxdi_rtc(
+ const struct imx_imxdi_rtc_data *data);
+
+#include <mach/imxfb.h>
+struct imx_imx_fb_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_fb(
+ const struct imx_imx_fb_data *data,
+ const struct imx_fb_platform_data *pdata);
+
#include <mach/i2c.h>
struct imx_imx_i2c_data {
int id;
@@ -44,6 +102,16 @@ struct platform_device *__init imx_add_imx_i2c(
const struct imx_imx_i2c_data *data,
const struct imxi2c_platform_data *pdata);
+#include <linux/input/matrix_keypad.h>
+struct imx_imx_keypad_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_keypad(
+ const struct imx_imx_keypad_data *data,
+ const struct matrix_keymap_data *pdata);
+
#include <mach/ssi.h>
struct imx_imx_ssi_data {
int id;
@@ -82,6 +150,67 @@ struct platform_device *__init imx_add_imx_uart_1irq(
const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata);
+#include <mach/usb.h>
+struct imx_imx_udc_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq0;
+ resource_size_t irq1;
+ resource_size_t irq2;
+ resource_size_t irq3;
+ resource_size_t irq4;
+ resource_size_t irq5;
+ resource_size_t irq6;
+};
+struct platform_device *__init imx_add_imx_udc(
+ const struct imx_imx_udc_data *data,
+ const struct imxusb_platform_data *pdata);
+
+#include <mach/mx1_camera.h>
+struct imx_mx1_camera_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mx1_camera(
+ const struct imx_mx1_camera_data *data,
+ const struct mx1_camera_pdata *pdata);
+
+#include <mach/mx2_cam.h>
+struct imx_mx2_camera_data {
+ resource_size_t iobasecsi;
+ resource_size_t iosizecsi;
+ resource_size_t irqcsi;
+ resource_size_t iobaseemmaprp;
+ resource_size_t iosizeemmaprp;
+ resource_size_t irqemmaprp;
+};
+struct platform_device *__init imx_add_mx2_camera(
+ const struct imx_mx2_camera_data *data,
+ const struct mx2_camera_platform_data *pdata);
+
+#include <mach/mxc_ehci.h>
+struct imx_mxc_ehci_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct mxc_usbh_platform_data *pdata);
+
+#include <mach/mmc.h>
+struct imx_mxc_mmc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmareq;
+};
+struct platform_device *__init imx_add_mxc_mmc(
+ const struct imx_mxc_mmc_data *data,
+ const struct imxmmc_platform_data *pdata);
+
#include <mach/mxc_nand.h>
struct imx_mxc_nand_data {
/*
@@ -99,24 +228,39 @@ struct platform_device *__init imx_add_mxc_nand(
const struct imx_mxc_nand_data *data,
const struct mxc_nand_platform_data *pdata);
-#include <mach/spi.h>
-struct imx_spi_imx_data {
- const char *devid;
+struct imx_mxc_pwm_data {
int id;
resource_size_t iobase;
resource_size_t iosize;
- int irq;
+ resource_size_t irq;
};
-struct platform_device *__init imx_add_spi_imx(
- const struct imx_spi_imx_data *data,
- const struct spi_imx_master *pdata);
+struct platform_device *__init imx_add_mxc_pwm(
+ const struct imx_mxc_pwm_data *data);
+
+struct imx_mxc_w1_data {
+ resource_size_t iobase;
+};
+struct platform_device *__init imx_add_mxc_w1(
+ const struct imx_mxc_w1_data *data);
#include <mach/esdhc.h>
-struct imx_esdhc_imx_data {
+struct imx_sdhci_esdhc_imx_data {
int id;
resource_size_t iobase;
resource_size_t irq;
};
-struct platform_device *__init imx_add_esdhc(
- const struct imx_esdhc_imx_data *data,
+struct platform_device *__init imx_add_sdhci_esdhc_imx(
+ const struct imx_sdhci_esdhc_imx_data *data,
const struct esdhc_platform_data *pdata);
+
+#include <mach/spi.h>
+struct imx_spi_imx_data {
+ const char *devid;
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ int irq;
+};
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
+ const struct spi_imx_master *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index aeb08697726b..bd9bb9799141 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -54,15 +54,15 @@
#elif defined CONFIG_MXC_TZIC
@ Load offset & priority of the highest priority
@ interrupt pending.
+ @ 0x080 is INTSEC0 register
@ 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
+1000: add \irqstat, \base, \irqnr, lsr #3
+ ldr \tmp, [\irqstat, #0xd80]
+ ldr \irqstat, [\irqstat, #0x080]
+ ands \tmp, \tmp, \irqstat
+ bne 1001f
+ add \irqnr, \irqnr, #32
cmp \irqnr, #128
blo 1000b
b 2001f
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
index af33b74f569e..0044e2f1bea8 100644
--- a/arch/arm/plat-mxc/include/mach/gpio.h
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -23,6 +23,11 @@
#include <mach/hardware.h>
#include <asm-generic/gpio.h>
+
+/* There's a off-by-one betweem the gpio bank number and the gpiochip */
+/* range e.g. GPIO_1_5 is gpio 5 under linux */
+#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))
+
/* use gpiolib dispatchers */
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index ebadf4ac43fc..26bb1bab4aeb 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -22,13 +22,92 @@
#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 __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#define IMX_IO_P2V_MODULE(addr, module) \
+ (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? \
+ (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
+
+/*
+ * This is rather complicated for humans and ugly to verify, but for a machine
+ * it's OK. Still more as it is usually only applied to constants. The upsides
+ * on using this approach are:
+ *
+ * - same mapping on all i.MX machines
+ * - works for assembler, too
+ * - no need to nurture #defines for virtual addresses
+ *
+ * The downside it, it's hard to verify (but I have a script for that).
+ *
+ * Obviously this needs to be injective for each SoC. In general it maps the
+ * whole address space to [0xf4000000, 0xf5ffffff]. So [0xf6000000,0xfeffffff]
+ * is free for per-machine use (e.g. KZM_ARM11_01 uses 64MiB there).
+ *
+ * It applies the following mappings for the different SoCs:
+ *
+ * mx1:
+ * IO 0x00200000+0x100000 -> 0xf4000000+0x100000
+ * mx21:
+ * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
+ * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
+ * X_MEMC 0xdf000000+0x004000 -> 0xf5f00000+0x004000
+ * mx25:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * mx27:
+ * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
+ * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
+ * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000
+ * mx31:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * mx35:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * mx50:
+ * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
+ * mx51:
+ * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000
+ * DEBUG 0x60000000+0x100000 -> 0xf5000000+0x100000
+ * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x83f00000+0x100000 -> 0xf4300000+0x100000
+ * mxc91231:
+ * L2CC 0x30000000+0x010000 -> 0xf4400000+0x010000
+ * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000
+ * ROMP 0x60000000+0x010000 -> 0xf5000000+0x010000
+ * AVIC 0x68000000+0x010000 -> 0xf5800000+0x010000
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * SPBA1 0x52000000+0x100000 -> 0xf5600000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ */
+#define IMX_IO_P2V(x) ( \
+ 0xf4000000 + \
+ (((x) & 0x50000000) >> 6) + \
+ (((x) & 0x0b000000) >> 4) + \
+ (((x) & 0x000fffff)))
+
+#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
#ifdef CONFIG_ARCH_MX5
+#include <mach/mx50.h>
#include <mach/mx51.h>
+#include <mach/mx53.h>
#endif
#ifdef CONFIG_ARCH_MX3
@@ -61,4 +140,11 @@
#include <mach/mxc.h>
+#define imx_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
index 5263506b7ddf..9de8f062ad5d 100644
--- a/arch/arm/plat-mxc/include/mach/imxfb.h
+++ b/arch/arm/plat-mxc/include/mach/imxfb.h
@@ -1,6 +1,8 @@
/*
* This structure describes the machine which we are running on.
*/
+#ifndef __MACH_IMXFB_H__
+#define __MACH_IMXFB_H__
#include <linux/fb.h>
@@ -79,3 +81,4 @@ struct imx_fb_platform_data {
};
void set_imx_fb_info(struct imx_fb_platform_data *);
+#endif /* ifndef __MACH_IMXFB_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx50.h b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
new file mode 100644
index 000000000000..058a922ca147
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_IOMUX_MX50_H__
+#define __MACH_IOMUX_MX50_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX50_ELCDIF_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+
+#define MX50_SD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_UART_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE)
+
+#define MX50_I2C_PAD_CTRL (PAD_CTL_ODE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_HYS)
+
+#define MX50_USB_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP)
+
+#define MX50_FEC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH)
+
+#define MX50_OWIRE_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
+
+#define MX50_KEYPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_CSPI_SS_PAD (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x2CC, 0x20, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL0__GPIO_4_0 IOMUX_PAD(0x2CC, 0x20, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL0__NANDF_CLE IOMUX_PAD(0x2CC, 0x20, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x2D0, 0x24, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW0__GPIO_4_1 IOMUX_PAD(0x2D0, 0x24, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW0__NANDF_ALE IOMUX_PAD(0x2D0, 0x24, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x2D4, 0x28, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL1__GPIO_4_2 IOMUX_PAD(0x2D4, 0x28, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL1__NANDF_CE0 IOMUX_PAD(0x2D4, 0x28, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x2D8, 0x2C, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW1__GPIO_4_3 IOMUX_PAD(0x2D8, 0x2C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW1__NANDF_CE1 IOMUX_PAD(0x2D8, 0x2C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x2DC, 0x30, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_COL2__GPIO_4_4 IOMUX_PAD(0x2DC, 0x30, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL2__NANDF_CE2 IOMUX_PAD(0x2DC, 0x30, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x2E0, 0x34, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW2__GPIO_4_5 IOMUX_PAD(0x2E0, 0x34, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW2__NANDF_CE3 IOMUX_PAD(0x2E0, 0x34, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x2E4, 0x38, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL3__GPIO_4_6 IOMUX_PAD(0x2E4, 0x38, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL3__NANDF_READY IOMUX_PAD(0x2E4, 0x38, 2, 0x7b4, 0, PAD_CTL_PKE | \
+ PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_KEY_COL3__SDMA_EXT0 IOMUX_PAD(0x2E4, 0x38, 6, 0x7b8, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x2E8, 0x3C, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW3__GPIO_4_7 IOMUX_PAD(0x2E8, 0x3C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW3__NANDF_DQS IOMUX_PAD(0x2E8, 0x3C, 2, 0x7b0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_KEY_ROW3__SDMA_EXT1 IOMUX_PAD(0x2E8, 0x3C, 6, 0x7bc, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C1_SCL__I2C1_SCL IOMUX_PAD(0x2EC, 0x40, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C1_SCL__GPIO_6_18 IOMUX_PAD(0x2EC, 0x40, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C1_SCL__UART2_TXD IOMUX_PAD(0x2EC, 0x40, 2, 0x7cc, 0, MX50_UART_PAD_CTRL)
+
+#define MX50_PAD_I2C1_SDA__I2C1_SDA IOMUX_PAD(0x2F0, 0x44, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C1_SDA__GPIO_6_19 IOMUX_PAD(0x2F0, 0x44, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C1_SDA__UART2_RXD IOMUX_PAD(0x2F0, 0x44, 2, 0x7cc, 1, MX50_UART_PAD_CTRL)
+
+#define MX50_PAD_I2C2_SCL__I2C2_SCL IOMUX_PAD(0x2F4, 0x48, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__GPIO_6_20 IOMUX_PAD(0x2F4, 0x48, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__UART2_CTS IOMUX_PAD(0x2F4, 0x48, 2, 0x7c8, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__DCDC_OK IOMUX_PAD(0x2F4, 0x48, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C2_SDA__I2C2_SDA IOMUX_PAD(0x2F8, 0x4C, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__GPIO_6_21 IOMUX_PAD(0x2F8, 0x4C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__UART2_RTS IOMUX_PAD(0x2F8, 0x4C, 2, 0x7c8, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__PWRSTABLE IOMUX_PAD(0x2F8, 0x4C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C3_SCL__I2C3_SCL IOMUX_PAD(0x2FC, 0x50, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__GPIO_6_22 IOMUX_PAD(0x2FC, 0x50, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__FEC_MDC IOMUX_PAD(0x2FC, 0x50, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_I2C3_SCL__PMIC_RDY IOMUX_PAD(0x2FC, 0x50, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__GPT_CAPIN1 IOMUX_PAD(0x2FC, 0x50, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__USBOTG_OC IOMUX_PAD(0x2FC, 0x50, 7, 0x7E8, 0, MX50_USB_PAD_CTRL)
+
+#define MX50_PAD_I2C3_SDA__I2C3_SDA IOMUX_PAD(0x300, 0x54, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__GPIO_6_23 IOMUX_PAD(0x300, 0x54, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__FEC_MDIO IOMUX_PAD(0x300, 0x54, 2, 0x774, 0, MX50_FEC_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__PWRFAIL_INT IOMUX_PAD(0x300, 0x54, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__ALARM_DEB IOMUX_PAD(0x300, 0x54, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__GPT_CAPIN1 IOMUX_PAD(0x300, 0x54, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__USBOTG_PWR IOMUX_PAD(0x300, 0x54, 7, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_PWM1__PWM1_PWMO IOMUX_PAD(0x304, 0x58, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM1__GPIO_6_24 IOMUX_PAD(0x304, 0x58, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM1__USBOTG_OC IOMUX_PAD(0x304, 0x58, 2, 0x7E8, 1, MX50_USB_PAD_CTRL)
+#define MX50_PAD_PWM1__GPT_CMPOUT1 IOMUX_PAD(0x304, 0x58, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PWM2__PWM2_PWMO IOMUX_PAD(0x308, 0x5C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__GPIO_6_25 IOMUX_PAD(0x308, 0x5C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__USBOTG_PWR IOMUX_PAD(0x308, 0x5C, 2, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+#define MX50_PAD_PWM2__DCDC_PWM IOMUX_PAD(0x308, 0x5C, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__GPT_CMPOUT2 IOMUX_PAD(0x308, 0x5C, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__ANY_PU_RST IOMUX_PAD(0x308, 0x5C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_OWIRE__OWIRE IOMUX_PAD(0x30C, 0x60, 0, 0x0, 0, MX50_OWIRE_PAD_CTRL)
+#define MX50_PAD_OWIRE__GPIO_6_26 IOMUX_PAD(0x30C, 0x60, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__USBH1_OC IOMUX_PAD(0x30C, 0x60, 2, 0x0, 0, MX50_USB_PAD_CTRL)
+#define MX50_PAD_OWIRE__SSI_EXT1_CLK IOMUX_PAD(0x30C, 0x60, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__EPDC_PWRIRQ IOMUX_PAD(0x30C, 0x60, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__GPT_CMPOUT3 IOMUX_PAD(0x30C, 0x60, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPITO__EPITO IOMUX_PAD(0x310, 0x64, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__GPIO_6_27 IOMUX_PAD(0x310, 0x64, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__USBH1_PWR IOMUX_PAD(0x310, 0x64, 2, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EPITO__SSI_EXT2_CLK IOMUX_PAD(0x310, 0x64, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__TOG_EN IOMUX_PAD(0x310, 0x64, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__GPT_CLKIN IOMUX_PAD(0x310, 0x64, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_WDOG__WDOG IOMUX_PAD(0x314, 0x68, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__GPIO_6_28 IOMUX_PAD(0x314, 0x68, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__WDOG_RST IOMUX_PAD(0x314, 0x68, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__XTAL32K IOMUX_PAD(0x314, 0x68, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXFS__SSI_TXFS IOMUX_PAD(0x318, 0x6C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXFS__GPIO_6_0 IOMUX_PAD(0x318, 0x6C, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXC__SSI_TXC IOMUX_PAD(0x31C, 0x70, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXC__GPIO_6_1 IOMUX_PAD(0x31C, 0x70, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXD__SSI_TXD IOMUX_PAD(0x320, 0x74, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXD__GPIO_6_2 IOMUX_PAD(0x320, 0x74, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXD__CSPI_RDY IOMUX_PAD(0x320, 0x74, 4, 0x6e8, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_RXD__SSI_RXD IOMUX_PAD(0x324, 0x78, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXD__GPIO_6_3 IOMUX_PAD(0x324, 0x78, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXD__CSPI_SS3 IOMUX_PAD(0x324, 0x78, 4, 0x6f4, 0, MX50_CSPI_SS_PAD)
+
+#define MX50_PAD_SSI_RXFS__AUD3_RXFS IOMUX_PAD(0x328, 0x7C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__GPIO_6_4 IOMUX_PAD(0x328, 0x7C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__UART5_TXD IOMUX_PAD(0x328, 0x7C, 2, 0x7e4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__WEIM_D6 IOMUX_PAD(0x328, 0x7C, 3, 0x804, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__CSPI_SS2 IOMUX_PAD(0x328, 0x7C, 4, 0x6f0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_SSI_RXFS__FEC_COL IOMUX_PAD(0x328, 0x7C, 5, 0x770, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SSI_RXFS__FEC_MDC IOMUX_PAD(0x328, 0x7C, 6, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_SSI_RXC__AUD3_RXC IOMUX_PAD(0x32C, 0x80, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__GPIO_6_5 IOMUX_PAD(0x32C, 0x80, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__UART5_RXD IOMUX_PAD(0x32C, 0x80, 2, 0x7e4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__WEIM_D7 IOMUX_PAD(0x32C, 0x80, 3, 0x808, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__CSPI_SS1 IOMUX_PAD(0x32C, 0x80, 4, 0x6ec, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_SSI_RXC__FEC_RX_CLK IOMUX_PAD(0x32C, 0x80, 5, 0x780, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__FEC_MDIO IOMUX_PAD(0x32C, 0x80, 6, 0x774, 1, MX50_FEC_PAD_CTRL)
+
+#define MX50_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x330, 0x84, 0, 0x7c4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_TXD__GPIO_6_6 IOMUX_PAD(0x330, 0x84, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x334, 0x88, 0, 0x7c4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RXD__GPIO_6_7 IOMUX_PAD(0x334, 0x88, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x338, 0x8C, 0, 0x7c0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__GPIO_6_8 IOMUX_PAD(0x338, 0x8C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__UART5_TXD IOMUX_PAD(0x338, 0x8C, 2, 0x7e4, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__SD4_D4 IOMUX_PAD(0x338, 0x8C, 4, 0x760, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__SD4_CMD IOMUX_PAD(0x338, 0x8C, 5, 0x74c, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x33C, 0x90, 0, 0x7c0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__GPIO_6_9 IOMUX_PAD(0x33C, 0x90, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__UART5_RXD IOMUX_PAD(0x33C, 0x90, 2, 0x7e4, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_D5 IOMUX_PAD(0x33C, 0x90, 4, 0x0, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_CLK IOMUX_PAD(0x33C, 0x90, 5, 0x0, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x340, 0x94, 0, 0x7cc, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__GPIO_6_10 IOMUX_PAD(0x340, 0x94, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__SD4_D6 IOMUX_PAD(0x340, 0x94, 4, 0x768, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__SD4_D4 IOMUX_PAD(0x340, 0x94, 5, 0x760, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x344, 0x98, 0, 0x7cc, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__GPIO_6_11 IOMUX_PAD(0x344, 0x98, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__SD4_D7 IOMUX_PAD(0x344, 0x98, 4, 0x76c, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__SD4_D5 IOMUX_PAD(0x344, 0x98, 5, 0x764, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x348, 0x9C, 0, 0x7c8, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__GPIO_6_12 IOMUX_PAD(0x348, 0x9C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__SD4_CMD IOMUX_PAD(0x348, 0x9C, 4, 0x74c, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__SD4_D6 IOMUX_PAD(0x348, 0x9C, 5, 0x768, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x34C, 0xA0, 0, 0x7c8, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__GPIO_6_13 IOMUX_PAD(0x34C, 0xA0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__SD4_CLK IOMUX_PAD(0x34C, 0xA0, 4, 0x748, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__SD4_D7 IOMUX_PAD(0x34C, 0xA0, 5, 0x76c, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x350, 0xA4, 0, 0x7d4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__GPIO_6_14 IOMUX_PAD(0x350, 0xA4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD1_D4 IOMUX_PAD(0x350, 0xA4, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD4_D0 IOMUX_PAD(0x350, 0xA4, 4, 0x750, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD2_WP IOMUX_PAD(0x350, 0xA4, 5, 0x744, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__WEIM_D12 IOMUX_PAD(0x350, 0xA4, 6, 0x81c, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x354, 0xA8, 0, 0x7d4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__GPIO_6_15 IOMUX_PAD(0x354, 0xA8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD1_D5 IOMUX_PAD(0x354, 0xA8, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD4_D1 IOMUX_PAD(0x354, 0xA8, 4, 0x754, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD2_CD IOMUX_PAD(0x354, 0xA8, 5, 0x740, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__WEIM_D13 IOMUX_PAD(0x354, 0xA8, 6, 0x820, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART4_TXD__UART4_TXD IOMUX_PAD(0x358, 0xAC, 0, 0x7dc, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__GPIO_6_16 IOMUX_PAD(0x358, 0xAC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__UART3_CTS IOMUX_PAD(0x358, 0xAC, 2, 0x7d0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD1_D6 IOMUX_PAD(0x358, 0xAC, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD4_D2 IOMUX_PAD(0x358, 0xAC, 4, 0x758, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD2_LCTL IOMUX_PAD(0x358, 0xAC, 5, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__WEIM_D14 IOMUX_PAD(0x358, 0xAC, 6, 0x824, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART4_RXD__UART4_RXD IOMUX_PAD(0x35C, 0xB0, 0, 0x7dc, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__GPIO_6_17 IOMUX_PAD(0x35C, 0xB0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__UART3_RTS IOMUX_PAD(0x35C, 0xB0, 2, 0x7d0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD1_D7 IOMUX_PAD(0x35C, 0xB0, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD4_D3 IOMUX_PAD(0x35C, 0xB0, 4, 0x75c, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD1_LCTL IOMUX_PAD(0x35C, 0xB0, 5, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__WEIM_D15 IOMUX_PAD(0x35C, 0xB0, 6, 0x828, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_SCLK__CSPI_SCLK IOMUX_PAD(0x360, 0xB4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_SCLK__GPIO_4_8 IOMUX_PAD(0x360, 0xB4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_MOSI__CSPI_MOSI IOMUX_PAD(0x364, 0xB8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_MOSI__GPIO_4_9 IOMUX_PAD(0x364, 0xB8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_MISO__CSPI_MISO IOMUX_PAD(0x368, 0xBC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_MISO__GPIO_4_10 IOMUX_PAD(0x368, 0xBC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_SS0__CSPI_SS0 IOMUX_PAD(0x36C, 0xC0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_CSPI_SS0__GPIO_4_11 IOMUX_PAD(0x36C, 0xC0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x370, 0xC4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__GPIO_4_12 IOMUX_PAD(0x370, 0xC4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY IOMUX_PAD(0x370, 0xC4, 2, 0x6e8, 1, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY IOMUX_PAD(0x370, 0xC4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__UART3_RTS IOMUX_PAD(0x370, 0xC4, 4, 0x7d0, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE6 IOMUX_PAD(0x370, 0xC4, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__WEIM_D8 IOMUX_PAD(0x370, 0xC4, 7, 0x80c, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x374, 0xC8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__GPIO_4_13 IOMUX_PAD(0x374, 0xC8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1 IOMUX_PAD(0x374, 0xC8, 2, 0x6ec, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1 IOMUX_PAD(0x374, 0xC8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS IOMUX_PAD(0x374, 0xC8, 4, 0x7d0, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE7 IOMUX_PAD(0x374, 0xC8, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__WEIM_D9 IOMUX_PAD(0x374, 0xC8, 7, 0x810, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x378, 0xCC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__GPIO_4_14 IOMUX_PAD(0x378, 0xCC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__CSPI_SS2 IOMUX_PAD(0x378, 0xCC, 2, 0x6f0, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2 IOMUX_PAD(0x378, 0xCC, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MISO__UART4_RTS IOMUX_PAD(0x378, 0xCC, 4, 0x7d8, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE8 IOMUX_PAD(0x378, 0xCC, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__WEIM_D10 IOMUX_PAD(0x378, 0xCC, 7, 0x814, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x37C, 0xD0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__GPIO_4_15 IOMUX_PAD(0x37C, 0xD0, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_ECSPI1_SS0__CSPI_SS3 IOMUX_PAD(0x37C, 0xD0, 2, 0x6f4, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3 IOMUX_PAD(0x37C, 0xD0, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS IOMUX_PAD(0x37C, 0xD0, 4, 0x7d8, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE9 IOMUX_PAD(0x37C, 0xD0, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SS0__WEIM_D11 IOMUX_PAD(0x37C, 0xD0, 7, 0x818, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK IOMUX_PAD(0x380, 0xD4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__GPIO_4_16 IOMUX_PAD(0x380, 0xD4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR IOMUX_PAD(0x380, 0xD4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY IOMUX_PAD(0x380, 0xD4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__UART5_RTS IOMUX_PAD(0x380, 0xD4, 4, 0x7e0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK IOMUX_PAD(0x380, 0xD4, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__NANDF_CEN4 IOMUX_PAD(0x380, 0xD4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__WEIM_D8 IOMUX_PAD(0x380, 0xD4, 7, 0x80c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI IOMUX_PAD(0x384, 0xD8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__GPIO_4_17 IOMUX_PAD(0x384, 0xD8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RD IOMUX_PAD(0x384, 0xD8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1 IOMUX_PAD(0x384, 0xD8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS IOMUX_PAD(0x384, 0xD8, 4, 0x7e0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_EN IOMUX_PAD(0x384, 0xD8, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__NANDF_CEN5 IOMUX_PAD(0x384, 0xD8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__WEIM_D9 IOMUX_PAD(0x384, 0xD8, 7, 0x810, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO IOMUX_PAD(0x388, 0xDC, 0, 0x73c, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__GPIO_4_18 IOMUX_PAD(0x388, 0xDC, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS IOMUX_PAD(0x388, 0xDC, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2 IOMUX_PAD(0x388, 0xDC, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD IOMUX_PAD(0x388, 0xDC, 4, 0x7e4, 4, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC IOMUX_PAD(0x388, 0xDC, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__NANDF_CEN6 IOMUX_PAD(0x388, 0xDC, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__WEIM_D10 IOMUX_PAD(0x388, 0xDC, 7, 0x814, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0 IOMUX_PAD(0x38C, 0xE0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_SS0__GPIO_4_19 IOMUX_PAD(0x38C, 0xE0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS IOMUX_PAD(0x38C, 0xE0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ECSPI1_SS3 IOMUX_PAD(0x38C, 0xE0, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_SS0__UART5_RXD IOMUX_PAD(0x38C, 0xE0, 4, 0x7e4, 5, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC IOMUX_PAD(0x38C, 0xE0, 5, 0x6f8, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__NANDF_CEN7 IOMUX_PAD(0x38C, 0xE0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__WEIM_D11 IOMUX_PAD(0x38C, 0xE0, 7, 0x818, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x390, 0xE4, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_CLK__GPIO_5_0 IOMUX_PAD(0x390, 0xE4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_CLK__CLKO IOMUX_PAD(0x390, 0xE4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x394, 0xE8, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_CMD__GPIO_5_1 IOMUX_PAD(0x394, 0xE8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_CMD__CLKO2 IOMUX_PAD(0x394, 0xE8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D0__SD1_D0 IOMUX_PAD(0x398, 0xEC, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D0__GPIO_5_2 IOMUX_PAD(0x398, 0xEC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D0__PLL1_BYP IOMUX_PAD(0x398, 0xEC, 7, 0x6dc, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D1__SD1_D1 IOMUX_PAD(0x39C, 0xF0, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D1__GPIO_5_3 IOMUX_PAD(0x39C, 0xF0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D1__PLL2_BYP IOMUX_PAD(0x39C, 0xF0, 7, 0x6e0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D2__SD1_D2 IOMUX_PAD(0x3A0, 0xF4, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D2__GPIO_5_4 IOMUX_PAD(0x3A0, 0xF4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D2__PLL3_BYP IOMUX_PAD(0x3A0, 0xF4, 7, 0x6e4, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D3__SD1_D3 IOMUX_PAD(0x3A4, 0xF8, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D3__GPIO_5_5 IOMUX_PAD(0x3A4, 0xF8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x3A8, 0xFC, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CLK__GPIO_5_6 IOMUX_PAD(0x3A8, 0xFC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CLK__MSHC_SCLK IOMUX_PAD(0x3A8, 0xFC, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x3AC, 0x100, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CMD__GPIO_5_7 IOMUX_PAD(0x3AC, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CMD__MSHC_BS IOMUX_PAD(0x3AC, 0x100, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_SD2_D0__SD2_D0 IOMUX_PAD(0x3B0, 0x104, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D0__GPIO_5_8 IOMUX_PAD(0x3B0, 0x104, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D0__MSHC_D0 IOMUX_PAD(0x3B0, 0x104, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D0__KEY_COL4 IOMUX_PAD(0x3B0, 0x104, 3, 0x790, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D1__SD2_D1 IOMUX_PAD(0x3B4, 0x108, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D1__GPIO_5_9 IOMUX_PAD(0x3B4, 0x108, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D1__MSHC_D1 IOMUX_PAD(0x3B4, 0x108, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D1__KEY_ROW4 IOMUX_PAD(0x3B4, 0x108, 3, 0x7a0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D2__SD2_D2 IOMUX_PAD(0x3B8, 0x10C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D2__GPIO_5_10 IOMUX_PAD(0x3B8, 0x10C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D2__MSHC_D2 IOMUX_PAD(0x3B8, 0x10C, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D2__KEY_COL5 IOMUX_PAD(0x3B8, 0x10C, 3, 0x794, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D3__SD2_D3 IOMUX_PAD(0x3BC, 0x110, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D3__GPIO_5_11 IOMUX_PAD(0x3BC, 0x110, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D3__MSHC_D3 IOMUX_PAD(0x3BC, 0x110, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D3__KEY_ROW5 IOMUX_PAD(0x3BC, 0x110, 3, 0x7a4, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D4__SD2_D4 IOMUX_PAD(0x3C0, 0x114, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D4__GPIO_5_12 IOMUX_PAD(0x3C0, 0x114, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__AUD4_RXFS IOMUX_PAD(0x3C0, 0x114, 2, 0x6d0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__KEY_COL6 IOMUX_PAD(0x3C0, 0x114, 3, 0x798, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__WEIM_D0 IOMUX_PAD(0x3C0, 0x114, 4, 0x7ec, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__CCM_OUT0 IOMUX_PAD(0x3C0, 0x114, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D5__SD2_D5 IOMUX_PAD(0x3C4, 0x118, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D5__GPIO_5_13 IOMUX_PAD(0x3C4, 0x118, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__AUD4_RXC IOMUX_PAD(0x3C4, 0x118, 2, 0x6cc, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__KEY_ROW6 IOMUX_PAD(0x3C4, 0x118, 3, 0x7a8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__WEIM_D1 IOMUX_PAD(0x3C4, 0x118, 4, 0x7f0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__CCM_OUT1 IOMUX_PAD(0x3C4, 0x118, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D6__SD2_D6 IOMUX_PAD(0x3C8, 0x11C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D6__GPIO_5_14 IOMUX_PAD(0x3C8, 0x11C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__AUD4_RXD IOMUX_PAD(0x3C8, 0x11C, 2, 0x6c4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__KEY_COL7 IOMUX_PAD(0x3C8, 0x11C, 3, 0x79c, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__WEIM_D2 IOMUX_PAD(0x3C8, 0x11C, 4, 0x7f4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__CCM_OUT2 IOMUX_PAD(0x3C8, 0x11C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D7__SD2_D7 IOMUX_PAD(0x3CC, 0x120, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D7__GPIO_5_15 IOMUX_PAD(0x3CC, 0x120, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__AUD4_TXFS IOMUX_PAD(0x3CC, 0x120, 2, 0x6d8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__KEY_ROW7 IOMUX_PAD(0x3CC, 0x120, 3, 0x7ac, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__WEIM_D3 IOMUX_PAD(0x3CC, 0x120, 4, 0x7f8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__CCM_STOP IOMUX_PAD(0x3CC, 0x120, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_WP__SD2_WP IOMUX_PAD(0x3D0, 0x124, 0, 0x744, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_WP__GPIO_5_16 IOMUX_PAD(0x3D0, 0x124, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__AUD4_TXD IOMUX_PAD(0x3D0, 0x124, 2, 0x6c8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__WEIM_D4 IOMUX_PAD(0x3D0, 0x124, 4, 0x7fc, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__CCM_WAIT IOMUX_PAD(0x3D0, 0x124, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_CD__SD2_CD IOMUX_PAD(0x3D4, 0x128, 0, 0x740, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CD__GPIO_5_17 IOMUX_PAD(0x3D4, 0x128, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__AUD4_TXC IOMUX_PAD(0x3D4, 0x128, 2, 0x6d4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__WEIM_D5 IOMUX_PAD(0x3D4, 0x128, 4, 0x800, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__CCM_REF_EN IOMUX_PAD(0x3D4, 0x128, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_ON_REQ__PMIC_ON_REQ IOMUX_PAD(0x3D8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_STBY_REQ__PMIC_STBY_REQ IOMUX_PAD(0x3DC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_PORT_B__PMIC_PORT_B IOMUX_PAD(0x3E0, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_BOOT_MODE1__PMIC_BOOT_MODE1 IOMUX_PAD(0x3E4, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_RESET_IN_B__PMIC_RESET_IN_B IOMUX_PAD(0x3E8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_BOOT_MODE0__PMIC_BOOT_MODE0 IOMUX_PAD(0x3EC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_TEST_MODE__PMIC_TEST_MODE IOMUX_PAD(0x3F0, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TMS__PMIC_JTAG_TMS IOMUX_PAD(0x3F4, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_MOD__PMIC_JTAG_MOD IOMUX_PAD(0x3F8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TRSTB__PMIC_JTAG_TRSTB IOMUX_PAD(0x3FC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TDI__PMIC_JTAG_TDI IOMUX_PAD(0x400, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TCK__PMIC_JTAG_TCK IOMUX_PAD(0x404, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TDO__PMIC_JTAG_TDO IOMUX_PAD(0x408, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D0__DISP_D0 IOMUX_PAD(0x40C, 0x12C, 0, 0x6fc, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D0__GPIO_2_0 IOMUX_PAD(0x40C, 0x12C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D0__FEC_TXCLK IOMUX_PAD(0x40C, 0x12C, 2, 0x78c, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+
+#define MX50_PAD_DISP_D1__DISP_D1 IOMUX_PAD(0x410, 0x130, 0, 0x700, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D1__GPIO_2_1 IOMUX_PAD(0x410, 0x130, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D1__FEC_RX_ER IOMUX_PAD(0x410, 0x130, 2, 0x788, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D1__WEIM_A17 IOMUX_PAD(0x410, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D2__DISP_D2 IOMUX_PAD(0x414, 0x134, 0, 0x704, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D2__GPIO_2_2 IOMUX_PAD(0x414, 0x134, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D2__FEC_RX_DV IOMUX_PAD(0x414, 0x134, 2, 0x784, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D2__WEIM_A18 IOMUX_PAD(0x414, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D3__DISP_D3 IOMUX_PAD(0x418, 0x138, 0, 0x708, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D3__GPIO_2_3 IOMUX_PAD(0x418, 0x138, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D3__FEC_RXD1 IOMUX_PAD(0x418, 0x138, 2, 0x77C, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D3__WEIM_A19 IOMUX_PAD(0x418, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D3__FEC_COL IOMUX_PAD(0x418, 0x138, 4, 0x770, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D4__DISP_D4 IOMUX_PAD(0x41C, 0x13C, 0, 0x70c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D4__GPIO_2_4 IOMUX_PAD(0x41C, 0x13C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D4__FEC_RXD0 IOMUX_PAD(0x41C, 0x13C, 2, 0x778, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D4__WEIM_A20 IOMUX_PAD(0x41C, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D5__DISP_D5 IOMUX_PAD(0x420, 0x140, 0, 0x710, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D5__GPIO_2_5 IOMUX_PAD(0x420, 0x140, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D5__FEC_TX_EN IOMUX_PAD(0x420, 0x140, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D5__WEIM_A21 IOMUX_PAD(0x420, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D6__DISP_D6 IOMUX_PAD(0x424, 0x144, 0, 0x714, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D6__GPIO_2_6 IOMUX_PAD(0x424, 0x144, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D6__FEC_TXD1 IOMUX_PAD(0x424, 0x144, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D6__WEIM_A22 IOMUX_PAD(0x424, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D6__FEC_RX_CLK IOMUX_PAD(0x424, 0x144, 4, 0x780, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D7__DISP_D7 IOMUX_PAD(0x428, 0x148, 0, 0x718, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D7__GPIO_2_7 IOMUX_PAD(0x428, 0x148, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D7__FEC_TXD0 IOMUX_PAD(0x428, 0x148, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D7__WEIM_A23 IOMUX_PAD(0x428, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+
+
+#define MX50_PAD_DISP_WR__ELCDIF_WR IOMUX_PAD(0x42C, 0x14C, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_WR__GPIO_2_16 IOMUX_PAD(0x42C, 0x14C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_WR__ELCDIF_PIXCLK IOMUX_PAD(0x42C, 0x14C, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_WR__WEIM_A24 IOMUX_PAD(0x42C, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RD__ELCDIF_RD IOMUX_PAD(0x430, 0x150, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RD__GPIO_2_19 IOMUX_PAD(0x430, 0x150, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RD__ELCDIF_EN IOMUX_PAD(0x430, 0x150, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RD__WEIM_A25 IOMUX_PAD(0x430, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RS__ELCDIF_RS IOMUX_PAD(0x434, 0x154, 0, 0x73c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RS__GPIO_2_17 IOMUX_PAD(0x434, 0x154, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RS__ELCDIF_VSYNC IOMUX_PAD(0x434, 0x154, 2, 0x73c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RS__WEIM_A26 IOMUX_PAD(0x434, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_CS__ELCDIF_CS IOMUX_PAD(0x438, 0x158, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_CS__GPIO_2_21 IOMUX_PAD(0x438, 0x158, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_CS__ELCDIF_HSYNC IOMUX_PAD(0x438, 0x158, 2, 0x6f8, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_CS__WEIM_A27 IOMUX_PAD(0x438, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_CS__WEIM_CS3 IOMUX_PAD(0x438, 0x158, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_BUSY__ELCDIF_HSYNC IOMUX_PAD(0x43C, 0x15C, 0, 0x6f8, 2, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_BUSY__GPIO_2_18 IOMUX_PAD(0x43C, 0x15C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_BUSY__WEIM_CS3 IOMUX_PAD(0x43C, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RESET__ELCDIF_RST IOMUX_PAD(0x440, 0x160, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RESET__GPIO_2_20 IOMUX_PAD(0x440, 0x160, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RESET__WEIM_CS3 IOMUX_PAD(0x440, 0x160, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_CMD__SD3_CMD IOMUX_PAD(0x444, 0x164, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_CMD__GPIO_5_18 IOMUX_PAD(0x444, 0x164, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_CMD__NANDF_WRN IOMUX_PAD(0x444, 0x164, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_CMD__SSP_CMD IOMUX_PAD(0x444, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_CLK__SD3_CLK IOMUX_PAD(0x448, 0x168, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_CLK__GPIO_5_19 IOMUX_PAD(0x448, 0x168, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_CLK__NANDF_RDN IOMUX_PAD(0x448, 0x168, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_CLK__SSP_CLK IOMUX_PAD(0x448, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D0__SD3_D0 IOMUX_PAD(0x44C, 0x16C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D0__GPIO_5_20 IOMUX_PAD(0x44C, 0x16C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D0__NANDF_D4 IOMUX_PAD(0x44C, 0x16C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D0__SSP_D0 IOMUX_PAD(0x44C, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_D0__PLL1_BYP IOMUX_PAD(0x44C, 0x16C, 7, 0x6dc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D1__SD3_D1 IOMUX_PAD(0x450, 0x170, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D1__GPIO_5_21 IOMUX_PAD(0x450, 0x170, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D1__NANDF_D5 IOMUX_PAD(0x450, 0x170, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D1__PLL2_BYP IOMUX_PAD(0x450, 0x170, 7, 0x6e0, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D2__SD3_D2 IOMUX_PAD(0x454, 0x174, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D2__GPIO_5_22 IOMUX_PAD(0x454, 0x174, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D2__NANDF_D6 IOMUX_PAD(0x454, 0x174, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D2__SSP_D2 IOMUX_PAD(0x454, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_D2__PLL3_BYP IOMUX_PAD(0x454, 0x174, 7, 0x6e4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D3__SD3_D3 IOMUX_PAD(0x458, 0x178, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D3__GPIO_5_23 IOMUX_PAD(0x458, 0x178, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D3__NANDF_D7 IOMUX_PAD(0x458, 0x178, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D3__SSP_D3 IOMUX_PAD(0x458, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D4__SD3_D4 IOMUX_PAD(0x45C, 0x17C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D4__GPIO_5_24 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D4__NANDF_D0 IOMUX_PAD(0x45C, 0x17C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D4__SSP_D4 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D5__SD3_D5 IOMUX_PAD(0x460, 0x180, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D5__GPIO_5_25 IOMUX_PAD(0x460, 0x180, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D5__NANDF_D1 IOMUX_PAD(0x460, 0x180, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D5__SSP_D5 IOMUX_PAD(0x460, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D6__SD3_D6 IOMUX_PAD(0x464, 0x184, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D6__GPIO_5_26 IOMUX_PAD(0x464, 0x184, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D6__NANDF_D2 IOMUX_PAD(0x464, 0x184, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D6__SSP_D6 IOMUX_PAD(0x464, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D7__SD3_D7 IOMUX_PAD(0x468, 0x188, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D7__GPIO_5_27 IOMUX_PAD(0x468, 0x188, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D7__NANDF_D3 IOMUX_PAD(0x468, 0x188, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D7__SSP_D7 IOMUX_PAD(0x468, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_WP__SD3_WP IOMUX_PAD(0x46C, 0x18C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_WP__GPIO_5_28 IOMUX_PAD(0x46C, 0x18C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_WP__NANDF_RESETN IOMUX_PAD(0x46C, 0x18C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_WP__SSP_CD IOMUX_PAD(0x46C, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_WP__SD4_LCTL IOMUX_PAD(0x46C, 0x18C, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_WP__WEIM_CS3 IOMUX_PAD(0x46C, 0x18C, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D8__DISP_D8 IOMUX_PAD(0x470, 0x190, 0, 0x71c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D8__GPIO_2_8 IOMUX_PAD(0x470, 0x190, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__NANDF_CLE IOMUX_PAD(0x470, 0x190, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__SD1_LCTL IOMUX_PAD(0x470, 0x190, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D8__SD4_CMD IOMUX_PAD(0x470, 0x190, 4, 0x74c, 2, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D8__KEY_COL4 IOMUX_PAD(0x470, 0x190, 5, 0x790, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__FEC_TX_CLK IOMUX_PAD(0x470, 0x190, 6, 0x78c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D9__DISP_D9 IOMUX_PAD(0x474, 0x194, 0, 0x720, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D9__GPIO_2_9 IOMUX_PAD(0x474, 0x194, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__NANDF_ALE IOMUX_PAD(0x474, 0x194, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__SD2_LCTL IOMUX_PAD(0x474, 0x194, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D9__SD4_CLK IOMUX_PAD(0x474, 0x194, 4, 0x748, 2, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D9__KEY_ROW4 IOMUX_PAD(0x474, 0x194, 5, 0x7a0, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__FEC_RX_ER IOMUX_PAD(0x474, 0x194, 6, 0x788, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D10__DISP_D10 IOMUX_PAD(0x478, 0x198, 0, 0x724, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D10__GPIO_2_10 IOMUX_PAD(0x478, 0x198, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__NANDF_CEN0 IOMUX_PAD(0x478, 0x198, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__SD3_LCTL IOMUX_PAD(0x478, 0x198, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D10__SD4_D0 IOMUX_PAD(0x478, 0x198, 4, 0x750, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D10__KEY_COL5 IOMUX_PAD(0x478, 0x198, 5, 0x794, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__FEC_RX_DV IOMUX_PAD(0x478, 0x198, 6, 0x784, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D11__DISP_D11 IOMUX_PAD(0x47C, 0x19C, 0, 0x728, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D11__GPIO_2_11 IOMUX_PAD(0x47C, 0x19C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__NANDF_CEN1 IOMUX_PAD(0x47C, 0x19C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__SD4_D1 IOMUX_PAD(0x47C, 0x19C, 4, 0x754, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D11__KEY_ROW5 IOMUX_PAD(0x47C, 0x19C, 5, 0x7a4, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__FEC_RDAT1 IOMUX_PAD(0x47C, 0x19C, 6, 0x77c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D12__DISP_D12 IOMUX_PAD(0x480, 0x1A0, 0, 0x72c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D12__GPIO_2_12 IOMUX_PAD(0x480, 0x1A0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__NANDF_CEN2 IOMUX_PAD(0x480, 0x1A0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__SD1_CD IOMUX_PAD(0x480, 0x1A0, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D12__SD4_D2 IOMUX_PAD(0x480, 0x1A0, 4, 0x758, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D12__KEY_COL6 IOMUX_PAD(0x480, 0x1A0, 5, 0x798, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__FEC_RDAT0 IOMUX_PAD(0x480, 0x1A0, 6, 0x778, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D13__DISP_D13 IOMUX_PAD(0x484, 0x1A4, 0, 0x730, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D13__GPIO_2_13 IOMUX_PAD(0x484, 0x1A4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__NANDF_CEN3 IOMUX_PAD(0x484, 0x1A4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__SD3_CD IOMUX_PAD(0x484, 0x1A4, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D13__SD4_D3 IOMUX_PAD(0x484, 0x1A4, 4, 0x75c, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D13__KEY_ROW6 IOMUX_PAD(0x484, 0x1A4, 5, 0x7a8, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__FEC_TX_EN IOMUX_PAD(0x484, 0x1A4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D14__DISP_D14 IOMUX_PAD(0x488, 0x1A8, 0, 0x734, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D14__GPIO_2_14 IOMUX_PAD(0x488, 0x1A8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__NANDF_RDY0 IOMUX_PAD(0x488, 0x1A8, 2, 0x7b4, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__SD1_WP IOMUX_PAD(0x488, 0x1A8, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D14__SD4_WP IOMUX_PAD(0x488, 0x1A8, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D14__KEY_COL7 IOMUX_PAD(0x488, 0x1A8, 5, 0x79c, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__FEC_TDAT1 IOMUX_PAD(0x488, 0x1A8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D15__DISP_D15 IOMUX_PAD(0x48C, 0x1AC, 0, 0x738, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D15__GPIO_2_15 IOMUX_PAD(0x48C, 0x1AC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__NANDF_DQS IOMUX_PAD(0x48C, 0x1AC, 2, 0x7b0, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__SD3_RST IOMUX_PAD(0x48C, 0x1AC, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D15__SD4_CD IOMUX_PAD(0x48C, 0x1AC, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D15__KEY_ROW7 IOMUX_PAD(0x48C, 0x1AC, 5, 0x7ac, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__FEC_TDAT0 IOMUX_PAD(0x48C, 0x1AC, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D0__EPDC_D0 IOMUX_PAD(0x54C, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__GPIO_3_0 IOMUX_PAD(0x54C, 0x1B0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__WEIM_D0 IOMUX_PAD(0x54C, 0x1B0, 2, 0x7ec, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__ELCDIF_RS IOMUX_PAD(0x54C, 0x1B0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__ELCDIF_PIXCLK IOMUX_PAD(0x54C, 0x1B0, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D1__EPDC_D1 IOMUX_PAD(0x550, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__GPIO_3_1 IOMUX_PAD(0x550, 0x1B4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__WEIM_D1 IOMUX_PAD(0x550, 0x1B4, 2, 0x7f0, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__ELCDIF_CS IOMUX_PAD(0x550, 0x1B4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__ELCDIF_EN IOMUX_PAD(0x550, 0x1B4, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D2__EPDC_D2 IOMUX_PAD(0x554, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__GPIO_3_2 IOMUX_PAD(0x554, 0x1B8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__WEIM_D2 IOMUX_PAD(0x554, 0x1B8, 2, 0x7f4, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__ELCDIF_WR IOMUX_PAD(0x554, 0x1B8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC IOMUX_PAD(0x554, 0x1B8, 4, 0x73c, 2, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D3__EPDC_D3 IOMUX_PAD(0x558, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__GPIO_3_3 IOMUX_PAD(0x558, 0x1BC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__WEIM_D3 IOMUX_PAD(0x558, 0x1BC, 2, 0x7f8, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__ELCDIF_RD IOMUX_PAD(0x558, 0x1BC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC IOMUX_PAD(0x558, 0x1BC, 4, 0x6f8, 3, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D4__EPDC_D4 IOMUX_PAD(0x55C, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D4__GPIO_3_4 IOMUX_PAD(0x55C, 0x1C0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D4__WEIM_D4 IOMUX_PAD(0x55C, 0x1C0, 2, 0x7fc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D5__EPDC_D5 IOMUX_PAD(0x560, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D5__GPIO_3_5 IOMUX_PAD(0x560, 0x1C4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D5__WEIM_D5 IOMUX_PAD(0x560, 0x1C4, 2, 0x800, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D6__EPDC_D6 IOMUX_PAD(0x564, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D6__GPIO_3_6 IOMUX_PAD(0x564, 0x1C8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D6__WEIM_D6 IOMUX_PAD(0x564, 0x1C8, 2, 0x804, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D7__EPDC_D7 IOMUX_PAD(0x568, 0x1CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D7__GPIO_3_7 IOMUX_PAD(0x568, 0x1CC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D7__WEIM_D7 IOMUX_PAD(0x568, 0x1CC, 2, 0x808, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D8__EPDC_D8 IOMUX_PAD(0x56C, 0x1D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__GPIO_3_8 IOMUX_PAD(0x56C, 0x1D0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__WEIM_D8 IOMUX_PAD(0x56C, 0x1D0, 2, 0x80c, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__ELCDIF_D24 IOMUX_PAD(0x56C, 0x1D0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D9__EPDC_D9 IOMUX_PAD(0x570, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__GPIO_3_9 IOMUX_PAD(0x570, 0x1D4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__WEIM_D9 IOMUX_PAD(0x570, 0x1D4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__ELCDIF_D25 IOMUX_PAD(0x570, 0x1D4, 3, 0x810, 2, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D10__EPDC_D10 IOMUX_PAD(0x574, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__GPIO_3_10 IOMUX_PAD(0x574, 0x1D8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__WEIM_D10 IOMUX_PAD(0x574, 0x1D8, 2, 0x814, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__ELCDIF_D26 IOMUX_PAD(0x574, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D11__EPDC_D11 IOMUX_PAD(0x578, 0x1DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__GPIO_3_11 IOMUX_PAD(0x578, 0x1DC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__WEIM_D11 IOMUX_PAD(0x578, 0x1DC, 2, 0x818, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__ELCDIF_D27 IOMUX_PAD(0x578, 0x1DC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D12__EPDC_D12 IOMUX_PAD(0x57C, 0x1E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__GPIO_3_12 IOMUX_PAD(0x57C, 0x1E0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__WEIM_D12 IOMUX_PAD(0x57C, 0x1E0, 2, 0x81c, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__ELCDIF_D28 IOMUX_PAD(0x57C, 0x1E0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D13__EPDC_D13 IOMUX_PAD(0x580, 0x1E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__GPIO_3_13 IOMUX_PAD(0x580, 0x1E4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__WEIM_D13 IOMUX_PAD(0x580, 0x1E4, 2, 0x820, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__ELCDIF_D29 IOMUX_PAD(0x580, 0x1E4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D14__EPDC_D14 IOMUX_PAD(0x584, 0x1E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__GPIO_3_14 IOMUX_PAD(0x584, 0x1E8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__WEIM_D14 IOMUX_PAD(0x584, 0x1E8, 2, 0x824, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__ELCDIF_D30 IOMUX_PAD(0x584, 0x1E8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__AUD6_TXD IOMUX_PAD(0x584, 0x1E8, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D15__EPDC_D15 IOMUX_PAD(0x588, 0x1EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__GPIO_3_15 IOMUX_PAD(0x588, 0x1EC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__WEIM_D15 IOMUX_PAD(0x588, 0x1EC, 2, 0x828, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__ELCDIF_D31 IOMUX_PAD(0x588, 0x1EC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__AUD6_TXC IOMUX_PAD(0x588, 0x1EC, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK IOMUX_PAD(0x58C, 0x1F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__GPIO_3_16 IOMUX_PAD(0x58C, 0x1F0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__WEIM_D16 IOMUX_PAD(0x58C, 0x1F0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__ELCDIF_D16 IOMUX_PAD(0x58C, 0x1F0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__AUD6_TXFS IOMUX_PAD(0x58C, 0x1F0, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDSP__EPDC_GDSP IOMUX_PAD(0x590, 0x1F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__GPIO_3_17 IOMUX_PAD(0x590, 0x1F4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__WEIM_D17 IOMUX_PAD(0x590, 0x1F4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__ELCDIF_D17 IOMUX_PAD(0x590, 0x1F4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__AUD6_RXD IOMUX_PAD(0x590, 0x1F4, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDOE__EPDC_GDOE IOMUX_PAD(0x594, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__GPIO_3_18 IOMUX_PAD(0x594, 0x1F8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__WEIM_D18 IOMUX_PAD(0x594, 0x1F8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__ELCDIF_D18 IOMUX_PAD(0x594, 0x1F8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__AUD6_RXC IOMUX_PAD(0x594, 0x1F8, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDRL__EPDC_GDRL IOMUX_PAD(0x598, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__GPIO_3_19 IOMUX_PAD(0x598, 0x1FC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__WEIM_D19 IOMUX_PAD(0x598, 0x1FC, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__ELCDIF_D19 IOMUX_PAD(0x598, 0x1FC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__AUD6_RXFS IOMUX_PAD(0x598, 0x1FC, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCLK__EPDC_SDCLK IOMUX_PAD(0x59C, 0x200, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__GPIO_3_20 IOMUX_PAD(0x59C, 0x200, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__WEIM_D20 IOMUX_PAD(0x59C, 0x200, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__ELCDIF_D20 IOMUX_PAD(0x59C, 0x200, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__AUD5_TXD IOMUX_PAD(0x59C, 0x200, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOEZ__EPDC_SDOEZ IOMUX_PAD(0x5A0, 0x204, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__GPIO_3_21 IOMUX_PAD(0x5A0, 0x204, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__WEIM_D21 IOMUX_PAD(0x5A0, 0x204, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__ELCDIF_D21 IOMUX_PAD(0x5A0, 0x204, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__AUD5_TXC IOMUX_PAD(0x5A0, 0x204, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOED__EPDC_SDOED IOMUX_PAD(0x5A4, 0x208, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__GPIO_3_22 IOMUX_PAD(0x5A4, 0x208, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__WEIM_D22 IOMUX_PAD(0x5A4, 0x208, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__ELCDIF_D22 IOMUX_PAD(0x5A4, 0x208, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__AUD5_TXFS IOMUX_PAD(0x5A4, 0x208, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOE__EPDC_SDOE IOMUX_PAD(0x5A8, 0x20C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__GPIO_3_23 IOMUX_PAD(0x5A8, 0x20C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__WEIM_D23 IOMUX_PAD(0x5A8, 0x20C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__ELCDIF_D23 IOMUX_PAD(0x5A8, 0x20C, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__AUD5_RXD IOMUX_PAD(0x5A8, 0x20C, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDLE__EPDC_SDLE IOMUX_PAD(0x5AC, 0x210, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__GPIO_3_24 IOMUX_PAD(0x5AC, 0x210, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__WEIM_D24 IOMUX_PAD(0x5AC, 0x210, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__ELCDIF_D8 IOMUX_PAD(0x5AC, 0x210, 3, 0x71c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__AUD5_RXC IOMUX_PAD(0x5AC, 0x210, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCLKN__EPDC_SDCLKN IOMUX_PAD(0x5B0, 0x214, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__GPIO_3_25 IOMUX_PAD(0x5B0, 0x214, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__WEIM_D25 IOMUX_PAD(0x5B0, 0x214, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__ELCDIF_D9 IOMUX_PAD(0x5B0, 0x214, 3, 0x720, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__AUD5_RXFS IOMUX_PAD(0x5B0, 0x214, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDSHR__EPDC_SDSHR IOMUX_PAD(0x5B4, 0x218, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__GPIO_3_26 IOMUX_PAD(0x5B4, 0x218, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__WEIM_D26 IOMUX_PAD(0x5B4, 0x218, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__ELCDIF_D10 IOMUX_PAD(0x5B4, 0x218, 3, 0x724, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__AUD4_TXD IOMUX_PAD(0x5B4, 0x218, 4, 0x6c8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCOM__EPDC_PWRCOM IOMUX_PAD(0x5B8, 0x21C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__GPIO_3_27 IOMUX_PAD(0x5B8, 0x21C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__WEIM_D27 IOMUX_PAD(0x5B8, 0x21C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__ELCDIF_D11 IOMUX_PAD(0x5B8, 0x21C, 3, 0x728, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__AUD4_TXC IOMUX_PAD(0x5B8, 0x21C, 4, 0x6d4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRSTAT__EPDC_PWRSTAT IOMUX_PAD(0x5BC, 0x220, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__GPIO_3_28 IOMUX_PAD(0x5BC, 0x220, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__WEIM_D28 IOMUX_PAD(0x5BC, 0x220, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_D12 IOMUX_PAD(0x5BC, 0x220, 3, 0x72c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__AUD4_TXFS IOMUX_PAD(0x5BC, 0x220, 4, 0x6d8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL0__EPDC_PWRCTRL0 IOMUX_PAD(0x5C0, 0x224, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__GPIO_3_29 IOMUX_PAD(0x5C0, 0x224, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__WEIM_D29 IOMUX_PAD(0x5C0, 0x224, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_D13 IOMUX_PAD(0x5C0, 0x224, 3, 0x730, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__AUD4_RXD IOMUX_PAD(0x5C0, 0x224, 4, 0x6c4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL1__EPDC_PWRCTRL1 IOMUX_PAD(0x5C4, 0x228, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__GPIO_3_30 IOMUX_PAD(0x5C4, 0x228, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__WEIM_D30 IOMUX_PAD(0x5C4, 0x228, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_D14 IOMUX_PAD(0x5C4, 0x228, 3, 0x734, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__AUD4_RXC IOMUX_PAD(0x5C4, 0x228, 4, 0x6cc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL2__EPDC_PWRCTRL2 IOMUX_PAD(0x5C8, 0x22C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__GPIO_3_31 IOMUX_PAD(0x5C8, 0x22C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__WEIM_D31 IOMUX_PAD(0x5C8, 0x22C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_D15 IOMUX_PAD(0x5C8, 0x22C, 3, 0x738, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__AUD4_RXFS IOMUX_PAD(0x5C8, 0x22C, 4, 0x6d0, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT0 IOMUX_PAD(0x5C8, 0x22C, 6, 0x7b8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL3__PWRCTRL3 IOMUX_PAD(0x5CC, 0x230, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__GPIO_4_20 IOMUX_PAD(0x5CC, 0x230, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__WEIM_EB2 IOMUX_PAD(0x5CC, 0x230, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT1 IOMUX_PAD(0x5CC, 0x230, 6, 0x7bc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_VCOM0__EPDC_VCOM0 IOMUX_PAD(0x5D0, 0x234, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM0__GPIO_4_21 IOMUX_PAD(0x5D0, 0x234, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM0__WEIM_EB3 IOMUX_PAD(0x5D0, 0x234, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_VCOM1__EPDC_VCOM1 IOMUX_PAD(0x5D4, 0x238, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM1__GPIO_4_22 IOMUX_PAD(0x5D4, 0x238, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM1__WEIM_CS3 IOMUX_PAD(0x5D4, 0x238, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_BDR0__EPDC_BDR0 IOMUX_PAD(0x5D8, 0x23C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR0__GPIO_4_23 IOMUX_PAD(0x5D8, 0x23C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR0__ELCDIF_D7 IOMUX_PAD(0x5D8, 0x23C, 3, 0x718, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_BDR1__EPDC_BDR1 IOMUX_PAD(0x5DC, 0x240, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR1__GPIO_4_24 IOMUX_PAD(0x5DC, 0x240, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR1__ELCDIF_D6 IOMUX_PAD(0x5DC, 0x240, 3, 0x714, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE0__EPDC_SDCE0 IOMUX_PAD(0x5E0, 0x244, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE0__GPIO_4_25 IOMUX_PAD(0x5E0, 0x244, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE0__ELCDIF_D5 IOMUX_PAD(0x5E0, 0x244, 3, 0x710, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE1__EPDC_SDCE1 IOMUX_PAD(0x5E4, 0x248, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE1__GPIO_4_26 IOMUX_PAD(0x5E4, 0x248, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE1__ELCDIF_D4 IOMUX_PAD(0x5E4, 0x248, 2, 0x70c, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE2__EPDC_SDCE2 IOMUX_PAD(0x5E8, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE2__GPIO_4_27 IOMUX_PAD(0x5E8, 0x24C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT3 IOMUX_PAD(0x5E8, 0x24C, 3, 0x708, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE3__EPDC_SDCE3 IOMUX_PAD(0x5EC, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE3__GPIO_4_28 IOMUX_PAD(0x5EC, 0x250, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE3__ELCDIF_D2 IOMUX_PAD(0x5EC, 0x250, 3, 0x704, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE4__EPDC_SDCE4 IOMUX_PAD(0x5F0, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE4__GPIO_4_29 IOMUX_PAD(0x5F0, 0x254, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE4__ELCDIF_D1 IOMUX_PAD(0x5F0, 0x254, 3, 0x700, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE5__EPDC_SDCE5 IOMUX_PAD(0x5F4, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE5__GPIO_4_30 IOMUX_PAD(0x5F4, 0x258, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE5__ELCDIF_D0 IOMUX_PAD(0x5F4, 0x258, 3, 0x6fc, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA0__WEIM_A0 IOMUX_PAD(0x5F8, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA0__GPIO_1_0 IOMUX_PAD(0x5F8, 0x25C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA0__KEY_COL4 IOMUX_PAD(0x5f8, 0x25C, 3, 0x790, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA1__WEIM_A1 IOMUX_PAD(0x5FC, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA1__GPIO_1_1 IOMUX_PAD(0x5FC, 0x260, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA1__KEY_ROW4 IOMUX_PAD(0x5fc, 0x260, 3, 0x7a0, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA2__WEIM_A2 IOMUX_PAD(0x600, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA2__GPIO_1_2 IOMUX_PAD(0x600, 0x264, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA2__KEY_COL5 IOMUX_PAD(0x600, 0x264, 3, 0x794, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA3__WEIM_A3 IOMUX_PAD(0x604, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA3__GPIO_1_3 IOMUX_PAD(0x604, 0x268, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA3__KEY_ROW5 IOMUX_PAD(0x604, 0x268, 3, 0x7a4, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA4__WEIM_A4 IOMUX_PAD(0x608, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA4__GPIO_1_4 IOMUX_PAD(0x608, 0x26C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA4__KEY_COL6 IOMUX_PAD(0x608, 0x26C, 3, 0x798, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA5__WEIM_A5 IOMUX_PAD(0x60C, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA5__GPIO_1_5 IOMUX_PAD(0x60C, 0x270, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA5__KEY_ROW6 IOMUX_PAD(0x60C, 0x270, 3, 0x7a8, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA6__WEIM_A6 IOMUX_PAD(0x610, 0x274, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA6__GPIO_1_6 IOMUX_PAD(0x610, 0x274, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA6__KEY_COL7 IOMUX_PAD(0x610, 0x274, 3, 0x79c, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA7__WEIM_A7 IOMUX_PAD(0x614, 0x278, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA7__GPIO_1_7 IOMUX_PAD(0x614, 0x278, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA7__KEY_ROW7 IOMUX_PAD(0x614, 0x278, 3, 0x7ac, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA8__WEIM_A8 IOMUX_PAD(0x618, 0x27C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA8__GPIO_1_8 IOMUX_PAD(0x618, 0x27C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA8__NANDF_CLE IOMUX_PAD(0x618, 0x27C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA9__WEIM_A9 IOMUX_PAD(0x61C, 0x280, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA9__GPIO_1_9 IOMUX_PAD(0x61C, 0x280, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA9__NANDF_ALE IOMUX_PAD(0x61C, 0x280, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA10__WEIM_A10 IOMUX_PAD(0x620, 0x284, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA10__GPIO_1_10 IOMUX_PAD(0x620, 0x284, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA10__NANDF_CE0 IOMUX_PAD(0x620, 0x284, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA11__WEIM_A11 IOMUX_PAD(0x624, 0x288, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA11__GPIO_1_11 IOMUX_PAD(0x624, 0x288, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA11__NANDF_CE1 IOMUX_PAD(0x624, 0x288, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA12__WEIM_A12 IOMUX_PAD(0x628, 0x28C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA12__GPIO_1_12 IOMUX_PAD(0x628, 0x28C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA12__NANDF_CE2 IOMUX_PAD(0x628, 0x28C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EIM_DA12__EPDC_SDCE6 IOMUX_PAD(0x628, 0x28C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA13__WEIM_A13 IOMUX_PAD(0x62C, 0x290, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA13__GPIO_1_13 IOMUX_PAD(0x62C, 0x290, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA13__NANDF_CE3 IOMUX_PAD(0x62C, 0x290, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PIN_EIM_DA13__EPDC_SDCE7 IOMUX_PAD(0x62C, 0x290, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA14__WEIM_A14 IOMUX_PAD(0x630, 0x294, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA14__GPIO_1_14 IOMUX_PAD(0x630, 0x294, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA14__NANDF_READY IOMUX_PAD(0x630, 0x294, 2, 0x7B4, 2, PAD_CTL_PKE | \
+ PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_EIM_DA14__EPDC_SDCE8 IOMUX_PAD(0x630, 0x294, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA15__WEIM_A15 IOMUX_PAD(0x634, 0x298, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA15__GPIO_1_15 IOMUX_PAD(0x634, 0x298, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA15__NANDF_DQS IOMUX_PAD(0x634, 0x298, 2, 0x7B0, 2, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EIM_DA15__EPDC_SDCE9 IOMUX_PAD(0x634, 0x298, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS2__WEIM_CS2 IOMUX_PAD(0x638, 0x29C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS2__GPIO_1_16 IOMUX_PAD(0x638, 0x29C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS2__WEIM_A27 IOMUX_PAD(0x638, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS1__WEIM_CS1 IOMUX_PAD(0x63C, 0x2A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS1__GPIO_1_17 IOMUX_PAD(0x63C, 0x2A0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS0__WEIM_CS0 IOMUX_PAD(0x640, 0x2A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS0__GPIO_1_18 IOMUX_PAD(0x640, 0x2A4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_EB0__WEIM_EB0 IOMUX_PAD(0x644, 0x2A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_EB0__GPIO_1_19 IOMUX_PAD(0x644, 0x2A8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_EB1__WEIM_EB1 IOMUX_PAD(0x648, 0x2AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_EB1__GPIO_1_20 IOMUX_PAD(0x648, 0x2AC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_WAIT__WEIM_WAIT IOMUX_PAD(0x64C, 0x2B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_WAIT__GPIO_1_21 IOMUX_PAD(0x64C, 0x2B0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_BCLK__WEIM_BCLK IOMUX_PAD(0x650, 0x2B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_BCLK__GPIO_1_22 IOMUX_PAD(0x650, 0x2B4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_RDY__WEIM_RDY IOMUX_PAD(0x654, 0x2B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_RDY__GPIO_1_23 IOMUX_PAD(0x654, 0x2B8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_OE__WEIM_OE IOMUX_PAD(0x658, 0x2BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_OE__GPIO_1_24 IOMUX_PAD(0x658, 0x2BC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_RW__WEIM_RW IOMUX_PAD(0x65C, 0x2C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_RW__GPIO_1_25 IOMUX_PAD(0x65C, 0x2C0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_LBA__WEIM_LBA IOMUX_PAD(0x660, 0x2C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_LBA__GPIO_1_26 IOMUX_PAD(0x660, 0x2C4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CRE__WEIM_CRE IOMUX_PAD(0x664, 0x2C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CRE__GPIO_1_27 IOMUX_PAD(0x664, 0x2C8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX50_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index d7a41e9a2605..b6767f90ef14 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -15,373 +15,1553 @@
#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)
+#define MX51_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_HYS | PAD_CTL_SRE_FAST)
#define MX51_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
- PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS)
-#define MX51_USBH1_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
- PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
- PAD_CTL_PKE | PAD_CTL_HYS)
-#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
- PAD_CTL_SRE_FAST)
-#define MX51_GPIO_PAD_CTRL_2 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
- PAD_CTL_PUS_100K_UP)
-#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
- PAD_CTL_SRE_FAST)
-#define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
- PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_SRE_FAST | \
- PAD_CTL_DVS)
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS)
+#define MX51_ESDHC_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS)
+#define MX51_USBH1_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS | PAD_CTL_PUE)
+#define MX51_ECSPI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_HYS | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
+#define MX51_SDHCI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_PUE | \
+ PAD_CTL_SRE_FAST | PAD_CTL_DVS)
+#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | PAD_CTL_SRE_FAST)
-#define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
- PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS)
-#define MX51_PAD_CTRL_2 (PAD_CTL_HYS | PAD_CTL_PKE)
-#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
-#define MX51_PAD_CTRL_4 (PAD_CTL_DVS | PAD_CTL_HYS | PAD_CTL_PKE)
-#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+#define MX51_PAD_CTRL_2 (PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_CTRL_4 (PAD_CTL_PKE | PAD_CTL_DVS | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
/*
* 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>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO<unit>_<num>
* See also iomux-v3.h
*/
-/* PAD MUX ALT INPSE PATH PADCTRL */
-#define MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x7a8, 0x01c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x7a8, 0x020, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x7a8, 0x024, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x7a8, 0x028, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x7ac, 0x02c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x7ac, 0x030, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x7ac, 0x034, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x7ac, 0x038, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x7b0, 0x03c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x7b0, 0x040, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x7b0, 0x044, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x7b0, 0x048, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x7bc, 0x04c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x7bc, 0x050, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x7bc, 0x054, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x7bc, 0x058, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D16__GPIO_2_0 IOMUX_PAD(0x3f0, 0x05c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D16__I2C1_SDA IOMUX_PAD(0x3f0, 0x05c, (4 | IOMUX_CONFIG_SION), \
- 0x09b4, 0, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_EIM_D17__GPIO_2_1 IOMUX_PAD(0x3f4, 0x060, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D18__GPIO_2_2 IOMUX_PAD(0x3f8, 0x064, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D19__GPIO_2_3 IOMUX_PAD(0x3fc, 0x068, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D19__I2C1_SCL IOMUX_PAD(0x3fc, 0x068, (4 | IOMUX_CONFIG_SION), \
- 0x09b0, 0, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_EIM_D20__GPIO_2_4 IOMUX_PAD(0x400, 0x06c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D21__GPIO_2_5 IOMUX_PAD(0x404, 0x070, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_EIM_D22__GPIO_2_6 IOMUX_PAD(0x408, 0x074, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D23__GPIO_2_7 IOMUX_PAD(0x40c, 0x078, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D24__UART3_CTS IOMUX_PAD(0x410, 0x07c, 3, 0x0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D25__UART3_RXD IOMUX_PAD(0x414, 0x080, 3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D25__UART2_CTS IOMUX_PAD(0x414, 0x080, 4, 0x0, 0, MX51_UART2_PAD_CTRL)
-#define MX51_PAD_EIM_D26__UART3_TXD IOMUX_PAD(0x418, 0x084, 3, 0x0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D26__UART2_RTS IOMUX_PAD(0x418, 0x084, 4, 0x9e8, 3, MX51_UART2_PAD_CTRL)
-#define MX51_PAD_EIM_D27__UART3_RTS IOMUX_PAD(0x41c, 0x088, 3, 0x9f0, 3, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x08c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x090, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x094, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42c, 0x09c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A16__GPIO_2_10 IOMUX_PAD(0x430, 0x09c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A17__GPIO_2_11 IOMUX_PAD(0x434, 0x0a0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A18__GPIO_2_12 IOMUX_PAD(0x438, 0x0a4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A19__GPIO_2_13 IOMUX_PAD(0x43c, 0x0a8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A20__GPIO_2_14 IOMUX_PAD(0x440, 0x0ac, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A21__GPIO_2_15 IOMUX_PAD(0x444, 0x0b0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A22__GPIO_2_16 IOMUX_PAD(0x448, 0x0b4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A23__GPIO_2_17 IOMUX_PAD(0x44c, 0x0b8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A24__GPIO_2_18 IOMUX_PAD(0x450, 0x0bc, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A25__GPIO_2_19 IOMUX_PAD(0x454, 0x0c0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A26__GPIO_2_20 IOMUX_PAD(0x458, 0x0c4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_A27__GPIO_2_21 IOMUX_PAD(0x45c, 0x0c8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB2__GPIO_2_22 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0x0d4, 3, 0x0, 0, MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP)
-#define MX51_PAD_EIM_EB3__GPIO_2_23 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB3__FEC_RDAT1 IOMUX_PAD(0x46c, 0x0d8, 3, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_EIM_OE__GPIO_2_24 IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS0__GPIO_2_25 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS1__GPIO_2_26 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS2__GPIO_2_27 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS2__FEC_RDAT2 IOMUX_PAD(0x47c, 0x0e8, 3, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_EIM_CS3__GPIO_2_28 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS3__FEC_RDAT3 IOMUX_PAD(0x480, 0x0ec, 3, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_EIM_CS4__GPIO_2_29 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0x0f0, 3, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_EIM_CS5__GPIO_2_30 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0x0f4, 3, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_EIM_DTACK__GPIO_2_31 IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_LBA__GPIO_3_1 IOMUX_PAD(0x494, 0x0FC, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_CRE__GPIO_3_2 IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_WE_B__GPIO_3_3 IOMUX_PAD(0x4E4, 0x108, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RE_B__GPIO_3_4 IOMUX_PAD(0x4E8, 0x10C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_ALE__GPIO_3_5 IOMUX_PAD(0x4EC, 0x110, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CLE__GPIO_3_6 IOMUX_PAD(0x4F0, 0x114, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_WP_B__GPIO_3_7 IOMUX_PAD(0x4F4, 0x118, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RB0__GPIO_3_8 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RB1__GPIO_3_9 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RB2__GPIO_3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_NANDF_RB3__GPIO_3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_NANDF_RB3__FEC_RXCLK IOMUX_PAD(0x504, 0x128, 1, 0x0, 0, MX51_PAD_CTRL_2)
-#define MX51_PAD_NANDF_RB6__FEC_RDAT0 IOMUX_PAD(0x5DC, 0x134, 1, 0x0, 0, MX51_PAD_CTRL_4)
-#define MX51_PAD_NANDF_RB7__FEC_TDAT0 IOMUX_PAD(0x5E0, 0x138, 1, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_GPIO_NAND__GPIO_3_12 IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS0__GPIO_3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS1__GPIO_3_17 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS2__GPIO_3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_CS3__GPIO_3_19 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_CS4__GPIO_3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS4__FEC_TDAT1 IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_CS5__GPIO_3_21 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS5__FEC_TDAT2 IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_CS6__GPIO_3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS6__FEC_TDAT3 IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_CS7__GPIO_3_23 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_PAD_CTRL_5)
-#define MX51_PAD_NANDF_RDY_INT__GPIO_3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0, 0, MX51_PAD_CTRL_4)
-#define MX51_PAD_NANDF_D15__GPIO_3_25 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53C, 0x154, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_NANDF_D14__GPIO_3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D13__GPIO_3_27 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D12__GPIO_3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D11__GPIO_3_29 IOMUX_PAD(0x54C, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D10__GPIO_3_30 IOMUX_PAD(0x550, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D9__GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D8__GPIO_4_0 IOMUX_PAD(0x558, 0x170, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D7__GPIO_4_1 IOMUX_PAD(0x55C, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D6__GPIO_4_2 IOMUX_PAD(0x560, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D5__GPIO_4_3 IOMUX_PAD(0x564, 0x17C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D4__GPIO_4_4 IOMUX_PAD(0x568, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D3__GPIO_4_5 IOMUX_PAD(0x56C, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D2__GPIO_4_6 IOMUX_PAD(0x570, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D1__GPIO_4_7 IOMUX_PAD(0x574, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_NANDF_D0__GPIO_4_8 IOMUX_PAD(0x578, 0x190, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D8__GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D9__GPIO_3_13 IOMUX_PAD(0x580, 0x198, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5B4, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5B8, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_PKE0__CSI1_PKE0 IOMUX_PAD(0x860, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D12__GPIO_4_9 IOMUX_PAD(0x5BC, 0x1CC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D13__GPIO_4_10 IOMUX_PAD(0x5C0, 0x1D0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D14__GPIO_4_11 IOMUX_PAD(0x5C4, 0x1D4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D15__GPIO_4_12 IOMUX_PAD(0x5C8, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D16__GPIO_4_11 IOMUX_PAD(0x5CC, 0x1DC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D17__GPIO_4_12 IOMUX_PAD(0x5D0, 0x1E0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D18__GPIO_4_11 IOMUX_PAD(0x5D4, 0x1E4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_D19__GPIO_4_12 IOMUX_PAD(0x5D8, 0x1E8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_VSYNC__GPIO_4_13 IOMUX_PAD(0x5DC, 0x1EC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_HSYNC__GPIO_4_14 IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_PIXCLK__GPIO_4_15 IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_I2C1_CLK__GPIO_4_16 IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_I2C1_DAT__GPIO_4_17 IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_TXD__GPIO_4_18 IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_RXD__GPIO_4_19 IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_CK__GPIO_4_20 IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_AUD3_BB_FS__GPIO_4_21 IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_MOSI__GPIO_4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_MISO__GPIO_4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_SS0__GPIO_4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_SS1__GPIO_4_25 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_RDY__GPIO_4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL)
-#define MX51_PAD_CSPI1_SCLK__GPIO_4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
-#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
-#define MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, 0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
-#define MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, 0, 0x0, 0, MX51_UART1_PAD_CTRL)
-#define MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, 0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
-#define MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62C, 0x23C, 0, 0x0, 0, MX51_UART2_PAD_CTRL)
-#define MX51_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x630, 0x240, 1, 0x9f4, 4, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_UART3_RXD__GPIO_1_22 IOMUX_PAD(0x630, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x634, 0x244, 1, 0x0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_UART3_TXD__GPIO_1_23 IOMUX_PAD(0x634, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_OWIRE_LINE__GPIO_1_24 IOMUX_PAD(0x638, 0x248, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL4__UART3_RTS IOMUX_PAD(0x65C, 0x26C, 2, 0x9f0, 4, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_KEY_COL4__I2C2_SCL IOMUX_PAD(0x65C, 0x26C, (3 | IOMUX_CONFIG_SION), \
- 0x09b8, 1, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL5__UART3_CTS IOMUX_PAD(0x660, 0x270, 2, 0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_KEY_COL5__I2C2_SDA IOMUX_PAD(0x660, 0x270, (3 | IOMUX_CONFIG_SION), \
- 0x09bc, 1, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_STP__GPIO_1_27 IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_DI1_PIN11__GPIO_3_0 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x978, 1, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x97c, 1, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x980, 1, NO_PAD_CTRL)
-#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x984, 1, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x988, 1, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x98c, 1, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x990, 1, NO_PAD_CTRL)
-#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x994, 1, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP1__DI_GP1 IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP2__DI_GP2 IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP3__DI_GP3 IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP4__DI_GP4 IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT6__GPIO_1_19 IOMUX_PAD(0x774, 0x36C, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT7__GPIO_1_29 IOMUX_PAD(0x778, 0x370, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT8__GPIO_1_30 IOMUX_PAD(0x77C, 0x374, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT9__GPIO_1_31 IOMUX_PAD(0x780, 0x378, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS)
-#define MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, IOMUX_CONFIG_SION, 0x0, 1, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS)
-#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, IOMUX_CONFIG_SION, 0x0, 0, \
- MX51_SDHCI_PAD_CTRL)
-#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_2__I2C2_SCL IOMUX_PAD(0x7D4, 0x3CC, (2 | IOMUX_CONFIG_SION), \
- 0x9b8, 3, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_3__I2C2_SDA IOMUX_PAD(0x7D8, 0x3D0, (2 | IOMUX_CONFIG_SION), \
- 0x9bc, 3, MX51_I2C_PAD_CTRL)
-#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+/* Raw pin modes without pad control */
+/* PAD MUX ALT INPSE PATH PADCTRL */
+#define _MX51_PAD_EIM_D16__AUD4_RXFS IOMUX_PAD(0x3f0, 0x5c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__AUD5_TXD IOMUX_PAD(0x3f0, 0x5c, 7, 0x08d8, 0, 0)
+#define _MX51_PAD_EIM_D16__EIM_D16 IOMUX_PAD(0x3f0, 0x5c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__GPIO2_0 IOMUX_PAD(0x3f0, 0x5c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__I2C1_SDA IOMUX_PAD(0x3f0, 0x5c, 0x14, 0x09b4, 0, 0)
+#define _MX51_PAD_EIM_D16__UART2_CTS IOMUX_PAD(0x3f0, 0x5c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__USBH2_DATA0 IOMUX_PAD(0x3f0, 0x5c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__AUD5_RXD IOMUX_PAD(0x3f4, 0x60, 7, 0x08d4, 0, 0)
+#define _MX51_PAD_EIM_D17__EIM_D17 IOMUX_PAD(0x3f4, 0x60, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__GPIO2_1 IOMUX_PAD(0x3f4, 0x60, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__UART2_RXD IOMUX_PAD(0x3f4, 0x60, 3, 0x09ec, 0, 0)
+#define _MX51_PAD_EIM_D17__UART3_CTS IOMUX_PAD(0x3f4, 0x60, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__USBH2_DATA1 IOMUX_PAD(0x3f4, 0x60, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__AUD5_TXC IOMUX_PAD(0x3f8, 0x64, 7, 0x08e4, 0, 0)
+#define _MX51_PAD_EIM_D18__EIM_D18 IOMUX_PAD(0x3f8, 0x64, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__GPIO2_2 IOMUX_PAD(0x3f8, 0x64, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__UART2_TXD IOMUX_PAD(0x3f8, 0x64, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__UART3_RTS IOMUX_PAD(0x3f8, 0x64, 4, 0x09f0, 1, 0)
+#define _MX51_PAD_EIM_D18__USBH2_DATA2 IOMUX_PAD(0x3f8, 0x64, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__AUD4_RXC IOMUX_PAD(0x3fc, 0x68, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__AUD5_TXFS IOMUX_PAD(0x3fc, 0x68, 7, 0x08e8, 0, 0)
+#define _MX51_PAD_EIM_D19__EIM_D19 IOMUX_PAD(0x3fc, 0x68, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__GPIO2_3 IOMUX_PAD(0x3fc, 0x68, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__I2C1_SCL IOMUX_PAD(0x3fc, 0x68, 0x14, 0x09b0, 0, 0)
+#define _MX51_PAD_EIM_D19__UART2_RTS IOMUX_PAD(0x3fc, 0x68, 3, 0x09e8, 1, 0)
+#define _MX51_PAD_EIM_D19__USBH2_DATA3 IOMUX_PAD(0x3fc, 0x68, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__AUD4_TXD IOMUX_PAD(0x400, 0x6c, 5, 0x08c8, 0, 0)
+#define _MX51_PAD_EIM_D20__EIM_D20 IOMUX_PAD(0x400, 0x6c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__GPIO2_4 IOMUX_PAD(0x400, 0x6c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__SRTC_ALARM_DEB IOMUX_PAD(0x400, 0x6c, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__USBH2_DATA4 IOMUX_PAD(0x400, 0x6c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__AUD4_RXD IOMUX_PAD(0x404, 0x70, 5, 0x08c4, 0, 0)
+#define _MX51_PAD_EIM_D21__EIM_D21 IOMUX_PAD(0x404, 0x70, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__GPIO2_5 IOMUX_PAD(0x404, 0x70, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__SRTC_ALARM_DEB IOMUX_PAD(0x404, 0x70, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__USBH2_DATA5 IOMUX_PAD(0x404, 0x70, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__AUD4_TXC IOMUX_PAD(0x408, 0x74, 5, 0x08cc, 0, 0)
+#define _MX51_PAD_EIM_D22__EIM_D22 IOMUX_PAD(0x408, 0x74, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__GPIO2_6 IOMUX_PAD(0x408, 0x74, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__USBH2_DATA6 IOMUX_PAD(0x408, 0x74, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__AUD4_TXFS IOMUX_PAD(0x40c, 0x78, 5, 0x08d0, 0, 0)
+#define _MX51_PAD_EIM_D23__EIM_D23 IOMUX_PAD(0x40c, 0x78, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__GPIO2_7 IOMUX_PAD(0x40c, 0x78, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__SPDIF_OUT1 IOMUX_PAD(0x40c, 0x78, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__USBH2_DATA7 IOMUX_PAD(0x40c, 0x78, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__AUD6_RXFS IOMUX_PAD(0x410, 0x7c, 5, 0x08f8, 0, 0)
+#define _MX51_PAD_EIM_D24__EIM_D24 IOMUX_PAD(0x410, 0x7c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__GPIO2_8 IOMUX_PAD(0x410, 0x7c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__I2C2_SDA IOMUX_PAD(0x410, 0x7c, 0x14, 0x09bc, 0, 0)
+#define _MX51_PAD_EIM_D24__UART3_CTS IOMUX_PAD(0x410, 0x7c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__USBOTG_DATA0 IOMUX_PAD(0x410, 0x7c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__EIM_D25 IOMUX_PAD(0x414, 0x80, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__KEY_COL6 IOMUX_PAD(0x414, 0x80, 1, 0x09c8, 0, 0)
+#define _MX51_PAD_EIM_D25__UART2_CTS IOMUX_PAD(0x414, 0x80, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__UART3_RXD IOMUX_PAD(0x414, 0x80, 3, 0x09f4, 0, 0)
+#define _MX51_PAD_EIM_D25__USBOTG_DATA1 IOMUX_PAD(0x414, 0x80, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__EIM_D26 IOMUX_PAD(0x418, 0x84, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__KEY_COL7 IOMUX_PAD(0x418, 0x84, 1, 0x09cc, 0, 0)
+#define _MX51_PAD_EIM_D26__UART2_RTS IOMUX_PAD(0x418, 0x84, 4, 0x09e8, 3, 0)
+#define _MX51_PAD_EIM_D26__UART3_TXD IOMUX_PAD(0x418, 0x84, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__USBOTG_DATA2 IOMUX_PAD(0x418, 0x84, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__AUD6_RXC IOMUX_PAD(0x41c, 0x88, 5, 0x08f4, 0, 0)
+#define _MX51_PAD_EIM_D27__EIM_D27 IOMUX_PAD(0x41c, 0x88, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__GPIO2_9 IOMUX_PAD(0x41c, 0x88, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__I2C2_SCL IOMUX_PAD(0x41c, 0x88, 0x14, 0x09b8, 0, 0)
+#define _MX51_PAD_EIM_D27__UART3_RTS IOMUX_PAD(0x41c, 0x88, 3, 0x09f0, 3, 0)
+#define _MX51_PAD_EIM_D27__USBOTG_DATA3 IOMUX_PAD(0x41c, 0x88, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D28__AUD6_TXD IOMUX_PAD(0x420, 0x8c, 5, 0x08f0, 0, 0)
+#define _MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x8c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D28__KEY_ROW4 IOMUX_PAD(0x420, 0x8c, 1, 0x09d0, 0, 0)
+#define _MX51_PAD_EIM_D28__USBOTG_DATA4 IOMUX_PAD(0x420, 0x8c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D29__AUD6_RXD IOMUX_PAD(0x424, 0x90, 5, 0x08ec, 0, 0)
+#define _MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x90, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D29__KEY_ROW5 IOMUX_PAD(0x424, 0x90, 1, 0x09d4, 0, 0)
+#define _MX51_PAD_EIM_D29__USBOTG_DATA5 IOMUX_PAD(0x424, 0x90, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D30__AUD6_TXC IOMUX_PAD(0x428, 0x94, 5, 0x08fc, 0, 0)
+#define _MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x94, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D30__KEY_ROW6 IOMUX_PAD(0x428, 0x94, 1, 0x09d8, 0, 0)
+#define _MX51_PAD_EIM_D30__USBOTG_DATA6 IOMUX_PAD(0x428, 0x94, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D31__AUD6_TXFS IOMUX_PAD(0x42c, 0x98, 5, 0x0900, 0, 0)
+#define _MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42c, 0x98, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D31__KEY_ROW7 IOMUX_PAD(0x42c, 0x98, 1, 0x09dc, 0, 0)
+#define _MX51_PAD_EIM_D31__USBOTG_DATA7 IOMUX_PAD(0x42c, 0x98, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__EIM_A16 IOMUX_PAD(0x430, 0x9c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__GPIO2_10 IOMUX_PAD(0x430, 0x9c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__OSC_FREQ_SEL0 IOMUX_PAD(0x430, 0x9c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__EIM_A17 IOMUX_PAD(0x434, 0xa0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__GPIO2_11 IOMUX_PAD(0x434, 0xa0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__OSC_FREQ_SEL1 IOMUX_PAD(0x434, 0xa0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__BOOT_LPB0 IOMUX_PAD(0x438, 0xa4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__EIM_A18 IOMUX_PAD(0x438, 0xa4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__GPIO2_12 IOMUX_PAD(0x438, 0xa4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__BOOT_LPB1 IOMUX_PAD(0x43c, 0xa8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__EIM_A19 IOMUX_PAD(0x43c, 0xa8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__GPIO2_13 IOMUX_PAD(0x43c, 0xa8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__BOOT_UART_SRC0 IOMUX_PAD(0x440, 0xac, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__EIM_A20 IOMUX_PAD(0x440, 0xac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__GPIO2_14 IOMUX_PAD(0x440, 0xac, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__BOOT_UART_SRC1 IOMUX_PAD(0x444, 0xb0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__EIM_A21 IOMUX_PAD(0x444, 0xb0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__GPIO2_15 IOMUX_PAD(0x444, 0xb0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A22__EIM_A22 IOMUX_PAD(0x448, 0xb4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A22__GPIO2_16 IOMUX_PAD(0x448, 0xb4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__BOOT_HPN_EN IOMUX_PAD(0x44c, 0xb8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__EIM_A23 IOMUX_PAD(0x44c, 0xb8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__GPIO2_17 IOMUX_PAD(0x44c, 0xb8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__EIM_A24 IOMUX_PAD(0x450, 0xbc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__GPIO2_18 IOMUX_PAD(0x450, 0xbc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__USBH2_CLK IOMUX_PAD(0x450, 0xbc, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__DISP1_PIN4 IOMUX_PAD(0x454, 0xc0, 6, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__EIM_A25 IOMUX_PAD(0x454, 0xc0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__GPIO2_19 IOMUX_PAD(0x454, 0xc0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__USBH2_DIR IOMUX_PAD(0x454, 0xc0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__CSI1_DATA_EN IOMUX_PAD(0x458, 0xc4, 5, 0x09a0, 0, 0)
+#define _MX51_PAD_EIM_A26__DISP2_EXT_CLK IOMUX_PAD(0x458, 0xc4, 6, 0x0908, 0, 0)
+#define _MX51_PAD_EIM_A26__EIM_A26 IOMUX_PAD(0x458, 0xc4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__GPIO2_20 IOMUX_PAD(0x458, 0xc4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__USBH2_STP IOMUX_PAD(0x458, 0xc4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__CSI2_DATA_EN IOMUX_PAD(0x45c, 0xc8, 5, 0x099c, 0, 0)
+#define _MX51_PAD_EIM_A27__DISP1_PIN1 IOMUX_PAD(0x45c, 0xc8, 6, 0x09a4, 0, 0)
+#define _MX51_PAD_EIM_A27__EIM_A27 IOMUX_PAD(0x45c, 0xc8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__GPIO2_21 IOMUX_PAD(0x45c, 0xc8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__USBH2_NXT IOMUX_PAD(0x45c, 0xc8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0xcc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0xd0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__AUD5_RXFS IOMUX_PAD(0x468, 0xd4, 6, 0x08e0, 0, 0)
+#define _MX51_PAD_EIM_EB2__CSI1_D2 IOMUX_PAD(0x468, 0xd4, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__EIM_EB2 IOMUX_PAD(0x468, 0xd4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0xd4, 3, 0x0954, 0, 0)
+#define _MX51_PAD_EIM_EB2__GPIO2_22 IOMUX_PAD(0x468, 0xd4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__GPT_CMPOUT1 IOMUX_PAD(0x468, 0xd4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__AUD5_RXC IOMUX_PAD(0x46c, 0xd8, 6, 0x08dc, 0, 0)
+#define _MX51_PAD_EIM_EB3__CSI1_D3 IOMUX_PAD(0x46c, 0xd8, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__EIM_EB3 IOMUX_PAD(0x46c, 0xd8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__FEC_RDATA1 IOMUX_PAD(0x46c, 0xd8, 3, 0x095c, 0, 0)
+#define _MX51_PAD_EIM_EB3__GPIO2_23 IOMUX_PAD(0x46c, 0xd8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__GPT_CMPOUT2 IOMUX_PAD(0x46c, 0xd8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_OE__EIM_OE IOMUX_PAD(0x470, 0xdc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_OE__GPIO2_24 IOMUX_PAD(0x470, 0xdc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS0__EIM_CS0 IOMUX_PAD(0x474, 0xe0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS0__GPIO2_25 IOMUX_PAD(0x474, 0xe0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS1__EIM_CS1 IOMUX_PAD(0x478, 0xe4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS1__GPIO2_26 IOMUX_PAD(0x478, 0xe4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__AUD5_TXD IOMUX_PAD(0x47c, 0xe8, 6, 0x08d8, 1, 0)
+#define _MX51_PAD_EIM_CS2__CSI1_D4 IOMUX_PAD(0x47c, 0xe8, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__EIM_CS2 IOMUX_PAD(0x47c, 0xe8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__FEC_RDATA2 IOMUX_PAD(0x47c, 0xe8, 3, 0x0960, 0, 0)
+#define _MX51_PAD_EIM_CS2__GPIO2_27 IOMUX_PAD(0x47c, 0xe8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__USBOTG_STP IOMUX_PAD(0x47c, 0xe8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__AUD5_RXD IOMUX_PAD(0x480, 0xec, 6, 0x08d4, 1, 0)
+#define _MX51_PAD_EIM_CS3__CSI1_D5 IOMUX_PAD(0x480, 0xec, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__EIM_CS3 IOMUX_PAD(0x480, 0xec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__FEC_RDATA3 IOMUX_PAD(0x480, 0xec, 3, 0x0964, 0, 0)
+#define _MX51_PAD_EIM_CS3__GPIO2_28 IOMUX_PAD(0x480, 0xec, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__USBOTG_NXT IOMUX_PAD(0x480, 0xec, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__AUD5_TXC IOMUX_PAD(0x484, 0xf0, 6, 0x08e4, 1, 0)
+#define _MX51_PAD_EIM_CS4__CSI1_D6 IOMUX_PAD(0x484, 0xf0, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__EIM_CS4 IOMUX_PAD(0x484, 0xf0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0xf0, 3, 0x0970, 0, 0)
+#define _MX51_PAD_EIM_CS4__GPIO2_29 IOMUX_PAD(0x484, 0xf0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__USBOTG_CLK IOMUX_PAD(0x484, 0xf0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__AUD5_TXFS IOMUX_PAD(0x488, 0xf4, 6, 0x08e8, 1, 0)
+#define _MX51_PAD_EIM_CS5__CSI1_D7 IOMUX_PAD(0x488, 0xf4, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__DISP1_EXT_CLK IOMUX_PAD(0x488, 0xf4, 4, 0x0904, 0, 0)
+#define _MX51_PAD_EIM_CS5__EIM_CS5 IOMUX_PAD(0x488, 0xf4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0xf4, 3, 0x0950, 0, 0)
+#define _MX51_PAD_EIM_CS5__GPIO2_30 IOMUX_PAD(0x488, 0xf4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__USBOTG_DIR IOMUX_PAD(0x488, 0xf4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DTACK__EIM_DTACK IOMUX_PAD(0x48c, 0xf8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DTACK__GPIO2_31 IOMUX_PAD(0x48c, 0xf8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_LBA__EIM_LBA IOMUX_PAD(0x494, 0xfc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_LBA__GPIO3_1 IOMUX_PAD(0x494, 0xfc, 1, 0x0978, 0, 0)
+#define _MX51_PAD_EIM_CRE__EIM_CRE IOMUX_PAD(0x4a0, 0x100, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CRE__GPIO3_2 IOMUX_PAD(0x4a0, 0x100, 1, 0x097c, 0, 0)
+#define _MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4d0, 0x104, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__GPIO3_3 IOMUX_PAD(0x4e4, 0x108, 3, 0x0980, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__NANDF_WE_B IOMUX_PAD(0x4e4, 0x108, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__PATA_DIOW IOMUX_PAD(0x4e4, 0x108, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__SD3_DATA0 IOMUX_PAD(0x4e4, 0x108, 2, 0x093c, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__GPIO3_4 IOMUX_PAD(0x4e8, 0x10c, 3, 0x0984, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__NANDF_RE_B IOMUX_PAD(0x4e8, 0x10c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__PATA_DIOR IOMUX_PAD(0x4e8, 0x10c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__SD3_DATA1 IOMUX_PAD(0x4e8, 0x10c, 2, 0x0940, 0, 0)
+#define _MX51_PAD_NANDF_ALE__GPIO3_5 IOMUX_PAD(0x4ec, 0x110, 3, 0x0988, 0, 0)
+#define _MX51_PAD_NANDF_ALE__NANDF_ALE IOMUX_PAD(0x4ec, 0x110, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_ALE__PATA_BUFFER_EN IOMUX_PAD(0x4ec, 0x110, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CLE__GPIO3_6 IOMUX_PAD(0x4f0, 0x114, 3, 0x098c, 0, 0)
+#define _MX51_PAD_NANDF_CLE__NANDF_CLE IOMUX_PAD(0x4f0, 0x114, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CLE__PATA_RESET_B IOMUX_PAD(0x4f0, 0x114, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__GPIO3_7 IOMUX_PAD(0x4f4, 0x118, 3, 0x0990, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__NANDF_WP_B IOMUX_PAD(0x4f4, 0x118, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__PATA_DMACK IOMUX_PAD(0x4f4, 0x118, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__SD3_DATA2 IOMUX_PAD(0x4f4, 0x118, 2, 0x0944, 0, 0)
+#define _MX51_PAD_NANDF_RB0__ECSPI2_SS1 IOMUX_PAD(0x4f8, 0x11c, 5, 0x0930, 0, 0)
+#define _MX51_PAD_NANDF_RB0__GPIO3_8 IOMUX_PAD(0x4f8, 0x11c, 3, 0x0994, 0, 0)
+#define _MX51_PAD_NANDF_RB0__NANDF_RB0 IOMUX_PAD(0x4f8, 0x11c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB0__PATA_DMARQ IOMUX_PAD(0x4f8, 0x11c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB0__SD3_DATA3 IOMUX_PAD(0x4f8, 0x11c, 2, 0x0948, 0, 0)
+#define _MX51_PAD_NANDF_RB1__CSPI_MOSI IOMUX_PAD(0x4fc, 0x120, 6, 0x091c, 0, 0)
+#define _MX51_PAD_NANDF_RB1__ECSPI2_RDY IOMUX_PAD(0x4fc, 0x120, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__GPIO3_9 IOMUX_PAD(0x4fc, 0x120, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__NANDF_RB1 IOMUX_PAD(0x4fc, 0x120, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__PATA_IORDY IOMUX_PAD(0x4fc, 0x120, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__DISP2_WAIT IOMUX_PAD(0x500, 0x124, 5, 0x09a8, 0, 0)
+#define _MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x094c, 0, 0)
+#define _MX51_PAD_NANDF_RB2__GPIO3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__USBH3_NXT IOMUX_PAD(0x500, 0x124, 6, 0x0a20, 0, 0)
+#define _MX51_PAD_NANDF_RB3__DISP1_WAIT IOMUX_PAD(0x504, 0x128, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__FEC_RX_CLK IOMUX_PAD(0x504, 0x128, 1, 0x0968, 0, 0)
+#define _MX51_PAD_NANDF_RB3__GPIO3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__USBH3_CLK IOMUX_PAD(0x504, 0x128, 6, 0x09f8, 0, 0)
+#define _MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 7, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO_NAND__GPIO_NAND IOMUX_PAD(0x514, 0x12c, 0, 0x0998, 0, 0)
+#define _MX51_PAD_GPIO_NAND__PATA_INTRQ IOMUX_PAD(0x514, 0x12c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS0__GPIO3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS0__NANDF_CS0 IOMUX_PAD(0x518, 0x130, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS1__GPIO3_17 IOMUX_PAD(0x51c, 0x134, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS1__NANDF_CS1 IOMUX_PAD(0x51c, 0x134, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__CSPI_SCLK IOMUX_PAD(0x520, 0x138, 6, 0x0914, 0, 0)
+#define _MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__GPIO3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__PATA_CS_0 IOMUX_PAD(0x520, 0x138, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__SD4_CLK IOMUX_PAD(0x520, 0x138, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__GPIO3_19 IOMUX_PAD(0x524, 0x13c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__NANDF_CS3 IOMUX_PAD(0x524, 0x13c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__PATA_CS_1 IOMUX_PAD(0x524, 0x13c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__SD4_DAT0 IOMUX_PAD(0x524, 0x13c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__FEC_TDATA1 IOMUX_PAD(0x528, 0x140, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__GPIO3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__PATA_DA_0 IOMUX_PAD(0x528, 0x140, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__SD4_DAT1 IOMUX_PAD(0x528, 0x140, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__USBH3_STP IOMUX_PAD(0x528, 0x140, 7, 0x0a24, 0, 0)
+#define _MX51_PAD_NANDF_CS5__FEC_TDATA2 IOMUX_PAD(0x52c, 0x144, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__GPIO3_21 IOMUX_PAD(0x52c, 0x144, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__NANDF_CS5 IOMUX_PAD(0x52c, 0x144, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__PATA_DA_1 IOMUX_PAD(0x52c, 0x144, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__SD4_DAT2 IOMUX_PAD(0x52c, 0x144, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__USBH3_DIR IOMUX_PAD(0x52c, 0x144, 7, 0x0a1c, 0, 0)
+#define _MX51_PAD_NANDF_CS6__CSPI_SS3 IOMUX_PAD(0x530, 0x148, 7, 0x0928, 0, 0)
+#define _MX51_PAD_NANDF_CS6__FEC_TDATA3 IOMUX_PAD(0x530, 0x148, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__GPIO3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__NANDF_CS6 IOMUX_PAD(0x530, 0x148, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__PATA_DA_2 IOMUX_PAD(0x530, 0x148, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__SD4_DAT3 IOMUX_PAD(0x530, 0x148, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__GPIO3_23 IOMUX_PAD(0x534, 0x14c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__NANDF_CS7 IOMUX_PAD(0x534, 0x14c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__SD3_CLK IOMUX_PAD(0x534, 0x14c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 IOMUX_PAD(0x538, 0x150, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0974, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__GPIO3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 0, 0x0938, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53c, 0x154, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__GPIO3_25 IOMUX_PAD(0x53c, 0x154, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__NANDF_D15 IOMUX_PAD(0x53c, 0x154, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__PATA_DATA15 IOMUX_PAD(0x53c, 0x154, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__SD3_DAT7 IOMUX_PAD(0x53c, 0x154, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__ECSPI2_SS3 IOMUX_PAD(0x540, 0x158, 2, 0x0934, 0, 0)
+#define _MX51_PAD_NANDF_D14__GPIO3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__NANDF_D14 IOMUX_PAD(0x540, 0x158, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__PATA_DATA14 IOMUX_PAD(0x540, 0x158, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__SD3_DAT6 IOMUX_PAD(0x540, 0x158, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__ECSPI2_SS2 IOMUX_PAD(0x544, 0x15c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__GPIO3_27 IOMUX_PAD(0x544, 0x15c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__NANDF_D13 IOMUX_PAD(0x544, 0x15c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__PATA_DATA13 IOMUX_PAD(0x544, 0x15c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__SD3_DAT5 IOMUX_PAD(0x544, 0x15c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__ECSPI2_SS1 IOMUX_PAD(0x548, 0x160, 2, 0x0930, 1, 0)
+#define _MX51_PAD_NANDF_D12__GPIO3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__NANDF_D12 IOMUX_PAD(0x548, 0x160, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__PATA_DATA12 IOMUX_PAD(0x548, 0x160, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__SD3_DAT4 IOMUX_PAD(0x548, 0x160, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__FEC_RX_DV IOMUX_PAD(0x54c, 0x164, 2, 0x096c, 0, 0)
+#define _MX51_PAD_NANDF_D11__GPIO3_29 IOMUX_PAD(0x54c, 0x164, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__NANDF_D11 IOMUX_PAD(0x54c, 0x164, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__PATA_DATA11 IOMUX_PAD(0x54c, 0x164, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__SD3_DATA3 IOMUX_PAD(0x54c, 0x164, 5, 0x0948, 1, 0)
+#define _MX51_PAD_NANDF_D10__GPIO3_30 IOMUX_PAD(0x550, 0x168, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__NANDF_D10 IOMUX_PAD(0x550, 0x168, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__PATA_DATA10 IOMUX_PAD(0x550, 0x168, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__SD3_DATA2 IOMUX_PAD(0x550, 0x168, 5, 0x0944, 1, 0)
+#define _MX51_PAD_NANDF_D9__FEC_RDATA0 IOMUX_PAD(0x554, 0x16c, 0x12, 0x0958, 0, 0)
+#define _MX51_PAD_NANDF_D9__GPIO3_31 IOMUX_PAD(0x554, 0x16c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__NANDF_D9 IOMUX_PAD(0x554, 0x16c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__PATA_DATA9 IOMUX_PAD(0x554, 0x16c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__SD3_DATA1 IOMUX_PAD(0x554, 0x16c, 5, 0x0940, 1, 0)
+#define _MX51_PAD_NANDF_D8__FEC_TDATA0 IOMUX_PAD(0x558, 0x170, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__GPIO4_0 IOMUX_PAD(0x558, 0x170, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__NANDF_D8 IOMUX_PAD(0x558, 0x170, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__PATA_DATA8 IOMUX_PAD(0x558, 0x170, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__SD3_DATA0 IOMUX_PAD(0x558, 0x170, 5, 0x093c, 1, 0)
+#define _MX51_PAD_NANDF_D7__GPIO4_1 IOMUX_PAD(0x55c, 0x174, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__NANDF_D7 IOMUX_PAD(0x55c, 0x174, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__PATA_DATA7 IOMUX_PAD(0x55c, 0x174, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__USBH3_DATA0 IOMUX_PAD(0x55c, 0x174, 5, 0x09fc, 0, 0)
+#define _MX51_PAD_NANDF_D6__GPIO4_2 IOMUX_PAD(0x560, 0x178, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__NANDF_D6 IOMUX_PAD(0x560, 0x178, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__PATA_DATA6 IOMUX_PAD(0x560, 0x178, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__SD4_LCTL IOMUX_PAD(0x560, 0x178, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__USBH3_DATA1 IOMUX_PAD(0x560, 0x178, 5, 0x0a00, 0, 0)
+#define _MX51_PAD_NANDF_D5__GPIO4_3 IOMUX_PAD(0x564, 0x17c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__NANDF_D5 IOMUX_PAD(0x564, 0x17c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__PATA_DATA5 IOMUX_PAD(0x564, 0x17c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__SD4_WP IOMUX_PAD(0x564, 0x17c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__USBH3_DATA2 IOMUX_PAD(0x564, 0x17c, 5, 0x0a04, 0, 0)
+#define _MX51_PAD_NANDF_D4__GPIO4_4 IOMUX_PAD(0x568, 0x180, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__NANDF_D4 IOMUX_PAD(0x568, 0x180, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__PATA_DATA4 IOMUX_PAD(0x568, 0x180, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__SD4_CD IOMUX_PAD(0x568, 0x180, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__USBH3_DATA3 IOMUX_PAD(0x568, 0x180, 5, 0x0a08, 0, 0)
+#define _MX51_PAD_NANDF_D3__GPIO4_5 IOMUX_PAD(0x56c, 0x184, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__NANDF_D3 IOMUX_PAD(0x56c, 0x184, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__PATA_DATA3 IOMUX_PAD(0x56c, 0x184, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__SD4_DAT4 IOMUX_PAD(0x56c, 0x184, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__USBH3_DATA4 IOMUX_PAD(0x56c, 0x184, 5, 0x0a0c, 0, 0)
+#define _MX51_PAD_NANDF_D2__GPIO4_6 IOMUX_PAD(0x570, 0x188, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__NANDF_D2 IOMUX_PAD(0x570, 0x188, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__PATA_DATA2 IOMUX_PAD(0x570, 0x188, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__SD4_DAT5 IOMUX_PAD(0x570, 0x188, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__USBH3_DATA5 IOMUX_PAD(0x570, 0x188, 5, 0x0a10, 0, 0)
+#define _MX51_PAD_NANDF_D1__GPIO4_7 IOMUX_PAD(0x574, 0x18c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__NANDF_D1 IOMUX_PAD(0x574, 0x18c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__PATA_DATA1 IOMUX_PAD(0x574, 0x18c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__SD4_DAT6 IOMUX_PAD(0x574, 0x18c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__USBH3_DATA6 IOMUX_PAD(0x574, 0x18c, 5, 0x0a14, 0, 0)
+#define _MX51_PAD_NANDF_D0__GPIO4_8 IOMUX_PAD(0x578, 0x190, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__NANDF_D0 IOMUX_PAD(0x578, 0x190, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__PATA_DATA0 IOMUX_PAD(0x578, 0x190, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__SD4_DAT7 IOMUX_PAD(0x578, 0x190, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__USBH3_DATA7 IOMUX_PAD(0x578, 0x190, 5, 0x0a18, 0, 0)
+#define _MX51_PAD_CSI1_D8__CSI1_D8 IOMUX_PAD(0x57c, 0x194, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D8__GPIO3_12 IOMUX_PAD(0x57c, 0x194, 3, 0x0998, 1, 0)
+#define _MX51_PAD_CSI1_D9__CSI1_D9 IOMUX_PAD(0x580, 0x198, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D9__GPIO3_13 IOMUX_PAD(0x580, 0x198, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1a0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58c, 0x1a4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1a8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59c, 0x1b4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5a0, 0x1b8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5a4, 0x1bc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5a8, 0x1c0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5ac, 0x1c4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_VSYNC__GPIO3_14 IOMUX_PAD(0x5ac, 0x1c4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5b0, 0x1c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_HSYNC__GPIO3_15 IOMUX_PAD(0x5b0, 0x1c8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5b4, 0x000, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5b8, 0x000, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D12__CSI2_D12 IOMUX_PAD(0x5bc, 0x1cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D12__GPIO4_9 IOMUX_PAD(0x5bc, 0x1cc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D13__CSI2_D13 IOMUX_PAD(0x5c0, 0x1d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D13__GPIO4_10 IOMUX_PAD(0x5c0, 0x1d0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D14__CSI2_D14 IOMUX_PAD(0x5c4, 0x1d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D15__CSI2_D15 IOMUX_PAD(0x5c8, 0x1d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D16__CSI2_D16 IOMUX_PAD(0x5cc, 0x1dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D17__CSI2_D17 IOMUX_PAD(0x5d0, 0x1e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D18__CSI2_D18 IOMUX_PAD(0x5d4, 0x1e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D18__GPIO4_11 IOMUX_PAD(0x5d4, 0x1e4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D19__CSI2_D19 IOMUX_PAD(0x5d8, 0x1e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D19__GPIO4_12 IOMUX_PAD(0x5d8, 0x1e8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_VSYNC__CSI2_VSYNC IOMUX_PAD(0x5dc, 0x1ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_VSYNC__GPIO4_13 IOMUX_PAD(0x5dc, 0x1ec, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_HSYNC__CSI2_HSYNC IOMUX_PAD(0x5e0, 0x1f0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_HSYNC__GPIO4_14 IOMUX_PAD(0x5e0, 0x1f0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK IOMUX_PAD(0x5e4, 0x1f4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_PIXCLK__GPIO4_15 IOMUX_PAD(0x5e4, 0x1f4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_CLK__GPIO4_16 IOMUX_PAD(0x5e8, 0x1f8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x5e8, 0x1f8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_DAT__GPIO4_17 IOMUX_PAD(0x5ec, 0x1fc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x5ec, 0x1fc, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_TXD__AUD3_TXD IOMUX_PAD(0x5f0, 0x200, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_TXD__GPIO4_18 IOMUX_PAD(0x5f0, 0x200, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__AUD3_RXD IOMUX_PAD(0x5f4, 0x204, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__GPIO4_19 IOMUX_PAD(0x5f4, 0x204, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__UART3_RXD IOMUX_PAD(0x5f4, 0x204, 1, 0x09f4, 2, 0)
+#define _MX51_PAD_AUD3_BB_CK__AUD3_TXC IOMUX_PAD(0x5f8, 0x208, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_CK__GPIO4_20 IOMUX_PAD(0x5f8, 0x208, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__AUD3_TXFS IOMUX_PAD(0x5fc, 0x20c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__GPIO4_21 IOMUX_PAD(0x5fc, 0x20c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__UART3_TXD IOMUX_PAD(0x5fc, 0x20c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__GPIO4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__I2C1_SDA IOMUX_PAD(0x600, 0x210, 0x11, 0x09b4, 1, 0)
+#define _MX51_PAD_CSPI1_MISO__AUD4_RXD IOMUX_PAD(0x604, 0x214, 1, 0x08c4, 1, 0)
+#define _MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MISO__GPIO4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS0__AUD4_TXC IOMUX_PAD(0x608, 0x218, 1, 0x08cc, 1, 0)
+#define _MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS0__GPIO4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS1__AUD4_TXD IOMUX_PAD(0x60c, 0x21c, 1, 0x08c8, 1, 0)
+#define _MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60c, 0x21c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS1__GPIO4_25 IOMUX_PAD(0x60c, 0x21c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_RDY__AUD4_TXFS IOMUX_PAD(0x610, 0x220, 1, 0x08d0, 1, 0)
+#define _MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_RDY__GPIO4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__GPIO4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__I2C1_SCL IOMUX_PAD(0x614, 0x224, 0x11, 0x09b0, 1, 0)
+#define _MX51_PAD_UART1_RXD__GPIO4_28 IOMUX_PAD(0x618, 0x228, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x09e4, 0, 0)
+#define _MX51_PAD_UART1_TXD__GPIO4_29 IOMUX_PAD(0x61c, 0x22c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_TXD__PWM2_PWMO IOMUX_PAD(0x61c, 0x22c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61c, 0x22c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RTS__GPIO4_30 IOMUX_PAD(0x620, 0x230, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, 0, 0x09e0, 0, 0)
+#define _MX51_PAD_UART1_CTS__GPIO4_31 IOMUX_PAD(0x624, 0x234, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__FIRI_TXD IOMUX_PAD(0x628, 0x238, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__GPIO1_20 IOMUX_PAD(0x628, 0x238, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, 0, 0x09ec, 2, 0)
+#define _MX51_PAD_UART2_TXD__FIRI_RXD IOMUX_PAD(0x62c, 0x23c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_TXD__GPIO1_21 IOMUX_PAD(0x62c, 0x23c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62c, 0x23c, 0, 0x09ec, 3, 0)
+#define _MX51_PAD_UART3_RXD__CSI1_D0 IOMUX_PAD(0x630, 0x240, 2, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__GPIO1_22 IOMUX_PAD(0x630, 0x240, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__UART1_DTR IOMUX_PAD(0x630, 0x240, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x630, 0x240, 1, 0x09f4, 4, 0)
+#define _MX51_PAD_UART3_TXD__CSI1_D1 IOMUX_PAD(0x634, 0x244, 2, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__GPIO1_23 IOMUX_PAD(0x634, 0x244, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__UART1_DSR IOMUX_PAD(0x634, 0x244, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x634, 0x244, 1, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__GPIO1_24 IOMUX_PAD(0x638, 0x248, 3, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__OWIRE_LINE IOMUX_PAD(0x638, 0x248, 0, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__SPDIF_OUT IOMUX_PAD(0x638, 0x248, 6, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63c, 0x24c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64c, 0x25c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL0__PLL1_BYP IOMUX_PAD(0x64c, 0x25c, 7, 0x090c, 0, 0)
+#define _MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL1__PLL2_BYP IOMUX_PAD(0x650, 0x260, 7, 0x0910, 0, 0)
+#define _MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL2__PLL3_BYP IOMUX_PAD(0x654, 0x264, 7, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__I2C2_SCL IOMUX_PAD(0x65c, 0x26c, 0x13, 0x09b8, 1, 0)
+#define _MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65c, 0x26c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__SPDIF_OUT1 IOMUX_PAD(0x65c, 0x26c, 6, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__UART1_RI IOMUX_PAD(0x65c, 0x26c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__UART3_RTS IOMUX_PAD(0x65c, 0x26c, 2, 0x09f0, 4, 0)
+#define _MX51_PAD_KEY_COL5__I2C2_SDA IOMUX_PAD(0x660, 0x270, 0x13, 0x09bc, 1, 0)
+#define _MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL5__UART1_DCD IOMUX_PAD(0x660, 0x270, 1, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL5__UART3_CTS IOMUX_PAD(0x660, 0x270, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_CLK__CSPI_SCLK IOMUX_PAD(0x678, 0x278, 1, 0x0914, 1, 0)
+#define _MX51_PAD_USBH1_CLK__GPIO1_25 IOMUX_PAD(0x678, 0x278, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_CLK__I2C2_SCL IOMUX_PAD(0x678, 0x278, 0x15, 0x09b8, 2, 0)
+#define _MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DIR__CSPI_MOSI IOMUX_PAD(0x67c, 0x27c, 1, 0x091c, 1, 0)
+#define _MX51_PAD_USBH1_DIR__GPIO1_26 IOMUX_PAD(0x67c, 0x27c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DIR__I2C2_SDA IOMUX_PAD(0x67c, 0x27c, 0x15, 0x09bc, 2, 0)
+#define _MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67c, 0x27c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__CSPI_RDY IOMUX_PAD(0x680, 0x280, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__GPIO1_27 IOMUX_PAD(0x680, 0x280, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__UART3_RXD IOMUX_PAD(0x680, 0x280, 5, 0x09f4, 6, 0)
+#define _MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__CSPI_MISO IOMUX_PAD(0x684, 0x284, 1, 0x0918, 0, 0)
+#define _MX51_PAD_USBH1_NXT__GPIO1_28 IOMUX_PAD(0x684, 0x284, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__UART3_TXD IOMUX_PAD(0x684, 0x284, 5, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__GPIO1_11 IOMUX_PAD(0x688, 0x288, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__UART2_CTS IOMUX_PAD(0x688, 0x288, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA1__GPIO1_12 IOMUX_PAD(0x68c, 0x28c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA1__UART2_RXD IOMUX_PAD(0x68c, 0x28c, 1, 0x09ec, 4, 0)
+#define _MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68c, 0x28c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA2__GPIO1_13 IOMUX_PAD(0x690, 0x290, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA2__UART2_TXD IOMUX_PAD(0x690, 0x290, 1, 0x09ec, 5, 0)
+#define _MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA3__GPIO1_14 IOMUX_PAD(0x694, 0x294, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA3__UART2_RTS IOMUX_PAD(0x694, 0x294, 1, 0x09e8, 5, 0)
+#define _MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__CSPI_SS0 IOMUX_PAD(0x698, 0x298, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__GPIO1_15 IOMUX_PAD(0x698, 0x298, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__CSPI_SS1 IOMUX_PAD(0x69c, 0x29c, 1, 0x0920, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__GPIO1_16 IOMUX_PAD(0x69c, 0x29c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69c, 0x29c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA6__CSPI_SS3 IOMUX_PAD(0x6a0, 0x2a0, 1, 0x0928, 1, 0)
+#define _MX51_PAD_USBH1_DATA6__GPIO1_17 IOMUX_PAD(0x6a0, 0x2a0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6a0, 0x2a0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__ECSPI1_SS3 IOMUX_PAD(0x6a4, 0x2a4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__ECSPI2_SS3 IOMUX_PAD(0x6a4, 0x2a4, 5, 0x0934, 1, 0)
+#define _MX51_PAD_USBH1_DATA7__GPIO1_18 IOMUX_PAD(0x6a4, 0x2a4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6a4, 0x2a4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__DI1_PIN11 IOMUX_PAD(0x6a8, 0x2a8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__ECSPI1_SS2 IOMUX_PAD(0x6a8, 0x2a8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__GPIO3_0 IOMUX_PAD(0x6a8, 0x2a8, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN12__DI1_PIN12 IOMUX_PAD(0x6ac, 0x2ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN12__GPIO3_1 IOMUX_PAD(0x6ac, 0x2ac, 4, 0x0978, 1, 0)
+#define _MX51_PAD_DI1_PIN13__DI1_PIN13 IOMUX_PAD(0x6b0, 0x2b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN13__GPIO3_2 IOMUX_PAD(0x6b0, 0x2b0, 4, 0x097c, 1, 0)
+#define _MX51_PAD_DI1_D0_CS__DI1_D0_CS IOMUX_PAD(0x6b4, 0x2b4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D0_CS__GPIO3_3 IOMUX_PAD(0x6b4, 0x2b4, 4, 0x0980, 1, 0)
+#define _MX51_PAD_DI1_D1_CS__DI1_D1_CS IOMUX_PAD(0x6b8, 0x2b8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__DISP1_PIN14 IOMUX_PAD(0x6b8, 0x2b8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__DISP1_PIN5 IOMUX_PAD(0x6b8, 0x2b8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__GPIO3_4 IOMUX_PAD(0x6b8, 0x2b8, 4, 0x0984, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 IOMUX_PAD(0x6bc, 0x2bc, 2, 0x09a4, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN IOMUX_PAD(0x6bc, 0x2bc, 0, 0x09c4, 0, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__GPIO3_5 IOMUX_PAD(0x6bc, 0x2bc, 4, 0x0988, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 IOMUX_PAD(0x6c0, 0x2c0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO IOMUX_PAD(0x6c0, 0x2c0, 0, 0x09c4, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__GPIO3_6 IOMUX_PAD(0x6c0, 0x2c0, 4, 0x098c, 1, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 IOMUX_PAD(0x6c4, 0x2c4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 IOMUX_PAD(0x6c4, 0x2c4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK IOMUX_PAD(0x6c4, 0x2c4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__GPIO3_7 IOMUX_PAD(0x6c4, 0x2c4, 4, 0x0990, 1, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK IOMUX_PAD(0x6c8, 0x2c8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 IOMUX_PAD(0x6c8, 0x2c8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 IOMUX_PAD(0x6c8, 0x2c8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS IOMUX_PAD(0x6c8, 0x2c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS IOMUX_PAD(0x6c8, 0x2c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__GPIO3_8 IOMUX_PAD(0x6c8, 0x2c8, 4, 0x0994, 1, 0)
+#define _MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6cc, 0x2cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6d0, 0x2d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6d4, 0x2d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6d8, 0x2d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6dc, 0x2dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6e0, 0x2e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT6__BOOT_USB_SRC IOMUX_PAD(0x6e4, 0x2e4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6e4, 0x2e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG IOMUX_PAD(0x6e8, 0x2e8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6e8, 0x2e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT8__BOOT_SRC0 IOMUX_PAD(0x6ec, 0x2ec, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6ec, 0x2ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT9__BOOT_SRC1 IOMUX_PAD(0x6f0, 0x2f0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6f0, 0x2f0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE IOMUX_PAD(0x6f4, 0x2f4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6f4, 0x2f4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 IOMUX_PAD(0x6f8, 0x2f8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6f8, 0x2f8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL IOMUX_PAD(0x6fc, 0x2fc, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6fc, 0x2fc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 IOMUX_PAD(0x700, 0x300, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 IOMUX_PAD(0x704, 0x304, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH IOMUX_PAD(0x708, 0x308, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 IOMUX_PAD(0x70c, 0x30c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70c, 0x30c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 IOMUX_PAD(0x710, 0x310, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 IOMUX_PAD(0x714, 0x314, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP2_PIN11 IOMUX_PAD(0x714, 0x314, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP2_PIN5 IOMUX_PAD(0x714, 0x314, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 IOMUX_PAD(0x718, 0x318, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP2_PIN12 IOMUX_PAD(0x718, 0x318, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP2_PIN6 IOMUX_PAD(0x718, 0x318, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 IOMUX_PAD(0x71c, 0x31c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71c, 0x31c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP2_PIN13 IOMUX_PAD(0x71c, 0x31c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP2_PIN7 IOMUX_PAD(0x71c, 0x31c, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 IOMUX_PAD(0x720, 0x320, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP2_PIN14 IOMUX_PAD(0x720, 0x320, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP2_PIN8 IOMUX_PAD(0x720, 0x320, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 IOMUX_PAD(0x724, 0x324, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP2_D0_CS IOMUX_PAD(0x724, 0x324, 6, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP2_DAT16 IOMUX_PAD(0x724, 0x324, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 IOMUX_PAD(0x728, 0x328, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_D1_CS IOMUX_PAD(0x728, 0x328, 6, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_DAT17 IOMUX_PAD(0x728, 0x328, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_SER_CS IOMUX_PAD(0x728, 0x328, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72c, 0x32c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP2__DISP1_SER_CLK IOMUX_PAD(0x740, 0x338, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP2__DISP2_WAIT IOMUX_PAD(0x740, 0x338, 2, 0x09a8, 1, 0)
+#define _MX51_PAD_DI_GP3__CSI1_DATA_EN IOMUX_PAD(0x744, 0x33c, 3, 0x09a0, 1, 0)
+#define _MX51_PAD_DI_GP3__DISP1_SER_DIO IOMUX_PAD(0x744, 0x33c, 0, 0x09c0, 0, 0)
+#define _MX51_PAD_DI_GP3__FEC_TX_ER IOMUX_PAD(0x744, 0x33c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN4__CSI2_DATA_EN IOMUX_PAD(0x748, 0x340, 3, 0x099c, 1, 0)
+#define _MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN4__FEC_CRS IOMUX_PAD(0x748, 0x340, 2, 0x0950, 1, 0)
+#define _MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74c, 0x344, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN2__FEC_MDC IOMUX_PAD(0x74c, 0x344, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN3__FEC_MDIO IOMUX_PAD(0x750, 0x348, 2, 0x0954, 1, 0)
+#define _MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 IOMUX_PAD(0x754, 0x34c, 2, 0x095c, 1, 0)
+#define _MX51_PAD_DI_GP4__DI2_PIN15 IOMUX_PAD(0x758, 0x350, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP4__DISP1_SER_DIN IOMUX_PAD(0x758, 0x350, 0, 0x09c0, 1, 0)
+#define _MX51_PAD_DI_GP4__DISP2_PIN1 IOMUX_PAD(0x758, 0x350, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP4__FEC_RDATA2 IOMUX_PAD(0x758, 0x350, 2, 0x0960, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75c, 0x354, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT0__FEC_RDATA3 IOMUX_PAD(0x75c, 0x354, 2, 0x0964, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__KEY_COL6 IOMUX_PAD(0x75c, 0x354, 4, 0x09c8, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__UART3_RXD IOMUX_PAD(0x75c, 0x354, 5, 0x09f4, 8, 0)
+#define _MX51_PAD_DISP2_DAT0__USBH3_CLK IOMUX_PAD(0x75c, 0x354, 3, 0x09f8, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT1__FEC_RX_ER IOMUX_PAD(0x760, 0x358, 2, 0x0970, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__KEY_COL7 IOMUX_PAD(0x760, 0x358, 4, 0x09cc, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__UART3_TXD IOMUX_PAD(0x760, 0x358, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT1__USBH3_DIR IOMUX_PAD(0x760, 0x358, 3, 0x0a1c, 1, 0)
+#define _MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76c, 0x364, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__DISP2_DAT6 IOMUX_PAD(0x774, 0x36c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__FEC_TDATA1 IOMUX_PAD(0x774, 0x36c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__KEY_ROW4 IOMUX_PAD(0x774, 0x36c, 4, 0x09d0, 1, 0)
+#define _MX51_PAD_DISP2_DAT6__USBH3_STP IOMUX_PAD(0x774, 0x36c, 3, 0x0a24, 1, 0)
+#define _MX51_PAD_DISP2_DAT7__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__FEC_TDATA2 IOMUX_PAD(0x778, 0x370, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__KEY_ROW5 IOMUX_PAD(0x778, 0x370, 4, 0x09d4, 1, 0)
+#define _MX51_PAD_DISP2_DAT7__USBH3_NXT IOMUX_PAD(0x778, 0x370, 3, 0x0a20, 1, 0)
+#define _MX51_PAD_DISP2_DAT8__DISP2_DAT8 IOMUX_PAD(0x77c, 0x374, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__FEC_TDATA3 IOMUX_PAD(0x77c, 0x374, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__KEY_ROW6 IOMUX_PAD(0x77c, 0x374, 4, 0x09d8, 1, 0)
+#define _MX51_PAD_DISP2_DAT8__USBH3_DATA0 IOMUX_PAD(0x77c, 0x374, 3, 0x09fc, 1, 0)
+#define _MX51_PAD_DISP2_DAT9__AUD6_RXC IOMUX_PAD(0x780, 0x378, 4, 0x08f4, 1, 0)
+#define _MX51_PAD_DISP2_DAT9__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__FEC_TX_EN IOMUX_PAD(0x780, 0x378, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__USBH3_DATA1 IOMUX_PAD(0x780, 0x378, 3, 0x0a00, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT10__DISP2_SER_CS IOMUX_PAD(0x784, 0x37c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT10__FEC_COL IOMUX_PAD(0x784, 0x37c, 2, 0x094c, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__KEY_ROW7 IOMUX_PAD(0x784, 0x37c, 4, 0x09dc, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__USBH3_DATA2 IOMUX_PAD(0x784, 0x37c, 3, 0x0a04, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__AUD6_TXD IOMUX_PAD(0x788, 0x380, 4, 0x08f0, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x0968, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT11__USBH3_DATA3 IOMUX_PAD(0x788, 0x380, 3, 0x0a08, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__AUD6_RXD IOMUX_PAD(0x78c, 0x384, 4, 0x08ec, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78c, 0x384, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT12__FEC_RX_DV IOMUX_PAD(0x78c, 0x384, 2, 0x096c, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__USBH3_DATA4 IOMUX_PAD(0x78c, 0x384, 3, 0x0a0c, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__AUD6_TXC IOMUX_PAD(0x790, 0x388, 4, 0x08fc, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT13__FEC_TX_CLK IOMUX_PAD(0x790, 0x388, 2, 0x0974, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__USBH3_DATA5 IOMUX_PAD(0x790, 0x388, 3, 0x0a10, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__AUD6_TXFS IOMUX_PAD(0x794, 0x38c, 4, 0x0900, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT14__FEC_RDATA0 IOMUX_PAD(0x794, 0x38c, 2, 0x0958, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__USBH3_DATA6 IOMUX_PAD(0x794, 0x38c, 3, 0x0a14, 1, 0)
+#define _MX51_PAD_DISP2_DAT15__AUD6_RXFS IOMUX_PAD(0x798, 0x390, 4, 0x08f8, 1, 0)
+#define _MX51_PAD_DISP2_DAT15__DISP1_SER_CS IOMUX_PAD(0x798, 0x390, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__FEC_TDATA0 IOMUX_PAD(0x798, 0x390, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__USBH3_DATA7 IOMUX_PAD(0x798, 0x390, 3, 0x0a18, 1, 0)
+#define _MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79c, 0x394, 1, 0x08e0, 1, 0)
+#define _MX51_PAD_SD1_CMD__CSPI_MOSI IOMUX_PAD(0x79c, 0x394, 2, 0x091c, 2, 0)
+#define _MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79c, 0x394, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7a0, 0x398, 1, 0x08dc, 1, 0)
+#define _MX51_PAD_SD1_CLK__CSPI_SCLK IOMUX_PAD(0x7a0, 0x398, 2, 0x0914, 2, 0)
+#define _MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7a0, 0x398, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7a4, 0x39c, 1, 0x08d8, 2, 0)
+#define _MX51_PAD_SD1_DATA0__CSPI_MISO IOMUX_PAD(0x7a4, 0x39c, 2, 0x0918, 1, 0)
+#define _MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7a4, 0x39c, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x000, 0x01c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x000, 0x020, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x000, 0x024, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x000, 0x028, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7a8, 0x3a0, 1, 0x08d4, 2, 0)
+#define _MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7a8, 0x3a0, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x000, 0x02c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x000, 0x030, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x000, 0x034, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x000, 0x038, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7ac, 0x3a4, 1, 0x08e4, 2, 0)
+#define _MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7ac, 0x3a4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x000, 0x044, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x000, 0x048, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x000, 0x03c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x000, 0x040, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7b0, 0x3a8, 1, 0x08e8, 2, 0)
+#define _MX51_PAD_SD1_DATA3__CSPI_SS1 IOMUX_PAD(0x7b0, 0x3a8, 2, 0x0920, 1, 0)
+#define _MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7b0, 0x3a8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_0__CSPI_SS2 IOMUX_PAD(0x7b4, 0x3ac, 2, 0x0924, 0, 0)
+#define _MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_0__SD1_CD IOMUX_PAD(0x7b4, 0x3ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_1__CSPI_MISO IOMUX_PAD(0x7b8, 0x3b0, 2, 0x0918, 2, 0)
+#define _MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_1__SD1_WP IOMUX_PAD(0x7b8, 0x3b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x000, 0x04c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x000, 0x050, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x000, 0x054, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x000, 0x058, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(0x000, 0x3b4, 2, 0x091c, 3, 0)
+#define _MX51_PAD_SD2_CMD__I2C1_SCL IOMUX_PAD(0x7bc, 0x3b4, 0x11, 0x09b0, 2, 0)
+#define _MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7bc, 0x3b4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_CLK__CSPI_SCLK IOMUX_PAD(0x7c0, 0x3b8, 2, 0x0914, 3, 0)
+#define _MX51_PAD_SD2_CLK__I2C1_SDA IOMUX_PAD(0x7c0, 0x3b8, 0x11, 0x09b4, 2, 0)
+#define _MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7c0, 0x3b8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA0__CSPI_MISO IOMUX_PAD(0x7c4, 0x3bc, 2, 0x0918, 3, 0)
+#define _MX51_PAD_SD2_DATA0__SD1_DAT4 IOMUX_PAD(0x7c4, 0x3bc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7c4, 0x3bc, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__SD1_DAT5 IOMUX_PAD(0x7c8, 0x3c0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7c8, 0x3c0, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__SD1_DAT6 IOMUX_PAD(0x7cc, 0x3c4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7cc, 0x3c4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA3__CSPI_SS2 IOMUX_PAD(0x7d0, 0x3c8, 2, 0x0924, 1, 0)
+#define _MX51_PAD_SD2_DATA3__SD1_DAT7 IOMUX_PAD(0x7d0, 0x3c8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7d0, 0x3c8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__CCM_OUT_2 IOMUX_PAD(0x7d4, 0x3cc, 5, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__I2C2_SCL IOMUX_PAD(0x7d4, 0x3cc, 0x12, 0x09b8, 3, 0)
+#define _MX51_PAD_GPIO1_2__PLL1_BYP IOMUX_PAD(0x7d4, 0x3cc, 7, 0x090c, 1, 0)
+#define _MX51_PAD_GPIO1_2__PWM1_PWMO IOMUX_PAD(0x7d4, 0x3cc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_3__I2C2_SDA IOMUX_PAD(0x7d8, 0x3d0, 0x12, 0x09bc, 3, 0)
+#define _MX51_PAD_GPIO1_3__PLL2_BYP IOMUX_PAD(0x7d8, 0x3d0, 7, 0x0910, 1, 0)
+#define _MX51_PAD_GPIO1_3__PWM2_PWMO IOMUX_PAD(0x7d8, 0x3d0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7fc, 0x3d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B IOMUX_PAD(0x7fc, 0x3d4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_4__DISP2_EXT_CLK IOMUX_PAD(0x804, 0x3d8, 4, 0x0908, 1, 0)
+#define _MX51_PAD_GPIO1_4__EIM_RDY IOMUX_PAD(0x804, 0x3d8, 3, 0x0938, 1, 0)
+#define _MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_4__WDOG1_WDOG_B IOMUX_PAD(0x804, 0x3d8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__CSI2_MCLK IOMUX_PAD(0x808, 0x3dc, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__DISP2_PIN16 IOMUX_PAD(0x808, 0x3dc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__WDOG2_WDOG_B IOMUX_PAD(0x808, 0x3dc, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__DISP2_PIN17 IOMUX_PAD(0x80c, 0x3e0, 4, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__REF_EN_B IOMUX_PAD(0x80c, 0x3e0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__CCM_OUT_0 IOMUX_PAD(0x810, 0x3e4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__SD2_WP IOMUX_PAD(0x810, 0x3e4, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__SPDIF_OUT1 IOMUX_PAD(0x810, 0x3e4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__CSI2_DATA_EN IOMUX_PAD(0x814, 0x3e8, 2, 0x099c, 2, 0)
+#define _MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__SD2_CD IOMUX_PAD(0x814, 0x3e8, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__USBH3_PWR IOMUX_PAD(0x814, 0x3e8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__CCM_OUT_1 IOMUX_PAD(0x818, 0x3ec, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__DISP2_D1_CS IOMUX_PAD(0x818, 0x3ec, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__DISP2_SER_CS IOMUX_PAD(0x818, 0x3ec, 7, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__SD2_LCTL IOMUX_PAD(0x818, 0x3ec, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__USBH3_OC IOMUX_PAD(0x818, 0x3ec, 1, 0x0000, 0, 0)
+
+/* The same pins as above but with the default pad control values applied */
+#define MX51_PAD_EIM_D16__AUD4_RXFS (_MX51_PAD_EIM_D16__AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__AUD5_TXD (_MX51_PAD_EIM_D16__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__EIM_D16 (_MX51_PAD_EIM_D16__EIM_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__GPIO2_0 (_MX51_PAD_EIM_D16__GPIO2_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__I2C1_SDA (_MX51_PAD_EIM_D16__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D16__UART2_CTS (_MX51_PAD_EIM_D16__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D16__USBH2_DATA0 (_MX51_PAD_EIM_D16__USBH2_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__AUD5_RXD (_MX51_PAD_EIM_D17__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__EIM_D17 (_MX51_PAD_EIM_D17__EIM_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__GPIO2_1 (_MX51_PAD_EIM_D17__GPIO2_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__UART2_RXD (_MX51_PAD_EIM_D17__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D17__UART3_CTS (_MX51_PAD_EIM_D17__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D17__USBH2_DATA1 (_MX51_PAD_EIM_D17__USBH2_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__AUD5_TXC (_MX51_PAD_EIM_D18__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__EIM_D18 (_MX51_PAD_EIM_D18__EIM_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__GPIO2_2 (_MX51_PAD_EIM_D18__GPIO2_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__UART2_TXD (_MX51_PAD_EIM_D18__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D18__UART3_RTS (_MX51_PAD_EIM_D18__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D18__USBH2_DATA2 (_MX51_PAD_EIM_D18__USBH2_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__AUD4_RXC (_MX51_PAD_EIM_D19__AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__AUD5_TXFS (_MX51_PAD_EIM_D19__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__EIM_D19 (_MX51_PAD_EIM_D19__EIM_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__GPIO2_3 (_MX51_PAD_EIM_D19__GPIO2_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__I2C1_SCL (_MX51_PAD_EIM_D19__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D19__UART2_RTS (_MX51_PAD_EIM_D19__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D19__USBH2_DATA3 (_MX51_PAD_EIM_D19__USBH2_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__AUD4_TXD (_MX51_PAD_EIM_D20__AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__EIM_D20 (_MX51_PAD_EIM_D20__EIM_D20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__GPIO2_4 (_MX51_PAD_EIM_D20__GPIO2_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__SRTC_ALARM_DEB (_MX51_PAD_EIM_D20__SRTC_ALARM_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__USBH2_DATA4 (_MX51_PAD_EIM_D20__USBH2_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__AUD4_RXD (_MX51_PAD_EIM_D21__AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__EIM_D21 (_MX51_PAD_EIM_D21__EIM_D21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__GPIO2_5 (_MX51_PAD_EIM_D21__GPIO2_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__SRTC_ALARM_DEB (_MX51_PAD_EIM_D21__SRTC_ALARM_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__USBH2_DATA5 (_MX51_PAD_EIM_D21__USBH2_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__AUD4_TXC (_MX51_PAD_EIM_D22__AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__EIM_D22 (_MX51_PAD_EIM_D22__EIM_D22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__GPIO2_6 (_MX51_PAD_EIM_D22__GPIO2_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__USBH2_DATA6 (_MX51_PAD_EIM_D22__USBH2_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__AUD4_TXFS (_MX51_PAD_EIM_D23__AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__EIM_D23 (_MX51_PAD_EIM_D23__EIM_D23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__GPIO2_7 (_MX51_PAD_EIM_D23__GPIO2_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__SPDIF_OUT1 (_MX51_PAD_EIM_D23__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__USBH2_DATA7 (_MX51_PAD_EIM_D23__USBH2_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__AUD6_RXFS (_MX51_PAD_EIM_D24__AUD6_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__EIM_D24 (_MX51_PAD_EIM_D24__EIM_D24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__GPIO2_8 (_MX51_PAD_EIM_D24__GPIO2_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__I2C2_SDA (_MX51_PAD_EIM_D24__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D24__UART3_CTS (_MX51_PAD_EIM_D24__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D24__USBOTG_DATA0 (_MX51_PAD_EIM_D24__USBOTG_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__EIM_D25 (_MX51_PAD_EIM_D25__EIM_D25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__KEY_COL6 (_MX51_PAD_EIM_D25__KEY_COL6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__UART2_CTS (_MX51_PAD_EIM_D25__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D25__UART3_RXD (_MX51_PAD_EIM_D25__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D25__USBOTG_DATA1 (_MX51_PAD_EIM_D25__USBOTG_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__EIM_D26 (_MX51_PAD_EIM_D26__EIM_D26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__KEY_COL7 (_MX51_PAD_EIM_D26__KEY_COL7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__UART2_RTS (_MX51_PAD_EIM_D26__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D26__UART3_TXD (_MX51_PAD_EIM_D26__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D26__USBOTG_DATA2 (_MX51_PAD_EIM_D26__USBOTG_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__AUD6_RXC (_MX51_PAD_EIM_D27__AUD6_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__EIM_D27 (_MX51_PAD_EIM_D27__EIM_D27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__GPIO2_9 (_MX51_PAD_EIM_D27__GPIO2_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__I2C2_SCL (_MX51_PAD_EIM_D27__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D27__UART3_RTS (_MX51_PAD_EIM_D27__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D27__USBOTG_DATA3 (_MX51_PAD_EIM_D27__USBOTG_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__AUD6_TXD (_MX51_PAD_EIM_D28__AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__EIM_D28 (_MX51_PAD_EIM_D28__EIM_D28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__KEY_ROW4 (_MX51_PAD_EIM_D28__KEY_ROW4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__USBOTG_DATA4 (_MX51_PAD_EIM_D28__USBOTG_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__AUD6_RXD (_MX51_PAD_EIM_D29__AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__EIM_D29 (_MX51_PAD_EIM_D29__EIM_D29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__KEY_ROW5 (_MX51_PAD_EIM_D29__KEY_ROW5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__USBOTG_DATA5 (_MX51_PAD_EIM_D29__USBOTG_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__AUD6_TXC (_MX51_PAD_EIM_D30__AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__EIM_D30 (_MX51_PAD_EIM_D30__EIM_D30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__KEY_ROW6 (_MX51_PAD_EIM_D30__KEY_ROW6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__USBOTG_DATA6 (_MX51_PAD_EIM_D30__USBOTG_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__AUD6_TXFS (_MX51_PAD_EIM_D31__AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__EIM_D31 (_MX51_PAD_EIM_D31__EIM_D31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__KEY_ROW7 (_MX51_PAD_EIM_D31__KEY_ROW7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__USBOTG_DATA7 (_MX51_PAD_EIM_D31__USBOTG_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__EIM_A16 (_MX51_PAD_EIM_A16__EIM_A16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__GPIO2_10 (_MX51_PAD_EIM_A16__GPIO2_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__OSC_FREQ_SEL0 (_MX51_PAD_EIM_A16__OSC_FREQ_SEL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__EIM_A17 (_MX51_PAD_EIM_A17__EIM_A17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__GPIO2_11 (_MX51_PAD_EIM_A17__GPIO2_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__OSC_FREQ_SEL1 (_MX51_PAD_EIM_A17__OSC_FREQ_SEL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__BOOT_LPB0 (_MX51_PAD_EIM_A18__BOOT_LPB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__EIM_A18 (_MX51_PAD_EIM_A18__EIM_A18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__GPIO2_12 (_MX51_PAD_EIM_A18__GPIO2_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__BOOT_LPB1 (_MX51_PAD_EIM_A19__BOOT_LPB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__EIM_A19 (_MX51_PAD_EIM_A19__EIM_A19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__GPIO2_13 (_MX51_PAD_EIM_A19__GPIO2_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__BOOT_UART_SRC0 (_MX51_PAD_EIM_A20__BOOT_UART_SRC0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__EIM_A20 (_MX51_PAD_EIM_A20__EIM_A20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__GPIO2_14 (_MX51_PAD_EIM_A20__GPIO2_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__BOOT_UART_SRC1 (_MX51_PAD_EIM_A21__BOOT_UART_SRC1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__EIM_A21 (_MX51_PAD_EIM_A21__EIM_A21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__GPIO2_15 (_MX51_PAD_EIM_A21__GPIO2_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A22__EIM_A22 (_MX51_PAD_EIM_A22__EIM_A22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A22__GPIO2_16 (_MX51_PAD_EIM_A22__GPIO2_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__BOOT_HPN_EN (_MX51_PAD_EIM_A23__BOOT_HPN_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__EIM_A23 (_MX51_PAD_EIM_A23__EIM_A23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__GPIO2_17 (_MX51_PAD_EIM_A23__GPIO2_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__EIM_A24 (_MX51_PAD_EIM_A24__EIM_A24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__GPIO2_18 (_MX51_PAD_EIM_A24__GPIO2_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__USBH2_CLK (_MX51_PAD_EIM_A24__USBH2_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__DISP1_PIN4 (_MX51_PAD_EIM_A25__DISP1_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__EIM_A25 (_MX51_PAD_EIM_A25__EIM_A25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__GPIO2_19 (_MX51_PAD_EIM_A25__GPIO2_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__USBH2_DIR (_MX51_PAD_EIM_A25__USBH2_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__CSI1_DATA_EN (_MX51_PAD_EIM_A26__CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__DISP2_EXT_CLK (_MX51_PAD_EIM_A26__DISP2_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__EIM_A26 (_MX51_PAD_EIM_A26__EIM_A26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__GPIO2_20 (_MX51_PAD_EIM_A26__GPIO2_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__USBH2_STP (_MX51_PAD_EIM_A26__USBH2_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__CSI2_DATA_EN (_MX51_PAD_EIM_A27__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__DISP1_PIN1 (_MX51_PAD_EIM_A27__DISP1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__EIM_A27 (_MX51_PAD_EIM_A27__EIM_A27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__GPIO2_21 (_MX51_PAD_EIM_A27__GPIO2_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__USBH2_NXT (_MX51_PAD_EIM_A27__USBH2_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB0__EIM_EB0 (_MX51_PAD_EIM_EB0__EIM_EB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB1__EIM_EB1 (_MX51_PAD_EIM_EB1__EIM_EB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__AUD5_RXFS (_MX51_PAD_EIM_EB2__AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__CSI1_D2 (_MX51_PAD_EIM_EB2__CSI1_D2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__EIM_EB2 (_MX51_PAD_EIM_EB2__EIM_EB2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__FEC_MDIO (_MX51_PAD_EIM_EB2__FEC_MDIO | \
+ MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP | PAD_CTL_PKE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS))
+#define MX51_PAD_EIM_EB2__GPIO2_22 (_MX51_PAD_EIM_EB2__GPIO2_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__GPT_CMPOUT1 (_MX51_PAD_EIM_EB2__GPT_CMPOUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__AUD5_RXC (_MX51_PAD_EIM_EB3__AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__CSI1_D3 (_MX51_PAD_EIM_EB3__CSI1_D3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__EIM_EB3 (_MX51_PAD_EIM_EB3__EIM_EB3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__FEC_RDATA1 (_MX51_PAD_EIM_EB3__FEC_RDATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__GPIO2_23 (_MX51_PAD_EIM_EB3__GPIO2_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__GPT_CMPOUT2 (_MX51_PAD_EIM_EB3__GPT_CMPOUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_OE__EIM_OE (_MX51_PAD_EIM_OE__EIM_OE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_OE__GPIO2_24 (_MX51_PAD_EIM_OE__GPIO2_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS0__EIM_CS0 (_MX51_PAD_EIM_CS0__EIM_CS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS0__GPIO2_25 (_MX51_PAD_EIM_CS0__GPIO2_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS1__EIM_CS1 (_MX51_PAD_EIM_CS1__EIM_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS1__GPIO2_26 (_MX51_PAD_EIM_CS1__GPIO2_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__AUD5_TXD (_MX51_PAD_EIM_CS2__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__CSI1_D4 (_MX51_PAD_EIM_CS2__CSI1_D4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__EIM_CS2 (_MX51_PAD_EIM_CS2__EIM_CS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__FEC_RDATA2 (_MX51_PAD_EIM_CS2__FEC_RDATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__GPIO2_27 (_MX51_PAD_EIM_CS2__GPIO2_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__USBOTG_STP (_MX51_PAD_EIM_CS2__USBOTG_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__AUD5_RXD (_MX51_PAD_EIM_CS3__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__CSI1_D5 (_MX51_PAD_EIM_CS3__CSI1_D5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__EIM_CS3 (_MX51_PAD_EIM_CS3__EIM_CS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__FEC_RDATA3 (_MX51_PAD_EIM_CS3__FEC_RDATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__GPIO2_28 (_MX51_PAD_EIM_CS3__GPIO2_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__USBOTG_NXT (_MX51_PAD_EIM_CS3__USBOTG_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__AUD5_TXC (_MX51_PAD_EIM_CS4__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__CSI1_D6 (_MX51_PAD_EIM_CS4__CSI1_D6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__EIM_CS4 (_MX51_PAD_EIM_CS4__EIM_CS4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__FEC_RX_ER (_MX51_PAD_EIM_CS4__FEC_RX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_EIM_CS4__GPIO2_29 (_MX51_PAD_EIM_CS4__GPIO2_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__USBOTG_CLK (_MX51_PAD_EIM_CS4__USBOTG_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__AUD5_TXFS (_MX51_PAD_EIM_CS5__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__CSI1_D7 (_MX51_PAD_EIM_CS5__CSI1_D7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__DISP1_EXT_CLK (_MX51_PAD_EIM_CS5__DISP1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__EIM_CS5 (_MX51_PAD_EIM_CS5__EIM_CS5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__FEC_CRS (_MX51_PAD_EIM_CS5__FEC_CRS | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_EIM_CS5__GPIO2_30 (_MX51_PAD_EIM_CS5__GPIO2_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__USBOTG_DIR (_MX51_PAD_EIM_CS5__USBOTG_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DTACK__EIM_DTACK (_MX51_PAD_EIM_DTACK__EIM_DTACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DTACK__GPIO2_31 (_MX51_PAD_EIM_DTACK__GPIO2_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_LBA__EIM_LBA (_MX51_PAD_EIM_LBA__EIM_LBA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_LBA__GPIO3_1 (_MX51_PAD_EIM_LBA__GPIO3_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CRE__EIM_CRE (_MX51_PAD_EIM_CRE__EIM_CRE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CRE__GPIO3_2 (_MX51_PAD_EIM_CRE__GPIO3_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DRAM_CS1__DRAM_CS1 (_MX51_PAD_DRAM_CS1__DRAM_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__GPIO3_3 (_MX51_PAD_NANDF_WE_B__GPIO3_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__NANDF_WE_B (_MX51_PAD_NANDF_WE_B__NANDF_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__PATA_DIOW (_MX51_PAD_NANDF_WE_B__PATA_DIOW | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__SD3_DATA0 (_MX51_PAD_NANDF_WE_B__SD3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__GPIO3_4 (_MX51_PAD_NANDF_RE_B__GPIO3_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__NANDF_RE_B (_MX51_PAD_NANDF_RE_B__NANDF_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__PATA_DIOR (_MX51_PAD_NANDF_RE_B__PATA_DIOR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__SD3_DATA1 (_MX51_PAD_NANDF_RE_B__SD3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__GPIO3_5 (_MX51_PAD_NANDF_ALE__GPIO3_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__NANDF_ALE (_MX51_PAD_NANDF_ALE__NANDF_ALE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__PATA_BUFFER_EN (_MX51_PAD_NANDF_ALE__PATA_BUFFER_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__GPIO3_6 (_MX51_PAD_NANDF_CLE__GPIO3_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__NANDF_CLE (_MX51_PAD_NANDF_CLE__NANDF_CLE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__PATA_RESET_B (_MX51_PAD_NANDF_CLE__PATA_RESET_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__GPIO3_7 (_MX51_PAD_NANDF_WP_B__GPIO3_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__NANDF_WP_B (_MX51_PAD_NANDF_WP_B__NANDF_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__PATA_DMACK (_MX51_PAD_NANDF_WP_B__PATA_DMACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__SD3_DATA2 (_MX51_PAD_NANDF_WP_B__SD3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__ECSPI2_SS1 (_MX51_PAD_NANDF_RB0__ECSPI2_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__GPIO3_8 (_MX51_PAD_NANDF_RB0__GPIO3_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__NANDF_RB0 (_MX51_PAD_NANDF_RB0__NANDF_RB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__PATA_DMARQ (_MX51_PAD_NANDF_RB0__PATA_DMARQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__SD3_DATA3 (_MX51_PAD_NANDF_RB0__SD3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__CSPI_MOSI (_MX51_PAD_NANDF_RB1__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__ECSPI2_RDY (_MX51_PAD_NANDF_RB1__ECSPI2_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__GPIO3_9 (_MX51_PAD_NANDF_RB1__GPIO3_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__NANDF_RB1 (_MX51_PAD_NANDF_RB1__NANDF_RB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__PATA_IORDY (_MX51_PAD_NANDF_RB1__PATA_IORDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__SD4_CMD (_MX51_PAD_NANDF_RB1__SD4_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__DISP2_WAIT (_MX51_PAD_NANDF_RB2__DISP2_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK (_MX51_PAD_NANDF_RB2__ECSPI2_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__FEC_COL (_MX51_PAD_NANDF_RB2__FEC_COL | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_NANDF_RB2__GPIO3_10 (_MX51_PAD_NANDF_RB2__GPIO3_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__NANDF_RB2 (_MX51_PAD_NANDF_RB2__NANDF_RB2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__USBH3_H3_DP (_MX51_PAD_NANDF_RB2__USBH3_H3_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__USBH3_NXT (_MX51_PAD_NANDF_RB2__USBH3_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__DISP1_WAIT (_MX51_PAD_NANDF_RB3__DISP1_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO (_MX51_PAD_NANDF_RB3__ECSPI2_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__FEC_RX_CLK (_MX51_PAD_NANDF_RB3__FEC_RX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_NANDF_RB3__GPIO3_11 (_MX51_PAD_NANDF_RB3__GPIO3_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__NANDF_RB3 (_MX51_PAD_NANDF_RB3__NANDF_RB3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__USBH3_CLK (_MX51_PAD_NANDF_RB3__USBH3_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__USBH3_H3_DM (_MX51_PAD_NANDF_RB3__USBH3_H3_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO_NAND__GPIO_NAND (_MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_GPIO_NAND__PATA_INTRQ (_MX51_PAD_GPIO_NAND__PATA_INTRQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS0__GPIO3_16 (_MX51_PAD_NANDF_CS0__GPIO3_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS0__NANDF_CS0 (_MX51_PAD_NANDF_CS0__NANDF_CS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS1__GPIO3_17 (_MX51_PAD_NANDF_CS1__GPIO3_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS1__NANDF_CS1 (_MX51_PAD_NANDF_CS1__NANDF_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__CSPI_SCLK (_MX51_PAD_NANDF_CS2__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER (_MX51_PAD_NANDF_CS2__FEC_TX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS2__GPIO3_18 (_MX51_PAD_NANDF_CS2__GPIO3_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__NANDF_CS2 (_MX51_PAD_NANDF_CS2__NANDF_CS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__PATA_CS_0 (_MX51_PAD_NANDF_CS2__PATA_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__SD4_CLK (_MX51_PAD_NANDF_CS2__SD4_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__USBH3_H1_DP (_MX51_PAD_NANDF_CS2__USBH3_H1_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__FEC_MDC (_MX51_PAD_NANDF_CS3__FEC_MDC | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS3__GPIO3_19 (_MX51_PAD_NANDF_CS3__GPIO3_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__NANDF_CS3 (_MX51_PAD_NANDF_CS3__NANDF_CS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__PATA_CS_1 (_MX51_PAD_NANDF_CS3__PATA_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__SD4_DAT0 (_MX51_PAD_NANDF_CS3__SD4_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__USBH3_H1_DM (_MX51_PAD_NANDF_CS3__USBH3_H1_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__FEC_TDATA1 (_MX51_PAD_NANDF_CS4__FEC_TDATA1 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS4__GPIO3_20 (_MX51_PAD_NANDF_CS4__GPIO3_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__NANDF_CS4 (_MX51_PAD_NANDF_CS4__NANDF_CS4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__PATA_DA_0 (_MX51_PAD_NANDF_CS4__PATA_DA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__SD4_DAT1 (_MX51_PAD_NANDF_CS4__SD4_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__USBH3_STP (_MX51_PAD_NANDF_CS4__USBH3_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__FEC_TDATA2 (_MX51_PAD_NANDF_CS5__FEC_TDATA2 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS5__GPIO3_21 (_MX51_PAD_NANDF_CS5__GPIO3_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__NANDF_CS5 (_MX51_PAD_NANDF_CS5__NANDF_CS5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__PATA_DA_1 (_MX51_PAD_NANDF_CS5__PATA_DA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__SD4_DAT2 (_MX51_PAD_NANDF_CS5__SD4_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__USBH3_DIR (_MX51_PAD_NANDF_CS5__USBH3_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__CSPI_SS3 (_MX51_PAD_NANDF_CS6__CSPI_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__FEC_TDATA3 (_MX51_PAD_NANDF_CS6__FEC_TDATA3 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS6__GPIO3_22 (_MX51_PAD_NANDF_CS6__GPIO3_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__NANDF_CS6 (_MX51_PAD_NANDF_CS6__NANDF_CS6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__PATA_DA_2 (_MX51_PAD_NANDF_CS6__PATA_DA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__SD4_DAT3 (_MX51_PAD_NANDF_CS6__SD4_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN (_MX51_PAD_NANDF_CS7__FEC_TX_EN | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS7__GPIO3_23 (_MX51_PAD_NANDF_CS7__GPIO3_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__NANDF_CS7 (_MX51_PAD_NANDF_CS7__NANDF_CS7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__SD3_CLK (_MX51_PAD_NANDF_CS7__SD3_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 (_MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK (_MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_NANDF_RDY_INT__GPIO3_24 (_MX51_PAD_NANDF_RDY_INT__GPIO3_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT (_MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__SD3_CMD (_MX51_PAD_NANDF_RDY_INT__SD3_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI (_MX51_PAD_NANDF_D15__ECSPI2_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__GPIO3_25 (_MX51_PAD_NANDF_D15__GPIO3_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__NANDF_D15 (_MX51_PAD_NANDF_D15__NANDF_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__PATA_DATA15 (_MX51_PAD_NANDF_D15__PATA_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__SD3_DAT7 (_MX51_PAD_NANDF_D15__SD3_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__ECSPI2_SS3 (_MX51_PAD_NANDF_D14__ECSPI2_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__GPIO3_26 (_MX51_PAD_NANDF_D14__GPIO3_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__NANDF_D14 (_MX51_PAD_NANDF_D14__NANDF_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__PATA_DATA14 (_MX51_PAD_NANDF_D14__PATA_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__SD3_DAT6 (_MX51_PAD_NANDF_D14__SD3_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__ECSPI2_SS2 (_MX51_PAD_NANDF_D13__ECSPI2_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__GPIO3_27 (_MX51_PAD_NANDF_D13__GPIO3_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__NANDF_D13 (_MX51_PAD_NANDF_D13__NANDF_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__PATA_DATA13 (_MX51_PAD_NANDF_D13__PATA_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__SD3_DAT5 (_MX51_PAD_NANDF_D13__SD3_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__ECSPI2_SS1 (_MX51_PAD_NANDF_D12__ECSPI2_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__GPIO3_28 (_MX51_PAD_NANDF_D12__GPIO3_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__NANDF_D12 (_MX51_PAD_NANDF_D12__NANDF_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__PATA_DATA12 (_MX51_PAD_NANDF_D12__PATA_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__SD3_DAT4 (_MX51_PAD_NANDF_D12__SD3_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__FEC_RX_DV (_MX51_PAD_NANDF_D11__FEC_RX_DV | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__GPIO3_29 (_MX51_PAD_NANDF_D11__GPIO3_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__NANDF_D11 (_MX51_PAD_NANDF_D11__NANDF_D11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__PATA_DATA11 (_MX51_PAD_NANDF_D11__PATA_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__SD3_DATA3 (_MX51_PAD_NANDF_D11__SD3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__GPIO3_30 (_MX51_PAD_NANDF_D10__GPIO3_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__NANDF_D10 (_MX51_PAD_NANDF_D10__NANDF_D10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__PATA_DATA10 (_MX51_PAD_NANDF_D10__PATA_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__SD3_DATA2 (_MX51_PAD_NANDF_D10__SD3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__FEC_RDATA0 (_MX51_PAD_NANDF_D9__FEC_RDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_NANDF_D9__GPIO3_31 (_MX51_PAD_NANDF_D9__GPIO3_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__NANDF_D9 (_MX51_PAD_NANDF_D9__NANDF_D9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__PATA_DATA9 (_MX51_PAD_NANDF_D9__PATA_DATA9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__SD3_DATA1 (_MX51_PAD_NANDF_D9__SD3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__FEC_TDATA0 (_MX51_PAD_NANDF_D8__FEC_TDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_D8__GPIO4_0 (_MX51_PAD_NANDF_D8__GPIO4_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__NANDF_D8 (_MX51_PAD_NANDF_D8__NANDF_D8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__PATA_DATA8 (_MX51_PAD_NANDF_D8__PATA_DATA8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__SD3_DATA0 (_MX51_PAD_NANDF_D8__SD3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__GPIO4_1 (_MX51_PAD_NANDF_D7__GPIO4_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__NANDF_D7 (_MX51_PAD_NANDF_D7__NANDF_D7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__PATA_DATA7 (_MX51_PAD_NANDF_D7__PATA_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__USBH3_DATA0 (_MX51_PAD_NANDF_D7__USBH3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__GPIO4_2 (_MX51_PAD_NANDF_D6__GPIO4_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__NANDF_D6 (_MX51_PAD_NANDF_D6__NANDF_D6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__PATA_DATA6 (_MX51_PAD_NANDF_D6__PATA_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__SD4_LCTL (_MX51_PAD_NANDF_D6__SD4_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__USBH3_DATA1 (_MX51_PAD_NANDF_D6__USBH3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__GPIO4_3 (_MX51_PAD_NANDF_D5__GPIO4_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__NANDF_D5 (_MX51_PAD_NANDF_D5__NANDF_D5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__PATA_DATA5 (_MX51_PAD_NANDF_D5__PATA_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__SD4_WP (_MX51_PAD_NANDF_D5__SD4_WP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__USBH3_DATA2 (_MX51_PAD_NANDF_D5__USBH3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__GPIO4_4 (_MX51_PAD_NANDF_D4__GPIO4_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__NANDF_D4 (_MX51_PAD_NANDF_D4__NANDF_D4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__PATA_DATA4 (_MX51_PAD_NANDF_D4__PATA_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__SD4_CD (_MX51_PAD_NANDF_D4__SD4_CD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__USBH3_DATA3 (_MX51_PAD_NANDF_D4__USBH3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__GPIO4_5 (_MX51_PAD_NANDF_D3__GPIO4_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__NANDF_D3 (_MX51_PAD_NANDF_D3__NANDF_D3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__PATA_DATA3 (_MX51_PAD_NANDF_D3__PATA_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__SD4_DAT4 (_MX51_PAD_NANDF_D3__SD4_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__USBH3_DATA4 (_MX51_PAD_NANDF_D3__USBH3_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__GPIO4_6 (_MX51_PAD_NANDF_D2__GPIO4_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__NANDF_D2 (_MX51_PAD_NANDF_D2__NANDF_D2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__PATA_DATA2 (_MX51_PAD_NANDF_D2__PATA_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__SD4_DAT5 (_MX51_PAD_NANDF_D2__SD4_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__USBH3_DATA5 (_MX51_PAD_NANDF_D2__USBH3_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__GPIO4_7 (_MX51_PAD_NANDF_D1__GPIO4_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__NANDF_D1 (_MX51_PAD_NANDF_D1__NANDF_D1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__PATA_DATA1 (_MX51_PAD_NANDF_D1__PATA_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__SD4_DAT6 (_MX51_PAD_NANDF_D1__SD4_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__USBH3_DATA6 (_MX51_PAD_NANDF_D1__USBH3_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__GPIO4_8 (_MX51_PAD_NANDF_D0__GPIO4_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__NANDF_D0 (_MX51_PAD_NANDF_D0__NANDF_D0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__PATA_DATA0 (_MX51_PAD_NANDF_D0__PATA_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__SD4_DAT7 (_MX51_PAD_NANDF_D0__SD4_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__USBH3_DATA7 (_MX51_PAD_NANDF_D0__USBH3_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D8__CSI1_D8 (_MX51_PAD_CSI1_D8__CSI1_D8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D8__GPIO3_12 (_MX51_PAD_CSI1_D8__GPIO3_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_D9__CSI1_D9 (_MX51_PAD_CSI1_D9__CSI1_D9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D9__GPIO3_13 (_MX51_PAD_CSI1_D9__GPIO3_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_D10__CSI1_D10 (_MX51_PAD_CSI1_D10__CSI1_D10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D11__CSI1_D11 (_MX51_PAD_CSI1_D11__CSI1_D11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D12__CSI1_D12 (_MX51_PAD_CSI1_D12__CSI1_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D13__CSI1_D13 (_MX51_PAD_CSI1_D13__CSI1_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D14__CSI1_D14 (_MX51_PAD_CSI1_D14__CSI1_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D15__CSI1_D15 (_MX51_PAD_CSI1_D15__CSI1_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D16__CSI1_D16 (_MX51_PAD_CSI1_D16__CSI1_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D17__CSI1_D17 (_MX51_PAD_CSI1_D17__CSI1_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D18__CSI1_D18 (_MX51_PAD_CSI1_D18__CSI1_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D19__CSI1_D19 (_MX51_PAD_CSI1_D19__CSI1_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC (_MX51_PAD_CSI1_VSYNC__CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_VSYNC__GPIO3_14 (_MX51_PAD_CSI1_VSYNC__GPIO3_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC (_MX51_PAD_CSI1_HSYNC__CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_HSYNC__GPIO3_15 (_MX51_PAD_CSI1_HSYNC__GPIO3_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK (_MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK (_MX51_PAD_CSI1_MCLK__CSI1_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D12__CSI2_D12 (_MX51_PAD_CSI2_D12__CSI2_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D12__GPIO4_9 (_MX51_PAD_CSI2_D12__GPIO4_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D13__CSI2_D13 (_MX51_PAD_CSI2_D13__CSI2_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D13__GPIO4_10 (_MX51_PAD_CSI2_D13__GPIO4_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D14__CSI2_D14 (_MX51_PAD_CSI2_D14__CSI2_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D15__CSI2_D15 (_MX51_PAD_CSI2_D15__CSI2_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D16__CSI2_D16 (_MX51_PAD_CSI2_D16__CSI2_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D17__CSI2_D17 (_MX51_PAD_CSI2_D17__CSI2_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D18__CSI2_D18 (_MX51_PAD_CSI2_D18__CSI2_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D18__GPIO4_11 (_MX51_PAD_CSI2_D18__GPIO4_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D19__CSI2_D19 (_MX51_PAD_CSI2_D19__CSI2_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D19__GPIO4_12 (_MX51_PAD_CSI2_D19__GPIO4_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC (_MX51_PAD_CSI2_VSYNC__CSI2_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_VSYNC__GPIO4_13 (_MX51_PAD_CSI2_VSYNC__GPIO4_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC (_MX51_PAD_CSI2_HSYNC__CSI2_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_HSYNC__GPIO4_14 (_MX51_PAD_CSI2_HSYNC__GPIO4_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK (_MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_PIXCLK__GPIO4_15 (_MX51_PAD_CSI2_PIXCLK__GPIO4_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_CLK__GPIO4_16 (_MX51_PAD_I2C1_CLK__GPIO4_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_CLK__I2C1_CLK (_MX51_PAD_I2C1_CLK__I2C1_CLK | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_I2C1_DAT__GPIO4_17 (_MX51_PAD_I2C1_DAT__GPIO4_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_DAT__I2C1_DAT (_MX51_PAD_I2C1_DAT__I2C1_DAT | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_TXD__AUD3_TXD (_MX51_PAD_AUD3_BB_TXD__AUD3_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_TXD__GPIO4_18 (_MX51_PAD_AUD3_BB_TXD__GPIO4_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__AUD3_RXD (_MX51_PAD_AUD3_BB_RXD__AUD3_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__GPIO4_19 (_MX51_PAD_AUD3_BB_RXD__GPIO4_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__UART3_RXD (_MX51_PAD_AUD3_BB_RXD__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_CK__AUD3_TXC (_MX51_PAD_AUD3_BB_CK__AUD3_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_CK__GPIO4_20 (_MX51_PAD_AUD3_BB_CK__GPIO4_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__AUD3_TXFS (_MX51_PAD_AUD3_BB_FS__AUD3_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__GPIO4_21 (_MX51_PAD_AUD3_BB_FS__GPIO4_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__UART3_TXD (_MX51_PAD_AUD3_BB_FS__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI (_MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__GPIO4_22 (_MX51_PAD_CSPI1_MOSI__GPIO4_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__I2C1_SDA (_MX51_PAD_CSPI1_MOSI__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__AUD4_RXD (_MX51_PAD_CSPI1_MISO__AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO (_MX51_PAD_CSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__GPIO4_23 (_MX51_PAD_CSPI1_MISO__GPIO4_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__AUD4_TXC (_MX51_PAD_CSPI1_SS0__AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 (_MX51_PAD_CSPI1_SS0__ECSPI1_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__GPIO4_24 (_MX51_PAD_CSPI1_SS0__GPIO4_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__AUD4_TXD (_MX51_PAD_CSPI1_SS1__AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 (_MX51_PAD_CSPI1_SS1__ECSPI1_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__GPIO4_25 (_MX51_PAD_CSPI1_SS1__GPIO4_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__AUD4_TXFS (_MX51_PAD_CSPI1_RDY__AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY (_MX51_PAD_CSPI1_RDY__ECSPI1_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__GPIO4_26 (_MX51_PAD_CSPI1_RDY__GPIO4_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK (_MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__GPIO4_27 (_MX51_PAD_CSPI1_SCLK__GPIO4_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__I2C1_SCL (_MX51_PAD_CSPI1_SCLK__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_UART1_RXD__GPIO4_28 (_MX51_PAD_UART1_RXD__GPIO4_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_RXD__UART1_RXD (_MX51_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__GPIO4_29 (_MX51_PAD_UART1_TXD__GPIO4_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__PWM2_PWMO (_MX51_PAD_UART1_TXD__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__UART1_TXD (_MX51_PAD_UART1_TXD__UART1_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_RTS__GPIO4_30 (_MX51_PAD_UART1_RTS__GPIO4_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_RTS__UART1_RTS (_MX51_PAD_UART1_RTS__UART1_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_CTS__GPIO4_31 (_MX51_PAD_UART1_CTS__GPIO4_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_CTS__UART1_CTS (_MX51_PAD_UART1_CTS__UART1_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__FIRI_TXD (_MX51_PAD_UART2_RXD__FIRI_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__GPIO1_20 (_MX51_PAD_UART2_RXD__GPIO1_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__UART2_RXD (_MX51_PAD_UART2_RXD__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__FIRI_RXD (_MX51_PAD_UART2_TXD__FIRI_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__GPIO1_21 (_MX51_PAD_UART2_TXD__GPIO1_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__UART2_TXD (_MX51_PAD_UART2_TXD__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__CSI1_D0 (_MX51_PAD_UART3_RXD__CSI1_D0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__GPIO1_22 (_MX51_PAD_UART3_RXD__GPIO1_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__UART1_DTR (_MX51_PAD_UART3_RXD__UART1_DTR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__UART3_RXD (_MX51_PAD_UART3_RXD__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__CSI1_D1 (_MX51_PAD_UART3_TXD__CSI1_D1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__GPIO1_23 (_MX51_PAD_UART3_TXD__GPIO1_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__UART1_DSR (_MX51_PAD_UART3_TXD__UART1_DSR | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__UART3_TXD (_MX51_PAD_UART3_TXD__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__GPIO1_24 (_MX51_PAD_OWIRE_LINE__GPIO1_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__OWIRE_LINE (_MX51_PAD_OWIRE_LINE__OWIRE_LINE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__SPDIF_OUT (_MX51_PAD_OWIRE_LINE__SPDIF_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW0__KEY_ROW0 (_MX51_PAD_KEY_ROW0__KEY_ROW0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW1__KEY_ROW1 (_MX51_PAD_KEY_ROW1__KEY_ROW1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW2__KEY_ROW2 (_MX51_PAD_KEY_ROW2__KEY_ROW2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW3__KEY_ROW3 (_MX51_PAD_KEY_ROW3__KEY_ROW3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL0__KEY_COL0 (_MX51_PAD_KEY_COL0__KEY_COL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL0__PLL1_BYP (_MX51_PAD_KEY_COL0__PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL1__KEY_COL1 (_MX51_PAD_KEY_COL1__KEY_COL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL1__PLL2_BYP (_MX51_PAD_KEY_COL1__PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL2__KEY_COL2 (_MX51_PAD_KEY_COL2__KEY_COL2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL2__PLL3_BYP (_MX51_PAD_KEY_COL2__PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL3__KEY_COL3 (_MX51_PAD_KEY_COL3__KEY_COL3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__I2C2_SCL (_MX51_PAD_KEY_COL4__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__KEY_COL4 (_MX51_PAD_KEY_COL4__KEY_COL4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__SPDIF_OUT1 (_MX51_PAD_KEY_COL4__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__UART1_RI (_MX51_PAD_KEY_COL4__UART1_RI | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__UART3_RTS (_MX51_PAD_KEY_COL4__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__I2C2_SDA (_MX51_PAD_KEY_COL5__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__KEY_COL5 (_MX51_PAD_KEY_COL5__KEY_COL5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__UART1_DCD (_MX51_PAD_KEY_COL5__UART1_DCD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__UART3_CTS (_MX51_PAD_KEY_COL5__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__CSPI_SCLK (_MX51_PAD_USBH1_CLK__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__GPIO1_25 (_MX51_PAD_USBH1_CLK__GPIO1_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__I2C2_SCL (_MX51_PAD_USBH1_CLK__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__USBH1_CLK (_MX51_PAD_USBH1_CLK__USBH1_CLK | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__CSPI_MOSI (_MX51_PAD_USBH1_DIR__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__GPIO1_26 (_MX51_PAD_USBH1_DIR__GPIO1_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__I2C2_SDA (_MX51_PAD_USBH1_DIR__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__USBH1_DIR (_MX51_PAD_USBH1_DIR__USBH1_DIR | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__CSPI_RDY (_MX51_PAD_USBH1_STP__CSPI_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__GPIO1_27 (_MX51_PAD_USBH1_STP__GPIO1_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__UART3_RXD (_MX51_PAD_USBH1_STP__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__USBH1_STP (_MX51_PAD_USBH1_STP__USBH1_STP | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__CSPI_MISO (_MX51_PAD_USBH1_NXT__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__GPIO1_28 (_MX51_PAD_USBH1_NXT__GPIO1_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__UART3_TXD (_MX51_PAD_USBH1_NXT__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__USBH1_NXT (_MX51_PAD_USBH1_NXT__USBH1_NXT | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__GPIO1_11 (_MX51_PAD_USBH1_DATA0__GPIO1_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__UART2_CTS (_MX51_PAD_USBH1_DATA0__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 (_MX51_PAD_USBH1_DATA0__USBH1_DATA0 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__GPIO1_12 (_MX51_PAD_USBH1_DATA1__GPIO1_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__UART2_RXD (_MX51_PAD_USBH1_DATA1__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 (_MX51_PAD_USBH1_DATA1__USBH1_DATA1 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__GPIO1_13 (_MX51_PAD_USBH1_DATA2__GPIO1_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__UART2_TXD (_MX51_PAD_USBH1_DATA2__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 (_MX51_PAD_USBH1_DATA2__USBH1_DATA2 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__GPIO1_14 (_MX51_PAD_USBH1_DATA3__GPIO1_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__UART2_RTS (_MX51_PAD_USBH1_DATA3__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 (_MX51_PAD_USBH1_DATA3__USBH1_DATA3 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__CSPI_SS0 (_MX51_PAD_USBH1_DATA4__CSPI_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__GPIO1_15 (_MX51_PAD_USBH1_DATA4__GPIO1_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 (_MX51_PAD_USBH1_DATA4__USBH1_DATA4 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__CSPI_SS1 (_MX51_PAD_USBH1_DATA5__CSPI_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__GPIO1_16 (_MX51_PAD_USBH1_DATA5__GPIO1_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 (_MX51_PAD_USBH1_DATA5__USBH1_DATA5 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__CSPI_SS3 (_MX51_PAD_USBH1_DATA6__CSPI_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__GPIO1_17 (_MX51_PAD_USBH1_DATA6__GPIO1_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 (_MX51_PAD_USBH1_DATA6__USBH1_DATA6 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__ECSPI1_SS3 (_MX51_PAD_USBH1_DATA7__ECSPI1_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__ECSPI2_SS3 (_MX51_PAD_USBH1_DATA7__ECSPI2_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__GPIO1_18 (_MX51_PAD_USBH1_DATA7__GPIO1_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 (_MX51_PAD_USBH1_DATA7__USBH1_DATA7 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__DI1_PIN11 (_MX51_PAD_DI1_PIN11__DI1_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__ECSPI1_SS2 (_MX51_PAD_DI1_PIN11__ECSPI1_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__GPIO3_0 (_MX51_PAD_DI1_PIN11__GPIO3_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN12__DI1_PIN12 (_MX51_PAD_DI1_PIN12__DI1_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN12__GPIO3_1 (_MX51_PAD_DI1_PIN12__GPIO3_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN13__DI1_PIN13 (_MX51_PAD_DI1_PIN13__DI1_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN13__GPIO3_2 (_MX51_PAD_DI1_PIN13__GPIO3_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_D0_CS__DI1_D0_CS (_MX51_PAD_DI1_D0_CS__DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D0_CS__GPIO3_3 (_MX51_PAD_DI1_D0_CS__GPIO3_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DI1_D1_CS (_MX51_PAD_DI1_D1_CS__DI1_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN14 (_MX51_PAD_DI1_D1_CS__DISP1_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN5 (_MX51_PAD_DI1_D1_CS__DISP1_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__GPIO3_4 (_MX51_PAD_DI1_D1_CS__GPIO3_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 (_MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN (_MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__GPIO3_5 (_MX51_PAD_DISPB2_SER_DIN__GPIO3_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 (_MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO (_MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__GPIO3_6 (_MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 (_MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 (_MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK (_MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__GPIO3_7 (_MX51_PAD_DISPB2_SER_CLK__GPIO3_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK (_MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 (_MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 (_MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS (_MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS (_MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__GPIO3_8 (_MX51_PAD_DISPB2_SER_RS__GPIO3_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 (_MX51_PAD_DISP1_DAT0__DISP1_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 (_MX51_PAD_DISP1_DAT1__DISP1_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 (_MX51_PAD_DISP1_DAT2__DISP1_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 (_MX51_PAD_DISP1_DAT3__DISP1_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 (_MX51_PAD_DISP1_DAT4__DISP1_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 (_MX51_PAD_DISP1_DAT5__DISP1_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT6__BOOT_USB_SRC (_MX51_PAD_DISP1_DAT6__BOOT_USB_SRC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 (_MX51_PAD_DISP1_DAT6__DISP1_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG (_MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 (_MX51_PAD_DISP1_DAT7__DISP1_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT8__BOOT_SRC0 (_MX51_PAD_DISP1_DAT8__BOOT_SRC0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 (_MX51_PAD_DISP1_DAT8__DISP1_DAT8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT9__BOOT_SRC1 (_MX51_PAD_DISP1_DAT9__BOOT_SRC1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 (_MX51_PAD_DISP1_DAT9__DISP1_DAT9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE (_MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 (_MX51_PAD_DISP1_DAT10__DISP1_DAT10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 (_MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 (_MX51_PAD_DISP1_DAT11__DISP1_DAT11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL (_MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 (_MX51_PAD_DISP1_DAT12__DISP1_DAT12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 (_MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 (_MX51_PAD_DISP1_DAT13__DISP1_DAT13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 (_MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 (_MX51_PAD_DISP1_DAT14__DISP1_DAT14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH (_MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 (_MX51_PAD_DISP1_DAT15__DISP1_DAT15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 (_MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 (_MX51_PAD_DISP1_DAT16__DISP1_DAT16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 (_MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 (_MX51_PAD_DISP1_DAT17__DISP1_DAT17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 (_MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 (_MX51_PAD_DISP1_DAT18__DISP1_DAT18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN11 (_MX51_PAD_DISP1_DAT18__DISP2_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN5 (_MX51_PAD_DISP1_DAT18__DISP2_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 (_MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 (_MX51_PAD_DISP1_DAT19__DISP1_DAT19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN12 (_MX51_PAD_DISP1_DAT19__DISP2_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN6 (_MX51_PAD_DISP1_DAT19__DISP2_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 (_MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 (_MX51_PAD_DISP1_DAT20__DISP1_DAT20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN13 (_MX51_PAD_DISP1_DAT20__DISP2_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN7 (_MX51_PAD_DISP1_DAT20__DISP2_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 (_MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 (_MX51_PAD_DISP1_DAT21__DISP1_DAT21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN14 (_MX51_PAD_DISP1_DAT21__DISP2_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN8 (_MX51_PAD_DISP1_DAT21__DISP2_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 (_MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 (_MX51_PAD_DISP1_DAT22__DISP1_DAT22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP2_D0_CS (_MX51_PAD_DISP1_DAT22__DISP2_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP2_DAT16 (_MX51_PAD_DISP1_DAT22__DISP2_DAT16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 (_MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 (_MX51_PAD_DISP1_DAT23__DISP1_DAT23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_D1_CS (_MX51_PAD_DISP1_DAT23__DISP2_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_DAT17 (_MX51_PAD_DISP1_DAT23__DISP2_DAT17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_SER_CS (_MX51_PAD_DISP1_DAT23__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN3__DI1_PIN3 (_MX51_PAD_DI1_PIN3__DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN2__DI1_PIN2 (_MX51_PAD_DI1_PIN2__DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP2__DISP1_SER_CLK (_MX51_PAD_DI_GP2__DISP1_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP2__DISP2_WAIT (_MX51_PAD_DI_GP2__DISP2_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__CSI1_DATA_EN (_MX51_PAD_DI_GP3__CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__DISP1_SER_DIO (_MX51_PAD_DI_GP3__DISP1_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__FEC_TX_ER (_MX51_PAD_DI_GP3__FEC_TX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DI2_PIN4__CSI2_DATA_EN (_MX51_PAD_DI2_PIN4__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN4__DI2_PIN4 (_MX51_PAD_DI2_PIN4__DI2_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN4__FEC_CRS (_MX51_PAD_DI2_PIN4__FEC_CRS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN2__DI2_PIN2 (_MX51_PAD_DI2_PIN2__DI2_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN2__FEC_MDC (_MX51_PAD_DI2_PIN2__FEC_MDC | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DI2_PIN3__DI2_PIN3 (_MX51_PAD_DI2_PIN3__DI2_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN3__FEC_MDIO (_MX51_PAD_DI2_PIN3__FEC_MDIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK (_MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 (_MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DI2_PIN15 (_MX51_PAD_DI_GP4__DI2_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DISP1_SER_DIN (_MX51_PAD_DI_GP4__DISP1_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DISP2_PIN1 (_MX51_PAD_DI_GP4__DISP2_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__FEC_RDATA2 (_MX51_PAD_DI_GP4__FEC_RDATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 (_MX51_PAD_DISP2_DAT0__DISP2_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 (_MX51_PAD_DISP2_DAT0__FEC_RDATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__KEY_COL6 (_MX51_PAD_DISP2_DAT0__KEY_COL6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__UART3_RXD (_MX51_PAD_DISP2_DAT0__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__USBH3_CLK (_MX51_PAD_DISP2_DAT0__USBH3_CLK | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 (_MX51_PAD_DISP2_DAT1__DISP2_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__FEC_RX_ER (_MX51_PAD_DISP2_DAT1__FEC_RX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__KEY_COL7 (_MX51_PAD_DISP2_DAT1__KEY_COL7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__UART3_TXD (_MX51_PAD_DISP2_DAT1__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__USBH3_DIR (_MX51_PAD_DISP2_DAT1__USBH3_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 (_MX51_PAD_DISP2_DAT2__DISP2_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 (_MX51_PAD_DISP2_DAT3__DISP2_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 (_MX51_PAD_DISP2_DAT4__DISP2_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 (_MX51_PAD_DISP2_DAT5__DISP2_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__DISP2_DAT6 (_MX51_PAD_DISP2_DAT6__DISP2_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__FEC_TDATA1 (_MX51_PAD_DISP2_DAT6__FEC_TDATA1 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT6__GPIO1_19 (_MX51_PAD_DISP2_DAT6__GPIO1_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__KEY_ROW4 (_MX51_PAD_DISP2_DAT6__KEY_ROW4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__USBH3_STP (_MX51_PAD_DISP2_DAT6__USBH3_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__DISP2_DAT7 (_MX51_PAD_DISP2_DAT7__DISP2_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__FEC_TDATA2 (_MX51_PAD_DISP2_DAT7__FEC_TDATA2 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT7__GPIO1_29 (_MX51_PAD_DISP2_DAT7__GPIO1_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__KEY_ROW5 (_MX51_PAD_DISP2_DAT7__KEY_ROW5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__USBH3_NXT (_MX51_PAD_DISP2_DAT7__USBH3_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__DISP2_DAT8 (_MX51_PAD_DISP2_DAT8__DISP2_DAT8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__FEC_TDATA3 (_MX51_PAD_DISP2_DAT8__FEC_TDATA3 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT8__GPIO1_30 (_MX51_PAD_DISP2_DAT8__GPIO1_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__KEY_ROW6 (_MX51_PAD_DISP2_DAT8__KEY_ROW6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__USBH3_DATA0 (_MX51_PAD_DISP2_DAT8__USBH3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__AUD6_RXC (_MX51_PAD_DISP2_DAT9__AUD6_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__DISP2_DAT9 (_MX51_PAD_DISP2_DAT9__DISP2_DAT9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__FEC_TX_EN (_MX51_PAD_DISP2_DAT9__FEC_TX_EN | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT9__GPIO1_31 (_MX51_PAD_DISP2_DAT9__GPIO1_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__USBH3_DATA1 (_MX51_PAD_DISP2_DAT9__USBH3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 (_MX51_PAD_DISP2_DAT10__DISP2_DAT10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__DISP2_SER_CS (_MX51_PAD_DISP2_DAT10__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__FEC_COL (_MX51_PAD_DISP2_DAT10__FEC_COL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__KEY_ROW7 (_MX51_PAD_DISP2_DAT10__KEY_ROW7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__USBH3_DATA2 (_MX51_PAD_DISP2_DAT10__USBH3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__AUD6_TXD (_MX51_PAD_DISP2_DAT11__AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 (_MX51_PAD_DISP2_DAT11__DISP2_DAT11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK (_MX51_PAD_DISP2_DAT11__FEC_RX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__GPIO1_10 (_MX51_PAD_DISP2_DAT11__GPIO1_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__USBH3_DATA3 (_MX51_PAD_DISP2_DAT11__USBH3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__AUD6_RXD (_MX51_PAD_DISP2_DAT12__AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 (_MX51_PAD_DISP2_DAT12__DISP2_DAT12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__FEC_RX_DV (_MX51_PAD_DISP2_DAT12__FEC_RX_DV | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__USBH3_DATA4 (_MX51_PAD_DISP2_DAT12__USBH3_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__AUD6_TXC (_MX51_PAD_DISP2_DAT13__AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 (_MX51_PAD_DISP2_DAT13__DISP2_DAT13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__FEC_TX_CLK (_MX51_PAD_DISP2_DAT13__FEC_TX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_DISP2_DAT13__USBH3_DATA5 (_MX51_PAD_DISP2_DAT13__USBH3_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__AUD6_TXFS (_MX51_PAD_DISP2_DAT14__AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 (_MX51_PAD_DISP2_DAT14__DISP2_DAT14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__FEC_RDATA0 (_MX51_PAD_DISP2_DAT14__FEC_RDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_DISP2_DAT14__USBH3_DATA6 (_MX51_PAD_DISP2_DAT14__USBH3_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__AUD6_RXFS (_MX51_PAD_DISP2_DAT15__AUD6_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__DISP1_SER_CS (_MX51_PAD_DISP2_DAT15__DISP1_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 (_MX51_PAD_DISP2_DAT15__DISP2_DAT15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__FEC_TDATA0 (_MX51_PAD_DISP2_DAT15__FEC_TDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT15__USBH3_DATA7 (_MX51_PAD_DISP2_DAT15__USBH3_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__AUD5_RXFS (_MX51_PAD_SD1_CMD__AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__CSPI_MOSI (_MX51_PAD_SD1_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__SD1_CMD (_MX51_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__AUD5_RXC (_MX51_PAD_SD1_CLK__AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__CSPI_SCLK (_MX51_PAD_SD1_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__SD1_CLK (_MX51_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_SD1_DATA0__AUD5_TXD (_MX51_PAD_SD1_DATA0__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA0__CSPI_MISO (_MX51_PAD_SD1_DATA0__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 (_MX51_PAD_SD1_DATA0__SD1_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA0__EIM_DA0 (_MX51_PAD_EIM_DA0__EIM_DA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA1__EIM_DA1 (_MX51_PAD_EIM_DA1__EIM_DA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA2__EIM_DA2 (_MX51_PAD_EIM_DA2__EIM_DA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA3__EIM_DA3 (_MX51_PAD_EIM_DA3__EIM_DA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA1__AUD5_RXD (_MX51_PAD_SD1_DATA1__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 (_MX51_PAD_SD1_DATA1__SD1_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA4__EIM_DA4 (_MX51_PAD_EIM_DA4__EIM_DA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA5__EIM_DA5 (_MX51_PAD_EIM_DA5__EIM_DA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA6__EIM_DA6 (_MX51_PAD_EIM_DA6__EIM_DA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA7__EIM_DA7 (_MX51_PAD_EIM_DA7__EIM_DA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA2__AUD5_TXC (_MX51_PAD_SD1_DATA2__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 (_MX51_PAD_SD1_DATA2__SD1_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA10__EIM_DA10 (_MX51_PAD_EIM_DA10__EIM_DA10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA11__EIM_DA11 (_MX51_PAD_EIM_DA11__EIM_DA11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA8__EIM_DA8 (_MX51_PAD_EIM_DA8__EIM_DA8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA9__EIM_DA9 (_MX51_PAD_EIM_DA9__EIM_DA9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS (_MX51_PAD_SD1_DATA3__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__CSPI_SS1 (_MX51_PAD_SD1_DATA3__CSPI_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 (_MX51_PAD_SD1_DATA3__SD1_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__CSPI_SS2 (_MX51_PAD_GPIO1_0__CSPI_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__GPIO1_0 (_MX51_PAD_GPIO1_0__GPIO1_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__SD1_CD (_MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__CSPI_MISO (_MX51_PAD_GPIO1_1__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__GPIO1_1 (_MX51_PAD_GPIO1_1__GPIO1_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__SD1_WP (_MX51_PAD_GPIO1_1__SD1_WP | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_EIM_DA12__EIM_DA12 (_MX51_PAD_EIM_DA12__EIM_DA12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA13__EIM_DA13 (_MX51_PAD_EIM_DA13__EIM_DA13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA14__EIM_DA14 (_MX51_PAD_EIM_DA14__EIM_DA14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA15__EIM_DA15 (_MX51_PAD_EIM_DA15__EIM_DA15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__CSPI_MOSI (_MX51_PAD_SD2_CMD__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__I2C1_SCL (_MX51_PAD_SD2_CMD__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__SD2_CMD (_MX51_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__CSPI_SCLK (_MX51_PAD_SD2_CLK__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__I2C1_SDA (_MX51_PAD_SD2_CLK__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__SD2_CLK (_MX51_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_SD2_DATA0__CSPI_MISO (_MX51_PAD_SD2_DATA0__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA0__SD1_DAT4 (_MX51_PAD_SD2_DATA0__SD1_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 (_MX51_PAD_SD2_DATA0__SD2_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__SD1_DAT5 (_MX51_PAD_SD2_DATA1__SD1_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 (_MX51_PAD_SD2_DATA1__SD2_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__USBH3_H2_DP (_MX51_PAD_SD2_DATA1__USBH3_H2_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__SD1_DAT6 (_MX51_PAD_SD2_DATA2__SD1_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 (_MX51_PAD_SD2_DATA2__SD2_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__USBH3_H2_DM (_MX51_PAD_SD2_DATA2__USBH3_H2_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__CSPI_SS2 (_MX51_PAD_SD2_DATA3__CSPI_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__SD1_DAT7 (_MX51_PAD_SD2_DATA3__SD1_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 (_MX51_PAD_SD2_DATA3__SD2_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__CCM_OUT_2 (_MX51_PAD_GPIO1_2__CCM_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__GPIO1_2 (_MX51_PAD_GPIO1_2__GPIO1_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__I2C2_SCL (_MX51_PAD_GPIO1_2__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__PLL1_BYP (_MX51_PAD_GPIO1_2__PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__PWM1_PWMO (_MX51_PAD_GPIO1_2__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__GPIO1_3 (_MX51_PAD_GPIO1_3__GPIO1_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__I2C2_SDA (_MX51_PAD_GPIO1_3__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__PLL2_BYP (_MX51_PAD_GPIO1_3__PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__PWM2_PWMO (_MX51_PAD_GPIO1_3__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ (_MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B (_MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__DISP2_EXT_CLK (_MX51_PAD_GPIO1_4__DISP2_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__EIM_RDY (_MX51_PAD_GPIO1_4__EIM_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__GPIO1_4 (_MX51_PAD_GPIO1_4__GPIO1_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__WDOG1_WDOG_B (_MX51_PAD_GPIO1_4__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__CSI2_MCLK (_MX51_PAD_GPIO1_5__CSI2_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__DISP2_PIN16 (_MX51_PAD_GPIO1_5__DISP2_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__GPIO1_5 (_MX51_PAD_GPIO1_5__GPIO1_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__WDOG2_WDOG_B (_MX51_PAD_GPIO1_5__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__DISP2_PIN17 (_MX51_PAD_GPIO1_6__DISP2_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__GPIO1_6 (_MX51_PAD_GPIO1_6__GPIO1_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__REF_EN_B (_MX51_PAD_GPIO1_6__REF_EN_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__CCM_OUT_0 (_MX51_PAD_GPIO1_7__CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__GPIO1_7 (_MX51_PAD_GPIO1_7__GPIO1_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__SD2_WP (_MX51_PAD_GPIO1_7__SD2_WP | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__SPDIF_OUT1 (_MX51_PAD_GPIO1_7__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__CSI2_DATA_EN (_MX51_PAD_GPIO1_8__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__GPIO1_8 (_MX51_PAD_GPIO1_8__GPIO1_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__SD2_CD (_MX51_PAD_GPIO1_8__SD2_CD | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__USBH3_PWR (_MX51_PAD_GPIO1_8__USBH3_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__CCM_OUT_1 (_MX51_PAD_GPIO1_9__CCM_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__DISP2_D1_CS (_MX51_PAD_GPIO1_9__DISP2_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__DISP2_SER_CS (_MX51_PAD_GPIO1_9__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__GPIO1_9 (_MX51_PAD_GPIO1_9__GPIO1_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__SD2_LCTL (_MX51_PAD_GPIO1_9__SD2_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__USBH3_OC (_MX51_PAD_GPIO1_9__USBH3_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
new file mode 100644
index 000000000000..5deee019c29e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc..
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_IOMUX_MX53_H__
+#define __MACH_IOMUX_MX53_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;
+
+/* These 2 defines are for pins that may not have a mux register, but could
+ * have a pad setting register, and vice-versa. */
+#define NON_MUX_I 0x00
+#define NON_PAD_I 0x00
+
+#define MX53_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+/* UART1 */
+#define MX53_PAD_CSI0_D10__UART1_TXD IOMUX_PAD(0x414, 0xE8, 2, 0x0, 0, MX53_UART_PAD_CTRL)
+#define MX53_PAD_CSI0_D11__UART1_RXD IOMUX_PAD(0x418, 0xEC, 2, 0x878, 1, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DIOW__UART1_TXD IOMUX_PAD(0x5F0, 0x270, 3, 0x0, 0, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DMACK__UART1_RXD IOMUX_PAD(0x5F4, 0x274, 3, 0x880, 3, MX53_UART_PAD_CTRL)
+
+/* UART2 */
+#define MX53_PAD_ATA_BUFFER_EN__UART2_RXD IOMUX_PAD(0x5FC, 0x27C, 3, 0x880, 3, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DMARQ__UART2_TXD IOMUX_PAD(0x5F8, 0x278, 3, 0x0, 0, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DIOR__UART2_RTS IOMUX_PAD(0x604, 0x284, 3, 0x87C, 3, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_INTRQ__UART2_CTS IOMUX_PAD(0x600, 0x280, 3, 0x0, 0, MX53_UART_PAD_CTRL)
+
+/* UART3 */
+#define MX53_PAD_ATA_CS_0__UART3_TXD IOMUX_PAD(0x61C, 0x29C, 4, 0x0, 0, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_CS_1__UART3_RXD IOMUX_PAD(0x620, 0x2A0, 4, 0x888, 3, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DA_1__UART3_CTS IOMUX_PAD(0x614, 0x294, 4, 0x0, 0, MX53_UART_PAD_CTRL)
+#define MX53_PAD_ATA_DA_2__UART3_RTS IOMUX_PAD(0x618, 0x298, 4, 0x884, 5, MX53_UART_PAD_CTRL)
+
+#define MX53_PAD_GPIO_19__GPIO_4_5 IOMUX_PAD(0x348, 0x20,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_COL0__GPIO_4_6 IOMUX_PAD(0x34C, 0x24,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_ROW0__GPIO_4_7 IOMUX_PAD(0x350, 0x28,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_COL1__GPIO_4_8 IOMUX_PAD(0x354, 0x2C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_ROW1__GPIO_4_9 IOMUX_PAD(0x358, 0x30,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_COL2__GPIO_4_10 IOMUX_PAD(0x35C, 0x34,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_ROW2__GPIO_4_11 IOMUX_PAD(0x360, 0x38,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_COL3__GPIO_4_12 IOMUX_PAD(0x364, 0x3C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_ROW3__GPIO_4_13 IOMUX_PAD(0x368, 0x40,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_COL4__GPIO_4_14 IOMUX_PAD(0x36C, 0x44,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_KEY_ROW4__GPIO_4_15 IOMUX_PAD(0x370, 0x48,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_KEYPAD__NVCC_KEYPAD IOMUX_PAD(0x374, NON_MUX_I,IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DI0_DISP_CLK__GPIO_4_16 IOMUX_PAD(0x378, 0x4C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DI0_PIN15__GPIO_4_17 IOMUX_PAD(0x37C, 0x50,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DI0_PIN2__GPIO_4_18 IOMUX_PAD(0x380, 0x54,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DI0_PIN3__GPIO_4_19 IOMUX_PAD(0x384, 0x58,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DI0_PIN4__GPIO_4_20 IOMUX_PAD(0x388, 0x5C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT0__GPIO_4_21 IOMUX_PAD(0x38C, 0x60,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT1__GPIO_4_22 IOMUX_PAD(0x390, 0x64,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT2__GPIO_4_23 IOMUX_PAD(0x394, 0x68,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT3__GPIO_4_24 IOMUX_PAD(0x398, 0x6C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT4__GPIO_4_25 IOMUX_PAD(0x39C, 0x70,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT5__GPIO_4_26 IOMUX_PAD(0x3A0, 0x74,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT6__GPIO_4_27 IOMUX_PAD(0x3A4, 0x78,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT7__GPIO_4_28 IOMUX_PAD(0x3A8, 0x7C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT8__GPIO_4_29 IOMUX_PAD(0x3AC, 0x80,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT9__GPIO_4_30 IOMUX_PAD(0x3B0, 0x84,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT10__GPIO_4_31 IOMUX_PAD(0x3B4, 0x88,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT11__GPIO_5_5 IOMUX_PAD(0x3B8, 0x8C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT12__GPIO_5_6 IOMUX_PAD(0x3BC, 0x90,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT13__GPIO_5_7 IOMUX_PAD(0x3C0, 0x94,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT14__GPIO_5_8 IOMUX_PAD(0x3C4, 0x98,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT15__GPIO_5_9 IOMUX_PAD(0x3C8, 0x9C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT16__GPIO_5_10 IOMUX_PAD(0x3CC, 0xA0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT17__GPIO_5_11 IOMUX_PAD(0x3D0, 0xA4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT18__GPIO_5_12 IOMUX_PAD(0x3D4, 0xA8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT19__GPIO_5_13 IOMUX_PAD(0x3D8, 0xAC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT20__GPIO_5_14 IOMUX_PAD(0x3DC, 0xB0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT21__GPIO_5_15 IOMUX_PAD(0x3E0, 0xB4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT22__GPIO_5_16 IOMUX_PAD(0x3E4, 0xB8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DISP0_DAT23__GPIO_5_17 IOMUX_PAD(0x3E8, 0xBC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_PIXCLK__GPIO_5_18 IOMUX_PAD(0x3EC, 0xC0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_MCLK__GPIO_5_19 IOMUX_PAD(0x3F0, 0xC4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_DATA_EN__GPIO_5_20 IOMUX_PAD(0x3F4, 0xC8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_VSYNC__GPIO_5_21 IOMUX_PAD(0x3F8, 0xCC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D4__GPIO_5_22 IOMUX_PAD(0x3FC, 0xD0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D5__GPIO_5_23 IOMUX_PAD(0x400, 0xD4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D6__GPIO_5_24 IOMUX_PAD(0x404, 0xD8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D7__GPIO_5_25 IOMUX_PAD(0x408, 0xDC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D8__GPIO_5_26 IOMUX_PAD(0x40C, 0xE0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D9__GPIO_5_27 IOMUX_PAD(0x410, 0xE4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D10__GPIO_5_28 IOMUX_PAD(0x414, 0xE8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D11__GPIO_5_29 IOMUX_PAD(0x418, 0xEC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D12__GPIO_5_30 IOMUX_PAD(0x41C, 0xF0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D13__GPIO_5_31 IOMUX_PAD(0x420, 0xF4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D14__GPIO_6_0 IOMUX_PAD(0x424, 0xF8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D15__GPIO_6_1 IOMUX_PAD(0x428, 0xFC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D16__GPIO_6_2 IOMUX_PAD(0x42C, 0x100,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D17__GPIO_6_3 IOMUX_PAD(0x430, 0x104,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D18__GPIO_6_4 IOMUX_PAD(0x434, 0x108,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_CSI0_D19__GPIO_6_5 IOMUX_PAD(0x438, 0x10C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_CSI0__NVCC_CSI0 IOMUX_PAD(0x43C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_TMS__JTAG_TMS IOMUX_PAD(0x440, NON_MUX_I,IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_MOD__JTAG_MOD IOMUX_PAD(0x444, NON_MUX_I,IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_TRSTB__JTAG_TRSTB IOMUX_PAD(0x448, NON_MUX_I,IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_TDI__JTAG_TDI IOMUX_PAD(0x44C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_TCK__JTAG_TCK IOMUX_PAD(0x450, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_JTAG_TDO__JTAG_TDO IOMUX_PAD(0x454, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A25__GPIO_5_2 IOMUX_PAD(0x458, 0x110,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_EB2__GPIO_2_30 IOMUX_PAD(0x45C, 0x114,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D16__GPIO_3_16 IOMUX_PAD(0x460, 0x118,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D17__GPIO_3_17 IOMUX_PAD(0x464, 0x11C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D18__GPIO_3_18 IOMUX_PAD(0x468, 0x120,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D19__GPIO_3_19 IOMUX_PAD(0x46C, 0x124,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D20__GPIO_3_20 IOMUX_PAD(0x470, 0x128,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D21__GPIO_3_21 IOMUX_PAD(0x474, 0x12C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D22__GPIO_3_22 IOMUX_PAD(0x478, 0x130,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D23__GPIO_3_23 IOMUX_PAD(0x47C, 0x134,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_EB3__GPIO_2_31 IOMUX_PAD(0x480, 0x138,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D24__GPIO_3_24 IOMUX_PAD(0x484, 0x13C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D25__GPIO_3_25 IOMUX_PAD(0x488, 0x140,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D26__GPIO_3_26 IOMUX_PAD(0x48C, 0x144,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D27__GPIO_3_27 IOMUX_PAD(0x490, 0x148,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D28__GPIO_3_28 IOMUX_PAD(0x494, 0x14C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D29__GPIO_3_29 IOMUX_PAD(0x498, 0x150,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D30__GPIO_3_30 IOMUX_PAD(0x49C, 0x154,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_D31__GPIO_3_31 IOMUX_PAD(0x4A0, 0x158,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_EIM1__NVCC_EIM1 IOMUX_PAD(0x4A4, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A24__GPIO_5_4 IOMUX_PAD(0x4A8, 0x15C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A23__GPIO_6_6 IOMUX_PAD(0x4AC, 0x160,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A22__GPIO_2_16 IOMUX_PAD(0x4B0, 0x164,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A21__GPIO_2_17 IOMUX_PAD(0x4B4, 0x168,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A20__GPIO_2_18 IOMUX_PAD(0x4B8, 0x16C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A19__GPIO_2_19 IOMUX_PAD(0x4BC, 0x170,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A18__GPIO_2_20 IOMUX_PAD(0x4C0, 0x174,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A17__GPIO_2_21 IOMUX_PAD(0x4C4, 0x178,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_A16__GPIO_2_22 IOMUX_PAD(0x4C8, 0x17C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_CS0__GPIO_2_23 IOMUX_PAD(0x4CC, 0x180,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_CS1__GPIO_2_24 IOMUX_PAD(0x4D0, 0x184,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_OE__GPIO_2_25 IOMUX_PAD(0x4D4, 0x188,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_RW__GPIO_2_26 IOMUX_PAD(0x4D8, 0x18C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_LBA__GPIO_2_27 IOMUX_PAD(0x4DC, 0x190,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_EIM4__NVCC_EIM4 IOMUX_PAD(0x4E0, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_EB0__GPIO_2_28 IOMUX_PAD(0x4E4, 0x194,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_EB1__GPIO_2_29 IOMUX_PAD(0x4E8, 0x198,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA0__GPIO_3_0 IOMUX_PAD(0x4EC, 0x19C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA1__GPIO_3_1 IOMUX_PAD(0x4F0, 0x1A0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA2__GPIO_3_2 IOMUX_PAD(0x4F4, 0x1A4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA3__GPIO_3_3 IOMUX_PAD(0x4F8, 0x1A8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA4__GPIO_3_4 IOMUX_PAD(0x4FC, 0x1AC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA5__GPIO_3_5 IOMUX_PAD(0x500, 0x1B0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA6__GPIO_3_6 IOMUX_PAD(0x504, 0x1B4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA7__GPIO_3_7 IOMUX_PAD(0x508, 0x1B8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA8__GPIO_3_8 IOMUX_PAD(0x50C, 0x1BC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA9__GPIO_3_9 IOMUX_PAD(0x510, 0x1C0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA10__GPIO_3_10 IOMUX_PAD(0x514, 0x1C4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA11__GPIO_3_11 IOMUX_PAD(0x518, 0x1C8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA12__GPIO_3_12 IOMUX_PAD(0x51C, 0x1CC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA13__GPIO_3_13 IOMUX_PAD(0x520, 0x1D0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA14__GPIO_3_14 IOMUX_PAD(0x524, 0x1D4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_DA15__GPIO_3_15 IOMUX_PAD(0x528, 0x1D8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_WE_B__GPIO_6_12 IOMUX_PAD(0x52C, 0x1DC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_RE_B__GPIO_6_13 IOMUX_PAD(0x530, 0x1E0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_WAIT__GPIO_5_0 IOMUX_PAD(0x534, 0x1E4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_EIM_BCLK__EIM_BCLK IOMUX_PAD(0x538, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_EIM7__NVCC_EIM7 IOMUX_PAD(0x53C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS1_TX3_P__GPIO_6_22 IOMUX_PAD(NON_PAD_I, 0x1EC, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS1_TX2_P__GPIO_6_24 IOMUX_PAD(NON_PAD_I, 0x1F0, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS1_CLK_P__GPIO_6_26 IOMUX_PAD(NON_PAD_I, 0x1F4, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS1_TX1_P__GPIO_6_28 IOMUX_PAD(NON_PAD_I, 0x1F8, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS1_TX0_P__GPIO_6_30 IOMUX_PAD(NON_PAD_I, 0x1FC, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS0_TX3_P__GPIO_7_22 IOMUX_PAD(NON_PAD_I, 0x200, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS0_CLK_P__GPIO_7_24 IOMUX_PAD(NON_PAD_I, 0x204, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS0_TX2_P__GPIO_7_26 IOMUX_PAD(NON_PAD_I, 0x208, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS0_TX1_P__GPIO_7_28 IOMUX_PAD(NON_PAD_I, 0x20C, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_LVDS0_TX0_P__GPIO_7_30 IOMUX_PAD(NON_PAD_I, 0x210, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_10__GPIO_4_0 IOMUX_PAD(0x540, 0x214, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_11__GPIO_4_1 IOMUX_PAD(0x544, 0x218, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_12__GPIO_4_2 IOMUX_PAD(0x548, 0x21C, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_13__GPIO_4_3 IOMUX_PAD(0x54C, 0x220, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_14__GPIO_4_4 IOMUX_PAD(0x550, 0x224, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_DQM3__DRAM_DQM3 IOMUX_PAD(0x554, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDQS3__DRAM_SDQS3 IOMUX_PAD(0x558, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDCKE1__DRAM_SDCKE1 IOMUX_PAD(0x55C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_DQM2__DRAM_DQM2 IOMUX_PAD(0x560, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDODT1__DRAM_SDODT1 IOMUX_PAD(0x564, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDQS2__DRAM_SDQS2 IOMUX_PAD(0x568, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_RESET__DRAM_RESET IOMUX_PAD(0x56C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDCLK1__DRAM_SDCLK1 IOMUX_PAD(0x570, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_CAS__DRAM_CAS IOMUX_PAD(0x574, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDCLK0__DRAM_SDCLK0 IOMUX_PAD(0x578, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDQS0__DRAM_SDQS0 IOMUX_PAD(0x57C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDODT0__DRAM_SDODT0 IOMUX_PAD(0x580, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_DQM0__DRAM_DQM0 IOMUX_PAD(0x584, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_RAS__DRAM_RAS IOMUX_PAD(0x588, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDCKE0__DRAM_SDCKE0 IOMUX_PAD(0x58C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_SDQS1__DRAM_SDQS1 IOMUX_PAD(0x590, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_DRAM_DQM1__DRAM_DQM1 IOMUX_PAD(0x594, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_PMIC_ON_REQ__PMIC_ON_REQ IOMUX_PAD(0x598, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_PMIC_STBY_REQ__PMIC_STBY_REQ IOMUX_PAD(0x59C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_CLE__GPIO_6_7 IOMUX_PAD(0x5A0, 0x228,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_ALE__GPIO_6_8 IOMUX_PAD(0x5A4, 0x22C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_WP_B__GPIO_6_9 IOMUX_PAD(0x5A8, 0x230,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_RB0__GPIO_6_10 IOMUX_PAD(0x5AC, 0x234,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_CS0__GPIO_6_11 IOMUX_PAD(0x5B0, 0x238,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_CS1__GPIO_6_14 IOMUX_PAD(0x5B4, 0x23C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_CS2__GPIO_6_15 IOMUX_PAD(0x5B8, 0x240,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NANDF_CS3__GPIO_6_16 IOMUX_PAD(0x5BC, 0x244,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_NANDF__NVCC_NANDF IOMUX_PAD(0x5C0, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_MDIO__GPIO_1_22 IOMUX_PAD(0x5C4, 0x248,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_REF_CLK__GPIO_1_23 IOMUX_PAD(0x5C8, 0x24C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_RX_ER__GPIO_1_24 IOMUX_PAD(0x5CC, 0x250,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_CRS_DV__GPIO_1_25 IOMUX_PAD(0x5D0, 0x254,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_RXD1__GPIO_1_26 IOMUX_PAD(0x5D4, 0x258,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_RXD0__GPIO_1_27 IOMUX_PAD(0x5D8, 0x25C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_TX_EN__GPIO_1_28 IOMUX_PAD(0x5DC, 0x260,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_TXD1__GPIO_1_29 IOMUX_PAD(0x5E0, 0x264,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_TXD0__GPIO_1_30 IOMUX_PAD(0x5E4, 0x268,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_FEC_MDC__GPIO_1_31 IOMUX_PAD(0x5E8, 0x26C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_FEC__NVCC_FEC IOMUX_PAD(0x5EC, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DIOW__GPIO_6_17 IOMUX_PAD(0x5F0, 0x270,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DMACK__GPIO_6_18 IOMUX_PAD(0x5F4, 0x274,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DMARQ__GPIO_7_0 IOMUX_PAD(0x5F8, 0x278,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_BUFFER_EN__GPIO_7_1 IOMUX_PAD(0x5FC, 0x27C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_INTRQ__GPIO_7_2 IOMUX_PAD(0x600, 0x280,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DIOR__GPIO_7_3 IOMUX_PAD(0x604, 0x284,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_RESET_B__GPIO_7_4 IOMUX_PAD(0x608, 0x288,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_IORDY__GPIO_7_5 IOMUX_PAD(0x60C, 0x28C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DA_0__GPIO_7_6 IOMUX_PAD(0x610, 0x290,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DA_1__GPIO_7_7 IOMUX_PAD(0x614, 0x294,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DA_2__GPIO_7_8 IOMUX_PAD(0x618, 0x298,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_CS_0__GPIO_7_9 IOMUX_PAD(0x61C, 0x29C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_CS_1__GPIO_7_10 IOMUX_PAD(0x620, 0x2A0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_ATA2__NVCC_ATA2 IOMUX_PAD(0x624, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA0__GPIO_2_0 IOMUX_PAD(0x628, 0x2A4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA1__GPIO_2_1 IOMUX_PAD(0x62C, 0x2A8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA2__GPIO_2_2 IOMUX_PAD(0x630, 0x2AC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA3__GPIO_2_3 IOMUX_PAD(0x634, 0x2B0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA4__GPIO_2_4 IOMUX_PAD(0x638, 0x2B4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA5__GPIO_2_5 IOMUX_PAD(0x63C, 0x2B8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA6__GPIO_2_6 IOMUX_PAD(0x640, 0x2BC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA7__GPIO_2_7 IOMUX_PAD(0x644, 0x2C0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA8__GPIO_2_8 IOMUX_PAD(0x648, 0x2C4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA9__GPIO_2_9 IOMUX_PAD(0x64C, 0x2C8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA10__GPIO_2_10 IOMUX_PAD(0x650, 0x2CC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA11__GPIO_2_11 IOMUX_PAD(0x654, 0x2D0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA12__GPIO_2_12 IOMUX_PAD(0x658, 0x2D4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA13__GPIO_2_13 IOMUX_PAD(0x65C, 0x2D8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA14__GPIO_2_14 IOMUX_PAD(0x660, 0x2DC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_ATA_DATA15__GPIO_2_15 IOMUX_PAD(0x664, 0x2E0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_ATA0__NVCC_ATA0 IOMUX_PAD(0x668, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_DATA0__GPIO_1_16 IOMUX_PAD(0x66C, 0x2E4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_DATA1__GPIO_1_17 IOMUX_PAD(0x670, 0x2E8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_CMD__GPIO_1_18 IOMUX_PAD(0x674, 0x2EC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_DATA2__GPIO_1_19 IOMUX_PAD(0x678, 0x2F0,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_CLK__GPIO_1_20 IOMUX_PAD(0x67C, 0x2F4,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD1_DATA3__GPIO_1_21 IOMUX_PAD(0x680, 0x2F8,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_SD1__NVCC_SD1 IOMUX_PAD(0x684, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_CLK__GPIO_1_10 IOMUX_PAD(0x688, 0x2FC,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_CMD__GPIO_1_11 IOMUX_PAD(0x68C, 0x300,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_DATA3__GPIO_1_12 IOMUX_PAD(0x690, 0x304,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_DATA2__GPIO_1_13 IOMUX_PAD(0x694, 0x308,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_DATA1__GPIO_1_14 IOMUX_PAD(0x698, 0x30C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_SD2_DATA0__GPIO_1_15 IOMUX_PAD(0x69C, 0x310,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_SD2__NVCC_SD2 IOMUX_PAD(0x6A0, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_0__GPIO_1_0 IOMUX_PAD(0x6A4, 0x314,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_1__GPIO_1_1 IOMUX_PAD(0x6A8, 0x318,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_9__GPIO_1_9 IOMUX_PAD(0x6AC, 0x31C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_3__GPIO_1_3 IOMUX_PAD(0x6B0, 0x320,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_6__GPIO_1_6 IOMUX_PAD(0x6B4, 0x324,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_2__GPIO_1_2 IOMUX_PAD(0x6B8, 0x328,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_4__GPIO_1_4 IOMUX_PAD(0x6BC, 0x32C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_5__GPIO_1_5 IOMUX_PAD(0x6C0, 0x330,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_7__GPIO_1_7 IOMUX_PAD(0x6C4, 0x334,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_8__GPIO_1_8 IOMUX_PAD(0x6C8, 0x338,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_16__GPIO_7_11 IOMUX_PAD(0x6CC, 0x33C,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_17__GPIO_7_12 IOMUX_PAD(0x6D0, 0x340,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GPIO_18__GPIO_7_13 IOMUX_PAD(0x6D4, 0x344,IOMUX_CONFIG_ALT1, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_NVCC_GPIO__NVCC_GPIO IOMUX_PAD(0x6D8, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_POR_B__POR_B IOMUX_PAD(0x6DC, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(0x6E0, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_RESET_IN_B__RESET_IN_B IOMUX_PAD(0x6E4, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(0x6E8, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_TEST_MODE__TEST_MODE IOMUX_PAD(0x6EC, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_ADDDS__GRP_ADDDS IOMUX_PAD(0x6F0, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDRMODE_CTL__GRP_DDRMODE_CTL IOMUX_PAD(0x6F4, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDRPKE__GRP_DDRPKE IOMUX_PAD(0x6FC, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDRPK__GRP_DDRPK IOMUX_PAD(0x708, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_TERM_CTL3__GRP_TERM_CTL3 IOMUX_PAD(0x70C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDRHYS__GRP_DDRHYS IOMUX_PAD(0x710, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDRMODE__GRP_DDRMODE IOMUX_PAD(0x714, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_B0DS__GRP_B0DS IOMUX_PAD(0x718, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_B1DS__GRP_B1DS IOMUX_PAD(0x71C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_CTLDS__GRP_CTLDS IOMUX_PAD(0x720, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_DDR_TYPE__GRP_DDR_TYPE IOMUX_PAD(0x724, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_B2DS__GRP_B2DS IOMUX_PAD(0x728, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+#define MX53_PAD_GRP_B3DS__GRP_B3DS IOMUX_PAD(0x72C, NON_MUX_I, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX53_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index 0880a4a1aed1..2277b01c855d 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -42,28 +42,44 @@
* If <padname> or <padmode> refers to a GPIO, it is named
* GPIO_<unit>_<num>
*
- */
-
-struct pad_desc {
- unsigned mux_ctrl_ofs:12; /* IOMUXC_SW_MUX_CTL_PAD offset */
- unsigned mux_mode:8;
- unsigned pad_ctrl_ofs:12; /* IOMUXC_SW_PAD_CTRL offset */
-#define NO_PAD_CTRL (1 << 16)
- unsigned pad_ctrl:17;
- unsigned select_input_ofs:12; /* IOMUXC_SELECT_INPUT offset */
- unsigned select_input:3;
-};
-
-#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _select_input_ofs, \
- _select_input, _pad_ctrl) \
- { \
- .mux_ctrl_ofs = _mux_ctrl_ofs, \
- .mux_mode = _mux_mode, \
- .pad_ctrl_ofs = _pad_ctrl_ofs, \
- .pad_ctrl = _pad_ctrl, \
- .select_input_ofs = _select_input_ofs, \
- .select_input = _select_input, \
- }
+ * IOMUX/PAD Bit field definitions
+ *
+ * MUX_CTRL_OFS: 0..11 (12)
+ * PAD_CTRL_OFS: 12..23 (12)
+ * SEL_INPUT_OFS: 24..35 (12)
+ * MUX_MODE + SION: 36..40 (5)
+ * PAD_CTRL + NO_PAD_CTRL: 41..57 (17)
+ * SEL_INP: 58..61 (4)
+ * reserved: 63 (1)
+*/
+
+typedef u64 iomux_v3_cfg_t;
+
+#define MUX_CTRL_OFS_SHIFT 0
+#define MUX_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_CTRL_OFS_SHIFT)
+#define MUX_PAD_CTRL_OFS_SHIFT 12
+#define MUX_PAD_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_PAD_CTRL_OFS_SHIFT)
+#define MUX_SEL_INPUT_OFS_SHIFT 24
+#define MUX_SEL_INPUT_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_SEL_INPUT_OFS_SHIFT)
+
+#define MUX_MODE_SHIFT 36
+#define MUX_MODE_MASK ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT)
+#define MUX_PAD_CTRL_SHIFT 41
+#define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT)
+#define NO_PAD_CTRL ((iomux_v3_cfg_t)1 << (MUX_PAD_CTRL_SHIFT + 16))
+#define MUX_SEL_INPUT_SHIFT 58
+#define MUX_SEL_INPUT_MASK ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT)
+
+#define MUX_PAD_CTRL(x) ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
+
+#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _sel_input_ofs, \
+ _sel_input, _pad_ctrl) \
+ (((iomux_v3_cfg_t)(_mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_mux_mode) << MUX_MODE_SHIFT) | \
+ ((iomux_v3_cfg_t)(_pad_ctrl_ofs) << MUX_PAD_CTRL_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_pad_ctrl) << MUX_PAD_CTRL_SHIFT) | \
+ ((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT))
/*
* Use to set PAD control
@@ -107,13 +123,13 @@ struct pad_desc {
/*
* setups a single pad in the iomuxer
*/
-int mxc_iomux_v3_setup_pad(struct pad_desc *pad);
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
/*
* setups mutliple pads
* convenient way to call the above function with tables
*/
-int mxc_iomux_v3_setup_multiple_pads(struct pad_desc *pad_list, unsigned count);
+int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count);
/*
* Initialise the iomux controller
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 86781f7b0c0c..58a49cc83797 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -23,13 +23,17 @@
#define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
/* these are ordered by size to support multi-SoC kernels */
-#if defined CONFIG_ARCH_MX2
+#if defined CONFIG_ARCH_MX53
+#define MXC_GPIO_IRQS (32 * 7)
+#elif defined CONFIG_ARCH_MX2
+#define MXC_GPIO_IRQS (32 * 6)
+#elif defined CONFIG_ARCH_MX50
#define MXC_GPIO_IRQS (32 * 6)
#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
+#elif defined CONFIG_ARCH_MX51
#define MXC_GPIO_IRQS (32 * 4)
#elif defined CONFIG_ARCH_MXC91231
#define MXC_GPIO_IRQS (32 * 4)
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 564ec9dbc93d..83861408133f 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -16,7 +16,9 @@
#define MX25_PHYS_OFFSET UL(0x80000000)
#define MX27_PHYS_OFFSET UL(0xa0000000)
#define MX3x_PHYS_OFFSET UL(0x80000000)
+#define MX50_PHYS_OFFSET UL(0x70000000)
#define MX51_PHYS_OFFSET UL(0x90000000)
+#define MX53_PHYS_OFFSET UL(0x70000000)
#define MXC91231_PHYS_OFFSET UL(0x90000000)
#if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
@@ -32,8 +34,12 @@
# define PHYS_OFFSET MX3x_PHYS_OFFSET
# elif defined CONFIG_ARCH_MXC91231
# define PHYS_OFFSET MXC91231_PHYS_OFFSET
-# elif defined CONFIG_ARCH_MX5
+# elif defined CONFIG_ARCH_MX50
+# define PHYS_OFFSET MX50_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX51
# define PHYS_OFFSET MX51_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX53
+# define PHYS_OFFSET MX53_PHYS_OFFSET
# endif
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
index 641b24618239..75d96214b831 100644
--- a/arch/arm/plat-mxc/include/mach/mx1.h
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -19,7 +19,6 @@
*/
#define MX1_IO_BASE_ADDR 0x00200000
#define MX1_IO_SIZE SZ_1M
-#define MX1_IO_BASE_ADDR_VIRT VMALLOC_END
#define MX1_CS0_PHYS 0x10000000
#define MX1_CS0_SIZE 0x02000000
@@ -66,6 +65,10 @@
#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_GPIO1_BASE_ADDR (0x1C000 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO2_BASE_ADDR (0x1C100 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO3_BASE_ADDR (0x1C200 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO4_BASE_ADDR (0x1C300 + 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)
@@ -73,12 +76,12 @@
#define MX1_CSI_BASE_ADDR (0x24000 + MX1_IO_BASE_ADDR)
/* macro to get at IO space when running virtually */
-#define MX1_IO_ADDRESS(x) ( \
- IMX_IO_ADDRESS(x, MX1_IO))
+#define MX1_IO_P2V(x) IMX_IO_P2V(x)
+#define MX1_IO_ADDRESS(x) IOMEM(MX1_IO_P2V(x))
/* fixed interrput numbers */
#define MX1_INT_SOFTINT 0
-#define MX1_CSI_INT 6
+#define MX1_INT_CSI 6
#define MX1_DSPA_MAC_INT 7
#define MX1_DSPA_INT 8
#define MX1_COMP_INT 9
@@ -115,13 +118,13 @@
#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_INT_USBD0 47
+#define MX1_INT_USBD1 48
+#define MX1_INT_USBD2 49
+#define MX1_INT_USBD3 50
+#define MX1_INT_USBD4 51
+#define MX1_INT_USBD5 52
+#define MX1_INT_USBD6 53
#define MX1_BTSYS_INT 55
#define MX1_BTTIM_INT 56
#define MX1_BTWUI_INT 57
@@ -164,134 +167,6 @@
* 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_INT_I2C
-#define CSPI_INT MX1_CSPI_INT
-#define SSI_TX_INT MX1_SSI_TX_INT
-#define SSI_TX_ERR_INT MX1_SSI_TX_ERR_INT
-#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 */
+#define USBD_INT0 MX1_INT_USBD0
#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 8bc59720b6e4..6cd049ebbd8d 100644
--- a/arch/arm/plat-mxc/include/mach/mx21.h
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -26,7 +26,6 @@
#define __MACH_MX21_H__
#define MX21_AIPI_BASE_ADDR 0x10000000
-#define MX21_AIPI_BASE_ADDR_VIRT 0xf4000000
#define MX21_AIPI_SIZE SZ_1M
#define MX21_DMA_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x01000)
#define MX21_WDOG_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x02000)
@@ -49,6 +48,12 @@
#define MX21_SDHC1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x13000)
#define MX21_SDHC2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x14000)
#define MX21_GPIO_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x15000)
+#define MX21_GPIO1_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x000)
+#define MX21_GPIO2_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x100)
+#define MX21_GPIO3_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x200)
+#define MX21_GPIO4_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x300)
+#define MX21_GPIO5_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x400)
+#define MX21_GPIO6_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x500)
#define MX21_AUDMUX_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x16000)
#define MX21_CSPI3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x17000)
#define MX21_LCDC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x21000)
@@ -64,7 +69,6 @@
#define MX21_AVIC_BASE_ADDR 0x10040000
#define MX21_SAHB1_BASE_ADDR 0x80000000
-#define MX21_SAHB1_BASE_ADDR_VIRT 0xf4100000
#define MX21_SAHB1_SIZE SZ_1M
#define MX21_CSI_BASE_ADDR (MX2x_SAHB1_BASE_ADDR + 0x0000)
@@ -82,7 +86,6 @@
/* NAND, SDRAM, WEIM etc controllers */
#define MX21_X_MEMC_BASE_ADDR 0xdf000000
-#define MX21_X_MEMC_BASE_ADDR_VIRT 0xf4200000
#define MX21_X_MEMC_SIZE SZ_256K
#define MX21_SDRAMC_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x0000)
@@ -92,10 +95,8 @@
#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))
+#define MX21_IO_P2V(x) IMX_IO_P2V(x)
+#define MX21_IO_ADDRESS(x) IOMEM(MX21_IO_P2V(x))
/* fixed interrupt numbers */
#define MX21_INT_CSPI3 6
@@ -184,39 +185,4 @@
#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
-#define CS0_BASE_ADDR MX21_CS0_BASE_ADDR
-#define CS1_BASE_ADDR MX21_CS1_BASE_ADDR
-#define CS2_BASE_ADDR MX21_CS2_BASE_ADDR
-#define CS3_BASE_ADDR MX21_CS3_BASE_ADDR
-#define CS4_BASE_ADDR MX21_CS4_BASE_ADDR
-#define PCMCIA_MEM_BASE_ADDR MX21_PCMCIA_MEM_BASE_ADDR
-#define CS5_BASE_ADDR MX21_CS5_BASE_ADDR
-#define X_MEMC_BASE_ADDR MX21_X_MEMC_BASE_ADDR
-#define X_MEMC_BASE_ADDR_VIRT MX21_X_MEMC_BASE_ADDR_VIRT
-#define X_MEMC_SIZE MX21_X_MEMC_SIZE
-#define SDRAMC_BASE_ADDR MX21_SDRAMC_BASE_ADDR
-#define EIM_BASE_ADDR MX21_EIM_BASE_ADDR
-#define PCMCIA_CTL_BASE_ADDR MX21_PCMCIA_CTL_BASE_ADDR
-#define NFC_BASE_ADDR MX21_NFC_BASE_ADDR
-#define IRAM_BASE_ADDR MX21_IRAM_BASE_ADDR
-#define MXC_INT_FIRI MX21_INT_FIRI
-#define MXC_INT_BMI MX21_INT_BMI
-#define MXC_INT_EMMAENC MX21_INT_EMMAENC
-#define MXC_INT_EMMADEC MX21_INT_EMMADEC
-#define MXC_INT_USBWKUP MX21_INT_USBWKUP
-#define MXC_INT_USBDMA MX21_INT_USBDMA
-#define MXC_INT_USBHOST MX21_INT_USBHOST
-#define MXC_INT_USBFUNC MX21_INT_USBFUNC
-#define MXC_INT_USBMNP MX21_INT_USBMNP
-#define MXC_INT_USBCTRL MX21_INT_USBCTRL
-#define MXC_INT_USBCTRL MX21_INT_USBCTRL
-#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 /* 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 cf46a45b0d4e..087cd7ac8d52 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -2,13 +2,10 @@
#define __MACH_MX25_H__
#define MX25_AIPS1_BASE_ADDR 0x43f00000
-#define MX25_AIPS1_BASE_ADDR_VIRT 0xfc000000
#define MX25_AIPS1_SIZE SZ_1M
#define MX25_AIPS2_BASE_ADDR 0x53f00000
-#define MX25_AIPS2_BASE_ADDR_VIRT 0xfc200000
#define MX25_AIPS2_SIZE SZ_1M
#define MX25_AVIC_BASE_ADDR 0x68000000
-#define MX25_AVIC_BASE_ADDR_VIRT 0xfc400000
#define MX25_AVIC_SIZE SZ_1M
#define MX25_I2C1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x80000)
@@ -21,20 +18,15 @@
#define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
#define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000)
+#define MX25_GPIO4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x9c000)
+#define MX25_PWM2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa0000)
+#define MX25_GPIO3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa4000)
+#define MX25_PWM3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa8000)
+#define MX25_PWM4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xc8000)
+#define MX25_GPIO1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xcc000)
+#define MX25_GPIO2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xd0000)
#define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000)
-
-#define MX25_GPIO1_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xcc000)
-#define MX25_GPIO2_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xd0000)
-#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_IO_ADDRESS(x) ( \
- IMX_IO_ADDRESS(x, MX25_AIPS1) ?: \
- IMX_IO_ADDRESS(x, MX25_AIPS2) ?: \
- IMX_IO_ADDRESS(x, MX25_AVIC))
-
-#define MX25_AIPS1_IO_ADDRESS(x) \
- (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
+#define MX25_PWM1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xe0000)
#define MX25_UART1_BASE_ADDR 0x43f90000
#define MX25_UART2_BASE_ADDR 0x43f94000
@@ -55,9 +47,19 @@
#define MX25_LCDC_BASE_ADDR 0x53fbc000
#define MX25_KPP_BASE_ADDR 0x43fa8000
#define MX25_SDMA_BASE_ADDR 0x53fd4000
-#define MX25_OTG_BASE_ADDR 0x53ff4000
+#define MX25_USB_BASE_ADDR 0x53ff4000
+#define MX25_USB_OTG_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0000)
+/*
+ * The reference manual (IMX25RM, Rev. 1, 06/2009) specifies an offset of 0x200
+ * for the host controller. Early documentation drafts specified 0x400 and
+ * Freescale internal sources confirm only the latter value to work.
+ */
+#define MX25_USB_HS_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0400)
#define MX25_CSI_BASE_ADDR 0x53ff8000
+#define MX25_IO_P2V(x) IMX_IO_P2V(x)
+#define MX25_IO_ADDRESS(x) IOMEM(MX25_IO_P2V(x))
+
#define MX25_INT_CSPI3 0
#define MX25_INT_I2C1 3
#define MX25_INT_I2C2 4
@@ -69,18 +71,28 @@
#define MX25_INT_SSI1 12
#define MX25_INT_CSPI2 13
#define MX25_INT_CSPI1 14
+#define MX25_INT_GPIO3 16
#define MX25_INT_CSI 17
#define MX25_INT_UART3 18
+#define MX25_INT_GPIO4 23
#define MX25_INT_KPP 24
#define MX25_INT_DRYICE 25
+#define MX25_INT_PWM1 26
#define MX25_INT_UART2 32
#define MX25_INT_NFC 33
#define MX25_INT_SDMA 34
+#define MX25_INT_USB_HS 35
+#define MX25_INT_PWM2 36
+#define MX25_INT_USB_OTG 37
#define MX25_INT_LCDC 39
#define MX25_INT_UART5 40
+#define MX25_INT_PWM3 41
+#define MX25_INT_PWM4 42
#define MX25_INT_CAN1 43
#define MX25_INT_CAN2 44
#define MX25_INT_UART1 45
+#define MX25_INT_GPIO2 51
+#define MX25_INT_GPIO1 52
#define MX25_INT_FEC 57
#define MX25_DMA_REQ_SSI2_RX1 22
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index 2237ba2e5351..cbc43ad5ef48 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -29,7 +29,6 @@
#endif
#define MX27_AIPI_BASE_ADDR 0x10000000
-#define MX27_AIPI_BASE_ADDR_VIRT 0xf4000000
#define MX27_AIPI_SIZE SZ_1M
#define MX27_DMA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x01000)
#define MX27_WDOG_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x02000)
@@ -52,6 +51,12 @@
#define MX27_SDHC1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x13000)
#define MX27_SDHC2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x14000)
#define MX27_GPIO_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x15000)
+#define MX27_GPIO1_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x000)
+#define MX27_GPIO2_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x100)
+#define MX27_GPIO3_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x200)
+#define MX27_GPIO4_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x300)
+#define MX27_GPIO5_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x400)
+#define MX27_GPIO6_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x500)
#define MX27_AUDMUX_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x16000)
#define MX27_CSPI3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x17000)
#define MX27_MSHC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x18000)
@@ -65,11 +70,13 @@
#define MX27_LCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x21000)
#define MX27_SLCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x22000)
#define MX27_VPU_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x23000)
-#define MX27_USBOTG_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x24000)
-#define MX27_OTG_BASE_ADDR MX27_USBOTG_BASE_ADDR
+#define MX27_USB_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x24000)
+#define MX27_USB_OTG_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0000)
+#define MX27_USB_HS1_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0200)
+#define MX27_USB_HS2_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0400)
#define MX27_SAHARA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x25000)
-#define MX27_EMMA_PP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26000)
-#define MX27_EMMA_PRP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26400)
+#define MX27_EMMAPP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26000)
+#define MX27_EMMAPRP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26400)
#define MX27_CCM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27000)
#define MX27_SYSCTRL_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27800)
#define MX27_IIM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x28000)
@@ -87,7 +94,6 @@
#define MX27_ROMP_BASE_ADDR 0x10041000
#define MX27_SAHB1_BASE_ADDR 0x80000000
-#define MX27_SAHB1_BASE_ADDR_VIRT 0xf4100000
#define MX27_SAHB1_SIZE SZ_1M
#define MX27_CSI_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x0000)
#define MX27_ATA_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x1000)
@@ -105,7 +111,6 @@
/* NAND, SDRAM, WEIM, M3IF, EMI controllers */
#define MX27_X_MEMC_BASE_ADDR 0xd8000000
-#define MX27_X_MEMC_BASE_ADDR_VIRT 0xf4200000
#define MX27_X_MEMC_SIZE SZ_1M
#define MX27_NFC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR)
#define MX27_SDRAMC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x1000)
@@ -123,10 +128,8 @@
/* 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))
+#define MX27_IO_P2V(x) IMX_IO_P2V(x)
+#define MX27_IO_ADDRESS(x) IOMEM(MX27_IO_P2V(x))
#ifndef __ASSEMBLER__
static inline void mx27_setup_weimcs(size_t cs,
@@ -192,9 +195,9 @@ static inline void mx27_setup_weimcs(size_t cs,
#define MX27_INT_EMMAPRP 51
#define MX27_INT_EMMAPP 52
#define MX27_INT_VPU 53
-#define MX27_INT_USB1 54
-#define MX27_INT_USB2 55
-#define MX27_INT_USB3 56
+#define MX27_INT_USB_HS1 54
+#define MX27_INT_USB_HS2 55
+#define MX27_INT_USB_OTG 56
#define MX27_INT_SCC_SMN 57
#define MX27_INT_SCC_SCM 58
#define MX27_INT_SAHARA 59
@@ -241,82 +244,8 @@ static inline void mx27_setup_weimcs(size_t cs,
#define MX27_DMA_REQ_SDHC3 36
#define MX27_DMA_REQ_NFC 37
-/* silicon revisions specific to i.MX27 */
-#define CHIP_REV_1_0 0x00
-#define CHIP_REV_2_0 0x01
-
#ifndef __ASSEMBLY__
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
-#define GPT4_BASE_ADDR MX27_GPT4_BASE_ADDR
-#define UART5_BASE_ADDR MX27_UART5_BASE_ADDR
-#define UART6_BASE_ADDR MX27_UART6_BASE_ADDR
-#define I2C2_BASE_ADDR MX27_I2C2_BASE_ADDR
-#define SDHC3_BASE_ADDR MX27_SDHC3_BASE_ADDR
-#define GPT6_BASE_ADDR MX27_GPT6_BASE_ADDR
-#define VPU_BASE_ADDR MX27_VPU_BASE_ADDR
-#define OTG_BASE_ADDR MX27_OTG_BASE_ADDR
-#define SAHARA_BASE_ADDR MX27_SAHARA_BASE_ADDR
-#define IIM_BASE_ADDR MX27_IIM_BASE_ADDR
-#define RTIC_BASE_ADDR MX27_RTIC_BASE_ADDR
-#define FEC_BASE_ADDR MX27_FEC_BASE_ADDR
-#define SCC_BASE_ADDR MX27_SCC_BASE_ADDR
-#define ETB_BASE_ADDR MX27_ETB_BASE_ADDR
-#define ETB_RAM_BASE_ADDR MX27_ETB_RAM_BASE_ADDR
-#define ROMP_BASE_ADDR MX27_ROMP_BASE_ADDR
-#define ATA_BASE_ADDR MX27_ATA_BASE_ADDR
-#define SDRAM_BASE_ADDR MX27_SDRAM_BASE_ADDR
-#define CSD1_BASE_ADDR MX27_CSD1_BASE_ADDR
-#define CS0_BASE_ADDR MX27_CS0_BASE_ADDR
-#define CS1_BASE_ADDR MX27_CS1_BASE_ADDR
-#define CS2_BASE_ADDR MX27_CS2_BASE_ADDR
-#define CS3_BASE_ADDR MX27_CS3_BASE_ADDR
-#define CS4_BASE_ADDR MX27_CS4_BASE_ADDR
-#define CS5_BASE_ADDR MX27_CS5_BASE_ADDR
-#define X_MEMC_BASE_ADDR MX27_X_MEMC_BASE_ADDR
-#define X_MEMC_BASE_ADDR_VIRT MX27_X_MEMC_BASE_ADDR_VIRT
-#define X_MEMC_SIZE MX27_X_MEMC_SIZE
-#define NFC_BASE_ADDR MX27_NFC_BASE_ADDR
-#define SDRAMC_BASE_ADDR MX27_SDRAMC_BASE_ADDR
-#define WEIM_BASE_ADDR MX27_WEIM_BASE_ADDR
-#define M3IF_BASE_ADDR MX27_M3IF_BASE_ADDR
-#define PCMCIA_CTL_BASE_ADDR MX27_PCMCIA_CTL_BASE_ADDR
-#define PCMCIA_MEM_BASE_ADDR MX27_PCMCIA_MEM_BASE_ADDR
-#define IRAM_BASE_ADDR MX27_IRAM_BASE_ADDR
-#define MXC_INT_I2C2 MX27_INT_I2C2
-#define MXC_INT_GPT6 MX27_INT_GPT6
-#define MXC_INT_GPT5 MX27_INT_GPT5
-#define MXC_INT_GPT4 MX27_INT_GPT4
-#define MXC_INT_RTIC MX27_INT_RTIC
-#define MXC_INT_SDHC MX27_INT_SDHC
-#define MXC_INT_SDHC3 MX27_INT_SDHC3
-#define MXC_INT_ATA MX27_INT_ATA
-#define MXC_INT_UART6 MX27_INT_UART6
-#define MXC_INT_UART5 MX27_INT_UART5
-#define MXC_INT_FEC MX27_INT_FEC
-#define MXC_INT_VPU MX27_INT_VPU
-#define MXC_INT_USB1 MX27_INT_USB1
-#define MXC_INT_USB2 MX27_INT_USB2
-#define MXC_INT_USB3 MX27_INT_USB3
-#define MXC_INT_SCC_SMN MX27_INT_SCC_SMN
-#define MXC_INT_SCC_SCM MX27_INT_SCC_SCM
-#define MXC_INT_SAHARA MX27_INT_SAHARA
-#define MXC_INT_IIM MX27_INT_IIM
-#define MXC_INT_CCM MX27_INT_CCM
-#define DMA_REQ_MSHC MX27_DMA_REQ_MSHC
-#define DMA_REQ_ATA_TX MX27_DMA_REQ_ATA_TX
-#define DMA_REQ_ATA_RCV MX27_DMA_REQ_ATA_RCV
-#define DMA_REQ_UART5_TX MX27_DMA_REQ_UART5_TX
-#define DMA_REQ_UART5_RX MX27_DMA_REQ_UART5_RX
-#define DMA_REQ_UART6_TX MX27_DMA_REQ_UART6_TX
-#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 /* 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 afb895a0b5b8..6d07839fdec2 100644
--- a/arch/arm/plat-mxc/include/mach/mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -27,7 +27,6 @@
/* Register offsets */
#define MX2x_AIPI_BASE_ADDR 0x10000000
-#define MX2x_AIPI_BASE_ADDR_VIRT 0xf4000000
#define MX2x_AIPI_SIZE SZ_1M
#define MX2x_DMA_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x01000)
#define MX2x_WDOG_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x02000)
@@ -65,43 +64,9 @@
#define MX2x_AVIC_BASE_ADDR 0x10040000
#define MX2x_SAHB1_BASE_ADDR 0x80000000
-#define MX2x_SAHB1_BASE_ADDR_VIRT 0xf4100000
#define MX2x_SAHB1_SIZE SZ_1M
#define MX2x_CSI_BASE_ADDR (MX2x_SAHB1_BASE_ADDR + 0x0000)
-/*
- * 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 IO_ADDRESS(x) \
- (void __force __iomem *) \
- (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
- AIPI_IO_ADDRESS(x) : \
- ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
- SAHB1_IO_ADDRESS(x) : \
- ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \
- X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF)
-
-/* define the address mapping macros: in physical address order */
-#define AIPI_IO_ADDRESS(x) \
- (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x)
-
-#define SAHB1_IO_ADDRESS(x) \
- (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x) \
- (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
-#define PCMCIA_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
/* fixed interrupt numbers */
#define MX2x_INT_CSPI3 6
#define MX2x_INT_GPIO 8
@@ -176,118 +141,4 @@
#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
-#define AIPI_SIZE MX2x_AIPI_SIZE
-#define DMA_BASE_ADDR MX2x_DMA_BASE_ADDR
-#define WDOG_BASE_ADDR MX2x_WDOG_BASE_ADDR
-#define GPT1_BASE_ADDR MX2x_GPT1_BASE_ADDR
-#define GPT2_BASE_ADDR MX2x_GPT2_BASE_ADDR
-#define GPT3_BASE_ADDR MX2x_GPT3_BASE_ADDR
-#define PWM_BASE_ADDR MX2x_PWM_BASE_ADDR
-#define RTC_BASE_ADDR MX2x_RTC_BASE_ADDR
-#define KPP_BASE_ADDR MX2x_KPP_BASE_ADDR
-#define OWIRE_BASE_ADDR MX2x_OWIRE_BASE_ADDR
-#define UART1_BASE_ADDR MX2x_UART1_BASE_ADDR
-#define UART2_BASE_ADDR MX2x_UART2_BASE_ADDR
-#define UART3_BASE_ADDR MX2x_UART3_BASE_ADDR
-#define UART4_BASE_ADDR MX2x_UART4_BASE_ADDR
-#define CSPI1_BASE_ADDR MX2x_CSPI1_BASE_ADDR
-#define CSPI2_BASE_ADDR MX2x_CSPI2_BASE_ADDR
-#define SSI1_BASE_ADDR MX2x_SSI1_BASE_ADDR
-#define SSI2_BASE_ADDR MX2x_SSI2_BASE_ADDR
-#define I2C_BASE_ADDR MX2x_I2C_BASE_ADDR
-#define SDHC1_BASE_ADDR MX2x_SDHC1_BASE_ADDR
-#define SDHC2_BASE_ADDR MX2x_SDHC2_BASE_ADDR
-#define GPIO_BASE_ADDR MX2x_GPIO_BASE_ADDR
-#define AUDMUX_BASE_ADDR MX2x_AUDMUX_BASE_ADDR
-#define CSPI3_BASE_ADDR MX2x_CSPI3_BASE_ADDR
-#define LCDC_BASE_ADDR MX2x_LCDC_BASE_ADDR
-#define SLCDC_BASE_ADDR MX2x_SLCDC_BASE_ADDR
-#define USBOTG_BASE_ADDR MX2x_USBOTG_BASE_ADDR
-#define EMMA_PP_BASE_ADDR MX2x_EMMA_PP_BASE_ADDR
-#define EMMA_PRP_BASE_ADDR MX2x_EMMA_PRP_BASE_ADDR
-#define CCM_BASE_ADDR MX2x_CCM_BASE_ADDR
-#define SYSCTRL_BASE_ADDR MX2x_SYSCTRL_BASE_ADDR
-#define JAM_BASE_ADDR MX2x_JAM_BASE_ADDR
-#define MAX_BASE_ADDR MX2x_MAX_BASE_ADDR
-#define AVIC_BASE_ADDR MX2x_AVIC_BASE_ADDR
-#define SAHB1_BASE_ADDR MX2x_SAHB1_BASE_ADDR
-#define SAHB1_BASE_ADDR_VIRT MX2x_SAHB1_BASE_ADDR_VIRT
-#define SAHB1_SIZE MX2x_SAHB1_SIZE
-#define CSI_BASE_ADDR MX2x_CSI_BASE_ADDR
-#define MXC_INT_CSPI3 MX2x_INT_CSPI3
-#define MXC_INT_GPIO MX2x_INT_GPIO
-#define MXC_INT_SDHC2 MX2x_INT_SDHC2
-#define MXC_INT_SDHC1 MX2x_INT_SDHC1
-#define MXC_INT_I2C MX2x_INT_I2C
-#define MXC_INT_SSI2 MX2x_INT_SSI2
-#define MXC_INT_SSI1 MX2x_INT_SSI1
-#define MXC_INT_CSPI2 MX2x_INT_CSPI2
-#define MXC_INT_CSPI1 MX2x_INT_CSPI1
-#define MXC_INT_UART4 MX2x_INT_UART4
-#define MXC_INT_UART3 MX2x_INT_UART3
-#define MXC_INT_UART2 MX2x_INT_UART2
-#define MXC_INT_UART1 MX2x_INT_UART1
-#define MXC_INT_KPP MX2x_INT_KPP
-#define MXC_INT_RTC MX2x_INT_RTC
-#define MXC_INT_PWM MX2x_INT_PWM
-#define MXC_INT_GPT3 MX2x_INT_GPT3
-#define MXC_INT_GPT2 MX2x_INT_GPT2
-#define MXC_INT_GPT1 MX2x_INT_GPT1
-#define MXC_INT_WDOG MX2x_INT_WDOG
-#define MXC_INT_PCMCIA MX2x_INT_PCMCIA
-#define MXC_INT_NANDFC MX2x_INT_NANDFC
-#define MXC_INT_CSI MX2x_INT_CSI
-#define MXC_INT_DMACH0 MX2x_INT_DMACH0
-#define MXC_INT_DMACH1 MX2x_INT_DMACH1
-#define MXC_INT_DMACH2 MX2x_INT_DMACH2
-#define MXC_INT_DMACH3 MX2x_INT_DMACH3
-#define MXC_INT_DMACH4 MX2x_INT_DMACH4
-#define MXC_INT_DMACH5 MX2x_INT_DMACH5
-#define MXC_INT_DMACH6 MX2x_INT_DMACH6
-#define MXC_INT_DMACH7 MX2x_INT_DMACH7
-#define MXC_INT_DMACH8 MX2x_INT_DMACH8
-#define MXC_INT_DMACH9 MX2x_INT_DMACH9
-#define MXC_INT_DMACH10 MX2x_INT_DMACH10
-#define MXC_INT_DMACH11 MX2x_INT_DMACH11
-#define MXC_INT_DMACH12 MX2x_INT_DMACH12
-#define MXC_INT_DMACH13 MX2x_INT_DMACH13
-#define MXC_INT_DMACH14 MX2x_INT_DMACH14
-#define MXC_INT_DMACH15 MX2x_INT_DMACH15
-#define MXC_INT_EMMAPRP MX2x_INT_EMMAPRP
-#define MXC_INT_EMMAPP MX2x_INT_EMMAPP
-#define MXC_INT_SLCDC MX2x_INT_SLCDC
-#define MXC_INT_LCDC MX2x_INT_LCDC
-#define DMA_REQ_CSPI3_RX MX2x_DMA_REQ_CSPI3_RX
-#define DMA_REQ_CSPI3_TX MX2x_DMA_REQ_CSPI3_TX
-#define DMA_REQ_EXT MX2x_DMA_REQ_EXT
-#define DMA_REQ_SDHC2 MX2x_DMA_REQ_SDHC2
-#define DMA_REQ_SDHC1 MX2x_DMA_REQ_SDHC1
-#define DMA_REQ_SSI2_RX0 MX2x_DMA_REQ_SSI2_RX0
-#define DMA_REQ_SSI2_TX0 MX2x_DMA_REQ_SSI2_TX0
-#define DMA_REQ_SSI2_RX1 MX2x_DMA_REQ_SSI2_RX1
-#define DMA_REQ_SSI2_TX1 MX2x_DMA_REQ_SSI2_TX1
-#define DMA_REQ_SSI1_RX0 MX2x_DMA_REQ_SSI1_RX0
-#define DMA_REQ_SSI1_TX0 MX2x_DMA_REQ_SSI1_TX0
-#define DMA_REQ_SSI1_RX1 MX2x_DMA_REQ_SSI1_RX1
-#define DMA_REQ_SSI1_TX1 MX2x_DMA_REQ_SSI1_TX1
-#define DMA_REQ_CSPI2_RX MX2x_DMA_REQ_CSPI2_RX
-#define DMA_REQ_CSPI2_TX MX2x_DMA_REQ_CSPI2_TX
-#define DMA_REQ_CSPI1_RX MX2x_DMA_REQ_CSPI1_RX
-#define DMA_REQ_CSPI1_TX MX2x_DMA_REQ_CSPI1_TX
-#define DMA_REQ_UART4_RX MX2x_DMA_REQ_UART4_RX
-#define DMA_REQ_UART4_TX MX2x_DMA_REQ_UART4_TX
-#define DMA_REQ_UART3_RX MX2x_DMA_REQ_UART3_RX
-#define DMA_REQ_UART3_TX MX2x_DMA_REQ_UART3_TX
-#define DMA_REQ_UART2_RX MX2x_DMA_REQ_UART2_RX
-#define DMA_REQ_UART2_TX MX2x_DMA_REQ_UART2_TX
-#define DMA_REQ_UART1_RX MX2x_DMA_REQ_UART1_RX
-#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 /* 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 61cfe827498b..79e7fc01bb59 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -15,7 +15,6 @@
#define MX31_L2CC_SIZE SZ_1M
#define MX31_AIPS1_BASE_ADDR 0x43f00000
-#define MX31_AIPS1_BASE_ADDR_VIRT 0xfc000000
#define MX31_AIPS1_SIZE SZ_1M
#define MX31_MAX_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x04000)
#define MX31_EVTMON_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x08000)
@@ -25,7 +24,10 @@
#define MX31_ECT_CTIO_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x18000)
#define MX31_I2C1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x80000)
#define MX31_I2C3_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x84000)
-#define MX31_OTG_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000)
+#define MX31_USB_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000)
+#define MX31_USB_OTG_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0000)
+#define MX31_USB_HS1_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0200)
+#define MX31_USB_HS2_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0400)
#define MX31_ATA_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x8c000)
#define MX31_UART1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x90000)
#define MX31_UART2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x94000)
@@ -41,10 +43,9 @@
#define MX31_ECT_IP2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xbc000)
#define MX31_SPBA0_BASE_ADDR 0x50000000
-#define MX31_SPBA0_BASE_ADDR_VIRT 0xfc100000
#define MX31_SPBA0_SIZE SZ_1M
-#define MX31_MMC_SDHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x04000)
-#define MX31_MMC_SDHC2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x08000)
+#define MX31_SDHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x04000)
+#define MX31_SDHC2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x08000)
#define MX31_UART3_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x0c000)
#define MX31_CSPI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x10000)
#define MX31_SSI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x14000)
@@ -55,7 +56,6 @@
#define MX31_SPBA_CTRL_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x3c000)
#define MX31_AIPS2_BASE_ADDR 0x53f00000
-#define MX31_AIPS2_BASE_ADDR_VIRT 0xfc200000
#define MX31_AIPS2_SIZE SZ_1M
#define MX31_CCM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x80000)
#define MX31_CSPI3_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x84000)
@@ -84,7 +84,6 @@
#define MX31_ROMP_SIZE SZ_1M
#define MX31_AVIC_BASE_ADDR 0x68000000
-#define MX31_AVIC_BASE_ADDR_VIRT 0xfc400000
#define MX31_AVIC_SIZE SZ_1M
#define MX31_IPU_MEM_BASE_ADDR 0x70000000
@@ -97,15 +96,14 @@
#define MX31_CS3_BASE_ADDR 0xb2000000
#define MX31_CS4_BASE_ADDR 0xb4000000
-#define MX31_CS4_BASE_ADDR_VIRT 0xf4000000
+#define MX31_CS4_BASE_ADDR_VIRT 0xf6000000
#define MX31_CS4_SIZE SZ_32M
#define MX31_CS5_BASE_ADDR 0xb6000000
-#define MX31_CS5_BASE_ADDR_VIRT 0xf6000000
+#define MX31_CS5_BASE_ADDR_VIRT 0xf8000000
#define MX31_CS5_SIZE SZ_32M
#define MX31_X_MEMC_BASE_ADDR 0xb8000000
-#define MX31_X_MEMC_BASE_ADDR_VIRT 0xfc320000
#define MX31_X_MEMC_SIZE SZ_64K
#define MX31_NFC_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x0000)
#define MX31_ESDCTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x1000)
@@ -121,12 +119,8 @@
#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))
+#define MX31_IO_P2V(x) IMX_IO_P2V(x)
+#define MX31_IO_ADDRESS(x) IOMEM(MX31_IO_P2V(x))
#ifndef __ASSEMBLER__
static inline void mx31_setup_weimcs(size_t cs,
@@ -143,8 +137,8 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_MPEG4_ENCODER 5
#define MX31_INT_RTIC 6
#define MX31_INT_FIRI 7
-#define MX31_INT_MMC_SDHC2 8
-#define MX31_INT_MMC_SDHC1 9
+#define MX31_INT_SDHC2 8
+#define MX31_INT_SDHC1 9
#define MX31_INT_I2C1 10
#define MX31_INT_SSI2 11
#define MX31_INT_SSI1 12
@@ -170,10 +164,9 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_UART2 32
#define MX31_INT_NFC 33
#define MX31_INT_SDMA 34
-#define MX31_INT_USB1 35
-#define MX31_INT_USB2 36
-#define MX31_INT_USB3 37
-#define MX31_INT_USB4 38
+#define MX31_INT_USB_HS1 35
+#define MX31_INT_USB_HS2 36
+#define MX31_INT_USB_OTG 37
#define MX31_INT_MSHC1 39
#define MX31_INT_MSHC2 40
#define MX31_INT_IPU_ERR 41
@@ -197,6 +190,8 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_EXT_WDOG 62
#define MX31_INT_EXT_TV 63
+#define MX31_DMA_REQ_SDHC1 20
+#define MX31_DMA_REQ_SDHC2 21
#define MX31_DMA_REQ_SSI2_RX1 22
#define MX31_DMA_REQ_SSI2_TX1 23
#define MX31_DMA_REQ_SSI2_RX0 24
@@ -208,52 +203,4 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 */
-#define MX31_CHIP_REV_1_0 0x10
-#define MX31_CHIP_REV_1_1 0x11
-#define MX31_CHIP_REV_1_2 0x12
-#define MX31_CHIP_REV_1_3 0x13
-#define MX31_CHIP_REV_2_0 0x20
-#define MX31_CHIP_REV_2_1 0x21
-#define MX31_CHIP_REV_2_2 0x22
-#define MX31_CHIP_REV_2_3 0x23
-#define MX31_CHIP_REV_3_0 0x30
-#define MX31_CHIP_REV_3_1 0x31
-#define MX31_CHIP_REV_3_2 0x32
-
-#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
-#define UART5_BASE_ADDR MX31_UART5_BASE_ADDR
-#define MMC_SDHC1_BASE_ADDR MX31_MMC_SDHC1_BASE_ADDR
-#define MMC_SDHC2_BASE_ADDR MX31_MMC_SDHC2_BASE_ADDR
-#define SIM1_BASE_ADDR MX31_SIM1_BASE_ADDR
-#define IIM_BASE_ADDR MX31_IIM_BASE_ADDR
-#define CSPI3_BASE_ADDR MX31_CSPI3_BASE_ADDR
-#define FIRI_BASE_ADDR MX31_FIRI_BASE_ADDR
-#define SCM_BASE_ADDR MX31_SCM_BASE_ADDR
-#define SMN_BASE_ADDR MX31_SMN_BASE_ADDR
-#define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR
-#define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER
-#define MXC_INT_FIRI MX31_INT_FIRI
-#define MXC_INT_MBX MX31_INT_MBX
-#define MXC_INT_CSPI3 MX31_INT_CSPI3
-#define MXC_INT_SIM2 MX31_INT_SIM2
-#define MXC_INT_SIM1 MX31_INT_SIM1
-#define MXC_INT_CCM_DVFS MX31_INT_CCM_DVFS
-#define MXC_INT_USB1 MX31_INT_USB1
-#define MXC_INT_USB2 MX31_INT_USB2
-#define MXC_INT_USB3 MX31_INT_USB3
-#define MXC_INT_USB4 MX31_INT_USB4
-#define MXC_INT_MSHC2 MX31_INT_MSHC2
-#define MXC_INT_UART4 MX31_INT_UART4
-#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 6267cff6035d..d13dbfeef08a 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -11,7 +11,6 @@
#define MX35_L2CC_SIZE SZ_1M
#define MX35_AIPS1_BASE_ADDR 0x43f00000
-#define MX35_AIPS1_BASE_ADDR_VIRT 0xfc000000
#define MX35_AIPS1_SIZE SZ_1M
#define MX35_MAX_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x04000)
#define MX35_EVTMON_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x08000)
@@ -33,7 +32,6 @@
#define MX35_ECT_IP2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xbc000)
#define MX35_SPBA0_BASE_ADDR 0x50000000
-#define MX35_SPBA0_BASE_ADDR_VIRT 0xfc100000
#define MX35_SPBA0_SIZE SZ_1M
#define MX35_UART3_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x0c000)
#define MX35_CSPI2_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x10000)
@@ -44,7 +42,6 @@
#define MX35_SPBA_CTRL_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x3c000)
#define MX35_AIPS2_BASE_ADDR 0x53f00000
-#define MX35_AIPS2_BASE_ADDR_VIRT 0xfc200000
#define MX35_AIPS2_SIZE SZ_1M
#define MX35_CCM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x80000)
#define MX35_GPT1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x90000)
@@ -68,15 +65,19 @@
#define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000)
#define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000)
#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000)
-
-#define MX35_OTG_BASE_ADDR 0x53ff4000
+#define MX35_USB_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf4000)
+#define MX35_USB_OTG_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0000)
+/*
+ * The Reference Manual (IMX35RM, Rev. 2, 3/2009) claims an offset of 0x200 for
+ * HS. When host support was implemented only a preliminary document was
+ * available, which told 0x400. This works fine.
+ */
+#define MX35_USB_HS_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0400)
#define MX35_ROMP_BASE_ADDR 0x60000000
-#define MX35_ROMP_BASE_ADDR_VIRT 0xfc500000
#define MX35_ROMP_SIZE SZ_1M
#define MX35_AVIC_BASE_ADDR 0x68000000
-#define MX35_AVIC_BASE_ADDR_VIRT 0xfc400000
#define MX35_AVIC_SIZE SZ_1M
/*
@@ -92,18 +93,17 @@
#define MX35_CS3_BASE_ADDR 0xb2000000
#define MX35_CS4_BASE_ADDR 0xb4000000
-#define MX35_CS4_BASE_ADDR_VIRT 0xf4000000
+#define MX35_CS4_BASE_ADDR_VIRT 0xf6000000
#define MX35_CS4_SIZE SZ_32M
#define MX35_CS5_BASE_ADDR 0xb6000000
-#define MX35_CS5_BASE_ADDR_VIRT 0xf6000000
+#define MX35_CS5_BASE_ADDR_VIRT 0xf8000000
#define MX35_CS5_SIZE SZ_32M
/*
* NAND, SDRAM, WEIM, M3IF, EMI controllers
*/
#define MX35_X_MEMC_BASE_ADDR 0xb8000000
-#define MX35_X_MEMC_BASE_ADDR_VIRT 0xfc320000
#define MX35_X_MEMC_SIZE SZ_64K
#define MX35_ESDCTL_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x1000)
#define MX35_WEIM_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x2000)
@@ -114,12 +114,8 @@
#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))
+#define MX35_IO_P2V(x) IMX_IO_P2V(x)
+#define MX35_IO_ADDRESS(x) IOMEM(MX35_IO_P2V(x))
/*
* Interrupt numbers
@@ -153,8 +149,8 @@
#define MX35_INT_UART2 32
#define MX35_INT_NFC 33
#define MX35_INT_SDMA 34
-#define MX35_INT_USBHS 35
-#define MX35_INT_USBOTG 37
+#define MX35_INT_USB_HS 35
+#define MX35_INT_USB_OTG 37
#define MX35_INT_MSHC1 39
#define MX35_INT_ESAI 40
#define MX35_INT_IPU_ERR 41
@@ -190,23 +186,4 @@
#define MX35_PROD_SIGNATURE 0x1 /* For MX31 */
-#define MX35_SYSTEM_REV_MIN MX3x_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
-#define MXC_INT_GPU2D MX35_INT_GPU2D
-#define MXC_INT_ASRC MX35_INT_ASRC
-#define MXC_INT_USBHS MX35_INT_USBHS
-#define MXC_INT_USBOTG MX35_INT_USBOTG
-#define MXC_INT_ESAI MX35_INT_ESAI
-#define MXC_INT_CAN1 MX35_INT_CAN1
-#define MXC_INT_CAN2 MX35_INT_CAN2
-#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 d1bd26d7b8a6..388a407d72d6 100644
--- a/arch/arm/plat-mxc/include/mach/mx3x.h
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -44,7 +44,6 @@
* AIPS 1
*/
#define MX3x_AIPS1_BASE_ADDR 0x43f00000
-#define MX3x_AIPS1_BASE_ADDR_VIRT 0xfc000000
#define MX3x_AIPS1_SIZE SZ_1M
#define MX3x_MAX_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x04000)
#define MX3x_EVTMON_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x08000)
@@ -69,7 +68,6 @@
* SPBA global module enabled #0
*/
#define MX3x_SPBA0_BASE_ADDR 0x50000000
-#define MX3x_SPBA0_BASE_ADDR_VIRT 0xfc100000
#define MX3x_SPBA0_SIZE SZ_1M
#define MX3x_UART3_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x0c000)
#define MX3x_CSPI2_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x10000)
@@ -82,7 +80,6 @@
* AIPS 2
*/
#define MX3x_AIPS2_BASE_ADDR 0x53f00000
-#define MX3x_AIPS2_BASE_ADDR_VIRT 0xfc200000
#define MX3x_AIPS2_SIZE SZ_1M
#define MX3x_CCM_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x80000)
#define MX3x_GPT1_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x90000)
@@ -105,11 +102,9 @@
* ROMP and AVIC
*/
#define MX3x_ROMP_BASE_ADDR 0x60000000
-#define MX3x_ROMP_BASE_ADDR_VIRT 0xfc500000
#define MX3x_ROMP_SIZE SZ_1M
#define MX3x_AVIC_BASE_ADDR 0x68000000
-#define MX3x_AVIC_BASE_ADDR_VIRT 0xfc400000
#define MX3x_AVIC_SIZE SZ_1M
/*
@@ -125,18 +120,17 @@
#define MX3x_CS3_BASE_ADDR 0xb2000000
#define MX3x_CS4_BASE_ADDR 0xb4000000
-#define MX3x_CS4_BASE_ADDR_VIRT 0xf4000000
+#define MX3x_CS4_BASE_ADDR_VIRT 0xf6000000
#define MX3x_CS4_SIZE SZ_32M
#define MX3x_CS5_BASE_ADDR 0xb6000000
-#define MX3x_CS5_BASE_ADDR_VIRT 0xf6000000
+#define MX3x_CS5_BASE_ADDR_VIRT 0xf8000000
#define MX3x_CS5_SIZE SZ_32M
/*
* NAND, SDRAM, WEIM, M3IF, EMI controllers
*/
#define MX3x_X_MEMC_BASE_ADDR 0xb8000000
-#define MX3x_X_MEMC_BASE_ADDR_VIRT 0xfc320000
#define MX3x_X_MEMC_SIZE SZ_64K
#define MX3x_ESDCTL_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x1000)
#define MX3x_WEIM_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x2000)
@@ -146,56 +140,6 @@
#define MX3x_PCMCIA_MEM_BASE_ADDR 0xbc000000
-/*!
- * 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 IO_ADDRESS(x) \
- (void __force __iomem *) \
- (((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
- ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
- ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
- ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
- ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
- ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
- ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
- 0xDEADBEEF)
-
-/*
- * define the address mapping macros: in physical address order
- */
-#define L2CC_IO_ADDRESS(x) \
- (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
-
-#define AIPS1_IO_ADDRESS(x) \
- (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
-
-#define SPBA0_IO_ADDRESS(x) \
- (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
-
-#define AIPS2_IO_ADDRESS(x) \
- (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
-
-#define ROMP_IO_ADDRESS(x) \
- (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x) \
- (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x) \
- (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define CS5_IO_ADDRESS(x) \
- (((x) - CS5_BASE_ADDR) + CS5_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
-#define PCMCIA_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
/*
* Interrupt numbers
*/
@@ -240,22 +184,6 @@
#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
-/* silicon revisions specific to i.MX31 and i.MX35 */
-#define MX3x_CHIP_REV_1_0 0x10
-#define MX3x_CHIP_REV_1_1 0x11
-#define MX3x_CHIP_REV_1_2 0x12
-#define MX3x_CHIP_REV_1_3 0x13
-#define MX3x_CHIP_REV_2_0 0x20
-#define MX3x_CHIP_REV_2_1 0x21
-#define MX3x_CHIP_REV_2_2 0x22
-#define MX3x_CHIP_REV_2_3 0x23
-#define MX3x_CHIP_REV_3_0 0x30
-#define MX3x_CHIP_REV_3_1 0x31
-#define MX3x_CHIP_REV_3_2 0x32
-
-#define MX3x_SYSTEM_REV_MIN MX3x_CHIP_REV_1_0
-#define MX3x_SYSTEM_REV_NUM 3
-
/* Mandatory defines used globally */
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
@@ -277,126 +205,4 @@ static inline int mx35_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
-#define AIPS1_BASE_ADDR MX3x_AIPS1_BASE_ADDR
-#define AIPS1_BASE_ADDR_VIRT MX3x_AIPS1_BASE_ADDR_VIRT
-#define AIPS1_SIZE MX3x_AIPS1_SIZE
-#define MAX_BASE_ADDR MX3x_MAX_BASE_ADDR
-#define EVTMON_BASE_ADDR MX3x_EVTMON_BASE_ADDR
-#define CLKCTL_BASE_ADDR MX3x_CLKCTL_BASE_ADDR
-#define ETB_SLOT4_BASE_ADDR MX3x_ETB_SLOT4_BASE_ADDR
-#define ETB_SLOT5_BASE_ADDR MX3x_ETB_SLOT5_BASE_ADDR
-#define ECT_CTIO_BASE_ADDR MX3x_ECT_CTIO_BASE_ADDR
-#define I2C_BASE_ADDR MX3x_I2C_BASE_ADDR
-#define I2C3_BASE_ADDR MX3x_I2C3_BASE_ADDR
-#define UART1_BASE_ADDR MX3x_UART1_BASE_ADDR
-#define UART2_BASE_ADDR MX3x_UART2_BASE_ADDR
-#define I2C2_BASE_ADDR MX3x_I2C2_BASE_ADDR
-#define OWIRE_BASE_ADDR MX3x_OWIRE_BASE_ADDR
-#define SSI1_BASE_ADDR MX3x_SSI1_BASE_ADDR
-#define CSPI1_BASE_ADDR MX3x_CSPI1_BASE_ADDR
-#define KPP_BASE_ADDR MX3x_KPP_BASE_ADDR
-#define IOMUXC_BASE_ADDR MX3x_IOMUXC_BASE_ADDR
-#define ECT_IP1_BASE_ADDR MX3x_ECT_IP1_BASE_ADDR
-#define ECT_IP2_BASE_ADDR MX3x_ECT_IP2_BASE_ADDR
-#define SPBA0_BASE_ADDR MX3x_SPBA0_BASE_ADDR
-#define SPBA0_BASE_ADDR_VIRT MX3x_SPBA0_BASE_ADDR_VIRT
-#define SPBA0_SIZE MX3x_SPBA0_SIZE
-#define UART3_BASE_ADDR MX3x_UART3_BASE_ADDR
-#define CSPI2_BASE_ADDR MX3x_CSPI2_BASE_ADDR
-#define SSI2_BASE_ADDR MX3x_SSI2_BASE_ADDR
-#define ATA_DMA_BASE_ADDR MX3x_ATA_DMA_BASE_ADDR
-#define MSHC1_BASE_ADDR MX3x_MSHC1_BASE_ADDR
-#define SPBA_CTRL_BASE_ADDR MX3x_SPBA_CTRL_BASE_ADDR
-#define AIPS2_BASE_ADDR MX3x_AIPS2_BASE_ADDR
-#define AIPS2_BASE_ADDR_VIRT MX3x_AIPS2_BASE_ADDR_VIRT
-#define AIPS2_SIZE MX3x_AIPS2_SIZE
-#define CCM_BASE_ADDR MX3x_CCM_BASE_ADDR
-#define GPT1_BASE_ADDR MX3x_GPT1_BASE_ADDR
-#define EPIT1_BASE_ADDR MX3x_EPIT1_BASE_ADDR
-#define EPIT2_BASE_ADDR MX3x_EPIT2_BASE_ADDR
-#define GPIO3_BASE_ADDR MX3x_GPIO3_BASE_ADDR
-#define SCC_BASE_ADDR MX3x_SCC_BASE_ADDR
-#define RNGA_BASE_ADDR MX3x_RNGA_BASE_ADDR
-#define IPU_CTRL_BASE_ADDR MX3x_IPU_CTRL_BASE_ADDR
-#define AUDMUX_BASE_ADDR MX3x_AUDMUX_BASE_ADDR
-#define GPIO1_BASE_ADDR MX3x_GPIO1_BASE_ADDR
-#define GPIO2_BASE_ADDR MX3x_GPIO2_BASE_ADDR
-#define SDMA_BASE_ADDR MX3x_SDMA_BASE_ADDR
-#define RTC_BASE_ADDR MX3x_RTC_BASE_ADDR
-#define WDOG_BASE_ADDR MX3x_WDOG_BASE_ADDR
-#define PWM_BASE_ADDR MX3x_PWM_BASE_ADDR
-#define RTIC_BASE_ADDR MX3x_RTIC_BASE_ADDR
-#define ROMP_BASE_ADDR MX3x_ROMP_BASE_ADDR
-#define ROMP_BASE_ADDR_VIRT MX3x_ROMP_BASE_ADDR_VIRT
-#define ROMP_SIZE MX3x_ROMP_SIZE
-#define AVIC_BASE_ADDR MX3x_AVIC_BASE_ADDR
-#define AVIC_BASE_ADDR_VIRT MX3x_AVIC_BASE_ADDR_VIRT
-#define AVIC_SIZE MX3x_AVIC_SIZE
-#define IPU_MEM_BASE_ADDR MX3x_IPU_MEM_BASE_ADDR
-#define CSD0_BASE_ADDR MX3x_CSD0_BASE_ADDR
-#define CSD1_BASE_ADDR MX3x_CSD1_BASE_ADDR
-#define CS0_BASE_ADDR MX3x_CS0_BASE_ADDR
-#define CS1_BASE_ADDR MX3x_CS1_BASE_ADDR
-#define CS2_BASE_ADDR MX3x_CS2_BASE_ADDR
-#define CS3_BASE_ADDR MX3x_CS3_BASE_ADDR
-#define CS4_BASE_ADDR MX3x_CS4_BASE_ADDR
-#define CS4_BASE_ADDR_VIRT MX3x_CS4_BASE_ADDR_VIRT
-#define CS4_SIZE MX3x_CS4_SIZE
-#define CS5_BASE_ADDR MX3x_CS5_BASE_ADDR
-#define CS5_BASE_ADDR_VIRT MX3x_CS5_BASE_ADDR_VIRT
-#define CS5_SIZE MX3x_CS5_SIZE
-#define X_MEMC_BASE_ADDR MX3x_X_MEMC_BASE_ADDR
-#define X_MEMC_BASE_ADDR_VIRT MX3x_X_MEMC_BASE_ADDR_VIRT
-#define X_MEMC_SIZE MX3x_X_MEMC_SIZE
-#define ESDCTL_BASE_ADDR MX3x_ESDCTL_BASE_ADDR
-#define WEIM_BASE_ADDR MX3x_WEIM_BASE_ADDR
-#define M3IF_BASE_ADDR MX3x_M3IF_BASE_ADDR
-#define EMI_CTL_BASE_ADDR MX3x_EMI_CTL_BASE_ADDR
-#define PCMCIA_CTL_BASE_ADDR MX3x_PCMCIA_CTL_BASE_ADDR
-#define PCMCIA_MEM_BASE_ADDR MX3x_PCMCIA_MEM_BASE_ADDR
-#define MXC_INT_I2C3 MX3x_INT_I2C3
-#define MXC_INT_I2C2 MX3x_INT_I2C2
-#define MXC_INT_RTIC MX3x_INT_RTIC
-#define MXC_INT_I2C MX3x_INT_I2C
-#define MXC_INT_CSPI2 MX3x_INT_CSPI2
-#define MXC_INT_CSPI1 MX3x_INT_CSPI1
-#define MXC_INT_ATA MX3x_INT_ATA
-#define MXC_INT_UART3 MX3x_INT_UART3
-#define MXC_INT_IIM MX3x_INT_IIM
-#define MXC_INT_RNGA MX3x_INT_RNGA
-#define MXC_INT_EVTMON MX3x_INT_EVTMON
-#define MXC_INT_KPP MX3x_INT_KPP
-#define MXC_INT_RTC MX3x_INT_RTC
-#define MXC_INT_PWM MX3x_INT_PWM
-#define MXC_INT_EPIT2 MX3x_INT_EPIT2
-#define MXC_INT_EPIT1 MX3x_INT_EPIT1
-#define MXC_INT_GPT MX3x_INT_GPT
-#define MXC_INT_POWER_FAIL MX3x_INT_POWER_FAIL
-#define MXC_INT_UART2 MX3x_INT_UART2
-#define MXC_INT_NANDFC MX3x_INT_NANDFC
-#define MXC_INT_SDMA MX3x_INT_SDMA
-#define MXC_INT_MSHC1 MX3x_INT_MSHC1
-#define MXC_INT_IPU_ERR MX3x_INT_IPU_ERR
-#define MXC_INT_IPU_SYN MX3x_INT_IPU_SYN
-#define MXC_INT_UART1 MX3x_INT_UART1
-#define MXC_INT_ECT MX3x_INT_ECT
-#define MXC_INT_SCC_SCM MX3x_INT_SCC_SCM
-#define MXC_INT_SCC_SMN MX3x_INT_SCC_SMN
-#define MXC_INT_GPIO2 MX3x_INT_GPIO2
-#define MXC_INT_GPIO1 MX3x_INT_GPIO1
-#define MXC_INT_WDOG MX3x_INT_WDOG
-#define MXC_INT_GPIO3 MX3x_INT_GPIO3
-#define MXC_INT_EXT_POWER MX3x_INT_EXT_POWER
-#define MXC_INT_EXT_TEMPER MX3x_INT_EXT_TEMPER
-#define MXC_INT_EXT_SENSOR60 MX3x_INT_EXT_SENSOR60
-#define MXC_INT_EXT_SENSOR61 MX3x_INT_EXT_SENSOR61
-#define MXC_INT_EXT_WDOG MX3x_INT_EXT_WDOG
-#define MXC_INT_EXT_TV MX3x_INT_EXT_TV
-#define PROD_SIGNATURE MX3x_PROD_SIGNATURE
-#endif
-
#endif /* ifndef __MACH_MX3x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/plat-mxc/include/mach/mx50.h
new file mode 100644
index 000000000000..aaec2a6e7b3a
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx50.h
@@ -0,0 +1,285 @@
+#ifndef __MACH_MX50_H__
+#define __MACH_MX50_H__
+
+/*
+ * IROM
+ */
+#define MX50_IROM_BASE_ADDR 0x0
+#define MX50_IROM_SIZE SZ_64K
+
+/* TZIC */
+#define MX50_TZIC_BASE_ADDR 0x0fffc000
+#define MX50_TZIC_SIZE SZ_16K
+
+/*
+ * IRAM
+ */
+#define MX50_IRAM_BASE_ADDR 0xf8000000 /* internal ram */
+#define MX50_IRAM_PARTITIONS 16
+#define MX50_IRAM_SIZE (MX50_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * Databahn
+ */
+#define MX50_DATABAHN_BASE_ADDR 0x14000000
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX50_GPU2D_BASE_ADDR 0x20000000
+
+#define MX50_DEBUG_BASE_ADDR 0x40000000
+#define MX50_DEBUG_SIZE SZ_1M
+#define MX50_ETB_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00001000)
+#define MX50_ETM_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00002000)
+#define MX50_TPIU_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00003000)
+#define MX50_CTI0_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00004000)
+#define MX50_CTI1_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00005000)
+#define MX50_CTI2_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00006000)
+#define MX50_CTI3_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00007000)
+#define MX50_CORTEX_DBG_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00008000)
+
+#define MX50_APBHDMA_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01000000)
+#define MX50_OCOTP_CTRL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01002000)
+#define MX50_DIGCTL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01004000)
+#define MX50_GPMI_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01006000)
+#define MX50_BCH_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01008000)
+#define MX50_ELCDIF_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100a000)
+#define MX50_EPXP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100c000)
+#define MX50_DCP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100e000)
+#define MX50_EPDC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01010000)
+#define MX50_QOSC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01012000)
+#define MX50_PERFMON_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01014000)
+#define MX50_SSP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01016000)
+#define MX50_ANATOP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01018000)
+#define MX50_NIC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x08000000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX50_SPBA0_BASE_ADDR 0x50000000
+#define MX50_SPBA0_SIZE SZ_1M
+
+#define MX50_MMC_SDHC1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00004000)
+#define MX50_MMC_SDHC2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00008000)
+#define MX50_UART3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x0000c000)
+#define MX50_CSPI1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00010000)
+#define MX50_SSI2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00014000)
+#define MX50_MMC_SDHC3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00020000)
+#define MX50_MMC_SDHC4_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00024000)
+
+/*
+ * AIPS 1
+ */
+#define MX50_AIPS1_BASE_ADDR 0x53f00000
+#define MX50_AIPS1_SIZE SZ_1M
+
+#define MX50_OTG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00080000)
+#define MX50_GPIO1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00084000)
+#define MX50_GPIO2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00088000)
+#define MX50_GPIO3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x0008c000)
+#define MX50_GPIO4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00090000)
+#define MX50_KPP_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00094000)
+#define MX50_WDOG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00098000)
+#define MX50_GPT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a0000)
+#define MX50_SRTC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a4000)
+#define MX50_IOMUXC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a8000)
+#define MX50_EPIT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ac000)
+#define MX50_PWM1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b4000)
+#define MX50_PWM2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b8000)
+#define MX50_UART1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000bc000)
+#define MX50_UART2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000c0000)
+#define MX50_SRC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d0000)
+#define MX50_CCM_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d4000)
+#define MX50_GPC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d8000)
+#define MX50_GPIO5_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000dc000)
+#define MX50_GPIO6_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000e0000)
+#define MX50_I2C3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ec000)
+#define MX50_UART4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f0000)
+
+#define MX50_MSHC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f4000)
+#define MX50_RNGB_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f8000)
+
+/*
+ * AIPS 2
+ */
+#define MX50_AIPS2_BASE_ADDR 0x63f00000
+#define MX50_AIPS2_SIZE SZ_1M
+
+#define MX50_PLL1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00080000)
+#define MX50_PLL2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00084000)
+#define MX50_PLL3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00088000)
+#define MX50_UART5_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00090000)
+#define MX50_AHBMAX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00094000)
+#define MX50_ARM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a0000)
+#define MX50_OWIRE_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a4000)
+#define MX50_CSPI2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ac000)
+#define MX50_SDMA_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b0000)
+#define MX50_ROMCP_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b8000)
+#define MX50_CSPI3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c0000)
+#define MX50_I2C2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c4000)
+#define MX50_I2C1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c8000)
+#define MX50_SSI1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000cc000)
+#define MX50_AUDMUX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d0000)
+#define MX50_WEIM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d8000)
+#define MX50_FEC_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ec000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX50_CSD0_BASE_ADDR 0x70000000
+#define MX50_CSD1_BASE_ADDR 0xb0000000
+#define MX50_CS0_BASE_ADDR 0xf0000000
+
+#define MX50_IO_P2V(x) IMX_IO_P2V(x)
+#define MX50_IO_ADDRESS(x) IOMEM(MX50_IO_P2V(x))
+
+/*
+ * defines for SPBA modules
+ */
+#define MX50_SPBA_SDHC1 0x04
+#define MX50_SPBA_SDHC2 0x08
+#define MX50_SPBA_UART3 0x0c
+#define MX50_SPBA_CSPI1 0x10
+#define MX50_SPBA_SSI2 0x14
+#define MX50_SPBA_SDHC3 0x20
+#define MX50_SPBA_SDHC4 0x24
+#define MX50_SPBA_SPDIF 0x28
+#define MX50_SPBA_ATA 0x30
+#define MX50_SPBA_SLIM 0x34
+#define MX50_SPBA_HSI2C 0x38
+#define MX50_SPBA_CTRL 0x3c
+
+/*
+ * DMA request assignments
+ */
+#define MX50_DMA_REQ_GPC 1
+#define MX50_DMA_REQ_ATA_UART4_RX 2
+#define MX50_DMA_REQ_ATA_UART4_TX 3
+#define MX50_DMA_REQ_CSPI1_RX 6
+#define MX50_DMA_REQ_CSPI1_TX 7
+#define MX50_DMA_REQ_CSPI2_RX 8
+#define MX50_DMA_REQ_CSPI2_TX 9
+#define MX50_DMA_REQ_I2C3_SDHC3 10
+#define MX50_DMA_REQ_SDHC4 11
+#define MX50_DMA_REQ_UART2_FIRI_RX 12
+#define MX50_DMA_REQ_UART2_FIRI_TX 13
+#define MX50_DMA_REQ_EXT0 14
+#define MX50_DMA_REQ_EXT1 15
+#define MX50_DMA_REQ_UART5_RX 16
+#define MX50_DMA_REQ_UART5_TX 17
+#define MX50_DMA_REQ_UART1_RX 18
+#define MX50_DMA_REQ_UART1_TX 19
+#define MX50_DMA_REQ_I2C1_SDHC1 20
+#define MX50_DMA_REQ_I2C2_SDHC2 21
+#define MX50_DMA_REQ_SSI2_RX2 22
+#define MX50_DMA_REQ_SSI2_TX2 23
+#define MX50_DMA_REQ_SSI2_RX1 24
+#define MX50_DMA_REQ_SSI2_TX1 25
+#define MX50_DMA_REQ_SSI1_RX2 26
+#define MX50_DMA_REQ_SSI1_TX2 27
+#define MX50_DMA_REQ_SSI1_RX1 28
+#define MX50_DMA_REQ_SSI1_TX1 29
+#define MX50_DMA_REQ_CSPI_RX 38
+#define MX50_DMA_REQ_CSPI_TX 39
+#define MX50_DMA_REQ_UART3_RX 42
+#define MX50_DMA_REQ_UART3_TX 43
+
+/*
+ * Interrupt numbers
+ */
+#define MX50_INT_MMC_SDHC1 1
+#define MX50_INT_MMC_SDHC2 2
+#define MX50_INT_MMC_SDHC3 3
+#define MX50_INT_MMC_SDHC4 4
+#define MX50_INT_DAP 5
+#define MX50_INT_SDMA 6
+#define MX50_INT_IOMUX 7
+#define MX50_INT_UART4 13
+#define MX50_INT_USB_H1 14
+#define MX50_INT_USB_OTG 18
+#define MX50_INT_DATABAHN 19
+#define MX50_INT_ELCDIF 20
+#define MX50_INT_EPXP 21
+#define MX50_INT_SRTC_NTZ 24
+#define MX50_INT_SRTC_TZ 25
+#define MX50_INT_EPDC 27
+#define MX50_INT_NIC 28
+#define MX50_INT_SSI1 29
+#define MX50_INT_SSI2 30
+#define MX50_INT_UART1 31
+#define MX50_INT_UART2 32
+#define MX50_INT_UART3 33
+#define MX50_INT_RESV34 34
+#define MX50_INT_RESV35 35
+#define MX50_INT_CSPI1 36
+#define MX50_INT_CSPI2 37
+#define MX50_INT_CSPI 38
+#define MX50_INT_GPT 39
+#define MX50_INT_EPIT1 40
+#define MX50_INT_GPIO1_INT7 42
+#define MX50_INT_GPIO1_INT6 43
+#define MX50_INT_GPIO1_INT5 44
+#define MX50_INT_GPIO1_INT4 45
+#define MX50_INT_GPIO1_INT3 46
+#define MX50_INT_GPIO1_INT2 47
+#define MX50_INT_GPIO1_INT1 48
+#define MX50_INT_GPIO1_INT0 49
+#define MX50_INT_GPIO1_LOW 50
+#define MX50_INT_GPIO1_HIGH 51
+#define MX50_INT_GPIO2_LOW 52
+#define MX50_INT_GPIO2_HIGH 53
+#define MX50_INT_GPIO3_LOW 54
+#define MX50_INT_GPIO3_HIGH 55
+#define MX50_INT_GPIO4_LOW 56
+#define MX50_INT_GPIO4_HIGH 57
+#define MX50_INT_WDOG1 58
+#define MX50_INT_KPP 60
+#define MX50_INT_PWM1 61
+#define MX50_INT_I2C1 62
+#define MX50_INT_I2C2 63
+#define MX50_INT_I2C3 64
+#define MX50_INT_RESV65 65
+#define MX50_INT_DCDC 66
+#define MX50_INT_THERMAL_ALARM 67
+#define MX50_INT_ANA3 68
+#define MX50_INT_ANA4 69
+#define MX50_INT_CCM1 71
+#define MX50_INT_CCM2 72
+#define MX50_INT_GPC1 73
+#define MX50_INT_GPC2 74
+#define MX50_INT_SRC 75
+#define MX50_INT_NM 76
+#define MX50_INT_PMU 77
+#define MX50_INT_CTI_IRQ 78
+#define MX50_INT_CTI1_TG0 79
+#define MX50_INT_CTI1_TG1 80
+#define MX50_INT_GPU2_IRQ 84
+#define MX50_INT_GPU2_BUSY 85
+#define MX50_INT_UART5 86
+#define MX50_INT_FEC 87
+#define MX50_INT_OWIRE 88
+#define MX50_INT_CTI1_TG2 89
+#define MX50_INT_SJC 90
+#define MX50_INT_DCP_CHAN1_3 91
+#define MX50_INT_DCP_CHAN0 92
+#define MX50_INT_PWM2 94
+#define MX50_INT_RNGB 97
+#define MX50_INT_CTI1_TG3 98
+#define MX50_INT_RAWNAND_BCH 100
+#define MX50_INT_RAWNAND_GPMI 102
+#define MX50_INT_GPIO5_LOW 103
+#define MX50_INT_GPIO5_HIGH 104
+#define MX50_INT_GPIO6_LOW 105
+#define MX50_INT_GPIO6_HIGH 106
+#define MX50_INT_MSHC 109
+#define MX50_INT_APBHDMA_CHAN0 110
+#define MX50_INT_APBHDMA_CHAN1 111
+#define MX50_INT_APBHDMA_CHAN2 112
+#define MX50_INT_APBHDMA_CHAN3 113
+#define MX50_INT_APBHDMA_CHAN4 114
+#define MX50_INT_APBHDMA_CHAN5 115
+#define MX50_INT_APBHDMA_CHAN6 116
+#define MX50_INT_APBHDMA_CHAN7 117
+
+#endif /* ifndef __MACH_MX50_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
index 2af7a1056fc1..873807f96d70 100644
--- a/arch/arm/plat-mxc/include/mach/mx51.h
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -2,31 +2,6 @@
#define __MACH_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
@@ -36,7 +11,6 @@
* IRAM
*/
#define MX51_IRAM_BASE_ADDR 0x1ffe0000 /* internal ram */
-#define MX51_IRAM_BASE_ADDR_VIRT 0xfa3e0000
#define MX51_IRAM_PARTITIONS 16
#define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */
@@ -45,7 +19,6 @@
#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
#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 + 0x01000)
@@ -61,7 +34,6 @@
* 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_ESDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x04000)
@@ -81,7 +53,6 @@
* 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 + 0x80000)
@@ -90,7 +61,7 @@
#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x8c000)
#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x90000)
#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x94000)
-#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000)
+#define MX51_WDOG1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000)
#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x9c000)
#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa0000)
#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa4000)
@@ -109,7 +80,6 @@
* 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 + 0x80000)
@@ -139,7 +109,7 @@
#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdc000)
#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe0000)
#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe4000)
-#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000)
+#define MX51_SSI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000)
#define MX51_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xec000)
#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf0000)
#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf4000)
@@ -163,16 +133,8 @@
#define MX51_GPU2D_BASE_ADDR 0xd0000000
#define MX51_TZIC_BASE_ADDR 0xe0000000
-#define MX51_IO_ADDRESS(x) ( \
- IMX_IO_ADDRESS(x, MX51_IRAM) ?: \
- IMX_IO_ADDRESS(x, MX51_DEBUG) ?: \
- IMX_IO_ADDRESS(x, MX51_SPBA0) ?: \
- IMX_IO_ADDRESS(x, MX51_AIPS1) ?: \
- IMX_IO_ADDRESS(x, MX51_AIPS2))
-
-/* This is currently used in <mach/debug-macro.S>, but should go away */
-#define MX51_AIPS1_IO_ADDRESS(x) \
- (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
+#define MX51_IO_P2V(x) IMX_IO_P2V(x)
+#define MX51_IO_ADDRESS(x) IOMEM(MX51_IO_P2V(x))
/*
* defines for SPBA modules
@@ -261,9 +223,9 @@
#define MX51_DMA_REQ_EMI_WR 32
#define MX51_DMA_REQ_CTI2_1 33
#define MX51_DMA_REQ_EPIT2 34
-#define MX51_DMA_REQ_SSI3_RX2 35
+#define MX51_DMA_REQ_SSI3_RX1 35
#define MX51_DMA_REQ_IPU 36
-#define MX51_DMA_REQ_SSI3_TX2 37
+#define MX51_DMA_REQ_SSI3_TX1 37
#define MX51_DMA_REQ_CSPI_RX 38
#define MX51_DMA_REQ_CSPI_TX 39
#define MX51_DMA_REQ_SDHC3 40
@@ -272,8 +234,8 @@
#define MX51_DMA_REQ_UART3_RX 43
#define MX51_DMA_REQ_UART3_TX 44
#define MX51_DMA_REQ_SPDIF 45
-#define MX51_DMA_REQ_SSI3_RX1 46
-#define MX51_DMA_REQ_SSI3_TX1 47
+#define MX51_DMA_REQ_SSI3_RX0 46
+#define MX51_DMA_REQ_SSI3_TX0 47
/*
* Interrupt numbers
@@ -289,8 +251,8 @@
#define MX51_MXC_INT_IOMUX 7
#define MX51_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_INT_IPU_ERR 10
+#define MX51_INT_IPU_SYN 11
#define MX51_MXC_INT_GPU 12
#define MX51_MXC_INT_RESV13 13
#define MX51_MXC_INT_USB_H1 14
@@ -375,7 +337,7 @@
#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_INT_SSI3 96
#define MX51_MXC_INT_EMI_BOOT 97
#define MX51_MXC_INT_CTI1_TG3 98
#define MX51_MXC_INT_SMC_RX 99
@@ -383,19 +345,6 @@
#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
-
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
extern int mx51_revision(void);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx53.h b/arch/arm/plat-mxc/include/mach/mx53.h
new file mode 100644
index 000000000000..9577cdbf7fad
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx53.h
@@ -0,0 +1,353 @@
+#ifndef __MACH_MX53_H__
+#define __MACH_MX53_H__
+
+/*
+ * IROM
+ */
+#define MX53_IROM_BASE_ADDR 0x0
+#define MX53_IROM_SIZE SZ_64K
+
+/* TZIC */
+#define MX53_TZIC_BASE_ADDR 0x0FFFC000
+
+/*
+ * AHCI SATA
+ */
+#define MX53_SATA_BASE_ADDR 0x10000000
+
+/*
+ * NFC
+ */
+#define MX53_NFC_AXI_BASE_ADDR 0xF7FF0000 /* NAND flash AXI */
+#define MX53_NFC_AXI_SIZE SZ_64K
+
+/*
+ * IRAM
+ */
+#define MX53_IRAM_BASE_ADDR 0xF8000000 /* internal ram */
+#define MX53_IRAM_PARTITIONS 16
+#define MX53_IRAM_SIZE (MX53_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX53_IPU_CTRL_BASE_ADDR 0x18000000
+#define MX53_GPU2D_BASE_ADDR 0x20000000
+#define MX53_GPU_BASE_ADDR 0x30000000
+#define MX53_GPU_GMEM_BASE_ADDR 0xF8020000
+
+#define MX53_DEBUG_BASE_ADDR 0x40000000
+#define MX53_DEBUG_SIZE SZ_1M
+#define MX53_ETB_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00001000)
+#define MX53_ETM_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00002000)
+#define MX53_TPIU_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00003000)
+#define MX53_CTI0_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00004000)
+#define MX53_CTI1_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00005000)
+#define MX53_CTI2_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00006000)
+#define MX53_CTI3_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00007000)
+#define MX53_CORTEX_DBG_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX53_SPBA0_BASE_ADDR 0x50000000
+#define MX53_SPBA0_SIZE SZ_1M
+
+#define MX53_MMC_SDHC1_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00004000)
+#define MX53_MMC_SDHC2_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00008000)
+#define MX53_UART3_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0000C000)
+#define MX53_CSPI1_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00010000)
+#define MX53_SSI2_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00014000)
+#define MX53_MMC_SDHC3_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00020000)
+#define MX53_MMC_SDHC4_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00024000)
+#define MX53_SPDIF_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00028000)
+#define MX53_ASRC_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0002C000)
+#define MX53_ATA_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00030000)
+#define MX53_SLIM_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00034000)
+#define MX53_HSI2C_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00038000)
+#define MX53_SPBA_CTRL_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * AIPS 1
+ */
+#define MX53_AIPS1_BASE_ADDR 0x53F00000
+#define MX53_AIPS1_SIZE SZ_1M
+
+#define MX53_OTG_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00080000)
+#define MX53_GPIO1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00084000)
+#define MX53_GPIO2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00088000)
+#define MX53_GPIO3_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX53_GPIO4_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00090000)
+#define MX53_KPP_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00094000)
+#define MX53_WDOG_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00098000)
+#define MX53_WDOG2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX53_GPT1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX53_SRTC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX53_IOMUXC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX53_EPIT1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX53_EPIT2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX53_PWM1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX53_PWM2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX53_UART1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX53_UART2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX53_SRC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX53_CCM_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX53_GPC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D8000)
+#define MX53_GPIO5_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000DC000)
+#define MX53_GPIO6_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E0000)
+#define MX53_GPIO7_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E4000)
+#define MX53_ATA_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E8000)
+#define MX53_I2C3_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000EC000)
+#define MX53_UART4_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000F0000)
+
+/*
+ * AIPS 2
+ */
+#define MX53_AIPS2_BASE_ADDR 0x63F00000
+#define MX53_AIPS2_SIZE SZ_1M
+
+#define MX53_PLL1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00080000)
+#define MX53_PLL2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00084000)
+#define MX53_PLL3_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00088000)
+#define MX53_PLL4_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x0008C000)
+#define MX53_UART5_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00090000)
+#define MX53_AHBMAX_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00094000)
+#define MX53_IIM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00098000)
+#define MX53_CSU_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX53_ARM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX53_OWIRE_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX53_FIRI_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX53_CSPI2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX53_SDMA_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX53_SCC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX53_ROMCP_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX53_RTIC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX53_CSPI3_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX53_I2C2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX53_I2C1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX53_SSI1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX53_AUDMUX_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX53_RTC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D4000)
+#define MX53_M4IF_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX53_ESDCTL_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX53_WEIM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX53_NFC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX53_EMI_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX53_MIPI_HSC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX53_MLB_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX53_SSI3_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX53_MXC_FEC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX53_TVE_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX53_VPU_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX53_SAHARA_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F8000)
+#define MX53_PTP_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000FC000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX53_CSD0_BASE_ADDR 0x90000000
+#define MX53_CSD1_BASE_ADDR 0xA0000000
+#define MX53_CS0_BASE_ADDR 0xB0000000
+#define MX53_CS1_BASE_ADDR 0xB8000000
+#define MX53_CS2_BASE_ADDR 0xC0000000
+#define MX53_CS3_BASE_ADDR 0xC8000000
+#define MX53_CS4_BASE_ADDR 0xCC000000
+#define MX53_CS5_BASE_ADDR 0xCE000000
+
+#define MX53_IO_P2V(x) IMX_IO_P2V(x)
+#define MX53_IO_ADDRESS(x) IOMEM(MX53_IO_P2V(x))
+
+/*
+ * defines for SPBA modules
+ */
+#define MX53_SPBA_SDHC1 0x04
+#define MX53_SPBA_SDHC2 0x08
+#define MX53_SPBA_UART3 0x0C
+#define MX53_SPBA_CSPI1 0x10
+#define MX53_SPBA_SSI2 0x14
+#define MX53_SPBA_SDHC3 0x20
+#define MX53_SPBA_SDHC4 0x24
+#define MX53_SPBA_SPDIF 0x28
+#define MX53_SPBA_ATA 0x30
+#define MX53_SPBA_SLIM 0x34
+#define MX53_SPBA_HSI2C 0x38
+#define MX53_SPBA_CTRL 0x3C
+
+/*
+ * DMA request assignments
+ */
+#define MX53_DMA_REQ_SSI3_TX1 47
+#define MX53_DMA_REQ_SSI3_RX1 46
+#define MX53_DMA_REQ_SSI3_TX2 45
+#define MX53_DMA_REQ_SSI3_RX2 44
+#define MX53_DMA_REQ_UART3_TX 43
+#define MX53_DMA_REQ_UART3_RX 42
+#define MX53_DMA_REQ_ESAI_TX 41
+#define MX53_DMA_REQ_ESAI_RX 40
+#define MX53_DMA_REQ_CSPI_TX 39
+#define MX53_DMA_REQ_CSPI_RX 38
+#define MX53_DMA_REQ_ASRC_DMA6 37
+#define MX53_DMA_REQ_ASRC_DMA5 36
+#define MX53_DMA_REQ_ASRC_DMA4 35
+#define MX53_DMA_REQ_ASRC_DMA3 34
+#define MX53_DMA_REQ_ASRC_DMA2 33
+#define MX53_DMA_REQ_ASRC_DMA1 32
+#define MX53_DMA_REQ_EMI_WR 31
+#define MX53_DMA_REQ_EMI_RD 30
+#define MX53_DMA_REQ_SSI1_TX1 29
+#define MX53_DMA_REQ_SSI1_RX1 28
+#define MX53_DMA_REQ_SSI1_TX2 27
+#define MX53_DMA_REQ_SSI1_RX2 26
+#define MX53_DMA_REQ_SSI2_TX1 25
+#define MX53_DMA_REQ_SSI2_RX1 24
+#define MX53_DMA_REQ_SSI2_TX2 23
+#define MX53_DMA_REQ_SSI2_RX2 22
+#define MX53_DMA_REQ_I2C2_SDHC2 21
+#define MX53_DMA_REQ_I2C1_SDHC1 20
+#define MX53_DMA_REQ_UART1_TX 19
+#define MX53_DMA_REQ_UART1_RX 18
+#define MX53_DMA_REQ_UART5_TX 17
+#define MX53_DMA_REQ_UART5_RX 16
+#define MX53_DMA_REQ_SPDIF_TX 15
+#define MX53_DMA_REQ_SPDIF_RX 14
+#define MX53_DMA_REQ_UART2_FIRI_TX 13
+#define MX53_DMA_REQ_UART2_FIRI_RX 12
+#define MX53_DMA_REQ_SDHC4 11
+#define MX53_DMA_REQ_I2C3_SDHC3 10
+#define MX53_DMA_REQ_CSPI2_TX 9
+#define MX53_DMA_REQ_CSPI2_RX 8
+#define MX53_DMA_REQ_CSPI1_TX 7
+#define MX53_DMA_REQ_CSPI1_RX 6
+#define MX53_DMA_REQ_IPU 5
+#define MX53_DMA_REQ_ATA_TX_END 4
+#define MX53_DMA_REQ_ATA_UART4_TX 3
+#define MX53_DMA_REQ_ATA_UART4_RX 2
+#define MX53_DMA_REQ_GPC 1
+#define MX53_DMA_REQ_VPU 0
+
+/*
+ * Interrupt numbers
+ */
+#define MX53_INT_RESV0 0
+#define MX53_INT_MMC_SDHC1 1
+#define MX53_INT_MMC_SDHC2 2
+#define MX53_INT_MMC_SDHC3 3
+#define MX53_INT_MMC_SDHC4 4
+#define MX53_INT_RESV5 5
+#define MX53_INT_SDMA 6
+#define MX53_INT_IOMUX 7
+#define MX53_INT_NFC 8
+#define MX53_INT_VPU 9
+#define MX53_INT_IPU_ERR 10
+#define MX53_INT_IPU_SYN 11
+#define MX53_INT_GPU 12
+#define MX53_INT_RESV13 13
+#define MX53_INT_USB_H1 14
+#define MX53_INT_EMI 15
+#define MX53_INT_USB_H2 16
+#define MX53_INT_USB_H3 17
+#define MX53_INT_USB_OTG 18
+#define MX53_INT_SAHARA_H0 19
+#define MX53_INT_SAHARA_H1 20
+#define MX53_INT_SCC_SMN 21
+#define MX53_INT_SCC_STZ 22
+#define MX53_INT_SCC_SCM 23
+#define MX53_INT_SRTC_NTZ 24
+#define MX53_INT_SRTC_TZ 25
+#define MX53_INT_RTIC 26
+#define MX53_INT_CSU 27
+#define MX53_INT_SATA 28
+#define MX53_INT_SSI1 29
+#define MX53_INT_SSI2 30
+#define MX53_INT_UART1 31
+#define MX53_INT_UART2 32
+#define MX53_INT_UART3 33
+#define MX53_INT_RESV34 34
+#define MX53_INT_RESV35 35
+#define MX53_INT_CSPI1 36
+#define MX53_INT_CSPI2 37
+#define MX53_INT_CSPI 38
+#define MX53_INT_GPT 39
+#define MX53_INT_EPIT1 40
+#define MX53_INT_EPIT2 41
+#define MX53_INT_GPIO1_INT7 42
+#define MX53_INT_GPIO1_INT6 43
+#define MX53_INT_GPIO1_INT5 44
+#define MX53_INT_GPIO1_INT4 45
+#define MX53_INT_GPIO1_INT3 46
+#define MX53_INT_GPIO1_INT2 47
+#define MX53_INT_GPIO1_INT1 48
+#define MX53_INT_GPIO1_INT0 49
+#define MX53_INT_GPIO1_LOW 50
+#define MX53_INT_GPIO1_HIGH 51
+#define MX53_INT_GPIO2_LOW 52
+#define MX53_INT_GPIO2_HIGH 53
+#define MX53_INT_GPIO3_LOW 54
+#define MX53_INT_GPIO3_HIGH 55
+#define MX53_INT_GPIO4_LOW 56
+#define MX53_INT_GPIO4_HIGH 57
+#define MX53_INT_WDOG1 58
+#define MX53_INT_WDOG2 59
+#define MX53_INT_KPP 60
+#define MX53_INT_PWM1 61
+#define MX53_INT_I2C1 62
+#define MX53_INT_I2C2 63
+#define MX53_INT_I2C3 64
+#define MX53_INT_RESV65 65
+#define MX53_INT_RESV66 66
+#define MX53_INT_SPDIF 67
+#define MX53_INT_SIM_DAT 68
+#define MX53_INT_IIM 69
+#define MX53_INT_ATA 70
+#define MX53_INT_CCM1 71
+#define MX53_INT_CCM2 72
+#define MX53_INT_GPC1 73
+#define MX53_INT_GPC2 74
+#define MX53_INT_SRC 75
+#define MX53_INT_NM 76
+#define MX53_INT_PMU 77
+#define MX53_INT_CTI_IRQ 78
+#define MX53_INT_CTI1_TG0 79
+#define MX53_INT_CTI1_TG1 80
+#define MX53_INT_ESAI 81
+#define MX53_INT_CAN1 82
+#define MX53_INT_CAN2 83
+#define MX53_INT_GPU2_IRQ 84
+#define MX53_INT_GPU2_BUSY 85
+#define MX53_INT_RESV86 86
+#define MX53_INT_FEC 87
+#define MX53_INT_OWIRE 88
+#define MX53_INT_CTI1_TG2 89
+#define MX53_INT_SJC 90
+#define MX53_INT_TVE 92
+#define MX53_INT_FIRI 93
+#define MX53_INT_PWM2 94
+#define MX53_INT_SLIM_EXP 95
+#define MX53_INT_SSI3 96
+#define MX53_INT_EMI_BOOT 97
+#define MX53_INT_CTI1_TG3 98
+#define MX53_INT_SMC_RX 99
+#define MX53_INT_VPU_IDLE 100
+#define MX53_INT_EMI_NFC 101
+#define MX53_INT_GPU_IDLE 102
+#define MX53_INT_GPIO5_LOW 103
+#define MX53_INT_GPIO5_HIGH 104
+#define MX53_INT_GPIO6_LOW 105
+#define MX53_INT_GPIO6_HIGH 106
+#define MX53_INT_GPIO7_LOW 107
+#define MX53_INT_GPIO7_HIGH 108
+
+/* silicon revisions specific to i.MX53 */
+#define MX53_CHIP_REV_1_0 0x10
+#define MX53_CHIP_REV_1_1 0x11
+#define MX53_CHIP_REV_1_2 0x12
+#define MX53_CHIP_REV_1_3 0x13
+#define MX53_CHIP_REV_2_0 0x20
+#define MX53_CHIP_REV_2_1 0x21
+#define MX53_CHIP_REV_2_2 0x22
+#define MX53_CHIP_REV_2_3 0x23
+#define MX53_CHIP_REV_3_0 0x30
+#define MX53_CHIP_REV_3_1 0x31
+#define MX53_CHIP_REV_3_2 0x32
+
+#endif /* ifndef __MACH_MX53_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a42c7207082d..04c7a26b1f26 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -32,9 +32,25 @@
#define MXC_CPU_MX27 27
#define MXC_CPU_MX31 31
#define MXC_CPU_MX35 35
+#define MXC_CPU_MX50 50
#define MXC_CPU_MX51 51
+#define MXC_CPU_MX53 53
#define MXC_CPU_MXC91231 91231
+#define IMX_CHIP_REVISION_1_0 0x10
+#define IMX_CHIP_REVISION_1_1 0x11
+#define IMX_CHIP_REVISION_1_2 0x12
+#define IMX_CHIP_REVISION_1_3 0x13
+#define IMX_CHIP_REVISION_2_0 0x20
+#define IMX_CHIP_REVISION_2_1 0x21
+#define IMX_CHIP_REVISION_2_2 0x22
+#define IMX_CHIP_REVISION_2_3 0x23
+#define IMX_CHIP_REVISION_3_0 0x30
+#define IMX_CHIP_REVISION_3_1 0x31
+#define IMX_CHIP_REVISION_3_2 0x32
+#define IMX_CHIP_REVISION_3_3 0x33
+#define IMX_CHIP_REVISION_UNKNOWN 0xff
+
#ifndef __ASSEMBLY__
extern unsigned int __mxc_cpu_type;
#endif
@@ -111,7 +127,19 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mx35() (0)
#endif
-#ifdef CONFIG_ARCH_MX5
+#ifdef CONFIG_ARCH_MX50
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX50
+# endif
+# define cpu_is_mx50() (mxc_cpu_type == MXC_CPU_MX50)
+#else
+# define cpu_is_mx50() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX51
# ifdef mxc_cpu_type
# undef mxc_cpu_type
# define mxc_cpu_type __mxc_cpu_type
@@ -123,6 +151,18 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mx51() (0)
#endif
+#ifdef CONFIG_ARCH_MX53
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX53
+# endif
+# define cpu_is_mx53() (mxc_cpu_type == MXC_CPU_MX53)
+#else
+# define cpu_is_mx53() (0)
+#endif
+
#ifdef CONFIG_ARCH_MXC91231
# ifdef mxc_cpu_type
# undef mxc_cpu_type
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
index 0ca3101ebf36..765190fe6332 100644
--- a/arch/arm/plat-mxc/include/mach/mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -21,14 +21,12 @@
* L2CC
*/
#define MXC91231_L2CC_BASE_ADDR 0x30000000
-#define MXC91231_L2CC_BASE_ADDR_VIRT 0xF9000000
#define MXC91231_L2CC_SIZE SZ_64K
/*
* AIPS 1
*/
#define MXC91231_AIPS1_BASE_ADDR 0x43F00000
-#define MXC91231_AIPS1_BASE_ADDR_VIRT 0xFC000000
#define MXC91231_AIPS1_SIZE SZ_1M
#define MXC91231_AIPS1_CTRL_BASE_ADDR MXC91231_AIPS1_BASE_ADDR
@@ -53,7 +51,6 @@
* AIPS 2
*/
#define MXC91231_AIPS2_BASE_ADDR 0x53F00000
-#define MXC91231_AIPS2_BASE_ADDR_VIRT 0xFC100000
#define MXC91231_AIPS2_SIZE SZ_1M
#define MXC91231_GEMK_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x8C000)
@@ -79,7 +76,6 @@
* SPBA global module 0
*/
#define MXC91231_SPBA0_BASE_ADDR 0x50000000
-#define MXC91231_SPBA0_BASE_ADDR_VIRT 0xFC200000
#define MXC91231_SPBA0_SIZE SZ_1M
#define MXC91231_MMC_SDHC1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x04000)
@@ -109,7 +105,6 @@
* SPBA global module 1
*/
#define MXC91231_SPBA1_BASE_ADDR 0x52000000
-#define MXC91231_SPBA1_BASE_ADDR_VIRT 0xFC300000
#define MXC91231_SPBA1_SIZE SZ_1M
#define MXC91231_MQSPI_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x34000)
@@ -144,18 +139,15 @@
* ROMP and AVIC
*/
#define MXC91231_ROMP_BASE_ADDR 0x60000000
-#define MXC91231_ROMP_BASE_ADDR_VIRT 0xFC400000
#define MXC91231_ROMP_SIZE SZ_64K
#define MXC91231_AVIC_BASE_ADDR 0x68000000
-#define MXC91231_AVIC_BASE_ADDR_VIRT 0xFC410000
#define MXC91231_AVIC_SIZE SZ_64K
/*
* NAND, SDRAM, WEIM, M3IF, EMI controllers
*/
#define MXC91231_X_MEMC_BASE_ADDR 0xB8000000
-#define MXC91231_X_MEMC_BASE_ADDR_VIRT 0xFC420000
#define MXC91231_X_MEMC_SIZE SZ_64K
#define MXC91231_NFC_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x0000)
@@ -183,19 +175,10 @@
/*
* 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 0.
+ * and returning the virtual address.
*/
-
-#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))
+#define MXC91231_IO_P2V(x) IMX_IO_P2V(x)
+#define MXC91231_IO_ADDRESS(x) IOMEM(MXC91231_IO_P2V(x))
/*
* 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 7fc5f9946199..a523a4079299 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -31,6 +31,7 @@
#define MXC_USBCTRL_OFFSET 0
#define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8
#define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc
+#define MXC_USBH2CTRL_OFFSET 0x14
#define MX5_USBOTHER_REGS_OFFSET 0x800
diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h
index 9be112227ac4..913e0432e40e 100644
--- a/arch/arm/plat-mxc/include/mach/sdma.h
+++ b/arch/arm/plat-mxc/include/mach/sdma.h
@@ -2,16 +2,62 @@
#define __MACH_MXC_SDMA_H__
/**
+ * struct sdma_script_start_addrs - SDMA script start pointers
+ *
+ * start addresses of the different functions in the physical
+ * address space of the SDMA engine.
+ */
+struct sdma_script_start_addrs {
+ s32 ap_2_ap_addr;
+ s32 ap_2_bp_addr;
+ s32 ap_2_ap_fixed_addr;
+ s32 bp_2_ap_addr;
+ s32 loopback_on_dsp_side_addr;
+ s32 mcu_interrupt_only_addr;
+ s32 firi_2_per_addr;
+ s32 firi_2_mcu_addr;
+ s32 per_2_firi_addr;
+ s32 mcu_2_firi_addr;
+ s32 uart_2_per_addr;
+ s32 uart_2_mcu_addr;
+ s32 per_2_app_addr;
+ s32 mcu_2_app_addr;
+ s32 per_2_per_addr;
+ s32 uartsh_2_per_addr;
+ s32 uartsh_2_mcu_addr;
+ s32 per_2_shp_addr;
+ s32 mcu_2_shp_addr;
+ s32 ata_2_mcu_addr;
+ s32 mcu_2_ata_addr;
+ s32 app_2_per_addr;
+ s32 app_2_mcu_addr;
+ s32 shp_2_per_addr;
+ s32 shp_2_mcu_addr;
+ s32 mshc_2_mcu_addr;
+ s32 mcu_2_mshc_addr;
+ s32 spdif_2_mcu_addr;
+ s32 mcu_2_spdif_addr;
+ s32 asrc_2_mcu_addr;
+ s32 ext_mem_2_ipu_addr;
+ s32 descrambler_addr;
+ s32 dptc_dvfs_addr;
+ s32 utra_addr;
+ s32 ram_code_start_addr;
+};
+
+/**
* struct sdma_platform_data - platform specific data for SDMA engine
*
* @sdma_version The version of this SDMA engine
* @cpu_name used to generate the firmware name
* @to_version CPU Tape out version
+ * @script_addrs SDMA scripts addresses in SDMA ROM
*/
struct sdma_platform_data {
int sdma_version;
char *cpu_name;
int to_version;
+ struct sdma_script_start_addrs *script_addrs;
};
#endif /* __MACH_MXC_SDMA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index 9dd9c2085aad..3a70ebf0477f 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -63,6 +63,8 @@ static inline void flush(void)
#define MX3X_UART1_BASE_ADDR 0x43F90000
#define MX3X_UART2_BASE_ADDR 0x43F94000
#define MX51_UART1_BASE_ADDR 0x73fbc000
+#define MX50_UART1_BASE_ADDR 0x53fbc000
+#define MX53_UART1_BASE_ADDR 0x53fbc000
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
{
@@ -102,6 +104,12 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
case MACH_TYPE_EUKREA_CPUIMX51SD:
uart_base = MX51_UART1_BASE_ADDR;
break;
+ case MACH_TYPE_MX50_RDP:
+ uart_base = MX50_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX53_EVK:
+ uart_base = MX53_UART1_BASE_ADDR;
+ break;
default:
break;
}
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/plat-mxc/iomux-v3.c
index b318c6a222d5..99a9cdb9d6be 100644
--- a/arch/arm/plat-mxc/iomux-v3.c
+++ b/arch/arm/plat-mxc/iomux-v3.c
@@ -32,31 +32,38 @@
static void __iomem *base;
/*
- * setups a single pad in the iomuxer
+ * configures a single pad in the iomuxer
*/
-int mxc_iomux_v3_setup_pad(struct pad_desc *pad)
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
{
- if (pad->mux_ctrl_ofs)
- __raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs);
+ u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+ u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+ u32 sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+ u32 sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+ u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+ u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
- if (pad->select_input_ofs)
- __raw_writel(pad->select_input,
- base + pad->select_input_ofs);
+ if (mux_ctrl_ofs)
+ __raw_writel(mux_mode, base + mux_ctrl_ofs);
+
+ if (sel_input_ofs)
+ __raw_writel(sel_input, base + sel_input_ofs);
+
+ if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+ __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
- if (!(pad->pad_ctrl & NO_PAD_CTRL) && pad->pad_ctrl_ofs)
- __raw_writel(pad->pad_ctrl, base + pad->pad_ctrl_ofs);
return 0;
}
EXPORT_SYMBOL(mxc_iomux_v3_setup_pad);
-int mxc_iomux_v3_setup_multiple_pads(struct pad_desc *pad_list, unsigned count)
+int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count)
{
- struct pad_desc *p = pad_list;
+ iomux_v3_cfg_t *p = pad_list;
int i;
int ret;
for (i = 0; i < count; i++) {
- ret = mxc_iomux_v3_setup_pad(p);
+ ret = mxc_iomux_v3_setup_pad(*p);
if (ret)
return ret;
p++;
diff --git a/arch/arm/plat-mxc/irq-common.c b/arch/arm/plat-mxc/irq-common.c
new file mode 100644
index 000000000000..0c799ac27730
--- /dev/null
+++ b/arch/arm/plat-mxc/irq-common.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) BitBox Ltd 2010
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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/irq.h>
+
+#include "irq-common.h"
+
+int imx_irq_set_priority(unsigned char irq, unsigned char prio)
+{
+ struct mxc_irq_chip *chip;
+ struct irq_chip *base;
+ int ret;
+
+ ret = -ENOSYS;
+
+ base = get_irq_chip(irq);
+ if (base) {
+ chip = container_of(base, struct mxc_irq_chip, base);
+ if (chip->set_priority)
+ ret = chip->set_priority(irq, prio);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_irq_set_priority);
+
+int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ struct mxc_irq_chip *chip;
+ struct irq_chip *base;
+ int ret;
+
+ ret = -ENOSYS;
+
+ base = get_irq_chip(irq);
+ if (base) {
+ chip = container_of(base, struct mxc_irq_chip, base);
+ if (chip->set_irq_fiq)
+ ret = chip->set_irq_fiq(irq, type);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_set_irq_fiq);
diff --git a/arch/arm/plat-mxc/irq-common.h b/arch/arm/plat-mxc/irq-common.h
new file mode 100644
index 000000000000..7203543fb1b3
--- /dev/null
+++ b/arch/arm/plat-mxc/irq-common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) BitBox Ltd 2010
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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 __PLAT_MXC_IRQ_COMMON_H__
+#define __PLAT_MXC_IRQ_COMMON_H__
+
+struct mxc_irq_chip
+{
+ struct irq_chip base;
+ int (*set_priority)(unsigned char irq, unsigned char prio);
+ int (*set_irq_fiq)(unsigned int irq, unsigned int type);
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
index 4ddce565b353..8397a2dd19f2 100644
--- a/arch/arm/plat-mxc/ssi-fiq.S
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -124,6 +124,8 @@ imx_ssi_fiq_start:
1:
@ return from FIQ
subs pc, lr, #4
+
+ .align
imx_ssi_fiq_base:
.word 0x0
imx_ssi_fiq_rx_buffer:
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 925bce4607e7..3455fc0575a6 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -26,6 +26,7 @@
#include <mach/common.h>
#include <asm/proc-fns.h>
#include <asm/system.h>
+#include <asm/mach-types.h>
static void __iomem *wdog_base;
@@ -42,12 +43,19 @@ void arch_reset(char mode, const char *cmd)
return;
}
#endif
+#ifdef CONFIG_MACH_MX51_EFIKAMX
+ if (machine_is_mx51_efikamx()) {
+ mx51_efikamx_reset();
+ return;
+ }
+#endif
+
if (cpu_is_mx1()) {
wcr_enable = (1 << 0);
} else {
struct clk *clk;
- clk = clk_get_sys("imx-wdt.0", NULL);
+ clk = clk_get_sys("imx2-wdt.0", NULL);
if (!IS_ERR(clk))
clk_enable(clk);
wcr_enable = (1 << 2);
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index f9a1b059a76c..9f0c2610595e 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -120,7 +120,6 @@ static struct clocksource clocksource_mxc = {
.rating = 200,
.read = mx1_2_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -131,9 +130,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
if (timer_is_v2())
clocksource_mxc.read = v2_get_cycles;
- clocksource_mxc.mult = clocksource_hz2mult(c,
- clocksource_mxc.shift);
- clocksource_register(&clocksource_mxc);
+ clocksource_register_hz(&clocksource_mxc, c);
return 0;
}
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 3703ab28257f..e69ed8a8c203 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -21,6 +21,8 @@
#include <mach/hardware.h>
#include <mach/common.h>
+#include "irq-common.h"
+
/*
*****************************************
* TZIC Registers *
@@ -47,6 +49,25 @@
void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
+#ifdef CONFIG_FIQ
+static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ unsigned int index, mask, value;
+
+ index = irq >> 5;
+ if (unlikely(index >= 4))
+ return -EINVAL;
+ mask = 1U << (irq & 0x1F);
+
+ value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask;
+ if (type)
+ value &= ~mask;
+ __raw_writel(value, tzic_base + TZIC_INTSEC0(index));
+
+ return 0;
+}
+#endif
+
/**
* tzic_mask_irq() - Disable interrupt number "irq" in the TZIC
*
@@ -104,12 +125,17 @@ static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
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,
+static struct mxc_irq_chip mxc_tzic_chip = {
+ .base = {
+ .name = "MXC_TZIC",
+ .ack = tzic_mask_irq,
+ .mask = tzic_mask_irq,
+ .unmask = tzic_unmask_irq,
+ .set_wake = tzic_set_wake_irq,
+ },
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = tzic_set_irq_fiq,
+#endif
};
/*
@@ -141,10 +167,16 @@ void __init tzic_init_irq(void __iomem *irqbase)
/* all IRQ no FIQ Warning :: No selection */
for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
- set_irq_chip(i, &mxc_tzic_chip);
+ set_irq_chip(i, &mxc_tzic_chip.base);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
+
+#ifdef CONFIG_FIQ
+ /* Initialize FIQ */
+ init_FIQ();
+#endif
+
pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
}
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index 5da3f97c537b..187f4e84bb22 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -14,6 +14,7 @@ if PLAT_NOMADIK
config HAS_MTU
bool
+ select HAVE_SCHED_CLOCK
help
Support for Multi Timer Unit. MTU provides access
to multiple interrupt generating programmable
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 85e6fd212a41..eda4e3a11a3d 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -119,7 +119,7 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
}
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
- pin_cfg_t cfg)
+ pin_cfg_t cfg, bool sleep)
{
static const char *afnames[] = {
[NMK_GPIO_ALT_GPIO] = "GPIO",
@@ -145,11 +145,34 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
int output = PIN_DIR(cfg);
int val = PIN_VAL(cfg);
- dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n",
- pin, afnames[af], pullnames[pull], slpmnames[slpm],
+ dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
+ pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
output ? "output " : "input",
output ? (val ? "high" : "low") : "");
+ if (sleep) {
+ int slpm_pull = PIN_SLPM_PULL(cfg);
+ int slpm_output = PIN_SLPM_DIR(cfg);
+ int slpm_val = PIN_SLPM_VAL(cfg);
+
+ /*
+ * The SLPM_* values are normal values + 1 to allow zero to
+ * mean "same as normal".
+ */
+ if (slpm_pull)
+ pull = slpm_pull - 1;
+ if (slpm_output)
+ output = slpm_output - 1;
+ if (slpm_val)
+ val = slpm_val - 1;
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
+ pin,
+ slpm_pull ? pullnames[pull] : "same",
+ slpm_output ? (output ? "output" : "input") : "same",
+ slpm_val ? (val ? "high" : "low") : "same");
+ }
+
if (output)
__nmk_gpio_make_output(nmk_chip, offset, val);
else {
@@ -175,7 +198,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
* side-effects. The gpio can be manipulated later using standard GPIO API
* calls.
*/
-int nmk_config_pin(pin_cfg_t cfg)
+int nmk_config_pin(pin_cfg_t cfg, bool sleep)
{
struct nmk_gpio_chip *nmk_chip;
int gpio = PIN_NUM(cfg);
@@ -186,7 +209,7 @@ int nmk_config_pin(pin_cfg_t cfg)
return -EINVAL;
spin_lock_irqsave(&nmk_chip->lock, flags);
- __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg);
+ __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
return 0;
@@ -207,7 +230,7 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num)
int i;
for (i = 0; i < num; i++) {
- int ret = nmk_config_pin(cfgs[i]);
+ ret = nmk_config_pin(cfgs[i], false);
if (ret)
break;
}
@@ -216,6 +239,21 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num)
}
EXPORT_SYMBOL(nmk_config_pins);
+int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ ret = nmk_config_pin(cfgs[i], true);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(nmk_config_pins_sleep);
+
/**
* nmk_gpio_set_slpm() - configure the sleep mode of a pin
* @gpio: pin number
@@ -634,7 +672,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
chip = &nmk_chip->chip;
chip->base = pdata->first_gpio;
- chip->label = pdata->name;
+ chip->label = pdata->name ?: dev_name(&dev->dev);
chip->dev = &dev->dev;
chip->owner = THIS_MODULE;
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 8c5ae3f2acf8..05a3936ae6d1 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -19,16 +19,22 @@
* bit 9..10 - Alternate Function Selection
* bit 11..12 - Pull up/down state
* bit 13 - Sleep mode behaviour
- * bit 14 - (sleep mode) Direction
- * bit 15 - (sleep mode) Value (if output)
+ * bit 14 - Direction
+ * bit 15 - Value (if output)
+ * bit 16..18 - SLPM pull up/down state
+ * bit 19..20 - SLPM direction
+ * bit 21..22 - SLPM Value (if output)
*
* to facilitate the definition, the following macros are provided
*
* PIN_CFG_DEFAULT - default config (0):
* pull up/down = disabled
* sleep mode = input/wakeup
- * (sleep mode) direction = input
- * (sleep mode) value = low
+ * direction = input
+ * value = low
+ * SLPM direction = same as normal
+ * SLPM pull = same as normal
+ * SLPM value = same as normal
*
* PIN_CFG - default config with alternate function
* PIN_CFG_PULL - default config with alternate function and pull up/down
@@ -75,30 +81,64 @@ typedef unsigned long pin_cfg_t;
#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
-/* Shortcuts. Use these instead of separate DIR and VAL. */
-#define PIN_INPUT PIN_DIR_INPUT
+#define PIN_SLPM_PULL_SHIFT 16
+#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL(x) \
+ (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_NONE \
+ ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_UP \
+ ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_DOWN \
+ ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
+
+#define PIN_SLPM_DIR_SHIFT 19
+#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR(x) \
+ (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
+
+#define PIN_SLPM_VAL_SHIFT 21
+#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL(x) \
+ (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
+
+/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
+#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
+#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
+#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
-/*
- * These are the same as the ones above, but should make more sense to the
- * reader when seen along with a setting a pin to AF mode.
- */
-#define PIN_SLPM_INPUT PIN_INPUT
-#define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW
-#define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH
+#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
+#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
+#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
+#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
+#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
-#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
+#define PIN_CFG_DEFAULT (0)
#define PIN_CFG(num, alt) \
(PIN_CFG_DEFAULT |\
(PIN_NUM(num) | PIN_##alt))
+#define PIN_CFG_INPUT(num, alt, pull) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
+
+#define PIN_CFG_OUTPUT(num, alt, val) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
+
#define PIN_CFG_PULL(num, alt, pull) \
((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
(PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
-extern int nmk_config_pin(pin_cfg_t cfg);
+extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
+extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 63cdc6025bd7..41723402006b 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -17,9 +17,9 @@
#include <linux/clk.h>
#include <linux/jiffies.h>
#include <linux/err.h>
-#include <linux/cnt32_to_63.h>
-#include <linux/timer.h>
+#include <linux/sched.h>
#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
#include <plat/mtu.h>
@@ -52,81 +52,24 @@ static struct clocksource nmdk_clksrc = {
* Override the global weak sched_clock symbol with this
* local implementation which uses the clocksource to get some
* better resolution when scheduling the kernel.
- *
- * Because the hardware timer period may be quite short
- * (32.3 secs on the 133 MHz MTU timer selection on ux500)
- * and because cnt32_to_63() needs to be called at least once per
- * half period to work properly, a kernel keepwarm() timer is set up
- * to ensure this requirement is always met.
- *
- * Also the sched_clock timer will wrap around at some point,
- * here we set it to run continously for a year.
*/
-#define SCHED_CLOCK_MIN_WRAP 3600*24*365
-static struct timer_list cnt32_to_63_keepwarm_timer;
-static u32 sched_mult;
-static u32 sched_shift;
+static DEFINE_CLOCK_DATA(cd);
unsigned long long notrace sched_clock(void)
{
- u64 cycles;
+ u32 cyc;
if (unlikely(!mtu_base))
return 0;
- cycles = cnt32_to_63(-readl(mtu_base + MTU_VAL(0)));
- /*
- * sched_mult is guaranteed to be even so will
- * shift out bit 63
- */
- return (cycles * sched_mult) >> sched_shift;
+ cyc = -readl(mtu_base + MTU_VAL(0));
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
}
-/* Just kick sched_clock every so often */
-static void cnt32_to_63_keepwarm(unsigned long data)
+static void notrace nomadik_update_sched_clock(void)
{
- mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- (void) sched_clock();
-}
-
-/*
- * Set up a timer to keep sched_clock():s 32_to_63 algorithm warm
- * once in half a 32bit timer wrap interval.
- */
-static void __init nmdk_sched_clock_init(unsigned long rate)
-{
- u32 v;
- unsigned long delta;
- u64 days;
-
- /* Find the apropriate mult and shift factors */
- clocks_calc_mult_shift(&sched_mult, &sched_shift,
- rate, NSEC_PER_SEC, SCHED_CLOCK_MIN_WRAP);
- /* We need to multiply by an even number to get rid of bit 63 */
- if (sched_mult & 1)
- sched_mult++;
-
- /* Let's see what we get, take max counter and scale it */
- days = (0xFFFFFFFFFFFFFFFFLLU * sched_mult) >> sched_shift;
- do_div(days, NSEC_PER_SEC);
- do_div(days, (3600*24));
-
- pr_info("sched_clock: using %d bits @ %lu Hz wrap in %lu days\n",
- (64 - sched_shift), rate, (unsigned long) days);
-
- /*
- * Program a timer to kick us at half 32bit wraparound
- * Formula: seconds per wrap = (2^32) / f
- */
- v = 0xFFFFFFFFUL / rate;
- /* We want half of the wrap time to keep cnt32_to_63 warm */
- v /= 2;
- pr_debug("sched_clock: prescaled timer rate: %lu Hz, "
- "initialize keepwarm timer every %d seconds\n", rate, v);
- /* Convert seconds to jiffies */
- delta = msecs_to_jiffies(v*1000);
- setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, delta);
- mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + delta));
+ u32 cyc = -readl(mtu_base + MTU_VAL(0));
+ update_sched_clock(&cd, cyc, (u32)~0);
}
/* Clockevent device: use one-shot mode */
@@ -222,7 +165,6 @@ void __init nmdk_timer_init(void)
} else {
cr |= MTU_CRn_PRESCALE_1;
}
- clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
/* Timer 0 is the free running clocksource */
writel(cr, mtu_base + MTU_CR(0));
@@ -233,11 +175,11 @@ void __init nmdk_timer_init(void)
/* Now the clock source is ready */
nmdk_clksrc.read = nmdk_read_timer;
- if (clocksource_register(&nmdk_clksrc))
+ if (clocksource_register_hz(&nmdk_clksrc, rate))
pr_err("timer: failed to initialize clock source %s\n",
nmdk_clksrc.name);
- nmdk_sched_clock_init(rate);
+ init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
/* Timer 1 is used for events */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 92c5bb7909f5..18fe3cb195dc 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -11,13 +11,14 @@ choice
config ARCH_OMAP1
bool "TI OMAP1"
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
help
"Systems based on omap7xx, omap15xx or omap16xx"
config ARCH_OMAP2PLUS
bool "TI OMAP2/3/4"
- select COMMON_CLKDEV
+ select CLKDEV_LOOKUP
+ select OMAP_DM_TIMER
help
"Systems based on OMAP2, OMAP3 or OMAP4"
@@ -35,6 +36,37 @@ config OMAP_DEBUG_LEDS
depends on OMAP_DEBUG_DEVICES
default y if LEDS_CLASS
+config OMAP_SMARTREFLEX
+ bool "SmartReflex support"
+ depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ help
+ Say Y if you want to enable SmartReflex.
+
+ SmartReflex can perform continuous dynamic voltage
+ scaling around the nominal operating point voltage
+ according to silicon characteristics and operating
+ conditions. Enabling SmartReflex reduces power
+ consumption.
+
+ Please note, that by default SmartReflex is only
+ initialized. To enable the automatic voltage
+ compensation for vdd mpu and vdd core from user space,
+ user must write 1 to
+ /debug/voltage/vdd_<X>/smartreflex/autocomp,
+ where X is mpu or core for OMAP3.
+ Optionallly autocompensation can be enabled in the kernel
+ by default during system init via the enable_on_init flag
+ which an be passed as platform data to the smartreflex driver.
+
+config OMAP_SMARTREFLEX_CLASS3
+ bool "Class 3 mode of Smartreflex Implementation"
+ depends on OMAP_SMARTREFLEX && TWL4030_CORE
+ help
+ Say Y to enable Class 3 implementation of Smartreflex
+
+ Class 3 implementation of Smartreflex employs continuous hardware
+ voltage calibration.
+
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_OMAP
@@ -109,6 +141,9 @@ config OMAP_IOMMU_DEBUG
Say N unless you know you need this.
+config OMAP_IOMMU_IVA2
+ bool
+
choice
prompt "System timer"
default OMAP_32K_TIMER if !ARCH_OMAP15XX
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 155fe43a672b..ea4644021fb9 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -15,7 +15,11 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/io.h>
+#include <linux/sched.h>
+
+#include <asm/sched_clock.h>
#include <plat/common.h>
#include <plat/board.h>
@@ -44,7 +48,7 @@
static u32 offset_32k __read_mostly;
#ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t omap16xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
{
return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
}
@@ -53,7 +57,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
#endif
#ifdef CONFIG_ARCH_OMAP2420
-static cycle_t omap2420_32k_read(struct clocksource *cs)
+static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
{
return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
}
@@ -62,7 +66,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
#endif
#ifdef CONFIG_ARCH_OMAP2430
-static cycle_t omap2430_32k_read(struct clocksource *cs)
+static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
{
return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
}
@@ -71,7 +75,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
#endif
#ifdef CONFIG_ARCH_OMAP3
-static cycle_t omap34xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
{
return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
}
@@ -80,7 +84,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
#endif
#ifdef CONFIG_ARCH_OMAP4
-static cycle_t omap44xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
{
return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
}
@@ -92,7 +96,7 @@ static cycle_t omap44xx_32k_read(struct clocksource *cs)
* Kernel assumes that sched_clock can be called early but may not have
* things ready yet.
*/
-static cycle_t omap_32k_read_dummy(struct clocksource *cs)
+static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
{
return 0;
}
@@ -102,7 +106,6 @@ static struct clocksource clocksource_32k = {
.rating = 250,
.read = omap_32k_read_dummy,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -110,10 +113,25 @@ static struct clocksource clocksource_32k = {
* Returns current time from boot in nsecs. It's OK for this to wrap
* around for now, as it's just a relative time stamp.
*/
-unsigned long long sched_clock(void)
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 30us and a wrap period of about 36hrs.
+ */
+#define SC_MULT 4000000000u
+#define SC_SHIFT 17
+
+unsigned long long notrace sched_clock(void)
{
- return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
- clocksource_32k.mult, clocksource_32k.shift);
+ u32 cyc = clocksource_32k.read(&clocksource_32k);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace omap_update_sched_clock(void)
+{
+ u32 cyc = clocksource_32k.read(&clocksource_32k);
+ update_sched_clock(&cd, cyc, (u32)~0);
}
/**
@@ -164,16 +182,16 @@ static int __init omap_init_clocksource_32k(void)
return -ENODEV;
sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
- if (sync_32k_ick)
+ if (!IS_ERR(sync_32k_ick))
clk_enable(sync_32k_ick);
- clocksource_32k.mult = clocksource_hz2mult(32768,
- clocksource_32k.shift);
-
offset_32k = clocksource_32k.read(&clocksource_32k);
- if (clocksource_register(&clocksource_32k))
+ if (clocksource_register_hz(&clocksource_32k, 32768))
printk(err, clocksource_32k.name);
+
+ init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
+ 32768, SC_MULT, SC_SHIFT);
}
return 0;
}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index fc819120978d..10245b837c10 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -232,46 +232,6 @@ static void omap_init_uwire(void)
static inline void omap_init_uwire(void) {}
#endif
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
-
-static struct resource wdt_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device omap_wdt_device = {
- .name = "omap_wdt",
- .id = -1,
- .num_resources = ARRAY_SIZE(wdt_resources),
- .resource = wdt_resources,
-};
-
-static void omap_init_wdt(void)
-{
- if (cpu_is_omap16xx())
- wdt_resources[0].start = 0xfffeb000;
- else if (cpu_is_omap2420())
- wdt_resources[0].start = 0x48022000; /* WDT2 */
- else if (cpu_is_omap2430())
- wdt_resources[0].start = 0x49016000; /* WDT2 */
- else if (cpu_is_omap343x())
- wdt_resources[0].start = 0x48314000; /* WDT2 */
- else if (cpu_is_omap44xx())
- wdt_resources[0].start = 0x4a314000;
- else
- return;
-
- wdt_resources[0].end = wdt_resources[0].start + 0x4f;
-
- (void) platform_device_register(&omap_wdt_device);
-}
-#else
-static inline void omap_init_wdt(void) {}
-#endif
-
#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
static phys_addr_t omap_dsp_phys_mempool_base;
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 2c2826571d45..c4b2b478b1a5 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -15,6 +15,10 @@
*
* Support functions for the OMAP internal DMA channels.
*
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into DMA platform driver.
+ * - G, Manjunath Kondaiah <manjugk@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.
@@ -53,7 +57,11 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+static struct omap_system_dma_plat_info *p;
+static struct omap_dma_dev_attr *d;
+
static int enable_1510_mode;
+static u32 errata;
static struct omap_dma_global_context_registers {
u32 dma_irqenable_l0;
@@ -61,27 +69,6 @@ static struct omap_dma_global_context_registers {
u32 dma_gcr;
} omap_dma_global_context;
-struct omap_dma_lch {
- int next_lch;
- int dev_id;
- u16 saved_csr;
- u16 enabled_irqs;
- const char *dev_name;
- void (*callback)(int lch, u16 ch_status, void *data);
- void *data;
-
-#ifndef CONFIG_ARCH_OMAP1
- /* required for Dynamic chaining */
- int prev_linked_ch;
- int next_linked_ch;
- int state;
- int chain_id;
-
- int status;
-#endif
- long flags;
-};
-
struct dma_link_info {
int *linked_dmach_q;
int no_of_lchs_linked;
@@ -137,15 +124,6 @@ static int omap_dma_reserve_channels;
static spinlock_t dma_chan_lock;
static struct omap_dma_lch *dma_chan;
-static void __iomem *omap_dma_base;
-
-static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
- INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
- INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
- INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
- INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
- INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
-};
static inline void disable_lnk(int lch);
static void omap_disable_channel_irq(int lch);
@@ -154,24 +132,6 @@ static inline void omap_enable_channel_irq(int lch);
#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
__func__);
-#define dma_read(reg) \
-({ \
- u32 __val; \
- if (cpu_class_is_omap1()) \
- __val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \
- else \
- __val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \
- __val; \
-})
-
-#define dma_write(val, reg) \
-({ \
- if (cpu_class_is_omap1()) \
- __raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \
- else \
- __raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \
-})
-
#ifdef CONFIG_ARCH_OMAP15XX
/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
int omap_dma_in_1510_mode(void)
@@ -206,16 +166,6 @@ static inline void set_gdma_dev(int req, int dev)
#define set_gdma_dev(req, dev) do {} while (0)
#endif
-/* Omap1 only */
-static void clear_lch_regs(int lch)
-{
- int i;
- void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch);
-
- for (i = 0; i < 0x2c; i += 2)
- __raw_writew(0, lch_base + i);
-}
-
void omap_set_dma_priority(int lch, int dst_port, int priority)
{
unsigned long reg;
@@ -248,12 +198,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
if (cpu_class_is_omap2()) {
u32 ccr;
- ccr = dma_read(CCR(lch));
+ ccr = p->dma_read(CCR, lch);
if (priority)
ccr |= (1 << 6);
else
ccr &= ~(1 << 6);
- dma_write(ccr, CCR(lch));
+ p->dma_write(ccr, CCR, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_priority);
@@ -264,31 +214,31 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~0x03;
l |= data_type;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
if (cpu_class_is_omap1()) {
u16 ccr;
- ccr = dma_read(CCR(lch));
+ ccr = p->dma_read(CCR, lch);
ccr &= ~(1 << 5);
if (sync_mode == OMAP_DMA_SYNC_FRAME)
ccr |= 1 << 5;
- dma_write(ccr, CCR(lch));
+ p->dma_write(ccr, CCR, lch);
- ccr = dma_read(CCR2(lch));
+ ccr = p->dma_read(CCR2, lch);
ccr &= ~(1 << 2);
if (sync_mode == OMAP_DMA_SYNC_BLOCK)
ccr |= 1 << 2;
- dma_write(ccr, CCR2(lch));
+ p->dma_write(ccr, CCR2, lch);
}
if (cpu_class_is_omap2() && dma_trigger) {
u32 val;
- val = dma_read(CCR(lch));
+ val = p->dma_read(CCR, lch);
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
val &= ~((1 << 23) | (3 << 19) | 0x1f);
@@ -313,11 +263,11 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
} else {
val &= ~(1 << 24); /* dest synch */
}
- dma_write(val, CCR(lch));
+ p->dma_write(val, CCR, lch);
}
- dma_write(elem_count, CEN(lch));
- dma_write(frame_count, CFN(lch));
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
}
EXPORT_SYMBOL(omap_set_dma_transfer_params);
@@ -328,7 +278,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CCR2(lch));
+ w = p->dma_read(CCR2, lch);
w &= ~0x03;
switch (mode) {
@@ -343,23 +293,22 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(w, CCR2(lch));
+ p->dma_write(w, CCR2, lch);
- w = dma_read(LCH_CTRL(lch));
+ w = p->dma_read(LCH_CTRL, lch);
w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
- dma_write((u16)color, COLOR_L(lch));
- dma_write((u16)(color >> 16), COLOR_U(lch));
+ p->dma_write(color, COLOR, lch);
w |= 1; /* Channel type G */
}
- dma_write(w, LCH_CTRL(lch));
+ p->dma_write(w, LCH_CTRL, lch);
}
if (cpu_class_is_omap2()) {
u32 val;
- val = dma_read(CCR(lch));
+ val = p->dma_read(CCR, lch);
val &= ~((1 << 17) | (1 << 16));
switch (mode) {
@@ -374,10 +323,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(val, CCR(lch));
+ p->dma_write(val, CCR, lch);
color &= 0xffffff;
- dma_write(color, COLOR(lch));
+ p->dma_write(color, COLOR, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_color_mode);
@@ -387,10 +336,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
if (cpu_class_is_omap2()) {
u32 csdp;
- csdp = dma_read(CSDP(lch));
+ csdp = p->dma_read(CSDP, lch);
csdp &= ~(0x3 << 16);
csdp |= (mode << 16);
- dma_write(csdp, CSDP(lch));
+ p->dma_write(csdp, CSDP, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_write_mode);
@@ -400,10 +349,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
u32 l;
- l = dma_read(LCH_CTRL(lch));
+ l = p->dma_read(LCH_CTRL, lch);
l &= ~0x7;
l |= mode;
- dma_write(l, LCH_CTRL(lch));
+ p->dma_write(l, LCH_CTRL, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_channel_mode);
@@ -418,27 +367,21 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CSDP(lch));
+ w = p->dma_read(CSDP, lch);
w &= ~(0x1f << 2);
w |= src_port << 2;
- dma_write(w, CSDP(lch));
+ p->dma_write(w, CSDP, lch);
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~(0x03 << 12);
l |= src_amode << 12;
- dma_write(l, CCR(lch));
-
- if (cpu_class_is_omap1()) {
- dma_write(src_start >> 16, CSSA_U(lch));
- dma_write((u16)src_start, CSSA_L(lch));
- }
+ p->dma_write(l, CCR, lch);
- if (cpu_class_is_omap2())
- dma_write(src_start, CSSA(lch));
+ p->dma_write(src_start, CSSA, lch);
- dma_write(src_ei, CSEI(lch));
- dma_write(src_fi, CSFI(lch));
+ p->dma_write(src_ei, CSEI, lch);
+ p->dma_write(src_fi, CSFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_params);
@@ -466,8 +409,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CSEI(lch));
- dma_write(fidx, CSFI(lch));
+ p->dma_write(eidx, CSEI, lch);
+ p->dma_write(fidx, CSFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_index);
@@ -475,11 +418,11 @@ void omap_set_dma_src_data_pack(int lch, int enable)
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(1 << 6);
if (enable)
l |= (1 << 6);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_data_pack);
@@ -488,7 +431,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned int burst = 0;
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x03 << 7);
switch (burst_mode) {
@@ -524,7 +467,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
}
l |= (burst << 7);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
@@ -536,27 +479,21 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
u32 l;
if (cpu_class_is_omap1()) {
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x1f << 9);
l |= dest_port << 9;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~(0x03 << 14);
l |= dest_amode << 14;
- dma_write(l, CCR(lch));
-
- if (cpu_class_is_omap1()) {
- dma_write(dest_start >> 16, CDSA_U(lch));
- dma_write(dest_start, CDSA_L(lch));
- }
+ p->dma_write(l, CCR, lch);
- if (cpu_class_is_omap2())
- dma_write(dest_start, CDSA(lch));
+ p->dma_write(dest_start, CDSA, lch);
- dma_write(dst_ei, CDEI(lch));
- dma_write(dst_fi, CDFI(lch));
+ p->dma_write(dst_ei, CDEI, lch);
+ p->dma_write(dst_fi, CDFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_params);
@@ -565,8 +502,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CDEI(lch));
- dma_write(fidx, CDFI(lch));
+ p->dma_write(eidx, CDEI, lch);
+ p->dma_write(fidx, CDFI, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_index);
@@ -574,11 +511,11 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
{
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(1 << 13);
if (enable)
l |= 1 << 13;
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
@@ -587,7 +524,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned int burst = 0;
u32 l;
- l = dma_read(CSDP(lch));
+ l = p->dma_read(CSDP, lch);
l &= ~(0x03 << 14);
switch (burst_mode) {
@@ -620,7 +557,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
return;
}
l |= (burst << 14);
- dma_write(l, CSDP(lch));
+ p->dma_write(l, CSDP, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
@@ -630,18 +567,18 @@ static inline void omap_enable_channel_irq(int lch)
/* Clear CSR */
if (cpu_class_is_omap1())
- status = dma_read(CSR(lch));
+ status = p->dma_read(CSR, lch);
else if (cpu_class_is_omap2())
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
/* Enable some nice interrupts. */
- dma_write(dma_chan[lch].enabled_irqs, CICR(lch));
+ p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
}
static void omap_disable_channel_irq(int lch)
{
if (cpu_class_is_omap2())
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
}
void omap_enable_dma_irq(int lch, u16 bits)
@@ -660,7 +597,7 @@ static inline void enable_lnk(int lch)
{
u32 l;
- l = dma_read(CLNK_CTRL(lch));
+ l = p->dma_read(CLNK_CTRL, lch);
if (cpu_class_is_omap1())
l &= ~(1 << 14);
@@ -675,18 +612,18 @@ static inline void enable_lnk(int lch)
l = dma_chan[lch].next_linked_ch | (1 << 15);
#endif
- dma_write(l, CLNK_CTRL(lch));
+ p->dma_write(l, CLNK_CTRL, lch);
}
static inline void disable_lnk(int lch)
{
u32 l;
- l = dma_read(CLNK_CTRL(lch));
+ l = p->dma_read(CLNK_CTRL, lch);
/* Disable interrupts */
if (cpu_class_is_omap1()) {
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Set the STOP_LNK bit */
l |= 1 << 14;
}
@@ -697,7 +634,7 @@ static inline void disable_lnk(int lch)
l &= ~(1 << 15);
}
- dma_write(l, CLNK_CTRL(lch));
+ p->dma_write(l, CLNK_CTRL, lch);
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
@@ -710,9 +647,9 @@ static inline void omap2_enable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0);
+ val = p->dma_read(IRQENABLE_L0, lch);
val |= 1 << lch;
- dma_write(val, IRQENABLE_L0);
+ p->dma_write(val, IRQENABLE_L0, lch);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -725,9 +662,9 @@ static inline void omap2_disable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0);
+ val = p->dma_read(IRQENABLE_L0, lch);
val &= ~(1 << lch);
- dma_write(val, IRQENABLE_L0);
+ p->dma_write(val, IRQENABLE_L0, lch);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -754,8 +691,8 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan = dma_chan + free_ch;
chan->dev_id = dev_id;
- if (cpu_class_is_omap1())
- clear_lch_regs(free_ch);
+ if (p->clear_lch_regs)
+ p->clear_lch_regs(free_ch);
if (cpu_class_is_omap2())
omap_clear_dma(free_ch);
@@ -792,17 +729,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
* Disable the 1510 compatibility mode and set the sync device
* id.
*/
- dma_write(dev_id | (1 << 10), CCR(free_ch));
+ p->dma_write(dev_id | (1 << 10), CCR, free_ch);
} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
- dma_write(dev_id, CCR(free_ch));
+ p->dma_write(dev_id, CCR, free_ch);
}
if (cpu_class_is_omap2()) {
omap2_enable_irq_lch(free_ch);
omap_enable_channel_irq(free_ch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch));
- dma_write(1 << free_ch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, free_ch);
+ p->dma_write(1 << free_ch, IRQSTATUS_L0, 0);
}
*dma_ch_out = free_ch;
@@ -823,23 +760,23 @@ void omap_free_dma(int lch)
if (cpu_class_is_omap1()) {
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR(lch));
+ p->dma_write(0, CCR, lch);
}
if (cpu_class_is_omap2()) {
omap2_disable_irq_lch(lch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
- dma_write(1 << lch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
+ p->dma_write(1 << lch, IRQSTATUS_L0, lch);
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR(lch));
+ p->dma_write(0, CCR, lch);
omap_clear_dma(lch);
}
@@ -880,7 +817,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
reg |= (0x3 & tparams) << 12;
reg |= (arb_rate & 0xff) << 16;
- dma_write(reg, GCR);
+ p->dma_write(reg, GCR, 0);
}
EXPORT_SYMBOL(omap_dma_set_global_params);
@@ -903,14 +840,14 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
printk(KERN_ERR "Invalid channel id\n");
return -EINVAL;
}
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~((1 << 6) | (1 << 26));
if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
else
l |= ((read_prio & 0x1) << 6);
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
return 0;
}
@@ -925,25 +862,7 @@ void omap_clear_dma(int lch)
unsigned long flags;
local_irq_save(flags);
-
- if (cpu_class_is_omap1()) {
- u32 l;
-
- l = dma_read(CCR(lch));
- l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
-
- /* Clear pending interrupts */
- l = dma_read(CSR(lch));
- }
-
- if (cpu_class_is_omap2()) {
- int i;
- void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch);
- for (i = 0; i < 0x44; i += 4)
- __raw_writel(0, lch_base + i);
- }
-
+ p->clear_dma(lch);
local_irq_restore(flags);
}
EXPORT_SYMBOL(omap_clear_dma);
@@ -957,13 +876,13 @@ void omap_start_dma(int lch)
* before starting dma transfer.
*/
if (cpu_is_omap15xx())
- dma_write(0, CPC(lch));
+ p->dma_write(0, CPC, lch);
else
- dma_write(0, CDAC(lch));
+ p->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];
+ char dma_chan_link_map[dma_lch_count];
dma_chan_link_map[lch] = 1;
/* Set the link register of the first channel */
@@ -985,32 +904,18 @@ void omap_start_dma(int lch)
cur_lch = next_lch;
} while (next_lch != -1);
- } else if (cpu_is_omap242x() ||
- (cpu_is_omap243x() && omap_type() <= OMAP2430_REV_ES1_0)) {
-
- /* Errata: Need to write lch even if not using chaining */
- dma_write(lch, CLNK_CTRL(lch));
- }
+ } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
+ p->dma_write(lch, CLNK_CTRL, lch);
omap_enable_channel_irq(lch);
- l = dma_read(CCR(lch));
-
- /*
- * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
- * OMAP2430ES1.0): DMA will wrongly buffer elements if packing and
- * bursting is enabled. This might result in data gets stalled in
- * FIFO at the end of the block.
- * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
- * guarantee no data will stay in the DMA FIFO in case inter frame
- * buffering occurs.
- */
- if (cpu_is_omap2420() ||
- (cpu_is_omap2430() && (omap_type() == OMAP2430_REV_ES1_0)))
- l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
+ l = p->dma_read(CCR, lch);
+ if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
+ l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
l |= OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+
+ p->dma_write(l, CCR, lch);
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1022,46 +927,46 @@ void omap_stop_dma(int lch)
/* Disable all interrupts on the channel */
if (cpu_class_is_omap1())
- dma_write(0, CICR(lch));
+ p->dma_write(0, CICR, lch);
- l = dma_read(CCR(lch));
- /* OMAP3 Errata i541: sDMA FIFO draining does not finish */
- if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
+ l = p->dma_read(CCR, lch);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
+ (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
int i = 0;
u32 sys_cf;
/* Configure No-Standby */
- l = dma_read(OCP_SYSCONFIG);
+ l = p->dma_read(OCP_SYSCONFIG, lch);
sys_cf = l;
l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
- dma_write(l , OCP_SYSCONFIG);
+ p->dma_write(l , OCP_SYSCONFIG, 0);
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
/* Wait for sDMA FIFO drain */
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
OMAP_DMA_CCR_WR_ACTIVE))) {
udelay(5);
i++;
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
}
if (i >= 100)
printk(KERN_ERR "DMA drain did not complete on "
"lch %d\n", lch);
/* Restore OCP_SYSCONFIG */
- dma_write(sys_cf, OCP_SYSCONFIG);
+ p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
} else {
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
}
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
- char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[dma_lch_count];
memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
do {
@@ -1122,19 +1027,15 @@ dma_addr_t omap_get_dma_src_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC(lch));
+ offset = p->dma_read(CPC, lch);
else
- offset = dma_read(CSAC(lch));
+ offset = p->dma_read(CSAC, lch);
- /*
- * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- if (!cpu_is_omap15xx() && offset == 0)
- offset = dma_read(CSAC(lch));
+ if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
+ offset = p->dma_read(CSAC, lch);
if (cpu_class_is_omap1())
- offset |= (dma_read(CSSA_U(lch)) << 16);
+ offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
return offset;
}
@@ -1153,19 +1054,19 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC(lch));
+ offset = p->dma_read(CPC, lch);
else
- offset = dma_read(CDAC(lch));
+ offset = p->dma_read(CDAC, lch);
/*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if (!cpu_is_omap15xx() && offset == 0)
- offset = dma_read(CDAC(lch));
+ offset = p->dma_read(CDAC, lch);
if (cpu_class_is_omap1())
- offset |= (dma_read(CDSA_U(lch)) << 16);
+ offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
return offset;
}
@@ -1173,7 +1074,7 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
int omap_get_dma_active_status(int lch)
{
- return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0;
+ return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
}
EXPORT_SYMBOL(omap_get_dma_active_status);
@@ -1186,7 +1087,7 @@ int omap_dma_running(void)
return 1;
for (lch = 0; lch < dma_chan_count; lch++)
- if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN)
+ if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
return 1;
return 0;
@@ -1201,8 +1102,8 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR(lch_head)) | (3 << 8),
- CCR(lch_head));
+ p->dma_write(p->dma_read(CCR, lch_head) | (3 << 8),
+ CCR, lch_head);
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1228,8 +1129,8 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
- CCR(lch_head));
+ p->dma_write(p->dma_read(CCR, lch_head) & ~(3 << 8),
+ CCR, lch_head);
return;
}
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -1255,8 +1156,6 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
}
EXPORT_SYMBOL(omap_dma_unlink_lch);
-/*----------------------------------------------------------------------------*/
-
#ifndef CONFIG_ARCH_OMAP1
/* Create chain of DMA channesls */
static void create_dma_lch_chain(int lch_head, int lch_queue)
@@ -1281,15 +1180,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
lch_queue;
}
- l = dma_read(CLNK_CTRL(lch_head));
+ l = p->dma_read(CLNK_CTRL, lch_head);
l &= ~(0x1f);
l |= lch_queue;
- dma_write(l, CLNK_CTRL(lch_head));
+ p->dma_write(l, CLNK_CTRL, lch_head);
- l = dma_read(CLNK_CTRL(lch_queue));
+ l = p->dma_read(CLNK_CTRL, lch_queue);
l &= ~(0x1f);
l |= (dma_chan[lch_queue].next_linked_ch);
- dma_write(l, CLNK_CTRL(lch_queue));
+ p->dma_write(l, CLNK_CTRL, lch_queue);
}
/**
@@ -1565,13 +1464,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Set the params to the free channel */
if (src_start != 0)
- dma_write(src_start, CSSA(lch));
+ p->dma_write(src_start, CSSA, lch);
if (dest_start != 0)
- dma_write(dest_start, CDSA(lch));
+ p->dma_write(dest_start, CDSA, lch);
/* Write the buffer size */
- dma_write(elem_count, CEN(lch));
- dma_write(frame_count, CFN(lch));
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
/*
* If the chain is dynamically linked,
@@ -1604,8 +1503,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
enable_lnk(dma_chan[lch].prev_linked_ch);
dma_chan[lch].state = DMA_CH_QUEUED;
start_dma = 0;
- if (0 == ((1 << 7) & dma_read(
- CCR(dma_chan[lch].prev_linked_ch)))) {
+ if (0 == ((1 << 7) & p->dma_read(
+ CCR, dma_chan[lch].prev_linked_ch))) {
disable_lnk(dma_chan[lch].
prev_linked_ch);
pr_debug("\n prev ch is stopped\n");
@@ -1621,7 +1520,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
}
omap_enable_channel_irq(lch);
- l = dma_read(CCR(lch));
+ l = p->dma_read(CCR, lch);
if ((0 == (l & (1 << 24))))
l &= ~(1 << 25);
@@ -1632,12 +1531,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
l |= (1 << 7);
dma_chan[lch].state = DMA_CH_STARTED;
pr_debug("starting %d\n", lch);
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
} else
start_dma = 0;
} else {
if (0 == (l & (1 << 7)))
- dma_write(l, CCR(lch));
+ p->dma_write(l, CCR, lch);
}
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1682,7 +1581,7 @@ int omap_start_dma_chain_transfers(int chain_id)
omap_enable_channel_irq(channels[0]);
}
- l = dma_read(CCR(channels[0]));
+ l = p->dma_read(CCR, channels[0]);
l |= (1 << 7);
dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
dma_chan[channels[0]].state = DMA_CH_STARTED;
@@ -1691,7 +1590,7 @@ int omap_start_dma_chain_transfers(int chain_id)
l &= ~(1 << 25);
else
l |= (1 << 25);
- dma_write(l, CCR(channels[0]));
+ p->dma_write(l, CCR, channels[0]);
dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
@@ -1711,7 +1610,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
{
int *channels;
u32 l, i;
- u32 sys_cf;
+ u32 sys_cf = 0;
/* Check for input params */
if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1726,22 +1625,20 @@ int omap_stop_dma_chain_transfers(int chain_id)
}
channels = dma_linked_lch[chain_id].linked_dmach_q;
- /*
- * DMA Errata:
- * Special programming model needed to disable DMA before end of block
- */
- sys_cf = dma_read(OCP_SYSCONFIG);
- l = sys_cf;
- /* Middle mode reg set no Standby */
- l &= ~((1 << 12)|(1 << 13));
- dma_write(l, OCP_SYSCONFIG);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
+ sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
+ l = sys_cf;
+ /* Middle mode reg set no Standby */
+ l &= ~((1 << 12)|(1 << 13));
+ p->dma_write(l, OCP_SYSCONFIG, 0);
+ }
for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
/* Stop the Channel transmission */
- l = dma_read(CCR(channels[i]));
+ l = p->dma_read(CCR, channels[i]);
l &= ~(1 << 7);
- dma_write(l, CCR(channels[i]));
+ p->dma_write(l, CCR, channels[i]);
/* Disable the link in all the channels */
disable_lnk(channels[i]);
@@ -1753,8 +1650,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
/* Reset the Queue pointers */
OMAP_DMA_CHAIN_QINIT(chain_id);
- /* Errata - put in the old value */
- dma_write(sys_cf, OCP_SYSCONFIG);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88))
+ p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
return 0;
}
@@ -1796,8 +1693,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- *ei = dma_read(CCEN(lch));
- *fi = dma_read(CCFN(lch));
+ *ei = p->dma_read(CCEN, lch);
+ *fi = p->dma_read(CCFN, lch);
return 0;
}
@@ -1834,7 +1731,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CDAC(lch));
+ return p->dma_read(CDAC, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
@@ -1868,7 +1765,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CSAC(lch));
+ return p->dma_read(CSAC, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
#endif /* ifndef CONFIG_ARCH_OMAP1 */
@@ -1885,7 +1782,7 @@ static int omap1_dma_handle_ch(int ch)
csr = dma_chan[ch].saved_csr;
dma_chan[ch].saved_csr = 0;
} else
- csr = dma_read(CSR(ch));
+ csr = p->dma_read(CSR, ch);
if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
dma_chan[ch + 6].saved_csr = csr >> 7;
csr &= 0x7f;
@@ -1938,13 +1835,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
static int omap2_dma_handle_ch(int ch)
{
- u32 status = dma_read(CSR(ch));
+ u32 status = p->dma_read(CSR, ch);
if (!status) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
ch);
- dma_write(1 << ch, IRQSTATUS_L0);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
return 0;
}
if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -1960,17 +1857,12 @@ static int omap2_dma_handle_ch(int ch)
if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
printk(KERN_INFO "DMA transaction error with device %d\n",
dma_chan[ch].dev_id);
- if (cpu_class_is_omap2()) {
- /*
- * Errata: sDMA Channel is not disabled
- * after a transaction error. So we explicitely
- * disable the channel
- */
+ if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
u32 ccr;
- ccr = dma_read(CCR(ch));
+ ccr = p->dma_read(CCR, ch);
ccr &= ~OMAP_DMA_CCR_EN;
- dma_write(ccr, CCR(ch));
+ p->dma_write(ccr, CCR, ch);
dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
}
}
@@ -1981,16 +1873,16 @@ static int omap2_dma_handle_ch(int ch)
printk(KERN_INFO "DMA misaligned error with device %d\n",
dma_chan[ch].dev_id);
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
- dma_write(1 << ch, IRQSTATUS_L0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
/* read back the register to flush the write */
- dma_read(IRQSTATUS_L0);
+ p->dma_read(IRQSTATUS_L0, ch);
/* If the ch is not chained then chain_id will be -1 */
if (dma_chan[ch].chain_id != -1) {
int chain_id = dma_chan[ch].chain_id;
dma_chan[ch].state = DMA_CH_NOTSTARTED;
- if (dma_read(CLNK_CTRL(ch)) & (1 << 15))
+ if (p->dma_read(CLNK_CTRL, ch) & (1 << 15))
dma_chan[dma_chan[ch].next_linked_ch].state =
DMA_CH_STARTED;
if (dma_linked_lch[chain_id].chain_mode ==
@@ -2000,10 +1892,10 @@ static int omap2_dma_handle_ch(int ch)
if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
OMAP_DMA_CHAIN_INCQHEAD(chain_id);
- status = dma_read(CSR(ch));
+ status = p->dma_read(CSR, ch);
}
- dma_write(status, CSR(ch));
+ p->dma_write(status, CSR, ch);
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, status, dma_chan[ch].data);
@@ -2017,13 +1909,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
u32 val, enable_reg;
int i;
- val = dma_read(IRQSTATUS_L0);
+ val = p->dma_read(IRQSTATUS_L0, 0);
if (val == 0) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ\n");
return IRQ_HANDLED;
}
- enable_reg = dma_read(IRQENABLE_L0);
+ enable_reg = p->dma_read(IRQENABLE_L0, 0);
val &= enable_reg; /* Dispatch only relevant interrupts */
for (i = 0; i < dma_lch_count && val != 0; i++) {
if (val & 1)
@@ -2049,119 +1941,66 @@ static struct irqaction omap24xx_dma_irq;
void omap_dma_global_context_save(void)
{
omap_dma_global_context.dma_irqenable_l0 =
- dma_read(IRQENABLE_L0);
+ p->dma_read(IRQENABLE_L0, 0);
omap_dma_global_context.dma_ocp_sysconfig =
- dma_read(OCP_SYSCONFIG);
- omap_dma_global_context.dma_gcr = dma_read(GCR);
+ p->dma_read(OCP_SYSCONFIG, 0);
+ omap_dma_global_context.dma_gcr = p->dma_read(GCR, 0);
}
void omap_dma_global_context_restore(void)
{
int ch;
- dma_write(omap_dma_global_context.dma_gcr, GCR);
- dma_write(omap_dma_global_context.dma_ocp_sysconfig,
- OCP_SYSCONFIG);
- dma_write(omap_dma_global_context.dma_irqenable_l0,
- IRQENABLE_L0);
+ p->dma_write(omap_dma_global_context.dma_gcr, GCR, 0);
+ p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+ OCP_SYSCONFIG, 0);
+ p->dma_write(omap_dma_global_context.dma_irqenable_l0,
+ IRQENABLE_L0, 0);
- /*
- * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
- * after secure sram context save and restore. Hence we need to
- * manually clear those IRQs to avoid spurious interrupts. This
- * affects only secure devices.
- */
- if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
- dma_write(0x3 , IRQSTATUS_L0);
+ if (IS_DMA_ERRATA(DMA_ROMCODE_BUG))
+ p->dma_write(0x3 , IRQSTATUS_L0, 0);
for (ch = 0; ch < dma_chan_count; ch++)
if (dma_chan[ch].dev_id != -1)
omap_clear_dma(ch);
}
-/*----------------------------------------------------------------------------*/
-
-static int __init omap_init_dma(void)
+static int __devinit omap_system_dma_probe(struct platform_device *pdev)
{
- unsigned long base;
- int ch, r;
-
- if (cpu_class_is_omap1()) {
- base = OMAP1_DMA_BASE;
- dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap24xx()) {
- base = OMAP24XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap34xx()) {
- base = OMAP34XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap44xx()) {
- base = OMAP44XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else {
- pr_err("DMA init failed for unsupported omap\n");
- return -ENODEV;
+ int ch, ret = 0;
+ int dma_irq;
+ char irq_name[4];
+ int irq_rel;
+
+ p = pdev->dev.platform_data;
+ if (!p) {
+ dev_err(&pdev->dev, "%s: System DMA initialized without"
+ "platform data\n", __func__);
+ return -EINVAL;
}
- omap_dma_base = ioremap(base, SZ_4K);
- BUG_ON(!omap_dma_base);
+ d = p->dma_attr;
+ errata = p->errata;
- if (cpu_class_is_omap2() && omap_dma_reserve_channels
+ if ((d->dev_caps & RESERVE_CHANNEL) && omap_dma_reserve_channels
&& (omap_dma_reserve_channels <= dma_lch_count))
- dma_lch_count = omap_dma_reserve_channels;
+ d->lch_count = omap_dma_reserve_channels;
- dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
- GFP_KERNEL);
- if (!dma_chan) {
- r = -ENOMEM;
- goto out_unmap;
- }
+ dma_lch_count = d->lch_count;
+ dma_chan_count = dma_lch_count;
+ dma_chan = d->chan;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
if (cpu_class_is_omap2()) {
dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
dma_lch_count, GFP_KERNEL);
if (!dma_linked_lch) {
- r = -ENOMEM;
- goto out_free;
+ ret = -ENOMEM;
+ goto exit_dma_lch_fail;
}
}
- if (cpu_is_omap15xx()) {
- printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
- dma_chan_count = 9;
- enable_1510_mode = 1;
- } else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
- printk(KERN_INFO "OMAP DMA hardware version %d\n",
- dma_read(HW_ID));
- printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (dma_read(CAPS_0_U) << 16) |
- dma_read(CAPS_0_L),
- (dma_read(CAPS_1_U) << 16) |
- dma_read(CAPS_1_L),
- dma_read(CAPS_2), dma_read(CAPS_3),
- dma_read(CAPS_4));
- if (!enable_1510_mode) {
- u16 w;
-
- /* Disable OMAP 3.0/3.1 compatibility mode. */
- w = dma_read(GSCR);
- w |= 1 << 3;
- dma_write(w, GSCR);
- dma_chan_count = 16;
- } else
- dma_chan_count = 9;
- } else if (cpu_class_is_omap2()) {
- u8 revision = dma_read(REVISION) & 0xff;
- printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
- revision >> 4, revision & 0xf);
- dma_chan_count = dma_lch_count;
- } else {
- dma_chan_count = 0;
- return 0;
- }
-
spin_lock_init(&dma_chan_lock);
-
for (ch = 0; ch < dma_chan_count; ch++) {
omap_clear_dma(ch);
if (cpu_class_is_omap2())
@@ -2178,20 +2017,23 @@ static int __init omap_init_dma(void)
* request_irq() doesn't like dev_id (ie. ch) being
* zero, so we have to kludge around this.
*/
- r = request_irq(omap1_dma_irq[ch],
+ sprintf(&irq_name[0], "%d", ch);
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+
+ if (dma_irq < 0) {
+ ret = dma_irq;
+ goto exit_dma_irq_fail;
+ }
+
+ /* INT_DMA_LCD is handled in lcd_dma.c */
+ if (dma_irq == INT_DMA_LCD)
+ continue;
+
+ ret = request_irq(dma_irq,
omap1_dma_irq_handler, 0, "DMA",
(void *) (ch + 1));
- if (r != 0) {
- int i;
-
- printk(KERN_ERR "unable to request IRQ %d "
- "for DMA (error %d)\n",
- omap1_dma_irq[ch], r);
- for (i = 0; i < ch; i++)
- free_irq(omap1_dma_irq[i],
- (void *) (i + 1));
- goto out_free;
- }
+ if (ret != 0)
+ goto exit_dma_irq_fail;
}
}
@@ -2200,46 +2042,91 @@ static int __init omap_init_dma(void)
DMA_DEFAULT_FIFO_DEPTH, 0);
if (cpu_class_is_omap2()) {
- int irq;
- if (cpu_is_omap44xx())
- irq = OMAP44XX_IRQ_SDMA_0;
- else
- irq = INT_24XX_SDMA_IRQ0;
- setup_irq(irq, &omap24xx_dma_irq);
- }
-
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- /* Enable smartidle idlemodes and autoidle */
- u32 v = dma_read(OCP_SYSCONFIG);
- v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
- DMA_SYSCONFIG_SIDLEMODE_MASK |
- DMA_SYSCONFIG_AUTOIDLE);
- v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_AUTOIDLE);
- dma_write(v , OCP_SYSCONFIG);
- /* reserve dma channels 0 and 1 in high security devices */
- if (cpu_is_omap34xx() &&
- (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
- printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
- "HS ROM code\n");
- dma_chan[0].dev_id = 0;
- dma_chan[1].dev_id = 1;
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ if (dma_irq < 0) {
+ dev_err(&pdev->dev, "failed: request IRQ %d", dma_irq);
+ goto exit_dma_lch_fail;
+ }
+ ret = setup_irq(dma_irq, &omap24xx_dma_irq);
+ if (ret) {
+ dev_err(&pdev->dev, "set_up failed for IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ goto exit_dma_lch_fail;
}
}
+ /* reserve dma channels 0 and 1 in high security devices */
+ if (cpu_is_omap34xx() &&
+ (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+ "HS ROM code\n");
+ dma_chan[0].dev_id = 0;
+ dma_chan[1].dev_id = 1;
+ }
+ p->show_dma_caps();
return 0;
-out_free:
+exit_dma_irq_fail:
+ dev_err(&pdev->dev, "unable to request IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ for (irq_rel = 0; irq_rel < ch; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+
+exit_dma_lch_fail:
+ kfree(p);
+ kfree(d);
kfree(dma_chan);
+ return ret;
+}
-out_unmap:
- iounmap(omap_dma_base);
+static int __devexit omap_system_dma_remove(struct platform_device *pdev)
+{
+ int dma_irq;
- return r;
+ if (cpu_class_is_omap2()) {
+ char irq_name[4];
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ remove_irq(dma_irq, &omap24xx_dma_irq);
+ } else {
+ int irq_rel = 0;
+ for ( ; irq_rel < dma_chan_count; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+ }
+ kfree(p);
+ kfree(d);
+ kfree(dma_chan);
+ return 0;
+}
+
+static struct platform_driver omap_system_dma_driver = {
+ .probe = omap_system_dma_probe,
+ .remove = omap_system_dma_remove,
+ .driver = {
+ .name = "omap_dma_system"
+ },
+};
+
+static int __init omap_system_dma_init(void)
+{
+ return platform_driver_register(&omap_system_dma_driver);
+}
+arch_initcall(omap_system_dma_init);
+
+static void __exit omap_system_dma_exit(void)
+{
+ platform_driver_unregister(&omap_system_dma_driver);
}
-arch_initcall(omap_init_dma);
+MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
/*
* Reserve the omap SDMA channels using cmdline bootarg
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index c05c653d1674..1f98e0b94847 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -21,18 +21,18 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/irqs.h>
#include <mach/gpio.h>
#include <asm/mach/irq.h>
-#include <plat/powerdomain.h>
/*
* OMAP1510 GPIO registers
*/
-#define OMAP1510_GPIO_BASE 0xfffce000
#define OMAP1510_GPIO_DATA_INPUT 0x00
#define OMAP1510_GPIO_DATA_OUTPUT 0x04
#define OMAP1510_GPIO_DIR_CONTROL 0x08
@@ -46,10 +46,6 @@
/*
* OMAP1610 specific GPIO registers
*/
-#define OMAP1610_GPIO1_BASE 0xfffbe400
-#define OMAP1610_GPIO2_BASE 0xfffbec00
-#define OMAP1610_GPIO3_BASE 0xfffbb400
-#define OMAP1610_GPIO4_BASE 0xfffbbc00
#define OMAP1610_GPIO_REVISION 0x0000
#define OMAP1610_GPIO_SYSCONFIG 0x0010
#define OMAP1610_GPIO_SYSSTATUS 0x0014
@@ -71,12 +67,6 @@
/*
* OMAP7XX specific GPIO registers
*/
-#define OMAP7XX_GPIO1_BASE 0xfffbc000
-#define OMAP7XX_GPIO2_BASE 0xfffbc800
-#define OMAP7XX_GPIO3_BASE 0xfffbd000
-#define OMAP7XX_GPIO4_BASE 0xfffbd800
-#define OMAP7XX_GPIO5_BASE 0xfffbe000
-#define OMAP7XX_GPIO6_BASE 0xfffbe800
#define OMAP7XX_GPIO_DATA_INPUT 0x00
#define OMAP7XX_GPIO_DATA_OUTPUT 0x04
#define OMAP7XX_GPIO_DIR_CONTROL 0x08
@@ -84,25 +74,10 @@
#define OMAP7XX_GPIO_INT_MASK 0x10
#define OMAP7XX_GPIO_INT_STATUS 0x14
-#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
-
/*
- * omap24xx specific GPIO registers
+ * omap2+ specific GPIO registers
*/
-#define OMAP242X_GPIO1_BASE 0x48018000
-#define OMAP242X_GPIO2_BASE 0x4801a000
-#define OMAP242X_GPIO3_BASE 0x4801c000
-#define OMAP242X_GPIO4_BASE 0x4801e000
-
-#define OMAP243X_GPIO1_BASE 0x4900C000
-#define OMAP243X_GPIO2_BASE 0x4900E000
-#define OMAP243X_GPIO3_BASE 0x49010000
-#define OMAP243X_GPIO4_BASE 0x49012000
-#define OMAP243X_GPIO5_BASE 0x480B6000
-
#define OMAP24XX_GPIO_REVISION 0x0000
-#define OMAP24XX_GPIO_SYSCONFIG 0x0010
-#define OMAP24XX_GPIO_SYSSTATUS 0x0014
#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
#define OMAP24XX_GPIO_IRQENABLE2 0x002c
@@ -126,7 +101,6 @@
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
#define OMAP4_GPIO_REVISION 0x0000
-#define OMAP4_GPIO_SYSCONFIG 0x0010
#define OMAP4_GPIO_EOI 0x0020
#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
@@ -138,7 +112,6 @@
#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
#define OMAP4_GPIO_IRQWAKEN0 0x0044
#define OMAP4_GPIO_IRQWAKEN1 0x0048
-#define OMAP4_GPIO_SYSSTATUS 0x0114
#define OMAP4_GPIO_IRQENABLE1 0x011c
#define OMAP4_GPIO_WAKE_EN 0x0120
#define OMAP4_GPIO_IRQSTATUS2 0x0128
@@ -159,26 +132,6 @@
#define OMAP4_GPIO_SETWKUENA 0x0184
#define OMAP4_GPIO_CLEARDATAOUT 0x0190
#define OMAP4_GPIO_SETDATAOUT 0x0194
-/*
- * omap34xx specific GPIO registers
- */
-
-#define OMAP34XX_GPIO1_BASE 0x48310000
-#define OMAP34XX_GPIO2_BASE 0x49050000
-#define OMAP34XX_GPIO3_BASE 0x49052000
-#define OMAP34XX_GPIO4_BASE 0x49054000
-#define OMAP34XX_GPIO5_BASE 0x49056000
-#define OMAP34XX_GPIO6_BASE 0x49058000
-
-/*
- * OMAP44XX specific GPIO registers
- */
-#define OMAP44XX_GPIO1_BASE 0x4a310000
-#define OMAP44XX_GPIO2_BASE 0x48055000
-#define OMAP44XX_GPIO3_BASE 0x48057000
-#define OMAP44XX_GPIO4_BASE 0x48059000
-#define OMAP44XX_GPIO5_BASE 0x4805B000
-#define OMAP44XX_GPIO6_BASE 0x4805D000
struct gpio_bank {
unsigned long pbase;
@@ -190,14 +143,12 @@ struct gpio_bank {
u32 suspend_wakeup;
u32 saved_wakeup;
#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
u32 non_wakeup_gpios;
u32 enabled_non_wakeup_gpios;
u32 saved_datain;
u32 saved_fallingdetect;
u32 saved_risingdetect;
-#endif
u32 level_mask;
u32 toggle_mask;
spinlock_t lock;
@@ -205,104 +156,13 @@ struct gpio_bank {
struct clk *dbck;
u32 mod_usage;
u32 dbck_enable_mask;
+ struct device *dev;
+ bool dbck_flag;
+ int stride;
};
-#define METHOD_MPUIO 0
-#define METHOD_GPIO_1510 1
-#define METHOD_GPIO_1610 2
-#define METHOD_GPIO_7XX 3
-#define METHOD_GPIO_24XX 5
-#define METHOD_GPIO_44XX 6
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static struct gpio_bank gpio_bank_1610[5] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32,
- METHOD_GPIO_1610 },
- { OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48,
- METHOD_GPIO_1610 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP15XX
-static struct gpio_bank gpio_bank_1510[2] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_1510 }
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-static struct gpio_bank gpio_bank_7xx[7] = {
- { OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE,
- METHOD_MPUIO },
- { OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_7XX },
- { OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6, IH_GPIO_BASE + 160,
- METHOD_GPIO_7XX },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
-
-static struct gpio_bank gpio_bank_242x[4] = {
- { OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
-};
-
-static struct gpio_bank gpio_bank_243x[5] = {
- { OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
- { OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_24XX },
-};
-
-#endif
-
#ifdef CONFIG_ARCH_OMAP3
-static struct gpio_bank gpio_bank_34xx[6] = {
- { OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO2_BASE, NULL, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO3_BASE, NULL, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO4_BASE, NULL, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO5_BASE, NULL, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128,
- METHOD_GPIO_24XX },
- { OMAP34XX_GPIO6_BASE, NULL, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160,
- METHOD_GPIO_24XX },
-};
-
struct omap3_gpio_regs {
- u32 sysconfig;
u32 irqenable1;
u32 irqenable2;
u32 wake_en;
@@ -318,26 +178,16 @@ struct omap3_gpio_regs {
static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
#endif
-#ifdef CONFIG_ARCH_OMAP4
-static struct gpio_bank gpio_bank_44xx[6] = {
- { OMAP44XX_GPIO1_BASE, NULL, OMAP44XX_IRQ_GPIO1, IH_GPIO_BASE,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO2_BASE, NULL, OMAP44XX_IRQ_GPIO2, IH_GPIO_BASE + 32,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO3_BASE, NULL, OMAP44XX_IRQ_GPIO3, IH_GPIO_BASE + 64,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO4_BASE, NULL, OMAP44XX_IRQ_GPIO4, IH_GPIO_BASE + 96,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO5_BASE, NULL, OMAP44XX_IRQ_GPIO5, IH_GPIO_BASE + 128,
- METHOD_GPIO_44XX },
- { OMAP44XX_GPIO6_BASE, NULL, OMAP44XX_IRQ_GPIO6, IH_GPIO_BASE + 160,
- METHOD_GPIO_44XX },
-};
+/*
+ * TODO: Cleanup gpio_bank usage as it is having information
+ * related to all instances of the device
+ */
+static struct gpio_bank *gpio_bank;
-#endif
+static int bank_width;
-static struct gpio_bank *gpio_bank;
-static int gpio_bank_count;
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+int gpio_bank_count;
static inline struct gpio_bank *get_gpio_bank(int gpio)
{
@@ -417,7 +267,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_IO_CNTL;
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -465,7 +315,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_OUTPUT;
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
l = __raw_readl(reg);
if (enable)
l |= 1 << gpio;
@@ -537,7 +387,7 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_INPUT_LATCH;
+ reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -583,7 +433,7 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_OUTPUT;
+ reg += OMAP_MPUIO_OUTPUT / bank->stride;
break;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
@@ -642,6 +492,9 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
u32 val;
u32 l;
+ if (!bank->dbck_flag)
+ return;
+
if (debounce < 32)
debounce = 0x01;
else if (debounce > 7936)
@@ -651,7 +504,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
l = 1 << get_gpio_index(gpio);
- if (cpu_is_omap44xx())
+ if (bank->method == METHOD_GPIO_44XX)
reg += OMAP4_GPIO_DEBOUNCINGTIME;
else
reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
@@ -659,7 +512,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
__raw_writel(debounce, reg);
reg = bank->base;
- if (cpu_is_omap44xx())
+ if (bank->method == METHOD_GPIO_44XX)
reg += OMAP4_GPIO_DEBOUNCENABLE;
else
reg += OMAP24XX_GPIO_DEBOUNCE_EN;
@@ -668,12 +521,10 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
if (debounce) {
val |= l;
- if (cpu_is_omap34xx() || cpu_is_omap44xx())
- clk_enable(bank->dbck);
+ clk_enable(bank->dbck);
} else {
val &= ~l;
- if (cpu_is_omap34xx() || cpu_is_omap44xx())
- clk_disable(bank->dbck);
+ clk_disable(bank->dbck);
}
bank->dbck_enable_mask = val;
@@ -769,7 +620,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_INT_EDGE;
+ reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
break;
#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
@@ -803,7 +654,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_INT_EDGE;
+ reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
l = __raw_readl(reg);
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
@@ -989,7 +840,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_MASKIT;
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
mask = 0xffff;
inv = 1;
break;
@@ -1046,7 +897,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
switch (bank->method) {
#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_MASKIT;
+ reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
l = __raw_readl(reg);
if (enable)
l &= ~(gpio_mask);
@@ -1296,7 +1147,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
bank = get_irq_data(irq);
#ifdef CONFIG_ARCH_OMAP1
if (bank->method == METHOD_MPUIO)
- isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
+ isr_reg = bank->base +
+ OMAP_MPUIO_GPIO_INT / bank->stride;
#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510)
@@ -1318,6 +1170,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (bank->method == METHOD_GPIO_44XX)
isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
#endif
+
+ if (WARN_ON(!isr_reg))
+ goto exit;
+
while(1) {
u32 isr_saved, level_mask = 0;
u32 enabled;
@@ -1377,6 +1233,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
configured, we must unmask the bank interrupt only after
handler(s) are executed in order to avoid spurious bank
interrupt */
+exit:
if (!unmasked)
desc->chip->unmask(irq);
@@ -1489,7 +1346,8 @@ static int omap_mpuio_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_bank *bank = platform_get_drvdata(pdev);
- void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+ void __iomem *mask_reg = bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride;
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
@@ -1504,7 +1362,8 @@ static int omap_mpuio_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_bank *bank = platform_get_drvdata(pdev);
- void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+ void __iomem *mask_reg = bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride;
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
@@ -1540,7 +1399,8 @@ static struct platform_device omap_mpuio_device = {
static inline void mpuio_init(void)
{
- platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]);
+ struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+ platform_set_drvdata(&omap_mpuio_device, bank);
if (platform_driver_register(&omap_mpuio_driver) == 0)
(void) platform_device_register(&omap_mpuio_device);
@@ -1583,7 +1443,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_IO_CNTL;
+ reg += OMAP_MPUIO_IO_CNTL / bank->stride;
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DIR_CONTROL;
@@ -1645,6 +1505,13 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
unsigned long flags;
bank = container_of(chip, struct gpio_bank, chip);
+
+ if (!bank->dbck) {
+ bank->dbck = clk_get(bank->dev, "dbclk");
+ if (IS_ERR(bank->dbck))
+ dev_err(bank->dev, "Could not get gpio dbck\n");
+ }
+
spin_lock_irqsave(&bank->lock, flags);
_set_gpio_debounce(bank, offset, debounce);
spin_unlock_irqrestore(&bank->lock, flags);
@@ -1673,34 +1540,16 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
/*---------------------------------------------------------------------*/
-static int initialized;
-#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_ick;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2430)
-static struct clk * gpio5_ick;
-static struct clk * gpio5_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
-#endif
-
-static void __init omap_gpio_show_rev(void)
+static void __init omap_gpio_show_rev(struct gpio_bank *bank)
{
u32 rev;
- if (cpu_is_omap16xx())
- rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+ if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
+ rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
else if (cpu_is_omap24xx() || cpu_is_omap34xx())
- rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
else if (cpu_is_omap44xx())
- rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
+ rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
else
return;
@@ -1713,250 +1562,190 @@ static void __init omap_gpio_show_rev(void)
*/
static struct lock_class_key gpio_lock_class;
-static int __init _omap_gpio_init(void)
+static inline int init_gpio_info(struct platform_device *pdev)
{
- int i;
- int gpio = 0;
- struct gpio_bank *bank;
- int bank_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
- char clk_name[11];
-
- initialized = 1;
-
-#if defined(CONFIG_ARCH_OMAP1)
- if (cpu_is_omap15xx()) {
- gpio_ick = clk_get(NULL, "arm_gpio_ck");
- if (IS_ERR(gpio_ick))
- printk("Could not get arm_gpio_ck\n");
- else
- clk_enable(gpio_ick);
+ /* TODO: Analyze removing gpio_bank_count usage from driver code */
+ gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
+ GFP_KERNEL);
+ if (!gpio_bank) {
+ dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+ return -ENOMEM;
}
-#endif
-#if defined(CONFIG_ARCH_OMAP2)
- if (cpu_class_is_omap2()) {
- gpio_ick = clk_get(NULL, "gpios_ick");
- if (IS_ERR(gpio_ick))
- printk("Could not get gpios_ick\n");
- else
- clk_enable(gpio_ick);
- gpio_fck = clk_get(NULL, "gpios_fck");
- if (IS_ERR(gpio_fck))
- printk("Could not get gpios_fck\n");
- else
- clk_enable(gpio_fck);
+ return 0;
+}
- /*
- * On 2430 & 3430 GPIO 5 uses CORE L4 ICLK
- */
-#if defined(CONFIG_ARCH_OMAP2430)
- if (cpu_is_omap2430()) {
- gpio5_ick = clk_get(NULL, "gpio5_ick");
- if (IS_ERR(gpio5_ick))
- printk("Could not get gpio5_ick\n");
- else
- clk_enable(gpio5_ick);
- gpio5_fck = clk_get(NULL, "gpio5_fck");
- if (IS_ERR(gpio5_fck))
- printk("Could not get gpio5_fck\n");
- else
- clk_enable(gpio5_fck);
+/* TODO: Cleanup cpu_is_* checks */
+static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
+{
+ if (cpu_class_is_omap2()) {
+ if (cpu_is_omap44xx()) {
+ __raw_writel(0xffffffff, bank->base +
+ OMAP4_GPIO_IRQSTATUSCLR0);
+ __raw_writel(0x00000000, bank->base +
+ OMAP4_GPIO_DEBOUNCENABLE);
+ /* Initialize interface clk ungated, module enabled */
+ __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
+ } else if (cpu_is_omap34xx()) {
+ __raw_writel(0x00000000, bank->base +
+ OMAP24XX_GPIO_IRQENABLE1);
+ __raw_writel(0xffffffff, bank->base +
+ OMAP24XX_GPIO_IRQSTATUS1);
+ __raw_writel(0x00000000, bank->base +
+ OMAP24XX_GPIO_DEBOUNCE_EN);
+
+ /* Initialize interface clk ungated, module enabled */
+ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+ } else if (cpu_is_omap24xx()) {
+ static const u32 non_wakeup_gpios[] = {
+ 0xe203ffc0, 0x08700040
+ };
+ if (id < ARRAY_SIZE(non_wakeup_gpios))
+ bank->non_wakeup_gpios = non_wakeup_gpios[id];
}
-#endif
- }
-#endif
+ } else if (cpu_class_is_omap1()) {
+ if (bank_is_mpuio(bank))
+ __raw_writew(0xffff, bank->base +
+ OMAP_MPUIO_GPIO_MASKIT / bank->stride);
+ if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
+ __raw_writew(0xffff, bank->base
+ + OMAP1510_GPIO_INT_MASK);
+ __raw_writew(0x0000, bank->base
+ + OMAP1510_GPIO_INT_STATUS);
+ }
+ if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
+ __raw_writew(0x0000, bank->base
+ + OMAP1610_GPIO_IRQENABLE1);
+ __raw_writew(0xffff, bank->base
+ + OMAP1610_GPIO_IRQSTATUS1);
+ __raw_writew(0x0014, bank->base
+ + OMAP1610_GPIO_SYSCONFIG);
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- for (i = 0; i < OMAP34XX_NR_GPIOS; i++) {
- sprintf(clk_name, "gpio%d_ick", i + 1);
- gpio_iclks[i] = clk_get(NULL, clk_name);
- if (IS_ERR(gpio_iclks[i]))
- printk(KERN_ERR "Could not get %s\n", clk_name);
- else
- clk_enable(gpio_iclks[i]);
+ /*
+ * Enable system clock for GPIO module.
+ * The CAM_CLK_CTRL *is* really the right place.
+ */
+ omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+ ULPD_CAM_CLK_CTRL);
+ }
+ if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
+ __raw_writel(0xffffffff, bank->base
+ + OMAP7XX_GPIO_INT_MASK);
+ __raw_writel(0x00000000, bank->base
+ + OMAP7XX_GPIO_INT_STATUS);
}
}
-#endif
+}
+static void __init omap_gpio_chip_init(struct gpio_bank *bank)
+{
+ int j;
+ static int gpio;
-#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx()) {
- gpio_bank_count = 2;
- gpio_bank = gpio_bank_1510;
- bank_size = SZ_2K;
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
- if (cpu_is_omap16xx()) {
- gpio_bank_count = 5;
- gpio_bank = gpio_bank_1610;
- bank_size = SZ_2K;
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
- if (cpu_is_omap7xx()) {
- gpio_bank_count = 7;
- gpio_bank = gpio_bank_7xx;
- bank_size = SZ_2K;
- }
-#endif
-#ifdef CONFIG_ARCH_OMAP2
- if (cpu_is_omap242x()) {
- gpio_bank_count = 4;
- gpio_bank = gpio_bank_242x;
- }
- if (cpu_is_omap243x()) {
- gpio_bank_count = 5;
- gpio_bank = gpio_bank_243x;
- }
+ bank->mod_usage = 0;
+ /*
+ * REVISIT eventually switch from OMAP-specific gpio structs
+ * over to the generic ones
+ */
+ bank->chip.request = omap_gpio_request;
+ bank->chip.free = omap_gpio_free;
+ bank->chip.direction_input = gpio_input;
+ bank->chip.get = gpio_get;
+ bank->chip.direction_output = gpio_output;
+ bank->chip.set_debounce = gpio_debounce;
+ bank->chip.set = gpio_set;
+ bank->chip.to_irq = gpio_2irq;
+ if (bank_is_mpuio(bank)) {
+ bank->chip.label = "mpuio";
+#ifdef CONFIG_ARCH_OMAP16XX
+ bank->chip.dev = &omap_mpuio_device.dev;
#endif
-#ifdef CONFIG_ARCH_OMAP3
- if (cpu_is_omap34xx()) {
- gpio_bank_count = OMAP34XX_NR_GPIOS;
- gpio_bank = gpio_bank_34xx;
+ bank->chip.base = OMAP_MPUIO(0);
+ } else {
+ bank->chip.label = "gpio";
+ bank->chip.base = gpio;
+ gpio += bank_width;
}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
- if (cpu_is_omap44xx()) {
- gpio_bank_count = OMAP34XX_NR_GPIOS;
- gpio_bank = gpio_bank_44xx;
+ bank->chip.ngpio = bank_width;
+
+ gpiochip_add(&bank->chip);
+
+ for (j = bank->virtual_irq_start;
+ j < bank->virtual_irq_start + bank_width; j++) {
+ lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
+ set_irq_chip_data(j, bank);
+ if (bank_is_mpuio(bank))
+ set_irq_chip(j, &mpuio_irq_chip);
+ else
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_simple_irq);
+ set_irq_flags(j, IRQF_VALID);
}
-#endif
- for (i = 0; i < gpio_bank_count; i++) {
- int j, gpio_count = 16;
+ set_irq_chained_handler(bank->irq, gpio_irq_handler);
+ set_irq_data(bank->irq, bank);
+}
+
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
+{
+ static int gpio_init_done;
+ struct omap_gpio_platform_data *pdata;
+ struct resource *res;
+ int id;
+ struct gpio_bank *bank;
- bank = &gpio_bank[i];
- spin_lock_init(&bank->lock);
+ if (!pdev->dev.platform_data)
+ return -EINVAL;
- /* Static mapping, never released */
- bank->base = ioremap(bank->pbase, bank_size);
- if (!bank->base) {
- printk(KERN_ERR "Could not ioremap gpio bank%i\n", i);
- continue;
- }
+ pdata = pdev->dev.platform_data;
- if (bank_is_mpuio(bank))
- __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
- if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
- __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
- __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
- }
- if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
- __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
- __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
- __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
- }
- if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
- __raw_writel(0xffffffff, bank->base + OMAP7XX_GPIO_INT_MASK);
- __raw_writel(0x00000000, bank->base + OMAP7XX_GPIO_INT_STATUS);
+ if (!gpio_init_done) {
+ int ret;
- gpio_count = 32; /* 7xx has 32-bit GPIOs */
- }
+ ret = init_gpio_info(pdev);
+ if (ret)
+ return ret;
+ }
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if ((bank->method == METHOD_GPIO_24XX) ||
- (bank->method == METHOD_GPIO_44XX)) {
- static const u32 non_wakeup_gpios[] = {
- 0xe203ffc0, 0x08700040
- };
+ id = pdev->id;
+ bank = &gpio_bank[id];
- if (cpu_is_omap44xx()) {
- __raw_writel(0xffffffff, bank->base +
- OMAP4_GPIO_IRQSTATUSCLR0);
- __raw_writew(0x0015, bank->base +
- OMAP4_GPIO_SYSCONFIG);
- __raw_writel(0x00000000, bank->base +
- OMAP4_GPIO_DEBOUNCENABLE);
- /*
- * Initialize interface clock ungated,
- * module enabled
- */
- __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
- } else {
- __raw_writel(0x00000000, bank->base +
- OMAP24XX_GPIO_IRQENABLE1);
- __raw_writel(0xffffffff, bank->base +
- OMAP24XX_GPIO_IRQSTATUS1);
- __raw_writew(0x0015, bank->base +
- OMAP24XX_GPIO_SYSCONFIG);
- __raw_writel(0x00000000, bank->base +
- OMAP24XX_GPIO_DEBOUNCE_EN);
-
- /*
- * Initialize interface clock ungated,
- * module enabled
- */
- __raw_writel(0, bank->base +
- OMAP24XX_GPIO_CTRL);
- }
- if (cpu_is_omap24xx() &&
- i < ARRAY_SIZE(non_wakeup_gpios))
- bank->non_wakeup_gpios = non_wakeup_gpios[i];
- gpio_count = 32;
- }
-#endif
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
+ return -ENODEV;
+ }
- bank->mod_usage = 0;
- /* REVISIT eventually switch from OMAP-specific gpio structs
- * over to the generic ones
- */
- bank->chip.request = omap_gpio_request;
- bank->chip.free = omap_gpio_free;
- bank->chip.direction_input = gpio_input;
- bank->chip.get = gpio_get;
- bank->chip.direction_output = gpio_output;
- bank->chip.set_debounce = gpio_debounce;
- bank->chip.set = gpio_set;
- bank->chip.to_irq = gpio_2irq;
- if (bank_is_mpuio(bank)) {
- bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
- bank->chip.dev = &omap_mpuio_device.dev;
-#endif
- bank->chip.base = OMAP_MPUIO(0);
- } else {
- bank->chip.label = "gpio";
- bank->chip.base = gpio;
- gpio += gpio_count;
- }
- bank->chip.ngpio = gpio_count;
+ bank->irq = res->start;
+ bank->virtual_irq_start = pdata->virtual_irq_start;
+ bank->method = pdata->bank_type;
+ bank->dev = &pdev->dev;
+ bank->dbck_flag = pdata->dbck_flag;
+ bank->stride = pdata->bank_stride;
+ bank_width = pdata->bank_width;
- gpiochip_add(&bank->chip);
+ spin_lock_init(&bank->lock);
- for (j = bank->virtual_irq_start;
- j < bank->virtual_irq_start + gpio_count; j++) {
- lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
- set_irq_chip_data(j, bank);
- if (bank_is_mpuio(bank))
- set_irq_chip(j, &mpuio_irq_chip);
- else
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_simple_irq);
- set_irq_flags(j, IRQF_VALID);
- }
- set_irq_chained_handler(bank->irq, gpio_irq_handler);
- set_irq_data(bank->irq, bank);
-
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- sprintf(clk_name, "gpio%d_dbck", i + 1);
- bank->dbck = clk_get(NULL, clk_name);
- if (IS_ERR(bank->dbck))
- printk(KERN_ERR "Could not get %s\n", clk_name);
- }
+ /* Static mapping, never released */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
+ return -ENODEV;
}
- /* Enable system clock for GPIO module.
- * The CAM_CLK_CTRL *is* really the right place. */
- if (cpu_is_omap16xx())
- omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
+ bank->base = ioremap(res->start, resource_size(res));
+ if (!bank->base) {
+ dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
+ return -ENOMEM;
+ }
- /* Enable autoidle for the OCP interface */
- if (cpu_is_omap24xx())
- omap_writel(1 << 0, 0x48019010);
- if (cpu_is_omap34xx())
- omap_writel(1 << 0, 0x48306814);
+ pm_runtime_enable(bank->dev);
+ pm_runtime_get_sync(bank->dev);
+
+ omap_gpio_mod_init(bank, id);
+ omap_gpio_chip_init(bank);
+ omap_gpio_show_rev(bank);
- omap_gpio_show_rev();
+ if (!gpio_init_done)
+ gpio_init_done = 1;
return 0;
}
@@ -2074,7 +1863,7 @@ static struct sys_device omap_gpio_device = {
static int workaround_enabled;
-void omap2_gpio_prepare_for_idle(int power_state)
+void omap2_gpio_prepare_for_idle(int off_mode)
{
int i, c = 0;
int min = 0;
@@ -2090,7 +1879,7 @@ void omap2_gpio_prepare_for_idle(int power_state)
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_disable(bank->dbck);
- if (power_state > PWRDM_POWER_OFF)
+ if (!off_mode)
continue;
/* If going to OFF, remove triggering for all
@@ -2251,8 +2040,6 @@ void omap_gpio_save_context(void)
/* saving banks from 2-6 only since GPIO1 is in WKUP */
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- gpio_context[i].sysconfig =
- __raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);
gpio_context[i].irqenable1 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
gpio_context[i].irqenable2 =
@@ -2283,8 +2070,6 @@ void omap_gpio_restore_context(void)
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
- __raw_writel(gpio_context[i].sysconfig,
- bank->base + OMAP24XX_GPIO_SYSCONFIG);
__raw_writel(gpio_context[i].irqenable1,
bank->base + OMAP24XX_GPIO_IRQENABLE1);
__raw_writel(gpio_context[i].irqenable2,
@@ -2309,25 +2094,28 @@ void omap_gpio_restore_context(void)
}
#endif
+static struct platform_driver omap_gpio_driver = {
+ .probe = omap_gpio_probe,
+ .driver = {
+ .name = "omap_gpio",
+ },
+};
+
/*
- * This may get called early from board specific init
- * for boards that have interrupts routed via FPGA.
+ * gpio driver register needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap_gpio_drv_reg() is a postcore_initcall.
*/
-int __init omap_gpio_init(void)
+static int __init omap_gpio_drv_reg(void)
{
- if (!initialized)
- return _omap_gpio_init();
- else
- return 0;
+ return platform_driver_register(&omap_gpio_driver);
}
+postcore_initcall(omap_gpio_drv_reg);
static int __init omap_gpio_sysinit(void)
{
int ret = 0;
- if (!initialized)
- ret = _omap_gpio_init();
-
mpuio_init();
#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5ce4f0aad35..a4f8003de664 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -27,20 +27,20 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-omap.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/mux.h>
#include <plat/i2c.h>
#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
#define OMAP1_I2C_BASE 0xfffb3800
-#define OMAP2_I2C_BASE1 0x48070000
-#define OMAP2_I2C_BASE2 0x48072000
-#define OMAP2_I2C_BASE3 0x48060000
-#define OMAP4_I2C_BASE4 0x48350000
-static const char name[] = "i2c_omap";
+static const char name[] = "omap_i2c";
#define I2C_RESOURCE_BUILDER(base, irq) \
{ \
@@ -55,15 +55,6 @@ static const char name[] = "i2c_omap";
static struct resource i2c_resources[][2] = {
{ I2C_RESOURCE_BUILDER(0, 0) },
-#if defined(CONFIG_ARCH_OMAP2PLUS)
- { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) },
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) },
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
- { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) },
-#endif
};
#define I2C_DEV_BUILDER(bus_id, res, data) \
@@ -77,18 +68,11 @@ static struct resource i2c_resources[][2] = {
}, \
}
-static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)];
+#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
+#define OMAP_I2C_MAX_CONTROLLERS 4
+static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
-#if defined(CONFIG_ARCH_OMAP2PLUS)
- I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
- I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
- I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]),
-#endif
};
#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
@@ -109,35 +93,25 @@ static int __init omap_i2c_nr_ports(void)
return ports;
}
-/* Shared between omap2 and 3 */
-static resource_size_t omap2_i2c_irq[3] __initdata = {
- INT_24XX_I2C1_IRQ,
- INT_24XX_I2C2_IRQ,
- INT_34XX_I2C3_IRQ,
-};
-
-static resource_size_t omap4_i2c_irq[4] __initdata = {
- OMAP44XX_IRQ_I2C1,
- OMAP44XX_IRQ_I2C2,
- OMAP44XX_IRQ_I2C3,
- OMAP44XX_IRQ_I2C4,
-};
-
-static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
+static inline int omap1_i2c_add_bus(int bus_id)
{
- struct omap_i2c_bus_platform_data *pd;
+ struct platform_device *pdev;
+ struct omap_i2c_bus_platform_data *pdata;
struct resource *res;
- pd = pdev->dev.platform_data;
+ omap1_i2c_mux_pins(bus_id);
+
+ pdev = &omap_i2c_devices[bus_id - 1];
res = pdev->resource;
res[0].start = OMAP1_I2C_BASE;
res[0].end = res[0].start + OMAP_I2C_SIZE;
res[1].start = INT_I2C;
- omap1_i2c_mux_pins(bus_id);
+ pdata = &i2c_pdata[bus_id - 1];
return platform_device_register(pdev);
}
+
/*
* XXX This function is a temporary compatibility wrapper - only
* needed until the I2C driver can be converted to call
@@ -148,52 +122,64 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
omap_pm_set_max_mpu_wakeup_lat(dev, t);
}
-static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
-{
- struct resource *res;
- resource_size_t *irq;
+static struct omap_device_pm_latency omap_i2c_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
- res = pdev->resource;
+#ifdef CONFIG_ARCH_OMAP2PLUS
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ int l;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
+ struct omap_i2c_bus_platform_data *pdata;
- if (!cpu_is_omap44xx())
- irq = omap2_i2c_irq;
- else
- irq = omap4_i2c_irq;
+ omap2_i2c_mux_pins(bus_id);
- if (bus_id == 1) {
- res[0].start = OMAP2_I2C_BASE1;
- res[0].end = res[0].start + OMAP_I2C_SIZE;
+ l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
+ WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
+ "String buffer overflow in I2C%d device setup\n", bus_id);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -EEXIST;
}
- res[1].start = irq[bus_id - 1];
- omap2_i2c_mux_pins(bus_id);
-
+ pdata = &i2c_pdata[bus_id - 1];
/*
* When waiting for completion of a i2c transfer, we need to
* set a wake up latency constraint for the MPU. This is to
* ensure quick enough wakeup from idle, when transfer
* completes.
+ * Only omap3 has support for constraints
*/
- if (cpu_is_omap34xx()) {
- struct omap_i2c_bus_platform_data *pd;
-
- pd = pdev->dev.platform_data;
- pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
- }
-
- return platform_device_register(pdev);
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+ od = omap_device_build(name, bus_id, oh, pdata,
+ sizeof(struct omap_i2c_bus_platform_data),
+ omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
+ WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
+
+ return PTR_ERR(od);
}
+#else
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ return 0;
+}
+#endif
static int __init omap_i2c_add_bus(int bus_id)
{
- struct platform_device *pdev;
-
- pdev = &omap_i2c_devices[bus_id - 1];
-
if (cpu_class_is_omap1())
- return omap1_i2c_add_bus(pdev, bus_id);
+ return omap1_i2c_add_bus(bus_id);
else
- return omap2_i2c_add_bus(pdev, bus_id);
+ return omap2_i2c_add_bus(bus_id);
}
/**
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index bb937f3fabed..256ab3f1ec8f 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -8,7 +8,7 @@
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
struct omap_clk {
u16 cpu;
@@ -31,18 +31,18 @@ struct omap_clk {
#define CK_1510 (1 << 2)
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
#define CK_242X (1 << 4)
-#define CK_243X (1 << 5)
-#define CK_3XXX (1 << 6) /* OMAP3 + AM3 common clocks*/
-#define CK_343X (1 << 7) /* OMAP34xx common clocks */
-#define CK_3430ES1 (1 << 8) /* 34xxES1 only */
-#define CK_3430ES2 (1 << 9) /* 34xxES2, ES3, non-Sitara 35xx only */
-#define CK_3505 (1 << 10)
-#define CK_3517 (1 << 11)
-#define CK_36XX (1 << 12) /* OMAP36xx/37xx-specific clocks */
-#define CK_443X (1 << 13)
+#define CK_243X (1 << 5) /* 243x, 253x */
+#define CK_3430ES1 (1 << 6) /* 34xxES1 only */
+#define CK_3430ES2PLUS (1 << 7) /* 34xxES2, ES3, non-Sitara 35xx only */
+#define CK_3505 (1 << 8)
+#define CK_3517 (1 << 9)
+#define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */
+#define CK_443X (1 << 11)
-#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
+#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
+#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
+#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
#endif
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index fef4696dcf67..8eb0adab19ea 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -49,13 +49,18 @@ struct clkops {
/* struct clksel_rate.flags possibilities */
#define RATE_IN_242X (1 << 0)
#define RATE_IN_243X (1 << 1)
-#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
-#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
+#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */
+#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */
#define RATE_IN_36XX (1 << 4)
#define RATE_IN_4430 (1 << 5)
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
-#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
+#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
+#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX)
+
+/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
+#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
+
/**
* struct clksel_rate - register bitfield values corresponding to clk divisors
@@ -119,8 +124,7 @@ struct clksel {
*
* Possible values for @flags:
* DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
- * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs)
-
+ *
* @freqsel_mask is only used on the OMAP34xx family and AM35xx.
*
* XXX Some DPLLs have multiple bypass inputs, so it's not technically
@@ -156,6 +160,8 @@ struct dpll_data {
u32 autoidle_mask;
u32 freqsel_mask;
u32 idlest_mask;
+ u32 dco_mask;
+ u32 sddiv_mask;
u8 auto_recal_bit;
u8 recal_en_bit;
u8 recal_st_bit;
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index a9d69a09920d..6b8088ec74af 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -27,6 +27,8 @@
#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
#define __ARCH_ARM_MACH_OMAP_COMMON_H
+#include <linux/delay.h>
+
#include <plat/i2c.h>
struct sys_timer;
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 0cce4ca83aa0..d1c916fcf770 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -21,141 +21,15 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
-/* Move omap4 specific defines to dma-44xx.h */
-#include "dma-44xx.h"
+#include <linux/platform_device.h>
-/* Hardware registers for omap1 */
-#define OMAP1_DMA_BASE (0xfffed800)
-
-#define OMAP1_DMA_GCR 0x400
-#define OMAP1_DMA_GSCR 0x404
-#define OMAP1_DMA_GRST 0x408
-#define OMAP1_DMA_HW_ID 0x442
-#define OMAP1_DMA_PCH2_ID 0x444
-#define OMAP1_DMA_PCH0_ID 0x446
-#define OMAP1_DMA_PCH1_ID 0x448
-#define OMAP1_DMA_PCHG_ID 0x44a
-#define OMAP1_DMA_PCHD_ID 0x44c
-#define OMAP1_DMA_CAPS_0_U 0x44e
-#define OMAP1_DMA_CAPS_0_L 0x450
-#define OMAP1_DMA_CAPS_1_U 0x452
-#define OMAP1_DMA_CAPS_1_L 0x454
-#define OMAP1_DMA_CAPS_2 0x456
-#define OMAP1_DMA_CAPS_3 0x458
-#define OMAP1_DMA_CAPS_4 0x45a
-#define OMAP1_DMA_PCH2_SR 0x460
-#define OMAP1_DMA_PCH0_SR 0x480
-#define OMAP1_DMA_PCH1_SR 0x482
-#define OMAP1_DMA_PCHD_SR 0x4c0
-
-/* Hardware registers for omap2 and omap3 */
-#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
-#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
-#define OMAP44XX_DMA4_BASE (L4_44XX_BASE + 0x56000)
-
-#define OMAP_DMA4_REVISION 0x00
-#define OMAP_DMA4_GCR 0x78
-#define OMAP_DMA4_IRQSTATUS_L0 0x08
-#define OMAP_DMA4_IRQSTATUS_L1 0x0c
-#define OMAP_DMA4_IRQSTATUS_L2 0x10
-#define OMAP_DMA4_IRQSTATUS_L3 0x14
-#define OMAP_DMA4_IRQENABLE_L0 0x18
-#define OMAP_DMA4_IRQENABLE_L1 0x1c
-#define OMAP_DMA4_IRQENABLE_L2 0x20
-#define OMAP_DMA4_IRQENABLE_L3 0x24
-#define OMAP_DMA4_SYSSTATUS 0x28
-#define OMAP_DMA4_OCP_SYSCONFIG 0x2c
-#define OMAP_DMA4_CAPS_0 0x64
-#define OMAP_DMA4_CAPS_2 0x6c
-#define OMAP_DMA4_CAPS_3 0x70
-#define OMAP_DMA4_CAPS_4 0x74
-
-#define OMAP1_LOGICAL_DMA_CH_COUNT 17
-#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
-
-/* Common channel specific registers for omap1 */
-#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00)
-#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00)
-#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02)
-#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04)
-#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06)
-#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10)
-#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12)
-#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14)
-#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16)
-#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18) /* 15xx only */
-#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18)
-#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a)
-#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c)
-#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e)
-#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28)
-
-/* Common channel specific registers for omap2 */
-#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80)
-#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80)
-#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84)
-#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88)
-#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c)
-#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90)
-#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94)
-#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98)
-#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4)
-#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8)
-#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac)
-#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0)
-#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4)
-#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8)
-
-/* Channel specific registers only on omap1 */
-#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08)
-#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a)
-#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c)
-#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e)
-#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20)
-#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22)
-#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24)
-#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a) /* not on 15xx */
-#define OMAP1_DMA_CCEN(n) 0
-#define OMAP1_DMA_CCFN(n) 0
-
-/* Channel specific registers only on omap2 */
-#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c)
-#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0)
-#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc)
-#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0)
-#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4)
-
-/* Additional registers available on OMAP4 */
-#define OMAP_DMA4_CDP(n) (0x60 * (n) + 0xd0)
-#define OMAP_DMA4_CNDP(n) (0x60 * (n) + 0xd4)
-#define OMAP_DMA4_CCDN(n) (0x60 * (n) + 0xd8)
-
-/* Dummy defines to keep multi-omap compiles happy */
-#define OMAP1_DMA_REVISION 0
-#define OMAP1_DMA_IRQSTATUS_L0 0
-#define OMAP1_DMA_IRQENABLE_L0 0
-#define OMAP1_DMA_OCP_SYSCONFIG 0
-#define OMAP_DMA4_HW_ID 0
-#define OMAP_DMA4_CAPS_0_L 0
-#define OMAP_DMA4_CAPS_0_U 0
-#define OMAP_DMA4_CAPS_1_L 0
-#define OMAP_DMA4_CAPS_1_U 0
-#define OMAP_DMA4_GSCR 0
-#define OMAP_DMA4_CPC(n) 0
-
-#define OMAP_DMA4_LCH_CTRL(n) 0
-#define OMAP_DMA4_COLOR_L(n) 0
-#define OMAP_DMA4_COLOR_U(n) 0
-#define OMAP_DMA4_CCR2(n) 0
-#define OMAP1_DMA_CSSA(n) 0
-#define OMAP1_DMA_CDSA(n) 0
-#define OMAP_DMA4_CSSA_L(n) 0
-#define OMAP_DMA4_CSSA_U(n) 0
-#define OMAP_DMA4_CDSA_L(n) 0
-#define OMAP_DMA4_CDSA_U(n) 0
-#define OMAP1_DMA_COLOR(n) 0
+/*
+ * TODO: These dma channel defines should go away once all
+ * the omap drivers hwmod adapted.
+ */
-/*----------------------------------------------------------------------------*/
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
/* DMA channels for omap1 */
#define OMAP_DMA_NO_DEVICE 0
@@ -405,6 +279,63 @@
#define DMA_CH_PRIO_HIGH 0x1
#define DMA_CH_PRIO_LOW 0x0 /* Def */
+/* Errata handling */
+#define IS_DMA_ERRATA(id) (errata & (id))
+#define SET_DMA_ERRATA(id) (errata |= (id))
+
+#define DMA_ERRATA_IFRAME_BUFFERING BIT(0x0)
+#define DMA_ERRATA_PARALLEL_CHANNELS BIT(0x1)
+#define DMA_ERRATA_i378 BIT(0x2)
+#define DMA_ERRATA_i541 BIT(0x3)
+#define DMA_ERRATA_i88 BIT(0x4)
+#define DMA_ERRATA_3_3 BIT(0x5)
+#define DMA_ROMCODE_BUG BIT(0x6)
+
+/* Attributes for OMAP DMA Contrller */
+#define DMA_LINKED_LCH BIT(0x0)
+#define GLOBAL_PRIORITY BIT(0x1)
+#define RESERVE_CHANNEL BIT(0x2)
+#define IS_CSSA_32 BIT(0x3)
+#define IS_CDSA_32 BIT(0x4)
+#define IS_RW_PRIORITY BIT(0x5)
+#define ENABLE_1510_MODE BIT(0x6)
+#define SRC_PORT BIT(0x7)
+#define DST_PORT BIT(0x8)
+#define SRC_INDEX BIT(0x9)
+#define DST_INDEX BIT(0xA)
+#define IS_BURST_ONLY4 BIT(0xB)
+#define CLEAR_CSR_ON_READ BIT(0xC)
+#define IS_WORD_16 BIT(0xD)
+
+enum omap_reg_offsets {
+
+GCR, GSCR, GRST1, HW_ID,
+PCH2_ID, PCH0_ID, PCH1_ID, PCHG_ID,
+PCHD_ID, CAPS_0, CAPS_1, CAPS_2,
+CAPS_3, CAPS_4, PCH2_SR, PCH0_SR,
+PCH1_SR, PCHD_SR, REVISION, IRQSTATUS_L0,
+IRQSTATUS_L1, IRQSTATUS_L2, IRQSTATUS_L3, IRQENABLE_L0,
+IRQENABLE_L1, IRQENABLE_L2, IRQENABLE_L3, SYSSTATUS,
+OCP_SYSCONFIG,
+
+/* omap1+ specific */
+CPC, CCR2, LCH_CTRL,
+
+/* Common registers for all omap's */
+CSDP, CCR, CICR, CSR,
+CEN, CFN, CSFI, CSEI,
+CSAC, CDAC, CDEI,
+CDFI, CLNK_CTRL,
+
+/* Channel specific registers */
+CSSA, CDSA, COLOR,
+CCEN, CCFN,
+
+/* omap3630 and omap4 specific */
+CDP, CNDP, CCDN,
+
+};
+
enum omap_dma_burst_mode {
OMAP_DMA_DATA_BURST_DIS = 0,
OMAP_DMA_DATA_BURST_4,
@@ -470,6 +401,41 @@ struct omap_dma_channel_params {
#endif
};
+struct omap_dma_lch {
+ int next_lch;
+ int dev_id;
+ u16 saved_csr;
+ u16 enabled_irqs;
+ const char *dev_name;
+ void (*callback)(int lch, u16 ch_status, void *data);
+ void *data;
+ long flags;
+ /* required for Dynamic chaining */
+ int prev_linked_ch;
+ int next_linked_ch;
+ int state;
+ int chain_id;
+ int status;
+};
+
+struct omap_dma_dev_attr {
+ u32 dev_caps;
+ u16 lch_count;
+ u16 chan_count;
+ struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+ struct omap_dma_dev_attr *dma_attr;
+ u32 errata;
+ void (*disable_irq_lch)(int lch);
+ void (*show_dma_caps)(void);
+ void (*clear_lch_regs)(int lch);
+ void (*clear_dma)(int lch);
+ void (*dma_write)(u32 val, int reg, int lch);
+ u32 (*dma_read)(int reg, int lch);
+};
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
diff --git a/arch/arm/plat-omap/include/plat/fpga.h b/arch/arm/plat-omap/include/plat/fpga.h
index f1864a652f7a..ae39bcb3f5ba 100644
--- a/arch/arm/plat-omap/include/plat/fpga.h
+++ b/arch/arm/plat-omap/include/plat/fpga.h
@@ -19,11 +19,7 @@
#ifndef __ASM_ARCH_OMAP_FPGA_H
#define __ASM_ARCH_OMAP_FPGA_H
-#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
extern void omap1510_fpga_init_irq(void);
-#else
-#define omap1510_fpga_init_irq() (0)
-#endif
#define fpga_read(reg) __raw_readb(reg)
#define fpga_write(val, reg) __raw_writeb(val, reg)
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index de1c604962eb..d6f9fa0f62af 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -27,26 +27,15 @@
#define __ASM_ARCH_OMAP_GPIO_H
#include <linux/io.h>
+#include <linux/platform_device.h>
#include <mach/irqs.h>
#define OMAP1_MPUIO_BASE 0xfffb5000
-#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
-
-#define OMAP_MPUIO_INPUT_LATCH 0x00
-#define OMAP_MPUIO_OUTPUT 0x02
-#define OMAP_MPUIO_IO_CNTL 0x04
-#define OMAP_MPUIO_KBR_LATCH 0x08
-#define OMAP_MPUIO_KBC 0x0a
-#define OMAP_MPUIO_GPIO_EVENT_MODE 0x0c
-#define OMAP_MPUIO_GPIO_INT_EDGE 0x0e
-#define OMAP_MPUIO_KBD_INT 0x10
-#define OMAP_MPUIO_GPIO_INT 0x12
-#define OMAP_MPUIO_KBD_MASKIT 0x14
-#define OMAP_MPUIO_GPIO_MASKIT 0x16
-#define OMAP_MPUIO_GPIO_DEBOUNCING 0x18
-#define OMAP_MPUIO_LATCH 0x1a
-#else
+/*
+ * These are the omap15xx/16xx offsets. The omap7xx offset are
+ * OMAP_MPUIO_ / 2 offsets below.
+ */
#define OMAP_MPUIO_INPUT_LATCH 0x00
#define OMAP_MPUIO_OUTPUT 0x04
#define OMAP_MPUIO_IO_CNTL 0x08
@@ -60,7 +49,6 @@
#define OMAP_MPUIO_GPIO_MASKIT 0x2c
#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
#define OMAP_MPUIO_LATCH 0x34
-#endif
#define OMAP34XX_NR_GPIOS 6
@@ -71,8 +59,30 @@
IH_MPUIO_BASE + ((nr) & 0x0f) : \
IH_GPIO_BASE + (nr))
-extern int omap_gpio_init(void); /* Call from board init only */
-extern void omap2_gpio_prepare_for_idle(int power_state);
+#define METHOD_MPUIO 0
+#define METHOD_GPIO_1510 1
+#define METHOD_GPIO_1610 2
+#define METHOD_GPIO_7XX 3
+#define METHOD_GPIO_24XX 5
+#define METHOD_GPIO_44XX 6
+
+struct omap_gpio_dev_attr {
+ int bank_width; /* GPIO bank width */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+struct omap_gpio_platform_data {
+ u16 virtual_irq_start;
+ int bank_type;
+ int bank_width; /* GPIO bank width */
+ int bank_stride; /* Only needed for omap1 MPUIO */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+extern int gpio_bank_count;
+
+extern void omap2_gpio_prepare_for_idle(int off_mode);
extern void omap2_gpio_resume_after_idle(void);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 9fd99b9e40ab..85ded598853e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -80,12 +80,12 @@
#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
/*
- * Note that all values in this struct are in nanoseconds, while
- * the register values are in gpmc_fck cycles.
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
*/
struct gpmc_timings {
- /* Minimum clock period for synchronous mode */
- u16 sync_clk;
+ /* Minimum clock period for synchronous mode (in picoseconds) */
+ u32 sync_clk;
/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
u16 cs_on; /* Assertion time */
@@ -117,6 +117,7 @@ struct gpmc_timings {
};
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
extern unsigned long gpmc_get_fclk_period(void);
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h
index 36a0befd6168..878d632c4092 100644
--- a/arch/arm/plat-omap/include/plat/i2c.h
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -36,6 +36,19 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
}
#endif
+/**
+ * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod
+ * @fifo_depth: total controller FIFO size (in bytes)
+ * @flags: differences in hardware support capability
+ *
+ * @fifo_depth represents what exists on the hardware, not what is
+ * actually configured at runtime by the device driver.
+ */
+struct omap_i2c_dev_attr {
+ u8 fifo_depth;
+ u8 flags;
+};
+
void __init omap1_i2c_mux_pins(int bus_id);
void __init omap2_i2c_mux_pins(int bus_id);
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
index 128b549c2796..ef4106c13183 100644
--- a/arch/arm/plat-omap/include/plat/io.h
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -291,11 +291,12 @@ static inline void omap44xx_map_common_io(void)
}
#endif
-extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
- struct omap_sdrc_params *sdrc_cs1);
+extern void omap2_init_common_infrastructure(void);
+extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1);
-#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t)
-#define __arch_iounmap(v) omap_iounmap(v)
+#define __arch_ioremap omap_ioremap
+#define __arch_iounmap omap_iounmap
void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
void omap_iounmap(volatile void __iomem *addr);
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 33c7d41cb6a5..69230d685538 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -50,6 +50,8 @@ struct iommu {
int (*isr)(struct iommu *obj);
void *ctx; /* iommu context: registres saved area */
+ u32 da_start;
+ u32 da_end;
};
struct cr_regs {
@@ -103,6 +105,8 @@ struct iommu_platform_data {
const char *name;
const char *clk_name;
const int nr_tlb_entries;
+ u32 da_start;
+ u32 da_end;
};
#if defined(CONFIG_ARCH_OMAP1)
@@ -152,6 +156,7 @@ extern void flush_iotlb_all(struct iommu *obj);
extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
+extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
extern struct iommu *iommu_get(const char *name);
extern void iommu_put(struct iommu *obj);
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 65e20a686713..2910de921c52 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -77,7 +77,7 @@
/*
* OMAP-1610 specific IRQ numbers for interrupt handler 1
*/
-#define INT_1610_IH2_IRQ 0
+#define INT_1610_IH2_IRQ INT_1510_IH2_IRQ
#define INT_1610_IH2_FIQ 2
#define INT_1610_McBSP2_TX 4
#define INT_1610_McBSP2_RX 5
diff --git a/arch/arm/plat-omap/include/plat/keypad.h b/arch/arm/plat-omap/include/plat/keypad.h
index 3ae52ccc793c..793ce9d53294 100644
--- a/arch/arm/plat-omap/include/plat/keypad.h
+++ b/arch/arm/plat-omap/include/plat/keypad.h
@@ -10,16 +10,18 @@
#ifndef ASMARM_ARCH_KEYPAD_H
#define ASMARM_ARCH_KEYPAD_H
-#warning: Please update the board to use matrix_keypad.h instead
+#ifndef CONFIG_ARCH_OMAP1
+#warning Please update the board to use matrix-keypad driver
+#endif
+#include <linux/input/matrix_keypad.h>
struct omap_kp_platform_data {
int rows;
int cols;
- int *keymap;
- unsigned int keymapsize;
- unsigned int rep:1;
+ const struct matrix_keymap_data *keymap_data;
+ bool rep;
unsigned long delay;
- unsigned int dbounce:1;
+ bool dbounce;
/* specific to OMAP242x*/
unsigned int *row_gpios;
unsigned int *col_gpios;
@@ -28,18 +30,21 @@ struct omap_kp_platform_data {
/* Group (0..3) -- when multiple keys are pressed, only the
* keys pressed in the same group are considered as pressed. This is
* in order to workaround certain crappy HW designs that produce ghost
- * keypresses. */
-#define GROUP_0 (0 << 16)
-#define GROUP_1 (1 << 16)
-#define GROUP_2 (2 << 16)
-#define GROUP_3 (3 << 16)
+ * keypresses. Two free bits, not used by neither row/col nor keynum,
+ * must be available for use as group bits. The below GROUP_SHIFT
+ * macro definition is based on some prior knowledge of the
+ * matrix_keypad defined KEY() macro internals.
+ */
+#define GROUP_SHIFT 14
+#define GROUP_0 (0 << GROUP_SHIFT)
+#define GROUP_1 (1 << GROUP_SHIFT)
+#define GROUP_2 (2 << GROUP_SHIFT)
+#define GROUP_3 (3 << GROUP_SHIFT)
#define GROUP_MASK GROUP_3
+#if KEY_MAX & GROUP_MASK
+#error Group bits in conflict with keynum bits
+#endif
-#define KEY_PERSISTENT 0x00800000
-#define KEYNUM_MASK 0x00EFFFFF
-#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
-#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
- KEY_PERSISTENT)
#endif
diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h
new file mode 100644
index 000000000000..5e1949375422
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or 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 __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+
+/* L4 CORE */
+#define OMAP3_L4_CORE_FW_I2C1_REGION 21
+#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22
+#define OMAP3_L4_CORE_FW_I2C2_REGION 23
+#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24
+#define OMAP3_L4_CORE_FW_I2C3_REGION 73
+#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h
index 997656552109..cc3921e9059c 100644
--- a/arch/arm/plat-omap/include/plat/mailbox.h
+++ b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -46,8 +46,8 @@ struct omap_mbox_queue {
struct kfifo fifo;
struct work_struct work;
struct tasklet_struct tasklet;
- int (*callback)(void *);
struct omap_mbox *mbox;
+ bool full;
};
struct omap_mbox {
@@ -57,13 +57,15 @@ struct omap_mbox {
struct omap_mbox_ops *ops;
struct device *dev;
void *priv;
+ int use_count;
+ struct blocking_notifier_head notifier;
};
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
void omap_mbox_init_seq(struct omap_mbox *);
-struct omap_mbox *omap_mbox_get(const char *);
-void omap_mbox_put(struct omap_mbox *);
+struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
int omap_mbox_register(struct device *parent, struct omap_mbox **);
int omap_mbox_unregister(void);
diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h
index d5306bee44b2..f8d922fb5584 100644
--- a/arch/arm/plat-omap/include/plat/memory.h
+++ b/arch/arm/plat-omap/include/plat/memory.h
@@ -61,17 +61,17 @@
#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
-#define __arch_page_to_dma(dev, page) \
- ({ dma_addr_t __dma = page_to_phys(page); \
+#define __arch_pfn_to_dma(dev, pfn) \
+ ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
if (is_lbus_device(dev)) \
__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
__dma; })
-#define __arch_dma_to_page(dev, addr) \
+#define __arch_dma_to_pfn(dev, addr) \
({ dma_addr_t __dma = addr; \
if (is_lbus_device(dev)) \
__dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \
- phys_to_page(__dma); \
+ __phys_to_pfn(__dma); \
})
#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 728fbb9dd549..c0a752053039 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -17,26 +17,7 @@
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
-
-#include "powerdomain.h"
-
-/**
- * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
- * @rate: target clock rate
- * @opp_id: OPP ID
- * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
- *
- * Operating performance point data. Can vary by OMAP chip and board.
- */
-struct omap_opp {
- unsigned long rate;
- u8 opp_id;
- u16 min_vdd;
-};
-
-extern struct omap_opp *mpu_opps;
-extern struct omap_opp *dsp_opps;
-extern struct omap_opp *l3_opps;
+#include <linux/opp.h>
/*
* agent_id values for use with omap_pm_set_min_bus_tput():
@@ -59,9 +40,11 @@ extern struct omap_opp *l3_opps;
* framework starts. The "_if_" is to avoid name collisions with the
* PM idle-loop code.
*/
-int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
- struct omap_opp *dsp_opp_table,
- struct omap_opp *l3_opp_table);
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_early_init() 0
+#else
+int __init omap_pm_if_early_init(void);
+#endif
/**
* omap_pm_if_init - OMAP PM init code called after clock fw init
@@ -69,7 +52,11 @@ int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
* The main initialization code. OPP tables are passed in here. The
* "_if_" is to avoid name collisions with the PM idle-loop code.
*/
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_init() 0
+#else
int __init omap_pm_if_init(void);
+#endif
/**
* omap_pm_if_exit - OMAP PM exit code
@@ -363,9 +350,11 @@ unsigned long omap_pm_cpu_get_freq(void);
* driver must restore device context. If the number of context losses
* exceeds the maximum positive integer, the function will wrap to 0 and
* continue counting. Returns the number of context losses for this device,
- * or -EINVAL upon error.
+ * or zero upon error.
*/
-int omap_pm_get_dev_context_loss_count(struct device *dev);
+u32 omap_pm_get_dev_context_loss_count(struct device *dev);
+void omap_pm_enable_off_mode(void);
+void omap_pm_disable_off_mode(void);
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index c8dae02f0704..2682043f5a5b 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -22,7 +22,7 @@
#include <plat/mux.h>
-#define DRIVER_NAME "omap-hsuart"
+#define DRIVER_NAME "omap_uart"
/*
* Use tty device name as ttyO, [O -> OMAP]
@@ -31,20 +31,8 @@
*/
#define OMAP_SERIAL_NAME "ttyO"
-#define OMAP_MDR1_DISABLE 0x07
-#define OMAP_MDR1_MODE13X 0x03
-#define OMAP_MDR1_MODE16X 0x00
#define OMAP_MODE13X_SPEED 230400
-/*
- * LCR = 0XBF: Switch to Configuration Mode B.
- * In configuration mode b allow access
- * to EFR,DLL,DLH.
- * Reference OMAP TRM Chapter 17
- * Section: 1.4.3 Mode Selection
- */
-#define OMAP_UART_LCR_CONF_MDB 0XBF
-
/* WER = 0x7F
* Enable module level wakeup in WER reg
*/
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 28e2d1a78433..e4c349ff9fd8 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -107,6 +107,7 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+u32 omap_device_get_context_loss_count(struct platform_device *pdev);
/* Other */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 7eaa8edf3b14..6864a997f2ca 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -23,7 +23,7 @@
* - add pinmuxing
* - init_conn_id_bit (CONNID_BIT_VECTOR)
* - implement default hwmod SMS/SDRC flags?
- * - remove unused fields
+ * - move Linux-specific data ("non-ROM data") out
*
*/
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
@@ -32,8 +32,9 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ioport.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
struct omap_device;
@@ -76,6 +77,20 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_FORCE (1 << 0)
#define HWMOD_IDLEMODE_NO (1 << 1)
#define HWMOD_IDLEMODE_SMART (1 << 2)
+/* Slave idle mode flag only */
+#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
+
+/**
+ * struct omap_hwmod_mux_info - hwmod specific mux configuration
+ * @pads: array of omap_device_pad entries
+ * @nr_pads: number of omap_device_pad entries
+ *
+ * Note that this is currently built during init as needed.
+ */
+struct omap_hwmod_mux_info {
+ int nr_pads;
+ struct omap_device_pad *pads;
+};
/**
* struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
@@ -159,7 +174,7 @@ struct omap_hwmod_omap2_firewall {
* ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
* ADDR_TYPE_RT: Address space contains module register target data.
*/
-#define ADDR_MAP_ON_INIT (1 << 0)
+#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */
#define ADDR_TYPE_RT (1 << 1)
/**
@@ -200,8 +215,6 @@ struct omap_hwmod_addr_space {
* @fw: interface firewall data
* @addr_cnt: ARRAY_SIZE(@addr)
* @width: OCP data width
- * @thread_cnt: number of threads
- * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
* @user: initiators using this interface (see OCP_USER_* macros above)
* @flags: OCP interface flags (see OCPIF_* macros above)
*
@@ -221,8 +234,6 @@ struct omap_hwmod_ocp_if {
} fw;
u8 addr_cnt;
u8 width;
- u8 thread_cnt;
- u8 max_burst_len;
u8 user;
u8 flags;
};
@@ -231,11 +242,12 @@ struct omap_hwmod_ocp_if {
/* Macros for use in struct omap_hwmod_sysconfig */
/* Flags for use in omap_hwmod_sysconfig.idlemodes */
-#define MASTER_STANDBY_SHIFT 2
+#define MASTER_STANDBY_SHIFT 4
#define SLAVE_IDLE_SHIFT 0
#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT)
#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
@@ -357,14 +369,14 @@ struct omap_hwmod_omap4_prcm {
* HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
* of standby, rather than relying on module smart-standby
* HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
- * SDRAM controller, etc.
+ * SDRAM controller, etc. XXX probably belongs outside the main hwmod file
* HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
- * controller, etc.
+ * controller, etc. XXX probably belongs outside the main hwmod file
* HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
* when module is enabled, rather than the default, which is to
* enable autoidle
* HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
- * HWMOD_NO_IDLEST : this module does not have idle status - this is the case
+ * HWMOD_NO_IDLEST: this module does not have idle status - this is the case
* only for few initiator modules on OMAP2 & 3.
* HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
* This is needed for devices like DSS that require optional clocks enabled
@@ -415,14 +427,31 @@ struct omap_hwmod_omap4_prcm {
* @name: name of the hwmod_class
* @sysc: device SYSCONFIG/SYSSTATUS register data
* @rev: revision of the IP class
+ * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
+ * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
*
* Represent the class of a OMAP hardware "modules" (e.g. timer,
* smartreflex, gpio, uart...)
+ *
+ * @pre_shutdown is a function that will be run immediately before
+ * hwmod clocks are disabled, etc. It is intended for use for hwmods
+ * like the MPU watchdog, which cannot be disabled with the standard
+ * omap_hwmod_shutdown(). The function should return 0 upon success,
+ * or some negative error upon failure. Returning an error will cause
+ * omap_hwmod_shutdown() to abort the device shutdown and return an
+ * error.
+ *
+ * If @reset is defined, then the function it points to will be
+ * executed in place of the standard hwmod _reset() code in
+ * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have
+ * unusual reset sequences - usually processor IP blocks like the IVA.
*/
struct omap_hwmod_class {
const char *name;
struct omap_hwmod_class_sysconfig *sysc;
u32 rev;
+ int (*pre_shutdown)(struct omap_hwmod *oh);
+ int (*reset)(struct omap_hwmod *oh);
};
/**
@@ -436,14 +465,14 @@ struct omap_hwmod_class {
* @main_clk: main clock: OMAP clock name
* @_clk: pointer to the main struct clk (filled in at runtime)
* @opt_clks: other device clocks that drivers can request (0..*)
+ * @vdd_name: voltage domain name
+ * @voltdm: pointer to voltage domain (filled in at runtime)
* @masters: ptr to array of OCP ifs that this hwmod can initiate on
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
* @dev_attr: arbitrary device attributes that can be passed to the driver
* @_sysc_cache: internal-use hwmod flags
* @_mpu_rt_va: cached register target start address (internal use)
* @_mpu_port_index: cached MPU register target slave ID (internal use)
- * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
- * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
* @mpu_irqs_cnt: number of @mpu_irqs
* @sdma_reqs_cnt: number of @sdma_reqs
* @opt_clks_cnt: number of @opt_clks
@@ -452,9 +481,10 @@ struct omap_hwmod_class {
* @response_lat: device OCP response latency (in interface clock cycles)
* @_int_flags: internal-use hwmod flags
* @_state: internal-use hwmod state
+ * @_postsetup_state: internal-use state to leave the hwmod in after _setup()
* @flags: hwmod flags (documented below)
* @omap_chip: OMAP chips this hwmod is present on
- * @_mutex: mutex serializing operations on this hwmod
+ * @_lock: spinlock serializing operations on this hwmod
* @node: list node for hwmod list (internal use)
*
* @main_clk refers to this module's "main clock," which for our
@@ -469,6 +499,7 @@ struct omap_hwmod {
const char *name;
struct omap_hwmod_class *class;
struct omap_device *od;
+ struct omap_hwmod_mux_info *mux;
struct omap_hwmod_irq_info *mpu_irqs;
struct omap_hwmod_dma_info *sdma_reqs;
struct omap_hwmod_rst_info *rst_lines;
@@ -479,17 +510,17 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
+ char *vdd_name;
+ struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
u32 _sysc_cache;
void __iomem *_mpu_rt_va;
- struct mutex _mutex;
+ spinlock_t _lock;
struct list_head node;
u16 flags;
u8 _mpu_port_index;
- u8 msuspendmux_reg_id;
- u8 msuspendmux_shift;
u8 response_lat;
u8 mpu_irqs_cnt;
u8 sdma_reqs_cnt;
@@ -500,16 +531,15 @@ struct omap_hwmod {
u8 hwmods_cnt;
u8 _int_flags;
u8 _state;
+ u8 _postsetup_state;
const struct omap_chip_id omap_chip;
};
int omap_hwmod_init(struct omap_hwmod **ohs);
-int omap_hwmod_register(struct omap_hwmod *oh);
-int omap_hwmod_unregister(struct omap_hwmod *oh);
struct omap_hwmod *omap_hwmod_lookup(const char *name);
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
void *data);
-int omap_hwmod_late_init(u8 skip_setup_idle);
+int omap_hwmod_late_init(void);
int omap_hwmod_enable(struct omap_hwmod *oh);
int _omap_hwmod_enable(struct omap_hwmod *oh);
@@ -556,6 +586,9 @@ int omap_hwmod_for_each_by_class(const char *classname,
void *user),
void *user);
+int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
+u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+
/*
* Chip variant-specific hwmod init routines - XXX should be converted
* to use initcalls once the initial boot ordering is straightened out
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index ab77442e42ab..2fdf8c80d390 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -18,6 +18,10 @@
* You 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
+ *
+ * XXX This file is deprecated. The PRCM is an OMAP2+-only subsystem,
+ * so this file doesn't belong in plat-omap/include/plat. Please
+ * do not add anything new to this file.
*/
#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
@@ -28,22 +32,6 @@ 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);
-#define START_PADCONF_SAVE 0x2
-#define PADCONF_SAVE_DONE 0x1
-
-void omap3_prcm_save_context(void);
-void omap3_prcm_restore_context(void);
-
-u32 prm_read_mod_reg(s16 module, u16 idx);
-void prm_write_mod_reg(u32 val, s16 module, u16 idx);
-u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
-u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
-u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
-u32 cm_read_mod_reg(s16 module, u16 idx);
-void cm_write_mod_reg(u32 val, s16 module, u16 idx);
-u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-
#endif
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 19145f5c32ba..cec5d56db2eb 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -93,9 +93,12 @@
})
#ifndef __ASSEMBLER__
+
+struct omap_board_data;
+
extern void __init omap_serial_early_init(void);
extern void omap_serial_init(void);
-extern void omap_serial_init_port(int port);
+extern void omap_serial_init_port(struct omap_board_data *bdata);
extern int omap_uart_can_sleep(void);
extern void omap_uart_check_wakeup(void);
extern void omap_uart_prepare_suspend(void);
diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h
new file mode 100644
index 000000000000..6568c885f37a
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/smartreflex.h
@@ -0,0 +1,245 @@
+/*
+ * OMAP Smartreflex Defines and Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@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.
+ */
+
+#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
+#define __ASM_ARM_OMAP_SMARTREFLEX_H
+
+#include <linux/platform_device.h>
+#include <plat/voltage.h>
+
+/*
+ * Different Smartreflex IPs version. The v1 is the 65nm version used in
+ * OMAP3430. The v2 is the update for the 45nm version of the IP
+ * used in OMAP3630 and OMAP4430
+ */
+#define SR_TYPE_V1 1
+#define SR_TYPE_V2 2
+
+/* SMART REFLEX REG ADDRESS OFFSET */
+#define SRCONFIG 0x00
+#define SRSTATUS 0x04
+#define SENVAL 0x08
+#define SENMIN 0x0C
+#define SENMAX 0x10
+#define SENAVG 0x14
+#define AVGWEIGHT 0x18
+#define NVALUERECIPROCAL 0x1c
+#define SENERROR_V1 0x20
+#define ERRCONFIG_V1 0x24
+#define IRQ_EOI 0x20
+#define IRQSTATUS_RAW 0x24
+#define IRQSTATUS 0x28
+#define IRQENABLE_SET 0x2C
+#define IRQENABLE_CLR 0x30
+#define SENERROR_V2 0x34
+#define ERRCONFIG_V2 0x38
+
+/* Bit/Shift Positions */
+
+/* SRCONFIG */
+#define SRCONFIG_ACCUMDATA_SHIFT 22
+#define SRCONFIG_SRCLKLENGTH_SHIFT 12
+#define SRCONFIG_SENNENABLE_V1_SHIFT 5
+#define SRCONFIG_SENPENABLE_V1_SHIFT 3
+#define SRCONFIG_SENNENABLE_V2_SHIFT 1
+#define SRCONFIG_SENPENABLE_V2_SHIFT 0
+#define SRCONFIG_CLKCTRL_SHIFT 0
+
+#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
+
+#define SRCONFIG_SRENABLE BIT(11)
+#define SRCONFIG_SENENABLE BIT(10)
+#define SRCONFIG_ERRGEN_EN BIT(9)
+#define SRCONFIG_MINMAXAVG_EN BIT(8)
+#define SRCONFIG_DELAYCTRL BIT(2)
+
+/* AVGWEIGHT */
+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
+
+/* NVALUERECIPROCAL */
+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
+
+/* ERRCONFIG */
+#define ERRCONFIG_ERRWEIGHT_SHIFT 16
+#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
+#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
+
+#define SR_ERRWEIGHT_MASK (0x07 << 16)
+#define SR_ERRMAXLIMIT_MASK (0xff << 8)
+#define SR_ERRMINLIMIT_MASK (0xff << 0)
+
+#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
+#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
+#define ERRCONFIG_MCUACCUMINTEN BIT(29)
+#define ERRCONFIG_MCUACCUMINTST BIT(28)
+#define ERRCONFIG_MCUVALIDINTEN BIT(27)
+#define ERRCONFIG_MCUVALIDINTST BIT(26)
+#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
+#define ERRCONFIG_MCUBOUNDINTST BIT(24)
+#define ERRCONFIG_MCUDISACKINTEN BIT(23)
+#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
+#define ERRCONFIG_MCUDISACKINTST BIT(22)
+#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
+
+#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
+ ERRCONFIG_MCUACCUMINTST | \
+ ERRCONFIG_MCUVALIDINTST | \
+ ERRCONFIG_MCUBOUNDINTST | \
+ ERRCONFIG_MCUDISACKINTST)
+/* IRQSTATUS */
+#define IRQSTATUS_MCUACCUMINT BIT(3)
+#define IRQSTATUS_MCVALIDINT BIT(2)
+#define IRQSTATUS_MCBOUNDSINT BIT(1)
+#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
+
+/* IRQENABLE_SET and IRQENABLE_CLEAR */
+#define IRQENABLE_MCUACCUMINT BIT(3)
+#define IRQENABLE_MCUVALIDINT BIT(2)
+#define IRQENABLE_MCUBOUNDSINT BIT(1)
+#define IRQENABLE_MCUDISABLEACKINT BIT(0)
+
+/* Common Bit values */
+
+#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
+#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
+#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
+#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
+#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
+
+/*
+ * 3430 specific values. Maybe these should be passed from board file or
+ * pmic structures.
+ */
+#define OMAP3430_SR_ACCUMDATA 0x1f4
+
+#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
+#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
+
+#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
+#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
+
+#define OMAP3430_SR_ERRWEIGHT 0x04
+#define OMAP3430_SR_ERRMAXLIMIT 0x02
+
+/**
+ * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
+ * pmic specific info to smartreflex driver
+ *
+ * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
+ */
+struct omap_sr_pmic_data {
+ void (*sr_pmic_init) (void);
+};
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+/*
+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
+ * The smartreflex class driver should pass the class type.
+ * Should be used to populate the class_type field of the
+ * omap_smartreflex_class_data structure.
+ */
+#define SR_CLASS1 0x1
+#define SR_CLASS2 0x2
+#define SR_CLASS3 0x3
+
+/**
+ * struct omap_sr_class_data - Smartreflex class driver info
+ *
+ * @enable: API to enable a particular class smaartreflex.
+ * @disable: API to disable a particular class smartreflex.
+ * @configure: API to configure a particular class smartreflex.
+ * @notify: API to notify the class driver about an event in SR.
+ * Not needed for class3.
+ * @notify_flags: specify the events to be notified to the class driver
+ * @class_type: specify which smartreflex class.
+ * Can be used by the SR driver to take any class
+ * based decisions.
+ */
+struct omap_sr_class_data {
+ int (*enable)(struct voltagedomain *voltdm);
+ int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
+ int (*configure)(struct voltagedomain *voltdm);
+ int (*notify)(struct voltagedomain *voltdm, u32 status);
+ u8 notify_flags;
+ u8 class_type;
+};
+
+/**
+ * struct omap_sr_nvalue_table - Smartreflex n-target value info
+ *
+ * @efuse_offs: The offset of the efuse where n-target values are stored.
+ * @nvalue: The n-target value.
+ */
+struct omap_sr_nvalue_table {
+ u32 efuse_offs;
+ u32 nvalue;
+};
+
+/**
+ * struct omap_sr_data - Smartreflex platform data.
+ *
+ * @ip_type: Smartreflex IP type.
+ * @senp_mod: SENPENABLE value for the sr
+ * @senn_mod: SENNENABLE value for sr
+ * @nvalue_count: Number of distinct nvalues in the nvalue table
+ * @enable_on_init: whether this sr module needs to enabled at
+ * boot up or not.
+ * @nvalue_table: table containing the efuse offsets and nvalues
+ * corresponding to them.
+ * @voltdm: Pointer to the voltage domain associated with the SR
+ */
+struct omap_sr_data {
+ int ip_type;
+ u32 senp_mod;
+ u32 senn_mod;
+ int nvalue_count;
+ bool enable_on_init;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+};
+
+/* Smartreflex module enable/disable interface */
+void omap_sr_enable(struct voltagedomain *voltdm);
+void omap_sr_disable(struct voltagedomain *voltdm);
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
+
+/* API to register the pmic specific data with the smartreflex driver. */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
+
+/* Smartreflex driver hooks to be called from Smartreflex class driver */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
+void sr_disable(struct voltagedomain *voltdm);
+int sr_configure_errgen(struct voltagedomain *voltdm);
+int sr_configure_minmax(struct voltagedomain *voltdm);
+
+/* API to register the smartreflex class driver with the smartreflex driver */
+int sr_register_class(struct omap_sr_class_data *class_data);
+#else
+static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable_reset_volt(
+ struct voltagedomain *voltdm) {}
+static inline void omap_sr_register_pmic(
+ struct omap_sr_pmic_data *pmic_data) {}
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index ecd6a488c497..7a10257909ef 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,7 +18,6 @@
#define OMAP_ARCH_SMP_H
#include <asm/hardware/gic.h>
-#include <asm/smp_mpidr.h>
/* Needed for secondary core boot */
extern void omap_secondary_startup(void);
@@ -29,9 +28,9 @@ extern u32 omap_read_auxcoreboot0(void);
/*
* We use Soft IRQ1 as the IPI
*/
-static inline void smp_cross_call(const struct cpumask *mask)
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
- gic_raise_softirq(mask, 1);
+ gic_raise_softirq(mask, ipi);
}
#endif
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 5905100b29a1..9967d5e855c7 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -11,6 +11,7 @@
#ifndef __ARCH_ARM_OMAP_SRAM_H
#define __ARCH_ARM_OMAP_SRAM_H
+#ifndef __ASSEMBLY__
extern void * omap_sram_push(void * start, unsigned long size);
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
@@ -74,4 +75,14 @@ extern void omap_push_sram_idle(void);
static inline void omap_push_sram_idle(void) {}
#endif /* CONFIG_PM */
+#endif /* __ASSEMBLY__ */
+
+/*
+ * OMAP2+: define the SRAM PA addresses.
+ * Used by the SRAM management code and the idle sleep code.
+ */
+#define OMAP2_SRAM_PA 0x40200000
+#define OMAP3_SRAM_PA 0x40200000
+#define OMAP4_SRAM_PA 0x40300000
+
#endif
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index 9036e374e0ac..ad98b85cae21 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -145,8 +145,11 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
/* omap3 based boards using UART3 */
DEBUG_LL_OMAP3(3, cm_t35);
DEBUG_LL_OMAP3(3, cm_t3517);
+ DEBUG_LL_OMAP3(3, craneboard);
+ DEBUG_LL_OMAP3(3, devkit8000);
DEBUG_LL_OMAP3(3, igep0020);
DEBUG_LL_OMAP3(3, igep0030);
+ DEBUG_LL_OMAP3(3, nokia_rm680);
DEBUG_LL_OMAP3(3, nokia_rx51);
DEBUG_LL_OMAP3(3, omap3517evm);
DEBUG_LL_OMAP3(3, omap3_beagle);
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
new file mode 100644
index 000000000000..0ff123399f3b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -0,0 +1,146 @@
+/*
+ * OMAP Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Thara Gopinath <thara@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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+
+#define VOLTSCALE_VPFORCEUPDATE 1
+#define VOLTSCALE_VCBYPASS 2
+
+/*
+ * OMAP3 GENERIC setup times. Revisit to see if these needs to be
+ * passed from board or PMIC file
+ */
+#define OMAP3_CLKSETUP 0xff
+#define OMAP3_VOLTOFFSET 0xff
+#define OMAP3_VOLTSETUP2 0xff
+
+/* Voltage value defines */
+#define OMAP3430_VDD_MPU_OPP1_UV 975000
+#define OMAP3430_VDD_MPU_OPP2_UV 1075000
+#define OMAP3430_VDD_MPU_OPP3_UV 1200000
+#define OMAP3430_VDD_MPU_OPP4_UV 1270000
+#define OMAP3430_VDD_MPU_OPP5_UV 1350000
+
+#define OMAP3430_VDD_CORE_OPP1_UV 975000
+#define OMAP3430_VDD_CORE_OPP2_UV 1050000
+#define OMAP3430_VDD_CORE_OPP3_UV 1150000
+
+#define OMAP3630_VDD_MPU_OPP50_UV 1012500
+#define OMAP3630_VDD_MPU_OPP100_UV 1200000
+#define OMAP3630_VDD_MPU_OPP120_UV 1325000
+#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
+
+#define OMAP3630_VDD_CORE_OPP50_UV 1000000
+#define OMAP3630_VDD_CORE_OPP100_UV 1200000
+
+#define OMAP4430_VDD_MPU_OPP50_UV 930000
+#define OMAP4430_VDD_MPU_OPP100_UV 1100000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
+
+#define OMAP4430_VDD_IVA_OPP50_UV 930000
+#define OMAP4430_VDD_IVA_OPP100_UV 1100000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
+
+#define OMAP4430_VDD_CORE_OPP50_UV 930000
+#define OMAP4430_VDD_CORE_OPP100_UV 1100000
+
+/**
+ * struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as a unique
+ * identifier.
+ */
+struct voltagedomain {
+ char *name;
+};
+
+/* API to get the voltagedomain pointer */
+struct voltagedomain *omap_voltage_domain_lookup(char *name);
+
+/**
+ * struct omap_volt_data - Omap voltage specific data.
+ * @voltage_nominal: The possible voltage value in uV
+ * @sr_efuse_offs: The offset of the efuse register(from system
+ * control module base address) from where to read
+ * the n-target value for the smartreflex module.
+ * @sr_errminlimit: Error min limit value for smartreflex. This value
+ * differs at differnet opp and thus is linked
+ * with voltage.
+ * @vp_errorgain: Error gain value for the voltage processor. This
+ * field also differs according to the voltage/opp.
+ */
+struct omap_volt_data {
+ u32 volt_nominal;
+ u32 sr_efuse_offs;
+ u8 sr_errminlimit;
+ u8 vp_errgain;
+};
+
+/**
+ * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * @slew_rate: PMIC slew rate (in uv/us)
+ * @step_size: PMIC voltage step size (in uv)
+ * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
+ * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
+ */
+struct omap_volt_pmic_info {
+ int slew_rate;
+ int step_size;
+ u32 on_volt;
+ u32 onlp_volt;
+ u32 ret_volt;
+ u32 off_volt;
+ u16 volt_setup_time;
+ u8 vp_erroroffset;
+ u8 vp_vstepmin;
+ u8 vp_vstepmax;
+ u8 vp_vddmin;
+ u8 vp_vddmax;
+ u8 vp_timeout_us;
+ u8 i2c_slave_addr;
+ u8 pmic_reg;
+ unsigned long (*vsel_to_uv) (const u8 vsel);
+ u8 (*uv_to_vsel) (unsigned long uV);
+};
+
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+void omap_voltage_reset(struct voltagedomain *voltdm);
+void omap_voltage_get_volttable(struct voltagedomain *voltdm,
+ struct omap_volt_data **volt_data);
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt);
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+#ifdef CONFIG_PM
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info);
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method);
+int omap_voltage_late_init(void);
+#else
+static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info) {}
+static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method) {}
+static inline int omap_voltage_late_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
index b0078cf96281..f1295fafcd31 100644
--- a/arch/arm/plat-omap/io.c
+++ b/arch/arm/plat-omap/io.c
@@ -136,61 +136,3 @@ void omap_iounmap(volatile void __iomem *addr)
__iounmap(addr);
}
EXPORT_SYMBOL(omap_iounmap);
-
-/*
- * NOTE: Please use ioremap + __raw_read/write where possible instead of these
- */
-
-u8 omap_readb(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readb(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readb);
-
-u16 omap_readw(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readw(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readw);
-
-u32 omap_readl(u32 pa)
-{
- if (cpu_class_is_omap1())
- return __raw_readl(OMAP1_IO_ADDRESS(pa));
- else
- return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readl);
-
-void omap_writeb(u8 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writeb(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writeb);
-
-void omap_writew(u16 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writew(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writew);
-
-void omap_writel(u32 v, u32 pa)
-{
- if (cpu_class_is_omap1())
- __raw_writel(v, OMAP1_IO_ADDRESS(pa));
- else
- __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 6cd151b31bc5..b1107c08da56 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -830,6 +830,28 @@ static int device_match_by_alias(struct device *dev, void *data)
}
/**
+ * iommu_set_da_range - Set a valid device address range
+ * @obj: target iommu
+ * @start Start of valid range
+ * @end End of valid range
+ **/
+int iommu_set_da_range(struct iommu *obj, u32 start, u32 end)
+{
+
+ if (!obj)
+ return -EFAULT;
+
+ if (end < start || !PAGE_ALIGN(start | end))
+ return -EINVAL;
+
+ obj->da_start = start;
+ obj->da_end = end;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_set_da_range);
+
+/**
* iommu_get - Get iommu handler
* @name: target iommu name
**/
@@ -922,6 +944,8 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
obj->name = pdata->name;
obj->dev = &pdev->dev;
obj->ctx = (void *)obj + sizeof(*obj);
+ obj->da_start = pdata->da_start;
+ obj->da_end = pdata->da_end;
mutex_init(&obj->iommu_lock);
mutex_init(&obj->mmap_lock);
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 8ce0de247c71..6dc1296c8c77 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt)
}
#define sgtable_ok(x) (!!sgtable_len(x))
+static unsigned max_alignment(u32 addr)
+{
+ int i;
+ unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
+ for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++)
+ ;
+ return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0;
+}
+
/*
* calculate the optimal number sg elements from total bytes based on
* iommu superpages
*/
-static unsigned int sgtable_nents(size_t bytes)
+static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa)
{
- int i;
- unsigned int nr_entries;
- const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
+ unsigned nr_entries = 0, ent_sz;
if (!IS_ALIGNED(bytes, PAGE_SIZE)) {
pr_err("%s: wrong size %08x\n", __func__, bytes);
return 0;
}
- nr_entries = 0;
- for (i = 0; i < ARRAY_SIZE(pagesize); i++) {
- if (bytes >= pagesize[i]) {
- nr_entries += (bytes / pagesize[i]);
- bytes %= pagesize[i];
- }
+ while (bytes) {
+ ent_sz = max_alignment(da | pa);
+ ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes));
+ nr_entries++;
+ da += ent_sz;
+ pa += ent_sz;
+ bytes -= ent_sz;
}
- BUG_ON(bytes);
return nr_entries;
}
/* allocate and initialize sg_table header(a kind of 'superblock') */
-static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
+static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags,
+ u32 da, u32 pa)
{
unsigned int nr_entries;
int err;
@@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
if (!IS_ALIGNED(bytes, PAGE_SIZE))
return ERR_PTR(-EINVAL);
- /* FIXME: IOVMF_DA_FIXED should support 'superpages' */
- if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) {
- nr_entries = sgtable_nents(bytes);
+ if (flags & IOVMF_LINEAR) {
+ nr_entries = sgtable_nents(bytes, da, pa);
if (!nr_entries)
return ERR_PTR(-EINVAL);
} else
@@ -273,13 +280,14 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
alignement = PAGE_SIZE;
if (flags & IOVMF_DA_ANON) {
- /*
- * Reserve the first page for NULL
- */
- start = PAGE_SIZE;
+ start = obj->da_start;
+
if (flags & IOVMF_LINEAR)
alignement = iopgsz_max(bytes);
start = roundup(start, alignement);
+ } else if (start < obj->da_start || start > obj->da_end ||
+ obj->da_end - start < bytes) {
+ return ERR_PTR(-EINVAL);
}
tmp = NULL;
@@ -289,19 +297,19 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
prev_end = 0;
list_for_each_entry(tmp, &obj->mmap, list) {
- if (prev_end >= start)
+ if (prev_end > start)
break;
- if (start + bytes < tmp->da_start)
+ if (tmp->da_start > start && (tmp->da_start - start) >= bytes)
goto found;
- if (flags & IOVMF_DA_ANON)
+ if (tmp->da_end >= start && flags & IOVMF_DA_ANON)
start = roundup(tmp->da_end + 1, alignement);
prev_end = tmp->da_end;
}
- if ((start > prev_end) && (ULONG_MAX - start >= bytes))
+ if ((start >= prev_end) && (obj->da_end - start >= bytes))
goto found;
dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n",
@@ -409,7 +417,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
BUG_ON(!sgt);
}
-static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
+static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da,
+ size_t len)
{
unsigned int i;
struct scatterlist *sg;
@@ -418,9 +427,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
va = phys_to_virt(pa);
for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes;
+ unsigned bytes;
- bytes = iopgsz_max(len);
+ bytes = max_alignment(da | pa);
+ bytes = min_t(unsigned, bytes, iopgsz_max(len));
BUG_ON(!iopgsz_ok(bytes));
@@ -429,6 +439,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
* 'pa' is cotinuous(linear).
*/
pa += bytes;
+ da += bytes;
len -= bytes;
}
BUG_ON(len);
@@ -695,18 +706,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
if (!va)
return -ENOMEM;
- sgt = sgtable_alloc(bytes, flags);
+ flags &= IOVMF_HW_MASK;
+ flags |= IOVMF_DISCONT;
+ flags |= IOVMF_ALLOC;
+ flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
+
+ sgt = sgtable_alloc(bytes, flags, da, 0);
if (IS_ERR(sgt)) {
da = PTR_ERR(sgt);
goto err_sgt_alloc;
}
sgtable_fill_vmalloc(sgt, va);
- flags &= IOVMF_HW_MASK;
- flags |= IOVMF_DISCONT;
- flags |= IOVMF_ALLOC;
- flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
-
da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
if (IS_ERR_VALUE(da))
goto err_iommu_vmap;
@@ -746,11 +757,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va,
{
struct sg_table *sgt;
- sgt = sgtable_alloc(bytes, flags);
+ sgt = sgtable_alloc(bytes, flags, da, pa);
if (IS_ERR(sgt))
return PTR_ERR(sgt);
- sgtable_fill_kmalloc(sgt, pa, bytes);
+ sgtable_fill_kmalloc(sgt, pa, da, bytes);
da = map_iommu_region(obj, da, sgt, va, bytes, flags);
if (IS_ERR_VALUE(da)) {
@@ -811,7 +822,7 @@ void iommu_kunmap(struct iommu *obj, u32 da)
struct sg_table *sgt;
typedef void (*func_t)(const void *);
- sgt = unmap_vm_area(obj, da, (func_t)__iounmap,
+ sgt = unmap_vm_area(obj, da, (func_t)iounmap,
IOVMF_LINEAR | IOVMF_MMIO);
if (!sgt)
dev_dbg(obj->dev, "%s: No sgt\n", __func__);
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index d2fafb892f7f..459b319a9fad 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -28,12 +28,12 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <linux/err.h>
+#include <linux/notifier.h>
#include <plat/mailbox.h>
static struct workqueue_struct *mboxd;
static struct omap_mbox **mboxes;
-static bool rq_full;
static int mbox_configured;
static DEFINE_MUTEX(mbox_configured_lock);
@@ -93,20 +93,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
struct omap_mbox_queue *mq = mbox->txq;
int ret = 0, len;
- spin_lock(&mq->lock);
+ spin_lock_bh(&mq->lock);
if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
ret = -ENOMEM;
goto out;
}
+ if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
+ mbox_fifo_write(mbox, msg);
+ goto out;
+ }
+
len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));
tasklet_schedule(&mbox->txq->tasklet);
out:
- spin_unlock(&mq->lock);
+ spin_unlock_bh(&mq->lock);
return ret;
}
EXPORT_SYMBOL(omap_mbox_msg_send);
@@ -146,8 +151,14 @@ static void mbox_rx_work(struct work_struct *work)
len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));
- if (mq->callback)
- mq->callback((void *)msg);
+ blocking_notifier_call_chain(&mq->mbox->notifier, len,
+ (void *)msg);
+ spin_lock_irq(&mq->lock);
+ if (mq->full) {
+ mq->full = false;
+ omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+ }
+ spin_unlock_irq(&mq->lock);
}
}
@@ -170,7 +181,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
while (!mbox_fifo_empty(mbox)) {
if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
omap_mbox_disable_irq(mbox, IRQ_RX);
- rq_full = true;
+ mq->full = true;
goto nomem;
}
@@ -239,73 +250,77 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
int ret = 0;
struct omap_mbox_queue *mq;
- if (mbox->ops->startup) {
- mutex_lock(&mbox_configured_lock);
- if (!mbox_configured)
+ mutex_lock(&mbox_configured_lock);
+ if (!mbox_configured++) {
+ if (likely(mbox->ops->startup)) {
ret = mbox->ops->startup(mbox);
-
- if (ret) {
- mutex_unlock(&mbox_configured_lock);
- return ret;
- }
- mbox_configured++;
- mutex_unlock(&mbox_configured_lock);
- }
-
- ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
- mbox->name, mbox);
- if (ret) {
- printk(KERN_ERR
- "failed to register mailbox interrupt:%d\n", ret);
- goto fail_request_irq;
+ if (unlikely(ret))
+ goto fail_startup;
+ } else
+ goto fail_startup;
}
- mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
- if (!mq) {
- ret = -ENOMEM;
- goto fail_alloc_txq;
- }
- mbox->txq = mq;
+ if (!mbox->use_count++) {
+ ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+ mbox->name, mbox);
+ if (unlikely(ret)) {
+ pr_err("failed to register mailbox interrupt:%d\n",
+ ret);
+ goto fail_request_irq;
+ }
+ mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_txq;
+ }
+ mbox->txq = mq;
- mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
- if (!mq) {
- ret = -ENOMEM;
- goto fail_alloc_rxq;
+ mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_rxq;
+ }
+ mbox->rxq = mq;
+ mq->mbox = mbox;
}
- mbox->rxq = mq;
-
+ mutex_unlock(&mbox_configured_lock);
return 0;
- fail_alloc_rxq:
+fail_alloc_rxq:
mbox_queue_free(mbox->txq);
- fail_alloc_txq:
+fail_alloc_txq:
free_irq(mbox->irq, mbox);
- fail_request_irq:
+fail_request_irq:
if (mbox->ops->shutdown)
mbox->ops->shutdown(mbox);
-
+ mbox->use_count--;
+fail_startup:
+ mbox_configured--;
+ mutex_unlock(&mbox_configured_lock);
return ret;
}
static void omap_mbox_fini(struct omap_mbox *mbox)
{
- free_irq(mbox->irq, mbox);
- tasklet_kill(&mbox->txq->tasklet);
- flush_work(&mbox->rxq->work);
- mbox_queue_free(mbox->txq);
- mbox_queue_free(mbox->rxq);
+ mutex_lock(&mbox_configured_lock);
+
+ if (!--mbox->use_count) {
+ free_irq(mbox->irq, mbox);
+ tasklet_kill(&mbox->txq->tasklet);
+ flush_work(&mbox->rxq->work);
+ mbox_queue_free(mbox->txq);
+ mbox_queue_free(mbox->rxq);
+ }
- if (mbox->ops->shutdown) {
- mutex_lock(&mbox_configured_lock);
- if (mbox_configured > 0)
- mbox_configured--;
- if (!mbox_configured)
+ if (likely(mbox->ops->shutdown)) {
+ if (!--mbox_configured)
mbox->ops->shutdown(mbox);
- mutex_unlock(&mbox_configured_lock);
}
+
+ mutex_unlock(&mbox_configured_lock);
}
-struct omap_mbox *omap_mbox_get(const char *name)
+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
{
struct omap_mbox *mbox;
int ret;
@@ -324,12 +339,16 @@ struct omap_mbox *omap_mbox_get(const char *name)
if (ret)
return ERR_PTR(-ENODEV);
+ if (nb)
+ blocking_notifier_chain_register(&mbox->notifier, nb);
+
return mbox;
}
EXPORT_SYMBOL(omap_mbox_get);
-void omap_mbox_put(struct omap_mbox *mbox)
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
{
+ blocking_notifier_chain_unregister(&mbox->notifier, nb);
omap_mbox_fini(mbox);
}
EXPORT_SYMBOL(omap_mbox_put);
@@ -353,6 +372,8 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list)
ret = PTR_ERR(mbox->dev);
goto err_out;
}
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
}
return 0;
@@ -391,7 +412,8 @@ static int __init omap_mbox_init(void)
/* kfifo size sanity check: alignment and minimal size */
mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
- mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t));
+ mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
+ sizeof(mbox_msg_t));
return 0;
}
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index eac4b978e9fd..b5a6e178a7f9 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -28,6 +28,8 @@
#include <plat/dma.h>
#include <plat/mcbsp.h>
+/* XXX These "sideways" includes are a sign that something is wrong */
+#include "../mach-omap2/cm2xxx_3xxx.h"
#include "../mach-omap2/cm-regbits-34xx.h"
struct omap_mcbsp **mcbsp_ptr;
@@ -234,9 +236,9 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
* Sidetone uses McBSP ICLK - which must not idle when sidetones
* are enabled or sidetones start sounding ugly.
*/
- w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
w &= ~(1 << (mcbsp->id - 2));
- cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
/* Enable McBSP Sidetone */
w = MCBSP_READ(mcbsp, SSELCR);
@@ -263,9 +265,9 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
w = MCBSP_READ(mcbsp, SSELCR);
MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
- w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
w |= 1 << (mcbsp->id - 2);
- cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
}
static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
@@ -755,7 +757,7 @@ int omap_mcbsp_request(unsigned int id)
goto err_kfree;
}
- mcbsp->free = 0;
+ mcbsp->free = false;
mcbsp->reg_cache = reg_cache;
spin_unlock(&mcbsp->lock);
@@ -815,7 +817,7 @@ err_clk_disable:
clk_disable(mcbsp->iclk);
spin_lock(&mcbsp->lock);
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->reg_cache = NULL;
err_kfree:
spin_unlock(&mcbsp->lock);
@@ -858,7 +860,7 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->free)
dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
else
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->reg_cache = NULL;
spin_unlock(&mcbsp->lock);
@@ -1771,7 +1773,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
spin_lock_init(&mcbsp->lock);
mcbsp->id = id + 1;
- mcbsp->free = 1;
+ mcbsp->free = true;
mcbsp->dma_tx_lch = -1;
mcbsp->dma_rx_lch = -1;
@@ -1836,17 +1838,11 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
omap34xx_device_exit(mcbsp);
- clk_disable(mcbsp->fclk);
- clk_disable(mcbsp->iclk);
clk_put(mcbsp->fclk);
clk_put(mcbsp->iclk);
iounmap(mcbsp->io_base);
-
- mcbsp->fclk = NULL;
- mcbsp->iclk = NULL;
- mcbsp->free = 0;
- mcbsp->dev = NULL;
+ kfree(mcbsp);
}
return 0;
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index e129ce80c53b..b0471bb2d47d 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -20,15 +20,14 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
/* Interface documentation is in mach/omap-pm.h */
#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
-#include <plat/powerdomain.h>
-
-struct omap_opp *dsp_opps;
-struct omap_opp *mpu_opps;
-struct omap_opp *l3_opps;
+static bool off_mode_enabled;
+static u32 dummy_context_loss_counter;
/*
* Device-driver-originated constraints (via board-*.c files)
@@ -284,37 +283,70 @@ unsigned long omap_pm_cpu_get_freq(void)
return 0;
}
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+ off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+ off_mode_enabled = false;
+}
+
/*
* Device context loss tracking
*/
-int omap_pm_get_dev_context_loss_count(struct device *dev)
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
{
- if (!dev) {
- WARN_ON(1);
- return -EINVAL;
- };
+ struct platform_device *pdev = to_platform_device(dev);
+ u32 count;
+
+ if (WARN_ON(!dev))
+ return 0;
+
+ if (dev->parent == &omap_device_parent) {
+ count = omap_device_get_context_loss_count(pdev);
+ } else {
+ WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
+ dev_name(dev));
+ if (off_mode_enabled)
+ dummy_context_loss_counter++;
+ count = dummy_context_loss_counter;
+ }
- pr_debug("OMAP PM: returning context loss count for dev %s\n",
- dev_name(dev));
+ pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+ dev_name(dev), count);
- /*
- * Map the device to the powerdomain. Return the powerdomain
- * off counter.
- */
+ return count;
+}
- return 0;
+#else
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ return dummy_context_loss_counter;
}
+#endif
/* Should be called before clk framework init */
-int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
- struct omap_opp *dsp_opp_table,
- struct omap_opp *l3_opp_table)
+int __init omap_pm_if_early_init(void)
{
- mpu_opps = mpu_opp_table;
- dsp_opps = dsp_opp_table;
- l3_opps = l3_opp_table;
return 0;
}
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index abe933cd8f09..57adb270767b 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -280,6 +280,34 @@ static void _add_optional_clock_alias(struct omap_device *od,
/* Public functions for use by core code */
/**
+ * omap_device_get_context_loss_count - get lost context count
+ * @od: struct omap_device *
+ *
+ * Using the primary hwmod, query the context loss count for this
+ * device.
+ *
+ * Callers should consider context for this device lost any time this
+ * function returns a value different than the value the caller got
+ * the last time it called this function.
+ *
+ * If any hwmods exist for the omap_device assoiated with @pdev,
+ * return the context loss counter for that hwmod, otherwise return
+ * zero.
+ */
+u32 omap_device_get_context_loss_count(struct platform_device *pdev)
+{
+ struct omap_device *od;
+ u32 ret = 0;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->hwmods_cnt)
+ ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
+
+ return ret;
+}
+
+/**
* omap_device_count_resources - count number of struct resource entries needed
* @od: struct omap_device *
*
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e2c8eebe6b3a..e26e50487d60 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -33,23 +33,21 @@
#include "sram.h"
#include "fb.h"
+
+/* XXX These "sideways" includes are a sign that something is wrong */
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-# include "../mach-omap2/prm.h"
-# include "../mach-omap2/cm.h"
+# include "../mach-omap2/prm2xxx_3xxx.h"
# include "../mach-omap2/sdrc.h"
#endif
#define OMAP1_SRAM_PA 0x20000000
#define OMAP1_SRAM_VA VMALLOC_END
-#define OMAP2_SRAM_PA 0x40200000
-#define OMAP2_SRAM_PUB_PA 0x4020f800
+#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
#define OMAP2_SRAM_VA 0xfe400000
#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
-#define OMAP3_SRAM_PA 0x40200000
#define OMAP3_SRAM_VA 0xfe400000
-#define OMAP3_SRAM_PUB_PA 0x40208000
+#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
#define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000)
-#define OMAP4_SRAM_PA 0x40300000
#define OMAP4_SRAM_VA 0xfe400000
#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000)
@@ -166,7 +164,7 @@ static void __init omap_detect_sram(void)
cpu_is_omap1710())
omap_sram_size = 0x4000; /* 16K */
else if (cpu_is_omap1611())
- omap_sram_size = 0x3e800; /* 250K */
+ omap_sram_size = SZ_256K;
else {
printk(KERN_ERR "Could not detect SRAM size\n");
omap_sram_size = 0x4000;
@@ -270,7 +268,7 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
_omap_sram_reprogram_clock(dpllctl, ckctl);
}
-int __init omap1_sram_init(void)
+static int __init omap1_sram_init(void)
{
_omap_sram_reprogram_clock =
omap_sram_push(omap1_sram_reprogram_clock,
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index 715a30177f28..c3da2478b2aa 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -13,11 +13,11 @@
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/cnt32_to_63.h>
#include <linux/timer.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <asm/sched_clock.h>
#include <asm/mach/time.h>
#include <mach/bridge-regs.h>
#include <mach/hardware.h>
@@ -44,52 +44,26 @@ static u32 ticks_per_jiffy;
/*
* Orion's sched_clock implementation. It has a resolution of
- * at least 7.5ns (133MHz TCLK) and a maximum value of 834 days.
- *
- * Because the hardware timer period is quite short (21 secs if
- * 200MHz TCLK) and because cnt32_to_63() needs to be called at
- * least once per half period to work properly, a kernel timer is
- * set up to ensure this requirement is always met.
+ * at least 7.5ns (133MHz TCLK).
*/
-#define TCLK2NS_SCALE_FACTOR 8
-
-static unsigned long tclk2ns_scale;
+static DEFINE_CLOCK_DATA(cd);
-unsigned long long sched_clock(void)
+unsigned long long notrace sched_clock(void)
{
- unsigned long long v = cnt32_to_63(0xffffffff - readl(TIMER0_VAL));
- return (v * tclk2ns_scale) >> TCLK2NS_SCALE_FACTOR;
+ u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
}
-static struct timer_list cnt32_to_63_keepwarm_timer;
-static void cnt32_to_63_keepwarm(unsigned long data)
+static void notrace orion_update_sched_clock(void)
{
- mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- (void) sched_clock();
+ u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+ update_sched_clock(&cd, cyc, (u32)~0);
}
static void __init setup_sched_clock(unsigned long tclk)
{
- unsigned long long v;
- unsigned long data;
-
- v = NSEC_PER_SEC;
- v <<= TCLK2NS_SCALE_FACTOR;
- v += tclk/2;
- do_div(v, tclk);
- /*
- * We want an even value to automatically clear the top bit
- * returned by cnt32_to_63() without an additional run time
- * instruction. So if the LSB is 1 then round it up.
- */
- if (v & 1)
- v++;
- tclk2ns_scale = v;
-
- data = (0xffffffffUL / tclk / 2 - 2) * HZ;
- setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
- mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
+ init_sched_clock(&cd, orion_update_sched_clock, 32, tclk);
}
/*
@@ -102,7 +76,6 @@ static cycle_t orion_clksrc_read(struct clocksource *cs)
static struct clocksource orion_clksrc = {
.name = "orion_clocksource",
- .shift = 20,
.rating = 300,
.read = orion_clksrc_read,
.mask = CLOCKSOURCE_MASK(32),
@@ -245,8 +218,7 @@ void __init orion_time_init(unsigned int irq, unsigned int tclk)
writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK);
u = readl(TIMER_CTRL);
writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL);
- orion_clksrc.mult = clocksource_hz2mult(tclk, orion_clksrc.shift);
- clocksource_register(&orion_clksrc);
+ clocksource_register_hz(&orion_clksrc, tclk);
/*
* Setup clockevent timer (interrupt-driven.)
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 4aacdd12c9cc..3aca5ba0f876 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -6,6 +6,7 @@ obj-y := dma.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PXA3xx) += mfp.o
+obj-$(CONFIG_PXA95x) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
index 9e604c80618f..75f656471240 100644
--- a/arch/arm/plat-pxa/include/plat/mfp.h
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -423,7 +423,7 @@ typedef unsigned long mfp_cfg_t;
((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
(MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
-#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) || defined(CONFIG_ARCH_MMP)
/*
* each MFP pin will have a MFPR register, since the offset of the
* register varies between processors, the processor specific code
@@ -470,6 +470,6 @@ void mfp_write(int mfp, unsigned long mfpr_val);
void mfp_config(unsigned long *mfp_cfgs, int num);
void mfp_config_run(void);
void mfp_config_lpm(void);
-#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
+#endif /* CONFIG_PXA3xx || CONFIG_PXA95x || CONFIG_ARCH_MMP */
#endif /* __ASM_PLAT_MFP_H */
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 5a27b1b538f2..eb105e61c746 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -8,7 +8,7 @@ config PLAT_S3C24XX
default y
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
- select S3C_DEVICE_NAND
+ select S3C_DEV_NAND
select S3C_GPIO_CFG_S3C24XX
help
Base platform code for any Samsung S3C24XX device
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 76d0858c3cbb..4a10c0f684b2 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440000,
.idmask = 0xffffffff,
- .map_io = s3c244x_map_io,
+ .map_io = s3c2440_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
@@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440001,
.idmask = 0xffffffff,
- .map_io = s3c244x_map_io,
+ .map_io = s3c2440_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
@@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440aaa,
.idmask = 0xffffffff,
- .map_io = s3c244x_map_io,
+ .map_io = s3c2442_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2442_init,
@@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440aab,
.idmask = 0xffffffff,
- .map_io = s3c244x_map_io,
+ .map_io = s3c2442_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2442_init,
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 2f91057a0c02..8a42bc48dbf0 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -259,21 +259,6 @@ struct platform_device s3c_device_iis = {
EXPORT_SYMBOL(s3c_device_iis);
-/* ASoC PCM DMA */
-
-static u64 s3c_device_audio_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_pcm = {
- .name = "s3c24xx-pcm-audio",
- .id = -1,
- .dev = {
- .dma_mask = &s3c_device_audio_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-
-EXPORT_SYMBOL(s3c_device_pcm);
-
/* RTC */
static struct resource s3c_rtc_resource[] = {
@@ -496,8 +481,10 @@ static struct resource s3c_ac97_resource[] = {
},
};
+static u64 s3c_device_audio_dmamask = 0xffffffffUL;
+
struct platform_device s3c_device_ac97 = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_ac97_resource),
.resource = s3c_ac97_resource,
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 24c6f5a30596..243b6411050d 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
- .set_pull = s3c_gpio_setpull_1up,
- .get_pull = s3c_gpio_getpull_1up,
};
struct s3c_gpio_chip s3c24xx_gpios[] = {
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 69e1be8bec35..ec087d6054b1 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -107,9 +107,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
/* exported for use in arch/arm/mach-s3c2410 */
#ifdef CONFIG_PM
-extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
#else
#define s3c_irq_wake NULL
#endif
-extern int s3c_irqext_type(unsigned int irq, unsigned int type);
+extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
index 307248d1ccbb..89e8d0a25f87 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
@@ -21,17 +21,22 @@ 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);
+
+extern void s3c2440_map_io(void);
#else
#define s3c2440_init NULL
+#define s3c2440_map_io NULL
#endif
#ifdef CONFIG_CPU_S3C2442
extern int s3c2442_init(void);
+
+extern void s3c2442_map_io(void);
#else
#define s3c2442_init NULL
+#define s3c2442_map_io NULL
#endif
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
index ea8dea3339a4..c3624d898630 100644
--- a/arch/arm/plat-s3c24xx/irq-pm.c
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -15,11 +15,14 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
+#include <linux/irq.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/irq.h>
+#include <asm/irq.h>
+
/* state for IRQs over sleep */
/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
@@ -30,15 +33,15 @@
unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
-int s3c_irq_wake(unsigned int irqno, unsigned int state)
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
{
- unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+ unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
if (!(s3c_irqwake_intallow & irqbit))
return -ENOENT;
printk(KERN_INFO "wake %s for irq %d\n",
- state ? "enabled" : "disabled", irqno);
+ state ? "enabled" : "disabled", data->irq);
if (!state)
s3c_irqwake_intmask |= irqbit;
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ad0d44ef1f93..4434cb56bd9a 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -34,30 +34,29 @@
#include <plat/irq.h>
static void
-s3c_irq_mask(unsigned int irqno)
+s3c_irq_mask(struct irq_data *data)
{
+ unsigned int irqno = data->irq - IRQ_EINT0;
unsigned long mask;
- irqno -= IRQ_EINT0;
-
mask = __raw_readl(S3C2410_INTMSK);
mask |= 1UL << irqno;
__raw_writel(mask, S3C2410_INTMSK);
}
static inline void
-s3c_irq_ack(unsigned int irqno)
+s3c_irq_ack(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
__raw_writel(bitval, S3C2410_SRCPND);
__raw_writel(bitval, S3C2410_INTPND);
}
static inline void
-s3c_irq_maskack(unsigned int irqno)
+s3c_irq_maskack(struct irq_data *data)
{
- unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
@@ -69,8 +68,9 @@ s3c_irq_maskack(unsigned int irqno)
static void
-s3c_irq_unmask(unsigned int irqno)
+s3c_irq_unmask(struct irq_data *data)
{
+ unsigned int irqno = data->irq;
unsigned long mask;
if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
@@ -85,40 +85,39 @@ s3c_irq_unmask(unsigned int irqno)
struct irq_chip s3c_irq_level_chip = {
.name = "s3c-level",
- .ack = s3c_irq_maskack,
- .mask = s3c_irq_mask,
- .unmask = s3c_irq_unmask,
- .set_wake = s3c_irq_wake
+ .irq_ack = s3c_irq_maskack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake
};
struct irq_chip s3c_irq_chip = {
.name = "s3c",
- .ack = s3c_irq_ack,
- .mask = s3c_irq_mask,
- .unmask = s3c_irq_unmask,
- .set_wake = s3c_irq_wake
+ .irq_ack = s3c_irq_ack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake
};
static void
-s3c_irqext_mask(unsigned int irqno)
+s3c_irqext_mask(struct irq_data *data)
{
+ unsigned int irqno = data->irq - EXTINT_OFF;
unsigned long mask;
- irqno -= EXTINT_OFF;
-
mask = __raw_readl(S3C24XX_EINTMASK);
mask |= ( 1UL << irqno);
__raw_writel(mask, S3C24XX_EINTMASK);
}
static void
-s3c_irqext_ack(unsigned int irqno)
+s3c_irqext_ack(struct irq_data *data)
{
unsigned long req;
unsigned long bit;
unsigned long mask;
- bit = 1UL << (irqno - EXTINT_OFF);
+ bit = 1UL << (data->irq - EXTINT_OFF);
mask = __raw_readl(S3C24XX_EINTMASK);
@@ -129,64 +128,57 @@ s3c_irqext_ack(unsigned int irqno)
/* not sure if we should be acking the parent irq... */
- if (irqno <= IRQ_EINT7 ) {
+ if (data->irq <= IRQ_EINT7) {
if ((req & 0xf0) == 0)
- s3c_irq_ack(IRQ_EINT4t7);
+ s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7));
} else {
if ((req >> 8) == 0)
- s3c_irq_ack(IRQ_EINT8t23);
+ s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23));
}
}
static void
-s3c_irqext_unmask(unsigned int irqno)
+s3c_irqext_unmask(struct irq_data *data)
{
+ unsigned int irqno = data->irq - EXTINT_OFF;
unsigned long mask;
- irqno -= EXTINT_OFF;
-
mask = __raw_readl(S3C24XX_EINTMASK);
- mask &= ~( 1UL << irqno);
+ mask &= ~(1UL << irqno);
__raw_writel(mask, S3C24XX_EINTMASK);
}
int
-s3c_irqext_type(unsigned int irq, unsigned int type)
+s3c_irqext_type(struct irq_data *data, unsigned int type)
{
void __iomem *extint_reg;
void __iomem *gpcon_reg;
unsigned long gpcon_offset, extint_offset;
unsigned long newvalue = 0, value;
- if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
- {
+ if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) {
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C24XX_EXTINT0;
- gpcon_offset = (irq - IRQ_EINT0) * 2;
- extint_offset = (irq - IRQ_EINT0) * 4;
- }
- else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
- {
+ gpcon_offset = (data->irq - IRQ_EINT0) * 2;
+ extint_offset = (data->irq - IRQ_EINT0) * 4;
+ } else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) {
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C24XX_EXTINT0;
- gpcon_offset = (irq - (EXTINT_OFF)) * 2;
- extint_offset = (irq - (EXTINT_OFF)) * 4;
- }
- else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
- {
+ gpcon_offset = (data->irq - (EXTINT_OFF)) * 2;
+ extint_offset = (data->irq - (EXTINT_OFF)) * 4;
+ } else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) {
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C24XX_EXTINT1;
- gpcon_offset = (irq - IRQ_EINT8) * 2;
- extint_offset = (irq - IRQ_EINT8) * 4;
- }
- else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
- {
+ gpcon_offset = (data->irq - IRQ_EINT8) * 2;
+ extint_offset = (data->irq - IRQ_EINT8) * 4;
+ } else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) {
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C24XX_EXTINT2;
- gpcon_offset = (irq - IRQ_EINT8) * 2;
- extint_offset = (irq - IRQ_EINT16) * 4;
- } else
+ gpcon_offset = (data->irq - IRQ_EINT8) * 2;
+ extint_offset = (data->irq - IRQ_EINT16) * 4;
+ } else {
return -1;
+ }
/* Set the GPIO to external interrupt mode */
value = __raw_readl(gpcon_reg);
@@ -234,20 +226,20 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
static struct irq_chip s3c_irqext_chip = {
.name = "s3c-ext",
- .mask = s3c_irqext_mask,
- .unmask = s3c_irqext_unmask,
- .ack = s3c_irqext_ack,
- .set_type = s3c_irqext_type,
- .set_wake = s3c_irqext_wake
+ .irq_mask = s3c_irqext_mask,
+ .irq_unmask = s3c_irqext_unmask,
+ .irq_ack = s3c_irqext_ack,
+ .irq_set_type = s3c_irqext_type,
+ .irq_set_wake = s3c_irqext_wake
};
static struct irq_chip s3c_irq_eint0t4 = {
.name = "s3c-ext0",
- .ack = s3c_irq_ack,
- .mask = s3c_irq_mask,
- .unmask = s3c_irq_unmask,
- .set_wake = s3c_irq_wake,
- .set_type = s3c_irqext_type,
+ .irq_ack = s3c_irq_ack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake,
+ .irq_set_type = s3c_irqext_type,
};
/* mask values for the parent registers for each of the interrupt types */
@@ -261,109 +253,109 @@ static struct irq_chip s3c_irq_eint0t4 = {
/* UART0 */
static void
-s3c_irq_uart0_mask(unsigned int irqno)
+s3c_irq_uart0_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+ s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
}
static void
-s3c_irq_uart0_unmask(unsigned int irqno)
+s3c_irq_uart0_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_UART0);
+ s3c_irqsub_unmask(data->irq, INTMSK_UART0);
}
static void
-s3c_irq_uart0_ack(unsigned int irqno)
+s3c_irq_uart0_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+ s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
}
static struct irq_chip s3c_irq_uart0 = {
.name = "s3c-uart0",
- .mask = s3c_irq_uart0_mask,
- .unmask = s3c_irq_uart0_unmask,
- .ack = s3c_irq_uart0_ack,
+ .irq_mask = s3c_irq_uart0_mask,
+ .irq_unmask = s3c_irq_uart0_unmask,
+ .irq_ack = s3c_irq_uart0_ack,
};
/* UART1 */
static void
-s3c_irq_uart1_mask(unsigned int irqno)
+s3c_irq_uart1_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+ s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
}
static void
-s3c_irq_uart1_unmask(unsigned int irqno)
+s3c_irq_uart1_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_UART1);
+ s3c_irqsub_unmask(data->irq, INTMSK_UART1);
}
static void
-s3c_irq_uart1_ack(unsigned int irqno)
+s3c_irq_uart1_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+ s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
}
static struct irq_chip s3c_irq_uart1 = {
.name = "s3c-uart1",
- .mask = s3c_irq_uart1_mask,
- .unmask = s3c_irq_uart1_unmask,
- .ack = s3c_irq_uart1_ack,
+ .irq_mask = s3c_irq_uart1_mask,
+ .irq_unmask = s3c_irq_uart1_unmask,
+ .irq_ack = s3c_irq_uart1_ack,
};
/* UART2 */
static void
-s3c_irq_uart2_mask(unsigned int irqno)
+s3c_irq_uart2_mask(struct irq_data *data)
{
- s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+ s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
}
static void
-s3c_irq_uart2_unmask(unsigned int irqno)
+s3c_irq_uart2_unmask(struct irq_data *data)
{
- s3c_irqsub_unmask(irqno, INTMSK_UART2);
+ s3c_irqsub_unmask(data->irq, INTMSK_UART2);
}
static void
-s3c_irq_uart2_ack(unsigned int irqno)
+s3c_irq_uart2_ack(struct irq_data *data)
{
- s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+ s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
}
static struct irq_chip s3c_irq_uart2 = {
.name = "s3c-uart2",
- .mask = s3c_irq_uart2_mask,
- .unmask = s3c_irq_uart2_unmask,
- .ack = s3c_irq_uart2_ack,
+ .irq_mask = s3c_irq_uart2_mask,
+ .irq_unmask = s3c_irq_uart2_unmask,
+ .irq_ack = s3c_irq_uart2_ack,
};
/* ADC and Touchscreen */
static void
-s3c_irq_adc_mask(unsigned int irqno)
+s3c_irq_adc_mask(struct irq_data *d)
{
- s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+ s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
}
static void
-s3c_irq_adc_unmask(unsigned int irqno)
+s3c_irq_adc_unmask(struct irq_data *d)
{
- s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+ s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
}
static void
-s3c_irq_adc_ack(unsigned int irqno)
+s3c_irq_adc_ack(struct irq_data *d)
{
- s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+ s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
}
static struct irq_chip s3c_irq_adc = {
.name = "s3c-adc",
- .mask = s3c_irq_adc_mask,
- .unmask = s3c_irq_adc_unmask,
- .ack = s3c_irq_adc_ack,
+ .irq_mask = s3c_irq_adc_mask,
+ .irq_unmask = s3c_irq_adc_unmask,
+ .irq_ack = s3c_irq_adc_ack,
};
/* irq demux for adc */
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 65dbfa8e0a86..6a161f317a79 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -56,3 +56,13 @@ config S5P_DEV_ONENAND
bool
help
Compile in platform device definition for OneNAND controller
+
+config S5P_DEV_CSIS0
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 0
+
+config S5P_DEV_CSIS1
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 1
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index de65238a7aef..2b7317378103 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -28,3 +28,5 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
+obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
+obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index 74f7f5a5446c..047d31c1bbd8 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -108,6 +108,11 @@ static struct map_desc s5p_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S3C_PA_WDT),
.length = SZ_4K,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(S5P_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
},
};
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
new file mode 100644
index 000000000000..dfab1c85f54f
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * S5P series device definition for MIPI-CSIS channel 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/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+
+static struct resource s5p_mipi_csis0_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS0,
+ .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPI_CSIS0,
+ .end = IRQ_MIPI_CSIS0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_mipi_csis0 = {
+ .name = "s5p-mipi-csis",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
+ .resource = s5p_mipi_csis0_resource,
+};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
new file mode 100644
index 000000000000..e3053f27fbbf
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * S5P series device definition for MIPI-CSIS channel 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/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+
+static struct resource s5p_mipi_csis1_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS1,
+ .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPI_CSIS1,
+ .end = IRQ_MIPI_CSIS1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_mipi_csis1 = {
+ .name = "s5p-mipi-csis",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
+ .resource = s5p_mipi_csis1_resource,
+};
diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h
new file mode 100644
index 000000000000..51e308c7981d
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/csis.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * S5P series MIPI CSI slave device 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 PLAT_S5P_CSIS_H_
+#define PLAT_S5P_CSIS_H_ __FILE__
+
+/**
+ * struct s5p_platform_mipi_csis - platform data for MIPI-CSIS
+ * @clk_rate: bus clock frequency
+ * @lanes: number of data lanes used
+ * @alignment: data alignment in bits
+ * @hs_settle: HS-RX settle time
+ */
+struct s5p_platform_mipi_csis {
+ unsigned long clk_rate;
+ u8 lanes;
+ u8 alignment;
+ u8 hs_settle;
+};
+
+#endif /* PLAT_S5P_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index fef353d44513..d973d39666a3 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -15,6 +15,7 @@
#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
#define S5P_VA_CMU S3C_ADDR(0x02100000)
+#define S5P_VA_PMU S3C_ADDR(0x02180000)
#define S5P_VA_GPIO S3C_ADDR(0x02200000)
#define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
new file mode 100644
index 000000000000..f121ab5e76cb
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P SROMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_REGS_SROM_H
+#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
+
+#define S5P_SROM_BW S5P_SROMREG(0x0)
+#define S5P_SROM_BC0 S5P_SROMREG(0x4)
+#define S5P_SROM_BC1 S5P_SROMREG(0x8)
+#define S5P_SROM_BC2 S5P_SROMREG(0xc)
+#define S5P_SROM_BC3 S5P_SROMREG(0x10)
+#define S5P_SROM_BC4 S5P_SROMREG(0x14)
+#define S5P_SROM_BC5 S5P_SROMREG(0x18)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
+#define S5P_SROM_BW__ADDRMODE__SHIFT 1
+#define S5P_SROM_BW__WAITENABLE__SHIFT 2
+#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
+
+#define S5P_SROM_BW__CS_MASK 0xf
+
+#define S5P_SROM_BW__NCS0__SHIFT 0
+#define S5P_SROM_BW__NCS1__SHIFT 4
+#define S5P_SROM_BW__NCS2__SHIFT 8
+#define S5P_SROM_BW__NCS3__SHIFT 12
+#define S5P_SROM_BW__NCS4__SHIFT 16
+#define S5P_SROM_BW__NCS5__SHIFT 20
+
+/* applies to same to BCS0 - BCS3 */
+
+#define S5P_SROM_BCX__PMC__SHIFT 0
+#define S5P_SROM_BCX__TACP__SHIFT 4
+#define S5P_SROM_BCX__TCAH__SHIFT 8
+#define S5P_SROM_BCX__TCOH__SHIFT 12
+#define S5P_SROM_BCX__TACC__SHIFT 16
+#define S5P_SROM_BCX__TCOS__SHIFT 24
+#define S5P_SROM_BCX__TACS__SHIFT 28
+
+#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 752f1a645f9d..225aa25405db 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -28,39 +28,40 @@
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
-static inline void s5p_irq_eint_mask(unsigned int irq)
+static inline void s5p_irq_eint_mask(struct irq_data *data)
{
u32 mask;
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
- mask |= eint_irq_to_bit(irq);
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask |= eint_irq_to_bit(data->irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
}
-static void s5p_irq_eint_unmask(unsigned int irq)
+static void s5p_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
- mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
- mask &= ~(eint_irq_to_bit(irq));
- __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask &= ~(eint_irq_to_bit(data->irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
}
-static inline void s5p_irq_eint_ack(unsigned int irq)
+static inline void s5p_irq_eint_ack(struct irq_data *data)
{
- __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
}
-static void s5p_irq_eint_maskack(unsigned int irq)
+static void s5p_irq_eint_maskack(struct irq_data *data)
{
/* compiler should in-line these */
- s5p_irq_eint_mask(irq);
- s5p_irq_eint_ack(irq);
+ s5p_irq_eint_mask(data);
+ s5p_irq_eint_ack(data);
}
-static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
+static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
- int offs = EINT_OFFSET(irq);
+ int offs = EINT_OFFSET(data->irq);
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
@@ -94,10 +95,10 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
shift = (offs & 0x7) * 4;
mask = 0x7 << shift;
- ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
ctrl &= ~mask;
ctrl |= newvalue << shift;
- __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
if ((0 <= offs) && (offs < 8))
s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
@@ -119,13 +120,13 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
static struct irq_chip s5p_irq_eint = {
.name = "s5p-eint",
- .mask = s5p_irq_eint_mask,
- .unmask = s5p_irq_eint_unmask,
- .mask_ack = s5p_irq_eint_maskack,
- .ack = s5p_irq_eint_ack,
- .set_type = s5p_irq_eint_set_type,
+ .irq_mask = s5p_irq_eint_mask,
+ .irq_unmask = s5p_irq_eint_unmask,
+ .irq_mask_ack = s5p_irq_eint_maskack,
+ .irq_ack = s5p_irq_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
#ifdef CONFIG_PM
- .set_wake = s3c_irqext_wake,
+ .irq_set_wake = s3c_irqext_wake,
#endif
};
@@ -159,42 +160,43 @@ static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
s5p_irq_demux_eint(IRQ_EINT(24));
}
-static inline void s5p_irq_vic_eint_mask(unsigned int irq)
+static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
{
- void __iomem *base = get_irq_chip_data(irq);
+ void __iomem *base = irq_data_get_irq_chip_data(data);
- s5p_irq_eint_mask(irq);
- writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE_CLEAR);
+ s5p_irq_eint_mask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
}
-static void s5p_irq_vic_eint_unmask(unsigned int irq)
+static void s5p_irq_vic_eint_unmask(struct irq_data *data)
{
- void __iomem *base = get_irq_chip_data(irq);
+ void __iomem *base = irq_data_get_irq_chip_data(data);
- s5p_irq_eint_unmask(irq);
- writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE);
+ s5p_irq_eint_unmask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
}
-static inline void s5p_irq_vic_eint_ack(unsigned int irq)
+static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
{
- __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
}
-static void s5p_irq_vic_eint_maskack(unsigned int irq)
+static void s5p_irq_vic_eint_maskack(struct irq_data *data)
{
- s5p_irq_vic_eint_mask(irq);
- s5p_irq_vic_eint_ack(irq);
+ s5p_irq_vic_eint_mask(data);
+ s5p_irq_vic_eint_ack(data);
}
static struct irq_chip s5p_irq_vic_eint = {
.name = "s5p_vic_eint",
- .mask = s5p_irq_vic_eint_mask,
- .unmask = s5p_irq_vic_eint_unmask,
- .mask_ack = s5p_irq_vic_eint_maskack,
- .ack = s5p_irq_vic_eint_ack,
- .set_type = s5p_irq_eint_set_type,
+ .irq_mask = s5p_irq_vic_eint_mask,
+ .irq_unmask = s5p_irq_vic_eint_unmask,
+ .irq_mask_ack = s5p_irq_vic_eint_maskack,
+ .irq_ack = s5p_irq_vic_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
#ifdef CONFIG_PM
- .set_wake = s3c_irqext_wake,
+ .irq_set_wake = s3c_irqext_wake,
#endif
};
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 0e5dc8cbf5e3..3b6bf89d1739 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -30,9 +30,9 @@
static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
-static int s5p_gpioint_get_group(unsigned int irq)
+static int s5p_gpioint_get_group(struct irq_data *data)
{
- struct gpio_chip *chip = get_irq_data(irq);
+ struct gpio_chip *chip = irq_data_get_irq_data(data);
struct s3c_gpio_chip *s3c_chip = container_of(chip,
struct s3c_gpio_chip, chip);
int group;
@@ -44,22 +44,22 @@ static int s5p_gpioint_get_group(unsigned int irq)
return group;
}
-static int s5p_gpioint_get_offset(unsigned int irq)
+static int s5p_gpioint_get_offset(struct irq_data *data)
{
- struct gpio_chip *chip = get_irq_data(irq);
+ struct gpio_chip *chip = irq_data_get_irq_data(data);
struct s3c_gpio_chip *s3c_chip = container_of(chip,
struct s3c_gpio_chip, chip);
- return irq - s3c_chip->irq_base;
+ return data->irq - s3c_chip->irq_base;
}
-static void s5p_gpioint_ack(unsigned int irq)
+static void s5p_gpioint_ack(struct irq_data *data)
{
int group, offset, pend_offset;
unsigned int value;
- group = s5p_gpioint_get_group(irq);
- offset = s5p_gpioint_get_offset(irq);
+ group = s5p_gpioint_get_group(data);
+ offset = s5p_gpioint_get_offset(data);
pend_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
@@ -67,13 +67,13 @@ static void s5p_gpioint_ack(unsigned int irq)
__raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
}
-static void s5p_gpioint_mask(unsigned int irq)
+static void s5p_gpioint_mask(struct irq_data *data)
{
int group, offset, mask_offset;
unsigned int value;
- group = s5p_gpioint_get_group(irq);
- offset = s5p_gpioint_get_offset(irq);
+ group = s5p_gpioint_get_group(data);
+ offset = s5p_gpioint_get_offset(data);
mask_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -81,13 +81,13 @@ static void s5p_gpioint_mask(unsigned int irq)
__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
}
-static void s5p_gpioint_unmask(unsigned int irq)
+static void s5p_gpioint_unmask(struct irq_data *data)
{
int group, offset, mask_offset;
unsigned int value;
- group = s5p_gpioint_get_group(irq);
- offset = s5p_gpioint_get_offset(irq);
+ group = s5p_gpioint_get_group(data);
+ offset = s5p_gpioint_get_offset(data);
mask_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -95,19 +95,19 @@ static void s5p_gpioint_unmask(unsigned int irq)
__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
}
-static void s5p_gpioint_mask_ack(unsigned int irq)
+static void s5p_gpioint_mask_ack(struct irq_data *data)
{
- s5p_gpioint_mask(irq);
- s5p_gpioint_ack(irq);
+ s5p_gpioint_mask(data);
+ s5p_gpioint_ack(data);
}
-static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
+static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
{
int group, offset, con_offset;
unsigned int value;
- group = s5p_gpioint_get_group(irq);
- offset = s5p_gpioint_get_offset(irq);
+ group = s5p_gpioint_get_group(data);
+ offset = s5p_gpioint_get_offset(data);
con_offset = group << 2;
switch (type) {
@@ -142,11 +142,11 @@ static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
struct irq_chip s5p_gpioint = {
.name = "s5p_gpioint",
- .ack = s5p_gpioint_ack,
- .mask = s5p_gpioint_mask,
- .mask_ack = s5p_gpioint_mask_ack,
- .unmask = s5p_gpioint_unmask,
- .set_type = s5p_gpioint_set_type,
+ .irq_ack = s5p_gpioint_ack,
+ .irq_mask = s5p_gpioint_mask,
+ .irq_mask_ack = s5p_gpioint_mask_ack,
+ .irq_unmask = s5p_gpioint_unmask,
+ .irq_set_type = s5p_gpioint_set_type,
};
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
index dc33b9ecda45..5259ad458bc8 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -37,14 +37,14 @@
unsigned long s3c_irqwake_intallow = 0x00000006L;
unsigned long s3c_irqwake_eintallow = 0xffffffffL;
-int s3c_irq_wake(unsigned int irqno, unsigned int state)
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
{
unsigned long irqbit;
- switch (irqno) {
+ switch (data->irq) {
case IRQ_RTC_TIC:
case IRQ_RTC_ALARM:
- irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
+ irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
if (!state)
s3c_irqwake_intmask |= irqbit;
else
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index dcd6eff4ee53..2ebf4157d93a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -333,4 +333,12 @@ config SAMSUNG_WAKEMASK
and above. This code allows a set of interrupt to wakeup-mask
mappings. See <plat/wakeup-mask.h>
+comment "Power Domain"
+
+config SAMSUNG_PD
+ bool "Samsung Power Domain"
+ depends on PM_RUNTIME
+ help
+ Say Y here if you want to control Power Domain by Runtime PM.
+
endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index afcce474af8e..29932f88a8d6 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -17,6 +17,7 @@ obj-y += clock.o
obj-y += pwm-clock.o
obj-y += gpio.o
obj-y += gpio-config.o
+obj-y += dev-asocdma.o
obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o
obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
@@ -73,6 +74,10 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
+# PD support
+
+obj-$(CONFIG_SAMSUNG_PD) += pd.o
+
# PWM support
obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
new file mode 100644
index 000000000000..a068c4f42d56
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-samsung/dev-asocdma.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. 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/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <plat/devs.h>
+
+static u64 audio_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_dma = {
+ .name = "samsung-audio",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_dma);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index b732b773b9af..0aa32f242ee4 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
}
#endif
-#ifdef CONFIG_S3C_GPIO_PULL_UP
-int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull)
+#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
+static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull,
+ s3c_gpio_pull_t updown)
{
void __iomem *reg = chip->base + 0x08;
u32 pup = __raw_readl(reg);
- pup = __raw_readl(reg);
-
- if (pup == S3C_GPIO_PULL_UP)
+ if (pull == updown)
pup &= ~(1 << off);
- else if (pup == S3C_GPIO_PULL_NONE)
+ else if (pull == S3C_GPIO_PULL_NONE)
pup |= (1 << off);
else
return -EINVAL;
@@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
return 0;
}
-s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
- unsigned int off)
+static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t updown)
{
void __iomem *reg = chip->base + 0x08;
u32 pup = __raw_readl(reg);
pup &= (1 << off);
- return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+ return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
}
#endif /* CONFIG_S3C_GPIO_PULL_UP */
+#ifdef CONFIG_S3C_GPIO_PULL_DOWN
+s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
+
#ifdef CONFIG_S5P_GPIO_DRVSTR
s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
{
diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c
index c354089254fc..ea37c0461788 100644
--- a/arch/arm/plat-samsung/gpiolib.c
+++ b/arch/arm/plat-samsung/gpiolib.c
@@ -197,3 +197,10 @@ void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
s3c_gpiolib_add(chip);
}
}
+
+void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++)
+ s3c_gpiolib_add(chip);
+}
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index 7712ff6336f4..a0826ed2f9fe 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -25,10 +25,34 @@ extern void s3c64xx_ac97_setup_gpio(int);
#define S5PC100_SPDIF_GPG3 1
extern void s5pc100_spdif_setup_gpio(int);
+struct samsung_i2s {
+/* If the Primary DAI has 5.1 Channels */
+#define QUIRK_PRI_6CHAN (1 << 0)
+/* If the I2S block has a Stereo Overlay Channel */
+#define QUIRK_SEC_DAI (1 << 1)
+/*
+ * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit)
+ * The Machine driver must provide suitably set clock to the I2S block.
+ */
+#define QUIRK_NO_MUXPSR (1 << 2)
+#define QUIRK_NEED_RSTCLR (1 << 3)
+ /* Quirks of the I2S controller */
+ u32 quirks;
+
+ /*
+ * Array of clock names that can be used to generate I2S signals.
+ * Also corresponds to clocks of I2SMOD[10]
+ */
+ const char **src_clk;
+};
+
/**
* 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 *);
+ union {
+ struct samsung_i2s i2s;
+ } type;
};
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2d82a6cb1444..3f1b889b2107 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -32,7 +32,7 @@ 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 s3c_device_pcm;
+extern struct platform_device samsung_asoc_dma;
extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
@@ -96,6 +96,16 @@ extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2;
extern struct platform_device s5pv210_device_spdif;
+extern struct platform_device s5pv310_device_ac97;
+extern struct platform_device s5pv310_device_pcm0;
+extern struct platform_device s5pv310_device_pcm1;
+extern struct platform_device s5pv310_device_pcm2;
+extern struct platform_device s5pv310_device_i2s0;
+extern struct platform_device s5pv310_device_i2s1;
+extern struct platform_device s5pv310_device_i2s2;
+extern struct platform_device s5pv310_device_spdif;
+extern struct platform_device s5pv310_device_pd[];
+
extern struct platform_device s5p6442_device_pcm0;
extern struct platform_device s5p6442_device_pcm1;
extern struct platform_device s5p6442_device_iis0;
@@ -106,6 +116,8 @@ extern struct platform_device s5p6440_device_pcm;
extern struct platform_device s5p6440_device_iis;
extern struct platform_device s5p6450_device_iis0;
+extern struct platform_device s5p6450_device_iis1;
+extern struct platform_device s5p6450_device_iis2;
extern struct platform_device s5p6450_device_pcm0;
extern struct platform_device s5pc100_device_ac97;
@@ -122,6 +134,9 @@ extern struct platform_device s5p_device_fimc0;
extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2;
+extern struct platform_device s5p_device_mipi_csis0;
+extern struct platform_device s5p_device_mipi_csis1;
+
/* s3c2440 specific devices */
#ifdef CONFIG_CPU_S3C2440
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 8fd65d8b5863..0d2c5703f1ee 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -210,6 +210,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
unsigned int off);
/**
+ * s3c_gpio_getpull_1down() - Get configuration for choice of 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-down resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1down.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1down(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.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 13a22b8861ef..dac35d0a711d 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -118,6 +118,8 @@ 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_2bit_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);
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
new file mode 100644
index 000000000000..5f0ad85783db
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/plat-samsung/include/plat/pd.h
+ *
+ * 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.
+*/
+
+#ifndef __ASM_PLAT_SAMSUNG_PD_H
+#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
+
+struct samsung_pd_info {
+ int (*enable)(struct device *dev);
+ int (*disable)(struct device *dev);
+ void __iomem *base;
+};
+
+enum s5pv310_pd_block {
+ PD_MFC,
+ PD_G3D,
+ PD_LCD0,
+ PD_LCD1,
+ PD_TV,
+ PD_CAM,
+ PD_GPS
+};
+
+#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 245836d91931..d9025e377675 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -15,6 +15,8 @@
* management
*/
+#include <linux/irq.h>
+
#ifdef CONFIG_PM
extern __init int s3c_pm_init(void);
@@ -100,7 +102,7 @@ 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 s3c_irqext_wake(struct irq_data *data, 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
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 4f8c102674ae..4e770355ccbc 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -28,9 +28,9 @@
* are consecutive when looking up the interrupt in the demux routines.
*/
-static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
+static inline void __iomem *s3c_irq_uart_base(struct irq_data *data)
{
- struct s3c_uart_irq *uirq = get_irq_chip_data(irq);
+ struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data);
return uirq->regs;
}
@@ -39,10 +39,10 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
return irq & 3;
}
-static void s3c_irq_uart_mask(unsigned int irq)
+static void s3c_irq_uart_mask(struct irq_data *data)
{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
+ void __iomem *regs = s3c_irq_uart_base(data);
+ unsigned int bit = s3c_irq_uart_bit(data->irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -50,10 +50,10 @@ static void s3c_irq_uart_mask(unsigned int irq)
__raw_writel(reg, regs + S3C64XX_UINTM);
}
-static void s3c_irq_uart_maskack(unsigned int irq)
+static void s3c_irq_uart_maskack(struct irq_data *data)
{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
+ void __iomem *regs = s3c_irq_uart_base(data);
+ unsigned int bit = s3c_irq_uart_bit(data->irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -62,10 +62,10 @@ static void s3c_irq_uart_maskack(unsigned int irq)
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
}
-static void s3c_irq_uart_unmask(unsigned int irq)
+static void s3c_irq_uart_unmask(struct irq_data *data)
{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
+ void __iomem *regs = s3c_irq_uart_base(data);
+ unsigned int bit = s3c_irq_uart_bit(data->irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -73,17 +73,17 @@ static void s3c_irq_uart_unmask(unsigned int irq)
__raw_writel(reg, regs + S3C64XX_UINTM);
}
-static void s3c_irq_uart_ack(unsigned int irq)
+static void s3c_irq_uart_ack(struct irq_data *data)
{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
+ void __iomem *regs = s3c_irq_uart_base(data);
+ unsigned int bit = s3c_irq_uart_bit(data->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;
+ struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
@@ -99,10 +99,10 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
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,
+ .irq_mask = s3c_irq_uart_mask,
+ .irq_unmask = s3c_irq_uart_unmask,
+ .irq_mask_ack = s3c_irq_uart_maskack,
+ .irq_ack = s3c_irq_uart_ack,
};
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
@@ -124,7 +124,7 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
set_irq_flags(irq, IRQF_VALID);
}
- desc->handler_data = uirq;
+ desc->irq_data.handler_data = uirq;
set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
}
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index 0270519fcabc..dd8692ae5c4c 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -24,43 +24,46 @@
static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
{
- generic_handle_irq((int)desc->handler_data);
+ generic_handle_irq((int)desc->irq_data.handler_data);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-static void s3c_irq_timer_mask(unsigned int irq)
+static void s3c_irq_timer_mask(struct irq_data *data)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+ u32 mask = (u32)data->chip_data;
reg &= 0x1f; /* mask out pending interrupts */
- reg &= ~(1 << (irq - IRQ_TIMER0));
+ reg &= ~mask;
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
-static void s3c_irq_timer_unmask(unsigned int irq)
+static void s3c_irq_timer_unmask(struct irq_data *data)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+ u32 mask = (u32)data->chip_data;
reg &= 0x1f; /* mask out pending interrupts */
- reg |= 1 << (irq - IRQ_TIMER0);
+ reg |= mask;
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
-static void s3c_irq_timer_ack(unsigned int irq)
+static void s3c_irq_timer_ack(struct irq_data *data)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+ u32 mask = (u32)data->chip_data;
reg &= 0x1f;
- reg |= (1 << 5) << (irq - IRQ_TIMER0);
+ reg |= mask << 5;
__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,
+ .irq_mask = s3c_irq_timer_mask,
+ .irq_unmask = s3c_irq_timer_unmask,
+ .irq_ack = s3c_irq_timer_ack,
};
/**
@@ -79,8 +82,9 @@ void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
set_irq_chip(timer_irq, &s3c_irq_timer);
+ set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
set_irq_handler(timer_irq, handle_level_irq);
set_irq_flags(timer_irq, IRQF_VALID);
- desc->handler_data = (void *)timer_irq;
+ desc->irq_data.handler_data = (void *)timer_irq;
}
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
new file mode 100644
index 000000000000..efe1d564473e
--- /dev/null
+++ b/arch/arm/plat-samsung/pd.c
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-samsung/pd.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung Power domain 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/platform_device.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+
+#include <plat/pd.h>
+
+static int samsung_pd_probe(struct platform_device *pdev)
+{
+ struct samsung_pd_info *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+
+ if (!pdata) {
+ dev_err(dev, "no device data specified\n");
+ return -ENOENT;
+ }
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ dev_info(dev, "power domain registered\n");
+ return 0;
+}
+
+static int __devexit samsung_pd_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ pm_runtime_disable(dev);
+ return 0;
+}
+
+static int samsung_pd_runtime_suspend(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->disable)
+ ret = pdata->disable(dev);
+
+ dev_dbg(dev, "suspended\n");
+ return ret;
+}
+
+static int samsung_pd_runtime_resume(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->enable)
+ ret = pdata->enable(dev);
+
+ dev_dbg(dev, "resumed\n");
+ return ret;
+}
+
+static const struct dev_pm_ops samsung_pd_pm_ops = {
+ .runtime_suspend = samsung_pd_runtime_suspend,
+ .runtime_resume = samsung_pd_runtime_resume,
+};
+
+static struct platform_driver samsung_pd_driver = {
+ .driver = {
+ .name = "samsung-pd",
+ .owner = THIS_MODULE,
+ .pm = &samsung_pd_pm_ops,
+ },
+ .probe = samsung_pd_probe,
+ .remove = __devexit_p(samsung_pd_remove),
+};
+
+static int __init samsung_pd_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&samsung_pd_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add PD driver\n", __func__);
+
+ return ret;
+}
+arch_initcall(samsung_pd_init);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 27cfca597699..eaa57dc969ae 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -136,15 +136,15 @@ static void s3c_pm_restore_uarts(void) { }
unsigned long s3c_irqwake_intmask = 0xffffffffL;
unsigned long s3c_irqwake_eintmask = 0xffffffffL;
-int s3c_irqext_wake(unsigned int irqno, unsigned int state)
+int s3c_irqext_wake(struct irq_data *data, unsigned int state)
{
- unsigned long bit = 1L << IRQ_EINT_BIT(irqno);
+ unsigned long bit = 1L << IRQ_EINT_BIT(data->irq);
if (!(s3c_irqwake_eintallow & bit))
return -ENOENT;
printk(KERN_INFO "wake %s for irq %d\n",
- state ? "enabled" : "disabled", irqno);
+ state ? "enabled" : "disabled", data->irq);
if (!state)
s3c_irqwake_eintmask |= bit;
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 298bafc0a52f..2572260f990f 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -15,7 +15,7 @@
#define __PLAT_CLOCK_H
#include <linux/list.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <linux/types.h>
/* clk structure flags */
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
new file mode 100644
index 000000000000..68b5394fc583
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2010 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_KEYBOARD_H
+#define __PLAT_KEYBOARD_H
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/types.h>
+
+#define DECLARE_KEYMAP(_name) \
+int _name[] = { \
+ KEY(0, 0, KEY_ESC), \
+ KEY(0, 1, KEY_1), \
+ KEY(0, 2, KEY_2), \
+ KEY(0, 3, KEY_3), \
+ KEY(0, 4, KEY_4), \
+ KEY(0, 5, KEY_5), \
+ KEY(0, 6, KEY_6), \
+ KEY(0, 7, KEY_7), \
+ KEY(0, 8, KEY_8), \
+ KEY(1, 0, KEY_9), \
+ KEY(1, 1, KEY_MINUS), \
+ KEY(1, 2, KEY_EQUAL), \
+ KEY(1, 3, KEY_BACKSPACE), \
+ KEY(1, 4, KEY_TAB), \
+ KEY(1, 5, KEY_Q), \
+ KEY(1, 6, KEY_W), \
+ KEY(1, 7, KEY_E), \
+ KEY(1, 8, KEY_R), \
+ KEY(2, 0, KEY_T), \
+ KEY(2, 1, KEY_Y), \
+ KEY(2, 2, KEY_U), \
+ KEY(2, 3, KEY_I), \
+ KEY(2, 4, KEY_O), \
+ KEY(2, 5, KEY_P), \
+ KEY(2, 6, KEY_LEFTBRACE), \
+ KEY(2, 7, KEY_RIGHTBRACE), \
+ KEY(2, 8, KEY_ENTER), \
+ KEY(3, 0, KEY_LEFTCTRL), \
+ KEY(3, 1, KEY_A), \
+ KEY(3, 2, KEY_S), \
+ KEY(3, 3, KEY_D), \
+ KEY(3, 4, KEY_F), \
+ KEY(3, 5, KEY_G), \
+ KEY(3, 6, KEY_H), \
+ KEY(3, 7, KEY_J), \
+ KEY(3, 8, KEY_K), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(5, 0, KEY_V), \
+ KEY(5, 1, KEY_B), \
+ KEY(5, 2, KEY_N), \
+ KEY(5, 3, KEY_M), \
+ KEY(5, 4, KEY_COMMA), \
+ KEY(5, 5, KEY_DOT), \
+ KEY(5, 6, KEY_SLASH), \
+ KEY(5, 7, KEY_RIGHTSHIFT), \
+ KEY(5, 8, KEY_KPASTERISK), \
+ KEY(6, 0, KEY_LEFTALT), \
+ KEY(6, 1, KEY_SPACE), \
+ KEY(6, 2, KEY_CAPSLOCK), \
+ KEY(6, 3, KEY_F1), \
+ KEY(6, 4, KEY_F2), \
+ KEY(6, 5, KEY_F3), \
+ KEY(6, 6, KEY_F4), \
+ KEY(6, 7, KEY_F5), \
+ KEY(6, 8, KEY_F6), \
+ KEY(7, 0, KEY_F7), \
+ KEY(7, 1, KEY_F8), \
+ KEY(7, 2, KEY_F9), \
+ KEY(7, 3, KEY_F10), \
+ KEY(7, 4, KEY_NUMLOCK), \
+ KEY(7, 5, KEY_SCROLLLOCK), \
+ KEY(7, 6, KEY_KP7), \
+ KEY(7, 7, KEY_KP8), \
+ KEY(7, 8, KEY_KP9), \
+ KEY(8, 0, KEY_KPMINUS), \
+ KEY(8, 1, KEY_KP4), \
+ KEY(8, 2, KEY_KP5), \
+ KEY(8, 3, KEY_KP6), \
+ KEY(8, 4, KEY_KPPLUS), \
+ KEY(8, 5, KEY_KP1), \
+ KEY(8, 6, KEY_KP2), \
+ KEY(8, 7, KEY_KP3), \
+ KEY(8, 8, KEY_KP0), \
+}
+
+/**
+ * struct kbd_platform_data - spear keyboard platform data
+ * keymap: pointer to keymap data (table and size)
+ * rep: enables key autorepeat
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement keyboards.
+ */
+struct kbd_platform_data {
+ const struct matrix_keymap_data *keymap;
+ bool rep;
+};
+
+/* This function is used to set platform data field of pdev->dev */
+static inline void
+kbd_set_plat_data(struct platform_device *pdev, struct kbd_platform_data *data)
+{
+ pdev->dev.platform_data = data;
+}
+
+#endif /* __PLAT_KEYBOARD_H */
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index ab211652e4ca..839c88df9994 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -81,8 +81,6 @@ static struct clocksource clksrc = {
.rating = 200, /* its a pretty decent clock */
.read = clocksource_read_cycles,
.mask = 0xFFFF, /* 16 bits */
- .mult = 0, /* to be computed */
- .shift = 0, /* to be computed */
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -105,10 +103,8 @@ static void spear_clocksource_init(void)
val |= CTRL_ENABLE ;
writew(val, gpt_base + CR(CLKSRC));
- clocksource_calc_mult_shift(&clksrc, tick_rate, SPEAR_MIN_RANGE);
-
/* register the clocksource */
- clocksource_register(&clksrc);
+ clocksource_register_hz(&clksrc, tick_rate);
}
static struct clock_event_device clkevt = {
diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c
index e593a2a801c6..2e712e17ce72 100644
--- a/arch/arm/plat-stmp3xxx/clock.c
+++ b/arch/arm/plat-stmp3xxx/clock.c
@@ -25,9 +25,9 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/clkdev.h>
#include <asm/mach-types.h>
-#include <asm/clkdev.h>
#include <mach/platform.h>
#include <mach/regs-clkctrl.h>
diff --git a/arch/arm/plat-stmp3xxx/timer.c b/arch/arm/plat-stmp3xxx/timer.c
index 063c7bc0e740..c395630a6edc 100644
--- a/arch/arm/plat-stmp3xxx/timer.c
+++ b/arch/arm/plat-stmp3xxx/timer.c
@@ -89,7 +89,6 @@ static struct clocksource cksrc_stmp3xxx = {
.rating = 250,
.read = stmp3xxx_clock_read,
.mask = CLOCKSOURCE_MASK(16),
- .shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -106,8 +105,6 @@ static struct irqaction stmp3xxx_timer_irq = {
*/
static void __init stmp3xxx_init_timer(void)
{
- cksrc_stmp3xxx.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
- cksrc_stmp3xxx.shift);
ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
ckevt_timrot.shift);
ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
@@ -140,7 +137,7 @@ static void __init stmp3xxx_init_timer(void)
setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
- clocksource_register(&cksrc_stmp3xxx);
+ clocksource_register_hz(&cksrc_stmp3xxx, CLOCK_TICK_RATE);
clockevents_register_device(&ckevt_timrot);
}
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 5cf88e8427b1..07a47e92b5c2 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -1,7 +1,4 @@
-obj-y := clock.o
-obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
-obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o
-obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o
+obj-y := clock.o sched-clock.o
ifeq ($(CONFIG_LEDS_CLASS),y)
obj-$(CONFIG_ARCH_REALVIEW) += leds.o
obj-$(CONFIG_ARCH_VERSATILE) += leds.o
diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h
new file mode 100644
index 000000000000..5c3e4fc9fa0c
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/sched_clock.h
@@ -0,0 +1,6 @@
+#ifndef ARM_PLAT_SCHED_CLOCK_H
+#define ARM_PLAT_SCHED_CLOCK_H
+
+void versatile_sched_clock_init(void __iomem *, unsigned long);
+
+#endif
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
index 9768cf7e83d7..3d6a4c292cab 100644
--- a/arch/arm/plat-versatile/sched-clock.c
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -18,36 +18,41 @@
* 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/cnt32_to_63.h>
#include <linux/io.h>
-#include <asm/div64.h>
+#include <linux/sched.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <asm/sched_clock.h>
+#include <plat/sched_clock.h>
-#ifdef VERSATILE_SYS_BASE
-#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
-#endif
-
-#ifdef REALVIEW_SYS_BASE
-#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
-#endif
+static DEFINE_CLOCK_DATA(cd);
+static void __iomem *ctr;
/*
- * This is the Realview and Versatile sched_clock implementation. This
- * has a resolution of 41.7ns, and a maximum value of about 35583 days.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 89 seconds between successive
- * calls to this function.
+ * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 41ns and a wrap period of about 178s.
*/
-unsigned long long sched_clock(void)
+#define SC_MULT 2796202667u
+#define SC_SHIFT 26
+
+unsigned long long notrace sched_clock(void)
{
- unsigned long long v = cnt32_to_63(readl(REFCOUNTER));
+ if (ctr) {
+ u32 cyc = readl(ctr);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
+ SC_MULT, SC_SHIFT);
+ } else
+ return 0;
+}
- /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
- v *= 125<<1;
- do_div(v, 3<<1);
+static void notrace versatile_update_sched_clock(void)
+{
+ u32 cyc = readl(ctr);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
- return v;
+void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
+{
+ ctr = reg;
+ init_fixed_sched_clock(&cd, versatile_update_sched_clock,
+ 32, rate, SC_MULT, SC_SHIFT);
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 55590a4d87c9..2fea897ebeb1 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: Thu Sep 9 22:43:01 2010
+# Last update: Sun Dec 12 23:24:27 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332
u380 MACH_U380 U380 2333
oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334
npcmx50 MACH_NPCMX50 NPCMX50 2335
-mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336
+mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336
mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337
riom MACH_RIOM RIOM 2338
comcas MACH_COMCAS COMCAS 2339
@@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366
csb732 MACH_CSB732 CSB732 2367
u8500 MACH_U8500 U8500 2368
huqiu MACH_HUQIU HUQIU 2369
-mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370
+mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370
pmt1g MACH_PMT1G PMT1G 2371
htcelf MACH_HTCELF HTCELF 2372
armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373
@@ -2971,7 +2971,7 @@ premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985
wasabi MACH_WASABI WASABI 2986
vivow MACH_VIVOW VIVOW 2987
mx50_rdp MACH_MX50_RDP MX50_RDP 2988
-universal MACH_UNIVERSAL UNIVERSAL 2989
+universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
real6410 MACH_REAL6410 REAL6410 2990
spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991
ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992
@@ -3044,3 +3044,178 @@ harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059
msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060
spear900 MACH_SPEAR900 SPEAR900 3061
pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062
+rdstor MACH_RDSTOR RDSTOR 3063
+usdloader MACH_USDLOADER USDLOADER 3064
+tsoploader MACH_TSOPLOADER TSOPLOADER 3065
+kronos MACH_KRONOS KRONOS 3066
+ffcore MACH_FFCORE FFCORE 3067
+mone MACH_MONE MONE 3068
+unit2s MACH_UNIT2S UNIT2S 3069
+acer_a5 MACH_ACER_A5 ACER_A5 3070
+etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071
+stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072
+p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073
+tulip MACH_TULIP TULIP 3074
+sunflower MACH_SUNFLOWER SUNFLOWER 3075
+rib MACH_RIB RIB 3076
+clod MACH_CLOD CLOD 3077
+rump MACH_RUMP RUMP 3078
+tenderloin MACH_TENDERLOIN TENDERLOIN 3079
+shortloin MACH_SHORTLOIN SHORTLOIN 3080
+crespo MACH_CRESPO CRESPO 3081
+antares MACH_ANTARES ANTARES 3082
+wb40n MACH_WB40N WB40N 3083
+herring MACH_HERRING HERRING 3084
+naxy400 MACH_NAXY400 NAXY400 3085
+naxy1200 MACH_NAXY1200 NAXY1200 3086
+vpr200 MACH_VPR200 VPR200 3087
+bug20 MACH_BUG20 BUG20 3088
+goflexnet MACH_GOFLEXNET GOFLEXNET 3089
+torbreck MACH_TORBRECK TORBRECK 3090
+saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091
+callisto MACH_CALLISTO CALLISTO 3092
+multhsu MACH_MULTHSU MULTHSU 3093
+saluda MACH_SALUDA SALUDA 3094
+pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095
+vc0718 MACH_VC0718 VC0718 3096
+mvblx MACH_MVBLX MVBLX 3097
+inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098
+inhand_fury MACH_INHAND_FURY INHAND_FURY 3099
+inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100
+hdnvp MACH_HDNVP HDNVP 3101
+softwinner MACH_SOFTWINNER SOFTWINNER 3102
+prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
+nas6210 MACH_NAS6210 NAS6210 3104
+unisdev MACH_UNISDEV UNISDEV 3105
+sbca11 MACH_SBCA11 SBCA11 3106
+saga MACH_SAGA SAGA 3107
+ns_k330 MACH_NS_K330 NS_K330 3108
+tanna MACH_TANNA TANNA 3109
+imate8502 MACH_IMATE8502 IMATE8502 3110
+aspen MACH_ASPEN ASPEN 3111
+daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112
+zmx25 MACH_ZMX25 ZMX25 3113
+maple1 MACH_MAPLE1 MAPLE1 3114
+qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115
+qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116
+abilene MACH_ABILENE ABILENE 3117
+eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118
+iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119
+coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120
+santiago MACH_SANTIAGO SANTIAGO 3121
+mx257sol MACH_MX257SOL MX257SOL 3122
+strasbourg MACH_STRASBOURG STRASBOURG 3123
+msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124
+smartqv5 MACH_SMARTQV5 SMARTQV5 3125
+smartqv3 MACH_SMARTQV3 SMARTQV3 3126
+smartqv7 MACH_SMARTQV7 SMARTQV7 3127
+paz00 MACH_PAZ00 PAZ00 3128
+acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+htcwillow MACH_HTCWILLOW HTCWILLOW 3130
+fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131
+hdgu MACH_HDGU HDGU 3132
+pyramid MACH_PYRAMID PYRAMID 3133
+epiphan MACH_EPIPHAN EPIPHAN 3134
+omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135
+gurnard MACH_GURNARD GURNARD 3136
+gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137
+bcm2708 MACH_BCM2708 BCM2708 3138
+mx51_ggc MACH_MX51_GGC MX51_GGC 3139
+sharespace MACH_SHARESPACE SHARESPACE 3140
+haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141
+simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142
+crux MACH_CRUX CRUX 3143
+mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144
+charon MACH_CHARON CHARON 3145
+picocom3 MACH_PICOCOM3 PICOCOM3 3146
+picocom4 MACH_PICOCOM4 PICOCOM4 3147
+serrano MACH_SERRANO SERRANO 3148
+doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149
+evsy MACH_EVSY EVSY 3150
+huashan MACH_HUASHAN HUASHAN 3151
+lausanne MACH_LAUSANNE LAUSANNE 3152
+emerald MACH_EMERALD EMERALD 3153
+tqma35 MACH_TQMA35 TQMA35 3154
+marvel MACH_MARVEL MARVEL 3155
+manuae MACH_MANUAE MANUAE 3156
+chacha MACH_CHACHA CHACHA 3157
+lemon MACH_LEMON LEMON 3158
+csc MACH_CSC CSC 3159
+gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160
+t20 MACH_T20 T20 3161
+hdmini MACH_HDMINI HDMINI 3162
+sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163
+express MACH_EXPRESS EXPRESS 3164
+express_kt MACH_EXPRESS_KT EXPRESS_KT 3165
+maximasp MACH_MAXIMASP MAXIMASP 3166
+nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167
+nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168
+sunfire MACH_SUNFIRE SUNFIRE 3169
+arowana MACH_AROWANA AROWANA 3170
+tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171
+tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172
+edison MACH_EDISON EDISON 3173
+svp8500v1 MACH_SVP8500V1 SVP8500V1 3174
+svp8500v2 MACH_SVP8500V2 SVP8500V2 3175
+svp5500 MACH_SVP5500 SVP5500 3176
+b5500 MACH_B5500 B5500 3177
+s5500 MACH_S5500 S5500 3178
+icon MACH_ICON ICON 3179
+elephant MACH_ELEPHANT ELEPHANT 3180
+msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181
+shooter MACH_SHOOTER SHOOTER 3182
+spade_lte MACH_SPADE_LTE SPADE_LTE 3183
+philhwani MACH_PHILHWANI PHILHWANI 3184
+gsncomm MACH_GSNCOMM GSNCOMM 3185
+strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186
+mmm MACH_MMM MMM 3187
+davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188
+ag5evm MACH_AG5EVM AG5EVM 3189
+sc575plc MACH_SC575PLC SC575PLC 3190
+sc575hmi MACH_SC575IPC SC575IPC 3191
+omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192
+g7 MACH_G7 G7 3193
+top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194
+top9000_su MACH_TOP9000_SU TOP9000_SU 3195
+utm300 MACH_UTM300 UTM300 3196
+tsunagi MACH_TSUNAGI TSUNAGI 3197
+ts75xx MACH_TS75XX TS75XX 3198
+msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199
+ts47xx MACH_TS47XX TS47XX 3200
+da850_k5 MACH_DA850_K5 DA850_K5 3201
+ax502 MACH_AX502 AX502 3202
+igep0032 MACH_IGEP0032 IGEP0032 3203
+antero MACH_ANTERO ANTERO 3204
+synergy MACH_SYNERGY SYNERGY 3205
+ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
+punica MACH_PUNICA PUNICA 3208
+sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209
+mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210
+mackerel MACH_MACKEREL MACKEREL 3211
+fa9x27 MACH_FA9X27 FA9X27 3213
+ns2816tb MACH_NS2816TB NS2816TB 3214
+ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215
+ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216
+kaen MACH_KAEN KAEN 3217
+nv1000 MACH_NV1000 NV1000 3218
+nuc950ts MACH_NUC950TS NUC950TS 3219
+nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+ast2200 MACH_AST2200 AST2200 3221
+lead MACH_LEAD LEAD 3222
+unino1 MACH_UNINO1 UNINO1 3223
+greeco MACH_GREECO GREECO 3224
+verdi MACH_VERDI VERDI 3225
+dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226
+quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227
+abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228
+svcid MACH_SVCID SVCID 3229
+msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+icon_g MACH_ICON_G ICON_G 3232
+mb3 MACH_MB3 MB3 3233
+gsia18s MACH_GSIA18S GSIA18S 3234
+pivicc MACH_PIVICC PIVICC 3235
+pcm048 MACH_PCM048 PCM048 3236
+dds MACH_DDS DDS 3237
+chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index d66cead97d28..9897dcfc16d6 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -206,6 +206,7 @@ ENTRY(vfp_save_state)
mov pc, lr
ENDPROC(vfp_save_state)
+ .align
last_VFP_context_address:
.word last_VFP_context
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 8063a322c790..0797cb528b46 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -10,9 +10,12 @@
*/
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/cpu.h>
#include <linux/kernel.h>
+#include <linux/notifier.h>
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/smp.h>
#include <linux/init.h>
#include <asm/cputype.h>
@@ -484,7 +487,24 @@ void vfp_flush_hwstate(struct thread_info *thread)
put_cpu();
}
-#include <linux/smp.h>
+/*
+ * VFP hardware can lose all context when a CPU goes offline.
+ * Safely clear our held state when a CPU has been killed, and
+ * re-enable access to VFP when the CPU comes back online.
+ *
+ * Both CPU_DYING and CPU_STARTING are called on the CPU which
+ * is being offlined/onlined.
+ */
+static int vfp_hotplug(struct notifier_block *b, unsigned long action,
+ void *hcpu)
+{
+ if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
+ unsigned int cpu = (long)hcpu;
+ last_VFP_context[cpu] = NULL;
+ } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+ vfp_enable(NULL);
+ return NOTIFY_OK;
+}
/*
* VFP support code initialisation.
@@ -514,6 +534,8 @@ static int __init vfp_init(void)
else if (vfpsid & FPSID_NODOUBLE) {
printk("no double precision support\n");
} else {
+ hotcpu_notifier(vfp_hotplug, 0);
+
smp_call_function(vfp_enable, NULL, 1);
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
diff --git a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
new file mode 100644
index 000000000000..4cf451024fd8
--- /dev/null
+++ b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
@@ -0,0 +1,113 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_FUTEX is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_SLAB=y
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_BF561=y
+CONFIG_SMP=y
+CONFIG_IRQ_TIMER0=10
+CONFIG_CLKIN_HZ=30000000
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=m
+CONFIG_C_CDPRIO=y
+CONFIG_BANK_3=0xAAC2
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRTTY_SIR=m
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+CONFIG_MTD_PHYSMAP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_BFIN_JTAG_COMM=m
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_SPI_BFIN=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_BFIN_WDT=y
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_JFFS2_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_SMB_FS=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/blackfin/include/asm/bfin_dma.h b/arch/blackfin/include/asm/bfin_dma.h
new file mode 100644
index 000000000000..d51120744148
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_dma.h
@@ -0,0 +1,91 @@
+/*
+ * bfin_dma.h - Blackfin DMA defines/structures/etc...
+ *
+ * Copyright 2004-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_DMA_H__
+#define __ASM_BFIN_DMA_H__
+
+#include <linux/types.h>
+
+/* DMA_CONFIG Masks */
+#define DMAEN 0x0001 /* DMA Channel Enable */
+#define WNR 0x0002 /* Channel Direction (W/R*) */
+#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */
+#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */
+#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */
+#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */
+#define RESTART 0x0020 /* DMA Buffer Clear */
+#define DI_SEL 0x0040 /* Data Interrupt Timing Select */
+#define DI_EN 0x0080 /* Data Interrupt Enable */
+#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
+#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
+#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
+#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
+#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
+#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
+#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
+#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
+#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
+#define NDSIZE 0x0f00 /* Next Descriptor Size */
+#define DMAFLOW 0x7000 /* Flow Control */
+#define DMAFLOW_STOP 0x0000 /* Stop Mode */
+#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
+#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
+#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
+
+/* DMA_IRQ_STATUS Masks */
+#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */
+#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */
+#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */
+#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */
+
+/*
+ * 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 dma registers layout
+ */
+struct bfin_dma_regs {
+ u32 next_desc_ptr;
+ u32 start_addr;
+ __BFP(config);
+ u32 __pad0;
+ __BFP(x_count);
+ __BFP(x_modify);
+ __BFP(y_count);
+ __BFP(y_modify);
+ u32 curr_desc_ptr;
+ u32 curr_addr;
+ __BFP(irq_status);
+ __BFP(peripheral_map);
+ __BFP(curr_x_count);
+ u32 __pad1;
+ __BFP(curr_y_count);
+ u32 __pad2;
+};
+
+/*
+ * bfin handshake mdma registers layout
+ */
+struct bfin_hmdma_regs {
+ __BFP(control);
+ __BFP(ecinit);
+ __BFP(bcinit);
+ __BFP(ecurgent);
+ __BFP(ecoverflow);
+ __BFP(ecount);
+ __BFP(bcount);
+};
+
+#undef __BFP
+
+#endif
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h
new file mode 100644
index 000000000000..e9510eab5e22
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_serial.h
@@ -0,0 +1,263 @@
+/*
+ * bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_ASM_SERIAL_H__
+#define __BFIN_ASM_SERIAL_H__
+
+#include <linux/serial_core.h>
+#include <mach/anomaly.h>
+#include <mach/bfin_serial.h>
+
+struct circ_buf;
+struct timer_list;
+struct work_struct;
+
+struct bfin_serial_port {
+ struct uart_port port;
+ unsigned int old_status;
+ int status_irq;
+#ifndef BFIN_UART_BF54X_STYLE
+ unsigned int lsr;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ int tx_done;
+ int tx_count;
+ struct circ_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+ struct work_struct tx_dma_workqueue;
+#elif ANOMALY_05000363
+ unsigned int anomaly_threshold;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ int scts;
+#endif
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
+ int cts_pin;
+ int rts_pin;
+#endif
+};
+
+/* UART_LCR Masks */
+#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
+#define STB 0x04 /* Stop Bits */
+#define PEN 0x08 /* Parity Enable */
+#define EPS 0x10 /* Even Parity Select */
+#define STP 0x20 /* Stick Parity */
+#define SB 0x40 /* Set Break */
+#define DLAB 0x80 /* Divisor Latch Access */
+
+/* UART_LSR Masks */
+#define DR 0x01 /* Data Ready */
+#define OE 0x02 /* Overrun Error */
+#define PE 0x04 /* Parity Error */
+#define FE 0x08 /* Framing Error */
+#define BI 0x10 /* Break Interrupt */
+#define THRE 0x20 /* THR Empty */
+#define TEMT 0x40 /* TSR and UART_THR Empty */
+#define TFI 0x80 /* Transmission Finished Indicator */
+
+/* UART_IER Masks */
+#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
+#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
+#define ELSI 0x04 /* Enable RX Status Interrupt */
+#define EDSSI 0x08 /* Enable Modem Status Interrupt */
+#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */
+#define ETFI 0x20 /* Enable Transmission Finished Interrupt */
+#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */
+
+/* UART_MCR Masks */
+#define XOFF 0x01 /* Transmitter Off */
+#define MRTS 0x02 /* Manual Request To Send */
+#define RFIT 0x04 /* Receive FIFO IRQ Threshold */
+#define RFRT 0x08 /* Receive FIFO RTS Threshold */
+#define LOOP_ENA 0x10 /* Loopback Mode Enable */
+#define FCPOL 0x20 /* Flow Control Pin Polarity */
+#define ARTS 0x40 /* Automatic Request To Send */
+#define ACTS 0x80 /* Automatic Clear To Send */
+
+/* UART_MSR Masks */
+#define SCTS 0x01 /* Sticky CTS */
+#define CTS 0x10 /* Clear To Send */
+#define RFCS 0x20 /* Receive FIFO Count Status */
+
+/* UART_GCTL Masks */
+#define UCEN 0x01 /* Enable UARTx Clocks */
+#define IREN 0x02 /* Enable IrDA Mode */
+#define TPOLC 0x04 /* IrDA TX Polarity Change */
+#define RPOLC 0x08 /* IrDA RX Polarity Change */
+#define FPE 0x10 /* Force Parity Error On Transmit */
+#define FFE 0x20 /* Force Framing Error On Transmit */
+
+#ifdef BFIN_UART_BF54X_STYLE
+# define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+# define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+# define OFFSET_GCTL 0x08 /* Global Control Register */
+# define OFFSET_LCR 0x0C /* Line Control Register */
+# define OFFSET_MCR 0x10 /* Modem Control Register */
+# define OFFSET_LSR 0x14 /* Line Status Register */
+# define OFFSET_MSR 0x18 /* Modem Status Register */
+# define OFFSET_SCR 0x1C /* SCR Scratch Register */
+# define OFFSET_IER_SET 0x20 /* Set Interrupt Enable Register */
+# define OFFSET_IER_CLEAR 0x24 /* Clear Interrupt Enable Register */
+# define OFFSET_THR 0x28 /* Transmit Holding register */
+# define OFFSET_RBR 0x2C /* Receive Buffer register */
+#else /* BF533 style */
+# define OFFSET_THR 0x00 /* Transmit Holding register */
+# define OFFSET_RBR 0x00 /* Receive Buffer register */
+# define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+# define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+# define OFFSET_IER 0x04 /* Interrupt Enable Register */
+# define OFFSET_IIR 0x08 /* Interrupt Identification Register */
+# define OFFSET_LCR 0x0C /* Line Control Register */
+# define OFFSET_MCR 0x10 /* Modem Control Register */
+# define OFFSET_LSR 0x14 /* Line Status Register */
+# define OFFSET_MSR 0x18 /* Modem Status Register */
+# define OFFSET_SCR 0x1C /* SCR Scratch Register */
+# define OFFSET_GCTL 0x24 /* Global Control Register */
+/* code should not need IIR, so force build error if they use it */
+# undef OFFSET_IIR
+#endif
+
+/*
+ * 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 bfin_uart_regs {
+#ifdef BFIN_UART_BF54X_STYLE
+ __BFP(dll);
+ __BFP(dlh);
+ __BFP(gctl);
+ __BFP(lcr);
+ __BFP(mcr);
+ __BFP(lsr);
+ __BFP(msr);
+ __BFP(scr);
+ __BFP(ier_set);
+ __BFP(ier_clear);
+ __BFP(thr);
+ __BFP(rbr);
+#else
+ union {
+ u16 dll;
+ u16 thr;
+ const u16 rbr;
+ };
+ const u16 __pad0;
+ union {
+ u16 dlh;
+ u16 ier;
+ };
+ const u16 __pad1;
+ const __BFP(iir);
+ __BFP(lcr);
+ __BFP(mcr);
+ __BFP(lsr);
+ __BFP(msr);
+ __BFP(scr);
+ const u32 __pad2;
+ __BFP(gctl);
+#endif
+};
+#undef __BFP
+
+#ifndef port_membase
+# define port_membase(p) (((struct bfin_serial_port *)(p))->port.membase)
+#endif
+
+#define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR)
+#define UART_GET_DLL(p) bfin_read16(port_membase(p) + OFFSET_DLL)
+#define UART_GET_DLH(p) bfin_read16(port_membase(p) + OFFSET_DLH)
+#define UART_GET_GCTL(p) bfin_read16(port_membase(p) + OFFSET_GCTL)
+#define UART_GET_LCR(p) bfin_read16(port_membase(p) + OFFSET_LCR)
+#define UART_GET_MCR(p) bfin_read16(port_membase(p) + OFFSET_MCR)
+#define UART_GET_MSR(p) bfin_read16(port_membase(p) + OFFSET_MSR)
+
+#define UART_PUT_CHAR(p, v) bfin_write16(port_membase(p) + OFFSET_THR, v)
+#define UART_PUT_DLL(p, v) bfin_write16(port_membase(p) + OFFSET_DLL, v)
+#define UART_PUT_DLH(p, v) bfin_write16(port_membase(p) + OFFSET_DLH, v)
+#define UART_PUT_GCTL(p, v) bfin_write16(port_membase(p) + OFFSET_GCTL, v)
+#define UART_PUT_LCR(p, v) bfin_write16(port_membase(p) + OFFSET_LCR, v)
+#define UART_PUT_MCR(p, v) bfin_write16(port_membase(p) + OFFSET_MCR, v)
+
+#ifdef BFIN_UART_BF54X_STYLE
+
+#define UART_CLEAR_IER(p, v) bfin_write16(port_membase(p) + OFFSET_IER_CLEAR, v)
+#define UART_GET_IER(p) bfin_read16(port_membase(p) + OFFSET_IER_SET)
+#define UART_SET_IER(p, v) bfin_write16(port_membase(p) + OFFSET_IER_SET, v)
+
+#define UART_CLEAR_DLAB(p) /* MMRs not muxed on BF54x */
+#define UART_SET_DLAB(p) /* MMRs not muxed on BF54x */
+
+#define UART_CLEAR_LSR(p) bfin_write16(port_membase(p) + OFFSET_LSR, -1)
+#define UART_GET_LSR(p) bfin_read16(port_membase(p) + OFFSET_LSR)
+#define UART_PUT_LSR(p, v) bfin_write16(port_membase(p) + OFFSET_LSR, v)
+
+/* This handles hard CTS/RTS */
+#define UART_CLEAR_SCTS(p) bfin_write16((port_membase(p) + OFFSET_MSR), SCTS)
+#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
+#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS | MRTS))
+#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
+#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
+#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)
+
+#else /* BF533 style */
+
+#define UART_CLEAR_IER(p, v) UART_PUT_IER(p, UART_GET_IER(p) & ~(v))
+#define UART_GET_IER(p) bfin_read16(port_membase(p) + OFFSET_IER)
+#define UART_PUT_IER(p, v) bfin_write16(port_membase(p) + OFFSET_IER, v)
+#define UART_SET_IER(p, v) UART_PUT_IER(p, UART_GET_IER(p) | (v))
+
+#define UART_CLEAR_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) & ~DLAB); SSYNC(); } while (0)
+#define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0)
+
+#ifndef put_lsr_cache
+# define put_lsr_cache(p, v) (((struct bfin_serial_port *)(p))->lsr = (v))
+#endif
+#ifndef get_lsr_cache
+# define get_lsr_cache(p) (((struct bfin_serial_port *)(p))->lsr)
+#endif
+
+/* The hardware clears the LSR bits upon read, so we need to cache
+ * some of the more fun bits in software so they don't get lost
+ * when checking the LSR in other code paths (TX).
+ */
+static inline void UART_CLEAR_LSR(void *p)
+{
+ put_lsr_cache(p, 0);
+ bfin_write16(port_membase(p) + OFFSET_LSR, -1);
+}
+static inline unsigned int UART_GET_LSR(void *p)
+{
+ unsigned int lsr = bfin_read16(port_membase(p) + OFFSET_LSR);
+ put_lsr_cache(p, get_lsr_cache(p) | (lsr & (BI|FE|PE|OE)));
+ return lsr | get_lsr_cache(p);
+}
+static inline void UART_PUT_LSR(void *p, uint16_t val)
+{
+ put_lsr_cache(p, get_lsr_cache(p) & ~val);
+}
+
+/* This handles soft CTS/RTS */
+#define UART_GET_CTS(x) gpio_get_value((x)->cts_pin)
+#define UART_DISABLE_RTS(x) gpio_set_value((x)->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value((x)->rts_pin, 0)
+#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
+#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
+
+#endif
+
+#ifndef BFIN_UART_TX_FIFO_SIZE
+# define BFIN_UART_TX_FIFO_SIZE 2
+#endif
+
+#endif /* __BFIN_ASM_SERIAL_H__ */
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
index eedf3ca65ba2..d9dbc1a53534 100644
--- a/arch/blackfin/include/asm/dma.h
+++ b/arch/blackfin/include/asm/dma.h
@@ -14,40 +14,7 @@
#include <asm/blackfin.h>
#include <asm/page.h>
#include <asm-generic/dma.h>
-
-/* DMA_CONFIG Masks */
-#define DMAEN 0x0001 /* DMA Channel Enable */
-#define WNR 0x0002 /* Channel Direction (W/R*) */
-#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */
-#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */
-#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */
-#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */
-#define RESTART 0x0020 /* DMA Buffer Clear */
-#define DI_SEL 0x0040 /* Data Interrupt Timing Select */
-#define DI_EN 0x0080 /* Data Interrupt Enable */
-#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
-#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
-#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
-#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
-#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
-#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
-#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
-#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
-#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
-#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
-#define NDSIZE 0x0f00 /* Next Descriptor Size */
-#define DMAFLOW 0x7000 /* Flow Control */
-#define DMAFLOW_STOP 0x0000 /* Stop Mode */
-#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
-#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
-#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
-#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
-
-/* DMA_IRQ_STATUS Masks */
-#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */
-#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */
-#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */
-#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */
+#include <asm/bfin_dma.h>
/*-------------------------
* config reg bits value
@@ -149,7 +116,7 @@ void blackfin_dma_resume(void);
* DMA API's
*******************************************************************************/
extern struct dma_channel dma_ch[MAX_DMA_CHANNELS];
-extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS];
+extern struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS];
extern int channel2irq(unsigned int channel);
static inline void set_dma_start_addr(unsigned int channel, unsigned long addr)
diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h
index 234fbac17ec1..dccae26805b0 100644
--- a/arch/blackfin/include/asm/io.h
+++ b/arch/blackfin/include/asm/io.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,148 +7,48 @@
#ifndef _BFIN_IO_H
#define _BFIN_IO_H
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-#endif
#include <linux/compiler.h>
-
-/*
- * These are for ISA/PCI shared memory _only_ and should never be used
- * on any other type of memory, including Zorro memory. They are meant to
- * access the bus in the bus byte order which is little-endian!.
- *
- * readX/writeX() are used to access memory mapped devices. On some
- * architectures the memory mapped IO stuff needs to be accessed
- * differently. On the bfin architecture, we just read/write the
- * memory location directly.
- */
-#ifndef __ASSEMBLY__
-
-static inline unsigned char readb(const volatile void __iomem *addr)
-{
- unsigned int val;
- int tmp;
-
- __asm__ __volatile__ (
- "cli %1;"
- "NOP; NOP; SSYNC;"
- "%0 = b [%2] (z);"
- "sti %1;"
- : "=d"(val), "=d"(tmp)
- : "a"(addr)
- );
-
- return (unsigned char) val;
-}
-
-static inline unsigned short readw(const volatile void __iomem *addr)
-{
- unsigned int val;
- int tmp;
-
- __asm__ __volatile__ (
- "cli %1;"
- "NOP; NOP; SSYNC;"
- "%0 = w [%2] (z);"
- "sti %1;"
- : "=d"(val), "=d"(tmp)
- : "a"(addr)
- );
-
- return (unsigned short) val;
-}
-
-static inline unsigned int readl(const volatile void __iomem *addr)
-{
- unsigned int val;
- int tmp;
-
- __asm__ __volatile__ (
- "cli %1;"
- "NOP; NOP; SSYNC;"
- "%0 = [%2];"
- "sti %1;"
- : "=d"(val), "=d"(tmp)
- : "a"(addr)
- );
-
- return val;
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#define DECLARE_BFIN_RAW_READX(size, type, asm, asm_sign) \
+static inline type __raw_read##size(const volatile void __iomem *addr) \
+{ \
+ unsigned int val; \
+ int tmp; \
+ __asm__ __volatile__ ( \
+ "cli %1;" \
+ "NOP; NOP; SSYNC;" \
+ "%0 = "#asm" [%2] "#asm_sign";" \
+ "sti %1;" \
+ : "=d"(val), "=d"(tmp) \
+ : "a"(addr) \
+ ); \
+ return (type) val; \
}
-
-#endif /* __ASSEMBLY__ */
-
-#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
-
-#define __raw_readb readb
-#define __raw_readw readw
-#define __raw_readl readl
-#define __raw_writeb writeb
-#define __raw_writew writew
-#define __raw_writel writel
-#define memset_io(a, b, c) memset((void *)(a), (b), (c))
-#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
-#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
-
-/* Convert "I/O port addresses" to actual addresses. i.e. ugly casts. */
-#define __io(port) ((void *)(unsigned long)(port))
-
-#define inb(port) readb(__io(port))
-#define inw(port) readw(__io(port))
-#define inl(port) readl(__io(port))
-#define outb(x, port) writeb(x, __io(port))
-#define outw(x, port) writew(x, __io(port))
-#define outl(x, port) writel(x, __io(port))
-
-#define inb_p(port) inb(__io(port))
-#define inw_p(port) inw(__io(port))
-#define inl_p(port) inl(__io(port))
-#define outb_p(x, port) outb(x, __io(port))
-#define outw_p(x, port) outw(x, __io(port))
-#define outl_p(x, port) outl(x, __io(port))
-
-#define ioread8_rep(a, d, c) readsb(a, d, c)
-#define ioread16_rep(a, d, c) readsw(a, d, c)
-#define ioread32_rep(a, d, c) readsl(a, d, c)
-#define iowrite8_rep(a, s, c) writesb(a, s, c)
-#define iowrite16_rep(a, s, c) writesw(a, s, c)
-#define iowrite32_rep(a, s, c) writesl(a, s, c)
-
-#define ioread8(x) readb(x)
-#define ioread16(x) readw(x)
-#define ioread32(x) readl(x)
-#define iowrite8(val, x) writeb(val, x)
-#define iowrite16(val, x) writew(val, x)
-#define iowrite32(val, x) writel(val, x)
-
-/**
- * I/O write barrier
- *
- * Ensure ordering of I/O space writes. This will make sure that writes
- * following the barrier will arrive after all previous writes.
- */
-#define mmiowb() do { SSYNC(); wmb(); } while (0)
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/* Values for nocacheflag and cmode */
-#define IOMAP_NOCACHE_SER 1
-
-#ifndef __ASSEMBLY__
+DECLARE_BFIN_RAW_READX(b, u8, b, (z))
+#define __raw_readb __raw_readb
+DECLARE_BFIN_RAW_READX(w, u16, w, (z))
+#define __raw_readw __raw_readw
+DECLARE_BFIN_RAW_READX(l, u32, , )
+#define __raw_readl __raw_readl
extern void outsb(unsigned long port, const void *addr, unsigned long count);
extern void outsw(unsigned long port, const void *addr, unsigned long count);
extern void outsw_8(unsigned long port, const void *addr, unsigned long count);
extern void outsl(unsigned long port, const void *addr, unsigned long count);
+#define outsb outsb
+#define outsw outsw
+#define outsl outsl
extern void insb(unsigned long port, void *addr, unsigned long count);
extern void insw(unsigned long port, void *addr, unsigned long count);
extern void insw_8(unsigned long port, void *addr, unsigned long count);
extern void insl(unsigned long port, void *addr, unsigned long count);
extern void insl_16(unsigned long port, void *addr, unsigned long count);
+#define insb insb
+#define insw insw
+#define insl insl
extern void dma_outsb(unsigned long port, const void *addr, unsigned short count);
extern void dma_outsw(unsigned long port, const void *addr, unsigned short count);
@@ -158,108 +58,14 @@ extern void dma_insb(unsigned long port, void *addr, unsigned short count);
extern void dma_insw(unsigned long port, void *addr, unsigned short count);
extern void dma_insl(unsigned long port, void *addr, unsigned short count);
-static inline void readsl(const void __iomem *addr, void *buf, int len)
-{
- insl((unsigned long)addr, buf, len);
-}
-
-static inline void readsw(const void __iomem *addr, void *buf, int len)
-{
- insw((unsigned long)addr, buf, len);
-}
-
-static inline void readsb(const void __iomem *addr, void *buf, int len)
-{
- insb((unsigned long)addr, buf, len);
-}
-
-static inline void writesl(const void __iomem *addr, const void *buf, int len)
-{
- outsl((unsigned long)addr, buf, len);
-}
-
-static inline void writesw(const void __iomem *addr, const void *buf, int len)
-{
- outsw((unsigned long)addr, buf, len);
-}
-
-static inline void writesb(const void __iomem *addr, const void *buf, int len)
-{
- outsb((unsigned long)addr, buf, len);
-}
-
-/*
- * Map some physical address range into the kernel address space.
- */
-static inline void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
- int cacheflag)
-{
- return (void __iomem *)physaddr;
-}
-
-/*
- * Unmap a ioremap()ed region again
- */
-static inline void iounmap(void *addr)
-{
-}
-
-/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-static inline void __iounmap(void *addr, unsigned long size)
-{
-}
-
-/*
- * Set new cache mode for some kernel address space.
- * The caller must push data for that range itself, if such data may already
- * be in the cache.
+/**
+ * I/O write barrier
+ *
+ * Ensure ordering of I/O space writes. This will make sure that writes
+ * following the barrier will arrive after all previous writes.
*/
-static inline void kernel_set_cachemode(void *addr, unsigned long size,
- int cmode)
-{
-}
-
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-static inline void __iomem *ioremap_nocache(unsigned long physaddr,
- unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
+#define mmiowb() do { SSYNC(); wmb(); } while (0)
-extern void blkfin_inv_cache_all(void);
+#include <asm-generic/io.h>
#endif
-
-#define ioport_map(port, nr) ((void __iomem*)(port))
-#define ioport_unmap(addr)
-
-/* Pages to physical address... */
-#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
-
-#define phys_to_virt(vaddr) ((void *) (vaddr))
-#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
-
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p) __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p) p
-
-#endif /* __KERNEL__ */
-
-#endif /* _BFIN_IO_H */
diff --git a/arch/blackfin/include/mach-common/ports-a.h b/arch/blackfin/include/mach-common/ports-a.h
new file mode 100644
index 000000000000..9f78a761c40a
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-a.h
@@ -0,0 +1,25 @@
+/*
+ * Port A Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_A__
+#define __BFIN_PERIPHERAL_PORT_A__
+
+#define PA0 (1 << 0)
+#define PA1 (1 << 1)
+#define PA2 (1 << 2)
+#define PA3 (1 << 3)
+#define PA4 (1 << 4)
+#define PA5 (1 << 5)
+#define PA6 (1 << 6)
+#define PA7 (1 << 7)
+#define PA8 (1 << 8)
+#define PA9 (1 << 9)
+#define PA10 (1 << 10)
+#define PA11 (1 << 11)
+#define PA12 (1 << 12)
+#define PA13 (1 << 13)
+#define PA14 (1 << 14)
+#define PA15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-b.h b/arch/blackfin/include/mach-common/ports-b.h
new file mode 100644
index 000000000000..b81702f09ec6
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-b.h
@@ -0,0 +1,25 @@
+/*
+ * Port B Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_B__
+#define __BFIN_PERIPHERAL_PORT_B__
+
+#define PB0 (1 << 0)
+#define PB1 (1 << 1)
+#define PB2 (1 << 2)
+#define PB3 (1 << 3)
+#define PB4 (1 << 4)
+#define PB5 (1 << 5)
+#define PB6 (1 << 6)
+#define PB7 (1 << 7)
+#define PB8 (1 << 8)
+#define PB9 (1 << 9)
+#define PB10 (1 << 10)
+#define PB11 (1 << 11)
+#define PB12 (1 << 12)
+#define PB13 (1 << 13)
+#define PB14 (1 << 14)
+#define PB15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-c.h b/arch/blackfin/include/mach-common/ports-c.h
new file mode 100644
index 000000000000..3cc665e0ba08
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-c.h
@@ -0,0 +1,25 @@
+/*
+ * Port C Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_C__
+#define __BFIN_PERIPHERAL_PORT_C__
+
+#define PC0 (1 << 0)
+#define PC1 (1 << 1)
+#define PC2 (1 << 2)
+#define PC3 (1 << 3)
+#define PC4 (1 << 4)
+#define PC5 (1 << 5)
+#define PC6 (1 << 6)
+#define PC7 (1 << 7)
+#define PC8 (1 << 8)
+#define PC9 (1 << 9)
+#define PC10 (1 << 10)
+#define PC11 (1 << 11)
+#define PC12 (1 << 12)
+#define PC13 (1 << 13)
+#define PC14 (1 << 14)
+#define PC15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-d.h b/arch/blackfin/include/mach-common/ports-d.h
new file mode 100644
index 000000000000..868c6a01f1b2
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-d.h
@@ -0,0 +1,25 @@
+/*
+ * Port D Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_D__
+#define __BFIN_PERIPHERAL_PORT_D__
+
+#define PD0 (1 << 0)
+#define PD1 (1 << 1)
+#define PD2 (1 << 2)
+#define PD3 (1 << 3)
+#define PD4 (1 << 4)
+#define PD5 (1 << 5)
+#define PD6 (1 << 6)
+#define PD7 (1 << 7)
+#define PD8 (1 << 8)
+#define PD9 (1 << 9)
+#define PD10 (1 << 10)
+#define PD11 (1 << 11)
+#define PD12 (1 << 12)
+#define PD13 (1 << 13)
+#define PD14 (1 << 14)
+#define PD15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-e.h b/arch/blackfin/include/mach-common/ports-e.h
new file mode 100644
index 000000000000..c88b0d0dd443
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-e.h
@@ -0,0 +1,25 @@
+/*
+ * Port E Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_E__
+#define __BFIN_PERIPHERAL_PORT_E__
+
+#define PE0 (1 << 0)
+#define PE1 (1 << 1)
+#define PE2 (1 << 2)
+#define PE3 (1 << 3)
+#define PE4 (1 << 4)
+#define PE5 (1 << 5)
+#define PE6 (1 << 6)
+#define PE7 (1 << 7)
+#define PE8 (1 << 8)
+#define PE9 (1 << 9)
+#define PE10 (1 << 10)
+#define PE11 (1 << 11)
+#define PE12 (1 << 12)
+#define PE13 (1 << 13)
+#define PE14 (1 << 14)
+#define PE15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-f.h b/arch/blackfin/include/mach-common/ports-f.h
new file mode 100644
index 000000000000..d6af20633278
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-f.h
@@ -0,0 +1,25 @@
+/*
+ * Port F Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_F__
+#define __BFIN_PERIPHERAL_PORT_F__
+
+#define PF0 (1 << 0)
+#define PF1 (1 << 1)
+#define PF2 (1 << 2)
+#define PF3 (1 << 3)
+#define PF4 (1 << 4)
+#define PF5 (1 << 5)
+#define PF6 (1 << 6)
+#define PF7 (1 << 7)
+#define PF8 (1 << 8)
+#define PF9 (1 << 9)
+#define PF10 (1 << 10)
+#define PF11 (1 << 11)
+#define PF12 (1 << 12)
+#define PF13 (1 << 13)
+#define PF14 (1 << 14)
+#define PF15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-g.h b/arch/blackfin/include/mach-common/ports-g.h
new file mode 100644
index 000000000000..09355d333c0e
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-g.h
@@ -0,0 +1,25 @@
+/*
+ * Port G Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_G__
+#define __BFIN_PERIPHERAL_PORT_G__
+
+#define PG0 (1 << 0)
+#define PG1 (1 << 1)
+#define PG2 (1 << 2)
+#define PG3 (1 << 3)
+#define PG4 (1 << 4)
+#define PG5 (1 << 5)
+#define PG6 (1 << 6)
+#define PG7 (1 << 7)
+#define PG8 (1 << 8)
+#define PG9 (1 << 9)
+#define PG10 (1 << 10)
+#define PG11 (1 << 11)
+#define PG12 (1 << 12)
+#define PG13 (1 << 13)
+#define PG14 (1 << 14)
+#define PG15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-h.h b/arch/blackfin/include/mach-common/ports-h.h
new file mode 100644
index 000000000000..fa3910c6fbd4
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-h.h
@@ -0,0 +1,25 @@
+/*
+ * Port H Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_H__
+#define __BFIN_PERIPHERAL_PORT_H__
+
+#define PH0 (1 << 0)
+#define PH1 (1 << 1)
+#define PH2 (1 << 2)
+#define PH3 (1 << 3)
+#define PH4 (1 << 4)
+#define PH5 (1 << 5)
+#define PH6 (1 << 6)
+#define PH7 (1 << 7)
+#define PH8 (1 << 8)
+#define PH9 (1 << 9)
+#define PH10 (1 << 10)
+#define PH11 (1 << 11)
+#define PH12 (1 << 12)
+#define PH13 (1 << 13)
+#define PH14 (1 << 14)
+#define PH15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-i.h b/arch/blackfin/include/mach-common/ports-i.h
new file mode 100644
index 000000000000..f176f08af624
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-i.h
@@ -0,0 +1,25 @@
+/*
+ * Port I Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_I__
+#define __BFIN_PERIPHERAL_PORT_I__
+
+#define PI0 (1 << 0)
+#define PI1 (1 << 1)
+#define PI2 (1 << 2)
+#define PI3 (1 << 3)
+#define PI4 (1 << 4)
+#define PI5 (1 << 5)
+#define PI6 (1 << 6)
+#define PI7 (1 << 7)
+#define PI8 (1 << 8)
+#define PI9 (1 << 9)
+#define PI10 (1 << 10)
+#define PI11 (1 << 11)
+#define PI12 (1 << 12)
+#define PI13 (1 << 13)
+#define PI14 (1 << 14)
+#define PI15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/include/mach-common/ports-j.h b/arch/blackfin/include/mach-common/ports-j.h
new file mode 100644
index 000000000000..924123ecec5a
--- /dev/null
+++ b/arch/blackfin/include/mach-common/ports-j.h
@@ -0,0 +1,25 @@
+/*
+ * Port J Masks
+ */
+
+#ifndef __BFIN_PERIPHERAL_PORT_J__
+#define __BFIN_PERIPHERAL_PORT_J__
+
+#define PJ0 (1 << 0)
+#define PJ1 (1 << 1)
+#define PJ2 (1 << 2)
+#define PJ3 (1 << 3)
+#define PJ4 (1 << 4)
+#define PJ5 (1 << 5)
+#define PJ6 (1 << 6)
+#define PJ7 (1 << 7)
+#define PJ8 (1 << 8)
+#define PJ9 (1 << 9)
+#define PJ10 (1 << 10)
+#define PJ11 (1 << 11)
+#define PJ12 (1 << 12)
+#define PJ13 (1 << 13)
+#define PJ14 (1 << 14)
+#define PJ15 (1 << 15)
+
+#endif
diff --git a/arch/blackfin/mach-bf518/dma.c b/arch/blackfin/mach-bf518/dma.c
index 78b43605a0b5..bcd1fbc8c543 100644
--- a/arch/blackfin/mach-bf518/dma.c
+++ b/arch/blackfin/mach-bf518/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..00c603fe8218
--- /dev/null
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 2
+
+#endif
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
index 970d310021e7..f6d924ac0c44 100644
--- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v)
-#define UART_PUT_DLL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
-#define UART_PUT_IER(uart, v) bfin_write16(((uart)->port.membase + OFFSET_IER), v)
-#define UART_SET_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
-#define UART_PUT_LCR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
-#define UART_PUT_GCTL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
# define CONFIG_SERIAL_BFIN_CTSRTS
@@ -54,50 +27,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-/*
- * The pin configuration is different from schematic
- */
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -146,3 +75,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h
index 9053462be4b1..a8828863226e 100644
--- a/arch/blackfin/mach-bf518/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h
@@ -1,61 +1,43 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
#define _MACH_BLACKFIN_H_
#include "bf518.h"
-#include "defBF512.h"
#include "anomaly.h"
-#if defined(CONFIG_BF518)
-#include "defBF518.h"
+#include <asm/def_LPBlackfin.h>
+#ifdef CONFIG_BF512
+# include "defBF512.h"
#endif
-
-#if defined(CONFIG_BF516)
-#include "defBF516.h"
-#endif
-
-#if defined(CONFIG_BF514)
-#include "defBF514.h"
+#ifdef CONFIG_BF514
+# include "defBF514.h"
#endif
-
-#if defined(CONFIG_BF512)
-#include "defBF512.h"
+#ifdef CONFIG_BF516
+# include "defBF516.h"
#endif
-
-#if !defined(__ASSEMBLY__)
-#include "cdefBF512.h"
-
-#if defined(CONFIG_BF518)
-#include "cdefBF518.h"
+#ifdef CONFIG_BF518
+# include "defBF518.h"
#endif
-#if defined(CONFIG_BF516)
-#include "cdefBF516.h"
+#ifndef __ASSEMBLY__
+# include <asm/cdef_LPBlackfin.h>
+# ifdef CONFIG_BF512
+# include "cdefBF512.h"
+# endif
+# ifdef CONFIG_BF514
+# include "cdefBF514.h"
+# endif
+# ifdef CONFIG_BF516
+# include "cdefBF516.h"
+# endif
+# ifdef CONFIG_BF518
+# include "cdefBF518.h"
+# endif
#endif
-#if defined(CONFIG_BF514)
-#include "cdefBF514.h"
-#endif
-#endif
-
-#define BFIN_UART_NR_PORTS 2
-
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
-
#endif
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
index 493020d0a65a..b657d37a3402 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,15 +7,1037 @@
#ifndef _CDEF_BF512_H
#define _CDEF_BF512_H
-/* include all Core registers and bit definitions */
-#include "defBF512.h"
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
+#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
+#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV, val)
+#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
+#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT, val)
+#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
+#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT, val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val)
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF512 */
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define bfin_read_SWRST() bfin_read16(SWRST)
+#define bfin_write_SWRST(val) bfin_write16(SWRST, val)
+#define bfin_read_SYSCR() bfin_read16(SYSCR)
+#define bfin_write_SYSCR(val) bfin_write16(SYSCR, val)
-/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "cdefBF51x_base.h"
+#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
+#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
+#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
+#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
+#define bfin_read_SIC_IMASK(x) bfin_read32(SIC_IMASK0 + (x << 6))
+#define bfin_write_SIC_IMASK(x, val) bfin_write32((SIC_IMASK0 + (x << 6)), val)
+
+#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
+#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0, val)
+#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
+#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1, val)
+#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
+#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2, val)
+#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
+#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3, val)
+
+#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
+#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0, val)
+#define bfin_read_SIC_ISR(x) bfin_read32(SIC_ISR0 + (x << 6))
+#define bfin_write_SIC_ISR(x, val) bfin_write32((SIC_ISR0 + (x << 6)), val)
+
+#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
+#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0, val)
+#define bfin_read_SIC_IWR(x) bfin_read32(SIC_IWR0 + (x << 6))
+#define bfin_write_SIC_IWR(x, val) bfin_write32((SIC_IWR0 + (x << 6)), val)
+
+/* SIC Additions to ADSP-BF51x (0xFFC0014C - 0xFFC00162) */
+
+#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
+#define bfin_write_SIC_IMASK1(val) bfin_write32(SIC_IMASK1, val)
+#define bfin_read_SIC_IAR4() bfin_read32(SIC_IAR4)
+#define bfin_write_SIC_IAR4(val) bfin_write32(SIC_IAR4, val)
+#define bfin_read_SIC_IAR5() bfin_read32(SIC_IAR5)
+#define bfin_write_SIC_IAR5(val) bfin_write32(SIC_IAR5, val)
+#define bfin_read_SIC_IAR6() bfin_read32(SIC_IAR6)
+#define bfin_write_SIC_IAR6(val) bfin_write32(SIC_IAR6, val)
+#define bfin_read_SIC_IAR7() bfin_read32(SIC_IAR7)
+#define bfin_write_SIC_IAR7(val) bfin_write32(SIC_IAR7, val)
+#define bfin_read_SIC_ISR1() bfin_read32(SIC_ISR1)
+#define bfin_write_SIC_ISR1(val) bfin_write32(SIC_ISR1, val)
+#define bfin_read_SIC_IWR1() bfin_read32(SIC_IWR1)
+#define bfin_write_SIC_IWR1(val) bfin_write32(SIC_IWR1, val)
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
+#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val)
+#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
+#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val)
+#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
+#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val)
+
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
+#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT, val)
+#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
+#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL, val)
+#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
+#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT, val)
+#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
+#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT, val)
+#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
+#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM, val)
+#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
+#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST, val)
+#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
+#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN, val)
+
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define bfin_read_UART0_THR() bfin_read16(UART0_THR)
+#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR, val)
+#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR)
+#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR, val)
+#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL)
+#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL, val)
+#define bfin_read_UART0_IER() bfin_read16(UART0_IER)
+#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER, val)
+#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH)
+#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH, val)
+#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR)
+#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR, val)
+#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR)
+#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR, val)
+#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR)
+#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR, val)
+#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR)
+#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR, val)
+#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR)
+#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR, val)
+#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR)
+#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR, val)
+#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL)
+#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL, val)
+
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
+#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val)
+#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
+#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val)
+#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
+#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val)
+#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
+#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val)
+
+#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
+#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val)
+#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
+#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val)
+#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
+#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val)
+#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
+#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val)
+
+#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
+#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val)
+#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
+#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val)
+#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
+#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val)
+#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
+#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val)
+
+#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
+#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val)
+#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
+#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val)
+#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
+#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val)
+#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
+#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val)
+
+#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
+#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val)
+#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
+#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val)
+#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
+#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val)
+#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
+#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val)
+
+#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
+#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val)
+#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
+#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val)
+#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
+#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val)
+#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
+#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val)
+
+#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
+#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val)
+#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
+#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val)
+#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
+#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val)
+#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
+#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val)
+
+#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
+#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val)
+#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
+#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val)
+#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
+#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val)
+#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
+#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val)
+
+#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
+#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE, val)
+#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
+#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE, val)
+#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS)
+#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS, val)
+
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define bfin_read_PORTFIO() bfin_read16(PORTFIO)
+#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO, val)
+#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR)
+#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR, val)
+#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET)
+#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET, val)
+#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE)
+#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE, val)
+#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA)
+#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA, val)
+#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR)
+#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR, val)
+#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET)
+#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET, val)
+#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE)
+#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB)
+#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB, val)
+#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR)
+#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR, val)
+#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET)
+#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET, val)
+#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE)
+#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR)
+#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR, val)
+#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR)
+#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR, val)
+#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE)
+#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE, val)
+#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH)
+#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH, val)
+#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN)
+#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN, val)
+
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
+#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val)
+#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
+#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val)
+#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
+#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val)
+#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
+#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val)
+#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
+#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
+#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
+#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
+#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val)
+#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
+#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val)
+#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
+#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val)
+#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
+#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val)
+#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
+#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val)
+#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
+#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val)
+#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
+#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val)
+#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
+#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val)
+#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
+#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val)
+#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
+#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val)
+#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
+#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val)
+#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
+#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val)
+#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
+#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val)
+#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
+#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val)
+#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
+#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val)
+
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
+#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1, val)
+#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
+#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2, val)
+#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
+#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV, val)
+#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
+#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV, val)
+#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
+#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
+#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
+#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
+#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2, val)
+#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
+#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV, val)
+#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
+#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV, val)
+#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
+#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT, val)
+#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
+#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL, val)
+#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
+#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1, val)
+#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
+#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2, val)
+#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
+#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0, val)
+#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
+#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1, val)
+#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
+#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2, val)
+#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
+#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3, val)
+#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
+#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0, val)
+#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
+#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1, val)
+#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
+#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2, val)
+#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
+#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3, val)
+
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
+#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL, val)
+#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
+#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0, val)
+#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
+#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1, val)
+#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
+#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL, val)
+#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
+#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL, val)
+#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
+#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC, val)
+#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
+#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT, val)
+
+
+/* DMA Traffic Control Registers */
+#define bfin_read_DMAC_TC_PER() bfin_read16(DMAC_TC_PER)
+#define bfin_write_DMAC_TC_PER(val) bfin_write16(DMAC_TC_PER, val)
+#define bfin_read_DMAC_TC_CNT() bfin_read16(DMAC_TC_CNT)
+#define bfin_write_DMAC_TC_CNT(val) bfin_write16(DMAC_TC_CNT, val)
+
+/* DMA Controller */
+#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
+#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG, val)
+#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
+#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val)
+#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
+#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val)
+#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
+#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT, val)
+#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
+#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT, val)
+#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
+#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY, val)
+#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
+#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY, val)
+#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
+#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val)
+#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
+#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val)
+#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
+#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT, val)
+#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
+#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT, val)
+#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
+#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS, val)
+#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
+#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
+#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG, val)
+#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
+#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val)
+#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
+#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val)
+#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
+#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT, val)
+#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
+#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT, val)
+#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
+#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY, val)
+#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
+#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY, val)
+#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
+#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val)
+#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
+#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val)
+#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
+#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT, val)
+#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
+#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT, val)
+#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
+#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS, val)
+#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
+#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
+#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG, val)
+#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
+#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val)
+#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
+#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val)
+#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
+#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT, val)
+#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
+#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT, val)
+#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
+#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY, val)
+#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
+#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY, val)
+#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
+#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val)
+#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
+#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val)
+#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
+#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT, val)
+#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
+#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT, val)
+#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
+#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS, val)
+#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
+#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
+#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG, val)
+#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
+#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val)
+#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
+#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val)
+#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
+#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT, val)
+#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
+#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT, val)
+#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
+#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY, val)
+#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
+#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY, val)
+#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
+#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val)
+#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
+#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val)
+#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
+#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT, val)
+#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
+#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT, val)
+#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
+#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS, val)
+#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
+#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
+#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG, val)
+#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
+#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val)
+#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
+#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val)
+#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
+#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT, val)
+#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
+#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT, val)
+#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
+#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY, val)
+#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
+#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY, val)
+#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
+#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val)
+#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
+#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val)
+#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
+#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT, val)
+#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
+#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT, val)
+#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
+#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS, val)
+#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
+#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
+#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG, val)
+#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
+#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val)
+#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
+#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val)
+#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
+#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT, val)
+#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
+#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT, val)
+#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
+#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY, val)
+#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
+#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY, val)
+#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
+#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val)
+#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
+#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val)
+#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
+#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT, val)
+#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
+#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT, val)
+#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
+#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS, val)
+#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
+#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
+#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG, val)
+#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
+#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val)
+#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
+#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val)
+#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
+#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT, val)
+#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
+#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT, val)
+#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
+#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY, val)
+#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
+#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY, val)
+#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
+#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val)
+#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
+#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val)
+#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
+#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT, val)
+#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
+#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT, val)
+#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
+#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS, val)
+#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
+#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
+#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG, val)
+#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
+#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val)
+#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
+#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val)
+#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
+#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT, val)
+#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
+#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT, val)
+#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
+#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY, val)
+#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
+#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY, val)
+#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
+#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val)
+#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
+#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val)
+#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
+#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT, val)
+#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
+#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT, val)
+#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
+#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS, val)
+#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
+#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG)
+#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG, val)
+#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR)
+#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val)
+#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR)
+#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val)
+#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT)
+#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT, val)
+#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT)
+#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT, val)
+#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY)
+#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY, val)
+#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY)
+#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY, val)
+#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR)
+#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val)
+#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR)
+#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val)
+#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT)
+#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT, val)
+#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT)
+#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT, val)
+#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS)
+#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS, val)
+#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP)
+#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG)
+#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG, val)
+#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR)
+#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val)
+#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR)
+#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val)
+#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT)
+#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT, val)
+#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT)
+#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT, val)
+#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY)
+#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY, val)
+#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY)
+#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY, val)
+#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR)
+#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val)
+#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR)
+#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val)
+#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT)
+#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT, val)
+#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT)
+#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT, val)
+#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS)
+#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS, val)
+#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP)
+#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG)
+#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG, val)
+#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR)
+#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val)
+#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR)
+#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val)
+#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT)
+#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT, val)
+#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT)
+#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT, val)
+#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY)
+#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY, val)
+#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY)
+#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY, val)
+#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR)
+#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val)
+#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR)
+#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val)
+#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT)
+#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT, val)
+#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT)
+#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT, val)
+#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS)
+#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS, val)
+#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP)
+#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG)
+#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG, val)
+#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR)
+#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val)
+#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR)
+#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val)
+#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT)
+#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT, val)
+#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT)
+#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT, val)
+#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY)
+#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY, val)
+#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY)
+#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY, val)
+#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR)
+#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val)
+#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR)
+#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val)
+#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT)
+#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT, val)
+#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT)
+#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT, val)
+#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS)
+#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS, val)
+#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP)
+#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG, val)
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR, val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT, val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT, val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY, val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY, val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR, val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS, val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG, val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR, val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT, val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT, val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY, val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY, val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR, val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS, val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG, val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR, val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT, val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT, val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY, val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY, val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR, val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS, val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG, val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR, val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT, val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT, val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY, val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY, val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR, val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS, val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP, val)
+
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
+#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val)
+#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
+#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF)
+#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
+#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val)
+#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
+#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT, val)
+#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
+#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME, val)
+
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define bfin_read_PORTGIO() bfin_read16(PORTGIO)
+#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO, val)
+#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR)
+#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR, val)
+#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET)
+#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET, val)
+#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE)
+#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE, val)
+#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA)
+#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA, val)
+#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR)
+#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR, val)
+#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET)
+#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET, val)
+#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE)
+#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB)
+#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB, val)
+#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR)
+#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR, val)
+#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET)
+#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET, val)
+#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE)
+#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR)
+#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR, val)
+#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR)
+#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR, val)
+#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE)
+#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE, val)
+#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH)
+#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH, val)
+#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN)
+#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN, val)
+
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define bfin_read_PORTHIO() bfin_read16(PORTHIO)
+#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO, val)
+#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR)
+#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR, val)
+#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET)
+#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET, val)
+#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE)
+#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE, val)
+#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA)
+#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA, val)
+#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR)
+#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR, val)
+#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET)
+#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET, val)
+#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE)
+#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB)
+#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB, val)
+#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR)
+#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR, val)
+#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET)
+#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET, val)
+#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE)
+#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR)
+#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR, val)
+#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR)
+#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR, val)
+#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE)
+#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE, val)
+#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH)
+#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH, val)
+#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN)
+#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN, val)
+
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define bfin_read_UART1_THR() bfin_read16(UART1_THR)
+#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR, val)
+#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR)
+#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR, val)
+#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL)
+#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL, val)
+#define bfin_read_UART1_IER() bfin_read16(UART1_IER)
+#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER, val)
+#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH)
+#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH, val)
+#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR)
+#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR, val)
+#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR)
+#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR, val)
+#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR)
+#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR, val)
+#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR)
+#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR, val)
+#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR)
+#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR, val)
+#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR)
+#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR, val)
+#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL)
+#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL, val)
+
+/* Omit CAN register sets from the cdefBF534.h (CAN is not in the ADSP-BF51x processor) */
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER)
+#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER, val)
+#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER)
+#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER, val)
+#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER)
+#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER, val)
+#define bfin_read_PORT_MUX() bfin_read16(PORT_MUX)
+#define bfin_write_PORT_MUX(val) bfin_write16(PORT_MUX, val)
+
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL)
+#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val)
+#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT)
+#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val)
+#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT)
+#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val)
+#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT)
+#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val)
+#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW)
+#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val)
+#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT)
+#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val)
+#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT)
+#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val)
+
+#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL)
+#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val)
+#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT)
+#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val)
+#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT)
+#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val)
+#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT)
+#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val)
+#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW)
+#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val)
+#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT)
+#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val)
+#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
+#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val)
+
+/* ==== end from cdefBF534.h ==== */
+
+/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
+
+#define bfin_read_PORTF_MUX() bfin_read16(PORTF_MUX)
+#define bfin_write_PORTF_MUX(val) bfin_write16(PORTF_MUX, val)
+#define bfin_read_PORTG_MUX() bfin_read16(PORTG_MUX)
+#define bfin_write_PORTG_MUX(val) bfin_write16(PORTG_MUX, val)
+#define bfin_read_PORTH_MUX() bfin_read16(PORTH_MUX)
+#define bfin_write_PORTH_MUX(val) bfin_write16(PORTH_MUX, val)
+
+#define bfin_read_PORTF_DRIVE() bfin_read16(PORTF_DRIVE)
+#define bfin_write_PORTF_DRIVE(val) bfin_write16(PORTF_DRIVE, val)
+#define bfin_read_PORTG_DRIVE() bfin_read16(PORTG_DRIVE)
+#define bfin_write_PORTG_DRIVE(val) bfin_write16(PORTG_DRIVE, val)
+#define bfin_read_PORTH_DRIVE() bfin_read16(PORTH_DRIVE)
+#define bfin_write_PORTH_DRIVE(val) bfin_write16(PORTH_DRIVE, val)
+#define bfin_read_PORTF_SLEW() bfin_read16(PORTF_SLEW)
+#define bfin_write_PORTF_SLEW(val) bfin_write16(PORTF_SLEW, val)
+#define bfin_read_PORTG_SLEW() bfin_read16(PORTG_SLEW)
+#define bfin_write_PORTG_SLEW(val) bfin_write16(PORTG_SLEW, val)
+#define bfin_read_PORTH_SLEW() bfin_read16(PORTH_SLEW)
+#define bfin_write_PORTH_SLEW(val) bfin_write16(PORTH_SLEW, val)
+#define bfin_read_PORTF_HYSTERISIS() bfin_read16(PORTF_HYSTERISIS)
+#define bfin_write_PORTF_HYSTERISIS(val) bfin_write16(PORTF_HYSTERISIS, val)
+#define bfin_read_PORTG_HYSTERISIS() bfin_read16(PORTG_HYSTERISIS)
+#define bfin_write_PORTG_HYSTERISIS(val) bfin_write16(PORTG_HYSTERISIS, val)
+#define bfin_read_PORTH_HYSTERISIS() bfin_read16(PORTH_HYSTERISIS)
+#define bfin_write_PORTH_HYSTERISIS(val) bfin_write16(PORTH_HYSTERISIS, val)
+#define bfin_read_MISCPORT_DRIVE() bfin_read16(MISCPORT_DRIVE)
+#define bfin_write_MISCPORT_DRIVE(val) bfin_write16(MISCPORT_DRIVE, val)
+#define bfin_read_MISCPORT_SLEW() bfin_read16(MISCPORT_SLEW)
+#define bfin_write_MISCPORT_SLEW(val) bfin_write16(MISCPORT_SLEW, val)
+#define bfin_read_MISCPORT_HYSTERISIS() bfin_read16(MISCPORT_HYSTERISIS)
+#define bfin_write_MISCPORT_HYSTERISIS(val) bfin_write16(MISCPORT_HYSTERISIS, val)
+
+/* HOST Port Registers */
+
+#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL)
+#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val)
+#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS)
+#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val)
+#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT)
+#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val)
+
+/* Counter Registers */
+
+#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG)
+#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val)
+#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK)
+#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val)
+#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS)
+#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val)
+#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND)
+#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val)
+#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE)
+#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val)
+#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER)
+#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val)
+#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX)
+#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val)
+#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN)
+#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val)
+
+/* Security Registers */
+
+#define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT)
+#define bfin_write_SECURE_SYSSWT(val) bfin_write32(SECURE_SYSSWT, val)
+#define bfin_read_SECURE_CONTROL() bfin_read16(SECURE_CONTROL)
+#define bfin_write_SECURE_CONTROL(val) bfin_write16(SECURE_CONTROL, val)
+#define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS)
+#define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val)
#endif /* _CDEF_BF512_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
index 108fa4bde277..dc988668203e 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,9 +7,6 @@
#ifndef _CDEF_BF514_H
#define _CDEF_BF514_H
-/* include all Core registers and bit definitions */
-#include "defBF514.h"
-
/* BF514 is BF512 + RSI */
#include "cdefBF512.h"
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
index 2751592ef1c1..142e45cbc253 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,9 +7,6 @@
#ifndef _CDEF_BF516_H
#define _CDEF_BF516_H
-/* include all Core registers and bit definitions */
-#include "defBF516.h"
-
/* BF516 is BF514 + EMAC */
#include "cdefBF514.h"
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
index 7fb7f0eab990..e638197bf8b1 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,9 +7,6 @@
#ifndef _CDEF_BF518_H
#define _CDEF_BF518_H
-/* include all Core registers and bit definitions */
-#include "defBF518.h"
-
/* BF518 is BF516 + IEEE-1588 */
#include "cdefBF516.h"
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
deleted file mode 100644
index e16969f24ffd..000000000000
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*
- * Copyright 2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#ifndef _CDEF_BF52X_H
-#define _CDEF_BF52X_H
-
-#include <asm/blackfin.h>
-
-#include "defBF51x_base.h"
-
-/* Include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* ==== begin from cdefBF534.h ==== */
-
-/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
-#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
-#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
-#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV, val)
-#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
-#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
-#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT, val)
-#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
-#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT, val)
-#define bfin_read_CHIPID() bfin_read32(CHIPID)
-#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val)
-
-
-/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
-#define bfin_read_SWRST() bfin_read16(SWRST)
-#define bfin_write_SWRST(val) bfin_write16(SWRST, val)
-#define bfin_read_SYSCR() bfin_read16(SYSCR)
-#define bfin_write_SYSCR(val) bfin_write16(SYSCR, val)
-
-#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
-#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
-#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
-#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
-#define bfin_read_SIC_IMASK(x) bfin_read32(SIC_IMASK0 + (x << 6))
-#define bfin_write_SIC_IMASK(x, val) bfin_write32((SIC_IMASK0 + (x << 6)), val)
-
-#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
-#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0, val)
-#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
-#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1, val)
-#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
-#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2, val)
-#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
-#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3, val)
-
-#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
-#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0, val)
-#define bfin_read_SIC_ISR(x) bfin_read32(SIC_ISR0 + (x << 6))
-#define bfin_write_SIC_ISR(x, val) bfin_write32((SIC_ISR0 + (x << 6)), val)
-
-#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
-#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0, val)
-#define bfin_read_SIC_IWR(x) bfin_read32(SIC_IWR0 + (x << 6))
-#define bfin_write_SIC_IWR(x, val) bfin_write32((SIC_IWR0 + (x << 6)), val)
-
-/* SIC Additions to ADSP-BF51x (0xFFC0014C - 0xFFC00162) */
-
-#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
-#define bfin_write_SIC_IMASK1(val) bfin_write32(SIC_IMASK1, val)
-#define bfin_read_SIC_IAR4() bfin_read32(SIC_IAR4)
-#define bfin_write_SIC_IAR4(val) bfin_write32(SIC_IAR4, val)
-#define bfin_read_SIC_IAR5() bfin_read32(SIC_IAR5)
-#define bfin_write_SIC_IAR5(val) bfin_write32(SIC_IAR5, val)
-#define bfin_read_SIC_IAR6() bfin_read32(SIC_IAR6)
-#define bfin_write_SIC_IAR6(val) bfin_write32(SIC_IAR6, val)
-#define bfin_read_SIC_IAR7() bfin_read32(SIC_IAR7)
-#define bfin_write_SIC_IAR7(val) bfin_write32(SIC_IAR7, val)
-#define bfin_read_SIC_ISR1() bfin_read32(SIC_ISR1)
-#define bfin_write_SIC_ISR1(val) bfin_write32(SIC_ISR1, val)
-#define bfin_read_SIC_IWR1() bfin_read32(SIC_IWR1)
-#define bfin_write_SIC_IWR1(val) bfin_write32(SIC_IWR1, val)
-
-/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
-#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
-#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val)
-#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
-#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val)
-#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
-#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val)
-
-
-/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
-#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
-#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT, val)
-#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
-#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL, val)
-#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
-#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT, val)
-#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
-#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT, val)
-#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
-#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM, val)
-#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
-#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST, val)
-#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
-#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN, val)
-
-
-/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
-#define bfin_read_UART0_THR() bfin_read16(UART0_THR)
-#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR, val)
-#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR)
-#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR, val)
-#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL)
-#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL, val)
-#define bfin_read_UART0_IER() bfin_read16(UART0_IER)
-#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER, val)
-#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH)
-#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH, val)
-#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR)
-#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR, val)
-#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR)
-#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR, val)
-#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR)
-#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR, val)
-#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR)
-#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR, val)
-#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR)
-#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR, val)
-#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR)
-#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR, val)
-#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL)
-#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL, val)
-
-
-/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
-#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
-#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val)
-#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
-#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val)
-#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
-#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val)
-#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
-#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val)
-
-#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
-#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val)
-#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
-#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val)
-#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
-#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val)
-#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
-#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val)
-
-#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
-#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val)
-#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
-#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val)
-#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
-#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val)
-#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
-#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val)
-
-#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
-#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val)
-#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
-#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val)
-#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
-#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val)
-#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
-#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val)
-
-#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
-#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val)
-#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
-#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val)
-#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
-#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val)
-#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
-#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val)
-
-#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
-#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val)
-#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
-#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val)
-#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
-#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val)
-#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
-#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val)
-
-#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
-#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val)
-#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
-#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val)
-#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
-#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val)
-#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
-#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val)
-
-#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
-#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val)
-#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
-#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val)
-#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
-#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val)
-#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
-#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val)
-
-#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
-#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE, val)
-#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
-#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE, val)
-#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS)
-#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS, val)
-
-
-/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
-#define bfin_read_PORTFIO() bfin_read16(PORTFIO)
-#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO, val)
-#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR)
-#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR, val)
-#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET)
-#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET, val)
-#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE)
-#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE, val)
-#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA)
-#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA, val)
-#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR)
-#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR, val)
-#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET)
-#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET, val)
-#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE)
-#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB)
-#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB, val)
-#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR)
-#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR, val)
-#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET)
-#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET, val)
-#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE)
-#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR)
-#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR, val)
-#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR)
-#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR, val)
-#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE)
-#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE, val)
-#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH)
-#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH, val)
-#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN)
-#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN, val)
-
-
-/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
-#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
-#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val)
-#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
-#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val)
-#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
-#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val)
-#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
-#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val)
-#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
-#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
-#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
-#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
-#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
-#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
-#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val)
-#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
-#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val)
-#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
-#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val)
-#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
-#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val)
-#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
-#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val)
-#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
-#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val)
-#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
-#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val)
-#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
-#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val)
-#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
-#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val)
-#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
-#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val)
-#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
-#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val)
-#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
-#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val)
-#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
-#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val)
-#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
-#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val)
-#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
-#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val)
-
-
-/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
-#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
-#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1, val)
-#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
-#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2, val)
-#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
-#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV, val)
-#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
-#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV, val)
-#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
-#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
-#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
-#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
-#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
-#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
-#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
-#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
-#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
-#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
-#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2, val)
-#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
-#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV, val)
-#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
-#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV, val)
-#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
-#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT, val)
-#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
-#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL, val)
-#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
-#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1, val)
-#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
-#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2, val)
-#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
-#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0, val)
-#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
-#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1, val)
-#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
-#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2, val)
-#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
-#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3, val)
-#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
-#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0, val)
-#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
-#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1, val)
-#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
-#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2, val)
-#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
-#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3, val)
-
-
-/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
-#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
-#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL, val)
-#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
-#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0, val)
-#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
-#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1, val)
-#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
-#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL, val)
-#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
-#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL, val)
-#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
-#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC, val)
-#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
-#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT, val)
-
-
-/* DMA Traffic Control Registers */
-#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER)
-#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER, val)
-#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT)
-#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT, val)
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
-#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER, val)
-#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
-#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT, val)
-
-/* DMA Controller */
-#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
-#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG, val)
-#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
-#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val)
-#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
-#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val)
-#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
-#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT, val)
-#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
-#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT, val)
-#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
-#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY, val)
-#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
-#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY, val)
-#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
-#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val)
-#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
-#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val)
-#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
-#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT, val)
-#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
-#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT, val)
-#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
-#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS, val)
-#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
-#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
-#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG, val)
-#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
-#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val)
-#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
-#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val)
-#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
-#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT, val)
-#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
-#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT, val)
-#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
-#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY, val)
-#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
-#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY, val)
-#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
-#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val)
-#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
-#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val)
-#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
-#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT, val)
-#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
-#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT, val)
-#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
-#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS, val)
-#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
-#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
-#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG, val)
-#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
-#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val)
-#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
-#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val)
-#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
-#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT, val)
-#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
-#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT, val)
-#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
-#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY, val)
-#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
-#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY, val)
-#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
-#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val)
-#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
-#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val)
-#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
-#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT, val)
-#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
-#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT, val)
-#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
-#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS, val)
-#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
-#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
-#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG, val)
-#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
-#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val)
-#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
-#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val)
-#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
-#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT, val)
-#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
-#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT, val)
-#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
-#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY, val)
-#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
-#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY, val)
-#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
-#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val)
-#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
-#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val)
-#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
-#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT, val)
-#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
-#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT, val)
-#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
-#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS, val)
-#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
-#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
-#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG, val)
-#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
-#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val)
-#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
-#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val)
-#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
-#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT, val)
-#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
-#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT, val)
-#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
-#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY, val)
-#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
-#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY, val)
-#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
-#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val)
-#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
-#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val)
-#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
-#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT, val)
-#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
-#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT, val)
-#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
-#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS, val)
-#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
-#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
-#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG, val)
-#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
-#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val)
-#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
-#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val)
-#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
-#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT, val)
-#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
-#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT, val)
-#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
-#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY, val)
-#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
-#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY, val)
-#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
-#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val)
-#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
-#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val)
-#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
-#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT, val)
-#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
-#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT, val)
-#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
-#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS, val)
-#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
-#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
-#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG, val)
-#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
-#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val)
-#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
-#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val)
-#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
-#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT, val)
-#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
-#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT, val)
-#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
-#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY, val)
-#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
-#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY, val)
-#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
-#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val)
-#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
-#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val)
-#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
-#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT, val)
-#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
-#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT, val)
-#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
-#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS, val)
-#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
-#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
-#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG, val)
-#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
-#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val)
-#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
-#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val)
-#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
-#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT, val)
-#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
-#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT, val)
-#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
-#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY, val)
-#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
-#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY, val)
-#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
-#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val)
-#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
-#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val)
-#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
-#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT, val)
-#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
-#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT, val)
-#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
-#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS, val)
-#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
-#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG)
-#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG, val)
-#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR)
-#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val)
-#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR)
-#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val)
-#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT)
-#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT, val)
-#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT)
-#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT, val)
-#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY)
-#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY, val)
-#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY)
-#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY, val)
-#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR)
-#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val)
-#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR)
-#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val)
-#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT)
-#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT, val)
-#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT)
-#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT, val)
-#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS)
-#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS, val)
-#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP)
-#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG)
-#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG, val)
-#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR)
-#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val)
-#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR)
-#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val)
-#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT)
-#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT, val)
-#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT)
-#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT, val)
-#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY)
-#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY, val)
-#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY)
-#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY, val)
-#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR)
-#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val)
-#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR)
-#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val)
-#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT)
-#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT, val)
-#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT)
-#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT, val)
-#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS)
-#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS, val)
-#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP)
-#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG)
-#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG, val)
-#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR)
-#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val)
-#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR)
-#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val)
-#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT)
-#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT, val)
-#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT)
-#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT, val)
-#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY)
-#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY, val)
-#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY)
-#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY, val)
-#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR)
-#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val)
-#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR)
-#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val)
-#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT)
-#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT, val)
-#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT)
-#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT, val)
-#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS)
-#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS, val)
-#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP)
-#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG)
-#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG, val)
-#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR)
-#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val)
-#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR)
-#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val)
-#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT)
-#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT, val)
-#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT)
-#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT, val)
-#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY)
-#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY, val)
-#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY)
-#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY, val)
-#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR)
-#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val)
-#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR)
-#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val)
-#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT)
-#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT, val)
-#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT)
-#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT, val)
-#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS)
-#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS, val)
-#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP)
-#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
-#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG, val)
-#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
-#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR, val)
-#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
-#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT, val)
-#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
-#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT, val)
-#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
-#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY, val)
-#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
-#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY, val)
-#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
-#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR, val)
-#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
-#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT, val)
-#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
-#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS, val)
-#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
-#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG, val)
-#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
-#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR, val)
-#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
-#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT, val)
-#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
-#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT, val)
-#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
-#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY, val)
-#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
-#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY, val)
-#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
-#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR, val)
-#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
-#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT, val)
-#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
-#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS, val)
-#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
-#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG, val)
-#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
-#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR, val)
-#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
-#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT, val)
-#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
-#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT, val)
-#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
-#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY, val)
-#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
-#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY, val)
-#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
-#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR, val)
-#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
-#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT, val)
-#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
-#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS, val)
-#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
-#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG, val)
-#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
-#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR, val)
-#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
-#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT, val)
-#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
-#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT, val)
-#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
-#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY, val)
-#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
-#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY, val)
-#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
-#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR, val)
-#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
-#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT, val)
-#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
-#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS, val)
-#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP, val)
-
-
-/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
-#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
-#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val)
-#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
-#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val)
-#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF)
-#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
-#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val)
-#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
-#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT, val)
-#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
-#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME, val)
-
-
-/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
-
-/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
-#define bfin_read_PORTGIO() bfin_read16(PORTGIO)
-#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO, val)
-#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR)
-#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR, val)
-#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET)
-#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET, val)
-#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE)
-#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE, val)
-#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA)
-#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA, val)
-#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR)
-#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR, val)
-#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET)
-#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET, val)
-#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE)
-#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB)
-#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB, val)
-#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR)
-#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR, val)
-#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET)
-#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET, val)
-#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE)
-#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR)
-#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR, val)
-#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR)
-#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR, val)
-#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE)
-#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE, val)
-#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH)
-#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH, val)
-#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN)
-#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN, val)
-
-
-/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
-#define bfin_read_PORTHIO() bfin_read16(PORTHIO)
-#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO, val)
-#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR)
-#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR, val)
-#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET)
-#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET, val)
-#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE)
-#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE, val)
-#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA)
-#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA, val)
-#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR)
-#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR, val)
-#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET)
-#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET, val)
-#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE)
-#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB)
-#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB, val)
-#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR)
-#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR, val)
-#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET)
-#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET, val)
-#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE)
-#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR)
-#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR, val)
-#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR)
-#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR, val)
-#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE)
-#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE, val)
-#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH)
-#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH, val)
-#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN)
-#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN, val)
-
-
-/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
-#define bfin_read_UART1_THR() bfin_read16(UART1_THR)
-#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR, val)
-#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR)
-#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR, val)
-#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL)
-#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL, val)
-#define bfin_read_UART1_IER() bfin_read16(UART1_IER)
-#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER, val)
-#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH)
-#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH, val)
-#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR)
-#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR, val)
-#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR)
-#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR, val)
-#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR)
-#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR, val)
-#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR)
-#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR, val)
-#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR)
-#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR, val)
-#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR)
-#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR, val)
-#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL)
-#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL, val)
-
-/* Omit CAN register sets from the cdefBF534.h (CAN is not in the ADSP-BF51x processor) */
-
-/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
-#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER)
-#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER, val)
-#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER)
-#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER, val)
-#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER)
-#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER, val)
-#define bfin_read_PORT_MUX() bfin_read16(PORT_MUX)
-#define bfin_write_PORT_MUX(val) bfin_write16(PORT_MUX, val)
-
-
-/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
-#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL)
-#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val)
-#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT)
-#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val)
-#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT)
-#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val)
-#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT)
-#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val)
-#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW)
-#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val)
-#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT)
-#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val)
-#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT)
-#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val)
-
-#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL)
-#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val)
-#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT)
-#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val)
-#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT)
-#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val)
-#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT)
-#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val)
-#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW)
-#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val)
-#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT)
-#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val)
-#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
-#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val)
-
-/* ==== end from cdefBF534.h ==== */
-
-/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
-
-#define bfin_read_PORTF_MUX() bfin_read16(PORTF_MUX)
-#define bfin_write_PORTF_MUX(val) bfin_write16(PORTF_MUX, val)
-#define bfin_read_PORTG_MUX() bfin_read16(PORTG_MUX)
-#define bfin_write_PORTG_MUX(val) bfin_write16(PORTG_MUX, val)
-#define bfin_read_PORTH_MUX() bfin_read16(PORTH_MUX)
-#define bfin_write_PORTH_MUX(val) bfin_write16(PORTH_MUX, val)
-
-#define bfin_read_PORTF_DRIVE() bfin_read16(PORTF_DRIVE)
-#define bfin_write_PORTF_DRIVE(val) bfin_write16(PORTF_DRIVE, val)
-#define bfin_read_PORTG_DRIVE() bfin_read16(PORTG_DRIVE)
-#define bfin_write_PORTG_DRIVE(val) bfin_write16(PORTG_DRIVE, val)
-#define bfin_read_PORTH_DRIVE() bfin_read16(PORTH_DRIVE)
-#define bfin_write_PORTH_DRIVE(val) bfin_write16(PORTH_DRIVE, val)
-#define bfin_read_PORTF_SLEW() bfin_read16(PORTF_SLEW)
-#define bfin_write_PORTF_SLEW(val) bfin_write16(PORTF_SLEW, val)
-#define bfin_read_PORTG_SLEW() bfin_read16(PORTG_SLEW)
-#define bfin_write_PORTG_SLEW(val) bfin_write16(PORTG_SLEW, val)
-#define bfin_read_PORTH_SLEW() bfin_read16(PORTH_SLEW)
-#define bfin_write_PORTH_SLEW(val) bfin_write16(PORTH_SLEW, val)
-#define bfin_read_PORTF_HYSTERISIS() bfin_read16(PORTF_HYSTERISIS)
-#define bfin_write_PORTF_HYSTERISIS(val) bfin_write16(PORTF_HYSTERISIS, val)
-#define bfin_read_PORTG_HYSTERISIS() bfin_read16(PORTG_HYSTERISIS)
-#define bfin_write_PORTG_HYSTERISIS(val) bfin_write16(PORTG_HYSTERISIS, val)
-#define bfin_read_PORTH_HYSTERISIS() bfin_read16(PORTH_HYSTERISIS)
-#define bfin_write_PORTH_HYSTERISIS(val) bfin_write16(PORTH_HYSTERISIS, val)
-#define bfin_read_MISCPORT_DRIVE() bfin_read16(MISCPORT_DRIVE)
-#define bfin_write_MISCPORT_DRIVE(val) bfin_write16(MISCPORT_DRIVE, val)
-#define bfin_read_MISCPORT_SLEW() bfin_read16(MISCPORT_SLEW)
-#define bfin_write_MISCPORT_SLEW(val) bfin_write16(MISCPORT_SLEW, val)
-#define bfin_read_MISCPORT_HYSTERISIS() bfin_read16(MISCPORT_HYSTERISIS)
-#define bfin_write_MISCPORT_HYSTERISIS(val) bfin_write16(MISCPORT_HYSTERISIS, val)
-
-/* HOST Port Registers */
-
-#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL)
-#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val)
-#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS)
-#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val)
-#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT)
-#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val)
-
-/* Counter Registers */
-
-#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG)
-#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val)
-#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK)
-#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val)
-#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS)
-#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val)
-#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND)
-#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val)
-#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE)
-#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val)
-#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER)
-#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val)
-#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX)
-#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val)
-#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN)
-#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val)
-
-/* Security Registers */
-
-#define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT)
-#define bfin_write_SECURE_SYSSWT(val) bfin_write32(SECURE_SYSSWT, val)
-#define bfin_read_SECURE_CONTROL() bfin_read16(SECURE_CONTROL)
-#define bfin_write_SECURE_CONTROL(val) bfin_write16(SECURE_CONTROL, val)
-#define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS)
-#define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val)
-
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
-#endif /* _CDEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF512.h b/arch/blackfin/mach-bf518/include/mach/defBF512.h
index 9b505bb0cb2d..27285823fb25 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF512.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,12 +7,1388 @@
#ifndef _DEF_BF512_H
#define _DEF_BF512_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
+/* ************************************************************** */
+/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF51x */
+/* ************************************************************** */
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF512 */
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define PLL_CTL 0xFFC00000 /* PLL Control Register */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */
+#define PLL_STAT 0xFFC0000C /* PLL Status Register */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */
+#define CHIPID 0xFFC00014 /* Device ID Register */
-/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "defBF51x_base.h"
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define SWRST 0xFFC00100 /* Software Reset Register */
+#define SYSCR 0xFFC00104 /* System Configuration Register */
+#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
+
+#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
+#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
+#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
+
+/* SIC Additions to ADSP-BF51x (0xFFC0014C - 0xFFC00162) */
+#define SIC_IMASK1 0xFFC0014C /* Interrupt Mask register of SIC2 */
+#define SIC_IAR4 0xFFC00150 /* Interrupt Assignment register4 */
+#define SIC_IAR5 0xFFC00154 /* Interrupt Assignment register5 */
+#define SIC_IAR6 0xFFC00158 /* Interrupt Assignment register6 */
+#define SIC_IAR7 0xFFC0015C /* Interrupt Assignment register7 */
+#define SIC_ISR1 0xFFC00160 /* Interrupt Statur register */
+#define SIC_IWR1 0xFFC00164 /* Interrupt Wakeup register */
+
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
+#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
+#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
+
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define RTC_STAT 0xFFC00300 /* RTC Status Register */
+#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
+#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
+#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
+#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
+#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
+#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */
+
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART0_THR 0xFFC00400 /* Transmit Holding register */
+#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART0_LCR 0xFFC0040C /* Line Control Register */
+#define UART0_MCR 0xFFC00410 /* Modem Control Register */
+#define UART0_LSR 0xFFC00414 /* Line Status Register */
+#define UART0_MSR 0xFFC00418 /* Modem Status Register */
+#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART0_GCTL 0xFFC00424 /* Global Control Register */
+
+/* SPI0 Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI0_REGBASE 0xFFC00500
+#define SPI0_CTL 0xFFC00500 /* SPI Control Register */
+#define SPI0_FLG 0xFFC00504 /* SPI Flag register */
+#define SPI0_STAT 0xFFC00508 /* SPI Status register */
+#define SPI0_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
+#define SPI0_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
+#define SPI0_BAUD 0xFFC00514 /* SPI Baud rate Register */
+#define SPI0_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
+
+/* SPI1 Controller (0xFFC03400 - 0xFFC034FF) */
+#define SPI1_REGBASE 0xFFC03400
+#define SPI1_CTL 0xFFC03400 /* SPI Control Register */
+#define SPI1_FLG 0xFFC03404 /* SPI Flag register */
+#define SPI1_STAT 0xFFC03408 /* SPI Status register */
+#define SPI1_TDBR 0xFFC0340C /* SPI Transmit Data Buffer Register */
+#define SPI1_RDBR 0xFFC03410 /* SPI Receive Data Buffer Register */
+#define SPI1_BAUD 0xFFC03414 /* SPI Baud rate Register */
+#define SPI1_SHADOW 0xFFC03418 /* SPI_RDBR Shadow Register */
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
+
+#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */
+#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */
+#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */
+#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */
+
+#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */
+#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */
+#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */
+#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */
+
+#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */
+#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */
+#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */
+#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */
+
+#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */
+#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */
+#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */
+#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */
+
+#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */
+#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */
+#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */
+#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */
+
+#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */
+#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */
+#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */
+#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */
+#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */
+#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */
+#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */
+#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */
+#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */
+#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */
+#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */
+#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */
+#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */
+#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */
+#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */
+#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */
+#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */
+#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */
+#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+/* DMA Traffic Control Registers */
+#define DMAC_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMAC_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+
+/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
+#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
+#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
+#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
+#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
+#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
+#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
+#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
+#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
+#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
+#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
+#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
+#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
+#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
+
+#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
+#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
+#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
+#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
+#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
+#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
+#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
+#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
+#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
+#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
+#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
+#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
+#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
+
+#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
+#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
+#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
+#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
+#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
+#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
+#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
+#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
+#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
+#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
+#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
+#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
+#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
+
+#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
+#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
+#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
+#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
+#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
+#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
+#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
+#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
+#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
+#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
+#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
+#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
+#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
+
+#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
+#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
+#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
+#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
+#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
+#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
+#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
+#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
+#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
+#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
+#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
+#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
+#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
+
+#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
+#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
+#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
+#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
+#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
+#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
+#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
+#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
+#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
+#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
+#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
+#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
+#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
+
+#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
+#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
+#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
+#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
+#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
+#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
+#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
+#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
+#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
+#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
+#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
+#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
+#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
+
+#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
+#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
+#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
+#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
+#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
+#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
+#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
+#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
+#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
+#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
+#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
+#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
+#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
+
+#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */
+#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */
+#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */
+#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */
+#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */
+#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */
+#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */
+#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */
+#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */
+#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */
+#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */
+#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */
+#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */
+
+#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */
+#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */
+#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */
+#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */
+#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */
+#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */
+#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */
+#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */
+#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */
+#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */
+#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */
+#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */
+#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */
+
+#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */
+#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */
+#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */
+#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */
+#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */
+#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */
+#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */
+#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */
+#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */
+#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */
+#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */
+#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */
+#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */
+
+#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */
+#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */
+#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */
+#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */
+#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */
+#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */
+#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */
+#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */
+#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */
+#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */
+#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */
+#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */
+#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */
+
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */
+#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */
+#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */
+#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */
+#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */
+#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */
+#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */
+
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */
+#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */
+#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */
+#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */
+#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */
+#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */
+#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */
+
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */
+#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */
+#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */
+#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */
+#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */
+#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */
+#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */
+
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */
+#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */
+#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */
+#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */
+#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */
+#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */
+#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */
+
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
+#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
+#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
+#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
+#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
+
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+#define TWI0_REGBASE 0xFFC01400
+#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
+#define TWI0_CONTROL 0xFFC01404 /* TWI Control Register */
+#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
+#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
+#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
+#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
+#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
+#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
+#define TWI0_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */
+#define TWI0_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */
+#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
+#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
+#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
+#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
+#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
+#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
+
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */
+#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */
+#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */
+#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */
+#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */
+#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */
+#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */
+#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */
+#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */
+#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */
+#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */
+#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */
+#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */
+#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */
+#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */
+#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */
+#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */
+
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */
+#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */
+#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */
+#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */
+#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */
+#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */
+#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */
+#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */
+#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */
+#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */
+#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */
+#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */
+#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */
+#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */
+#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */
+#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */
+#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */
+
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define UART1_THR 0xFFC02000 /* Transmit Holding register */
+#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
+#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
+#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
+#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
+#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
+#define UART1_LCR 0xFFC0200C /* Line Control Register */
+#define UART1_MCR 0xFFC02010 /* Modem Control Register */
+#define UART1_LSR 0xFFC02014 /* Line Status Register */
+#define UART1_MSR 0xFFC02018 /* Modem Status Register */
+#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
+#define UART1_GCTL 0xFFC02024 /* Global Control Register */
+
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */
+#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */
+#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */
+#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */
+
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */
+#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */
+#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */
+#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */
+#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */
+#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */
+#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */
+
+#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */
+#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */
+#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */
+#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */
+#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */
+#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */
+#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */
+
+
+/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
+#define PORTF_MUX 0xFFC03210 /* Port F mux control */
+#define PORTG_MUX 0xFFC03214 /* Port G mux control */
+#define PORTH_MUX 0xFFC03218 /* Port H mux control */
+#define PORTF_DRIVE 0xFFC03220 /* Port F drive strength control */
+#define PORTG_DRIVE 0xFFC03224 /* Port G drive strength control */
+#define PORTH_DRIVE 0xFFC03228 /* Port H drive strength control */
+#define PORTF_SLEW 0xFFC03230 /* Port F slew control */
+#define PORTG_SLEW 0xFFC03234 /* Port G slew control */
+#define PORTH_SLEW 0xFFC03238 /* Port H slew control */
+#define PORTF_HYSTERISIS 0xFFC03240 /* Port F Schmitt trigger control */
+#define PORTG_HYSTERISIS 0xFFC03244 /* Port G Schmitt trigger control */
+#define PORTH_HYSTERISIS 0xFFC03248 /* Port H Schmitt trigger control */
+#define MISCPORT_DRIVE 0xFFC03280 /* Misc Port drive strength control */
+#define MISCPORT_SLEW 0xFFC03284 /* Misc Port slew control */
+#define MISCPORT_HYSTERISIS 0xFFC03288 /* Misc Port Schmitt trigger control */
+
+
+/***********************************************************************************
+** System MMR Register Bits And Macros
+**
+** Disclaimer: All macros are intended to make C and Assembly code more readable.
+** Use these macros carefully, as any that do left shifts for field
+** depositing will result in the lower order bits being destroyed. Any
+** macro that shifts left to properly position the bit-field should be
+** used as part of an OR to initialize a register and NOT as a dynamic
+** modifier UNLESS the lower order bits are saved and ORed back in when
+** the macro is used.
+*************************************************************************************/
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* SWRST Masks */
+#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
+#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
+#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
+#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
+#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
+
+/* SYSCR Masks */
+#define BMODE 0x0007 /* Boot Mode - Latched During HW Reset From Mode Pins */
+#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
+
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
+/* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK */
+
+#if 0
+#define IRQ_PLL_WAKEUP 0x00000001 /* PLL Wakeup Interrupt */
+
+#define IRQ_ERROR1 0x00000002 /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
+#define IRQ_ERROR2 0x00000004 /* Error Interrupt (CAN, Ethernet, SPORTx, PPI, SPI, UARTx) */
+#define IRQ_RTC 0x00000008 /* Real Time Clock Interrupt */
+#define IRQ_DMA0 0x00000010 /* DMA Channel 0 (PPI) Interrupt */
+#define IRQ_DMA3 0x00000020 /* DMA Channel 3 (SPORT0 RX) Interrupt */
+#define IRQ_DMA4 0x00000040 /* DMA Channel 4 (SPORT0 TX) Interrupt */
+#define IRQ_DMA5 0x00000080 /* DMA Channel 5 (SPORT1 RX) Interrupt */
+
+#define IRQ_DMA6 0x00000100 /* DMA Channel 6 (SPORT1 TX) Interrupt */
+#define IRQ_TWI 0x00000200 /* TWI Interrupt */
+#define IRQ_DMA7 0x00000400 /* DMA Channel 7 (SPI) Interrupt */
+#define IRQ_DMA8 0x00000800 /* DMA Channel 8 (UART0 RX) Interrupt */
+#define IRQ_DMA9 0x00001000 /* DMA Channel 9 (UART0 TX) Interrupt */
+#define IRQ_DMA10 0x00002000 /* DMA Channel 10 (UART1 RX) Interrupt */
+#define IRQ_DMA11 0x00004000 /* DMA Channel 11 (UART1 TX) Interrupt */
+#define IRQ_CAN_RX 0x00008000 /* CAN Receive Interrupt */
+
+#define IRQ_CAN_TX 0x00010000 /* CAN Transmit Interrupt */
+#define IRQ_DMA1 0x00020000 /* DMA Channel 1 (Ethernet RX) Interrupt */
+#define IRQ_PFA_PORTH 0x00020000 /* PF Port H (PF47:32) Interrupt A */
+#define IRQ_DMA2 0x00040000 /* DMA Channel 2 (Ethernet TX) Interrupt */
+#define IRQ_PFB_PORTH 0x00040000 /* PF Port H (PF47:32) Interrupt B */
+#define IRQ_TIMER0 0x00080000 /* Timer 0 Interrupt */
+#define IRQ_TIMER1 0x00100000 /* Timer 1 Interrupt */
+#define IRQ_TIMER2 0x00200000 /* Timer 2 Interrupt */
+#define IRQ_TIMER3 0x00400000 /* Timer 3 Interrupt */
+#define IRQ_TIMER4 0x00800000 /* Timer 4 Interrupt */
+
+#define IRQ_TIMER5 0x01000000 /* Timer 5 Interrupt */
+#define IRQ_TIMER6 0x02000000 /* Timer 6 Interrupt */
+#define IRQ_TIMER7 0x04000000 /* Timer 7 Interrupt */
+#define IRQ_PFA_PORTFG 0x08000000 /* PF Ports F&G (PF31:0) Interrupt A */
+#define IRQ_PFB_PORTF 0x80000000 /* PF Port F (PF15:0) Interrupt B */
+#define IRQ_DMA12 0x20000000 /* DMA Channels 12 (MDMA1 Source) RX Interrupt */
+#define IRQ_DMA13 0x20000000 /* DMA Channels 13 (MDMA1 Destination) TX Interrupt */
+#define IRQ_DMA14 0x40000000 /* DMA Channels 14 (MDMA0 Source) RX Interrupt */
+#define IRQ_DMA15 0x40000000 /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
+#define IRQ_WDOG 0x80000000 /* Software Watchdog Timer Interrupt */
+#define IRQ_PFB_PORTG 0x10000000 /* PF Port G (PF31:16) Interrupt B */
+#endif
+
+/* SIC_IAR0 Macros */
+#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
+#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
+#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
+#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */
+#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
+#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
+#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
+#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
+
+/* SIC_IAR1 Macros */
+#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */
+#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
+#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
+#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */
+#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
+#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
+#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
+#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
+
+/* SIC_IAR2 Macros */
+#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */
+#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
+#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
+#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */
+#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
+#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
+#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
+#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
+
+/* SIC_IAR3 Macros */
+#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */
+#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */
+#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */
+#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */
+#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */
+#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */
+#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */
+#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */
+
+
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
+
+/* **************** GENERAL PURPOSE TIMER MASKS **********************/
+/* TIMER_ENABLE Masks */
+#define TIMEN0 0x0001 /* Enable Timer 0 */
+#define TIMEN1 0x0002 /* Enable Timer 1 */
+#define TIMEN2 0x0004 /* Enable Timer 2 */
+#define TIMEN3 0x0008 /* Enable Timer 3 */
+#define TIMEN4 0x0010 /* Enable Timer 4 */
+#define TIMEN5 0x0020 /* Enable Timer 5 */
+#define TIMEN6 0x0040 /* Enable Timer 6 */
+#define TIMEN7 0x0080 /* Enable Timer 7 */
+
+/* TIMER_DISABLE Masks */
+#define TIMDIS0 TIMEN0 /* Disable Timer 0 */
+#define TIMDIS1 TIMEN1 /* Disable Timer 1 */
+#define TIMDIS2 TIMEN2 /* Disable Timer 2 */
+#define TIMDIS3 TIMEN3 /* Disable Timer 3 */
+#define TIMDIS4 TIMEN4 /* Disable Timer 4 */
+#define TIMDIS5 TIMEN5 /* Disable Timer 5 */
+#define TIMDIS6 TIMEN6 /* Disable Timer 6 */
+#define TIMDIS7 TIMEN7 /* Disable Timer 7 */
+
+/* TIMER_STATUS Masks */
+#define TIMIL0 0x00000001 /* Timer 0 Interrupt */
+#define TIMIL1 0x00000002 /* Timer 1 Interrupt */
+#define TIMIL2 0x00000004 /* Timer 2 Interrupt */
+#define TIMIL3 0x00000008 /* Timer 3 Interrupt */
+#define TOVF_ERR0 0x00000010 /* Timer 0 Counter Overflow */
+#define TOVF_ERR1 0x00000020 /* Timer 1 Counter Overflow */
+#define TOVF_ERR2 0x00000040 /* Timer 2 Counter Overflow */
+#define TOVF_ERR3 0x00000080 /* Timer 3 Counter Overflow */
+#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */
+#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */
+#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */
+#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */
+#define TIMIL4 0x00010000 /* Timer 4 Interrupt */
+#define TIMIL5 0x00020000 /* Timer 5 Interrupt */
+#define TIMIL6 0x00040000 /* Timer 6 Interrupt */
+#define TIMIL7 0x00080000 /* Timer 7 Interrupt */
+#define TOVF_ERR4 0x00100000 /* Timer 4 Counter Overflow */
+#define TOVF_ERR5 0x00200000 /* Timer 5 Counter Overflow */
+#define TOVF_ERR6 0x00400000 /* Timer 6 Counter Overflow */
+#define TOVF_ERR7 0x00800000 /* Timer 7 Counter Overflow */
+#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */
+#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */
+#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */
+#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */
+
+/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
+#define TOVL_ERR0 TOVF_ERR0
+#define TOVL_ERR1 TOVF_ERR1
+#define TOVL_ERR2 TOVF_ERR2
+#define TOVL_ERR3 TOVF_ERR3
+#define TOVL_ERR4 TOVF_ERR4
+#define TOVL_ERR5 TOVF_ERR5
+#define TOVL_ERR6 TOVF_ERR6
+#define TOVL_ERR7 TOVF_ERR7
+
+/* TIMERx_CONFIG Masks */
+#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */
+#define WDTH_CAP 0x0002 /* Width Capture Input Mode */
+#define EXT_CLK 0x0003 /* External Clock Mode */
+#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */
+#define PERIOD_CNT 0x0008 /* Period Count */
+#define IRQ_ENA 0x0010 /* Interrupt Request Enable */
+#define TIN_SEL 0x0020 /* Timer Input Select */
+#define OUT_DIS 0x0040 /* Output Pad Disable */
+#define CLK_SEL 0x0080 /* Timer Clock Select */
+#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */
+#define EMU_RUN 0x0200 /* Emulation Behavior Select */
+#define ERR_TYP 0xC000 /* Error Type */
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
+/* EBIU_AMGCTL Masks */
+#define AMCKEN 0x0001 /* Enable CLKOUT */
+#define AMBEN_NONE 0x0000 /* All Banks Disabled */
+#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */
+#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */
+
+/* EBIU_AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */
+#define B0RDYPOL 0x00000002 /* B0 RDY Active High */
+#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */
+#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */
+#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */
+#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */
+#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */
+
+#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */
+#define B1RDYPOL 0x00020000 /* B1 RDY Active High */
+#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */
+#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */
+#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */
+#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */
+#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */
+
+/* EBIU_AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */
+#define B2RDYPOL 0x00000002 /* B2 RDY Active High */
+#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */
+#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */
+#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */
+#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */
+#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */
+
+#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */
+#define B3RDYPOL 0x00020000 /* B3 RDY Active High */
+#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */
+#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */
+#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */
+#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */
+#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */
+
+
+/* ********************** SDRAM CONTROLLER MASKS **********************************************/
+/* EBIU_SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SDRAM Signals */
+#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */
+#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
+#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
+#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */
+#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */
+#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */
+#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */
+#define EBUFE 0x02000000 /* Enable External Buffering Timing */
+#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */
+#define EMREN 0x10000000 /* Extended Mode Register Enable */
+#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */
+#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x0001 /* Enable SDRAM External Bank */
+#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */
+#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */
+#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */
+#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */
+#define EBSZ_256 0x0008 /* SDRAM External Bank Size = 256MB */
+#define EBSZ_512 0x000A /* SDRAM External Bank Size = 512MB */
+#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */
+#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */
+#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */
+#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x0001 /* SDRAM Controller Idle */
+#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */
+#define SDPUA 0x0004 /* SDRAM Power-Up Active */
+#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */
+#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */
+#define BGSTAT 0x0020 /* Bus Grant Status */
+
+
+/* ************************** DMA CONTROLLER MASKS ********************************/
+
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */
+#define PMAP 0xF000 /* Peripheral Mapped To This Channel */
+#define PMAP_PPI 0x0000 /* PPI Port DMA */
+#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */
+#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */
+#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */
+#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */
+#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */
+#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */
+#define PMAP_SPI 0x7000 /* SPI Port DMA */
+#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */
+#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */
+#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */
+#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */
+
+/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x0001 /* PPI Port Enable */
+#define PORT_DIR 0x0002 /* PPI Port Direction */
+#define XFR_TYPE 0x000C /* PPI Transfer Type */
+#define PORT_CFG 0x0030 /* PPI Port Configuration */
+#define FLD_SEL 0x0040 /* PPI Active Field Select */
+#define PACK_EN 0x0080 /* PPI Packing Mode */
+#define DMA32 0x0100 /* PPI 32-bit DMA Enable */
+#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
+#define DLEN_8 0x0000 /* Data Length = 8 Bits */
+#define DLEN_10 0x0800 /* Data Length = 10 Bits */
+#define DLEN_11 0x1000 /* Data Length = 11 Bits */
+#define DLEN_12 0x1800 /* Data Length = 12 Bits */
+#define DLEN_13 0x2000 /* Data Length = 13 Bits */
+#define DLEN_14 0x2800 /* Data Length = 14 Bits */
+#define DLEN_15 0x3000 /* Data Length = 15 Bits */
+#define DLEN_16 0x3800 /* Data Length = 16 Bits */
+#define DLENGTH 0x3800 /* PPI Data Length */
+#define POLC 0x4000 /* PPI Clock Polarity */
+#define POLS 0x8000 /* PPI Frame Sync Polarity */
+
+/* PPI_STATUS Masks */
+#define FLD 0x0400 /* Field Indicator */
+#define FT_ERR 0x0800 /* Frame Track Error */
+#define OVR 0x1000 /* FIFO Overflow Error */
+#define UNDR 0x2000 /* FIFO Underrun Error */
+#define ERR_DET 0x4000 /* Error Detected Indicator */
+#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
+
+
+/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/
+/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
+#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
+#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
+
+/* TWI_PRESCALE Masks */
+#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
+#define TWI_ENA 0x0080 /* TWI Enable */
+#define SCCB 0x0200 /* SCCB Compatibility Enable */
+
+/* TWI_SLAVE_CTL Masks */
+#define SEN 0x0001 /* Slave Enable */
+#define SADD_LEN 0x0002 /* Slave Address Length */
+#define STDVAL 0x0004 /* Slave Transmit Data Valid */
+#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
+#define GEN 0x0010 /* General Call Adrress Matching Enabled */
+
+/* TWI_SLAVE_STAT Masks */
+#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
+#define GCALL 0x0002 /* General Call Indicator */
+
+/* TWI_MASTER_CTL Masks */
+#define MEN 0x0001 /* Master Mode Enable */
+#define MADD_LEN 0x0002 /* Master Address Length */
+#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
+#define FAST 0x0008 /* Use Fast Mode Timing Specs */
+#define STOP 0x0010 /* Issue Stop Condition */
+#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
+#define DCNT 0x3FC0 /* Data Bytes To Transfer */
+#define SDAOVR 0x4000 /* Serial Data Override */
+#define SCLOVR 0x8000 /* Serial Clock Override */
+
+/* TWI_MASTER_STAT Masks */
+#define MPROG 0x0001 /* Master Transfer In Progress */
+#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
+#define ANAK 0x0004 /* Address Not Acknowledged */
+#define DNAK 0x0008 /* Data Not Acknowledged */
+#define BUFRDERR 0x0010 /* Buffer Read Error */
+#define BUFWRERR 0x0020 /* Buffer Write Error */
+#define SDASEN 0x0040 /* Serial Data Sense */
+#define SCLSEN 0x0080 /* Serial Clock Sense */
+#define BUSBUSY 0x0100 /* Bus Busy Indicator */
+
+/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
+#define SINIT 0x0001 /* Slave Transfer Initiated */
+#define SCOMP 0x0002 /* Slave Transfer Complete */
+#define SERR 0x0004 /* Slave Transfer Error */
+#define SOVF 0x0008 /* Slave Overflow */
+#define MCOMP 0x0010 /* Master Transfer Complete */
+#define MERR 0x0020 /* Master Transfer Error */
+#define XMTSERV 0x0040 /* Transmit FIFO Service */
+#define RCVSERV 0x0080 /* Receive FIFO Service */
+
+/* TWI_FIFO_CTRL Masks */
+#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
+#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
+#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
+#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
+
+/* TWI_FIFO_STAT Masks */
+#define XMTSTAT 0x0003 /* Transmit FIFO Status */
+#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
+#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
+#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
+
+#define RCVSTAT 0x000C /* Receive FIFO Status */
+#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
+#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
+#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
+
+
+/* ******************* PIN CONTROL REGISTER MASKS ************************/
+/* PORT_MUX Masks */
+#define PJSE 0x0001 /* Port J SPI/SPORT Enable */
+#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */
+#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */
+
+#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */
+#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */
+#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */
+#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */
+
+#define PFDE 0x0008 /* Port F DMA Request Enable */
+#define PFDE_UART 0x0000 /* Enable UART0 RX/TX */
+#define PFDE_DMA 0x0008 /* Enable DMAR1:0 */
+
+#define PFTE 0x0010 /* Port F Timer Enable */
+#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */
+#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */
+
+#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */
+#define PFS6E_TIMER 0x0000 /* Enable TMR5 */
+#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */
+
+#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */
+#define PFS5E_TIMER 0x0000 /* Enable TMR4 */
+#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */
+
+#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */
+#define PFS4E_TIMER 0x0000 /* Enable TMR3 */
+#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */
+
+#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */
+#define PFFE_TIMER 0x0000 /* Enable TMR2 */
+#define PFFE_PPI 0x0100 /* Enable PPI FS3 */
+
+#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */
+#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */
+#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */
+
+#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */
+#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */
+#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */
+
+#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */
+#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */
+#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */
+
+
+/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/
+/* HDMAx_CTL Masks */
+#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */
+#define REP 0x0002 /* HDMA Request Polarity */
+#define UTE 0x0004 /* Urgency Threshold Enable */
+#define OIE 0x0010 /* Overflow Interrupt Enable */
+#define BDIE 0x0020 /* Block Done Interrupt Enable */
+#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */
+#define DRQ 0x0300 /* HDMA Request Type */
+#define DRQ_NONE 0x0000 /* No Request */
+#define DRQ_SINGLE 0x0100 /* Channels Request Single */
+#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */
+#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */
+#define RBC 0x1000 /* Reload BCNT With IBCNT */
+#define PS 0x2000 /* HDMA Pin Status */
+#define OI 0x4000 /* Overflow Interrupt Generated */
+#define BDI 0x8000 /* Block Done Interrupt Generated */
+
+/* entry addresses of the user-callable Boot ROM functions */
+
+#define _BOOTROM_RESET 0xEF000000
+#define _BOOTROM_FINAL_INIT 0xEF000002
+#define _BOOTROM_DO_MEMORY_DMA 0xEF000006
+#define _BOOTROM_BOOT_DXE_FLASH 0xEF000008
+#define _BOOTROM_BOOT_DXE_SPI 0xEF00000A
+#define _BOOTROM_BOOT_DXE_TWI 0xEF00000C
+#define _BOOTROM_GET_DXE_ADDRESS_FLASH 0xEF000010
+#define _BOOTROM_GET_DXE_ADDRESS_SPI 0xEF000012
+#define _BOOTROM_GET_DXE_ADDRESS_TWI 0xEF000014
+
+/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
+#define PGDE_UART PFDE_UART
+#define PGDE_DMA PFDE_DMA
+#define CKELOW SCKELOW
+
+/* HOST Port Registers */
+
+#define HOST_CONTROL 0xffc03400 /* HOST Control Register */
+#define HOST_STATUS 0xffc03404 /* HOST Status Register */
+#define HOST_TIMEOUT 0xffc03408 /* HOST Acknowledge Mode Timeout Register */
+
+/* Counter Registers */
+
+#define CNT_CONFIG 0xffc03500 /* Configuration Register */
+#define CNT_IMASK 0xffc03504 /* Interrupt Mask Register */
+#define CNT_STATUS 0xffc03508 /* Status Register */
+#define CNT_COMMAND 0xffc0350c /* Command Register */
+#define CNT_DEBOUNCE 0xffc03510 /* Debounce Register */
+#define CNT_COUNTER 0xffc03514 /* Counter Register */
+#define CNT_MAX 0xffc03518 /* Maximal Count Register */
+#define CNT_MIN 0xffc0351c /* Minimal Count Register */
+
+/* OTP/FUSE Registers */
+
+#define OTP_CONTROL 0xffc03600 /* OTP/Fuse Control Register */
+#define OTP_BEN 0xffc03604 /* OTP/Fuse Byte Enable */
+#define OTP_STATUS 0xffc03608 /* OTP/Fuse Status */
+#define OTP_TIMING 0xffc0360c /* OTP/Fuse Access Timing */
+
+/* Security Registers */
+
+#define SECURE_SYSSWT 0xffc03620 /* Secure System Switches */
+#define SECURE_CONTROL 0xffc03624 /* Secure Control */
+#define SECURE_STATUS 0xffc03628 /* Secure Status */
+
+/* OTP Read/Write Data Buffer Registers */
+
+#define OTP_DATA0 0xffc03680 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA1 0xffc03684 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA2 0xffc03688 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA3 0xffc0368c /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+
+/* Motor Control PWM Registers */
+
+#define PWM_CTRL 0xffc03700 /* PWM Control Register */
+#define PWM_STAT 0xffc03704 /* PWM Status Register */
+#define PWM_TM 0xffc03708 /* PWM Period Register */
+#define PWM_DT 0xffc0370c /* PWM Dead Time Register */
+#define PWM_GATE 0xffc03710 /* PWM Chopping Control */
+#define PWM_CHA 0xffc03714 /* PWM Channel A Duty Control */
+#define PWM_CHB 0xffc03718 /* PWM Channel B Duty Control */
+#define PWM_CHC 0xffc0371c /* PWM Channel C Duty Control */
+#define PWM_SEG 0xffc03720 /* PWM Crossover and Output Enable */
+#define PWM_SYNCWT 0xffc03724 /* PWM Sync Pluse Width Control */
+#define PWM_CHAL 0xffc03728 /* PWM Channel AL Duty Control (SR mode only) */
+#define PWM_CHBL 0xffc0372c /* PWM Channel BL Duty Control (SR mode only) */
+#define PWM_CHCL 0xffc03730 /* PWM Channel CL Duty Control (SR mode only) */
+#define PWM_LSI 0xffc03734 /* PWM Low Side Invert (SR mode only) */
+#define PWM_STAT2 0xffc03738 /* PWM Status Register 2 */
+
+
+/* ********************************************************** */
+/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
+/* and MULTI BIT READ MACROS */
+/* ********************************************************** */
+
+/* Bit masks for HOST_CONTROL */
+
+#define HOST_CNTR_HOST_EN 0x1 /* Host Enable */
+#define HOST_CNTR_nHOST_EN 0x0
+#define HOST_CNTR_HOST_END 0x2 /* Host Endianess */
+#define HOST_CNTR_nHOST_END 0x0
+#define HOST_CNTR_DATA_SIZE 0x4 /* Data Size */
+#define HOST_CNTR_nDATA_SIZE 0x0
+#define HOST_CNTR_HOST_RST 0x8 /* Host Reset */
+#define HOST_CNTR_nHOST_RST 0x0
+#define HOST_CNTR_HRDY_OVR 0x20 /* Host Ready Override */
+#define HOST_CNTR_nHRDY_OVR 0x0
+#define HOST_CNTR_INT_MODE 0x40 /* Interrupt Mode */
+#define HOST_CNTR_nINT_MODE 0x0
+#define HOST_CNTR_BT_EN 0x80 /* Bus Timeout Enable */
+#define HOST_CNTR_ nBT_EN 0x0
+#define HOST_CNTR_EHW 0x100 /* Enable Host Write */
+#define HOST_CNTR_nEHW 0x0
+#define HOST_CNTR_EHR 0x200 /* Enable Host Read */
+#define HOST_CNTR_nEHR 0x0
+#define HOST_CNTR_BDR 0x400 /* Burst DMA Requests */
+#define HOST_CNTR_nBDR 0x0
+
+/* Bit masks for HOST_STATUS */
+
+#define HOST_STAT_READY 0x1 /* DMA Ready */
+#define HOST_STAT_nREADY 0x0
+#define HOST_STAT_FIFOFULL 0x2 /* FIFO Full */
+#define HOST_STAT_nFIFOFULL 0x0
+#define HOST_STAT_FIFOEMPTY 0x4 /* FIFO Empty */
+#define HOST_STAT_nFIFOEMPTY 0x0
+#define HOST_STAT_COMPLETE 0x8 /* DMA Complete */
+#define HOST_STAT_nCOMPLETE 0x0
+#define HOST_STAT_HSHK 0x10 /* Host Handshake */
+#define HOST_STAT_nHSHK 0x0
+#define HOST_STAT_TIMEOUT 0x20 /* Host Timeout */
+#define HOST_STAT_nTIMEOUT 0x0
+#define HOST_STAT_HIRQ 0x40 /* Host Interrupt Request */
+#define HOST_STAT_nHIRQ 0x0
+#define HOST_STAT_ALLOW_CNFG 0x80 /* Allow New Configuration */
+#define HOST_STAT_nALLOW_CNFG 0x0
+#define HOST_STAT_DMA_DIR 0x100 /* DMA Direction */
+#define HOST_STAT_nDMA_DIR 0x0
+#define HOST_STAT_BTE 0x200 /* Bus Timeout Enabled */
+#define HOST_STAT_nBTE 0x0
+#define HOST_STAT_HOSTRD_DONE 0x8000 /* Host Read Completion Interrupt */
+#define HOST_STAT_nHOSTRD_DONE 0x0
+
+/* Bit masks for HOST_TIMEOUT */
+
+#define HOST_COUNT_TIMEOUT 0x7ff /* Host Timeout count */
+
+/* Bit masks for SECURE_SYSSWT */
+
+#define EMUDABL 0x1 /* Emulation Disable. */
+#define nEMUDABL 0x0
+#define RSTDABL 0x2 /* Reset Disable */
+#define nRSTDABL 0x0
+#define L1IDABL 0x1c /* L1 Instruction Memory Disable. */
+#define L1DADABL 0xe0 /* L1 Data Bank A Memory Disable. */
+#define L1DBDABL 0x700 /* L1 Data Bank B Memory Disable. */
+#define DMA0OVR 0x800 /* DMA0 Memory Access Override */
+#define nDMA0OVR 0x0
+#define DMA1OVR 0x1000 /* DMA1 Memory Access Override */
+#define nDMA1OVR 0x0
+#define EMUOVR 0x4000 /* Emulation Override */
+#define nEMUOVR 0x0
+#define OTPSEN 0x8000 /* OTP Secrets Enable. */
+#define nOTPSEN 0x0
+#define L2DABL 0x70000 /* L2 Memory Disable. */
+
+/* Bit masks for SECURE_CONTROL */
+
+#define SECURE0 0x1 /* SECURE 0 */
+#define nSECURE0 0x0
+#define SECURE1 0x2 /* SECURE 1 */
+#define nSECURE1 0x0
+#define SECURE2 0x4 /* SECURE 2 */
+#define nSECURE2 0x0
+#define SECURE3 0x8 /* SECURE 3 */
+#define nSECURE3 0x0
+
+/* Bit masks for SECURE_STATUS */
+
+#define SECMODE 0x3 /* Secured Mode Control State */
+#define NMI 0x4 /* Non Maskable Interrupt */
+#define nNMI 0x0
+#define AFVALID 0x8 /* Authentication Firmware Valid */
+#define nAFVALID 0x0
+#define AFEXIT 0x10 /* Authentication Firmware Exit */
+#define nAFEXIT 0x0
+#define SECSTAT 0xe0 /* Secure Status */
#endif /* _DEF_BF512_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
deleted file mode 100644
index 5f84913dcd91..000000000000
--- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
+++ /dev/null
@@ -1,1495 +0,0 @@
-/*
- * Copyright 2008 Analog Devices Inc.
- *
- * Licensed under the ADI BSD license or the GPL-2 (or later)
- */
-
-#ifndef _DEF_BF51X_H
-#define _DEF_BF51X_H
-
-
-/* ************************************************************** */
-/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF51x */
-/* ************************************************************** */
-
-/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
-#define PLL_CTL 0xFFC00000 /* PLL Control Register */
-#define PLL_DIV 0xFFC00004 /* PLL Divide Register */
-#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */
-#define PLL_STAT 0xFFC0000C /* PLL Status Register */
-#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */
-#define CHIPID 0xFFC00014 /* Device ID Register */
-
-/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
-#define SWRST 0xFFC00100 /* Software Reset Register */
-#define SYSCR 0xFFC00104 /* System Configuration Register */
-#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
-
-#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
-#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
-#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
-#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
-#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
-#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
-#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
-
-/* SIC Additions to ADSP-BF51x (0xFFC0014C - 0xFFC00162) */
-#define SIC_IMASK1 0xFFC0014C /* Interrupt Mask register of SIC2 */
-#define SIC_IAR4 0xFFC00150 /* Interrupt Assignment register4 */
-#define SIC_IAR5 0xFFC00154 /* Interrupt Assignment register5 */
-#define SIC_IAR6 0xFFC00158 /* Interrupt Assignment register6 */
-#define SIC_IAR7 0xFFC0015C /* Interrupt Assignment register7 */
-#define SIC_ISR1 0xFFC00160 /* Interrupt Statur register */
-#define SIC_IWR1 0xFFC00164 /* Interrupt Wakeup register */
-
-
-/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
-#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
-#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
-#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
-
-
-/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
-#define RTC_STAT 0xFFC00300 /* RTC Status Register */
-#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
-#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
-#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
-#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
-#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
-#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */
-
-
-/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
-#define UART0_THR 0xFFC00400 /* Transmit Holding register */
-#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
-#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
-#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
-#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
-#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
-#define UART0_LCR 0xFFC0040C /* Line Control Register */
-#define UART0_MCR 0xFFC00410 /* Modem Control Register */
-#define UART0_LSR 0xFFC00414 /* Line Status Register */
-#define UART0_MSR 0xFFC00418 /* Modem Status Register */
-#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
-#define UART0_GCTL 0xFFC00424 /* Global Control Register */
-
-/* SPI0 Controller (0xFFC00500 - 0xFFC005FF) */
-#define SPI0_REGBASE 0xFFC00500
-#define SPI0_CTL 0xFFC00500 /* SPI Control Register */
-#define SPI0_FLG 0xFFC00504 /* SPI Flag register */
-#define SPI0_STAT 0xFFC00508 /* SPI Status register */
-#define SPI0_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
-#define SPI0_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
-#define SPI0_BAUD 0xFFC00514 /* SPI Baud rate Register */
-#define SPI0_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
-
-/* SPI1 Controller (0xFFC03400 - 0xFFC034FF) */
-#define SPI1_REGBASE 0xFFC03400
-#define SPI1_CTL 0xFFC03400 /* SPI Control Register */
-#define SPI1_FLG 0xFFC03404 /* SPI Flag register */
-#define SPI1_STAT 0xFFC03408 /* SPI Status register */
-#define SPI1_TDBR 0xFFC0340C /* SPI Transmit Data Buffer Register */
-#define SPI1_RDBR 0xFFC03410 /* SPI Receive Data Buffer Register */
-#define SPI1_BAUD 0xFFC03414 /* SPI Baud rate Register */
-#define SPI1_SHADOW 0xFFC03418 /* SPI_RDBR Shadow Register */
-
-/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
-#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
-#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
-#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
-#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
-
-#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
-#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
-#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
-#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
-
-#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
-#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
-#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
-#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
-
-#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */
-#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */
-#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */
-#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */
-
-#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */
-#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */
-#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */
-#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */
-
-#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */
-#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */
-#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */
-#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */
-
-#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */
-#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */
-#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */
-#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */
-
-#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */
-#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */
-#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */
-#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */
-
-#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */
-#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */
-#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */
-
-/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
-#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */
-#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */
-#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */
-#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */
-#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */
-#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */
-#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */
-#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */
-#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */
-#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */
-#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */
-#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */
-#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */
-#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */
-#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */
-#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */
-#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */
-
-/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
-#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
-#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
-#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
-#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
-#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
-#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
-#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
-#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
-#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
-#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
-#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
-#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
-#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
-#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
-#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
-#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
-#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
-#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
-
-/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
-#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
-#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
-#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
-#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
-#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
-#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
-#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
-#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
-#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
-#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
-#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
-#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
-#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
-#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
-#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
-#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
-#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
-#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
-
-/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
-#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
-#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
-#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
-#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
-#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
-#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
-#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
-
-/* DMA Traffic Control Registers */
-#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
-#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
-#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
-#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
-#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
-#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
-#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
-#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
-#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
-#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
-#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
-#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
-#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
-#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
-
-#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
-#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
-#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
-#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
-#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
-#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
-#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
-#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
-#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
-#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
-#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
-#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
-#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
-
-#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
-#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
-#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
-#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
-#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
-#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
-#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
-#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
-#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
-#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
-#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
-#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
-#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
-
-#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
-#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
-#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
-#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
-#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
-#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
-#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
-#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
-#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
-#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
-#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
-#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
-#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
-
-#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
-#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
-#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
-#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
-#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
-#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
-#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
-#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
-#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
-#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
-#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
-#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
-#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
-
-#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
-#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
-#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
-#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
-#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
-#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
-#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
-#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
-#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
-#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
-#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
-#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
-#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
-
-#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
-#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
-#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
-#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
-#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
-#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
-#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
-#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
-#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
-#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
-#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
-#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
-#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
-
-#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
-#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
-#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
-#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
-#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
-#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
-#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
-#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
-#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
-#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
-#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
-#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
-#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
-
-#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */
-#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */
-#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */
-#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */
-#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */
-#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */
-#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */
-#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */
-#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */
-#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */
-#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */
-#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */
-#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */
-
-#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */
-#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */
-#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */
-#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */
-#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */
-#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */
-#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */
-#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */
-#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */
-#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */
-#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */
-#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */
-#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */
-
-#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */
-#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */
-#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */
-#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */
-#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */
-#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */
-#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */
-#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */
-#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */
-#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */
-#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */
-#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */
-#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */
-
-#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */
-#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */
-#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */
-#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */
-#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */
-#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */
-#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */
-#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */
-#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */
-#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */
-#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */
-#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */
-#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */
-
-#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
-#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */
-#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */
-#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */
-#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */
-#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */
-#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */
-#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
-#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */
-#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
-#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */
-#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */
-#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */
-
-#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
-#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */
-#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */
-#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */
-#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */
-#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */
-#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */
-#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
-#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */
-#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */
-#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */
-#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */
-#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */
-
-#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
-#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */
-#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */
-#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */
-#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */
-#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */
-#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */
-#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
-#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */
-#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
-#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */
-#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */
-#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */
-
-#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
-#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */
-#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */
-#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */
-#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */
-#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */
-#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */
-#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
-#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */
-#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
-#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */
-#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */
-#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */
-
-
-/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
-#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
-#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
-#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
-#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
-#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
-
-
-/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
-#define TWI0_REGBASE 0xFFC01400
-#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
-#define TWI0_CONTROL 0xFFC01404 /* TWI Control Register */
-#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
-#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
-#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
-#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
-#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
-#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
-#define TWI0_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */
-#define TWI0_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */
-#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
-#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
-#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
-#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
-#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
-#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
-
-
-/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
-#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */
-#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */
-#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */
-#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */
-#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */
-#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */
-#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */
-#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */
-#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */
-#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */
-#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */
-#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */
-#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */
-#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */
-#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */
-#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */
-#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */
-
-
-/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
-#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */
-#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */
-#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */
-#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */
-#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */
-#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */
-#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */
-#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */
-#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */
-#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */
-#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */
-#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */
-#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */
-#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */
-#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */
-#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */
-#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */
-
-
-/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
-#define UART1_THR 0xFFC02000 /* Transmit Holding register */
-#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
-#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
-#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
-#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
-#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
-#define UART1_LCR 0xFFC0200C /* Line Control Register */
-#define UART1_MCR 0xFFC02010 /* Modem Control Register */
-#define UART1_LSR 0xFFC02014 /* Line Status Register */
-#define UART1_MSR 0xFFC02018 /* Modem Status Register */
-#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
-#define UART1_GCTL 0xFFC02024 /* Global Control Register */
-
-
-/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
-#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */
-#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */
-#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */
-#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */
-
-
-/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
-#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */
-#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */
-#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */
-#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */
-#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */
-#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */
-#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */
-
-#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */
-#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */
-#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */
-#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */
-#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */
-#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */
-#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */
-
-
-/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
-#define PORTF_MUX 0xFFC03210 /* Port F mux control */
-#define PORTG_MUX 0xFFC03214 /* Port G mux control */
-#define PORTH_MUX 0xFFC03218 /* Port H mux control */
-#define PORTF_DRIVE 0xFFC03220 /* Port F drive strength control */
-#define PORTG_DRIVE 0xFFC03224 /* Port G drive strength control */
-#define PORTH_DRIVE 0xFFC03228 /* Port H drive strength control */
-#define PORTF_SLEW 0xFFC03230 /* Port F slew control */
-#define PORTG_SLEW 0xFFC03234 /* Port G slew control */
-#define PORTH_SLEW 0xFFC03238 /* Port H slew control */
-#define PORTF_HYSTERISIS 0xFFC03240 /* Port F Schmitt trigger control */
-#define PORTG_HYSTERISIS 0xFFC03244 /* Port G Schmitt trigger control */
-#define PORTH_HYSTERISIS 0xFFC03248 /* Port H Schmitt trigger control */
-#define MISCPORT_DRIVE 0xFFC03280 /* Misc Port drive strength control */
-#define MISCPORT_SLEW 0xFFC03284 /* Misc Port slew control */
-#define MISCPORT_HYSTERISIS 0xFFC03288 /* Misc Port Schmitt trigger control */
-
-
-/***********************************************************************************
-** System MMR Register Bits And Macros
-**
-** Disclaimer: All macros are intended to make C and Assembly code more readable.
-** Use these macros carefully, as any that do left shifts for field
-** depositing will result in the lower order bits being destroyed. Any
-** macro that shifts left to properly position the bit-field should be
-** used as part of an OR to initialize a register and NOT as a dynamic
-** modifier UNLESS the lower order bits are saved and ORed back in when
-** the macro is used.
-*************************************************************************************/
-
-/* CHIPID Masks */
-#define CHIPID_VERSION 0xF0000000
-#define CHIPID_FAMILY 0x0FFFF000
-#define CHIPID_MANUFACTURE 0x00000FFE
-
-/* SWRST Masks */
-#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
-#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
-#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
-#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
-#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
-
-/* SYSCR Masks */
-#define BMODE 0x0007 /* Boot Mode - Latched During HW Reset From Mode Pins */
-#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
-
-
-/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
-/* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK */
-
-#if 0
-#define IRQ_PLL_WAKEUP 0x00000001 /* PLL Wakeup Interrupt */
-
-#define IRQ_ERROR1 0x00000002 /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
-#define IRQ_ERROR2 0x00000004 /* Error Interrupt (CAN, Ethernet, SPORTx, PPI, SPI, UARTx) */
-#define IRQ_RTC 0x00000008 /* Real Time Clock Interrupt */
-#define IRQ_DMA0 0x00000010 /* DMA Channel 0 (PPI) Interrupt */
-#define IRQ_DMA3 0x00000020 /* DMA Channel 3 (SPORT0 RX) Interrupt */
-#define IRQ_DMA4 0x00000040 /* DMA Channel 4 (SPORT0 TX) Interrupt */
-#define IRQ_DMA5 0x00000080 /* DMA Channel 5 (SPORT1 RX) Interrupt */
-
-#define IRQ_DMA6 0x00000100 /* DMA Channel 6 (SPORT1 TX) Interrupt */
-#define IRQ_TWI 0x00000200 /* TWI Interrupt */
-#define IRQ_DMA7 0x00000400 /* DMA Channel 7 (SPI) Interrupt */
-#define IRQ_DMA8 0x00000800 /* DMA Channel 8 (UART0 RX) Interrupt */
-#define IRQ_DMA9 0x00001000 /* DMA Channel 9 (UART0 TX) Interrupt */
-#define IRQ_DMA10 0x00002000 /* DMA Channel 10 (UART1 RX) Interrupt */
-#define IRQ_DMA11 0x00004000 /* DMA Channel 11 (UART1 TX) Interrupt */
-#define IRQ_CAN_RX 0x00008000 /* CAN Receive Interrupt */
-
-#define IRQ_CAN_TX 0x00010000 /* CAN Transmit Interrupt */
-#define IRQ_DMA1 0x00020000 /* DMA Channel 1 (Ethernet RX) Interrupt */
-#define IRQ_PFA_PORTH 0x00020000 /* PF Port H (PF47:32) Interrupt A */
-#define IRQ_DMA2 0x00040000 /* DMA Channel 2 (Ethernet TX) Interrupt */
-#define IRQ_PFB_PORTH 0x00040000 /* PF Port H (PF47:32) Interrupt B */
-#define IRQ_TIMER0 0x00080000 /* Timer 0 Interrupt */
-#define IRQ_TIMER1 0x00100000 /* Timer 1 Interrupt */
-#define IRQ_TIMER2 0x00200000 /* Timer 2 Interrupt */
-#define IRQ_TIMER3 0x00400000 /* Timer 3 Interrupt */
-#define IRQ_TIMER4 0x00800000 /* Timer 4 Interrupt */
-
-#define IRQ_TIMER5 0x01000000 /* Timer 5 Interrupt */
-#define IRQ_TIMER6 0x02000000 /* Timer 6 Interrupt */
-#define IRQ_TIMER7 0x04000000 /* Timer 7 Interrupt */
-#define IRQ_PFA_PORTFG 0x08000000 /* PF Ports F&G (PF31:0) Interrupt A */
-#define IRQ_PFB_PORTF 0x80000000 /* PF Port F (PF15:0) Interrupt B */
-#define IRQ_DMA12 0x20000000 /* DMA Channels 12 (MDMA1 Source) RX Interrupt */
-#define IRQ_DMA13 0x20000000 /* DMA Channels 13 (MDMA1 Destination) TX Interrupt */
-#define IRQ_DMA14 0x40000000 /* DMA Channels 14 (MDMA0 Source) RX Interrupt */
-#define IRQ_DMA15 0x40000000 /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
-#define IRQ_WDOG 0x80000000 /* Software Watchdog Timer Interrupt */
-#define IRQ_PFB_PORTG 0x10000000 /* PF Port G (PF31:16) Interrupt B */
-#endif
-
-/* SIC_IAR0 Macros */
-#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
-#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
-#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
-#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */
-#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
-#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
-#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
-#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
-
-/* SIC_IAR1 Macros */
-#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */
-#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
-#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
-#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */
-#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
-#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
-#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
-#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
-
-/* SIC_IAR2 Macros */
-#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */
-#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
-#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
-#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */
-#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
-#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
-#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
-#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
-
-/* SIC_IAR3 Macros */
-#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */
-#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */
-#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */
-#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */
-#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */
-#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */
-#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */
-#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */
-
-
-/* SIC_IMASK Masks */
-#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
-#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
-#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
-#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
-
-/* SIC_IWR Masks */
-#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
-#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
-#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
-#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
-
-
-/* ************** UART CONTROLLER MASKS *************************/
-/* UARTx_LCR Masks */
-#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
-#define STB 0x04 /* Stop Bits */
-#define PEN 0x08 /* Parity Enable */
-#define EPS 0x10 /* Even Parity Select */
-#define STP 0x20 /* Stick Parity */
-#define SB 0x40 /* Set Break */
-#define DLAB 0x80 /* Divisor Latch Access */
-
-/* UARTx_MCR Mask */
-#define LOOP_ENA 0x10 /* Loopback Mode Enable */
-#define LOOP_ENA_P 0x04
-
-/* UARTx_LSR Masks */
-#define DR 0x01 /* Data Ready */
-#define OE 0x02 /* Overrun Error */
-#define PE 0x04 /* Parity Error */
-#define FE 0x08 /* Framing Error */
-#define BI 0x10 /* Break Interrupt */
-#define THRE 0x20 /* THR Empty */
-#define TEMT 0x40 /* TSR and UART_THR Empty */
-
-/* UARTx_IER Masks */
-#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
-#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
-#define ELSI 0x04 /* Enable RX Status Interrupt */
-
-/* UARTx_IIR Masks */
-#define NINT 0x01 /* Pending Interrupt */
-#define IIR_TX_READY 0x02 /* UART_THR empty */
-#define IIR_RX_READY 0x04 /* Receive data ready */
-#define IIR_LINE_CHANGE 0x06 /* Receive line status */
-#define IIR_STATUS 0x06 /* Highest Priority Pending Interrupt */
-
-/* UARTx_GCTL Masks */
-#define UCEN 0x01 /* Enable UARTx Clocks */
-#define IREN 0x02 /* Enable IrDA Mode */
-#define TPOLC 0x04 /* IrDA TX Polarity Change */
-#define RPOLC 0x08 /* IrDA RX Polarity Change */
-#define FPE 0x10 /* Force Parity Error On Transmit */
-#define FFE 0x20 /* Force Framing Error On Transmit */
-
-
-/* **************** GENERAL PURPOSE TIMER MASKS **********************/
-/* TIMER_ENABLE Masks */
-#define TIMEN0 0x0001 /* Enable Timer 0 */
-#define TIMEN1 0x0002 /* Enable Timer 1 */
-#define TIMEN2 0x0004 /* Enable Timer 2 */
-#define TIMEN3 0x0008 /* Enable Timer 3 */
-#define TIMEN4 0x0010 /* Enable Timer 4 */
-#define TIMEN5 0x0020 /* Enable Timer 5 */
-#define TIMEN6 0x0040 /* Enable Timer 6 */
-#define TIMEN7 0x0080 /* Enable Timer 7 */
-
-/* TIMER_DISABLE Masks */
-#define TIMDIS0 TIMEN0 /* Disable Timer 0 */
-#define TIMDIS1 TIMEN1 /* Disable Timer 1 */
-#define TIMDIS2 TIMEN2 /* Disable Timer 2 */
-#define TIMDIS3 TIMEN3 /* Disable Timer 3 */
-#define TIMDIS4 TIMEN4 /* Disable Timer 4 */
-#define TIMDIS5 TIMEN5 /* Disable Timer 5 */
-#define TIMDIS6 TIMEN6 /* Disable Timer 6 */
-#define TIMDIS7 TIMEN7 /* Disable Timer 7 */
-
-/* TIMER_STATUS Masks */
-#define TIMIL0 0x00000001 /* Timer 0 Interrupt */
-#define TIMIL1 0x00000002 /* Timer 1 Interrupt */
-#define TIMIL2 0x00000004 /* Timer 2 Interrupt */
-#define TIMIL3 0x00000008 /* Timer 3 Interrupt */
-#define TOVF_ERR0 0x00000010 /* Timer 0 Counter Overflow */
-#define TOVF_ERR1 0x00000020 /* Timer 1 Counter Overflow */
-#define TOVF_ERR2 0x00000040 /* Timer 2 Counter Overflow */
-#define TOVF_ERR3 0x00000080 /* Timer 3 Counter Overflow */
-#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */
-#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */
-#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */
-#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */
-#define TIMIL4 0x00010000 /* Timer 4 Interrupt */
-#define TIMIL5 0x00020000 /* Timer 5 Interrupt */
-#define TIMIL6 0x00040000 /* Timer 6 Interrupt */
-#define TIMIL7 0x00080000 /* Timer 7 Interrupt */
-#define TOVF_ERR4 0x00100000 /* Timer 4 Counter Overflow */
-#define TOVF_ERR5 0x00200000 /* Timer 5 Counter Overflow */
-#define TOVF_ERR6 0x00400000 /* Timer 6 Counter Overflow */
-#define TOVF_ERR7 0x00800000 /* Timer 7 Counter Overflow */
-#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */
-#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */
-#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */
-#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */
-
-/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
-#define TOVL_ERR0 TOVF_ERR0
-#define TOVL_ERR1 TOVF_ERR1
-#define TOVL_ERR2 TOVF_ERR2
-#define TOVL_ERR3 TOVF_ERR3
-#define TOVL_ERR4 TOVF_ERR4
-#define TOVL_ERR5 TOVF_ERR5
-#define TOVL_ERR6 TOVF_ERR6
-#define TOVL_ERR7 TOVF_ERR7
-
-/* TIMERx_CONFIG Masks */
-#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */
-#define WDTH_CAP 0x0002 /* Width Capture Input Mode */
-#define EXT_CLK 0x0003 /* External Clock Mode */
-#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */
-#define PERIOD_CNT 0x0008 /* Period Count */
-#define IRQ_ENA 0x0010 /* Interrupt Request Enable */
-#define TIN_SEL 0x0020 /* Timer Input Select */
-#define OUT_DIS 0x0040 /* Output Pad Disable */
-#define CLK_SEL 0x0080 /* Timer Clock Select */
-#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */
-#define EMU_RUN 0x0200 /* Emulation Behavior Select */
-#define ERR_TYP 0xC000 /* Error Type */
-
-
-/* ****************** GPIO PORTS F, G, H MASKS ***********************/
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
-/* Port F Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* Port G Masks */
-#define PG0 0x0001
-#define PG1 0x0002
-#define PG2 0x0004
-#define PG3 0x0008
-#define PG4 0x0010
-#define PG5 0x0020
-#define PG6 0x0040
-#define PG7 0x0080
-#define PG8 0x0100
-#define PG9 0x0200
-#define PG10 0x0400
-#define PG11 0x0800
-#define PG12 0x1000
-#define PG13 0x2000
-#define PG14 0x4000
-#define PG15 0x8000
-
-/* Port H Masks */
-#define PH0 0x0001
-#define PH1 0x0002
-#define PH2 0x0004
-#define PH3 0x0008
-#define PH4 0x0010
-#define PH5 0x0020
-#define PH6 0x0040
-#define PH7 0x0080
-
-/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
-/* EBIU_AMGCTL Masks */
-#define AMCKEN 0x0001 /* Enable CLKOUT */
-#define AMBEN_NONE 0x0000 /* All Banks Disabled */
-#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */
-#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */
-#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */
-#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */
-
-/* EBIU_AMBCTL0 Masks */
-#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */
-#define B0RDYPOL 0x00000002 /* B0 RDY Active High */
-#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */
-#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */
-#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */
-#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */
-#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */
-#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */
-#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */
-#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */
-#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */
-#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */
-#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */
-#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */
-#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */
-#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */
-#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */
-#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */
-#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */
-#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */
-#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */
-#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */
-#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */
-#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */
-#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */
-#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */
-#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */
-#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */
-#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */
-#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */
-#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */
-#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */
-#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */
-#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */
-#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */
-#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */
-
-#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */
-#define B1RDYPOL 0x00020000 /* B1 RDY Active High */
-#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */
-#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */
-#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */
-#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */
-#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */
-#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */
-#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */
-#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */
-#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */
-#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */
-#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */
-#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */
-#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */
-#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */
-#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */
-#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */
-#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */
-#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */
-#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */
-#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */
-#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */
-#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */
-#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */
-#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */
-#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */
-#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */
-#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */
-#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */
-#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */
-#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */
-#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */
-#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */
-#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */
-#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */
-
-/* EBIU_AMBCTL1 Masks */
-#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */
-#define B2RDYPOL 0x00000002 /* B2 RDY Active High */
-#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */
-#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */
-#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */
-#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */
-#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */
-#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */
-#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */
-#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */
-#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */
-#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */
-#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */
-#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */
-#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */
-#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */
-#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */
-#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */
-#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */
-#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */
-#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */
-#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */
-#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */
-#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */
-#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */
-#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */
-#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */
-#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */
-#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */
-#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */
-#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */
-#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */
-#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */
-#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */
-#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */
-#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */
-
-#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */
-#define B3RDYPOL 0x00020000 /* B3 RDY Active High */
-#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */
-#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */
-#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */
-#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */
-#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */
-#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */
-#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */
-#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */
-#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */
-#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */
-#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */
-#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */
-#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */
-#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */
-#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */
-#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */
-#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */
-#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */
-#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */
-#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */
-#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */
-#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */
-#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */
-#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */
-#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */
-#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */
-#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */
-#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */
-#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */
-#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */
-#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */
-#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */
-#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */
-#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */
-
-
-/* ********************** SDRAM CONTROLLER MASKS **********************************************/
-/* EBIU_SDGCTL Masks */
-#define SCTLE 0x00000001 /* Enable SDRAM Signals */
-#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */
-#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */
-#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
-#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
-#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
-#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
-#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
-#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
-#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
-#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
-#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
-#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
-#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
-#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
-#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
-#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
-#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
-#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
-#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
-#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
-#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
-#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
-#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
-#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
-#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
-#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
-#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
-#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
-#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
-#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
-#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
-#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
-#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
-#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
-#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
-#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
-#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
-#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */
-#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */
-#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */
-#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */
-#define EBUFE 0x02000000 /* Enable External Buffering Timing */
-#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */
-#define EMREN 0x10000000 /* Extended Mode Register Enable */
-#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */
-#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */
-
-/* EBIU_SDBCTL Masks */
-#define EBE 0x0001 /* Enable SDRAM External Bank */
-#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */
-#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */
-#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */
-#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */
-#define EBSZ_256 0x0008 /* SDRAM External Bank Size = 256MB */
-#define EBSZ_512 0x000A /* SDRAM External Bank Size = 512MB */
-#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */
-#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */
-#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */
-#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */
-
-/* EBIU_SDSTAT Masks */
-#define SDCI 0x0001 /* SDRAM Controller Idle */
-#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */
-#define SDPUA 0x0004 /* SDRAM Power-Up Active */
-#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */
-#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */
-#define BGSTAT 0x0020 /* Bus Grant Status */
-
-
-/* ************************** DMA CONTROLLER MASKS ********************************/
-
-/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
-#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */
-#define PMAP 0xF000 /* Peripheral Mapped To This Channel */
-#define PMAP_PPI 0x0000 /* PPI Port DMA */
-#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */
-#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */
-#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */
-#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */
-#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */
-#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */
-#define PMAP_SPI 0x7000 /* SPI Port DMA */
-#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */
-#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */
-#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */
-#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */
-
-/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
-/* PPI_CONTROL Masks */
-#define PORT_EN 0x0001 /* PPI Port Enable */
-#define PORT_DIR 0x0002 /* PPI Port Direction */
-#define XFR_TYPE 0x000C /* PPI Transfer Type */
-#define PORT_CFG 0x0030 /* PPI Port Configuration */
-#define FLD_SEL 0x0040 /* PPI Active Field Select */
-#define PACK_EN 0x0080 /* PPI Packing Mode */
-#define DMA32 0x0100 /* PPI 32-bit DMA Enable */
-#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
-#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
-#define DLEN_8 0x0000 /* Data Length = 8 Bits */
-#define DLEN_10 0x0800 /* Data Length = 10 Bits */
-#define DLEN_11 0x1000 /* Data Length = 11 Bits */
-#define DLEN_12 0x1800 /* Data Length = 12 Bits */
-#define DLEN_13 0x2000 /* Data Length = 13 Bits */
-#define DLEN_14 0x2800 /* Data Length = 14 Bits */
-#define DLEN_15 0x3000 /* Data Length = 15 Bits */
-#define DLEN_16 0x3800 /* Data Length = 16 Bits */
-#define DLENGTH 0x3800 /* PPI Data Length */
-#define POLC 0x4000 /* PPI Clock Polarity */
-#define POLS 0x8000 /* PPI Frame Sync Polarity */
-
-/* PPI_STATUS Masks */
-#define FLD 0x0400 /* Field Indicator */
-#define FT_ERR 0x0800 /* Frame Track Error */
-#define OVR 0x1000 /* FIFO Overflow Error */
-#define UNDR 0x2000 /* FIFO Underrun Error */
-#define ERR_DET 0x4000 /* Error Detected Indicator */
-#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
-
-
-/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/
-/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
-#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
-#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
-
-/* TWI_PRESCALE Masks */
-#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
-#define TWI_ENA 0x0080 /* TWI Enable */
-#define SCCB 0x0200 /* SCCB Compatibility Enable */
-
-/* TWI_SLAVE_CTL Masks */
-#define SEN 0x0001 /* Slave Enable */
-#define SADD_LEN 0x0002 /* Slave Address Length */
-#define STDVAL 0x0004 /* Slave Transmit Data Valid */
-#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
-#define GEN 0x0010 /* General Call Adrress Matching Enabled */
-
-/* TWI_SLAVE_STAT Masks */
-#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
-#define GCALL 0x0002 /* General Call Indicator */
-
-/* TWI_MASTER_CTL Masks */
-#define MEN 0x0001 /* Master Mode Enable */
-#define MADD_LEN 0x0002 /* Master Address Length */
-#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
-#define FAST 0x0008 /* Use Fast Mode Timing Specs */
-#define STOP 0x0010 /* Issue Stop Condition */
-#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
-#define DCNT 0x3FC0 /* Data Bytes To Transfer */
-#define SDAOVR 0x4000 /* Serial Data Override */
-#define SCLOVR 0x8000 /* Serial Clock Override */
-
-/* TWI_MASTER_STAT Masks */
-#define MPROG 0x0001 /* Master Transfer In Progress */
-#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
-#define ANAK 0x0004 /* Address Not Acknowledged */
-#define DNAK 0x0008 /* Data Not Acknowledged */
-#define BUFRDERR 0x0010 /* Buffer Read Error */
-#define BUFWRERR 0x0020 /* Buffer Write Error */
-#define SDASEN 0x0040 /* Serial Data Sense */
-#define SCLSEN 0x0080 /* Serial Clock Sense */
-#define BUSBUSY 0x0100 /* Bus Busy Indicator */
-
-/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
-#define SINIT 0x0001 /* Slave Transfer Initiated */
-#define SCOMP 0x0002 /* Slave Transfer Complete */
-#define SERR 0x0004 /* Slave Transfer Error */
-#define SOVF 0x0008 /* Slave Overflow */
-#define MCOMP 0x0010 /* Master Transfer Complete */
-#define MERR 0x0020 /* Master Transfer Error */
-#define XMTSERV 0x0040 /* Transmit FIFO Service */
-#define RCVSERV 0x0080 /* Receive FIFO Service */
-
-/* TWI_FIFO_CTRL Masks */
-#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
-#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
-#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
-#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
-
-/* TWI_FIFO_STAT Masks */
-#define XMTSTAT 0x0003 /* Transmit FIFO Status */
-#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
-#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
-#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
-
-#define RCVSTAT 0x000C /* Receive FIFO Status */
-#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
-#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
-#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
-
-
-/* ******************* PIN CONTROL REGISTER MASKS ************************/
-/* PORT_MUX Masks */
-#define PJSE 0x0001 /* Port J SPI/SPORT Enable */
-#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */
-#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */
-
-#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */
-#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */
-#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */
-#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */
-
-#define PFDE 0x0008 /* Port F DMA Request Enable */
-#define PFDE_UART 0x0000 /* Enable UART0 RX/TX */
-#define PFDE_DMA 0x0008 /* Enable DMAR1:0 */
-
-#define PFTE 0x0010 /* Port F Timer Enable */
-#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */
-#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */
-
-#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */
-#define PFS6E_TIMER 0x0000 /* Enable TMR5 */
-#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */
-
-#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */
-#define PFS5E_TIMER 0x0000 /* Enable TMR4 */
-#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */
-
-#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */
-#define PFS4E_TIMER 0x0000 /* Enable TMR3 */
-#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */
-
-#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */
-#define PFFE_TIMER 0x0000 /* Enable TMR2 */
-#define PFFE_PPI 0x0100 /* Enable PPI FS3 */
-
-#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */
-#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */
-#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */
-
-#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */
-#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */
-#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */
-
-#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */
-#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */
-#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */
-
-
-/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/
-/* HDMAx_CTL Masks */
-#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */
-#define REP 0x0002 /* HDMA Request Polarity */
-#define UTE 0x0004 /* Urgency Threshold Enable */
-#define OIE 0x0010 /* Overflow Interrupt Enable */
-#define BDIE 0x0020 /* Block Done Interrupt Enable */
-#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */
-#define DRQ 0x0300 /* HDMA Request Type */
-#define DRQ_NONE 0x0000 /* No Request */
-#define DRQ_SINGLE 0x0100 /* Channels Request Single */
-#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */
-#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */
-#define RBC 0x1000 /* Reload BCNT With IBCNT */
-#define PS 0x2000 /* HDMA Pin Status */
-#define OI 0x4000 /* Overflow Interrupt Generated */
-#define BDI 0x8000 /* Block Done Interrupt Generated */
-
-/* entry addresses of the user-callable Boot ROM functions */
-
-#define _BOOTROM_RESET 0xEF000000
-#define _BOOTROM_FINAL_INIT 0xEF000002
-#define _BOOTROM_DO_MEMORY_DMA 0xEF000006
-#define _BOOTROM_BOOT_DXE_FLASH 0xEF000008
-#define _BOOTROM_BOOT_DXE_SPI 0xEF00000A
-#define _BOOTROM_BOOT_DXE_TWI 0xEF00000C
-#define _BOOTROM_GET_DXE_ADDRESS_FLASH 0xEF000010
-#define _BOOTROM_GET_DXE_ADDRESS_SPI 0xEF000012
-#define _BOOTROM_GET_DXE_ADDRESS_TWI 0xEF000014
-
-/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
-#define PGDE_UART PFDE_UART
-#define PGDE_DMA PFDE_DMA
-#define CKELOW SCKELOW
-
-/* HOST Port Registers */
-
-#define HOST_CONTROL 0xffc03400 /* HOST Control Register */
-#define HOST_STATUS 0xffc03404 /* HOST Status Register */
-#define HOST_TIMEOUT 0xffc03408 /* HOST Acknowledge Mode Timeout Register */
-
-/* Counter Registers */
-
-#define CNT_CONFIG 0xffc03500 /* Configuration Register */
-#define CNT_IMASK 0xffc03504 /* Interrupt Mask Register */
-#define CNT_STATUS 0xffc03508 /* Status Register */
-#define CNT_COMMAND 0xffc0350c /* Command Register */
-#define CNT_DEBOUNCE 0xffc03510 /* Debounce Register */
-#define CNT_COUNTER 0xffc03514 /* Counter Register */
-#define CNT_MAX 0xffc03518 /* Maximal Count Register */
-#define CNT_MIN 0xffc0351c /* Minimal Count Register */
-
-/* OTP/FUSE Registers */
-
-#define OTP_CONTROL 0xffc03600 /* OTP/Fuse Control Register */
-#define OTP_BEN 0xffc03604 /* OTP/Fuse Byte Enable */
-#define OTP_STATUS 0xffc03608 /* OTP/Fuse Status */
-#define OTP_TIMING 0xffc0360c /* OTP/Fuse Access Timing */
-
-/* Security Registers */
-
-#define SECURE_SYSSWT 0xffc03620 /* Secure System Switches */
-#define SECURE_CONTROL 0xffc03624 /* Secure Control */
-#define SECURE_STATUS 0xffc03628 /* Secure Status */
-
-/* OTP Read/Write Data Buffer Registers */
-
-#define OTP_DATA0 0xffc03680 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA1 0xffc03684 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA2 0xffc03688 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA3 0xffc0368c /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-
-/* Motor Control PWM Registers */
-
-#define PWM_CTRL 0xffc03700 /* PWM Control Register */
-#define PWM_STAT 0xffc03704 /* PWM Status Register */
-#define PWM_TM 0xffc03708 /* PWM Period Register */
-#define PWM_DT 0xffc0370c /* PWM Dead Time Register */
-#define PWM_GATE 0xffc03710 /* PWM Chopping Control */
-#define PWM_CHA 0xffc03714 /* PWM Channel A Duty Control */
-#define PWM_CHB 0xffc03718 /* PWM Channel B Duty Control */
-#define PWM_CHC 0xffc0371c /* PWM Channel C Duty Control */
-#define PWM_SEG 0xffc03720 /* PWM Crossover and Output Enable */
-#define PWM_SYNCWT 0xffc03724 /* PWM Sync Pluse Width Control */
-#define PWM_CHAL 0xffc03728 /* PWM Channel AL Duty Control (SR mode only) */
-#define PWM_CHBL 0xffc0372c /* PWM Channel BL Duty Control (SR mode only) */
-#define PWM_CHCL 0xffc03730 /* PWM Channel CL Duty Control (SR mode only) */
-#define PWM_LSI 0xffc03734 /* PWM Low Side Invert (SR mode only) */
-#define PWM_STAT2 0xffc03738 /* PWM Status Register 2 */
-
-
-/* ********************************************************** */
-/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
-/* and MULTI BIT READ MACROS */
-/* ********************************************************** */
-
-/* Bit masks for HOST_CONTROL */
-
-#define HOST_CNTR_HOST_EN 0x1 /* Host Enable */
-#define HOST_CNTR_nHOST_EN 0x0
-#define HOST_CNTR_HOST_END 0x2 /* Host Endianess */
-#define HOST_CNTR_nHOST_END 0x0
-#define HOST_CNTR_DATA_SIZE 0x4 /* Data Size */
-#define HOST_CNTR_nDATA_SIZE 0x0
-#define HOST_CNTR_HOST_RST 0x8 /* Host Reset */
-#define HOST_CNTR_nHOST_RST 0x0
-#define HOST_CNTR_HRDY_OVR 0x20 /* Host Ready Override */
-#define HOST_CNTR_nHRDY_OVR 0x0
-#define HOST_CNTR_INT_MODE 0x40 /* Interrupt Mode */
-#define HOST_CNTR_nINT_MODE 0x0
-#define HOST_CNTR_BT_EN 0x80 /* Bus Timeout Enable */
-#define HOST_CNTR_ nBT_EN 0x0
-#define HOST_CNTR_EHW 0x100 /* Enable Host Write */
-#define HOST_CNTR_nEHW 0x0
-#define HOST_CNTR_EHR 0x200 /* Enable Host Read */
-#define HOST_CNTR_nEHR 0x0
-#define HOST_CNTR_BDR 0x400 /* Burst DMA Requests */
-#define HOST_CNTR_nBDR 0x0
-
-/* Bit masks for HOST_STATUS */
-
-#define HOST_STAT_READY 0x1 /* DMA Ready */
-#define HOST_STAT_nREADY 0x0
-#define HOST_STAT_FIFOFULL 0x2 /* FIFO Full */
-#define HOST_STAT_nFIFOFULL 0x0
-#define HOST_STAT_FIFOEMPTY 0x4 /* FIFO Empty */
-#define HOST_STAT_nFIFOEMPTY 0x0
-#define HOST_STAT_COMPLETE 0x8 /* DMA Complete */
-#define HOST_STAT_nCOMPLETE 0x0
-#define HOST_STAT_HSHK 0x10 /* Host Handshake */
-#define HOST_STAT_nHSHK 0x0
-#define HOST_STAT_TIMEOUT 0x20 /* Host Timeout */
-#define HOST_STAT_nTIMEOUT 0x0
-#define HOST_STAT_HIRQ 0x40 /* Host Interrupt Request */
-#define HOST_STAT_nHIRQ 0x0
-#define HOST_STAT_ALLOW_CNFG 0x80 /* Allow New Configuration */
-#define HOST_STAT_nALLOW_CNFG 0x0
-#define HOST_STAT_DMA_DIR 0x100 /* DMA Direction */
-#define HOST_STAT_nDMA_DIR 0x0
-#define HOST_STAT_BTE 0x200 /* Bus Timeout Enabled */
-#define HOST_STAT_nBTE 0x0
-#define HOST_STAT_HOSTRD_DONE 0x8000 /* Host Read Completion Interrupt */
-#define HOST_STAT_nHOSTRD_DONE 0x0
-
-/* Bit masks for HOST_TIMEOUT */
-
-#define HOST_COUNT_TIMEOUT 0x7ff /* Host Timeout count */
-
-/* Bit masks for SECURE_SYSSWT */
-
-#define EMUDABL 0x1 /* Emulation Disable. */
-#define nEMUDABL 0x0
-#define RSTDABL 0x2 /* Reset Disable */
-#define nRSTDABL 0x0
-#define L1IDABL 0x1c /* L1 Instruction Memory Disable. */
-#define L1DADABL 0xe0 /* L1 Data Bank A Memory Disable. */
-#define L1DBDABL 0x700 /* L1 Data Bank B Memory Disable. */
-#define DMA0OVR 0x800 /* DMA0 Memory Access Override */
-#define nDMA0OVR 0x0
-#define DMA1OVR 0x1000 /* DMA1 Memory Access Override */
-#define nDMA1OVR 0x0
-#define EMUOVR 0x4000 /* Emulation Override */
-#define nEMUOVR 0x0
-#define OTPSEN 0x8000 /* OTP Secrets Enable. */
-#define nOTPSEN 0x0
-#define L2DABL 0x70000 /* L2 Memory Disable. */
-
-/* Bit masks for SECURE_CONTROL */
-
-#define SECURE0 0x1 /* SECURE 0 */
-#define nSECURE0 0x0
-#define SECURE1 0x2 /* SECURE 1 */
-#define nSECURE1 0x0
-#define SECURE2 0x4 /* SECURE 2 */
-#define nSECURE2 0x0
-#define SECURE3 0x8 /* SECURE 3 */
-#define nSECURE3 0x0
-
-/* Bit masks for SECURE_STATUS */
-
-#define SECMODE 0x3 /* Secured Mode Control State */
-#define NMI 0x4 /* Non Maskable Interrupt */
-#define nNMI 0x0
-#define AFVALID 0x8 /* Authentication Firmware Valid */
-#define nAFVALID 0x0
-#define AFEXIT 0x10 /* Authentication Firmware Exit */
-#define nAFEXIT 0x0
-#define SECSTAT 0xe0 /* Secure Status */
-
-
-
-#endif /* _DEF_BF51X_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/gpio.h b/arch/blackfin/mach-bf518/include/mach/gpio.h
index 9af6ce0f6321..b480705bfc2e 100644
--- a/arch/blackfin/mach-bf518/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf518/include/mach/gpio.h
@@ -55,4 +55,8 @@
#define PORT_G GPIO_PG0
#define PORT_H GPIO_PH0
+#include <mach-common/ports-f.h>
+#include <mach-common/ports-g.h>
+#include <mach-common/ports-h.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c
index fc767ac76381..df95e072f7a2 100644
--- a/arch/blackfin/mach-bf527/boards/ad7160eval.c
+++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -67,6 +67,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 2c31af7a320a..ea71a7b0e47e 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -102,6 +102,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 9a736a850c5c..290ed1d9034e 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -66,6 +66,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 9222bc00bbd3..d54452c408d7 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -106,6 +106,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
index 7bc7577d6c4f..1fabdefea73a 100644
--- a/arch/blackfin/mach-bf527/dma.c
+++ b/arch/blackfin/mach-bf527/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..00c603fe8218
--- /dev/null
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 2
+
+#endif
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index c1d55b878b45..960e08919def 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v)
-#define UART_PUT_DLL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
-#define UART_PUT_IER(uart, v) bfin_write16(((uart)->port.membase + OFFSET_IER), v)
-#define UART_SET_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
-#define UART_PUT_LCR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
-#define UART_PUT_GCTL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
# define CONFIG_SERIAL_BFIN_CTSRTS
@@ -54,50 +27,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-/*
- * The pin configuration is different from schematic
- */
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -146,3 +75,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h
index f714c5de3073..e1d279274487 100644
--- a/arch/blackfin/mach-bf527/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h
@@ -1,49 +1,37 @@
/*
- * Copyright 2007-2009 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
#define _MACH_BLACKFIN_H_
#include "bf527.h"
-#include "defBF522.h"
#include "anomaly.h"
-#if defined(CONFIG_BF527) || defined(CONFIG_BF526)
-#include "defBF527.h"
+#include <asm/def_LPBlackfin.h>
+#if defined(CONFIG_BF523) || defined(CONFIG_BF522)
+# include "defBF522.h"
#endif
-
#if defined(CONFIG_BF525) || defined(CONFIG_BF524)
-#include "defBF525.h"
+# include "defBF525.h"
#endif
-
-#if !defined(__ASSEMBLY__)
-#include "cdefBF522.h"
-
#if defined(CONFIG_BF527) || defined(CONFIG_BF526)
-#include "cdefBF527.h"
+# include "defBF527.h"
#endif
-#if defined(CONFIG_BF525) || defined(CONFIG_BF524)
-#include "cdefBF525.h"
-#endif
+#if !defined(__ASSEMBLY__)
+# include <asm/cdef_LPBlackfin.h>
+# if defined(CONFIG_BF523) || defined(CONFIG_BF522)
+# include "cdefBF522.h"
+# endif
+# if defined(CONFIG_BF525) || defined(CONFIG_BF524)
+# include "cdefBF525.h"
+# endif
+# if defined(CONFIG_BF527) || defined(CONFIG_BF526)
+# include "cdefBF527.h"
+# endif
#endif
-#define BFIN_UART_NR_PORTS 2
-
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
-
#endif
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
index 1079af8c7aef..618dfcdfa91a 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
@@ -1,21 +1,1095 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF522_H
#define _CDEF_BF522_H
-/* include all Core registers and bit definitions */
-#include "defBF522.h"
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
+#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
+#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV, val)
+#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
+#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT, val)
+#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
+#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT, val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val)
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF522 */
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define bfin_read_SWRST() bfin_read16(SWRST)
+#define bfin_write_SWRST(val) bfin_write16(SWRST, val)
+#define bfin_read_SYSCR() bfin_read16(SYSCR)
+#define bfin_write_SYSCR(val) bfin_write16(SYSCR, val)
-/* include cdefBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "cdefBF52x_base.h"
+#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
+#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
+#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
+#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
+#define bfin_read_SIC_IMASK(x) bfin_read32(SIC_IMASK0 + (x << 6))
+#define bfin_write_SIC_IMASK(x, val) bfin_write32((SIC_IMASK0 + (x << 6)), val)
+
+#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
+#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0, val)
+#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
+#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1, val)
+#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
+#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2, val)
+#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
+#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3, val)
+
+#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
+#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0, val)
+#define bfin_read_SIC_ISR(x) bfin_read32(SIC_ISR0 + (x << 6))
+#define bfin_write_SIC_ISR(x, val) bfin_write32((SIC_ISR0 + (x << 6)), val)
+
+#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
+#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0, val)
+#define bfin_read_SIC_IWR(x) bfin_read32(SIC_IWR0 + (x << 6))
+#define bfin_write_SIC_IWR(x, val) bfin_write32((SIC_IWR0 + (x << 6)), val)
+
+/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
+
+#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
+#define bfin_write_SIC_IMASK1(val) bfin_write32(SIC_IMASK1, val)
+#define bfin_read_SIC_IAR4() bfin_read32(SIC_IAR4)
+#define bfin_write_SIC_IAR4(val) bfin_write32(SIC_IAR4, val)
+#define bfin_read_SIC_IAR5() bfin_read32(SIC_IAR5)
+#define bfin_write_SIC_IAR5(val) bfin_write32(SIC_IAR5, val)
+#define bfin_read_SIC_IAR6() bfin_read32(SIC_IAR6)
+#define bfin_write_SIC_IAR6(val) bfin_write32(SIC_IAR6, val)
+#define bfin_read_SIC_IAR7() bfin_read32(SIC_IAR7)
+#define bfin_write_SIC_IAR7(val) bfin_write32(SIC_IAR7, val)
+#define bfin_read_SIC_ISR1() bfin_read32(SIC_ISR1)
+#define bfin_write_SIC_ISR1(val) bfin_write32(SIC_ISR1, val)
+#define bfin_read_SIC_IWR1() bfin_read32(SIC_IWR1)
+#define bfin_write_SIC_IWR1(val) bfin_write32(SIC_IWR1, val)
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
+#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val)
+#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
+#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val)
+#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
+#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val)
+
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
+#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT, val)
+#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
+#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL, val)
+#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
+#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT, val)
+#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
+#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT, val)
+#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
+#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM, val)
+#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
+#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST, val)
+#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
+#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN, val)
+
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define bfin_read_UART0_THR() bfin_read16(UART0_THR)
+#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR, val)
+#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR)
+#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR, val)
+#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL)
+#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL, val)
+#define bfin_read_UART0_IER() bfin_read16(UART0_IER)
+#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER, val)
+#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH)
+#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH, val)
+#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR)
+#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR, val)
+#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR)
+#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR, val)
+#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR)
+#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR, val)
+#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR)
+#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR, val)
+#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR)
+#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR, val)
+#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR)
+#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR, val)
+#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL)
+#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL, val)
+
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL)
+#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL, val)
+#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG)
+#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG, val)
+#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT)
+#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT, val)
+#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR)
+#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR, val)
+#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR)
+#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR, val)
+#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD)
+#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD, val)
+#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW)
+#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW, val)
+
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
+#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val)
+#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
+#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val)
+#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
+#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val)
+#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
+#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val)
+
+#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
+#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val)
+#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
+#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val)
+#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
+#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val)
+#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
+#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val)
+
+#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
+#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val)
+#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
+#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val)
+#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
+#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val)
+#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
+#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val)
+
+#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
+#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val)
+#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
+#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val)
+#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
+#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val)
+#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
+#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val)
+
+#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
+#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val)
+#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
+#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val)
+#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
+#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val)
+#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
+#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val)
+
+#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
+#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val)
+#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
+#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val)
+#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
+#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val)
+#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
+#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val)
+
+#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
+#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val)
+#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
+#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val)
+#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
+#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val)
+#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
+#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val)
+
+#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
+#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val)
+#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
+#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val)
+#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
+#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val)
+#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
+#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val)
+
+#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
+#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE, val)
+#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
+#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE, val)
+#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS)
+#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS, val)
+
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define bfin_read_PORTFIO() bfin_read16(PORTFIO)
+#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO, val)
+#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR)
+#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR, val)
+#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET)
+#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET, val)
+#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE)
+#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE, val)
+#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA)
+#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA, val)
+#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR)
+#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR, val)
+#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET)
+#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET, val)
+#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE)
+#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB)
+#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB, val)
+#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR)
+#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR, val)
+#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET)
+#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET, val)
+#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE)
+#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR)
+#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR, val)
+#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR)
+#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR, val)
+#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE)
+#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE, val)
+#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH)
+#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH, val)
+#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN)
+#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN, val)
+
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
+#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val)
+#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
+#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val)
+#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
+#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val)
+#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
+#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val)
+#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
+#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
+#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
+#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
+#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val)
+#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
+#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val)
+#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
+#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val)
+#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
+#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val)
+#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
+#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val)
+#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
+#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val)
+#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
+#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val)
+#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
+#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val)
+#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
+#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val)
+#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
+#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val)
+#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
+#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val)
+#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
+#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val)
+#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
+#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val)
+#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
+#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val)
+#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
+#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val)
+
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
+#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1, val)
+#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
+#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2, val)
+#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
+#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV, val)
+#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
+#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV, val)
+#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
+#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
+#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
+#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
+#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2, val)
+#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
+#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV, val)
+#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
+#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV, val)
+#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
+#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT, val)
+#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
+#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL, val)
+#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
+#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1, val)
+#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
+#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2, val)
+#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
+#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0, val)
+#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
+#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1, val)
+#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
+#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2, val)
+#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
+#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3, val)
+#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
+#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0, val)
+#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
+#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1, val)
+#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
+#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2, val)
+#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
+#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3, val)
+
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
+#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL, val)
+#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
+#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0, val)
+#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
+#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1, val)
+#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
+#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL, val)
+#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
+#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL, val)
+#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
+#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC, val)
+#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
+#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT, val)
+
+
+/* DMA Traffic Control Registers */
+#define bfin_read_DMAC_TC_PER() bfin_read16(DMAC_TC_PER)
+#define bfin_write_DMAC_TC_PER(val) bfin_write16(DMAC_TC_PER, val)
+#define bfin_read_DMAC_TC_CNT() bfin_read16(DMAC_TC_CNT)
+#define bfin_write_DMAC_TC_CNT(val) bfin_write16(DMAC_TC_CNT, val)
+
+/* DMA Controller */
+#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
+#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG, val)
+#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
+#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val)
+#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
+#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val)
+#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
+#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT, val)
+#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
+#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT, val)
+#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
+#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY, val)
+#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
+#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY, val)
+#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
+#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val)
+#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
+#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val)
+#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
+#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT, val)
+#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
+#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT, val)
+#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
+#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS, val)
+#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
+#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
+#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG, val)
+#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
+#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val)
+#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
+#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val)
+#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
+#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT, val)
+#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
+#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT, val)
+#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
+#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY, val)
+#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
+#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY, val)
+#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
+#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val)
+#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
+#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val)
+#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
+#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT, val)
+#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
+#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT, val)
+#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
+#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS, val)
+#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
+#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
+#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG, val)
+#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
+#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val)
+#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
+#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val)
+#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
+#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT, val)
+#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
+#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT, val)
+#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
+#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY, val)
+#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
+#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY, val)
+#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
+#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val)
+#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
+#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val)
+#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
+#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT, val)
+#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
+#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT, val)
+#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
+#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS, val)
+#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
+#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
+#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG, val)
+#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
+#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val)
+#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
+#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val)
+#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
+#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT, val)
+#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
+#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT, val)
+#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
+#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY, val)
+#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
+#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY, val)
+#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
+#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val)
+#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
+#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val)
+#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
+#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT, val)
+#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
+#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT, val)
+#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
+#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS, val)
+#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
+#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
+#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG, val)
+#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
+#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val)
+#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
+#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val)
+#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
+#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT, val)
+#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
+#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT, val)
+#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
+#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY, val)
+#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
+#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY, val)
+#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
+#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val)
+#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
+#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val)
+#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
+#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT, val)
+#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
+#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT, val)
+#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
+#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS, val)
+#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
+#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
+#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG, val)
+#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
+#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val)
+#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
+#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val)
+#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
+#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT, val)
+#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
+#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT, val)
+#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
+#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY, val)
+#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
+#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY, val)
+#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
+#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val)
+#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
+#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val)
+#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
+#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT, val)
+#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
+#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT, val)
+#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
+#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS, val)
+#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
+#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
+#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG, val)
+#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
+#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val)
+#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
+#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val)
+#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
+#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT, val)
+#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
+#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT, val)
+#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
+#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY, val)
+#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
+#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY, val)
+#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
+#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val)
+#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
+#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val)
+#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
+#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT, val)
+#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
+#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT, val)
+#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
+#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS, val)
+#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
+#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
+#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG, val)
+#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
+#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val)
+#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
+#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val)
+#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
+#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT, val)
+#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
+#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT, val)
+#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
+#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY, val)
+#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
+#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY, val)
+#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
+#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val)
+#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
+#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val)
+#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
+#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT, val)
+#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
+#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT, val)
+#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
+#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS, val)
+#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
+#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG)
+#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG, val)
+#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR)
+#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val)
+#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR)
+#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val)
+#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT)
+#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT, val)
+#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT)
+#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT, val)
+#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY)
+#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY, val)
+#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY)
+#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY, val)
+#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR)
+#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val)
+#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR)
+#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val)
+#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT)
+#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT, val)
+#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT)
+#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT, val)
+#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS)
+#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS, val)
+#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP)
+#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG)
+#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG, val)
+#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR)
+#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val)
+#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR)
+#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val)
+#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT)
+#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT, val)
+#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT)
+#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT, val)
+#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY)
+#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY, val)
+#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY)
+#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY, val)
+#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR)
+#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val)
+#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR)
+#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val)
+#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT)
+#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT, val)
+#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT)
+#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT, val)
+#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS)
+#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS, val)
+#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP)
+#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG)
+#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG, val)
+#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR)
+#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val)
+#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR)
+#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val)
+#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT)
+#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT, val)
+#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT)
+#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT, val)
+#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY)
+#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY, val)
+#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY)
+#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY, val)
+#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR)
+#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val)
+#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR)
+#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val)
+#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT)
+#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT, val)
+#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT)
+#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT, val)
+#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS)
+#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS, val)
+#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP)
+#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP, val)
+
+#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG)
+#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG, val)
+#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR)
+#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val)
+#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR)
+#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val)
+#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT)
+#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT, val)
+#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT)
+#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT, val)
+#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY)
+#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY, val)
+#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY)
+#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY, val)
+#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR)
+#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val)
+#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR)
+#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val)
+#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT)
+#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT, val)
+#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT)
+#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT, val)
+#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS)
+#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS, val)
+#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP)
+#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG, val)
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR, val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT, val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT, val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY, val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY, val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR, val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS, val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG, val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR, val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT, val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT, val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY, val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY, val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR, val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS, val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG, val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR, val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT, val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT, val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY, val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY, val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR, val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS, val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP, val)
+
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG, val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR, val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT, val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT, val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY, val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY, val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR, val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS, val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP, val)
+
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
+#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val)
+#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
+#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF)
+#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
+#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val)
+#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
+#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT, val)
+#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
+#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME, val)
+
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define bfin_read_PORTGIO() bfin_read16(PORTGIO)
+#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO, val)
+#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR)
+#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR, val)
+#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET)
+#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET, val)
+#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE)
+#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE, val)
+#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA)
+#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA, val)
+#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR)
+#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR, val)
+#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET)
+#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET, val)
+#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE)
+#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB)
+#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB, val)
+#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR)
+#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR, val)
+#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET)
+#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET, val)
+#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE)
+#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR)
+#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR, val)
+#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR)
+#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR, val)
+#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE)
+#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE, val)
+#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH)
+#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH, val)
+#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN)
+#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN, val)
+
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define bfin_read_PORTHIO() bfin_read16(PORTHIO)
+#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO, val)
+#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR)
+#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR, val)
+#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET)
+#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET, val)
+#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE)
+#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE, val)
+#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA)
+#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA, val)
+#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR)
+#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR, val)
+#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET)
+#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET, val)
+#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE)
+#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE, val)
+#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB)
+#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB, val)
+#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR)
+#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR, val)
+#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET)
+#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET, val)
+#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE)
+#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE, val)
+#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR)
+#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR, val)
+#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR)
+#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR, val)
+#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE)
+#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE, val)
+#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH)
+#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH, val)
+#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN)
+#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN, val)
+
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define bfin_read_UART1_THR() bfin_read16(UART1_THR)
+#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR, val)
+#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR)
+#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR, val)
+#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL)
+#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL, val)
+#define bfin_read_UART1_IER() bfin_read16(UART1_IER)
+#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER, val)
+#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH)
+#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH, val)
+#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR)
+#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR, val)
+#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR)
+#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR, val)
+#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR)
+#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR, val)
+#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR)
+#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR, val)
+#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR)
+#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR, val)
+#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR)
+#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR, val)
+#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL)
+#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL, val)
+
+/* Omit CAN register sets from the cdefBF534.h (CAN is not in the ADSP-BF52x processor) */
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER)
+#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER, val)
+#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER)
+#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER, val)
+#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER)
+#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER, val)
+#define bfin_read_PORT_MUX() bfin_read16(PORT_MUX)
+#define bfin_write_PORT_MUX(val) bfin_write16(PORT_MUX, val)
+
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL)
+#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val)
+#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT)
+#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val)
+#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT)
+#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val)
+#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT)
+#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val)
+#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW)
+#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val)
+#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT)
+#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val)
+#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT)
+#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val)
+
+#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL)
+#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val)
+#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT)
+#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val)
+#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT)
+#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val)
+#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT)
+#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val)
+#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW)
+#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val)
+#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT)
+#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val)
+#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
+#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val)
+
+/* ==== end from cdefBF534.h ==== */
+
+/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
+
+#define bfin_read_PORTF_MUX() bfin_read16(PORTF_MUX)
+#define bfin_write_PORTF_MUX(val) bfin_write16(PORTF_MUX, val)
+#define bfin_read_PORTG_MUX() bfin_read16(PORTG_MUX)
+#define bfin_write_PORTG_MUX(val) bfin_write16(PORTG_MUX, val)
+#define bfin_read_PORTH_MUX() bfin_read16(PORTH_MUX)
+#define bfin_write_PORTH_MUX(val) bfin_write16(PORTH_MUX, val)
+
+#define bfin_read_PORTF_DRIVE() bfin_read16(PORTF_DRIVE)
+#define bfin_write_PORTF_DRIVE(val) bfin_write16(PORTF_DRIVE, val)
+#define bfin_read_PORTG_DRIVE() bfin_read16(PORTG_DRIVE)
+#define bfin_write_PORTG_DRIVE(val) bfin_write16(PORTG_DRIVE, val)
+#define bfin_read_PORTH_DRIVE() bfin_read16(PORTH_DRIVE)
+#define bfin_write_PORTH_DRIVE(val) bfin_write16(PORTH_DRIVE, val)
+#define bfin_read_PORTF_SLEW() bfin_read16(PORTF_SLEW)
+#define bfin_write_PORTF_SLEW(val) bfin_write16(PORTF_SLEW, val)
+#define bfin_read_PORTG_SLEW() bfin_read16(PORTG_SLEW)
+#define bfin_write_PORTG_SLEW(val) bfin_write16(PORTG_SLEW, val)
+#define bfin_read_PORTH_SLEW() bfin_read16(PORTH_SLEW)
+#define bfin_write_PORTH_SLEW(val) bfin_write16(PORTH_SLEW, val)
+#define bfin_read_PORTF_HYSTERISIS() bfin_read16(PORTF_HYSTERISIS)
+#define bfin_write_PORTF_HYSTERISIS(val) bfin_write16(PORTF_HYSTERISIS, val)
+#define bfin_read_PORTG_HYSTERISIS() bfin_read16(PORTG_HYSTERISIS)
+#define bfin_write_PORTG_HYSTERISIS(val) bfin_write16(PORTG_HYSTERISIS, val)
+#define bfin_read_PORTH_HYSTERISIS() bfin_read16(PORTH_HYSTERISIS)
+#define bfin_write_PORTH_HYSTERISIS(val) bfin_write16(PORTH_HYSTERISIS, val)
+#define bfin_read_MISCPORT_DRIVE() bfin_read16(MISCPORT_DRIVE)
+#define bfin_write_MISCPORT_DRIVE(val) bfin_write16(MISCPORT_DRIVE, val)
+#define bfin_read_MISCPORT_SLEW() bfin_read16(MISCPORT_SLEW)
+#define bfin_write_MISCPORT_SLEW(val) bfin_write16(MISCPORT_SLEW, val)
+#define bfin_read_MISCPORT_HYSTERISIS() bfin_read16(MISCPORT_HYSTERISIS)
+#define bfin_write_MISCPORT_HYSTERISIS(val) bfin_write16(MISCPORT_HYSTERISIS, val)
+
+/* HOST Port Registers */
+
+#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL)
+#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val)
+#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS)
+#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val)
+#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT)
+#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val)
+
+/* Counter Registers */
+
+#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG)
+#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val)
+#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK)
+#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val)
+#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS)
+#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val)
+#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND)
+#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val)
+#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE)
+#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val)
+#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER)
+#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val)
+#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX)
+#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val)
+#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN)
+#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val)
+
+/* Security Registers */
+
+#define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT)
+#define bfin_write_SECURE_SYSSWT(val) bfin_write32(SECURE_SYSSWT, val)
+#define bfin_read_SECURE_CONTROL() bfin_read16(SECURE_CONTROL)
+#define bfin_write_SECURE_CONTROL(val) bfin_write16(SECURE_CONTROL, val)
+#define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS)
+#define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val)
+
+/* NFC Registers */
+
+#define bfin_read_NFC_CTL() bfin_read16(NFC_CTL)
+#define bfin_write_NFC_CTL(val) bfin_write16(NFC_CTL, val)
+#define bfin_read_NFC_STAT() bfin_read16(NFC_STAT)
+#define bfin_write_NFC_STAT(val) bfin_write16(NFC_STAT, val)
+#define bfin_read_NFC_IRQSTAT() bfin_read16(NFC_IRQSTAT)
+#define bfin_write_NFC_IRQSTAT(val) bfin_write16(NFC_IRQSTAT, val)
+#define bfin_read_NFC_IRQMASK() bfin_read16(NFC_IRQMASK)
+#define bfin_write_NFC_IRQMASK(val) bfin_write16(NFC_IRQMASK, val)
+#define bfin_read_NFC_ECC0() bfin_read16(NFC_ECC0)
+#define bfin_write_NFC_ECC0(val) bfin_write16(NFC_ECC0, val)
+#define bfin_read_NFC_ECC1() bfin_read16(NFC_ECC1)
+#define bfin_write_NFC_ECC1(val) bfin_write16(NFC_ECC1, val)
+#define bfin_read_NFC_ECC2() bfin_read16(NFC_ECC2)
+#define bfin_write_NFC_ECC2(val) bfin_write16(NFC_ECC2, val)
+#define bfin_read_NFC_ECC3() bfin_read16(NFC_ECC3)
+#define bfin_write_NFC_ECC3(val) bfin_write16(NFC_ECC3, val)
+#define bfin_read_NFC_COUNT() bfin_read16(NFC_COUNT)
+#define bfin_write_NFC_COUNT(val) bfin_write16(NFC_COUNT, val)
+#define bfin_read_NFC_RST() bfin_read16(NFC_RST)
+#define bfin_write_NFC_RST(val) bfin_write16(NFC_RST, val)
+#define bfin_read_NFC_PGCTL() bfin_read16(NFC_PGCTL)
+#define bfin_write_NFC_PGCTL(val) bfin_write16(NFC_PGCTL, val)
+#define bfin_read_NFC_READ() bfin_read16(NFC_READ)
+#define bfin_write_NFC_READ(val) bfin_write16(NFC_READ, val)
+#define bfin_read_NFC_ADDR() bfin_read16(NFC_ADDR)
+#define bfin_write_NFC_ADDR(val) bfin_write16(NFC_ADDR, val)
+#define bfin_read_NFC_CMD() bfin_read16(NFC_CMD)
+#define bfin_write_NFC_CMD(val) bfin_write16(NFC_CMD, val)
+#define bfin_read_NFC_DATA_WR() bfin_read16(NFC_DATA_WR)
+#define bfin_write_NFC_DATA_WR(val) bfin_write16(NFC_DATA_WR, val)
+#define bfin_read_NFC_DATA_RD() bfin_read16(NFC_DATA_RD)
+#define bfin_write_NFC_DATA_RD(val) bfin_write16(NFC_DATA_RD, val)
#endif /* _CDEF_BF522_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
index d7e2751c6bcc..d90a85b6b6b9 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
@@ -1,15 +1,12 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF525_H
#define _CDEF_BF525_H
-/* include all Core registers and bit definitions */
-#include "defBF525.h"
-
/* BF525 is BF522 + USB */
#include "cdefBF522.h"
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
index c7ba544d50b6..eb22f5866105 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
@@ -1,15 +1,12 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF527_H
#define _CDEF_BF527_H
-/* include all Core registers and bit definitions */
-#include "defBF527.h"
-
/* BF527 is BF525 + EMAC */
#include "cdefBF525.h"
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
deleted file mode 100644
index 3048b52bf46a..000000000000
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright 2007-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#ifndef _CDEF_BF52X_H
-#define _CDEF_BF52X_H
-
-#include <asm/blackfin.h>
-
-#include "defBF52x_base.h"
-
-/* Include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* ==== begin from cdefBF534.h ==== */
-
-/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
-#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
-#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
-#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV, val)
-#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
-#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
-#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT, val)
-#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
-#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT, val)
-#define bfin_read_CHIPID() bfin_read32(CHIPID)
-#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val)
-
-
-/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
-#define bfin_read_SWRST() bfin_read16(SWRST)
-#define bfin_write_SWRST(val) bfin_write16(SWRST, val)
-#define bfin_read_SYSCR() bfin_read16(SYSCR)
-#define bfin_write_SYSCR(val) bfin_write16(SYSCR, val)
-
-#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
-#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
-#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
-#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
-#define bfin_read_SIC_IMASK(x) bfin_read32(SIC_IMASK0 + (x << 6))
-#define bfin_write_SIC_IMASK(x, val) bfin_write32((SIC_IMASK0 + (x << 6)), val)
-
-#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
-#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0, val)
-#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
-#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1, val)
-#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
-#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2, val)
-#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
-#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3, val)
-
-#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
-#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0, val)
-#define bfin_read_SIC_ISR(x) bfin_read32(SIC_ISR0 + (x << 6))
-#define bfin_write_SIC_ISR(x, val) bfin_write32((SIC_ISR0 + (x << 6)), val)
-
-#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
-#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0, val)
-#define bfin_read_SIC_IWR(x) bfin_read32(SIC_IWR0 + (x << 6))
-#define bfin_write_SIC_IWR(x, val) bfin_write32((SIC_IWR0 + (x << 6)), val)
-
-/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
-
-#define bfin_read_SIC_IMASK1() bfin_read32(SIC_IMASK1)
-#define bfin_write_SIC_IMASK1(val) bfin_write32(SIC_IMASK1, val)
-#define bfin_read_SIC_IAR4() bfin_read32(SIC_IAR4)
-#define bfin_write_SIC_IAR4(val) bfin_write32(SIC_IAR4, val)
-#define bfin_read_SIC_IAR5() bfin_read32(SIC_IAR5)
-#define bfin_write_SIC_IAR5(val) bfin_write32(SIC_IAR5, val)
-#define bfin_read_SIC_IAR6() bfin_read32(SIC_IAR6)
-#define bfin_write_SIC_IAR6(val) bfin_write32(SIC_IAR6, val)
-#define bfin_read_SIC_IAR7() bfin_read32(SIC_IAR7)
-#define bfin_write_SIC_IAR7(val) bfin_write32(SIC_IAR7, val)
-#define bfin_read_SIC_ISR1() bfin_read32(SIC_ISR1)
-#define bfin_write_SIC_ISR1(val) bfin_write32(SIC_ISR1, val)
-#define bfin_read_SIC_IWR1() bfin_read32(SIC_IWR1)
-#define bfin_write_SIC_IWR1(val) bfin_write32(SIC_IWR1, val)
-
-/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
-#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
-#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val)
-#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
-#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val)
-#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
-#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val)
-
-
-/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
-#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
-#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT, val)
-#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
-#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL, val)
-#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
-#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT, val)
-#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
-#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT, val)
-#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
-#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM, val)
-#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
-#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST, val)
-#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
-#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN, val)
-
-
-/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
-#define bfin_read_UART0_THR() bfin_read16(UART0_THR)
-#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR, val)
-#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR)
-#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR, val)
-#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL)
-#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL, val)
-#define bfin_read_UART0_IER() bfin_read16(UART0_IER)
-#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER, val)
-#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH)
-#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH, val)
-#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR)
-#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR, val)
-#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR)
-#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR, val)
-#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR)
-#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR, val)
-#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR)
-#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR, val)
-#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR)
-#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR, val)
-#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR)
-#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR, val)
-#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL)
-#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL, val)
-
-
-/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
-#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL)
-#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL, val)
-#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG)
-#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG, val)
-#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT)
-#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT, val)
-#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR)
-#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR, val)
-#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR)
-#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR, val)
-#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD)
-#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD, val)
-#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW)
-#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW, val)
-
-
-/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
-#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
-#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val)
-#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
-#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val)
-#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
-#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val)
-#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
-#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val)
-
-#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
-#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val)
-#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
-#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val)
-#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
-#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val)
-#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
-#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val)
-
-#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
-#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val)
-#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
-#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val)
-#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
-#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val)
-#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
-#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val)
-
-#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
-#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val)
-#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
-#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val)
-#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
-#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val)
-#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
-#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val)
-
-#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
-#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val)
-#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
-#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val)
-#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
-#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val)
-#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
-#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val)
-
-#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
-#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val)
-#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
-#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val)
-#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
-#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val)
-#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
-#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val)
-
-#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
-#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val)
-#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
-#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val)
-#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
-#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val)
-#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
-#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val)
-
-#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
-#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val)
-#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
-#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val)
-#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
-#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val)
-#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
-#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val)
-
-#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
-#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE, val)
-#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
-#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE, val)
-#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS)
-#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS, val)
-
-
-/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
-#define bfin_read_PORTFIO() bfin_read16(PORTFIO)
-#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO, val)
-#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR)
-#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR, val)
-#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET)
-#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET, val)
-#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE)
-#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE, val)
-#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA)
-#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA, val)
-#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR)
-#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR, val)
-#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET)
-#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET, val)
-#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE)
-#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB)
-#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB, val)
-#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR)
-#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR, val)
-#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET)
-#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET, val)
-#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE)
-#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR)
-#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR, val)
-#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR)
-#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR, val)
-#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE)
-#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE, val)
-#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH)
-#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH, val)
-#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN)
-#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN, val)
-
-
-/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
-#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
-#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val)
-#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
-#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val)
-#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
-#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val)
-#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
-#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val)
-#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
-#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
-#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX, val)
-#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
-#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val)
-#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
-#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val)
-#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
-#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val)
-#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
-#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val)
-#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
-#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val)
-#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
-#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val)
-#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
-#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val)
-#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
-#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val)
-#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
-#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val)
-#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
-#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val)
-#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
-#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val)
-#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
-#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val)
-#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
-#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val)
-#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
-#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val)
-#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
-#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val)
-#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
-#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val)
-
-
-/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
-#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
-#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1, val)
-#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
-#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2, val)
-#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
-#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV, val)
-#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
-#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV, val)
-#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
-#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
-#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
-#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
-#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX, val)
-#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
-#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX, val)
-#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
-#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX, val)
-#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
-#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1, val)
-#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
-#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2, val)
-#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
-#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV, val)
-#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
-#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV, val)
-#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
-#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT, val)
-#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
-#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL, val)
-#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
-#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1, val)
-#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
-#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2, val)
-#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
-#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0, val)
-#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
-#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1, val)
-#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
-#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2, val)
-#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
-#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3, val)
-#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
-#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0, val)
-#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
-#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1, val)
-#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
-#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2, val)
-#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
-#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3, val)
-
-
-/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
-#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
-#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL, val)
-#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
-#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0, val)
-#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
-#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1, val)
-#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
-#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL, val)
-#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
-#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL, val)
-#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
-#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC, val)
-#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
-#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT, val)
-
-
-/* DMA Traffic Control Registers */
-#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER)
-#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER, val)
-#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT)
-#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT, val)
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
-#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER, val)
-#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
-#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT, val)
-
-/* DMA Controller */
-#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
-#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG, val)
-#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
-#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val)
-#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
-#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val)
-#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
-#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT, val)
-#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
-#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT, val)
-#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
-#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY, val)
-#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
-#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY, val)
-#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
-#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val)
-#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
-#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val)
-#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
-#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT, val)
-#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
-#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT, val)
-#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
-#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS, val)
-#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
-#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
-#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG, val)
-#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
-#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val)
-#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
-#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val)
-#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
-#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT, val)
-#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
-#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT, val)
-#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
-#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY, val)
-#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
-#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY, val)
-#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
-#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val)
-#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
-#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val)
-#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
-#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT, val)
-#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
-#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT, val)
-#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
-#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS, val)
-#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
-#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
-#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG, val)
-#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
-#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val)
-#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
-#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val)
-#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
-#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT, val)
-#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
-#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT, val)
-#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
-#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY, val)
-#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
-#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY, val)
-#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
-#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val)
-#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
-#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val)
-#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
-#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT, val)
-#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
-#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT, val)
-#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
-#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS, val)
-#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
-#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
-#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG, val)
-#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
-#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val)
-#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
-#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val)
-#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
-#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT, val)
-#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
-#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT, val)
-#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
-#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY, val)
-#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
-#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY, val)
-#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
-#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val)
-#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
-#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val)
-#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
-#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT, val)
-#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
-#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT, val)
-#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
-#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS, val)
-#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
-#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
-#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG, val)
-#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
-#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val)
-#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
-#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val)
-#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
-#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT, val)
-#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
-#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT, val)
-#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
-#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY, val)
-#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
-#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY, val)
-#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
-#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val)
-#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
-#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val)
-#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
-#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT, val)
-#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
-#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT, val)
-#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
-#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS, val)
-#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
-#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
-#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG, val)
-#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
-#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val)
-#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
-#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val)
-#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
-#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT, val)
-#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
-#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT, val)
-#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
-#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY, val)
-#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
-#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY, val)
-#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
-#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val)
-#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
-#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val)
-#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
-#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT, val)
-#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
-#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT, val)
-#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
-#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS, val)
-#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
-#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
-#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG, val)
-#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
-#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val)
-#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
-#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val)
-#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
-#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT, val)
-#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
-#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT, val)
-#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
-#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY, val)
-#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
-#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY, val)
-#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
-#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val)
-#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
-#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val)
-#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
-#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT, val)
-#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
-#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT, val)
-#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
-#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS, val)
-#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
-#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
-#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG, val)
-#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
-#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val)
-#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
-#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val)
-#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
-#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT, val)
-#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
-#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT, val)
-#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
-#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY, val)
-#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
-#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY, val)
-#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
-#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val)
-#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
-#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val)
-#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
-#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT, val)
-#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
-#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT, val)
-#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
-#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS, val)
-#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
-#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG)
-#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG, val)
-#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR)
-#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val)
-#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR)
-#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val)
-#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT)
-#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT, val)
-#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT)
-#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT, val)
-#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY)
-#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY, val)
-#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY)
-#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY, val)
-#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR)
-#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val)
-#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR)
-#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val)
-#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT)
-#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT, val)
-#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT)
-#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT, val)
-#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS)
-#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS, val)
-#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP)
-#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG)
-#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG, val)
-#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR)
-#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val)
-#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR)
-#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val)
-#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT)
-#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT, val)
-#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT)
-#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT, val)
-#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY)
-#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY, val)
-#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY)
-#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY, val)
-#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR)
-#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val)
-#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR)
-#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val)
-#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT)
-#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT, val)
-#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT)
-#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT, val)
-#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS)
-#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS, val)
-#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP)
-#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG)
-#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG, val)
-#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR)
-#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val)
-#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR)
-#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val)
-#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT)
-#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT, val)
-#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT)
-#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT, val)
-#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY)
-#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY, val)
-#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY)
-#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY, val)
-#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR)
-#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val)
-#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR)
-#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val)
-#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT)
-#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT, val)
-#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT)
-#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT, val)
-#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS)
-#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS, val)
-#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP)
-#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP, val)
-
-#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG)
-#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG, val)
-#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR)
-#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val)
-#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR)
-#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val)
-#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT)
-#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT, val)
-#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT)
-#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT, val)
-#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY)
-#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY, val)
-#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY)
-#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY, val)
-#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR)
-#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val)
-#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR)
-#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val)
-#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT)
-#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT, val)
-#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT)
-#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT, val)
-#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS)
-#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS, val)
-#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP)
-#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
-#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG, val)
-#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
-#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR, val)
-#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
-#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT, val)
-#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
-#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT, val)
-#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
-#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY, val)
-#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
-#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY, val)
-#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
-#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR, val)
-#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
-#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT, val)
-#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
-#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS, val)
-#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
-#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG, val)
-#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
-#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR, val)
-#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
-#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT, val)
-#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
-#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT, val)
-#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
-#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY, val)
-#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
-#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY, val)
-#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
-#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR, val)
-#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
-#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT, val)
-#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
-#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS, val)
-#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
-#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG, val)
-#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
-#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR, val)
-#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
-#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT, val)
-#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
-#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT, val)
-#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
-#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY, val)
-#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
-#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY, val)
-#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
-#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR, val)
-#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
-#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT, val)
-#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
-#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS, val)
-#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP, val)
-
-#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
-#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG, val)
-#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
-#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR, val)
-#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
-#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT, val)
-#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
-#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT, val)
-#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
-#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY, val)
-#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
-#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY, val)
-#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
-#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR, val)
-#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
-#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT, val)
-#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
-#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS, val)
-#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP, val)
-
-
-/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
-#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
-#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val)
-#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
-#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val)
-#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF)
-#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
-#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val)
-#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
-#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT, val)
-#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
-#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME, val)
-
-
-/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
-
-/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
-#define bfin_read_PORTGIO() bfin_read16(PORTGIO)
-#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO, val)
-#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR)
-#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR, val)
-#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET)
-#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET, val)
-#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE)
-#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE, val)
-#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA)
-#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA, val)
-#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR)
-#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR, val)
-#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET)
-#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET, val)
-#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE)
-#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB)
-#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB, val)
-#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR)
-#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR, val)
-#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET)
-#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET, val)
-#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE)
-#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR)
-#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR, val)
-#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR)
-#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR, val)
-#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE)
-#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE, val)
-#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH)
-#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH, val)
-#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN)
-#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN, val)
-
-
-/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
-#define bfin_read_PORTHIO() bfin_read16(PORTHIO)
-#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO, val)
-#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR)
-#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR, val)
-#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET)
-#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET, val)
-#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE)
-#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE, val)
-#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA)
-#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA, val)
-#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR)
-#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR, val)
-#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET)
-#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET, val)
-#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE)
-#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE, val)
-#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB)
-#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB, val)
-#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR)
-#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR, val)
-#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET)
-#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET, val)
-#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE)
-#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE, val)
-#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR)
-#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR, val)
-#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR)
-#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR, val)
-#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE)
-#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE, val)
-#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH)
-#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH, val)
-#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN)
-#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN, val)
-
-
-/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
-#define bfin_read_UART1_THR() bfin_read16(UART1_THR)
-#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR, val)
-#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR)
-#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR, val)
-#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL)
-#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL, val)
-#define bfin_read_UART1_IER() bfin_read16(UART1_IER)
-#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER, val)
-#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH)
-#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH, val)
-#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR)
-#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR, val)
-#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR)
-#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR, val)
-#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR)
-#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR, val)
-#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR)
-#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR, val)
-#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR)
-#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR, val)
-#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR)
-#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR, val)
-#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL)
-#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL, val)
-
-/* Omit CAN register sets from the cdefBF534.h (CAN is not in the ADSP-BF52x processor) */
-
-/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
-#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER)
-#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER, val)
-#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER)
-#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER, val)
-#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER)
-#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER, val)
-#define bfin_read_PORT_MUX() bfin_read16(PORT_MUX)
-#define bfin_write_PORT_MUX(val) bfin_write16(PORT_MUX, val)
-
-
-/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
-#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL)
-#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val)
-#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT)
-#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val)
-#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT)
-#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val)
-#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT)
-#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val)
-#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW)
-#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val)
-#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT)
-#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val)
-#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT)
-#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val)
-
-#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL)
-#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val)
-#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT)
-#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val)
-#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT)
-#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val)
-#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT)
-#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val)
-#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW)
-#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val)
-#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT)
-#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val)
-#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
-#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val)
-
-/* ==== end from cdefBF534.h ==== */
-
-/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
-
-#define bfin_read_PORTF_MUX() bfin_read16(PORTF_MUX)
-#define bfin_write_PORTF_MUX(val) bfin_write16(PORTF_MUX, val)
-#define bfin_read_PORTG_MUX() bfin_read16(PORTG_MUX)
-#define bfin_write_PORTG_MUX(val) bfin_write16(PORTG_MUX, val)
-#define bfin_read_PORTH_MUX() bfin_read16(PORTH_MUX)
-#define bfin_write_PORTH_MUX(val) bfin_write16(PORTH_MUX, val)
-
-#define bfin_read_PORTF_DRIVE() bfin_read16(PORTF_DRIVE)
-#define bfin_write_PORTF_DRIVE(val) bfin_write16(PORTF_DRIVE, val)
-#define bfin_read_PORTG_DRIVE() bfin_read16(PORTG_DRIVE)
-#define bfin_write_PORTG_DRIVE(val) bfin_write16(PORTG_DRIVE, val)
-#define bfin_read_PORTH_DRIVE() bfin_read16(PORTH_DRIVE)
-#define bfin_write_PORTH_DRIVE(val) bfin_write16(PORTH_DRIVE, val)
-#define bfin_read_PORTF_SLEW() bfin_read16(PORTF_SLEW)
-#define bfin_write_PORTF_SLEW(val) bfin_write16(PORTF_SLEW, val)
-#define bfin_read_PORTG_SLEW() bfin_read16(PORTG_SLEW)
-#define bfin_write_PORTG_SLEW(val) bfin_write16(PORTG_SLEW, val)
-#define bfin_read_PORTH_SLEW() bfin_read16(PORTH_SLEW)
-#define bfin_write_PORTH_SLEW(val) bfin_write16(PORTH_SLEW, val)
-#define bfin_read_PORTF_HYSTERISIS() bfin_read16(PORTF_HYSTERISIS)
-#define bfin_write_PORTF_HYSTERISIS(val) bfin_write16(PORTF_HYSTERISIS, val)
-#define bfin_read_PORTG_HYSTERISIS() bfin_read16(PORTG_HYSTERISIS)
-#define bfin_write_PORTG_HYSTERISIS(val) bfin_write16(PORTG_HYSTERISIS, val)
-#define bfin_read_PORTH_HYSTERISIS() bfin_read16(PORTH_HYSTERISIS)
-#define bfin_write_PORTH_HYSTERISIS(val) bfin_write16(PORTH_HYSTERISIS, val)
-#define bfin_read_MISCPORT_DRIVE() bfin_read16(MISCPORT_DRIVE)
-#define bfin_write_MISCPORT_DRIVE(val) bfin_write16(MISCPORT_DRIVE, val)
-#define bfin_read_MISCPORT_SLEW() bfin_read16(MISCPORT_SLEW)
-#define bfin_write_MISCPORT_SLEW(val) bfin_write16(MISCPORT_SLEW, val)
-#define bfin_read_MISCPORT_HYSTERISIS() bfin_read16(MISCPORT_HYSTERISIS)
-#define bfin_write_MISCPORT_HYSTERISIS(val) bfin_write16(MISCPORT_HYSTERISIS, val)
-
-/* HOST Port Registers */
-
-#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL)
-#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val)
-#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS)
-#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val)
-#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT)
-#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val)
-
-/* Counter Registers */
-
-#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG)
-#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val)
-#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK)
-#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val)
-#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS)
-#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val)
-#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND)
-#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val)
-#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE)
-#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val)
-#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER)
-#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val)
-#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX)
-#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val)
-#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN)
-#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val)
-
-/* Security Registers */
-
-#define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT)
-#define bfin_write_SECURE_SYSSWT(val) bfin_write32(SECURE_SYSSWT, val)
-#define bfin_read_SECURE_CONTROL() bfin_read16(SECURE_CONTROL)
-#define bfin_write_SECURE_CONTROL(val) bfin_write16(SECURE_CONTROL, val)
-#define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS)
-#define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val)
-
-/* NFC Registers */
-
-#define bfin_read_NFC_CTL() bfin_read16(NFC_CTL)
-#define bfin_write_NFC_CTL(val) bfin_write16(NFC_CTL, val)
-#define bfin_read_NFC_STAT() bfin_read16(NFC_STAT)
-#define bfin_write_NFC_STAT(val) bfin_write16(NFC_STAT, val)
-#define bfin_read_NFC_IRQSTAT() bfin_read16(NFC_IRQSTAT)
-#define bfin_write_NFC_IRQSTAT(val) bfin_write16(NFC_IRQSTAT, val)
-#define bfin_read_NFC_IRQMASK() bfin_read16(NFC_IRQMASK)
-#define bfin_write_NFC_IRQMASK(val) bfin_write16(NFC_IRQMASK, val)
-#define bfin_read_NFC_ECC0() bfin_read16(NFC_ECC0)
-#define bfin_write_NFC_ECC0(val) bfin_write16(NFC_ECC0, val)
-#define bfin_read_NFC_ECC1() bfin_read16(NFC_ECC1)
-#define bfin_write_NFC_ECC1(val) bfin_write16(NFC_ECC1, val)
-#define bfin_read_NFC_ECC2() bfin_read16(NFC_ECC2)
-#define bfin_write_NFC_ECC2(val) bfin_write16(NFC_ECC2, val)
-#define bfin_read_NFC_ECC3() bfin_read16(NFC_ECC3)
-#define bfin_write_NFC_ECC3(val) bfin_write16(NFC_ECC3, val)
-#define bfin_read_NFC_COUNT() bfin_read16(NFC_COUNT)
-#define bfin_write_NFC_COUNT(val) bfin_write16(NFC_COUNT, val)
-#define bfin_read_NFC_RST() bfin_read16(NFC_RST)
-#define bfin_write_NFC_RST(val) bfin_write16(NFC_RST, val)
-#define bfin_read_NFC_PGCTL() bfin_read16(NFC_PGCTL)
-#define bfin_write_NFC_PGCTL(val) bfin_write16(NFC_PGCTL, val)
-#define bfin_read_NFC_READ() bfin_read16(NFC_READ)
-#define bfin_write_NFC_READ(val) bfin_write16(NFC_READ, val)
-#define bfin_read_NFC_ADDR() bfin_read16(NFC_ADDR)
-#define bfin_write_NFC_ADDR(val) bfin_write16(NFC_ADDR, val)
-#define bfin_read_NFC_CMD() bfin_read16(NFC_CMD)
-#define bfin_write_NFC_CMD(val) bfin_write16(NFC_CMD, val)
-#define bfin_read_NFC_DATA_WR() bfin_read16(NFC_DATA_WR)
-#define bfin_write_NFC_DATA_WR(val) bfin_write16(NFC_DATA_WR, val)
-#define bfin_read_NFC_DATA_RD() bfin_read16(NFC_DATA_RD)
-#define bfin_write_NFC_DATA_RD(val) bfin_write16(NFC_DATA_RD, val)
-
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
-#endif /* _CDEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF522.h b/arch/blackfin/mach-bf527/include/mach/defBF522.h
index cb139a254810..89f5420ee6cd 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF522.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,12 +7,1393 @@
#ifndef _DEF_BF522_H
#define _DEF_BF522_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
+/* ************************************************************** */
+/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF52x */
+/* ************************************************************** */
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF522 */
+/* ==== begin from defBF534.h ==== */
-/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "defBF52x_base.h"
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define PLL_CTL 0xFFC00000 /* PLL Control Register */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */
+#define PLL_STAT 0xFFC0000C /* PLL Status Register */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */
+#define CHIPID 0xFFC00014 /* Device ID Register */
+
+
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define SWRST 0xFFC00100 /* Software Reset Register */
+#define SYSCR 0xFFC00104 /* System Configuration Register */
+#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
+
+#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
+#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
+#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
+
+/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
+#define SIC_IMASK1 0xFFC0014C /* Interrupt Mask register of SIC2 */
+#define SIC_IAR4 0xFFC00150 /* Interrupt Assignment register4 */
+#define SIC_IAR5 0xFFC00154 /* Interrupt Assignment register5 */
+#define SIC_IAR6 0xFFC00158 /* Interrupt Assignment register6 */
+#define SIC_IAR7 0xFFC0015C /* Interrupt Assignment register7 */
+#define SIC_ISR1 0xFFC00160 /* Interrupt Statur register */
+#define SIC_IWR1 0xFFC00164 /* Interrupt Wakeup register */
+
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
+#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
+#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
+
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define RTC_STAT 0xFFC00300 /* RTC Status Register */
+#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
+#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
+#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
+#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
+#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
+#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */
+
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART0_THR 0xFFC00400 /* Transmit Holding register */
+#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART0_LCR 0xFFC0040C /* Line Control Register */
+#define UART0_MCR 0xFFC00410 /* Modem Control Register */
+#define UART0_LSR 0xFFC00414 /* Line Status Register */
+#define UART0_MSR 0xFFC00418 /* Modem Status Register */
+#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART0_GCTL 0xFFC00424 /* Global Control Register */
+
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI0_REGBASE 0xFFC00500
+#define SPI_CTL 0xFFC00500 /* SPI Control Register */
+#define SPI_FLG 0xFFC00504 /* SPI Flag register */
+#define SPI_STAT 0xFFC00508 /* SPI Status register */
+#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
+#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
+#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */
+#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
+
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
+
+#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */
+#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */
+#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */
+#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */
+
+#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */
+#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */
+#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */
+#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */
+
+#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */
+#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */
+#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */
+#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */
+
+#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */
+#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */
+#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */
+#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */
+
+#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */
+#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */
+#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */
+#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */
+
+#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */
+#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */
+#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */
+
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */
+#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */
+#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */
+#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */
+#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */
+#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */
+#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */
+#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */
+#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */
+#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */
+#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */
+#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */
+#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */
+#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */
+#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */
+#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */
+#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */
+
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+
+/* DMA Traffic Control Registers */
+#define DMAC_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMAC_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+
+/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
+#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
+#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
+#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
+#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
+#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
+#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
+#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
+#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
+#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
+#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
+#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
+#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
+#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
+
+#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
+#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
+#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
+#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
+#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
+#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
+#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
+#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
+#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
+#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
+#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
+#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
+#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
+
+#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
+#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
+#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
+#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
+#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
+#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
+#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
+#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
+#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
+#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
+#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
+#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
+#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
+
+#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
+#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
+#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
+#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
+#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
+#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
+#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
+#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
+#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
+#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
+#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
+#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
+#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
+
+#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
+#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
+#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
+#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
+#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
+#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
+#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
+#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
+#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
+#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
+#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
+#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
+#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
+
+#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
+#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
+#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
+#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
+#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
+#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
+#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
+#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
+#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
+#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
+#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
+#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
+#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
+
+#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
+#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
+#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
+#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
+#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
+#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
+#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
+#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
+#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
+#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
+#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
+#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
+#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
+
+#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
+#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
+#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
+#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
+#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
+#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
+#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
+#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
+#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
+#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
+#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
+#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
+#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
+
+#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */
+#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */
+#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */
+#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */
+#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */
+#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */
+#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */
+#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */
+#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */
+#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */
+#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */
+#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */
+#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */
+
+#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */
+#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */
+#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */
+#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */
+#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */
+#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */
+#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */
+#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */
+#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */
+#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */
+#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */
+#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */
+#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */
+
+#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */
+#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */
+#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */
+#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */
+#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */
+#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */
+#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */
+#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */
+#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */
+#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */
+#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */
+#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */
+#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */
+
+#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */
+#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */
+#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */
+#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */
+#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */
+#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */
+#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */
+#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */
+#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */
+#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */
+#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */
+#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */
+#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */
+
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */
+#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */
+#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */
+#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */
+#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */
+#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */
+#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */
+
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */
+#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */
+#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */
+#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */
+#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */
+#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */
+#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */
+
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */
+#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */
+#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */
+#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */
+#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */
+#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */
+#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */
+
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */
+#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */
+#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */
+#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */
+#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */
+#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */
+#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */
+
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
+#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
+#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
+#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
+#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
+
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+#define TWI0_REGBASE 0xFFC01400
+#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
+#define TWI0_CONTROL 0xFFC01404 /* TWI Control Register */
+#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
+#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
+#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
+#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
+#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
+#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
+#define TWI0_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */
+#define TWI0_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */
+#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
+#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
+#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
+#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
+#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
+#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
+
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */
+#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */
+#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */
+#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */
+#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */
+#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */
+#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */
+#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */
+#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */
+#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */
+#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */
+#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */
+#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */
+#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */
+#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */
+#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */
+#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */
+
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */
+#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */
+#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */
+#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */
+#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */
+#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */
+#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */
+#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */
+#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */
+#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */
+#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */
+#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */
+#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */
+#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */
+#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */
+#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */
+#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */
+
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define UART1_THR 0xFFC02000 /* Transmit Holding register */
+#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
+#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
+#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
+#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
+#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
+#define UART1_LCR 0xFFC0200C /* Line Control Register */
+#define UART1_MCR 0xFFC02010 /* Modem Control Register */
+#define UART1_LSR 0xFFC02014 /* Line Status Register */
+#define UART1_MSR 0xFFC02018 /* Modem Status Register */
+#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
+#define UART1_GCTL 0xFFC02024 /* Global Control Register */
+
+
+/* Omit CAN register sets from the defBF534.h (CAN is not in the ADSP-BF52x processor) */
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */
+#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */
+#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */
+#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */
+
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */
+#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */
+#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */
+#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */
+#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */
+#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */
+#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */
+
+#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */
+#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */
+#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */
+#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */
+#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */
+#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */
+#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */
+
+/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
+#define PORTF_MUX 0xFFC03210 /* Port F mux control */
+#define PORTG_MUX 0xFFC03214 /* Port G mux control */
+#define PORTH_MUX 0xFFC03218 /* Port H mux control */
+#define PORTF_DRIVE 0xFFC03220 /* Port F drive strength control */
+#define PORTG_DRIVE 0xFFC03224 /* Port G drive strength control */
+#define PORTH_DRIVE 0xFFC03228 /* Port H drive strength control */
+#define PORTF_SLEW 0xFFC03230 /* Port F slew control */
+#define PORTG_SLEW 0xFFC03234 /* Port G slew control */
+#define PORTH_SLEW 0xFFC03238 /* Port H slew control */
+#define PORTF_HYSTERISIS 0xFFC03240 /* Port F Schmitt trigger control */
+#define PORTG_HYSTERISIS 0xFFC03244 /* Port G Schmitt trigger control */
+#define PORTH_HYSTERISIS 0xFFC03248 /* Port H Schmitt trigger control */
+#define MISCPORT_DRIVE 0xFFC03280 /* Misc Port drive strength control */
+#define MISCPORT_SLEW 0xFFC03284 /* Misc Port slew control */
+#define MISCPORT_HYSTERISIS 0xFFC03288 /* Misc Port Schmitt trigger control */
+
+
+/***********************************************************************************
+** System MMR Register Bits And Macros
+**
+** Disclaimer: All macros are intended to make C and Assembly code more readable.
+** Use these macros carefully, as any that do left shifts for field
+** depositing will result in the lower order bits being destroyed. Any
+** macro that shifts left to properly position the bit-field should be
+** used as part of an OR to initialize a register and NOT as a dynamic
+** modifier UNLESS the lower order bits are saved and ORed back in when
+** the macro is used.
+*************************************************************************************/
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* SWRST Masks */
+#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
+#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
+#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
+#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
+#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
+
+/* SYSCR Masks */
+#define BMODE 0x0007 /* Boot Mode - Latched During HW Reset From Mode Pins */
+#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
+
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
+/* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK */
+
+#if 0
+#define IRQ_PLL_WAKEUP 0x00000001 /* PLL Wakeup Interrupt */
+
+#define IRQ_ERROR1 0x00000002 /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
+#define IRQ_ERROR2 0x00000004 /* Error Interrupt (CAN, Ethernet, SPORTx, PPI, SPI, UARTx) */
+#define IRQ_RTC 0x00000008 /* Real Time Clock Interrupt */
+#define IRQ_DMA0 0x00000010 /* DMA Channel 0 (PPI) Interrupt */
+#define IRQ_DMA3 0x00000020 /* DMA Channel 3 (SPORT0 RX) Interrupt */
+#define IRQ_DMA4 0x00000040 /* DMA Channel 4 (SPORT0 TX) Interrupt */
+#define IRQ_DMA5 0x00000080 /* DMA Channel 5 (SPORT1 RX) Interrupt */
+
+#define IRQ_DMA6 0x00000100 /* DMA Channel 6 (SPORT1 TX) Interrupt */
+#define IRQ_TWI 0x00000200 /* TWI Interrupt */
+#define IRQ_DMA7 0x00000400 /* DMA Channel 7 (SPI) Interrupt */
+#define IRQ_DMA8 0x00000800 /* DMA Channel 8 (UART0 RX) Interrupt */
+#define IRQ_DMA9 0x00001000 /* DMA Channel 9 (UART0 TX) Interrupt */
+#define IRQ_DMA10 0x00002000 /* DMA Channel 10 (UART1 RX) Interrupt */
+#define IRQ_DMA11 0x00004000 /* DMA Channel 11 (UART1 TX) Interrupt */
+#define IRQ_CAN_RX 0x00008000 /* CAN Receive Interrupt */
+
+#define IRQ_CAN_TX 0x00010000 /* CAN Transmit Interrupt */
+#define IRQ_DMA1 0x00020000 /* DMA Channel 1 (Ethernet RX) Interrupt */
+#define IRQ_PFA_PORTH 0x00020000 /* PF Port H (PF47:32) Interrupt A */
+#define IRQ_DMA2 0x00040000 /* DMA Channel 2 (Ethernet TX) Interrupt */
+#define IRQ_PFB_PORTH 0x00040000 /* PF Port H (PF47:32) Interrupt B */
+#define IRQ_TIMER0 0x00080000 /* Timer 0 Interrupt */
+#define IRQ_TIMER1 0x00100000 /* Timer 1 Interrupt */
+#define IRQ_TIMER2 0x00200000 /* Timer 2 Interrupt */
+#define IRQ_TIMER3 0x00400000 /* Timer 3 Interrupt */
+#define IRQ_TIMER4 0x00800000 /* Timer 4 Interrupt */
+
+#define IRQ_TIMER5 0x01000000 /* Timer 5 Interrupt */
+#define IRQ_TIMER6 0x02000000 /* Timer 6 Interrupt */
+#define IRQ_TIMER7 0x04000000 /* Timer 7 Interrupt */
+#define IRQ_PFA_PORTFG 0x08000000 /* PF Ports F&G (PF31:0) Interrupt A */
+#define IRQ_PFB_PORTF 0x80000000 /* PF Port F (PF15:0) Interrupt B */
+#define IRQ_DMA12 0x20000000 /* DMA Channels 12 (MDMA1 Source) RX Interrupt */
+#define IRQ_DMA13 0x20000000 /* DMA Channels 13 (MDMA1 Destination) TX Interrupt */
+#define IRQ_DMA14 0x40000000 /* DMA Channels 14 (MDMA0 Source) RX Interrupt */
+#define IRQ_DMA15 0x40000000 /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
+#define IRQ_WDOG 0x80000000 /* Software Watchdog Timer Interrupt */
+#define IRQ_PFB_PORTG 0x10000000 /* PF Port G (PF31:16) Interrupt B */
+#endif
+
+/* SIC_IAR0 Macros */
+#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
+#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
+#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
+#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */
+#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
+#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
+#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
+#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
+
+/* SIC_IAR1 Macros */
+#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */
+#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
+#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
+#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */
+#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
+#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
+#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
+#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
+
+/* SIC_IAR2 Macros */
+#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */
+#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
+#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
+#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */
+#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
+#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
+#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
+#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
+
+/* SIC_IAR3 Macros */
+#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */
+#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */
+#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */
+#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */
+#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */
+#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */
+#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */
+#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */
+
+
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
+
+/* **************** GENERAL PURPOSE TIMER MASKS **********************/
+/* TIMER_ENABLE Masks */
+#define TIMEN0 0x0001 /* Enable Timer 0 */
+#define TIMEN1 0x0002 /* Enable Timer 1 */
+#define TIMEN2 0x0004 /* Enable Timer 2 */
+#define TIMEN3 0x0008 /* Enable Timer 3 */
+#define TIMEN4 0x0010 /* Enable Timer 4 */
+#define TIMEN5 0x0020 /* Enable Timer 5 */
+#define TIMEN6 0x0040 /* Enable Timer 6 */
+#define TIMEN7 0x0080 /* Enable Timer 7 */
+
+/* TIMER_DISABLE Masks */
+#define TIMDIS0 TIMEN0 /* Disable Timer 0 */
+#define TIMDIS1 TIMEN1 /* Disable Timer 1 */
+#define TIMDIS2 TIMEN2 /* Disable Timer 2 */
+#define TIMDIS3 TIMEN3 /* Disable Timer 3 */
+#define TIMDIS4 TIMEN4 /* Disable Timer 4 */
+#define TIMDIS5 TIMEN5 /* Disable Timer 5 */
+#define TIMDIS6 TIMEN6 /* Disable Timer 6 */
+#define TIMDIS7 TIMEN7 /* Disable Timer 7 */
+
+/* TIMER_STATUS Masks */
+#define TIMIL0 0x00000001 /* Timer 0 Interrupt */
+#define TIMIL1 0x00000002 /* Timer 1 Interrupt */
+#define TIMIL2 0x00000004 /* Timer 2 Interrupt */
+#define TIMIL3 0x00000008 /* Timer 3 Interrupt */
+#define TOVF_ERR0 0x00000010 /* Timer 0 Counter Overflow */
+#define TOVF_ERR1 0x00000020 /* Timer 1 Counter Overflow */
+#define TOVF_ERR2 0x00000040 /* Timer 2 Counter Overflow */
+#define TOVF_ERR3 0x00000080 /* Timer 3 Counter Overflow */
+#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */
+#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */
+#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */
+#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */
+#define TIMIL4 0x00010000 /* Timer 4 Interrupt */
+#define TIMIL5 0x00020000 /* Timer 5 Interrupt */
+#define TIMIL6 0x00040000 /* Timer 6 Interrupt */
+#define TIMIL7 0x00080000 /* Timer 7 Interrupt */
+#define TOVF_ERR4 0x00100000 /* Timer 4 Counter Overflow */
+#define TOVF_ERR5 0x00200000 /* Timer 5 Counter Overflow */
+#define TOVF_ERR6 0x00400000 /* Timer 6 Counter Overflow */
+#define TOVF_ERR7 0x00800000 /* Timer 7 Counter Overflow */
+#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */
+#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */
+#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */
+#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */
+
+/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
+#define TOVL_ERR0 TOVF_ERR0
+#define TOVL_ERR1 TOVF_ERR1
+#define TOVL_ERR2 TOVF_ERR2
+#define TOVL_ERR3 TOVF_ERR3
+#define TOVL_ERR4 TOVF_ERR4
+#define TOVL_ERR5 TOVF_ERR5
+#define TOVL_ERR6 TOVF_ERR6
+#define TOVL_ERR7 TOVF_ERR7
+
+/* TIMERx_CONFIG Masks */
+#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */
+#define WDTH_CAP 0x0002 /* Width Capture Input Mode */
+#define EXT_CLK 0x0003 /* External Clock Mode */
+#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */
+#define PERIOD_CNT 0x0008 /* Period Count */
+#define IRQ_ENA 0x0010 /* Interrupt Request Enable */
+#define TIN_SEL 0x0020 /* Timer Input Select */
+#define OUT_DIS 0x0040 /* Output Pad Disable */
+#define CLK_SEL 0x0080 /* Timer Clock Select */
+#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */
+#define EMU_RUN 0x0200 /* Emulation Behavior Select */
+#define ERR_TYP 0xC000 /* Error Type */
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
+/* EBIU_AMGCTL Masks */
+#define AMCKEN 0x0001 /* Enable CLKOUT */
+#define AMBEN_NONE 0x0000 /* All Banks Disabled */
+#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */
+#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */
+
+/* EBIU_AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */
+#define B0RDYPOL 0x00000002 /* B0 RDY Active High */
+#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */
+#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */
+#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */
+#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */
+#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */
+
+#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */
+#define B1RDYPOL 0x00020000 /* B1 RDY Active High */
+#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */
+#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */
+#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */
+#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */
+#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */
+
+/* EBIU_AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */
+#define B2RDYPOL 0x00000002 /* B2 RDY Active High */
+#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */
+#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */
+#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */
+#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */
+#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */
+
+#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */
+#define B3RDYPOL 0x00020000 /* B3 RDY Active High */
+#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */
+#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */
+#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */
+#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */
+#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */
+
+
+/* ********************** SDRAM CONTROLLER MASKS **********************************************/
+/* EBIU_SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SDRAM Signals */
+#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */
+#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
+#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
+#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */
+#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */
+#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */
+#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */
+#define EBUFE 0x02000000 /* Enable External Buffering Timing */
+#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */
+#define EMREN 0x10000000 /* Extended Mode Register Enable */
+#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */
+#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x0001 /* Enable SDRAM External Bank */
+#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */
+#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */
+#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */
+#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */
+#define EBSZ_256 0x0008 /* SDRAM External Bank Size = 256MB */
+#define EBSZ_512 0x000A /* SDRAM External Bank Size = 512MB */
+#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */
+#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */
+#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */
+#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x0001 /* SDRAM Controller Idle */
+#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */
+#define SDPUA 0x0004 /* SDRAM Power-Up Active */
+#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */
+#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */
+#define BGSTAT 0x0020 /* Bus Grant Status */
+
+
+/* ************************** DMA CONTROLLER MASKS ********************************/
+
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */
+#define PMAP 0xF000 /* Peripheral Mapped To This Channel */
+#define PMAP_PPI 0x0000 /* PPI Port DMA */
+#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */
+#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */
+#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */
+#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */
+#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */
+#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */
+#define PMAP_SPI 0x7000 /* SPI Port DMA */
+#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */
+#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */
+#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */
+#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */
+
+/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x0001 /* PPI Port Enable */
+#define PORT_DIR 0x0002 /* PPI Port Direction */
+#define XFR_TYPE 0x000C /* PPI Transfer Type */
+#define PORT_CFG 0x0030 /* PPI Port Configuration */
+#define FLD_SEL 0x0040 /* PPI Active Field Select */
+#define PACK_EN 0x0080 /* PPI Packing Mode */
+#define DMA32 0x0100 /* PPI 32-bit DMA Enable */
+#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
+#define DLEN_8 0x0000 /* Data Length = 8 Bits */
+#define DLEN_10 0x0800 /* Data Length = 10 Bits */
+#define DLEN_11 0x1000 /* Data Length = 11 Bits */
+#define DLEN_12 0x1800 /* Data Length = 12 Bits */
+#define DLEN_13 0x2000 /* Data Length = 13 Bits */
+#define DLEN_14 0x2800 /* Data Length = 14 Bits */
+#define DLEN_15 0x3000 /* Data Length = 15 Bits */
+#define DLEN_16 0x3800 /* Data Length = 16 Bits */
+#define DLENGTH 0x3800 /* PPI Data Length */
+#define POLC 0x4000 /* PPI Clock Polarity */
+#define POLS 0x8000 /* PPI Frame Sync Polarity */
+
+/* PPI_STATUS Masks */
+#define FLD 0x0400 /* Field Indicator */
+#define FT_ERR 0x0800 /* Frame Track Error */
+#define OVR 0x1000 /* FIFO Overflow Error */
+#define UNDR 0x2000 /* FIFO Underrun Error */
+#define ERR_DET 0x4000 /* Error Detected Indicator */
+#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
+
+
+/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/
+/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
+#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
+#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
+
+/* TWI_PRESCALE Masks */
+#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
+#define TWI_ENA 0x0080 /* TWI Enable */
+#define SCCB 0x0200 /* SCCB Compatibility Enable */
+
+/* TWI_SLAVE_CTL Masks */
+#define SEN 0x0001 /* Slave Enable */
+#define SADD_LEN 0x0002 /* Slave Address Length */
+#define STDVAL 0x0004 /* Slave Transmit Data Valid */
+#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
+#define GEN 0x0010 /* General Call Adrress Matching Enabled */
+
+/* TWI_SLAVE_STAT Masks */
+#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
+#define GCALL 0x0002 /* General Call Indicator */
+
+/* TWI_MASTER_CTL Masks */
+#define MEN 0x0001 /* Master Mode Enable */
+#define MADD_LEN 0x0002 /* Master Address Length */
+#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
+#define FAST 0x0008 /* Use Fast Mode Timing Specs */
+#define STOP 0x0010 /* Issue Stop Condition */
+#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
+#define DCNT 0x3FC0 /* Data Bytes To Transfer */
+#define SDAOVR 0x4000 /* Serial Data Override */
+#define SCLOVR 0x8000 /* Serial Clock Override */
+
+/* TWI_MASTER_STAT Masks */
+#define MPROG 0x0001 /* Master Transfer In Progress */
+#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
+#define ANAK 0x0004 /* Address Not Acknowledged */
+#define DNAK 0x0008 /* Data Not Acknowledged */
+#define BUFRDERR 0x0010 /* Buffer Read Error */
+#define BUFWRERR 0x0020 /* Buffer Write Error */
+#define SDASEN 0x0040 /* Serial Data Sense */
+#define SCLSEN 0x0080 /* Serial Clock Sense */
+#define BUSBUSY 0x0100 /* Bus Busy Indicator */
+
+/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
+#define SINIT 0x0001 /* Slave Transfer Initiated */
+#define SCOMP 0x0002 /* Slave Transfer Complete */
+#define SERR 0x0004 /* Slave Transfer Error */
+#define SOVF 0x0008 /* Slave Overflow */
+#define MCOMP 0x0010 /* Master Transfer Complete */
+#define MERR 0x0020 /* Master Transfer Error */
+#define XMTSERV 0x0040 /* Transmit FIFO Service */
+#define RCVSERV 0x0080 /* Receive FIFO Service */
+
+/* TWI_FIFO_CTRL Masks */
+#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
+#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
+#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
+#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
+
+/* TWI_FIFO_STAT Masks */
+#define XMTSTAT 0x0003 /* Transmit FIFO Status */
+#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
+#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
+#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
+
+#define RCVSTAT 0x000C /* Receive FIFO Status */
+#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
+#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
+#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
+
+
+/* Omit CAN masks from defBF534.h */
+
+/* ******************* PIN CONTROL REGISTER MASKS ************************/
+/* PORT_MUX Masks */
+#define PJSE 0x0001 /* Port J SPI/SPORT Enable */
+#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */
+#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */
+
+#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */
+#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */
+#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */
+#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */
+
+#define PFDE 0x0008 /* Port F DMA Request Enable */
+#define PFDE_UART 0x0000 /* Enable UART0 RX/TX */
+#define PFDE_DMA 0x0008 /* Enable DMAR1:0 */
+
+#define PFTE 0x0010 /* Port F Timer Enable */
+#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */
+#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */
+
+#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */
+#define PFS6E_TIMER 0x0000 /* Enable TMR5 */
+#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */
+
+#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */
+#define PFS5E_TIMER 0x0000 /* Enable TMR4 */
+#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */
+
+#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */
+#define PFS4E_TIMER 0x0000 /* Enable TMR3 */
+#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */
+
+#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */
+#define PFFE_TIMER 0x0000 /* Enable TMR2 */
+#define PFFE_PPI 0x0100 /* Enable PPI FS3 */
+
+#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */
+#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */
+#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */
+
+#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */
+#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */
+#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */
+
+#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */
+#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */
+#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */
+
+
+/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/
+/* HDMAx_CTL Masks */
+#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */
+#define REP 0x0002 /* HDMA Request Polarity */
+#define UTE 0x0004 /* Urgency Threshold Enable */
+#define OIE 0x0010 /* Overflow Interrupt Enable */
+#define BDIE 0x0020 /* Block Done Interrupt Enable */
+#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */
+#define DRQ 0x0300 /* HDMA Request Type */
+#define DRQ_NONE 0x0000 /* No Request */
+#define DRQ_SINGLE 0x0100 /* Channels Request Single */
+#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */
+#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */
+#define RBC 0x1000 /* Reload BCNT With IBCNT */
+#define PS 0x2000 /* HDMA Pin Status */
+#define OI 0x4000 /* Overflow Interrupt Generated */
+#define BDI 0x8000 /* Block Done Interrupt Generated */
+
+/* entry addresses of the user-callable Boot ROM functions */
+
+#define _BOOTROM_RESET 0xEF000000
+#define _BOOTROM_FINAL_INIT 0xEF000002
+#define _BOOTROM_DO_MEMORY_DMA 0xEF000006
+#define _BOOTROM_BOOT_DXE_FLASH 0xEF000008
+#define _BOOTROM_BOOT_DXE_SPI 0xEF00000A
+#define _BOOTROM_BOOT_DXE_TWI 0xEF00000C
+#define _BOOTROM_GET_DXE_ADDRESS_FLASH 0xEF000010
+#define _BOOTROM_GET_DXE_ADDRESS_SPI 0xEF000012
+#define _BOOTROM_GET_DXE_ADDRESS_TWI 0xEF000014
+
+/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
+#define PGDE_UART PFDE_UART
+#define PGDE_DMA PFDE_DMA
+#define CKELOW SCKELOW
+
+/* ==== end from defBF534.h ==== */
+
+/* HOST Port Registers */
+
+#define HOST_CONTROL 0xffc03400 /* HOST Control Register */
+#define HOST_STATUS 0xffc03404 /* HOST Status Register */
+#define HOST_TIMEOUT 0xffc03408 /* HOST Acknowledge Mode Timeout Register */
+
+/* Counter Registers */
+
+#define CNT_CONFIG 0xffc03500 /* Configuration Register */
+#define CNT_IMASK 0xffc03504 /* Interrupt Mask Register */
+#define CNT_STATUS 0xffc03508 /* Status Register */
+#define CNT_COMMAND 0xffc0350c /* Command Register */
+#define CNT_DEBOUNCE 0xffc03510 /* Debounce Register */
+#define CNT_COUNTER 0xffc03514 /* Counter Register */
+#define CNT_MAX 0xffc03518 /* Maximal Count Register */
+#define CNT_MIN 0xffc0351c /* Minimal Count Register */
+
+/* OTP/FUSE Registers */
+
+#define OTP_CONTROL 0xffc03600 /* OTP/Fuse Control Register */
+#define OTP_BEN 0xffc03604 /* OTP/Fuse Byte Enable */
+#define OTP_STATUS 0xffc03608 /* OTP/Fuse Status */
+#define OTP_TIMING 0xffc0360c /* OTP/Fuse Access Timing */
+
+/* Security Registers */
+
+#define SECURE_SYSSWT 0xffc03620 /* Secure System Switches */
+#define SECURE_CONTROL 0xffc03624 /* Secure Control */
+#define SECURE_STATUS 0xffc03628 /* Secure Status */
+
+/* OTP Read/Write Data Buffer Registers */
+
+#define OTP_DATA0 0xffc03680 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA1 0xffc03684 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA2 0xffc03688 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+#define OTP_DATA3 0xffc0368c /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
+
+/* NFC Registers */
+
+#define NFC_CTL 0xffc03700 /* NAND Control Register */
+#define NFC_STAT 0xffc03704 /* NAND Status Register */
+#define NFC_IRQSTAT 0xffc03708 /* NAND Interrupt Status Register */
+#define NFC_IRQMASK 0xffc0370c /* NAND Interrupt Mask Register */
+#define NFC_ECC0 0xffc03710 /* NAND ECC Register 0 */
+#define NFC_ECC1 0xffc03714 /* NAND ECC Register 1 */
+#define NFC_ECC2 0xffc03718 /* NAND ECC Register 2 */
+#define NFC_ECC3 0xffc0371c /* NAND ECC Register 3 */
+#define NFC_COUNT 0xffc03720 /* NAND ECC Count Register */
+#define NFC_RST 0xffc03724 /* NAND ECC Reset Register */
+#define NFC_PGCTL 0xffc03728 /* NAND Page Control Register */
+#define NFC_READ 0xffc0372c /* NAND Read Data Register */
+#define NFC_ADDR 0xffc03740 /* NAND Address Register */
+#define NFC_CMD 0xffc03744 /* NAND Command Register */
+#define NFC_DATA_WR 0xffc03748 /* NAND Data Write Register */
+#define NFC_DATA_RD 0xffc0374c /* NAND Data Read Register */
+
+/* ********************************************************** */
+/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
+/* and MULTI BIT READ MACROS */
+/* ********************************************************** */
+
+/* Bit masks for HOST_CONTROL */
+
+#define HOST_CNTR_HOST_EN 0x1 /* Host Enable */
+#define HOST_CNTR_nHOST_EN 0x0
+#define HOST_CNTR_HOST_END 0x2 /* Host Endianess */
+#define HOST_CNTR_nHOST_END 0x0
+#define HOST_CNTR_DATA_SIZE 0x4 /* Data Size */
+#define HOST_CNTR_nDATA_SIZE 0x0
+#define HOST_CNTR_HOST_RST 0x8 /* Host Reset */
+#define HOST_CNTR_nHOST_RST 0x0
+#define HOST_CNTR_HRDY_OVR 0x20 /* Host Ready Override */
+#define HOST_CNTR_nHRDY_OVR 0x0
+#define HOST_CNTR_INT_MODE 0x40 /* Interrupt Mode */
+#define HOST_CNTR_nINT_MODE 0x0
+#define HOST_CNTR_BT_EN 0x80 /* Bus Timeout Enable */
+#define HOST_CNTR_ nBT_EN 0x0
+#define HOST_CNTR_EHW 0x100 /* Enable Host Write */
+#define HOST_CNTR_nEHW 0x0
+#define HOST_CNTR_EHR 0x200 /* Enable Host Read */
+#define HOST_CNTR_nEHR 0x0
+#define HOST_CNTR_BDR 0x400 /* Burst DMA Requests */
+#define HOST_CNTR_nBDR 0x0
+
+/* Bit masks for HOST_STATUS */
+
+#define HOST_STAT_READY 0x1 /* DMA Ready */
+#define HOST_STAT_nREADY 0x0
+#define HOST_STAT_FIFOFULL 0x2 /* FIFO Full */
+#define HOST_STAT_nFIFOFULL 0x0
+#define HOST_STAT_FIFOEMPTY 0x4 /* FIFO Empty */
+#define HOST_STAT_nFIFOEMPTY 0x0
+#define HOST_STAT_COMPLETE 0x8 /* DMA Complete */
+#define HOST_STAT_nCOMPLETE 0x0
+#define HOST_STAT_HSHK 0x10 /* Host Handshake */
+#define HOST_STAT_nHSHK 0x0
+#define HOST_STAT_TIMEOUT 0x20 /* Host Timeout */
+#define HOST_STAT_nTIMEOUT 0x0
+#define HOST_STAT_HIRQ 0x40 /* Host Interrupt Request */
+#define HOST_STAT_nHIRQ 0x0
+#define HOST_STAT_ALLOW_CNFG 0x80 /* Allow New Configuration */
+#define HOST_STAT_nALLOW_CNFG 0x0
+#define HOST_STAT_DMA_DIR 0x100 /* DMA Direction */
+#define HOST_STAT_nDMA_DIR 0x0
+#define HOST_STAT_BTE 0x200 /* Bus Timeout Enabled */
+#define HOST_STAT_nBTE 0x0
+#define HOST_STAT_HOSTRD_DONE 0x8000 /* Host Read Completion Interrupt */
+#define HOST_STAT_nHOSTRD_DONE 0x0
+
+/* Bit masks for HOST_TIMEOUT */
+
+#define HOST_COUNT_TIMEOUT 0x7ff /* Host Timeout count */
+
+/* Bit masks for SECURE_SYSSWT */
+
+#define EMUDABL 0x1 /* Emulation Disable. */
+#define nEMUDABL 0x0
+#define RSTDABL 0x2 /* Reset Disable */
+#define nRSTDABL 0x0
+#define L1IDABL 0x1c /* L1 Instruction Memory Disable. */
+#define L1DADABL 0xe0 /* L1 Data Bank A Memory Disable. */
+#define L1DBDABL 0x700 /* L1 Data Bank B Memory Disable. */
+#define DMA0OVR 0x800 /* DMA0 Memory Access Override */
+#define nDMA0OVR 0x0
+#define DMA1OVR 0x1000 /* DMA1 Memory Access Override */
+#define nDMA1OVR 0x0
+#define EMUOVR 0x4000 /* Emulation Override */
+#define nEMUOVR 0x0
+#define OTPSEN 0x8000 /* OTP Secrets Enable. */
+#define nOTPSEN 0x0
+#define L2DABL 0x70000 /* L2 Memory Disable. */
+
+/* Bit masks for SECURE_CONTROL */
+
+#define SECURE0 0x1 /* SECURE 0 */
+#define nSECURE0 0x0
+#define SECURE1 0x2 /* SECURE 1 */
+#define nSECURE1 0x0
+#define SECURE2 0x4 /* SECURE 2 */
+#define nSECURE2 0x0
+#define SECURE3 0x8 /* SECURE 3 */
+#define nSECURE3 0x0
+
+/* Bit masks for SECURE_STATUS */
+
+#define SECMODE 0x3 /* Secured Mode Control State */
+#define NMI 0x4 /* Non Maskable Interrupt */
+#define nNMI 0x0
+#define AFVALID 0x8 /* Authentication Firmware Valid */
+#define nAFVALID 0x0
+#define AFEXIT 0x10 /* Authentication Firmware Exit */
+#define nAFEXIT 0x0
+#define SECSTAT 0xe0 /* Secure Status */
#endif /* _DEF_BF522_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h
index c136f7032962..cc383adfdffa 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF527.h b/arch/blackfin/mach-bf527/include/mach/defBF527.h
index 4dd58fb33156..05369a92fbc8 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF527.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
deleted file mode 100644
index 09475034c6a1..000000000000
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ /dev/null
@@ -1,1506 +0,0 @@
-/*
- * Copyright 2007-2008 Analog Devices Inc.
- *
- * Licensed under the ADI BSD license or the GPL-2 (or later)
- */
-
-#ifndef _DEF_BF52X_H
-#define _DEF_BF52X_H
-
-
-/* ************************************************************** */
-/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF52x */
-/* ************************************************************** */
-
-/* ==== begin from defBF534.h ==== */
-
-/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
-#define PLL_CTL 0xFFC00000 /* PLL Control Register */
-#define PLL_DIV 0xFFC00004 /* PLL Divide Register */
-#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */
-#define PLL_STAT 0xFFC0000C /* PLL Status Register */
-#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */
-#define CHIPID 0xFFC00014 /* Device ID Register */
-
-
-/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
-#define SWRST 0xFFC00100 /* Software Reset Register */
-#define SYSCR 0xFFC00104 /* System Configuration Register */
-#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
-
-#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
-#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
-#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
-#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
-#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
-#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
-#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
-
-/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
-#define SIC_IMASK1 0xFFC0014C /* Interrupt Mask register of SIC2 */
-#define SIC_IAR4 0xFFC00150 /* Interrupt Assignment register4 */
-#define SIC_IAR5 0xFFC00154 /* Interrupt Assignment register5 */
-#define SIC_IAR6 0xFFC00158 /* Interrupt Assignment register6 */
-#define SIC_IAR7 0xFFC0015C /* Interrupt Assignment register7 */
-#define SIC_ISR1 0xFFC00160 /* Interrupt Statur register */
-#define SIC_IWR1 0xFFC00164 /* Interrupt Wakeup register */
-
-
-/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
-#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
-#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
-#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
-
-
-/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
-#define RTC_STAT 0xFFC00300 /* RTC Status Register */
-#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
-#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
-#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
-#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
-#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
-#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */
-
-
-/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
-#define UART0_THR 0xFFC00400 /* Transmit Holding register */
-#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
-#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
-#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
-#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
-#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
-#define UART0_LCR 0xFFC0040C /* Line Control Register */
-#define UART0_MCR 0xFFC00410 /* Modem Control Register */
-#define UART0_LSR 0xFFC00414 /* Line Status Register */
-#define UART0_MSR 0xFFC00418 /* Modem Status Register */
-#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
-#define UART0_GCTL 0xFFC00424 /* Global Control Register */
-
-
-/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
-#define SPI0_REGBASE 0xFFC00500
-#define SPI_CTL 0xFFC00500 /* SPI Control Register */
-#define SPI_FLG 0xFFC00504 /* SPI Flag register */
-#define SPI_STAT 0xFFC00508 /* SPI Status register */
-#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
-#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
-#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */
-#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
-
-
-/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
-#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
-#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
-#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
-#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
-
-#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
-#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
-#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
-#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
-
-#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
-#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
-#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
-#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
-
-#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */
-#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */
-#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */
-#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */
-
-#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */
-#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */
-#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */
-#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */
-
-#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */
-#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */
-#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */
-#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */
-
-#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */
-#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */
-#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */
-#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */
-
-#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */
-#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */
-#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */
-#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */
-
-#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */
-#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */
-#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */
-
-
-/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
-#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */
-#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */
-#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */
-#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */
-#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */
-#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */
-#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */
-#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */
-#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */
-#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */
-#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */
-#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */
-#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */
-#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */
-#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */
-#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */
-#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */
-
-
-/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
-#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
-#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
-#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
-#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
-#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
-#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
-#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
-#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
-#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
-#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
-#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
-#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
-#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
-#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
-#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
-#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
-#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
-#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
-
-
-/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
-#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
-#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
-#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
-#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
-#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
-#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
-#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
-#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
-#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
-#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
-#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
-#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
-#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
-#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
-#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
-#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
-#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
-#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
-
-
-/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
-#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
-#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
-#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
-#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
-#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
-#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
-#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
-
-
-/* DMA Traffic Control Registers */
-#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
-#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
-#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
-#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
-#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
-#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
-#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
-#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
-#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
-#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
-#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
-#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
-#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
-#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
-
-#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
-#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
-#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
-#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
-#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
-#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
-#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
-#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
-#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
-#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
-#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
-#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
-#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
-
-#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
-#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
-#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
-#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
-#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
-#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
-#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
-#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
-#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
-#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
-#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
-#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
-#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
-
-#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
-#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
-#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
-#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
-#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
-#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
-#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
-#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
-#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
-#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
-#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
-#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
-#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
-
-#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
-#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
-#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
-#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
-#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
-#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
-#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
-#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
-#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
-#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
-#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
-#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
-#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
-
-#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
-#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
-#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
-#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
-#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
-#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
-#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
-#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
-#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
-#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
-#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
-#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
-#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
-
-#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
-#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
-#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
-#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
-#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
-#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
-#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
-#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
-#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
-#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
-#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
-#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
-#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
-
-#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
-#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
-#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
-#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
-#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
-#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
-#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
-#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
-#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
-#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
-#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
-#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
-#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
-
-#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */
-#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */
-#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */
-#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */
-#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */
-#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */
-#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */
-#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */
-#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */
-#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */
-#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */
-#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */
-#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */
-
-#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */
-#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */
-#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */
-#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */
-#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */
-#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */
-#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */
-#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */
-#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */
-#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */
-#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */
-#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */
-#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */
-
-#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */
-#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */
-#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */
-#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */
-#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */
-#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */
-#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */
-#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */
-#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */
-#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */
-#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */
-#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */
-#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */
-
-#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */
-#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */
-#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */
-#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */
-#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */
-#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */
-#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */
-#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */
-#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */
-#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */
-#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */
-#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */
-#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */
-
-#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
-#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */
-#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */
-#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */
-#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */
-#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */
-#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */
-#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
-#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */
-#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
-#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */
-#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */
-#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */
-
-#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
-#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */
-#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */
-#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */
-#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */
-#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */
-#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */
-#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
-#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */
-#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */
-#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */
-#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */
-#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */
-
-#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
-#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */
-#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */
-#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */
-#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */
-#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */
-#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */
-#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
-#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */
-#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
-#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */
-#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */
-#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */
-
-#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
-#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */
-#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */
-#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */
-#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */
-#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */
-#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */
-#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
-#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */
-#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
-#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */
-#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */
-#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */
-
-
-/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
-#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
-#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
-#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
-#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
-#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
-
-
-/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
-#define TWI0_REGBASE 0xFFC01400
-#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
-#define TWI0_CONTROL 0xFFC01404 /* TWI Control Register */
-#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
-#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
-#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
-#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
-#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
-#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
-#define TWI0_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */
-#define TWI0_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */
-#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
-#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
-#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
-#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
-#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
-#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
-
-
-/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
-#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */
-#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */
-#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */
-#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */
-#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */
-#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */
-#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */
-#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */
-#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */
-#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */
-#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */
-#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */
-#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */
-#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */
-#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */
-#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */
-#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */
-
-
-/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
-#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */
-#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */
-#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */
-#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */
-#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */
-#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */
-#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */
-#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */
-#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */
-#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */
-#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */
-#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */
-#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */
-#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */
-#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */
-#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */
-#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */
-
-
-/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
-#define UART1_THR 0xFFC02000 /* Transmit Holding register */
-#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
-#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
-#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
-#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
-#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
-#define UART1_LCR 0xFFC0200C /* Line Control Register */
-#define UART1_MCR 0xFFC02010 /* Modem Control Register */
-#define UART1_LSR 0xFFC02014 /* Line Status Register */
-#define UART1_MSR 0xFFC02018 /* Modem Status Register */
-#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
-#define UART1_GCTL 0xFFC02024 /* Global Control Register */
-
-
-/* Omit CAN register sets from the defBF534.h (CAN is not in the ADSP-BF52x processor) */
-
-/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
-#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */
-#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */
-#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */
-#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */
-
-
-/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
-#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */
-#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */
-#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */
-#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */
-#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */
-#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */
-#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */
-
-#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */
-#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */
-#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */
-#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */
-#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */
-#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */
-#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */
-
-/* GPIO PIN mux (0xFFC03210 - OxFFC03288) */
-#define PORTF_MUX 0xFFC03210 /* Port F mux control */
-#define PORTG_MUX 0xFFC03214 /* Port G mux control */
-#define PORTH_MUX 0xFFC03218 /* Port H mux control */
-#define PORTF_DRIVE 0xFFC03220 /* Port F drive strength control */
-#define PORTG_DRIVE 0xFFC03224 /* Port G drive strength control */
-#define PORTH_DRIVE 0xFFC03228 /* Port H drive strength control */
-#define PORTF_SLEW 0xFFC03230 /* Port F slew control */
-#define PORTG_SLEW 0xFFC03234 /* Port G slew control */
-#define PORTH_SLEW 0xFFC03238 /* Port H slew control */
-#define PORTF_HYSTERISIS 0xFFC03240 /* Port F Schmitt trigger control */
-#define PORTG_HYSTERISIS 0xFFC03244 /* Port G Schmitt trigger control */
-#define PORTH_HYSTERISIS 0xFFC03248 /* Port H Schmitt trigger control */
-#define MISCPORT_DRIVE 0xFFC03280 /* Misc Port drive strength control */
-#define MISCPORT_SLEW 0xFFC03284 /* Misc Port slew control */
-#define MISCPORT_HYSTERISIS 0xFFC03288 /* Misc Port Schmitt trigger control */
-
-
-/***********************************************************************************
-** System MMR Register Bits And Macros
-**
-** Disclaimer: All macros are intended to make C and Assembly code more readable.
-** Use these macros carefully, as any that do left shifts for field
-** depositing will result in the lower order bits being destroyed. Any
-** macro that shifts left to properly position the bit-field should be
-** used as part of an OR to initialize a register and NOT as a dynamic
-** modifier UNLESS the lower order bits are saved and ORed back in when
-** the macro is used.
-*************************************************************************************/
-
-/* CHIPID Masks */
-#define CHIPID_VERSION 0xF0000000
-#define CHIPID_FAMILY 0x0FFFF000
-#define CHIPID_MANUFACTURE 0x00000FFE
-
-/* SWRST Masks */
-#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
-#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
-#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
-#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
-#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
-
-/* SYSCR Masks */
-#define BMODE 0x0007 /* Boot Mode - Latched During HW Reset From Mode Pins */
-#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
-
-
-/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
-/* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK */
-
-#if 0
-#define IRQ_PLL_WAKEUP 0x00000001 /* PLL Wakeup Interrupt */
-
-#define IRQ_ERROR1 0x00000002 /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
-#define IRQ_ERROR2 0x00000004 /* Error Interrupt (CAN, Ethernet, SPORTx, PPI, SPI, UARTx) */
-#define IRQ_RTC 0x00000008 /* Real Time Clock Interrupt */
-#define IRQ_DMA0 0x00000010 /* DMA Channel 0 (PPI) Interrupt */
-#define IRQ_DMA3 0x00000020 /* DMA Channel 3 (SPORT0 RX) Interrupt */
-#define IRQ_DMA4 0x00000040 /* DMA Channel 4 (SPORT0 TX) Interrupt */
-#define IRQ_DMA5 0x00000080 /* DMA Channel 5 (SPORT1 RX) Interrupt */
-
-#define IRQ_DMA6 0x00000100 /* DMA Channel 6 (SPORT1 TX) Interrupt */
-#define IRQ_TWI 0x00000200 /* TWI Interrupt */
-#define IRQ_DMA7 0x00000400 /* DMA Channel 7 (SPI) Interrupt */
-#define IRQ_DMA8 0x00000800 /* DMA Channel 8 (UART0 RX) Interrupt */
-#define IRQ_DMA9 0x00001000 /* DMA Channel 9 (UART0 TX) Interrupt */
-#define IRQ_DMA10 0x00002000 /* DMA Channel 10 (UART1 RX) Interrupt */
-#define IRQ_DMA11 0x00004000 /* DMA Channel 11 (UART1 TX) Interrupt */
-#define IRQ_CAN_RX 0x00008000 /* CAN Receive Interrupt */
-
-#define IRQ_CAN_TX 0x00010000 /* CAN Transmit Interrupt */
-#define IRQ_DMA1 0x00020000 /* DMA Channel 1 (Ethernet RX) Interrupt */
-#define IRQ_PFA_PORTH 0x00020000 /* PF Port H (PF47:32) Interrupt A */
-#define IRQ_DMA2 0x00040000 /* DMA Channel 2 (Ethernet TX) Interrupt */
-#define IRQ_PFB_PORTH 0x00040000 /* PF Port H (PF47:32) Interrupt B */
-#define IRQ_TIMER0 0x00080000 /* Timer 0 Interrupt */
-#define IRQ_TIMER1 0x00100000 /* Timer 1 Interrupt */
-#define IRQ_TIMER2 0x00200000 /* Timer 2 Interrupt */
-#define IRQ_TIMER3 0x00400000 /* Timer 3 Interrupt */
-#define IRQ_TIMER4 0x00800000 /* Timer 4 Interrupt */
-
-#define IRQ_TIMER5 0x01000000 /* Timer 5 Interrupt */
-#define IRQ_TIMER6 0x02000000 /* Timer 6 Interrupt */
-#define IRQ_TIMER7 0x04000000 /* Timer 7 Interrupt */
-#define IRQ_PFA_PORTFG 0x08000000 /* PF Ports F&G (PF31:0) Interrupt A */
-#define IRQ_PFB_PORTF 0x80000000 /* PF Port F (PF15:0) Interrupt B */
-#define IRQ_DMA12 0x20000000 /* DMA Channels 12 (MDMA1 Source) RX Interrupt */
-#define IRQ_DMA13 0x20000000 /* DMA Channels 13 (MDMA1 Destination) TX Interrupt */
-#define IRQ_DMA14 0x40000000 /* DMA Channels 14 (MDMA0 Source) RX Interrupt */
-#define IRQ_DMA15 0x40000000 /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
-#define IRQ_WDOG 0x80000000 /* Software Watchdog Timer Interrupt */
-#define IRQ_PFB_PORTG 0x10000000 /* PF Port G (PF31:16) Interrupt B */
-#endif
-
-/* SIC_IAR0 Macros */
-#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
-#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
-#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
-#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */
-#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
-#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
-#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
-#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
-
-/* SIC_IAR1 Macros */
-#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */
-#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
-#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
-#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */
-#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
-#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
-#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
-#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
-
-/* SIC_IAR2 Macros */
-#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */
-#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
-#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
-#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */
-#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
-#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
-#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
-#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
-
-/* SIC_IAR3 Macros */
-#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */
-#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */
-#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */
-#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */
-#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */
-#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */
-#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */
-#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */
-
-
-/* SIC_IMASK Masks */
-#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
-#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
-#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
-#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
-
-/* SIC_IWR Masks */
-#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
-#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
-#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
-#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
-
-
-/* ************** UART CONTROLLER MASKS *************************/
-/* UARTx_LCR Masks */
-#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
-#define STB 0x04 /* Stop Bits */
-#define PEN 0x08 /* Parity Enable */
-#define EPS 0x10 /* Even Parity Select */
-#define STP 0x20 /* Stick Parity */
-#define SB 0x40 /* Set Break */
-#define DLAB 0x80 /* Divisor Latch Access */
-
-/* UARTx_MCR Mask */
-#define LOOP_ENA 0x10 /* Loopback Mode Enable */
-#define LOOP_ENA_P 0x04
-
-/* UARTx_LSR Masks */
-#define DR 0x01 /* Data Ready */
-#define OE 0x02 /* Overrun Error */
-#define PE 0x04 /* Parity Error */
-#define FE 0x08 /* Framing Error */
-#define BI 0x10 /* Break Interrupt */
-#define THRE 0x20 /* THR Empty */
-#define TEMT 0x40 /* TSR and UART_THR Empty */
-
-/* UARTx_IER Masks */
-#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
-#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
-#define ELSI 0x04 /* Enable RX Status Interrupt */
-
-/* UARTx_IIR Masks */
-#define NINT 0x01 /* Pending Interrupt */
-#define IIR_TX_READY 0x02 /* UART_THR empty */
-#define IIR_RX_READY 0x04 /* Receive data ready */
-#define IIR_LINE_CHANGE 0x06 /* Receive line status */
-#define IIR_STATUS 0x06 /* Highest Priority Pending Interrupt */
-
-/* UARTx_GCTL Masks */
-#define UCEN 0x01 /* Enable UARTx Clocks */
-#define IREN 0x02 /* Enable IrDA Mode */
-#define TPOLC 0x04 /* IrDA TX Polarity Change */
-#define RPOLC 0x08 /* IrDA RX Polarity Change */
-#define FPE 0x10 /* Force Parity Error On Transmit */
-#define FFE 0x20 /* Force Framing Error On Transmit */
-
-
-/* **************** GENERAL PURPOSE TIMER MASKS **********************/
-/* TIMER_ENABLE Masks */
-#define TIMEN0 0x0001 /* Enable Timer 0 */
-#define TIMEN1 0x0002 /* Enable Timer 1 */
-#define TIMEN2 0x0004 /* Enable Timer 2 */
-#define TIMEN3 0x0008 /* Enable Timer 3 */
-#define TIMEN4 0x0010 /* Enable Timer 4 */
-#define TIMEN5 0x0020 /* Enable Timer 5 */
-#define TIMEN6 0x0040 /* Enable Timer 6 */
-#define TIMEN7 0x0080 /* Enable Timer 7 */
-
-/* TIMER_DISABLE Masks */
-#define TIMDIS0 TIMEN0 /* Disable Timer 0 */
-#define TIMDIS1 TIMEN1 /* Disable Timer 1 */
-#define TIMDIS2 TIMEN2 /* Disable Timer 2 */
-#define TIMDIS3 TIMEN3 /* Disable Timer 3 */
-#define TIMDIS4 TIMEN4 /* Disable Timer 4 */
-#define TIMDIS5 TIMEN5 /* Disable Timer 5 */
-#define TIMDIS6 TIMEN6 /* Disable Timer 6 */
-#define TIMDIS7 TIMEN7 /* Disable Timer 7 */
-
-/* TIMER_STATUS Masks */
-#define TIMIL0 0x00000001 /* Timer 0 Interrupt */
-#define TIMIL1 0x00000002 /* Timer 1 Interrupt */
-#define TIMIL2 0x00000004 /* Timer 2 Interrupt */
-#define TIMIL3 0x00000008 /* Timer 3 Interrupt */
-#define TOVF_ERR0 0x00000010 /* Timer 0 Counter Overflow */
-#define TOVF_ERR1 0x00000020 /* Timer 1 Counter Overflow */
-#define TOVF_ERR2 0x00000040 /* Timer 2 Counter Overflow */
-#define TOVF_ERR3 0x00000080 /* Timer 3 Counter Overflow */
-#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */
-#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */
-#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */
-#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */
-#define TIMIL4 0x00010000 /* Timer 4 Interrupt */
-#define TIMIL5 0x00020000 /* Timer 5 Interrupt */
-#define TIMIL6 0x00040000 /* Timer 6 Interrupt */
-#define TIMIL7 0x00080000 /* Timer 7 Interrupt */
-#define TOVF_ERR4 0x00100000 /* Timer 4 Counter Overflow */
-#define TOVF_ERR5 0x00200000 /* Timer 5 Counter Overflow */
-#define TOVF_ERR6 0x00400000 /* Timer 6 Counter Overflow */
-#define TOVF_ERR7 0x00800000 /* Timer 7 Counter Overflow */
-#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */
-#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */
-#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */
-#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */
-
-/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
-#define TOVL_ERR0 TOVF_ERR0
-#define TOVL_ERR1 TOVF_ERR1
-#define TOVL_ERR2 TOVF_ERR2
-#define TOVL_ERR3 TOVF_ERR3
-#define TOVL_ERR4 TOVF_ERR4
-#define TOVL_ERR5 TOVF_ERR5
-#define TOVL_ERR6 TOVF_ERR6
-#define TOVL_ERR7 TOVF_ERR7
-
-/* TIMERx_CONFIG Masks */
-#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */
-#define WDTH_CAP 0x0002 /* Width Capture Input Mode */
-#define EXT_CLK 0x0003 /* External Clock Mode */
-#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */
-#define PERIOD_CNT 0x0008 /* Period Count */
-#define IRQ_ENA 0x0010 /* Interrupt Request Enable */
-#define TIN_SEL 0x0020 /* Timer Input Select */
-#define OUT_DIS 0x0040 /* Output Pad Disable */
-#define CLK_SEL 0x0080 /* Timer Clock Select */
-#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */
-#define EMU_RUN 0x0200 /* Emulation Behavior Select */
-#define ERR_TYP 0xC000 /* Error Type */
-
-
-/* ****************** GPIO PORTS F, G, H MASKS ***********************/
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
-/* Port F Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* Port G Masks */
-#define PG0 0x0001
-#define PG1 0x0002
-#define PG2 0x0004
-#define PG3 0x0008
-#define PG4 0x0010
-#define PG5 0x0020
-#define PG6 0x0040
-#define PG7 0x0080
-#define PG8 0x0100
-#define PG9 0x0200
-#define PG10 0x0400
-#define PG11 0x0800
-#define PG12 0x1000
-#define PG13 0x2000
-#define PG14 0x4000
-#define PG15 0x8000
-
-/* Port H Masks */
-#define PH0 0x0001
-#define PH1 0x0002
-#define PH2 0x0004
-#define PH3 0x0008
-#define PH4 0x0010
-#define PH5 0x0020
-#define PH6 0x0040
-#define PH7 0x0080
-#define PH8 0x0100
-#define PH9 0x0200
-#define PH10 0x0400
-#define PH11 0x0800
-#define PH12 0x1000
-#define PH13 0x2000
-#define PH14 0x4000
-#define PH15 0x8000
-
-/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
-/* EBIU_AMGCTL Masks */
-#define AMCKEN 0x0001 /* Enable CLKOUT */
-#define AMBEN_NONE 0x0000 /* All Banks Disabled */
-#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */
-#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */
-#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */
-#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */
-
-/* EBIU_AMBCTL0 Masks */
-#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */
-#define B0RDYPOL 0x00000002 /* B0 RDY Active High */
-#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */
-#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */
-#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */
-#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */
-#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */
-#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */
-#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */
-#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */
-#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */
-#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */
-#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */
-#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */
-#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */
-#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */
-#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */
-#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */
-#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */
-#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */
-#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */
-#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */
-#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */
-#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */
-#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */
-#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */
-#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */
-#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */
-#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */
-#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */
-#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */
-#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */
-#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */
-#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */
-#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */
-#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */
-
-#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */
-#define B1RDYPOL 0x00020000 /* B1 RDY Active High */
-#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */
-#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */
-#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */
-#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */
-#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */
-#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */
-#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */
-#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */
-#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */
-#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */
-#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */
-#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */
-#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */
-#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */
-#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */
-#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */
-#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */
-#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */
-#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */
-#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */
-#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */
-#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */
-#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */
-#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */
-#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */
-#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */
-#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */
-#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */
-#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */
-#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */
-#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */
-#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */
-#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */
-#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */
-
-/* EBIU_AMBCTL1 Masks */
-#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */
-#define B2RDYPOL 0x00000002 /* B2 RDY Active High */
-#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */
-#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */
-#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */
-#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */
-#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */
-#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */
-#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */
-#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */
-#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */
-#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */
-#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */
-#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */
-#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */
-#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */
-#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */
-#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */
-#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */
-#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */
-#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */
-#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */
-#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */
-#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */
-#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */
-#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */
-#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */
-#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */
-#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */
-#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */
-#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */
-#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */
-#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */
-#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */
-#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */
-#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */
-
-#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */
-#define B3RDYPOL 0x00020000 /* B3 RDY Active High */
-#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */
-#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */
-#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */
-#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */
-#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */
-#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */
-#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */
-#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */
-#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */
-#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */
-#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */
-#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */
-#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */
-#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */
-#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */
-#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */
-#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */
-#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */
-#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */
-#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */
-#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */
-#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */
-#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */
-#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */
-#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */
-#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */
-#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */
-#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */
-#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */
-#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */
-#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */
-#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */
-#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */
-#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */
-#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */
-#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */
-#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */
-#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */
-#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */
-#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */
-#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */
-#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */
-
-
-/* ********************** SDRAM CONTROLLER MASKS **********************************************/
-/* EBIU_SDGCTL Masks */
-#define SCTLE 0x00000001 /* Enable SDRAM Signals */
-#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */
-#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */
-#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
-#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
-#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
-#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
-#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
-#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
-#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
-#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
-#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
-#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
-#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
-#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
-#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
-#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
-#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
-#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
-#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
-#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
-#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
-#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
-#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
-#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
-#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
-#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
-#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
-#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
-#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
-#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
-#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
-#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
-#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
-#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
-#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
-#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
-#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
-#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */
-#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */
-#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */
-#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */
-#define EBUFE 0x02000000 /* Enable External Buffering Timing */
-#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */
-#define EMREN 0x10000000 /* Extended Mode Register Enable */
-#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */
-#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */
-
-/* EBIU_SDBCTL Masks */
-#define EBE 0x0001 /* Enable SDRAM External Bank */
-#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */
-#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */
-#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */
-#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */
-#define EBSZ_256 0x0008 /* SDRAM External Bank Size = 256MB */
-#define EBSZ_512 0x000A /* SDRAM External Bank Size = 512MB */
-#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */
-#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */
-#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */
-#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */
-
-/* EBIU_SDSTAT Masks */
-#define SDCI 0x0001 /* SDRAM Controller Idle */
-#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */
-#define SDPUA 0x0004 /* SDRAM Power-Up Active */
-#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */
-#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */
-#define BGSTAT 0x0020 /* Bus Grant Status */
-
-
-/* ************************** DMA CONTROLLER MASKS ********************************/
-
-/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
-#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */
-#define PMAP 0xF000 /* Peripheral Mapped To This Channel */
-#define PMAP_PPI 0x0000 /* PPI Port DMA */
-#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */
-#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */
-#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */
-#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */
-#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */
-#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */
-#define PMAP_SPI 0x7000 /* SPI Port DMA */
-#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */
-#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */
-#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */
-#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */
-
-/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
-/* PPI_CONTROL Masks */
-#define PORT_EN 0x0001 /* PPI Port Enable */
-#define PORT_DIR 0x0002 /* PPI Port Direction */
-#define XFR_TYPE 0x000C /* PPI Transfer Type */
-#define PORT_CFG 0x0030 /* PPI Port Configuration */
-#define FLD_SEL 0x0040 /* PPI Active Field Select */
-#define PACK_EN 0x0080 /* PPI Packing Mode */
-#define DMA32 0x0100 /* PPI 32-bit DMA Enable */
-#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
-#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
-#define DLEN_8 0x0000 /* Data Length = 8 Bits */
-#define DLEN_10 0x0800 /* Data Length = 10 Bits */
-#define DLEN_11 0x1000 /* Data Length = 11 Bits */
-#define DLEN_12 0x1800 /* Data Length = 12 Bits */
-#define DLEN_13 0x2000 /* Data Length = 13 Bits */
-#define DLEN_14 0x2800 /* Data Length = 14 Bits */
-#define DLEN_15 0x3000 /* Data Length = 15 Bits */
-#define DLEN_16 0x3800 /* Data Length = 16 Bits */
-#define DLENGTH 0x3800 /* PPI Data Length */
-#define POLC 0x4000 /* PPI Clock Polarity */
-#define POLS 0x8000 /* PPI Frame Sync Polarity */
-
-/* PPI_STATUS Masks */
-#define FLD 0x0400 /* Field Indicator */
-#define FT_ERR 0x0800 /* Frame Track Error */
-#define OVR 0x1000 /* FIFO Overflow Error */
-#define UNDR 0x2000 /* FIFO Underrun Error */
-#define ERR_DET 0x4000 /* Error Detected Indicator */
-#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
-
-
-/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/
-/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
-#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
-#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
-
-/* TWI_PRESCALE Masks */
-#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
-#define TWI_ENA 0x0080 /* TWI Enable */
-#define SCCB 0x0200 /* SCCB Compatibility Enable */
-
-/* TWI_SLAVE_CTL Masks */
-#define SEN 0x0001 /* Slave Enable */
-#define SADD_LEN 0x0002 /* Slave Address Length */
-#define STDVAL 0x0004 /* Slave Transmit Data Valid */
-#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
-#define GEN 0x0010 /* General Call Adrress Matching Enabled */
-
-/* TWI_SLAVE_STAT Masks */
-#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
-#define GCALL 0x0002 /* General Call Indicator */
-
-/* TWI_MASTER_CTL Masks */
-#define MEN 0x0001 /* Master Mode Enable */
-#define MADD_LEN 0x0002 /* Master Address Length */
-#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
-#define FAST 0x0008 /* Use Fast Mode Timing Specs */
-#define STOP 0x0010 /* Issue Stop Condition */
-#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
-#define DCNT 0x3FC0 /* Data Bytes To Transfer */
-#define SDAOVR 0x4000 /* Serial Data Override */
-#define SCLOVR 0x8000 /* Serial Clock Override */
-
-/* TWI_MASTER_STAT Masks */
-#define MPROG 0x0001 /* Master Transfer In Progress */
-#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
-#define ANAK 0x0004 /* Address Not Acknowledged */
-#define DNAK 0x0008 /* Data Not Acknowledged */
-#define BUFRDERR 0x0010 /* Buffer Read Error */
-#define BUFWRERR 0x0020 /* Buffer Write Error */
-#define SDASEN 0x0040 /* Serial Data Sense */
-#define SCLSEN 0x0080 /* Serial Clock Sense */
-#define BUSBUSY 0x0100 /* Bus Busy Indicator */
-
-/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
-#define SINIT 0x0001 /* Slave Transfer Initiated */
-#define SCOMP 0x0002 /* Slave Transfer Complete */
-#define SERR 0x0004 /* Slave Transfer Error */
-#define SOVF 0x0008 /* Slave Overflow */
-#define MCOMP 0x0010 /* Master Transfer Complete */
-#define MERR 0x0020 /* Master Transfer Error */
-#define XMTSERV 0x0040 /* Transmit FIFO Service */
-#define RCVSERV 0x0080 /* Receive FIFO Service */
-
-/* TWI_FIFO_CTRL Masks */
-#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
-#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
-#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
-#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
-
-/* TWI_FIFO_STAT Masks */
-#define XMTSTAT 0x0003 /* Transmit FIFO Status */
-#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
-#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
-#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
-
-#define RCVSTAT 0x000C /* Receive FIFO Status */
-#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
-#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
-#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
-
-
-/* Omit CAN masks from defBF534.h */
-
-/* ******************* PIN CONTROL REGISTER MASKS ************************/
-/* PORT_MUX Masks */
-#define PJSE 0x0001 /* Port J SPI/SPORT Enable */
-#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */
-#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */
-
-#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */
-#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */
-#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */
-#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */
-
-#define PFDE 0x0008 /* Port F DMA Request Enable */
-#define PFDE_UART 0x0000 /* Enable UART0 RX/TX */
-#define PFDE_DMA 0x0008 /* Enable DMAR1:0 */
-
-#define PFTE 0x0010 /* Port F Timer Enable */
-#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */
-#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */
-
-#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */
-#define PFS6E_TIMER 0x0000 /* Enable TMR5 */
-#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */
-
-#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */
-#define PFS5E_TIMER 0x0000 /* Enable TMR4 */
-#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */
-
-#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */
-#define PFS4E_TIMER 0x0000 /* Enable TMR3 */
-#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */
-
-#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */
-#define PFFE_TIMER 0x0000 /* Enable TMR2 */
-#define PFFE_PPI 0x0100 /* Enable PPI FS3 */
-
-#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */
-#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */
-#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */
-
-#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */
-#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */
-#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */
-
-#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */
-#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */
-#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */
-
-
-/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/
-/* HDMAx_CTL Masks */
-#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */
-#define REP 0x0002 /* HDMA Request Polarity */
-#define UTE 0x0004 /* Urgency Threshold Enable */
-#define OIE 0x0010 /* Overflow Interrupt Enable */
-#define BDIE 0x0020 /* Block Done Interrupt Enable */
-#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */
-#define DRQ 0x0300 /* HDMA Request Type */
-#define DRQ_NONE 0x0000 /* No Request */
-#define DRQ_SINGLE 0x0100 /* Channels Request Single */
-#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */
-#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */
-#define RBC 0x1000 /* Reload BCNT With IBCNT */
-#define PS 0x2000 /* HDMA Pin Status */
-#define OI 0x4000 /* Overflow Interrupt Generated */
-#define BDI 0x8000 /* Block Done Interrupt Generated */
-
-/* entry addresses of the user-callable Boot ROM functions */
-
-#define _BOOTROM_RESET 0xEF000000
-#define _BOOTROM_FINAL_INIT 0xEF000002
-#define _BOOTROM_DO_MEMORY_DMA 0xEF000006
-#define _BOOTROM_BOOT_DXE_FLASH 0xEF000008
-#define _BOOTROM_BOOT_DXE_SPI 0xEF00000A
-#define _BOOTROM_BOOT_DXE_TWI 0xEF00000C
-#define _BOOTROM_GET_DXE_ADDRESS_FLASH 0xEF000010
-#define _BOOTROM_GET_DXE_ADDRESS_SPI 0xEF000012
-#define _BOOTROM_GET_DXE_ADDRESS_TWI 0xEF000014
-
-/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
-#define PGDE_UART PFDE_UART
-#define PGDE_DMA PFDE_DMA
-#define CKELOW SCKELOW
-
-/* ==== end from defBF534.h ==== */
-
-/* HOST Port Registers */
-
-#define HOST_CONTROL 0xffc03400 /* HOST Control Register */
-#define HOST_STATUS 0xffc03404 /* HOST Status Register */
-#define HOST_TIMEOUT 0xffc03408 /* HOST Acknowledge Mode Timeout Register */
-
-/* Counter Registers */
-
-#define CNT_CONFIG 0xffc03500 /* Configuration Register */
-#define CNT_IMASK 0xffc03504 /* Interrupt Mask Register */
-#define CNT_STATUS 0xffc03508 /* Status Register */
-#define CNT_COMMAND 0xffc0350c /* Command Register */
-#define CNT_DEBOUNCE 0xffc03510 /* Debounce Register */
-#define CNT_COUNTER 0xffc03514 /* Counter Register */
-#define CNT_MAX 0xffc03518 /* Maximal Count Register */
-#define CNT_MIN 0xffc0351c /* Minimal Count Register */
-
-/* OTP/FUSE Registers */
-
-#define OTP_CONTROL 0xffc03600 /* OTP/Fuse Control Register */
-#define OTP_BEN 0xffc03604 /* OTP/Fuse Byte Enable */
-#define OTP_STATUS 0xffc03608 /* OTP/Fuse Status */
-#define OTP_TIMING 0xffc0360c /* OTP/Fuse Access Timing */
-
-/* Security Registers */
-
-#define SECURE_SYSSWT 0xffc03620 /* Secure System Switches */
-#define SECURE_CONTROL 0xffc03624 /* Secure Control */
-#define SECURE_STATUS 0xffc03628 /* Secure Status */
-
-/* OTP Read/Write Data Buffer Registers */
-
-#define OTP_DATA0 0xffc03680 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA1 0xffc03684 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA2 0xffc03688 /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-#define OTP_DATA3 0xffc0368c /* OTP/Fuse Data (OTP_DATA0-3) accesses the fuse read write buffer */
-
-/* NFC Registers */
-
-#define NFC_CTL 0xffc03700 /* NAND Control Register */
-#define NFC_STAT 0xffc03704 /* NAND Status Register */
-#define NFC_IRQSTAT 0xffc03708 /* NAND Interrupt Status Register */
-#define NFC_IRQMASK 0xffc0370c /* NAND Interrupt Mask Register */
-#define NFC_ECC0 0xffc03710 /* NAND ECC Register 0 */
-#define NFC_ECC1 0xffc03714 /* NAND ECC Register 1 */
-#define NFC_ECC2 0xffc03718 /* NAND ECC Register 2 */
-#define NFC_ECC3 0xffc0371c /* NAND ECC Register 3 */
-#define NFC_COUNT 0xffc03720 /* NAND ECC Count Register */
-#define NFC_RST 0xffc03724 /* NAND ECC Reset Register */
-#define NFC_PGCTL 0xffc03728 /* NAND Page Control Register */
-#define NFC_READ 0xffc0372c /* NAND Read Data Register */
-#define NFC_ADDR 0xffc03740 /* NAND Address Register */
-#define NFC_CMD 0xffc03744 /* NAND Command Register */
-#define NFC_DATA_WR 0xffc03748 /* NAND Data Write Register */
-#define NFC_DATA_RD 0xffc0374c /* NAND Data Read Register */
-
-/* ********************************************************** */
-/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
-/* and MULTI BIT READ MACROS */
-/* ********************************************************** */
-
-/* Bit masks for HOST_CONTROL */
-
-#define HOST_CNTR_HOST_EN 0x1 /* Host Enable */
-#define HOST_CNTR_nHOST_EN 0x0
-#define HOST_CNTR_HOST_END 0x2 /* Host Endianess */
-#define HOST_CNTR_nHOST_END 0x0
-#define HOST_CNTR_DATA_SIZE 0x4 /* Data Size */
-#define HOST_CNTR_nDATA_SIZE 0x0
-#define HOST_CNTR_HOST_RST 0x8 /* Host Reset */
-#define HOST_CNTR_nHOST_RST 0x0
-#define HOST_CNTR_HRDY_OVR 0x20 /* Host Ready Override */
-#define HOST_CNTR_nHRDY_OVR 0x0
-#define HOST_CNTR_INT_MODE 0x40 /* Interrupt Mode */
-#define HOST_CNTR_nINT_MODE 0x0
-#define HOST_CNTR_BT_EN 0x80 /* Bus Timeout Enable */
-#define HOST_CNTR_ nBT_EN 0x0
-#define HOST_CNTR_EHW 0x100 /* Enable Host Write */
-#define HOST_CNTR_nEHW 0x0
-#define HOST_CNTR_EHR 0x200 /* Enable Host Read */
-#define HOST_CNTR_nEHR 0x0
-#define HOST_CNTR_BDR 0x400 /* Burst DMA Requests */
-#define HOST_CNTR_nBDR 0x0
-
-/* Bit masks for HOST_STATUS */
-
-#define HOST_STAT_READY 0x1 /* DMA Ready */
-#define HOST_STAT_nREADY 0x0
-#define HOST_STAT_FIFOFULL 0x2 /* FIFO Full */
-#define HOST_STAT_nFIFOFULL 0x0
-#define HOST_STAT_FIFOEMPTY 0x4 /* FIFO Empty */
-#define HOST_STAT_nFIFOEMPTY 0x0
-#define HOST_STAT_COMPLETE 0x8 /* DMA Complete */
-#define HOST_STAT_nCOMPLETE 0x0
-#define HOST_STAT_HSHK 0x10 /* Host Handshake */
-#define HOST_STAT_nHSHK 0x0
-#define HOST_STAT_TIMEOUT 0x20 /* Host Timeout */
-#define HOST_STAT_nTIMEOUT 0x0
-#define HOST_STAT_HIRQ 0x40 /* Host Interrupt Request */
-#define HOST_STAT_nHIRQ 0x0
-#define HOST_STAT_ALLOW_CNFG 0x80 /* Allow New Configuration */
-#define HOST_STAT_nALLOW_CNFG 0x0
-#define HOST_STAT_DMA_DIR 0x100 /* DMA Direction */
-#define HOST_STAT_nDMA_DIR 0x0
-#define HOST_STAT_BTE 0x200 /* Bus Timeout Enabled */
-#define HOST_STAT_nBTE 0x0
-#define HOST_STAT_HOSTRD_DONE 0x8000 /* Host Read Completion Interrupt */
-#define HOST_STAT_nHOSTRD_DONE 0x0
-
-/* Bit masks for HOST_TIMEOUT */
-
-#define HOST_COUNT_TIMEOUT 0x7ff /* Host Timeout count */
-
-/* Bit masks for SECURE_SYSSWT */
-
-#define EMUDABL 0x1 /* Emulation Disable. */
-#define nEMUDABL 0x0
-#define RSTDABL 0x2 /* Reset Disable */
-#define nRSTDABL 0x0
-#define L1IDABL 0x1c /* L1 Instruction Memory Disable. */
-#define L1DADABL 0xe0 /* L1 Data Bank A Memory Disable. */
-#define L1DBDABL 0x700 /* L1 Data Bank B Memory Disable. */
-#define DMA0OVR 0x800 /* DMA0 Memory Access Override */
-#define nDMA0OVR 0x0
-#define DMA1OVR 0x1000 /* DMA1 Memory Access Override */
-#define nDMA1OVR 0x0
-#define EMUOVR 0x4000 /* Emulation Override */
-#define nEMUOVR 0x0
-#define OTPSEN 0x8000 /* OTP Secrets Enable. */
-#define nOTPSEN 0x0
-#define L2DABL 0x70000 /* L2 Memory Disable. */
-
-/* Bit masks for SECURE_CONTROL */
-
-#define SECURE0 0x1 /* SECURE 0 */
-#define nSECURE0 0x0
-#define SECURE1 0x2 /* SECURE 1 */
-#define nSECURE1 0x0
-#define SECURE2 0x4 /* SECURE 2 */
-#define nSECURE2 0x0
-#define SECURE3 0x8 /* SECURE 3 */
-#define nSECURE3 0x0
-
-/* Bit masks for SECURE_STATUS */
-
-#define SECMODE 0x3 /* Secured Mode Control State */
-#define NMI 0x4 /* Non Maskable Interrupt */
-#define nNMI 0x0
-#define AFVALID 0x8 /* Authentication Firmware Valid */
-#define nAFVALID 0x0
-#define AFEXIT 0x10 /* Authentication Firmware Exit */
-#define nAFEXIT 0x0
-#define SECSTAT 0xe0 /* Secure Status */
-
-#endif /* _DEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/gpio.h b/arch/blackfin/mach-bf527/include/mach/gpio.h
index f80c2995efdb..fba606b699c3 100644
--- a/arch/blackfin/mach-bf527/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf527/include/mach/gpio.h
@@ -62,4 +62,8 @@
#define PORT_G GPIO_PG0
#define PORT_H GPIO_PH0
+#include <mach-common/ports-f.h>
+#include <mach-common/ports-g.h>
+#include <mach-common/ports-h.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 20c102285bef..992f551f06a1 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -25,7 +25,6 @@
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
-#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -476,10 +475,16 @@ static int __init blackstamp_init(void)
return ret;
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
- /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
- bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF0);
- bfin_write_FIO_FLAG_S(PF0);
- SSYNC();
+ /*
+ * setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC.
+ * the bfin-async-map driver takes care of flipping between
+ * flash and ethernet when necessary.
+ */
+ ret = gpio_request(GPIO_PF0, "enet_cpld");
+ if (!ret) {
+ gpio_direction_output(GPIO_PF0, 1);
+ gpio_free(GPIO_PF0);
+ }
#endif
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index 5ba4b02a12eb..631f0516e465 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -22,7 +22,6 @@
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
-#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -295,15 +294,7 @@ static int __init ip0x_init(void)
printk(KERN_INFO "%s(): registering device resources\n", __func__);
platform_add_devices(ip0x_devices, ARRAY_SIZE(ip0x_devices));
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
- for (i = 0; i < ARRAY_SIZE(bfin_spi_board_info); ++i) {
- int j = 1 << bfin_spi_board_info[i].chip_select;
- /* set spi cs to 1 */
- bfin_write_FIO_DIR(bfin_read_FIO_DIR() | j);
- bfin_write_FIO_FLAG_S(j);
- }
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
-#endif
return 0;
}
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index b3b1cdea2703..4b73d4295f82 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -24,7 +24,6 @@
#include <asm/reboot.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
-#include <mach/fio_flag.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -674,10 +673,16 @@ static int __init stamp_init(void)
return ret;
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
- /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
- bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF0);
- bfin_write_FIO_FLAG_S(PF0);
- SSYNC();
+ /*
+ * setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC.
+ * the bfin-async-map driver takes care of flipping between
+ * flash and ethernet when necessary.
+ */
+ ret = gpio_request(GPIO_PF0, "enet_cpld");
+ if (!ret) {
+ gpio_direction_output(GPIO_PF0, 1);
+ gpio_free(GPIO_PF0);
+ }
#endif
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
@@ -713,7 +718,6 @@ void __init native_machine_early_platform_add_devices(void)
void native_machine_restart(char *cmd)
{
/* workaround pull up on cpld / flash pin not being strong enough */
- bfin_write_FIO_INEN(~PF0);
- bfin_write_FIO_DIR(PF0);
- bfin_write_FIO_FLAG_C(PF0);
+ gpio_request(GPIO_PF0, "flash_cpld");
+ gpio_direction_output(GPIO_PF0, 0);
}
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
index 4a14a46a9a68..1f5988d43139 100644
--- a/arch/blackfin/mach-bf533/dma.c
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..08072c86d5dc
--- /dev/null
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 1
+
+#endif
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 9e1f3defb6bc..45dcaa4f3e41 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
-#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
-#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
-#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
-#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
-#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#ifdef CONFIG_BFIN_UART0_CTSRTS
# define CONFIG_SERIAL_BFIN_CTSRTS
# ifndef CONFIG_UART0_CTS_PIN
@@ -44,51 +17,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#else
-# if ANOMALY_05000363
- unsigned int anomaly_threshold;
-# endif
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -120,3 +48,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf533/include/mach/blackfin.h b/arch/blackfin/mach-bf533/include/mach/blackfin.h
index f4bd6df5d968..e366207fbf12 100644
--- a/arch/blackfin/mach-bf533/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf533/include/mach/blackfin.h
@@ -1,7 +1,7 @@
/*
- * Copyright 2005-2009 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
@@ -10,26 +10,14 @@
#define BF533_FAMILY
#include "bf533.h"
-#include "defBF532.h"
#include "anomaly.h"
-#if !defined(__ASSEMBLY__)
-#include "cdefBF532.h"
-#endif
-
-#define BFIN_UART_NR_PORTS 1
+#include <asm/def_LPBlackfin.h>
+#include "defBF532.h"
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
+#ifndef __ASSEMBLY__
+# include <asm/cdef_LPBlackfin.h>
+# include "cdefBF532.h"
+#endif
-#endif /* _MACH_BLACKFIN_H_ */
+#endif
diff --git a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
index 401e524f5321..fd0cbe4df21a 100644
--- a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
@@ -7,9 +7,6 @@
#ifndef _CDEF_BF532_H
#define _CDEF_BF532_H
-/*include core specific register pointer definitions*/
-#include <asm/cdef_LPBlackfin.h>
-
/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */
#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
@@ -66,16 +63,10 @@
#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN,val)
/* DMA Traffic controls */
-#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
-#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val)
-#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
-#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val)
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER)
-#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER,val)
-#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT)
-#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT,val)
+#define bfin_read_DMAC_TC_PER() bfin_read16(DMAC_TC_PER)
+#define bfin_write_DMAC_TC_PER(val) bfin_write16(DMAC_TC_PER,val)
+#define bfin_read_DMAC_TC_CNT() bfin_read16(DMAC_TC_CNT)
+#define bfin_write_DMAC_TC_CNT(val) bfin_write16(DMAC_TC_CNT,val)
/* General Purpose IO (0xFFC0 2400-0xFFC0 27FF) */
#define bfin_read_FIO_DIR() bfin_read16(FIO_DIR)
@@ -105,6 +96,47 @@
#define bfin_read_FIO_MASKB_T() bfin_read16(FIO_MASKB_T)
#define bfin_write_FIO_MASKB_T(val) bfin_write16(FIO_MASKB_T,val)
+#if ANOMALY_05000311
+/* Keep at the CPP expansion to avoid circular header dependency loops */
+#define BFIN_WRITE_FIO_FLAG(name, val) \
+ do { \
+ unsigned long __flags; \
+ __flags = hard_local_irq_save(); \
+ bfin_write16(FIO_FLAG_##name, val); \
+ bfin_read_CHIPID(); \
+ hard_local_irq_restore(__flags); \
+ } while (0)
+#define bfin_write_FIO_FLAG_D(val) BFIN_WRITE_FIO_FLAG(D, val)
+#define bfin_write_FIO_FLAG_C(val) BFIN_WRITE_FIO_FLAG(C, val)
+#define bfin_write_FIO_FLAG_S(val) BFIN_WRITE_FIO_FLAG(S, val)
+#define bfin_write_FIO_FLAG_T(val) BFIN_WRITE_FIO_FLAG(T, val)
+
+#define BFIN_READ_FIO_FLAG(name) \
+ ({ \
+ unsigned long __flags; \
+ u16 __ret; \
+ __flags = hard_local_irq_save(); \
+ __ret = bfin_read16(FIO_FLAG_##name); \
+ bfin_read_CHIPID(); \
+ hard_local_irq_restore(__flags); \
+ __ret; \
+ })
+#define bfin_read_FIO_FLAG_D() BFIN_READ_FIO_FLAG(D)
+#define bfin_read_FIO_FLAG_C() BFIN_READ_FIO_FLAG(C)
+#define bfin_read_FIO_FLAG_S() BFIN_READ_FIO_FLAG(S)
+#define bfin_read_FIO_FLAG_T() BFIN_READ_FIO_FLAG(T)
+
+#else
+#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D, val)
+#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C, val)
+#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S, val)
+#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T, val)
+#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D)
+#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C)
+#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S)
+#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T)
+#endif
+
/* DMA Controller */
#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG,val)
@@ -647,7 +679,4 @@
#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME,val)
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
#endif /* _CDEF_BF532_H */
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h
index 3adb0b44e597..2376d5393511 100644
--- a/arch/blackfin/mach-bf533/include/mach/defBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h
@@ -1,7 +1,7 @@
/*
* System & MMR bit and Address definitions for ADSP-BF532
*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -9,9 +9,6 @@
#ifndef _DEF_BF532_H
#define _DEF_BF532_H
-/* include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
/*********************************************************************************** */
/* System MMR Register Map */
/*********************************************************************************** */
@@ -182,12 +179,8 @@
#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
/* DMA Traffic controls */
-#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+#define DMAC_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMAC_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
@@ -432,83 +425,6 @@
#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */
#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */
-/* ***************************** UART CONTROLLER MASKS ********************** */
-
-/* UART_LCR Register */
-
-#define DLAB 0x80
-#define SB 0x40
-#define STP 0x20
-#define EPS 0x10
-#define PEN 0x08
-#define STB 0x04
-#define WLS(x) ((x-5) & 0x03)
-
-#define DLAB_P 0x07
-#define SB_P 0x06
-#define STP_P 0x05
-#define EPS_P 0x04
-#define PEN_P 0x03
-#define STB_P 0x02
-#define WLS_P1 0x01
-#define WLS_P0 0x00
-
-/* UART_MCR Register */
-#define LOOP_ENA 0x10
-#define LOOP_ENA_P 0x04
-
-/* UART_LSR Register */
-#define TEMT 0x40
-#define THRE 0x20
-#define BI 0x10
-#define FE 0x08
-#define PE 0x04
-#define OE 0x02
-#define DR 0x01
-
-#define TEMP_P 0x06
-#define THRE_P 0x05
-#define BI_P 0x04
-#define FE_P 0x03
-#define PE_P 0x02
-#define OE_P 0x01
-#define DR_P 0x00
-
-/* UART_IER Register */
-#define ELSI 0x04
-#define ETBEI 0x02
-#define ERBFI 0x01
-
-#define ELSI_P 0x02
-#define ETBEI_P 0x01
-#define ERBFI_P 0x00
-
-/* UART_IIR Register */
-#define STATUS(x) ((x << 1) & 0x06)
-#define NINT 0x01
-#define STATUS_P1 0x02
-#define STATUS_P0 0x01
-#define NINT_P 0x00
-#define IIR_TX_READY 0x02 /* UART_THR empty */
-#define IIR_RX_READY 0x04 /* Receive data ready */
-#define IIR_LINE_CHANGE 0x06 /* Receive line status */
-#define IIR_STATUS 0x06
-
-/* UART_GCTL Register */
-#define FFE 0x20
-#define FPE 0x10
-#define RPOLC 0x08
-#define TPOLC 0x04
-#define IREN 0x02
-#define UCEN 0x01
-
-#define FFE_P 0x05
-#define FPE_P 0x04
-#define RPOLC_P 0x03
-#define TPOLC_P 0x02
-#define IREN_P 0x01
-#define UCEN_P 0x00
-
/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
/* PPI_CONTROL Masks */
@@ -643,44 +559,6 @@
#define ERR_TYP_P0 0x0E
#define ERR_TYP_P1 0x0F
-/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */
-
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */
-#define PF0_P 0
-#define PF1_P 1
-#define PF2_P 2
-#define PF3_P 3
-#define PF4_P 4
-#define PF5_P 5
-#define PF6_P 6
-#define PF7_P 7
-#define PF8_P 8
-#define PF9_P 9
-#define PF10_P 10
-#define PF11_P 11
-#define PF12_P 12
-#define PF13_P 13
-#define PF14_P 14
-#define PF15_P 15
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
/* AMGCTL Masks */
diff --git a/arch/blackfin/mach-bf533/include/mach/fio_flag.h b/arch/blackfin/mach-bf533/include/mach/fio_flag.h
deleted file mode 100644
index d0bfba0b083b..000000000000
--- a/arch/blackfin/mach-bf533/include/mach/fio_flag.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2005-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#ifndef _MACH_FIO_FLAG_H
-#define _MACH_FIO_FLAG_H
-
-#include <asm/blackfin.h>
-#include <asm/irqflags.h>
-
-#if ANOMALY_05000311
-#define BFIN_WRITE_FIO_FLAG(name) \
-static inline void bfin_write_FIO_FLAG_##name(unsigned short val) \
-{ \
- unsigned long flags; \
- flags = hard_local_irq_save(); \
- bfin_write16(FIO_FLAG_##name, val); \
- bfin_read_CHIPID(); \
- hard_local_irq_restore(flags); \
-}
-BFIN_WRITE_FIO_FLAG(D)
-BFIN_WRITE_FIO_FLAG(C)
-BFIN_WRITE_FIO_FLAG(S)
-BFIN_WRITE_FIO_FLAG(T)
-
-#define BFIN_READ_FIO_FLAG(name) \
-static inline u16 bfin_read_FIO_FLAG_##name(void) \
-{ \
- unsigned long flags; \
- u16 ret; \
- flags = hard_local_irq_save(); \
- ret = bfin_read16(FIO_FLAG_##name); \
- bfin_read_CHIPID(); \
- hard_local_irq_restore(flags); \
- return ret; \
-}
-BFIN_READ_FIO_FLAG(D)
-BFIN_READ_FIO_FLAG(C)
-BFIN_READ_FIO_FLAG(S)
-BFIN_READ_FIO_FLAG(T)
-
-#else
-#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D, val)
-#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C, val)
-#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S, val)
-#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T, val)
-#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T)
-#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C)
-#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S)
-#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D)
-#endif
-
-#endif /* _MACH_FIO_FLAG_H */
diff --git a/arch/blackfin/mach-bf533/include/mach/gpio.h b/arch/blackfin/mach-bf533/include/mach/gpio.h
index e02416db4b00..cce4f8fb3785 100644
--- a/arch/blackfin/mach-bf533/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf533/include/mach/gpio.h
@@ -28,4 +28,6 @@
#define PORT_F GPIO_PF0
+#include <mach-common/ports-f.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
index 5c8c4ed517bb..5c62e99c9fac 100644
--- a/arch/blackfin/mach-bf537/dma.c
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..00c603fe8218
--- /dev/null
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 2
+
+#endif
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index 635c91c526a3..3e955dba8951 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
-#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
-#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
-#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
-#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
-#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
# define CONFIG_SERIAL_BFIN_CTSRTS
@@ -54,49 +27,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-/*
- * The pin configuration is different from schematic
- */
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -145,3 +75,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h
index a12d4b6a221d..baa096fc724a 100644
--- a/arch/blackfin/mach-bf537/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h
@@ -1,7 +1,7 @@
/*
- * Copyright 2005-2009 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
- * Licensed under the GPL-2 or later
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
@@ -10,34 +10,24 @@
#define BF537_FAMILY
#include "bf537.h"
-#include "defBF534.h"
#include "anomaly.h"
+#include <asm/def_LPBlackfin.h>
+#ifdef CONFIG_BF534
+# include "defBF534.h"
+#endif
#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
-#include "defBF537.h"
+# include "defBF537.h"
#endif
#if !defined(__ASSEMBLY__)
-#include "cdefBF534.h"
-
-#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
-#include "cdefBF537.h"
+# include <asm/cdef_LPBlackfin.h>
+# ifdef CONFIG_BF534
+# include "cdefBF534.h"
+# endif
+# if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+# include "cdefBF537.h"
+# endif
#endif
-#endif
-
-#define BFIN_UART_NR_PORTS 2
-
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
#endif
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
index fbeb35e14135..563ede907336 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF534_H
#define _CDEF_BF534_H
-#include <asm/blackfin.h>
-
-/* Include all Core registers and bit definitions */
-#include "defBF534.h"
-
-/* Include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
@@ -355,16 +347,10 @@
#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val)
/* DMA Traffic Control Registers */
-#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER)
-#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER,val)
-#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT)
-#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT,val)
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
-#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val)
-#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
-#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val)
+#define bfin_read_DMAC_TC_PER() bfin_read16(DMAC_TC_PER)
+#define bfin_write_DMAC_TC_PER(val) bfin_write16(DMAC_TC_PER,val)
+#define bfin_read_DMAC_TC_CNT() bfin_read16(DMAC_TC_CNT)
+#define bfin_write_DMAC_TC_CNT(val) bfin_write16(DMAC_TC_CNT,val)
/* DMA Controller */
#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
@@ -1747,7 +1733,4 @@
#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT,val)
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
#endif /* _CDEF_BF534_H */
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
index 9363c3990421..19ec21ea150a 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
@@ -10,9 +10,6 @@
/* Include MMRs Common to BF534 */
#include "cdefBF534.h"
-/* Include all Core registers and bit definitions */
-#include "defBF537.h"
-
/* Include Macro "Defines" For EMAC (Unique to BF536/BF537 */
/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */
#define bfin_read_EMAC_OPMODE() bfin_read32(EMAC_OPMODE)
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h
index 0323e6bacdae..32529a03b266 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,9 +7,6 @@
#ifndef _DEF_BF534_H
#define _DEF_BF534_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
/************************************************************************************
** System MMR Register Map
*************************************************************************************/
@@ -193,12 +190,8 @@
#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
/* DMA Traffic Control Registers */
-#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
-#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+#define DMAC_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMAC_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
@@ -1029,48 +1022,6 @@
#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
-/* ************** UART CONTROLLER MASKS *************************/
-/* UARTx_LCR Masks */
-#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
-#define STB 0x04 /* Stop Bits */
-#define PEN 0x08 /* Parity Enable */
-#define EPS 0x10 /* Even Parity Select */
-#define STP 0x20 /* Stick Parity */
-#define SB 0x40 /* Set Break */
-#define DLAB 0x80 /* Divisor Latch Access */
-
-/* UARTx_MCR Mask */
-#define LOOP_ENA 0x10 /* Loopback Mode Enable */
-#define LOOP_ENA_P 0x04
-/* UARTx_LSR Masks */
-#define DR 0x01 /* Data Ready */
-#define OE 0x02 /* Overrun Error */
-#define PE 0x04 /* Parity Error */
-#define FE 0x08 /* Framing Error */
-#define BI 0x10 /* Break Interrupt */
-#define THRE 0x20 /* THR Empty */
-#define TEMT 0x40 /* TSR and UART_THR Empty */
-
-/* UARTx_IER Masks */
-#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
-#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
-#define ELSI 0x04 /* Enable RX Status Interrupt */
-
-/* UARTx_IIR Masks */
-#define NINT 0x01 /* Pending Interrupt */
-#define IIR_TX_READY 0x02 /* UART_THR empty */
-#define IIR_RX_READY 0x04 /* Receive data ready */
-#define IIR_LINE_CHANGE 0x06 /* Receive line status */
-#define IIR_STATUS 0x06
-
-/* UARTx_GCTL Masks */
-#define UCEN 0x01 /* Enable UARTx Clocks */
-#define IREN 0x02 /* Enable IrDA Mode */
-#define TPOLC 0x04 /* IrDA TX Polarity Change */
-#define RPOLC 0x08 /* IrDA RX Polarity Change */
-#define FPE 0x10 /* Force Parity Error On Transmit */
-#define FFE 0x20 /* Force Framing Error On Transmit */
-
/* **************** GENERAL PURPOSE TIMER MASKS **********************/
/* TIMER_ENABLE Masks */
#define TIMEN0 0x0001 /* Enable Timer 0 */
@@ -1141,62 +1092,6 @@
#define EMU_RUN 0x0200 /* Emulation Behavior Select */
#define ERR_TYP 0xC000 /* Error Type */
-/* ****************** GPIO PORTS F, G, H MASKS ***********************/
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
-/* Port F Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* Port G Masks */
-#define PG0 0x0001
-#define PG1 0x0002
-#define PG2 0x0004
-#define PG3 0x0008
-#define PG4 0x0010
-#define PG5 0x0020
-#define PG6 0x0040
-#define PG7 0x0080
-#define PG8 0x0100
-#define PG9 0x0200
-#define PG10 0x0400
-#define PG11 0x0800
-#define PG12 0x1000
-#define PG13 0x2000
-#define PG14 0x4000
-#define PG15 0x8000
-
-/* Port H Masks */
-#define PH0 0x0001
-#define PH1 0x0002
-#define PH2 0x0004
-#define PH3 0x0008
-#define PH4 0x0010
-#define PH5 0x0020
-#define PH6 0x0040
-#define PH7 0x0080
-#define PH8 0x0100
-#define PH9 0x0200
-#define PH10 0x0400
-#define PH11 0x0800
-#define PH12 0x1000
-#define PH13 0x2000
-#define PH14 0x4000
-#define PH15 0x8000
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
/* EBIU_AMGCTL Masks */
#define AMCKEN 0x0001 /* Enable CLKOUT */
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF537.h b/arch/blackfin/mach-bf537/include/mach/defBF537.h
index 8cb5d5cf0c94..3d471d752684 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF537.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,9 +7,6 @@
#ifndef _DEF_BF537_H
#define _DEF_BF537_H
-/* Include all Core registers and bit definitions*/
-#include <asm/cdef_LPBlackfin.h>
-
/* Include all MMR and bit defines common to BF534 */
#include "defBF534.h"
diff --git a/arch/blackfin/mach-bf537/include/mach/gpio.h b/arch/blackfin/mach-bf537/include/mach/gpio.h
index f80c2995efdb..fba606b699c3 100644
--- a/arch/blackfin/mach-bf537/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf537/include/mach/gpio.h
@@ -62,4 +62,8 @@
#define PORT_G GPIO_PG0
#define PORT_H GPIO_PH0
+#include <mach-common/ports-f.h>
+#include <mach-common/ports-g.h>
+#include <mach-common/ports-h.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf538/dma.c b/arch/blackfin/mach-bf538/dma.c
index 5dc022589214..cce8ef5a5cec 100644
--- a/arch/blackfin/mach-bf538/dma.c
+++ b/arch/blackfin/mach-bf538/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
@@ -32,14 +32,14 @@ struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA17_NEXT_DESC_PTR,
(struct dma_register *) DMA18_NEXT_DESC_PTR,
(struct dma_register *) DMA19_NEXT_DESC_PTR,
- (struct dma_register *) MDMA0_D0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA0_S0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA0_D1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA0_S1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D2_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S2_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
};
EXPORT_SYMBOL(dma_io_base_addr);
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..c66e2760aad3
--- /dev/null
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 3
+
+#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
index 5c148142f041..beb502e9cb33 100644
--- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later.
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v)
-#define UART_PUT_DLL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
-#define UART_PUT_IER(uart, v) bfin_write16(((uart)->port.membase + OFFSET_IER), v)
-#define UART_SET_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
-#define UART_PUT_LCR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
-#define UART_PUT_GCTL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
# define CONFIG_SERIAL_BFIN_CTSRTS
@@ -54,50 +27,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-/*
- * The pin configuration is different from schematic
- */
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -160,3 +89,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h
index 08b5eabb1ed5..791d08400cf0 100644
--- a/arch/blackfin/mach-bf538/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -10,31 +10,24 @@
#define BF538_FAMILY
#include "bf538.h"
-#include "defBF539.h"
#include "anomaly.h"
-
-#if !defined(__ASSEMBLY__)
-#include "cdefBF538.h"
-
-#if defined(CONFIG_BF539)
-#include "cdefBF539.h"
+#include <asm/def_LPBlackfin.h>
+#ifdef CONFIG_BF538
+# include "defBF538.h"
#endif
+#ifdef CONFIG_BF539
+# include "defBF539.h"
#endif
-#define BFIN_UART_NR_PORTS 3
-
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
+#ifndef __ASSEMBLY__
+# include <asm/cdef_LPBlackfin.h>
+# ifdef CONFIG_BF538
+# include "cdefBF538.h"
+# endif
+# ifdef CONFIG_BF539
+# include "cdefBF539.h"
+# endif
+#endif
#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
index 085b06b8c0a5..f6a56792180b 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF538_H
#define _CDEF_BF538_H
-#include <asm/blackfin.h>
-
-/*include all Core registers and bit definitions*/
-#include "defBF539.h"
-
-/*include core specific register pointer definitions*/
-#include <asm/cdef_LPBlackfin.h>
-
#define bfin_writePTR(addr, val) bfin_write32(addr, val)
#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
@@ -487,10 +479,10 @@
#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC, val)
#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT, val)
-#define bfin_read_DMA0_TC_PER() bfin_read16(DMA0_TC_PER)
-#define bfin_write_DMA0_TC_PER(val) bfin_write16(DMA0_TC_PER, val)
-#define bfin_read_DMA0_TC_CNT() bfin_read16(DMA0_TC_CNT)
-#define bfin_write_DMA0_TC_CNT(val) bfin_write16(DMA0_TC_CNT, val)
+#define bfin_read_DMAC0_TC_PER() bfin_read16(DMAC0_TC_PER)
+#define bfin_write_DMAC0_TC_PER(val) bfin_write16(DMAC0_TC_PER, val)
+#define bfin_read_DMAC0_TC_CNT() bfin_read16(DMAC0_TC_CNT)
+#define bfin_write_DMAC0_TC_CNT(val) bfin_write16(DMAC0_TC_CNT, val)
#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_readPTR(DMA0_NEXT_DESC_PTR)
#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_writePTR(DMA0_NEXT_DESC_PTR, val)
#define bfin_read_DMA0_START_ADDR() bfin_readPTR(DMA0_START_ADDR)
@@ -699,10 +691,10 @@
#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT, val)
#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT, val)
-#define bfin_read_DMA1_TC_PER() bfin_read16(DMA1_TC_PER)
-#define bfin_write_DMA1_TC_PER(val) bfin_write16(DMA1_TC_PER, val)
-#define bfin_read_DMA1_TC_CNT() bfin_read16(DMA1_TC_CNT)
-#define bfin_write_DMA1_TC_CNT(val) bfin_write16(DMA1_TC_CNT, val)
+#define bfin_read_DMAC1_TC_PER() bfin_read16(DMAC1_TC_PER)
+#define bfin_write_DMAC1_TC_PER(val) bfin_write16(DMAC1_TC_PER, val)
+#define bfin_read_DMAC1_TC_CNT() bfin_read16(DMAC1_TC_CNT)
+#define bfin_write_DMAC1_TC_CNT(val) bfin_write16(DMAC1_TC_CNT, val)
#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_readPTR(DMA8_NEXT_DESC_PTR)
#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_writePTR(DMA8_NEXT_DESC_PTR, val)
#define bfin_read_DMA8_START_ADDR() bfin_readPTR(DMA8_START_ADDR)
@@ -1015,273 +1007,214 @@
#define bfin_write_DMA19_CURR_X_COUNT(val) bfin_write16(DMA19_CURR_X_COUNT, val)
#define bfin_read_DMA19_CURR_Y_COUNT() bfin_read16(DMA19_CURR_Y_COUNT)
#define bfin_write_DMA19_CURR_Y_COUNT(val) bfin_write16(DMA19_CURR_Y_COUNT, val)
-#define bfin_read_MDMA0_D0_NEXT_DESC_PTR() bfin_readPTR(MDMA0_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA0_D0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA0_D0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA0_D0_START_ADDR() bfin_readPTR(MDMA0_D0_START_ADDR)
-#define bfin_write_MDMA0_D0_START_ADDR(val) bfin_writePTR(MDMA0_D0_START_ADDR, val)
-#define bfin_read_MDMA0_D0_CONFIG() bfin_read16(MDMA0_D0_CONFIG)
-#define bfin_write_MDMA0_D0_CONFIG(val) bfin_write16(MDMA0_D0_CONFIG, val)
-#define bfin_read_MDMA0_D0_X_COUNT() bfin_read16(MDMA0_D0_X_COUNT)
-#define bfin_write_MDMA0_D0_X_COUNT(val) bfin_write16(MDMA0_D0_X_COUNT, val)
-#define bfin_read_MDMA0_D0_X_MODIFY() bfin_read16(MDMA0_D0_X_MODIFY)
-#define bfin_write_MDMA0_D0_X_MODIFY(val) bfin_write16(MDMA0_D0_X_MODIFY, val)
-#define bfin_read_MDMA0_D0_Y_COUNT() bfin_read16(MDMA0_D0_Y_COUNT)
-#define bfin_write_MDMA0_D0_Y_COUNT(val) bfin_write16(MDMA0_D0_Y_COUNT, val)
-#define bfin_read_MDMA0_D0_Y_MODIFY() bfin_read16(MDMA0_D0_Y_MODIFY)
-#define bfin_write_MDMA0_D0_Y_MODIFY(val) bfin_write16(MDMA0_D0_Y_MODIFY, val)
-#define bfin_read_MDMA0_D0_CURR_DESC_PTR() bfin_readPTR(MDMA0_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA0_D0_CURR_DESC_PTR(val) bfin_writePTR(MDMA0_D0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA0_D0_CURR_ADDR() bfin_readPTR(MDMA0_D0_CURR_ADDR)
-#define bfin_write_MDMA0_D0_CURR_ADDR(val) bfin_writePTR(MDMA0_D0_CURR_ADDR, val)
-#define bfin_read_MDMA0_D0_IRQ_STATUS() bfin_read16(MDMA0_D0_IRQ_STATUS)
-#define bfin_write_MDMA0_D0_IRQ_STATUS(val) bfin_write16(MDMA0_D0_IRQ_STATUS, val)
-#define bfin_read_MDMA0_D0_PERIPHERAL_MAP() bfin_read16(MDMA0_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA0_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA0_D0_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA0_D0_CURR_X_COUNT() bfin_read16(MDMA0_D0_CURR_X_COUNT)
-#define bfin_write_MDMA0_D0_CURR_X_COUNT(val) bfin_write16(MDMA0_D0_CURR_X_COUNT, val)
-#define bfin_read_MDMA0_D0_CURR_Y_COUNT() bfin_read16(MDMA0_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA0_D0_CURR_Y_COUNT(val) bfin_write16(MDMA0_D0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA0_S0_NEXT_DESC_PTR() bfin_readPTR(MDMA0_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA0_S0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA0_S0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA0_S0_START_ADDR() bfin_readPTR(MDMA0_S0_START_ADDR)
-#define bfin_write_MDMA0_S0_START_ADDR(val) bfin_writePTR(MDMA0_S0_START_ADDR, val)
-#define bfin_read_MDMA0_S0_CONFIG() bfin_read16(MDMA0_S0_CONFIG)
-#define bfin_write_MDMA0_S0_CONFIG(val) bfin_write16(MDMA0_S0_CONFIG, val)
-#define bfin_read_MDMA0_S0_X_COUNT() bfin_read16(MDMA0_S0_X_COUNT)
-#define bfin_write_MDMA0_S0_X_COUNT(val) bfin_write16(MDMA0_S0_X_COUNT, val)
-#define bfin_read_MDMA0_S0_X_MODIFY() bfin_read16(MDMA0_S0_X_MODIFY)
-#define bfin_write_MDMA0_S0_X_MODIFY(val) bfin_write16(MDMA0_S0_X_MODIFY, val)
-#define bfin_read_MDMA0_S0_Y_COUNT() bfin_read16(MDMA0_S0_Y_COUNT)
-#define bfin_write_MDMA0_S0_Y_COUNT(val) bfin_write16(MDMA0_S0_Y_COUNT, val)
-#define bfin_read_MDMA0_S0_Y_MODIFY() bfin_read16(MDMA0_S0_Y_MODIFY)
-#define bfin_write_MDMA0_S0_Y_MODIFY(val) bfin_write16(MDMA0_S0_Y_MODIFY, val)
-#define bfin_read_MDMA0_S0_CURR_DESC_PTR() bfin_readPTR(MDMA0_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA0_S0_CURR_DESC_PTR(val) bfin_writePTR(MDMA0_S0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA0_S0_CURR_ADDR() bfin_readPTR(MDMA0_S0_CURR_ADDR)
-#define bfin_write_MDMA0_S0_CURR_ADDR(val) bfin_writePTR(MDMA0_S0_CURR_ADDR, val)
-#define bfin_read_MDMA0_S0_IRQ_STATUS() bfin_read16(MDMA0_S0_IRQ_STATUS)
-#define bfin_write_MDMA0_S0_IRQ_STATUS(val) bfin_write16(MDMA0_S0_IRQ_STATUS, val)
-#define bfin_read_MDMA0_S0_PERIPHERAL_MAP() bfin_read16(MDMA0_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA0_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA0_S0_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA0_S0_CURR_X_COUNT() bfin_read16(MDMA0_S0_CURR_X_COUNT)
-#define bfin_write_MDMA0_S0_CURR_X_COUNT(val) bfin_write16(MDMA0_S0_CURR_X_COUNT, val)
-#define bfin_read_MDMA0_S0_CURR_Y_COUNT() bfin_read16(MDMA0_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA0_S0_CURR_Y_COUNT(val) bfin_write16(MDMA0_S0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA0_D1_NEXT_DESC_PTR() bfin_readPTR(MDMA0_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA0_D1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA0_D1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA0_D1_START_ADDR() bfin_readPTR(MDMA0_D1_START_ADDR)
-#define bfin_write_MDMA0_D1_START_ADDR(val) bfin_writePTR(MDMA0_D1_START_ADDR, val)
-#define bfin_read_MDMA0_D1_CONFIG() bfin_read16(MDMA0_D1_CONFIG)
-#define bfin_write_MDMA0_D1_CONFIG(val) bfin_write16(MDMA0_D1_CONFIG, val)
-#define bfin_read_MDMA0_D1_X_COUNT() bfin_read16(MDMA0_D1_X_COUNT)
-#define bfin_write_MDMA0_D1_X_COUNT(val) bfin_write16(MDMA0_D1_X_COUNT, val)
-#define bfin_read_MDMA0_D1_X_MODIFY() bfin_read16(MDMA0_D1_X_MODIFY)
-#define bfin_write_MDMA0_D1_X_MODIFY(val) bfin_write16(MDMA0_D1_X_MODIFY, val)
-#define bfin_read_MDMA0_D1_Y_COUNT() bfin_read16(MDMA0_D1_Y_COUNT)
-#define bfin_write_MDMA0_D1_Y_COUNT(val) bfin_write16(MDMA0_D1_Y_COUNT, val)
-#define bfin_read_MDMA0_D1_Y_MODIFY() bfin_read16(MDMA0_D1_Y_MODIFY)
-#define bfin_write_MDMA0_D1_Y_MODIFY(val) bfin_write16(MDMA0_D1_Y_MODIFY, val)
-#define bfin_read_MDMA0_D1_CURR_DESC_PTR() bfin_readPTR(MDMA0_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA0_D1_CURR_DESC_PTR(val) bfin_writePTR(MDMA0_D1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA0_D1_CURR_ADDR() bfin_readPTR(MDMA0_D1_CURR_ADDR)
-#define bfin_write_MDMA0_D1_CURR_ADDR(val) bfin_writePTR(MDMA0_D1_CURR_ADDR, val)
-#define bfin_read_MDMA0_D1_IRQ_STATUS() bfin_read16(MDMA0_D1_IRQ_STATUS)
-#define bfin_write_MDMA0_D1_IRQ_STATUS(val) bfin_write16(MDMA0_D1_IRQ_STATUS, val)
-#define bfin_read_MDMA0_D1_PERIPHERAL_MAP() bfin_read16(MDMA0_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA0_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA0_D1_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA0_D1_CURR_X_COUNT() bfin_read16(MDMA0_D1_CURR_X_COUNT)
-#define bfin_write_MDMA0_D1_CURR_X_COUNT(val) bfin_write16(MDMA0_D1_CURR_X_COUNT, val)
-#define bfin_read_MDMA0_D1_CURR_Y_COUNT() bfin_read16(MDMA0_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA0_D1_CURR_Y_COUNT(val) bfin_write16(MDMA0_D1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA0_S1_NEXT_DESC_PTR() bfin_readPTR(MDMA0_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA0_S1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA0_S1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA0_S1_START_ADDR() bfin_readPTR(MDMA0_S1_START_ADDR)
-#define bfin_write_MDMA0_S1_START_ADDR(val) bfin_writePTR(MDMA0_S1_START_ADDR, val)
-#define bfin_read_MDMA0_S1_CONFIG() bfin_read16(MDMA0_S1_CONFIG)
-#define bfin_write_MDMA0_S1_CONFIG(val) bfin_write16(MDMA0_S1_CONFIG, val)
-#define bfin_read_MDMA0_S1_X_COUNT() bfin_read16(MDMA0_S1_X_COUNT)
-#define bfin_write_MDMA0_S1_X_COUNT(val) bfin_write16(MDMA0_S1_X_COUNT, val)
-#define bfin_read_MDMA0_S1_X_MODIFY() bfin_read16(MDMA0_S1_X_MODIFY)
-#define bfin_write_MDMA0_S1_X_MODIFY(val) bfin_write16(MDMA0_S1_X_MODIFY, val)
-#define bfin_read_MDMA0_S1_Y_COUNT() bfin_read16(MDMA0_S1_Y_COUNT)
-#define bfin_write_MDMA0_S1_Y_COUNT(val) bfin_write16(MDMA0_S1_Y_COUNT, val)
-#define bfin_read_MDMA0_S1_Y_MODIFY() bfin_read16(MDMA0_S1_Y_MODIFY)
-#define bfin_write_MDMA0_S1_Y_MODIFY(val) bfin_write16(MDMA0_S1_Y_MODIFY, val)
-#define bfin_read_MDMA0_S1_CURR_DESC_PTR() bfin_readPTR(MDMA0_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA0_S1_CURR_DESC_PTR(val) bfin_writePTR(MDMA0_S1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA0_S1_CURR_ADDR() bfin_readPTR(MDMA0_S1_CURR_ADDR)
-#define bfin_write_MDMA0_S1_CURR_ADDR(val) bfin_writePTR(MDMA0_S1_CURR_ADDR, val)
-#define bfin_read_MDMA0_S1_IRQ_STATUS() bfin_read16(MDMA0_S1_IRQ_STATUS)
-#define bfin_write_MDMA0_S1_IRQ_STATUS(val) bfin_write16(MDMA0_S1_IRQ_STATUS, val)
-#define bfin_read_MDMA0_S1_PERIPHERAL_MAP() bfin_read16(MDMA0_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA0_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA0_S1_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA0_S1_CURR_X_COUNT() bfin_read16(MDMA0_S1_CURR_X_COUNT)
-#define bfin_write_MDMA0_S1_CURR_X_COUNT(val) bfin_write16(MDMA0_S1_CURR_X_COUNT, val)
-#define bfin_read_MDMA0_S1_CURR_Y_COUNT() bfin_read16(MDMA0_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA0_S1_CURR_Y_COUNT(val) bfin_write16(MDMA0_S1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA1_D0_NEXT_DESC_PTR() bfin_readPTR(MDMA1_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_D0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA1_D0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA1_D0_START_ADDR() bfin_readPTR(MDMA1_D0_START_ADDR)
-#define bfin_write_MDMA1_D0_START_ADDR(val) bfin_writePTR(MDMA1_D0_START_ADDR, val)
-#define bfin_read_MDMA1_D0_CONFIG() bfin_read16(MDMA1_D0_CONFIG)
-#define bfin_write_MDMA1_D0_CONFIG(val) bfin_write16(MDMA1_D0_CONFIG, val)
-#define bfin_read_MDMA1_D0_X_COUNT() bfin_read16(MDMA1_D0_X_COUNT)
-#define bfin_write_MDMA1_D0_X_COUNT(val) bfin_write16(MDMA1_D0_X_COUNT, val)
-#define bfin_read_MDMA1_D0_X_MODIFY() bfin_read16(MDMA1_D0_X_MODIFY)
-#define bfin_write_MDMA1_D0_X_MODIFY(val) bfin_write16(MDMA1_D0_X_MODIFY, val)
-#define bfin_read_MDMA1_D0_Y_COUNT() bfin_read16(MDMA1_D0_Y_COUNT)
-#define bfin_write_MDMA1_D0_Y_COUNT(val) bfin_write16(MDMA1_D0_Y_COUNT, val)
-#define bfin_read_MDMA1_D0_Y_MODIFY() bfin_read16(MDMA1_D0_Y_MODIFY)
-#define bfin_write_MDMA1_D0_Y_MODIFY(val) bfin_write16(MDMA1_D0_Y_MODIFY, val)
-#define bfin_read_MDMA1_D0_CURR_DESC_PTR() bfin_readPTR(MDMA1_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA1_D0_CURR_DESC_PTR(val) bfin_writePTR(MDMA1_D0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA1_D0_CURR_ADDR() bfin_readPTR(MDMA1_D0_CURR_ADDR)
-#define bfin_write_MDMA1_D0_CURR_ADDR(val) bfin_writePTR(MDMA1_D0_CURR_ADDR, val)
-#define bfin_read_MDMA1_D0_IRQ_STATUS() bfin_read16(MDMA1_D0_IRQ_STATUS)
-#define bfin_write_MDMA1_D0_IRQ_STATUS(val) bfin_write16(MDMA1_D0_IRQ_STATUS, val)
-#define bfin_read_MDMA1_D0_PERIPHERAL_MAP() bfin_read16(MDMA1_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D0_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA1_D0_CURR_X_COUNT() bfin_read16(MDMA1_D0_CURR_X_COUNT)
-#define bfin_write_MDMA1_D0_CURR_X_COUNT(val) bfin_write16(MDMA1_D0_CURR_X_COUNT, val)
-#define bfin_read_MDMA1_D0_CURR_Y_COUNT() bfin_read16(MDMA1_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA1_D0_CURR_Y_COUNT(val) bfin_write16(MDMA1_D0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA1_S0_NEXT_DESC_PTR() bfin_readPTR(MDMA1_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_S0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA1_S0_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA1_S0_START_ADDR() bfin_readPTR(MDMA1_S0_START_ADDR)
-#define bfin_write_MDMA1_S0_START_ADDR(val) bfin_writePTR(MDMA1_S0_START_ADDR, val)
-#define bfin_read_MDMA1_S0_CONFIG() bfin_read16(MDMA1_S0_CONFIG)
-#define bfin_write_MDMA1_S0_CONFIG(val) bfin_write16(MDMA1_S0_CONFIG, val)
-#define bfin_read_MDMA1_S0_X_COUNT() bfin_read16(MDMA1_S0_X_COUNT)
-#define bfin_write_MDMA1_S0_X_COUNT(val) bfin_write16(MDMA1_S0_X_COUNT, val)
-#define bfin_read_MDMA1_S0_X_MODIFY() bfin_read16(MDMA1_S0_X_MODIFY)
-#define bfin_write_MDMA1_S0_X_MODIFY(val) bfin_write16(MDMA1_S0_X_MODIFY, val)
-#define bfin_read_MDMA1_S0_Y_COUNT() bfin_read16(MDMA1_S0_Y_COUNT)
-#define bfin_write_MDMA1_S0_Y_COUNT(val) bfin_write16(MDMA1_S0_Y_COUNT, val)
-#define bfin_read_MDMA1_S0_Y_MODIFY() bfin_read16(MDMA1_S0_Y_MODIFY)
-#define bfin_write_MDMA1_S0_Y_MODIFY(val) bfin_write16(MDMA1_S0_Y_MODIFY, val)
-#define bfin_read_MDMA1_S0_CURR_DESC_PTR() bfin_readPTR(MDMA1_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA1_S0_CURR_DESC_PTR(val) bfin_writePTR(MDMA1_S0_CURR_DESC_PTR, val)
-#define bfin_read_MDMA1_S0_CURR_ADDR() bfin_readPTR(MDMA1_S0_CURR_ADDR)
-#define bfin_write_MDMA1_S0_CURR_ADDR(val) bfin_writePTR(MDMA1_S0_CURR_ADDR, val)
-#define bfin_read_MDMA1_S0_IRQ_STATUS() bfin_read16(MDMA1_S0_IRQ_STATUS)
-#define bfin_write_MDMA1_S0_IRQ_STATUS(val) bfin_write16(MDMA1_S0_IRQ_STATUS, val)
-#define bfin_read_MDMA1_S0_PERIPHERAL_MAP() bfin_read16(MDMA1_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S0_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA1_S0_CURR_X_COUNT() bfin_read16(MDMA1_S0_CURR_X_COUNT)
-#define bfin_write_MDMA1_S0_CURR_X_COUNT(val) bfin_write16(MDMA1_S0_CURR_X_COUNT, val)
-#define bfin_read_MDMA1_S0_CURR_Y_COUNT() bfin_read16(MDMA1_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA1_S0_CURR_Y_COUNT(val) bfin_write16(MDMA1_S0_CURR_Y_COUNT, val)
-#define bfin_read_MDMA1_D1_NEXT_DESC_PTR() bfin_readPTR(MDMA1_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_D1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA1_D1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA1_D1_START_ADDR() bfin_readPTR(MDMA1_D1_START_ADDR)
-#define bfin_write_MDMA1_D1_START_ADDR(val) bfin_writePTR(MDMA1_D1_START_ADDR, val)
-#define bfin_read_MDMA1_D1_CONFIG() bfin_read16(MDMA1_D1_CONFIG)
-#define bfin_write_MDMA1_D1_CONFIG(val) bfin_write16(MDMA1_D1_CONFIG, val)
-#define bfin_read_MDMA1_D1_X_COUNT() bfin_read16(MDMA1_D1_X_COUNT)
-#define bfin_write_MDMA1_D1_X_COUNT(val) bfin_write16(MDMA1_D1_X_COUNT, val)
-#define bfin_read_MDMA1_D1_X_MODIFY() bfin_read16(MDMA1_D1_X_MODIFY)
-#define bfin_write_MDMA1_D1_X_MODIFY(val) bfin_write16(MDMA1_D1_X_MODIFY, val)
-#define bfin_read_MDMA1_D1_Y_COUNT() bfin_read16(MDMA1_D1_Y_COUNT)
-#define bfin_write_MDMA1_D1_Y_COUNT(val) bfin_write16(MDMA1_D1_Y_COUNT, val)
-#define bfin_read_MDMA1_D1_Y_MODIFY() bfin_read16(MDMA1_D1_Y_MODIFY)
-#define bfin_write_MDMA1_D1_Y_MODIFY(val) bfin_write16(MDMA1_D1_Y_MODIFY, val)
-#define bfin_read_MDMA1_D1_CURR_DESC_PTR() bfin_readPTR(MDMA1_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA1_D1_CURR_DESC_PTR(val) bfin_writePTR(MDMA1_D1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA1_D1_CURR_ADDR() bfin_readPTR(MDMA1_D1_CURR_ADDR)
-#define bfin_write_MDMA1_D1_CURR_ADDR(val) bfin_writePTR(MDMA1_D1_CURR_ADDR, val)
-#define bfin_read_MDMA1_D1_IRQ_STATUS() bfin_read16(MDMA1_D1_IRQ_STATUS)
-#define bfin_write_MDMA1_D1_IRQ_STATUS(val) bfin_write16(MDMA1_D1_IRQ_STATUS, val)
-#define bfin_read_MDMA1_D1_PERIPHERAL_MAP() bfin_read16(MDMA1_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D1_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA1_D1_CURR_X_COUNT() bfin_read16(MDMA1_D1_CURR_X_COUNT)
-#define bfin_write_MDMA1_D1_CURR_X_COUNT(val) bfin_write16(MDMA1_D1_CURR_X_COUNT, val)
-#define bfin_read_MDMA1_D1_CURR_Y_COUNT() bfin_read16(MDMA1_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA1_D1_CURR_Y_COUNT(val) bfin_write16(MDMA1_D1_CURR_Y_COUNT, val)
-#define bfin_read_MDMA1_S1_NEXT_DESC_PTR() bfin_readPTR(MDMA1_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_S1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA1_S1_NEXT_DESC_PTR, val)
-#define bfin_read_MDMA1_S1_START_ADDR() bfin_readPTR(MDMA1_S1_START_ADDR)
-#define bfin_write_MDMA1_S1_START_ADDR(val) bfin_writePTR(MDMA1_S1_START_ADDR, val)
-#define bfin_read_MDMA1_S1_CONFIG() bfin_read16(MDMA1_S1_CONFIG)
-#define bfin_write_MDMA1_S1_CONFIG(val) bfin_write16(MDMA1_S1_CONFIG, val)
-#define bfin_read_MDMA1_S1_X_COUNT() bfin_read16(MDMA1_S1_X_COUNT)
-#define bfin_write_MDMA1_S1_X_COUNT(val) bfin_write16(MDMA1_S1_X_COUNT, val)
-#define bfin_read_MDMA1_S1_X_MODIFY() bfin_read16(MDMA1_S1_X_MODIFY)
-#define bfin_write_MDMA1_S1_X_MODIFY(val) bfin_write16(MDMA1_S1_X_MODIFY, val)
-#define bfin_read_MDMA1_S1_Y_COUNT() bfin_read16(MDMA1_S1_Y_COUNT)
-#define bfin_write_MDMA1_S1_Y_COUNT(val) bfin_write16(MDMA1_S1_Y_COUNT, val)
-#define bfin_read_MDMA1_S1_Y_MODIFY() bfin_read16(MDMA1_S1_Y_MODIFY)
-#define bfin_write_MDMA1_S1_Y_MODIFY(val) bfin_write16(MDMA1_S1_Y_MODIFY, val)
-#define bfin_read_MDMA1_S1_CURR_DESC_PTR() bfin_readPTR(MDMA1_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA1_S1_CURR_DESC_PTR(val) bfin_writePTR(MDMA1_S1_CURR_DESC_PTR, val)
-#define bfin_read_MDMA1_S1_CURR_ADDR() bfin_readPTR(MDMA1_S1_CURR_ADDR)
-#define bfin_write_MDMA1_S1_CURR_ADDR(val) bfin_writePTR(MDMA1_S1_CURR_ADDR, val)
-#define bfin_read_MDMA1_S1_IRQ_STATUS() bfin_read16(MDMA1_S1_IRQ_STATUS)
-#define bfin_write_MDMA1_S1_IRQ_STATUS(val) bfin_write16(MDMA1_S1_IRQ_STATUS, val)
-#define bfin_read_MDMA1_S1_PERIPHERAL_MAP() bfin_read16(MDMA1_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S1_PERIPHERAL_MAP, val)
-#define bfin_read_MDMA1_S1_CURR_X_COUNT() bfin_read16(MDMA1_S1_CURR_X_COUNT)
-#define bfin_write_MDMA1_S1_CURR_X_COUNT(val) bfin_write16(MDMA1_S1_CURR_X_COUNT, val)
-#define bfin_read_MDMA1_S1_CURR_Y_COUNT() bfin_read16(MDMA1_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA1_S1_CURR_Y_COUNT(val) bfin_write16(MDMA1_S1_CURR_Y_COUNT, val)
-
-#define bfin_read_MDMA_S0_CONFIG() bfin_read_MDMA0_S0_CONFIG()
-#define bfin_write_MDMA_S0_CONFIG(val) bfin_write_MDMA0_S0_CONFIG(val)
-#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read_MDMA0_S0_IRQ_STATUS()
-#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write_MDMA0_S0_IRQ_STATUS(val)
-#define bfin_read_MDMA_S0_X_MODIFY() bfin_read_MDMA0_S0_X_MODIFY()
-#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write_MDMA0_S0_X_MODIFY(val)
-#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read_MDMA0_S0_Y_MODIFY()
-#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write_MDMA0_S0_Y_MODIFY(val)
-#define bfin_read_MDMA_S0_X_COUNT() bfin_read_MDMA0_S0_X_COUNT()
-#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write_MDMA0_S0_X_COUNT(val)
-#define bfin_read_MDMA_S0_Y_COUNT() bfin_read_MDMA0_S0_Y_COUNT()
-#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write_MDMA0_S0_Y_COUNT(val)
-#define bfin_read_MDMA_S0_START_ADDR() bfin_read_MDMA0_S0_START_ADDR()
-#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write_MDMA0_S0_START_ADDR(val)
-#define bfin_read_MDMA_D0_CONFIG() bfin_read_MDMA0_D0_CONFIG()
-#define bfin_write_MDMA_D0_CONFIG(val) bfin_write_MDMA0_D0_CONFIG(val)
-#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read_MDMA0_D0_IRQ_STATUS()
-#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write_MDMA0_D0_IRQ_STATUS(val)
-#define bfin_read_MDMA_D0_X_MODIFY() bfin_read_MDMA0_D0_X_MODIFY()
-#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write_MDMA0_D0_X_MODIFY(val)
-#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read_MDMA0_D0_Y_MODIFY()
-#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write_MDMA0_D0_Y_MODIFY(val)
-#define bfin_read_MDMA_D0_X_COUNT() bfin_read_MDMA0_D0_X_COUNT()
-#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write_MDMA0_D0_X_COUNT(val)
-#define bfin_read_MDMA_D0_Y_COUNT() bfin_read_MDMA0_D0_Y_COUNT()
-#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write_MDMA0_D0_Y_COUNT(val)
-#define bfin_read_MDMA_D0_START_ADDR() bfin_read_MDMA0_D0_START_ADDR()
-#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write_MDMA0_D0_START_ADDR(val)
-
-#define bfin_read_MDMA_S1_CONFIG() bfin_read_MDMA0_S1_CONFIG()
-#define bfin_write_MDMA_S1_CONFIG(val) bfin_write_MDMA0_S1_CONFIG(val)
-#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read_MDMA0_S1_IRQ_STATUS()
-#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write_MDMA0_S1_IRQ_STATUS(val)
-#define bfin_read_MDMA_S1_X_MODIFY() bfin_read_MDMA0_S1_X_MODIFY()
-#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write_MDMA0_S1_X_MODIFY(val)
-#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read_MDMA0_S1_Y_MODIFY()
-#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write_MDMA0_S1_Y_MODIFY(val)
-#define bfin_read_MDMA_S1_X_COUNT() bfin_read_MDMA0_S1_X_COUNT()
-#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write_MDMA0_S1_X_COUNT(val)
-#define bfin_read_MDMA_S1_Y_COUNT() bfin_read_MDMA0_S1_Y_COUNT()
-#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write_MDMA0_S1_Y_COUNT(val)
-#define bfin_read_MDMA_S1_START_ADDR() bfin_read_MDMA0_S1_START_ADDR()
-#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write_MDMA0_S1_START_ADDR(val)
-#define bfin_read_MDMA_D1_CONFIG() bfin_read_MDMA0_D1_CONFIG()
-#define bfin_write_MDMA_D1_CONFIG(val) bfin_write_MDMA0_D1_CONFIG(val)
-#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read_MDMA0_D1_IRQ_STATUS()
-#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write_MDMA0_D1_IRQ_STATUS(val)
-#define bfin_read_MDMA_D1_X_MODIFY() bfin_read_MDMA0_D1_X_MODIFY()
-#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write_MDMA0_D1_X_MODIFY(val)
-#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read_MDMA0_D1_Y_MODIFY()
-#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write_MDMA0_D1_Y_MODIFY(val)
-#define bfin_read_MDMA_D1_X_COUNT() bfin_read_MDMA0_D1_X_COUNT()
-#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write_MDMA0_D1_X_COUNT(val)
-#define bfin_read_MDMA_D1_Y_COUNT() bfin_read_MDMA0_D1_Y_COUNT()
-#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write_MDMA0_D1_Y_COUNT(val)
-#define bfin_read_MDMA_D1_START_ADDR() bfin_read_MDMA0_D1_START_ADDR()
-#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write_MDMA0_D1_START_ADDR(val)
-
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_readPTR(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_D0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_readPTR(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_writePTR(MDMA_D0_START_ADDR, val)
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG, val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT, val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY, val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT, val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY, val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_readPTR(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_writePTR(MDMA_D0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_readPTR(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_writePTR(MDMA_D0_CURR_ADDR, val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS, val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_readPTR(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_S0_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_readPTR(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_writePTR(MDMA_S0_START_ADDR, val)
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG, val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT, val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY, val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT, val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY, val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_readPTR(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_writePTR(MDMA_S0_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_readPTR(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_writePTR(MDMA_S0_CURR_ADDR, val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS, val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_readPTR(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_D1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_readPTR(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_writePTR(MDMA_D1_START_ADDR, val)
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG, val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT, val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY, val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT, val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY, val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_readPTR(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_writePTR(MDMA_D1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_readPTR(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_writePTR(MDMA_D1_CURR_ADDR, val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS, val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_readPTR(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_S1_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_readPTR(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_writePTR(MDMA_S1_START_ADDR, val)
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG, val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT, val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY, val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT, val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY, val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_readPTR(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_writePTR(MDMA_S1_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_readPTR(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_writePTR(MDMA_S1_CURR_ADDR, val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS, val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D2_NEXT_DESC_PTR() bfin_readPTR(MDMA_D2_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D2_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_D2_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D2_START_ADDR() bfin_readPTR(MDMA_D2_START_ADDR)
+#define bfin_write_MDMA_D2_START_ADDR(val) bfin_writePTR(MDMA_D2_START_ADDR, val)
+#define bfin_read_MDMA_D2_CONFIG() bfin_read16(MDMA_D2_CONFIG)
+#define bfin_write_MDMA_D2_CONFIG(val) bfin_write16(MDMA_D2_CONFIG, val)
+#define bfin_read_MDMA_D2_X_COUNT() bfin_read16(MDMA_D2_X_COUNT)
+#define bfin_write_MDMA_D2_X_COUNT(val) bfin_write16(MDMA_D2_X_COUNT, val)
+#define bfin_read_MDMA_D2_X_MODIFY() bfin_read16(MDMA_D2_X_MODIFY)
+#define bfin_write_MDMA_D2_X_MODIFY(val) bfin_write16(MDMA_D2_X_MODIFY, val)
+#define bfin_read_MDMA_D2_Y_COUNT() bfin_read16(MDMA_D2_Y_COUNT)
+#define bfin_write_MDMA_D2_Y_COUNT(val) bfin_write16(MDMA_D2_Y_COUNT, val)
+#define bfin_read_MDMA_D2_Y_MODIFY() bfin_read16(MDMA_D2_Y_MODIFY)
+#define bfin_write_MDMA_D2_Y_MODIFY(val) bfin_write16(MDMA_D2_Y_MODIFY, val)
+#define bfin_read_MDMA_D2_CURR_DESC_PTR() bfin_readPTR(MDMA_D2_CURR_DESC_PTR)
+#define bfin_write_MDMA_D2_CURR_DESC_PTR(val) bfin_writePTR(MDMA_D2_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D2_CURR_ADDR() bfin_readPTR(MDMA_D2_CURR_ADDR)
+#define bfin_write_MDMA_D2_CURR_ADDR(val) bfin_writePTR(MDMA_D2_CURR_ADDR, val)
+#define bfin_read_MDMA_D2_IRQ_STATUS() bfin_read16(MDMA_D2_IRQ_STATUS)
+#define bfin_write_MDMA_D2_IRQ_STATUS(val) bfin_write16(MDMA_D2_IRQ_STATUS, val)
+#define bfin_read_MDMA_D2_PERIPHERAL_MAP() bfin_read16(MDMA_D2_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D2_PERIPHERAL_MAP(val) bfin_write16(MDMA_D2_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_D2_CURR_X_COUNT() bfin_read16(MDMA_D2_CURR_X_COUNT)
+#define bfin_write_MDMA_D2_CURR_X_COUNT(val) bfin_write16(MDMA_D2_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D2_CURR_Y_COUNT() bfin_read16(MDMA_D2_CURR_Y_COUNT)
+#define bfin_write_MDMA_D2_CURR_Y_COUNT(val) bfin_write16(MDMA_D2_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S2_NEXT_DESC_PTR() bfin_readPTR(MDMA_S2_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S2_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_S2_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S2_START_ADDR() bfin_readPTR(MDMA_S2_START_ADDR)
+#define bfin_write_MDMA_S2_START_ADDR(val) bfin_writePTR(MDMA_S2_START_ADDR, val)
+#define bfin_read_MDMA_S2_CONFIG() bfin_read16(MDMA_S2_CONFIG)
+#define bfin_write_MDMA_S2_CONFIG(val) bfin_write16(MDMA_S2_CONFIG, val)
+#define bfin_read_MDMA_S2_X_COUNT() bfin_read16(MDMA_S2_X_COUNT)
+#define bfin_write_MDMA_S2_X_COUNT(val) bfin_write16(MDMA_S2_X_COUNT, val)
+#define bfin_read_MDMA_S2_X_MODIFY() bfin_read16(MDMA_S2_X_MODIFY)
+#define bfin_write_MDMA_S2_X_MODIFY(val) bfin_write16(MDMA_S2_X_MODIFY, val)
+#define bfin_read_MDMA_S2_Y_COUNT() bfin_read16(MDMA_S2_Y_COUNT)
+#define bfin_write_MDMA_S2_Y_COUNT(val) bfin_write16(MDMA_S2_Y_COUNT, val)
+#define bfin_read_MDMA_S2_Y_MODIFY() bfin_read16(MDMA_S2_Y_MODIFY)
+#define bfin_write_MDMA_S2_Y_MODIFY(val) bfin_write16(MDMA_S2_Y_MODIFY, val)
+#define bfin_read_MDMA_S2_CURR_DESC_PTR() bfin_readPTR(MDMA_S2_CURR_DESC_PTR)
+#define bfin_write_MDMA_S2_CURR_DESC_PTR(val) bfin_writePTR(MDMA_S2_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S2_CURR_ADDR() bfin_readPTR(MDMA_S2_CURR_ADDR)
+#define bfin_write_MDMA_S2_CURR_ADDR(val) bfin_writePTR(MDMA_S2_CURR_ADDR, val)
+#define bfin_read_MDMA_S2_IRQ_STATUS() bfin_read16(MDMA_S2_IRQ_STATUS)
+#define bfin_write_MDMA_S2_IRQ_STATUS(val) bfin_write16(MDMA_S2_IRQ_STATUS, val)
+#define bfin_read_MDMA_S2_PERIPHERAL_MAP() bfin_read16(MDMA_S2_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S2_PERIPHERAL_MAP(val) bfin_write16(MDMA_S2_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_S2_CURR_X_COUNT() bfin_read16(MDMA_S2_CURR_X_COUNT)
+#define bfin_write_MDMA_S2_CURR_X_COUNT(val) bfin_write16(MDMA_S2_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S2_CURR_Y_COUNT() bfin_read16(MDMA_S2_CURR_Y_COUNT)
+#define bfin_write_MDMA_S2_CURR_Y_COUNT(val) bfin_write16(MDMA_S2_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_D3_NEXT_DESC_PTR() bfin_readPTR(MDMA_D3_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D3_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_D3_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_D3_START_ADDR() bfin_readPTR(MDMA_D3_START_ADDR)
+#define bfin_write_MDMA_D3_START_ADDR(val) bfin_writePTR(MDMA_D3_START_ADDR, val)
+#define bfin_read_MDMA_D3_CONFIG() bfin_read16(MDMA_D3_CONFIG)
+#define bfin_write_MDMA_D3_CONFIG(val) bfin_write16(MDMA_D3_CONFIG, val)
+#define bfin_read_MDMA_D3_X_COUNT() bfin_read16(MDMA_D3_X_COUNT)
+#define bfin_write_MDMA_D3_X_COUNT(val) bfin_write16(MDMA_D3_X_COUNT, val)
+#define bfin_read_MDMA_D3_X_MODIFY() bfin_read16(MDMA_D3_X_MODIFY)
+#define bfin_write_MDMA_D3_X_MODIFY(val) bfin_write16(MDMA_D3_X_MODIFY, val)
+#define bfin_read_MDMA_D3_Y_COUNT() bfin_read16(MDMA_D3_Y_COUNT)
+#define bfin_write_MDMA_D3_Y_COUNT(val) bfin_write16(MDMA_D3_Y_COUNT, val)
+#define bfin_read_MDMA_D3_Y_MODIFY() bfin_read16(MDMA_D3_Y_MODIFY)
+#define bfin_write_MDMA_D3_Y_MODIFY(val) bfin_write16(MDMA_D3_Y_MODIFY, val)
+#define bfin_read_MDMA_D3_CURR_DESC_PTR() bfin_readPTR(MDMA_D3_CURR_DESC_PTR)
+#define bfin_write_MDMA_D3_CURR_DESC_PTR(val) bfin_writePTR(MDMA_D3_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_D3_CURR_ADDR() bfin_readPTR(MDMA_D3_CURR_ADDR)
+#define bfin_write_MDMA_D3_CURR_ADDR(val) bfin_writePTR(MDMA_D3_CURR_ADDR, val)
+#define bfin_read_MDMA_D3_IRQ_STATUS() bfin_read16(MDMA_D3_IRQ_STATUS)
+#define bfin_write_MDMA_D3_IRQ_STATUS(val) bfin_write16(MDMA_D3_IRQ_STATUS, val)
+#define bfin_read_MDMA_D3_PERIPHERAL_MAP() bfin_read16(MDMA_D3_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D3_PERIPHERAL_MAP(val) bfin_write16(MDMA_D3_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_D3_CURR_X_COUNT() bfin_read16(MDMA_D3_CURR_X_COUNT)
+#define bfin_write_MDMA_D3_CURR_X_COUNT(val) bfin_write16(MDMA_D3_CURR_X_COUNT, val)
+#define bfin_read_MDMA_D3_CURR_Y_COUNT() bfin_read16(MDMA_D3_CURR_Y_COUNT)
+#define bfin_write_MDMA_D3_CURR_Y_COUNT(val) bfin_write16(MDMA_D3_CURR_Y_COUNT, val)
+#define bfin_read_MDMA_S3_NEXT_DESC_PTR() bfin_readPTR(MDMA_S3_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S3_NEXT_DESC_PTR(val) bfin_writePTR(MDMA_S3_NEXT_DESC_PTR, val)
+#define bfin_read_MDMA_S3_START_ADDR() bfin_readPTR(MDMA_S3_START_ADDR)
+#define bfin_write_MDMA_S3_START_ADDR(val) bfin_writePTR(MDMA_S3_START_ADDR, val)
+#define bfin_read_MDMA_S3_CONFIG() bfin_read16(MDMA_S3_CONFIG)
+#define bfin_write_MDMA_S3_CONFIG(val) bfin_write16(MDMA_S3_CONFIG, val)
+#define bfin_read_MDMA_S3_X_COUNT() bfin_read16(MDMA_S3_X_COUNT)
+#define bfin_write_MDMA_S3_X_COUNT(val) bfin_write16(MDMA_S3_X_COUNT, val)
+#define bfin_read_MDMA_S3_X_MODIFY() bfin_read16(MDMA_S3_X_MODIFY)
+#define bfin_write_MDMA_S3_X_MODIFY(val) bfin_write16(MDMA_S3_X_MODIFY, val)
+#define bfin_read_MDMA_S3_Y_COUNT() bfin_read16(MDMA_S3_Y_COUNT)
+#define bfin_write_MDMA_S3_Y_COUNT(val) bfin_write16(MDMA_S3_Y_COUNT, val)
+#define bfin_read_MDMA_S3_Y_MODIFY() bfin_read16(MDMA_S3_Y_MODIFY)
+#define bfin_write_MDMA_S3_Y_MODIFY(val) bfin_write16(MDMA_S3_Y_MODIFY, val)
+#define bfin_read_MDMA_S3_CURR_DESC_PTR() bfin_readPTR(MDMA_S3_CURR_DESC_PTR)
+#define bfin_write_MDMA_S3_CURR_DESC_PTR(val) bfin_writePTR(MDMA_S3_CURR_DESC_PTR, val)
+#define bfin_read_MDMA_S3_CURR_ADDR() bfin_readPTR(MDMA_S3_CURR_ADDR)
+#define bfin_write_MDMA_S3_CURR_ADDR(val) bfin_writePTR(MDMA_S3_CURR_ADDR, val)
+#define bfin_read_MDMA_S3_IRQ_STATUS() bfin_read16(MDMA_S3_IRQ_STATUS)
+#define bfin_write_MDMA_S3_IRQ_STATUS(val) bfin_write16(MDMA_S3_IRQ_STATUS, val)
+#define bfin_read_MDMA_S3_PERIPHERAL_MAP() bfin_read16(MDMA_S3_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S3_PERIPHERAL_MAP(val) bfin_write16(MDMA_S3_PERIPHERAL_MAP, val)
+#define bfin_read_MDMA_S3_CURR_X_COUNT() bfin_read16(MDMA_S3_CURR_X_COUNT)
+#define bfin_write_MDMA_S3_CURR_X_COUNT(val) bfin_write16(MDMA_S3_CURR_X_COUNT, val)
+#define bfin_read_MDMA_S3_CURR_Y_COUNT() bfin_read16(MDMA_S3_CURR_Y_COUNT)
+#define bfin_write_MDMA_S3_CURR_Y_COUNT(val) bfin_write16(MDMA_S3_CURR_Y_COUNT, val)
#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val)
#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
@@ -2024,7 +1957,4 @@
#define bfin_read_CAN_MB31_ID1() bfin_read16(CAN_MB31_ID1)
#define bfin_write_CAN_MB31_ID1(val) bfin_write16(CAN_MB31_ID1, val)
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF539.h b/arch/blackfin/mach-bf538/include/mach/cdefBF539.h
index 198c4bbc8e5d..acc15f3aba38 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF539.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF539.h
@@ -1,6 +1,7 @@
-/* DO NOT EDIT THIS FILE
- * Automatically generated by generate-cdef-headers.xsl
- * DO NOT EDIT THIS FILE
+/*
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF539_H
@@ -9,7 +10,6 @@
/* Include MMRs Common to BF538 */
#include "cdefBF538.h"
-
#define bfin_read_MXVR_CONFIG() bfin_read16(MXVR_CONFIG)
#define bfin_write_MXVR_CONFIG(val) bfin_write16(MXVR_CONFIG, val)
#define bfin_read_MXVR_PLL_CTL_0() bfin_read32(MXVR_PLL_CTL_0)
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF538.h b/arch/blackfin/mach-bf538/include/mach/defBF538.h
new file mode 100644
index 000000000000..d27f81d6c4b1
--- /dev/null
+++ b/arch/blackfin/mach-bf538/include/mach/defBF538.h
@@ -0,0 +1,1825 @@
+/*
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
+ */
+
+#ifndef _DEF_BF538_H
+#define _DEF_BF538_H
+
+/* Clock/Regulator Control (0xFFC00000 - 0xFFC000FF) */
+#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */
+#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */
+#define CHIPID 0xFFC00014 /* Chip ID Register */
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */
+#define SYSCR 0xFFC00104 /* System Configuration registe */
+#define SIC_RVECT 0xFFC00108
+#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
+#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
+#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
+#define SIC_IMASK1 0xFFC00128 /* Interrupt Mask Register 1 */
+#define SIC_ISR1 0xFFC0012C /* Interrupt Status Register 1 */
+#define SIC_IWR1 0xFFC00130 /* Interrupt Wakeup Register 1 */
+#define SIC_IAR4 0xFFC00134 /* Interrupt Assignment Register 4 */
+#define SIC_IAR5 0xFFC00138 /* Interrupt Assignment Register 5 */
+#define SIC_IAR6 0xFFC0013C /* Interrupt Assignment Register 6 */
+
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
+#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
+#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
+
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define RTC_STAT 0xFFC00300 /* RTC Status Register */
+#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
+#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
+#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
+#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
+#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
+#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Register (alternate macro) */
+
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART0_THR 0xFFC00400 /* Transmit Holding register */
+#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART0_LCR 0xFFC0040C /* Line Control Register */
+#define UART0_MCR 0xFFC00410 /* Modem Control Register */
+#define UART0_LSR 0xFFC00414 /* Line Status Register */
+#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART0_GCTL 0xFFC00424 /* Global Control Register */
+
+
+/* SPI0 Controller (0xFFC00500 - 0xFFC005FF) */
+
+#define SPI0_CTL 0xFFC00500 /* SPI0 Control Register */
+#define SPI0_FLG 0xFFC00504 /* SPI0 Flag register */
+#define SPI0_STAT 0xFFC00508 /* SPI0 Status register */
+#define SPI0_TDBR 0xFFC0050C /* SPI0 Transmit Data Buffer Register */
+#define SPI0_RDBR 0xFFC00510 /* SPI0 Receive Data Buffer Register */
+#define SPI0_BAUD 0xFFC00514 /* SPI0 Baud rate Register */
+#define SPI0_SHADOW 0xFFC00518 /* SPI0_RDBR Shadow Register */
+#define SPI0_REGBASE SPI0_CTL
+
+
+/* TIMER 0, 1, 2 Registers (0xFFC00600 - 0xFFC006FF) */
+#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
+
+#define TIMER_ENABLE 0xFFC00640 /* Timer Enable Register */
+#define TIMER_DISABLE 0xFFC00644 /* Timer Disable Register */
+#define TIMER_STATUS 0xFFC00648 /* Timer Status Register */
+
+
+/* Programmable Flags (0xFFC00700 - 0xFFC007FF) */
+#define FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */
+#define FIO_FLAG_C 0xFFC00704 /* Peripheral Interrupt Flag Register (clear) */
+#define FIO_FLAG_S 0xFFC00708 /* Peripheral Interrupt Flag Register (set) */
+#define FIO_FLAG_T 0xFFC0070C /* Flag Mask to directly toggle state of pins */
+#define FIO_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Register (set directly) */
+#define FIO_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Register (clear) */
+#define FIO_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Register (set) */
+#define FIO_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Register (toggle) */
+#define FIO_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Register (set directly) */
+#define FIO_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Register (clear) */
+#define FIO_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Register (set) */
+#define FIO_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Register (toggle) */
+#define FIO_DIR 0xFFC00730 /* Peripheral Flag Direction Register */
+#define FIO_POLAR 0xFFC00734 /* Flag Source Polarity Register */
+#define FIO_EDGE 0xFFC00738 /* Flag Source Sensitivity Register */
+#define FIO_BOTH 0xFFC0073C /* Flag Set on BOTH Edges Register */
+#define FIO_INEN 0xFFC00740 /* Flag Input Enable Register */
+
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+/* Asynchronous Memory Controller */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+
+/* SDRAM Controller */
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+
+
+/* DMA Controller 0 Traffic Control Registers (0xFFC00B00 - 0xFFC00BFF) */
+
+#define DMAC0_TC_PER 0xFFC00B0C /* DMA Controller 0 Traffic Control Periods Register */
+#define DMAC0_TC_CNT 0xFFC00B10 /* DMA Controller 0 Traffic Control Current Counts Register */
+
+
+
+/* DMA Controller 0 (0xFFC00C00 - 0xFFC00FFF) */
+
+#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
+#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
+#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
+#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
+#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
+#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
+#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
+#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
+#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
+#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
+#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
+#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
+#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
+
+#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
+#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
+#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
+#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
+#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
+#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
+#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
+#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
+#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
+#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
+#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
+#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
+#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
+
+#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
+#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
+#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
+#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
+#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
+#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
+#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
+#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
+#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
+#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
+#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
+#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
+#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
+
+#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
+#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
+#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
+#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
+#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
+#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
+#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
+#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
+#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
+#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
+#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
+#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
+#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
+
+#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
+#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
+#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
+#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
+#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
+#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
+#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
+#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
+#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
+#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
+#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
+#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
+#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
+
+#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
+#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
+#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
+#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
+#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
+#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
+#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
+#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
+#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
+#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
+#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
+#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
+#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
+
+#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
+#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
+#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
+#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
+#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
+#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
+#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
+#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
+#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
+#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
+#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
+#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
+#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
+
+#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
+#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
+#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
+#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
+#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
+#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
+#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
+#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
+#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
+#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
+#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
+#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
+#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
+
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00E00 /* MemDMA0 Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D0_START_ADDR 0xFFC00E04 /* MemDMA0 Stream 0 Destination Start Address Register */
+#define MDMA_D0_CONFIG 0xFFC00E08 /* MemDMA0 Stream 0 Destination Configuration Register */
+#define MDMA_D0_X_COUNT 0xFFC00E10 /* MemDMA0 Stream 0 Destination X Count Register */
+#define MDMA_D0_X_MODIFY 0xFFC00E14 /* MemDMA0 Stream 0 Destination X Modify Register */
+#define MDMA_D0_Y_COUNT 0xFFC00E18 /* MemDMA0 Stream 0 Destination Y Count Register */
+#define MDMA_D0_Y_MODIFY 0xFFC00E1C /* MemDMA0 Stream 0 Destination Y Modify Register */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00E20 /* MemDMA0 Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D0_CURR_ADDR 0xFFC00E24 /* MemDMA0 Stream 0 Destination Current Address Register */
+#define MDMA_D0_IRQ_STATUS 0xFFC00E28 /* MemDMA0 Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00E2C /* MemDMA0 Stream 0 Destination Peripheral Map Register */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00E30 /* MemDMA0 Stream 0 Destination Current X Count Register */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00E38 /* MemDMA0 Stream 0 Destination Current Y Count Register */
+
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00E40 /* MemDMA0 Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S0_START_ADDR 0xFFC00E44 /* MemDMA0 Stream 0 Source Start Address Register */
+#define MDMA_S0_CONFIG 0xFFC00E48 /* MemDMA0 Stream 0 Source Configuration Register */
+#define MDMA_S0_X_COUNT 0xFFC00E50 /* MemDMA0 Stream 0 Source X Count Register */
+#define MDMA_S0_X_MODIFY 0xFFC00E54 /* MemDMA0 Stream 0 Source X Modify Register */
+#define MDMA_S0_Y_COUNT 0xFFC00E58 /* MemDMA0 Stream 0 Source Y Count Register */
+#define MDMA_S0_Y_MODIFY 0xFFC00E5C /* MemDMA0 Stream 0 Source Y Modify Register */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00E60 /* MemDMA0 Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S0_CURR_ADDR 0xFFC00E64 /* MemDMA0 Stream 0 Source Current Address Register */
+#define MDMA_S0_IRQ_STATUS 0xFFC00E68 /* MemDMA0 Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00E6C /* MemDMA0 Stream 0 Source Peripheral Map Register */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00E70 /* MemDMA0 Stream 0 Source Current X Count Register */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00E78 /* MemDMA0 Stream 0 Source Current Y Count Register */
+
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00E80 /* MemDMA0 Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D1_START_ADDR 0xFFC00E84 /* MemDMA0 Stream 1 Destination Start Address Register */
+#define MDMA_D1_CONFIG 0xFFC00E88 /* MemDMA0 Stream 1 Destination Configuration Register */
+#define MDMA_D1_X_COUNT 0xFFC00E90 /* MemDMA0 Stream 1 Destination X Count Register */
+#define MDMA_D1_X_MODIFY 0xFFC00E94 /* MemDMA0 Stream 1 Destination X Modify Register */
+#define MDMA_D1_Y_COUNT 0xFFC00E98 /* MemDMA0 Stream 1 Destination Y Count Register */
+#define MDMA_D1_Y_MODIFY 0xFFC00E9C /* MemDMA0 Stream 1 Destination Y Modify Register */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00EA0 /* MemDMA0 Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D1_CURR_ADDR 0xFFC00EA4 /* MemDMA0 Stream 1 Destination Current Address Register */
+#define MDMA_D1_IRQ_STATUS 0xFFC00EA8 /* MemDMA0 Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00EAC /* MemDMA0 Stream 1 Destination Peripheral Map Register */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00EB0 /* MemDMA0 Stream 1 Destination Current X Count Register */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00EB8 /* MemDMA0 Stream 1 Destination Current Y Count Register */
+
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00EC0 /* MemDMA0 Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S1_START_ADDR 0xFFC00EC4 /* MemDMA0 Stream 1 Source Start Address Register */
+#define MDMA_S1_CONFIG 0xFFC00EC8 /* MemDMA0 Stream 1 Source Configuration Register */
+#define MDMA_S1_X_COUNT 0xFFC00ED0 /* MemDMA0 Stream 1 Source X Count Register */
+#define MDMA_S1_X_MODIFY 0xFFC00ED4 /* MemDMA0 Stream 1 Source X Modify Register */
+#define MDMA_S1_Y_COUNT 0xFFC00ED8 /* MemDMA0 Stream 1 Source Y Count Register */
+#define MDMA_S1_Y_MODIFY 0xFFC00EDC /* MemDMA0 Stream 1 Source Y Modify Register */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00EE0 /* MemDMA0 Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S1_CURR_ADDR 0xFFC00EE4 /* MemDMA0 Stream 1 Source Current Address Register */
+#define MDMA_S1_IRQ_STATUS 0xFFC00EE8 /* MemDMA0 Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00EEC /* MemDMA0 Stream 1 Source Peripheral Map Register */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00EF0 /* MemDMA0 Stream 1 Source Current X Count Register */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00EF8 /* MemDMA0 Stream 1 Source Current Y Count Register */
+
+
+/* Parallel Peripheral Interface (PPI) (0xFFC01000 - 0xFFC010FF) */
+#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
+#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
+#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
+#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
+#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
+
+
+/* Two-Wire Interface 0 (0xFFC01400 - 0xFFC014FF) */
+#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
+#define TWI0_CONTROL 0xFFC01404 /* TWI0 Master Internal Time Reference Register */
+#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
+#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
+#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
+#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
+#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
+#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
+#define TWI0_INT_STAT 0xFFC01420 /* TWI0 Master Interrupt Register */
+#define TWI0_INT_MASK 0xFFC01424 /* TWI0 Master Interrupt Mask Register */
+#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
+#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
+#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
+#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
+#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
+#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
+
+#define TWI0_REGBASE TWI0_CLKDIV
+
+/* the following are for backwards compatibility */
+#define TWI0_PRESCALE TWI0_CONTROL
+#define TWI0_INT_SRC TWI0_INT_STAT
+#define TWI0_INT_ENABLE TWI0_INT_MASK
+
+
+/* General-Purpose Ports (0xFFC01500 - 0xFFC015FF) */
+
+/* GPIO Port C Register Names */
+#define PORTCIO_FER 0xFFC01500 /* GPIO Pin Port C Configuration Register */
+#define PORTCIO 0xFFC01510 /* GPIO Pin Port C Data Register */
+#define PORTCIO_CLEAR 0xFFC01520 /* Clear GPIO Pin Port C Register */
+#define PORTCIO_SET 0xFFC01530 /* Set GPIO Pin Port C Register */
+#define PORTCIO_TOGGLE 0xFFC01540 /* Toggle GPIO Pin Port C Register */
+#define PORTCIO_DIR 0xFFC01550 /* GPIO Pin Port C Direction Register */
+#define PORTCIO_INEN 0xFFC01560 /* GPIO Pin Port C Input Enable Register */
+
+/* GPIO Port D Register Names */
+#define PORTDIO_FER 0xFFC01504 /* GPIO Pin Port D Configuration Register */
+#define PORTDIO 0xFFC01514 /* GPIO Pin Port D Data Register */
+#define PORTDIO_CLEAR 0xFFC01524 /* Clear GPIO Pin Port D Register */
+#define PORTDIO_SET 0xFFC01534 /* Set GPIO Pin Port D Register */
+#define PORTDIO_TOGGLE 0xFFC01544 /* Toggle GPIO Pin Port D Register */
+#define PORTDIO_DIR 0xFFC01554 /* GPIO Pin Port D Direction Register */
+#define PORTDIO_INEN 0xFFC01564 /* GPIO Pin Port D Input Enable Register */
+
+/* GPIO Port E Register Names */
+#define PORTEIO_FER 0xFFC01508 /* GPIO Pin Port E Configuration Register */
+#define PORTEIO 0xFFC01518 /* GPIO Pin Port E Data Register */
+#define PORTEIO_CLEAR 0xFFC01528 /* Clear GPIO Pin Port E Register */
+#define PORTEIO_SET 0xFFC01538 /* Set GPIO Pin Port E Register */
+#define PORTEIO_TOGGLE 0xFFC01548 /* Toggle GPIO Pin Port E Register */
+#define PORTEIO_DIR 0xFFC01558 /* GPIO Pin Port E Direction Register */
+#define PORTEIO_INEN 0xFFC01568 /* GPIO Pin Port E Input Enable Register */
+
+/* DMA Controller 1 Traffic Control Registers (0xFFC01B00 - 0xFFC01BFF) */
+
+#define DMAC1_TC_PER 0xFFC01B0C /* DMA Controller 1 Traffic Control Periods Register */
+#define DMAC1_TC_CNT 0xFFC01B10 /* DMA Controller 1 Traffic Control Current Counts Register */
+
+
+
+/* DMA Controller 1 (0xFFC01C00 - 0xFFC01FFF) */
+#define DMA8_NEXT_DESC_PTR 0xFFC01C00 /* DMA Channel 8 Next Descriptor Pointer Register */
+#define DMA8_START_ADDR 0xFFC01C04 /* DMA Channel 8 Start Address Register */
+#define DMA8_CONFIG 0xFFC01C08 /* DMA Channel 8 Configuration Register */
+#define DMA8_X_COUNT 0xFFC01C10 /* DMA Channel 8 X Count Register */
+#define DMA8_X_MODIFY 0xFFC01C14 /* DMA Channel 8 X Modify Register */
+#define DMA8_Y_COUNT 0xFFC01C18 /* DMA Channel 8 Y Count Register */
+#define DMA8_Y_MODIFY 0xFFC01C1C /* DMA Channel 8 Y Modify Register */
+#define DMA8_CURR_DESC_PTR 0xFFC01C20 /* DMA Channel 8 Current Descriptor Pointer Register */
+#define DMA8_CURR_ADDR 0xFFC01C24 /* DMA Channel 8 Current Address Register */
+#define DMA8_IRQ_STATUS 0xFFC01C28 /* DMA Channel 8 Interrupt/Status Register */
+#define DMA8_PERIPHERAL_MAP 0xFFC01C2C /* DMA Channel 8 Peripheral Map Register */
+#define DMA8_CURR_X_COUNT 0xFFC01C30 /* DMA Channel 8 Current X Count Register */
+#define DMA8_CURR_Y_COUNT 0xFFC01C38 /* DMA Channel 8 Current Y Count Register */
+
+#define DMA9_NEXT_DESC_PTR 0xFFC01C40 /* DMA Channel 9 Next Descriptor Pointer Register */
+#define DMA9_START_ADDR 0xFFC01C44 /* DMA Channel 9 Start Address Register */
+#define DMA9_CONFIG 0xFFC01C48 /* DMA Channel 9 Configuration Register */
+#define DMA9_X_COUNT 0xFFC01C50 /* DMA Channel 9 X Count Register */
+#define DMA9_X_MODIFY 0xFFC01C54 /* DMA Channel 9 X Modify Register */
+#define DMA9_Y_COUNT 0xFFC01C58 /* DMA Channel 9 Y Count Register */
+#define DMA9_Y_MODIFY 0xFFC01C5C /* DMA Channel 9 Y Modify Register */
+#define DMA9_CURR_DESC_PTR 0xFFC01C60 /* DMA Channel 9 Current Descriptor Pointer Register */
+#define DMA9_CURR_ADDR 0xFFC01C64 /* DMA Channel 9 Current Address Register */
+#define DMA9_IRQ_STATUS 0xFFC01C68 /* DMA Channel 9 Interrupt/Status Register */
+#define DMA9_PERIPHERAL_MAP 0xFFC01C6C /* DMA Channel 9 Peripheral Map Register */
+#define DMA9_CURR_X_COUNT 0xFFC01C70 /* DMA Channel 9 Current X Count Register */
+#define DMA9_CURR_Y_COUNT 0xFFC01C78 /* DMA Channel 9 Current Y Count Register */
+
+#define DMA10_NEXT_DESC_PTR 0xFFC01C80 /* DMA Channel 10 Next Descriptor Pointer Register */
+#define DMA10_START_ADDR 0xFFC01C84 /* DMA Channel 10 Start Address Register */
+#define DMA10_CONFIG 0xFFC01C88 /* DMA Channel 10 Configuration Register */
+#define DMA10_X_COUNT 0xFFC01C90 /* DMA Channel 10 X Count Register */
+#define DMA10_X_MODIFY 0xFFC01C94 /* DMA Channel 10 X Modify Register */
+#define DMA10_Y_COUNT 0xFFC01C98 /* DMA Channel 10 Y Count Register */
+#define DMA10_Y_MODIFY 0xFFC01C9C /* DMA Channel 10 Y Modify Register */
+#define DMA10_CURR_DESC_PTR 0xFFC01CA0 /* DMA Channel 10 Current Descriptor Pointer Register */
+#define DMA10_CURR_ADDR 0xFFC01CA4 /* DMA Channel 10 Current Address Register */
+#define DMA10_IRQ_STATUS 0xFFC01CA8 /* DMA Channel 10 Interrupt/Status Register */
+#define DMA10_PERIPHERAL_MAP 0xFFC01CAC /* DMA Channel 10 Peripheral Map Register */
+#define DMA10_CURR_X_COUNT 0xFFC01CB0 /* DMA Channel 10 Current X Count Register */
+#define DMA10_CURR_Y_COUNT 0xFFC01CB8 /* DMA Channel 10 Current Y Count Register */
+
+#define DMA11_NEXT_DESC_PTR 0xFFC01CC0 /* DMA Channel 11 Next Descriptor Pointer Register */
+#define DMA11_START_ADDR 0xFFC01CC4 /* DMA Channel 11 Start Address Register */
+#define DMA11_CONFIG 0xFFC01CC8 /* DMA Channel 11 Configuration Register */
+#define DMA11_X_COUNT 0xFFC01CD0 /* DMA Channel 11 X Count Register */
+#define DMA11_X_MODIFY 0xFFC01CD4 /* DMA Channel 11 X Modify Register */
+#define DMA11_Y_COUNT 0xFFC01CD8 /* DMA Channel 11 Y Count Register */
+#define DMA11_Y_MODIFY 0xFFC01CDC /* DMA Channel 11 Y Modify Register */
+#define DMA11_CURR_DESC_PTR 0xFFC01CE0 /* DMA Channel 11 Current Descriptor Pointer Register */
+#define DMA11_CURR_ADDR 0xFFC01CE4 /* DMA Channel 11 Current Address Register */
+#define DMA11_IRQ_STATUS 0xFFC01CE8 /* DMA Channel 11 Interrupt/Status Register */
+#define DMA11_PERIPHERAL_MAP 0xFFC01CEC /* DMA Channel 11 Peripheral Map Register */
+#define DMA11_CURR_X_COUNT 0xFFC01CF0 /* DMA Channel 11 Current X Count Register */
+#define DMA11_CURR_Y_COUNT 0xFFC01CF8 /* DMA Channel 11 Current Y Count Register */
+
+#define DMA12_NEXT_DESC_PTR 0xFFC01D00 /* DMA Channel 12 Next Descriptor Pointer Register */
+#define DMA12_START_ADDR 0xFFC01D04 /* DMA Channel 12 Start Address Register */
+#define DMA12_CONFIG 0xFFC01D08 /* DMA Channel 12 Configuration Register */
+#define DMA12_X_COUNT 0xFFC01D10 /* DMA Channel 12 X Count Register */
+#define DMA12_X_MODIFY 0xFFC01D14 /* DMA Channel 12 X Modify Register */
+#define DMA12_Y_COUNT 0xFFC01D18 /* DMA Channel 12 Y Count Register */
+#define DMA12_Y_MODIFY 0xFFC01D1C /* DMA Channel 12 Y Modify Register */
+#define DMA12_CURR_DESC_PTR 0xFFC01D20 /* DMA Channel 12 Current Descriptor Pointer Register */
+#define DMA12_CURR_ADDR 0xFFC01D24 /* DMA Channel 12 Current Address Register */
+#define DMA12_IRQ_STATUS 0xFFC01D28 /* DMA Channel 12 Interrupt/Status Register */
+#define DMA12_PERIPHERAL_MAP 0xFFC01D2C /* DMA Channel 12 Peripheral Map Register */
+#define DMA12_CURR_X_COUNT 0xFFC01D30 /* DMA Channel 12 Current X Count Register */
+#define DMA12_CURR_Y_COUNT 0xFFC01D38 /* DMA Channel 12 Current Y Count Register */
+
+#define DMA13_NEXT_DESC_PTR 0xFFC01D40 /* DMA Channel 13 Next Descriptor Pointer Register */
+#define DMA13_START_ADDR 0xFFC01D44 /* DMA Channel 13 Start Address Register */
+#define DMA13_CONFIG 0xFFC01D48 /* DMA Channel 13 Configuration Register */
+#define DMA13_X_COUNT 0xFFC01D50 /* DMA Channel 13 X Count Register */
+#define DMA13_X_MODIFY 0xFFC01D54 /* DMA Channel 13 X Modify Register */
+#define DMA13_Y_COUNT 0xFFC01D58 /* DMA Channel 13 Y Count Register */
+#define DMA13_Y_MODIFY 0xFFC01D5C /* DMA Channel 13 Y Modify Register */
+#define DMA13_CURR_DESC_PTR 0xFFC01D60 /* DMA Channel 13 Current Descriptor Pointer Register */
+#define DMA13_CURR_ADDR 0xFFC01D64 /* DMA Channel 13 Current Address Register */
+#define DMA13_IRQ_STATUS 0xFFC01D68 /* DMA Channel 13 Interrupt/Status Register */
+#define DMA13_PERIPHERAL_MAP 0xFFC01D6C /* DMA Channel 13 Peripheral Map Register */
+#define DMA13_CURR_X_COUNT 0xFFC01D70 /* DMA Channel 13 Current X Count Register */
+#define DMA13_CURR_Y_COUNT 0xFFC01D78 /* DMA Channel 13 Current Y Count Register */
+
+#define DMA14_NEXT_DESC_PTR 0xFFC01D80 /* DMA Channel 14 Next Descriptor Pointer Register */
+#define DMA14_START_ADDR 0xFFC01D84 /* DMA Channel 14 Start Address Register */
+#define DMA14_CONFIG 0xFFC01D88 /* DMA Channel 14 Configuration Register */
+#define DMA14_X_COUNT 0xFFC01D90 /* DMA Channel 14 X Count Register */
+#define DMA14_X_MODIFY 0xFFC01D94 /* DMA Channel 14 X Modify Register */
+#define DMA14_Y_COUNT 0xFFC01D98 /* DMA Channel 14 Y Count Register */
+#define DMA14_Y_MODIFY 0xFFC01D9C /* DMA Channel 14 Y Modify Register */
+#define DMA14_CURR_DESC_PTR 0xFFC01DA0 /* DMA Channel 14 Current Descriptor Pointer Register */
+#define DMA14_CURR_ADDR 0xFFC01DA4 /* DMA Channel 14 Current Address Register */
+#define DMA14_IRQ_STATUS 0xFFC01DA8 /* DMA Channel 14 Interrupt/Status Register */
+#define DMA14_PERIPHERAL_MAP 0xFFC01DAC /* DMA Channel 14 Peripheral Map Register */
+#define DMA14_CURR_X_COUNT 0xFFC01DB0 /* DMA Channel 14 Current X Count Register */
+#define DMA14_CURR_Y_COUNT 0xFFC01DB8 /* DMA Channel 14 Current Y Count Register */
+
+#define DMA15_NEXT_DESC_PTR 0xFFC01DC0 /* DMA Channel 15 Next Descriptor Pointer Register */
+#define DMA15_START_ADDR 0xFFC01DC4 /* DMA Channel 15 Start Address Register */
+#define DMA15_CONFIG 0xFFC01DC8 /* DMA Channel 15 Configuration Register */
+#define DMA15_X_COUNT 0xFFC01DD0 /* DMA Channel 15 X Count Register */
+#define DMA15_X_MODIFY 0xFFC01DD4 /* DMA Channel 15 X Modify Register */
+#define DMA15_Y_COUNT 0xFFC01DD8 /* DMA Channel 15 Y Count Register */
+#define DMA15_Y_MODIFY 0xFFC01DDC /* DMA Channel 15 Y Modify Register */
+#define DMA15_CURR_DESC_PTR 0xFFC01DE0 /* DMA Channel 15 Current Descriptor Pointer Register */
+#define DMA15_CURR_ADDR 0xFFC01DE4 /* DMA Channel 15 Current Address Register */
+#define DMA15_IRQ_STATUS 0xFFC01DE8 /* DMA Channel 15 Interrupt/Status Register */
+#define DMA15_PERIPHERAL_MAP 0xFFC01DEC /* DMA Channel 15 Peripheral Map Register */
+#define DMA15_CURR_X_COUNT 0xFFC01DF0 /* DMA Channel 15 Current X Count Register */
+#define DMA15_CURR_Y_COUNT 0xFFC01DF8 /* DMA Channel 15 Current Y Count Register */
+
+#define DMA16_NEXT_DESC_PTR 0xFFC01E00 /* DMA Channel 16 Next Descriptor Pointer Register */
+#define DMA16_START_ADDR 0xFFC01E04 /* DMA Channel 16 Start Address Register */
+#define DMA16_CONFIG 0xFFC01E08 /* DMA Channel 16 Configuration Register */
+#define DMA16_X_COUNT 0xFFC01E10 /* DMA Channel 16 X Count Register */
+#define DMA16_X_MODIFY 0xFFC01E14 /* DMA Channel 16 X Modify Register */
+#define DMA16_Y_COUNT 0xFFC01E18 /* DMA Channel 16 Y Count Register */
+#define DMA16_Y_MODIFY 0xFFC01E1C /* DMA Channel 16 Y Modify Register */
+#define DMA16_CURR_DESC_PTR 0xFFC01E20 /* DMA Channel 16 Current Descriptor Pointer Register */
+#define DMA16_CURR_ADDR 0xFFC01E24 /* DMA Channel 16 Current Address Register */
+#define DMA16_IRQ_STATUS 0xFFC01E28 /* DMA Channel 16 Interrupt/Status Register */
+#define DMA16_PERIPHERAL_MAP 0xFFC01E2C /* DMA Channel 16 Peripheral Map Register */
+#define DMA16_CURR_X_COUNT 0xFFC01E30 /* DMA Channel 16 Current X Count Register */
+#define DMA16_CURR_Y_COUNT 0xFFC01E38 /* DMA Channel 16 Current Y Count Register */
+
+#define DMA17_NEXT_DESC_PTR 0xFFC01E40 /* DMA Channel 17 Next Descriptor Pointer Register */
+#define DMA17_START_ADDR 0xFFC01E44 /* DMA Channel 17 Start Address Register */
+#define DMA17_CONFIG 0xFFC01E48 /* DMA Channel 17 Configuration Register */
+#define DMA17_X_COUNT 0xFFC01E50 /* DMA Channel 17 X Count Register */
+#define DMA17_X_MODIFY 0xFFC01E54 /* DMA Channel 17 X Modify Register */
+#define DMA17_Y_COUNT 0xFFC01E58 /* DMA Channel 17 Y Count Register */
+#define DMA17_Y_MODIFY 0xFFC01E5C /* DMA Channel 17 Y Modify Register */
+#define DMA17_CURR_DESC_PTR 0xFFC01E60 /* DMA Channel 17 Current Descriptor Pointer Register */
+#define DMA17_CURR_ADDR 0xFFC01E64 /* DMA Channel 17 Current Address Register */
+#define DMA17_IRQ_STATUS 0xFFC01E68 /* DMA Channel 17 Interrupt/Status Register */
+#define DMA17_PERIPHERAL_MAP 0xFFC01E6C /* DMA Channel 17 Peripheral Map Register */
+#define DMA17_CURR_X_COUNT 0xFFC01E70 /* DMA Channel 17 Current X Count Register */
+#define DMA17_CURR_Y_COUNT 0xFFC01E78 /* DMA Channel 17 Current Y Count Register */
+
+#define DMA18_NEXT_DESC_PTR 0xFFC01E80 /* DMA Channel 18 Next Descriptor Pointer Register */
+#define DMA18_START_ADDR 0xFFC01E84 /* DMA Channel 18 Start Address Register */
+#define DMA18_CONFIG 0xFFC01E88 /* DMA Channel 18 Configuration Register */
+#define DMA18_X_COUNT 0xFFC01E90 /* DMA Channel 18 X Count Register */
+#define DMA18_X_MODIFY 0xFFC01E94 /* DMA Channel 18 X Modify Register */
+#define DMA18_Y_COUNT 0xFFC01E98 /* DMA Channel 18 Y Count Register */
+#define DMA18_Y_MODIFY 0xFFC01E9C /* DMA Channel 18 Y Modify Register */
+#define DMA18_CURR_DESC_PTR 0xFFC01EA0 /* DMA Channel 18 Current Descriptor Pointer Register */
+#define DMA18_CURR_ADDR 0xFFC01EA4 /* DMA Channel 18 Current Address Register */
+#define DMA18_IRQ_STATUS 0xFFC01EA8 /* DMA Channel 18 Interrupt/Status Register */
+#define DMA18_PERIPHERAL_MAP 0xFFC01EAC /* DMA Channel 18 Peripheral Map Register */
+#define DMA18_CURR_X_COUNT 0xFFC01EB0 /* DMA Channel 18 Current X Count Register */
+#define DMA18_CURR_Y_COUNT 0xFFC01EB8 /* DMA Channel 18 Current Y Count Register */
+
+#define DMA19_NEXT_DESC_PTR 0xFFC01EC0 /* DMA Channel 19 Next Descriptor Pointer Register */
+#define DMA19_START_ADDR 0xFFC01EC4 /* DMA Channel 19 Start Address Register */
+#define DMA19_CONFIG 0xFFC01EC8 /* DMA Channel 19 Configuration Register */
+#define DMA19_X_COUNT 0xFFC01ED0 /* DMA Channel 19 X Count Register */
+#define DMA19_X_MODIFY 0xFFC01ED4 /* DMA Channel 19 X Modify Register */
+#define DMA19_Y_COUNT 0xFFC01ED8 /* DMA Channel 19 Y Count Register */
+#define DMA19_Y_MODIFY 0xFFC01EDC /* DMA Channel 19 Y Modify Register */
+#define DMA19_CURR_DESC_PTR 0xFFC01EE0 /* DMA Channel 19 Current Descriptor Pointer Register */
+#define DMA19_CURR_ADDR 0xFFC01EE4 /* DMA Channel 19 Current Address Register */
+#define DMA19_IRQ_STATUS 0xFFC01EE8 /* DMA Channel 19 Interrupt/Status Register */
+#define DMA19_PERIPHERAL_MAP 0xFFC01EEC /* DMA Channel 19 Peripheral Map Register */
+#define DMA19_CURR_X_COUNT 0xFFC01EF0 /* DMA Channel 19 Current X Count Register */
+#define DMA19_CURR_Y_COUNT 0xFFC01EF8 /* DMA Channel 19 Current Y Count Register */
+
+#define MDMA_D2_NEXT_DESC_PTR 0xFFC01F00 /* MemDMA1 Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D2_START_ADDR 0xFFC01F04 /* MemDMA1 Stream 0 Destination Start Address Register */
+#define MDMA_D2_CONFIG 0xFFC01F08 /* MemDMA1 Stream 0 Destination Configuration Register */
+#define MDMA_D2_X_COUNT 0xFFC01F10 /* MemDMA1 Stream 0 Destination X Count Register */
+#define MDMA_D2_X_MODIFY 0xFFC01F14 /* MemDMA1 Stream 0 Destination X Modify Register */
+#define MDMA_D2_Y_COUNT 0xFFC01F18 /* MemDMA1 Stream 0 Destination Y Count Register */
+#define MDMA_D2_Y_MODIFY 0xFFC01F1C /* MemDMA1 Stream 0 Destination Y Modify Register */
+#define MDMA_D2_CURR_DESC_PTR 0xFFC01F20 /* MemDMA1 Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D2_CURR_ADDR 0xFFC01F24 /* MemDMA1 Stream 0 Destination Current Address Register */
+#define MDMA_D2_IRQ_STATUS 0xFFC01F28 /* MemDMA1 Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D2_PERIPHERAL_MAP 0xFFC01F2C /* MemDMA1 Stream 0 Destination Peripheral Map Register */
+#define MDMA_D2_CURR_X_COUNT 0xFFC01F30 /* MemDMA1 Stream 0 Destination Current X Count Register */
+#define MDMA_D2_CURR_Y_COUNT 0xFFC01F38 /* MemDMA1 Stream 0 Destination Current Y Count Register */
+
+#define MDMA_S2_NEXT_DESC_PTR 0xFFC01F40 /* MemDMA1 Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S2_START_ADDR 0xFFC01F44 /* MemDMA1 Stream 0 Source Start Address Register */
+#define MDMA_S2_CONFIG 0xFFC01F48 /* MemDMA1 Stream 0 Source Configuration Register */
+#define MDMA_S2_X_COUNT 0xFFC01F50 /* MemDMA1 Stream 0 Source X Count Register */
+#define MDMA_S2_X_MODIFY 0xFFC01F54 /* MemDMA1 Stream 0 Source X Modify Register */
+#define MDMA_S2_Y_COUNT 0xFFC01F58 /* MemDMA1 Stream 0 Source Y Count Register */
+#define MDMA_S2_Y_MODIFY 0xFFC01F5C /* MemDMA1 Stream 0 Source Y Modify Register */
+#define MDMA_S2_CURR_DESC_PTR 0xFFC01F60 /* MemDMA1 Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S2_CURR_ADDR 0xFFC01F64 /* MemDMA1 Stream 0 Source Current Address Register */
+#define MDMA_S2_IRQ_STATUS 0xFFC01F68 /* MemDMA1 Stream 0 Source Interrupt/Status Register */
+#define MDMA_S2_PERIPHERAL_MAP 0xFFC01F6C /* MemDMA1 Stream 0 Source Peripheral Map Register */
+#define MDMA_S2_CURR_X_COUNT 0xFFC01F70 /* MemDMA1 Stream 0 Source Current X Count Register */
+#define MDMA_S2_CURR_Y_COUNT 0xFFC01F78 /* MemDMA1 Stream 0 Source Current Y Count Register */
+
+#define MDMA_D3_NEXT_DESC_PTR 0xFFC01F80 /* MemDMA1 Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D3_START_ADDR 0xFFC01F84 /* MemDMA1 Stream 1 Destination Start Address Register */
+#define MDMA_D3_CONFIG 0xFFC01F88 /* MemDMA1 Stream 1 Destination Configuration Register */
+#define MDMA_D3_X_COUNT 0xFFC01F90 /* MemDMA1 Stream 1 Destination X Count Register */
+#define MDMA_D3_X_MODIFY 0xFFC01F94 /* MemDMA1 Stream 1 Destination X Modify Register */
+#define MDMA_D3_Y_COUNT 0xFFC01F98 /* MemDMA1 Stream 1 Destination Y Count Register */
+#define MDMA_D3_Y_MODIFY 0xFFC01F9C /* MemDMA1 Stream 1 Destination Y Modify Register */
+#define MDMA_D3_CURR_DESC_PTR 0xFFC01FA0 /* MemDMA1 Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D3_CURR_ADDR 0xFFC01FA4 /* MemDMA1 Stream 1 Destination Current Address Register */
+#define MDMA_D3_IRQ_STATUS 0xFFC01FA8 /* MemDMA1 Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D3_PERIPHERAL_MAP 0xFFC01FAC /* MemDMA1 Stream 1 Destination Peripheral Map Register */
+#define MDMA_D3_CURR_X_COUNT 0xFFC01FB0 /* MemDMA1 Stream 1 Destination Current X Count Register */
+#define MDMA_D3_CURR_Y_COUNT 0xFFC01FB8 /* MemDMA1 Stream 1 Destination Current Y Count Register */
+
+#define MDMA_S3_NEXT_DESC_PTR 0xFFC01FC0 /* MemDMA1 Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S3_START_ADDR 0xFFC01FC4 /* MemDMA1 Stream 1 Source Start Address Register */
+#define MDMA_S3_CONFIG 0xFFC01FC8 /* MemDMA1 Stream 1 Source Configuration Register */
+#define MDMA_S3_X_COUNT 0xFFC01FD0 /* MemDMA1 Stream 1 Source X Count Register */
+#define MDMA_S3_X_MODIFY 0xFFC01FD4 /* MemDMA1 Stream 1 Source X Modify Register */
+#define MDMA_S3_Y_COUNT 0xFFC01FD8 /* MemDMA1 Stream 1 Source Y Count Register */
+#define MDMA_S3_Y_MODIFY 0xFFC01FDC /* MemDMA1 Stream 1 Source Y Modify Register */
+#define MDMA_S3_CURR_DESC_PTR 0xFFC01FE0 /* MemDMA1 Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S3_CURR_ADDR 0xFFC01FE4 /* MemDMA1 Stream 1 Source Current Address Register */
+#define MDMA_S3_IRQ_STATUS 0xFFC01FE8 /* MemDMA1 Stream 1 Source Interrupt/Status Register */
+#define MDMA_S3_PERIPHERAL_MAP 0xFFC01FEC /* MemDMA1 Stream 1 Source Peripheral Map Register */
+#define MDMA_S3_CURR_X_COUNT 0xFFC01FF0 /* MemDMA1 Stream 1 Source Current X Count Register */
+#define MDMA_S3_CURR_Y_COUNT 0xFFC01FF8 /* MemDMA1 Stream 1 Source Current Y Count Register */
+
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define UART1_THR 0xFFC02000 /* Transmit Holding register */
+#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
+#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
+#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
+#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
+#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
+#define UART1_LCR 0xFFC0200C /* Line Control Register */
+#define UART1_MCR 0xFFC02010 /* Modem Control Register */
+#define UART1_LSR 0xFFC02014 /* Line Status Register */
+#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
+#define UART1_GCTL 0xFFC02024 /* Global Control Register */
+
+
+/* UART2 Controller (0xFFC02100 - 0xFFC021FF) */
+#define UART2_THR 0xFFC02100 /* Transmit Holding register */
+#define UART2_RBR 0xFFC02100 /* Receive Buffer register */
+#define UART2_DLL 0xFFC02100 /* Divisor Latch (Low-Byte) */
+#define UART2_IER 0xFFC02104 /* Interrupt Enable Register */
+#define UART2_DLH 0xFFC02104 /* Divisor Latch (High-Byte) */
+#define UART2_IIR 0xFFC02108 /* Interrupt Identification Register */
+#define UART2_LCR 0xFFC0210C /* Line Control Register */
+#define UART2_MCR 0xFFC02110 /* Modem Control Register */
+#define UART2_LSR 0xFFC02114 /* Line Status Register */
+#define UART2_SCR 0xFFC0211C /* SCR Scratch Register */
+#define UART2_GCTL 0xFFC02124 /* Global Control Register */
+
+
+/* Two-Wire Interface 1 (0xFFC02200 - 0xFFC022FF) */
+#define TWI1_CLKDIV 0xFFC02200 /* Serial Clock Divider Register */
+#define TWI1_CONTROL 0xFFC02204 /* TWI1 Master Internal Time Reference Register */
+#define TWI1_SLAVE_CTL 0xFFC02208 /* Slave Mode Control Register */
+#define TWI1_SLAVE_STAT 0xFFC0220C /* Slave Mode Status Register */
+#define TWI1_SLAVE_ADDR 0xFFC02210 /* Slave Mode Address Register */
+#define TWI1_MASTER_CTL 0xFFC02214 /* Master Mode Control Register */
+#define TWI1_MASTER_STAT 0xFFC02218 /* Master Mode Status Register */
+#define TWI1_MASTER_ADDR 0xFFC0221C /* Master Mode Address Register */
+#define TWI1_INT_STAT 0xFFC02220 /* TWI1 Master Interrupt Register */
+#define TWI1_INT_MASK 0xFFC02224 /* TWI1 Master Interrupt Mask Register */
+#define TWI1_FIFO_CTL 0xFFC02228 /* FIFO Control Register */
+#define TWI1_FIFO_STAT 0xFFC0222C /* FIFO Status Register */
+#define TWI1_XMT_DATA8 0xFFC02280 /* FIFO Transmit Data Single Byte Register */
+#define TWI1_XMT_DATA16 0xFFC02284 /* FIFO Transmit Data Double Byte Register */
+#define TWI1_RCV_DATA8 0xFFC02288 /* FIFO Receive Data Single Byte Register */
+#define TWI1_RCV_DATA16 0xFFC0228C /* FIFO Receive Data Double Byte Register */
+#define TWI1_REGBASE TWI1_CLKDIV
+
+
+/* the following are for backwards compatibility */
+#define TWI1_PRESCALE TWI1_CONTROL
+#define TWI1_INT_SRC TWI1_INT_STAT
+#define TWI1_INT_ENABLE TWI1_INT_MASK
+
+
+/* SPI1 Controller (0xFFC02300 - 0xFFC023FF) */
+#define SPI1_CTL 0xFFC02300 /* SPI1 Control Register */
+#define SPI1_FLG 0xFFC02304 /* SPI1 Flag register */
+#define SPI1_STAT 0xFFC02308 /* SPI1 Status register */
+#define SPI1_TDBR 0xFFC0230C /* SPI1 Transmit Data Buffer Register */
+#define SPI1_RDBR 0xFFC02310 /* SPI1 Receive Data Buffer Register */
+#define SPI1_BAUD 0xFFC02314 /* SPI1 Baud rate Register */
+#define SPI1_SHADOW 0xFFC02318 /* SPI1_RDBR Shadow Register */
+#define SPI1_REGBASE SPI1_CTL
+
+/* SPI2 Controller (0xFFC02400 - 0xFFC024FF) */
+#define SPI2_CTL 0xFFC02400 /* SPI2 Control Register */
+#define SPI2_FLG 0xFFC02404 /* SPI2 Flag register */
+#define SPI2_STAT 0xFFC02408 /* SPI2 Status register */
+#define SPI2_TDBR 0xFFC0240C /* SPI2 Transmit Data Buffer Register */
+#define SPI2_RDBR 0xFFC02410 /* SPI2 Receive Data Buffer Register */
+#define SPI2_BAUD 0xFFC02414 /* SPI2 Baud rate Register */
+#define SPI2_SHADOW 0xFFC02418 /* SPI2_RDBR Shadow Register */
+#define SPI2_REGBASE SPI2_CTL
+
+/* SPORT2 Controller (0xFFC02500 - 0xFFC025FF) */
+#define SPORT2_TCR1 0xFFC02500 /* SPORT2 Transmit Configuration 1 Register */
+#define SPORT2_TCR2 0xFFC02504 /* SPORT2 Transmit Configuration 2 Register */
+#define SPORT2_TCLKDIV 0xFFC02508 /* SPORT2 Transmit Clock Divider */
+#define SPORT2_TFSDIV 0xFFC0250C /* SPORT2 Transmit Frame Sync Divider */
+#define SPORT2_TX 0xFFC02510 /* SPORT2 TX Data Register */
+#define SPORT2_RX 0xFFC02518 /* SPORT2 RX Data Register */
+#define SPORT2_RCR1 0xFFC02520 /* SPORT2 Transmit Configuration 1 Register */
+#define SPORT2_RCR2 0xFFC02524 /* SPORT2 Transmit Configuration 2 Register */
+#define SPORT2_RCLKDIV 0xFFC02528 /* SPORT2 Receive Clock Divider */
+#define SPORT2_RFSDIV 0xFFC0252C /* SPORT2 Receive Frame Sync Divider */
+#define SPORT2_STAT 0xFFC02530 /* SPORT2 Status Register */
+#define SPORT2_CHNL 0xFFC02534 /* SPORT2 Current Channel Register */
+#define SPORT2_MCMC1 0xFFC02538 /* SPORT2 Multi-Channel Configuration Register 1 */
+#define SPORT2_MCMC2 0xFFC0253C /* SPORT2 Multi-Channel Configuration Register 2 */
+#define SPORT2_MTCS0 0xFFC02540 /* SPORT2 Multi-Channel Transmit Select Register 0 */
+#define SPORT2_MTCS1 0xFFC02544 /* SPORT2 Multi-Channel Transmit Select Register 1 */
+#define SPORT2_MTCS2 0xFFC02548 /* SPORT2 Multi-Channel Transmit Select Register 2 */
+#define SPORT2_MTCS3 0xFFC0254C /* SPORT2 Multi-Channel Transmit Select Register 3 */
+#define SPORT2_MRCS0 0xFFC02550 /* SPORT2 Multi-Channel Receive Select Register 0 */
+#define SPORT2_MRCS1 0xFFC02554 /* SPORT2 Multi-Channel Receive Select Register 1 */
+#define SPORT2_MRCS2 0xFFC02558 /* SPORT2 Multi-Channel Receive Select Register 2 */
+#define SPORT2_MRCS3 0xFFC0255C /* SPORT2 Multi-Channel Receive Select Register 3 */
+
+
+/* SPORT3 Controller (0xFFC02600 - 0xFFC026FF) */
+#define SPORT3_TCR1 0xFFC02600 /* SPORT3 Transmit Configuration 1 Register */
+#define SPORT3_TCR2 0xFFC02604 /* SPORT3 Transmit Configuration 2 Register */
+#define SPORT3_TCLKDIV 0xFFC02608 /* SPORT3 Transmit Clock Divider */
+#define SPORT3_TFSDIV 0xFFC0260C /* SPORT3 Transmit Frame Sync Divider */
+#define SPORT3_TX 0xFFC02610 /* SPORT3 TX Data Register */
+#define SPORT3_RX 0xFFC02618 /* SPORT3 RX Data Register */
+#define SPORT3_RCR1 0xFFC02620 /* SPORT3 Transmit Configuration 1 Register */
+#define SPORT3_RCR2 0xFFC02624 /* SPORT3 Transmit Configuration 2 Register */
+#define SPORT3_RCLKDIV 0xFFC02628 /* SPORT3 Receive Clock Divider */
+#define SPORT3_RFSDIV 0xFFC0262C /* SPORT3 Receive Frame Sync Divider */
+#define SPORT3_STAT 0xFFC02630 /* SPORT3 Status Register */
+#define SPORT3_CHNL 0xFFC02634 /* SPORT3 Current Channel Register */
+#define SPORT3_MCMC1 0xFFC02638 /* SPORT3 Multi-Channel Configuration Register 1 */
+#define SPORT3_MCMC2 0xFFC0263C /* SPORT3 Multi-Channel Configuration Register 2 */
+#define SPORT3_MTCS0 0xFFC02640 /* SPORT3 Multi-Channel Transmit Select Register 0 */
+#define SPORT3_MTCS1 0xFFC02644 /* SPORT3 Multi-Channel Transmit Select Register 1 */
+#define SPORT3_MTCS2 0xFFC02648 /* SPORT3 Multi-Channel Transmit Select Register 2 */
+#define SPORT3_MTCS3 0xFFC0264C /* SPORT3 Multi-Channel Transmit Select Register 3 */
+#define SPORT3_MRCS0 0xFFC02650 /* SPORT3 Multi-Channel Receive Select Register 0 */
+#define SPORT3_MRCS1 0xFFC02654 /* SPORT3 Multi-Channel Receive Select Register 1 */
+#define SPORT3_MRCS2 0xFFC02658 /* SPORT3 Multi-Channel Receive Select Register 2 */
+#define SPORT3_MRCS3 0xFFC0265C /* SPORT3 Multi-Channel Receive Select Register 3 */
+
+
+/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */
+/* For Mailboxes 0-15 */
+#define CAN_MC1 0xFFC02A00 /* Mailbox config reg 1 */
+#define CAN_MD1 0xFFC02A04 /* Mailbox direction reg 1 */
+#define CAN_TRS1 0xFFC02A08 /* Transmit Request Set reg 1 */
+#define CAN_TRR1 0xFFC02A0C /* Transmit Request Reset reg 1 */
+#define CAN_TA1 0xFFC02A10 /* Transmit Acknowledge reg 1 */
+#define CAN_AA1 0xFFC02A14 /* Transmit Abort Acknowledge reg 1 */
+#define CAN_RMP1 0xFFC02A18 /* Receive Message Pending reg 1 */
+#define CAN_RML1 0xFFC02A1C /* Receive Message Lost reg 1 */
+#define CAN_MBTIF1 0xFFC02A20 /* Mailbox Transmit Interrupt Flag reg 1 */
+#define CAN_MBRIF1 0xFFC02A24 /* Mailbox Receive Interrupt Flag reg 1 */
+#define CAN_MBIM1 0xFFC02A28 /* Mailbox Interrupt Mask reg 1 */
+#define CAN_RFH1 0xFFC02A2C /* Remote Frame Handling reg 1 */
+#define CAN_OPSS1 0xFFC02A30 /* Overwrite Protection Single Shot Xmission reg 1 */
+
+/* For Mailboxes 16-31 */
+#define CAN_MC2 0xFFC02A40 /* Mailbox config reg 2 */
+#define CAN_MD2 0xFFC02A44 /* Mailbox direction reg 2 */
+#define CAN_TRS2 0xFFC02A48 /* Transmit Request Set reg 2 */
+#define CAN_TRR2 0xFFC02A4C /* Transmit Request Reset reg 2 */
+#define CAN_TA2 0xFFC02A50 /* Transmit Acknowledge reg 2 */
+#define CAN_AA2 0xFFC02A54 /* Transmit Abort Acknowledge reg 2 */
+#define CAN_RMP2 0xFFC02A58 /* Receive Message Pending reg 2 */
+#define CAN_RML2 0xFFC02A5C /* Receive Message Lost reg 2 */
+#define CAN_MBTIF2 0xFFC02A60 /* Mailbox Transmit Interrupt Flag reg 2 */
+#define CAN_MBRIF2 0xFFC02A64 /* Mailbox Receive Interrupt Flag reg 2 */
+#define CAN_MBIM2 0xFFC02A68 /* Mailbox Interrupt Mask reg 2 */
+#define CAN_RFH2 0xFFC02A6C /* Remote Frame Handling reg 2 */
+#define CAN_OPSS2 0xFFC02A70 /* Overwrite Protection Single Shot Xmission reg 2 */
+
+#define CAN_CLOCK 0xFFC02A80 /* Bit Timing Configuration register 0 */
+#define CAN_TIMING 0xFFC02A84 /* Bit Timing Configuration register 1 */
+
+#define CAN_DEBUG 0xFFC02A88 /* Debug Register */
+/* the following is for backwards compatibility */
+#define CAN_CNF CAN_DEBUG
+
+#define CAN_STATUS 0xFFC02A8C /* Global Status Register */
+#define CAN_CEC 0xFFC02A90 /* Error Counter Register */
+#define CAN_GIS 0xFFC02A94 /* Global Interrupt Status Register */
+#define CAN_GIM 0xFFC02A98 /* Global Interrupt Mask Register */
+#define CAN_GIF 0xFFC02A9C /* Global Interrupt Flag Register */
+#define CAN_CONTROL 0xFFC02AA0 /* Master Control Register */
+#define CAN_INTR 0xFFC02AA4 /* Interrupt Pending Register */
+#define CAN_MBTD 0xFFC02AAC /* Mailbox Temporary Disable Feature */
+#define CAN_EWR 0xFFC02AB0 /* Programmable Warning Level */
+#define CAN_ESR 0xFFC02AB4 /* Error Status Register */
+#define CAN_UCCNT 0xFFC02AC4 /* Universal Counter */
+#define CAN_UCRC 0xFFC02AC8 /* Universal Counter Reload/Capture Register */
+#define CAN_UCCNF 0xFFC02ACC /* Universal Counter Configuration Register */
+
+/* Mailbox Acceptance Masks */
+#define CAN_AM00L 0xFFC02B00 /* Mailbox 0 Low Acceptance Mask */
+#define CAN_AM00H 0xFFC02B04 /* Mailbox 0 High Acceptance Mask */
+#define CAN_AM01L 0xFFC02B08 /* Mailbox 1 Low Acceptance Mask */
+#define CAN_AM01H 0xFFC02B0C /* Mailbox 1 High Acceptance Mask */
+#define CAN_AM02L 0xFFC02B10 /* Mailbox 2 Low Acceptance Mask */
+#define CAN_AM02H 0xFFC02B14 /* Mailbox 2 High Acceptance Mask */
+#define CAN_AM03L 0xFFC02B18 /* Mailbox 3 Low Acceptance Mask */
+#define CAN_AM03H 0xFFC02B1C /* Mailbox 3 High Acceptance Mask */
+#define CAN_AM04L 0xFFC02B20 /* Mailbox 4 Low Acceptance Mask */
+#define CAN_AM04H 0xFFC02B24 /* Mailbox 4 High Acceptance Mask */
+#define CAN_AM05L 0xFFC02B28 /* Mailbox 5 Low Acceptance Mask */
+#define CAN_AM05H 0xFFC02B2C /* Mailbox 5 High Acceptance Mask */
+#define CAN_AM06L 0xFFC02B30 /* Mailbox 6 Low Acceptance Mask */
+#define CAN_AM06H 0xFFC02B34 /* Mailbox 6 High Acceptance Mask */
+#define CAN_AM07L 0xFFC02B38 /* Mailbox 7 Low Acceptance Mask */
+#define CAN_AM07H 0xFFC02B3C /* Mailbox 7 High Acceptance Mask */
+#define CAN_AM08L 0xFFC02B40 /* Mailbox 8 Low Acceptance Mask */
+#define CAN_AM08H 0xFFC02B44 /* Mailbox 8 High Acceptance Mask */
+#define CAN_AM09L 0xFFC02B48 /* Mailbox 9 Low Acceptance Mask */
+#define CAN_AM09H 0xFFC02B4C /* Mailbox 9 High Acceptance Mask */
+#define CAN_AM10L 0xFFC02B50 /* Mailbox 10 Low Acceptance Mask */
+#define CAN_AM10H 0xFFC02B54 /* Mailbox 10 High Acceptance Mask */
+#define CAN_AM11L 0xFFC02B58 /* Mailbox 11 Low Acceptance Mask */
+#define CAN_AM11H 0xFFC02B5C /* Mailbox 11 High Acceptance Mask */
+#define CAN_AM12L 0xFFC02B60 /* Mailbox 12 Low Acceptance Mask */
+#define CAN_AM12H 0xFFC02B64 /* Mailbox 12 High Acceptance Mask */
+#define CAN_AM13L 0xFFC02B68 /* Mailbox 13 Low Acceptance Mask */
+#define CAN_AM13H 0xFFC02B6C /* Mailbox 13 High Acceptance Mask */
+#define CAN_AM14L 0xFFC02B70 /* Mailbox 14 Low Acceptance Mask */
+#define CAN_AM14H 0xFFC02B74 /* Mailbox 14 High Acceptance Mask */
+#define CAN_AM15L 0xFFC02B78 /* Mailbox 15 Low Acceptance Mask */
+#define CAN_AM15H 0xFFC02B7C /* Mailbox 15 High Acceptance Mask */
+
+#define CAN_AM16L 0xFFC02B80 /* Mailbox 16 Low Acceptance Mask */
+#define CAN_AM16H 0xFFC02B84 /* Mailbox 16 High Acceptance Mask */
+#define CAN_AM17L 0xFFC02B88 /* Mailbox 17 Low Acceptance Mask */
+#define CAN_AM17H 0xFFC02B8C /* Mailbox 17 High Acceptance Mask */
+#define CAN_AM18L 0xFFC02B90 /* Mailbox 18 Low Acceptance Mask */
+#define CAN_AM18H 0xFFC02B94 /* Mailbox 18 High Acceptance Mask */
+#define CAN_AM19L 0xFFC02B98 /* Mailbox 19 Low Acceptance Mask */
+#define CAN_AM19H 0xFFC02B9C /* Mailbox 19 High Acceptance Mask */
+#define CAN_AM20L 0xFFC02BA0 /* Mailbox 20 Low Acceptance Mask */
+#define CAN_AM20H 0xFFC02BA4 /* Mailbox 20 High Acceptance Mask */
+#define CAN_AM21L 0xFFC02BA8 /* Mailbox 21 Low Acceptance Mask */
+#define CAN_AM21H 0xFFC02BAC /* Mailbox 21 High Acceptance Mask */
+#define CAN_AM22L 0xFFC02BB0 /* Mailbox 22 Low Acceptance Mask */
+#define CAN_AM22H 0xFFC02BB4 /* Mailbox 22 High Acceptance Mask */
+#define CAN_AM23L 0xFFC02BB8 /* Mailbox 23 Low Acceptance Mask */
+#define CAN_AM23H 0xFFC02BBC /* Mailbox 23 High Acceptance Mask */
+#define CAN_AM24L 0xFFC02BC0 /* Mailbox 24 Low Acceptance Mask */
+#define CAN_AM24H 0xFFC02BC4 /* Mailbox 24 High Acceptance Mask */
+#define CAN_AM25L 0xFFC02BC8 /* Mailbox 25 Low Acceptance Mask */
+#define CAN_AM25H 0xFFC02BCC /* Mailbox 25 High Acceptance Mask */
+#define CAN_AM26L 0xFFC02BD0 /* Mailbox 26 Low Acceptance Mask */
+#define CAN_AM26H 0xFFC02BD4 /* Mailbox 26 High Acceptance Mask */
+#define CAN_AM27L 0xFFC02BD8 /* Mailbox 27 Low Acceptance Mask */
+#define CAN_AM27H 0xFFC02BDC /* Mailbox 27 High Acceptance Mask */
+#define CAN_AM28L 0xFFC02BE0 /* Mailbox 28 Low Acceptance Mask */
+#define CAN_AM28H 0xFFC02BE4 /* Mailbox 28 High Acceptance Mask */
+#define CAN_AM29L 0xFFC02BE8 /* Mailbox 29 Low Acceptance Mask */
+#define CAN_AM29H 0xFFC02BEC /* Mailbox 29 High Acceptance Mask */
+#define CAN_AM30L 0xFFC02BF0 /* Mailbox 30 Low Acceptance Mask */
+#define CAN_AM30H 0xFFC02BF4 /* Mailbox 30 High Acceptance Mask */
+#define CAN_AM31L 0xFFC02BF8 /* Mailbox 31 Low Acceptance Mask */
+#define CAN_AM31H 0xFFC02BFC /* Mailbox 31 High Acceptance Mask */
+
+/* CAN Acceptance Mask Macros */
+#define CAN_AM_L(x) (CAN_AM00L+((x)*0x8))
+#define CAN_AM_H(x) (CAN_AM00H+((x)*0x8))
+
+/* Mailbox Registers */
+#define CAN_MB00_DATA0 0xFFC02C00 /* Mailbox 0 Data Word 0 [15:0] Register */
+#define CAN_MB00_DATA1 0xFFC02C04 /* Mailbox 0 Data Word 1 [31:16] Register */
+#define CAN_MB00_DATA2 0xFFC02C08 /* Mailbox 0 Data Word 2 [47:32] Register */
+#define CAN_MB00_DATA3 0xFFC02C0C /* Mailbox 0 Data Word 3 [63:48] Register */
+#define CAN_MB00_LENGTH 0xFFC02C10 /* Mailbox 0 Data Length Code Register */
+#define CAN_MB00_TIMESTAMP 0xFFC02C14 /* Mailbox 0 Time Stamp Value Register */
+#define CAN_MB00_ID0 0xFFC02C18 /* Mailbox 0 Identifier Low Register */
+#define CAN_MB00_ID1 0xFFC02C1C /* Mailbox 0 Identifier High Register */
+
+#define CAN_MB01_DATA0 0xFFC02C20 /* Mailbox 1 Data Word 0 [15:0] Register */
+#define CAN_MB01_DATA1 0xFFC02C24 /* Mailbox 1 Data Word 1 [31:16] Register */
+#define CAN_MB01_DATA2 0xFFC02C28 /* Mailbox 1 Data Word 2 [47:32] Register */
+#define CAN_MB01_DATA3 0xFFC02C2C /* Mailbox 1 Data Word 3 [63:48] Register */
+#define CAN_MB01_LENGTH 0xFFC02C30 /* Mailbox 1 Data Length Code Register */
+#define CAN_MB01_TIMESTAMP 0xFFC02C34 /* Mailbox 1 Time Stamp Value Register */
+#define CAN_MB01_ID0 0xFFC02C38 /* Mailbox 1 Identifier Low Register */
+#define CAN_MB01_ID1 0xFFC02C3C /* Mailbox 1 Identifier High Register */
+
+#define CAN_MB02_DATA0 0xFFC02C40 /* Mailbox 2 Data Word 0 [15:0] Register */
+#define CAN_MB02_DATA1 0xFFC02C44 /* Mailbox 2 Data Word 1 [31:16] Register */
+#define CAN_MB02_DATA2 0xFFC02C48 /* Mailbox 2 Data Word 2 [47:32] Register */
+#define CAN_MB02_DATA3 0xFFC02C4C /* Mailbox 2 Data Word 3 [63:48] Register */
+#define CAN_MB02_LENGTH 0xFFC02C50 /* Mailbox 2 Data Length Code Register */
+#define CAN_MB02_TIMESTAMP 0xFFC02C54 /* Mailbox 2 Time Stamp Value Register */
+#define CAN_MB02_ID0 0xFFC02C58 /* Mailbox 2 Identifier Low Register */
+#define CAN_MB02_ID1 0xFFC02C5C /* Mailbox 2 Identifier High Register */
+
+#define CAN_MB03_DATA0 0xFFC02C60 /* Mailbox 3 Data Word 0 [15:0] Register */
+#define CAN_MB03_DATA1 0xFFC02C64 /* Mailbox 3 Data Word 1 [31:16] Register */
+#define CAN_MB03_DATA2 0xFFC02C68 /* Mailbox 3 Data Word 2 [47:32] Register */
+#define CAN_MB03_DATA3 0xFFC02C6C /* Mailbox 3 Data Word 3 [63:48] Register */
+#define CAN_MB03_LENGTH 0xFFC02C70 /* Mailbox 3 Data Length Code Register */
+#define CAN_MB03_TIMESTAMP 0xFFC02C74 /* Mailbox 3 Time Stamp Value Register */
+#define CAN_MB03_ID0 0xFFC02C78 /* Mailbox 3 Identifier Low Register */
+#define CAN_MB03_ID1 0xFFC02C7C /* Mailbox 3 Identifier High Register */
+
+#define CAN_MB04_DATA0 0xFFC02C80 /* Mailbox 4 Data Word 0 [15:0] Register */
+#define CAN_MB04_DATA1 0xFFC02C84 /* Mailbox 4 Data Word 1 [31:16] Register */
+#define CAN_MB04_DATA2 0xFFC02C88 /* Mailbox 4 Data Word 2 [47:32] Register */
+#define CAN_MB04_DATA3 0xFFC02C8C /* Mailbox 4 Data Word 3 [63:48] Register */
+#define CAN_MB04_LENGTH 0xFFC02C90 /* Mailbox 4 Data Length Code Register */
+#define CAN_MB04_TIMESTAMP 0xFFC02C94 /* Mailbox 4 Time Stamp Value Register */
+#define CAN_MB04_ID0 0xFFC02C98 /* Mailbox 4 Identifier Low Register */
+#define CAN_MB04_ID1 0xFFC02C9C /* Mailbox 4 Identifier High Register */
+
+#define CAN_MB05_DATA0 0xFFC02CA0 /* Mailbox 5 Data Word 0 [15:0] Register */
+#define CAN_MB05_DATA1 0xFFC02CA4 /* Mailbox 5 Data Word 1 [31:16] Register */
+#define CAN_MB05_DATA2 0xFFC02CA8 /* Mailbox 5 Data Word 2 [47:32] Register */
+#define CAN_MB05_DATA3 0xFFC02CAC /* Mailbox 5 Data Word 3 [63:48] Register */
+#define CAN_MB05_LENGTH 0xFFC02CB0 /* Mailbox 5 Data Length Code Register */
+#define CAN_MB05_TIMESTAMP 0xFFC02CB4 /* Mailbox 5 Time Stamp Value Register */
+#define CAN_MB05_ID0 0xFFC02CB8 /* Mailbox 5 Identifier Low Register */
+#define CAN_MB05_ID1 0xFFC02CBC /* Mailbox 5 Identifier High Register */
+
+#define CAN_MB06_DATA0 0xFFC02CC0 /* Mailbox 6 Data Word 0 [15:0] Register */
+#define CAN_MB06_DATA1 0xFFC02CC4 /* Mailbox 6 Data Word 1 [31:16] Register */
+#define CAN_MB06_DATA2 0xFFC02CC8 /* Mailbox 6 Data Word 2 [47:32] Register */
+#define CAN_MB06_DATA3 0xFFC02CCC /* Mailbox 6 Data Word 3 [63:48] Register */
+#define CAN_MB06_LENGTH 0xFFC02CD0 /* Mailbox 6 Data Length Code Register */
+#define CAN_MB06_TIMESTAMP 0xFFC02CD4 /* Mailbox 6 Time Stamp Value Register */
+#define CAN_MB06_ID0 0xFFC02CD8 /* Mailbox 6 Identifier Low Register */
+#define CAN_MB06_ID1 0xFFC02CDC /* Mailbox 6 Identifier High Register */
+
+#define CAN_MB07_DATA0 0xFFC02CE0 /* Mailbox 7 Data Word 0 [15:0] Register */
+#define CAN_MB07_DATA1 0xFFC02CE4 /* Mailbox 7 Data Word 1 [31:16] Register */
+#define CAN_MB07_DATA2 0xFFC02CE8 /* Mailbox 7 Data Word 2 [47:32] Register */
+#define CAN_MB07_DATA3 0xFFC02CEC /* Mailbox 7 Data Word 3 [63:48] Register */
+#define CAN_MB07_LENGTH 0xFFC02CF0 /* Mailbox 7 Data Length Code Register */
+#define CAN_MB07_TIMESTAMP 0xFFC02CF4 /* Mailbox 7 Time Stamp Value Register */
+#define CAN_MB07_ID0 0xFFC02CF8 /* Mailbox 7 Identifier Low Register */
+#define CAN_MB07_ID1 0xFFC02CFC /* Mailbox 7 Identifier High Register */
+
+#define CAN_MB08_DATA0 0xFFC02D00 /* Mailbox 8 Data Word 0 [15:0] Register */
+#define CAN_MB08_DATA1 0xFFC02D04 /* Mailbox 8 Data Word 1 [31:16] Register */
+#define CAN_MB08_DATA2 0xFFC02D08 /* Mailbox 8 Data Word 2 [47:32] Register */
+#define CAN_MB08_DATA3 0xFFC02D0C /* Mailbox 8 Data Word 3 [63:48] Register */
+#define CAN_MB08_LENGTH 0xFFC02D10 /* Mailbox 8 Data Length Code Register */
+#define CAN_MB08_TIMESTAMP 0xFFC02D14 /* Mailbox 8 Time Stamp Value Register */
+#define CAN_MB08_ID0 0xFFC02D18 /* Mailbox 8 Identifier Low Register */
+#define CAN_MB08_ID1 0xFFC02D1C /* Mailbox 8 Identifier High Register */
+
+#define CAN_MB09_DATA0 0xFFC02D20 /* Mailbox 9 Data Word 0 [15:0] Register */
+#define CAN_MB09_DATA1 0xFFC02D24 /* Mailbox 9 Data Word 1 [31:16] Register */
+#define CAN_MB09_DATA2 0xFFC02D28 /* Mailbox 9 Data Word 2 [47:32] Register */
+#define CAN_MB09_DATA3 0xFFC02D2C /* Mailbox 9 Data Word 3 [63:48] Register */
+#define CAN_MB09_LENGTH 0xFFC02D30 /* Mailbox 9 Data Length Code Register */
+#define CAN_MB09_TIMESTAMP 0xFFC02D34 /* Mailbox 9 Time Stamp Value Register */
+#define CAN_MB09_ID0 0xFFC02D38 /* Mailbox 9 Identifier Low Register */
+#define CAN_MB09_ID1 0xFFC02D3C /* Mailbox 9 Identifier High Register */
+
+#define CAN_MB10_DATA0 0xFFC02D40 /* Mailbox 10 Data Word 0 [15:0] Register */
+#define CAN_MB10_DATA1 0xFFC02D44 /* Mailbox 10 Data Word 1 [31:16] Register */
+#define CAN_MB10_DATA2 0xFFC02D48 /* Mailbox 10 Data Word 2 [47:32] Register */
+#define CAN_MB10_DATA3 0xFFC02D4C /* Mailbox 10 Data Word 3 [63:48] Register */
+#define CAN_MB10_LENGTH 0xFFC02D50 /* Mailbox 10 Data Length Code Register */
+#define CAN_MB10_TIMESTAMP 0xFFC02D54 /* Mailbox 10 Time Stamp Value Register */
+#define CAN_MB10_ID0 0xFFC02D58 /* Mailbox 10 Identifier Low Register */
+#define CAN_MB10_ID1 0xFFC02D5C /* Mailbox 10 Identifier High Register */
+
+#define CAN_MB11_DATA0 0xFFC02D60 /* Mailbox 11 Data Word 0 [15:0] Register */
+#define CAN_MB11_DATA1 0xFFC02D64 /* Mailbox 11 Data Word 1 [31:16] Register */
+#define CAN_MB11_DATA2 0xFFC02D68 /* Mailbox 11 Data Word 2 [47:32] Register */
+#define CAN_MB11_DATA3 0xFFC02D6C /* Mailbox 11 Data Word 3 [63:48] Register */
+#define CAN_MB11_LENGTH 0xFFC02D70 /* Mailbox 11 Data Length Code Register */
+#define CAN_MB11_TIMESTAMP 0xFFC02D74 /* Mailbox 11 Time Stamp Value Register */
+#define CAN_MB11_ID0 0xFFC02D78 /* Mailbox 11 Identifier Low Register */
+#define CAN_MB11_ID1 0xFFC02D7C /* Mailbox 11 Identifier High Register */
+
+#define CAN_MB12_DATA0 0xFFC02D80 /* Mailbox 12 Data Word 0 [15:0] Register */
+#define CAN_MB12_DATA1 0xFFC02D84 /* Mailbox 12 Data Word 1 [31:16] Register */
+#define CAN_MB12_DATA2 0xFFC02D88 /* Mailbox 12 Data Word 2 [47:32] Register */
+#define CAN_MB12_DATA3 0xFFC02D8C /* Mailbox 12 Data Word 3 [63:48] Register */
+#define CAN_MB12_LENGTH 0xFFC02D90 /* Mailbox 12 Data Length Code Register */
+#define CAN_MB12_TIMESTAMP 0xFFC02D94 /* Mailbox 12 Time Stamp Value Register */
+#define CAN_MB12_ID0 0xFFC02D98 /* Mailbox 12 Identifier Low Register */
+#define CAN_MB12_ID1 0xFFC02D9C /* Mailbox 12 Identifier High Register */
+
+#define CAN_MB13_DATA0 0xFFC02DA0 /* Mailbox 13 Data Word 0 [15:0] Register */
+#define CAN_MB13_DATA1 0xFFC02DA4 /* Mailbox 13 Data Word 1 [31:16] Register */
+#define CAN_MB13_DATA2 0xFFC02DA8 /* Mailbox 13 Data Word 2 [47:32] Register */
+#define CAN_MB13_DATA3 0xFFC02DAC /* Mailbox 13 Data Word 3 [63:48] Register */
+#define CAN_MB13_LENGTH 0xFFC02DB0 /* Mailbox 13 Data Length Code Register */
+#define CAN_MB13_TIMESTAMP 0xFFC02DB4 /* Mailbox 13 Time Stamp Value Register */
+#define CAN_MB13_ID0 0xFFC02DB8 /* Mailbox 13 Identifier Low Register */
+#define CAN_MB13_ID1 0xFFC02DBC /* Mailbox 13 Identifier High Register */
+
+#define CAN_MB14_DATA0 0xFFC02DC0 /* Mailbox 14 Data Word 0 [15:0] Register */
+#define CAN_MB14_DATA1 0xFFC02DC4 /* Mailbox 14 Data Word 1 [31:16] Register */
+#define CAN_MB14_DATA2 0xFFC02DC8 /* Mailbox 14 Data Word 2 [47:32] Register */
+#define CAN_MB14_DATA3 0xFFC02DCC /* Mailbox 14 Data Word 3 [63:48] Register */
+#define CAN_MB14_LENGTH 0xFFC02DD0 /* Mailbox 14 Data Length Code Register */
+#define CAN_MB14_TIMESTAMP 0xFFC02DD4 /* Mailbox 14 Time Stamp Value Register */
+#define CAN_MB14_ID0 0xFFC02DD8 /* Mailbox 14 Identifier Low Register */
+#define CAN_MB14_ID1 0xFFC02DDC /* Mailbox 14 Identifier High Register */
+
+#define CAN_MB15_DATA0 0xFFC02DE0 /* Mailbox 15 Data Word 0 [15:0] Register */
+#define CAN_MB15_DATA1 0xFFC02DE4 /* Mailbox 15 Data Word 1 [31:16] Register */
+#define CAN_MB15_DATA2 0xFFC02DE8 /* Mailbox 15 Data Word 2 [47:32] Register */
+#define CAN_MB15_DATA3 0xFFC02DEC /* Mailbox 15 Data Word 3 [63:48] Register */
+#define CAN_MB15_LENGTH 0xFFC02DF0 /* Mailbox 15 Data Length Code Register */
+#define CAN_MB15_TIMESTAMP 0xFFC02DF4 /* Mailbox 15 Time Stamp Value Register */
+#define CAN_MB15_ID0 0xFFC02DF8 /* Mailbox 15 Identifier Low Register */
+#define CAN_MB15_ID1 0xFFC02DFC /* Mailbox 15 Identifier High Register */
+
+#define CAN_MB16_DATA0 0xFFC02E00 /* Mailbox 16 Data Word 0 [15:0] Register */
+#define CAN_MB16_DATA1 0xFFC02E04 /* Mailbox 16 Data Word 1 [31:16] Register */
+#define CAN_MB16_DATA2 0xFFC02E08 /* Mailbox 16 Data Word 2 [47:32] Register */
+#define CAN_MB16_DATA3 0xFFC02E0C /* Mailbox 16 Data Word 3 [63:48] Register */
+#define CAN_MB16_LENGTH 0xFFC02E10 /* Mailbox 16 Data Length Code Register */
+#define CAN_MB16_TIMESTAMP 0xFFC02E14 /* Mailbox 16 Time Stamp Value Register */
+#define CAN_MB16_ID0 0xFFC02E18 /* Mailbox 16 Identifier Low Register */
+#define CAN_MB16_ID1 0xFFC02E1C /* Mailbox 16 Identifier High Register */
+
+#define CAN_MB17_DATA0 0xFFC02E20 /* Mailbox 17 Data Word 0 [15:0] Register */
+#define CAN_MB17_DATA1 0xFFC02E24 /* Mailbox 17 Data Word 1 [31:16] Register */
+#define CAN_MB17_DATA2 0xFFC02E28 /* Mailbox 17 Data Word 2 [47:32] Register */
+#define CAN_MB17_DATA3 0xFFC02E2C /* Mailbox 17 Data Word 3 [63:48] Register */
+#define CAN_MB17_LENGTH 0xFFC02E30 /* Mailbox 17 Data Length Code Register */
+#define CAN_MB17_TIMESTAMP 0xFFC02E34 /* Mailbox 17 Time Stamp Value Register */
+#define CAN_MB17_ID0 0xFFC02E38 /* Mailbox 17 Identifier Low Register */
+#define CAN_MB17_ID1 0xFFC02E3C /* Mailbox 17 Identifier High Register */
+
+#define CAN_MB18_DATA0 0xFFC02E40 /* Mailbox 18 Data Word 0 [15:0] Register */
+#define CAN_MB18_DATA1 0xFFC02E44 /* Mailbox 18 Data Word 1 [31:16] Register */
+#define CAN_MB18_DATA2 0xFFC02E48 /* Mailbox 18 Data Word 2 [47:32] Register */
+#define CAN_MB18_DATA3 0xFFC02E4C /* Mailbox 18 Data Word 3 [63:48] Register */
+#define CAN_MB18_LENGTH 0xFFC02E50 /* Mailbox 18 Data Length Code Register */
+#define CAN_MB18_TIMESTAMP 0xFFC02E54 /* Mailbox 18 Time Stamp Value Register */
+#define CAN_MB18_ID0 0xFFC02E58 /* Mailbox 18 Identifier Low Register */
+#define CAN_MB18_ID1 0xFFC02E5C /* Mailbox 18 Identifier High Register */
+
+#define CAN_MB19_DATA0 0xFFC02E60 /* Mailbox 19 Data Word 0 [15:0] Register */
+#define CAN_MB19_DATA1 0xFFC02E64 /* Mailbox 19 Data Word 1 [31:16] Register */
+#define CAN_MB19_DATA2 0xFFC02E68 /* Mailbox 19 Data Word 2 [47:32] Register */
+#define CAN_MB19_DATA3 0xFFC02E6C /* Mailbox 19 Data Word 3 [63:48] Register */
+#define CAN_MB19_LENGTH 0xFFC02E70 /* Mailbox 19 Data Length Code Register */
+#define CAN_MB19_TIMESTAMP 0xFFC02E74 /* Mailbox 19 Time Stamp Value Register */
+#define CAN_MB19_ID0 0xFFC02E78 /* Mailbox 19 Identifier Low Register */
+#define CAN_MB19_ID1 0xFFC02E7C /* Mailbox 19 Identifier High Register */
+
+#define CAN_MB20_DATA0 0xFFC02E80 /* Mailbox 20 Data Word 0 [15:0] Register */
+#define CAN_MB20_DATA1 0xFFC02E84 /* Mailbox 20 Data Word 1 [31:16] Register */
+#define CAN_MB20_DATA2 0xFFC02E88 /* Mailbox 20 Data Word 2 [47:32] Register */
+#define CAN_MB20_DATA3 0xFFC02E8C /* Mailbox 20 Data Word 3 [63:48] Register */
+#define CAN_MB20_LENGTH 0xFFC02E90 /* Mailbox 20 Data Length Code Register */
+#define CAN_MB20_TIMESTAMP 0xFFC02E94 /* Mailbox 20 Time Stamp Value Register */
+#define CAN_MB20_ID0 0xFFC02E98 /* Mailbox 20 Identifier Low Register */
+#define CAN_MB20_ID1 0xFFC02E9C /* Mailbox 20 Identifier High Register */
+
+#define CAN_MB21_DATA0 0xFFC02EA0 /* Mailbox 21 Data Word 0 [15:0] Register */
+#define CAN_MB21_DATA1 0xFFC02EA4 /* Mailbox 21 Data Word 1 [31:16] Register */
+#define CAN_MB21_DATA2 0xFFC02EA8 /* Mailbox 21 Data Word 2 [47:32] Register */
+#define CAN_MB21_DATA3 0xFFC02EAC /* Mailbox 21 Data Word 3 [63:48] Register */
+#define CAN_MB21_LENGTH 0xFFC02EB0 /* Mailbox 21 Data Length Code Register */
+#define CAN_MB21_TIMESTAMP 0xFFC02EB4 /* Mailbox 21 Time Stamp Value Register */
+#define CAN_MB21_ID0 0xFFC02EB8 /* Mailbox 21 Identifier Low Register */
+#define CAN_MB21_ID1 0xFFC02EBC /* Mailbox 21 Identifier High Register */
+
+#define CAN_MB22_DATA0 0xFFC02EC0 /* Mailbox 22 Data Word 0 [15:0] Register */
+#define CAN_MB22_DATA1 0xFFC02EC4 /* Mailbox 22 Data Word 1 [31:16] Register */
+#define CAN_MB22_DATA2 0xFFC02EC8 /* Mailbox 22 Data Word 2 [47:32] Register */
+#define CAN_MB22_DATA3 0xFFC02ECC /* Mailbox 22 Data Word 3 [63:48] Register */
+#define CAN_MB22_LENGTH 0xFFC02ED0 /* Mailbox 22 Data Length Code Register */
+#define CAN_MB22_TIMESTAMP 0xFFC02ED4 /* Mailbox 22 Time Stamp Value Register */
+#define CAN_MB22_ID0 0xFFC02ED8 /* Mailbox 22 Identifier Low Register */
+#define CAN_MB22_ID1 0xFFC02EDC /* Mailbox 22 Identifier High Register */
+
+#define CAN_MB23_DATA0 0xFFC02EE0 /* Mailbox 23 Data Word 0 [15:0] Register */
+#define CAN_MB23_DATA1 0xFFC02EE4 /* Mailbox 23 Data Word 1 [31:16] Register */
+#define CAN_MB23_DATA2 0xFFC02EE8 /* Mailbox 23 Data Word 2 [47:32] Register */
+#define CAN_MB23_DATA3 0xFFC02EEC /* Mailbox 23 Data Word 3 [63:48] Register */
+#define CAN_MB23_LENGTH 0xFFC02EF0 /* Mailbox 23 Data Length Code Register */
+#define CAN_MB23_TIMESTAMP 0xFFC02EF4 /* Mailbox 23 Time Stamp Value Register */
+#define CAN_MB23_ID0 0xFFC02EF8 /* Mailbox 23 Identifier Low Register */
+#define CAN_MB23_ID1 0xFFC02EFC /* Mailbox 23 Identifier High Register */
+
+#define CAN_MB24_DATA0 0xFFC02F00 /* Mailbox 24 Data Word 0 [15:0] Register */
+#define CAN_MB24_DATA1 0xFFC02F04 /* Mailbox 24 Data Word 1 [31:16] Register */
+#define CAN_MB24_DATA2 0xFFC02F08 /* Mailbox 24 Data Word 2 [47:32] Register */
+#define CAN_MB24_DATA3 0xFFC02F0C /* Mailbox 24 Data Word 3 [63:48] Register */
+#define CAN_MB24_LENGTH 0xFFC02F10 /* Mailbox 24 Data Length Code Register */
+#define CAN_MB24_TIMESTAMP 0xFFC02F14 /* Mailbox 24 Time Stamp Value Register */
+#define CAN_MB24_ID0 0xFFC02F18 /* Mailbox 24 Identifier Low Register */
+#define CAN_MB24_ID1 0xFFC02F1C /* Mailbox 24 Identifier High Register */
+
+#define CAN_MB25_DATA0 0xFFC02F20 /* Mailbox 25 Data Word 0 [15:0] Register */
+#define CAN_MB25_DATA1 0xFFC02F24 /* Mailbox 25 Data Word 1 [31:16] Register */
+#define CAN_MB25_DATA2 0xFFC02F28 /* Mailbox 25 Data Word 2 [47:32] Register */
+#define CAN_MB25_DATA3 0xFFC02F2C /* Mailbox 25 Data Word 3 [63:48] Register */
+#define CAN_MB25_LENGTH 0xFFC02F30 /* Mailbox 25 Data Length Code Register */
+#define CAN_MB25_TIMESTAMP 0xFFC02F34 /* Mailbox 25 Time Stamp Value Register */
+#define CAN_MB25_ID0 0xFFC02F38 /* Mailbox 25 Identifier Low Register */
+#define CAN_MB25_ID1 0xFFC02F3C /* Mailbox 25 Identifier High Register */
+
+#define CAN_MB26_DATA0 0xFFC02F40 /* Mailbox 26 Data Word 0 [15:0] Register */
+#define CAN_MB26_DATA1 0xFFC02F44 /* Mailbox 26 Data Word 1 [31:16] Register */
+#define CAN_MB26_DATA2 0xFFC02F48 /* Mailbox 26 Data Word 2 [47:32] Register */
+#define CAN_MB26_DATA3 0xFFC02F4C /* Mailbox 26 Data Word 3 [63:48] Register */
+#define CAN_MB26_LENGTH 0xFFC02F50 /* Mailbox 26 Data Length Code Register */
+#define CAN_MB26_TIMESTAMP 0xFFC02F54 /* Mailbox 26 Time Stamp Value Register */
+#define CAN_MB26_ID0 0xFFC02F58 /* Mailbox 26 Identifier Low Register */
+#define CAN_MB26_ID1 0xFFC02F5C /* Mailbox 26 Identifier High Register */
+
+#define CAN_MB27_DATA0 0xFFC02F60 /* Mailbox 27 Data Word 0 [15:0] Register */
+#define CAN_MB27_DATA1 0xFFC02F64 /* Mailbox 27 Data Word 1 [31:16] Register */
+#define CAN_MB27_DATA2 0xFFC02F68 /* Mailbox 27 Data Word 2 [47:32] Register */
+#define CAN_MB27_DATA3 0xFFC02F6C /* Mailbox 27 Data Word 3 [63:48] Register */
+#define CAN_MB27_LENGTH 0xFFC02F70 /* Mailbox 27 Data Length Code Register */
+#define CAN_MB27_TIMESTAMP 0xFFC02F74 /* Mailbox 27 Time Stamp Value Register */
+#define CAN_MB27_ID0 0xFFC02F78 /* Mailbox 27 Identifier Low Register */
+#define CAN_MB27_ID1 0xFFC02F7C /* Mailbox 27 Identifier High Register */
+
+#define CAN_MB28_DATA0 0xFFC02F80 /* Mailbox 28 Data Word 0 [15:0] Register */
+#define CAN_MB28_DATA1 0xFFC02F84 /* Mailbox 28 Data Word 1 [31:16] Register */
+#define CAN_MB28_DATA2 0xFFC02F88 /* Mailbox 28 Data Word 2 [47:32] Register */
+#define CAN_MB28_DATA3 0xFFC02F8C /* Mailbox 28 Data Word 3 [63:48] Register */
+#define CAN_MB28_LENGTH 0xFFC02F90 /* Mailbox 28 Data Length Code Register */
+#define CAN_MB28_TIMESTAMP 0xFFC02F94 /* Mailbox 28 Time Stamp Value Register */
+#define CAN_MB28_ID0 0xFFC02F98 /* Mailbox 28 Identifier Low Register */
+#define CAN_MB28_ID1 0xFFC02F9C /* Mailbox 28 Identifier High Register */
+
+#define CAN_MB29_DATA0 0xFFC02FA0 /* Mailbox 29 Data Word 0 [15:0] Register */
+#define CAN_MB29_DATA1 0xFFC02FA4 /* Mailbox 29 Data Word 1 [31:16] Register */
+#define CAN_MB29_DATA2 0xFFC02FA8 /* Mailbox 29 Data Word 2 [47:32] Register */
+#define CAN_MB29_DATA3 0xFFC02FAC /* Mailbox 29 Data Word 3 [63:48] Register */
+#define CAN_MB29_LENGTH 0xFFC02FB0 /* Mailbox 29 Data Length Code Register */
+#define CAN_MB29_TIMESTAMP 0xFFC02FB4 /* Mailbox 29 Time Stamp Value Register */
+#define CAN_MB29_ID0 0xFFC02FB8 /* Mailbox 29 Identifier Low Register */
+#define CAN_MB29_ID1 0xFFC02FBC /* Mailbox 29 Identifier High Register */
+
+#define CAN_MB30_DATA0 0xFFC02FC0 /* Mailbox 30 Data Word 0 [15:0] Register */
+#define CAN_MB30_DATA1 0xFFC02FC4 /* Mailbox 30 Data Word 1 [31:16] Register */
+#define CAN_MB30_DATA2 0xFFC02FC8 /* Mailbox 30 Data Word 2 [47:32] Register */
+#define CAN_MB30_DATA3 0xFFC02FCC /* Mailbox 30 Data Word 3 [63:48] Register */
+#define CAN_MB30_LENGTH 0xFFC02FD0 /* Mailbox 30 Data Length Code Register */
+#define CAN_MB30_TIMESTAMP 0xFFC02FD4 /* Mailbox 30 Time Stamp Value Register */
+#define CAN_MB30_ID0 0xFFC02FD8 /* Mailbox 30 Identifier Low Register */
+#define CAN_MB30_ID1 0xFFC02FDC /* Mailbox 30 Identifier High Register */
+
+#define CAN_MB31_DATA0 0xFFC02FE0 /* Mailbox 31 Data Word 0 [15:0] Register */
+#define CAN_MB31_DATA1 0xFFC02FE4 /* Mailbox 31 Data Word 1 [31:16] Register */
+#define CAN_MB31_DATA2 0xFFC02FE8 /* Mailbox 31 Data Word 2 [47:32] Register */
+#define CAN_MB31_DATA3 0xFFC02FEC /* Mailbox 31 Data Word 3 [63:48] Register */
+#define CAN_MB31_LENGTH 0xFFC02FF0 /* Mailbox 31 Data Length Code Register */
+#define CAN_MB31_TIMESTAMP 0xFFC02FF4 /* Mailbox 31 Time Stamp Value Register */
+#define CAN_MB31_ID0 0xFFC02FF8 /* Mailbox 31 Identifier Low Register */
+#define CAN_MB31_ID1 0xFFC02FFC /* Mailbox 31 Identifier High Register */
+
+/* CAN Mailbox Area Macros */
+#define CAN_MB_ID1(x) (CAN_MB00_ID1+((x)*0x20))
+#define CAN_MB_ID0(x) (CAN_MB00_ID0+((x)*0x20))
+#define CAN_MB_TIMESTAMP(x) (CAN_MB00_TIMESTAMP+((x)*0x20))
+#define CAN_MB_LENGTH(x) (CAN_MB00_LENGTH+((x)*0x20))
+#define CAN_MB_DATA3(x) (CAN_MB00_DATA3+((x)*0x20))
+#define CAN_MB_DATA2(x) (CAN_MB00_DATA2+((x)*0x20))
+#define CAN_MB_DATA1(x) (CAN_MB00_DATA1+((x)*0x20))
+#define CAN_MB_DATA0(x) (CAN_MB00_DATA0+((x)*0x20))
+
+
+/*********************************************************************************** */
+/* System MMR Register Bits and Macros */
+/******************************************************************************* */
+
+/* SWRST Mask */
+#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
+#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
+#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
+#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
+#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
+
+/* SYSCR Masks */
+#define BMODE 0x0006 /* Boot Mode - Latched During HW Reset From Mode Pins */
+#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
+
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */
+
+/* Peripheral Masks For SIC0_ISR, SIC0_IWR, SIC0_IMASK */
+#define PLL_WAKEUP_IRQ 0x00000001 /* PLL Wakeup Interrupt Request */
+#define DMAC0_ERR_IRQ 0x00000002 /* DMA Controller 0 Error Interrupt Request */
+#define PPI_ERR_IRQ 0x00000004 /* PPI Error Interrupt Request */
+#define SPORT0_ERR_IRQ 0x00000008 /* SPORT0 Error Interrupt Request */
+#define SPORT1_ERR_IRQ 0x00000010 /* SPORT1 Error Interrupt Request */
+#define SPI0_ERR_IRQ 0x00000020 /* SPI0 Error Interrupt Request */
+#define UART0_ERR_IRQ 0x00000040 /* UART0 Error Interrupt Request */
+#define RTC_IRQ 0x00000080 /* Real-Time Clock Interrupt Request */
+#define DMA0_IRQ 0x00000100 /* DMA Channel 0 (PPI) Interrupt Request */
+#define DMA1_IRQ 0x00000200 /* DMA Channel 1 (SPORT0 RX) Interrupt Request */
+#define DMA2_IRQ 0x00000400 /* DMA Channel 2 (SPORT0 TX) Interrupt Request */
+#define DMA3_IRQ 0x00000800 /* DMA Channel 3 (SPORT1 RX) Interrupt Request */
+#define DMA4_IRQ 0x00001000 /* DMA Channel 4 (SPORT1 TX) Interrupt Request */
+#define DMA5_IRQ 0x00002000 /* DMA Channel 5 (SPI) Interrupt Request */
+#define DMA6_IRQ 0x00004000 /* DMA Channel 6 (UART RX) Interrupt Request */
+#define DMA7_IRQ 0x00008000 /* DMA Channel 7 (UART TX) Interrupt Request */
+#define TIMER0_IRQ 0x00010000 /* Timer 0 Interrupt Request */
+#define TIMER1_IRQ 0x00020000 /* Timer 1 Interrupt Request */
+#define TIMER2_IRQ 0x00040000 /* Timer 2 Interrupt Request */
+#define PFA_IRQ 0x00080000 /* Programmable Flag Interrupt Request A */
+#define PFB_IRQ 0x00100000 /* Programmable Flag Interrupt Request B */
+#define MDMA0_0_IRQ 0x00200000 /* MemDMA0 Stream 0 Interrupt Request */
+#define MDMA0_1_IRQ 0x00400000 /* MemDMA0 Stream 1 Interrupt Request */
+#define WDOG_IRQ 0x00800000 /* Software Watchdog Timer Interrupt Request */
+#define DMAC1_ERR_IRQ 0x01000000 /* DMA Controller 1 Error Interrupt Request */
+#define SPORT2_ERR_IRQ 0x02000000 /* SPORT2 Error Interrupt Request */
+#define SPORT3_ERR_IRQ 0x04000000 /* SPORT3 Error Interrupt Request */
+#define MXVR_SD_IRQ 0x08000000 /* MXVR Synchronous Data Interrupt Request */
+#define SPI1_ERR_IRQ 0x10000000 /* SPI1 Error Interrupt Request */
+#define SPI2_ERR_IRQ 0x20000000 /* SPI2 Error Interrupt Request */
+#define UART1_ERR_IRQ 0x40000000 /* UART1 Error Interrupt Request */
+#define UART2_ERR_IRQ 0x80000000 /* UART2 Error Interrupt Request */
+
+/* the following are for backwards compatibility */
+#define DMA0_ERR_IRQ DMAC0_ERR_IRQ
+#define DMA1_ERR_IRQ DMAC1_ERR_IRQ
+
+
+/* Peripheral Masks For SIC_ISR1, SIC_IWR1, SIC_IMASK1 */
+#define CAN_ERR_IRQ 0x00000001 /* CAN Error Interrupt Request */
+#define DMA8_IRQ 0x00000002 /* DMA Channel 8 (SPORT2 RX) Interrupt Request */
+#define DMA9_IRQ 0x00000004 /* DMA Channel 9 (SPORT2 TX) Interrupt Request */
+#define DMA10_IRQ 0x00000008 /* DMA Channel 10 (SPORT3 RX) Interrupt Request */
+#define DMA11_IRQ 0x00000010 /* DMA Channel 11 (SPORT3 TX) Interrupt Request */
+#define DMA12_IRQ 0x00000020 /* DMA Channel 12 Interrupt Request */
+#define DMA13_IRQ 0x00000040 /* DMA Channel 13 Interrupt Request */
+#define DMA14_IRQ 0x00000080 /* DMA Channel 14 (SPI1) Interrupt Request */
+#define DMA15_IRQ 0x00000100 /* DMA Channel 15 (SPI2) Interrupt Request */
+#define DMA16_IRQ 0x00000200 /* DMA Channel 16 (UART1 RX) Interrupt Request */
+#define DMA17_IRQ 0x00000400 /* DMA Channel 17 (UART1 TX) Interrupt Request */
+#define DMA18_IRQ 0x00000800 /* DMA Channel 18 (UART2 RX) Interrupt Request */
+#define DMA19_IRQ 0x00001000 /* DMA Channel 19 (UART2 TX) Interrupt Request */
+#define TWI0_IRQ 0x00002000 /* TWI0 Interrupt Request */
+#define TWI1_IRQ 0x00004000 /* TWI1 Interrupt Request */
+#define CAN_RX_IRQ 0x00008000 /* CAN Receive Interrupt Request */
+#define CAN_TX_IRQ 0x00010000 /* CAN Transmit Interrupt Request */
+#define MDMA1_0_IRQ 0x00020000 /* MemDMA1 Stream 0 Interrupt Request */
+#define MDMA1_1_IRQ 0x00040000 /* MemDMA1 Stream 1 Interrupt Request */
+#define MXVR_STAT_IRQ 0x00080000 /* MXVR Status Interrupt Request */
+#define MXVR_CM_IRQ 0x00100000 /* MXVR Control Message Interrupt Request */
+#define MXVR_AP_IRQ 0x00200000 /* MXVR Asynchronous Packet Interrupt */
+
+/* the following are for backwards compatibility */
+#define MDMA0_IRQ MDMA1_0_IRQ
+#define MDMA1_IRQ MDMA1_1_IRQ
+
+#ifdef _MISRA_RULES
+#define _MF15 0xFu
+#define _MF7 7u
+#else
+#define _MF15 0xF
+#define _MF7 7
+#endif /* _MISRA_RULES */
+
+/* SIC_IMASKx Masks */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#ifdef _MISRA_RULES
+#define SIC_MASK(x) (1 << ((x)&0x1Fu)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFFu ^ (1 << ((x)&0x1Fu))) /* Unmask Peripheral #x interrupt */
+#else
+#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
+#endif /* _MISRA_RULES */
+
+/* SIC_IWRx Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+#ifdef _MISRA_RULES
+#define IWR_ENABLE(x) (1 << ((x)&0x1Fu)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFFu ^ (1 << ((x)&0x1Fu))) /* Wakeup Disable Peripheral #x */
+#else
+#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
+#endif /* _MISRA_RULES */
+
+/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x0001 /* PPI Port Enable */
+#define PORT_DIR 0x0002 /* PPI Port Direction */
+#define XFR_TYPE 0x000C /* PPI Transfer Type */
+#define PORT_CFG 0x0030 /* PPI Port Configuration */
+#define FLD_SEL 0x0040 /* PPI Active Field Select */
+#define PACK_EN 0x0080 /* PPI Packing Mode */
+/* previous versions of defBF539.h erroneously included DMA32 (PPI 32-bit DMA Enable) */
+#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
+#define DLENGTH 0x3800 /* PPI Data Length */
+#define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */
+#define DLEN_10 0x0800 /* Data Length = 10 Bits */
+#define DLEN_11 0x1000 /* Data Length = 11 Bits */
+#define DLEN_12 0x1800 /* Data Length = 12 Bits */
+#define DLEN_13 0x2000 /* Data Length = 13 Bits */
+#define DLEN_14 0x2800 /* Data Length = 14 Bits */
+#define DLEN_15 0x3000 /* Data Length = 15 Bits */
+#define DLEN_16 0x3800 /* Data Length = 16 Bits */
+#ifdef _MISRA_RULES
+#define DLEN(x) ((((x)-9u) & 0x07u) << 11) /* PPI Data Length (only works for x=10-->x=16) */
+#else
+#define DLEN(x) ((((x)-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */
+#endif /* _MISRA_RULES */
+#define POL 0xC000 /* PPI Signal Polarities */
+#define POLC 0x4000 /* PPI Clock Polarity */
+#define POLS 0x8000 /* PPI Frame Sync Polarity */
+
+
+/* PPI_STATUS Masks */
+#define FLD 0x0400 /* Field Indicator */
+#define FT_ERR 0x0800 /* Frame Track Error */
+#define OVR 0x1000 /* FIFO Overflow Error */
+#define UNDR 0x2000 /* FIFO Underrun Error */
+#define ERR_DET 0x4000 /* Error Detected Indicator */
+#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
+
+
+/* ********** DMA CONTROLLER MASKS ***********************/
+
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+
+#define CTYPE 0x0040 /* DMA Channel Type Indicator */
+#define CTYPE_P 0x6 /* DMA Channel Type Indicator BIT POSITION */
+#define PCAP8 0x0080 /* DMA 8-bit Operation Indicator */
+#define PCAP16 0x0100 /* DMA 16-bit Operation Indicator */
+#define PCAP32 0x0200 /* DMA 32-bit Operation Indicator */
+#define PCAPWR 0x0400 /* DMA Write Operation Indicator */
+#define PCAPRD 0x0800 /* DMA Read Operation Indicator */
+#define PMAP 0xF000 /* DMA Peripheral Map Field */
+
+/* PMAP Encodings For DMA Controller 0 */
+#define PMAP_PPI 0x0000 /* PMAP PPI Port DMA */
+#define PMAP_SPORT0RX 0x1000 /* PMAP SPORT0 Receive DMA */
+#define PMAP_SPORT0TX 0x2000 /* PMAP SPORT0 Transmit DMA */
+#define PMAP_SPORT1RX 0x3000 /* PMAP SPORT1 Receive DMA */
+#define PMAP_SPORT1TX 0x4000 /* PMAP SPORT1 Transmit DMA */
+#define PMAP_SPI0 0x5000 /* PMAP SPI DMA */
+#define PMAP_UART0RX 0x6000 /* PMAP UART Receive DMA */
+#define PMAP_UART0TX 0x7000 /* PMAP UART Transmit DMA */
+
+/* PMAP Encodings For DMA Controller 1 */
+#define PMAP_SPORT2RX 0x0000 /* PMAP SPORT2 Receive DMA */
+#define PMAP_SPORT2TX 0x1000 /* PMAP SPORT2 Transmit DMA */
+#define PMAP_SPORT3RX 0x2000 /* PMAP SPORT3 Receive DMA */
+#define PMAP_SPORT3TX 0x3000 /* PMAP SPORT3 Transmit DMA */
+#define PMAP_SPI1 0x6000 /* PMAP SPI1 DMA */
+#define PMAP_SPI2 0x7000 /* PMAP SPI2 DMA */
+#define PMAP_UART1RX 0x8000 /* PMAP UART1 Receive DMA */
+#define PMAP_UART1TX 0x9000 /* PMAP UART1 Transmit DMA */
+#define PMAP_UART2RX 0xA000 /* PMAP UART2 Receive DMA */
+#define PMAP_UART2TX 0xB000 /* PMAP UART2 Transmit DMA */
+
+
+/* ************* GENERAL PURPOSE TIMER MASKS ******************** */
+/* PWM Timer bit definitions */
+/* TIMER_ENABLE Register */
+#define TIMEN0 0x0001 /* Enable Timer 0 */
+#define TIMEN1 0x0002 /* Enable Timer 1 */
+#define TIMEN2 0x0004 /* Enable Timer 2 */
+
+#define TIMEN0_P 0x00
+#define TIMEN1_P 0x01
+#define TIMEN2_P 0x02
+
+/* TIMER_DISABLE Register */
+#define TIMDIS0 0x0001 /* Disable Timer 0 */
+#define TIMDIS1 0x0002 /* Disable Timer 1 */
+#define TIMDIS2 0x0004 /* Disable Timer 2 */
+
+#define TIMDIS0_P 0x00
+#define TIMDIS1_P 0x01
+#define TIMDIS2_P 0x02
+
+/* TIMER_STATUS Register */
+#define TIMIL0 0x0001 /* Timer 0 Interrupt */
+#define TIMIL1 0x0002 /* Timer 1 Interrupt */
+#define TIMIL2 0x0004 /* Timer 2 Interrupt */
+#define TOVF_ERR0 0x0010 /* Timer 0 Counter Overflow */
+#define TOVF_ERR1 0x0020 /* Timer 1 Counter Overflow */
+#define TOVF_ERR2 0x0040 /* Timer 2 Counter Overflow */
+#define TRUN0 0x1000 /* Timer 0 Slave Enable Status */
+#define TRUN1 0x2000 /* Timer 1 Slave Enable Status */
+#define TRUN2 0x4000 /* Timer 2 Slave Enable Status */
+
+#define TIMIL0_P 0x00
+#define TIMIL1_P 0x01
+#define TIMIL2_P 0x02
+#define TOVF_ERR0_P 0x04
+#define TOVF_ERR1_P 0x05
+#define TOVF_ERR2_P 0x06
+#define TRUN0_P 0x0C
+#define TRUN1_P 0x0D
+#define TRUN2_P 0x0E
+
+/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
+#define TOVL_ERR0 TOVF_ERR0
+#define TOVL_ERR1 TOVF_ERR1
+#define TOVL_ERR2 TOVF_ERR2
+#define TOVL_ERR0_P TOVF_ERR0_P
+#define TOVL_ERR1_P TOVF_ERR1_P
+#define TOVL_ERR2_P TOVF_ERR2_P
+
+/* TIMERx_CONFIG Registers */
+#define PWM_OUT 0x0001
+#define WDTH_CAP 0x0002
+#define EXT_CLK 0x0003
+#define PULSE_HI 0x0004
+#define PERIOD_CNT 0x0008
+#define IRQ_ENA 0x0010
+#define TIN_SEL 0x0020
+#define OUT_DIS 0x0040
+#define CLK_SEL 0x0080
+#define TOGGLE_HI 0x0100
+#define EMU_RUN 0x0200
+#ifdef _MISRA_RULES
+#define ERR_TYP(x) (((x) & 0x03u) << 14)
+#else
+#define ERR_TYP(x) (((x) & 0x03) << 14)
+#endif /* _MISRA_RULES */
+
+#define TMODE_P0 0x00
+#define TMODE_P1 0x01
+#define PULSE_HI_P 0x02
+#define PERIOD_CNT_P 0x03
+#define IRQ_ENA_P 0x04
+#define TIN_SEL_P 0x05
+#define OUT_DIS_P 0x06
+#define CLK_SEL_P 0x07
+#define TOGGLE_HI_P 0x08
+#define EMU_RUN_P 0x09
+#define ERR_TYP_P0 0x0E
+#define ERR_TYP_P1 0x0F
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
+/* EBIU_AMGCTL Masks */
+#define AMCKEN 0x0001 /* Enable CLKOUT */
+#define AMBEN_NONE 0x0000 /* All Banks Disabled */
+#define AMBEN_B0 0x0002 /* Enable Asynchronous Memory Bank 0 only */
+#define AMBEN_B0_B1 0x0004 /* Enable Asynchronous Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x0006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x0008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */
+#define CDPRIO 0x0100 /* DMA has priority over core for external accesses */
+
+/* EBIU_AMGCTL Bit Positions */
+#define AMCKEN_P 0x0000 /* Enable CLKOUT */
+#define AMBEN_P0 0x0001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */
+#define AMBEN_P1 0x0002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */
+#define AMBEN_P2 0x0003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */
+
+/* EBIU_AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */
+#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */
+#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */
+#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */
+#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */
+#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */
+#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */
+#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */
+#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */
+#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */
+#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */
+#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */
+#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */
+#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */
+#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */
+#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */
+#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */
+#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */
+#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */
+#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */
+#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */
+#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */
+
+/* EBIU_AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */
+#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */
+#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */
+#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */
+#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */
+#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */
+#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */
+#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */
+#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */
+#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */
+#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */
+#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */
+#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */
+#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */
+
+/* ********************** SDRAM CONTROLLER MASKS *************************** */
+/* EBIU_SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */
+#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */
+#define PFE 0x00000010 /* Enable SDRAM prefetch */
+#define PFP 0x00000020 /* Prefetch has priority over AMC requests */
+#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
+#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
+#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /*Power-up start delay */
+#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */
+#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */
+#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */
+#define EBUFE 0x02000000 /* Enable external buffering timing */
+#define FBBRW 0x04000000 /* Fast back-to-back read write enable */
+#define EMREN 0x10000000 /* Extended mode register enable */
+#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */
+#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x00000001 /* Enable SDRAM external bank */
+#define EBSZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EBSZ_32 0x00000002 /* SDRAM external bank size = 32MB */
+#define EBSZ_64 0x00000004 /* SDRAM external bank size = 64MB */
+#define EBSZ_128 0x00000006 /* SDRAM external bank size = 128MB */
+#define EBSZ_256 0x00000008 /* SDRAM External Bank Size = 256MB */
+#define EBSZ_512 0x0000000A /* SDRAM External Bank Size = 512MB */
+#define EBCAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EBCAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */
+#define EBCAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */
+#define EBCAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x00000001 /* SDRAM controller is idle */
+#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */
+#define SDPUA 0x00000004 /* SDRAM power up active */
+#define SDRS 0x00000008 /* SDRAM is in reset state */
+#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */
+#define BGSTAT 0x00000020 /* Bus granted */
+
+
+/* ******************** TWO-WIRE INTERFACE (TWIx) MASKS ***********************/
+/* TWIx_CLKDIV Macros (Use: *pTWIx_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
+#ifdef _MISRA_RULES
+#define CLKLOW(x) ((x) & 0xFFu) /* Periods Clock Is Held Low */
+#define CLKHI(y) (((y)&0xFFu)<<0x8) /* Periods Before New Clock Low */
+#else
+#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
+#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
+#endif /* _MISRA_RULES */
+
+/* TWIx_PRESCALE Masks */
+#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
+#define TWI_ENA 0x0080 /* TWI Enable */
+#define SCCB 0x0200 /* SCCB Compatibility Enable */
+
+/* TWIx_SLAVE_CTRL Masks */
+#define SEN 0x0001 /* Slave Enable */
+#define SADD_LEN 0x0002 /* Slave Address Length */
+#define STDVAL 0x0004 /* Slave Transmit Data Valid */
+#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
+#define GEN 0x0010 /* General Call Adrress Matching Enabled */
+
+/* TWIx_SLAVE_STAT Masks */
+#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
+#define GCALL 0x0002 /* General Call Indicator */
+
+/* TWIx_MASTER_CTRL Masks */
+#define MEN 0x0001 /* Master Mode Enable */
+#define MADD_LEN 0x0002 /* Master Address Length */
+#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
+#define FAST 0x0008 /* Use Fast Mode Timing Specs */
+#define STOP 0x0010 /* Issue Stop Condition */
+#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
+#define DCNT 0x3FC0 /* Data Bytes To Transfer */
+#define SDAOVR 0x4000 /* Serial Data Override */
+#define SCLOVR 0x8000 /* Serial Clock Override */
+
+/* TWIx_MASTER_STAT Masks */
+#define MPROG 0x0001 /* Master Transfer In Progress */
+#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
+#define ANAK 0x0004 /* Address Not Acknowledged */
+#define DNAK 0x0008 /* Data Not Acknowledged */
+#define BUFRDERR 0x0010 /* Buffer Read Error */
+#define BUFWRERR 0x0020 /* Buffer Write Error */
+#define SDASEN 0x0040 /* Serial Data Sense */
+#define SCLSEN 0x0080 /* Serial Clock Sense */
+#define BUSBUSY 0x0100 /* Bus Busy Indicator */
+
+/* TWIx_INT_SRC and TWIx_INT_ENABLE Masks */
+#define SINIT 0x0001 /* Slave Transfer Initiated */
+#define SCOMP 0x0002 /* Slave Transfer Complete */
+#define SERR 0x0004 /* Slave Transfer Error */
+#define SOVF 0x0008 /* Slave Overflow */
+#define MCOMP 0x0010 /* Master Transfer Complete */
+#define MERR 0x0020 /* Master Transfer Error */
+#define XMTSERV 0x0040 /* Transmit FIFO Service */
+#define RCVSERV 0x0080 /* Receive FIFO Service */
+
+/* TWIx_FIFO_CTL Masks */
+#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
+#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
+#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
+#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
+
+/* TWIx_FIFO_STAT Masks */
+#define XMTSTAT 0x0003 /* Transmit FIFO Status */
+#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
+#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
+#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
+
+#define RCVSTAT 0x000C /* Receive FIFO Status */
+#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
+#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
+#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
+
+#endif
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h
index 7a8ac5f44204..8100bcd01a0d 100644
--- a/arch/blackfin/mach-bf538/include/mach/defBF539.h
+++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h
@@ -1,859 +1,13 @@
/*
- * Copyright 2008-2009 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
-/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF538/9 */
-
#ifndef _DEF_BF539_H
#define _DEF_BF539_H
-/* include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-
-/*********************************************************************************** */
-/* System MMR Register Map */
-/*********************************************************************************** */
-/* Clock/Regulator Control (0xFFC00000 - 0xFFC000FF) */
-#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */
-#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */
-#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */
-#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */
-#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */
-#define CHIPID 0xFFC00014 /* Chip ID Register */
-
-/* CHIPID Masks */
-#define CHIPID_VERSION 0xF0000000
-#define CHIPID_FAMILY 0x0FFFF000
-#define CHIPID_MANUFACTURE 0x00000FFE
-
-/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
-#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */
-#define SYSCR 0xFFC00104 /* System Configuration registe */
-#define SIC_RVECT 0xFFC00108
-#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
-#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
-#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
-#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
-#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
-#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
-#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
-#define SIC_IMASK1 0xFFC00128 /* Interrupt Mask Register 1 */
-#define SIC_ISR1 0xFFC0012C /* Interrupt Status Register 1 */
-#define SIC_IWR1 0xFFC00130 /* Interrupt Wakeup Register 1 */
-#define SIC_IAR4 0xFFC00134 /* Interrupt Assignment Register 4 */
-#define SIC_IAR5 0xFFC00138 /* Interrupt Assignment Register 5 */
-#define SIC_IAR6 0xFFC0013C /* Interrupt Assignment Register 6 */
-
-
-/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
-#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
-#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
-#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
-
-
-/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
-#define RTC_STAT 0xFFC00300 /* RTC Status Register */
-#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
-#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
-#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
-#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
-#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
-#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Register (alternate macro) */
-
-
-/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
-#define UART0_THR 0xFFC00400 /* Transmit Holding register */
-#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
-#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
-#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
-#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
-#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
-#define UART0_LCR 0xFFC0040C /* Line Control Register */
-#define UART0_MCR 0xFFC00410 /* Modem Control Register */
-#define UART0_LSR 0xFFC00414 /* Line Status Register */
-#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
-#define UART0_GCTL 0xFFC00424 /* Global Control Register */
-
-
-/* SPI0 Controller (0xFFC00500 - 0xFFC005FF) */
-
-#define SPI0_CTL 0xFFC00500 /* SPI0 Control Register */
-#define SPI0_FLG 0xFFC00504 /* SPI0 Flag register */
-#define SPI0_STAT 0xFFC00508 /* SPI0 Status register */
-#define SPI0_TDBR 0xFFC0050C /* SPI0 Transmit Data Buffer Register */
-#define SPI0_RDBR 0xFFC00510 /* SPI0 Receive Data Buffer Register */
-#define SPI0_BAUD 0xFFC00514 /* SPI0 Baud rate Register */
-#define SPI0_SHADOW 0xFFC00518 /* SPI0_RDBR Shadow Register */
-#define SPI0_REGBASE SPI0_CTL
-
-
-/* TIMER 0, 1, 2 Registers (0xFFC00600 - 0xFFC006FF) */
-#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
-#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
-#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
-#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
-
-#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
-#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
-#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
-#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
-
-#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
-#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
-#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
-#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
-
-#define TIMER_ENABLE 0xFFC00640 /* Timer Enable Register */
-#define TIMER_DISABLE 0xFFC00644 /* Timer Disable Register */
-#define TIMER_STATUS 0xFFC00648 /* Timer Status Register */
-
-
-/* Programmable Flags (0xFFC00700 - 0xFFC007FF) */
-#define FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */
-#define FIO_FLAG_C 0xFFC00704 /* Peripheral Interrupt Flag Register (clear) */
-#define FIO_FLAG_S 0xFFC00708 /* Peripheral Interrupt Flag Register (set) */
-#define FIO_FLAG_T 0xFFC0070C /* Flag Mask to directly toggle state of pins */
-#define FIO_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Register (set directly) */
-#define FIO_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Register (clear) */
-#define FIO_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Register (set) */
-#define FIO_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Register (toggle) */
-#define FIO_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Register (set directly) */
-#define FIO_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Register (clear) */
-#define FIO_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Register (set) */
-#define FIO_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Register (toggle) */
-#define FIO_DIR 0xFFC00730 /* Peripheral Flag Direction Register */
-#define FIO_POLAR 0xFFC00734 /* Flag Source Polarity Register */
-#define FIO_EDGE 0xFFC00738 /* Flag Source Sensitivity Register */
-#define FIO_BOTH 0xFFC0073C /* Flag Set on BOTH Edges Register */
-#define FIO_INEN 0xFFC00740 /* Flag Input Enable Register */
-
-
-/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
-#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
-#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
-#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
-#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
-#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
-#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
-#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
-#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
-#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
-#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
-#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
-#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
-#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
-#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
-#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
-#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
-#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
-#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
-#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
-#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
-
-
-/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
-#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
-#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
-#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
-#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
-#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
-#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
-#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
-#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
-#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
-#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
-#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
-#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
-#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
-#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
-#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
-#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
-#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
-#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
-#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
-#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
-
-
-/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
-/* Asynchronous Memory Controller */
-#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
-#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
-#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
-
-/* SDRAM Controller */
-#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
-#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
-#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
-#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
-
-
-
-/* DMA Controller 0 Traffic Control Registers (0xFFC00B00 - 0xFFC00BFF) */
-
-#define DMAC0_TC_PER 0xFFC00B0C /* DMA Controller 0 Traffic Control Periods Register */
-#define DMAC0_TC_CNT 0xFFC00B10 /* DMA Controller 0 Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA0_TCPER DMAC0_TC_PER
-#define DMA0_TCCNT DMAC0_TC_CNT
-
-
-/* DMA Controller 0 (0xFFC00C00 - 0xFFC00FFF) */
-
-#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
-#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
-#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
-#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
-#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
-#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
-#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
-#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
-#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
-#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
-#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
-#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
-#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
-
-#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
-#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
-#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
-#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
-#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
-#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
-#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
-#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
-#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
-#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
-#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
-#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
-#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
-
-#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
-#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
-#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
-#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
-#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
-#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
-#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
-#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
-#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
-#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
-#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
-#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
-#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
-
-#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
-#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
-#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
-#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
-#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
-#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
-#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
-#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
-#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
-#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
-#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
-#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
-#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
-
-#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
-#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
-#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
-#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
-#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
-#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
-#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
-#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
-#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
-#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
-#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
-#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
-#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
-
-#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
-#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
-#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
-#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
-#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
-#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
-#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
-#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
-#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
-#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
-#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
-#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
-#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
-
-#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
-#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
-#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
-#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
-#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
-#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
-#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
-#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
-#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
-#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
-#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
-#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
-#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
-
-#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
-#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
-#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
-#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
-#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
-#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
-#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
-#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
-#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
-#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
-#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
-#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
-#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
-
-#define MDMA0_D0_NEXT_DESC_PTR 0xFFC00E00 /* MemDMA0 Stream 0 Destination Next Descriptor Pointer Register */
-#define MDMA0_D0_START_ADDR 0xFFC00E04 /* MemDMA0 Stream 0 Destination Start Address Register */
-#define MDMA0_D0_CONFIG 0xFFC00E08 /* MemDMA0 Stream 0 Destination Configuration Register */
-#define MDMA0_D0_X_COUNT 0xFFC00E10 /* MemDMA0 Stream 0 Destination X Count Register */
-#define MDMA0_D0_X_MODIFY 0xFFC00E14 /* MemDMA0 Stream 0 Destination X Modify Register */
-#define MDMA0_D0_Y_COUNT 0xFFC00E18 /* MemDMA0 Stream 0 Destination Y Count Register */
-#define MDMA0_D0_Y_MODIFY 0xFFC00E1C /* MemDMA0 Stream 0 Destination Y Modify Register */
-#define MDMA0_D0_CURR_DESC_PTR 0xFFC00E20 /* MemDMA0 Stream 0 Destination Current Descriptor Pointer Register */
-#define MDMA0_D0_CURR_ADDR 0xFFC00E24 /* MemDMA0 Stream 0 Destination Current Address Register */
-#define MDMA0_D0_IRQ_STATUS 0xFFC00E28 /* MemDMA0 Stream 0 Destination Interrupt/Status Register */
-#define MDMA0_D0_PERIPHERAL_MAP 0xFFC00E2C /* MemDMA0 Stream 0 Destination Peripheral Map Register */
-#define MDMA0_D0_CURR_X_COUNT 0xFFC00E30 /* MemDMA0 Stream 0 Destination Current X Count Register */
-#define MDMA0_D0_CURR_Y_COUNT 0xFFC00E38 /* MemDMA0 Stream 0 Destination Current Y Count Register */
-
-#define MDMA0_S0_NEXT_DESC_PTR 0xFFC00E40 /* MemDMA0 Stream 0 Source Next Descriptor Pointer Register */
-#define MDMA0_S0_START_ADDR 0xFFC00E44 /* MemDMA0 Stream 0 Source Start Address Register */
-#define MDMA0_S0_CONFIG 0xFFC00E48 /* MemDMA0 Stream 0 Source Configuration Register */
-#define MDMA0_S0_X_COUNT 0xFFC00E50 /* MemDMA0 Stream 0 Source X Count Register */
-#define MDMA0_S0_X_MODIFY 0xFFC00E54 /* MemDMA0 Stream 0 Source X Modify Register */
-#define MDMA0_S0_Y_COUNT 0xFFC00E58 /* MemDMA0 Stream 0 Source Y Count Register */
-#define MDMA0_S0_Y_MODIFY 0xFFC00E5C /* MemDMA0 Stream 0 Source Y Modify Register */
-#define MDMA0_S0_CURR_DESC_PTR 0xFFC00E60 /* MemDMA0 Stream 0 Source Current Descriptor Pointer Register */
-#define MDMA0_S0_CURR_ADDR 0xFFC00E64 /* MemDMA0 Stream 0 Source Current Address Register */
-#define MDMA0_S0_IRQ_STATUS 0xFFC00E68 /* MemDMA0 Stream 0 Source Interrupt/Status Register */
-#define MDMA0_S0_PERIPHERAL_MAP 0xFFC00E6C /* MemDMA0 Stream 0 Source Peripheral Map Register */
-#define MDMA0_S0_CURR_X_COUNT 0xFFC00E70 /* MemDMA0 Stream 0 Source Current X Count Register */
-#define MDMA0_S0_CURR_Y_COUNT 0xFFC00E78 /* MemDMA0 Stream 0 Source Current Y Count Register */
-
-#define MDMA0_D1_NEXT_DESC_PTR 0xFFC00E80 /* MemDMA0 Stream 1 Destination Next Descriptor Pointer Register */
-#define MDMA0_D1_START_ADDR 0xFFC00E84 /* MemDMA0 Stream 1 Destination Start Address Register */
-#define MDMA0_D1_CONFIG 0xFFC00E88 /* MemDMA0 Stream 1 Destination Configuration Register */
-#define MDMA0_D1_X_COUNT 0xFFC00E90 /* MemDMA0 Stream 1 Destination X Count Register */
-#define MDMA0_D1_X_MODIFY 0xFFC00E94 /* MemDMA0 Stream 1 Destination X Modify Register */
-#define MDMA0_D1_Y_COUNT 0xFFC00E98 /* MemDMA0 Stream 1 Destination Y Count Register */
-#define MDMA0_D1_Y_MODIFY 0xFFC00E9C /* MemDMA0 Stream 1 Destination Y Modify Register */
-#define MDMA0_D1_CURR_DESC_PTR 0xFFC00EA0 /* MemDMA0 Stream 1 Destination Current Descriptor Pointer Register */
-#define MDMA0_D1_CURR_ADDR 0xFFC00EA4 /* MemDMA0 Stream 1 Destination Current Address Register */
-#define MDMA0_D1_IRQ_STATUS 0xFFC00EA8 /* MemDMA0 Stream 1 Destination Interrupt/Status Register */
-#define MDMA0_D1_PERIPHERAL_MAP 0xFFC00EAC /* MemDMA0 Stream 1 Destination Peripheral Map Register */
-#define MDMA0_D1_CURR_X_COUNT 0xFFC00EB0 /* MemDMA0 Stream 1 Destination Current X Count Register */
-#define MDMA0_D1_CURR_Y_COUNT 0xFFC00EB8 /* MemDMA0 Stream 1 Destination Current Y Count Register */
-
-#define MDMA0_S1_NEXT_DESC_PTR 0xFFC00EC0 /* MemDMA0 Stream 1 Source Next Descriptor Pointer Register */
-#define MDMA0_S1_START_ADDR 0xFFC00EC4 /* MemDMA0 Stream 1 Source Start Address Register */
-#define MDMA0_S1_CONFIG 0xFFC00EC8 /* MemDMA0 Stream 1 Source Configuration Register */
-#define MDMA0_S1_X_COUNT 0xFFC00ED0 /* MemDMA0 Stream 1 Source X Count Register */
-#define MDMA0_S1_X_MODIFY 0xFFC00ED4 /* MemDMA0 Stream 1 Source X Modify Register */
-#define MDMA0_S1_Y_COUNT 0xFFC00ED8 /* MemDMA0 Stream 1 Source Y Count Register */
-#define MDMA0_S1_Y_MODIFY 0xFFC00EDC /* MemDMA0 Stream 1 Source Y Modify Register */
-#define MDMA0_S1_CURR_DESC_PTR 0xFFC00EE0 /* MemDMA0 Stream 1 Source Current Descriptor Pointer Register */
-#define MDMA0_S1_CURR_ADDR 0xFFC00EE4 /* MemDMA0 Stream 1 Source Current Address Register */
-#define MDMA0_S1_IRQ_STATUS 0xFFC00EE8 /* MemDMA0 Stream 1 Source Interrupt/Status Register */
-#define MDMA0_S1_PERIPHERAL_MAP 0xFFC00EEC /* MemDMA0 Stream 1 Source Peripheral Map Register */
-#define MDMA0_S1_CURR_X_COUNT 0xFFC00EF0 /* MemDMA0 Stream 1 Source Current X Count Register */
-#define MDMA0_S1_CURR_Y_COUNT 0xFFC00EF8 /* MemDMA0 Stream 1 Source Current Y Count Register */
-
-#define MDMA_D0_NEXT_DESC_PTR MDMA0_D0_NEXT_DESC_PTR
-#define MDMA_D0_START_ADDR MDMA0_D0_START_ADDR
-#define MDMA_D0_CONFIG MDMA0_D0_CONFIG
-#define MDMA_D0_X_COUNT MDMA0_D0_X_COUNT
-#define MDMA_D0_X_MODIFY MDMA0_D0_X_MODIFY
-#define MDMA_D0_Y_COUNT MDMA0_D0_Y_COUNT
-#define MDMA_D0_Y_MODIFY MDMA0_D0_Y_MODIFY
-#define MDMA_D0_CURR_DESC_PTR MDMA0_D0_CURR_DESC_PTR
-#define MDMA_D0_CURR_ADDR MDMA0_D0_CURR_ADDR
-#define MDMA_D0_IRQ_STATUS MDMA0_D0_IRQ_STATUS
-#define MDMA_D0_PERIPHERAL_MAP MDMA0_D0_PERIPHERAL_MAP
-#define MDMA_D0_CURR_X_COUNT MDMA0_D0_CURR_X_COUNT
-#define MDMA_D0_CURR_Y_COUNT MDMA0_D0_CURR_Y_COUNT
-
-#define MDMA_S0_NEXT_DESC_PTR MDMA0_S0_NEXT_DESC_PTR
-#define MDMA_S0_START_ADDR MDMA0_S0_START_ADDR
-#define MDMA_S0_CONFIG MDMA0_S0_CONFIG
-#define MDMA_S0_X_COUNT MDMA0_S0_X_COUNT
-#define MDMA_S0_X_MODIFY MDMA0_S0_X_MODIFY
-#define MDMA_S0_Y_COUNT MDMA0_S0_Y_COUNT
-#define MDMA_S0_Y_MODIFY MDMA0_S0_Y_MODIFY
-#define MDMA_S0_CURR_DESC_PTR MDMA0_S0_CURR_DESC_PTR
-#define MDMA_S0_CURR_ADDR MDMA0_S0_CURR_ADDR
-#define MDMA_S0_IRQ_STATUS MDMA0_S0_IRQ_STATUS
-#define MDMA_S0_PERIPHERAL_MAP MDMA0_S0_PERIPHERAL_MAP
-#define MDMA_S0_CURR_X_COUNT MDMA0_S0_CURR_X_COUNT
-#define MDMA_S0_CURR_Y_COUNT MDMA0_S0_CURR_Y_COUNT
-
-#define MDMA_D1_NEXT_DESC_PTR MDMA0_D1_NEXT_DESC_PTR
-#define MDMA_D1_START_ADDR MDMA0_D1_START_ADDR
-#define MDMA_D1_CONFIG MDMA0_D1_CONFIG
-#define MDMA_D1_X_COUNT MDMA0_D1_X_COUNT
-#define MDMA_D1_X_MODIFY MDMA0_D1_X_MODIFY
-#define MDMA_D1_Y_COUNT MDMA0_D1_Y_COUNT
-#define MDMA_D1_Y_MODIFY MDMA0_D1_Y_MODIFY
-#define MDMA_D1_CURR_DESC_PTR MDMA0_D1_CURR_DESC_PTR
-#define MDMA_D1_CURR_ADDR MDMA0_D1_CURR_ADDR
-#define MDMA_D1_IRQ_STATUS MDMA0_D1_IRQ_STATUS
-#define MDMA_D1_PERIPHERAL_MAP MDMA0_D1_PERIPHERAL_MAP
-#define MDMA_D1_CURR_X_COUNT MDMA0_D1_CURR_X_COUNT
-#define MDMA_D1_CURR_Y_COUNT MDMA0_D1_CURR_Y_COUNT
-
-#define MDMA_S1_NEXT_DESC_PTR MDMA0_S1_NEXT_DESC_PTR
-#define MDMA_S1_START_ADDR MDMA0_S1_START_ADDR
-#define MDMA_S1_CONFIG MDMA0_S1_CONFIG
-#define MDMA_S1_X_COUNT MDMA0_S1_X_COUNT
-#define MDMA_S1_X_MODIFY MDMA0_S1_X_MODIFY
-#define MDMA_S1_Y_COUNT MDMA0_S1_Y_COUNT
-#define MDMA_S1_Y_MODIFY MDMA0_S1_Y_MODIFY
-#define MDMA_S1_CURR_DESC_PTR MDMA0_S1_CURR_DESC_PTR
-#define MDMA_S1_CURR_ADDR MDMA0_S1_CURR_ADDR
-#define MDMA_S1_IRQ_STATUS MDMA0_S1_IRQ_STATUS
-#define MDMA_S1_PERIPHERAL_MAP MDMA0_S1_PERIPHERAL_MAP
-#define MDMA_S1_CURR_X_COUNT MDMA0_S1_CURR_X_COUNT
-#define MDMA_S1_CURR_Y_COUNT MDMA0_S1_CURR_Y_COUNT
-
-
-/* Parallel Peripheral Interface (PPI) (0xFFC01000 - 0xFFC010FF) */
-#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
-#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
-#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
-#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
-#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
-
-
-/* Two-Wire Interface 0 (0xFFC01400 - 0xFFC014FF) */
-#define TWI0_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
-#define TWI0_CONTROL 0xFFC01404 /* TWI0 Master Internal Time Reference Register */
-#define TWI0_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
-#define TWI0_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
-#define TWI0_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
-#define TWI0_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
-#define TWI0_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
-#define TWI0_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
-#define TWI0_INT_STAT 0xFFC01420 /* TWI0 Master Interrupt Register */
-#define TWI0_INT_MASK 0xFFC01424 /* TWI0 Master Interrupt Mask Register */
-#define TWI0_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
-#define TWI0_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
-#define TWI0_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
-#define TWI0_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
-#define TWI0_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
-#define TWI0_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
-
-#define TWI0_REGBASE TWI0_CLKDIV
-
-/* the following are for backwards compatibility */
-#define TWI0_PRESCALE TWI0_CONTROL
-#define TWI0_INT_SRC TWI0_INT_STAT
-#define TWI0_INT_ENABLE TWI0_INT_MASK
-
-
-/* General-Purpose Ports (0xFFC01500 - 0xFFC015FF) */
-
-/* GPIO Port C Register Names */
-#define PORTCIO_FER 0xFFC01500 /* GPIO Pin Port C Configuration Register */
-#define PORTCIO 0xFFC01510 /* GPIO Pin Port C Data Register */
-#define PORTCIO_CLEAR 0xFFC01520 /* Clear GPIO Pin Port C Register */
-#define PORTCIO_SET 0xFFC01530 /* Set GPIO Pin Port C Register */
-#define PORTCIO_TOGGLE 0xFFC01540 /* Toggle GPIO Pin Port C Register */
-#define PORTCIO_DIR 0xFFC01550 /* GPIO Pin Port C Direction Register */
-#define PORTCIO_INEN 0xFFC01560 /* GPIO Pin Port C Input Enable Register */
-
-/* GPIO Port D Register Names */
-#define PORTDIO_FER 0xFFC01504 /* GPIO Pin Port D Configuration Register */
-#define PORTDIO 0xFFC01514 /* GPIO Pin Port D Data Register */
-#define PORTDIO_CLEAR 0xFFC01524 /* Clear GPIO Pin Port D Register */
-#define PORTDIO_SET 0xFFC01534 /* Set GPIO Pin Port D Register */
-#define PORTDIO_TOGGLE 0xFFC01544 /* Toggle GPIO Pin Port D Register */
-#define PORTDIO_DIR 0xFFC01554 /* GPIO Pin Port D Direction Register */
-#define PORTDIO_INEN 0xFFC01564 /* GPIO Pin Port D Input Enable Register */
-
-/* GPIO Port E Register Names */
-#define PORTEIO_FER 0xFFC01508 /* GPIO Pin Port E Configuration Register */
-#define PORTEIO 0xFFC01518 /* GPIO Pin Port E Data Register */
-#define PORTEIO_CLEAR 0xFFC01528 /* Clear GPIO Pin Port E Register */
-#define PORTEIO_SET 0xFFC01538 /* Set GPIO Pin Port E Register */
-#define PORTEIO_TOGGLE 0xFFC01548 /* Toggle GPIO Pin Port E Register */
-#define PORTEIO_DIR 0xFFC01558 /* GPIO Pin Port E Direction Register */
-#define PORTEIO_INEN 0xFFC01568 /* GPIO Pin Port E Input Enable Register */
-
-/* DMA Controller 1 Traffic Control Registers (0xFFC01B00 - 0xFFC01BFF) */
-
-#define DMAC1_TC_PER 0xFFC01B0C /* DMA Controller 1 Traffic Control Periods Register */
-#define DMAC1_TC_CNT 0xFFC01B10 /* DMA Controller 1 Traffic Control Current Counts Register */
-
-/* Alternate deprecated register names (below) provided for backwards code compatibility */
-#define DMA1_TCPER DMAC1_TC_PER
-#define DMA1_TCCNT DMAC1_TC_CNT
-
-
-/* DMA Controller 1 (0xFFC01C00 - 0xFFC01FFF) */
-#define DMA8_NEXT_DESC_PTR 0xFFC01C00 /* DMA Channel 8 Next Descriptor Pointer Register */
-#define DMA8_START_ADDR 0xFFC01C04 /* DMA Channel 8 Start Address Register */
-#define DMA8_CONFIG 0xFFC01C08 /* DMA Channel 8 Configuration Register */
-#define DMA8_X_COUNT 0xFFC01C10 /* DMA Channel 8 X Count Register */
-#define DMA8_X_MODIFY 0xFFC01C14 /* DMA Channel 8 X Modify Register */
-#define DMA8_Y_COUNT 0xFFC01C18 /* DMA Channel 8 Y Count Register */
-#define DMA8_Y_MODIFY 0xFFC01C1C /* DMA Channel 8 Y Modify Register */
-#define DMA8_CURR_DESC_PTR 0xFFC01C20 /* DMA Channel 8 Current Descriptor Pointer Register */
-#define DMA8_CURR_ADDR 0xFFC01C24 /* DMA Channel 8 Current Address Register */
-#define DMA8_IRQ_STATUS 0xFFC01C28 /* DMA Channel 8 Interrupt/Status Register */
-#define DMA8_PERIPHERAL_MAP 0xFFC01C2C /* DMA Channel 8 Peripheral Map Register */
-#define DMA8_CURR_X_COUNT 0xFFC01C30 /* DMA Channel 8 Current X Count Register */
-#define DMA8_CURR_Y_COUNT 0xFFC01C38 /* DMA Channel 8 Current Y Count Register */
-
-#define DMA9_NEXT_DESC_PTR 0xFFC01C40 /* DMA Channel 9 Next Descriptor Pointer Register */
-#define DMA9_START_ADDR 0xFFC01C44 /* DMA Channel 9 Start Address Register */
-#define DMA9_CONFIG 0xFFC01C48 /* DMA Channel 9 Configuration Register */
-#define DMA9_X_COUNT 0xFFC01C50 /* DMA Channel 9 X Count Register */
-#define DMA9_X_MODIFY 0xFFC01C54 /* DMA Channel 9 X Modify Register */
-#define DMA9_Y_COUNT 0xFFC01C58 /* DMA Channel 9 Y Count Register */
-#define DMA9_Y_MODIFY 0xFFC01C5C /* DMA Channel 9 Y Modify Register */
-#define DMA9_CURR_DESC_PTR 0xFFC01C60 /* DMA Channel 9 Current Descriptor Pointer Register */
-#define DMA9_CURR_ADDR 0xFFC01C64 /* DMA Channel 9 Current Address Register */
-#define DMA9_IRQ_STATUS 0xFFC01C68 /* DMA Channel 9 Interrupt/Status Register */
-#define DMA9_PERIPHERAL_MAP 0xFFC01C6C /* DMA Channel 9 Peripheral Map Register */
-#define DMA9_CURR_X_COUNT 0xFFC01C70 /* DMA Channel 9 Current X Count Register */
-#define DMA9_CURR_Y_COUNT 0xFFC01C78 /* DMA Channel 9 Current Y Count Register */
-
-#define DMA10_NEXT_DESC_PTR 0xFFC01C80 /* DMA Channel 10 Next Descriptor Pointer Register */
-#define DMA10_START_ADDR 0xFFC01C84 /* DMA Channel 10 Start Address Register */
-#define DMA10_CONFIG 0xFFC01C88 /* DMA Channel 10 Configuration Register */
-#define DMA10_X_COUNT 0xFFC01C90 /* DMA Channel 10 X Count Register */
-#define DMA10_X_MODIFY 0xFFC01C94 /* DMA Channel 10 X Modify Register */
-#define DMA10_Y_COUNT 0xFFC01C98 /* DMA Channel 10 Y Count Register */
-#define DMA10_Y_MODIFY 0xFFC01C9C /* DMA Channel 10 Y Modify Register */
-#define DMA10_CURR_DESC_PTR 0xFFC01CA0 /* DMA Channel 10 Current Descriptor Pointer Register */
-#define DMA10_CURR_ADDR 0xFFC01CA4 /* DMA Channel 10 Current Address Register */
-#define DMA10_IRQ_STATUS 0xFFC01CA8 /* DMA Channel 10 Interrupt/Status Register */
-#define DMA10_PERIPHERAL_MAP 0xFFC01CAC /* DMA Channel 10 Peripheral Map Register */
-#define DMA10_CURR_X_COUNT 0xFFC01CB0 /* DMA Channel 10 Current X Count Register */
-#define DMA10_CURR_Y_COUNT 0xFFC01CB8 /* DMA Channel 10 Current Y Count Register */
-
-#define DMA11_NEXT_DESC_PTR 0xFFC01CC0 /* DMA Channel 11 Next Descriptor Pointer Register */
-#define DMA11_START_ADDR 0xFFC01CC4 /* DMA Channel 11 Start Address Register */
-#define DMA11_CONFIG 0xFFC01CC8 /* DMA Channel 11 Configuration Register */
-#define DMA11_X_COUNT 0xFFC01CD0 /* DMA Channel 11 X Count Register */
-#define DMA11_X_MODIFY 0xFFC01CD4 /* DMA Channel 11 X Modify Register */
-#define DMA11_Y_COUNT 0xFFC01CD8 /* DMA Channel 11 Y Count Register */
-#define DMA11_Y_MODIFY 0xFFC01CDC /* DMA Channel 11 Y Modify Register */
-#define DMA11_CURR_DESC_PTR 0xFFC01CE0 /* DMA Channel 11 Current Descriptor Pointer Register */
-#define DMA11_CURR_ADDR 0xFFC01CE4 /* DMA Channel 11 Current Address Register */
-#define DMA11_IRQ_STATUS 0xFFC01CE8 /* DMA Channel 11 Interrupt/Status Register */
-#define DMA11_PERIPHERAL_MAP 0xFFC01CEC /* DMA Channel 11 Peripheral Map Register */
-#define DMA11_CURR_X_COUNT 0xFFC01CF0 /* DMA Channel 11 Current X Count Register */
-#define DMA11_CURR_Y_COUNT 0xFFC01CF8 /* DMA Channel 11 Current Y Count Register */
-
-#define DMA12_NEXT_DESC_PTR 0xFFC01D00 /* DMA Channel 12 Next Descriptor Pointer Register */
-#define DMA12_START_ADDR 0xFFC01D04 /* DMA Channel 12 Start Address Register */
-#define DMA12_CONFIG 0xFFC01D08 /* DMA Channel 12 Configuration Register */
-#define DMA12_X_COUNT 0xFFC01D10 /* DMA Channel 12 X Count Register */
-#define DMA12_X_MODIFY 0xFFC01D14 /* DMA Channel 12 X Modify Register */
-#define DMA12_Y_COUNT 0xFFC01D18 /* DMA Channel 12 Y Count Register */
-#define DMA12_Y_MODIFY 0xFFC01D1C /* DMA Channel 12 Y Modify Register */
-#define DMA12_CURR_DESC_PTR 0xFFC01D20 /* DMA Channel 12 Current Descriptor Pointer Register */
-#define DMA12_CURR_ADDR 0xFFC01D24 /* DMA Channel 12 Current Address Register */
-#define DMA12_IRQ_STATUS 0xFFC01D28 /* DMA Channel 12 Interrupt/Status Register */
-#define DMA12_PERIPHERAL_MAP 0xFFC01D2C /* DMA Channel 12 Peripheral Map Register */
-#define DMA12_CURR_X_COUNT 0xFFC01D30 /* DMA Channel 12 Current X Count Register */
-#define DMA12_CURR_Y_COUNT 0xFFC01D38 /* DMA Channel 12 Current Y Count Register */
-
-#define DMA13_NEXT_DESC_PTR 0xFFC01D40 /* DMA Channel 13 Next Descriptor Pointer Register */
-#define DMA13_START_ADDR 0xFFC01D44 /* DMA Channel 13 Start Address Register */
-#define DMA13_CONFIG 0xFFC01D48 /* DMA Channel 13 Configuration Register */
-#define DMA13_X_COUNT 0xFFC01D50 /* DMA Channel 13 X Count Register */
-#define DMA13_X_MODIFY 0xFFC01D54 /* DMA Channel 13 X Modify Register */
-#define DMA13_Y_COUNT 0xFFC01D58 /* DMA Channel 13 Y Count Register */
-#define DMA13_Y_MODIFY 0xFFC01D5C /* DMA Channel 13 Y Modify Register */
-#define DMA13_CURR_DESC_PTR 0xFFC01D60 /* DMA Channel 13 Current Descriptor Pointer Register */
-#define DMA13_CURR_ADDR 0xFFC01D64 /* DMA Channel 13 Current Address Register */
-#define DMA13_IRQ_STATUS 0xFFC01D68 /* DMA Channel 13 Interrupt/Status Register */
-#define DMA13_PERIPHERAL_MAP 0xFFC01D6C /* DMA Channel 13 Peripheral Map Register */
-#define DMA13_CURR_X_COUNT 0xFFC01D70 /* DMA Channel 13 Current X Count Register */
-#define DMA13_CURR_Y_COUNT 0xFFC01D78 /* DMA Channel 13 Current Y Count Register */
-
-#define DMA14_NEXT_DESC_PTR 0xFFC01D80 /* DMA Channel 14 Next Descriptor Pointer Register */
-#define DMA14_START_ADDR 0xFFC01D84 /* DMA Channel 14 Start Address Register */
-#define DMA14_CONFIG 0xFFC01D88 /* DMA Channel 14 Configuration Register */
-#define DMA14_X_COUNT 0xFFC01D90 /* DMA Channel 14 X Count Register */
-#define DMA14_X_MODIFY 0xFFC01D94 /* DMA Channel 14 X Modify Register */
-#define DMA14_Y_COUNT 0xFFC01D98 /* DMA Channel 14 Y Count Register */
-#define DMA14_Y_MODIFY 0xFFC01D9C /* DMA Channel 14 Y Modify Register */
-#define DMA14_CURR_DESC_PTR 0xFFC01DA0 /* DMA Channel 14 Current Descriptor Pointer Register */
-#define DMA14_CURR_ADDR 0xFFC01DA4 /* DMA Channel 14 Current Address Register */
-#define DMA14_IRQ_STATUS 0xFFC01DA8 /* DMA Channel 14 Interrupt/Status Register */
-#define DMA14_PERIPHERAL_MAP 0xFFC01DAC /* DMA Channel 14 Peripheral Map Register */
-#define DMA14_CURR_X_COUNT 0xFFC01DB0 /* DMA Channel 14 Current X Count Register */
-#define DMA14_CURR_Y_COUNT 0xFFC01DB8 /* DMA Channel 14 Current Y Count Register */
-
-#define DMA15_NEXT_DESC_PTR 0xFFC01DC0 /* DMA Channel 15 Next Descriptor Pointer Register */
-#define DMA15_START_ADDR 0xFFC01DC4 /* DMA Channel 15 Start Address Register */
-#define DMA15_CONFIG 0xFFC01DC8 /* DMA Channel 15 Configuration Register */
-#define DMA15_X_COUNT 0xFFC01DD0 /* DMA Channel 15 X Count Register */
-#define DMA15_X_MODIFY 0xFFC01DD4 /* DMA Channel 15 X Modify Register */
-#define DMA15_Y_COUNT 0xFFC01DD8 /* DMA Channel 15 Y Count Register */
-#define DMA15_Y_MODIFY 0xFFC01DDC /* DMA Channel 15 Y Modify Register */
-#define DMA15_CURR_DESC_PTR 0xFFC01DE0 /* DMA Channel 15 Current Descriptor Pointer Register */
-#define DMA15_CURR_ADDR 0xFFC01DE4 /* DMA Channel 15 Current Address Register */
-#define DMA15_IRQ_STATUS 0xFFC01DE8 /* DMA Channel 15 Interrupt/Status Register */
-#define DMA15_PERIPHERAL_MAP 0xFFC01DEC /* DMA Channel 15 Peripheral Map Register */
-#define DMA15_CURR_X_COUNT 0xFFC01DF0 /* DMA Channel 15 Current X Count Register */
-#define DMA15_CURR_Y_COUNT 0xFFC01DF8 /* DMA Channel 15 Current Y Count Register */
-
-#define DMA16_NEXT_DESC_PTR 0xFFC01E00 /* DMA Channel 16 Next Descriptor Pointer Register */
-#define DMA16_START_ADDR 0xFFC01E04 /* DMA Channel 16 Start Address Register */
-#define DMA16_CONFIG 0xFFC01E08 /* DMA Channel 16 Configuration Register */
-#define DMA16_X_COUNT 0xFFC01E10 /* DMA Channel 16 X Count Register */
-#define DMA16_X_MODIFY 0xFFC01E14 /* DMA Channel 16 X Modify Register */
-#define DMA16_Y_COUNT 0xFFC01E18 /* DMA Channel 16 Y Count Register */
-#define DMA16_Y_MODIFY 0xFFC01E1C /* DMA Channel 16 Y Modify Register */
-#define DMA16_CURR_DESC_PTR 0xFFC01E20 /* DMA Channel 16 Current Descriptor Pointer Register */
-#define DMA16_CURR_ADDR 0xFFC01E24 /* DMA Channel 16 Current Address Register */
-#define DMA16_IRQ_STATUS 0xFFC01E28 /* DMA Channel 16 Interrupt/Status Register */
-#define DMA16_PERIPHERAL_MAP 0xFFC01E2C /* DMA Channel 16 Peripheral Map Register */
-#define DMA16_CURR_X_COUNT 0xFFC01E30 /* DMA Channel 16 Current X Count Register */
-#define DMA16_CURR_Y_COUNT 0xFFC01E38 /* DMA Channel 16 Current Y Count Register */
-
-#define DMA17_NEXT_DESC_PTR 0xFFC01E40 /* DMA Channel 17 Next Descriptor Pointer Register */
-#define DMA17_START_ADDR 0xFFC01E44 /* DMA Channel 17 Start Address Register */
-#define DMA17_CONFIG 0xFFC01E48 /* DMA Channel 17 Configuration Register */
-#define DMA17_X_COUNT 0xFFC01E50 /* DMA Channel 17 X Count Register */
-#define DMA17_X_MODIFY 0xFFC01E54 /* DMA Channel 17 X Modify Register */
-#define DMA17_Y_COUNT 0xFFC01E58 /* DMA Channel 17 Y Count Register */
-#define DMA17_Y_MODIFY 0xFFC01E5C /* DMA Channel 17 Y Modify Register */
-#define DMA17_CURR_DESC_PTR 0xFFC01E60 /* DMA Channel 17 Current Descriptor Pointer Register */
-#define DMA17_CURR_ADDR 0xFFC01E64 /* DMA Channel 17 Current Address Register */
-#define DMA17_IRQ_STATUS 0xFFC01E68 /* DMA Channel 17 Interrupt/Status Register */
-#define DMA17_PERIPHERAL_MAP 0xFFC01E6C /* DMA Channel 17 Peripheral Map Register */
-#define DMA17_CURR_X_COUNT 0xFFC01E70 /* DMA Channel 17 Current X Count Register */
-#define DMA17_CURR_Y_COUNT 0xFFC01E78 /* DMA Channel 17 Current Y Count Register */
-
-#define DMA18_NEXT_DESC_PTR 0xFFC01E80 /* DMA Channel 18 Next Descriptor Pointer Register */
-#define DMA18_START_ADDR 0xFFC01E84 /* DMA Channel 18 Start Address Register */
-#define DMA18_CONFIG 0xFFC01E88 /* DMA Channel 18 Configuration Register */
-#define DMA18_X_COUNT 0xFFC01E90 /* DMA Channel 18 X Count Register */
-#define DMA18_X_MODIFY 0xFFC01E94 /* DMA Channel 18 X Modify Register */
-#define DMA18_Y_COUNT 0xFFC01E98 /* DMA Channel 18 Y Count Register */
-#define DMA18_Y_MODIFY 0xFFC01E9C /* DMA Channel 18 Y Modify Register */
-#define DMA18_CURR_DESC_PTR 0xFFC01EA0 /* DMA Channel 18 Current Descriptor Pointer Register */
-#define DMA18_CURR_ADDR 0xFFC01EA4 /* DMA Channel 18 Current Address Register */
-#define DMA18_IRQ_STATUS 0xFFC01EA8 /* DMA Channel 18 Interrupt/Status Register */
-#define DMA18_PERIPHERAL_MAP 0xFFC01EAC /* DMA Channel 18 Peripheral Map Register */
-#define DMA18_CURR_X_COUNT 0xFFC01EB0 /* DMA Channel 18 Current X Count Register */
-#define DMA18_CURR_Y_COUNT 0xFFC01EB8 /* DMA Channel 18 Current Y Count Register */
-
-#define DMA19_NEXT_DESC_PTR 0xFFC01EC0 /* DMA Channel 19 Next Descriptor Pointer Register */
-#define DMA19_START_ADDR 0xFFC01EC4 /* DMA Channel 19 Start Address Register */
-#define DMA19_CONFIG 0xFFC01EC8 /* DMA Channel 19 Configuration Register */
-#define DMA19_X_COUNT 0xFFC01ED0 /* DMA Channel 19 X Count Register */
-#define DMA19_X_MODIFY 0xFFC01ED4 /* DMA Channel 19 X Modify Register */
-#define DMA19_Y_COUNT 0xFFC01ED8 /* DMA Channel 19 Y Count Register */
-#define DMA19_Y_MODIFY 0xFFC01EDC /* DMA Channel 19 Y Modify Register */
-#define DMA19_CURR_DESC_PTR 0xFFC01EE0 /* DMA Channel 19 Current Descriptor Pointer Register */
-#define DMA19_CURR_ADDR 0xFFC01EE4 /* DMA Channel 19 Current Address Register */
-#define DMA19_IRQ_STATUS 0xFFC01EE8 /* DMA Channel 19 Interrupt/Status Register */
-#define DMA19_PERIPHERAL_MAP 0xFFC01EEC /* DMA Channel 19 Peripheral Map Register */
-#define DMA19_CURR_X_COUNT 0xFFC01EF0 /* DMA Channel 19 Current X Count Register */
-#define DMA19_CURR_Y_COUNT 0xFFC01EF8 /* DMA Channel 19 Current Y Count Register */
-
-#define MDMA1_D0_NEXT_DESC_PTR 0xFFC01F00 /* MemDMA1 Stream 0 Destination Next Descriptor Pointer Register */
-#define MDMA1_D0_START_ADDR 0xFFC01F04 /* MemDMA1 Stream 0 Destination Start Address Register */
-#define MDMA1_D0_CONFIG 0xFFC01F08 /* MemDMA1 Stream 0 Destination Configuration Register */
-#define MDMA1_D0_X_COUNT 0xFFC01F10 /* MemDMA1 Stream 0 Destination X Count Register */
-#define MDMA1_D0_X_MODIFY 0xFFC01F14 /* MemDMA1 Stream 0 Destination X Modify Register */
-#define MDMA1_D0_Y_COUNT 0xFFC01F18 /* MemDMA1 Stream 0 Destination Y Count Register */
-#define MDMA1_D0_Y_MODIFY 0xFFC01F1C /* MemDMA1 Stream 0 Destination Y Modify Register */
-#define MDMA1_D0_CURR_DESC_PTR 0xFFC01F20 /* MemDMA1 Stream 0 Destination Current Descriptor Pointer Register */
-#define MDMA1_D0_CURR_ADDR 0xFFC01F24 /* MemDMA1 Stream 0 Destination Current Address Register */
-#define MDMA1_D0_IRQ_STATUS 0xFFC01F28 /* MemDMA1 Stream 0 Destination Interrupt/Status Register */
-#define MDMA1_D0_PERIPHERAL_MAP 0xFFC01F2C /* MemDMA1 Stream 0 Destination Peripheral Map Register */
-#define MDMA1_D0_CURR_X_COUNT 0xFFC01F30 /* MemDMA1 Stream 0 Destination Current X Count Register */
-#define MDMA1_D0_CURR_Y_COUNT 0xFFC01F38 /* MemDMA1 Stream 0 Destination Current Y Count Register */
-
-#define MDMA1_S0_NEXT_DESC_PTR 0xFFC01F40 /* MemDMA1 Stream 0 Source Next Descriptor Pointer Register */
-#define MDMA1_S0_START_ADDR 0xFFC01F44 /* MemDMA1 Stream 0 Source Start Address Register */
-#define MDMA1_S0_CONFIG 0xFFC01F48 /* MemDMA1 Stream 0 Source Configuration Register */
-#define MDMA1_S0_X_COUNT 0xFFC01F50 /* MemDMA1 Stream 0 Source X Count Register */
-#define MDMA1_S0_X_MODIFY 0xFFC01F54 /* MemDMA1 Stream 0 Source X Modify Register */
-#define MDMA1_S0_Y_COUNT 0xFFC01F58 /* MemDMA1 Stream 0 Source Y Count Register */
-#define MDMA1_S0_Y_MODIFY 0xFFC01F5C /* MemDMA1 Stream 0 Source Y Modify Register */
-#define MDMA1_S0_CURR_DESC_PTR 0xFFC01F60 /* MemDMA1 Stream 0 Source Current Descriptor Pointer Register */
-#define MDMA1_S0_CURR_ADDR 0xFFC01F64 /* MemDMA1 Stream 0 Source Current Address Register */
-#define MDMA1_S0_IRQ_STATUS 0xFFC01F68 /* MemDMA1 Stream 0 Source Interrupt/Status Register */
-#define MDMA1_S0_PERIPHERAL_MAP 0xFFC01F6C /* MemDMA1 Stream 0 Source Peripheral Map Register */
-#define MDMA1_S0_CURR_X_COUNT 0xFFC01F70 /* MemDMA1 Stream 0 Source Current X Count Register */
-#define MDMA1_S0_CURR_Y_COUNT 0xFFC01F78 /* MemDMA1 Stream 0 Source Current Y Count Register */
-
-#define MDMA1_D1_NEXT_DESC_PTR 0xFFC01F80 /* MemDMA1 Stream 1 Destination Next Descriptor Pointer Register */
-#define MDMA1_D1_START_ADDR 0xFFC01F84 /* MemDMA1 Stream 1 Destination Start Address Register */
-#define MDMA1_D1_CONFIG 0xFFC01F88 /* MemDMA1 Stream 1 Destination Configuration Register */
-#define MDMA1_D1_X_COUNT 0xFFC01F90 /* MemDMA1 Stream 1 Destination X Count Register */
-#define MDMA1_D1_X_MODIFY 0xFFC01F94 /* MemDMA1 Stream 1 Destination X Modify Register */
-#define MDMA1_D1_Y_COUNT 0xFFC01F98 /* MemDMA1 Stream 1 Destination Y Count Register */
-#define MDMA1_D1_Y_MODIFY 0xFFC01F9C /* MemDMA1 Stream 1 Destination Y Modify Register */
-#define MDMA1_D1_CURR_DESC_PTR 0xFFC01FA0 /* MemDMA1 Stream 1 Destination Current Descriptor Pointer Register */
-#define MDMA1_D1_CURR_ADDR 0xFFC01FA4 /* MemDMA1 Stream 1 Destination Current Address Register */
-#define MDMA1_D1_IRQ_STATUS 0xFFC01FA8 /* MemDMA1 Stream 1 Destination Interrupt/Status Register */
-#define MDMA1_D1_PERIPHERAL_MAP 0xFFC01FAC /* MemDMA1 Stream 1 Destination Peripheral Map Register */
-#define MDMA1_D1_CURR_X_COUNT 0xFFC01FB0 /* MemDMA1 Stream 1 Destination Current X Count Register */
-#define MDMA1_D1_CURR_Y_COUNT 0xFFC01FB8 /* MemDMA1 Stream 1 Destination Current Y Count Register */
-
-#define MDMA1_S1_NEXT_DESC_PTR 0xFFC01FC0 /* MemDMA1 Stream 1 Source Next Descriptor Pointer Register */
-#define MDMA1_S1_START_ADDR 0xFFC01FC4 /* MemDMA1 Stream 1 Source Start Address Register */
-#define MDMA1_S1_CONFIG 0xFFC01FC8 /* MemDMA1 Stream 1 Source Configuration Register */
-#define MDMA1_S1_X_COUNT 0xFFC01FD0 /* MemDMA1 Stream 1 Source X Count Register */
-#define MDMA1_S1_X_MODIFY 0xFFC01FD4 /* MemDMA1 Stream 1 Source X Modify Register */
-#define MDMA1_S1_Y_COUNT 0xFFC01FD8 /* MemDMA1 Stream 1 Source Y Count Register */
-#define MDMA1_S1_Y_MODIFY 0xFFC01FDC /* MemDMA1 Stream 1 Source Y Modify Register */
-#define MDMA1_S1_CURR_DESC_PTR 0xFFC01FE0 /* MemDMA1 Stream 1 Source Current Descriptor Pointer Register */
-#define MDMA1_S1_CURR_ADDR 0xFFC01FE4 /* MemDMA1 Stream 1 Source Current Address Register */
-#define MDMA1_S1_IRQ_STATUS 0xFFC01FE8 /* MemDMA1 Stream 1 Source Interrupt/Status Register */
-#define MDMA1_S1_PERIPHERAL_MAP 0xFFC01FEC /* MemDMA1 Stream 1 Source Peripheral Map Register */
-#define MDMA1_S1_CURR_X_COUNT 0xFFC01FF0 /* MemDMA1 Stream 1 Source Current X Count Register */
-#define MDMA1_S1_CURR_Y_COUNT 0xFFC01FF8 /* MemDMA1 Stream 1 Source Current Y Count Register */
-
-
-/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
-#define UART1_THR 0xFFC02000 /* Transmit Holding register */
-#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
-#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
-#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
-#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
-#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
-#define UART1_LCR 0xFFC0200C /* Line Control Register */
-#define UART1_MCR 0xFFC02010 /* Modem Control Register */
-#define UART1_LSR 0xFFC02014 /* Line Status Register */
-#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
-#define UART1_GCTL 0xFFC02024 /* Global Control Register */
-
-
-/* UART2 Controller (0xFFC02100 - 0xFFC021FF) */
-#define UART2_THR 0xFFC02100 /* Transmit Holding register */
-#define UART2_RBR 0xFFC02100 /* Receive Buffer register */
-#define UART2_DLL 0xFFC02100 /* Divisor Latch (Low-Byte) */
-#define UART2_IER 0xFFC02104 /* Interrupt Enable Register */
-#define UART2_DLH 0xFFC02104 /* Divisor Latch (High-Byte) */
-#define UART2_IIR 0xFFC02108 /* Interrupt Identification Register */
-#define UART2_LCR 0xFFC0210C /* Line Control Register */
-#define UART2_MCR 0xFFC02110 /* Modem Control Register */
-#define UART2_LSR 0xFFC02114 /* Line Status Register */
-#define UART2_SCR 0xFFC0211C /* SCR Scratch Register */
-#define UART2_GCTL 0xFFC02124 /* Global Control Register */
-
-
-/* Two-Wire Interface 1 (0xFFC02200 - 0xFFC022FF) */
-#define TWI1_CLKDIV 0xFFC02200 /* Serial Clock Divider Register */
-#define TWI1_CONTROL 0xFFC02204 /* TWI1 Master Internal Time Reference Register */
-#define TWI1_SLAVE_CTL 0xFFC02208 /* Slave Mode Control Register */
-#define TWI1_SLAVE_STAT 0xFFC0220C /* Slave Mode Status Register */
-#define TWI1_SLAVE_ADDR 0xFFC02210 /* Slave Mode Address Register */
-#define TWI1_MASTER_CTL 0xFFC02214 /* Master Mode Control Register */
-#define TWI1_MASTER_STAT 0xFFC02218 /* Master Mode Status Register */
-#define TWI1_MASTER_ADDR 0xFFC0221C /* Master Mode Address Register */
-#define TWI1_INT_STAT 0xFFC02220 /* TWI1 Master Interrupt Register */
-#define TWI1_INT_MASK 0xFFC02224 /* TWI1 Master Interrupt Mask Register */
-#define TWI1_FIFO_CTL 0xFFC02228 /* FIFO Control Register */
-#define TWI1_FIFO_STAT 0xFFC0222C /* FIFO Status Register */
-#define TWI1_XMT_DATA8 0xFFC02280 /* FIFO Transmit Data Single Byte Register */
-#define TWI1_XMT_DATA16 0xFFC02284 /* FIFO Transmit Data Double Byte Register */
-#define TWI1_RCV_DATA8 0xFFC02288 /* FIFO Receive Data Single Byte Register */
-#define TWI1_RCV_DATA16 0xFFC0228C /* FIFO Receive Data Double Byte Register */
-#define TWI1_REGBASE TWI1_CLKDIV
-
-
-/* the following are for backwards compatibility */
-#define TWI1_PRESCALE TWI1_CONTROL
-#define TWI1_INT_SRC TWI1_INT_STAT
-#define TWI1_INT_ENABLE TWI1_INT_MASK
-
-
-/* SPI1 Controller (0xFFC02300 - 0xFFC023FF) */
-#define SPI1_CTL 0xFFC02300 /* SPI1 Control Register */
-#define SPI1_FLG 0xFFC02304 /* SPI1 Flag register */
-#define SPI1_STAT 0xFFC02308 /* SPI1 Status register */
-#define SPI1_TDBR 0xFFC0230C /* SPI1 Transmit Data Buffer Register */
-#define SPI1_RDBR 0xFFC02310 /* SPI1 Receive Data Buffer Register */
-#define SPI1_BAUD 0xFFC02314 /* SPI1 Baud rate Register */
-#define SPI1_SHADOW 0xFFC02318 /* SPI1_RDBR Shadow Register */
-#define SPI1_REGBASE SPI1_CTL
-
-/* SPI2 Controller (0xFFC02400 - 0xFFC024FF) */
-#define SPI2_CTL 0xFFC02400 /* SPI2 Control Register */
-#define SPI2_FLG 0xFFC02404 /* SPI2 Flag register */
-#define SPI2_STAT 0xFFC02408 /* SPI2 Status register */
-#define SPI2_TDBR 0xFFC0240C /* SPI2 Transmit Data Buffer Register */
-#define SPI2_RDBR 0xFFC02410 /* SPI2 Receive Data Buffer Register */
-#define SPI2_BAUD 0xFFC02414 /* SPI2 Baud rate Register */
-#define SPI2_SHADOW 0xFFC02418 /* SPI2_RDBR Shadow Register */
-#define SPI2_REGBASE SPI2_CTL
-
-/* SPORT2 Controller (0xFFC02500 - 0xFFC025FF) */
-#define SPORT2_TCR1 0xFFC02500 /* SPORT2 Transmit Configuration 1 Register */
-#define SPORT2_TCR2 0xFFC02504 /* SPORT2 Transmit Configuration 2 Register */
-#define SPORT2_TCLKDIV 0xFFC02508 /* SPORT2 Transmit Clock Divider */
-#define SPORT2_TFSDIV 0xFFC0250C /* SPORT2 Transmit Frame Sync Divider */
-#define SPORT2_TX 0xFFC02510 /* SPORT2 TX Data Register */
-#define SPORT2_RX 0xFFC02518 /* SPORT2 RX Data Register */
-#define SPORT2_RCR1 0xFFC02520 /* SPORT2 Transmit Configuration 1 Register */
-#define SPORT2_RCR2 0xFFC02524 /* SPORT2 Transmit Configuration 2 Register */
-#define SPORT2_RCLKDIV 0xFFC02528 /* SPORT2 Receive Clock Divider */
-#define SPORT2_RFSDIV 0xFFC0252C /* SPORT2 Receive Frame Sync Divider */
-#define SPORT2_STAT 0xFFC02530 /* SPORT2 Status Register */
-#define SPORT2_CHNL 0xFFC02534 /* SPORT2 Current Channel Register */
-#define SPORT2_MCMC1 0xFFC02538 /* SPORT2 Multi-Channel Configuration Register 1 */
-#define SPORT2_MCMC2 0xFFC0253C /* SPORT2 Multi-Channel Configuration Register 2 */
-#define SPORT2_MTCS0 0xFFC02540 /* SPORT2 Multi-Channel Transmit Select Register 0 */
-#define SPORT2_MTCS1 0xFFC02544 /* SPORT2 Multi-Channel Transmit Select Register 1 */
-#define SPORT2_MTCS2 0xFFC02548 /* SPORT2 Multi-Channel Transmit Select Register 2 */
-#define SPORT2_MTCS3 0xFFC0254C /* SPORT2 Multi-Channel Transmit Select Register 3 */
-#define SPORT2_MRCS0 0xFFC02550 /* SPORT2 Multi-Channel Receive Select Register 0 */
-#define SPORT2_MRCS1 0xFFC02554 /* SPORT2 Multi-Channel Receive Select Register 1 */
-#define SPORT2_MRCS2 0xFFC02558 /* SPORT2 Multi-Channel Receive Select Register 2 */
-#define SPORT2_MRCS3 0xFFC0255C /* SPORT2 Multi-Channel Receive Select Register 3 */
-
-
-/* SPORT3 Controller (0xFFC02600 - 0xFFC026FF) */
-#define SPORT3_TCR1 0xFFC02600 /* SPORT3 Transmit Configuration 1 Register */
-#define SPORT3_TCR2 0xFFC02604 /* SPORT3 Transmit Configuration 2 Register */
-#define SPORT3_TCLKDIV 0xFFC02608 /* SPORT3 Transmit Clock Divider */
-#define SPORT3_TFSDIV 0xFFC0260C /* SPORT3 Transmit Frame Sync Divider */
-#define SPORT3_TX 0xFFC02610 /* SPORT3 TX Data Register */
-#define SPORT3_RX 0xFFC02618 /* SPORT3 RX Data Register */
-#define SPORT3_RCR1 0xFFC02620 /* SPORT3 Transmit Configuration 1 Register */
-#define SPORT3_RCR2 0xFFC02624 /* SPORT3 Transmit Configuration 2 Register */
-#define SPORT3_RCLKDIV 0xFFC02628 /* SPORT3 Receive Clock Divider */
-#define SPORT3_RFSDIV 0xFFC0262C /* SPORT3 Receive Frame Sync Divider */
-#define SPORT3_STAT 0xFFC02630 /* SPORT3 Status Register */
-#define SPORT3_CHNL 0xFFC02634 /* SPORT3 Current Channel Register */
-#define SPORT3_MCMC1 0xFFC02638 /* SPORT3 Multi-Channel Configuration Register 1 */
-#define SPORT3_MCMC2 0xFFC0263C /* SPORT3 Multi-Channel Configuration Register 2 */
-#define SPORT3_MTCS0 0xFFC02640 /* SPORT3 Multi-Channel Transmit Select Register 0 */
-#define SPORT3_MTCS1 0xFFC02644 /* SPORT3 Multi-Channel Transmit Select Register 1 */
-#define SPORT3_MTCS2 0xFFC02648 /* SPORT3 Multi-Channel Transmit Select Register 2 */
-#define SPORT3_MTCS3 0xFFC0264C /* SPORT3 Multi-Channel Transmit Select Register 3 */
-#define SPORT3_MRCS0 0xFFC02650 /* SPORT3 Multi-Channel Receive Select Register 0 */
-#define SPORT3_MRCS1 0xFFC02654 /* SPORT3 Multi-Channel Receive Select Register 1 */
-#define SPORT3_MRCS2 0xFFC02658 /* SPORT3 Multi-Channel Receive Select Register 2 */
-#define SPORT3_MRCS3 0xFFC0265C /* SPORT3 Multi-Channel Receive Select Register 3 */
-
+#include "defBF538.h"
/* Media Transceiver (MXVR) (0xFFC02700 - 0xFFC028FF) */
@@ -995,1249 +149,4 @@
#define MXVR_BLOCK_CNT 0xFFC028C0 /* MXVR Block Counter */
#define MXVR_PLL_CTL_2 0xFFC028C4 /* MXVR Phase Lock Loop Control Register 2 */
-
-/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */
-/* For Mailboxes 0-15 */
-#define CAN_MC1 0xFFC02A00 /* Mailbox config reg 1 */
-#define CAN_MD1 0xFFC02A04 /* Mailbox direction reg 1 */
-#define CAN_TRS1 0xFFC02A08 /* Transmit Request Set reg 1 */
-#define CAN_TRR1 0xFFC02A0C /* Transmit Request Reset reg 1 */
-#define CAN_TA1 0xFFC02A10 /* Transmit Acknowledge reg 1 */
-#define CAN_AA1 0xFFC02A14 /* Transmit Abort Acknowledge reg 1 */
-#define CAN_RMP1 0xFFC02A18 /* Receive Message Pending reg 1 */
-#define CAN_RML1 0xFFC02A1C /* Receive Message Lost reg 1 */
-#define CAN_MBTIF1 0xFFC02A20 /* Mailbox Transmit Interrupt Flag reg 1 */
-#define CAN_MBRIF1 0xFFC02A24 /* Mailbox Receive Interrupt Flag reg 1 */
-#define CAN_MBIM1 0xFFC02A28 /* Mailbox Interrupt Mask reg 1 */
-#define CAN_RFH1 0xFFC02A2C /* Remote Frame Handling reg 1 */
-#define CAN_OPSS1 0xFFC02A30 /* Overwrite Protection Single Shot Xmission reg 1 */
-
-/* For Mailboxes 16-31 */
-#define CAN_MC2 0xFFC02A40 /* Mailbox config reg 2 */
-#define CAN_MD2 0xFFC02A44 /* Mailbox direction reg 2 */
-#define CAN_TRS2 0xFFC02A48 /* Transmit Request Set reg 2 */
-#define CAN_TRR2 0xFFC02A4C /* Transmit Request Reset reg 2 */
-#define CAN_TA2 0xFFC02A50 /* Transmit Acknowledge reg 2 */
-#define CAN_AA2 0xFFC02A54 /* Transmit Abort Acknowledge reg 2 */
-#define CAN_RMP2 0xFFC02A58 /* Receive Message Pending reg 2 */
-#define CAN_RML2 0xFFC02A5C /* Receive Message Lost reg 2 */
-#define CAN_MBTIF2 0xFFC02A60 /* Mailbox Transmit Interrupt Flag reg 2 */
-#define CAN_MBRIF2 0xFFC02A64 /* Mailbox Receive Interrupt Flag reg 2 */
-#define CAN_MBIM2 0xFFC02A68 /* Mailbox Interrupt Mask reg 2 */
-#define CAN_RFH2 0xFFC02A6C /* Remote Frame Handling reg 2 */
-#define CAN_OPSS2 0xFFC02A70 /* Overwrite Protection Single Shot Xmission reg 2 */
-
-#define CAN_CLOCK 0xFFC02A80 /* Bit Timing Configuration register 0 */
-#define CAN_TIMING 0xFFC02A84 /* Bit Timing Configuration register 1 */
-
-#define CAN_DEBUG 0xFFC02A88 /* Debug Register */
-/* the following is for backwards compatibility */
-#define CAN_CNF CAN_DEBUG
-
-#define CAN_STATUS 0xFFC02A8C /* Global Status Register */
-#define CAN_CEC 0xFFC02A90 /* Error Counter Register */
-#define CAN_GIS 0xFFC02A94 /* Global Interrupt Status Register */
-#define CAN_GIM 0xFFC02A98 /* Global Interrupt Mask Register */
-#define CAN_GIF 0xFFC02A9C /* Global Interrupt Flag Register */
-#define CAN_CONTROL 0xFFC02AA0 /* Master Control Register */
-#define CAN_INTR 0xFFC02AA4 /* Interrupt Pending Register */
-#define CAN_MBTD 0xFFC02AAC /* Mailbox Temporary Disable Feature */
-#define CAN_EWR 0xFFC02AB0 /* Programmable Warning Level */
-#define CAN_ESR 0xFFC02AB4 /* Error Status Register */
-#define CAN_UCCNT 0xFFC02AC4 /* Universal Counter */
-#define CAN_UCRC 0xFFC02AC8 /* Universal Counter Reload/Capture Register */
-#define CAN_UCCNF 0xFFC02ACC /* Universal Counter Configuration Register */
-
-/* Mailbox Acceptance Masks */
-#define CAN_AM00L 0xFFC02B00 /* Mailbox 0 Low Acceptance Mask */
-#define CAN_AM00H 0xFFC02B04 /* Mailbox 0 High Acceptance Mask */
-#define CAN_AM01L 0xFFC02B08 /* Mailbox 1 Low Acceptance Mask */
-#define CAN_AM01H 0xFFC02B0C /* Mailbox 1 High Acceptance Mask */
-#define CAN_AM02L 0xFFC02B10 /* Mailbox 2 Low Acceptance Mask */
-#define CAN_AM02H 0xFFC02B14 /* Mailbox 2 High Acceptance Mask */
-#define CAN_AM03L 0xFFC02B18 /* Mailbox 3 Low Acceptance Mask */
-#define CAN_AM03H 0xFFC02B1C /* Mailbox 3 High Acceptance Mask */
-#define CAN_AM04L 0xFFC02B20 /* Mailbox 4 Low Acceptance Mask */
-#define CAN_AM04H 0xFFC02B24 /* Mailbox 4 High Acceptance Mask */
-#define CAN_AM05L 0xFFC02B28 /* Mailbox 5 Low Acceptance Mask */
-#define CAN_AM05H 0xFFC02B2C /* Mailbox 5 High Acceptance Mask */
-#define CAN_AM06L 0xFFC02B30 /* Mailbox 6 Low Acceptance Mask */
-#define CAN_AM06H 0xFFC02B34 /* Mailbox 6 High Acceptance Mask */
-#define CAN_AM07L 0xFFC02B38 /* Mailbox 7 Low Acceptance Mask */
-#define CAN_AM07H 0xFFC02B3C /* Mailbox 7 High Acceptance Mask */
-#define CAN_AM08L 0xFFC02B40 /* Mailbox 8 Low Acceptance Mask */
-#define CAN_AM08H 0xFFC02B44 /* Mailbox 8 High Acceptance Mask */
-#define CAN_AM09L 0xFFC02B48 /* Mailbox 9 Low Acceptance Mask */
-#define CAN_AM09H 0xFFC02B4C /* Mailbox 9 High Acceptance Mask */
-#define CAN_AM10L 0xFFC02B50 /* Mailbox 10 Low Acceptance Mask */
-#define CAN_AM10H 0xFFC02B54 /* Mailbox 10 High Acceptance Mask */
-#define CAN_AM11L 0xFFC02B58 /* Mailbox 11 Low Acceptance Mask */
-#define CAN_AM11H 0xFFC02B5C /* Mailbox 11 High Acceptance Mask */
-#define CAN_AM12L 0xFFC02B60 /* Mailbox 12 Low Acceptance Mask */
-#define CAN_AM12H 0xFFC02B64 /* Mailbox 12 High Acceptance Mask */
-#define CAN_AM13L 0xFFC02B68 /* Mailbox 13 Low Acceptance Mask */
-#define CAN_AM13H 0xFFC02B6C /* Mailbox 13 High Acceptance Mask */
-#define CAN_AM14L 0xFFC02B70 /* Mailbox 14 Low Acceptance Mask */
-#define CAN_AM14H 0xFFC02B74 /* Mailbox 14 High Acceptance Mask */
-#define CAN_AM15L 0xFFC02B78 /* Mailbox 15 Low Acceptance Mask */
-#define CAN_AM15H 0xFFC02B7C /* Mailbox 15 High Acceptance Mask */
-
-#define CAN_AM16L 0xFFC02B80 /* Mailbox 16 Low Acceptance Mask */
-#define CAN_AM16H 0xFFC02B84 /* Mailbox 16 High Acceptance Mask */
-#define CAN_AM17L 0xFFC02B88 /* Mailbox 17 Low Acceptance Mask */
-#define CAN_AM17H 0xFFC02B8C /* Mailbox 17 High Acceptance Mask */
-#define CAN_AM18L 0xFFC02B90 /* Mailbox 18 Low Acceptance Mask */
-#define CAN_AM18H 0xFFC02B94 /* Mailbox 18 High Acceptance Mask */
-#define CAN_AM19L 0xFFC02B98 /* Mailbox 19 Low Acceptance Mask */
-#define CAN_AM19H 0xFFC02B9C /* Mailbox 19 High Acceptance Mask */
-#define CAN_AM20L 0xFFC02BA0 /* Mailbox 20 Low Acceptance Mask */
-#define CAN_AM20H 0xFFC02BA4 /* Mailbox 20 High Acceptance Mask */
-#define CAN_AM21L 0xFFC02BA8 /* Mailbox 21 Low Acceptance Mask */
-#define CAN_AM21H 0xFFC02BAC /* Mailbox 21 High Acceptance Mask */
-#define CAN_AM22L 0xFFC02BB0 /* Mailbox 22 Low Acceptance Mask */
-#define CAN_AM22H 0xFFC02BB4 /* Mailbox 22 High Acceptance Mask */
-#define CAN_AM23L 0xFFC02BB8 /* Mailbox 23 Low Acceptance Mask */
-#define CAN_AM23H 0xFFC02BBC /* Mailbox 23 High Acceptance Mask */
-#define CAN_AM24L 0xFFC02BC0 /* Mailbox 24 Low Acceptance Mask */
-#define CAN_AM24H 0xFFC02BC4 /* Mailbox 24 High Acceptance Mask */
-#define CAN_AM25L 0xFFC02BC8 /* Mailbox 25 Low Acceptance Mask */
-#define CAN_AM25H 0xFFC02BCC /* Mailbox 25 High Acceptance Mask */
-#define CAN_AM26L 0xFFC02BD0 /* Mailbox 26 Low Acceptance Mask */
-#define CAN_AM26H 0xFFC02BD4 /* Mailbox 26 High Acceptance Mask */
-#define CAN_AM27L 0xFFC02BD8 /* Mailbox 27 Low Acceptance Mask */
-#define CAN_AM27H 0xFFC02BDC /* Mailbox 27 High Acceptance Mask */
-#define CAN_AM28L 0xFFC02BE0 /* Mailbox 28 Low Acceptance Mask */
-#define CAN_AM28H 0xFFC02BE4 /* Mailbox 28 High Acceptance Mask */
-#define CAN_AM29L 0xFFC02BE8 /* Mailbox 29 Low Acceptance Mask */
-#define CAN_AM29H 0xFFC02BEC /* Mailbox 29 High Acceptance Mask */
-#define CAN_AM30L 0xFFC02BF0 /* Mailbox 30 Low Acceptance Mask */
-#define CAN_AM30H 0xFFC02BF4 /* Mailbox 30 High Acceptance Mask */
-#define CAN_AM31L 0xFFC02BF8 /* Mailbox 31 Low Acceptance Mask */
-#define CAN_AM31H 0xFFC02BFC /* Mailbox 31 High Acceptance Mask */
-
-/* CAN Acceptance Mask Macros */
-#define CAN_AM_L(x) (CAN_AM00L+((x)*0x8))
-#define CAN_AM_H(x) (CAN_AM00H+((x)*0x8))
-
-/* Mailbox Registers */
-#define CAN_MB00_DATA0 0xFFC02C00 /* Mailbox 0 Data Word 0 [15:0] Register */
-#define CAN_MB00_DATA1 0xFFC02C04 /* Mailbox 0 Data Word 1 [31:16] Register */
-#define CAN_MB00_DATA2 0xFFC02C08 /* Mailbox 0 Data Word 2 [47:32] Register */
-#define CAN_MB00_DATA3 0xFFC02C0C /* Mailbox 0 Data Word 3 [63:48] Register */
-#define CAN_MB00_LENGTH 0xFFC02C10 /* Mailbox 0 Data Length Code Register */
-#define CAN_MB00_TIMESTAMP 0xFFC02C14 /* Mailbox 0 Time Stamp Value Register */
-#define CAN_MB00_ID0 0xFFC02C18 /* Mailbox 0 Identifier Low Register */
-#define CAN_MB00_ID1 0xFFC02C1C /* Mailbox 0 Identifier High Register */
-
-#define CAN_MB01_DATA0 0xFFC02C20 /* Mailbox 1 Data Word 0 [15:0] Register */
-#define CAN_MB01_DATA1 0xFFC02C24 /* Mailbox 1 Data Word 1 [31:16] Register */
-#define CAN_MB01_DATA2 0xFFC02C28 /* Mailbox 1 Data Word 2 [47:32] Register */
-#define CAN_MB01_DATA3 0xFFC02C2C /* Mailbox 1 Data Word 3 [63:48] Register */
-#define CAN_MB01_LENGTH 0xFFC02C30 /* Mailbox 1 Data Length Code Register */
-#define CAN_MB01_TIMESTAMP 0xFFC02C34 /* Mailbox 1 Time Stamp Value Register */
-#define CAN_MB01_ID0 0xFFC02C38 /* Mailbox 1 Identifier Low Register */
-#define CAN_MB01_ID1 0xFFC02C3C /* Mailbox 1 Identifier High Register */
-
-#define CAN_MB02_DATA0 0xFFC02C40 /* Mailbox 2 Data Word 0 [15:0] Register */
-#define CAN_MB02_DATA1 0xFFC02C44 /* Mailbox 2 Data Word 1 [31:16] Register */
-#define CAN_MB02_DATA2 0xFFC02C48 /* Mailbox 2 Data Word 2 [47:32] Register */
-#define CAN_MB02_DATA3 0xFFC02C4C /* Mailbox 2 Data Word 3 [63:48] Register */
-#define CAN_MB02_LENGTH 0xFFC02C50 /* Mailbox 2 Data Length Code Register */
-#define CAN_MB02_TIMESTAMP 0xFFC02C54 /* Mailbox 2 Time Stamp Value Register */
-#define CAN_MB02_ID0 0xFFC02C58 /* Mailbox 2 Identifier Low Register */
-#define CAN_MB02_ID1 0xFFC02C5C /* Mailbox 2 Identifier High Register */
-
-#define CAN_MB03_DATA0 0xFFC02C60 /* Mailbox 3 Data Word 0 [15:0] Register */
-#define CAN_MB03_DATA1 0xFFC02C64 /* Mailbox 3 Data Word 1 [31:16] Register */
-#define CAN_MB03_DATA2 0xFFC02C68 /* Mailbox 3 Data Word 2 [47:32] Register */
-#define CAN_MB03_DATA3 0xFFC02C6C /* Mailbox 3 Data Word 3 [63:48] Register */
-#define CAN_MB03_LENGTH 0xFFC02C70 /* Mailbox 3 Data Length Code Register */
-#define CAN_MB03_TIMESTAMP 0xFFC02C74 /* Mailbox 3 Time Stamp Value Register */
-#define CAN_MB03_ID0 0xFFC02C78 /* Mailbox 3 Identifier Low Register */
-#define CAN_MB03_ID1 0xFFC02C7C /* Mailbox 3 Identifier High Register */
-
-#define CAN_MB04_DATA0 0xFFC02C80 /* Mailbox 4 Data Word 0 [15:0] Register */
-#define CAN_MB04_DATA1 0xFFC02C84 /* Mailbox 4 Data Word 1 [31:16] Register */
-#define CAN_MB04_DATA2 0xFFC02C88 /* Mailbox 4 Data Word 2 [47:32] Register */
-#define CAN_MB04_DATA3 0xFFC02C8C /* Mailbox 4 Data Word 3 [63:48] Register */
-#define CAN_MB04_LENGTH 0xFFC02C90 /* Mailbox 4 Data Length Code Register */
-#define CAN_MB04_TIMESTAMP 0xFFC02C94 /* Mailbox 4 Time Stamp Value Register */
-#define CAN_MB04_ID0 0xFFC02C98 /* Mailbox 4 Identifier Low Register */
-#define CAN_MB04_ID1 0xFFC02C9C /* Mailbox 4 Identifier High Register */
-
-#define CAN_MB05_DATA0 0xFFC02CA0 /* Mailbox 5 Data Word 0 [15:0] Register */
-#define CAN_MB05_DATA1 0xFFC02CA4 /* Mailbox 5 Data Word 1 [31:16] Register */
-#define CAN_MB05_DATA2 0xFFC02CA8 /* Mailbox 5 Data Word 2 [47:32] Register */
-#define CAN_MB05_DATA3 0xFFC02CAC /* Mailbox 5 Data Word 3 [63:48] Register */
-#define CAN_MB05_LENGTH 0xFFC02CB0 /* Mailbox 5 Data Length Code Register */
-#define CAN_MB05_TIMESTAMP 0xFFC02CB4 /* Mailbox 5 Time Stamp Value Register */
-#define CAN_MB05_ID0 0xFFC02CB8 /* Mailbox 5 Identifier Low Register */
-#define CAN_MB05_ID1 0xFFC02CBC /* Mailbox 5 Identifier High Register */
-
-#define CAN_MB06_DATA0 0xFFC02CC0 /* Mailbox 6 Data Word 0 [15:0] Register */
-#define CAN_MB06_DATA1 0xFFC02CC4 /* Mailbox 6 Data Word 1 [31:16] Register */
-#define CAN_MB06_DATA2 0xFFC02CC8 /* Mailbox 6 Data Word 2 [47:32] Register */
-#define CAN_MB06_DATA3 0xFFC02CCC /* Mailbox 6 Data Word 3 [63:48] Register */
-#define CAN_MB06_LENGTH 0xFFC02CD0 /* Mailbox 6 Data Length Code Register */
-#define CAN_MB06_TIMESTAMP 0xFFC02CD4 /* Mailbox 6 Time Stamp Value Register */
-#define CAN_MB06_ID0 0xFFC02CD8 /* Mailbox 6 Identifier Low Register */
-#define CAN_MB06_ID1 0xFFC02CDC /* Mailbox 6 Identifier High Register */
-
-#define CAN_MB07_DATA0 0xFFC02CE0 /* Mailbox 7 Data Word 0 [15:0] Register */
-#define CAN_MB07_DATA1 0xFFC02CE4 /* Mailbox 7 Data Word 1 [31:16] Register */
-#define CAN_MB07_DATA2 0xFFC02CE8 /* Mailbox 7 Data Word 2 [47:32] Register */
-#define CAN_MB07_DATA3 0xFFC02CEC /* Mailbox 7 Data Word 3 [63:48] Register */
-#define CAN_MB07_LENGTH 0xFFC02CF0 /* Mailbox 7 Data Length Code Register */
-#define CAN_MB07_TIMESTAMP 0xFFC02CF4 /* Mailbox 7 Time Stamp Value Register */
-#define CAN_MB07_ID0 0xFFC02CF8 /* Mailbox 7 Identifier Low Register */
-#define CAN_MB07_ID1 0xFFC02CFC /* Mailbox 7 Identifier High Register */
-
-#define CAN_MB08_DATA0 0xFFC02D00 /* Mailbox 8 Data Word 0 [15:0] Register */
-#define CAN_MB08_DATA1 0xFFC02D04 /* Mailbox 8 Data Word 1 [31:16] Register */
-#define CAN_MB08_DATA2 0xFFC02D08 /* Mailbox 8 Data Word 2 [47:32] Register */
-#define CAN_MB08_DATA3 0xFFC02D0C /* Mailbox 8 Data Word 3 [63:48] Register */
-#define CAN_MB08_LENGTH 0xFFC02D10 /* Mailbox 8 Data Length Code Register */
-#define CAN_MB08_TIMESTAMP 0xFFC02D14 /* Mailbox 8 Time Stamp Value Register */
-#define CAN_MB08_ID0 0xFFC02D18 /* Mailbox 8 Identifier Low Register */
-#define CAN_MB08_ID1 0xFFC02D1C /* Mailbox 8 Identifier High Register */
-
-#define CAN_MB09_DATA0 0xFFC02D20 /* Mailbox 9 Data Word 0 [15:0] Register */
-#define CAN_MB09_DATA1 0xFFC02D24 /* Mailbox 9 Data Word 1 [31:16] Register */
-#define CAN_MB09_DATA2 0xFFC02D28 /* Mailbox 9 Data Word 2 [47:32] Register */
-#define CAN_MB09_DATA3 0xFFC02D2C /* Mailbox 9 Data Word 3 [63:48] Register */
-#define CAN_MB09_LENGTH 0xFFC02D30 /* Mailbox 9 Data Length Code Register */
-#define CAN_MB09_TIMESTAMP 0xFFC02D34 /* Mailbox 9 Time Stamp Value Register */
-#define CAN_MB09_ID0 0xFFC02D38 /* Mailbox 9 Identifier Low Register */
-#define CAN_MB09_ID1 0xFFC02D3C /* Mailbox 9 Identifier High Register */
-
-#define CAN_MB10_DATA0 0xFFC02D40 /* Mailbox 10 Data Word 0 [15:0] Register */
-#define CAN_MB10_DATA1 0xFFC02D44 /* Mailbox 10 Data Word 1 [31:16] Register */
-#define CAN_MB10_DATA2 0xFFC02D48 /* Mailbox 10 Data Word 2 [47:32] Register */
-#define CAN_MB10_DATA3 0xFFC02D4C /* Mailbox 10 Data Word 3 [63:48] Register */
-#define CAN_MB10_LENGTH 0xFFC02D50 /* Mailbox 10 Data Length Code Register */
-#define CAN_MB10_TIMESTAMP 0xFFC02D54 /* Mailbox 10 Time Stamp Value Register */
-#define CAN_MB10_ID0 0xFFC02D58 /* Mailbox 10 Identifier Low Register */
-#define CAN_MB10_ID1 0xFFC02D5C /* Mailbox 10 Identifier High Register */
-
-#define CAN_MB11_DATA0 0xFFC02D60 /* Mailbox 11 Data Word 0 [15:0] Register */
-#define CAN_MB11_DATA1 0xFFC02D64 /* Mailbox 11 Data Word 1 [31:16] Register */
-#define CAN_MB11_DATA2 0xFFC02D68 /* Mailbox 11 Data Word 2 [47:32] Register */
-#define CAN_MB11_DATA3 0xFFC02D6C /* Mailbox 11 Data Word 3 [63:48] Register */
-#define CAN_MB11_LENGTH 0xFFC02D70 /* Mailbox 11 Data Length Code Register */
-#define CAN_MB11_TIMESTAMP 0xFFC02D74 /* Mailbox 11 Time Stamp Value Register */
-#define CAN_MB11_ID0 0xFFC02D78 /* Mailbox 11 Identifier Low Register */
-#define CAN_MB11_ID1 0xFFC02D7C /* Mailbox 11 Identifier High Register */
-
-#define CAN_MB12_DATA0 0xFFC02D80 /* Mailbox 12 Data Word 0 [15:0] Register */
-#define CAN_MB12_DATA1 0xFFC02D84 /* Mailbox 12 Data Word 1 [31:16] Register */
-#define CAN_MB12_DATA2 0xFFC02D88 /* Mailbox 12 Data Word 2 [47:32] Register */
-#define CAN_MB12_DATA3 0xFFC02D8C /* Mailbox 12 Data Word 3 [63:48] Register */
-#define CAN_MB12_LENGTH 0xFFC02D90 /* Mailbox 12 Data Length Code Register */
-#define CAN_MB12_TIMESTAMP 0xFFC02D94 /* Mailbox 12 Time Stamp Value Register */
-#define CAN_MB12_ID0 0xFFC02D98 /* Mailbox 12 Identifier Low Register */
-#define CAN_MB12_ID1 0xFFC02D9C /* Mailbox 12 Identifier High Register */
-
-#define CAN_MB13_DATA0 0xFFC02DA0 /* Mailbox 13 Data Word 0 [15:0] Register */
-#define CAN_MB13_DATA1 0xFFC02DA4 /* Mailbox 13 Data Word 1 [31:16] Register */
-#define CAN_MB13_DATA2 0xFFC02DA8 /* Mailbox 13 Data Word 2 [47:32] Register */
-#define CAN_MB13_DATA3 0xFFC02DAC /* Mailbox 13 Data Word 3 [63:48] Register */
-#define CAN_MB13_LENGTH 0xFFC02DB0 /* Mailbox 13 Data Length Code Register */
-#define CAN_MB13_TIMESTAMP 0xFFC02DB4 /* Mailbox 13 Time Stamp Value Register */
-#define CAN_MB13_ID0 0xFFC02DB8 /* Mailbox 13 Identifier Low Register */
-#define CAN_MB13_ID1 0xFFC02DBC /* Mailbox 13 Identifier High Register */
-
-#define CAN_MB14_DATA0 0xFFC02DC0 /* Mailbox 14 Data Word 0 [15:0] Register */
-#define CAN_MB14_DATA1 0xFFC02DC4 /* Mailbox 14 Data Word 1 [31:16] Register */
-#define CAN_MB14_DATA2 0xFFC02DC8 /* Mailbox 14 Data Word 2 [47:32] Register */
-#define CAN_MB14_DATA3 0xFFC02DCC /* Mailbox 14 Data Word 3 [63:48] Register */
-#define CAN_MB14_LENGTH 0xFFC02DD0 /* Mailbox 14 Data Length Code Register */
-#define CAN_MB14_TIMESTAMP 0xFFC02DD4 /* Mailbox 14 Time Stamp Value Register */
-#define CAN_MB14_ID0 0xFFC02DD8 /* Mailbox 14 Identifier Low Register */
-#define CAN_MB14_ID1 0xFFC02DDC /* Mailbox 14 Identifier High Register */
-
-#define CAN_MB15_DATA0 0xFFC02DE0 /* Mailbox 15 Data Word 0 [15:0] Register */
-#define CAN_MB15_DATA1 0xFFC02DE4 /* Mailbox 15 Data Word 1 [31:16] Register */
-#define CAN_MB15_DATA2 0xFFC02DE8 /* Mailbox 15 Data Word 2 [47:32] Register */
-#define CAN_MB15_DATA3 0xFFC02DEC /* Mailbox 15 Data Word 3 [63:48] Register */
-#define CAN_MB15_LENGTH 0xFFC02DF0 /* Mailbox 15 Data Length Code Register */
-#define CAN_MB15_TIMESTAMP 0xFFC02DF4 /* Mailbox 15 Time Stamp Value Register */
-#define CAN_MB15_ID0 0xFFC02DF8 /* Mailbox 15 Identifier Low Register */
-#define CAN_MB15_ID1 0xFFC02DFC /* Mailbox 15 Identifier High Register */
-
-#define CAN_MB16_DATA0 0xFFC02E00 /* Mailbox 16 Data Word 0 [15:0] Register */
-#define CAN_MB16_DATA1 0xFFC02E04 /* Mailbox 16 Data Word 1 [31:16] Register */
-#define CAN_MB16_DATA2 0xFFC02E08 /* Mailbox 16 Data Word 2 [47:32] Register */
-#define CAN_MB16_DATA3 0xFFC02E0C /* Mailbox 16 Data Word 3 [63:48] Register */
-#define CAN_MB16_LENGTH 0xFFC02E10 /* Mailbox 16 Data Length Code Register */
-#define CAN_MB16_TIMESTAMP 0xFFC02E14 /* Mailbox 16 Time Stamp Value Register */
-#define CAN_MB16_ID0 0xFFC02E18 /* Mailbox 16 Identifier Low Register */
-#define CAN_MB16_ID1 0xFFC02E1C /* Mailbox 16 Identifier High Register */
-
-#define CAN_MB17_DATA0 0xFFC02E20 /* Mailbox 17 Data Word 0 [15:0] Register */
-#define CAN_MB17_DATA1 0xFFC02E24 /* Mailbox 17 Data Word 1 [31:16] Register */
-#define CAN_MB17_DATA2 0xFFC02E28 /* Mailbox 17 Data Word 2 [47:32] Register */
-#define CAN_MB17_DATA3 0xFFC02E2C /* Mailbox 17 Data Word 3 [63:48] Register */
-#define CAN_MB17_LENGTH 0xFFC02E30 /* Mailbox 17 Data Length Code Register */
-#define CAN_MB17_TIMESTAMP 0xFFC02E34 /* Mailbox 17 Time Stamp Value Register */
-#define CAN_MB17_ID0 0xFFC02E38 /* Mailbox 17 Identifier Low Register */
-#define CAN_MB17_ID1 0xFFC02E3C /* Mailbox 17 Identifier High Register */
-
-#define CAN_MB18_DATA0 0xFFC02E40 /* Mailbox 18 Data Word 0 [15:0] Register */
-#define CAN_MB18_DATA1 0xFFC02E44 /* Mailbox 18 Data Word 1 [31:16] Register */
-#define CAN_MB18_DATA2 0xFFC02E48 /* Mailbox 18 Data Word 2 [47:32] Register */
-#define CAN_MB18_DATA3 0xFFC02E4C /* Mailbox 18 Data Word 3 [63:48] Register */
-#define CAN_MB18_LENGTH 0xFFC02E50 /* Mailbox 18 Data Length Code Register */
-#define CAN_MB18_TIMESTAMP 0xFFC02E54 /* Mailbox 18 Time Stamp Value Register */
-#define CAN_MB18_ID0 0xFFC02E58 /* Mailbox 18 Identifier Low Register */
-#define CAN_MB18_ID1 0xFFC02E5C /* Mailbox 18 Identifier High Register */
-
-#define CAN_MB19_DATA0 0xFFC02E60 /* Mailbox 19 Data Word 0 [15:0] Register */
-#define CAN_MB19_DATA1 0xFFC02E64 /* Mailbox 19 Data Word 1 [31:16] Register */
-#define CAN_MB19_DATA2 0xFFC02E68 /* Mailbox 19 Data Word 2 [47:32] Register */
-#define CAN_MB19_DATA3 0xFFC02E6C /* Mailbox 19 Data Word 3 [63:48] Register */
-#define CAN_MB19_LENGTH 0xFFC02E70 /* Mailbox 19 Data Length Code Register */
-#define CAN_MB19_TIMESTAMP 0xFFC02E74 /* Mailbox 19 Time Stamp Value Register */
-#define CAN_MB19_ID0 0xFFC02E78 /* Mailbox 19 Identifier Low Register */
-#define CAN_MB19_ID1 0xFFC02E7C /* Mailbox 19 Identifier High Register */
-
-#define CAN_MB20_DATA0 0xFFC02E80 /* Mailbox 20 Data Word 0 [15:0] Register */
-#define CAN_MB20_DATA1 0xFFC02E84 /* Mailbox 20 Data Word 1 [31:16] Register */
-#define CAN_MB20_DATA2 0xFFC02E88 /* Mailbox 20 Data Word 2 [47:32] Register */
-#define CAN_MB20_DATA3 0xFFC02E8C /* Mailbox 20 Data Word 3 [63:48] Register */
-#define CAN_MB20_LENGTH 0xFFC02E90 /* Mailbox 20 Data Length Code Register */
-#define CAN_MB20_TIMESTAMP 0xFFC02E94 /* Mailbox 20 Time Stamp Value Register */
-#define CAN_MB20_ID0 0xFFC02E98 /* Mailbox 20 Identifier Low Register */
-#define CAN_MB20_ID1 0xFFC02E9C /* Mailbox 20 Identifier High Register */
-
-#define CAN_MB21_DATA0 0xFFC02EA0 /* Mailbox 21 Data Word 0 [15:0] Register */
-#define CAN_MB21_DATA1 0xFFC02EA4 /* Mailbox 21 Data Word 1 [31:16] Register */
-#define CAN_MB21_DATA2 0xFFC02EA8 /* Mailbox 21 Data Word 2 [47:32] Register */
-#define CAN_MB21_DATA3 0xFFC02EAC /* Mailbox 21 Data Word 3 [63:48] Register */
-#define CAN_MB21_LENGTH 0xFFC02EB0 /* Mailbox 21 Data Length Code Register */
-#define CAN_MB21_TIMESTAMP 0xFFC02EB4 /* Mailbox 21 Time Stamp Value Register */
-#define CAN_MB21_ID0 0xFFC02EB8 /* Mailbox 21 Identifier Low Register */
-#define CAN_MB21_ID1 0xFFC02EBC /* Mailbox 21 Identifier High Register */
-
-#define CAN_MB22_DATA0 0xFFC02EC0 /* Mailbox 22 Data Word 0 [15:0] Register */
-#define CAN_MB22_DATA1 0xFFC02EC4 /* Mailbox 22 Data Word 1 [31:16] Register */
-#define CAN_MB22_DATA2 0xFFC02EC8 /* Mailbox 22 Data Word 2 [47:32] Register */
-#define CAN_MB22_DATA3 0xFFC02ECC /* Mailbox 22 Data Word 3 [63:48] Register */
-#define CAN_MB22_LENGTH 0xFFC02ED0 /* Mailbox 22 Data Length Code Register */
-#define CAN_MB22_TIMESTAMP 0xFFC02ED4 /* Mailbox 22 Time Stamp Value Register */
-#define CAN_MB22_ID0 0xFFC02ED8 /* Mailbox 22 Identifier Low Register */
-#define CAN_MB22_ID1 0xFFC02EDC /* Mailbox 22 Identifier High Register */
-
-#define CAN_MB23_DATA0 0xFFC02EE0 /* Mailbox 23 Data Word 0 [15:0] Register */
-#define CAN_MB23_DATA1 0xFFC02EE4 /* Mailbox 23 Data Word 1 [31:16] Register */
-#define CAN_MB23_DATA2 0xFFC02EE8 /* Mailbox 23 Data Word 2 [47:32] Register */
-#define CAN_MB23_DATA3 0xFFC02EEC /* Mailbox 23 Data Word 3 [63:48] Register */
-#define CAN_MB23_LENGTH 0xFFC02EF0 /* Mailbox 23 Data Length Code Register */
-#define CAN_MB23_TIMESTAMP 0xFFC02EF4 /* Mailbox 23 Time Stamp Value Register */
-#define CAN_MB23_ID0 0xFFC02EF8 /* Mailbox 23 Identifier Low Register */
-#define CAN_MB23_ID1 0xFFC02EFC /* Mailbox 23 Identifier High Register */
-
-#define CAN_MB24_DATA0 0xFFC02F00 /* Mailbox 24 Data Word 0 [15:0] Register */
-#define CAN_MB24_DATA1 0xFFC02F04 /* Mailbox 24 Data Word 1 [31:16] Register */
-#define CAN_MB24_DATA2 0xFFC02F08 /* Mailbox 24 Data Word 2 [47:32] Register */
-#define CAN_MB24_DATA3 0xFFC02F0C /* Mailbox 24 Data Word 3 [63:48] Register */
-#define CAN_MB24_LENGTH 0xFFC02F10 /* Mailbox 24 Data Length Code Register */
-#define CAN_MB24_TIMESTAMP 0xFFC02F14 /* Mailbox 24 Time Stamp Value Register */
-#define CAN_MB24_ID0 0xFFC02F18 /* Mailbox 24 Identifier Low Register */
-#define CAN_MB24_ID1 0xFFC02F1C /* Mailbox 24 Identifier High Register */
-
-#define CAN_MB25_DATA0 0xFFC02F20 /* Mailbox 25 Data Word 0 [15:0] Register */
-#define CAN_MB25_DATA1 0xFFC02F24 /* Mailbox 25 Data Word 1 [31:16] Register */
-#define CAN_MB25_DATA2 0xFFC02F28 /* Mailbox 25 Data Word 2 [47:32] Register */
-#define CAN_MB25_DATA3 0xFFC02F2C /* Mailbox 25 Data Word 3 [63:48] Register */
-#define CAN_MB25_LENGTH 0xFFC02F30 /* Mailbox 25 Data Length Code Register */
-#define CAN_MB25_TIMESTAMP 0xFFC02F34 /* Mailbox 25 Time Stamp Value Register */
-#define CAN_MB25_ID0 0xFFC02F38 /* Mailbox 25 Identifier Low Register */
-#define CAN_MB25_ID1 0xFFC02F3C /* Mailbox 25 Identifier High Register */
-
-#define CAN_MB26_DATA0 0xFFC02F40 /* Mailbox 26 Data Word 0 [15:0] Register */
-#define CAN_MB26_DATA1 0xFFC02F44 /* Mailbox 26 Data Word 1 [31:16] Register */
-#define CAN_MB26_DATA2 0xFFC02F48 /* Mailbox 26 Data Word 2 [47:32] Register */
-#define CAN_MB26_DATA3 0xFFC02F4C /* Mailbox 26 Data Word 3 [63:48] Register */
-#define CAN_MB26_LENGTH 0xFFC02F50 /* Mailbox 26 Data Length Code Register */
-#define CAN_MB26_TIMESTAMP 0xFFC02F54 /* Mailbox 26 Time Stamp Value Register */
-#define CAN_MB26_ID0 0xFFC02F58 /* Mailbox 26 Identifier Low Register */
-#define CAN_MB26_ID1 0xFFC02F5C /* Mailbox 26 Identifier High Register */
-
-#define CAN_MB27_DATA0 0xFFC02F60 /* Mailbox 27 Data Word 0 [15:0] Register */
-#define CAN_MB27_DATA1 0xFFC02F64 /* Mailbox 27 Data Word 1 [31:16] Register */
-#define CAN_MB27_DATA2 0xFFC02F68 /* Mailbox 27 Data Word 2 [47:32] Register */
-#define CAN_MB27_DATA3 0xFFC02F6C /* Mailbox 27 Data Word 3 [63:48] Register */
-#define CAN_MB27_LENGTH 0xFFC02F70 /* Mailbox 27 Data Length Code Register */
-#define CAN_MB27_TIMESTAMP 0xFFC02F74 /* Mailbox 27 Time Stamp Value Register */
-#define CAN_MB27_ID0 0xFFC02F78 /* Mailbox 27 Identifier Low Register */
-#define CAN_MB27_ID1 0xFFC02F7C /* Mailbox 27 Identifier High Register */
-
-#define CAN_MB28_DATA0 0xFFC02F80 /* Mailbox 28 Data Word 0 [15:0] Register */
-#define CAN_MB28_DATA1 0xFFC02F84 /* Mailbox 28 Data Word 1 [31:16] Register */
-#define CAN_MB28_DATA2 0xFFC02F88 /* Mailbox 28 Data Word 2 [47:32] Register */
-#define CAN_MB28_DATA3 0xFFC02F8C /* Mailbox 28 Data Word 3 [63:48] Register */
-#define CAN_MB28_LENGTH 0xFFC02F90 /* Mailbox 28 Data Length Code Register */
-#define CAN_MB28_TIMESTAMP 0xFFC02F94 /* Mailbox 28 Time Stamp Value Register */
-#define CAN_MB28_ID0 0xFFC02F98 /* Mailbox 28 Identifier Low Register */
-#define CAN_MB28_ID1 0xFFC02F9C /* Mailbox 28 Identifier High Register */
-
-#define CAN_MB29_DATA0 0xFFC02FA0 /* Mailbox 29 Data Word 0 [15:0] Register */
-#define CAN_MB29_DATA1 0xFFC02FA4 /* Mailbox 29 Data Word 1 [31:16] Register */
-#define CAN_MB29_DATA2 0xFFC02FA8 /* Mailbox 29 Data Word 2 [47:32] Register */
-#define CAN_MB29_DATA3 0xFFC02FAC /* Mailbox 29 Data Word 3 [63:48] Register */
-#define CAN_MB29_LENGTH 0xFFC02FB0 /* Mailbox 29 Data Length Code Register */
-#define CAN_MB29_TIMESTAMP 0xFFC02FB4 /* Mailbox 29 Time Stamp Value Register */
-#define CAN_MB29_ID0 0xFFC02FB8 /* Mailbox 29 Identifier Low Register */
-#define CAN_MB29_ID1 0xFFC02FBC /* Mailbox 29 Identifier High Register */
-
-#define CAN_MB30_DATA0 0xFFC02FC0 /* Mailbox 30 Data Word 0 [15:0] Register */
-#define CAN_MB30_DATA1 0xFFC02FC4 /* Mailbox 30 Data Word 1 [31:16] Register */
-#define CAN_MB30_DATA2 0xFFC02FC8 /* Mailbox 30 Data Word 2 [47:32] Register */
-#define CAN_MB30_DATA3 0xFFC02FCC /* Mailbox 30 Data Word 3 [63:48] Register */
-#define CAN_MB30_LENGTH 0xFFC02FD0 /* Mailbox 30 Data Length Code Register */
-#define CAN_MB30_TIMESTAMP 0xFFC02FD4 /* Mailbox 30 Time Stamp Value Register */
-#define CAN_MB30_ID0 0xFFC02FD8 /* Mailbox 30 Identifier Low Register */
-#define CAN_MB30_ID1 0xFFC02FDC /* Mailbox 30 Identifier High Register */
-
-#define CAN_MB31_DATA0 0xFFC02FE0 /* Mailbox 31 Data Word 0 [15:0] Register */
-#define CAN_MB31_DATA1 0xFFC02FE4 /* Mailbox 31 Data Word 1 [31:16] Register */
-#define CAN_MB31_DATA2 0xFFC02FE8 /* Mailbox 31 Data Word 2 [47:32] Register */
-#define CAN_MB31_DATA3 0xFFC02FEC /* Mailbox 31 Data Word 3 [63:48] Register */
-#define CAN_MB31_LENGTH 0xFFC02FF0 /* Mailbox 31 Data Length Code Register */
-#define CAN_MB31_TIMESTAMP 0xFFC02FF4 /* Mailbox 31 Time Stamp Value Register */
-#define CAN_MB31_ID0 0xFFC02FF8 /* Mailbox 31 Identifier Low Register */
-#define CAN_MB31_ID1 0xFFC02FFC /* Mailbox 31 Identifier High Register */
-
-/* CAN Mailbox Area Macros */
-#define CAN_MB_ID1(x) (CAN_MB00_ID1+((x)*0x20))
-#define CAN_MB_ID0(x) (CAN_MB00_ID0+((x)*0x20))
-#define CAN_MB_TIMESTAMP(x) (CAN_MB00_TIMESTAMP+((x)*0x20))
-#define CAN_MB_LENGTH(x) (CAN_MB00_LENGTH+((x)*0x20))
-#define CAN_MB_DATA3(x) (CAN_MB00_DATA3+((x)*0x20))
-#define CAN_MB_DATA2(x) (CAN_MB00_DATA2+((x)*0x20))
-#define CAN_MB_DATA1(x) (CAN_MB00_DATA1+((x)*0x20))
-#define CAN_MB_DATA0(x) (CAN_MB00_DATA0+((x)*0x20))
-
-
-/*********************************************************************************** */
-/* System MMR Register Bits and Macros */
-/******************************************************************************* */
-
-/* SWRST Mask */
-#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
-#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
-#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
-#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
-#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
-
-/* SYSCR Masks */
-#define BMODE 0x0006 /* Boot Mode - Latched During HW Reset From Mode Pins */
-#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
-
-
-/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */
-
-/* Peripheral Masks For SIC0_ISR, SIC0_IWR, SIC0_IMASK */
-#define PLL_WAKEUP_IRQ 0x00000001 /* PLL Wakeup Interrupt Request */
-#define DMAC0_ERR_IRQ 0x00000002 /* DMA Controller 0 Error Interrupt Request */
-#define PPI_ERR_IRQ 0x00000004 /* PPI Error Interrupt Request */
-#define SPORT0_ERR_IRQ 0x00000008 /* SPORT0 Error Interrupt Request */
-#define SPORT1_ERR_IRQ 0x00000010 /* SPORT1 Error Interrupt Request */
-#define SPI0_ERR_IRQ 0x00000020 /* SPI0 Error Interrupt Request */
-#define UART0_ERR_IRQ 0x00000040 /* UART0 Error Interrupt Request */
-#define RTC_IRQ 0x00000080 /* Real-Time Clock Interrupt Request */
-#define DMA0_IRQ 0x00000100 /* DMA Channel 0 (PPI) Interrupt Request */
-#define DMA1_IRQ 0x00000200 /* DMA Channel 1 (SPORT0 RX) Interrupt Request */
-#define DMA2_IRQ 0x00000400 /* DMA Channel 2 (SPORT0 TX) Interrupt Request */
-#define DMA3_IRQ 0x00000800 /* DMA Channel 3 (SPORT1 RX) Interrupt Request */
-#define DMA4_IRQ 0x00001000 /* DMA Channel 4 (SPORT1 TX) Interrupt Request */
-#define DMA5_IRQ 0x00002000 /* DMA Channel 5 (SPI) Interrupt Request */
-#define DMA6_IRQ 0x00004000 /* DMA Channel 6 (UART RX) Interrupt Request */
-#define DMA7_IRQ 0x00008000 /* DMA Channel 7 (UART TX) Interrupt Request */
-#define TIMER0_IRQ 0x00010000 /* Timer 0 Interrupt Request */
-#define TIMER1_IRQ 0x00020000 /* Timer 1 Interrupt Request */
-#define TIMER2_IRQ 0x00040000 /* Timer 2 Interrupt Request */
-#define PFA_IRQ 0x00080000 /* Programmable Flag Interrupt Request A */
-#define PFB_IRQ 0x00100000 /* Programmable Flag Interrupt Request B */
-#define MDMA0_0_IRQ 0x00200000 /* MemDMA0 Stream 0 Interrupt Request */
-#define MDMA0_1_IRQ 0x00400000 /* MemDMA0 Stream 1 Interrupt Request */
-#define WDOG_IRQ 0x00800000 /* Software Watchdog Timer Interrupt Request */
-#define DMAC1_ERR_IRQ 0x01000000 /* DMA Controller 1 Error Interrupt Request */
-#define SPORT2_ERR_IRQ 0x02000000 /* SPORT2 Error Interrupt Request */
-#define SPORT3_ERR_IRQ 0x04000000 /* SPORT3 Error Interrupt Request */
-#define MXVR_SD_IRQ 0x08000000 /* MXVR Synchronous Data Interrupt Request */
-#define SPI1_ERR_IRQ 0x10000000 /* SPI1 Error Interrupt Request */
-#define SPI2_ERR_IRQ 0x20000000 /* SPI2 Error Interrupt Request */
-#define UART1_ERR_IRQ 0x40000000 /* UART1 Error Interrupt Request */
-#define UART2_ERR_IRQ 0x80000000 /* UART2 Error Interrupt Request */
-
-/* the following are for backwards compatibility */
-#define DMA0_ERR_IRQ DMAC0_ERR_IRQ
-#define DMA1_ERR_IRQ DMAC1_ERR_IRQ
-
-
-/* Peripheral Masks For SIC_ISR1, SIC_IWR1, SIC_IMASK1 */
-#define CAN_ERR_IRQ 0x00000001 /* CAN Error Interrupt Request */
-#define DMA8_IRQ 0x00000002 /* DMA Channel 8 (SPORT2 RX) Interrupt Request */
-#define DMA9_IRQ 0x00000004 /* DMA Channel 9 (SPORT2 TX) Interrupt Request */
-#define DMA10_IRQ 0x00000008 /* DMA Channel 10 (SPORT3 RX) Interrupt Request */
-#define DMA11_IRQ 0x00000010 /* DMA Channel 11 (SPORT3 TX) Interrupt Request */
-#define DMA12_IRQ 0x00000020 /* DMA Channel 12 Interrupt Request */
-#define DMA13_IRQ 0x00000040 /* DMA Channel 13 Interrupt Request */
-#define DMA14_IRQ 0x00000080 /* DMA Channel 14 (SPI1) Interrupt Request */
-#define DMA15_IRQ 0x00000100 /* DMA Channel 15 (SPI2) Interrupt Request */
-#define DMA16_IRQ 0x00000200 /* DMA Channel 16 (UART1 RX) Interrupt Request */
-#define DMA17_IRQ 0x00000400 /* DMA Channel 17 (UART1 TX) Interrupt Request */
-#define DMA18_IRQ 0x00000800 /* DMA Channel 18 (UART2 RX) Interrupt Request */
-#define DMA19_IRQ 0x00001000 /* DMA Channel 19 (UART2 TX) Interrupt Request */
-#define TWI0_IRQ 0x00002000 /* TWI0 Interrupt Request */
-#define TWI1_IRQ 0x00004000 /* TWI1 Interrupt Request */
-#define CAN_RX_IRQ 0x00008000 /* CAN Receive Interrupt Request */
-#define CAN_TX_IRQ 0x00010000 /* CAN Transmit Interrupt Request */
-#define MDMA1_0_IRQ 0x00020000 /* MemDMA1 Stream 0 Interrupt Request */
-#define MDMA1_1_IRQ 0x00040000 /* MemDMA1 Stream 1 Interrupt Request */
-#define MXVR_STAT_IRQ 0x00080000 /* MXVR Status Interrupt Request */
-#define MXVR_CM_IRQ 0x00100000 /* MXVR Control Message Interrupt Request */
-#define MXVR_AP_IRQ 0x00200000 /* MXVR Asynchronous Packet Interrupt */
-
-/* the following are for backwards compatibility */
-#define MDMA0_IRQ MDMA1_0_IRQ
-#define MDMA1_IRQ MDMA1_1_IRQ
-
-#ifdef _MISRA_RULES
-#define _MF15 0xFu
-#define _MF7 7u
-#else
-#define _MF15 0xF
-#define _MF7 7
-#endif /* _MISRA_RULES */
-
-/* SIC_IMASKx Masks */
-#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
-#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
-#ifdef _MISRA_RULES
-#define SIC_MASK(x) (1 << ((x)&0x1Fu)) /* Mask Peripheral #x interrupt */
-#define SIC_UNMASK(x) (0xFFFFFFFFu ^ (1 << ((x)&0x1Fu))) /* Unmask Peripheral #x interrupt */
-#else
-#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
-#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
-#endif /* _MISRA_RULES */
-
-/* SIC_IWRx Masks */
-#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
-#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
-#ifdef _MISRA_RULES
-#define IWR_ENABLE(x) (1 << ((x)&0x1Fu)) /* Wakeup Enable Peripheral #x */
-#define IWR_DISABLE(x) (0xFFFFFFFFu ^ (1 << ((x)&0x1Fu))) /* Wakeup Disable Peripheral #x */
-#else
-#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
-#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
-#endif /* _MISRA_RULES */
-
-
-/* ***************************** UART CONTROLLER MASKS ********************** */
-/* UARTx_LCR Register */
-#ifdef _MISRA_RULES
-#define WLS(x) (((x)-5u) & 0x03u) /* Word Length Select */
-#else
-#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
-#endif /* _MISRA_RULES */
-#define STB 0x04 /* Stop Bits */
-#define PEN 0x08 /* Parity Enable */
-#define EPS 0x10 /* Even Parity Select */
-#define STP 0x20 /* Stick Parity */
-#define SB 0x40 /* Set Break */
-#define DLAB 0x80 /* Divisor Latch Access */
-
-#define DLAB_P 0x07
-#define SB_P 0x06
-#define STP_P 0x05
-#define EPS_P 0x04
-#define PEN_P 0x03
-#define STB_P 0x02
-#define WLS_P1 0x01
-#define WLS_P0 0x00
-
-/* UARTx_MCR Register */
-#define LOOP_ENA 0x10 /* Loopback Mode Enable */
-#define LOOP_ENA_P 0x04
-/* Deprecated UARTx_MCR Mask */
-
-/* UARTx_LSR Register */
-#define DR 0x01 /* Data Ready */
-#define OE 0x02 /* Overrun Error */
-#define PE 0x04 /* Parity Error */
-#define FE 0x08 /* Framing Error */
-#define BI 0x10 /* Break Interrupt */
-#define THRE 0x20 /* THR Empty */
-#define TEMT 0x40 /* TSR and UART_THR Empty */
-
-#define TEMP_P 0x06
-#define THRE_P 0x05
-#define BI_P 0x04
-#define FE_P 0x03
-#define PE_P 0x02
-#define OE_P 0x01
-#define DR_P 0x00
-
-/* UARTx_IER Register */
-#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
-#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
-#define ELSI 0x04 /* Enable RX Status Interrupt */
-
-#define ELSI_P 0x02
-#define ETBEI_P 0x01
-#define ERBFI_P 0x00
-
-/* UARTx_IIR Register */
-#define NINT 0x01
-#define STATUS_P1 0x02
-#define STATUS_P0 0x01
-#define NINT_P 0x00
-
-/* UARTx_GCTL Register */
-#define UCEN 0x01 /* Enable UARTx Clocks */
-#define IREN 0x02 /* Enable IrDA Mode */
-#define TPOLC 0x04 /* IrDA TX Polarity Change */
-#define RPOLC 0x08 /* IrDA RX Polarity Change */
-#define FPE 0x10 /* Force Parity Error On Transmit */
-#define FFE 0x20 /* Force Framing Error On Transmit */
-
-#define FFE_P 0x05
-#define FPE_P 0x04
-#define RPOLC_P 0x03
-#define TPOLC_P 0x02
-#define IREN_P 0x01
-#define UCEN_P 0x00
-
-
-/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
-/* PPI_CONTROL Masks */
-#define PORT_EN 0x0001 /* PPI Port Enable */
-#define PORT_DIR 0x0002 /* PPI Port Direction */
-#define XFR_TYPE 0x000C /* PPI Transfer Type */
-#define PORT_CFG 0x0030 /* PPI Port Configuration */
-#define FLD_SEL 0x0040 /* PPI Active Field Select */
-#define PACK_EN 0x0080 /* PPI Packing Mode */
-/* previous versions of defBF539.h erroneously included DMA32 (PPI 32-bit DMA Enable) */
-#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
-#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
-#define DLENGTH 0x3800 /* PPI Data Length */
-#define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */
-#define DLEN_10 0x0800 /* Data Length = 10 Bits */
-#define DLEN_11 0x1000 /* Data Length = 11 Bits */
-#define DLEN_12 0x1800 /* Data Length = 12 Bits */
-#define DLEN_13 0x2000 /* Data Length = 13 Bits */
-#define DLEN_14 0x2800 /* Data Length = 14 Bits */
-#define DLEN_15 0x3000 /* Data Length = 15 Bits */
-#define DLEN_16 0x3800 /* Data Length = 16 Bits */
-#ifdef _MISRA_RULES
-#define DLEN(x) ((((x)-9u) & 0x07u) << 11) /* PPI Data Length (only works for x=10-->x=16) */
-#else
-#define DLEN(x) ((((x)-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */
-#endif /* _MISRA_RULES */
-#define POL 0xC000 /* PPI Signal Polarities */
-#define POLC 0x4000 /* PPI Clock Polarity */
-#define POLS 0x8000 /* PPI Frame Sync Polarity */
-
-
-/* PPI_STATUS Masks */
-#define FLD 0x0400 /* Field Indicator */
-#define FT_ERR 0x0800 /* Frame Track Error */
-#define OVR 0x1000 /* FIFO Overflow Error */
-#define UNDR 0x2000 /* FIFO Underrun Error */
-#define ERR_DET 0x4000 /* Error Detected Indicator */
-#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
-
-
-/* ********** DMA CONTROLLER MASKS ***********************/
-
-/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
-
-#define CTYPE 0x0040 /* DMA Channel Type Indicator */
-#define CTYPE_P 0x6 /* DMA Channel Type Indicator BIT POSITION */
-#define PCAP8 0x0080 /* DMA 8-bit Operation Indicator */
-#define PCAP16 0x0100 /* DMA 16-bit Operation Indicator */
-#define PCAP32 0x0200 /* DMA 32-bit Operation Indicator */
-#define PCAPWR 0x0400 /* DMA Write Operation Indicator */
-#define PCAPRD 0x0800 /* DMA Read Operation Indicator */
-#define PMAP 0xF000 /* DMA Peripheral Map Field */
-
-/* PMAP Encodings For DMA Controller 0 */
-#define PMAP_PPI 0x0000 /* PMAP PPI Port DMA */
-#define PMAP_SPORT0RX 0x1000 /* PMAP SPORT0 Receive DMA */
-#define PMAP_SPORT0TX 0x2000 /* PMAP SPORT0 Transmit DMA */
-#define PMAP_SPORT1RX 0x3000 /* PMAP SPORT1 Receive DMA */
-#define PMAP_SPORT1TX 0x4000 /* PMAP SPORT1 Transmit DMA */
-#define PMAP_SPI0 0x5000 /* PMAP SPI DMA */
-#define PMAP_UART0RX 0x6000 /* PMAP UART Receive DMA */
-#define PMAP_UART0TX 0x7000 /* PMAP UART Transmit DMA */
-
-/* PMAP Encodings For DMA Controller 1 */
-#define PMAP_SPORT2RX 0x0000 /* PMAP SPORT2 Receive DMA */
-#define PMAP_SPORT2TX 0x1000 /* PMAP SPORT2 Transmit DMA */
-#define PMAP_SPORT3RX 0x2000 /* PMAP SPORT3 Receive DMA */
-#define PMAP_SPORT3TX 0x3000 /* PMAP SPORT3 Transmit DMA */
-#define PMAP_SPI1 0x6000 /* PMAP SPI1 DMA */
-#define PMAP_SPI2 0x7000 /* PMAP SPI2 DMA */
-#define PMAP_UART1RX 0x8000 /* PMAP UART1 Receive DMA */
-#define PMAP_UART1TX 0x9000 /* PMAP UART1 Transmit DMA */
-#define PMAP_UART2RX 0xA000 /* PMAP UART2 Receive DMA */
-#define PMAP_UART2TX 0xB000 /* PMAP UART2 Transmit DMA */
-
-
-/* ************* GENERAL PURPOSE TIMER MASKS ******************** */
-/* PWM Timer bit definitions */
-/* TIMER_ENABLE Register */
-#define TIMEN0 0x0001 /* Enable Timer 0 */
-#define TIMEN1 0x0002 /* Enable Timer 1 */
-#define TIMEN2 0x0004 /* Enable Timer 2 */
-
-#define TIMEN0_P 0x00
-#define TIMEN1_P 0x01
-#define TIMEN2_P 0x02
-
-/* TIMER_DISABLE Register */
-#define TIMDIS0 0x0001 /* Disable Timer 0 */
-#define TIMDIS1 0x0002 /* Disable Timer 1 */
-#define TIMDIS2 0x0004 /* Disable Timer 2 */
-
-#define TIMDIS0_P 0x00
-#define TIMDIS1_P 0x01
-#define TIMDIS2_P 0x02
-
-/* TIMER_STATUS Register */
-#define TIMIL0 0x0001 /* Timer 0 Interrupt */
-#define TIMIL1 0x0002 /* Timer 1 Interrupt */
-#define TIMIL2 0x0004 /* Timer 2 Interrupt */
-#define TOVF_ERR0 0x0010 /* Timer 0 Counter Overflow */
-#define TOVF_ERR1 0x0020 /* Timer 1 Counter Overflow */
-#define TOVF_ERR2 0x0040 /* Timer 2 Counter Overflow */
-#define TRUN0 0x1000 /* Timer 0 Slave Enable Status */
-#define TRUN1 0x2000 /* Timer 1 Slave Enable Status */
-#define TRUN2 0x4000 /* Timer 2 Slave Enable Status */
-
-#define TIMIL0_P 0x00
-#define TIMIL1_P 0x01
-#define TIMIL2_P 0x02
-#define TOVF_ERR0_P 0x04
-#define TOVF_ERR1_P 0x05
-#define TOVF_ERR2_P 0x06
-#define TRUN0_P 0x0C
-#define TRUN1_P 0x0D
-#define TRUN2_P 0x0E
-
-/* Alternate Deprecated Macros Provided For Backwards Code Compatibility */
-#define TOVL_ERR0 TOVF_ERR0
-#define TOVL_ERR1 TOVF_ERR1
-#define TOVL_ERR2 TOVF_ERR2
-#define TOVL_ERR0_P TOVF_ERR0_P
-#define TOVL_ERR1_P TOVF_ERR1_P
-#define TOVL_ERR2_P TOVF_ERR2_P
-
-/* TIMERx_CONFIG Registers */
-#define PWM_OUT 0x0001
-#define WDTH_CAP 0x0002
-#define EXT_CLK 0x0003
-#define PULSE_HI 0x0004
-#define PERIOD_CNT 0x0008
-#define IRQ_ENA 0x0010
-#define TIN_SEL 0x0020
-#define OUT_DIS 0x0040
-#define CLK_SEL 0x0080
-#define TOGGLE_HI 0x0100
-#define EMU_RUN 0x0200
-#ifdef _MISRA_RULES
-#define ERR_TYP(x) (((x) & 0x03u) << 14)
-#else
-#define ERR_TYP(x) (((x) & 0x03) << 14)
-#endif /* _MISRA_RULES */
-
-#define TMODE_P0 0x00
-#define TMODE_P1 0x01
-#define PULSE_HI_P 0x02
-#define PERIOD_CNT_P 0x03
-#define IRQ_ENA_P 0x04
-#define TIN_SEL_P 0x05
-#define OUT_DIS_P 0x06
-#define CLK_SEL_P 0x07
-#define TOGGLE_HI_P 0x08
-#define EMU_RUN_P 0x09
-#define ERR_TYP_P0 0x0E
-#define ERR_TYP_P1 0x0F
-
-
-/*/ ****************** GENERAL-PURPOSE I/O ********************* */
-/* Flag I/O (FIO_) Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* PORT F BIT POSITIONS */
-#define PF0_P 0x0
-#define PF1_P 0x1
-#define PF2_P 0x2
-#define PF3_P 0x3
-#define PF4_P 0x4
-#define PF5_P 0x5
-#define PF6_P 0x6
-#define PF7_P 0x7
-#define PF8_P 0x8
-#define PF9_P 0x9
-#define PF10_P 0xA
-#define PF11_P 0xB
-#define PF12_P 0xC
-#define PF13_P 0xD
-#define PF14_P 0xE
-#define PF15_P 0xF
-
-
-/******************* GPIO MASKS *********************/
-/* Port C Masks */
-#define PC0 0x0001
-#define PC1 0x0002
-#define PC4 0x0010
-#define PC5 0x0020
-#define PC6 0x0040
-#define PC7 0x0080
-#define PC8 0x0100
-#define PC9 0x0200
-/* Port C Bit Positions */
-#define PC0_P 0x0
-#define PC1_P 0x1
-#define PC4_P 0x4
-#define PC5_P 0x5
-#define PC6_P 0x6
-#define PC7_P 0x7
-#define PC8_P 0x8
-#define PC9_P 0x9
-
-/* Port D */
-#define PD0 0x0001
-#define PD1 0x0002
-#define PD2 0x0004
-#define PD3 0x0008
-#define PD4 0x0010
-#define PD5 0x0020
-#define PD6 0x0040
-#define PD7 0x0080
-#define PD8 0x0100
-#define PD9 0x0200
-#define PD10 0x0400
-#define PD11 0x0800
-#define PD12 0x1000
-#define PD13 0x2000
-#define PD14 0x4000
-#define PD15 0x8000
-/* Port D Bit Positions */
-#define PD0_P 0x0
-#define PD1_P 0x1
-#define PD2_P 0x2
-#define PD3_P 0x3
-#define PD4_P 0x4
-#define PD5_P 0x5
-#define PD6_P 0x6
-#define PD7_P 0x7
-#define PD8_P 0x8
-#define PD9_P 0x9
-#define PD10_P 0xA
-#define PD11_P 0xB
-#define PD12_P 0xC
-#define PD13_P 0xD
-#define PD14_P 0xE
-#define PD15_P 0xF
-
-/* Port E */
-#define PE0 0x0001
-#define PE1 0x0002
-#define PE2 0x0004
-#define PE3 0x0008
-#define PE4 0x0010
-#define PE5 0x0020
-#define PE6 0x0040
-#define PE7 0x0080
-#define PE8 0x0100
-#define PE9 0x0200
-#define PE10 0x0400
-#define PE11 0x0800
-#define PE12 0x1000
-#define PE13 0x2000
-#define PE14 0x4000
-#define PE15 0x8000
-/* Port E Bit Positions */
-#define PE0_P 0x0
-#define PE1_P 0x1
-#define PE2_P 0x2
-#define PE3_P 0x3
-#define PE4_P 0x4
-#define PE5_P 0x5
-#define PE6_P 0x6
-#define PE7_P 0x7
-#define PE8_P 0x8
-#define PE9_P 0x9
-#define PE10_P 0xA
-#define PE11_P 0xB
-#define PE12_P 0xC
-#define PE13_P 0xD
-#define PE14_P 0xE
-#define PE15_P 0xF
-
-/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
-/* EBIU_AMGCTL Masks */
-#define AMCKEN 0x0001 /* Enable CLKOUT */
-#define AMBEN_NONE 0x0000 /* All Banks Disabled */
-#define AMBEN_B0 0x0002 /* Enable Asynchronous Memory Bank 0 only */
-#define AMBEN_B0_B1 0x0004 /* Enable Asynchronous Memory Banks 0 & 1 only */
-#define AMBEN_B0_B1_B2 0x0006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */
-#define AMBEN_ALL 0x0008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */
-#define CDPRIO 0x0100 /* DMA has priority over core for external accesses */
-
-/* EBIU_AMGCTL Bit Positions */
-#define AMCKEN_P 0x0000 /* Enable CLKOUT */
-#define AMBEN_P0 0x0001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */
-#define AMBEN_P1 0x0002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */
-#define AMBEN_P2 0x0003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */
-
-/* EBIU_AMBCTL0 Masks */
-#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */
-#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */
-#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */
-#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */
-#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */
-#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */
-#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */
-#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */
-#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */
-#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */
-#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */
-#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */
-#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */
-#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */
-#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */
-#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */
-#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */
-#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */
-#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */
-#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */
-#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */
-#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */
-#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */
-#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */
-#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */
-#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */
-#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */
-#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */
-#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */
-#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */
-#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */
-#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */
-#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */
-#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */
-#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */
-#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */
-#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */
-#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */
-#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */
-#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */
-#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */
-#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */
-#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */
-#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */
-#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */
-#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */
-#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */
-#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */
-#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */
-#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */
-#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
-#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
-#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
-#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
-#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
-#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
-#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
-#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
-#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */
-#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */
-#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */
-#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */
-#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */
-#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */
-#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */
-#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */
-#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */
-#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */
-#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */
-#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */
-#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */
-#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */
-#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */
-#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */
-#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */
-#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */
-#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */
-#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */
-#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */
-#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */
-#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */
-#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */
-#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */
-#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */
-#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */
-#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */
-#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */
-#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */
-
-/* EBIU_AMBCTL1 Masks */
-#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */
-#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */
-#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */
-#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */
-#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */
-#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */
-#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
-#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
-#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
-#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
-#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
-#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
-#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
-#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
-#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */
-#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */
-#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */
-#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */
-#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */
-#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */
-#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */
-#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */
-#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */
-#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */
-#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */
-#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */
-#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */
-#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */
-#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */
-#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */
-#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */
-#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */
-#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */
-#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */
-#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */
-#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */
-#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */
-#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */
-#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */
-#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */
-#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */
-#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */
-#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */
-#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */
-#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */
-#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */
-#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */
-#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */
-#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */
-#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */
-#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
-#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
-#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
-#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
-#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
-#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
-#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
-#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
-#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */
-#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */
-#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */
-#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */
-#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */
-#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */
-#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */
-#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */
-#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */
-#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */
-#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */
-#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */
-#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */
-#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */
-#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */
-#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */
-#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */
-#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */
-#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */
-#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */
-#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */
-#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */
-#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */
-#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */
-#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */
-#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */
-#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */
-#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */
-#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */
-#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */
-
-/* ********************** SDRAM CONTROLLER MASKS *************************** */
-/* EBIU_SDGCTL Masks */
-#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */
-#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */
-#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */
-#define PFE 0x00000010 /* Enable SDRAM prefetch */
-#define PFP 0x00000020 /* Prefetch has priority over AMC requests */
-#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
-#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
-#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
-#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
-#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
-#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
-#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
-#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
-#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
-#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
-#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
-#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
-#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
-#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
-#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
-#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
-#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
-#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
-#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
-#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
-#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
-#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
-#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
-#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
-#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
-#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
-#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
-#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
-#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
-#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
-#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
-#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
-#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
-#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
-#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
-#define PUPSD 0x00200000 /*Power-up start delay */
-#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */
-#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */
-#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */
-#define EBUFE 0x02000000 /* Enable external buffering timing */
-#define FBBRW 0x04000000 /* Fast back-to-back read write enable */
-#define EMREN 0x10000000 /* Extended mode register enable */
-#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */
-#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */
-
-/* EBIU_SDBCTL Masks */
-#define EBE 0x00000001 /* Enable SDRAM external bank */
-#define EBSZ_16 0x00000000 /* SDRAM external bank size = 16MB */
-#define EBSZ_32 0x00000002 /* SDRAM external bank size = 32MB */
-#define EBSZ_64 0x00000004 /* SDRAM external bank size = 64MB */
-#define EBSZ_128 0x00000006 /* SDRAM external bank size = 128MB */
-#define EBSZ_256 0x00000008 /* SDRAM External Bank Size = 256MB */
-#define EBSZ_512 0x0000000A /* SDRAM External Bank Size = 512MB */
-#define EBCAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
-#define EBCAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */
-#define EBCAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */
-#define EBCAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */
-
-/* EBIU_SDSTAT Masks */
-#define SDCI 0x00000001 /* SDRAM controller is idle */
-#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */
-#define SDPUA 0x00000004 /* SDRAM power up active */
-#define SDRS 0x00000008 /* SDRAM is in reset state */
-#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */
-#define BGSTAT 0x00000020 /* Bus granted */
-
-
-/* ******************** TWO-WIRE INTERFACE (TWIx) MASKS ***********************/
-/* TWIx_CLKDIV Macros (Use: *pTWIx_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
-#ifdef _MISRA_RULES
-#define CLKLOW(x) ((x) & 0xFFu) /* Periods Clock Is Held Low */
-#define CLKHI(y) (((y)&0xFFu)<<0x8) /* Periods Before New Clock Low */
-#else
-#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
-#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
-#endif /* _MISRA_RULES */
-
-/* TWIx_PRESCALE Masks */
-#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
-#define TWI_ENA 0x0080 /* TWI Enable */
-#define SCCB 0x0200 /* SCCB Compatibility Enable */
-
-/* TWIx_SLAVE_CTRL Masks */
-#define SEN 0x0001 /* Slave Enable */
-#define SADD_LEN 0x0002 /* Slave Address Length */
-#define STDVAL 0x0004 /* Slave Transmit Data Valid */
-#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
-#define GEN 0x0010 /* General Call Adrress Matching Enabled */
-
-/* TWIx_SLAVE_STAT Masks */
-#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
-#define GCALL 0x0002 /* General Call Indicator */
-
-/* TWIx_MASTER_CTRL Masks */
-#define MEN 0x0001 /* Master Mode Enable */
-#define MADD_LEN 0x0002 /* Master Address Length */
-#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
-#define FAST 0x0008 /* Use Fast Mode Timing Specs */
-#define STOP 0x0010 /* Issue Stop Condition */
-#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
-#define DCNT 0x3FC0 /* Data Bytes To Transfer */
-#define SDAOVR 0x4000 /* Serial Data Override */
-#define SCLOVR 0x8000 /* Serial Clock Override */
-
-/* TWIx_MASTER_STAT Masks */
-#define MPROG 0x0001 /* Master Transfer In Progress */
-#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
-#define ANAK 0x0004 /* Address Not Acknowledged */
-#define DNAK 0x0008 /* Data Not Acknowledged */
-#define BUFRDERR 0x0010 /* Buffer Read Error */
-#define BUFWRERR 0x0020 /* Buffer Write Error */
-#define SDASEN 0x0040 /* Serial Data Sense */
-#define SCLSEN 0x0080 /* Serial Clock Sense */
-#define BUSBUSY 0x0100 /* Bus Busy Indicator */
-
-/* TWIx_INT_SRC and TWIx_INT_ENABLE Masks */
-#define SINIT 0x0001 /* Slave Transfer Initiated */
-#define SCOMP 0x0002 /* Slave Transfer Complete */
-#define SERR 0x0004 /* Slave Transfer Error */
-#define SOVF 0x0008 /* Slave Overflow */
-#define MCOMP 0x0010 /* Master Transfer Complete */
-#define MERR 0x0020 /* Master Transfer Error */
-#define XMTSERV 0x0040 /* Transmit FIFO Service */
-#define RCVSERV 0x0080 /* Receive FIFO Service */
-
-/* TWIx_FIFO_CTL Masks */
-#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
-#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
-#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
-#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
-
-/* TWIx_FIFO_STAT Masks */
-#define XMTSTAT 0x0003 /* Transmit FIFO Status */
-#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
-#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
-#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
-
-#define RCVSTAT 0x000C /* Receive FIFO Status */
-#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
-#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
-#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
-
#endif /* _DEF_BF539_H */
diff --git a/arch/blackfin/mach-bf538/include/mach/gpio.h b/arch/blackfin/mach-bf538/include/mach/gpio.h
index bd9adb7183da..8a5beeece996 100644
--- a/arch/blackfin/mach-bf538/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf538/include/mach/gpio.h
@@ -70,4 +70,9 @@
#define PORT_D GPIO_PD0
#define PORT_E GPIO_PE0
+#include <mach-common/ports-c.h>
+#include <mach-common/ports-d.h>
+#include <mach-common/ports-e.h>
+#include <mach-common/ports-f.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index f0c0eef95ba8..09829fe23e41 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -502,6 +502,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 216e26999af9..c5ac921d2272 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -607,6 +607,7 @@ static struct musb_hdrc_config musb_config = {
* if it is the case.
*/
.gpio_vrsel_active = 1,
+ .clkin = 24, /* musb CLKIN in MHZ */
};
static struct musb_hdrc_platform_data musb_plat = {
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index 888b9cc0b822..69ead33cbf91 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_NEXT_DESC_PTR,
(struct dma_register *) DMA2_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..a77109f99720
--- /dev/null
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial.h
@@ -0,0 +1,16 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 4
+
+#define BFIN_UART_BF54X_STYLE
+
+#endif
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index dd44aa75fe72..0d94edaaaa2e 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -4,72 +4,14 @@
* Licensed under the GPL-2 or later.
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER_SET))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-#define UART_GET_MSR(uart) bfin_read16(((uart)->port.membase + OFFSET_MSR))
-#define UART_GET_MCR(uart) bfin_read16(((uart)->port.membase + OFFSET_MCR))
-
-#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
-#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
-#define UART_SET_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
-#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
-#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
-#define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
-#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
-#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1)
-#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
-#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
-#define UART_CLEAR_SCTS(uart) bfin_write16(((uart)->port.membase + OFFSET_MSR),SCTS)
-
-#define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */
-#define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */
-
-#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
-#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS|MRTS))
-#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
-#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)
-
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \
defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS)
# define CONFIG_SERIAL_BFIN_HARD_CTSRTS
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-/*
- * The pin configuration is different from schematic
- */
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
- int scts;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -148,3 +90,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h
index 5684030ccc21..72da721a77f5 100644
--- a/arch/blackfin/mach-bf548/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2009 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -10,58 +10,40 @@
#include "bf548.h"
#include "anomaly.h"
+#include <asm/def_LPBlackfin.h>
#ifdef CONFIG_BF542
-#include "defBF542.h"
+# include "defBF542.h"
#endif
-
#ifdef CONFIG_BF544
-#include "defBF544.h"
+# include "defBF544.h"
#endif
-
#ifdef CONFIG_BF547
-#include "defBF547.h"
+# include "defBF547.h"
#endif
-
#ifdef CONFIG_BF548
-#include "defBF548.h"
+# include "defBF548.h"
#endif
-
#ifdef CONFIG_BF549
-#include "defBF549.h"
-#endif
-
-#if !defined(__ASSEMBLY__)
-#ifdef CONFIG_BF542
-#include "cdefBF542.h"
+# include "defBF549.h"
+#endif
+
+#ifndef __ASSEMBLY__
+# include <asm/cdef_LPBlackfin.h>
+# ifdef CONFIG_BF542
+# include "cdefBF542.h"
+# endif
+# ifdef CONFIG_BF544
+# include "cdefBF544.h"
+# endif
+# ifdef CONFIG_BF547
+# include "cdefBF547.h"
+# endif
+# ifdef CONFIG_BF548
+# include "cdefBF548.h"
+# endif
+# ifdef CONFIG_BF549
+# include "cdefBF549.h"
+# endif
#endif
-#ifdef CONFIG_BF544
-#include "cdefBF544.h"
-#endif
-#ifdef CONFIG_BF547
-#include "cdefBF547.h"
-#endif
-#ifdef CONFIG_BF548
-#include "cdefBF548.h"
-#endif
-#ifdef CONFIG_BF549
-#include "cdefBF549.h"
-#endif
-
-#endif
-
-#define BFIN_UART_NR_PORTS 4
-
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_GCTL 0x08 /* Global Control Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_IER_SET 0x20 /* Set Interrupt Enable Register */
-#define OFFSET_IER_CLEAR 0x24 /* Clear Interrupt Enable Register */
-#define OFFSET_THR 0x28 /* Transmit Holding register */
-#define OFFSET_RBR 0x2C /* Receive Buffer register */
#endif
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
index 42f4a9469549..d09c19cd1b7b 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF542_H
#define _CDEF_BF542_H
-/* include all Core registers and bit definitions */
-#include "defBF542.h"
-
-/* include core sbfin_read_()ecific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF542 */
-
/* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
#include "cdefBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
index 2207799575ff..33ec8102ceda 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF544_H
#define _CDEF_BF544_H
-/* include all Core registers and bit definitions */
-#include "defBF544.h"
-
-/* include core sbfin_read_()ecific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF544 */
-
/* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
#include "cdefBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
index bc650e6ea482..bcb9726dea54 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF547_H
#define _CDEF_BF547_H
-/* include all Core registers and bit definitions */
-#include "defBF547.h"
-
-/* include core sbfin_read_()ecific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */
-
/* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
#include "cdefBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
index 3523e08f7968..bae67a65633e 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF548_H
#define _CDEF_BF548_H
-/* include all Core registers and bit definitions */
-#include "defBF548.h"
-
-/* include core sbfin_read_()ecific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */
-
/* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
#include "cdefBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
index 80201ed41f80..002136ad5a44 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF549_H
#define _CDEF_BF549_H
-/* include all Core registers and bit definitions */
-#include "defBF549.h"
-
-/* include core sbfin_read_()ecific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF549 */
-
/* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
#include "cdefBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
index deaf5d6542d5..50c89c8052f3 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,10 +7,6 @@
#ifndef _CDEF_BF54X_H
#define _CDEF_BF54X_H
-#include <asm/blackfin.h>
-
-#include "defBF54x_base.h"
-
/* ************************************************************** */
/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF54x */
/* ************************************************************** */
@@ -2633,22 +2629,5 @@
/* Handshake MDMA is not defined in the shared file because it is not available on the ADSP-BF542 bfin_read_()rocessor */
-/* legacy definitions */
-#define bfin_read_EBIU_AMCBCTL0 bfin_read_EBIU_AMBCTL0
-#define bfin_write_EBIU_AMCBCTL0 bfin_write_EBIU_AMBCTL0
-#define bfin_read_EBIU_AMCBCTL1 bfin_read_EBIU_AMBCTL1
-#define bfin_write_EBIU_AMCBCTL1 bfin_write_EBIU_AMBCTL1
-#define bfin_read_PINT0_IRQ bfin_read_PINT0_REQUEST
-#define bfin_write_PINT0_IRQ bfin_write_PINT0_REQUEST
-#define bfin_read_PINT1_IRQ bfin_read_PINT1_REQUEST
-#define bfin_write_PINT1_IRQ bfin_write_PINT1_REQUEST
-#define bfin_read_PINT2_IRQ bfin_read_PINT2_REQUEST
-#define bfin_write_PINT2_IRQ bfin_write_PINT2_REQUEST
-#define bfin_read_PINT3_IRQ bfin_read_PINT3_REQUEST
-#define bfin_write_PINT3_IRQ bfin_write_PINT3_REQUEST
-
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
#endif /* _CDEF_BF54X_H */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF542.h b/arch/blackfin/mach-bf548/include/mach/defBF542.h
index abf5f750dd8b..629bf216e2b5 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF542.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,11 +7,6 @@
#ifndef _DEF_BF542_H
#define _DEF_BF542_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF542 */
-
/* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
#include "defBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h
index e2771094de02..642468c1bcb1 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,11 +7,6 @@
#ifndef _DEF_BF544_H
#define _DEF_BF544_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF544 */
-
/* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
#include "defBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h
index be21ba5b3aa8..2f3337cd311e 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Analog Devices Inc.
+ * Copyright 2008-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,11 +7,6 @@
#ifndef _DEF_BF547_H
#define _DEF_BF547_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */
-
/* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
#include "defBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h
index 3fb33b040ab7..3c7f1b69349e 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,11 +7,6 @@
#ifndef _DEF_BF548_H
#define _DEF_BF548_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */
-
/* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
#include "defBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h
index 5a04e6d4017e..9a45cb6b30da 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -7,11 +7,6 @@
#ifndef _DEF_BF549_H
#define _DEF_BF549_H
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF549 */
-
/* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
#include "defBF54x_base.h"
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
index 78f91103f175..0867c2bedb43 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Analog Devices Inc.
+ * Copyright 2007-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
@@ -1615,14 +1615,14 @@
#define CTYPE 0x40 /* DMA Channel Type */
#define PMAP 0xf000 /* Peripheral Mapped To This Channel */
-/* Bit masks for DMACx_TCPER */
+/* Bit masks for DMACx_TC_PER */
#define DCB_TRAFFIC_PERIOD 0xf /* DCB Traffic Control Period */
#define DEB_TRAFFIC_PERIOD 0xf0 /* DEB Traffic Control Period */
#define DAB_TRAFFIC_PERIOD 0x700 /* DAB Traffic Control Period */
#define MDMA_ROUND_ROBIN_PERIOD 0xf800 /* MDMA Round Robin Period */
-/* Bit masks for DMACx_TCCNT */
+/* Bit masks for DMACx_TC_CNT */
#define DCB_TRAFFIC_COUNT 0xf /* DCB Traffic Control Count */
#define DEB_TRAFFIC_COUNT 0xf0 /* DEB Traffic Control Count */
@@ -2172,68 +2172,6 @@
#define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */
-/* Bit masks for UARTx_LCR */
-
-#if 0
-/* conflicts with legacy one in last section */
-#define WLS 0x3 /* Word Length Select */
-#endif
-#define STB 0x4 /* Stop Bits */
-#define PEN 0x8 /* Parity Enable */
-#define EPS 0x10 /* Even Parity Select */
-#define STP 0x20 /* Sticky Parity */
-#define SB 0x40 /* Set Break */
-
-/* Bit masks for UARTx_MCR */
-
-#define XOFF 0x1 /* Transmitter Off */
-#define MRTS 0x2 /* Manual Request To Send */
-#define RFIT 0x4 /* Receive FIFO IRQ Threshold */
-#define RFRT 0x8 /* Receive FIFO RTS Threshold */
-#define LOOP_ENA 0x10 /* Loopback Mode Enable */
-#define FCPOL 0x20 /* Flow Control Pin Polarity */
-#define ARTS 0x40 /* Automatic Request To Send */
-#define ACTS 0x80 /* Automatic Clear To Send */
-
-/* Bit masks for UARTx_LSR */
-
-#define DR 0x1 /* Data Ready */
-#define OE 0x2 /* Overrun Error */
-#define PE 0x4 /* Parity Error */
-#define FE 0x8 /* Framing Error */
-#define BI 0x10 /* Break Interrupt */
-#define THRE 0x20 /* THR Empty */
-#define TEMT 0x40 /* Transmitter Empty */
-#define TFI 0x80 /* Transmission Finished Indicator */
-
-/* Bit masks for UARTx_MSR */
-
-#define SCTS 0x1 /* Sticky CTS */
-#define CTS 0x10 /* Clear To Send */
-#define RFCS 0x20 /* Receive FIFO Count Status */
-
-/* Bit masks for UARTx_IER_SET & UARTx_IER_CLEAR */
-
-#define ERBFI 0x1 /* Enable Receive Buffer Full Interrupt */
-#define ETBEI 0x2 /* Enable Transmit Buffer Empty Interrupt */
-#define ELSI 0x4 /* Enable Receive Status Interrupt */
-#define EDSSI 0x8 /* Enable Modem Status Interrupt */
-#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */
-#define ETFI 0x20 /* Enable Transmission Finished Interrupt */
-#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */
-
-/* Bit masks for UARTx_GCTL */
-
-#define UCEN 0x1 /* UART Enable */
-#define IREN 0x2 /* IrDA Mode Enable */
-#define TPOLC 0x4 /* IrDA TX Polarity Change */
-#define RPOLC 0x8 /* IrDA RX Polarity Change */
-#define FPE 0x10 /* Force Parity Error */
-#define FFE 0x20 /* Force Framing Error */
-#define EDBO 0x40 /* Enable Divide-by-One */
-#define EGLSI 0x80 /* Enable Global LS Interrupt */
-
-
/* ******************************************* */
/* MULTI BIT MACRO ENUMERATIONS */
/* ******************************************* */
@@ -2251,13 +2189,6 @@
#define WDTH_CAP 0x0002
#define EXT_CLK 0x0003
-/* UARTx_LCR bit field options */
-
-#define WLS_5 0x0000 /* 5 data bits */
-#define WLS_6 0x0001 /* 6 data bits */
-#define WLS_7 0x0002 /* 7 data bits */
-#define WLS_8 0x0003 /* 8 data bits */
-
/* PINTx Register Bit Definitions */
#define PIQ0 0x00000001
@@ -2300,240 +2231,6 @@
#define PIQ30 0x40000000
#define PIQ31 0x80000000
-/* PORT A Bit Definitions for the registers
-PORTA, PORTA_SET, PORTA_CLEAR,
-PORTA_DIR_SET, PORTA_DIR_CLEAR, PORTA_INEN,
-PORTA_FER registers
-*/
-
-#define PA0 0x0001
-#define PA1 0x0002
-#define PA2 0x0004
-#define PA3 0x0008
-#define PA4 0x0010
-#define PA5 0x0020
-#define PA6 0x0040
-#define PA7 0x0080
-#define PA8 0x0100
-#define PA9 0x0200
-#define PA10 0x0400
-#define PA11 0x0800
-#define PA12 0x1000
-#define PA13 0x2000
-#define PA14 0x4000
-#define PA15 0x8000
-
-/* PORT B Bit Definitions for the registers
-PORTB, PORTB_SET, PORTB_CLEAR,
-PORTB_DIR_SET, PORTB_DIR_CLEAR, PORTB_INEN,
-PORTB_FER registers
-*/
-
-#define PB0 0x0001
-#define PB1 0x0002
-#define PB2 0x0004
-#define PB3 0x0008
-#define PB4 0x0010
-#define PB5 0x0020
-#define PB6 0x0040
-#define PB7 0x0080
-#define PB8 0x0100
-#define PB9 0x0200
-#define PB10 0x0400
-#define PB11 0x0800
-#define PB12 0x1000
-#define PB13 0x2000
-#define PB14 0x4000
-
-
-/* PORT C Bit Definitions for the registers
-PORTC, PORTC_SET, PORTC_CLEAR,
-PORTC_DIR_SET, PORTC_DIR_CLEAR, PORTC_INEN,
-PORTC_FER registers
-*/
-
-
-#define PC0 0x0001
-#define PC1 0x0002
-#define PC2 0x0004
-#define PC3 0x0008
-#define PC4 0x0010
-#define PC5 0x0020
-#define PC6 0x0040
-#define PC7 0x0080
-#define PC8 0x0100
-#define PC9 0x0200
-#define PC10 0x0400
-#define PC11 0x0800
-#define PC12 0x1000
-#define PC13 0x2000
-
-
-/* PORT D Bit Definitions for the registers
-PORTD, PORTD_SET, PORTD_CLEAR,
-PORTD_DIR_SET, PORTD_DIR_CLEAR, PORTD_INEN,
-PORTD_FER registers
-*/
-
-#define PD0 0x0001
-#define PD1 0x0002
-#define PD2 0x0004
-#define PD3 0x0008
-#define PD4 0x0010
-#define PD5 0x0020
-#define PD6 0x0040
-#define PD7 0x0080
-#define PD8 0x0100
-#define PD9 0x0200
-#define PD10 0x0400
-#define PD11 0x0800
-#define PD12 0x1000
-#define PD13 0x2000
-#define PD14 0x4000
-#define PD15 0x8000
-
-/* PORT E Bit Definitions for the registers
-PORTE, PORTE_SET, PORTE_CLEAR,
-PORTE_DIR_SET, PORTE_DIR_CLEAR, PORTE_INEN,
-PORTE_FER registers
-*/
-
-
-#define PE0 0x0001
-#define PE1 0x0002
-#define PE2 0x0004
-#define PE3 0x0008
-#define PE4 0x0010
-#define PE5 0x0020
-#define PE6 0x0040
-#define PE7 0x0080
-#define PE8 0x0100
-#define PE9 0x0200
-#define PE10 0x0400
-#define PE11 0x0800
-#define PE12 0x1000
-#define PE13 0x2000
-#define PE14 0x4000
-#define PE15 0x8000
-
-/* PORT F Bit Definitions for the registers
-PORTF, PORTF_SET, PORTF_CLEAR,
-PORTF_DIR_SET, PORTF_DIR_CLEAR, PORTF_INEN,
-PORTF_FER registers
-*/
-
-
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* PORT G Bit Definitions for the registers
-PORTG, PORTG_SET, PORTG_CLEAR,
-PORTG_DIR_SET, PORTG_DIR_CLEAR, PORTG_INEN,
-PORTG_FER registers
-*/
-
-
-#define PG0 0x0001
-#define PG1 0x0002
-#define PG2 0x0004
-#define PG3 0x0008
-#define PG4 0x0010
-#define PG5 0x0020
-#define PG6 0x0040
-#define PG7 0x0080
-#define PG8 0x0100
-#define PG9 0x0200
-#define PG10 0x0400
-#define PG11 0x0800
-#define PG12 0x1000
-#define PG13 0x2000
-#define PG14 0x4000
-#define PG15 0x8000
-
-/* PORT H Bit Definitions for the registers
-PORTH, PORTH_SET, PORTH_CLEAR,
-PORTH_DIR_SET, PORTH_DIR_CLEAR, PORTH_INEN,
-PORTH_FER registers
-*/
-
-
-#define PH0 0x0001
-#define PH1 0x0002
-#define PH2 0x0004
-#define PH3 0x0008
-#define PH4 0x0010
-#define PH5 0x0020
-#define PH6 0x0040
-#define PH7 0x0080
-#define PH8 0x0100
-#define PH9 0x0200
-#define PH10 0x0400
-#define PH11 0x0800
-#define PH12 0x1000
-#define PH13 0x2000
-
-
-/* PORT I Bit Definitions for the registers
-PORTI, PORTI_SET, PORTI_CLEAR,
-PORTI_DIR_SET, PORTI_DIR_CLEAR, PORTI_INEN,
-PORTI_FER registers
-*/
-
-
-#define PI0 0x0001
-#define PI1 0x0002
-#define PI2 0x0004
-#define PI3 0x0008
-#define PI4 0x0010
-#define PI5 0x0020
-#define PI6 0x0040
-#define PI7 0x0080
-#define PI8 0x0100
-#define PI9 0x0200
-#define PI10 0x0400
-#define PI11 0x0800
-#define PI12 0x1000
-#define PI13 0x2000
-#define PI14 0x4000
-#define PI15 0x8000
-
-/* PORT J Bit Definitions for the registers
-PORTJ, PORTJ_SET, PORTJ_CLEAR,
-PORTJ_DIR_SET, PORTJ_DIR_CLEAR, PORTJ_INEN,
-PORTJ_FER registers
-*/
-
-
-#define PJ0 0x0001
-#define PJ1 0x0002
-#define PJ2 0x0004
-#define PJ3 0x0008
-#define PJ4 0x0010
-#define PJ5 0x0020
-#define PJ6 0x0040
-#define PJ7 0x0080
-#define PJ8 0x0100
-#define PJ9 0x0200
-#define PJ10 0x0400
-#define PJ11 0x0800
-#define PJ12 0x1000
-#define PJ13 0x2000
-
-
/* Port Muxing Bit Fields for PORTx_MUX Registers */
#define MUX0 0x00000003
@@ -2703,16 +2400,4 @@ PORTJ_FER registers
#define B3MAP_PIH 0x06000000 /* Map Port I High to Byte 3 */
#define B3MAP_PJH 0x07000000 /* Map Port J High to Byte 3 */
-
-/* for legacy compatibility */
-
-#define WLS(x) (((x)-5) & 0x03) /* Word Length Select */
-#define W1LMAX_MAX W1LMAX_MIN
-#define EBIU_AMCBCTL0 EBIU_AMBCTL0
-#define EBIU_AMCBCTL1 EBIU_AMBCTL1
-#define PINT0_IRQ PINT0_REQUEST
-#define PINT1_IRQ PINT1_REQUEST
-#define PINT2_IRQ PINT2_REQUEST
-#define PINT3_IRQ PINT3_REQUEST
-
#endif /* _DEF_BF54X_H */
diff --git a/arch/blackfin/mach-bf548/include/mach/gpio.h b/arch/blackfin/mach-bf548/include/mach/gpio.h
index 28037e331964..7db433514e3f 100644
--- a/arch/blackfin/mach-bf548/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf548/include/mach/gpio.h
@@ -200,4 +200,15 @@ struct gpio_port_s {
#endif
+#include <mach-common/ports-a.h>
+#include <mach-common/ports-b.h>
+#include <mach-common/ports-c.h>
+#include <mach-common/ports-d.h>
+#include <mach-common/ports-e.h>
+#include <mach-common/ports-f.h>
+#include <mach-common/ports-g.h>
+#include <mach-common/ports-h.h>
+#include <mach-common/ports-i.h>
+#include <mach-common/ports-j.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
index c938c3c7355d..8ffdd6b4a242 100644
--- a/arch/blackfin/mach-bf561/dma.c
+++ b/arch/blackfin/mach-bf561/dma.c
@@ -11,7 +11,7 @@
#include <asm/blackfin.h>
#include <asm/dma.h>
-struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
+struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA1_0_NEXT_DESC_PTR,
(struct dma_register *) DMA1_1_NEXT_DESC_PTR,
(struct dma_register *) DMA1_2_NEXT_DESC_PTR,
@@ -36,14 +36,14 @@ struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = {
(struct dma_register *) DMA2_9_NEXT_DESC_PTR,
(struct dma_register *) DMA2_10_NEXT_DESC_PTR,
(struct dma_register *) DMA2_11_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
- (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
- (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D2_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S2_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
(struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
(struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
(struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial.h
new file mode 100644
index 000000000000..08072c86d5dc
--- /dev/null
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial.h
@@ -0,0 +1,14 @@
+/*
+ * mach/bfin_serial.h - Blackfin UART/Serial definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MACH_SERIAL_H__
+#define __BFIN_MACH_SERIAL_H__
+
+#define BFIN_UART_NR_PORTS 1
+
+#endif
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index e33e158bc16d..3a6947456cf1 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -4,36 +4,9 @@
* Licensed under the GPL-2 or later.
*/
-#include <linux/serial.h>
#include <asm/dma.h>
#include <asm/portmux.h>
-#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
-#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
-#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
-#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
-#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
-#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
-#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
-
-#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
-#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
-#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
-#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
-#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
-#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
-#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
-#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
-
-#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
-#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
-#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
-#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
-
#ifdef CONFIG_BFIN_UART0_CTSRTS
# define CONFIG_SERIAL_BFIN_CTSRTS
# ifndef CONFIG_UART0_CTS_PIN
@@ -44,51 +17,6 @@
# endif
#endif
-#define BFIN_UART_TX_FIFO_SIZE 2
-
-struct bfin_serial_port {
- struct uart_port port;
- unsigned int old_status;
- int status_irq;
- unsigned int lsr;
-#ifdef CONFIG_SERIAL_BFIN_DMA
- int tx_done;
- int tx_count;
- struct circ_buf rx_dma_buf;
- struct timer_list rx_dma_timer;
- int rx_dma_nrows;
- unsigned int tx_dma_channel;
- unsigned int rx_dma_channel;
- struct work_struct tx_dma_workqueue;
-#else
-# if ANOMALY_05000363
- unsigned int anomaly_threshold;
-# endif
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
-#endif
-};
-
-/* The hardware clears the LSR bits upon read, so we need to cache
- * some of the more fun bits in software so they don't get lost
- * when checking the LSR in other code paths (TX).
- */
-static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
-{
- unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
- uart->lsr |= (lsr & (BI|FE|PE|OE));
- return lsr | uart->lsr;
-}
-
-static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
-{
- uart->lsr = 0;
- bfin_write16(uart->port.membase + OFFSET_LSR, -1);
-}
-
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
@@ -120,3 +48,5 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
+
+#include <asm/bfin_serial.h>
diff --git a/arch/blackfin/mach-bf561/include/mach/blackfin.h b/arch/blackfin/mach-bf561/include/mach/blackfin.h
index 6c7dc58c018c..dc470534c085 100644
--- a/arch/blackfin/mach-bf561/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf561/include/mach/blackfin.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -10,11 +10,14 @@
#define BF561_FAMILY
#include "bf561.h"
-#include "defBF561.h"
#include "anomaly.h"
-#if !defined(__ASSEMBLY__)
-#include "cdefBF561.h"
+#include <asm/def_LPBlackfin.h>
+#include "defBF561.h"
+
+#ifndef __ASSEMBLY__
+# include <asm/cdef_LPBlackfin.h>
+# include "cdefBF561.h"
#endif
#define bfin_read_FIO_FLAG_D() bfin_read_FIO0_FLAG_D()
@@ -35,19 +38,4 @@
#define bfin_read_SICB_ISR(x) bfin_read32(__SIC_MUX(SICB_ISR0, x))
#define bfin_write_SICB_ISR(x, val) bfin_write32(__SIC_MUX(SICB_ISR0, x), val)
-#define BFIN_UART_NR_PORTS 1
-
-#define OFFSET_THR 0x00 /* Transmit Holding register */
-#define OFFSET_RBR 0x00 /* Receive Buffer register */
-#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
-#define OFFSET_IER 0x04 /* Interrupt Enable Register */
-#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
-#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
-#define OFFSET_LCR 0x0C /* Line Control Register */
-#define OFFSET_MCR 0x10 /* Modem Control Register */
-#define OFFSET_LSR 0x14 /* Line Status Register */
-#define OFFSET_MSR 0x18 /* Modem Status Register */
-#define OFFSET_SCR 0x1C /* SCR Scratch Register */
-#define OFFSET_GCTL 0x24 /* Global Control Register */
-
#endif /* _MACH_BLACKFIN_H_ */
diff --git a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
index 2bab99152495..753331597207 100644
--- a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -7,14 +7,6 @@
#ifndef _CDEF_BF561_H
#define _CDEF_BF561_H
-#include <asm/blackfin.h>
-
-/* include all Core registers and bit definitions */
-#include "defBF561.h"
-
-/*include core specific register pointer definitions*/
-#include <asm/cdef_LPBlackfin.h>
-
/*********************************************************************************** */
/* System MMR Register Map */
/*********************************************************************************** */
@@ -523,14 +515,14 @@
#define bfin_read_PPI1_FRAME() bfin_read16(PPI1_FRAME)
#define bfin_write_PPI1_FRAME(val) bfin_write16(PPI1_FRAME,val)
/*DMA traffic control registers */
-#define bfin_read_DMA1_TC_PER() bfin_read16(DMA1_TC_PER)
-#define bfin_write_DMA1_TC_PER(val) bfin_write16(DMA1_TC_PER,val)
-#define bfin_read_DMA1_TC_CNT() bfin_read16(DMA1_TC_CNT)
-#define bfin_write_DMA1_TC_CNT(val) bfin_write16(DMA1_TC_CNT,val)
-#define bfin_read_DMA2_TC_PER() bfin_read16(DMA2_TC_PER)
-#define bfin_write_DMA2_TC_PER(val) bfin_write16(DMA2_TC_PER,val)
-#define bfin_read_DMA2_TC_CNT() bfin_read16(DMA2_TC_CNT)
-#define bfin_write_DMA2_TC_CNT(val) bfin_write16(DMA2_TC_CNT,val)
+#define bfin_read_DMAC0_TC_PER() bfin_read16(DMAC0_TC_PER)
+#define bfin_write_DMAC0_TC_PER(val) bfin_write16(DMAC0_TC_PER,val)
+#define bfin_read_DMAC0_TC_CNT() bfin_read16(DMAC0_TC_CNT)
+#define bfin_write_DMAC0_TC_CNT(val) bfin_write16(DMAC0_TC_CNT,val)
+#define bfin_read_DMAC1_TC_PER() bfin_read16(DMAC1_TC_PER)
+#define bfin_write_DMAC1_TC_PER(val) bfin_write16(DMAC1_TC_PER,val)
+#define bfin_read_DMAC1_TC_CNT() bfin_read16(DMAC1_TC_CNT)
+#define bfin_write_DMAC1_TC_CNT(val) bfin_write16(DMAC1_TC_CNT,val)
/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */
#define bfin_read_DMA1_0_CONFIG() bfin_read16(DMA1_0_CONFIG)
#define bfin_write_DMA1_0_CONFIG(val) bfin_write16(DMA1_0_CONFIG,val)
@@ -845,110 +837,110 @@
#define bfin_read_DMA1_11_PERIPHERAL_MAP() bfin_read16(DMA1_11_PERIPHERAL_MAP)
#define bfin_write_DMA1_11_PERIPHERAL_MAP(val) bfin_write16(DMA1_11_PERIPHERAL_MAP,val)
/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */
-#define bfin_read_MDMA1_D0_CONFIG() bfin_read16(MDMA1_D0_CONFIG)
-#define bfin_write_MDMA1_D0_CONFIG(val) bfin_write16(MDMA1_D0_CONFIG,val)
-#define bfin_read_MDMA1_D0_NEXT_DESC_PTR() bfin_read32(MDMA1_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D0_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA1_D0_START_ADDR() bfin_read32(MDMA1_D0_START_ADDR)
-#define bfin_write_MDMA1_D0_START_ADDR(val) bfin_write32(MDMA1_D0_START_ADDR,val)
-#define bfin_read_MDMA1_D0_X_COUNT() bfin_read16(MDMA1_D0_X_COUNT)
-#define bfin_write_MDMA1_D0_X_COUNT(val) bfin_write16(MDMA1_D0_X_COUNT,val)
-#define bfin_read_MDMA1_D0_Y_COUNT() bfin_read16(MDMA1_D0_Y_COUNT)
-#define bfin_write_MDMA1_D0_Y_COUNT(val) bfin_write16(MDMA1_D0_Y_COUNT,val)
-#define bfin_read_MDMA1_D0_X_MODIFY() bfin_read16(MDMA1_D0_X_MODIFY)
-#define bfin_write_MDMA1_D0_X_MODIFY(val) bfin_write16(MDMA1_D0_X_MODIFY,val)
-#define bfin_read_MDMA1_D0_Y_MODIFY() bfin_read16(MDMA1_D0_Y_MODIFY)
-#define bfin_write_MDMA1_D0_Y_MODIFY(val) bfin_write16(MDMA1_D0_Y_MODIFY,val)
-#define bfin_read_MDMA1_D0_CURR_DESC_PTR() bfin_read32(MDMA1_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA1_D0_CURR_DESC_PTR(val) bfin_write32(MDMA1_D0_CURR_DESC_PTR,val)
-#define bfin_read_MDMA1_D0_CURR_ADDR() bfin_read32(MDMA1_D0_CURR_ADDR)
-#define bfin_write_MDMA1_D0_CURR_ADDR(val) bfin_write32(MDMA1_D0_CURR_ADDR,val)
-#define bfin_read_MDMA1_D0_CURR_X_COUNT() bfin_read16(MDMA1_D0_CURR_X_COUNT)
-#define bfin_write_MDMA1_D0_CURR_X_COUNT(val) bfin_write16(MDMA1_D0_CURR_X_COUNT,val)
-#define bfin_read_MDMA1_D0_CURR_Y_COUNT() bfin_read16(MDMA1_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA1_D0_CURR_Y_COUNT(val) bfin_write16(MDMA1_D0_CURR_Y_COUNT,val)
-#define bfin_read_MDMA1_D0_IRQ_STATUS() bfin_read16(MDMA1_D0_IRQ_STATUS)
-#define bfin_write_MDMA1_D0_IRQ_STATUS(val) bfin_write16(MDMA1_D0_IRQ_STATUS,val)
-#define bfin_read_MDMA1_D0_PERIPHERAL_MAP() bfin_read16(MDMA1_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D0_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA1_S0_CONFIG() bfin_read16(MDMA1_S0_CONFIG)
-#define bfin_write_MDMA1_S0_CONFIG(val) bfin_write16(MDMA1_S0_CONFIG,val)
-#define bfin_read_MDMA1_S0_NEXT_DESC_PTR() bfin_read32(MDMA1_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S0_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA1_S0_START_ADDR() bfin_read32(MDMA1_S0_START_ADDR)
-#define bfin_write_MDMA1_S0_START_ADDR(val) bfin_write32(MDMA1_S0_START_ADDR,val)
-#define bfin_read_MDMA1_S0_X_COUNT() bfin_read16(MDMA1_S0_X_COUNT)
-#define bfin_write_MDMA1_S0_X_COUNT(val) bfin_write16(MDMA1_S0_X_COUNT,val)
-#define bfin_read_MDMA1_S0_Y_COUNT() bfin_read16(MDMA1_S0_Y_COUNT)
-#define bfin_write_MDMA1_S0_Y_COUNT(val) bfin_write16(MDMA1_S0_Y_COUNT,val)
-#define bfin_read_MDMA1_S0_X_MODIFY() bfin_read16(MDMA1_S0_X_MODIFY)
-#define bfin_write_MDMA1_S0_X_MODIFY(val) bfin_write16(MDMA1_S0_X_MODIFY,val)
-#define bfin_read_MDMA1_S0_Y_MODIFY() bfin_read16(MDMA1_S0_Y_MODIFY)
-#define bfin_write_MDMA1_S0_Y_MODIFY(val) bfin_write16(MDMA1_S0_Y_MODIFY,val)
-#define bfin_read_MDMA1_S0_CURR_DESC_PTR() bfin_read32(MDMA1_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA1_S0_CURR_DESC_PTR(val) bfin_write32(MDMA1_S0_CURR_DESC_PTR,val)
-#define bfin_read_MDMA1_S0_CURR_ADDR() bfin_read32(MDMA1_S0_CURR_ADDR)
-#define bfin_write_MDMA1_S0_CURR_ADDR(val) bfin_write32(MDMA1_S0_CURR_ADDR,val)
-#define bfin_read_MDMA1_S0_CURR_X_COUNT() bfin_read16(MDMA1_S0_CURR_X_COUNT)
-#define bfin_write_MDMA1_S0_CURR_X_COUNT(val) bfin_write16(MDMA1_S0_CURR_X_COUNT,val)
-#define bfin_read_MDMA1_S0_CURR_Y_COUNT() bfin_read16(MDMA1_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA1_S0_CURR_Y_COUNT(val) bfin_write16(MDMA1_S0_CURR_Y_COUNT,val)
-#define bfin_read_MDMA1_S0_IRQ_STATUS() bfin_read16(MDMA1_S0_IRQ_STATUS)
-#define bfin_write_MDMA1_S0_IRQ_STATUS(val) bfin_write16(MDMA1_S0_IRQ_STATUS,val)
-#define bfin_read_MDMA1_S0_PERIPHERAL_MAP() bfin_read16(MDMA1_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S0_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA1_D1_CONFIG() bfin_read16(MDMA1_D1_CONFIG)
-#define bfin_write_MDMA1_D1_CONFIG(val) bfin_write16(MDMA1_D1_CONFIG,val)
-#define bfin_read_MDMA1_D1_NEXT_DESC_PTR() bfin_read32(MDMA1_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D1_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA1_D1_START_ADDR() bfin_read32(MDMA1_D1_START_ADDR)
-#define bfin_write_MDMA1_D1_START_ADDR(val) bfin_write32(MDMA1_D1_START_ADDR,val)
-#define bfin_read_MDMA1_D1_X_COUNT() bfin_read16(MDMA1_D1_X_COUNT)
-#define bfin_write_MDMA1_D1_X_COUNT(val) bfin_write16(MDMA1_D1_X_COUNT,val)
-#define bfin_read_MDMA1_D1_Y_COUNT() bfin_read16(MDMA1_D1_Y_COUNT)
-#define bfin_write_MDMA1_D1_Y_COUNT(val) bfin_write16(MDMA1_D1_Y_COUNT,val)
-#define bfin_read_MDMA1_D1_X_MODIFY() bfin_read16(MDMA1_D1_X_MODIFY)
-#define bfin_write_MDMA1_D1_X_MODIFY(val) bfin_write16(MDMA1_D1_X_MODIFY,val)
-#define bfin_read_MDMA1_D1_Y_MODIFY() bfin_read16(MDMA1_D1_Y_MODIFY)
-#define bfin_write_MDMA1_D1_Y_MODIFY(val) bfin_write16(MDMA1_D1_Y_MODIFY,val)
-#define bfin_read_MDMA1_D1_CURR_DESC_PTR() bfin_read32(MDMA1_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA1_D1_CURR_DESC_PTR(val) bfin_write32(MDMA1_D1_CURR_DESC_PTR,val)
-#define bfin_read_MDMA1_D1_CURR_ADDR() bfin_read32(MDMA1_D1_CURR_ADDR)
-#define bfin_write_MDMA1_D1_CURR_ADDR(val) bfin_write32(MDMA1_D1_CURR_ADDR,val)
-#define bfin_read_MDMA1_D1_CURR_X_COUNT() bfin_read16(MDMA1_D1_CURR_X_COUNT)
-#define bfin_write_MDMA1_D1_CURR_X_COUNT(val) bfin_write16(MDMA1_D1_CURR_X_COUNT,val)
-#define bfin_read_MDMA1_D1_CURR_Y_COUNT() bfin_read16(MDMA1_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA1_D1_CURR_Y_COUNT(val) bfin_write16(MDMA1_D1_CURR_Y_COUNT,val)
-#define bfin_read_MDMA1_D1_IRQ_STATUS() bfin_read16(MDMA1_D1_IRQ_STATUS)
-#define bfin_write_MDMA1_D1_IRQ_STATUS(val) bfin_write16(MDMA1_D1_IRQ_STATUS,val)
-#define bfin_read_MDMA1_D1_PERIPHERAL_MAP() bfin_read16(MDMA1_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D1_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA1_S1_CONFIG() bfin_read16(MDMA1_S1_CONFIG)
-#define bfin_write_MDMA1_S1_CONFIG(val) bfin_write16(MDMA1_S1_CONFIG,val)
-#define bfin_read_MDMA1_S1_NEXT_DESC_PTR() bfin_read32(MDMA1_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA1_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S1_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA1_S1_START_ADDR() bfin_read32(MDMA1_S1_START_ADDR)
-#define bfin_write_MDMA1_S1_START_ADDR(val) bfin_write32(MDMA1_S1_START_ADDR,val)
-#define bfin_read_MDMA1_S1_X_COUNT() bfin_read16(MDMA1_S1_X_COUNT)
-#define bfin_write_MDMA1_S1_X_COUNT(val) bfin_write16(MDMA1_S1_X_COUNT,val)
-#define bfin_read_MDMA1_S1_Y_COUNT() bfin_read16(MDMA1_S1_Y_COUNT)
-#define bfin_write_MDMA1_S1_Y_COUNT(val) bfin_write16(MDMA1_S1_Y_COUNT,val)
-#define bfin_read_MDMA1_S1_X_MODIFY() bfin_read16(MDMA1_S1_X_MODIFY)
-#define bfin_write_MDMA1_S1_X_MODIFY(val) bfin_write16(MDMA1_S1_X_MODIFY,val)
-#define bfin_read_MDMA1_S1_Y_MODIFY() bfin_read16(MDMA1_S1_Y_MODIFY)
-#define bfin_write_MDMA1_S1_Y_MODIFY(val) bfin_write16(MDMA1_S1_Y_MODIFY,val)
-#define bfin_read_MDMA1_S1_CURR_DESC_PTR() bfin_read32(MDMA1_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA1_S1_CURR_DESC_PTR(val) bfin_write32(MDMA1_S1_CURR_DESC_PTR,val)
-#define bfin_read_MDMA1_S1_CURR_ADDR() bfin_read32(MDMA1_S1_CURR_ADDR)
-#define bfin_write_MDMA1_S1_CURR_ADDR(val) bfin_write32(MDMA1_S1_CURR_ADDR,val)
-#define bfin_read_MDMA1_S1_CURR_X_COUNT() bfin_read16(MDMA1_S1_CURR_X_COUNT)
-#define bfin_write_MDMA1_S1_CURR_X_COUNT(val) bfin_write16(MDMA1_S1_CURR_X_COUNT,val)
-#define bfin_read_MDMA1_S1_CURR_Y_COUNT() bfin_read16(MDMA1_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA1_S1_CURR_Y_COUNT(val) bfin_write16(MDMA1_S1_CURR_Y_COUNT,val)
-#define bfin_read_MDMA1_S1_IRQ_STATUS() bfin_read16(MDMA1_S1_IRQ_STATUS)
-#define bfin_write_MDMA1_S1_IRQ_STATUS(val) bfin_write16(MDMA1_S1_IRQ_STATUS,val)
-#define bfin_read_MDMA1_S1_PERIPHERAL_MAP() bfin_read16(MDMA1_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA1_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S1_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_D2_CONFIG() bfin_read16(MDMA_D2_CONFIG)
+#define bfin_write_MDMA_D2_CONFIG(val) bfin_write16(MDMA_D2_CONFIG,val)
+#define bfin_read_MDMA_D2_NEXT_DESC_PTR() bfin_read32(MDMA_D2_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D2_NEXT_DESC_PTR(val) bfin_write32(MDMA_D2_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D2_START_ADDR() bfin_read32(MDMA_D2_START_ADDR)
+#define bfin_write_MDMA_D2_START_ADDR(val) bfin_write32(MDMA_D2_START_ADDR,val)
+#define bfin_read_MDMA_D2_X_COUNT() bfin_read16(MDMA_D2_X_COUNT)
+#define bfin_write_MDMA_D2_X_COUNT(val) bfin_write16(MDMA_D2_X_COUNT,val)
+#define bfin_read_MDMA_D2_Y_COUNT() bfin_read16(MDMA_D2_Y_COUNT)
+#define bfin_write_MDMA_D2_Y_COUNT(val) bfin_write16(MDMA_D2_Y_COUNT,val)
+#define bfin_read_MDMA_D2_X_MODIFY() bfin_read16(MDMA_D2_X_MODIFY)
+#define bfin_write_MDMA_D2_X_MODIFY(val) bfin_write16(MDMA_D2_X_MODIFY,val)
+#define bfin_read_MDMA_D2_Y_MODIFY() bfin_read16(MDMA_D2_Y_MODIFY)
+#define bfin_write_MDMA_D2_Y_MODIFY(val) bfin_write16(MDMA_D2_Y_MODIFY,val)
+#define bfin_read_MDMA_D2_CURR_DESC_PTR() bfin_read32(MDMA_D2_CURR_DESC_PTR)
+#define bfin_write_MDMA_D2_CURR_DESC_PTR(val) bfin_write32(MDMA_D2_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D2_CURR_ADDR() bfin_read32(MDMA_D2_CURR_ADDR)
+#define bfin_write_MDMA_D2_CURR_ADDR(val) bfin_write32(MDMA_D2_CURR_ADDR,val)
+#define bfin_read_MDMA_D2_CURR_X_COUNT() bfin_read16(MDMA_D2_CURR_X_COUNT)
+#define bfin_write_MDMA_D2_CURR_X_COUNT(val) bfin_write16(MDMA_D2_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D2_CURR_Y_COUNT() bfin_read16(MDMA_D2_CURR_Y_COUNT)
+#define bfin_write_MDMA_D2_CURR_Y_COUNT(val) bfin_write16(MDMA_D2_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D2_IRQ_STATUS() bfin_read16(MDMA_D2_IRQ_STATUS)
+#define bfin_write_MDMA_D2_IRQ_STATUS(val) bfin_write16(MDMA_D2_IRQ_STATUS,val)
+#define bfin_read_MDMA_D2_PERIPHERAL_MAP() bfin_read16(MDMA_D2_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D2_PERIPHERAL_MAP(val) bfin_write16(MDMA_D2_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_S2_CONFIG() bfin_read16(MDMA_S2_CONFIG)
+#define bfin_write_MDMA_S2_CONFIG(val) bfin_write16(MDMA_S2_CONFIG,val)
+#define bfin_read_MDMA_S2_NEXT_DESC_PTR() bfin_read32(MDMA_S2_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S2_NEXT_DESC_PTR(val) bfin_write32(MDMA_S2_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S2_START_ADDR() bfin_read32(MDMA_S2_START_ADDR)
+#define bfin_write_MDMA_S2_START_ADDR(val) bfin_write32(MDMA_S2_START_ADDR,val)
+#define bfin_read_MDMA_S2_X_COUNT() bfin_read16(MDMA_S2_X_COUNT)
+#define bfin_write_MDMA_S2_X_COUNT(val) bfin_write16(MDMA_S2_X_COUNT,val)
+#define bfin_read_MDMA_S2_Y_COUNT() bfin_read16(MDMA_S2_Y_COUNT)
+#define bfin_write_MDMA_S2_Y_COUNT(val) bfin_write16(MDMA_S2_Y_COUNT,val)
+#define bfin_read_MDMA_S2_X_MODIFY() bfin_read16(MDMA_S2_X_MODIFY)
+#define bfin_write_MDMA_S2_X_MODIFY(val) bfin_write16(MDMA_S2_X_MODIFY,val)
+#define bfin_read_MDMA_S2_Y_MODIFY() bfin_read16(MDMA_S2_Y_MODIFY)
+#define bfin_write_MDMA_S2_Y_MODIFY(val) bfin_write16(MDMA_S2_Y_MODIFY,val)
+#define bfin_read_MDMA_S2_CURR_DESC_PTR() bfin_read32(MDMA_S2_CURR_DESC_PTR)
+#define bfin_write_MDMA_S2_CURR_DESC_PTR(val) bfin_write32(MDMA_S2_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S2_CURR_ADDR() bfin_read32(MDMA_S2_CURR_ADDR)
+#define bfin_write_MDMA_S2_CURR_ADDR(val) bfin_write32(MDMA_S2_CURR_ADDR,val)
+#define bfin_read_MDMA_S2_CURR_X_COUNT() bfin_read16(MDMA_S2_CURR_X_COUNT)
+#define bfin_write_MDMA_S2_CURR_X_COUNT(val) bfin_write16(MDMA_S2_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S2_CURR_Y_COUNT() bfin_read16(MDMA_S2_CURR_Y_COUNT)
+#define bfin_write_MDMA_S2_CURR_Y_COUNT(val) bfin_write16(MDMA_S2_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S2_IRQ_STATUS() bfin_read16(MDMA_S2_IRQ_STATUS)
+#define bfin_write_MDMA_S2_IRQ_STATUS(val) bfin_write16(MDMA_S2_IRQ_STATUS,val)
+#define bfin_read_MDMA_S2_PERIPHERAL_MAP() bfin_read16(MDMA_S2_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S2_PERIPHERAL_MAP(val) bfin_write16(MDMA_S2_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_D3_CONFIG() bfin_read16(MDMA_D3_CONFIG)
+#define bfin_write_MDMA_D3_CONFIG(val) bfin_write16(MDMA_D3_CONFIG,val)
+#define bfin_read_MDMA_D3_NEXT_DESC_PTR() bfin_read32(MDMA_D3_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D3_NEXT_DESC_PTR(val) bfin_write32(MDMA_D3_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D3_START_ADDR() bfin_read32(MDMA_D3_START_ADDR)
+#define bfin_write_MDMA_D3_START_ADDR(val) bfin_write32(MDMA_D3_START_ADDR,val)
+#define bfin_read_MDMA_D3_X_COUNT() bfin_read16(MDMA_D3_X_COUNT)
+#define bfin_write_MDMA_D3_X_COUNT(val) bfin_write16(MDMA_D3_X_COUNT,val)
+#define bfin_read_MDMA_D3_Y_COUNT() bfin_read16(MDMA_D3_Y_COUNT)
+#define bfin_write_MDMA_D3_Y_COUNT(val) bfin_write16(MDMA_D3_Y_COUNT,val)
+#define bfin_read_MDMA_D3_X_MODIFY() bfin_read16(MDMA_D3_X_MODIFY)
+#define bfin_write_MDMA_D3_X_MODIFY(val) bfin_write16(MDMA_D3_X_MODIFY,val)
+#define bfin_read_MDMA_D3_Y_MODIFY() bfin_read16(MDMA_D3_Y_MODIFY)
+#define bfin_write_MDMA_D3_Y_MODIFY(val) bfin_write16(MDMA_D3_Y_MODIFY,val)
+#define bfin_read_MDMA_D3_CURR_DESC_PTR() bfin_read32(MDMA_D3_CURR_DESC_PTR)
+#define bfin_write_MDMA_D3_CURR_DESC_PTR(val) bfin_write32(MDMA_D3_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D3_CURR_ADDR() bfin_read32(MDMA_D3_CURR_ADDR)
+#define bfin_write_MDMA_D3_CURR_ADDR(val) bfin_write32(MDMA_D3_CURR_ADDR,val)
+#define bfin_read_MDMA_D3_CURR_X_COUNT() bfin_read16(MDMA_D3_CURR_X_COUNT)
+#define bfin_write_MDMA_D3_CURR_X_COUNT(val) bfin_write16(MDMA_D3_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D3_CURR_Y_COUNT() bfin_read16(MDMA_D3_CURR_Y_COUNT)
+#define bfin_write_MDMA_D3_CURR_Y_COUNT(val) bfin_write16(MDMA_D3_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D3_IRQ_STATUS() bfin_read16(MDMA_D3_IRQ_STATUS)
+#define bfin_write_MDMA_D3_IRQ_STATUS(val) bfin_write16(MDMA_D3_IRQ_STATUS,val)
+#define bfin_read_MDMA_D3_PERIPHERAL_MAP() bfin_read16(MDMA_D3_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D3_PERIPHERAL_MAP(val) bfin_write16(MDMA_D3_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_S3_CONFIG() bfin_read16(MDMA_S3_CONFIG)
+#define bfin_write_MDMA_S3_CONFIG(val) bfin_write16(MDMA_S3_CONFIG,val)
+#define bfin_read_MDMA_S3_NEXT_DESC_PTR() bfin_read32(MDMA_S3_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S3_NEXT_DESC_PTR(val) bfin_write32(MDMA_S3_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S3_START_ADDR() bfin_read32(MDMA_S3_START_ADDR)
+#define bfin_write_MDMA_S3_START_ADDR(val) bfin_write32(MDMA_S3_START_ADDR,val)
+#define bfin_read_MDMA_S3_X_COUNT() bfin_read16(MDMA_S3_X_COUNT)
+#define bfin_write_MDMA_S3_X_COUNT(val) bfin_write16(MDMA_S3_X_COUNT,val)
+#define bfin_read_MDMA_S3_Y_COUNT() bfin_read16(MDMA_S3_Y_COUNT)
+#define bfin_write_MDMA_S3_Y_COUNT(val) bfin_write16(MDMA_S3_Y_COUNT,val)
+#define bfin_read_MDMA_S3_X_MODIFY() bfin_read16(MDMA_S3_X_MODIFY)
+#define bfin_write_MDMA_S3_X_MODIFY(val) bfin_write16(MDMA_S3_X_MODIFY,val)
+#define bfin_read_MDMA_S3_Y_MODIFY() bfin_read16(MDMA_S3_Y_MODIFY)
+#define bfin_write_MDMA_S3_Y_MODIFY(val) bfin_write16(MDMA_S3_Y_MODIFY,val)
+#define bfin_read_MDMA_S3_CURR_DESC_PTR() bfin_read32(MDMA_S3_CURR_DESC_PTR)
+#define bfin_write_MDMA_S3_CURR_DESC_PTR(val) bfin_write32(MDMA_S3_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S3_CURR_ADDR() bfin_read32(MDMA_S3_CURR_ADDR)
+#define bfin_write_MDMA_S3_CURR_ADDR(val) bfin_write32(MDMA_S3_CURR_ADDR,val)
+#define bfin_read_MDMA_S3_CURR_X_COUNT() bfin_read16(MDMA_S3_CURR_X_COUNT)
+#define bfin_write_MDMA_S3_CURR_X_COUNT(val) bfin_write16(MDMA_S3_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S3_CURR_Y_COUNT() bfin_read16(MDMA_S3_CURR_Y_COUNT)
+#define bfin_write_MDMA_S3_CURR_Y_COUNT(val) bfin_write16(MDMA_S3_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S3_IRQ_STATUS() bfin_read16(MDMA_S3_IRQ_STATUS)
+#define bfin_write_MDMA_S3_IRQ_STATUS(val) bfin_write16(MDMA_S3_IRQ_STATUS,val)
+#define bfin_read_MDMA_S3_PERIPHERAL_MAP() bfin_read16(MDMA_S3_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S3_PERIPHERAL_MAP(val) bfin_write16(MDMA_S3_PERIPHERAL_MAP,val)
/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */
#define bfin_read_DMA2_0_CONFIG() bfin_read16(DMA2_0_CONFIG)
#define bfin_write_DMA2_0_CONFIG(val) bfin_write16(DMA2_0_CONFIG,val)
@@ -1263,110 +1255,110 @@
#define bfin_read_DMA2_11_PERIPHERAL_MAP() bfin_read16(DMA2_11_PERIPHERAL_MAP)
#define bfin_write_DMA2_11_PERIPHERAL_MAP(val) bfin_write16(DMA2_11_PERIPHERAL_MAP,val)
/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */
-#define bfin_read_MDMA2_D0_CONFIG() bfin_read16(MDMA2_D0_CONFIG)
-#define bfin_write_MDMA2_D0_CONFIG(val) bfin_write16(MDMA2_D0_CONFIG,val)
-#define bfin_read_MDMA2_D0_NEXT_DESC_PTR() bfin_read32(MDMA2_D0_NEXT_DESC_PTR)
-#define bfin_write_MDMA2_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D0_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA2_D0_START_ADDR() bfin_read32(MDMA2_D0_START_ADDR)
-#define bfin_write_MDMA2_D0_START_ADDR(val) bfin_write32(MDMA2_D0_START_ADDR,val)
-#define bfin_read_MDMA2_D0_X_COUNT() bfin_read16(MDMA2_D0_X_COUNT)
-#define bfin_write_MDMA2_D0_X_COUNT(val) bfin_write16(MDMA2_D0_X_COUNT,val)
-#define bfin_read_MDMA2_D0_Y_COUNT() bfin_read16(MDMA2_D0_Y_COUNT)
-#define bfin_write_MDMA2_D0_Y_COUNT(val) bfin_write16(MDMA2_D0_Y_COUNT,val)
-#define bfin_read_MDMA2_D0_X_MODIFY() bfin_read16(MDMA2_D0_X_MODIFY)
-#define bfin_write_MDMA2_D0_X_MODIFY(val) bfin_write16(MDMA2_D0_X_MODIFY,val)
-#define bfin_read_MDMA2_D0_Y_MODIFY() bfin_read16(MDMA2_D0_Y_MODIFY)
-#define bfin_write_MDMA2_D0_Y_MODIFY(val) bfin_write16(MDMA2_D0_Y_MODIFY,val)
-#define bfin_read_MDMA2_D0_CURR_DESC_PTR() bfin_read32(MDMA2_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA2_D0_CURR_DESC_PTR(val) bfin_write32(MDMA2_D0_CURR_DESC_PTR,val)
-#define bfin_read_MDMA2_D0_CURR_ADDR() bfin_read32(MDMA2_D0_CURR_ADDR)
-#define bfin_write_MDMA2_D0_CURR_ADDR(val) bfin_write32(MDMA2_D0_CURR_ADDR,val)
-#define bfin_read_MDMA2_D0_CURR_X_COUNT() bfin_read16(MDMA2_D0_CURR_X_COUNT)
-#define bfin_write_MDMA2_D0_CURR_X_COUNT(val) bfin_write16(MDMA2_D0_CURR_X_COUNT,val)
-#define bfin_read_MDMA2_D0_CURR_Y_COUNT() bfin_read16(MDMA2_D0_CURR_Y_COUNT)
-#define bfin_write_MDMA2_D0_CURR_Y_COUNT(val) bfin_write16(MDMA2_D0_CURR_Y_COUNT,val)
-#define bfin_read_MDMA2_D0_IRQ_STATUS() bfin_read16(MDMA2_D0_IRQ_STATUS)
-#define bfin_write_MDMA2_D0_IRQ_STATUS(val) bfin_write16(MDMA2_D0_IRQ_STATUS,val)
-#define bfin_read_MDMA2_D0_PERIPHERAL_MAP() bfin_read16(MDMA2_D0_PERIPHERAL_MAP)
-#define bfin_write_MDMA2_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D0_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA2_S0_CONFIG() bfin_read16(MDMA2_S0_CONFIG)
-#define bfin_write_MDMA2_S0_CONFIG(val) bfin_write16(MDMA2_S0_CONFIG,val)
-#define bfin_read_MDMA2_S0_NEXT_DESC_PTR() bfin_read32(MDMA2_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA2_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S0_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA2_S0_START_ADDR() bfin_read32(MDMA2_S0_START_ADDR)
-#define bfin_write_MDMA2_S0_START_ADDR(val) bfin_write32(MDMA2_S0_START_ADDR,val)
-#define bfin_read_MDMA2_S0_X_COUNT() bfin_read16(MDMA2_S0_X_COUNT)
-#define bfin_write_MDMA2_S0_X_COUNT(val) bfin_write16(MDMA2_S0_X_COUNT,val)
-#define bfin_read_MDMA2_S0_Y_COUNT() bfin_read16(MDMA2_S0_Y_COUNT)
-#define bfin_write_MDMA2_S0_Y_COUNT(val) bfin_write16(MDMA2_S0_Y_COUNT,val)
-#define bfin_read_MDMA2_S0_X_MODIFY() bfin_read16(MDMA2_S0_X_MODIFY)
-#define bfin_write_MDMA2_S0_X_MODIFY(val) bfin_write16(MDMA2_S0_X_MODIFY,val)
-#define bfin_read_MDMA2_S0_Y_MODIFY() bfin_read16(MDMA2_S0_Y_MODIFY)
-#define bfin_write_MDMA2_S0_Y_MODIFY(val) bfin_write16(MDMA2_S0_Y_MODIFY,val)
-#define bfin_read_MDMA2_S0_CURR_DESC_PTR() bfin_read32(MDMA2_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA2_S0_CURR_DESC_PTR(val) bfin_write32(MDMA2_S0_CURR_DESC_PTR,val)
-#define bfin_read_MDMA2_S0_CURR_ADDR() bfin_read32(MDMA2_S0_CURR_ADDR)
-#define bfin_write_MDMA2_S0_CURR_ADDR(val) bfin_write32(MDMA2_S0_CURR_ADDR,val)
-#define bfin_read_MDMA2_S0_CURR_X_COUNT() bfin_read16(MDMA2_S0_CURR_X_COUNT)
-#define bfin_write_MDMA2_S0_CURR_X_COUNT(val) bfin_write16(MDMA2_S0_CURR_X_COUNT,val)
-#define bfin_read_MDMA2_S0_CURR_Y_COUNT() bfin_read16(MDMA2_S0_CURR_Y_COUNT)
-#define bfin_write_MDMA2_S0_CURR_Y_COUNT(val) bfin_write16(MDMA2_S0_CURR_Y_COUNT,val)
-#define bfin_read_MDMA2_S0_IRQ_STATUS() bfin_read16(MDMA2_S0_IRQ_STATUS)
-#define bfin_write_MDMA2_S0_IRQ_STATUS(val) bfin_write16(MDMA2_S0_IRQ_STATUS,val)
-#define bfin_read_MDMA2_S0_PERIPHERAL_MAP() bfin_read16(MDMA2_S0_PERIPHERAL_MAP)
-#define bfin_write_MDMA2_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S0_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA2_D1_CONFIG() bfin_read16(MDMA2_D1_CONFIG)
-#define bfin_write_MDMA2_D1_CONFIG(val) bfin_write16(MDMA2_D1_CONFIG,val)
-#define bfin_read_MDMA2_D1_NEXT_DESC_PTR() bfin_read32(MDMA2_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA2_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D1_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA2_D1_START_ADDR() bfin_read32(MDMA2_D1_START_ADDR)
-#define bfin_write_MDMA2_D1_START_ADDR(val) bfin_write32(MDMA2_D1_START_ADDR,val)
-#define bfin_read_MDMA2_D1_X_COUNT() bfin_read16(MDMA2_D1_X_COUNT)
-#define bfin_write_MDMA2_D1_X_COUNT(val) bfin_write16(MDMA2_D1_X_COUNT,val)
-#define bfin_read_MDMA2_D1_Y_COUNT() bfin_read16(MDMA2_D1_Y_COUNT)
-#define bfin_write_MDMA2_D1_Y_COUNT(val) bfin_write16(MDMA2_D1_Y_COUNT,val)
-#define bfin_read_MDMA2_D1_X_MODIFY() bfin_read16(MDMA2_D1_X_MODIFY)
-#define bfin_write_MDMA2_D1_X_MODIFY(val) bfin_write16(MDMA2_D1_X_MODIFY,val)
-#define bfin_read_MDMA2_D1_Y_MODIFY() bfin_read16(MDMA2_D1_Y_MODIFY)
-#define bfin_write_MDMA2_D1_Y_MODIFY(val) bfin_write16(MDMA2_D1_Y_MODIFY,val)
-#define bfin_read_MDMA2_D1_CURR_DESC_PTR() bfin_read32(MDMA2_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA2_D1_CURR_DESC_PTR(val) bfin_write32(MDMA2_D1_CURR_DESC_PTR,val)
-#define bfin_read_MDMA2_D1_CURR_ADDR() bfin_read32(MDMA2_D1_CURR_ADDR)
-#define bfin_write_MDMA2_D1_CURR_ADDR(val) bfin_write32(MDMA2_D1_CURR_ADDR,val)
-#define bfin_read_MDMA2_D1_CURR_X_COUNT() bfin_read16(MDMA2_D1_CURR_X_COUNT)
-#define bfin_write_MDMA2_D1_CURR_X_COUNT(val) bfin_write16(MDMA2_D1_CURR_X_COUNT,val)
-#define bfin_read_MDMA2_D1_CURR_Y_COUNT() bfin_read16(MDMA2_D1_CURR_Y_COUNT)
-#define bfin_write_MDMA2_D1_CURR_Y_COUNT(val) bfin_write16(MDMA2_D1_CURR_Y_COUNT,val)
-#define bfin_read_MDMA2_D1_IRQ_STATUS() bfin_read16(MDMA2_D1_IRQ_STATUS)
-#define bfin_write_MDMA2_D1_IRQ_STATUS(val) bfin_write16(MDMA2_D1_IRQ_STATUS,val)
-#define bfin_read_MDMA2_D1_PERIPHERAL_MAP() bfin_read16(MDMA2_D1_PERIPHERAL_MAP)
-#define bfin_write_MDMA2_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D1_PERIPHERAL_MAP,val)
-#define bfin_read_MDMA2_S1_CONFIG() bfin_read16(MDMA2_S1_CONFIG)
-#define bfin_write_MDMA2_S1_CONFIG(val) bfin_write16(MDMA2_S1_CONFIG,val)
-#define bfin_read_MDMA2_S1_NEXT_DESC_PTR() bfin_read32(MDMA2_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA2_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S1_NEXT_DESC_PTR,val)
-#define bfin_read_MDMA2_S1_START_ADDR() bfin_read32(MDMA2_S1_START_ADDR)
-#define bfin_write_MDMA2_S1_START_ADDR(val) bfin_write32(MDMA2_S1_START_ADDR,val)
-#define bfin_read_MDMA2_S1_X_COUNT() bfin_read16(MDMA2_S1_X_COUNT)
-#define bfin_write_MDMA2_S1_X_COUNT(val) bfin_write16(MDMA2_S1_X_COUNT,val)
-#define bfin_read_MDMA2_S1_Y_COUNT() bfin_read16(MDMA2_S1_Y_COUNT)
-#define bfin_write_MDMA2_S1_Y_COUNT(val) bfin_write16(MDMA2_S1_Y_COUNT,val)
-#define bfin_read_MDMA2_S1_X_MODIFY() bfin_read16(MDMA2_S1_X_MODIFY)
-#define bfin_write_MDMA2_S1_X_MODIFY(val) bfin_write16(MDMA2_S1_X_MODIFY,val)
-#define bfin_read_MDMA2_S1_Y_MODIFY() bfin_read16(MDMA2_S1_Y_MODIFY)
-#define bfin_write_MDMA2_S1_Y_MODIFY(val) bfin_write16(MDMA2_S1_Y_MODIFY,val)
-#define bfin_read_MDMA2_S1_CURR_DESC_PTR() bfin_read32(MDMA2_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA2_S1_CURR_DESC_PTR(val) bfin_write32(MDMA2_S1_CURR_DESC_PTR,val)
-#define bfin_read_MDMA2_S1_CURR_ADDR() bfin_read32(MDMA2_S1_CURR_ADDR)
-#define bfin_write_MDMA2_S1_CURR_ADDR(val) bfin_write32(MDMA2_S1_CURR_ADDR,val)
-#define bfin_read_MDMA2_S1_CURR_X_COUNT() bfin_read16(MDMA2_S1_CURR_X_COUNT)
-#define bfin_write_MDMA2_S1_CURR_X_COUNT(val) bfin_write16(MDMA2_S1_CURR_X_COUNT,val)
-#define bfin_read_MDMA2_S1_CURR_Y_COUNT() bfin_read16(MDMA2_S1_CURR_Y_COUNT)
-#define bfin_write_MDMA2_S1_CURR_Y_COUNT(val) bfin_write16(MDMA2_S1_CURR_Y_COUNT,val)
-#define bfin_read_MDMA2_S1_IRQ_STATUS() bfin_read16(MDMA2_S1_IRQ_STATUS)
-#define bfin_write_MDMA2_S1_IRQ_STATUS(val) bfin_write16(MDMA2_S1_IRQ_STATUS,val)
-#define bfin_read_MDMA2_S1_PERIPHERAL_MAP() bfin_read16(MDMA2_S1_PERIPHERAL_MAP)
-#define bfin_write_MDMA2_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S1_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG,val)
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR,val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT,val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT,val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY,val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY,val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR,val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS,val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG,val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR,val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT,val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT,val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY,val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY,val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR,val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS,val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG,val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR,val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT,val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT,val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY,val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY,val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR,val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS,val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG,val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR,val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT,val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT,val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY,val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY,val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR,val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS,val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP,val)
/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */
#define bfin_read_IMDMA_D0_CONFIG() bfin_read16(IMDMA_D0_CONFIG)
#define bfin_write_IMDMA_D0_CONFIG(val) bfin_write16(IMDMA_D0_CONFIG,val)
@@ -1465,65 +1457,4 @@
#define bfin_read_IMDMA_S1_IRQ_STATUS() bfin_read16(IMDMA_S1_IRQ_STATUS)
#define bfin_write_IMDMA_S1_IRQ_STATUS(val) bfin_write16(IMDMA_S1_IRQ_STATUS,val)
-#define bfin_read_MDMA_S0_CONFIG() bfin_read_MDMA1_S0_CONFIG()
-#define bfin_write_MDMA_S0_CONFIG(val) bfin_write_MDMA1_S0_CONFIG(val)
-#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read_MDMA1_S0_IRQ_STATUS()
-#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write_MDMA1_S0_IRQ_STATUS(val)
-#define bfin_read_MDMA_S0_X_MODIFY() bfin_read_MDMA1_S0_X_MODIFY()
-#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write_MDMA1_S0_X_MODIFY(val)
-#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read_MDMA1_S0_Y_MODIFY()
-#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write_MDMA1_S0_Y_MODIFY(val)
-#define bfin_read_MDMA_S0_X_COUNT() bfin_read_MDMA1_S0_X_COUNT()
-#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write_MDMA1_S0_X_COUNT(val)
-#define bfin_read_MDMA_S0_Y_COUNT() bfin_read_MDMA1_S0_Y_COUNT()
-#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write_MDMA1_S0_Y_COUNT(val)
-#define bfin_read_MDMA_S0_START_ADDR() bfin_read_MDMA1_S0_START_ADDR()
-#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write_MDMA1_S0_START_ADDR(val)
-#define bfin_read_MDMA_D0_CONFIG() bfin_read_MDMA1_D0_CONFIG()
-#define bfin_write_MDMA_D0_CONFIG(val) bfin_write_MDMA1_D0_CONFIG(val)
-#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read_MDMA1_D0_IRQ_STATUS()
-#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write_MDMA1_D0_IRQ_STATUS(val)
-#define bfin_read_MDMA_D0_X_MODIFY() bfin_read_MDMA1_D0_X_MODIFY()
-#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write_MDMA1_D0_X_MODIFY(val)
-#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read_MDMA1_D0_Y_MODIFY()
-#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write_MDMA1_D0_Y_MODIFY(val)
-#define bfin_read_MDMA_D0_X_COUNT() bfin_read_MDMA1_D0_X_COUNT()
-#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write_MDMA1_D0_X_COUNT(val)
-#define bfin_read_MDMA_D0_Y_COUNT() bfin_read_MDMA1_D0_Y_COUNT()
-#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write_MDMA1_D0_Y_COUNT(val)
-#define bfin_read_MDMA_D0_START_ADDR() bfin_read_MDMA1_D0_START_ADDR()
-#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write_MDMA1_D0_START_ADDR(val)
-
-#define bfin_read_MDMA_S1_CONFIG() bfin_read_MDMA1_S1_CONFIG()
-#define bfin_write_MDMA_S1_CONFIG(val) bfin_write_MDMA1_S1_CONFIG(val)
-#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read_MDMA1_S1_IRQ_STATUS()
-#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write_MDMA1_S1_IRQ_STATUS(val)
-#define bfin_read_MDMA_S1_X_MODIFY() bfin_read_MDMA1_S1_X_MODIFY()
-#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write_MDMA1_S1_X_MODIFY(val)
-#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read_MDMA1_S1_Y_MODIFY()
-#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write_MDMA1_S1_Y_MODIFY(val)
-#define bfin_read_MDMA_S1_X_COUNT() bfin_read_MDMA1_S1_X_COUNT()
-#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write_MDMA1_S1_X_COUNT(val)
-#define bfin_read_MDMA_S1_Y_COUNT() bfin_read_MDMA1_S1_Y_COUNT()
-#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write_MDMA1_S1_Y_COUNT(val)
-#define bfin_read_MDMA_S1_START_ADDR() bfin_read_MDMA1_S1_START_ADDR()
-#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write_MDMA1_S1_START_ADDR(val)
-#define bfin_read_MDMA_D1_CONFIG() bfin_read_MDMA1_D1_CONFIG()
-#define bfin_write_MDMA_D1_CONFIG(val) bfin_write_MDMA1_D1_CONFIG(val)
-#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read_MDMA1_D1_IRQ_STATUS()
-#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write_MDMA1_D1_IRQ_STATUS(val)
-#define bfin_read_MDMA_D1_X_MODIFY() bfin_read_MDMA1_D1_X_MODIFY()
-#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write_MDMA1_D1_X_MODIFY(val)
-#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read_MDMA1_D1_Y_MODIFY()
-#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write_MDMA1_D1_Y_MODIFY(val)
-#define bfin_read_MDMA_D1_X_COUNT() bfin_read_MDMA1_D1_X_COUNT()
-#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write_MDMA1_D1_X_COUNT(val)
-#define bfin_read_MDMA_D1_Y_COUNT() bfin_read_MDMA1_D1_Y_COUNT()
-#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write_MDMA1_D1_Y_COUNT(val)
-#define bfin_read_MDMA_D1_START_ADDR() bfin_read_MDMA1_D1_START_ADDR()
-#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write_MDMA1_D1_START_ADDR(val)
-
-/* These need to be last due to the cdef/linux inter-dependencies */
-#include <asm/irq.h>
-
#endif /* _CDEF_BF561_H */
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index 79e048d452e0..71e805ea74e5 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -1,18 +1,11 @@
/*
- * Copyright 2005-2009 Analog Devices Inc.
+ * Copyright 2005-2010 Analog Devices Inc.
*
* Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF561_H
#define _DEF_BF561_H
-/*
-#if !defined(__ADSPBF561__)
-#warning defBF561.h should only be included for BF561 chip.
-#endif
-*/
-/* include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
/*********************************************************************************** */
/* System MMR Register Map */
@@ -311,10 +304,10 @@
#define PPI1_FRAME 0xFFC01310 /* PPI1 Frame Length register */
/*DMA traffic control registers */
-#define DMA1_TC_PER 0xFFC01B0C /* Traffic control periods */
-#define DMA1_TC_CNT 0xFFC01B10 /* Traffic control current counts */
-#define DMA2_TC_PER 0xFFC00B0C /* Traffic control periods */
-#define DMA2_TC_CNT 0xFFC00B10 /* Traffic control current counts */
+#define DMAC0_TC_PER 0xFFC00B0C /* Traffic control periods */
+#define DMAC0_TC_CNT 0xFFC00B10 /* Traffic control current counts */
+#define DMAC1_TC_PER 0xFFC01B0C /* Traffic control periods */
+#define DMAC1_TC_CNT 0xFFC01B10 /* Traffic control current counts */
/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */
#define DMA1_0_CONFIG 0xFFC01C08 /* DMA1 Channel 0 Configuration register */
@@ -486,61 +479,61 @@
#define DMA1_11_PERIPHERAL_MAP 0xFFC01EEC /* DMA1 Channel 11 Peripheral Map Register */
/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */
-#define MDMA1_D0_CONFIG 0xFFC01F08 /*MemDMA1 Stream 0 Destination Configuration */
-#define MDMA1_D0_NEXT_DESC_PTR 0xFFC01F00 /*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */
-#define MDMA1_D0_START_ADDR 0xFFC01F04 /*MemDMA1 Stream 0 Destination Start Address */
-#define MDMA1_D0_X_COUNT 0xFFC01F10 /*MemDMA1 Stream 0 Destination Inner-Loop Count */
-#define MDMA1_D0_Y_COUNT 0xFFC01F18 /*MemDMA1 Stream 0 Destination Outer-Loop Count */
-#define MDMA1_D0_X_MODIFY 0xFFC01F14 /*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */
-#define MDMA1_D0_Y_MODIFY 0xFFC01F1C /*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */
-#define MDMA1_D0_CURR_DESC_PTR 0xFFC01F20 /*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */
-#define MDMA1_D0_CURR_ADDR 0xFFC01F24 /*MemDMA1 Stream 0 Destination Current Address */
-#define MDMA1_D0_CURR_X_COUNT 0xFFC01F30 /*MemDMA1 Stream 0 Dest Current Inner-Loop Count */
-#define MDMA1_D0_CURR_Y_COUNT 0xFFC01F38 /*MemDMA1 Stream 0 Dest Current Outer-Loop Count */
-#define MDMA1_D0_IRQ_STATUS 0xFFC01F28 /*MemDMA1 Stream 0 Destination Interrupt/Status */
-#define MDMA1_D0_PERIPHERAL_MAP 0xFFC01F2C /*MemDMA1 Stream 0 Destination Peripheral Map */
-
-#define MDMA1_S0_CONFIG 0xFFC01F48 /*MemDMA1 Stream 0 Source Configuration */
-#define MDMA1_S0_NEXT_DESC_PTR 0xFFC01F40 /*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */
-#define MDMA1_S0_START_ADDR 0xFFC01F44 /*MemDMA1 Stream 0 Source Start Address */
-#define MDMA1_S0_X_COUNT 0xFFC01F50 /*MemDMA1 Stream 0 Source Inner-Loop Count */
-#define MDMA1_S0_Y_COUNT 0xFFC01F58 /*MemDMA1 Stream 0 Source Outer-Loop Count */
-#define MDMA1_S0_X_MODIFY 0xFFC01F54 /*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */
-#define MDMA1_S0_Y_MODIFY 0xFFC01F5C /*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */
-#define MDMA1_S0_CURR_DESC_PTR 0xFFC01F60 /*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */
-#define MDMA1_S0_CURR_ADDR 0xFFC01F64 /*MemDMA1 Stream 0 Source Current Address */
-#define MDMA1_S0_CURR_X_COUNT 0xFFC01F70 /*MemDMA1 Stream 0 Source Current Inner-Loop Count */
-#define MDMA1_S0_CURR_Y_COUNT 0xFFC01F78 /*MemDMA1 Stream 0 Source Current Outer-Loop Count */
-#define MDMA1_S0_IRQ_STATUS 0xFFC01F68 /*MemDMA1 Stream 0 Source Interrupt/Status */
-#define MDMA1_S0_PERIPHERAL_MAP 0xFFC01F6C /*MemDMA1 Stream 0 Source Peripheral Map */
-
-#define MDMA1_D1_CONFIG 0xFFC01F88 /*MemDMA1 Stream 1 Destination Configuration */
-#define MDMA1_D1_NEXT_DESC_PTR 0xFFC01F80 /*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */
-#define MDMA1_D1_START_ADDR 0xFFC01F84 /*MemDMA1 Stream 1 Destination Start Address */
-#define MDMA1_D1_X_COUNT 0xFFC01F90 /*MemDMA1 Stream 1 Destination Inner-Loop Count */
-#define MDMA1_D1_Y_COUNT 0xFFC01F98 /*MemDMA1 Stream 1 Destination Outer-Loop Count */
-#define MDMA1_D1_X_MODIFY 0xFFC01F94 /*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */
-#define MDMA1_D1_Y_MODIFY 0xFFC01F9C /*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */
-#define MDMA1_D1_CURR_DESC_PTR 0xFFC01FA0 /*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */
-#define MDMA1_D1_CURR_ADDR 0xFFC01FA4 /*MemDMA1 Stream 1 Dest Current Address */
-#define MDMA1_D1_CURR_X_COUNT 0xFFC01FB0 /*MemDMA1 Stream 1 Dest Current Inner-Loop Count */
-#define MDMA1_D1_CURR_Y_COUNT 0xFFC01FB8 /*MemDMA1 Stream 1 Dest Current Outer-Loop Count */
-#define MDMA1_D1_IRQ_STATUS 0xFFC01FA8 /*MemDMA1 Stream 1 Dest Interrupt/Status */
-#define MDMA1_D1_PERIPHERAL_MAP 0xFFC01FAC /*MemDMA1 Stream 1 Dest Peripheral Map */
-
-#define MDMA1_S1_CONFIG 0xFFC01FC8 /*MemDMA1 Stream 1 Source Configuration */
-#define MDMA1_S1_NEXT_DESC_PTR 0xFFC01FC0 /*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */
-#define MDMA1_S1_START_ADDR 0xFFC01FC4 /*MemDMA1 Stream 1 Source Start Address */
-#define MDMA1_S1_X_COUNT 0xFFC01FD0 /*MemDMA1 Stream 1 Source Inner-Loop Count */
-#define MDMA1_S1_Y_COUNT 0xFFC01FD8 /*MemDMA1 Stream 1 Source Outer-Loop Count */
-#define MDMA1_S1_X_MODIFY 0xFFC01FD4 /*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */
-#define MDMA1_S1_Y_MODIFY 0xFFC01FDC /*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */
-#define MDMA1_S1_CURR_DESC_PTR 0xFFC01FE0 /*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */
-#define MDMA1_S1_CURR_ADDR 0xFFC01FE4 /*MemDMA1 Stream 1 Source Current Address */
-#define MDMA1_S1_CURR_X_COUNT 0xFFC01FF0 /*MemDMA1 Stream 1 Source Current Inner-Loop Count */
-#define MDMA1_S1_CURR_Y_COUNT 0xFFC01FF8 /*MemDMA1 Stream 1 Source Current Outer-Loop Count */
-#define MDMA1_S1_IRQ_STATUS 0xFFC01FE8 /*MemDMA1 Stream 1 Source Interrupt/Status */
-#define MDMA1_S1_PERIPHERAL_MAP 0xFFC01FEC /*MemDMA1 Stream 1 Source Peripheral Map */
+#define MDMA_D2_CONFIG 0xFFC01F08 /*MemDMA1 Stream 0 Destination Configuration */
+#define MDMA_D2_NEXT_DESC_PTR 0xFFC01F00 /*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA_D2_START_ADDR 0xFFC01F04 /*MemDMA1 Stream 0 Destination Start Address */
+#define MDMA_D2_X_COUNT 0xFFC01F10 /*MemDMA1 Stream 0 Destination Inner-Loop Count */
+#define MDMA_D2_Y_COUNT 0xFFC01F18 /*MemDMA1 Stream 0 Destination Outer-Loop Count */
+#define MDMA_D2_X_MODIFY 0xFFC01F14 /*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA_D2_Y_MODIFY 0xFFC01F1C /*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA_D2_CURR_DESC_PTR 0xFFC01F20 /*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA_D2_CURR_ADDR 0xFFC01F24 /*MemDMA1 Stream 0 Destination Current Address */
+#define MDMA_D2_CURR_X_COUNT 0xFFC01F30 /*MemDMA1 Stream 0 Dest Current Inner-Loop Count */
+#define MDMA_D2_CURR_Y_COUNT 0xFFC01F38 /*MemDMA1 Stream 0 Dest Current Outer-Loop Count */
+#define MDMA_D2_IRQ_STATUS 0xFFC01F28 /*MemDMA1 Stream 0 Destination Interrupt/Status */
+#define MDMA_D2_PERIPHERAL_MAP 0xFFC01F2C /*MemDMA1 Stream 0 Destination Peripheral Map */
+
+#define MDMA_S2_CONFIG 0xFFC01F48 /*MemDMA1 Stream 0 Source Configuration */
+#define MDMA_S2_NEXT_DESC_PTR 0xFFC01F40 /*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA_S2_START_ADDR 0xFFC01F44 /*MemDMA1 Stream 0 Source Start Address */
+#define MDMA_S2_X_COUNT 0xFFC01F50 /*MemDMA1 Stream 0 Source Inner-Loop Count */
+#define MDMA_S2_Y_COUNT 0xFFC01F58 /*MemDMA1 Stream 0 Source Outer-Loop Count */
+#define MDMA_S2_X_MODIFY 0xFFC01F54 /*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */
+#define MDMA_S2_Y_MODIFY 0xFFC01F5C /*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */
+#define MDMA_S2_CURR_DESC_PTR 0xFFC01F60 /*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA_S2_CURR_ADDR 0xFFC01F64 /*MemDMA1 Stream 0 Source Current Address */
+#define MDMA_S2_CURR_X_COUNT 0xFFC01F70 /*MemDMA1 Stream 0 Source Current Inner-Loop Count */
+#define MDMA_S2_CURR_Y_COUNT 0xFFC01F78 /*MemDMA1 Stream 0 Source Current Outer-Loop Count */
+#define MDMA_S2_IRQ_STATUS 0xFFC01F68 /*MemDMA1 Stream 0 Source Interrupt/Status */
+#define MDMA_S2_PERIPHERAL_MAP 0xFFC01F6C /*MemDMA1 Stream 0 Source Peripheral Map */
+
+#define MDMA_D3_CONFIG 0xFFC01F88 /*MemDMA1 Stream 1 Destination Configuration */
+#define MDMA_D3_NEXT_DESC_PTR 0xFFC01F80 /*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA_D3_START_ADDR 0xFFC01F84 /*MemDMA1 Stream 1 Destination Start Address */
+#define MDMA_D3_X_COUNT 0xFFC01F90 /*MemDMA1 Stream 1 Destination Inner-Loop Count */
+#define MDMA_D3_Y_COUNT 0xFFC01F98 /*MemDMA1 Stream 1 Destination Outer-Loop Count */
+#define MDMA_D3_X_MODIFY 0xFFC01F94 /*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA_D3_Y_MODIFY 0xFFC01F9C /*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA_D3_CURR_DESC_PTR 0xFFC01FA0 /*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */
+#define MDMA_D3_CURR_ADDR 0xFFC01FA4 /*MemDMA1 Stream 1 Dest Current Address */
+#define MDMA_D3_CURR_X_COUNT 0xFFC01FB0 /*MemDMA1 Stream 1 Dest Current Inner-Loop Count */
+#define MDMA_D3_CURR_Y_COUNT 0xFFC01FB8 /*MemDMA1 Stream 1 Dest Current Outer-Loop Count */
+#define MDMA_D3_IRQ_STATUS 0xFFC01FA8 /*MemDMA1 Stream 1 Dest Interrupt/Status */
+#define MDMA_D3_PERIPHERAL_MAP 0xFFC01FAC /*MemDMA1 Stream 1 Dest Peripheral Map */
+
+#define MDMA_S3_CONFIG 0xFFC01FC8 /*MemDMA1 Stream 1 Source Configuration */
+#define MDMA_S3_NEXT_DESC_PTR 0xFFC01FC0 /*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA_S3_START_ADDR 0xFFC01FC4 /*MemDMA1 Stream 1 Source Start Address */
+#define MDMA_S3_X_COUNT 0xFFC01FD0 /*MemDMA1 Stream 1 Source Inner-Loop Count */
+#define MDMA_S3_Y_COUNT 0xFFC01FD8 /*MemDMA1 Stream 1 Source Outer-Loop Count */
+#define MDMA_S3_X_MODIFY 0xFFC01FD4 /*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */
+#define MDMA_S3_Y_MODIFY 0xFFC01FDC /*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA_S3_CURR_DESC_PTR 0xFFC01FE0 /*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA_S3_CURR_ADDR 0xFFC01FE4 /*MemDMA1 Stream 1 Source Current Address */
+#define MDMA_S3_CURR_X_COUNT 0xFFC01FF0 /*MemDMA1 Stream 1 Source Current Inner-Loop Count */
+#define MDMA_S3_CURR_Y_COUNT 0xFFC01FF8 /*MemDMA1 Stream 1 Source Current Outer-Loop Count */
+#define MDMA_S3_IRQ_STATUS 0xFFC01FE8 /*MemDMA1 Stream 1 Source Interrupt/Status */
+#define MDMA_S3_PERIPHERAL_MAP 0xFFC01FEC /*MemDMA1 Stream 1 Source Peripheral Map */
/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */
#define DMA2_0_CONFIG 0xFFC00C08 /* DMA2 Channel 0 Configuration register */
@@ -712,117 +705,61 @@
#define DMA2_11_PERIPHERAL_MAP 0xFFC00EEC /* DMA2 Channel 11 Peripheral Map Register */
/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */
-#define MDMA2_D0_CONFIG 0xFFC00F08 /*MemDMA2 Stream 0 Destination Configuration register */
-#define MDMA2_D0_NEXT_DESC_PTR 0xFFC00F00 /*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */
-#define MDMA2_D0_START_ADDR 0xFFC00F04 /*MemDMA2 Stream 0 Destination Start Address */
-#define MDMA2_D0_X_COUNT 0xFFC00F10 /*MemDMA2 Stream 0 Dest Inner-Loop Count register */
-#define MDMA2_D0_Y_COUNT 0xFFC00F18 /*MemDMA2 Stream 0 Dest Outer-Loop Count register */
-#define MDMA2_D0_X_MODIFY 0xFFC00F14 /*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */
-#define MDMA2_D0_Y_MODIFY 0xFFC00F1C /*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */
-#define MDMA2_D0_CURR_DESC_PTR 0xFFC00F20 /*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */
-#define MDMA2_D0_CURR_ADDR 0xFFC00F24 /*MemDMA2 Stream 0 Destination Current Address */
-#define MDMA2_D0_CURR_X_COUNT 0xFFC00F30 /*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */
-#define MDMA2_D0_CURR_Y_COUNT 0xFFC00F38 /*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */
-#define MDMA2_D0_IRQ_STATUS 0xFFC00F28 /*MemDMA2 Stream 0 Dest Interrupt/Status Register */
-#define MDMA2_D0_PERIPHERAL_MAP 0xFFC00F2C /*MemDMA2 Stream 0 Destination Peripheral Map register */
-
-#define MDMA2_S0_CONFIG 0xFFC00F48 /*MemDMA2 Stream 0 Source Configuration register */
-#define MDMA2_S0_NEXT_DESC_PTR 0xFFC00F40 /*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */
-#define MDMA2_S0_START_ADDR 0xFFC00F44 /*MemDMA2 Stream 0 Source Start Address */
-#define MDMA2_S0_X_COUNT 0xFFC00F50 /*MemDMA2 Stream 0 Source Inner-Loop Count register */
-#define MDMA2_S0_Y_COUNT 0xFFC00F58 /*MemDMA2 Stream 0 Source Outer-Loop Count register */
-#define MDMA2_S0_X_MODIFY 0xFFC00F54 /*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */
-#define MDMA2_S0_Y_MODIFY 0xFFC00F5C /*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */
-#define MDMA2_S0_CURR_DESC_PTR 0xFFC00F60 /*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */
-#define MDMA2_S0_CURR_ADDR 0xFFC00F64 /*MemDMA2 Stream 0 Source Current Address */
-#define MDMA2_S0_CURR_X_COUNT 0xFFC00F70 /*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */
-#define MDMA2_S0_CURR_Y_COUNT 0xFFC00F78 /*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */
-#define MDMA2_S0_IRQ_STATUS 0xFFC00F68 /*MemDMA2 Stream 0 Source Interrupt/Status Register */
-#define MDMA2_S0_PERIPHERAL_MAP 0xFFC00F6C /*MemDMA2 Stream 0 Source Peripheral Map register */
-
-#define MDMA2_D1_CONFIG 0xFFC00F88 /*MemDMA2 Stream 1 Destination Configuration register */
-#define MDMA2_D1_NEXT_DESC_PTR 0xFFC00F80 /*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */
-#define MDMA2_D1_START_ADDR 0xFFC00F84 /*MemDMA2 Stream 1 Destination Start Address */
-#define MDMA2_D1_X_COUNT 0xFFC00F90 /*MemDMA2 Stream 1 Dest Inner-Loop Count register */
-#define MDMA2_D1_Y_COUNT 0xFFC00F98 /*MemDMA2 Stream 1 Dest Outer-Loop Count register */
-#define MDMA2_D1_X_MODIFY 0xFFC00F94 /*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */
-#define MDMA2_D1_Y_MODIFY 0xFFC00F9C /*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */
-#define MDMA2_D1_CURR_DESC_PTR 0xFFC00FA0 /*MemDMA2 Stream 1 Destination Current Descriptor Ptr */
-#define MDMA2_D1_CURR_ADDR 0xFFC00FA4 /*MemDMA2 Stream 1 Destination Current Address reg */
-#define MDMA2_D1_CURR_X_COUNT 0xFFC00FB0 /*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */
-#define MDMA2_D1_CURR_Y_COUNT 0xFFC00FB8 /*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */
-#define MDMA2_D1_IRQ_STATUS 0xFFC00FA8 /*MemDMA2 Stream 1 Destination Interrupt/Status Reg */
-#define MDMA2_D1_PERIPHERAL_MAP 0xFFC00FAC /*MemDMA2 Stream 1 Destination Peripheral Map register */
-
-#define MDMA2_S1_CONFIG 0xFFC00FC8 /*MemDMA2 Stream 1 Source Configuration register */
-#define MDMA2_S1_NEXT_DESC_PTR 0xFFC00FC0 /*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */
-#define MDMA2_S1_START_ADDR 0xFFC00FC4 /*MemDMA2 Stream 1 Source Start Address */
-#define MDMA2_S1_X_COUNT 0xFFC00FD0 /*MemDMA2 Stream 1 Source Inner-Loop Count register */
-#define MDMA2_S1_Y_COUNT 0xFFC00FD8 /*MemDMA2 Stream 1 Source Outer-Loop Count register */
-#define MDMA2_S1_X_MODIFY 0xFFC00FD4 /*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */
-#define MDMA2_S1_Y_MODIFY 0xFFC00FDC /*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */
-#define MDMA2_S1_CURR_DESC_PTR 0xFFC00FE0 /*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */
-#define MDMA2_S1_CURR_ADDR 0xFFC00FE4 /*MemDMA2 Stream 1 Source Current Address */
-#define MDMA2_S1_CURR_X_COUNT 0xFFC00FF0 /*MemDMA2 Stream 1 Source Current Inner-Loop Count */
-#define MDMA2_S1_CURR_Y_COUNT 0xFFC00FF8 /*MemDMA2 Stream 1 Source Current Outer-Loop Count */
-#define MDMA2_S1_IRQ_STATUS 0xFFC00FE8 /*MemDMA2 Stream 1 Source Interrupt/Status Register */
-#define MDMA2_S1_PERIPHERAL_MAP 0xFFC00FEC /*MemDMA2 Stream 1 Source Peripheral Map register */
-
-#define MDMA_D0_NEXT_DESC_PTR MDMA1_D0_NEXT_DESC_PTR
-#define MDMA_D0_START_ADDR MDMA1_D0_START_ADDR
-#define MDMA_D0_CONFIG MDMA1_D0_CONFIG
-#define MDMA_D0_X_COUNT MDMA1_D0_X_COUNT
-#define MDMA_D0_X_MODIFY MDMA1_D0_X_MODIFY
-#define MDMA_D0_Y_COUNT MDMA1_D0_Y_COUNT
-#define MDMA_D0_Y_MODIFY MDMA1_D0_Y_MODIFY
-#define MDMA_D0_CURR_DESC_PTR MDMA1_D0_CURR_DESC_PTR
-#define MDMA_D0_CURR_ADDR MDMA1_D0_CURR_ADDR
-#define MDMA_D0_IRQ_STATUS MDMA1_D0_IRQ_STATUS
-#define MDMA_D0_PERIPHERAL_MAP MDMA1_D0_PERIPHERAL_MAP
-#define MDMA_D0_CURR_X_COUNT MDMA1_D0_CURR_X_COUNT
-#define MDMA_D0_CURR_Y_COUNT MDMA1_D0_CURR_Y_COUNT
-
-#define MDMA_S0_NEXT_DESC_PTR MDMA1_S0_NEXT_DESC_PTR
-#define MDMA_S0_START_ADDR MDMA1_S0_START_ADDR
-#define MDMA_S0_CONFIG MDMA1_S0_CONFIG
-#define MDMA_S0_X_COUNT MDMA1_S0_X_COUNT
-#define MDMA_S0_X_MODIFY MDMA1_S0_X_MODIFY
-#define MDMA_S0_Y_COUNT MDMA1_S0_Y_COUNT
-#define MDMA_S0_Y_MODIFY MDMA1_S0_Y_MODIFY
-#define MDMA_S0_CURR_DESC_PTR MDMA1_S0_CURR_DESC_PTR
-#define MDMA_S0_CURR_ADDR MDMA1_S0_CURR_ADDR
-#define MDMA_S0_IRQ_STATUS MDMA1_S0_IRQ_STATUS
-#define MDMA_S0_PERIPHERAL_MAP MDMA1_S0_PERIPHERAL_MAP
-#define MDMA_S0_CURR_X_COUNT MDMA1_S0_CURR_X_COUNT
-#define MDMA_S0_CURR_Y_COUNT MDMA1_S0_CURR_Y_COUNT
-
-#define MDMA_D1_NEXT_DESC_PTR MDMA1_D1_NEXT_DESC_PTR
-#define MDMA_D1_START_ADDR MDMA1_D1_START_ADDR
-#define MDMA_D1_CONFIG MDMA1_D1_CONFIG
-#define MDMA_D1_X_COUNT MDMA1_D1_X_COUNT
-#define MDMA_D1_X_MODIFY MDMA1_D1_X_MODIFY
-#define MDMA_D1_Y_COUNT MDMA1_D1_Y_COUNT
-#define MDMA_D1_Y_MODIFY MDMA1_D1_Y_MODIFY
-#define MDMA_D1_CURR_DESC_PTR MDMA1_D1_CURR_DESC_PTR
-#define MDMA_D1_CURR_ADDR MDMA1_D1_CURR_ADDR
-#define MDMA_D1_IRQ_STATUS MDMA1_D1_IRQ_STATUS
-#define MDMA_D1_PERIPHERAL_MAP MDMA1_D1_PERIPHERAL_MAP
-#define MDMA_D1_CURR_X_COUNT MDMA1_D1_CURR_X_COUNT
-#define MDMA_D1_CURR_Y_COUNT MDMA1_D1_CURR_Y_COUNT
-
-#define MDMA_S1_NEXT_DESC_PTR MDMA1_S1_NEXT_DESC_PTR
-#define MDMA_S1_START_ADDR MDMA1_S1_START_ADDR
-#define MDMA_S1_CONFIG MDMA1_S1_CONFIG
-#define MDMA_S1_X_COUNT MDMA1_S1_X_COUNT
-#define MDMA_S1_X_MODIFY MDMA1_S1_X_MODIFY
-#define MDMA_S1_Y_COUNT MDMA1_S1_Y_COUNT
-#define MDMA_S1_Y_MODIFY MDMA1_S1_Y_MODIFY
-#define MDMA_S1_CURR_DESC_PTR MDMA1_S1_CURR_DESC_PTR
-#define MDMA_S1_CURR_ADDR MDMA1_S1_CURR_ADDR
-#define MDMA_S1_IRQ_STATUS MDMA1_S1_IRQ_STATUS
-#define MDMA_S1_PERIPHERAL_MAP MDMA1_S1_PERIPHERAL_MAP
-#define MDMA_S1_CURR_X_COUNT MDMA1_S1_CURR_X_COUNT
-#define MDMA_S1_CURR_Y_COUNT MDMA1_S1_CURR_Y_COUNT
+#define MDMA_D0_CONFIG 0xFFC00F08 /*MemDMA2 Stream 0 Destination Configuration register */
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA_D0_START_ADDR 0xFFC00F04 /*MemDMA2 Stream 0 Destination Start Address */
+#define MDMA_D0_X_COUNT 0xFFC00F10 /*MemDMA2 Stream 0 Dest Inner-Loop Count register */
+#define MDMA_D0_Y_COUNT 0xFFC00F18 /*MemDMA2 Stream 0 Dest Outer-Loop Count register */
+#define MDMA_D0_X_MODIFY 0xFFC00F14 /*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA_D0_Y_MODIFY 0xFFC00F1C /*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA_D0_CURR_ADDR 0xFFC00F24 /*MemDMA2 Stream 0 Destination Current Address */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */
+#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /*MemDMA2 Stream 0 Dest Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /*MemDMA2 Stream 0 Destination Peripheral Map register */
+
+#define MDMA_S0_CONFIG 0xFFC00F48 /*MemDMA2 Stream 0 Source Configuration register */
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA_S0_START_ADDR 0xFFC00F44 /*MemDMA2 Stream 0 Source Start Address */
+#define MDMA_S0_X_COUNT 0xFFC00F50 /*MemDMA2 Stream 0 Source Inner-Loop Count register */
+#define MDMA_S0_Y_COUNT 0xFFC00F58 /*MemDMA2 Stream 0 Source Outer-Loop Count register */
+#define MDMA_S0_X_MODIFY 0xFFC00F54 /*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */
+#define MDMA_S0_Y_MODIFY 0xFFC00F5C /*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA_S0_CURR_ADDR 0xFFC00F64 /*MemDMA2 Stream 0 Source Current Address */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */
+#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /*MemDMA2 Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /*MemDMA2 Stream 0 Source Peripheral Map register */
+
+#define MDMA_D1_CONFIG 0xFFC00F88 /*MemDMA2 Stream 1 Destination Configuration register */
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA_D1_START_ADDR 0xFFC00F84 /*MemDMA2 Stream 1 Destination Start Address */
+#define MDMA_D1_X_COUNT 0xFFC00F90 /*MemDMA2 Stream 1 Dest Inner-Loop Count register */
+#define MDMA_D1_Y_COUNT 0xFFC00F98 /*MemDMA2 Stream 1 Dest Outer-Loop Count register */
+#define MDMA_D1_X_MODIFY 0xFFC00F94 /*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA_D1_Y_MODIFY 0xFFC00F9C /*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /*MemDMA2 Stream 1 Destination Current Descriptor Ptr */
+#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /*MemDMA2 Stream 1 Destination Current Address reg */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */
+#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /*MemDMA2 Stream 1 Destination Interrupt/Status Reg */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /*MemDMA2 Stream 1 Destination Peripheral Map register */
+
+#define MDMA_S1_CONFIG 0xFFC00FC8 /*MemDMA2 Stream 1 Source Configuration register */
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA_S1_START_ADDR 0xFFC00FC4 /*MemDMA2 Stream 1 Source Start Address */
+#define MDMA_S1_X_COUNT 0xFFC00FD0 /*MemDMA2 Stream 1 Source Inner-Loop Count register */
+#define MDMA_S1_Y_COUNT 0xFFC00FD8 /*MemDMA2 Stream 1 Source Outer-Loop Count register */
+#define MDMA_S1_X_MODIFY 0xFFC00FD4 /*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */
+#define MDMA_S1_Y_MODIFY 0xFFC00FDC /*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /*MemDMA2 Stream 1 Source Current Address */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /*MemDMA2 Stream 1 Source Current Inner-Loop Count */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /*MemDMA2 Stream 1 Source Current Outer-Loop Count */
+#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /*MemDMA2 Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /*MemDMA2 Stream 1 Source Peripheral Map register */
/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */
#define IMDMA_D0_CONFIG 0xFFC01808 /*IMDMA Stream 0 Destination Configuration */
@@ -927,83 +864,6 @@
#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */
#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */
-/* ***************************** UART CONTROLLER MASKS ********************** */
-
-/* UART_LCR Register */
-
-#define DLAB 0x80
-#define SB 0x40
-#define STP 0x20
-#define EPS 0x10
-#define PEN 0x08
-#define STB 0x04
-#define WLS(x) ((x-5) & 0x03)
-
-#define DLAB_P 0x07
-#define SB_P 0x06
-#define STP_P 0x05
-#define EPS_P 0x04
-#define PEN_P 0x03
-#define STB_P 0x02
-#define WLS_P1 0x01
-#define WLS_P0 0x00
-
-/* UART_MCR Register */
-#define LOOP_ENA 0x10
-#define LOOP_ENA_P 0x04
-
-/* UART_LSR Register */
-#define TEMT 0x40
-#define THRE 0x20
-#define BI 0x10
-#define FE 0x08
-#define PE 0x04
-#define OE 0x02
-#define DR 0x01
-
-#define TEMP_P 0x06
-#define THRE_P 0x05
-#define BI_P 0x04
-#define FE_P 0x03
-#define PE_P 0x02
-#define OE_P 0x01
-#define DR_P 0x00
-
-/* UART_IER Register */
-#define ELSI 0x04
-#define ETBEI 0x02
-#define ERBFI 0x01
-
-#define ELSI_P 0x02
-#define ETBEI_P 0x01
-#define ERBFI_P 0x00
-
-/* UART_IIR Register */
-#define STATUS(x) ((x << 1) & 0x06)
-#define NINT 0x01
-#define STATUS_P1 0x02
-#define STATUS_P0 0x01
-#define NINT_P 0x00
-#define IIR_TX_READY 0x02 /* UART_THR empty */
-#define IIR_RX_READY 0x04 /* Receive data ready */
-#define IIR_LINE_CHANGE 0x06 /* Receive line status */
-#define IIR_STATUS 0x06
-
-/* UART_GCTL Register */
-#define FFE 0x20
-#define FPE 0x10
-#define RPOLC 0x08
-#define TPOLC 0x04
-#define IREN 0x02
-#define UCEN 0x01
-
-#define FFE_P 0x05
-#define FPE_P 0x04
-#define RPOLC_P 0x03
-#define TPOLC_P 0x02
-#define IREN_P 0x01
-#define UCEN_P 0x00
-
/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
/* PPI_CONTROL Masks */
@@ -1230,44 +1090,6 @@
#define ERR_TYP_P0 0x0E
#define ERR_TYP_P1 0x0F
-/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */
-
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
-#define PF0 0x0001
-#define PF1 0x0002
-#define PF2 0x0004
-#define PF3 0x0008
-#define PF4 0x0010
-#define PF5 0x0020
-#define PF6 0x0040
-#define PF7 0x0080
-#define PF8 0x0100
-#define PF9 0x0200
-#define PF10 0x0400
-#define PF11 0x0800
-#define PF12 0x1000
-#define PF13 0x2000
-#define PF14 0x4000
-#define PF15 0x8000
-
-/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */
-#define PF0_P 0
-#define PF1_P 1
-#define PF2_P 2
-#define PF3_P 3
-#define PF4_P 4
-#define PF5_P 5
-#define PF6_P 6
-#define PF7_P 7
-#define PF8_P 8
-#define PF9_P 9
-#define PF10_P 10
-#define PF11_P 11
-#define PF12_P 12
-#define PF13_P 13
-#define PF14_P 14
-#define PF15_P 15
-
/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
/* AMGCTL Masks */
diff --git a/arch/blackfin/mach-bf561/include/mach/gpio.h b/arch/blackfin/mach-bf561/include/mach/gpio.h
index 4f8aa5d08802..57d5eab59faf 100644
--- a/arch/blackfin/mach-bf561/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf561/include/mach/gpio.h
@@ -62,4 +62,6 @@
#define PORT_FIO1 GPIO_16
#define PORT_FIO2 GPIO_32
+#include <mach-common/ports-f.h>
+
#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index f540ed1257d6..be6083a7e42f 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -86,12 +86,12 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
spin_lock(&boot_lock);
- if ((bfin_read_SIC_SYSCR() & COREB_SRAM_INIT) == 0) {
+ if ((bfin_read_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_SIC_SYSCR(bfin_read_SIC_SYSCR() & ~COREB_SRAM_INIT);
+ bfin_write_SYSCR(bfin_read_SYSCR() & ~COREB_SRAM_INIT);
SSYNC();
}
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index cc8335eb3110..e5a6c3530c6c 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size)
extern void iounmap (volatile void __iomem *addr);
extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
+static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
+{
+ return ioremap(phys_addr, size);
+}
+
/*
* String version of IO memory access ops:
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 2f229e5de498..2689ee54a1c9 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -590,6 +590,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
void kvm_sal_emul(struct kvm_vcpu *vcpu);
+#define __KVM_HAVE_ARCH_VM_ALLOC 1
+struct kvm *kvm_arch_alloc_vm(void);
+void kvm_arch_free_vm(struct kvm *kvm);
+
#endif /* __ASSEMBLY__*/
#endif
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 9a26015c3e50..38c07b866901 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -633,7 +633,7 @@ ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL));
desc = irq_desc + irq;
desc->status |= IRQ_PER_CPU;
- desc->chip = &irq_type_ia64_lsapic;
+ set_irq_chip(irq, &irq_type_ia64_lsapic);
if (action)
setup_irq(irq, action);
set_irq_handler(irq, handle_percpu_irq);
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 39e534f5a3b0..d92d5b5161fc 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -829,10 +829,9 @@ pfm_rvmalloc(unsigned long size)
unsigned long addr;
size = PAGE_ALIGN(size);
- mem = vmalloc(size);
+ mem = vzalloc(size);
if (mem) {
//printk("perfmon: CPU%d pfm_rvmalloc(%ld)=%p\n", smp_processor_id(), size, mem);
- memset(mem, 0, size);
addr = (unsigned long)mem;
while (size > 0) {
pfm_reserve_page(addr);
@@ -1542,7 +1541,7 @@ pfm_exit_smpl_buffer(pfm_buffer_fmt_t *fmt)
* any operations on the root directory. However, we need a non-trivial
* d_name - pfm: will go nicely and kill the special-casing in procfs.
*/
-static struct vfsmount *pfmfs_mnt;
+static struct vfsmount *pfmfs_mnt __read_mostly;
static int __init
init_pfm_fs(void)
@@ -2185,7 +2184,7 @@ static const struct file_operations pfm_file_ops = {
};
static int
-pfmfs_delete_dentry(struct dentry *dentry)
+pfmfs_delete_dentry(const struct dentry *dentry)
{
return 1;
}
@@ -2233,7 +2232,7 @@ pfm_alloc_file(pfm_context_t *ctx)
}
path.mnt = mntget(pfmfs_mnt);
- path.dentry->d_op = &pfmfs_dentry_operations;
+ d_set_d_op(path.dentry, &pfmfs_dentry_operations);
d_add(path.dentry, inode);
file = alloc_file(&path, FMODE_READ, &pfm_file_ops);
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index dabeefe21134..be450a3e9871 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -293,6 +293,7 @@ smp_flush_tlb_all (void)
void
smp_flush_tlb_mm (struct mm_struct *mm)
{
+ cpumask_var_t cpus;
preempt_disable();
/* this happens for the common case of a single-threaded fork(): */
if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
@@ -301,9 +302,15 @@ smp_flush_tlb_mm (struct mm_struct *mm)
preempt_enable();
return;
}
-
- smp_call_function_many(mm_cpumask(mm),
- (void (*)(void *))local_finish_flush_tlb_mm, mm, 1);
+ if (!alloc_cpumask_var(&cpus, GFP_ATOMIC)) {
+ smp_call_function((void (*)(void *))local_finish_flush_tlb_mm,
+ mm, 1);
+ } else {
+ cpumask_copy(cpus, mm_cpumask(mm));
+ smp_call_function_many(cpus,
+ (void (*)(void *))local_finish_flush_tlb_mm, mm, 1);
+ free_cpumask_var(cpus);
+ }
local_irq_disable();
local_finish_flush_tlb_mm(mm);
local_irq_enable();
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index ed6f22eb5b12..9702fa92489e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -168,7 +168,7 @@ timer_interrupt (int irq, void *dev_id)
{
unsigned long new_itm;
- if (unlikely(cpu_is_offline(smp_processor_id()))) {
+ if (cpu_is_offline(smp_processor_id())) {
return IRQ_HANDLED;
}
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index f56a6316e134..70d224d4264c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -749,7 +749,7 @@ out:
return r;
}
-static struct kvm *kvm_alloc_kvm(void)
+struct kvm *kvm_arch_alloc_vm(void)
{
struct kvm *kvm;
@@ -760,7 +760,7 @@ static struct kvm *kvm_alloc_kvm(void)
vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE));
if (!vm_base)
- return ERR_PTR(-ENOMEM);
+ return NULL;
memset((void *)vm_base, 0, KVM_VM_DATA_SIZE);
kvm = (struct kvm *)(vm_base +
@@ -806,10 +806,12 @@ static void kvm_build_io_pmt(struct kvm *kvm)
#define GUEST_PHYSICAL_RR4 0x2739
#define VMM_INIT_RR 0x1660
-static void kvm_init_vm(struct kvm *kvm)
+int kvm_arch_init_vm(struct kvm *kvm)
{
BUG_ON(!kvm);
+ kvm->arch.is_sn2 = ia64_platform_is("sn2");
+
kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0;
kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4;
kvm->arch.vmm_init_rr = VMM_INIT_RR;
@@ -823,21 +825,8 @@ static void kvm_init_vm(struct kvm *kvm)
/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
-}
-
-struct kvm *kvm_arch_create_vm(void)
-{
- struct kvm *kvm = kvm_alloc_kvm();
-
- if (IS_ERR(kvm))
- return ERR_PTR(-ENOMEM);
-
- kvm->arch.is_sn2 = ia64_platform_is("sn2");
-
- kvm_init_vm(kvm);
-
- return kvm;
+ return 0;
}
static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm,
@@ -962,7 +951,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
r = kvm_setup_default_irq_routing(kvm);
if (r) {
+ mutex_lock(&kvm->slots_lock);
kvm_ioapic_destroy(kvm);
+ mutex_unlock(&kvm->slots_lock);
goto out;
}
break;
@@ -1357,7 +1348,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
return -EINVAL;
}
-static void free_kvm(struct kvm *kvm)
+void kvm_arch_free_vm(struct kvm *kvm)
{
unsigned long vm_base = kvm->arch.vm_base;
@@ -1399,9 +1390,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
#endif
kfree(kvm->arch.vioapic);
kvm_release_vm_pages(kvm);
- kvm_free_physmem(kvm);
- cleanup_srcu_struct(&kvm->srcu);
- free_kvm(kvm);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h
index 7085bd51668b..cb88aa96c4f1 100644
--- a/arch/m68k/include/asm/cacheflush_no.h
+++ b/arch/m68k/include/asm/cacheflush_no.h
@@ -2,21 +2,22 @@
#define _M68KNOMMU_CACHEFLUSH_H
/*
- * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2000-2010, Greg Ungerer <gerg@snapgear.com>
*/
#include <linux/mm.h>
+#include <asm/mcfsim.h>
#define flush_cache_all() __flush_cache_all()
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) __flush_cache_all()
+#define flush_cache_range(vma, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr) do { } while (0)
-#define flush_dcache_range(start,len) __flush_cache_all()
+#define flush_dcache_range(start, len) __flush_dcache_all()
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
#define flush_dcache_page(page) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-#define flush_icache_range(start,len) __flush_cache_all()
+#define flush_icache_range(start, len) __flush_icache_all()
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
@@ -27,66 +28,52 @@
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
+void mcf_cache_push(void);
+
static inline void __flush_cache_all(void)
{
-#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
- /*
- * Use cpushl to push and invalidate all cache lines.
- * Gas doesn't seem to know how to generate the ColdFire
- * cpushl instruction... Oh well, bit stuff it for now.
- */
- __asm__ __volatile__ (
- "nop\n\t"
- "clrl %%d0\n\t"
- "1:\n\t"
- "movel %%d0,%%a0\n\t"
- "2:\n\t"
- ".word 0xf468\n\t"
- "addl #0x10,%%a0\n\t"
- "cmpl #0x00000800,%%a0\n\t"
- "blt 2b\n\t"
- "addql #1,%%d0\n\t"
- "cmpil #4,%%d0\n\t"
- "bne 1b\n\t"
- "movel #0xb6088500,%%d0\n\t"
- "movec %%d0,%%CACR\n\t"
- : : : "d0", "a0" );
-#endif /* CONFIG_M5407 */
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
- __asm__ __volatile__ (
- "movel #0x81400100, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
- "nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M523x || CONFIG_M527x */
-#if defined(CONFIG_M528x)
- __asm__ __volatile__ (
- "movel #0x81000200, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
- "nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M528x */
-#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272)
+#ifdef CACHE_PUSH
+ mcf_cache_push();
+#endif
+#ifdef CACHE_INVALIDATE
__asm__ __volatile__ (
- "movel #0x81000100, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
-#ifdef CONFIG_M5249
+ : : "i" (CACHE_INVALIDATE) : "d0" );
+#endif
+}
+
+/*
+ * Some ColdFire parts implement separate instruction and data caches,
+ * on those we should just flush the appropriate cache. If we don't need
+ * to do any specific flushing then this will be optimized away.
+ */
+static inline void __flush_icache_all(void)
+{
+#ifdef CACHE_INVALIDATEI
__asm__ __volatile__ (
- "movel #0xa1000200, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M5249 */
-#ifdef CONFIG_M532x
+ : : "i" (CACHE_INVALIDATEI) : "d0" );
+#endif
+}
+
+static inline void __flush_dcache_all(void)
+{
+#ifdef CACHE_PUSH
+ mcf_cache_push();
+#endif
+#ifdef CACHE_INVALIDATED
__asm__ __volatile__ (
- "movel #0x81000200, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M532x */
+ : : "i" (CACHE_INVALIDATED) : "d0" );
+#else
+ /* Flush the wrtite buffer */
+ __asm__ __volatile__ ( "nop" );
+#endif
}
-
#endif /* _M68KNOMMU_CACHEFLUSH_H */
diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h
index 3b0a34d0fe33..213028cbe110 100644
--- a/arch/m68k/include/asm/coldfire.h
+++ b/arch/m68k/include/asm/coldfire.h
@@ -32,7 +32,7 @@
*/
#define MCF_MBAR 0x10000000
#define MCF_MBAR2 0x80000000
-#if defined(CONFIG_M548x)
+#if defined(CONFIG_M54xx)
#define MCF_IPSBAR MCF_MBAR
#elif defined(CONFIG_M520x)
#define MCF_IPSBAR 0xFC000000
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
index 26be277394f9..627d69bacc58 100644
--- a/arch/m68k/include/asm/entry_no.h
+++ b/arch/m68k/include/asm/entry_no.h
@@ -42,12 +42,16 @@
*/
#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
/*
- * This is made a little more tricky on the ColdFire. There is no
- * separate kernel and user stack pointers. Need to artificially
+ * This is made a little more tricky on older ColdFires. There is no
+ * separate supervisor and user stack pointers. Need to artificially
* construct a usp in software... When doing this we need to disable
- * interrupts, otherwise bad things could happen.
+ * interrupts, otherwise bad things will happen.
*/
+.globl sw_usp
+.globl sw_ksp
+
.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
btst #5,%sp@(2) /* from user? */
@@ -74,9 +78,7 @@
7:
.endm
-.macro RESTORE_ALL
- btst #5,%sp@(PT_SR) /* going user? */
- bnes 8f /* no, skip */
+.macro RESTORE_USER
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
@@ -91,19 +93,22 @@
subql #8,sw_usp /* set exception */
movel sw_usp,%sp /* restore usp */
rte
- 8:
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stkadj */
- rte
.endm
+.macro RDUSP
+ movel sw_usp,%a2
+.endm
+
+.macro WRUSP
+ movel %a0,sw_usp
+.endm
+
+#else /* !CONFIG_COLDFIRE_SW_A7 */
/*
- * Quick exception save, use current stack only.
+ * Modern ColdFire parts have separate supervisor and user stack
+ * pointers. Simple load and restore macros for this case.
*/
-.macro SAVE_LOCAL
+.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
@@ -112,7 +117,7 @@
moveml %d1-%d5/%a0-%a2,%sp@
.endm
-.macro RESTORE_LOCAL
+.macro RESTORE_USER
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
@@ -121,6 +126,18 @@
rte
.endm
+.macro RDUSP
+ /*move %usp,%a2*/
+ .word 0x4e6a
+.endm
+
+.macro WRUSP
+ /*move %a0,%usp*/
+ .word 0x4e60
+.endm
+
+#endif /* !CONFIG_COLDFIRE_SW_A7 */
+
.macro SAVE_SWITCH_STACK
lea %sp@(-24),%sp /* 6 regs */
moveml %a3-%a6/%d6-%d7,%sp@
@@ -131,14 +148,6 @@
lea %sp@(24),%sp /* 6 regs */
.endm
-/*
- * Software copy of the user and kernel stack pointers... Ugh...
- * Need these to get around ColdFire not having separate kernel
- * and user stack pointers.
- */
-.globl sw_usp
-.globl sw_ksp
-
#else /* !CONFIG_COLDFIRE */
/*
@@ -167,6 +176,6 @@
moveml %sp@+,%a3-%a6/%d6-%d7
.endm
-#endif /* !CONFIG_COLDFIRE */
+#endif /* !COLDFIRE_SW_A7 */
#endif /* __ASSEMBLY__ */
#endif /* __M68KNOMMU_ENTRY_H */
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
index 1b57adbafad5..c64c7b74cf86 100644
--- a/arch/m68k/include/asm/gpio.h
+++ b/arch/m68k/include/asm/gpio.h
@@ -37,7 +37,7 @@
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M532x) || defined(CONFIG_M548x)
+ defined(CONFIG_M532x) || defined(CONFIG_M54xx)
/* These parts have GPIO organized by 8 bit ports */
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 6e2413e518cb..cf20f3097af6 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -145,7 +145,6 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
#define IOMAP_WRITETHROUGH 3
extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
-extern void __iounmap(void *addr, unsigned long size);
static inline void *ioremap(unsigned long physaddr, unsigned long size)
{
diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h
index 9c384e294af9..561b03b5ddf8 100644
--- a/arch/m68k/include/asm/m5206sim.h
+++ b/arch/m68k/include/asm/m5206sim.h
@@ -12,6 +12,10 @@
#define m5206sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5206)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5206 SIM register set addresses.
@@ -88,6 +92,14 @@
#define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */
+#if defined(CONFIG_NETtel)
+#define MCFUART_BASE1 0x180 /* Base address of UART1 */
+#define MCFUART_BASE2 0x140 /* Base address of UART2 */
+#else
+#define MCFUART_BASE1 0x140 /* Base address of UART1 */
+#define MCFUART_BASE2 0x180 /* Base address of UART2 */
+#endif
+
/*
* Define system peripheral IRQ usage.
*/
@@ -95,7 +107,7 @@
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
- * Generic GPIO
+ * Generic GPIO
*/
#define MCFGPIO_PIN_MAX 8
#define MCFGPIO_IRQ_VECBASE -1
diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h
index db824a4b136e..88ed8239fe4e 100644
--- a/arch/m68k/include/asm/m520xsim.h
+++ b/arch/m68k/include/asm/m520xsim.h
@@ -11,6 +11,11 @@
#define m520xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m520x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 520x SIM register set addresses.
*/
@@ -54,6 +59,9 @@
#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */
#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */
+/*
+ * EPORT and GPIO registers.
+ */
#define MCFEPORT_EPDDR 0xFC088002
#define MCFEPORT_EPDR 0xFC088004
#define MCFEPORT_EPPDR 0xFC088005
@@ -97,6 +105,7 @@
#define MCFGPIO_PCLRR_UART 0xFC0A402A
#define MCFGPIO_PCLRR_FECH 0xFC0A402B
#define MCFGPIO_PCLRR_FECL 0xFC0A402C
+
/*
* Generic GPIO support
*/
@@ -109,7 +118,6 @@
#define MCFGPIO_PIN_MAX 80
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
-/****************************************************************************/
#define MCF_GPIO_PAR_UART (0xA4036)
#define MCF_GPIO_PAR_FECI2C (0xA4033)
@@ -126,6 +134,13 @@
#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04)
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x60000 /* Base address of UART1 */
+#define MCFUART_BASE2 0x64000 /* Base address of UART2 */
+#define MCFUART_BASE3 0x68000 /* Base address of UART2 */
+
+/*
* Reset Controll Unit.
*/
#define MCF_RCR 0xFC0A0000
diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h
index e8d06b24a48e..4ad7a00257a8 100644
--- a/arch/m68k/include/asm/m523xsim.h
+++ b/arch/m68k/include/asm/m523xsim.h
@@ -11,6 +11,10 @@
#define m523xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m523x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 523x SIM register set addresses.
@@ -50,6 +54,13 @@
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
+
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002)
diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h
index 79b7b402f3c9..4908b118f2fd 100644
--- a/arch/m68k/include/asm/m5249sim.h
+++ b/arch/m68k/include/asm/m5249sim.h
@@ -11,6 +11,11 @@
#define m5249sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5249)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 5249 SIM register set addresses.
*/
@@ -56,6 +61,11 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
/*
* Some symbol defines for the above...
diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h
index df3332c2317d..b7cc50abc831 100644
--- a/arch/m68k/include/asm/m5272sim.h
+++ b/arch/m68k/include/asm/m5272sim.h
@@ -12,6 +12,11 @@
#define m5272sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5272)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 5272 SIM register set addresses.
*/
@@ -62,6 +67,9 @@
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
+#define MCFUART_BASE1 0x100 /* Base address of UART1 */
+#define MCFUART_BASE2 0x140 /* Base address of UART2 */
+
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */
diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h
index 1feb46f108ce..e8042e8bc003 100644
--- a/arch/m68k/include/asm/m527xsim.h
+++ b/arch/m68k/include/asm/m527xsim.h
@@ -11,6 +11,10 @@
#define m527xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m527x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5270/5271 SIM register set addresses.
@@ -55,6 +59,12 @@
#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */
#endif
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
#ifdef CONFIG_M5271
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h
index 891cbedad972..a6d2f4d9aaa0 100644
--- a/arch/m68k/include/asm/m528xsim.h
+++ b/arch/m68k/include/asm/m528xsim.h
@@ -11,6 +11,10 @@
#define m528xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m528x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5280/5282 SIM register set addresses.
@@ -42,6 +46,13 @@
#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
+
+/*
* GPIO registers
*/
#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000)
diff --git a/arch/m68k/include/asm/m52xxacr.h b/arch/m68k/include/asm/m52xxacr.h
new file mode 100644
index 000000000000..abc391a9ae8d
--- /dev/null
+++ b/arch/m68k/include/asm/m52xxacr.h
@@ -0,0 +1,94 @@
+/****************************************************************************/
+
+/*
+ * m52xxacr.h -- ColdFire version 2 core cache support
+ *
+ * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef m52xxacr_h
+#define m52xxacr_h
+/****************************************************************************/
+
+/*
+ * All varients of the ColdFire using version 2 cores have a similar
+ * cache setup. Although not absolutely identical the cache register
+ * definitions are compatible for all of them. Mostly they support a
+ * configurable cache memory that can be instruction only, data only,
+ * or split instruction and data. The exception is the very old version 2
+ * core based parts, like the 5206(e), 5249 and 5272, which are instruction
+ * cache only. Cache size varies from 2k up to 16k.
+ */
+
+/*
+ * Define the Cache Control register flags.
+ */
+#define CACR_CENB 0x80000000 /* Enable cache */
+#define CACR_CDPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_CFRZ 0x08000000 /* Cache freeze mode */
+#define CACR_CINV 0x01000000 /* Invalidate cache */
+#define CACR_DISI 0x00800000 /* Disable instruction cache */
+#define CACR_DISD 0x00400000 /* Disable data cache */
+#define CACR_INVI 0x00200000 /* Invalidate instruction cache */
+#define CACR_INVD 0x00100000 /* Invalidate data cache */
+#define CACR_CEIB 0x00000400 /* Non-cachable instruction burst */
+#define CACR_DCM 0x00000200 /* Default cache mode */
+#define CACR_DBWE 0x00000100 /* Buffered write enable */
+#define CACR_DWP 0x00000020 /* Write protection */
+#define CACR_EUSP 0x00000010 /* Enable separate user a7 */
+
+/*
+ * Define the Access Control register flags.
+ */
+#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */
+#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */
+#define ACR_ENABLE 0x00008000 /* Enable this ACR */
+#define ACR_USER 0x00000000 /* Allow only user accesses */
+#define ACR_SUPER 0x00002000 /* Allow supervisor access only */
+#define ACR_ANY 0x00004000 /* Allow any access type */
+#define ACR_CENB 0x00000000 /* Caching of region enabled */
+#define ACR_CDIS 0x00000040 /* Caching of region disabled */
+#define ACR_BWE 0x00000020 /* Write buffer enabled */
+#define ACR_WPROTECT 0x00000004 /* Write protect region */
+
+/*
+ * Set the cache controller settings we will use. On the cores that support
+ * a split cache configuration we allow all the combinations at Kconfig
+ * time. For those cores that only have an instruction cache we just set
+ * that as on.
+ */
+#if defined(CONFIG_CACHE_I)
+#define CACHE_TYPE (CACR_DISD + CACR_EUSP)
+#define CACHE_INVTYPEI 0
+#elif defined(CONFIG_CACHE_D)
+#define CACHE_TYPE (CACR_DISI + CACR_EUSP)
+#define CACHE_INVTYPED 0
+#elif defined(CONFIG_CACHE_BOTH)
+#define CACHE_TYPE CACR_EUSP
+#define CACHE_INVTYPEI CACR_INVI
+#define CACHE_INVTYPED CACR_INVD
+#else
+/* This is the instruction cache only devices (no split cache, no eusp) */
+#define CACHE_TYPE 0
+#define CACHE_INVTYPEI 0
+#endif
+
+#define CACHE_INIT (CACR_CINV + CACHE_TYPE)
+#define CACHE_MODE (CACR_CENB + CACHE_TYPE + CACR_DCM)
+
+#define CACHE_INVALIDATE (CACHE_MODE + CACR_CINV)
+#if defined(CACHE_INVTYPEI)
+#define CACHE_INVALIDATEI (CACHE_MODE + CACR_CINV + CACHE_INVTYPEI)
+#endif
+#if defined(CACHE_INVTYPED)
+#define CACHE_INVALIDATED (CACHE_MODE + CACR_CINV + CACHE_INVTYPED)
+#endif
+
+#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \
+ (0x000f0000) + \
+ (ACR_ENABLE + ACR_ANY + ACR_CENB + ACR_BWE))
+#define ACR1_MODE 0
+
+/****************************************************************************/
+#endif /* m52xxsim_h */
diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h
index c6830e5b54ce..0bf57397e7a9 100644
--- a/arch/m68k/include/asm/m5307sim.h
+++ b/arch/m68k/include/asm/m5307sim.h
@@ -14,6 +14,11 @@
#define m5307sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5307)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m53xxacr.h>
+
/*
* Define the 5307 SIM register set addresses.
*/
@@ -94,6 +99,17 @@
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
/*
+ * UART module.
+ */
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
+#else
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
+#endif
+
+/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 16
@@ -146,32 +162,5 @@
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
-/*
- * Define the Cache register flags.
- */
-#define CACR_EC (1<<31)
-#define CACR_ESB (1<<29)
-#define CACR_DPI (1<<28)
-#define CACR_HLCK (1<<27)
-#define CACR_CINVA (1<<24)
-#define CACR_DNFB (1<<10)
-#define CACR_DCM_WTHRU (0<<8)
-#define CACR_DCM_WBACK (1<<8)
-#define CACR_DCM_OFF_PRE (2<<8)
-#define CACR_DCM_OFF_IMP (3<<8)
-#define CACR_DW (1<<5)
-
-#define ACR_BASE_POS 24
-#define ACR_MASK_POS 16
-#define ACR_ENABLE (1<<15)
-#define ACR_USER (0<<13)
-#define ACR_SUPER (1<<13)
-#define ACR_ANY (2<<13)
-#define ACR_CM_WTHRU (0<<5)
-#define ACR_CM_WBACK (1<<5)
-#define ACR_CM_OFF_PRE (2<<5)
-#define ACR_CM_OFF_IMP (3<<5)
-#define ACR_WPROTECT (1<<2)
-
/****************************************************************************/
#endif /* m5307sim_h */
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index c4bf1c81e3cf..e6470f8ca324 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -9,6 +9,11 @@
#define m532xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m532x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m53xxacr.h>
+
#define MCF_REG32(x) (*(volatile unsigned long *)(x))
#define MCF_REG16(x) (*(volatile unsigned short *)(x))
#define MCF_REG08(x) (*(volatile unsigned char *)(x))
@@ -74,31 +79,11 @@
#define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */
/*
- * Define the Cache register flags.
+ * UART module.
*/
-#define CACR_EC (1<<31)
-#define CACR_ESB (1<<29)
-#define CACR_DPI (1<<28)
-#define CACR_HLCK (1<<27)
-#define CACR_CINVA (1<<24)
-#define CACR_DNFB (1<<10)
-#define CACR_DCM_WTHRU (0<<8)
-#define CACR_DCM_WBACK (1<<8)
-#define CACR_DCM_OFF_PRE (2<<8)
-#define CACR_DCM_OFF_IMP (3<<8)
-#define CACR_DW (1<<5)
-
-#define ACR_BASE_POS 24
-#define ACR_MASK_POS 16
-#define ACR_ENABLE (1<<15)
-#define ACR_USER (0<<13)
-#define ACR_SUPER (1<<13)
-#define ACR_ANY (2<<13)
-#define ACR_CM_WTHRU (0<<5)
-#define ACR_CM_WBACK (1<<5)
-#define ACR_CM_OFF_PRE (2<<5)
-#define ACR_CM_OFF_IMP (3<<5)
-#define ACR_WPROTECT (1<<2)
+#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
+#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
+#define MCFUART_BASE3 0xFC068000 /* Base address of UART3 */
/*********************************************************************
*
diff --git a/arch/m68k/include/asm/m53xxacr.h b/arch/m68k/include/asm/m53xxacr.h
new file mode 100644
index 000000000000..cd952b0a8bd3
--- /dev/null
+++ b/arch/m68k/include/asm/m53xxacr.h
@@ -0,0 +1,101 @@
+/****************************************************************************/
+
+/*
+ * m53xxacr.h -- ColdFire version 3 core cache support
+ *
+ * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef m53xxacr_h
+#define m53xxacr_h
+/****************************************************************************/
+
+/*
+ * All varients of the ColdFire using version 3 cores have a similar
+ * cache setup. They have a unified instruction and data cache, with
+ * configurable write-through or copy-back operation.
+ */
+
+/*
+ * Define the Cache Control register flags.
+ */
+#define CACR_EC 0x80000000 /* Enable cache */
+#define CACR_ESB 0x20000000 /* Enable store buffer */
+#define CACR_DPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_HLCK 0x08000000 /* Half cache lock mode */
+#define CACR_CINVA 0x01000000 /* Invalidate cache */
+#define CACR_DNFB 0x00000400 /* Inhibited fill buffer */
+#define CACR_DCM_WT 0x00000000 /* Cacheable write-through */
+#define CACR_DCM_CB 0x00000100 /* Cacheable copy-back */
+#define CACR_DCM_PRE 0x00000200 /* Cache inhibited, precise */
+#define CACR_DCM_IMPRE 0x00000300 /* Cache inhibited, imprecise */
+#define CACR_WPROTECT 0x00000020 /* Write protect*/
+#define CACR_EUSP 0x00000010 /* Eanble separate user a7 */
+
+/*
+ * Define the Access Control register flags.
+ */
+#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */
+#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */
+#define ACR_ENABLE 0x00008000 /* Enable this ACR */
+#define ACR_USER 0x00000000 /* Allow only user accesses */
+#define ACR_SUPER 0x00002000 /* Allow supervisor access only */
+#define ACR_ANY 0x00004000 /* Allow any access type */
+#define ACR_CM_WT 0x00000000 /* Cacheable, write-through */
+#define ACR_CM_CB 0x00000020 /* Cacheable, copy-back */
+#define ACR_CM_PRE 0x00000040 /* Cache inhibited, precise */
+#define ACR_CM_IMPRE 0x00000060 /* Cache inhibited, imprecise */
+#define ACR_WPROTECT 0x00000004 /* Write protect region */
+
+/*
+ * Define the cache type and arrangement (needed for pushes).
+ */
+#if defined(CONFIG_M5307)
+#define CACHE_SIZE 0x2000 /* 8k of unified cache */
+#define ICACHE_SIZE CACHE_SIZE
+#define DCACHE_SIZE CACHE_SIZE
+#elif defined(CONFIG_M532x)
+#define CACHE_SIZE 0x4000 /* 32k of unified cache */
+#define ICACHE_SIZE CACHE_SIZE
+#define DCACHE_SIZE CACHE_SIZE
+#endif
+
+#define CACHE_LINE_SIZE 16 /* 16 byte line size */
+#define CACHE_WAYS 4 /* 4 ways - set associative */
+
+/*
+ * Set the cache controller settings we will use. This default in the
+ * CACR is cache inhibited, we use the ACR register to set cacheing
+ * enabled on the regions we want (eg RAM).
+ */
+#if defined(CONFIG_CACHE_COPYBACK)
+#define CACHE_TYPE ACR_CM_CB
+#define CACHE_PUSH
+#else
+#define CACHE_TYPE ACR_CM_WT
+#endif
+
+#ifdef CONFIG_COLDFIRE_SW_A7
+#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE)
+#else
+#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE + CACR_EUSP)
+#endif
+
+/*
+ * Unified cache means we will never need to flush for coherency of
+ * instruction fetch. We will need to flush to maintain memory/DMA
+ * coherency though in all cases. And for copyback caches we will need
+ * to push cached data as well.
+ */
+#define CACHE_INIT CACR_CINVA
+#define CACHE_INVALIDATE CACR_CINVA
+#define CACHE_INVALIDATED CACR_CINVA
+
+#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \
+ (0x000f0000) + \
+ (ACR_ENABLE + ACR_ANY + CACHE_TYPE))
+#define ACR1_MODE 0
+
+/****************************************************************************/
+#endif /* m53xxsim_h */
diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h
index c399abbf953c..75f5c28a551d 100644
--- a/arch/m68k/include/asm/m5407sim.h
+++ b/arch/m68k/include/asm/m5407sim.h
@@ -14,6 +14,11 @@
#define m5407sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5407)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m54xxacr.h>
+
/*
* Define the 5407 SIM register set addresses.
*/
@@ -73,6 +78,9 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
+
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
@@ -117,39 +125,5 @@
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
-/*
- * Define the Cache register flags.
- */
-#define CACR_DEC 0x80000000 /* Enable data cache */
-#define CACR_DWP 0x40000000 /* Data write protection */
-#define CACR_DESB 0x20000000 /* Enable data store buffer */
-#define CACR_DDPI 0x10000000 /* Disable CPUSHL */
-#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */
-#define CACR_DDCM_WT 0x00000000 /* Write through cache*/
-#define CACR_DDCM_CP 0x02000000 /* Copyback cache */
-#define CACR_DDCM_P 0x04000000 /* No cache, precise */
-#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */
-#define CACR_DCINVA 0x01000000 /* Invalidate data cache */
-#define CACR_BEC 0x00080000 /* Enable branch cache */
-#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */
-#define CACR_IEC 0x00008000 /* Enable instruction cache */
-#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */
-#define CACR_IDPI 0x00001000 /* Disable CPUSHL */
-#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */
-#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */
-#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */
-
-#define ACR_BASE_POS 24 /* Address Base */
-#define ACR_MASK_POS 16 /* Address Mask */
-#define ACR_ENABLE 0x00008000 /* Enable address */
-#define ACR_USER 0x00000000 /* User mode access only */
-#define ACR_SUPER 0x00002000 /* Supervisor mode only */
-#define ACR_ANY 0x00004000 /* Match any access mode */
-#define ACR_CM_WT 0x00000000 /* Write through mode */
-#define ACR_CM_CP 0x00000020 /* Copyback mode */
-#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */
-#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */
-#define ACR_WPROTECT 0x00000004 /* Write protect */
-
/****************************************************************************/
#endif /* m5407sim_h */
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
new file mode 100644
index 000000000000..622850bf99ea
--- /dev/null
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -0,0 +1,97 @@
+/*
+ * Bit definitions for the MCF54xx ACR and CACR registers.
+ */
+
+#ifndef m54xxacr_h
+#define m54xxacr_h
+
+/*
+ * Define the Cache register flags.
+ */
+#define CACR_DEC 0x80000000 /* Enable data cache */
+#define CACR_DWP 0x40000000 /* Data write protection */
+#define CACR_DESB 0x20000000 /* Enable data store buffer */
+#define CACR_DDPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */
+#define CACR_DDCM_WT 0x00000000 /* Write through cache*/
+#define CACR_DDCM_CP 0x02000000 /* Copyback cache */
+#define CACR_DDCM_P 0x04000000 /* No cache, precise */
+#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */
+#define CACR_DCINVA 0x01000000 /* Invalidate data cache */
+#define CACR_BEC 0x00080000 /* Enable branch cache */
+#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */
+#define CACR_IEC 0x00008000 /* Enable instruction cache */
+#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */
+#define CACR_IDPI 0x00001000 /* Disable CPUSHL */
+#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */
+#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */
+#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */
+#define CACR_EUSP 0x00000020 /* Enable separate user a7 */
+
+#define ACR_BASE_POS 24 /* Address Base */
+#define ACR_MASK_POS 16 /* Address Mask */
+#define ACR_ENABLE 0x00008000 /* Enable address */
+#define ACR_USER 0x00000000 /* User mode access only */
+#define ACR_SUPER 0x00002000 /* Supervisor mode only */
+#define ACR_ANY 0x00004000 /* Match any access mode */
+#define ACR_CM_WT 0x00000000 /* Write through mode */
+#define ACR_CM_CP 0x00000020 /* Copyback mode */
+#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */
+#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */
+#define ACR_CM 0x00000060 /* Cache mode mask */
+#define ACR_WPROTECT 0x00000004 /* Write protect */
+
+#if defined(CONFIG_M5407)
+
+#define ICACHE_SIZE 0x4000 /* instruction - 16k */
+#define DCACHE_SIZE 0x2000 /* data - 8k */
+
+#elif defined(CONFIG_M54xx)
+
+#define ICACHE_SIZE 0x8000 /* instruction - 32k */
+#define DCACHE_SIZE 0x8000 /* data - 32k */
+
+#endif
+
+#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */
+#define CACHE_WAYS 4 /* 4 ways */
+
+/*
+ * Version 4 cores have a true harvard style separate instruction
+ * and data cache. Enable data and instruction caches, also enable write
+ * buffers and branch accelerator.
+ */
+/* attention : enabling CACR_DESB requires a "nop" to flush the store buffer */
+/* use '+' instead of '|' for assembler's sake */
+
+ /* Enable data cache */
+ /* Enable data store buffer */
+ /* outside ACRs : No cache, precise */
+ /* Enable instruction+branch caches */
+#if defined(CONFIG_M5407)
+#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC)
+#else
+#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC+CACR_EUSP)
+#endif
+#if defined(CONFIG_CACHE_COPYBACK)
+#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_CP)
+#else
+#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_WT)
+#endif
+#define INSN_CACHE_MODE (ACR_ENABLE+ACR_ANY)
+
+#define CACHE_INIT (CACR_DCINVA+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATE (CACHE_MODE+CACR_DCINVA+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATEI (CACHE_MODE+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATED (CACHE_MODE+CACR_DCINVA)
+#define ACR0_MODE (0x000f0000+DATA_CACHE_MODE)
+#define ACR1_MODE 0
+#define ACR2_MODE (0x000f0000+INSN_CACHE_MODE)
+#define ACR3_MODE 0
+
+#if ((DATA_CACHE_MODE & ACR_CM) == ACR_CM_CP)
+/* Copyback cache mode must push dirty cache lines first */
+#define CACHE_PUSH
+#endif
+
+#endif /* m54xxacr_h */
diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m54xxgpt.h
index c8ef158a1c4e..47ae5cfec66b 100644
--- a/arch/m68k/include/asm/m548xgpt.h
+++ b/arch/m68k/include/asm/m54xxgpt.h
@@ -1,13 +1,13 @@
/*
- * File: m548xgpt.h
- * Purpose: Register and bit definitions for the MCF548X
+ * File: m54xxgpt.h
+ * Purpose: Register and bit definitions for the MCF54XX
*
* Notes:
*
*/
-#ifndef m548xgpt_h
-#define m548xgpt_h
+#ifndef m54xxgpt_h
+#define m54xxgpt_h
/*********************************************************************
*
@@ -85,4 +85,4 @@
/********************************************************************/
-#endif /* m548xgpt_h */
+#endif /* m54xxgpt_h */
diff --git a/arch/m68k/include/asm/m548xsim.h b/arch/m68k/include/asm/m54xxsim.h
index 149135ef30d2..462ae5328441 100644
--- a/arch/m68k/include/asm/m548xsim.h
+++ b/arch/m68k/include/asm/m54xxsim.h
@@ -1,11 +1,16 @@
/*
- * m548xsim.h -- ColdFire 547x/548x System Integration Unit support.
+ * m54xxsim.h -- ColdFire 547x/548x System Integration Unit support.
*/
-#ifndef m548xsim_h
-#define m548xsim_h
+#ifndef m54xxsim_h
+#define m54xxsim_h
-#define MCFINT_VECBASE 64
+#define CPU_NAME "COLDFIRE(m54xx)"
+#define CPU_INSTR_PER_JIFFY 2
+
+#include <asm/m54xxacr.h>
+
+#define MCFINT_VECBASE 64
/*
* Interrupt Controller Registers
@@ -22,6 +27,14 @@
#define MCFINTC_ICR0 0x40 /* Base ICR register */
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x8600 /* Base address of UART1 */
+#define MCFUART_BASE2 0x8700 /* Base address of UART2 */
+#define MCFUART_BASE3 0x8800 /* Base address of UART3 */
+#define MCFUART_BASE4 0x8900 /* Base address of UART4 */
+
+/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
@@ -52,4 +65,4 @@
#define MCF_PAR_PSC_RTS_RTS (0x30)
#define MCF_PAR_PSC_CANRX (0x40)
-#endif /* m548xsim_h */
+#endif /* m54xxsim_h */
diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h
deleted file mode 100644
index f49dfc09f70a..000000000000
--- a/arch/m68k/include/asm/mcfcache.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************/
-
-/*
- * mcfcache.h -- ColdFire CPU cache support code
- *
- * (C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
- */
-
-/****************************************************************************/
-#ifndef __M68KNOMMU_MCFCACHE_H
-#define __M68KNOMMU_MCFCACHE_H
-/****************************************************************************/
-
-
-/*
- * The different ColdFire families have different cache arrangments.
- * Everything from a small instruction only cache, to configurable
- * data and/or instruction cache, to unified instruction/data, to
- * harvard style separate instruction and data caches.
- */
-
-#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272)
-/*
- * Simple version 2 core cache. These have instruction cache only,
- * we just need to invalidate it and enable it.
- */
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate cache cmd */
- movec %d0,%CACR /* do invalidate cache */
- movel #0x80000100,%d0 /* setup cache mask */
- movec %d0,%CACR /* enable cache */
-.endm
-#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
-
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
-/*
- * New version 2 cores have a configurable split cache arrangement.
- * For now I am just enabling instruction cache - but ultimately I
- * think a split instruction/data cache would be better.
- */
-.macro CACHE_ENABLE
- movel #0x01400000,%d0
- movec %d0,%CACR /* invalidate cache */
- nop
- movel #0x0000c000,%d0 /* set SDRAM cached only */
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0x80400100,%d0 /* configure cache */
- movec %d0,%CACR /* enable cache */
- nop
-.endm
-#endif /* CONFIG_M523x || CONFIG_M527x */
-
-#if defined(CONFIG_M528x)
-.macro CACHE_ENABLE
- nop
- movel #0x01000000, %d0
- movec %d0, %CACR /* Invalidate cache */
- nop
- movel #0x0000c020, %d0 /* Set SDRAM cached only */
- movec %d0, %ACR0
- movel #0x00000000, %d0 /* No other regions cached */
- movec %d0, %ACR1
- movel #0x80000200, %d0 /* Setup cache mask */
- movec %d0, %CACR /* Enable cache */
- nop
-.endm
-#endif /* CONFIG_M528x */
-
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307)
-/*
- * The version 3 core cache. Oddly enough the version 2 core 5249
- * has the same SDRAM and cache setup as the version 3 cores.
- * This is a single unified instruction/data cache.
- */
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
-#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3)
- movel #0x0000c000,%d0 /* set SDRAM cached (write-thru) */
-#else
- movel #0x0000c020,%d0 /* set SDRAM cached (copyback) */
-#endif
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0xa0000200,%d0 /* enable cache */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M5249 || CONFIG_M5307 */
-
-#if defined(CONFIG_M532x)
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate cache cmd */
- movec %d0,%CACR /* do invalidate cache */
- nop
- movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0x80000200,%d0 /* setup cache mask */
- movec %d0,%CACR /* enable cache */
- nop
-.endm
-#endif /* CONFIG_M532x */
-
-#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
-/*
- * Version 4 cores have a true harvard style separate instruction
- * and data cache. Invalidate and enable cache, also enable write
- * buffers and branch accelerator.
- */
-.macro CACHE_ENABLE
- movel #0x01040100,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
- movel #0x000fc000,%d0 /* set SDRAM cached only */
- movec %d0, %ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0, %ACR1
- movel #0x000fc000,%d0 /* set SDRAM cached only */
- movec %d0, %ACR2
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0, %ACR3
- movel #0xb6088400,%d0 /* enable caches */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M5407 */
-
-#if defined(CONFIG_M520x)
-.macro CACHE_ENABLE
- move.l #0x01000000,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
- move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */
- movec %d0,%ACR0
- move.l #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- move.l #0x80400000,%d0 /* enable 8K instruction cache */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M520x */
-
-/****************************************************************************/
-#endif /* __M68KNOMMU_MCFCACHE_H */
diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
index 6901fd68165b..ebd0304054ad 100644
--- a/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -41,8 +41,8 @@
#elif defined(CONFIG_M5407)
#include <asm/m5407sim.h>
#include <asm/mcfintc.h>
-#elif defined(CONFIG_M548x)
-#include <asm/m548xsim.h>
+#elif defined(CONFIG_M54xx)
+#include <asm/m54xxsim.h>
#endif
/****************************************************************************/
diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h
index db72e2b889ca..2abedff0a694 100644
--- a/arch/m68k/include/asm/mcfuart.h
+++ b/arch/m68k/include/asm/mcfuart.h
@@ -12,49 +12,6 @@
#define mcfuart_h
/****************************************************************************/
-/*
- * Define the base address of the UARTS within the MBAR address
- * space.
- */
-#if defined(CONFIG_M5272)
-#define MCFUART_BASE1 0x100 /* Base address of UART1 */
-#define MCFUART_BASE2 0x140 /* Base address of UART2 */
-#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
-#if defined(CONFIG_NETtel)
-#define MCFUART_BASE1 0x180 /* Base address of UART1 */
-#define MCFUART_BASE2 0x140 /* Base address of UART2 */
-#else
-#define MCFUART_BASE1 0x140 /* Base address of UART1 */
-#define MCFUART_BASE2 0x180 /* Base address of UART2 */
-#endif
-#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-#define MCFUART_BASE1 0x200 /* Base address of UART1 */
-#define MCFUART_BASE2 0x240 /* Base address of UART2 */
-#define MCFUART_BASE3 0x280 /* Base address of UART3 */
-#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
-#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
-#define MCFUART_BASE1 0x200 /* Base address of UART1 */
-#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
-#else
-#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
-#define MCFUART_BASE2 0x200 /* Base address of UART2 */
-#endif
-#elif defined(CONFIG_M520x)
-#define MCFUART_BASE1 0x60000 /* Base address of UART1 */
-#define MCFUART_BASE2 0x64000 /* Base address of UART2 */
-#define MCFUART_BASE3 0x68000 /* Base address of UART2 */
-#elif defined(CONFIG_M532x)
-#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */
-#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */
-#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */
-#elif defined(CONFIG_M548x)
-#define MCFUART_BASE1 0x8600 /* on M548x */
-#define MCFUART_BASE2 0x8700 /* on M548x */
-#define MCFUART_BASE3 0x8800 /* on M548x */
-#define MCFUART_BASE4 0x8900 /* on M548x */
-#endif
-
-
#include <linux/serial_core.h>
#include <linux/platform_device.h>
@@ -217,7 +174,7 @@ struct mcf_platform_uart {
#define MCFUART_URF_RXS 0xc0 /* Receiver status */
#endif
-#if defined(CONFIG_M548x)
+#if defined(CONFIG_M54xx)
#define MCFUART_TXFIFOSIZE 512
#elif defined(CONFIG_M5272)
#define MCFUART_TXFIFOSIZE 25
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index 7a6a7590cc02..278c69bad57a 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -20,23 +20,26 @@
static inline unsigned long rdusp(void)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
return sw_usp;
#else
- unsigned long usp;
- __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+ register unsigned long usp __asm__("a0");
+ /* move %usp,%a0 */
+ __asm__ __volatile__(".word 0x4e68" : "=a" (usp));
return usp;
#endif
}
static inline void wrusp(unsigned long usp)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
sw_usp = usp;
#else
- __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+ register unsigned long a0 __asm__("a0") = usp;
+ /* move %a0,%usp */
+ __asm__ __volatile__(".word 0x4e60" : : "a" (a0) );
#endif
}
diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h
index cf5fad9b5250..f55aa04161e8 100644
--- a/arch/m68k/include/asm/sun3_pgtable.h
+++ b/arch/m68k/include/asm/sun3_pgtable.h
@@ -217,9 +217,8 @@ static inline pte_t pgoff_to_pte(unsigned off)
/* Find an entry in the third-level pagetable. */
#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address))
-/* FIXME: should we bother with kmap() here? */
-#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address))
-#define pte_unmap(pte) kunmap(pte)
+#define pte_offset_map(pmd, address) ((pte_t *)page_address(pmd_page(*pmd)) + pte_index(address))
+#define pte_unmap(pte) do { } while (0)
/* Macros to (de)construct the fake PTEs representing swap pages. */
#define __swp_type(x) ((x).val & 0x7F)
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index fa9f746cf4ae..2f30fe639f1f 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -75,6 +75,16 @@ config GENERIC_CLOCKEVENTS
config NO_IOPORT
def_bool y
+config COLDFIRE_SW_A7
+ bool
+ default n
+
+config HAVE_CACHE_SPLIT
+ bool
+
+config HAVE_CACHE_CB
+ bool
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -107,69 +117,91 @@ config M68360
config M5206
bool "MCF5206"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206 processor support.
config M5206e
bool "MCF5206e"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206e processor support.
config M520x
bool "MCF520x"
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5207/5208 processor support.
config M523x
bool "MCF523x"
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5230/1/2/4/5 processor support
config M5249
bool "MCF5249"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5249 processor support.
config M5271
bool "MCF5271"
+ select HAVE_CACHE_SPLIT
help
Freescale (Motorola) ColdFire 5270/5271 processor support.
config M5272
bool "MCF5272"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5272 processor support.
config M5275
bool "MCF5275"
+ select HAVE_CACHE_SPLIT
help
Freescale (Motorola) ColdFire 5274/5275 processor support.
config M528x
bool "MCF528x"
+ select COLDFIRE_SW_A7
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Motorola ColdFire 5280/5282 processor support.
config M5307
bool "MCF5307"
+ select COLDFIRE_SW_A7
+ select HAVE_CACHE_CB
help
Motorola ColdFire 5307 processor support.
config M532x
bool "MCF532x"
+ select HAVE_CACHE_CB
help
Freescale (Motorola) ColdFire 532x processor support.
config M5407
bool "MCF5407"
+ select COLDFIRE_SW_A7
+ select HAVE_CACHE_CB
help
Motorola ColdFire 5407 processor support.
+config M547x
+ bool "MCF547x"
+ select HAVE_CACHE_CB
+ help
+ Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
+
config M548x
bool "MCF548x"
+ select HAVE_CACHE_CB
help
Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
@@ -181,9 +213,14 @@ config M527x
select GENERIC_CLOCKEVENTS
default y
+config M54xx
+ bool
+ depends on (M548x || M547x)
+ default y
+
config COLDFIRE
bool
- depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M548x)
+ depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M54xx)
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
default y
@@ -230,6 +267,46 @@ config OLDMASK
Build support for the older revision ColdFire 5307 silicon.
Specifically this is the 1H55J mask revision.
+if HAVE_CACHE_SPLIT
+choice
+ prompt "Split Cache Configuration"
+ default CACHE_I
+
+config CACHE_I
+ bool "Instruction"
+ help
+ Use all of the ColdFire CPU cache memory as an instruction cache.
+
+config CACHE_D
+ bool "Data"
+ help
+ Use all of the ColdFire CPU cache memory as a data cache.
+
+config CACHE_BOTH
+ bool "Both"
+ help
+ Split the ColdFire CPU cache, and use half as an instruction cache
+ and half as a data cache.
+endchoice
+endif
+
+if HAVE_CACHE_CB
+choice
+ prompt "Data cache mode"
+ default CACHE_WRITETHRU
+
+config CACHE_WRITETHRU
+ bool "Write-through"
+ help
+ The ColdFire CPU cache is set into Write-through mode.
+
+config CACHE_COPYBACK
+ bool "Copy-back"
+ help
+ The ColdFire CPU cache is set into Copy-back mode.
+endchoice
+endif
+
comment "Platform"
config PILOT3
@@ -245,16 +322,16 @@ config XCOPILOT_BUGS
Support the bugs of Xcopilot.
config UC5272
- bool 'Arcturus Networks uC5272 dimm board support'
- depends on M5272
- help
- Support for the Arcturus Networks uC5272 dimm board.
+ bool 'Arcturus Networks uC5272 dimm board support'
+ depends on M5272
+ help
+ Support for the Arcturus Networks uC5272 dimm board.
config UC5282
- bool "Arcturus Networks uC5282 board support"
- depends on M528x
- help
- Support for the Arcturus Networks uC5282 dimm board.
+ bool "Arcturus Networks uC5282 board support"
+ depends on M528x
+ help
+ Support for the Arcturus Networks uC5282 dimm board.
config UCSIMM
bool "uCsimm module support"
@@ -279,7 +356,7 @@ config DIRECT_IO_ACCESS
depends on (UCSIMM || UCDIMM || DRAGEN2)
help
Disable the CPU internal registers protection in user mode,
- to allow a user application to read/write them.
+ to allow a user application to read/write them.
config INIT_LCD
bool "Initialize LCD"
@@ -517,7 +594,7 @@ config EMAC_INC
depends on (SOM5282EM)
config SNEHA
- bool
+ bool
default y
depends on CPU16B
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 026ef16fa68e..589613fed31d 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -25,7 +25,7 @@ platform-$(CONFIG_M528x) := 528x
platform-$(CONFIG_M5307) := 5307
platform-$(CONFIG_M532x) := 532x
platform-$(CONFIG_M5407) := 5407
-platform-$(CONFIG_M548x) := 548x
+platform-$(CONFIG_M54xx) := 54xx
PLATFORM := $(platform-y)
board-$(CONFIG_PILOT) := pilot
@@ -74,7 +74,7 @@ cpuclass-$(CONFIG_M528x) := coldfire
cpuclass-$(CONFIG_M5307) := coldfire
cpuclass-$(CONFIG_M532x) := coldfire
cpuclass-$(CONFIG_M5407) := coldfire
-cpuclass-$(CONFIG_M548x) := coldfire
+cpuclass-$(CONFIG_M54xx) := coldfire
cpuclass-$(CONFIG_M68328) := 68328
cpuclass-$(CONFIG_M68EZ328) := 68328
cpuclass-$(CONFIG_M68VZ328) := 68328
@@ -91,18 +91,18 @@ export PLATFORM BOARD MODEL CPUCLASS
# Some CFLAG additions based on specific CPU type.
#
cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
-cflags-$(CONFIG_M5206e) := $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M5206e) := $(call cc-option,-mcpu=5206e,-m5200)
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=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)
+cflags-$(CONFIG_M528x) := $(call cc-option,-mcpu=528x,-m5307)
+cflags-$(CONFIG_M5307) := $(call cc-option,-mcpu=5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
-cflags-$(CONFIG_M548x) := $(call cc-option,-m5407,-m5200)
+cflags-$(CONFIG_M5407) := $(call cc-option,-mcpu=5407,-m5200)
+cflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index c684adf5dc40..16b2de7f5101 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -55,55 +55,29 @@ void (*mach_halt)(void);
void (*mach_power_off)(void);
#ifdef CONFIG_M68328
- #define CPU "MC68328"
+#define CPU_NAME "MC68328"
#endif
#ifdef CONFIG_M68EZ328
- #define CPU "MC68EZ328"
+#define CPU_NAME "MC68EZ328"
#endif
#ifdef CONFIG_M68VZ328
- #define CPU "MC68VZ328"
+#define CPU_NAME "MC68VZ328"
#endif
#ifdef CONFIG_M68360
- #define CPU "MC68360"
+#define CPU_NAME "MC68360"
#endif
-#if defined(CONFIG_M5206)
- #define CPU "COLDFIRE(m5206)"
+#ifndef CPU_NAME
+#define CPU_NAME "UNKNOWN"
#endif
-#if defined(CONFIG_M5206e)
- #define CPU "COLDFIRE(m5206e)"
-#endif
-#if defined(CONFIG_M520x)
- #define CPU "COLDFIRE(m520x)"
-#endif
-#if defined(CONFIG_M523x)
- #define CPU "COLDFIRE(m523x)"
-#endif
-#if defined(CONFIG_M5249)
- #define CPU "COLDFIRE(m5249)"
-#endif
-#if defined(CONFIG_M5271)
- #define CPU "COLDFIRE(m5270/5271)"
-#endif
-#if defined(CONFIG_M5272)
- #define CPU "COLDFIRE(m5272)"
-#endif
-#if defined(CONFIG_M5275)
- #define CPU "COLDFIRE(m5274/5275)"
-#endif
-#if defined(CONFIG_M528x)
- #define CPU "COLDFIRE(m5280/5282)"
-#endif
-#if defined(CONFIG_M5307)
- #define CPU "COLDFIRE(m5307)"
-#endif
-#if defined(CONFIG_M532x)
- #define CPU "COLDFIRE(m532x)"
-#endif
-#if defined(CONFIG_M5407)
- #define CPU "COLDFIRE(m5407)"
-#endif
-#ifndef CPU
- #define CPU "UNKNOWN"
+
+/*
+ * Different cores have different instruction execution timings.
+ * The old/traditional 68000 cores are basically all the same, at 16.
+ * The ColdFire cores vary a little, their values are defined in their
+ * headers. We default to the standard 68000 value here.
+ */
+#ifndef CPU_INSTR_PER_JIFFY
+#define CPU_INSTR_PER_JIFFY 16
#endif
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
@@ -208,7 +182,7 @@ void __init setup_arch(char **cmdline_p)
command_line[sizeof(command_line) - 1] = 0;
#endif /* CONFIG_UBOOT */
- printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
+ printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU_NAME "\n");
#ifdef CONFIG_UCDIMM
printk(KERN_INFO "uCdimm by Lineo, Inc. <www.lineo.com>\n");
@@ -257,11 +231,6 @@ void __init setup_arch(char **cmdline_p)
memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = 0;
-#ifdef DEBUG
- if (strlen(*cmdline_p))
- printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
-#endif
-
#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
@@ -303,15 +272,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
char *cpu, *mmu, *fpu;
u_long clockfreq;
- cpu = CPU;
+ cpu = CPU_NAME;
mmu = "none";
fpu = "none";
-
-#ifdef CONFIG_COLDFIRE
- clockfreq = (loops_per_jiffy * HZ) * 3;
-#else
- clockfreq = (loops_per_jiffy * HZ) * 16;
-#endif
+ clockfreq = (loops_per_jiffy * HZ) * CPU_INSTR_PER_JIFFY;
seq_printf(m, "CPU:\t\t%s\n"
"MMU:\t\t%s\n"
diff --git a/arch/m68knommu/mm/Makefile b/arch/m68knommu/mm/Makefile
index fc91f254f51b..b54ab6b4b523 100644
--- a/arch/m68knommu/mm/Makefile
+++ b/arch/m68knommu/mm/Makefile
@@ -2,4 +2,4 @@
# Makefile for the linux m68knommu specific parts of the memory manager.
#
-obj-y += init.o fault.o memory.o kmap.o
+obj-y += init.o kmap.o
diff --git a/arch/m68knommu/mm/fault.c b/arch/m68knommu/mm/fault.c
deleted file mode 100644
index bc05cf74d9c0..000000000000
--- a/arch/m68knommu/mm/fault.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/arch/m68knommu/mm/fault.c
- *
- * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
- * Copyright (C) 2000 Lineo, Inc. (www.lineo.com)
- *
- * Based on:
- *
- * linux/arch/m68k/mm/fault.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
-extern void die_if_kernel(char *, struct pt_regs *, long);
-
-/*
- * This routine handles page faults. It determines the problem, and
- * then passes it off to one of the appropriate routines.
- *
- * error_code:
- * bit 0 == 0 means no page found, 1 means protection fault
- * bit 1 == 0 means read, 1 means write
- *
- * If this routine detects a bad access, it returns 1, otherwise it
- * returns 0.
- */
-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
- unsigned long error_code)
-{
-#ifdef DEBUG
- printk(KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
- regs->sr, regs->pc, address, error_code);
-#endif
-
- /*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
- if ((unsigned long) address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
- else
- printk(KERN_ALERT "Unable to handle kernel access");
- printk(KERN_ALERT " at virtual address %08lx\n", address);
- die_if_kernel("Oops", regs, error_code);
- do_exit(SIGKILL);
-
- return 1;
-}
-
diff --git a/arch/m68knommu/mm/kmap.c b/arch/m68knommu/mm/kmap.c
index 902c1dfda9e5..ece8d5ad4e6c 100644
--- a/arch/m68knommu/mm/kmap.c
+++ b/arch/m68knommu/mm/kmap.c
@@ -36,15 +36,6 @@ void iounmap(void *addr)
}
/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-void __iounmap(void *addr, unsigned long size)
-{
-}
-
-/*
* Set new cache mode for some kernel address space.
* The caller must push data for that range itself, if such data may already
* be in the cache.
diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c
deleted file mode 100644
index 8f7949e786d4..000000000000
--- a/arch/m68knommu/mm/memory.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * linux/arch/m68knommu/mm/memory.c
- *
- * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
- * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
- *
- * Based on:
- *
- * linux/arch/m68k/mm/memory.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-
-/*
- * Map some physical address range into the kernel address space.
- */
-
-unsigned long kernel_map(unsigned long paddr, unsigned long size,
- int nocacheflag, unsigned long *memavailp )
-{
- return paddr;
-}
-
diff --git a/arch/m68knommu/platform/548x/Makefile b/arch/m68knommu/platform/54xx/Makefile
index e6035e7a2d3f..e6035e7a2d3f 100644
--- a/arch/m68knommu/platform/548x/Makefile
+++ b/arch/m68knommu/platform/54xx/Makefile
diff --git a/arch/m68knommu/platform/548x/config.c b/arch/m68knommu/platform/54xx/config.c
index 9888846bd1cf..78130984db95 100644
--- a/arch/m68knommu/platform/548x/config.c
+++ b/arch/m68knommu/platform/54xx/config.c
@@ -1,7 +1,7 @@
/***************************************************************************/
/*
- * linux/arch/m68knommu/platform/548x/config.c
+ * linux/arch/m68knommu/platform/54xx/config.c
*
* Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be>
*/
@@ -15,13 +15,13 @@
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
-#include <asm/m548xsim.h>
+#include <asm/m54xxsim.h>
#include <asm/mcfuart.h>
-#include <asm/m548xgpt.h>
+#include <asm/m54xxgpt.h>
/***************************************************************************/
-static struct mcf_platform_uart m548x_uart_platform[] = {
+static struct mcf_platform_uart m54xx_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
.irq = 64 + 35,
@@ -40,20 +40,20 @@ static struct mcf_platform_uart m548x_uart_platform[] = {
},
};
-static struct platform_device m548x_uart = {
+static struct platform_device m54xx_uart = {
.name = "mcfuart",
.id = 0,
- .dev.platform_data = m548x_uart_platform,
+ .dev.platform_data = m54xx_uart_platform,
};
-static struct platform_device *m548x_devices[] __initdata = {
- &m548x_uart,
+static struct platform_device *m54xx_devices[] __initdata = {
+ &m54xx_uart,
};
/***************************************************************************/
-static void __init m548x_uart_init_line(int line, int irq)
+static void __init m54xx_uart_init_line(int line, int irq)
{
int rts_cts;
@@ -72,18 +72,18 @@ static void __init m548x_uart_init_line(int line, int irq)
MCF_MBAR + MCF_PAR_PSC(line));
}
-static void __init m548x_uarts_init(void)
+static void __init m54xx_uarts_init(void)
{
- const int nrlines = ARRAY_SIZE(m548x_uart_platform);
+ const int nrlines = ARRAY_SIZE(m54xx_uart_platform);
int line;
for (line = 0; (line < nrlines); line++)
- m548x_uart_init_line(line, m548x_uart_platform[line].irq);
+ m54xx_uart_init_line(line, m54xx_uart_platform[line].irq);
}
/***************************************************************************/
-static void mcf548x_reset(void)
+static void mcf54xx_reset(void)
{
/* disable interrupts and enable the watchdog */
asm("movew #0x2700, %sr\n");
@@ -97,8 +97,8 @@ static void mcf548x_reset(void)
void __init config_BSP(char *commandp, int size)
{
- mach_reset = mcf548x_reset;
- m548x_uarts_init();
+ mach_reset = mcf54xx_reset;
+ m54xx_uarts_init();
}
/***************************************************************************/
@@ -106,7 +106,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
- platform_add_devices(m548x_devices, ARRAY_SIZE(m548x_devices));
+ platform_add_devices(m54xx_devices, ARRAY_SIZE(m54xx_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 45f501fa4525..a8967baabd72 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -14,7 +14,7 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
-obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE) += cache.o clk.o dma.o entry.o vectors.o
obj-$(CONFIG_M5206) += timers.o intc.o
obj-$(CONFIG_M5206e) += timers.o intc.o
obj-$(CONFIG_M520x) += pit.o intc-simr.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_M528x) += pit.o intc-2.o
obj-$(CONFIG_M5307) += timers.o intc.o
obj-$(CONFIG_M532x) += timers.o intc-simr.o
obj-$(CONFIG_M5407) += timers.o intc.o
-obj-$(CONFIG_M548x) += sltimers.o intc-2.o
+obj-$(CONFIG_M54xx) += sltimers.o intc-2.o
obj-y += pinmux.o gpio.o
extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/cache.c b/arch/m68knommu/platform/coldfire/cache.c
new file mode 100644
index 000000000000..235d3c4f4f0f
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/cache.c
@@ -0,0 +1,48 @@
+/***************************************************************************/
+
+/*
+ * cache.c -- general ColdFire Cache maintainence code
+ *
+ * Copyright (C) 2010, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/***************************************************************************/
+#ifdef CACHE_PUSH
+/***************************************************************************/
+
+/*
+ * Use cpushl to push all dirty cache lines back to memory.
+ * Older versions of GAS don't seem to know how to generate the
+ * ColdFire cpushl instruction... Oh well, bit stuff it for now.
+ */
+
+void mcf_cache_push(void)
+{
+ __asm__ __volatile__ (
+ "clrl %%d0\n\t"
+ "1:\n\t"
+ "movel %%d0,%%a0\n\t"
+ "2:\n\t"
+ ".word 0xf468\n\t"
+ "addl %0,%%a0\n\t"
+ "cmpl %1,%%a0\n\t"
+ "blt 2b\n\t"
+ "addql #1,%%d0\n\t"
+ "cmpil %2,%%d0\n\t"
+ "bne 1b\n\t"
+ : /* No output */
+ : "i" (CACHE_LINE_SIZE),
+ "i" (DCACHE_SIZE / CACHE_WAYS),
+ "i" (CACHE_WAYS)
+ : "d0", "a0" );
+}
+
+/***************************************************************************/
+#endif /* CACHE_PUSH */
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index 5e92bed94b7e..f90e6173ccd4 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -36,13 +36,16 @@
#include <asm/asm-offsets.h>
#include <asm/entry.h>
+#ifdef CONFIG_COLDFIRE_SW_A7
+/*
+ * Define software copies of the supervisor and user stack pointers.
+ */
.bss
-
sw_ksp:
.long 0
-
sw_usp:
.long 0
+#endif /* CONFIG_COLDFIRE_SW_A7 */
.text
@@ -51,7 +54,6 @@ sw_usp:
.globl ret_from_exception
.globl ret_from_signal
.globl sys_call_table
-.globl ret_from_interrupt
.globl inthandler
.globl fasthandler
@@ -140,20 +142,7 @@ Luser_return:
jne Lwork_to_do /* still work to do */
Lreturn:
- move #0x2700,%sr /* disable intrs */
- movel sw_usp,%a0 /* get usp */
- movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
- movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stk adj */
- addql #8,%sp /* remove exception */
- movel %sp,sw_ksp /* save ksp */
- subql #8,sw_usp /* set exception */
- movel sw_usp,%sp /* restore usp */
- rte
+ RESTORE_USER
Lwork_to_do:
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
@@ -192,31 +181,7 @@ ENTRY(inthandler)
jbsr do_IRQ /* call high level irq handler */
lea %sp@(8),%sp /* pop args off stack */
- bra ret_from_interrupt /* this was fallthrough */
-
-/*
- * This is the fast interrupt handler (for certain hardware interrupt
- * sources). Unlike the normal interrupt handler it just uses the
- * current stack (doesn't care if it is user or kernel). It also
- * doesn't bother doing the bottom half handlers.
- */
-ENTRY(fasthandler)
- SAVE_LOCAL
-
- movew %sp@(PT_OFF_FORMATVEC),%d0
- andl #0x03fc,%d0 /* mask out vector only */
-
- movel %sp,%sp@- /* push regs arg */
- lsrl #2,%d0 /* calculate real vector # */
- movel %d0,%sp@- /* push vector number */
- jbsr do_IRQ /* call high level irq handler */
- lea %sp@(8),%sp /* pop args off stack */
-
- RESTORE_LOCAL
-
-ENTRY(ret_from_interrupt)
- /* the fasthandler is confusing me, haven't seen any user */
- jmp ret_from_exception
+ bra ret_from_exception
/*
* Beware - when entering resume, prev (the current task) is
@@ -227,9 +192,8 @@ ENTRY(ret_from_interrupt)
*/
ENTRY(resume)
movel %a0, %d1 /* get prev thread in d1 */
-
- movel sw_usp,%d0 /* save usp */
- movel %d0,%a0@(TASK_THREAD+THREAD_USP)
+ RDUSP
+ movel %a2,%a0@(TASK_THREAD+THREAD_USP)
SAVE_SWITCH_STACK
movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
@@ -237,5 +201,5 @@ ENTRY(resume)
RESTORE_SWITCH_STACK
movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
- movel %a0, sw_usp
+ WRUSP
rts
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S
index 0b2d7c7adf79..d5977909ae5f 100644
--- a/arch/m68knommu/platform/coldfire/head.S
+++ b/arch/m68knommu/platform/coldfire/head.S
@@ -3,7 +3,7 @@
/*
* head.S -- common startup code for ColdFire CPUs.
*
- * (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>.
+ * (C) Copyright 1999-2010, Greg Ungerer <gerg@snapgear.com>.
*/
/*****************************************************************************/
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/coldfire.h>
-#include <asm/mcfcache.h>
#include <asm/mcfsim.h>
#include <asm/thread_info.h>
@@ -173,10 +172,27 @@ _start:
/*
* Now that we know what the memory is, lets enable cache
- * and get things moving. This is Coldfire CPU specific.
+ * and get things moving. This is Coldfire CPU specific. Not
+ * all version cores have identical cache register setup. But
+ * it is very similar. Define the exact settings in the headers
+ * then the code here is the same for all.
*/
- CACHE_ENABLE /* enable CPU cache */
-
+ movel #CACHE_INIT,%d0 /* invalidate whole cache */
+ movec %d0,%CACR
+ nop
+ movel #ACR0_MODE,%d0 /* set RAM region for caching */
+ movec %d0,%ACR0
+ movel #ACR1_MODE,%d0 /* anything else to cache? */
+ movec %d0,%ACR1
+#ifdef ACR2_MODE
+ movel #ACR2_MODE,%d0
+ movec %d0,%ACR2
+ movel #ACR3_MODE,%d0
+ movec %d0,%ACR3
+#endif
+ movel #CACHE_MODE,%d0 /* enable cache */
+ movec %d0,%CACR
+ nop
#ifdef CONFIG_ROMFS_FS
/*
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index 15f1f1d1840d..6f432e6df9af 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -17,7 +17,7 @@ export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
# The various CONFIG_XILINX cpu features options are integers 0/1/2...
# rather than bools y/n
-# Work out HW multipler support. This is icky.
+# Work out HW multipler support. This is tricky.
# 1. Spartan2 has no HW multiplers.
# 2. MicroBlaze v3.x always uses them, except in Spartan 2
# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
index 37db96a15b45..a10bec62e857 100644
--- a/arch/microblaze/include/asm/pvr.h
+++ b/arch/microblaze/include/asm/pvr.h
@@ -1,9 +1,9 @@
/*
* Support for the MicroBlaze PVR (Processor Version Register)
*
- * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 - 2011 Michal Simek <monstr@monstr.eu>
* Copyright (C) 2007 John Williams <john.williams@petalogix.com>
- * Copyright (C) 2007 - 2009 PetaLogix
+ * Copyright (C) 2007 - 2011 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
@@ -46,11 +46,11 @@ struct pvr_s {
#define PVR2_I_LMB_MASK 0x10000000
#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
-#define PVR2_D_PLB_MASK 0x02000000 /* new */
-#define PVR2_I_PLB_MASK 0x01000000 /* new */
-#define PVR2_INTERCONNECT 0x00800000 /* new */
-#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */
-#define PVR2_USE_FSL_EXC 0x00040000 /* new */
+#define PVR2_D_PLB_MASK 0x02000000 /* new */
+#define PVR2_I_PLB_MASK 0x01000000 /* new */
+#define PVR2_INTERCONNECT 0x00800000 /* new */
+#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */
+#define PVR2_USE_FSL_EXC 0x00040000 /* new */
#define PVR2_USE_MSR_INSTR 0x00020000
#define PVR2_USE_PCMP_INSTR 0x00010000
#define PVR2_AREA_OPTIMISED 0x00008000
@@ -59,7 +59,7 @@ struct pvr_s {
#define PVR2_USE_HW_MUL_MASK 0x00001000
#define PVR2_USE_FPU_MASK 0x00000800
#define PVR2_USE_MUL64_MASK 0x00000400
-#define PVR2_USE_FPU2_MASK 0x00000200 /* new */
+#define PVR2_USE_FPU2_MASK 0x00000200 /* new */
#define PVR2_USE_IPLBEXC 0x00000100
#define PVR2_USE_DPLBEXC 0x00000080
#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
@@ -122,96 +122,103 @@ struct pvr_s {
/* PVR access macros */
-#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK)
-#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK)
-#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK)
-#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
-#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK)
-#define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK)
-#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
-#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
-#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
-#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK)
-#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK)
-
-#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK)
-#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK)
-#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK)
-#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK)
-#define PVR_INTERRUPT_IS_EDGE(pvr) \
- (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
-#define PVR_EDGE_IS_POSITIVE(pvr) \
- (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
-#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR)
-#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
-#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED)
-#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK)
-#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
- (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
-#define PVR_UNALIGNED_EXCEPTION(pvr) \
- (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
-#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
- (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
-#define PVR_IOPB_BUS_EXCEPTION(pvr) \
- (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
-#define PVR_DOPB_BUS_EXCEPTION(pvr) \
- (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
-#define PVR_DIV_ZERO_EXCEPTION(pvr) \
- (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
-#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK)
-#define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
-
-#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
-#define PVR_NUMBER_OF_PC_BRK(pvr) \
- ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
-#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
- ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
-#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
- ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
-#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
-
-#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
- ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
-#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
-#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
-#define PVR_ICACHE_LINE_LEN(pvr) \
- (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
-#define PVR_ICACHE_BYTE_SIZE(pvr) \
- (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
-
-#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
- ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
-#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
-#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
+#define PVR_IS_FULL(_pvr) (_pvr.pvr[0] & PVR0_PVR_FULL_MASK)
+#define PVR_USE_BARREL(_pvr) (_pvr.pvr[0] & PVR0_USE_BARREL_MASK)
+#define PVR_USE_DIV(_pvr) (_pvr.pvr[0] & PVR0_USE_DIV_MASK)
+#define PVR_USE_HW_MUL(_pvr) (_pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
+#define PVR_USE_FPU(_pvr) (_pvr.pvr[0] & PVR0_USE_FPU_MASK)
+#define PVR_USE_FPU2(_pvr) (_pvr.pvr[2] & PVR2_USE_FPU2_MASK)
+#define PVR_USE_ICACHE(_pvr) (_pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
+#define PVR_USE_DCACHE(_pvr) (_pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
+#define PVR_VERSION(_pvr) ((_pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
+#define PVR_USER1(_pvr) (_pvr.pvr[0] & PVR0_USER1_MASK)
+#define PVR_USER2(_pvr) (_pvr.pvr[1] & PVR1_USER2_MASK)
+
+#define PVR_D_OPB(_pvr) (_pvr.pvr[2] & PVR2_D_OPB_MASK)
+#define PVR_D_LMB(_pvr) (_pvr.pvr[2] & PVR2_D_LMB_MASK)
+#define PVR_I_OPB(_pvr) (_pvr.pvr[2] & PVR2_I_OPB_MASK)
+#define PVR_I_LMB(_pvr) (_pvr.pvr[2] & PVR2_I_LMB_MASK)
+#define PVR_INTERRUPT_IS_EDGE(_pvr) \
+ (_pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
+#define PVR_EDGE_IS_POSITIVE(_pvr) \
+ (_pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
+#define PVR_USE_MSR_INSTR(_pvr) (_pvr.pvr[2] & PVR2_USE_MSR_INSTR)
+#define PVR_USE_PCMP_INSTR(_pvr) (_pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
+#define PVR_AREA_OPTIMISED(_pvr) (_pvr.pvr[2] & PVR2_AREA_OPTIMISED)
+#define PVR_USE_MUL64(_pvr) (_pvr.pvr[2] & PVR2_USE_MUL64_MASK)
+#define PVR_OPCODE_0x0_ILLEGAL(_pvr) \
+ (_pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
+#define PVR_UNALIGNED_EXCEPTION(_pvr) \
+ (_pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
+#define PVR_ILL_OPCODE_EXCEPTION(_pvr) \
+ (_pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
+#define PVR_IOPB_BUS_EXCEPTION(_pvr) \
+ (_pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
+#define PVR_DOPB_BUS_EXCEPTION(_pvr) \
+ (_pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
+#define PVR_DIV_ZERO_EXCEPTION(_pvr) \
+ (_pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
+#define PVR_FPU_EXCEPTION(_pvr) (_pvr.pvr[2] & PVR2_FPU_EXC_MASK)
+#define PVR_FSL_EXCEPTION(_pvr) (_pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
+
+#define PVR_DEBUG_ENABLED(_pvr) (_pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
+#define PVR_NUMBER_OF_PC_BRK(_pvr) \
+ ((_pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
+#define PVR_NUMBER_OF_RD_ADDR_BRK(_pvr) \
+ ((_pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
+#define PVR_NUMBER_OF_WR_ADDR_BRK(_pvr) \
+ ((_pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
+#define PVR_FSL_LINKS(_pvr) ((_pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
+
+#define PVR_ICACHE_ADDR_TAG_BITS(_pvr) \
+ ((_pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_ICACHE_USE_FSL(_pvr) \
+ (_pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
+#define PVR_ICACHE_ALLOW_WR(_pvr) \
+ (_pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
+#define PVR_ICACHE_LINE_LEN(_pvr) \
+ (1 << ((_pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
+#define PVR_ICACHE_BYTE_SIZE(_pvr) \
+ (1 << ((_pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
+
+#define PVR_DCACHE_ADDR_TAG_BITS(_pvr) \
+ ((_pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_DCACHE_USE_FSL(_pvr) (_pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
+#define PVR_DCACHE_ALLOW_WR(_pvr) \
+ (_pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
/* FIXME two shifts on one line needs any comment */
-#define PVR_DCACHE_LINE_LEN(pvr) \
- (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
-#define PVR_DCACHE_BYTE_SIZE(pvr) \
- (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
+#define PVR_DCACHE_LINE_LEN(_pvr) \
+ (1 << ((_pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
+#define PVR_DCACHE_BYTE_SIZE(_pvr) \
+ (1 << ((_pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
-#define PVR_DCACHE_USE_WRITEBACK(pvr) \
- ((pvr.pvr[5] & PVR5_DCACHE_USE_WRITEBACK) >> 14)
+#define PVR_DCACHE_USE_WRITEBACK(_pvr) \
+ ((_pvr.pvr[5] & PVR5_DCACHE_USE_WRITEBACK) >> 14)
-#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
-#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+#define PVR_ICACHE_BASEADDR(_pvr) \
+ (_pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
+#define PVR_ICACHE_HIGHADDR(_pvr) \
+ (_pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+#define PVR_DCACHE_BASEADDR(_pvr) \
+ (_pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
+#define PVR_DCACHE_HIGHADDR(_pvr) \
+ (_pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
-#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
-#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
+#define PVR_TARGET_FAMILY(_pvr) \
+ ((_pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
-#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
-
-#define PVR_MSR_RESET_VALUE(pvr) \
- (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
+#define PVR_MSR_RESET_VALUE(_pvr) \
+ (_pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
/* mmu */
-#define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30)
-#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
-#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
-#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
-#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
+#define PVR_USE_MMU(_pvr) ((_pvr.pvr[11] & PVR11_USE_MMU) >> 30)
+#define PVR_MMU_ITLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
+#define PVR_MMU_DTLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
+#define PVR_MMU_TLB_ACCESS(_pvr) (_pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
+#define PVR_MMU_ZONES(_pvr) (_pvr.pvr[11] & PVR11_MMU_ZONES)
/* endian */
-#define PVR_ENDIAN(pvr) (pvr.pvr[0] & PVR0_ENDI)
+#define PVR_ENDIAN(_pvr) (_pvr.pvr[0] & PVR0_ENDI)
int cpu_has_pvr(void);
void get_pvr(struct pvr_s *pvr);
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 87c79fa275c3..2c309fccf230 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -32,6 +32,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"7.30.a", 0x10},
{"7.30.b", 0x11},
{"8.00.a", 0x12},
+ {"8.00.b", 0x13},
{NULL, 0},
};
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 819238b8a429..41c30cdb2704 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -287,25 +287,44 @@
* are masked. This is nice, means we don't have to CLI before state save
*/
C_ENTRY(_user_exception):
- addi r14, r14, 4 /* return address is 4 byte after call */
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
+ addi r14, r14, 4 /* return address is 4 byte after call */
+
+ mfs r1, rmsr
+ nop
+ andi r1, r1, MSR_UMS
+ bnei r1, 1f
+
+/* Kernel-mode state save - kernel execve */
+ lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
+ tophys(r1,r1);
+
+ addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
+ SAVE_REGS
+ swi r1, r1, PTO + PT_MODE; /* pt_regs -> kernel mode */
+ brid 2f;
+ nop; /* Fill delay slot */
+
+/* User-mode state save. */
+1:
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
tophys(r1,r1);
lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
- /* MS these three instructions can be added to one */
- /* addik r1, r1, THREAD_SIZE; */
- /* tophys(r1,r1); */
- /* addik r1, r1, -STATE_SAVE_SIZE; */
- addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
+/* calculate kernel stack pointer from task struct 8k */
+ addik r1, r1, THREAD_SIZE;
+ tophys(r1,r1);
+
+ addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
SAVE_REGS
swi r0, r1, PTO + PT_R3
swi r0, r1, PTO + PT_R4
+ swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1; /* Store user SP. */
clear_ums;
- lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
+2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
/* Save away the syscall number. */
swi r12, r1, PTO+PT_R0;
tovirt(r1,r1)
@@ -375,6 +394,9 @@ C_ENTRY(ret_from_trap):
swi r3, r1, PTO + PT_R3
swi r4, r1, PTO + PT_R4
+ lwi r11, r1, PTO + PT_MODE;
+/* See if returning to kernel mode, if so, skip resched &c. */
+ bnei r11, 2f;
/* We're returning to user mode, so check for various conditions that
* trigger rescheduling. */
/* FIXME: Restructure all these flag checks. */
@@ -417,6 +439,16 @@ C_ENTRY(ret_from_trap):
RESTORE_REGS;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
+ bri 6f;
+
+/* Return to kernel state. */
+2: set_bip; /* Ints masked for state restore */
+ VM_OFF;
+ tophys(r1,r1);
+ RESTORE_REGS;
+ addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
+ tovirt(r1,r1);
+6:
TRAP_return: /* Make global symbol for debugging */
rtbd r14, 0; /* Instructions to return from an IRQ */
nop;
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index 478f2943ede7..a7fa6ae76d89 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -25,6 +25,7 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <asm/current.h>
+#include <asm/cacheflush.h>
#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02
#define MICROBLAZE_IBUS_EXCEPTION 0x03
@@ -52,6 +53,8 @@ void die(const char *str, struct pt_regs *fp, long err)
void sw_exception(struct pt_regs *regs)
{
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16);
+ flush_dcache_range(regs->r16, regs->r16 + 0x4);
+ flush_icache_range(regs->r16, regs->r16 + 0x4);
}
void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 781195438ee6..25f6e07d8de8 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -945,11 +945,20 @@ store3: sbi r3, r4, 2;
store4: sbi r3, r4, 3; /* Delay slot */
ex_shw_vm:
/* Store the lower half-word, byte-by-byte into destination address */
+#ifdef __MICROBLAZEEL__
+ lbui r3, r5, 0;
+store5: sbi r3, r4, 0;
+ lbui r3, r5, 1;
+ brid ret_from_exc;
+store6: sbi r3, r4, 1; /* Delay slot */
+#else
lbui r3, r5, 2;
store5: sbi r3, r4, 0;
lbui r3, r5, 3;
brid ret_from_exc;
store6: sbi r3, r4, 1; /* Delay slot */
+#endif
+
ex_sw_end_vm: /* Exception handling of store word, ends. */
/* We have to prevent cases that get/put_user macros get unaligned pointer
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index a105301e2b7f..c881393f07fd 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -61,14 +61,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
char *p;
int *addr;
- pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+ pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname);
/* find all serial nodes */
if (strncmp(uname, "serial", 6) != 0)
return 0;
- early_init_dt_check_for_initrd(node);
-
/* find compatible node with uartlite */
p = of_get_flat_dt_prop(node, "compatible", &l);
if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index 96a88c31fe48..3451bdec9f05 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -123,20 +123,10 @@ SECTIONS {
__init_end_before_initramfs = .;
- .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
- __initramfs_start = .;
- *(.init.ramfs)
- __initramfs_end = .;
- . = ALIGN(4);
- LONG(0);
-/*
- * FIXME this can break initramfs for MMU.
- * Pad init.ramfs up to page boundary,
- * so that __init_end == __bss_start. This will make image.elf
- * consistent with the image.bin
- */
- /* . = ALIGN(PAGE_SIZE); */
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ INIT_RAM_FS
}
+
__init_end = .;
.bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) {
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
index 123e3616f2dd..810fd68775e3 100644
--- a/arch/microblaze/lib/memmove.c
+++ b/arch/microblaze/lib/memmove.c
@@ -182,7 +182,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
for (; c >= 4; c -= 4) {
value = *--i_src;
*--i_dst = buf_hold | ((value & 0xFF000000)>> 24);
- buf_hold = (value & 0xFFFFFF) << 8;;
+ buf_hold = (value & 0xFFFFFF) << 8;
}
#endif
/* Realign the source */
diff --git a/arch/microblaze/lib/muldi3.S b/arch/microblaze/lib/muldi3.S
deleted file mode 100644
index ceeaa8c407f2..000000000000
--- a/arch/microblaze/lib/muldi3.S
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <linux/linkage.h>
-
-/*
- * Multiply operation for 64 bit integers, for devices with hard multiply
- * Input : Operand1[H] in Reg r5
- * Operand1[L] in Reg r6
- * Operand2[H] in Reg r7
- * Operand2[L] in Reg r8
- * Output: Result[H] in Reg r3
- * Result[L] in Reg r4
- *
- * Explaination:
- *
- * Both the input numbers are divided into 16 bit number as follows
- * op1 = A B C D
- * op2 = E F G H
- * result = D * H
- * + (C * H + D * G) << 16
- * + (B * H + C * G + D * F) << 32
- * + (A * H + B * G + C * F + D * E) << 48
- *
- * Only 64 bits of the output are considered
- */
-
- .text
- .globl __muldi3
- .type __muldi3, @function
- .ent __muldi3
-
-__muldi3:
- addi r1, r1, -40
-
-/* Save the input operands on the caller's stack */
- swi r5, r1, 44
- swi r6, r1, 48
- swi r7, r1, 52
- swi r8, r1, 56
-
-/* Store all the callee saved registers */
- sw r20, r1, r0
- swi r21, r1, 4
- swi r22, r1, 8
- swi r23, r1, 12
- swi r24, r1, 16
- swi r25, r1, 20
- swi r26, r1, 24
- swi r27, r1, 28
-
-/* Load all the 16 bit values for A thru H */
- lhui r20, r1, 44 /* A */
- lhui r21, r1, 46 /* B */
- lhui r22, r1, 48 /* C */
- lhui r23, r1, 50 /* D */
- lhui r24, r1, 52 /* E */
- lhui r25, r1, 54 /* F */
- lhui r26, r1, 56 /* G */
- lhui r27, r1, 58 /* H */
-
-/* D * H ==> LSB of the result on stack ==> Store1 */
- mul r9, r23, r27
- swi r9, r1, 36 /* Pos2 and Pos3 */
-
-/* Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2 */
-/* Store the carry generated in position 2 for Pos 3 */
- lhui r11, r1, 36 /* Pos2 */
- mul r9, r22, r27 /* C * H */
- mul r10, r23, r26 /* D * G */
- add r9, r9, r10
- addc r12, r0, r0
- add r9, r9, r11
- addc r12, r12, r0 /* Store the Carry */
- shi r9, r1, 36 /* Store Pos2 */
- swi r9, r1, 32
- lhui r11, r1, 32
- shi r11, r1, 34 /* Store Pos1 */
-
-/* Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1 */
- mul r9, r21, r27 /* B * H */
- mul r10, r22, r26 /* C * G */
- mul r7, r23, r25 /* D * F */
- add r9, r9, r11
- add r9, r9, r10
- add r9, r9, r7
- swi r9, r1, 32 /* Pos0 and Pos1 */
-
-/* Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0 */
- lhui r11, r1, 32 /* Pos0 */
- mul r9, r20, r27 /* A * H */
- mul r10, r21, r26 /* B * G */
- mul r7, r22, r25 /* C * F */
- mul r8, r23, r24 /* D * E */
- add r9, r9, r11
- add r9, r9, r10
- add r9, r9, r7
- add r9, r9, r8
- sext16 r9, r9 /* Sign extend the MSB */
- shi r9, r1, 32
-
-/* Move results to r3 and r4 */
- lhui r3, r1, 32
- add r3, r3, r12
- shi r3, r1, 32
- lwi r3, r1, 32 /* Hi Part */
- lwi r4, r1, 36 /* Lo Part */
-
-/* Restore Callee saved registers */
- lw r20, r1, r0
- lwi r21, r1, 4
- lwi r22, r1, 8
- lwi r23, r1, 12
- lwi r24, r1, 16
- lwi r25, r1, 20
- lwi r26, r1, 24
- lwi r27, r1, 28
-
-/* Restore Frame and return */
- rtsd r15, 8
- addi r1, r1, 40
-
-.size __muldi3, . - __muldi3
-.end __muldi3
diff --git a/arch/microblaze/lib/muldi3.c b/arch/microblaze/lib/muldi3.c
new file mode 100644
index 000000000000..d4860e154d29
--- /dev/null
+++ b/arch/microblaze/lib/muldi3.c
@@ -0,0 +1,60 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+#define DWtype long long
+#define UWtype unsigned long
+#define UHWtype unsigned short
+
+#define W_TYPE_SIZE 32
+
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* If we still don't have umul_ppmm, define it using plain C. */
+#if !defined(umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart(u); \
+ __uh = __ll_highpart(u); \
+ __vl = __ll_lowpart(v); \
+ __vh = __ll_highpart(v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart(__x0); /* this can't give carry */\
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos */ \
+ \
+ (w1) = __x3 + __ll_highpart(__x1); \
+ (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\
+ } while (0)
+#endif
+
+#if !defined(__umulsidi3)
+#define __umulsidi3(u, v) ({ \
+ DWunion __w; \
+ umul_ppmm(__w.s.high, __w.s.low, u, v); \
+ __w.ll; \
+ })
+#endif
+
+DWtype __muldi3(DWtype u, DWtype v)
+{
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
+ DWunion w = {.ll = __umulsidi3(uu.s.low, vv.s.low)};
+
+ w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
+ + (UWtype) uu.s.high * (UWtype) vv.s.low);
+
+ return w.ll;
+}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 67a2fa2caa49..12d0d0f89375 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -19,6 +19,9 @@ config MIPS
select GENERIC_ATOMIC64 if !64BIT
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_PROBE
+ select HAVE_ARCH_JUMP_LABEL
menu "Machine selection"
@@ -881,6 +884,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
config SYNC_R4K
bool
+config MIPS_MACHINE
+ def_bool n
+
config NO_IOPORT
def_bool n
@@ -1664,6 +1670,28 @@ config PAGE_SIZE_64KB
endchoice
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order"
+ range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+ default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+ range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+ default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+ range 11 64
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+ blocks into "zones", where each zone is a power of two number of
+ pages. This option selects the largest power of two that the kernel
+ keeps in the memory allocator. If you need to allocate very large
+ blocks of physically contiguous memory, then you may need to
+ increase this value.
+
+ This config option is actually maximum order plus one. For example,
+ a value of 11 means that the largest free memory block is 2^10 pages.
+
+ The page size is not necessarily 4KB. Keep this in mind
+ when choosing a value for this option.
+
config BOARD_SCACHE
bool
@@ -1922,20 +1950,6 @@ config CPU_R4400_WORKAROUNDS
bool
#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
- bool
- default y
-
-config GENERIC_IRQ_PROBE
- bool
- default y
-
-config IRQ_PER_CPU
- bool
-
-#
# - Highmem only makes sense for the 32-bit kernel.
# - The current highmem code will only work properly on physically indexed
# caches such as R3000, SB1, R7000 or those that look like they're virtually
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 3691630931d6..9e7814db3d03 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -27,6 +27,7 @@
static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
unsigned int old_state)
{
+#ifdef CONFIG_SERIAL_8250
switch (state) {
case 0:
if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
@@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
serial8250_do_pm(port, state, old_state);
break;
}
+#endif
}
#define PORT(_base, _irq) \
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
index b30df5c97ad3..baeb21385058 100644
--- a/arch/mips/alchemy/devboards/prom.c
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -54,10 +54,9 @@ void __init prom_init(void)
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
- if (!memsize_str)
+ if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
- else
- strict_strtoul(memsize_str, 0, &memsize);
+
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c
index fc0e7154e8d6..2ca4ada1c291 100644
--- a/arch/mips/ar7/clock.c
+++ b/arch/mips/ar7/clock.c
@@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
calculate(base_clock, frequency, &prediv, &postdiv, &mul);
writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
- msleep(1);
+ mdelay(1);
writel(4, &clock->pll);
while (readl(&clock->pll) & PLL_STATUS)
;
writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
- msleep(75);
+ mdelay(75);
}
static void __init tnetd7300_init_clocks(void)
@@ -456,7 +456,7 @@ void clk_put(struct clk *clk)
}
EXPORT_SYMBOL(clk_put);
-int __init ar7_init_clocks(void)
+void __init ar7_init_clocks(void)
{
switch (ar7_chip_id()) {
case AR7_CHIP_7100:
@@ -472,7 +472,4 @@ int __init ar7_init_clocks(void)
}
/* adjust vbus clock rate */
vbus_clk.rate = bus_clk.rate / 2;
-
- return 0;
}
-arch_initcall(ar7_init_clocks);
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c
index 5fb8a0134085..22c93213b233 100644
--- a/arch/mips/ar7/time.c
+++ b/arch/mips/ar7/time.c
@@ -30,6 +30,9 @@ void __init plat_time_init(void)
{
struct clk *cpu_clk;
+ /* Initialize ar7 clocks so the CPU clock frequency is correct */
+ ar7_init_clocks();
+
cpu_clk = clk_get(NULL, "cpu");
if (IS_ERR(cpu_clk)) {
printk(KERN_ERR "unable to get cpu clock\n");
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index b1aee33efd11..c95f90bf734c 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -32,7 +32,6 @@
#include <asm/reboot.h>
#include <asm/time.h>
#include <bcm47xx.h>
-#include <asm/fw/cfe/cfe_api.h>
#include <asm/mach-bcm47xx/nvram.h>
struct ssb_bus ssb_bcm47xx;
@@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void)
cpu_relax();
}
-static void str2eaddr(char *str, char *dest)
-{
- int i = 0;
+#define READ_FROM_NVRAM(_outvar, name, buf) \
+ if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
+ sprom->_outvar = simple_strtoul(buf, NULL, 0);
- if (str == NULL) {
- memset(dest, 0, 6);
- return;
+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
+{
+ char buf[100];
+ u32 boardflags;
+
+ memset(sprom, 0, sizeof(struct ssb_sprom));
+
+ sprom->revision = 1; /* Fallback: Old hardware does not define this. */
+ READ_FROM_NVRAM(revision, "sromrev", buf);
+ if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->il0mac);
+ if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->et0mac);
+ if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->et1mac);
+ READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
+ READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
+ READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
+ READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
+ READ_FROM_NVRAM(board_rev, "boardrev", buf);
+ READ_FROM_NVRAM(country_code, "ccode", buf);
+ READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
+ READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
+ READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
+ READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
+ READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
+ READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
+ READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
+ READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
+ READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
+ READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
+ READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
+ READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
+ READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
+ READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
+ READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
+ READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
+ READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
+ READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
+ READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
+ READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
+ READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
+ READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
+ READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
+ READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
+ READ_FROM_NVRAM(tri2g, "tri2g", buf);
+ READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
+ READ_FROM_NVRAM(tri5g, "tri5g", buf);
+ READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
+ READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
+ READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
+ READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
+ READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
+ READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
+ READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
+ READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
+ READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
+ READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
+ READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
+ READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
+ READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
+ READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
+ READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
+ READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
+
+ if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
+ boardflags = simple_strtoul(buf, NULL, 0);
+ if (boardflags) {
+ sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
+ sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
+ }
}
-
- for (;;) {
- dest[i++] = (char) simple_strtoul(str, NULL, 16);
- str += 2;
- if (!*str++ || i == 6)
- break;
+ if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
+ boardflags = simple_strtoul(buf, NULL, 0);
+ if (boardflags) {
+ sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
+ sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
+ }
}
}
static int bcm47xx_get_invariants(struct ssb_bus *bus,
struct ssb_init_invariants *iv)
{
- char buf[100];
+ char buf[20];
/* Fill boardinfo structure */
memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
- if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
- iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
- if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
+ if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+ iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
+ else
+ iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+ if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
- if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
+ if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
- /* Fill sprom structure */
- memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
- iv->sprom.revision = 3;
-
- if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
- str2eaddr(buf, iv->sprom.et0mac);
+ bcm47xx_fill_sprom(&iv->sprom);
- if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
- str2eaddr(buf, iv->sprom.et1mac);
-
- if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
-
- if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
-
- if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
- iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
-
- if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
- nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
- iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
+ if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
+ iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
return 0;
}
@@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
void __init plat_mem_setup(void)
{
int err;
+ char buf[100];
+ struct ssb_mipscore *mcore;
err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
bcm47xx_get_invariants);
if (err)
panic("Failed to initialize SSB bus (err %d)\n", err);
+ mcore = &ssb_bcm47xx.mipscore;
+ if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
+ if (strstr(buf, "console=ttyS1")) {
+ struct ssb_serial_port port;
+
+ printk(KERN_DEBUG "Swapping serial ports!\n");
+ /* swap serial ports */
+ memcpy(&port, &mcore->serial_ports[0], sizeof(port));
+ memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
+ sizeof(port));
+ memcpy(&mcore->serial_ports[1], &port, sizeof(port));
+ }
+ }
+
_machine_restart = bcm47xx_machine_restart;
_machine_halt = bcm47xx_machine_halt;
pm_power_off = bcm47xx_machine_halt;
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index b39def3f6e03..c454550eb0c0 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -78,6 +78,7 @@ struct cpuinfo_mips {
unsigned int watch_reg_use_cnt; /* Usable by ptrace */
#define NUM_WATCH_REGS 4
u16 watch_reg_masks[NUM_WATCH_REGS];
+ unsigned int kscratch_mask; /* Usable KScratch mask. */
} __attribute__((aligned(SMP_CACHE_BYTES)));
extern struct cpuinfo_mips cpu_data[];
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 06d59dcbe243..86877539c6e8 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -111,8 +111,8 @@
* These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
*/
-#define PRID_IMP_BMIPS4KC 0x4000
-#define PRID_IMP_BMIPS32 0x8000
+#define PRID_IMP_BMIPS32_REV4 0x4000
+#define PRID_IMP_BMIPS32_REV8 0x8000
#define PRID_IMP_BMIPS3300 0x9000
#define PRID_IMP_BMIPS3300_ALT 0x9100
#define PRID_IMP_BMIPS3300_BUG 0x0000
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index fd1d39eb7431..455c0ac7d4ea 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32;
#define SET_PERSONALITY(ex) \
do { \
- set_personality(PER_LINUX); \
+ if (personality(current->personality) != PER_LINUX) \
+ set_personality(PER_LINUX); \
\
current->thread.abi = &mips_abi; \
} while (0)
@@ -296,6 +297,8 @@ do { \
#define SET_PERSONALITY(ex) \
do { \
+ unsigned int p; \
+ \
clear_thread_flag(TIF_32BIT_REGS); \
clear_thread_flag(TIF_32BIT_ADDR); \
\
@@ -304,7 +307,8 @@ do { \
else \
current->thread.abi = &mips_abi; \
\
- if (current->personality != PER_LINUX32) \
+ p = personality(current->personality); \
+ if (p != PER_LINUX32 && p != PER_LINUX) \
set_personality(PER_LINUX); \
} while (0)
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h
index 444ff71aa0e8..7ebfc392e58d 100644
--- a/arch/mips/include/asm/inst.h
+++ b/arch/mips/include/asm/inst.h
@@ -72,6 +72,7 @@ enum spec2_op {
enum spec3_op {
ext_op, dextm_op, dextu_op, dext_op,
ins_op, dinsm_op, dinsu_op, dins_op,
+ lx_op = 0x0a,
bshfl_op = 0x20,
dbshfl_op = 0x24,
rdhwr_op = 0x3b
@@ -179,6 +180,19 @@ enum mad_func {
};
/*
+ * func field for special3 lx opcodes (Cavium Octeon).
+ */
+enum lx_func {
+ lwx_op = 0x00,
+ lhx_op = 0x04,
+ lbux_op = 0x06,
+ ldx_op = 0x08,
+ lwux_op = 0x10,
+ lhux_op = 0x14,
+ lbx_op = 0x16,
+};
+
+/*
* Damn ... bitfields depend from byteorder :-(
*/
#ifdef __MIPSEB__
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index c98bf514ec7d..5b017f23e243 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \
"dsrl32 %L0, %L0, 0" "\n\t" \
"dsll32 %M0, %M0, 0" "\n\t" \
"or %L0, %L0, %M0" "\n\t" \
+ ".set push" "\n\t" \
+ ".set noreorder" "\n\t" \
+ ".set nomacro" "\n\t" \
"sd %L0, %2" "\n\t" \
+ ".set pop" "\n\t" \
".set mips0" "\n" \
: "=r" (__tmp) \
- : "0" (__val), "m" (*__mem)); \
+ : "0" (__val), "R" (*__mem)); \
if (irq) \
local_irq_restore(__flags); \
} else \
@@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
local_irq_save(__flags); \
__asm__ __volatile__( \
".set mips3" "\t\t# __readq" "\n\t" \
+ ".set push" "\n\t" \
+ ".set noreorder" "\n\t" \
+ ".set nomacro" "\n\t" \
"ld %L0, %1" "\n\t" \
+ ".set pop" "\n\t" \
"dsra32 %M0, %L0, 0" "\n\t" \
"sll %L0, %L0, 0" "\n\t" \
".set mips0" "\n" \
: "=r" (__val) \
- : "m" (*__mem)); \
+ : "R" (*__mem)); \
if (irq) \
local_irq_restore(__flags); \
} else { \
diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h
new file mode 100644
index 000000000000..7622ccf75076
--- /dev/null
+++ b/arch/mips/include/asm/jump_label.h
@@ -0,0 +1,48 @@
+/*
+ * 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) 2010 Cavium Networks, Inc.
+ */
+#ifndef _ASM_MIPS_JUMP_LABEL_H
+#define _ASM_MIPS_JUMP_LABEL_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+#ifdef CONFIG_64BIT
+#define WORD_INSN ".dword"
+#else
+#define WORD_INSN ".word"
+#endif
+
+#define JUMP_LABEL(key, label) \
+ do { \
+ asm goto("1:\tnop\n\t" \
+ "nop\n\t" \
+ ".pushsection __jump_table, \"a\"\n\t" \
+ WORD_INSN " 1b, %l[" #label "], %0\n\t" \
+ ".popsection\n\t" \
+ : : "i" (key) : : label); \
+ } while (0)
+
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_64BIT
+typedef u64 jump_label_t;
+#else
+typedef u32 jump_label_t;
+#endif
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* _ASM_MIPS_JUMP_LABEL_H */
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index 7919d76186bf..07d3fadb2443 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit)
}
int __init ar7_gpio_init(void);
-
-int __init ar7_gpio_init(void);
+void __init ar7_init_clocks(void);
#endif /* __AR7_H__ */
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
index c58ebd8bc155..9759588ba3cf 100644
--- a/arch/mips/include/asm/mach-bcm47xx/nvram.h
+++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
@@ -12,6 +12,7 @@
#define __NVRAM_H
#include <linux/types.h>
+#include <linux/kernel.h>
struct nvram_header {
u32 magic;
@@ -36,4 +37,10 @@ struct nvram_header {
extern int nvram_getenv(char *name, char *val, size_t val_len);
+static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+{
+ sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
+ &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
+}
+
#endif
diff --git a/arch/mips/include/asm/mips_machine.h b/arch/mips/include/asm/mips_machine.h
new file mode 100644
index 000000000000..363bb352c7f7
--- /dev/null
+++ b/arch/mips/include/asm/mips_machine.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MIPS_MACHINE_H
+#define __ASM_MIPS_MACHINE_H
+
+#include <linux/init.h>
+#include <linux/stddef.h>
+
+#include <asm/bootinfo.h>
+
+struct mips_machine {
+ unsigned long mach_type;
+ const char *mach_id;
+ const char *mach_name;
+ void (*mach_setup)(void);
+};
+
+#define MIPS_MACHINE(_type, _id, _name, _setup) \
+static const char machine_name_##_type[] __initconst \
+ __aligned(1) = _name; \
+static const char machine_id_##_type[] __initconst \
+ __aligned(1) = _id; \
+static struct mips_machine machine_##_type \
+ __used __section(.mips.machines.init) = \
+{ \
+ .mach_type = _type, \
+ .mach_id = machine_id_##_type, \
+ .mach_name = machine_name_##_type, \
+ .mach_setup = _setup, \
+};
+
+extern long __mips_machines_start;
+extern long __mips_machines_end;
+
+#ifdef CONFIG_MIPS_MACHINE
+int mips_machtype_setup(char *id) __init;
+void mips_machine_setup(void) __init;
+void mips_set_machine_name(const char *name) __init;
+char *mips_get_machine_name(void);
+#else
+static inline int mips_machtype_setup(char *id) { return 1; }
+static inline void mips_machine_setup(void) { }
+static inline void mips_set_machine_name(const char *name) { }
+static inline char *mips_get_machine_name(void) { return NULL; }
+#endif /* CONFIG_MIPS_MACHINE */
+
+#endif /* __ASM_MIPS_MACHINE_H */
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index d9592733a7ba..73c0d45798de 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -29,13 +29,7 @@
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
tlbmiss_handler_setup_pgd((unsigned long)(pgd))
-static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
-{
- /* Check for swapper_pg_dir and convert to physical address. */
- if ((pgd & CKSEG3) == CKSEG0)
- pgd = CPHYSADDR(pgd);
- write_c0_context(pgd << 11);
-}
+extern void tlbmiss_handler_setup_pgd(unsigned long pgd);
#define TLBMISS_HANDLER_SETUP() \
do { \
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 892062d6d748..dcbd4bb417ec 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -115,7 +115,12 @@ Ip_0(_tlbwr);
Ip_u3u1u2(_xor);
Ip_u2u1u3(_xori);
Ip_u2u1msbu3(_dins);
+Ip_u2u1msbu3(_dinsm);
Ip_u1(_syscall);
+Ip_u1u2s3(_bbit0);
+Ip_u1u2s3(_bbit1);
+Ip_u3u1u2(_lwx);
+Ip_u3u1u2(_ldx);
/* Handle labels. */
struct uasm_label {
@@ -153,6 +158,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd)
#else
# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
@@ -167,6 +173,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd)
#endif
#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 5742bb4d78f4..5c0a3575877c 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2009 Qi Hardware inc.,
* Author: Xiangfu Liu <xiangfu@qi-hardware.com>
- * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.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 or later
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = {
QI_LB60_GPIO_KEYIN(3),
QI_LB60_GPIO_KEYIN(4),
QI_LB60_GPIO_KEYIN(5),
- QI_LB60_GPIO_KEYIN(7),
+ QI_LB60_GPIO_KEYIN(6),
QI_LB60_GPIO_KEYIN8,
};
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 95bc2b5b14f1..1cc9e544d16b 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = {
/* PCM */
struct platform_device jz4740_pcm_device = {
- .name = "jz4740-pcm",
+ .name = "jz4740-pcm-audio",
.id = -1,
};
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index cfeac15eb2e4..4a70407f55bb 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -23,7 +23,7 @@
#include <asm/bootinfo.h>
#include <asm/mach-jz4740/base.h>
-void jz4740_init_cmdline(int argc, char *argv[])
+static __init void jz4740_init_cmdline(int argc, char *argv[])
{
unsigned int count = COMMAND_LINE_SIZE - 1;
int i;
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 22b2e0e38617..cedee2bcbd18 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
obj-$(CONFIG_OF) += prom.o
@@ -106,4 +107,6 @@ obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 2f4d7a99bcc2..98c5a9737c14 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);
- res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+ res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
return res;
}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 71620e19827a..f65d4c8c65a6 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -739,6 +739,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
&& cpu_has_tlb)
c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+ c->kscratch_mask = (config4 >> 16) & 0xff;
+
return config4 & MIPS_CONF_M;
}
@@ -905,7 +907,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
{
decode_configs(c);
switch (c->processor_id & 0xff00) {
- case PRID_IMP_BMIPS32:
+ case PRID_IMP_BMIPS32_REV4:
+ case PRID_IMP_BMIPS32_REV8:
c->cputype = CPU_BMIPS32;
__cpu_name[cpu] = "Broadcom BMIPS32";
break;
@@ -933,10 +936,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
__cpu_name[cpu] = "Broadcom BMIPS5000";
c->options |= MIPS_CPU_ULRI;
break;
- case PRID_IMP_BMIPS4KC:
- c->cputype = CPU_4KC;
- __cpu_name[cpu] = "MIPS 4Kc";
- break;
}
}
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
new file mode 100644
index 000000000000..6001610cfe55
--- /dev/null
+++ b/arch/mips/kernel/jump_label.c
@@ -0,0 +1,54 @@
+/*
+ * 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) 2010 Cavium Networks, Inc.
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/inst.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+#define J_RANGE_MASK ((1ul << 28) - 1)
+
+void arch_jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ union mips_instruction insn;
+ union mips_instruction *insn_p =
+ (union mips_instruction *)(unsigned long)e->code;
+
+ /* Jump only works within a 256MB aligned region. */
+ BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
+
+ /* Target must have 4 byte alignment. */
+ BUG_ON((e->target & 3) != 0);
+
+ if (type == JUMP_LABEL_ENABLE) {
+ insn.j_format.opcode = j_op;
+ insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
+ } else {
+ insn.word = 0; /* nop */
+ }
+
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn_p = insn;
+
+ flush_icache_range((unsigned long)insn_p,
+ (unsigned long)insn_p + sizeof(*insn_p));
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+#endif /* HAVE_JUMP_LABEL */
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 6343b4a5b835..876a75cc376f 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
{
+ unsigned int p = personality & 0xffffffff;
int ret;
- personality &= 0xffffffff;
+
if (personality(current->personality) == PER_LINUX32 &&
- personality == PER_LINUX)
- personality = PER_LINUX32;
- ret = sys_personality(personality);
- if (ret == PER_LINUX32)
- ret = PER_LINUX;
+ personality(p) == PER_LINUX)
+ p = (p & ~PER_MASK) | PER_LINUX32;
+ ret = sys_personality(p);
+ if (ret != -1 && personality(ret) == PER_LINUX32)
+ ret = (ret & ~PER_MASK) | PER_LINUX;
return ret;
}
diff --git a/arch/mips/kernel/mips_machine.c b/arch/mips/kernel/mips_machine.c
new file mode 100644
index 000000000000..411a058d2c53
--- /dev/null
+++ b/arch/mips/kernel/mips_machine.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/mips_machine.h>
+
+static struct mips_machine *mips_machine __initdata;
+static char *mips_machine_name = "Unknown";
+
+#define for_each_machine(mach) \
+ for ((mach) = (struct mips_machine *)&__mips_machines_start; \
+ (mach) && \
+ (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \
+ (mach)++)
+
+__init void mips_set_machine_name(const char *name)
+{
+ char *p;
+
+ if (name == NULL)
+ return;
+
+ p = kstrdup(name, GFP_KERNEL);
+ if (!p)
+ pr_err("MIPS: no memory for machine_name\n");
+
+ mips_machine_name = p;
+}
+
+char *mips_get_machine_name(void)
+{
+ return mips_machine_name;
+}
+
+__init int mips_machtype_setup(char *id)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mach->mach_id == NULL)
+ continue;
+
+ if (strcmp(mach->mach_id, id) == 0) {
+ mips_machtype = mach->mach_type;
+ return 0;
+ }
+ }
+
+ pr_err("MIPS: no machine found for id '%s', supported machines:\n", id);
+ pr_err("%-24s %s\n", "id", "name");
+ for_each_machine(mach)
+ pr_err("%-24s %s\n", mach->mach_id, mach->mach_name);
+
+ return 1;
+}
+
+__setup("machtype=", mips_machtype_setup);
+
+__init void mips_machine_setup(void)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mips_machtype == mach->mach_type) {
+ mips_machine = mach;
+ break;
+ }
+ }
+
+ if (!mips_machine)
+ return;
+
+ mips_set_machine_name(mips_machine->mach_name);
+ pr_info("MIPS: machine is %s\n", mips_machine_name);
+
+ if (mips_machine->mach_setup)
+ mips_machine->mach_setup();
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 6f51dda87fce..bb9cde4933b4 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -30,6 +30,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/jump_label.h>
+
#include <asm/pgtable.h> /* MODULE_START */
struct mips_hi16 {
@@ -390,6 +392,9 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *s;
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ /* Make jump label nops. */
+ jump_label_apply_nops(me);
+
INIT_LIST_HEAD(&me->arch.dbe_list);
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 26109c4d5170..e309665b6c81 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -12,6 +12,7 @@
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/mips_machine.h>
unsigned int vced_count, vcei_count;
@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/*
* For the first processor also print the system type
*/
- if (n == 0)
+ if (n == 0) {
seq_printf(m, "system type\t\t: %s\n", get_system_type());
+ if (mips_get_machine_name())
+ seq_printf(m, "machine\t\t\t: %s\n",
+ mips_get_machine_name());
+ }
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
@@ -69,6 +74,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
);
seq_printf(m, "shadow register sets\t: %d\n",
cpu_data[n].srsets);
+ seq_printf(m, "kscratch registers\t: %d\n",
+ hweight8(cpu_data[n].kscratch_mask));
seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 99960940d4a4..ae167df73ddd 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs->regs[7] = 0; /* Clear error flag */
childregs->regs[2] = 0; /* Child gets zero as return value */
- regs->regs[2] = p->pid;
if (childregs->cp0_status & ST0_CU0) {
childregs->regs[28] = (unsigned long) ti;
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index e000b278f024..9dbe58368953 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -100,7 +100,7 @@ void __init device_tree_init(void)
return;
base = virt_to_phys((void *)initial_boot_params);
- size = initial_boot_params->totalsize;
+ size = be32_to_cpu(initial_boot_params->totalsize);
/* Before we do anything, lets reserve the dt blob */
reserve_mem_mach(base, size);
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 43e7cdc5ded2..c0e81418ba21 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void)
{
extern int gic_present;
- /* This is Malta specific: IPI,performance and timer inetrrupts */
+ /* This is Malta specific: IPI,performance and timer interrupts */
if (gic_present)
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
STATUSF_IP6 | STATUSF_IP7);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8e9fbe75894e..71350f7f2d88 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void);
extern asmlinkage void handle_reserved(void);
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
- struct mips_fpu_struct *ctx, int has_fpu);
+ struct mips_fpu_struct *ctx, int has_fpu,
+ void *__user *fault_addr);
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs)
force_sig_info(SIGFPE, &info, current);
}
+static int process_fpemu_return(int sig, void __user *fault_addr)
+{
+ if (sig == SIGSEGV || sig == SIGBUS) {
+ struct siginfo si = {0};
+ si.si_addr = fault_addr;
+ si.si_signo = sig;
+ if (sig == SIGSEGV) {
+ if (find_vma(current->mm, (unsigned long)fault_addr))
+ si.si_code = SEGV_ACCERR;
+ else
+ si.si_code = SEGV_MAPERR;
+ } else {
+ si.si_code = BUS_ADRERR;
+ }
+ force_sig_info(sig, &si, current);
+ return 1;
+ } else if (sig) {
+ force_sig(sig, current);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
/*
* XXX Delayed fp exceptions when doing a lazy ctx switch XXX
*/
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{
- siginfo_t info;
+ siginfo_t info = {0};
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
== NOTIFY_STOP)
@@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
if (fcr31 & FPU_CSR_UNI_X) {
int sig;
+ void __user *fault_addr = NULL;
/*
* Unimplemented operation exception. If we've got the full
@@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
lose_fpu(1);
/* Run the emulator */
- sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1);
+ sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
+ &fault_addr);
/*
* We can't allow the emulated instruction to leave any of
@@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
own_fpu(1); /* Using the FPU again. */
/* If something went wrong, signal */
- if (sig)
- force_sig(sig, current);
+ process_fpemu_return(sig, fault_addr);
return;
} else if (fcr31 & FPU_CSR_INV_X)
@@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
if (!raw_cpu_has_fpu) {
int sig;
+ void __user *fault_addr = NULL;
sig = fpu_emulator_cop1Handler(regs,
- &current->thread.fpu, 0);
- if (sig)
- force_sig(sig, current);
- else
+ &current->thread.fpu,
+ 0, &fault_addr);
+ if (!process_fpemu_return(sig, fault_addr))
mt_ase_fp_affinity();
}
@@ -1566,7 +1592,6 @@ void __cpuinit per_cpu_trap_init(void)
#endif /* CONFIG_MIPS_MT_SMTC */
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
- TLBMISS_HANDLER_SETUP();
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
@@ -1588,6 +1613,7 @@ void __cpuinit per_cpu_trap_init(void)
write_c0_wired(0);
}
#endif /* CONFIG_MIPS_MT_SMTC */
+ TLBMISS_HANDLER_SETUP();
}
/* Install CPU exception handler */
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index f25df73db923..570607b376b5 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -98,6 +98,13 @@ SECTIONS
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
+ . = ALIGN(4);
+ .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
+ __mips_machines_start = .;
+ *(.mips.machines.init)
+ __mips_machines_end = .;
+ }
+
/* .exit.text is discarded at runtime, not link time, to deal with
* references from .rodata
*/
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 3eb3cde2f661..6a1fdfef8fde 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp)
/* this of-course trashes what was there before... */
v->pbuffer = vmalloc(P_SIZE);
+ if (!v->pbuffer) {
+ pr_warning("VPE loader: unable to allocate memory\n");
+ return -ENOMEM;
+ }
v->plen = P_SIZE;
v->load_addr = NULL;
v->len = 0;
@@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp)
if (ret < 0)
v->shared_ptr = NULL;
- // cleanup any temp buffers
- if (v->pbuffer)
- vfree(v->pbuffer);
+ vfree(v->pbuffer);
v->plen = 0;
+
return ret;
}
@@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
if (v == NULL)
return -ENODEV;
- if (v->pbuffer == NULL) {
- printk(KERN_ERR "VPE loader: no buffer for program\n");
- return -ENOMEM;
- }
-
if ((count + v->len) > v->plen) {
printk(KERN_WARNING
"VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 77dc3b20110a..606c8a9efe3b 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -161,16 +161,16 @@ FEXPORT(__bzero)
.Lfwd_fixup:
PTR_L t0, TI_TASK($28)
- LONG_L t0, THREAD_BUADDR(t0)
andi a2, 0x3f
+ LONG_L t0, THREAD_BUADDR(t0)
LONG_ADDU a2, t1
jr ra
LONG_SUBU a2, t0
.Lpartial_fixup:
PTR_L t0, TI_TASK($28)
- LONG_L t0, THREAD_BUADDR(t0)
andi a2, LONGMASK
+ LONG_L t0, THREAD_BUADDR(t0)
LONG_ADDU a2, t1
jr ra
LONG_SUBU a2, t0
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
index ae4cff97a56c..11b193f848f8 100644
--- a/arch/mips/loongson/common/env.c
+++ b/arch/mips/loongson/common/env.c
@@ -29,9 +29,9 @@ unsigned long memsize, highmemsize;
#define parse_even_earlier(res, option, p) \
do { \
+ int ret; \
if (strncmp(option, (char *)p, strlen(option)) == 0) \
- strict_strtol((char *)p + strlen(option"="), \
- 10, &res); \
+ ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \
} while (0)
void __init prom_init_env(void)
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index b2ad1b0910ff..d32cb0503110 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
#if __mips >= 4 && __mips != 32
static int fpux_emu(struct pt_regs *,
- struct mips_fpu_struct *, mips_instruction);
+ struct mips_fpu_struct *, mips_instruction, void *__user *);
#endif
/* Further private data for which no space exists in mips_fpu_struct */
@@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp)
* Two instructions if the instruction is in a branch delay slot.
*/
-static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ void *__user *fault_addr)
{
mips_instruction ir;
unsigned long emulpc, contpc;
unsigned int cond;
- if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
return SIGBUS;
}
+ if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
/* XXX NEC Vr54xx bug workaround */
if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
@@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
#endif
return SIGILL;
}
- if (get_user(ir, (mips_instruction __user *) emulpc)) {
+ if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)emulpc;
return SIGBUS;
}
+ if (__get_user(ir, (mips_instruction __user *) emulpc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)emulpc;
+ return SIGSEGV;
+ }
/* __compute_return_epc() will have updated cp0_epc */
contpc = xcp->cp0_epc;
/* In order not to confuse ptrace() et al, tweak context */
@@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
u64 val;
MIPS_FPU_EMU_INC_STATS(loads);
- if (get_user(val, va)) {
+
+ if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
DITOREG(val, MIPSInst_RT(ir));
break;
}
@@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
MIPS_FPU_EMU_INC_STATS(stores);
DIFROMREG(val, MIPSInst_RT(ir));
- if (put_user(val, va)) {
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
break;
}
@@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
u32 val;
MIPS_FPU_EMU_INC_STATS(loads);
- if (get_user(val, va)) {
+ if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
SITOREG(val, MIPSInst_RT(ir));
break;
}
@@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
MIPS_FPU_EMU_INC_STATS(stores);
SIFROMREG(val, MIPSInst_RT(ir));
- if (put_user(val, va)) {
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
break;
}
@@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
contpc = (xcp->cp0_epc +
(MIPSInst_SIMM(ir) << 2));
- if (get_user(ir,
- (mips_instruction __user *) xcp->cp0_epc)) {
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc,
+ sizeof(mips_instruction))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
return SIGBUS;
}
+ if (__get_user(ir,
+ (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
switch (MIPSInst_OPCODE(ir)) {
case lwc1_op:
@@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
#if __mips >= 4 && __mips != 32
case cop1x_op:{
- int sig;
-
- if ((sig = fpux_emu(xcp, ctx, ir)))
+ int sig = fpux_emu(xcp, ctx, ir, fault_addr);
+ if (sig)
return sig;
break;
}
@@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
- mips_instruction ir)
+ mips_instruction ir, void *__user *fault_addr)
{
unsigned rcsr = 0; /* resulting csr */
@@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
xcp->regs[MIPSInst_FT(ir)]);
MIPS_FPU_EMU_INC_STATS(loads);
- if (get_user(val, va)) {
+ if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
SITOREG(val, MIPSInst_FD(ir));
break;
@@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
MIPS_FPU_EMU_INC_STATS(stores);
SIFROMREG(val, MIPSInst_FS(ir));
- if (put_user(val, va)) {
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
break;
case madd_s_op:
@@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
xcp->regs[MIPSInst_FT(ir)]);
MIPS_FPU_EMU_INC_STATS(loads);
- if (get_user(val, va)) {
+ if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
DITOREG(val, MIPSInst_FD(ir));
break;
@@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
MIPS_FPU_EMU_INC_STATS(stores);
DIFROMREG(val, MIPSInst_FS(ir));
- if (put_user(val, va)) {
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
return SIGBUS;
}
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
break;
case madd_d_op:
@@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
}
int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
- int has_fpu)
+ int has_fpu, void *__user *fault_addr)
{
unsigned long oldepc, prevepc;
mips_instruction insn;
@@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
do {
prevepc = xcp->cp0_epc;
- if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
return SIGBUS;
}
+ if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
if (insn == 0)
xcp->cp0_epc += 4; /* skip nops */
else {
@@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
*/
/* convert to ieee library modes */
ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
- sig = cop1Emulate(xcp, ctx);
+ sig = cop1Emulate(xcp, ctx, fault_addr);
/* revert to mips rounding mode */
ieee754_csr.rm = mips_rm[ieee754_csr.rm];
}
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4fc1a0fbe007..21ea14efb837 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask)
return plat_dma_supported(dev, mask);
}
-void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
@@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
__dma_sync((unsigned long)vaddr, size, direction);
}
+EXPORT_SYMBOL(dma_cache_sync);
+
static struct dma_map_ops mips_default_dma_map_ops = {
.alloc_coherent = mips_dma_alloc_coherent,
.free_coherent = mips_dma_free_coherent,
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 505fecad4684..9cca8de00545 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
*/
static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
{
+ unsigned int config2 = read_c0_config2();
+ unsigned int tmp;
+
/* Check the bypass bit (L2B) */
switch (c->cputype) {
case CPU_34K:
@@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
c->scache.linesz = 2 << tmp;
else
return 0;
+ return 1;
}
static inline int __init mips_sc_probe(void)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 93816f3bca67..083d3412d0bc 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -26,8 +26,10 @@
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/cache.h>
-#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
#include <asm/war.h>
#include <asm/uasm.h>
@@ -63,6 +65,52 @@ static inline int __maybe_unused r10000_llsc_war(void)
return R10000_LLSC_WAR;
}
+static int use_bbit_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int use_lwx_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+#if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+static bool scratchpad_available(void)
+{
+ return true;
+}
+static int scratchpad_offset(int i)
+{
+ /*
+ * CVMSEG starts at address -32768 and extends for
+ * CAVIUM_OCTEON_CVMSEG_SIZE 128 byte cache lines.
+ */
+ i += 1; /* Kernel use starts at the top and works down. */
+ return CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128 - (8 * i) - 32768;
+}
+#else
+static bool scratchpad_available(void)
+{
+ return false;
+}
+static int scratchpad_offset(int i)
+{
+ BUG();
+}
+#endif
/*
* Found by experiment: At least some revisions of the 4kc throw under
* some circumstances a machine check exception, triggered by invalid
@@ -173,11 +221,41 @@ static struct uasm_reloc relocs[128] __cpuinitdata;
static int check_for_high_segbits __cpuinitdata;
#endif
+static int check_for_high_segbits __cpuinitdata;
+
+static unsigned int kscratch_used_mask __cpuinitdata;
+
+static int __cpuinit allocate_kscratch(void)
+{
+ int r;
+ unsigned int a = cpu_data[0].kscratch_mask & ~kscratch_used_mask;
+
+ r = ffs(a);
+
+ if (r == 0)
+ return -1;
+
+ r--; /* make it zero based */
+
+ kscratch_used_mask |= (1 << r);
+
+ return r;
+}
+
+static int scratch_reg __cpuinitdata;
+static int pgd_reg __cpuinitdata;
+enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch};
+
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
/*
* CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
* we cannot do r3000 under these circumstances.
+ *
+ * Declare pgd_current here instead of including mmu_context.h to avoid type
+ * conflicts for tlbmiss_handler_setup_pgd
*/
+extern unsigned long pgd_current[];
/*
* The R3000 TLB handler is simple.
@@ -440,21 +518,43 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
static __cpuinit void build_restore_pagemask(u32 **p,
struct uasm_reloc **r,
unsigned int tmp,
- enum label_id lid)
+ enum label_id lid,
+ int restore_scratch)
{
- /* Reset default page size */
- if (PM_DEFAULT_MASK >> 16) {
- uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
- uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, tmp, C0_PAGEMASK);
- } else if (PM_DEFAULT_MASK) {
- uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ if (restore_scratch) {
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else {
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ }
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else {
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else {
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ }
}
}
@@ -462,7 +562,8 @@ static __cpuinit void build_huge_tlb_write_entry(u32 **p,
struct uasm_label **l,
struct uasm_reloc **r,
unsigned int tmp,
- enum tlb_write_entry wmode)
+ enum tlb_write_entry wmode,
+ int restore_scratch)
{
/* Set huge page tlb entry size */
uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
@@ -471,7 +572,7 @@ static __cpuinit void build_huge_tlb_write_entry(u32 **p,
build_tlb_write_entry(p, l, r, wmode);
- build_restore_pagemask(p, r, tmp, label_leave);
+ build_restore_pagemask(p, r, tmp, label_leave, restore_scratch);
}
/*
@@ -482,8 +583,12 @@ build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
unsigned int pmd, int lid)
{
UASM_i_LW(p, tmp, 0, pmd);
- uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
- uasm_il_bnez(p, r, tmp, lid);
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);
+ } else {
+ uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
+ uasm_il_bnez(p, r, tmp, lid);
+ }
}
static __cpuinit void build_huge_update_entries(u32 **p,
@@ -532,7 +637,7 @@ static __cpuinit void build_huge_handler_tail(u32 **p,
UASM_i_SW(p, pte, 0, ptr);
#endif
build_huge_update_entries(p, pte, ptr);
- build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed);
+ build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0);
}
#endif /* CONFIG_HUGETLB_PAGE */
@@ -573,13 +678,22 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
- /*
- * &pgd << 11 stored in CONTEXT [23..63].
- */
- UASM_i_MFC0(p, ptr, C0_CONTEXT);
- uasm_i_dins(p, ptr, 0, 0, 23); /* Clear lower 23 bits of context. */
- uasm_i_ori(p, ptr, ptr, 0x540); /* 1 0 1 0 1 << 6 xkphys cached */
- uasm_i_drotr(p, ptr, ptr, 11);
+ if (pgd_reg != -1) {
+ /* pgd is in pgd_reg */
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ } else {
+ /*
+ * &pgd << 11 stored in CONTEXT [23..63].
+ */
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
#elif defined(CONFIG_SMP)
# ifdef CONFIG_MIPS_MT_SMTC
/*
@@ -620,7 +734,6 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
#endif
}
-enum vmalloc64_mode {not_refill, refill};
/*
* BVADDR is the faulting address, PTR is scratch.
* PTR will hold the pgd for vmalloc.
@@ -638,7 +751,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_l_vmalloc(l, *p);
- if (mode == refill && check_for_high_segbits) {
+ if (mode != not_refill && check_for_high_segbits) {
if (single_insn_swpd) {
uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
@@ -661,7 +774,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
}
}
- if (mode == refill && check_for_high_segbits) {
+ if (mode != not_refill && check_for_high_segbits) {
uasm_l_large_segbits_fault(l, *p);
/*
* We get here if we are an xsseg address, or if we are
@@ -677,7 +790,15 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
*/
UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
uasm_i_jr(p, ptr);
- uasm_i_nop(p);
+
+ if (mode == refill_scratch) {
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
+ } else {
+ uasm_i_nop(p);
+ }
}
}
@@ -834,6 +955,185 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
#endif
}
+struct mips_huge_tlb_info {
+ int huge_pte;
+ int restore_scratch;
+};
+
+static struct mips_huge_tlb_info __cpuinit
+build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
+ unsigned int ptr, int c0_scratch)
+{
+ struct mips_huge_tlb_info rv;
+ unsigned int even, odd;
+ int vmalloc_branch_delay_filled = 0;
+ const int scratch = 1; /* Our extra working register */
+
+ rv.huge_pte = scratch;
+ rv.restore_scratch = 0;
+
+ if (check_for_high_segbits) {
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ uasm_i_dsrl_safe(p, scratch, tmp,
+ PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+ uasm_il_bnez(p, r, scratch, label_vmalloc);
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+ }
+ } else {
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ if (pgd_reg == -1)
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
+ }
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
+
+#ifdef __PAGETABLE_PMD_FOLDED
+#define LOC_PTEP scratch
+#else
+#define LOC_PTEP ptr
+#endif
+
+ if (!vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+ uasm_l_vmalloc_done(l, *p);
+
+ /*
+ * tmp ptr
+ * fall-through case = badvaddr *pgd_current
+ * vmalloc case = badvaddr swapper_pg_dir
+ */
+
+ if (vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+#ifdef __PAGETABLE_PMD_FOLDED
+ GET_CONTEXT(p, tmp); /* get context reg */
+#endif
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PGD - 1) << 3);
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, LOC_PTEP, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pgd offset */
+ uasm_i_ld(p, LOC_PTEP, 0, ptr); /* get pmd pointer */
+ }
+
+#ifndef __PAGETABLE_PMD_FOLDED
+ /* get pmd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PMD_SHIFT - 3);
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PMD - 1) << 3);
+ GET_CONTEXT(p, tmp); /* get context reg */
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, scratch, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pmd offset */
+ UASM_i_LW(p, scratch, 0, ptr);
+ }
+#endif
+ /* Adjust the context during the load latency. */
+ build_adjust_context(p, tmp);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ uasm_il_bbit1(p, r, scratch, ilog2(_PAGE_HUGE), label_tlb_huge_update);
+ /*
+ * The in the LWX case we don't want to do the load in the
+ * delay slot. It cannot issue in the same cycle and may be
+ * speculative and unneeded.
+ */
+ if (use_lwx_insns())
+ uasm_i_nop(p);
+#endif /* CONFIG_HUGETLB_PAGE */
+
+
+ /* build_update_entries */
+ if (use_lwx_insns()) {
+ even = ptr;
+ odd = tmp;
+ UASM_i_LWX(p, even, scratch, tmp);
+ UASM_i_ADDIU(p, tmp, tmp, sizeof(pte_t));
+ UASM_i_LWX(p, odd, scratch, tmp);
+ } else {
+ UASM_i_ADDU(p, ptr, scratch, tmp); /* add in offset */
+ even = tmp;
+ odd = ptr;
+ UASM_i_LW(p, even, 0, ptr); /* get even pte */
+ UASM_i_LW(p, odd, sizeof(pte_t), ptr); /* get odd pte */
+ }
+ if (kernel_uses_smartmips_rixi) {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_NO_EXEC));
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_NO_EXEC));
+ uasm_i_drotr(p, even, even,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_drotr(p, odd, odd,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_GLOBAL));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_GLOBAL));
+ }
+ UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
+
+ if (c0_scratch >= 0) {
+ UASM_i_MFC0(p, scratch, 31, c0_scratch);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ } else if (PAGE_SHIFT == 14 || PAGE_SHIFT == 13) {
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ } else {
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ }
+
+ uasm_i_eret(p); /* return from trap */
+
+ return rv;
+}
+
/*
* For a 64-bit kernel, we are using the 64-bit XTLB refill exception
* because EXL == 0. If we wrap, we can also use the 32 instruction
@@ -849,54 +1149,67 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
struct uasm_reloc *r = relocs;
u32 *f;
unsigned int final_len;
+ struct mips_huge_tlb_info htlb_info;
+ enum vmalloc64_mode vmalloc_mode;
memset(tlb_handler, 0, sizeof(tlb_handler));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler));
- /*
- * create the plain linear handler
- */
- if (bcm1250_m3_war()) {
- unsigned int segbits = 44;
+ if (scratch_reg == 0)
+ scratch_reg = allocate_kscratch();
- uasm_i_dmfc0(&p, K0, C0_BADVADDR);
- uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
- uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
- uasm_i_or(&p, K0, K0, K1);
- uasm_il_bnez(&p, &r, K0, label_leave);
- /* No need for uasm_i_nop */
- }
+ if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+ htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
+ scratch_reg);
+ vmalloc_mode = refill_scratch;
+ } else {
+ htlb_info.huge_pte = K0;
+ htlb_info.restore_scratch = 0;
+ vmalloc_mode = refill_noscratch;
+ /*
+ * create the plain linear handler
+ */
+ if (bcm1250_m3_war()) {
+ 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_dsrl_safe(&p, K1, K0, 62);
+ uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+ uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, K0, K0, K1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
+ }
#ifdef CONFIG_64BIT
- build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
#else
- build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
#endif
#ifdef CONFIG_HUGETLB_PAGE
- build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+ build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
#endif
- build_get_ptep(&p, K0, K1);
- build_update_entries(&p, K0, K1);
- build_tlb_write_entry(&p, &l, &r, tlb_random);
- uasm_l_leave(&l, p);
- uasm_i_eret(&p); /* return from trap */
-
+ build_get_ptep(&p, K0, K1);
+ build_update_entries(&p, K0, K1);
+ build_tlb_write_entry(&p, &l, &r, tlb_random);
+ uasm_l_leave(&l, p);
+ uasm_i_eret(&p); /* return from trap */
+ }
#ifdef CONFIG_HUGETLB_PAGE
uasm_l_tlb_huge_update(&l, p);
- UASM_i_LW(&p, K0, 0, K1);
- build_huge_update_entries(&p, K0, K1);
- build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random);
+ build_huge_update_entries(&p, htlb_info.huge_pte, K1);
+ build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
+ htlb_info.restore_scratch);
#endif
#ifdef CONFIG_64BIT
- build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
+ build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, vmalloc_mode);
#endif
/*
@@ -1014,6 +1327,55 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+u32 tlbmiss_handler_setup_pgd[16] __cacheline_aligned;
+
+static void __cpuinit build_r4000_setup_pgd(void)
+{
+ const int a0 = 4;
+ const int a1 = 5;
+ u32 *p = tlbmiss_handler_setup_pgd;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(tlbmiss_handler_setup_pgd, 0, sizeof(tlbmiss_handler_setup_pgd));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ pgd_reg = allocate_kscratch();
+
+ if (pgd_reg == -1) {
+ /* PGD << 11 in c0_Context */
+ /*
+ * If it is a ckseg0 address, convert to a physical
+ * address. Shifting right by 29 and adding 4 will
+ * result in zero for these addresses.
+ *
+ */
+ UASM_i_SRA(&p, a1, a0, 29);
+ UASM_i_ADDIU(&p, a1, a1, 4);
+ uasm_il_bnez(&p, &r, a1, label_tlbl_goaround1);
+ uasm_i_nop(&p);
+ uasm_i_dinsm(&p, a0, 0, 29, 64 - 29);
+ uasm_l_tlbl_goaround1(&l, p);
+ UASM_i_SLL(&p, a0, a0, 11);
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, C0_CONTEXT);
+ } else {
+ /* PGD in c0_KScratch */
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, 31, pgd_reg);
+ }
+ if (p - tlbmiss_handler_setup_pgd > ARRAY_SIZE(tlbmiss_handler_setup_pgd))
+ panic("tlbmiss_handler_setup_pgd space exceeded");
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
+ (unsigned int)(p - tlbmiss_handler_setup_pgd));
+
+ dump_handler(tlbmiss_handler_setup_pgd,
+ ARRAY_SIZE(tlbmiss_handler_setup_pgd));
+}
+#endif
static void __cpuinit
iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
@@ -1100,14 +1462,20 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
if (kernel_uses_smartmips_rixi) {
- uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
- uasm_il_beqz(p, r, pte, lid);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
} else {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
}
- iPTE_LW(p, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
@@ -1128,10 +1496,17 @@ static void __cpuinit
build_pte_writable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- uasm_il_bnez(p, r, pte, lid);
- iPTE_LW(p, pte, ptr);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
}
/* Make PTE writable, update software status bits as well, then store
@@ -1155,12 +1530,19 @@ static void __cpuinit
build_pte_modifiable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- uasm_i_andi(p, pte, pte, _PAGE_WRITE);
- uasm_il_beqz(p, r, pte, lid);
- iPTE_LW(p, pte, ptr);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_WRITE);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
}
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
+
/*
* R3000 style TLB load/store/modify handlers.
*/
@@ -1402,14 +1784,23 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
- uasm_i_andi(&p, K0, K0, _PAGE_VALID);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround1);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+ }
uasm_i_nop(&p);
uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
- uasm_i_andi(&p, K0, K1, sizeof(pte_t));
- uasm_i_beqz(&p, K0, 8);
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
@@ -1417,12 +1808,18 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
- uasm_i_andi(&p, K0, K0, 2);
- uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
-
- uasm_l_tlbl_goaround1(&l, p);
- /* Reload the PTE value */
- iPTE_LW(&p, K0, K1);
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(&p, &r, K0, 1, label_nopage_tlbl);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ uasm_l_tlbl_goaround1(&l, p);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
+ uasm_l_tlbl_goaround1(&l, p);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ }
}
build_make_valid(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
@@ -1442,23 +1839,35 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
- uasm_i_andi(&p, K0, K0, _PAGE_VALID);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
uasm_i_nop(&p);
uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
- uasm_i_andi(&p, K0, K1, sizeof(pte_t));
- uasm_i_beqz(&p, K0, 8);
-
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
/*
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
- uasm_i_andi(&p, K0, K0, 2);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, 1, label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);
@@ -1466,7 +1875,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* We clobbered C0_PAGEMASK, restore it. On the other branch
* it is restored in build_huge_tlb_write_entry.
*/
- build_restore_pagemask(&p, &r, K0, label_nopage_tlbl);
+ build_restore_pagemask(&p, &r, K0, label_nopage_tlbl, 0);
uasm_l_tlbl_goaround2(&l, p);
}
@@ -1623,13 +2032,16 @@ void __cpuinit build_tlb_refill_handler(void)
break;
default:
- build_r4000_tlb_refill_handler();
if (!run_once) {
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ build_r4000_setup_pgd();
+#endif
build_r4000_tlb_load_handler();
build_r4000_tlb_store_handler();
build_r4000_tlb_modify_handler();
run_once++;
}
+ build_r4000_tlb_refill_handler();
}
}
@@ -1641,4 +2053,8 @@ void __cpuinit flush_tlb_handlers(void)
(unsigned long)handle_tlbs + sizeof(handle_tlbs));
local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm + sizeof(handle_tlbm));
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
+ (unsigned long)tlbmiss_handler_setup_pgd + sizeof(handle_tlbm));
+#endif
}
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 23afdebc8e5c..5fa185151fc8 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -68,7 +68,8 @@ enum opcode {
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_syscall, insn_bbit0, insn_bbit1
+ insn_dins, insn_dinsm, insn_syscall, insn_bbit0, insn_bbit1,
+ insn_lwx, insn_ldx
};
struct insn {
@@ -142,9 +143,12 @@ static struct insn insn_table[] __uasminitdata = {
{ 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_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
{ insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
{ insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
+ { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
{ insn_invalid, 0, 0 }
};
@@ -152,91 +156,83 @@ static struct insn insn_table[] __uasminitdata = {
static inline __uasminit u32 build_rs(u32 arg)
{
- if (arg & ~RS_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RS_MASK) << RS_SH;
}
static inline __uasminit u32 build_rt(u32 arg)
{
- if (arg & ~RT_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RT_MASK) << RT_SH;
}
static inline __uasminit u32 build_rd(u32 arg)
{
- if (arg & ~RD_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RD_MASK) << RD_SH;
}
static inline __uasminit u32 build_re(u32 arg)
{
- if (arg & ~RE_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RE_MASK) << RE_SH;
}
static inline __uasminit u32 build_simm(s32 arg)
{
- if (arg > 0x7fff || arg < -0x8000)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg > 0x7fff || arg < -0x8000,
+ KERN_WARNING "Micro-assembler field overflow\n");
return arg & 0xffff;
}
static inline __uasminit u32 build_uimm(u32 arg)
{
- if (arg & ~IMM_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & IMM_MASK;
}
static inline __uasminit u32 build_bimm(s32 arg)
{
- if (arg > 0x1ffff || arg < -0x20000)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg > 0x1ffff || arg < -0x20000,
+ KERN_WARNING "Micro-assembler field overflow\n");
- if (arg & 0x3)
- printk(KERN_WARNING "Invalid micro-assembler branch target\n");
+ WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n");
return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
}
static inline __uasminit u32 build_jimm(u32 arg)
{
- if (arg & ~((JIMM_MASK) << 2))
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~(JIMM_MASK << 2),
+ KERN_WARNING "Micro-assembler field overflow\n");
return (arg >> 2) & JIMM_MASK;
}
static inline __uasminit u32 build_scimm(u32 arg)
{
- if (arg & ~SCIMM_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~SCIMM_MASK,
+ KERN_WARNING "Micro-assembler field overflow\n");
return (arg & SCIMM_MASK) << SCIMM_SH;
}
static inline __uasminit u32 build_func(u32 arg)
{
- if (arg & ~FUNC_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & FUNC_MASK;
}
static inline __uasminit u32 build_set(u32 arg)
{
- if (arg & ~SET_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & SET_MASK;
}
@@ -340,6 +336,13 @@ Ip_u2u1msbu3(op) \
} \
UASM_EXPORT_SYMBOL(uasm_i##op);
+#define I_u2u1msb32u3(op) \
+Ip_u2u1msbu3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c+d-33, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
#define I_u1u2(op) \
Ip_u1u2(op) \
{ \
@@ -422,9 +425,12 @@ I_0(_tlbwr)
I_u3u1u2(_xor)
I_u2u1u3(_xori)
I_u2u1msbu3(_dins);
+I_u2u1msb32u3(_dinsm);
I_u1(_syscall);
I_u1u2s3(_bbit0);
I_u1u2s3(_bbit1);
+I_u3u1u2(_lwx)
+I_u3u1u2(_ldx)
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#include <asm/octeon/octeon.h>
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
index b7f1d9c4a8a3..434d7b1a8c6a 100644
--- a/arch/mips/pmc-sierra/yosemite/py-console.c
+++ b/arch/mips/pmc-sierra/yosemite/py-console.c
@@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys)
__asm__ __volatile__ (
" .set mips3 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set nomacro \n"
" ld %0, %1 \n"
+ " .set pop \n"
" lbu %0, (%0) \n"
" .set mips0 \n"
: "=r" (res)
- : "m" (vaddr));
+ : "R" (vaddr));
write_c0_status(sr);
ssnop_4();
@@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
__asm__ __volatile__ (
" .set mips3 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set nomacro \n"
" ld %0, %1 \n"
+ " .set pop \n"
" sb %2, (%0) \n"
" .set mips0 \n"
: "=&r" (tmp)
- : "m" (vaddr), "r" (c));
+ : "R" (vaddr), "r" (c));
write_c0_status(sr);
ssnop_4();
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 87ccdb4b5ac9..48853ab5bcf0 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -410,14 +410,13 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp)
return -EBUSY;
memset(&sbp, 0, sizeof(struct sbprof_tb));
- sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
+ sbp.sbprof_tbbuf = vzalloc(MAX_TBSAMPLE_BYTES);
if (!sbp.sbprof_tbbuf) {
sbp.open = SB_CLOSED;
wmb();
return -ENOMEM;
}
- memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
init_waitqueue_head(&sbp.tb_sync);
init_waitqueue_head(&sbp.tb_read);
mutex_init(&sbp.lock);
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index c308989fc464..41707a245dea 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
enum swarm_rtc_type {
RTC_NONE,
RTC_XICOR,
- RTC_M4LT81
+ RTC_M41T81,
};
enum swarm_rtc_type swarm_rtc_type;
@@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts)
sec = xicor_get_time();
break;
- case RTC_M4LT81:
+ case RTC_M41T81:
sec = m41t81_get_time();
break;
@@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec)
case RTC_XICOR:
return xicor_set_time(sec);
- case RTC_M4LT81:
+ case RTC_M41T81:
return m41t81_set_time(sec);
case RTC_NONE:
@@ -141,7 +141,7 @@ void __init plat_mem_setup(void)
if (xicor_probe())
swarm_rtc_type = RTC_XICOR;
if (m41t81_probe())
- swarm_rtc_type = RTC_M4LT81;
+ swarm_rtc_type = RTC_M41T81;
#ifdef CONFIG_VT
screen_info = (struct screen_info) {
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 9a0be810cafa..c609e7bd2cf5 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -213,11 +213,8 @@ txx9_alloc_pci_controller(struct pci_controller *pcic,
pcic->mem_offset = 0; /* busaddr == physaddr */
- printk(KERN_INFO "PCI: IO 0x%08llx-0x%08llx MEM 0x%08llx-0x%08llx\n",
- (unsigned long long)pcic->mem_resource[1].start,
- (unsigned long long)pcic->mem_resource[1].end,
- (unsigned long long)pcic->mem_resource[0].start,
- (unsigned long long)pcic->mem_resource[0].end);
+ printk(KERN_INFO "PCI: IO %pR MEM %pR\n",
+ &pcic->mem_resource[1], &pcic->mem_resource[0]);
/* register_pci_controller() will request MEM resource */
release_resource(&pcic->mem_resource[0]);
diff --git a/arch/mn10300/include/asm/syscall.h b/arch/mn10300/include/asm/syscall.h
new file mode 100644
index 000000000000..b44b0bb75a01
--- /dev/null
+++ b/arch/mn10300/include/asm/syscall.h
@@ -0,0 +1,117 @@
+/* Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2010 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/sched.h>
+#include <linux/err.h>
+
+extern const unsigned long sys_call_table[];
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->orig_d0;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ regs->d0 = regs->orig_d0;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ unsigned long error = regs->d0;
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->d0;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ regs->d0 = (long) error ?: val;
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ switch (i) {
+ case 0:
+ if (!n--) break;
+ *args++ = regs->a0;
+ case 1:
+ if (!n--) break;
+ *args++ = regs->d1;
+ case 2:
+ if (!n--) break;
+ *args++ = regs->a3;
+ case 3:
+ if (!n--) break;
+ *args++ = regs->a2;
+ case 4:
+ if (!n--) break;
+ *args++ = regs->d3;
+ case 5:
+ if (!n--) break;
+ *args++ = regs->d2;
+ case 6:
+ if (!n--) break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ switch (i) {
+ case 0:
+ if (!n--) break;
+ regs->a0 = *args++;
+ case 1:
+ if (!n--) break;
+ regs->d1 = *args++;
+ case 2:
+ if (!n--) break;
+ regs->a3 = *args++;
+ case 3:
+ if (!n--) break;
+ regs->a2 = *args++;
+ case 4:
+ if (!n--) break;
+ regs->d3 = *args++;
+ case 5:
+ if (!n--) break;
+ regs->d2 = *args++;
+ case 6:
+ if (!n--) break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+#endif /* _ASM_SYSCALL_H */
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c
index 0d5d63c91dc3..f28dc99c6f72 100644
--- a/arch/mn10300/kernel/gdb-io-serial.c
+++ b/arch/mn10300/kernel/gdb-io-serial.c
@@ -73,7 +73,8 @@ void gdbstub_io_init(void)
GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
/* permit level 0 IRQs to take place */
- local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+ arch_local_change_intr_mask_level(
+ NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
}
/*
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index 97dfda23342c..abdeea153c89 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -87,7 +87,8 @@ void __init gdbstub_io_init(void)
tmp = *gdbstub_port->_control;
/* permit level 0 IRQs only */
- local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+ arch_local_change_intr_mask_level(
+ NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
}
/*
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index a5fc3f05309b..b169d99d9f20 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
asm volatile("mov mdr,%0" : "=d"(mdr));
local_save_flags(epsw);
- local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+ arch_local_change_intr_mask_level(
+ NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
gdbstub_store_fpu();
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index c2e44597c22b..ac11754ecec5 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -459,7 +459,7 @@ void migrate_irqs(void)
tmp = CROSS_GxICR(irq, new);
x &= GxICR_LEVEL | GxICR_ENABLE;
- if (GxICR(irq) & GxICR_REQUEST) {
+ if (GxICR(irq) & GxICR_REQUEST)
x |= GxICR_REQUEST | GxICR_DETECT;
CROSS_GxICR(irq, new) = x;
tmp = CROSS_GxICR(irq, new);
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index f860a340acc9..75da468090b9 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
unsigned long long ll;
unsigned l[2];
} tsc64, result;
- unsigned long tsc, tmp;
+ unsigned long tmp;
unsigned product[3]; /* 96-bit intermediate value */
/* cnt32_to_63() is not safe with preemption */
preempt_disable();
- /* read the TSC value
- */
- tsc = get_cycles();
-
- /* expand to 64-bits.
+ /* expand the tsc to 64-bits.
* - sched_clock() must be called once a minute or better or the
* following will go horribly wrong - see cnt32_to_63()
*/
- tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
+ tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
preempt_enable();
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 5024f643b3b1..d7d94b845dc2 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -75,9 +75,6 @@ static void cpu_unmask_irq(unsigned int irq)
smp_send_all_nop();
}
-void no_ack_irq(unsigned int irq) { }
-void no_end_irq(unsigned int irq) { }
-
void cpu_ack_irq(unsigned int irq)
{
unsigned long mask = EIEM_MASK(irq);
@@ -241,7 +238,7 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
/* for iosapic interrupts */
if (type) {
- set_irq_chip_and_handler(irq, type, handle_level_irq);
+ set_irq_chip_and_handler(irq, type, handle_percpu_irq);
set_irq_chip_data(irq, data);
cpu_unmask_irq(irq);
}
@@ -392,7 +389,7 @@ static void claim_cpu_irqs(void)
int i;
for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
set_irq_chip_and_handler(i, &cpu_interrupt_type,
- handle_level_irq);
+ handle_percpu_irq);
}
set_irq_handler(TIMER_IRQ, handle_percpu_irq);
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 35c827e94e31..609a331878e7 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -98,7 +98,6 @@ void
sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
{
struct rt_sigframe __user *frame;
- struct siginfo si;
sigset_t set;
unsigned long usp = (regs->gr[30] & ~(0x01UL));
unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
@@ -178,13 +177,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
give_sigsegv:
DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
- si.si_signo = SIGSEGV;
- si.si_errno = 0;
- si.si_code = SI_KERNEL;
- si.si_pid = task_pid_vnr(current);
- si.si_uid = current_uid();
- si.si_addr = &frame->uc;
- force_sig_info(SIGSEGV, &si, current);
+ force_sig(SIGSEGV, current);
return;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e625e9e034ae..e16b4988f825 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -20,6 +20,9 @@ config WORD_SIZE
config ARCH_PHYS_ADDR_T_64BIT
def_bool PPC64 || PHYS_64BIT
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool ARCH_PHYS_ADDR_T_64BIT
+
config MMU
bool
default y
@@ -209,7 +212,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- PPC_85xx || PPC_86xx || PPC_PSERIES
+ PPC_85xx || PPC_86xx || PPC_PSERIES || 44x || 40x
config PPC_DCR_NATIVE
bool
@@ -595,13 +598,11 @@ config EXTRA_TARGETS
If unsure, leave blank
-if !44x || BROKEN
config ARCH_WANTS_FREEZER_CONTROL
def_bool y
depends on ADB_PMU
source kernel/power/Kconfig
-endif
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
@@ -682,6 +683,15 @@ config FSL_PMC
Freescale MPC85xx/MPC86xx power management controller support
(suspend/resume). For MPC83xx see platforms/83xx/suspend.c
+config PPC4xx_CPM
+ bool
+ default y
+ depends on SUSPEND && (44x || 40x)
+ help
+ PPC4xx Clock Power Management (CPM) support (suspend/resume).
+ It also enables support for two different idle states (idle-wait
+ and idle-doze).
+
config 4xx_SOC
bool
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index a30370396250..5b27a4b74b79 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -105,6 +105,15 @@
dcr-reg = <0x00c 0x002>;
};
+ CPM0: cpm {
+ compatible = "ibm,cpm";
+ dcr-access-method = "native";
+ dcr-reg = <0x160 0x003>;
+ unused-units = <0x00000100>;
+ idle-doze = <0x02000000>;
+ standby = <0xfeff791d>;
+ };
+
L2C0: l2c {
compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";
dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */
@@ -270,28 +279,6 @@
interrupts = <0x1 0x4>;
};
- UART2: serial@ef600500 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600500 0x00000008>;
- virtual-reg = <0xef600500>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>; /* Filled in by U-Boot */
- interrupt-parent = <&UIC1>;
- interrupts = <28 0x4>;
- };
-
- UART3: serial@ef600600 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0xef600600 0x00000008>;
- virtual-reg = <0xef600600>;
- clock-frequency = <0>; /* Filled in by U-Boot */
- current-speed = <0>; /* Filled in by U-Boot */
- interrupt-parent = <&UIC1>;
- interrupts = <29 0x4>;
- };
-
IIC0: i2c@ef600700 {
compatible = "ibm,iic-460ex", "ibm,iic";
reg = <0xef600700 0x00000014>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 083e68eeaca4..89edb16649c3 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -82,6 +82,15 @@
interrupt-parent = <&UIC0>;
};
+ CPM0: cpm {
+ compatible = "ibm,cpm";
+ dcr-access-method = "native";
+ dcr-reg = <0x0b0 0x003>;
+ unused-units = <0x00000000>;
+ idle-doze = <0x02000000>;
+ standby = <0xe3e74800>;
+ };
+
plb {
compatible = "ibm,plb-405ex", "ibm,plb4";
#address-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8308_p1m.dts b/arch/powerpc/boot/dts/mpc8308_p1m.dts
index 05a76ccfd499..697b3f6b78bf 100644
--- a/arch/powerpc/boot/dts/mpc8308_p1m.dts
+++ b/arch/powerpc/boot/dts/mpc8308_p1m.dts
@@ -297,6 +297,14 @@
interrupt-parent = < &ipic >;
};
+ dma@2c000 {
+ compatible = "fsl,mpc8308-dma", "fsl,mpc5121-dma";
+ reg = <0x2c000 0x1800>;
+ interrupts = <3 0x8
+ 94 0x8>;
+ interrupt-parent = < &ipic >;
+ };
+
};
pci0: pcie@e0009000 {
diff --git a/arch/powerpc/boot/dts/mpc8308rdb.dts b/arch/powerpc/boot/dts/mpc8308rdb.dts
index a97eb2db5a18..d3db02f98ddd 100644
--- a/arch/powerpc/boot/dts/mpc8308rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8308rdb.dts
@@ -265,6 +265,14 @@
interrupt-parent = < &ipic >;
};
+ dma@2c000 {
+ compatible = "fsl,mpc8308-dma", "fsl,mpc5121-dma";
+ reg = <0x2c000 0x1800>;
+ interrupts = <3 0x8
+ 94 0x8>;
+ interrupt-parent = < &ipic >;
+ };
+
};
pci0: pcie@e0009000 {
diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig
index 4e19ee7ce4ee..34b8c1a1e752 100644
--- a/arch/powerpc/configs/40x/kilauea_defconfig
+++ b/arch/powerpc/configs/40x/kilauea_defconfig
@@ -12,6 +12,8 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_KILAUEA=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
# CONFIG_WALNUT is not set
CONFIG_SPARSE_IRQ=y
CONFIG_PCI=y
@@ -42,6 +44,9 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_NDFC=y
CONFIG_PROC_DEVICETREE=y
+CONFIG_PM=y
+CONFIG_SUSPEND=y
+CONFIG_PPC4xx_CPM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=35000
# CONFIG_MISC_DEVICES is not set
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig
index 45c64d818b2a..17e4dd98eed7 100644
--- a/arch/powerpc/configs/44x/canyonlands_defconfig
+++ b/arch/powerpc/configs/44x/canyonlands_defconfig
@@ -42,6 +42,9 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_NDFC=y
CONFIG_PROC_DEVICETREE=y
+CONFIG_PM=y
+CONFIG_SUSPEND=y
+CONFIG_PPC4xx_CPM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=35000
# CONFIG_MISC_DEVICES is not set
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 30964ae2d096..8a7e9314c68a 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -267,7 +267,16 @@ static __inline__ int fls64(__u64 x)
#include <asm-generic/bitops/fls64.h>
#endif /* __powerpc64__ */
+#ifdef CONFIG_PPC64
+unsigned int __arch_hweight8(unsigned int w);
+unsigned int __arch_hweight16(unsigned int w);
+unsigned int __arch_hweight32(unsigned int w);
+unsigned long __arch_hweight64(__u64 w);
+#include <asm-generic/bitops/const_hweight.h>
+#else
#include <asm-generic/bitops/hweight.h>
+#endif
+
#include <asm-generic/bitops/find.h>
/* Little-endian versions */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index f3a1fdd9cf08..f0a211d96923 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -199,6 +199,8 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000)
#define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0100000000000000)
#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0200000000000000)
+#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0400000000000000)
+#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000)
#ifndef __ASSEMBLY__
@@ -403,21 +405,22 @@ extern const char *powerpc_base_platform;
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
- CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS)
+ CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS | \
+ CPU_FTR_POPCNTB)
#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
- CPU_FTR_STCX_CHECKS_ADDRESS)
+ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
- CPU_FTR_STCX_CHECKS_ADDRESS)
+ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h
index a8e18447c62b..f71bb4c118b4 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -61,22 +61,25 @@ static inline cpumask_t cpu_online_cores_map(void)
return cpu_thread_mask_to_cores(cpu_online_map);
}
-static inline int cpu_thread_to_core(int cpu)
-{
- return cpu >> threads_shift;
-}
+#ifdef CONFIG_SMP
+int cpu_core_index_of_thread(int cpu);
+int cpu_first_thread_of_core(int core);
+#else
+static inline int cpu_core_index_of_thread(int cpu) { return cpu; }
+static inline int cpu_first_thread_of_core(int core) { return core; }
+#endif
static inline int cpu_thread_in_core(int cpu)
{
return cpu & (threads_per_core - 1);
}
-static inline int cpu_first_thread_in_core(int cpu)
+static inline int cpu_first_thread_sibling(int cpu)
{
return cpu & ~(threads_per_core - 1);
}
-static inline int cpu_last_thread_in_core(int cpu)
+static inline int cpu_last_thread_sibling(int cpu)
{
return cpu | (threads_per_core - 1);
}
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index a3954e4fcbe2..16d25c0974be 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -9,6 +9,12 @@
struct dma_map_ops;
struct device_node;
+/*
+ * Arch extensions to struct device.
+ *
+ * When adding fields, consider macio_add_one_device in
+ * drivers/macintosh/macio_asic.c
+ */
struct dev_archdata {
/* DMA operations on that device */
struct dma_map_ops *dma_ops;
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 20778a405d7a..4ef662e4a31d 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -46,6 +46,7 @@
#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000)
#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000)
#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
+#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
#ifndef __ASSEMBLY__
@@ -59,7 +60,7 @@ enum {
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
- FW_FEATURE_CMO,
+ FW_FEATURE_CMO | FW_FEATURE_VPHN,
FW_FEATURE_PSERIES_ALWAYS = 0,
FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index de03ca58db5d..ec089acfa56b 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -232,7 +232,9 @@
#define H_GET_EM_PARMS 0x2B8
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
-#define MAX_HCALL_OPCODE H_GET_MPP
+#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
+#define H_BEST_ENERGY 0x2F4
+#define MAX_HCALL_OPCODE H_BEST_ENERGY
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 7f5e0fefebb0..380d48bacd16 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -62,7 +62,10 @@ struct lppaca {
volatile u32 dyn_pir; // Dynamic ProcIdReg value x20-x23
u32 dsei_data; // DSEI data x24-x27
u64 sprg3; // SPRG3 value x28-x2F
- u8 reserved3[80]; // Reserved x30-x7F
+ u8 reserved3[40]; // Reserved x30-x57
+ volatile u8 vphn_assoc_counts[8]; // Virtual processor home node
+ // associativity change counters x58-x5F
+ u8 reserved4[32]; // Reserved x60-x7F
//=============================================================================
// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index d045b0145537..8433d36619a1 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -27,9 +27,7 @@ struct iommu_table;
struct rtc_time;
struct file;
struct pci_controller;
-#ifdef CONFIG_KEXEC
struct kimage;
-#endif
#ifdef CONFIG_SMP
struct smp_ops_t {
@@ -72,7 +70,7 @@ struct machdep_calls {
int psize, int ssize);
void (*flush_hash_range)(unsigned long number, int local);
- /* special for kexec, to be called in real mode, linar mapping is
+ /* special for kexec, to be called in real mode, linear mapping is
* destroyed as well */
void (*hpte_clear_all)(void);
@@ -324,8 +322,6 @@ extern sys_ctrler_t sys_ctrler;
#endif /* CONFIG_PPC_PMAC */
-extern void setup_pci_ptrs(void);
-
#ifdef CONFIG_SMP
/* Poor default implementations */
extern void __devinit smp_generic_give_timebase(void);
diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h
index aac87cbceb57..fd3fd58bad84 100644
--- a/arch/powerpc/include/asm/mmzone.h
+++ b/arch/powerpc/include/asm/mmzone.h
@@ -33,6 +33,9 @@ extern int numa_cpu_lookup_table[];
extern cpumask_var_t node_to_cpumask_map[];
#ifdef CONFIG_MEMORY_HOTPLUG
extern unsigned long max_pfn;
+u64 memory_hotplug_max(void);
+#else
+#define memory_hotplug_max() memblock_end_of_DRAM()
#endif
/*
@@ -42,6 +45,8 @@ extern unsigned long max_pfn;
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
+#else
+#define memory_hotplug_max() memblock_end_of_DRAM()
#endif /* CONFIG_NEED_MULTIPLE_NODES */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index 850b72f27445..92efe67d1c57 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -10,31 +10,7 @@
#ifndef _ASM_POWERPC_NVRAM_H
#define _ASM_POWERPC_NVRAM_H
-#include <linux/errno.h>
-
-#define NVRW_CNT 0x20
-#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
-#define NVRAM_BLOCK_LEN 16
-#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN)
-#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN)
-
-#define NVRAM_AS0 0x74
-#define NVRAM_AS1 0x75
-#define NVRAM_DATA 0x77
-
-
-/* RTC Offsets */
-
-#define MOTO_RTC_SECONDS 0x1FF9
-#define MOTO_RTC_MINUTES 0x1FFA
-#define MOTO_RTC_HOURS 0x1FFB
-#define MOTO_RTC_DAY_OF_WEEK 0x1FFC
-#define MOTO_RTC_DAY_OF_MONTH 0x1FFD
-#define MOTO_RTC_MONTH 0x1FFE
-#define MOTO_RTC_YEAR 0x1FFF
-#define MOTO_RTC_CONTROLA 0x1FF8
-#define MOTO_RTC_CONTROLB 0x1FF9
-
+/* Signatures for nvram partitions */
#define NVRAM_SIG_SP 0x02 /* support processor */
#define NVRAM_SIG_OF 0x50 /* open firmware config */
#define NVRAM_SIG_FW 0x51 /* general firmware */
@@ -49,32 +25,19 @@
#define NVRAM_SIG_OS 0xa0 /* OS defined */
#define NVRAM_SIG_PANIC 0xa1 /* Apple OSX "panic" */
-/* If change this size, then change the size of NVNAME_LEN */
-struct nvram_header {
- unsigned char signature;
- unsigned char checksum;
- unsigned short length;
- char name[12];
-};
-
#ifdef __KERNEL__
+#include <linux/errno.h>
#include <linux/list.h>
-struct nvram_partition {
- struct list_head partition;
- struct nvram_header header;
- unsigned int index;
-};
-
-
+#ifdef CONFIG_PPC_PSERIES
extern int nvram_write_error_log(char * buff, int length,
unsigned int err_type, unsigned int err_seq);
extern int nvram_read_error_log(char * buff, int length,
unsigned int * err_type, unsigned int *err_seq);
extern int nvram_clear_error_log(void);
-
extern int pSeries_nvram_init(void);
+#endif /* CONFIG_PPC_PSERIES */
#ifdef CONFIG_MMIO_NVRAM
extern int mmio_nvram_init(void);
@@ -85,6 +48,13 @@ static inline int mmio_nvram_init(void)
}
#endif
+extern int __init nvram_scan_partitions(void);
+extern loff_t nvram_create_partition(const char *name, int sig,
+ int req_size, int min_size);
+extern int nvram_remove_partition(const char *name, int sig);
+extern int nvram_get_partition_size(loff_t data_index);
+extern loff_t nvram_find_partition(const char *name, int sig, int *out_size);
+
#endif /* __KERNEL__ */
/* PowerMac specific nvram stuffs */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 43adc8b819ed..1255569387b6 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -36,6 +36,8 @@
#define PPC_INST_NOP 0x60000000
#define PPC_INST_POPCNTB 0x7c0000f4
#define PPC_INST_POPCNTB_MASK 0xfc0007fe
+#define PPC_INST_POPCNTD 0x7c0003f4
+#define PPC_INST_POPCNTW 0x7c0002f4
#define PPC_INST_RFCI 0x4c000066
#define PPC_INST_RFDI 0x4c00004e
#define PPC_INST_RFMCI 0x4c00004c
@@ -88,6 +90,12 @@
__PPC_RB(b) | __PPC_EH(eh))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
__PPC_RB(b))
+#define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \
+ __PPC_RA(a) | __PPC_RS(s))
+#define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \
+ __PPC_RA(a) | __PPC_RS(s))
+#define PPC_POPCNTW(a, s) stringify_in_c(.long PPC_INST_POPCNTW | \
+ __PPC_RA(a) | __PPC_RS(s))
#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI)
#define PPC_RFDI stringify_in_c(.long PPC_INST_RFDI)
#define PPC_RFMCI stringify_in_c(.long PPC_INST_RFMCI)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 4c14187ba02d..de1967a1ff57 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -122,7 +122,6 @@ extern struct task_struct *last_task_used_spe;
TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
#endif
-#ifdef __KERNEL__
#ifdef __powerpc64__
#define STACK_TOP_USER64 TASK_SIZE_USER64
@@ -139,7 +138,6 @@ extern struct task_struct *last_task_used_spe;
#define STACK_TOP_MAX STACK_TOP
#endif /* __powerpc64__ */
-#endif /* __KERNEL__ */
typedef struct {
unsigned long seg;
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2efd089..ab34f6072095 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void);
/* Translate a DMA address from device space to CPU space */
extern u64 of_translate_dma_address(struct device_node *dev,
- const u32 *in_addr);
+ const __be32 *in_addr);
#ifdef CONFIG_PCI
extern unsigned long pci_address_to_pio(phys_addr_t address);
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index afe4aaa65c3b..aed188bd70db 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -93,6 +93,8 @@ extern void __init dump_numa_cpu_topology(void);
extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
+extern int start_topology_update(void);
+extern int stop_topology_update(void);
#else
static inline void dump_numa_cpu_topology(void) {}
@@ -107,6 +109,14 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev,
{
}
+static inline int start_topology_update(void)
+{
+ return 0;
+}
+static inline int stop_topology_update(void)
+{
+ return 0;
+}
#endif /* CONFIG_NUMA */
#include <asm-generic/topology.h>
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index 08679c5319b8..25e39220e89c 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -116,9 +116,7 @@ struct vdso_data {
#endif /* CONFIG_PPC64 */
-#ifdef __KERNEL__
extern struct vdso_data *vdso_data;
-#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 36c30f31ec93..3bb2a3e6a337 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -29,8 +29,10 @@ endif
obj-y := cputable.o ptrace.o syscalls.o \
irq.o align.o signal_32.o pmc.o vdso.o \
init_task.o process.o systbl.o idle.o \
- signal.o sysfs.o cacheinfo.o
-obj-y += vdso32/
+ signal.o sysfs.o cacheinfo.o time.o \
+ prom.o traps.o setup-common.o \
+ udbg.o misc.o io.o dma.o \
+ misc_$(CONFIG_WORD_SIZE).o vdso32/
obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o nvram_64.o firmware.o
@@ -80,9 +82,6 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-y += vmlinux.lds
-obj-y += time.o prom.o traps.o setup-common.o \
- udbg.o misc.o io.o dma.o \
- misc_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index bd0df2e6aa8f..23e6a93145ab 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -209,7 +209,6 @@ int main(void)
DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
/* Interrupt register frame */
- DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 96a908f1cd87..be5ab18b03b5 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -457,16 +457,26 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 128,
.num_pmcs = 6,
.pmc_type = PPC_PMC_IBM,
- .cpu_setup = __setup_cpu_power7,
- .cpu_restore = __restore_cpu_power7,
.oprofile_cpu_type = "ppc64/power7",
.oprofile_type = PPC_OPROFILE_POWER4,
- .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
- .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
- .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
- POWER6_MMCRA_OTHER,
.platform = "power7",
},
+ { /* Power7+ */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x004A0000,
+ .cpu_name = "POWER7+ (raw)",
+ .cpu_features = CPU_FTRS_POWER7,
+ .cpu_user_features = COMMON_USER_POWER7,
+ .mmu_features = MMU_FTR_HPTE_TABLE |
+ MMU_FTR_TLBIE_206,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .pmc_type = PPC_PMC_IBM,
+ .oprofile_cpu_type = "ppc64/power7",
+ .oprofile_type = PPC_OPROFILE_POWER4,
+ .platform = "power7+",
+ },
{ /* Cell Broadband Engine */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00700000,
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 8e05c16344e4..0a2af50243cb 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -19,6 +19,7 @@
#include <asm/prom.h>
#include <asm/firmware.h>
#include <asm/uaccess.h>
+#include <asm/rtas.h>
#ifdef DEBUG
#include <asm/udbg.h>
@@ -141,3 +142,35 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
return csize;
}
+
+#ifdef CONFIG_PPC_RTAS
+/*
+ * The crashkernel region will almost always overlap the RTAS region, so
+ * we have to be careful when shrinking the crashkernel region.
+ */
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
+{
+ unsigned long addr;
+ const u32 *basep, *sizep;
+ unsigned int rtas_start = 0, rtas_end = 0;
+
+ basep = of_get_property(rtas.dev, "linux,rtas-base", NULL);
+ sizep = of_get_property(rtas.dev, "rtas-size", NULL);
+
+ if (basep && sizep) {
+ rtas_start = *basep;
+ rtas_end = *basep + *sizep;
+ }
+
+ for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ /* Does this page overlap with the RTAS region? */
+ if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start))
+ continue;
+
+ ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT));
+ init_page_count(pfn_to_page(addr >> PAGE_SHIFT));
+ free_page((unsigned long)__va(addr));
+ totalram_pages++;
+ }
+}
+#endif
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 6e54a0fd31aa..e7554154a6de 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -19,7 +19,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
- dma_handle, device_to_mask(dev), flag,
+ dma_handle, dev->coherent_dma_mask, flag,
dev_to_node(dev));
}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index ed4aeb96398b..c22dc1ec1c94 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -31,6 +31,7 @@
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/ftrace.h>
+#include <asm/ptrace.h>
#undef SHOW_SYSCALLS
#undef SHOW_SYSCALLS_TASK
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 9f8b01d6466f..8a817995b4cd 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -13,6 +13,7 @@
*/
#include <asm/exception-64s.h>
+#include <asm/ptrace.h>
/*
* We layout physical memory as follows:
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index e86c040ae585..de369558bf0a 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -23,6 +23,7 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
#ifdef CONFIG_VSX
#define REST_32FPVSRS(n,c,base) \
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 8278e8bad5a0..9dd21a8c4d52 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -40,6 +40,7 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
/* As with the other PowerPC ports, it is expected that when code
* execution begins here, the following registers contain valid, yet
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 562305b40a8e..cbb3436b592d 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -37,6 +37,7 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
#include <asm/synch.h>
#include "head_booke.h"
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index f0dd577e4a5b..782f23df7c85 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -38,6 +38,7 @@
#include <asm/page_64.h>
#include <asm/irqflags.h>
#include <asm/kvm_book3s_asm.h>
+#include <asm/ptrace.h>
/* The physical memory is layed out such that the secondary processor
* spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -96,7 +97,7 @@ __secondary_hold_acknowledge:
.llong hvReleaseData-KERNELBASE
#endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_CRASH_DUMP
+#ifdef CONFIG_RELOCATABLE
/* This flag is set to 1 by a loader if the kernel should run
* at the loaded address instead of the linked address. This
* is used by kexec-tools to keep the the kdump kernel in the
@@ -384,12 +385,10 @@ _STATIC(__after_prom_start)
/* process relocations for the final address of the kernel */
lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
sldi r25,r25,32
-#ifdef CONFIG_CRASH_DUMP
lwz r7,__run_at_load-_stext(r26)
- cmplwi cr0,r7,1 /* kdump kernel ? - stay where we are */
+ cmplwi cr0,r7,1 /* flagged to stay where we are ? */
bne 1f
add r25,r25,r26
-#endif
1: mr r3,r25
bl .relocate
#endif
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 1f1a04b5c2a4..1cbf64e6b416 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -29,6 +29,7 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
/* Macro to make the code more readable. */
#ifdef CONFIG_8xx_CPU6
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 529b817f473b..3e02710d9562 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -41,6 +41,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
+#include <asm/ptrace.h>
#include "head_booke.h"
/* As with the other PowerPC ports, it is expected that when code
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index d5839179ec77..961bb03413f3 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -311,8 +311,9 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
/* Handle failure */
if (unlikely(entry == DMA_ERROR_CODE)) {
if (printk_ratelimit())
- printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx"
- " npages %lx\n", tbl, vaddr, npages);
+ dev_info(dev, "iommu_alloc failed, tbl %p "
+ "vaddr %lx npages %lu\n", tbl, vaddr,
+ npages);
goto failure;
}
@@ -579,9 +580,9 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
attrs);
if (dma_handle == DMA_ERROR_CODE) {
if (printk_ratelimit()) {
- printk(KERN_INFO "iommu_alloc failed, "
- "tbl %p vaddr %p npages %d\n",
- tbl, vaddr, npages);
+ dev_info(dev, "iommu_alloc failed, tbl %p "
+ "vaddr %p npages %d\n", tbl, vaddr,
+ npages);
}
} else
dma_handle |= (uaddr & ~IOMMU_PAGE_MASK);
@@ -627,7 +628,8 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
* the tce tables.
*/
if (order >= IOMAP_MAX_ORDER) {
- printk("iommu_alloc_consistent size too large: 0x%lx\n", size);
+ dev_info(dev, "iommu_alloc_consistent size too large: 0x%lx\n",
+ size);
return NULL;
}
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 2d29752cbe16..b69463ec2010 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -122,8 +122,3 @@ _GLOBAL(longjmp)
mtlr r0
mr r3,r4
blr
-
-_GLOBAL(__setup_cpu_power7)
-_GLOBAL(__restore_cpu_power7)
- /* place holder */
- blr
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index a7a570dcdd57..094bd9821ad4 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -30,6 +30,7 @@
#include <asm/processor.h>
#include <asm/kexec.h>
#include <asm/bug.h>
+#include <asm/ptrace.h>
.text
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index e5144906a56d..206a321a71d3 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -25,6 +25,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/kexec.h>
+#include <asm/ptrace.h>
.text
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 9cf197f01e94..bb12b3248f13 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -34,15 +34,26 @@
#undef DEBUG_NVRAM
-static struct nvram_partition * nvram_part;
-static long nvram_error_log_index = -1;
-static long nvram_error_log_size = 0;
+#define NVRAM_HEADER_LEN sizeof(struct nvram_header)
+#define NVRAM_BLOCK_LEN NVRAM_HEADER_LEN
+
+/* If change this size, then change the size of NVNAME_LEN */
+struct nvram_header {
+ unsigned char signature;
+ unsigned char checksum;
+ unsigned short length;
+ /* Terminating null required only for names < 12 chars. */
+ char name[12];
+};
-struct err_log_info {
- int error_type;
- unsigned int seq_num;
+struct nvram_partition {
+ struct list_head partition;
+ struct nvram_header header;
+ unsigned int index;
};
+static LIST_HEAD(nvram_partitions);
+
static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
{
int size;
@@ -186,14 +197,12 @@ static struct miscdevice nvram_dev = {
#ifdef DEBUG_NVRAM
static void __init nvram_print_partitions(char * label)
{
- struct list_head * p;
struct nvram_partition * tmp_part;
printk(KERN_WARNING "--------%s---------\n", label);
printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
- list_for_each(p, &nvram_part->partition) {
- tmp_part = list_entry(p, struct nvram_partition, partition);
- printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%s\n",
+ list_for_each_entry(tmp_part, &nvram_partitions, partition) {
+ printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n",
tmp_part->index, tmp_part->header.signature,
tmp_part->header.checksum, tmp_part->header.length,
tmp_part->header.name);
@@ -228,95 +237,113 @@ static unsigned char __init nvram_checksum(struct nvram_header *p)
return c_sum;
}
-static int __init nvram_remove_os_partition(void)
+/**
+ * nvram_remove_partition - Remove one or more partitions in nvram
+ * @name: name of the partition to remove, or NULL for a
+ * signature only match
+ * @sig: signature of the partition(s) to remove
+ */
+
+int __init nvram_remove_partition(const char *name, int sig)
{
- struct list_head *i;
- struct list_head *j;
- struct nvram_partition * part;
- struct nvram_partition * cur_part;
+ struct nvram_partition *part, *prev, *tmp;
int rc;
- list_for_each(i, &nvram_part->partition) {
- part = list_entry(i, struct nvram_partition, partition);
- if (part->header.signature != NVRAM_SIG_OS)
+ list_for_each_entry(part, &nvram_partitions, partition) {
+ if (part->header.signature != sig)
continue;
-
- /* Make os partition a free partition */
+ if (name && strncmp(name, part->header.name, 12))
+ continue;
+
+ /* Make partition a free partition */
part->header.signature = NVRAM_SIG_FREE;
- sprintf(part->header.name, "wwwwwwwwwwww");
+ strncpy(part->header.name, "wwwwwwwwwwww", 12);
part->header.checksum = nvram_checksum(&part->header);
-
- /* Merge contiguous free partitions backwards */
- list_for_each_prev(j, &part->partition) {
- cur_part = list_entry(j, struct nvram_partition, partition);
- if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
- break;
- }
-
- part->header.length += cur_part->header.length;
- part->header.checksum = nvram_checksum(&part->header);
- part->index = cur_part->index;
-
- list_del(&cur_part->partition);
- kfree(cur_part);
- j = &part->partition; /* fixup our loop */
- }
-
- /* Merge contiguous free partitions forwards */
- list_for_each(j, &part->partition) {
- cur_part = list_entry(j, struct nvram_partition, partition);
- if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
- break;
- }
-
- part->header.length += cur_part->header.length;
- part->header.checksum = nvram_checksum(&part->header);
-
- list_del(&cur_part->partition);
- kfree(cur_part);
- j = &part->partition; /* fixup our loop */
- }
-
rc = nvram_write_header(part);
if (rc <= 0) {
- printk(KERN_ERR "nvram_remove_os_partition: nvram_write failed (%d)\n", rc);
+ printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
return rc;
}
+ }
+ /* Merge contiguous ones */
+ prev = NULL;
+ list_for_each_entry_safe(part, tmp, &nvram_partitions, partition) {
+ if (part->header.signature != NVRAM_SIG_FREE) {
+ prev = NULL;
+ continue;
+ }
+ if (prev) {
+ prev->header.length += part->header.length;
+ prev->header.checksum = nvram_checksum(&part->header);
+ rc = nvram_write_header(part);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
+ return rc;
+ }
+ list_del(&part->partition);
+ kfree(part);
+ } else
+ prev = part;
}
return 0;
}
-/* nvram_create_os_partition
+/**
+ * nvram_create_partition - Create a partition in nvram
+ * @name: name of the partition to create
+ * @sig: signature of the partition to create
+ * @req_size: size of data to allocate in bytes
+ * @min_size: minimum acceptable size (0 means req_size)
*
- * Create a OS linux partition to buffer error logs.
- * Will create a partition starting at the first free
- * space found if space has enough room.
+ * Returns a negative error code or a positive nvram index
+ * of the beginning of the data area of the newly created
+ * partition. If you provided a min_size smaller than req_size
+ * you need to query for the actual size yourself after the
+ * call using nvram_partition_get_size().
*/
-static int __init nvram_create_os_partition(void)
+loff_t __init nvram_create_partition(const char *name, int sig,
+ int req_size, int min_size)
{
struct nvram_partition *part;
struct nvram_partition *new_part;
struct nvram_partition *free_part = NULL;
- int seq_init[2] = { 0, 0 };
+ static char nv_init_vals[16];
loff_t tmp_index;
long size = 0;
int rc;
-
+
+ /* Convert sizes from bytes to blocks */
+ req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
+ min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
+
+ /* If no minimum size specified, make it the same as the
+ * requested size
+ */
+ if (min_size == 0)
+ min_size = req_size;
+ if (min_size > req_size)
+ return -EINVAL;
+
+ /* Now add one block to each for the header */
+ req_size += 1;
+ min_size += 1;
+
/* Find a free partition that will give us the maximum needed size
If can't find one that will give us the minimum size needed */
- list_for_each_entry(part, &nvram_part->partition, partition) {
+ list_for_each_entry(part, &nvram_partitions, partition) {
if (part->header.signature != NVRAM_SIG_FREE)
continue;
- if (part->header.length >= NVRAM_MAX_REQ) {
- size = NVRAM_MAX_REQ;
+ if (part->header.length >= req_size) {
+ size = req_size;
free_part = part;
break;
}
- if (!size && part->header.length >= NVRAM_MIN_REQ) {
- size = NVRAM_MIN_REQ;
+ if (part->header.length > size &&
+ part->header.length >= min_size) {
+ size = part->header.length;
free_part = part;
}
}
@@ -326,136 +353,95 @@ static int __init nvram_create_os_partition(void)
/* Create our OS partition */
new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
if (!new_part) {
- printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n");
+ pr_err("nvram_create_os_partition: kmalloc failed\n");
return -ENOMEM;
}
new_part->index = free_part->index;
- new_part->header.signature = NVRAM_SIG_OS;
+ new_part->header.signature = sig;
new_part->header.length = size;
- strcpy(new_part->header.name, "ppc64,linux");
+ strncpy(new_part->header.name, name, 12);
new_part->header.checksum = nvram_checksum(&new_part->header);
rc = nvram_write_header(new_part);
if (rc <= 0) {
- printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
- "failed (%d)\n", rc);
- return rc;
- }
-
- /* make sure and initialize to zero the sequence number and the error
- type logged */
- tmp_index = new_part->index + NVRAM_HEADER_LEN;
- rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_create_os_partition: nvram_write "
+ pr_err("nvram_create_os_partition: nvram_write_header "
"failed (%d)\n", rc);
return rc;
}
-
- nvram_error_log_index = new_part->index + NVRAM_HEADER_LEN;
- nvram_error_log_size = ((part->header.length - 1) *
- NVRAM_BLOCK_LEN) - sizeof(struct err_log_info);
-
list_add_tail(&new_part->partition, &free_part->partition);
- if (free_part->header.length <= size) {
+ /* Adjust or remove the partition we stole the space from */
+ if (free_part->header.length > size) {
+ free_part->index += size * NVRAM_BLOCK_LEN;
+ free_part->header.length -= size;
+ free_part->header.checksum = nvram_checksum(&free_part->header);
+ rc = nvram_write_header(free_part);
+ if (rc <= 0) {
+ pr_err("nvram_create_os_partition: nvram_write_header "
+ "failed (%d)\n", rc);
+ return rc;
+ }
+ } else {
list_del(&free_part->partition);
kfree(free_part);
- return 0;
}
- /* Adjust the partition we stole the space from */
- free_part->index += size * NVRAM_BLOCK_LEN;
- free_part->header.length -= size;
- free_part->header.checksum = nvram_checksum(&free_part->header);
-
- rc = nvram_write_header(free_part);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
- "failed (%d)\n", rc);
- return rc;
+ /* Clear the new partition */
+ for (tmp_index = new_part->index + NVRAM_HEADER_LEN;
+ tmp_index < ((size - 1) * NVRAM_BLOCK_LEN);
+ tmp_index += NVRAM_BLOCK_LEN) {
+ rc = ppc_md.nvram_write(nv_init_vals, NVRAM_BLOCK_LEN, &tmp_index);
+ if (rc <= 0) {
+ pr_err("nvram_create_partition: nvram_write failed (%d)\n", rc);
+ return rc;
+ }
}
-
- return 0;
+
+ return new_part->index + NVRAM_HEADER_LEN;
}
-
-/* nvram_setup_partition
- *
- * This will setup the partition we need for buffering the
- * error logs and cleanup partitions if needed.
- *
- * The general strategy is the following:
- * 1.) If there is ppc64,linux partition large enough then use it.
- * 2.) If there is not a ppc64,linux partition large enough, search
- * for a free partition that is large enough.
- * 3.) If there is not a free partition large enough remove
- * _all_ OS partitions and consolidate the space.
- * 4.) Will first try getting a chunk that will satisfy the maximum
- * error log size (NVRAM_MAX_REQ).
- * 5.) If the max chunk cannot be allocated then try finding a chunk
- * that will satisfy the minum needed (NVRAM_MIN_REQ).
+/**
+ * nvram_get_partition_size - Get the data size of an nvram partition
+ * @data_index: This is the offset of the start of the data of
+ * the partition. The same value that is returned by
+ * nvram_create_partition().
*/
-static int __init nvram_setup_partition(void)
+int nvram_get_partition_size(loff_t data_index)
{
- struct list_head * p;
- struct nvram_partition * part;
- int rc;
-
- /* For now, we don't do any of this on pmac, until I
- * have figured out if it's worth killing some unused stuffs
- * in our nvram, as Apple defined partitions use pretty much
- * all of the space
- */
- if (machine_is(powermac))
- return -ENOSPC;
-
- /* see if we have an OS partition that meets our needs.
- will try getting the max we need. If not we'll delete
- partitions and try again. */
- list_for_each(p, &nvram_part->partition) {
- part = list_entry(p, struct nvram_partition, partition);
- if (part->header.signature != NVRAM_SIG_OS)
- continue;
+ struct nvram_partition *part;
+
+ list_for_each_entry(part, &nvram_partitions, partition) {
+ if (part->index + NVRAM_HEADER_LEN == data_index)
+ return (part->header.length - 1) * NVRAM_BLOCK_LEN;
+ }
+ return -1;
+}
- if (strcmp(part->header.name, "ppc64,linux"))
- continue;
- if (part->header.length >= NVRAM_MIN_REQ) {
- /* found our partition */
- nvram_error_log_index = part->index + NVRAM_HEADER_LEN;
- nvram_error_log_size = ((part->header.length - 1) *
- NVRAM_BLOCK_LEN) - sizeof(struct err_log_info);
- return 0;
+/**
+ * nvram_find_partition - Find an nvram partition by signature and name
+ * @name: Name of the partition or NULL for any name
+ * @sig: Signature to test against
+ * @out_size: if non-NULL, returns the size of the data part of the partition
+ */
+loff_t nvram_find_partition(const char *name, int sig, int *out_size)
+{
+ struct nvram_partition *p;
+
+ list_for_each_entry(p, &nvram_partitions, partition) {
+ if (p->header.signature == sig &&
+ (!name || !strncmp(p->header.name, name, 12))) {
+ if (out_size)
+ *out_size = (p->header.length - 1) *
+ NVRAM_BLOCK_LEN;
+ return p->index + NVRAM_HEADER_LEN;
}
}
-
- /* try creating a partition with the free space we have */
- rc = nvram_create_os_partition();
- if (!rc) {
- return 0;
- }
-
- /* need to free up some space */
- rc = nvram_remove_os_partition();
- if (rc) {
- return rc;
- }
-
- /* create a partition in this new space */
- rc = nvram_create_os_partition();
- if (rc) {
- printk(KERN_ERR "nvram_create_os_partition: Could not find a "
- "NVRAM partition large enough\n");
- return rc;
- }
-
return 0;
}
-
-static int __init nvram_scan_partitions(void)
+int __init nvram_scan_partitions(void)
{
loff_t cur_index = 0;
struct nvram_header phead;
@@ -465,7 +451,7 @@ static int __init nvram_scan_partitions(void)
int total_size;
int err;
- if (ppc_md.nvram_size == NULL)
+ if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0)
return -ENODEV;
total_size = ppc_md.nvram_size();
@@ -512,12 +498,16 @@ static int __init nvram_scan_partitions(void)
memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN);
tmp_part->index = cur_index;
- list_add_tail(&tmp_part->partition, &nvram_part->partition);
+ list_add_tail(&tmp_part->partition, &nvram_partitions);
cur_index += phead.length * NVRAM_BLOCK_LEN;
}
err = 0;
+#ifdef DEBUG_NVRAM
+ nvram_print_partitions("NVRAM Partitions");
+#endif
+
out:
kfree(header);
return err;
@@ -525,9 +515,10 @@ static int __init nvram_scan_partitions(void)
static int __init nvram_init(void)
{
- int error;
int rc;
+ BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
+
if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0)
return -ENODEV;
@@ -537,29 +528,6 @@ static int __init nvram_init(void)
return rc;
}
- /* initialize our anchor for the nvram partition list */
- nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
- if (!nvram_part) {
- printk(KERN_ERR "nvram_init: Failed kmalloc\n");
- return -ENOMEM;
- }
- INIT_LIST_HEAD(&nvram_part->partition);
-
- /* Get all the NVRAM partitions */
- error = nvram_scan_partitions();
- if (error) {
- printk(KERN_ERR "nvram_init: Failed nvram_scan_partitions\n");
- return error;
- }
-
- if(nvram_setup_partition())
- printk(KERN_WARNING "nvram_init: Could not find nvram partition"
- " for nvram buffered error logging.\n");
-
-#ifdef DEBUG_NVRAM
- nvram_print_partitions("NVRAM Partitions");
-#endif
-
return rc;
}
@@ -568,135 +536,6 @@ void __exit nvram_cleanup(void)
misc_deregister( &nvram_dev );
}
-
-#ifdef CONFIG_PPC_PSERIES
-
-/* nvram_write_error_log
- *
- * We need to buffer the error logs into nvram to ensure that we have
- * the failure information to decode. If we have a severe error there
- * is no way to guarantee that the OS or the machine is in a state to
- * get back to user land and write the error to disk. For example if
- * the SCSI device driver causes a Machine Check by writing to a bad
- * IO address, there is no way of guaranteeing that the device driver
- * is in any state that is would also be able to write the error data
- * captured to disk, thus we buffer it in NVRAM for analysis on the
- * next boot.
- *
- * In NVRAM the partition containing the error log buffer will looks like:
- * Header (in bytes):
- * +-----------+----------+--------+------------+------------------+
- * | signature | checksum | length | name | data |
- * |0 |1 |2 3|4 15|16 length-1|
- * +-----------+----------+--------+------------+------------------+
- *
- * The 'data' section would look like (in bytes):
- * +--------------+------------+-----------------------------------+
- * | event_logged | sequence # | error log |
- * |0 3|4 7|8 nvram_error_log_size-1|
- * +--------------+------------+-----------------------------------+
- *
- * event_logged: 0 if event has not been logged to syslog, 1 if it has
- * sequence #: The unique sequence # for each event. (until it wraps)
- * error log: The error log from event_scan
- */
-int nvram_write_error_log(char * buff, int length,
- unsigned int err_type, unsigned int error_log_cnt)
-{
- int rc;
- loff_t tmp_index;
- struct err_log_info info;
-
- if (nvram_error_log_index == -1) {
- return -ESPIPE;
- }
-
- if (length > nvram_error_log_size) {
- length = nvram_error_log_size;
- }
-
- info.error_type = err_type;
- info.seq_num = error_log_cnt;
-
- tmp_index = nvram_error_log_index;
-
- rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
- return rc;
- }
-
- rc = ppc_md.nvram_write(buff, length, &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-/* nvram_read_error_log
- *
- * Reads nvram for error log for at most 'length'
- */
-int nvram_read_error_log(char * buff, int length,
- unsigned int * err_type, unsigned int * error_log_cnt)
-{
- int rc;
- loff_t tmp_index;
- struct err_log_info info;
-
- if (nvram_error_log_index == -1)
- return -1;
-
- if (length > nvram_error_log_size)
- length = nvram_error_log_size;
-
- tmp_index = nvram_error_log_index;
-
- rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
- return rc;
- }
-
- rc = ppc_md.nvram_read(buff, length, &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
- return rc;
- }
-
- *error_log_cnt = info.seq_num;
- *err_type = info.error_type;
-
- return 0;
-}
-
-/* This doesn't actually zero anything, but it sets the event_logged
- * word to tell that this event is safely in syslog.
- */
-int nvram_clear_error_log(void)
-{
- loff_t tmp_index;
- int clear_word = ERR_FLAG_ALREADY_LOGGED;
- int rc;
-
- if (nvram_error_log_index == -1)
- return -1;
-
- tmp_index = nvram_error_log_index;
-
- rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
- if (rc <= 0) {
- printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_PPC_PSERIES */
-
module_init(nvram_init);
module_exit(nvram_cleanup);
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index d43fc65749c1..851577608a78 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -193,8 +193,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
hose->io_resource.start += io_virt_offset;
hose->io_resource.end += io_virt_offset;
- pr_debug(" hose->io_resource=0x%016llx...0x%016llx\n",
- hose->io_resource.start, hose->io_resource.end);
+ pr_debug(" hose->io_resource=%pR\n", &hose->io_resource);
return 0;
}
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index ab3e392ac63c..ef3ef566235e 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -186,3 +186,10 @@ EXPORT_SYMBOL(__mtdcr);
EXPORT_SYMBOL(__mfdcr);
#endif
EXPORT_SYMBOL(empty_zero_page);
+
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(__arch_hweight8);
+EXPORT_SYMBOL(__arch_hweight16);
+EXPORT_SYMBOL(__arch_hweight32);
+EXPORT_SYMBOL(__arch_hweight64);
+#endif
diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S
index 5113bd2285e1..e83ba3f078e4 100644
--- a/arch/powerpc/kernel/ppc_save_regs.S
+++ b/arch/powerpc/kernel/ppc_save_regs.S
@@ -11,6 +11,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
/*
* Grab the register values as they are now.
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index a9b32967cff6..906536998291 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1316,6 +1316,10 @@ static int set_dac_range(struct task_struct *child,
static long ppc_set_hwdebug(struct task_struct *child,
struct ppc_hw_breakpoint *bp_info)
{
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
+ unsigned long dabr;
+#endif
+
if (bp_info->version != 1)
return -ENOTSUPP;
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -1353,11 +1357,10 @@ static long ppc_set_hwdebug(struct task_struct *child,
/*
* We only support one data breakpoint
*/
- if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
- ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
- (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
- (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
- (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+ if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
+ (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
+ bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
+ bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
return -EINVAL;
if (child->thread.dabr)
@@ -1366,7 +1369,14 @@ static long ppc_set_hwdebug(struct task_struct *child,
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
- child->thread.dabr = (unsigned long)bp_info->addr;
+ dabr = (unsigned long)bp_info->addr & ~7UL;
+ dabr |= DABR_TRANSLATION;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+ dabr |= DABR_DATA_READ;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+ dabr |= DABR_DATA_WRITE;
+
+ child->thread.dabr = dabr;
return 1;
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 8a6daf4129f6..69c4be917d07 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -280,7 +280,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
/* We only support one DABR and no IABRS at the moment */
if (addr > 0)
break;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ ret = put_user(child->thread.dac1, (u32 __user *)data);
+#else
ret = put_user(child->thread.dabr, (u32 __user *)data);
+#endif
break;
}
@@ -312,6 +316,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case PTRACE_SET_DEBUGREG:
case PTRACE_SYSCALL:
case PTRACE_CONT:
+ case PPC_PTRACE_GETHWDBGINFO:
+ case PPC_PTRACE_SETHWDEBUG:
+ case PPC_PTRACE_DELHWDEBUG:
ret = arch_ptrace(child, request, addr, data);
break;
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8fe8bc61c10a..2097f2b3cba8 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -41,6 +41,7 @@
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/mmu.h>
+#include <asm/topology.h>
struct rtas_t rtas = {
.lock = __ARCH_SPIN_LOCK_UNLOCKED
@@ -713,6 +714,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
int cpu;
slb_set_size(SLB_MIN_SIZE);
+ stop_topology_update();
printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
@@ -728,6 +730,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
rc = atomic_read(&data->error);
atomic_set(&data->error, rc);
+ start_topology_update();
if (wake_when_done) {
atomic_set(&data->done, 1);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index ce6f61c6f871..5a0401fcaebd 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -437,8 +437,8 @@ static void __init irqstack_early_init(void)
unsigned int i;
/*
- * interrupt stacks must be under 256MB, we cannot afford to take
- * SLB misses on them.
+ * Interrupt stacks must be in the first segment since we
+ * cannot afford to take SLB misses on them.
*/
for_each_possible_cpu(i) {
softirq_ctx[i] = (struct thread_info *)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 68034bbf2e4f..981360509172 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -466,7 +466,20 @@ out:
return id;
}
-/* Must be called when no change can occur to cpu_present_mask,
+/* Helper routines for cpu to core mapping */
+int cpu_core_index_of_thread(int cpu)
+{
+ return cpu >> threads_shift;
+}
+EXPORT_SYMBOL_GPL(cpu_core_index_of_thread);
+
+int cpu_first_thread_of_core(int core)
+{
+ return core << threads_shift;
+}
+EXPORT_SYMBOL_GPL(cpu_first_thread_of_core);
+
+/* Must be called when no change can occur to cpu_present_map,
* i.e. during cpu online or offline.
*/
static struct device_node *cpu_to_l2cache(int cpu)
@@ -514,7 +527,7 @@ int __devinit start_secondary(void *unused)
notify_cpu_starting(cpu);
set_cpu_online(cpu, true);
/* Update sibling maps */
- base = cpu_first_thread_in_core(cpu);
+ base = cpu_first_thread_sibling(cpu);
for (i = 0; i < threads_per_core; i++) {
if (cpu_is_offline(base + i))
continue;
@@ -600,7 +613,7 @@ int __cpu_disable(void)
return err;
/* Update sibling maps */
- base = cpu_first_thread_in_core(cpu);
+ base = cpu_first_thread_sibling(cpu);
for (i = 0; i < threads_per_core; i++) {
cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i));
cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu));
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 010406958d97..09e4dea4a85a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(rtc_lock);
static u64 tb_to_ns_scale __read_mostly;
static unsigned tb_to_ns_shift __read_mostly;
-static unsigned long boot_tb __read_mostly;
+static u64 boot_tb __read_mostly;
extern struct timezone sys_tz;
static long timezone_offset;
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index fe460482fa68..9de6f396cf85 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -5,6 +5,7 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
/*
* load_up_altivec(unused, unused, tsk)
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 441d2a722f06..1b695fdc362b 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -600,6 +600,11 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
vio_cmo_dealloc(viodev, alloc_size);
}
+static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask)
+{
+ return dma_iommu_ops.dma_supported(dev, mask);
+}
+
struct dma_map_ops vio_dma_mapping_ops = {
.alloc_coherent = vio_dma_iommu_alloc_coherent,
.free_coherent = vio_dma_iommu_free_coherent,
@@ -607,6 +612,7 @@ struct dma_map_ops vio_dma_mapping_ops = {
.unmap_sg = vio_dma_iommu_unmap_sg,
.map_page = vio_dma_iommu_map_page,
.unmap_page = vio_dma_iommu_unmap_page,
+ .dma_supported = vio_dma_iommu_dma_supported,
};
@@ -858,8 +864,7 @@ static void vio_cmo_bus_remove(struct vio_dev *viodev)
static void vio_cmo_set_dma_ops(struct vio_dev *viodev)
{
- vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported;
- viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops;
+ set_dma_ops(&viodev->dev, &vio_dma_mapping_ops);
}
/**
@@ -1244,7 +1249,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
if (firmware_has_feature(FW_FEATURE_CMO))
vio_cmo_set_dma_ops(viodev);
else
- viodev->dev.archdata.dma_ops = &dma_iommu_ops;
+ set_dma_ops(&viodev->dev, &dma_iommu_ops);
set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
set_dev_node(&viodev->dev, of_node_to_nid(of_node));
@@ -1252,6 +1257,10 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
viodev->dev.parent = &vio_bus_device.dev;
viodev->dev.bus = &vio_bus_type;
viodev->dev.release = vio_dev_release;
+ /* needed to ensure proper operation of coherent allocations
+ * later, in case driver doesn't set it explicitly */
+ dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
+ dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
/* register with generic device framework */
if (device_register(&viodev->dev)) {
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index e316847c08c0..badc983031b3 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1307,12 +1307,10 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
int err = -ENOMEM;
unsigned long p;
- vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s));
+ vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s));
if (!vcpu_book3s)
goto out;
- memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s));
-
vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *)
kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL);
if (!vcpu_book3s->shadow_vcpu)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 38f756f25053..99758460efde 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -145,18 +145,12 @@ void kvm_arch_check_processor_compat(void *rtn)
*(int *)rtn = kvmppc_core_check_processor_compat();
}
-struct kvm *kvm_arch_create_vm(void)
+int kvm_arch_init_vm(struct kvm *kvm)
{
- struct kvm *kvm;
-
- kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
- if (!kvm)
- return ERR_PTR(-ENOMEM);
-
- return kvm;
+ return 0;
}
-static void kvmppc_free_vcpus(struct kvm *kvm)
+void kvm_arch_destroy_vm(struct kvm *kvm)
{
unsigned int i;
struct kvm_vcpu *vcpu;
@@ -176,14 +170,6 @@ void kvm_arch_sync_events(struct kvm *kvm)
{
}
-void kvm_arch_destroy_vm(struct kvm *kvm)
-{
- kvmppc_free_vcpus(kvm);
- kvm_free_physmem(kvm);
- cleanup_srcu_struct(&kvm->srcu);
- kfree(kvm);
-}
-
int kvm_dev_ioctl_check_extension(long ext)
{
int r;
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 889f2bc106dd..166a6a0ad544 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_HAS_IOMEM) += devres.o
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o \
- checksum_wrappers_64.o
+ checksum_wrappers_64.o hweight_64.o
obj-$(CONFIG_XMON) += sstep.o ldstfp.o
obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o
diff --git a/arch/powerpc/lib/hweight_64.S b/arch/powerpc/lib/hweight_64.S
new file mode 100644
index 000000000000..fda27868cf8c
--- /dev/null
+++ b/arch/powerpc/lib/hweight_64.S
@@ -0,0 +1,110 @@
+/*
+ * This program is free software; you can redistribute it and/or 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) IBM Corporation, 2010
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+
+/* Note: This code relies on -mminimal-toc */
+
+_GLOBAL(__arch_hweight8)
+BEGIN_FTR_SECTION
+ b .__sw_hweight8
+ nop
+ nop
+FTR_SECTION_ELSE
+ PPC_POPCNTB(r3,r3)
+ clrldi r3,r3,64-8
+ blr
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+_GLOBAL(__arch_hweight16)
+BEGIN_FTR_SECTION
+ b .__sw_hweight16
+ nop
+ nop
+ nop
+ nop
+FTR_SECTION_ELSE
+ BEGIN_FTR_SECTION_NESTED(50)
+ PPC_POPCNTB(r3,r3)
+ srdi r4,r3,8
+ add r3,r4,r3
+ clrldi r3,r3,64-8
+ blr
+ FTR_SECTION_ELSE_NESTED(50)
+ clrlwi r3,r3,16
+ PPC_POPCNTW(r3,r3)
+ clrldi r3,r3,64-8
+ blr
+ ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 50)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+_GLOBAL(__arch_hweight32)
+BEGIN_FTR_SECTION
+ b .__sw_hweight32
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+FTR_SECTION_ELSE
+ BEGIN_FTR_SECTION_NESTED(51)
+ PPC_POPCNTB(r3,r3)
+ srdi r4,r3,16
+ add r3,r4,r3
+ srdi r4,r3,8
+ add r3,r4,r3
+ clrldi r3,r3,64-8
+ blr
+ FTR_SECTION_ELSE_NESTED(51)
+ PPC_POPCNTW(r3,r3)
+ clrldi r3,r3,64-8
+ blr
+ ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 51)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+_GLOBAL(__arch_hweight64)
+BEGIN_FTR_SECTION
+ b .__sw_hweight64
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+FTR_SECTION_ELSE
+ BEGIN_FTR_SECTION_NESTED(52)
+ PPC_POPCNTB(r3,r3)
+ srdi r4,r3,32
+ add r3,r4,r3
+ srdi r4,r3,16
+ add r3,r4,r3
+ srdi r4,r3,8
+ add r3,r4,r3
+ clrldi r3,r3,64-8
+ blr
+ FTR_SECTION_ELSE_NESTED(52)
+ PPC_POPCNTD(r3,r3)
+ clrldi r3,r3,64-8
+ blr
+ ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 52)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 5e9584405c45..a5991facddce 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1070,7 +1070,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap)
{
unsigned long vsid;
- void *pgdir;
+ pgd_t *pgdir;
pte_t *ptep;
unsigned long flags;
int rc, ssize, local = 0;
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 5ce99848d91e..c0aab52da3a5 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -111,8 +111,8 @@ static unsigned int steal_context_smp(unsigned int id)
* a core map instead but this will do for now.
*/
for_each_cpu(cpu, mm_cpumask(mm)) {
- for (i = cpu_first_thread_in_core(cpu);
- i <= cpu_last_thread_in_core(cpu); i++)
+ for (i = cpu_first_thread_sibling(cpu);
+ i <= cpu_last_thread_sibling(cpu); i++)
__set_bit(id, stale_map[i]);
cpu = i - 1;
}
@@ -264,14 +264,14 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
*/
if (test_bit(id, stale_map[cpu])) {
pr_hardcont(" | stale flush %d [%d..%d]",
- id, cpu_first_thread_in_core(cpu),
- cpu_last_thread_in_core(cpu));
+ id, cpu_first_thread_sibling(cpu),
+ cpu_last_thread_sibling(cpu));
local_flush_tlb_mm(next);
/* XXX This clear should ultimately be part of local_flush_tlb_mm */
- for (i = cpu_first_thread_in_core(cpu);
- i <= cpu_last_thread_in_core(cpu); i++) {
+ for (i = cpu_first_thread_sibling(cpu);
+ i <= cpu_last_thread_sibling(cpu); i++) {
__clear_bit(id, stale_map[i]);
}
}
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 74505b245374..d644ba7e8aba 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -20,10 +20,14 @@
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/pfn.h>
+#include <linux/cpuset.h>
+#include <linux/node.h>
#include <asm/sparsemem.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/smp.h>
+#include <asm/firmware.h>
+#include <asm/paca.h>
static int numa_enabled = 1;
@@ -246,32 +250,41 @@ static void initialize_distance_lookup_table(int nid,
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
* info is found.
*/
-static int of_node_to_nid_single(struct device_node *device)
+static int associativity_to_nid(const unsigned int *associativity)
{
int nid = -1;
- const unsigned int *tmp;
if (min_common_depth == -1)
goto out;
- tmp = of_get_associativity(device);
- if (!tmp)
- goto out;
-
- if (tmp[0] >= min_common_depth)
- nid = tmp[min_common_depth];
+ if (associativity[0] >= min_common_depth)
+ nid = associativity[min_common_depth];
/* POWER4 LPAR uses 0xffff as invalid node */
if (nid == 0xffff || nid >= MAX_NUMNODES)
nid = -1;
- if (nid > 0 && tmp[0] >= distance_ref_points_depth)
- initialize_distance_lookup_table(nid, tmp);
+ if (nid > 0 && associativity[0] >= distance_ref_points_depth)
+ initialize_distance_lookup_table(nid, associativity);
out:
return nid;
}
+/* Returns the nid associated with the given device tree node,
+ * or -1 if not found.
+ */
+static int of_node_to_nid_single(struct device_node *device)
+{
+ int nid = -1;
+ const unsigned int *tmp;
+
+ tmp = of_get_associativity(device);
+ if (tmp)
+ nid = associativity_to_nid(tmp);
+ return nid;
+}
+
/* Walk the device tree upwards, looking for an associativity id */
int of_node_to_nid(struct device_node *device)
{
@@ -1247,4 +1260,274 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
return nid;
}
+static u64 hot_add_drconf_memory_max(void)
+{
+ struct device_node *memory = NULL;
+ unsigned int drconf_cell_cnt = 0;
+ u64 lmb_size = 0;
+ const u32 *dm = 0;
+
+ memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (memory) {
+ drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
+ lmb_size = of_get_lmb_size(memory);
+ of_node_put(memory);
+ }
+ return lmb_size * drconf_cell_cnt;
+}
+
+/*
+ * memory_hotplug_max - return max address of memory that may be added
+ *
+ * This is currently only used on systems that support drconfig memory
+ * hotplug.
+ */
+u64 memory_hotplug_max(void)
+{
+ return max(hot_add_drconf_memory_max(), memblock_end_of_DRAM());
+}
#endif /* CONFIG_MEMORY_HOTPLUG */
+
+/* Vrtual Processor Home Node (VPHN) support */
+#define VPHN_NR_CHANGE_CTRS (8)
+static u8 vphn_cpu_change_counts[NR_CPUS][VPHN_NR_CHANGE_CTRS];
+static cpumask_t cpu_associativity_changes_mask;
+static int vphn_enabled;
+static void set_topology_timer(void);
+int stop_topology_update(void);
+
+/*
+ * Store the current values of the associativity change counters in the
+ * hypervisor.
+ */
+static void setup_cpu_associativity_change_counters(void)
+{
+ int cpu = 0;
+
+ for_each_possible_cpu(cpu) {
+ int i = 0;
+ u8 *counts = vphn_cpu_change_counts[cpu];
+ volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
+
+ for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
+ counts[i] = hypervisor_counts[i];
+ }
+ }
+}
+
+/*
+ * The hypervisor maintains a set of 8 associativity change counters in
+ * the VPA of each cpu that correspond to the associativity levels in the
+ * ibm,associativity-reference-points property. When an associativity
+ * level changes, the corresponding counter is incremented.
+ *
+ * Set a bit in cpu_associativity_changes_mask for each cpu whose home
+ * node associativity levels have changed.
+ *
+ * Returns the number of cpus with unhandled associativity changes.
+ */
+static int update_cpu_associativity_changes_mask(void)
+{
+ int cpu = 0, nr_cpus = 0;
+ cpumask_t *changes = &cpu_associativity_changes_mask;
+
+ cpumask_clear(changes);
+
+ for_each_possible_cpu(cpu) {
+ int i, changed = 0;
+ u8 *counts = vphn_cpu_change_counts[cpu];
+ volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
+
+ for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
+ if (hypervisor_counts[i] > counts[i]) {
+ counts[i] = hypervisor_counts[i];
+ changed = 1;
+ }
+ }
+ if (changed) {
+ cpumask_set_cpu(cpu, changes);
+ nr_cpus++;
+ }
+ }
+
+ return nr_cpus;
+}
+
+/* 6 64-bit registers unpacked into 12 32-bit associativity values */
+#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32))
+
+/*
+ * Convert the associativity domain numbers returned from the hypervisor
+ * to the sequence they would appear in the ibm,associativity property.
+ */
+static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
+{
+ int i = 0;
+ int nr_assoc_doms = 0;
+ const u16 *field = (const u16*) packed;
+
+#define VPHN_FIELD_UNUSED (0xffff)
+#define VPHN_FIELD_MSB (0x8000)
+#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
+
+ for (i = 0; i < VPHN_ASSOC_BUFSIZE; i++) {
+ if (*field == VPHN_FIELD_UNUSED) {
+ /* All significant fields processed, and remaining
+ * fields contain the reserved value of all 1's.
+ * Just store them.
+ */
+ unpacked[i] = *((u32*)field);
+ field += 2;
+ }
+ else if (*field & VPHN_FIELD_MSB) {
+ /* Data is in the lower 15 bits of this field */
+ unpacked[i] = *field & VPHN_FIELD_MASK;
+ field++;
+ nr_assoc_doms++;
+ }
+ else {
+ /* Data is in the lower 15 bits of this field
+ * concatenated with the next 16 bit field
+ */
+ unpacked[i] = *((u32*)field);
+ field += 2;
+ nr_assoc_doms++;
+ }
+ }
+
+ return nr_assoc_doms;
+}
+
+/*
+ * Retrieve the new associativity information for a virtual processor's
+ * home node.
+ */
+static long hcall_vphn(unsigned long cpu, unsigned int *associativity)
+{
+ long rc = 0;
+ long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+ u64 flags = 1;
+ int hwcpu = get_hard_smp_processor_id(cpu);
+
+ rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
+ vphn_unpack_associativity(retbuf, associativity);
+
+ return rc;
+}
+
+static long vphn_get_associativity(unsigned long cpu,
+ unsigned int *associativity)
+{
+ long rc = 0;
+
+ rc = hcall_vphn(cpu, associativity);
+
+ switch (rc) {
+ case H_FUNCTION:
+ printk(KERN_INFO
+ "VPHN is not supported. Disabling polling...\n");
+ stop_topology_update();
+ break;
+ case H_HARDWARE:
+ printk(KERN_ERR
+ "hcall_vphn() experienced a hardware fault "
+ "preventing VPHN. Disabling polling...\n");
+ stop_topology_update();
+ }
+
+ return rc;
+}
+
+/*
+ * Update the node maps and sysfs entries for each cpu whose home node
+ * has changed.
+ */
+int arch_update_cpu_topology(void)
+{
+ int cpu = 0, nid = 0, old_nid = 0;
+ unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
+ struct sys_device *sysdev = NULL;
+
+ for_each_cpu_mask(cpu, cpu_associativity_changes_mask) {
+ vphn_get_associativity(cpu, associativity);
+ nid = associativity_to_nid(associativity);
+
+ if (nid < 0 || !node_online(nid))
+ nid = first_online_node;
+
+ old_nid = numa_cpu_lookup_table[cpu];
+
+ /* Disable hotplug while we update the cpu
+ * masks and sysfs.
+ */
+ get_online_cpus();
+ unregister_cpu_under_node(cpu, old_nid);
+ unmap_cpu_from_node(cpu);
+ map_cpu_to_node(cpu, nid);
+ register_cpu_under_node(cpu, nid);
+ put_online_cpus();
+
+ sysdev = get_cpu_sysdev(cpu);
+ if (sysdev)
+ kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
+ }
+
+ return 1;
+}
+
+static void topology_work_fn(struct work_struct *work)
+{
+ rebuild_sched_domains();
+}
+static DECLARE_WORK(topology_work, topology_work_fn);
+
+void topology_schedule_update(void)
+{
+ schedule_work(&topology_work);
+}
+
+static void topology_timer_fn(unsigned long ignored)
+{
+ if (!vphn_enabled)
+ return;
+ if (update_cpu_associativity_changes_mask() > 0)
+ topology_schedule_update();
+ set_topology_timer();
+}
+static struct timer_list topology_timer =
+ TIMER_INITIALIZER(topology_timer_fn, 0, 0);
+
+static void set_topology_timer(void)
+{
+ topology_timer.data = 0;
+ topology_timer.expires = jiffies + 60 * HZ;
+ add_timer(&topology_timer);
+}
+
+/*
+ * Start polling for VPHN associativity changes.
+ */
+int start_topology_update(void)
+{
+ int rc = 0;
+
+ if (firmware_has_feature(FW_FEATURE_VPHN)) {
+ vphn_enabled = 1;
+ setup_cpu_associativity_change_counters();
+ init_timer_deferrable(&topology_timer);
+ set_topology_timer();
+ rc = 1;
+ }
+
+ return rc;
+}
+__initcall(start_topology_update);
+
+/*
+ * Disable polling for VPHN associativity changes.
+ */
+int stop_topology_update(void)
+{
+ vphn_enabled = 0;
+ return del_timer_sync(&topology_timer);
+}
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index a87ead0138b4..8dc41c0157fe 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -78,7 +78,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
/* pgdir take page or two with 4K pages and a page fraction otherwise */
#ifndef CONFIG_PPC_4K_PAGES
- ret = (pgd_t *)kzalloc(1 << PGDIR_ORDER, GFP_KERNEL);
+ ret = kzalloc(1 << PGDIR_ORDER, GFP_KERNEL);
#else
ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
PGDIR_ORDER - PAGE_SHIFT);
@@ -230,6 +230,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
area = get_vm_area_caller(size, VM_IOREMAP, caller);
if (area == 0)
return NULL;
+ area->phys_addr = p;
v = (unsigned long) area->addr;
} else {
v = (ioremap_bot -= size);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 21d6dfab7942..88927a05cdc2 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -223,6 +223,8 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
caller);
if (area == NULL)
return NULL;
+
+ area->phys_addr = paligned;
ret = __ioremap_at(paligned, area->addr, size, flags);
if (!ret)
vunmap(area->addr);
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 82ff326e0795..c04d16df8488 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -1,4 +1,7 @@
-obj-$(CONFIG_44x) := misc_44x.o idle.o
+obj-$(CONFIG_44x) += misc_44x.o
+ifneq ($(CONFIG_PPC4xx_CPM),y)
+obj-$(CONFIG_44x) += idle.o
+endif
obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o
obj-$(CONFIG_EBONY) += ebony.o
obj-$(CONFIG_SAM440EP) += sam440ep.o
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index fea833e18ad5..e0d703c7fdf7 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -63,6 +63,7 @@
#include <linux/of_gpio.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/fs.h>
#include <linux/watchdog.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 956154f32cfe..20576829eca5 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -313,13 +313,14 @@ config OF_RTC
source "arch/powerpc/sysdev/bestcomm/Kconfig"
config MPC8xxx_GPIO
- bool "MPC8xxx GPIO support"
- depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || FSL_SOC_BOOKE || PPC_86xx
+ bool "MPC512x/MPC8xxx GPIO support"
+ depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
+ FSL_SOC_BOOKE || PPC_86xx
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
Say Y here if you're going to use hardware that connects to the
- MPC831x/834x/837x/8572/8610 GPIOs.
+ MPC512x/831x/834x/837x/8572/8610 GPIOs.
config SIMPLE_GPIO
bool "Support for simple, memory-mapped GPIO controllers"
diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c
index beec405eb6f8..3ce685568935 100644
--- a/arch/powerpc/platforms/cell/beat_iommu.c
+++ b/arch/powerpc/platforms/cell/beat_iommu.c
@@ -76,7 +76,7 @@ static void __init celleb_init_direct_mapping(void)
static void celleb_dma_dev_setup(struct device *dev)
{
- dev->archdata.dma_ops = get_pci_dma_ops();
+ set_dma_ops(dev, &dma_direct_ops);
set_dma_offset(dev, celleb_dma_direct_offset);
}
@@ -106,7 +106,6 @@ static struct notifier_block celleb_of_bus_notifier = {
static int __init celleb_init_iommu(void)
{
celleb_init_direct_mapping();
- set_pci_dma_ops(&dma_direct_ops);
ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 3532b92de983..856e9c398068 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -71,12 +71,18 @@ spufs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void
-spufs_destroy_inode(struct inode *inode)
+static void spufs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(spufs_inode_cache, SPUFS_I(inode));
}
+static void spufs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, spufs_i_callback);
+}
+
static void
spufs_init_once(void *p)
{
@@ -159,18 +165,18 @@ static void spufs_prune_dir(struct dentry *dir)
mutex_lock(&dir->d_inode->i_mutex);
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
- spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry)) && dentry->d_inode) {
- dget_locked(dentry);
+ dget_dlock(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
simple_unlink(dir->d_inode, dentry);
- spin_unlock(&dcache_lock);
+ /* XXX: what was dcache_lock protecting here? Other
+ * filesystems (IB, configfs) release dcache_lock
+ * before unlink */
dput(dentry);
} else {
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
}
}
shrink_dcache_parent(dir);
diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
index a101abf17504..3b894f585280 100644
--- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
+++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
@@ -36,10 +36,9 @@ static int spu_alloc_lscsa_std(struct spu_state *csa)
struct spu_lscsa *lscsa;
unsigned char *p;
- lscsa = vmalloc(sizeof(struct spu_lscsa));
+ lscsa = vzalloc(sizeof(struct spu_lscsa));
if (!lscsa)
return -ENOMEM;
- memset(lscsa, 0, sizeof(struct spu_lscsa));
csa->lscsa = lscsa;
/* Set LS pages reserved to allow for user-space mapping. */
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 054dfe5b8e77..f803f4b8ab6f 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -29,6 +29,10 @@
extern spinlock_t rtc_lock;
+#define NVRAM_AS0 0x74
+#define NVRAM_AS1 0x75
+#define NVRAM_DATA 0x77
+
static int nvram_as1 = NVRAM_AS1;
static int nvram_as0 = NVRAM_AS0;
static int nvram_data = NVRAM_DATA;
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 42d0a886de05..b5e026bdca21 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -1045,71 +1045,9 @@ static const struct file_operations mf_side_proc_fops = {
.write = mf_side_proc_write,
};
-#if 0
-static void mf_getSrcHistory(char *buffer, int size)
-{
- struct IplTypeReturnStuff return_stuff;
- struct pending_event *ev = new_pending_event();
- int rc = 0;
- char *pages[4];
-
- pages[0] = kmalloc(4096, GFP_ATOMIC);
- pages[1] = kmalloc(4096, GFP_ATOMIC);
- pages[2] = kmalloc(4096, GFP_ATOMIC);
- pages[3] = kmalloc(4096, GFP_ATOMIC);
- if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL)
- || (pages[2] == NULL) || (pages[3] == NULL))
- return -ENOMEM;
-
- return_stuff.xType = 0;
- return_stuff.xRc = 0;
- return_stuff.xDone = 0;
- ev->event.hp_lp_event.xSubtype = 6;
- ev->event.hp_lp_event.x.xSubtypeData =
- subtype_data('M', 'F', 'V', 'I');
- ev->event.data.vsp_cmd.xEvent = &return_stuff;
- ev->event.data.vsp_cmd.cmd = 4;
- ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
- ev->event.data.vsp_cmd.result_code = 0xFF;
- ev->event.data.vsp_cmd.reserved = 0;
- ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]);
- ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]);
- ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]);
- ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]);
- mb();
- if (signal_event(ev) != 0)
- return;
-
- while (return_stuff.xDone != 1)
- udelay(10);
- if (return_stuff.xRc == 0)
- memcpy(buffer, pages[0], size);
- kfree(pages[0]);
- kfree(pages[1]);
- kfree(pages[2]);
- kfree(pages[3]);
-}
-#endif
-
static int mf_src_proc_show(struct seq_file *m, void *v)
{
-#if 0
- int len;
-
- mf_getSrcHistory(page, count);
- len = count;
- len -= off;
- if (len < count) {
- *eof = 1;
- if (len <= 0)
- return 0;
- } else
- len = count;
- *start = page + off;
- return len;
-#else
return 0;
-#endif
}
static int mf_src_proc_open(struct inode *inode, struct file *file)
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 1f9fb2c57761..14943ef01918 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -156,20 +156,12 @@ static void iommu_table_iobmap_setup(void)
static void pci_dma_bus_setup_pasemi(struct pci_bus *bus)
{
- struct device_node *dn;
-
pr_debug("pci_dma_bus_setup, bus %p, bus->self %p\n", bus, bus->self);
if (!iommu_table_iobmap_inited) {
iommu_table_iobmap_inited = 1;
iommu_table_iobmap_setup();
}
-
- dn = pci_bus_to_OF_node(bus);
-
- if (dn)
- PCI_DN(dn)->iommu_table = &iommu_table_iobmap;
-
}
@@ -192,9 +184,6 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
set_iommu_table_base(&dev->dev, &iommu_table_iobmap);
}
-static void pci_dma_bus_setup_null(struct pci_bus *b) { }
-static void pci_dma_dev_setup_null(struct pci_dev *d) { }
-
int __init iob_init(struct device_node *dn)
{
unsigned long tmp;
@@ -251,14 +240,8 @@ void __init iommu_init_early_pasemi(void)
iommu_off = of_chosen &&
of_get_property(of_chosen, "linux,iommu-off", NULL);
#endif
- if (iommu_off) {
- /* Direct I/O, IOMMU off */
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_null;
- ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_null;
- set_pci_dma_ops(&dma_direct_ops);
-
+ if (iommu_off)
return;
- }
iob_init(NULL);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 9deb274841f1..d5aceb7fb125 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -506,6 +506,15 @@ static int __init pmac_declare_of_platform_devices(void)
of_platform_device_create(np, "smu", NULL);
of_node_put(np);
}
+ np = of_find_node_by_type(NULL, "fcu");
+ if (np == NULL) {
+ /* Some machines have strangely broken device-tree */
+ np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e");
+ }
+ if (np) {
+ of_platform_device_create(np, "temperature", NULL);
+ of_node_put(np);
+ }
return 0;
}
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 3139814f6439..5d1b743dbe7e 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -33,6 +33,16 @@ config PSERIES_MSI
depends on PCI_MSI && EEH
default y
+config PSERIES_ENERGY
+ tristate "pSeries energy management capabilities driver"
+ depends on PPC_PSERIES
+ default y
+ help
+ Provides interface to platform energy management capabilities
+ on supported PSERIES platforms.
+ Provides: /sys/devices/system/cpu/pseries_(de)activation_hint_list
+ and /sys/devices/system/cpu/cpuN/pseries_(de)activation_hint
+
config SCANLOG
tristate "Scanlog dump interface"
depends on RTAS_PROC && PPC_PSERIES
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 59eb8bdaa79d..fc5237810ece 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
obj-$(CONFIG_PSERIES_MSI) += msi.o
+obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 0a14d8cd314f..0b0eff0cce35 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -55,6 +55,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
{FW_FEATURE_XDABR, "hcall-xdabr"},
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
{FW_FEATURE_SPLPAR, "hcall-splpar"},
+ {FW_FEATURE_VPHN, "hcall-vphn"},
};
/* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 48d20573e4de..fd05fdee576a 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -11,6 +11,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
#define STK_PARM(i) (48 + ((i)-3)*8)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index a77bcaed80af..edea60b7ee90 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -140,7 +140,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
return ret;
}
-static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
+static DEFINE_PER_CPU(u64 *, tce_page);
static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
@@ -323,14 +323,13 @@ static void iommu_table_setparms(struct pci_controller *phb,
static void iommu_table_setparms_lpar(struct pci_controller *phb,
struct device_node *dn,
struct iommu_table *tbl,
- const void *dma_window,
- int bussubno)
+ const void *dma_window)
{
unsigned long offset, size;
- tbl->it_busno = bussubno;
of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
+ tbl->it_busno = phb->bus->number;
tbl->it_base = 0;
tbl->it_blocksize = 16;
tbl->it_type = TCE_PCI;
@@ -450,14 +449,10 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
if (!ppci->iommu_table) {
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
ppci->phb->node);
- iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
- bus->number);
+ iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
pr_debug(" created table: %p\n", ppci->iommu_table);
}
-
- if (pdn != dn)
- PCI_DN(dn)->iommu_table = ppci->iommu_table;
}
@@ -533,21 +528,11 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
}
pr_debug(" parent is %s\n", pdn->full_name);
- /* Check for parent == NULL so we don't try to setup the empty EADS
- * slots on POWER4 machines.
- */
- if (dma_window == NULL || pdn->parent == NULL) {
- pr_debug(" no dma window for device, linking to parent\n");
- set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table);
- return;
- }
-
pci = PCI_DN(pdn);
if (!pci->iommu_table) {
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
- iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
- pci->phb->bus->number);
+ iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
pr_debug(" created table: %p\n", pci->iommu_table);
} else {
@@ -571,8 +556,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
switch (action) {
case PSERIES_RECONFIG_REMOVE:
- if (pci && pci->iommu_table &&
- of_get_property(np, "ibm,dma-window", NULL))
+ if (pci && pci->iommu_table)
iommu_free_table(pci->iommu_table, np->full_name);
break;
default:
@@ -589,13 +573,8 @@ static struct notifier_block iommu_reconfig_nb = {
/* These are called very early. */
void iommu_init_early_pSeries(void)
{
- if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL)) {
- /* Direct I/O, IOMMU off */
- ppc_md.pci_dma_dev_setup = NULL;
- ppc_md.pci_dma_bus_setup = NULL;
- set_pci_dma_ops(&dma_direct_ops);
+ if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL))
return;
- }
if (firmware_has_feature(FW_FEATURE_LPAR)) {
if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
@@ -622,3 +601,17 @@ void iommu_init_early_pSeries(void)
set_pci_dma_ops(&dma_iommu_ops);
}
+static int __init disable_multitce(char *str)
+{
+ if (strcmp(str, "off") == 0 &&
+ firmware_has_feature(FW_FEATURE_LPAR) &&
+ firmware_has_feature(FW_FEATURE_MULTITCE)) {
+ printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
+ ppc_md.tce_build = tce_build_pSeriesLP;
+ ppc_md.tce_free = tce_free_pSeriesLP;
+ powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
+ }
+ return 1;
+}
+
+__setup("multitce=", disable_multitce);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index f129040d974c..5d3ea9f60dd7 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -627,6 +627,18 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
}
+static int __init disable_bulk_remove(char *str)
+{
+ if (strcmp(str, "off") == 0 &&
+ firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+ printk(KERN_INFO "Disabling BULK_REMOVE firmware feature");
+ powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE;
+ }
+ return 1;
+}
+
+__setup("bulk_remove=", disable_bulk_remove);
+
void __init hpte_init_lpar(void)
{
ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index bc3c7f2abd79..7e828ba29bc3 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -22,11 +22,25 @@
#include <asm/prom.h>
#include <asm/machdep.h>
+/* Max bytes to read/write in one go */
+#define NVRW_CNT 0x20
+
static unsigned int nvram_size;
static int nvram_fetch, nvram_store;
static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
static DEFINE_SPINLOCK(nvram_lock);
+static long nvram_error_log_index = -1;
+static long nvram_error_log_size = 0;
+
+struct err_log_info {
+ int error_type;
+ unsigned int seq_num;
+};
+#define NVRAM_MAX_REQ 2079
+#define NVRAM_MIN_REQ 1055
+
+#define NVRAM_LOG_PART_NAME "ibm,rtas-log"
static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
{
@@ -119,6 +133,197 @@ static ssize_t pSeries_nvram_get_size(void)
return nvram_size ? nvram_size : -ENODEV;
}
+
+/* nvram_write_error_log
+ *
+ * We need to buffer the error logs into nvram to ensure that we have
+ * the failure information to decode. If we have a severe error there
+ * is no way to guarantee that the OS or the machine is in a state to
+ * get back to user land and write the error to disk. For example if
+ * the SCSI device driver causes a Machine Check by writing to a bad
+ * IO address, there is no way of guaranteeing that the device driver
+ * is in any state that is would also be able to write the error data
+ * captured to disk, thus we buffer it in NVRAM for analysis on the
+ * next boot.
+ *
+ * In NVRAM the partition containing the error log buffer will looks like:
+ * Header (in bytes):
+ * +-----------+----------+--------+------------+------------------+
+ * | signature | checksum | length | name | data |
+ * |0 |1 |2 3|4 15|16 length-1|
+ * +-----------+----------+--------+------------+------------------+
+ *
+ * The 'data' section would look like (in bytes):
+ * +--------------+------------+-----------------------------------+
+ * | event_logged | sequence # | error log |
+ * |0 3|4 7|8 nvram_error_log_size-1|
+ * +--------------+------------+-----------------------------------+
+ *
+ * event_logged: 0 if event has not been logged to syslog, 1 if it has
+ * sequence #: The unique sequence # for each event. (until it wraps)
+ * error log: The error log from event_scan
+ */
+int nvram_write_error_log(char * buff, int length,
+ unsigned int err_type, unsigned int error_log_cnt)
+{
+ int rc;
+ loff_t tmp_index;
+ struct err_log_info info;
+
+ if (nvram_error_log_index == -1) {
+ return -ESPIPE;
+ }
+
+ if (length > nvram_error_log_size) {
+ length = nvram_error_log_size;
+ }
+
+ info.error_type = err_type;
+ info.seq_num = error_log_cnt;
+
+ tmp_index = nvram_error_log_index;
+
+ rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
+ return rc;
+ }
+
+ rc = ppc_md.nvram_write(buff, length, &tmp_index);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char * buff, int length,
+ unsigned int * err_type, unsigned int * error_log_cnt)
+{
+ int rc;
+ loff_t tmp_index;
+ struct err_log_info info;
+
+ if (nvram_error_log_index == -1)
+ return -1;
+
+ if (length > nvram_error_log_size)
+ length = nvram_error_log_size;
+
+ tmp_index = nvram_error_log_index;
+
+ rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
+ return rc;
+ }
+
+ rc = ppc_md.nvram_read(buff, length, &tmp_index);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
+ return rc;
+ }
+
+ *error_log_cnt = info.seq_num;
+ *err_type = info.error_type;
+
+ return 0;
+}
+
+/* This doesn't actually zero anything, but it sets the event_logged
+ * word to tell that this event is safely in syslog.
+ */
+int nvram_clear_error_log(void)
+{
+ loff_t tmp_index;
+ int clear_word = ERR_FLAG_ALREADY_LOGGED;
+ int rc;
+
+ if (nvram_error_log_index == -1)
+ return -1;
+
+ tmp_index = nvram_error_log_index;
+
+ rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
+ if (rc <= 0) {
+ printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+/* pseries_nvram_init_log_partition
+ *
+ * This will setup the partition we need for buffering the
+ * error logs and cleanup partitions if needed.
+ *
+ * The general strategy is the following:
+ * 1.) If there is log partition large enough then use it.
+ * 2.) If there is none large enough, search
+ * for a free partition that is large enough.
+ * 3.) If there is not a free partition large enough remove
+ * _all_ OS partitions and consolidate the space.
+ * 4.) Will first try getting a chunk that will satisfy the maximum
+ * error log size (NVRAM_MAX_REQ).
+ * 5.) If the max chunk cannot be allocated then try finding a chunk
+ * that will satisfy the minum needed (NVRAM_MIN_REQ).
+ */
+static int __init pseries_nvram_init_log_partition(void)
+{
+ loff_t p;
+ int size;
+
+ /* Scan nvram for partitions */
+ nvram_scan_partitions();
+
+ /* Lookg for ours */
+ p = nvram_find_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, &size);
+
+ /* Found one but too small, remove it */
+ if (p && size < NVRAM_MIN_REQ) {
+ pr_info("nvram: Found too small "NVRAM_LOG_PART_NAME" partition"
+ ",removing it...");
+ nvram_remove_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS);
+ p = 0;
+ }
+
+ /* Create one if we didn't find */
+ if (!p) {
+ p = nvram_create_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS,
+ NVRAM_MAX_REQ, NVRAM_MIN_REQ);
+ /* No room for it, try to get rid of any OS partition
+ * and try again
+ */
+ if (p == -ENOSPC) {
+ pr_info("nvram: No room to create "NVRAM_LOG_PART_NAME
+ " partition, deleting all OS partitions...");
+ nvram_remove_partition(NULL, NVRAM_SIG_OS);
+ p = nvram_create_partition(NVRAM_LOG_PART_NAME,
+ NVRAM_SIG_OS, NVRAM_MAX_REQ,
+ NVRAM_MIN_REQ);
+ }
+ }
+
+ if (p <= 0) {
+ pr_err("nvram: Failed to find or create "NVRAM_LOG_PART_NAME
+ " partition, err %d\n", (int)p);
+ return 0;
+ }
+
+ nvram_error_log_index = p;
+ nvram_error_log_size = nvram_get_partition_size(p) -
+ sizeof(struct err_log_info);
+
+ return 0;
+}
+machine_arch_initcall(pseries, pseries_nvram_init_log_partition);
+
int __init pSeries_nvram_init(void)
{
struct device_node *nvram;
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
new file mode 100644
index 000000000000..c8b3c69fe891
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -0,0 +1,326 @@
+/*
+ * POWER platform energy management driver
+ * Copyright (C) 2010 IBM 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 pseries platform device driver provides access to
+ * platform energy management capabilities.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <asm/cputhreads.h>
+#include <asm/page.h>
+#include <asm/hvcall.h>
+
+
+#define MODULE_VERS "1.0"
+#define MODULE_NAME "pseries_energy"
+
+/* Driver flags */
+
+static int sysfs_entries;
+
+/* Helper routines */
+
+/*
+ * Routine to detect firmware support for hcall
+ * return 1 if H_BEST_ENERGY is supported
+ * else return 0
+ */
+
+static int check_for_h_best_energy(void)
+{
+ struct device_node *rtas = NULL;
+ const char *hypertas, *s;
+ int length;
+ int rc = 0;
+
+ rtas = of_find_node_by_path("/rtas");
+ if (!rtas)
+ return 0;
+
+ hypertas = of_get_property(rtas, "ibm,hypertas-functions", &length);
+ if (!hypertas) {
+ of_node_put(rtas);
+ return 0;
+ }
+
+ /* hypertas will have list of strings with hcall names */
+ for (s = hypertas; s < hypertas + length; s += strlen(s) + 1) {
+ if (!strncmp("hcall-best-energy-1", s, 19)) {
+ rc = 1; /* Found the string */
+ break;
+ }
+ }
+ of_node_put(rtas);
+ return rc;
+}
+
+/* Helper Routines to convert between drc_index to cpu numbers */
+
+static u32 cpu_to_drc_index(int cpu)
+{
+ struct device_node *dn = NULL;
+ const int *indexes;
+ int i;
+ int rc = 1;
+ u32 ret = 0;
+
+ dn = of_find_node_by_path("/cpus");
+ if (dn == NULL)
+ goto err;
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ if (indexes == NULL)
+ goto err_of_node_put;
+ /* Convert logical cpu number to core number */
+ i = cpu_core_index_of_thread(cpu);
+ /*
+ * The first element indexes[0] is the number of drc_indexes
+ * returned in the list. Hence i+1 will get the drc_index
+ * corresponding to core number i.
+ */
+ WARN_ON(i > indexes[0]);
+ ret = indexes[i + 1];
+ rc = 0;
+
+err_of_node_put:
+ of_node_put(dn);
+err:
+ if (rc)
+ printk(KERN_WARNING "cpu_to_drc_index(%d) failed", cpu);
+ return ret;
+}
+
+static int drc_index_to_cpu(u32 drc_index)
+{
+ struct device_node *dn = NULL;
+ const int *indexes;
+ int i, cpu = 0;
+ int rc = 1;
+
+ dn = of_find_node_by_path("/cpus");
+ if (dn == NULL)
+ goto err;
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ if (indexes == NULL)
+ goto err_of_node_put;
+ /*
+ * First element in the array is the number of drc_indexes
+ * returned. Search through the list to find the matching
+ * drc_index and get the core number
+ */
+ for (i = 0; i < indexes[0]; i++) {
+ if (indexes[i + 1] == drc_index)
+ break;
+ }
+ /* Convert core number to logical cpu number */
+ cpu = cpu_first_thread_of_core(i);
+ rc = 0;
+
+err_of_node_put:
+ of_node_put(dn);
+err:
+ if (rc)
+ printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index);
+ return cpu;
+}
+
+/*
+ * pseries hypervisor call H_BEST_ENERGY provides hints to OS on
+ * preferred logical cpus to activate or deactivate for optimized
+ * energy consumption.
+ */
+
+#define FLAGS_MODE1 0x004E200000080E01
+#define FLAGS_MODE2 0x004E200000080401
+#define FLAGS_ACTIVATE 0x100
+
+static ssize_t get_best_energy_list(char *page, int activate)
+{
+ int rc, cnt, i, cpu;
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long flags = 0;
+ u32 *buf_page;
+ char *s = page;
+
+ buf_page = (u32 *) get_zeroed_page(GFP_KERNEL);
+ if (!buf_page)
+ return -ENOMEM;
+
+ flags = FLAGS_MODE1;
+ if (activate)
+ flags |= FLAGS_ACTIVATE;
+
+ rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags, 0, __pa(buf_page),
+ 0, 0, 0, 0, 0, 0);
+ if (rc != H_SUCCESS) {
+ free_page((unsigned long) buf_page);
+ return -EINVAL;
+ }
+
+ cnt = retbuf[0];
+ for (i = 0; i < cnt; i++) {
+ cpu = drc_index_to_cpu(buf_page[2*i+1]);
+ if ((cpu_online(cpu) && !activate) ||
+ (!cpu_online(cpu) && activate))
+ s += sprintf(s, "%d,", cpu);
+ }
+ if (s > page) { /* Something to show */
+ s--; /* Suppress last comma */
+ s += sprintf(s, "\n");
+ }
+
+ free_page((unsigned long) buf_page);
+ return s-page;
+}
+
+static ssize_t get_best_energy_data(struct sys_device *dev,
+ char *page, int activate)
+{
+ int rc;
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long flags = 0;
+
+ flags = FLAGS_MODE2;
+ if (activate)
+ flags |= FLAGS_ACTIVATE;
+
+ rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags,
+ cpu_to_drc_index(dev->id),
+ 0, 0, 0, 0, 0, 0, 0);
+
+ if (rc != H_SUCCESS)
+ return -EINVAL;
+
+ return sprintf(page, "%lu\n", retbuf[1] >> 32);
+}
+
+/* Wrapper functions */
+
+static ssize_t cpu_activate_hint_list_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *page)
+{
+ return get_best_energy_list(page, 1);
+}
+
+static ssize_t cpu_deactivate_hint_list_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *page)
+{
+ return get_best_energy_list(page, 0);
+}
+
+static ssize_t percpu_activate_hint_show(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *page)
+{
+ return get_best_energy_data(dev, page, 1);
+}
+
+static ssize_t percpu_deactivate_hint_show(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *page)
+{
+ return get_best_energy_data(dev, page, 0);
+}
+
+/*
+ * Create sysfs interface:
+ * /sys/devices/system/cpu/pseries_activate_hint_list
+ * /sys/devices/system/cpu/pseries_deactivate_hint_list
+ * Comma separated list of cpus to activate or deactivate
+ * /sys/devices/system/cpu/cpuN/pseries_activate_hint
+ * /sys/devices/system/cpu/cpuN/pseries_deactivate_hint
+ * Per-cpu value of the hint
+ */
+
+struct sysdev_class_attribute attr_cpu_activate_hint_list =
+ _SYSDEV_CLASS_ATTR(pseries_activate_hint_list, 0444,
+ cpu_activate_hint_list_show, NULL);
+
+struct sysdev_class_attribute attr_cpu_deactivate_hint_list =
+ _SYSDEV_CLASS_ATTR(pseries_deactivate_hint_list, 0444,
+ cpu_deactivate_hint_list_show, NULL);
+
+struct sysdev_attribute attr_percpu_activate_hint =
+ _SYSDEV_ATTR(pseries_activate_hint, 0444,
+ percpu_activate_hint_show, NULL);
+
+struct sysdev_attribute attr_percpu_deactivate_hint =
+ _SYSDEV_ATTR(pseries_deactivate_hint, 0444,
+ percpu_deactivate_hint_show, NULL);
+
+static int __init pseries_energy_init(void)
+{
+ int cpu, err;
+ struct sys_device *cpu_sys_dev;
+
+ if (!check_for_h_best_energy()) {
+ printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n");
+ return 0;
+ }
+ /* Create the sysfs files */
+ err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_activate_hint_list.attr);
+ if (!err)
+ err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_deactivate_hint_list.attr);
+
+ if (err)
+ return err;
+ for_each_possible_cpu(cpu) {
+ cpu_sys_dev = get_cpu_sysdev(cpu);
+ err = sysfs_create_file(&cpu_sys_dev->kobj,
+ &attr_percpu_activate_hint.attr);
+ if (err)
+ break;
+ err = sysfs_create_file(&cpu_sys_dev->kobj,
+ &attr_percpu_deactivate_hint.attr);
+ if (err)
+ break;
+ }
+
+ if (err)
+ return err;
+
+ sysfs_entries = 1; /* Removed entries on cleanup */
+ return 0;
+
+}
+
+static void __exit pseries_energy_cleanup(void)
+{
+ int cpu;
+ struct sys_device *cpu_sys_dev;
+
+ if (!sysfs_entries)
+ return;
+
+ /* Remove the sysfs files */
+ sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_activate_hint_list.attr);
+
+ sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_deactivate_hint_list.attr);
+
+ for_each_possible_cpu(cpu) {
+ cpu_sys_dev = get_cpu_sysdev(cpu);
+ sysfs_remove_file(&cpu_sys_dev->kobj,
+ &attr_percpu_activate_hint.attr);
+ sysfs_remove_file(&cpu_sys_dev->kobj,
+ &attr_percpu_deactivate_hint.attr);
+ }
+}
+
+module_init(pseries_energy_init);
+module_exit(pseries_energy_cleanup);
+MODULE_DESCRIPTION("Driver for pSeries platform energy management");
+MODULE_AUTHOR("Vaidyanathan Srinivasan");
+MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 0bef9dacb64e..9c2973479142 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_4xx) += ppc4xx_pci.o
endif
+obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o
obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o
obj-$(CONFIG_CPM) += cpm_common.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 17cf15ec38be..8e9e06a7ca59 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -312,17 +312,10 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev)
static void pci_dma_bus_setup_dart(struct pci_bus *bus)
{
- struct device_node *dn;
-
if (!iommu_table_dart_inited) {
iommu_table_dart_inited = 1;
iommu_table_dart_setup();
}
-
- dn = pci_bus_to_OF_node(bus);
-
- if (dn)
- PCI_DN(dn)->iommu_table = &iommu_table_dart;
}
static bool dart_device_on_pcie(struct device *dev)
@@ -373,7 +366,7 @@ void __init iommu_init_early_dart(void)
if (dn == NULL) {
dn = of_find_compatible_node(NULL, "dart", "u4-dart");
if (dn == NULL)
- goto bail;
+ return; /* use default direct_dma_ops */
dart_is_u4 = 1;
}
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index c0ea05e87f1d..c48cd8178079 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -1,5 +1,5 @@
/*
- * GPIOs on MPC8349/8572/8610 and compatible
+ * GPIOs on MPC512x/8349/8572/8610 and compatible
*
* Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
*
@@ -26,6 +26,7 @@
#define GPIO_IER 0x0c
#define GPIO_IMR 0x10
#define GPIO_ICR 0x14
+#define GPIO_ICR2 0x18
struct mpc8xxx_gpio_chip {
struct of_mm_gpio_chip mm_gc;
@@ -37,6 +38,7 @@ struct mpc8xxx_gpio_chip {
*/
u32 data;
struct irq_host *irq;
+ void *of_dev_id_data;
};
static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
@@ -215,6 +217,51 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
return 0;
}
+static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned long gpio = virq_to_hw(virq);
+ void __iomem *reg;
+ unsigned int shift;
+ unsigned long flags;
+
+ if (gpio < 16) {
+ reg = mm->regs + GPIO_ICR;
+ shift = (15 - gpio) * 2;
+ } else {
+ reg = mm->regs + GPIO_ICR2;
+ shift = (15 - (gpio % 16)) * 2;
+ }
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_FALLING:
+ case IRQ_TYPE_LEVEL_LOW:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrsetbits_be32(reg, 3 << shift, 2 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_LEVEL_HIGH:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrsetbits_be32(reg, 3 << shift, 1 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrbits32(reg, 3 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static struct irq_chip mpc8xxx_irq_chip = {
.name = "mpc8xxx-gpio",
.unmask = mpc8xxx_irq_unmask,
@@ -226,6 +273,11 @@ static struct irq_chip mpc8xxx_irq_chip = {
static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
+
+ if (mpc8xxx_gc->of_dev_id_data)
+ mpc8xxx_irq_chip.set_type = mpc8xxx_gc->of_dev_id_data;
+
set_irq_chip_data(virq, h->host_data);
set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
set_irq_type(virq, IRQ_TYPE_NONE);
@@ -253,11 +305,20 @@ static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
.xlate = mpc8xxx_gpio_irq_xlate,
};
+static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
+ { .compatible = "fsl,mpc8349-gpio", },
+ { .compatible = "fsl,mpc8572-gpio", },
+ { .compatible = "fsl,mpc8610-gpio", },
+ { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+ {}
+};
+
static void __init mpc8xxx_add_controller(struct device_node *np)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc;
struct of_mm_gpio_chip *mm_gc;
struct gpio_chip *gc;
+ const struct of_device_id *id;
unsigned hwirq;
int ret;
@@ -297,6 +358,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
if (!mpc8xxx_gc->irq)
goto skip_irq;
+ id = of_match_node(mpc8xxx_gpio_ids, np);
+ if (id)
+ mpc8xxx_gc->of_dev_id_data = id->data;
+
mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
/* ack and mask all irqs */
@@ -321,13 +386,7 @@ static int __init mpc8xxx_add_gpiochips(void)
{
struct device_node *np;
- for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio")
- mpc8xxx_add_controller(np);
-
- for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio")
- mpc8xxx_add_controller(np);
-
- for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio")
+ for_each_matching_node(np, mpc8xxx_gpio_ids)
mpc8xxx_add_controller(np);
for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/sysdev/ppc4xx_cpm.c
new file mode 100644
index 000000000000..73b86cc5ea74
--- /dev/null
+++ b/arch/powerpc/sysdev/ppc4xx_cpm.c
@@ -0,0 +1,346 @@
+/*
+ * PowerPC 4xx Clock and Power Management
+ *
+ * Copyright (C) 2010, Applied Micro Circuits Corporation
+ * Victor Gallardo (vgallardo@apm.com)
+ *
+ * Based on arch/powerpc/platforms/44x/idle.c:
+ * Jerone Young <jyoung5@us.ibm.com>
+ * Copyright 2008 IBM Corp.
+ *
+ * Based on arch/powerpc/sysdev/fsl_pmc.c:
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ * Copyright 2009 MontaVista Software, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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/of_platform.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+#include <linux/suspend.h>
+#include <asm/dcr.h>
+#include <asm/dcr-native.h>
+#include <asm/machdep.h>
+
+#define CPM_ER 0
+#define CPM_FR 1
+#define CPM_SR 2
+
+#define CPM_IDLE_WAIT 0
+#define CPM_IDLE_DOZE 1
+
+struct cpm {
+ dcr_host_t dcr_host;
+ unsigned int dcr_offset[3];
+ unsigned int powersave_off;
+ unsigned int unused;
+ unsigned int idle_doze;
+ unsigned int standby;
+ unsigned int suspend;
+};
+
+static struct cpm cpm;
+
+struct cpm_idle_mode {
+ unsigned int enabled;
+ const char *name;
+};
+
+static struct cpm_idle_mode idle_mode[] = {
+ [CPM_IDLE_WAIT] = { 1, "wait" }, /* default */
+ [CPM_IDLE_DOZE] = { 0, "doze" },
+};
+
+static unsigned int cpm_set(unsigned int cpm_reg, unsigned int mask)
+{
+ unsigned int value;
+
+ /* CPM controller supports 3 different types of sleep interface
+ * known as class 1, 2 and 3. For class 1 units, they are
+ * unconditionally put to sleep when the corresponding CPM bit is
+ * set. For class 2 and 3 units this is not case; if they can be
+ * put to to sleep, they will. Here we do not verify, we just
+ * set them and expect them to eventually go off when they can.
+ */
+ value = dcr_read(cpm.dcr_host, cpm.dcr_offset[cpm_reg]);
+ dcr_write(cpm.dcr_host, cpm.dcr_offset[cpm_reg], value | mask);
+
+ /* return old state, to restore later if needed */
+ return value;
+}
+
+static void cpm_idle_wait(void)
+{
+ unsigned long msr_save;
+
+ /* save off initial state */
+ msr_save = mfmsr();
+ /* sync required when CPM0_ER[CPU] is set */
+ mb();
+ /* set wait state MSR */
+ mtmsr(msr_save|MSR_WE|MSR_EE|MSR_CE|MSR_DE);
+ isync();
+ /* return to initial state */
+ mtmsr(msr_save);
+ isync();
+}
+
+static void cpm_idle_sleep(unsigned int mask)
+{
+ unsigned int er_save;
+
+ /* update CPM_ER state */
+ er_save = cpm_set(CPM_ER, mask);
+
+ /* go to wait state so that CPM0_ER[CPU] can take effect */
+ cpm_idle_wait();
+
+ /* restore CPM_ER state */
+ dcr_write(cpm.dcr_host, cpm.dcr_offset[CPM_ER], er_save);
+}
+
+static void cpm_idle_doze(void)
+{
+ cpm_idle_sleep(cpm.idle_doze);
+}
+
+static void cpm_idle_config(int mode)
+{
+ int i;
+
+ if (idle_mode[mode].enabled)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(idle_mode); i++)
+ idle_mode[i].enabled = 0;
+
+ idle_mode[mode].enabled = 1;
+}
+
+static ssize_t cpm_idle_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ char *s = buf;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(idle_mode); i++) {
+ if (idle_mode[i].enabled)
+ s += sprintf(s, "[%s] ", idle_mode[i].name);
+ else
+ s += sprintf(s, "%s ", idle_mode[i].name);
+ }
+
+ *(s-1) = '\n'; /* convert the last space to a newline */
+
+ return s - buf;
+}
+
+static ssize_t cpm_idle_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ int i;
+ char *p;
+ int len;
+
+ p = memchr(buf, '\n', n);
+ len = p ? p - buf : n;
+
+ for (i = 0; i < ARRAY_SIZE(idle_mode); i++) {
+ if (strncmp(buf, idle_mode[i].name, len) == 0) {
+ cpm_idle_config(i);
+ return n;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static struct kobj_attribute cpm_idle_attr =
+ __ATTR(idle, 0644, cpm_idle_show, cpm_idle_store);
+
+static void cpm_idle_config_sysfs(void)
+{
+ struct sys_device *sys_dev;
+ unsigned long ret;
+
+ sys_dev = get_cpu_sysdev(0);
+
+ ret = sysfs_create_file(&sys_dev->kobj,
+ &cpm_idle_attr.attr);
+ if (ret)
+ printk(KERN_WARNING
+ "cpm: failed to create idle sysfs entry\n");
+}
+
+static void cpm_idle(void)
+{
+ if (idle_mode[CPM_IDLE_DOZE].enabled)
+ cpm_idle_doze();
+ else
+ cpm_idle_wait();
+}
+
+static int cpm_suspend_valid(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ return !!cpm.standby;
+ case PM_SUSPEND_MEM:
+ return !!cpm.suspend;
+ default:
+ return 0;
+ }
+}
+
+static void cpm_suspend_standby(unsigned int mask)
+{
+ unsigned long tcr_save;
+
+ /* disable decrement interrupt */
+ tcr_save = mfspr(SPRN_TCR);
+ mtspr(SPRN_TCR, tcr_save & ~TCR_DIE);
+
+ /* go to sleep state */
+ cpm_idle_sleep(mask);
+
+ /* restore decrement interrupt */
+ mtspr(SPRN_TCR, tcr_save);
+}
+
+static int cpm_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ cpm_suspend_standby(cpm.standby);
+ break;
+ case PM_SUSPEND_MEM:
+ cpm_suspend_standby(cpm.suspend);
+ break;
+ }
+
+ return 0;
+}
+
+static struct platform_suspend_ops cpm_suspend_ops = {
+ .valid = cpm_suspend_valid,
+ .enter = cpm_suspend_enter,
+};
+
+static int cpm_get_uint_property(struct device_node *np,
+ const char *name)
+{
+ int len;
+ const unsigned int *prop = of_get_property(np, name, &len);
+
+ if (prop == NULL || len < sizeof(u32))
+ return 0;
+
+ return *prop;
+}
+
+static int __init cpm_init(void)
+{
+ struct device_node *np;
+ int dcr_base, dcr_len;
+ int ret = 0;
+
+ if (!cpm.powersave_off) {
+ cpm_idle_config(CPM_IDLE_WAIT);
+ ppc_md.power_save = &cpm_idle;
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "ibm,cpm");
+ if (!np) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ dcr_base = dcr_resource_start(np, 0);
+ dcr_len = dcr_resource_len(np, 0);
+
+ if (dcr_base == 0 || dcr_len == 0) {
+ printk(KERN_ERR "cpm: could not parse dcr property for %s\n",
+ np->full_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ cpm.dcr_host = dcr_map(np, dcr_base, dcr_len);
+
+ if (!DCR_MAP_OK(cpm.dcr_host)) {
+ printk(KERN_ERR "cpm: failed to map dcr property for %s\n",
+ np->full_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* All 4xx SoCs with a CPM controller have one of two
+ * different order for the CPM registers. Some have the
+ * CPM registers in the following order (ER,FR,SR). The
+ * others have them in the following order (SR,ER,FR).
+ */
+
+ if (cpm_get_uint_property(np, "er-offset") == 0) {
+ cpm.dcr_offset[CPM_ER] = 0;
+ cpm.dcr_offset[CPM_FR] = 1;
+ cpm.dcr_offset[CPM_SR] = 2;
+ } else {
+ cpm.dcr_offset[CPM_ER] = 1;
+ cpm.dcr_offset[CPM_FR] = 2;
+ cpm.dcr_offset[CPM_SR] = 0;
+ }
+
+ /* Now let's see what IPs to turn off for the following modes */
+
+ cpm.unused = cpm_get_uint_property(np, "unused-units");
+ cpm.idle_doze = cpm_get_uint_property(np, "idle-doze");
+ cpm.standby = cpm_get_uint_property(np, "standby");
+ cpm.suspend = cpm_get_uint_property(np, "suspend");
+
+ /* If some IPs are unused let's turn them off now */
+
+ if (cpm.unused) {
+ cpm_set(CPM_ER, cpm.unused);
+ cpm_set(CPM_FR, cpm.unused);
+ }
+
+ /* Now let's export interfaces */
+
+ if (!cpm.powersave_off && cpm.idle_doze)
+ cpm_idle_config_sysfs();
+
+ if (cpm.standby || cpm.suspend)
+ suspend_set_ops(&cpm_suspend_ops);
+out:
+ if (np)
+ of_node_put(np);
+ return ret;
+}
+
+late_initcall(cpm_init);
+
+static int __init cpm_powersave_off(char *arg)
+{
+ cpm.powersave_off = 1;
+ return 0;
+}
+__setup("powersave=off", cpm_powersave_off);
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index d4d15aaf18fa..5e249a85c1c0 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -83,8 +83,8 @@ static int __init tsi108_eth_of_init(void)
memset(&tsi_eth_data, 0, sizeof(tsi_eth_data));
ret = of_address_to_resource(np, 0, &r[0]);
- DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
- __func__,r[0].name, r[0].start, r[0].end);
+ DBG("%s: name:start->end = %s:%pR\n",
+ __func__, r[0].name, &r[0]);
if (ret)
goto err;
@@ -92,8 +92,8 @@ static int __init tsi108_eth_of_init(void)
r[1].start = irq_of_parse_and_map(np, 0);
r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
- DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
- __func__,r[1].name, r[1].start, r[1].end);
+ DBG("%s: name:start->end = %s:%pR\n",
+ __func__, r[1].name, &r[1]);
tsi_eth_dev =
platform_device_register_simple("tsi-ethernet", i++, &r[0],
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index e0b98e71ff47..ff19efdf6fef 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -1,13 +1,8 @@
-config SCHED_MC
- def_bool y
- depends on SMP
-
config MMU
def_bool y
config ZONE_DMA
- def_bool y
- depends on 64BIT
+ def_bool y if 64BIT
config LOCKDEP_SUPPORT
def_bool y
@@ -25,12 +20,10 @@ config RWSEM_XCHGADD_ALGORITHM
def_bool y
config ARCH_HAS_ILOG2_U32
- bool
- default n
+ def_bool n
config ARCH_HAS_ILOG2_U64
- bool
- default n
+ def_bool n
config GENERIC_HWEIGHT
def_bool y
@@ -42,9 +35,7 @@ config GENERIC_CLOCKEVENTS
def_bool y
config GENERIC_BUG
- bool
- depends on BUG
- default y
+ def_bool y if BUG
config GENERIC_BUG_RELATIVE_POINTERS
def_bool y
@@ -59,13 +50,10 @@ config ARCH_DMA_ADDR_T_64BIT
def_bool 64BIT
config GENERIC_LOCKBREAK
- bool
- default y
- depends on SMP && PREEMPT
+ def_bool y if SMP && PREEMPT
config PGSTE
- bool
- default y if KVM
+ def_bool y if KVM
config VIRT_CPU_ACCOUNTING
def_bool y
@@ -85,7 +73,6 @@ config S390
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_DEFAULT_NO_SPIN_MUTEXES
select HAVE_OPROFILE
select HAVE_KPROBES
select HAVE_KRETPROBES
@@ -99,6 +86,7 @@ config S390
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_GET_USER_PAGES_FAST
+ select HAVE_ARCH_MUTEX_CPU_RELAX
select ARCH_INLINE_SPIN_TRYLOCK
select ARCH_INLINE_SPIN_TRYLOCK_BH
select ARCH_INLINE_SPIN_LOCK
@@ -129,8 +117,7 @@ config S390
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
config SCHED_OMIT_FRAME_POINTER
- bool
- default y
+ def_bool y
source "init/Kconfig"
@@ -143,20 +130,21 @@ comment "Processor type and features"
source "kernel/time/Kconfig"
config 64BIT
- bool "64 bit kernel"
+ def_bool y
+ prompt "64 bit kernel"
help
Select this option if you have an IBM z/Architecture machine
and want to use the 64 bit addressing mode.
config 32BIT
- bool
- default y if !64BIT
+ def_bool y if !64BIT
config KTIME_SCALAR
def_bool 32BIT
config SMP
- bool "Symmetric multi-processing support"
+ def_bool y
+ prompt "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -188,10 +176,10 @@ config NR_CPUS
approximately sixteen kilobytes to the kernel image.
config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs"
+ def_bool y
+ prompt "Support for hot-pluggable CPUs"
depends on SMP
select HOTPLUG
- default n
help
Say Y here to be able to turn CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#.
@@ -207,14 +195,16 @@ config SCHED_MC
increased overhead in some places.
config SCHED_BOOK
- bool "Book scheduler support"
+ def_bool y
+ prompt "Book scheduler support"
depends on SMP && SCHED_MC
help
Book scheduler support improves the CPU scheduler's decision making
when dealing with machines that have several books.
config MATHEMU
- bool "IEEE FPU emulation"
+ def_bool y
+ prompt "IEEE FPU emulation"
depends on MARCH_G5
help
This option is required for IEEE compliant floating point arithmetic
@@ -222,7 +212,8 @@ config MATHEMU
need this.
config COMPAT
- bool "Kernel support for 31 bit emulation"
+ def_bool y
+ prompt "Kernel support for 31 bit emulation"
depends on 64BIT
select COMPAT_BINFMT_ELF
help
@@ -232,16 +223,14 @@ config COMPAT
executing 31 bit applications. It is safe to say "Y".
config SYSVIPC_COMPAT
- bool
- depends on COMPAT && SYSVIPC
- default y
+ def_bool y if COMPAT && SYSVIPC
config AUDIT_ARCH
- bool
- default y
+ def_bool y
config S390_EXEC_PROTECT
- bool "Data execute protection"
+ def_bool y
+ prompt "Data execute protection"
help
This option allows to enable a buffer overflow protection for user
space programs and it also selects the addressing mode option above.
@@ -301,7 +290,8 @@ config MARCH_Z196
endchoice
config PACK_STACK
- bool "Pack kernel stack"
+ def_bool y
+ prompt "Pack kernel stack"
help
This option enables the compiler option -mkernel-backchain if it
is available. If the option is available the compiler supports
@@ -314,7 +304,8 @@ config PACK_STACK
Say Y if you are unsure.
config SMALL_STACK
- bool "Use 8kb for kernel stack instead of 16kb"
+ def_bool n
+ prompt "Use 8kb for kernel stack instead of 16kb"
depends on PACK_STACK && 64BIT && !LOCKDEP
help
If you say Y here and the compiler supports the -mkernel-backchain
@@ -326,7 +317,8 @@ config SMALL_STACK
Say N if you are unsure.
config CHECK_STACK
- bool "Detect kernel stack overflow"
+ def_bool y
+ prompt "Detect kernel stack overflow"
help
This option enables the compiler option -mstack-guard and
-mstack-size if they are available. If the compiler supports them
@@ -350,7 +342,8 @@ config STACK_GUARD
512 for 64 bit.
config WARN_STACK
- bool "Emit compiler warnings for function with broken stack usage"
+ def_bool n
+ prompt "Emit compiler warnings for function with broken stack usage"
help
This option enables the compiler options -mwarn-framesize and
-mwarn-dynamicstack. If the compiler supports these options it
@@ -385,24 +378,24 @@ config ARCH_SPARSEMEM_DEFAULT
def_bool y
config ARCH_SELECT_MEMORY_MODEL
- def_bool y
+ def_bool y
config ARCH_ENABLE_MEMORY_HOTPLUG
- def_bool y
- depends on SPARSEMEM
+ def_bool y if SPARSEMEM
config ARCH_ENABLE_MEMORY_HOTREMOVE
def_bool y
config ARCH_HIBERNATION_POSSIBLE
- def_bool y if 64BIT
+ def_bool y if 64BIT
source "mm/Kconfig"
comment "I/O subsystem configuration"
config QDIO
- tristate "QDIO support"
+ def_tristate y
+ prompt "QDIO support"
---help---
This driver provides the Queued Direct I/O base support for
IBM System z.
@@ -413,7 +406,8 @@ config QDIO
If unsure, say Y.
config CHSC_SCH
- tristate "Support for CHSC subchannels"
+ def_tristate y
+ prompt "Support for CHSC subchannels"
help
This driver allows usage of CHSC subchannels. A CHSC subchannel
is usually present on LPAR only.
@@ -431,7 +425,8 @@ config CHSC_SCH
comment "Misc"
config IPL
- bool "Builtin IPL record support"
+ def_bool y
+ prompt "Builtin IPL record support"
help
If you want to use the produced kernel to IPL directly from a
device, you have to merge a bootsector specific to the device
@@ -463,7 +458,8 @@ config FORCE_MAX_ZONEORDER
default "9"
config PFAULT
- bool "Pseudo page fault support"
+ def_bool y
+ prompt "Pseudo page fault support"
help
Select this option, if you want to use PFAULT pseudo page fault
handling under VM. If running native or in LPAR, this option
@@ -475,7 +471,8 @@ config PFAULT
this option.
config SHARED_KERNEL
- bool "VM shared kernel support"
+ def_bool y
+ prompt "VM shared kernel support"
help
Select this option, if you want to share the text segment of the
Linux kernel between different VM guests. This reduces memory
@@ -486,7 +483,8 @@ config SHARED_KERNEL
doing and want to exploit this feature.
config CMM
- tristate "Cooperative memory management"
+ def_tristate n
+ prompt "Cooperative memory management"
help
Select this option, if you want to enable the kernel interface
to reduce the memory size of the system. This is accomplished
@@ -498,14 +496,16 @@ config CMM
option.
config CMM_IUCV
- bool "IUCV special message interface to cooperative memory management"
+ def_bool y
+ prompt "IUCV special message interface to cooperative memory management"
depends on CMM && (SMSGIUCV=y || CMM=SMSGIUCV)
help
Select this option to enable the special message interface to
the cooperative memory management.
config APPLDATA_BASE
- bool "Linux - VM Monitor Stream, base infrastructure"
+ def_bool n
+ prompt "Linux - VM Monitor Stream, base infrastructure"
depends on PROC_FS
help
This provides a kernel interface for creating and updating z/VM APPLDATA
@@ -520,7 +520,8 @@ config APPLDATA_BASE
The /proc entries can also be read from, showing the current settings.
config APPLDATA_MEM
- tristate "Monitor memory management statistics"
+ def_tristate m
+ prompt "Monitor memory management statistics"
depends on APPLDATA_BASE && VM_EVENT_COUNTERS
help
This provides memory management related data to the Linux - VM Monitor
@@ -536,7 +537,8 @@ config APPLDATA_MEM
appldata_mem.o.
config APPLDATA_OS
- tristate "Monitor OS statistics"
+ def_tristate m
+ prompt "Monitor OS statistics"
depends on APPLDATA_BASE
help
This provides OS related data to the Linux - VM Monitor Stream, like
@@ -550,7 +552,8 @@ config APPLDATA_OS
appldata_os.o.
config APPLDATA_NET_SUM
- tristate "Monitor overall network statistics"
+ def_tristate m
+ prompt "Monitor overall network statistics"
depends on APPLDATA_BASE && NET
help
This provides network related data to the Linux - VM Monitor Stream,
@@ -567,30 +570,32 @@ config APPLDATA_NET_SUM
source kernel/Kconfig.hz
config S390_HYPFS_FS
- bool "s390 hypervisor file system support"
+ def_bool y
+ prompt "s390 hypervisor file system support"
select SYS_HYPERVISOR
- default y
help
This is a virtual file system intended to provide accounting
information in an s390 hypervisor environment.
config KEXEC
- bool "kexec system call"
+ def_bool n
+ prompt "kexec system call"
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
but is independent of hardware/microcode support.
config ZFCPDUMP
- bool "zfcpdump support"
+ def_bool n
+ prompt "zfcpdump support"
select SMP
- default n
help
Select this option if you want to build an zfcpdump enabled kernel.
Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
config S390_GUEST
-bool "s390 guest support for KVM (EXPERIMENTAL)"
+ def_bool y
+ prompt "s390 guest support for KVM (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
@@ -602,9 +607,9 @@ bool "s390 guest support for KVM (EXPERIMENTAL)"
the default console.
config SECCOMP
- bool "Enable seccomp to safely compute untrusted bytecode"
+ def_bool y
+ prompt "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
- default y
help
This kernel feature is useful for number crunching applications
that may need to compute untrusted bytecode during their
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 05221b13ffb1..2b380df95606 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -1,8 +1,7 @@
menu "Kernel hacking"
config TRACE_IRQFLAGS_SUPPORT
- bool
- default y
+ def_bool y
source "lib/Kconfig.debug"
@@ -19,7 +18,8 @@ config STRICT_DEVMEM
If you are unsure, say Y.
config DEBUG_STRICT_USER_COPY_CHECKS
- bool "Strict user copy size checks"
+ def_bool n
+ prompt "Strict user copy size checks"
---help---
Enabling this option turns a certain set of sanity checks for user
copy operations into compile time warnings.
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index e40ac6ee6526..d79697157ac0 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -2,16 +2,12 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
+CONFIG_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_UTS_NS=y
-CONFIG_IPC_NS=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_COMPAT_BRK is not set
+CONFIG_PERF_EVENTS=y
CONFIG_SLAB=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
@@ -20,24 +16,12 @@ CONFIG_MODVERSIONS=y
CONFIG_DEFAULT_DEADLINE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
-CONFIG_64BIT=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=32
-CONFIG_COMPAT=y
-CONFIG_S390_EXEC_PROTECT=y
-CONFIG_PACK_STACK=y
-CONFIG_CHECK_STACK=y
CONFIG_PREEMPT=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_QDIO=y
-CONFIG_CHSC_SCH=m
-CONFIG_IPL=y
CONFIG_BINFMT_MISC=m
-CONFIG_PFAULT=y
CONFIG_HZ_100=y
CONFIG_KEXEC=y
-CONFIG_S390_GUEST=y
CONFIG_PM=y
CONFIG_HIBERNATION=y
CONFIG_PACKET=y
@@ -46,16 +30,15 @@ CONFIG_NET_KEY=y
CONFIG_AFIUCV=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
+# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK=m
-# CONFIG_NF_CT_PROTO_SCTP is not set
+CONFIG_NET_SCTPPROBE=m
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_VLAN_8021Q=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
@@ -69,28 +52,14 @@ CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
-CONFIG_NET_ACT_NAT=m
-CONFIG_CAN=m
-CONFIG_CAN_RAW=m
-CONFIG_CAN_BCM=m
-CONFIG_CAN_VCAN=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_XIP=y
-CONFIG_BLK_DEV_XPRAM=m
-CONFIG_DASD=y
-CONFIG_DASD_PROFILE=y
-CONFIG_DASD_ECKD=y
-CONFIG_DASD_FBA=y
-CONFIG_DASD_DIAG=y
-CONFIG_DASD_EER=y
-CONFIG_VIRTIO_BLK=m
+CONFIG_VIRTIO_BLK=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
@@ -102,101 +71,92 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_ZFCP=y
-CONFIG_SCSI_DH=m
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_CRYPT=y
-CONFIG_DM_SNAPSHOT=y
-CONFIG_DM_MIRROR=y
-CONFIG_DM_ZERO=y
-CONFIG_DM_MULTIPATH=m
+CONFIG_ZFCP_DIF=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_VETH=m
CONFIG_NET_ETHERNET=y
-CONFIG_LCS=m
-CONFIG_CTCM=m
-CONFIG_QETH=y
-CONFIG_QETH_L2=y
-CONFIG_QETH_L3=y
-CONFIG_VIRTIO_NET=m
-CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_VIRTIO_NET=y
CONFIG_RAW_DRIVER=m
-CONFIG_TN3270=y
-CONFIG_TN3270_TTY=y
-CONFIG_TN3270_FS=m
-CONFIG_TN3270_CONSOLE=y
-CONFIG_TN3215=y
-CONFIG_TN3215_CONSOLE=y
-CONFIG_SCLP_TTY=y
-CONFIG_SCLP_CONSOLE=y
-CONFIG_SCLP_VT220_TTY=y
-CONFIG_SCLP_VT220_CONSOLE=y
-CONFIG_SCLP_CPI=m
-CONFIG_SCLP_ASYNC=m
-CONFIG_S390_TAPE=m
-CONFIG_S390_TAPE_BLOCK=y
-CONFIG_S390_TAPE_34XX=m
-CONFIG_ACCESSIBILITY=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_IBM_PARTITION=y
CONFIG_DLM=m
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
+CONFIG_TIMER_STATS=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_PROVE_RCU=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_NOTIFIERS=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+CONFIG_KPROBES_SANITY_TEST=y
+CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
+CONFIG_LATENCYTOP=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_SAMPLES=y
-CONFIG_CRYPTO_FIPS=y
+CONFIG_DEBUG_PAGEALLOC=y
+# CONFIG_FTRACE is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD128=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_RMD256=m
CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SALSA20=m
CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_ZLIB=m
CONFIG_CRYPTO_LZO=m
CONFIG_ZCRYPT=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
CONFIG_CRYPTO_SHA512_S390=m
-CONFIG_CRC_T10DIF=y
-CONFIG_CRC32=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
CONFIG_CRC7=m
-CONFIG_KVM=m
-CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_BALLOON=y
diff --git a/arch/s390/hypfs/Makefile b/arch/s390/hypfs/Makefile
index b08d2abf6178..2e671d5004ca 100644
--- a/arch/s390/hypfs/Makefile
+++ b/arch/s390/hypfs/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o
-s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o
+s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h
index fa487d4cc08b..80c1526f2af3 100644
--- a/arch/s390/hypfs/hypfs.h
+++ b/arch/s390/hypfs/hypfs.h
@@ -12,6 +12,8 @@
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/debugfs.h>
+#include <linux/workqueue.h>
+#include <linux/kref.h>
#define REG_FILE_MODE 0440
#define UPDATE_FILE_MODE 0220
@@ -38,6 +40,33 @@ extern int hypfs_vm_init(void);
extern void hypfs_vm_exit(void);
extern int hypfs_vm_create_files(struct super_block *sb, struct dentry *root);
-/* Directory for debugfs files */
-extern struct dentry *hypfs_dbfs_dir;
+/* debugfs interface */
+struct hypfs_dbfs_file;
+
+struct hypfs_dbfs_data {
+ void *buf;
+ void *buf_free_ptr;
+ size_t size;
+ struct hypfs_dbfs_file *dbfs_file;;
+ struct kref kref;
+};
+
+struct hypfs_dbfs_file {
+ const char *name;
+ int (*data_create)(void **data, void **data_free_ptr,
+ size_t *size);
+ void (*data_free)(const void *buf_free_ptr);
+
+ /* Private data for hypfs_dbfs.c */
+ struct hypfs_dbfs_data *data;
+ struct delayed_work data_free_work;
+ struct mutex lock;
+ struct dentry *dentry;
+};
+
+extern int hypfs_dbfs_init(void);
+extern void hypfs_dbfs_exit(void);
+extern int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df);
+extern void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df);
+
#endif /* _HYPFS_H_ */
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c
new file mode 100644
index 000000000000..b478013b7fec
--- /dev/null
+++ b/arch/s390/hypfs/hypfs_dbfs.c
@@ -0,0 +1,116 @@
+/*
+ * Hypervisor filesystem for Linux on s390 - debugfs interface
+ *
+ * Copyright (C) IBM Corp. 2010
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <linux/slab.h>
+#include "hypfs.h"
+
+static struct dentry *dbfs_dir;
+
+static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f)
+{
+ struct hypfs_dbfs_data *data;
+
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return NULL;
+ kref_init(&data->kref);
+ data->dbfs_file = f;
+ return data;
+}
+
+static void hypfs_dbfs_data_free(struct kref *kref)
+{
+ struct hypfs_dbfs_data *data;
+
+ data = container_of(kref, struct hypfs_dbfs_data, kref);
+ data->dbfs_file->data_free(data->buf_free_ptr);
+ kfree(data);
+}
+
+static void data_free_delayed(struct work_struct *work)
+{
+ struct hypfs_dbfs_data *data;
+ struct hypfs_dbfs_file *df;
+
+ df = container_of(work, struct hypfs_dbfs_file, data_free_work.work);
+ mutex_lock(&df->lock);
+ data = df->data;
+ df->data = NULL;
+ mutex_unlock(&df->lock);
+ kref_put(&data->kref, hypfs_dbfs_data_free);
+}
+
+static ssize_t dbfs_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ struct hypfs_dbfs_data *data;
+ struct hypfs_dbfs_file *df;
+ ssize_t rc;
+
+ if (*ppos != 0)
+ return 0;
+
+ df = file->f_path.dentry->d_inode->i_private;
+ mutex_lock(&df->lock);
+ if (!df->data) {
+ data = hypfs_dbfs_data_alloc(df);
+ if (!data) {
+ mutex_unlock(&df->lock);
+ return -ENOMEM;
+ }
+ rc = df->data_create(&data->buf, &data->buf_free_ptr,
+ &data->size);
+ if (rc) {
+ mutex_unlock(&df->lock);
+ kfree(data);
+ return rc;
+ }
+ df->data = data;
+ schedule_delayed_work(&df->data_free_work, HZ);
+ }
+ data = df->data;
+ kref_get(&data->kref);
+ mutex_unlock(&df->lock);
+
+ rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
+ kref_put(&data->kref, hypfs_dbfs_data_free);
+ return rc;
+}
+
+static const struct file_operations dbfs_ops = {
+ .read = dbfs_read,
+ .llseek = no_llseek,
+};
+
+int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
+{
+ df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
+ &dbfs_ops);
+ if (IS_ERR(df->dentry))
+ return PTR_ERR(df->dentry);
+ mutex_init(&df->lock);
+ INIT_DELAYED_WORK(&df->data_free_work, data_free_delayed);
+ return 0;
+}
+
+void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
+{
+ debugfs_remove(df->dentry);
+}
+
+int hypfs_dbfs_init(void)
+{
+ dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
+ if (IS_ERR(dbfs_dir))
+ return PTR_ERR(dbfs_dir);
+ return 0;
+}
+
+void hypfs_dbfs_exit(void)
+{
+ debugfs_remove(dbfs_dir);
+}
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index cd4a81be9cf8..6023c6dc1fb7 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -555,81 +555,38 @@ struct dbfs_d204 {
char buf[]; /* d204 buffer */
} __attribute__ ((packed));
-struct dbfs_d204_private {
- struct dbfs_d204 *d204; /* Aligned d204 data with header */
- void *base; /* Base pointer (needed for vfree) */
-};
-
-static int dbfs_d204_open(struct inode *inode, struct file *file)
+static int dbfs_d204_create(void **data, void **data_free_ptr, size_t *size)
{
- struct dbfs_d204_private *data;
struct dbfs_d204 *d204;
int rc, buf_size;
+ void *base;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr);
- data->base = vmalloc(buf_size);
- if (!data->base) {
- rc = -ENOMEM;
- goto fail_kfree_data;
+ base = vmalloc(buf_size);
+ if (!base)
+ return -ENOMEM;
+ memset(base, 0, buf_size);
+ d204 = page_align_ptr(base + sizeof(d204->hdr)) - sizeof(d204->hdr);
+ rc = diag204_do_store(d204->buf, diag204_buf_pages);
+ if (rc) {
+ vfree(base);
+ return rc;
}
- memset(data->base, 0, buf_size);
- d204 = page_align_ptr(data->base + sizeof(d204->hdr))
- - sizeof(d204->hdr);
- rc = diag204_do_store(&d204->buf, diag204_buf_pages);
- if (rc)
- goto fail_vfree_base;
d204->hdr.version = DBFS_D204_HDR_VERSION;
d204->hdr.len = PAGE_SIZE * diag204_buf_pages;
d204->hdr.sc = diag204_store_sc;
- data->d204 = d204;
- file->private_data = data;
- return nonseekable_open(inode, file);
-
-fail_vfree_base:
- vfree(data->base);
-fail_kfree_data:
- kfree(data);
- return rc;
-}
-
-static int dbfs_d204_release(struct inode *inode, struct file *file)
-{
- struct dbfs_d204_private *data = file->private_data;
-
- vfree(data->base);
- kfree(data);
+ *data = d204;
+ *data_free_ptr = base;
+ *size = d204->hdr.len + sizeof(struct dbfs_d204_hdr);
return 0;
}
-static ssize_t dbfs_d204_read(struct file *file, char __user *buf,
- size_t size, loff_t *ppos)
-{
- struct dbfs_d204_private *data = file->private_data;
-
- return simple_read_from_buffer(buf, size, ppos, data->d204,
- data->d204->hdr.len +
- sizeof(data->d204->hdr));
-}
-
-static const struct file_operations dbfs_d204_ops = {
- .open = dbfs_d204_open,
- .read = dbfs_d204_read,
- .release = dbfs_d204_release,
- .llseek = no_llseek,
+static struct hypfs_dbfs_file dbfs_file_d204 = {
+ .name = "diag_204",
+ .data_create = dbfs_d204_create,
+ .data_free = vfree,
};
-static int hypfs_dbfs_init(void)
-{
- dbfs_d204_file = debugfs_create_file("diag_204", 0400, hypfs_dbfs_dir,
- NULL, &dbfs_d204_ops);
- if (IS_ERR(dbfs_d204_file))
- return PTR_ERR(dbfs_d204_file);
- return 0;
-}
-
__init int hypfs_diag_init(void)
{
int rc;
@@ -639,7 +596,7 @@ __init int hypfs_diag_init(void)
return -ENODATA;
}
if (diag204_info_type == INFO_EXT) {
- rc = hypfs_dbfs_init();
+ rc = hypfs_dbfs_create_file(&dbfs_file_d204);
if (rc)
return rc;
}
@@ -660,6 +617,7 @@ void hypfs_diag_exit(void)
debugfs_remove(dbfs_d204_file);
diag224_delete_name_table();
diag204_free_buffer();
+ hypfs_dbfs_remove_file(&dbfs_file_d204);
}
/*
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c
index 26cf177f6a3a..e54796002f61 100644
--- a/arch/s390/hypfs/hypfs_vm.c
+++ b/arch/s390/hypfs/hypfs_vm.c
@@ -20,8 +20,6 @@ static char local_guest[] = " ";
static char all_guests[] = "* ";
static char *guest_query;
-static struct dentry *dbfs_d2fc_file;
-
struct diag2fc_data {
__u32 version;
__u32 flags;
@@ -104,7 +102,7 @@ static void *diag2fc_store(char *query, unsigned int *count, int offset)
return data;
}
-static void diag2fc_free(void *data)
+static void diag2fc_free(const void *data)
{
vfree(data);
}
@@ -239,43 +237,29 @@ struct dbfs_d2fc {
char buf[]; /* d2fc buffer */
} __attribute__ ((packed));
-static int dbfs_d2fc_open(struct inode *inode, struct file *file)
+static int dbfs_diag2fc_create(void **data, void **data_free_ptr, size_t *size)
{
- struct dbfs_d2fc *data;
+ struct dbfs_d2fc *d2fc;
unsigned int count;
- data = diag2fc_store(guest_query, &count, sizeof(data->hdr));
- if (IS_ERR(data))
- return PTR_ERR(data);
- get_clock_ext(data->hdr.tod_ext);
- data->hdr.len = count * sizeof(struct diag2fc_data);
- data->hdr.version = DBFS_D2FC_HDR_VERSION;
- data->hdr.count = count;
- memset(&data->hdr.reserved, 0, sizeof(data->hdr.reserved));
- file->private_data = data;
- return nonseekable_open(inode, file);
-}
-
-static int dbfs_d2fc_release(struct inode *inode, struct file *file)
-{
- diag2fc_free(file->private_data);
+ d2fc = diag2fc_store(guest_query, &count, sizeof(d2fc->hdr));
+ if (IS_ERR(d2fc))
+ return PTR_ERR(d2fc);
+ get_clock_ext(d2fc->hdr.tod_ext);
+ d2fc->hdr.len = count * sizeof(struct diag2fc_data);
+ d2fc->hdr.version = DBFS_D2FC_HDR_VERSION;
+ d2fc->hdr.count = count;
+ memset(&d2fc->hdr.reserved, 0, sizeof(d2fc->hdr.reserved));
+ *data = d2fc;
+ *data_free_ptr = d2fc;
+ *size = d2fc->hdr.len + sizeof(struct dbfs_d2fc_hdr);
return 0;
}
-static ssize_t dbfs_d2fc_read(struct file *file, char __user *buf,
- size_t size, loff_t *ppos)
-{
- struct dbfs_d2fc *data = file->private_data;
-
- return simple_read_from_buffer(buf, size, ppos, data, data->hdr.len +
- sizeof(struct dbfs_d2fc_hdr));
-}
-
-static const struct file_operations dbfs_d2fc_ops = {
- .open = dbfs_d2fc_open,
- .read = dbfs_d2fc_read,
- .release = dbfs_d2fc_release,
- .llseek = no_llseek,
+static struct hypfs_dbfs_file dbfs_file_2fc = {
+ .name = "diag_2fc",
+ .data_create = dbfs_diag2fc_create,
+ .data_free = diag2fc_free,
};
int hypfs_vm_init(void)
@@ -288,18 +272,12 @@ int hypfs_vm_init(void)
guest_query = local_guest;
else
return -EACCES;
-
- dbfs_d2fc_file = debugfs_create_file("diag_2fc", 0400, hypfs_dbfs_dir,
- NULL, &dbfs_d2fc_ops);
- if (IS_ERR(dbfs_d2fc_file))
- return PTR_ERR(dbfs_d2fc_file);
-
- return 0;
+ return hypfs_dbfs_create_file(&dbfs_file_2fc);
}
void hypfs_vm_exit(void)
{
if (!MACHINE_IS_VM)
return;
- debugfs_remove(dbfs_d2fc_file);
+ hypfs_dbfs_remove_file(&dbfs_file_2fc);
}
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 47cc446dab8f..6fe874fc5f8e 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -46,8 +46,6 @@ static const struct super_operations hypfs_s_ops;
/* start of list of all dentries, which have to be deleted on update */
static struct dentry *hypfs_last_dentry;
-struct dentry *hypfs_dbfs_dir;
-
static void hypfs_update_update(struct super_block *sb)
{
struct hypfs_sb_info *sb_info = sb->s_fs_info;
@@ -471,13 +469,12 @@ static int __init hypfs_init(void)
{
int rc;
- hypfs_dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
- if (IS_ERR(hypfs_dbfs_dir))
- return PTR_ERR(hypfs_dbfs_dir);
-
+ rc = hypfs_dbfs_init();
+ if (rc)
+ return rc;
if (hypfs_diag_init()) {
rc = -ENODATA;
- goto fail_debugfs_remove;
+ goto fail_dbfs_exit;
}
if (hypfs_vm_init()) {
rc = -ENODATA;
@@ -499,9 +496,8 @@ fail_hypfs_vm_exit:
hypfs_vm_exit();
fail_hypfs_diag_exit:
hypfs_diag_exit();
-fail_debugfs_remove:
- debugfs_remove(hypfs_dbfs_dir);
-
+fail_dbfs_exit:
+ hypfs_dbfs_exit();
pr_err("Initialization of hypfs failed with rc=%i\n", rc);
return rc;
}
@@ -510,7 +506,7 @@ static void __exit hypfs_exit(void)
{
hypfs_diag_exit();
hypfs_vm_exit();
- debugfs_remove(hypfs_dbfs_dir);
+ hypfs_dbfs_exit();
unregister_filesystem(&hypfs_type);
kobject_put(s390_kobj);
}
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index e8501115eca8..ff6f62e0ec3e 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -204,6 +204,8 @@ int ccw_device_tm_start_timeout(struct ccw_device *, struct tcw *,
unsigned long, u8, int);
int ccw_device_tm_intrg(struct ccw_device *cdev);
+int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask);
+
extern int ccw_device_set_online(struct ccw_device *cdev);
extern int ccw_device_set_offline(struct ccw_device *cdev);
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 40e2ab0fa3f0..081434878296 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -202,7 +202,7 @@ static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock,
static inline int s390_nohz_delay(int cpu)
{
- return per_cpu(s390_idle, cpu).nohz_delay != 0;
+ return __get_cpu_var(s390_idle).nohz_delay != 0;
}
#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h
index b604a9186f8e..0be28efe5b66 100644
--- a/arch/s390/include/asm/dasd.h
+++ b/arch/s390/include/asm/dasd.h
@@ -73,6 +73,7 @@ typedef struct dasd_information2_t {
* 0x02: use diag discipline (diag)
* 0x04: set the device initially online (internal use only)
* 0x08: enable ERP related logging
+ * 0x20: give access to raw eckd data
*/
#define DASD_FEATURE_DEFAULT 0x00
#define DASD_FEATURE_READONLY 0x01
@@ -80,6 +81,8 @@ typedef struct dasd_information2_t {
#define DASD_FEATURE_INITIAL_ONLINE 0x04
#define DASD_FEATURE_ERPLOG 0x08
#define DASD_FEATURE_FAILFAST 0x10
+#define DASD_FEATURE_FAILONSLCK 0x20
+#define DASD_FEATURE_USERAW 0x40
#define DASD_PARTN_BITS 2
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index 96c14a9102b8..3c29be4836ed 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -4,20 +4,17 @@
#ifndef __ASSEMBLY__
extern void _mcount(void);
-extern unsigned long ftrace_dyn_func;
struct dyn_arch_ftrace { };
#define MCOUNT_ADDR ((long)_mcount)
#ifdef CONFIG_64BIT
-#define MCOUNT_OFFSET_RET 18
-#define MCOUNT_INSN_SIZE 24
-#define MCOUNT_OFFSET 14
-#else
-#define MCOUNT_OFFSET_RET 26
-#define MCOUNT_INSN_SIZE 30
+#define MCOUNT_INSN_SIZE 12
#define MCOUNT_OFFSET 8
+#else
+#define MCOUNT_INSN_SIZE 20
+#define MCOUNT_OFFSET 4
#endif
static inline unsigned long ftrace_call_adjust(unsigned long addr)
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h
index 881d94590aeb..e4155d3eb2cb 100644
--- a/arch/s390/include/asm/hardirq.h
+++ b/arch/s390/include/asm/hardirq.h
@@ -21,20 +21,4 @@
#define HARDIRQ_BITS 8
-void clock_comparator_work(void);
-
-static inline unsigned long long local_tick_disable(void)
-{
- unsigned long long old;
-
- old = S390_lowcore.clock_comparator;
- S390_lowcore.clock_comparator = -1ULL;
- return old;
-}
-
-static inline void local_tick_enable(unsigned long long comp)
-{
- S390_lowcore.clock_comparator = comp;
-}
-
#endif /* __ASM_HARDIRQ_H */
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index 7da991a858f8..db14a311f1d2 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -1,23 +1,33 @@
#ifndef _ASM_IRQ_H
#define _ASM_IRQ_H
-#ifdef __KERNEL__
#include <linux/hardirq.h>
-/*
- * the definition of irqs has changed in 2.5.46:
- * NR_IRQS is no longer the number of i/o
- * interrupts (65536), but rather the number
- * of interrupt classes (2).
- * Only external and i/o interrupts make much sense here (CH).
- */
-
enum interruption_class {
EXTERNAL_INTERRUPT,
IO_INTERRUPT,
-
+ EXTINT_CLK,
+ EXTINT_IPI,
+ EXTINT_TMR,
+ EXTINT_TLA,
+ EXTINT_PFL,
+ EXTINT_DSD,
+ EXTINT_VRT,
+ EXTINT_SCP,
+ EXTINT_IUC,
+ IOINT_QAI,
+ IOINT_QDI,
+ IOINT_DAS,
+ IOINT_C15,
+ IOINT_C70,
+ IOINT_TAP,
+ IOINT_VMR,
+ IOINT_LCS,
+ IOINT_CLW,
+ IOINT_CTC,
+ IOINT_APB,
+ NMI_NMI,
NR_IRQS,
};
-#endif /* __KERNEL__ */
-#endif
+#endif /* _ASM_IRQ_H */
diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h
index 330f68caffe4..a231a9439c4b 100644
--- a/arch/s390/include/asm/kprobes.h
+++ b/arch/s390/include/asm/kprobes.h
@@ -31,7 +31,6 @@
#include <linux/ptrace.h>
#include <linux/percpu.h>
-#define __ARCH_WANT_KPROBES_INSN_SLOT
struct pt_regs;
struct kprobe;
@@ -58,23 +57,12 @@ typedef u16 kprobe_opcode_t;
/* Architecture specific copy of original instruction */
struct arch_specific_insn {
/* copy of original instruction */
- kprobe_opcode_t *insn;
- int fixup;
- int ilen;
- int reg;
+ kprobe_opcode_t insn[MAX_INSN_SIZE];
};
-struct ins_replace_args {
- kprobe_opcode_t *ptr;
- kprobe_opcode_t old;
- kprobe_opcode_t new;
-};
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
- unsigned long saved_psw;
- unsigned long kprobe_saved_imask;
- unsigned long kprobe_saved_ctl[3];
};
/* per-cpu kprobe control block */
@@ -82,17 +70,13 @@ struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long kprobe_saved_imask;
unsigned long kprobe_saved_ctl[3];
- struct pt_regs jprobe_saved_regs;
- unsigned long jprobe_saved_r14;
- unsigned long jprobe_saved_r15;
struct prev_kprobe prev_kprobe;
+ struct pt_regs jprobe_saved_regs;
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
};
void arch_remove_kprobe(struct kprobe *p);
void kretprobe_trampoline(void);
-int is_prohibited_opcode(kprobe_opcode_t *instruction);
-void get_instruction_type(struct arch_specific_insn *ainsn);
int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
int kprobe_exceptions_notify(struct notifier_block *self,
diff --git a/arch/s390/include/asm/mutex.h b/arch/s390/include/asm/mutex.h
index 458c1f7fbc18..688271f5f2e4 100644
--- a/arch/s390/include/asm/mutex.h
+++ b/arch/s390/include/asm/mutex.h
@@ -7,3 +7,5 @@
*/
#include <asm-generic/mutex-dec.h>
+
+#define arch_mutex_cpu_relax() barrier()
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 8d6f87169577..bf3de04170a7 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -32,7 +32,6 @@ static inline void get_cpu_id(struct cpuid *ptr)
}
extern void s390_adjust_jiffies(void);
-extern void print_cpu_info(void);
extern int get_cpu_capability(unsigned int *);
/*
@@ -81,7 +80,8 @@ struct thread_struct {
mm_segment_t mm_segment;
unsigned long prot_addr; /* address of protection-excep. */
unsigned int trap_no;
- per_struct per_info;
+ struct per_regs per_user; /* User specified PER registers */
+ struct per_event per_event; /* Cause of the last PER trap */
/* pfault_wait is used to block the process on a pfault event */
unsigned long pfault_wait;
};
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index d9d42b1e46fa..9ad628a8574a 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -331,10 +331,60 @@ struct pt_regs
unsigned short ilc;
unsigned short svcnr;
};
+
+/*
+ * Program event recording (PER) register set.
+ */
+struct per_regs {
+ unsigned long control; /* PER control bits */
+ unsigned long start; /* PER starting address */
+ unsigned long end; /* PER ending address */
+};
+
+/*
+ * PER event contains information about the cause of the last PER exception.
+ */
+struct per_event {
+ unsigned short cause; /* PER code, ATMID and AI */
+ unsigned long address; /* PER address */
+ unsigned char paid; /* PER access identification */
+};
+
+/*
+ * Simplified per_info structure used to decode the ptrace user space ABI.
+ */
+struct per_struct_kernel {
+ unsigned long cr9; /* PER control bits */
+ unsigned long cr10; /* PER starting address */
+ unsigned long cr11; /* PER ending address */
+ unsigned long bits; /* Obsolete software bits */
+ unsigned long starting_addr; /* User specified start address */
+ unsigned long ending_addr; /* User specified end address */
+ unsigned short perc_atmid; /* PER trap ATMID */
+ unsigned long address; /* PER trap instruction address */
+ unsigned char access_id; /* PER trap access identification */
+};
+
+#define PER_EVENT_MASK 0xE9000000UL
+
+#define PER_EVENT_BRANCH 0x80000000UL
+#define PER_EVENT_IFETCH 0x40000000UL
+#define PER_EVENT_STORE 0x20000000UL
+#define PER_EVENT_STORE_REAL 0x08000000UL
+#define PER_EVENT_NULLIFICATION 0x01000000UL
+
+#define PER_CONTROL_MASK 0x00a00000UL
+
+#define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL
+#define PER_CONTROL_ALTERATION 0x00200000UL
+
#endif
/*
- * Now for the program event recording (trace) definitions.
+ * Now for the user space program event recording (trace) definitions.
+ * The following structures are used only for the ptrace interface, don't
+ * touch or even look at it if you don't want to modify the user-space
+ * ptrace interface. In particular stay away from it for in-kernel PER.
*/
typedef struct
{
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 46e96bc1f5a1..350e7ee5952d 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -361,6 +361,7 @@ struct qdio_initialize {
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
+ int scan_threshold;
unsigned long int_parm;
void **input_sbal_addr_array;
void **output_sbal_addr_array;
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h
index 06cbd1e8c943..90efda0b137d 100644
--- a/arch/s390/include/asm/qeth.h
+++ b/arch/s390/include/asm/qeth.h
@@ -28,39 +28,70 @@ struct qeth_arp_cache_entry {
__u8 reserved2[32];
} __attribute__ ((packed));
+enum qeth_arp_ipaddrtype {
+ QETHARP_IP_ADDR_V4 = 1,
+ QETHARP_IP_ADDR_V6 = 2,
+};
+struct qeth_arp_entrytype {
+ __u8 mac;
+ __u8 ip;
+} __attribute__((packed));
+
+#define QETH_QARP_MEDIASPECIFIC_BYTES 32
+#define QETH_QARP_MACADDRTYPE_BYTES 1
struct qeth_arp_qi_entry7 {
- __u8 media_specific[32];
- __u8 macaddr_type;
- __u8 ipaddr_type;
+ __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+ struct qeth_arp_entrytype type;
__u8 macaddr[6];
__u8 ipaddr[4];
} __attribute__((packed));
+struct qeth_arp_qi_entry7_ipv6 {
+ __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+ struct qeth_arp_entrytype type;
+ __u8 macaddr[6];
+ __u8 ipaddr[16];
+} __attribute__((packed));
+
struct qeth_arp_qi_entry7_short {
- __u8 macaddr_type;
- __u8 ipaddr_type;
+ struct qeth_arp_entrytype type;
__u8 macaddr[6];
__u8 ipaddr[4];
} __attribute__((packed));
+struct qeth_arp_qi_entry7_short_ipv6 {
+ struct qeth_arp_entrytype type;
+ __u8 macaddr[6];
+ __u8 ipaddr[16];
+} __attribute__((packed));
+
struct qeth_arp_qi_entry5 {
- __u8 media_specific[32];
- __u8 macaddr_type;
- __u8 ipaddr_type;
+ __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+ struct qeth_arp_entrytype type;
__u8 ipaddr[4];
} __attribute__((packed));
+struct qeth_arp_qi_entry5_ipv6 {
+ __u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+ struct qeth_arp_entrytype type;
+ __u8 ipaddr[16];
+} __attribute__((packed));
+
struct qeth_arp_qi_entry5_short {
- __u8 macaddr_type;
- __u8 ipaddr_type;
+ struct qeth_arp_entrytype type;
__u8 ipaddr[4];
} __attribute__((packed));
+struct qeth_arp_qi_entry5_short_ipv6 {
+ struct qeth_arp_entrytype type;
+ __u8 ipaddr[16];
+} __attribute__((packed));
/*
* can be set by user if no "media specific information" is wanted
* -> saves a lot of space in user space buffer
*/
#define QETH_QARP_STRIP_ENTRIES 0x8000
+#define QETH_QARP_WITH_IPV6 0x4000
#define QETH_QARP_REQUEST_MASK 0x00ff
/* data sent to user space as result of query arp ioctl */
diff --git a/arch/s390/include/asm/s390_ext.h b/arch/s390/include/asm/s390_ext.h
index 1a9307e70842..080876d5f196 100644
--- a/arch/s390/include/asm/s390_ext.h
+++ b/arch/s390/include/asm/s390_ext.h
@@ -1,32 +1,17 @@
-#ifndef _S390_EXTINT_H
-#define _S390_EXTINT_H
-
/*
- * include/asm-s390/s390_ext.h
- *
- * S390 version
- * Copyright IBM Corp. 1999,2007
- * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com),
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
+ * Copyright IBM Corp. 1999,2010
+ * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
*/
+#ifndef _S390_EXTINT_H
+#define _S390_EXTINT_H
+
#include <linux/types.h>
typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
-typedef struct ext_int_info_t {
- struct ext_int_info_t *next;
- ext_int_handler_t handler;
- __u16 code;
-} ext_int_info_t;
-
-extern ext_int_info_t *ext_int_hash[];
-
int register_external_interrupt(__u16 code, ext_int_handler_t handler);
-int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
- ext_int_info_t *info);
int unregister_external_interrupt(__u16 code, ext_int_handler_t handler);
-int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
- ext_int_info_t *info);
-#endif
+#endif /* _S390_EXTINT_H */
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index edc03cb9cd79..045e009fc164 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -20,7 +20,6 @@ extern void machine_power_off_smp(void);
extern int __cpu_disable (void);
extern void __cpu_die (unsigned int cpu);
-extern void cpu_die (void) __attribute__ ((noreturn));
extern int __cpu_up (unsigned int cpu);
extern struct mutex smp_cpu_state_mutex;
@@ -71,8 +70,10 @@ static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
#ifdef CONFIG_HOTPLUG_CPU
extern int smp_rescan_cpus(void);
+extern void __noreturn cpu_die(void);
#else
static inline int smp_rescan_cpus(void) { return 0; }
+static inline void cpu_die(void) { }
#endif
#endif /* __ASM_SMP_H */
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index 3ad16dbf622e..6710b0eac165 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -20,6 +20,7 @@
struct task_struct;
extern struct task_struct *__switch_to(void *, void *);
+extern void update_per_regs(struct task_struct *task);
static inline void save_fp_regs(s390_fp_regs *fpregs)
{
@@ -93,6 +94,7 @@ static inline void restore_access_regs(unsigned int *acrs)
if (next->mm) { \
restore_fp_regs(&next->thread.fp_regs); \
restore_access_regs(&next->thread.acrs[0]); \
+ update_per_regs(next); \
} \
prev = __switch_to(prev,next); \
} while (0)
@@ -101,11 +103,9 @@ extern void account_vtime(struct task_struct *, struct task_struct *);
extern void account_tick_vtime(struct task_struct *);
#ifdef CONFIG_PFAULT
-extern void pfault_irq_init(void);
extern int pfault_init(void);
extern void pfault_fini(void);
#else /* CONFIG_PFAULT */
-#define pfault_irq_init() do { } while (0)
#define pfault_init() ({-1;})
#define pfault_fini() do { } while (0)
#endif /* CONFIG_PFAULT */
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 5baf0230b29b..ebc77091466f 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -74,7 +74,7 @@ struct thread_info {
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
- return (struct thread_info *)(S390_lowcore.kernel_stack - THREAD_SIZE);
+ return (struct thread_info *) S390_lowcore.thread_info;
}
#define THREAD_SIZE_ORDER THREAD_ORDER
@@ -88,7 +88,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
-#define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */
+#define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */
#define TIF_MCCK_PENDING 7 /* machine check handling is pending */
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
@@ -99,14 +99,15 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_31BIT 17 /* 32bit process */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */
-#define TIF_FREEZE 20 /* thread is freezing for suspend */
+#define TIF_SINGLE_STEP 20 /* This task is single stepped */
+#define TIF_FREEZE 21 /* thread is freezing for suspend */
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
-#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
+#define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
@@ -114,6 +115,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT)
+#define _TIF_SINGLE_STEP (1<<TIF_FREEZE)
#define _TIF_FREEZE (1<<TIF_FREEZE)
#endif /* __KERNEL__ */
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index 09d345a701dc..88829a40af6f 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -11,6 +11,8 @@
#ifndef _ASM_S390_TIMEX_H
#define _ASM_S390_TIMEX_H
+#include <asm/lowcore.h>
+
/* The value of the TOD clock for 1.1.1970. */
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
@@ -49,6 +51,24 @@ static inline void store_clock_comparator(__u64 *time)
asm volatile("stckc %0" : "=Q" (*time));
}
+void clock_comparator_work(void);
+
+static inline unsigned long long local_tick_disable(void)
+{
+ unsigned long long old;
+
+ old = S390_lowcore.clock_comparator;
+ S390_lowcore.clock_comparator = -1ULL;
+ set_clock_comparator(S390_lowcore.clock_comparator);
+ return old;
+}
+
+static inline void local_tick_enable(unsigned long long comp)
+{
+ S390_lowcore.clock_comparator = comp;
+ set_clock_comparator(S390_lowcore.clock_comparator);
+}
+
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
typedef unsigned long long cycles_t;
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 33982e7ce04d..fe03c140002a 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -23,14 +23,16 @@ int main(void)
{
DEFINE(__THREAD_info, offsetof(struct task_struct, stack));
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp));
- DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info));
DEFINE(__THREAD_mm_segment, offsetof(struct task_struct, thread.mm_segment));
BLANK();
DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
BLANK();
- DEFINE(__PER_atmid, offsetof(per_struct, lowcore.words.perc_atmid));
- DEFINE(__PER_address, offsetof(per_struct, lowcore.words.address));
- DEFINE(__PER_access_id, offsetof(per_struct, lowcore.words.access_id));
+ DEFINE(__THREAD_per_cause,
+ offsetof(struct task_struct, thread.per_event.cause));
+ DEFINE(__THREAD_per_address,
+ offsetof(struct task_struct, thread.per_event.address));
+ DEFINE(__THREAD_per_paid,
+ offsetof(struct task_struct, thread.per_event.paid));
BLANK();
DEFINE(__TI_task, offsetof(struct thread_info, task));
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain));
@@ -85,9 +87,9 @@ int main(void)
DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
DEFINE(__LC_TRANS_EXC_CODE, offsetof(struct _lowcore, trans_exc_code));
- DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
+ DEFINE(__LC_PER_CAUSE, offsetof(struct _lowcore, per_perc_atmid));
DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
- DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
+ DEFINE(__LC_PER_PAID, offsetof(struct _lowcore, per_access_id));
DEFINE(__LC_AR_MODE_ID, offsetof(struct _lowcore, ar_access_id));
DEFINE(__LC_SUBCHANNEL_ID, offsetof(struct _lowcore, subchannel_id));
DEFINE(__LC_SUBCHANNEL_NR, offsetof(struct _lowcore, subchannel_nr));
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h
index 3141025724f4..12b823833510 100644
--- a/arch/s390/kernel/compat_ptrace.h
+++ b/arch/s390/kernel/compat_ptrace.h
@@ -4,40 +4,19 @@
#include <asm/ptrace.h> /* needed for NUM_CR_WORDS */
#include "compat_linux.h" /* needed for psw_compat_t */
-typedef struct {
- __u32 cr[NUM_CR_WORDS];
-} per_cr_words32;
-
-typedef struct {
- __u16 perc_atmid; /* 0x096 */
- __u32 address; /* 0x098 */
- __u8 access_id; /* 0x0a1 */
-} per_lowcore_words32;
-
-typedef struct {
- union {
- per_cr_words32 words;
- } control_regs;
- /*
- * Use these flags instead of setting em_instruction_fetch
- * directly they are used so that single stepping can be
- * switched on & off while not affecting other tracing
- */
- unsigned single_step : 1;
- unsigned instruction_fetch : 1;
- unsigned : 30;
- /*
- * These addresses are copied into cr10 & cr11 if single
- * stepping is switched off
- */
- __u32 starting_addr;
- __u32 ending_addr;
- union {
- per_lowcore_words32 words;
- } lowcore;
-} per_struct32;
+struct compat_per_struct_kernel {
+ __u32 cr9; /* PER control bits */
+ __u32 cr10; /* PER starting address */
+ __u32 cr11; /* PER ending address */
+ __u32 bits; /* Obsolete software bits */
+ __u32 starting_addr; /* User specified start address */
+ __u32 ending_addr; /* User specified end address */
+ __u16 perc_atmid; /* PER trap ATMID */
+ __u32 address; /* PER trap instruction address */
+ __u8 access_id; /* PER trap access identification */
+};
-struct user_regs_struct32
+struct compat_user_regs_struct
{
psw_compat_t psw;
u32 gprs[NUM_GPRS];
@@ -50,14 +29,14 @@ struct user_regs_struct32
* itself as there is no "official" ptrace interface for hardware
* watchpoints. This is the way intel does it.
*/
- per_struct32 per_info;
+ struct compat_per_struct_kernel per_info;
u32 ieee_instruction_pointer; /* obsolete, always 0 */
};
-struct user32 {
+struct compat_user {
/* We start with the registers, to mimic the way that "memory"
is returned from the ptrace(3,...) function. */
- struct user_regs_struct32 regs; /* Where the registers are actually stored */
+ struct compat_user_regs_struct regs;
/* The rest of this junk is to help gdb figure out what goes where */
u32 u_tsize; /* Text segment size (pages). */
u32 u_dsize; /* Data segment size (pages). */
@@ -79,6 +58,6 @@ typedef struct
__u32 len;
__u32 kernel_addr;
__u32 process_addr;
-} ptrace_area_emu31;
+} compat_ptrace_area;
#endif /* _PTRACE32_H */
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 1ecc337fb679..648f64239a9d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -9,7 +9,6 @@
* Heiko Carstens <heiko.carstens@de.ibm.com>
*/
-#include <linux/sys.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/cache.h>
@@ -49,7 +48,7 @@ SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
- _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
@@ -110,31 +109,36 @@ STACK_SIZE = 1 << STACK_SHIFT
1: stm %r10,%r11,\lc_sum
.endm
- .macro SAVE_ALL_BASE savearea
+ .macro SAVE_ALL_SVC psworg,savearea
stm %r12,%r15,\savearea
l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
+ l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ s %r15,BASED(.Lc_spsize) # make room for registers & psw
.endm
- .macro SAVE_ALL_SVC psworg,savearea
- la %r12,\psworg
- l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ .macro SAVE_ALL_BASE savearea
+ stm %r12,%r15,\savearea
+ l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
.endm
- .macro SAVE_ALL_SYNC psworg,savearea
- la %r12,\psworg
+ .macro SAVE_ALL_PGM psworg,savearea
tm \psworg+1,0x01 # test problem state bit
- bz BASED(2f) # skip stack setup save
- l %r15,__LC_KERNEL_STACK # problem state -> load ksp
#ifdef CONFIG_CHECK_STACK
- b BASED(3f)
-2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
- bz BASED(stack_overflow)
-3:
+ bnz BASED(1f)
+ tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
+ bnz BASED(2f)
+ la %r12,\psworg
+ b BASED(stack_overflow)
+#else
+ bz BASED(2f)
#endif
-2:
+1: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+2: s %r15,BASED(.Lc_spsize) # make room for registers & psw
.endm
.macro SAVE_ALL_ASYNC psworg,savearea
+ stm %r12,%r15,\savearea
+ l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
la %r12,\psworg
tm \psworg+1,0x01 # test problem state bit
bnz BASED(1f) # from user -> load async stack
@@ -149,27 +153,23 @@ STACK_SIZE = 1 << STACK_SHIFT
0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
slr %r14,%r15
sra %r14,STACK_SHIFT
- be BASED(2f)
-1: l %r15,__LC_ASYNC_STACK
#ifdef CONFIG_CHECK_STACK
- b BASED(3f)
-2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
- bz BASED(stack_overflow)
-3:
+ bnz BASED(1f)
+ tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
+ bnz BASED(2f)
+ b BASED(stack_overflow)
+#else
+ bz BASED(2f)
#endif
-2:
+1: l %r15,__LC_ASYNC_STACK
+2: s %r15,BASED(.Lc_spsize) # make room for registers & psw
.endm
- .macro CREATE_STACK_FRAME psworg,savearea
- s %r15,BASED(.Lc_spsize) # make room for registers & psw
- mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
+ .macro CREATE_STACK_FRAME savearea
+ xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
- icm %r12,12,__LC_SVC_ILC
- stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
- st %r12,SP_ILC(%r15)
mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
- la %r12,0
- st %r12,__SF_BACKCHAIN(%r15) # clear back chain
+ stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
.endm
.macro RESTORE_ALL psworg,sync
@@ -188,6 +188,8 @@ STACK_SIZE = 1 << STACK_SHIFT
ssm __SF_EMPTY(%r15)
.endm
+ .section .kprobes.text, "ax"
+
/*
* Scheduler resume function, called by switch_to
* gpr2 = (task_struct *) prev
@@ -198,31 +200,21 @@ STACK_SIZE = 1 << STACK_SHIFT
.globl __switch_to
__switch_to:
basr %r1,0
-__switch_to_base:
- tm __THREAD_per(%r3),0xe8 # new process is using per ?
- bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine
- stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff
- clc __THREAD_per(12,%r3),__SF_EMPTY(%r15)
- be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's
- lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't
-__switch_to_noper:
- l %r4,__THREAD_info(%r2) # get thread_info of prev
+0: l %r4,__THREAD_info(%r2) # get thread_info of prev
+ l %r5,__THREAD_info(%r3) # get thread_info of next
tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
- bz __switch_to_no_mcck-__switch_to_base(%r1)
- ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
- l %r4,__THREAD_info(%r3) # get thread_info of next
- oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
-__switch_to_no_mcck:
- stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
- st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
- l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
- lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
- st %r3,__LC_CURRENT # __LC_CURRENT = current task struct
- lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
- l %r3,__THREAD_info(%r3) # load thread_info from task struct
- st %r3,__LC_THREAD_INFO
- ahi %r3,STACK_SIZE
- st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
+ bz 1f-0b(%r1)
+ ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+ oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
+1: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
+ st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
+ l %r15,__THREAD_ksp(%r3) # load kernel stack of next
+ lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
+ lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
+ st %r3,__LC_CURRENT # store task struct of next
+ st %r5,__LC_THREAD_INFO # store thread info of next
+ ahi %r5,STACK_SIZE # end of kernel stack of next
+ st %r5,__LC_KERNEL_STACK # store end of kernel stack
br %r14
__critical_start:
@@ -235,10 +227,11 @@ __critical_start:
system_call:
stpt __LC_SYNC_ENTER_TIMER
sysc_saveall:
- SAVE_ALL_BASE __LC_SAVE_AREA
SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
- CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
- lh %r7,0x8a # get svc number from lowcore
+ CREATE_STACK_FRAME __LC_SAVE_AREA
+ mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
+ mvc SP_ILC(4,%r15),__LC_SVC_ILC
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
sysc_vtime:
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
@@ -246,20 +239,20 @@ sysc_stime:
sysc_update:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
sysc_do_svc:
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- ltr %r7,%r7 # test for svc 0
+ xr %r7,%r7
+ icm %r7,3,SP_SVCNR(%r15) # load svc number and test for svc 0
bnz BASED(sysc_nr_ok) # svc number > 0
# svc 0: system call number in %r1
cl %r1,BASED(.Lnr_syscalls)
bnl BASED(sysc_nr_ok)
+ sth %r1,SP_SVCNR(%r15)
lr %r7,%r1 # copy svc number to %r7
sysc_nr_ok:
- sth %r7,SP_SVCNR(%r15)
sll %r7,2 # svc number *4
- l %r8,BASED(.Lsysc_table)
- tm __TI_flags+2(%r9),_TIF_SYSCALL
+ l %r10,BASED(.Lsysc_table)
+ tm __TI_flags+2(%r12),_TIF_SYSCALL
mvc SP_ARGS(4,%r15),SP_R7(%r15)
- l %r8,0(%r7,%r8) # get system call addr.
+ l %r8,0(%r7,%r10) # get system call addr.
bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
st %r2,SP_R2(%r15) # store return value (change R2 on stack)
@@ -267,7 +260,7 @@ sysc_nr_ok:
sysc_return:
LOCKDEP_SYS_EXIT
sysc_tif:
- tm __TI_flags+3(%r9),_TIF_WORK_SVC
+ tm __TI_flags+3(%r12),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
sysc_restore:
RESTORE_ALL __LC_RETURN_PSW,1
@@ -284,17 +277,17 @@ sysc_work:
# One of the work bits is on. Find out which one.
#
sysc_work_tif:
- tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
+ tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
bo BASED(sysc_mcck_pending)
- tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
+ tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
bo BASED(sysc_reschedule)
- tm __TI_flags+3(%r9),_TIF_SIGPENDING
+ tm __TI_flags+3(%r12),_TIF_SIGPENDING
bo BASED(sysc_sigpending)
- tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
+ tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
bo BASED(sysc_notify_resume)
- tm __TI_flags+3(%r9),_TIF_RESTART_SVC
+ tm __TI_flags+3(%r12),_TIF_RESTART_SVC
bo BASED(sysc_restart)
- tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
+ tm __TI_flags+3(%r12),_TIF_PER_TRAP
bo BASED(sysc_singlestep)
b BASED(sysc_return) # beware of critical section cleanup
@@ -318,13 +311,13 @@ sysc_mcck_pending:
# _TIF_SIGPENDING is set, call do_signal
#
sysc_sigpending:
- ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+ ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
- tm __TI_flags+3(%r9),_TIF_RESTART_SVC
+ tm __TI_flags+3(%r12),_TIF_RESTART_SVC
bo BASED(sysc_restart)
- tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
+ tm __TI_flags+3(%r12),_TIF_PER_TRAP
bo BASED(sysc_singlestep)
b BASED(sysc_return)
@@ -342,23 +335,23 @@ sysc_notify_resume:
# _TIF_RESTART_SVC is set, set up registers and restart svc
#
sysc_restart:
- ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
+ ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
l %r7,SP_R2(%r15) # load new svc number
mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
lm %r2,%r6,SP_R2(%r15) # load svc arguments
+ sth %r7,SP_SVCNR(%r15)
b BASED(sysc_nr_ok) # restart svc
#
-# _TIF_SINGLE_STEP is set, call do_single_step
+# _TIF_PER_TRAP is set, call do_per_trap
#
sysc_singlestep:
- ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
- mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
- mvi SP_SVCNR+1(%r15),0xff
+ ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
+ xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_return) # load adr. of system return
- br %r1 # branch to do_single_step
+ br %r1 # branch to do_per_trap
#
# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
@@ -368,15 +361,15 @@ sysc_tracesys:
l %r1,BASED(.Ltrace_entry)
la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,0
- srl %r7,2
- st %r7,SP_R2(%r15)
+ xr %r0,%r0
+ icm %r0,3,SP_SVCNR(%r15)
+ st %r0,SP_R2(%r15)
basr %r14,%r1
cl %r2,BASED(.Lnr_syscalls)
bnl BASED(sysc_tracenogo)
- l %r8,BASED(.Lsysc_table)
lr %r7,%r2
sll %r7,2 # svc number *4
- l %r8,0(%r7,%r8)
+ l %r8,0(%r7,%r10)
sysc_tracego:
lm %r3,%r6,SP_R3(%r15)
mvc SP_ARGS(4,%r15),SP_R7(%r15)
@@ -384,7 +377,7 @@ sysc_tracego:
basr %r14,%r8 # call sys_xxx
st %r2,SP_R2(%r15) # store return value
sysc_tracenogo:
- tm __TI_flags+2(%r9),_TIF_SYSCALL
+ tm __TI_flags+2(%r12),_TIF_SYSCALL
bz BASED(sysc_return)
l %r1,BASED(.Ltrace_exit)
la %r2,SP_PTREGS(%r15) # load pt_regs
@@ -397,7 +390,7 @@ sysc_tracenogo:
.globl ret_from_fork
ret_from_fork:
l %r13,__LC_SVC_NEW_PSW+4
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # forking a kernel thread ?
bo BASED(0f)
st %r15,SP_R15(%r15) # store stack pointer for new kthread
@@ -432,8 +425,8 @@ kernel_execve:
0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
l %r15,__LC_KERNEL_STACK # load ksp
s %r15,BASED(.Lc_spsize) # make room for registers & psw
- l %r9,__LC_THREAD_INFO
mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
+ l %r12,__LC_THREAD_INFO
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
l %r1,BASED(.Lexecve_tail)
@@ -463,26 +456,27 @@ pgm_check_handler:
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
bnz BASED(pgm_per) # got per exception -> special case
- SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
- CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ CREATE_STACK_FRAME __LC_SAVE_AREA
+ xc SP_ILC(4,%r15),SP_ILC(%r15)
+ mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(pgm_no_vtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime:
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r3,__LC_PGM_ILC # load program interruption code
l %r4,__LC_TRANS_EXC_CODE
REENABLE_IRQS
la %r8,0x7f
nr %r8,%r3
-pgm_do_call:
- l %r7,BASED(.Ljump_table)
sll %r8,2
- l %r7,0(%r8,%r7) # load address of handler routine
+ l %r1,BASED(.Ljump_table)
+ l %r1,0(%r8,%r1) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
- basr %r14,%r7 # branch to interrupt-handler
+ basr %r14,%r1 # branch to interrupt-handler
pgm_exit:
b BASED(sysc_return)
@@ -503,33 +497,34 @@ pgm_per:
# Normal per exception
#
pgm_per_std:
- SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
- CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ CREATE_STACK_FRAME __LC_SAVE_AREA
+ mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(pgm_no_vtime2)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime2:
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- l %r1,__TI_task(%r9)
+ l %r1,__TI_task(%r12)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
bz BASED(kernel_per)
- mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
- oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
+ mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
+ mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
+ oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
l %r3,__LC_PGM_ILC # load program interruption code
l %r4,__LC_TRANS_EXC_CODE
REENABLE_IRQS
la %r8,0x7f
nr %r8,%r3 # clear per-event-bit and ilc
be BASED(pgm_exit2) # only per or per+check ?
- l %r7,BASED(.Ljump_table)
sll %r8,2
- l %r7,0(%r8,%r7) # load address of handler routine
+ l %r1,BASED(.Ljump_table)
+ l %r1,0(%r8,%r1) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
- basr %r14,%r7 # branch to interrupt-handler
+ basr %r14,%r1 # branch to interrupt-handler
pgm_exit2:
b BASED(sysc_return)
@@ -537,18 +532,19 @@ pgm_exit2:
# it was a single stepped SVC that is causing all the trouble
#
pgm_svcper:
- SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
- CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+ CREATE_STACK_FRAME __LC_SAVE_AREA
+ mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
+ mvc SP_ILC(4,%r15),__LC_SVC_ILC
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
- lh %r7,0x8a # get svc number from lowcore
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- l %r8,__TI_task(%r9)
- mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
- oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ l %r8,__TI_task(%r12)
+ mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
+ mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
+ oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
lm %r2,%r6,SP_R2(%r15) # load svc arguments
b BASED(sysc_do_svc)
@@ -558,8 +554,7 @@ pgm_svcper:
#
kernel_per:
REENABLE_IRQS
- mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
- mvi SP_SVCNR+1(%r15),0xff
+ xc SP_SVCNR(2,%r15),SP_SVCNR(%r15)
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
basr %r14,%r1 # branch to do_single_step
@@ -573,9 +568,10 @@ kernel_per:
io_int_handler:
stck __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER
- SAVE_ALL_BASE __LC_SAVE_AREA+16
SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
- CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
+ CREATE_STACK_FRAME __LC_SAVE_AREA+16
+ mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(io_no_vtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -583,7 +579,6 @@ io_int_handler:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
io_no_vtime:
TRACE_IRQS_OFF
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
@@ -591,7 +586,7 @@ io_return:
LOCKDEP_SYS_EXIT
TRACE_IRQS_ON
io_tif:
- tm __TI_flags+3(%r9),_TIF_WORK_INT
+ tm __TI_flags+3(%r12),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.)
io_restore:
RESTORE_ALL __LC_RETURN_PSW,0
@@ -609,9 +604,9 @@ io_work:
bo BASED(io_work_user) # yes -> do resched & signal
#ifdef CONFIG_PREEMPT
# check for preemptive scheduling
- icm %r0,15,__TI_precount(%r9)
+ icm %r0,15,__TI_precount(%r12)
bnz BASED(io_restore) # preemption disabled
- tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
+ tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
bno BASED(io_restore)
# switch to kernel stack
l %r1,SP_R15(%r15)
@@ -645,13 +640,13 @@ io_work_user:
# and _TIF_MCCK_PENDING
#
io_work_tif:
- tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
+ tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
bo BASED(io_mcck_pending)
- tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
+ tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
bo BASED(io_reschedule)
- tm __TI_flags+3(%r9),_TIF_SIGPENDING
+ tm __TI_flags+3(%r12),_TIF_SIGPENDING
bo BASED(io_sigpending)
- tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
+ tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
bo BASED(io_notify_resume)
b BASED(io_return) # beware of critical section cleanup
@@ -711,16 +706,16 @@ io_notify_resume:
ext_int_handler:
stck __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER
- SAVE_ALL_BASE __LC_SAVE_AREA+16
SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
- CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
+ CREATE_STACK_FRAME __LC_SAVE_AREA+16
+ mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(ext_no_vtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
ext_no_vtime:
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
@@ -775,7 +770,10 @@ mcck_int_main:
sra %r14,PAGE_SHIFT
be BASED(0f)
l %r15,__LC_PANIC_STACK # load panic stack
-0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
+0: s %r15,BASED(.Lc_spsize) # make room for registers & psw
+ CREATE_STACK_FRAME __LC_SAVE_AREA+32
+ mvc SP_PSW(8,%r15),0(%r12)
+ l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
bno BASED(mcck_no_vtime) # no -> skip cleanup critical
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -784,7 +782,6 @@ mcck_int_main:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
mcck_no_vtime:
- l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ls390_mcck)
basr %r14,%r1 # call machine check handler
@@ -796,7 +793,7 @@ mcck_no_vtime:
xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
lr %r15,%r1
stosm __SF_EMPTY(%r15),0x04 # turn dat on
- tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
+ tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
bno BASED(mcck_return)
TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck)
@@ -861,6 +858,8 @@ restart_crash:
restart_go:
#endif
+ .section .kprobes.text, "ax"
+
#ifdef CONFIG_CHECK_STACK
/*
* The synchronous or the asynchronous stack overflowed. We are dead.
@@ -943,12 +942,13 @@ cleanup_system_call:
bh BASED(0f)
mvc __LC_SAVE_AREA(16),0(%r12)
0: st %r13,4(%r12)
- st %r12,__LC_SAVE_AREA+48 # argh
- SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
- CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
- l %r12,__LC_SAVE_AREA+48 # argh
+ l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ s %r15,BASED(.Lc_spsize) # make room for registers & psw
st %r15,12(%r12)
- lh %r7,0x8a
+ CREATE_STACK_FRAME __LC_SAVE_AREA
+ mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
+ mvc SP_ILC(4,%r15),__LC_SVC_ILC
+ mvc 0(4,%r12),__LC_THREAD_INFO
cleanup_vtime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
bhe BASED(cleanup_stime)
@@ -1046,7 +1046,7 @@ cleanup_io_restore_insn:
.Ldo_signal: .long do_signal
.Ldo_notify_resume:
.long do_notify_resume
-.Lhandle_per: .long do_single_step
+.Lhandle_per: .long do_per_trap
.Ldo_execve: .long do_execve
.Lexecve_tail: .long execve_tail
.Ljump_table: .long pgm_check_table
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 95c1dfc4ef31..17a6f83a2d67 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -12,7 +12,7 @@ pgm_check_handler_t do_dat_exception;
extern int sysctl_userprocess_debug;
-void do_single_step(struct pt_regs *regs);
+void do_per_trap(struct pt_regs *regs);
void syscall_trace(struct pt_regs *regs, int entryexit);
void kernel_stack_overflow(struct pt_regs * regs);
void do_signal(struct pt_regs *regs);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 8f3e802174db..9d3603d6c511 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -51,7 +51,7 @@ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
- _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
@@ -197,6 +197,8 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
ssm __SF_EMPTY(%r15)
.endm
+ .section .kprobes.text, "ax"
+
/*
* Scheduler resume function, called by switch_to
* gpr2 = (task_struct *) prev
@@ -206,30 +208,21 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
*/
.globl __switch_to
__switch_to:
- tm __THREAD_per+4(%r3),0xe8 # is the new process using per ?
- jz __switch_to_noper # if not we're fine
- stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff
- clc __THREAD_per(24,%r3),__SF_EMPTY(%r15)
- je __switch_to_noper # we got away without bashing TLB's
- lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't
-__switch_to_noper:
- lg %r4,__THREAD_info(%r2) # get thread_info of prev
+ lg %r4,__THREAD_info(%r2) # get thread_info of prev
+ lg %r5,__THREAD_info(%r3) # get thread_info of next
tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
- jz __switch_to_no_mcck
- ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
- lg %r4,__THREAD_info(%r3) # get thread_info of next
- oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next
-__switch_to_no_mcck:
- stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
- stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
- lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
- lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
- stg %r3,__LC_CURRENT # __LC_CURRENT = current task struct
- lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
- lg %r3,__THREAD_info(%r3) # load thread_info from task struct
- stg %r3,__LC_THREAD_INFO
- aghi %r3,STACK_SIZE
- stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
+ jz 0f
+ ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+ oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next
+0: stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
+ stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev
+ lg %r15,__THREAD_ksp(%r3) # load kernel stack of next
+ lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
+ lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
+ stg %r3,__LC_CURRENT # store task struct of next
+ stg %r5,__LC_THREAD_INFO # store thread info of next
+ aghi %r5,STACK_SIZE # end of kernel stack of next
+ stg %r5,__LC_KERNEL_STACK # store end of kernel stack
br %r14
__critical_start:
@@ -309,7 +302,7 @@ sysc_work_tif:
jo sysc_notify_resume
tm __TI_flags+7(%r12),_TIF_RESTART_SVC
jo sysc_restart
- tm __TI_flags+7(%r12),_TIF_SINGLE_STEP
+ tm __TI_flags+7(%r12),_TIF_PER_TRAP
jo sysc_singlestep
j sysc_return # beware of critical section cleanup
@@ -331,12 +324,12 @@ sysc_mcck_pending:
# _TIF_SIGPENDING is set, call do_signal
#
sysc_sigpending:
- ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+ ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
la %r2,SP_PTREGS(%r15) # load pt_regs
brasl %r14,do_signal # call do_signal
tm __TI_flags+7(%r12),_TIF_RESTART_SVC
jo sysc_restart
- tm __TI_flags+7(%r12),_TIF_SINGLE_STEP
+ tm __TI_flags+7(%r12),_TIF_PER_TRAP
jo sysc_singlestep
j sysc_return
@@ -361,14 +354,14 @@ sysc_restart:
j sysc_nr_ok # restart svc
#
-# _TIF_SINGLE_STEP is set, call do_single_step
+# _TIF_PER_TRAP is set, call do_per_trap
#
sysc_singlestep:
- ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+ ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
la %r2,SP_PTREGS(%r15) # address of register-save area
larl %r14,sysc_return # load adr. of system return
- jg do_single_step # branch to do_sigtrap
+ jg do_per_trap
#
# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
@@ -524,10 +517,10 @@ pgm_no_vtime2:
lg %r1,__TI_task(%r12)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
jz kernel_per
- mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
- oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
+ mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
+ mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
+ oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
lgf %r3,__LC_PGM_ILC # load program interruption code
lg %r4,__LC_TRANS_EXC_CODE
REENABLE_IRQS
@@ -556,10 +549,10 @@ pgm_svcper:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
LAST_BREAK
lg %r8,__TI_task(%r12)
- mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
- oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
+ mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
+ oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
j sysc_do_svc
@@ -571,7 +564,7 @@ kernel_per:
REENABLE_IRQS
xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
la %r2,SP_PTREGS(%r15) # address of register-save area
- brasl %r14,do_single_step
+ brasl %r14,do_per_trap
j pgm_exit
/*
@@ -868,6 +861,8 @@ restart_crash:
restart_go:
#endif
+ .section .kprobes.text, "ax"
+
#ifdef CONFIG_CHECK_STACK
/*
* The synchronous or the asynchronous stack overflowed. We are dead.
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 6a83d0581317..8624230d2bbe 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -4,7 +4,7 @@
* Copyright IBM Corp. 2009
*
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
- *
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/hardirq.h>
@@ -15,173 +15,139 @@
#include <trace/syscall.h>
#include <asm/asm-offsets.h>
+#ifdef CONFIG_64BIT
+#define MCOUNT_OFFSET_RET 12
+#else
+#define MCOUNT_OFFSET_RET 22
+#endif
+
#ifdef CONFIG_DYNAMIC_FTRACE
void ftrace_disable_code(void);
-void ftrace_disable_return(void);
-void ftrace_call_code(void);
-void ftrace_nop_code(void);
-
-#define FTRACE_INSN_SIZE 4
+void ftrace_enable_insn(void);
#ifdef CONFIG_64BIT
-
+/*
+ * The 64-bit mcount code looks like this:
+ * stg %r14,8(%r15) # offset 0
+ * > larl %r1,<&counter> # offset 6
+ * > brasl %r14,_mcount # offset 12
+ * lg %r14,8(%r15) # offset 18
+ * Total length is 24 bytes. The middle two instructions of the mcount
+ * block get overwritten by ftrace_make_nop / ftrace_make_call.
+ * The 64-bit enabled ftrace code block looks like this:
+ * stg %r14,8(%r15) # offset 0
+ * > lg %r1,__LC_FTRACE_FUNC # offset 6
+ * > lgr %r0,%r0 # offset 12
+ * > basr %r14,%r1 # offset 16
+ * lg %r14,8(%15) # offset 18
+ * The return points of the mcount/ftrace function have the same offset 18.
+ * The 64-bit disable ftrace code block looks like this:
+ * stg %r14,8(%r15) # offset 0
+ * > jg .+18 # offset 6
+ * > lgr %r0,%r0 # offset 12
+ * > basr %r14,%r1 # offset 16
+ * lg %r14,8(%15) # offset 18
+ * The jg instruction branches to offset 24 to skip as many instructions
+ * as possible.
+ */
asm(
" .align 4\n"
"ftrace_disable_code:\n"
- " j 0f\n"
- " .word 0x0024\n"
- " lg %r1,"__stringify(__LC_FTRACE_FUNC)"\n"
- " basr %r14,%r1\n"
- "ftrace_disable_return:\n"
- " lg %r14,8(15)\n"
+ " jg 0f\n"
" lgr %r0,%r0\n"
- "0:\n");
-
-asm(
+ " basr %r14,%r1\n"
+ "0:\n"
" .align 4\n"
- "ftrace_nop_code:\n"
- " j .+"__stringify(MCOUNT_INSN_SIZE)"\n");
+ "ftrace_enable_insn:\n"
+ " lg %r1,"__stringify(__LC_FTRACE_FUNC)"\n");
-asm(
- " .align 4\n"
- "ftrace_call_code:\n"
- " stg %r14,8(%r15)\n");
+#define FTRACE_INSN_SIZE 6
#else /* CONFIG_64BIT */
-
+/*
+ * The 31-bit mcount code looks like this:
+ * st %r14,4(%r15) # offset 0
+ * > bras %r1,0f # offset 4
+ * > .long _mcount # offset 8
+ * > .long <&counter> # offset 12
+ * > 0: l %r14,0(%r1) # offset 16
+ * > l %r1,4(%r1) # offset 20
+ * basr %r14,%r14 # offset 24
+ * l %r14,4(%r15) # offset 26
+ * Total length is 30 bytes. The twenty bytes starting from offset 4
+ * to offset 24 get overwritten by ftrace_make_nop / ftrace_make_call.
+ * The 31-bit enabled ftrace code block looks like this:
+ * st %r14,4(%r15) # offset 0
+ * > l %r14,__LC_FTRACE_FUNC # offset 4
+ * > j 0f # offset 8
+ * > .fill 12,1,0x07 # offset 12
+ * 0: basr %r14,%r14 # offset 24
+ * l %r14,4(%r14) # offset 26
+ * The return points of the mcount/ftrace function have the same offset 26.
+ * The 31-bit disabled ftrace code block looks like this:
+ * st %r14,4(%r15) # offset 0
+ * > j .+26 # offset 4
+ * > j 0f # offset 8
+ * > .fill 12,1,0x07 # offset 12
+ * 0: basr %r14,%r14 # offset 24
+ * l %r14,4(%r14) # offset 26
+ * The j instruction branches to offset 30 to skip as many instructions
+ * as possible.
+ */
asm(
" .align 4\n"
"ftrace_disable_code:\n"
+ " j 1f\n"
" j 0f\n"
- " l %r1,"__stringify(__LC_FTRACE_FUNC)"\n"
- " basr %r14,%r1\n"
- "ftrace_disable_return:\n"
- " l %r14,4(%r15)\n"
- " j 0f\n"
- " bcr 0,%r7\n"
- " bcr 0,%r7\n"
- " bcr 0,%r7\n"
- " bcr 0,%r7\n"
- " bcr 0,%r7\n"
- " bcr 0,%r7\n"
- "0:\n");
-
-asm(
+ " .fill 12,1,0x07\n"
+ "0: basr %r14,%r14\n"
+ "1:\n"
" .align 4\n"
- "ftrace_nop_code:\n"
- " j .+"__stringify(MCOUNT_INSN_SIZE)"\n");
+ "ftrace_enable_insn:\n"
+ " l %r14,"__stringify(__LC_FTRACE_FUNC)"\n");
-asm(
- " .align 4\n"
- "ftrace_call_code:\n"
- " st %r14,4(%r15)\n");
+#define FTRACE_INSN_SIZE 4
#endif /* CONFIG_64BIT */
-static int ftrace_modify_code(unsigned long ip,
- void *old_code, int old_size,
- void *new_code, int new_size)
-{
- unsigned char replaced[MCOUNT_INSN_SIZE];
-
- /*
- * Note: Due to modules code can disappear and change.
- * We need to protect against faulting as well as code
- * changing. We do this by using the probe_kernel_*
- * functions.
- * This however is just a simple sanity check.
- */
- if (probe_kernel_read(replaced, (void *)ip, old_size))
- return -EFAULT;
- if (memcmp(replaced, old_code, old_size) != 0)
- return -EINVAL;
- if (probe_kernel_write((void *)ip, new_code, new_size))
- return -EPERM;
- return 0;
-}
-
-static int ftrace_make_initial_nop(struct module *mod, struct dyn_ftrace *rec,
- unsigned long addr)
-{
- return ftrace_modify_code(rec->ip,
- ftrace_call_code, FTRACE_INSN_SIZE,
- ftrace_disable_code, MCOUNT_INSN_SIZE);
-}
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
unsigned long addr)
{
- if (addr == MCOUNT_ADDR)
- return ftrace_make_initial_nop(mod, rec, addr);
- return ftrace_modify_code(rec->ip,
- ftrace_call_code, FTRACE_INSN_SIZE,
- ftrace_nop_code, FTRACE_INSN_SIZE);
+ if (probe_kernel_write((void *) rec->ip, ftrace_disable_code,
+ MCOUNT_INSN_SIZE))
+ return -EPERM;
+ return 0;
}
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
- return ftrace_modify_code(rec->ip,
- ftrace_nop_code, FTRACE_INSN_SIZE,
- ftrace_call_code, FTRACE_INSN_SIZE);
+ if (probe_kernel_write((void *) rec->ip, ftrace_enable_insn,
+ FTRACE_INSN_SIZE))
+ return -EPERM;
+ return 0;
}
int ftrace_update_ftrace_func(ftrace_func_t func)
{
- ftrace_dyn_func = (unsigned long)func;
return 0;
}
int __init ftrace_dyn_arch_init(void *data)
{
- *(unsigned long *)data = 0;
+ *(unsigned long *) data = 0;
return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-#ifdef CONFIG_DYNAMIC_FTRACE
-/*
- * Patch the kernel code at ftrace_graph_caller location:
- * The instruction there is branch relative on condition. The condition mask
- * is either all ones (always branch aka disable ftrace_graph_caller) or all
- * zeroes (nop aka enable ftrace_graph_caller).
- * Instruction format for brc is a7m4xxxx where m is the condition mask.
- */
-int ftrace_enable_ftrace_graph_caller(void)
-{
- unsigned short opcode = 0xa704;
-
- return probe_kernel_write(ftrace_graph_caller, &opcode, sizeof(opcode));
-}
-
-int ftrace_disable_ftrace_graph_caller(void)
-{
- unsigned short opcode = 0xa7f4;
-
- return probe_kernel_write(ftrace_graph_caller, &opcode, sizeof(opcode));
-}
-
-static inline unsigned long ftrace_mcount_call_adjust(unsigned long addr)
-{
- return addr - (ftrace_disable_return - ftrace_disable_code);
-}
-
-#else /* CONFIG_DYNAMIC_FTRACE */
-
-static inline unsigned long ftrace_mcount_call_adjust(unsigned long addr)
-{
- return addr - MCOUNT_OFFSET_RET;
-}
-
-#endif /* CONFIG_DYNAMIC_FTRACE */
-
/*
* Hook the return address and push it in the stack of return addresses
* in current thread info.
*/
-unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent)
+unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
{
struct ftrace_graph_ent trace;
@@ -189,14 +155,42 @@ unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent)
goto out;
if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
goto out;
- trace.func = ftrace_mcount_call_adjust(ip) & PSW_ADDR_INSN;
+ trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET;
/* Only trace if the calling function expects to. */
if (!ftrace_graph_entry(&trace)) {
current->curr_ret_stack--;
goto out;
}
- parent = (unsigned long)return_to_handler;
+ parent = (unsigned long) return_to_handler;
out:
return parent;
}
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+/*
+ * Patch the kernel code at ftrace_graph_caller location. The instruction
+ * there is branch relative and save to prepare_ftrace_return. To disable
+ * the call to prepare_ftrace_return we patch the bras offset to point
+ * directly after the instructions. To enable the call we calculate
+ * the original offset to prepare_ftrace_return and put it back.
+ */
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ unsigned short offset;
+
+ offset = ((void *) prepare_ftrace_return -
+ (void *) ftrace_graph_caller) / 2;
+ return probe_kernel_write(ftrace_graph_caller + 2,
+ &offset, sizeof(offset));
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ static unsigned short offset = 0x0002;
+
+ return probe_kernel_write(ftrace_graph_caller + 2,
+ &offset, sizeof(offset));
+}
+
+#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 026a37a94fc9..ea5099c9709c 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -1,7 +1,5 @@
/*
- * arch/s390/kernel/irq.c
- *
- * Copyright IBM Corp. 2004,2007
+ * Copyright IBM Corp. 2004,2010
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Thomas Spatzier (tspat@de.ibm.com)
*
@@ -17,12 +15,42 @@
#include <linux/proc_fs.h>
#include <linux/profile.h>
+struct irq_class {
+ char *name;
+ char *desc;
+};
+
+static const struct irq_class intrclass_names[] = {
+ {.name = "EXT" },
+ {.name = "I/O" },
+ {.name = "CLK", .desc = "[EXT] Clock Comparator" },
+ {.name = "IPI", .desc = "[EXT] Signal Processor" },
+ {.name = "TMR", .desc = "[EXT] CPU Timer" },
+ {.name = "TAL", .desc = "[EXT] Timing Alert" },
+ {.name = "PFL", .desc = "[EXT] Pseudo Page Fault" },
+ {.name = "DSD", .desc = "[EXT] DASD Diag" },
+ {.name = "VRT", .desc = "[EXT] Virtio" },
+ {.name = "SCP", .desc = "[EXT] Service Call" },
+ {.name = "IUC", .desc = "[EXT] IUCV" },
+ {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" },
+ {.name = "QDI", .desc = "[I/O] QDIO Interrupt" },
+ {.name = "DAS", .desc = "[I/O] DASD" },
+ {.name = "C15", .desc = "[I/O] 3215" },
+ {.name = "C70", .desc = "[I/O] 3270" },
+ {.name = "TAP", .desc = "[I/O] Tape" },
+ {.name = "VMR", .desc = "[I/O] Unit Record Devices" },
+ {.name = "LCS", .desc = "[I/O] LCS" },
+ {.name = "CLW", .desc = "[I/O] CLAW" },
+ {.name = "CTC", .desc = "[I/O] CTC" },
+ {.name = "APB", .desc = "[I/O] AP Bus" },
+ {.name = "NMI", .desc = "[NMI] Machine Check" },
+};
+
/*
* show_interrupts is needed by /proc/interrupts.
*/
int show_interrupts(struct seq_file *p, void *v)
{
- static const char *intrclass_names[] = { "EXT", "I/O", };
int i = *(loff_t *) v, j;
get_online_cpus();
@@ -34,15 +62,16 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < NR_IRQS) {
- seq_printf(p, "%s: ", intrclass_names[i]);
+ seq_printf(p, "%s: ", intrclass_names[i].name);
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
+ if (intrclass_names[i].desc)
+ seq_printf(p, " %s", intrclass_names[i].desc);
seq_putc(p, '\n');
-
}
put_online_cpus();
return 0;
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 2564793ec2b6..1d05d669107c 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -32,34 +32,14 @@
#include <linux/slab.h>
#include <linux/hardirq.h>
-DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe);
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+struct kretprobe_blackpoint kretprobe_blacklist[] = { };
-int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
- /* Make sure the probe isn't going on a difficult instruction */
- if (is_prohibited_opcode((kprobe_opcode_t *) p->addr))
- return -EINVAL;
-
- if ((unsigned long)p->addr & 0x01)
- return -EINVAL;
-
- /* Use the get_insn_slot() facility for correctness */
- if (!(p->ainsn.insn = get_insn_slot()))
- return -ENOMEM;
-
- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-
- get_instruction_type(&p->ainsn);
- p->opcode = *p->addr;
- return 0;
-}
-
-int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
+static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn)
{
- switch (*(__u8 *) instruction) {
+ switch (insn[0] >> 8) {
case 0x0c: /* bassm */
case 0x0b: /* bsm */
case 0x83: /* diag */
@@ -68,7 +48,7 @@ int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
case 0xad: /* stosm */
return -EINVAL;
}
- switch (*(__u16 *) instruction) {
+ switch (insn[0]) {
case 0x0101: /* pr */
case 0xb25a: /* bsa */
case 0xb240: /* bakr */
@@ -81,93 +61,92 @@ int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
return 0;
}
-void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
+static int __kprobes get_fixup_type(kprobe_opcode_t *insn)
{
/* default fixup method */
- ainsn->fixup = FIXUP_PSW_NORMAL;
-
- /* save r1 operand */
- ainsn->reg = (*ainsn->insn & 0xf0) >> 4;
+ int fixup = FIXUP_PSW_NORMAL;
- /* save the instruction length (pop 5-5) in bytes */
- switch (*(__u8 *) (ainsn->insn) >> 6) {
- case 0:
- ainsn->ilen = 2;
- break;
- case 1:
- case 2:
- ainsn->ilen = 4;
- break;
- case 3:
- ainsn->ilen = 6;
- break;
- }
-
- switch (*(__u8 *) ainsn->insn) {
+ switch (insn[0] >> 8) {
case 0x05: /* balr */
case 0x0d: /* basr */
- ainsn->fixup = FIXUP_RETURN_REGISTER;
+ fixup = FIXUP_RETURN_REGISTER;
/* if r2 = 0, no branch will be taken */
- if ((*ainsn->insn & 0x0f) == 0)
- ainsn->fixup |= FIXUP_BRANCH_NOT_TAKEN;
+ if ((insn[0] & 0x0f) == 0)
+ fixup |= FIXUP_BRANCH_NOT_TAKEN;
break;
case 0x06: /* bctr */
case 0x07: /* bcr */
- ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ fixup = FIXUP_BRANCH_NOT_TAKEN;
break;
case 0x45: /* bal */
case 0x4d: /* bas */
- ainsn->fixup = FIXUP_RETURN_REGISTER;
+ fixup = FIXUP_RETURN_REGISTER;
break;
case 0x47: /* bc */
case 0x46: /* bct */
case 0x86: /* bxh */
case 0x87: /* bxle */
- ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ fixup = FIXUP_BRANCH_NOT_TAKEN;
break;
case 0x82: /* lpsw */
- ainsn->fixup = FIXUP_NOT_REQUIRED;
+ fixup = FIXUP_NOT_REQUIRED;
break;
case 0xb2: /* lpswe */
- if (*(((__u8 *) ainsn->insn) + 1) == 0xb2) {
- ainsn->fixup = FIXUP_NOT_REQUIRED;
- }
+ if ((insn[0] & 0xff) == 0xb2)
+ fixup = FIXUP_NOT_REQUIRED;
break;
case 0xa7: /* bras */
- if ((*ainsn->insn & 0x0f) == 0x05) {
- ainsn->fixup |= FIXUP_RETURN_REGISTER;
- }
+ if ((insn[0] & 0x0f) == 0x05)
+ fixup |= FIXUP_RETURN_REGISTER;
break;
case 0xc0:
- if ((*ainsn->insn & 0x0f) == 0x00 /* larl */
- || (*ainsn->insn & 0x0f) == 0x05) /* brasl */
- ainsn->fixup |= FIXUP_RETURN_REGISTER;
+ if ((insn[0] & 0x0f) == 0x00 || /* larl */
+ (insn[0] & 0x0f) == 0x05) /* brasl */
+ fixup |= FIXUP_RETURN_REGISTER;
break;
case 0xeb:
- if (*(((__u8 *) ainsn->insn) + 5 ) == 0x44 || /* bxhg */
- *(((__u8 *) ainsn->insn) + 5) == 0x45) {/* bxleg */
- ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
- }
+ if ((insn[2] & 0xff) == 0x44 || /* bxhg */
+ (insn[2] & 0xff) == 0x45) /* bxleg */
+ fixup = FIXUP_BRANCH_NOT_TAKEN;
break;
case 0xe3: /* bctg */
- if (*(((__u8 *) ainsn->insn) + 5) == 0x46) {
- ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
- }
+ if ((insn[2] & 0xff) == 0x46)
+ fixup = FIXUP_BRANCH_NOT_TAKEN;
break;
}
+ return fixup;
+}
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+ if ((unsigned long) p->addr & 0x01)
+ return -EINVAL;
+
+ /* Make sure the probe isn't going on a difficult instruction */
+ if (is_prohibited_opcode(p->addr))
+ return -EINVAL;
+
+ p->opcode = *p->addr;
+ memcpy(p->ainsn.insn, p->addr, ((p->opcode >> 14) + 3) & -2);
+
+ return 0;
}
+struct ins_replace_args {
+ kprobe_opcode_t *ptr;
+ kprobe_opcode_t opcode;
+};
+
static int __kprobes swap_instruction(void *aref)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
unsigned long status = kcb->kprobe_status;
struct ins_replace_args *args = aref;
- int rc;
kcb->kprobe_status = KPROBE_SWAP_INST;
- rc = probe_kernel_write(args->ptr, &args->new, sizeof(args->new));
+ probe_kernel_write(args->ptr, &args->opcode, sizeof(args->opcode));
kcb->kprobe_status = status;
- return rc;
+ return 0;
}
void __kprobes arch_arm_kprobe(struct kprobe *p)
@@ -175,8 +154,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
struct ins_replace_args args;
args.ptr = p->addr;
- args.old = p->opcode;
- args.new = BREAKPOINT_INSTRUCTION;
+ args.opcode = BREAKPOINT_INSTRUCTION;
stop_machine(swap_instruction, &args, NULL);
}
@@ -185,64 +163,69 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
struct ins_replace_args args;
args.ptr = p->addr;
- args.old = BREAKPOINT_INSTRUCTION;
- args.new = p->opcode;
+ args.opcode = p->opcode;
stop_machine(swap_instruction, &args, NULL);
}
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- if (p->ainsn.insn) {
- free_insn_slot(p->ainsn.insn, 0);
- p->ainsn.insn = NULL;
- }
}
-static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb,
+ struct pt_regs *regs,
+ unsigned long ip)
{
- per_cr_bits kprobe_per_regs[1];
+ struct per_regs per_kprobe;
- memset(kprobe_per_regs, 0, sizeof(per_cr_bits));
- regs->psw.addr = (unsigned long)p->ainsn.insn | PSW_ADDR_AMODE;
+ /* Set up the PER control registers %cr9-%cr11 */
+ per_kprobe.control = PER_EVENT_IFETCH;
+ per_kprobe.start = ip;
+ per_kprobe.end = ip;
- /* Set up the per control reg info, will pass to lctl */
- kprobe_per_regs[0].em_instruction_fetch = 1;
- kprobe_per_regs[0].starting_addr = (unsigned long)p->ainsn.insn;
- kprobe_per_regs[0].ending_addr = (unsigned long)p->ainsn.insn + 1;
+ /* Save control regs and psw mask */
+ __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
+ kcb->kprobe_saved_imask = regs->psw.mask &
+ (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT);
- /* Set the PER control regs, turns on single step for this address */
- __ctl_load(kprobe_per_regs, 9, 11);
+ /* Set PER control regs, turns on single step for the given address */
+ __ctl_load(per_kprobe, 9, 11);
regs->psw.mask |= PSW_MASK_PER;
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
+ regs->psw.addr = ip | PSW_ADDR_AMODE;
}
-static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb,
+ struct pt_regs *regs,
+ unsigned long ip)
{
- kcb->prev_kprobe.kp = kprobe_running();
- kcb->prev_kprobe.status = kcb->kprobe_status;
- kcb->prev_kprobe.kprobe_saved_imask = kcb->kprobe_saved_imask;
- memcpy(kcb->prev_kprobe.kprobe_saved_ctl, kcb->kprobe_saved_ctl,
- sizeof(kcb->kprobe_saved_ctl));
+ /* Restore control regs and psw mask, set new psw address */
+ __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
+ regs->psw.mask &= ~PSW_MASK_PER;
+ regs->psw.mask |= kcb->kprobe_saved_imask;
+ regs->psw.addr = ip | PSW_ADDR_AMODE;
}
-static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+/*
+ * Activate a kprobe by storing its pointer to current_kprobe. The
+ * previous kprobe is stored in kcb->prev_kprobe. A stack of up to
+ * two kprobes can be active, see KPROBE_REENTER.
+ */
+static void __kprobes push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p)
{
- __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
- kcb->kprobe_status = kcb->prev_kprobe.status;
- kcb->kprobe_saved_imask = kcb->prev_kprobe.kprobe_saved_imask;
- memcpy(kcb->kprobe_saved_ctl, kcb->prev_kprobe.kprobe_saved_ctl,
- sizeof(kcb->kprobe_saved_ctl));
+ kcb->prev_kprobe.kp = __get_cpu_var(current_kprobe);
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ __get_cpu_var(current_kprobe) = p;
}
-static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb)
+/*
+ * Deactivate a kprobe by backing up to the previous state. If the
+ * current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL,
+ * for any other state prev_kprobe.kp will be NULL.
+ */
+static void __kprobes pop_kprobe(struct kprobe_ctlblk *kcb)
{
- __get_cpu_var(current_kprobe) = p;
- /* Save the interrupt and per flags */
- kcb->kprobe_saved_imask = regs->psw.mask &
- (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT);
- /* Save the control regs that govern PER */
- __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
}
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
@@ -251,79 +234,104 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
/* Replace the return addr with trampoline addr */
- regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
+ regs->gprs[14] = (unsigned long) &kretprobe_trampoline;
+}
+
+static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb,
+ struct kprobe *p)
+{
+ switch (kcb->kprobe_status) {
+ case KPROBE_HIT_SSDONE:
+ case KPROBE_HIT_ACTIVE:
+ kprobes_inc_nmissed_count(p);
+ break;
+ case KPROBE_HIT_SS:
+ case KPROBE_REENTER:
+ default:
+ /*
+ * A kprobe on the code path to single step an instruction
+ * is a BUG. The code path resides in the .kprobes.text
+ * section and is executed with interrupts disabled.
+ */
+ printk(KERN_EMERG "Invalid kprobe detected at %p.\n", p->addr);
+ dump_kprobe(p);
+ BUG();
+ }
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
{
- struct kprobe *p;
- int ret = 0;
- unsigned long *addr = (unsigned long *)
- ((regs->psw.addr & PSW_ADDR_INSN) - 2);
struct kprobe_ctlblk *kcb;
+ struct kprobe *p;
/*
- * We don't want to be preempted for the entire
- * duration of kprobe processing
+ * We want to disable preemption for the entire duration of kprobe
+ * processing. That includes the calls to the pre/post handlers
+ * and single stepping the kprobe instruction.
*/
preempt_disable();
kcb = get_kprobe_ctlblk();
+ p = get_kprobe((void *)((regs->psw.addr & PSW_ADDR_INSN) - 2));
- /* Check we're not actually recursing */
- if (kprobe_running()) {
- p = get_kprobe(addr);
- if (p) {
- if (kcb->kprobe_status == KPROBE_HIT_SS &&
- *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
- regs->psw.mask &= ~PSW_MASK_PER;
- regs->psw.mask |= kcb->kprobe_saved_imask;
- goto no_kprobe;
- }
- /* We have reentered the kprobe_handler(), since
- * another probe was hit while within the handler.
- * We here save the original kprobes variables and
- * just single step on the instruction of the new probe
- * without calling any user handlers.
+ if (p) {
+ if (kprobe_running()) {
+ /*
+ * We have hit a kprobe while another is still
+ * active. This can happen in the pre and post
+ * handler. Single step the instruction of the
+ * new probe but do not call any handler function
+ * of this secondary kprobe.
+ * push_kprobe and pop_kprobe saves and restores
+ * the currently active kprobe.
*/
- save_previous_kprobe(kcb);
- set_current_kprobe(p, regs, kcb);
- kprobes_inc_nmissed_count(p);
- prepare_singlestep(p, regs);
+ kprobe_reenter_check(kcb, p);
+ push_kprobe(kcb, p);
kcb->kprobe_status = KPROBE_REENTER;
- return 1;
} else {
- p = __get_cpu_var(current_kprobe);
- if (p->break_handler && p->break_handler(p, regs)) {
- goto ss_probe;
- }
+ /*
+ * If we have no pre-handler or it returned 0, we
+ * continue with single stepping. If we have a
+ * pre-handler and it returned non-zero, it prepped
+ * for calling the break_handler below on re-entry
+ * for jprobe processing, so get out doing nothing
+ * more here.
+ */
+ push_kprobe(kcb, p);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ if (p->pre_handler && p->pre_handler(p, regs))
+ return 1;
+ kcb->kprobe_status = KPROBE_HIT_SS;
}
- goto no_kprobe;
- }
-
- p = get_kprobe(addr);
- if (!p)
- /*
- * No kprobe at this address. The fault has not been
- * caused by a kprobe breakpoint. The race of breakpoint
- * vs. kprobe remove does not exist because on s390 we
- * use stop_machine to arm/disarm the breakpoints.
- */
- goto no_kprobe;
-
- kcb->kprobe_status = KPROBE_HIT_ACTIVE;
- set_current_kprobe(p, regs, kcb);
- if (p->pre_handler && p->pre_handler(p, regs))
- /* handler has already set things up, so skip ss setup */
+ enable_singlestep(kcb, regs, (unsigned long) p->ainsn.insn);
return 1;
-
-ss_probe:
- prepare_singlestep(p, regs);
- kcb->kprobe_status = KPROBE_HIT_SS;
- return 1;
-
-no_kprobe:
+ } else if (kprobe_running()) {
+ p = __get_cpu_var(current_kprobe);
+ if (p->break_handler && p->break_handler(p, regs)) {
+ /*
+ * Continuation after the jprobe completed and
+ * caused the jprobe_return trap. The jprobe
+ * break_handler "returns" to the original
+ * function that still has the kprobe breakpoint
+ * installed. We continue with single stepping.
+ */
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ enable_singlestep(kcb, regs,
+ (unsigned long) p->ainsn.insn);
+ return 1;
+ } /* else:
+ * No kprobe at this address and the current kprobe
+ * has no break handler (no jprobe!). The kernel just
+ * exploded, let the standard trap handler pick up the
+ * pieces.
+ */
+ } /* else:
+ * No kprobe at this address and no active kprobe. The trap has
+ * not been caused by a kprobe breakpoint. The race of breakpoint
+ * vs. kprobe remove does not exist because on s390 as we use
+ * stop_machine to arm/disarm the breakpoints.
+ */
preempt_enable_no_resched();
- return ret;
+ return 0;
}
/*
@@ -344,12 +352,12 @@ static void __used kretprobe_trampoline_holder(void)
static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri = NULL;
+ struct kretprobe_instance *ri;
struct hlist_head *head, empty_rp;
struct hlist_node *node, *tmp;
- unsigned long flags, orig_ret_address = 0;
- unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
- kprobe_opcode_t *correct_ret_addr = NULL;
+ unsigned long flags, orig_ret_address;
+ unsigned long trampoline_address;
+ kprobe_opcode_t *correct_ret_addr;
INIT_HLIST_HEAD(&empty_rp);
kretprobe_hash_lock(current, &head, &flags);
@@ -367,12 +375,16 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
* real return address, and all the rest will point to
* kretprobe_trampoline
*/
+ ri = NULL;
+ orig_ret_address = 0;
+ correct_ret_addr = NULL;
+ trampoline_address = (unsigned long) &kretprobe_trampoline;
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
if (ri->task != current)
/* another task is sharing our hash bucket */
continue;
- orig_ret_address = (unsigned long)ri->ret_addr;
+ orig_ret_address = (unsigned long) ri->ret_addr;
if (orig_ret_address != trampoline_address)
/*
@@ -391,7 +403,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
/* another task is sharing our hash bucket */
continue;
- orig_ret_address = (unsigned long)ri->ret_addr;
+ orig_ret_address = (unsigned long) ri->ret_addr;
if (ri->rp && ri->rp->handler) {
ri->ret_addr = correct_ret_addr;
@@ -400,19 +412,18 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
recycle_rp_inst(ri, &empty_rp);
- if (orig_ret_address != trampoline_address) {
+ if (orig_ret_address != trampoline_address)
/*
* This is the real return address. Any other
* instances associated with this task are for
* other calls deeper on the call stack
*/
break;
- }
}
regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
- reset_current_kprobe();
+ pop_kprobe(get_kprobe_ctlblk());
kretprobe_hash_unlock(current, &flags);
preempt_enable_no_resched();
@@ -439,55 +450,42 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long ip = regs->psw.addr & PSW_ADDR_INSN;
+ int fixup = get_fixup_type(p->ainsn.insn);
- regs->psw.addr &= PSW_ADDR_INSN;
-
- if (p->ainsn.fixup & FIXUP_PSW_NORMAL)
- regs->psw.addr = (unsigned long)p->addr +
- ((unsigned long)regs->psw.addr -
- (unsigned long)p->ainsn.insn);
+ if (fixup & FIXUP_PSW_NORMAL)
+ ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn;
- if (p->ainsn.fixup & FIXUP_BRANCH_NOT_TAKEN)
- if ((unsigned long)regs->psw.addr -
- (unsigned long)p->ainsn.insn == p->ainsn.ilen)
- regs->psw.addr = (unsigned long)p->addr + p->ainsn.ilen;
+ if (fixup & FIXUP_BRANCH_NOT_TAKEN) {
+ int ilen = ((p->ainsn.insn[0] >> 14) + 3) & -2;
+ if (ip - (unsigned long) p->ainsn.insn == ilen)
+ ip = (unsigned long) p->addr + ilen;
+ }
- if (p->ainsn.fixup & FIXUP_RETURN_REGISTER)
- regs->gprs[p->ainsn.reg] = ((unsigned long)p->addr +
- (regs->gprs[p->ainsn.reg] -
- (unsigned long)p->ainsn.insn))
- | PSW_ADDR_AMODE;
+ if (fixup & FIXUP_RETURN_REGISTER) {
+ int reg = (p->ainsn.insn[0] & 0xf0) >> 4;
+ regs->gprs[reg] += (unsigned long) p->addr -
+ (unsigned long) p->ainsn.insn;
+ }
- regs->psw.addr |= PSW_ADDR_AMODE;
- /* turn off PER mode */
- regs->psw.mask &= ~PSW_MASK_PER;
- /* Restore the original per control regs */
- __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
- regs->psw.mask |= kcb->kprobe_saved_imask;
+ disable_singlestep(kcb, regs, ip);
}
static int __kprobes post_kprobe_handler(struct pt_regs *regs)
{
- struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ struct kprobe *p = kprobe_running();
- if (!cur)
+ if (!p)
return 0;
- if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) {
kcb->kprobe_status = KPROBE_HIT_SSDONE;
- cur->post_handler(cur, regs, 0);
+ p->post_handler(p, regs, 0);
}
- resume_execution(cur, regs);
-
- /*Restore back the original saved kprobes variables and continue. */
- if (kcb->kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe(kcb);
- goto out;
- }
- reset_current_kprobe();
-out:
+ resume_execution(p, regs);
+ pop_kprobe(kcb);
preempt_enable_no_resched();
/*
@@ -495,17 +493,16 @@ out:
* will have PER set, in which case, continue the remaining processing
* of do_single_step, as if this is not a probe hit.
*/
- if (regs->psw.mask & PSW_MASK_PER) {
+ if (regs->psw.mask & PSW_MASK_PER)
return 0;
- }
return 1;
}
static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
{
- struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ struct kprobe *p = kprobe_running();
const struct exception_table_entry *entry;
switch(kcb->kprobe_status) {
@@ -521,14 +518,8 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* and allow the page fault handler to continue as a
* normal page fault.
*/
- regs->psw.addr = (unsigned long)cur->addr | PSW_ADDR_AMODE;
- regs->psw.mask &= ~PSW_MASK_PER;
- regs->psw.mask |= kcb->kprobe_saved_imask;
- if (kcb->kprobe_status == KPROBE_REENTER)
- restore_previous_kprobe(kcb);
- else {
- reset_current_kprobe();
- }
+ disable_singlestep(kcb, regs, (unsigned long) p->addr);
+ pop_kprobe(kcb);
preempt_enable_no_resched();
break;
case KPROBE_HIT_ACTIVE:
@@ -538,7 +529,7 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* we can also use npre/npostfault count for accouting
* these specific fault cases.
*/
- kprobes_inc_nmissed_count(cur);
+ kprobes_inc_nmissed_count(p);
/*
* We come here because instructions in the pre/post
@@ -547,7 +538,7 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* copy_from_user(), get_user() etc. Let the
* user-specified handler try to fix it first.
*/
- if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+ if (p->fault_handler && p->fault_handler(p, regs, trapnr))
return 1;
/*
@@ -589,7 +580,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
- struct die_args *args = (struct die_args *)data;
+ struct die_args *args = (struct die_args *) data;
struct pt_regs *regs = args->regs;
int ret = NOTIFY_DONE;
@@ -598,16 +589,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
switch (val) {
case DIE_BPT:
- if (kprobe_handler(args->regs))
+ if (kprobe_handler(regs))
ret = NOTIFY_STOP;
break;
case DIE_SSTEP:
- if (post_kprobe_handler(args->regs))
+ if (post_kprobe_handler(regs))
ret = NOTIFY_STOP;
break;
case DIE_TRAP:
if (!preemptible() && kprobe_running() &&
- kprobe_trap_handler(args->regs, args->trapnr))
+ kprobe_trap_handler(regs, args->trapnr))
ret = NOTIFY_STOP;
break;
default:
@@ -623,23 +614,19 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
- unsigned long addr;
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long stack;
memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
/* setup return addr to the jprobe handler routine */
- regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
+ regs->psw.addr = (unsigned long) jp->entry | PSW_ADDR_AMODE;
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
- /* r14 is the function return address */
- kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
/* r15 is the stack pointer */
- kcb->jprobe_saved_r15 = (unsigned long)regs->gprs[15];
- addr = (unsigned long)kcb->jprobe_saved_r15;
+ stack = (unsigned long) regs->gprs[15];
- memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
- MIN_STACK_SIZE(addr));
+ memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
return 1;
}
@@ -656,30 +643,29 @@ void __kprobes jprobe_return_end(void)
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_r15);
+ unsigned long stack;
+
+ stack = (unsigned long) kcb->jprobe_saved_regs.gprs[15];
/* Put the regs back */
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
/* put the stack back */
- memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
- MIN_STACK_SIZE(stack_addr));
+ memcpy((void *) stack, kcb->jprobes_stack, MIN_STACK_SIZE(stack));
preempt_enable_no_resched();
return 1;
}
-static struct kprobe trampoline_p = {
- .addr = (kprobe_opcode_t *) & kretprobe_trampoline,
+static struct kprobe trampoline = {
+ .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
.pre_handler = trampoline_probe_handler
};
int __init arch_init_kprobes(void)
{
- return register_kprobe(&trampoline_p);
+ return register_kprobe(&trampoline);
}
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
{
- if (p->addr == (kprobe_opcode_t *) & kretprobe_trampoline)
- return 1;
- return 0;
+ return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline;
}
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index dfe015d7398c..1e6a55795628 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -7,6 +7,8 @@
#include <asm/asm-offsets.h>
+ .section .kprobes.text, "ax"
+
.globl ftrace_stub
ftrace_stub:
br %r14
@@ -16,22 +18,12 @@ _mcount:
#ifdef CONFIG_DYNAMIC_FTRACE
br %r14
- .data
- .globl ftrace_dyn_func
-ftrace_dyn_func:
- .long ftrace_stub
- .previous
-
.globl ftrace_caller
ftrace_caller:
#endif
stm %r2,%r5,16(%r15)
bras %r1,2f
-#ifdef CONFIG_DYNAMIC_FTRACE
-0: .long ftrace_dyn_func
-#else
0: .long ftrace_trace_function
-#endif
1: .long function_trace_stop
2: l %r2,1b-0b(%r1)
icm %r2,0xf,0(%r2)
@@ -47,21 +39,15 @@ ftrace_caller:
l %r14,0(%r14)
basr %r14,%r14
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-#ifdef CONFIG_DYNAMIC_FTRACE
+ l %r2,100(%r15)
+ l %r3,152(%r15)
.globl ftrace_graph_caller
ftrace_graph_caller:
- # This unconditional branch gets runtime patched. Change only if
- # you know what you are doing. See ftrace_enable_graph_caller().
- j 1f
-#endif
- bras %r1,0f
- .long prepare_ftrace_return
-0: l %r2,152(%r15)
- l %r4,0(%r1)
- l %r3,100(%r15)
- basr %r14,%r4
- st %r2,100(%r15)
-1:
+# The bras instruction gets runtime patched to call prepare_ftrace_return.
+# See ftrace_enable_ftrace_graph_caller. The patched instruction is:
+# bras %r14,prepare_ftrace_return
+ bras %r14,0f
+0: st %r2,100(%r15)
#endif
ahi %r15,96
l %r14,56(%r15)
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S
index c37211c6092b..e73667286ac0 100644
--- a/arch/s390/kernel/mcount64.S
+++ b/arch/s390/kernel/mcount64.S
@@ -7,6 +7,8 @@
#include <asm/asm-offsets.h>
+ .section .kprobes.text, "ax"
+
.globl ftrace_stub
ftrace_stub:
br %r14
@@ -16,12 +18,6 @@ _mcount:
#ifdef CONFIG_DYNAMIC_FTRACE
br %r14
- .data
- .globl ftrace_dyn_func
-ftrace_dyn_func:
- .quad ftrace_stub
- .previous
-
.globl ftrace_caller
ftrace_caller:
#endif
@@ -35,26 +31,19 @@ ftrace_caller:
stg %r1,__SF_BACKCHAIN(%r15)
lgr %r2,%r14
lg %r3,168(%r15)
-#ifdef CONFIG_DYNAMIC_FTRACE
- larl %r14,ftrace_dyn_func
-#else
larl %r14,ftrace_trace_function
-#endif
lg %r14,0(%r14)
basr %r14,%r14
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-#ifdef CONFIG_DYNAMIC_FTRACE
+ lg %r2,168(%r15)
+ lg %r3,272(%r15)
.globl ftrace_graph_caller
ftrace_graph_caller:
- # This unconditional branch gets runtime patched. Change only if
- # you know what you are doing. See ftrace_enable_graph_caller().
- j 0f
-#endif
- lg %r2,272(%r15)
- lg %r3,168(%r15)
- brasl %r14,prepare_ftrace_return
- stg %r2,168(%r15)
-0:
+# The bras instruction gets runtime patched to call prepare_ftrace_return.
+# See ftrace_enable_ftrace_graph_caller. The patched instruction is:
+# bras %r14,prepare_ftrace_return
+ bras %r14,0f
+0: stg %r2,168(%r15)
#endif
aghi %r15,160
lmg %r2,%r5,32(%r15)
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 1995c1712fc8..fab88431a06f 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -8,6 +8,7 @@
* Heiko Carstens <heiko.carstens@de.ibm.com>,
*/
+#include <linux/kernel_stat.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
@@ -255,7 +256,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
nmi_enter();
s390_idle_check(regs, S390_lowcore.mcck_clock,
S390_lowcore.mcck_enter_timer);
-
+ kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++;
mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
mcck = &__get_cpu_var(cpu_mcck);
umode = user_mode(regs);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index ec2e03b22ead..6ba42222b542 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -32,6 +32,7 @@
#include <linux/kernel_stat.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
+#include <linux/kprobes.h>
#include <asm/compat.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -41,6 +42,7 @@
#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/nmi.h>
+#include <asm/smp.h>
#include "entry.h"
asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -75,13 +77,8 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
*/
static void default_idle(void)
{
- /* CPU is going idle. */
-#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_is_offline(smp_processor_id())) {
- preempt_enable_no_resched();
+ if (cpu_is_offline(smp_processor_id()))
cpu_die();
- }
-#endif
local_irq_disable();
if (need_resched()) {
local_irq_enable();
@@ -116,15 +113,17 @@ void cpu_idle(void)
}
}
-extern void kernel_thread_starter(void);
+extern void __kprobes kernel_thread_starter(void);
asm(
- ".align 4\n"
+ ".section .kprobes.text, \"ax\"\n"
+ ".global kernel_thread_starter\n"
"kernel_thread_starter:\n"
" la 2,0(10)\n"
" basr 14,9\n"
" la 2,0\n"
- " br 11\n");
+ " br 11\n"
+ ".previous\n");
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
@@ -214,8 +213,10 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
/* start new process with ar4 pointing to the correct address space */
p->thread.mm_segment = get_fs();
/* Don't copy debug registers */
- memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
+ memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
+ memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(p, TIF_PER_TRAP);
/* Initialize per thread user and system timer values */
ti = task_thread_info(p);
ti->user_timer = 0;
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 644548e615c6..311e9d712888 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -13,7 +13,7 @@
#include <linux/smp.h>
#include <linux/seq_file.h>
#include <linux/delay.h>
-
+#include <linux/cpu.h>
#include <asm/elf.h>
#include <asm/lowcore.h>
#include <asm/param.h>
@@ -35,17 +35,6 @@ void __cpuinit cpu_init(void)
}
/*
- * print_cpu_info - print basic information about a cpu
- */
-void __cpuinit print_cpu_info(void)
-{
- struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
-
- pr_info("Processor %d started, address %d, identification %06X\n",
- S390_lowcore.cpu_nr, stap(), id->ident);
-}
-
-/*
* show_cpuinfo - Get information on one CPU for use by procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
@@ -57,9 +46,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
unsigned long n = (unsigned long) v - 1;
int i;
- s390_adjust_jiffies();
- preempt_disable();
if (!n) {
+ s390_adjust_jiffies();
seq_printf(m, "vendor_id : IBM/S390\n"
"# processors : %i\n"
"bogomips per cpu: %lu.%02lu\n",
@@ -71,7 +59,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "%s ", hwcap_str[i]);
seq_puts(m, "\n");
}
-
+ get_online_cpus();
if (cpu_online(n)) {
struct cpuid *id = &per_cpu(cpu_id, n);
seq_printf(m, "processor %li: "
@@ -80,7 +68,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"machine = %04X\n",
n, id->version, id->ident, id->machine);
}
- preempt_enable();
+ put_online_cpus();
return 0;
}
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 019bb714db49..ef86ad243986 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -1,25 +1,9 @@
/*
- * arch/s390/kernel/ptrace.c
+ * Ptrace user space interface.
*
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ * Copyright IBM Corp. 1999,2010
+ * Author(s): Denis Joseph Barrow
* Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * Based on PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/m68k/kernel/ptrace.c"
- * Copyright (C) 1994 by Hamish Macdonald
- * Taken from linux/kernel/ptrace.c and modified for M680x0.
- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- *
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- *
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file README.legal in the main directory of
- * this archive for more details.
*/
#include <linux/kernel.h>
@@ -61,76 +45,58 @@ enum s390_regset {
REGSET_GENERAL_EXTENDED,
};
-static void
-FixPerRegisters(struct task_struct *task)
+void update_per_regs(struct task_struct *task)
{
- struct pt_regs *regs;
- per_struct *per_info;
- per_cr_words cr_words;
-
- regs = task_pt_regs(task);
- per_info = (per_struct *) &task->thread.per_info;
- per_info->control_regs.bits.em_instruction_fetch =
- per_info->single_step | per_info->instruction_fetch;
-
- if (per_info->single_step) {
- per_info->control_regs.bits.starting_addr = 0;
-#ifdef CONFIG_COMPAT
- if (is_compat_task())
- per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
- else
-#endif
- per_info->control_regs.bits.ending_addr = PSW_ADDR_INSN;
- } else {
- per_info->control_regs.bits.starting_addr =
- per_info->starting_addr;
- per_info->control_regs.bits.ending_addr =
- per_info->ending_addr;
- }
- /*
- * if any of the control reg tracing bits are on
- * we switch on per in the psw
- */
- if (per_info->control_regs.words.cr[0] & PER_EM_MASK)
- regs->psw.mask |= PSW_MASK_PER;
- else
+ static const struct per_regs per_single_step = {
+ .control = PER_EVENT_IFETCH,
+ .start = 0,
+ .end = PSW_ADDR_INSN,
+ };
+ struct pt_regs *regs = task_pt_regs(task);
+ struct thread_struct *thread = &task->thread;
+ const struct per_regs *new;
+ struct per_regs old;
+
+ /* TIF_SINGLE_STEP overrides the user specified PER registers. */
+ new = test_tsk_thread_flag(task, TIF_SINGLE_STEP) ?
+ &per_single_step : &thread->per_user;
+
+ /* Take care of the PER enablement bit in the PSW. */
+ if (!(new->control & PER_EVENT_MASK)) {
regs->psw.mask &= ~PSW_MASK_PER;
-
- if (per_info->control_regs.bits.em_storage_alteration)
- per_info->control_regs.bits.storage_alt_space_ctl = 1;
- else
- per_info->control_regs.bits.storage_alt_space_ctl = 0;
-
- if (task == current) {
- __ctl_store(cr_words, 9, 11);
- if (memcmp(&cr_words, &per_info->control_regs.words,
- sizeof(cr_words)) != 0)
- __ctl_load(per_info->control_regs.words, 9, 11);
+ return;
}
+ regs->psw.mask |= PSW_MASK_PER;
+ __ctl_store(old, 9, 11);
+ if (memcmp(new, &old, sizeof(struct per_regs)) != 0)
+ __ctl_load(*new, 9, 11);
}
void user_enable_single_step(struct task_struct *task)
{
- task->thread.per_info.single_step = 1;
- FixPerRegisters(task);
+ set_tsk_thread_flag(task, TIF_SINGLE_STEP);
+ if (task == current)
+ update_per_regs(task);
}
void user_disable_single_step(struct task_struct *task)
{
- task->thread.per_info.single_step = 0;
- FixPerRegisters(task);
+ clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
+ if (task == current)
+ update_per_regs(task);
}
/*
* Called by kernel/ptrace.c when detaching..
*
- * Make sure single step bits etc are not set.
+ * Clear all debugging related fields.
*/
-void
-ptrace_disable(struct task_struct *child)
+void ptrace_disable(struct task_struct *task)
{
- /* make sure the single step bit is not set. */
- user_disable_single_step(child);
+ memset(&task->thread.per_user, 0, sizeof(task->thread.per_user));
+ memset(&task->thread.per_event, 0, sizeof(task->thread.per_event));
+ clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(task, TIF_PER_TRAP);
}
#ifndef CONFIG_64BIT
@@ -139,6 +105,47 @@ ptrace_disable(struct task_struct *child)
# define __ADDR_MASK 7
#endif
+static inline unsigned long __peek_user_per(struct task_struct *child,
+ addr_t addr)
+{
+ struct per_struct_kernel *dummy = NULL;
+
+ if (addr == (addr_t) &dummy->cr9)
+ /* Control bits of the active per set. */
+ return test_thread_flag(TIF_SINGLE_STEP) ?
+ PER_EVENT_IFETCH : child->thread.per_user.control;
+ else if (addr == (addr_t) &dummy->cr10)
+ /* Start address of the active per set. */
+ return test_thread_flag(TIF_SINGLE_STEP) ?
+ 0 : child->thread.per_user.start;
+ else if (addr == (addr_t) &dummy->cr11)
+ /* End address of the active per set. */
+ return test_thread_flag(TIF_SINGLE_STEP) ?
+ PSW_ADDR_INSN : child->thread.per_user.end;
+ else if (addr == (addr_t) &dummy->bits)
+ /* Single-step bit. */
+ return test_thread_flag(TIF_SINGLE_STEP) ?
+ (1UL << (BITS_PER_LONG - 1)) : 0;
+ else if (addr == (addr_t) &dummy->starting_addr)
+ /* Start address of the user specified per set. */
+ return child->thread.per_user.start;
+ else if (addr == (addr_t) &dummy->ending_addr)
+ /* End address of the user specified per set. */
+ return child->thread.per_user.end;
+ else if (addr == (addr_t) &dummy->perc_atmid)
+ /* PER code, ATMID and AI of the last PER trap */
+ return (unsigned long)
+ child->thread.per_event.cause << (BITS_PER_LONG - 16);
+ else if (addr == (addr_t) &dummy->address)
+ /* Address of the last PER trap */
+ return child->thread.per_event.address;
+ else if (addr == (addr_t) &dummy->access_id)
+ /* Access id of the last PER trap */
+ return (unsigned long)
+ child->thread.per_event.paid << (BITS_PER_LONG - 8);
+ return 0;
+}
+
/*
* Read the word at offset addr from the user area of a process. The
* trouble here is that the information is littered over different
@@ -204,10 +211,10 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
/*
- * per_info is found in the thread structure
+ * Handle access to the per_info structure.
*/
- offset = addr - (addr_t) &dummy->regs.per_info;
- tmp = *(addr_t *)((addr_t) &child->thread.per_info + offset);
+ addr -= (addr_t) &dummy->regs.per_info;
+ tmp = __peek_user_per(child, addr);
} else
tmp = 0;
@@ -237,6 +244,35 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
return put_user(tmp, (addr_t __user *) data);
}
+static inline void __poke_user_per(struct task_struct *child,
+ addr_t addr, addr_t data)
+{
+ struct per_struct_kernel *dummy = NULL;
+
+ /*
+ * There are only three fields in the per_info struct that the
+ * debugger user can write to.
+ * 1) cr9: the debugger wants to set a new PER event mask
+ * 2) starting_addr: the debugger wants to set a new starting
+ * address to use with the PER event mask.
+ * 3) ending_addr: the debugger wants to set a new ending
+ * address to use with the PER event mask.
+ * The user specified PER event mask and the start and end
+ * addresses are used only if single stepping is not in effect.
+ * Writes to any other field in per_info are ignored.
+ */
+ if (addr == (addr_t) &dummy->cr9)
+ /* PER event mask of the user specified per set. */
+ child->thread.per_user.control =
+ data & (PER_EVENT_MASK | PER_CONTROL_MASK);
+ else if (addr == (addr_t) &dummy->starting_addr)
+ /* Starting address of the user specified per set. */
+ child->thread.per_user.start = data;
+ else if (addr == (addr_t) &dummy->ending_addr)
+ /* Ending address of the user specified per set. */
+ child->thread.per_user.end = data;
+}
+
/*
* Write a word to the user area of a process at location addr. This
* operation does have an additional problem compared to peek_user.
@@ -311,19 +347,17 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
/*
- * per_info is found in the thread structure
+ * Handle access to the per_info structure.
*/
- offset = addr - (addr_t) &dummy->regs.per_info;
- *(addr_t *)((addr_t) &child->thread.per_info + offset) = data;
+ addr -= (addr_t) &dummy->regs.per_info;
+ __poke_user_per(child, addr, data);
}
- FixPerRegisters(child);
return 0;
}
-static int
-poke_user(struct task_struct *child, addr_t addr, addr_t data)
+static int poke_user(struct task_struct *child, addr_t addr, addr_t data)
{
addr_t mask;
@@ -410,12 +444,53 @@ long arch_ptrace(struct task_struct *child, long request,
*/
/*
+ * Same as peek_user_per but for a 31 bit program.
+ */
+static inline __u32 __peek_user_per_compat(struct task_struct *child,
+ addr_t addr)
+{
+ struct compat_per_struct_kernel *dummy32 = NULL;
+
+ if (addr == (addr_t) &dummy32->cr9)
+ /* Control bits of the active per set. */
+ return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
+ PER_EVENT_IFETCH : child->thread.per_user.control;
+ else if (addr == (addr_t) &dummy32->cr10)
+ /* Start address of the active per set. */
+ return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
+ 0 : child->thread.per_user.start;
+ else if (addr == (addr_t) &dummy32->cr11)
+ /* End address of the active per set. */
+ return test_thread_flag(TIF_SINGLE_STEP) ?
+ PSW32_ADDR_INSN : child->thread.per_user.end;
+ else if (addr == (addr_t) &dummy32->bits)
+ /* Single-step bit. */
+ return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
+ 0x80000000 : 0;
+ else if (addr == (addr_t) &dummy32->starting_addr)
+ /* Start address of the user specified per set. */
+ return (__u32) child->thread.per_user.start;
+ else if (addr == (addr_t) &dummy32->ending_addr)
+ /* End address of the user specified per set. */
+ return (__u32) child->thread.per_user.end;
+ else if (addr == (addr_t) &dummy32->perc_atmid)
+ /* PER code, ATMID and AI of the last PER trap */
+ return (__u32) child->thread.per_event.cause << 16;
+ else if (addr == (addr_t) &dummy32->address)
+ /* Address of the last PER trap */
+ return (__u32) child->thread.per_event.address;
+ else if (addr == (addr_t) &dummy32->access_id)
+ /* Access id of the last PER trap */
+ return (__u32) child->thread.per_event.paid << 24;
+ return 0;
+}
+
+/*
* Same as peek_user but for a 31 bit program.
*/
static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
{
- struct user32 *dummy32 = NULL;
- per_struct32 *dummy_per32 = NULL;
+ struct compat_user *dummy32 = NULL;
addr_t offset;
__u32 tmp;
@@ -465,19 +540,10 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
/*
- * per_info is found in the thread structure
+ * Handle access to the per_info structure.
*/
- offset = addr - (addr_t) &dummy32->regs.per_info;
- /* This is magic. See per_struct and per_struct32. */
- if ((offset >= (addr_t) &dummy_per32->control_regs &&
- offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
- (offset >= (addr_t) &dummy_per32->starting_addr &&
- offset <= (addr_t) &dummy_per32->ending_addr) ||
- offset == (addr_t) &dummy_per32->lowcore.words.address)
- offset = offset*2 + 4;
- else
- offset = offset*2;
- tmp = *(__u32 *)((addr_t) &child->thread.per_info + offset);
+ addr -= (addr_t) &dummy32->regs.per_info;
+ tmp = __peek_user_per_compat(child, addr);
} else
tmp = 0;
@@ -498,13 +564,32 @@ static int peek_user_compat(struct task_struct *child,
}
/*
+ * Same as poke_user_per but for a 31 bit program.
+ */
+static inline void __poke_user_per_compat(struct task_struct *child,
+ addr_t addr, __u32 data)
+{
+ struct compat_per_struct_kernel *dummy32 = NULL;
+
+ if (addr == (addr_t) &dummy32->cr9)
+ /* PER event mask of the user specified per set. */
+ child->thread.per_user.control =
+ data & (PER_EVENT_MASK | PER_CONTROL_MASK);
+ else if (addr == (addr_t) &dummy32->starting_addr)
+ /* Starting address of the user specified per set. */
+ child->thread.per_user.start = data;
+ else if (addr == (addr_t) &dummy32->ending_addr)
+ /* Ending address of the user specified per set. */
+ child->thread.per_user.end = data;
+}
+
+/*
* Same as poke_user but for a 31 bit program.
*/
static int __poke_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
- struct user32 *dummy32 = NULL;
- per_struct32 *dummy_per32 = NULL;
+ struct compat_user *dummy32 = NULL;
__u32 tmp = (__u32) data;
addr_t offset;
@@ -561,37 +646,20 @@ static int __poke_user_compat(struct task_struct *child,
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
/*
- * per_info is found in the thread structure.
- */
- offset = addr - (addr_t) &dummy32->regs.per_info;
- /*
- * This is magic. See per_struct and per_struct32.
- * By incident the offsets in per_struct are exactly
- * twice the offsets in per_struct32 for all fields.
- * The 8 byte fields need special handling though,
- * because the second half (bytes 4-7) is needed and
- * not the first half.
+ * Handle access to the per_info structure.
*/
- if ((offset >= (addr_t) &dummy_per32->control_regs &&
- offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
- (offset >= (addr_t) &dummy_per32->starting_addr &&
- offset <= (addr_t) &dummy_per32->ending_addr) ||
- offset == (addr_t) &dummy_per32->lowcore.words.address)
- offset = offset*2 + 4;
- else
- offset = offset*2;
- *(__u32 *)((addr_t) &child->thread.per_info + offset) = tmp;
-
+ addr -= (addr_t) &dummy32->regs.per_info;
+ __poke_user_per_compat(child, addr, data);
}
- FixPerRegisters(child);
return 0;
}
static int poke_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
- if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user32) - 3)
+ if (!is_compat_task() || (addr & 3) ||
+ addr > sizeof(struct compat_user) - 3)
return -EIO;
return __poke_user_compat(child, addr, data);
@@ -602,7 +670,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
{
unsigned long addr = caddr;
unsigned long data = cdata;
- ptrace_area_emu31 parea;
+ compat_ptrace_area parea;
int copied, ret;
switch (request) {
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index bd1db508e8af..185029919c4d 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -1,33 +1,36 @@
/*
- * arch/s390/kernel/s390_ext.c
- *
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com),
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
+ * Copyright IBM Corp. 1999,2010
+ * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
*/
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/ftrace.h>
#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/interrupt.h>
-#include <asm/cputime.h>
-#include <asm/lowcore.h>
+#include <linux/slab.h>
#include <asm/s390_ext.h>
#include <asm/irq_regs.h>
+#include <asm/cputime.h>
+#include <asm/lowcore.h>
#include <asm/irq.h>
#include "entry.h"
+struct ext_int_info {
+ struct ext_int_info *next;
+ ext_int_handler_t handler;
+ __u16 code;
+};
+
/*
* ext_int_hash[index] is the start of the list for all external interrupts
* that hash to this index. With the current set of external interrupts
* (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
* iucv and 0x2603 pfault) this is always the first element.
*/
-ext_int_info_t *ext_int_hash[256] = { NULL, };
+static struct ext_int_info *ext_int_hash[256];
static inline int ext_hash(__u16 code)
{
@@ -36,90 +39,53 @@ static inline int ext_hash(__u16 code)
int register_external_interrupt(__u16 code, ext_int_handler_t handler)
{
- ext_int_info_t *p;
- int index;
-
- p = kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
- if (p == NULL)
- return -ENOMEM;
- p->code = code;
- p->handler = handler;
- index = ext_hash(code);
- p->next = ext_int_hash[index];
- ext_int_hash[index] = p;
- return 0;
-}
-
-int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
- ext_int_info_t *p)
-{
- int index;
+ struct ext_int_info *p;
+ int index;
- if (p == NULL)
- return -EINVAL;
- p->code = code;
- p->handler = handler;
+ p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ if (!p)
+ return -ENOMEM;
+ p->code = code;
+ p->handler = handler;
index = ext_hash(code);
- p->next = ext_int_hash[index];
- ext_int_hash[index] = p;
- return 0;
+ p->next = ext_int_hash[index];
+ ext_int_hash[index] = p;
+ return 0;
}
+EXPORT_SYMBOL(register_external_interrupt);
int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
{
- ext_int_info_t *p, *q;
- int index;
-
- index = ext_hash(code);
- q = NULL;
- p = ext_int_hash[index];
- while (p != NULL) {
- if (p->code == code && p->handler == handler)
- break;
- q = p;
- p = p->next;
- }
- if (p == NULL)
- return -ENOENT;
- if (q != NULL)
- q->next = p->next;
- else
- ext_int_hash[index] = p->next;
- kfree(p);
- return 0;
-}
-
-int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
- ext_int_info_t *p)
-{
- ext_int_info_t *q;
+ struct ext_int_info *p, *q;
int index;
- if (p == NULL || p->code != code || p->handler != handler)
- return -EINVAL;
index = ext_hash(code);
- q = ext_int_hash[index];
- if (p != q) {
- while (q != NULL) {
- if (q->next == p)
- break;
- q = q->next;
- }
- if (q == NULL)
- return -ENOENT;
+ q = NULL;
+ p = ext_int_hash[index];
+ while (p) {
+ if (p->code == code && p->handler == handler)
+ break;
+ q = p;
+ p = p->next;
+ }
+ if (!p)
+ return -ENOENT;
+ if (q)
q->next = p->next;
- } else
+ else
ext_int_hash[index] = p->next;
+ kfree(p);
return 0;
}
+EXPORT_SYMBOL(unregister_external_interrupt);
void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
unsigned int param32, unsigned long param64)
{
struct pt_regs *old_regs;
unsigned short code;
- ext_int_info_t *p;
- int index;
+ struct ext_int_info *p;
+ int index;
code = (unsigned short) ext_int_code;
old_regs = set_irq_regs(regs);
@@ -132,7 +98,7 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
if (code != 0x1004)
__get_cpu_var(s390_idle).nohz_delay = 1;
- index = ext_hash(code);
+ index = ext_hash(code);
for (p = ext_int_hash[index]; p; p = p->next) {
if (likely(p->code == code))
p->handler(ext_int_code, param32, param64);
@@ -140,6 +106,3 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
irq_exit();
set_irq_regs(old_regs);
}
-
-EXPORT_SYMBOL(register_external_interrupt);
-EXPORT_SYMBOL(unregister_external_interrupt);
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index ee7ac8b11782..abbb3c3c7aab 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -505,7 +505,7 @@ void do_signal(struct pt_regs *regs)
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler(signr, &info, &ka, regs,
- current->thread.per_info.single_step);
+ test_thread_flag(TIF_SINGLE_STEP));
}
return;
}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 94cf510b8fe1..63a97db83f96 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -23,6 +23,7 @@
#define KMSG_COMPONENT "cpu"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
@@ -161,6 +162,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
{
unsigned long bits;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++;
/*
* handle bit signal external calls
*
@@ -469,25 +471,25 @@ int __cpuinit start_secondary(void *cpuvoid)
ipi_call_unlock();
/* Switch on interrupts */
local_irq_enable();
- /* Print info about this processor */
- print_cpu_info();
/* cpu_idle will call schedule for us */
cpu_idle();
return 0;
}
-static void __init smp_create_idle(unsigned int cpu)
+struct create_idle {
+ struct work_struct work;
+ struct task_struct *idle;
+ struct completion done;
+ int cpu;
+};
+
+static void __cpuinit smp_fork_idle(struct work_struct *work)
{
- struct task_struct *p;
+ struct create_idle *c_idle;
- /*
- * don't care about the psw and regs settings since we'll never
- * reschedule the forked task.
- */
- p = fork_idle(cpu);
- if (IS_ERR(p))
- panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
- current_set[cpu] = p;
+ c_idle = container_of(work, struct create_idle, work);
+ c_idle->idle = fork_idle(c_idle->cpu);
+ complete(&c_idle->done);
}
static int __cpuinit smp_alloc_lowcore(int cpu)
@@ -551,6 +553,7 @@ static void smp_free_lowcore(int cpu)
int __cpuinit __cpu_up(unsigned int cpu)
{
struct _lowcore *cpu_lowcore;
+ struct create_idle c_idle;
struct task_struct *idle;
struct stack_frame *sf;
u32 lowcore;
@@ -558,6 +561,19 @@ int __cpuinit __cpu_up(unsigned int cpu)
if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
return -EIO;
+ idle = current_set[cpu];
+ if (!idle) {
+ c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done);
+ INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle);
+ c_idle.cpu = cpu;
+ schedule_work(&c_idle.work);
+ wait_for_completion(&c_idle.done);
+ if (IS_ERR(c_idle.idle))
+ return PTR_ERR(c_idle.idle);
+ idle = c_idle.idle;
+ current_set[cpu] = c_idle.idle;
+ }
+ init_idle(idle, cpu);
if (smp_alloc_lowcore(cpu))
return -ENOMEM;
do {
@@ -572,7 +588,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
udelay(10);
- idle = current_set[cpu];
cpu_lowcore = lowcore_ptr[cpu];
cpu_lowcore->kernel_stack = (unsigned long)
task_stack_page(idle) + THREAD_SIZE;
@@ -664,7 +679,6 @@ void __cpu_die(unsigned int cpu)
udelay(10);
smp_free_lowcore(cpu);
atomic_dec(&init_mm.context.attach_count);
- pr_info("Processor %d stopped\n", cpu);
}
void cpu_die(void)
@@ -684,14 +698,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
#endif
unsigned long async_stack, panic_stack;
struct _lowcore *lowcore;
- unsigned int cpu;
smp_detect_cpus();
/* request the 0x1201 emergency signal external interrupt */
if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
panic("Couldn't request external interrupt 0x1201");
- print_cpu_info();
/* Reallocate current lowcore, but keep its contents. */
lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
@@ -719,9 +731,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (vdso_alloc_per_cpu(smp_processor_id(), &S390_lowcore))
BUG();
#endif
- for_each_possible_cpu(cpu)
- if (cpu != smp_processor_id())
- smp_create_idle(cpu);
}
void __init smp_prepare_boot_cpu(void)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index f754a6dc4f94..9e7b039458da 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -15,6 +15,7 @@
#define KMSG_COMPONENT "time"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
@@ -37,6 +38,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/gfp.h>
+#include <linux/kprobes.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/s390_ext.h>
@@ -60,7 +62,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
/*
* Scheduler clock - returns current time in nanosec units.
*/
-unsigned long long notrace sched_clock(void)
+unsigned long long notrace __kprobes sched_clock(void)
{
return (get_clock_monotonic() * 125) >> 9;
}
@@ -159,6 +161,7 @@ static void clock_comparator_interrupt(unsigned int ext_int_code,
unsigned int param32,
unsigned long param64)
{
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++;
if (S390_lowcore.clock_comparator == -1ULL)
set_clock_comparator(S390_lowcore.clock_comparator);
}
@@ -169,6 +172,7 @@ static void stp_timing_alert(struct stp_irq_parm *);
static void timing_alert_interrupt(unsigned int ext_int_code,
unsigned int param32, unsigned long param64)
{
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++;
if (param32 & 0x00c40000)
etr_timing_alert((struct etr_irq_parm *) &param32);
if (param32 & 0x00038000)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 70640822621a..5eb78dd584ce 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -365,12 +365,10 @@ static inline void __user *get_psw_address(struct pt_regs *regs,
((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
}
-void __kprobes do_single_step(struct pt_regs *regs)
+void __kprobes do_per_trap(struct pt_regs *regs)
{
- if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0,
- SIGTRAP) == NOTIFY_STOP){
+ if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
return;
- }
if (tracehook_consider_fatal_signal(current, SIGTRAP))
force_sig(SIGTRAP, current);
}
@@ -451,8 +449,8 @@ static inline void do_fp_trap(struct pt_regs *regs, void __user *location,
"floating point exception", regs, &si);
}
-static void illegal_op(struct pt_regs *regs, long pgm_int_code,
- unsigned long trans_exc_code)
+static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
+ unsigned long trans_exc_code)
{
siginfo_t info;
__u8 opcode[6];
@@ -688,7 +686,7 @@ static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
}
-asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
+asmlinkage void __kprobes kernel_stack_overflow(struct pt_regs * regs)
{
bust_spinlocks(1);
printk("Kernel stack overflow.\n");
@@ -733,5 +731,6 @@ void __init trap_init(void)
pgm_check_table[0x15] = &operand_exception;
pgm_check_table[0x1C] = &space_switch_exception;
pgm_check_table[0x1D] = &hfp_sqrt_exception;
- pfault_irq_init();
+ /* Enable machine checks early. */
+ local_mcck_enable();
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 56c8687b29b3..1ccdf4d8aa85 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -19,6 +19,8 @@
#include <linux/kernel_stat.h>
#include <linux/rcupdate.h>
#include <linux/posix-timers.h>
+#include <linux/cpu.h>
+#include <linux/kprobes.h>
#include <asm/s390_ext.h>
#include <asm/timer.h>
@@ -121,7 +123,7 @@ void account_system_vtime(struct task_struct *tsk)
}
EXPORT_SYMBOL_GPL(account_system_vtime);
-void vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
+void __kprobes vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
{
struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
@@ -161,7 +163,7 @@ void vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
idle->sequence++;
}
-void vtime_stop_cpu(void)
+void __kprobes vtime_stop_cpu(void)
{
struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
@@ -322,6 +324,7 @@ static void do_cpu_timer_interrupt(unsigned int ext_int_code,
struct list_head cb_list; /* the callback queue */
__u64 elapsed, next;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_TMR]++;
INIT_LIST_HEAD(&cb_list);
vq = &__get_cpu_var(virt_cpu_timer);
@@ -566,6 +569,23 @@ void init_cpu_vtimer(void)
__ctl_set_bit(0,10);
}
+static int __cpuinit s390_nohz_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ struct s390_idle_data *idle;
+ long cpu = (long) hcpu;
+
+ idle = &per_cpu(s390_idle, cpu);
+ switch (action) {
+ case CPU_DYING:
+ case CPU_DYING_FROZEN:
+ idle->nohz_delay = 0;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
void __init vtime_init(void)
{
/* request the cpu timer external interrupt */
@@ -574,5 +594,6 @@ void __init vtime_init(void)
/* Enable cpu timer interrupts on the boot cpu. */
init_cpu_vtimer();
+ cpu_notifier(s390_nohz_notify, 0);
}
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index a7251580891c..f66a1bdbb61d 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -4,8 +4,8 @@
source "virt/kvm/Kconfig"
menuconfig VIRTUALIZATION
- bool "Virtualization"
- default y
+ def_bool y
+ prompt "Virtualization"
---help---
Say Y here to get to see options for using your Linux host to run other
operating systems inside virtual machines (guests).
@@ -16,7 +16,8 @@ menuconfig VIRTUALIZATION
if VIRTUALIZATION
config KVM
- tristate "Kernel-based Virtual Machine (KVM) support"
+ def_tristate y
+ prompt "Kernel-based Virtual Machine (KVM) support"
depends on HAVE_KVM && EXPERIMENTAL
select PREEMPT_NOTIFIERS
select ANON_INODES
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 985d825494f1..bade533ba288 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -164,24 +164,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
return r;
}
-struct kvm *kvm_arch_create_vm(void)
+int kvm_arch_init_vm(struct kvm *kvm)
{
- struct kvm *kvm;
int rc;
char debug_name[16];
rc = s390_enable_sie();
if (rc)
- goto out_nokvm;
-
- rc = -ENOMEM;
- kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
- if (!kvm)
- goto out_nokvm;
+ goto out_err;
kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
if (!kvm->arch.sca)
- goto out_nosca;
+ goto out_err;
sprintf(debug_name, "kvm-%u", current->pid);
@@ -195,13 +189,11 @@ struct kvm *kvm_arch_create_vm(void)
debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
VM_EVENT(kvm, 3, "%s", "vm created");
- return kvm;
+ return 0;
out_nodbf:
free_page((unsigned long)(kvm->arch.sca));
-out_nosca:
- kfree(kvm);
-out_nokvm:
- return ERR_PTR(rc);
+out_err:
+ return rc;
}
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -240,11 +232,8 @@ void kvm_arch_sync_events(struct kvm *kvm)
void kvm_arch_destroy_vm(struct kvm *kvm)
{
kvm_free_vcpus(kvm);
- kvm_free_physmem(kvm);
free_page((unsigned long)(kvm->arch.sca));
debug_unregister(kvm->arch.dbf);
- cleanup_srcu_struct(&kvm->srcu);
- kfree(kvm);
}
/* Section: vcpu related */
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 7c37ec359ec2..0f53110e1d09 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -47,7 +47,6 @@ static void __udelay_disabled(unsigned long long usecs)
lockdep_on();
__ctl_load(cr0_saved, 0, 0);
local_tick_enable(clock_saved);
- set_clock_comparator(S390_lowcore.clock_comparator);
}
static void __udelay_enabled(unsigned long long usecs)
@@ -70,7 +69,6 @@ static void __udelay_enabled(unsigned long long usecs)
if (clock_saved)
local_tick_enable(clock_saved);
} while (get_clock() < end);
- set_clock_comparator(S390_lowcore.clock_comparator);
}
/*
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fe5701e9efbf..2c57806c0858 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -10,6 +10,7 @@
* Copyright (C) 1995 Linus Torvalds
*/
+#include <linux/kernel_stat.h>
#include <linux/perf_event.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -234,13 +235,13 @@ static noinline int signal_return(struct pt_regs *regs, long int_code,
rc = __get_user(instruction, (u16 __user *) regs->psw.addr);
if (!rc && instruction == 0x0a77) {
- clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(current, TIF_PER_TRAP);
if (is_compat_task())
sys32_sigreturn();
else
sys_sigreturn();
} else if (!rc && instruction == 0x0aad) {
- clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(current, TIF_PER_TRAP);
if (is_compat_task())
sys32_rt_sigreturn();
else
@@ -378,7 +379,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
* The instruction that caused the program check will
* be repeated. Don't signal single step via SIGTRAP.
*/
- clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(tsk, TIF_PER_TRAP);
fault = 0;
out_up:
up_read(&mm->mmap_sem);
@@ -480,8 +481,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
/*
* 'pfault' pseudo page faults routines.
*/
-static ext_int_info_t ext_int_pfault;
-static int pfault_disable = 0;
+static int pfault_disable;
static int __init nopfault(char *str)
{
@@ -543,6 +543,7 @@ static void pfault_interrupt(unsigned int ext_int_code,
struct task_struct *tsk;
__u16 subcode;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
/*
* Get the external interruption subcode & pfault
* initial/completion signal bit. VM stores this
@@ -592,24 +593,28 @@ static void pfault_interrupt(unsigned int ext_int_code,
}
}
-void __init pfault_irq_init(void)
+static int __init pfault_irq_init(void)
{
- if (!MACHINE_IS_VM)
- return;
+ int rc;
+ if (!MACHINE_IS_VM)
+ return 0;
/*
* Try to get pfault pseudo page faults going.
*/
- if (register_early_external_interrupt(0x2603, pfault_interrupt,
- &ext_int_pfault) != 0)
- panic("Couldn't request external interrupt 0x2603");
-
+ rc = register_external_interrupt(0x2603, pfault_interrupt);
+ if (rc) {
+ pfault_disable = 1;
+ return rc;
+ }
if (pfault_init() == 0)
- return;
+ return 0;
/* Tough luck, no pfault. */
pfault_disable = 1;
- unregister_early_external_interrupt(0x2603, pfault_interrupt,
- &ext_int_pfault);
+ unregister_external_interrupt(0x2603, pfault_interrupt);
+ return 0;
}
+early_initcall(pfault_irq_init);
+
#endif
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 7f217b3a50a8..e9e71120040c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,7 +1,7 @@
config SUPERH
def_bool y
select EMBEDDED
- select HAVE_CLK
+ select CLKDEV_LOOKUP
select HAVE_IDE if HAS_IOPORT
select HAVE_MEMBLOCK
select HAVE_OPROFILE
@@ -22,7 +22,8 @@ config SUPERH
select HAVE_SPARSE_IRQ
select RTC_LIB
select GENERIC_ATOMIC64
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ # Support the deprecated APIs until MFD and GPIOLIB catch up.
+ select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@@ -161,7 +162,8 @@ config ARCH_HAS_CPU_IDLE_WAIT
def_bool y
config NO_IOPORT
- bool
+ def_bool !PCI
+ depends on !SH_CAYMAN && !SH_SH4202_MICRODEV
config IO_TRAPPED
bool
@@ -274,6 +276,7 @@ config CPU_SUBTYPE_SH7203
select CPU_HAS_FPU
select SYS_SUPPORTS_CMT
select SYS_SUPPORTS_MTU2
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config CPU_SUBTYPE_SH7206
bool "Support SH7206 processor"
@@ -345,6 +348,7 @@ config CPU_SUBTYPE_SH7720
select CPU_SH3
select CPU_HAS_DSP
select SYS_SUPPORTS_CMT
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Select SH7720 if you have a SH3-DSP SH7720 CPU.
@@ -407,6 +411,7 @@ config CPU_SUBTYPE_SH7723
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_CMT
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Select SH7723 if you have an SH-MobileR2 CPU.
@@ -417,6 +422,7 @@ config CPU_SUBTYPE_SH7724
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_CMT
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Select SH7724 if you have an SH-MobileR2R CPU.
@@ -424,6 +430,7 @@ config CPU_SUBTYPE_SH7757
bool "Support SH7757 processor"
select CPU_SH4A
select CPU_SHX2
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Select SH7757 if you have a SH4A SH7757 CPU.
@@ -447,6 +454,7 @@ config CPU_SUBTYPE_SH7785
select CPU_SHX2
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config CPU_SUBTYPE_SH7786
bool "Support SH7786 processor"
@@ -454,6 +462,7 @@ config CPU_SUBTYPE_SH7786
select CPU_SHX3
select CPU_HAS_PTEAEX
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config CPU_SUBTYPE_SHX3
bool "Support SH-X3 processor"
@@ -478,6 +487,7 @@ config CPU_SUBTYPE_SH7722
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_CMT
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config CPU_SUBTYPE_SH7366
bool "Support SH7366 processor"
@@ -567,15 +577,6 @@ config SH_CLK_CPG_LEGACY
def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
!CPU_SHX3 && !CPU_SUBTYPE_SH7757
-config SH_CLK_MD
- int "CPU Mode Pin Setting"
- depends on CPU_SH2
- default 6 if CPU_SUBTYPE_SH7206
- default 5 if CPU_SUBTYPE_SH7619
- default 0
- help
- MD2 - MD0 pin setting.
-
source "kernel/time/Kconfig"
endmenu
diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c
index 32f875e8493d..f968f17891a4 100644
--- a/arch/sh/boards/board-secureedge5410.c
+++ b/arch/sh/boards/board-secureedge5410.c
@@ -29,8 +29,6 @@ unsigned short secureedge5410_ioport;
*/
static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
{
- ctrl_delay(); /* dummy read */
-
printk("SnapGear: erase switch interrupt!\n");
return IRQ_HANDLED;
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 2eaeb9e59585..f48c492a68d3 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -720,32 +720,6 @@ static struct platform_device camera_devices[] = {
};
/* FSI */
-/*
- * FSI-B use external clock which came from da7210.
- * So, we should change parent of fsi
- */
-#define FCLKBCR 0xa415000c
-static void fsimck_init(struct clk *clk)
-{
- u32 status = __raw_readl(clk->enable_reg);
-
- /* use external clock */
- status &= ~0x000000ff;
- status |= 0x00000080;
-
- __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
- .init = fsimck_init,
-};
-
-static struct clk fsimckb_clk = {
- .ops = &fsimck_clk_ops,
- .enable_reg = (void __iomem *)FCLKBCR,
- .rate = 0, /* unknown */
-};
-
static struct sh_fsi_platform_info fsi_info = {
.portb_flags = SH_FSI_BRS_INV |
SH_FSI_OUT_SLAVE_MODE |
@@ -1264,10 +1238,10 @@ static int __init arch_setup(void)
/* change parent of FSI B */
clk = clk_get(NULL, "fsib_clk");
if (!IS_ERR(clk)) {
- clk_register(&fsimckb_clk);
- clk_set_parent(clk, &fsimckb_clk);
- clk_set_rate(clk, 11000);
- clk_set_rate(&fsimckb_clk, 11000);
+ /* 48kHz dummy clock was used to make sure 1/1 divide */
+ clk_set_rate(&sh7724_fsimckb_clk, 48000);
+ clk_set_parent(clk, &sh7724_fsimckb_clk);
+ clk_set_rate(clk, 48000);
clk_put(clk);
}
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index a5ecfbacaf36..87618c91d178 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -24,10 +24,10 @@
#include <linux/interrupt.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
+#include <linux/clkdev.h>
#include <net/ax88796.h>
#include <asm/machvec.h>
#include <mach/highlander.h>
-#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/heartbeat.h>
#include <asm/io.h>
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
index 4fa08ba10253..a8089f79d058 100644
--- a/arch/sh/boards/mach-rsk/devices-rsk7203.c
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -1,7 +1,7 @@
/*
* Renesas Technology Europe RSK+ 7203 Support.
*
- * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008 - 2010 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
@@ -12,7 +12,9 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/smsc911x.h>
+#include <linux/input.h>
#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <asm/machvec.h>
#include <asm/io.h>
@@ -84,9 +86,42 @@ static struct platform_device led_device = {
},
};
+static struct gpio_keys_button rsk7203_gpio_keys_table[] = {
+ {
+ .code = BTN_0,
+ .gpio = GPIO_PB0,
+ .active_low = 1,
+ .desc = "SW1",
+ }, {
+ .code = BTN_1,
+ .gpio = GPIO_PB1,
+ .active_low = 1,
+ .desc = "SW2",
+ }, {
+ .code = BTN_2,
+ .gpio = GPIO_PB2,
+ .active_low = 1,
+ .desc = "SW3",
+ },
+};
+
+static struct gpio_keys_platform_data rsk7203_gpio_keys_info = {
+ .buttons = rsk7203_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(rsk7203_gpio_keys_table),
+ .poll_interval = 50, /* default to 50ms */
+};
+
+static struct platform_device keys_device = {
+ .name = "gpio-keys-polled",
+ .dev = {
+ .platform_data = &rsk7203_gpio_keys_info,
+ },
+};
+
static struct platform_device *rsk7203_devices[] __initdata = {
&smsc911x_device,
&led_device,
+ &keys_device,
};
static int __init rsk7203_devices_setup(void)
diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile
index 23ff7d4ac491..8ae56e9560ac 100644
--- a/arch/sh/boards/mach-sdk7786/Makefile
+++ b/arch/sh/boards/mach-sdk7786/Makefile
@@ -1,4 +1,4 @@
-obj-y := fpga.o irq.o setup.o
+obj-y := fpga.o irq.o nmi.o setup.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
diff --git a/arch/sh/boards/mach-sdk7786/nmi.c b/arch/sh/boards/mach-sdk7786/nmi.c
new file mode 100644
index 000000000000..edcfa1f568ba
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/nmi.c
@@ -0,0 +1,83 @@
+/*
+ * SDK7786 FPGA NMI Support.
+ *
+ * Copyright (C) 2010 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+
+enum {
+ NMI_MODE_MANUAL,
+ NMI_MODE_AUX,
+ NMI_MODE_MASKED,
+ NMI_MODE_ANY,
+ NMI_MODE_UNKNOWN,
+};
+
+/*
+ * Default to the manual NMI switch.
+ */
+static unsigned int __initdata nmi_mode = NMI_MODE_ANY;
+
+static int __init nmi_mode_setup(char *str)
+{
+ if (!str)
+ return 0;
+
+ if (strcmp(str, "manual") == 0)
+ nmi_mode = NMI_MODE_MANUAL;
+ else if (strcmp(str, "aux") == 0)
+ nmi_mode = NMI_MODE_AUX;
+ else if (strcmp(str, "masked") == 0)
+ nmi_mode = NMI_MODE_MASKED;
+ else if (strcmp(str, "any") == 0)
+ nmi_mode = NMI_MODE_ANY;
+ else {
+ nmi_mode = NMI_MODE_UNKNOWN;
+ pr_warning("Unknown NMI mode %s\n", str);
+ }
+
+ printk("Set NMI mode to %d\n", nmi_mode);
+ return 0;
+}
+early_param("nmi_mode", nmi_mode_setup);
+
+void __init sdk7786_nmi_init(void)
+{
+ unsigned int source, mask, tmp;
+
+ switch (nmi_mode) {
+ case NMI_MODE_MANUAL:
+ source = NMISR_MAN_NMI;
+ mask = NMIMR_MAN_NMIM;
+ break;
+ case NMI_MODE_AUX:
+ source = NMISR_AUX_NMI;
+ mask = NMIMR_AUX_NMIM;
+ break;
+ case NMI_MODE_ANY:
+ source = NMISR_MAN_NMI | NMISR_AUX_NMI;
+ mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM;
+ break;
+ case NMI_MODE_MASKED:
+ case NMI_MODE_UNKNOWN:
+ default:
+ source = mask = 0;
+ break;
+ }
+
+ /* Set the NMI source */
+ tmp = fpga_read_reg(NMISR);
+ tmp &= ~NMISR_MASK;
+ tmp |= source;
+ fpga_write_reg(tmp, NMISR);
+
+ /* And the IRQ masking */
+ fpga_write_reg(NMIMR_MASK ^ mask, NMIMR);
+}
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
index 7e0c4e3878e0..75e4ddbbec3e 100644
--- a/arch/sh/boards/mach-sdk7786/setup.c
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -237,6 +237,7 @@ static void __init sdk7786_setup(char **cmdline_p)
pr_info("Renesas Technology Europe SDK7786 support:\n");
sdk7786_fpga_init();
+ sdk7786_nmi_init();
pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index d961949600fd..9070d7e60704 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void)
make_se7206_irq(IRQ1_IRQ); /* ATA */
make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
- __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */
+ __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
/* FPGA System register setup*/
__raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c
index 7f4871c71a01..33039e0dc568 100644
--- a/arch/sh/boards/mach-se/7206/setup.c
+++ b/arch/sh/boards/mach-se/7206/setup.c
@@ -79,6 +79,11 @@ static int __init se7206_devices_setup(void)
}
__initcall(se7206_devices_setup);
+static int se7206_mode_pins(void)
+{
+ return MODE_PIN1 | MODE_PIN2;
+}
+
/*
* The Machine Vector
*/
@@ -87,4 +92,5 @@ static struct sh_machine_vector mv_se __initmv = {
.mv_name = "SolutionEngine",
.mv_nr_irqs = 256,
.mv_init_irq = init_se7206_IRQ,
+ .mv_mode_pins = se7206_mode_pins,
};
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index c31d228fdfc6..b710757c33c3 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -283,31 +283,6 @@ static struct platform_device ceu1_device = {
};
/* FSI */
-/*
- * FSI-A use external clock which came from ak464x.
- * So, we should change parent of fsi
- */
-#define FCLKACR 0xa4150008
-static void fsimck_init(struct clk *clk)
-{
- u32 status = __raw_readl(clk->enable_reg);
-
- /* use external clock */
- status &= ~0x000000ff;
- status |= 0x00000080;
- __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
- .init = fsimck_init,
-};
-
-static struct clk fsimcka_clk = {
- .ops = &fsimck_clk_ops,
- .enable_reg = (void __iomem *)FCLKACR,
- .rate = 0, /* unknown */
-};
-
/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV |
@@ -343,6 +318,10 @@ static struct platform_device fsi_device = {
},
};
+static struct platform_device fsi_ak4642_device = {
+ .name = "sh_fsi_a_ak4642",
+};
+
/* KEYSC in SoC (Needs SW33-2 set to ON) */
static struct sh_keysc_info keysc_info = {
.mode = SH_KEYSC_MODE_1,
@@ -615,6 +594,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
&sh7724_usb0_host_device,
&sh7724_usb1_gadget_device,
&fsi_device,
+ &fsi_ak4642_device,
&sdhi0_cn7_device,
&sdhi1_cn8_device,
&irda_device,
@@ -852,37 +832,29 @@ static int __init devices_setup(void)
gpio_request(GPIO_FN_KEYOUT0, NULL);
/* enable FSI */
- gpio_request(GPIO_FN_FSIMCKB, NULL);
gpio_request(GPIO_FN_FSIMCKA, NULL);
+ gpio_request(GPIO_FN_FSIIASD, NULL);
gpio_request(GPIO_FN_FSIOASD, NULL);
gpio_request(GPIO_FN_FSIIABCK, NULL);
gpio_request(GPIO_FN_FSIIALRCK, NULL);
gpio_request(GPIO_FN_FSIOABCK, NULL);
gpio_request(GPIO_FN_FSIOALRCK, NULL);
gpio_request(GPIO_FN_CLKAUDIOAO, NULL);
- gpio_request(GPIO_FN_FSIIBSD, NULL);
- gpio_request(GPIO_FN_FSIOBSD, NULL);
- gpio_request(GPIO_FN_FSIIBBCK, NULL);
- gpio_request(GPIO_FN_FSIIBLRCK, NULL);
- gpio_request(GPIO_FN_FSIOBBCK, NULL);
- gpio_request(GPIO_FN_FSIOBLRCK, NULL);
- gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
- gpio_request(GPIO_FN_FSIIASD, NULL);
/* set SPU2 clock to 83.4 MHz */
clk = clk_get(NULL, "spu_clk");
- if (clk) {
+ if (!IS_ERR(clk)) {
clk_set_rate(clk, clk_round_rate(clk, 83333333));
clk_put(clk);
}
/* change parent of FSI A */
clk = clk_get(NULL, "fsia_clk");
- if (clk) {
- clk_register(&fsimcka_clk);
- clk_set_parent(clk, &fsimcka_clk);
- clk_set_rate(clk, 11000);
- clk_set_rate(&fsimcka_clk, 11000);
+ if (!IS_ERR(clk)) {
+ /* 48kHz dummy clock was used to make sure 1/1 divide */
+ clk_set_rate(&sh7724_fsimcka_clk, 48000);
+ clk_set_parent(clk, &sh7724_fsimcka_clk);
+ clk_set_rate(clk, 48000);
clk_put(clk);
}
diff --git a/arch/sh/boards/mach-se/board-se7619.c b/arch/sh/boards/mach-se/board-se7619.c
index 1d0ef7faa10d..82b6d4a5dc02 100644
--- a/arch/sh/boards/mach-se/board-se7619.c
+++ b/arch/sh/boards/mach-se/board-se7619.c
@@ -11,6 +11,11 @@
#include <asm/io.h>
#include <asm/machvec.h>
+static int se7619_mode_pins(void)
+{
+ return MODE_PIN2 | MODE_PIN0;
+}
+
/*
* The Machine Vector
*/
@@ -18,4 +23,5 @@
static struct sh_machine_vector mv_se __initmv = {
.mv_name = "SolutionEngine",
.mv_nr_irqs = 108,
+ .mv_mode_pins = se7619_mode_pins,
};
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 60ee09a4e121..a09c77dd09db 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -382,14 +382,13 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
struct pci_channel *chan = dev->sysdata;
if (unlikely(!chan->io_map_base)) {
- chan->io_map_base = generic_io_base;
+ chan->io_map_base = sh_io_port_base;
if (pci_domains_supported)
panic("To avoid data corruption io_map_base MUST be "
"set with multiple PCI domains.");
}
-
return (void __iomem *)(chan->io_map_base + port);
}
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 1f4e562c5e8c..82e1eabeac98 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -96,7 +96,7 @@ void kmap_coherent_init(void);
void *kmap_coherent(struct page *page, unsigned long addr);
void kunmap_coherent(void *kvaddr);
-#define PG_dcache_dirty PG_arch_1
+#define PG_dcache_clean PG_arch_1
void cpu_cache_init(void);
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
index 5645f358128b..6ba91868201c 100644
--- a/arch/sh/include/asm/clkdev.h
+++ b/arch/sh/include/asm/clkdev.h
@@ -1,9 +1,5 @@
/*
- * arch/sh/include/asm/clkdev.h
- *
- * Cloned from arch/arm/include/asm/clkdev.h:
- *
- * Copyright (C) 2008 Russell King.
+ * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.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
@@ -11,25 +7,25 @@
*
* Helper for the clk API to assist looking up a struct clk.
*/
-#ifndef __ASM_CLKDEV_H
-#define __ASM_CLKDEV_H
-struct clk;
+#ifndef __CLKDEV__H_
+#define __CLKDEV__H_
-struct clk_lookup {
- struct list_head node;
- const char *dev_id;
- const char *con_id;
- struct clk *clk;
-};
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
-struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
- const char *dev_fmt, ...);
+#include <asm/clock.h>
-void clkdev_add(struct clk_lookup *cl);
-void clkdev_drop(struct clk_lookup *cl);
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ if (!slab_is_available())
+ return alloc_bootmem_low_pages(size);
+ else
+ return kzalloc(size, GFP_KERNEL);
+}
-void clkdev_add_table(struct clk_lookup *, size_t);
-int clk_add_alias(const char *, const char *, char *, struct device *);
+#define __clk_put(clk)
+#define __clk_get(clk) ({ 1; })
-#endif
+#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index b237d525d592..89ab2c57a4c2 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -1,5 +1,6 @@
#ifndef __ASM_SH_IO_H
#define __ASM_SH_IO_H
+
/*
* Convention:
* read{b,w,l,q}/write{b,w,l,q} are for PCI,
@@ -15,12 +16,6 @@
* SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice
* these have the same semantics as the __raw variants, and as such, all
* new code should be using the __raw versions.
- *
- * All ISA I/O routines are wrapped through the machine vector. If a
- * board does not provide overrides, a generic set that are copied in
- * from the default machine vector are used instead. These are largely
- * for old compat code for I/O offseting to SuperIOs, all of which are
- * better handled through the machvec ioport mapping routines these days.
*/
#include <linux/errno.h>
#include <asm/cache.h>
@@ -31,39 +26,10 @@
#include <asm-generic/iomap.h>
#ifdef __KERNEL__
-/*
- * Depending on which platform we are running on, we need different
- * I/O functions.
- */
-#define __IO_PREFIX generic
+#define __IO_PREFIX generic
#include <asm/io_generic.h>
#include <asm/io_trapped.h>
-#ifdef CONFIG_HAS_IOPORT
-
-#define inb(p) sh_mv.mv_inb((p))
-#define inw(p) sh_mv.mv_inw((p))
-#define inl(p) sh_mv.mv_inl((p))
-#define outb(x,p) sh_mv.mv_outb((x),(p))
-#define outw(x,p) sh_mv.mv_outw((x),(p))
-#define outl(x,p) sh_mv.mv_outl((x),(p))
-
-#define inb_p(p) sh_mv.mv_inb_p((p))
-#define inw_p(p) sh_mv.mv_inw_p((p))
-#define inl_p(p) sh_mv.mv_inl_p((p))
-#define outb_p(x,p) sh_mv.mv_outb_p((x),(p))
-#define outw_p(x,p) sh_mv.mv_outw_p((x),(p))
-#define outl_p(x,p) sh_mv.mv_outl_p((x),(p))
-
-#define insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
-#define insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
-#define insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
-#define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
-#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
-#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
-
-#endif
-
#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
@@ -74,68 +40,39 @@
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
-#define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; })
-#define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; })
-#define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; })
-#define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; })
-
-#define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); })
-#define writew(v,a) ({ __raw_writew((v),(a)); mb(); })
-#define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
-#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); })
-
-/*
- * Legacy SuperH on-chip I/O functions
- *
- * These are all deprecated, all new (and especially cross-platform) code
- * should be using the __raw_xxx() routines directly.
- */
-static inline u8 __deprecated ctrl_inb(unsigned long addr)
-{
- return __raw_readb(addr);
-}
-
-static inline u16 __deprecated ctrl_inw(unsigned long addr)
-{
- return __raw_readw(addr);
-}
-
-static inline u32 __deprecated ctrl_inl(unsigned long addr)
-{
- return __raw_readl(addr);
-}
-
-static inline u64 __deprecated ctrl_inq(unsigned long addr)
-{
- return __raw_readq(addr);
-}
-
-static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
-{
- __raw_writeb(v, addr);
-}
-
-static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
-{
- __raw_writew(v, addr);
-}
-
-static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
-{
- __raw_writel(v, addr);
-}
-
-static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
-{
- __raw_writeq(v, addr);
-}
-
-extern unsigned long generic_io_base;
-
-static inline void ctrl_delay(void)
-{
- __raw_readw(generic_io_base);
-}
+#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
+#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \
+ __raw_readw(c)); __v; })
+#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \
+ __raw_readl(c)); __v; })
+#define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64) \
+ __raw_readq(c)); __v; })
+
+#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c))
+#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \
+ cpu_to_le16(v),c))
+#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
+ cpu_to_le32(v),c))
+#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64) \
+ cpu_to_le64(v),c))
+
+#define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; })
+#define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; })
+#define readl(a) ({ u32 r_ = readl_relaxed(a); rmb(); r_; })
+#define readq(a) ({ u64 r_ = readq_relaxed(a); rmb(); r_; })
+
+#define writeb(v,a) ({ wmb(); writeb_relaxed((v),(a)); })
+#define writew(v,a) ({ wmb(); writew_relaxed((v),(a)); })
+#define writel(v,a) ({ wmb(); writel_relaxed((v),(a)); })
+#define writeq(v,a) ({ wmb(); writeq_relaxed((v),(a)); })
+
+#define readsb(p,d,l) __raw_readsb(p,d,l)
+#define readsw(p,d,l) __raw_readsw(p,d,l)
+#define readsl(p,d,l) __raw_readsl(p,d,l)
+
+#define writesb(p,d,l) __raw_writesb(p,d,l)
+#define writesw(p,d,l) __raw_writesw(p,d,l)
+#define writesl(p,d,l) __raw_writesl(p,d,l)
#define __BUILD_UNCACHED_IO(bwlq, type) \
static inline type read##bwlq##_uncached(unsigned long addr) \
@@ -159,10 +96,11 @@ __BUILD_UNCACHED_IO(w, u16)
__BUILD_UNCACHED_IO(l, u32)
__BUILD_UNCACHED_IO(q, u64)
-#define __BUILD_MEMORY_STRING(bwlq, type) \
+#define __BUILD_MEMORY_STRING(pfx, bwlq, type) \
\
-static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
- const void *addr, unsigned int count) \
+static inline void \
+pfx##writes##bwlq(volatile void __iomem *mem, const void *addr, \
+ unsigned int count) \
{ \
const volatile type *__addr = addr; \
\
@@ -172,8 +110,8 @@ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
} \
} \
\
-static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
- void *addr, unsigned int count) \
+static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
+ void *addr, unsigned int count) \
{ \
volatile type *__addr = addr; \
\
@@ -183,85 +121,166 @@ static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
} \
}
-__BUILD_MEMORY_STRING(b, u8)
-__BUILD_MEMORY_STRING(w, u16)
+__BUILD_MEMORY_STRING(__raw_, b, u8)
+__BUILD_MEMORY_STRING(__raw_, w, u16)
#ifdef CONFIG_SUPERH32
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
#else
-__BUILD_MEMORY_STRING(l, u32)
+__BUILD_MEMORY_STRING(__raw_, l, u32)
#endif
-__BUILD_MEMORY_STRING(q, u64)
-
-#define writesb __raw_writesb
-#define writesw __raw_writesw
-#define writesl __raw_writesl
-
-#define readsb __raw_readsb
-#define readsw __raw_readsw
-#define readsl __raw_readsl
-
-#define readb_relaxed(a) readb(a)
-#define readw_relaxed(a) readw(a)
-#define readl_relaxed(a) readl(a)
-#define readq_relaxed(a) readq(a)
-
-#ifndef CONFIG_GENERIC_IOMAP
-/* Simple MMIO */
-#define ioread8(a) __raw_readb(a)
-#define ioread16(a) __raw_readw(a)
-#define ioread16be(a) be16_to_cpu(__raw_readw((a)))
-#define ioread32(a) __raw_readl(a)
-#define ioread32be(a) be32_to_cpu(__raw_readl((a)))
-
-#define iowrite8(v,a) __raw_writeb((v),(a))
-#define iowrite16(v,a) __raw_writew((v),(a))
-#define iowrite16be(v,a) __raw_writew(cpu_to_be16((v)),(a))
-#define iowrite32(v,a) __raw_writel((v),(a))
-#define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a))
-
-#define ioread8_rep(a, d, c) __raw_readsb((a), (d), (c))
-#define ioread16_rep(a, d, c) __raw_readsw((a), (d), (c))
-#define ioread32_rep(a, d, c) __raw_readsl((a), (d), (c))
-
-#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
-#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
-#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
+__BUILD_MEMORY_STRING(__raw_, q, u64)
+
+#ifdef CONFIG_HAS_IOPORT
+
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
+
+/*
+ * On SuperH I/O ports are memory mapped, so we access them using normal
+ * load/store instructions. sh_io_port_base is the virtual address to
+ * which all ports are being mapped.
+ */
+extern const unsigned long sh_io_port_base;
+
+static inline void __set_io_port_base(unsigned long pbase)
+{
+ *(unsigned long *)&sh_io_port_base = pbase;
+ barrier();
+}
+
+#ifdef CONFIG_GENERIC_IOMAP
+#define __ioport_map ioport_map
+#else
+extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
#endif
-#define mmio_insb(p,d,c) __raw_readsb(p,d,c)
-#define mmio_insw(p,d,c) __raw_readsw(p,d,c)
-#define mmio_insl(p,d,c) __raw_readsl(p,d,c)
+#ifdef CONF_SLOWDOWN_IO
+#define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
+#else
+#define SLOW_DOWN_IO
+#endif
-#define mmio_outsb(p,s,c) __raw_writesb(p,s,c)
-#define mmio_outsw(p,s,c) __raw_writesw(p,s,c)
-#define mmio_outsl(p,s,c) __raw_writesl(p,s,c)
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
+ \
+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
+{ \
+ volatile type *__addr; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ *__addr = val; \
+ slow; \
+} \
+ \
+static inline type pfx##in##bwlq##p(unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ __val = *__addr; \
+ slow; \
+ \
+ return __val; \
+}
-/* synco on SH-4A, otherwise a nop */
-#define mmiowb() wmb()
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
-#define IO_SPACE_LIMIT 0xffffffff
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type)
-#ifdef CONFIG_HAS_IOPORT
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+BUILDIO_IOPORT(q, u64)
+
+#define __BUILD_IOPORT_STRING(bwlq, type) \
+ \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
+ unsigned int count) \
+{ \
+ const volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ out##bwlq(*__addr, port); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void ins##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = in##bwlq(port); \
+ __addr++; \
+ } \
+}
+
+__BUILD_IOPORT_STRING(b, u8)
+__BUILD_IOPORT_STRING(w, u16)
+__BUILD_IOPORT_STRING(l, u32)
+__BUILD_IOPORT_STRING(q, u64)
+
+#endif
/*
- * This function provides a method for the generic case where a
- * board-specific ioport_map simply needs to return the port + some
- * arbitrary port base.
+ * Legacy SuperH on-chip I/O functions
*
- * We use this at board setup time to implicitly set the port base, and
- * as a result, we can use the generic ioport_map.
+ * These are all deprecated, all new (and especially cross-platform) code
+ * should be using the __raw_xxx() routines directly.
*/
-static inline void __set_io_port_base(unsigned long pbase)
+static inline u8 __deprecated ctrl_inb(unsigned long addr)
{
- generic_io_base = pbase;
+ return __raw_readb(addr);
}
-#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
+static inline u16 __deprecated ctrl_inw(unsigned long addr)
+{
+ return __raw_readw(addr);
+}
-#endif
+static inline u32 __deprecated ctrl_inl(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+static inline u64 __deprecated ctrl_inq(unsigned long addr)
+{
+ return __raw_readq(addr);
+}
+
+static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
+{
+ __raw_writeb(v, addr);
+}
+
+static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
+{
+ __raw_writew(v, addr);
+}
+
+static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
+{
+ __raw_writel(v, addr);
+}
+
+static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
+{
+ __raw_writeq(v, addr);
+}
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* synco on SH-4A, otherwise a nop */
+#define mmiowb() wmb()
/* We really want to try and get these to memcpy etc */
void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
@@ -395,10 +414,6 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define ioremap_nocache ioremap
#define iounmap __iounmap
-#define maybebadio(port) \
- printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
- __func__, __LINE__, (port), (u32)__builtin_return_address(0))
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h
index 491df93cbf8e..b5f6956f19c8 100644
--- a/arch/sh/include/asm/io_generic.h
+++ b/arch/sh/include/asm/io_generic.h
@@ -11,31 +11,6 @@
#error "Don't include this header without a valid system prefix"
#endif
-u8 IO_CONCAT(__IO_PREFIX,inb)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl)(unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,outb)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl)(u32, unsigned long);
-
-u8 IO_CONCAT(__IO_PREFIX,inb_p)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw_p)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl_p)(unsigned long);
-void IO_CONCAT(__IO_PREFIX,outb_p)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw_p)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl_p)(u32, unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,insb)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insw)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insl)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
-
-void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
-void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
-
void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
void IO_CONCAT(__IO_PREFIX,mem_init)(void);
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index a0b0cf79cf8a..dd5d6e5bf204 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -23,27 +23,6 @@ struct sh_machine_vector {
void (*mv_init_irq)(void);
#ifdef CONFIG_HAS_IOPORT
- u8 (*mv_inb)(unsigned long);
- u16 (*mv_inw)(unsigned long);
- u32 (*mv_inl)(unsigned long);
- void (*mv_outb)(u8, unsigned long);
- void (*mv_outw)(u16, unsigned long);
- void (*mv_outl)(u32, unsigned long);
-
- u8 (*mv_inb_p)(unsigned long);
- u16 (*mv_inw_p)(unsigned long);
- u32 (*mv_inl_p)(unsigned long);
- void (*mv_outb_p)(u8, unsigned long);
- void (*mv_outw_p)(u16, unsigned long);
- void (*mv_outl_p)(u32, unsigned long);
-
- void (*mv_insb)(unsigned long, void *dst, unsigned long count);
- void (*mv_insw)(unsigned long, void *dst, unsigned long count);
- void (*mv_insl)(unsigned long, void *dst, unsigned long count);
- void (*mv_outsb)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
-
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
void (*mv_ioport_unmap)(void __iomem *);
#endif
diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h
index 9f4dd252c981..c48a9c3420da 100644
--- a/arch/sh/include/asm/unaligned-sh4a.h
+++ b/arch/sh/include/asm/unaligned-sh4a.h
@@ -18,10 +18,20 @@
* of spill registers and blowing up when building at low optimization
* levels. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34777.
*/
+#include <linux/unaligned/packed_struct.h>
#include <linux/types.h>
#include <asm/byteorder.h>
-static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
+static inline u16 sh4a_get_unaligned_cpu16(const u8 *p)
+{
+#ifdef __LITTLE_ENDIAN
+ return p[0] | p[1] << 8;
+#else
+ return p[0] << 8 | p[1];
+#endif
+}
+
+static __always_inline u32 sh4a_get_unaligned_cpu32(const u8 *p)
{
unsigned long unaligned;
@@ -34,218 +44,148 @@ static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
return unaligned;
}
-struct __una_u16 { u16 x __attribute__((packed)); };
-struct __una_u32 { u32 x __attribute__((packed)); };
-struct __una_u64 { u64 x __attribute__((packed)); };
-
-static inline u16 __get_unaligned_cpu16(const u8 *p)
-{
-#ifdef __LITTLE_ENDIAN
- return p[0] | p[1] << 8;
-#else
- return p[0] << 8 | p[1];
-#endif
-}
-
/*
* Even though movua.l supports auto-increment on the read side, it can
* only store to r0 due to instruction encoding constraints, so just let
* the compiler sort it out on its own.
*/
-static inline u64 __get_unaligned_cpu64(const u8 *p)
+static inline u64 sh4a_get_unaligned_cpu64(const u8 *p)
{
#ifdef __LITTLE_ENDIAN
- return (u64)__get_unaligned_cpu32(p + 4) << 32 |
- __get_unaligned_cpu32(p);
+ return (u64)sh4a_get_unaligned_cpu32(p + 4) << 32 |
+ sh4a_get_unaligned_cpu32(p);
#else
- return (u64)__get_unaligned_cpu32(p) << 32 |
- __get_unaligned_cpu32(p + 4);
+ return (u64)sh4a_get_unaligned_cpu32(p) << 32 |
+ sh4a_get_unaligned_cpu32(p + 4);
#endif
}
static inline u16 get_unaligned_le16(const void *p)
{
- return le16_to_cpu(__get_unaligned_cpu16(p));
+ return le16_to_cpu(sh4a_get_unaligned_cpu16(p));
}
static inline u32 get_unaligned_le32(const void *p)
{
- return le32_to_cpu(__get_unaligned_cpu32(p));
+ return le32_to_cpu(sh4a_get_unaligned_cpu32(p));
}
static inline u64 get_unaligned_le64(const void *p)
{
- return le64_to_cpu(__get_unaligned_cpu64(p));
+ return le64_to_cpu(sh4a_get_unaligned_cpu64(p));
}
static inline u16 get_unaligned_be16(const void *p)
{
- return be16_to_cpu(__get_unaligned_cpu16(p));
+ return be16_to_cpu(sh4a_get_unaligned_cpu16(p));
}
static inline u32 get_unaligned_be32(const void *p)
{
- return be32_to_cpu(__get_unaligned_cpu32(p));
+ return be32_to_cpu(sh4a_get_unaligned_cpu32(p));
}
static inline u64 get_unaligned_be64(const void *p)
{
- return be64_to_cpu(__get_unaligned_cpu64(p));
+ return be64_to_cpu(sh4a_get_unaligned_cpu64(p));
}
-static inline void __put_le16_noalign(u8 *p, u16 val)
+static inline void nonnative_put_le16(u16 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
}
-static inline void __put_le32_noalign(u8 *p, u32 val)
+static inline void nonnative_put_le32(u32 val, u8 *p)
{
- __put_le16_noalign(p, val);
- __put_le16_noalign(p + 2, val >> 16);
+ nonnative_put_le16(val, p);
+ nonnative_put_le16(val >> 16, p + 2);
}
-static inline void __put_le64_noalign(u8 *p, u64 val)
+static inline void nonnative_put_le64(u64 val, u8 *p)
{
- __put_le32_noalign(p, val);
- __put_le32_noalign(p + 4, val >> 32);
+ nonnative_put_le32(val, p);
+ nonnative_put_le32(val >> 32, p + 4);
}
-static inline void __put_be16_noalign(u8 *p, u16 val)
+static inline void nonnative_put_be16(u16 val, u8 *p)
{
*p++ = val >> 8;
*p++ = val;
}
-static inline void __put_be32_noalign(u8 *p, u32 val)
+static inline void nonnative_put_be32(u32 val, u8 *p)
{
- __put_be16_noalign(p, val >> 16);
- __put_be16_noalign(p + 2, val);
+ nonnative_put_be16(val >> 16, p);
+ nonnative_put_be16(val, p + 2);
}
-static inline void __put_be64_noalign(u8 *p, u64 val)
+static inline void nonnative_put_be64(u64 val, u8 *p)
{
- __put_be32_noalign(p, val >> 32);
- __put_be32_noalign(p + 4, val);
+ nonnative_put_be32(val >> 32, p);
+ nonnative_put_be32(val, p + 4);
}
static inline void put_unaligned_le16(u16 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u16 *)p)->x = val;
+ __put_unaligned_cpu16(val, p);
#else
- __put_le16_noalign(p, val);
+ nonnative_put_le16(val, p);
#endif
}
static inline void put_unaligned_le32(u32 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u32 *)p)->x = val;
+ __put_unaligned_cpu32(val, p);
#else
- __put_le32_noalign(p, val);
+ nonnative_put_le32(val, p);
#endif
}
static inline void put_unaligned_le64(u64 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u64 *)p)->x = val;
+ __put_unaligned_cpu64(val, p);
#else
- __put_le64_noalign(p, val);
+ nonnative_put_le64(val, p);
#endif
}
static inline void put_unaligned_be16(u16 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u16 *)p)->x = val;
+ __put_unaligned_cpu16(val, p);
#else
- __put_be16_noalign(p, val);
+ nonnative_put_be16(val, p);
#endif
}
static inline void put_unaligned_be32(u32 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u32 *)p)->x = val;
+ __put_unaligned_cpu32(val, p);
#else
- __put_be32_noalign(p, val);
+ nonnative_put_be32(val, p);
#endif
}
static inline void put_unaligned_be64(u64 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u64 *)p)->x = val;
+ __put_unaligned_cpu64(val, p);
#else
- __put_be64_noalign(p, val);
+ nonnative_put_be64(val, p);
#endif
}
/*
- * Cause a link-time error if we try an unaligned access other than
- * 1,2,4 or 8 bytes long
+ * While it's a bit non-obvious, even though the generic le/be wrappers
+ * use the __get/put_xxx prefixing, they actually wrap in to the
+ * non-prefixed get/put_xxx variants as provided above.
*/
-extern void __bad_unaligned_access_size(void);
-
-#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \
- __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
- __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
- __bad_unaligned_access_size())))); \
- }))
-
-#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \
- __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
- __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
- __bad_unaligned_access_size())))); \
- }))
-
-#define __put_unaligned_le(val, ptr) ({ \
- void *__gu_p = (ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- *(u8 *)__gu_p = (__force u8)(val); \
- break; \
- case 2: \
- put_unaligned_le16((__force u16)(val), __gu_p); \
- break; \
- case 4: \
- put_unaligned_le32((__force u32)(val), __gu_p); \
- break; \
- case 8: \
- put_unaligned_le64((__force u64)(val), __gu_p); \
- break; \
- default: \
- __bad_unaligned_access_size(); \
- break; \
- } \
- (void)0; })
-
-#define __put_unaligned_be(val, ptr) ({ \
- void *__gu_p = (ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- *(u8 *)__gu_p = (__force u8)(val); \
- break; \
- case 2: \
- put_unaligned_be16((__force u16)(val), __gu_p); \
- break; \
- case 4: \
- put_unaligned_be32((__force u32)(val), __gu_p); \
- break; \
- case 8: \
- put_unaligned_be64((__force u64)(val), __gu_p); \
- break; \
- default: \
- __bad_unaligned_access_size(); \
- break; \
- } \
- (void)0; })
+#include <linux/unaligned/generic.h>
#ifdef __LITTLE_ENDIAN
# define get_unaligned __get_unaligned_le
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 903cd618eb74..d6741fca89a4 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -368,8 +368,9 @@
#define __NR_sendmsg 355
#define __NR_recvmsg 356
#define __NR_recvmmsg 357
+#define __NR_accept4 358
-#define NR_syscalls 358
+#define NR_syscalls 359
#ifdef __KERNEL__
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index 4c27b68789b3..7eb435999426 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -303,4 +303,7 @@ enum {
SHDMA_SLAVE_SDHI1_RX,
};
+extern struct clk sh7724_fsimcka_clk;
+extern struct clk sh7724_fsimckb_clk;
+
#endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h
index 08fb42269ecd..3670455faaac 100644
--- a/arch/sh/include/mach-common/mach/romimage.h
+++ b/arch/sh/include/mach-common/mach/romimage.h
@@ -4,7 +4,7 @@
#else /* __ASSEMBLY__ */
-extern inline void mmcif_update_progress(int nr)
+static inline void mmcif_update_progress(int nr)
{
}
diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h
index 1dcf5e6c8d83..d63ef51ec186 100644
--- a/arch/sh/include/mach-ecovec24/mach/romimage.h
+++ b/arch/sh/include/mach-ecovec24/mach/romimage.h
@@ -35,7 +35,7 @@
#define HIZCRA 0xa4050158
#define PGDR 0xa405012c
-extern inline void mmcif_update_progress(int nr)
+static inline void mmcif_update_progress(int nr)
{
/* disable Hi-Z for LED pins */
__raw_writew(__raw_readw(HIZCRA) & ~(1 << 1), HIZCRA);
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
index 976256a323f2..7a883167c846 100644
--- a/arch/sh/include/mach-kfr2r09/mach/romimage.h
+++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h
@@ -23,7 +23,7 @@
#else /* __ASSEMBLY__ */
-extern inline void mmcif_update_progress(int nr)
+static inline void mmcif_update_progress(int nr)
{
}
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
index 40f0c2d3690c..a9cdac469927 100644
--- a/arch/sh/include/mach-sdk7786/mach/fpga.h
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -14,11 +14,16 @@
#define INTTESTR 0x040
#define SYSSR 0x050
#define NRGPR 0x060
+
#define NMISR 0x070
+#define NMISR_MAN_NMI BIT(0)
+#define NMISR_AUX_NMI BIT(1)
+#define NMISR_MASK (NMISR_MAN_NMI | NMISR_AUX_NMI)
#define NMIMR 0x080
#define NMIMR_MAN_NMIM BIT(0) /* Manual NMI mask */
#define NMIMR_AUX_NMIM BIT(1) /* Auxiliary NMI mask */
+#define NMIMR_MASK (NMIMR_MAN_NMIM | NMIMR_AUX_NMIM)
#define INTBSR 0x090
#define INTBMR 0x0a0
@@ -126,6 +131,9 @@
extern void __iomem *sdk7786_fpga_base;
extern void sdk7786_fpga_init(void);
+/* arch/sh/boards/mach-sdk7786/nmi.c */
+extern void sdk7786_nmi_init(void);
+
#define SDK7786_FPGA_REGADDR(reg) (sdk7786_fpga_base + (reg))
/*
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8eed6a485446..77f7ae1d4647 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -11,7 +11,7 @@ endif
CFLAGS_REMOVE_return_address.o = -pg
-obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
+obj-y := debugtraps.o dma-nommu.o dumpstack.o \
idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \
machvec.o nmi_debug.o process.o \
process_$(BITS).o ptrace.o ptrace_$(BITS).o \
@@ -20,6 +20,11 @@ obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
syscalls_$(BITS).o time.o topology.o traps.o \
traps_$(BITS).o unwinder.o
+ifndef CONFIG_GENERIC_IOMAP
+obj-y += iomap.o
+obj-$(CONFIG_HAS_IOPORT) += ioport.o
+endif
+
obj-y += cpu/
obj-$(CONFIG_VSYSCALL) += vsyscall/
obj-$(CONFIG_SMP) += smp.o
@@ -39,7 +44,6 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o
obj-$(CONFIG_HIBERNATION) += swsusp.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
-obj-$(CONFIG_HAS_IOPORT) += io_generic.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
deleted file mode 100644
index 1f800ef4a735..000000000000
--- a/arch/sh/kernel/clkdev.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * arch/sh/kernel/clkdev.c
- *
- * Cloned from arch/arm/common/clkdev.c:
- *
- * Copyright (C) 2008 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.
- *
- * Helper for the clk API to assist looking up a struct clk.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <asm/clock.h>
-#include <asm/clkdev.h>
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-/*
- * Find the correct struct clk for the device and connection ID.
- * We do slightly fuzzy matching here:
- * An entry with a NULL ID is assumed to be a wildcard.
- * 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 precedence: dev+con > dev only > con only.
- */
-static struct clk *clk_find(const char *dev_id, const char *con_id)
-{
- struct clk_lookup *p;
- struct clk *clk = NULL;
- int match, best = 0;
-
- list_for_each_entry(p, &clocks, node) {
- match = 0;
- if (p->dev_id) {
- if (!dev_id || strcmp(p->dev_id, dev_id))
- continue;
- match += 2;
- }
- if (p->con_id) {
- if (!con_id || strcmp(p->con_id, con_id))
- continue;
- match += 1;
- }
- if (match == 0)
- continue;
-
- if (match > best) {
- clk = p->clk;
- best = match;
- }
- }
- return clk;
-}
-
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
-{
- struct clk *clk;
-
- mutex_lock(&clocks_mutex);
- clk = clk_find(dev_id, con_id);
- mutex_unlock(&clocks_mutex);
-
- return clk ? clk : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(clk_get_sys);
-
-void clkdev_add(struct clk_lookup *cl)
-{
- mutex_lock(&clocks_mutex);
- list_add_tail(&cl->node, &clocks);
- mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clkdev_add);
-
-void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
-{
- mutex_lock(&clocks_mutex);
- while (num--) {
- list_add_tail(&cl->node, &clocks);
- cl++;
- }
- mutex_unlock(&clocks_mutex);
-}
-
-#define MAX_DEV_ID 20
-#define MAX_CON_ID 16
-
-struct clk_lookup_alloc {
- struct clk_lookup cl;
- char dev_id[MAX_DEV_ID];
- char con_id[MAX_CON_ID];
-};
-
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
-{
- struct clk_lookup_alloc *cla;
-
- if (!slab_is_available())
- cla = alloc_bootmem_low_pages(sizeof(*cla));
- else
- cla = kzalloc(sizeof(*cla), GFP_KERNEL);
-
- if (!cla)
- return NULL;
-
- cla->cl.clk = clk;
- if (con_id) {
- strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
- cla->cl.con_id = cla->con_id;
- }
-
- if (dev_fmt) {
- va_list ap;
-
- va_start(ap, dev_fmt);
- vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
- cla->cl.dev_id = cla->dev_id;
- va_end(ap);
- }
-
- return &cla->cl;
-}
-EXPORT_SYMBOL(clkdev_alloc);
-
-int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
- struct device *dev)
-{
- struct clk *r = clk_get(dev, id);
- struct clk_lookup *l;
-
- if (IS_ERR(r))
- return PTR_ERR(r);
-
- l = clkdev_alloc(r, alias, alias_dev_name);
- clk_put(r);
- if (!l)
- return -ENODEV;
- clkdev_add(l);
- return 0;
-}
-EXPORT_SYMBOL(clk_add_alias);
-
-/*
- * clkdev_drop - remove a clock dynamically allocated
- */
-void clkdev_drop(struct clk_lookup *cl)
-{
- struct clk_lookup_alloc *cla = container_of(cl, struct clk_lookup_alloc, cl);
-
- mutex_lock(&clocks_mutex);
- list_del(&cl->node);
- mutex_unlock(&clocks_mutex);
- kfree(cla);
-}
-EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 4edcb60a1355..d49c2135fd48 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -20,4 +20,4 @@ obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_SH_FPU_EMU) += fpu.o
-obj-y += irq/ init.o clock.o hwblk.o
+obj-y += irq/ init.o clock.o hwblk.o proc.o
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index e2f63d68da51..dd0e0f211359 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -2,7 +2,7 @@
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
static struct clk master_clk = {
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 50f887dda565..4187cf4fe185 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -48,20 +48,4 @@ int __init clk_init(void)
return ret;
}
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk *clk_get(struct device *dev, const char *con_id)
-{
- const char *dev_id = dev ? dev_name(dev) : NULL;
-
- return clk_get_sys(dev_id, con_id);
-}
-EXPORT_SYMBOL_GPL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL_GPL(clk_put);
diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c
new file mode 100644
index 000000000000..e80a936f409a
--- /dev/null
+++ b/arch/sh/kernel/cpu/proc.c
@@ -0,0 +1,148 @@
+#include <linux/seq_file.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/machvec.h>
+#include <asm/processor.h>
+
+static const char *cpu_name[] = {
+ [CPU_SH7201] = "SH7201",
+ [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
+ [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
+ [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
+ [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
+ [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
+ [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
+ [CPU_SH7721] = "SH7721", [CPU_SH7729] = "SH7729",
+ [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S",
+ [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751",
+ [CPU_SH7751R] = "SH7751R", [CPU_SH7760] = "SH7760",
+ [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
+ [CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770",
+ [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781",
+ [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
+ [CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757",
+ [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
+ [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
+ [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
+ [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
+ [CPU_SH_NONE] = "Unknown"
+};
+
+const char *get_cpu_subtype(struct sh_cpuinfo *c)
+{
+ return cpu_name[c->type];
+}
+EXPORT_SYMBOL(get_cpu_subtype);
+
+#ifdef CONFIG_PROC_FS
+/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
+static const char *cpu_flags[] = {
+ "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
+ "ptea", "llsc", "l2", "op32", "pteaex", NULL
+};
+
+static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
+{
+ unsigned long i;
+
+ seq_printf(m, "cpu flags\t:");
+
+ if (!c->flags) {
+ seq_printf(m, " %s\n", cpu_flags[0]);
+ return;
+ }
+
+ for (i = 0; cpu_flags[i]; i++)
+ if ((c->flags & (1 << i)))
+ seq_printf(m, " %s", cpu_flags[i+1]);
+
+ seq_printf(m, "\n");
+}
+
+static void show_cacheinfo(struct seq_file *m, const char *type,
+ struct cache_info info)
+{
+ unsigned int cache_size;
+
+ cache_size = info.ways * info.sets * info.linesz;
+
+ seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
+ type, cache_size >> 10, info.ways);
+}
+
+/*
+ * Get CPU information for use by the procfs.
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ struct sh_cpuinfo *c = v;
+ unsigned int cpu = c - cpu_data;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ if (cpu == 0)
+ seq_printf(m, "machine\t\t: %s\n", get_system_type());
+ else
+ seq_printf(m, "\n");
+
+ seq_printf(m, "processor\t: %d\n", cpu);
+ seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
+ seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
+ if (c->cut_major == -1)
+ seq_printf(m, "cut\t\t: unknown\n");
+ else if (c->cut_minor == -1)
+ seq_printf(m, "cut\t\t: %d.x\n", c->cut_major);
+ else
+ seq_printf(m, "cut\t\t: %d.%d\n", c->cut_major, c->cut_minor);
+
+ show_cpuflags(m, c);
+
+ seq_printf(m, "cache type\t: ");
+
+ /*
+ * Check for what type of cache we have, we support both the
+ * unified cache on the SH-2 and SH-3, as well as the harvard
+ * style cache on the SH-4.
+ */
+ if (c->icache.flags & SH_CACHE_COMBINED) {
+ seq_printf(m, "unified\n");
+ show_cacheinfo(m, "cache", c->icache);
+ } else {
+ seq_printf(m, "split (harvard)\n");
+ show_cacheinfo(m, "icache", c->icache);
+ show_cacheinfo(m, "dcache", c->dcache);
+ }
+
+ /* Optional secondary cache */
+ if (c->flags & CPU_HAS_L2_CACHE)
+ show_cacheinfo(m, "scache", c->scache);
+
+ seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits);
+
+ seq_printf(m, "bogomips\t: %lu.%02lu\n",
+ c->loops_per_jiffy/(500000/HZ),
+ (c->loops_per_jiffy/(5000/HZ)) % 100);
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+}
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+#endif /* CONFIG_PROC_FS */
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
index 0c9f24d7a02f..5b7f12e58a8d 100644
--- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
@@ -14,24 +14,18 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/io.h>
#include <asm/clock.h>
#include <asm/freq.h>
-#include <asm/io.h>
+#include <asm/processor.h>
static const int pll1rate[] = {1,2};
static const int pfc_divisors[] = {1,2,0,4};
-
-#if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6)
-#define PLL2 (2)
-#else
-#error "Illigal Clock Mode!"
-#endif
+static unsigned int pll2_mult;
static void master_clk_init(struct clk *clk)
{
- clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
+ clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
}
static struct clk_ops sh7619_master_clk_ops = {
@@ -70,6 +64,14 @@ static struct clk_ops *sh7619_clk_ops[] = {
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
+ if (test_mode_pin(MODE_PIN2 | MODE_PIN0) ||
+ test_mode_pin(MODE_PIN2 | MODE_PIN1))
+ pll2_mult = 2;
+ else if (test_mode_pin(MODE_PIN0) || test_mode_pin(MODE_PIN1))
+ pll2_mult = 4;
+
+ BUG_ON(!pll2_mult);
+
if (idx < ARRAY_SIZE(sh7619_clk_ops))
*ops = sh7619_clk_ops[idx];
}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index b26264dc2aef..1174e2d96c03 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -22,19 +22,12 @@ static const int pll1rate[]={1,2,3,4,6,8};
static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
-#if (CONFIG_SH_CLK_MD == 0)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (2)
-#elif (CONFIG_SH_CLK_MD == 3)
-#define PLL2 (1)
-#else
-#error "Illegal Clock Mode!"
-#endif
+static unsigned int pll2_mult;
static void master_clk_init(struct clk *clk)
{
- return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
+ clk->rate = 10000000 * pll2_mult *
+ pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
}
static struct clk_ops sh7201_master_clk_ops = {
@@ -80,6 +73,13 @@ static struct clk_ops *sh7201_clk_ops[] = {
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
+ if (test_mode_pin(MODE_PIN1 | MODE_PIN0))
+ pll2_mult = 1;
+ else if (test_mode_pin(MODE_PIN1))
+ pll2_mult = 2;
+ else
+ pll2_mult = 4;
+
if (idx < ARRAY_SIZE(sh7201_clk_ops))
*ops = sh7201_clk_ops[idx];
}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 7e75d8f79502..95a008e8b735 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -25,21 +25,11 @@ static const int pll1rate[]={8,12,16,0};
static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
-#if (CONFIG_SH_CLK_MD == 0)
-#define PLL2 (1)
-#elif (CONFIG_SH_CLK_MD == 1)
-#define PLL2 (2)
-#elif (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 3)
-#define PLL2 (4)
-#else
-#error "Illegal Clock Mode!"
-#endif
+static unsigned int pll2_mult;
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ;
+ clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * pll2_mult;
}
static struct clk_ops sh7203_master_clk_ops = {
@@ -79,6 +69,13 @@ static struct clk_ops *sh7203_clk_ops[] = {
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
+ if (test_mode_pin(MODE_PIN1))
+ pll2_mult = 4;
+ else if (test_mode_pin(MODE_PIN0))
+ pll2_mult = 2;
+ else
+ pll2_mult = 1;
+
if (idx < ARRAY_SIZE(sh7203_clk_ops))
*ops = sh7203_clk_ops[idx];
}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index b27a5e2687ab..3c314d7cd6e6 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -22,19 +22,11 @@ static const int pll1rate[]={1,2,3,4,6,8};
static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
-#if (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 6)
-#define PLL2 (2)
-#elif (CONFIG_SH_CLK_MD == 7)
-#define PLL2 (1)
-#else
-#error "Illigal Clock Mode!"
-#endif
+static unsigned int pll2_mult;
static void master_clk_init(struct clk *clk)
{
- clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
+ clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
}
static struct clk_ops sh7206_master_clk_ops = {
@@ -79,7 +71,13 @@ static struct clk_ops *sh7206_clk_ops[] = {
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
+ if (test_mode_pin(MODE_PIN2 | MODE_PIN1 | MODE_PIN0))
+ pll2_mult = 1;
+ else if (test_mode_pin(MODE_PIN2 | MODE_PIN1))
+ pll2_mult = 2;
+ else if (test_mode_pin(MODE_PIN1))
+ pll2_mult = 4;
+
if (idx < ARRAY_SIZE(sh7206_clk_ops))
*ops = sh7206_clk_ops[idx];
}
-
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index b601fa3978d1..3f6f8e98635c 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -13,7 +13,7 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
@@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk)
for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
int divisor = frqcr3_divisors[i];
- if (clk->ops->set_rate(clk, clk->parent->rate /
- divisor, 0) == 0)
+ if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
break;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 71291ae201b9..93c646072c1b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
/* SH7343 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 7ce5bbcd4084..049dc0628ccc 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
/* SH7366 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 2030f3d9fac7..9d23a36f0647 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7722.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index d3938f0d3702..55493cd5bd8f 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -22,7 +22,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clk.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7723.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 0fe2e9329cb2..d08fa953c88b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -22,7 +22,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clk.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7724.h>
@@ -111,12 +111,21 @@ static struct clk div3_clk = {
.parent = &pll_clk,
};
+/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+struct clk sh7724_fsimcka_clk = {
+};
+
+struct clk sh7724_fsimckb_clk = {
+};
+
static struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&fll_clk,
&pll_clk,
&div3_clk,
+ &sh7724_fsimcka_clk,
+ &sh7724_fsimckb_clk,
};
static void div4_kick(struct clk *clk)
@@ -154,16 +163,38 @@ struct clk div4_clks[DIV4_NR] = {
[DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
};
-enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
static struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
- [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0),
- [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0),
[DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
[DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
};
+enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+
+/* Indices are important - they are the actual src selecting values */
+static struct clk *fclkacr_parent[] = {
+ [0] = &div3_clk,
+ [1] = NULL,
+ [2] = &sh7724_fsimcka_clk,
+ [3] = NULL,
+};
+
+static struct clk *fclkbcr_parent[] = {
+ [0] = &div3_clk,
+ [1] = NULL,
+ [2] = &sh7724_fsimckb_clk,
+ [3] = NULL,
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0,
+ fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
+ [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0,
+ fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
+};
+
static struct clk mstp_clks[HWBLK_NR] = {
SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
@@ -240,8 +271,8 @@ static struct clk_lookup lookups[] = {
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
- CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
- CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
+ CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
+ CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
@@ -376,6 +407,9 @@ int __init arch_clk_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
+ ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+
+ if (!ret)
ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
return ret;
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index ce39a2ae8c6c..e073e3eb4c3d 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index 1f1df48008cd..599630fc4d3b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index 62d706350060..8894926479a6 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index c3e458aaa2b7..2d960247f3eb 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -14,7 +14,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <cpu/sh7785.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index 597c9fbe49c6..42e403be9076 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -13,7 +13,7 @@
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 4f70df6b6169..1afdb93b8ccb 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -14,7 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
-#include <asm/clkdev.h>
+#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
deleted file mode 100644
index 447d78f666f9..000000000000
--- a/arch/sh/kernel/io_generic.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * arch/sh/kernel/io_generic.c
- *
- * Copyright (C) 2000 Niibe Yutaka
- * Copyright (C) 2005 - 2007 Paul Mundt
- *
- * Generic I/O routine. These can be used where a machine specific version
- * is not required.
- *
- * 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/module.h>
-#include <linux/io.h>
-#include <asm/machvec.h>
-
-#ifdef CONFIG_CPU_SH3
-/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
- * workaround. */
-/* I'm not sure SH7709 has this kind of bug */
-#define dummy_read() __raw_readb(0xba000000)
-#else
-#define dummy_read()
-#endif
-
-unsigned long generic_io_base = 0;
-
-u8 generic_inb(unsigned long port)
-{
- return __raw_readb(__ioport_map(port, 1));
-}
-
-u16 generic_inw(unsigned long port)
-{
- return __raw_readw(__ioport_map(port, 2));
-}
-
-u32 generic_inl(unsigned long port)
-{
- return __raw_readl(__ioport_map(port, 4));
-}
-
-u8 generic_inb_p(unsigned long port)
-{
- unsigned long v = generic_inb(port);
-
- ctrl_delay();
- return v;
-}
-
-u16 generic_inw_p(unsigned long port)
-{
- unsigned long v = generic_inw(port);
-
- ctrl_delay();
- return v;
-}
-
-u32 generic_inl_p(unsigned long port)
-{
- unsigned long v = generic_inl(port);
-
- ctrl_delay();
- return v;
-}
-
-/*
- * insb/w/l all read a series of bytes/words/longs from a fixed port
- * address. However as the port address doesn't change we only need to
- * convert the port address to real address once.
- */
-
-void generic_insb(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsb(__ioport_map(port, 1), dst, count);
- dummy_read();
-}
-
-void generic_insw(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsw(__ioport_map(port, 2), dst, count);
- dummy_read();
-}
-
-void generic_insl(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsl(__ioport_map(port, 4), dst, count);
- dummy_read();
-}
-
-void generic_outb(u8 b, unsigned long port)
-{
- __raw_writeb(b, __ioport_map(port, 1));
-}
-
-void generic_outw(u16 b, unsigned long port)
-{
- __raw_writew(b, __ioport_map(port, 2));
-}
-
-void generic_outl(u32 b, unsigned long port)
-{
- __raw_writel(b, __ioport_map(port, 4));
-}
-
-void generic_outb_p(u8 b, unsigned long port)
-{
- generic_outb(b, port);
- ctrl_delay();
-}
-
-void generic_outw_p(u16 b, unsigned long port)
-{
- generic_outw(b, port);
- ctrl_delay();
-}
-
-void generic_outl_p(u32 b, unsigned long port)
-{
- generic_outl(b, port);
- ctrl_delay();
-}
-
-/*
- * outsb/w/l all write a series of bytes/words/longs to a fixed port
- * address. However as the port address doesn't change we only need to
- * convert the port address to real address once.
- */
-void generic_outsb(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesb(__ioport_map(port, 1), src, count);
- dummy_read();
-}
-
-void generic_outsw(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesw(__ioport_map(port, 2), src, count);
- dummy_read();
-}
-
-void generic_outsl(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesl(__ioport_map(port, 4), src, count);
- dummy_read();
-}
-
-void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
-{
-#ifdef P1SEG
- if (PXSEG(addr) >= P1SEG)
- return (void __iomem *)addr;
-#endif
-
- return (void __iomem *)(addr + generic_io_base);
-}
-
-void generic_ioport_unmap(void __iomem *addr)
-{
-}
-
-#ifndef CONFIG_GENERIC_IOMAP
-void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
- void __iomem *ret;
-
- ret = __ioport_map_trapped(port, nr);
- if (ret)
- return ret;
-
- return __ioport_map(port, nr);
-}
-EXPORT_SYMBOL(ioport_map);
-
-void ioport_unmap(void __iomem *addr)
-{
- sh_mv.mv_ioport_unmap(addr);
-}
-EXPORT_SYMBOL(ioport_unmap);
-#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/iomap.c b/arch/sh/kernel/iomap.c
new file mode 100644
index 000000000000..2e8e8b9b9cef
--- /dev/null
+++ b/arch/sh/kernel/iomap.c
@@ -0,0 +1,165 @@
+/*
+ * arch/sh/kernel/iomap.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * Copyright (C) 2005 - 2007 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.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+
+unsigned int ioread8(void __iomem *addr)
+{
+ return readb(addr);
+}
+EXPORT_SYMBOL(ioread8);
+
+unsigned int ioread16(void __iomem *addr)
+{
+ return readw(addr);
+}
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
+{
+ return be16_to_cpu(__raw_readw(addr));
+}
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
+{
+ return readl(addr);
+}
+EXPORT_SYMBOL(ioread32);
+
+unsigned int ioread32be(void __iomem *addr)
+{
+ return be32_to_cpu(__raw_readl(addr));
+}
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+ writeb(val, addr);
+}
+EXPORT_SYMBOL(iowrite8);
+
+void iowrite16(u16 val, void __iomem *addr)
+{
+ writew(val, addr);
+}
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+ __raw_writew(cpu_to_be16(val), addr);
+}
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+ __raw_writel(cpu_to_be32(val), addr);
+}
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+ while (--count >= 0) {
+ u8 data = __raw_readb(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+ while (--count >= 0) {
+ u16 data = __raw_readw(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+{
+ while (--count >= 0) {
+ u32 data = __raw_readl(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writeb(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writew(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writel(*src, addr);
+ src++;
+ }
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insb(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insw(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insl(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsb(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsw(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsl(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite32_rep);
diff --git a/arch/sh/kernel/ioport.c b/arch/sh/kernel/ioport.c
new file mode 100644
index 000000000000..e3ad6103e7c1
--- /dev/null
+++ b/arch/sh/kernel/ioport.c
@@ -0,0 +1,43 @@
+/*
+ * arch/sh/kernel/ioport.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * Copyright (C) 2005 - 2007 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.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+
+const unsigned long sh_io_port_base __read_mostly = -1;
+EXPORT_SYMBOL(sh_io_port_base);
+
+void __iomem *__ioport_map(unsigned long addr, unsigned int size)
+{
+ if (sh_mv.mv_ioport_map)
+ return sh_mv.mv_ioport_map(addr, size);
+
+ return (void __iomem *)(addr + sh_io_port_base);
+}
+EXPORT_SYMBOL(__ioport_map);
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ void __iomem *ret;
+
+ ret = __ioport_map_trapped(port, nr);
+ if (ret)
+ return ret;
+
+ return __ioport_map(port, nr);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+ if (sh_mv.mv_ioport_unmap)
+ sh_mv.mv_ioport_unmap(addr);
+}
+EXPORT_SYMBOL(ioport_unmap);
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 9f9bb63616ad..3d722e49db08 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -118,28 +118,6 @@ void __init sh_mv_setup(void)
sh_mv.mv_##elem = generic_##elem; \
} while (0)
-#ifdef CONFIG_HAS_IOPORT
-
-#ifdef P2SEG
- __set_io_port_base(P2SEG);
-#else
- __set_io_port_base(0);
-#endif
-
- mv_set(inb); mv_set(inw); mv_set(inl);
- mv_set(outb); mv_set(outw); mv_set(outl);
-
- mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
- mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
-
- mv_set(insb); mv_set(insw); mv_set(insl);
- mv_set(outsb); mv_set(outsw); mv_set(outsl);
-
- mv_set(ioport_map);
- mv_set(ioport_unmap);
-
-#endif
-
mv_set(irq_demux);
mv_set(mode_pins);
mv_set(mem_init);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index d6b018c7ebdc..4f267160c515 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -12,7 +12,6 @@
#include <linux/initrd.h>
#include <linux/bootmem.h>
#include <linux/console.h>
-#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/utsname.h>
#include <linux/nodemask.h>
@@ -319,146 +318,3 @@ int test_mode_pin(int pin)
{
return sh_mv.mv_mode_pins() & pin;
}
-
-static const char *cpu_name[] = {
- [CPU_SH7201] = "SH7201",
- [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
- [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
- [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
- [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
- [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
- [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
- [CPU_SH7721] = "SH7721", [CPU_SH7729] = "SH7729",
- [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S",
- [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751",
- [CPU_SH7751R] = "SH7751R", [CPU_SH7760] = "SH7760",
- [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
- [CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770",
- [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781",
- [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
- [CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757",
- [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
- [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
- [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
- [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
- [CPU_SH_NONE] = "Unknown"
-};
-
-const char *get_cpu_subtype(struct sh_cpuinfo *c)
-{
- return cpu_name[c->type];
-}
-EXPORT_SYMBOL(get_cpu_subtype);
-
-#ifdef CONFIG_PROC_FS
-/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
-static const char *cpu_flags[] = {
- "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
- "ptea", "llsc", "l2", "op32", "pteaex", NULL
-};
-
-static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
-{
- unsigned long i;
-
- seq_printf(m, "cpu flags\t:");
-
- if (!c->flags) {
- seq_printf(m, " %s\n", cpu_flags[0]);
- return;
- }
-
- for (i = 0; cpu_flags[i]; i++)
- if ((c->flags & (1 << i)))
- seq_printf(m, " %s", cpu_flags[i+1]);
-
- seq_printf(m, "\n");
-}
-
-static void show_cacheinfo(struct seq_file *m, const char *type,
- struct cache_info info)
-{
- unsigned int cache_size;
-
- cache_size = info.ways * info.sets * info.linesz;
-
- seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
- type, cache_size >> 10, info.ways);
-}
-
-/*
- * Get CPU information for use by the procfs.
- */
-static int show_cpuinfo(struct seq_file *m, void *v)
-{
- struct sh_cpuinfo *c = v;
- unsigned int cpu = c - cpu_data;
-
- if (!cpu_online(cpu))
- return 0;
-
- if (cpu == 0)
- seq_printf(m, "machine\t\t: %s\n", get_system_type());
- else
- seq_printf(m, "\n");
-
- seq_printf(m, "processor\t: %d\n", cpu);
- seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
- seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
- if (c->cut_major == -1)
- seq_printf(m, "cut\t\t: unknown\n");
- else if (c->cut_minor == -1)
- seq_printf(m, "cut\t\t: %d.x\n", c->cut_major);
- else
- seq_printf(m, "cut\t\t: %d.%d\n", c->cut_major, c->cut_minor);
-
- show_cpuflags(m, c);
-
- seq_printf(m, "cache type\t: ");
-
- /*
- * Check for what type of cache we have, we support both the
- * unified cache on the SH-2 and SH-3, as well as the harvard
- * style cache on the SH-4.
- */
- if (c->icache.flags & SH_CACHE_COMBINED) {
- seq_printf(m, "unified\n");
- show_cacheinfo(m, "cache", c->icache);
- } else {
- seq_printf(m, "split (harvard)\n");
- show_cacheinfo(m, "icache", c->icache);
- show_cacheinfo(m, "dcache", c->dcache);
- }
-
- /* Optional secondary cache */
- if (c->flags & CPU_HAS_L2_CACHE)
- show_cacheinfo(m, "scache", c->scache);
-
- seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits);
-
- seq_printf(m, "bogomips\t: %lu.%02lu\n",
- c->loops_per_jiffy/(500000/HZ),
- (c->loops_per_jiffy/(5000/HZ)) % 100);
-
- return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos < NR_CPUS ? cpu_data + *pos : NULL;
-}
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return c_start(m, pos);
-}
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-const struct seq_operations cpuinfo_op = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = show_cpuinfo,
-};
-#endif /* CONFIG_PROC_FS */
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index e872e81add8a..6fc347ebe59d 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -375,3 +375,4 @@ ENTRY(sys_call_table)
.long sys_sendmsg /* 355 */
.long sys_recvmsg
.long sys_recvmmsg
+ .long sys_accept4
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 2cfae81914aa..92eb98633ab0 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -114,7 +114,7 @@ static void sh4_flush_dcache_page(void *arg)
struct address_space *mapping = page_mapping(page);
if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
+ clear_bit(PG_dcache_clean, &page->flags);
else
#endif
flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
@@ -239,7 +239,7 @@ static void sh4_flush_cache_page(void *args)
* another ASID than the current one.
*/
map_coherent = (current_cpu_data.dcache.n_aliases &&
- !test_bit(PG_dcache_dirty, &page->flags) &&
+ test_bit(PG_dcache_clean, &page->flags) &&
page_mapped(page));
if (map_coherent)
vaddr = kmap_coherent(page, address);
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index f498da1cce7a..7729cca727eb 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -139,7 +139,7 @@ static void sh7705_flush_dcache_page(void *arg)
struct address_space *mapping = page_mapping(page);
if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
+ clear_bit(PG_dcache_clean, &page->flags);
else
__flush_dcache_page(__pa(page_address(page)));
}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index ba401d137bb9..88d3dc3d30d5 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -60,14 +60,14 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long len)
{
if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
- !test_bit(PG_dcache_dirty, &page->flags)) {
+ test_bit(PG_dcache_clean, &page->flags)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent(vto);
} else {
memcpy(dst, src, len);
if (boot_cpu_data.dcache.n_aliases)
- set_bit(PG_dcache_dirty, &page->flags);
+ clear_bit(PG_dcache_clean, &page->flags);
}
if (vma->vm_flags & VM_EXEC)
@@ -79,14 +79,14 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long len)
{
if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
- !test_bit(PG_dcache_dirty, &page->flags)) {
+ test_bit(PG_dcache_clean, &page->flags)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent(vfrom);
} else {
memcpy(dst, src, len);
if (boot_cpu_data.dcache.n_aliases)
- set_bit(PG_dcache_dirty, &page->flags);
+ clear_bit(PG_dcache_clean, &page->flags);
}
}
@@ -98,7 +98,7 @@ void copy_user_highpage(struct page *to, struct page *from,
vto = kmap_atomic(to, KM_USER1);
if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
- !test_bit(PG_dcache_dirty, &from->flags)) {
+ test_bit(PG_dcache_clean, &from->flags)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
kunmap_coherent(vfrom);
@@ -141,7 +141,7 @@ void __update_cache(struct vm_area_struct *vma,
page = pfn_to_page(pfn);
if (pfn_valid(pfn)) {
- int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+ int dirty = !test_and_set_bit(PG_dcache_clean, &page->flags);
if (dirty)
__flush_purge_region(page_address(page), PAGE_SIZE);
}
@@ -153,7 +153,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
if (pages_do_alias(addr, vmaddr)) {
if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
- !test_bit(PG_dcache_dirty, &page->flags)) {
+ test_bit(PG_dcache_clean, &page->flags)) {
void *kaddr;
kaddr = kmap_coherent(page, vmaddr);
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
index 15d74ea42094..ec29e14ec5a8 100644
--- a/arch/sh/mm/kmap.c
+++ b/arch/sh/mm/kmap.c
@@ -34,7 +34,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
enum fixed_addresses idx;
unsigned long vaddr;
- BUG_ON(test_bit(PG_dcache_dirty, &page->flags));
+ BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
pagefault_disable();
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h
index 81cd43432dc0..47eaafad15ce 100644
--- a/arch/sparc/include/asm/openprom.h
+++ b/arch/sparc/include/asm/openprom.h
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs {
int (*v2_dev_open)(char *devpath);
void (*v2_dev_close)(int d);
int (*v2_dev_read)(int d, char *buf, int nbytes);
- int (*v2_dev_write)(int d, char *buf, int nbytes);
+ int (*v2_dev_write)(int d, const char *buf, int nbytes);
int (*v2_dev_seek)(int d, int hi, int lo);
/* Never issued (multistage load support) */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 51296a6f5005..98f70822fa05 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -48,37 +48,6 @@ extern void prom_init(struct linux_romvec *rom_ptr);
/* Boot argument acquisition, returns the boot command line string. */
extern char *prom_getbootargs(void);
-/* Device utilities. */
-
-/* Map and unmap devices in IO space at virtual addresses. Note that the
- * virtual address you pass is a request and the prom may put your mappings
- * somewhere else, so check your return value as that is where your new
- * mappings really are!
- *
- * Another note, these are only available on V2 or higher proms!
- */
-extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
-extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
-
-/* Device operations. */
-
-/* Open the device described by the passed string. Note, that the format
- * of the string is different on V0 vs. V2->higher proms. The caller must
- * know what he/she is doing! Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
- unsigned int seek_lowval);
-
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
@@ -121,19 +90,8 @@ extern int prom_getrev(void);
/* Get the prom firmware revision. */
extern int prom_getprev(void);
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
extern void prom_printf(const char *fmt, ...);
@@ -147,25 +105,6 @@ extern void prom_write(const char *buf, unsigned int len);
extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
int context, char *program_counter);
-/* Stop the CPU with the passed device tree node. */
-extern int prom_stopcpu(int cpunode);
-
-/* Idle the CPU with the passed device tree node. */
-extern int prom_idlecpu(int cpunode);
-
-/* Re-Start the CPU with the passed device tree node. */
-extern int prom_restartcpu(int cpunode);
-
-/* PROM memory allocation facilities... */
-
-/* Allocated at possibly the given virtual address a chunk of the
- * indicated size.
- */
-extern char *prom_alloc(char *virt_hint, unsigned int size);
-
-/* Free a previously allocated chunk. */
-extern void prom_free(char *virt_addr, unsigned int size);
-
/* Sun4/sun4c specific memory-management startup hook. */
/* Map the passed segment in the given context at the passed
@@ -208,19 +147,11 @@ extern int prom_getbool(phandle node, char *prop);
/* Acquire a string property, null string on error. */
extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize);
-/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(phandle thisnode, char *name);
-
/* Search all siblings starting at the passed node for "name" matching
* the given string. Returns the node on success, zero on failure.
*/
extern phandle prom_searchsiblings(phandle node_start, char *name);
-/* Return the first property type, as a string, for the given node.
- * Returns a null string on error.
- */
-extern char *prom_firstprop(phandle node, char *buffer);
-
/* Returns the next property after the passed property for the given
* node. Returns null string on failure.
*/
@@ -229,16 +160,12 @@ extern char *prom_nextprop(phandle node, char *prev_property, char *buffer);
/* Returns phandle of the path specified */
extern phandle prom_finddevice(char *name);
-/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(phandle node, char *property);
-
/* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took.
*/
extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern phandle prom_pathtoinode(char *path);
extern phandle prom_inst2pkg(int);
/* Dorking with Bus ranges... */
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index c9cc078e3e31..97a90475c314 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -18,8 +18,8 @@ extern char prom_version[];
*/
extern phandle prom_root_node;
-/* PROM stdin and stdout */
-extern int prom_stdin, prom_stdout;
+/* PROM stdout */
+extern int prom_stdout;
/* /chosen node of the prom device tree, this stays constant after
* initialization is complete.
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack);
/* Boot argument acquisition, returns the boot command line string. */
extern char *prom_getbootargs(void);
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string. Note, that the format
- * of the string is different on V0 vs. V2->higher proms. The caller must
- * know what he/she is doing! Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
- unsigned int seek_lowval);
-
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn));
/* Halt and power-off the machine. */
extern void prom_halt_power_off(void) __attribute__ ((noreturn));
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
/* Acquire the IDPROM of the root node in the prom device tree. This
* gets passed a buffer where you would like it stuffed. The return value
* is the format type of this idprom or 0xff on error.
*/
extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
extern void prom_printf(const char *fmt, ...);
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name);
extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern phandle prom_pathtoinode(const char *path);
extern phandle prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
extern void prom_sun4v_guest_soft_state(void);
extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 2d51527d810f..f01c42661ee5 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
if (leon3_gptimer_regs && leon3_irqctrl_regs) {
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
- (((1000000 / 100) - 1)));
+ (((1000000 / HZ) - 1)));
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
#ifdef CONFIG_SMP
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
}
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
# endif
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 1b8c073adb44..8287bbe88768 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -5,13 +5,10 @@ asflags := -ansi
ccflags := -Werror
lib-y := bootstr_$(BITS).o
-lib-$(CONFIG_SPARC32) += devmap.o
-lib-y += devops_$(BITS).o
lib-y += init_$(BITS).o
lib-$(CONFIG_SPARC32) += memory.o
lib-y += misc_$(BITS).o
lib-$(CONFIG_SPARC32) += mp.o
-lib-$(CONFIG_SPARC32) += palloc.o
lib-$(CONFIG_SPARC32) += ranges.o
lib-$(CONFIG_SPARC32) += segment.o
lib-y += console_$(BITS).o
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 5340264b78f5..b05e3db5fa63 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -16,63 +16,27 @@
extern void restore_current(void);
-/* Non blocking get character from console input device, returns -1
- * if no input was taken. This can be used for polling.
- */
-int
-prom_nbgetchar(void)
-{
- static char inc;
- int i = -1;
- unsigned long flags;
-
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- i = (*(romvec->pv_nbgetchar))();
- break;
- case PROM_V2:
- case PROM_V3:
- if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
- i = inc;
- } else {
- i = -1;
- }
- break;
- default:
- i = -1;
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
- return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
/* Non blocking put character to console device, returns -1 if
* unsuccessful.
*/
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
{
- static char outc;
unsigned long flags;
int i = -1;
spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
- i = (*(romvec->pv_nbputchar))(c);
+ if ((*(romvec->pv_nbputchar))(*buf))
+ i = 1;
break;
case PROM_V2:
case PROM_V3:
- outc = c;
- if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
- i = 0;
- else
- i = -1;
+ if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+ buf, 0x1) == 1)
+ i = 1;
break;
default:
- i = -1;
break;
};
restore_current();
@@ -80,18 +44,14 @@ prom_nbputchar(char c)
return i; /* Ugh, we could spin forever on unsupported proms ;( */
}
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
{
- int character;
- while((character = prom_nbgetchar()) == -1) ;
- return (char) character;
+ while (len) {
+ int n = prom_nbputchar(buf);
+ if (n < 0)
+ continue;
+ len--;
+ buf++;
+ }
}
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
- while(prom_nbputchar(c) == -1) ;
-}
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index 10322dc2f557..9de6c8cfe04a 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -13,87 +13,34 @@
#include <asm/system.h>
#include <linux/string.h>
-extern int prom_stdin, prom_stdout;
-
-/* Non blocking get character from console input device, returns -1
- * if no input was taken. This can be used for polling.
- */
-inline int
-prom_nbgetchar(void)
+static int __prom_console_write_buf(const char *buf, int len)
{
unsigned long args[7];
- char inc;
-
- args[0] = (unsigned long) "read";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdin;
- args[4] = (unsigned long) &inc;
- args[5] = 1;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[6] == 1)
- return inc;
- return -1;
-}
-
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-inline int
-prom_nbputchar(char c)
-{
- unsigned long args[7];
- char outc;
-
- outc = c;
+ int ret;
args[0] = (unsigned long) "write";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) &outc;
- args[5] = 1;
+ args[4] = (unsigned long) buf;
+ args[5] = (unsigned int) len;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
- if (args[6] == 1)
- return 0;
- else
+ ret = (int) args[6];
+ if (ret < 0)
return -1;
+ return ret;
}
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
{
- int character;
- while((character = prom_nbgetchar()) == -1) ;
- return (char) character;
-}
-
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
- prom_nbputchar(c);
-}
-
-void
-prom_puts(const char *s, int len)
-{
- unsigned long args[7];
-
- args[0] = (unsigned long) "write";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) s;
- args[5] = len;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
+ while (len) {
+ int n = __prom_console_write_buf(buf, len);
+ if (n < 0)
+ continue;
+ len -= n;
+ buf += len;
+ }
}
diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c
deleted file mode 100644
index 46157d2aba0d..000000000000
--- a/arch/sparc/prom/devmap.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * promdevmap.c: Map device/IO areas to virtual addresses.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Just like the routines in palloc.c, these should not be used
- * by the kernel at all. Bootloader facility mainly. And again,
- * this is only available on V2 proms and above.
- */
-
-/* Map physical device address 'paddr' in IO space 'ios' of size
- * 'num_bytes' to a virtual address, with 'vhint' being a hint to
- * the prom as to where you would prefer the mapping. We return
- * where the prom actually mapped it.
- */
-char *
-prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes)
-{
- unsigned long flags;
- char *ret;
-
- spin_lock_irqsave(&prom_lock, flags);
- if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0;
- else
- ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr,
- num_bytes);
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
- return ret;
-}
-
-/* Unmap an IO/device area that was mapped using the above routine. */
-void
-prom_unmapio(char *vaddr, unsigned int num_bytes)
-{
- unsigned long flags;
-
- if(num_bytes == 0x0) return;
- spin_lock_irqsave(&prom_lock, flags);
- (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes);
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644
index 9c5d4687242a..000000000000
--- a/arch/sparc/prom/devops_32.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c: Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'. Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
- int handle;
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
- if(handle == 0) handle = -1;
- break;
- case PROM_V2:
- case PROM_V3:
- handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
- break;
- default:
- handle = -1;
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-
- return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- (*(romvec->pv_v0devops.v0_devclose))(dhandle);
- break;
- case PROM_V2:
- case PROM_V3:
- (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
- break;
- default:
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
- return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
- break;
- case PROM_V2:
- case PROM_V3:
- (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
- break;
- default:
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644
index a017119e7ef1..000000000000
--- a/arch/sparc/prom/devops_64.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c: Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'. Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
- unsigned long args[5];
-
- args[0] = (unsigned long) "open";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) dstr;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
- unsigned long args[4];
-
- args[0] = (unsigned long) "close";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned int) dhandle;
-
- p1275_cmd_direct(args);
-
- return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
- unsigned long args[7];
-
- args[0] = (unsigned long) "seek";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) dhandle;
- args[4] = seekhi;
- args[5] = seeklo;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-}
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 3ff911e7d25b..9c6ac4b81ded 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -18,7 +18,7 @@
char prom_version[80];
/* The root node of the prom device tree. */
-int prom_stdin, prom_stdout;
+int prom_stdout;
phandle prom_chosen_node;
/* You must call prom_init() before you attempt to use any of the
@@ -38,7 +38,6 @@ void __init prom_init(void *cif_handler, void *cif_stack)
if (!prom_chosen_node || prom_chosen_node == -1)
prom_halt();
- prom_stdin = prom_getint(prom_chosen_node, "stdin");
prom_stdout = prom_getint(prom_chosen_node, "stdout");
node = prom_finddevice("/openprom");
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index d24bc44e361e..e4f31d4d3715 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -18,7 +18,7 @@
#include <asm/system.h>
#include <asm/ldc.h>
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
{
unsigned long args[5];
@@ -150,20 +150,6 @@ void prom_halt_power_off(void)
prom_halt();
}
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
- unsigned long args[5];
- if (!funcp)
- return;
- args[0] = (unsigned long) "set-callback";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) funcp;
- args[4] = (unsigned long) -1;
- p1275_cmd_direct(args);
-}
-
/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
* format type. 'num_bytes' is the number of bytes that your idbuf
* has space for. Returns 0xff on error.
diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c
index 4c4dc79f65af..97c44c9ddbc8 100644
--- a/arch/sparc/prom/mp.c
+++ b/arch/sparc/prom/mp.c
@@ -41,81 +41,3 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
return ret;
}
-
-/* Stop CPU with device prom-tree node 'cpunode'.
- * XXX Again, what does the return value really mean? XXX
- */
-int
-prom_stopcpu(int cpunode)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- case PROM_V2:
- default:
- ret = -1;
- break;
- case PROM_V3:
- ret = (*(romvec->v3_cpustop))(cpunode);
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-
- return ret;
-}
-
-/* Make CPU with device prom-tree node 'cpunode' idle.
- * XXX Return value, anyone? XXX
- */
-int
-prom_idlecpu(int cpunode)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- case PROM_V2:
- default:
- ret = -1;
- break;
- case PROM_V3:
- ret = (*(romvec->v3_cpuidle))(cpunode);
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-
- return ret;
-}
-
-/* Resume the execution of CPU with nodeid 'cpunode'.
- * XXX Come on, somebody has to know... XXX
- */
-int
-prom_restartcpu(int cpunode)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- case PROM_V2:
- default:
- ret = -1;
- break;
- case PROM_V3:
- ret = (*(romvec->v3_cpuresume))(cpunode);
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-
- return ret;
-}
diff --git a/arch/sparc/prom/palloc.c b/arch/sparc/prom/palloc.c
deleted file mode 100644
index 2e2a88b211fb..000000000000
--- a/arch/sparc/prom/palloc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * palloc.c: Memory allocation from the Sun PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* You should not call these routines after memory management
- * has been initialized in the kernel, if fact you should not
- * use these if at all possible in the kernel. They are mainly
- * to be used for a bootloader for temporary allocations which
- * it will free before jumping into the kernel it has loaded.
- *
- * Also, these routines don't work on V0 proms, only V2 and later.
- */
-
-/* Allocate a chunk of memory of size 'num_bytes' giving a suggestion
- * of virtual_hint as the preferred virtual base address of this chunk.
- * There are no guarantees that you will get the allocation, or that
- * the prom will abide by your "hint". So check your return value.
- */
-char *
-prom_alloc(char *virtual_hint, unsigned int num_bytes)
-{
- if(prom_vers == PROM_V0) return (char *) 0x0;
- if(num_bytes == 0x0) return (char *) 0x0;
- return (*(romvec->pv_v2devops.v2_dumb_mem_alloc))(virtual_hint, num_bytes);
-}
-
-/* Free a previously allocated chunk back to the prom at virtual address
- * 'vaddr' of size 'num_bytes'. NOTE: This vaddr is not the hint you
- * used for the allocation, but the virtual address the prom actually
- * returned to you. They may be have been the same, they may have not,
- * doesn't matter.
- */
-void
-prom_free(char *vaddr, unsigned int num_bytes)
-{
- if((prom_vers == PROM_V0) || (num_bytes == 0x0)) return;
- (*(romvec->pv_v2devops.v2_dumb_mem_free))(vaddr, num_bytes);
-}
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index ca869266b9f3..d9682f06b3b0 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -15,22 +15,45 @@
#include <linux/kernel.h>
#include <linux/compiler.h>
+#include <linux/spinlock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
void notrace prom_write(const char *buf, unsigned int n)
{
- char ch;
+ unsigned int dest_len;
+ unsigned long flags;
+ char *dest;
+
+ dest = console_write_buf;
+ raw_spin_lock_irqsave(&console_write_lock, flags);
- while (n != 0) {
- --n;
- if ((ch = *buf++) == '\n')
- prom_putchar('\r');
- prom_putchar(ch);
+ dest_len = 0;
+ while (n-- != 0) {
+ char ch = *buf++;
+ if (ch == '\n') {
+ *dest++ = '\r';
+ dest_len++;
+ }
+ *dest++ = ch;
+ dest_len++;
+ if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+ prom_console_write_buf(console_write_buf, dest_len);
+ dest = console_write_buf;
+ dest_len = 0;
+ }
}
+ if (dest_len)
+ prom_console_write_buf(console_write_buf, dest_len);
+
+ raw_spin_unlock_irqrestore(&console_write_lock, flags);
}
void notrace prom_printf(const char *fmt, ...)
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index 63e08e149774..f8860eba32c2 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -20,7 +20,7 @@ extern void restore_current(void);
static char promlib_buf[128];
/* Internal version of prom_getchild that does not alter return values. */
-phandle __prom_getchild(phandle node)
+static phandle __prom_getchild(phandle node)
{
unsigned long flags;
phandle cnode;
@@ -52,7 +52,7 @@ phandle prom_getchild(phandle node)
EXPORT_SYMBOL(prom_getchild);
/* Internal version of prom_getsibling that does not alter return values. */
-phandle __prom_getsibling(phandle node)
+static phandle __prom_getsibling(phandle node)
{
unsigned long flags;
phandle cnode;
@@ -177,20 +177,6 @@ void prom_getstring(phandle node, char *prop, char *user_buf, int ubuf_size)
EXPORT_SYMBOL(prom_getstring);
-/* Does the device at node 'node' have name 'name'?
- * YES = 1 NO = 0
- */
-int prom_nodematch(phandle node, char *name)
-{
- int error;
-
- static char namebuf[128];
- error = prom_getproperty(node, "name", namebuf, sizeof(namebuf));
- if (error == -1) return 0;
- if(strcmp(namebuf, name) == 0) return 1;
- return 0;
-}
-
/* Search siblings at 'node_start' for a node with name
* 'nodename'. Return node if successful, zero if not.
*/
@@ -214,7 +200,7 @@ phandle prom_searchsiblings(phandle node_start, char *nodename)
EXPORT_SYMBOL(prom_searchsiblings);
/* Interal version of nextprop that does not alter return values. */
-char *__prom_nextprop(phandle node, char * oprop)
+static char *__prom_nextprop(phandle node, char * oprop)
{
unsigned long flags;
char *prop;
@@ -227,17 +213,6 @@ char *__prom_nextprop(phandle node, char * oprop)
return prop;
}
-/* Return the first property name for node 'node'. */
-/* buffer is unused argument, but as v9 uses it, we need to have the same interface */
-char *prom_firstprop(phandle node, char *bufer)
-{
- if (node == 0 || node == -1)
- return "";
-
- return __prom_nextprop(node, "");
-}
-EXPORT_SYMBOL(prom_firstprop);
-
/* Return the property type string after property type 'oprop'
* at node 'node' . Returns empty string if no more
* property types for this node.
@@ -299,19 +274,6 @@ phandle prom_finddevice(char *name)
}
EXPORT_SYMBOL(prom_finddevice);
-int prom_node_has_property(phandle node, char *prop)
-{
- char *current_property = "";
-
- do {
- current_property = prom_nextprop(node, current_property, NULL);
- if(!strcmp(current_property, prop))
- return 1;
- } while (*current_property);
- return 0;
-}
-EXPORT_SYMBOL(prom_node_has_property);
-
/* Set property 'pname' at node 'node' to value 'value' which has a length
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
@@ -342,19 +304,3 @@ phandle prom_inst2pkg(int inst)
if (node == -1) return 0;
return node;
}
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(char *path)
-{
- phandle node;
- int inst;
-
- inst = prom_devopen (path);
- if (inst == -1) return 0;
- node = prom_inst2pkg (inst);
- prom_devclose (inst);
- if (node == -1) return 0;
- return node;
-}
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 691be68932f8..d93660048376 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst)
return node;
}
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(const char *path)
-{
- phandle node;
- int inst;
-
- inst = prom_devopen (path);
- if (inst == 0)
- return 0;
- node = prom_inst2pkg(inst);
- prom_devclose(inst);
- if (node == -1)
- return 0;
- return node;
-}
-
int prom_ihandle2path(int handle, char *buffer, int bufsize)
{
unsigned long args[7];
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
index c1ee1d61d44c..81d92a45cd4b 100644
--- a/arch/tile/include/asm/signal.h
+++ b/arch/tile/include/asm/signal.h
@@ -25,7 +25,7 @@
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
struct pt_regs;
-int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
+int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
void do_signal(struct pt_regs *regs);
#endif
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 543d6a33aa26..dbb0dfc7bece 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
return ret;
}
+/* The assembly shim for this function arranges to ignore the return value. */
long compat_sys_rt_sigreturn(struct pt_regs *regs)
{
struct compat_rt_sigframe __user *frame =
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
sigset_t set;
- long r0;
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
goto badframe;
- return r0;
+ return 0;
badframe:
force_sig(SIGSEGV, current);
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index f5821626247f..5eed4a02bf62 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -1342,8 +1342,8 @@ handle_syscall:
lw r20, r20
/* Jump to syscall handler. */
- jalr r20; .Lhandle_syscall_link:
- FEEDBACK_REENTER(handle_syscall)
+ jalr r20
+.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
/*
* Write our r0 onto the stack so it gets restored instead
@@ -1352,6 +1352,9 @@ handle_syscall:
PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
sw r29, r0
+.Lsyscall_sigreturn_skip:
+ FEEDBACK_REENTER(handle_syscall)
+
/* Do syscall trace again, if requested. */
lw r30, r31
andi r30, r30, _TIF_SYSCALL_TRACE
@@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
}; \
STD_ENDPROC(_##x)
+/*
+ * Special-case sigreturn to not write r0 to the stack on return.
+ * This is technically more efficient, but it also avoids difficulties
+ * in the 64-bit OS when handling 32-bit compat code, since we must not
+ * sign-extend r0 for the sigreturn return-value case.
+ */
+#define PTREGS_SYSCALL_SIGRETURN(x, reg) \
+ STD_ENTRY(_##x); \
+ addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
+ { \
+ PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
+ j x \
+ }; \
+ STD_ENDPROC(_##x)
+
PTREGS_SYSCALL(sys_execve, r3)
PTREGS_SYSCALL(sys_sigaltstack, r2)
-PTREGS_SYSCALL(sys_rt_sigreturn, r0)
+PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 8430f45daea6..e90eb53173b0 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -212,6 +212,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
childregs->sp = sp; /* override with new user stack pointer */
/*
+ * If CLONE_SETTLS is set, set "tp" in the new task to "r4",
+ * which is passed in as arg #5 to sys_clone().
+ */
+ if (clone_flags & CLONE_SETTLS)
+ childregs->tp = regs->regs[4];
+
+ /*
* Copy the callee-saved registers from the passed pt_regs struct
* into the context-switch callee-saved registers area.
* This way when we start the interrupt-return sequence, the
@@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
return __switch_to(prev, next, next_current_ksp0(next));
}
+/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
void __user *, parent_tidptr, void __user *, child_tidptr,
struct pt_regs *, regs)
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index 757407e36696..1260321155f1 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
*/
int restore_sigcontext(struct pt_regs *regs,
- struct sigcontext __user *sc, long *pr0)
+ struct sigcontext __user *sc)
{
int err = 0;
int i;
@@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
regs->faultnum = INT_SWINT_1_SIGRETURN;
- err |= __get_user(*pr0, &sc->gregs[0]);
return err;
}
-/* sigreturn() returns long since it restores r0 in the interrupted code. */
+/* The assembly shim for this function arranges to ignore the return value. */
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
{
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->sp);
sigset_t set;
- long r0;
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
goto badframe;
- return r0;
+ return 0;
badframe:
force_sig(SIGSEGV, current);
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 23f315c9f215..325c05294fc4 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
if (heap > 0x3fffffffffffUL)
error("Destination address too large");
#else
- if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
+ if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
error("Destination address too large");
#endif
#ifndef CONFIG_RELOCATABLE
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index ff16756a51c1..8fe2a4966b7a 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -9,6 +9,20 @@
* Vinodh Gopal <vinodh.gopal@intel.com>
* Kahraman Akdemir
*
+ * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
+ * interface for 64-bit kernels.
+ * Authors: Erdinc Ozturk (erdinc.ozturk@intel.com)
+ * Aidan O'Mahony (aidan.o.mahony@intel.com)
+ * Adrian Hoban <adrian.hoban@intel.com>
+ * James Guilford (james.guilford@intel.com)
+ * Gabriele Paoloni <gabriele.paoloni@intel.com>
+ * Tadeusz Struk (tadeusz.struk@intel.com)
+ * Wajdi Feghali (wajdi.k.feghali@intel.com)
+ * Copyright (c) 2010, Intel Corporation.
+ *
+ * Ported x86_64 version to x86:
+ * Author: Mathias Krause <minipli@googlemail.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
@@ -18,8 +32,62 @@
#include <linux/linkage.h>
#include <asm/inst.h>
+#ifdef __x86_64__
+.data
+POLY: .octa 0xC2000000000000000000000000000001
+TWOONE: .octa 0x00000001000000000000000000000001
+
+# order of these constants should not change.
+# more specifically, ALL_F should follow SHIFT_MASK,
+# and ZERO should follow ALL_F
+
+SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F
+MASK1: .octa 0x0000000000000000ffffffffffffffff
+MASK2: .octa 0xffffffffffffffff0000000000000000
+SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100
+ALL_F: .octa 0xffffffffffffffffffffffffffffffff
+ZERO: .octa 0x00000000000000000000000000000000
+ONE: .octa 0x00000000000000000000000000000001
+F_MIN_MASK: .octa 0xf1f2f3f4f5f6f7f8f9fafbfcfdfeff0
+dec: .octa 0x1
+enc: .octa 0x2
+
+
.text
+
+#define STACK_OFFSET 8*3
+#define HashKey 16*0 // store HashKey <<1 mod poly here
+#define HashKey_2 16*1 // store HashKey^2 <<1 mod poly here
+#define HashKey_3 16*2 // store HashKey^3 <<1 mod poly here
+#define HashKey_4 16*3 // store HashKey^4 <<1 mod poly here
+#define HashKey_k 16*4 // store XOR of High 64 bits and Low 64
+ // bits of HashKey <<1 mod poly here
+ //(for Karatsuba purposes)
+#define HashKey_2_k 16*5 // store XOR of High 64 bits and Low 64
+ // bits of HashKey^2 <<1 mod poly here
+ // (for Karatsuba purposes)
+#define HashKey_3_k 16*6 // store XOR of High 64 bits and Low 64
+ // bits of HashKey^3 <<1 mod poly here
+ // (for Karatsuba purposes)
+#define HashKey_4_k 16*7 // store XOR of High 64 bits and Low 64
+ // bits of HashKey^4 <<1 mod poly here
+ // (for Karatsuba purposes)
+#define VARIABLE_OFFSET 16*8
+
+#define arg1 rdi
+#define arg2 rsi
+#define arg3 rdx
+#define arg4 rcx
+#define arg5 r8
+#define arg6 r9
+#define arg7 STACK_OFFSET+8(%r14)
+#define arg8 STACK_OFFSET+16(%r14)
+#define arg9 STACK_OFFSET+24(%r14)
+#define arg10 STACK_OFFSET+32(%r14)
+#endif
+
+
#define STATE1 %xmm0
#define STATE2 %xmm4
#define STATE3 %xmm5
@@ -32,12 +100,16 @@
#define IN IN1
#define KEY %xmm2
#define IV %xmm3
+
#define BSWAP_MASK %xmm10
#define CTR %xmm11
#define INC %xmm12
+#ifdef __x86_64__
+#define AREG %rax
#define KEYP %rdi
#define OUTP %rsi
+#define UKEYP OUTP
#define INP %rdx
#define LEN %rcx
#define IVP %r8
@@ -46,6 +118,1588 @@
#define TKEYP T1
#define T2 %r11
#define TCTR_LOW T2
+#else
+#define AREG %eax
+#define KEYP %edi
+#define OUTP AREG
+#define UKEYP OUTP
+#define INP %edx
+#define LEN %esi
+#define IVP %ebp
+#define KLEN %ebx
+#define T1 %ecx
+#define TKEYP T1
+#endif
+
+
+#ifdef __x86_64__
+/* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
+*
+*
+* Input: A and B (128-bits each, bit-reflected)
+* Output: C = A*B*x mod poly, (i.e. >>1 )
+* To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
+* GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
+*
+*/
+.macro GHASH_MUL GH HK TMP1 TMP2 TMP3 TMP4 TMP5
+ movdqa \GH, \TMP1
+ pshufd $78, \GH, \TMP2
+ pshufd $78, \HK, \TMP3
+ pxor \GH, \TMP2 # TMP2 = a1+a0
+ pxor \HK, \TMP3 # TMP3 = b1+b0
+ PCLMULQDQ 0x11, \HK, \TMP1 # TMP1 = a1*b1
+ PCLMULQDQ 0x00, \HK, \GH # GH = a0*b0
+ PCLMULQDQ 0x00, \TMP3, \TMP2 # TMP2 = (a0+a1)*(b1+b0)
+ pxor \GH, \TMP2
+ pxor \TMP1, \TMP2 # TMP2 = (a0*b0)+(a1*b0)
+ movdqa \TMP2, \TMP3
+ pslldq $8, \TMP3 # left shift TMP3 2 DWs
+ psrldq $8, \TMP2 # right shift TMP2 2 DWs
+ pxor \TMP3, \GH
+ pxor \TMP2, \TMP1 # TMP2:GH holds the result of GH*HK
+
+ # first phase of the reduction
+
+ movdqa \GH, \TMP2
+ movdqa \GH, \TMP3
+ movdqa \GH, \TMP4 # copy GH into TMP2,TMP3 and TMP4
+ # in in order to perform
+ # independent shifts
+ pslld $31, \TMP2 # packed right shift <<31
+ pslld $30, \TMP3 # packed right shift <<30
+ pslld $25, \TMP4 # packed right shift <<25
+ pxor \TMP3, \TMP2 # xor the shifted versions
+ pxor \TMP4, \TMP2
+ movdqa \TMP2, \TMP5
+ psrldq $4, \TMP5 # right shift TMP5 1 DW
+ pslldq $12, \TMP2 # left shift TMP2 3 DWs
+ pxor \TMP2, \GH
+
+ # second phase of the reduction
+
+ movdqa \GH,\TMP2 # copy GH into TMP2,TMP3 and TMP4
+ # in in order to perform
+ # independent shifts
+ movdqa \GH,\TMP3
+ movdqa \GH,\TMP4
+ psrld $1,\TMP2 # packed left shift >>1
+ psrld $2,\TMP3 # packed left shift >>2
+ psrld $7,\TMP4 # packed left shift >>7
+ pxor \TMP3,\TMP2 # xor the shifted versions
+ pxor \TMP4,\TMP2
+ pxor \TMP5, \TMP2
+ pxor \TMP2, \GH
+ pxor \TMP1, \GH # result is in TMP1
+.endm
+
+/*
+* if a = number of total plaintext bytes
+* b = floor(a/16)
+* num_initial_blocks = b mod 4
+* encrypt the initial num_initial_blocks blocks and apply ghash on
+* the ciphertext
+* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+* are clobbered
+* arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+*/
+
+
+.macro INITIAL_BLOCKS_DEC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \
+XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ mov arg7, %r10 # %r10 = AAD
+ mov arg8, %r12 # %r12 = aadLen
+ mov %r12, %r11
+ pxor %xmm\i, %xmm\i
+_get_AAD_loop\num_initial_blocks\operation:
+ movd (%r10), \TMP1
+ pslldq $12, \TMP1
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+ sub $4, %r12
+ jne _get_AAD_loop\num_initial_blocks\operation
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+ mov $16, %r12
+_get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ sub $4, %r12
+ cmp %r11, %r12
+ jne _get_AAD_loop2\num_initial_blocks\operation
+_get_AAD_loop2_done\num_initial_blocks\operation:
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data
+
+ xor %r11, %r11 # initialise the data pointer offset as zero
+
+ # start AES for num_initial_blocks blocks
+
+ mov %arg5, %rax # %rax = *Y0
+ movdqu (%rax), \XMM0 # XMM0 = Y0
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM0
+
+.if (\i == 5) || (\i == 6) || (\i == 7)
+.irpc index, \i_seq
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, %xmm\index
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap
+
+.endr
+.irpc index, \i_seq
+ pxor 16*0(%arg1), %xmm\index
+.endr
+.irpc index, \i_seq
+ movaps 0x10(%rdi), \TMP1
+ AESENC \TMP1, %xmm\index # Round 1
+.endr
+.irpc index, \i_seq
+ movaps 0x20(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x30(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x40(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x50(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x60(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x70(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x80(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x90(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0xa0(%arg1), \TMP1
+ AESENCLAST \TMP1, %xmm\index # Round 10
+.endr
+.irpc index, \i_seq
+ movdqu (%arg3 , %r11, 1), \TMP1
+ pxor \TMP1, %xmm\index
+ movdqu %xmm\index, (%arg2 , %r11, 1)
+ # write back plaintext/ciphertext for num_initial_blocks
+ add $16, %r11
+
+ movdqa \TMP1, %xmm\index
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\index
+
+ # prepare plaintext/ciphertext for GHASH computation
+.endr
+.endif
+ GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ # apply GHASH on num_initial_blocks blocks
+
+.if \i == 5
+ pxor %xmm5, %xmm6
+ GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm6, %xmm7
+ GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.elseif \i == 6
+ pxor %xmm6, %xmm7
+ GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.elseif \i == 7
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.endif
+ cmp $64, %r13
+ jl _initial_blocks_done\num_initial_blocks\operation
+ # no need for precomputed values
+/*
+*
+* Precomputations for HashKey parallel with encryption of first 4 blocks.
+* Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
+*/
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM1
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM2
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM3
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM4
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap
+
+ pxor 16*0(%arg1), \XMM1
+ pxor 16*0(%arg1), \XMM2
+ pxor 16*0(%arg1), \XMM3
+ pxor 16*0(%arg1), \XMM4
+ movdqa \TMP3, \TMP5
+ pshufd $78, \TMP3, \TMP1
+ pxor \TMP3, \TMP1
+ movdqa \TMP1, HashKey_k(%rsp)
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^2<<1 (mod poly)
+ movdqa \TMP5, HashKey_2(%rsp)
+# HashKey_2 = HashKey^2<<1 (mod poly)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_2_k(%rsp)
+.irpc index, 1234 # do 4 rounds
+ movaps 0x10*\index(%arg1), \TMP1
+ AESENC \TMP1, \XMM1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+.endr
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^3<<1 (mod poly)
+ movdqa \TMP5, HashKey_3(%rsp)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_3_k(%rsp)
+.irpc index, 56789 # do next 5 rounds
+ movaps 0x10*\index(%arg1), \TMP1
+ AESENC \TMP1, \XMM1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+.endr
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^3<<1 (mod poly)
+ movdqa \TMP5, HashKey_4(%rsp)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_4_k(%rsp)
+ movaps 0xa0(%arg1), \TMP2
+ AESENCLAST \TMP2, \XMM1
+ AESENCLAST \TMP2, \XMM2
+ AESENCLAST \TMP2, \XMM3
+ AESENCLAST \TMP2, \XMM4
+ movdqu 16*0(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM1
+ movdqu \XMM1, 16*0(%arg2 , %r11 , 1)
+ movdqa \TMP1, \XMM1
+ movdqu 16*1(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM2
+ movdqu \XMM2, 16*1(%arg2 , %r11 , 1)
+ movdqa \TMP1, \XMM2
+ movdqu 16*2(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM3
+ movdqu \XMM3, 16*2(%arg2 , %r11 , 1)
+ movdqa \TMP1, \XMM3
+ movdqu 16*3(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM4
+ movdqu \XMM4, 16*3(%arg2 , %r11 , 1)
+ movdqa \TMP1, \XMM4
+ add $64, %r11
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap
+ pxor \XMMDst, \XMM1
+# combine GHASHed value with the corresponding ciphertext
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap
+
+_initial_blocks_done\num_initial_blocks\operation:
+
+.endm
+
+
+/*
+* if a = number of total plaintext bytes
+* b = floor(a/16)
+* num_initial_blocks = b mod 4
+* encrypt the initial num_initial_blocks blocks and apply ghash on
+* the ciphertext
+* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+* are clobbered
+* arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+*/
+
+
+.macro INITIAL_BLOCKS_ENC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \
+XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ mov arg7, %r10 # %r10 = AAD
+ mov arg8, %r12 # %r12 = aadLen
+ mov %r12, %r11
+ pxor %xmm\i, %xmm\i
+_get_AAD_loop\num_initial_blocks\operation:
+ movd (%r10), \TMP1
+ pslldq $12, \TMP1
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+ sub $4, %r12
+ jne _get_AAD_loop\num_initial_blocks\operation
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+ mov $16, %r12
+_get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ sub $4, %r12
+ cmp %r11, %r12
+ jne _get_AAD_loop2\num_initial_blocks\operation
+_get_AAD_loop2_done\num_initial_blocks\operation:
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data
+
+ xor %r11, %r11 # initialise the data pointer offset as zero
+
+ # start AES for num_initial_blocks blocks
+
+ mov %arg5, %rax # %rax = *Y0
+ movdqu (%rax), \XMM0 # XMM0 = Y0
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM0
+
+.if (\i == 5) || (\i == 6) || (\i == 7)
+.irpc index, \i_seq
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, %xmm\index
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap
+
+.endr
+.irpc index, \i_seq
+ pxor 16*0(%arg1), %xmm\index
+.endr
+.irpc index, \i_seq
+ movaps 0x10(%rdi), \TMP1
+ AESENC \TMP1, %xmm\index # Round 1
+.endr
+.irpc index, \i_seq
+ movaps 0x20(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x30(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x40(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x50(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x60(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x70(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x80(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0x90(%arg1), \TMP1
+ AESENC \TMP1, %xmm\index # Round 2
+.endr
+.irpc index, \i_seq
+ movaps 0xa0(%arg1), \TMP1
+ AESENCLAST \TMP1, %xmm\index # Round 10
+.endr
+.irpc index, \i_seq
+ movdqu (%arg3 , %r11, 1), \TMP1
+ pxor \TMP1, %xmm\index
+ movdqu %xmm\index, (%arg2 , %r11, 1)
+ # write back plaintext/ciphertext for num_initial_blocks
+ add $16, %r11
+
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, %xmm\index
+
+ # prepare plaintext/ciphertext for GHASH computation
+.endr
+.endif
+ GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ # apply GHASH on num_initial_blocks blocks
+
+.if \i == 5
+ pxor %xmm5, %xmm6
+ GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm6, %xmm7
+ GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.elseif \i == 6
+ pxor %xmm6, %xmm7
+ GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.elseif \i == 7
+ pxor %xmm7, %xmm8
+ GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1
+.endif
+ cmp $64, %r13
+ jl _initial_blocks_done\num_initial_blocks\operation
+ # no need for precomputed values
+/*
+*
+* Precomputations for HashKey parallel with encryption of first 4 blocks.
+* Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
+*/
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM1
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM2
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM3
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap
+
+ paddd ONE(%rip), \XMM0 # INCR Y0
+ movdqa \XMM0, \XMM4
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap
+
+ pxor 16*0(%arg1), \XMM1
+ pxor 16*0(%arg1), \XMM2
+ pxor 16*0(%arg1), \XMM3
+ pxor 16*0(%arg1), \XMM4
+ movdqa \TMP3, \TMP5
+ pshufd $78, \TMP3, \TMP1
+ pxor \TMP3, \TMP1
+ movdqa \TMP1, HashKey_k(%rsp)
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^2<<1 (mod poly)
+ movdqa \TMP5, HashKey_2(%rsp)
+# HashKey_2 = HashKey^2<<1 (mod poly)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_2_k(%rsp)
+.irpc index, 1234 # do 4 rounds
+ movaps 0x10*\index(%arg1), \TMP1
+ AESENC \TMP1, \XMM1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+.endr
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^3<<1 (mod poly)
+ movdqa \TMP5, HashKey_3(%rsp)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_3_k(%rsp)
+.irpc index, 56789 # do next 5 rounds
+ movaps 0x10*\index(%arg1), \TMP1
+ AESENC \TMP1, \XMM1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+.endr
+ GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
+# TMP5 = HashKey^3<<1 (mod poly)
+ movdqa \TMP5, HashKey_4(%rsp)
+ pshufd $78, \TMP5, \TMP1
+ pxor \TMP5, \TMP1
+ movdqa \TMP1, HashKey_4_k(%rsp)
+ movaps 0xa0(%arg1), \TMP2
+ AESENCLAST \TMP2, \XMM1
+ AESENCLAST \TMP2, \XMM2
+ AESENCLAST \TMP2, \XMM3
+ AESENCLAST \TMP2, \XMM4
+ movdqu 16*0(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM1
+ movdqu 16*1(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM2
+ movdqu 16*2(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM3
+ movdqu 16*3(%arg3 , %r11 , 1), \TMP1
+ pxor \TMP1, \XMM4
+ movdqu \XMM1, 16*0(%arg2 , %r11 , 1)
+ movdqu \XMM2, 16*1(%arg2 , %r11 , 1)
+ movdqu \XMM3, 16*2(%arg2 , %r11 , 1)
+ movdqu \XMM4, 16*3(%arg2 , %r11 , 1)
+
+ add $64, %r11
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap
+ pxor \XMMDst, \XMM1
+# combine GHASHed value with the corresponding ciphertext
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap
+ movdqa SHUF_MASK(%rip), %xmm14
+ PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap
+
+_initial_blocks_done\num_initial_blocks\operation:
+
+.endm
+
+/*
+* encrypt 4 blocks at a time
+* ghash the 4 previously encrypted ciphertext blocks
+* arg1, %arg2, %arg3 are used as pointers only, not modified
+* %r11 is the data offset value
+*/
+.macro GHASH_4_ENCRYPT_4_PARALLEL_ENC TMP1 TMP2 TMP3 TMP4 TMP5 \
+TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
+
+ movdqa \XMM1, \XMM5
+ movdqa \XMM2, \XMM6
+ movdqa \XMM3, \XMM7
+ movdqa \XMM4, \XMM8
+
+ movdqa SHUF_MASK(%rip), %xmm15
+ # multiply TMP5 * HashKey using karatsuba
+
+ movdqa \XMM5, \TMP4
+ pshufd $78, \XMM5, \TMP6
+ pxor \XMM5, \TMP6
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa HashKey_4(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
+ movdqa \XMM0, \XMM1
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM2
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM3
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM4
+ PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap
+ PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0
+ PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap
+
+ pxor (%arg1), \XMM1
+ pxor (%arg1), \XMM2
+ pxor (%arg1), \XMM3
+ pxor (%arg1), \XMM4
+ movdqa HashKey_4_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
+ movaps 0x10(%arg1), \TMP1
+ AESENC \TMP1, \XMM1 # Round 1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+ movaps 0x20(%arg1), \TMP1
+ AESENC \TMP1, \XMM1 # Round 2
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+ movdqa \XMM6, \TMP1
+ pshufd $78, \XMM6, \TMP2
+ pxor \XMM6, \TMP2
+ movdqa HashKey_3(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
+ movaps 0x30(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 3
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0
+ movaps 0x40(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 4
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ movdqa HashKey_3_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movaps 0x50(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 5
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ pxor \TMP1, \TMP4
+# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
+ pxor \XMM6, \XMM5
+ pxor \TMP2, \TMP6
+ movdqa \XMM7, \TMP1
+ pshufd $78, \XMM7, \TMP2
+ pxor \XMM7, \TMP2
+ movdqa HashKey_2(%rsp ), \TMP5
+
+ # Multiply TMP5 * HashKey using karatsuba
+
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ movaps 0x60(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 6
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0
+ movaps 0x70(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 7
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ movdqa HashKey_2_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movaps 0x80(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 8
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ pxor \TMP1, \TMP4
+# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
+ pxor \XMM7, \XMM5
+ pxor \TMP2, \TMP6
+
+ # Multiply XMM8 * HashKey
+ # XMM8 and TMP5 hold the values for the two operands
+
+ movdqa \XMM8, \TMP1
+ pshufd $78, \XMM8, \TMP2
+ pxor \XMM8, \TMP2
+ movdqa HashKey(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ movaps 0x90(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 9
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0
+ movaps 0xa0(%arg1), \TMP3
+ AESENCLAST \TMP3, \XMM1 # Round 10
+ AESENCLAST \TMP3, \XMM2
+ AESENCLAST \TMP3, \XMM3
+ AESENCLAST \TMP3, \XMM4
+ movdqa HashKey_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movdqu (%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
+ movdqu 16(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK
+ movdqu 32(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK
+ movdqu 48(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK
+ movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer
+ movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer
+ movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer
+ movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer
+ PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap
+
+ pxor \TMP4, \TMP1
+ pxor \XMM8, \XMM5
+ pxor \TMP6, \TMP2
+ pxor \TMP1, \TMP2
+ pxor \XMM5, \TMP2
+ movdqa \TMP2, \TMP3
+ pslldq $8, \TMP3 # left shift TMP3 2 DWs
+ psrldq $8, \TMP2 # right shift TMP2 2 DWs
+ pxor \TMP3, \XMM5
+ pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5
+
+ # first phase of reduction
+
+ movdqa \XMM5, \TMP2
+ movdqa \XMM5, \TMP3
+ movdqa \XMM5, \TMP4
+# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently
+ pslld $31, \TMP2 # packed right shift << 31
+ pslld $30, \TMP3 # packed right shift << 30
+ pslld $25, \TMP4 # packed right shift << 25
+ pxor \TMP3, \TMP2 # xor the shifted versions
+ pxor \TMP4, \TMP2
+ movdqa \TMP2, \TMP5
+ psrldq $4, \TMP5 # right shift T5 1 DW
+ pslldq $12, \TMP2 # left shift T2 3 DWs
+ pxor \TMP2, \XMM5
+
+ # second phase of reduction
+
+ movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4
+ movdqa \XMM5,\TMP3
+ movdqa \XMM5,\TMP4
+ psrld $1, \TMP2 # packed left shift >>1
+ psrld $2, \TMP3 # packed left shift >>2
+ psrld $7, \TMP4 # packed left shift >>7
+ pxor \TMP3,\TMP2 # xor the shifted versions
+ pxor \TMP4,\TMP2
+ pxor \TMP5, \TMP2
+ pxor \TMP2, \XMM5
+ pxor \TMP1, \XMM5 # result is in TMP1
+
+ pxor \XMM5, \XMM1
+.endm
+
+/*
+* decrypt 4 blocks at a time
+* ghash the 4 previously decrypted ciphertext blocks
+* arg1, %arg2, %arg3 are used as pointers only, not modified
+* %r11 is the data offset value
+*/
+.macro GHASH_4_ENCRYPT_4_PARALLEL_DEC TMP1 TMP2 TMP3 TMP4 TMP5 \
+TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
+
+ movdqa \XMM1, \XMM5
+ movdqa \XMM2, \XMM6
+ movdqa \XMM3, \XMM7
+ movdqa \XMM4, \XMM8
+
+ movdqa SHUF_MASK(%rip), %xmm15
+ # multiply TMP5 * HashKey using karatsuba
+
+ movdqa \XMM5, \TMP4
+ pshufd $78, \XMM5, \TMP6
+ pxor \XMM5, \TMP6
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa HashKey_4(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
+ movdqa \XMM0, \XMM1
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM2
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM3
+ paddd ONE(%rip), \XMM0 # INCR CNT
+ movdqa \XMM0, \XMM4
+ PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap
+ PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0
+ PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap
+
+ pxor (%arg1), \XMM1
+ pxor (%arg1), \XMM2
+ pxor (%arg1), \XMM3
+ pxor (%arg1), \XMM4
+ movdqa HashKey_4_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
+ movaps 0x10(%arg1), \TMP1
+ AESENC \TMP1, \XMM1 # Round 1
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+ movaps 0x20(%arg1), \TMP1
+ AESENC \TMP1, \XMM1 # Round 2
+ AESENC \TMP1, \XMM2
+ AESENC \TMP1, \XMM3
+ AESENC \TMP1, \XMM4
+ movdqa \XMM6, \TMP1
+ pshufd $78, \XMM6, \TMP2
+ pxor \XMM6, \TMP2
+ movdqa HashKey_3(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
+ movaps 0x30(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 3
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0
+ movaps 0x40(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 4
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ movdqa HashKey_3_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movaps 0x50(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 5
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ pxor \TMP1, \TMP4
+# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
+ pxor \XMM6, \XMM5
+ pxor \TMP2, \TMP6
+ movdqa \XMM7, \TMP1
+ pshufd $78, \XMM7, \TMP2
+ pxor \XMM7, \TMP2
+ movdqa HashKey_2(%rsp ), \TMP5
+
+ # Multiply TMP5 * HashKey using karatsuba
+
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ movaps 0x60(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 6
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0
+ movaps 0x70(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 7
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ movdqa HashKey_2_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movaps 0x80(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 8
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ pxor \TMP1, \TMP4
+# accumulate the results in TMP4:XMM5, TMP6 holds the middle part
+ pxor \XMM7, \XMM5
+ pxor \TMP2, \TMP6
+
+ # Multiply XMM8 * HashKey
+ # XMM8 and TMP5 hold the values for the two operands
+
+ movdqa \XMM8, \TMP1
+ pshufd $78, \XMM8, \TMP2
+ pxor \XMM8, \TMP2
+ movdqa HashKey(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ movaps 0x90(%arg1), \TMP3
+ AESENC \TMP3, \XMM1 # Round 9
+ AESENC \TMP3, \XMM2
+ AESENC \TMP3, \XMM3
+ AESENC \TMP3, \XMM4
+ PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0
+ movaps 0xa0(%arg1), \TMP3
+ AESENCLAST \TMP3, \XMM1 # Round 10
+ AESENCLAST \TMP3, \XMM2
+ AESENCLAST \TMP3, \XMM3
+ AESENCLAST \TMP3, \XMM4
+ movdqa HashKey_k(%rsp), \TMP5
+ PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movdqu (%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
+ movdqu \XMM1, (%arg2,%r11,1) # Write to plaintext buffer
+ movdqa \TMP3, \XMM1
+ movdqu 16(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK
+ movdqu \XMM2, 16(%arg2,%r11,1) # Write to plaintext buffer
+ movdqa \TMP3, \XMM2
+ movdqu 32(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK
+ movdqu \XMM3, 32(%arg2,%r11,1) # Write to plaintext buffer
+ movdqa \TMP3, \XMM3
+ movdqu 48(%arg3,%r11,1), \TMP3
+ pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK
+ movdqu \XMM4, 48(%arg2,%r11,1) # Write to plaintext buffer
+ movdqa \TMP3, \XMM4
+ PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap
+ PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap
+
+ pxor \TMP4, \TMP1
+ pxor \XMM8, \XMM5
+ pxor \TMP6, \TMP2
+ pxor \TMP1, \TMP2
+ pxor \XMM5, \TMP2
+ movdqa \TMP2, \TMP3
+ pslldq $8, \TMP3 # left shift TMP3 2 DWs
+ psrldq $8, \TMP2 # right shift TMP2 2 DWs
+ pxor \TMP3, \XMM5
+ pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5
+
+ # first phase of reduction
+
+ movdqa \XMM5, \TMP2
+ movdqa \XMM5, \TMP3
+ movdqa \XMM5, \TMP4
+# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently
+ pslld $31, \TMP2 # packed right shift << 31
+ pslld $30, \TMP3 # packed right shift << 30
+ pslld $25, \TMP4 # packed right shift << 25
+ pxor \TMP3, \TMP2 # xor the shifted versions
+ pxor \TMP4, \TMP2
+ movdqa \TMP2, \TMP5
+ psrldq $4, \TMP5 # right shift T5 1 DW
+ pslldq $12, \TMP2 # left shift T2 3 DWs
+ pxor \TMP2, \XMM5
+
+ # second phase of reduction
+
+ movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4
+ movdqa \XMM5,\TMP3
+ movdqa \XMM5,\TMP4
+ psrld $1, \TMP2 # packed left shift >>1
+ psrld $2, \TMP3 # packed left shift >>2
+ psrld $7, \TMP4 # packed left shift >>7
+ pxor \TMP3,\TMP2 # xor the shifted versions
+ pxor \TMP4,\TMP2
+ pxor \TMP5, \TMP2
+ pxor \TMP2, \XMM5
+ pxor \TMP1, \XMM5 # result is in TMP1
+
+ pxor \XMM5, \XMM1
+.endm
+
+/* GHASH the last 4 ciphertext blocks. */
+.macro GHASH_LAST_4 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 \
+TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
+
+ # Multiply TMP6 * HashKey (using Karatsuba)
+
+ movdqa \XMM1, \TMP6
+ pshufd $78, \XMM1, \TMP2
+ pxor \XMM1, \TMP2
+ movdqa HashKey_4(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1
+ PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0
+ movdqa HashKey_4_k(%rsp), \TMP4
+ PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ movdqa \XMM1, \XMMDst
+ movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1
+
+ # Multiply TMP1 * HashKey (using Karatsuba)
+
+ movdqa \XMM2, \TMP1
+ pshufd $78, \XMM2, \TMP2
+ pxor \XMM2, \TMP2
+ movdqa HashKey_3(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0
+ movdqa HashKey_3_k(%rsp), \TMP4
+ PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ pxor \TMP1, \TMP6
+ pxor \XMM2, \XMMDst
+ pxor \TMP2, \XMM1
+# results accumulated in TMP6, XMMDst, XMM1
+
+ # Multiply TMP1 * HashKey (using Karatsuba)
+
+ movdqa \XMM3, \TMP1
+ pshufd $78, \XMM3, \TMP2
+ pxor \XMM3, \TMP2
+ movdqa HashKey_2(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0
+ movdqa HashKey_2_k(%rsp), \TMP4
+ PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ pxor \TMP1, \TMP6
+ pxor \XMM3, \XMMDst
+ pxor \TMP2, \XMM1 # results accumulated in TMP6, XMMDst, XMM1
+
+ # Multiply TMP1 * HashKey (using Karatsuba)
+ movdqa \XMM4, \TMP1
+ pshufd $78, \XMM4, \TMP2
+ pxor \XMM4, \TMP2
+ movdqa HashKey(%rsp), \TMP5
+ PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
+ PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0
+ movdqa HashKey_k(%rsp), \TMP4
+ PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
+ pxor \TMP1, \TMP6
+ pxor \XMM4, \XMMDst
+ pxor \XMM1, \TMP2
+ pxor \TMP6, \TMP2
+ pxor \XMMDst, \TMP2
+ # middle section of the temp results combined as in karatsuba algorithm
+ movdqa \TMP2, \TMP4
+ pslldq $8, \TMP4 # left shift TMP4 2 DWs
+ psrldq $8, \TMP2 # right shift TMP2 2 DWs
+ pxor \TMP4, \XMMDst
+ pxor \TMP2, \TMP6
+# TMP6:XMMDst holds the result of the accumulated carry-less multiplications
+ # first phase of the reduction
+ movdqa \XMMDst, \TMP2
+ movdqa \XMMDst, \TMP3
+ movdqa \XMMDst, \TMP4
+# move XMMDst into TMP2, TMP3, TMP4 in order to perform 3 shifts independently
+ pslld $31, \TMP2 # packed right shifting << 31
+ pslld $30, \TMP3 # packed right shifting << 30
+ pslld $25, \TMP4 # packed right shifting << 25
+ pxor \TMP3, \TMP2 # xor the shifted versions
+ pxor \TMP4, \TMP2
+ movdqa \TMP2, \TMP7
+ psrldq $4, \TMP7 # right shift TMP7 1 DW
+ pslldq $12, \TMP2 # left shift TMP2 3 DWs
+ pxor \TMP2, \XMMDst
+
+ # second phase of the reduction
+ movdqa \XMMDst, \TMP2
+ # make 3 copies of XMMDst for doing 3 shift operations
+ movdqa \XMMDst, \TMP3
+ movdqa \XMMDst, \TMP4
+ psrld $1, \TMP2 # packed left shift >> 1
+ psrld $2, \TMP3 # packed left shift >> 2
+ psrld $7, \TMP4 # packed left shift >> 7
+ pxor \TMP3, \TMP2 # xor the shifted versions
+ pxor \TMP4, \TMP2
+ pxor \TMP7, \TMP2
+ pxor \TMP2, \XMMDst
+ pxor \TMP6, \XMMDst # reduced result is in XMMDst
+.endm
+
+/* Encryption of a single block done*/
+.macro ENCRYPT_SINGLE_BLOCK XMM0 TMP1
+
+ pxor (%arg1), \XMM0
+ movaps 16(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 32(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 48(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 64(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 80(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 96(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 112(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 128(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 144(%arg1), \TMP1
+ AESENC \TMP1, \XMM0
+ movaps 160(%arg1), \TMP1
+ AESENCLAST \TMP1, \XMM0
+.endm
+
+
+/*****************************************************************************
+* void aesni_gcm_dec(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
+* u8 *out, // Plaintext output. Encrypt in-place is allowed.
+* const u8 *in, // Ciphertext input
+* u64 plaintext_len, // Length of data in bytes for decryption.
+* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association)
+* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload)
+* // concatenated with 0x00000001. 16-byte aligned pointer.
+* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary.
+* const u8 *aad, // Additional Authentication Data (AAD)
+* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes
+* u8 *auth_tag, // Authenticated Tag output. The driver will compare this to the
+* // given authentication tag and only return the plaintext if they match.
+* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16
+* // (most likely), 12 or 8.
+*
+* Assumptions:
+*
+* keys:
+* keys are pre-expanded and aligned to 16 bytes. we are using the first
+* set of 11 keys in the data structure void *aes_ctx
+*
+* iv:
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Salt (From the SA) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Initialization Vector |
+* | (This is the sequence number from IPSec header) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x1 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+*
+*
+* AAD:
+* AAD padded to 128 bits with 0
+* for example, assume AAD is a u32 vector
+*
+* if AAD is 8 bytes:
+* AAD[3] = {A0, A1};
+* padded AAD in xmm register = {A1 A0 0 0}
+*
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | SPI (A1) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 32-bit Sequence Number (A0) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x0 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+* AAD Format with 32-bit Sequence Number
+*
+* if AAD is 12 bytes:
+* AAD[3] = {A0, A1, A2};
+* padded AAD in xmm register = {A2 A1 A0 0}
+*
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | SPI (A2) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 64-bit Extended Sequence Number {A1,A0} |
+* | |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x0 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+* AAD Format with 64-bit Extended Sequence Number
+*
+* aadLen:
+* from the definition of the spec, aadLen can only be 8 or 12 bytes.
+* The code supports 16 too but for other sizes, the code will fail.
+*
+* TLen:
+* from the definition of the spec, TLen can only be 8, 12 or 16 bytes.
+* For other sizes, the code will fail.
+*
+* poly = x^128 + x^127 + x^126 + x^121 + 1
+*
+*****************************************************************************/
+
+ENTRY(aesni_gcm_dec)
+ push %r12
+ push %r13
+ push %r14
+ mov %rsp, %r14
+/*
+* states of %xmm registers %xmm6:%xmm15 not saved
+* all %xmm registers are clobbered
+*/
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp # align rsp to 64 bytes
+ mov %arg6, %r12
+ movdqu (%r12), %xmm13 # %xmm13 = HashKey
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+
+# Precompute HashKey<<1 (mod poly) from the hash key (required for GHASH)
+
+ movdqa %xmm13, %xmm2
+ psllq $1, %xmm13
+ psrlq $63, %xmm2
+ movdqa %xmm2, %xmm1
+ pslldq $8, %xmm2
+ psrldq $8, %xmm1
+ por %xmm2, %xmm13
+
+ # Reduction
+
+ pshufd $0x24, %xmm1, %xmm2
+ pcmpeqd TWOONE(%rip), %xmm2
+ pand POLY(%rip), %xmm2
+ pxor %xmm2, %xmm13 # %xmm13 holds the HashKey<<1 (mod poly)
+
+
+ # Decrypt first few blocks
+
+ movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly)
+ mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext
+ and $-16, %r13 # %r13 = %r13 - (%r13 mod 16)
+ mov %r13, %r12
+ and $(3<<4), %r12
+ jz _initial_num_blocks_is_0_decrypt
+ cmp $(2<<4), %r12
+ jb _initial_num_blocks_is_1_decrypt
+ je _initial_num_blocks_is_2_decrypt
+_initial_num_blocks_is_3_decrypt:
+ INITIAL_BLOCKS_DEC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, dec
+ sub $48, %r13
+ jmp _initial_blocks_decrypted
+_initial_num_blocks_is_2_decrypt:
+ INITIAL_BLOCKS_DEC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, dec
+ sub $32, %r13
+ jmp _initial_blocks_decrypted
+_initial_num_blocks_is_1_decrypt:
+ INITIAL_BLOCKS_DEC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, dec
+ sub $16, %r13
+ jmp _initial_blocks_decrypted
+_initial_num_blocks_is_0_decrypt:
+ INITIAL_BLOCKS_DEC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, dec
+_initial_blocks_decrypted:
+ cmp $0, %r13
+ je _zero_cipher_left_decrypt
+ sub $64, %r13
+ je _four_cipher_left_decrypt
+_decrypt_by_4:
+ GHASH_4_ENCRYPT_4_PARALLEL_DEC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \
+%xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, dec
+ add $64, %r11
+ sub $64, %r13
+ jne _decrypt_by_4
+_four_cipher_left_decrypt:
+ GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \
+%xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8
+_zero_cipher_left_decrypt:
+ mov %arg4, %r13
+ and $15, %r13 # %r13 = arg4 (mod 16)
+ je _multiple_of_16_bytes_decrypt
+
+ # Handle the last <16 byte block seperately
+
+ paddd ONE(%rip), %xmm0 # increment CNT to get Yn
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm0
+
+ ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Yn)
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # recieve the last <16 byte block
+ lea SHIFT_MASK+16(%rip), %r12
+ sub %r13, %r12
+# adjust the shuffle mask pointer to be able to shift 16-%r13 bytes
+# (%r13 is the number of bytes in plaintext mod 16)
+ movdqu (%r12), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes
+
+ movdqa %xmm1, %xmm2
+ pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn)
+ movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
+ # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm2
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10 ,%xmm2
+
+ pxor %xmm2, %xmm8
+ GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
+ # GHASH computation for the last <16 byte block
+ sub %r13, %r11
+ add $16, %r11
+
+ # output %r13 bytes
+ MOVQ_R64_XMM %xmm0, %rax
+ cmp $8, %r13
+ jle _less_than_8_bytes_left_decrypt
+ mov %rax, (%arg2 , %r11, 1)
+ add $8, %r11
+ psrldq $8, %xmm0
+ MOVQ_R64_XMM %xmm0, %rax
+ sub $8, %r13
+_less_than_8_bytes_left_decrypt:
+ mov %al, (%arg2, %r11, 1)
+ add $1, %r11
+ shr $8, %rax
+ sub $1, %r13
+ jne _less_than_8_bytes_left_decrypt
+_multiple_of_16_bytes_decrypt:
+ mov arg8, %r12 # %r13 = aadLen (number of bytes)
+ shl $3, %r12 # convert into number of bits
+ movd %r12d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+ pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C)
+ pxor %xmm15, %xmm8
+ GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
+ # final GHASH computation
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm8
+
+ mov %arg5, %rax # %rax = *Y0
+ movdqu (%rax), %xmm0 # %xmm0 = Y0
+ ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0)
+ pxor %xmm8, %xmm0
+_return_T_decrypt:
+ mov arg9, %r10 # %r10 = authTag
+ mov arg10, %r11 # %r11 = auth_tag_len
+ cmp $16, %r11
+ je _T_16_decrypt
+ cmp $12, %r11
+ je _T_12_decrypt
+_T_8_decrypt:
+ MOVQ_R64_XMM %xmm0, %rax
+ mov %rax, (%r10)
+ jmp _return_T_done_decrypt
+_T_12_decrypt:
+ MOVQ_R64_XMM %xmm0, %rax
+ mov %rax, (%r10)
+ psrldq $8, %xmm0
+ movd %xmm0, %eax
+ mov %eax, 8(%r10)
+ jmp _return_T_done_decrypt
+_T_16_decrypt:
+ movdqu %xmm0, (%r10)
+_return_T_done_decrypt:
+ mov %r14, %rsp
+ pop %r14
+ pop %r13
+ pop %r12
+ ret
+
+
+/*****************************************************************************
+* void aesni_gcm_enc(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary.
+* u8 *out, // Ciphertext output. Encrypt in-place is allowed.
+* const u8 *in, // Plaintext input
+* u64 plaintext_len, // Length of data in bytes for encryption.
+* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association)
+* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload)
+* // concatenated with 0x00000001. 16-byte aligned pointer.
+* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary.
+* const u8 *aad, // Additional Authentication Data (AAD)
+* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes
+* u8 *auth_tag, // Authenticated Tag output.
+* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely),
+* // 12 or 8.
+*
+* Assumptions:
+*
+* keys:
+* keys are pre-expanded and aligned to 16 bytes. we are using the
+* first set of 11 keys in the data structure void *aes_ctx
+*
+*
+* iv:
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Salt (From the SA) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Initialization Vector |
+* | (This is the sequence number from IPSec header) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x1 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+*
+*
+* AAD:
+* AAD padded to 128 bits with 0
+* for example, assume AAD is a u32 vector
+*
+* if AAD is 8 bytes:
+* AAD[3] = {A0, A1};
+* padded AAD in xmm register = {A1 A0 0 0}
+*
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | SPI (A1) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 32-bit Sequence Number (A0) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x0 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+* AAD Format with 32-bit Sequence Number
+*
+* if AAD is 12 bytes:
+* AAD[3] = {A0, A1, A2};
+* padded AAD in xmm register = {A2 A1 A0 0}
+*
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | SPI (A2) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 64-bit Extended Sequence Number {A1,A0} |
+* | |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | 0x0 |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+* AAD Format with 64-bit Extended Sequence Number
+*
+* aadLen:
+* from the definition of the spec, aadLen can only be 8 or 12 bytes.
+* The code supports 16 too but for other sizes, the code will fail.
+*
+* TLen:
+* from the definition of the spec, TLen can only be 8, 12 or 16 bytes.
+* For other sizes, the code will fail.
+*
+* poly = x^128 + x^127 + x^126 + x^121 + 1
+***************************************************************************/
+ENTRY(aesni_gcm_enc)
+ push %r12
+ push %r13
+ push %r14
+ mov %rsp, %r14
+#
+# states of %xmm registers %xmm6:%xmm15 not saved
+# all %xmm registers are clobbered
+#
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp
+ mov %arg6, %r12
+ movdqu (%r12), %xmm13
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+
+# precompute HashKey<<1 mod poly from the HashKey (required for GHASH)
+
+ movdqa %xmm13, %xmm2
+ psllq $1, %xmm13
+ psrlq $63, %xmm2
+ movdqa %xmm2, %xmm1
+ pslldq $8, %xmm2
+ psrldq $8, %xmm1
+ por %xmm2, %xmm13
+
+ # reduce HashKey<<1
+
+ pshufd $0x24, %xmm1, %xmm2
+ pcmpeqd TWOONE(%rip), %xmm2
+ pand POLY(%rip), %xmm2
+ pxor %xmm2, %xmm13
+ movdqa %xmm13, HashKey(%rsp)
+ mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly)
+ and $-16, %r13
+ mov %r13, %r12
+
+ # Encrypt first few blocks
+
+ and $(3<<4), %r12
+ jz _initial_num_blocks_is_0_encrypt
+ cmp $(2<<4), %r12
+ jb _initial_num_blocks_is_1_encrypt
+ je _initial_num_blocks_is_2_encrypt
+_initial_num_blocks_is_3_encrypt:
+ INITIAL_BLOCKS_ENC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, enc
+ sub $48, %r13
+ jmp _initial_blocks_encrypted
+_initial_num_blocks_is_2_encrypt:
+ INITIAL_BLOCKS_ENC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, enc
+ sub $32, %r13
+ jmp _initial_blocks_encrypted
+_initial_num_blocks_is_1_encrypt:
+ INITIAL_BLOCKS_ENC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, enc
+ sub $16, %r13
+ jmp _initial_blocks_encrypted
+_initial_num_blocks_is_0_encrypt:
+ INITIAL_BLOCKS_ENC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \
+%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, enc
+_initial_blocks_encrypted:
+
+ # Main loop - Encrypt remaining blocks
+
+ cmp $0, %r13
+ je _zero_cipher_left_encrypt
+ sub $64, %r13
+ je _four_cipher_left_encrypt
+_encrypt_by_4_encrypt:
+ GHASH_4_ENCRYPT_4_PARALLEL_ENC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \
+%xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, enc
+ add $64, %r11
+ sub $64, %r13
+ jne _encrypt_by_4_encrypt
+_four_cipher_left_encrypt:
+ GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \
+%xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8
+_zero_cipher_left_encrypt:
+ mov %arg4, %r13
+ and $15, %r13 # %r13 = arg4 (mod 16)
+ je _multiple_of_16_bytes_encrypt
+
+ # Handle the last <16 Byte block seperately
+ paddd ONE(%rip), %xmm0 # INCR CNT to get Yn
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm0
+
+ ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn)
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks
+ lea SHIFT_MASK+16(%rip), %r12
+ sub %r13, %r12
+ # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
+ # (%r13 is the number of bytes in plaintext mod 16)
+ movdqu (%r12), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte
+ pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn)
+ movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
+ # get the appropriate mask to mask out top 16-r13 bytes of xmm0
+ pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10,%xmm0
+
+ pxor %xmm0, %xmm8
+ GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
+ # GHASH computation for the last <16 byte block
+ sub %r13, %r11
+ add $16, %r11
+ PSHUFB_XMM %xmm10, %xmm1
+
+ # shuffle xmm0 back to output as ciphertext
+
+ # Output %r13 bytes
+ MOVQ_R64_XMM %xmm0, %rax
+ cmp $8, %r13
+ jle _less_than_8_bytes_left_encrypt
+ mov %rax, (%arg2 , %r11, 1)
+ add $8, %r11
+ psrldq $8, %xmm0
+ MOVQ_R64_XMM %xmm0, %rax
+ sub $8, %r13
+_less_than_8_bytes_left_encrypt:
+ mov %al, (%arg2, %r11, 1)
+ add $1, %r11
+ shr $8, %rax
+ sub $1, %r13
+ jne _less_than_8_bytes_left_encrypt
+_multiple_of_16_bytes_encrypt:
+ mov arg8, %r12 # %r12 = addLen (number of bytes)
+ shl $3, %r12
+ movd %r12d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+ pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C)
+ pxor %xmm15, %xmm8
+ GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6
+ # final GHASH computation
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm8 # perform a 16 byte swap
+
+ mov %arg5, %rax # %rax = *Y0
+ movdqu (%rax), %xmm0 # %xmm0 = Y0
+ ENCRYPT_SINGLE_BLOCK %xmm0, %xmm15 # Encrypt(K, Y0)
+ pxor %xmm8, %xmm0
+_return_T_encrypt:
+ mov arg9, %r10 # %r10 = authTag
+ mov arg10, %r11 # %r11 = auth_tag_len
+ cmp $16, %r11
+ je _T_16_encrypt
+ cmp $12, %r11
+ je _T_12_encrypt
+_T_8_encrypt:
+ MOVQ_R64_XMM %xmm0, %rax
+ mov %rax, (%r10)
+ jmp _return_T_done_encrypt
+_T_12_encrypt:
+ MOVQ_R64_XMM %xmm0, %rax
+ mov %rax, (%r10)
+ psrldq $8, %xmm0
+ movd %xmm0, %eax
+ mov %eax, 8(%r10)
+ jmp _return_T_done_encrypt
+_T_16_encrypt:
+ movdqu %xmm0, (%r10)
+_return_T_done_encrypt:
+ mov %r14, %rsp
+ pop %r14
+ pop %r13
+ pop %r12
+ ret
+
+#endif
+
_key_expansion_128:
_key_expansion_256a:
@@ -55,10 +1709,11 @@ _key_expansion_256a:
shufps $0b10001100, %xmm0, %xmm4
pxor %xmm4, %xmm0
pxor %xmm1, %xmm0
- movaps %xmm0, (%rcx)
- add $0x10, %rcx
+ movaps %xmm0, (TKEYP)
+ add $0x10, TKEYP
ret
+.align 4
_key_expansion_192a:
pshufd $0b01010101, %xmm1, %xmm1
shufps $0b00010000, %xmm0, %xmm4
@@ -76,12 +1731,13 @@ _key_expansion_192a:
movaps %xmm0, %xmm1
shufps $0b01000100, %xmm0, %xmm6
- movaps %xmm6, (%rcx)
+ movaps %xmm6, (TKEYP)
shufps $0b01001110, %xmm2, %xmm1
- movaps %xmm1, 16(%rcx)
- add $0x20, %rcx
+ movaps %xmm1, 0x10(TKEYP)
+ add $0x20, TKEYP
ret
+.align 4
_key_expansion_192b:
pshufd $0b01010101, %xmm1, %xmm1
shufps $0b00010000, %xmm0, %xmm4
@@ -96,10 +1752,11 @@ _key_expansion_192b:
pxor %xmm3, %xmm2
pxor %xmm5, %xmm2
- movaps %xmm0, (%rcx)
- add $0x10, %rcx
+ movaps %xmm0, (TKEYP)
+ add $0x10, TKEYP
ret
+.align 4
_key_expansion_256b:
pshufd $0b10101010, %xmm1, %xmm1
shufps $0b00010000, %xmm2, %xmm4
@@ -107,8 +1764,8 @@ _key_expansion_256b:
shufps $0b10001100, %xmm2, %xmm4
pxor %xmm4, %xmm2
pxor %xmm1, %xmm2
- movaps %xmm2, (%rcx)
- add $0x10, %rcx
+ movaps %xmm2, (TKEYP)
+ add $0x10, TKEYP
ret
/*
@@ -116,17 +1773,23 @@ _key_expansion_256b:
* unsigned int key_len)
*/
ENTRY(aesni_set_key)
- movups (%rsi), %xmm0 # user key (first 16 bytes)
- movaps %xmm0, (%rdi)
- lea 0x10(%rdi), %rcx # key addr
- movl %edx, 480(%rdi)
+#ifndef __x86_64__
+ pushl KEYP
+ movl 8(%esp), KEYP # ctx
+ movl 12(%esp), UKEYP # in_key
+ movl 16(%esp), %edx # key_len
+#endif
+ movups (UKEYP), %xmm0 # user key (first 16 bytes)
+ movaps %xmm0, (KEYP)
+ lea 0x10(KEYP), TKEYP # key addr
+ movl %edx, 480(KEYP)
pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x
cmp $24, %dl
jb .Lenc_key128
je .Lenc_key192
- movups 0x10(%rsi), %xmm2 # other user key
- movaps %xmm2, (%rcx)
- add $0x10, %rcx
+ movups 0x10(UKEYP), %xmm2 # other user key
+ movaps %xmm2, (TKEYP)
+ add $0x10, TKEYP
AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1
call _key_expansion_256a
AESKEYGENASSIST 0x1 %xmm0 %xmm1
@@ -155,7 +1818,7 @@ ENTRY(aesni_set_key)
call _key_expansion_256a
jmp .Ldec_key
.Lenc_key192:
- movq 0x10(%rsi), %xmm2 # other user key
+ movq 0x10(UKEYP), %xmm2 # other user key
AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1
call _key_expansion_192a
AESKEYGENASSIST 0x2 %xmm2 %xmm1 # round 2
@@ -195,33 +1858,47 @@ ENTRY(aesni_set_key)
AESKEYGENASSIST 0x36 %xmm0 %xmm1 # round 10
call _key_expansion_128
.Ldec_key:
- sub $0x10, %rcx
- movaps (%rdi), %xmm0
- movaps (%rcx), %xmm1
- movaps %xmm0, 240(%rcx)
- movaps %xmm1, 240(%rdi)
- add $0x10, %rdi
- lea 240-16(%rcx), %rsi
+ sub $0x10, TKEYP
+ movaps (KEYP), %xmm0
+ movaps (TKEYP), %xmm1
+ movaps %xmm0, 240(TKEYP)
+ movaps %xmm1, 240(KEYP)
+ add $0x10, KEYP
+ lea 240-16(TKEYP), UKEYP
.align 4
.Ldec_key_loop:
- movaps (%rdi), %xmm0
+ movaps (KEYP), %xmm0
AESIMC %xmm0 %xmm1
- movaps %xmm1, (%rsi)
- add $0x10, %rdi
- sub $0x10, %rsi
- cmp %rcx, %rdi
+ movaps %xmm1, (UKEYP)
+ add $0x10, KEYP
+ sub $0x10, UKEYP
+ cmp TKEYP, KEYP
jb .Ldec_key_loop
- xor %rax, %rax
+ xor AREG, AREG
+#ifndef __x86_64__
+ popl KEYP
+#endif
ret
/*
* void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
*/
ENTRY(aesni_enc)
+#ifndef __x86_64__
+ pushl KEYP
+ pushl KLEN
+ movl 12(%esp), KEYP
+ movl 16(%esp), OUTP
+ movl 20(%esp), INP
+#endif
movl 480(KEYP), KLEN # key length
movups (INP), STATE # input
call _aesni_enc1
movups STATE, (OUTP) # output
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+#endif
ret
/*
@@ -236,6 +1913,7 @@ ENTRY(aesni_enc)
* KEY
* TKEYP (T1)
*/
+.align 4
_aesni_enc1:
movaps (KEYP), KEY # key
mov KEYP, TKEYP
@@ -298,6 +1976,7 @@ _aesni_enc1:
* KEY
* TKEYP (T1)
*/
+.align 4
_aesni_enc4:
movaps (KEYP), KEY # key
mov KEYP, TKEYP
@@ -391,11 +2070,22 @@ _aesni_enc4:
* void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
*/
ENTRY(aesni_dec)
+#ifndef __x86_64__
+ pushl KEYP
+ pushl KLEN
+ movl 12(%esp), KEYP
+ movl 16(%esp), OUTP
+ movl 20(%esp), INP
+#endif
mov 480(KEYP), KLEN # key length
add $240, KEYP
movups (INP), STATE # input
call _aesni_dec1
movups STATE, (OUTP) #output
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+#endif
ret
/*
@@ -410,6 +2100,7 @@ ENTRY(aesni_dec)
* KEY
* TKEYP (T1)
*/
+.align 4
_aesni_dec1:
movaps (KEYP), KEY # key
mov KEYP, TKEYP
@@ -472,6 +2163,7 @@ _aesni_dec1:
* KEY
* TKEYP (T1)
*/
+.align 4
_aesni_dec4:
movaps (KEYP), KEY # key
mov KEYP, TKEYP
@@ -566,6 +2258,15 @@ _aesni_dec4:
* size_t len)
*/
ENTRY(aesni_ecb_enc)
+#ifndef __x86_64__
+ pushl LEN
+ pushl KEYP
+ pushl KLEN
+ movl 16(%esp), KEYP
+ movl 20(%esp), OUTP
+ movl 24(%esp), INP
+ movl 28(%esp), LEN
+#endif
test LEN, LEN # check length
jz .Lecb_enc_ret
mov 480(KEYP), KLEN
@@ -602,6 +2303,11 @@ ENTRY(aesni_ecb_enc)
cmp $16, LEN
jge .Lecb_enc_loop1
.Lecb_enc_ret:
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+ popl LEN
+#endif
ret
/*
@@ -609,6 +2315,15 @@ ENTRY(aesni_ecb_enc)
* size_t len);
*/
ENTRY(aesni_ecb_dec)
+#ifndef __x86_64__
+ pushl LEN
+ pushl KEYP
+ pushl KLEN
+ movl 16(%esp), KEYP
+ movl 20(%esp), OUTP
+ movl 24(%esp), INP
+ movl 28(%esp), LEN
+#endif
test LEN, LEN
jz .Lecb_dec_ret
mov 480(KEYP), KLEN
@@ -646,6 +2361,11 @@ ENTRY(aesni_ecb_dec)
cmp $16, LEN
jge .Lecb_dec_loop1
.Lecb_dec_ret:
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+ popl LEN
+#endif
ret
/*
@@ -653,6 +2373,17 @@ ENTRY(aesni_ecb_dec)
* size_t len, u8 *iv)
*/
ENTRY(aesni_cbc_enc)
+#ifndef __x86_64__
+ pushl IVP
+ pushl LEN
+ pushl KEYP
+ pushl KLEN
+ movl 20(%esp), KEYP
+ movl 24(%esp), OUTP
+ movl 28(%esp), INP
+ movl 32(%esp), LEN
+ movl 36(%esp), IVP
+#endif
cmp $16, LEN
jb .Lcbc_enc_ret
mov 480(KEYP), KLEN
@@ -670,6 +2401,12 @@ ENTRY(aesni_cbc_enc)
jge .Lcbc_enc_loop
movups STATE, (IVP)
.Lcbc_enc_ret:
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+ popl LEN
+ popl IVP
+#endif
ret
/*
@@ -677,6 +2414,17 @@ ENTRY(aesni_cbc_enc)
* size_t len, u8 *iv)
*/
ENTRY(aesni_cbc_dec)
+#ifndef __x86_64__
+ pushl IVP
+ pushl LEN
+ pushl KEYP
+ pushl KLEN
+ movl 20(%esp), KEYP
+ movl 24(%esp), OUTP
+ movl 28(%esp), INP
+ movl 32(%esp), LEN
+ movl 36(%esp), IVP
+#endif
cmp $16, LEN
jb .Lcbc_dec_just_ret
mov 480(KEYP), KLEN
@@ -690,16 +2438,30 @@ ENTRY(aesni_cbc_dec)
movaps IN1, STATE1
movups 0x10(INP), IN2
movaps IN2, STATE2
+#ifdef __x86_64__
movups 0x20(INP), IN3
movaps IN3, STATE3
movups 0x30(INP), IN4
movaps IN4, STATE4
+#else
+ movups 0x20(INP), IN1
+ movaps IN1, STATE3
+ movups 0x30(INP), IN2
+ movaps IN2, STATE4
+#endif
call _aesni_dec4
pxor IV, STATE1
+#ifdef __x86_64__
pxor IN1, STATE2
pxor IN2, STATE3
pxor IN3, STATE4
movaps IN4, IV
+#else
+ pxor (INP), STATE2
+ pxor 0x10(INP), STATE3
+ pxor IN1, STATE4
+ movaps IN2, IV
+#endif
movups STATE1, (OUTP)
movups STATE2, 0x10(OUTP)
movups STATE3, 0x20(OUTP)
@@ -727,8 +2489,15 @@ ENTRY(aesni_cbc_dec)
.Lcbc_dec_ret:
movups IV, (IVP)
.Lcbc_dec_just_ret:
+#ifndef __x86_64__
+ popl KLEN
+ popl KEYP
+ popl LEN
+ popl IVP
+#endif
ret
+#ifdef __x86_64__
.align 16
.Lbswap_mask:
.byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
@@ -744,6 +2513,7 @@ ENTRY(aesni_cbc_dec)
* INC: == 1, in little endian
* BSWAP_MASK == endian swapping mask
*/
+.align 4
_aesni_inc_init:
movaps .Lbswap_mask, BSWAP_MASK
movaps IV, CTR
@@ -768,6 +2538,7 @@ _aesni_inc_init:
* CTR: == output IV, in little endian
* TCTR_LOW: == lower qword of CTR
*/
+.align 4
_aesni_inc:
paddq INC, CTR
add $1, TCTR_LOW
@@ -839,3 +2610,4 @@ ENTRY(aesni_ctr_enc)
movups IV, (IVP)
.Lctr_enc_just_ret:
ret
+#endif
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 2cb3dcc4490a..e1e60c7d5813 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -5,6 +5,14 @@
* Copyright (C) 2008, Intel Corp.
* Author: Huang Ying <ying.huang@intel.com>
*
+ * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
+ * interface for 64-bit kernels.
+ * Authors: Adrian Hoban <adrian.hoban@intel.com>
+ * Gabriele Paoloni <gabriele.paoloni@intel.com>
+ * Tadeusz Struk (tadeusz.struk@intel.com)
+ * Aidan O'Mahony (aidan.o.mahony@intel.com)
+ * Copyright (c) 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 as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -21,6 +29,10 @@
#include <crypto/ctr.h>
#include <asm/i387.h>
#include <asm/aes.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/internal/aead.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
#if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE)
#define HAS_CTR
@@ -42,8 +54,31 @@ struct async_aes_ctx {
struct cryptd_ablkcipher *cryptd_tfm;
};
-#define AESNI_ALIGN 16
+/* This data is stored at the end of the crypto_tfm struct.
+ * It's a type of per "session" data storage location.
+ * This needs to be 16 byte aligned.
+ */
+struct aesni_rfc4106_gcm_ctx {
+ u8 hash_subkey[16];
+ struct crypto_aes_ctx aes_key_expanded;
+ u8 nonce[4];
+ struct cryptd_aead *cryptd_tfm;
+};
+
+struct aesni_gcm_set_hash_subkey_result {
+ int err;
+ struct completion completion;
+};
+
+struct aesni_hash_subkey_req_data {
+ u8 iv[16];
+ struct aesni_gcm_set_hash_subkey_result result;
+ struct scatterlist sg;
+};
+
+#define AESNI_ALIGN (16)
#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1))
+#define RFC4106_HASH_SUBKEY_SIZE 16
asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
unsigned int key_len);
@@ -59,9 +94,62 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
const u8 *in, unsigned int len, u8 *iv);
asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
const u8 *in, unsigned int len, u8 *iv);
+#ifdef CONFIG_X86_64
asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out,
const u8 *in, unsigned int len, u8 *iv);
+/* asmlinkage void aesni_gcm_enc()
+ * void *ctx, AES Key schedule. Starts on a 16 byte boundary.
+ * u8 *out, Ciphertext output. Encrypt in-place is allowed.
+ * const u8 *in, Plaintext input
+ * unsigned long plaintext_len, Length of data in bytes for encryption.
+ * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association)
+ * concatenated with 8 byte Initialisation Vector (from IPSec ESP
+ * Payload) concatenated with 0x00000001. 16-byte aligned pointer.
+ * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary.
+ * const u8 *aad, Additional Authentication Data (AAD)
+ * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this
+ * is going to be 8 or 12 bytes
+ * u8 *auth_tag, Authenticated Tag output.
+ * unsigned long auth_tag_len), Authenticated Tag Length in bytes.
+ * Valid values are 16 (most likely), 12 or 8.
+ */
+asmlinkage void aesni_gcm_enc(void *ctx, u8 *out,
+ const u8 *in, unsigned long plaintext_len, u8 *iv,
+ u8 *hash_subkey, const u8 *aad, unsigned long aad_len,
+ u8 *auth_tag, unsigned long auth_tag_len);
+
+/* asmlinkage void aesni_gcm_dec()
+ * void *ctx, AES Key schedule. Starts on a 16 byte boundary.
+ * u8 *out, Plaintext output. Decrypt in-place is allowed.
+ * const u8 *in, Ciphertext input
+ * unsigned long ciphertext_len, Length of data in bytes for decryption.
+ * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association)
+ * concatenated with 8 byte Initialisation Vector (from IPSec ESP
+ * Payload) concatenated with 0x00000001. 16-byte aligned pointer.
+ * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary.
+ * const u8 *aad, Additional Authentication Data (AAD)
+ * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this is going
+ * to be 8 or 12 bytes
+ * u8 *auth_tag, Authenticated Tag output.
+ * unsigned long auth_tag_len) Authenticated Tag Length in bytes.
+ * Valid values are 16 (most likely), 12 or 8.
+ */
+asmlinkage void aesni_gcm_dec(void *ctx, u8 *out,
+ const u8 *in, unsigned long ciphertext_len, u8 *iv,
+ u8 *hash_subkey, const u8 *aad, unsigned long aad_len,
+ u8 *auth_tag, unsigned long auth_tag_len);
+
+static inline struct
+aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm)
+{
+ return
+ (struct aesni_rfc4106_gcm_ctx *)
+ PTR_ALIGN((u8 *)
+ crypto_tfm_ctx(crypto_aead_tfm(tfm)), AESNI_ALIGN);
+}
+#endif
+
static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
{
unsigned long addr = (unsigned long)raw_ctx;
@@ -324,6 +412,7 @@ static struct crypto_alg blk_cbc_alg = {
},
};
+#ifdef CONFIG_X86_64
static void ctr_crypt_final(struct crypto_aes_ctx *ctx,
struct blkcipher_walk *walk)
{
@@ -389,6 +478,7 @@ static struct crypto_alg blk_ctr_alg = {
},
},
};
+#endif
static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
unsigned int key_len)
@@ -536,6 +626,7 @@ static struct crypto_alg ablk_cbc_alg = {
},
};
+#ifdef CONFIG_X86_64
static int ablk_ctr_init(struct crypto_tfm *tfm)
{
struct cryptd_ablkcipher *cryptd_tfm;
@@ -612,6 +703,7 @@ static struct crypto_alg ablk_rfc3686_ctr_alg = {
},
};
#endif
+#endif
#ifdef HAS_LRW
static int ablk_lrw_init(struct crypto_tfm *tfm)
@@ -730,6 +822,424 @@ static struct crypto_alg ablk_xts_alg = {
};
#endif
+#ifdef CONFIG_X86_64
+static int rfc4106_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_aead *cryptd_tfm;
+ struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *)
+ PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
+ cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ctx->cryptd_tfm = cryptd_tfm;
+ tfm->crt_aead.reqsize = sizeof(struct aead_request)
+ + crypto_aead_reqsize(&cryptd_tfm->base);
+ return 0;
+}
+
+static void rfc4106_exit(struct crypto_tfm *tfm)
+{
+ struct aesni_rfc4106_gcm_ctx *ctx =
+ (struct aesni_rfc4106_gcm_ctx *)
+ PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
+ if (!IS_ERR(ctx->cryptd_tfm))
+ cryptd_free_aead(ctx->cryptd_tfm);
+ return;
+}
+
+static void
+rfc4106_set_hash_subkey_done(struct crypto_async_request *req, int err)
+{
+ struct aesni_gcm_set_hash_subkey_result *result = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+ result->err = err;
+ complete(&result->completion);
+}
+
+static int
+rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
+{
+ struct crypto_ablkcipher *ctr_tfm;
+ struct ablkcipher_request *req;
+ int ret = -EINVAL;
+ struct aesni_hash_subkey_req_data *req_data;
+
+ ctr_tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, 0);
+ if (IS_ERR(ctr_tfm))
+ return PTR_ERR(ctr_tfm);
+
+ crypto_ablkcipher_clear_flags(ctr_tfm, ~0);
+
+ ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len);
+ if (ret) {
+ crypto_free_ablkcipher(ctr_tfm);
+ return ret;
+ }
+
+ req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL);
+ if (!req) {
+ crypto_free_ablkcipher(ctr_tfm);
+ return -EINVAL;
+ }
+
+ req_data = kmalloc(sizeof(*req_data), GFP_KERNEL);
+ if (!req_data) {
+ crypto_free_ablkcipher(ctr_tfm);
+ return -ENOMEM;
+ }
+ memset(req_data->iv, 0, sizeof(req_data->iv));
+
+ /* Clear the data in the hash sub key container to zero.*/
+ /* We want to cipher all zeros to create the hash sub key. */
+ memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE);
+
+ init_completion(&req_data->result.completion);
+ sg_init_one(&req_data->sg, hash_subkey, RFC4106_HASH_SUBKEY_SIZE);
+ ablkcipher_request_set_tfm(req, ctr_tfm);
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
+ CRYPTO_TFM_REQ_MAY_BACKLOG,
+ rfc4106_set_hash_subkey_done,
+ &req_data->result);
+
+ ablkcipher_request_set_crypt(req, &req_data->sg,
+ &req_data->sg, RFC4106_HASH_SUBKEY_SIZE, req_data->iv);
+
+ ret = crypto_ablkcipher_encrypt(req);
+ if (ret == -EINPROGRESS || ret == -EBUSY) {
+ ret = wait_for_completion_interruptible
+ (&req_data->result.completion);
+ if (!ret)
+ ret = req_data->result.err;
+ }
+ ablkcipher_request_free(req);
+ kfree(req_data);
+ crypto_free_ablkcipher(ctr_tfm);
+ return ret;
+}
+
+static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
+ unsigned int key_len)
+{
+ int ret = 0;
+ struct crypto_tfm *tfm = crypto_aead_tfm(parent);
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+ u8 *new_key_mem = NULL;
+
+ if (key_len < 4) {
+ crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+ /*Account for 4 byte nonce at the end.*/
+ key_len -= 4;
+ if (key_len != AES_KEYSIZE_128) {
+ crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce));
+ /*This must be on a 16 byte boundary!*/
+ if ((unsigned long)(&(ctx->aes_key_expanded.key_enc[0])) % AESNI_ALIGN)
+ return -EINVAL;
+
+ if ((unsigned long)key % AESNI_ALIGN) {
+ /*key is not aligned: use an auxuliar aligned pointer*/
+ new_key_mem = kmalloc(key_len+AESNI_ALIGN, GFP_KERNEL);
+ if (!new_key_mem)
+ return -ENOMEM;
+
+ new_key_mem = PTR_ALIGN(new_key_mem, AESNI_ALIGN);
+ memcpy(new_key_mem, key, key_len);
+ key = new_key_mem;
+ }
+
+ if (!irq_fpu_usable())
+ ret = crypto_aes_expand_key(&(ctx->aes_key_expanded),
+ key, key_len);
+ else {
+ kernel_fpu_begin();
+ ret = aesni_set_key(&(ctx->aes_key_expanded), key, key_len);
+ kernel_fpu_end();
+ }
+ /*This must be on a 16 byte boundary!*/
+ if ((unsigned long)(&(ctx->hash_subkey[0])) % AESNI_ALIGN) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
+exit:
+ kfree(new_key_mem);
+ return ret;
+}
+
+/* This is the Integrity Check Value (aka the authentication tag length and can
+ * be 8, 12 or 16 bytes long. */
+static int rfc4106_set_authsize(struct crypto_aead *parent,
+ unsigned int authsize)
+{
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+
+ switch (authsize) {
+ case 8:
+ case 12:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+ crypto_aead_crt(parent)->authsize = authsize;
+ crypto_aead_crt(cryptd_child)->authsize = authsize;
+ return 0;
+}
+
+static int rfc4106_encrypt(struct aead_request *req)
+{
+ int ret;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+
+ if (!irq_fpu_usable()) {
+ struct aead_request *cryptd_req =
+ (struct aead_request *) aead_request_ctx(req);
+ memcpy(cryptd_req, req, sizeof(*req));
+ aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+ return crypto_aead_encrypt(cryptd_req);
+ } else {
+ kernel_fpu_begin();
+ ret = cryptd_child->base.crt_aead.encrypt(req);
+ kernel_fpu_end();
+ return ret;
+ }
+}
+
+static int rfc4106_decrypt(struct aead_request *req)
+{
+ int ret;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+
+ if (!irq_fpu_usable()) {
+ struct aead_request *cryptd_req =
+ (struct aead_request *) aead_request_ctx(req);
+ memcpy(cryptd_req, req, sizeof(*req));
+ aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+ return crypto_aead_decrypt(cryptd_req);
+ } else {
+ kernel_fpu_begin();
+ ret = cryptd_child->base.crt_aead.decrypt(req);
+ kernel_fpu_end();
+ return ret;
+ }
+}
+
+static struct crypto_alg rfc4106_alg = {
+ .cra_name = "rfc4106(gcm(aes))",
+ .cra_driver_name = "rfc4106-gcm-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN,
+ .cra_alignmask = 0,
+ .cra_type = &crypto_nivaead_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(rfc4106_alg.cra_list),
+ .cra_init = rfc4106_init,
+ .cra_exit = rfc4106_exit,
+ .cra_u = {
+ .aead = {
+ .setkey = rfc4106_set_key,
+ .setauthsize = rfc4106_set_authsize,
+ .encrypt = rfc4106_encrypt,
+ .decrypt = rfc4106_decrypt,
+ .geniv = "seqiv",
+ .ivsize = 8,
+ .maxauthsize = 16,
+ },
+ },
+};
+
+static int __driver_rfc4106_encrypt(struct aead_request *req)
+{
+ u8 one_entry_in_sg = 0;
+ u8 *src, *dst, *assoc;
+ __be32 counter = cpu_to_be32(1);
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+ void *aes_ctx = &(ctx->aes_key_expanded);
+ unsigned long auth_tag_len = crypto_aead_authsize(tfm);
+ u8 iv_tab[16+AESNI_ALIGN];
+ u8* iv = (u8 *) PTR_ALIGN((u8 *)iv_tab, AESNI_ALIGN);
+ struct scatter_walk src_sg_walk;
+ struct scatter_walk assoc_sg_walk;
+ struct scatter_walk dst_sg_walk;
+ unsigned int i;
+
+ /* Assuming we are supporting rfc4106 64-bit extended */
+ /* sequence numbers We need to have the AAD length equal */
+ /* to 8 or 12 bytes */
+ if (unlikely(req->assoclen != 8 && req->assoclen != 12))
+ return -EINVAL;
+ /* IV below built */
+ for (i = 0; i < 4; i++)
+ *(iv+i) = ctx->nonce[i];
+ for (i = 0; i < 8; i++)
+ *(iv+4+i) = req->iv[i];
+ *((__be32 *)(iv+12)) = counter;
+
+ if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) {
+ one_entry_in_sg = 1;
+ scatterwalk_start(&src_sg_walk, req->src);
+ scatterwalk_start(&assoc_sg_walk, req->assoc);
+ src = scatterwalk_map(&src_sg_walk, 0);
+ assoc = scatterwalk_map(&assoc_sg_walk, 0);
+ dst = src;
+ if (unlikely(req->src != req->dst)) {
+ scatterwalk_start(&dst_sg_walk, req->dst);
+ dst = scatterwalk_map(&dst_sg_walk, 0);
+ }
+
+ } else {
+ /* Allocate memory for src, dst, assoc */
+ src = kmalloc(req->cryptlen + auth_tag_len + req->assoclen,
+ GFP_ATOMIC);
+ if (unlikely(!src))
+ return -ENOMEM;
+ assoc = (src + req->cryptlen + auth_tag_len);
+ scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0);
+ scatterwalk_map_and_copy(assoc, req->assoc, 0,
+ req->assoclen, 0);
+ dst = src;
+ }
+
+ aesni_gcm_enc(aes_ctx, dst, src, (unsigned long)req->cryptlen, iv,
+ ctx->hash_subkey, assoc, (unsigned long)req->assoclen, dst
+ + ((unsigned long)req->cryptlen), auth_tag_len);
+
+ /* The authTag (aka the Integrity Check Value) needs to be written
+ * back to the packet. */
+ if (one_entry_in_sg) {
+ if (unlikely(req->src != req->dst)) {
+ scatterwalk_unmap(dst, 0);
+ scatterwalk_done(&dst_sg_walk, 0, 0);
+ }
+ scatterwalk_unmap(src, 0);
+ scatterwalk_unmap(assoc, 0);
+ scatterwalk_done(&src_sg_walk, 0, 0);
+ scatterwalk_done(&assoc_sg_walk, 0, 0);
+ } else {
+ scatterwalk_map_and_copy(dst, req->dst, 0,
+ req->cryptlen + auth_tag_len, 1);
+ kfree(src);
+ }
+ return 0;
+}
+
+static int __driver_rfc4106_decrypt(struct aead_request *req)
+{
+ u8 one_entry_in_sg = 0;
+ u8 *src, *dst, *assoc;
+ unsigned long tempCipherLen = 0;
+ __be32 counter = cpu_to_be32(1);
+ int retval = 0;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+ struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+ void *aes_ctx = &(ctx->aes_key_expanded);
+ unsigned long auth_tag_len = crypto_aead_authsize(tfm);
+ u8 iv_and_authTag[32+AESNI_ALIGN];
+ u8 *iv = (u8 *) PTR_ALIGN((u8 *)iv_and_authTag, AESNI_ALIGN);
+ u8 *authTag = iv + 16;
+ struct scatter_walk src_sg_walk;
+ struct scatter_walk assoc_sg_walk;
+ struct scatter_walk dst_sg_walk;
+ unsigned int i;
+
+ if (unlikely((req->cryptlen < auth_tag_len) ||
+ (req->assoclen != 8 && req->assoclen != 12)))
+ return -EINVAL;
+ /* Assuming we are supporting rfc4106 64-bit extended */
+ /* sequence numbers We need to have the AAD length */
+ /* equal to 8 or 12 bytes */
+
+ tempCipherLen = (unsigned long)(req->cryptlen - auth_tag_len);
+ /* IV below built */
+ for (i = 0; i < 4; i++)
+ *(iv+i) = ctx->nonce[i];
+ for (i = 0; i < 8; i++)
+ *(iv+4+i) = req->iv[i];
+ *((__be32 *)(iv+12)) = counter;
+
+ if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) {
+ one_entry_in_sg = 1;
+ scatterwalk_start(&src_sg_walk, req->src);
+ scatterwalk_start(&assoc_sg_walk, req->assoc);
+ src = scatterwalk_map(&src_sg_walk, 0);
+ assoc = scatterwalk_map(&assoc_sg_walk, 0);
+ dst = src;
+ if (unlikely(req->src != req->dst)) {
+ scatterwalk_start(&dst_sg_walk, req->dst);
+ dst = scatterwalk_map(&dst_sg_walk, 0);
+ }
+
+ } else {
+ /* Allocate memory for src, dst, assoc */
+ src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC);
+ if (!src)
+ return -ENOMEM;
+ assoc = (src + req->cryptlen + auth_tag_len);
+ scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0);
+ scatterwalk_map_and_copy(assoc, req->assoc, 0,
+ req->assoclen, 0);
+ dst = src;
+ }
+
+ aesni_gcm_dec(aes_ctx, dst, src, tempCipherLen, iv,
+ ctx->hash_subkey, assoc, (unsigned long)req->assoclen,
+ authTag, auth_tag_len);
+
+ /* Compare generated tag with passed in tag. */
+ retval = memcmp(src + tempCipherLen, authTag, auth_tag_len) ?
+ -EBADMSG : 0;
+
+ if (one_entry_in_sg) {
+ if (unlikely(req->src != req->dst)) {
+ scatterwalk_unmap(dst, 0);
+ scatterwalk_done(&dst_sg_walk, 0, 0);
+ }
+ scatterwalk_unmap(src, 0);
+ scatterwalk_unmap(assoc, 0);
+ scatterwalk_done(&src_sg_walk, 0, 0);
+ scatterwalk_done(&assoc_sg_walk, 0, 0);
+ } else {
+ scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1);
+ kfree(src);
+ }
+ return retval;
+}
+
+static struct crypto_alg __rfc4106_alg = {
+ .cra_name = "__gcm-aes-aesni",
+ .cra_driver_name = "__driver-gcm-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN,
+ .cra_alignmask = 0,
+ .cra_type = &crypto_aead_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(__rfc4106_alg.cra_list),
+ .cra_u = {
+ .aead = {
+ .encrypt = __driver_rfc4106_encrypt,
+ .decrypt = __driver_rfc4106_decrypt,
+ },
+ },
+};
+#endif
+
static int __init aesni_init(void)
{
int err;
@@ -738,6 +1248,7 @@ static int __init aesni_init(void)
printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
return -ENODEV;
}
+
if ((err = crypto_register_alg(&aesni_alg)))
goto aes_err;
if ((err = crypto_register_alg(&__aesni_alg)))
@@ -746,18 +1257,24 @@ static int __init aesni_init(void)
goto blk_ecb_err;
if ((err = crypto_register_alg(&blk_cbc_alg)))
goto blk_cbc_err;
- if ((err = crypto_register_alg(&blk_ctr_alg)))
- goto blk_ctr_err;
if ((err = crypto_register_alg(&ablk_ecb_alg)))
goto ablk_ecb_err;
if ((err = crypto_register_alg(&ablk_cbc_alg)))
goto ablk_cbc_err;
+#ifdef CONFIG_X86_64
+ if ((err = crypto_register_alg(&blk_ctr_alg)))
+ goto blk_ctr_err;
if ((err = crypto_register_alg(&ablk_ctr_alg)))
goto ablk_ctr_err;
+ if ((err = crypto_register_alg(&__rfc4106_alg)))
+ goto __aead_gcm_err;
+ if ((err = crypto_register_alg(&rfc4106_alg)))
+ goto aead_gcm_err;
#ifdef HAS_CTR
if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg)))
goto ablk_rfc3686_ctr_err;
#endif
+#endif
#ifdef HAS_LRW
if ((err = crypto_register_alg(&ablk_lrw_alg)))
goto ablk_lrw_err;
@@ -770,7 +1287,6 @@ static int __init aesni_init(void)
if ((err = crypto_register_alg(&ablk_xts_alg)))
goto ablk_xts_err;
#endif
-
return err;
#ifdef HAS_XTS
@@ -784,18 +1300,24 @@ ablk_pcbc_err:
crypto_unregister_alg(&ablk_lrw_alg);
ablk_lrw_err:
#endif
+#ifdef CONFIG_X86_64
#ifdef HAS_CTR
crypto_unregister_alg(&ablk_rfc3686_ctr_alg);
ablk_rfc3686_ctr_err:
#endif
+ crypto_unregister_alg(&rfc4106_alg);
+aead_gcm_err:
+ crypto_unregister_alg(&__rfc4106_alg);
+__aead_gcm_err:
crypto_unregister_alg(&ablk_ctr_alg);
ablk_ctr_err:
+ crypto_unregister_alg(&blk_ctr_alg);
+blk_ctr_err:
+#endif
crypto_unregister_alg(&ablk_cbc_alg);
ablk_cbc_err:
crypto_unregister_alg(&ablk_ecb_alg);
ablk_ecb_err:
- crypto_unregister_alg(&blk_ctr_alg);
-blk_ctr_err:
crypto_unregister_alg(&blk_cbc_alg);
blk_cbc_err:
crypto_unregister_alg(&blk_ecb_alg);
@@ -818,13 +1340,17 @@ static void __exit aesni_exit(void)
#ifdef HAS_LRW
crypto_unregister_alg(&ablk_lrw_alg);
#endif
+#ifdef CONFIG_X86_64
#ifdef HAS_CTR
crypto_unregister_alg(&ablk_rfc3686_ctr_alg);
#endif
+ crypto_unregister_alg(&rfc4106_alg);
+ crypto_unregister_alg(&__rfc4106_alg);
crypto_unregister_alg(&ablk_ctr_alg);
+ crypto_unregister_alg(&blk_ctr_alg);
+#endif
crypto_unregister_alg(&ablk_cbc_alg);
crypto_unregister_alg(&ablk_ecb_alg);
- crypto_unregister_alg(&blk_ctr_alg);
crypto_unregister_alg(&blk_cbc_alg);
crypto_unregister_alg(&blk_ecb_alg);
crypto_unregister_alg(&__aesni_alg);
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
index cbcc8d8ea93a..7a6e68e4f748 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -10,6 +10,7 @@
* by the Free Software Foundation.
*/
+#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 5be1542fbfaf..e99d55d74df5 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -72,6 +72,9 @@ struct e820map {
#define BIOS_BEGIN 0x000a0000
#define BIOS_END 0x00100000
+#define BIOS_ROM_BASE 0xffe00000
+#define BIOS_ROM_END 0xffffffff
+
#ifdef __KERNEL__
/* see comment in arch/x86/kernel/e820.c */
extern struct e820map e820;
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index b36c6b3fe144..8e37deb1eb38 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -15,6 +15,14 @@
struct x86_emulate_ctxt;
+struct x86_exception {
+ u8 vector;
+ bool error_code_valid;
+ u16 error_code;
+ bool nested_page_fault;
+ u64 address; /* cr2 or nested page fault gpa */
+};
+
/*
* x86_emulate_ops:
*
@@ -64,7 +72,8 @@ struct x86_emulate_ops {
* @bytes: [IN ] Number of bytes to read from memory.
*/
int (*read_std)(unsigned long addr, void *val,
- unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
+ unsigned int bytes, struct kvm_vcpu *vcpu,
+ struct x86_exception *fault);
/*
* write_std: Write bytes of standard (non-emulated/special) memory.
@@ -74,7 +83,8 @@ struct x86_emulate_ops {
* @bytes: [IN ] Number of bytes to write to memory.
*/
int (*write_std)(unsigned long addr, void *val,
- unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
+ unsigned int bytes, struct kvm_vcpu *vcpu,
+ struct x86_exception *fault);
/*
* fetch: Read bytes of standard (non-emulated/special) memory.
* Used for instruction fetch.
@@ -83,7 +93,8 @@ struct x86_emulate_ops {
* @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);
+ unsigned int bytes, struct kvm_vcpu *vcpu,
+ struct x86_exception *fault);
/*
* read_emulated: Read bytes from emulated/special memory area.
@@ -94,7 +105,7 @@ struct x86_emulate_ops {
int (*read_emulated)(unsigned long addr,
void *val,
unsigned int bytes,
- unsigned int *error,
+ struct x86_exception *fault,
struct kvm_vcpu *vcpu);
/*
@@ -107,7 +118,7 @@ struct x86_emulate_ops {
int (*write_emulated)(unsigned long addr,
const void *val,
unsigned int bytes,
- unsigned int *error,
+ struct x86_exception *fault,
struct kvm_vcpu *vcpu);
/*
@@ -122,7 +133,7 @@ struct x86_emulate_ops {
const void *old,
const void *new,
unsigned int bytes,
- unsigned int *error,
+ struct x86_exception *fault,
struct kvm_vcpu *vcpu);
int (*pio_in_emulated)(int size, unsigned short port, void *val,
@@ -159,7 +170,10 @@ struct operand {
};
union {
unsigned long *reg;
- unsigned long mem;
+ struct segmented_address {
+ ulong ea;
+ unsigned seg;
+ } mem;
} addr;
union {
unsigned long val;
@@ -226,9 +240,8 @@ struct x86_emulate_ctxt {
bool perm_ok; /* do not check permissions if true */
- int exception; /* exception that happens during emulation or -1 */
- u32 error_code; /* error code for exception */
- bool error_code_valid;
+ bool have_exception;
+ struct x86_exception exception;
/* decode cache */
struct decode_cache decode;
@@ -252,7 +265,7 @@ struct x86_emulate_ctxt {
#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
#endif
-int x86_decode_insn(struct x86_emulate_ctxt *ctxt);
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len);
#define EMULATION_FAILED -1
#define EMULATION_OK 0
#define EMULATION_RESTART 1
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9e6fe391094e..aa75f21a9fba 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -79,15 +79,18 @@
#define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
#define KVM_MIN_FREE_MMU_PAGES 5
#define KVM_REFILL_PAGES 25
-#define KVM_MAX_CPUID_ENTRIES 40
+#define KVM_MAX_CPUID_ENTRIES 80
#define KVM_NR_FIXED_MTRR_REGION 88
#define KVM_NR_VAR_MTRR 8
+#define ASYNC_PF_PER_VCPU 64
+
extern spinlock_t kvm_lock;
extern struct list_head vm_list;
struct kvm_vcpu;
struct kvm;
+struct kvm_async_pf;
enum kvm_reg {
VCPU_REGS_RAX = 0,
@@ -114,6 +117,7 @@ enum kvm_reg {
enum kvm_reg_ex {
VCPU_EXREG_PDPTR = NR_VCPU_REGS,
+ VCPU_EXREG_CR3,
};
enum {
@@ -238,16 +242,18 @@ struct kvm_mmu {
void (*new_cr3)(struct kvm_vcpu *vcpu);
void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root);
unsigned long (*get_cr3)(struct kvm_vcpu *vcpu);
- int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
- void (*inject_page_fault)(struct kvm_vcpu *vcpu);
+ int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err,
+ bool prefault);
+ void (*inject_page_fault)(struct kvm_vcpu *vcpu,
+ struct x86_exception *fault);
void (*free)(struct kvm_vcpu *vcpu);
gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
- u32 *error);
+ struct x86_exception *exception);
gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access);
void (*prefetch_page)(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *page);
int (*sync_page)(struct kvm_vcpu *vcpu,
- struct kvm_mmu_page *sp, bool clear_unsync);
+ struct kvm_mmu_page *sp);
void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva);
hpa_t root_hpa;
int root_level;
@@ -315,16 +321,6 @@ struct kvm_vcpu_arch {
*/
struct kvm_mmu *walk_mmu;
- /*
- * This struct is filled with the necessary information to propagate a
- * page fault into the guest
- */
- struct {
- u64 address;
- unsigned error_code;
- bool nested;
- } fault;
-
/* only needed in kvm_pv_mmu_op() path, but it's hot so
* put it here to avoid allocation */
struct kvm_pv_mmu_op_buffer mmu_op_buffer;
@@ -412,6 +408,15 @@ struct kvm_vcpu_arch {
u64 hv_vapic;
cpumask_var_t wbinvd_dirty_mask;
+
+ struct {
+ bool halted;
+ gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)];
+ struct gfn_to_hva_cache data;
+ u64 msr_val;
+ u32 id;
+ bool send_user_only;
+ } apf;
};
struct kvm_arch {
@@ -456,6 +461,10 @@ struct kvm_arch {
/* fields used by HYPER-V emulation */
u64 hv_guest_os_id;
u64 hv_hypercall;
+
+ #ifdef CONFIG_KVM_MMU_AUDIT
+ int audit_point;
+ #endif
};
struct kvm_vm_stat {
@@ -529,6 +538,7 @@ struct kvm_x86_ops {
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_cr3)(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);
@@ -582,9 +592,17 @@ struct kvm_x86_ops {
void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
+ void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
const struct trace_print_flags *exit_reasons_str;
};
+struct kvm_arch_async_pf {
+ u32 token;
+ gfn_t gfn;
+ unsigned long cr3;
+ bool direct_map;
+};
+
extern struct kvm_x86_ops *kvm_x86_ops;
int kvm_mmu_module_init(void);
@@ -594,7 +612,6 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
int kvm_mmu_create(struct kvm_vcpu *vcpu);
int kvm_mmu_setup(struct kvm_vcpu *vcpu);
void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
-void kvm_mmu_set_base_ptes(u64 base_pte);
void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
u64 dirty_mask, u64 nx_mask, u64 x_mask);
@@ -623,8 +640,15 @@ enum emulation_result {
#define EMULTYPE_NO_DECODE (1 << 0)
#define EMULTYPE_TRAP_UD (1 << 1)
#define EMULTYPE_SKIP (1 << 2)
-int emulate_instruction(struct kvm_vcpu *vcpu,
- unsigned long cr2, u16 error_code, int emulation_type);
+int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
+ int emulation_type, void *insn, int insn_len);
+
+static inline int emulate_instruction(struct kvm_vcpu *vcpu,
+ int emulation_type)
+{
+ return x86_emulate_instruction(vcpu, 0, emulation_type, NULL, 0);
+}
+
void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
@@ -650,7 +674,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason,
int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
-void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8);
+int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8);
int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val);
int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val);
unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu);
@@ -668,11 +692,11 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
-void kvm_inject_page_fault(struct kvm_vcpu *vcpu);
+void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
gfn_t gfn, void *data, int offset, int len,
u32 access);
-void kvm_propagate_fault(struct kvm_vcpu *vcpu);
+void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
int kvm_pic_set_irq(void *opaque, int irq, int level);
@@ -690,16 +714,21 @@ 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);
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception);
+gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception);
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception);
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception);
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
int kvm_fix_hypercall(struct kvm_vcpu *vcpu);
-int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
+int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code,
+ void *insn, int insn_len);
void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
void kvm_enable_tdp(void);
@@ -766,20 +795,25 @@ enum {
#define HF_VINTR_MASK (1 << 2)
#define HF_NMI_MASK (1 << 3)
#define HF_IRET_MASK (1 << 4)
+#define HF_GUEST_MASK (1 << 5) /* VCPU is in guest-mode */
/*
* Hardware virtualization extension instructions may fault if a
* reboot turns off virtualization while processes are running.
* Trap the fault and ignore the instruction if that happens.
*/
-asmlinkage void kvm_handle_fault_on_reboot(void);
+asmlinkage void kvm_spurious_fault(void);
+extern bool kvm_rebooting;
#define __kvm_handle_fault_on_reboot(insn) \
"666: " insn "\n\t" \
+ "668: \n\t" \
".pushsection .fixup, \"ax\" \n" \
"667: \n\t" \
+ "cmpb $0, kvm_rebooting \n\t" \
+ "jne 668b \n\t" \
__ASM_SIZE(push) " $666b \n\t" \
- "jmp kvm_handle_fault_on_reboot \n\t" \
+ "call kvm_spurious_fault \n\t" \
".popsection \n\t" \
".pushsection __ex_table, \"a\" \n\t" \
_ASM_PTR " 666b, 667b \n\t" \
@@ -799,4 +833,15 @@ void kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip);
+void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
+ struct kvm_async_pf *work);
+void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
+ struct kvm_async_pf *work);
+void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu,
+ struct kvm_async_pf *work);
+bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu);
+extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);
+
+void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
+
#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 7b562b6184bc..a427bf77a93d 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -20,6 +20,7 @@
* are available. The use of 0x11 and 0x12 is deprecated
*/
#define KVM_FEATURE_CLOCKSOURCE2 3
+#define KVM_FEATURE_ASYNC_PF 4
/* The last 8 bits are used to indicate how to interpret the flags field
* in pvclock structure. If no bits are set, all flags are ignored.
@@ -32,9 +33,13 @@
/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */
#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00
#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
+#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
#define KVM_MAX_MMU_OP_BATCH 32
+#define KVM_ASYNC_PF_ENABLED (1 << 0)
+#define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
+
/* Operations for KVM_HC_MMU_OP */
#define KVM_MMU_OP_WRITE_PTE 1
#define KVM_MMU_OP_FLUSH_TLB 2
@@ -61,10 +66,20 @@ struct kvm_mmu_op_release_pt {
__u64 pt_phys;
};
+#define KVM_PV_REASON_PAGE_NOT_PRESENT 1
+#define KVM_PV_REASON_PAGE_READY 2
+
+struct kvm_vcpu_pv_apf_data {
+ __u32 reason;
+ __u8 pad[60];
+ __u32 enabled;
+};
+
#ifdef __KERNEL__
#include <asm/processor.h>
extern void kvmclock_init(void);
+extern int kvm_register_clock(char *txt);
/* This instruction is vmcall. On non-VT architectures, it will generate a
@@ -160,8 +175,17 @@ static inline unsigned int kvm_arch_para_features(void)
#ifdef CONFIG_KVM_GUEST
void __init kvm_guest_init(void);
+void kvm_async_pf_task_wait(u32 token);
+void kvm_async_pf_task_wake(u32 token);
+u32 kvm_read_and_reset_pf_reason(void);
#else
#define kvm_guest_init() do { } while (0)
+#define kvm_async_pf_task_wait(T) do {} while(0)
+#define kvm_async_pf_task_wake(T) do {} while(0)
+static inline u32 kvm_read_and_reset_pf_reason(void)
+{
+ return 0;
+}
#endif
#endif /* __KERNEL__ */
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index 7f7e577a0e39..31d84acc1512 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
struct pvclock_vcpu_time_info *vcpu,
struct timespec *ts);
+void pvclock_resume(void);
/*
* Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 0e831059ac5a..f2b83bc7d784 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -47,14 +47,13 @@ enum {
INTERCEPT_MONITOR,
INTERCEPT_MWAIT,
INTERCEPT_MWAIT_COND,
+ INTERCEPT_XSETBV,
};
struct __attribute__ ((__packed__)) vmcb_control_area {
- u16 intercept_cr_read;
- u16 intercept_cr_write;
- u16 intercept_dr_read;
- u16 intercept_dr_write;
+ u32 intercept_cr;
+ u32 intercept_dr;
u32 intercept_exceptions;
u64 intercept;
u8 reserved_1[42];
@@ -81,14 +80,19 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
u32 event_inj_err;
u64 nested_cr3;
u64 lbr_ctl;
- u64 reserved_5;
+ u32 clean;
+ u32 reserved_5;
u64 next_rip;
- u8 reserved_6[816];
+ u8 insn_len;
+ u8 insn_bytes[15];
+ u8 reserved_6[800];
};
#define TLB_CONTROL_DO_NOTHING 0
#define TLB_CONTROL_FLUSH_ALL_ASID 1
+#define TLB_CONTROL_FLUSH_ASID 3
+#define TLB_CONTROL_FLUSH_ASID_LOCAL 7
#define V_TPR_MASK 0x0f
@@ -204,19 +208,31 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
#define SVM_SELECTOR_CODE_MASK (1 << 3)
-#define INTERCEPT_CR0_MASK 1
-#define INTERCEPT_CR3_MASK (1 << 3)
-#define INTERCEPT_CR4_MASK (1 << 4)
-#define INTERCEPT_CR8_MASK (1 << 8)
-
-#define INTERCEPT_DR0_MASK 1
-#define INTERCEPT_DR1_MASK (1 << 1)
-#define INTERCEPT_DR2_MASK (1 << 2)
-#define INTERCEPT_DR3_MASK (1 << 3)
-#define INTERCEPT_DR4_MASK (1 << 4)
-#define INTERCEPT_DR5_MASK (1 << 5)
-#define INTERCEPT_DR6_MASK (1 << 6)
-#define INTERCEPT_DR7_MASK (1 << 7)
+#define INTERCEPT_CR0_READ 0
+#define INTERCEPT_CR3_READ 3
+#define INTERCEPT_CR4_READ 4
+#define INTERCEPT_CR8_READ 8
+#define INTERCEPT_CR0_WRITE (16 + 0)
+#define INTERCEPT_CR3_WRITE (16 + 3)
+#define INTERCEPT_CR4_WRITE (16 + 4)
+#define INTERCEPT_CR8_WRITE (16 + 8)
+
+#define INTERCEPT_DR0_READ 0
+#define INTERCEPT_DR1_READ 1
+#define INTERCEPT_DR2_READ 2
+#define INTERCEPT_DR3_READ 3
+#define INTERCEPT_DR4_READ 4
+#define INTERCEPT_DR5_READ 5
+#define INTERCEPT_DR6_READ 6
+#define INTERCEPT_DR7_READ 7
+#define INTERCEPT_DR0_WRITE (16 + 0)
+#define INTERCEPT_DR1_WRITE (16 + 1)
+#define INTERCEPT_DR2_WRITE (16 + 2)
+#define INTERCEPT_DR3_WRITE (16 + 3)
+#define INTERCEPT_DR4_WRITE (16 + 4)
+#define INTERCEPT_DR5_WRITE (16 + 5)
+#define INTERCEPT_DR6_WRITE (16 + 6)
+#define INTERCEPT_DR7_WRITE (16 + 7)
#define SVM_EVTINJ_VEC_MASK 0xff
@@ -246,6 +262,8 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EXITINFOSHIFT_TS_REASON_JMP 38
#define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44
+#define SVM_EXITINFO_REG_MASK 0x0F
+
#define SVM_EXIT_READ_CR0 0x000
#define SVM_EXIT_READ_CR3 0x003
#define SVM_EXIT_READ_CR4 0x004
@@ -316,6 +334,7 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EXIT_MONITOR 0x08a
#define SVM_EXIT_MWAIT 0x08b
#define SVM_EXIT_MWAIT_COND 0x08c
+#define SVM_EXIT_XSETBV 0x08d
#define SVM_EXIT_NPF 0x400
#define SVM_EXIT_ERR -1
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index f66cda56781d..0310da67307f 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -30,6 +30,7 @@ asmlinkage void segment_not_present(void);
asmlinkage void stack_segment(void);
asmlinkage void general_protection(void);
asmlinkage void page_fault(void);
+asmlinkage void async_page_fault(void);
asmlinkage void spurious_interrupt_bug(void);
asmlinkage void coprocessor_error(void);
asmlinkage void alignment_check(void);
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 9f0cbd987d50..84471b810460 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -66,15 +66,23 @@
#define PIN_BASED_NMI_EXITING 0x00000008
#define PIN_BASED_VIRTUAL_NMIS 0x00000020
+#define VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000002
#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200
+#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000
#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000
#define VM_EXIT_SAVE_IA32_PAT 0x00040000
#define VM_EXIT_LOAD_IA32_PAT 0x00080000
+#define VM_EXIT_SAVE_IA32_EFER 0x00100000
+#define VM_EXIT_LOAD_IA32_EFER 0x00200000
+#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000
+#define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000002
#define VM_ENTRY_IA32E_MODE 0x00000200
#define VM_ENTRY_SMM 0x00000400
#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
+#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000
#define VM_ENTRY_LOAD_IA32_PAT 0x00004000
+#define VM_ENTRY_LOAD_IA32_EFER 0x00008000
/* VMCS Encodings */
enum vmcs_field {
@@ -239,6 +247,7 @@ enum vmcs_field {
#define EXIT_REASON_TASK_SWITCH 9
#define EXIT_REASON_CPUID 10
#define EXIT_REASON_HLT 12
+#define EXIT_REASON_INVD 13
#define EXIT_REASON_INVLPG 14
#define EXIT_REASON_RDPMC 15
#define EXIT_REASON_RDTSC 16
@@ -296,6 +305,12 @@ enum vmcs_field {
#define GUEST_INTR_STATE_SMI 0x00000004
#define GUEST_INTR_STATE_NMI 0x00000008
+/* GUEST_ACTIVITY_STATE flags */
+#define GUEST_ACTIVITY_ACTIVE 0
+#define GUEST_ACTIVITY_HLT 1
+#define GUEST_ACTIVITY_SHUTDOWN 2
+#define GUEST_ACTIVITY_WAIT_SIPI 3
+
/*
* Exit Qualifications for MOV for Control Register Access
*/
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9e13763b6092..1e994754d323 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
obj-y += tsc.o io_delay.o rtc.o
obj-y += pci-iommu_table.o
+obj-y += resource.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-y += process.o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3f838d537392..78218135b48e 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void)
setup_apic_nmi_watchdog(NULL);
apic_pm_activate();
+
+ /*
+ * Now that local APIC setup is completed for BP, configure the fault
+ * handling for interrupt remapping.
+ */
+ if (!smp_processor_id() && intr_remapping_enabled)
+ enable_drhd_fault_handling();
+
}
#ifdef CONFIG_X86_X2APIC
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7cc0a721f628..fadcd743a74f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data)
{
struct irq_cfg *cfg = data->chip_data;
int i, do_unmask_irq = 0, irq = data->irq;
- struct irq_desc *desc = irq_to_desc(irq);
unsigned long v;
irq_complete_move(cfg);
#ifdef CONFIG_GENERIC_PENDING_IRQ
/* If we are moving the irq we need to mask it */
- if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
+ if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
mask_ioapic(cfg);
}
@@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
msg.data |= MSI_DATA_VECTOR(cfg->vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+ msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
dmar_msi_write(irq, &msg);
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index f9e4e6a54073..d8c4a6feb286 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void)
/* need to update phys_pkg_id */
apic->phys_pkg_id = apicid_phys_pkg_id;
}
-
- /*
- * Now that apic routing model is selected, configure the
- * fault handling for intr remapping.
- */
- if (intr_remapping_enabled)
- enable_drhd_fault_handling();
}
/* Same for both flat and physical. */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 491977baf6c0..8f85ed23e600 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -1537,6 +1537,7 @@ static struct notifier_block cpb_nb = {
static int __cpuinit powernowk8_init(void)
{
unsigned int i, supported_cpus = 0, cpu;
+ int rv;
for_each_online_cpu(i) {
int rc;
@@ -1555,14 +1556,14 @@ static int __cpuinit powernowk8_init(void)
cpb_capable = true;
- register_cpu_notifier(&cpb_nb);
-
msrs = msrs_alloc();
if (!msrs) {
printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
return -ENOMEM;
}
+ register_cpu_notifier(&cpb_nb);
+
rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
for_each_cpu(cpu, cpu_online_mask) {
@@ -1574,7 +1575,13 @@ static int __cpuinit powernowk8_init(void)
(cpb_enabled ? "on" : "off"));
}
- return cpufreq_register_driver(&cpufreq_amd64_driver);
+ rv = cpufreq_register_driver(&cpufreq_amd64_driver);
+ if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) {
+ unregister_cpu_notifier(&cpb_nb);
+ msrs_free(msrs);
+ msrs = NULL;
+ }
+ return rv;
}
/* driver entry point for term */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 591e60104278..c8b4efad7ebb 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1406,6 +1406,16 @@ ENTRY(general_protection)
CFI_ENDPROC
END(general_protection)
+#ifdef CONFIG_KVM_GUEST
+ENTRY(async_page_fault)
+ RING0_EC_FRAME
+ pushl $do_async_page_fault
+ CFI_ADJUST_CFA_OFFSET 4
+ jmp error_code
+ CFI_ENDPROC
+END(apf_page_fault)
+#endif
+
/*
* End of kprobes section
*/
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index e3ba417e8697..bb3f6e9bfa68 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1319,6 +1319,9 @@ errorentry xen_stack_segment do_stack_segment
#endif
errorentry general_protection do_general_protection
errorentry page_fault do_page_fault
+#ifdef CONFIG_KVM_GUEST
+errorentry async_page_fault do_async_page_fault
+#endif
#ifdef CONFIG_X86_MCE
paranoidzeroentry machine_check *machine_check_vector(%rip)
#endif
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index bcece91dd311..c0dbd9ac24f0 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -60,16 +60,18 @@
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
#endif
+/* Number of possible pages in the lowmem region */
+LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
+
/* Enough space to fit pagetables for the low memory linear map */
-MAPPING_BEYOND_END = \
- PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
/*
* Worst-case size of the kernel mapping we need to make:
- * the worst-case size of the kernel itself, plus the extra we need
- * to map for the linear map.
+ * a relocatable kernel can live anywhere in lowmem, so we need to be able
+ * to map all of lowmem.
*/
-KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
+KERNEL_PAGES = LOWMEM_PAGES
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
@@ -620,13 +622,13 @@ ENTRY(initial_code)
__PAGE_ALIGNED_BSS
.align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
-initial_pg_pmd:
+ENTRY(initial_pg_pmd)
.fill 1024*KPMDS,4,0
#else
ENTRY(initial_page_table)
.fill 1024,4,0
#endif
-initial_pg_fixmap:
+ENTRY(initial_pg_fixmap)
.fill 1024,4,0
ENTRY(empty_zero_page)
.fill 4096,1,0
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ae03cab4352e..4ff5968f12d2 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -27,6 +27,9 @@
#define HPET_DEV_FSB_CAP 0x1000
#define HPET_DEV_PERI_CAP 0x2000
+#define HPET_MIN_CYCLES 128
+#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
/*
@@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void)
/* Calculate the min / max delta */
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
&hpet_clockevent);
- /* 5 usec minimum reprogramming delta. */
- hpet_clockevent.min_delta_ns = 5000;
+ /* Setup minimum reprogramming delta. */
+ hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
+ &hpet_clockevent);
/*
* Start hpet with the boot cpu mask and make it
@@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta,
* the wraparound into account) nor a simple count down event
* mode. Further the write to the comparator register is
* delayed internally up to two HPET clock cycles in certain
- * chipsets (ATI, ICH9,10). We worked around that by reading
- * back the compare register, but that required another
- * workaround for ICH9,10 chips where the first readout after
- * write can return the old stale value. We already have a
- * minimum delta of 5us enforced, but a NMI or SMI hitting
+ * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
+ * longer delays. We worked around that by reading back the
+ * compare register, but that required another workaround for
+ * ICH9,10 chips where the first readout after write can
+ * return the old stale value. We already had a minimum
+ * programming delta of 5us enforced, but a NMI or SMI hitting
* between the counter readout and the comparator write can
* move us behind that point easily. Now instead of reading
* the compare register back several times, we make the ETIME
* decision based on the following: Return ETIME if the
- * counter value after the write is less than 8 HPET cycles
+ * counter value after the write is less than HPET_MIN_CYCLES
* away from the event or if the counter is already ahead of
- * the event.
+ * the event. The minimum programming delta for the generic
+ * clockevents code is set to 1.5 * HPET_MIN_CYCLES.
*/
res = (s32)(cnt - hpet_readl(HPET_COUNTER));
- return res < 8 ? -ETIME : 0;
+ return res < HPET_MIN_CYCLES ? -ETIME : 0;
}
static void hpet_legacy_set_mode(enum clock_event_mode mode,
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 63b0ec8d3d4a..8dc44662394b 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -27,16 +27,37 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/hardirq.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/hash.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/kprobes.h>
#include <asm/timer.h>
+#include <asm/cpu.h>
+#include <asm/traps.h>
+#include <asm/desc.h>
+#include <asm/tlbflush.h>
#define MMU_QUEUE_SIZE 1024
+static int kvmapf = 1;
+
+static int parse_no_kvmapf(char *arg)
+{
+ kvmapf = 0;
+ return 0;
+}
+
+early_param("no-kvmapf", parse_no_kvmapf);
+
struct kvm_para_state {
u8 mmu_queue[MMU_QUEUE_SIZE];
int mmu_queue_len;
};
static DEFINE_PER_CPU(struct kvm_para_state, para_state);
+static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
static struct kvm_para_state *kvm_para_state(void)
{
@@ -50,6 +71,195 @@ static void kvm_io_delay(void)
{
}
+#define KVM_TASK_SLEEP_HASHBITS 8
+#define KVM_TASK_SLEEP_HASHSIZE (1<<KVM_TASK_SLEEP_HASHBITS)
+
+struct kvm_task_sleep_node {
+ struct hlist_node link;
+ wait_queue_head_t wq;
+ u32 token;
+ int cpu;
+ bool halted;
+ struct mm_struct *mm;
+};
+
+static struct kvm_task_sleep_head {
+ spinlock_t lock;
+ struct hlist_head list;
+} async_pf_sleepers[KVM_TASK_SLEEP_HASHSIZE];
+
+static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b,
+ u32 token)
+{
+ struct hlist_node *p;
+
+ hlist_for_each(p, &b->list) {
+ struct kvm_task_sleep_node *n =
+ hlist_entry(p, typeof(*n), link);
+ if (n->token == token)
+ return n;
+ }
+
+ return NULL;
+}
+
+void kvm_async_pf_task_wait(u32 token)
+{
+ u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
+ struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
+ struct kvm_task_sleep_node n, *e;
+ DEFINE_WAIT(wait);
+ int cpu, idle;
+
+ cpu = get_cpu();
+ idle = idle_cpu(cpu);
+ put_cpu();
+
+ spin_lock(&b->lock);
+ e = _find_apf_task(b, token);
+ if (e) {
+ /* dummy entry exist -> wake up was delivered ahead of PF */
+ hlist_del(&e->link);
+ kfree(e);
+ spin_unlock(&b->lock);
+ return;
+ }
+
+ n.token = token;
+ n.cpu = smp_processor_id();
+ n.mm = current->active_mm;
+ n.halted = idle || preempt_count() > 1;
+ atomic_inc(&n.mm->mm_count);
+ init_waitqueue_head(&n.wq);
+ hlist_add_head(&n.link, &b->list);
+ spin_unlock(&b->lock);
+
+ for (;;) {
+ if (!n.halted)
+ prepare_to_wait(&n.wq, &wait, TASK_UNINTERRUPTIBLE);
+ if (hlist_unhashed(&n.link))
+ break;
+
+ if (!n.halted) {
+ local_irq_enable();
+ schedule();
+ local_irq_disable();
+ } else {
+ /*
+ * We cannot reschedule. So halt.
+ */
+ native_safe_halt();
+ local_irq_disable();
+ }
+ }
+ if (!n.halted)
+ finish_wait(&n.wq, &wait);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait);
+
+static void apf_task_wake_one(struct kvm_task_sleep_node *n)
+{
+ hlist_del_init(&n->link);
+ if (!n->mm)
+ return;
+ mmdrop(n->mm);
+ if (n->halted)
+ smp_send_reschedule(n->cpu);
+ else if (waitqueue_active(&n->wq))
+ wake_up(&n->wq);
+}
+
+static void apf_task_wake_all(void)
+{
+ int i;
+
+ for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) {
+ struct hlist_node *p, *next;
+ struct kvm_task_sleep_head *b = &async_pf_sleepers[i];
+ spin_lock(&b->lock);
+ hlist_for_each_safe(p, next, &b->list) {
+ struct kvm_task_sleep_node *n =
+ hlist_entry(p, typeof(*n), link);
+ if (n->cpu == smp_processor_id())
+ apf_task_wake_one(n);
+ }
+ spin_unlock(&b->lock);
+ }
+}
+
+void kvm_async_pf_task_wake(u32 token)
+{
+ u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
+ struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
+ struct kvm_task_sleep_node *n;
+
+ if (token == ~0) {
+ apf_task_wake_all();
+ return;
+ }
+
+again:
+ spin_lock(&b->lock);
+ n = _find_apf_task(b, token);
+ if (!n) {
+ /*
+ * async PF was not yet handled.
+ * Add dummy entry for the token.
+ */
+ n = kmalloc(sizeof(*n), GFP_ATOMIC);
+ if (!n) {
+ /*
+ * Allocation failed! Busy wait while other cpu
+ * handles async PF.
+ */
+ spin_unlock(&b->lock);
+ cpu_relax();
+ goto again;
+ }
+ n->token = token;
+ n->cpu = smp_processor_id();
+ n->mm = NULL;
+ init_waitqueue_head(&n->wq);
+ hlist_add_head(&n->link, &b->list);
+ } else
+ apf_task_wake_one(n);
+ spin_unlock(&b->lock);
+ return;
+}
+EXPORT_SYMBOL_GPL(kvm_async_pf_task_wake);
+
+u32 kvm_read_and_reset_pf_reason(void)
+{
+ u32 reason = 0;
+
+ if (__get_cpu_var(apf_reason).enabled) {
+ reason = __get_cpu_var(apf_reason).reason;
+ __get_cpu_var(apf_reason).reason = 0;
+ }
+
+ return reason;
+}
+EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason);
+
+dotraplinkage void __kprobes
+do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+ switch (kvm_read_and_reset_pf_reason()) {
+ default:
+ do_page_fault(regs, error_code);
+ break;
+ case KVM_PV_REASON_PAGE_NOT_PRESENT:
+ /* page is swapped out by the host. */
+ kvm_async_pf_task_wait((u32)read_cr2());
+ break;
+ case KVM_PV_REASON_PAGE_READY:
+ kvm_async_pf_task_wake((u32)read_cr2());
+ break;
+ }
+}
+
static void kvm_mmu_op(void *buffer, unsigned len)
{
int r;
@@ -231,10 +441,117 @@ static void __init paravirt_ops_setup(void)
#endif
}
+void __cpuinit kvm_guest_cpu_init(void)
+{
+ if (!kvm_para_available())
+ return;
+
+ if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
+ u64 pa = __pa(&__get_cpu_var(apf_reason));
+
+#ifdef CONFIG_PREEMPT
+ pa |= KVM_ASYNC_PF_SEND_ALWAYS;
+#endif
+ wrmsrl(MSR_KVM_ASYNC_PF_EN, pa | KVM_ASYNC_PF_ENABLED);
+ __get_cpu_var(apf_reason).enabled = 1;
+ printk(KERN_INFO"KVM setup async PF for cpu %d\n",
+ smp_processor_id());
+ }
+}
+
+static void kvm_pv_disable_apf(void *unused)
+{
+ if (!__get_cpu_var(apf_reason).enabled)
+ return;
+
+ wrmsrl(MSR_KVM_ASYNC_PF_EN, 0);
+ __get_cpu_var(apf_reason).enabled = 0;
+
+ printk(KERN_INFO"Unregister pv shared memory for cpu %d\n",
+ smp_processor_id());
+}
+
+static int kvm_pv_reboot_notify(struct notifier_block *nb,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_RESTART)
+ on_each_cpu(kvm_pv_disable_apf, NULL, 1);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block kvm_pv_reboot_nb = {
+ .notifier_call = kvm_pv_reboot_notify,
+};
+
+#ifdef CONFIG_SMP
+static void __init kvm_smp_prepare_boot_cpu(void)
+{
+#ifdef CONFIG_KVM_CLOCK
+ WARN_ON(kvm_register_clock("primary cpu clock"));
+#endif
+ kvm_guest_cpu_init();
+ native_smp_prepare_boot_cpu();
+}
+
+static void kvm_guest_cpu_online(void *dummy)
+{
+ kvm_guest_cpu_init();
+}
+
+static void kvm_guest_cpu_offline(void *dummy)
+{
+ kvm_pv_disable_apf(NULL);
+ apf_task_wake_all();
+}
+
+static int __cpuinit kvm_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ int cpu = (unsigned long)hcpu;
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_DOWN_FAILED:
+ case CPU_ONLINE_FROZEN:
+ smp_call_function_single(cpu, kvm_guest_cpu_online, NULL, 0);
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ smp_call_function_single(cpu, kvm_guest_cpu_offline, NULL, 1);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata kvm_cpu_notifier = {
+ .notifier_call = kvm_cpu_notify,
+};
+#endif
+
+static void __init kvm_apf_trap_init(void)
+{
+ set_intr_gate(14, &async_page_fault);
+}
+
void __init kvm_guest_init(void)
{
+ int i;
+
if (!kvm_para_available())
return;
paravirt_ops_setup();
+ register_reboot_notifier(&kvm_pv_reboot_nb);
+ for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++)
+ spin_lock_init(&async_pf_sleepers[i].lock);
+ if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF))
+ x86_init.irqs.trap_init = kvm_apf_trap_init;
+
+#ifdef CONFIG_SMP
+ smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
+ register_cpu_notifier(&kvm_cpu_notifier);
+#else
+ kvm_guest_cpu_init();
+#endif
}
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index ca43ce31a19c..f98d3eafe07a 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -125,7 +125,7 @@ static struct clocksource kvm_clock = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static int kvm_register_clock(char *txt)
+int kvm_register_clock(char *txt)
{
int cpu = smp_processor_id();
int low, high, ret;
@@ -152,14 +152,6 @@ static void __cpuinit kvm_setup_secondary_clock(void)
}
#endif
-#ifdef CONFIG_SMP
-static void __init kvm_smp_prepare_boot_cpu(void)
-{
- WARN_ON(kvm_register_clock("primary cpu clock"));
- native_smp_prepare_boot_cpu();
-}
-#endif
-
/*
* After the clock is registered, the host will keep writing to the
* registered memory location. If the guest happens to shutdown, this memory
@@ -206,9 +198,6 @@ void __init kvmclock_init(void)
x86_cpuinit.setup_percpu_clockev =
kvm_setup_secondary_clock;
#endif
-#ifdef CONFIG_SMP
- smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
-#endif
machine_ops.shutdown = kvm_shutdown;
#ifdef CONFIG_KEXEC
machine_ops.crash_shutdown = kvm_crash_shutdown;
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index dcb65cc0a053..1a1b606d3e92 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
/* For performance reasons, reuse mc area when possible */
if (!mc || mc_size > curr_mc_size) {
- if (mc)
- vfree(mc);
+ vfree(mc);
mc = vmalloc(mc_size);
if (!mc)
break;
@@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
if (get_ucode_data(mc, ucode_ptr, mc_size) ||
microcode_sanity_check(mc) < 0) {
- vfree(mc);
break;
}
if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
- if (new_mc)
- vfree(new_mc);
+ vfree(new_mc);
new_rev = mc_header.rev;
new_mc = mc;
mc = NULL; /* trigger new vmalloc */
@@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
leftover -= mc_size;
}
- if (mc)
- vfree(mc);
+ vfree(mc);
if (leftover) {
- if (new_mc)
- vfree(new_mc);
+ vfree(new_mc);
state = UCODE_ERROR;
goto out;
}
@@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
goto out;
}
- if (uci->mc)
- vfree(uci->mc);
+ vfree(uci->mc);
uci->mc = (struct microcode_intel *)new_mc;
pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 008b91eefa18..42eb3300dfc6 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
static atomic64_t last_value = ATOMIC64_INIT(0);
+void pvclock_resume(void)
+{
+ atomic64_set(&last_value, 0);
+}
+
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
{
struct pvclock_shadow_time shadow;
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
new file mode 100644
index 000000000000..2a26819bb6a8
--- /dev/null
+++ b/arch/x86/kernel/resource.c
@@ -0,0 +1,48 @@
+#include <linux/ioport.h>
+#include <asm/e820.h>
+
+static void resource_clip(struct resource *res, resource_size_t start,
+ resource_size_t end)
+{
+ resource_size_t low = 0, high = 0;
+
+ if (res->end < start || res->start > end)
+ return; /* no conflict */
+
+ if (res->start < start)
+ low = start - res->start;
+
+ if (res->end > end)
+ high = res->end - end;
+
+ /* Keep the area above or below the conflict, whichever is larger */
+ if (low > high)
+ res->end = start - 1;
+ else
+ res->start = end + 1;
+}
+
+static void remove_e820_regions(struct resource *avail)
+{
+ int i;
+ struct e820entry *entry;
+
+ for (i = 0; i < e820.nr_map; i++) {
+ entry = &e820.map[i];
+
+ resource_clip(avail, entry->addr,
+ entry->addr + entry->size - 1);
+ }
+}
+
+void arch_remove_reservations(struct resource *avail)
+{
+ /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
+ if (avail->flags & IORESOURCE_MEM) {
+ if (avail->start < BIOS_END)
+ avail->start = BIOS_END;
+ resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
+
+ remove_e820_regions(avail);
+ }
+}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 21c6746338af..a0f52af256a0 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void)
return total << PAGE_SHIFT;
}
-#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
+/*
+ * Keep the crash kernel below this limit. On 32 bits earlier kernels
+ * would limit the kernel to the low 512 MiB due to mapping restrictions.
+ * On 64 bits, kexec-tools currently limits us to 896 MiB; increase this
+ * limit once kexec-tools are fixed.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_KERNEL_ADDR_MAX (512 << 20)
+#else
+# define CRASH_KERNEL_ADDR_MAX (896 << 20)
+#endif
+
static void __init reserve_crashkernel(void)
{
unsigned long long total_mem;
@@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void)
const unsigned long long alignment = 16<<20; /* 16M */
/*
- * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
+ * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
*/
crash_base = memblock_find_in_range(alignment,
- DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
+ CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
if (crash_base == MEMBLOCK_ERROR) {
pr_info("crashkernel reservation failed - No suitable area found.\n");
@@ -769,7 +780,6 @@ void __init setup_arch(char **cmdline_p)
x86_init.oem.arch_setup();
- resource_alloc_from_bottom = 0;
iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
setup_memory_map();
parse_setup_data();
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 9c253bd65e24..547128546cc3 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -394,7 +394,8 @@ static void __init setup_xstate_init(void)
* Setup init_xstate_buf to represent the init state of
* all the features managed by the xsave
*/
- init_xstate_buf = alloc_bootmem(xstate_size);
+ init_xstate_buf = alloc_bootmem_align(xstate_size,
+ __alignof__(struct xsave_struct));
init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
clts();
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ddc131ff438f..50f63648ce1b 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -28,6 +28,7 @@ config KVM
select HAVE_KVM_IRQCHIP
select HAVE_KVM_EVENTFD
select KVM_APIC_ARCHITECTURE
+ select KVM_ASYNC_PF
select USER_RETURN_NOTIFIER
select KVM_MMIO
---help---
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 31a7035c4bd9..f15501f431c8 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -1,5 +1,5 @@
-EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
+ccflags-y += -Ivirt/kvm -Iarch/x86/kvm
CFLAGS_x86.o := -I.
CFLAGS_svm.o := -I.
@@ -9,6 +9,7 @@ kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
coalesced_mmio.o irq_comm.o eventfd.o \
assigned-dev.o)
kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o)
+kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o)
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
i8254.o timer.o
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 38b6e8dafaff..caf966781d25 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -20,16 +20,8 @@
* From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
*/
-#ifndef __KERNEL__
-#include <stdio.h>
-#include <stdint.h>
-#include <public/xen.h>
-#define DPRINTF(_f, _a ...) printf(_f , ## _a)
-#else
#include <linux/kvm_host.h>
#include "kvm_cache_regs.h"
-#define DPRINTF(x...) do {} while (0)
-#endif
#include <linux/module.h>
#include <asm/kvm_emulate.h>
@@ -418,9 +410,9 @@ address_mask(struct decode_cache *c, unsigned long reg)
}
static inline unsigned long
-register_address(struct decode_cache *c, unsigned long base, unsigned long reg)
+register_address(struct decode_cache *c, unsigned long reg)
{
- return base + address_mask(c, reg);
+ return address_mask(c, reg);
}
static inline void
@@ -452,60 +444,55 @@ static unsigned long seg_base(struct x86_emulate_ctxt *ctxt,
return ops->get_cached_segment_base(seg, ctxt->vcpu);
}
-static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops,
- struct decode_cache *c)
+static unsigned seg_override(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ struct decode_cache *c)
{
if (!c->has_seg_override)
return 0;
- return seg_base(ctxt, ops, c->seg_override);
+ return c->seg_override;
}
-static unsigned long es_base(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
+static ulong linear(struct x86_emulate_ctxt *ctxt,
+ struct segmented_address addr)
{
- return seg_base(ctxt, ops, VCPU_SREG_ES);
-}
-
-static unsigned long ss_base(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
-{
- return seg_base(ctxt, ops, VCPU_SREG_SS);
-}
+ struct decode_cache *c = &ctxt->decode;
+ ulong la;
-static void emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
- u32 error, bool valid)
-{
- ctxt->exception = vec;
- ctxt->error_code = error;
- ctxt->error_code_valid = valid;
+ la = seg_base(ctxt, ctxt->ops, addr.seg) + addr.ea;
+ if (c->ad_bytes != 8)
+ la &= (u32)-1;
+ return la;
}
-static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
+static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
+ u32 error, bool valid)
{
- emulate_exception(ctxt, GP_VECTOR, err, true);
+ ctxt->exception.vector = vec;
+ ctxt->exception.error_code = error;
+ ctxt->exception.error_code_valid = valid;
+ return X86EMUL_PROPAGATE_FAULT;
}
-static void emulate_pf(struct x86_emulate_ctxt *ctxt)
+static int emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
{
- emulate_exception(ctxt, PF_VECTOR, 0, true);
+ return emulate_exception(ctxt, GP_VECTOR, err, true);
}
-static void emulate_ud(struct x86_emulate_ctxt *ctxt)
+static int emulate_ud(struct x86_emulate_ctxt *ctxt)
{
- emulate_exception(ctxt, UD_VECTOR, 0, false);
+ return emulate_exception(ctxt, UD_VECTOR, 0, false);
}
-static void emulate_ts(struct x86_emulate_ctxt *ctxt, int err)
+static int emulate_ts(struct x86_emulate_ctxt *ctxt, int err)
{
- emulate_exception(ctxt, TS_VECTOR, err, true);
+ return emulate_exception(ctxt, TS_VECTOR, err, true);
}
static int emulate_de(struct x86_emulate_ctxt *ctxt)
{
- emulate_exception(ctxt, DE_VECTOR, 0, false);
- return X86EMUL_PROPAGATE_FAULT;
+ return emulate_exception(ctxt, DE_VECTOR, 0, false);
}
static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
@@ -520,7 +507,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
cur_size = fc->end - fc->start;
size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip));
rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size,
- size, ctxt->vcpu, NULL);
+ size, ctxt->vcpu, &ctxt->exception);
if (rc != X86EMUL_CONTINUE)
return rc;
fc->end += size;
@@ -564,7 +551,7 @@ static void *decode_register(u8 modrm_reg, unsigned long *regs,
static int read_descriptor(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
- ulong addr,
+ struct segmented_address addr,
u16 *size, unsigned long *address, int op_bytes)
{
int rc;
@@ -572,10 +559,13 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
if (op_bytes == 2)
op_bytes = 3;
*address = 0;
- rc = ops->read_std(addr, (unsigned long *)size, 2, ctxt->vcpu, NULL);
+ rc = ops->read_std(linear(ctxt, addr), (unsigned long *)size, 2,
+ ctxt->vcpu, &ctxt->exception);
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = ops->read_std(addr + 2, address, op_bytes, ctxt->vcpu, NULL);
+ addr.ea += 2;
+ rc = ops->read_std(linear(ctxt, addr), address, op_bytes,
+ ctxt->vcpu, &ctxt->exception);
return rc;
}
@@ -768,7 +758,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
break;
}
}
- op->addr.mem = modrm_ea;
+ op->addr.mem.ea = modrm_ea;
done:
return rc;
}
@@ -783,13 +773,13 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt,
op->type = OP_MEM;
switch (c->ad_bytes) {
case 2:
- op->addr.mem = insn_fetch(u16, 2, c->eip);
+ op->addr.mem.ea = insn_fetch(u16, 2, c->eip);
break;
case 4:
- op->addr.mem = insn_fetch(u32, 4, c->eip);
+ op->addr.mem.ea = insn_fetch(u32, 4, c->eip);
break;
case 8:
- op->addr.mem = insn_fetch(u64, 8, c->eip);
+ op->addr.mem.ea = insn_fetch(u64, 8, c->eip);
break;
}
done:
@@ -808,7 +798,7 @@ static void fetch_bit_operand(struct decode_cache *c)
else if (c->src.bytes == 4)
sv = (s32)c->src.val & (s32)mask;
- c->dst.addr.mem += (sv >> 3);
+ c->dst.addr.mem.ea += (sv >> 3);
}
/* only subword offset */
@@ -821,7 +811,6 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
{
int rc;
struct read_cache *mc = &ctxt->decode.mem_read;
- u32 err;
while (size) {
int n = min(size, 8u);
@@ -829,10 +818,8 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
if (mc->pos < mc->end)
goto read_cached;
- rc = ops->read_emulated(addr, mc->data + mc->end, n, &err,
- ctxt->vcpu);
- if (rc == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt);
+ rc = ops->read_emulated(addr, mc->data + mc->end, n,
+ &ctxt->exception, ctxt->vcpu);
if (rc != X86EMUL_CONTINUE)
return rc;
mc->end += n;
@@ -907,19 +894,15 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt,
struct desc_ptr dt;
u16 index = selector >> 3;
int ret;
- u32 err;
ulong addr;
get_descriptor_table_ptr(ctxt, ops, selector, &dt);
- if (dt.size < index * 8 + 7) {
- emulate_gp(ctxt, selector & 0xfffc);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (dt.size < index * 8 + 7)
+ return emulate_gp(ctxt, selector & 0xfffc);
addr = dt.address + index * 8;
- ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, &err);
- if (ret == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt);
+ ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu,
+ &ctxt->exception);
return ret;
}
@@ -931,21 +914,17 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
{
struct desc_ptr dt;
u16 index = selector >> 3;
- u32 err;
ulong addr;
int ret;
get_descriptor_table_ptr(ctxt, ops, selector, &dt);
- if (dt.size < index * 8 + 7) {
- emulate_gp(ctxt, selector & 0xfffc);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (dt.size < index * 8 + 7)
+ return emulate_gp(ctxt, selector & 0xfffc);
addr = dt.address + index * 8;
- ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, &err);
- if (ret == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt);
+ ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu,
+ &ctxt->exception);
return ret;
}
@@ -1092,7 +1071,6 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
{
int rc;
struct decode_cache *c = &ctxt->decode;
- u32 err;
switch (c->dst.type) {
case OP_REG:
@@ -1101,21 +1079,19 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
case OP_MEM:
if (c->lock_prefix)
rc = ops->cmpxchg_emulated(
- c->dst.addr.mem,
+ linear(ctxt, c->dst.addr.mem),
&c->dst.orig_val,
&c->dst.val,
c->dst.bytes,
- &err,
+ &ctxt->exception,
ctxt->vcpu);
else
rc = ops->write_emulated(
- c->dst.addr.mem,
+ linear(ctxt, c->dst.addr.mem),
&c->dst.val,
c->dst.bytes,
- &err,
+ &ctxt->exception,
ctxt->vcpu);
- if (rc == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
break;
@@ -1137,8 +1113,8 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt,
c->dst.bytes = c->op_bytes;
c->dst.val = c->src.val;
register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
- c->dst.addr.mem = register_address(c, ss_base(ctxt, ops),
- c->regs[VCPU_REGS_RSP]);
+ c->dst.addr.mem.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
+ c->dst.addr.mem.seg = VCPU_SREG_SS;
}
static int emulate_pop(struct x86_emulate_ctxt *ctxt,
@@ -1147,10 +1123,11 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
{
struct decode_cache *c = &ctxt->decode;
int rc;
+ struct segmented_address addr;
- rc = read_emulated(ctxt, ops, register_address(c, ss_base(ctxt, ops),
- c->regs[VCPU_REGS_RSP]),
- dest, len);
+ addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
+ addr.seg = VCPU_SREG_SS;
+ rc = read_emulated(ctxt, ops, linear(ctxt, addr), dest, len);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -1184,10 +1161,8 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
change_mask |= EFLG_IF;
break;
case X86EMUL_MODE_VM86:
- if (iopl < 3) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (iopl < 3)
+ return emulate_gp(ctxt, 0);
change_mask |= EFLG_IF;
break;
default: /* real mode */
@@ -1198,9 +1173,6 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
*(unsigned long *)dest =
(ctxt->eflags & ~change_mask) | (val & change_mask);
- if (rc == X86EMUL_PROPAGATE_FAULT)
- emulate_pf(ctxt);
-
return rc;
}
@@ -1287,7 +1259,6 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
gva_t cs_addr;
gva_t eip_addr;
u16 cs, eip;
- u32 err;
/* TODO: Add limit checks */
c->src.val = ctxt->eflags;
@@ -1317,11 +1288,11 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
eip_addr = dt.address + (irq << 2);
cs_addr = dt.address + (irq << 2) + 2;
- rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &err);
+ rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &ctxt->exception);
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &err);
+ rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &ctxt->exception);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -1370,10 +1341,8 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
if (rc != X86EMUL_CONTINUE)
return rc;
- if (temp_eip & ~0xffff) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (temp_eip & ~0xffff)
+ return emulate_gp(ctxt, 0);
rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
@@ -1624,10 +1593,8 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
/* syscall is not available in real mode */
if (ctxt->mode == X86EMUL_MODE_REAL ||
- ctxt->mode == X86EMUL_MODE_VM86) {
- emulate_ud(ctxt);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ ctxt->mode == X86EMUL_MODE_VM86)
+ return emulate_ud(ctxt);
setup_syscalls_segments(ctxt, ops, &cs, &ss);
@@ -1678,34 +1645,26 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
u16 cs_sel, ss_sel;
/* inject #GP if in real mode */
- if (ctxt->mode == X86EMUL_MODE_REAL) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (ctxt->mode == X86EMUL_MODE_REAL)
+ return emulate_gp(ctxt, 0);
/* XXX sysenter/sysexit have not been tested in 64bit mode.
* Therefore, we inject an #UD.
*/
- if (ctxt->mode == X86EMUL_MODE_PROT64) {
- emulate_ud(ctxt);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ return emulate_ud(ctxt);
setup_syscalls_segments(ctxt, ops, &cs, &ss);
ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
switch (ctxt->mode) {
case X86EMUL_MODE_PROT32:
- if ((msr_data & 0xfffc) == 0x0) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if ((msr_data & 0xfffc) == 0x0)
+ return emulate_gp(ctxt, 0);
break;
case X86EMUL_MODE_PROT64:
- if (msr_data == 0x0) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (msr_data == 0x0)
+ return emulate_gp(ctxt, 0);
break;
}
@@ -1745,10 +1704,8 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
/* inject #GP if in real mode or Virtual 8086 mode */
if (ctxt->mode == X86EMUL_MODE_REAL ||
- ctxt->mode == X86EMUL_MODE_VM86) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ ctxt->mode == X86EMUL_MODE_VM86)
+ return emulate_gp(ctxt, 0);
setup_syscalls_segments(ctxt, ops, &cs, &ss);
@@ -1763,18 +1720,14 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
switch (usermode) {
case X86EMUL_MODE_PROT32:
cs_sel = (u16)(msr_data + 16);
- if ((msr_data & 0xfffc) == 0x0) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if ((msr_data & 0xfffc) == 0x0)
+ return emulate_gp(ctxt, 0);
ss_sel = (u16)(msr_data + 24);
break;
case X86EMUL_MODE_PROT64:
cs_sel = (u16)(msr_data + 32);
- if (msr_data == 0x0) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (msr_data == 0x0)
+ return emulate_gp(ctxt, 0);
ss_sel = cs_sel + 8;
cs.d = 0;
cs.l = 1;
@@ -1934,33 +1887,27 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
{
struct tss_segment_16 tss_seg;
int ret;
- u32 err, new_tss_base = get_desc_base(new_desc);
+ u32 new_tss_base = get_desc_base(new_desc);
ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
save_state_to_tss16(ctxt, ops, &tss_seg);
ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
if (old_tss_sel != 0xffff) {
tss_seg.prev_task_link = old_tss_sel;
@@ -1968,12 +1915,10 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
ret = ops->write_std(new_tss_base,
&tss_seg.prev_task_link,
sizeof tss_seg.prev_task_link,
- ctxt->vcpu, &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ ctxt->vcpu, &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
}
return load_state_from_tss16(ctxt, ops, &tss_seg);
@@ -2013,10 +1958,8 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
struct decode_cache *c = &ctxt->decode;
int ret;
- if (ops->set_cr(3, tss->cr3, ctxt->vcpu)) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (ops->set_cr(3, tss->cr3, ctxt->vcpu))
+ return emulate_gp(ctxt, 0);
c->eip = tss->eip;
ctxt->eflags = tss->eflags | 2;
c->regs[VCPU_REGS_RAX] = tss->eax;
@@ -2076,33 +2019,27 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
{
struct tss_segment_32 tss_seg;
int ret;
- u32 err, new_tss_base = get_desc_base(new_desc);
+ u32 new_tss_base = get_desc_base(new_desc);
ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
save_state_to_tss32(ctxt, ops, &tss_seg);
ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
- &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
if (old_tss_sel != 0xffff) {
tss_seg.prev_task_link = old_tss_sel;
@@ -2110,12 +2047,10 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
ret = ops->write_std(new_tss_base,
&tss_seg.prev_task_link,
sizeof tss_seg.prev_task_link,
- ctxt->vcpu, &err);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
+ ctxt->vcpu, &ctxt->exception);
+ if (ret != X86EMUL_CONTINUE)
/* FIXME: need to provide precise fault address */
- emulate_pf(ctxt);
return ret;
- }
}
return load_state_from_tss32(ctxt, ops, &tss_seg);
@@ -2146,10 +2081,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
if (reason != TASK_SWITCH_IRET) {
if ((tss_selector & 3) > next_tss_desc.dpl ||
- ops->cpl(ctxt->vcpu) > next_tss_desc.dpl) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ ops->cpl(ctxt->vcpu) > next_tss_desc.dpl)
+ return emulate_gp(ctxt, 0);
}
desc_limit = desc_limit_scaled(&next_tss_desc);
@@ -2231,14 +2164,15 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
}
-static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
+static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned seg,
int reg, struct operand *op)
{
struct decode_cache *c = &ctxt->decode;
int df = (ctxt->eflags & EFLG_DF) ? -1 : 1;
register_address_increment(c, &c->regs[reg], df * op->bytes);
- op->addr.mem = register_address(c, base, c->regs[reg]);
+ op->addr.mem.ea = register_address(c, c->regs[reg]);
+ op->addr.mem.seg = seg;
}
static int em_push(struct x86_emulate_ctxt *ctxt)
@@ -2369,10 +2303,8 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
struct decode_cache *c = &ctxt->decode;
u64 tsc = 0;
- if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) {
- emulate_gp(ctxt, 0);
- return X86EMUL_PROPAGATE_FAULT;
- }
+ if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD))
+ return emulate_gp(ctxt, 0);
ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc);
c->regs[VCPU_REGS_RAX] = (u32)tsc;
c->regs[VCPU_REGS_RDX] = tsc >> 32;
@@ -2647,7 +2579,7 @@ static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op,
op->type = OP_IMM;
op->bytes = size;
- op->addr.mem = c->eip;
+ op->addr.mem.ea = c->eip;
/* NB. Immediates are sign-extended as necessary. */
switch (op->bytes) {
case 1:
@@ -2678,7 +2610,7 @@ done:
}
int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt)
+x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
{
struct x86_emulate_ops *ops = ctxt->ops;
struct decode_cache *c = &ctxt->decode;
@@ -2689,7 +2621,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
struct operand memop = { .type = OP_NONE };
c->eip = ctxt->eip;
- c->fetch.start = c->fetch.end = c->eip;
+ c->fetch.start = c->eip;
+ c->fetch.end = c->fetch.start + insn_len;
+ if (insn_len > 0)
+ memcpy(c->fetch.data, insn, insn_len);
ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
switch (mode) {
@@ -2803,10 +2738,8 @@ done_prefixes:
c->execute = opcode.u.execute;
/* Unrecognised? */
- if (c->d == 0 || (c->d & Undefined)) {
- DPRINTF("Cannot emulate %02x\n", c->b);
+ if (c->d == 0 || (c->d & Undefined))
return -1;
- }
if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
c->op_bytes = 8;
@@ -2831,14 +2764,13 @@ done_prefixes:
if (!c->has_seg_override)
set_seg_override(c, VCPU_SREG_DS);
- if (memop.type == OP_MEM && !(!c->twobyte && c->b == 0x8d))
- memop.addr.mem += seg_override_base(ctxt, ops, c);
+ memop.addr.mem.seg = seg_override(ctxt, ops, c);
if (memop.type == OP_MEM && c->ad_bytes != 8)
- memop.addr.mem = (u32)memop.addr.mem;
+ memop.addr.mem.ea = (u32)memop.addr.mem.ea;
if (memop.type == OP_MEM && c->rip_relative)
- memop.addr.mem += c->eip;
+ memop.addr.mem.ea += c->eip;
/*
* Decode and fetch the source operand: register, memory
@@ -2890,14 +2822,14 @@ done_prefixes:
case SrcSI:
c->src.type = OP_MEM;
c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->src.addr.mem =
- register_address(c, seg_override_base(ctxt, ops, c),
- c->regs[VCPU_REGS_RSI]);
+ c->src.addr.mem.ea =
+ register_address(c, c->regs[VCPU_REGS_RSI]);
+ c->src.addr.mem.seg = seg_override(ctxt, ops, c),
c->src.val = 0;
break;
case SrcImmFAddr:
c->src.type = OP_IMM;
- c->src.addr.mem = c->eip;
+ c->src.addr.mem.ea = c->eip;
c->src.bytes = c->op_bytes + 2;
insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
break;
@@ -2944,7 +2876,7 @@ done_prefixes:
break;
case DstImmUByte:
c->dst.type = OP_IMM;
- c->dst.addr.mem = c->eip;
+ c->dst.addr.mem.ea = c->eip;
c->dst.bytes = 1;
c->dst.val = insn_fetch(u8, 1, c->eip);
break;
@@ -2969,9 +2901,9 @@ done_prefixes:
case DstDI:
c->dst.type = OP_MEM;
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
- c->dst.addr.mem =
- register_address(c, es_base(ctxt, ops),
- c->regs[VCPU_REGS_RDI]);
+ c->dst.addr.mem.ea =
+ register_address(c, c->regs[VCPU_REGS_RDI]);
+ c->dst.addr.mem.seg = VCPU_SREG_ES;
c->dst.val = 0;
break;
case ImplicitOps:
@@ -3020,24 +2952,24 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
ctxt->decode.mem_read.pos = 0;
if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
- emulate_ud(ctxt);
+ rc = emulate_ud(ctxt);
goto done;
}
/* LOCK prefix is allowed only with some instructions */
if (c->lock_prefix && (!(c->d & Lock) || c->dst.type != OP_MEM)) {
- emulate_ud(ctxt);
+ rc = emulate_ud(ctxt);
goto done;
}
if ((c->d & SrcMask) == SrcMemFAddr && c->src.type != OP_MEM) {
- emulate_ud(ctxt);
+ rc = emulate_ud(ctxt);
goto done;
}
/* Privileged instruction can be executed only in CPL=0 */
if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) {
- emulate_gp(ctxt, 0);
+ rc = emulate_gp(ctxt, 0);
goto done;
}
@@ -3050,7 +2982,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
}
if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) {
- rc = read_emulated(ctxt, ops, c->src.addr.mem,
+ rc = read_emulated(ctxt, ops, linear(ctxt, c->src.addr.mem),
c->src.valptr, c->src.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -3058,7 +2990,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
}
if (c->src2.type == OP_MEM) {
- rc = read_emulated(ctxt, ops, c->src2.addr.mem,
+ rc = read_emulated(ctxt, ops, linear(ctxt, c->src2.addr.mem),
&c->src2.val, c->src2.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -3070,7 +3002,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
if ((c->dst.type == OP_MEM) && !(c->d & Mov)) {
/* optimisation - avoid slow emulated read if Mov */
- rc = read_emulated(ctxt, ops, c->dst.addr.mem,
+ rc = read_emulated(ctxt, ops, linear(ctxt, c->dst.addr.mem),
&c->dst.val, c->dst.bytes);
if (rc != X86EMUL_CONTINUE)
goto done;
@@ -3215,13 +3147,13 @@ special_insn:
break;
case 0x8c: /* mov r/m, sreg */
if (c->modrm_reg > VCPU_SREG_GS) {
- emulate_ud(ctxt);
+ rc = emulate_ud(ctxt);
goto done;
}
c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu);
break;
case 0x8d: /* lea r16/r32, m */
- c->dst.val = c->src.addr.mem;
+ c->dst.val = c->src.addr.mem.ea;
break;
case 0x8e: { /* mov seg, r/m16 */
uint16_t sel;
@@ -3230,7 +3162,7 @@ special_insn:
if (c->modrm_reg == VCPU_SREG_CS ||
c->modrm_reg > VCPU_SREG_GS) {
- emulate_ud(ctxt);
+ rc = emulate_ud(ctxt);
goto done;
}
@@ -3268,7 +3200,6 @@ special_insn:
break;
case 0xa6 ... 0xa7: /* cmps */
c->dst.type = OP_NONE; /* Disable writeback. */
- DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.addr.mem, c->dst.addr.mem);
goto cmp;
case 0xa8 ... 0xa9: /* test ax, imm */
goto test;
@@ -3363,7 +3294,7 @@ special_insn:
do_io_in:
c->dst.bytes = min(c->dst.bytes, 4u);
if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) {
- emulate_gp(ctxt, 0);
+ rc = emulate_gp(ctxt, 0);
goto done;
}
if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val,
@@ -3377,7 +3308,7 @@ special_insn:
c->src.bytes = min(c->src.bytes, 4u);
if (!emulator_io_permited(ctxt, ops, c->dst.val,
c->src.bytes)) {
- emulate_gp(ctxt, 0);
+ rc = emulate_gp(ctxt, 0);
goto done;
}
ops->pio_out_emulated(c->src.bytes, c->dst.val,
@@ -3402,14 +3333,14 @@ special_insn:
break;
case 0xfa: /* cli */
if (emulator_bad_iopl(ctxt, ops)) {
- emulate_gp(ctxt, 0);
+ rc = emulate_gp(ctxt, 0);
goto done;
} else
ctxt->eflags &= ~X86_EFLAGS_IF;
break;
case 0xfb: /* sti */
if (emulator_bad_iopl(ctxt, ops)) {
- emulate_gp(ctxt, 0);
+ rc = emulate_gp(ctxt, 0);
goto done;
} else {
ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
@@ -3449,11 +3380,11 @@ writeback:
c->dst.type = saved_dst_type;
if ((c->d & SrcMask) == SrcSI)
- string_addr_inc(ctxt, seg_override_base(ctxt, ops, c),
+ string_addr_inc(ctxt, seg_override(ctxt, ops, c),
VCPU_REGS_RSI, &c->src);
if ((c->d & DstMask) == DstDI)
- string_addr_inc(ctxt, es_base(ctxt, ops), VCPU_REGS_RDI,
+ string_addr_inc(ctxt, VCPU_SREG_ES, VCPU_REGS_RDI,
&c->dst);
if (c->rep_prefix && (c->d & String)) {
@@ -3482,6 +3413,8 @@ writeback:
ctxt->eip = c->eip;
done:
+ if (rc == X86EMUL_PROPAGATE_FAULT)
+ ctxt->have_exception = true;
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
twobyte_insn:
@@ -3544,9 +3477,11 @@ twobyte_insn:
break;
case 5: /* not defined */
emulate_ud(ctxt);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
case 7: /* invlpg*/
- emulate_invlpg(ctxt->vcpu, c->src.addr.mem);
+ emulate_invlpg(ctxt->vcpu,
+ linear(ctxt, c->src.addr.mem));
/* Disable writeback. */
c->dst.type = OP_NONE;
break;
@@ -3573,6 +3508,7 @@ twobyte_insn:
case 5 ... 7:
case 9 ... 15:
emulate_ud(ctxt);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu);
@@ -3581,6 +3517,7 @@ twobyte_insn:
if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
(c->modrm_reg == 4 || c->modrm_reg == 5)) {
emulate_ud(ctxt);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu);
@@ -3588,6 +3525,7 @@ twobyte_insn:
case 0x22: /* mov reg, cr */
if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) {
emulate_gp(ctxt, 0);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
c->dst.type = OP_NONE;
@@ -3596,6 +3534,7 @@ twobyte_insn:
if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
(c->modrm_reg == 4 || c->modrm_reg == 5)) {
emulate_ud(ctxt);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
@@ -3604,6 +3543,7 @@ twobyte_insn:
~0ULL : ~0U), ctxt->vcpu) < 0) {
/* #UD condition is already handled by the code above */
emulate_gp(ctxt, 0);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
@@ -3615,6 +3555,7 @@ twobyte_insn:
| ((u64)c->regs[VCPU_REGS_RDX] << 32);
if (ops->set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) {
emulate_gp(ctxt, 0);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
}
rc = X86EMUL_CONTINUE;
@@ -3623,6 +3564,7 @@ twobyte_insn:
/* rdmsr */
if (ops->get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) {
emulate_gp(ctxt, 0);
+ rc = X86EMUL_PROPAGATE_FAULT;
goto done;
} else {
c->regs[VCPU_REGS_RAX] = (u32)msr_data;
@@ -3785,6 +3727,5 @@ twobyte_insn:
goto writeback;
cannot_emulate:
- DPRINTF("Cannot emulate %02x\n", c->b);
return -1;
}
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index f628234fbeca..3cece05e4ac4 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
s->pics[1].elcr_mask = 0xde;
s->pics[0].pics_state = s;
s->pics[1].pics_state = s;
+ s->pics[0].isr_ack = 0xff;
+ s->pics[1].isr_ack = 0xff;
/*
* Initialize PIO device
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 975bb45329a1..3377d53fcd36 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -73,6 +73,13 @@ static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask)
return vcpu->arch.cr4 & mask;
}
+static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu)
+{
+ if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail))
+ kvm_x86_ops->decache_cr3(vcpu);
+ return vcpu->arch.cr3;
+}
+
static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu)
{
return kvm_read_cr4_bits(vcpu, ~0UL);
@@ -84,4 +91,19 @@ static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcpu)
| ((u64)(kvm_register_read(vcpu, VCPU_REGS_RDX) & -1u) << 32);
}
+static inline void enter_guest_mode(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.hflags |= HF_GUEST_MASK;
+}
+
+static inline void leave_guest_mode(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.hflags &= ~HF_GUEST_MASK;
+}
+
+static inline bool is_guest_mode(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.hflags & HF_GUEST_MASK;
+}
+
#endif
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 413f8973a855..93cf9d0d3653 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -277,7 +277,8 @@ static void apic_update_ppr(struct kvm_lapic *apic)
if (old_ppr != ppr) {
apic_set_reg(apic, APIC_PROCPRI, ppr);
- kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
+ if (ppr < old_ppr)
+ kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
}
}
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index fb8b376bf28c..9cafbb499813 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -18,9 +18,11 @@
*
*/
+#include "irq.h"
#include "mmu.h"
#include "x86.h"
#include "kvm_cache_regs.h"
+#include "x86.h"
#include <linux/kvm_host.h>
#include <linux/types.h>
@@ -194,7 +196,6 @@ static struct percpu_counter kvm_total_used_mmu_pages;
static u64 __read_mostly shadow_trap_nonpresent_pte;
static u64 __read_mostly shadow_notrap_nonpresent_pte;
-static u64 __read_mostly shadow_base_present_pte;
static u64 __read_mostly shadow_nx_mask;
static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */
static u64 __read_mostly shadow_user_mask;
@@ -213,12 +214,6 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte)
}
EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes);
-void kvm_mmu_set_base_ptes(u64 base_pte)
-{
- shadow_base_present_pte = base_pte;
-}
-EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes);
-
void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
u64 dirty_mask, u64 nx_mask, u64 x_mask)
{
@@ -482,46 +477,46 @@ static void kvm_mmu_page_set_gfn(struct kvm_mmu_page *sp, int index, gfn_t gfn)
}
/*
- * Return the pointer to the largepage write count for a given
- * gfn, handling slots that are not large page aligned.
+ * Return the pointer to the large page information for a given gfn,
+ * handling slots that are not large page aligned.
*/
-static int *slot_largepage_idx(gfn_t gfn,
- struct kvm_memory_slot *slot,
- int level)
+static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn,
+ struct kvm_memory_slot *slot,
+ int level)
{
unsigned long idx;
idx = (gfn >> KVM_HPAGE_GFN_SHIFT(level)) -
(slot->base_gfn >> KVM_HPAGE_GFN_SHIFT(level));
- return &slot->lpage_info[level - 2][idx].write_count;
+ return &slot->lpage_info[level - 2][idx];
}
static void account_shadowed(struct kvm *kvm, gfn_t gfn)
{
struct kvm_memory_slot *slot;
- int *write_count;
+ struct kvm_lpage_info *linfo;
int i;
slot = gfn_to_memslot(kvm, gfn);
for (i = PT_DIRECTORY_LEVEL;
i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
- write_count = slot_largepage_idx(gfn, slot, i);
- *write_count += 1;
+ linfo = lpage_info_slot(gfn, slot, i);
+ linfo->write_count += 1;
}
}
static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn)
{
struct kvm_memory_slot *slot;
- int *write_count;
+ struct kvm_lpage_info *linfo;
int i;
slot = gfn_to_memslot(kvm, gfn);
for (i = PT_DIRECTORY_LEVEL;
i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
- write_count = slot_largepage_idx(gfn, slot, i);
- *write_count -= 1;
- WARN_ON(*write_count < 0);
+ linfo = lpage_info_slot(gfn, slot, i);
+ linfo->write_count -= 1;
+ WARN_ON(linfo->write_count < 0);
}
}
@@ -530,12 +525,12 @@ static int has_wrprotected_page(struct kvm *kvm,
int level)
{
struct kvm_memory_slot *slot;
- int *largepage_idx;
+ struct kvm_lpage_info *linfo;
slot = gfn_to_memslot(kvm, gfn);
if (slot) {
- largepage_idx = slot_largepage_idx(gfn, slot, level);
- return *largepage_idx;
+ linfo = lpage_info_slot(gfn, slot, level);
+ return linfo->write_count;
}
return 1;
@@ -590,16 +585,15 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level)
{
struct kvm_memory_slot *slot;
- unsigned long idx;
+ struct kvm_lpage_info *linfo;
slot = gfn_to_memslot(kvm, gfn);
if (likely(level == PT_PAGE_TABLE_LEVEL))
return &slot->rmap[gfn - slot->base_gfn];
- idx = (gfn >> KVM_HPAGE_GFN_SHIFT(level)) -
- (slot->base_gfn >> KVM_HPAGE_GFN_SHIFT(level));
+ linfo = lpage_info_slot(gfn, slot, level);
- return &slot->lpage_info[level - 2][idx].rmap_pde;
+ return &linfo->rmap_pde;
}
/*
@@ -887,19 +881,16 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
end = start + (memslot->npages << PAGE_SHIFT);
if (hva >= start && hva < end) {
gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
+ gfn_t gfn = memslot->base_gfn + gfn_offset;
ret = handler(kvm, &memslot->rmap[gfn_offset], data);
for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
- unsigned long idx;
- int sh;
-
- sh = KVM_HPAGE_GFN_SHIFT(PT_DIRECTORY_LEVEL+j);
- idx = ((memslot->base_gfn+gfn_offset) >> sh) -
- (memslot->base_gfn >> sh);
- ret |= handler(kvm,
- &memslot->lpage_info[j][idx].rmap_pde,
- data);
+ struct kvm_lpage_info *linfo;
+
+ linfo = lpage_info_slot(gfn, memslot,
+ PT_DIRECTORY_LEVEL + j);
+ ret |= handler(kvm, &linfo->rmap_pde, data);
}
trace_kvm_age_page(hva, memslot, ret);
retval |= ret;
@@ -1161,7 +1152,7 @@ static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu,
}
static int nonpaging_sync_page(struct kvm_vcpu *vcpu,
- struct kvm_mmu_page *sp, bool clear_unsync)
+ struct kvm_mmu_page *sp)
{
return 1;
}
@@ -1291,7 +1282,7 @@ static int __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
if (clear_unsync)
kvm_unlink_unsync_page(vcpu->kvm, sp);
- if (vcpu->arch.mmu.sync_page(vcpu, sp, clear_unsync)) {
+ if (vcpu->arch.mmu.sync_page(vcpu, sp)) {
kvm_mmu_prepare_zap_page(vcpu->kvm, sp, invalid_list);
return 1;
}
@@ -1332,12 +1323,12 @@ static void kvm_sync_pages(struct kvm_vcpu *vcpu, gfn_t gfn)
continue;
WARN_ON(s->role.level != PT_PAGE_TABLE_LEVEL);
+ kvm_unlink_unsync_page(vcpu->kvm, s);
if ((s->role.cr4_pae != !!is_pae(vcpu)) ||
- (vcpu->arch.mmu.sync_page(vcpu, s, true))) {
+ (vcpu->arch.mmu.sync_page(vcpu, s))) {
kvm_mmu_prepare_zap_page(vcpu->kvm, s, &invalid_list);
continue;
}
- kvm_unlink_unsync_page(vcpu->kvm, s);
flush = true;
}
@@ -1963,9 +1954,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
unsigned pte_access, int user_fault,
int write_fault, int dirty, int level,
gfn_t gfn, pfn_t pfn, bool speculative,
- bool can_unsync, bool reset_host_protection)
+ bool can_unsync, bool host_writable)
{
- u64 spte;
+ u64 spte, entry = *sptep;
int ret = 0;
/*
@@ -1973,7 +1964,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
* whether the guest actually used the pte (in order to detect
* demand paging).
*/
- spte = shadow_base_present_pte;
+ spte = PT_PRESENT_MASK;
if (!speculative)
spte |= shadow_accessed_mask;
if (!dirty)
@@ -1990,8 +1981,10 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
kvm_is_mmio_pfn(pfn));
- if (reset_host_protection)
+ if (host_writable)
spte |= SPTE_HOST_WRITEABLE;
+ else
+ pte_access &= ~ACC_WRITE_MASK;
spte |= (u64)pfn << PAGE_SHIFT;
@@ -2036,6 +2029,14 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
set_pte:
update_spte(sptep, spte);
+ /*
+ * If we overwrite a writable spte with a read-only one we
+ * should flush remote TLBs. Otherwise rmap_write_protect
+ * will find a read-only spte, even though the writable spte
+ * might be cached on a CPU's TLB.
+ */
+ if (is_writable_pte(entry) && !is_writable_pte(*sptep))
+ kvm_flush_remote_tlbs(vcpu->kvm);
done:
return ret;
}
@@ -2045,7 +2046,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
int user_fault, int write_fault, int dirty,
int *ptwrite, int level, gfn_t gfn,
pfn_t pfn, bool speculative,
- bool reset_host_protection)
+ bool host_writable)
{
int was_rmapped = 0;
int rmap_count;
@@ -2080,7 +2081,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault,
dirty, level, gfn, pfn, speculative, true,
- reset_host_protection)) {
+ host_writable)) {
if (write_fault)
*ptwrite = 1;
kvm_mmu_flush_tlb(vcpu);
@@ -2211,7 +2212,8 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep)
}
static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int level, gfn_t gfn, pfn_t pfn)
+ int map_writable, int level, gfn_t gfn, pfn_t pfn,
+ bool prefault)
{
struct kvm_shadow_walk_iterator iterator;
struct kvm_mmu_page *sp;
@@ -2220,9 +2222,11 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
if (iterator.level == level) {
- mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
+ unsigned pte_access = ACC_ALL;
+
+ mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, pte_access,
0, write, 1, &pt_write,
- level, gfn, pfn, false, true);
+ level, gfn, pfn, prefault, map_writable);
direct_pte_prefetch(vcpu, iterator.sptep);
++vcpu->stat.pf_fixed;
break;
@@ -2277,12 +2281,17 @@ static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn)
return 1;
}
-static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
+static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
+ gva_t gva, pfn_t *pfn, bool write, bool *writable);
+
+static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn,
+ bool prefault)
{
int r;
int level;
pfn_t pfn;
unsigned long mmu_seq;
+ bool map_writable;
level = mapping_level(vcpu, gfn);
@@ -2297,7 +2306,9 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
mmu_seq = vcpu->kvm->mmu_notifier_seq;
smp_rmb();
- pfn = gfn_to_pfn(vcpu->kvm, gfn);
+
+ if (try_async_pf(vcpu, prefault, gfn, v, &pfn, write, &map_writable))
+ return 0;
/* mmio */
if (is_error_pfn(pfn))
@@ -2307,7 +2318,8 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
- r = __direct_map(vcpu, v, write, level, gfn, pfn);
+ r = __direct_map(vcpu, v, write, map_writable, level, gfn, pfn,
+ prefault);
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -2394,7 +2406,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
ASSERT(!VALID_PAGE(root));
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
- sp = kvm_mmu_get_page(vcpu, i << 30, i << 30,
+ sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
+ i << 30,
PT32_ROOT_LEVEL, 1, ACC_ALL,
NULL);
root = __pa(sp->spt);
@@ -2529,6 +2542,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
hpa_t root = vcpu->arch.mmu.root_hpa;
sp = page_header(root);
mmu_sync_children(vcpu, sp);
+ trace_kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
return;
}
for (i = 0; i < 4; ++i) {
@@ -2551,23 +2565,24 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
}
static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr,
- u32 access, u32 *error)
+ u32 access, struct x86_exception *exception)
{
- if (error)
- *error = 0;
+ if (exception)
+ exception->error_code = 0;
return vaddr;
}
static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gva_t vaddr,
- u32 access, u32 *error)
+ u32 access,
+ struct x86_exception *exception)
{
- if (error)
- *error = 0;
+ if (exception)
+ exception->error_code = 0;
return vcpu->arch.nested_mmu.translate_gpa(vcpu, vaddr, access);
}
static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
- u32 error_code)
+ u32 error_code, bool prefault)
{
gfn_t gfn;
int r;
@@ -2583,17 +2598,67 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
gfn = gva >> PAGE_SHIFT;
return nonpaging_map(vcpu, gva & PAGE_MASK,
- error_code & PFERR_WRITE_MASK, gfn);
+ error_code & PFERR_WRITE_MASK, gfn, prefault);
+}
+
+static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)
+{
+ struct kvm_arch_async_pf arch;
+
+ arch.token = (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
+ arch.gfn = gfn;
+ arch.direct_map = vcpu->arch.mmu.direct_map;
+ arch.cr3 = vcpu->arch.mmu.get_cr3(vcpu);
+
+ return kvm_setup_async_pf(vcpu, gva, gfn, &arch);
}
-static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
- u32 error_code)
+static bool can_do_async_pf(struct kvm_vcpu *vcpu)
+{
+ if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
+ kvm_event_needs_reinjection(vcpu)))
+ return false;
+
+ return kvm_x86_ops->interrupt_allowed(vcpu);
+}
+
+static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
+ gva_t gva, pfn_t *pfn, bool write, bool *writable)
+{
+ bool async;
+
+ *pfn = gfn_to_pfn_async(vcpu->kvm, gfn, &async, write, writable);
+
+ if (!async)
+ return false; /* *pfn has correct page already */
+
+ put_page(pfn_to_page(*pfn));
+
+ if (!prefault && can_do_async_pf(vcpu)) {
+ trace_kvm_try_async_get_page(gva, gfn);
+ if (kvm_find_async_pf_gfn(vcpu, gfn)) {
+ trace_kvm_async_pf_doublefault(gva, gfn);
+ kvm_make_request(KVM_REQ_APF_HALT, vcpu);
+ return true;
+ } else if (kvm_arch_setup_async_pf(vcpu, gva, gfn))
+ return true;
+ }
+
+ *pfn = gfn_to_pfn_prot(vcpu->kvm, gfn, write, writable);
+
+ return false;
+}
+
+static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
+ bool prefault)
{
pfn_t pfn;
int r;
int level;
gfn_t gfn = gpa >> PAGE_SHIFT;
unsigned long mmu_seq;
+ int write = error_code & PFERR_WRITE_MASK;
+ bool map_writable;
ASSERT(vcpu);
ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa));
@@ -2608,15 +2673,19 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
mmu_seq = vcpu->kvm->mmu_notifier_seq;
smp_rmb();
- pfn = gfn_to_pfn(vcpu->kvm, gfn);
+
+ if (try_async_pf(vcpu, prefault, gfn, gpa, &pfn, write, &map_writable))
+ return 0;
+
+ /* mmio */
if (is_error_pfn(pfn))
return kvm_handle_bad_page(vcpu->kvm, gfn, pfn);
spin_lock(&vcpu->kvm->mmu_lock);
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
- r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
- level, gfn, pfn);
+ r = __direct_map(vcpu, gpa, write, map_writable,
+ level, gfn, pfn, prefault);
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
@@ -2658,18 +2727,19 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu)
static void paging_new_cr3(struct kvm_vcpu *vcpu)
{
- pgprintk("%s: cr3 %lx\n", __func__, vcpu->arch.cr3);
+ pgprintk("%s: cr3 %lx\n", __func__, kvm_read_cr3(vcpu));
mmu_free_roots(vcpu);
}
static unsigned long get_cr3(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.cr3;
+ return kvm_read_cr3(vcpu);
}
-static void inject_page_fault(struct kvm_vcpu *vcpu)
+static void inject_page_fault(struct kvm_vcpu *vcpu,
+ struct x86_exception *fault)
{
- vcpu->arch.mmu.inject_page_fault(vcpu);
+ vcpu->arch.mmu.inject_page_fault(vcpu, fault);
}
static void paging_free(struct kvm_vcpu *vcpu)
@@ -2815,6 +2885,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
{
struct kvm_mmu *context = vcpu->arch.walk_mmu;
+ context->base_role.word = 0;
context->new_cr3 = nonpaging_new_cr3;
context->page_fault = tdp_page_fault;
context->free = nonpaging_free;
@@ -3007,9 +3078,6 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
return;
}
- if (is_rsvd_bits_set(&vcpu->arch.mmu, *(u64 *)new, PT_PAGE_TABLE_LEVEL))
- return;
-
++vcpu->kvm->stat.mmu_pte_updated;
if (!sp->role.cr4_pae)
paging32_update_pte(vcpu, sp, spte, new);
@@ -3263,12 +3331,13 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
}
}
-int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
+int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code,
+ void *insn, int insn_len)
{
int r;
enum emulation_result er;
- r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code);
+ r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code, false);
if (r < 0)
goto out;
@@ -3281,7 +3350,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
if (r)
goto out;
- er = emulate_instruction(vcpu, cr2, error_code, 0);
+ er = x86_emulate_instruction(vcpu, cr2, 0, insn, insn_len);
switch (er) {
case EMULATE_DONE:
@@ -3376,11 +3445,14 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
if (!test_bit(slot, sp->slot_bitmap))
continue;
+ if (sp->role.level != PT_PAGE_TABLE_LEVEL)
+ continue;
+
pt = sp->spt;
for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
/* avoid RMW */
if (is_writable_pte(pt[i]))
- pt[i] &= ~PT_WRITABLE_MASK;
+ update_spte(&pt[i], pt[i] & ~PT_WRITABLE_MASK);
}
kvm_flush_remote_tlbs(kvm);
}
@@ -3462,13 +3534,6 @@ static void mmu_destroy_caches(void)
kmem_cache_destroy(mmu_page_header_cache);
}
-void kvm_mmu_module_exit(void)
-{
- mmu_destroy_caches();
- percpu_counter_destroy(&kvm_total_used_mmu_pages);
- unregister_shrinker(&mmu_shrinker);
-}
-
int kvm_mmu_module_init(void)
{
pte_chain_cache = kmem_cache_create("kvm_pte_chain",
@@ -3565,7 +3630,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu,
static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu)
{
- (void)kvm_set_cr3(vcpu, vcpu->arch.cr3);
+ (void)kvm_set_cr3(vcpu, kvm_read_cr3(vcpu));
return 1;
}
@@ -3661,12 +3726,6 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
}
EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
-#ifdef CONFIG_KVM_MMU_AUDIT
-#include "mmu_audit.c"
-#else
-static void mmu_audit_disable(void) { }
-#endif
-
void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
{
ASSERT(vcpu);
@@ -3674,5 +3733,18 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
destroy_kvm_mmu(vcpu);
free_mmu_pages(vcpu);
mmu_free_memory_caches(vcpu);
+}
+
+#ifdef CONFIG_KVM_MMU_AUDIT
+#include "mmu_audit.c"
+#else
+static void mmu_audit_disable(void) { }
+#endif
+
+void kvm_mmu_module_exit(void)
+{
+ mmu_destroy_caches();
+ percpu_counter_destroy(&kvm_total_used_mmu_pages);
+ unregister_shrinker(&mmu_shrinker);
mmu_audit_disable();
}
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index ba2bcdde6221..5f6223b8bcf7 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -19,11 +19,9 @@
#include <linux/ratelimit.h>
-static int audit_point;
-
-#define audit_printk(fmt, args...) \
+#define audit_printk(kvm, fmt, args...) \
printk(KERN_ERR "audit: (%s) error: " \
- fmt, audit_point_name[audit_point], ##args)
+ fmt, audit_point_name[kvm->arch.audit_point], ##args)
typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level);
@@ -97,18 +95,21 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
if (sp->unsync) {
if (level != PT_PAGE_TABLE_LEVEL) {
- audit_printk("unsync sp: %p level = %d\n", sp, level);
+ audit_printk(vcpu->kvm, "unsync sp: %p "
+ "level = %d\n", sp, level);
return;
}
if (*sptep == shadow_notrap_nonpresent_pte) {
- audit_printk("notrap spte in unsync sp: %p\n", sp);
+ audit_printk(vcpu->kvm, "notrap spte in unsync "
+ "sp: %p\n", sp);
return;
}
}
if (sp->role.direct && *sptep == shadow_notrap_nonpresent_pte) {
- audit_printk("notrap spte in direct sp: %p\n", sp);
+ audit_printk(vcpu->kvm, "notrap spte in direct sp: %p\n",
+ sp);
return;
}
@@ -125,8 +126,9 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
hpa = pfn << PAGE_SHIFT;
if ((*sptep & PT64_BASE_ADDR_MASK) != hpa)
- audit_printk("levels %d pfn %llx hpa %llx ent %llxn",
- vcpu->arch.mmu.root_level, pfn, hpa, *sptep);
+ audit_printk(vcpu->kvm, "levels %d pfn %llx hpa %llx "
+ "ent %llxn", vcpu->arch.mmu.root_level, pfn,
+ hpa, *sptep);
}
static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
@@ -142,8 +144,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
if (!gfn_to_memslot(kvm, gfn)) {
if (!printk_ratelimit())
return;
- audit_printk("no memslot for gfn %llx\n", gfn);
- audit_printk("index %ld of sp (gfn=%llx)\n",
+ audit_printk(kvm, "no memslot for gfn %llx\n", gfn);
+ audit_printk(kvm, "index %ld of sp (gfn=%llx)\n",
(long int)(sptep - rev_sp->spt), rev_sp->gfn);
dump_stack();
return;
@@ -153,7 +155,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
if (!*rmapp) {
if (!printk_ratelimit())
return;
- audit_printk("no rmap for writable spte %llx\n", *sptep);
+ audit_printk(kvm, "no rmap for writable spte %llx\n",
+ *sptep);
dump_stack();
}
}
@@ -168,8 +171,9 @@ static void audit_spte_after_sync(struct kvm_vcpu *vcpu, u64 *sptep, int level)
{
struct kvm_mmu_page *sp = page_header(__pa(sptep));
- if (audit_point == AUDIT_POST_SYNC && sp->unsync)
- audit_printk("meet unsync sp(%p) after sync root.\n", sp);
+ if (vcpu->kvm->arch.audit_point == AUDIT_POST_SYNC && sp->unsync)
+ audit_printk(vcpu->kvm, "meet unsync sp(%p) after sync "
+ "root.\n", sp);
}
static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
@@ -202,8 +206,9 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
spte = rmap_next(kvm, rmapp, NULL);
while (spte) {
if (is_writable_pte(*spte))
- audit_printk("shadow page has writable mappings: gfn "
- "%llx role %x\n", sp->gfn, sp->role.word);
+ audit_printk(kvm, "shadow page has writable "
+ "mappings: gfn %llx role %x\n",
+ sp->gfn, sp->role.word);
spte = rmap_next(kvm, rmapp, spte);
}
}
@@ -238,7 +243,7 @@ static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int point)
if (!__ratelimit(&ratelimit_state))
return;
- audit_point = point;
+ vcpu->kvm->arch.audit_point = point;
audit_all_active_sps(vcpu->kvm);
audit_vcpu_spte(vcpu);
}
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index cd7a833a3b52..53210f1e94c2 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -72,7 +72,7 @@ struct guest_walker {
unsigned pt_access;
unsigned pte_access;
gfn_t gfn;
- u32 error_code;
+ struct x86_exception fault;
};
static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl)
@@ -266,21 +266,23 @@ walk:
return 1;
error:
- walker->error_code = 0;
+ walker->fault.vector = PF_VECTOR;
+ walker->fault.error_code_valid = true;
+ walker->fault.error_code = 0;
if (present)
- walker->error_code |= PFERR_PRESENT_MASK;
+ walker->fault.error_code |= PFERR_PRESENT_MASK;
- walker->error_code |= write_fault | user_fault;
+ walker->fault.error_code |= write_fault | user_fault;
if (fetch_fault && mmu->nx)
- walker->error_code |= PFERR_FETCH_MASK;
+ walker->fault.error_code |= PFERR_FETCH_MASK;
if (rsvd_fault)
- walker->error_code |= PFERR_RSVD_MASK;
+ walker->fault.error_code |= PFERR_RSVD_MASK;
- vcpu->arch.fault.address = addr;
- vcpu->arch.fault.error_code = walker->error_code;
+ walker->fault.address = addr;
+ walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu;
- trace_kvm_mmu_walker_error(walker->error_code);
+ trace_kvm_mmu_walker_error(walker->fault.error_code);
return 0;
}
@@ -299,25 +301,42 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker,
addr, access);
}
+static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp, u64 *spte,
+ pt_element_t gpte)
+{
+ u64 nonpresent = shadow_trap_nonpresent_pte;
+
+ if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL))
+ goto no_present;
+
+ if (!is_present_gpte(gpte)) {
+ if (!sp->unsync)
+ nonpresent = shadow_notrap_nonpresent_pte;
+ goto no_present;
+ }
+
+ if (!(gpte & PT_ACCESSED_MASK))
+ goto no_present;
+
+ return false;
+
+no_present:
+ drop_spte(vcpu->kvm, spte, nonpresent);
+ return true;
+}
+
static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
u64 *spte, const void *pte)
{
pt_element_t gpte;
unsigned pte_access;
pfn_t pfn;
- u64 new_spte;
gpte = *(const pt_element_t *)pte;
- if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
- if (!is_present_gpte(gpte)) {
- if (sp->unsync)
- new_spte = shadow_trap_nonpresent_pte;
- else
- new_spte = shadow_notrap_nonpresent_pte;
- __set_spte(spte, new_spte);
- }
+ if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte))
return;
- }
+
pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte);
pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn)
@@ -329,7 +348,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
return;
kvm_get_pfn(pfn);
/*
- * we call mmu_set_spte() with reset_host_protection = true beacuse that
+ * we call mmu_set_spte() with host_writable = true beacuse that
* vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1).
*/
mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0,
@@ -364,7 +383,6 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
u64 *sptep)
{
struct kvm_mmu_page *sp;
- struct kvm_mmu *mmu = &vcpu->arch.mmu;
pt_element_t *gptep = gw->prefetch_ptes;
u64 *spte;
int i;
@@ -395,14 +413,7 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
gpte = gptep[i];
- if (!is_present_gpte(gpte) ||
- is_rsvd_bits_set(mmu, gpte, PT_PAGE_TABLE_LEVEL)) {
- if (!sp->unsync)
- __set_spte(spte, shadow_notrap_nonpresent_pte);
- continue;
- }
-
- if (!(gpte & PT_ACCESSED_MASK))
+ if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte))
continue;
pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
@@ -427,7 +438,8 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
struct guest_walker *gw,
int user_fault, int write_fault, int hlevel,
- int *ptwrite, pfn_t pfn)
+ int *ptwrite, pfn_t pfn, bool map_writable,
+ bool prefault)
{
unsigned access = gw->pt_access;
struct kvm_mmu_page *sp = NULL;
@@ -501,7 +513,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
mmu_set_spte(vcpu, it.sptep, access, gw->pte_access & access,
user_fault, write_fault, dirty, ptwrite, it.level,
- gw->gfn, pfn, false, true);
+ gw->gfn, pfn, prefault, map_writable);
FNAME(pte_prefetch)(vcpu, gw, it.sptep);
return it.sptep;
@@ -527,8 +539,8 @@ out_gpte_changed:
* Returns: 1 if we need to emulate the instruction, 0 otherwise, or
* a negative value on error.
*/
-static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
- u32 error_code)
+static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
+ bool prefault)
{
int write_fault = error_code & PFERR_WRITE_MASK;
int user_fault = error_code & PFERR_USER_MASK;
@@ -539,6 +551,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
pfn_t pfn;
int level = PT_PAGE_TABLE_LEVEL;
unsigned long mmu_seq;
+ bool map_writable;
pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
@@ -556,8 +569,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
*/
if (!r) {
pgprintk("%s: guest page fault\n", __func__);
- inject_page_fault(vcpu);
- vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
+ if (!prefault) {
+ inject_page_fault(vcpu, &walker.fault);
+ /* reset fork detector */
+ vcpu->arch.last_pt_write_count = 0;
+ }
return 0;
}
@@ -568,7 +584,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
mmu_seq = vcpu->kvm->mmu_notifier_seq;
smp_rmb();
- pfn = gfn_to_pfn(vcpu->kvm, walker.gfn);
+
+ if (try_async_pf(vcpu, prefault, walker.gfn, addr, &pfn, write_fault,
+ &map_writable))
+ return 0;
/* mmio */
if (is_error_pfn(pfn))
@@ -581,7 +600,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
kvm_mmu_free_some_pages(vcpu);
sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
- level, &write_pt, pfn);
+ level, &write_pt, pfn, map_writable, prefault);
(void)sptep;
pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__,
sptep, *sptep, write_pt);
@@ -661,7 +680,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
}
static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
- u32 *error)
+ struct x86_exception *exception)
{
struct guest_walker walker;
gpa_t gpa = UNMAPPED_GVA;
@@ -672,14 +691,15 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
if (r) {
gpa = gfn_to_gpa(walker.gfn);
gpa |= vaddr & ~PAGE_MASK;
- } else if (error)
- *error = walker.error_code;
+ } else if (exception)
+ *exception = walker.fault;
return gpa;
}
static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr,
- u32 access, u32 *error)
+ u32 access,
+ struct x86_exception *exception)
{
struct guest_walker walker;
gpa_t gpa = UNMAPPED_GVA;
@@ -690,8 +710,8 @@ static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr,
if (r) {
gpa = gfn_to_gpa(walker.gfn);
gpa |= vaddr & ~PAGE_MASK;
- } else if (error)
- *error = walker.error_code;
+ } else if (exception)
+ *exception = walker.fault;
return gpa;
}
@@ -730,12 +750,19 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
* Using the cached information from sp->gfns is safe because:
* - The spte has a reference to the struct page, so the pfn for a given gfn
* can't change unless all sptes pointing to it are nuked first.
+ *
+ * Note:
+ * We should flush all tlbs if spte is dropped even though guest is
+ * responsible for it. Since if we don't, kvm_mmu_notifier_invalidate_page
+ * and kvm_mmu_notifier_invalidate_range_start detect the mapping page isn't
+ * used by guest then tlbs are not flushed, so guest is allowed to access the
+ * freed pages.
+ * And we increase kvm->tlbs_dirty to delay tlbs flush in this case.
*/
-static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
- bool clear_unsync)
+static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
{
int i, offset, nr_present;
- bool reset_host_protection;
+ bool host_writable;
gpa_t first_pte_gpa;
offset = nr_present = 0;
@@ -764,31 +791,27 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
return -EINVAL;
gfn = gpte_to_gfn(gpte);
- if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)
- || gfn != sp->gfns[i] || !is_present_gpte(gpte)
- || !(gpte & PT_ACCESSED_MASK)) {
- u64 nonpresent;
- if (is_present_gpte(gpte) || !clear_unsync)
- nonpresent = shadow_trap_nonpresent_pte;
- else
- nonpresent = shadow_notrap_nonpresent_pte;
- drop_spte(vcpu->kvm, &sp->spt[i], nonpresent);
+ if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) {
+ vcpu->kvm->tlbs_dirty++;
+ continue;
+ }
+
+ if (gfn != sp->gfns[i]) {
+ drop_spte(vcpu->kvm, &sp->spt[i],
+ shadow_trap_nonpresent_pte);
+ vcpu->kvm->tlbs_dirty++;
continue;
}
nr_present++;
pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
- if (!(sp->spt[i] & SPTE_HOST_WRITEABLE)) {
- pte_access &= ~ACC_WRITE_MASK;
- reset_host_protection = 0;
- } else {
- reset_host_protection = 1;
- }
+ host_writable = sp->spt[i] & SPTE_HOST_WRITEABLE;
+
set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn,
spte_to_pfn(sp->spt[i]), true, false,
- reset_host_protection);
+ host_writable);
}
return !nr_present;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1ca12298ffc7..25bd1bc5aad2 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -31,6 +31,7 @@
#include <asm/tlbflush.h>
#include <asm/desc.h>
+#include <asm/kvm_para.h>
#include <asm/virtext.h>
#include "trace.h"
@@ -50,6 +51,10 @@ MODULE_LICENSE("GPL");
#define SVM_FEATURE_LBRV (1 << 1)
#define SVM_FEATURE_SVML (1 << 2)
#define SVM_FEATURE_NRIP (1 << 3)
+#define SVM_FEATURE_TSC_RATE (1 << 4)
+#define SVM_FEATURE_VMCB_CLEAN (1 << 5)
+#define SVM_FEATURE_FLUSH_ASID (1 << 6)
+#define SVM_FEATURE_DECODE_ASSIST (1 << 7)
#define SVM_FEATURE_PAUSE_FILTER (1 << 10)
#define NESTED_EXIT_HOST 0 /* Exit handled on host level */
@@ -97,10 +102,8 @@ struct nested_state {
unsigned long vmexit_rax;
/* cache for intercepts of the guest */
- u16 intercept_cr_read;
- u16 intercept_cr_write;
- u16 intercept_dr_read;
- u16 intercept_dr_write;
+ u32 intercept_cr;
+ u32 intercept_dr;
u32 intercept_exceptions;
u64 intercept;
@@ -123,7 +126,12 @@ struct vcpu_svm {
u64 next_rip;
u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
- u64 host_gs_base;
+ struct {
+ u16 fs;
+ u16 gs;
+ u16 ldt;
+ u64 gs_base;
+ } host;
u32 *msrpm;
@@ -133,6 +141,7 @@ struct vcpu_svm {
unsigned int3_injected;
unsigned long int3_rip;
+ u32 apf_reason;
};
#define MSR_INVALID 0xffffffffU
@@ -180,14 +189,151 @@ static int nested_svm_vmexit(struct vcpu_svm *svm);
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code);
+enum {
+ VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
+ pause filter count */
+ VMCB_PERM_MAP, /* IOPM Base and MSRPM Base */
+ VMCB_ASID, /* ASID */
+ VMCB_INTR, /* int_ctl, int_vector */
+ VMCB_NPT, /* npt_en, nCR3, gPAT */
+ VMCB_CR, /* CR0, CR3, CR4, EFER */
+ VMCB_DR, /* DR6, DR7 */
+ VMCB_DT, /* GDT, IDT */
+ VMCB_SEG, /* CS, DS, SS, ES, CPL */
+ VMCB_CR2, /* CR2 only */
+ VMCB_LBR, /* DBGCTL, BR_FROM, BR_TO, LAST_EX_FROM, LAST_EX_TO */
+ VMCB_DIRTY_MAX,
+};
+
+/* TPR and CR2 are always written before VMRUN */
+#define VMCB_ALWAYS_DIRTY_MASK ((1U << VMCB_INTR) | (1U << VMCB_CR2))
+
+static inline void mark_all_dirty(struct vmcb *vmcb)
+{
+ vmcb->control.clean = 0;
+}
+
+static inline void mark_all_clean(struct vmcb *vmcb)
+{
+ vmcb->control.clean = ((1 << VMCB_DIRTY_MAX) - 1)
+ & ~VMCB_ALWAYS_DIRTY_MASK;
+}
+
+static inline void mark_dirty(struct vmcb *vmcb, int bit)
+{
+ vmcb->control.clean &= ~(1 << bit);
+}
+
static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
{
return container_of(vcpu, struct vcpu_svm, vcpu);
}
-static inline bool is_nested(struct vcpu_svm *svm)
+static void recalc_intercepts(struct vcpu_svm *svm)
+{
+ struct vmcb_control_area *c, *h;
+ struct nested_state *g;
+
+ mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
+
+ if (!is_guest_mode(&svm->vcpu))
+ return;
+
+ c = &svm->vmcb->control;
+ h = &svm->nested.hsave->control;
+ g = &svm->nested;
+
+ c->intercept_cr = h->intercept_cr | g->intercept_cr;
+ c->intercept_dr = h->intercept_dr | g->intercept_dr;
+ c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions;
+ c->intercept = h->intercept | g->intercept;
+}
+
+static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm)
+{
+ if (is_guest_mode(&svm->vcpu))
+ return svm->nested.hsave;
+ else
+ return svm->vmcb;
+}
+
+static inline void set_cr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_cr |= (1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void clr_cr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_cr &= ~(1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ return vmcb->control.intercept_cr & (1U << bit);
+}
+
+static inline void set_dr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_dr |= (1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_dr &= ~(1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void set_exception_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_exceptions |= (1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void clr_exception_intercept(struct vcpu_svm *svm, int bit)
{
- return svm->nested.vmcb;
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept_exceptions &= ~(1U << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void set_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept |= (1ULL << bit);
+
+ recalc_intercepts(svm);
+}
+
+static inline void clr_intercept(struct vcpu_svm *svm, int bit)
+{
+ struct vmcb *vmcb = get_host_vmcb(svm);
+
+ vmcb->control.intercept &= ~(1ULL << bit);
+
+ recalc_intercepts(svm);
}
static inline void enable_gif(struct vcpu_svm *svm)
@@ -264,11 +410,6 @@ static u32 svm_msrpm_offset(u32 msr)
#define MAX_INST_SIZE 15
-static inline u32 svm_has(u32 feat)
-{
- return svm_features & feat;
-}
-
static inline void clgi(void)
{
asm volatile (__ex(SVM_CLGI));
@@ -284,16 +425,6 @@ static inline void invlpga(unsigned long addr, u32 asid)
asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid));
}
-static inline void force_new_asid(struct kvm_vcpu *vcpu)
-{
- to_svm(vcpu)->asid_generation--;
-}
-
-static inline void flush_guest_tlb(struct kvm_vcpu *vcpu)
-{
- force_new_asid(vcpu);
-}
-
static int get_npt_level(void)
{
#ifdef CONFIG_X86_64
@@ -310,6 +441,7 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
efer &= ~EFER_LME;
to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
+ mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR);
}
static int is_external_interrupt(u32 info)
@@ -347,7 +479,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
svm->next_rip = svm->vmcb->control.next_rip;
if (!svm->next_rip) {
- if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) !=
+ if (emulate_instruction(vcpu, EMULTYPE_SKIP) !=
EMULATE_DONE)
printk(KERN_DEBUG "%s: NOP\n", __func__);
return;
@@ -374,7 +506,7 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
nested_svm_check_exception(svm, nr, has_error_code, error_code))
return;
- if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) {
+ if (nr == BP_VECTOR && !static_cpu_has(X86_FEATURE_NRIPS)) {
unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu);
/*
@@ -670,7 +802,7 @@ static __init int svm_hardware_setup(void)
svm_features = cpuid_edx(SVM_CPUID_FUNC);
- if (!svm_has(SVM_FEATURE_NPT))
+ if (!boot_cpu_has(X86_FEATURE_NPT))
npt_enabled = false;
if (npt_enabled && !npt) {
@@ -725,13 +857,15 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
struct vcpu_svm *svm = to_svm(vcpu);
u64 g_tsc_offset = 0;
- if (is_nested(svm)) {
+ if (is_guest_mode(vcpu)) {
g_tsc_offset = svm->vmcb->control.tsc_offset -
svm->nested.hsave->control.tsc_offset;
svm->nested.hsave->control.tsc_offset = offset;
}
svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
+
+ mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
}
static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment)
@@ -739,8 +873,9 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment)
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->control.tsc_offset += adjustment;
- if (is_nested(svm))
+ if (is_guest_mode(vcpu))
svm->nested.hsave->control.tsc_offset += adjustment;
+ mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
}
static void init_vmcb(struct vcpu_svm *svm)
@@ -749,62 +884,62 @@ static void init_vmcb(struct vcpu_svm *svm)
struct vmcb_save_area *save = &svm->vmcb->save;
svm->vcpu.fpu_active = 1;
+ svm->vcpu.arch.hflags = 0;
- control->intercept_cr_read = INTERCEPT_CR0_MASK |
- INTERCEPT_CR3_MASK |
- INTERCEPT_CR4_MASK;
-
- control->intercept_cr_write = INTERCEPT_CR0_MASK |
- INTERCEPT_CR3_MASK |
- INTERCEPT_CR4_MASK |
- INTERCEPT_CR8_MASK;
-
- control->intercept_dr_read = 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_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) |
- (1 << UD_VECTOR) |
- (1 << MC_VECTOR);
-
-
- control->intercept = (1ULL << INTERCEPT_INTR) |
- (1ULL << INTERCEPT_NMI) |
- (1ULL << INTERCEPT_SMI) |
- (1ULL << INTERCEPT_SELECTIVE_CR0) |
- (1ULL << INTERCEPT_CPUID) |
- (1ULL << INTERCEPT_INVD) |
- (1ULL << INTERCEPT_HLT) |
- (1ULL << INTERCEPT_INVLPG) |
- (1ULL << INTERCEPT_INVLPGA) |
- (1ULL << INTERCEPT_IOIO_PROT) |
- (1ULL << INTERCEPT_MSR_PROT) |
- (1ULL << INTERCEPT_TASK_SWITCH) |
- (1ULL << INTERCEPT_SHUTDOWN) |
- (1ULL << INTERCEPT_VMRUN) |
- (1ULL << INTERCEPT_VMMCALL) |
- (1ULL << INTERCEPT_VMLOAD) |
- (1ULL << INTERCEPT_VMSAVE) |
- (1ULL << INTERCEPT_STGI) |
- (1ULL << INTERCEPT_CLGI) |
- (1ULL << INTERCEPT_SKINIT) |
- (1ULL << INTERCEPT_WBINVD) |
- (1ULL << INTERCEPT_MONITOR) |
- (1ULL << INTERCEPT_MWAIT);
+ set_cr_intercept(svm, INTERCEPT_CR0_READ);
+ set_cr_intercept(svm, INTERCEPT_CR3_READ);
+ set_cr_intercept(svm, INTERCEPT_CR4_READ);
+ set_cr_intercept(svm, INTERCEPT_CR0_WRITE);
+ set_cr_intercept(svm, INTERCEPT_CR3_WRITE);
+ set_cr_intercept(svm, INTERCEPT_CR4_WRITE);
+ set_cr_intercept(svm, INTERCEPT_CR8_WRITE);
+
+ set_dr_intercept(svm, INTERCEPT_DR0_READ);
+ set_dr_intercept(svm, INTERCEPT_DR1_READ);
+ set_dr_intercept(svm, INTERCEPT_DR2_READ);
+ set_dr_intercept(svm, INTERCEPT_DR3_READ);
+ set_dr_intercept(svm, INTERCEPT_DR4_READ);
+ set_dr_intercept(svm, INTERCEPT_DR5_READ);
+ set_dr_intercept(svm, INTERCEPT_DR6_READ);
+ set_dr_intercept(svm, INTERCEPT_DR7_READ);
+
+ set_dr_intercept(svm, INTERCEPT_DR0_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR1_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR2_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR3_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR4_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR5_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR6_WRITE);
+ set_dr_intercept(svm, INTERCEPT_DR7_WRITE);
+
+ set_exception_intercept(svm, PF_VECTOR);
+ set_exception_intercept(svm, UD_VECTOR);
+ set_exception_intercept(svm, MC_VECTOR);
+
+ set_intercept(svm, INTERCEPT_INTR);
+ set_intercept(svm, INTERCEPT_NMI);
+ set_intercept(svm, INTERCEPT_SMI);
+ set_intercept(svm, INTERCEPT_SELECTIVE_CR0);
+ set_intercept(svm, INTERCEPT_CPUID);
+ set_intercept(svm, INTERCEPT_INVD);
+ set_intercept(svm, INTERCEPT_HLT);
+ set_intercept(svm, INTERCEPT_INVLPG);
+ set_intercept(svm, INTERCEPT_INVLPGA);
+ set_intercept(svm, INTERCEPT_IOIO_PROT);
+ set_intercept(svm, INTERCEPT_MSR_PROT);
+ set_intercept(svm, INTERCEPT_TASK_SWITCH);
+ set_intercept(svm, INTERCEPT_SHUTDOWN);
+ set_intercept(svm, INTERCEPT_VMRUN);
+ set_intercept(svm, INTERCEPT_VMMCALL);
+ set_intercept(svm, INTERCEPT_VMLOAD);
+ set_intercept(svm, INTERCEPT_VMSAVE);
+ set_intercept(svm, INTERCEPT_STGI);
+ set_intercept(svm, INTERCEPT_CLGI);
+ set_intercept(svm, INTERCEPT_SKINIT);
+ set_intercept(svm, INTERCEPT_WBINVD);
+ set_intercept(svm, INTERCEPT_MONITOR);
+ set_intercept(svm, INTERCEPT_MWAIT);
+ set_intercept(svm, INTERCEPT_XSETBV);
control->iopm_base_pa = iopm_base;
control->msrpm_base_pa = __pa(svm->msrpm);
@@ -855,25 +990,27 @@ static void init_vmcb(struct vcpu_svm *svm)
if (npt_enabled) {
/* Setup VMCB for Nested Paging */
control->nested_ctl = 1;
- control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) |
- (1ULL << INTERCEPT_INVLPG));
- control->intercept_exceptions &= ~(1 << PF_VECTOR);
- control->intercept_cr_read &= ~INTERCEPT_CR3_MASK;
- control->intercept_cr_write &= ~INTERCEPT_CR3_MASK;
+ clr_intercept(svm, INTERCEPT_TASK_SWITCH);
+ clr_intercept(svm, INTERCEPT_INVLPG);
+ clr_exception_intercept(svm, PF_VECTOR);
+ clr_cr_intercept(svm, INTERCEPT_CR3_READ);
+ clr_cr_intercept(svm, INTERCEPT_CR3_WRITE);
save->g_pat = 0x0007040600070406ULL;
save->cr3 = 0;
save->cr4 = 0;
}
- force_new_asid(&svm->vcpu);
+ svm->asid_generation = 0;
svm->nested.vmcb = 0;
svm->vcpu.arch.hflags = 0;
- if (svm_has(SVM_FEATURE_PAUSE_FILTER)) {
+ if (boot_cpu_has(X86_FEATURE_PAUSEFILTER)) {
control->pause_filter_count = 3000;
- control->intercept |= (1ULL << INTERCEPT_PAUSE);
+ set_intercept(svm, INTERCEPT_PAUSE);
}
+ mark_all_dirty(svm->vmcb);
+
enable_gif(svm);
}
@@ -990,8 +1127,16 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (unlikely(cpu != vcpu->cpu)) {
svm->asid_generation = 0;
+ mark_all_dirty(svm->vmcb);
}
+#ifdef CONFIG_X86_64
+ rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host.gs_base);
+#endif
+ savesegment(fs, svm->host.fs);
+ savesegment(gs, svm->host.gs);
+ svm->host.ldt = kvm_read_ldt();
+
for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
}
@@ -1002,6 +1147,14 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
int i;
++vcpu->stat.host_state_reload;
+ kvm_load_ldt(svm->host.ldt);
+#ifdef CONFIG_X86_64
+ loadsegment(fs, svm->host.fs);
+ load_gs_index(svm->host.gs);
+ wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+#else
+ loadsegment(gs, svm->host.gs);
+#endif
for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
}
@@ -1021,7 +1174,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
switch (reg) {
case VCPU_EXREG_PDPTR:
BUG_ON(!npt_enabled);
- load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
+ load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu));
break;
default:
BUG();
@@ -1030,12 +1183,12 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
static void svm_set_vintr(struct vcpu_svm *svm)
{
- svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR;
+ set_intercept(svm, INTERCEPT_VINTR);
}
static void svm_clear_vintr(struct vcpu_svm *svm)
{
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
+ clr_intercept(svm, INTERCEPT_VINTR);
}
static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg)
@@ -1150,6 +1303,7 @@ static void svm_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
svm->vmcb->save.idtr.limit = dt->size;
svm->vmcb->save.idtr.base = dt->address ;
+ mark_dirty(svm->vmcb, VMCB_DT);
}
static void svm_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
@@ -1166,19 +1320,23 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
svm->vmcb->save.gdtr.limit = dt->size;
svm->vmcb->save.gdtr.base = dt->address ;
+ mark_dirty(svm->vmcb, VMCB_DT);
}
static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
{
}
+static void svm_decache_cr3(struct kvm_vcpu *vcpu)
+{
+}
+
static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
}
static void update_cr0_intercept(struct vcpu_svm *svm)
{
- struct vmcb *vmcb = svm->vmcb;
ulong gcr0 = svm->vcpu.arch.cr0;
u64 *hcr0 = &svm->vmcb->save.cr0;
@@ -1188,27 +1346,14 @@ static void update_cr0_intercept(struct vcpu_svm *svm)
*hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK)
| (gcr0 & SVM_CR0_SELECTIVE_MASK);
+ mark_dirty(svm->vmcb, VMCB_CR);
if (gcr0 == *hcr0 && svm->vcpu.fpu_active) {
- vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
- vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
- if (is_nested(svm)) {
- struct vmcb *hsave = svm->nested.hsave;
-
- hsave->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
- hsave->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
- vmcb->control.intercept_cr_read |= svm->nested.intercept_cr_read;
- vmcb->control.intercept_cr_write |= svm->nested.intercept_cr_write;
- }
+ clr_cr_intercept(svm, INTERCEPT_CR0_READ);
+ clr_cr_intercept(svm, INTERCEPT_CR0_WRITE);
} else {
- svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
- svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
- if (is_nested(svm)) {
- struct vmcb *hsave = svm->nested.hsave;
-
- hsave->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
- hsave->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
- }
+ set_cr_intercept(svm, INTERCEPT_CR0_READ);
+ set_cr_intercept(svm, INTERCEPT_CR0_WRITE);
}
}
@@ -1216,7 +1361,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (is_nested(svm)) {
+ if (is_guest_mode(vcpu)) {
/*
* We are here because we run in nested mode, the host kvm
* intercepts cr0 writes but the l1 hypervisor does not.
@@ -1268,6 +1413,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
*/
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
svm->vmcb->save.cr0 = cr0;
+ mark_dirty(svm->vmcb, VMCB_CR);
update_cr0_intercept(svm);
}
@@ -1277,13 +1423,14 @@ static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4;
if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
- force_new_asid(vcpu);
+ svm_flush_tlb(vcpu);
vcpu->arch.cr4 = cr4;
if (!npt_enabled)
cr4 |= X86_CR4_PAE;
cr4 |= host_cr4_mce;
to_svm(vcpu)->vmcb->save.cr4 = cr4;
+ mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR);
}
static void svm_set_segment(struct kvm_vcpu *vcpu,
@@ -1312,26 +1459,25 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
= (svm->vmcb->save.cs.attrib
>> SVM_SELECTOR_DPL_SHIFT) & 3;
+ mark_dirty(svm->vmcb, VMCB_SEG);
}
static void update_db_intercept(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- svm->vmcb->control.intercept_exceptions &=
- ~((1 << DB_VECTOR) | (1 << BP_VECTOR));
+ clr_exception_intercept(svm, DB_VECTOR);
+ clr_exception_intercept(svm, BP_VECTOR);
if (svm->nmi_singlestep)
- svm->vmcb->control.intercept_exceptions |= (1 << DB_VECTOR);
+ set_exception_intercept(svm, DB_VECTOR);
if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
if (vcpu->guest_debug &
(KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
- svm->vmcb->control.intercept_exceptions |=
- 1 << DB_VECTOR;
+ set_exception_intercept(svm, DB_VECTOR);
if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
- svm->vmcb->control.intercept_exceptions |=
- 1 << BP_VECTOR;
+ set_exception_intercept(svm, BP_VECTOR);
} else
vcpu->guest_debug = 0;
}
@@ -1345,21 +1491,9 @@ static void svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
else
svm->vmcb->save.dr7 = vcpu->arch.dr7;
- update_db_intercept(vcpu);
-}
-
-static void load_host_msrs(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_X86_64
- wrmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base);
-#endif
-}
+ mark_dirty(svm->vmcb, VMCB_DR);
-static void save_host_msrs(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_X86_64
- rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base);
-#endif
+ update_db_intercept(vcpu);
}
static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
@@ -1372,6 +1506,8 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
svm->asid_generation = sd->asid_generation;
svm->vmcb->control.asid = sd->next_asid++;
+
+ mark_dirty(svm->vmcb, VMCB_ASID);
}
static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value)
@@ -1379,20 +1515,40 @@ static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value)
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->save.dr7 = value;
+ mark_dirty(svm->vmcb, VMCB_DR);
}
static int pf_interception(struct vcpu_svm *svm)
{
- u64 fault_address;
+ u64 fault_address = svm->vmcb->control.exit_info_2;
u32 error_code;
+ int r = 1;
- fault_address = svm->vmcb->control.exit_info_2;
- error_code = svm->vmcb->control.exit_info_1;
-
- trace_kvm_page_fault(fault_address, error_code);
- if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu))
- kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
- return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
+ switch (svm->apf_reason) {
+ default:
+ error_code = svm->vmcb->control.exit_info_1;
+
+ trace_kvm_page_fault(fault_address, error_code);
+ if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu))
+ kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
+ r = kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code,
+ svm->vmcb->control.insn_bytes,
+ svm->vmcb->control.insn_len);
+ break;
+ case KVM_PV_REASON_PAGE_NOT_PRESENT:
+ svm->apf_reason = 0;
+ local_irq_disable();
+ kvm_async_pf_task_wait(fault_address);
+ local_irq_enable();
+ break;
+ case KVM_PV_REASON_PAGE_READY:
+ svm->apf_reason = 0;
+ local_irq_disable();
+ kvm_async_pf_task_wake(fault_address);
+ local_irq_enable();
+ break;
+ }
+ return r;
}
static int db_interception(struct vcpu_svm *svm)
@@ -1440,7 +1596,7 @@ static int ud_interception(struct vcpu_svm *svm)
{
int er;
- er = emulate_instruction(&svm->vcpu, 0, 0, EMULTYPE_TRAP_UD);
+ er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD);
if (er != EMULATE_DONE)
kvm_queue_exception(&svm->vcpu, UD_VECTOR);
return 1;
@@ -1449,21 +1605,8 @@ static int ud_interception(struct vcpu_svm *svm)
static void svm_fpu_activate(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- u32 excp;
-
- if (is_nested(svm)) {
- u32 h_excp, n_excp;
-
- h_excp = svm->nested.hsave->control.intercept_exceptions;
- n_excp = svm->nested.intercept_exceptions;
- h_excp &= ~(1 << NM_VECTOR);
- excp = h_excp | n_excp;
- } else {
- excp = svm->vmcb->control.intercept_exceptions;
- excp &= ~(1 << NM_VECTOR);
- }
- svm->vmcb->control.intercept_exceptions = excp;
+ clr_exception_intercept(svm, NM_VECTOR);
svm->vcpu.fpu_active = 1;
update_cr0_intercept(svm);
@@ -1570,7 +1713,7 @@ static int io_interception(struct vcpu_svm *svm)
string = (io_info & SVM_IOIO_STR_MASK) != 0;
in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
if (string || in)
- return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE;
+ return emulate_instruction(vcpu, 0) == EMULATE_DONE;
port = io_info >> 16;
size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
@@ -1624,17 +1767,19 @@ static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->control.nested_cr3 = root;
- force_new_asid(vcpu);
+ mark_dirty(svm->vmcb, VMCB_NPT);
+ svm_flush_tlb(vcpu);
}
-static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu)
+static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
+ struct x86_exception *fault)
{
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->control.exit_code = SVM_EXIT_NPF;
svm->vmcb->control.exit_code_hi = 0;
- svm->vmcb->control.exit_info_1 = vcpu->arch.fault.error_code;
- svm->vmcb->control.exit_info_2 = vcpu->arch.fault.address;
+ svm->vmcb->control.exit_info_1 = fault->error_code;
+ svm->vmcb->control.exit_info_2 = fault->address;
nested_svm_vmexit(svm);
}
@@ -1680,7 +1825,7 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
{
int vmexit;
- if (!is_nested(svm))
+ if (!is_guest_mode(&svm->vcpu))
return 0;
svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
@@ -1698,7 +1843,7 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
/* This function returns true if it is save to enable the irq window */
static inline bool nested_svm_intr(struct vcpu_svm *svm)
{
- if (!is_nested(svm))
+ if (!is_guest_mode(&svm->vcpu))
return true;
if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
@@ -1737,7 +1882,7 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm)
/* This function returns true if it is save to enable the nmi window */
static inline bool nested_svm_nmi(struct vcpu_svm *svm)
{
- if (!is_nested(svm))
+ if (!is_guest_mode(&svm->vcpu))
return true;
if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI)))
@@ -1836,8 +1981,8 @@ static int nested_svm_exit_special(struct vcpu_svm *svm)
return NESTED_EXIT_HOST;
break;
case SVM_EXIT_EXCP_BASE + PF_VECTOR:
- /* When we're shadowing, trap PFs */
- if (!npt_enabled)
+ /* When we're shadowing, trap PFs, but not async PF */
+ if (!npt_enabled && svm->apf_reason == 0)
return NESTED_EXIT_HOST;
break;
case SVM_EXIT_EXCP_BASE + NM_VECTOR:
@@ -1865,27 +2010,15 @@ static int nested_svm_intercept(struct vcpu_svm *svm)
case SVM_EXIT_IOIO:
vmexit = nested_svm_intercept_ioio(svm);
break;
- case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
- u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
- if (svm->nested.intercept_cr_read & cr_bits)
+ case SVM_EXIT_READ_CR0 ... SVM_EXIT_WRITE_CR8: {
+ u32 bit = 1U << (exit_code - SVM_EXIT_READ_CR0);
+ if (svm->nested.intercept_cr & bit)
vmexit = NESTED_EXIT_DONE;
break;
}
- case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
- u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
- if (svm->nested.intercept_cr_write & cr_bits)
- vmexit = NESTED_EXIT_DONE;
- break;
- }
- case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
- u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
- if (svm->nested.intercept_dr_read & dr_bits)
- vmexit = NESTED_EXIT_DONE;
- break;
- }
- case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
- u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
- if (svm->nested.intercept_dr_write & dr_bits)
+ case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: {
+ u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0);
+ if (svm->nested.intercept_dr & bit)
vmexit = NESTED_EXIT_DONE;
break;
}
@@ -1893,6 +2026,10 @@ static int nested_svm_intercept(struct vcpu_svm *svm)
u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
if (svm->nested.intercept_exceptions & excp_bits)
vmexit = NESTED_EXIT_DONE;
+ /* async page fault always cause vmexit */
+ else if ((exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR) &&
+ svm->apf_reason != 0)
+ vmexit = NESTED_EXIT_DONE;
break;
}
case SVM_EXIT_ERR: {
@@ -1926,10 +2063,8 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr
struct vmcb_control_area *dst = &dst_vmcb->control;
struct vmcb_control_area *from = &from_vmcb->control;
- dst->intercept_cr_read = from->intercept_cr_read;
- dst->intercept_cr_write = from->intercept_cr_write;
- dst->intercept_dr_read = from->intercept_dr_read;
- dst->intercept_dr_write = from->intercept_dr_write;
+ dst->intercept_cr = from->intercept_cr;
+ dst->intercept_dr = from->intercept_dr;
dst->intercept_exceptions = from->intercept_exceptions;
dst->intercept = from->intercept;
dst->iopm_base_pa = from->iopm_base_pa;
@@ -1970,7 +2105,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
if (!nested_vmcb)
return 1;
- /* Exit nested SVM mode */
+ /* Exit Guest-Mode */
+ leave_guest_mode(&svm->vcpu);
svm->nested.vmcb = 0;
/* Give the current vmcb to the guest */
@@ -1984,7 +2120,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_vmcb->save.idtr = vmcb->save.idtr;
nested_vmcb->save.efer = svm->vcpu.arch.efer;
nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu);
- nested_vmcb->save.cr3 = svm->vcpu.arch.cr3;
+ nested_vmcb->save.cr3 = kvm_read_cr3(&svm->vcpu);
nested_vmcb->save.cr2 = vmcb->save.cr2;
nested_vmcb->save.cr4 = svm->vcpu.arch.cr4;
nested_vmcb->save.rflags = vmcb->save.rflags;
@@ -2061,6 +2197,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
svm->vmcb->save.cpl = 0;
svm->vmcb->control.exit_int_info = 0;
+ mark_all_dirty(svm->vmcb);
+
nested_svm_unmap(page);
nested_svm_uninit_mmu_context(&svm->vcpu);
@@ -2148,8 +2286,8 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
nested_vmcb->control.event_inj,
nested_vmcb->control.nested_ctl);
- trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr_read,
- nested_vmcb->control.intercept_cr_write,
+ trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr & 0xffff,
+ nested_vmcb->control.intercept_cr >> 16,
nested_vmcb->control.intercept_exceptions,
nested_vmcb->control.intercept);
@@ -2177,7 +2315,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
if (npt_enabled)
hsave->save.cr3 = vmcb->save.cr3;
else
- hsave->save.cr3 = svm->vcpu.arch.cr3;
+ hsave->save.cr3 = kvm_read_cr3(&svm->vcpu);
copy_vmcb_control_area(hsave, vmcb);
@@ -2229,14 +2367,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL;
/* cache intercepts */
- svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read;
- svm->nested.intercept_cr_write = nested_vmcb->control.intercept_cr_write;
- svm->nested.intercept_dr_read = nested_vmcb->control.intercept_dr_read;
- svm->nested.intercept_dr_write = nested_vmcb->control.intercept_dr_write;
+ svm->nested.intercept_cr = nested_vmcb->control.intercept_cr;
+ svm->nested.intercept_dr = nested_vmcb->control.intercept_dr;
svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions;
svm->nested.intercept = nested_vmcb->control.intercept;
- force_new_asid(&svm->vcpu);
+ svm_flush_tlb(&svm->vcpu);
svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | V_INTR_MASKING_MASK;
if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK)
svm->vcpu.arch.hflags |= HF_VINTR_MASK;
@@ -2245,29 +2381,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
if (svm->vcpu.arch.hflags & HF_VINTR_MASK) {
/* We only want the cr8 intercept bits of the guest */
- svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK;
- svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
+ clr_cr_intercept(svm, INTERCEPT_CR8_READ);
+ clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
}
/* We don't want to see VMMCALLs from a nested guest */
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL);
-
- /*
- * We don't want a nested guest to be more powerful than the guest, so
- * all intercepts are ORed
- */
- svm->vmcb->control.intercept_cr_read |=
- nested_vmcb->control.intercept_cr_read;
- svm->vmcb->control.intercept_cr_write |=
- nested_vmcb->control.intercept_cr_write;
- svm->vmcb->control.intercept_dr_read |=
- nested_vmcb->control.intercept_dr_read;
- svm->vmcb->control.intercept_dr_write |=
- nested_vmcb->control.intercept_dr_write;
- svm->vmcb->control.intercept_exceptions |=
- nested_vmcb->control.intercept_exceptions;
-
- svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
+ clr_intercept(svm, INTERCEPT_VMMCALL);
svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl;
svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
@@ -2278,11 +2397,21 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
nested_svm_unmap(page);
- /* nested_vmcb is our indicator if nested SVM is activated */
+ /* Enter Guest-Mode */
+ enter_guest_mode(&svm->vcpu);
+
+ /*
+ * Merge guest and host intercepts - must be called with vcpu in
+ * guest-mode to take affect here
+ */
+ recalc_intercepts(svm);
+
svm->nested.vmcb = vmcb_gpa;
enable_gif(svm);
+ mark_all_dirty(svm->vmcb);
+
return true;
}
@@ -2400,6 +2529,8 @@ static int clgi_interception(struct vcpu_svm *svm)
svm_clear_vintr(svm);
svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+ mark_dirty(svm->vmcb, VMCB_INTR);
+
return 1;
}
@@ -2426,6 +2557,19 @@ static int skinit_interception(struct vcpu_svm *svm)
return 1;
}
+static int xsetbv_interception(struct vcpu_svm *svm)
+{
+ u64 new_bv = kvm_read_edx_eax(&svm->vcpu);
+ u32 index = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX);
+
+ if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+ }
+
+ return 1;
+}
+
static int invalid_op_interception(struct vcpu_svm *svm)
{
kvm_queue_exception(&svm->vcpu, UD_VECTOR);
@@ -2507,19 +2651,92 @@ static int cpuid_interception(struct vcpu_svm *svm)
static int iret_interception(struct vcpu_svm *svm)
{
++svm->vcpu.stat.nmi_window_exits;
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
+ clr_intercept(svm, INTERCEPT_IRET);
svm->vcpu.arch.hflags |= HF_IRET_MASK;
return 1;
}
static int invlpg_interception(struct vcpu_svm *svm)
{
- return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE;
+ if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
+ return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
+
+ kvm_mmu_invlpg(&svm->vcpu, svm->vmcb->control.exit_info_1);
+ skip_emulated_instruction(&svm->vcpu);
+ return 1;
}
static int emulate_on_interception(struct vcpu_svm *svm)
{
- return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE;
+ return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
+}
+
+#define CR_VALID (1ULL << 63)
+
+static int cr_interception(struct vcpu_svm *svm)
+{
+ int reg, cr;
+ unsigned long val;
+ int err;
+
+ if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
+ return emulate_on_interception(svm);
+
+ if (unlikely((svm->vmcb->control.exit_info_1 & CR_VALID) == 0))
+ return emulate_on_interception(svm);
+
+ reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK;
+ cr = svm->vmcb->control.exit_code - SVM_EXIT_READ_CR0;
+
+ err = 0;
+ if (cr >= 16) { /* mov to cr */
+ cr -= 16;
+ val = kvm_register_read(&svm->vcpu, reg);
+ switch (cr) {
+ case 0:
+ err = kvm_set_cr0(&svm->vcpu, val);
+ break;
+ case 3:
+ err = kvm_set_cr3(&svm->vcpu, val);
+ break;
+ case 4:
+ err = kvm_set_cr4(&svm->vcpu, val);
+ break;
+ case 8:
+ err = kvm_set_cr8(&svm->vcpu, val);
+ break;
+ default:
+ WARN(1, "unhandled write to CR%d", cr);
+ kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+ return 1;
+ }
+ } else { /* mov from cr */
+ switch (cr) {
+ case 0:
+ val = kvm_read_cr0(&svm->vcpu);
+ break;
+ case 2:
+ val = svm->vcpu.arch.cr2;
+ break;
+ case 3:
+ val = kvm_read_cr3(&svm->vcpu);
+ break;
+ case 4:
+ val = kvm_read_cr4(&svm->vcpu);
+ break;
+ case 8:
+ val = kvm_get_cr8(&svm->vcpu);
+ break;
+ default:
+ WARN(1, "unhandled read from CR%d", cr);
+ kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+ return 1;
+ }
+ kvm_register_write(&svm->vcpu, reg, val);
+ }
+ kvm_complete_insn_gp(&svm->vcpu, err);
+
+ return 1;
}
static int cr0_write_interception(struct vcpu_svm *svm)
@@ -2527,7 +2744,7 @@ static int cr0_write_interception(struct vcpu_svm *svm)
struct kvm_vcpu *vcpu = &svm->vcpu;
int r;
- r = emulate_instruction(&svm->vcpu, 0, 0, 0);
+ r = cr_interception(svm);
if (svm->nested.vmexit_rip) {
kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip);
@@ -2536,22 +2753,47 @@ static int cr0_write_interception(struct vcpu_svm *svm)
svm->nested.vmexit_rip = 0;
}
- return r == EMULATE_DONE;
+ return r;
+}
+
+static int dr_interception(struct vcpu_svm *svm)
+{
+ int reg, dr;
+ unsigned long val;
+ int err;
+
+ if (!boot_cpu_has(X86_FEATURE_DECODEASSISTS))
+ return emulate_on_interception(svm);
+
+ reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK;
+ dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0;
+
+ if (dr >= 16) { /* mov to DRn */
+ val = kvm_register_read(&svm->vcpu, reg);
+ kvm_set_dr(&svm->vcpu, dr - 16, val);
+ } else {
+ err = kvm_get_dr(&svm->vcpu, dr, &val);
+ if (!err)
+ kvm_register_write(&svm->vcpu, reg, val);
+ }
+
+ return 1;
}
static int cr8_write_interception(struct vcpu_svm *svm)
{
struct kvm_run *kvm_run = svm->vcpu.run;
+ int r;
u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
/* instruction emulation calls kvm_set_cr8() */
- emulate_instruction(&svm->vcpu, 0, 0, 0);
+ r = cr_interception(svm);
if (irqchip_in_kernel(svm->vcpu.kvm)) {
- svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
- return 1;
+ clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
+ return r;
}
if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
- return 1;
+ return r;
kvm_run->exit_reason = KVM_EXIT_SET_TPR;
return 0;
}
@@ -2562,14 +2804,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
switch (ecx) {
case MSR_IA32_TSC: {
- u64 tsc_offset;
+ struct vmcb *vmcb = get_host_vmcb(svm);
- if (is_nested(svm))
- tsc_offset = svm->nested.hsave->control.tsc_offset;
- else
- tsc_offset = svm->vmcb->control.tsc_offset;
-
- *data = tsc_offset + native_read_tsc();
+ *data = vmcb->control.tsc_offset + native_read_tsc();
break;
}
case MSR_STAR:
@@ -2714,7 +2951,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
svm->vmcb->save.sysenter_esp = data;
break;
case MSR_IA32_DEBUGCTLMSR:
- if (!svm_has(SVM_FEATURE_LBRV)) {
+ if (!boot_cpu_has(X86_FEATURE_LBRV)) {
pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
__func__, data);
break;
@@ -2723,6 +2960,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
return 1;
svm->vmcb->save.dbgctl = data;
+ mark_dirty(svm->vmcb, VMCB_LBR);
if (data & (1ULL<<0))
svm_enable_lbrv(svm);
else
@@ -2775,6 +3013,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
svm_clear_vintr(svm);
svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+ mark_dirty(svm->vmcb, VMCB_INTR);
/*
* If the user space waits to inject interrupts, exit as soon as
* possible
@@ -2797,31 +3036,31 @@ static int pause_interception(struct vcpu_svm *svm)
}
static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
- [SVM_EXIT_READ_CR0] = emulate_on_interception,
- [SVM_EXIT_READ_CR3] = emulate_on_interception,
- [SVM_EXIT_READ_CR4] = emulate_on_interception,
- [SVM_EXIT_READ_CR8] = emulate_on_interception,
+ [SVM_EXIT_READ_CR0] = cr_interception,
+ [SVM_EXIT_READ_CR3] = cr_interception,
+ [SVM_EXIT_READ_CR4] = cr_interception,
+ [SVM_EXIT_READ_CR8] = cr_interception,
[SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception,
[SVM_EXIT_WRITE_CR0] = cr0_write_interception,
- [SVM_EXIT_WRITE_CR3] = emulate_on_interception,
- [SVM_EXIT_WRITE_CR4] = emulate_on_interception,
+ [SVM_EXIT_WRITE_CR3] = cr_interception,
+ [SVM_EXIT_WRITE_CR4] = cr_interception,
[SVM_EXIT_WRITE_CR8] = cr8_write_interception,
- [SVM_EXIT_READ_DR0] = emulate_on_interception,
- [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_READ_DR0] = dr_interception,
+ [SVM_EXIT_READ_DR1] = dr_interception,
+ [SVM_EXIT_READ_DR2] = dr_interception,
+ [SVM_EXIT_READ_DR3] = dr_interception,
+ [SVM_EXIT_READ_DR4] = dr_interception,
+ [SVM_EXIT_READ_DR5] = dr_interception,
+ [SVM_EXIT_READ_DR6] = dr_interception,
+ [SVM_EXIT_READ_DR7] = dr_interception,
+ [SVM_EXIT_WRITE_DR0] = dr_interception,
+ [SVM_EXIT_WRITE_DR1] = dr_interception,
+ [SVM_EXIT_WRITE_DR2] = dr_interception,
+ [SVM_EXIT_WRITE_DR3] = dr_interception,
+ [SVM_EXIT_WRITE_DR4] = dr_interception,
+ [SVM_EXIT_WRITE_DR5] = dr_interception,
+ [SVM_EXIT_WRITE_DR6] = dr_interception,
+ [SVM_EXIT_WRITE_DR7] = dr_interception,
[SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception,
[SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception,
[SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception,
@@ -2854,6 +3093,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_WBINVD] = emulate_on_interception,
[SVM_EXIT_MONITOR] = invalid_op_interception,
[SVM_EXIT_MWAIT] = invalid_op_interception,
+ [SVM_EXIT_XSETBV] = xsetbv_interception,
[SVM_EXIT_NPF] = pf_interception,
};
@@ -2864,10 +3104,10 @@ void dump_vmcb(struct kvm_vcpu *vcpu)
struct vmcb_save_area *save = &svm->vmcb->save;
pr_err("VMCB Control Area:\n");
- pr_err("cr_read: %04x\n", control->intercept_cr_read);
- pr_err("cr_write: %04x\n", control->intercept_cr_write);
- pr_err("dr_read: %04x\n", control->intercept_dr_read);
- pr_err("dr_write: %04x\n", control->intercept_dr_write);
+ pr_err("cr_read: %04x\n", control->intercept_cr & 0xffff);
+ pr_err("cr_write: %04x\n", control->intercept_cr >> 16);
+ pr_err("dr_read: %04x\n", control->intercept_dr & 0xffff);
+ pr_err("dr_write: %04x\n", control->intercept_dr >> 16);
pr_err("exceptions: %08x\n", control->intercept_exceptions);
pr_err("intercepts: %016llx\n", control->intercept);
pr_err("pause filter count: %d\n", control->pause_filter_count);
@@ -2950,15 +3190,23 @@ void dump_vmcb(struct kvm_vcpu *vcpu)
}
+static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
+{
+ struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control;
+
+ *info1 = control->exit_info_1;
+ *info2 = control->exit_info_2;
+}
+
static int handle_exit(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct kvm_run *kvm_run = vcpu->run;
u32 exit_code = svm->vmcb->control.exit_code;
- trace_kvm_exit(exit_code, vcpu);
+ trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM);
- if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK))
+ if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE))
vcpu->arch.cr0 = svm->vmcb->save.cr0;
if (npt_enabled)
vcpu->arch.cr3 = svm->vmcb->save.cr3;
@@ -2970,7 +3218,7 @@ static int handle_exit(struct kvm_vcpu *vcpu)
return 1;
}
- if (is_nested(svm)) {
+ if (is_guest_mode(vcpu)) {
int vmexit;
trace_kvm_nested_vmexit(svm->vmcb->save.rip, exit_code,
@@ -3033,7 +3281,6 @@ static void pre_svm_run(struct vcpu_svm *svm)
struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
- svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
/* FIXME: handle wraparound of asid_generation */
if (svm->asid_generation != sd->asid_generation)
new_asid(svm, sd);
@@ -3045,7 +3292,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
vcpu->arch.hflags |= HF_NMI_MASK;
- svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
+ set_intercept(svm, INTERCEPT_IRET);
++vcpu->stat.nmi_injections;
}
@@ -3058,6 +3305,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
control->int_ctl &= ~V_INTR_PRIO_MASK;
control->int_ctl |= V_IRQ_MASK |
((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
+ mark_dirty(svm->vmcb, VMCB_INTR);
}
static void svm_set_irq(struct kvm_vcpu *vcpu)
@@ -3077,14 +3325,14 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK))
return;
if (irr == -1)
return;
if (tpr >= irr)
- svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
+ set_cr_intercept(svm, INTERCEPT_CR8_WRITE);
}
static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
@@ -3112,10 +3360,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
if (masked) {
svm->vcpu.arch.hflags |= HF_NMI_MASK;
- svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
+ set_intercept(svm, INTERCEPT_IRET);
} else {
svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
+ clr_intercept(svm, INTERCEPT_IRET);
}
}
@@ -3131,7 +3379,7 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
ret = !!(vmcb->save.rflags & X86_EFLAGS_IF);
- if (is_nested(svm))
+ if (is_guest_mode(vcpu))
return ret && !(svm->vcpu.arch.hflags & HF_VINTR_MASK);
return ret;
@@ -3177,7 +3425,12 @@ static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
static void svm_flush_tlb(struct kvm_vcpu *vcpu)
{
- force_new_asid(vcpu);
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ if (static_cpu_has(X86_FEATURE_FLUSHBYASID))
+ svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
+ else
+ svm->asid_generation--;
}
static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
@@ -3188,10 +3441,10 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK))
return;
- if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) {
+ if (!is_cr_intercept(svm, INTERCEPT_CR8_WRITE)) {
int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK;
kvm_set_cr8(vcpu, cr8);
}
@@ -3202,7 +3455,7 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
u64 cr8;
- if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK))
return;
cr8 = kvm_get_cr8(vcpu);
@@ -3289,9 +3542,6 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu)
static void svm_vcpu_run(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- u16 fs_selector;
- u16 gs_selector;
- u16 ldt_selector;
svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
@@ -3308,10 +3558,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
sync_lapic_to_cr8(vcpu);
- save_host_msrs(vcpu);
- savesegment(fs, fs_selector);
- savesegment(gs, gs_selector);
- ldt_selector = kvm_read_ldt();
svm->vmcb->save.cr2 = vcpu->arch.cr2;
clgi();
@@ -3389,19 +3635,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
#endif
);
- vcpu->arch.cr2 = svm->vmcb->save.cr2;
- vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
- vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
- vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
-
- load_host_msrs(vcpu);
- kvm_load_ldt(ldt_selector);
- loadsegment(fs, fs_selector);
#ifdef CONFIG_X86_64
- load_gs_index(gs_selector);
- wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+ wrmsrl(MSR_GS_BASE, svm->host.gs_base);
#else
- loadsegment(gs, gs_selector);
+ loadsegment(fs, svm->host.fs);
#endif
reload_tss(vcpu);
@@ -3410,10 +3647,21 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
stgi();
+ vcpu->arch.cr2 = svm->vmcb->save.cr2;
+ vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
+ vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
+ vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
+
sync_cr8_to_lapic(vcpu);
svm->next_rip = 0;
+ svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
+
+ /* if exit due to PF check for async PF */
+ if (svm->vmcb->control.exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR)
+ svm->apf_reason = kvm_read_and_reset_pf_reason();
+
if (npt_enabled) {
vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR);
vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR);
@@ -3426,6 +3674,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
if (unlikely(svm->vmcb->control.exit_code ==
SVM_EXIT_EXCP_BASE + MC_VECTOR))
svm_handle_mce(svm);
+
+ mark_all_clean(svm->vmcb);
}
#undef R
@@ -3435,7 +3685,8 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->save.cr3 = root;
- force_new_asid(vcpu);
+ mark_dirty(svm->vmcb, VMCB_CR);
+ svm_flush_tlb(vcpu);
}
static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
@@ -3443,11 +3694,13 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->control.nested_cr3 = root;
+ mark_dirty(svm->vmcb, VMCB_NPT);
/* Also sync guest cr3 here in case we live migrate */
- svm->vmcb->save.cr3 = vcpu->arch.cr3;
+ svm->vmcb->save.cr3 = kvm_read_cr3(vcpu);
+ mark_dirty(svm->vmcb, VMCB_CR);
- force_new_asid(vcpu);
+ svm_flush_tlb(vcpu);
}
static int is_disabled(void)
@@ -3507,7 +3760,7 @@ static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
additional features */
/* Support next_rip if host supports it */
- if (svm_has(SVM_FEATURE_NRIP))
+ if (boot_cpu_has(X86_FEATURE_NRIPS))
entry->edx |= SVM_FEATURE_NRIP;
/* Support NPT for the guest if enabled */
@@ -3567,6 +3820,7 @@ static const struct trace_print_flags svm_exit_reasons_str[] = {
{ SVM_EXIT_WBINVD, "wbinvd" },
{ SVM_EXIT_MONITOR, "monitor" },
{ SVM_EXIT_MWAIT, "mwait" },
+ { SVM_EXIT_XSETBV, "xsetbv" },
{ SVM_EXIT_NPF, "npf" },
{ -1, NULL }
};
@@ -3590,9 +3844,7 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR;
- if (is_nested(svm))
- svm->nested.hsave->control.intercept_exceptions |= 1 << NM_VECTOR;
+ set_exception_intercept(svm, NM_VECTOR);
update_cr0_intercept(svm);
}
@@ -3623,6 +3875,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.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_cr3 = svm_decache_cr3,
.decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
.set_cr0 = svm_set_cr0,
.set_cr3 = svm_set_cr3,
@@ -3663,7 +3916,9 @@ static struct kvm_x86_ops svm_x86_ops = {
.get_tdp_level = get_npt_level,
.get_mt_mask = svm_get_mt_mask,
+ .get_exit_info = svm_get_exit_info,
.exit_reasons_str = svm_exit_reasons_str,
+
.get_lpage_level = svm_get_lpage_level,
.cpuid_update = svm_cpuid_update,
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index a6544b8e7c0f..1357d7cf4ec8 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -178,27 +178,36 @@ TRACE_EVENT(kvm_apic,
#define trace_kvm_apic_read(reg, val) trace_kvm_apic(0, reg, val)
#define trace_kvm_apic_write(reg, val) trace_kvm_apic(1, reg, val)
+#define KVM_ISA_VMX 1
+#define KVM_ISA_SVM 2
+
/*
* Tracepoint for kvm guest exit:
*/
TRACE_EVENT(kvm_exit,
- TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu),
- TP_ARGS(exit_reason, vcpu),
+ TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu, u32 isa),
+ TP_ARGS(exit_reason, vcpu, isa),
TP_STRUCT__entry(
__field( unsigned int, exit_reason )
__field( unsigned long, guest_rip )
+ __field( u32, isa )
+ __field( u64, info1 )
+ __field( u64, info2 )
),
TP_fast_assign(
__entry->exit_reason = exit_reason;
__entry->guest_rip = kvm_rip_read(vcpu);
+ __entry->isa = isa;
+ kvm_x86_ops->get_exit_info(vcpu, &__entry->info1,
+ &__entry->info2);
),
- TP_printk("reason %s rip 0x%lx",
+ TP_printk("reason %s rip 0x%lx info %llx %llx",
ftrace_print_symbols_seq(p, __entry->exit_reason,
kvm_x86_ops->exit_reasons_str),
- __entry->guest_rip)
+ __entry->guest_rip, __entry->info1, __entry->info2)
);
/*
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ff21fdda0c53..bf89ec2cfb82 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -69,6 +69,9 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
static int __read_mostly vmm_exclusive = 1;
module_param(vmm_exclusive, bool, S_IRUGO);
+static int __read_mostly yield_on_hlt = 1;
+module_param(yield_on_hlt, 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 \
@@ -177,6 +180,7 @@ static int init_rmode(struct kvm *kvm);
static u64 construct_eptp(unsigned long root_hpa);
static void kvm_cpu_vmxon(u64 addr);
static void kvm_cpu_vmxoff(void);
+static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -188,6 +192,8 @@ static unsigned long *vmx_io_bitmap_b;
static unsigned long *vmx_msr_bitmap_legacy;
static unsigned long *vmx_msr_bitmap_longmode;
+static bool cpu_has_load_ia32_efer;
+
static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
static DEFINE_SPINLOCK(vmx_vpid_lock);
@@ -472,7 +478,7 @@ static void vmcs_clear(struct vmcs *vmcs)
u8 error;
asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0"
- : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
+ : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr)
: "cc", "memory");
if (error)
printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n",
@@ -485,7 +491,7 @@ static void vmcs_load(struct vmcs *vmcs)
u8 error;
asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0"
- : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
+ : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr)
: "cc", "memory");
if (error)
printk(KERN_ERR "kvm: vmptrld %p/%llx fail\n",
@@ -565,10 +571,10 @@ static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa)
static unsigned long vmcs_readl(unsigned long field)
{
- unsigned long value;
+ unsigned long value = 0;
asm volatile (__ex(ASM_VMX_VMREAD_RDX_RAX)
- : "=a"(value) : "d"(field) : "cc");
+ : "+a"(value) : "d"(field) : "cc");
return value;
}
@@ -661,6 +667,12 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
unsigned i;
struct msr_autoload *m = &vmx->msr_autoload;
+ if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
+ vmcs_clear_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
+ vmcs_clear_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
+ return;
+ }
+
for (i = 0; i < m->nr; ++i)
if (m->guest[i].index == msr)
break;
@@ -680,6 +692,14 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
unsigned i;
struct msr_autoload *m = &vmx->msr_autoload;
+ if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
+ vmcs_write64(GUEST_IA32_EFER, guest_val);
+ vmcs_write64(HOST_IA32_EFER, host_val);
+ vmcs_set_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
+ vmcs_set_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
+ return;
+ }
+
for (i = 0; i < m->nr; ++i)
if (m->guest[i].index == msr)
break;
@@ -1009,6 +1029,17 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
vmx_set_interrupt_shadow(vcpu, 0);
}
+static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
+{
+ /* Ensure that we clear the HLT state in the VMCS. We don't need to
+ * explicitly skip the instruction because if the HLT state is set, then
+ * the instruction is already executing and RIP has already been
+ * advanced. */
+ if (!yield_on_hlt &&
+ vmcs_read32(GUEST_ACTIVITY_STATE) == GUEST_ACTIVITY_HLT)
+ vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
+}
+
static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code,
bool reinject)
@@ -1035,6 +1066,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
intr_info |= INTR_TYPE_HARD_EXCEPTION;
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
+ vmx_clear_hlt(vcpu);
}
static bool vmx_rdtscp_supported(void)
@@ -1305,8 +1337,11 @@ static __init int vmx_disabled_by_bios(void)
&& tboot_enabled())
return 1;
if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
- && !tboot_enabled())
+ && !tboot_enabled()) {
+ printk(KERN_WARNING "kvm: disable TXT in the BIOS or "
+ " activate TXT before enabling KVM\n");
return 1;
+ }
}
return 0;
@@ -1400,6 +1435,14 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
return 0;
}
+static __init bool allow_1_setting(u32 msr, u32 ctl)
+{
+ u32 vmx_msr_low, vmx_msr_high;
+
+ rdmsr(msr, vmx_msr_low, vmx_msr_high);
+ return vmx_msr_high & ctl;
+}
+
static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
{
u32 vmx_msr_low, vmx_msr_high;
@@ -1416,7 +1459,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
&_pin_based_exec_control) < 0)
return -EIO;
- min = CPU_BASED_HLT_EXITING |
+ min =
#ifdef CONFIG_X86_64
CPU_BASED_CR8_LOAD_EXITING |
CPU_BASED_CR8_STORE_EXITING |
@@ -1429,6 +1472,10 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
CPU_BASED_MWAIT_EXITING |
CPU_BASED_MONITOR_EXITING |
CPU_BASED_INVLPG_EXITING;
+
+ if (yield_on_hlt)
+ min |= CPU_BASED_HLT_EXITING;
+
opt = CPU_BASED_TPR_SHADOW |
CPU_BASED_USE_MSR_BITMAPS |
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
@@ -1510,6 +1557,12 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
vmcs_conf->vmexit_ctrl = _vmexit_control;
vmcs_conf->vmentry_ctrl = _vmentry_control;
+ cpu_has_load_ia32_efer =
+ allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS,
+ VM_ENTRY_LOAD_IA32_EFER)
+ && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
+ VM_EXIT_LOAD_IA32_EFER);
+
return 0;
}
@@ -1683,9 +1736,13 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
save->limit = vmcs_read32(sf->limit);
save->ar = vmcs_read32(sf->ar_bytes);
vmcs_write16(sf->selector, save->base >> 4);
- vmcs_write32(sf->base, save->base & 0xfffff);
+ vmcs_write32(sf->base, save->base & 0xffff0);
vmcs_write32(sf->limit, 0xffff);
vmcs_write32(sf->ar_bytes, 0xf3);
+ if (save->base & 0xf)
+ printk_once(KERN_WARNING "kvm: segment base is not paragraph"
+ " aligned when entering protected mode (seg=%d)",
+ seg);
}
static void enter_rmode(struct kvm_vcpu *vcpu)
@@ -1814,6 +1871,13 @@ static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits;
}
+static void vmx_decache_cr3(struct kvm_vcpu *vcpu)
+{
+ if (enable_ept && is_paging(vcpu))
+ vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
+ __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
+}
+
static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits;
@@ -1857,6 +1921,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
unsigned long cr0,
struct kvm_vcpu *vcpu)
{
+ vmx_decache_cr3(vcpu);
if (!(cr0 & X86_CR0_PG)) {
/* From paging/starting to nonpaging */
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1937,7 +2002,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
if (enable_ept) {
eptp = construct_eptp(cr3);
vmcs_write64(EPT_POINTER, eptp);
- guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
+ guest_cr3 = is_paging(vcpu) ? kvm_read_cr3(vcpu) :
vcpu->kvm->arch.ept_identity_map_addr;
ept_load_pdptrs(vcpu);
}
@@ -2725,7 +2790,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_IDTR_BASE, 0);
vmcs_write32(GUEST_IDTR_LIMIT, 0xffff);
- vmcs_write32(GUEST_ACTIVITY_STATE, 0);
+ vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
@@ -2787,6 +2852,10 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
return;
}
+ if (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) {
+ enable_irq_window(vcpu);
+ return;
+ }
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
@@ -2814,6 +2883,7 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
} else
intr |= INTR_TYPE_EXT_INTR;
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr);
+ vmx_clear_hlt(vcpu);
}
static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
@@ -2841,6 +2911,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
}
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
+ vmx_clear_hlt(vcpu);
}
static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
@@ -2849,7 +2920,8 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
return 0;
return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
- (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI));
+ (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_STI
+ | GUEST_INTR_STATE_NMI));
}
static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -2910,7 +2982,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
* Cause the #SS fault with 0 error code in VM86 mode.
*/
if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
- if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE)
+ if (emulate_instruction(vcpu, 0) == EMULATE_DONE)
return 1;
/*
* Forward all other exceptions that are valid in real mode.
@@ -3007,7 +3079,7 @@ static int handle_exception(struct kvm_vcpu *vcpu)
}
if (is_invalid_opcode(intr_info)) {
- er = emulate_instruction(vcpu, 0, 0, EMULTYPE_TRAP_UD);
+ er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD);
if (er != EMULATE_DONE)
kvm_queue_exception(vcpu, UD_VECTOR);
return 1;
@@ -3026,7 +3098,7 @@ static int handle_exception(struct kvm_vcpu *vcpu)
if (kvm_event_needs_reinjection(vcpu))
kvm_mmu_unprotect_page_virt(vcpu, cr2);
- return kvm_mmu_page_fault(vcpu, cr2, error_code);
+ return kvm_mmu_page_fault(vcpu, cr2, error_code, NULL, 0);
}
if (vmx->rmode.vm86_active &&
@@ -3098,7 +3170,7 @@ static int handle_io(struct kvm_vcpu *vcpu)
++vcpu->stat.io_exits;
if (string || in)
- return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE;
+ return emulate_instruction(vcpu, 0) == EMULATE_DONE;
port = exit_qualification >> 16;
size = (exit_qualification & 7) + 1;
@@ -3118,14 +3190,6 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
hypercall[2] = 0xc1;
}
-static void complete_insn_gp(struct kvm_vcpu *vcpu, int err)
-{
- if (err)
- kvm_inject_gp(vcpu, 0);
- else
- skip_emulated_instruction(vcpu);
-}
-
static int handle_cr(struct kvm_vcpu *vcpu)
{
unsigned long exit_qualification, val;
@@ -3143,21 +3207,21 @@ static int handle_cr(struct kvm_vcpu *vcpu)
switch (cr) {
case 0:
err = kvm_set_cr0(vcpu, val);
- complete_insn_gp(vcpu, err);
+ kvm_complete_insn_gp(vcpu, err);
return 1;
case 3:
err = kvm_set_cr3(vcpu, val);
- complete_insn_gp(vcpu, err);
+ kvm_complete_insn_gp(vcpu, err);
return 1;
case 4:
err = kvm_set_cr4(vcpu, val);
- complete_insn_gp(vcpu, err);
+ kvm_complete_insn_gp(vcpu, err);
return 1;
case 8: {
u8 cr8_prev = kvm_get_cr8(vcpu);
u8 cr8 = kvm_register_read(vcpu, reg);
- kvm_set_cr8(vcpu, cr8);
- skip_emulated_instruction(vcpu);
+ err = kvm_set_cr8(vcpu, cr8);
+ kvm_complete_insn_gp(vcpu, err);
if (irqchip_in_kernel(vcpu->kvm))
return 1;
if (cr8_prev <= cr8)
@@ -3176,8 +3240,9 @@ static int handle_cr(struct kvm_vcpu *vcpu)
case 1: /*mov from cr*/
switch (cr) {
case 3:
- kvm_register_write(vcpu, reg, vcpu->arch.cr3);
- trace_kvm_cr_read(cr, vcpu->arch.cr3);
+ val = kvm_read_cr3(vcpu);
+ kvm_register_write(vcpu, reg, val);
+ trace_kvm_cr_read(cr, val);
skip_emulated_instruction(vcpu);
return 1;
case 8:
@@ -3349,6 +3414,11 @@ static int handle_vmx_insn(struct kvm_vcpu *vcpu)
return 1;
}
+static int handle_invd(struct kvm_vcpu *vcpu)
+{
+ return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+}
+
static int handle_invlpg(struct kvm_vcpu *vcpu)
{
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
@@ -3377,7 +3447,7 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu)
static int handle_apic_access(struct kvm_vcpu *vcpu)
{
- return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE;
+ return emulate_instruction(vcpu, 0) == EMULATE_DONE;
}
static int handle_task_switch(struct kvm_vcpu *vcpu)
@@ -3476,7 +3546,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
trace_kvm_page_fault(gpa, exit_qualification);
- return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
+ return kvm_mmu_page_fault(vcpu, gpa, exit_qualification & 0x3, NULL, 0);
}
static u64 ept_rsvd_mask(u64 spte, int level)
@@ -3592,7 +3662,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
&& (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF))
return handle_interrupt_window(&vmx->vcpu);
- err = emulate_instruction(vcpu, 0, 0, 0);
+ err = emulate_instruction(vcpu, 0);
if (err == EMULATE_DO_MMIO) {
ret = 0;
@@ -3649,6 +3719,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_MSR_WRITE] = handle_wrmsr,
[EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window,
[EXIT_REASON_HLT] = handle_halt,
+ [EXIT_REASON_INVD] = handle_invd,
[EXIT_REASON_INVLPG] = handle_invlpg,
[EXIT_REASON_VMCALL] = handle_vmcall,
[EXIT_REASON_VMCLEAR] = handle_vmx_insn,
@@ -3676,6 +3747,12 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
static const int kvm_vmx_max_exit_handlers =
ARRAY_SIZE(kvm_vmx_exit_handlers);
+static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
+{
+ *info1 = vmcs_readl(EXIT_QUALIFICATION);
+ *info2 = vmcs_read32(VM_EXIT_INTR_INFO);
+}
+
/*
* The guest has exited. See if we can fix it or if we need userspace
* assistance.
@@ -3686,17 +3763,12 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
u32 exit_reason = vmx->exit_reason;
u32 vectoring_info = vmx->idt_vectoring_info;
- trace_kvm_exit(exit_reason, vcpu);
+ trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX);
/* If guest state is invalid, start emulating */
if (vmx->emulation_required && emulate_invalid_guest_state)
return handle_invalid_guest_state(vcpu);
- /* Access CR3 don't cause VMExit in paging mode, so we need
- * to sync with guest real CR3. */
- if (enable_ept && is_paging(vcpu))
- vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
-
if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
vcpu->run->fail_entry.hardware_entry_failure_reason
@@ -4013,7 +4085,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
);
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
- | (1 << VCPU_EXREG_PDPTR));
+ | (1 << VCPU_EXREG_PDPTR)
+ | (1 << VCPU_EXREG_CR3));
vcpu->arch.regs_dirty = 0;
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
@@ -4227,11 +4300,6 @@ static int vmx_get_lpage_level(void)
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;
@@ -4285,6 +4353,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.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_cr3 = vmx_decache_cr3,
.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
.set_cr0 = vmx_set_cr0,
.set_cr3 = vmx_set_cr3,
@@ -4325,7 +4394,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
.get_tdp_level = get_ept_level,
.get_mt_mask = vmx_get_mt_mask,
+ .get_exit_info = vmx_get_exit_info,
.exit_reasons_str = vmx_exit_reasons_str,
+
.get_lpage_level = vmx_get_lpage_level,
.cpuid_update = vmx_cpuid_update,
@@ -4401,8 +4472,6 @@ static int __init vmx_init(void)
if (enable_ept) {
bypass_guest_pf = 0;
- kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
- VMX_EPT_WRITABLE_MASK);
kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
VMX_EPT_EXECUTABLE_MASK);
kvm_enable_tdp();
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cdac9e592aa5..fa708c9a7437 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <linux/uaccess.h>
+#include <linux/hash.h>
#include <trace/events/kvm.h>
#define CREATE_TRACE_POINTS
@@ -155,9 +156,11 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
u64 __read_mostly host_xcr0;
-static inline u32 bit(int bitno)
+static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu)
{
- return 1 << (bitno & 31);
+ int i;
+ for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU); i++)
+ vcpu->arch.apf.gfns[i] = ~0;
}
static void kvm_on_user_return(struct user_return_notifier *urn)
@@ -331,23 +334,28 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr)
}
EXPORT_SYMBOL_GPL(kvm_requeue_exception);
-void kvm_inject_page_fault(struct kvm_vcpu *vcpu)
+void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err)
{
- unsigned error_code = vcpu->arch.fault.error_code;
+ if (err)
+ kvm_inject_gp(vcpu, 0);
+ else
+ kvm_x86_ops->skip_emulated_instruction(vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_complete_insn_gp);
+void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
+{
++vcpu->stat.pf_guest;
- vcpu->arch.cr2 = vcpu->arch.fault.address;
- kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
+ vcpu->arch.cr2 = fault->address;
+ kvm_queue_exception_e(vcpu, PF_VECTOR, fault->error_code);
}
-void kvm_propagate_fault(struct kvm_vcpu *vcpu)
+void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
{
- if (mmu_is_nested(vcpu) && !vcpu->arch.fault.nested)
- vcpu->arch.nested_mmu.inject_page_fault(vcpu);
+ if (mmu_is_nested(vcpu) && !fault->nested_page_fault)
+ vcpu->arch.nested_mmu.inject_page_fault(vcpu, fault);
else
- vcpu->arch.mmu.inject_page_fault(vcpu);
-
- vcpu->arch.fault.nested = false;
+ vcpu->arch.mmu.inject_page_fault(vcpu, fault);
}
void kvm_inject_nmi(struct kvm_vcpu *vcpu)
@@ -465,8 +473,8 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
(unsigned long *)&vcpu->arch.regs_avail))
return true;
- gfn = (vcpu->arch.cr3 & ~31u) >> PAGE_SHIFT;
- offset = (vcpu->arch.cr3 & ~31u) & (PAGE_SIZE - 1);
+ gfn = (kvm_read_cr3(vcpu) & ~31u) >> PAGE_SHIFT;
+ offset = (kvm_read_cr3(vcpu) & ~31u) & (PAGE_SIZE - 1);
r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
PFERR_USER_MASK | PFERR_WRITE_MASK);
if (r < 0)
@@ -511,12 +519,15 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
} else
#endif
if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.walk_mmu,
- vcpu->arch.cr3))
+ kvm_read_cr3(vcpu)))
return 1;
}
kvm_x86_ops->set_cr0(vcpu, cr0);
+ if ((cr0 ^ old_cr0) & X86_CR0_PG)
+ kvm_clear_async_pf_completion_queue(vcpu);
+
if ((cr0 ^ old_cr0) & update_bits)
kvm_mmu_reset_context(vcpu);
return 0;
@@ -600,7 +611,8 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
return 1;
} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
&& ((cr4 ^ old_cr4) & pdptr_bits)
- && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3))
+ && !load_pdptrs(vcpu, vcpu->arch.walk_mmu,
+ kvm_read_cr3(vcpu)))
return 1;
if (cr4 & X86_CR4_VMXE)
@@ -620,7 +632,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4);
int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
- if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) {
+ if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) {
kvm_mmu_sync_roots(vcpu);
kvm_mmu_flush_tlb(vcpu);
return 0;
@@ -655,12 +667,13 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT)))
return 1;
vcpu->arch.cr3 = cr3;
+ __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
vcpu->arch.mmu.new_cr3(vcpu);
return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_cr3);
-int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
+int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
{
if (cr8 & CR8_RESERVED_BITS)
return 1;
@@ -670,12 +683,6 @@ int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
vcpu->arch.cr8 = cr8;
return 0;
}
-
-void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
-{
- if (__kvm_set_cr8(vcpu, cr8))
- kvm_inject_gp(vcpu, 0);
-}
EXPORT_SYMBOL_GPL(kvm_set_cr8);
unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
@@ -780,12 +787,12 @@ EXPORT_SYMBOL_GPL(kvm_get_dr);
* kvm-specific. Those are put in the beginning of the list.
*/
-#define KVM_SAVE_MSRS_BEGIN 7
+#define KVM_SAVE_MSRS_BEGIN 8
static u32 msrs_to_save[] = {
MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
- HV_X64_MSR_APIC_ASSIST_PAGE,
+ HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN,
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
MSR_STAR,
#ifdef CONFIG_X86_64
@@ -835,7 +842,6 @@ static int set_efer(struct kvm_vcpu *vcpu, u64 efer)
kvm_x86_ops->set_efer(vcpu, efer);
vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled;
- kvm_mmu_reset_context(vcpu);
/* Update reserved bits */
if ((efer ^ old_efer) & EFER_NX)
@@ -1423,6 +1429,30 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
return 0;
}
+static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
+{
+ gpa_t gpa = data & ~0x3f;
+
+ /* Bits 2:5 are resrved, Should be zero */
+ if (data & 0x3c)
+ return 1;
+
+ vcpu->arch.apf.msr_val = data;
+
+ if (!(data & KVM_ASYNC_PF_ENABLED)) {
+ kvm_clear_async_pf_completion_queue(vcpu);
+ kvm_async_pf_hash_reset(vcpu);
+ return 0;
+ }
+
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
+ return 1;
+
+ vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS);
+ kvm_async_pf_wakeup_all(vcpu);
+ return 0;
+}
+
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
switch (msr) {
@@ -1504,6 +1534,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
}
break;
}
+ case MSR_KVM_ASYNC_PF_EN:
+ if (kvm_pv_enable_async_pf(vcpu, data))
+ return 1;
+ break;
case MSR_IA32_MCG_CTL:
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
@@ -1780,6 +1814,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_KVM_SYSTEM_TIME_NEW:
data = vcpu->arch.time;
break;
+ case MSR_KVM_ASYNC_PF_EN:
+ data = vcpu->arch.apf.msr_val;
+ break;
case MSR_IA32_P5_MC_ADDR:
case MSR_IA32_P5_MC_TYPE:
case MSR_IA32_MCG_CAP:
@@ -1909,6 +1946,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_NOP_IO_DELAY:
case KVM_CAP_MP_STATE:
case KVM_CAP_SYNC_MMU:
+ case KVM_CAP_USER_NMI:
case KVM_CAP_REINJECT_CONTROL:
case KVM_CAP_IRQ_INJECT_STATUS:
case KVM_CAP_ASSIGN_DEV_IRQ:
@@ -1927,6 +1965,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_DEBUGREGS:
case KVM_CAP_X86_ROBUST_SINGLESTEP:
case KVM_CAP_XSAVE:
+ case KVM_CAP_ASYNC_PF:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -2190,6 +2229,11 @@ out:
return r;
}
+static void cpuid_mask(u32 *word, int wordnum)
+{
+ *word &= boot_cpu_data.x86_capability[wordnum];
+}
+
static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
u32 index)
{
@@ -2264,7 +2308,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
break;
case 1:
entry->edx &= kvm_supported_word0_x86_features;
+ cpuid_mask(&entry->edx, 0);
entry->ecx &= kvm_supported_word4_x86_features;
+ cpuid_mask(&entry->ecx, 4);
/* we support x2apic emulation even if host does not support
* it since we emulate x2apic in software */
entry->ecx |= F(X2APIC);
@@ -2355,7 +2401,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
break;
case 0x80000001:
entry->edx &= kvm_supported_word1_x86_features;
+ cpuid_mask(&entry->edx, 1);
entry->ecx &= kvm_supported_word6_x86_features;
+ cpuid_mask(&entry->ecx, 6);
break;
}
@@ -3174,20 +3222,18 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_memslots *slots, *old_slots;
unsigned long *dirty_bitmap;
- r = -ENOMEM;
- dirty_bitmap = vmalloc(n);
- if (!dirty_bitmap)
- goto out;
+ dirty_bitmap = memslot->dirty_bitmap_head;
+ if (memslot->dirty_bitmap == dirty_bitmap)
+ dirty_bitmap += n / sizeof(long);
memset(dirty_bitmap, 0, n);
r = -ENOMEM;
slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
- if (!slots) {
- vfree(dirty_bitmap);
+ if (!slots)
goto out;
- }
memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+ slots->generation++;
old_slots = kvm->memslots;
rcu_assign_pointer(kvm->memslots, slots);
@@ -3200,11 +3246,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
spin_unlock(&kvm->mmu_lock);
r = -EFAULT;
- if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) {
- vfree(dirty_bitmap);
+ if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
goto out;
- }
- vfree(dirty_bitmap);
} else {
r = -EFAULT;
if (clear_user(log->dirty_bitmap, n))
@@ -3271,8 +3314,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (vpic) {
r = kvm_ioapic_init(kvm);
if (r) {
+ mutex_lock(&kvm->slots_lock);
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
&vpic->dev);
+ mutex_unlock(&kvm->slots_lock);
kfree(vpic);
goto create_irqchip_unlock;
}
@@ -3283,10 +3328,12 @@ long kvm_arch_vm_ioctl(struct file *filp,
smp_wmb();
r = kvm_setup_default_irq_routing(kvm);
if (r) {
+ mutex_lock(&kvm->slots_lock);
mutex_lock(&kvm->irq_lock);
kvm_ioapic_destroy(kvm);
kvm_destroy_pic(kvm);
mutex_unlock(&kvm->irq_lock);
+ mutex_unlock(&kvm->slots_lock);
}
create_irqchip_unlock:
mutex_unlock(&kvm->lock);
@@ -3562,63 +3609,63 @@ static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
{
gpa_t t_gpa;
- u32 error;
+ struct x86_exception exception;
BUG_ON(!mmu_is_nested(vcpu));
/* NPT walks are always user-walks */
access |= PFERR_USER_MASK;
- t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &error);
- if (t_gpa == UNMAPPED_GVA)
- vcpu->arch.fault.nested = true;
+ t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &exception);
return t_gpa;
}
-gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
- return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception);
}
- gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+ gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
access |= PFERR_FETCH_MASK;
- return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception);
}
-gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception)
{
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
access |= PFERR_WRITE_MASK;
- return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception);
}
/* 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)
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
+ struct x86_exception *exception)
{
- return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, error);
+ return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, exception);
}
static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
struct kvm_vcpu *vcpu, u32 access,
- u32 *error)
+ struct x86_exception *exception)
{
void *data = val;
int r = X86EMUL_CONTINUE;
while (bytes) {
gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access,
- error);
+ exception);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
- if (gpa == UNMAPPED_GVA) {
- r = X86EMUL_PROPAGATE_FAULT;
- goto out;
- }
+ if (gpa == UNMAPPED_GVA)
+ return X86EMUL_PROPAGATE_FAULT;
ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
if (ret < 0) {
r = X86EMUL_IO_NEEDED;
@@ -3635,31 +3682,35 @@ out:
/* used for instruction fetching */
static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes,
- struct kvm_vcpu *vcpu, u32 *error)
+ struct kvm_vcpu *vcpu,
+ struct x86_exception *exception)
{
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);
+ access | PFERR_FETCH_MASK,
+ exception);
}
static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
- struct kvm_vcpu *vcpu, u32 *error)
+ struct kvm_vcpu *vcpu,
+ struct x86_exception *exception)
{
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);
+ exception);
}
static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes,
- struct kvm_vcpu *vcpu, u32 *error)
+ struct kvm_vcpu *vcpu,
+ struct x86_exception *exception)
{
- return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
+ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
}
static int kvm_write_guest_virt_system(gva_t addr, void *val,
unsigned int bytes,
struct kvm_vcpu *vcpu,
- u32 *error)
+ struct x86_exception *exception)
{
void *data = val;
int r = X86EMUL_CONTINUE;
@@ -3667,15 +3718,13 @@ static int kvm_write_guest_virt_system(gva_t addr, void *val,
while (bytes) {
gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr,
PFERR_WRITE_MASK,
- error);
+ exception);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
- if (gpa == UNMAPPED_GVA) {
- r = X86EMUL_PROPAGATE_FAULT;
- goto out;
- }
+ if (gpa == UNMAPPED_GVA)
+ return X86EMUL_PROPAGATE_FAULT;
ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
if (ret < 0) {
r = X86EMUL_IO_NEEDED;
@@ -3693,7 +3742,7 @@ out:
static int emulator_read_emulated(unsigned long addr,
void *val,
unsigned int bytes,
- unsigned int *error_code,
+ struct x86_exception *exception,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
@@ -3706,7 +3755,7 @@ static int emulator_read_emulated(unsigned long addr,
return X86EMUL_CONTINUE;
}
- gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, error_code);
+ gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, exception);
if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT;
@@ -3715,8 +3764,8 @@ static int emulator_read_emulated(unsigned long addr,
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
goto mmio;
- if (kvm_read_guest_virt(addr, val, bytes, vcpu, NULL)
- == X86EMUL_CONTINUE)
+ if (kvm_read_guest_virt(addr, val, bytes, vcpu, exception)
+ == X86EMUL_CONTINUE)
return X86EMUL_CONTINUE;
mmio:
@@ -3740,7 +3789,7 @@ mmio:
}
int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
- const void *val, int bytes)
+ const void *val, int bytes)
{
int ret;
@@ -3754,12 +3803,12 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
static int emulator_write_emulated_onepage(unsigned long addr,
const void *val,
unsigned int bytes,
- unsigned int *error_code,
+ struct x86_exception *exception,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
- gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error_code);
+ gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, exception);
if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT;
@@ -3792,7 +3841,7 @@ mmio:
int emulator_write_emulated(unsigned long addr,
const void *val,
unsigned int bytes,
- unsigned int *error_code,
+ struct x86_exception *exception,
struct kvm_vcpu *vcpu)
{
/* Crossing a page boundary? */
@@ -3800,7 +3849,7 @@ int emulator_write_emulated(unsigned long addr,
int rc, now;
now = -addr & ~PAGE_MASK;
- rc = emulator_write_emulated_onepage(addr, val, now, error_code,
+ rc = emulator_write_emulated_onepage(addr, val, now, exception,
vcpu);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -3808,7 +3857,7 @@ int emulator_write_emulated(unsigned long addr,
val += now;
bytes -= now;
}
- return emulator_write_emulated_onepage(addr, val, bytes, error_code,
+ return emulator_write_emulated_onepage(addr, val, bytes, exception,
vcpu);
}
@@ -3826,7 +3875,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
const void *old,
const void *new,
unsigned int bytes,
- unsigned int *error_code,
+ struct x86_exception *exception,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
@@ -3884,7 +3933,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
emul_write:
printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
- return emulator_write_emulated(addr, new, bytes, error_code, vcpu);
+ return emulator_write_emulated(addr, new, bytes, exception, vcpu);
}
static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
@@ -3909,7 +3958,7 @@ static int emulator_pio_in_emulated(int size, unsigned short port, void *val,
if (vcpu->arch.pio.count)
goto data_avail;
- trace_kvm_pio(0, port, size, 1);
+ trace_kvm_pio(0, port, size, count);
vcpu->arch.pio.port = port;
vcpu->arch.pio.in = 1;
@@ -3937,7 +3986,7 @@ static int emulator_pio_out_emulated(int size, unsigned short port,
const void *val, unsigned int count,
struct kvm_vcpu *vcpu)
{
- trace_kvm_pio(1, port, size, 1);
+ trace_kvm_pio(1, port, size, count);
vcpu->arch.pio.port = port;
vcpu->arch.pio.in = 0;
@@ -3978,13 +4027,15 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu)
return X86EMUL_CONTINUE;
if (kvm_x86_ops->has_wbinvd_exit()) {
- preempt_disable();
+ int cpu = get_cpu();
+
+ cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);
smp_call_function_many(vcpu->arch.wbinvd_dirty_mask,
wbinvd_ipi, NULL, 1);
- preempt_enable();
+ put_cpu();
cpumask_clear(vcpu->arch.wbinvd_dirty_mask);
- }
- wbinvd();
+ } else
+ wbinvd();
return X86EMUL_CONTINUE;
}
EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd);
@@ -4024,7 +4075,7 @@ static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu)
value = vcpu->arch.cr2;
break;
case 3:
- value = vcpu->arch.cr3;
+ value = kvm_read_cr3(vcpu);
break;
case 4:
value = kvm_read_cr4(vcpu);
@@ -4058,7 +4109,7 @@ static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu)
res = kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val));
break;
case 8:
- res = __kvm_set_cr8(vcpu, val & 0xfUL);
+ res = kvm_set_cr8(vcpu, val);
break;
default:
vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
@@ -4211,12 +4262,13 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
static void inject_emulated_exception(struct kvm_vcpu *vcpu)
{
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
- if (ctxt->exception == PF_VECTOR)
- kvm_propagate_fault(vcpu);
- else if (ctxt->error_code_valid)
- kvm_queue_exception_e(vcpu, ctxt->exception, ctxt->error_code);
+ if (ctxt->exception.vector == PF_VECTOR)
+ kvm_propagate_fault(vcpu, &ctxt->exception);
+ else if (ctxt->exception.error_code_valid)
+ kvm_queue_exception_e(vcpu, ctxt->exception.vector,
+ ctxt->exception.error_code);
else
- kvm_queue_exception(vcpu, ctxt->exception);
+ kvm_queue_exception(vcpu, ctxt->exception.vector);
}
static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
@@ -4272,13 +4324,19 @@ EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
static int handle_emulation_failure(struct kvm_vcpu *vcpu)
{
+ int r = EMULATE_DONE;
+
++vcpu->stat.insn_emulation_fail;
trace_kvm_emulate_insn_failed(vcpu);
- vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
- vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
- vcpu->run->internal.ndata = 0;
+ if (!is_guest_mode(vcpu)) {
+ vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+ vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+ vcpu->run->internal.ndata = 0;
+ r = EMULATE_FAIL;
+ }
kvm_queue_exception(vcpu, UD_VECTOR);
- return EMULATE_FAIL;
+
+ return r;
}
static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
@@ -4307,10 +4365,11 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
return false;
}
-int emulate_instruction(struct kvm_vcpu *vcpu,
- unsigned long cr2,
- u16 error_code,
- int emulation_type)
+int x86_emulate_instruction(struct kvm_vcpu *vcpu,
+ unsigned long cr2,
+ int emulation_type,
+ void *insn,
+ int insn_len)
{
int r;
struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
@@ -4328,10 +4387,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
init_emulate_ctxt(vcpu);
vcpu->arch.emulate_ctxt.interruptibility = 0;
- vcpu->arch.emulate_ctxt.exception = -1;
+ vcpu->arch.emulate_ctxt.have_exception = false;
vcpu->arch.emulate_ctxt.perm_ok = false;
- r = x86_decode_insn(&vcpu->arch.emulate_ctxt);
+ r = x86_decode_insn(&vcpu->arch.emulate_ctxt, insn, insn_len);
if (r == X86EMUL_PROPAGATE_FAULT)
goto done;
@@ -4394,7 +4453,7 @@ restart:
}
done:
- if (vcpu->arch.emulate_ctxt.exception >= 0) {
+ if (vcpu->arch.emulate_ctxt.have_exception) {
inject_emulated_exception(vcpu);
r = EMULATE_DONE;
} else if (vcpu->arch.pio.count) {
@@ -4418,7 +4477,7 @@ done:
return r;
}
-EXPORT_SYMBOL_GPL(emulate_instruction);
+EXPORT_SYMBOL_GPL(x86_emulate_instruction);
int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
{
@@ -4569,9 +4628,11 @@ static void kvm_timer_init(void)
#ifdef CONFIG_CPU_FREQ
struct cpufreq_policy policy;
memset(&policy, 0, sizeof(policy));
- cpufreq_get_policy(&policy, get_cpu());
+ cpu = get_cpu();
+ cpufreq_get_policy(&policy, cpu);
if (policy.cpuinfo.max_freq)
max_tsc_khz = policy.cpuinfo.max_freq;
+ put_cpu();
#endif
cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
@@ -4656,7 +4717,6 @@ int kvm_arch_init(void *opaque)
kvm_x86_ops = ops;
kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
- kvm_mmu_set_base_ptes(PT_PRESENT_MASK);
kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
PT_DIRTY_MASK, PT64_NX_MASK, 0);
@@ -5119,6 +5179,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
vcpu->fpu_active = 0;
kvm_x86_ops->fpu_deactivate(vcpu);
}
+ if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) {
+ /* Page is swapped out. Do synthetic halt */
+ vcpu->arch.apf.halted = true;
+ r = 1;
+ goto out;
+ }
}
r = kvm_mmu_reload(vcpu);
@@ -5247,7 +5313,8 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
r = 1;
while (r > 0) {
- if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
+ if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
+ !vcpu->arch.apf.halted)
r = vcpu_enter_guest(vcpu);
else {
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
@@ -5260,6 +5327,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.mp_state =
KVM_MP_STATE_RUNNABLE;
case KVM_MP_STATE_RUNNABLE:
+ vcpu->arch.apf.halted = false;
break;
case KVM_MP_STATE_SIPI_RECEIVED:
default:
@@ -5281,6 +5349,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
vcpu->run->exit_reason = KVM_EXIT_INTR;
++vcpu->stat.request_irq_exits;
}
+
+ kvm_check_async_pf_completion(vcpu);
+
if (signal_pending(current)) {
r = -EINTR;
vcpu->run->exit_reason = KVM_EXIT_INTR;
@@ -5316,8 +5387,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
/* re-sync apic's tpr */
- if (!irqchip_in_kernel(vcpu->kvm))
- kvm_set_cr8(vcpu, kvm_run->cr8);
+ if (!irqchip_in_kernel(vcpu->kvm)) {
+ if (kvm_set_cr8(vcpu, kvm_run->cr8) != 0) {
+ r = -EINVAL;
+ goto out;
+ }
+ }
if (vcpu->arch.pio.count || vcpu->mmio_needed) {
if (vcpu->mmio_needed) {
@@ -5326,7 +5401,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
vcpu->mmio_needed = 0;
}
vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
- r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE);
+ r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
if (r != EMULATE_DONE) {
r = 0;
@@ -5439,7 +5514,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->cr0 = kvm_read_cr0(vcpu);
sregs->cr2 = vcpu->arch.cr2;
- sregs->cr3 = vcpu->arch.cr3;
+ sregs->cr3 = kvm_read_cr3(vcpu);
sregs->cr4 = kvm_read_cr4(vcpu);
sregs->cr8 = kvm_get_cr8(vcpu);
sregs->efer = vcpu->arch.efer;
@@ -5507,8 +5582,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_x86_ops->set_gdt(vcpu, &dt);
vcpu->arch.cr2 = sregs->cr2;
- mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
+ mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3;
vcpu->arch.cr3 = sregs->cr3;
+ __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
kvm_set_cr8(vcpu, sregs->cr8);
@@ -5522,8 +5598,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
+ if (sregs->cr4 & X86_CR4_OSXSAVE)
+ update_cpuid(vcpu);
if (!is_long_mode(vcpu) && is_pae(vcpu)) {
- load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
+ load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu));
mmu_reset_needed = 1;
}
@@ -5774,6 +5852,8 @@ free_vcpu:
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.apf.msr_val = 0;
+
vcpu_load(vcpu);
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
@@ -5793,6 +5873,11 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
vcpu->arch.dr7 = DR7_FIXED_1;
kvm_make_request(KVM_REQ_EVENT, vcpu);
+ vcpu->arch.apf.msr_val = 0;
+
+ kvm_clear_async_pf_completion_queue(vcpu);
+ kvm_async_pf_hash_reset(vcpu);
+ vcpu->arch.apf.halted = false;
return kvm_x86_ops->vcpu_reset(vcpu);
}
@@ -5882,6 +5967,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL))
goto fail_free_mce_banks;
+ kvm_async_pf_hash_reset(vcpu);
+
return 0;
fail_free_mce_banks:
kfree(vcpu->arch.mce_banks);
@@ -5907,13 +5994,8 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
free_page((unsigned long)vcpu->arch.pio_data);
}
-struct kvm *kvm_arch_create_vm(void)
+int kvm_arch_init_vm(struct kvm *kvm)
{
- struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
-
- if (!kvm)
- return ERR_PTR(-ENOMEM);
-
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
@@ -5922,7 +6004,7 @@ struct kvm *kvm_arch_create_vm(void)
spin_lock_init(&kvm->arch.tsc_write_lock);
- return kvm;
+ return 0;
}
static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
@@ -5940,8 +6022,10 @@ static void kvm_free_vcpus(struct kvm *kvm)
/*
* Unpin any mmu pages first.
*/
- kvm_for_each_vcpu(i, vcpu, kvm)
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ kvm_clear_async_pf_completion_queue(vcpu);
kvm_unload_vcpu_mmu(vcpu);
+ }
kvm_for_each_vcpu(i, vcpu, kvm)
kvm_arch_vcpu_free(vcpu);
@@ -5965,13 +6049,10 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kfree(kvm->arch.vpic);
kfree(kvm->arch.vioapic);
kvm_free_vcpus(kvm);
- kvm_free_physmem(kvm);
if (kvm->arch.apic_access_page)
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);
}
int kvm_arch_prepare_memory_region(struct kvm *kvm,
@@ -6052,7 +6133,9 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE
+ return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
+ !vcpu->arch.apf.halted)
+ || !list_empty_careful(&vcpu->async_pf.done)
|| vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED
|| vcpu->arch.nmi_pending ||
(kvm_arch_interrupt_allowed(vcpu) &&
@@ -6111,6 +6194,147 @@ void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
}
EXPORT_SYMBOL_GPL(kvm_set_rflags);
+void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work)
+{
+ int r;
+
+ if ((vcpu->arch.mmu.direct_map != work->arch.direct_map) ||
+ is_error_page(work->page))
+ return;
+
+ r = kvm_mmu_reload(vcpu);
+ if (unlikely(r))
+ return;
+
+ if (!vcpu->arch.mmu.direct_map &&
+ work->arch.cr3 != vcpu->arch.mmu.get_cr3(vcpu))
+ return;
+
+ vcpu->arch.mmu.page_fault(vcpu, work->gva, 0, true);
+}
+
+static inline u32 kvm_async_pf_hash_fn(gfn_t gfn)
+{
+ return hash_32(gfn & 0xffffffff, order_base_2(ASYNC_PF_PER_VCPU));
+}
+
+static inline u32 kvm_async_pf_next_probe(u32 key)
+{
+ return (key + 1) & (roundup_pow_of_two(ASYNC_PF_PER_VCPU) - 1);
+}
+
+static void kvm_add_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+ u32 key = kvm_async_pf_hash_fn(gfn);
+
+ while (vcpu->arch.apf.gfns[key] != ~0)
+ key = kvm_async_pf_next_probe(key);
+
+ vcpu->arch.apf.gfns[key] = gfn;
+}
+
+static u32 kvm_async_pf_gfn_slot(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+ int i;
+ u32 key = kvm_async_pf_hash_fn(gfn);
+
+ for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU) &&
+ (vcpu->arch.apf.gfns[key] != gfn &&
+ vcpu->arch.apf.gfns[key] != ~0); i++)
+ key = kvm_async_pf_next_probe(key);
+
+ return key;
+}
+
+bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+ return vcpu->arch.apf.gfns[kvm_async_pf_gfn_slot(vcpu, gfn)] == gfn;
+}
+
+static void kvm_del_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+ u32 i, j, k;
+
+ i = j = kvm_async_pf_gfn_slot(vcpu, gfn);
+ while (true) {
+ vcpu->arch.apf.gfns[i] = ~0;
+ do {
+ j = kvm_async_pf_next_probe(j);
+ if (vcpu->arch.apf.gfns[j] == ~0)
+ return;
+ k = kvm_async_pf_hash_fn(vcpu->arch.apf.gfns[j]);
+ /*
+ * k lies cyclically in ]i,j]
+ * | i.k.j |
+ * |....j i.k.| or |.k..j i...|
+ */
+ } while ((i <= j) ? (i < k && k <= j) : (i < k || k <= j));
+ vcpu->arch.apf.gfns[i] = vcpu->arch.apf.gfns[j];
+ i = j;
+ }
+}
+
+static int apf_put_user(struct kvm_vcpu *vcpu, u32 val)
+{
+
+ return kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apf.data, &val,
+ sizeof(val));
+}
+
+void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
+ struct kvm_async_pf *work)
+{
+ struct x86_exception fault;
+
+ trace_kvm_async_pf_not_present(work->arch.token, work->gva);
+ kvm_add_async_pf_gfn(vcpu, work->arch.gfn);
+
+ if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) ||
+ (vcpu->arch.apf.send_user_only &&
+ kvm_x86_ops->get_cpl(vcpu) == 0))
+ kvm_make_request(KVM_REQ_APF_HALT, vcpu);
+ else if (!apf_put_user(vcpu, KVM_PV_REASON_PAGE_NOT_PRESENT)) {
+ fault.vector = PF_VECTOR;
+ fault.error_code_valid = true;
+ fault.error_code = 0;
+ fault.nested_page_fault = false;
+ fault.address = work->arch.token;
+ kvm_inject_page_fault(vcpu, &fault);
+ }
+}
+
+void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
+ struct kvm_async_pf *work)
+{
+ struct x86_exception fault;
+
+ trace_kvm_async_pf_ready(work->arch.token, work->gva);
+ if (is_error_page(work->page))
+ work->arch.token = ~0; /* broadcast wakeup */
+ else
+ kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
+
+ if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) &&
+ !apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
+ fault.vector = PF_VECTOR;
+ fault.error_code_valid = true;
+ fault.error_code = 0;
+ fault.nested_page_fault = false;
+ fault.address = work->arch.token;
+ kvm_inject_page_fault(vcpu, &fault);
+ }
+ vcpu->arch.apf.halted = false;
+}
+
+bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
+{
+ if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED))
+ return true;
+ else
+ return !kvm_event_needs_reinjection(vcpu) &&
+ kvm_x86_ops->interrupt_allowed(vcpu);
+}
+
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2cea414489f3..c600da830ce0 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
}
+static inline u32 bit(int bitno)
+{
+ return 1 << (bitno & 31);
+}
+
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 73b1e1a1f489..eba687f0cc0c 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3)
{
lguest_data.pgdir = cr3;
lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
- cr3_changed = true;
+
+ /* These two page tables are simple, linear, and used during boot */
+ if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
+ cr3_changed = true;
}
static unsigned long lguest_read_cr3(void)
@@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
* to forget all of them. Fortunately, this is very rare.
*
* ... except in early boot when the kernel sets up the initial pagetables,
- * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell
- * the Host anything changed until we've done the first page table switch,
- * which brings boot back to 0.25 seconds.
+ * which makes booting astonishingly slow: 48 seconds! So we don't even tell
+ * the Host anything changed until we've done the first real page table switch,
+ * which brings boot back to 4.3 seconds.
*/
static void lguest_set_pte(pte_t *ptep, pte_t pteval)
{
@@ -821,7 +824,7 @@ static void __init lguest_init_IRQ(void)
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
/* Some systems map "vectors" to interrupts weirdly. Not us! */
- __get_cpu_var(vector_irq)[i] = i - FIRST_EXTERNAL_VECTOR;
+ __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
if (i != SYSCALL_VECTOR)
set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
@@ -1002,7 +1005,7 @@ static void lguest_time_init(void)
clockevents_register_device(&lguest_clockevent);
/* Finally, we unblock the timer interrupt. */
- enable_lguest_irq(0);
+ clear_bit(0, lguest_data.blocked_interrupts);
}
/*
@@ -1349,9 +1352,6 @@ __init void lguest_init(void)
*/
switch_to_new_gdt(0);
- /* We actually boot with all memory mapped, but let's say 128MB. */
- max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
-
/*
* The Host<->Guest Switcher lives at the top of our address space, and
* the Host told us how big it is when we made LGUEST_INIT hypercall:
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 4f420c2f2d55..e7d5382ef263 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -4,6 +4,7 @@
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/processor-flags.h>
+#include <asm/pgtable.h>
/*G:020
* Our story starts with the kernel booting into startup_32 in
@@ -37,9 +38,113 @@ ENTRY(lguest_entry)
/* Set up the initial stack so we can run C code. */
movl $(init_thread_union+THREAD_SIZE),%esp
+ call init_pagetables
+
/* Jumps are relative: we're running __PAGE_OFFSET too low. */
jmp lguest_init+__PAGE_OFFSET
+/*
+ * Initialize page tables. This creates a PDE and a set of page
+ * tables, which are located immediately beyond __brk_base. The variable
+ * _brk_end is set up to point to the first "safe" location.
+ * Mappings are created both at virtual address 0 (identity mapping)
+ * and PAGE_OFFSET for up to _end.
+ *
+ * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they
+ * don't have a stack at this point, so we can't just use call and ret.
+ */
+init_pagetables:
+#if PTRS_PER_PMD > 1
+#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
+#else
+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
+#endif
+#define pa(X) ((X) - __PAGE_OFFSET)
+
+/* Enough space to fit pagetables for the low memory linear map */
+MAPPING_BEYOND_END = \
+ PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+#ifdef CONFIG_X86_PAE
+
+ /*
+ * In PAE mode initial_page_table is statically defined to contain
+ * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
+ * entries). The identity mapping is handled by pointing two PGD entries
+ * to the first kernel PMD.
+ *
+ * Note the upper half of each PMD or PTE are always zero at this stage.
+ */
+
+#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
+
+ xorl %ebx,%ebx /* %ebx is kept at zero */
+
+ movl $pa(__brk_base), %edi
+ movl $pa(initial_pg_pmd), %edx
+ movl $PTE_IDENT_ATTR, %eax
+10:
+ leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */
+ movl %ecx,(%edx) /* Store PMD entry */
+ /* Upper half already zero */
+ addl $8,%edx
+ movl $512,%ecx
+11:
+ stosl
+ xchgl %eax,%ebx
+ stosl
+ xchgl %eax,%ebx
+ addl $0x1000,%eax
+ loop 11b
+
+ /*
+ * End condition: we must map up to the end + MAPPING_BEYOND_END.
+ */
+ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+ cmpl %ebp,%eax
+ jb 10b
+1:
+ addl $__PAGE_OFFSET, %edi
+ movl %edi, pa(_brk_end)
+ shrl $12, %eax
+ movl %eax, pa(max_pfn_mapped)
+
+ /* Do early initialization of the fixmap area */
+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+ movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
+#else /* Not PAE */
+
+page_pde_offset = (__PAGE_OFFSET >> 20);
+
+ movl $pa(__brk_base), %edi
+ movl $pa(initial_page_table), %edx
+ movl $PTE_IDENT_ATTR, %eax
+10:
+ leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
+ movl %ecx,(%edx) /* Store identity PDE entry */
+ movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
+ addl $4,%edx
+ movl $1024, %ecx
+11:
+ stosl
+ addl $0x1000,%eax
+ loop 11b
+ /*
+ * End condition: we must map up to the end + MAPPING_BEYOND_END.
+ */
+ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+ cmpl %ebp,%eax
+ jb 10b
+ addl $__PAGE_OFFSET, %edi
+ movl %edi, pa(_brk_end)
+ shrl $12, %eax
+ movl %eax, pa(max_pfn_mapped)
+
+ /* Do early initialization of the fixmap area */
+ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+ movl %eax,pa(initial_page_table+0xffc)
+#endif
+ ret
+
/*G:055
* We create a macro which puts the assembler code between lgstart_ and lgend_
* markers. These templates are put in the .text section: they can't be
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index a011bcc0f943..7d90d47655ba 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -630,21 +630,29 @@ static int __init_ibs_nmi(void)
return 0;
}
-/* initialize the APIC for the IBS interrupts if available */
+/*
+ * check and reserve APIC extended interrupt LVT offset for IBS if
+ * available
+ *
+ * init_ibs() preforms implicitly cpu-local operations, so pin this
+ * thread to its current CPU
+ */
+
static void init_ibs(void)
{
- ibs_caps = get_ibs_caps();
+ preempt_disable();
+ ibs_caps = get_ibs_caps();
if (!ibs_caps)
- return;
+ goto out;
- if (__init_ibs_nmi()) {
+ if (__init_ibs_nmi() < 0)
ibs_caps = 0;
- return;
- }
+ else
+ printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
- printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n",
- (unsigned)ibs_caps);
+out:
+ preempt_enable();
}
static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index c4bb261c106e..b1805b78842f 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pci_dev *dev = data;
- resource_size_t start = round_down(res->end - size + 1, align);
+ resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO) {
-
- /*
- * If we're avoiding ISA aliases, the largest contiguous I/O
- * port space is 256 bytes. Clearing bits 9 and 10 preserves
- * all 256-byte and smaller alignments, so the result will
- * still be correctly aligned.
- */
- if (!skip_isa_ioresource_align(dev))
- start &= ~0x300;
- } else if (res->flags & IORESOURCE_MEM) {
- if (start < BIOS_END)
- start = res->end; /* fail; no space */
+ if (skip_isa_ioresource_align(dev))
+ return start;
+ if (start & 0x300)
+ start = (start + 0x3ff) & ~0x3ff;
}
return start;
}
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 9f9bfb705cf9..87e6c8323117 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -589,7 +589,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH10_1:
case PCI_DEVICE_ID_INTEL_ICH10_2:
case PCI_DEVICE_ID_INTEL_ICH10_3:
- case PCI_DEVICE_ID_INTEL_PATSBURG_LPC:
+ case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0:
+ case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index d7b5109f7a9c..25cd4a07d09f 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -70,6 +70,9 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
struct xen_pci_frontend_ops *xen_pci_frontend;
EXPORT_SYMBOL_GPL(xen_pci_frontend);
+#define XEN_PIRQ_MSI_DATA (MSI_DATA_TRIGGER_EDGE | \
+ MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0))
+
static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
struct msi_msg *msg)
{
@@ -83,12 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
MSI_ADDR_REDIRECTION_CPU |
MSI_ADDR_DEST_ID(pirq);
- msg->data =
- MSI_DATA_TRIGGER_EDGE |
- MSI_DATA_LEVEL_ASSERT |
- /* delivery mode reserved */
- (3 << 8) |
- MSI_DATA_VECTOR(0);
+ msg->data = XEN_PIRQ_MSI_DATA;
}
static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
@@ -98,8 +96,23 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
struct msi_msg msg;
list_for_each_entry(msidesc, &dev->msi_list, list) {
+ __read_msi_msg(msidesc, &msg);
+ pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
+ ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
+ if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) {
+ xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
+ "msi-x" : "msi", &irq, &pirq, XEN_ALLOC_IRQ);
+ if (irq < 0)
+ goto error;
+ ret = set_irq_msi(irq, msidesc);
+ if (ret < 0)
+ goto error_while;
+ printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d"
+ " pirq=%d\n", irq, pirq);
+ return 0;
+ }
xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
- "msi-x" : "msi", &irq, &pirq);
+ "msi-x" : "msi", &irq, &pirq, (XEN_ALLOC_IRQ | XEN_ALLOC_PIRQ));
if (irq < 0 || pirq < 0)
goto error;
printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index 4a2afa1bac51..b6552b189bcd 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
export CPPFLAGS_vdso.lds += -P -C
-VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \
+VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
@@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter
vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
-VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1
+VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
# This makes sure the $(obj) subdirectory exists even though vdso32/
# is not a kbuild sub-make subdirectory.
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 02c710bebf7a..44dcad43989d 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1021,10 +1021,6 @@ static void xen_reboot(int reason)
{
struct sched_shutdown r = { .reason = reason };
-#ifdef CONFIG_SMP
- stop_other_cpus();
-#endif
-
if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
BUG();
}
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index a1feff9e59b6..44924e551fde 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2415,8 +2415,6 @@ void __init xen_init_mmu_ops(void)
x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
pv_mmu_ops = xen_mmu_ops;
- vmap_lazy_unmap = false;
-
memset(dummy_mapping, 0xff, PAGE_SIZE);
}
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
index 0f456386cce5..25c52f94a27c 100644
--- a/arch/x86/xen/platform-pci-unplug.c
+++ b/arch/x86/xen/platform-pci-unplug.c
@@ -68,7 +68,7 @@ static int __init check_platform_magic(void)
return 0;
}
-void __init xen_unplug_emulated_devices(void)
+void xen_unplug_emulated_devices(void)
{
int r;
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 01afd8a94607..b5a7f928234b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -181,24 +181,21 @@ char * __init xen_memory_setup(void)
for (i = 0; i < memmap.nr_entries; i++) {
unsigned long long end = map[i].addr + map[i].size;
- if (map[i].type == E820_RAM) {
- if (map[i].addr < mem_end && end > mem_end) {
- /* Truncate region to max_mem. */
- u64 delta = end - mem_end;
+ if (map[i].type == E820_RAM && end > mem_end) {
+ /* RAM off the end - may be partially included */
+ u64 delta = min(map[i].size, end - mem_end);
- map[i].size -= delta;
- extra_pages += PFN_DOWN(delta);
+ map[i].size -= delta;
+ end -= delta;
- end = mem_end;
- }
+ extra_pages += PFN_DOWN(delta);
}
- if (end > xen_extra_mem_start)
+ if (map[i].size > 0 && end > xen_extra_mem_start)
xen_extra_mem_start = end;
- /* If region is non-RAM or below mem_end, add what remains */
- if ((map[i].type != E820_RAM || map[i].addr < mem_end) &&
- map[i].size > 0)
+ /* Add region if any remains */
+ if (map[i].size > 0)
e820_add_region(map[i].addr, map[i].size, map[i].type);
}
@@ -252,20 +249,6 @@ char * __init xen_memory_setup(void)
return "Xen";
}
-static void xen_idle(void)
-{
- local_irq_disable();
-
- if (need_resched())
- local_irq_enable();
- else {
- current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
- safe_halt();
- current_thread_info()->status |= TS_POLLING;
- }
-}
-
/*
* Set the bit indicating "nosegneg" library variants should be used.
* We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -362,7 +345,11 @@ void __init xen_arch_setup(void)
MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ?
COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
- pm_idle = xen_idle;
+ /* Set up idle, making sure it calls safe_halt() pvop */
+#ifdef CONFIG_X86_32
+ boot_cpu_data.hlt_works_ok = 1;
+#endif
+ pm_idle = default_idle;
fiddle_vdso();
}
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 1d789d56877c..9bbd63a129b5 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -31,6 +31,7 @@ void xen_hvm_post_suspend(int suspend_cancelled)
int cpu;
xen_hvm_init_shared_info();
xen_callback_vector();
+ xen_unplug_emulated_devices();
if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
for_each_online_cpu(cpu) {
xen_setup_runstate_info(cpu);
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index b2bb5aa3b054..5da5e53fb94c 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -426,6 +426,8 @@ void xen_timer_resume(void)
{
int cpu;
+ pvclock_resume();
+
if (xen_clockevent != &xen_vcpuop_clockevent)
return;
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 64044747348e..9d41bf985757 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -43,7 +43,7 @@ void xen_vcpu_restore(void);
void xen_callback_vector(void);
void xen_hvm_init_shared_info(void);
-void __init xen_unplug_emulated_devices(void);
+void xen_unplug_emulated_devices(void);
void __init xen_build_dynamic_phys_to_machine(void);
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index d373d159e75e..f2d948a77ac0 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -76,10 +76,10 @@ config XTENSA_VARIANT_S6000
endchoice
config XTENSA_UNALIGNED_USER
- bool "Unaligned memory access in use space"
+ bool "Unaligned memory access in user space"
help
- The Xtensa architecture currently does not handle unaligned
- memory accesses in hardware but through an exception handler.
+ Xtensa processors are often not configured to handle unaligned
+ memory accesses in hardware, but rather through an exception handler.
Per default, unaligned memory accesses are disabled in user space.
Say Y here to enable unaligned memory access in user space.
@@ -149,8 +149,15 @@ config XTENSA_PLATFORM_ISS
config XTENSA_PLATFORM_XT2000
bool "XT2000"
help
- XT2000 is the name of Tensilica's feature-rich emulation platform.
- This hardware is capable of running a full Linux distribution.
+ XT2000 is the name of Tensilica's older emulation platform.
+
+config XTENSA_PLATFORM_XTAVNET
+ bool "XTAVNET"
+ select XTENSA_CALIBRATE_CCOUNT
+ select ETHOC
+ help
+ Selects support for the Tensilica-configured Avnet emulation boards.
+ These include the LX60 (XT-AV60), LX200 (XT-AV200), and LX110 (XT-AV110).
config XTENSA_PLATFORM_S6105
bool "S6105"
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 7608559de93a..34d8427622eb 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -24,6 +24,7 @@ export VARIANT
# Platform configuration
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
+platform-$(CONFIG_XTENSA_PLATFORM_XTAVNET) := xtavnet
platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105
@@ -61,7 +62,9 @@ ifneq ($(VARIANT),)
ifneq ($(COMPILE_ARCH), xtensa)
ifndef CROSS_COMPILE
- CROSS_COMPILE = xtensa_$(VARIANT)-
+ CROSS_COMPILE := $(call cc-cross-prefix, xtensa_$(VARIANT)- \
+ xtensa-linux-uclibc- xtensa_$(VARIANT)-linux-uclibc- \
+ xtensa-linux-gnu- xtensa_$(VARIANT)-linux-gnu-)
endif
endif
endif
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 40aa55b485be..8657c62fc78b 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -23,6 +23,7 @@ subdir-y := lib
bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
+bootdir-$(CONFIG_XTENSA_PLATFORM_XTAVNET) += boot-redboot boot-elf
zImage zImage.initrd Image Image.initrd: $(bootdir-y)
diff --git a/arch/xtensa/include/asm/coprocessor.h b/arch/xtensa/include/asm/coprocessor.h
index 75c94a1658b0..42da613d1623 100644
--- a/arch/xtensa/include/asm/coprocessor.h
+++ b/arch/xtensa/include/asm/coprocessor.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/coprocessor.h
+ * arch/xtensa/include/asm/coprocessor.h
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2003 - 2007 Tensilica Inc.
+ * Copyright (C) 2003-2010 Tensilica Inc.
*/
@@ -15,9 +15,10 @@
#include <linux/stringify.h>
#include <variant/core.h>
#include <variant/tie.h>
+#include <variant/core.h>
#include <asm/types.h>
-#ifdef __ASSEMBLY__
+#if defined(__ASSEMBLY__) && !defined(LINKER_SCRIPT)
# include <variant/tie-asm.h>
.macro xchal_sa_start a b
@@ -70,7 +71,7 @@
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLY__ && !LINKER_SCRIPT */
/*
* XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index d04cd3a625fa..145db5cc6191 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/io.h
+ * arch/xtensa/include/asm/io.h
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_IO_H
@@ -63,40 +63,33 @@ static inline void * phys_to_virt(unsigned long address)
#define bus_to_virt(x) phys_to_virt(x)
/*
- * Return the virtual (cached) address for the specified bus memory.
+ * Return the virtual (uncached) address for the specified bus memory
+ * (which is, for now, simply a physical address).
* Note that we currently don't support any address outside the KIO segment.
+ * See also arch/mips/include/asm/io.h for nice comments.
*/
-static inline void *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *__ioremap(unsigned long offset, unsigned long size)
{
#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
- return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
+ && offset <= XCHAL_KIO_PADDR + XCHAL_KIO_SIZE - 1)
+ return (void __iomem *)(offset - XCHAL_KIO_PADDR + XCHAL_KIO_BYPASS_VADDR);
else
BUG();
#else
- return (void *)offset;
+ return (void __iomem *)offset;
#endif
}
-static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
-{
-#ifdef CONFIG_MMU
- if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
- return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
- else
- BUG();
-#else
- return (void *)offset;
-#endif
-}
+#define ioremap(offset, size) __ioremap(offset, size)
+#define ioremap_nocache(offset, size) __ioremap(offset, size)
-static inline void iounmap(void *addr)
+static inline void iounmap(void __iomem *addr)
{
}
+
/*
* Generic I/O
*/
@@ -191,6 +184,13 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
#endif
+#ifndef CONFIG_GENERIC_IOMAP
+/* Partial Simple MMIO */
+#define ioread32(a) __raw_readl(a)
+#define iowrite32(v,a) __raw_writel((v),(a))
+#endif
+
+
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem access
*/
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h
index 4c0ccc9c4f4c..6af436f4429d 100644
--- a/arch/xtensa/include/asm/irq.h
+++ b/arch/xtensa/include/asm/irq.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/irq.h
+ * arch/xtensa/include/asm/irq.h
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_IRQ_H
@@ -22,6 +22,9 @@ static inline void variant_irq_enable(unsigned int irq) { }
static inline void variant_irq_disable(unsigned int irq) { }
#endif
+/* This number is used when no interrupt has been assigned. */
+#define NO_IRQ (-1)
+
#ifndef VARIANT_NR_IRQS
# define VARIANT_NR_IRQS 0
#endif
diff --git a/arch/xtensa/include/asm/serial.h b/arch/xtensa/include/asm/serial.h
index a8a2493260f6..c55a0e2b47ca 100644
--- a/arch/xtensa/include/asm/serial.h
+++ b/arch/xtensa/include/asm/serial.h
@@ -1,5 +1,5 @@
/*
- * include/asm-xtensa/serial.h
+ * arch/xtensa/include/asm/serial.h
*
* Configuration details for 8250, 16450, 16550, etc. serial ports
*
@@ -7,12 +7,20 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_SERIAL_H
#define _XTENSA_SERIAL_H
+#include <asm/irq.h>
#include <platform/serial.h>
+/* The 8250 driver treats IRQ 0 as absent. For the Xtensa architecture,
+ interrupt 0 is valid, must compare against NO_IRQ instead. */
+#ifdef is_real_interrupt
+#undef is_real_interrupt
+#define is_real_interrupt(irq) ((irq) != NO_IRQ)
+#endif
+
#endif /* _XTENSA_SERIAL_H */
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 2d2728b3e862..e426a4ec7f22 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -27,8 +27,8 @@ sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \
-e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
quiet_cmd__cpp_lds_S = LDS $@
- cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \
- | sed $(sed-y) >$@
+ cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ \
+ -DLINKER_SCRIPT $< | sed $(sed-y) >$@
$(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
$(call if_changed_dep,_cpp_lds_S)
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 19df764f6399..88ba96e2df25 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -31,7 +31,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */
unsigned long nsec_per_ccount; /* nsec per ccount increment */
#endif
-static cycle_t ccount_read(void)
+static cycle_t ccount_read(struct clocksource *cs)
{
return (cycle_t)get_ccount();
}
diff --git a/arch/xtensa/platforms/xtavnet/Makefile b/arch/xtensa/platforms/xtavnet/Makefile
new file mode 100644
index 000000000000..06b120b40015
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/Makefile
@@ -0,0 +1,10 @@
+# Makefile for the Tensilica Avnet-based Emulation Boards
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are in the main makefile...
+
+obj-y = setup.o lcd.o
+
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/hardware.h b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h
new file mode 100644
index 000000000000..5301be745113
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h
@@ -0,0 +1,85 @@
+/*
+ * arch/xtensa/platforms/xtavnet/include/platform/hardware.h
+ *
+ * This file contains the hardware configuration of Tensilica Avnet boards
+ * (XT-AV60, XT-AV110, XT-AV200, derived from Avnet LX60, LX110, LX200
+ * boards respectively).
+ *
+ * Copyright (C) 2006-2010 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __XTAVNET_HARDWARE_H
+#define __XTAVNET_HARDWARE_H
+
+#include <variant/core.h>
+
+/* Memory configuration. */
+
+#define PLATFORM_DEFAULT_MEM_START 0x00000000
+#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000
+
+/* Interrupt configuration. */
+
+#define PLATFORM_NR_IRQS 2
+
+/*
+ * Default assignment of XTAVnet devices to external interrupts.
+ *
+ * CONFIG_ARCH_HAS_SMP means the hardware supports SMP, ie. is Xtensa MX.
+ *
+ * Systems with SMP support (MX) have an External Interrupt Distributor
+ * between external interrupts and the core's interrupts. The first three
+ * core interrupts are used for IPI (interprocessor interrupts), so
+ * external (board device) interrupts end up shifted up by 3.
+ */
+
+/* UART interrupt: */
+#ifdef CONFIG_ARCH_HAS_SMP
+#define UART_INTNUM XCHAL_EXTINT3_NUM
+#else
+#define UART_INTNUM XCHAL_EXTINT0_NUM
+#endif
+
+/* Ethernet interrupt: */
+#ifdef CONFIG_ARCH_HAS_SMP
+#define OETH_IRQ XCHAL_EXTINT4_NUM
+#else
+#define OETH_IRQ XCHAL_EXTINT1_NUM
+#endif
+
+/*
+ * Device addresses and parameters.
+ */
+
+/* UART */
+#define UART_PADDR 0xFD050020
+
+/* LCD instruction and data virt. addresses. */
+#define LCD_INSTR_ADDR (char*)(0xFD040000)
+#define LCD_DATA_ADDR (char*)(0xFD040004)
+
+/* Misc. */
+#define XTAVNET_FPGAREGS_VADDR 0xFD020000
+/* Clock frequency in Hz (read-only): */
+#define XTAVNET_CLKFRQ_VADDR (XTAVNET_FPGAREGS_VADDR + 0x04)
+/* Setting of 8 DIP switches: */
+#define DIP_SWITCHES_VADDR (XTAVNET_FPGAREGS_VADDR + 0x0C)
+/* Software reset (write 0xdead): */
+#define XTAVNET_SWRST_VADDR (XTAVNET_FPGAREGS_VADDR + 0x10)
+
+/* OpenCores Ethernet controller: */
+#define OETH_REGS_PADDR IOADDR(0xD030000) /* regs + RX/TX descriptors */
+#define OETH_REGS_VADDR 0xFD030000
+#define OETH_REGS_SIZE 0x1000
+#define OETH_SRAMBUFF_PADDR 0xFD800000
+#define OETH_SRAMBUFF_SIZE (5*0x600 + 5*0x600) /* 5*rx buffs + 5*tx buffs */
+/*#define OETH_SRAMBUFF_SIZE 0x3C00*/ /* probably 0x4000 ? */
+/* The MAC address for these boards is 00:50:c2:13:6f:xx.
+ The last byte (here as zero) is read from the DIP switches on the board. */
+#define OETH_MACADDR 0x00, 0x50, 0xc2, 0x13, 0x6f, 0
+
+#endif /* __XTAVNET_HARDWARE_H */
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/lcd.h b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h
new file mode 100644
index 000000000000..67de96acb2f9
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h
@@ -0,0 +1,22 @@
+/*
+ * arch/xtensa/platforms/xtavnet/include/platform/lcd.h
+ *
+ * Copyright (C) 2001-2006 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __XTAVNET_LCD_H
+#define __XTAVNET_LCD_H
+
+/* Display string STR at position POS on the LCD. */
+void lcd_disp_at_pos(char *str, unsigned char pos);
+
+/* Shift the contents of the LCD display left or right. */
+void lcd_shiftleft(void);
+void lcd_shiftright(void);
+
+#endif
+
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/serial.h b/arch/xtensa/platforms/xtavnet/include/platform/serial.h
new file mode 100644
index 000000000000..a0cb0caff152
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/serial.h
@@ -0,0 +1 @@
+#include <asm-generic/serial.h>
diff --git a/arch/xtensa/platforms/xtavnet/lcd.c b/arch/xtensa/platforms/xtavnet/lcd.c
new file mode 100644
index 000000000000..283986f158ad
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/lcd.c
@@ -0,0 +1,79 @@
+/*
+ * Driver for the LCD display on the Tensilica LX60 Board.
+ * This code has no effect on the LX200 board. (LX110: TBD)
+ *
+ * Copyright (C) 2001-2006 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ *
+ * FIXME: this code is from the examples from the LX60 user guide.
+ *
+ * The lcd_pause function does busy waiting, which is probably not
+ * great. Maybe the code could be changed to use kernel timers, or
+ * change the hardware to not need to wait.
+ */
+
+#include <linux/init.h>
+
+#include <platform/hardware.h>
+#include <asm/processor.h>
+#include <platform/lcd.h>
+#include <linux/delay.h>
+
+#define LCD_PAUSE_ITERATIONS 4000
+#define LCD_CLEAR 0x1
+#define LCD_DISPLAY_ON 0xc
+
+/* 8bit and 2 lines display */
+#define LCD_DISPLAY_MODE8BIT 0x38
+#define LCD_DISPLAY_POS 0x80
+#define LCD_SHIFT_LEFT 0x18
+#define LCD_SHIFT_RIGHT 0x1c
+
+static int __init lcd_init(void)
+{
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ mdelay(5);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ udelay(200);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ udelay(50);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_ON;
+ udelay(50);
+ *LCD_INSTR_ADDR = LCD_CLEAR;
+ mdelay(10);
+ lcd_disp_at_pos("XTENSA LINUX", 0);
+
+ return 0;
+}
+
+void lcd_disp_at_pos (char *str, unsigned char pos)
+{
+ *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos;
+ udelay(100);
+ while (*str != 0){
+ *LCD_DATA_ADDR = *str;
+ udelay(200);
+ str++;
+ }
+}
+
+void lcd_shiftleft(void)
+{
+ *LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
+ udelay(50);
+}
+
+void lcd_shiftright(void)
+{
+ *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
+ udelay(50);
+}
+
+arch_initcall(lcd_init);
+
diff --git a/arch/xtensa/platforms/xtavnet/setup.c b/arch/xtensa/platforms/xtavnet/setup.c
new file mode 100644
index 000000000000..256fcb2b2af4
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/setup.c
@@ -0,0 +1,269 @@
+/*
+ * arch/xtensa/platform-xtavnet/setup.c
+ *
+ * Setup/initialization for Tensilica Avnet boards (XT-AV60, XT-AV110, XT-AV200,
+ * derived from Avnet LX60, LX110, LX200 boards respectively).
+ * For details, see "Tensilica Avnet LX### (XT-AV###) Board User's Guide"
+ * (where ### is 60, 110, or 200).
+ *
+ * Authors: Chris Zankel <chris@zankel.net>
+ * Joe Taylor <joe@tensilica.com>
+ * Pete Delaney <piet@tensilica.com>
+ * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ *
+ * Copyright 2001-2010 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License, version 2. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/stringify.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <asm/timex.h>
+
+#include <linux/etherdevice.h>
+#include <net/ethoc.h>
+
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/bootparam.h>
+#include <platform/lcd.h>
+#include <platform/hardware.h>
+#include <variant/core.h>
+
+/* For doing extra init. beyond what the ethoc driver does. */
+struct oeth_regs {
+ unsigned moder; /* Mode Register */
+ unsigned int_src; /* Interrupt Source Register */
+ unsigned int_mask; /* Interrupt Mask Register */
+ unsigned ipgt; /* Back to Bak Inter Packet Gap Register */
+ unsigned ipgr1; /* Non Back to Back Inter Packet Gap Register 1 */
+ unsigned ipgr2; /* Non Back to Back Inter Packet Gap Register 2 */
+ unsigned packet_len; /* Packet Length Register (min. and max.) */
+ unsigned collconf; /* Collision and Retry Configuration Register */
+ unsigned tx_bd_num; /* Transmit Buffer Descriptor Number Register */
+ unsigned ctrlmoder; /* Control Module Mode Register */
+ unsigned miimoder; /* MII Mode Register */
+ unsigned miicommand; /* MII Command Register */
+ unsigned miiaddress; /* MII Address Register */
+ unsigned miitx_data; /* MII Transmit Data Register */
+ unsigned miirx_data; /* MII Receive Data Register */
+ unsigned miistatus; /* MII Status Register */
+ unsigned mac_addr0; /* MAC Individual Address Register 0 */
+ unsigned mac_addr1; /* MAC Individual Address Register 1 */
+ unsigned hash_addr0; /* Hash Register 0 */
+ unsigned hash_addr1; /* Hash Register 1 */
+};
+/* MODER Register */
+#define OETH_MODER_RST 0x00000800 /* Reset MAC */
+/* MII Mode Register */
+#define OETH_MIIMODER_CLKDIV 0x000000FF /* Clock Divider */
+
+
+
+void platform_halt(void)
+{
+ /* Just display HALT on LCD display, and loop. */
+ lcd_disp_at_pos(" HALT ", 0);
+ local_irq_disable();
+ while (1);
+}
+
+void platform_power_off(void)
+{
+ /* No software-controlled power-off, just display POWEROFF and loop. */
+ lcd_disp_at_pos ("POWEROFF", 0);
+ local_irq_disable();
+ while (1);
+}
+
+void platform_restart(void)
+{
+ /* Software-initiated board reset. */
+ *(volatile unsigned *)XTAVNET_SWRST_VADDR = 0xdead;
+}
+
+void platform_heartbeat(void)
+{
+ /* Executes every timer tick. */
+}
+
+
+/*
+ * Called from time_init(). "Calibrating" is a misnomer, here we just read
+ * the clock rate from the board specific FPGA registers.
+ */
+void platform_calibrate_ccount(void)
+{
+ long clk_freq = *(long *)XTAVNET_CLKFRQ_VADDR;
+
+ ccount_per_jiffy = clk_freq / HZ;
+ nsec_per_ccount = 1000000000UL / clk_freq;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Ethernet -- OpenCores Ethernet MAC (ethoc driver)
+ */
+
+static struct resource ethoc_res[] = {
+ [0] = { /* register space */
+ .start = OETH_REGS_PADDR,
+ .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* buffer space */
+ .start = OETH_SRAMBUFF_PADDR,
+ .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ number */
+ .start = OETH_IRQ,
+ .end = OETH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ethoc_platform_data ethoc_pdata = {
+ .hwaddr = { OETH_MACADDR }, /* last byte written in setup below */
+ .phy_id = -1,
+};
+
+static struct platform_device ethoc_device = {
+ .name = "ethoc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ethoc_res),
+ .resource = ethoc_res,
+ .dev = {
+ .platform_data = &ethoc_pdata,
+ },
+};
+
+
+/*----------------------------------------------------------------------------
+ * UART
+ */
+
+static struct resource serial_resource = {
+ .start = UART_PADDR,
+ .end = UART_PADDR + 0x1f,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ [0] = {
+ .mapbase = UART_PADDR,
+ .irq = UART_INTNUM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ .uartclk = 0, /* set in xtavnet_init() */
+ },
+ { },
+};
+
+static struct platform_device xtavnet_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = 1,
+ .resource = &serial_resource,
+};
+
+
+/*----------------------------------------------------------------------------
+ */
+
+/* platform devices */
+static struct platform_device *platform_devices[] = {
+ &ethoc_device,
+ &xtavnet_uart,
+};
+
+
+
+/* very early init */
+void __init platform_setup(char **cmdline)
+{
+ if (cmdline) {
+ if (cmdline[0])
+ printk("XTAVnet: platform_setup(cmdline[0]:'%s')\n", cmdline[0]);
+ else
+ printk("XTAVnet: platform_setup(cmdline[0]:<null>)\n");
+ }
+}
+
+/* early initialization, before secondary cpu's have been brought up */
+
+void platform_init(bp_tag_t *bootparams)
+{
+ printk("\n");
+ if( bootparams )
+ printk("XTAVnet: platform_init(bootparams:0x%x)\n", (unsigned)bootparams);
+}
+
+static int xtavnet_init(void)
+{
+ volatile struct oeth_regs *regs = (volatile struct oeth_regs*)OETH_REGS_VADDR;
+
+ /*
+ * Do some of the initialization missing in the ETHOC driver.
+ * (Perhaps not all necessary, but was in a previously used driver.)
+ */
+
+ /* Reset the controller. */
+ regs->moder = OETH_MODER_RST; /* Reset ON */
+ regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
+
+ regs->packet_len = (64 << 16) | 1536;
+ regs->ipgr1 = 0x0000000c;
+ regs->ipgr2 = 0x00000012;
+ regs->collconf = 0x000f003f;
+ regs->ctrlmoder = 0;
+ regs->miimoder = (OETH_MIIMODER_CLKDIV & 0x2);
+
+ /*
+ * Setup dynamic info in platform device init structures.
+ */
+
+ /* Ethernet MAC address. */
+ ethoc_pdata.hwaddr[5] = *(u32*)DIP_SWITCHES_VADDR;
+
+ /* Clock rate varies among FPGA bitstreams; board specific FPGA register
+ * reports the actual clock rate. */
+ serial_platform_data[0].uartclk = *(long *)XTAVNET_CLKFRQ_VADDR;
+
+
+ /* register platform devices */
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user
+ knows whether they set it correctly on the DIP switches. */
+ printk("XTAVnet: Ethernet MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ethoc_pdata.hwaddr[0], ethoc_pdata.hwaddr[1], ethoc_pdata.hwaddr[2],
+ ethoc_pdata.hwaddr[3], ethoc_pdata.hwaddr[4], ethoc_pdata.hwaddr[5]);
+
+ return 0;
+}
+
+
+/*
+ * Register to be done during do_initcalls().
+ */
+arch_initcall(xtavnet_init);
+
+
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index b1febd0f6d2a..455768a3eb9e 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1452,10 +1452,6 @@ blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
goto done;
}
- /* Currently we do not support hierarchy deeper than two level (0,1) */
- if (parent != cgroup->top_cgroup)
- return ERR_PTR(-EPERM);
-
blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
if (!blkcg)
return ERR_PTR(-ENOMEM);
diff --git a/block/blk-core.c b/block/blk-core.c
index 4ce953f1b390..3689319a5974 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -33,7 +33,7 @@
#include "blk.h"
-EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
@@ -1329,9 +1329,9 @@ static inline void blk_partition_remap(struct bio *bio)
bio->bi_sector += p->start_sect;
bio->bi_bdev = bdev->bd_contains;
- trace_block_remap(bdev_get_queue(bio->bi_bdev), bio,
- bdev->bd_dev,
- bio->bi_sector - p->start_sect);
+ trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), bio,
+ bdev->bd_dev,
+ bio->bi_sector - p->start_sect);
}
}
@@ -1500,7 +1500,7 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
if (old_sector != -1)
- trace_block_remap(q, bio, old_dev, old_sector);
+ trace_block_bio_remap(q, bio, old_dev, old_sector);
old_sector = bio->bi_sector;
old_dev = bio->bi_bdev->bd_dev;
@@ -2606,7 +2606,9 @@ int __init blk_dev_init(void)
BUILD_BUG_ON(__REQ_NR_BITS > 8 *
sizeof(((struct request *)0)->cmd_flags));
- kblockd_workqueue = create_workqueue("kblockd");
+ /* used for unplugging and affects IO latency/throughput - HIGHPRI */
+ kblockd_workqueue = alloc_workqueue("kblockd",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
if (!kblockd_workqueue)
panic("Failed to create kblockd\n");
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 3c7a339fe381..b791022beef3 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -64,7 +64,7 @@ static void cfq_exit(struct io_context *ioc)
rcu_read_unlock();
}
-/* Called by the exitting task */
+/* Called by the exiting task */
void exit_io_context(struct task_struct *task)
{
struct io_context *ioc;
@@ -74,10 +74,9 @@ void exit_io_context(struct task_struct *task)
task->io_context = NULL;
task_unlock(task);
- if (atomic_dec_and_test(&ioc->nr_tasks)) {
+ if (atomic_dec_and_test(&ioc->nr_tasks))
cfq_exit(ioc);
- }
put_io_context(ioc);
}
diff --git a/block/blk-map.c b/block/blk-map.c
index 5d5dbe47c228..e663ac2d8e68 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
for (i = 0; i < iov_count; i++) {
unsigned long uaddr = (unsigned long)iov[i].iov_base;
+ if (!iov[i].iov_len)
+ return -EINVAL;
+
if (uaddr & queue_dma_alignment(q)) {
unaligned = 1;
break;
}
- if (!iov[i].iov_len)
- return -EINVAL;
}
if (unaligned || (q->dma_pad_mask & len) || map_data)
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 77b7c26df6b5..74bc4a768f32 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
return 0;
fbio = bio;
- cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+ cluster = blk_queue_cluster(q);
seg_size = 0;
nr_phys_segs = 0;
for_each_bio(bio) {
@@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments);
static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
struct bio *nxt)
{
- if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+ if (!blk_queue_cluster(q))
return 0;
if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
@@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
int nsegs, cluster;
nsegs = 0;
- cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+ cluster = blk_queue_cluster(q);
/*
* for each bio in rq
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 701859fb9647..36c8c1f2af18 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->alignment_offset = 0;
lim->io_opt = 0;
lim->misaligned = 0;
- lim->no_cluster = 0;
+ lim->cluster = 1;
}
EXPORT_SYMBOL(blk_set_default_limits);
@@ -229,8 +229,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
EXPORT_SYMBOL(blk_queue_bounce_limit);
/**
- * blk_queue_max_hw_sectors - set max sectors for a request for this queue
- * @q: the request queue for the device
+ * blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request
+ * @limits: the queue limits
* @max_hw_sectors: max hardware sectors in the usual 512b unit
*
* Description:
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
* per-device basis in /sys/block/<device>/queue/max_sectors_kb.
* The soft limit can not exceed max_hw_sectors.
**/
-void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
+void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors)
{
if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
@@ -252,9 +252,23 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto
__func__, max_hw_sectors);
}
- q->limits.max_hw_sectors = max_hw_sectors;
- q->limits.max_sectors = min_t(unsigned int, max_hw_sectors,
- BLK_DEF_MAX_SECTORS);
+ limits->max_hw_sectors = max_hw_sectors;
+ limits->max_sectors = min_t(unsigned int, max_hw_sectors,
+ BLK_DEF_MAX_SECTORS);
+}
+EXPORT_SYMBOL(blk_limits_max_hw_sectors);
+
+/**
+ * blk_queue_max_hw_sectors - set max sectors for a request for this queue
+ * @q: the request queue for the device
+ * @max_hw_sectors: max hardware sectors in the usual 512b unit
+ *
+ * Description:
+ * See description for blk_limits_max_hw_sectors().
+ **/
+void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
+{
+ blk_limits_max_hw_sectors(&q->limits, max_hw_sectors);
}
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
@@ -464,15 +478,6 @@ EXPORT_SYMBOL(blk_queue_io_opt);
void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
{
blk_stack_limits(&t->limits, &b->limits, 0);
-
- if (!t->queue_lock)
- WARN_ON_ONCE(1);
- else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
- unsigned long flags;
- spin_lock_irqsave(t->queue_lock, flags);
- queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
- spin_unlock_irqrestore(t->queue_lock, flags);
- }
}
EXPORT_SYMBOL(blk_queue_stack_limits);
@@ -545,7 +550,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
t->io_min = max(t->io_min, b->io_min);
t->io_opt = lcm(t->io_opt, b->io_opt);
- t->no_cluster |= b->no_cluster;
+ t->cluster &= b->cluster;
t->discard_zeroes_data &= b->discard_zeroes_data;
/* Physical block size a multiple of the logical block size? */
@@ -641,7 +646,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
sector_t offset)
{
struct request_queue *t = disk->queue;
- struct request_queue *b = bdev_get_queue(bdev);
if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
@@ -652,17 +656,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
top, bottom);
}
-
- if (!t->queue_lock)
- WARN_ON_ONCE(1);
- else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
- unsigned long flags;
-
- spin_lock_irqsave(t->queue_lock, flags);
- if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
- queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
- spin_unlock_irqrestore(t->queue_lock, flags);
- }
}
EXPORT_SYMBOL(disk_stack_limits);
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 013457f47fdc..41fb69150b4d 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *
static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
{
- if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+ if (blk_queue_cluster(q))
return queue_var_show(queue_max_segment_size(q), (page));
return queue_var_show(PAGE_CACHE_SIZE, (page));
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 004be80fd894..381b09bb562b 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -355,6 +355,12 @@ throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
tg->slice_end[rw], jiffies);
}
+static inline void throtl_set_slice_end(struct throtl_data *td,
+ struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
+{
+ tg->slice_end[rw] = roundup(jiffy_end, throtl_slice);
+}
+
static inline void throtl_extend_slice(struct throtl_data *td,
struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
{
@@ -391,6 +397,16 @@ throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
if (throtl_slice_used(td, tg, rw))
return;
+ /*
+ * A bio has been dispatched. Also adjust slice_end. It might happen
+ * that initially cgroup limit was very low resulting in high
+ * slice_end, but later limit was bumped up and bio was dispached
+ * sooner, then we need to reduce slice_end. A high bogus slice_end
+ * is bad because it does not allow new slice to start.
+ */
+
+ throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice);
+
time_elapsed = jiffies - tg->slice_start[rw];
nr_slices = time_elapsed / throtl_slice;
@@ -709,26 +725,21 @@ static void throtl_process_limit_change(struct throtl_data *td)
struct throtl_grp *tg;
struct hlist_node *pos, *n;
- /*
- * Make sure atomic_inc() effects from
- * throtl_update_blkio_group_read_bps(), group of functions are
- * visible.
- * Is this required or smp_mb__after_atomic_inc() was suffcient
- * after the atomic_inc().
- */
- smp_rmb();
if (!atomic_read(&td->limits_changed))
return;
throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed));
- hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
- /*
- * Do I need an smp_rmb() here to make sure tg->limits_changed
- * update is visible. I am relying on smp_rmb() at the
- * beginning of function and not putting a new one here.
- */
+ /*
+ * Make sure updates from throtl_update_blkio_group_read_bps() group
+ * of functions to tg->limits_changed are visible. We do not
+ * want update td->limits_changed to be visible but update to
+ * tg->limits_changed not being visible yet on this cpu. Hence
+ * the read barrier.
+ */
+ smp_rmb();
+ hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
if (throtl_tg_on_rr(tg) && tg->limits_changed) {
throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu"
" riops=%u wiops=%u", tg->bps[READ],
diff --git a/block/bsg.c b/block/bsg.c
index f20d6a789d48..0c8b64a16484 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
int ret, rw;
unsigned int dxfer_len;
void *dxferp = NULL;
+ struct bsg_class_device *bcd = &q->bsg_dev;
+
+ /* if the LLD has been removed then the bsg_unregister_queue will
+ * eventually be called and the class_dev was freed, so we can no
+ * longer use this request_queue. Return no such address.
+ */
+ if (!bcd->class_dev)
+ return ERR_PTR(-ENXIO);
dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp,
hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 4cd59b0d7c15..c19d015ac5a5 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -87,7 +87,6 @@ struct cfq_rb_root {
unsigned count;
unsigned total_weight;
u64 min_vdisktime;
- struct rb_node *active;
};
#define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT, .left = NULL, \
.count = 0, .min_vdisktime = 0, }
@@ -180,7 +179,6 @@ struct cfq_group {
/* group service_tree key */
u64 vdisktime;
unsigned int weight;
- bool on_st;
/* number of cfqq currently on this group */
int nr_cfqq;
@@ -563,11 +561,6 @@ static void update_min_vdisktime(struct cfq_rb_root *st)
u64 vdisktime = st->min_vdisktime;
struct cfq_group *cfqg;
- if (st->active) {
- cfqg = rb_entry_cfqg(st->active);
- vdisktime = cfqg->vdisktime;
- }
-
if (st->left) {
cfqg = rb_entry_cfqg(st->left);
vdisktime = min_vdisktime(vdisktime, cfqg->vdisktime);
@@ -646,11 +639,11 @@ cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
static inline bool cfq_slice_used(struct cfq_queue *cfqq)
{
if (cfq_cfqq_slice_new(cfqq))
- return 0;
+ return false;
if (time_before(jiffies, cfqq->slice_end))
- return 0;
+ return false;
- return 1;
+ return true;
}
/*
@@ -869,7 +862,7 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
struct rb_node *n;
cfqg->nr_cfqq++;
- if (cfqg->on_st)
+ if (!RB_EMPTY_NODE(&cfqg->rb_node))
return;
/*
@@ -885,7 +878,6 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
cfqg->vdisktime = st->min_vdisktime;
__cfq_group_service_tree_add(st, cfqg);
- cfqg->on_st = true;
st->total_weight += cfqg->weight;
}
@@ -894,9 +886,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg)
{
struct cfq_rb_root *st = &cfqd->grp_service_tree;
- if (st->active == &cfqg->rb_node)
- st->active = NULL;
-
BUG_ON(cfqg->nr_cfqq < 1);
cfqg->nr_cfqq--;
@@ -905,7 +894,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg)
return;
cfq_log_cfqg(cfqd, cfqg, "del_from_rr group");
- cfqg->on_st = false;
st->total_weight -= cfqg->weight;
if (!RB_EMPTY_NODE(&cfqg->rb_node))
cfq_rb_erase(&cfqg->rb_node, st);
@@ -1095,7 +1083,7 @@ static void cfq_put_cfqg(struct cfq_group *cfqg)
if (!atomic_dec_and_test(&cfqg->ref))
return;
for_each_cfqg_st(cfqg, i, j, st)
- BUG_ON(!RB_EMPTY_ROOT(&st->rb) || st->active != NULL);
+ BUG_ON(!RB_EMPTY_ROOT(&st->rb));
kfree(cfqg);
}
@@ -1687,9 +1675,6 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cfqq == cfqd->active_queue)
cfqd->active_queue = NULL;
- if (&cfqq->cfqg->rb_node == cfqd->grp_service_tree.active)
- cfqd->grp_service_tree.active = NULL;
-
if (cfqd->active_cic) {
put_io_context(cfqd->active_cic->ioc);
cfqd->active_cic = NULL;
@@ -1901,10 +1886,10 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
* in their service tree.
*/
if (service_tree->count == 1 && cfq_cfqq_sync(cfqq))
- return 1;
+ return true;
cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
service_tree->count);
- return 0;
+ return false;
}
static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -2116,12 +2101,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
unsigned count;
struct cfq_rb_root *st;
unsigned group_slice;
-
- if (!cfqg) {
- cfqd->serving_prio = IDLE_WORKLOAD;
- cfqd->workload_expires = jiffies + 1;
- return;
- }
+ enum wl_prio_t original_prio = cfqd->serving_prio;
/* Choose next priority. RT > BE > IDLE */
if (cfq_group_busy_queues_wl(RT_WORKLOAD, cfqd, cfqg))
@@ -2134,6 +2114,9 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
return;
}
+ if (original_prio != cfqd->serving_prio)
+ goto new_workload;
+
/*
* For RT and BE, we have to choose also the type
* (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload
@@ -2148,6 +2131,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
if (count && !time_after(jiffies, cfqd->workload_expires))
return;
+new_workload:
/* otherwise select new workload type */
cfqd->serving_type =
cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio);
@@ -2199,7 +2183,6 @@ static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd)
if (RB_EMPTY_ROOT(&st->rb))
return NULL;
cfqg = cfq_rb_first_group(st);
- st->active = &cfqg->rb_node;
update_min_vdisktime(st);
return cfqg;
}
@@ -2293,6 +2276,17 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
goto keep_queue;
}
+ /*
+ * This is a deep seek queue, but the device is much faster than
+ * the queue can deliver, don't idle
+ **/
+ if (CFQQ_SEEKY(cfqq) && cfq_cfqq_idle_window(cfqq) &&
+ (cfq_cfqq_slice_new(cfqq) ||
+ (cfqq->slice_end - jiffies > jiffies - cfqq->slice_start))) {
+ cfq_clear_cfqq_deep(cfqq);
+ cfq_clear_cfqq_idle_window(cfqq);
+ }
+
if (cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) {
cfqq = NULL;
goto keep_queue;
@@ -2367,12 +2361,12 @@ static inline bool cfq_slice_used_soon(struct cfq_data *cfqd,
{
/* the queue hasn't finished any request, can't estimate */
if (cfq_cfqq_slice_new(cfqq))
- return 1;
+ return true;
if (time_after(jiffies + cfqd->cfq_slice_idle * cfqq->dispatched,
cfqq->slice_end))
- return 1;
+ return true;
- return 0;
+ return false;
}
static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -3265,6 +3259,10 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq))
return true;
+ /* An idle queue should not be idle now for some reason */
+ if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq))
+ return true;
+
if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq))
return false;
diff --git a/block/genhd.c b/block/genhd.c
index 5fa2b44a72ff..743317381632 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -18,6 +18,7 @@
#include <linux/buffer_head.h>
#include <linux/mutex.h>
#include <linux/idr.h>
+#include <linux/log2.h>
#include "blk.h"
@@ -35,6 +36,10 @@ static DEFINE_IDR(ext_devt_idr);
static struct device_type disk_type;
+static void disk_add_events(struct gendisk *disk);
+static void disk_del_events(struct gendisk *disk);
+static void disk_release_events(struct gendisk *disk);
+
/**
* disk_get_part - get partition
* @disk: disk to look partition from
@@ -239,7 +244,7 @@ static struct blk_major_name {
} *major_names[BLKDEV_MAJOR_HASH_SIZE];
/* index in the above - for now: assume no multimajor ranges */
-static inline int major_to_index(int major)
+static inline int major_to_index(unsigned major)
{
return major % BLKDEV_MAJOR_HASH_SIZE;
}
@@ -502,6 +507,64 @@ static int exact_lock(dev_t devt, void *data)
return 0;
}
+void register_disk(struct gendisk *disk)
+{
+ struct device *ddev = disk_to_dev(disk);
+ struct block_device *bdev;
+ struct disk_part_iter piter;
+ struct hd_struct *part;
+ int err;
+
+ ddev->parent = disk->driverfs_dev;
+
+ dev_set_name(ddev, disk->disk_name);
+
+ /* delay uevents, until we scanned partition table */
+ dev_set_uevent_suppress(ddev, 1);
+
+ if (device_add(ddev))
+ return;
+ if (!sysfs_deprecated) {
+ err = sysfs_create_link(block_depr, &ddev->kobj,
+ kobject_name(&ddev->kobj));
+ if (err) {
+ device_del(ddev);
+ return;
+ }
+ }
+ disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
+ disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
+
+ /* No minors to use for partitions */
+ if (!disk_partitionable(disk))
+ goto exit;
+
+ /* No such device (e.g., media were just removed) */
+ if (!get_capacity(disk))
+ goto exit;
+
+ bdev = bdget_disk(disk, 0);
+ if (!bdev)
+ goto exit;
+
+ bdev->bd_invalidated = 1;
+ err = blkdev_get(bdev, FMODE_READ, NULL);
+ if (err < 0)
+ goto exit;
+ blkdev_put(bdev, FMODE_READ);
+
+exit:
+ /* announce disk after possible partitions are created */
+ dev_set_uevent_suppress(ddev, 0);
+ kobject_uevent(&ddev->kobj, KOBJ_ADD);
+
+ /* announce possible partitions */
+ disk_part_iter_init(&piter, disk, 0);
+ while ((part = disk_part_iter_next(&piter)))
+ kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
+ disk_part_iter_exit(&piter);
+}
+
/**
* add_disk - add partitioning information to kernel list
* @disk: per-device partitioning information
@@ -551,18 +614,48 @@ void add_disk(struct gendisk *disk)
retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
"bdi");
WARN_ON(retval);
-}
+ disk_add_events(disk);
+}
EXPORT_SYMBOL(add_disk);
-EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */
-void unlink_gendisk(struct gendisk *disk)
+void del_gendisk(struct gendisk *disk)
{
+ struct disk_part_iter piter;
+ struct hd_struct *part;
+
+ disk_del_events(disk);
+
+ /* invalidate stuff */
+ disk_part_iter_init(&piter, disk,
+ DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
+ while ((part = disk_part_iter_next(&piter))) {
+ invalidate_partition(disk, part->partno);
+ delete_partition(disk, part->partno);
+ }
+ disk_part_iter_exit(&piter);
+
+ invalidate_partition(disk, 0);
+ blk_free_devt(disk_to_dev(disk)->devt);
+ set_capacity(disk, 0);
+ disk->flags &= ~GENHD_FL_UP;
+
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
bdi_unregister(&disk->queue->backing_dev_info);
blk_unregister_queue(disk);
blk_unregister_region(disk_devt(disk), disk->minors);
+
+ part_stat_set_all(&disk->part0, 0);
+ disk->part0.stamp = 0;
+
+ kobject_put(disk->part0.holder_dir);
+ kobject_put(disk->slave_dir);
+ disk->driverfs_dev = NULL;
+ if (!sysfs_deprecated)
+ sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
+ device_del(disk_to_dev(disk));
}
+EXPORT_SYMBOL(del_gendisk);
/**
* get_gendisk - get partitioning information for a given device
@@ -735,7 +828,7 @@ static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
static void *p;
p = disk_seqf_start(seqf, pos);
- if (!IS_ERR(p) && p && !*pos)
+ if (!IS_ERR_OR_NULL(p) && !*pos)
seq_puts(seqf, "major minor #blocks name\n\n");
return p;
}
@@ -1005,6 +1098,7 @@ static void disk_release(struct device *dev)
{
struct gendisk *disk = dev_to_disk(dev);
+ disk_release_events(disk);
kfree(disk->random);
disk_replace_part_tbl(disk, NULL);
free_part_stats(&disk->part0);
@@ -1110,29 +1204,6 @@ static int __init proc_genhd_init(void)
module_init(proc_genhd_init);
#endif /* CONFIG_PROC_FS */
-static void media_change_notify_thread(struct work_struct *work)
-{
- struct gendisk *gd = container_of(work, struct gendisk, async_notify);
- char event[] = "MEDIA_CHANGE=1";
- char *envp[] = { event, NULL };
-
- /*
- * set enviroment vars to indicate which event this is for
- * so that user space will know to go check the media status.
- */
- kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
- put_device(gd->driverfs_dev);
-}
-
-#if 0
-void genhd_media_change_notify(struct gendisk *disk)
-{
- get_device(disk->driverfs_dev);
- schedule_work(&disk->async_notify);
-}
-EXPORT_SYMBOL_GPL(genhd_media_change_notify);
-#endif /* 0 */
-
dev_t blk_lookup_devt(const char *name, int partno)
{
dev_t devt = MKDEV(0, 0);
@@ -1198,8 +1269,6 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
disk_to_dev(disk)->class = &block_class;
disk_to_dev(disk)->type = &disk_type;
device_initialize(disk_to_dev(disk));
- INIT_WORK(&disk->async_notify,
- media_change_notify_thread);
}
return disk;
}
@@ -1291,3 +1360,422 @@ int invalidate_partition(struct gendisk *disk, int partno)
}
EXPORT_SYMBOL(invalidate_partition);
+
+/*
+ * Disk events - monitor disk events like media change and eject request.
+ */
+struct disk_events {
+ struct list_head node; /* all disk_event's */
+ struct gendisk *disk; /* the associated disk */
+ spinlock_t lock;
+
+ int block; /* event blocking depth */
+ unsigned int pending; /* events already sent out */
+ unsigned int clearing; /* events being cleared */
+
+ long poll_msecs; /* interval, -1 for default */
+ struct delayed_work dwork;
+};
+
+static const char *disk_events_strs[] = {
+ [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "media_change",
+ [ilog2(DISK_EVENT_EJECT_REQUEST)] = "eject_request",
+};
+
+static char *disk_uevents[] = {
+ [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "DISK_MEDIA_CHANGE=1",
+ [ilog2(DISK_EVENT_EJECT_REQUEST)] = "DISK_EJECT_REQUEST=1",
+};
+
+/* list of all disk_events */
+static DEFINE_MUTEX(disk_events_mutex);
+static LIST_HEAD(disk_events);
+
+/* disable in-kernel polling by default */
+static unsigned long disk_events_dfl_poll_msecs = 0;
+
+static unsigned long disk_events_poll_jiffies(struct gendisk *disk)
+{
+ struct disk_events *ev = disk->ev;
+ long intv_msecs = 0;
+
+ /*
+ * If device-specific poll interval is set, always use it. If
+ * the default is being used, poll iff there are events which
+ * can't be monitored asynchronously.
+ */
+ if (ev->poll_msecs >= 0)
+ intv_msecs = ev->poll_msecs;
+ else if (disk->events & ~disk->async_events)
+ intv_msecs = disk_events_dfl_poll_msecs;
+
+ return msecs_to_jiffies(intv_msecs);
+}
+
+static void __disk_block_events(struct gendisk *disk, bool sync)
+{
+ struct disk_events *ev = disk->ev;
+ unsigned long flags;
+ bool cancel;
+
+ spin_lock_irqsave(&ev->lock, flags);
+ cancel = !ev->block++;
+ spin_unlock_irqrestore(&ev->lock, flags);
+
+ if (cancel) {
+ if (sync)
+ cancel_delayed_work_sync(&disk->ev->dwork);
+ else
+ cancel_delayed_work(&disk->ev->dwork);
+ }
+}
+
+static void __disk_unblock_events(struct gendisk *disk, bool check_now)
+{
+ struct disk_events *ev = disk->ev;
+ unsigned long intv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ev->lock, flags);
+
+ if (WARN_ON_ONCE(ev->block <= 0))
+ goto out_unlock;
+
+ if (--ev->block)
+ goto out_unlock;
+
+ /*
+ * Not exactly a latency critical operation, set poll timer
+ * slack to 25% and kick event check.
+ */
+ intv = disk_events_poll_jiffies(disk);
+ set_timer_slack(&ev->dwork.timer, intv / 4);
+ if (check_now)
+ queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
+ else if (intv)
+ queue_delayed_work(system_nrt_wq, &ev->dwork, intv);
+out_unlock:
+ spin_unlock_irqrestore(&ev->lock, flags);
+}
+
+/**
+ * disk_block_events - block and flush disk event checking
+ * @disk: disk to block events for
+ *
+ * On return from this function, it is guaranteed that event checking
+ * isn't in progress and won't happen until unblocked by
+ * disk_unblock_events(). Events blocking is counted and the actual
+ * unblocking happens after the matching number of unblocks are done.
+ *
+ * Note that this intentionally does not block event checking from
+ * disk_clear_events().
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+void disk_block_events(struct gendisk *disk)
+{
+ if (disk->ev)
+ __disk_block_events(disk, true);
+}
+
+/**
+ * disk_unblock_events - unblock disk event checking
+ * @disk: disk to unblock events for
+ *
+ * Undo disk_block_events(). When the block count reaches zero, it
+ * starts events polling if configured.
+ *
+ * CONTEXT:
+ * Don't care. Safe to call from irq context.
+ */
+void disk_unblock_events(struct gendisk *disk)
+{
+ if (disk->ev)
+ __disk_unblock_events(disk, true);
+}
+
+/**
+ * disk_check_events - schedule immediate event checking
+ * @disk: disk to check events for
+ *
+ * Schedule immediate event checking on @disk if not blocked.
+ *
+ * CONTEXT:
+ * Don't care. Safe to call from irq context.
+ */
+void disk_check_events(struct gendisk *disk)
+{
+ if (disk->ev) {
+ __disk_block_events(disk, false);
+ __disk_unblock_events(disk, true);
+ }
+}
+EXPORT_SYMBOL_GPL(disk_check_events);
+
+/**
+ * disk_clear_events - synchronously check, clear and return pending events
+ * @disk: disk to fetch and clear events from
+ * @mask: mask of events to be fetched and clearted
+ *
+ * Disk events are synchronously checked and pending events in @mask
+ * are cleared and returned. This ignores the block count.
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
+{
+ const struct block_device_operations *bdops = disk->fops;
+ struct disk_events *ev = disk->ev;
+ unsigned int pending;
+
+ if (!ev) {
+ /* for drivers still using the old ->media_changed method */
+ if ((mask & DISK_EVENT_MEDIA_CHANGE) &&
+ bdops->media_changed && bdops->media_changed(disk))
+ return DISK_EVENT_MEDIA_CHANGE;
+ return 0;
+ }
+
+ /* tell the workfn about the events being cleared */
+ spin_lock_irq(&ev->lock);
+ ev->clearing |= mask;
+ spin_unlock_irq(&ev->lock);
+
+ /* uncondtionally schedule event check and wait for it to finish */
+ __disk_block_events(disk, true);
+ queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
+ flush_delayed_work(&ev->dwork);
+ __disk_unblock_events(disk, false);
+
+ /* then, fetch and clear pending events */
+ spin_lock_irq(&ev->lock);
+ WARN_ON_ONCE(ev->clearing & mask); /* cleared by workfn */
+ pending = ev->pending & mask;
+ ev->pending &= ~mask;
+ spin_unlock_irq(&ev->lock);
+
+ return pending;
+}
+
+static void disk_events_workfn(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct disk_events *ev = container_of(dwork, struct disk_events, dwork);
+ struct gendisk *disk = ev->disk;
+ char *envp[ARRAY_SIZE(disk_uevents) + 1] = { };
+ unsigned int clearing = ev->clearing;
+ unsigned int events;
+ unsigned long intv;
+ int nr_events = 0, i;
+
+ /* check events */
+ events = disk->fops->check_events(disk, clearing);
+
+ /* accumulate pending events and schedule next poll if necessary */
+ spin_lock_irq(&ev->lock);
+
+ events &= ~ev->pending;
+ ev->pending |= events;
+ ev->clearing &= ~clearing;
+
+ intv = disk_events_poll_jiffies(disk);
+ if (!ev->block && intv)
+ queue_delayed_work(system_nrt_wq, &ev->dwork, intv);
+
+ spin_unlock_irq(&ev->lock);
+
+ /* tell userland about new events */
+ for (i = 0; i < ARRAY_SIZE(disk_uevents); i++)
+ if (events & (1 << i))
+ envp[nr_events++] = disk_uevents[i];
+
+ if (nr_events)
+ kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp);
+}
+
+/*
+ * A disk events enabled device has the following sysfs nodes under
+ * its /sys/block/X/ directory.
+ *
+ * events : list of all supported events
+ * events_async : list of events which can be detected w/o polling
+ * events_poll_msecs : polling interval, 0: disable, -1: system default
+ */
+static ssize_t __disk_events_show(unsigned int events, char *buf)
+{
+ const char *delim = "";
+ ssize_t pos = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(disk_events_strs); i++)
+ if (events & (1 << i)) {
+ pos += sprintf(buf + pos, "%s%s",
+ delim, disk_events_strs[i]);
+ delim = " ";
+ }
+ if (pos)
+ pos += sprintf(buf + pos, "\n");
+ return pos;
+}
+
+static ssize_t disk_events_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return __disk_events_show(disk->events, buf);
+}
+
+static ssize_t disk_events_async_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return __disk_events_show(disk->async_events, buf);
+}
+
+static ssize_t disk_events_poll_msecs_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return sprintf(buf, "%ld\n", disk->ev->poll_msecs);
+}
+
+static ssize_t disk_events_poll_msecs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+ long intv;
+
+ if (!count || !sscanf(buf, "%ld", &intv))
+ return -EINVAL;
+
+ if (intv < 0 && intv != -1)
+ return -EINVAL;
+
+ __disk_block_events(disk, true);
+ disk->ev->poll_msecs = intv;
+ __disk_unblock_events(disk, true);
+
+ return count;
+}
+
+static const DEVICE_ATTR(events, S_IRUGO, disk_events_show, NULL);
+static const DEVICE_ATTR(events_async, S_IRUGO, disk_events_async_show, NULL);
+static const DEVICE_ATTR(events_poll_msecs, S_IRUGO|S_IWUSR,
+ disk_events_poll_msecs_show,
+ disk_events_poll_msecs_store);
+
+static const struct attribute *disk_events_attrs[] = {
+ &dev_attr_events.attr,
+ &dev_attr_events_async.attr,
+ &dev_attr_events_poll_msecs.attr,
+ NULL,
+};
+
+/*
+ * The default polling interval can be specified by the kernel
+ * parameter block.events_dfl_poll_msecs which defaults to 0
+ * (disable). This can also be modified runtime by writing to
+ * /sys/module/block/events_dfl_poll_msecs.
+ */
+static int disk_events_set_dfl_poll_msecs(const char *val,
+ const struct kernel_param *kp)
+{
+ struct disk_events *ev;
+ int ret;
+
+ ret = param_set_ulong(val, kp);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&disk_events_mutex);
+
+ list_for_each_entry(ev, &disk_events, node)
+ disk_check_events(ev->disk);
+
+ mutex_unlock(&disk_events_mutex);
+
+ return 0;
+}
+
+static const struct kernel_param_ops disk_events_dfl_poll_msecs_param_ops = {
+ .set = disk_events_set_dfl_poll_msecs,
+ .get = param_get_ulong,
+};
+
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "block."
+
+module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops,
+ &disk_events_dfl_poll_msecs, 0644);
+
+/*
+ * disk_{add|del|release}_events - initialize and destroy disk_events.
+ */
+static void disk_add_events(struct gendisk *disk)
+{
+ struct disk_events *ev;
+
+ if (!disk->fops->check_events || !(disk->events | disk->async_events))
+ return;
+
+ ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+ if (!ev) {
+ pr_warn("%s: failed to initialize events\n", disk->disk_name);
+ return;
+ }
+
+ if (sysfs_create_files(&disk_to_dev(disk)->kobj,
+ disk_events_attrs) < 0) {
+ pr_warn("%s: failed to create sysfs files for events\n",
+ disk->disk_name);
+ kfree(ev);
+ return;
+ }
+
+ disk->ev = ev;
+
+ INIT_LIST_HEAD(&ev->node);
+ ev->disk = disk;
+ spin_lock_init(&ev->lock);
+ ev->block = 1;
+ ev->poll_msecs = -1;
+ INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn);
+
+ mutex_lock(&disk_events_mutex);
+ list_add_tail(&ev->node, &disk_events);
+ mutex_unlock(&disk_events_mutex);
+
+ /*
+ * Block count is initialized to 1 and the following initial
+ * unblock kicks it into action.
+ */
+ __disk_unblock_events(disk, true);
+}
+
+static void disk_del_events(struct gendisk *disk)
+{
+ if (!disk->ev)
+ return;
+
+ __disk_block_events(disk, true);
+
+ mutex_lock(&disk_events_mutex);
+ list_del_init(&disk->ev->node);
+ mutex_unlock(&disk_events_mutex);
+
+ sysfs_remove_files(&disk_to_dev(disk)->kobj, disk_events_attrs);
+}
+
+static void disk_release_events(struct gendisk *disk)
+{
+ /* the block count should be 1 from disk_del_events() */
+ WARN_ON_ONCE(disk->ev && disk->ev->block != 1);
+ kfree(disk->ev);
+}
diff --git a/block/ioctl.c b/block/ioctl.c
index a9a302eba01e..9049d460fa89 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -294,11 +294,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
return -EINVAL;
if (get_user(n, (int __user *) arg))
return -EFAULT;
- if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0)
+ if (!(mode & FMODE_EXCL) &&
+ blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0)
return -EBUSY;
ret = set_blocksize(bdev, n);
if (!(mode & FMODE_EXCL))
- bd_release(bdev);
+ blkdev_put(bdev, mode | FMODE_EXCL);
return ret;
case BLKPG:
ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
diff --git a/crypto/Kconfig b/crypto/Kconfig
index e4bac29a32e7..4b7cb0e691cd 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,7 +110,6 @@ config CRYPTO_MANAGER_DISABLE_TESTS
config CRYPTO_GF128MUL
tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
- depends on EXPERIMENTAL
help
Efficient table driven implementation of multiplications in the
field GF(2^128). This is needed by some cypher modes. This
@@ -539,8 +538,9 @@ config CRYPTO_AES_X86_64
config CRYPTO_AES_NI_INTEL
tristate "AES cipher algorithms (AES-NI)"
- depends on (X86 || UML_X86) && 64BIT
- select CRYPTO_AES_X86_64
+ depends on (X86 || UML_X86)
+ select CRYPTO_AES_X86_64 if 64BIT
+ select CRYPTO_AES_586 if !64BIT
select CRYPTO_CRYPTD
select CRYPTO_ALGAPI
select CRYPTO_FPU
@@ -563,9 +563,10 @@ config CRYPTO_AES_NI_INTEL
See <http://csrc.nist.gov/encryption/aes/> for more information.
- In addition to AES cipher algorithm support, the
- acceleration for some popular block cipher mode is supported
- too, including ECB, CBC, CTR, LRW, PCBC, XTS.
+ In addition to AES cipher algorithm support, the acceleration
+ for some popular block cipher mode is supported too, including
+ ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional
+ acceleration for CTR.
config CRYPTO_ANUBIS
tristate "Anubis cipher algorithm"
@@ -841,6 +842,27 @@ config CRYPTO_ANSI_CPRNG
ANSI X9.31 A.2.4. Note that this option must be enabled if
CRYPTO_FIPS is selected
+config CRYPTO_USER_API
+ tristate
+
+config CRYPTO_USER_API_HASH
+ tristate "User-space interface for hash algorithms"
+ depends on NET
+ select CRYPTO_HASH
+ select CRYPTO_USER_API
+ help
+ This option enables the user-spaces interface for hash
+ algorithms.
+
+config CRYPTO_USER_API_SKCIPHER
+ tristate "User-space interface for symmetric key cipher algorithms"
+ depends on NET
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_USER_API
+ help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
source "drivers/crypto/Kconfig"
endif # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 423b7de61f93..e9a399ca69db 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -3,32 +3,32 @@
#
obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-objs := api.o cipher.o compress.o
+crypto-y := api.o cipher.o compress.o
obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
obj-$(CONFIG_CRYPTO_FIPS) += fips.o
crypto_algapi-$(CONFIG_PROC_FS) += proc.o
-crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y)
+crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o
obj-$(CONFIG_CRYPTO_AEAD2) += aead.o
-crypto_blkcipher-objs := ablkcipher.o
-crypto_blkcipher-objs += blkcipher.o
+crypto_blkcipher-y := ablkcipher.o
+crypto_blkcipher-y += blkcipher.o
obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o
obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o
obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o
obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
-crypto_hash-objs += ahash.o
-crypto_hash-objs += shash.o
+crypto_hash-y += ahash.o
+crypto_hash-y += shash.o
obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
-cryptomgr-objs := algboss.o testmgr.o
+cryptomgr-y := algboss.o testmgr.o
obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
@@ -85,6 +85,9 @@ obj-$(CONFIG_CRYPTO_RNG2) += krng.o
obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
+obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
+obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
+obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
#
# generic algorithms and the async_tx api
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
new file mode 100644
index 000000000000..940d70cb5c25
--- /dev/null
+++ b/crypto/af_alg.c
@@ -0,0 +1,483 @@
+/*
+ * af_alg: User-space algorithm interface
+ *
+ * This file provides the user-space API for algorithms.
+ *
+ * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <asm/atomic.h>
+#include <crypto/if_alg.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/rwsem.h>
+
+struct alg_type_list {
+ const struct af_alg_type *type;
+ struct list_head list;
+};
+
+static atomic_long_t alg_memory_allocated;
+
+static struct proto alg_proto = {
+ .name = "ALG",
+ .owner = THIS_MODULE,
+ .memory_allocated = &alg_memory_allocated,
+ .obj_size = sizeof(struct alg_sock),
+};
+
+static LIST_HEAD(alg_types);
+static DECLARE_RWSEM(alg_types_sem);
+
+static const struct af_alg_type *alg_get_type(const char *name)
+{
+ const struct af_alg_type *type = ERR_PTR(-ENOENT);
+ struct alg_type_list *node;
+
+ down_read(&alg_types_sem);
+ list_for_each_entry(node, &alg_types, list) {
+ if (strcmp(node->type->name, name))
+ continue;
+
+ if (try_module_get(node->type->owner))
+ type = node->type;
+ break;
+ }
+ up_read(&alg_types_sem);
+
+ return type;
+}
+
+int af_alg_register_type(const struct af_alg_type *type)
+{
+ struct alg_type_list *node;
+ int err = -EEXIST;
+
+ down_write(&alg_types_sem);
+ list_for_each_entry(node, &alg_types, list) {
+ if (!strcmp(node->type->name, type->name))
+ goto unlock;
+ }
+
+ node = kmalloc(sizeof(*node), GFP_KERNEL);
+ err = -ENOMEM;
+ if (!node)
+ goto unlock;
+
+ type->ops->owner = THIS_MODULE;
+ node->type = type;
+ list_add(&node->list, &alg_types);
+ err = 0;
+
+unlock:
+ up_write(&alg_types_sem);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(af_alg_register_type);
+
+int af_alg_unregister_type(const struct af_alg_type *type)
+{
+ struct alg_type_list *node;
+ int err = -ENOENT;
+
+ down_write(&alg_types_sem);
+ list_for_each_entry(node, &alg_types, list) {
+ if (strcmp(node->type->name, type->name))
+ continue;
+
+ list_del(&node->list);
+ kfree(node);
+ err = 0;
+ break;
+ }
+ up_write(&alg_types_sem);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(af_alg_unregister_type);
+
+static void alg_do_release(const struct af_alg_type *type, void *private)
+{
+ if (!type)
+ return;
+
+ type->release(private);
+ module_put(type->owner);
+}
+
+int af_alg_release(struct socket *sock)
+{
+ if (sock->sk)
+ sock_put(sock->sk);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(af_alg_release);
+
+static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct sockaddr_alg *sa = (void *)uaddr;
+ const struct af_alg_type *type;
+ void *private;
+
+ if (sock->state == SS_CONNECTED)
+ return -EINVAL;
+
+ if (addr_len != sizeof(*sa))
+ return -EINVAL;
+
+ sa->salg_type[sizeof(sa->salg_type) - 1] = 0;
+ sa->salg_name[sizeof(sa->salg_name) - 1] = 0;
+
+ type = alg_get_type(sa->salg_type);
+ if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) {
+ request_module("algif-%s", sa->salg_type);
+ type = alg_get_type(sa->salg_type);
+ }
+
+ if (IS_ERR(type))
+ return PTR_ERR(type);
+
+ private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask);
+ if (IS_ERR(private)) {
+ module_put(type->owner);
+ return PTR_ERR(private);
+ }
+
+ lock_sock(sk);
+
+ swap(ask->type, type);
+ swap(ask->private, private);
+
+ release_sock(sk);
+
+ alg_do_release(type, private);
+
+ return 0;
+}
+
+static int alg_setkey(struct sock *sk, char __user *ukey,
+ unsigned int keylen)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ const struct af_alg_type *type = ask->type;
+ u8 *key;
+ int err;
+
+ key = sock_kmalloc(sk, keylen, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ err = -EFAULT;
+ if (copy_from_user(key, ukey, keylen))
+ goto out;
+
+ err = type->setkey(ask->private, key, keylen);
+
+out:
+ sock_kfree_s(sk, key, keylen);
+
+ return err;
+}
+
+static int alg_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, unsigned int optlen)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ const struct af_alg_type *type;
+ int err = -ENOPROTOOPT;
+
+ lock_sock(sk);
+ type = ask->type;
+
+ if (level != SOL_ALG || !type)
+ goto unlock;
+
+ switch (optname) {
+ case ALG_SET_KEY:
+ if (sock->state == SS_CONNECTED)
+ goto unlock;
+ if (!type->setkey)
+ goto unlock;
+
+ err = alg_setkey(sk, optval, optlen);
+ }
+
+unlock:
+ release_sock(sk);
+
+ return err;
+}
+
+int af_alg_accept(struct sock *sk, struct socket *newsock)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ const struct af_alg_type *type;
+ struct sock *sk2;
+ int err;
+
+ lock_sock(sk);
+ type = ask->type;
+
+ err = -EINVAL;
+ if (!type)
+ goto unlock;
+
+ sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto);
+ err = -ENOMEM;
+ if (!sk2)
+ goto unlock;
+
+ sock_init_data(newsock, sk2);
+ sock_graft(sk2, newsock);
+
+ err = type->accept(ask->private, sk2);
+ if (err) {
+ sk_free(sk2);
+ goto unlock;
+ }
+
+ sk2->sk_family = PF_ALG;
+
+ sock_hold(sk);
+ alg_sk(sk2)->parent = sk;
+ alg_sk(sk2)->type = type;
+
+ newsock->ops = type->ops;
+ newsock->state = SS_CONNECTED;
+
+ err = 0;
+
+unlock:
+ release_sock(sk);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(af_alg_accept);
+
+static int alg_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+ return af_alg_accept(sock->sk, newsock);
+}
+
+static const struct proto_ops alg_proto_ops = {
+ .family = PF_ALG,
+ .owner = THIS_MODULE,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .poll = sock_no_poll,
+
+ .bind = alg_bind,
+ .release = af_alg_release,
+ .setsockopt = alg_setsockopt,
+ .accept = alg_accept,
+};
+
+static void alg_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+
+ alg_do_release(ask->type, ask->private);
+}
+
+static int alg_create(struct net *net, struct socket *sock, int protocol,
+ int kern)
+{
+ struct sock *sk;
+ int err;
+
+ if (sock->type != SOCK_SEQPACKET)
+ return -ESOCKTNOSUPPORT;
+ if (protocol != 0)
+ return -EPROTONOSUPPORT;
+
+ err = -ENOMEM;
+ sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto);
+ if (!sk)
+ goto out;
+
+ sock->ops = &alg_proto_ops;
+ sock_init_data(sock, sk);
+
+ sk->sk_family = PF_ALG;
+ sk->sk_destruct = alg_sock_destruct;
+
+ return 0;
+out:
+ return err;
+}
+
+static const struct net_proto_family alg_family = {
+ .family = PF_ALG,
+ .create = alg_create,
+ .owner = THIS_MODULE,
+};
+
+int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
+ int write)
+{
+ unsigned long from = (unsigned long)addr;
+ unsigned long npages;
+ unsigned off;
+ int err;
+ int i;
+
+ err = -EFAULT;
+ if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len))
+ goto out;
+
+ off = from & ~PAGE_MASK;
+ npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (npages > ALG_MAX_PAGES)
+ npages = ALG_MAX_PAGES;
+
+ err = get_user_pages_fast(from, npages, write, sgl->pages);
+ if (err < 0)
+ goto out;
+
+ npages = err;
+ err = -EINVAL;
+ if (WARN_ON(npages == 0))
+ goto out;
+
+ err = 0;
+
+ sg_init_table(sgl->sg, npages);
+
+ for (i = 0; i < npages; i++) {
+ int plen = min_t(int, len, PAGE_SIZE - off);
+
+ sg_set_page(sgl->sg + i, sgl->pages[i], plen, off);
+
+ off = 0;
+ len -= plen;
+ err += plen;
+ }
+
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(af_alg_make_sg);
+
+void af_alg_free_sg(struct af_alg_sgl *sgl)
+{
+ int i;
+
+ i = 0;
+ do {
+ put_page(sgl->pages[i]);
+ } while (!sg_is_last(sgl->sg + (i++)));
+}
+EXPORT_SYMBOL_GPL(af_alg_free_sg);
+
+int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
+{
+ struct cmsghdr *cmsg;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ if (!CMSG_OK(msg, cmsg))
+ return -EINVAL;
+ if (cmsg->cmsg_level != SOL_ALG)
+ continue;
+
+ switch(cmsg->cmsg_type) {
+ case ALG_SET_IV:
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv)))
+ return -EINVAL;
+ con->iv = (void *)CMSG_DATA(cmsg);
+ if (cmsg->cmsg_len < CMSG_LEN(con->iv->ivlen +
+ sizeof(*con->iv)))
+ return -EINVAL;
+ break;
+
+ case ALG_SET_OP:
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32)))
+ return -EINVAL;
+ con->op = *(u32 *)CMSG_DATA(cmsg);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(af_alg_cmsg_send);
+
+int af_alg_wait_for_completion(int err, struct af_alg_completion *completion)
+{
+ switch (err) {
+ case -EINPROGRESS:
+ case -EBUSY:
+ wait_for_completion(&completion->completion);
+ INIT_COMPLETION(completion->completion);
+ err = completion->err;
+ break;
+ };
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(af_alg_wait_for_completion);
+
+void af_alg_complete(struct crypto_async_request *req, int err)
+{
+ struct af_alg_completion *completion = req->data;
+
+ completion->err = err;
+ complete(&completion->completion);
+}
+EXPORT_SYMBOL_GPL(af_alg_complete);
+
+static int __init af_alg_init(void)
+{
+ int err = proto_register(&alg_proto, 0);
+
+ if (err)
+ goto out;
+
+ err = sock_register(&alg_family);
+ if (err != 0)
+ goto out_unregister_proto;
+
+out:
+ return err;
+
+out_unregister_proto:
+ proto_unregister(&alg_proto);
+ goto out;
+}
+
+static void __exit af_alg_exit(void)
+{
+ sock_unregister(PF_ALG);
+ proto_unregister(&alg_proto);
+}
+
+module_init(af_alg_init);
+module_exit(af_alg_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(AF_ALG);
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
new file mode 100644
index 000000000000..62122a1a2f7a
--- /dev/null
+++ b/crypto/algif_hash.c
@@ -0,0 +1,319 @@
+/*
+ * algif_hash: User-space interface for hash algorithms
+ *
+ * This file provides the user-space API for hash algorithms.
+ *
+ * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or 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 <crypto/hash.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct hash_ctx {
+ struct af_alg_sgl sgl;
+
+ u8 *result;
+
+ struct af_alg_completion completion;
+
+ unsigned int len;
+ bool more;
+
+ struct ahash_request req;
+};
+
+static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t ignored)
+{
+ int limit = ALG_MAX_PAGES * PAGE_SIZE;
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct hash_ctx *ctx = ask->private;
+ unsigned long iovlen;
+ struct iovec *iov;
+ long copied = 0;
+ int err;
+
+ if (limit > sk->sk_sndbuf)
+ limit = sk->sk_sndbuf;
+
+ lock_sock(sk);
+ if (!ctx->more) {
+ err = crypto_ahash_init(&ctx->req);
+ if (err)
+ goto unlock;
+ }
+
+ ctx->more = 0;
+
+ for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
+ iovlen--, iov++) {
+ unsigned long seglen = iov->iov_len;
+ char __user *from = iov->iov_base;
+
+ while (seglen) {
+ int len = min_t(unsigned long, seglen, limit);
+ int newlen;
+
+ newlen = af_alg_make_sg(&ctx->sgl, from, len, 0);
+ if (newlen < 0)
+ goto unlock;
+
+ ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL,
+ newlen);
+
+ err = af_alg_wait_for_completion(
+ crypto_ahash_update(&ctx->req),
+ &ctx->completion);
+
+ af_alg_free_sg(&ctx->sgl);
+
+ if (err)
+ goto unlock;
+
+ seglen -= newlen;
+ from += newlen;
+ copied += newlen;
+ }
+ }
+
+ err = 0;
+
+ ctx->more = msg->msg_flags & MSG_MORE;
+ if (!ctx->more) {
+ ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
+ err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
+ &ctx->completion);
+ }
+
+unlock:
+ release_sock(sk);
+
+ return err ?: copied;
+}
+
+static ssize_t hash_sendpage(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct hash_ctx *ctx = ask->private;
+ int err;
+
+ lock_sock(sk);
+ sg_init_table(ctx->sgl.sg, 1);
+ sg_set_page(ctx->sgl.sg, page, size, offset);
+
+ ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size);
+
+ if (!(flags & MSG_MORE)) {
+ if (ctx->more)
+ err = crypto_ahash_finup(&ctx->req);
+ else
+ err = crypto_ahash_digest(&ctx->req);
+ } else {
+ if (!ctx->more) {
+ err = crypto_ahash_init(&ctx->req);
+ if (err)
+ goto unlock;
+ }
+
+ err = crypto_ahash_update(&ctx->req);
+ }
+
+ err = af_alg_wait_for_completion(err, &ctx->completion);
+ if (err)
+ goto unlock;
+
+ ctx->more = flags & MSG_MORE;
+
+unlock:
+ release_sock(sk);
+
+ return err ?: size;
+}
+
+static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct hash_ctx *ctx = ask->private;
+ unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
+ int err;
+
+ if (len > ds)
+ len = ds;
+ else if (len < ds)
+ msg->msg_flags |= MSG_TRUNC;
+
+ lock_sock(sk);
+ if (ctx->more) {
+ ctx->more = 0;
+ ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
+ err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
+ &ctx->completion);
+ if (err)
+ goto unlock;
+ }
+
+ err = memcpy_toiovec(msg->msg_iov, ctx->result, len);
+
+unlock:
+ release_sock(sk);
+
+ return err ?: len;
+}
+
+static int hash_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct hash_ctx *ctx = ask->private;
+ struct ahash_request *req = &ctx->req;
+ char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))];
+ struct sock *sk2;
+ struct alg_sock *ask2;
+ struct hash_ctx *ctx2;
+ int err;
+
+ err = crypto_ahash_export(req, state);
+ if (err)
+ return err;
+
+ err = af_alg_accept(ask->parent, newsock);
+ if (err)
+ return err;
+
+ sk2 = newsock->sk;
+ ask2 = alg_sk(sk2);
+ ctx2 = ask2->private;
+ ctx2->more = 1;
+
+ err = crypto_ahash_import(&ctx2->req, state);
+ if (err) {
+ sock_orphan(sk2);
+ sock_put(sk2);
+ }
+
+ return err;
+}
+
+static struct proto_ops algif_hash_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .setsockopt = sock_no_setsockopt,
+ .poll = sock_no_poll,
+
+ .release = af_alg_release,
+ .sendmsg = hash_sendmsg,
+ .sendpage = hash_sendpage,
+ .recvmsg = hash_recvmsg,
+ .accept = hash_accept,
+};
+
+static void *hash_bind(const char *name, u32 type, u32 mask)
+{
+ return crypto_alloc_ahash(name, type, mask);
+}
+
+static void hash_release(void *private)
+{
+ crypto_free_ahash(private);
+}
+
+static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
+{
+ return crypto_ahash_setkey(private, key, keylen);
+}
+
+static void hash_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct hash_ctx *ctx = ask->private;
+
+ sock_kfree_s(sk, ctx->result,
+ crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)));
+ sock_kfree_s(sk, ctx, ctx->len);
+ af_alg_release_parent(sk);
+}
+
+static int hash_accept_parent(void *private, struct sock *sk)
+{
+ struct hash_ctx *ctx;
+ struct alg_sock *ask = alg_sk(sk);
+ unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
+ unsigned ds = crypto_ahash_digestsize(private);
+
+ ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL);
+ if (!ctx->result) {
+ sock_kfree_s(sk, ctx, len);
+ return -ENOMEM;
+ }
+
+ memset(ctx->result, 0, ds);
+
+ ctx->len = len;
+ ctx->more = 0;
+ af_alg_init_completion(&ctx->completion);
+
+ ask->private = ctx;
+
+ ahash_request_set_tfm(&ctx->req, private);
+ ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ af_alg_complete, &ctx->completion);
+
+ sk->sk_destruct = hash_sock_destruct;
+
+ return 0;
+}
+
+static const struct af_alg_type algif_type_hash = {
+ .bind = hash_bind,
+ .release = hash_release,
+ .setkey = hash_setkey,
+ .accept = hash_accept_parent,
+ .ops = &algif_hash_ops,
+ .name = "hash",
+ .owner = THIS_MODULE
+};
+
+static int __init algif_hash_init(void)
+{
+ return af_alg_register_type(&algif_type_hash);
+}
+
+static void __exit algif_hash_exit(void)
+{
+ int err = af_alg_unregister_type(&algif_type_hash);
+ BUG_ON(err);
+}
+
+module_init(algif_hash_init);
+module_exit(algif_hash_exit);
+MODULE_LICENSE("GPL");
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000000000000..6a6dfc062d2a
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,632 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or 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 <crypto/scatterwalk.h>
+#include <crypto/skcipher.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct skcipher_sg_list {
+ struct list_head list;
+
+ int cur;
+
+ struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+ struct list_head tsgl;
+ struct af_alg_sgl rsgl;
+
+ void *iv;
+
+ struct af_alg_completion completion;
+
+ unsigned used;
+
+ unsigned int len;
+ bool more;
+ bool merge;
+ bool enc;
+
+ struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline int skcipher_sndbuf(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+
+ return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
+ ctx->used, 0);
+}
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+ return PAGE_SIZE <= skcipher_sndbuf(sk);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct skcipher_sg_list *sgl;
+ struct scatterlist *sg = NULL;
+
+ sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+ if (!list_empty(&ctx->tsgl))
+ sg = sgl->sg;
+
+ if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+ sgl = sock_kmalloc(sk, sizeof(*sgl) +
+ sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+ GFP_KERNEL);
+ if (!sgl)
+ return -ENOMEM;
+
+ sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+ sgl->cur = 0;
+
+ if (sg)
+ scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+ list_add_tail(&sgl->list, &ctx->tsgl);
+ }
+
+ return 0;
+}
+
+static void skcipher_pull_sgl(struct sock *sk, int used)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct skcipher_sg_list *sgl;
+ struct scatterlist *sg;
+ int i;
+
+ while (!list_empty(&ctx->tsgl)) {
+ sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list,
+ list);
+ sg = sgl->sg;
+
+ for (i = 0; i < sgl->cur; i++) {
+ int plen = min_t(int, used, sg[i].length);
+
+ if (!sg_page(sg + i))
+ continue;
+
+ sg[i].length -= plen;
+ sg[i].offset += plen;
+
+ used -= plen;
+ ctx->used -= plen;
+
+ if (sg[i].length)
+ return;
+
+ put_page(sg_page(sg + i));
+ sg_assign_page(sg + i, NULL);
+ }
+
+ list_del(&sgl->list);
+ sock_kfree_s(sk, sgl,
+ sizeof(*sgl) + sizeof(sgl->sg[0]) *
+ (MAX_SGL_ENTS + 1));
+ }
+
+ if (!ctx->used)
+ ctx->merge = 0;
+}
+
+static void skcipher_free_sgl(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+
+ skcipher_pull_sgl(sk, ctx->used);
+}
+
+static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags)
+{
+ long timeout;
+ DEFINE_WAIT(wait);
+ int err = -ERESTARTSYS;
+
+ if (flags & MSG_DONTWAIT)
+ return -EAGAIN;
+
+ set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+
+ for (;;) {
+ if (signal_pending(current))
+ break;
+ prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) {
+ err = 0;
+ break;
+ }
+ }
+ finish_wait(sk_sleep(sk), &wait);
+
+ return err;
+}
+
+static void skcipher_wmem_wakeup(struct sock *sk)
+{
+ struct socket_wq *wq;
+
+ if (!skcipher_writable(sk))
+ return;
+
+ rcu_read_lock();
+ wq = rcu_dereference(sk->sk_wq);
+ if (wq_has_sleeper(wq))
+ wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
+ POLLRDNORM |
+ POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+ rcu_read_unlock();
+}
+
+static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ long timeout;
+ DEFINE_WAIT(wait);
+ int err = -ERESTARTSYS;
+
+ if (flags & MSG_DONTWAIT) {
+ return -EAGAIN;
+ }
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+ for (;;) {
+ if (signal_pending(current))
+ break;
+ prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ if (sk_wait_event(sk, &timeout, ctx->used)) {
+ err = 0;
+ break;
+ }
+ }
+ finish_wait(sk_sleep(sk), &wait);
+
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+ return err;
+}
+
+static void skcipher_data_wakeup(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct socket_wq *wq;
+
+ if (!ctx->used)
+ return;
+
+ rcu_read_lock();
+ wq = rcu_dereference(sk->sk_wq);
+ if (wq_has_sleeper(wq))
+ wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
+ POLLRDNORM |
+ POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
+ rcu_read_unlock();
+}
+
+static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t size)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
+ unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
+ struct skcipher_sg_list *sgl;
+ struct af_alg_control con = {};
+ long copied = 0;
+ bool enc = 0;
+ int err;
+ int i;
+
+ if (msg->msg_controllen) {
+ err = af_alg_cmsg_send(msg, &con);
+ if (err)
+ return err;
+
+ switch (con.op) {
+ case ALG_OP_ENCRYPT:
+ enc = 1;
+ break;
+ case ALG_OP_DECRYPT:
+ enc = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (con.iv && con.iv->ivlen != ivsize)
+ return -EINVAL;
+ }
+
+ err = -EINVAL;
+
+ lock_sock(sk);
+ if (!ctx->more && ctx->used)
+ goto unlock;
+
+ if (!ctx->used) {
+ ctx->enc = enc;
+ if (con.iv)
+ memcpy(ctx->iv, con.iv->iv, ivsize);
+ }
+
+ while (size) {
+ struct scatterlist *sg;
+ unsigned long len = size;
+ int plen;
+
+ if (ctx->merge) {
+ sgl = list_entry(ctx->tsgl.prev,
+ struct skcipher_sg_list, list);
+ sg = sgl->sg + sgl->cur - 1;
+ len = min_t(unsigned long, len,
+ PAGE_SIZE - sg->offset - sg->length);
+
+ err = memcpy_fromiovec(page_address(sg_page(sg)) +
+ sg->offset + sg->length,
+ msg->msg_iov, len);
+ if (err)
+ goto unlock;
+
+ sg->length += len;
+ ctx->merge = (sg->offset + sg->length) &
+ (PAGE_SIZE - 1);
+
+ ctx->used += len;
+ copied += len;
+ size -= len;
+ continue;
+ }
+
+ if (!skcipher_writable(sk)) {
+ err = skcipher_wait_for_wmem(sk, msg->msg_flags);
+ if (err)
+ goto unlock;
+ }
+
+ len = min_t(unsigned long, len, skcipher_sndbuf(sk));
+
+ err = skcipher_alloc_sgl(sk);
+ if (err)
+ goto unlock;
+
+ sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+ sg = sgl->sg;
+ do {
+ i = sgl->cur;
+ plen = min_t(int, len, PAGE_SIZE);
+
+ sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
+ err = -ENOMEM;
+ if (!sg_page(sg + i))
+ goto unlock;
+
+ err = memcpy_fromiovec(page_address(sg_page(sg + i)),
+ msg->msg_iov, plen);
+ if (err) {
+ __free_page(sg_page(sg + i));
+ sg_assign_page(sg + i, NULL);
+ goto unlock;
+ }
+
+ sg[i].length = plen;
+ len -= plen;
+ ctx->used += plen;
+ copied += plen;
+ size -= plen;
+ sgl->cur++;
+ } while (len && sgl->cur < MAX_SGL_ENTS);
+
+ ctx->merge = plen & (PAGE_SIZE - 1);
+ }
+
+ err = 0;
+
+ ctx->more = msg->msg_flags & MSG_MORE;
+ if (!ctx->more && !list_empty(&ctx->tsgl))
+ sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+
+unlock:
+ skcipher_data_wakeup(sk);
+ release_sock(sk);
+
+ return copied ?: err;
+}
+
+static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct skcipher_sg_list *sgl;
+ int err = -EINVAL;
+
+ lock_sock(sk);
+ if (!ctx->more && ctx->used)
+ goto unlock;
+
+ if (!size)
+ goto done;
+
+ if (!skcipher_writable(sk)) {
+ err = skcipher_wait_for_wmem(sk, flags);
+ if (err)
+ goto unlock;
+ }
+
+ err = skcipher_alloc_sgl(sk);
+ if (err)
+ goto unlock;
+
+ ctx->merge = 0;
+ sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+
+ get_page(page);
+ sg_set_page(sgl->sg + sgl->cur, page, size, offset);
+ sgl->cur++;
+ ctx->used += size;
+
+done:
+ ctx->more = flags & MSG_MORE;
+ if (!ctx->more && !list_empty(&ctx->tsgl))
+ sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+
+unlock:
+ skcipher_data_wakeup(sk);
+ release_sock(sk);
+
+ return err ?: size;
+}
+
+static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t ignored, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(
+ &ctx->req));
+ struct skcipher_sg_list *sgl;
+ struct scatterlist *sg;
+ unsigned long iovlen;
+ struct iovec *iov;
+ int err = -EAGAIN;
+ int used;
+ long copied = 0;
+
+ lock_sock(sk);
+ for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
+ iovlen--, iov++) {
+ unsigned long seglen = iov->iov_len;
+ char __user *from = iov->iov_base;
+
+ while (seglen) {
+ sgl = list_first_entry(&ctx->tsgl,
+ struct skcipher_sg_list, list);
+ sg = sgl->sg;
+
+ while (!sg->length)
+ sg++;
+
+ used = ctx->used;
+ if (!used) {
+ err = skcipher_wait_for_data(sk, flags);
+ if (err)
+ goto unlock;
+ }
+
+ used = min_t(unsigned long, used, seglen);
+
+ used = af_alg_make_sg(&ctx->rsgl, from, used, 1);
+ err = used;
+ if (err < 0)
+ goto unlock;
+
+ if (ctx->more || used < ctx->used)
+ used -= used % bs;
+
+ err = -EINVAL;
+ if (!used)
+ goto free;
+
+ ablkcipher_request_set_crypt(&ctx->req, sg,
+ ctx->rsgl.sg, used,
+ ctx->iv);
+
+ err = af_alg_wait_for_completion(
+ ctx->enc ?
+ crypto_ablkcipher_encrypt(&ctx->req) :
+ crypto_ablkcipher_decrypt(&ctx->req),
+ &ctx->completion);
+
+free:
+ af_alg_free_sg(&ctx->rsgl);
+
+ if (err)
+ goto unlock;
+
+ copied += used;
+ from += used;
+ seglen -= used;
+ skcipher_pull_sgl(sk, used);
+ }
+ }
+
+ err = 0;
+
+unlock:
+ skcipher_wmem_wakeup(sk);
+ release_sock(sk);
+
+ return copied ?: err;
+}
+
+
+static unsigned int skcipher_poll(struct file *file, struct socket *sock,
+ poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ unsigned int mask;
+
+ sock_poll_wait(file, sk_sleep(sk), wait);
+ mask = 0;
+
+ if (ctx->used)
+ mask |= POLLIN | POLLRDNORM;
+
+ if (skcipher_writable(sk))
+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+ return mask;
+}
+
+static struct proto_ops algif_skcipher_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .accept = sock_no_accept,
+ .setsockopt = sock_no_setsockopt,
+
+ .release = af_alg_release,
+ .sendmsg = skcipher_sendmsg,
+ .sendpage = skcipher_sendpage,
+ .recvmsg = skcipher_recvmsg,
+ .poll = skcipher_poll,
+};
+
+static void *skcipher_bind(const char *name, u32 type, u32 mask)
+{
+ return crypto_alloc_ablkcipher(name, type, mask);
+}
+
+static void skcipher_release(void *private)
+{
+ crypto_free_ablkcipher(private);
+}
+
+static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
+{
+ return crypto_ablkcipher_setkey(private, key, keylen);
+}
+
+static void skcipher_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct skcipher_ctx *ctx = ask->private;
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
+
+ skcipher_free_sgl(sk);
+ sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
+ sock_kfree_s(sk, ctx, ctx->len);
+ af_alg_release_parent(sk);
+}
+
+static int skcipher_accept_parent(void *private, struct sock *sk)
+{
+ struct skcipher_ctx *ctx;
+ struct alg_sock *ask = alg_sk(sk);
+ unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private);
+
+ ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private),
+ GFP_KERNEL);
+ if (!ctx->iv) {
+ sock_kfree_s(sk, ctx, len);
+ return -ENOMEM;
+ }
+
+ memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private));
+
+ INIT_LIST_HEAD(&ctx->tsgl);
+ ctx->len = len;
+ ctx->used = 0;
+ ctx->more = 0;
+ ctx->merge = 0;
+ ctx->enc = 0;
+ af_alg_init_completion(&ctx->completion);
+
+ ask->private = ctx;
+
+ ablkcipher_request_set_tfm(&ctx->req, private);
+ ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ af_alg_complete, &ctx->completion);
+
+ sk->sk_destruct = skcipher_sock_destruct;
+
+ return 0;
+}
+
+static const struct af_alg_type algif_type_skcipher = {
+ .bind = skcipher_bind,
+ .release = skcipher_release,
+ .setkey = skcipher_setkey,
+ .accept = skcipher_accept_parent,
+ .ops = &algif_skcipher_ops,
+ .name = "skcipher",
+ .owner = THIS_MODULE
+};
+
+static int __init algif_skcipher_init(void)
+{
+ return af_alg_register_type(&algif_type_skcipher);
+}
+
+static void __exit algif_skcipher_exit(void)
+{
+ int err = af_alg_unregister_type(&algif_type_skcipher);
+ BUG_ON(err);
+}
+
+module_init(algif_skcipher_init);
+module_exit(algif_skcipher_exit);
+MODULE_LICENSE("GPL");
diff --git a/crypto/authenc.c b/crypto/authenc.c
index a5a22cfcd07b..5ef7ba6b6a76 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -107,20 +107,6 @@ badkey:
goto out;
}
-static void authenc_chain(struct scatterlist *head, struct scatterlist *sg,
- int chain)
-{
- if (chain) {
- head->length += sg->length;
- sg = scatterwalk_sg_next(sg);
- }
-
- if (sg)
- scatterwalk_sg_chain(head, 2, sg);
- else
- sg_mark_end(head);
-}
-
static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
int err)
{
@@ -345,7 +331,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
if (ivsize) {
sg_init_table(cipher, 2);
sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, dst, vdst == iv + ivsize);
+ scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2);
dst = cipher;
cryptlen += ivsize;
}
@@ -354,7 +340,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
authenc_ahash_fn = crypto_authenc_ahash;
sg_init_table(asg, 2);
sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset);
- authenc_chain(asg, dst, 0);
+ scatterwalk_crypto_chain(asg, dst, 0, 2);
dst = asg;
cryptlen += req->assoclen;
}
@@ -499,7 +485,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
if (ivsize) {
sg_init_table(cipher, 2);
sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, src, vsrc == iv + ivsize);
+ scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2);
src = cipher;
cryptlen += ivsize;
}
@@ -508,7 +494,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
authenc_ahash_fn = crypto_authenc_ahash;
sg_init_table(asg, 2);
sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset);
- authenc_chain(asg, src, 0);
+ scatterwalk_crypto_chain(asg, src, 0, 2);
src = asg;
cryptlen += req->assoclen;
}
diff --git a/crypto/cast5.c b/crypto/cast5.c
index a1d2294b50ad..4a230ddec877 100644
--- a/crypto/cast5.c
+++ b/crypto/cast5.c
@@ -604,36 +604,23 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
* Rounds 3, 6, 9, 12, and 15 use f function Type 3.
*/
+ t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
+ t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
+ t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
+ t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
+ t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
+ t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
+ t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
+ t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
+ t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
+ t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
+ t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+ t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
if (!(c->rr)) {
- t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
- t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
- t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
- t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
- t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
- t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
- t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
- t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
- t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
- t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
- t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
- t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
- } else {
- t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
- t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
- t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
- t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
- t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
- t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
- t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
- t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
- t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
- t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
- t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
- t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
}
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
@@ -663,32 +650,19 @@ static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
- t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
- t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
- t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
- t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
- t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
- t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
- t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
- t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
- t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
- t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
- t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
- t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
- } else {
- t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
- t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
- t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
- t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
- t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
- t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
- t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
- t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
- t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
- t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
- t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
- t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
}
+ t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
+ t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+ t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
+ t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
+ t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
+ t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
+ t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
+ t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
+ t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
+ t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
+ t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
+ t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
dst[0] = cpu_to_be32(r);
dst[1] = cpu_to_be32(l);
diff --git a/crypto/crypto_wq.c b/crypto/crypto_wq.c
index fdcf6248f152..b980ee1af459 100644
--- a/crypto/crypto_wq.c
+++ b/crypto/crypto_wq.c
@@ -20,7 +20,8 @@ EXPORT_SYMBOL_GPL(kcrypto_wq);
static int __init crypto_wq_init(void)
{
- kcrypto_wq = create_workqueue("crypto");
+ kcrypto_wq = alloc_workqueue("crypto",
+ WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
if (unlikely(!kcrypto_wq))
return -ENOMEM;
return 0;
diff --git a/crypto/deflate.c b/crypto/deflate.c
index 463dc859aa05..cbc7a33a9600 100644
--- a/crypto/deflate.c
+++ b/crypto/deflate.c
@@ -48,12 +48,11 @@ static int deflate_comp_init(struct deflate_ctx *ctx)
int ret = 0;
struct z_stream_s *stream = &ctx->comp_stream;
- stream->workspace = vmalloc(zlib_deflate_workspacesize());
+ stream->workspace = vzalloc(zlib_deflate_workspacesize());
if (!stream->workspace) {
ret = -ENOMEM;
goto out;
}
- memset(stream->workspace, 0, zlib_deflate_workspacesize());
ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 3ca3b669d5d5..42ce9f570aec 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -62,20 +62,6 @@ out:
skcipher_givcrypt_complete(req, err);
}
-static void eseqiv_chain(struct scatterlist *head, struct scatterlist *sg,
- int chain)
-{
- if (chain) {
- head->length += sg->length;
- sg = scatterwalk_sg_next(sg);
- }
-
- if (sg)
- scatterwalk_sg_chain(head, 2, sg);
- else
- sg_mark_end(head);
-}
-
static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
{
struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
@@ -124,13 +110,13 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
sg_init_table(reqctx->src, 2);
sg_set_buf(reqctx->src, giv, ivsize);
- eseqiv_chain(reqctx->src, osrc, vsrc == giv + ivsize);
+ scatterwalk_crypto_chain(reqctx->src, osrc, vsrc == giv + ivsize, 2);
dst = reqctx->src;
if (osrc != odst) {
sg_init_table(reqctx->dst, 2);
sg_set_buf(reqctx->dst, giv, ivsize);
- eseqiv_chain(reqctx->dst, odst, vdst == giv + ivsize);
+ scatterwalk_crypto_chain(reqctx->dst, odst, vdst == giv + ivsize, 2);
dst = reqctx->dst;
}
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 2f5fbba6576c..1a252639ef91 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -1102,21 +1102,6 @@ static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
return crypto_aead_setauthsize(ctx->child, authsize);
}
-/* this is the same as crypto_authenc_chain */
-static void crypto_rfc4543_chain(struct scatterlist *head,
- struct scatterlist *sg, int chain)
-{
- if (chain) {
- head->length += sg->length;
- sg = scatterwalk_sg_next(sg);
- }
-
- if (sg)
- scatterwalk_sg_chain(head, 2, sg);
- else
- sg_mark_end(head);
-}
-
static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
int enc)
{
@@ -1154,13 +1139,13 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
sg_init_table(payload, 2);
sg_set_buf(payload, req->iv, 8);
- crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8);
+ scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2);
assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
sg_init_table(assoc, 2);
sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
req->assoc->offset);
- crypto_rfc4543_chain(assoc, payload, 0);
+ scatterwalk_crypto_chain(assoc, payload, 0, 2);
aead_request_set_tfm(subreq, ctx->child);
aead_request_set_callback(subreq, req->base.flags, req->base.complete,
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 75586f1f86e7..29a89dad68b6 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -455,7 +455,8 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
get_online_cpus();
- pcrypt->wq = create_workqueue(name);
+ pcrypt->wq = alloc_workqueue(name,
+ WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
if (!pcrypt->wq)
goto err;
diff --git a/crypto/rmd128.c b/crypto/rmd128.c
index 1ceb6735aa53..8a0f68b7f257 100644
--- a/crypto/rmd128.c
+++ b/crypto/rmd128.c
@@ -5,7 +5,7 @@
*
* Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
*
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch>
+ * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.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
@@ -325,4 +325,5 @@ module_init(rmd128_mod_init);
module_exit(rmd128_mod_fini);
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
MODULE_DESCRIPTION("RIPEMD-128 Message Digest");
diff --git a/crypto/rmd160.c b/crypto/rmd160.c
index 472261fc913f..525d7bb752cf 100644
--- a/crypto/rmd160.c
+++ b/crypto/rmd160.c
@@ -5,7 +5,7 @@
*
* Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
*
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch>
+ * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.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
@@ -369,4 +369,5 @@ module_init(rmd160_mod_init);
module_exit(rmd160_mod_fini);
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
MODULE_DESCRIPTION("RIPEMD-160 Message Digest");
diff --git a/crypto/rmd256.c b/crypto/rmd256.c
index 72eafa8d2e7b..69293d9b56e0 100644
--- a/crypto/rmd256.c
+++ b/crypto/rmd256.c
@@ -5,7 +5,7 @@
*
* Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
*
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch>
+ * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.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
@@ -344,4 +344,5 @@ module_init(rmd256_mod_init);
module_exit(rmd256_mod_fini);
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
MODULE_DESCRIPTION("RIPEMD-256 Message Digest");
diff --git a/crypto/rmd320.c b/crypto/rmd320.c
index 86becaba2f05..09f97dfdfbba 100644
--- a/crypto/rmd320.c
+++ b/crypto/rmd320.c
@@ -5,7 +5,7 @@
*
* Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
*
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch>
+ * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.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
@@ -393,4 +393,5 @@ module_init(rmd320_mod_init);
module_exit(rmd320_mod_fini);
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
MODULE_DESCRIPTION("RIPEMD-320 Message Digest");
diff --git a/crypto/shash.c b/crypto/shash.c
index 22fd9433141f..76f74b963151 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -310,7 +310,13 @@ static int shash_async_export(struct ahash_request *req, void *out)
static int shash_async_import(struct ahash_request *req, const void *in)
{
- return crypto_shash_import(ahash_request_ctx(req), in);
+ struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+ struct shash_desc *desc = ahash_request_ctx(req);
+
+ desc->tfm = *ctx;
+ desc->flags = req->base.flags;
+
+ return crypto_shash_import(desc, in);
}
static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 3ca68f9fc14d..9aac5e58be94 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -8,6 +8,13 @@
* Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
* Copyright (c) 2007 Nokia Siemens Networks
*
+ * Updated RFC4106 AES-GCM testing.
+ * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com)
+ * Adrian Hoban <adrian.hoban@intel.com>
+ * Gabriele Paoloni <gabriele.paoloni@intel.com>
+ * Tadeusz Struk (tadeusz.struk@intel.com)
+ * Copyright (c) 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 as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -980,6 +987,10 @@ static int do_test(int m)
ret += tcrypt_test("ansi_cprng");
break;
+ case 151:
+ ret += tcrypt_test("rfc4106(gcm(aes))");
+ break;
+
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index fa8c8f78c8d4..27ea9fe9476f 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -6,6 +6,13 @@
* Copyright (c) 2007 Nokia Siemens Networks
* Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
*
+ * Updated RFC4106 AES-GCM testing.
+ * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com)
+ * Adrian Hoban <adrian.hoban@intel.com>
+ * Gabriele Paoloni <gabriele.paoloni@intel.com>
+ * Tadeusz Struk (tadeusz.struk@intel.com)
+ * Copyright (c) 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 as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -2242,6 +2249,23 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "rfc4106(gcm(aes))",
+ .test = alg_test_aead,
+ .suite = {
+ .aead = {
+ .enc = {
+ .vecs = aes_gcm_rfc4106_enc_tv_template,
+ .count = AES_GCM_4106_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_gcm_rfc4106_dec_tv_template,
+ .count = AES_GCM_4106_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+
+
.alg = "rfc4309(ccm(aes))",
.test = alg_test_aead,
.fips_allowed = 1,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 74e35377fd30..834af7f2adee 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -6,6 +6,15 @@
* Copyright (c) 2007 Nokia Siemens Networks
* Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
*
+ * Updated RFC4106 AES-GCM testing. Some test vectors were taken from
+ * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/
+ * gcm/gcm-test-vectors.tar.gz
+ * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com)
+ * Adrian Hoban <adrian.hoban@intel.com>
+ * Gabriele Paoloni <gabriele.paoloni@intel.com>
+ * Tadeusz Struk (tadeusz.struk@intel.com)
+ * Copyright (c) 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 as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -2947,6 +2956,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
#define AES_CTR_3686_DEC_TEST_VECTORS 6
#define AES_GCM_ENC_TEST_VECTORS 9
#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_GCM_4106_ENC_TEST_VECTORS 7
+#define AES_GCM_4106_DEC_TEST_VECTORS 7
#define AES_CCM_ENC_TEST_VECTORS 7
#define AES_CCM_DEC_TEST_VECTORS 7
#define AES_CCM_4309_ENC_TEST_VECTORS 7
@@ -5829,6 +5840,356 @@ static struct aead_testvec aes_gcm_dec_tv_template[] = {
}
};
+static struct aead_testvec aes_gcm_rfc4106_enc_tv_template[] = {
+ { /* Generated using Crypto++ */
+ .key = zeroed_string,
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = zeroed_string,
+ .ilen = 16,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92"
+ "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78"
+ "\x97\xFE\x4C\x23\x37\x42\x01\xE0"
+ "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B",
+ .rlen = 32,
+ },{
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = zeroed_string,
+ .ilen = 16,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18"
+ "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28"
+ "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D"
+ "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF",
+ .rlen = 32,
+
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .ilen = 16,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE"
+ "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC"
+ "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C"
+ "\xB1\x68\xFD\x14\x52\x64\x61\xB2",
+ .rlen = 32,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .ilen = 16,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE"
+ "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC"
+ "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63"
+ "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5",
+ .rlen = 32,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .ilen = 16,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19"
+ "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29"
+ "\x64\x50\xF9\x32\x13\xFB\x74\x61"
+ "\xF4\xED\x52\xD3\xC5\x10\x55\x3C",
+ .rlen = 32,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .ilen = 64,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19"
+ "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29"
+ "\x98\x14\xA1\x42\x37\x80\xFD\x90"
+ "\x68\x12\x01\xA8\x91\x89\xB9\x83"
+ "\x5B\x11\x77\x12\x9B\xFF\x24\x89"
+ "\x94\x5F\x18\x12\xBA\x27\x09\x39"
+ "\x99\x96\x76\x42\x15\x1C\xCD\xCB"
+ "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD"
+ "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85"
+ "\xBD\xCF\x62\x98\x58\x14\xE5\xBD",
+ .rlen = 80,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef"
+ "\x00\x00\x00\x00",
+ .input = "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff",
+ .ilen = 192,
+ .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .alen = 12,
+ .result = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE"
+ "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A"
+ "\x44\x6D\xC3\x88\x46\x2E\xC2\x01"
+ "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82"
+ "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44"
+ "\x41\xA9\x82\x6F\x22\xA1\x23\x1A"
+ "\xA8\xE3\x16\xFD\x31\x5C\x27\x31"
+ "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1"
+ "\xCF\x07\x57\x41\x67\xD0\xC4\x42"
+ "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F"
+ "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B"
+ "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE"
+ "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C"
+ "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF"
+ "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59"
+ "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA"
+ "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25"
+ "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B"
+ "\x7E\x13\x06\x82\x08\x17\xA4\x35"
+ "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F"
+ "\xA3\x05\x38\x95\x20\x1A\x47\x04"
+ "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35"
+ "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E"
+ "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B"
+ "\x37\x08\x1C\xCF\xBA\x5D\x71\x46"
+ "\x80\x72\xB0\x4C\x82\x0D\x60\x3C",
+ .rlen = 208,
+ }
+};
+
+static struct aead_testvec aes_gcm_rfc4106_dec_tv_template[] = {
+ { /* Generated using Crypto++ */
+ .key = zeroed_string,
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92"
+ "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78"
+ "\x97\xFE\x4C\x23\x37\x42\x01\xE0"
+ "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B",
+ .ilen = 32,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = zeroed_string,
+ .rlen = 16,
+
+ },{
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18"
+ "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28"
+ "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D"
+ "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF",
+ .ilen = 32,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE"
+ "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC"
+ "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C"
+ "\xB1\x68\xFD\x14\x52\x64\x61\xB2",
+ .ilen = 32,
+ .assoc = zeroed_string,
+ .alen = 8,
+ .result = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .rlen = 16,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = zeroed_string,
+ .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE"
+ "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC"
+ "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63"
+ "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5",
+ .ilen = 32,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .rlen = 16,
+
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19"
+ "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29"
+ "\x64\x50\xF9\x32\x13\xFB\x74\x61"
+ "\xF4\xED\x52\xD3\xC5\x10\x55\x3C",
+ .ilen = 32,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .rlen = 16,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19"
+ "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29"
+ "\x98\x14\xA1\x42\x37\x80\xFD\x90"
+ "\x68\x12\x01\xA8\x91\x89\xB9\x83"
+ "\x5B\x11\x77\x12\x9B\xFF\x24\x89"
+ "\x94\x5F\x18\x12\xBA\x27\x09\x39"
+ "\x99\x96\x76\x42\x15\x1C\xCD\xCB"
+ "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD"
+ "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85"
+ "\xBD\xCF\x62\x98\x58\x14\xE5\xBD",
+ .ilen = 80,
+ .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .alen = 8,
+ .result = "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .rlen = 64,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x00\x00\x00\x00",
+ .klen = 20,
+ .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef"
+ "\x00\x00\x00\x00",
+ .input = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE"
+ "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A"
+ "\x44\x6D\xC3\x88\x46\x2E\xC2\x01"
+ "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82"
+ "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44"
+ "\x41\xA9\x82\x6F\x22\xA1\x23\x1A"
+ "\xA8\xE3\x16\xFD\x31\x5C\x27\x31"
+ "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1"
+ "\xCF\x07\x57\x41\x67\xD0\xC4\x42"
+ "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F"
+ "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B"
+ "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE"
+ "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C"
+ "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF"
+ "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59"
+ "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA"
+ "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25"
+ "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B"
+ "\x7E\x13\x06\x82\x08\x17\xA4\x35"
+ "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F"
+ "\xA3\x05\x38\x95\x20\x1A\x47\x04"
+ "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35"
+ "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E"
+ "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B"
+ "\x37\x08\x1C\xCF\xBA\x5D\x71\x46"
+ "\x80\x72\xB0\x4C\x82\x0D\x60\x3C",
+ .ilen = 208,
+ .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .alen = 12,
+ .result = "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff",
+ .rlen = 192,
+
+ }
+};
+
static struct aead_testvec aes_ccm_enc_tv_template[] = {
{ /* From RFC 3610 */
.key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
diff --git a/crypto/zlib.c b/crypto/zlib.c
index c3015733c990..739b8fca4cea 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -95,11 +95,10 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
zlib_comp_exit(ctx);
workspacesize = zlib_deflate_workspacesize();
- stream->workspace = vmalloc(workspacesize);
+ stream->workspace = vzalloc(workspacesize);
if (!stream->workspace)
return -ENOMEM;
- memset(stream->workspace, 0, workspacesize);
ret = zlib_deflateInit2(stream,
tb[ZLIB_COMP_LEVEL]
? nla_get_u32(tb[ZLIB_COMP_LEVEL])
diff --git a/drivers/Kconfig b/drivers/Kconfig
index a2b902f4d437..3d93b3a3d630 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -111,4 +111,6 @@ source "drivers/xen/Kconfig"
source "drivers/staging/Kconfig"
source "drivers/platform/Kconfig"
+
+source "drivers/clk/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index f3ebb30f1b7f..bf15ce7493d2 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -115,3 +115,5 @@ obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_STAGING) += staging/
obj-y += platform/
obj-y += ieee802154/
+#common clk code
+obj-y += clk/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3f3489c5ca8c..a0c03658b2ea 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -209,6 +209,17 @@ config ACPI_PROCESSOR
To compile this driver as a module, choose M here:
the module will be called processor.
+config ACPI_IPMI
+ tristate "IPMI"
+ depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
+ default n
+ help
+ This driver enables the ACPI to access the BMC controller. And it
+ uses the IPMI request/response message to communicate with BMC
+ controller, which can be found on on the server.
+
+ To compile this driver as a module, choose M here:
+ the module will be called as acpi_ipmi.
config ACPI_HOTPLUG_CPU
bool
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 3d031d02e54b..df4c4f030388 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -69,5 +69,6 @@ processor-y += processor_idle.o processor_thermal.o
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
+obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
obj-$(CONFIG_ACPI_APEI) += apei/
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index ba9afeaa23ac..25d3aaebc10d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = {
.release = single_release,
};
#endif
-static int get_ac_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct acpi_ac *ac = to_acpi_ac(psy);
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = ac->state;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-static enum power_supply_property ac_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
/* --------------------------------------------------------------------------
AC Adapter Management
-------------------------------------------------------------------------- */
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
return 0;
}
+/* --------------------------------------------------------------------------
+ sysfs I/F
+ -------------------------------------------------------------------------- */
+static int get_ac_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct acpi_ac *ac = to_acpi_ac(psy);
+
+ if (!ac)
+ return -ENODEV;
+
+ if (acpi_ac_get_state(ac))
+ return -ENODEV;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = ac->state;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
#ifdef CONFIG_ACPI_PROCFS_POWER
/* --------------------------------------------------------------------------
FS Interface (/proc)
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
new file mode 100644
index 000000000000..f40acef80269
--- /dev/null
+++ b/drivers/acpi/acpi_ipmi.c
@@ -0,0 +1,525 @@
+/*
+ * acpi_ipmi.c - ACPI IPMI opregion
+ *
+ * Copyright (C) 2010 Intel Corporation
+ * Copyright (C) 2010 Zhao Yakui <yakui.zhao@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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/ipmi.h>
+#include <linux/device.h>
+#include <linux/pnp.h>
+
+MODULE_AUTHOR("Zhao Yakui");
+MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
+MODULE_LICENSE("GPL");
+
+#define IPMI_FLAGS_HANDLER_INSTALL 0
+
+#define ACPI_IPMI_OK 0
+#define ACPI_IPMI_TIMEOUT 0x10
+#define ACPI_IPMI_UNKNOWN 0x07
+/* the IPMI timeout is 5s */
+#define IPMI_TIMEOUT (5 * HZ)
+
+struct acpi_ipmi_device {
+ /* the device list attached to driver_data.ipmi_devices */
+ struct list_head head;
+ /* the IPMI request message list */
+ struct list_head tx_msg_list;
+ struct mutex tx_msg_lock;
+ acpi_handle handle;
+ struct pnp_dev *pnp_dev;
+ ipmi_user_t user_interface;
+ int ipmi_ifnum; /* IPMI interface number */
+ long curr_msgid;
+ unsigned long flags;
+ struct ipmi_smi_info smi_data;
+};
+
+struct ipmi_driver_data {
+ struct list_head ipmi_devices;
+ struct ipmi_smi_watcher bmc_events;
+ struct ipmi_user_hndl ipmi_hndlrs;
+ struct mutex ipmi_lock;
+};
+
+struct acpi_ipmi_msg {
+ struct list_head head;
+ /*
+ * General speaking the addr type should be SI_ADDR_TYPE. And
+ * the addr channel should be BMC.
+ * In fact it can also be IPMB type. But we will have to
+ * parse it from the Netfn command buffer. It is so complex
+ * that it is skipped.
+ */
+ struct ipmi_addr addr;
+ long tx_msgid;
+ /* it is used to track whether the IPMI message is finished */
+ struct completion tx_complete;
+ struct kernel_ipmi_msg tx_message;
+ int msg_done;
+ /* tx data . And copy it from ACPI object buffer */
+ u8 tx_data[64];
+ int tx_len;
+ u8 rx_data[64];
+ int rx_len;
+ struct acpi_ipmi_device *device;
+};
+
+/* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */
+struct acpi_ipmi_buffer {
+ u8 status;
+ u8 length;
+ u8 data[64];
+};
+
+static void ipmi_register_bmc(int iface, struct device *dev);
+static void ipmi_bmc_gone(int iface);
+static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
+static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device);
+static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device);
+
+static struct ipmi_driver_data driver_data = {
+ .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices),
+ .bmc_events = {
+ .owner = THIS_MODULE,
+ .new_smi = ipmi_register_bmc,
+ .smi_gone = ipmi_bmc_gone,
+ },
+ .ipmi_hndlrs = {
+ .ipmi_recv_hndl = ipmi_msg_handler,
+ },
+};
+
+static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi)
+{
+ struct acpi_ipmi_msg *ipmi_msg;
+ struct pnp_dev *pnp_dev = ipmi->pnp_dev;
+
+ ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL);
+ if (!ipmi_msg) {
+ dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n");
+ return NULL;
+ }
+ init_completion(&ipmi_msg->tx_complete);
+ INIT_LIST_HEAD(&ipmi_msg->head);
+ ipmi_msg->device = ipmi;
+ return ipmi_msg;
+}
+
+#define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff)
+#define IPMI_OP_RGN_CMD(offset) (offset & 0xff)
+static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg,
+ acpi_physical_address address,
+ acpi_integer *value)
+{
+ struct kernel_ipmi_msg *msg;
+ struct acpi_ipmi_buffer *buffer;
+ struct acpi_ipmi_device *device;
+
+ msg = &tx_msg->tx_message;
+ /*
+ * IPMI network function and command are encoded in the address
+ * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3.
+ */
+ msg->netfn = IPMI_OP_RGN_NETFN(address);
+ msg->cmd = IPMI_OP_RGN_CMD(address);
+ msg->data = tx_msg->tx_data;
+ /*
+ * value is the parameter passed by the IPMI opregion space handler.
+ * It points to the IPMI request message buffer
+ */
+ buffer = (struct acpi_ipmi_buffer *)value;
+ /* copy the tx message data */
+ msg->data_len = buffer->length;
+ memcpy(tx_msg->tx_data, buffer->data, msg->data_len);
+ /*
+ * now the default type is SYSTEM_INTERFACE and channel type is BMC.
+ * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE,
+ * the addr type should be changed to IPMB. Then we will have to parse
+ * the IPMI request message buffer to get the IPMB address.
+ * If so, please fix me.
+ */
+ tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+ tx_msg->addr.channel = IPMI_BMC_CHANNEL;
+ tx_msg->addr.data[0] = 0;
+
+ /* Get the msgid */
+ device = tx_msg->device;
+ mutex_lock(&device->tx_msg_lock);
+ device->curr_msgid++;
+ tx_msg->tx_msgid = device->curr_msgid;
+ mutex_unlock(&device->tx_msg_lock);
+}
+
+static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg,
+ acpi_integer *value, int rem_time)
+{
+ struct acpi_ipmi_buffer *buffer;
+
+ /*
+ * value is also used as output parameter. It represents the response
+ * IPMI message returned by IPMI command.
+ */
+ buffer = (struct acpi_ipmi_buffer *)value;
+ if (!rem_time && !msg->msg_done) {
+ buffer->status = ACPI_IPMI_TIMEOUT;
+ return;
+ }
+ /*
+ * If the flag of msg_done is not set or the recv length is zero, it
+ * means that the IPMI command is not executed correctly.
+ * The status code will be ACPI_IPMI_UNKNOWN.
+ */
+ if (!msg->msg_done || !msg->rx_len) {
+ buffer->status = ACPI_IPMI_UNKNOWN;
+ return;
+ }
+ /*
+ * If the IPMI response message is obtained correctly, the status code
+ * will be ACPI_IPMI_OK
+ */
+ buffer->status = ACPI_IPMI_OK;
+ buffer->length = msg->rx_len;
+ memcpy(buffer->data, msg->rx_data, msg->rx_len);
+}
+
+static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
+{
+ struct acpi_ipmi_msg *tx_msg, *temp;
+ int count = HZ / 10;
+ struct pnp_dev *pnp_dev = ipmi->pnp_dev;
+
+ list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) {
+ /* wake up the sleep thread on the Tx msg */
+ complete(&tx_msg->tx_complete);
+ }
+
+ /* wait for about 100ms to flush the tx message list */
+ while (count--) {
+ if (list_empty(&ipmi->tx_msg_list))
+ break;
+ schedule_timeout(1);
+ }
+ if (!list_empty(&ipmi->tx_msg_list))
+ dev_warn(&pnp_dev->dev, "tx msg list is not NULL\n");
+}
+
+static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
+{
+ struct acpi_ipmi_device *ipmi_device = user_msg_data;
+ int msg_found = 0;
+ struct acpi_ipmi_msg *tx_msg;
+ struct pnp_dev *pnp_dev = ipmi_device->pnp_dev;
+
+ if (msg->user != ipmi_device->user_interface) {
+ dev_warn(&pnp_dev->dev, "Unexpected response is returned. "
+ "returned user %p, expected user %p\n",
+ msg->user, ipmi_device->user_interface);
+ ipmi_free_recv_msg(msg);
+ return;
+ }
+ mutex_lock(&ipmi_device->tx_msg_lock);
+ list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) {
+ if (msg->msgid == tx_msg->tx_msgid) {
+ msg_found = 1;
+ break;
+ }
+ }
+
+ mutex_unlock(&ipmi_device->tx_msg_lock);
+ if (!msg_found) {
+ dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is "
+ "returned.\n", msg->msgid);
+ ipmi_free_recv_msg(msg);
+ return;
+ }
+
+ if (msg->msg.data_len) {
+ /* copy the response data to Rx_data buffer */
+ memcpy(tx_msg->rx_data, msg->msg_data, msg->msg.data_len);
+ tx_msg->rx_len = msg->msg.data_len;
+ tx_msg->msg_done = 1;
+ }
+ complete(&tx_msg->tx_complete);
+ ipmi_free_recv_msg(msg);
+};
+
+static void ipmi_register_bmc(int iface, struct device *dev)
+{
+ struct acpi_ipmi_device *ipmi_device, *temp;
+ struct pnp_dev *pnp_dev;
+ ipmi_user_t user;
+ int err;
+ struct ipmi_smi_info smi_data;
+ acpi_handle handle;
+
+ err = ipmi_get_smi_info(iface, &smi_data);
+
+ if (err)
+ return;
+
+ if (smi_data.addr_src != SI_ACPI) {
+ put_device(smi_data.dev);
+ return;
+ }
+
+ handle = smi_data.addr_info.acpi_info.acpi_handle;
+
+ mutex_lock(&driver_data.ipmi_lock);
+ list_for_each_entry(temp, &driver_data.ipmi_devices, head) {
+ /*
+ * if the corresponding ACPI handle is already added
+ * to the device list, don't add it again.
+ */
+ if (temp->handle == handle)
+ goto out;
+ }
+
+ ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL);
+
+ if (!ipmi_device)
+ goto out;
+
+ pnp_dev = to_pnp_dev(smi_data.dev);
+ ipmi_device->handle = handle;
+ ipmi_device->pnp_dev = pnp_dev;
+
+ err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs,
+ ipmi_device, &user);
+ if (err) {
+ dev_warn(&pnp_dev->dev, "Can't create IPMI user interface\n");
+ kfree(ipmi_device);
+ goto out;
+ }
+ acpi_add_ipmi_device(ipmi_device);
+ ipmi_device->user_interface = user;
+ ipmi_device->ipmi_ifnum = iface;
+ mutex_unlock(&driver_data.ipmi_lock);
+ memcpy(&ipmi_device->smi_data, &smi_data, sizeof(struct ipmi_smi_info));
+ return;
+
+out:
+ mutex_unlock(&driver_data.ipmi_lock);
+ put_device(smi_data.dev);
+ return;
+}
+
+static void ipmi_bmc_gone(int iface)
+{
+ struct acpi_ipmi_device *ipmi_device, *temp;
+
+ mutex_lock(&driver_data.ipmi_lock);
+ list_for_each_entry_safe(ipmi_device, temp,
+ &driver_data.ipmi_devices, head) {
+ if (ipmi_device->ipmi_ifnum != iface)
+ continue;
+
+ acpi_remove_ipmi_device(ipmi_device);
+ put_device(ipmi_device->smi_data.dev);
+ kfree(ipmi_device);
+ break;
+ }
+ mutex_unlock(&driver_data.ipmi_lock);
+}
+/* --------------------------------------------------------------------------
+ * Address Space Management
+ * -------------------------------------------------------------------------- */
+/*
+ * This is the IPMI opregion space handler.
+ * @function: indicates the read/write. In fact as the IPMI message is driven
+ * by command, only write is meaningful.
+ * @address: This contains the netfn/command of IPMI request message.
+ * @bits : not used.
+ * @value : it is an in/out parameter. It points to the IPMI message buffer.
+ * Before the IPMI message is sent, it represents the actual request
+ * IPMI message. After the IPMI message is finished, it represents
+ * the response IPMI message returned by IPMI command.
+ * @handler_context: IPMI device context.
+ */
+
+static acpi_status
+acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
+ u32 bits, acpi_integer *value,
+ void *handler_context, void *region_context)
+{
+ struct acpi_ipmi_msg *tx_msg;
+ struct acpi_ipmi_device *ipmi_device = handler_context;
+ int err, rem_time;
+ acpi_status status;
+ /*
+ * IPMI opregion message.
+ * IPMI message is firstly written to the BMC and system software
+ * can get the respsonse. So it is unmeaningful for the read access
+ * of IPMI opregion.
+ */
+ if ((function & ACPI_IO_MASK) == ACPI_READ)
+ return AE_TYPE;
+
+ if (!ipmi_device->user_interface)
+ return AE_NOT_EXIST;
+
+ tx_msg = acpi_alloc_ipmi_msg(ipmi_device);
+ if (!tx_msg)
+ return AE_NO_MEMORY;
+
+ acpi_format_ipmi_msg(tx_msg, address, value);
+ mutex_lock(&ipmi_device->tx_msg_lock);
+ list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list);
+ mutex_unlock(&ipmi_device->tx_msg_lock);
+ err = ipmi_request_settime(ipmi_device->user_interface,
+ &tx_msg->addr,
+ tx_msg->tx_msgid,
+ &tx_msg->tx_message,
+ NULL, 0, 0, 0);
+ if (err) {
+ status = AE_ERROR;
+ goto end_label;
+ }
+ rem_time = wait_for_completion_timeout(&tx_msg->tx_complete,
+ IPMI_TIMEOUT);
+ acpi_format_ipmi_response(tx_msg, value, rem_time);
+ status = AE_OK;
+
+end_label:
+ mutex_lock(&ipmi_device->tx_msg_lock);
+ list_del(&tx_msg->head);
+ mutex_unlock(&ipmi_device->tx_msg_lock);
+ kfree(tx_msg);
+ return status;
+}
+
+static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi)
+{
+ if (!test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags))
+ return;
+
+ acpi_remove_address_space_handler(ipmi->handle,
+ ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler);
+
+ clear_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags);
+}
+
+static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi)
+{
+ acpi_status status;
+
+ if (test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags))
+ return 0;
+
+ status = acpi_install_address_space_handler(ipmi->handle,
+ ACPI_ADR_SPACE_IPMI,
+ &acpi_ipmi_space_handler,
+ NULL, ipmi);
+ if (ACPI_FAILURE(status)) {
+ struct pnp_dev *pnp_dev = ipmi->pnp_dev;
+ dev_warn(&pnp_dev->dev, "Can't register IPMI opregion space "
+ "handle\n");
+ return -EINVAL;
+ }
+ set_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags);
+ return 0;
+}
+
+static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device)
+{
+
+ INIT_LIST_HEAD(&ipmi_device->head);
+
+ mutex_init(&ipmi_device->tx_msg_lock);
+ INIT_LIST_HEAD(&ipmi_device->tx_msg_list);
+ ipmi_install_space_handler(ipmi_device);
+
+ list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices);
+}
+
+static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device)
+{
+ /*
+ * If the IPMI user interface is created, it should be
+ * destroyed.
+ */
+ if (ipmi_device->user_interface) {
+ ipmi_destroy_user(ipmi_device->user_interface);
+ ipmi_device->user_interface = NULL;
+ }
+ /* flush the Tx_msg list */
+ if (!list_empty(&ipmi_device->tx_msg_list))
+ ipmi_flush_tx_msg(ipmi_device);
+
+ list_del(&ipmi_device->head);
+ ipmi_remove_space_handler(ipmi_device);
+}
+
+static int __init acpi_ipmi_init(void)
+{
+ int result = 0;
+
+ if (acpi_disabled)
+ return result;
+
+ mutex_init(&driver_data.ipmi_lock);
+
+ result = ipmi_smi_watcher_register(&driver_data.bmc_events);
+
+ return result;
+}
+
+static void __exit acpi_ipmi_exit(void)
+{
+ struct acpi_ipmi_device *ipmi_device, *temp;
+
+ if (acpi_disabled)
+ return;
+
+ ipmi_smi_watcher_unregister(&driver_data.bmc_events);
+
+ /*
+ * When one smi_watcher is unregistered, it is only deleted
+ * from the smi_watcher list. But the smi_gone callback function
+ * is not called. So explicitly uninstall the ACPI IPMI oregion
+ * handler and free it.
+ */
+ mutex_lock(&driver_data.ipmi_lock);
+ list_for_each_entry_safe(ipmi_device, temp,
+ &driver_data.ipmi_devices, head) {
+ acpi_remove_ipmi_device(ipmi_device);
+ put_device(ipmi_device->smi_data.dev);
+ kfree(ipmi_device);
+ }
+ mutex_unlock(&driver_data.ipmi_lock);
+}
+
+module_init(acpi_ipmi_init);
+module_exit(acpi_ipmi_exit);
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index a7e1d1aa4107..eec2eadd2431 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
evmisc.o evrgnini.o evxface.o evxfregn.o \
- evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o
+ evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o
acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index a6f99cc37a19..70e0b28801aa 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void);
acpi_status acpi_ev_install_xrupt_handlers(void);
-acpi_status acpi_ev_install_fadt_gpes(void);
-
u32 acpi_ev_fixed_event_detect(void);
/*
@@ -82,9 +80,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
u32 gpe_number);
@@ -93,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
struct acpi_gpe_block_info
*gpe_block);
+acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info);
+
/*
* evgpeblk - Upper-level GPE block support
*/
@@ -107,12 +107,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
acpi_status
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block,
- void *ignored);
+ void *context);
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
u32
-acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
+acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
+ struct acpi_gpe_event_info *gpe_event_info,
u32 gpe_number);
/*
@@ -126,10 +127,6 @@ acpi_status
acpi_ev_match_gpe_method(acpi_handle obj_handle,
u32 level, void *context, void **return_value);
-acpi_status
-acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
- u32 level, void *context, void **return_value);
-
/*
* evgpeutil - GPE utilities
*/
@@ -138,6 +135,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status
+acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block, void *context);
+
struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number);
acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ad88fcae4eb9..9bb69c59bb12 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running;
extern u32 acpi_gbl_nesting_level;
+ACPI_EXTERN u32 acpi_gpe_count;
+ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
+
/* Support for dynamic control method tracing mechanism */
ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
@@ -370,7 +373,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler
ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
ACPI_EXTERN struct acpi_gpe_block_info
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
-ACPI_EXTERN u8 acpi_all_gpes_initialized;
+ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
+ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
+ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
/*****************************************************************************
*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 167470ad2d21..258d628793ea 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
struct acpi_gpe_register_info *gpe_register_info);
acpi_status
-acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action);
+acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
acpi_status
acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 2ceb0c05b2d7..74000f5b7dab 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -408,17 +408,18 @@ struct acpi_predefined_data {
/* Dispatch info for each GPE -- either a method or handler, cannot be both */
-struct acpi_handler_info {
- acpi_event_handler address; /* Address of handler, if any */
+struct acpi_gpe_handler_info {
+ acpi_gpe_handler address; /* Address of handler, if any */
void *context; /* Context to be passed to handler */
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
- u8 orig_flags; /* Original misc info about this GPE */
- u8 orig_enabled; /* Set if the GPE was originally enabled */
+ u8 original_flags; /* Original (pre-handler) GPE info */
+ u8 originally_enabled; /* True if GPE was originally enabled */
};
union acpi_gpe_dispatch_info {
struct acpi_namespace_node *method_node; /* Method node for this GPE level */
- struct acpi_handler_info *handler;
+ struct acpi_gpe_handler_info *handler; /* Installed GPE handler */
+ struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */
};
/*
@@ -458,7 +459,7 @@ struct acpi_gpe_block_info {
u32 register_count; /* Number of register pairs in block */
u16 gpe_count; /* Number of individual GPEs in block */
u8 block_base_number; /* Base GPE number for this block */
- u8 initialized; /* If set, the GPE block has been initialized */
+ u8 initialized; /* TRUE if this block is initialized */
};
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index c61c3039c31a..e5e313c663a5 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void)
status_bit_mask)
&& (fixed_enable & acpi_gbl_fixed_event_info[i].
enable_bit_mask)) {
+ /*
+ * Found an active (signalled) event. Invoke global event
+ * handler if present.
+ */
+ acpi_fixed_event_count[i]++;
+ if (acpi_gbl_global_event_handler) {
+ acpi_gbl_global_event_handler
+ (ACPI_EVENT_TYPE_FIXED, NULL, i,
+ acpi_gbl_global_event_handler_context);
+ }
- /* Found an active (signalled) event */
- acpi_os_fixed_event_count(i);
int_status |= acpi_ev_fixed_event_dispatch(i);
}
}
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f226eac314db..7c339d34ab42 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe")
/* Local prototypes */
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context);
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_update_gpe_enable_mask
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
*
* RETURN: Status
*
- * DESCRIPTION: Clear the given GPE from stale events and enable it.
+ * DESCRIPTION: Clear a GPE of stale events and enable it.
*
******************************************************************************/
acpi_status
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
ACPI_FUNCTION_TRACE(ev_enable_gpe);
/*
- * We will only allow a GPE to be enabled if it has either an
- * associated method (_Lxx/_Exx) or a handler. Otherwise, the
- * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
- * first time it fires.
+ * We will only allow a GPE to be enabled if it has either an associated
+ * method (_Lxx/_Exx) or a handler, or is using the implicit notify
+ * feature. Otherwise, the GPE will be immediately disabled by
+ * acpi_ev_gpe_dispatch the first time it fires.
*/
- if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE) {
return_ACPI_STATUS(AE_NO_HANDLER);
}
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/*******************************************************************************
*
- * FUNCTION: acpi_raw_enable_gpe
+ * FUNCTION: acpi_ev_add_gpe_reference
*
- * PARAMETERS: gpe_event_info - GPE to enable
+ * PARAMETERS: gpe_event_info - Add a reference to this GPE
*
* RETURN: Status
*
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
*
******************************************************************************/
-acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE(ev_add_gpe_reference);
+
if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
return_ACPI_STATUS(AE_LIMIT);
}
gpe_event_info->runtime_count++;
if (gpe_event_info->runtime_count == 1) {
+
+ /* Enable on first reference */
+
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status = acpi_ev_enable_gpe(gpe_event_info);
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/*******************************************************************************
*
- * FUNCTION: acpi_raw_disable_gpe
+ * FUNCTION: acpi_ev_remove_gpe_reference
*
- * PARAMETERS: gpe_event_info - GPE to disable
+ * PARAMETERS: gpe_event_info - Remove a reference to this GPE
*
* RETURN: Status
*
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
*
******************************************************************************/
-acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
+ ACPI_FUNCTION_TRACE(ev_remove_gpe_reference);
+
if (!gpe_event_info->runtime_count) {
return_ACPI_STATUS(AE_LIMIT);
}
gpe_event_info->runtime_count--;
if (!gpe_event_info->runtime_count) {
+
+ /* Disable on last reference */
+
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status = acpi_hw_low_set_gpe(gpe_event_info,
@@ -379,7 +392,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
}
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
- "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+ "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
gpe_register_info->base_gpe_number,
status_reg, enable_reg));
@@ -405,7 +418,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
* or method.
*/
int_status |=
- acpi_ev_gpe_dispatch(&gpe_block->
+ acpi_ev_gpe_dispatch(gpe_block->
+ node,
+ &gpe_block->
event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
}
}
@@ -435,17 +450,25 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
* an interrupt handler.
*
******************************************************************************/
-static void acpi_ev_asynch_enable_gpe(void *context);
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
- struct acpi_gpe_event_info *gpe_event_info = (void *)context;
+ struct acpi_gpe_event_info *gpe_event_info = context;
acpi_status status;
- struct acpi_gpe_event_info local_gpe_event_info;
+ struct acpi_gpe_event_info *local_gpe_event_info;
struct acpi_evaluate_info *info;
ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
+ /* Allocate a local GPE block */
+
+ local_gpe_event_info =
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
+ if (!local_gpe_event_info) {
+ ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
+ return_VOID;
+ }
+
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
return_VOID;
@@ -462,7 +485,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
* Take a snapshot of the GPE info for this level - we copy the info to
* prevent a race condition with remove_handler/remove_block.
*/
- ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
+ ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
sizeof(struct acpi_gpe_event_info));
status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
@@ -470,12 +493,26 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
return_VOID;
}
- /*
- * Must check for control method type dispatch one more time to avoid a
- * race with ev_gpe_install_handler
- */
- if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD) {
+ /* Do the correct dispatch - normal method or implicit notify */
+
+ switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
+ case ACPI_GPE_DISPATCH_NOTIFY:
+
+ /*
+ * Implicit notify.
+ * Dispatch a DEVICE_WAKE notify to the appropriate handler.
+ * NOTE: the request is queued for execution after this method
+ * completes. The notify handlers are NOT invoked synchronously
+ * from this thread -- because handlers may in turn run other
+ * control methods.
+ */
+ status =
+ acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
+ device_node,
+ ACPI_NOTIFY_DEVICE_WAKE);
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
/* Allocate the evaluation information block */
@@ -488,7 +525,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
* control method that corresponds to this GPE
*/
info->prefix_node =
- local_gpe_event_info.dispatch.method_node;
+ local_gpe_event_info->dispatch.method_node;
info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info);
@@ -499,46 +536,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
ACPI_EXCEPTION((AE_INFO, status,
"while evaluating GPE method [%4.4s]",
acpi_ut_get_node_name
- (local_gpe_event_info.dispatch.
+ (local_gpe_event_info->dispatch.
method_node)));
}
+
+ break;
+
+ default:
+ return_VOID; /* Should never happen */
}
+
/* Defer enabling of GPE until all notify handlers are done */
- acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
- gpe_event_info);
+
+ status = acpi_os_execute(OSL_NOTIFY_HANDLER,
+ acpi_ev_asynch_enable_gpe,
+ local_gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_FREE(local_gpe_event_info);
+ }
return_VOID;
}
-static void acpi_ev_asynch_enable_gpe(void *context)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_asynch_enable_gpe
+ *
+ * PARAMETERS: Context (gpe_event_info) - Info for this GPE
+ * Callback from acpi_os_execute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
+ * complete (i.e., finish execution of Notify)
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
{
struct acpi_gpe_event_info *gpe_event_info = context;
+
+ (void)acpi_ev_finish_gpe(gpe_event_info);
+
+ ACPI_FREE(gpe_event_info);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_finish_gpe
+ *
+ * PARAMETERS: gpe_event_info - Info for this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
+ * of a GPE method or a synchronous or asynchronous GPE handler.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
+{
acpi_status status;
+
if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_LEVEL_TRIGGERED) {
/*
- * GPE is level-triggered, we clear the GPE status bit after handling
- * the event.
+ * GPE is level-triggered, we clear the GPE status bit after
+ * handling the event.
*/
status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
- return_VOID;
+ return (status);
}
}
/*
- * Enable this GPE, conditionally. This means that the GPE will only be
- * physically enabled if the enable_for_run bit is set in the event_info
+ * Enable this GPE, conditionally. This means that the GPE will
+ * only be physically enabled if the enable_for_run bit is set
+ * in the event_info.
*/
- (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE);
-
- return_VOID;
+ (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
+ return (AE_OK);
}
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_dispatch
*
- * PARAMETERS: gpe_event_info - Info for this GPE
+ * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
+ * gpe_event_info - Info for this GPE
* gpe_number - Number relative to the parent GPE block
*
* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -551,13 +640,22 @@ static void acpi_ev_asynch_enable_gpe(void *context)
******************************************************************************/
u32
-acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
+acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
+ struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
{
acpi_status status;
+ u32 return_value;
ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
- acpi_os_gpe_count(gpe_number);
+ /* Invoke global event handler if present */
+
+ acpi_gpe_count++;
+ if (acpi_gbl_global_event_handler) {
+ acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
+ gpe_number,
+ acpi_gbl_global_event_handler_context);
+ }
/*
* If edge-triggered, clear the GPE status bit now. Note that
@@ -568,59 +666,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
- "Unable to clear GPE[0x%2X]",
- gpe_number));
+ "Unable to clear GPE%02X", gpe_number));
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
}
}
/*
- * Dispatch the GPE to either an installed handler, or the control method
- * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
- * it and do not attempt to run the method. If there is neither a handler
- * nor a method, we disable this GPE to prevent further such pointless
- * events from firing.
+ * Always disable the GPE so that it does not keep firing before
+ * any asynchronous activity completes (either from the execution
+ * of a GPE method or an asynchronous GPE handler.)
+ *
+ * If there is no handler or method to run, just disable the
+ * GPE and leave it disabled permanently to prevent further such
+ * pointless events from firing.
+ */
+ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Unable to disable GPE%02X", gpe_number));
+ return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+ }
+
+ /*
+ * Dispatch the GPE to either an installed handler or the control
+ * method associated with this GPE (_Lxx or _Exx). If a handler
+ * exists, we invoke it and do not attempt to run the method.
+ * If there is neither a handler nor a method, leave the GPE
+ * disabled.
*/
switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
case ACPI_GPE_DISPATCH_HANDLER:
- /*
- * Invoke the installed handler (at interrupt level)
- * Ignore return status for now.
- * TBD: leave GPE disabled on error?
- */
- (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
- dispatch.
- handler->
- context);
+ /* Invoke the installed handler (at interrupt level) */
- /* It is now safe to clear level-triggered events. */
+ return_value =
+ gpe_event_info->dispatch.handler->address(gpe_device,
+ gpe_number,
+ gpe_event_info->
+ dispatch.handler->
+ context);
- if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_LEVEL_TRIGGERED) {
- status = acpi_hw_clear_gpe(gpe_event_info);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "Unable to clear GPE[0x%2X]",
- gpe_number));
- return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
- }
+ /* If requested, clear (if level-triggered) and reenable the GPE */
+
+ if (return_value & ACPI_REENABLE_GPE) {
+ (void)acpi_ev_finish_gpe(gpe_event_info);
}
break;
case ACPI_GPE_DISPATCH_METHOD:
-
- /*
- * Disable the GPE, so it doesn't keep firing before the method has a
- * chance to run (it runs asynchronously with interrupts enabled).
- */
- status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "Unable to disable GPE[0x%2X]",
- gpe_number));
- return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
- }
+ case ACPI_GPE_DISPATCH_NOTIFY:
/*
* Execute the method associated with the GPE
@@ -631,7 +725,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
- "Unable to queue handler for GPE[0x%2X] - event disabled",
+ "Unable to queue handler for GPE%2X - event disabled",
gpe_number));
}
break;
@@ -644,20 +738,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
* a GPE to be enabled if it has no handler or method.
*/
ACPI_ERROR((AE_INFO,
- "No handler or method for GPE[0x%2X], disabling event",
+ "No handler or method for GPE%02X, disabling event",
gpe_number));
- /*
- * Disable the GPE. The GPE will remain disabled a handler
- * is installed or ACPICA is restarted.
- */
- status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "Unable to disable GPE[0x%2X]",
- gpe_number));
- return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
- }
break;
}
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 020add3eee1c..9acb86958c09 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -361,9 +361,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_block->node = gpe_device;
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
+ gpe_block->initialized = FALSE;
gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number;
- gpe_block->initialized = FALSE;
ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
sizeof(struct acpi_generic_address));
@@ -386,7 +386,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
return_ACPI_STATUS(status);
}
- acpi_all_gpes_initialized = FALSE;
+ acpi_gbl_all_gpes_initialized = FALSE;
/* Find all GPE methods (_Lxx or_Exx) for this block */
@@ -423,14 +423,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
*
* FUNCTION: acpi_ev_initialize_gpe_block
*
- * PARAMETERS: gpe_device - Handle to the parent GPE block
- * gpe_block - Gpe Block info
+ * PARAMETERS: acpi_gpe_callback
*
* RETURN: Status
*
- * DESCRIPTION: Initialize and enable a GPE block. First find and run any
- * _PRT methods associated with the block, then enable the
- * appropriate GPEs.
+ * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
+ * associated methods.
* Note: Assumes namespace is locked.
*
******************************************************************************/
@@ -450,8 +448,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
/*
- * Ignore a null GPE block (e.g., if no GPE block 1 exists) and
- * GPE blocks that have been initialized already.
+ * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
+ * any GPE blocks that have been initialized already.
*/
if (!gpe_block || gpe_block->initialized) {
return_ACPI_STATUS(AE_OK);
@@ -459,8 +457,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
/*
* Enable all GPEs that have a corresponding method and have the
- * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must
- * be enabled via the acpi_enable_gpe() interface.
+ * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
+ * must be enabled via the acpi_enable_gpe() interface.
*/
gpe_enabled_count = 0;
@@ -472,14 +470,19 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
gpe_event_info = &gpe_block->event_info[gpe_index];
- /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
-
- if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
+ /*
+ * Ignore GPEs that have no corresponding _Lxx/_Exx method
+ * and GPEs that are used to wake the system
+ */
+ if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
+ || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
+ == ACPI_GPE_DISPATCH_HANDLER)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
continue;
}
- status = acpi_raw_enable_gpe(gpe_event_info);
+ status = acpi_ev_add_gpe_reference(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X",
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c
index 2c7def95f721..c59dc2340593 100644
--- a/drivers/acpi/acpica/evgpeinit.c
+++ b/drivers/acpi/acpica/evgpeinit.c
@@ -45,11 +45,27 @@
#include "accommon.h"
#include "acevents.h"
#include "acnamesp.h"
-#include "acinterp.h"
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evgpeinit")
+/*
+ * Note: History of _PRW support in ACPICA
+ *
+ * Originally (2000 - 2010), the GPE initialization code performed a walk of
+ * the entire namespace to execute the _PRW methods and detect all GPEs
+ * capable of waking the system.
+ *
+ * As of 10/2010, the _PRW method execution has been removed since it is
+ * actually unnecessary. The host OS must in fact execute all _PRW methods
+ * in order to identify the device/power-resource dependencies. We now put
+ * the onus on the host OS to identify the wake GPEs as part of this process
+ * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This
+ * not only reduces the complexity of the ACPICA initialization code, but in
+ * some cases (on systems with very large namespaces) it should reduce the
+ * kernel boot time as well.
+ */
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_initialize
@@ -222,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
acpi_status status = AE_OK;
/*
- * 2) Find any _Lxx/_Exx GPE methods that have just been loaded.
+ * Find any _Lxx/_Exx GPE methods that have just been loaded.
*
* Any GPEs that correspond to new _Lxx/_Exx methods are immediately
* enabled.
@@ -235,9 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
return;
}
+ walk_info.count = 0;
walk_info.owner_id = table_owner_id;
walk_info.execute_by_owner_id = TRUE;
- walk_info.count = 0;
/* Walk the interrupt level descriptor list */
@@ -298,7 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
* xx - is the GPE number [in HEX]
*
* If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
- * with that owner.
+ * with that owner.
*
******************************************************************************/
@@ -408,10 +424,14 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
return_ACPI_STATUS(AE_OK);
}
+ /* Disable the GPE in case it's been enabled already. */
+ (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+
/*
* Add the GPE information from above to the gpe_event_info block for
* use during dispatch of this GPE.
*/
+ gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
gpe_event_info->dispatch.method_node = method_node;
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c
index 19a0e513ea48..10e477494dcf 100644
--- a/drivers/acpi/acpica/evgpeutil.c
+++ b/drivers/acpi/acpica/evgpeutil.c
@@ -154,6 +154,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
/*******************************************************************************
*
+ * FUNCTION: acpi_ev_get_gpe_device
+ *
+ * PARAMETERS: GPE_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
+ * block device. NULL if the GPE is one of the FADT-defined GPEs.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block, void *context)
+{
+ struct acpi_gpe_device_info *info = context;
+
+ /* Increment Index by the number of GPEs in this block */
+
+ info->next_block_base_index += gpe_block->gpe_count;
+
+ if (info->index < info->next_block_base_index) {
+ /*
+ * The GPE index is within this block, get the node. Leave the node
+ * NULL for the FADT-defined GPEs
+ */
+ if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
+ info->gpe_device = gpe_block->node;
+ }
+
+ info->status = AE_OK;
+ return (AE_CTRL_END);
+ }
+
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ev_get_gpe_xrupt_block
*
* PARAMETERS: interrupt_number - Interrupt for a GPE block
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 36af222cac65..1226689bdb1b 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
#endif /* ACPI_FUTURE_USAGE */
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_install_global_event_handler
+ *
+ * PARAMETERS: Handler - Pointer to the global event handler function
+ * Context - Value passed to the handler on each event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function. The global handler
+ * is invoked upon each incoming GPE and Fixed Event. It is
+ * invoked at interrupt level at the time of the event dispatch.
+ * Can be used to update event counters, etc.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
+
+ /* Parameter validation */
+
+ if (!handler) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Don't allow two handlers. */
+
+ if (acpi_gbl_global_event_handler) {
+ status = AE_ALREADY_EXISTS;
+ goto cleanup;
+ }
+
+ acpi_gbl_global_event_handler = handler;
+ acpi_gbl_global_event_handler_context = context;
+
+ cleanup:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
+
/*******************************************************************************
*
* FUNCTION: acpi_install_fixed_event_handler
@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
acpi_status
acpi_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
- u32 type, acpi_event_handler address, void *context)
+ u32 type, acpi_gpe_handler address, void *context)
{
struct acpi_gpe_event_info *gpe_event_info;
- struct acpi_handler_info *handler;
+ struct acpi_gpe_handler_info *handler;
acpi_status status;
acpi_cpu_flags flags;
@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Allocate memory for the handler object */
- handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
+ handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
if (!handler) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
@@ -722,7 +773,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
handler->address = address;
handler->context = context;
handler->method_node = gpe_event_info->dispatch.method_node;
- handler->orig_flags = gpe_event_info->flags &
+ handler->original_flags = gpe_event_info->flags &
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
/*
@@ -731,10 +782,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
* disabled now to avoid spurious execution of the handler.
*/
- if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
+ if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
&& gpe_event_info->runtime_count) {
- handler->orig_enabled = 1;
- (void)acpi_raw_disable_gpe(gpe_event_info);
+ handler->originally_enabled = 1;
+ (void)acpi_ev_remove_gpe_reference(gpe_event_info);
}
/* Install the handler */
@@ -777,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
******************************************************************************/
acpi_status
acpi_remove_gpe_handler(acpi_handle gpe_device,
- u32 gpe_number, acpi_event_handler address)
+ u32 gpe_number, acpi_gpe_handler address)
{
struct acpi_gpe_event_info *gpe_event_info;
- struct acpi_handler_info *handler;
+ struct acpi_gpe_handler_info *handler;
acpi_status status;
acpi_cpu_flags flags;
@@ -835,7 +886,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
gpe_event_info->dispatch.method_node = handler->method_node;
gpe_event_info->flags &=
~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
- gpe_event_info->flags |= handler->orig_flags;
+ gpe_event_info->flags |= handler->original_flags;
/*
* If the GPE was previously associated with a method and it was
@@ -843,9 +894,9 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
* post-initialization configuration.
*/
- if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
- && handler->orig_enabled)
- (void)acpi_raw_enable_gpe(gpe_event_info);
+ if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
+ && handler->originally_enabled)
+ (void)acpi_ev_add_gpe_reference(gpe_event_info);
/* Now we can free the handler object */
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index a1dabe3fd8ae..90488c1e0f3d 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -43,18 +43,11 @@
#include <acpi/acpi.h>
#include "accommon.h"
-#include "acevents.h"
-#include "acnamesp.h"
#include "actables.h"
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evxfevnt")
-/* Local prototypes */
-static acpi_status
-acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block, void *context);
-
/*******************************************************************************
*
* FUNCTION: acpi_enable
@@ -213,185 +206,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
/*******************************************************************************
*
- * FUNCTION: acpi_gpe_wakeup
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- * Action - Enable or Disable
- *
- * RETURN: Status
- *
- * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
- *
- ******************************************************************************/
-acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
-{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
- struct acpi_gpe_register_info *gpe_register_info;
- acpi_cpu_flags flags;
- u32 register_bit;
-
- ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- gpe_register_info = gpe_event_info->register_info;
- if (!gpe_register_info) {
- status = AE_NOT_EXIST;
- goto unlock_and_exit;
- }
-
- register_bit =
- acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
-
- /* Perform the action */
-
- switch (action) {
- case ACPI_GPE_ENABLE:
- ACPI_SET_BIT(gpe_register_info->enable_for_wake,
- (u8)register_bit);
- break;
-
- case ACPI_GPE_DISABLE:
- ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
- (u8)register_bit);
- break;
-
- default:
- ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
- status = AE_BAD_PARAMETER;
- break;
- }
-
-unlock_and_exit:
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_enable_gpe
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
- * hardware-enabled.
- *
- ******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
- acpi_status status = AE_BAD_PARAMETER;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_cpu_flags flags;
-
- ACPI_FUNCTION_TRACE(acpi_enable_gpe);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (gpe_event_info) {
- status = acpi_raw_enable_gpe(gpe_event_info);
- }
-
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_disable_gpe
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Remove a reference to a GPE. When the last reference is
- * removed, only then is the GPE disabled (for runtime GPEs), or
- * the GPE mask bit disabled (for wake GPEs)
- *
- ******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
- acpi_status status = AE_BAD_PARAMETER;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_cpu_flags flags;
-
- ACPI_FUNCTION_TRACE(acpi_disable_gpe);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (gpe_event_info) {
- status = acpi_raw_disable_gpe(gpe_event_info) ;
- }
-
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_gpe_can_wake
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
- * has a corresponding method and is currently enabled, disable it
- * (GPEs with corresponding methods are enabled unconditionally
- * during initialization, but GPEs that can wake up are expected
- * to be initially disabled).
- *
- ******************************************************************************/
-acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
-{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_cpu_flags flags;
-
- ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (gpe_event_info) {
- gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
- } else {
- status = AE_BAD_PARAMETER;
- }
-
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
-
-/*******************************************************************************
- *
* FUNCTION: acpi_disable_event
*
* PARAMETERS: Event - The fixed eventto be enabled
@@ -483,44 +297,6 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event)
/*******************************************************************************
*
- * FUNCTION: acpi_clear_gpe
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Clear an ACPI event (general purpose)
- *
- ******************************************************************************/
-acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
-{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_cpu_flags flags;
-
- ACPI_FUNCTION_TRACE(acpi_clear_gpe);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (!gpe_event_info) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- status = acpi_hw_clear_gpe(gpe_event_info);
-
- unlock_and_exit:
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
-/*******************************************************************************
- *
* FUNCTION: acpi_get_event_status
*
* PARAMETERS: Event - The fixed event
@@ -575,379 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
}
ACPI_EXPORT_SYMBOL(acpi_get_event_status)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_get_gpe_status
- *
- * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
- * gpe_number - GPE level within the GPE block
- * event_status - Where the current status of the event will
- * be returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get status of an event (general purpose)
- *
- ******************************************************************************/
-acpi_status
-acpi_get_gpe_status(acpi_handle gpe_device,
- u32 gpe_number, acpi_event_status *event_status)
-{
- acpi_status status = AE_OK;
- struct acpi_gpe_event_info *gpe_event_info;
- acpi_cpu_flags flags;
-
- ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
-
- flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
-
- /* Ensure that we have a valid GPE number */
-
- gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
- if (!gpe_event_info) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- /* Obtain status on the requested GPE number */
-
- status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
-
- if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
- *event_status |= ACPI_EVENT_FLAG_HANDLE;
-
- unlock_and_exit:
- acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
-/*******************************************************************************
- *
- * FUNCTION: acpi_install_gpe_block
- *
- * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
- * gpe_block_address - Address and space_iD
- * register_count - Number of GPE register pairs in the block
- * interrupt_number - H/W interrupt for the block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create and Install a block of GPE registers
- *
- ******************************************************************************/
-acpi_status
-acpi_install_gpe_block(acpi_handle gpe_device,
- struct acpi_generic_address *gpe_block_address,
- u32 register_count, u32 interrupt_number)
-{
- acpi_status status = AE_OK;
- union acpi_operand_object *obj_desc;
- struct acpi_namespace_node *node;
- struct acpi_gpe_block_info *gpe_block;
-
- ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
-
- if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return (status);
- }
-
- node = acpi_ns_validate_handle(gpe_device);
- if (!node) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- /*
- * For user-installed GPE Block Devices, the gpe_block_base_number
- * is always zero
- */
- status =
- acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
- interrupt_number, &gpe_block);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
-
- /* Install block in the device_object attached to the node */
-
- obj_desc = acpi_ns_get_attached_object(node);
- if (!obj_desc) {
-
- /*
- * No object, create a new one (Device nodes do not always have
- * an attached object)
- */
- obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
- if (!obj_desc) {
- status = AE_NO_MEMORY;
- goto unlock_and_exit;
- }
-
- status =
- acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
-
- /* Remove local reference to the object */
-
- acpi_ut_remove_reference(obj_desc);
-
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
- }
-
- /* Now install the GPE block in the device_object */
-
- obj_desc->device.gpe_block = gpe_block;
-
- unlock_and_exit:
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_remove_gpe_block
- *
- * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
- *
- * RETURN: Status
- *
- * DESCRIPTION: Remove a previously installed block of GPE registers
- *
- ******************************************************************************/
-acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
-{
- union acpi_operand_object *obj_desc;
- acpi_status status;
- struct acpi_namespace_node *node;
-
- ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
-
- if (!gpe_device) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return (status);
- }
-
- node = acpi_ns_validate_handle(gpe_device);
- if (!node) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- /* Get the device_object attached to the node */
-
- obj_desc = acpi_ns_get_attached_object(node);
- if (!obj_desc || !obj_desc->device.gpe_block) {
- return_ACPI_STATUS(AE_NULL_OBJECT);
- }
-
- /* Delete the GPE block (but not the device_object) */
-
- status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
- if (ACPI_SUCCESS(status)) {
- obj_desc->device.gpe_block = NULL;
- }
-
- unlock_and_exit:
- (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_get_gpe_device
- *
- * PARAMETERS: Index - System GPE index (0-current_gpe_count)
- * gpe_device - Where the parent GPE Device is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
- * gpe device indicates that the gpe number is contained in one of
- * the FADT-defined gpe blocks. Otherwise, the GPE block device.
- *
- ******************************************************************************/
-acpi_status
-acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
-{
- struct acpi_gpe_device_info info;
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
-
- if (!gpe_device) {
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- if (index >= acpi_current_gpe_count) {
- return_ACPI_STATUS(AE_NOT_EXIST);
- }
-
- /* Setup and walk the GPE list */
-
- info.index = index;
- info.status = AE_NOT_EXIST;
- info.gpe_device = NULL;
- info.next_block_base_index = 0;
-
- status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- *gpe_device = info.gpe_device;
- return_ACPI_STATUS(info.status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ev_get_gpe_device
- *
- * PARAMETERS: GPE_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
- * block device. NULL if the GPE is one of the FADT-defined GPEs.
- *
- ******************************************************************************/
-static acpi_status
-acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block, void *context)
-{
- struct acpi_gpe_device_info *info = context;
-
- /* Increment Index by the number of GPEs in this block */
-
- info->next_block_base_index += gpe_block->gpe_count;
-
- if (info->index < info->next_block_base_index) {
- /*
- * The GPE index is within this block, get the node. Leave the node
- * NULL for the FADT-defined GPEs
- */
- if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
- info->gpe_device = gpe_block->node;
- }
-
- info->status = AE_OK;
- return (AE_CTRL_END);
- }
-
- return (AE_OK);
-}
-
-/******************************************************************************
- *
- * FUNCTION: acpi_disable_all_gpes
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
- *
- ******************************************************************************/
-
-acpi_status acpi_disable_all_gpes(void)
-{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- status = acpi_hw_disable_all_gpes();
- (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
- return_ACPI_STATUS(status);
-}
-
-/******************************************************************************
- *
- * FUNCTION: acpi_enable_all_runtime_gpes
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
- *
- ******************************************************************************/
-
-acpi_status acpi_enable_all_runtime_gpes(void)
-{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- status = acpi_hw_enable_all_runtime_gpes();
- (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
- return_ACPI_STATUS(status);
-}
-
-/******************************************************************************
- *
- * FUNCTION: acpi_update_gpes
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
- * are not pointed to by any device _PRW methods indicating that
- * these GPEs are generally intended for system or device wakeup
- * (such GPEs have to be enabled directly when the devices whose
- * _PRW methods point to them are set up for wakeup signaling).
- *
- ******************************************************************************/
-
-acpi_status acpi_update_gpes(void)
-{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(acpi_update_gpes);
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- } else if (acpi_all_gpes_initialized) {
- goto unlock;
- }
-
- status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
- if (ACPI_SUCCESS(status)) {
- acpi_all_gpes_initialized = TRUE;
- }
-
-unlock:
- (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-
- return_ACPI_STATUS(status);
-}
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
new file mode 100644
index 000000000000..416845bc9c1f
--- /dev/null
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -0,0 +1,669 @@
+/******************************************************************************
+ *
+ * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2010, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+
+#define _COMPONENT ACPI_EVENTS
+ACPI_MODULE_NAME("evxfgpe")
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_update_all_gpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
+ * associated _Lxx or _Exx methods and are not pointed to by any
+ * device _PRW methods (this indicates that these GPEs are
+ * generally intended for system or device wakeup. Such GPEs
+ * have to be enabled directly when the devices whose _PRW
+ * methods point to them are set up for wakeup signaling.)
+ *
+ * NOTE: Should be called after any GPEs are added to the system. Primarily,
+ * after the system _PRW methods have been run, but also after a GPE Block
+ * Device has been added or if any new GPE methods have been added via a
+ * dynamic table load.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_update_all_gpes(void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (acpi_gbl_all_gpes_initialized) {
+ goto unlock_and_exit;
+ }
+
+ status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
+ if (ACPI_SUCCESS(status)) {
+ acpi_gbl_all_gpes_initialized = TRUE;
+ }
+
+unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_enable_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+ acpi_status status = AE_BAD_PARAMETER;
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_enable_gpe);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (gpe_event_info) {
+ status = acpi_ev_add_gpe_reference(gpe_event_info);
+ }
+
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_disable_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, only then is the GPE disabled (for runtime GPEs), or
+ * the GPE mask bit disabled (for wake GPEs)
+ *
+ ******************************************************************************/
+
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+ acpi_status status = AE_BAD_PARAMETER;
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_disable_gpe);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (gpe_event_info) {
+ status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
+ }
+
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_setup_gpe_for_wake
+ *
+ * PARAMETERS: wake_device - Device associated with the GPE (via _PRW)
+ * gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
+ * interface is intended to be used as the host executes the
+ * _PRW methods (Power Resources for Wake) in the system tables.
+ * Each _PRW appears under a Device Object (The wake_device), and
+ * contains the info for the wake GPE associated with the
+ * wake_device.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_setup_gpe_for_wake(acpi_handle wake_device,
+ acpi_handle gpe_device, u32 gpe_number)
+{
+ acpi_status status = AE_BAD_PARAMETER;
+ struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_namespace_node *device_node;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
+
+ /* Parameter Validation */
+
+ if (!wake_device) {
+ /*
+ * By forcing wake_device to be valid, we automatically enable the
+ * implicit notify feature on all hosts.
+ */
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ /* Validate wake_device is of type Device */
+
+ device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
+ if (device_node->type != ACPI_TYPE_DEVICE) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (gpe_event_info) {
+ /*
+ * If there is no method or handler for this GPE, then the
+ * wake_device will be notified whenever this GPE fires (aka
+ * "implicit notify") Note: The GPE is assumed to be
+ * level-triggered (for windows compatibility).
+ */
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE) {
+ gpe_event_info->flags =
+ (ACPI_GPE_DISPATCH_NOTIFY |
+ ACPI_GPE_LEVEL_TRIGGERED);
+ gpe_event_info->dispatch.device_node = device_node;
+ }
+
+ gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
+ status = AE_OK;
+ }
+
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_set_gpe_wake_mask
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ * Action - Enable or Disable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
+ * already be marked as a WAKE GPE.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_cpu_flags flags;
+ u32 register_bit;
+
+ ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /*
+ * Ensure that we have a valid GPE number and that this GPE is in
+ * fact a wake GPE
+ */
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
+ status = AE_TYPE;
+ goto unlock_and_exit;
+ }
+
+ gpe_register_info = gpe_event_info->register_info;
+ if (!gpe_register_info) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ register_bit =
+ acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+
+ /* Perform the action */
+
+ switch (action) {
+ case ACPI_GPE_ENABLE:
+ ACPI_SET_BIT(gpe_register_info->enable_for_wake,
+ (u8)register_bit);
+ break;
+
+ case ACPI_GPE_DISABLE:
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
+ (u8)register_bit);
+ break;
+
+ default:
+ ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
+ status = AE_BAD_PARAMETER;
+ break;
+ }
+
+unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_clear_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_clear_gpe);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ status = acpi_hw_clear_gpe(gpe_event_info);
+
+ unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_gpe_status
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ * event_status - Where the current status of the event will
+ * be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_gpe_status(acpi_handle gpe_device,
+ u32 gpe_number, acpi_event_status *event_status)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ /* Obtain status on the requested GPE number */
+
+ status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
+
+ if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
+ *event_status |= ACPI_EVENT_FLAG_HANDLE;
+
+ unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_disable_all_gpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
+ *
+ ******************************************************************************/
+
+acpi_status acpi_disable_all_gpes(void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ status = acpi_hw_disable_all_gpes();
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_enable_all_runtime_gpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+acpi_status acpi_enable_all_runtime_gpes(void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ status = acpi_hw_enable_all_runtime_gpes();
+ (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_install_gpe_block
+ *
+ * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
+ * gpe_block_address - Address and space_iD
+ * register_count - Number of GPE register pairs in the block
+ * interrupt_number - H/W interrupt for the block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
+ * enabled here.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_install_gpe_block(acpi_handle gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count, u32 interrupt_number)
+{
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ struct acpi_gpe_block_info *gpe_block;
+
+ ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
+
+ if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ node = acpi_ns_validate_handle(gpe_device);
+ if (!node) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ /*
+ * For user-installed GPE Block Devices, the gpe_block_base_number
+ * is always zero
+ */
+ status =
+ acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
+ interrupt_number, &gpe_block);
+ if (ACPI_FAILURE(status)) {
+ goto unlock_and_exit;
+ }
+
+ /* Install block in the device_object attached to the node */
+
+ obj_desc = acpi_ns_get_attached_object(node);
+ if (!obj_desc) {
+
+ /*
+ * No object, create a new one (Device nodes do not always have
+ * an attached object)
+ */
+ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
+ if (!obj_desc) {
+ status = AE_NO_MEMORY;
+ goto unlock_and_exit;
+ }
+
+ status =
+ acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
+
+ /* Remove local reference to the object */
+
+ acpi_ut_remove_reference(obj_desc);
+
+ if (ACPI_FAILURE(status)) {
+ goto unlock_and_exit;
+ }
+ }
+
+ /* Now install the GPE block in the device_object */
+
+ obj_desc->device.gpe_block = gpe_block;
+
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_remove_gpe_block
+ *
+ * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ struct acpi_namespace_node *node;
+
+ ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
+
+ if (!gpe_device) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ node = acpi_ns_validate_handle(gpe_device);
+ if (!node) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ /* Get the device_object attached to the node */
+
+ obj_desc = acpi_ns_get_attached_object(node);
+ if (!obj_desc || !obj_desc->device.gpe_block) {
+ return_ACPI_STATUS(AE_NULL_OBJECT);
+ }
+
+ /* Delete the GPE block (but not the device_object) */
+
+ status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
+ if (ACPI_SUCCESS(status)) {
+ obj_desc->device.gpe_block = NULL;
+ }
+
+ unlock_and_exit:
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_gpe_device
+ *
+ * PARAMETERS: Index - System GPE index (0-current_gpe_count)
+ * gpe_device - Where the parent GPE Device is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
+ * gpe device indicates that the gpe number is contained in one of
+ * the FADT-defined gpe blocks. Otherwise, the GPE block device.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
+{
+ struct acpi_gpe_device_info info;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
+
+ if (!gpe_device) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ if (index >= acpi_current_gpe_count) {
+ return_ACPI_STATUS(AE_NOT_EXIST);
+ }
+
+ /* Setup and walk the GPE list */
+
+ info.index = index;
+ info.status = AE_NOT_EXIST;
+ info.gpe_device = NULL;
+ info.next_block_base_index = 0;
+
+ status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
+ return_ACPI_STATUS(info.status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 14750db2a1b8..85c3cbd4304d 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
* PARAMETERS: gpe_event_info - Info block for the GPE
* gpe_register_info - Info block for the GPE register
*
- * RETURN: Status
+ * RETURN: Register mask with a one in the GPE bit position
*
- * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given
- * GPE set.
+ * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
+ * correct position for the input GPE.
*
******************************************************************************/
@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
*
* RETURN: Status
*
- * DESCRIPTION: Enable or disable a single GPE in its enable register.
+ * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
*
******************************************************************************/
acpi_status
-acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
+acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
{
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
return (status);
}
- /* Set ot clear just the bit that corresponds to this GPE */
+ /* Set or clear just the bit that corresponds to this GPE */
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
gpe_register_info);
switch (action) {
- case ACPI_GPE_COND_ENABLE:
- if (!(register_bit & gpe_register_info->enable_for_run))
+ case ACPI_GPE_CONDITIONAL_ENABLE:
+
+ /* Only enable if the enable_for_run bit is set */
+
+ if (!(register_bit & gpe_register_info->enable_for_run)) {
return (AE_BAD_PARAMETER);
+ }
+
+ /*lint -fallthrough */
case ACPI_GPE_ENABLE:
ACPI_SET_BIT(enable_mask, register_bit);
@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
break;
default:
- ACPI_ERROR((AE_INFO, "Invalid action\n"));
+ ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
return (AE_BAD_PARAMETER);
}
@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
return (AE_NOT_EXIST);
}
- register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
- gpe_register_info);
-
/*
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
+ register_bit =
+ acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+
status = acpi_hw_write(register_bit,
&gpe_register_info->status_address);
@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
u32 in_byte;
u32 register_bit;
struct acpi_gpe_register_info *gpe_register_info;
- acpi_status status;
acpi_event_status local_event_status = 0;
+ acpi_status status;
ACPI_FUNCTION_ENTRY();
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index e87bc6760be6..508537f884ac 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -768,7 +768,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_gpe_fadt_blocks[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL;
acpi_current_gpe_count = 0;
- acpi_all_gpes_initialized = FALSE;
+ acpi_gbl_all_gpes_initialized = FALSE;
/* Global handlers */
@@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_init_handler = NULL;
acpi_gbl_table_handler = NULL;
acpi_gbl_interface_handler = NULL;
+ acpi_gbl_global_event_handler = NULL;
/* Global Lock support */
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index fca34ccfd294..e91680c7e047 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -1,5 +1,6 @@
config ACPI_APEI
bool "ACPI Platform Error Interface (APEI)"
+ select PSTORE
depends on X86
help
APEI allows to report errors (for example from the chipset)
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index 18df1e940276..ef0581f2094d 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
return sizeof(*estatus) + estatus->data_length;
}
+void apei_estatus_print(const char *pfx,
+ const struct acpi_hest_generic_status *estatus);
int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
#endif
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index f4cf2fc4c8c1..31464a006d76 100644
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -46,6 +46,317 @@ u64 cper_next_record_id(void)
}
EXPORT_SYMBOL_GPL(cper_next_record_id);
+static const char *cper_severity_strs[] = {
+ "recoverable",
+ "fatal",
+ "corrected",
+ "info",
+};
+
+static const char *cper_severity_str(unsigned int severity)
+{
+ return severity < ARRAY_SIZE(cper_severity_strs) ?
+ cper_severity_strs[severity] : "unknown";
+}
+
+/*
+ * cper_print_bits - print strings for set bits
+ * @pfx: prefix for each line, including log level and prefix string
+ * @bits: bit mask
+ * @strs: string array, indexed by bit position
+ * @strs_size: size of the string array: @strs
+ *
+ * For each set bit in @bits, print the corresponding string in @strs.
+ * If the output length is longer than 80, multiple line will be
+ * printed, with @pfx is printed at the beginning of each line.
+ */
+static void cper_print_bits(const char *pfx, unsigned int bits,
+ const char *strs[], unsigned int strs_size)
+{
+ int i, len = 0;
+ const char *str;
+ char buf[84];
+
+ for (i = 0; i < strs_size; i++) {
+ if (!(bits & (1U << i)))
+ continue;
+ str = strs[i];
+ if (len && len + strlen(str) + 2 > 80) {
+ printk("%s\n", buf);
+ len = 0;
+ }
+ if (!len)
+ len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
+ else
+ len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
+ }
+ if (len)
+ printk("%s\n", buf);
+}
+
+static const char *cper_proc_type_strs[] = {
+ "IA32/X64",
+ "IA64",
+};
+
+static const char *cper_proc_isa_strs[] = {
+ "IA32",
+ "IA64",
+ "X64",
+};
+
+static const char *cper_proc_error_type_strs[] = {
+ "cache error",
+ "TLB error",
+ "bus error",
+ "micro-architectural error",
+};
+
+static const char *cper_proc_op_strs[] = {
+ "unknown or generic",
+ "data read",
+ "data write",
+ "instruction execution",
+};
+
+static const char *cper_proc_flag_strs[] = {
+ "restartable",
+ "precise IP",
+ "overflow",
+ "corrected",
+};
+
+static void cper_print_proc_generic(const char *pfx,
+ const struct cper_sec_proc_generic *proc)
+{
+ if (proc->validation_bits & CPER_PROC_VALID_TYPE)
+ printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
+ proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
+ cper_proc_type_strs[proc->proc_type] : "unknown");
+ if (proc->validation_bits & CPER_PROC_VALID_ISA)
+ printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
+ proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
+ cper_proc_isa_strs[proc->proc_isa] : "unknown");
+ if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
+ printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
+ cper_print_bits(pfx, proc->proc_error_type,
+ cper_proc_error_type_strs,
+ ARRAY_SIZE(cper_proc_error_type_strs));
+ }
+ if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
+ printk("%s""operation: %d, %s\n", pfx, proc->operation,
+ proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
+ cper_proc_op_strs[proc->operation] : "unknown");
+ if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
+ printk("%s""flags: 0x%02x\n", pfx, proc->flags);
+ cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
+ ARRAY_SIZE(cper_proc_flag_strs));
+ }
+ if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
+ printk("%s""level: %d\n", pfx, proc->level);
+ if (proc->validation_bits & CPER_PROC_VALID_VERSION)
+ printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version);
+ if (proc->validation_bits & CPER_PROC_VALID_ID)
+ printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id);
+ if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
+ printk("%s""target_address: 0x%016llx\n",
+ pfx, proc->target_addr);
+ if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
+ printk("%s""requestor_id: 0x%016llx\n",
+ pfx, proc->requestor_id);
+ if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
+ printk("%s""responder_id: 0x%016llx\n",
+ pfx, proc->responder_id);
+ if (proc->validation_bits & CPER_PROC_VALID_IP)
+ printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
+}
+
+static const char *cper_mem_err_type_strs[] = {
+ "unknown",
+ "no error",
+ "single-bit ECC",
+ "multi-bit ECC",
+ "single-symbol chipkill ECC",
+ "multi-symbol chipkill ECC",
+ "master abort",
+ "target abort",
+ "parity error",
+ "watchdog timeout",
+ "invalid address",
+ "mirror Broken",
+ "memory sparing",
+ "scrub corrected error",
+ "scrub uncorrected error",
+};
+
+static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
+{
+ if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
+ printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
+ if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)
+ printk("%s""physical_address: 0x%016llx\n",
+ pfx, mem->physical_addr);
+ if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)
+ printk("%s""physical_address_mask: 0x%016llx\n",
+ pfx, mem->physical_addr_mask);
+ if (mem->validation_bits & CPER_MEM_VALID_NODE)
+ printk("%s""node: %d\n", pfx, mem->node);
+ if (mem->validation_bits & CPER_MEM_VALID_CARD)
+ printk("%s""card: %d\n", pfx, mem->card);
+ if (mem->validation_bits & CPER_MEM_VALID_MODULE)
+ printk("%s""module: %d\n", pfx, mem->module);
+ if (mem->validation_bits & CPER_MEM_VALID_BANK)
+ printk("%s""bank: %d\n", pfx, mem->bank);
+ if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
+ printk("%s""device: %d\n", pfx, mem->device);
+ if (mem->validation_bits & CPER_MEM_VALID_ROW)
+ printk("%s""row: %d\n", pfx, mem->row);
+ if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
+ printk("%s""column: %d\n", pfx, mem->column);
+ if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
+ printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
+ if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
+ printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);
+ if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
+ printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
+ if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
+ printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
+ if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
+ u8 etype = mem->error_type;
+ printk("%s""error_type: %d, %s\n", pfx, etype,
+ etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
+ cper_mem_err_type_strs[etype] : "unknown");
+ }
+}
+
+static const char *cper_pcie_port_type_strs[] = {
+ "PCIe end point",
+ "legacy PCI end point",
+ "unknown",
+ "unknown",
+ "root port",
+ "upstream switch port",
+ "downstream switch port",
+ "PCIe to PCI/PCI-X bridge",
+ "PCI/PCI-X to PCIe bridge",
+ "root complex integrated endpoint device",
+ "root complex event collector",
+};
+
+static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
+{
+ if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
+ printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
+ pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
+ cper_pcie_port_type_strs[pcie->port_type] : "unknown");
+ if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
+ printk("%s""version: %d.%d\n", pfx,
+ pcie->version.major, pcie->version.minor);
+ if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
+ printk("%s""command: 0x%04x, status: 0x%04x\n", pfx,
+ pcie->command, pcie->status);
+ if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
+ const __u8 *p;
+ printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx,
+ pcie->device_id.segment, pcie->device_id.bus,
+ pcie->device_id.device, pcie->device_id.function);
+ printk("%s""slot: %d\n", pfx,
+ pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
+ printk("%s""secondary_bus: 0x%02x\n", pfx,
+ pcie->device_id.secondary_bus);
+ printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
+ pcie->device_id.vendor_id, pcie->device_id.device_id);
+ p = pcie->device_id.class_code;
+ printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
+ }
+ if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
+ printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
+ pcie->serial_number.lower, pcie->serial_number.upper);
+ if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
+ printk(
+ "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
+ pfx, pcie->bridge.secondary_status, pcie->bridge.control);
+}
+
+static const char *apei_estatus_section_flag_strs[] = {
+ "primary",
+ "containment warning",
+ "reset",
+ "threshold exceeded",
+ "resource not accessible",
+ "latent error",
+};
+
+static void apei_estatus_print_section(
+ const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
+{
+ uuid_le *sec_type = (uuid_le *)gdata->section_type;
+ __u16 severity;
+
+ severity = gdata->error_severity;
+ printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
+ cper_severity_str(severity));
+ printk("%s""flags: 0x%02x\n", pfx, gdata->flags);
+ cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs,
+ ARRAY_SIZE(apei_estatus_section_flag_strs));
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+ printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+ printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);
+
+ if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
+ struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
+ printk("%s""section_type: general processor error\n", pfx);
+ if (gdata->error_data_length >= sizeof(*proc_err))
+ cper_print_proc_generic(pfx, proc_err);
+ else
+ goto err_section_too_small;
+ } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
+ struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
+ printk("%s""section_type: memory error\n", pfx);
+ if (gdata->error_data_length >= sizeof(*mem_err))
+ cper_print_mem(pfx, mem_err);
+ else
+ goto err_section_too_small;
+ } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
+ struct cper_sec_pcie *pcie = (void *)(gdata + 1);
+ printk("%s""section_type: PCIe error\n", pfx);
+ if (gdata->error_data_length >= sizeof(*pcie))
+ cper_print_pcie(pfx, pcie);
+ else
+ goto err_section_too_small;
+ } else
+ printk("%s""section type: unknown, %pUl\n", pfx, sec_type);
+
+ return;
+
+err_section_too_small:
+ pr_err(FW_WARN "error section length is too small\n");
+}
+
+void apei_estatus_print(const char *pfx,
+ const struct acpi_hest_generic_status *estatus)
+{
+ struct acpi_hest_generic_data *gdata;
+ unsigned int data_len, gedata_len;
+ int sec_no = 0;
+ __u16 severity;
+
+ printk("%s""APEI generic hardware error status\n", pfx);
+ severity = estatus->error_severity;
+ printk("%s""severity: %d, %s\n", pfx, severity,
+ cper_severity_str(severity));
+ data_len = estatus->data_length;
+ gdata = (struct acpi_hest_generic_data *)(estatus + 1);
+ while (data_len > sizeof(*gdata)) {
+ gedata_len = gdata->error_data_length;
+ apei_estatus_print_section(pfx, gdata, sec_no);
+ data_len -= gedata_len + sizeof(*gdata);
+ sec_no++;
+ }
+}
+EXPORT_SYMBOL_GPL(apei_estatus_print);
+
int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
{
if (estatus->data_length &&
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 1211c03149e8..22d70dbe75d1 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -34,6 +34,7 @@
#include <linux/cper.h>
#include <linux/nmi.h>
#include <linux/hardirq.h>
+#include <linux/pstore.h>
#include <acpi/apei.h>
#include "apei-internal.h"
@@ -86,7 +87,7 @@ static struct erst_erange {
* It is used to provide exclusive accessing for ERST Error Log
* Address Range too.
*/
-static DEFINE_SPINLOCK(erst_lock);
+static DEFINE_RAW_SPINLOCK(erst_lock);
static inline int erst_errno(int command_status)
{
@@ -421,9 +422,9 @@ ssize_t erst_get_record_count(void)
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
count = __erst_get_record_count();
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return count;
}
@@ -456,9 +457,9 @@ int erst_get_next_record_id(u64 *record_id)
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(record_id);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@@ -624,17 +625,17 @@ int erst_write(const struct cper_record_header *record)
return -EINVAL;
if (erst_erange.attr & ERST_RANGE_NVRAM) {
- if (!spin_trylock_irqsave(&erst_lock, flags))
+ if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
rc = __erst_write_to_nvram(record);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
if (record->record_length > erst_erange.size)
return -EINVAL;
- if (!spin_trylock_irqsave(&erst_lock, flags))
+ if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
memcpy(erst_erange.vaddr, record, record->record_length);
rcd_erange = erst_erange.vaddr;
@@ -642,7 +643,7 @@ int erst_write(const struct cper_record_header *record)
memcpy(&rcd_erange->persistence_information, "ER", 2);
rc = __erst_write_to_storage(0);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@@ -696,9 +697,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
len = __erst_read(record_id, record, buflen);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
EXPORT_SYMBOL_GPL(erst_read);
@@ -719,20 +720,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(&record_id);
if (rc) {
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
/* no more record */
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return 0;
}
len = __erst_read(record_id, record, buflen);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
@@ -746,12 +747,12 @@ int erst_clear(u64 record_id)
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
if (erst_erange.attr & ERST_RANGE_NVRAM)
rc = __erst_clear_from_nvram(record_id);
else
rc = __erst_clear_from_storage(record_id);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@@ -781,6 +782,128 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
return 0;
}
+static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+ struct timespec *time);
+static u64 erst_writer(enum pstore_type_id type, size_t size);
+
+static struct pstore_info erst_info = {
+ .owner = THIS_MODULE,
+ .name = "erst",
+ .read = erst_reader,
+ .write = erst_writer,
+ .erase = erst_clear
+};
+
+#define CPER_CREATOR_PSTORE \
+ UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \
+ 0x64, 0x90, 0xb8, 0x9d)
+#define CPER_SECTION_TYPE_DMESG \
+ UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \
+ 0x94, 0x19, 0xeb, 0x12)
+#define CPER_SECTION_TYPE_MCE \
+ UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \
+ 0x04, 0x4a, 0x38, 0xfc)
+
+struct cper_pstore_record {
+ struct cper_record_header hdr;
+ struct cper_section_descriptor sec_hdr;
+ char data[];
+} __packed;
+
+static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+ struct timespec *time)
+{
+ int rc;
+ ssize_t len;
+ unsigned long flags;
+ u64 record_id;
+ struct cper_pstore_record *rcd = (struct cper_pstore_record *)
+ (erst_info.buf - sizeof(*rcd));
+
+ if (erst_disable)
+ return -ENODEV;
+
+ raw_spin_lock_irqsave(&erst_lock, flags);
+skip:
+ rc = __erst_get_next_record_id(&record_id);
+ if (rc) {
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
+ return rc;
+ }
+ /* no more record */
+ if (record_id == APEI_ERST_INVALID_RECORD_ID) {
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
+ return 0;
+ }
+
+ len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
+ erst_erange.size);
+ if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
+ goto skip;
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
+
+ *id = record_id;
+ if (uuid_le_cmp(rcd->sec_hdr.section_type,
+ CPER_SECTION_TYPE_DMESG) == 0)
+ *type = PSTORE_TYPE_DMESG;
+ else if (uuid_le_cmp(rcd->sec_hdr.section_type,
+ CPER_SECTION_TYPE_MCE) == 0)
+ *type = PSTORE_TYPE_MCE;
+ else
+ *type = PSTORE_TYPE_UNKNOWN;
+
+ if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP)
+ time->tv_sec = rcd->hdr.timestamp;
+ else
+ time->tv_sec = 0;
+ time->tv_nsec = 0;
+
+ return len - sizeof(*rcd);
+}
+
+static u64 erst_writer(enum pstore_type_id type, size_t size)
+{
+ struct cper_pstore_record *rcd = (struct cper_pstore_record *)
+ (erst_info.buf - sizeof(*rcd));
+
+ memset(rcd, 0, sizeof(*rcd));
+ memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE);
+ rcd->hdr.revision = CPER_RECORD_REV;
+ rcd->hdr.signature_end = CPER_SIG_END;
+ rcd->hdr.section_count = 1;
+ rcd->hdr.error_severity = CPER_SEV_FATAL;
+ /* timestamp valid. platform_id, partition_id are invalid */
+ rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP;
+ rcd->hdr.timestamp = get_seconds();
+ rcd->hdr.record_length = sizeof(*rcd) + size;
+ rcd->hdr.creator_id = CPER_CREATOR_PSTORE;
+ rcd->hdr.notification_type = CPER_NOTIFY_MCE;
+ rcd->hdr.record_id = cper_next_record_id();
+ rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR;
+
+ rcd->sec_hdr.section_offset = sizeof(*rcd);
+ rcd->sec_hdr.section_length = size;
+ rcd->sec_hdr.revision = CPER_SEC_REV;
+ /* fru_id and fru_text is invalid */
+ rcd->sec_hdr.validation_bits = 0;
+ rcd->sec_hdr.flags = CPER_SEC_PRIMARY;
+ switch (type) {
+ case PSTORE_TYPE_DMESG:
+ rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
+ break;
+ case PSTORE_TYPE_MCE:
+ rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ rcd->sec_hdr.section_severity = CPER_SEV_FATAL;
+
+ erst_write(&rcd->hdr);
+
+ return rcd->hdr.record_id;
+}
+
static int __init erst_init(void)
{
int rc = 0;
@@ -788,6 +911,7 @@ static int __init erst_init(void)
struct apei_exec_context ctx;
struct apei_resources erst_resources;
struct resource *r;
+ char *buf;
if (acpi_disabled)
goto err;
@@ -854,6 +978,18 @@ static int __init erst_init(void)
if (!erst_erange.vaddr)
goto err_release_erange;
+ buf = kmalloc(erst_erange.size, GFP_KERNEL);
+ mutex_init(&erst_info.buf_mutex);
+ if (buf) {
+ erst_info.buf = buf + sizeof(struct cper_pstore_record);
+ erst_info.bufsize = erst_erange.size -
+ sizeof(struct cper_pstore_record);
+ if (pstore_register(&erst_info)) {
+ pr_info(ERST_PFX "Could not register with persistent store\n");
+ kfree(buf);
+ }
+ }
+
pr_info(ERST_PFX
"Error Record Serialization Table (ERST) support is initialized.\n");
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0d505e59214d..51905d07a4d9 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -43,6 +43,7 @@
#include <linux/kdebug.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/ratelimit.h>
#include <acpi/apei.h>
#include <acpi/atomicio.h>
#include <acpi/hed.h>
@@ -255,11 +256,26 @@ static void ghes_do_proc(struct ghes *ghes)
}
#endif
}
+}
- if (!processed && printk_ratelimit())
- pr_warning(GHES_PFX
- "Unknown error record from generic hardware error source: %d\n",
- ghes->generic->header.source_id);
+static void ghes_print_estatus(const char *pfx, struct ghes *ghes)
+{
+ /* Not more than 2 messages every 5 seconds */
+ static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2);
+
+ if (pfx == NULL) {
+ if (ghes_severity(ghes->estatus->error_severity) <=
+ GHES_SEV_CORRECTED)
+ pfx = KERN_WARNING HW_ERR;
+ else
+ pfx = KERN_ERR HW_ERR;
+ }
+ if (__ratelimit(&ratelimit)) {
+ printk(
+ "%s""Hardware error from APEI Generic Hardware Error Source: %d\n",
+ pfx, ghes->generic->header.source_id);
+ apei_estatus_print(pfx, ghes->estatus);
+ }
}
static int ghes_proc(struct ghes *ghes)
@@ -269,6 +285,7 @@ static int ghes_proc(struct ghes *ghes)
rc = ghes_read_estatus(ghes, 0);
if (rc)
goto out;
+ ghes_print_estatus(NULL, ghes);
ghes_do_proc(ghes);
out:
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 1a3508a7fe03..daa7bc63f1d4 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
/* HEST table parsing */
-static struct acpi_table_hest *hest_tab;
+static struct acpi_table_hest *__read_mostly hest_tab;
-static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
+static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
[ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
[ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
[ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@ struct ghes_arr {
unsigned int count;
};
-static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
{
int *count = data;
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
return 0;
}
-static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{
struct platform_device *ghes_dev;
struct ghes_arr *ghes_arr = data;
@@ -165,7 +165,7 @@ err:
return rc;
}
-static int hest_ghes_dev_register(unsigned int ghes_count)
+static int __init hest_ghes_dev_register(unsigned int ghes_count)
{
int rc, i;
struct ghes_arr ghes_arr;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index d68bd61072bb..7ced61f39492 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -52,22 +52,6 @@ EXPORT_SYMBOL(acpi_root_dir);
#define STRUCT_TO_INT(s) (*((int*)&s))
-static int set_power_nocheck(const struct dmi_system_id *id)
-{
- printk(KERN_NOTICE PREFIX "%s detected - "
- "disable power check in power transition\n", id->ident);
- acpi_power_nocheck = 1;
- return 0;
-}
-static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
- {
- set_power_nocheck, "HP Pavilion 05", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
- DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
- {},
-};
-
#ifdef CONFIG_X86
static int set_copy_dsdt(const struct dmi_system_id *id)
@@ -196,33 +180,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
Power Management
-------------------------------------------------------------------------- */
-int acpi_bus_get_power(acpi_handle handle, int *state)
+static int __acpi_bus_get_power(struct acpi_device *device, int *state)
{
int result = 0;
acpi_status status = 0;
- struct acpi_device *device = NULL;
unsigned long long psc = 0;
-
- result = acpi_bus_get_device(handle, &device);
- if (result)
- return result;
+ if (!device || !state)
+ return -EINVAL;
*state = ACPI_STATE_UNKNOWN;
- if (!device->flags.power_manageable) {
- /* TBD: Non-recursive algorithm for walking up hierarchy */
- if (device->parent)
- *state = device->parent->power.state;
- else
- *state = ACPI_STATE_D0;
- } else {
+ if (device->flags.power_manageable) {
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if (device->power.flags.power_resources) {
- result = acpi_power_get_inferred_state(device);
+ result = acpi_power_get_inferred_state(device, state);
if (result)
return result;
} else if (device->power.flags.explicit_get) {
@@ -230,59 +205,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
NULL, &psc);
if (ACPI_FAILURE(status))
return -ENODEV;
- device->power.state = (int)psc;
+ *state = (int)psc;
}
-
- *state = device->power.state;
+ } else {
+ /* TBD: Non-recursive algorithm for walking up hierarchy. */
+ *state = device->parent ?
+ device->parent->power.state : ACPI_STATE_D0;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
- device->pnp.bus_id, device->power.state));
+ device->pnp.bus_id, *state));
return 0;
}
-EXPORT_SYMBOL(acpi_bus_get_power);
-int acpi_bus_set_power(acpi_handle handle, int state)
+static int __acpi_bus_set_power(struct acpi_device *device, int state)
{
int result = 0;
acpi_status status = AE_OK;
- struct acpi_device *device = NULL;
char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
-
- result = acpi_bus_get_device(handle, &device);
- if (result)
- return result;
-
- if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+ if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
/* Make sure this is a valid target state */
- if (!device->flags.power_manageable) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
- kobject_name(&device->dev.kobj)));
- return -ENODEV;
- }
- /*
- * Get device's current power state
- */
- if (!acpi_power_nocheck) {
- /*
- * Maybe the incorrect power state is returned on the bogus
- * bios, which is different with the real power state.
- * For example: the bios returns D0 state and the real power
- * state is D3. OS expects to set the device to D0 state. In
- * such case if OS uses the power state returned by the BIOS,
- * the device can't be transisted to the correct power state.
- * So if the acpi_power_nocheck is set, it is unnecessary to
- * get the power state by calling acpi_bus_get_power.
- */
- acpi_bus_get_power(device->handle, &device->power.state);
- }
- if ((state == device->power.state) && !device->flags.force_power_state) {
+ if (state == device->power.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
state));
return 0;
@@ -351,8 +300,75 @@ int acpi_bus_set_power(acpi_handle handle, int state)
return result;
}
+
+int acpi_bus_set_power(acpi_handle handle, int state)
+{
+ struct acpi_device *device;
+ int result;
+
+ result = acpi_bus_get_device(handle, &device);
+ if (result)
+ return result;
+
+ if (!device->flags.power_manageable) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Device [%s] is not power manageable\n",
+ dev_name(&device->dev)));
+ return -ENODEV;
+ }
+
+ return __acpi_bus_set_power(device, state);
+}
EXPORT_SYMBOL(acpi_bus_set_power);
+
+int acpi_bus_init_power(struct acpi_device *device)
+{
+ int state;
+ int result;
+
+ if (!device)
+ return -EINVAL;
+
+ device->power.state = ACPI_STATE_UNKNOWN;
+
+ result = __acpi_bus_get_power(device, &state);
+ if (result)
+ return result;
+
+ if (device->power.flags.power_resources)
+ result = acpi_power_on_resources(device, state);
+
+ if (!result)
+ device->power.state = state;
+
+ return result;
+}
+
+
+int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+ struct acpi_device *device;
+ int state;
+ int result;
+
+ result = acpi_bus_get_device(handle, &device);
+ if (result)
+ return result;
+
+ result = __acpi_bus_get_power(device, &state);
+ if (result)
+ return result;
+
+ result = __acpi_bus_set_power(device, state);
+ if (!result && state_p)
+ *state_p = state;
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_update_power);
+
+
bool acpi_bus_power_manageable(acpi_handle handle)
{
struct acpi_device *device;
@@ -1023,15 +1039,8 @@ static int __init acpi_init(void)
if (acpi_disabled)
return result;
- /*
- * If the laptop falls into the DMI check table, the power state check
- * will be disabled in the course of device power transition.
- */
- dmi_check_system(power_nocheck_dmi_table);
-
acpi_scan_init();
acpi_ec_init();
- acpi_power_init();
acpi_debugfs_init();
acpi_sleep_proc_init();
acpi_wakeup_device_init();
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 81514a4918cc..1864ad3cf895 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -725,7 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
complete_dock(ds);
dock_event(ds, event, DOCK_EVENT);
dock_lock(ds, 1);
- acpi_update_gpes();
+ acpi_update_all_gpes();
break;
}
if (dock_present(ds) || dock_in_progress(ds))
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 372ff80b7b0c..81887724de80 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -606,7 +606,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
return 0;
}
-static u32 acpi_ec_gpe_handler(void *data)
+static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
+ u32 gpe_number, void *data)
{
struct acpi_ec *ec = data;
@@ -934,6 +935,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
ec_flag_msi, "MSI hardware", {
DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
{
+ ec_flag_msi, "MSI hardware", {
+ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
+ {
ec_validate_ecdt, "ASUS hardware", {
DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
{},
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 60049080c869..467479f07c1f 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -86,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
if (!device)
return -EINVAL;
- result = acpi_bus_get_power(device->handle, &acpi_state);
+ result = acpi_bus_update_power(device->handle, &acpi_state);
if (result)
return result;
@@ -123,7 +123,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = {
static int acpi_fan_add(struct acpi_device *device)
{
int result = 0;
- int state = 0;
struct thermal_cooling_device *cdev;
if (!device)
@@ -132,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device)
strcpy(acpi_device_name(device), "Fan");
strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
- result = acpi_bus_get_power(device->handle, &state);
+ result = acpi_bus_update_power(device->handle, NULL);
if (result) {
- printk(KERN_ERR PREFIX "Reading power state\n");
+ printk(KERN_ERR PREFIX "Setting initial power state\n");
goto end;
}
- device->flags.force_power_state = 1;
- acpi_bus_set_power(device->handle, state);
- device->flags.force_power_state = 0;
-
cdev = thermal_cooling_device_register("Fan", device,
&fan_cooling_ops);
if (IS_ERR(cdev)) {
@@ -200,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
static int acpi_fan_resume(struct acpi_device *device)
{
- int result = 0;
- int power_state = 0;
+ int result;
if (!device)
return -EINVAL;
- result = acpi_bus_get_power(device->handle, &power_state);
- if (result) {
- printk(KERN_ERR PREFIX
- "Error reading fan power state\n");
- return result;
- }
-
- device->flags.force_power_state = 1;
- acpi_bus_set_power(device->handle, power_state);
- device->flags.force_power_state = 0;
+ result = acpi_bus_update_power(device->handle, NULL);
+ if (result)
+ printk(KERN_ERR PREFIX "Error updating fan power state\n");
return result;
}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index a212bfeddf8c..8df5d7061a45 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,9 +41,10 @@ static inline int acpi_debugfs_init(void) { return 0; }
int acpi_power_init(void);
int acpi_device_sleep_wake(struct acpi_device *dev,
int enable, int sleep_state, int dev_state);
-int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
+int acpi_power_on_resources(struct acpi_device *device, int state);
int acpi_power_transition(struct acpi_device *device, int state);
-extern int acpi_power_nocheck;
+int acpi_bus_init_power(struct acpi_device *device);
int acpi_wakeup_device_init(void);
void acpi_early_processor_set_pdc(void);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 966feddf6b1b..3a7b4879fd99 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -110,9 +110,6 @@ struct acpi_ioremap {
static LIST_HEAD(acpi_ioremaps);
static DEFINE_SPINLOCK(acpi_ioremap_lock);
-#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
static void __init acpi_osi_setup_late(void);
/*
@@ -152,8 +149,7 @@ static struct osi_linux {
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
- unsigned int known:1;
-} osi_linux = { 0, 0, 0, 0};
+} osi_linux = {0, 0, 0};
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
@@ -324,7 +320,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = ioremap(pg_off, pg_sz);
+ virt = ioremap_cache(pg_off, pg_sz);
if (!virt) {
kfree(map);
return NULL;
@@ -646,7 +642,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
- virt_addr = ioremap(phys_addr, size);
+ virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
if (!value)
@@ -682,7 +678,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
- virt_addr = ioremap(phys_addr, size);
+ virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)
__setup("acpi_os_name=", acpi_os_name_setup);
+#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
+#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
+
+struct osi_setup_entry {
+ char string[OSI_STRING_LENGTH_MAX];
+ bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
+void __init acpi_osi_setup(char *str)
+{
+ struct osi_setup_entry *osi;
+ bool enable = true;
+ int i;
+
+ if (!acpi_gbl_create_osi_method)
+ return;
+
+ if (str == NULL || *str == '\0') {
+ printk(KERN_INFO PREFIX "_OSI method disabled\n");
+ acpi_gbl_create_osi_method = FALSE;
+ return;
+ }
+
+ if (*str == '!') {
+ str++;
+ enable = false;
+ }
+
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ if (!strcmp(osi->string, str)) {
+ osi->enable = enable;
+ break;
+ } else if (osi->string[0] == '\0') {
+ osi->enable = enable;
+ strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+ break;
+ }
+ }
+}
+
static void __init set_osi_linux(unsigned int enable)
{
- if (osi_linux.enable != enable) {
+ if (osi_linux.enable != enable)
osi_linux.enable = enable;
- printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
- enable ? "Add": "Delet");
- }
if (osi_linux.enable)
acpi_osi_setup("Linux");
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)
static void __init acpi_cmdline_osi_linux(unsigned int enable)
{
- osi_linux.cmdline = 1; /* cmdline set the default */
+ osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
+ osi_linux.dmi = 0;
set_osi_linux(enable);
return;
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
{
- osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
-
printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
if (enable == -1)
return;
- osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
-
+ osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
set_osi_linux(enable);
return;
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
*/
static void __init acpi_osi_setup_late(void)
{
- char *str = osi_setup_string;
+ struct osi_setup_entry *osi;
+ char *str;
+ int i;
+ acpi_status status;
- if (*str == '\0')
- return;
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ str = osi->string;
- if (!strcmp("!Linux", str)) {
- acpi_cmdline_osi_linux(0); /* !enable */
- } else if (*str == '!') {
- if (acpi_remove_interface(++str) == AE_OK)
- printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
- } else if (!strcmp("Linux", str)) {
- acpi_cmdline_osi_linux(1); /* enable */
- } else {
- if (acpi_install_interface(str) == AE_OK)
- printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ if (*str == '\0')
+ break;
+ if (osi->enable) {
+ status = acpi_install_interface(str);
+
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ } else {
+ status = acpi_remove_interface(str);
+
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ }
}
}
-int __init acpi_osi_setup(char *str)
+static int __init osi_setup(char *str)
{
- if (str == NULL || *str == '\0') {
- printk(KERN_INFO PREFIX "_OSI method disabled\n");
- acpi_gbl_create_osi_method = FALSE;
- } else {
- strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
- }
+ if (str && !strcmp("Linux", str))
+ acpi_cmdline_osi_linux(1);
+ else if (str && !strcmp("!Linux", str))
+ acpi_cmdline_osi_linux(0);
+ else
+ acpi_osi_setup(str);
return 1;
}
-__setup("acpi_osi=", acpi_osi_setup);
+__setup("acpi_osi=", osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
static int __init acpi_serialize_setup(char *str)
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)
return AE_OK;
}
-acpi_status acpi_os_initialize1(void)
+acpi_status __init acpi_os_initialize1(void)
{
kacpid_wq = create_workqueue("kacpid");
kacpi_notify_wq = create_workqueue("kacpi_notify");
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 67dedeed144c..0003f1009885 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-int acpi_power_nocheck;
-module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
-
static int acpi_power_add(struct acpi_device *device);
static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_resume(struct acpi_device *device);
@@ -213,11 +210,13 @@ static int acpi_power_on(acpi_handle handle)
resource->name));
} else {
result = __acpi_power_on(resource);
+ if (result)
+ resource->ref_count--;
}
mutex_unlock(&resource->resource_lock);
- return 0;
+ return result;
}
static int acpi_power_off_device(acpi_handle handle)
@@ -264,6 +263,35 @@ static int acpi_power_off_device(acpi_handle handle)
return result;
}
+static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
+{
+ int i;
+
+ for (i = num_res - 1; i >= 0 ; i--)
+ acpi_power_off_device(list->handles[i]);
+}
+
+static void acpi_power_off_list(struct acpi_handle_list *list)
+{
+ __acpi_power_off_list(list, list->count);
+}
+
+static int acpi_power_on_list(struct acpi_handle_list *list)
+{
+ int result = 0;
+ int i;
+
+ for (i = 0; i < list->count; i++) {
+ result = acpi_power_on(list->handles[i]);
+ if (result) {
+ __acpi_power_off_list(list, i);
+ break;
+ }
+ }
+
+ return result;
+}
+
/**
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
* ACPI 3.0) _PSW (Power State Wake)
@@ -421,19 +449,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
Device Power Management
-------------------------------------------------------------------------- */
-int acpi_power_get_inferred_state(struct acpi_device *device)
+int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
{
int result = 0;
struct acpi_handle_list *list = NULL;
int list_state = 0;
int i = 0;
-
- if (!device)
+ if (!device || !state)
return -EINVAL;
- device->power.state = ACPI_STATE_UNKNOWN;
-
/*
* We know a device's inferred power state when all the resources
* required for a given D-state are 'on'.
@@ -448,66 +473,51 @@ int acpi_power_get_inferred_state(struct acpi_device *device)
return result;
if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
- device->power.state = i;
+ *state = i;
return 0;
}
}
- device->power.state = ACPI_STATE_D3;
-
+ *state = ACPI_STATE_D3;
return 0;
}
-int acpi_power_transition(struct acpi_device *device, int state)
+int acpi_power_on_resources(struct acpi_device *device, int state)
{
- int result = 0;
- struct acpi_handle_list *cl = NULL; /* Current Resources */
- struct acpi_handle_list *tl = NULL; /* Target Resources */
- int i = 0;
+ if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
+ return -EINVAL;
+ return acpi_power_on_list(&device->power.states[state].resources);
+}
+
+int acpi_power_transition(struct acpi_device *device, int state)
+{
+ int result;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
+ if (device->power.state == state)
+ return 0;
+
if ((device->power.state < ACPI_STATE_D0)
|| (device->power.state > ACPI_STATE_D3))
return -ENODEV;
- cl = &device->power.states[device->power.state].resources;
- tl = &device->power.states[state].resources;
-
/* TBD: Resources must be ordered. */
/*
* First we reference all power resources required in the target list
- * (e.g. so the device doesn't lose power while transitioning).
+ * (e.g. so the device doesn't lose power while transitioning). Then,
+ * we dereference all power resources used in the current list.
*/
- for (i = 0; i < tl->count; i++) {
- result = acpi_power_on(tl->handles[i]);
- if (result)
- goto end;
- }
-
- if (device->power.state == state) {
- goto end;
- }
-
- /*
- * Then we dereference all power resources used in the current list.
- */
- for (i = 0; i < cl->count; i++) {
- result = acpi_power_off_device(cl->handles[i]);
- if (result)
- goto end;
- }
+ result = acpi_power_on_list(&device->power.states[state].resources);
+ if (!result)
+ acpi_power_off_list(
+ &device->power.states[device->power.state].resources);
- end:
- if (result)
- device->power.state = ACPI_STATE_UNKNOWN;
- else {
- /* We shouldn't change the state till all above operations succeed */
- device->power.state = state;
- }
+ /* We shouldn't change the state unless the above operations succeed. */
+ device->power.state = result ? ACPI_STATE_UNKNOWN : state;
return result;
}
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index fde49b9b1d99..79cb65332894 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
return 0;
}
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
- return -ENODEV;
-}
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
- return -ENODEV;
-}
-
#endif
int acpi_processor_get_limit_info(struct acpi_processor *pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2b6c21d86b98..23c6b6aca919 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
}
static acpi_status
-acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
- union acpi_object *package)
+acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
+ struct acpi_device_wakeup *wakeup)
{
- int i = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *package = NULL;
union acpi_object *element = NULL;
+ acpi_status status;
+ int i = 0;
- if (!device || !package || (package->package.count < 2))
+ if (!wakeup)
return AE_BAD_PARAMETER;
+ /* _PRW */
+ status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
+ return status;
+ }
+
+ package = (union acpi_object *)buffer.pointer;
+
+ if (!package || (package->package.count < 2)) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
+
element = &(package->package.elements[0]);
- if (!element)
- return AE_BAD_PARAMETER;
+ if (!element) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
if (element->type == ACPI_TYPE_PACKAGE) {
if ((element->package.count < 2) ||
(element->package.elements[0].type !=
ACPI_TYPE_LOCAL_REFERENCE)
- || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
- return AE_BAD_DATA;
- device->wakeup.gpe_device =
+ || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
+ wakeup->gpe_device =
element->package.elements[0].reference.handle;
- device->wakeup.gpe_number =
+ wakeup->gpe_number =
(u32) element->package.elements[1].integer.value;
} else if (element->type == ACPI_TYPE_INTEGER) {
- device->wakeup.gpe_number = element->integer.value;
- } else
- return AE_BAD_DATA;
+ wakeup->gpe_device = NULL;
+ wakeup->gpe_number = element->integer.value;
+ } else {
+ status = AE_BAD_DATA;
+ goto out;
+ }
element = &(package->package.elements[1]);
if (element->type != ACPI_TYPE_INTEGER) {
- return AE_BAD_DATA;
+ status = AE_BAD_DATA;
+ goto out;
}
- device->wakeup.sleep_state = element->integer.value;
+ wakeup->sleep_state = element->integer.value;
if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
- return AE_NO_MEMORY;
+ status = AE_NO_MEMORY;
+ goto out;
}
- device->wakeup.resources.count = package->package.count - 2;
- for (i = 0; i < device->wakeup.resources.count; i++) {
+ wakeup->resources.count = package->package.count - 2;
+ for (i = 0; i < wakeup->resources.count; i++) {
element = &(package->package.elements[i + 2]);
- if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
- return AE_BAD_DATA;
+ if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
- device->wakeup.resources.handles[i] = element->reference.handle;
+ wakeup->resources.handles[i] = element->reference.handle;
}
- acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number);
+ acpi_setup_gpe_for_wake(wakeup->gpe_device, NULL, wakeup->gpe_number);
- return AE_OK;
+ out:
+ kfree(buffer.pointer);
+
+ return status;
}
static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
@@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
{
acpi_status status = 0;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *package = NULL;
int psw_error;
- /* _PRW */
- status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
- goto end;
- }
-
- package = (union acpi_object *)buffer.pointer;
- status = acpi_bus_extract_wakeup_device_power_package(device, package);
+ status = acpi_bus_extract_wakeup_device_power_package(device->handle,
+ &device->wakeup);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
goto end;
}
- kfree(buffer.pointer);
-
device->wakeup.flags.valid = 1;
device->wakeup.prepare_count = 0;
acpi_bus_set_run_wake_flags(device);
@@ -827,6 +847,8 @@ end:
return 0;
}
+static void acpi_bus_add_power_resource(acpi_handle handle);
+
static int acpi_bus_get_power_flags(struct acpi_device *device)
{
acpi_status status = 0;
@@ -855,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
acpi_evaluate_reference(device->handle, object_name, NULL,
&ps->resources);
if (ps->resources.count) {
+ int j;
+
device->power.flags.power_resources = 1;
ps->flags.valid = 1;
+ for (j = 0; j < ps->resources.count; j++)
+ acpi_bus_add_power_resource(ps->resources.handles[j]);
}
/* Evaluate "_PSx" to see if we can do explicit sets */
@@ -881,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
device->power.states[ACPI_STATE_D3].flags.valid = 1;
device->power.states[ACPI_STATE_D3].power = 0;
- /* TBD: System wake support and resource requirements. */
-
- device->power.state = ACPI_STATE_UNKNOWN;
- acpi_bus_get_power(device->handle, &(device->power.state));
+ acpi_bus_init_power(device);
return 0;
}
@@ -1306,6 +1329,20 @@ end:
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
+static void acpi_bus_add_power_resource(acpi_handle handle)
+{
+ struct acpi_bus_ops ops = {
+ .acpi_op_add = 1,
+ .acpi_op_start = 1,
+ };
+ struct acpi_device *device = NULL;
+
+ acpi_bus_get_device(handle, &device);
+ if (!device)
+ acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
+ ACPI_STA_DEFAULT, &ops);
+}
+
static int acpi_bus_type_and_status(acpi_handle handle, int *type,
unsigned long long *sta)
{
@@ -1351,6 +1388,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
struct acpi_bus_ops *ops = context;
int type;
unsigned long long sta;
+ struct acpi_device_wakeup wakeup;
struct acpi_device *device;
acpi_status status;
int result;
@@ -1360,8 +1398,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
return AE_OK;
if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
- !(sta & ACPI_STA_DEVICE_FUNCTIONING))
+ !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
+ acpi_bus_extract_wakeup_device_power_package(handle, &wakeup);
return AE_CTRL_DEPTH;
+ }
/*
* We may already have an acpi_device from a previous enumeration. If
@@ -1444,7 +1484,7 @@ int acpi_bus_start(struct acpi_device *device)
result = acpi_bus_scan(device->handle, &ops, NULL);
- acpi_update_gpes();
+ acpi_update_all_gpes();
return result;
}
@@ -1550,6 +1590,8 @@ int __init acpi_scan_init(void)
printk(KERN_ERR PREFIX "Could not register bus type\n");
}
+ acpi_power_init();
+
/*
* Enumerate devices in the ACPI namespace.
*/
@@ -1561,7 +1603,7 @@ int __init acpi_scan_init(void)
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
else
- acpi_update_gpes();
+ acpi_update_all_gpes();
return result;
}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 721d93b3ceee..febb153b5a68 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -27,8 +27,6 @@
static u8 sleep_states[ACPI_S_STATE_COUNT];
-static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
static void acpi_sleep_tts_switch(u32 acpi_state)
{
union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
}
#ifdef CONFIG_ACPI_SLEEP
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
@@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
},
},
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-NW130D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index f8588f81048a..61891e75583d 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void)
return;
}
-void acpi_os_gpe_count(u32 gpe_number)
+static void gpe_count(u32 gpe_number)
{
acpi_gpe_count++;
@@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number)
return;
}
-void acpi_os_fixed_event_count(u32 event_number)
+static void fixed_event_count(u32 event_number)
{
if (!all_counters)
return;
@@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number)
return;
}
+static void acpi_gbl_event_handler(u32 event_type, acpi_handle device,
+ u32 event_number, void *context)
+{
+ if (event_type == ACPI_EVENT_TYPE_GPE)
+ gpe_count(event_number);
+
+ if (event_type == ACPI_EVENT_TYPE_FIXED)
+ fixed_event_count(event_number);
+}
+
static int get_status(u32 index, acpi_event_status *status,
acpi_handle *handle)
{
@@ -601,6 +611,7 @@ end:
void acpi_irq_stats_init(void)
{
+ acpi_status status;
int i;
if (all_counters)
@@ -619,6 +630,10 @@ void acpi_irq_stats_init(void)
if (all_counters == NULL)
goto fail;
+ status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL);
+ if (ACPI_FAILURE(status))
+ goto fail;
+
counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
GFP_KERNEL);
if (counter_attrs == NULL)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5a27b0a31315..2607e17b520f 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -1059,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device)
break;
tz->trips.active[i].flags.enabled = 1;
for (j = 0; j < tz->trips.active[i].devices.count; j++) {
- result = acpi_bus_get_power(tz->trips.active[i].devices.
- handles[j], &power_state);
+ result = acpi_bus_update_power(
+ tz->trips.active[i].devices.handles[j],
+ &power_state);
if (result || (power_state != ACPI_STATE_D0)) {
tz->trips.active[i].flags.enabled = 0;
break;
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index f62a50c3ed34..c6cb68e0a80c 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -45,7 +45,7 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
acpi_enable_wakeup_device_power(dev, sleep_state);
/* The wake-up power should have been enabled already. */
- acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+ acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
ACPI_GPE_ENABLE);
}
}
@@ -67,7 +67,7 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
|| (sleep_state > (u32) dev->wakeup.sleep_state))
continue;
- acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+ acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
ACPI_GPE_DISABLE);
if (dev->wakeup.state.enabled)
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 2737b9752205..e7df019d29d4 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -147,6 +147,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
clk_put(pclk);
}
+static int amba_get_enable_vcore(struct amba_device *pcdev)
+{
+ struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
+ int ret;
+
+ pcdev->vcore = vcore;
+
+ if (IS_ERR(vcore)) {
+ /* It is OK not to supply a vcore regulator */
+ if (PTR_ERR(vcore) == -ENODEV)
+ return 0;
+ return PTR_ERR(vcore);
+ }
+
+ ret = regulator_enable(vcore);
+ if (ret) {
+ regulator_put(vcore);
+ pcdev->vcore = ERR_PTR(-ENODEV);
+ }
+
+ return ret;
+}
+
+static void amba_put_disable_vcore(struct amba_device *pcdev)
+{
+ struct regulator *vcore = pcdev->vcore;
+
+ if (!IS_ERR(vcore)) {
+ regulator_disable(vcore);
+ regulator_put(vcore);
+ }
+}
+
/*
* These are the device model conversion veneers; they convert the
* device model structures to our more specific structures.
@@ -159,6 +192,10 @@ static int amba_probe(struct device *dev)
int ret;
do {
+ ret = amba_get_enable_vcore(pcdev);
+ if (ret)
+ break;
+
ret = amba_get_enable_pclk(pcdev);
if (ret)
break;
@@ -168,6 +205,7 @@ static int amba_probe(struct device *dev)
break;
amba_put_disable_pclk(pcdev);
+ amba_put_disable_vcore(pcdev);
} while (0);
return ret;
@@ -180,6 +218,7 @@ static int amba_remove(struct device *dev)
int ret = drv->remove(pcdev);
amba_put_disable_pclk(pcdev);
+ amba_put_disable_vcore(pcdev);
return ret;
}
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 11ec911016c6..e3e0e95c7aa5 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -90,6 +90,14 @@ config SATA_INIC162X
help
This option enables support for Initio 162x Serial ATA.
+config SATA_ACARD_AHCI
+ tristate "ACard AHCI variant (ATP 8620)"
+ depends on PCI
+ help
+ This option enables support for Acard.
+
+ If unsure, say N.
+
config SATA_SIL24
tristate "Silicon Image 3124/3132 SATA support"
depends on PCI
@@ -128,16 +136,6 @@ config PDC_ADMA
If unsure, say N.
-config PATA_MPC52xx
- tristate "Freescale MPC52xx SoC internal IDE"
- depends on PPC_MPC52xx && PPC_BESTCOMM
- select PPC_BESTCOMM_ATA
- help
- This option enables support for integrated IDE controller
- of the Freescale MPC52xx SoC.
-
- If unsure, say N.
-
config PATA_OCTEON_CF
tristate "OCTEON Boot Bus Compact Flash support"
depends on CPU_CAVIUM_OCTEON
@@ -366,7 +364,7 @@ config PATA_CS5535
config PATA_CS5536
tristate "CS5536 PATA support"
- depends on PCI && X86 && !X86_64
+ depends on PCI
help
This option enables support for the AMD CS5536
companion chip used with the Geode LX processor family.
@@ -491,6 +489,16 @@ config PATA_MARVELL
If unsure, say N.
+config PATA_MPC52xx
+ tristate "Freescale MPC52xx SoC internal IDE"
+ depends on PPC_MPC52xx && PPC_BESTCOMM
+ select PPC_BESTCOMM_ATA
+ help
+ This option enables support for integrated IDE controller
+ of the Freescale MPC52xx SoC.
+
+ If unsure, say N.
+
config PATA_NETCELL
tristate "NETCELL Revolution RAID support"
depends on PCI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index c501af5b12b9..27291aad6ca7 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_ATA) += libata.o
# non-SFF interface
obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
+obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
@@ -11,7 +12,6 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
-obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o
obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o
obj-$(CONFIG_SATA_SX4) += sata_sx4.o
@@ -52,6 +52,7 @@ obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
obj-$(CONFIG_PATA_MACIO) += pata_macio.o
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
+obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o
obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
new file mode 100644
index 000000000000..339c210f03a6
--- /dev/null
+++ b/drivers/ata/acard-ahci.c
@@ -0,0 +1,528 @@
+
+/*
+ * acard-ahci.c - ACard AHCI SATA support
+ *
+ * Maintained by: Jeff Garzik <jgarzik@pobox.com>
+ * Please ALWAYS copy linux-ide@vger.kernel.org
+ * on emails.
+ *
+ * Copyright 2010 Red Hat, 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, 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ * AHCI hardware documentation:
+ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
+ * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#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>
+#include "ahci.h"
+
+#define DRV_NAME "acard-ahci"
+#define DRV_VERSION "1.0"
+
+/*
+ Received FIS structure limited to 80h.
+*/
+
+#define ACARD_AHCI_RX_FIS_SZ 128
+
+enum {
+ AHCI_PCI_BAR = 5,
+};
+
+enum board_ids {
+ board_acard_ahci,
+};
+
+struct acard_sg {
+ __le32 addr;
+ __le32 addr_hi;
+ __le32 reserved;
+ __le32 size; /* bit 31 (EOT) max==0x10000 (64k) */
+};
+
+static void acard_ahci_qc_prep(struct ata_queued_cmd *qc);
+static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
+static int acard_ahci_port_start(struct ata_port *ap);
+static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+
+#ifdef CONFIG_PM
+static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
+static int acard_ahci_pci_device_resume(struct pci_dev *pdev);
+#endif
+
+static struct scsi_host_template acard_ahci_sht = {
+ AHCI_SHT("acard-ahci"),
+};
+
+static struct ata_port_operations acard_ops = {
+ .inherits = &ahci_ops,
+ .qc_prep = acard_ahci_qc_prep,
+ .qc_fill_rtf = acard_ahci_qc_fill_rtf,
+ .port_start = acard_ahci_port_start,
+};
+
+#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
+
+static const struct ata_port_info acard_ahci_port_info[] = {
+ [board_acard_ahci] =
+ {
+ AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ),
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &acard_ops,
+ },
+};
+
+static const struct pci_device_id acard_ahci_pci_tbl[] = {
+ /* ACard */
+ { PCI_VDEVICE(ARTOP, 0x000d), board_acard_ahci }, /* ATP8620 */
+
+ { } /* terminate list */
+};
+
+static struct pci_driver acard_ahci_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = acard_ahci_pci_tbl,
+ .probe = acard_ahci_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
+ .suspend = acard_ahci_pci_device_suspend,
+ .resume = acard_ahci_pci_device_resume,
+#endif
+};
+
+#ifdef CONFIG_PM
+static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->mmio;
+ u32 ctl;
+
+ if (mesg.event & PM_EVENT_SUSPEND &&
+ hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "BIOS update required for suspend/resume\n");
+ return -EIO;
+ }
+
+ if (mesg.event & PM_EVENT_SLEEP) {
+ /* AHCI spec rev1.1 section 8.3.3:
+ * Software must disable interrupts prior to requesting a
+ * transition of the HBA to D3 state.
+ */
+ ctl = readl(mmio + HOST_CTL);
+ ctl &= ~HOST_IRQ_EN;
+ writel(ctl, mmio + HOST_CTL);
+ readl(mmio + HOST_CTL); /* flush */
+ }
+
+ return ata_pci_device_suspend(pdev, mesg);
+}
+
+static int acard_ahci_pci_device_resume(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
+
+ ahci_init_controller(host);
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+#endif
+
+static int acard_ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
+{
+ int rc;
+
+ if (using_dac &&
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ if (rc) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
+ return rc;
+ }
+ }
+ } else {
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ return rc;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ return rc;
+ }
+ }
+ return 0;
+}
+
+static void acard_ahci_pci_print_info(struct ata_host *host)
+{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ u16 cc;
+ const char *scc_s;
+
+ pci_read_config_word(pdev, 0x0a, &cc);
+ if (cc == PCI_CLASS_STORAGE_IDE)
+ scc_s = "IDE";
+ else if (cc == PCI_CLASS_STORAGE_SATA)
+ scc_s = "SATA";
+ else if (cc == PCI_CLASS_STORAGE_RAID)
+ scc_s = "RAID";
+ else
+ scc_s = "unknown";
+
+ ahci_print_info(host, scc_s);
+}
+
+static unsigned int acard_ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
+{
+ struct scatterlist *sg;
+ struct acard_sg *acard_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ;
+ unsigned int si, last_si = 0;
+
+ VPRINTK("ENTER\n");
+
+ /*
+ * Next, the S/G list.
+ */
+ for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ dma_addr_t addr = sg_dma_address(sg);
+ u32 sg_len = sg_dma_len(sg);
+
+ /*
+ * ACard note:
+ * We must set an end-of-table (EOT) bit,
+ * and the segment cannot exceed 64k (0x10000)
+ */
+ acard_sg[si].addr = cpu_to_le32(addr & 0xffffffff);
+ acard_sg[si].addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ acard_sg[si].size = cpu_to_le32(sg_len);
+ last_si = si;
+ }
+
+ acard_sg[last_si].size |= cpu_to_le32(1 << 31); /* set EOT */
+
+ return si;
+}
+
+static void acard_ahci_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct ahci_port_priv *pp = ap->private_data;
+ int is_atapi = ata_is_atapi(qc->tf.protocol);
+ void *cmd_tbl;
+ u32 opts;
+ const u32 cmd_fis_len = 5; /* five dwords */
+ unsigned int n_elem;
+
+ /*
+ * Fill in command table information. First, the header,
+ * a SATA Register - Host to Device command FIS.
+ */
+ cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
+
+ ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
+ if (is_atapi) {
+ memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
+ memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
+ }
+
+ n_elem = 0;
+ if (qc->flags & ATA_QCFLAG_DMAMAP)
+ n_elem = acard_ahci_fill_sg(qc, cmd_tbl);
+
+ /*
+ * Fill in command slot information.
+ *
+ * ACard note: prd table length not filled in
+ */
+ opts = cmd_fis_len | (qc->dev->link->pmp << 12);
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ opts |= AHCI_CMD_WRITE;
+ if (is_atapi)
+ opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH;
+
+ ahci_fill_cmd_slot(pp, qc->tag, opts);
+}
+
+static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+ struct ahci_port_priv *pp = qc->ap->private_data;
+ u8 *rx_fis = pp->rx_fis;
+
+ if (pp->fbs_enabled)
+ rx_fis += qc->dev->link->pmp * ACARD_AHCI_RX_FIS_SZ;
+
+ /*
+ * After a successful execution of an ATA PIO data-in command,
+ * the device doesn't send D2H Reg FIS to update the TF and
+ * the host should take TF and E_Status from the preceding PIO
+ * Setup FIS.
+ */
+ if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
+ !(qc->flags & ATA_QCFLAG_FAILED)) {
+ ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
+ qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
+ } else
+ ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
+
+ return true;
+}
+
+static int acard_ahci_port_start(struct ata_port *ap)
+{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+ struct device *dev = ap->host->dev;
+ struct ahci_port_priv *pp;
+ void *mem;
+ dma_addr_t mem_dma;
+ size_t dma_sz, rx_fis_sz;
+
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ /* check FBS capability */
+ if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) {
+ void __iomem *port_mmio = ahci_port_base(ap);
+ u32 cmd = readl(port_mmio + PORT_CMD);
+ if (cmd & PORT_CMD_FBSCP)
+ pp->fbs_supported = true;
+ else if (hpriv->flags & AHCI_HFLAG_YES_FBS) {
+ dev_printk(KERN_INFO, dev,
+ "port %d can do FBS, forcing FBSCP\n",
+ ap->port_no);
+ pp->fbs_supported = true;
+ } else
+ dev_printk(KERN_WARNING, dev,
+ "port %d is not capable of FBS\n",
+ ap->port_no);
+ }
+
+ if (pp->fbs_supported) {
+ dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ;
+ rx_fis_sz = ACARD_AHCI_RX_FIS_SZ * 16;
+ } else {
+ dma_sz = AHCI_PORT_PRIV_DMA_SZ;
+ rx_fis_sz = ACARD_AHCI_RX_FIS_SZ;
+ }
+
+ mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+ memset(mem, 0, dma_sz);
+
+ /*
+ * First item in chunk of DMA memory: 32-slot command table,
+ * 32 bytes each in size
+ */
+ pp->cmd_slot = mem;
+ pp->cmd_slot_dma = mem_dma;
+
+ mem += AHCI_CMD_SLOT_SZ;
+ mem_dma += AHCI_CMD_SLOT_SZ;
+
+ /*
+ * Second item: Received-FIS area
+ */
+ pp->rx_fis = mem;
+ pp->rx_fis_dma = mem_dma;
+
+ mem += rx_fis_sz;
+ mem_dma += rx_fis_sz;
+
+ /*
+ * Third item: data area for storing a single command
+ * and its scatter-gather table
+ */
+ pp->cmd_tbl = mem;
+ pp->cmd_tbl_dma = mem_dma;
+
+ /*
+ * Save off initial list of interrupts to be enabled.
+ * This could be changed later
+ */
+ pp->intr_mask = DEF_PORT_IRQ;
+
+ ap->private_data = pp;
+
+ /* engage engines, captain */
+ return ahci_port_resume(ap);
+}
+
+static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ unsigned int board_id = ent->driver_data;
+ struct ata_port_info pi = acard_ahci_port_info[board_id];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ struct ata_host *host;
+ int n_ports, i, rc;
+
+ VPRINTK("ENTER\n");
+
+ WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS);
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ /* acquire resources */
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ /* AHCI controllers often implement SFF compatible interface.
+ * Grab all PCI BARs just in case.
+ */
+ rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
+
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
+ hpriv->flags |= (unsigned long)pi.private_data;
+
+ if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+ pci_enable_msi(pdev);
+
+ hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
+
+ /* save initial config */
+ ahci_save_initial_config(&pdev->dev, hpriv, 0, 0);
+
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ)
+ pi.flags |= ATA_FLAG_NCQ;
+
+ if (hpriv->cap & HOST_CAP_PMP)
+ pi.flags |= ATA_FLAG_PMP;
+
+ ahci_set_em_messages(hpriv, &pi);
+
+ /* CAP.NP sometimes indicate the index of the last enabled
+ * port, at other times, that of the last possible port, so
+ * determining the maximum port number requires looking at
+ * both CAP.NP and port_map.
+ */
+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ if (!host)
+ return -ENOMEM;
+ host->private_data = hpriv;
+
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
+ host->flags |= ATA_HOST_PARALLEL_SCAN;
+ else
+ printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
+ ata_port_pbar_desc(ap, AHCI_PCI_BAR,
+ 0x100 + ap->port_no * 0x80, "port");
+
+ /* set initial link pm policy */
+ /*
+ ap->pm_policy = NOT_AVAILABLE;
+ */
+ /* disabled/not-implemented port */
+ if (!(hpriv->port_map & (1 << i)))
+ ap->ops = &ata_dummy_port_ops;
+ }
+
+ /* initialize adapter */
+ rc = acard_ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
+ if (rc)
+ return rc;
+
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
+
+ ahci_init_controller(host);
+ acard_ahci_pci_print_info(host);
+
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
+ &acard_ahci_sht);
+}
+
+static int __init acard_ahci_init(void)
+{
+ return pci_register_driver(&acard_ahci_pci_driver);
+}
+
+static void __exit acard_ahci_exit(void)
+{
+ pci_unregister_driver(&acard_ahci_pci_driver);
+}
+
+MODULE_AUTHOR("Jeff Garzik");
+MODULE_DESCRIPTION("ACard AHCI SATA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, acard_ahci_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(acard_ahci_init);
+module_exit(acard_ahci_exit);
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 329cbbb91284..3e606c34f57b 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -311,6 +311,8 @@ extern struct device_attribute *ahci_sdev_attrs[];
extern struct ata_port_operations ahci_ops;
+void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
+ u32 opts);
void ahci_save_initial_config(struct device *dev,
struct ahci_host_priv *hpriv,
unsigned int force_port_map,
@@ -326,6 +328,7 @@ int ahci_stop_engine(struct ata_port *ap);
void ahci_start_engine(struct ata_port *ap);
int ahci_check_ready(struct ata_link *link);
int ahci_kick_engine(struct ata_port *ap);
+int ahci_port_resume(struct ata_port *ap);
void ahci_set_em_messages(struct ahci_host_priv *hpriv,
struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host);
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index ebc08d65b3dd..26d452339e98 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -87,10 +87,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
static void ahci_postreset(struct ata_link *link, unsigned int *class);
static void ahci_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
-static int ahci_port_resume(struct ata_port *ap);
static void ahci_dev_config(struct ata_device *dev);
-static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
- u32 opts);
#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
#endif
@@ -1133,8 +1130,8 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)
return ata_dev_classify(&tf);
}
-static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
- u32 opts)
+void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
+ u32 opts)
{
dma_addr_t cmd_tbl_dma;
@@ -1145,6 +1142,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff);
pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16);
}
+EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot);
int ahci_kick_engine(struct ata_port *ap)
{
@@ -1918,7 +1916,7 @@ static void ahci_pmp_detach(struct ata_port *ap)
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
}
-static int ahci_port_resume(struct ata_port *ap)
+int ahci_port_resume(struct ata_port *ap)
{
ahci_power_up(ap);
ahci_start_port(ap);
@@ -1930,6 +1928,7 @@ static int ahci_port_resume(struct ata_port *ap)
return 0;
}
+EXPORT_SYMBOL_GPL(ahci_port_resume);
#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 7f77c67d267c..f23d6d46b95b 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4807,9 +4807,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
{
struct ata_device *dev = qc->dev;
- if (ata_tag_internal(qc->tag))
- return;
-
if (ata_is_nodata(qc->tf.protocol))
return;
@@ -4858,14 +4855,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
if (unlikely(qc->err_mask))
qc->flags |= ATA_QCFLAG_FAILED;
- if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
- /* always fill result TF for failed qc */
+ /*
+ * Finish internal commands without any further processing
+ * and always with the result TF filled.
+ */
+ if (unlikely(ata_tag_internal(qc->tag))) {
fill_result_tf(qc);
+ __ata_qc_complete(qc);
+ return;
+ }
- if (!ata_tag_internal(qc->tag))
- ata_qc_schedule_eh(qc);
- else
- __ata_qc_complete(qc);
+ /*
+ * Non-internal qc has failed. Fill the result TF and
+ * summon EH.
+ */
+ if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
+ fill_result_tf(qc);
+ ata_qc_schedule_eh(qc);
return;
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 5e590504f3aa..17a637877d03 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3275,6 +3275,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
+ enum ata_lpm_policy old_policy = link->lpm_policy;
unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
unsigned int err_mask;
int rc;
@@ -3338,6 +3339,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
goto fail;
}
+ /*
+ * Low level driver acked the transition. Issue DIPM command
+ * with the new policy set.
+ */
+ link->lpm_policy = policy;
+ if (ap && ap->slave_link)
+ ap->slave_link->lpm_policy = policy;
+
/* host config updated, enable DIPM if transitioning to MIN_POWER */
ata_for_each_dev(dev, link, ENABLED) {
if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) {
@@ -3353,12 +3362,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
}
}
- link->lpm_policy = policy;
- if (ap && ap->slave_link)
- ap->slave_link->lpm_policy = policy;
return 0;
fail:
+ /* restore the old policy */
+ link->lpm_policy = old_policy;
+ if (ap && ap->slave_link)
+ ap->slave_link->lpm_policy = old_policy;
+
/* if no device or only one more chance is left, disable LPM */
if (!dev || ehc->tries[dev->devno] <= 2) {
ata_link_printk(link, KERN_WARNING,
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 66aa4bee80a6..5defc74973d7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -346,12 +346,11 @@ struct device_attribute *ata_common_sdev_attrs[] = {
};
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
-static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *))
+static void ata_scsi_invalid_field(struct scsi_cmnd *cmd)
{
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
- done(cmd);
+ cmd->scsi_done(cmd);
}
/**
@@ -719,7 +718,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
* @dev: ATA device to which the new command is attached
* @cmd: SCSI command that originated this ATA command
- * @done: SCSI command completion function
*
* Obtain a reference to an unused ata_queued_cmd structure,
* which is the basic libata structure representing a single
@@ -736,21 +734,20 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
* Command allocated, or %NULL if none available.
*/
static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
- struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *))
+ struct scsi_cmnd *cmd)
{
struct ata_queued_cmd *qc;
qc = ata_qc_new_init(dev);
if (qc) {
qc->scsicmd = cmd;
- qc->scsidone = done;
+ qc->scsidone = cmd->scsi_done;
qc->sg = scsi_sglist(cmd);
qc->n_elem = scsi_sg_count(cmd);
} else {
cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1);
- done(cmd);
+ cmd->scsi_done(cmd);
}
return qc;
@@ -1735,7 +1732,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* ata_scsi_translate - Translate then issue SCSI command to ATA device
* @dev: ATA device to which the command is addressed
* @cmd: SCSI command to execute
- * @done: SCSI command completion function
* @xlat_func: Actor which translates @cmd to an ATA taskfile
*
* Our ->queuecommand() function has decided that the SCSI
@@ -1759,7 +1755,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* needs to be deferred.
*/
static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *),
ata_xlat_func_t xlat_func)
{
struct ata_port *ap = dev->link->ap;
@@ -1768,7 +1763,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
VPRINTK("ENTER\n");
- qc = ata_scsi_qc_new(dev, cmd, done);
+ qc = ata_scsi_qc_new(dev, cmd);
if (!qc)
goto err_mem;
@@ -1804,14 +1799,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
early_finish:
ata_qc_free(qc);
- qc->scsidone(cmd);
+ cmd->scsi_done(cmd);
DPRINTK("EXIT - early finish (good or error)\n");
return 0;
err_did:
ata_qc_free(qc);
cmd->result = (DID_ERROR << 16);
- qc->scsidone(cmd);
+ cmd->scsi_done(cmd);
err_mem:
DPRINTK("EXIT - internal\n");
return 0;
@@ -3116,7 +3111,6 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
}
static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
- void (*done)(struct scsi_cmnd *),
struct ata_device *dev)
{
u8 scsi_op = scmd->cmnd[0];
@@ -3150,9 +3144,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
}
if (xlat_func)
- rc = ata_scsi_translate(dev, scmd, done, xlat_func);
+ rc = ata_scsi_translate(dev, scmd, xlat_func);
else
- ata_scsi_simulate(dev, scmd, done);
+ ata_scsi_simulate(dev, scmd);
return rc;
@@ -3160,7 +3154,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",
scmd->cmd_len, scsi_op, dev->cdb_len);
scmd->result = DID_ERROR << 16;
- done(scmd);
+ scmd->scsi_done(scmd);
return 0;
}
@@ -3199,7 +3193,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
dev = ata_scsi_find_dev(ap, scsidev);
if (likely(dev))
- rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev);
+ rc = __ata_scsi_queuecmd(cmd, dev);
else {
cmd->result = (DID_BAD_TARGET << 16);
cmd->scsi_done(cmd);
@@ -3214,7 +3208,6 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
* ata_scsi_simulate - simulate SCSI command on ATA device
* @dev: the target device
* @cmd: SCSI command being sent to device.
- * @done: SCSI command completion function.
*
* Interprets and directly executes a select list of SCSI commands
* that can be handled internally.
@@ -3223,8 +3216,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
* spin_lock_irqsave(host lock)
*/
-void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *))
+void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
{
struct ata_scsi_args args;
const u8 *scsicmd = cmd->cmnd;
@@ -3233,17 +3225,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
args.dev = dev;
args.id = dev->id;
args.cmd = cmd;
- args.done = done;
+ args.done = cmd->scsi_done;
switch(scsicmd[0]) {
/* TODO: worth improving? */
case FORMAT_UNIT:
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
break;
case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
else switch (scsicmd[2]) {
@@ -3269,7 +3261,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
break;
default:
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
break;
}
break;
@@ -3281,7 +3273,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
case MODE_SELECT: /* unconditionally return */
case MODE_SELECT_10: /* bad-field-in-cdb */
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
break;
case READ_CAPACITY:
@@ -3292,7 +3284,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
break;
case REPORT_LUNS:
@@ -3302,7 +3294,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
case REQUEST_SENSE:
ata_scsi_set_sense(cmd, 0, 0, 0);
cmd->result = (DRIVER_SENSE << 24);
- done(cmd);
+ cmd->scsi_done(cmd);
break;
/* if we reach this, then writeback caching is disabled,
@@ -3324,14 +3316,14 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
else
- ata_scsi_invalid_field(cmd, done);
+ ata_scsi_invalid_field(cmd);
break;
/* all other commands */
default:
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
/* "Invalid command operation code" */
- done(cmd);
+ cmd->scsi_done(cmd);
break;
}
}
@@ -3858,7 +3850,6 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
/**
* ata_sas_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent
- * @done: Completion function, called when command is complete
* @ap: ATA port to which the command is being sent
*
* RETURNS:
@@ -3866,18 +3857,17 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
* 0 otherwise.
*/
-int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
- struct ata_port *ap)
+int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap)
{
int rc = 0;
ata_scsi_dump_cdb(ap, cmd);
if (likely(ata_dev_enabled(ap->link.device)))
- rc = __ata_scsi_queuecmd(cmd, done, ap->link.device);
+ rc = __ata_scsi_queuecmd(cmd, ap->link.device);
else {
cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
+ cmd->scsi_done(cmd);
}
return rc;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d05387d1e14b..484697fef386 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1532,11 +1532,10 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap,
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
return ata_sff_idle_irq(ap);
break;
- case HSM_ST:
- case HSM_ST_LAST:
- break;
- default:
+ case HSM_ST_IDLE:
return ata_sff_idle_irq(ap);
+ default:
+ break;
}
/* check main status, clearing INTRQ if needed */
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 21ee23f89e88..628c8fae5937 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -37,10 +37,22 @@
#include <linux/delay.h>
#include <linux/libata.h>
#include <scsi/scsi_host.h>
+
+#ifdef CONFIG_X86_32
#include <asm/msr.h>
+static int use_msr;
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+#else
+#undef rdmsr /* avoid accidental MSR usage on, e.g. x86-64 */
+#undef wrmsr
+#define rdmsr(x, y, z) do { } while (0)
+#define wrmsr(x, y, z) do { } while (0)
+#define use_msr 0
+#endif
#define DRV_NAME "pata_cs5536"
-#define DRV_VERSION "0.0.7"
+#define DRV_VERSION "0.0.8"
enum {
CFG = 0,
@@ -75,8 +87,6 @@ enum {
IDE_ETC_NODMA = 0x03,
};
-static int use_msr;
-
static const u32 msr_reg[4] = {
MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC,
};
@@ -88,7 +98,7 @@ static const u8 pci_reg[4] = {
static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
{
if (unlikely(use_msr)) {
- u32 dummy;
+ u32 dummy __maybe_unused;
rdmsr(msr_reg[reg], *val, dummy);
return 0;
@@ -294,8 +304,6 @@ MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5536);
MODULE_VERSION(DRV_VERSION);
-module_param_named(msr, use_msr, int, 0644);
-MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
module_init(cs5536_init);
module_exit(cs5536_exit);
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 46b94762125b..f9b983ae6877 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -154,7 +154,7 @@ static int __init adummy_init(void)
err = -ENOMEM;
goto out;
}
- atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+ atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
err = -ENODEV;
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index a33896a482e6..ffe9b655292e 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
goto out_reset;
}
- dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
+ dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1,
+ NULL);
if (!dev->atm_dev) {
PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
err = -EINVAL;
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
index b9101818b47b..0b0625054a87 100644
--- a/drivers/atm/atmtcp.c
+++ b/drivers/atm/atmtcp.c
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result)
if (!dev_data)
return -ENOMEM;
- dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
+ dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
if (!dev) {
kfree(dev_data);
return itf == -1 ? -ENOMEM : -EBUSY;
@@ -392,7 +392,10 @@ static int atmtcp_attach(struct atm_vcc *vcc,int itf)
atm_dev_put(dev);
return -EMEDIUMTYPE;
}
- if (PRIV(dev)->vcc) return -EBUSY;
+ if (PRIV(dev)->vcc) {
+ atm_dev_put(dev);
+ return -EBUSY;
+ }
}
else {
int error;
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 97c5898cd76e..c495fae74200 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
&zeroes);
if (!cpu_zeroes) goto out1;
}
- dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+ dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
if (!dev) goto out2;
pci_set_drvdata(pci_dev, dev);
eni_dev->pci_dev = pci_dev;
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 5d86bb803e94..7d912baf01d4 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
fs_dev, sizeof (struct fs_dev));
if (!fs_dev)
goto err_out;
- atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+ atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
if (!atm_dev)
goto err_out_free_fs_dev;
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index c8fc69c85a06..44f778507770 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -92,7 +92,7 @@
#define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ])
-#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo))
+#define FORE200E_NEXT_ENTRY(index, modulo) (index = ((index) + 1) % (modulo))
#if 1
#define ASSERT(expr) if (!(expr)) { \
@@ -2567,14 +2567,14 @@ release:
static int __devinit
-fore200e_register(struct fore200e* fore200e)
+fore200e_register(struct fore200e* fore200e, struct device *parent)
{
struct atm_dev* atm_dev;
DPRINTK(2, "device %s being registered\n", fore200e->name);
- atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
- NULL);
+ atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
+ -1, NULL);
if (atm_dev == NULL) {
printk(FORE200E "unable to register device %s\n", fore200e->name);
return -ENODEV;
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e)
static int __devinit
-fore200e_init(struct fore200e* fore200e)
+fore200e_init(struct fore200e* fore200e, struct device *parent)
{
- if (fore200e_register(fore200e) < 0)
+ if (fore200e_register(fore200e, parent) < 0)
return -ENODEV;
if (fore200e->bus->configure(fore200e) < 0)
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op,
sprintf(fore200e->name, "%s-%d", bus->model_name, index);
- err = fore200e_init(fore200e);
+ err = fore200e_init(fore200e, &op->dev);
if (err < 0) {
fore200e_shutdown(fore200e);
kfree(fore200e);
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent
sprintf(fore200e->name, "%s-%d", bus->model_name, index);
- err = fore200e_init(fore200e);
+ err = fore200e_init(fore200e, &pci_dev->dev);
if (err < 0) {
fore200e_shutdown(fore200e);
goto out_free;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 801e8b6e9d1f..6cf59bf281dc 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
goto init_one_failure;
}
- atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
+ atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
if (!atm_dev) {
err = -ENODEV;
goto init_one_failure;
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index a95790452a68..24761e1d6642 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
iobase, irq, membase);
- dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL);
+ dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
+ NULL);
if (!(dev->atm_dev)) {
PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
err = -EINVAL;
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index bce57328ddde..bfb7feee0400 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
goto err_out_iounmap;
}
- dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL);
+ dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
+ NULL);
if (!dev) {
printk("%s: can't register atm device\n", card->name);
err = -EIO;
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 9309d4724e13..729254053758 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
ret = -ENODEV;
goto err_out_free_iadev;
}
- dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
if (!dev) {
ret = -ENOMEM;
goto err_out_disable_dev;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index cbe15a86c669..52880c8387d8 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -2241,11 +2241,8 @@ static int __devinit lanai_dev_open(struct atm_dev *atmdev)
memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);
lanai_timed_poll_start(lanai);
printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%u "
- "(%02X-%02X-%02X-%02X-%02X-%02X)\n", lanai->number,
- (int) lanai->pci->revision, (unsigned long) lanai->base,
- lanai->pci->irq,
- atmdev->esi[0], atmdev->esi[1], atmdev->esi[2],
- atmdev->esi[3], atmdev->esi[4], atmdev->esi[5]);
+ "(%pMF)\n", lanai->number, (int) lanai->pci->revision,
+ (unsigned long) lanai->base, lanai->pci->irq, atmdev->esi);
printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), "
"board_rev=%d\n", lanai->number,
lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno,
@@ -2591,7 +2588,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
return -ENOMEM;
}
- atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
if (atmdev == NULL) {
printk(KERN_ERR DEV_LABEL
": couldn't register atm device!\n");
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 2f3516b7f118..6b313ee9231b 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
}
/* Register device */
- card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
+ card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+ -1, NULL);
if (card->atmdev == NULL) {
printk("nicstar%d: can't register device.\n", i);
error = 17;
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 2e08c996fd30..73fb1c4f4cd4 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
static void release_vccs(struct atm_dev *dev);
-static int atm_init(struct solos_card *);
+static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
static void solos_bh(unsigned long);
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (db_firmware_upgrade)
flash_upgrade(card, 3);
- err = atm_init(card);
+ err = atm_init(card, &dev->dev);
if (err)
goto out_free_irq;
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
return err;
}
-static int atm_init(struct solos_card *card)
+static int atm_init(struct solos_card *card, struct device *parent)
{
int i;
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card)
skb_queue_head_init(&card->tx_queue[i]);
skb_queue_head_init(&card->cli_queue[i]);
- card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
+ card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
if (!card->atmdev[i]) {
dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
atm_remove(card);
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 4e885d2da49c..624917902b65 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
goto out;
}
- dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
if (!dev)
goto out_free;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6ed645411c40..761359261589 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -338,6 +338,35 @@ static void device_remove_attributes(struct device *dev,
device_remove_file(dev, &attrs[i]);
}
+static int device_add_bin_attributes(struct device *dev,
+ struct bin_attribute *attrs)
+{
+ int error = 0;
+ int i;
+
+ if (attrs) {
+ for (i = 0; attr_name(attrs[i]); i++) {
+ error = device_create_bin_file(dev, &attrs[i]);
+ if (error)
+ break;
+ }
+ if (error)
+ while (--i >= 0)
+ device_remove_bin_file(dev, &attrs[i]);
+ }
+ return error;
+}
+
+static void device_remove_bin_attributes(struct device *dev,
+ struct bin_attribute *attrs)
+{
+ int i;
+
+ if (attrs)
+ for (i = 0; attr_name(attrs[i]); i++)
+ device_remove_bin_file(dev, &attrs[i]);
+}
+
static int device_add_groups(struct device *dev,
const struct attribute_group **groups)
{
@@ -378,12 +407,15 @@ static int device_add_attrs(struct device *dev)
error = device_add_attributes(dev, class->dev_attrs);
if (error)
return error;
+ error = device_add_bin_attributes(dev, class->dev_bin_attrs);
+ if (error)
+ goto err_remove_class_attrs;
}
if (type) {
error = device_add_groups(dev, type->groups);
if (error)
- goto err_remove_class_attrs;
+ goto err_remove_class_bin_attrs;
}
error = device_add_groups(dev, dev->groups);
@@ -395,6 +427,9 @@ static int device_add_attrs(struct device *dev)
err_remove_type_groups:
if (type)
device_remove_groups(dev, type->groups);
+ err_remove_class_bin_attrs:
+ if (class)
+ device_remove_bin_attributes(dev, class->dev_bin_attrs);
err_remove_class_attrs:
if (class)
device_remove_attributes(dev, class->dev_attrs);
@@ -412,8 +447,10 @@ static void device_remove_attrs(struct device *dev)
if (type)
device_remove_groups(dev, type->groups);
- if (class)
+ if (class) {
device_remove_attributes(dev, class->dev_attrs);
+ device_remove_bin_attributes(dev, class->dev_bin_attrs);
+ }
}
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 5674bd01d96d..de0435e63b02 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -297,8 +297,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
struct sk_buff *skb;
struct net_device *ifp;
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, ifp) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, ifp) {
dev_hold(ifp);
if (!is_aoe_netif(ifp))
goto cont;
@@ -325,7 +325,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
cont:
dev_put(ifp);
}
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
}
static void
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index f291587d753e..8e0f9256eb58 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk)
InquiryData_struct *inq_buff = NULL;
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
+ if (!h->drv[logvol])
+ continue;
if (memcmp(h->drv[logvol]->LunID, drv->LunID,
sizeof(drv->LunID)) == 0) {
FOUND = 1;
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1ea1a34e78b2..3803a0348937 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -911,8 +911,6 @@ struct drbd_md {
struct drbd_backing_dev {
struct block_device *backing_bdev;
struct block_device *md_bdev;
- struct file *lo_file;
- struct file *md_file;
struct drbd_md md;
struct disk_conf dc; /* The user provided config... */
sector_t known_size; /* last known size of that backing device */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 6be5401d0e88..29cd0dc9fe4f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3372,11 +3372,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
if (ldev == NULL)
return;
- bd_release(ldev->backing_bdev);
- bd_release(ldev->md_bdev);
-
- fput(ldev->lo_file);
- fput(ldev->md_file);
+ blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+ blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
kfree(ldev);
}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 29e5c70e4e26..8cbfaa687d72 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
sector_t max_possible_sectors;
sector_t min_md_device_sectors;
struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
- struct inode *inode, *inode2;
+ struct block_device *bdev;
struct lru_cache *resync_lru = NULL;
union drbd_state ns, os;
unsigned int max_seg_s;
@@ -907,46 +907,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
}
}
- nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0);
- if (IS_ERR(nbc->lo_file)) {
+ bdev = blkdev_get_by_path(nbc->dc.backing_dev,
+ FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev);
+ if (IS_ERR(bdev)) {
dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
- PTR_ERR(nbc->lo_file));
- nbc->lo_file = NULL;
+ PTR_ERR(bdev));
retcode = ERR_OPEN_DISK;
goto fail;
}
+ nbc->backing_bdev = bdev;
- inode = nbc->lo_file->f_dentry->d_inode;
-
- if (!S_ISBLK(inode->i_mode)) {
- retcode = ERR_DISK_NOT_BDEV;
- goto fail;
- }
-
- nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0);
- if (IS_ERR(nbc->md_file)) {
+ /*
+ * meta_dev_idx >= 0: external fixed size, possibly multiple
+ * drbd sharing one meta device. TODO in that case, paranoia
+ * check that [md_bdev, meta_dev_idx] is not yet used by some
+ * other drbd minor! (if you use drbd.conf + drbdadm, that
+ * should check it for you already; but if you don't, or
+ * someone fooled it, we need to double check here)
+ */
+ bdev = blkdev_get_by_path(nbc->dc.meta_dev,
+ FMODE_READ | FMODE_WRITE | FMODE_EXCL,
+ (nbc->dc.meta_dev_idx < 0) ?
+ (void *)mdev : (void *)drbd_m_holder);
+ if (IS_ERR(bdev)) {
dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
- PTR_ERR(nbc->md_file));
- nbc->md_file = NULL;
+ PTR_ERR(bdev));
retcode = ERR_OPEN_MD_DISK;
goto fail;
}
+ nbc->md_bdev = bdev;
- inode2 = nbc->md_file->f_dentry->d_inode;
-
- if (!S_ISBLK(inode2->i_mode)) {
- retcode = ERR_MD_NOT_BDEV;
- goto fail;
- }
-
- nbc->backing_bdev = inode->i_bdev;
- if (bd_claim(nbc->backing_bdev, mdev)) {
- printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n",
- nbc->backing_bdev, mdev,
- nbc->backing_bdev->bd_holder,
- nbc->backing_bdev->bd_contains->bd_holder,
- nbc->backing_bdev->bd_holders);
- retcode = ERR_BDCLAIM_DISK;
+ if ((nbc->backing_bdev == nbc->md_bdev) !=
+ (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
+ nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
+ retcode = ERR_MD_IDX_INVALID;
goto fail;
}
@@ -955,28 +949,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
offsetof(struct bm_extent, lce));
if (!resync_lru) {
retcode = ERR_NOMEM;
- goto release_bdev_fail;
- }
-
- /* meta_dev_idx >= 0: external fixed size,
- * possibly multiple drbd sharing one meta device.
- * TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is
- * not yet used by some other drbd minor!
- * (if you use drbd.conf + drbdadm,
- * that should check it for you already; but if you don't, or someone
- * fooled it, we need to double check here) */
- nbc->md_bdev = inode2->i_bdev;
- if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev
- : (void *) drbd_m_holder)) {
- retcode = ERR_BDCLAIM_MD_DISK;
- goto release_bdev_fail;
- }
-
- if ((nbc->backing_bdev == nbc->md_bdev) !=
- (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
- nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
- retcode = ERR_MD_IDX_INVALID;
- goto release_bdev2_fail;
+ goto fail;
}
/* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
@@ -987,7 +960,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
(unsigned long long) drbd_get_max_capacity(nbc),
(unsigned long long) nbc->dc.disk_size);
retcode = ERR_DISK_TO_SMALL;
- goto release_bdev2_fail;
+ goto fail;
}
if (nbc->dc.meta_dev_idx < 0) {
@@ -1004,7 +977,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
dev_warn(DEV, "refusing attach: md-device too small, "
"at least %llu sectors needed for this meta-disk type\n",
(unsigned long long) min_md_device_sectors);
- goto release_bdev2_fail;
+ goto fail;
}
/* Make sure the new disk is big enough
@@ -1012,7 +985,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
if (drbd_get_max_capacity(nbc) <
drbd_get_capacity(mdev->this_bdev)) {
retcode = ERR_DISK_TO_SMALL;
- goto release_bdev2_fail;
+ goto fail;
}
nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
@@ -1035,7 +1008,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
drbd_resume_io(mdev);
if (retcode < SS_SUCCESS)
- goto release_bdev2_fail;
+ goto fail;
if (!get_ldev_if_state(mdev, D_ATTACHING))
goto force_diskless;
@@ -1269,18 +1242,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
force_diskless:
drbd_force_state(mdev, NS(disk, D_FAILED));
drbd_md_sync(mdev);
- release_bdev2_fail:
- if (nbc)
- bd_release(nbc->md_bdev);
- release_bdev_fail:
- if (nbc)
- bd_release(nbc->backing_bdev);
fail:
if (nbc) {
- if (nbc->lo_file)
- fput(nbc->lo_file);
- if (nbc->md_file)
- fput(nbc->md_file);
+ if (nbc->backing_bdev)
+ blkdev_put(nbc->backing_bdev,
+ FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+ if (nbc->md_bdev)
+ blkdev_put(nbc->md_bdev,
+ FMODE_READ | FMODE_WRITE | FMODE_EXCL);
kfree(nbc);
}
lc_destroy(resync_lru);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 89d8a7cc4054..24487d4fb202 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev)
}
shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header);
- rv = drbd_recv(mdev, &header->h80.payload, shs);
- if (unlikely(rv != shs)) {
- dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
- goto err_out;
- }
-
if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
goto err_out;
}
+ if (shs) {
+ rv = drbd_recv(mdev, &header->h80.payload, shs);
+ if (unlikely(rv != shs)) {
+ dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
+ goto err_out;
+ }
+ }
+
rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs);
if (unlikely(!rv)) {
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 181ea0364822..ab2bd09d54b4 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
}
/* completion of master bio is outside of spinlock.
- * If you need it irqsave, do it your self! */
+ * If you need it irqsave, do it your self!
+ * Which means: don't use from bio endio callback. */
static inline int req_mod(struct drbd_request *req,
enum drbd_req_event what)
{
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 47d223c2409c..34f224b018b3 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error)
*/
void drbd_endio_pri(struct bio *bio, int error)
{
+ unsigned long flags;
struct drbd_request *req = bio->bi_private;
struct drbd_conf *mdev = req->mdev;
+ struct bio_and_error m;
enum drbd_req_event what;
int uptodate = bio_flagged(bio, BIO_UPTODATE);
@@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error)
bio_put(req->private_bio);
req->private_bio = ERR_PTR(error);
- req_mod(req, what);
+ /* not req_mod(), we need irqsave here! */
+ spin_lock_irqsave(&mdev->req_lock, flags);
+ __req_mod(req, what, &m);
+ spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+ if (m.bio)
+ complete_master_bio(mdev, &m);
}
int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 7ea0bea2f7e3..44e18c073c44 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -395,11 +395,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct loop_device *lo = p->lo;
struct page *page = buf->page;
sector_t IV;
- int size, ret;
-
- ret = buf->ops->confirm(pipe, buf);
- if (unlikely(ret))
- return ret;
+ int size;
IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
(buf->offset >> 9);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 19b3568e9326..77d70eebb6b2 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
* so bdget() can't fail.
*/
bdget(pd->bdev->bd_dev);
- if ((ret = blkdev_get(pd->bdev, FMODE_READ)))
+ if ((ret = blkdev_get(pd->bdev, FMODE_READ | FMODE_EXCL, pd)))
goto out;
- if ((ret = bd_claim(pd->bdev, pd)))
- goto out_putdev;
-
if ((ret = pkt_get_last_written(pd, &lba))) {
printk(DRIVER_NAME": pkt_get_last_written failed\n");
- goto out_unclaim;
+ goto out_putdev;
}
set_capacity(pd->disk, lba << 2);
@@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
q = bdev_get_queue(pd->bdev);
if (write) {
if ((ret = pkt_open_write(pd)))
- goto out_unclaim;
+ goto out_putdev;
/*
* Some CDRW drives can not handle writes larger than one packet,
* even if the size is a multiple of the packet size.
@@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
}
if ((ret = pkt_set_segment_merging(pd, q)))
- goto out_unclaim;
+ goto out_putdev;
if (write) {
if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
printk(DRIVER_NAME": not enough memory for buffers\n");
ret = -ENOMEM;
- goto out_unclaim;
+ goto out_putdev;
}
printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
}
return 0;
-out_unclaim:
- bd_release(pd->bdev);
out_putdev:
- blkdev_put(pd->bdev, FMODE_READ);
+ blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
out:
return ret;
}
@@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
pkt_lock_door(pd, 0);
pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
- bd_release(pd->bdev);
- blkdev_put(pd->bdev, FMODE_READ);
+ blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
pkt_shrink_pktlist(pd);
}
@@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
bdev = bdget(dev);
if (!bdev)
return -ENOMEM;
- ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY);
+ ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL);
if (ret)
return ret;
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 6ec9d53806c5..008d4a00b50d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -21,80 +21,9 @@
- Instructions for use
- --------------------
+ For usage instructions, please refer to:
- 1) Map a Linux block device to an existing rbd image.
-
- Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
-
- $ echo "192.168.0.1 name=admin rbd foo" > /sys/class/rbd/add
-
- The snapshot name can be "-" or omitted to map the image read/write.
-
- 2) List all active blkdev<->object mappings.
-
- In this example, we have performed step #1 twice, creating two blkdevs,
- mapped to two separate rados objects in the rados rbd pool
-
- $ cat /sys/class/rbd/list
- #id major client_name pool name snap KB
- 0 254 client4143 rbd foo - 1024000
-
- The columns, in order, are:
- - blkdev unique id
- - blkdev assigned major
- - rados client id
- - rados pool name
- - rados block device name
- - mapped snapshot ("-" if none)
- - device size in KB
-
-
- 3) Create a snapshot.
-
- Usage: <blkdev id> <snapname>
-
- $ echo "0 mysnap" > /sys/class/rbd/snap_create
-
-
- 4) Listing a snapshot.
-
- $ cat /sys/class/rbd/snaps_list
- #id snap KB
- 0 - 1024000 (*)
- 0 foo 1024000
-
- The columns, in order, are:
- - blkdev unique id
- - snapshot name, '-' means none (active read/write version)
- - size of device at time of snapshot
- - the (*) indicates this is the active version
-
- 5) Rollback to snapshot.
-
- Usage: <blkdev id> <snapname>
-
- $ echo "0 mysnap" > /sys/class/rbd/snap_rollback
-
-
- 6) Mapping an image using snapshot.
-
- A snapshot mapping is read-only. This is being done by passing
- snap=<snapname> to the options when adding a device.
-
- $ echo "192.168.0.1 name=admin,snap=mysnap rbd foo" > /sys/class/rbd/add
-
-
- 7) Remove an active blkdev<->rbd image mapping.
-
- In this example, we remove the mapping with blkdev unique id 1.
-
- $ echo 1 > /sys/class/rbd/remove
-
-
- NOTE: The actual creation and deletion of rados objects is outside the scope
- of this driver.
+ Documentation/ABI/testing/sysfs-bus-rbd
*/
@@ -163,6 +92,14 @@ struct rbd_request {
u64 len;
};
+struct rbd_snap {
+ struct device dev;
+ const char *name;
+ size_t size;
+ struct list_head node;
+ u64 id;
+};
+
/*
* a single device
*/
@@ -193,21 +130,60 @@ struct rbd_device {
int read_only;
struct list_head node;
+
+ /* list of snapshots */
+ struct list_head snaps;
+
+ /* sysfs related */
+ struct device dev;
+};
+
+static struct bus_type rbd_bus_type = {
+ .name = "rbd",
};
static spinlock_t node_lock; /* protects client get/put */
-static struct class *class_rbd; /* /sys/class/rbd */
static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */
static LIST_HEAD(rbd_dev_list); /* devices */
static LIST_HEAD(rbd_client_list); /* clients */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static void rbd_dev_release(struct device *dev);
+static ssize_t rbd_snap_rollback(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size);
+static ssize_t rbd_snap_add(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count);
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap);;
+
+
+static struct rbd_device *dev_to_rbd(struct device *dev)
+{
+ return container_of(dev, struct rbd_device, dev);
+}
+
+static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
+{
+ return get_device(&rbd_dev->dev);
+}
+
+static void rbd_put_dev(struct rbd_device *rbd_dev)
+{
+ put_device(&rbd_dev->dev);
+}
static int rbd_open(struct block_device *bdev, fmode_t mode)
{
struct gendisk *disk = bdev->bd_disk;
struct rbd_device *rbd_dev = disk->private_data;
+ rbd_get_dev(rbd_dev);
+
set_device_ro(bdev, rbd_dev->read_only);
if ((mode & FMODE_WRITE) && rbd_dev->read_only)
@@ -216,9 +192,19 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
return 0;
}
+static int rbd_release(struct gendisk *disk, fmode_t mode)
+{
+ struct rbd_device *rbd_dev = disk->private_data;
+
+ rbd_put_dev(rbd_dev);
+
+ return 0;
+}
+
static const struct block_device_operations rbd_bd_ops = {
.owner = THIS_MODULE,
.open = rbd_open,
+ .release = rbd_release,
};
/*
@@ -361,7 +347,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
int ret = -ENOMEM;
init_rwsem(&header->snap_rwsem);
-
header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
snap_count *
@@ -1256,10 +1241,20 @@ bad:
return -ERANGE;
}
+static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
+{
+ struct rbd_snap *snap;
+
+ while (!list_empty(&rbd_dev->snaps)) {
+ snap = list_first_entry(&rbd_dev->snaps, struct rbd_snap, node);
+ __rbd_remove_snap_dev(rbd_dev, snap);
+ }
+}
+
/*
* only read the first part of the ondisk header, without the snaps info
*/
-static int rbd_update_snaps(struct rbd_device *rbd_dev)
+static int __rbd_update_snaps(struct rbd_device *rbd_dev)
{
int ret;
struct rbd_image_header h;
@@ -1280,12 +1275,15 @@ static int rbd_update_snaps(struct rbd_device *rbd_dev)
rbd_dev->header.total_snaps = h.total_snaps;
rbd_dev->header.snapc = h.snapc;
rbd_dev->header.snap_names = h.snap_names;
+ rbd_dev->header.snap_names_len = h.snap_names_len;
rbd_dev->header.snap_sizes = h.snap_sizes;
rbd_dev->header.snapc->seq = snap_seq;
+ ret = __rbd_init_snaps_header(rbd_dev);
+
up_write(&rbd_dev->header.snap_rwsem);
- return 0;
+ return ret;
}
static int rbd_init_disk(struct rbd_device *rbd_dev)
@@ -1300,6 +1298,11 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
if (rc)
return rc;
+ /* no need to lock here, as rbd_dev is not registered yet */
+ rc = __rbd_init_snaps_header(rbd_dev);
+ if (rc)
+ return rc;
+
rc = rbd_header_set_snap(rbd_dev, rbd_dev->snap_name, &total_size);
if (rc)
return rc;
@@ -1343,54 +1346,360 @@ out:
return rc;
}
-/********************************************************************
- * /sys/class/rbd/
- * add map rados objects to blkdev
- * remove unmap rados objects
- * list show mappings
- *******************************************************************/
+/*
+ sysfs
+*/
+
+static ssize_t rbd_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%llu\n", (unsigned long long)rbd_dev->header.image_size);
+}
+
+static ssize_t rbd_major_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
-static void class_rbd_release(struct class *cls)
+ return sprintf(buf, "%d\n", rbd_dev->major);
+}
+
+static ssize_t rbd_client_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- kfree(cls);
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "client%lld\n", ceph_client_id(rbd_dev->client));
}
-static ssize_t class_rbd_list(struct class *c,
- struct class_attribute *attr,
- char *data)
+static ssize_t rbd_pool_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- int n = 0;
- struct list_head *tmp;
- int max = PAGE_SIZE;
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->pool_name);
+}
+
+static ssize_t rbd_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->obj);
+}
+
+static ssize_t rbd_snap_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->snap_name);
+}
+
+static ssize_t rbd_image_refresh(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int rc;
+ int ret = size;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- n += snprintf(data, max,
- "#id\tmajor\tclient_name\tpool\tname\tsnap\tKB\n");
+ rc = __rbd_update_snaps(rbd_dev);
+ if (rc < 0)
+ ret = rc;
- list_for_each(tmp, &rbd_dev_list) {
- struct rbd_device *rbd_dev;
+ mutex_unlock(&ctl_mutex);
+ return ret;
+}
- rbd_dev = list_entry(tmp, struct rbd_device, node);
- n += snprintf(data+n, max-n,
- "%d\t%d\tclient%lld\t%s\t%s\t%s\t%lld\n",
- rbd_dev->id,
- rbd_dev->major,
- ceph_client_id(rbd_dev->client),
- rbd_dev->pool_name,
- rbd_dev->obj, rbd_dev->snap_name,
- rbd_dev->header.image_size >> 10);
- if (n == max)
+static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
+static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
+static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
+static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
+static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
+static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);
+
+static struct attribute *rbd_attrs[] = {
+ &dev_attr_size.attr,
+ &dev_attr_major.attr,
+ &dev_attr_client_id.attr,
+ &dev_attr_pool.attr,
+ &dev_attr_name.attr,
+ &dev_attr_current_snap.attr,
+ &dev_attr_refresh.attr,
+ &dev_attr_create_snap.attr,
+ &dev_attr_rollback_snap.attr,
+ NULL
+};
+
+static struct attribute_group rbd_attr_group = {
+ .attrs = rbd_attrs,
+};
+
+static const struct attribute_group *rbd_attr_groups[] = {
+ &rbd_attr_group,
+ NULL
+};
+
+static void rbd_sysfs_dev_release(struct device *dev)
+{
+}
+
+static struct device_type rbd_device_type = {
+ .name = "rbd",
+ .groups = rbd_attr_groups,
+ .release = rbd_sysfs_dev_release,
+};
+
+
+/*
+ sysfs - snapshots
+*/
+
+static ssize_t rbd_snap_size_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+ return sprintf(buf, "%lld\n", (long long)snap->size);
+}
+
+static ssize_t rbd_snap_id_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+ return sprintf(buf, "%lld\n", (long long)snap->id);
+}
+
+static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
+static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+
+static struct attribute *rbd_snap_attrs[] = {
+ &dev_attr_snap_size.attr,
+ &dev_attr_snap_id.attr,
+ NULL,
+};
+
+static struct attribute_group rbd_snap_attr_group = {
+ .attrs = rbd_snap_attrs,
+};
+
+static void rbd_snap_dev_release(struct device *dev)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+ kfree(snap->name);
+ kfree(snap);
+}
+
+static const struct attribute_group *rbd_snap_attr_groups[] = {
+ &rbd_snap_attr_group,
+ NULL
+};
+
+static struct device_type rbd_snap_device_type = {
+ .groups = rbd_snap_attr_groups,
+ .release = rbd_snap_dev_release,
+};
+
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap)
+{
+ list_del(&snap->node);
+ device_unregister(&snap->dev);
+}
+
+static int rbd_register_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap,
+ struct device *parent)
+{
+ struct device *dev = &snap->dev;
+ int ret;
+
+ dev->type = &rbd_snap_device_type;
+ dev->parent = parent;
+ dev->release = rbd_snap_dev_release;
+ dev_set_name(dev, "snap_%s", snap->name);
+ ret = device_register(dev);
+
+ return ret;
+}
+
+static int __rbd_add_snap_dev(struct rbd_device *rbd_dev,
+ int i, const char *name,
+ struct rbd_snap **snapp)
+{
+ int ret;
+ struct rbd_snap *snap = kzalloc(sizeof(*snap), GFP_KERNEL);
+ if (!snap)
+ return -ENOMEM;
+ snap->name = kstrdup(name, GFP_KERNEL);
+ snap->size = rbd_dev->header.snap_sizes[i];
+ snap->id = rbd_dev->header.snapc->snaps[i];
+ if (device_is_registered(&rbd_dev->dev)) {
+ ret = rbd_register_snap_dev(rbd_dev, snap,
+ &rbd_dev->dev);
+ if (ret < 0)
+ goto err;
+ }
+ *snapp = snap;
+ return 0;
+err:
+ kfree(snap->name);
+ kfree(snap);
+ return ret;
+}
+
+/*
+ * search for the previous snap in a null delimited string list
+ */
+const char *rbd_prev_snap_name(const char *name, const char *start)
+{
+ if (name < start + 2)
+ return NULL;
+
+ name -= 2;
+ while (*name) {
+ if (name == start)
+ return start;
+ name--;
+ }
+ return name + 1;
+}
+
+/*
+ * compare the old list of snapshots that we have to what's in the header
+ * and update it accordingly. Note that the header holds the snapshots
+ * in a reverse order (from newest to oldest) and we need to go from
+ * older to new so that we don't get a duplicate snap name when
+ * doing the process (e.g., removed snapshot and recreated a new
+ * one with the same name.
+ */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+{
+ const char *name, *first_name;
+ int i = rbd_dev->header.total_snaps;
+ struct rbd_snap *snap, *old_snap = NULL;
+ int ret;
+ struct list_head *p, *n;
+
+ first_name = rbd_dev->header.snap_names;
+ name = first_name + rbd_dev->header.snap_names_len;
+
+ list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
+ u64 cur_id;
+
+ old_snap = list_entry(p, struct rbd_snap, node);
+
+ if (i)
+ cur_id = rbd_dev->header.snapc->snaps[i - 1];
+
+ if (!i || old_snap->id < cur_id) {
+ /* old_snap->id was skipped, thus was removed */
+ __rbd_remove_snap_dev(rbd_dev, old_snap);
+ continue;
+ }
+ if (old_snap->id == cur_id) {
+ /* we have this snapshot already */
+ i--;
+ name = rbd_prev_snap_name(name, first_name);
+ continue;
+ }
+ for (; i > 0;
+ i--, name = rbd_prev_snap_name(name, first_name)) {
+ if (!name) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ cur_id = rbd_dev->header.snapc->snaps[i];
+ /* snapshot removal? handle it above */
+ if (cur_id >= old_snap->id)
+ break;
+ /* a new snapshot */
+ ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+ if (ret < 0)
+ return ret;
+
+ /* note that we add it backward so using n and not p */
+ list_add(&snap->node, n);
+ p = &snap->node;
+ }
+ }
+ /* we're done going over the old snap list, just add what's left */
+ for (; i > 0; i--) {
+ name = rbd_prev_snap_name(name, first_name);
+ if (!name) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+ if (ret < 0)
+ return ret;
+ list_add(&snap->node, &rbd_dev->snaps);
+ }
+
+ return 0;
+}
+
+
+static void rbd_root_dev_release(struct device *dev)
+{
+}
+
+static struct device rbd_root_dev = {
+ .init_name = "rbd",
+ .release = rbd_root_dev_release,
+};
+
+static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
+{
+ int ret = -ENOMEM;
+ struct device *dev;
+ struct rbd_snap *snap;
+
+ mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+ dev = &rbd_dev->dev;
+
+ dev->bus = &rbd_bus_type;
+ dev->type = &rbd_device_type;
+ dev->parent = &rbd_root_dev;
+ dev->release = rbd_dev_release;
+ dev_set_name(dev, "%d", rbd_dev->id);
+ ret = device_register(dev);
+ if (ret < 0)
+ goto done_free;
+
+ list_for_each_entry(snap, &rbd_dev->snaps, node) {
+ ret = rbd_register_snap_dev(rbd_dev, snap,
+ &rbd_dev->dev);
+ if (ret < 0)
break;
}
mutex_unlock(&ctl_mutex);
- return n;
+ return 0;
+done_free:
+ mutex_unlock(&ctl_mutex);
+ return ret;
}
-static ssize_t class_rbd_add(struct class *c,
- struct class_attribute *attr,
- const char *buf, size_t count)
+static void rbd_bus_del_dev(struct rbd_device *rbd_dev)
+{
+ device_unregister(&rbd_dev->dev);
+}
+
+static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count)
{
struct ceph_osd_client *osdc;
struct rbd_device *rbd_dev;
@@ -1419,6 +1728,7 @@ static ssize_t class_rbd_add(struct class *c,
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
INIT_LIST_HEAD(&rbd_dev->node);
+ INIT_LIST_HEAD(&rbd_dev->snaps);
/* generate unique id: find highest unique id, add one */
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1478,6 +1788,9 @@ static ssize_t class_rbd_add(struct class *c,
}
rbd_dev->major = irc;
+ rc = rbd_bus_add_dev(rbd_dev);
+ if (rc)
+ goto err_out_disk;
/* set up and announce blkdev mapping */
rc = rbd_init_disk(rbd_dev);
if (rc)
@@ -1487,6 +1800,8 @@ static ssize_t class_rbd_add(struct class *c,
err_out_blkdev:
unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_disk:
+ rbd_free_disk(rbd_dev);
err_out_client:
rbd_put_client(rbd_dev);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1518,35 +1833,10 @@ static struct rbd_device *__rbd_get_dev(unsigned long id)
return NULL;
}
-static ssize_t class_rbd_remove(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static void rbd_dev_release(struct device *dev)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, rc;
- unsigned long ul;
-
- rc = strict_strtoul(buf, 10, &ul);
- if (rc)
- return rc;
-
- /* convert to int; abort if we lost anything in the conversion */
- target_id = (int) ul;
- if (target_id != ul)
- return -EINVAL;
-
- /* remove object from list immediately */
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
- rbd_dev = __rbd_get_dev(target_id);
- if (rbd_dev)
- list_del_init(&rbd_dev->node);
-
- mutex_unlock(&ctl_mutex);
-
- if (!rbd_dev)
- return -ENOENT;
+ struct rbd_device *rbd_dev =
+ container_of(dev, struct rbd_device, dev);
rbd_put_client(rbd_dev);
@@ -1557,67 +1847,11 @@ static ssize_t class_rbd_remove(struct class *c,
/* release module ref */
module_put(THIS_MODULE);
-
- return count;
}
-static ssize_t class_rbd_snaps_list(struct class *c,
- struct class_attribute *attr,
- char *data)
-{
- struct rbd_device *rbd_dev = NULL;
- struct list_head *tmp;
- struct rbd_image_header *header;
- int i, n = 0, max = PAGE_SIZE;
- int ret;
-
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
- n += snprintf(data, max, "#id\tsnap\tKB\n");
-
- list_for_each(tmp, &rbd_dev_list) {
- char *names, *p;
- struct ceph_snap_context *snapc;
-
- rbd_dev = list_entry(tmp, struct rbd_device, node);
- header = &rbd_dev->header;
-
- down_read(&header->snap_rwsem);
-
- names = header->snap_names;
- snapc = header->snapc;
-
- n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
- rbd_dev->id, RBD_SNAP_HEAD_NAME,
- header->image_size >> 10,
- (!rbd_dev->cur_snap ? " (*)" : ""));
- if (n == max)
- break;
-
- p = names;
- for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) {
- n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
- rbd_dev->id, p, header->snap_sizes[i] >> 10,
- (rbd_dev->cur_snap &&
- (snap_index(header, i) == rbd_dev->cur_snap) ?
- " (*)" : ""));
- if (n == max)
- break;
- }
-
- up_read(&header->snap_rwsem);
- }
-
-
- ret = n;
- mutex_unlock(&ctl_mutex);
- return ret;
-}
-
-static ssize_t class_rbd_snaps_refresh(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_remove(struct bus_type *bus,
+ const char *buf,
+ size_t count)
{
struct rbd_device *rbd_dev = NULL;
int target_id, rc;
@@ -1641,95 +1875,70 @@ static ssize_t class_rbd_snaps_refresh(struct class *c,
goto done;
}
- rc = rbd_update_snaps(rbd_dev);
- if (rc < 0)
- ret = rc;
+ list_del_init(&rbd_dev->node);
+
+ __rbd_remove_all_snaps(rbd_dev);
+ rbd_bus_del_dev(rbd_dev);
done:
mutex_unlock(&ctl_mutex);
return ret;
}
-static ssize_t class_rbd_snap_create(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_snap_add(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, ret;
- char *name;
-
- name = kmalloc(RBD_MAX_SNAP_NAME_LEN + 1, GFP_KERNEL);
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int ret;
+ char *name = kmalloc(count + 1, GFP_KERNEL);
if (!name)
return -ENOMEM;
- /* parse snaps add command */
- if (sscanf(buf, "%d "
- "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
- &target_id,
- name) != 2) {
- ret = -EINVAL;
- goto done;
- }
+ snprintf(name, count, "%s", buf);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- rbd_dev = __rbd_get_dev(target_id);
- if (!rbd_dev) {
- ret = -ENOENT;
- goto done_unlock;
- }
-
ret = rbd_header_add_snap(rbd_dev,
name, GFP_KERNEL);
if (ret < 0)
goto done_unlock;
- ret = rbd_update_snaps(rbd_dev);
+ ret = __rbd_update_snaps(rbd_dev);
if (ret < 0)
goto done_unlock;
ret = count;
done_unlock:
mutex_unlock(&ctl_mutex);
-done:
kfree(name);
return ret;
}
-static ssize_t class_rbd_rollback(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_snap_rollback(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, ret;
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int ret;
u64 snapid;
- char snap_name[RBD_MAX_SNAP_NAME_LEN];
u64 cur_ofs;
- char *seg_name;
+ char *seg_name = NULL;
+ char *snap_name = kmalloc(count + 1, GFP_KERNEL);
+ ret = -ENOMEM;
+ if (!snap_name)
+ return ret;
/* parse snaps add command */
- if (sscanf(buf, "%d "
- "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
- &target_id,
- snap_name) != 2) {
- return -EINVAL;
- }
-
- ret = -ENOMEM;
+ snprintf(snap_name, count, "%s", buf);
seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
if (!seg_name)
- return ret;
+ goto done;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- rbd_dev = __rbd_get_dev(target_id);
- if (!rbd_dev) {
- ret = -ENOENT;
- goto done_unlock;
- }
-
ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL);
if (ret < 0)
goto done_unlock;
@@ -1750,7 +1959,7 @@ static ssize_t class_rbd_rollback(struct class *c,
seg_name, ret);
}
- ret = rbd_update_snaps(rbd_dev);
+ ret = __rbd_update_snaps(rbd_dev);
if (ret < 0)
goto done_unlock;
@@ -1758,57 +1967,42 @@ static ssize_t class_rbd_rollback(struct class *c,
done_unlock:
mutex_unlock(&ctl_mutex);
+done:
kfree(seg_name);
+ kfree(snap_name);
return ret;
}
-static struct class_attribute class_rbd_attrs[] = {
- __ATTR(add, 0200, NULL, class_rbd_add),
- __ATTR(remove, 0200, NULL, class_rbd_remove),
- __ATTR(list, 0444, class_rbd_list, NULL),
- __ATTR(snaps_refresh, 0200, NULL, class_rbd_snaps_refresh),
- __ATTR(snap_create, 0200, NULL, class_rbd_snap_create),
- __ATTR(snaps_list, 0444, class_rbd_snaps_list, NULL),
- __ATTR(snap_rollback, 0200, NULL, class_rbd_rollback),
+static struct bus_attribute rbd_bus_attrs[] = {
+ __ATTR(add, S_IWUSR, NULL, rbd_add),
+ __ATTR(remove, S_IWUSR, NULL, rbd_remove),
__ATTR_NULL
};
/*
* create control files in sysfs
- * /sys/class/rbd/...
+ * /sys/bus/rbd/...
*/
static int rbd_sysfs_init(void)
{
- int ret = -ENOMEM;
+ int ret;
- class_rbd = kzalloc(sizeof(*class_rbd), GFP_KERNEL);
- if (!class_rbd)
- goto out;
+ rbd_bus_type.bus_attrs = rbd_bus_attrs;
- class_rbd->name = DRV_NAME;
- class_rbd->owner = THIS_MODULE;
- class_rbd->class_release = class_rbd_release;
- class_rbd->class_attrs = class_rbd_attrs;
+ ret = bus_register(&rbd_bus_type);
+ if (ret < 0)
+ return ret;
- ret = class_register(class_rbd);
- if (ret)
- goto out_class;
- return 0;
+ ret = device_register(&rbd_root_dev);
-out_class:
- kfree(class_rbd);
- class_rbd = NULL;
- pr_err(DRV_NAME ": failed to create class rbd\n");
-out:
return ret;
}
static void rbd_sysfs_cleanup(void)
{
- if (class_rbd)
- class_destroy(class_rbd);
- class_rbd = NULL;
+ device_unregister(&rbd_root_dev);
+ bus_unregister(&rbd_bus_type);
}
int __init rbd_init(void)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4f9e22f29138..657873e4328d 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -72,7 +72,7 @@ struct blk_shadow {
static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
+#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
/*
* We have one of these per vbd, whether ide, scsi or 'other'. They
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 128cae4e8629..949ed09c6361 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -35,6 +35,10 @@
static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
{ USB_DEVICE(0x0CF3, 0x3000) },
+
+ /* Atheros AR3011 with sflash firmware*/
+ { USB_DEVICE(0x0CF3, 0x3002) },
+
{ } /* Terminating entry */
};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ab3894f742c3..1da773f899a2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
+ /* Atheros 3011 with sflash firmware */
+ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 720148294e64..3c6cabcb7d84 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
+ if (hdev) {
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ }
}
}
}
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index af13c62dc473..14033a36bcd0 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1348,7 +1348,10 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
if (!CDROM_CAN(CDC_SELECT_DISC))
return -EDRIVE_CANT_DO_THIS;
- (void) cdi->ops->media_changed(cdi, slot);
+ if (cdi->ops->check_events)
+ cdi->ops->check_events(cdi, 0, slot);
+ else
+ cdi->ops->media_changed(cdi, slot);
if (slot == CDSL_NONE) {
/* set media changed bits, on both queues */
@@ -1392,6 +1395,42 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
return slot;
}
+/*
+ * As cdrom implements an extra ioctl consumer for media changed
+ * event, it needs to buffer ->check_events() output, such that event
+ * is not lost for both the usual VFS and ioctl paths.
+ * cdi->{vfs|ioctl}_events are used to buffer pending events for each
+ * path.
+ *
+ * XXX: Locking is non-existent. cdi->ops->check_events() can be
+ * called in parallel and buffering fields are accessed without any
+ * exclusion. The original media_changed code had the same problem.
+ * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl
+ * and remove this cruft altogether. It doesn't have much usefulness
+ * at this point.
+ */
+static void cdrom_update_events(struct cdrom_device_info *cdi,
+ unsigned int clearing)
+{
+ unsigned int events;
+
+ events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT);
+ cdi->vfs_events |= events;
+ cdi->ioctl_events |= events;
+}
+
+unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
+ unsigned int clearing)
+{
+ unsigned int events;
+
+ cdrom_update_events(cdi, clearing);
+ events = cdi->vfs_events;
+ cdi->vfs_events = 0;
+ return events;
+}
+EXPORT_SYMBOL(cdrom_check_events);
+
/* We want to make media_changed accessible to the user through an
* ioctl. The main problem now is that we must double-buffer the
* low-level implementation, to assure that the VFS and the user both
@@ -1403,15 +1442,26 @@ int media_changed(struct cdrom_device_info *cdi, int queue)
{
unsigned int mask = (1 << (queue & 1));
int ret = !!(cdi->mc_flags & mask);
+ bool changed;
if (!CDROM_CAN(CDC_MEDIA_CHANGED))
- return ret;
+ return ret;
+
/* changed since last call? */
- if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) {
+ if (cdi->ops->check_events) {
+ BUG_ON(!queue); /* shouldn't be called from VFS path */
+ cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE);
+ changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE;
+ cdi->ioctl_events = 0;
+ } else
+ changed = cdi->ops->media_changed(cdi, CDSL_CURRENT);
+
+ if (changed) {
cdi->mc_flags = 0x3; /* set bit on both queues */
ret |= 1;
cdi->media_written = 0;
}
+
cdi->mc_flags &= ~mask; /* clear bit */
return ret;
}
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 9272c38dd3c6..29ac6d499fa6 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void)
static void i830_cleanup(void)
{
- kunmap(intel_private.i8xx_page);
- intel_private.i8xx_flush_page = NULL;
+ if (intel_private.i8xx_flush_page) {
+ kunmap(intel_private.i8xx_flush_page);
+ intel_private.i8xx_flush_page = NULL;
+ }
__free_page(intel_private.i8xx_page);
intel_private.i8xx_page = NULL;
@@ -1190,12 +1192,19 @@ static void i9xx_chipset_flush(void)
writel(1, intel_private.i9xx_flush_page);
}
-static void i965_write_entry(dma_addr_t addr, unsigned int entry,
+static void i965_write_entry(dma_addr_t addr,
+ unsigned int entry,
unsigned int flags)
{
+ u32 pte_flags;
+
+ pte_flags = I810_PTE_VALID;
+ if (flags == AGP_USER_CACHED_MEMORY)
+ pte_flags |= I830_PTE_SYSTEM_CACHED;
+
/* Shift high bits down */
addr |= (addr >> 28) & 0xf0;
- writel(addr | I810_PTE_VALID, intel_private.gtt + entry);
+ writel(addr | pte_flags, intel_private.gtt + entry);
}
static bool gen6_check_flags(unsigned int flags)
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 27370e99c66f..5e2f52b33327 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -39,7 +39,7 @@
#include "hvc_console.h"
-char hvc_driver_name[] = "hvc_console";
+static const char hvc_driver_name[] = "hvc_console";
static struct vio_device_id hvc_driver_table[] __devinitdata = {
{"serial", "hvterm1"},
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 2fe72f8edf44..38223e93aa98 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -970,6 +970,33 @@ out_kfree:
}
EXPORT_SYMBOL(ipmi_create_user);
+int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
+{
+ int rv = 0;
+ ipmi_smi_t intf;
+ struct ipmi_smi_handlers *handlers;
+
+ mutex_lock(&ipmi_interfaces_mutex);
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ if (intf->intf_num == if_num)
+ goto found;
+ }
+ /* Not found, return an error */
+ rv = -EINVAL;
+ mutex_unlock(&ipmi_interfaces_mutex);
+ return rv;
+
+found:
+ handlers = intf->handlers;
+ rv = -ENOSYS;
+ if (handlers->get_smi_info)
+ rv = handlers->get_smi_info(intf->send_info, data);
+ mutex_unlock(&ipmi_interfaces_mutex);
+
+ return rv;
+}
+EXPORT_SYMBOL(ipmi_get_smi_info);
+
static void free_user(struct kref *ref)
{
ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 035da9e64a17..3a3643c6a579 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -57,6 +57,7 @@
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
+#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#include <asm/io.h>
#include "ipmi_si_sm.h"
@@ -107,10 +108,6 @@ enum si_type {
};
static char *si_to_str[] = { "kcs", "smic", "bt" };
-enum ipmi_addr_src {
- SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
- SI_PCI, SI_DEVICETREE, SI_DEFAULT
-};
static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI",
"ACPI", "SMBIOS", "PCI",
"device-tree", "default" };
@@ -291,6 +288,7 @@ struct smi_info {
struct task_struct *thread;
struct list_head link;
+ union ipmi_smi_info_union addr_info;
};
#define smi_inc_stat(smi, stat) \
@@ -1186,6 +1184,18 @@ static int smi_start_processing(void *send_info,
return 0;
}
+static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
+{
+ struct smi_info *smi = send_info;
+
+ data->addr_src = smi->addr_source;
+ data->dev = smi->dev;
+ data->addr_info = smi->addr_info;
+ get_device(smi->dev);
+
+ return 0;
+}
+
static void set_maintenance_mode(void *send_info, int enable)
{
struct smi_info *smi_info = send_info;
@@ -1197,6 +1207,7 @@ static void set_maintenance_mode(void *send_info, int enable)
static struct ipmi_smi_handlers handlers = {
.owner = THIS_MODULE,
.start_processing = smi_start_processing,
+ .get_smi_info = get_smi_info,
.sender = sender,
.request_events = request_events,
.set_maintenance_mode = set_maintenance_mode,
@@ -1928,7 +1939,8 @@ static void __devinit hardcode_find_bmc(void)
static int acpi_failure;
/* For GPE-type interrupts. */
-static u32 ipmi_acpi_gpe(void *context)
+static u32 ipmi_acpi_gpe(acpi_handle gpe_device,
+ u32 gpe_number, void *context)
{
struct smi_info *smi_info = context;
unsigned long flags;
@@ -2156,6 +2168,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
printk(KERN_INFO PFX "probing via ACPI\n");
handle = acpi_dev->handle;
+ info->addr_info.acpi_info.acpi_handle = handle;
/* _IFT tells us the interface type: KCS, BT, etc */
status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c
index 73dcb0ee41fd..d3d63be2cd37 100644
--- a/drivers/char/ramoops.c
+++ b/drivers/char/ramoops.c
@@ -29,7 +29,6 @@
#include <linux/ramoops.h>
#define RAMOOPS_KERNMSG_HDR "===="
-#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval))
#define RECORD_SIZE 4096
@@ -65,8 +64,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
struct ramoops_context, dump);
unsigned long s1_start, s2_start;
unsigned long l1_cpy, l2_cpy;
- int res;
- char *buf;
+ int res, hdr_size;
+ char *buf, *buf_orig;
struct timeval timestamp;
/* Only dump oopses if dump_oops is set */
@@ -74,6 +73,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
return;
buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE));
+ buf_orig = buf;
+
memset(buf, '\0', RECORD_SIZE);
res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
buf += res;
@@ -81,8 +82,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
buf += res;
- l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE));
- l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy);
+ hdr_size = buf - buf_orig;
+ l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size));
+ l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy);
s2_start = l2 - l2_cpy;
s1_start = l1 - l1_cpy;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index bfe25ea9766b..b4b9d5a47885 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp)
if (!bdev)
goto out;
igrab(bdev->bd_inode);
- err = blkdev_get(bdev, filp->f_mode);
+ err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
if (err)
goto out;
- err = bd_claim(bdev, raw_open);
- if (err)
- goto out1;
err = set_blocksize(bdev, bdev_logical_block_size(bdev));
if (err)
- goto out2;
+ goto out1;
filp->f_flags |= O_DIRECT;
filp->f_mapping = bdev->bd_inode->i_mapping;
if (++raw_devices[minor].inuse == 1)
@@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp)
mutex_unlock(&raw_mutex);
return 0;
-out2:
- bd_release(bdev);
out1:
- blkdev_put(bdev, filp->f_mode);
+ blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
out:
mutex_unlock(&raw_mutex);
return err;
@@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp)
}
mutex_unlock(&raw_mutex);
- bd_release(bdev);
- blkdev_put(bdev, filp->f_mode);
+ blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
return 0;
}
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
new file mode 100644
index 000000000000..4168c8896e16
--- /dev/null
+++ b/drivers/clk/Kconfig
@@ -0,0 +1,4 @@
+
+config CLKDEV_LOOKUP
+ bool
+ select HAVE_CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
new file mode 100644
index 000000000000..07613fa172c9
--- /dev/null
+++ b/drivers/clk/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
diff --git a/arch/arm/common/clkdev.c b/drivers/clk/clkdev.c
index e2b2bb66e094..0fc0a79852de 100644
--- a/arch/arm/common/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/common/clkdev.c
+ * drivers/clk/clkdev.c
*
* Copyright (C) 2008 Russell King.
*
@@ -18,10 +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>
+#include <linux/clkdev.h>
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
@@ -120,12 +117,12 @@ struct clk_lookup_alloc {
char con_id[MAX_CON_ID];
};
-struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
- const char *dev_fmt, ...)
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
{
struct clk_lookup_alloc *cla;
- cla = kzalloc(sizeof(*cla), GFP_KERNEL);
+ cla = __clkdev_alloc(sizeof(*cla));
if (!cla)
return NULL;
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index d68d3aa1814b..f975d24890fa 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
} while (delay);
}
-static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
{
- unsigned long flags;
-
if (delta > p->max_match_value)
dev_warn(&p->pdev->dev, "delta out of range\n");
- spin_lock_irqsave(&p->lock, flags);
p->next_match_value = delta;
sh_cmt_clock_event_program_verify(p, 0);
+}
+
+static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->lock, flags);
+ __sh_cmt_set_next(p, delta);
spin_unlock_irqrestore(&p->lock, flags);
}
@@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
/* setup timeout if no clockevent */
if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
- sh_cmt_set_next(p, p->max_match_value);
+ __sh_cmt_set_next(p, p->max_match_value);
out:
spin_unlock_irqrestore(&p->lock, flags);
@@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
/* adjust the timeout to maximum if only clocksource left */
if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
- sh_cmt_set_next(p, p->max_match_value);
+ __sh_cmt_set_next(p, p->max_match_value);
spin_unlock_irqrestore(&p->lock, flags);
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index e16c3fa8d2e3..05117f1ad867 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -36,6 +36,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
static struct cn_dev cdev;
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 526bfbf69611..b0d8f3df02e3 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -118,7 +118,7 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
if (wall)
*wall = (cputime64_t)jiffies_to_usecs(cur_wall_time);
- return (cputime64_t)jiffies_to_usecs(idle_time);;
+ return (cputime64_t)jiffies_to_usecs(idle_time);
}
static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 7d279e578df5..c99305afa58a 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -857,7 +857,7 @@ static int mv_cra_hash_init(struct crypto_tfm *tfm, const char *base_hash_name,
printk(KERN_WARNING MV_CESA
"Base driver '%s' could not be loaded!\n",
base_hash_name);
- err = PTR_ERR(fallback_tfm);
+ err = PTR_ERR(base_hash);
goto err_bad_base;
}
}
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 799ca517c121..add2a1a72ba4 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -74,11 +74,9 @@
#define FLAGS_CBC BIT(1)
#define FLAGS_GIV BIT(2)
-#define FLAGS_NEW_KEY BIT(4)
-#define FLAGS_NEW_IV BIT(5)
-#define FLAGS_INIT BIT(6)
-#define FLAGS_FAST BIT(7)
-#define FLAGS_BUSY 8
+#define FLAGS_INIT BIT(4)
+#define FLAGS_FAST BIT(5)
+#define FLAGS_BUSY BIT(6)
struct omap_aes_ctx {
struct omap_aes_dev *dd;
@@ -98,19 +96,18 @@ struct omap_aes_reqctx {
struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
- void __iomem *io_base;
+ void __iomem *io_base;
struct clk *iclk;
struct omap_aes_ctx *ctx;
struct device *dev;
unsigned long flags;
+ int err;
- u32 *iv;
- u32 ctrl;
+ spinlock_t lock;
+ struct crypto_queue queue;
- spinlock_t lock;
- struct crypto_queue queue;
-
- struct tasklet_struct task;
+ struct tasklet_struct done_task;
+ struct tasklet_struct queue_task;
struct ablkcipher_request *req;
size_t total;
@@ -179,9 +176,13 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)
static int omap_aes_hw_init(struct omap_aes_dev *dd)
{
- int err = 0;
-
+ /*
+ * clocks are enabled when request starts and disabled when finished.
+ * It may be long delays between requests.
+ * Device might go to off mode to save power.
+ */
clk_enable(dd->iclk);
+
if (!(dd->flags & FLAGS_INIT)) {
/* is it necessary to reset before every operation? */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
@@ -193,39 +194,26 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
- err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
- AES_REG_SYSSTATUS_RESETDONE);
- if (!err)
- dd->flags |= FLAGS_INIT;
- }
+ if (omap_aes_wait(dd, AES_REG_SYSSTATUS,
+ AES_REG_SYSSTATUS_RESETDONE))
+ return -ETIMEDOUT;
- return err;
-}
+ dd->flags |= FLAGS_INIT;
+ dd->err = 0;
+ }
-static void omap_aes_hw_cleanup(struct omap_aes_dev *dd)
-{
- clk_disable(dd->iclk);
+ return 0;
}
-static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
+static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
{
unsigned int key32;
- int i;
+ int i, err;
u32 val, mask;
- val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
- if (dd->flags & FLAGS_CBC)
- val |= AES_REG_CTRL_CBC;
- if (dd->flags & FLAGS_ENCRYPT)
- val |= AES_REG_CTRL_DIRECTION;
-
- if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) &&
- !(dd->ctx->flags & FLAGS_NEW_KEY))
- goto out;
-
- /* only need to write control registers for new settings */
-
- dd->ctrl = val;
+ err = omap_aes_hw_init(dd);
+ if (err)
+ return err;
val = 0;
if (dd->dma_lch_out >= 0)
@@ -237,30 +225,43 @@ static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
omap_aes_write_mask(dd, AES_REG_MASK, val, mask);
- pr_debug("Set key\n");
key32 = dd->ctx->keylen / sizeof(u32);
- /* set a key */
+
+ /* it seems a key should always be set even if it has not changed */
for (i = 0; i < key32; i++) {
omap_aes_write(dd, AES_REG_KEY(i),
__le32_to_cpu(dd->ctx->key[i]));
}
- dd->ctx->flags &= ~FLAGS_NEW_KEY;
- if (dd->flags & FLAGS_NEW_IV) {
- pr_debug("Set IV\n");
- omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4);
- dd->flags &= ~FLAGS_NEW_IV;
- }
+ if ((dd->flags & FLAGS_CBC) && dd->req->info)
+ omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
+
+ val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
+ if (dd->flags & FLAGS_CBC)
+ val |= AES_REG_CTRL_CBC;
+ if (dd->flags & FLAGS_ENCRYPT)
+ val |= AES_REG_CTRL_DIRECTION;
mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE;
- omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask);
+ omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);
-out:
- /* start DMA or disable idle mode */
- omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
- AES_REG_MASK_START);
+ /* IN */
+ omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+
+ /* OUT */
+ omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+
+ return 0;
}
static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
@@ -288,8 +289,16 @@ static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_aes_dev *dd = data;
- if (lch == dd->dma_lch_out)
- tasklet_schedule(&dd->task);
+ if (ch_status != OMAP_DMA_BLOCK_IRQ) {
+ pr_err("omap-aes DMA error status: 0x%hx\n", ch_status);
+ dd->err = -EIO;
+ dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
+ } else if (lch == dd->dma_lch_in) {
+ return;
+ }
+
+ /* dma_lch_out - completed */
+ tasklet_schedule(&dd->done_task);
}
static int omap_aes_dma_init(struct omap_aes_dev *dd)
@@ -339,18 +348,6 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
goto err_dma_out;
}
- omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
-
- omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
-
return 0;
err_dma_out:
@@ -406,6 +403,11 @@ static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
if (!count)
return off;
+ /*
+ * buflen and total are AES_BLOCK_SIZE size aligned,
+ * so count should be also aligned
+ */
+
sg_copy_buf(buf + off, *sg, *offset, count, out);
off += count;
@@ -461,7 +463,9 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
omap_start_dma(dd->dma_lch_in);
omap_start_dma(dd->dma_lch_out);
- omap_aes_write_ctrl(dd);
+ /* start DMA or disable idle mode */
+ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
+ AES_REG_MASK_START);
return 0;
}
@@ -488,8 +492,10 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
count = min(dd->total, sg_dma_len(dd->in_sg));
count = min(count, sg_dma_len(dd->out_sg));
- if (count != dd->total)
+ if (count != dd->total) {
+ pr_err("request length != buffer length\n");
return -EINVAL;
+ }
pr_debug("fast\n");
@@ -525,23 +531,25 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
dd->total -= count;
- err = omap_aes_hw_init(dd);
-
err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count);
+ if (err) {
+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
+ }
return err;
}
static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
{
- struct omap_aes_ctx *ctx;
+ struct ablkcipher_request *req = dd->req;
pr_debug("err: %d\n", err);
- ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req));
+ clk_disable(dd->iclk);
+ dd->flags &= ~FLAGS_BUSY;
- if (!dd->total)
- dd->req->base.complete(&dd->req->base, err);
+ req->base.complete(&req->base, err);
}
static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
@@ -553,8 +561,6 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);
- omap_aes_hw_cleanup(dd);
-
omap_stop_dma(dd->dma_lch_in);
omap_stop_dma(dd->dma_lch_out);
@@ -574,40 +580,39 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
}
}
- if (err || !dd->total)
- omap_aes_finish_req(dd, err);
-
return err;
}
-static int omap_aes_handle_req(struct omap_aes_dev *dd)
+static int omap_aes_handle_queue(struct omap_aes_dev *dd,
+ struct ablkcipher_request *req)
{
struct crypto_async_request *async_req, *backlog;
struct omap_aes_ctx *ctx;
struct omap_aes_reqctx *rctx;
- struct ablkcipher_request *req;
unsigned long flags;
-
- if (dd->total)
- goto start;
+ int err, ret = 0;
spin_lock_irqsave(&dd->lock, flags);
+ if (req)
+ ret = ablkcipher_enqueue_request(&dd->queue, req);
+ if (dd->flags & FLAGS_BUSY) {
+ spin_unlock_irqrestore(&dd->lock, flags);
+ return ret;
+ }
backlog = crypto_get_backlog(&dd->queue);
async_req = crypto_dequeue_request(&dd->queue);
- if (!async_req)
- clear_bit(FLAGS_BUSY, &dd->flags);
+ if (async_req)
+ dd->flags |= FLAGS_BUSY;
spin_unlock_irqrestore(&dd->lock, flags);
if (!async_req)
- return 0;
+ return ret;
if (backlog)
backlog->complete(backlog, -EINPROGRESS);
req = ablkcipher_request_cast(async_req);
- pr_debug("get new req\n");
-
/* assign new request to device */
dd->req = req;
dd->total = req->nbytes;
@@ -621,27 +626,22 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd)
rctx->mode &= FLAGS_MODE_MASK;
dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
- dd->iv = req->info;
- if ((dd->flags & FLAGS_CBC) && dd->iv)
- dd->flags |= FLAGS_NEW_IV;
- else
- dd->flags &= ~FLAGS_NEW_IV;
-
+ dd->ctx = ctx;
ctx->dd = dd;
- if (dd->ctx != ctx) {
- /* assign new context to device */
- dd->ctx = ctx;
- ctx->flags |= FLAGS_NEW_KEY;
- }
- if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
- pr_err("request size is not exact amount of AES blocks\n");
+ err = omap_aes_write_ctrl(dd);
+ if (!err)
+ err = omap_aes_crypt_dma_start(dd);
+ if (err) {
+ /* aes_task will not finish it, so do it here */
+ omap_aes_finish_req(dd, err);
+ tasklet_schedule(&dd->queue_task);
+ }
-start:
- return omap_aes_crypt_dma_start(dd);
+ return ret; /* return ret, which is enqueue return value */
}
-static void omap_aes_task(unsigned long data)
+static void omap_aes_done_task(unsigned long data)
{
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
int err;
@@ -650,40 +650,50 @@ static void omap_aes_task(unsigned long data)
err = omap_aes_crypt_dma_stop(dd);
- err = omap_aes_handle_req(dd);
+ err = dd->err ? : err;
+
+ if (dd->total && !err) {
+ err = omap_aes_crypt_dma_start(dd);
+ if (!err)
+ return; /* DMA started. Not fininishing. */
+ }
+
+ omap_aes_finish_req(dd, err);
+ omap_aes_handle_queue(dd, NULL);
pr_debug("exit\n");
}
+static void omap_aes_queue_task(unsigned long data)
+{
+ struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
+
+ omap_aes_handle_queue(dd, NULL);
+}
+
static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
{
struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
crypto_ablkcipher_reqtfm(req));
struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
struct omap_aes_dev *dd;
- unsigned long flags;
- int err;
pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
!!(mode & FLAGS_ENCRYPT),
!!(mode & FLAGS_CBC));
+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
+ pr_err("request size is not exact amount of AES blocks\n");
+ return -EINVAL;
+ }
+
dd = omap_aes_find_dev(ctx);
if (!dd)
return -ENODEV;
rctx->mode = mode;
- spin_lock_irqsave(&dd->lock, flags);
- err = ablkcipher_enqueue_request(&dd->queue, req);
- spin_unlock_irqrestore(&dd->lock, flags);
-
- if (!test_and_set_bit(FLAGS_BUSY, &dd->flags))
- omap_aes_handle_req(dd);
-
- pr_debug("exit\n");
-
- return err;
+ return omap_aes_handle_queue(dd, req);
}
/* ********************** ALG API ************************************ */
@@ -701,7 +711,6 @@ static int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
memcpy(ctx->key, key, keylen);
ctx->keylen = keylen;
- ctx->flags |= FLAGS_NEW_KEY;
return 0;
}
@@ -750,7 +759,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
@@ -770,7 +779,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
@@ -849,7 +858,8 @@ static int omap_aes_probe(struct platform_device *pdev)
(reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
clk_disable(dd->iclk);
- tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd);
+ tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
+ tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd);
err = omap_aes_dma_init(dd);
if (err)
@@ -876,7 +886,8 @@ err_algs:
crypto_unregister_alg(&algs[j]);
omap_aes_dma_cleanup(dd);
err_dma:
- tasklet_kill(&dd->task);
+ tasklet_kill(&dd->done_task);
+ tasklet_kill(&dd->queue_task);
iounmap(dd->io_base);
err_io:
clk_put(dd->iclk);
@@ -903,7 +914,8 @@ static int omap_aes_remove(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(algs); i++)
crypto_unregister_alg(&algs[i]);
- tasklet_kill(&dd->task);
+ tasklet_kill(&dd->done_task);
+ tasklet_kill(&dd->queue_task);
omap_aes_dma_cleanup(dd);
iounmap(dd->io_base);
clk_put(dd->iclk);
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index a081c7c7d03f..2e71123516e0 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -72,10 +72,9 @@
#define DEFAULT_TIMEOUT_INTERVAL HZ
-#define FLAGS_FIRST 0x0001
#define FLAGS_FINUP 0x0002
#define FLAGS_FINAL 0x0004
-#define FLAGS_FAST 0x0008
+#define FLAGS_SG 0x0008
#define FLAGS_SHA1 0x0010
#define FLAGS_DMA_ACTIVE 0x0020
#define FLAGS_OUTPUT_READY 0x0040
@@ -83,13 +82,17 @@
#define FLAGS_INIT 0x0100
#define FLAGS_CPU 0x0200
#define FLAGS_HMAC 0x0400
-
-/* 3rd byte */
-#define FLAGS_BUSY 16
+#define FLAGS_ERROR 0x0800
+#define FLAGS_BUSY 0x1000
#define OP_UPDATE 1
#define OP_FINAL 2
+#define OMAP_ALIGN_MASK (sizeof(u32)-1)
+#define OMAP_ALIGNED __attribute__((aligned(sizeof(u32))))
+
+#define BUFLEN PAGE_SIZE
+
struct omap_sham_dev;
struct omap_sham_reqctx {
@@ -97,8 +100,8 @@ struct omap_sham_reqctx {
unsigned long flags;
unsigned long op;
+ u8 digest[SHA1_DIGEST_SIZE] OMAP_ALIGNED;
size_t digcnt;
- u8 *buffer;
size_t bufcnt;
size_t buflen;
dma_addr_t dma_addr;
@@ -107,6 +110,8 @@ struct omap_sham_reqctx {
struct scatterlist *sg;
unsigned int offset; /* offset in current sg */
unsigned int total; /* total request */
+
+ u8 buffer[0] OMAP_ALIGNED;
};
struct omap_sham_hmac_ctx {
@@ -136,6 +141,7 @@ struct omap_sham_dev {
int irq;
struct clk *iclk;
spinlock_t lock;
+ int err;
int dma;
int dma_lch;
struct tasklet_struct done_task;
@@ -194,53 +200,68 @@ static inline int omap_sham_wait(struct omap_sham_dev *dd, u32 offset, u32 bit)
static void omap_sham_copy_hash(struct ahash_request *req, int out)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
+ u32 *hash = (u32 *)ctx->digest;
+ int i;
+
+ /* MD5 is almost unused. So copy sha1 size to reduce code */
+ for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
+ if (out)
+ hash[i] = omap_sham_read(ctx->dd,
+ SHA_REG_DIGEST(i));
+ else
+ omap_sham_write(ctx->dd,
+ SHA_REG_DIGEST(i), hash[i]);
+ }
+}
+
+static void omap_sham_copy_ready_hash(struct ahash_request *req)
+{
+ struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
+ u32 *in = (u32 *)ctx->digest;
u32 *hash = (u32 *)req->result;
int i;
+ if (!hash)
+ return;
+
if (likely(ctx->flags & FLAGS_SHA1)) {
/* SHA1 results are in big endian */
for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++)
- if (out)
- hash[i] = be32_to_cpu(omap_sham_read(ctx->dd,
- SHA_REG_DIGEST(i)));
- else
- omap_sham_write(ctx->dd, SHA_REG_DIGEST(i),
- cpu_to_be32(hash[i]));
+ hash[i] = be32_to_cpu(in[i]);
} else {
/* MD5 results are in little endian */
for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++)
- if (out)
- hash[i] = le32_to_cpu(omap_sham_read(ctx->dd,
- SHA_REG_DIGEST(i)));
- else
- omap_sham_write(ctx->dd, SHA_REG_DIGEST(i),
- cpu_to_le32(hash[i]));
+ hash[i] = le32_to_cpu(in[i]);
}
}
-static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
- int final, int dma)
+static int omap_sham_hw_init(struct omap_sham_dev *dd)
{
- struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
- u32 val = length << 5, mask;
+ clk_enable(dd->iclk);
- if (unlikely(!ctx->digcnt)) {
+ if (!(dd->flags & FLAGS_INIT)) {
+ omap_sham_write_mask(dd, SHA_REG_MASK,
+ SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
- clk_enable(dd->iclk);
+ if (omap_sham_wait(dd, SHA_REG_SYSSTATUS,
+ SHA_REG_SYSSTATUS_RESETDONE))
+ return -ETIMEDOUT;
- if (!(dd->flags & FLAGS_INIT)) {
- omap_sham_write_mask(dd, SHA_REG_MASK,
- SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
+ dd->flags |= FLAGS_INIT;
+ dd->err = 0;
+ }
- if (omap_sham_wait(dd, SHA_REG_SYSSTATUS,
- SHA_REG_SYSSTATUS_RESETDONE))
- return -ETIMEDOUT;
+ return 0;
+}
- dd->flags |= FLAGS_INIT;
- }
- } else {
+static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
+ int final, int dma)
+{
+ struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
+ u32 val = length << 5, mask;
+
+ if (likely(ctx->digcnt))
omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt);
- }
omap_sham_write_mask(dd, SHA_REG_MASK,
SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0),
@@ -260,29 +281,26 @@ static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
SHA_REG_CTRL_ALGO | SHA_REG_CTRL_LENGTH;
omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask);
-
- return 0;
}
static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
size_t length, int final)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
- int err, count, len32;
+ int count, len32;
const u32 *buffer = (const u32 *)buf;
dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n",
ctx->digcnt, length, final);
- err = omap_sham_write_ctrl(dd, length, final, 0);
- if (err)
- return err;
+ omap_sham_write_ctrl(dd, length, final, 0);
+
+ /* should be non-zero before next lines to disable clocks later */
+ ctx->digcnt += length;
if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY))
return -ETIMEDOUT;
- ctx->digcnt += length;
-
if (final)
ctx->flags |= FLAGS_FINAL; /* catch last interrupt */
@@ -298,16 +316,11 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
size_t length, int final)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
- int err, len32;
+ int len32;
dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
ctx->digcnt, length, final);
- /* flush cache entries related to our page */
- if (dma_addr == ctx->dma_addr)
- dma_sync_single_for_device(dd->dev, dma_addr, length,
- DMA_TO_DEVICE);
-
len32 = DIV_ROUND_UP(length, sizeof(u32));
omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
@@ -317,9 +330,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
dma_addr, 0, 0);
- err = omap_sham_write_ctrl(dd, length, final, 1);
- if (err)
- return err;
+ omap_sham_write_ctrl(dd, length, final, 1);
ctx->digcnt += length;
@@ -371,15 +382,29 @@ static size_t omap_sham_append_sg(struct omap_sham_reqctx *ctx)
return 0;
}
+static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
+ struct omap_sham_reqctx *ctx,
+ size_t length, int final)
+{
+ ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
+ dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen);
+ return -EINVAL;
+ }
+
+ ctx->flags &= ~FLAGS_SG;
+
+ /* next call does not fail... so no unmap in the case of error */
+ return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final);
+}
+
static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
unsigned int final;
size_t count;
- if (!ctx->total)
- return 0;
-
omap_sham_append_sg(ctx);
final = (ctx->flags & FLAGS_FINUP) && !ctx->total;
@@ -390,30 +415,68 @@ static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) {
count = ctx->bufcnt;
ctx->bufcnt = 0;
- return omap_sham_xmit_dma(dd, ctx->dma_addr, count, final);
+ return omap_sham_xmit_dma_map(dd, ctx, count, final);
}
return 0;
}
-static int omap_sham_update_dma_fast(struct omap_sham_dev *dd)
+/* Start address alignment */
+#define SG_AA(sg) (IS_ALIGNED(sg->offset, sizeof(u32)))
+/* SHA1 block size alignment */
+#define SG_SA(sg) (IS_ALIGNED(sg->length, SHA1_MD5_BLOCK_SIZE))
+
+static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
- unsigned int length;
+ unsigned int length, final, tail;
+ struct scatterlist *sg;
- ctx->flags |= FLAGS_FAST;
+ if (!ctx->total)
+ return 0;
+
+ if (ctx->bufcnt || ctx->offset)
+ return omap_sham_update_dma_slow(dd);
+
+ dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
+ ctx->digcnt, ctx->bufcnt, ctx->total);
+
+ sg = ctx->sg;
- length = min(ctx->total, sg_dma_len(ctx->sg));
- ctx->total = length;
+ if (!SG_AA(sg))
+ return omap_sham_update_dma_slow(dd);
+
+ if (!sg_is_last(sg) && !SG_SA(sg))
+ /* size is not SHA1_BLOCK_SIZE aligned */
+ return omap_sham_update_dma_slow(dd);
+
+ length = min(ctx->total, sg->length);
+
+ if (sg_is_last(sg)) {
+ if (!(ctx->flags & FLAGS_FINUP)) {
+ /* not last sg must be SHA1_MD5_BLOCK_SIZE aligned */
+ tail = length & (SHA1_MD5_BLOCK_SIZE - 1);
+ /* without finup() we need one block to close hash */
+ if (!tail)
+ tail = SHA1_MD5_BLOCK_SIZE;
+ length -= tail;
+ }
+ }
if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) {
dev_err(dd->dev, "dma_map_sg error\n");
return -EINVAL;
}
+ ctx->flags |= FLAGS_SG;
+
ctx->total -= length;
+ ctx->offset = length; /* offset where to start slow */
- return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1);
+ final = (ctx->flags & FLAGS_FINUP) && !ctx->total;
+
+ /* next call does not fail... so no unmap in the case of error */
+ return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final);
}
static int omap_sham_update_cpu(struct omap_sham_dev *dd)
@@ -433,8 +496,17 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
omap_stop_dma(dd->dma_lch);
- if (ctx->flags & FLAGS_FAST)
+ if (ctx->flags & FLAGS_SG) {
dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
+ if (ctx->sg->length == ctx->offset) {
+ ctx->sg = sg_next(ctx->sg);
+ if (ctx->sg)
+ ctx->offset = 0;
+ }
+ } else {
+ dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
+ DMA_TO_DEVICE);
+ }
return 0;
}
@@ -454,14 +526,7 @@ static void omap_sham_cleanup(struct ahash_request *req)
spin_unlock_irqrestore(&dd->lock, flags);
if (ctx->digcnt)
- clk_disable(dd->iclk);
-
- if (ctx->dma_addr)
- dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
- DMA_TO_DEVICE);
-
- if (ctx->buffer)
- free_page((unsigned long)ctx->buffer);
+ omap_sham_copy_ready_hash(req);
dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt);
}
@@ -489,8 +554,6 @@ static int omap_sham_init(struct ahash_request *req)
ctx->flags = 0;
- ctx->flags |= FLAGS_FIRST;
-
dev_dbg(dd->dev, "init: digest size: %d\n",
crypto_ahash_digestsize(tfm));
@@ -499,21 +562,7 @@ static int omap_sham_init(struct ahash_request *req)
ctx->bufcnt = 0;
ctx->digcnt = 0;
-
- ctx->buflen = PAGE_SIZE;
- ctx->buffer = (void *)__get_free_page(
- (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
- GFP_KERNEL : GFP_ATOMIC);
- if (!ctx->buffer)
- return -ENOMEM;
-
- ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
- DMA_TO_DEVICE);
- if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
- dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen);
- free_page((unsigned long)ctx->buffer);
- return -EINVAL;
- }
+ ctx->buflen = BUFLEN;
if (tctx->flags & FLAGS_HMAC) {
struct omap_sham_hmac_ctx *bctx = tctx->base;
@@ -538,10 +587,8 @@ static int omap_sham_update_req(struct omap_sham_dev *dd)
if (ctx->flags & FLAGS_CPU)
err = omap_sham_update_cpu(dd);
- else if (ctx->flags & FLAGS_FAST)
- err = omap_sham_update_dma_fast(dd);
else
- err = omap_sham_update_dma_slow(dd);
+ err = omap_sham_update_dma_start(dd);
/* wait for dma completion before can take more data */
dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt);
@@ -560,15 +607,12 @@ static int omap_sham_final_req(struct omap_sham_dev *dd)
use_dma = 0;
if (use_dma)
- err = omap_sham_xmit_dma(dd, ctx->dma_addr, ctx->bufcnt, 1);
+ err = omap_sham_xmit_dma_map(dd, ctx, ctx->bufcnt, 1);
else
err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1);
ctx->bufcnt = 0;
- if (err != -EINPROGRESS)
- omap_sham_cleanup(req);
-
dev_dbg(dd->dev, "final_req: err: %d\n", err);
return err;
@@ -576,6 +620,7 @@ static int omap_sham_final_req(struct omap_sham_dev *dd)
static int omap_sham_finish_req_hmac(struct ahash_request *req)
{
+ struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
struct omap_sham_hmac_ctx *bctx = tctx->base;
int bs = crypto_shash_blocksize(bctx->shash);
@@ -590,48 +635,56 @@ static int omap_sham_finish_req_hmac(struct ahash_request *req)
return crypto_shash_init(&desc.shash) ?:
crypto_shash_update(&desc.shash, bctx->opad, bs) ?:
- crypto_shash_finup(&desc.shash, req->result, ds, req->result);
+ crypto_shash_finup(&desc.shash, ctx->digest, ds, ctx->digest);
}
static void omap_sham_finish_req(struct ahash_request *req, int err)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
+ struct omap_sham_dev *dd = ctx->dd;
if (!err) {
omap_sham_copy_hash(ctx->dd->req, 1);
if (ctx->flags & FLAGS_HMAC)
err = omap_sham_finish_req_hmac(req);
+ } else {
+ ctx->flags |= FLAGS_ERROR;
}
- if (ctx->flags & FLAGS_FINAL)
+ if ((ctx->flags & FLAGS_FINAL) || err)
omap_sham_cleanup(req);
- clear_bit(FLAGS_BUSY, &ctx->dd->flags);
+ clk_disable(dd->iclk);
+ dd->flags &= ~FLAGS_BUSY;
if (req->base.complete)
req->base.complete(&req->base, err);
}
-static int omap_sham_handle_queue(struct omap_sham_dev *dd)
+static int omap_sham_handle_queue(struct omap_sham_dev *dd,
+ struct ahash_request *req)
{
struct crypto_async_request *async_req, *backlog;
struct omap_sham_reqctx *ctx;
- struct ahash_request *req, *prev_req;
+ struct ahash_request *prev_req;
unsigned long flags;
- int err = 0;
-
- if (test_and_set_bit(FLAGS_BUSY, &dd->flags))
- return 0;
+ int err = 0, ret = 0;
spin_lock_irqsave(&dd->lock, flags);
+ if (req)
+ ret = ahash_enqueue_request(&dd->queue, req);
+ if (dd->flags & FLAGS_BUSY) {
+ spin_unlock_irqrestore(&dd->lock, flags);
+ return ret;
+ }
backlog = crypto_get_backlog(&dd->queue);
async_req = crypto_dequeue_request(&dd->queue);
- if (!async_req)
- clear_bit(FLAGS_BUSY, &dd->flags);
+ if (async_req)
+ dd->flags |= FLAGS_BUSY;
spin_unlock_irqrestore(&dd->lock, flags);
if (!async_req)
- return 0;
+ return ret;
if (backlog)
backlog->complete(backlog, -EINPROGRESS);
@@ -646,7 +699,22 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd)
dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
ctx->op, req->nbytes);
- if (req != prev_req && ctx->digcnt)
+
+ err = omap_sham_hw_init(dd);
+ if (err)
+ goto err1;
+
+ omap_set_dma_dest_params(dd->dma_lch, 0,
+ OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + SHA_REG_DIN(0), 0, 16);
+
+ omap_set_dma_dest_burst_mode(dd->dma_lch,
+ OMAP_DMA_DATA_BURST_16);
+
+ omap_set_dma_src_burst_mode(dd->dma_lch,
+ OMAP_DMA_DATA_BURST_4);
+
+ if (ctx->digcnt)
/* request has changed - restore hash */
omap_sham_copy_hash(req, 0);
@@ -658,7 +726,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd)
} else if (ctx->op == OP_FINAL) {
err = omap_sham_final_req(dd);
}
-
+err1:
if (err != -EINPROGRESS) {
/* done_task will not finish it, so do it here */
omap_sham_finish_req(req, err);
@@ -667,7 +735,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd)
dev_dbg(dd->dev, "exit, err: %d\n", err);
- return err;
+ return ret;
}
static int omap_sham_enqueue(struct ahash_request *req, unsigned int op)
@@ -675,18 +743,10 @@ static int omap_sham_enqueue(struct ahash_request *req, unsigned int op)
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
struct omap_sham_dev *dd = tctx->dd;
- unsigned long flags;
- int err;
ctx->op = op;
- spin_lock_irqsave(&dd->lock, flags);
- err = ahash_enqueue_request(&dd->queue, req);
- spin_unlock_irqrestore(&dd->lock, flags);
-
- omap_sham_handle_queue(dd);
-
- return err;
+ return omap_sham_handle_queue(dd, req);
}
static int omap_sham_update(struct ahash_request *req)
@@ -709,21 +769,13 @@ static int omap_sham_update(struct ahash_request *req)
*/
omap_sham_append_sg(ctx);
return 0;
- } else if (ctx->bufcnt + ctx->total <= 64) {
+ } else if (ctx->bufcnt + ctx->total <= SHA1_MD5_BLOCK_SIZE) {
+ /*
+ * faster to use CPU for short transfers
+ */
ctx->flags |= FLAGS_CPU;
- } else if (!ctx->bufcnt && sg_is_last(ctx->sg)) {
- /* may be can use faster functions */
- int aligned = IS_ALIGNED((u32)ctx->sg->offset,
- sizeof(u32));
-
- if (aligned && (ctx->flags & FLAGS_FIRST))
- /* digest: first and final */
- ctx->flags |= FLAGS_FAST;
-
- ctx->flags &= ~FLAGS_FIRST;
}
- } else if (ctx->bufcnt + ctx->total <= ctx->buflen) {
- /* if not finaup -> not fast */
+ } else if (ctx->bufcnt + ctx->total < ctx->buflen) {
omap_sham_append_sg(ctx);
return 0;
}
@@ -761,12 +813,14 @@ static int omap_sham_final(struct ahash_request *req)
ctx->flags |= FLAGS_FINUP;
- /* OMAP HW accel works only with buffers >= 9 */
- /* HMAC is always >= 9 because of ipad */
- if ((ctx->digcnt + ctx->bufcnt) < 9)
- err = omap_sham_final_shash(req);
- else if (ctx->bufcnt)
- return omap_sham_enqueue(req, OP_FINAL);
+ if (!(ctx->flags & FLAGS_ERROR)) {
+ /* OMAP HW accel works only with buffers >= 9 */
+ /* HMAC is always >= 9 because of ipad */
+ if ((ctx->digcnt + ctx->bufcnt) < 9)
+ err = omap_sham_final_shash(req);
+ else if (ctx->bufcnt)
+ return omap_sham_enqueue(req, OP_FINAL);
+ }
omap_sham_cleanup(req);
@@ -836,6 +890,8 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm);
const char *alg_name = crypto_tfm_alg_name(tfm);
+ pr_info("enter\n");
+
/* Allocate a fallback and abort if it failed. */
tctx->fallback = crypto_alloc_shash(alg_name, 0,
CRYPTO_ALG_NEED_FALLBACK);
@@ -846,7 +902,7 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
}
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct omap_sham_reqctx));
+ sizeof(struct omap_sham_reqctx) + BUFLEN);
if (alg_base) {
struct omap_sham_hmac_ctx *bctx = tctx->base;
@@ -932,7 +988,7 @@ static struct ahash_alg algs[] = {
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = OMAP_ALIGN_MASK,
.cra_module = THIS_MODULE,
.cra_init = omap_sham_cra_init,
.cra_exit = omap_sham_cra_exit,
@@ -956,7 +1012,7 @@ static struct ahash_alg algs[] = {
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
sizeof(struct omap_sham_hmac_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = OMAP_ALIGN_MASK,
.cra_module = THIS_MODULE,
.cra_init = omap_sham_cra_sha1_init,
.cra_exit = omap_sham_cra_exit,
@@ -980,7 +1036,7 @@ static struct ahash_alg algs[] = {
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
sizeof(struct omap_sham_hmac_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = OMAP_ALIGN_MASK,
.cra_module = THIS_MODULE,
.cra_init = omap_sham_cra_md5_init,
.cra_exit = omap_sham_cra_exit,
@@ -993,7 +1049,7 @@ static void omap_sham_done_task(unsigned long data)
struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
struct ahash_request *req = dd->req;
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
- int ready = 1;
+ int ready = 0, err = 0;
if (ctx->flags & FLAGS_OUTPUT_READY) {
ctx->flags &= ~FLAGS_OUTPUT_READY;
@@ -1003,15 +1059,18 @@ static void omap_sham_done_task(unsigned long data)
if (dd->flags & FLAGS_DMA_ACTIVE) {
dd->flags &= ~FLAGS_DMA_ACTIVE;
omap_sham_update_dma_stop(dd);
- omap_sham_update_dma_slow(dd);
+ if (!dd->err)
+ err = omap_sham_update_dma_start(dd);
}
- if (ready && !(dd->flags & FLAGS_DMA_ACTIVE)) {
- dev_dbg(dd->dev, "update done\n");
+ err = dd->err ? : err;
+
+ if (err != -EINPROGRESS && (ready || err)) {
+ dev_dbg(dd->dev, "update done: err: %d\n", err);
/* finish curent request */
- omap_sham_finish_req(req, 0);
+ omap_sham_finish_req(req, err);
/* start new request */
- omap_sham_handle_queue(dd);
+ omap_sham_handle_queue(dd, NULL);
}
}
@@ -1019,7 +1078,7 @@ static void omap_sham_queue_task(unsigned long data)
{
struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
- omap_sham_handle_queue(dd);
+ omap_sham_handle_queue(dd, NULL);
}
static irqreturn_t omap_sham_irq(int irq, void *dev_id)
@@ -1041,6 +1100,7 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
omap_sham_read(dd, SHA_REG_CTRL);
ctx->flags |= FLAGS_OUTPUT_READY;
+ dd->err = 0;
tasklet_schedule(&dd->done_task);
return IRQ_HANDLED;
@@ -1050,8 +1110,13 @@ static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_sham_dev *dd = data;
- if (likely(lch == dd->dma_lch))
- tasklet_schedule(&dd->done_task);
+ if (ch_status != OMAP_DMA_BLOCK_IRQ) {
+ pr_err("omap-sham DMA error status: 0x%hx\n", ch_status);
+ dd->err = -EIO;
+ dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
+ }
+
+ tasklet_schedule(&dd->done_task);
}
static int omap_sham_dma_init(struct omap_sham_dev *dd)
@@ -1066,15 +1131,6 @@ static int omap_sham_dma_init(struct omap_sham_dev *dd)
dev_err(dd->dev, "Unable to request DMA channel\n");
return err;
}
- omap_set_dma_dest_params(dd->dma_lch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + SHA_REG_DIN(0), 0, 16);
-
- omap_set_dma_dest_burst_mode(dd->dma_lch,
- OMAP_DMA_DATA_BURST_16);
-
- omap_set_dma_src_burst_mode(dd->dma_lch,
- OMAP_DMA_DATA_BURST_4);
return 0;
}
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6ee23592700a..ef138731c0ea 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -109,7 +109,7 @@ config FSL_DMA
config MPC512X_DMA
tristate "Freescale MPC512x built-in DMA engine support"
- depends on PPC_MPC512x
+ depends on PPC_MPC512x || PPC_MPC831x
select DMA_ENGINE
---help---
Enable support for the Freescale MPC512x built-in DMA engine.
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a8a84f4587f2..64b21f5cd740 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,8 +1,8 @@
ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
- EXTRA_CFLAGS += -DDEBUG
+ ccflags-y += -DDEBUG
endif
ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
- EXTRA_CFLAGS += -DVERBOSE_DEBUG
+ ccflags-y += -DVERBOSE_DEBUG
endif
obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index a0f3e6a06e06..ea0ee81cff53 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
desc->lli.daddr = mem;
desc->lli.ctrla = ctrla
| ATC_DST_WIDTH(mem_width)
- | len >> mem_width;
+ | len >> reg_width;
desc->lli.ctrlb = ctrlb;
if (!first) {
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 286c3ac6bdcc..4de947a450fc 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1,7 +1,7 @@
/*
* Freescale MPC85xx, MPC83xx DMA Engine support
*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
*
* Author:
* Zhang Wei <wei.zhang@freescale.com>, Jul 2007
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan)
* EIE - Error interrupt enable
* EOSIE - End of segments interrupt enable (basic mode)
* EOLNIE - End of links interrupt enable
+ * BWC - Bandwidth sharing among channels
*/
- DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
- | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+ DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC
+ | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE
+ | FSL_DMA_MR_EOSIE, 32);
break;
case FSL_DMA_IP_83XX:
/* Set the channel to below modes:
@@ -1322,6 +1324,8 @@ static int __devinit fsldma_of_probe(struct platform_device *op,
fdev->common.device_control = fsl_dma_device_control;
fdev->common.dev = &op->dev;
+ dma_set_mask(&(op->dev), DMA_BIT_MASK(36));
+
dev_set_drvdata(&op->dev, fdev);
/*
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index cb4d6ff51597..ba9f403c0fbe 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
*
* Author:
* Zhang Wei <wei.zhang@freescale.com>, Jul 2007
@@ -36,6 +36,13 @@
#define FSL_DMA_MR_DAHE 0x00002000
#define FSL_DMA_MR_SAHE 0x00001000
+/*
+ * Bandwidth/pause control determines how many bytes a given
+ * channel is allowed to transfer before the DMA engine pauses
+ * the current channel and switches to the next channel
+ */
+#define FSL_DMA_MR_BWC 0x08000000
+
/* Special MR definition for MPC8349 */
#define FSL_DMA_MR_EOTIE 0x00000080
#define FSL_DMA_MR_PRC_RM 0x00000800
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index f629e4961af5..e53d438142bb 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
return 0;
err_init:
- while (i-- >= 0) {
+ while (--i >= 0) {
struct imxdma_channel *imxdmac = &imxdma->channel[i];
imx_dma_free(imxdmac->imxdma_channel);
}
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0834323a0599..d5a5d4d9c19b 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -273,50 +273,6 @@ struct sdma_channel {
#define MXC_SDMA_MIN_PRIORITY 1
#define MXC_SDMA_MAX_PRIORITY 7
-/**
- * struct sdma_script_start_addrs - SDMA script start pointers
- *
- * start addresses of the different functions in the physical
- * address space of the SDMA engine.
- */
-struct sdma_script_start_addrs {
- u32 ap_2_ap_addr;
- u32 ap_2_bp_addr;
- u32 ap_2_ap_fixed_addr;
- u32 bp_2_ap_addr;
- u32 loopback_on_dsp_side_addr;
- u32 mcu_interrupt_only_addr;
- u32 firi_2_per_addr;
- u32 firi_2_mcu_addr;
- u32 per_2_firi_addr;
- u32 mcu_2_firi_addr;
- u32 uart_2_per_addr;
- u32 uart_2_mcu_addr;
- u32 per_2_app_addr;
- u32 mcu_2_app_addr;
- u32 per_2_per_addr;
- u32 uartsh_2_per_addr;
- u32 uartsh_2_mcu_addr;
- u32 per_2_shp_addr;
- u32 mcu_2_shp_addr;
- u32 ata_2_mcu_addr;
- u32 mcu_2_ata_addr;
- u32 app_2_per_addr;
- u32 app_2_mcu_addr;
- u32 shp_2_per_addr;
- u32 shp_2_mcu_addr;
- u32 mshc_2_mcu_addr;
- u32 mcu_2_mshc_addr;
- u32 spdif_2_mcu_addr;
- u32 mcu_2_spdif_addr;
- u32 asrc_2_mcu_addr;
- u32 ext_mem_2_ipu_addr;
- u32 descrambler_addr;
- u32 dptc_dvfs_addr;
- u32 utra_addr;
- u32 ram_code_start_addr;
-};
-
#define SDMA_FIRMWARE_MAGIC 0x414d4453
/**
@@ -951,7 +907,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
int param;
- bd->buffer_addr = sgl->dma_address;
+ bd->buffer_addr = sg->dma_address;
count = sg->length;
@@ -1127,8 +1083,74 @@ static void sdma_issue_pending(struct dma_chan *chan)
*/
}
-static int __init sdma_init(struct sdma_engine *sdma,
- void *ram_code, int ram_code_size)
+#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
+
+static void sdma_add_scripts(struct sdma_engine *sdma,
+ const struct sdma_script_start_addrs *addr)
+{
+ s32 *addr_arr = (u32 *)addr;
+ s32 *saddr_arr = (u32 *)sdma->script_addrs;
+ int i;
+
+ for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
+ if (addr_arr[i] > 0)
+ saddr_arr[i] = addr_arr[i];
+}
+
+static int __init sdma_get_firmware(struct sdma_engine *sdma,
+ const char *cpu_name, int to_version)
+{
+ const struct firmware *fw;
+ char *fwname;
+ const struct sdma_firmware_header *header;
+ int ret;
+ const struct sdma_script_start_addrs *addr;
+ unsigned short *ram_code;
+
+ fwname = kasprintf(GFP_KERNEL, "sdma-%s-to%d.bin", cpu_name, to_version);
+ if (!fwname)
+ return -ENOMEM;
+
+ ret = request_firmware(&fw, fwname, sdma->dev);
+ if (ret) {
+ kfree(fwname);
+ return ret;
+ }
+ kfree(fwname);
+
+ if (fw->size < sizeof(*header))
+ goto err_firmware;
+
+ header = (struct sdma_firmware_header *)fw->data;
+
+ if (header->magic != SDMA_FIRMWARE_MAGIC)
+ goto err_firmware;
+ if (header->ram_code_start + header->ram_code_size > fw->size)
+ goto err_firmware;
+
+ addr = (void *)header + header->script_addrs_start;
+ ram_code = (void *)header + header->ram_code_start;
+
+ clk_enable(sdma->clk);
+ /* download the RAM image for SDMA */
+ sdma_load_script(sdma, ram_code,
+ header->ram_code_size,
+ sdma->script_addrs->ram_code_start_addr);
+ clk_disable(sdma->clk);
+
+ sdma_add_scripts(sdma, addr);
+
+ dev_info(sdma->dev, "loaded firmware %d.%d\n",
+ header->version_major,
+ header->version_minor);
+
+err_firmware:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int __init sdma_init(struct sdma_engine *sdma)
{
int i, ret;
dma_addr_t ccb_phys;
@@ -1192,11 +1214,6 @@ static int __init sdma_init(struct sdma_engine *sdma,
__raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR);
- /* download the RAM image for SDMA */
- sdma_load_script(sdma, ram_code,
- ram_code_size,
- sdma->script_addrs->ram_code_start_addr);
-
/* Set bits of CONFIG register with given context switching mode */
__raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
@@ -1216,14 +1233,9 @@ err_dma_alloc:
static int __init sdma_probe(struct platform_device *pdev)
{
int ret;
- const struct firmware *fw;
- const struct sdma_firmware_header *header;
- const struct sdma_script_start_addrs *addr;
int irq;
- unsigned short *ram_code;
struct resource *iores;
struct sdma_platform_data *pdata = pdev->dev.platform_data;
- char *fwname;
int i;
dma_cap_mask_t mask;
struct sdma_engine *sdma;
@@ -1262,38 +1274,9 @@ static int __init sdma_probe(struct platform_device *pdev)
if (ret)
goto err_request_irq;
- fwname = kasprintf(GFP_KERNEL, "sdma-%s-to%d.bin",
- pdata->cpu_name, pdata->to_version);
- if (!fwname) {
- ret = -ENOMEM;
- goto err_cputype;
- }
-
- ret = request_firmware(&fw, fwname, &pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "request firmware \"%s\" failed with %d\n",
- fwname, ret);
- kfree(fwname);
- goto err_cputype;
- }
- kfree(fwname);
-
- if (fw->size < sizeof(*header))
- goto err_firmware;
-
- header = (struct sdma_firmware_header *)fw->data;
-
- if (header->magic != SDMA_FIRMWARE_MAGIC)
- goto err_firmware;
- if (header->ram_code_start + header->ram_code_size > fw->size)
- goto err_firmware;
-
- addr = (void *)header + header->script_addrs_start;
- ram_code = (void *)header + header->ram_code_start;
- sdma->script_addrs = kmalloc(sizeof(*addr), GFP_KERNEL);
+ sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
if (!sdma->script_addrs)
- goto err_firmware;
- memcpy(sdma->script_addrs, addr, sizeof(*addr));
+ goto err_alloc;
sdma->version = pdata->sdma_version;
@@ -1316,10 +1299,15 @@ static int __init sdma_probe(struct platform_device *pdev)
list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels);
}
- ret = sdma_init(sdma, ram_code, header->ram_code_size);
+ ret = sdma_init(sdma);
if (ret)
goto err_init;
+ if (pdata->script_addrs)
+ sdma_add_scripts(sdma, pdata->script_addrs);
+
+ sdma_get_firmware(sdma, pdata->cpu_name, pdata->to_version);
+
sdma->dma_device.dev = &pdev->dev;
sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources;
@@ -1336,10 +1324,6 @@ static int __init sdma_probe(struct platform_device *pdev)
goto err_init;
}
- dev_info(&pdev->dev, "initialized (firmware %d.%d)\n",
- header->version_major,
- header->version_minor);
-
/* request channel 0. This is an internal control channel
* to the SDMA engine and not available to clients.
*/
@@ -1347,15 +1331,13 @@ static int __init sdma_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, mask);
dma_request_channel(mask, NULL, NULL);
- release_firmware(fw);
+ dev_info(sdma->dev, "initialized\n");
return 0;
err_init:
kfree(sdma->script_addrs);
-err_firmware:
- release_firmware(fw);
-err_cputype:
+err_alloc:
free_irq(irq, sdma);
err_request_irq:
iounmap(sdma->regs);
@@ -1385,7 +1367,7 @@ static int __init sdma_module_init(void)
{
return platform_driver_probe(&sdma_driver, sdma_probe);
}
-subsys_initcall(sdma_module_init);
+module_init(sdma_module_init);
MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("i.MX SDMA driver");
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 338bc4eed1f3..5397d8535e0a 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -664,11 +664,20 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy(
/*calculate CTL_LO*/
ctl_lo.ctl_lo = 0;
ctl_lo.ctlx.int_en = 1;
- ctl_lo.ctlx.dst_tr_width = mids->dma_slave.dst_addr_width;
- ctl_lo.ctlx.src_tr_width = mids->dma_slave.src_addr_width;
ctl_lo.ctlx.dst_msize = mids->dma_slave.src_maxburst;
ctl_lo.ctlx.src_msize = mids->dma_slave.dst_maxburst;
+ /*
+ * Here we need some translation from "enum dma_slave_buswidth"
+ * to the format for our dma controller
+ * standard intel_mid_dmac's format
+ * 1 Byte 0b000
+ * 2 Bytes 0b001
+ * 4 Bytes 0b010
+ */
+ ctl_lo.ctlx.dst_tr_width = mids->dma_slave.dst_addr_width / 2;
+ ctl_lo.ctlx.src_tr_width = mids->dma_slave.src_addr_width / 2;
+
if (mids->cfg_mode == LNW_DMA_MEM_TO_MEM) {
ctl_lo.ctlx.tt_fc = 0;
ctl_lo.ctlx.sinc = 0;
@@ -746,8 +755,18 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_slave_sg(
BUG_ON(!mids);
if (!midc->dma->pimr_mask) {
- pr_debug("MDMA: SG list is not supported by this controller\n");
- return NULL;
+ /* We can still handle sg list with only one item */
+ if (sg_len == 1) {
+ txd = intel_mid_dma_prep_memcpy(chan,
+ mids->dma_slave.dst_addr,
+ mids->dma_slave.src_addr,
+ sgl->length,
+ flags);
+ return txd;
+ } else {
+ pr_warn("MDMA: SG list is not supported by this controller\n");
+ return NULL;
+ }
}
pr_debug("MDMA: SG Length = %d, direction = %d, Flags = %#lx\n",
@@ -758,6 +777,7 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_slave_sg(
pr_err("MDMA: Prep memcpy failed\n");
return NULL;
}
+
desc = to_intel_mid_dma_desc(txd);
desc->dirn = direction;
ctl_lo.ctl_lo = desc->ctl_lo;
@@ -1021,11 +1041,6 @@ static irqreturn_t intel_mid_dma_interrupt(int irq, void *data)
/*DMA Interrupt*/
pr_debug("MDMA:Got an interrupt on irq %d\n", irq);
- if (!mid) {
- pr_err("ERR_MDMA:null pointer mid\n");
- return -EINVAL;
- }
-
pr_debug("MDMA: Status %x, Mask %x\n", tfr_status, mid->intr_mask);
tfr_status &= mid->intr_mask;
if (tfr_status) {
@@ -1075,7 +1090,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
if (NULL == dma->dma_pool) {
pr_err("ERR_MDMA:pci_pool_create failed\n");
err = -ENOMEM;
- kfree(dma);
goto err_dma_pool;
}
@@ -1186,7 +1200,6 @@ err_engine:
free_irq(pdev->irq, dma);
err_irq:
pci_pool_destroy(dma->dma_pool);
- kfree(dma);
err_dma_pool:
pr_err("ERR_MDMA:setup_dma failed: %d\n", err);
return err;
@@ -1413,7 +1426,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = {
.runtime_idle = dma_runtime_idle,
};
-static struct pci_driver intel_mid_dma_pci = {
+static struct pci_driver intel_mid_dma_pci_driver = {
.name = "Intel MID DMA",
.id_table = intel_mid_dma_ids,
.probe = intel_mid_dma_probe,
@@ -1431,13 +1444,13 @@ static int __init intel_mid_dma_init(void)
{
pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n",
INTEL_MID_DMA_DRIVER_VERSION);
- return pci_register_driver(&intel_mid_dma_pci);
+ return pci_register_driver(&intel_mid_dma_pci_driver);
}
fs_initcall(intel_mid_dma_init);
static void __exit intel_mid_dma_exit(void)
{
- pci_unregister_driver(&intel_mid_dma_pci);
+ pci_unregister_driver(&intel_mid_dma_pci_driver);
}
module_exit(intel_mid_dma_exit);
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile
index 8997d3fb9051..0ff7270af25b 100644
--- a/drivers/dma/ioat/Makefile
+++ b/drivers/dma/ioat/Makefile
@@ -1,2 +1,2 @@
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
-ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o
+ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 4e9cbf300594..59c270192ccc 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
* Copyright (C) Semihalf 2009
+ * Copyright (C) Ilya Yanok, Emcraft Systems 2010
*
* Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description
* (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -70,6 +71,8 @@
#define MPC_DMA_DMAES_SBE (1 << 1)
#define MPC_DMA_DMAES_DBE (1 << 0)
+#define MPC_DMA_DMAGPOR_SNOOP_ENABLE (1 << 6)
+
#define MPC_DMA_TSIZE_1 0x00
#define MPC_DMA_TSIZE_2 0x01
#define MPC_DMA_TSIZE_4 0x02
@@ -104,7 +107,10 @@ struct __attribute__ ((__packed__)) mpc_dma_regs {
/* 0x30 */
u32 dmahrsh; /* DMA hw request status high(ch63~32) */
u32 dmahrsl; /* DMA hardware request status low(ch31~0) */
- u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */
+ union {
+ u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */
+ u32 dmagpor; /* (General purpose register on MPC8308) */
+ };
u32 dmailsa; /* DMA interrupt low select AXE(ch31~0) */
/* 0x40 ~ 0xff */
u32 reserve0[48]; /* Reserved */
@@ -195,7 +201,9 @@ struct mpc_dma {
struct mpc_dma_regs __iomem *regs;
struct mpc_dma_tcd __iomem *tcd;
int irq;
+ int irq2;
uint error_status;
+ int is_mpc8308;
/* Lock for error_status field in this structure */
spinlock_t error_status_lock;
@@ -252,11 +260,13 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
prev = mdesc;
}
- prev->tcd->start = 0;
prev->tcd->int_maj = 1;
/* Send first descriptor in chain into hardware */
memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd));
+
+ if (first != prev)
+ mdma->tcd[cid].e_sg = 1;
out_8(&mdma->regs->dmassrt, cid);
}
@@ -274,6 +284,9 @@ static void mpc_dma_irq_process(struct mpc_dma *mdma, u32 is, u32 es, int off)
spin_lock(&mchan->lock);
+ out_8(&mdma->regs->dmacint, ch + off);
+ out_8(&mdma->regs->dmacerr, ch + off);
+
/* Check error status */
if (es & (1 << ch))
list_for_each_entry(mdesc, &mchan->active, node)
@@ -302,36 +315,68 @@ static irqreturn_t mpc_dma_irq(int irq, void *data)
spin_unlock(&mdma->error_status_lock);
/* Handle interrupt on each channel */
- mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth),
+ if (mdma->dma.chancnt > 32) {
+ mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth),
in_be32(&mdma->regs->dmaerrh), 32);
+ }
mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl),
in_be32(&mdma->regs->dmaerrl), 0);
- /* Ack interrupt on all channels */
- out_be32(&mdma->regs->dmainth, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF);
-
/* Schedule tasklet */
tasklet_schedule(&mdma->tasklet);
return IRQ_HANDLED;
}
-/* DMA Tasklet */
-static void mpc_dma_tasklet(unsigned long data)
+/* proccess completed descriptors */
+static void mpc_dma_process_completed(struct mpc_dma *mdma)
{
- struct mpc_dma *mdma = (void *)data;
dma_cookie_t last_cookie = 0;
struct mpc_dma_chan *mchan;
struct mpc_dma_desc *mdesc;
struct dma_async_tx_descriptor *desc;
unsigned long flags;
LIST_HEAD(list);
- uint es;
int i;
+ for (i = 0; i < mdma->dma.chancnt; i++) {
+ mchan = &mdma->channels[i];
+
+ /* Get all completed descriptors */
+ spin_lock_irqsave(&mchan->lock, flags);
+ if (!list_empty(&mchan->completed))
+ list_splice_tail_init(&mchan->completed, &list);
+ spin_unlock_irqrestore(&mchan->lock, flags);
+
+ if (list_empty(&list))
+ continue;
+
+ /* Execute callbacks and run dependencies */
+ list_for_each_entry(mdesc, &list, node) {
+ desc = &mdesc->desc;
+
+ if (desc->callback)
+ desc->callback(desc->callback_param);
+
+ last_cookie = desc->cookie;
+ dma_run_dependencies(desc);
+ }
+
+ /* Free descriptors */
+ spin_lock_irqsave(&mchan->lock, flags);
+ list_splice_tail_init(&list, &mchan->free);
+ mchan->completed_cookie = last_cookie;
+ spin_unlock_irqrestore(&mchan->lock, flags);
+ }
+}
+
+/* DMA Tasklet */
+static void mpc_dma_tasklet(unsigned long data)
+{
+ struct mpc_dma *mdma = (void *)data;
+ unsigned long flags;
+ uint es;
+
spin_lock_irqsave(&mdma->error_status_lock, flags);
es = mdma->error_status;
mdma->error_status = 0;
@@ -370,35 +415,7 @@ static void mpc_dma_tasklet(unsigned long data)
dev_err(mdma->dma.dev, "- Destination Bus Error\n");
}
- for (i = 0; i < mdma->dma.chancnt; i++) {
- mchan = &mdma->channels[i];
-
- /* Get all completed descriptors */
- spin_lock_irqsave(&mchan->lock, flags);
- if (!list_empty(&mchan->completed))
- list_splice_tail_init(&mchan->completed, &list);
- spin_unlock_irqrestore(&mchan->lock, flags);
-
- if (list_empty(&list))
- continue;
-
- /* Execute callbacks and run dependencies */
- list_for_each_entry(mdesc, &list, node) {
- desc = &mdesc->desc;
-
- if (desc->callback)
- desc->callback(desc->callback_param);
-
- last_cookie = desc->cookie;
- dma_run_dependencies(desc);
- }
-
- /* Free descriptors */
- spin_lock_irqsave(&mchan->lock, flags);
- list_splice_tail_init(&list, &mchan->free);
- mchan->completed_cookie = last_cookie;
- spin_unlock_irqrestore(&mchan->lock, flags);
- }
+ mpc_dma_process_completed(mdma);
}
/* Submit descriptor to hardware */
@@ -563,6 +580,7 @@ static struct dma_async_tx_descriptor *
mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
size_t len, unsigned long flags)
{
+ struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
struct mpc_dma_desc *mdesc = NULL;
struct mpc_dma_tcd *tcd;
@@ -577,8 +595,11 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
}
spin_unlock_irqrestore(&mchan->lock, iflags);
- if (!mdesc)
+ if (!mdesc) {
+ /* try to free completed descriptors */
+ mpc_dma_process_completed(mdma);
return NULL;
+ }
mdesc->error = 0;
tcd = mdesc->tcd;
@@ -591,7 +612,8 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
tcd->dsize = MPC_DMA_TSIZE_32;
tcd->soff = 32;
tcd->doff = 32;
- } else if (IS_ALIGNED(src | dst | len, 16)) {
+ } else if (!mdma->is_mpc8308 && IS_ALIGNED(src | dst | len, 16)) {
+ /* MPC8308 doesn't support 16 byte transfers */
tcd->ssize = MPC_DMA_TSIZE_16;
tcd->dsize = MPC_DMA_TSIZE_16;
tcd->soff = 16;
@@ -651,6 +673,15 @@ static int __devinit mpc_dma_probe(struct platform_device *op,
return -EINVAL;
}
+ if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) {
+ mdma->is_mpc8308 = 1;
+ mdma->irq2 = irq_of_parse_and_map(dn, 1);
+ if (mdma->irq2 == NO_IRQ) {
+ dev_err(dev, "Error mapping IRQ!\n");
+ return -EINVAL;
+ }
+ }
+
retval = of_address_to_resource(dn, 0, &res);
if (retval) {
dev_err(dev, "Error parsing memory region!\n");
@@ -681,11 +712,23 @@ static int __devinit mpc_dma_probe(struct platform_device *op,
return -EINVAL;
}
+ if (mdma->is_mpc8308) {
+ retval = devm_request_irq(dev, mdma->irq2, &mpc_dma_irq, 0,
+ DRV_NAME, mdma);
+ if (retval) {
+ dev_err(dev, "Error requesting IRQ2!\n");
+ return -EINVAL;
+ }
+ }
+
spin_lock_init(&mdma->error_status_lock);
dma = &mdma->dma;
dma->dev = dev;
- dma->chancnt = MPC_DMA_CHANNELS;
+ if (!mdma->is_mpc8308)
+ dma->chancnt = MPC_DMA_CHANNELS;
+ else
+ dma->chancnt = 16; /* MPC8308 DMA has only 16 channels */
dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma->device_free_chan_resources = mpc_dma_free_chan_resources;
dma->device_issue_pending = mpc_dma_issue_pending;
@@ -721,26 +764,40 @@ static int __devinit mpc_dma_probe(struct platform_device *op,
* - Round-robin group arbitration,
* - Round-robin channel arbitration.
*/
- out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG |
- MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA);
-
- /* Disable hardware DMA requests */
- out_be32(&mdma->regs->dmaerqh, 0);
- out_be32(&mdma->regs->dmaerql, 0);
-
- /* Disable error interrupts */
- out_be32(&mdma->regs->dmaeeih, 0);
- out_be32(&mdma->regs->dmaeeil, 0);
-
- /* Clear interrupts status */
- out_be32(&mdma->regs->dmainth, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF);
- out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF);
-
- /* Route interrupts to IPIC */
- out_be32(&mdma->regs->dmaihsa, 0);
- out_be32(&mdma->regs->dmailsa, 0);
+ if (!mdma->is_mpc8308) {
+ out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG |
+ MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA);
+
+ /* Disable hardware DMA requests */
+ out_be32(&mdma->regs->dmaerqh, 0);
+ out_be32(&mdma->regs->dmaerql, 0);
+
+ /* Disable error interrupts */
+ out_be32(&mdma->regs->dmaeeih, 0);
+ out_be32(&mdma->regs->dmaeeil, 0);
+
+ /* Clear interrupts status */
+ out_be32(&mdma->regs->dmainth, 0xFFFFFFFF);
+ out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF);
+ out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF);
+ out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF);
+
+ /* Route interrupts to IPIC */
+ out_be32(&mdma->regs->dmaihsa, 0);
+ out_be32(&mdma->regs->dmailsa, 0);
+ } else {
+ /* MPC8308 has 16 channels and lacks some registers */
+ out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA);
+
+ /* enable snooping */
+ out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+ /* Disable error interrupts */
+ out_be32(&mdma->regs->dmaeeil, 0);
+
+ /* Clear interrupts status */
+ out_be32(&mdma->regs->dmaintl, 0xFFFF);
+ out_be32(&mdma->regs->dmaerrl, 0xFFFF);
+ }
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 411d5bf50fc4..a25f5f61e0e0 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -449,7 +449,7 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
static void mv_xor_tasklet(unsigned long data)
{
struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
- __mv_xor_slot_cleanup(chan);
+ mv_xor_slot_cleanup(chan);
}
static struct mv_xor_desc_slot *
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 92b679024fed..c064c89420d0 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
return;
}
- channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
- channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
- channel_writel(pd_chan, SIZE, desc->regs.size);
- channel_writel(pd_chan, NEXT, desc->regs.next);
-
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n",
pd_chan->chan.chan_id, desc->regs.dev_addr);
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n",
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n",
pd_chan->chan.chan_id, desc->regs.next);
- if (list_empty(&desc->tx_list))
+ if (list_empty(&desc->tx_list)) {
+ channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
+ channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
+ channel_writel(pd_chan, SIZE, desc->regs.size);
+ channel_writel(pd_chan, NEXT, desc->regs.next);
pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT);
- else
+ } else {
+ channel_writel(pd_chan, NEXT, desc->txd.phys);
pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
+ }
val = dma_readl(pd, CTL2);
val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 0d58a4a4487f..cef584533ee8 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev,
if (!request_mem_region(res.start, resource_size(&res),
dev_driver_string(&ofdev->dev))) {
- dev_err(&ofdev->dev, "failed to request memory region "
- "(0x%016llx-0x%016llx)\n",
- (u64)res.start, (u64)res.end);
+ dev_err(&ofdev->dev, "failed to request memory region %pR\n",
+ &res);
initcode = PPC_ADMA_INIT_MEMREG;
ret = -EBUSY;
goto out;
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index eb6b54dbb806..a0069c171518 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -27,7 +27,10 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/sh_dma.h>
-
+#include <linux/notifier.h>
+#include <linux/kdebug.h>
+#include <linux/spinlock.h>
+#include <linux/rculist.h>
#include "shdma.h"
/* DMA descriptor control */
@@ -43,6 +46,13 @@ enum sh_dmae_desc_status {
/* Default MEMCPY transfer size = 2^2 = 4 bytes */
#define LOG2_DEFAULT_XFER_SIZE 2
+/*
+ * Used for write-side mutual exclusion for the global device list,
+ * read-side synchronization by way of RCU.
+ */
+static DEFINE_SPINLOCK(sh_dmae_lock);
+static LIST_HEAD(sh_dmae_devices);
+
/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SH_DMA_SLAVE_NUMBER)];
@@ -817,10 +827,9 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
return ret;
}
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
-static irqreturn_t sh_dmae_err(int irq, void *data)
+static unsigned int sh_dmae_reset(struct sh_dmae_device *shdev)
{
- struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
+ unsigned int handled = 0;
int i;
/* halt the dma controller */
@@ -829,25 +838,35 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
/* 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);
- }
- list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
+ struct sh_desc *desc;
+
+ if (!sh_chan)
+ continue;
+
+ /* 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);
}
+
+ list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
+ handled++;
}
+
sh_dmae_rst(shdev);
- return IRQ_HANDLED;
+ return !!handled;
+}
+
+static irqreturn_t sh_dmae_err(int irq, void *data)
+{
+ return IRQ_RETVAL(sh_dmae_reset(data));
}
-#endif
static void dmae_do_tasklet(unsigned long data)
{
@@ -876,6 +895,60 @@ static void dmae_do_tasklet(unsigned long data)
sh_dmae_chan_ld_cleanup(sh_chan, false);
}
+static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev)
+{
+ unsigned int handled;
+
+ /* Fast path out if NMIF is not asserted for this controller */
+ if ((dmaor_read(shdev) & DMAOR_NMIF) == 0)
+ return false;
+
+ handled = sh_dmae_reset(shdev);
+ if (handled)
+ return true;
+
+ return false;
+}
+
+static int sh_dmae_nmi_handler(struct notifier_block *self,
+ unsigned long cmd, void *data)
+{
+ struct sh_dmae_device *shdev;
+ int ret = NOTIFY_DONE;
+ bool triggered;
+
+ /*
+ * Only concern ourselves with NMI events.
+ *
+ * Normally we would check the die chain value, but as this needs
+ * to be architecture independent, check for NMI context instead.
+ */
+ if (!in_nmi())
+ return NOTIFY_DONE;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(shdev, &sh_dmae_devices, node) {
+ /*
+ * Only stop if one of the controllers has NMIF asserted,
+ * we do not want to interfere with regular address error
+ * handling or NMI events that don't concern the DMACs.
+ */
+ triggered = sh_dmae_nmi_notify(shdev);
+ if (triggered == true)
+ ret = NOTIFY_OK;
+ }
+ rcu_read_unlock();
+
+ return ret;
+}
+
+static struct notifier_block sh_dmae_nmi_notifier __read_mostly = {
+ .notifier_call = sh_dmae_nmi_handler,
+
+ /* Run before NMI debug handler and KGDB */
+ .priority = 1,
+};
+
static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
int irq, unsigned long flags)
{
@@ -967,6 +1040,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
unsigned long irqflags = IRQF_DISABLED,
chan_flag[SH_DMAC_MAX_CHANNELS] = {};
+ unsigned long flags;
int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
int err, i, irq_cnt = 0, irqres = 0;
struct sh_dmae_device *shdev;
@@ -1032,6 +1106,15 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
+ spin_lock_irqsave(&sh_dmae_lock, flags);
+ list_add_tail_rcu(&shdev->node, &sh_dmae_devices);
+ spin_unlock_irqrestore(&sh_dmae_lock, flags);
+
+ /* Wire up NMI handling before bringing the controller online */
+ err = register_die_notifier(&sh_dmae_nmi_notifier);
+ if (err)
+ goto notifier_err;
+
/* reset dma controller */
err = sh_dmae_rst(shdev);
if (err)
@@ -1135,6 +1218,12 @@ eirqres:
eirq_err:
#endif
rst_err:
+ unregister_die_notifier(&sh_dmae_nmi_notifier);
+notifier_err:
+ spin_lock_irqsave(&sh_dmae_lock, flags);
+ list_del_rcu(&shdev->node);
+ spin_unlock_irqrestore(&sh_dmae_lock, flags);
+
pm_runtime_put(&pdev->dev);
if (dmars)
iounmap(shdev->dmars);
@@ -1155,6 +1244,7 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
{
struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
struct resource *res;
+ unsigned long flags;
int errirq = platform_get_irq(pdev, 0);
dma_async_device_unregister(&shdev->common);
@@ -1162,6 +1252,12 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
if (errirq > 0)
free_irq(errirq, shdev);
+ unregister_die_notifier(&sh_dmae_nmi_notifier);
+
+ spin_lock_irqsave(&sh_dmae_lock, flags);
+ list_del_rcu(&shdev->node);
+ spin_unlock_irqrestore(&sh_dmae_lock, flags);
+
/* channel data remove */
sh_dmae_chan_remove(shdev);
@@ -1213,3 +1309,4 @@ module_exit(sh_dmae_exit);
MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>");
MODULE_DESCRIPTION("Renesas SH DMA Engine driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-dma-engine");
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 4021275a0a43..52e4fb173805 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -43,6 +43,7 @@ struct sh_dmae_device {
struct dma_device common;
struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
struct sh_dmae_pdata *pdata;
+ struct list_head node;
u32 __iomem *chan_reg;
u16 __iomem *dmars;
};
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 8521401bbd75..eca9ba193e94 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range,
debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n",
hole_off, hole_valid, intlv_sel);
- if (intlv_en ||
+ if (intlv_en &&
(intlv_sel != ((sys_addr >> 12) & intlv_en)))
return -EINVAL;
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index d7ca43a828bd..251440cd50a3 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -41,10 +41,10 @@
#define MC_PROC_NAME_MAX_LEN 7
#if PAGE_SHIFT < 20
-#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
-#define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT))
+#define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
#else /* PAGE_SHIFT > 20 */
-#define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20))
#define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20))
#endif
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index ba6586a69ccc..795ea69c4d8f 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
return NULL;
}
- /* marking MCI offline */
- mci->op_state = OP_OFFLINE;
-
del_mc_from_global_list(mci);
mutex_unlock(&mem_ctls_mutex);
- /* flush workq processes and remove sysfs */
+ /* flush workq processes */
edac_mc_workq_teardown(mci);
+
+ /* marking MCI offline */
+ mci->op_state = OP_OFFLINE;
+
+ /* remove from sysfs */
edac_remove_sysfs_mci_device(mci);
edac_printk(KERN_INFO, EDAC_MC,
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 40a222e19b2d..68f942cb30f2 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -19,7 +19,7 @@ config FIREWIRE
config FIREWIRE_OHCI
tristate "OHCI-1394 controllers"
- depends on PCI && FIREWIRE
+ depends on PCI && FIREWIRE && MMU
help
Enable this driver if you have a FireWire controller based
on the OHCI specification. For all practical purposes, this
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 14bb7b7b5dd7..48ae712e2101 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1501,9 +1501,10 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
e->client = client;
e->p.speed = SCODE_100;
e->p.generation = a->generation;
- e->p.header[0] = a->data[0];
- e->p.header[1] = a->data[1];
- e->p.header_length = 8;
+ e->p.header[0] = TCODE_LINK_INTERNAL << 4;
+ e->p.header[1] = a->data[0];
+ e->p.header[2] = a->data[1];
+ e->p.header_length = 12;
e->p.callback = outbound_phy_packet_callback;
e->phy_packet.closure = a->closure;
e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT;
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index b42a0bde8494..d00f8ce902cc 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -72,6 +72,15 @@
#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
#define PHY_IDENTIFIER(id) ((id) << 30)
+/* returns 0 if the split timeout handler is already running */
+static int try_cancel_split_timeout(struct fw_transaction *t)
+{
+ if (t->is_split_transaction)
+ return del_timer(&t->split_timeout_timer);
+ else
+ return 1;
+}
+
static int close_transaction(struct fw_transaction *transaction,
struct fw_card *card, int rcode)
{
@@ -81,7 +90,7 @@ static int close_transaction(struct fw_transaction *transaction,
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) {
if (t == transaction) {
- if (!del_timer(&t->split_timeout_timer)) {
+ if (!try_cancel_split_timeout(t)) {
spin_unlock_irqrestore(&card->lock, flags);
goto timed_out;
}
@@ -141,16 +150,28 @@ static void split_transaction_timeout_callback(unsigned long data)
card->tlabel_mask &= ~(1ULL << t->tlabel);
spin_unlock_irqrestore(&card->lock, flags);
- card->driver->cancel_packet(card, &t->packet);
-
- /*
- * At this point cancel_packet will never call the transaction
- * callback, since we just took the transaction out of the list.
- * So do it here.
- */
t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
}
+static void start_split_transaction_timeout(struct fw_transaction *t,
+ struct fw_card *card)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&card->lock, flags);
+
+ if (list_empty(&t->link) || WARN_ON(t->is_split_transaction)) {
+ spin_unlock_irqrestore(&card->lock, flags);
+ return;
+ }
+
+ t->is_split_transaction = true;
+ mod_timer(&t->split_timeout_timer,
+ jiffies + card->split_timeout_jiffies);
+
+ spin_unlock_irqrestore(&card->lock, flags);
+}
+
static void transmit_complete_callback(struct fw_packet *packet,
struct fw_card *card, int status)
{
@@ -162,7 +183,7 @@ static void transmit_complete_callback(struct fw_packet *packet,
close_transaction(t, card, RCODE_COMPLETE);
break;
case ACK_PENDING:
- t->timestamp = packet->timestamp;
+ start_split_transaction_timeout(t, card);
break;
case ACK_BUSY_X:
case ACK_BUSY_A:
@@ -250,7 +271,7 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
break;
default:
- WARN(1, "wrong tcode %d", tcode);
+ WARN(1, "wrong tcode %d\n", tcode);
}
common:
packet->speed = speed;
@@ -349,11 +370,9 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
t->node_id = destination_id;
t->tlabel = tlabel;
t->card = card;
+ t->is_split_transaction = false;
setup_timer(&t->split_timeout_timer,
split_transaction_timeout_callback, (unsigned long)t);
- /* FIXME: start this timer later, relative to t->timestamp */
- mod_timer(&t->split_timeout_timer,
- jiffies + card->split_timeout_jiffies);
t->callback = callback;
t->callback_data = callback_data;
@@ -423,7 +442,8 @@ static void transmit_phy_packet_callback(struct fw_packet *packet,
}
static struct fw_packet phy_config_packet = {
- .header_length = 8,
+ .header_length = 12,
+ .header[0] = TCODE_LINK_INTERNAL << 4,
.payload_length = 0,
.speed = SCODE_100,
.callback = transmit_phy_packet_callback,
@@ -451,8 +471,8 @@ void fw_send_phy_config(struct fw_card *card,
mutex_lock(&phy_config_mutex);
- phy_config_packet.header[0] = data;
- phy_config_packet.header[1] = ~data;
+ phy_config_packet.header[1] = data;
+ phy_config_packet.header[2] = ~data;
phy_config_packet.generation = generation;
INIT_COMPLETION(phy_config_done);
@@ -638,7 +658,7 @@ int fw_get_response_length(struct fw_request *r)
}
default:
- WARN(1, "wrong tcode %d", tcode);
+ WARN(1, "wrong tcode %d\n", tcode);
return 0;
}
}
@@ -694,7 +714,7 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
break;
default:
- WARN(1, "wrong tcode %d", tcode);
+ WARN(1, "wrong tcode %d\n", tcode);
}
response->payload_mapped = false;
@@ -925,7 +945,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) {
if (t->node_id == source && t->tlabel == tlabel) {
- if (!del_timer(&t->split_timeout_timer)) {
+ if (!try_cancel_split_timeout(t)) {
spin_unlock_irqrestore(&card->lock, flags);
goto timed_out;
}
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index e6239f971be6..f8dfcf1c6cbe 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -215,9 +215,11 @@ static inline bool is_next_generation(int new_generation, int old_generation)
/* -transaction */
+#define TCODE_LINK_INTERNAL 0xe
+
#define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4)
#define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0)
-#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == 0xe)
+#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == TCODE_LINK_INTERNAL)
#define TCODE_IS_REQUEST(tcode) (((tcode) & 2) == 0)
#define TCODE_IS_RESPONSE(tcode) (((tcode) & 2) != 0)
#define TCODE_HAS_REQUEST_DATA(tcode) (((tcode) & 12) != 4)
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 1a467a91fb0b..c2e194c58667 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -9,6 +9,7 @@
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/ethtool.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/highmem.h>
@@ -179,6 +180,7 @@ struct fwnet_device {
/* Number of tx datagrams that have been queued but not yet acked */
int queued_datagrams;
+ int peer_count;
struct list_head peer_list;
struct fw_card *card;
struct net_device *netdev;
@@ -996,15 +998,23 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask)
static void fwnet_write_complete(struct fw_card *card, int rcode,
void *payload, size_t length, void *data)
{
- struct fwnet_packet_task *ptask;
-
- ptask = data;
+ struct fwnet_packet_task *ptask = data;
+ static unsigned long j;
+ static int last_rcode, errors_skipped;
if (rcode == RCODE_COMPLETE) {
fwnet_transmit_packet_done(ptask);
} else {
- fw_error("fwnet_write_complete: failed: %x\n", rcode);
fwnet_transmit_packet_failed(ptask);
+
+ if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) {
+ fw_error("fwnet_write_complete: "
+ "failed: %x (skipped %d)\n", rcode, errors_skipped);
+
+ errors_skipped = 0;
+ last_rcode = rcode;
+ } else
+ errors_skipped++;
}
}
@@ -1213,6 +1223,14 @@ static int fwnet_broadcast_start(struct fwnet_device *dev)
return retval;
}
+static void set_carrier_state(struct fwnet_device *dev)
+{
+ if (dev->peer_count > 1)
+ netif_carrier_on(dev->netdev);
+ else
+ netif_carrier_off(dev->netdev);
+}
+
/* ifup */
static int fwnet_open(struct net_device *net)
{
@@ -1226,6 +1244,10 @@ static int fwnet_open(struct net_device *net)
}
netif_start_queue(net);
+ spin_lock_irq(&dev->lock);
+ set_carrier_state(dev);
+ spin_unlock_irq(&dev->lock);
+
return 0;
}
@@ -1397,6 +1419,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
return 0;
}
+static const struct ethtool_ops fwnet_ethtool_ops = {
+ .get_link = ethtool_op_get_link,
+};
+
static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
@@ -1415,6 +1441,7 @@ static void fwnet_init_dev(struct net_device *net)
net->hard_header_len = FWNET_HLEN;
net->type = ARPHRD_IEEE1394;
net->tx_queue_len = FWNET_TX_QUEUE_LEN;
+ net->ethtool_ops = &fwnet_ethtool_ops;
}
/* caller must hold fwnet_device_mutex */
@@ -1455,6 +1482,8 @@ static int fwnet_add_peer(struct fwnet_device *dev,
spin_lock_irq(&dev->lock);
list_add_tail(&peer->peer_link, &dev->peer_list);
+ dev->peer_count++;
+ set_carrier_state(dev);
spin_unlock_irq(&dev->lock);
return 0;
@@ -1535,13 +1564,15 @@ static int fwnet_probe(struct device *_dev)
return ret;
}
-static void fwnet_remove_peer(struct fwnet_peer *peer)
+static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
{
struct fwnet_partial_datagram *pd, *pd_next;
- spin_lock_irq(&peer->dev->lock);
+ spin_lock_irq(&dev->lock);
list_del(&peer->peer_link);
- spin_unlock_irq(&peer->dev->lock);
+ dev->peer_count--;
+ set_carrier_state(dev);
+ spin_unlock_irq(&dev->lock);
list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
fwnet_pd_delete(pd);
@@ -1558,7 +1589,7 @@ static int fwnet_remove(struct device *_dev)
mutex_lock(&fwnet_device_mutex);
- fwnet_remove_peer(peer);
+ fwnet_remove_peer(peer, dev);
if (list_empty(&dev->peer_list)) {
net = dev->netdev;
diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c
index bf184fb59a5e..0618145376ad 100644
--- a/drivers/firewire/nosy.c
+++ b/drivers/firewire/nosy.c
@@ -302,7 +302,7 @@ nosy_open(struct inode *inode, struct file *file)
file->private_data = client;
- return 0;
+ return nonseekable_open(inode, file);
fail:
kfree(client);
lynx_put(lynx);
@@ -405,7 +405,6 @@ static const struct file_operations nosy_ops = {
.poll = nosy_poll,
.open = nosy_open,
.release = nosy_release,
- .llseek = noop_llseek,
};
#define PHY_PACKET_SIZE 12 /* 1 payload, 1 inverse, 1 ack = 3 quadlets */
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 84eb607d6c03..d77d120ddc25 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -18,6 +18,7 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/delay.h>
@@ -40,6 +41,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/time.h>
+#include <linux/vmalloc.h>
#include <asm/byteorder.h>
#include <asm/page.h>
@@ -80,17 +82,23 @@ struct descriptor {
#define COMMAND_PTR(regs) ((regs) + 12)
#define CONTEXT_MATCH(regs) ((regs) + 16)
-struct ar_buffer {
- struct descriptor descriptor;
- struct ar_buffer *next;
- __le32 data[0];
-};
+#define AR_BUFFER_SIZE (32*1024)
+#define AR_BUFFERS_MIN DIV_ROUND_UP(AR_BUFFER_SIZE, PAGE_SIZE)
+/* we need at least two pages for proper list management */
+#define AR_BUFFERS (AR_BUFFERS_MIN >= 2 ? AR_BUFFERS_MIN : 2)
+
+#define MAX_ASYNC_PAYLOAD 4096
+#define MAX_AR_PACKET_SIZE (16 + MAX_ASYNC_PAYLOAD + 4)
+#define AR_WRAPAROUND_PAGES DIV_ROUND_UP(MAX_AR_PACKET_SIZE, PAGE_SIZE)
struct ar_context {
struct fw_ohci *ohci;
- struct ar_buffer *current_buffer;
- struct ar_buffer *last_buffer;
+ struct page *pages[AR_BUFFERS];
+ void *buffer;
+ struct descriptor *descriptors;
+ dma_addr_t descriptors_bus;
void *pointer;
+ unsigned int last_buffer_index;
u32 regs;
struct tasklet_struct tasklet;
};
@@ -117,6 +125,8 @@ struct context {
struct fw_ohci *ohci;
u32 regs;
int total_allocation;
+ bool running;
+ bool flushing;
/*
* List of page-sized buffers for storing DMA descriptors.
@@ -161,6 +171,9 @@ struct iso_context {
int excess_bytes;
void *header;
size_t header_length;
+
+ u8 sync;
+ u8 tags;
};
#define CONFIG_ROM_SIZE 1024
@@ -177,7 +190,8 @@ struct fw_ohci {
u32 bus_time;
bool is_root;
bool csr_state_setclear_abdicate;
-
+ int n_ir;
+ int n_it;
/*
* Spinlock for accessing fw_ohci data. Never call out of
* this driver with this lock held.
@@ -186,6 +200,9 @@ struct fw_ohci {
struct mutex phy_reg_mutex;
+ void *misc_buffer;
+ dma_addr_t misc_buffer_bus;
+
struct ar_context ar_request_ctx;
struct ar_context ar_response_ctx;
struct context at_request_ctx;
@@ -242,6 +259,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
static char ohci_driver_name[] = KBUILD_MODNAME;
+#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
@@ -253,18 +271,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
- unsigned short vendor, device, flags;
+ unsigned short vendor, device, revision, flags;
} ohci_quirks[] = {
- {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
- QUIRK_RESET_PACKET |
- QUIRK_NO_1394A},
- {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET},
- {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
- {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+ {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
+ QUIRK_BE_HEADERS},
+
+ {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
+ QUIRK_NO_MSI},
+
+ {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
+ QUIRK_NO_MSI},
+
+ {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
+
+ {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_RESET_PACKET},
+
+ {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
};
/* This overrides anything that was found in ohci_quirks[]. */
@@ -394,10 +428,6 @@ static const char *tcodes[] = {
[0xc] = "-reserved-", [0xd] = "-reserved-",
[0xe] = "link internal", [0xf] = "-reserved-",
};
-static const char *phys[] = {
- [0x0] = "phy config packet", [0x1] = "link-on packet",
- [0x2] = "self-id packet", [0x3] = "-reserved-",
-};
static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
{
@@ -416,12 +446,6 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
return;
}
- if (header[0] == ~header[1]) {
- fw_notify("A%c %s, %s, %08x\n",
- dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]);
- return;
- }
-
switch (tcode) {
case 0x0: case 0x6: case 0x8:
snprintf(specific, sizeof(specific), " = %08x",
@@ -436,9 +460,13 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
}
switch (tcode) {
- case 0xe: case 0xa:
+ case 0xa:
fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
break;
+ case 0xe:
+ fw_notify("A%c %s, PHY %08x %08x\n",
+ dir, evts[evt], header[1], header[2]);
+ break;
case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
fw_notify("A%c spd %x tl %02x, "
"%04x -> %04x, %s, "
@@ -577,59 +605,150 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr,
return ret;
}
-static void ar_context_link_page(struct ar_context *ctx,
- struct ar_buffer *ab, dma_addr_t ab_bus)
+static inline dma_addr_t ar_buffer_bus(struct ar_context *ctx, unsigned int i)
{
- size_t offset;
+ return page_private(ctx->pages[i]);
+}
+
+static void ar_context_link_page(struct ar_context *ctx, unsigned int index)
+{
+ struct descriptor *d;
- ab->next = NULL;
- memset(&ab->descriptor, 0, sizeof(ab->descriptor));
- ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
- DESCRIPTOR_STATUS |
- DESCRIPTOR_BRANCH_ALWAYS);
- offset = offsetof(struct ar_buffer, data);
- ab->descriptor.req_count = cpu_to_le16(PAGE_SIZE - offset);
- ab->descriptor.data_address = cpu_to_le32(ab_bus + offset);
- ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset);
- ab->descriptor.branch_address = 0;
+ d = &ctx->descriptors[index];
+ d->branch_address &= cpu_to_le32(~0xf);
+ d->res_count = cpu_to_le16(PAGE_SIZE);
+ d->transfer_status = 0;
wmb(); /* finish init of new descriptors before branch_address update */
- ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
- ctx->last_buffer->next = ab;
- ctx->last_buffer = ab;
+ d = &ctx->descriptors[ctx->last_buffer_index];
+ d->branch_address |= cpu_to_le32(1);
+
+ ctx->last_buffer_index = index;
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
flush_writes(ctx->ohci);
}
-static int ar_context_add_page(struct ar_context *ctx)
+static void ar_context_release(struct ar_context *ctx)
{
- struct device *dev = ctx->ohci->card.device;
- struct ar_buffer *ab;
- dma_addr_t uninitialized_var(ab_bus);
+ unsigned int i;
- ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
- if (ab == NULL)
- return -ENOMEM;
+ if (ctx->buffer)
+ vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES);
- ar_context_link_page(ctx, ab, ab_bus);
+ for (i = 0; i < AR_BUFFERS; i++)
+ if (ctx->pages[i]) {
+ dma_unmap_page(ctx->ohci->card.device,
+ ar_buffer_bus(ctx, i),
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ __free_page(ctx->pages[i]);
+ }
+}
- return 0;
+static void ar_context_abort(struct ar_context *ctx, const char *error_msg)
+{
+ if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) {
+ reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
+ flush_writes(ctx->ohci);
+
+ fw_error("AR error: %s; DMA stopped\n", error_msg);
+ }
+ /* FIXME: restart? */
}
-static void ar_context_release(struct ar_context *ctx)
+static inline unsigned int ar_next_buffer_index(unsigned int index)
+{
+ return (index + 1) % AR_BUFFERS;
+}
+
+static inline unsigned int ar_prev_buffer_index(unsigned int index)
+{
+ return (index - 1 + AR_BUFFERS) % AR_BUFFERS;
+}
+
+static inline unsigned int ar_first_buffer_index(struct ar_context *ctx)
+{
+ return ar_next_buffer_index(ctx->last_buffer_index);
+}
+
+/*
+ * We search for the buffer that contains the last AR packet DMA data written
+ * by the controller.
+ */
+static unsigned int ar_search_last_active_buffer(struct ar_context *ctx,
+ unsigned int *buffer_offset)
{
- struct ar_buffer *ab, *ab_next;
- size_t offset;
- dma_addr_t ab_bus;
+ unsigned int i, next_i, last = ctx->last_buffer_index;
+ __le16 res_count, next_res_count;
- for (ab = ctx->current_buffer; ab; ab = ab_next) {
- ab_next = ab->next;
- offset = offsetof(struct ar_buffer, data);
- ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
- dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE,
- ab, ab_bus);
+ i = ar_first_buffer_index(ctx);
+ res_count = ACCESS_ONCE(ctx->descriptors[i].res_count);
+
+ /* A buffer that is not yet completely filled must be the last one. */
+ while (i != last && res_count == 0) {
+
+ /* Peek at the next descriptor. */
+ next_i = ar_next_buffer_index(i);
+ rmb(); /* read descriptors in order */
+ next_res_count = ACCESS_ONCE(
+ ctx->descriptors[next_i].res_count);
+ /*
+ * If the next descriptor is still empty, we must stop at this
+ * descriptor.
+ */
+ if (next_res_count == cpu_to_le16(PAGE_SIZE)) {
+ /*
+ * The exception is when the DMA data for one packet is
+ * split over three buffers; in this case, the middle
+ * buffer's descriptor might be never updated by the
+ * controller and look still empty, and we have to peek
+ * at the third one.
+ */
+ if (MAX_AR_PACKET_SIZE > PAGE_SIZE && i != last) {
+ next_i = ar_next_buffer_index(next_i);
+ rmb();
+ next_res_count = ACCESS_ONCE(
+ ctx->descriptors[next_i].res_count);
+ if (next_res_count != cpu_to_le16(PAGE_SIZE))
+ goto next_buffer_is_active;
+ }
+
+ break;
+ }
+
+next_buffer_is_active:
+ i = next_i;
+ res_count = next_res_count;
}
+
+ rmb(); /* read res_count before the DMA data */
+
+ *buffer_offset = PAGE_SIZE - le16_to_cpu(res_count);
+ if (*buffer_offset > PAGE_SIZE) {
+ *buffer_offset = 0;
+ ar_context_abort(ctx, "corrupted descriptor");
+ }
+
+ return i;
+}
+
+static void ar_sync_buffers_for_cpu(struct ar_context *ctx,
+ unsigned int end_buffer_index,
+ unsigned int end_buffer_offset)
+{
+ unsigned int i;
+
+ i = ar_first_buffer_index(ctx);
+ while (i != end_buffer_index) {
+ dma_sync_single_for_cpu(ctx->ohci->card.device,
+ ar_buffer_bus(ctx, i),
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ i = ar_next_buffer_index(i);
+ }
+ if (end_buffer_offset > 0)
+ dma_sync_single_for_cpu(ctx->ohci->card.device,
+ ar_buffer_bus(ctx, i),
+ end_buffer_offset, DMA_FROM_DEVICE);
}
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
@@ -672,6 +791,10 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
p.header[3] = cond_le32_to_cpu(buffer[3]);
p.header_length = 16;
p.payload_length = p.header[3] >> 16;
+ if (p.payload_length > MAX_ASYNC_PAYLOAD) {
+ ar_context_abort(ctx, "invalid packet length");
+ return NULL;
+ }
break;
case TCODE_WRITE_RESPONSE:
@@ -682,9 +805,8 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
break;
default:
- /* FIXME: Stop context, discard everything, and restart? */
- p.header_length = 0;
- p.payload_length = 0;
+ ar_context_abort(ctx, "invalid tcode");
+ return NULL;
}
p.payload = (void *) buffer + p.header_length;
@@ -734,121 +856,147 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
return buffer + length + 1;
}
+static void *handle_ar_packets(struct ar_context *ctx, void *p, void *end)
+{
+ void *next;
+
+ while (p < end) {
+ next = handle_ar_packet(ctx, p);
+ if (!next)
+ return p;
+ p = next;
+ }
+
+ return p;
+}
+
+static void ar_recycle_buffers(struct ar_context *ctx, unsigned int end_buffer)
+{
+ unsigned int i;
+
+ i = ar_first_buffer_index(ctx);
+ while (i != end_buffer) {
+ dma_sync_single_for_device(ctx->ohci->card.device,
+ ar_buffer_bus(ctx, i),
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ ar_context_link_page(ctx, i);
+ i = ar_next_buffer_index(i);
+ }
+}
+
static void ar_context_tasklet(unsigned long data)
{
struct ar_context *ctx = (struct ar_context *)data;
- struct ar_buffer *ab;
- struct descriptor *d;
- void *buffer, *end;
- __le16 res_count;
+ unsigned int end_buffer_index, end_buffer_offset;
+ void *p, *end;
- ab = ctx->current_buffer;
- d = &ab->descriptor;
+ p = ctx->pointer;
+ if (!p)
+ return;
- res_count = ACCESS_ONCE(d->res_count);
- if (res_count == 0) {
- size_t size, size2, rest, pktsize, size3, offset;
- dma_addr_t start_bus;
- void *start;
+ end_buffer_index = ar_search_last_active_buffer(ctx,
+ &end_buffer_offset);
+ ar_sync_buffers_for_cpu(ctx, end_buffer_index, end_buffer_offset);
+ end = ctx->buffer + end_buffer_index * PAGE_SIZE + end_buffer_offset;
+ if (end_buffer_index < ar_first_buffer_index(ctx)) {
/*
- * This descriptor is finished and we may have a
- * packet split across this and the next buffer. We
- * reuse the page for reassembling the split packet.
+ * The filled part of the overall buffer wraps around; handle
+ * all packets up to the buffer end here. If the last packet
+ * wraps around, its tail will be visible after the buffer end
+ * because the buffer start pages are mapped there again.
*/
+ void *buffer_end = ctx->buffer + AR_BUFFERS * PAGE_SIZE;
+ p = handle_ar_packets(ctx, p, buffer_end);
+ if (p < buffer_end)
+ goto error;
+ /* adjust p to point back into the actual buffer */
+ p -= AR_BUFFERS * PAGE_SIZE;
+ }
- offset = offsetof(struct ar_buffer, data);
- start = ab;
- start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
- buffer = ab->data;
-
- ab = ab->next;
- d = &ab->descriptor;
- size = start + PAGE_SIZE - ctx->pointer;
- /* valid buffer data in the next page */
- rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
- /* what actually fits in this page */
- size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
- memmove(buffer, ctx->pointer, size);
- memcpy(buffer + size, ab->data, size2);
-
- while (size > 0) {
- void *next = handle_ar_packet(ctx, buffer);
- pktsize = next - buffer;
- if (pktsize >= size) {
- /*
- * We have handled all the data that was
- * originally in this page, so we can now
- * continue in the next page.
- */
- buffer = next;
- break;
- }
- /* move the next packet to the start of the buffer */
- memmove(buffer, next, size + size2 - pktsize);
- size -= pktsize;
- /* fill up this page again */
- size3 = min(rest - size2,
- (size_t)PAGE_SIZE - offset - size - size2);
- memcpy(buffer + size + size2,
- (void *) ab->data + size2, size3);
- size2 += size3;
- }
-
- if (rest > 0) {
- /* handle the packets that are fully in the next page */
- buffer = (void *) ab->data +
- (buffer - (start + offset + size));
- end = (void *) ab->data + rest;
-
- while (buffer < end)
- buffer = handle_ar_packet(ctx, buffer);
+ p = handle_ar_packets(ctx, p, end);
+ if (p != end) {
+ if (p > end)
+ ar_context_abort(ctx, "inconsistent descriptor");
+ goto error;
+ }
- ctx->current_buffer = ab;
- ctx->pointer = end;
+ ctx->pointer = p;
+ ar_recycle_buffers(ctx, end_buffer_index);
- ar_context_link_page(ctx, start, start_bus);
- } else {
- ctx->pointer = start + PAGE_SIZE;
- }
- } else {
- buffer = ctx->pointer;
- ctx->pointer = end =
- (void *) ab + PAGE_SIZE - le16_to_cpu(res_count);
+ return;
- while (buffer < end)
- buffer = handle_ar_packet(ctx, buffer);
- }
+error:
+ ctx->pointer = NULL;
}
-static int ar_context_init(struct ar_context *ctx,
- struct fw_ohci *ohci, u32 regs)
+static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
+ unsigned int descriptors_offset, u32 regs)
{
- struct ar_buffer ab;
+ unsigned int i;
+ dma_addr_t dma_addr;
+ struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES];
+ struct descriptor *d;
ctx->regs = regs;
ctx->ohci = ohci;
- ctx->last_buffer = &ab;
tasklet_init(&ctx->tasklet, ar_context_tasklet, (unsigned long)ctx);
- ar_context_add_page(ctx);
- ar_context_add_page(ctx);
- ctx->current_buffer = ab.next;
- ctx->pointer = ctx->current_buffer->data;
+ for (i = 0; i < AR_BUFFERS; i++) {
+ ctx->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32);
+ if (!ctx->pages[i])
+ goto out_of_memory;
+ dma_addr = dma_map_page(ohci->card.device, ctx->pages[i],
+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(ohci->card.device, dma_addr)) {
+ __free_page(ctx->pages[i]);
+ ctx->pages[i] = NULL;
+ goto out_of_memory;
+ }
+ set_page_private(ctx->pages[i], dma_addr);
+ }
+
+ for (i = 0; i < AR_BUFFERS; i++)
+ pages[i] = ctx->pages[i];
+ for (i = 0; i < AR_WRAPAROUND_PAGES; i++)
+ pages[AR_BUFFERS + i] = ctx->pages[i];
+ ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES,
+ -1, PAGE_KERNEL_RO);
+ if (!ctx->buffer)
+ goto out_of_memory;
+
+ ctx->descriptors = ohci->misc_buffer + descriptors_offset;
+ ctx->descriptors_bus = ohci->misc_buffer_bus + descriptors_offset;
+
+ for (i = 0; i < AR_BUFFERS; i++) {
+ d = &ctx->descriptors[i];
+ d->req_count = cpu_to_le16(PAGE_SIZE);
+ d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
+ DESCRIPTOR_STATUS |
+ DESCRIPTOR_BRANCH_ALWAYS);
+ d->data_address = cpu_to_le32(ar_buffer_bus(ctx, i));
+ d->branch_address = cpu_to_le32(ctx->descriptors_bus +
+ ar_next_buffer_index(i) * sizeof(struct descriptor));
+ }
return 0;
+
+out_of_memory:
+ ar_context_release(ctx);
+
+ return -ENOMEM;
}
static void ar_context_run(struct ar_context *ctx)
{
- struct ar_buffer *ab = ctx->current_buffer;
- dma_addr_t ab_bus;
- size_t offset;
+ unsigned int i;
+
+ for (i = 0; i < AR_BUFFERS; i++)
+ ar_context_link_page(ctx, i);
- offset = offsetof(struct ar_buffer, data);
- ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+ ctx->pointer = ctx->buffer;
- reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1);
+ reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1);
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
flush_writes(ctx->ohci);
}
@@ -1025,6 +1173,7 @@ static void context_run(struct context *ctx, u32 extra)
le32_to_cpu(ctx->last->branch_address));
reg_write(ohci, CONTROL_CLEAR(ctx->regs), ~0);
reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN | extra);
+ ctx->running = true;
flush_writes(ohci);
}
@@ -1052,6 +1201,7 @@ static void context_stop(struct context *ctx)
int i;
reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
+ ctx->running = false;
flush_writes(ctx->ohci);
for (i = 0; i < 10; i++) {
@@ -1082,7 +1232,6 @@ static int at_context_queue_packet(struct context *ctx,
struct descriptor *d, *last;
__le32 *header;
int z, tcode;
- u32 reg;
d = context_get_descriptors(ctx, 4, &d_bus);
if (d == NULL) {
@@ -1096,21 +1245,27 @@ static int at_context_queue_packet(struct context *ctx,
/*
* The DMA format for asyncronous link packets is different
* from the IEEE1394 layout, so shift the fields around
- * accordingly. If header_length is 8, it's a PHY packet, to
- * which we need to prepend an extra quadlet.
+ * accordingly.
*/
+ tcode = (packet->header[0] >> 4) & 0x0f;
header = (__le32 *) &d[1];
- switch (packet->header_length) {
- case 16:
- case 12:
+ switch (tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ case TCODE_WRITE_BLOCK_REQUEST:
+ case TCODE_WRITE_RESPONSE:
+ case TCODE_READ_QUADLET_REQUEST:
+ case TCODE_READ_BLOCK_REQUEST:
+ case TCODE_READ_QUADLET_RESPONSE:
+ case TCODE_READ_BLOCK_RESPONSE:
+ case TCODE_LOCK_REQUEST:
+ case TCODE_LOCK_RESPONSE:
header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
(packet->speed << 16));
header[1] = cpu_to_le32((packet->header[1] & 0xffff) |
(packet->header[0] & 0xffff0000));
header[2] = cpu_to_le32(packet->header[2]);
- tcode = (packet->header[0] >> 4) & 0x0f;
if (TCODE_IS_BLOCK_PACKET(tcode))
header[3] = cpu_to_le32(packet->header[3]);
else
@@ -1119,18 +1274,18 @@ static int at_context_queue_packet(struct context *ctx,
d[0].req_count = cpu_to_le16(packet->header_length);
break;
- case 8:
+ case TCODE_LINK_INTERNAL:
header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) |
(packet->speed << 16));
- header[1] = cpu_to_le32(packet->header[0]);
- header[2] = cpu_to_le32(packet->header[1]);
+ header[1] = cpu_to_le32(packet->header[1]);
+ header[2] = cpu_to_le32(packet->header[2]);
d[0].req_count = cpu_to_le16(12);
- if (is_ping_packet(packet->header))
+ if (is_ping_packet(&packet->header[1]))
d[0].control |= cpu_to_le16(DESCRIPTOR_PING);
break;
- case 4:
+ case TCODE_STREAM_DATA:
header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
(packet->speed << 16));
header[1] = cpu_to_le32(packet->header[0] & 0xffff0000);
@@ -1180,6 +1335,8 @@ static int at_context_queue_packet(struct context *ctx,
* some controllers (like a JMicron JMB381 PCI-e) misbehave and wind
* up stalling out. So we just bail out in software and try again
* later, and everyone is happy.
+ * FIXME: Test of IntEvent.busReset may no longer be necessary since we
+ * flush AT queues in bus_reset_tasklet.
* FIXME: Document how the locking works.
*/
if (ohci->generation != packet->generation ||
@@ -1193,14 +1350,23 @@ static int at_context_queue_packet(struct context *ctx,
context_append(ctx, d, z, 4 - z);
- /* If the context isn't already running, start it up. */
- reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
- if ((reg & CONTEXT_RUN) == 0)
+ if (!ctx->running)
context_run(ctx, 0);
return 0;
}
+static void at_context_flush(struct context *ctx)
+{
+ tasklet_disable(&ctx->tasklet);
+
+ ctx->flushing = true;
+ context_tasklet((unsigned long)ctx);
+ ctx->flushing = false;
+
+ tasklet_enable(&ctx->tasklet);
+}
+
static int handle_at_packet(struct context *context,
struct descriptor *d,
struct descriptor *last)
@@ -1210,7 +1376,7 @@ static int handle_at_packet(struct context *context,
struct fw_ohci *ohci = context->ohci;
int evt;
- if (last->transfer_status == 0)
+ if (last->transfer_status == 0 && !context->flushing)
/* This descriptor isn't done yet, stop iteration. */
return 0;
@@ -1244,11 +1410,15 @@ static int handle_at_packet(struct context *context,
break;
case OHCI1394_evt_missing_ack:
- /*
- * Using a valid (current) generation count, but the
- * node is not on the bus or not sending acks.
- */
- packet->ack = RCODE_NO_ACK;
+ if (context->flushing)
+ packet->ack = RCODE_GENERATION;
+ else {
+ /*
+ * Using a valid (current) generation count, but the
+ * node is not on the bus or not sending acks.
+ */
+ packet->ack = RCODE_NO_ACK;
+ }
break;
case ACK_COMPLETE + 0x10:
@@ -1261,6 +1431,13 @@ static int handle_at_packet(struct context *context,
packet->ack = evt - 0x10;
break;
+ case OHCI1394_evt_no_status:
+ if (context->flushing) {
+ packet->ack = RCODE_GENERATION;
+ break;
+ }
+ /* fall through */
+
default:
packet->ack = RCODE_SEND_ERROR;
break;
@@ -1566,9 +1743,23 @@ static void bus_reset_tasklet(unsigned long data)
/* FIXME: Document how the locking works. */
spin_lock_irqsave(&ohci->lock, flags);
- ohci->generation = generation;
+ ohci->generation = -1; /* prevent AT packet queueing */
context_stop(&ohci->at_request_ctx);
context_stop(&ohci->at_response_ctx);
+
+ spin_unlock_irqrestore(&ohci->lock, flags);
+
+ /*
+ * Per OHCI 1.2 draft, clause 7.2.3.3, hardware may leave unsent
+ * packets in the AT queues and software needs to drain them.
+ * Some OHCI 1.1 controllers (JMicron) apparently require this too.
+ */
+ at_context_flush(&ohci->at_request_ctx);
+ at_context_flush(&ohci->at_response_ctx);
+
+ spin_lock_irqsave(&ohci->lock, flags);
+
+ ohci->generation = generation;
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
if (ohci->quirks & QUIRK_RESET_PACKET)
@@ -1636,8 +1827,12 @@ static irqreturn_t irq_handler(int irq, void *data)
if (!event || !~event)
return IRQ_NONE;
- /* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */
- reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
+ /*
+ * busReset and postedWriteErr must not be cleared yet
+ * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
+ */
+ reg_write(ohci, OHCI1394_IntEventClear,
+ event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
log_irqs(event);
if (event & OHCI1394_selfIDComplete)
@@ -1655,30 +1850,41 @@ static irqreturn_t irq_handler(int irq, void *data)
if (event & OHCI1394_respTxComplete)
tasklet_schedule(&ohci->at_response_ctx.tasklet);
- iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear);
- reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event);
+ if (event & OHCI1394_isochRx) {
+ iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear);
+ reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event);
- while (iso_event) {
- i = ffs(iso_event) - 1;
- tasklet_schedule(&ohci->ir_context_list[i].context.tasklet);
- iso_event &= ~(1 << i);
+ while (iso_event) {
+ i = ffs(iso_event) - 1;
+ tasklet_schedule(
+ &ohci->ir_context_list[i].context.tasklet);
+ iso_event &= ~(1 << i);
+ }
}
- iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear);
- reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event);
+ if (event & OHCI1394_isochTx) {
+ iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear);
+ reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event);
- while (iso_event) {
- i = ffs(iso_event) - 1;
- tasklet_schedule(&ohci->it_context_list[i].context.tasklet);
- iso_event &= ~(1 << i);
+ while (iso_event) {
+ i = ffs(iso_event) - 1;
+ tasklet_schedule(
+ &ohci->it_context_list[i].context.tasklet);
+ iso_event &= ~(1 << i);
+ }
}
if (unlikely(event & OHCI1394_regAccessFail))
fw_error("Register access failure - "
"please notify linux1394-devel@lists.sf.net\n");
- if (unlikely(event & OHCI1394_postedWriteErr))
+ if (unlikely(event & OHCI1394_postedWriteErr)) {
+ reg_read(ohci, OHCI1394_PostedWriteAddressHi);
+ reg_read(ohci, OHCI1394_PostedWriteAddressLo);
+ reg_write(ohci, OHCI1394_IntEventClear,
+ OHCI1394_postedWriteErr);
fw_error("PCI posted write error\n");
+ }
if (unlikely(event & OHCI1394_cycleTooLong)) {
if (printk_ratelimit())
@@ -1702,7 +1908,8 @@ static irqreturn_t irq_handler(int irq, void *data)
spin_lock(&ohci->lock);
update_bus_time(ohci);
spin_unlock(&ohci->lock);
- }
+ } else
+ flush_writes(ohci);
return IRQ_HANDLED;
}
@@ -2478,6 +2685,10 @@ static int ohci_start_iso(struct fw_iso_context *base,
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index);
reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match);
context_run(&ctx->context, control);
+
+ ctx->sync = sync;
+ ctx->tags = tags;
+
break;
}
@@ -2575,6 +2786,26 @@ static int ohci_set_iso_channels(struct fw_iso_context *base, u64 *channels)
return ret;
}
+#ifdef CONFIG_PM
+static void ohci_resume_iso_dma(struct fw_ohci *ohci)
+{
+ int i;
+ struct iso_context *ctx;
+
+ for (i = 0 ; i < ohci->n_ir ; i++) {
+ ctx = &ohci->ir_context_list[i];
+ if (ctx->context.running)
+ ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
+ }
+
+ for (i = 0 ; i < ohci->n_it ; i++) {
+ ctx = &ohci->it_context_list[i];
+ if (ctx->context.running)
+ ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
+ }
+}
+#endif
+
static int queue_iso_transmit(struct iso_context *ctx,
struct fw_iso_packet *packet,
struct fw_iso_buffer *buffer,
@@ -2884,7 +3115,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
struct fw_ohci *ohci;
u32 bus_options, max_receive, link_speed, version;
u64 guid;
- int i, err, n_ir, n_it;
+ int i, err;
size_t size;
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
@@ -2927,40 +3158,66 @@ static int __devinit pci_probe(struct pci_dev *dev,
}
for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
- if (ohci_quirks[i].vendor == dev->vendor &&
- (ohci_quirks[i].device == dev->device ||
- ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+ if ((ohci_quirks[i].vendor == dev->vendor) &&
+ (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
+ ohci_quirks[i].device == dev->device) &&
+ (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
+ ohci_quirks[i].revision >= dev->revision)) {
ohci->quirks = ohci_quirks[i].flags;
break;
}
if (param_quirks)
ohci->quirks = param_quirks;
- ar_context_init(&ohci->ar_request_ctx, ohci,
- OHCI1394_AsReqRcvContextControlSet);
+ /*
+ * Because dma_alloc_coherent() allocates at least one page,
+ * we save space by using a common buffer for the AR request/
+ * response descriptors and the self IDs buffer.
+ */
+ BUILD_BUG_ON(AR_BUFFERS * sizeof(struct descriptor) > PAGE_SIZE/4);
+ BUILD_BUG_ON(SELF_ID_BUF_SIZE > PAGE_SIZE/2);
+ ohci->misc_buffer = dma_alloc_coherent(ohci->card.device,
+ PAGE_SIZE,
+ &ohci->misc_buffer_bus,
+ GFP_KERNEL);
+ if (!ohci->misc_buffer) {
+ err = -ENOMEM;
+ goto fail_iounmap;
+ }
+
+ err = ar_context_init(&ohci->ar_request_ctx, ohci, 0,
+ OHCI1394_AsReqRcvContextControlSet);
+ if (err < 0)
+ goto fail_misc_buf;
- ar_context_init(&ohci->ar_response_ctx, ohci,
- OHCI1394_AsRspRcvContextControlSet);
+ err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4,
+ OHCI1394_AsRspRcvContextControlSet);
+ if (err < 0)
+ goto fail_arreq_ctx;
- context_init(&ohci->at_request_ctx, ohci,
- OHCI1394_AsReqTrContextControlSet, handle_at_packet);
+ err = context_init(&ohci->at_request_ctx, ohci,
+ OHCI1394_AsReqTrContextControlSet, handle_at_packet);
+ if (err < 0)
+ goto fail_arrsp_ctx;
- context_init(&ohci->at_response_ctx, ohci,
- OHCI1394_AsRspTrContextControlSet, handle_at_packet);
+ err = context_init(&ohci->at_response_ctx, ohci,
+ OHCI1394_AsRspTrContextControlSet, handle_at_packet);
+ if (err < 0)
+ goto fail_atreq_ctx;
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
ohci->ir_context_channels = ~0ULL;
ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
- n_ir = hweight32(ohci->ir_context_mask);
- size = sizeof(struct iso_context) * n_ir;
+ ohci->n_ir = hweight32(ohci->ir_context_mask);
+ size = sizeof(struct iso_context) * ohci->n_ir;
ohci->ir_context_list = kzalloc(size, GFP_KERNEL);
reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
- n_it = hweight32(ohci->it_context_mask);
- size = sizeof(struct iso_context) * n_it;
+ ohci->n_it = hweight32(ohci->it_context_mask);
+ size = sizeof(struct iso_context) * ohci->n_it;
ohci->it_context_list = kzalloc(size, GFP_KERNEL);
if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) {
@@ -2968,15 +3225,8 @@ static int __devinit pci_probe(struct pci_dev *dev,
goto fail_contexts;
}
- /* self-id dma buffer allocation */
- ohci->self_id_cpu = dma_alloc_coherent(ohci->card.device,
- SELF_ID_BUF_SIZE,
- &ohci->self_id_bus,
- GFP_KERNEL);
- if (ohci->self_id_cpu == NULL) {
- err = -ENOMEM;
- goto fail_contexts;
- }
+ ohci->self_id_cpu = ohci->misc_buffer + PAGE_SIZE/2;
+ ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2;
bus_options = reg_read(ohci, OHCI1394_BusOptions);
max_receive = (bus_options >> 12) & 0xf;
@@ -2986,26 +3236,30 @@ static int __devinit pci_probe(struct pci_dev *dev,
err = fw_card_add(&ohci->card, max_receive, link_speed, guid);
if (err)
- goto fail_self_id;
+ goto fail_contexts;
version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
fw_notify("Added fw-ohci device %s, OHCI v%x.%x, "
"%d IR + %d IT contexts, quirks 0x%x\n",
dev_name(&dev->dev), version >> 16, version & 0xff,
- n_ir, n_it, ohci->quirks);
+ ohci->n_ir, ohci->n_it, ohci->quirks);
return 0;
- fail_self_id:
- dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
- ohci->self_id_cpu, ohci->self_id_bus);
fail_contexts:
kfree(ohci->ir_context_list);
kfree(ohci->it_context_list);
context_release(&ohci->at_response_ctx);
+ fail_atreq_ctx:
context_release(&ohci->at_request_ctx);
+ fail_arrsp_ctx:
ar_context_release(&ohci->ar_response_ctx);
+ fail_arreq_ctx:
ar_context_release(&ohci->ar_request_ctx);
+ fail_misc_buf:
+ dma_free_coherent(ohci->card.device, PAGE_SIZE,
+ ohci->misc_buffer, ohci->misc_buffer_bus);
+ fail_iounmap:
pci_iounmap(dev, ohci->registers);
fail_iomem:
pci_release_region(dev, 0);
@@ -3044,10 +3298,10 @@ static void pci_remove(struct pci_dev *dev)
if (ohci->config_rom)
dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
ohci->config_rom, ohci->config_rom_bus);
- dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
- ohci->self_id_cpu, ohci->self_id_bus);
ar_context_release(&ohci->ar_request_ctx);
ar_context_release(&ohci->ar_response_ctx);
+ dma_free_coherent(ohci->card.device, PAGE_SIZE,
+ ohci->misc_buffer, ohci->misc_buffer_bus);
context_release(&ohci->at_request_ctx);
context_release(&ohci->at_response_ctx);
kfree(ohci->it_context_list);
@@ -3098,7 +3352,20 @@ static int pci_resume(struct pci_dev *dev)
return err;
}
- return ohci_enable(&ohci->card, NULL, 0);
+ /* Some systems don't setup GUID register on resume from ram */
+ if (!reg_read(ohci, OHCI1394_GUIDLo) &&
+ !reg_read(ohci, OHCI1394_GUIDHi)) {
+ reg_write(ohci, OHCI1394_GUIDLo, (u32)ohci->card.guid);
+ reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32));
+ }
+
+ err = ohci_enable(&ohci->card, NULL, 0);
+ if (err)
+ return err;
+
+ ohci_resume_iso_dma(ohci);
+
+ return 0;
}
#endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3143ac795eb0..082495bb08a7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -230,11 +230,11 @@ config GPIO_STMPE
This enables support for the GPIOs found on the STMPE I/O
Expanders.
-config GPIO_TC35892
- bool "TC35892 GPIOs"
- depends on MFD_TC35892
+config GPIO_TC3589X
+ bool "TC3589X GPIOs"
+ depends on MFD_TC3589X
help
- This enables support for the GPIOs found on the TC35892
+ This enables support for the GPIOs found on the TC3589X
I/O Expander.
config GPIO_TWL4030
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index bdf3ddec0652..39bfd7a37650 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
obj-$(CONFIG_GPIO_PCH) += pch_gpio.o
obj-$(CONFIG_GPIO_PL061) += pl061.o
obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o
-obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o
+obj-$(CONFIG_GPIO_TC3589X) += tc3589x-gpio.o
obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o
obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o
obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index e23c06893d19..d3e55a0ae92b 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -56,6 +56,29 @@ static struct cs5535_gpio_chip {
* registers, see include/linux/cs5535.h.
*/
+static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
+ unsigned int reg)
+{
+ unsigned long addr = chip->base + 0x80 + reg;
+
+ /*
+ * According to the CS5536 errata (#36), after suspend
+ * a write to the high bank GPIO register will clear all
+ * non-selected bits; the recommended workaround is a
+ * read-modify-write operation.
+ *
+ * Don't apply this errata to the edge status GPIOs, as writing
+ * to their lower bits will clear them.
+ */
+ if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
+ if (val & 0xffff)
+ val |= (inl(addr) & 0xffff); /* ignore the high bits */
+ else
+ val |= (inl(addr) ^ (val >> 16));
+ }
+ outl(val, addr);
+}
+
static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
unsigned int reg)
{
@@ -64,7 +87,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
outl(1 << offset, chip->base + reg);
else
/* high bank register */
- outl(1 << (offset - 16), chip->base + 0x80 + reg);
+ errata_outl(chip, 1 << (offset - 16), reg);
}
void cs5535_gpio_set(unsigned offset, unsigned int reg)
@@ -86,7 +109,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
outl(1 << (offset + 16), chip->base + reg);
else
/* high bank register */
- outl(1 << offset, chip->base + 0x80 + reg);
+ errata_outl(chip, 1 << offset, reg);
}
void cs5535_gpio_clear(unsigned offset, unsigned int reg)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 21da9c19a0cb..649550e2cae9 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1281,6 +1281,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
err = gpio_direction_output(gpio,
(flags & GPIOF_INIT_HIGH) ? 1 : 0);
+ if (err)
+ gpio_free(gpio);
+
return err;
}
EXPORT_SYMBOL_GPL(gpio_request_one);
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c
index 2762698e0204..897e0577e65e 100644
--- a/drivers/gpio/rdc321x-gpio.c
+++ b/drivers/gpio/rdc321x-gpio.c
@@ -135,7 +135,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)
struct rdc321x_gpio *rdc321x_gpio_dev;
struct rdc321x_gpio_pdata *pdata;
- pdata = pdev->dev.platform_data;
+ pdata = platform_get_drvdata(pdev);
if (!pdata) {
dev_err(&pdev->dev, "no platform data supplied\n");
return -ENODEV;
diff --git a/drivers/gpio/tc35892-gpio.c b/drivers/gpio/tc35892-gpio.c
deleted file mode 100644
index 7e10c935a047..000000000000
--- a/drivers/gpio/tc35892-gpio.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License Terms: GNU General Public License, version 2
- * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/tc35892.h>
-
-/*
- * These registers are modified under the irq bus lock and cached to avoid
- * unnecessary writes in bus_sync_unlock.
- */
-enum { REG_IBE, REG_IEV, REG_IS, REG_IE };
-
-#define CACHE_NR_REGS 4
-#define CACHE_NR_BANKS 3
-
-struct tc35892_gpio {
- struct gpio_chip chip;
- struct tc35892 *tc35892;
- struct device *dev;
- struct mutex irq_lock;
-
- int irq_base;
-
- /* Caches of interrupt control registers for bus_lock */
- u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
- u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS];
-};
-
-static inline struct tc35892_gpio *to_tc35892_gpio(struct gpio_chip *chip)
-{
- return container_of(chip, struct tc35892_gpio, chip);
-}
-
-static int tc35892_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2;
- u8 mask = 1 << (offset % 8);
- int ret;
-
- ret = tc35892_reg_read(tc35892, reg);
- if (ret < 0)
- return ret;
-
- return ret & mask;
-}
-
-static void tc35892_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
- struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2;
- unsigned pos = offset % 8;
- u8 data[] = {!!val << pos, 1 << pos};
-
- tc35892_block_write(tc35892, reg, ARRAY_SIZE(data), data);
-}
-
-static int tc35892_gpio_direction_output(struct gpio_chip *chip,
- unsigned offset, int val)
-{
- struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- u8 reg = TC35892_GPIODIR0 + offset / 8;
- unsigned pos = offset % 8;
-
- tc35892_gpio_set(chip, offset, val);
-
- return tc35892_set_bits(tc35892, reg, 1 << pos, 1 << pos);
-}
-
-static int tc35892_gpio_direction_input(struct gpio_chip *chip,
- unsigned offset)
-{
- struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- u8 reg = TC35892_GPIODIR0 + offset / 8;
- unsigned pos = offset % 8;
-
- return tc35892_set_bits(tc35892, reg, 1 << pos, 0);
-}
-
-static int tc35892_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip);
-
- return tc35892_gpio->irq_base + offset;
-}
-
-static struct gpio_chip template_chip = {
- .label = "tc35892",
- .owner = THIS_MODULE,
- .direction_input = tc35892_gpio_direction_input,
- .get = tc35892_gpio_get,
- .direction_output = tc35892_gpio_direction_output,
- .set = tc35892_gpio_set,
- .to_irq = tc35892_gpio_to_irq,
- .can_sleep = 1,
-};
-
-static int tc35892_gpio_irq_set_type(unsigned int irq, unsigned int type)
-{
- struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq);
- int offset = irq - tc35892_gpio->irq_base;
- int regoffset = offset / 8;
- int mask = 1 << (offset % 8);
-
- if (type == IRQ_TYPE_EDGE_BOTH) {
- tc35892_gpio->regs[REG_IBE][regoffset] |= mask;
- return 0;
- }
-
- tc35892_gpio->regs[REG_IBE][regoffset] &= ~mask;
-
- if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH)
- tc35892_gpio->regs[REG_IS][regoffset] |= mask;
- else
- tc35892_gpio->regs[REG_IS][regoffset] &= ~mask;
-
- if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH)
- tc35892_gpio->regs[REG_IEV][regoffset] |= mask;
- else
- tc35892_gpio->regs[REG_IEV][regoffset] &= ~mask;
-
- return 0;
-}
-
-static void tc35892_gpio_irq_lock(unsigned int irq)
-{
- struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq);
-
- mutex_lock(&tc35892_gpio->irq_lock);
-}
-
-static void tc35892_gpio_irq_sync_unlock(unsigned int irq)
-{
- struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- static const u8 regmap[] = {
- [REG_IBE] = TC35892_GPIOIBE0,
- [REG_IEV] = TC35892_GPIOIEV0,
- [REG_IS] = TC35892_GPIOIS0,
- [REG_IE] = TC35892_GPIOIE0,
- };
- int i, j;
-
- for (i = 0; i < CACHE_NR_REGS; i++) {
- for (j = 0; j < CACHE_NR_BANKS; j++) {
- u8 old = tc35892_gpio->oldregs[i][j];
- u8 new = tc35892_gpio->regs[i][j];
-
- if (new == old)
- continue;
-
- tc35892_gpio->oldregs[i][j] = new;
- tc35892_reg_write(tc35892, regmap[i] + j * 8, new);
- }
- }
-
- mutex_unlock(&tc35892_gpio->irq_lock);
-}
-
-static void tc35892_gpio_irq_mask(unsigned int irq)
-{
- struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq);
- int offset = irq - tc35892_gpio->irq_base;
- int regoffset = offset / 8;
- int mask = 1 << (offset % 8);
-
- tc35892_gpio->regs[REG_IE][regoffset] &= ~mask;
-}
-
-static void tc35892_gpio_irq_unmask(unsigned int irq)
-{
- struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq);
- int offset = irq - tc35892_gpio->irq_base;
- int regoffset = offset / 8;
- int mask = 1 << (offset % 8);
-
- tc35892_gpio->regs[REG_IE][regoffset] |= mask;
-}
-
-static struct irq_chip tc35892_gpio_irq_chip = {
- .name = "tc35892-gpio",
- .bus_lock = tc35892_gpio_irq_lock,
- .bus_sync_unlock = tc35892_gpio_irq_sync_unlock,
- .mask = tc35892_gpio_irq_mask,
- .unmask = tc35892_gpio_irq_unmask,
- .set_type = tc35892_gpio_irq_set_type,
-};
-
-static irqreturn_t tc35892_gpio_irq(int irq, void *dev)
-{
- struct tc35892_gpio *tc35892_gpio = dev;
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- u8 status[CACHE_NR_BANKS];
- int ret;
- int i;
-
- ret = tc35892_block_read(tc35892, TC35892_GPIOMIS0,
- ARRAY_SIZE(status), status);
- if (ret < 0)
- return IRQ_NONE;
-
- for (i = 0; i < ARRAY_SIZE(status); i++) {
- unsigned int stat = status[i];
- if (!stat)
- continue;
-
- while (stat) {
- int bit = __ffs(stat);
- int line = i * 8 + bit;
-
- handle_nested_irq(tc35892_gpio->irq_base + line);
- stat &= ~(1 << bit);
- }
-
- tc35892_reg_write(tc35892, TC35892_GPIOIC0 + i, status[i]);
- }
-
- return IRQ_HANDLED;
-}
-
-static int tc35892_gpio_irq_init(struct tc35892_gpio *tc35892_gpio)
-{
- int base = tc35892_gpio->irq_base;
- int irq;
-
- for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) {
- set_irq_chip_data(irq, tc35892_gpio);
- set_irq_chip_and_handler(irq, &tc35892_gpio_irq_chip,
- handle_simple_irq);
- set_irq_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
-#else
- set_irq_noprobe(irq);
-#endif
- }
-
- return 0;
-}
-
-static void tc35892_gpio_irq_remove(struct tc35892_gpio *tc35892_gpio)
-{
- int base = tc35892_gpio->irq_base;
- int irq;
-
- for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) {
-#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
-#endif
- set_irq_chip_and_handler(irq, NULL, NULL);
- set_irq_chip_data(irq, NULL);
- }
-}
-
-static int __devinit tc35892_gpio_probe(struct platform_device *pdev)
-{
- struct tc35892 *tc35892 = dev_get_drvdata(pdev->dev.parent);
- struct tc35892_gpio_platform_data *pdata;
- struct tc35892_gpio *tc35892_gpio;
- int ret;
- int irq;
-
- pdata = tc35892->pdata->gpio;
- if (!pdata)
- return -ENODEV;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- tc35892_gpio = kzalloc(sizeof(struct tc35892_gpio), GFP_KERNEL);
- if (!tc35892_gpio)
- return -ENOMEM;
-
- mutex_init(&tc35892_gpio->irq_lock);
-
- tc35892_gpio->dev = &pdev->dev;
- tc35892_gpio->tc35892 = tc35892;
-
- tc35892_gpio->chip = template_chip;
- tc35892_gpio->chip.ngpio = tc35892->num_gpio;
- tc35892_gpio->chip.dev = &pdev->dev;
- tc35892_gpio->chip.base = pdata->gpio_base;
-
- tc35892_gpio->irq_base = tc35892->irq_base + TC35892_INT_GPIO(0);
-
- /* Bring the GPIO module out of reset */
- ret = tc35892_set_bits(tc35892, TC35892_RSTCTRL,
- TC35892_RSTCTRL_GPIRST, 0);
- if (ret < 0)
- goto out_free;
-
- ret = tc35892_gpio_irq_init(tc35892_gpio);
- if (ret)
- goto out_free;
-
- ret = request_threaded_irq(irq, NULL, tc35892_gpio_irq, IRQF_ONESHOT,
- "tc35892-gpio", tc35892_gpio);
- if (ret) {
- dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
- goto out_removeirq;
- }
-
- ret = gpiochip_add(&tc35892_gpio->chip);
- if (ret) {
- dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
- goto out_freeirq;
- }
-
- if (pdata->setup)
- pdata->setup(tc35892, tc35892_gpio->chip.base);
-
- platform_set_drvdata(pdev, tc35892_gpio);
-
- return 0;
-
-out_freeirq:
- free_irq(irq, tc35892_gpio);
-out_removeirq:
- tc35892_gpio_irq_remove(tc35892_gpio);
-out_free:
- kfree(tc35892_gpio);
- return ret;
-}
-
-static int __devexit tc35892_gpio_remove(struct platform_device *pdev)
-{
- struct tc35892_gpio *tc35892_gpio = platform_get_drvdata(pdev);
- struct tc35892 *tc35892 = tc35892_gpio->tc35892;
- struct tc35892_gpio_platform_data *pdata = tc35892->pdata->gpio;
- int irq = platform_get_irq(pdev, 0);
- int ret;
-
- if (pdata->remove)
- pdata->remove(tc35892, tc35892_gpio->chip.base);
-
- ret = gpiochip_remove(&tc35892_gpio->chip);
- if (ret < 0) {
- dev_err(tc35892_gpio->dev,
- "unable to remove gpiochip: %d\n", ret);
- return ret;
- }
-
- free_irq(irq, tc35892_gpio);
- tc35892_gpio_irq_remove(tc35892_gpio);
-
- platform_set_drvdata(pdev, NULL);
- kfree(tc35892_gpio);
-
- return 0;
-}
-
-static struct platform_driver tc35892_gpio_driver = {
- .driver.name = "tc35892-gpio",
- .driver.owner = THIS_MODULE,
- .probe = tc35892_gpio_probe,
- .remove = __devexit_p(tc35892_gpio_remove),
-};
-
-static int __init tc35892_gpio_init(void)
-{
- return platform_driver_register(&tc35892_gpio_driver);
-}
-subsys_initcall(tc35892_gpio_init);
-
-static void __exit tc35892_gpio_exit(void)
-{
- platform_driver_unregister(&tc35892_gpio_driver);
-}
-module_exit(tc35892_gpio_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("TC35892 GPIO driver");
-MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/tc3589x-gpio.c
new file mode 100644
index 000000000000..180d584454fb
--- /dev/null
+++ b/drivers/gpio/tc3589x-gpio.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License, version 2
+ * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/tc3589x.h>
+
+/*
+ * These registers are modified under the irq bus lock and cached to avoid
+ * unnecessary writes in bus_sync_unlock.
+ */
+enum { REG_IBE, REG_IEV, REG_IS, REG_IE };
+
+#define CACHE_NR_REGS 4
+#define CACHE_NR_BANKS 3
+
+struct tc3589x_gpio {
+ struct gpio_chip chip;
+ struct tc3589x *tc3589x;
+ struct device *dev;
+ struct mutex irq_lock;
+
+ int irq_base;
+
+ /* Caches of interrupt control registers for bus_lock */
+ u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
+ u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS];
+};
+
+static inline struct tc3589x_gpio *to_tc3589x_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct tc3589x_gpio, chip);
+}
+
+static int tc3589x_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ u8 reg = TC3589x_GPIODATA0 + (offset / 8) * 2;
+ u8 mask = 1 << (offset % 8);
+ int ret;
+
+ ret = tc3589x_reg_read(tc3589x, reg);
+ if (ret < 0)
+ return ret;
+
+ return ret & mask;
+}
+
+static void tc3589x_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ u8 reg = TC3589x_GPIODATA0 + (offset / 8) * 2;
+ unsigned pos = offset % 8;
+ u8 data[] = {!!val << pos, 1 << pos};
+
+ tc3589x_block_write(tc3589x, reg, ARRAY_SIZE(data), data);
+}
+
+static int tc3589x_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ u8 reg = TC3589x_GPIODIR0 + offset / 8;
+ unsigned pos = offset % 8;
+
+ tc3589x_gpio_set(chip, offset, val);
+
+ return tc3589x_set_bits(tc3589x, reg, 1 << pos, 1 << pos);
+}
+
+static int tc3589x_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ u8 reg = TC3589x_GPIODIR0 + offset / 8;
+ unsigned pos = offset % 8;
+
+ return tc3589x_set_bits(tc3589x, reg, 1 << pos, 0);
+}
+
+static int tc3589x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
+
+ return tc3589x_gpio->irq_base + offset;
+}
+
+static struct gpio_chip template_chip = {
+ .label = "tc3589x",
+ .owner = THIS_MODULE,
+ .direction_input = tc3589x_gpio_direction_input,
+ .get = tc3589x_gpio_get,
+ .direction_output = tc3589x_gpio_direction_output,
+ .set = tc3589x_gpio_set,
+ .to_irq = tc3589x_gpio_to_irq,
+ .can_sleep = 1,
+};
+
+static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+ struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ int offset = irq - tc3589x_gpio->irq_base;
+ int regoffset = offset / 8;
+ int mask = 1 << (offset % 8);
+
+ if (type == IRQ_TYPE_EDGE_BOTH) {
+ tc3589x_gpio->regs[REG_IBE][regoffset] |= mask;
+ return 0;
+ }
+
+ tc3589x_gpio->regs[REG_IBE][regoffset] &= ~mask;
+
+ if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH)
+ tc3589x_gpio->regs[REG_IS][regoffset] |= mask;
+ else
+ tc3589x_gpio->regs[REG_IS][regoffset] &= ~mask;
+
+ if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH)
+ tc3589x_gpio->regs[REG_IEV][regoffset] |= mask;
+ else
+ tc3589x_gpio->regs[REG_IEV][regoffset] &= ~mask;
+
+ return 0;
+}
+
+static void tc3589x_gpio_irq_lock(unsigned int irq)
+{
+ struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+
+ mutex_lock(&tc3589x_gpio->irq_lock);
+}
+
+static void tc3589x_gpio_irq_sync_unlock(unsigned int irq)
+{
+ struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ static const u8 regmap[] = {
+ [REG_IBE] = TC3589x_GPIOIBE0,
+ [REG_IEV] = TC3589x_GPIOIEV0,
+ [REG_IS] = TC3589x_GPIOIS0,
+ [REG_IE] = TC3589x_GPIOIE0,
+ };
+ int i, j;
+
+ for (i = 0; i < CACHE_NR_REGS; i++) {
+ for (j = 0; j < CACHE_NR_BANKS; j++) {
+ u8 old = tc3589x_gpio->oldregs[i][j];
+ u8 new = tc3589x_gpio->regs[i][j];
+
+ if (new == old)
+ continue;
+
+ tc3589x_gpio->oldregs[i][j] = new;
+ tc3589x_reg_write(tc3589x, regmap[i] + j * 8, new);
+ }
+ }
+
+ mutex_unlock(&tc3589x_gpio->irq_lock);
+}
+
+static void tc3589x_gpio_irq_mask(unsigned int irq)
+{
+ struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ int offset = irq - tc3589x_gpio->irq_base;
+ int regoffset = offset / 8;
+ int mask = 1 << (offset % 8);
+
+ tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask;
+}
+
+static void tc3589x_gpio_irq_unmask(unsigned int irq)
+{
+ struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq);
+ int offset = irq - tc3589x_gpio->irq_base;
+ int regoffset = offset / 8;
+ int mask = 1 << (offset % 8);
+
+ tc3589x_gpio->regs[REG_IE][regoffset] |= mask;
+}
+
+static struct irq_chip tc3589x_gpio_irq_chip = {
+ .name = "tc3589x-gpio",
+ .bus_lock = tc3589x_gpio_irq_lock,
+ .bus_sync_unlock = tc3589x_gpio_irq_sync_unlock,
+ .mask = tc3589x_gpio_irq_mask,
+ .unmask = tc3589x_gpio_irq_unmask,
+ .set_type = tc3589x_gpio_irq_set_type,
+};
+
+static irqreturn_t tc3589x_gpio_irq(int irq, void *dev)
+{
+ struct tc3589x_gpio *tc3589x_gpio = dev;
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ u8 status[CACHE_NR_BANKS];
+ int ret;
+ int i;
+
+ ret = tc3589x_block_read(tc3589x, TC3589x_GPIOMIS0,
+ ARRAY_SIZE(status), status);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ for (i = 0; i < ARRAY_SIZE(status); i++) {
+ unsigned int stat = status[i];
+ if (!stat)
+ continue;
+
+ while (stat) {
+ int bit = __ffs(stat);
+ int line = i * 8 + bit;
+
+ handle_nested_irq(tc3589x_gpio->irq_base + line);
+ stat &= ~(1 << bit);
+ }
+
+ tc3589x_reg_write(tc3589x, TC3589x_GPIOIC0 + i, status[i]);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio)
+{
+ int base = tc3589x_gpio->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + tc3589x_gpio->chip.ngpio; irq++) {
+ set_irq_chip_data(irq, tc3589x_gpio);
+ set_irq_chip_and_handler(irq, &tc3589x_gpio_irq_chip,
+ handle_simple_irq);
+ set_irq_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ set_irq_noprobe(irq);
+#endif
+ }
+
+ return 0;
+}
+
+static void tc3589x_gpio_irq_remove(struct tc3589x_gpio *tc3589x_gpio)
+{
+ int base = tc3589x_gpio->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + tc3589x_gpio->chip.ngpio; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip_and_handler(irq, NULL, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
+}
+
+static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
+{
+ struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
+ struct tc3589x_gpio_platform_data *pdata;
+ struct tc3589x_gpio *tc3589x_gpio;
+ int ret;
+ int irq;
+
+ pdata = tc3589x->pdata->gpio;
+ if (!pdata)
+ return -ENODEV;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ tc3589x_gpio = kzalloc(sizeof(struct tc3589x_gpio), GFP_KERNEL);
+ if (!tc3589x_gpio)
+ return -ENOMEM;
+
+ mutex_init(&tc3589x_gpio->irq_lock);
+
+ tc3589x_gpio->dev = &pdev->dev;
+ tc3589x_gpio->tc3589x = tc3589x;
+
+ tc3589x_gpio->chip = template_chip;
+ tc3589x_gpio->chip.ngpio = tc3589x->num_gpio;
+ tc3589x_gpio->chip.dev = &pdev->dev;
+ tc3589x_gpio->chip.base = pdata->gpio_base;
+
+ tc3589x_gpio->irq_base = tc3589x->irq_base + TC3589x_INT_GPIO(0);
+
+ /* Bring the GPIO module out of reset */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL,
+ TC3589x_RSTCTRL_GPIRST, 0);
+ if (ret < 0)
+ goto out_free;
+
+ ret = tc3589x_gpio_irq_init(tc3589x_gpio);
+ if (ret)
+ goto out_free;
+
+ ret = request_threaded_irq(irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT,
+ "tc3589x-gpio", tc3589x_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
+ goto out_removeirq;
+ }
+
+ ret = gpiochip_add(&tc3589x_gpio->chip);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
+ goto out_freeirq;
+ }
+
+ if (pdata->setup)
+ pdata->setup(tc3589x, tc3589x_gpio->chip.base);
+
+ platform_set_drvdata(pdev, tc3589x_gpio);
+
+ return 0;
+
+out_freeirq:
+ free_irq(irq, tc3589x_gpio);
+out_removeirq:
+ tc3589x_gpio_irq_remove(tc3589x_gpio);
+out_free:
+ kfree(tc3589x_gpio);
+ return ret;
+}
+
+static int __devexit tc3589x_gpio_remove(struct platform_device *pdev)
+{
+ struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev);
+ struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+ struct tc3589x_gpio_platform_data *pdata = tc3589x->pdata->gpio;
+ int irq = platform_get_irq(pdev, 0);
+ int ret;
+
+ if (pdata->remove)
+ pdata->remove(tc3589x, tc3589x_gpio->chip.base);
+
+ ret = gpiochip_remove(&tc3589x_gpio->chip);
+ if (ret < 0) {
+ dev_err(tc3589x_gpio->dev,
+ "unable to remove gpiochip: %d\n", ret);
+ return ret;
+ }
+
+ free_irq(irq, tc3589x_gpio);
+ tc3589x_gpio_irq_remove(tc3589x_gpio);
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(tc3589x_gpio);
+
+ return 0;
+}
+
+static struct platform_driver tc3589x_gpio_driver = {
+ .driver.name = "tc3589x-gpio",
+ .driver.owner = THIS_MODULE,
+ .probe = tc3589x_gpio_probe,
+ .remove = __devexit_p(tc3589x_gpio_remove),
+};
+
+static int __init tc3589x_gpio_init(void)
+{
+ return platform_driver_register(&tc3589x_gpio_driver);
+}
+subsys_initcall(tc3589x_gpio_init);
+
+static void __exit tc3589x_gpio_exit(void)
+{
+ platform_driver_unregister(&tc3589x_gpio_driver);
+}
+module_exit(tc3589x_gpio_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TC3589x GPIO driver");
+MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
index 618398e4ed8e..c822baacd8fc 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -35,6 +35,29 @@ 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_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ switch (wm8994->type) {
+ case WM8958:
+ switch (offset) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ return -EINVAL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
@@ -136,6 +159,7 @@ static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
static struct gpio_chip template_chip = {
.label = "wm8994",
.owner = THIS_MODULE,
+ .request = wm8994_gpio_request,
.direction_input = wm8994_gpio_direction_in,
.get = wm8994_gpio_get,
.direction_output = wm8994_gpio_direction_out,
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6985cb1da72c..2baa6708e44c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
- { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
- { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
- { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
- { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+ { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
+ { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
- { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
+ { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
};
static struct drm_prop_enum_list drm_encoder_enum_list[] =
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index f7af91cb273d..2d4e17a004db 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -471,6 +471,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
int ret = 0;
+ int i;
DRM_DEBUG_KMS("\n");
@@ -666,6 +667,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (ret != 0)
goto fail;
}
+ DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
+ for (i = 0; i < set->num_connectors; i++) {
+ DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
+ drm_get_connector_name(set->connectors[i]));
+ set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+ }
kfree(save_connectors);
kfree(save_encoders);
@@ -841,7 +848,7 @@ static void output_poll_execute(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
struct drm_connector *connector;
- enum drm_connector_status old_status, status;
+ enum drm_connector_status old_status;
bool repoll = false, changed = false;
if (!drm_kms_helper_poll)
@@ -866,8 +873,12 @@ static void output_poll_execute(struct work_struct *work)
!(connector->polled & DRM_CONNECTOR_POLL_HPD))
continue;
- status = connector->funcs->detect(connector, false);
- if (old_status != status)
+ connector->status = connector->funcs->detect(connector, false);
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+ connector->base.id,
+ drm_get_connector_name(connector),
+ old_status, connector->status);
+ if (old_status != connector->status)
changed = true;
}
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 9d3a5030b6e1..16d5155edad1 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
struct timeval now;
unsigned long flags;
unsigned int seq;
+ int ret;
e = kzalloc(sizeof *e, GFP_KERNEL);
- if (e == NULL)
- return -ENOMEM;
+ if (e == NULL) {
+ ret = -ENOMEM;
+ goto err_put;
+ }
e->pipe = pipe;
e->base.pid = current->pid;
@@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
spin_lock_irqsave(&dev->event_lock, flags);
if (file_priv->event_space < sizeof e->event) {
- spin_unlock_irqrestore(&dev->event_lock, flags);
- kfree(e);
- return -ENOMEM;
+ ret = -EBUSY;
+ goto err_unlock;
}
file_priv->event_space -= sizeof e->event;
@@ -626,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec;
- drm_vblank_put(dev, e->pipe);
+ drm_vblank_put(dev, pipe);
list_add_tail(&e->base.link, &e->base.file_priv->event_list);
wake_up_interruptible(&e->base.file_priv->event_wait);
trace_drm_vblank_event_delivered(current->pid, pipe,
@@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
spin_unlock_irqrestore(&dev->event_lock, flags);
return 0;
+
+err_unlock:
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(e);
+err_put:
+ drm_vblank_put(dev, pipe);
+ return ret;
}
/**
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c
index af70337567ce..d3e8c540f778 100644
--- a/drivers/gpu/drm/i915/dvo_ch7017.c
+++ b/drivers/gpu/drm/i915/dvo_ch7017.c
@@ -242,7 +242,7 @@ fail:
static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
{
- return connector_status_unknown;
+ return connector_status_connected;
}
static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7a26f4dd21ae..cb900dc83d95 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -34,6 +34,7 @@
#include "i915_drm.h"
#include "i915_drv.h"
#include "i915_trace.h"
+#include "../../../platform/x86/intel_ips.h"
#include <linux/pci.h>
#include <linux/vgaarb.h>
#include <linux/acpi.h>
@@ -767,6 +768,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_BLT:
value = HAS_BLT(dev);
break;
+ case I915_PARAM_HAS_COHERENT_RINGS:
+ value = 1;
+ break;
default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param);
@@ -1868,6 +1872,26 @@ out_unlock:
EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
/**
+ * Tells the intel_ips driver that the i915 driver is now loaded, if
+ * IPS got loaded first.
+ *
+ * This awkward dance is so that neither module has to depend on the
+ * other in order for IPS to do the appropriate communication of
+ * GPU turbo limits to i915.
+ */
+static void
+ips_ping_for_i915_load(void)
+{
+ void (*link)(void);
+
+ link = symbol_get(ips_link_to_i915_driver);
+ if (link) {
+ link();
+ symbol_put(ips_link_to_i915_driver);
+ }
+}
+
+/**
* i915_driver_load - setup chip and create an initial config
* @dev: DRM device
* @flags: startup flags
@@ -2072,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->mchdev_lock = &mchdev_lock;
spin_unlock(&mchdev_lock);
+ ips_ping_for_i915_load();
+
return 0;
out_workqueue_free:
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 17b1cba3b5f1..275ec6ed43ae 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -38,8 +38,7 @@
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
-static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
- bool pipelined);
+static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
@@ -2594,7 +2593,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
if (reg->gpu) {
int ret;
- ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
@@ -2742,8 +2741,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
/** Flushes any GPU write domain for the object if it's dirty. */
static int
-i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
- bool pipelined)
+i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
uint32_t old_write_domain;
@@ -2762,10 +2760,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
obj->read_domains,
old_write_domain);
- if (pipelined)
- return 0;
-
- return i915_gem_object_wait_rendering(obj, true);
+ return 0;
}
/** Flushes the GTT write domain for the object if it's dirty. */
@@ -2826,18 +2821,15 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
if (obj_priv->gtt_space == NULL)
return -EINVAL;
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
i915_gem_object_flush_cpu_write_domain(obj);
- if (write) {
- ret = i915_gem_object_wait_rendering(obj, true);
- if (ret)
- return ret;
- }
-
old_write_domain = obj->write_domain;
old_read_domains = obj->read_domains;
@@ -2875,7 +2867,7 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
if (obj_priv->gtt_space == NULL)
return -EINVAL;
- ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
@@ -2924,9 +2916,12 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
uint32_t old_write_domain, old_read_domains;
int ret;
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
i915_gem_object_flush_gtt_write_domain(obj);
@@ -2935,12 +2930,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
*/
i915_gem_object_set_to_full_cpu_read_domain(obj);
- if (write) {
- ret = i915_gem_object_wait_rendering(obj, true);
- if (ret)
- return ret;
- }
-
old_write_domain = obj->write_domain;
old_read_domains = obj->read_domains;
@@ -3205,9 +3194,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
if (offset == 0 && size == obj->size)
return i915_gem_object_set_to_cpu_domain(obj, 0);
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
+
i915_gem_object_flush_gtt_write_domain(obj);
/* If we're already fully in the CPU read domain, we're done. */
@@ -3254,192 +3247,230 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
return 0;
}
-/**
- * Pin an object to the GTT and evaluate the relocations landing in it.
- */
static int
-i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj,
- struct drm_file *file_priv,
- struct drm_i915_gem_exec_object2 *entry)
+i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry,
+ struct drm_i915_gem_relocation_entry *reloc)
{
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_relocation_entry __user *user_relocs;
- struct drm_gem_object *target_obj = NULL;
- uint32_t target_handle = 0;
- int i, ret = 0;
+ struct drm_gem_object *target_obj;
+ uint32_t target_offset;
+ int ret = -EINVAL;
- user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
- for (i = 0; i < entry->relocation_count; i++) {
- struct drm_i915_gem_relocation_entry reloc;
- uint32_t target_offset;
+ target_obj = drm_gem_object_lookup(dev, file_priv,
+ reloc->target_handle);
+ if (target_obj == NULL)
+ return -ENOENT;
- if (__copy_from_user_inatomic(&reloc,
- user_relocs+i,
- sizeof(reloc))) {
- ret = -EFAULT;
- break;
- }
+ target_offset = to_intel_bo(target_obj)->gtt_offset;
- if (reloc.target_handle != target_handle) {
- drm_gem_object_unreference(target_obj);
+#if WATCH_RELOC
+ DRM_INFO("%s: obj %p offset %08x target %d "
+ "read %08x write %08x gtt %08x "
+ "presumed %08x delta %08x\n",
+ __func__,
+ obj,
+ (int) reloc->offset,
+ (int) reloc->target_handle,
+ (int) reloc->read_domains,
+ (int) reloc->write_domain,
+ (int) target_offset,
+ (int) reloc->presumed_offset,
+ reloc->delta);
+#endif
- target_obj = drm_gem_object_lookup(dev, file_priv,
- reloc.target_handle);
- if (target_obj == NULL) {
- ret = -ENOENT;
- break;
- }
+ /* The target buffer should have appeared before us in the
+ * exec_object list, so it should have a GTT space bound by now.
+ */
+ if (target_offset == 0) {
+ DRM_ERROR("No GTT space found for object %d\n",
+ reloc->target_handle);
+ goto err;
+ }
- target_handle = reloc.target_handle;
- }
- target_offset = to_intel_bo(target_obj)->gtt_offset;
+ /* Validate that the target is in a valid r/w GPU domain */
+ if (reloc->write_domain & (reloc->write_domain - 1)) {
+ DRM_ERROR("reloc with multiple write domains: "
+ "obj %p target %d offset %d "
+ "read %08x write %08x",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->read_domains,
+ reloc->write_domain);
+ goto err;
+ }
+ if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+ reloc->read_domains & I915_GEM_DOMAIN_CPU) {
+ DRM_ERROR("reloc with read/write CPU domains: "
+ "obj %p target %d offset %d "
+ "read %08x write %08x",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->read_domains,
+ reloc->write_domain);
+ goto err;
+ }
+ if (reloc->write_domain && target_obj->pending_write_domain &&
+ reloc->write_domain != target_obj->pending_write_domain) {
+ DRM_ERROR("Write domain conflict: "
+ "obj %p target %d offset %d "
+ "new %08x old %08x\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->write_domain,
+ target_obj->pending_write_domain);
+ goto err;
+ }
-#if WATCH_RELOC
- DRM_INFO("%s: obj %p offset %08x target %d "
- "read %08x write %08x gtt %08x "
- "presumed %08x delta %08x\n",
- __func__,
- obj,
- (int) reloc.offset,
- (int) reloc.target_handle,
- (int) reloc.read_domains,
- (int) reloc.write_domain,
- (int) target_offset,
- (int) reloc.presumed_offset,
- reloc.delta);
-#endif
+ target_obj->pending_read_domains |= reloc->read_domains;
+ target_obj->pending_write_domain |= reloc->write_domain;
- /* The target buffer should have appeared before us in the
- * exec_object list, so it should have a GTT space bound by now.
- */
- if (target_offset == 0) {
- DRM_ERROR("No GTT space found for object %d\n",
- reloc.target_handle);
- ret = -EINVAL;
- break;
- }
+ /* If the relocation already has the right value in it, no
+ * more work needs to be done.
+ */
+ if (target_offset == reloc->presumed_offset)
+ goto out;
- /* Validate that the target is in a valid r/w GPU domain */
- if (reloc.write_domain & (reloc.write_domain - 1)) {
- DRM_ERROR("reloc with multiple write domains: "
- "obj %p target %d offset %d "
- "read %08x write %08x",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.read_domains,
- reloc.write_domain);
- ret = -EINVAL;
- break;
- }
- if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
- reloc.read_domains & I915_GEM_DOMAIN_CPU) {
- DRM_ERROR("reloc with read/write CPU domains: "
- "obj %p target %d offset %d "
- "read %08x write %08x",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.read_domains,
- reloc.write_domain);
- ret = -EINVAL;
- break;
- }
- if (reloc.write_domain && target_obj->pending_write_domain &&
- reloc.write_domain != target_obj->pending_write_domain) {
- DRM_ERROR("Write domain conflict: "
- "obj %p target %d offset %d "
- "new %08x old %08x\n",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.write_domain,
- target_obj->pending_write_domain);
- ret = -EINVAL;
- break;
- }
+ /* Check that the relocation address is valid... */
+ if (reloc->offset > obj->base.size - 4) {
+ DRM_ERROR("Relocation beyond object bounds: "
+ "obj %p target %d offset %d size %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ (int) obj->base.size);
+ goto err;
+ }
+ if (reloc->offset & 3) {
+ DRM_ERROR("Relocation not 4-byte aligned: "
+ "obj %p target %d offset %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset);
+ goto err;
+ }
- target_obj->pending_read_domains |= reloc.read_domains;
- target_obj->pending_write_domain |= reloc.write_domain;
+ /* and points to somewhere within the target object. */
+ if (reloc->delta >= target_obj->size) {
+ DRM_ERROR("Relocation beyond target object bounds: "
+ "obj %p target %d delta %d size %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->delta,
+ (int) target_obj->size);
+ goto err;
+ }
- /* If the relocation already has the right value in it, no
- * more work needs to be done.
- */
- if (target_offset == reloc.presumed_offset)
- continue;
+ reloc->delta += target_offset;
+ if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
+ uint32_t page_offset = reloc->offset & ~PAGE_MASK;
+ char *vaddr;
- /* Check that the relocation address is valid... */
- if (reloc.offset > obj->base.size - 4) {
- DRM_ERROR("Relocation beyond object bounds: "
- "obj %p target %d offset %d size %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset, (int) obj->base.size);
- ret = -EINVAL;
- break;
- }
- if (reloc.offset & 3) {
- DRM_ERROR("Relocation not 4-byte aligned: "
- "obj %p target %d offset %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset);
- ret = -EINVAL;
- break;
- }
+ vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
+ *(uint32_t *)(vaddr + page_offset) = reloc->delta;
+ kunmap_atomic(vaddr);
+ } else {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t __iomem *reloc_entry;
+ void __iomem *reloc_page;
- /* and points to somewhere within the target object. */
- if (reloc.delta >= target_obj->size) {
- DRM_ERROR("Relocation beyond target object bounds: "
- "obj %p target %d delta %d size %d.\n",
- obj, reloc.target_handle,
- (int) reloc.delta, (int) target_obj->size);
- ret = -EINVAL;
- break;
- }
+ ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
+ if (ret)
+ goto err;
- reloc.delta += target_offset;
- if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
- uint32_t page_offset = reloc.offset & ~PAGE_MASK;
- char *vaddr;
+ /* Map the page containing the relocation we're going to perform. */
+ reloc->offset += obj->gtt_offset;
+ reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+ reloc->offset & PAGE_MASK);
+ reloc_entry = (uint32_t __iomem *)
+ (reloc_page + (reloc->offset & ~PAGE_MASK));
+ iowrite32(reloc->delta, reloc_entry);
+ io_mapping_unmap_atomic(reloc_page);
+ }
- vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]);
- *(uint32_t *)(vaddr + page_offset) = reloc.delta;
- kunmap_atomic(vaddr);
- } else {
- uint32_t __iomem *reloc_entry;
- void __iomem *reloc_page;
+ /* and update the user's relocation entry */
+ reloc->presumed_offset = target_offset;
- ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
- if (ret)
- break;
+out:
+ ret = 0;
+err:
+ drm_gem_object_unreference(target_obj);
+ return ret;
+}
- /* Map the page containing the relocation we're going to perform. */
- reloc.offset += obj->gtt_offset;
- reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
- reloc.offset & PAGE_MASK);
- reloc_entry = (uint32_t __iomem *)
- (reloc_page + (reloc.offset & ~PAGE_MASK));
- iowrite32(reloc.delta, reloc_entry);
- io_mapping_unmap_atomic(reloc_page);
- }
+static int
+i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry)
+{
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+ int i, ret;
+
+ user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
+ for (i = 0; i < entry->relocation_count; i++) {
+ struct drm_i915_gem_relocation_entry reloc;
+
+ if (__copy_from_user_inatomic(&reloc,
+ user_relocs+i,
+ sizeof(reloc)))
+ return -EFAULT;
+
+ ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc);
+ if (ret)
+ return ret;
- /* and update the user's relocation entry */
- reloc.presumed_offset = target_offset;
if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
- &reloc.presumed_offset,
- sizeof(reloc.presumed_offset))) {
- ret = -EFAULT;
- break;
- }
+ &reloc.presumed_offset,
+ sizeof(reloc.presumed_offset)))
+ return -EFAULT;
}
- drm_gem_object_unreference(target_obj);
- return ret;
+ return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry,
+ struct drm_i915_gem_relocation_entry *relocs)
+{
+ int i, ret;
+
+ for (i = 0; i < entry->relocation_count; i++) {
+ ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int
-i915_gem_execbuffer_pin(struct drm_device *dev,
- struct drm_file *file,
- struct drm_gem_object **object_list,
- struct drm_i915_gem_exec_object2 *exec_list,
- int count)
+i915_gem_execbuffer_relocate(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->base.pending_read_domains = 0;
+ obj->base.pending_write_domain = 0;
+ ret = i915_gem_execbuffer_relocate_object(obj, file,
+ &exec_list[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+i915_gem_execbuffer_reserve(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i, retry;
@@ -3502,6 +3533,87 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
}
static int
+i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
+{
+ struct drm_i915_gem_relocation_entry *reloc;
+ int i, total, ret;
+
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->in_execbuffer = false;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ total = 0;
+ for (i = 0; i < count; i++)
+ total += exec_list[i].relocation_count;
+
+ reloc = drm_malloc_ab(total, sizeof(*reloc));
+ if (reloc == NULL) {
+ mutex_lock(&dev->struct_mutex);
+ return -ENOMEM;
+ }
+
+ total = 0;
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+ if (copy_from_user(reloc+total, user_relocs,
+ exec_list[i].relocation_count *
+ sizeof(*reloc))) {
+ ret = -EFAULT;
+ mutex_lock(&dev->struct_mutex);
+ goto err;
+ }
+
+ total += exec_list[i].relocation_count;
+ }
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret) {
+ mutex_lock(&dev->struct_mutex);
+ goto err;
+ }
+
+ ret = i915_gem_execbuffer_reserve(dev, file,
+ object_list, exec_list,
+ count);
+ if (ret)
+ goto err;
+
+ total = 0;
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->base.pending_read_domains = 0;
+ obj->base.pending_write_domain = 0;
+ ret = i915_gem_execbuffer_relocate_object_slow(obj, file,
+ &exec_list[i],
+ reloc + total);
+ if (ret)
+ goto err;
+
+ total += exec_list[i].relocation_count;
+ }
+
+ /* Leave the user relocations as are, this is the painfully slow path,
+ * and we want to avoid the complication of dropping the lock whilst
+ * having buffers reserved in the aperture and so causing spurious
+ * ENOSPC for random operations.
+ */
+
+err:
+ drm_free_large(reloc);
+ return ret;
+}
+
+static int
i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
struct drm_file *file,
struct intel_ring_buffer *ring,
@@ -3630,8 +3742,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
for (i = 0; i < count; i++) {
char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
- size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry);
+ int length; /* limited by fault_in_pages_readable() */
+
+ /* First check for malicious input causing overflow */
+ if (exec[i].relocation_count >
+ INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+ return -EINVAL;
+ length = exec[i].relocation_count *
+ sizeof(struct drm_i915_gem_relocation_entry);
if (!access_ok(VERIFY_READ, ptr, length))
return -EFAULT;
@@ -3774,18 +3893,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
/* Move the objects en-masse into the GTT, evicting if necessary. */
- ret = i915_gem_execbuffer_pin(dev, file,
- object_list, exec_list,
- args->buffer_count);
+ ret = i915_gem_execbuffer_reserve(dev, file,
+ object_list, exec_list,
+ args->buffer_count);
if (ret)
goto err;
/* The objects are in their final locations, apply the relocations. */
- for (i = 0; i < args->buffer_count; i++) {
- struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
- obj->base.pending_read_domains = 0;
- obj->base.pending_write_domain = 0;
- ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]);
+ ret = i915_gem_execbuffer_relocate(dev, file,
+ object_list, exec_list,
+ args->buffer_count);
+ if (ret) {
+ if (ret == -EFAULT) {
+ ret = i915_gem_execbuffer_relocate_slow(dev, file,
+ object_list,
+ exec_list,
+ args->buffer_count);
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+ }
if (ret)
goto err;
}
@@ -4249,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
* use this buffer rather sooner than later, so issuing the required
* flush earlier is beneficial.
*/
- if (obj->write_domain & I915_GEM_GPU_DOMAINS)
+ if (obj->write_domain & I915_GEM_GPU_DOMAINS) {
i915_gem_flush_ring(dev, file_priv,
obj_priv->ring,
0, obj->write_domain);
+ } else if (obj_priv->ring->outstanding_lazy_request) {
+ /* This ring is not being cleared by active usage,
+ * so emit a request to do so.
+ */
+ u32 seqno = i915_add_request(dev,
+ NULL, NULL,
+ obj_priv->ring);
+ if (seqno == 0)
+ ret = -ENOMEM;
+ }
/* Update the active list for the hardware's current position.
* Otherwise this only updates on a delayed timer or when irqs
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 25ed911a3112..cb8f43429279 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2471,6 +2471,9 @@
# define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18)
# define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1)
+#define PCH_3DCGDIS1 0x46024
+# define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11)
+
#define FDI_PLL_FREQ_CTL 0x46030
#define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24)
#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00
@@ -2588,6 +2591,13 @@
#define ILK_DISPLAY_CHICKEN2 0x42004
#define ILK_DPARB_GATE (1<<22)
#define ILK_VSDPFD_FULL (1<<21)
+#define ILK_DISPLAY_CHICKEN_FUSES 0x42014
+#define ILK_INTERNAL_GRAPHICS_DISABLE (1<<31)
+#define ILK_INTERNAL_DISPLAY_DISABLE (1<<30)
+#define ILK_DISPLAY_DEBUG_DISABLE (1<<29)
+#define ILK_HDCP_DISABLE (1<<25)
+#define ILK_eDP_A_DISABLE (1<<24)
+#define ILK_DESKTOP (1<<23)
#define ILK_DSPCLK_GATE 0x42020
#define ILK_DPARB_CLK_GATE (1<<5)
/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
@@ -3033,6 +3043,7 @@
#define TRANS_DP_10BPC (1<<9)
#define TRANS_DP_6BPC (2<<9)
#define TRANS_DP_12BPC (3<<9)
+#define TRANS_DP_BPC_MASK (3<<9)
#define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4)
#define TRANS_DP_VSYNC_ACTIVE_LOW 0
#define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 454c064f8ef7..42729d25da58 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -239,6 +239,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
+ /* Cursor state */
+ dev_priv->saveCURACNTR = I915_READ(CURACNTR);
+ dev_priv->saveCURAPOS = I915_READ(CURAPOS);
+ dev_priv->saveCURABASE = I915_READ(CURABASE);
+ dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
+ dev_priv->saveCURBPOS = I915_READ(CURBPOS);
+ dev_priv->saveCURBBASE = I915_READ(CURBBASE);
+ if (IS_GEN2(dev))
+ dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
if (HAS_PCH_SPLIT(dev)) {
dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
@@ -529,6 +539,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
+ /* Cursor state */
+ I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
+ I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
+ I915_WRITE(CURABASE, dev_priv->saveCURABASE);
+ I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
+ I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
+ I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
+ if (IS_GEN2(dev))
+ I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
return;
}
@@ -543,16 +563,6 @@ void i915_save_display(struct drm_device *dev)
/* Don't save them in KMS mode */
i915_save_modeset_reg(dev);
- /* Cursor state */
- dev_priv->saveCURACNTR = I915_READ(CURACNTR);
- dev_priv->saveCURAPOS = I915_READ(CURAPOS);
- dev_priv->saveCURABASE = I915_READ(CURABASE);
- dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
- dev_priv->saveCURBPOS = I915_READ(CURBPOS);
- dev_priv->saveCURBBASE = I915_READ(CURBBASE);
- if (IS_GEN2(dev))
- dev_priv->saveCURSIZE = I915_READ(CURSIZE);
-
/* CRT state */
if (HAS_PCH_SPLIT(dev)) {
dev_priv->saveADPA = I915_READ(PCH_ADPA);
@@ -657,16 +667,6 @@ void i915_restore_display(struct drm_device *dev)
/* Don't restore them in KMS mode */
i915_restore_modeset_reg(dev);
- /* Cursor state */
- I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
- I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
- I915_WRITE(CURABASE, dev_priv->saveCURABASE);
- I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
- I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
- I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
- if (IS_GEN2(dev))
- I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
-
/* CRT state */
if (HAS_PCH_SPLIT(dev))
I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index 65c88f9ba12c..2cb8e0b9f1ee 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -190,37 +190,6 @@ out:
kfree(output.pointer);
}
-static int intel_dsm_switchto(enum vga_switcheroo_client_id id)
-{
- return 0;
-}
-
-static int intel_dsm_power_state(enum vga_switcheroo_client_id id,
- enum vga_switcheroo_state state)
-{
- return 0;
-}
-
-static int intel_dsm_init(void)
-{
- return 0;
-}
-
-static int intel_dsm_get_client_id(struct pci_dev *pdev)
-{
- if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return VGA_SWITCHEROO_IGD;
- else
- return VGA_SWITCHEROO_DIS;
-}
-
-static struct vga_switcheroo_handler intel_dsm_handler = {
- .switchto = intel_dsm_switchto,
- .power_state = intel_dsm_power_state,
- .init = intel_dsm_init,
- .get_client_id = intel_dsm_get_client_id,
-};
-
static bool intel_dsm_pci_probe(struct pci_dev *pdev)
{
acpi_handle dhandle, intel_handle;
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void)
{
if (!intel_dsm_detect())
return;
-
- vga_switcheroo_register_handler(&intel_dsm_handler);
}
void intel_unregister_dsm_handler(void)
{
- vga_switcheroo_unregister_handler();
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bee24b1a58e8..fca523288aca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
reg = TRANS_DP_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(TRANS_DP_PORT_SEL_MASK |
- TRANS_DP_SYNC_MASK);
+ TRANS_DP_SYNC_MASK |
+ TRANS_DP_BPC_MASK);
temp |= (TRANS_DP_OUTPUT_ENABLE |
TRANS_DP_ENH_FRAMING);
+ temp |= TRANS_DP_8BPC;
if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
@@ -2712,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den)
}
}
-#define DATA_N 0x800000
-#define LINK_N 0x80000
-
static void
ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
int link_clock, struct fdi_m_n *m_n)
{
- u64 temp;
-
m_n->tu = 64; /* default size */
- temp = (u64) DATA_N * pixel_clock;
- temp = div_u64(temp, link_clock);
- m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
- m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
- m_n->gmch_n = DATA_N;
+ /* BUG_ON(pixel_clock > INT_MAX / 36); */
+ m_n->gmch_m = bits_per_pixel * pixel_clock;
+ m_n->gmch_n = link_clock * nlanes * 8;
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
- temp = (u64) LINK_N * pixel_clock;
- m_n->link_m = div_u64(temp, link_clock);
- m_n->link_n = LINK_N;
+ m_n->link_m = pixel_clock;
+ m_n->link_n = link_clock;
fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
}
@@ -3716,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* FDI link */
if (HAS_PCH_SPLIT(dev)) {
+ int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
int lane = 0, link_bw, bpp;
/* CPU eDP doesn't require FDI link, so just set DP M/N
according to current link config */
@@ -3799,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
intel_crtc->fdi_lanes = lane;
+ if (pixel_multiplier > 1)
+ link_bw *= pixel_multiplier;
ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
}
@@ -5236,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.page_flip = intel_crtc_page_flip,
};
+static void intel_sanitize_modesetting(struct drm_device *dev,
+ int pipe, int plane)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 reg, val;
+
+ if (HAS_PCH_SPLIT(dev))
+ return;
+
+ /* Who knows what state these registers were left in by the BIOS or
+ * grub?
+ *
+ * If we leave the registers in a conflicting state (e.g. with the
+ * display plane reading from the other pipe than the one we intend
+ * to use) then when we attempt to teardown the active mode, we will
+ * not disable the pipes and planes in the correct order -- leaving
+ * a plane reading from a disabled pipe and possibly leading to
+ * undefined behaviour.
+ */
+
+ reg = DSPCNTR(plane);
+ val = I915_READ(reg);
+
+ if ((val & DISPLAY_PLANE_ENABLE) == 0)
+ return;
+ if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe)
+ return;
+
+ /* This display plane is active and attached to the other CPU pipe. */
+ pipe = !pipe;
+
+ /* Disable the plane and wait for it to stop reading from the pipe. */
+ I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
+ intel_flush_display_plane(dev, plane);
+
+ if (IS_GEN2(dev))
+ intel_wait_for_vblank(dev, pipe);
+
+ if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+ return;
+
+ /* Switch off the pipe. */
+ reg = PIPECONF(pipe);
+ val = I915_READ(reg);
+ if (val & PIPECONF_ENABLE) {
+ I915_WRITE(reg, val & ~PIPECONF_ENABLE);
+ intel_wait_for_pipe_off(dev, pipe);
+ }
+}
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
@@ -5287,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
(unsigned long)intel_crtc);
+
+ intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
}
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -5331,19 +5379,41 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask)
return index_mask;
}
+static bool has_edp_a(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!IS_MOBILE(dev))
+ return false;
+
+ if ((I915_READ(DP_A) & DP_DETECTED) == 0)
+ return false;
+
+ if (IS_GEN5(dev) &&
+ (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
+ return false;
+
+ return true;
+}
+
static void intel_setup_outputs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
bool dpd_is_edp = false;
+ bool has_lvds = false;
if (IS_MOBILE(dev) && !IS_I830(dev))
- intel_lvds_init(dev);
+ has_lvds = intel_lvds_init(dev);
+ if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
+ /* disable the panel fitter on everything but LVDS */
+ I915_WRITE(PFIT_CONTROL, 0);
+ }
if (HAS_PCH_SPLIT(dev)) {
dpd_is_edp = intel_dpd_is_edp(dev);
- if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
+ if (has_edp_a(dev))
intel_dp_init(dev, DP_A);
if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
@@ -5772,6 +5842,8 @@ void intel_init_clock_gating(struct drm_device *dev)
I915_WRITE(PCH_3DCGDIS0,
MARIUNIT_CLOCK_GATE_DISABLE |
SVSMUNIT_CLOCK_GATE_DISABLE);
+ I915_WRITE(PCH_3DCGDIS1,
+ VFMUNIT_CLOCK_GATE_DISABLE);
}
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c8e005553310..864417cffe9a 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
uint16_t address = algo_data->address;
uint8_t msg[5];
uint8_t reply[2];
+ unsigned retry;
int msg_bytes;
int reply_bytes;
int ret;
@@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
break;
}
- for (;;) {
- ret = intel_dp_aux_ch(intel_dp,
- msg, msg_bytes,
- reply, reply_bytes);
+ for (retry = 0; retry < 5; retry++) {
+ ret = intel_dp_aux_ch(intel_dp,
+ msg, msg_bytes,
+ reply, reply_bytes);
if (ret < 0) {
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret;
}
+
+ switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
+ case AUX_NATIVE_REPLY_ACK:
+ /* I2C-over-AUX Reply field is only valid
+ * when paired with AUX ACK.
+ */
+ break;
+ case AUX_NATIVE_REPLY_NACK:
+ DRM_DEBUG_KMS("aux_ch native nack\n");
+ return -EREMOTEIO;
+ case AUX_NATIVE_REPLY_DEFER:
+ udelay(100);
+ continue;
+ default:
+ DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
+ reply[0]);
+ return -EREMOTEIO;
+ }
+
switch (reply[0] & AUX_I2C_REPLY_MASK) {
case AUX_I2C_REPLY_ACK:
if (mode == MODE_I2C_READ) {
@@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
return reply_bytes - 1;
case AUX_I2C_REPLY_NACK:
- DRM_DEBUG_KMS("aux_ch nack\n");
+ DRM_DEBUG_KMS("aux_i2c nack\n");
return -EREMOTEIO;
case AUX_I2C_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_ch defer\n");
+ DRM_DEBUG_KMS("aux_i2c defer\n");
udelay(100);
break;
default:
- DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+ DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
return -EREMOTEIO;
}
}
+
+ DRM_ERROR("too many retries, giving up\n");
+ return -EREMOTEIO;
}
static int
@@ -584,17 +607,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode->clock = dev_priv->panel_fixed_mode->clock;
}
- /* Just use VBT values for eDP */
- if (is_edp(intel_dp)) {
- intel_dp->lane_count = dev_priv->edp.lanes;
- intel_dp->link_bw = dev_priv->edp.rate;
- adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
- DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
- intel_dp->link_bw, intel_dp->lane_count,
- adjusted_mode->clock);
- return true;
- }
-
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -613,6 +625,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
}
}
+ if (is_edp(intel_dp)) {
+ /* okay we failed just pick the highest */
+ intel_dp->lane_count = max_lane_count;
+ intel_dp->link_bw = bws[max_clock];
+ adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+ DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+ "count %d clock %d\n",
+ intel_dp->link_bw, intel_dp->lane_count,
+ adjusted_mode->clock);
+
+ return true;
+ }
+
return false;
}
@@ -1087,21 +1112,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
}
static uint32_t
-intel_dp_signal_levels(struct intel_dp *intel_dp)
+intel_dp_signal_levels(uint8_t train_set, int lane_count)
{
- struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t signal_levels = 0;
- u8 train_set = intel_dp->train_set[0];
- u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK;
- u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK;
+ uint32_t signal_levels = 0;
- if (is_edp(intel_dp)) {
- vswing = dev_priv->edp.vswing;
- preemphasis = dev_priv->edp.preemphasis;
- }
-
- switch (vswing) {
+ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
default:
signal_levels |= DP_VOLTAGE_0_4;
@@ -1116,7 +1131,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp)
signal_levels |= DP_VOLTAGE_1_2;
break;
}
- switch (preemphasis) {
+ switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
case DP_TRAIN_PRE_EMPHASIS_0:
default:
signal_levels |= DP_PRE_EMPHASIS_0;
@@ -1203,18 +1218,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
}
static bool
-intel_dp_aux_handshake_required(struct intel_dp *intel_dp)
-{
- struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (is_edp(intel_dp) && dev_priv->no_aux_handshake)
- return false;
-
- return true;
-}
-
-static bool
intel_dp_set_link_train(struct intel_dp *intel_dp,
uint32_t dp_reg_value,
uint8_t dp_train_pat)
@@ -1226,9 +1229,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
- if (!intel_dp_aux_handshake_required(intel_dp))
- return true;
-
intel_dp_aux_native_write_1(intel_dp,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
@@ -1261,11 +1261,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
POSTING_READ(intel_dp->output_reg);
intel_wait_for_vblank(dev, intel_crtc->pipe);
- if (intel_dp_aux_handshake_required(intel_dp))
- /* Write the link configuration data */
- intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
- intel_dp->link_configuration,
- DP_LINK_CONFIGURATION_SIZE);
+ /* Write the link configuration data */
+ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+ intel_dp->link_configuration,
+ DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
@@ -1283,7 +1282,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(intel_dp);
+ signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
@@ -1297,37 +1296,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
break;
/* Set training pattern 1 */
- udelay(500);
- if (intel_dp_aux_handshake_required(intel_dp)) {
+ udelay(100);
+ if (!intel_dp_get_link_status(intel_dp))
break;
- } else {
- if (!intel_dp_get_link_status(intel_dp))
- break;
- if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
- clock_recovery = true;
- break;
- }
+ if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+ clock_recovery = true;
+ break;
+ }
- /* Check to see if we've tried the max voltage */
- for (i = 0; i < intel_dp->lane_count; i++)
- if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
- break;
- if (i == intel_dp->lane_count)
+ /* Check to see if we've tried the max voltage */
+ for (i = 0; i < intel_dp->lane_count; i++)
+ if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
+ if (i == intel_dp->lane_count)
+ break;
- /* Check to see if we've tried the same voltage 5 times */
- if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
- ++tries;
- if (tries == 5)
- break;
- } else
- tries = 0;
- voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+ /* Check to see if we've tried the same voltage 5 times */
+ if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+ ++tries;
+ if (tries == 5)
+ break;
+ } else
+ tries = 0;
+ voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
- /* Compute new intel_dp->train_set as requested by target */
- intel_get_adjust_train(intel_dp);
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp);
}
intel_dp->DP = DP;
@@ -1354,7 +1349,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(intel_dp);
+ signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
@@ -1368,28 +1363,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
DP_TRAINING_PATTERN_2))
break;
- udelay(500);
-
- if (!intel_dp_aux_handshake_required(intel_dp)) {
+ udelay(400);
+ if (!intel_dp_get_link_status(intel_dp))
break;
- } else {
- if (!intel_dp_get_link_status(intel_dp))
- break;
- if (intel_channel_eq_ok(intel_dp)) {
- channel_eq = true;
- break;
- }
+ if (intel_channel_eq_ok(intel_dp)) {
+ channel_eq = true;
+ break;
+ }
- /* Try 5 times */
- if (tries > 5)
- break;
+ /* Try 5 times */
+ if (tries > 5)
+ break;
- /* Compute new intel_dp->train_set as requested by target */
- intel_get_adjust_train(intel_dp);
- ++tries;
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp);
+ ++tries;
}
+
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
@@ -1408,6 +1399,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t DP = intel_dp->DP;
+ if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+ return;
+
DRM_DEBUG_KMS("\n");
if (is_edp(intel_dp)) {
@@ -1430,6 +1424,28 @@ intel_dp_link_down(struct intel_dp *intel_dp)
if (is_edp(intel_dp))
DP |= DP_LINK_TRAIN_OFF;
+
+ if (!HAS_PCH_CPT(dev) &&
+ I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
+ struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
+ /* Hardware workaround: leaving our transcoder select
+ * set to transcoder B while it's off will prevent the
+ * corresponding HDMI output on transcoder A.
+ *
+ * Combine this with another hardware workaround:
+ * transcoder select bit can only be cleared while the
+ * port is enabled.
+ */
+ DP &= ~DP_PIPEB_SELECT;
+ I915_WRITE(intel_dp->output_reg, DP);
+
+ /* Changes to enable or select take place the vblank
+ * after being written.
+ */
+ intel_wait_for_vblank(intel_dp->base.base.dev,
+ intel_crtc->pipe);
+ }
+
I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(intel_dp->output_reg);
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 21551fe74541..e52c6125bb1f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -237,7 +237,7 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
-extern void intel_lvds_init(struct drm_device *dev);
+extern bool intel_lvds_init(struct drm_device *dev);
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,
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 4324a326f98e..25bcedf386fd 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
/**
* Sets the power state for the panel.
*/
-static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
+static void intel_lvds_enable(struct intel_lvds *intel_lvds)
{
struct drm_device *dev = intel_lvds->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
lvds_reg = LVDS;
}
- if (on) {
- I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
- I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
- intel_panel_set_backlight(dev, dev_priv->backlight_level);
- } else {
- dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
- intel_panel_set_backlight(dev, 0);
- I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+ I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
- if (intel_lvds->pfit_control) {
- if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
- DRM_ERROR("timed out waiting for panel to power off\n");
- I915_WRITE(PFIT_CONTROL, 0);
- intel_lvds->pfit_control = 0;
+ if (intel_lvds->pfit_dirty) {
+ /*
+ * Enable automatic panel scaling so that non-native modes
+ * fill the screen. The panel fitter should only be
+ * adjusted whilst the pipe is disabled, according to
+ * register description and PRM.
+ */
+ DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
+ intel_lvds->pfit_control,
+ intel_lvds->pfit_pgm_ratios);
+ if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
+ DRM_ERROR("timed out waiting for panel to power off\n");
+ } else {
+ I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
+ I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
intel_lvds->pfit_dirty = false;
}
+ }
+
+ I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
+ POSTING_READ(lvds_reg);
+
+ intel_panel_set_backlight(dev, dev_priv->backlight_level);
+}
+
+static void intel_lvds_disable(struct intel_lvds *intel_lvds)
+{
+ struct drm_device *dev = intel_lvds->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 ctl_reg, lvds_reg;
+
+ if (HAS_PCH_SPLIT(dev)) {
+ ctl_reg = PCH_PP_CONTROL;
+ lvds_reg = PCH_LVDS;
+ } else {
+ ctl_reg = PP_CONTROL;
+ lvds_reg = LVDS;
+ }
+
+ dev_priv->backlight_level = intel_panel_get_backlight(dev);
+ intel_panel_set_backlight(dev, 0);
+
+ I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+
+ if (intel_lvds->pfit_control) {
+ if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
+ DRM_ERROR("timed out waiting for panel to power off\n");
- I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
+ I915_WRITE(PFIT_CONTROL, 0);
+ intel_lvds->pfit_dirty = true;
}
+
+ I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
POSTING_READ(lvds_reg);
}
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
if (mode == DRM_MODE_DPMS_ON)
- intel_lvds_set_power(intel_lvds, true);
+ intel_lvds_enable(intel_lvds);
else
- intel_lvds_set_power(intel_lvds, false);
+ intel_lvds_disable(intel_lvds);
/* XXX: We never power down the LVDS pairs. */
}
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
/* Always do a full power on as we do not know what state
* we were left in.
*/
- intel_lvds_set_power(intel_lvds, true);
+ intel_lvds_enable(intel_lvds);
}
static void intel_lvds_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
/*
* The LVDS pin pair will already have been turned on in the
* intel_crtc_mode_set since it has a large impact on the DPLL
* settings.
*/
-
- if (HAS_PCH_SPLIT(dev))
- return;
-
- if (!intel_lvds->pfit_dirty)
- return;
-
- /*
- * Enable automatic panel scaling so that non-native modes fill the
- * screen. Should be enabled before the pipe is enabled, according to
- * register description and PRM.
- */
- DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
- intel_lvds->pfit_control,
- intel_lvds->pfit_pgm_ratios);
- if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
- DRM_ERROR("timed out waiting for panel to power off\n");
-
- I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
- I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
- intel_lvds->pfit_dirty = false;
}
/**
@@ -837,7 +847,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
* Create the connector, register the LVDS DDC bus, and try to figure out what
* modes we can display on the LVDS panel (if present).
*/
-void intel_lvds_init(struct drm_device *dev)
+bool intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds *intel_lvds;
@@ -853,37 +863,37 @@ void intel_lvds_init(struct drm_device *dev)
/* Skip init on machines we know falsely report LVDS */
if (dmi_check_system(intel_no_lvds))
- return;
+ return false;
pin = GMBUS_PORT_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n");
- return;
+ return false;
}
if (HAS_PCH_SPLIT(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
- return;
+ return false;
if (dev_priv->edp.support) {
DRM_DEBUG_KMS("disable LVDS for eDP support\n");
- return;
+ return false;
}
}
if (!intel_lvds_ddc_probe(dev, pin)) {
DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
- return;
+ return false;
}
intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
if (!intel_lvds) {
- return;
+ return false;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_lvds);
- return;
+ return false;
}
if (!HAS_PCH_SPLIT(dev)) {
@@ -1026,7 +1036,7 @@ out:
/* keep the LVDS connector */
dev_priv->int_lvds_connector = connector;
drm_sysfs_connector_add(connector);
- return;
+ return true;
failed:
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1034,4 +1044,5 @@ failed:
drm_encoder_cleanup(encoder);
kfree(intel_lvds);
kfree(intel_connector);
+ return false;
}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b83306f9244b..31cd7e33e820 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev,
/* G45 ring initialization fails to reset head to zero */
if (head != 0) {
- DRM_ERROR("%s head not reset to zero "
- "ctl %08x head %08x tail %08x start %08x\n",
- ring->name,
- I915_READ_CTL(ring),
- I915_READ_HEAD(ring),
- I915_READ_TAIL(ring),
- I915_READ_START(ring));
+ DRM_DEBUG_KMS("%s head not reset to zero "
+ "ctl %08x head %08x tail %08x start %08x\n",
+ ring->name,
+ I915_READ_CTL(ring),
+ I915_READ_HEAD(ring),
+ I915_READ_TAIL(ring),
+ I915_READ_START(ring));
I915_WRITE_HEAD(ring, 0);
- DRM_ERROR("%s head forced to zero "
- "ctl %08x head %08x tail %08x start %08x\n",
- ring->name,
- I915_READ_CTL(ring),
- I915_READ_HEAD(ring),
- I915_READ_TAIL(ring),
- I915_READ_START(ring));
+ if (I915_READ_HEAD(ring) & HEAD_ADDR) {
+ DRM_ERROR("failed to set %s head to zero "
+ "ctl %08x head %08x tail %08x start %08x\n",
+ ring->name,
+ I915_READ_CTL(ring),
+ I915_READ_HEAD(ring),
+ I915_READ_TAIL(ring),
+ I915_READ_START(ring));
+ }
}
I915_WRITE_CTL(ring,
@@ -694,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev,
drm_i915_private_t *dev_priv = dev->dev_private;
u32 head;
- head = intel_read_status_page(ring, 4);
- if (head) {
- ring->head = head & HEAD_ADDR;
- ring->space = ring->head - (ring->tail + 8);
- if (ring->space < 0)
- ring->space += ring->size;
- if (ring->space >= n)
- return 0;
- }
-
trace_i915_ring_wait_begin (dev);
end = jiffies + 3 * HZ;
do {
- ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
+ /* If the reported head position has wrapped or hasn't advanced,
+ * fallback to the slow and accurate path.
+ */
+ head = intel_read_status_page(ring, 4);
+ if (head < ring->actual_head)
+ head = I915_READ_HEAD(ring);
+ ring->actual_head = head;
+ ring->head = head & HEAD_ADDR;
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->size;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 3126c2681983..d2cd0f1efeed 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -30,8 +30,9 @@ struct intel_ring_buffer {
struct drm_device *dev;
struct drm_gem_object *gem_object;
- unsigned int head;
- unsigned int tail;
+ u32 actual_head;
+ u32 head;
+ u32 tail;
int space;
struct intel_hw_status_page status_page;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index de158b76bcd5..6bc42fa2a6ec 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -107,7 +107,8 @@ struct intel_sdvo {
* This is set if we treat the device as HDMI, instead of DVI.
*/
bool is_hdmi;
- bool has_audio;
+ bool has_hdmi_monitor;
+ bool has_hdmi_audio;
/**
* This is set if we detect output of sdvo device as LVDS and
@@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (!intel_sdvo_set_target_input(intel_sdvo))
return;
- if (intel_sdvo->is_hdmi &&
+ if (intel_sdvo->has_hdmi_monitor &&
!intel_sdvo_set_avi_infoframe(intel_sdvo))
return;
@@ -1063,7 +1064,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
}
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
- if (intel_sdvo->has_audio)
+ if (intel_sdvo->has_hdmi_audio)
sdvox |= SDVO_AUDIO_ENABLE;
if (INTEL_INFO(dev)->gen >= 4) {
@@ -1295,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector)
return drm_get_edid(connector, &sdvo->ddc);
}
-static struct drm_connector *
-intel_find_analog_connector(struct drm_device *dev)
-{
- struct drm_connector *connector;
- struct intel_sdvo *encoder;
-
- list_for_each_entry(encoder,
- &dev->mode_config.encoder_list,
- base.base.head) {
- if (encoder->base.type == INTEL_OUTPUT_ANALOG) {
- list_for_each_entry(connector,
- &dev->mode_config.connector_list,
- head) {
- if (&encoder->base ==
- intel_attached_encoder(connector))
- return connector;
- }
- }
- }
-
- return NULL;
-}
-
-static int
-intel_analog_is_connected(struct drm_device *dev)
-{
- struct drm_connector *analog_connector;
-
- analog_connector = intel_find_analog_connector(dev);
- if (!analog_connector)
- return false;
-
- if (analog_connector->funcs->detect(analog_connector, false) ==
- connector_status_disconnected)
- return false;
-
- return true;
-}
-
/* Mac mini hack -- use the same DDC as the analog connector */
static struct edid *
intel_sdvo_get_analog_edid(struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
- if (!intel_analog_is_connected(connector->dev))
- return NULL;
-
- return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+ return drm_get_edid(connector,
+ &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
}
enum drm_connector_status
@@ -1388,8 +1348,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
/* DDC bus is shared, match EDID to connector type */
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
- intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
- intel_sdvo->has_audio = drm_detect_monitor_audio(edid);
+ if (intel_sdvo->is_hdmi) {
+ intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
+ intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
+ }
}
connector->display_info.raw_edid = NULL;
kfree(edid);
@@ -1398,7 +1360,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
if (status == connector_status_connected) {
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
if (intel_sdvo_connector->force_audio)
- intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0;
+ intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0;
}
return status;
@@ -1415,10 +1377,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
if (!intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
return connector_status_unknown;
- if (intel_sdvo->is_tv) {
- /* add 30ms delay when the output type is SDVO-TV */
+
+ /* add 30ms delay when the output type might be TV */
+ if (intel_sdvo->caps.output_flags &
+ (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
mdelay(30);
- }
+
if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
return connector_status_unknown;
@@ -1472,8 +1436,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
edid = intel_sdvo_get_analog_edid(connector);
if (edid != NULL) {
- drm_mode_connector_update_edid_property(connector, edid);
- drm_add_edid_modes(connector, edid);
+ if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+ drm_mode_connector_update_edid_property(connector, edid);
+ drm_add_edid_modes(connector, edid);
+ }
connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -1713,12 +1679,12 @@ intel_sdvo_set_property(struct drm_connector *connector,
intel_sdvo_connector->force_audio = val;
- if (val > 0 && intel_sdvo->has_audio)
+ if (val > 0 && intel_sdvo->has_hdmi_audio)
return 0;
- if (val < 0 && !intel_sdvo->has_audio)
+ if (val < 0 && !intel_sdvo->has_hdmi_audio)
return 0;
- intel_sdvo->has_audio = val > 0;
+ intel_sdvo->has_hdmi_audio = val > 0;
goto done;
}
@@ -1942,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
speed = mapping->i2c_speed;
}
- sdvo->i2c = &dev_priv->gmbus[pin].adapter;
- intel_gmbus_set_speed(sdvo->i2c, speed);
- intel_gmbus_force_bit(sdvo->i2c, true);
+ if (pin < GMBUS_NUM_PORTS) {
+ sdvo->i2c = &dev_priv->gmbus[pin].adapter;
+ intel_gmbus_set_speed(sdvo->i2c, speed);
+ intel_gmbus_force_bit(sdvo->i2c, true);
+ } else
+ sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
}
static bool
@@ -2070,14 +2039,15 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_set_colorimetry(intel_sdvo,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
intel_sdvo->is_hdmi = true;
}
intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT));
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
-
- intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
+ if (intel_sdvo->is_hdmi)
+ intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
return true;
}
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 8e421f644a54..05efb5b9f13e 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
base += 3;
break;
case ATOM_IIO_WRITE:
+ (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
base += 3;
break;
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index df2b6f2b35f8..9fbabaa6ee44 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -253,7 +253,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
- atombios_blank_crtc(crtc, ATOM_ENABLE);
+ if (radeon_crtc->enabled)
+ atombios_blank_crtc(crtc, ATOM_ENABLE);
if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_DISABLE);
@@ -530,7 +531,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
dp_clock = dig_connector->dp_clock;
}
}
-
+#if 0 /* doesn't work properly on some laptops */
/* use recommended ref_div for ss */
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
if (ss_enabled) {
@@ -540,7 +541,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
}
}
}
-
+#endif
if (ASIC_IS_AVIVO(rdev)) {
/* 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)
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 4dc5b4714c5a..7b337c361a12 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -748,6 +748,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
unsigned i;
u32 tmp;
+ WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+
WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
for (i = 0; i < rdev->usec_timeout; i++) {
/* read MC_STATUS */
@@ -1922,7 +1924,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev)
static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
{
struct evergreen_mc_save save;
- u32 srbm_reset = 0;
u32 grbm_reset = 0;
dev_info(rdev->dev, "GPU softreset \n");
@@ -1961,16 +1962,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
udelay(50);
WREG32(GRBM_SOFT_RESET, 0);
(void)RREG32(GRBM_SOFT_RESET);
-
- /* reset all the system blocks */
- srbm_reset = SRBM_SOFT_RESET_ALL_MASK;
-
- dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
- WREG32(SRBM_SOFT_RESET, srbm_reset);
- (void)RREG32(SRBM_SOFT_RESET);
- udelay(50);
- WREG32(SRBM_SOFT_RESET, 0);
- (void)RREG32(SRBM_SOFT_RESET);
/* Wait a little for things to settle down */
udelay(50);
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
@@ -1981,10 +1972,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
RREG32(GRBM_STATUS_SE1));
dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
RREG32(SRBM_STATUS));
- /* After reset we need to reinit the asic as GPU often endup in an
- * incoherent state.
- */
- atom_asic_init(rdev->mode_info.atom_context);
evergreen_mc_resume(rdev, &save);
return 0;
}
@@ -2596,6 +2583,11 @@ int evergreen_resume(struct radeon_device *rdev)
{
int r;
+ /* reset the asic, the gfx blocks are often in a bad state
+ * after the driver is unloaded or after a resume
+ */
+ if (radeon_asic_reset(rdev))
+ dev_warn(rdev->dev, "GPU reset failed !\n");
/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
* posting will perform necessary task to bring back GPU into good
* shape.
@@ -2712,6 +2704,11 @@ int evergreen_init(struct radeon_device *rdev)
r = radeon_atombios_init(rdev);
if (r)
return r;
+ /* reset the asic, the gfx blocks are often in a bad state
+ * after the driver is unloaded or after a resume
+ */
+ if (radeon_asic_reset(rdev))
+ dev_warn(rdev->dev, "GPU reset failed !\n");
/* Post card if necessary */
if (!evergreen_card_posted(rdev)) {
if (!rdev->bios) {
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 113c70cc8b39..a73b53c44359 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -174,6 +174,7 @@
#define HDP_NONSURFACE_BASE 0x2C04
#define HDP_NONSURFACE_INFO 0x2C08
#define HDP_NONSURFACE_SIZE 0x2C0C
+#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
#define HDP_TILING_CONFIG 0x2F3C
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a3552594ccc4..9c92db7c896b 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
u32 tmp;
/* flush hdp cache so updates hit vram */
- if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+ !(rdev->flags & RADEON_IS_AGP)) {
void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
u32 tmp;
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+ * This seems to cause problems on some AGP cards. Just use the old
+ * method for them.
*/
WREG32(HDP_DEBUG1, 0);
tmp = readl((void __iomem *)ptr);
@@ -1195,8 +1198,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
mc->vram_end, mc->real_vram_size >> 20);
} else {
u64 base = 0;
- if (rdev->flags & RADEON_IS_IGP)
- base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+ if (rdev->flags & RADEON_IS_IGP) {
+ base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+ }
radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = 0;
radeon_gtt_location(rdev, mc);
@@ -1337,13 +1342,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
u32 srbm_status;
u32 grbm_status;
u32 grbm_status2;
+ struct r100_gpu_lockup *lockup;
int r;
+ if (rdev->family >= CHIP_RV770)
+ lockup = &rdev->config.rv770.lockup;
+ else
+ lockup = &rdev->config.r600.lockup;
+
srbm_status = RREG32(R_000E50_SRBM_STATUS);
grbm_status = RREG32(R_008010_GRBM_STATUS);
grbm_status2 = RREG32(R_008014_GRBM_STATUS2);
if (!G_008010_GUI_ACTIVE(grbm_status)) {
- r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
+ r100_gpu_lockup_update(lockup, &rdev->cp);
return false;
}
/* force CP activities */
@@ -1355,7 +1366,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
radeon_ring_unlock_commit(rdev);
}
rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
- return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
+ return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp);
}
int r600_asic_reset(struct radeon_device *rdev)
@@ -3483,10 +3494,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
{
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
- * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+ * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
+ * This seems to cause problems on some AGP cards. Just use the old
+ * method for them.
*/
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
- rdev->vram_scratch.ptr) {
+ rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
u32 tmp;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 9bebac1ec006..7831e0890210 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -315,11 +315,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
/* the initial DDX does bad things with the CB size occasionally */
/* it rounds up height too far for slice tile max but the BO is smaller */
- tmp = (height - 7) * pitch * bpe;
- if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
- dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
- return -EINVAL;
- }
+ /* r600c,g also seem to flush at bad times in some apps resulting in
+ * bogus values here. So for linear just allow anything to avoid breaking
+ * broken userspace.
+ */
} else {
dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h
index d84612ae47e0..33cda016b083 100644
--- a/drivers/gpu/drm/radeon/r600_reg.h
+++ b/drivers/gpu/drm/radeon/r600_reg.h
@@ -86,6 +86,7 @@
#define R600_HDP_NONSURFACE_BASE 0x2c04
#define R600_BUS_CNTL 0x5420
+# define R600_BIOS_ROM_DIS (1 << 1)
#define R600_CONFIG_CNTL 0x5424
#define R600_CONFIG_MEMSIZE 0x5428
#define R600_CONFIG_F0_BASE 0x542C
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 87ead090c7d5..bc5a2c3382d9 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -98,6 +98,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
}
}
+ /* some DCE3 boards have bad data for this entry */
+ if (ASIC_IS_DCE3(rdev)) {
+ if ((i == 4) &&
+ (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+ (gpio->sucI2cId.ucAccess == 0x94))
+ gpio->sucI2cId.ucAccess = 0x14;
+ }
+
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;
@@ -174,6 +182,14 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
}
}
+ /* some DCE3 boards have bad data for this entry */
+ if (ASIC_IS_DCE3(rdev)) {
+ if ((i == 4) &&
+ (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+ (gpio->sucI2cId.ucAccess == 0x94))
+ gpio->sucI2cId.ucAccess = 0x14;
+ }
+
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;
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 654787ec43f4..8f2c7b50dcf5 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -130,6 +130,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+
static bool r700_read_disabled_bios(struct radeon_device *rdev)
{
uint32_t viph_control;
@@ -143,7 +144,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
bool r;
viph_control = RREG32(RADEON_VIPH_CONTROL);
- bus_cntl = RREG32(RADEON_BUS_CNTL);
+ bus_cntl = RREG32(R600_BUS_CNTL);
d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -152,7 +153,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
/* disable VIP */
WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
- WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+ WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
/* Disable VGA mode */
WREG32(AVIVO_D1VGA_CONTROL,
(d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -191,7 +192,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
cg_spll_status = RREG32(R600_CG_SPLL_STATUS);
}
WREG32(RADEON_VIPH_CONTROL, viph_control);
- WREG32(RADEON_BUS_CNTL, bus_cntl);
+ WREG32(R600_BUS_CNTL, bus_cntl);
WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
@@ -216,7 +217,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
bool r;
viph_control = RREG32(RADEON_VIPH_CONTROL);
- bus_cntl = RREG32(RADEON_BUS_CNTL);
+ bus_cntl = RREG32(R600_BUS_CNTL);
d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -231,7 +232,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
/* disable VIP */
WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
- WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+ WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
/* Disable VGA mode */
WREG32(AVIVO_D1VGA_CONTROL,
(d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -262,7 +263,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
/* restore regs */
WREG32(RADEON_VIPH_CONTROL, viph_control);
- WREG32(RADEON_BUS_CNTL, bus_cntl);
+ WREG32(R600_BUS_CNTL, bus_cntl);
WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 3bddea5b5295..137b8075f6e7 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -729,7 +729,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
clk = RBIOS8(offset + 3 + (i * 5) + 3);
data = RBIOS8(offset + 3 + (i * 5) + 4);
i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
- clk, data);
+ (1 << clk), (1 << data));
rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
break;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 3bef9f6d66fd..8afaf7a7459e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1175,6 +1175,8 @@ radeon_add_atom_connector(struct drm_device *dev,
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVIA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1190,6 +1192,8 @@ radeon_add_atom_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
@@ -1226,6 +1230,11 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.load_detect_property,
1);
}
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_HDMIA:
case DRM_MODE_CONNECTOR_HDMIB:
@@ -1256,6 +1265,11 @@ radeon_add_atom_connector(struct drm_device *dev,
0);
}
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
@@ -1293,6 +1307,9 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property,
0);
}
+ connector->interlace_allowed = true;
+ /* in theory with a DP to VGA converter... */
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
@@ -1308,6 +1325,8 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_atombios_get_tv_info(rdev));
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_LVDS:
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -1326,6 +1345,8 @@ radeon_add_atom_connector(struct drm_device *dev,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
}
@@ -1403,6 +1424,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVIA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1418,6 +1441,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
@@ -1435,6 +1460,11 @@ radeon_add_legacy_connector(struct drm_device *dev,
1);
}
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
@@ -1457,6 +1487,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
radeon_combios_get_tv_info(rdev));
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_LVDS:
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -1470,6 +1502,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index d8ac1849180d..501966a13f48 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
mc->mc_vram_size = mc->aper_size;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
- dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+ dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
mc->mc_vram_size >> 20, mc->vram_start,
mc->vram_end, mc->real_vram_size >> 20);
}
@@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
}
mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
- dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+ dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
}
@@ -910,11 +910,6 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_pm_resume(rdev);
radeon_restore_bios_scratch_regs(rdev);
- /* turn on display hw */
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
- }
-
radeon_fbdev_set_suspend(rdev, 0);
release_console_sem();
@@ -922,6 +917,10 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_hpd_init(rdev);
/* blat the mode back in */
drm_helper_resume_force_mode(dev);
+ /* turn on display hw */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 88e4ea925900..60e689f2d048 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -232,9 +232,28 @@ static struct drm_driver driver_old = {
static struct drm_driver kms_driver;
+static void radeon_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+ struct apertures_struct *ap;
+ bool primary = false;
+
+ ap = alloc_apertures(1);
+ ap->ranges[0].base = pci_resource_start(pdev, 0);
+ ap->ranges[0].size = pci_resource_len(pdev, 0);
+
+#ifdef CONFIG_X86
+ primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+#endif
+ remove_conflicting_framebuffers(ap, "radeondrmfb", primary);
+ kfree(ap);
+}
+
static int __devinit
radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ /* Get rid of things like offb */
+ radeon_kick_out_firmware_fb(pdev);
+
return drm_get_pci_dev(pdev, ent, &kms_driver);
}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index efa211898fe6..6abea32be5e8 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -245,7 +245,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
goto out_unref;
}
info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
- info->apertures->ranges[0].size = rdev->mc.real_vram_size;
+ info->apertures->ranges[0].size = rdev->mc.aper_size;
info->fix.mmio_start = 0;
info->fix.mmio_len = 0;
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1d067743fee0..a598d0049aa5 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
u32 c = 0;
rbo->placement.fpfn = 0;
- rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
+ rbo->placement.lpfn = 0;
rbo->placement.placement = rbo->placements;
rbo->placement.busy_placement = rbo->placements;
if (domain & RADEON_GEM_DOMAIN_VRAM)
@@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
{
struct radeon_bo *bo;
enum ttm_bo_type type;
- int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+ unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+ unsigned long max_size = 0;
int r;
if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
}
*bo_ptr = NULL;
+ /* maximun bo size is the minimun btw visible vram and gtt size */
+ max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
+ if ((page_align << PAGE_SHIFT) >= max_size) {
+ printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
+ __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20);
+ return -ENOMEM;
+ }
+
retry:
bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
if (bo == NULL)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3052e2969ad0..ffbc278647bf 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -150,11 +150,22 @@ config DRAGONRISE_FF
Say Y here if you want to enable force feedback support for DragonRise Inc.
game controllers.
+config HID_EMS_FF
+ tristate "EMS Production Inc. force feedback support"
+ depends on USB_HID
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to enable force feedback support for devices by
+ EMS Production Ltd.
+ Currently the following devices are known to be supported:
+ - Trio Linker Plus II
+
config HID_EGALAX
tristate "eGalax multi-touch panel"
depends on USB_HID
---help---
- Support for the eGalax dual-touch panel.
+ Support for the eGalax dual-touch panels, including the
+ Joojoo and Wetab tablets.
config HID_ELECOM
tristate "ELECOM BM084 bluetooth mouse"
@@ -396,6 +407,13 @@ config HID_ROCCAT_KONE
---help---
Support for Roccat Kone mouse.
+config HID_ROCCAT_KONEPLUS
+ tristate "Roccat Kone[+] mouse support"
+ depends on USB_HID
+ select HID_ROCCAT
+ ---help---
+ Support for Roccat Kone[+] mouse.
+
config HID_ROCCAT_PYRA
tristate "Roccat Pyra mouse support"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index c335605b9200..6eae9a90b8dd 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the HID driver
#
-hid-objs := hid-core.o hid-input.o
+hid-y := hid-core.o hid-input.o
ifdef CONFIG_DEBUG_FS
hid-objs += hid-debug.o
@@ -11,18 +11,18 @@ obj-$(CONFIG_HID) += hid.o
hid-$(CONFIG_HIDRAW) += hidraw.o
-hid-logitech-objs := hid-lg.o
+hid-logitech-y := hid-lg.o
ifdef CONFIG_LOGITECH_FF
- hid-logitech-objs += hid-lgff.o
+ hid-logitech-y += hid-lgff.o
endif
ifdef CONFIG_LOGIRUMBLEPAD2_FF
- hid-logitech-objs += hid-lg2ff.o
+ hid-logitech-y += hid-lg2ff.o
endif
ifdef CONFIG_LOGIG940_FF
- hid-logitech-objs += hid-lg3ff.o
+ hid-logitech-y += hid-lg3ff.o
endif
ifdef CONFIG_LOGIWII_FF
- hid-logitech-objs += hid-lg4ff.o
+ hid-logitech-y += hid-lg4ff.o
endif
obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
@@ -35,6 +35,7 @@ obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o
+obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
+obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o
obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 02d8cd3b1b1b..5243ae2d3730 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
+#include <linux/input/mt.h>
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
MODULE_DESCRIPTION("3M PCT multitouch panels");
@@ -27,8 +28,6 @@ MODULE_LICENSE("GPL");
#include "hid-ids.h"
#define MAX_SLOTS 60
-#define MAX_TRKID USHRT_MAX
-#define MAX_EVENTS 360
/* estimated signal-to-noise ratios */
#define SN_MOVE 2048
@@ -36,14 +35,11 @@ MODULE_LICENSE("GPL");
struct mmm_finger {
__s32 x, y, w, h;
- __u16 id;
- bool prev_touch;
bool touch, valid;
};
struct mmm_data {
struct mmm_finger f[MAX_SLOTS];
- __u16 id;
__u8 curid;
__u8 nexp, nreal;
bool touch, valid;
@@ -117,14 +113,7 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
0, 1, 0, 0);
return 1;
case HID_DG_CONTACTID:
- field->logical_maximum = MAX_TRKID;
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TRACKING_ID);
- input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
- 0, MAX_TRKID, 0, 0);
- if (!hi->input->mt)
- input_mt_create_slots(hi->input, MAX_SLOTS);
- input_set_events_per_packet(hi->input, MAX_EVENTS);
+ input_mt_init_slots(hi->input, MAX_SLOTS);
return 1;
}
/* let hid-input decide for the others */
@@ -154,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
*/
static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
{
- struct mmm_finger *oldest = 0;
int i;
for (i = 0; i < MAX_SLOTS; ++i) {
struct mmm_finger *f = &md->f[i];
@@ -163,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
continue;
}
input_mt_slot(input, i);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
if (f->touch) {
/* this finger is on the screen */
int wide = (f->w > f->h);
@@ -170,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
int major = max(f->w, f->h) >> 1;
int minor = min(f->w, f->h) >> 1;
- if (!f->prev_touch)
- f->id = md->id++;
- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
- /* touchscreen emulation: pick the oldest contact */
- if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
- oldest = f;
- } else {
- /* this finger took off the screen */
- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
}
- f->prev_touch = f->touch;
f->valid = 0;
}
- /* touchscreen emulation */
- if (oldest) {
- input_event(input, EV_KEY, BTN_TOUCH, 1);
- input_event(input, EV_ABS, ABS_X, oldest->x);
- input_event(input, EV_ABS, ABS_Y, oldest->y);
- } else {
- input_event(input, EV_KEY, BTN_TOUCH, 0);
- }
+ input_mt_report_pointer_emulation(input, true);
input_sync(input);
}
@@ -274,7 +246,7 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
if (!md) {
- dev_err(&hdev->dev, "cannot allocate 3M data\n");
+ hid_err(hdev, "cannot allocate 3M data\n");
return -ENOMEM;
}
hid_set_drvdata(hdev, md);
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index 1666c1684e79..902d1dfeb1b5 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -93,7 +93,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
a4 = kzalloc(sizeof(*a4), GFP_KERNEL);
if (a4 == NULL) {
- dev_err(&hdev->dev, "can't alloc device descriptor\n");
+ hid_err(hdev, "can't alloc device descriptor\n");
ret = -ENOMEM;
goto err_free;
}
@@ -104,13 +104,13 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index eaeca564a8d3..61aa71233392 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -16,6 +16,8 @@
* any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
@@ -59,6 +61,27 @@ struct apple_key_translation {
u8 flags;
};
+static const struct apple_key_translation macbookair_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
static const struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
@@ -146,7 +169,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hid);
- const struct apple_key_translation *trans;
+ const struct apple_key_translation *trans, *table;
if (usage->code == KEY_FN) {
asc->fn_on = !!value;
@@ -157,10 +180,16 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
if (fnmode) {
int do_translate;
- trans = apple_find_translation((hid->product < 0x21d ||
- hid->product >= 0x300) ?
- powerbook_fn_keys : apple_fn_keys,
- usage->code);
+ if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
+ hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
+ table = macbookair_fn_keys;
+ else if (hid->product < 0x21d || hid->product >= 0x300)
+ table = powerbook_fn_keys;
+ else
+ table = apple_fn_keys;
+
+ trans = apple_find_translation (table, usage->code);
+
if (trans) {
if (test_bit(usage->code, asc->pressed_fn))
do_translate = 1;
@@ -253,8 +282,8 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
rdesc[53] == 0x65 && rdesc[59] == 0x65) {
- dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
- "descriptor\n");
+ hid_info(hdev,
+ "fixing up MacBook JIS keyboard report descriptor\n");
rdesc[53] = rdesc[59] = 0xe7;
}
return rdesc;
@@ -324,7 +353,7 @@ static int apple_probe(struct hid_device *hdev,
asc = kzalloc(sizeof(*asc), GFP_KERNEL);
if (asc == NULL) {
- dev_err(&hdev->dev, "can't alloc apple descriptor\n");
+ hid_err(hdev, "can't alloc apple descriptor\n");
return -ENOMEM;
}
@@ -334,7 +363,7 @@ static int apple_probe(struct hid_device *hdev,
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
@@ -345,7 +374,7 @@ static int apple_probe(struct hid_device *hdev,
ret = hid_hw_start(hdev, connect_mask);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
@@ -440,6 +469,18 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
@@ -473,7 +514,7 @@ static int __init apple_init(void)
ret = hid_register_driver(&apple_driver);
if (ret)
- printk(KERN_ERR "can't register apple driver\n");
+ pr_err("can't register apple driver\n");
return ret;
}
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
index f42ee140738a..e5b961d6ff22 100644
--- a/drivers/hid/hid-axff.c
+++ b/drivers/hid/hid-axff.c
@@ -73,14 +73,14 @@ static int axff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output reports found\n");
+ hid_err(hid, "no output reports found\n");
return -ENODEV;
}
report = list_first_entry(report_list, struct hid_report, list);
if (report->maxfield < 4) {
- dev_err(&hid->dev, "no fields in the report: %d\n", report->maxfield);
+ hid_err(hid, "no fields in the report: %d\n", report->maxfield);
return -ENODEV;
}
@@ -101,7 +101,7 @@ static int axff_init(struct hid_device *hid)
axff->report->field[3]->value[0] = 0x00;
usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
- dev_info(&hid->dev, "Force Feedback for ACRUX game controllers by Sergei Kolzun<x0r@dv-life.ru>\n");
+ hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun<x0r@dv-life.ru>\n");
return 0;
@@ -114,17 +114,17 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int error;
- dev_dbg(&hdev->dev, "ACRUX HID hardware probe...");
+ dev_dbg(&hdev->dev, "ACRUX HID hardware probe...\n");
error = hid_parse(hdev);
if (error) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
return error;
}
error = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (error) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
return error;
}
@@ -134,7 +134,7 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
* Do not fail device initialization completely as device
* may still be partially operable, just warn.
*/
- dev_warn(&hdev->dev,
+ hid_warn(hdev,
"Failed to enable force feedback support, error: %d\n",
error);
}
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 4ce7aa3a519f..a1a765a5b08a 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -56,14 +56,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c
index 5925bdcd417d..375b50929a50 100644
--- a/drivers/hid/hid-cando.c
+++ b/drivers/hid/hid-cando.c
@@ -207,7 +207,7 @@ static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id)
td = kmalloc(sizeof(struct cando_data), GFP_KERNEL);
if (!td) {
- dev_err(&hdev->dev, "cannot allocate Cando Touch data\n");
+ hid_err(hdev, "cannot allocate Cando Touch data\n");
return -ENOMEM;
}
hid_set_drvdata(hdev, td);
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index e880086c2311..888ece68a47c 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -30,8 +30,7 @@ static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
- dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
- "descriptor\n");
+ hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n");
rdesc[11] = rdesc[16] = 0xff;
rdesc[12] = rdesc[17] = 0x03;
}
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 515345b11ac9..5607e2c95167 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -14,6 +14,8 @@
* any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
@@ -59,7 +61,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
if (report_enum->report_id_hash[id])
return report_enum->report_id_hash[id];
- if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL)))
+ report = kzalloc(sizeof(struct hid_report), GFP_KERNEL);
+ if (!report)
return NULL;
if (id != 0)
@@ -90,8 +93,11 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
return NULL;
}
- if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
- + values * sizeof(unsigned), GFP_KERNEL))) return NULL;
+ field = kzalloc((sizeof(struct hid_field) +
+ usages * sizeof(struct hid_usage) +
+ values * sizeof(unsigned)), GFP_KERNEL);
+ if (!field)
+ return NULL;
field->index = report->maxfield++;
report->field[field->index] = field;
@@ -172,10 +178,14 @@ static int close_collection(struct hid_parser *parser)
static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
{
+ struct hid_collection *collection = parser->device->collection;
int n;
- for (n = parser->collection_stack_ptr - 1; n >= 0; n--)
- if (parser->device->collection[parser->collection_stack[n]].type == type)
- return parser->device->collection[parser->collection_stack[n]].usage;
+
+ for (n = parser->collection_stack_ptr - 1; n >= 0; n--) {
+ unsigned index = parser->collection_stack[n];
+ if (collection[index].type == type)
+ return collection[index].usage;
+ }
return 0; /* we know nothing about this usage type */
}
@@ -209,7 +219,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
unsigned offset;
int i;
- if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
+ report = hid_register_report(parser->device, report_type, parser->global.report_id);
+ if (!report) {
dbg_hid("hid_register_report failed\n");
return -1;
}
@@ -227,7 +238,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
usages = max_t(int, parser->local.usage_index, parser->global.report_count);
- if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)
+ field = hid_register_field(report, usages, parser->global.report_count);
+ if (!field)
return 0;
field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
@@ -652,13 +664,12 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
return -ENOMEM;
device->rsize = size;
- parser = vmalloc(sizeof(struct hid_parser));
+ parser = vzalloc(sizeof(struct hid_parser));
if (!parser) {
ret = -ENOMEM;
goto err;
}
- memset(parser, 0, sizeof(struct hid_parser));
parser->device = device;
end = start + size;
@@ -672,7 +683,8 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
if (dispatch_type[item.type](parser, &item)) {
dbg_hid("item %u %u %u %u parsing failed\n",
- item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
+ item.format, (unsigned)item.size,
+ (unsigned)item.type, (unsigned)item.tag);
goto err;
}
@@ -737,13 +749,14 @@ static u32 s32ton(__s32 value, unsigned n)
* Search linux-kernel and linux-usb-devel archives for "hid-core extract".
*/
-static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
+static __u32 extract(const struct hid_device *hid, __u8 *report,
+ unsigned offset, unsigned n)
{
u64 x;
if (n > 32)
- printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n",
- n, current->comm);
+ hid_warn(hid, "extract() called with n (%d) > 32! (%s)\n",
+ n, current->comm);
report += offset >> 3; /* adjust byte index */
offset &= 7; /* now only need bit offset into one byte */
@@ -760,18 +773,19 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
* endianness of register values by considering a register
* a "cached" copy of the little endiad bit stream.
*/
-static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
+static void implement(const struct hid_device *hid, __u8 *report,
+ unsigned offset, unsigned n, __u32 value)
{
u64 x;
u64 m = (1ULL << n) - 1;
if (n > 32)
- printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n",
- n, current->comm);
+ hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n",
+ __func__, n, current->comm);
if (value > m)
- printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n",
- value, current->comm);
+ hid_warn(hid, "%s() called with too large value %d! (%s)\n",
+ __func__, value, current->comm);
WARN_ON(value > m);
value &= m;
@@ -788,7 +802,7 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3
* Search an array for a value.
*/
-static __inline__ int search(__s32 *array, __s32 value, unsigned n)
+static int search(__s32 *array, __s32 value, unsigned n)
{
while (n--) {
if (*array++ == value)
@@ -887,18 +901,22 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
__s32 max = field->logical_maximum;
__s32 *value;
- if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))
+ value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC);
+ if (!value)
return;
for (n = 0; n < count; n++) {
- value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) :
- extract(data, offset + n * size, size);
+ value[n] = min < 0 ?
+ snto32(extract(hid, data, offset + n * size, size),
+ size) :
+ extract(hid, data, offset + n * size, size);
- if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */
- && value[n] >= min && value[n] <= max
- && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
- goto exit;
+ /* Ignore report if ErrorRollOver */
+ if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
+ value[n] >= min && value[n] <= max &&
+ field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
+ goto exit;
}
for (n = 0; n < count; n++) {
@@ -928,7 +946,8 @@ exit:
* Output the field into the report.
*/
-static void hid_output_field(struct hid_field *field, __u8 *data)
+static void hid_output_field(const struct hid_device *hid,
+ struct hid_field *field, __u8 *data)
{
unsigned count = field->report_count;
unsigned offset = field->report_offset;
@@ -937,9 +956,11 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
for (n = 0; n < count; n++) {
if (field->logical_minimum < 0) /* signed values */
- implement(data, offset + n * size, size, s32ton(field->value[n], size));
+ implement(hid, data, offset + n * size, size,
+ s32ton(field->value[n], size));
else /* unsigned values */
- implement(data, offset + n * size, size, field->value[n]);
+ implement(hid, data, offset + n * size, size,
+ field->value[n]);
}
}
@@ -956,7 +977,7 @@ void hid_output_report(struct hid_report *report, __u8 *data)
memset(data, 0, ((report->size - 1) >> 3) + 1);
for (n = 0; n < report->maxfield; n++)
- hid_output_field(report->field[n], data);
+ hid_output_field(report->device, report->field[n], data);
}
EXPORT_SYMBOL_GPL(hid_output_report);
@@ -1169,8 +1190,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
hdev->claimed |= HID_CLAIMED_HIDRAW;
if (!hdev->claimed) {
- dev_err(&hdev->dev, "claimed by neither input, hiddev nor "
- "hidraw\n");
+ hid_err(hdev, "claimed by neither input, hiddev nor hidraw\n");
return -ENODEV;
}
@@ -1210,9 +1230,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
bus = "<UNKNOWN>";
}
- dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
- buf, bus, hdev->version >> 8, hdev->version & 0xff,
- type, hdev->name, hdev->phys);
+ hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
+ buf, bus, hdev->version >> 8, hdev->version & 0xff,
+ type, hdev->name, hdev->phys);
return 0;
}
@@ -1230,7 +1250,7 @@ void hid_disconnect(struct hid_device *hdev)
EXPORT_SYMBOL_GPL(hid_disconnect);
/* a list of devices for which there is a specialized driver on HID bus */
-static const struct hid_device_id hid_blacklist[] = {
+static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
@@ -1276,6 +1296,12 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
@@ -1292,6 +1318,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
@@ -1300,7 +1327,11 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1369,6 +1400,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
@@ -1386,6 +1418,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ 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_THRUSTMASTER, 0xb65a) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
@@ -1495,9 +1528,9 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv)
if (!hid_match_device(hdev, hdrv))
return 0;
- /* generic wants all non-blacklisted */
+ /* generic wants all that don't have specialized driver */
if (!strncmp(hdrv->name, "generic-", 8))
- return !hid_match_id(hdev, hid_blacklist);
+ return !hid_match_id(hdev, hid_have_special_driver);
return 1;
}
@@ -1756,6 +1789,12 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ }
@@ -1947,12 +1986,12 @@ static int __init hid_init(void)
int ret;
if (hid_debug)
- printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n"
- "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n");
+ pr_warn("hid_debug is now used solely for parser and driver debugging.\n"
+ "debugfs is now used for inspecting the device (report descriptor, reports)\n");
ret = bus_register(&hid_bus_type);
if (ret) {
- printk(KERN_ERR "HID: can't register hid bus\n");
+ pr_err("can't register hid bus\n");
goto err;
}
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 4cd0e2345991..2f0be4c66af7 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -107,13 +107,13 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 75c5e23d09d2..555382fc7417 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -26,6 +26,8 @@
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
@@ -393,7 +395,7 @@ char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
buf = resolv_usage_page(usage >> 16, f);
if (IS_ERR(buf)) {
- printk(KERN_ERR "error allocating HID debug buffer\n");
+ pr_err("error allocating HID debug buffer\n");
return NULL;
}
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
index 968b04f9b796..afcf3d67eb02 100644
--- a/drivers/hid/hid-drff.c
+++ b/drivers/hid/hid-drff.c
@@ -96,18 +96,18 @@ static int drff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output reports found\n");
+ hid_err(hid, "no output reports found\n");
return -ENODEV;
}
report = list_first_entry(report_list, struct hid_report, list);
if (report->maxfield < 1) {
- dev_err(&hid->dev, "no fields in the report\n");
+ hid_err(hid, "no fields in the report\n");
return -ENODEV;
}
if (report->field[0]->report_count < 7) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ hid_err(hid, "not enough values in the field\n");
return -ENODEV;
}
@@ -133,8 +133,8 @@ static int drff_init(struct hid_device *hid)
drff->report->field[0]->value[6] = 0x00;
usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
- dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
- "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+ hid_info(hid, "Force Feedback for DragonRise Inc. "
+ "game controllers by Richard Walmsley <richwalm@gmail.com>\n");
return 0;
}
@@ -153,13 +153,13 @@ static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index 54b017ad258d..03bee1970d70 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -2,6 +2,8 @@
* HID driver for eGalax dual-touch panels
*
* Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
+ * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
+ * Copyright (c) 2010 Canonical, Ltd.
*
*/
@@ -16,6 +18,7 @@
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/input/mt.h>
#include <linux/slab.h>
#include "usbhid/usbhid.h"
@@ -25,38 +28,53 @@ MODULE_LICENSE("GPL");
#include "hid-ids.h"
+#define MAX_SLOTS 2
+
+/* estimated signal-to-noise ratios */
+#define SN_MOVE 4096
+#define SN_PRESSURE 32
+
struct egalax_data {
- __u16 x, y, z;
- __u8 id;
- bool first; /* is this the first finger in the frame? */
- bool valid; /* valid finger data, or just placeholder? */
- bool activity; /* at least one active finger previously? */
- __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
+ int valid;
+ int slot;
+ int touch;
+ int x, y, z;
};
+static void set_abs(struct input_dev *input, unsigned int code,
+ struct hid_field *field, int snratio)
+{
+ int fmin = field->logical_minimum;
+ int fmax = field->logical_maximum;
+ int fuzz = snratio ? (fmax - fmin) / snratio : 0;
+ input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
+}
+
static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
+ struct input_dev *input = hi->input;
+
switch (usage->hid & HID_USAGE_PAGE) {
case HID_UP_GENDESK:
switch (usage->hid) {
case HID_GD_X:
+ field->logical_maximum = 32760;
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_POSITION_X);
+ set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE);
/* touchscreen emulation */
- input_set_abs_params(hi->input, ABS_X,
- field->logical_minimum,
- field->logical_maximum, 0, 0);
+ set_abs(input, ABS_X, field, SN_MOVE);
return 1;
case HID_GD_Y:
+ field->logical_maximum = 32760;
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_POSITION_Y);
+ set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE);
/* touchscreen emulation */
- input_set_abs_params(hi->input, ABS_Y,
- field->logical_minimum,
- field->logical_maximum, 0, 0);
+ set_abs(input, ABS_Y, field, SN_MOVE);
return 1;
}
return 0;
@@ -66,6 +84,7 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case HID_DG_TIPSWITCH:
/* touchscreen emulation */
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+ input_set_capability(input, EV_KEY, BTN_TOUCH);
return 1;
case HID_DG_INRANGE:
case HID_DG_CONFIDENCE:
@@ -73,16 +92,15 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case HID_DG_CONTACTMAX:
return -1;
case HID_DG_CONTACTID:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TRACKING_ID);
+ input_mt_init_slots(input, MAX_SLOTS);
return 1;
case HID_DG_TIPPRESSURE:
+ field->logical_minimum = 0;
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_PRESSURE);
+ set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE);
/* touchscreen emulation */
- input_set_abs_params(hi->input, ABS_PRESSURE,
- field->logical_minimum,
- field->logical_maximum, 0, 0);
+ set_abs(input, ABS_PRESSURE, field, SN_PRESSURE);
return 1;
}
return 0;
@@ -96,10 +114,10 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
+ /* tell hid-input to skip setup of these event types */
if (usage->type == EV_KEY || usage->type == EV_ABS)
- clear_bit(usage->code, *bit);
-
- return 0;
+ set_bit(usage->type, hi->input->evbit);
+ return -1;
}
/*
@@ -108,58 +126,16 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
*/
static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
{
- td->first = !td->first; /* touchscreen emulation */
-
- if (td->valid) {
- /* emit multitouch events */
- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
+ input_mt_slot(input, td->slot);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch);
+ if (td->touch) {
+ input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+ input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
-
- input_mt_sync(input);
-
- /*
- * touchscreen emulation: store (x, y) as
- * the last valid values in this frame
- */
- td->lastx = td->x;
- td->lasty = td->y;
- td->lastz = td->z;
- }
-
- /*
- * touchscreen emulation: if this is the second finger and at least
- * one in this frame is valid, the latest valid in the frame is
- * the oldest on the panel, the one we want for single touch
- */
- if (!td->first && td->activity) {
- input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
- input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
- input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
- }
-
- if (!td->valid) {
- /*
- * touchscreen emulation: if the first finger is invalid
- * and there previously was finger activity, this is a release
- */
- if (td->first && td->activity) {
- input_event(input, EV_KEY, BTN_TOUCH, 0);
- td->activity = false;
- }
- return;
- }
-
-
- /* touchscreen emulation: if no previous activity, emit touch event */
- if (!td->activity) {
- input_event(input, EV_KEY, BTN_TOUCH, 1);
- td->activity = true;
}
+ input_mt_report_pointer_emulation(input, true);
}
-
static int egalax_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
@@ -169,25 +145,26 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
* uses a standard parallel multitouch protocol (product ID ==
* 48xx). The second is capacitive and uses an unusual "serial"
* protocol with a different message for each multitouch finger
- * (product ID == 72xx). We do not yet generate a correct event
- * sequence for the capacitive/serial protocol.
+ * (product ID == 72xx).
*/
if (hid->claimed & HID_CLAIMED_INPUT) {
struct input_dev *input = field->hidinput->input;
switch (usage->hid) {
case HID_DG_INRANGE:
+ td->valid = value;
+ break;
case HID_DG_CONFIDENCE:
/* avoid interference from generic hidinput handling */
break;
case HID_DG_TIPSWITCH:
- td->valid = value;
+ td->touch = value;
break;
case HID_DG_TIPPRESSURE:
td->z = value;
break;
case HID_DG_CONTACTID:
- td->id = value;
+ td->slot = clamp_val(value, 0, MAX_SLOTS - 1);
break;
case HID_GD_X:
td->x = value;
@@ -195,11 +172,11 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
case HID_GD_Y:
td->y = value;
/* this is the last field in a finger */
- egalax_filter_event(td, input);
+ if (td->valid)
+ egalax_filter_event(td, input);
break;
case HID_DG_CONTACTCOUNT:
/* touch emulation: this is the last field in a frame */
- td->first = false;
break;
default:
@@ -221,9 +198,9 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
struct egalax_data *td;
struct hid_report *report;
- td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL);
+ td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
if (!td) {
- dev_err(&hdev->dev, "cannot allocate eGalax data\n");
+ hid_err(hdev, "cannot allocate eGalax data\n");
return -ENOMEM;
}
hid_set_drvdata(hdev, td);
@@ -261,6 +238,12 @@ static const struct hid_device_id egalax_devices[] = {
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
{ }
};
MODULE_DEVICE_TABLE(hid, egalax_devices);
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 6e31f305397d..79d0c61e7214 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -24,8 +24,7 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
- dev_info(&hdev->dev, "Fixing up Elecom BM084 "
- "report descriptor.\n");
+ hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n");
rdesc[47] = 0x00;
}
return rdesc;
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c
new file mode 100644
index 000000000000..81877c67caea
--- /dev/null
+++ b/drivers/hid/hid-emsff.c
@@ -0,0 +1,161 @@
+/*
+ * Force feedback support for EMS Trio Linker Plus II
+ *
+ * Copyright (c) 2010 Ignaz Forster <ignaz.forster@gmx.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/hid.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct emsff_device {
+ struct hid_report *report;
+};
+
+static int emsff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct emsff_device *emsff = data;
+ int weak, strong;
+
+ weak = effect->u.rumble.weak_magnitude;
+ strong = effect->u.rumble.strong_magnitude;
+
+ dbg_hid("called with 0x%04x 0x%04x\n", strong, weak);
+
+ weak = weak * 0xff / 0xffff;
+ strong = strong * 0xff / 0xffff;
+
+ emsff->report->field[0]->value[1] = weak;
+ emsff->report->field[0]->value[2] = strong;
+
+ dbg_hid("running with 0x%02x 0x%02x\n", strong, weak);
+ usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);
+
+ return 0;
+}
+
+static int emsff_init(struct hid_device *hid)
+{
+ struct emsff_device *emsff;
+ struct hid_report *report;
+ struct hid_input *hidinput = list_first_entry(&hid->inputs,
+ struct hid_input, list);
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (list_empty(report_list)) {
+ hid_err(hid, "no output reports found\n");
+ return -ENODEV;
+ }
+
+ report = list_first_entry(report_list, struct hid_report, list);
+ if (report->maxfield < 1) {
+ hid_err(hid, "no fields in the report\n");
+ return -ENODEV;
+ }
+
+ if (report->field[0]->report_count < 7) {
+ hid_err(hid, "not enough values in the field\n");
+ return -ENODEV;
+ }
+
+ emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL);
+ if (!emsff)
+ return -ENOMEM;
+
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, emsff, emsff_play);
+ if (error) {
+ kfree(emsff);
+ return error;
+ }
+
+ emsff->report = report;
+ emsff->report->field[0]->value[0] = 0x01;
+ emsff->report->field[0]->value[1] = 0x00;
+ emsff->report->field[0]->value[2] = 0x00;
+ emsff->report->field[0]->value[3] = 0x00;
+ emsff->report->field[0]->value[4] = 0x00;
+ emsff->report->field[0]->value[5] = 0x00;
+ emsff->report->field[0]->value[6] = 0x00;
+ usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);
+
+ hid_info(hid, "force feedback for EMS based devices by Ignaz Forster <ignaz.forster@gmx.de>\n");
+
+ return 0;
+}
+
+static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int ret;
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ goto err;
+ }
+
+ emsff_init(hdev);
+
+ return 0;
+err:
+ return ret;
+}
+
+static const struct hid_device_id ems_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_EMS, 0x118) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, ems_devices);
+
+static struct hid_driver ems_driver = {
+ .name = "hkems",
+ .id_table = ems_devices,
+ .probe = ems_probe,
+};
+
+static int ems_init(void)
+{
+ return hid_register_driver(&ems_driver);
+}
+
+static void ems_exit(void)
+{
+ hid_unregister_driver(&ems_driver);
+}
+
+module_init(ems_init);
+module_exit(ems_exit);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 88dfcf49a5d7..279ba530003c 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -87,7 +87,7 @@ static int gaff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output reports found\n");
+ hid_err(hid, "no output reports found\n");
return -ENODEV;
}
@@ -95,12 +95,12 @@ static int gaff_init(struct hid_device *hid)
report = list_entry(report_ptr, struct hid_report, list);
if (report->maxfield < 1) {
- dev_err(&hid->dev, "no fields in the report\n");
+ hid_err(hid, "no fields in the report\n");
return -ENODEV;
}
if (report->field[0]->report_count < 6) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ hid_err(hid, "not enough values in the field\n");
return -ENODEV;
}
@@ -128,8 +128,7 @@ static int gaff_init(struct hid_device *hid)
usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
- dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12"
- " devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n");
+ hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n");
return 0;
}
@@ -148,13 +147,13 @@ static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 3341baa86a30..b10a80c802e8 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -97,6 +97,12 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
@@ -156,6 +162,7 @@
#define USB_VENDOR_ID_CHICONY 0x04f2
#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
+#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
#define USB_VENDOR_ID_CIDC 0x1677
@@ -196,6 +203,9 @@
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4 0x726b
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
@@ -203,6 +213,9 @@
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
+#define USB_VENDOR_ID_EMS 0x2006
+#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
+
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
@@ -475,6 +488,7 @@
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
+#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index bb0b3659437b..e60fdb88101f 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -174,7 +174,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
clear_bit(*old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
- dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
+ dbg_hid("Assigned keycode %d to HID usage code %x\n",
usage->code, usage->hid);
/*
@@ -203,8 +203,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
*
* as seen in the HID specification v1.11 6.2.2.7 Global Items.
*
- * Only exponent 1 length units are processed. Centimeters are converted to
- * inches. Degrees are converted to radians.
+ * Only exponent 1 length units are processed. Centimeters and inches are
+ * converted to millimeters. Degrees are converted to radians.
*/
static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
{
@@ -225,13 +225,16 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
*/
if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
if (field->unit == 0x11) { /* If centimeters */
- /* Convert to inches */
- prev = logical_extents;
- logical_extents *= 254;
- if (logical_extents < prev)
+ /* Convert to millimeters */
+ unit_exponent += 1;
+ } else if (field->unit == 0x13) { /* If inches */
+ /* Convert to millimeters */
+ prev = physical_extents;
+ physical_extents *= 254;
+ if (physical_extents < prev)
return 0;
- unit_exponent += 2;
- } else if (field->unit != 0x13) { /* If not inches */
+ unit_exponent -= 1;
+ } else {
return 0;
}
} else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
@@ -316,21 +319,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
switch (field->application) {
case HID_GD_MOUSE:
- case HID_GD_POINTER: code += 0x110; break;
+ case HID_GD_POINTER: code += BTN_MOUSE; break;
case HID_GD_JOYSTICK:
if (code <= 0xf)
code += BTN_JOYSTICK;
else
code += BTN_TRIGGER_HAPPY;
break;
- case HID_GD_GAMEPAD: code += 0x130; break;
+ case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break;
default:
switch (field->physical) {
case HID_GD_MOUSE:
- case HID_GD_POINTER: code += 0x110; break;
- case HID_GD_JOYSTICK: code += 0x120; break;
- case HID_GD_GAMEPAD: code += 0x130; break;
- default: code += 0x100;
+ case HID_GD_POINTER: code += BTN_MOUSE; break;
+ case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break;
+ case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break;
+ default: code += BTN_MISC;
}
}
@@ -814,14 +817,14 @@ static int hidinput_open(struct input_dev *dev)
{
struct hid_device *hid = input_get_drvdata(dev);
- return hid->ll_driver->open(hid);
+ return hid_hw_open(hid);
}
static void hidinput_close(struct input_dev *dev)
{
struct hid_device *hid = input_get_drvdata(dev);
- hid->ll_driver->close(hid);
+ hid_hw_close(hid);
}
/*
@@ -868,7 +871,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
if (!hidinput || !input_dev) {
kfree(hidinput);
input_free_device(input_dev);
- err_hid("Out of memory during hid input probe");
+ hid_err(hid, "Out of memory during hid input probe\n");
goto out_unwind;
}
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index 817247ee006c..f2ba9efc3a53 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -32,8 +32,8 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
rdesc[73] == 0x95 && rdesc[74] == 0x01) {
- dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
- "descriptor\n");
+ hid_info(hdev,
+ "fixing up Kye/Genius Ergo Mouse report descriptor\n");
rdesc[62] = 0x09;
rdesc[64] = 0x04;
rdesc[66] = 0x07;
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index b629fba5a057..aef4104da141 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -53,23 +53,22 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
rdesc[84] == 0x8c && rdesc[85] == 0x02) {
- dev_info(&hdev->dev, "fixing up Logitech keyboard report "
- "descriptor\n");
+ hid_info(hdev,
+ "fixing up Logitech keyboard report descriptor\n");
rdesc[84] = rdesc[89] = 0x4d;
rdesc[85] = rdesc[90] = 0x10;
}
if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
rdesc[49] == 0x81 && rdesc[50] == 0x06) {
- dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
- "report descriptor\n");
+ hid_info(hdev,
+ "fixing up rel/abs in Logitech report descriptor\n");
rdesc[33] = rdesc[50] = 0x02;
}
if ((quirks & LG_FF4) && *rsize >= 101 &&
rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
rdesc[47] == 0x05 && rdesc[48] == 0x09) {
- dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless "
- "button descriptor\n");
+ hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n");
rdesc[41] = 0x05;
rdesc[42] = 0x09;
rdesc[47] = 0x95;
@@ -288,7 +287,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
@@ -297,7 +296,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_hw_start(hdev, connect_mask);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
index 4258253c36b3..3c31bc650e5d 100644
--- a/drivers/hid/hid-lg2ff.c
+++ b/drivers/hid/hid-lg2ff.c
@@ -72,18 +72,18 @@ int lg2ff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output report found\n");
+ hid_err(hid, "no output report found\n");
return -ENODEV;
}
report = list_entry(report_list->next, struct hid_report, list);
if (report->maxfield < 1) {
- dev_err(&hid->dev, "output report is empty\n");
+ hid_err(hid, "output report is empty\n");
return -ENODEV;
}
if (report->field[0]->report_count < 7) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ hid_err(hid, "not enough values in the field\n");
return -ENODEV;
}
@@ -110,8 +110,7 @@ int lg2ff_init(struct hid_device *hid)
usbhid_submit_report(hid, report, USB_DIR_OUT);
- dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by "
- "Anssi Hannula <anssi.hannula@gmail.com>\n");
+ hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <anssi.hannula@gmail.com>\n");
return 0;
}
diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c
index 4002832ee4af..f98644c26c1d 100644
--- a/drivers/hid/hid-lg3ff.c
+++ b/drivers/hid/hid-lg3ff.c
@@ -141,20 +141,20 @@ int lg3ff_init(struct hid_device *hid)
/* Find the report to use */
if (list_empty(report_list)) {
- err_hid("No output report found");
+ hid_err(hid, "No output report found\n");
return -1;
}
/* Check that the report looks ok */
report = list_entry(report_list->next, struct hid_report, list);
if (!report) {
- err_hid("NULL output report");
+ hid_err(hid, "NULL output report\n");
return -1;
}
field = report->field[0];
if (!field) {
- err_hid("NULL field");
+ hid_err(hid, "NULL field\n");
return -1;
}
@@ -169,8 +169,7 @@ int lg3ff_init(struct hid_device *hid)
if (test_bit(FF_AUTOCENTER, dev->ffbit))
dev->ff->set_autocenter = hid_lg3ff_set_autocenter;
- dev_info(&hid->dev, "Force feedback for Logitech Flight System G940 by "
- "Gary Stein <LordCnidarian@gmail.com>\n");
+ hid_info(hid, "Force feedback for Logitech Flight System G940 by Gary Stein <LordCnidarian@gmail.com>\n");
return 0;
}
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 7eef5a2ce948..fa550c8e1d1b 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -101,20 +101,20 @@ int lg4ff_init(struct hid_device *hid)
/* Find the report to use */
if (list_empty(report_list)) {
- err_hid("No output report found");
+ hid_err(hid, "No output report found\n");
return -1;
}
/* Check that the report looks ok */
report = list_entry(report_list->next, struct hid_report, list);
if (!report) {
- err_hid("NULL output report");
+ hid_err(hid, "NULL output report\n");
return -1;
}
field = report->field[0];
if (!field) {
- err_hid("NULL field");
+ hid_err(hid, "NULL field\n");
return -1;
}
@@ -129,8 +129,7 @@ int lg4ff_init(struct hid_device *hid)
if (test_bit(FF_AUTOCENTER, dev->ffbit))
dev->ff->set_autocenter = hid_lg4ff_set_autocenter;
- dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by "
- "Simon Wood <simon@mungewell.org>\n");
+ hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood <simon@mungewell.org>\n");
return 0;
}
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
index 61142b76a9b1..90d0ef2c92be 100644
--- a/drivers/hid/hid-lgff.c
+++ b/drivers/hid/hid-lgff.c
@@ -27,6 +27,8 @@
* e-mail - mail your message to <johann.deneux@it.uu.se>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/hid.h>
@@ -146,7 +148,7 @@ int lgff_init(struct hid_device* hid)
/* Find the report to use */
if (list_empty(report_list)) {
- err_hid("No output report found");
+ hid_err(hid, "No output report found\n");
return -1;
}
@@ -154,7 +156,7 @@ int lgff_init(struct hid_device* hid)
report = list_entry(report_list->next, struct hid_report, list);
field = report->field[0];
if (!field) {
- err_hid("NULL field");
+ hid_err(hid, "NULL field\n");
return -1;
}
@@ -176,7 +178,7 @@ int lgff_init(struct hid_device* hid)
if ( test_bit(FF_AUTOCENTER, dev->ffbit) )
dev->ff->set_autocenter = hid_lgff_set_autocenter;
- printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
+ pr_info("Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
return 0;
}
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index e6dc15171664..698e6459fd0b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -12,6 +12,8 @@
* any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
@@ -433,6 +435,11 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
if (!msc->input)
msc->input = hi->input;
+ /* Magic Trackpad does not give relative data after switching to MT */
+ if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+ field->flags & HID_MAIN_ITEM_RELATIVE)
+ return -1;
+
return 0;
}
@@ -446,7 +453,7 @@ static int magicmouse_probe(struct hid_device *hdev,
msc = kzalloc(sizeof(*msc), GFP_KERNEL);
if (msc == NULL) {
- dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n");
+ hid_err(hdev, "can't alloc magicmouse descriptor\n");
return -ENOMEM;
}
@@ -459,13 +466,13 @@ static int magicmouse_probe(struct hid_device *hdev,
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "magicmouse hid parse failed\n");
+ hid_err(hdev, "magicmouse hid parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "magicmouse hw start failed\n");
+ hid_err(hdev, "magicmouse hw start failed\n");
goto err_free;
}
@@ -486,7 +493,7 @@ static int magicmouse_probe(struct hid_device *hdev,
}
if (!report) {
- dev_err(&hdev->dev, "unable to register touch report\n");
+ hid_err(hdev, "unable to register touch report\n");
ret = -ENOMEM;
goto err_stop_hw;
}
@@ -495,8 +502,7 @@ static int magicmouse_probe(struct hid_device *hdev,
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
HID_FEATURE_REPORT);
if (ret != sizeof(feature)) {
- dev_err(&hdev->dev, "unable to request touch data (%d)\n",
- ret);
+ hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw;
}
@@ -540,7 +546,7 @@ static int __init magicmouse_init(void)
ret = hid_register_driver(&magicmouse_driver);
if (ret)
- printk(KERN_ERR "can't register magicmouse driver\n");
+ pr_err("can't register magicmouse driver\n");
return ret;
}
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index dc618c33d0a2..0f6fc54dc196 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -40,8 +40,7 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
rdesc[559] == 0x29) {
- dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
- "Model 1028 report descriptor\n");
+ hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
rdesc[557] = 0x35;
rdesc[559] = 0x45;
}
@@ -155,14 +154,14 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
HID_CONNECT_HIDINPUT_FORCE : 0));
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index c95c31e2d869..dedf757781ae 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -26,8 +26,7 @@ static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
- dev_info(&hdev->dev, "fixing up button/consumer in HID report "
- "descriptor\n");
+ hid_info(hdev, "fixing up button/consumer in HID report descriptor\n");
rdesc[30] = 0x0c;
}
return rdesc;
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c
index ac5421d568f1..9fb050ce6f04 100644
--- a/drivers/hid/hid-mosart.c
+++ b/drivers/hid/hid-mosart.c
@@ -90,6 +90,10 @@ static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case 0xff000000:
/* ignore HID features */
return -1;
+
+ case HID_UP_BUTTON:
+ /* ignore buttons */
+ return -1;
}
return 0;
@@ -199,7 +203,7 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL);
if (!td) {
- dev_err(&hdev->dev, "cannot allocate MosArt data\n");
+ hid_err(hdev, "cannot allocate MosArt data\n");
return -ENOMEM;
}
td->valid = false;
@@ -230,6 +234,19 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
+#ifdef CONFIG_PM
+static int mosart_reset_resume(struct hid_device *hdev)
+{
+ struct hid_report_enum *re = hdev->report_enum
+ + HID_FEATURE_REPORT;
+ struct hid_report *r = re->report_id_hash[7];
+
+ r->field[0]->value[0] = 0x02;
+ usbhid_submit_report(hdev, r, USB_DIR_OUT);
+ return 0;
+}
+#endif
+
static void mosart_remove(struct hid_device *hdev)
{
hid_hw_stop(hdev);
@@ -258,6 +275,9 @@ static struct hid_driver mosart_driver = {
.input_mapped = mosart_input_mapped,
.usage_table = mosart_grabbed_usages,
.event = mosart_event,
+#ifdef CONFIG_PM
+ .reset_resume = mosart_reset_resume,
+#endif
};
static int __init mosart_init(void)
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 69169efa1e16..beb403421e72 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -130,8 +130,7 @@ static void ntrig_report_version(struct hid_device *hdev)
if (ret == 8) {
ret = ntrig_version_string(&data[2], buf);
- dev_info(&hdev->dev,
- "Firmware version: %s (%02x%02x %02x%02x)\n",
+ hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n",
buf, data[2], data[3], data[4], data[5]);
}
@@ -831,7 +830,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
if (!nd) {
- dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
+ hid_err(hdev, "cannot allocate N-Trig data\n");
return -ENOMEM;
}
@@ -850,13 +849,13 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c
index 2e79716dca31..e90edfc63051 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -23,8 +23,7 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
- dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 "
- "report descriptor.\n");
+ hid_info(hdev, "Fixing up Ortek WKB-2000 report descriptor\n");
rdesc[55] = 0x92;
}
return rdesc;
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 308d6ae48a3e..f1ea3ff8a98d 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -29,8 +29,7 @@ static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
- dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report "
- "descriptor\n");
+ hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
rdesc[60] = 0xfa;
rdesc[40] = 0xfa;
}
@@ -77,13 +76,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index bc2e07740628..de9cf21b3494 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -253,7 +253,7 @@ static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int di
if (report->id == id)
return report;
}
- dev_warn(&hdev->dev, "No report with id 0x%x found\n", id);
+ hid_warn(hdev, "No report with id 0x%x found\n", id);
return NULL;
}
@@ -1329,7 +1329,7 @@ static int picolcd_check_version(struct hid_device *hdev)
verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
if (!verinfo) {
- dev_err(&hdev->dev, "no version response from PicoLCD");
+ hid_err(hdev, "no version response from PicoLCD\n");
return -ENODEV;
}
@@ -1337,14 +1337,14 @@ static int picolcd_check_version(struct hid_device *hdev)
data->version[0] = verinfo->raw_data[1];
data->version[1] = verinfo->raw_data[0];
if (data->status & PICOLCD_BOOTLOADER) {
- dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n",
- verinfo->raw_data[1], verinfo->raw_data[0]);
+ hid_info(hdev, "PicoLCD, bootloader version %d.%d\n",
+ verinfo->raw_data[1], verinfo->raw_data[0]);
} else {
- dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n",
- verinfo->raw_data[1], verinfo->raw_data[0]);
+ hid_info(hdev, "PicoLCD, firmware version %d.%d\n",
+ verinfo->raw_data[1], verinfo->raw_data[0]);
}
} else {
- dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n");
+ hid_err(hdev, "confused, got unexpected version response from PicoLCD\n");
ret = -EINVAL;
}
kfree(verinfo);
@@ -1544,7 +1544,7 @@ static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
/* prepare buffer with info about what we want to read (addr & len) */
raw_data[0] = *off & 0xff;
- raw_data[1] = (*off >> 8) && 0xff;
+ raw_data[1] = (*off >> 8) & 0xff;
raw_data[2] = s < 20 ? s : 20;
if (*off + raw_data[2] > 0xff)
raw_data[2] = 0x100 - *off;
@@ -1583,7 +1583,7 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
memset(raw_data, 0, sizeof(raw_data));
raw_data[0] = *off & 0xff;
- raw_data[1] = (*off >> 8) && 0xff;
+ raw_data[1] = (*off >> 8) & 0xff;
raw_data[2] = s < 20 ? s : 20;
if (*off + raw_data[2] > 0xff)
raw_data[2] = 0x100 - *off;
@@ -1867,6 +1867,7 @@ static void picolcd_debug_out_report(struct picolcd_data *data,
report->id, raw_size);
hid_debug_event(hdev, buff);
if (raw_size + 5 > sizeof(raw_data)) {
+ kfree(buff);
hid_debug_event(hdev, " TOO BIG\n");
return;
} else {
@@ -2328,8 +2329,7 @@ static void picolcd_init_devfs(struct picolcd_data *data,
(flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
hdev->debug_dir, data, &picolcd_debug_flash_fops);
} else if (flash_r || flash_w)
- dev_warn(&hdev->dev, "Unexpected FLASH access reports, "
- "please submit rdesc for review\n");
+ hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
}
static void picolcd_exit_devfs(struct picolcd_data *data)
@@ -2457,13 +2457,13 @@ static int picolcd_init_keys(struct picolcd_data *data,
return -ENODEV;
if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
report->field[0]->report_size != 8) {
- dev_err(&hdev->dev, "unsupported KEY_STATE report");
+ hid_err(hdev, "unsupported KEY_STATE report\n");
return -EINVAL;
}
idev = input_allocate_device();
if (idev == NULL) {
- dev_err(&hdev->dev, "failed to allocate input device");
+ hid_err(hdev, "failed to allocate input device\n");
return -ENOMEM;
}
input_set_drvdata(idev, hdev);
@@ -2485,7 +2485,7 @@ static int picolcd_init_keys(struct picolcd_data *data,
input_set_capability(idev, EV_KEY, data->keycode[i]);
error = input_register_device(idev);
if (error) {
- dev_err(&hdev->dev, "error registering the input device");
+ hid_err(hdev, "error registering the input device\n");
input_free_device(idev);
return error;
}
@@ -2522,9 +2522,8 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
return error;
if (data->version[0] != 0 && data->version[1] != 3)
- dev_info(&hdev->dev, "Device with untested firmware revision, "
- "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
- dev_name(&hdev->dev));
+ hid_info(hdev, "Device with untested firmware revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
+ dev_name(&hdev->dev));
/* Setup keypad input device */
error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
@@ -2581,9 +2580,8 @@ static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data
return error;
if (data->version[0] != 1 && data->version[1] != 0)
- dev_info(&hdev->dev, "Device with untested bootloader revision, "
- "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
- dev_name(&hdev->dev));
+ hid_info(hdev, "Device with untested bootloader revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
+ dev_name(&hdev->dev));
picolcd_init_devfs(data, NULL, NULL,
picolcd_out_report(REPORT_BL_READ_MEMORY, hdev),
@@ -2605,7 +2603,7 @@ static int picolcd_probe(struct hid_device *hdev,
*/
data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
if (data == NULL) {
- dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n");
+ hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n");
error = -ENOMEM;
goto err_no_cleanup;
}
@@ -2621,7 +2619,7 @@ static int picolcd_probe(struct hid_device *hdev,
/* Parse the device reports and start it up */
error = hid_parse(hdev);
if (error) {
- dev_err(&hdev->dev, "device report parse failed\n");
+ hid_err(hdev, "device report parse failed\n");
goto err_cleanup_data;
}
@@ -2631,25 +2629,25 @@ static int picolcd_probe(struct hid_device *hdev,
error = hid_hw_start(hdev, 0);
hdev->claimed = 0;
if (error) {
- dev_err(&hdev->dev, "hardware start failed\n");
+ hid_err(hdev, "hardware start failed\n");
goto err_cleanup_data;
}
- error = hdev->ll_driver->open(hdev);
+ error = hid_hw_open(hdev);
if (error) {
- dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n");
+ hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n");
goto err_cleanup_hid_hw;
}
error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay);
if (error) {
- dev_err(&hdev->dev, "failed to create sysfs attributes\n");
+ hid_err(hdev, "failed to create sysfs attributes\n");
goto err_cleanup_hid_ll;
}
error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
if (error) {
- dev_err(&hdev->dev, "failed to create sysfs attributes\n");
+ hid_err(hdev, "failed to create sysfs attributes\n");
goto err_cleanup_sysfs1;
}
@@ -2668,7 +2666,7 @@ err_cleanup_sysfs2:
err_cleanup_sysfs1:
device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
err_cleanup_hid_ll:
- hdev->ll_driver->close(hdev);
+ hid_hw_close(hdev);
err_cleanup_hid_hw:
hid_hw_stop(hdev);
err_cleanup_data:
@@ -2699,7 +2697,7 @@ static void picolcd_remove(struct hid_device *hdev)
picolcd_exit_devfs(data);
device_remove_file(&hdev->dev, &dev_attr_operation_mode);
device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
- hdev->ll_driver->close(hdev);
+ hid_hw_close(hdev);
hid_hw_stop(hdev);
hid_set_drvdata(hdev, NULL);
@@ -2753,7 +2751,7 @@ static void __exit picolcd_exit(void)
{
hid_unregister_driver(&picolcd_driver);
#ifdef CONFIG_HID_PICOLCD_FB
- flush_scheduled_work();
+ flush_work_sync(&picolcd_fb_cleanup);
WARN_ON(fb_pending);
#endif
}
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 9f41e2bd8483..06e5300d43d2 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -103,7 +103,7 @@ static int plff_init(struct hid_device *hid)
*/
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output reports found\n");
+ hid_err(hid, "no output reports found\n");
return -ENODEV;
}
@@ -112,14 +112,13 @@ static int plff_init(struct hid_device *hid)
report_ptr = report_ptr->next;
if (report_ptr == report_list) {
- dev_err(&hid->dev, "required output report is "
- "missing\n");
+ hid_err(hid, "required output report is missing\n");
return -ENODEV;
}
report = list_entry(report_ptr, struct hid_report, list);
if (report->maxfield < 1) {
- dev_err(&hid->dev, "no fields in the report\n");
+ hid_err(hid, "no fields in the report\n");
return -ENODEV;
}
@@ -137,7 +136,7 @@ static int plff_init(struct hid_device *hid)
weak = &report->field[3]->value[0];
debug("detected 4-field device");
} else {
- dev_err(&hid->dev, "not enough fields or values\n");
+ hid_err(hid, "not enough fields or values\n");
return -ENODEV;
}
@@ -164,8 +163,7 @@ static int plff_init(struct hid_device *hid)
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
}
- dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia "
- "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
+ hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
return 0;
}
@@ -185,13 +183,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 48eab84f53b5..ab19f2905d27 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -16,6 +16,8 @@
* any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/device.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -130,7 +132,7 @@ static ssize_t store_channel(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(channel, S_IRUGO | S_IWUGO, show_channel,
+static DEVICE_ATTR(channel, S_IRUGO | S_IWUSR | S_IWGRP , show_channel,
store_channel);
static struct device_attribute *sysfs_device_attr_channel = {
@@ -169,7 +171,7 @@ static ssize_t store_sustain(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(sustain, S_IRUGO | S_IWUGO, show_sustain,
+static DEVICE_ATTR(sustain, S_IRUGO | S_IWUSR | S_IWGRP, show_sustain,
store_sustain);
static struct device_attribute *sysfs_device_attr_sustain = {
@@ -207,7 +209,7 @@ static ssize_t store_octave(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(octave, S_IRUGO | S_IWUGO, show_octave,
+static DEVICE_ATTR(octave, S_IRUGO | S_IWUSR | S_IWGRP, show_octave,
store_octave);
static struct device_attribute *sysfs_device_attr_octave = {
@@ -285,11 +287,11 @@ static int pcmidi_get_output_report(struct pcmidi_snd *pm)
continue;
if (report->maxfield < 1) {
- dev_err(&hdev->dev, "output report is empty\n");
+ hid_err(hdev, "output report is empty\n");
break;
}
if (report->field[0]->report_count != 2) {
- dev_err(&hdev->dev, "field count too low\n");
+ hid_err(hdev, "field count too low\n");
break;
}
pm->pcmidi_report6 = report;
@@ -746,8 +748,8 @@ static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if (*rsize == 178 &&
rdesc[111] == 0x06 && rdesc[112] == 0x00 &&
rdesc[113] == 0xff) {
- dev_info(&hdev->dev, "fixing up pc-midi keyboard report "
- "descriptor\n");
+ hid_info(hdev,
+ "fixing up pc-midi keyboard report descriptor\n");
rdesc[144] = 0x18; /* report 4: was 0x10 report count */
}
@@ -805,7 +807,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
if (pk == NULL) {
- dev_err(&hdev->dev, "prodikeys: can't alloc descriptor\n");
+ hid_err(hdev, "can't alloc descriptor\n");
return -ENOMEM;
}
@@ -813,8 +815,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
pm = kzalloc(sizeof(*pm), GFP_KERNEL);
if (pm == NULL) {
- dev_err(&hdev->dev,
- "prodikeys: can't alloc descriptor\n");
+ hid_err(hdev, "can't alloc descriptor\n");
ret = -ENOMEM;
goto err_free;
}
@@ -827,7 +828,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "prodikeys: hid parse failed\n");
+ hid_err(hdev, "hid parse failed\n");
goto err_free;
}
@@ -837,7 +838,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "prodikeys: hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
@@ -896,7 +897,7 @@ static int pk_init(void)
ret = hid_register_driver(&pk_driver);
if (ret)
- printk(KERN_ERR "can't register prodikeys driver\n");
+ pr_err("can't register prodikeys driver\n");
return ret;
}
diff --git a/drivers/hid/hid-quanta.c b/drivers/hid/hid-quanta.c
index 54d3db50605b..87a54df4d4ac 100644
--- a/drivers/hid/hid-quanta.c
+++ b/drivers/hid/hid-quanta.c
@@ -195,7 +195,7 @@ static int quanta_probe(struct hid_device *hdev, const struct hid_device_id *id)
td = kmalloc(sizeof(struct quanta_data), GFP_KERNEL);
if (!td) {
- dev_err(&hdev->dev, "cannot allocate Quanta Touch data\n");
+ hid_err(hdev, "cannot allocate Quanta Touch data\n");
return -ENOMEM;
}
td->valid = false;
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index f77695762cb5..cbd8cc42e75a 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -35,6 +35,11 @@
#include "hid-roccat.h"
#include "hid-roccat-kone.h"
+static uint profile_numbers[5] = {0, 1, 2, 3, 4};
+
+/* kone_class is used for creating sysfs attributes via roccat char device */
+static struct class *kone_class;
+
static void kone_set_settings_checksum(struct kone_settings *settings)
{
uint16_t checksum = 0;
@@ -90,8 +95,7 @@ static int kone_check_write(struct usb_device *usb_dev)
kfree(data);
return 0;
} else { /* unknown answer */
- dev_err(&usb_dev->dev, "got retval %d when checking write\n",
- *data);
+ hid_err(usb_dev, "got retval %d when checking write\n", *data);
kfree(data);
return -EIO;
}
@@ -262,7 +266,8 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count) {
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct kone_settings))
@@ -286,7 +291,8 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count) {
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0, difference;
@@ -319,10 +325,11 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
return sizeof(struct kone_settings);
}
-static ssize_t kone_sysfs_read_profilex(struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count, int number) {
- struct device *dev = container_of(kobj, struct device, kobj);
+static ssize_t kone_sysfs_read_profilex(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count) {
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct kone_profile))
@@ -332,47 +339,18 @@ static ssize_t kone_sysfs_read_profilex(struct kobject *kobj,
count = sizeof(struct kone_profile) - off;
mutex_lock(&kone->kone_lock);
- memcpy(buf, ((char const *)&kone->profiles[number - 1]) + off, count);
+ memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
mutex_unlock(&kone->kone_lock);
return count;
}
-static ssize_t kone_sysfs_read_profile1(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 1);
-}
-
-static ssize_t kone_sysfs_read_profile2(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 2);
-}
-
-static ssize_t kone_sysfs_read_profile3(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 3);
-}
-
-static ssize_t kone_sysfs_read_profile4(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 4);
-}
-
-static ssize_t kone_sysfs_read_profile5(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 5);
-}
-
/* Writes data only if different to stored data */
-static ssize_t kone_sysfs_write_profilex(struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count, int number) {
- struct device *dev = container_of(kobj, struct device, kobj);
+static ssize_t kone_sysfs_write_profilex(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count) {
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
struct kone_profile *profile;
@@ -382,13 +360,14 @@ static ssize_t kone_sysfs_write_profilex(struct kobject *kobj,
if (off != 0 || count != sizeof(struct kone_profile))
return -EINVAL;
- profile = &kone->profiles[number - 1];
+ profile = &kone->profiles[*(uint *)(attr->private)];
mutex_lock(&kone->kone_lock);
difference = memcmp(buf, profile, sizeof(struct kone_profile));
if (difference) {
retval = kone_set_profile(usb_dev,
- (struct kone_profile const *)buf, number);
+ (struct kone_profile const *)buf,
+ *(uint *)(attr->private) + 1);
if (!retval)
memcpy(profile, buf, sizeof(struct kone_profile));
}
@@ -400,47 +379,19 @@ static ssize_t kone_sysfs_write_profilex(struct kobject *kobj,
return sizeof(struct kone_profile);
}
-static ssize_t kone_sysfs_write_profile1(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 1);
-}
-
-static ssize_t kone_sysfs_write_profile2(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 2);
-}
-
-static ssize_t kone_sysfs_write_profile3(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 3);
-}
-
-static ssize_t kone_sysfs_write_profile4(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 4);
-}
-
-static ssize_t kone_sysfs_write_profile5(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 5);
-}
-
static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
+ struct kone_device *kone =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
}
static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
+ struct kone_device *kone =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
}
@@ -448,11 +399,15 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
static ssize_t kone_sysfs_show_weight(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ struct kone_device *kone;
+ struct usb_device *usb_dev;
int weight = 0;
int retval;
+ dev = dev->parent->parent;
+ kone = hid_get_drvdata(dev_get_drvdata(dev));
+ usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
mutex_lock(&kone->kone_lock);
retval = kone_get_weight(usb_dev, &weight);
mutex_unlock(&kone->kone_lock);
@@ -465,14 +420,16 @@ static ssize_t kone_sysfs_show_weight(struct device *dev,
static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
+ struct kone_device *kone =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
}
static ssize_t kone_sysfs_show_tcu(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
+ struct kone_device *kone =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
}
@@ -504,11 +461,15 @@ static int kone_tcu_command(struct usb_device *usb_dev, int number)
static ssize_t kone_sysfs_set_tcu(struct device *dev,
struct device_attribute *attr, char const *buf, size_t size)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ struct kone_device *kone;
+ struct usb_device *usb_dev;
int retval;
unsigned long state;
+ dev = dev->parent->parent;
+ kone = hid_get_drvdata(dev_get_drvdata(dev));
+ usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
retval = strict_strtoul(buf, 10, &state);
if (retval)
return retval;
@@ -556,7 +517,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev,
retval = kone_set_settings(usb_dev, &kone->settings);
if (retval) {
- dev_err(&usb_dev->dev, "couldn't set tcu state\n");
+ hid_err(usb_dev, "couldn't set tcu state\n");
/*
* try to reread valid settings into buffer overwriting
* first error code
@@ -570,7 +531,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev,
retval = size;
exit_no_settings:
- dev_err(&usb_dev->dev, "couldn't read settings\n");
+ hid_err(usb_dev, "couldn't read settings\n");
exit_unlock:
mutex_unlock(&kone->kone_lock);
return retval;
@@ -579,18 +540,23 @@ exit_unlock:
static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
+ struct kone_device *kone =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
}
static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
struct device_attribute *attr, char const *buf, size_t size)
{
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ struct kone_device *kone;
+ struct usb_device *usb_dev;
int retval;
unsigned long new_startup_profile;
+ dev = dev->parent->parent;
+ kone = hid_get_drvdata(dev_get_drvdata(dev));
+ usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
retval = strict_strtoul(buf, 10, &new_startup_profile);
if (retval)
return retval;
@@ -617,160 +583,92 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
return size;
}
-/*
- * Read actual dpi settings.
- * Returns raw value for further processing. Refer to enum kone_polling_rates to
- * get real value.
- */
-static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
-
-static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
-
-/*
- * The mouse can be equipped with one of four supplied weights from 5 to 20
- * grams which are recognized and its value can be read out.
- * This returns the raw value reported by the mouse for easy evaluation by
- * software. Refer to enum kone_weights to get corresponding real weight.
- */
-static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
-
-/*
- * Prints firmware version stored in mouse as integer.
- * The raw value reported by the mouse is returned for easy evaluation, to get
- * the real version number the decimal point has to be shifted 2 positions to
- * the left. E.g. a value of 138 means 1.38.
- */
-static DEVICE_ATTR(firmware_version, 0440,
- kone_sysfs_show_firmware_version, NULL);
-
-/*
- * Prints state of Tracking Control Unit as number where 0 = off and 1 = on
- * Writing 0 deactivates tcu and writing 1 calibrates and activates the tcu
- */
-static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
-
-/* Prints and takes the number of the profile the mouse starts with */
-static DEVICE_ATTR(startup_profile, 0660,
- kone_sysfs_show_startup_profile,
- kone_sysfs_set_startup_profile);
-
-static struct attribute *kone_attributes[] = {
- &dev_attr_actual_dpi.attr,
- &dev_attr_actual_profile.attr,
- &dev_attr_weight.attr,
- &dev_attr_firmware_version.attr,
- &dev_attr_tcu.attr,
- &dev_attr_startup_profile.attr,
- NULL
-};
-
-static struct attribute_group kone_attribute_group = {
- .attrs = kone_attributes
-};
-
-static struct bin_attribute kone_settings_attr = {
- .attr = { .name = "settings", .mode = 0660 },
- .size = sizeof(struct kone_settings),
- .read = kone_sysfs_read_settings,
- .write = kone_sysfs_write_settings
-};
+static struct device_attribute kone_attributes[] = {
+ /*
+ * Read actual dpi settings.
+ * Returns raw value for further processing. Refer to enum
+ * kone_polling_rates to get real value.
+ */
+ __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL),
+ __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL),
-static struct bin_attribute kone_profile1_attr = {
- .attr = { .name = "profile1", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profile1,
- .write = kone_sysfs_write_profile1
-};
+ /*
+ * The mouse can be equipped with one of four supplied weights from 5
+ * to 20 grams which are recognized and its value can be read out.
+ * This returns the raw value reported by the mouse for easy evaluation
+ * by software. Refer to enum kone_weights to get corresponding real
+ * weight.
+ */
+ __ATTR(weight, 0440, kone_sysfs_show_weight, NULL),
-static struct bin_attribute kone_profile2_attr = {
- .attr = { .name = "profile2", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profile2,
- .write = kone_sysfs_write_profile2
-};
+ /*
+ * Prints firmware version stored in mouse as integer.
+ * The raw value reported by the mouse is returned for easy evaluation,
+ * to get the real version number the decimal point has to be shifted 2
+ * positions to the left. E.g. a value of 138 means 1.38.
+ */
+ __ATTR(firmware_version, 0440,
+ kone_sysfs_show_firmware_version, NULL),
-static struct bin_attribute kone_profile3_attr = {
- .attr = { .name = "profile3", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profile3,
- .write = kone_sysfs_write_profile3
-};
+ /*
+ * Prints state of Tracking Control Unit as number where 0 = off and
+ * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
+ * activates the tcu
+ */
+ __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu),
-static struct bin_attribute kone_profile4_attr = {
- .attr = { .name = "profile4", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profile4,
- .write = kone_sysfs_write_profile4
+ /* Prints and takes the number of the profile the mouse starts with */
+ __ATTR(startup_profile, 0660,
+ kone_sysfs_show_startup_profile,
+ kone_sysfs_set_startup_profile),
+ __ATTR_NULL
};
-static struct bin_attribute kone_profile5_attr = {
- .attr = { .name = "profile5", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profile5,
- .write = kone_sysfs_write_profile5
+static struct bin_attribute kone_bin_attributes[] = {
+ {
+ .attr = { .name = "settings", .mode = 0660 },
+ .size = sizeof(struct kone_settings),
+ .read = kone_sysfs_read_settings,
+ .write = kone_sysfs_write_settings
+ },
+ {
+ .attr = { .name = "profile1", .mode = 0660 },
+ .size = sizeof(struct kone_profile),
+ .read = kone_sysfs_read_profilex,
+ .write = kone_sysfs_write_profilex,
+ .private = &profile_numbers[0]
+ },
+ {
+ .attr = { .name = "profile2", .mode = 0660 },
+ .size = sizeof(struct kone_profile),
+ .read = kone_sysfs_read_profilex,
+ .write = kone_sysfs_write_profilex,
+ .private = &profile_numbers[1]
+ },
+ {
+ .attr = { .name = "profile3", .mode = 0660 },
+ .size = sizeof(struct kone_profile),
+ .read = kone_sysfs_read_profilex,
+ .write = kone_sysfs_write_profilex,
+ .private = &profile_numbers[2]
+ },
+ {
+ .attr = { .name = "profile4", .mode = 0660 },
+ .size = sizeof(struct kone_profile),
+ .read = kone_sysfs_read_profilex,
+ .write = kone_sysfs_write_profilex,
+ .private = &profile_numbers[3]
+ },
+ {
+ .attr = { .name = "profile5", .mode = 0660 },
+ .size = sizeof(struct kone_profile),
+ .read = kone_sysfs_read_profilex,
+ .write = kone_sysfs_write_profilex,
+ .private = &profile_numbers[4]
+ },
+ __ATTR_NULL
};
-static int kone_create_sysfs_attributes(struct usb_interface *intf)
-{
- int retval;
-
- retval = sysfs_create_group(&intf->dev.kobj, &kone_attribute_group);
- if (retval)
- goto exit_1;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_settings_attr);
- if (retval)
- goto exit_2;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile1_attr);
- if (retval)
- goto exit_3;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile2_attr);
- if (retval)
- goto exit_4;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile3_attr);
- if (retval)
- goto exit_5;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile4_attr);
- if (retval)
- goto exit_6;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile5_attr);
- if (retval)
- goto exit_7;
-
- return 0;
-
-exit_7:
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr);
-exit_6:
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr);
-exit_5:
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr);
-exit_4:
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr);
-exit_3:
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr);
-exit_2:
- sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group);
-exit_1:
- return retval;
-}
-
-static void kone_remove_sysfs_attributes(struct usb_interface *intf)
-{
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile5_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr);
- sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group);
-}
-
static int kone_init_kone_device_struct(struct usb_device *usb_dev,
struct kone_device *kone)
{
@@ -818,32 +716,25 @@ static int kone_init_specials(struct hid_device *hdev)
kone = kzalloc(sizeof(*kone), GFP_KERNEL);
if (!kone) {
- dev_err(&hdev->dev, "can't alloc device descriptor\n");
+ hid_err(hdev, "can't alloc device descriptor\n");
return -ENOMEM;
}
hid_set_drvdata(hdev, kone);
retval = kone_init_kone_device_struct(usb_dev, kone);
if (retval) {
- dev_err(&hdev->dev,
- "couldn't init struct kone_device\n");
+ hid_err(hdev, "couldn't init struct kone_device\n");
goto exit_free;
}
- retval = roccat_connect(hdev);
+ retval = roccat_connect(kone_class, hdev);
if (retval < 0) {
- dev_err(&hdev->dev, "couldn't init char dev\n");
+ hid_err(hdev, "couldn't init char dev\n");
/* be tolerant about not getting chrdev */
} else {
kone->roccat_claimed = 1;
kone->chrdev_minor = retval;
}
-
- retval = kone_create_sysfs_attributes(intf);
- if (retval) {
- dev_err(&hdev->dev, "cannot create sysfs files\n");
- goto exit_free;
- }
} else {
hid_set_drvdata(hdev, NULL);
}
@@ -854,7 +745,6 @@ exit_free:
return retval;
}
-
static void kone_remove_specials(struct hid_device *hdev)
{
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
@@ -862,7 +752,6 @@ static void kone_remove_specials(struct hid_device *hdev)
if (intf->cur_altsetting->desc.bInterfaceProtocol
== USB_INTERFACE_PROTOCOL_MOUSE) {
- kone_remove_sysfs_attributes(intf);
kone = hid_get_drvdata(hdev);
if (kone->roccat_claimed)
roccat_disconnect(kone->chrdev_minor);
@@ -876,19 +765,19 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
retval = hid_parse(hdev);
if (retval) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto exit;
}
retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (retval) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto exit;
}
retval = kone_init_specials(hdev);
if (retval) {
- dev_err(&hdev->dev, "couldn't install mouse\n");
+ hid_err(hdev, "couldn't install mouse\n");
goto exit_stop;
}
@@ -1006,11 +895,24 @@ static struct hid_driver kone_driver = {
static int __init kone_init(void)
{
- return hid_register_driver(&kone_driver);
+ int retval;
+
+ /* class name has to be same as driver name */
+ kone_class = class_create(THIS_MODULE, "kone");
+ if (IS_ERR(kone_class))
+ return PTR_ERR(kone_class);
+ kone_class->dev_attrs = kone_attributes;
+ kone_class->dev_bin_attrs = kone_bin_attributes;
+
+ retval = hid_register_driver(&kone_driver);
+ if (retval)
+ class_destroy(kone_class);
+ return retval;
}
static void __exit kone_exit(void)
{
+ class_destroy(kone_class);
hid_unregister_driver(&kone_driver);
}
diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h
index 130d6566ea82..64abb5b8a59a 100644
--- a/drivers/hid/hid-roccat-kone.h
+++ b/drivers/hid/hid-roccat-kone.h
@@ -14,14 +14,11 @@
#include <linux/types.h>
-#pragma pack(push)
-#pragma pack(1)
-
struct kone_keystroke {
uint8_t key;
uint8_t action;
uint16_t period; /* in milliseconds */
-};
+} __attribute__ ((__packed__));
enum kone_keystroke_buttons {
kone_keystroke_button_1 = 0xf0, /* left mouse button */
@@ -44,7 +41,7 @@ struct kone_button_info {
uint8_t macro_name[16]; /* can be max 15 chars long */
uint8_t count;
struct kone_keystroke keystrokes[20];
-};
+} __attribute__ ((__packed__));
enum kone_button_info_types {
/* valid button types until firmware 1.32 */
@@ -95,7 +92,7 @@ struct kone_light_info {
uint8_t red; /* range 0x00-0xff */
uint8_t green; /* range 0x00-0xff */
uint8_t blue; /* range 0x00-0xff */
-};
+} __attribute__ ((__packed__));
struct kone_profile {
uint16_t size; /* always 975 */
@@ -130,7 +127,7 @@ struct kone_profile {
struct kone_button_info button_infos[8];
uint16_t checksum; /* \brief holds checksum of struct */
-};
+} __attribute__ ((__packed__));
enum kone_polling_rates {
kone_polling_rate_125 = 1,
@@ -147,7 +144,7 @@ struct kone_settings {
uint8_t calibration_data[4];
uint8_t unknown3[2];
uint16_t checksum;
-};
+} __attribute__ ((__packed__));
/*
* 12 byte mouse event read by interrupt_read
@@ -163,7 +160,7 @@ struct kone_mouse_event {
uint8_t event;
uint8_t value; /* press = 0, release = 1 */
uint8_t macro_key; /* 0 to 8 */
-};
+} __attribute__ ((__packed__));
enum kone_mouse_events {
/* osd events are thought to be display on screen */
@@ -191,9 +188,7 @@ struct kone_roccat_report {
uint8_t event;
uint8_t value; /* holds dpi or profile value */
uint8_t key; /* macro key on overlong macro execution */
-};
-
-#pragma pack(pop)
+} __attribute__ ((__packed__));
struct kone_device {
/*
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
new file mode 100644
index 000000000000..1608c8d1efd6
--- /dev/null
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -0,0 +1,837 @@
+/*
+ * Roccat Kone[+] driver for Linux
+ *
+ * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.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.
+ */
+
+/*
+ * Roccat Kone[+] is an updated/improved version of the Kone with more memory
+ * and functionality and without the non-standard behaviours the Kone had.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/usb.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "hid-ids.h"
+#include "hid-roccat.h"
+#include "hid-roccat-koneplus.h"
+
+static uint profile_numbers[5] = {0, 1, 2, 3, 4};
+
+static struct class *koneplus_class;
+
+static void koneplus_profile_activated(struct koneplus_device *koneplus,
+ uint new_profile)
+{
+ koneplus->actual_profile = new_profile;
+}
+
+static int koneplus_send_control(struct usb_device *usb_dev, uint value,
+ enum koneplus_control_requests request)
+{
+ int len;
+ struct koneplus_control *control;
+
+ if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
+ request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
+ value > 4)
+ return -EINVAL;
+
+ control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL);
+ if (!control)
+ return -ENOMEM;
+
+ control->command = KONEPLUS_COMMAND_CONTROL;
+ control->value = value;
+ control->request = request;
+
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ KONEPLUS_USB_COMMAND_CONTROL, 0, control,
+ sizeof(struct koneplus_control),
+ USB_CTRL_SET_TIMEOUT);
+
+ kfree(control);
+
+ if (len != sizeof(struct koneplus_control))
+ return len;
+
+ return 0;
+}
+
+static int koneplus_receive(struct usb_device *usb_dev, uint usb_command,
+ void *buf, uint size) {
+ int len;
+
+ len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
+
+ return (len != size) ? -EIO : 0;
+}
+
+static int koneplus_receive_control_status(struct usb_device *usb_dev)
+{
+ int retval;
+ struct koneplus_control *control;
+
+ control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL);
+ if (!control)
+ return -ENOMEM;
+
+ do {
+ retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
+ control, sizeof(struct koneplus_control));
+
+ /* check if we get a completely wrong answer */
+ if (retval)
+ goto out;
+
+ if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) {
+ retval = 0;
+ goto out;
+ }
+
+ /* indicates that hardware needs some more time to complete action */
+ if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
+ msleep(500); /* windows driver uses 1000 */
+ continue;
+ }
+
+ /* seems to be critical - replug necessary */
+ if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ dev_err(&usb_dev->dev, "koneplus_receive_control_status: "
+ "unknown response value 0x%x\n", control->value);
+ retval = -EINVAL;
+ goto out;
+
+ } while (1);
+out:
+ kfree(control);
+ return retval;
+}
+
+static int koneplus_send(struct usb_device *usb_dev, uint command,
+ void *buf, uint size) {
+ int len;
+
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
+
+ if (len != size)
+ return -EIO;
+
+ if (koneplus_receive_control_status(usb_dev))
+ return -EIO;
+
+ return 0;
+}
+
+static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
+ enum koneplus_control_requests request)
+{
+ int retval;
+
+ retval = koneplus_send_control(usb_dev, number, request);
+ if (retval)
+ return retval;
+
+ /* allow time to settle things - windows driver uses 500 */
+ msleep(100);
+
+ retval = koneplus_receive_control_status(usb_dev);
+ if (retval)
+ return retval;
+
+ return 0;
+}
+
+static int koneplus_get_info(struct usb_device *usb_dev,
+ struct koneplus_info *buf)
+{
+ return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO,
+ buf, sizeof(struct koneplus_info));
+}
+
+static int koneplus_get_profile_settings(struct usb_device *usb_dev,
+ struct koneplus_profile_settings *buf, uint number)
+{
+ int retval;
+
+ retval = koneplus_select_profile(usb_dev, number,
+ KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
+ if (retval)
+ return retval;
+
+ return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
+ buf, sizeof(struct koneplus_profile_settings));
+}
+
+static int koneplus_set_profile_settings(struct usb_device *usb_dev,
+ struct koneplus_profile_settings const *settings)
+{
+ return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
+ (void *)settings, sizeof(struct koneplus_profile_settings));
+}
+
+static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
+ struct koneplus_profile_buttons *buf, int number)
+{
+ int retval;
+
+ retval = koneplus_select_profile(usb_dev, number,
+ KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
+ if (retval)
+ return retval;
+
+ return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
+ buf, sizeof(struct koneplus_profile_buttons));
+}
+
+static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
+ struct koneplus_profile_buttons const *buttons)
+{
+ return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
+ (void *)buttons, sizeof(struct koneplus_profile_buttons));
+}
+
+/* retval is 0-4 on success, < 0 on error */
+static int koneplus_get_startup_profile(struct usb_device *usb_dev)
+{
+ struct koneplus_startup_profile *buf;
+ int retval;
+
+ buf = kmalloc(sizeof(struct koneplus_startup_profile), GFP_KERNEL);
+
+ retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
+ buf, sizeof(struct koneplus_startup_profile));
+
+ if (retval)
+ goto out;
+
+ retval = buf->startup_profile;
+out:
+ kfree(buf);
+ return retval;
+}
+
+static int koneplus_set_startup_profile(struct usb_device *usb_dev,
+ int startup_profile)
+{
+ struct koneplus_startup_profile buf;
+
+ buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE;
+ buf.size = sizeof(struct koneplus_startup_profile);
+ buf.startup_profile = startup_profile;
+
+ return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
+ (char *)&buf, sizeof(struct koneplus_profile_buttons));
+}
+
+static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
+ char *buf, loff_t off, size_t count,
+ size_t real_size, uint command)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval;
+
+ if (off != 0 || count != real_size)
+ return -EINVAL;
+
+ mutex_lock(&koneplus->koneplus_lock);
+ retval = koneplus_receive(usb_dev, command, buf, real_size);
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ if (retval)
+ return retval;
+
+ return real_size;
+}
+
+static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
+ void const *buf, loff_t off, size_t count,
+ size_t real_size, uint command)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval;
+
+ if (off != 0 || count != real_size)
+ return -EINVAL;
+
+ mutex_lock(&koneplus->koneplus_lock);
+ retval = koneplus_send(usb_dev, command, (void *)buf, real_size);
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ if (retval)
+ return retval;
+
+ return real_size;
+}
+
+static ssize_t koneplus_sysfs_write_macro(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return koneplus_sysfs_write(fp, kobj, buf, off, count,
+ sizeof(struct koneplus_macro), KONEPLUS_USB_COMMAND_MACRO);
+}
+
+static ssize_t koneplus_sysfs_read_sensor(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return koneplus_sysfs_read(fp, kobj, buf, off, count,
+ sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR);
+}
+
+static ssize_t koneplus_sysfs_write_sensor(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return koneplus_sysfs_write(fp, kobj, buf, off, count,
+ sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR);
+}
+
+static ssize_t koneplus_sysfs_write_tcu(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return koneplus_sysfs_write(fp, kobj, buf, off, count,
+ sizeof(struct koneplus_tcu), KONEPLUS_USB_COMMAND_TCU);
+}
+
+static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return koneplus_sysfs_read(fp, kobj, buf, off, count,
+ sizeof(struct koneplus_tcu_image), KONEPLUS_USB_COMMAND_TCU);
+}
+
+static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+
+ if (off >= sizeof(struct koneplus_profile_settings))
+ return 0;
+
+ if (off + count > sizeof(struct koneplus_profile_settings))
+ count = sizeof(struct koneplus_profile_settings) - off;
+
+ mutex_lock(&koneplus->koneplus_lock);
+ memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
+ count);
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ return count;
+}
+
+static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval = 0;
+ int difference;
+ int profile_number;
+ struct koneplus_profile_settings *profile_settings;
+
+ if (off != 0 || count != sizeof(struct koneplus_profile_settings))
+ return -EINVAL;
+
+ profile_number = ((struct koneplus_profile_settings const *)buf)->number;
+ profile_settings = &koneplus->profile_settings[profile_number];
+
+ mutex_lock(&koneplus->koneplus_lock);
+ difference = memcmp(buf, profile_settings,
+ sizeof(struct koneplus_profile_settings));
+ if (difference) {
+ retval = koneplus_set_profile_settings(usb_dev,
+ (struct koneplus_profile_settings const *)buf);
+ if (!retval)
+ memcpy(profile_settings, buf,
+ sizeof(struct koneplus_profile_settings));
+ }
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ if (retval)
+ return retval;
+
+ return sizeof(struct koneplus_profile_settings);
+}
+
+static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+
+ if (off >= sizeof(struct koneplus_profile_buttons))
+ return 0;
+
+ if (off + count > sizeof(struct koneplus_profile_buttons))
+ count = sizeof(struct koneplus_profile_buttons) - off;
+
+ mutex_lock(&koneplus->koneplus_lock);
+ memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
+ count);
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ return count;
+}
+
+static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
+ struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval = 0;
+ int difference;
+ uint profile_number;
+ struct koneplus_profile_buttons *profile_buttons;
+
+ if (off != 0 || count != sizeof(struct koneplus_profile_buttons))
+ return -EINVAL;
+
+ profile_number = ((struct koneplus_profile_buttons const *)buf)->number;
+ profile_buttons = &koneplus->profile_buttons[profile_number];
+
+ mutex_lock(&koneplus->koneplus_lock);
+ difference = memcmp(buf, profile_buttons,
+ sizeof(struct koneplus_profile_buttons));
+ if (difference) {
+ retval = koneplus_set_profile_buttons(usb_dev,
+ (struct koneplus_profile_buttons const *)buf);
+ if (!retval)
+ memcpy(profile_buttons, buf,
+ sizeof(struct koneplus_profile_buttons));
+ }
+ mutex_unlock(&koneplus->koneplus_lock);
+
+ if (retval)
+ return retval;
+
+ return sizeof(struct koneplus_profile_buttons);
+}
+
+static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct koneplus_device *koneplus =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
+ return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile);
+}
+
+static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev,
+ struct device_attribute *attr, char const *buf, size_t size)
+{
+ struct koneplus_device *koneplus;
+ struct usb_device *usb_dev;
+ unsigned long profile;
+ int retval;
+
+ dev = dev->parent->parent;
+ koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+ usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
+ retval = strict_strtoul(buf, 10, &profile);
+ if (retval)
+ return retval;
+
+ mutex_lock(&koneplus->koneplus_lock);
+ retval = koneplus_set_startup_profile(usb_dev, profile);
+ mutex_unlock(&koneplus->koneplus_lock);
+ if (retval)
+ return retval;
+
+ return size;
+}
+
+static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct koneplus_device *koneplus =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
+ return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile);
+}
+
+static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct koneplus_device *koneplus =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
+ return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version);
+}
+
+static struct device_attribute koneplus_attributes[] = {
+ __ATTR(startup_profile, 0660,
+ koneplus_sysfs_show_startup_profile,
+ koneplus_sysfs_set_startup_profile),
+ __ATTR(actual_profile, 0440,
+ koneplus_sysfs_show_actual_profile, NULL),
+ __ATTR(firmware_version, 0440,
+ koneplus_sysfs_show_firmware_version, NULL),
+ __ATTR_NULL
+};
+
+static struct bin_attribute koneplus_bin_attributes[] = {
+ {
+ .attr = { .name = "sensor", .mode = 0220 },
+ .size = sizeof(struct koneplus_sensor),
+ .read = koneplus_sysfs_read_sensor,
+ .write = koneplus_sysfs_write_sensor
+ },
+ {
+ .attr = { .name = "tcu", .mode = 0220 },
+ .size = sizeof(struct koneplus_tcu),
+ .write = koneplus_sysfs_write_tcu
+ },
+ {
+ .attr = { .name = "tcu_image", .mode = 0440 },
+ .size = sizeof(struct koneplus_tcu_image),
+ .read = koneplus_sysfs_read_tcu_image
+ },
+ {
+ .attr = { .name = "profile_settings", .mode = 0220 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .write = koneplus_sysfs_write_profile_settings
+ },
+ {
+ .attr = { .name = "profile1_settings", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .read = koneplus_sysfs_read_profilex_settings,
+ .private = &profile_numbers[0]
+ },
+ {
+ .attr = { .name = "profile2_settings", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .read = koneplus_sysfs_read_profilex_settings,
+ .private = &profile_numbers[1]
+ },
+ {
+ .attr = { .name = "profile3_settings", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .read = koneplus_sysfs_read_profilex_settings,
+ .private = &profile_numbers[2]
+ },
+ {
+ .attr = { .name = "profile4_settings", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .read = koneplus_sysfs_read_profilex_settings,
+ .private = &profile_numbers[3]
+ },
+ {
+ .attr = { .name = "profile5_settings", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_settings),
+ .read = koneplus_sysfs_read_profilex_settings,
+ .private = &profile_numbers[4]
+ },
+ {
+ .attr = { .name = "profile_buttons", .mode = 0220 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .write = koneplus_sysfs_write_profile_buttons
+ },
+ {
+ .attr = { .name = "profile1_buttons", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .read = koneplus_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[0]
+ },
+ {
+ .attr = { .name = "profile2_buttons", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .read = koneplus_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[1]
+ },
+ {
+ .attr = { .name = "profile3_buttons", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .read = koneplus_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[2]
+ },
+ {
+ .attr = { .name = "profile4_buttons", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .read = koneplus_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[3]
+ },
+ {
+ .attr = { .name = "profile5_buttons", .mode = 0440 },
+ .size = sizeof(struct koneplus_profile_buttons),
+ .read = koneplus_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[4]
+ },
+ {
+ .attr = { .name = "macro", .mode = 0220 },
+ .size = sizeof(struct koneplus_macro),
+ .write = koneplus_sysfs_write_macro
+ },
+ __ATTR_NULL
+};
+
+static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
+ struct koneplus_device *koneplus)
+{
+ int retval, i;
+ static uint wait = 70; /* device will freeze with just 60 */
+
+ mutex_init(&koneplus->koneplus_lock);
+
+ koneplus->startup_profile = koneplus_get_startup_profile(usb_dev);
+
+ msleep(wait);
+ retval = koneplus_get_info(usb_dev, &koneplus->info);
+ if (retval)
+ return retval;
+
+ for (i = 0; i < 5; ++i) {
+ msleep(wait);
+ retval = koneplus_get_profile_settings(usb_dev,
+ &koneplus->profile_settings[i], i);
+ if (retval)
+ return retval;
+
+ msleep(wait);
+ retval = koneplus_get_profile_buttons(usb_dev,
+ &koneplus->profile_buttons[i], i);
+ if (retval)
+ return retval;
+ }
+
+ koneplus_profile_activated(koneplus, koneplus->startup_profile);
+
+ return 0;
+}
+
+static int koneplus_init_specials(struct hid_device *hdev)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct koneplus_device *koneplus;
+ int retval;
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ == USB_INTERFACE_PROTOCOL_MOUSE) {
+
+ koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL);
+ if (!koneplus) {
+ dev_err(&hdev->dev, "can't alloc device descriptor\n");
+ return -ENOMEM;
+ }
+ hid_set_drvdata(hdev, koneplus);
+
+ retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus);
+ if (retval) {
+ dev_err(&hdev->dev,
+ "couldn't init struct koneplus_device\n");
+ goto exit_free;
+ }
+
+ retval = roccat_connect(koneplus_class, hdev);
+ if (retval < 0) {
+ dev_err(&hdev->dev, "couldn't init char dev\n");
+ } else {
+ koneplus->chrdev_minor = retval;
+ koneplus->roccat_claimed = 1;
+ }
+ } else {
+ hid_set_drvdata(hdev, NULL);
+ }
+
+ return 0;
+exit_free:
+ kfree(koneplus);
+ return retval;
+}
+
+static void koneplus_remove_specials(struct hid_device *hdev)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct koneplus_device *koneplus;
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ == USB_INTERFACE_PROTOCOL_MOUSE) {
+ koneplus = hid_get_drvdata(hdev);
+ if (koneplus->roccat_claimed)
+ roccat_disconnect(koneplus->chrdev_minor);
+ kfree(koneplus);
+ }
+}
+
+static int koneplus_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ int retval;
+
+ retval = hid_parse(hdev);
+ if (retval) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto exit;
+ }
+
+ retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (retval) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto exit;
+ }
+
+ retval = koneplus_init_specials(hdev);
+ if (retval) {
+ dev_err(&hdev->dev, "couldn't install mouse\n");
+ goto exit_stop;
+ }
+
+ return 0;
+
+exit_stop:
+ hid_hw_stop(hdev);
+exit:
+ return retval;
+}
+
+static void koneplus_remove(struct hid_device *hdev)
+{
+ koneplus_remove_specials(hdev);
+ hid_hw_stop(hdev);
+}
+
+static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus,
+ u8 const *data)
+{
+ struct koneplus_mouse_report_button const *button_report;
+
+ switch (data[0]) {
+ case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON:
+ button_report = (struct koneplus_mouse_report_button const *)data;
+ switch (button_report->type) {
+ case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE:
+ koneplus_profile_activated(koneplus, button_report->data1 - 1);
+ break;
+ }
+ break;
+ }
+}
+
+static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus,
+ u8 const *data)
+{
+ struct koneplus_roccat_report roccat_report;
+ struct koneplus_mouse_report_button const *button_report;
+
+ if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON)
+ return;
+
+ button_report = (struct koneplus_mouse_report_button const *)data;
+
+ if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH ||
+ button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) &&
+ button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS)
+ return;
+
+ roccat_report.type = button_report->type;
+ roccat_report.data1 = button_report->data1;
+ roccat_report.data2 = button_report->data2;
+ roccat_report.profile = koneplus->actual_profile + 1;
+ roccat_report_event(koneplus->chrdev_minor,
+ (uint8_t const *)&roccat_report,
+ sizeof(struct koneplus_roccat_report));
+}
+
+static int koneplus_raw_event(struct hid_device *hdev,
+ struct hid_report *report, u8 *data, int size)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct koneplus_device *koneplus = hid_get_drvdata(hdev);
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ != USB_INTERFACE_PROTOCOL_MOUSE)
+ return 0;
+
+ koneplus_keep_values_up_to_date(koneplus, data);
+
+ if (koneplus->roccat_claimed)
+ koneplus_report_to_chrdev(koneplus, data);
+
+ return 0;
+}
+
+static const struct hid_device_id koneplus_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(hid, koneplus_devices);
+
+static struct hid_driver koneplus_driver = {
+ .name = "koneplus",
+ .id_table = koneplus_devices,
+ .probe = koneplus_probe,
+ .remove = koneplus_remove,
+ .raw_event = koneplus_raw_event
+};
+
+static int __init koneplus_init(void)
+{
+ int retval;
+
+ /* class name has to be same as driver name */
+ koneplus_class = class_create(THIS_MODULE, "koneplus");
+ if (IS_ERR(koneplus_class))
+ return PTR_ERR(koneplus_class);
+ koneplus_class->dev_attrs = koneplus_attributes;
+ koneplus_class->dev_bin_attrs = koneplus_bin_attributes;
+
+ retval = hid_register_driver(&koneplus_driver);
+ if (retval)
+ class_destroy(koneplus_class);
+ return retval;
+}
+
+static void __exit koneplus_exit(void)
+{
+ class_destroy(koneplus_class);
+ hid_unregister_driver(&koneplus_driver);
+}
+
+module_init(koneplus_init);
+module_exit(koneplus_exit);
+
+MODULE_AUTHOR("Stefan Achatz");
+MODULE_DESCRIPTION("USB Roccat Kone[+] driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h
new file mode 100644
index 000000000000..57a5c1ab7b05
--- /dev/null
+++ b/drivers/hid/hid-roccat-koneplus.h
@@ -0,0 +1,224 @@
+#ifndef __HID_ROCCAT_KONEPLUS_H
+#define __HID_ROCCAT_KONEPLUS_H
+
+/*
+ * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.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.
+ */
+
+#include <linux/types.h>
+
+/*
+ * case 1: writes request 80 and reads value 1
+ *
+ */
+struct koneplus_control {
+ uint8_t command; /* KONEPLUS_COMMAND_CONTROL */
+ /*
+ * value is profile number in range 0-4 for requesting settings and buttons
+ * 1 if status ok for requesting status
+ */
+ uint8_t value;
+ uint8_t request;
+} __attribute__ ((__packed__));
+
+enum koneplus_control_requests {
+ KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
+ KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
+ KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90,
+};
+
+enum koneplus_control_values {
+ KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0,
+ KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1,
+ KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
+};
+
+struct koneplus_startup_profile {
+ uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */
+ uint8_t size; /* always 3 */
+ uint8_t startup_profile; /* Range 0-4! */
+} __attribute__ ((__packed__));
+
+struct koneplus_profile_settings {
+ uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */
+ uint8_t size; /* always 43 */
+ uint8_t number; /* range 0-4 */
+ uint8_t advanced_sensitivity;
+ uint8_t sensitivity_x;
+ uint8_t sensitivity_y;
+ uint8_t cpi_levels_enabled;
+ uint8_t cpi_levels_x[5];
+ uint8_t cpi_startup_level; /* range 0-4 */
+ uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */
+ uint8_t unknown1;
+ uint8_t polling_rate;
+ uint8_t lights_enabled;
+ uint8_t light_effect_mode;
+ uint8_t color_flow_effect;
+ uint8_t light_effect_type;
+ uint8_t light_effect_speed;
+ uint8_t lights[16];
+ uint16_t checksum;
+} __attribute__ ((__packed__));
+
+struct koneplus_profile_buttons {
+ uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */
+ uint8_t size; /* always 77 */
+ uint8_t number; /* range 0-4 */
+ uint8_t data[72];
+ uint16_t checksum;
+} __attribute__ ((__packed__));
+
+struct koneplus_macro {
+ uint8_t command; /* KONEPLUS_COMMAND_MACRO */
+ uint16_t size; /* always 0x822 little endian */
+ uint8_t profile; /* range 0-4 */
+ uint8_t button; /* range 0-23 */
+ uint8_t data[2075];
+ uint16_t checksum;
+} __attribute__ ((__packed__));
+
+struct koneplus_info {
+ uint8_t command; /* KONEPLUS_COMMAND_INFO */
+ uint8_t size; /* always 6 */
+ uint8_t firmware_version;
+ uint8_t unknown[3];
+} __attribute__ ((__packed__));
+
+struct koneplus_e {
+ uint8_t command; /* KONEPLUS_COMMAND_E */
+ uint8_t size; /* always 3 */
+ uint8_t unknown; /* TODO 1; 0 before firmware update */
+} __attribute__ ((__packed__));
+
+struct koneplus_sensor {
+ uint8_t command; /* KONEPLUS_COMMAND_SENSOR */
+ uint8_t size; /* always 6 */
+ uint8_t data[4];
+} __attribute__ ((__packed__));
+
+struct koneplus_firmware_write {
+ uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */
+ uint8_t unknown[1025];
+} __attribute__ ((__packed__));
+
+struct koneplus_firmware_write_control {
+ uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */
+ /*
+ * value is 1 on success
+ * 3 means "not finished yet"
+ */
+ uint8_t value;
+ uint8_t unknown; /* always 0x75 */
+} __attribute__ ((__packed__));
+
+struct koneplus_tcu {
+ uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
+ uint8_t data[2];
+} __attribute__ ((__packed__));
+
+struct koneplus_tcu_image {
+ uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
+ uint8_t data[1024];
+ uint16_t checksum;
+} __attribute__ ((__packed__));
+
+enum koneplus_commands {
+ KONEPLUS_COMMAND_CONTROL = 0x4,
+ KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5,
+ KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
+ KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
+ KONEPLUS_COMMAND_MACRO = 0x8,
+ KONEPLUS_COMMAND_INFO = 0x9,
+ KONEPLUS_COMMAND_E = 0xe,
+ KONEPLUS_COMMAND_SENSOR = 0xf,
+ KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b,
+ KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
+};
+
+enum koneplus_usb_commands {
+ KONEPLUS_USB_COMMAND_CONTROL = 0x304,
+ KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305,
+ KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
+ KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
+ KONEPLUS_USB_COMMAND_MACRO = 0x308,
+ KONEPLUS_USB_COMMAND_INFO = 0x309,
+ KONEPLUS_USB_COMMAND_TCU = 0x30c,
+ KONEPLUS_USB_COMMAND_E = 0x30e,
+ KONEPLUS_USB_COMMAND_SENSOR = 0x30f,
+ KONEPLUS_USB_COMMAND_FIRMWARE_WRITE = 0x31b,
+ KONEPLUS_USB_COMMAND_FIRMWARE_WRITE_CONTROL = 0x31c,
+};
+
+enum koneplus_mouse_report_numbers {
+ KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1,
+ KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
+ KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3,
+};
+
+struct koneplus_mouse_report_button {
+ uint8_t report_number; /* always KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON */
+ uint8_t zero1;
+ uint8_t type;
+ uint8_t data1;
+ uint8_t data2;
+ uint8_t zero2;
+ uint8_t unknown[2];
+} __attribute__ ((__packed__));
+
+enum koneplus_mouse_report_button_types {
+ /* data1 = new profile range 1-5 */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20,
+
+ /* data1 = button number range 1-24; data2 = action */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
+
+ /* data1 = button number range 1-24; data2 = action */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
+
+ /* data1 = setting number range 1-5 */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
+
+ /* data1 and data2 = range 0x1-0xb */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
+
+ /* data1 = 22 = next track...
+ * data2 = action
+ */
+ KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
+};
+
+enum koneplus_mouse_report_button_action {
+ KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0,
+ KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1,
+};
+
+struct koneplus_roccat_report {
+ uint8_t type;
+ uint8_t data1;
+ uint8_t data2;
+ uint8_t profile;
+} __attribute__ ((__packed__));
+
+struct koneplus_device {
+ int actual_profile;
+
+ int roccat_claimed;
+ int chrdev_minor;
+
+ struct mutex koneplus_lock;
+
+ int startup_profile;
+ struct koneplus_info info;
+ struct koneplus_profile_settings profile_settings[5];
+ struct koneplus_profile_buttons profile_buttons[5];
+};
+
+#endif
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 9bf23047892a..02c58e015bee 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -27,6 +27,11 @@
#include "hid-roccat.h"
#include "hid-roccat-pyra.h"
+static uint profile_numbers[5] = {0, 1, 2, 3, 4};
+
+/* pyra_class is used for creating sysfs attributes via roccat char device */
+static struct class *pyra_class;
+
static void profile_activated(struct pyra_device *pyra,
unsigned int new_profile)
{
@@ -87,9 +92,8 @@ static int pyra_receive_control_status(struct usb_device *usb_dev)
control.value == 1)
return 0;
else {
- dev_err(&usb_dev->dev, "receive control status: "
- "unknown response 0x%x 0x%x\n",
- control.request, control.value);
+ hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
+ control.request, control.value);
return -EINVAL;
}
}
@@ -221,9 +225,10 @@ static int pyra_set_settings(struct usb_device *usb_dev,
static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count, int number)
+ loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_profile_settings))
@@ -233,58 +238,19 @@ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
count = sizeof(struct pyra_profile_settings) - off;
mutex_lock(&pyra->pyra_lock);
- memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off,
+ memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off,
count);
mutex_unlock(&pyra->pyra_lock);
return count;
}
-static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_settings(fp, kobj,
- attr, buf, off, count, 0);
-}
-
-static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_settings(fp, kobj,
- attr, buf, off, count, 1);
-}
-
-static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_settings(fp, kobj,
- attr, buf, off, count, 2);
-}
-
-static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_settings(fp, kobj,
- attr, buf, off, count, 3);
-}
-
-static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_settings(fp, kobj,
- attr, buf, off, count, 4);
-}
-
static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count, int number)
+ loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_profile_buttons))
@@ -294,58 +260,19 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
count = sizeof(struct pyra_profile_buttons) - off;
mutex_lock(&pyra->pyra_lock);
- memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off,
+ memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off,
count);
mutex_unlock(&pyra->pyra_lock);
return count;
}
-static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_buttons(fp, kobj,
- attr, buf, off, count, 0);
-}
-
-static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_buttons(fp, kobj,
- attr, buf, off, count, 1);
-}
-
-static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_buttons(fp, kobj,
- attr, buf, off, count, 2);
-}
-
-static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_buttons(fp, kobj,
- attr, buf, off, count, 3);
-}
-
-static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return pyra_sysfs_read_profilex_buttons(fp, kobj,
- attr, buf, off, count, 4);
-}
-
static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0;
@@ -381,7 +308,8 @@ static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0;
@@ -417,7 +345,8 @@ static ssize_t pyra_sysfs_read_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_settings))
@@ -437,7 +366,8 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev =
+ container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0;
@@ -469,255 +399,125 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct pyra_device *pyra =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
}
static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct pyra_device *pyra =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
}
static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct pyra_device *pyra =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
}
static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct pyra_device *pyra =
+ hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
}
-static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
-
-static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
-
-static DEVICE_ATTR(firmware_version, 0440,
- pyra_sysfs_show_firmware_version, NULL);
-
-static DEVICE_ATTR(startup_profile, 0440,
- pyra_sysfs_show_startup_profile, NULL);
-
-static struct attribute *pyra_attributes[] = {
- &dev_attr_actual_cpi.attr,
- &dev_attr_actual_profile.attr,
- &dev_attr_firmware_version.attr,
- &dev_attr_startup_profile.attr,
- NULL
-};
-
-static struct attribute_group pyra_attribute_group = {
- .attrs = pyra_attributes
+static struct device_attribute pyra_attributes[] = {
+ __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL),
+ __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL),
+ __ATTR(firmware_version, 0440,
+ pyra_sysfs_show_firmware_version, NULL),
+ __ATTR(startup_profile, 0440,
+ pyra_sysfs_show_startup_profile, NULL),
+ __ATTR_NULL
};
-static struct bin_attribute pyra_profile_settings_attr = {
+static struct bin_attribute pyra_bin_attributes[] = {
+ {
.attr = { .name = "profile_settings", .mode = 0220 },
.size = sizeof(struct pyra_profile_settings),
.write = pyra_sysfs_write_profile_settings
-};
-
-static struct bin_attribute pyra_profile1_settings_attr = {
+ },
+ {
.attr = { .name = "profile1_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profile1_settings
-};
-
-static struct bin_attribute pyra_profile2_settings_attr = {
+ .read = pyra_sysfs_read_profilex_settings,
+ .private = &profile_numbers[0]
+ },
+ {
.attr = { .name = "profile2_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profile2_settings
-};
-
-static struct bin_attribute pyra_profile3_settings_attr = {
+ .read = pyra_sysfs_read_profilex_settings,
+ .private = &profile_numbers[1]
+ },
+ {
.attr = { .name = "profile3_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profile3_settings
-};
-
-static struct bin_attribute pyra_profile4_settings_attr = {
+ .read = pyra_sysfs_read_profilex_settings,
+ .private = &profile_numbers[2]
+ },
+ {
.attr = { .name = "profile4_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profile4_settings
-};
-
-static struct bin_attribute pyra_profile5_settings_attr = {
+ .read = pyra_sysfs_read_profilex_settings,
+ .private = &profile_numbers[3]
+ },
+ {
.attr = { .name = "profile5_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profile5_settings
-};
-
-static struct bin_attribute pyra_profile_buttons_attr = {
+ .read = pyra_sysfs_read_profilex_settings,
+ .private = &profile_numbers[4]
+ },
+ {
.attr = { .name = "profile_buttons", .mode = 0220 },
.size = sizeof(struct pyra_profile_buttons),
.write = pyra_sysfs_write_profile_buttons
-};
-
-static struct bin_attribute pyra_profile1_buttons_attr = {
+ },
+ {
.attr = { .name = "profile1_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profile1_buttons
-};
-
-static struct bin_attribute pyra_profile2_buttons_attr = {
+ .read = pyra_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[0]
+ },
+ {
.attr = { .name = "profile2_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profile2_buttons
-};
-
-static struct bin_attribute pyra_profile3_buttons_attr = {
+ .read = pyra_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[1]
+ },
+ {
.attr = { .name = "profile3_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profile3_buttons
-};
-
-static struct bin_attribute pyra_profile4_buttons_attr = {
+ .read = pyra_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[2]
+ },
+ {
.attr = { .name = "profile4_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profile4_buttons
-};
-
-static struct bin_attribute pyra_profile5_buttons_attr = {
+ .read = pyra_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[3]
+ },
+ {
.attr = { .name = "profile5_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profile5_buttons
-};
-
-static struct bin_attribute pyra_settings_attr = {
+ .read = pyra_sysfs_read_profilex_buttons,
+ .private = &profile_numbers[4]
+ },
+ {
.attr = { .name = "settings", .mode = 0660 },
.size = sizeof(struct pyra_settings),
.read = pyra_sysfs_read_settings,
.write = pyra_sysfs_write_settings
+ },
+ __ATTR_NULL
};
-static int pyra_create_sysfs_attributes(struct usb_interface *intf)
-{
- int retval;
-
- retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
- if (retval)
- goto exit_1;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile_settings_attr);
- if (retval)
- goto exit_2;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile1_settings_attr);
- if (retval)
- goto exit_3;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile2_settings_attr);
- if (retval)
- goto exit_4;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile3_settings_attr);
- if (retval)
- goto exit_5;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile4_settings_attr);
- if (retval)
- goto exit_6;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile5_settings_attr);
- if (retval)
- goto exit_7;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile_buttons_attr);
- if (retval)
- goto exit_8;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile1_buttons_attr);
- if (retval)
- goto exit_9;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile2_buttons_attr);
- if (retval)
- goto exit_10;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile3_buttons_attr);
- if (retval)
- goto exit_11;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile4_buttons_attr);
- if (retval)
- goto exit_12;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_profile5_buttons_attr);
- if (retval)
- goto exit_13;
-
- retval = sysfs_create_bin_file(&intf->dev.kobj,
- &pyra_settings_attr);
- if (retval)
- goto exit_14;
-
- return 0;
-
-exit_14:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
-exit_13:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
-exit_12:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
-exit_11:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
-exit_10:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
-exit_9:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
-exit_8:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
-exit_7:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
-exit_6:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
-exit_5:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
-exit_4:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
-exit_3:
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
-exit_2:
- sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
-exit_1:
- return retval;
-}
-
-static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
-{
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
- sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
- sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
-}
-
static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
struct pyra_device *pyra)
{
@@ -770,31 +570,24 @@ static int pyra_init_specials(struct hid_device *hdev)
pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
if (!pyra) {
- dev_err(&hdev->dev, "can't alloc device descriptor\n");
+ hid_err(hdev, "can't alloc device descriptor\n");
return -ENOMEM;
}
hid_set_drvdata(hdev, pyra);
retval = pyra_init_pyra_device_struct(usb_dev, pyra);
if (retval) {
- dev_err(&hdev->dev,
- "couldn't init struct pyra_device\n");
+ hid_err(hdev, "couldn't init struct pyra_device\n");
goto exit_free;
}
- retval = roccat_connect(hdev);
+ retval = roccat_connect(pyra_class, hdev);
if (retval < 0) {
- dev_err(&hdev->dev, "couldn't init char dev\n");
+ hid_err(hdev, "couldn't init char dev\n");
} else {
pyra->chrdev_minor = retval;
pyra->roccat_claimed = 1;
}
-
- retval = pyra_create_sysfs_attributes(intf);
- if (retval) {
- dev_err(&hdev->dev, "cannot create sysfs files\n");
- goto exit_free;
- }
} else {
hid_set_drvdata(hdev, NULL);
}
@@ -812,7 +605,6 @@ static void pyra_remove_specials(struct hid_device *hdev)
if (intf->cur_altsetting->desc.bInterfaceProtocol
== USB_INTERFACE_PROTOCOL_MOUSE) {
- pyra_remove_sysfs_attributes(intf);
pyra = hid_get_drvdata(hdev);
if (pyra->roccat_claimed)
roccat_disconnect(pyra->chrdev_minor);
@@ -826,19 +618,19 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
retval = hid_parse(hdev);
if (retval) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto exit;
}
retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (retval) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto exit;
}
retval = pyra_init_specials(hdev);
if (retval) {
- dev_err(&hdev->dev, "couldn't install mouse\n");
+ hid_err(hdev, "couldn't install mouse\n");
goto exit_stop;
}
return 0;
@@ -952,11 +744,24 @@ static struct hid_driver pyra_driver = {
static int __init pyra_init(void)
{
- return hid_register_driver(&pyra_driver);
+ int retval;
+
+ /* class name has to be same as driver name */
+ pyra_class = class_create(THIS_MODULE, "pyra");
+ if (IS_ERR(pyra_class))
+ return PTR_ERR(pyra_class);
+ pyra_class->dev_attrs = pyra_attributes;
+ pyra_class->dev_bin_attrs = pyra_bin_attributes;
+
+ retval = hid_register_driver(&pyra_driver);
+ if (retval)
+ class_destroy(pyra_class);
+ return retval;
}
static void __exit pyra_exit(void)
{
+ class_destroy(pyra_class);
hid_unregister_driver(&pyra_driver);
}
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
index 22f80a8f26f9..14cbbe1621e0 100644
--- a/drivers/hid/hid-roccat-pyra.h
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -14,14 +14,11 @@
#include <linux/types.h>
-#pragma pack(push)
-#pragma pack(1)
-
struct pyra_b {
uint8_t command; /* PYRA_COMMAND_B */
uint8_t size; /* always 3 */
uint8_t unknown; /* 1 */
-};
+} __attribute__ ((__packed__));
struct pyra_control {
uint8_t command; /* PYRA_COMMAND_CONTROL */
@@ -31,7 +28,7 @@ struct pyra_control {
*/
uint8_t value; /* Range 0-4 */
uint8_t request;
-};
+} __attribute__ ((__packed__));
enum pyra_control_requests {
PYRA_CONTROL_REQUEST_STATUS = 0x00,
@@ -43,7 +40,7 @@ struct pyra_settings {
uint8_t command; /* PYRA_COMMAND_SETTINGS */
uint8_t size; /* always 3 */
uint8_t startup_profile; /* Range 0-4! */
-};
+} __attribute__ ((__packed__));
struct pyra_profile_settings {
uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
@@ -58,7 +55,7 @@ struct pyra_profile_settings {
uint8_t light_effect;
uint8_t handedness;
uint16_t checksum; /* byte sum */
-};
+} __attribute__ ((__packed__));
struct pyra_profile_buttons {
uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
@@ -66,7 +63,7 @@ struct pyra_profile_buttons {
uint8_t number; /* Range 0-4 */
uint8_t buttons[14];
uint16_t checksum; /* byte sum */
-};
+} __attribute__ ((__packed__));
struct pyra_info {
uint8_t command; /* PYRA_COMMAND_INFO */
@@ -75,7 +72,7 @@ struct pyra_info {
uint8_t unknown1; /* always 0 */
uint8_t unknown2; /* always 1 */
uint8_t unknown3; /* always 0 */
-};
+} __attribute__ ((__packed__));
enum pyra_commands {
PYRA_COMMAND_CONTROL = 0x4,
@@ -107,13 +104,13 @@ struct pyra_mouse_event_button {
uint8_t type;
uint8_t data1;
uint8_t data2;
-};
+} __attribute__ ((__packed__));
struct pyra_mouse_event_audio {
uint8_t report_number; /* always 2 */
uint8_t type;
uint8_t unused; /* always 0 */
-};
+} __attribute__ ((__packed__));
/* hid audio controls */
enum pyra_mouse_event_audio_types {
@@ -167,9 +164,7 @@ struct pyra_roccat_report {
uint8_t type;
uint8_t value;
uint8_t key;
-};
-
-#pragma pack(pop)
+} __attribute__ ((__packed__));
struct pyra_device {
int actual_profile;
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index 5a6879e235ac..a14c579ea781 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -21,6 +21,8 @@
* It is inspired by hidraw, but uses only one circular buffer for all readers.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/sched.h>
@@ -65,7 +67,6 @@ struct roccat_reader {
};
static int roccat_major;
-static struct class *roccat_class;
static struct cdev roccat_cdev;
static struct roccat_device *devices[ROCCAT_MAX_DEVICES];
@@ -165,27 +166,22 @@ static int roccat_open(struct inode *inode, struct file *file)
mutex_lock(&device->readers_lock);
if (!device) {
- printk(KERN_EMERG "roccat device with minor %d doesn't exist\n",
- minor);
+ pr_emerg("roccat device with minor %d doesn't exist\n", minor);
error = -ENODEV;
goto exit_err;
}
if (!device->open++) {
/* power on device on adding first reader */
- if (device->hid->ll_driver->power) {
- error = device->hid->ll_driver->power(device->hid,
- PM_HINT_FULLON);
- if (error < 0) {
- --device->open;
- goto exit_err;
- }
+ error = hid_hw_power(device->hid, PM_HINT_FULLON);
+ if (error < 0) {
+ --device->open;
+ goto exit_err;
}
- error = device->hid->ll_driver->open(device->hid);
+
+ error = hid_hw_open(device->hid);
if (error < 0) {
- if (device->hid->ll_driver->power)
- device->hid->ll_driver->power(device->hid,
- PM_HINT_NORMAL);
+ hid_hw_power(device->hid, PM_HINT_NORMAL);
--device->open;
goto exit_err;
}
@@ -218,8 +214,7 @@ static int roccat_release(struct inode *inode, struct file *file)
device = devices[minor];
if (!device) {
mutex_unlock(&devices_lock);
- printk(KERN_EMERG "roccat device with minor %d doesn't exist\n",
- minor);
+ pr_emerg("roccat device with minor %d doesn't exist\n", minor);
return -ENODEV;
}
@@ -231,10 +226,8 @@ static int roccat_release(struct inode *inode, struct file *file)
if (!--device->open) {
/* removing last reader */
if (device->exist) {
- if (device->hid->ll_driver->power)
- device->hid->ll_driver->power(device->hid,
- PM_HINT_NORMAL);
- device->hid->ll_driver->close(device->hid);
+ hid_hw_power(device->hid, PM_HINT_NORMAL);
+ hid_hw_close(device->hid);
} else {
kfree(device);
}
@@ -295,12 +288,14 @@ EXPORT_SYMBOL_GPL(roccat_report_event);
/*
* roccat_connect() - create a char device for special event output
+ * @class: the class thats used to create the device. Meant to hold device
+ * specific sysfs attributes.
* @hid: the hid device the char device should be connected to.
*
* Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on
* success, a negative error code on failure.
*/
-int roccat_connect(struct hid_device *hid)
+int roccat_connect(struct class *klass, struct hid_device *hid)
{
unsigned int minor;
struct roccat_device *device;
@@ -326,7 +321,7 @@ int roccat_connect(struct hid_device *hid)
return -EINVAL;
}
- device->dev = device_create(roccat_class, &hid->dev,
+ device->dev = device_create(klass, &hid->dev,
MKDEV(roccat_major, minor), NULL,
"%s%s%d", "roccat", hid->driver->name, minor);
@@ -367,10 +362,10 @@ void roccat_disconnect(int minor)
device->exist = 0; /* TODO exist maybe not needed */
- device_destroy(roccat_class, MKDEV(roccat_major, minor));
+ device_destroy(device->dev->class, MKDEV(roccat_major, minor));
if (device->open) {
- device->hid->ll_driver->close(device->hid);
+ hid_hw_close(device->hid);
wake_up_interruptible(&device->wait);
} else {
kfree(device);
@@ -398,14 +393,7 @@ static int __init roccat_init(void)
roccat_major = MAJOR(dev_id);
if (retval < 0) {
- printk(KERN_WARNING "roccat: can't get major number\n");
- return retval;
- }
-
- roccat_class = class_create(THIS_MODULE, "roccat");
- if (IS_ERR(roccat_class)) {
- retval = PTR_ERR(roccat_class);
- unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
+ pr_warn("can't get major number\n");
return retval;
}
@@ -420,7 +408,6 @@ static void __exit roccat_exit(void)
dev_t dev_id = MKDEV(roccat_major, 0);
cdev_del(&roccat_cdev);
- class_destroy(roccat_class);
unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
}
diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h
index 09e864e9f79d..5784281d613f 100644
--- a/drivers/hid/hid-roccat.h
+++ b/drivers/hid/hid-roccat.h
@@ -16,11 +16,12 @@
#include <linux/types.h>
#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE)
-int roccat_connect(struct hid_device *hid);
+int roccat_connect(struct class *klass, struct hid_device *hid);
void roccat_disconnect(int minor);
int roccat_report_event(int minor, u8 const *data, int len);
#else
-static inline int roccat_connect(struct hid_device *hid) { return -1; }
+static inline int roccat_connect(struct class *klass,
+ struct hid_device *hid) { return -1; }
static inline void roccat_disconnect(int minor) {}
static inline int roccat_report_event(int minor, u8 const *data, int len)
{
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 35894444e000..3c1fd8af5e0c 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -57,8 +57,8 @@
static inline void samsung_irda_dev_trace(struct hid_device *hdev,
unsigned int rsize)
{
- dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
- "descriptor\n", rsize);
+ hid_info(hdev, "fixing up Samsung IrDA %d byte report descriptor\n",
+ rsize);
}
static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -160,7 +160,7 @@ static int samsung_probe(struct hid_device *hdev,
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
@@ -174,7 +174,7 @@ static int samsung_probe(struct hid_device *hdev,
ret = hid_hw_start(hdev, cmask);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index e10a7687ebf2..16f7cafc9695 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -74,26 +74,25 @@ static int sjoyff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output reports found\n");
+ hid_err(hid, "no output reports found\n");
return -ENODEV;
}
report_ptr = report_ptr->next;
if (report_ptr == report_list) {
- dev_err(&hid->dev, "required output report is "
- "missing\n");
+ hid_err(hid, "required output report is missing\n");
return -ENODEV;
}
report = list_entry(report_ptr, struct hid_report, list);
if (report->maxfield < 1) {
- dev_err(&hid->dev, "no fields in the report\n");
+ hid_err(hid, "no fields in the report\n");
return -ENODEV;
}
if (report->field[0]->report_count < 3) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ hid_err(hid, "not enough values in the field\n");
return -ENODEV;
}
@@ -117,8 +116,7 @@ static int sjoyff_init(struct hid_device *hid)
sjoyff->report->field[0]->value[2] = 0x00;
usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
- dev_info(&hid->dev,
- "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
+ hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
return 0;
}
@@ -135,13 +133,13 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 677bb3da10e8..68d7b36e31e4 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -40,8 +40,7 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
*rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
- dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report "
- "descriptor\n");
+ hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
rdesc[55] = 0x06;
}
return rdesc;
@@ -89,7 +88,7 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
(3 << 8) | 0xf2, ifnum, buf, 17,
USB_CTRL_GET_TIMEOUT);
if (ret < 0)
- dev_err(&hdev->dev, "can't set operational mode\n");
+ hid_err(hdev, "can't set operational mode\n");
kfree(buf);
@@ -110,7 +109,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
sc = kzalloc(sizeof(*sc), GFP_KERNEL);
if (sc == NULL) {
- dev_err(&hdev->dev, "can't alloc sony descriptor\n");
+ hid_err(hdev, "can't alloc sony descriptor\n");
return -ENOMEM;
}
@@ -119,14 +118,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
HID_CONNECT_HIDDEV_FORCE);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c
index 3171be28c3d5..b2be1d11916b 100644
--- a/drivers/hid/hid-stantum.c
+++ b/drivers/hid/hid-stantum.c
@@ -222,7 +222,7 @@ static int stantum_probe(struct hid_device *hdev,
sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL);
if (!sd) {
- dev_err(&hdev->dev, "cannot allocate Stantum data\n");
+ hid_err(hdev, "cannot allocate Stantum data\n");
return -ENOMEM;
}
sd->valid = false;
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 164ed568f6cf..d484a0043dd4 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -27,8 +27,7 @@ static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
{
if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
rdesc[106] == 0x03) {
- dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop "
- "report descriptor\n");
+ hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n");
rdesc[105] = rdesc[110] = 0x03;
rdesc[106] = rdesc[111] = 0x21;
}
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 15434c814793..575862b0688e 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -151,28 +151,23 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
switch (field->usage[0].hid) {
case THRUSTMASTER_USAGE_FF:
if (field->report_count < 2) {
- dev_warn(&hid->dev, "ignoring FF field "
- "with report_count < 2\n");
+ hid_warn(hid, "ignoring FF field with report_count < 2\n");
continue;
}
if (field->logical_maximum ==
field->logical_minimum) {
- dev_warn(&hid->dev, "ignoring FF field "
- "with logical_maximum "
- "== logical_minimum\n");
+ hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n");
continue;
}
if (tmff->report && tmff->report != report) {
- dev_warn(&hid->dev, "ignoring FF field "
- "in other report\n");
+ hid_warn(hid, "ignoring FF field in other report\n");
continue;
}
if (tmff->ff_field && tmff->ff_field != field) {
- dev_warn(&hid->dev, "ignoring "
- "duplicate FF field\n");
+ hid_warn(hid, "ignoring duplicate FF field\n");
continue;
}
@@ -185,16 +180,15 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
break;
default:
- dev_warn(&hid->dev, "ignoring unknown output "
- "usage %08x\n",
- field->usage[0].hid);
+ hid_warn(hid, "ignoring unknown output usage %08x\n",
+ field->usage[0].hid);
continue;
}
}
}
if (!tmff->report) {
- dev_err(&hid->dev, "can't find FF field in output reports\n");
+ hid_err(hid, "can't find FF field in output reports\n");
error = -ENODEV;
goto fail;
}
@@ -203,8 +197,7 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
if (error)
goto fail;
- dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx "
- "Verituse <zinx@epicsol.org>");
+ hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse <zinx@epicsol.org>\n");
return 0;
fail:
@@ -224,13 +217,13 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
@@ -256,6 +249,8 @@ static const struct hid_device_id tm_devices[] = {
.driver_data = (unsigned long)ff_joystick },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */
.driver_data = (unsigned long)ff_joystick },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a), /* F430 Force Feedback Wheel */
+ .driver_data = (unsigned long)ff_joystick },
{ }
};
MODULE_DEVICE_TABLE(hid, tm_devices);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 956ed9ac19d4..613ff7b1d746 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -66,6 +66,7 @@ static const struct hid_device_id ts_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
{ }
};
MODULE_DEVICE_TABLE(hid, ts_devices);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 724f46ed612f..06888323828c 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -18,6 +18,8 @@
* any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
@@ -141,8 +143,8 @@ static void wacom_poke(struct hid_device *hdev, u8 speed)
* Note that if the raw queries fail, it's not a hard failure and it
* is safe to continue
*/
- dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n",
- rep_data[0], ret);
+ hid_warn(hdev, "failed to poke device, command %d, err %d\n",
+ rep_data[0], ret);
return;
}
@@ -172,7 +174,7 @@ static ssize_t wacom_store_speed(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
wacom_show_speed, wacom_store_speed);
static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
@@ -312,7 +314,7 @@ static int wacom_probe(struct hid_device *hdev,
wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
if (wdata == NULL) {
- dev_err(&hdev->dev, "can't alloc wacom descriptor\n");
+ hid_err(hdev, "can't alloc wacom descriptor\n");
return -ENOMEM;
}
@@ -321,20 +323,20 @@ static int wacom_probe(struct hid_device *hdev,
/* Parse the HID report now */
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
ret = device_create_file(&hdev->dev, &dev_attr_speed);
if (ret)
- dev_warn(&hdev->dev,
- "can't create sysfs speed attribute err: %d\n", ret);
+ hid_warn(hdev,
+ "can't create sysfs speed attribute err: %d\n", ret);
/* Set Wacom mode 2 with high reporting speed */
wacom_poke(hdev, 1);
@@ -349,8 +351,8 @@ static int wacom_probe(struct hid_device *hdev,
ret = power_supply_register(&hdev->dev, &wdata->battery);
if (ret) {
- dev_warn(&hdev->dev,
- "can't create sysfs battery attribute, err: %d\n", ret);
+ hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
+ ret);
/*
* battery attribute is not critical for the tablet, but if it
* failed then there is no need to create ac attribute
@@ -367,8 +369,8 @@ static int wacom_probe(struct hid_device *hdev,
ret = power_supply_register(&hdev->dev, &wdata->ac);
if (ret) {
- dev_warn(&hdev->dev,
- "can't create ac battery attribute, err: %d\n", ret);
+ hid_warn(hdev,
+ "can't create ac battery attribute, err: %d\n", ret);
/*
* ac attribute is not critical for the tablet, but if it
* failed then we don't want to battery attribute to exist
@@ -454,7 +456,7 @@ static int __init wacom_init(void)
ret = hid_register_driver(&wacom_driver);
if (ret)
- printk(KERN_ERR "can't register wacom driver\n");
+ pr_err("can't register wacom driver\n");
return ret;
}
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index b7acceabba80..f31fab012f2f 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -75,14 +75,14 @@ static int zpff_init(struct hid_device *hid)
int error;
if (list_empty(report_list)) {
- dev_err(&hid->dev, "no output report found\n");
+ hid_err(hid, "no output report found\n");
return -ENODEV;
}
report = list_entry(report_list->next, struct hid_report, list);
if (report->maxfield < 4) {
- dev_err(&hid->dev, "not enough fields in report\n");
+ hid_err(hid, "not enough fields in report\n");
return -ENODEV;
}
@@ -105,8 +105,7 @@ static int zpff_init(struct hid_device *hid)
zpff->report->field[3]->value[0] = 0x00;
usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
- dev_info(&hid->dev, "force feedback for Zeroplus based devices by "
- "Anssi Hannula <anssi.hannula@gmail.com>\n");
+ hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
return 0;
}
@@ -123,13 +122,13 @@ static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
- dev_err(&hdev->dev, "hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err;
}
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index aac1f9273149..e90371508fd2 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -34,9 +34,8 @@ static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
- dev_info(&hdev->dev,
- "fixing up zydacron remote control report "
- "descriptor\n");
+ hid_info(hdev,
+ "fixing up zydacron remote control report descriptor\n");
rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
}
@@ -172,7 +171,7 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)
zc = kzalloc(sizeof(*zc), GFP_KERNEL);
if (zc == NULL) {
- dev_err(&hdev->dev, "zydacron: can't alloc descriptor\n");
+ hid_err(hdev, "can't alloc descriptor\n");
return -ENOMEM;
}
@@ -180,13 +179,13 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
- dev_err(&hdev->dev, "zydacron: parse failed\n");
+ hid_err(hdev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
- dev_err(&hdev->dev, "zydacron: hw start failed\n");
+ hid_err(hdev, "hw start failed\n");
goto err_free;
}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index e1f07483691f..468e87b53ed2 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -19,6 +19,8 @@
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
@@ -122,15 +124,15 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
}
if (count > HID_MAX_BUFFER_SIZE) {
- printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
- task_pid_nr(current));
+ hid_warn(dev, "pid %d passed too large report\n",
+ task_pid_nr(current));
ret = -EINVAL;
goto out;
}
if (count < 2) {
- printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
- task_pid_nr(current));
+ hid_warn(dev, "pid %d passed too short report\n",
+ task_pid_nr(current));
ret = -EINVAL;
goto out;
}
@@ -192,15 +194,13 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor];
if (!dev->open++) {
- if (dev->hid->ll_driver->power) {
- err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
- if (err < 0)
- goto out_unlock;
- }
- err = dev->hid->ll_driver->open(dev->hid);
+ err = hid_hw_power(dev->hid, PM_HINT_FULLON);
+ if (err < 0)
+ goto out_unlock;
+
+ err = hid_hw_open(dev->hid);
if (err < 0) {
- if (dev->hid->ll_driver->power)
- dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
+ hid_hw_power(dev->hid, PM_HINT_NORMAL);
dev->open--;
}
}
@@ -229,9 +229,8 @@ static int hidraw_release(struct inode * inode, struct file * file)
dev = hidraw_table[minor];
if (!--dev->open) {
if (list->hidraw->exist) {
- if (dev->hid->ll_driver->power)
- dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
- dev->hid->ll_driver->close(dev->hid);
+ hid_hw_power(dev->hid, PM_HINT_NORMAL);
+ hid_hw_close(dev->hid);
} else {
kfree(list->hidraw);
}
@@ -345,6 +344,9 @@ static const struct file_operations hidraw_ops = {
.open = hidraw_open,
.release = hidraw_release,
.unlocked_ioctl = hidraw_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hidraw_ioctl,
+#endif
.llseek = noop_llseek,
};
@@ -433,7 +435,7 @@ void hidraw_disconnect(struct hid_device *hid)
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
if (hidraw->open) {
- hid->ll_driver->close(hid);
+ hid_hw_close(hid);
wake_up_interruptible(&hidraw->wait);
} else {
kfree(hidraw);
@@ -452,7 +454,7 @@ int __init hidraw_init(void)
hidraw_major = MAJOR(dev_id);
if (result < 0) {
- printk(KERN_WARNING "hidraw: can't get major number\n");
+ pr_warn("can't get major number\n");
result = 0;
goto out;
}
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 1329ecb37a1c..db3cf31c6fa1 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -3,15 +3,15 @@
#
# Multipart objects.
-usbhid-objs := hid-core.o hid-quirks.o
+usbhid-y := hid-core.o hid-quirks.o
# Optional parts of multipart objects.
ifeq ($(CONFIG_USB_HIDDEV),y)
- usbhid-objs += hiddev.o
+ usbhid-y += hiddev.o
endif
ifeq ($(CONFIG_HID_PID),y)
- usbhid-objs += hid-pidff.o
+ usbhid-y += hid-pidff.o
endif
obj-$(CONFIG_USB_HID) += usbhid.o
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 5489eab3a6bd..b336dd84036f 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -67,7 +67,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
* Input submission and I/O error handler.
*/
static DEFINE_MUTEX(hid_open_mut);
-static struct workqueue_struct *resumption_waker;
static void hid_io_error(struct hid_device *hid);
static int hid_submit_out(struct hid_device *hid);
@@ -136,10 +135,10 @@ static void hid_reset(struct work_struct *work)
hid_io_error(hid);
break;
default:
- err_hid("can't reset device, %s-%s/input%d, status %d",
- hid_to_usb_dev(hid)->bus->bus_name,
- hid_to_usb_dev(hid)->devpath,
- usbhid->ifnum, rc);
+ hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n",
+ hid_to_usb_dev(hid)->bus->bus_name,
+ hid_to_usb_dev(hid)->devpath,
+ usbhid->ifnum, rc);
/* FALLTHROUGH */
case -EHOSTUNREACH:
case -ENODEV:
@@ -278,18 +277,18 @@ static void hid_irq_in(struct urb *urb)
hid_io_error(hid);
return;
default: /* error */
- dev_warn(&urb->dev->dev, "input irq status %d "
- "received\n", urb->status);
+ hid_warn(urb->dev, "input irq status %d received\n",
+ urb->status);
}
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
if (status != -EPERM) {
- err_hid("can't resubmit intr, %s-%s/input%d, status %d",
- hid_to_usb_dev(hid)->bus->bus_name,
- hid_to_usb_dev(hid)->devpath,
- usbhid->ifnum, status);
+ hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n",
+ hid_to_usb_dev(hid)->bus->bus_name,
+ hid_to_usb_dev(hid)->devpath,
+ usbhid->ifnum, status);
hid_io_error(hid);
}
}
@@ -300,10 +299,19 @@ static int hid_submit_out(struct hid_device *hid)
struct hid_report *report;
char *raw_report;
struct usbhid_device *usbhid = hid->driver_data;
+ int r;
report = usbhid->out[usbhid->outtail].report;
raw_report = usbhid->out[usbhid->outtail].raw_report;
+ r = usb_autopm_get_interface_async(usbhid->intf);
+ if (r < 0)
+ return -1;
+
+ /*
+ * if the device hasn't been woken, we leave the output
+ * to resume()
+ */
if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
usbhid->urbout->dev = hid_to_usb_dev(hid);
@@ -313,17 +321,11 @@ static int hid_submit_out(struct hid_device *hid)
dbg_hid("submitting out urb\n");
if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(out) failed");
+ hid_err(hid, "usb_submit_urb(out) failed\n");
+ usb_autopm_put_interface_async(usbhid->intf);
return -1;
}
usbhid->last_out = jiffies;
- } else {
- /*
- * queue work to wake up the device.
- * as the work queue is freezeable, this is safe
- * with respect to STD and STR
- */
- queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -334,13 +336,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
struct hid_report *report;
unsigned char dir;
char *raw_report;
- int len;
+ int len, r;
struct usbhid_device *usbhid = hid->driver_data;
report = usbhid->ctrl[usbhid->ctrltail].report;
raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
dir = usbhid->ctrl[usbhid->ctrltail].dir;
+ r = usb_autopm_get_interface_async(usbhid->intf);
+ if (r < 0)
+ return -1;
if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
if (dir == USB_DIR_OUT) {
@@ -375,17 +380,11 @@ static int hid_submit_ctrl(struct hid_device *hid)
usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(ctrl) failed");
+ usb_autopm_put_interface_async(usbhid->intf);
+ hid_err(hid, "usb_submit_urb(ctrl) failed\n");
return -1;
}
usbhid->last_ctrl = jiffies;
- } else {
- /*
- * queue work to wake up the device.
- * as the work queue is freezeable, this is safe
- * with respect to STD and STR
- */
- queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -413,8 +412,8 @@ static void hid_irq_out(struct urb *urb)
case -ENOENT:
break;
default: /* error */
- dev_warn(&urb->dev->dev, "output irq status %d "
- "received\n", urb->status);
+ hid_warn(urb->dev, "output irq status %d received\n",
+ urb->status);
}
spin_lock_irqsave(&usbhid->lock, flags);
@@ -435,6 +434,7 @@ static void hid_irq_out(struct urb *urb)
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
spin_unlock_irqrestore(&usbhid->lock, flags);
+ usb_autopm_put_interface_async(usbhid->intf);
wake_up(&usbhid->wait);
}
@@ -466,8 +466,7 @@ static void hid_ctrl(struct urb *urb)
case -EPIPE: /* report not available */
break;
default: /* error */
- dev_warn(&urb->dev->dev, "ctrl urb status %d "
- "received\n", status);
+ hid_warn(urb->dev, "ctrl urb status %d received\n", status);
}
if (unplug)
@@ -481,11 +480,13 @@ static void hid_ctrl(struct urb *urb)
wake_up(&usbhid->wait);
}
spin_unlock(&usbhid->lock);
+ usb_autopm_put_interface_async(usbhid->intf);
return;
}
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
spin_unlock(&usbhid->lock);
+ usb_autopm_put_interface_async(usbhid->intf);
wake_up(&usbhid->wait);
}
@@ -501,13 +502,13 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- dev_warn(&hid->dev, "output queue full\n");
+ hid_warn(hid, "output queue full\n");
return;
}
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
- dev_warn(&hid->dev, "output queueing failed\n");
+ hid_warn(hid, "output queueing failed\n");
return;
}
hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
@@ -532,14 +533,14 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
}
if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- dev_warn(&hid->dev, "control queue full\n");
+ hid_warn(hid, "control queue full\n");
return;
}
if (dir == USB_DIR_OUT) {
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- dev_warn(&hid->dev, "control queueing failed\n");
+ hid_warn(hid, "control queueing failed\n");
return;
}
hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
@@ -590,7 +591,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
return -1;
if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
- dev_warn(&dev->dev, "event field not found\n");
+ hid_warn(dev, "event field not found\n");
return -1;
}
@@ -656,7 +657,7 @@ int usbhid_open(struct hid_device *hid)
mutex_lock(&hid_open_mut);
if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
- /* the device must be awake to reliable request remote wakeup */
+ /* the device must be awake to reliably request remote wakeup */
if (res < 0) {
hid->open--;
mutex_unlock(&hid_open_mut);
@@ -722,7 +723,7 @@ void usbhid_init_reports(struct hid_device *hid)
}
if (err)
- dev_warn(&hid->dev, "timeout initializing reports\n");
+ hid_warn(hid, "timeout initializing reports\n");
}
/*
@@ -857,18 +858,6 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid)
usbhid_restart_ctrl_queue(usbhid);
}
-static void __usbhid_restart_queues(struct work_struct *work)
-{
- struct usbhid_device *usbhid =
- container_of(work, struct usbhid_device, restart_work);
- int r;
-
- r = usb_autopm_get_interface(usbhid->intf);
- if (r < 0)
- return;
- usb_autopm_put_interface(usbhid->intf);
-}
-
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -1140,8 +1129,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
if (usb_endpoint_is_int_in(&interface->endpoint[n].desc))
has_in++;
if (!has_in) {
- dev_err(&intf->dev, "couldn't find an input interrupt "
- "endpoint\n");
+ hid_err(intf, "couldn't find an input interrupt endpoint\n");
return -ENODEV;
}
@@ -1206,14 +1194,13 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
- INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
spin_lock_init(&usbhid->lock);
ret = hid_add_device(hid);
if (ret) {
if (ret != -ENODEV)
- dev_err(&intf->dev, "can't add hid device: %d\n", ret);
+ hid_err(intf, "can't add hid device: %d\n", ret);
goto err_free;
}
@@ -1241,7 +1228,6 @@ static void usbhid_disconnect(struct usb_interface *intf)
static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
{
del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->restart_work);
cancel_work_sync(&usbhid->reset_work);
}
@@ -1262,7 +1248,6 @@ static int hid_pre_reset(struct usb_interface *intf)
spin_lock_irq(&usbhid->lock);
set_bit(HID_RESET_PENDING, &usbhid->iofl);
spin_unlock_irq(&usbhid->lock);
- cancel_work_sync(&usbhid->restart_work);
hid_cease_io(usbhid);
return 0;
@@ -1461,9 +1446,6 @@ static int __init hid_init(void)
{
int retval = -ENOMEM;
- resumption_waker = create_freezeable_workqueue("usbhid_resumer");
- if (!resumption_waker)
- goto no_queue;
retval = hid_register_driver(&hid_usb_driver);
if (retval)
goto hid_register_fail;
@@ -1481,8 +1463,6 @@ usb_register_fail:
usbhid_quirks_init_fail:
hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
- destroy_workqueue(resumption_waker);
-no_queue:
return retval;
}
@@ -1491,7 +1471,6 @@ static void __exit hid_exit(void)
usb_deregister(&hid_driver);
usbhid_quirks_exit();
hid_unregister_driver(&hid_usb_driver);
- destroy_workqueue(resumption_waker);
}
module_init(hid_init);
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index ef381d79cfa8..f91c136821f7 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -22,7 +22,7 @@
/* #define DEBUG */
-#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/input.h>
#include <linux/slab.h>
@@ -220,7 +220,7 @@ static int pidff_rescale_signed(int i, struct hid_field *field)
static void pidff_set(struct pidff_usage *usage, u16 value)
{
usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
- debug("calculated from %d to %d", value, usage->value[0]);
+ pr_debug("calculated from %d to %d\n", value, usage->value[0]);
}
static void pidff_set_signed(struct pidff_usage *usage, s16 value)
@@ -235,7 +235,7 @@ static void pidff_set_signed(struct pidff_usage *usage, s16 value)
usage->value[0] =
pidff_rescale(value, 0x7fff, usage->field);
}
- debug("calculated from %d to %d", value, usage->value[0]);
+ pr_debug("calculated from %d to %d\n", value, usage->value[0]);
}
/*
@@ -259,8 +259,9 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
- debug("attack %u => %d", envelope->attack_level,
- pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
+ hid_dbg(pidff->hid, "attack %u => %d\n",
+ envelope->attack_level,
+ pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
USB_DIR_OUT);
@@ -466,33 +467,33 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
pidff->create_new_effect_type->value[0] = efnum;
usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
USB_DIR_OUT);
- debug("create_new_effect sent, type: %d", efnum);
+ hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum);
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
pidff->block_load_status->value[0] = 0;
usbhid_wait_io(pidff->hid);
for (j = 0; j < 60; j++) {
- debug("pid_block_load requested");
+ hid_dbg(pidff->hid, "pid_block_load requested\n");
usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
USB_DIR_IN);
usbhid_wait_io(pidff->hid);
if (pidff->block_load_status->value[0] ==
pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
- debug("device reported free memory: %d bytes",
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+ hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
return 0;
}
if (pidff->block_load_status->value[0] ==
pidff->status_id[PID_BLOCK_LOAD_FULL]) {
- debug("not enough memory free: %d bytes",
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+ hid_dbg(pidff->hid, "not enough memory free: %d bytes\n",
+ pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
return -ENOSPC;
}
}
- printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n");
+ hid_err(pidff->hid, "pid_block_load failed 60 times\n");
return -EIO;
}
@@ -546,7 +547,8 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id)
struct pidff_device *pidff = dev->ff->private;
int pid_id = pidff->pid_id[effect_id];
- debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]);
+ hid_dbg(pidff->hid, "starting to erase %d/%d\n",
+ effect_id, pidff->pid_id[effect_id]);
/* Wait for the queue to clear. We do not want a full fifo to
prevent the effect removal. */
usbhid_wait_io(pidff->hid);
@@ -604,8 +606,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
type_id = PID_SAW_DOWN;
break;
default:
- printk(KERN_ERR
- "hid-pidff: invalid waveform\n");
+ hid_err(pidff->hid, "invalid waveform\n");
return -EINVAL;
}
@@ -696,7 +697,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
break;
default:
- printk(KERN_ERR "hid-pidff: invalid type\n");
+ hid_err(pidff->hid, "invalid type\n");
return -EINVAL;
}
@@ -704,7 +705,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
pidff->pid_id[effect->id] =
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
- debug("uploaded");
+ hid_dbg(pidff->hid, "uploaded\n");
return 0;
}
@@ -770,14 +771,14 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
for (i = 0; i < report->maxfield; i++) {
if (report->field[i]->maxusage !=
report->field[i]->report_count) {
- debug("maxusage and report_count do not match, "
- "skipping");
+ pr_debug("maxusage and report_count do not match, skipping\n");
continue;
}
for (j = 0; j < report->field[i]->maxusage; j++) {
if (report->field[i]->usage[j].hid ==
(HID_UP_PID | table[k])) {
- debug("found %d at %d->%d", k, i, j);
+ pr_debug("found %d at %d->%d\n",
+ k, i, j);
usage[k].field = report->field[i];
usage[k].value =
&report->field[i]->value[j];
@@ -789,7 +790,7 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
break;
}
if (!found && strict) {
- debug("failed to locate %d", k);
+ pr_debug("failed to locate %d\n", k);
return -1;
}
}
@@ -826,8 +827,8 @@ static void pidff_find_reports(struct hid_device *hid, int report_type,
continue;
ret = pidff_check_usage(report->field[0]->logical);
if (ret != -1) {
- debug("found usage 0x%02x from field->logical",
- pidff_reports[ret]);
+ hid_dbg(hid, "found usage 0x%02x from field->logical\n",
+ pidff_reports[ret]);
pidff->reports[ret] = report;
continue;
}
@@ -845,8 +846,9 @@ static void pidff_find_reports(struct hid_device *hid, int report_type,
continue;
ret = pidff_check_usage(hid->collection[i - 1].usage);
if (ret != -1 && !pidff->reports[ret]) {
- debug("found usage 0x%02x from collection array",
- pidff_reports[ret]);
+ hid_dbg(hid,
+ "found usage 0x%02x from collection array\n",
+ pidff_reports[ret]);
pidff->reports[ret] = report;
}
}
@@ -861,7 +863,7 @@ static int pidff_reports_ok(struct pidff_device *pidff)
for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
if (!pidff->reports[i]) {
- debug("%d missing", i);
+ hid_dbg(pidff->hid, "%d missing\n", i);
return 0;
}
}
@@ -884,8 +886,7 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report,
report->field[i]->logical_minimum == 1)
return report->field[i];
else {
- printk(KERN_ERR "hid-pidff: logical_minimum "
- "is not 1 as it should be\n");
+ pr_err("logical_minimum is not 1 as it should be\n");
return NULL;
}
}
@@ -924,7 +925,7 @@ static int pidff_find_special_keys(int *keys, struct hid_field *fld,
*/
static int pidff_find_special_fields(struct pidff_device *pidff)
{
- debug("finding special fields");
+ hid_dbg(pidff->hid, "finding special fields\n");
pidff->create_new_effect_type =
pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
@@ -945,32 +946,30 @@ static int pidff_find_special_fields(struct pidff_device *pidff)
pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
0x78, 1);
- debug("search done");
+ hid_dbg(pidff->hid, "search done\n");
if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
- printk(KERN_ERR "hid-pidff: effect lists not found\n");
+ hid_err(pidff->hid, "effect lists not found\n");
return -1;
}
if (!pidff->effect_direction) {
- printk(KERN_ERR "hid-pidff: direction field not found\n");
+ hid_err(pidff->hid, "direction field not found\n");
return -1;
}
if (!pidff->device_control) {
- printk(KERN_ERR "hid-pidff: device control field not found\n");
+ hid_err(pidff->hid, "device control field not found\n");
return -1;
}
if (!pidff->block_load_status) {
- printk(KERN_ERR
- "hid-pidff: block load status field not found\n");
+ hid_err(pidff->hid, "block load status field not found\n");
return -1;
}
if (!pidff->effect_operation_status) {
- printk(KERN_ERR
- "hid-pidff: effect operation field not found\n");
+ hid_err(pidff->hid, "effect operation field not found\n");
return -1;
}
@@ -982,23 +981,22 @@ static int pidff_find_special_fields(struct pidff_device *pidff)
if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
effect_types)) {
- printk(KERN_ERR "hid-pidff: no effect types found\n");
+ hid_err(pidff->hid, "no effect types found\n");
return -1;
}
if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
block_load_status) !=
sizeof(pidff_block_load_status)) {
- printk(KERN_ERR
- "hidpidff: block load status identifiers not found\n");
+ hid_err(pidff->hid,
+ "block load status identifiers not found\n");
return -1;
}
if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
effect_operation_status) !=
sizeof(pidff_effect_operation_status)) {
- printk(KERN_ERR
- "hidpidff: effect operation identifiers not found\n");
+ hid_err(pidff->hid, "effect operation identifiers not found\n");
return -1;
}
@@ -1017,8 +1015,8 @@ static int pidff_find_effects(struct pidff_device *pidff,
int pidff_type = pidff->type_id[i];
if (pidff->set_effect_type->usage[pidff_type].hid !=
pidff->create_new_effect_type->usage[pidff_type].hid) {
- printk(KERN_ERR "hid-pidff: "
- "effect type number %d is invalid\n", i);
+ hid_err(pidff->hid,
+ "effect type number %d is invalid\n", i);
return -1;
}
}
@@ -1073,27 +1071,23 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
int envelope_ok = 0;
if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
- printk(KERN_ERR
- "hid-pidff: unknown set_effect report layout\n");
+ hid_err(pidff->hid, "unknown set_effect report layout\n");
return -ENODEV;
}
PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
- printk(KERN_ERR
- "hid-pidff: unknown pid_block_load report layout\n");
+ hid_err(pidff->hid, "unknown pid_block_load report layout\n");
return -ENODEV;
}
if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
- printk(KERN_ERR
- "hid-pidff: unknown effect_operation report layout\n");
+ hid_err(pidff->hid, "unknown effect_operation report layout\n");
return -ENODEV;
}
if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
- printk(KERN_ERR
- "hid-pidff: unknown pid_block_free report layout\n");
+ hid_err(pidff->hid, "unknown pid_block_free report layout\n");
return -ENODEV;
}
@@ -1105,27 +1099,26 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
if (!envelope_ok) {
if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
- printk(KERN_WARNING "hid-pidff: "
- "has constant effect but no envelope\n");
+ hid_warn(pidff->hid,
+ "has constant effect but no envelope\n");
if (test_and_clear_bit(FF_RAMP, dev->ffbit))
- printk(KERN_WARNING "hid-pidff: "
- "has ramp effect but no envelope\n");
+ hid_warn(pidff->hid,
+ "has ramp effect but no envelope\n");
if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
- printk(KERN_WARNING "hid-pidff: "
- "has periodic effect but no envelope\n");
+ hid_warn(pidff->hid,
+ "has periodic effect but no envelope\n");
}
if (test_bit(FF_CONSTANT, dev->ffbit) &&
PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
- printk(KERN_WARNING
- "hid-pidff: unknown constant effect layout\n");
+ hid_warn(pidff->hid, "unknown constant effect layout\n");
clear_bit(FF_CONSTANT, dev->ffbit);
}
if (test_bit(FF_RAMP, dev->ffbit) &&
PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
- printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n");
+ hid_warn(pidff->hid, "unknown ramp effect layout\n");
clear_bit(FF_RAMP, dev->ffbit);
}
@@ -1134,8 +1127,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
test_bit(FF_FRICTION, dev->ffbit) ||
test_bit(FF_INERTIA, dev->ffbit)) &&
PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
- printk(KERN_WARNING
- "hid-pidff: unknown condition effect layout\n");
+ hid_warn(pidff->hid, "unknown condition effect layout\n");
clear_bit(FF_SPRING, dev->ffbit);
clear_bit(FF_DAMPER, dev->ffbit);
clear_bit(FF_FRICTION, dev->ffbit);
@@ -1144,8 +1136,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
if (test_bit(FF_PERIODIC, dev->ffbit) &&
PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
- printk(KERN_WARNING
- "hid-pidff: unknown periodic effect layout\n");
+ hid_warn(pidff->hid, "unknown periodic effect layout\n");
clear_bit(FF_PERIODIC, dev->ffbit);
}
@@ -1184,12 +1175,12 @@ static void pidff_reset(struct pidff_device *pidff)
if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
if (i++ > 20) {
- printk(KERN_WARNING "hid-pidff: device reports "
- "%d simultaneous effects\n",
- pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
+ hid_warn(pidff->hid,
+ "device reports %d simultaneous effects\n",
+ pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
break;
}
- debug("pid_pool requested again");
+ hid_dbg(pidff->hid, "pid_pool requested again\n");
usbhid_submit_report(hid, pidff->reports[PID_POOL],
USB_DIR_IN);
usbhid_wait_io(hid);
@@ -1215,7 +1206,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff,
error = pidff_request_effect_upload(pidff, 1);
if (error) {
- printk(KERN_ERR "hid-pidff: upload request failed\n");
+ hid_err(pidff->hid, "upload request failed\n");
return error;
}
@@ -1224,8 +1215,8 @@ static int pidff_check_autocenter(struct pidff_device *pidff,
pidff_autocenter(pidff, 0xffff);
set_bit(FF_AUTOCENTER, dev->ffbit);
} else {
- printk(KERN_NOTICE "hid-pidff: "
- "device has unknown autocenter control method\n");
+ hid_notice(pidff->hid,
+ "device has unknown autocenter control method\n");
}
pidff_erase_pid(pidff,
@@ -1248,10 +1239,10 @@ int hid_pidff_init(struct hid_device *hid)
int max_effects;
int error;
- debug("starting pid init");
+ hid_dbg(hid, "starting pid init\n");
if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
- debug("not a PID device, no output report");
+ hid_dbg(hid, "not a PID device, no output report\n");
return -ENODEV;
}
@@ -1265,7 +1256,7 @@ int hid_pidff_init(struct hid_device *hid)
pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
if (!pidff_reports_ok(pidff)) {
- debug("reports not ok, aborting");
+ hid_dbg(hid, "reports not ok, aborting\n");
error = -ENODEV;
goto fail;
}
@@ -1278,8 +1269,8 @@ int hid_pidff_init(struct hid_device *hid)
if (test_bit(FF_GAIN, dev->ffbit)) {
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
- usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
- USB_DIR_OUT);
+ usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN],
+ USB_DIR_OUT);
}
error = pidff_check_autocenter(pidff, dev);
@@ -1290,23 +1281,23 @@ int hid_pidff_init(struct hid_device *hid)
pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
1;
- debug("max effects is %d", max_effects);
+ hid_dbg(hid, "max effects is %d\n", max_effects);
if (max_effects > PID_EFFECTS_MAX)
max_effects = PID_EFFECTS_MAX;
if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
- debug("max simultaneous effects is %d",
- pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
+ hid_dbg(hid, "max simultaneous effects is %d\n",
+ pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
if (pidff->pool[PID_RAM_POOL_SIZE].value)
- debug("device memory size is %d bytes",
- pidff->pool[PID_RAM_POOL_SIZE].value[0]);
+ hid_dbg(hid, "device memory size is %d bytes\n",
+ pidff->pool[PID_RAM_POOL_SIZE].value[0]);
if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
- printk(KERN_NOTICE "hid-pidff: "
- "device does not support device managed pool\n");
+ hid_notice(hid,
+ "device does not support device managed pool\n");
goto fail;
}
@@ -1322,8 +1313,7 @@ int hid_pidff_init(struct hid_device *hid)
ff->set_autocenter = pidff_set_autocenter;
ff->playback = pidff_playback;
- printk(KERN_INFO "Force feedback for USB HID PID devices by "
- "Anssi Hannula <anssi.hannula@gmail.com>\n");
+ hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
return 0;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 2c185477eeb3..76b9a149c7df 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -85,7 +85,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
-
+ { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
{ 0, 0 }
};
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 984feb351a5a..af0a7c1002af 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -585,163 +585,168 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev;
- struct hid_device *hid = hiddev->hid;
- struct usb_device *dev;
+ struct hid_device *hid;
struct hiddev_collection_info cinfo;
struct hiddev_report_info rinfo;
struct hiddev_field_info finfo;
struct hiddev_devinfo dinfo;
struct hid_report *report;
struct hid_field *field;
- struct usbhid_device *usbhid = hid->driver_data;
void __user *user_arg = (void __user *)arg;
- int i, r;
-
+ int i, r = -EINVAL;
+
/* Called without BKL by compat methods so no BKL taken */
- /* FIXME: Who or what stop this racing with a disconnect ?? */
- if (!hiddev->exist || !hid)
- return -EIO;
+ mutex_lock(&hiddev->existancelock);
+ if (!hiddev->exist) {
+ r = -ENODEV;
+ goto ret_unlock;
+ }
- dev = hid_to_usb_dev(hid);
+ hid = hiddev->hid;
switch (cmd) {
case HIDIOCGVERSION:
- return put_user(HID_VERSION, (int __user *)arg);
+ r = put_user(HID_VERSION, (int __user *)arg) ?
+ -EFAULT : 0;
+ break;
case HIDIOCAPPLICATION:
if (arg < 0 || arg >= hid->maxapplication)
- return -EINVAL;
+ break;
for (i = 0; i < hid->maxcollection; i++)
if (hid->collection[i].type ==
HID_COLLECTION_APPLICATION && arg-- == 0)
break;
- if (i == hid->maxcollection)
- return -EINVAL;
-
- return hid->collection[i].usage;
+ if (i < hid->maxcollection)
+ r = hid->collection[i].usage;
+ break;
case HIDIOCGDEVINFO:
- dinfo.bustype = BUS_USB;
- dinfo.busnum = dev->bus->busnum;
- dinfo.devnum = dev->devnum;
- dinfo.ifnum = usbhid->ifnum;
- dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
- dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
- dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
- dinfo.num_applications = hid->maxapplication;
- if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
- return -EFAULT;
-
- return 0;
+ {
+ struct usb_device *dev = hid_to_usb_dev(hid);
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ dinfo.bustype = BUS_USB;
+ dinfo.busnum = dev->bus->busnum;
+ dinfo.devnum = dev->devnum;
+ dinfo.ifnum = usbhid->ifnum;
+ dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
+ dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
+ dinfo.num_applications = hid->maxapplication;
+
+ r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
+ -EFAULT : 0;
+ break;
+ }
case HIDIOCGFLAG:
- if (put_user(list->flags, (int __user *)arg))
- return -EFAULT;
-
- return 0;
+ r = put_user(list->flags, (int __user *)arg) ?
+ -EFAULT : 0;
+ break;
case HIDIOCSFLAG:
{
int newflags;
- if (get_user(newflags, (int __user *)arg))
- return -EFAULT;
+
+ if (get_user(newflags, (int __user *)arg)) {
+ r = -EFAULT;
+ break;
+ }
if ((newflags & ~HIDDEV_FLAGS) != 0 ||
((newflags & HIDDEV_FLAG_REPORT) != 0 &&
(newflags & HIDDEV_FLAG_UREF) == 0))
- return -EINVAL;
+ break;
list->flags = newflags;
- return 0;
+ r = 0;
+ break;
}
case HIDIOCGSTRING:
- mutex_lock(&hiddev->existancelock);
- if (hiddev->exist)
- r = hiddev_ioctl_string(hiddev, cmd, user_arg);
- else
- r = -ENODEV;
- mutex_unlock(&hiddev->existancelock);
- return r;
+ r = hiddev_ioctl_string(hiddev, cmd, user_arg);
+ break;
case HIDIOCINITREPORT:
- mutex_lock(&hiddev->existancelock);
- if (!hiddev->exist) {
- mutex_unlock(&hiddev->existancelock);
- return -ENODEV;
- }
usbhid_init_reports(hid);
- mutex_unlock(&hiddev->existancelock);
-
- return 0;
+ r = 0;
+ break;
case HIDIOCGREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
+ r = -EFAULT;
+ break;
+ }
if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
- return -EINVAL;
+ break;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
+ report = hiddev_lookup_report(hid, &rinfo);
+ if (report == NULL)
+ break;
- mutex_lock(&hiddev->existancelock);
- if (hiddev->exist) {
- usbhid_submit_report(hid, report, USB_DIR_IN);
- usbhid_wait_io(hid);
- }
- mutex_unlock(&hiddev->existancelock);
+ usbhid_submit_report(hid, report, USB_DIR_IN);
+ usbhid_wait_io(hid);
- return 0;
+ r = 0;
+ break;
case HIDIOCSREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
+ r = -EFAULT;
+ break;
+ }
if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
- return -EINVAL;
+ break;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
+ report = hiddev_lookup_report(hid, &rinfo);
+ if (report == NULL)
+ break;
- mutex_lock(&hiddev->existancelock);
- if (hiddev->exist) {
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- usbhid_wait_io(hid);
- }
- mutex_unlock(&hiddev->existancelock);
+ usbhid_submit_report(hid, report, USB_DIR_OUT);
+ usbhid_wait_io(hid);
- return 0;
+ r = 0;
+ break;
case HIDIOCGREPORTINFO:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
+ r = -EFAULT;
+ break;
+ }
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
+ report = hiddev_lookup_report(hid, &rinfo);
+ if (report == NULL)
+ break;
rinfo.num_fields = report->maxfield;
- if (copy_to_user(user_arg, &rinfo, sizeof(rinfo)))
- return -EFAULT;
-
- return 0;
+ r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
+ -EFAULT : 0;
+ break;
case HIDIOCGFIELDINFO:
- if (copy_from_user(&finfo, user_arg, sizeof(finfo)))
- return -EFAULT;
+ if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
+ r = -EFAULT;
+ break;
+ }
+
rinfo.report_type = finfo.report_type;
rinfo.report_id = finfo.report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
+
+ report = hiddev_lookup_report(hid, &rinfo);
+ if (report == NULL)
+ break;
if (finfo.field_index >= report->maxfield)
- return -EINVAL;
+ break;
field = report->field[finfo.field_index];
memset(&finfo, 0, sizeof(finfo));
@@ -760,10 +765,9 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
finfo.unit_exponent = field->unit_exponent;
finfo.unit = field->unit;
- if (copy_to_user(user_arg, &finfo, sizeof(finfo)))
- return -EFAULT;
-
- return 0;
+ r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
+ -EFAULT : 0;
+ break;
case HIDIOCGUCODE:
/* fall through */
@@ -772,57 +776,66 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case HIDIOCGUSAGES:
case HIDIOCSUSAGES:
case HIDIOCGCOLLECTIONINDEX:
- mutex_lock(&hiddev->existancelock);
- if (hiddev->exist)
- r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
- else
- r = -ENODEV;
- mutex_unlock(&hiddev->existancelock);
- return r;
+ r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
+ break;
case HIDIOCGCOLLECTIONINFO:
- if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
- return -EFAULT;
+ if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
+ r = -EFAULT;
+ break;
+ }
if (cinfo.index >= hid->maxcollection)
- return -EINVAL;
+ break;
cinfo.type = hid->collection[cinfo.index].type;
cinfo.usage = hid->collection[cinfo.index].usage;
cinfo.level = hid->collection[cinfo.index].level;
- if (copy_to_user(user_arg, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
+ r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
+ -EFAULT : 0;
+ break;
default:
-
if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
- return -EINVAL;
+ break;
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
int len;
- if (!hid->name)
- return 0;
+
+ if (!hid->name) {
+ r = 0;
+ break;
+ }
+
len = strlen(hid->name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->name, len) ?
+ r = copy_to_user(user_arg, hid->name, len) ?
-EFAULT : len;
+ break;
}
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
int len;
- if (!hid->phys)
- return 0;
+
+ if (!hid->phys) {
+ r = 0;
+ break;
+ }
+
len = strlen(hid->phys) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->phys, len) ?
+ r = copy_to_user(user_arg, hid->phys, len) ?
-EFAULT : len;
+ break;
}
}
- return -EINVAL;
+
+ret_unlock:
+ mutex_unlock(&hiddev->existancelock);
+ return r;
}
#ifdef CONFIG_COMPAT
@@ -892,7 +905,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hiddev->exist = 1;
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
- err_hid("Not able to get a minor for this device.");
+ hid_err(hid, "Not able to get a minor for this device\n");
hid->hiddev = NULL;
kfree(hiddev);
return -1;
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 89d2e847dcc6..1673cac93d77 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -95,7 +95,6 @@ struct usbhid_device {
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
- struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */
int ledcount; /* counting the number of active leds */
};
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index a948605564fb..065817329f03 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -24,6 +24,8 @@
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -104,16 +106,18 @@ static void usb_kbd_irq(struct urb *urb)
if (usb_kbd_keycode[kbd->old[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
else
- dev_info(&urb->dev->dev,
- "Unknown key (scancode %#x) released.\n", kbd->old[i]);
+ hid_info(urb->dev,
+ "Unknown key (scancode %#x) released.\n",
+ kbd->old[i]);
}
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
if (usb_kbd_keycode[kbd->new[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
else
- dev_info(&urb->dev->dev,
- "Unknown key (scancode %#x) released.\n", kbd->new[i]);
+ hid_info(urb->dev,
+ "Unknown key (scancode %#x) released.\n",
+ kbd->new[i]);
}
}
@@ -124,9 +128,9 @@ static void usb_kbd_irq(struct urb *urb)
resubmit:
i = usb_submit_urb (urb, GFP_ATOMIC);
if (i)
- err_hid ("can't resubmit intr, %s-%s/input0, status %d",
- kbd->usbdev->bus->bus_name,
- kbd->usbdev->devpath, i);
+ hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d",
+ kbd->usbdev->bus->bus_name,
+ kbd->usbdev->devpath, i);
}
static int usb_kbd_event(struct input_dev *dev, unsigned int type,
@@ -150,7 +154,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err_hid("usb_submit_urb(leds) failed");
+ pr_err("usb_submit_urb(leds) failed\n");
return 0;
}
@@ -160,7 +164,7 @@ static void usb_kbd_led(struct urb *urb)
struct usb_kbd *kbd = urb->context;
if (urb->status)
- dev_warn(&urb->dev->dev, "led urb status %d received\n",
+ hid_warn(urb->dev, "led urb status %d received\n",
urb->status);
if (*(kbd->leds) == kbd->newleds)
@@ -169,7 +173,7 @@ static void usb_kbd_led(struct urb *urb)
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err_hid("usb_submit_urb(leds) failed");
+ hid_err(urb->dev, "usb_submit_urb(leds) failed\n");
}
static int usb_kbd_open(struct input_dev *dev)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index a56f6adf3b76..5fcdbb4e1d5d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -274,6 +274,16 @@ config SENSORS_ATXP1
This driver can also be built as a module. If so, the module
will be called atxp1.
+config SENSORS_DS620
+ tristate "Dallas Semiconductor DS620"
+ depends on I2C
+ help
+ If you say yes here you get support for Dallas Semiconductor
+ DS620 sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called ds620.
+
config SENSORS_DS1621
tristate "Dallas Semiconductor DS1621 and DS1625"
depends on I2C
@@ -789,10 +799,10 @@ config SENSORS_DME1737
will be called dme1737.
config SENSORS_EMC1403
- tristate "SMSC EMC1403 thermal sensor"
+ tristate "SMSC EMC1403/23 thermal sensor"
depends on I2C
help
- If you say yes here you get support for the SMSC EMC1403
+ If you say yes here you get support for the SMSC EMC1403/23
temperature monitoring chip.
Threshold values can be configured using sysfs.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2479b3da272c..42542d7bebc0 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_PKGTEMP) += pkgtemp.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
+obj-$(CONFIG_SENSORS_DS620) += ds620.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 03694cc17a32..8f07a9dda152 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -20,6 +20,9 @@
the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because
of lack of specs the CPU/RAM voltage & frequency control is not supported!
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
@@ -220,6 +223,10 @@ struct abituguru_data {
u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5];
};
+static const char *never_happen = "This should never happen.";
+static const char *report_this =
+ "Please report this to the abituguru maintainer (see MAINTAINERS)";
+
/* wait till the uguru is in the specified state */
static int abituguru_wait(struct abituguru_data *data, u8 state)
{
@@ -438,8 +445,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
/* Test val is sane / usable for sensor type detection. */
if ((val < 10u) || (val > 250u)) {
- printk(KERN_WARNING ABIT_UGURU_NAME
- ": bank1-sensor: %d reading (%d) too close to limits, "
+ pr_warn("bank1-sensor: %d reading (%d) too close to limits, "
"unable to determine sensor type, skipping sensor\n",
(int)sensor_addr, (int)val);
/* assume no sensor is there for sensors for which we can't
@@ -535,10 +541,8 @@ abituguru_detect_bank1_sensor_type_exit:
3) == 3)
break;
if (i == 3) {
- printk(KERN_ERR ABIT_UGURU_NAME
- ": Fatal error could not restore original settings. "
- "This should never happen please report this to the "
- "abituguru maintainer (see MAINTAINERS)\n");
+ pr_err("Fatal error could not restore original settings. %s %s\n",
+ never_happen, report_this);
return -ENODEV;
}
return ret;
@@ -1268,14 +1272,12 @@ static int __devinit abituguru_probe(struct platform_device *pdev)
}
/* Fail safe check, this should never happen! */
if (sysfs_names_free < 0) {
- printk(KERN_ERR ABIT_UGURU_NAME ": Fatal error ran out of "
- "space for sysfs attr names. This should never "
- "happen please report to the abituguru maintainer "
- "(see MAINTAINERS)\n");
+ pr_err("Fatal error ran out of space for sysfs attr names. %s %s",
+ never_happen, report_this);
res = -ENAMETOOLONG;
goto abituguru_probe_error;
}
- printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n");
+ pr_info("found Abit uGuru\n");
/* Register sysfs hooks */
for (i = 0; i < sysfs_attr_i; i++)
@@ -1432,8 +1434,7 @@ static int __init abituguru_detect(void)
"0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
if (force) {
- printk(KERN_INFO ABIT_UGURU_NAME ": Assuming Abit uGuru is "
- "present because of \"force\" parameter\n");
+ pr_info("Assuming Abit uGuru is present because of \"force\" parameter\n");
return ABIT_UGURU_BASE;
}
@@ -1467,8 +1468,7 @@ static int __init abituguru_init(void)
abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address);
if (!abituguru_pdev) {
- printk(KERN_ERR ABIT_UGURU_NAME
- ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
err = -ENOMEM;
goto exit_driver_unregister;
}
@@ -1479,15 +1479,13 @@ static int __init abituguru_init(void)
err = platform_device_add_resources(abituguru_pdev, &res, 1);
if (err) {
- printk(KERN_ERR ABIT_UGURU_NAME
- ": Device resource addition failed (%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(abituguru_pdev);
if (err) {
- printk(KERN_ERR ABIT_UGURU_NAME
- ": Device addition failed (%d)\n", err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index 3cf28af614b5..48d21e22e930 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -23,6 +23,9 @@
chip found on newer Abit uGuru motherboards. Note: because of lack of specs
only reading the sensors and their settings is supported.
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -608,6 +611,9 @@ static int verbose = 1;
module_param(verbose, bool, 0644);
MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting");
+static const char *never_happen = "This should never happen.";
+static const char *report_this =
+ "Please report this to the abituguru3 maintainer (see MAINTAINERS)";
/* wait while the uguru is busy (usually after a write) */
static int abituguru3_wait_while_busy(struct abituguru3_data *data)
@@ -940,15 +946,13 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
if (abituguru3_motherboards[i].id == id)
break;
if (!abituguru3_motherboards[i].id) {
- printk(KERN_ERR ABIT_UGURU3_NAME ": error unknown motherboard "
- "ID: %04X. Please report this to the abituguru3 "
- "maintainer (see MAINTAINERS)\n", (unsigned int)id);
+ pr_err("error unknown motherboard ID: %04X. %s\n",
+ (unsigned int)id, report_this);
goto abituguru3_probe_error;
}
data->sensors = abituguru3_motherboards[i].sensors;
- printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
- "ID: %04X\n", (unsigned int)id);
+ pr_info("found Abit uGuru3, motherboard ID: %04X\n", (unsigned int)id);
/* Fill the sysfs attr array */
sysfs_attr_i = 0;
@@ -957,11 +961,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
for (i = 0; data->sensors[i].name; i++) {
/* Fail safe check, this should never happen! */
if (i >= ABIT_UGURU3_MAX_NO_SENSORS) {
- printk(KERN_ERR ABIT_UGURU3_NAME
- ": Fatal error motherboard has more sensors "
- "then ABIT_UGURU3_MAX_NO_SENSORS. This should "
- "never happen please report to the abituguru3 "
- "maintainer (see MAINTAINERS)\n");
+ pr_err("Fatal error motherboard has more sensors then ABIT_UGURU3_MAX_NO_SENSORS. %s %s\n",
+ never_happen, report_this);
res = -ENAMETOOLONG;
goto abituguru3_probe_error;
}
@@ -983,10 +984,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
}
/* Fail safe check, this should never happen! */
if (sysfs_names_free < 0) {
- printk(KERN_ERR ABIT_UGURU3_NAME
- ": Fatal error ran out of space for sysfs attr names. "
- "This should never happen please report to the "
- "abituguru3 maintainer (see MAINTAINERS)\n");
+ pr_err("Fatal error ran out of space for sysfs attr names. %s %s\n",
+ never_happen, report_this);
res = -ENAMETOOLONG;
goto abituguru3_probe_error;
}
@@ -1189,8 +1188,7 @@ static int __init abituguru3_detect(void)
"0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
if (force) {
- printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is "
- "present because of \"force\" parameter\n");
+ pr_info("Assuming Abit uGuru3 is present because of \"force\" parameter\n");
return 0;
}
@@ -1219,10 +1217,8 @@ static int __init abituguru3_init(void)
return err;
#ifdef CONFIG_DMI
- printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
- "not detected using DMI. Please send the output of "
- "\"dmidecode\" to the abituguru3 maintainer "
- "(see MAINTAINERS)\n");
+ pr_warn("this motherboard was not detected using DMI. "
+ "Please send the output of \"dmidecode\" to the abituguru3 maintainer (see MAINTAINERS)\n");
#endif
}
@@ -1233,8 +1229,7 @@ static int __init abituguru3_init(void)
abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME,
ABIT_UGURU3_BASE);
if (!abituguru3_pdev) {
- printk(KERN_ERR ABIT_UGURU3_NAME
- ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
err = -ENOMEM;
goto exit_driver_unregister;
}
@@ -1245,15 +1240,13 @@ static int __init abituguru3_init(void)
err = platform_device_add_resources(abituguru3_pdev, &res, 1);
if (err) {
- printk(KERN_ERR ABIT_UGURU3_NAME
- ": Device resource addition failed (%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(abituguru3_pdev);
if (err) {
- printk(KERN_ERR ABIT_UGURU3_NAME
- ": Device addition failed (%d)\n", err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 4bf969c0a32b..be0fdd58aa29 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val, orig_div, new_div, shift;
+ int val, orig_div, new_div;
val = simple_strtol(buf, NULL, 10);
new_div = DIV_TO_REG(val);
- if (new_div == 0) {
- return -EINVAL;
- }
+
mutex_lock(&data->update_lock);
orig_div = data->fan_div[nr];
data->fan_div[nr] = DIV_FROM_REG(new_div);
if (nr < 4) { /* 0 <= nr < 4 */
- shift = 2 * nr;
adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
- ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
- (new_div << shift)));
+ (DIV_TO_REG(data->fan_div[0]) << 0) |
+ (DIV_TO_REG(data->fan_div[1]) << 2) |
+ (DIV_TO_REG(data->fan_div[2]) << 4) |
+ (DIV_TO_REG(data->fan_div[3]) << 6));
} else { /* 3 < nr < 8 */
- shift = 2 * (nr - 4);
adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
- ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
- (new_div << shift)));
+ (DIV_TO_REG(data->fan_div[4]) << 0) |
+ (DIV_TO_REG(data->fan_div[5]) << 2) |
+ (DIV_TO_REG(data->fan_div[6]) << 4) |
+ (DIV_TO_REG(data->fan_div[7]) << 6));
}
if (data->fan_div[nr] != orig_div) {
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 0727ad250793..9e234b981b83 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -20,7 +20,7 @@
* Alarms 16-bit map of active alarms
* Analog Out 0..1250 mV output
*
- * Chassis Intrusion: clear CI latch with 'echo 1 > chassis_clear'
+ * Chassis Intrusion: clear CI latch with 'echo 0 > intrusion0_alarm'
*
* Test hardware: Intel SE440BX-2 desktop motherboard --Grant
*
@@ -476,13 +476,16 @@ static ssize_t set_aout(struct device *dev,
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
/* chassis_clear */
-static ssize_t chassis_clear(struct device *dev,
+static ssize_t chassis_clear_legacy(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
unsigned long val = simple_strtol(buf, NULL, 10);
+ dev_warn(dev, "Attribute chassis_clear is deprecated, "
+ "use intrusion0_alarm instead\n");
+
if (val == 1) {
i2c_smbus_write_byte_data(client,
ADM9240_REG_CHASSIS_CLEAR, 0x80);
@@ -490,7 +493,29 @@ static ssize_t chassis_clear(struct device *dev,
}
return count;
}
-static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear);
+static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear_legacy);
+
+static ssize_t chassis_clear(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adm9240_data *data = i2c_get_clientdata(client);
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) || val != 0)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_CHASSIS_CLEAR, 0x80);
+ data->valid = 0; /* Force cache refresh */
+ mutex_unlock(&data->update_lock);
+ dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
+
+ return count;
+}
+static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm,
+ chassis_clear, 12);
static struct attribute *adm9240_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
@@ -532,6 +557,7 @@ static struct attribute *adm9240_attributes[] = {
&dev_attr_alarms.attr,
&dev_attr_aout_output.attr,
&dev_attr_chassis_clear.attr,
+ &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
&dev_attr_cpu0_vid.attr,
NULL
};
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index aac85f3aed50..c42c5a69a664 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -4,7 +4,7 @@
This driver is based on the lm75 and other lm_sensors/hwmon drivers
- Written by Steve Hardy <steve@linuxrealtime.co.uk>
+ Written by Steve Hardy <shardy@redhat.com>
Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf
@@ -271,7 +271,7 @@ static void __exit sensors_ads7828_exit(void)
i2c_del_driver(&ads7828_driver);
}
-MODULE_AUTHOR("Steve Hardy <steve@linuxrealtime.co.uk>");
+MODULE_AUTHOR("Steve Hardy <shardy@redhat.com>");
MODULE_DESCRIPTION("ADS7828 driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 87d92a56a939..c6d1ce059aea 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
@@ -274,7 +276,7 @@ static int adt7470_read_temperatures(struct i2c_client *client,
i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]);
if (res) {
- printk(KERN_ERR "ha ha, interrupted");
+ pr_err("ha ha, interrupted\n");
return -EAGAIN;
}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b6598aa557a0..ce0372f0615e 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -4,6 +4,7 @@
* computers.
*
* Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
+ * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
*
* Based on hdaps.c driver:
* Copyright (C) 2005 Robert Love <rml@novell.com>
@@ -26,10 +27,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
@@ -49,6 +53,7 @@
#define APPLESMC_MAX_DATA_LENGTH 32
+/* wait up to 32 ms for a status change. */
#define APPLESMC_MIN_WAIT 0x0040
#define APPLESMC_MAX_WAIT 0x8000
@@ -73,104 +78,15 @@
#define FANS_COUNT "FNum" /* r-o ui8 */
#define FANS_MANUAL "FS! " /* r-w ui16 */
-#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
-#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
-#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
-#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
-#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
-#define FAN_POSITION "F0ID" /* r-o char[16] */
-
-/*
- * Temperature sensors keys (sp78 - 2 bytes).
- */
-static const char *temperature_sensors_sets[][41] = {
-/* Set 0: Macbook Pro */
- { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
- "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
-/* Set 1: Macbook2 set */
- { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
- "Th0S", "Th1H", NULL },
-/* Set 2: Macbook set */
- { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
- "Th1H", "Ts0P", NULL },
-/* Set 3: Macmini set */
- { "TC0D", "TC0P", NULL },
-/* Set 4: Mac Pro (2 x Quad-Core) */
- { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
- "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
- "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
- "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
- "TM9S", "TN0H", "TS0C", NULL },
-/* Set 5: iMac */
- { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
- "Tp0C", NULL },
-/* Set 6: Macbook3 set */
- { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
- "Th0S", "Th1H", NULL },
-/* Set 7: Macbook Air */
- { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
- "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
-/* Set 8: Macbook Pro 4,1 (Penryn) */
- { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
- "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
-/* Set 9: Macbook Pro 3,1 (Santa Rosa) */
- { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
- "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
-/* Set 10: iMac 5,1 */
- { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
-/* Set 11: Macbook 5,1 */
- { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
- "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
-/* Set 12: Macbook Pro 5,1 */
- { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
- "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0",
- "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL },
-/* Set 13: iMac 8,1 */
- { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
- "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
-/* Set 14: iMac 6,1 */
- { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
- "TO0P", "Tp0P", NULL },
-/* Set 15: MacBook Air 2,1 */
- { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
- "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
- "Ts0S", NULL },
-/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
- { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
- "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
- "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
- "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 },
-/* Set 19: Macbook Pro 5,3 */
- { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
- "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H",
- "Tm0P", "Ts0P", "Ts0S", NULL },
-/* Set 20: MacBook Pro 5,4 */
- { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D",
- "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL },
-/* Set 21: MacBook Pro 6,2 */
- { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D",
- "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P",
- "Ts0P", "Ts0S", NULL },
-/* Set 22: MacBook Pro 7,1 */
- { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
- "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
-};
+#define FAN_ID_FMT "F%dID" /* r-o char[16] */
/* List of keys used to read/write fan speeds */
-static const char* fan_speed_keys[] = {
- FAN_ACTUAL_SPEED,
- FAN_MIN_SPEED,
- FAN_MAX_SPEED,
- FAN_SAFE_SPEED,
- FAN_TARGET_SPEED
+static const char *const fan_speed_fmt[] = {
+ "F%dAc", /* actual speed */
+ "F%dMn", /* minimum speed (rw) */
+ "F%dMx", /* maximum speed */
+ "F%dSf", /* safe speed - not all models */
+ "F%dTg", /* target speed (manual: rw) */
};
#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
@@ -184,14 +100,48 @@ static const char* fan_speed_keys[] = {
#define SENSOR_Y 1
#define SENSOR_Z 2
-/* Structure to be passed to DMI_MATCH function */
-struct dmi_match_data {
-/* Indicates whether this computer has an accelerometer. */
- int accelerometer;
-/* Indicates whether this computer has light sensors and keyboard backlight. */
- int light;
-/* Indicates which temperature sensors set to use. */
- int temperature_set;
+#define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff)
+#define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16)
+
+/* Dynamic device node attributes */
+struct applesmc_dev_attr {
+ struct sensor_device_attribute sda; /* hwmon attributes */
+ char name[32]; /* room for node file name */
+};
+
+/* Dynamic device node group */
+struct applesmc_node_group {
+ char *format; /* format string */
+ void *show; /* show function */
+ void *store; /* store function */
+ int option; /* function argument */
+ struct applesmc_dev_attr *nodes; /* dynamic node array */
+};
+
+/* AppleSMC entry - cached register information */
+struct applesmc_entry {
+ char key[5]; /* four-letter key code */
+ u8 valid; /* set when entry is successfully read once */
+ u8 len; /* bounded by APPLESMC_MAX_DATA_LENGTH */
+ char type[5]; /* four-letter type code */
+ u8 flags; /* 0x10: func; 0x40: write; 0x80: read */
+};
+
+/* Register lookup and registers common to all SMCs */
+static struct applesmc_registers {
+ struct mutex mutex; /* register read/write mutex */
+ unsigned int key_count; /* number of SMC registers */
+ unsigned int fan_count; /* number of fans */
+ unsigned int temp_count; /* number of temperature registers */
+ unsigned int temp_begin; /* temperature lower index bound */
+ unsigned int temp_end; /* temperature upper index bound */
+ int num_light_sensors; /* number of light sensors */
+ bool has_accelerometer; /* has motion sensor */
+ bool has_key_backlight; /* has keyboard backlight */
+ bool init_complete; /* true when fully initialized */
+ struct applesmc_entry *cache; /* cached key entries */
+} smcreg = {
+ .mutex = __MUTEX_INITIALIZER(smcreg.mutex),
};
static const int debug;
@@ -203,20 +153,6 @@ static u8 backlight_state[2];
static struct device *hwmon_dev;
static struct input_polled_dev *applesmc_idev;
-/* Indicates whether this computer has an accelerometer. */
-static unsigned int applesmc_accelerometer;
-
-/* Indicates whether this computer has light sensors and keyboard backlight. */
-static unsigned int applesmc_light;
-
-/* The number of fans handled by the driver */
-static unsigned int fans_handled;
-
-/* Indicates which temperature sensors set to use. */
-static unsigned int applesmc_temperature_set;
-
-static DEFINE_MUTEX(applesmc_lock);
-
/*
* Last index written to key_at_index sysfs file, and value to use for all other
* key_at_index_* sysfs files.
@@ -238,18 +174,10 @@ static int __wait_status(u8 val)
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
udelay(us);
- if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
- if (debug)
- printk(KERN_DEBUG
- "Waited %d us for status %x\n",
- 2 * us - APPLESMC_MIN_WAIT, val);
+ if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val)
return 0;
- }
}
- printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
- val, inb(APPLESMC_CMD_PORT));
-
return -EIO;
}
@@ -267,159 +195,242 @@ static int send_command(u8 cmd)
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
return 0;
}
- printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
- cmd, inb(APPLESMC_CMD_PORT));
return -EIO;
}
-/*
- * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
- * Returns zero on success or a negative error on failure. Callers must
- * hold applesmc_lock.
- */
-static int applesmc_read_key(const char* key, u8* buffer, u8 len)
+static int send_argument(const char *key)
{
int i;
- if (len > APPLESMC_MAX_DATA_LENGTH) {
- printk(KERN_ERR "applesmc_read_key: cannot read more than "
- "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
- return -EINVAL;
- }
-
- if (send_command(APPLESMC_READ_CMD))
- return -EIO;
-
for (i = 0; i < 4; i++) {
outb(key[i], APPLESMC_DATA_PORT);
if (__wait_status(0x04))
return -EIO;
}
- if (debug)
- printk(KERN_DEBUG "<%s", key);
+ return 0;
+}
+
+static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
+{
+ int i;
+
+ if (send_command(cmd) || send_argument(key)) {
+ pr_warn("%s: read arg fail\n", key);
+ return -EIO;
+ }
outb(len, APPLESMC_DATA_PORT);
- if (debug)
- printk(KERN_DEBUG ">%x", len);
for (i = 0; i < len; i++) {
- if (__wait_status(0x05))
+ if (__wait_status(0x05)) {
+ pr_warn("%s: read data fail\n", key);
return -EIO;
+ }
buffer[i] = inb(APPLESMC_DATA_PORT);
- if (debug)
- printk(KERN_DEBUG "<%x", buffer[i]);
}
- if (debug)
- printk(KERN_DEBUG "\n");
return 0;
}
-/*
- * applesmc_write_key - writes len bytes from buffer to a given key.
- * Returns zero on success or a negative error on failure. Callers must
- * hold applesmc_lock.
- */
-static int applesmc_write_key(const char* key, u8* buffer, u8 len)
+static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
{
int i;
- if (len > APPLESMC_MAX_DATA_LENGTH) {
- printk(KERN_ERR "applesmc_write_key: cannot write more than "
- "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
- return -EINVAL;
- }
-
- if (send_command(APPLESMC_WRITE_CMD))
+ if (send_command(cmd) || send_argument(key)) {
+ pr_warn("%s: write arg fail\n", key);
return -EIO;
-
- for (i = 0; i < 4; i++) {
- outb(key[i], APPLESMC_DATA_PORT);
- if (__wait_status(0x04))
- return -EIO;
}
outb(len, APPLESMC_DATA_PORT);
for (i = 0; i < len; i++) {
- if (__wait_status(0x04))
+ if (__wait_status(0x04)) {
+ pr_warn("%s: write data fail\n", key);
return -EIO;
+ }
outb(buffer[i], APPLESMC_DATA_PORT);
}
return 0;
}
+static int read_register_count(unsigned int *count)
+{
+ __be32 be;
+ int ret;
+
+ ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
+ if (ret)
+ return ret;
+
+ *count = be32_to_cpu(be);
+ return 0;
+}
+
/*
- * applesmc_get_key_at_index - get key at index, and put the result in key
- * (char[6]). Returns zero on success or a negative error on failure. Callers
- * must hold applesmc_lock.
+ * Serialized I/O
+ *
+ * Returns zero on success or a negative error on failure.
+ * All functions below are concurrency safe - callers should NOT hold lock.
*/
-static int applesmc_get_key_at_index(int index, char* key)
+
+static int applesmc_read_entry(const struct applesmc_entry *entry,
+ u8 *buf, u8 len)
{
- int i;
- u8 readkey[4];
- readkey[0] = index >> 24;
- readkey[1] = index >> 16;
- readkey[2] = index >> 8;
- readkey[3] = index;
+ int ret;
- if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
- return -EIO;
+ if (entry->len != len)
+ return -EINVAL;
+ mutex_lock(&smcreg.mutex);
+ ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len);
+ mutex_unlock(&smcreg.mutex);
- for (i = 0; i < 4; i++) {
- outb(readkey[i], APPLESMC_DATA_PORT);
- if (__wait_status(0x04))
- return -EIO;
+ return ret;
+}
+
+static int applesmc_write_entry(const struct applesmc_entry *entry,
+ const u8 *buf, u8 len)
+{
+ int ret;
+
+ if (entry->len != len)
+ return -EINVAL;
+ mutex_lock(&smcreg.mutex);
+ ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len);
+ mutex_unlock(&smcreg.mutex);
+ return ret;
+}
+
+static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
+{
+ struct applesmc_entry *cache = &smcreg.cache[index];
+ u8 key[4], info[6];
+ __be32 be;
+ int ret = 0;
+
+ if (cache->valid)
+ return cache;
+
+ mutex_lock(&smcreg.mutex);
+
+ if (cache->valid)
+ goto out;
+ be = cpu_to_be32(index);
+ ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
+ if (ret)
+ goto out;
+ ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
+ if (ret)
+ goto out;
+
+ memcpy(cache->key, key, 4);
+ cache->len = info[0];
+ memcpy(cache->type, &info[1], 4);
+ cache->flags = info[5];
+ cache->valid = 1;
+
+out:
+ mutex_unlock(&smcreg.mutex);
+ if (ret)
+ return ERR_PTR(ret);
+ return cache;
+}
+
+static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
+{
+ int begin = 0, end = smcreg.key_count;
+ const struct applesmc_entry *entry;
+
+ while (begin != end) {
+ int middle = begin + (end - begin) / 2;
+ entry = applesmc_get_entry_by_index(middle);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+ if (strcmp(entry->key, key) < 0)
+ begin = middle + 1;
+ else
+ end = middle;
}
- outb(4, APPLESMC_DATA_PORT);
+ *lo = begin;
+ return 0;
+}
- for (i = 0; i < 4; i++) {
- if (__wait_status(0x05))
- return -EIO;
- key[i] = inb(APPLESMC_DATA_PORT);
+static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
+{
+ int begin = 0, end = smcreg.key_count;
+ const struct applesmc_entry *entry;
+
+ while (begin != end) {
+ int middle = begin + (end - begin) / 2;
+ entry = applesmc_get_entry_by_index(middle);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+ if (strcmp(key, entry->key) < 0)
+ end = middle;
+ else
+ begin = middle + 1;
}
- key[4] = 0;
+ *hi = begin;
return 0;
}
-/*
- * applesmc_get_key_type - get key type, and put the result in type (char[6]).
- * Returns zero on success or a negative error on failure. Callers must
- * hold applesmc_lock.
- */
-static int applesmc_get_key_type(char* key, char* type)
+static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key)
{
- int i;
+ int begin, end;
+ int ret;
- if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
- return -EIO;
+ ret = applesmc_get_lower_bound(&begin, key);
+ if (ret)
+ return ERR_PTR(ret);
+ ret = applesmc_get_upper_bound(&end, key);
+ if (ret)
+ return ERR_PTR(ret);
+ if (end - begin != 1)
+ return ERR_PTR(-EINVAL);
- for (i = 0; i < 4; i++) {
- outb(key[i], APPLESMC_DATA_PORT);
- if (__wait_status(0x04))
- return -EIO;
- }
+ return applesmc_get_entry_by_index(begin);
+}
- outb(6, APPLESMC_DATA_PORT);
+static int applesmc_read_key(const char *key, u8 *buffer, u8 len)
+{
+ const struct applesmc_entry *entry;
- for (i = 0; i < 6; i++) {
- if (__wait_status(0x05))
- return -EIO;
- type[i] = inb(APPLESMC_DATA_PORT);
- }
- type[5] = 0;
+ entry = applesmc_get_entry_by_key(key);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+
+ return applesmc_read_entry(entry, buffer, len);
+}
+
+static int applesmc_write_key(const char *key, const u8 *buffer, u8 len)
+{
+ const struct applesmc_entry *entry;
+ entry = applesmc_get_entry_by_key(key);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+
+ return applesmc_write_entry(entry, buffer, len);
+}
+
+static int applesmc_has_key(const char *key, bool *value)
+{
+ const struct applesmc_entry *entry;
+
+ entry = applesmc_get_entry_by_key(key);
+ if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL)
+ return PTR_ERR(entry);
+
+ *value = !IS_ERR(entry);
return 0;
}
/*
- * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
- * hold applesmc_lock.
+ * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z).
*/
-static int applesmc_read_motion_sensor(int index, s16* value)
+static int applesmc_read_motion_sensor(int index, s16 *value)
{
u8 buffer[2];
int ret;
@@ -444,69 +455,120 @@ static int applesmc_read_motion_sensor(int index, s16* value)
}
/*
- * applesmc_device_init - initialize the accelerometer. Returns zero on success
- * and negative error code on failure. Can sleep.
+ * applesmc_device_init - initialize the accelerometer. Can sleep.
*/
-static int applesmc_device_init(void)
+static void applesmc_device_init(void)
{
- int total, ret = -ENXIO;
+ int total;
u8 buffer[2];
- if (!applesmc_accelerometer)
- return 0;
-
- mutex_lock(&applesmc_lock);
+ if (!smcreg.has_accelerometer)
+ return;
for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
- if (debug)
- printk(KERN_DEBUG "applesmc try %d\n", total);
if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
- (buffer[0] != 0x00 || buffer[1] != 0x00)) {
- if (total == INIT_TIMEOUT_MSECS) {
- printk(KERN_DEBUG "applesmc: device has"
- " already been initialized"
- " (0x%02x, 0x%02x).\n",
- buffer[0], buffer[1]);
- } else {
- printk(KERN_DEBUG "applesmc: device"
- " successfully initialized"
- " (0x%02x, 0x%02x).\n",
- buffer[0], buffer[1]);
- }
- ret = 0;
- goto out;
- }
+ (buffer[0] != 0x00 || buffer[1] != 0x00))
+ return;
buffer[0] = 0xe0;
buffer[1] = 0x00;
applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
msleep(INIT_WAIT_MSECS);
}
- printk(KERN_WARNING "applesmc: failed to init the device\n");
-
-out:
- mutex_unlock(&applesmc_lock);
- return ret;
+ pr_warn("failed to init the device\n");
}
/*
- * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
- * applesmc_lock.
+ * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
*/
-static int applesmc_get_fan_count(void)
+static int applesmc_init_smcreg_try(void)
{
+ struct applesmc_registers *s = &smcreg;
+ bool left_light_sensor, right_light_sensor;
+ u8 tmp[1];
int ret;
- u8 buffer[1];
- mutex_lock(&applesmc_lock);
+ if (s->init_complete)
+ return 0;
- ret = applesmc_read_key(FANS_COUNT, buffer, 1);
+ ret = read_register_count(&s->key_count);
+ if (ret)
+ return ret;
+
+ if (!s->cache)
+ s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL);
+ if (!s->cache)
+ return -ENOMEM;
- mutex_unlock(&applesmc_lock);
+ ret = applesmc_read_key(FANS_COUNT, tmp, 1);
if (ret)
return ret;
- else
- return buffer[0];
+ s->fan_count = tmp[0];
+
+ ret = applesmc_get_lower_bound(&s->temp_begin, "T");
+ if (ret)
+ return ret;
+ ret = applesmc_get_lower_bound(&s->temp_end, "U");
+ if (ret)
+ return ret;
+ s->temp_count = s->temp_end - s->temp_begin;
+
+ ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
+ if (ret)
+ return ret;
+ ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor);
+ if (ret)
+ return ret;
+ ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer);
+ if (ret)
+ return ret;
+ ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight);
+ if (ret)
+ return ret;
+
+ s->num_light_sensors = left_light_sensor + right_light_sensor;
+ s->init_complete = true;
+
+ pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n",
+ s->key_count, s->fan_count, s->temp_count,
+ s->has_accelerometer,
+ s->num_light_sensors,
+ s->has_key_backlight);
+
+ return 0;
+}
+
+/*
+ * applesmc_init_smcreg - Initialize register cache.
+ *
+ * Retries until initialization is successful, or the operation times out.
+ *
+ */
+static int applesmc_init_smcreg(void)
+{
+ int ms, ret;
+
+ for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) {
+ ret = applesmc_init_smcreg_try();
+ if (!ret) {
+ if (ms)
+ pr_info("init_smcreg() took %d ms\n", ms);
+ return 0;
+ }
+ msleep(INIT_WAIT_MSECS);
+ }
+
+ kfree(smcreg.cache);
+ smcreg.cache = NULL;
+
+ return ret;
+}
+
+static void applesmc_destroy_smcreg(void)
+{
+ kfree(smcreg.cache);
+ smcreg.cache = NULL;
+ smcreg.init_complete = false;
}
/* Device model stuff */
@@ -514,30 +576,27 @@ static int applesmc_probe(struct platform_device *dev)
{
int ret;
- ret = applesmc_device_init();
+ ret = applesmc_init_smcreg();
if (ret)
return ret;
- printk(KERN_INFO "applesmc: device successfully initialized.\n");
+ applesmc_device_init();
+
return 0;
}
/* Synchronize device with memorized backlight state */
static int applesmc_pm_resume(struct device *dev)
{
- mutex_lock(&applesmc_lock);
- if (applesmc_light)
+ if (smcreg.has_key_backlight)
applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
- mutex_unlock(&applesmc_lock);
return 0;
}
/* Reinitialize device on resume from hibernation */
static int applesmc_pm_restore(struct device *dev)
{
- int ret = applesmc_device_init();
- if (ret)
- return ret;
+ applesmc_device_init();
return applesmc_pm_resume(dev);
}
@@ -571,20 +630,15 @@ static void applesmc_idev_poll(struct input_polled_dev *dev)
struct input_dev *idev = dev->input;
s16 x, y;
- mutex_lock(&applesmc_lock);
-
if (applesmc_read_motion_sensor(SENSOR_X, &x))
- goto out;
+ return;
if (applesmc_read_motion_sensor(SENSOR_Y, &y))
- goto out;
+ return;
x = -x;
input_report_abs(idev, ABS_X, x - rest_x);
input_report_abs(idev, ABS_Y, y - rest_y);
input_sync(idev);
-
-out:
- mutex_unlock(&applesmc_lock);
}
/* Sysfs Files */
@@ -601,8 +655,6 @@ static ssize_t applesmc_position_show(struct device *dev,
int ret;
s16 x, y, z;
- mutex_lock(&applesmc_lock);
-
ret = applesmc_read_motion_sensor(SENSOR_X, &x);
if (ret)
goto out;
@@ -614,7 +666,6 @@ static ssize_t applesmc_position_show(struct device *dev,
goto out;
out:
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -624,20 +675,20 @@ out:
static ssize_t applesmc_light_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ const struct applesmc_entry *entry;
static int data_length;
int ret;
u8 left = 0, right = 0;
- u8 buffer[10], query[6];
-
- mutex_lock(&applesmc_lock);
+ u8 buffer[10];
if (!data_length) {
- ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
- if (ret)
- goto out;
- data_length = clamp_val(query[0], 0, 10);
- printk(KERN_INFO "applesmc: light sensor data length set to "
- "%d\n", data_length);
+ entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+ if (entry->len > 10)
+ return -ENXIO;
+ data_length = entry->len;
+ pr_info("light sensor data length set to %d\n", data_length);
}
ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
@@ -653,7 +704,6 @@ static ssize_t applesmc_light_show(struct device *dev,
right = buffer[2];
out:
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -664,36 +714,44 @@ out:
static ssize_t applesmc_show_sensor_label(struct device *dev,
struct device_attribute *devattr, char *sysfsbuf)
{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- const char *key =
- temperature_sensors_sets[applesmc_temperature_set][attr->index];
+ int index = smcreg.temp_begin + to_index(devattr);
+ const struct applesmc_entry *entry;
+
+ entry = applesmc_get_entry_by_index(index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
}
/* Displays degree Celsius * 1000 */
static ssize_t applesmc_show_temperature(struct device *dev,
struct device_attribute *devattr, char *sysfsbuf)
{
+ int index = smcreg.temp_begin + to_index(devattr);
+ const struct applesmc_entry *entry;
int ret;
u8 buffer[2];
unsigned int temp;
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- const char* key =
- temperature_sensors_sets[applesmc_temperature_set][attr->index];
-
- mutex_lock(&applesmc_lock);
- ret = applesmc_read_key(key, buffer, 2);
- temp = buffer[0]*1000;
- temp += (buffer[1] >> 6) * 250;
-
- mutex_unlock(&applesmc_lock);
+ entry = applesmc_get_entry_by_index(index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+ if (entry->len > 2)
+ return -EINVAL;
+ ret = applesmc_read_entry(entry, buffer, entry->len);
if (ret)
return ret;
- else
- return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
+
+ if (entry->len == 2) {
+ temp = buffer[0] * 1000;
+ temp += (buffer[1] >> 6) * 250;
+ } else {
+ temp = buffer[0] * 4000;
+ }
+
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
}
static ssize_t applesmc_show_fan_speed(struct device *dev,
@@ -703,21 +761,12 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
unsigned int speed = 0;
char newkey[5];
u8 buffer[2];
- struct sensor_device_attribute_2 *sensor_attr =
- to_sensor_dev_attr_2(attr);
-
- newkey[0] = fan_speed_keys[sensor_attr->nr][0];
- newkey[1] = '0' + sensor_attr->index;
- newkey[2] = fan_speed_keys[sensor_attr->nr][2];
- newkey[3] = fan_speed_keys[sensor_attr->nr][3];
- newkey[4] = 0;
- mutex_lock(&applesmc_lock);
+ sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
ret = applesmc_read_key(newkey, buffer, 2);
speed = ((buffer[0] << 8 | buffer[1]) >> 2);
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -729,30 +778,19 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
const char *sysfsbuf, size_t count)
{
int ret;
- u32 speed;
+ unsigned long speed;
char newkey[5];
u8 buffer[2];
- struct sensor_device_attribute_2 *sensor_attr =
- to_sensor_dev_attr_2(attr);
-
- speed = simple_strtoul(sysfsbuf, NULL, 10);
-
- if (speed > 0x4000) /* Bigger than a 14-bit value */
- return -EINVAL;
- newkey[0] = fan_speed_keys[sensor_attr->nr][0];
- newkey[1] = '0' + sensor_attr->index;
- newkey[2] = fan_speed_keys[sensor_attr->nr][2];
- newkey[3] = fan_speed_keys[sensor_attr->nr][3];
- newkey[4] = 0;
+ if (strict_strtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000)
+ return -EINVAL; /* Bigger than a 14-bit value */
- mutex_lock(&applesmc_lock);
+ sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
buffer[0] = (speed >> 6) & 0xff;
buffer[1] = (speed << 2) & 0xff;
ret = applesmc_write_key(newkey, buffer, 2);
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -760,19 +798,15 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
}
static ssize_t applesmc_show_fan_manual(struct device *dev,
- struct device_attribute *devattr, char *sysfsbuf)
+ struct device_attribute *attr, char *sysfsbuf)
{
int ret;
u16 manual = 0;
u8 buffer[2];
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-
- mutex_lock(&applesmc_lock);
ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
- manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
+ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -780,18 +814,16 @@ static ssize_t applesmc_show_fan_manual(struct device *dev,
}
static ssize_t applesmc_store_fan_manual(struct device *dev,
- struct device_attribute *devattr,
+ struct device_attribute *attr,
const char *sysfsbuf, size_t count)
{
int ret;
u8 buffer[2];
- u32 input;
+ unsigned long input;
u16 val;
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-
- input = simple_strtoul(sysfsbuf, NULL, 10);
- mutex_lock(&applesmc_lock);
+ if (strict_strtoul(sysfsbuf, 10, &input) < 0)
+ return -EINVAL;
ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
val = (buffer[0] << 8 | buffer[1]);
@@ -799,9 +831,9 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
goto out;
if (input)
- val = val | (0x01 << attr->index);
+ val = val | (0x01 << to_index(attr));
else
- val = val & ~(0x01 << attr->index);
+ val = val & ~(0x01 << to_index(attr));
buffer[0] = (val >> 8) & 0xFF;
buffer[1] = val & 0xFF;
@@ -809,7 +841,6 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
out:
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -822,21 +853,12 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
int ret;
char newkey[5];
u8 buffer[17];
- struct sensor_device_attribute_2 *sensor_attr =
- to_sensor_dev_attr_2(attr);
-
- newkey[0] = FAN_POSITION[0];
- newkey[1] = '0' + sensor_attr->index;
- newkey[2] = FAN_POSITION[2];
- newkey[3] = FAN_POSITION[3];
- newkey[4] = 0;
- mutex_lock(&applesmc_lock);
+ sprintf(newkey, FAN_ID_FMT, to_index(attr));
ret = applesmc_read_key(newkey, buffer, 16);
buffer[16] = 0;
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -852,18 +874,14 @@ static ssize_t applesmc_calibrate_show(struct device *dev,
static ssize_t applesmc_calibrate_store(struct device *dev,
struct device_attribute *attr, const char *sysfsbuf, size_t count)
{
- mutex_lock(&applesmc_lock);
applesmc_calibrate();
- mutex_unlock(&applesmc_lock);
return count;
}
static void applesmc_backlight_set(struct work_struct *work)
{
- mutex_lock(&applesmc_lock);
applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
- mutex_unlock(&applesmc_lock);
}
static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
@@ -886,13 +904,10 @@ static ssize_t applesmc_key_count_show(struct device *dev,
u8 buffer[4];
u32 count;
- mutex_lock(&applesmc_lock);
-
ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
((u32)buffer[2]<<8) + buffer[3];
- mutex_unlock(&applesmc_lock);
if (ret)
return ret;
else
@@ -902,113 +917,53 @@ static ssize_t applesmc_key_count_show(struct device *dev,
static ssize_t applesmc_key_at_index_read_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- char key[5];
- char info[6];
+ const struct applesmc_entry *entry;
int ret;
- mutex_lock(&applesmc_lock);
-
- ret = applesmc_get_key_at_index(key_at_index, key);
-
- if (ret || !key[0]) {
- mutex_unlock(&applesmc_lock);
-
- return -EINVAL;
- }
-
- ret = applesmc_get_key_type(key, info);
-
- if (ret) {
- mutex_unlock(&applesmc_lock);
-
+ entry = applesmc_get_entry_by_index(key_at_index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+ ret = applesmc_read_entry(entry, sysfsbuf, entry->len);
+ if (ret)
return ret;
- }
-
- /*
- * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
- * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
- */
- ret = applesmc_read_key(key, sysfsbuf, info[0]);
-
- mutex_unlock(&applesmc_lock);
- if (!ret) {
- return info[0];
- } else {
- return ret;
- }
+ return entry->len;
}
static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- char key[5];
- char info[6];
- int ret;
-
- mutex_lock(&applesmc_lock);
-
- ret = applesmc_get_key_at_index(key_at_index, key);
+ const struct applesmc_entry *entry;
- if (ret || !key[0]) {
- mutex_unlock(&applesmc_lock);
+ entry = applesmc_get_entry_by_index(key_at_index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
- return -EINVAL;
- }
-
- ret = applesmc_get_key_type(key, info);
-
- mutex_unlock(&applesmc_lock);
-
- if (!ret)
- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
- else
- return ret;
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", entry->len);
}
static ssize_t applesmc_key_at_index_type_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- char key[5];
- char info[6];
- int ret;
-
- mutex_lock(&applesmc_lock);
-
- ret = applesmc_get_key_at_index(key_at_index, key);
-
- if (ret || !key[0]) {
- mutex_unlock(&applesmc_lock);
-
- return -EINVAL;
- }
-
- ret = applesmc_get_key_type(key, info);
+ const struct applesmc_entry *entry;
- mutex_unlock(&applesmc_lock);
+ entry = applesmc_get_entry_by_index(key_at_index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
- if (!ret)
- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
- else
- return ret;
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->type);
}
static ssize_t applesmc_key_at_index_name_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- char key[5];
- int ret;
+ const struct applesmc_entry *entry;
- mutex_lock(&applesmc_lock);
+ entry = applesmc_get_entry_by_index(key_at_index);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
- ret = applesmc_get_key_at_index(key_at_index, key);
-
- mutex_unlock(&applesmc_lock);
-
- if (!ret && key[0])
- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
- else
- return -EINVAL;
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
}
static ssize_t applesmc_key_at_index_show(struct device *dev,
@@ -1020,12 +975,13 @@ static ssize_t applesmc_key_at_index_show(struct device *dev,
static ssize_t applesmc_key_at_index_store(struct device *dev,
struct device_attribute *attr, const char *sysfsbuf, size_t count)
{
- mutex_lock(&applesmc_lock);
-
- key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
+ unsigned long newkey;
- mutex_unlock(&applesmc_lock);
+ if (strict_strtoul(sysfsbuf, 10, &newkey) < 0
+ || newkey >= smcreg.key_count)
+ return -EINVAL;
+ key_at_index = newkey;
return count;
}
@@ -1035,387 +991,101 @@ static struct led_classdev applesmc_backlight = {
.brightness_set = applesmc_brightness_set,
};
-static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
-
-static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
-static DEVICE_ATTR(calibrate, 0644,
- applesmc_calibrate_show, applesmc_calibrate_store);
-
-static struct attribute *accelerometer_attributes[] = {
- &dev_attr_position.attr,
- &dev_attr_calibrate.attr,
- NULL
-};
-
-static const struct attribute_group accelerometer_attributes_group =
- { .attrs = accelerometer_attributes };
-
-static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
-
-static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
-static DEVICE_ATTR(key_at_index, 0644,
- applesmc_key_at_index_show, applesmc_key_at_index_store);
-static DEVICE_ATTR(key_at_index_name, 0444,
- applesmc_key_at_index_name_show, NULL);
-static DEVICE_ATTR(key_at_index_type, 0444,
- applesmc_key_at_index_type_show, NULL);
-static DEVICE_ATTR(key_at_index_data_length, 0444,
- applesmc_key_at_index_data_length_show, NULL);
-static DEVICE_ATTR(key_at_index_data, 0444,
- applesmc_key_at_index_read_show, NULL);
-
-static struct attribute *key_enumeration_attributes[] = {
- &dev_attr_key_count.attr,
- &dev_attr_key_at_index.attr,
- &dev_attr_key_at_index_name.attr,
- &dev_attr_key_at_index_type.attr,
- &dev_attr_key_at_index_data_length.attr,
- &dev_attr_key_at_index_data.attr,
- NULL
-};
-
-static const struct attribute_group key_enumeration_group =
- { .attrs = key_enumeration_attributes };
-
-/*
- * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
- * - show actual speed
- * - show/store minimum speed
- * - show maximum speed
- * - show safe speed
- * - show/store target speed
- * - show/store manual mode
- */
-#define sysfs_fan_speeds_offset(offset) \
-static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
- applesmc_show_fan_speed, NULL, 0, offset-1); \
-\
-static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
- applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
-\
-static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
- applesmc_show_fan_speed, NULL, 2, offset-1); \
-\
-static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
- applesmc_show_fan_speed, NULL, 3, offset-1); \
-\
-static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
- applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
-\
-static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
- applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
-\
-static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
- applesmc_show_fan_position, NULL, offset-1); \
-\
-static struct attribute *fan##offset##_attributes[] = { \
- &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
- &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
- NULL \
+static struct applesmc_node_group info_group[] = {
+ { "name", applesmc_name_show },
+ { "key_count", applesmc_key_count_show },
+ { "key_at_index", applesmc_key_at_index_show, applesmc_key_at_index_store },
+ { "key_at_index_name", applesmc_key_at_index_name_show },
+ { "key_at_index_type", applesmc_key_at_index_type_show },
+ { "key_at_index_data_length", applesmc_key_at_index_data_length_show },
+ { "key_at_index_data", applesmc_key_at_index_read_show },
+ { }
};
-/*
- * Create the needed functions for each fan using the macro defined above
- * (4 fans are supported)
- */
-sysfs_fan_speeds_offset(1);
-sysfs_fan_speeds_offset(2);
-sysfs_fan_speeds_offset(3);
-sysfs_fan_speeds_offset(4);
-
-static const struct attribute_group fan_attribute_groups[] = {
- { .attrs = fan1_attributes },
- { .attrs = fan2_attributes },
- { .attrs = fan3_attributes },
- { .attrs = fan4_attributes },
+static struct applesmc_node_group accelerometer_group[] = {
+ { "position", applesmc_position_show },
+ { "calibrate", applesmc_calibrate_show, applesmc_calibrate_store },
+ { }
};
-/*
- * Temperature sensors sysfs entries.
- */
-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 3);
-static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 4);
-static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 5);
-static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 6);
-static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 7);
-static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 8);
-static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 9);
-static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 10);
-static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 11);
-static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 12);
-static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 13);
-static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 14);
-static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 15);
-static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 16);
-static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 17);
-static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 18);
-static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 19);
-static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 20);
-static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 21);
-static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 22);
-static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 23);
-static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 24);
-static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 25);
-static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 26);
-static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 27);
-static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 28);
-static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 29);
-static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 30);
-static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 31);
-static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 32);
-static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 33);
-static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 34);
-static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 35);
-static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 36);
-static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 37);
-static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 38);
-static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO,
- applesmc_show_sensor_label, NULL, 39);
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
- applesmc_show_temperature, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
- applesmc_show_temperature, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
- applesmc_show_temperature, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
- applesmc_show_temperature, NULL, 3);
-static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
- applesmc_show_temperature, NULL, 4);
-static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
- applesmc_show_temperature, NULL, 5);
-static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
- applesmc_show_temperature, NULL, 6);
-static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
- applesmc_show_temperature, NULL, 7);
-static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
- applesmc_show_temperature, NULL, 8);
-static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
- applesmc_show_temperature, NULL, 9);
-static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
- applesmc_show_temperature, NULL, 10);
-static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
- applesmc_show_temperature, NULL, 11);
-static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
- applesmc_show_temperature, NULL, 12);
-static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
- applesmc_show_temperature, NULL, 13);
-static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
- applesmc_show_temperature, NULL, 14);
-static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
- applesmc_show_temperature, NULL, 15);
-static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
- applesmc_show_temperature, NULL, 16);
-static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
- applesmc_show_temperature, NULL, 17);
-static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
- applesmc_show_temperature, NULL, 18);
-static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
- applesmc_show_temperature, NULL, 19);
-static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
- applesmc_show_temperature, NULL, 20);
-static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
- applesmc_show_temperature, NULL, 21);
-static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
- applesmc_show_temperature, NULL, 22);
-static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
- applesmc_show_temperature, NULL, 23);
-static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
- applesmc_show_temperature, NULL, 24);
-static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
- applesmc_show_temperature, NULL, 25);
-static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
- applesmc_show_temperature, NULL, 26);
-static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
- applesmc_show_temperature, NULL, 27);
-static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
- applesmc_show_temperature, NULL, 28);
-static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
- applesmc_show_temperature, NULL, 29);
-static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
- applesmc_show_temperature, NULL, 30);
-static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
- applesmc_show_temperature, NULL, 31);
-static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
- applesmc_show_temperature, NULL, 32);
-static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
- applesmc_show_temperature, NULL, 33);
-static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
- applesmc_show_temperature, NULL, 34);
-static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
- applesmc_show_temperature, NULL, 35);
-static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
- applesmc_show_temperature, NULL, 36);
-static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
- applesmc_show_temperature, NULL, 37);
-static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
- applesmc_show_temperature, NULL, 38);
-static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
- applesmc_show_temperature, NULL, 39);
-
-static struct attribute *label_attributes[] = {
- &sensor_dev_attr_temp1_label.dev_attr.attr,
- &sensor_dev_attr_temp2_label.dev_attr.attr,
- &sensor_dev_attr_temp3_label.dev_attr.attr,
- &sensor_dev_attr_temp4_label.dev_attr.attr,
- &sensor_dev_attr_temp5_label.dev_attr.attr,
- &sensor_dev_attr_temp6_label.dev_attr.attr,
- &sensor_dev_attr_temp7_label.dev_attr.attr,
- &sensor_dev_attr_temp8_label.dev_attr.attr,
- &sensor_dev_attr_temp9_label.dev_attr.attr,
- &sensor_dev_attr_temp10_label.dev_attr.attr,
- &sensor_dev_attr_temp11_label.dev_attr.attr,
- &sensor_dev_attr_temp12_label.dev_attr.attr,
- &sensor_dev_attr_temp13_label.dev_attr.attr,
- &sensor_dev_attr_temp14_label.dev_attr.attr,
- &sensor_dev_attr_temp15_label.dev_attr.attr,
- &sensor_dev_attr_temp16_label.dev_attr.attr,
- &sensor_dev_attr_temp17_label.dev_attr.attr,
- &sensor_dev_attr_temp18_label.dev_attr.attr,
- &sensor_dev_attr_temp19_label.dev_attr.attr,
- &sensor_dev_attr_temp20_label.dev_attr.attr,
- &sensor_dev_attr_temp21_label.dev_attr.attr,
- &sensor_dev_attr_temp22_label.dev_attr.attr,
- &sensor_dev_attr_temp23_label.dev_attr.attr,
- &sensor_dev_attr_temp24_label.dev_attr.attr,
- &sensor_dev_attr_temp25_label.dev_attr.attr,
- &sensor_dev_attr_temp26_label.dev_attr.attr,
- &sensor_dev_attr_temp27_label.dev_attr.attr,
- &sensor_dev_attr_temp28_label.dev_attr.attr,
- &sensor_dev_attr_temp29_label.dev_attr.attr,
- &sensor_dev_attr_temp30_label.dev_attr.attr,
- &sensor_dev_attr_temp31_label.dev_attr.attr,
- &sensor_dev_attr_temp32_label.dev_attr.attr,
- &sensor_dev_attr_temp33_label.dev_attr.attr,
- &sensor_dev_attr_temp34_label.dev_attr.attr,
- &sensor_dev_attr_temp35_label.dev_attr.attr,
- &sensor_dev_attr_temp36_label.dev_attr.attr,
- &sensor_dev_attr_temp37_label.dev_attr.attr,
- &sensor_dev_attr_temp38_label.dev_attr.attr,
- &sensor_dev_attr_temp39_label.dev_attr.attr,
- &sensor_dev_attr_temp40_label.dev_attr.attr,
- NULL
+static struct applesmc_node_group light_sensor_group[] = {
+ { "light", applesmc_light_show },
+ { }
};
-static struct attribute *temperature_attributes[] = {
- &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_temp4_input.dev_attr.attr,
- &sensor_dev_attr_temp5_input.dev_attr.attr,
- &sensor_dev_attr_temp6_input.dev_attr.attr,
- &sensor_dev_attr_temp7_input.dev_attr.attr,
- &sensor_dev_attr_temp8_input.dev_attr.attr,
- &sensor_dev_attr_temp9_input.dev_attr.attr,
- &sensor_dev_attr_temp10_input.dev_attr.attr,
- &sensor_dev_attr_temp11_input.dev_attr.attr,
- &sensor_dev_attr_temp12_input.dev_attr.attr,
- &sensor_dev_attr_temp13_input.dev_attr.attr,
- &sensor_dev_attr_temp14_input.dev_attr.attr,
- &sensor_dev_attr_temp15_input.dev_attr.attr,
- &sensor_dev_attr_temp16_input.dev_attr.attr,
- &sensor_dev_attr_temp17_input.dev_attr.attr,
- &sensor_dev_attr_temp18_input.dev_attr.attr,
- &sensor_dev_attr_temp19_input.dev_attr.attr,
- &sensor_dev_attr_temp20_input.dev_attr.attr,
- &sensor_dev_attr_temp21_input.dev_attr.attr,
- &sensor_dev_attr_temp22_input.dev_attr.attr,
- &sensor_dev_attr_temp23_input.dev_attr.attr,
- &sensor_dev_attr_temp24_input.dev_attr.attr,
- &sensor_dev_attr_temp25_input.dev_attr.attr,
- &sensor_dev_attr_temp26_input.dev_attr.attr,
- &sensor_dev_attr_temp27_input.dev_attr.attr,
- &sensor_dev_attr_temp28_input.dev_attr.attr,
- &sensor_dev_attr_temp29_input.dev_attr.attr,
- &sensor_dev_attr_temp30_input.dev_attr.attr,
- &sensor_dev_attr_temp31_input.dev_attr.attr,
- &sensor_dev_attr_temp32_input.dev_attr.attr,
- &sensor_dev_attr_temp33_input.dev_attr.attr,
- &sensor_dev_attr_temp34_input.dev_attr.attr,
- &sensor_dev_attr_temp35_input.dev_attr.attr,
- &sensor_dev_attr_temp36_input.dev_attr.attr,
- &sensor_dev_attr_temp37_input.dev_attr.attr,
- &sensor_dev_attr_temp38_input.dev_attr.attr,
- &sensor_dev_attr_temp39_input.dev_attr.attr,
- &sensor_dev_attr_temp40_input.dev_attr.attr,
- NULL
+static struct applesmc_node_group fan_group[] = {
+ { "fan%d_label", applesmc_show_fan_position },
+ { "fan%d_input", applesmc_show_fan_speed, NULL, 0 },
+ { "fan%d_min", applesmc_show_fan_speed, applesmc_store_fan_speed, 1 },
+ { "fan%d_max", applesmc_show_fan_speed, NULL, 2 },
+ { "fan%d_safe", applesmc_show_fan_speed, NULL, 3 },
+ { "fan%d_output", applesmc_show_fan_speed, applesmc_store_fan_speed, 4 },
+ { "fan%d_manual", applesmc_show_fan_manual, applesmc_store_fan_manual },
+ { }
};
-static const struct attribute_group temperature_attributes_group =
- { .attrs = temperature_attributes };
-
-static const struct attribute_group label_attributes_group = {
- .attrs = label_attributes
+static struct applesmc_node_group temp_group[] = {
+ { "temp%d_label", applesmc_show_sensor_label },
+ { "temp%d_input", applesmc_show_temperature },
+ { }
};
/* Module stuff */
/*
- * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
+ * applesmc_destroy_nodes - remove files and free associated memory
*/
-static int applesmc_dmi_match(const struct dmi_system_id *id)
+static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
{
- int i = 0;
- struct dmi_match_data* dmi_data = id->driver_data;
- printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
- applesmc_accelerometer = dmi_data->accelerometer;
- printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
- applesmc_accelerometer ? "with" : "without");
- applesmc_light = dmi_data->light;
- printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
- applesmc_light ? "with" : "without");
-
- applesmc_temperature_set = dmi_data->temperature_set;
- while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
- i++;
- printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
- return 1;
+ struct applesmc_node_group *grp;
+ struct applesmc_dev_attr *node;
+
+ for (grp = groups; grp->nodes; grp++) {
+ for (node = grp->nodes; node->sda.dev_attr.attr.name; node++)
+ sysfs_remove_file(&pdev->dev.kobj,
+ &node->sda.dev_attr.attr);
+ kfree(grp->nodes);
+ grp->nodes = NULL;
+ }
+}
+
+/*
+ * applesmc_create_nodes - create a two-dimensional group of sysfs files
+ */
+static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
+{
+ struct applesmc_node_group *grp;
+ struct applesmc_dev_attr *node;
+ struct attribute *attr;
+ int ret, i;
+
+ for (grp = groups; grp->format; grp++) {
+ grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL);
+ if (!grp->nodes) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ for (i = 0; i < num; i++) {
+ node = &grp->nodes[i];
+ sprintf(node->name, grp->format, i + 1);
+ node->sda.index = (grp->option << 16) | (i & 0xffff);
+ node->sda.dev_attr.show = grp->show;
+ node->sda.dev_attr.store = grp->store;
+ attr = &node->sda.dev_attr.attr;
+ attr->name = node->name;
+ attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0);
+ ret = sysfs_create_file(&pdev->dev.kobj, attr);
+ if (ret) {
+ attr->name = NULL;
+ goto out;
+ }
+ }
+ }
+
+ return 0;
+out:
+ applesmc_destroy_nodes(groups);
+ return ret;
}
/* Create accelerometer ressources */
@@ -1424,8 +1094,10 @@ static int applesmc_create_accelerometer(void)
struct input_dev *idev;
int ret;
- ret = sysfs_create_group(&pdev->dev.kobj,
- &accelerometer_attributes_group);
+ if (!smcreg.has_accelerometer)
+ return 0;
+
+ ret = applesmc_create_nodes(accelerometer_group, 1);
if (ret)
goto out;
@@ -1462,184 +1134,96 @@ out_idev:
input_free_polled_device(applesmc_idev);
out_sysfs:
- sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+ applesmc_destroy_nodes(accelerometer_group);
out:
- printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ pr_warn("driver init failed (ret=%d)!\n", ret);
return ret;
}
/* Release all ressources used by the accelerometer */
static void applesmc_release_accelerometer(void)
{
+ if (!smcreg.has_accelerometer)
+ return;
input_unregister_polled_device(applesmc_idev);
input_free_polled_device(applesmc_idev);
- sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+ applesmc_destroy_nodes(accelerometer_group);
}
-static __initdata struct dmi_match_data applesmc_dmi_data[] = {
-/* MacBook Pro: accelerometer, backlight and temperature set 0 */
- { .accelerometer = 1, .light = 1, .temperature_set = 0 },
-/* MacBook2: accelerometer and temperature set 1 */
- { .accelerometer = 1, .light = 0, .temperature_set = 1 },
-/* MacBook: accelerometer and temperature set 2 */
- { .accelerometer = 1, .light = 0, .temperature_set = 2 },
-/* MacMini: temperature set 3 */
- { .accelerometer = 0, .light = 0, .temperature_set = 3 },
-/* MacPro: temperature set 4 */
- { .accelerometer = 0, .light = 0, .temperature_set = 4 },
-/* iMac: temperature set 5 */
- { .accelerometer = 0, .light = 0, .temperature_set = 5 },
-/* MacBook3, MacBook4: accelerometer and temperature set 6 */
- { .accelerometer = 1, .light = 0, .temperature_set = 6 },
-/* MacBook Air: accelerometer, backlight and temperature set 7 */
- { .accelerometer = 1, .light = 1, .temperature_set = 7 },
-/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
- { .accelerometer = 1, .light = 1, .temperature_set = 8 },
-/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
- { .accelerometer = 1, .light = 1, .temperature_set = 9 },
-/* iMac 5: light sensor only, temperature set 10 */
- { .accelerometer = 0, .light = 0, .temperature_set = 10 },
-/* MacBook 5: accelerometer, backlight and temperature set 11 */
- { .accelerometer = 1, .light = 1, .temperature_set = 11 },
-/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
- { .accelerometer = 1, .light = 1, .temperature_set = 12 },
-/* iMac 8: light sensor only, temperature set 13 */
- { .accelerometer = 0, .light = 0, .temperature_set = 13 },
-/* iMac 6: light sensor only, temperature set 14 */
- { .accelerometer = 0, .light = 0, .temperature_set = 14 },
-/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
- { .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 },
-/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
- { .accelerometer = 1, .light = 1, .temperature_set = 19 },
-/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
- { .accelerometer = 1, .light = 1, .temperature_set = 20 },
-/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
- { .accelerometer = 1, .light = 1, .temperature_set = 21 },
-/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
- { .accelerometer = 1, .light = 1, .temperature_set = 22 },
-};
+static int applesmc_create_light_sensor(void)
+{
+ if (!smcreg.num_light_sensors)
+ return 0;
+ return applesmc_create_nodes(light_sensor_group, 1);
+}
+
+static void applesmc_release_light_sensor(void)
+{
+ if (!smcreg.num_light_sensors)
+ return;
+ applesmc_destroy_nodes(light_sensor_group);
+}
+
+static int applesmc_create_key_backlight(void)
+{
+ if (!smcreg.has_key_backlight)
+ return 0;
+ applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
+ if (!applesmc_led_wq)
+ return -ENOMEM;
+ return led_classdev_register(&pdev->dev, &applesmc_backlight);
+}
+
+static void applesmc_release_key_backlight(void)
+{
+ if (!smcreg.has_key_backlight)
+ return;
+ led_classdev_unregister(&applesmc_backlight);
+ destroy_workqueue(applesmc_led_wq);
+}
+
+static int applesmc_dmi_match(const struct dmi_system_id *id)
+{
+ return 1;
+}
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
* So we need to put "Apple MacBook Pro" before "Apple MacBook". */
static __initdata struct dmi_system_id applesmc_whitelist[] = {
- { applesmc_dmi_match, "Apple MacBook Air 2", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
- &applesmc_dmi_data[15]},
{ applesmc_dmi_match, "Apple MacBook Air", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
- &applesmc_dmi_data[7]},
- { applesmc_dmi_match, "Apple MacBook Pro 7", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") },
- &applesmc_dmi_data[22]},
- { applesmc_dmi_match, "Apple MacBook Pro 5,4", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
- &applesmc_dmi_data[20]},
- { applesmc_dmi_match, "Apple MacBook Pro 5,3", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
- &applesmc_dmi_data[19]},
- { applesmc_dmi_match, "Apple MacBook Pro 6", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
- &applesmc_dmi_data[21]},
- { applesmc_dmi_match, "Apple MacBook Pro 5", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
- &applesmc_dmi_data[12]},
- { applesmc_dmi_match, "Apple MacBook Pro 4", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
- &applesmc_dmi_data[8]},
- { applesmc_dmi_match, "Apple MacBook Pro 3", {
- 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") },
- &applesmc_dmi_data[0]},
- { applesmc_dmi_match, "Apple MacBook (v2)", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
- &applesmc_dmi_data[1]},
- { applesmc_dmi_match, "Apple MacBook (v3)", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
- &applesmc_dmi_data[6]},
- { applesmc_dmi_match, "Apple MacBook 4", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
- &applesmc_dmi_data[6]},
- { applesmc_dmi_match, "Apple MacBook 5", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
- &applesmc_dmi_data[11]},
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro") },
+ },
{ applesmc_dmi_match, "Apple MacBook", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
- &applesmc_dmi_data[2]},
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") },
+ },
{ applesmc_dmi_match, "Apple Macmini", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
- &applesmc_dmi_data[3]},
- { applesmc_dmi_match, "Apple MacPro2", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
- &applesmc_dmi_data[4]},
- { applesmc_dmi_match, "Apple MacPro3", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
- &applesmc_dmi_data[16]},
+ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") },
+ },
{ applesmc_dmi_match, "Apple MacPro", {
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") },
- &applesmc_dmi_data[13]},
- { applesmc_dmi_match, "Apple iMac 6", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
- &applesmc_dmi_data[14]},
- { applesmc_dmi_match, "Apple iMac 5", {
- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
- &applesmc_dmi_data[10]},
+ },
{ applesmc_dmi_match, "Apple iMac", {
- DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
- DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
- &applesmc_dmi_data[5]},
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac") },
+ },
{ .ident = NULL }
};
static int __init applesmc_init(void)
{
int ret;
- int count;
- int i;
if (!dmi_check_system(applesmc_whitelist)) {
- printk(KERN_WARNING "applesmc: supported laptop not found!\n");
+ pr_warn("supported laptop not found!\n");
ret = -ENODEV;
goto out;
}
@@ -1661,83 +1245,34 @@ static int __init applesmc_init(void)
goto out_driver;
}
- ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
+ /* create register cache */
+ ret = applesmc_init_smcreg();
if (ret)
goto out_device;
- /* Create key enumeration sysfs files */
- ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
+ ret = applesmc_create_nodes(info_group, 1);
if (ret)
- goto out_name;
-
- /* create fan files */
- count = applesmc_get_fan_count();
- if (count < 0)
- printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
- else
- printk(KERN_INFO "applesmc: %d fans found.\n", count);
+ goto out_smcreg;
- if (count > 4) {
- count = 4;
- printk(KERN_WARNING "applesmc: More than 4 fans found,"
- " but at most 4 fans are supported"
- " by the driver.\n");
- }
-
- while (fans_handled < count) {
- ret = sysfs_create_group(&pdev->dev.kobj,
- &fan_attribute_groups[fans_handled]);
- if (ret)
- goto out_fans;
- fans_handled++;
- }
-
- for (i = 0;
- temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
- i++) {
- if (temperature_attributes[i] == NULL ||
- label_attributes[i] == NULL) {
- printk(KERN_ERR "applesmc: More temperature sensors "
- "in temperature_sensors_sets (at least %i)"
- "than available sysfs files in "
- "temperature_attributes (%i), please report "
- "this bug.\n", i, i-1);
- goto out_temperature;
- }
- ret = sysfs_create_file(&pdev->dev.kobj,
- temperature_attributes[i]);
- if (ret)
- goto out_temperature;
- ret = sysfs_create_file(&pdev->dev.kobj,
- label_attributes[i]);
- if (ret)
- goto out_temperature;
- }
+ ret = applesmc_create_nodes(fan_group, smcreg.fan_count);
+ if (ret)
+ goto out_info;
- if (applesmc_accelerometer) {
- ret = applesmc_create_accelerometer();
- if (ret)
- goto out_temperature;
- }
+ ret = applesmc_create_nodes(temp_group, smcreg.temp_count);
+ if (ret)
+ goto out_fans;
- if (applesmc_light) {
- /* Add light sensor file */
- ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
- if (ret)
- goto out_accelerometer;
+ ret = applesmc_create_accelerometer();
+ if (ret)
+ goto out_temperature;
- /* Create the workqueue */
- applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
- if (!applesmc_led_wq) {
- ret = -ENOMEM;
- goto out_light_sysfs;
- }
+ ret = applesmc_create_light_sensor();
+ if (ret)
+ goto out_accelerometer;
- /* register as a led device */
- ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
- if (ret < 0)
- goto out_light_wq;
- }
+ ret = applesmc_create_key_backlight();
+ if (ret)
+ goto out_light_sysfs;
hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(hwmon_dev)) {
@@ -1745,32 +1280,22 @@ static int __init applesmc_init(void)
goto out_light_ledclass;
}
- printk(KERN_INFO "applesmc: driver successfully loaded.\n");
-
return 0;
out_light_ledclass:
- if (applesmc_light)
- led_classdev_unregister(&applesmc_backlight);
-out_light_wq:
- if (applesmc_light)
- destroy_workqueue(applesmc_led_wq);
+ applesmc_release_key_backlight();
out_light_sysfs:
- if (applesmc_light)
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
+ applesmc_release_light_sensor();
out_accelerometer:
- if (applesmc_accelerometer)
- applesmc_release_accelerometer();
+ applesmc_release_accelerometer();
out_temperature:
- sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group);
- sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
+ applesmc_destroy_nodes(temp_group);
out_fans:
- while (fans_handled)
- sysfs_remove_group(&pdev->dev.kobj,
- &fan_attribute_groups[--fans_handled]);
- sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
-out_name:
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
+ applesmc_destroy_nodes(fan_group);
+out_info:
+ applesmc_destroy_nodes(info_group);
+out_smcreg:
+ applesmc_destroy_smcreg();
out_device:
platform_device_unregister(pdev);
out_driver:
@@ -1778,32 +1303,23 @@ out_driver:
out_region:
release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
out:
- printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ pr_warn("driver init failed (ret=%d)!\n", ret);
return ret;
}
static void __exit applesmc_exit(void)
{
hwmon_device_unregister(hwmon_dev);
- if (applesmc_light) {
- led_classdev_unregister(&applesmc_backlight);
- destroy_workqueue(applesmc_led_wq);
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
- }
- if (applesmc_accelerometer)
- applesmc_release_accelerometer();
- sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group);
- sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
- while (fans_handled)
- sysfs_remove_group(&pdev->dev.kobj,
- &fan_attribute_groups[--fans_handled]);
- sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
+ applesmc_release_key_backlight();
+ applesmc_release_light_sensor();
+ applesmc_release_accelerometer();
+ applesmc_destroy_nodes(temp_group);
+ applesmc_destroy_nodes(fan_group);
+ applesmc_destroy_nodes(info_group);
+ applesmc_destroy_smcreg();
platform_device_unregister(pdev);
platform_driver_unregister(&applesmc_driver);
release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
-
- printk(KERN_INFO "applesmc: driver unloaded.\n");
}
module_init(applesmc_init);
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 7dada559b3a1..c02a052d3085 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -36,6 +36,8 @@
asb100 7 3 1 4 0x31 0x0694 yes no
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
@@ -701,8 +703,7 @@ static int asb100_detect(struct i2c_client *client,
int val1, val2;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- pr_debug("asb100.o: detect failed, "
- "smbus byte data not supported!\n");
+ pr_debug("detect failed, smbus byte data not supported!\n");
return -ENODEV;
}
@@ -715,7 +716,7 @@ static int asb100_detect(struct i2c_client *client,
(((!(val1 & 0x80)) && (val2 != 0x94)) ||
/* Check for ASB100 ID (high byte ) */
((val1 & 0x80) && (val2 != 0x06)))) {
- pr_debug("asb100: detect failed, bad chip id 0x%02x!\n", val2);
+ pr_debug("detect failed, bad chip id 0x%02x!\n", val2);
return -ENODEV;
}
@@ -744,7 +745,7 @@ static int asb100_probe(struct i2c_client *client,
data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL);
if (!data) {
- pr_debug("asb100.o: probe failed, kzalloc failed!\n");
+ pr_debug("probe failed, kzalloc failed!\n");
err = -ENOMEM;
goto ERROR0;
}
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 23b8555215d2..2d68cf3c223b 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -5,6 +5,8 @@
* See COPYING in the top level directory of the kernel tree.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/hwmon.h>
@@ -1414,14 +1416,13 @@ static int __init atk0110_init(void)
/* Make sure it's safe to access the device through ACPI */
if (!acpi_resources_are_enforced()) {
- pr_err("atk: Resources not safely usable due to "
- "acpi_enforce_resources kernel parameter\n");
+ pr_err("Resources not safely usable due to acpi_enforce_resources kernel parameter\n");
return -EBUSY;
}
ret = acpi_bus_register_driver(&atk_driver);
if (ret)
- pr_info("atk: acpi_bus_register_driver failed: %d\n", ret);
+ pr_info("acpi_bus_register_driver failed: %d\n", ret);
return ret;
}
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 42de98d73ff5..194ca0aa8b0c 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -20,6 +20,8 @@
* 02110-1301 USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -445,8 +447,8 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
* without thermal sensors will be filtered out.
*/
if (!cpu_has(c, X86_FEATURE_DTS)) {
- printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
- " has no thermal sensor.\n", c->x86_model);
+ pr_info("CPU (model=0x%x) has no thermal sensor\n",
+ c->x86_model);
return 0;
}
@@ -466,7 +468,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
pdev = platform_device_alloc(DRVNAME, cpu);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
@@ -478,8 +480,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_free;
}
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 980c17d5eeae..e9a610bfd0cc 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -25,6 +25,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -2446,7 +2448,7 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
/* Get the base address of the runtime registers */
if (!(base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
dme1737_sio_inb(sio_cip, 0x61))) {
- printk(KERN_ERR "dme1737: Base address not set.\n");
+ pr_err("Base address not set\n");
err = -ENODEV;
goto exit;
}
@@ -2475,20 +2477,18 @@ static int __init dme1737_isa_device_add(unsigned short addr)
goto exit;
if (!(pdev = platform_device_alloc("dme1737", addr))) {
- printk(KERN_ERR "dme1737: Failed to allocate device.\n");
+ pr_err("Failed to allocate device\n");
err = -ENOMEM;
goto exit;
}
if ((err = platform_device_add_resources(pdev, &res, 1))) {
- printk(KERN_ERR "dme1737: Failed to add device resource "
- "(err = %d).\n", err);
+ pr_err("Failed to add device resource (err = %d)\n", err);
goto exit_device_put;
}
if ((err = platform_device_add(pdev))) {
- printk(KERN_ERR "dme1737: Failed to add device (err = %d).\n",
- err);
+ pr_err("Failed to add device (err = %d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
new file mode 100644
index 000000000000..95dc44bf087d
--- /dev/null
+++ b/drivers/hwmon/ds620.c
@@ -0,0 +1,370 @@
+/*
+ ds620.c - Support for temperature sensor and thermostat DS620
+
+ Copyright (C) 2010 Roland Stigge <stigge@antcom.de>
+
+ based on ds1621.c by Christian W. Zuckschwerdt <zany@triq.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., 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>
+#include <linux/sysfs.h>
+
+/* Addresses to scan */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+ 0x4d, 0x4e, 0x4f, I2C_CLIENT_END
+};
+
+/* Many DS620 constants specified below */
+/* Config register used for detection */
+/* 15 14 13 12 11 10 09 08 */
+/* |Done|NVB |THF |TLF |R1 |R0 |AUTOC|1SHOT| */
+
+/* 07 06 05 04 03 02 01 00 */
+/* |PO2 |PO1 |A2 |A1 |A0 | | | | */
+#define DS620_REG_CONFIG_DONE 0x8000
+#define DS620_REG_CONFIG_NVB 0x4000
+#define DS620_REG_CONFIG_THF 0x2000
+#define DS620_REG_CONFIG_TLF 0x1000
+#define DS620_REG_CONFIG_R1 0x0800
+#define DS620_REG_CONFIG_R0 0x0400
+#define DS620_REG_CONFIG_AUTOC 0x0200
+#define DS620_REG_CONFIG_1SHOT 0x0100
+#define DS620_REG_CONFIG_PO2 0x0080
+#define DS620_REG_CONFIG_PO1 0x0040
+#define DS620_REG_CONFIG_A2 0x0020
+#define DS620_REG_CONFIG_A1 0x0010
+#define DS620_REG_CONFIG_A0 0x0008
+
+/* The DS620 registers */
+static const u8 DS620_REG_TEMP[3] = {
+ 0xAA, /* input, word, RO */
+ 0xA2, /* min, word, RW */
+ 0xA0, /* max, word, RW */
+};
+
+#define DS620_REG_CONF 0xAC /* word, RW */
+#define DS620_COM_START 0x51 /* no data */
+#define DS620_COM_STOP 0x22 /* no data */
+
+/* Conversions */
+#define ALARMS_FROM_REG(val) ((val) & \
+ (DS620_REG_CONFIG_THF | DS620_REG_CONFIG_TLF))
+
+/* Each client has this additional data */
+struct ds620_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if following fields are valid */
+ unsigned long last_updated; /* In jiffies */
+
+ u16 temp[3]; /* Register values, word */
+ u16 conf; /* Register encoding, combined */
+};
+
+/* Temperature registers are word-sized.
+ DS620 uses a high-byte first convention, which is exactly opposite to
+ the SMBus standard. */
+static int ds620_read_temp(struct i2c_client *client, u8 reg)
+{
+ int ret;
+
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return swab16(ret);
+}
+
+static int ds620_write_temp(struct i2c_client *client, u8 reg, u16 value)
+{
+ return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
+
+static void ds620_init_client(struct i2c_client *client)
+{
+ u16 conf, new_conf;
+
+ new_conf = conf =
+ swab16(i2c_smbus_read_word_data(client, DS620_REG_CONF));
+
+ /* switch to continuous conversion mode */
+ new_conf &= ~DS620_REG_CONFIG_1SHOT;
+ /* with highest precision */
+ new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0;
+
+ if (conf != new_conf) {
+ i2c_smbus_write_word_data(client, DS620_REG_CONF,
+ swab16(new_conf));
+ }
+
+ /* start conversion */
+ i2c_smbus_write_byte(client, DS620_COM_START);
+}
+
+static struct ds620_data *ds620_update_client(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds620_data *data = i2c_get_clientdata(client);
+ struct ds620_data *ret = data;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+ int res;
+
+ dev_dbg(&client->dev, "Starting ds620 update\n");
+
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
+ res = ds620_read_temp(client,
+ DS620_REG_TEMP[i]);
+ if (res < 0) {
+ ret = ERR_PTR(res);
+ goto abort;
+ }
+
+ data->temp[i] = res;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+abort:
+ mutex_unlock(&data->update_lock);
+ return ret;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ds620_data *data = ds620_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ return sprintf(buf, "%d\n", ((data->temp[attr->index] / 8) * 625) / 10);
+}
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int res;
+ long val;
+
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds620_data *data = i2c_get_clientdata(client);
+
+ res = strict_strtol(buf, 10, &val);
+ if (res)
+ return res;
+
+ val = (val * 10 / 625) * 8;
+
+ mutex_lock(&data->update_lock);
+ data->temp[attr->index] = val;
+ ds620_write_temp(client, DS620_REG_TEMP[attr->index],
+ data->temp[attr->index]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ds620_data *data = ds620_update_client(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ u16 new_conf;
+ int res;
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ /* reset alarms if necessary */
+ res = i2c_smbus_read_word_data(client, DS620_REG_CONF);
+ if (res < 0)
+ return res;
+
+ data->conf = swab16(res);
+ new_conf = data->conf;
+ if (data->temp[0] > data->temp[1]) /* input > min */
+ new_conf &= ~DS620_REG_CONFIG_TLF;
+ if (data->temp[0] < data->temp[2]) /* input < max */
+ new_conf &= ~DS620_REG_CONFIG_THF;
+ if (data->conf != new_conf) {
+ res = i2c_smbus_write_word_data(client, DS620_REG_CONF,
+ swab16(new_conf));
+ if (res < 0)
+ return res;
+ }
+
+ return sprintf(buf, "%d\n", !!(data->conf & attr->index));
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, 1);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, 2);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL,
+ DS620_REG_CONFIG_TLF);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
+ DS620_REG_CONFIG_THF);
+
+static struct attribute *ds620_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_min.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group ds620_group = {
+ .attrs = ds620_attributes,
+};
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int ds620_detect(struct i2c_client *client, struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;
+ int result, conf, temp;
+ int i;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_WORD_DATA
+ | I2C_FUNC_SMBUS_WRITE_BYTE))
+ return -ENODEV;
+
+ /* Now, we do the remaining detection. */
+ result = i2c_smbus_read_word_data(client, DS620_REG_CONF);
+ conf = swab16(result);
+ if (result < 0 || conf & DS620_REG_CONFIG_NVB ||
+ ((conf & DS620_REG_CONFIG_DONE) &&
+ (conf & DS620_REG_CONFIG_AUTOC)) ||
+ !((conf & DS620_REG_CONFIG_DONE) &&
+ !(conf & DS620_REG_CONFIG_AUTOC)))
+ return -ENODEV;
+ /* The 3 lowest bits of a temperature should always be 0. */
+ for (i = 0; i < ARRAY_SIZE(DS620_REG_TEMP); i++) {
+ temp = i2c_smbus_read_word_data(client, DS620_REG_TEMP[i]);
+ if (temp < 0 || (temp & 0x0700))
+ return -ENODEV;
+ }
+
+ strlcpy(info->type, "ds620", I2C_NAME_SIZE);
+
+ return 0;
+}
+
+static int ds620_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ds620_data *data;
+ int err;
+
+ data = kzalloc(sizeof(struct ds620_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ /* Initialize the DS620 chip */
+ ds620_init_client(client);
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &ds620_group);
+ 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_files;
+ }
+
+ dev_info(&client->dev, "temperature sensor found\n");
+
+ return 0;
+
+exit_remove_files:
+ sysfs_remove_group(&client->dev.kobj, &ds620_group);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int ds620_remove(struct i2c_client *client)
+{
+ struct ds620_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ds620_group);
+
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id ds620_id[] = {
+ {"ds620", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ds620_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ds620_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ds620",
+ },
+ .probe = ds620_probe,
+ .remove = ds620_remove,
+ .id_table = ds620_id,
+ .detect = ds620_detect,
+ .address_list = normal_i2c,
+};
+
+static int __init ds620_init(void)
+{
+ return i2c_add_driver(&ds620_driver);
+}
+
+static void __exit ds620_exit(void)
+{
+ i2c_del_driver(&ds620_driver);
+}
+
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("DS620 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds620_init);
+module_exit(ds620_exit);
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 8dee3f38fdfb..5dea9faa1656 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -269,23 +269,30 @@ static int emc1403_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
int id;
- /* Check if thermal chip is SMSC and EMC1403 */
+ /* Check if thermal chip is SMSC and EMC1403 or EMC1423 */
id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG);
if (id != 0x5d)
return -ENODEV;
+ id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG);
+ switch (id) {
+ case 0x21:
+ strlcpy(info->type, "emc1403", I2C_NAME_SIZE);
+ break;
+ case 0x23:
+ strlcpy(info->type, "emc1423", I2C_NAME_SIZE);
+ break;
/* Note: 0x25 is the 1404 which is very similar and this
driver could be extended */
- id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG);
- if (id != 0x21)
+ default:
return -ENODEV;
+ }
id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG);
if (id != 0x01)
return -ENODEV;
- strlcpy(info->type, "emc1403", I2C_NAME_SIZE);
return 0;
}
@@ -342,6 +349,7 @@ static const unsigned short emc1403_address_list[] = {
static const struct i2c_device_id emc1403_idtable[] = {
{ "emc1403", 0 },
+ { "emc1423", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 525a00bd70b1..92f949767ece 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -28,6 +28,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1309,7 +1311,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Out of memory\n");
+ pr_err("Out of memory\n");
goto exit;
}
@@ -1451,7 +1453,7 @@ static int __init f71805f_device_add(unsigned short address,
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
@@ -1462,22 +1464,20 @@ static int __init f71805f_device_add(unsigned short address,
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add_data(pdev, sio_data,
sizeof(struct f71805f_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
@@ -1516,30 +1516,27 @@ static int __init f71805f_find(int sioaddr, unsigned short *address,
sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
break;
default:
- printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
- "skipping\n");
+ pr_info("Unsupported Fintek device, skipping\n");
goto exit;
}
superio_select(sioaddr, F71805F_LD_HWM);
if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
- printk(KERN_WARNING DRVNAME ": Device not activated, "
- "skipping\n");
+ pr_warn("Device not activated, skipping\n");
goto exit;
}
*address = superio_inw(sioaddr, SIO_REG_ADDR);
if (*address == 0) {
- printk(KERN_WARNING DRVNAME ": Base address not set, "
- "skipping\n");
+ pr_warn("Base address not set, skipping\n");
goto exit;
}
*address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
err = 0;
- printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n",
- names[sio_data->kind], *address,
- superio_inb(sioaddr, SIO_REG_DEVREV));
+ pr_info("Found %s chip at %#x, revision %u\n",
+ names[sio_data->kind], *address,
+ superio_inb(sioaddr, SIO_REG_DEVREV));
exit:
superio_exit(sioaddr);
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 75afb3b0e076..3f49dd376f02 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -865,8 +867,7 @@ static inline int superio_enter(int base)
{
/* Don't step on other drivers' I/O space by accident */
if (!request_muxed_region(base, 2, DRVNAME)) {
- printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
- base);
+ pr_err("I/O address 0x%04x already in use\n", base);
return -EBUSY;
}
@@ -2192,7 +2193,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
devid = superio_inw(sioaddr, SIO_REG_MANID);
if (devid != SIO_FINTEK_ID) {
- pr_debug(DRVNAME ": Not a Fintek device\n");
+ pr_debug("Not a Fintek device\n");
err = -ENODEV;
goto exit;
}
@@ -2215,8 +2216,8 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
sio_data->type = f8000;
break;
default:
- printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
- (unsigned int)devid);
+ pr_info("Unsupported Fintek device: %04x\n",
+ (unsigned int)devid);
err = -ENODEV;
goto exit;
}
@@ -2227,21 +2228,21 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
superio_select(sioaddr, SIO_F71882FG_LD_HWM);
if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
- printk(KERN_WARNING DRVNAME ": Device not activated\n");
+ pr_warn("Device not activated\n");
err = -ENODEV;
goto exit;
}
*address = superio_inw(sioaddr, SIO_REG_ADDR);
if (*address == 0) {
- printk(KERN_WARNING DRVNAME ": Base address not set\n");
+ pr_warn("Base address not set\n");
err = -ENODEV;
goto exit;
}
*address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
err = 0;
- printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
+ pr_info("Found %s chip at %#x, revision %d\n",
f71882fg_names[sio_data->type], (unsigned int)*address,
(int)superio_inb(sioaddr, SIO_REG_DEVREV));
exit:
@@ -2270,20 +2271,20 @@ static int __init f71882fg_device_add(unsigned short address,
err = platform_device_add_resources(f71882fg_pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
+ pr_err("Device resource addition failed\n");
goto exit_device_put;
}
err = platform_device_add_data(f71882fg_pdev, sio_data,
sizeof(struct f71882fg_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(f71882fg_pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed\n");
+ pr_err("Device addition failed\n");
goto exit_device_put;
}
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index d4d4ca65d371..aa6d8b686f82 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -49,7 +49,6 @@
#include <linux/kref.h>
/* Addresses to scan */
-static DEFINE_MUTEX(watchdog_mutex);
static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
/* Insmod parameters */
@@ -850,7 +849,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf,
static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- static struct watchdog_info ident = {
+ struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
WDIOF_CARDRESET,
.identity = "FSC watchdog"
@@ -858,7 +857,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar
int i, ret = 0;
struct fschmd_data *data = filp->private_data;
- mutex_lock(&watchdog_mutex);
switch (cmd) {
case WDIOC_GETSUPPORT:
ident.firmware_version = data->revision;
@@ -915,7 +913,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar
default:
ret = -ENOTTY;
}
- mutex_unlock(&watchdog_mutex);
return ret;
}
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index a56a78412fcb..3d21fa2b97cd 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dmi.h>
@@ -147,7 +149,7 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
{
lis3_dev.ac = *((union axis_conversion *)dmi->driver_data);
- printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
+ pr_info("hardware type %s found\n", dmi->ident);
return 1;
}
@@ -303,11 +305,10 @@ static int lis3lv02d_add(struct acpi_device *device)
/* If possible use a "standard" axes order */
if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) {
- printk(KERN_INFO DRIVER_NAME ": Using custom axes %d,%d,%d\n",
- lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z);
+ pr_info("Using custom axes %d,%d,%d\n",
+ lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z);
} else if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
- printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
- "using default axes configuration\n");
+ pr_info("laptop model unknown, using default axes configuration\n");
lis3_dev.ac = lis3lv02d_axis_normal;
}
@@ -385,7 +386,7 @@ static int __init lis3lv02d_init_module(void)
if (ret < 0)
return ret;
- printk(KERN_INFO DRIVER_NAME " driver loaded.\n");
+ pr_info("driver loaded\n");
return 0;
}
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 2b2ca1694f95..2582bfef6ccb 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -22,6 +22,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hwmon-vid.h>
@@ -146,8 +148,8 @@ int vid_from_reg(int val, u8 vrm)
return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
default: /* report 0 for unknown */
if (vrm)
- printk(KERN_WARNING "hwmon-vid: Requested unsupported "
- "VRM version (%u)\n", (unsigned int)vrm);
+ pr_warn("Requested unsupported VRM version (%u)\n",
+ (unsigned int)vrm);
return 0;
}
}
@@ -246,8 +248,7 @@ u8 vid_which_vrm(void)
}
vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor);
if (vrm_ret == 0)
- printk(KERN_INFO "hwmon-vid: Unknown VRM version of your "
- "x86 CPU\n");
+ pr_info("Unknown VRM version of your x86 CPU\n");
return vrm_ret;
}
@@ -255,7 +256,7 @@ u8 vid_which_vrm(void)
#else
u8 vid_which_vrm(void)
{
- printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n");
+ pr_info("Unknown VRM version of your CPU\n");
return 0;
}
#endif
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 29ea6753f3bb..a61e7815a2a9 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -10,6 +10,8 @@
the Free Software Foundation; version 2 of the License.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -119,7 +121,7 @@ static int __init hwmon_init(void)
hwmon_class = class_create(THIS_MODULE, "hwmon");
if (IS_ERR(hwmon_class)) {
- printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n");
+ pr_err("couldn't create sysfs class\n");
return PTR_ERR(hwmon_class);
}
return 0;
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index eaee546af19a..bc6e2ab3a361 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/ipmi.h>
#include <linux/module.h>
#include <linux/hwmon.h>
@@ -1090,7 +1092,7 @@ static int __init aem_init(void)
res = driver_register(&aem_driver.driver);
if (res) {
- printk(KERN_ERR "Can't register aem driver\n");
+ pr_err("Can't register aem driver\n");
return res;
}
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 14a5d981be7d..316b64823f7b 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -38,6 +38,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -187,6 +189,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
#define IT87_REG_PWM(nr) (0x15 + (nr))
+#define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8)
#define IT87_REG_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr))
@@ -251,12 +254,16 @@ struct it87_data {
u8 fan_main_ctrl; /* Register value */
u8 fan_ctl; /* Register value */
- /* 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. */
+ /* The following 3 arrays correspond to the same registers up to
+ * the IT8720F. 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.
+ * Starting with the IT8721F, the manual PWM duty cycles are stored
+ * in separate registers (8-bit values), so the separate tracking
+ * is no longer needed, but it is still done to keep the driver
+ * simple. */
u8 pwm_ctrl[3]; /* Register value */
- u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */
+ u8 pwm_duty[3]; /* Manual PWM value set by user */
u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
/* Automatic fan speed control registers */
@@ -832,7 +839,9 @@ static ssize_t set_pwm_enable(struct device *dev,
data->fan_main_ctrl);
} else {
if (val == 1) /* Manual mode */
- data->pwm_ctrl[nr] = data->pwm_duty[nr];
+ data->pwm_ctrl[nr] = data->type == it8721 ?
+ data->pwm_temp_map[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]);
@@ -858,12 +867,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
return -EINVAL;
mutex_lock(&data->update_lock);
- data->pwm_duty[nr] = pwm_to_reg(data, 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]);
+ if (data->type == it8721) {
+ /* If we are in automatic mode, the PWM duty cycle register
+ * is read-only so we can't write the value */
+ if (data->pwm_ctrl[nr] & 0x80) {
+ mutex_unlock(&data->update_lock);
+ return -EBUSY;
+ }
+ data->pwm_duty[nr] = pwm_to_reg(data, val);
+ it87_write_value(data, IT87_REG_PWM_DUTY(nr),
+ data->pwm_duty[nr]);
+ } else {
+ data->pwm_duty[nr] = pwm_to_reg(data, 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;
@@ -1550,26 +1572,25 @@ static int __init it87_find(unsigned short *address,
case 0xffff: /* No device at all */
goto exit;
default:
- pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n",
- chip_type);
+ pr_debug("Unsupported chip (DEVID=0x%x)\n", chip_type);
goto exit;
}
superio_select(PME);
if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
- pr_info("it87: Device not activated, skipping\n");
+ pr_info("Device not activated, skipping\n");
goto exit;
}
*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
if (*address == 0) {
- pr_info("it87: Base address not set, skipping\n");
+ pr_info("Base address not set, skipping\n");
goto exit;
}
err = 0;
sio_data->revision = superio_inb(DEVREV) & 0x0f;
- pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
+ pr_info("Found IT%04xF chip at 0x%x, revision %d\n",
chip_type, *address, sio_data->revision);
/* in8 (Vbat) is always internal */
@@ -1595,7 +1616,7 @@ static int __init it87_find(unsigned short *address,
} else {
/* We need at least 4 VID pins */
if (reg & 0x0f) {
- pr_info("it87: VID is disabled (pins used for GPIO)\n");
+ pr_info("VID is disabled (pins used for GPIO)\n");
sio_data->skip_vid = 1;
}
}
@@ -1631,7 +1652,7 @@ static int __init it87_find(unsigned short *address,
if (sio_data->type == it8720 && !(reg & (1 << 1))) {
reg |= (1 << 1);
superio_outb(IT87_SIO_PINX2_REG, reg);
- pr_notice("it87: Routing internal VCCH to in7\n");
+ pr_notice("Routing internal VCCH to in7\n");
}
if (reg & (1 << 0))
sio_data->internal |= (1 << 0);
@@ -1641,7 +1662,7 @@ static int __init it87_find(unsigned short *address,
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
}
if (sio_data->beep_pin)
- pr_info("it87: Beeping is supported\n");
+ pr_info("Beeping is supported\n");
/* Disable specific features based on DMI strings */
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1655,8 +1676,7 @@ static int __init it87_find(unsigned short *address,
the PWM2 duty cycle, so we disable it.
I use the board name string as the trigger in case
the same board is ever used in other systems. */
- pr_info("it87: Disabling pwm2 due to "
- "hardware constraints\n");
+ pr_info("Disabling pwm2 due to hardware constraints\n");
sio_data->skip_pwm = (1 << 1);
}
}
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
* 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. */
+ * prior to switching to a different mode.
+ * Note that this is no longer needed for the IT8721F and later, as
+ * these have separate registers for the temperature mapping and the
+ * manual duty cycle. */
for (i = 0; i < 3; i++) {
data->pwm_temp_map[i] = i;
data->pwm_duty[i] = 0x7f; /* Full speed */
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev)
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 */
+ if (data->type == it8721) {
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
- else /* Manual mode */
- data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+ data->pwm_duty[nr] = it87_read_value(data,
+ IT87_REG_PWM_DUTY(nr));
+ } else {
+ 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;
@@ -2160,28 +2189,26 @@ static int __init it87_device_add(unsigned short address,
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add_data(pdev, sio_data,
sizeof(struct it87_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 0cee73a6124e..1b674b7d4584 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dmi.h>
@@ -860,8 +862,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
(p->irq_flags2 & IRQF_TRIGGER_MASK),
DRIVER_NAME, &lis3_dev);
if (err < 0)
- printk(KERN_ERR DRIVER_NAME
- "No second IRQ. Limited functionality\n");
+ pr_err("No second IRQ. Limited functionality\n");
}
}
@@ -879,7 +880,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
switch (dev->whoami) {
case WAI_12B:
- printk(KERN_INFO DRIVER_NAME ": 12 bits sensor found\n");
+ pr_info("12 bits sensor found\n");
dev->read_data = lis3lv02d_read_12;
dev->mdps_max_val = 2048;
dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
@@ -890,7 +891,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
break;
case WAI_8B:
- printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
+ pr_info("8 bits sensor found\n");
dev->read_data = lis3lv02d_read_8;
dev->mdps_max_val = 128;
dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
@@ -901,7 +902,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
break;
case WAI_3DC:
- printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n");
+ pr_info("8 bits 3DC sensor found\n");
dev->read_data = lis3lv02d_read_8;
dev->mdps_max_val = 128;
dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
@@ -910,8 +911,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
dev->scale = LIS3_SENSITIVITY_8B;
break;
default:
- printk(KERN_ERR DRIVER_NAME
- ": unknown sensor type 0x%X\n", dev->whoami);
+ pr_err("unknown sensor type 0x%X\n", dev->whoami);
return -EINVAL;
}
@@ -935,7 +935,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
}
if (lis3lv02d_joystick_enable())
- printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+ pr_err("joystick initialization failed\n");
/* passing in platform specific data is purely optional and only
* used by the SPI transport layer at the moment */
@@ -957,8 +957,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
/* bail if we did not get an IRQ from the bus layer */
if (!dev->irq) {
- printk(KERN_ERR DRIVER_NAME
- ": No IRQ. Disabling /dev/freefall\n");
+ pr_err("No IRQ. Disabling /dev/freefall\n");
goto out;
}
@@ -985,12 +984,12 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
DRIVER_NAME, &lis3_dev);
if (err < 0) {
- printk(KERN_ERR DRIVER_NAME "Cannot get IRQ\n");
+ pr_err("Cannot get IRQ\n");
goto out;
}
if (misc_register(&lis3lv02d_misc_device))
- printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+ pr_err("misc_register failed\n");
out:
return 0;
}
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index fd108cfc05c7..3b84fb503053 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -67,8 +69,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
*/
status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2);
if (status < 0) {
- printk(KERN_WARNING
- "spi_write_then_read failed with status %d\n", status);
+ pr_warn("spi_write_then_read failed with status %d\n", status);
goto out;
}
raw = (rxbuf[0] << 8) + rxbuf[1];
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 72ff2c4e757d..4cb24eafe318 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -19,6 +19,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -858,7 +860,7 @@ static int __init lm78_isa_found(unsigned short address)
* individually for the probing phase. */
for (port = address; port < address + LM78_EXTENT; port++) {
if (!request_region(port, 1, "lm78")) {
- pr_debug("lm78: Failed to request port 0x%x\n", port);
+ pr_debug("Failed to request port 0x%x\n", port);
goto release;
}
}
@@ -920,7 +922,7 @@ static int __init lm78_isa_found(unsigned short address)
found = 1;
if (found)
- pr_info("lm78: Found an %s chip at %#x\n",
+ pr_info("Found an %s chip at %#x\n",
val & 0x80 ? "LM79" : "LM78", (int)address);
release:
@@ -942,21 +944,19 @@ static int __init lm78_isa_device_add(unsigned short address)
pdev = platform_device_alloc("lm78", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "lm78: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR "lm78: Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "lm78: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 4546d82f024a..1a6dfb6df1e7 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -1,13 +1,9 @@
/*
- * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
- * monitoring
- * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
+ * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com>
*
- * Based on the max1619 driver. The LM95241 is a sensor chip made by National
- * Semiconductors.
- * It reports up to three temperatures (its own plus up to
- * two external ones). Complete datasheet can be
- * obtained from National's website at:
+ * The LM95241 is a sensor chip made by National Semiconductors.
+ * It reports up to three temperatures (its own plus up to two external ones).
+ * Complete datasheet can be obtained from National's website at:
* http://www.national.com/ds.cgi/LM/LM95241.pdf
*
* This program is free software; you can redistribute it and/or modify
@@ -36,8 +32,10 @@
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#define DEVNAME "lm95241"
+
static const unsigned short normal_i2c[] = {
- 0x19, 0x2a, 0x2b, I2C_CLIENT_END};
+ 0x19, 0x2a, 0x2b, I2C_CLIENT_END };
/* LM95241 registers */
#define LM95241_REG_R_MAN_ID 0xFE
@@ -46,7 +44,7 @@ static const unsigned short normal_i2c[] = {
#define LM95241_REG_RW_CONFIG 0x03
#define LM95241_REG_RW_REM_FILTER 0x06
#define LM95241_REG_RW_TRUTHERM 0x07
-#define LM95241_REG_W_ONE_SHOT 0x0F
+#define LM95241_REG_W_ONE_SHOT 0x0F
#define LM95241_REG_R_LOCAL_TEMPH 0x10
#define LM95241_REG_R_REMOTE1_TEMPH 0x11
#define LM95241_REG_R_REMOTE2_TEMPH 0x12
@@ -79,235 +77,246 @@ static const unsigned short normal_i2c[] = {
#define MANUFACTURER_ID 0x01
#define DEFAULT_REVISION 0xA4
-/* Conversions and various macros */
-#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
- (val_h)) * 1000 + (val_l) * 1000 / 256)
-
-/* Functions declaration */
-static void lm95241_init_client(struct i2c_client *client);
-static struct lm95241_data *lm95241_update_device(struct device *dev);
+static const u8 lm95241_reg_address[] = {
+ LM95241_REG_R_LOCAL_TEMPH,
+ LM95241_REG_R_LOCAL_TEMPL,
+ LM95241_REG_R_REMOTE1_TEMPH,
+ LM95241_REG_R_REMOTE1_TEMPL,
+ LM95241_REG_R_REMOTE2_TEMPH,
+ LM95241_REG_R_REMOTE2_TEMPL
+};
/* Client data (each client gets its own) */
struct lm95241_data {
struct device *hwmon_dev;
struct mutex update_lock;
- unsigned long last_updated, interval; /* in jiffies */
- char valid; /* zero until following fields are valid */
+ unsigned long last_updated, interval; /* in jiffies */
+ char valid; /* zero until following fields are valid */
/* registers values */
- u8 local_h, local_l; /* local */
- u8 remote1_h, remote1_l; /* remote1 */
- u8 remote2_h, remote2_l; /* remote2 */
+ u8 temp[ARRAY_SIZE(lm95241_reg_address)];
u8 config, model, trutherm;
};
+/* Conversions */
+static int TempFromReg(u8 val_h, u8 val_l)
+{
+ if (val_h & 0x80)
+ return val_h - 0x100;
+ return val_h * 1000 + val_l * 1000 / 256;
+}
+
+static struct lm95241_data *lm95241_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + data->interval) ||
+ !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Updating lm95241 data.\n");
+ for (i = 0; i < ARRAY_SIZE(lm95241_reg_address); i++)
+ data->temp[i]
+ = i2c_smbus_read_byte_data(client,
+ lm95241_reg_address[i]);
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
/* Sysfs stuff */
-#define show_temp(value) \
-static ssize_t show_##value(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct lm95241_data *data = lm95241_update_device(dev); \
- snprintf(buf, PAGE_SIZE - 1, "%d\n", \
- TEMP_FROM_REG(data->value##_h, data->value##_l)); \
- return strlen(buf); \
+static ssize_t show_input(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct lm95241_data *data = lm95241_update_device(dev);
+
+ return snprintf(buf, PAGE_SIZE - 1, "%d\n",
+ TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
+ data->temp[to_sensor_dev_attr(attr)->index + 1]));
}
-show_temp(local);
-show_temp(remote1);
-show_temp(remote2);
-static ssize_t show_interval(struct device *dev, struct device_attribute *attr,
+static ssize_t show_type(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct lm95241_data *data = lm95241_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
- snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval / HZ);
- return strlen(buf);
+ return snprintf(buf, PAGE_SIZE - 1,
+ data->model & to_sensor_dev_attr(attr)->index ? "1\n" : "2\n");
}
-static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
+static ssize_t set_type(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm95241_data *data = i2c_get_clientdata(client);
unsigned long val;
+ int shift;
+ u8 mask = to_sensor_dev_attr(attr)->index;
if (strict_strtoul(buf, 10, &val) < 0)
return -EINVAL;
+ if (val != 1 && val != 2)
+ return -EINVAL;
- data->interval = val * HZ / 1000;
+ shift = mask == R1MS_MASK ? TT1_SHIFT : TT2_SHIFT;
+
+ mutex_lock(&data->update_lock);
+
+ data->trutherm &= ~(TT_MASK << shift);
+ if (val == 1) {
+ data->model |= mask;
+ data->trutherm |= (TT_ON << shift);
+ } else {
+ data->model &= ~mask;
+ data->trutherm |= (TT_OFF << shift);
+ }
+ data->valid = 0;
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+ data->model);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+ data->trutherm);
+
+ mutex_unlock(&data->update_lock);
return count;
}
-#define show_type(flag) \
-static ssize_t show_type##flag(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- snprintf(buf, PAGE_SIZE - 1, \
- data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
- return strlen(buf); \
+static ssize_t show_min(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ return snprintf(buf, PAGE_SIZE - 1,
+ data->config & to_sensor_dev_attr(attr)->index ?
+ "-127000\n" : "0\n");
}
-show_type(1);
-show_type(2);
-
-#define show_min(flag) \
-static ssize_t show_min##flag(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- snprintf(buf, PAGE_SIZE - 1, \
- data->config & R##flag##DF_MASK ? \
- "-127000\n" : "0\n"); \
- return strlen(buf); \
+
+static ssize_t set_min(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
+ if (val < -128000)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+
+ if (val < 0)
+ data->config |= to_sensor_dev_attr(attr)->index;
+ else
+ data->config &= ~to_sensor_dev_attr(attr)->index;
+ data->valid = 0;
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
}
-show_min(1);
-show_min(2);
-
-#define show_max(flag) \
-static ssize_t show_max##flag(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- snprintf(buf, PAGE_SIZE - 1, \
- data->config & R##flag##DF_MASK ? \
- "127000\n" : "255000\n"); \
- return strlen(buf); \
+
+static ssize_t show_max(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ return snprintf(buf, PAGE_SIZE - 1,
+ data->config & to_sensor_dev_attr(attr)->index ?
+ "127000\n" : "255000\n");
}
-show_max(1);
-show_max(2);
-
-#define set_type(flag) \
-static ssize_t set_type##flag(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- long val; \
-\
- if (strict_strtol(buf, 10, &val) < 0) \
- return -EINVAL; \
-\
- if ((val == 1) || (val == 2)) { \
-\
- mutex_lock(&data->update_lock); \
-\
- data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
- if (val == 1) { \
- data->model |= R##flag##MS_MASK; \
- data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
- } \
- else { \
- data->model &= ~R##flag##MS_MASK; \
- data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
- } \
-\
- data->valid = 0; \
-\
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
- data->model); \
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
- data->trutherm); \
-\
- mutex_unlock(&data->update_lock); \
-\
- } \
- return count; \
+
+static ssize_t set_max(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
+ if (val >= 256000)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+
+ if (val <= 127000)
+ data->config |= to_sensor_dev_attr(attr)->index;
+ else
+ data->config &= ~to_sensor_dev_attr(attr)->index;
+ data->valid = 0;
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
}
-set_type(1);
-set_type(2);
-
-#define set_min(flag) \
-static ssize_t set_min##flag(struct device *dev, \
- struct device_attribute *devattr, const char *buf, size_t count) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- long val; \
-\
- if (strict_strtol(buf, 10, &val) < 0) \
- return -EINVAL;\
-\
- mutex_lock(&data->update_lock); \
-\
- if (val < 0) \
- data->config |= R##flag##DF_MASK; \
- else \
- data->config &= ~R##flag##DF_MASK; \
-\
- data->valid = 0; \
-\
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
- data->config); \
-\
- mutex_unlock(&data->update_lock); \
-\
- return count; \
+
+static ssize_t show_interval(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct lm95241_data *data = lm95241_update_device(dev);
+
+ return snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval
+ / HZ);
}
-set_min(1);
-set_min(2);
-
-#define set_max(flag) \
-static ssize_t set_max##flag(struct device *dev, \
- struct device_attribute *devattr, const char *buf, size_t count) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm95241_data *data = i2c_get_clientdata(client); \
-\
- long val; \
-\
- if (strict_strtol(buf, 10, &val) < 0) \
- return -EINVAL; \
-\
- mutex_lock(&data->update_lock); \
-\
- if (val <= 127000) \
- data->config |= R##flag##DF_MASK; \
- else \
- data->config &= ~R##flag##DF_MASK; \
-\
- data->valid = 0; \
-\
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
- data->config); \
-\
- mutex_unlock(&data->update_lock); \
-\
- return count; \
+
+static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
+
+ data->interval = val * HZ / 1000;
+
+ return count;
}
-set_max(1);
-set_max(2);
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
-static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
-static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
-static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
-static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
-static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type,
+ R1MS_MASK);
+static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type,
+ R2MS_MASK);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min,
+ R1DF_MASK);
+static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min,
+ R2DF_MASK);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max,
+ R1DF_MASK);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max,
+ R2DF_MASK);
static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval,
set_interval);
static struct attribute *lm95241_attributes[] = {
- &dev_attr_temp1_input.attr,
- &dev_attr_temp2_input.attr,
- &dev_attr_temp3_input.attr,
- &dev_attr_temp2_type.attr,
- &dev_attr_temp3_type.attr,
- &dev_attr_temp2_min.attr,
- &dev_attr_temp3_min.attr,
- &dev_attr_temp2_max.attr,
- &dev_attr_temp3_max.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_temp2_type.dev_attr.attr,
+ &sensor_dev_attr_temp3_type.dev_attr.attr,
+ &sensor_dev_attr_temp2_min.dev_attr.attr,
+ &sensor_dev_attr_temp3_min.dev_attr.attr,
+ &sensor_dev_attr_temp2_max.dev_attr.attr,
+ &sensor_dev_attr_temp3_max.dev_attr.attr,
&dev_attr_update_interval.attr,
NULL
};
@@ -329,9 +338,9 @@ static int lm95241_detect(struct i2c_client *new_client,
if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
== MANUFACTURER_ID)
- && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
- >= DEFAULT_REVISION)) {
- name = "lm95241";
+ && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+ >= DEFAULT_REVISION)) {
+ name = DEVNAME;
} else {
dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
address);
@@ -343,6 +352,25 @@ static int lm95241_detect(struct i2c_client *new_client,
return 0;
}
+static void lm95241_init_client(struct i2c_client *client)
+{
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ data->interval = HZ; /* 1 sec default */
+ data->valid = 0;
+ data->config = CFG_CR0076;
+ data->model = 0;
+ data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
+ R1FE_MASK | R2FE_MASK);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+ data->trutherm);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+ data->model);
+}
+
static int lm95241_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
@@ -382,26 +410,6 @@ exit:
return err;
}
-static void lm95241_init_client(struct i2c_client *client)
-{
- struct lm95241_data *data = i2c_get_clientdata(client);
-
- data->interval = HZ; /* 1 sec default */
- data->valid = 0;
- data->config = CFG_CR0076;
- data->model = 0;
- data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
-
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
- data->config);
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
- R1FE_MASK | R2FE_MASK);
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
- data->trutherm);
- i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
- data->model);
-}
-
static int lm95241_remove(struct i2c_client *client)
{
struct lm95241_data *data = i2c_get_clientdata(client);
@@ -413,46 +421,9 @@ static int lm95241_remove(struct i2c_client *client)
return 0;
}
-static struct lm95241_data *lm95241_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm95241_data *data = i2c_get_clientdata(client);
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + data->interval) ||
- !data->valid) {
- dev_dbg(&client->dev, "Updating lm95241 data.\n");
- data->local_h =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_LOCAL_TEMPH);
- data->local_l =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_LOCAL_TEMPL);
- data->remote1_h =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_REMOTE1_TEMPH);
- data->remote1_l =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_REMOTE1_TEMPL);
- data->remote2_h =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_REMOTE2_TEMPH);
- data->remote2_l =
- i2c_smbus_read_byte_data(client,
- LM95241_REG_R_REMOTE2_TEMPL);
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
-
- return data;
-}
-
/* Driver data (common to all clients) */
static const struct i2c_device_id lm95241_id[] = {
- { "lm95241", 0 },
+ { DEVNAME, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm95241_id);
@@ -460,7 +431,7 @@ MODULE_DEVICE_TABLE(i2c, lm95241_id);
static struct i2c_driver lm95241_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
- .name = "lm95241",
+ .name = DEVNAME,
},
.probe = lm95241_probe,
.remove = lm95241_remove,
@@ -479,7 +450,7 @@ static void __exit sensors_lm95241_exit(void)
i2c_del_driver(&lm95241_driver);
}
-MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
+MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>");
MODULE_DESCRIPTION("LM95241 sensor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 00d975eb5b83..c7e6d8e81656 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS);
/* Power (virtual) */
LTC4215_POWER(power1_input);
-LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS);
/* Input Voltage */
LTC4215_VOLTAGE(in1_input, LTC4215_ADIN);
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS);
/* Output Voltage */
LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE);
+LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS);
/* Finally, construct an array of pointers to members of the above objects,
* as required for sysfs_create_group()
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = {
&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
- &sensor_dev_attr_power1_alarm.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
NULL,
};
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 68e69a49633c..3d99b8854d7c 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -33,6 +33,8 @@
* the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1031,16 +1033,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
val = superio_inb(sioaddr, ACT);
if (!(val & 0x01)) {
- printk(KERN_INFO "pc87360: Device 0x%02x not "
- "activated\n", logdev[i]);
+ pr_info("Device 0x%02x not activated\n", logdev[i]);
continue;
}
val = (superio_inb(sioaddr, BASE) << 8)
| superio_inb(sioaddr, BASE + 1);
if (!val) {
- printk(KERN_INFO "pc87360: Base address not set for "
- "device 0x%02x\n", logdev[i]);
+ pr_info("Base address not set for device 0x%02x\n",
+ logdev[i]);
continue;
}
@@ -1050,17 +1051,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
confreg[0] = superio_inb(sioaddr, 0xF0);
confreg[1] = superio_inb(sioaddr, 0xF1);
-#ifdef DEBUG
- printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
- "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
- (confreg[0]>>3)&1, (confreg[0]>>4)&1);
- printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
- "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
- (confreg[0]>>6)&1, (confreg[0]>>7)&1);
- printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
- "ctrl=%d inv=%d\n", confreg[1]&1,
- (confreg[1]>>1)&1, (confreg[1]>>2)&1);
-#endif
+ pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 1,
+ (confreg[0] >> 2) & 1, (confreg[0] >> 3) & 1,
+ (confreg[0] >> 4) & 1);
+ pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 2,
+ (confreg[0] >> 5) & 1, (confreg[0] >> 6) & 1,
+ (confreg[0] >> 7) & 1);
+ pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 3,
+ confreg[1] & 1, (confreg[1] >> 1) & 1,
+ (confreg[1] >> 2) & 1);
} else if (i==1) { /* Voltages */
/* Are we using thermistors? */
if (*devid == 0xE9) { /* PC87366 */
@@ -1071,14 +1070,12 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
confreg[3] = superio_inb(sioaddr, 0x25);
if (confreg[2] & 0x40) {
- printk(KERN_INFO "pc87360: Using "
- "thermistors for temperature "
- "monitoring\n");
+ pr_info("Using thermistors for "
+ "temperature monitoring\n");
}
if (confreg[3] & 0xE0) {
- printk(KERN_INFO "pc87360: VID "
- "inputs routed (mode %u)\n",
- confreg[3] >> 5);
+ pr_info("VID inputs routed (mode %u)\n",
+ confreg[3] >> 5);
}
}
}
@@ -1616,7 +1613,7 @@ static int __init pc87360_device_add(unsigned short address)
pdev = platform_device_alloc("pc87360", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "pc87360: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
@@ -1639,15 +1636,13 @@ static int __init pc87360_device_add(unsigned short address)
err = platform_device_add_resources(pdev, res, res_count);
if (err) {
- printk(KERN_ERR "pc87360: Device resources addition failed "
- "(%d)\n", err);
+ pr_err("Device resources addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "pc87360: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
@@ -1666,8 +1661,7 @@ static int __init pc87360_init(void)
if (pc87360_find(0x2e, &devid, extra_isa)
&& pc87360_find(0x4e, &devid, extra_isa)) {
- printk(KERN_WARNING "pc87360: PC8736x not detected, "
- "module not inserted.\n");
+ pr_warn("PC8736x not detected, module not inserted\n");
return -ENODEV;
}
@@ -1680,8 +1674,7 @@ static int __init pc87360_init(void)
}
if (address == 0x0000) {
- printk(KERN_WARNING "pc87360: No active logical device, "
- "module not inserted.\n");
+ pr_warn("No active logical device, module not inserted\n");
return -ENODEV;
}
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 9ec4daaf6ca6..8da2181630b1 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -22,6 +22,8 @@
* mode, and voltages aren't supported at all.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1077,7 +1079,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Out of memory\n");
+ pr_err("Out of memory\n");
goto exit;
}
@@ -1196,28 +1198,26 @@ static int __init pc87427_device_add(const struct pc87427_sio_data *sio_data)
pdev = platform_device_alloc(DRVNAME, res[0].start);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, res, res_count);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add_data(pdev, sio_data,
sizeof(struct pc87427_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
@@ -1249,23 +1249,23 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data)
val = superio_inb(sioaddr, SIOREG_ACT);
if (!(val & 0x01)) {
- printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
- "not activated\n", logdev[i]);
+ pr_info("Logical device 0x%02x not activated\n",
+ logdev[i]);
continue;
}
val = superio_inb(sioaddr, SIOREG_MAP);
if (val & 0x01) {
- printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
- "is memory-mapped, can't use\n", logdev[i]);
+ pr_warn("Logical device 0x%02x is memory-mapped, "
+ "can't use\n", logdev[i]);
continue;
}
val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
| superio_inb(sioaddr, SIOREG_IOBASE + 1);
if (!val) {
- printk(KERN_INFO DRVNAME ": I/O base address not set "
- "for logical device 0x%02x\n", logdev[i]);
+ pr_info("I/O base address not set for logical device "
+ "0x%02x\n", logdev[i]);
continue;
}
sio_data->address[i] = val;
diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c
index dc7259d69812..731b09af76b9 100644
--- a/drivers/hwmon/pcf8591.c
+++ b/drivers/hwmon/pcf8591.c
@@ -18,6 +18,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -290,8 +292,7 @@ static struct i2c_driver pcf8591_driver = {
static int __init pcf8591_init(void)
{
if (input_mode < 0 || input_mode > 3) {
- printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n",
- input_mode);
+ pr_warn("invalid input_mode (%d)\n", input_mode);
input_mode = 0;
}
return i2c_add_driver(&pcf8591_driver);
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c
index 0798210590bc..21c817d98123 100644
--- a/drivers/hwmon/pkgtemp.c
+++ b/drivers/hwmon/pkgtemp.c
@@ -20,6 +20,8 @@
* 02110-1301 USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -303,7 +305,7 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu)
pdev = platform_device_alloc(DRVNAME, cpu);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
@@ -315,8 +317,7 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu)
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_free;
}
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index 05248f2d7581..92b42db43bcf 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -234,7 +234,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr->index = channel;
attr->dev_attr.attr.name = attrs->in_name;
attr->dev_attr.attr.mode = S_IRUGO;
- attr->dev_attr.attr.owner = THIS_MODULE;
attr->dev_attr.show = s3c_hwmon_ch_show;
ret = device_create_file(dev, &attr->dev_attr);
@@ -252,7 +251,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr->index = channel;
attr->dev_attr.attr.name = attrs->label_name;
attr->dev_attr.attr.mode = S_IRUGO;
- attr->dev_attr.attr.owner = THIS_MODULE;
attr->dev_attr.show = s3c_hwmon_label_show;
ret = device_create_file(dev, &attr->dev_attr);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 79c2931e3008..47d7ce9af8fb 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -50,6 +50,8 @@
735 0008 0735
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ioport.h>
@@ -735,21 +737,19 @@ static int __devinit sis5595_device_add(unsigned short address)
pdev = platform_device_alloc("sis5595", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "sis5595: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR "sis5595: Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "sis5595: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index f46d936c12da..9fb7516e6f45 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -26,6 +26,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ioport.h>
@@ -311,21 +313,19 @@ static int __init smsc47b397_device_add(unsigned short address)
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
@@ -367,8 +367,7 @@ static int __init smsc47b397_find(unsigned short *addr)
*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
| superio_inb(SUPERIO_REG_BASE_LSB);
- printk(KERN_INFO DRVNAME ": found SMSC %s "
- "(base address 0x%04x, revision %u)\n",
+ pr_info("found SMSC %s (base address 0x%04x, revision %u)\n",
name, *addr, rev);
superio_exit();
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 8fa462f2b570..f44a89aac381 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -26,6 +26,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ioport.h>
@@ -435,30 +437,29 @@ static int __init smsc47m1_find(unsigned short *addr,
*/
switch (val) {
case 0x51:
- pr_info(DRVNAME ": Found SMSC LPC47B27x\n");
+ pr_info("Found SMSC LPC47B27x\n");
sio_data->type = smsc47m1;
break;
case 0x59:
- pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
+ pr_info("Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
sio_data->type = smsc47m1;
break;
case 0x5F:
- pr_info(DRVNAME ": Found SMSC LPC47M14x\n");
+ pr_info("Found SMSC LPC47M14x\n");
sio_data->type = smsc47m1;
break;
case 0x60:
- pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
+ pr_info("Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
sio_data->type = smsc47m1;
break;
case 0x6B:
if (superio_inb(SUPERIO_REG_DEVREV) & 0x80) {
- pr_debug(DRVNAME ": "
- "Found SMSC LPC47M233, unsupported\n");
+ pr_debug("Found SMSC LPC47M233, unsupported\n");
superio_exit();
return -ENODEV;
}
- pr_info(DRVNAME ": Found SMSC LPC47M292\n");
+ pr_info("Found SMSC LPC47M292\n");
sio_data->type = smsc47m2;
break;
default:
@@ -470,7 +471,7 @@ static int __init smsc47m1_find(unsigned short *addr,
*addr = (superio_inb(SUPERIO_REG_BASE) << 8)
| superio_inb(SUPERIO_REG_BASE + 1);
if (*addr == 0) {
- pr_info(DRVNAME ": Device address not set, will not use\n");
+ pr_info("Device address not set, will not use\n");
superio_exit();
return -ENODEV;
}
@@ -479,7 +480,7 @@ static int __init smsc47m1_find(unsigned short *addr,
* Compaq Presario S4000NX) */
sio_data->activate = superio_inb(SUPERIO_REG_ACT);
if ((sio_data->activate & 0x01) == 0) {
- pr_info(DRVNAME ": Enabling device\n");
+ pr_info("Enabling device\n");
superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01);
}
@@ -494,7 +495,7 @@ static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
superio_enter();
superio_select();
- pr_info(DRVNAME ": Disabling device\n");
+ pr_info("Disabling device\n");
superio_outb(SUPERIO_REG_ACT, sio_data->activate);
superio_exit();
@@ -823,28 +824,26 @@ static int __init smsc47m1_device_add(unsigned short address,
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add_data(pdev, sio_data,
sizeof(struct smsc47m1_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index ec7fad747adc..0d18de424c66 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -21,6 +21,8 @@
* 02110-1301 USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -202,7 +204,7 @@ static int __cpuinit via_cputemp_device_add(unsigned int cpu)
pdev = platform_device_alloc(DRVNAME, cpu);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
@@ -214,8 +216,7 @@ static int __cpuinit via_cputemp_device_add(unsigned int cpu)
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_free;
}
@@ -237,13 +238,16 @@ exit:
static void __cpuinit via_cputemp_device_remove(unsigned int cpu)
{
- struct pdev_entry *p, *n;
+ struct pdev_entry *p;
+
mutex_lock(&pdev_list_mutex);
- list_for_each_entry_safe(p, n, &pdev_list, list) {
+ list_for_each_entry(p, &pdev_list, list) {
if (p->cpu == cpu) {
platform_device_unregister(p->pdev);
list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
kfree(p);
+ return;
}
}
mutex_unlock(&pdev_list_mutex);
@@ -273,7 +277,6 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = {
static int __init via_cputemp_init(void)
{
int i, err;
- struct pdev_entry *p, *n;
if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) {
printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n");
@@ -295,33 +298,27 @@ static int __init via_cputemp_init(void)
continue;
if (c->x86_model > 0x0f) {
- printk(KERN_WARNING DRVNAME ": Unknown CPU "
- "model 0x%x\n", c->x86_model);
+ pr_warn("Unknown CPU model 0x%x\n", c->x86_model);
continue;
}
- err = via_cputemp_device_add(i);
- if (err)
- goto exit_devices_unreg;
+ via_cputemp_device_add(i);
}
+
+#ifndef CONFIG_HOTPLUG_CPU
if (list_empty(&pdev_list)) {
err = -ENODEV;
goto exit_driver_unreg;
}
+#endif
register_hotcpu_notifier(&via_cputemp_cpu_notifier);
return 0;
-exit_devices_unreg:
- mutex_lock(&pdev_list_mutex);
- list_for_each_entry_safe(p, n, &pdev_list, list) {
- platform_device_unregister(p->pdev);
- list_del(&p->list);
- kfree(p);
- }
- mutex_unlock(&pdev_list_mutex);
+#ifndef CONFIG_HOTPLUG_CPU
exit_driver_unreg:
platform_driver_unregister(&via_cputemp_driver);
+#endif
exit:
return err;
}
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index f397ce7ad598..25e91665a0a2 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -30,6 +30,8 @@
Warning - only supports a single device.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
@@ -687,6 +689,13 @@ static int __devexit via686a_remove(struct platform_device *pdev)
return 0;
}
+static void via686a_update_fan_div(struct via686a_data *data)
+{
+ int reg = via686a_read_value(data, VIA686A_REG_FANDIV);
+ data->fan_div[0] = (reg >> 4) & 0x03;
+ data->fan_div[1] = reg >> 6;
+}
+
static void __devinit via686a_init_device(struct via686a_data *data)
{
u8 reg;
@@ -700,6 +709,9 @@ static void __devinit via686a_init_device(struct via686a_data *data)
via686a_write_value(data, VIA686A_REG_TEMP_MODE,
(reg & ~VIA686A_TEMP_MODE_MASK)
| VIA686A_TEMP_MODE_CONTINUOUS);
+
+ /* Pre-read fan clock divisor values */
+ via686a_update_fan_div(data);
}
static struct via686a_data *via686a_update_device(struct device *dev)
@@ -751,9 +763,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
(via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
0xc0) >> 6;
- i = via686a_read_value(data, VIA686A_REG_FANDIV);
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = i >> 6;
+ via686a_update_fan_div(data);
data->alarms =
via686a_read_value(data,
VIA686A_REG_ALARM1) |
@@ -791,21 +801,19 @@ static int __devinit via686a_device_add(unsigned short address)
pdev = platform_device_alloc("via686a", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "via686a: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR "via686a: Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "via686a: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index ae33bbb577c7..49163d48e966 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1254,8 +1256,7 @@ static int __init vt1211_device_add(unsigned short address)
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed (%d)\n",
- err);
+ pr_err("Device allocation failed (%d)\n", err);
goto EXIT;
}
@@ -1266,15 +1267,13 @@ static int __init vt1211_device_add(unsigned short address)
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto EXIT_DEV_PUT;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto EXIT_DEV_PUT;
}
@@ -1301,23 +1300,20 @@ static int __init vt1211_find(int sio_cip, unsigned short *address)
superio_select(sio_cip, SIO_VT1211_LDN_HWMON);
if ((superio_inb(sio_cip, SIO_VT1211_ACTIVE) & 1) == 0) {
- printk(KERN_WARNING DRVNAME ": HW monitor is disabled, "
- "skipping\n");
+ pr_warn("HW monitor is disabled, skipping\n");
goto EXIT;
}
*address = ((superio_inb(sio_cip, SIO_VT1211_BADDR) << 8) |
(superio_inb(sio_cip, SIO_VT1211_BADDR + 1))) & 0xff00;
if (*address == 0) {
- printk(KERN_WARNING DRVNAME ": Base address is not set, "
- "skipping\n");
+ pr_warn("Base address is not set, skipping\n");
goto EXIT;
}
err = 0;
- printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, "
- "revision %u\n", *address,
- superio_inb(sio_cip, SIO_VT1211_DEVREV));
+ pr_info("Found VT1211 chip at 0x%04x, revision %u\n",
+ *address, superio_inb(sio_cip, SIO_VT1211_DEVREV));
EXIT:
superio_exit(sio_cip);
@@ -1336,15 +1332,15 @@ static int __init vt1211_init(void)
if ((uch_config < -1) || (uch_config > 31)) {
err = -EINVAL;
- printk(KERN_WARNING DRVNAME ": Invalid UCH configuration %d. "
- "Choose a value between 0 and 31.\n", uch_config);
+ pr_warn("Invalid UCH configuration %d. "
+ "Choose a value between 0 and 31.\n", uch_config);
goto EXIT;
}
if ((int_mode < -1) || (int_mode > 0)) {
err = -EINVAL;
- printk(KERN_WARNING DRVNAME ": Invalid interrupt mode %d. "
- "Only mode 0 is supported.\n", int_mode);
+ pr_warn("Invalid interrupt mode %d. "
+ "Only mode 0 is supported.\n", int_mode);
goto EXIT;
}
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index e6078c9f0e27..db3b2e8d2a67 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -24,6 +24,8 @@
/* Supports VIA VT8231 South Bridge embedded sensors
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -902,21 +904,19 @@ static int __devinit vt8231_device_add(unsigned short address)
pdev = platform_device_alloc("vt8231", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "vt8231: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR "vt8231: Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "vt8231: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 072c58008a63..073eabedc432 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -42,6 +42,8 @@
w83667hg-b 9 5 3 3 0xb350 0xc1 0x5ca3
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1668,8 +1670,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
break;
default:
if (val != 0xffff)
- pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
- val);
+ pr_debug("unsupported chip ID: 0x%04x\n", val);
superio_exit(sioaddr);
return -ENODEV;
}
@@ -1680,8 +1681,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
| superio_inb(sioaddr, SIO_REG_ADDR + 1);
*addr = val & IOREGION_ALIGNMENT;
if (*addr == 0) {
- printk(KERN_ERR DRVNAME ": Refusing to enable a Super-I/O "
- "device with a base I/O port 0.\n");
+ pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
superio_exit(sioaddr);
return -ENODEV;
}
@@ -1689,13 +1689,12 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
/* Activate logical device if needed */
val = superio_inb(sioaddr, SIO_REG_ENABLE);
if (!(val & 0x01)) {
- printk(KERN_WARNING DRVNAME ": Forcibly enabling Super-I/O. "
- "Sensor is probably unusable.\n");
+ pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
}
superio_exit(sioaddr);
- pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr);
+ pr_info("Found %s chip at %#x\n", sio_name, *addr);
sio_data->sioreg = sioaddr;
return 0;
@@ -1729,14 +1728,14 @@ static int __init sensors_w83627ehf_init(void)
if (!(pdev = platform_device_alloc(DRVNAME, address))) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit_unregister;
}
err = platform_device_add_data(pdev, &sio_data,
sizeof(struct w83627ehf_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
@@ -1752,16 +1751,14 @@ static int __init sensors_w83627ehf_init(void)
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
/* platform_device_add calls probe() */
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 38e280523071..bde50e34d013 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -39,6 +39,8 @@
supported yet.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1166,14 +1168,13 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr,
superio_inb(sio_data, WINB_BASE_REG + 1);
*addr = val & WINB_ALIGNMENT;
if (*addr == 0) {
- printk(KERN_WARNING DRVNAME ": Base address not set, "
- "skipping\n");
+ pr_warn("Base address not set, skipping\n");
goto exit;
}
val = superio_inb(sio_data, WINB_ACT_REG);
if (!(val & 0x01)) {
- printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");
+ pr_warn("Enabling HWM logical device\n");
superio_outb(sio_data, WINB_ACT_REG, val | 0x01);
}
@@ -1789,28 +1790,26 @@ static int __init w83627hf_device_add(unsigned short address,
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR DRVNAME ": Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add_data(pdev, sio_data,
sizeof(struct w83627hf_sio_data));
if (err) {
- printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ pr_err("Platform data allocation failed\n");
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index c84b9b4e6960..eed43a008be1 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -33,6 +33,8 @@
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -1798,8 +1800,7 @@ w83781d_isa_found(unsigned short address)
* individually for the probing phase. */
for (port = address; port < address + W83781D_EXTENT; port++) {
if (!request_region(port, 1, "w83781d")) {
- pr_debug("w83781d: Failed to request port 0x%x\n",
- port);
+ pr_debug("Failed to request port 0x%x\n", port);
goto release;
}
}
@@ -1811,7 +1812,7 @@ w83781d_isa_found(unsigned short address)
if (inb_p(address + 2) != val
|| inb_p(address + 3) != val
|| inb_p(address + 7) != val) {
- pr_debug("w83781d: Detection failed at step 1\n");
+ pr_debug("Detection failed at step %d\n", 1);
goto release;
}
#undef REALLY_SLOW_IO
@@ -1820,14 +1821,14 @@ w83781d_isa_found(unsigned short address)
MSB (busy flag) should be clear initially, set after the write. */
save = inb_p(address + W83781D_ADDR_REG_OFFSET);
if (save & 0x80) {
- pr_debug("w83781d: Detection failed at step 2\n");
+ pr_debug("Detection failed at step %d\n", 2);
goto release;
}
val = ~save & 0x7f;
outb_p(val, address + W83781D_ADDR_REG_OFFSET);
if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) {
outb_p(save, address + W83781D_ADDR_REG_OFFSET);
- pr_debug("w83781d: Detection failed at step 3\n");
+ pr_debug("Detection failed at step %d\n", 3);
goto release;
}
@@ -1835,7 +1836,7 @@ w83781d_isa_found(unsigned short address)
outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET);
val = inb_p(address + W83781D_DATA_REG_OFFSET);
if (val & 0x80) {
- pr_debug("w83781d: Detection failed at step 4\n");
+ pr_debug("Detection failed at step %d\n", 4);
goto release;
}
outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET);
@@ -1844,19 +1845,19 @@ w83781d_isa_found(unsigned short address)
val = inb_p(address + W83781D_DATA_REG_OFFSET);
if ((!(save & 0x80) && (val != 0xa3))
|| ((save & 0x80) && (val != 0x5c))) {
- pr_debug("w83781d: Detection failed at step 5\n");
+ pr_debug("Detection failed at step %d\n", 5);
goto release;
}
outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET);
val = inb_p(address + W83781D_DATA_REG_OFFSET);
if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */
- pr_debug("w83781d: Detection failed at step 6\n");
+ pr_debug("Detection failed at step %d\n", 6);
goto release;
}
/* The busy flag should be clear again */
if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) {
- pr_debug("w83781d: Detection failed at step 7\n");
+ pr_debug("Detection failed at step %d\n", 7);
goto release;
}
@@ -1871,7 +1872,7 @@ w83781d_isa_found(unsigned short address)
found = 1;
if (found)
- pr_info("w83781d: Found a %s chip at %#x\n",
+ pr_info("Found a %s chip at %#x\n",
val == 0x30 ? "W83782D" : "W83781D", (int)address);
release:
@@ -1894,21 +1895,19 @@ w83781d_isa_device_add(unsigned short address)
pdev = platform_device_alloc("w83781d", address);
if (!pdev) {
err = -ENOMEM;
- printk(KERN_ERR "w83781d: Device allocation failed\n");
+ pr_err("Device allocation failed\n");
goto exit;
}
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
- printk(KERN_ERR "w83781d: Device resource addition failed "
- "(%d)\n", err);
+ pr_err("Device resource addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev);
if (err) {
- printk(KERN_ERR "w83781d: Device addition failed (%d)\n",
- err);
+ pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 679718e6b017..63841f8cec07 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -691,7 +691,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
}
static ssize_t
-show_regs_chassis(struct device *dev, struct device_attribute *attr,
+show_chassis(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct w83792d_data *data = w83792d_update_device(dev);
@@ -699,6 +699,16 @@ show_regs_chassis(struct device *dev, struct device_attribute *attr,
}
static ssize_t
+show_regs_chassis(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ dev_warn(dev,
+ "Attribute %s is deprecated, use intrusion0_alarm instead\n",
+ "chassis");
+ return show_chassis(dev, attr, buf);
+}
+
+static ssize_t
show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83792d_data *data = w83792d_update_device(dev);
@@ -706,7 +716,7 @@ show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-store_chassis_clear(struct device *dev, struct device_attribute *attr,
+store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -714,6 +724,10 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr,
u32 val;
u8 temp1 = 0, temp2 = 0;
+ dev_warn(dev,
+ "Attribute %s is deprecated, use intrusion0_alarm instead\n",
+ "chassis_clear");
+
val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
@@ -726,6 +740,27 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr,
return count;
}
+static ssize_t
+store_chassis_clear(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83792d_data *data = i2c_get_clientdata(client);
+ unsigned long val;
+ u8 reg;
+
+ if (strict_strtoul(buf, 10, &val) || val != 0)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ reg = w83792d_read_value(client, W83792D_REG_CHASSIS_CLR);
+ w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, reg | 0x80);
+ data->valid = 0; /* Force cache refresh */
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
/* For Smart Fan I / Thermal Cruise */
static ssize_t
show_thermal_cruise(struct device *dev, struct device_attribute *attr,
@@ -1012,7 +1047,9 @@ static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22);
static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23);
static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
- show_chassis_clear, store_chassis_clear);
+ show_chassis_clear, store_chassis_clear_legacy);
+static DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
+ show_chassis, store_chassis_clear);
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0);
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1);
static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2);
@@ -1214,6 +1251,7 @@ static struct attribute *w83792d_attributes[] = {
&dev_attr_alarms.attr,
&dev_attr_chassis.attr,
&dev_attr_chassis_clear.attr,
+ &dev_attr_intrusion0_alarm.attr,
&sensor_dev_attr_tolerance1.dev_attr.attr,
&sensor_dev_attr_thermal_cruise1.dev_attr.attr,
&sensor_dev_attr_tolerance2.dev_attr.attr,
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 8e540ada47d2..e3bdedfb5347 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -51,7 +51,6 @@
#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
/* Addresses to scan */
-static DEFINE_MUTEX(watchdog_mutex);
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
I2C_CLIENT_END };
@@ -421,14 +420,17 @@ store_beep_enable(struct device *dev, struct device_attribute *attr,
/* Write any value to clear chassis alarm */
static ssize_t
-store_chassis_clear(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
+store_chassis_clear_legacy(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83793_data *data = i2c_get_clientdata(client);
u8 val;
+ dev_warn(dev, "Attribute chassis is deprecated, "
+ "use intrusion0_alarm instead\n");
+
mutex_lock(&data->update_lock);
val = w83793_read_value(client, W83793_REG_CLR_CHASSIS);
val |= 0x80;
@@ -437,6 +439,28 @@ store_chassis_clear(struct device *dev,
return count;
}
+/* Write 0 to clear chassis alarm */
+static ssize_t
+store_chassis_clear(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ unsigned long val;
+ u8 reg;
+
+ if (strict_strtoul(buf, 10, &val) || val != 0)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ reg = w83793_read_value(client, W83793_REG_CLR_CHASSIS);
+ w83793_write_value(client, W83793_REG_CLR_CHASSIS, reg | 0x80);
+ data->valid = 0; /* Force cache refresh */
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
#define FAN_INPUT 0
#define FAN_MIN 1
static ssize_t
@@ -1102,6 +1126,8 @@ static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm);
static struct sensor_device_attribute_2 sda_single_files[] = {
SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
+ store_chassis_clear_legacy, ALARM_STATUS, 30),
+ SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep,
store_chassis_clear, ALARM_STATUS, 30),
SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
store_beep_enable, NOT_USED, NOT_USED),
@@ -1323,7 +1349,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf,
static long watchdog_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
- static struct watchdog_info ident = {
+ struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_CARDRESET,
@@ -1333,7 +1359,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd,
int val, ret = 0;
struct w83793_data *data = filp->private_data;
- mutex_lock(&watchdog_mutex);
switch (cmd) {
case WDIOC_GETSUPPORT:
if (!nowayout)
@@ -1387,7 +1412,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd,
default:
ret = -ENOTTY;
}
- mutex_unlock(&watchdog_mutex);
return ret;
}
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index cdbc7448491e..845232d7f611 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -458,6 +458,7 @@ static void w83795_update_limits(struct i2c_client *client)
{
struct w83795_data *data = i2c_get_clientdata(client);
int i, limit;
+ u8 lsb;
/* Read the voltage limits */
for (i = 0; i < ARRAY_SIZE(data->in); i++) {
@@ -479,9 +480,8 @@ static void w83795_update_limits(struct i2c_client *client)
}
/* Read the fan limits */
+ lsb = 0; /* Silent false gcc warning */
for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
- u8 lsb;
-
/* Each register contains LSB for 2 fans, but we want to
* read it only once to save time */
if ((i & 1) == 0 && (data->has_fan & (3 << i)))
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index b923074b2cbe..30f06e956bfb 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -75,8 +75,7 @@ config I2C_HELPER_AUTO
In doubt, say Y.
config I2C_SMBUS
- tristate
- prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO
+ tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
help
Say Y here if you want support for SMBus extensions to the I2C
specification. At the moment, the only supported extension is
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 3998dd620a03..f1cfe7e5508b 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -3,7 +3,7 @@
#
menu "I2C Algorithms"
- depends on !I2C_HELPER_AUTO
+ visible if !I2C_HELPER_AUTO
config I2C_ALGOBIT
tristate "I2C bit-banging interfaces"
@@ -15,15 +15,3 @@ config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
endmenu
-
-# In automatic configuration mode, we still have to define the
-# symbols to avoid unmet dependencies.
-
-if I2C_HELPER_AUTO
-config I2C_ALGOBIT
- tristate
-config I2C_ALGOPCF
- tristate
-config I2C_ALGOPCA
- tristate
-endif
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index a39e6cff86e7..38319a69bd0a 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -600,12 +600,14 @@ static const struct i2c_algorithm i2c_bit_algo = {
/*
* registering functions to load algorithms at runtime
*/
-static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
+static int __i2c_bit_add_bus(struct i2c_adapter *adap,
+ int (*add_adapter)(struct i2c_adapter *))
{
struct i2c_algo_bit_data *bit_adap = adap->algo_data;
+ int ret;
if (bit_test) {
- int ret = test_bus(bit_adap, adap->name);
+ ret = test_bus(bit_adap, adap->name);
if (ret < 0)
return -ENODEV;
}
@@ -614,30 +616,27 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
adap->algo = &i2c_bit_algo;
adap->retries = 3;
+ ret = add_adapter(adap);
+ if (ret < 0)
+ return ret;
+
+ /* Complain if SCL can't be read */
+ if (bit_adap->getscl == NULL) {
+ dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n");
+ dev_warn(&adap->dev, "Bus may be unreliable\n");
+ }
return 0;
}
int i2c_bit_add_bus(struct i2c_adapter *adap)
{
- int err;
-
- err = i2c_bit_prepare_bus(adap);
- if (err)
- return err;
-
- return i2c_add_adapter(adap);
+ return __i2c_bit_add_bus(adap, i2c_add_adapter);
}
EXPORT_SYMBOL(i2c_bit_add_bus);
int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
{
- int err;
-
- err = i2c_bit_prepare_bus(adap);
- if (err)
- return err;
-
- return i2c_add_numbered_adapter(adap);
+ return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter);
}
EXPORT_SYMBOL(i2c_bit_add_numbered_bus);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 3a6321cb8030..113505a6434e 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -638,6 +638,14 @@ config I2C_XILINX
This driver can also be built as a module. If so, the module
will be called xilinx_i2c.
+config I2C_EG20T
+ tristate "PCH I2C of Intel EG20T"
+ depends on PCI
+ help
+ This driver is for PCH(Platform controller Hub) I2C of EG20T which
+ is an IOH(Input/Output Hub) for x86 embedded processor.
+ This driver can access PCH I2C bus device.
+
comment "External I2C/SMBus adapter drivers"
config I2C_PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 84cb16ae6f9e..9d2d0ec7fb23 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -61,6 +61,7 @@ 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
+obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
# External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
new file mode 100644
index 000000000000..2e067dd2ee51
--- /dev/null
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -0,0 +1,900 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/ktime.h>
+
+#define PCH_EVENT_SET 0 /* I2C Interrupt Event Set Status */
+#define PCH_EVENT_NONE 1 /* I2C Interrupt Event Clear Status */
+#define PCH_MAX_CLK 100000 /* Maximum Clock speed in MHz */
+#define PCH_BUFFER_MODE_ENABLE 0x0002 /* flag for Buffer mode enable */
+#define PCH_EEPROM_SW_RST_MODE_ENABLE 0x0008 /* EEPROM SW RST enable flag */
+
+#define PCH_I2CSADR 0x00 /* I2C slave address register */
+#define PCH_I2CCTL 0x04 /* I2C control register */
+#define PCH_I2CSR 0x08 /* I2C status register */
+#define PCH_I2CDR 0x0C /* I2C data register */
+#define PCH_I2CMON 0x10 /* I2C bus monitor register */
+#define PCH_I2CBC 0x14 /* I2C bus transfer rate setup counter */
+#define PCH_I2CMOD 0x18 /* I2C mode register */
+#define PCH_I2CBUFSLV 0x1C /* I2C buffer mode slave address register */
+#define PCH_I2CBUFSUB 0x20 /* I2C buffer mode subaddress register */
+#define PCH_I2CBUFFOR 0x24 /* I2C buffer mode format register */
+#define PCH_I2CBUFCTL 0x28 /* I2C buffer mode control register */
+#define PCH_I2CBUFMSK 0x2C /* I2C buffer mode interrupt mask register */
+#define PCH_I2CBUFSTA 0x30 /* I2C buffer mode status register */
+#define PCH_I2CBUFLEV 0x34 /* I2C buffer mode level register */
+#define PCH_I2CESRFOR 0x38 /* EEPROM software reset mode format register */
+#define PCH_I2CESRCTL 0x3C /* EEPROM software reset mode ctrl register */
+#define PCH_I2CESRMSK 0x40 /* EEPROM software reset mode */
+#define PCH_I2CESRSTA 0x44 /* EEPROM software reset mode status register */
+#define PCH_I2CTMR 0x48 /* I2C timer register */
+#define PCH_I2CSRST 0xFC /* I2C reset register */
+#define PCH_I2CNF 0xF8 /* I2C noise filter register */
+
+#define BUS_IDLE_TIMEOUT 20
+#define PCH_I2CCTL_I2CMEN 0x0080
+#define TEN_BIT_ADDR_DEFAULT 0xF000
+#define TEN_BIT_ADDR_MASK 0xF0
+#define PCH_START 0x0020
+#define PCH_ESR_START 0x0001
+#define PCH_BUFF_START 0x1
+#define PCH_REPSTART 0x0004
+#define PCH_ACK 0x0008
+#define PCH_GETACK 0x0001
+#define CLR_REG 0x0
+#define I2C_RD 0x1
+#define I2CMCF_BIT 0x0080
+#define I2CMIF_BIT 0x0002
+#define I2CMAL_BIT 0x0010
+#define I2CBMFI_BIT 0x0001
+#define I2CBMAL_BIT 0x0002
+#define I2CBMNA_BIT 0x0004
+#define I2CBMTO_BIT 0x0008
+#define I2CBMIS_BIT 0x0010
+#define I2CESRFI_BIT 0X0001
+#define I2CESRTO_BIT 0x0002
+#define I2CESRFIIE_BIT 0x1
+#define I2CESRTOIE_BIT 0x2
+#define I2CBMDZ_BIT 0x0040
+#define I2CBMAG_BIT 0x0020
+#define I2CMBB_BIT 0x0020
+#define BUFFER_MODE_MASK (I2CBMFI_BIT | I2CBMAL_BIT | I2CBMNA_BIT | \
+ I2CBMTO_BIT | I2CBMIS_BIT)
+#define I2C_ADDR_MSK 0xFF
+#define I2C_MSB_2B_MSK 0x300
+#define FAST_MODE_CLK 400
+#define FAST_MODE_EN 0x0001
+#define SUB_ADDR_LEN_MAX 4
+#define BUF_LEN_MAX 32
+#define PCH_BUFFER_MODE 0x1
+#define EEPROM_SW_RST_MODE 0x0002
+#define NORMAL_INTR_ENBL 0x0300
+#define EEPROM_RST_INTR_ENBL (I2CESRFIIE_BIT | I2CESRTOIE_BIT)
+#define EEPROM_RST_INTR_DISBL 0x0
+#define BUFFER_MODE_INTR_ENBL 0x001F
+#define BUFFER_MODE_INTR_DISBL 0x0
+#define NORMAL_MODE 0x0
+#define BUFFER_MODE 0x1
+#define EEPROM_SR_MODE 0x2
+#define I2C_TX_MODE 0x0010
+#define PCH_BUF_TX 0xFFF7
+#define PCH_BUF_RD 0x0008
+#define I2C_ERROR_MASK (I2CESRTO_EVENT | I2CBMIS_EVENT | I2CBMTO_EVENT | \
+ I2CBMNA_EVENT | I2CBMAL_EVENT | I2CMAL_EVENT)
+#define I2CMAL_EVENT 0x0001
+#define I2CMCF_EVENT 0x0002
+#define I2CBMFI_EVENT 0x0004
+#define I2CBMAL_EVENT 0x0008
+#define I2CBMNA_EVENT 0x0010
+#define I2CBMTO_EVENT 0x0020
+#define I2CBMIS_EVENT 0x0040
+#define I2CESRFI_EVENT 0x0080
+#define I2CESRTO_EVENT 0x0100
+#define PCI_DEVICE_ID_PCH_I2C 0x8817
+
+#define pch_dbg(adap, fmt, arg...) \
+ dev_dbg(adap->pch_adapter.dev.parent, "%s :" fmt, __func__, ##arg)
+
+#define pch_err(adap, fmt, arg...) \
+ dev_err(adap->pch_adapter.dev.parent, "%s :" fmt, __func__, ##arg)
+
+#define pch_pci_err(pdev, fmt, arg...) \
+ dev_err(&pdev->dev, "%s :" fmt, __func__, ##arg)
+
+#define pch_pci_dbg(pdev, fmt, arg...) \
+ dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
+
+/**
+ * struct i2c_algo_pch_data - for I2C driver functionalities
+ * @pch_adapter: stores the reference to i2c_adapter structure
+ * @p_adapter_info: stores the reference to adapter_info structure
+ * @pch_base_address: specifies the remapped base address
+ * @pch_buff_mode_en: specifies if buffer mode is enabled
+ * @pch_event_flag: specifies occurrence of interrupt events
+ * @pch_i2c_xfer_in_progress: specifies whether the transfer is completed
+ */
+struct i2c_algo_pch_data {
+ struct i2c_adapter pch_adapter;
+ struct adapter_info *p_adapter_info;
+ void __iomem *pch_base_address;
+ int pch_buff_mode_en;
+ u32 pch_event_flag;
+ bool pch_i2c_xfer_in_progress;
+};
+
+/**
+ * struct adapter_info - This structure holds the adapter information for the
+ PCH i2c controller
+ * @pch_data: stores a list of i2c_algo_pch_data
+ * @pch_i2c_suspended: specifies whether the system is suspended or not
+ * perhaps with more lines and words.
+ *
+ * pch_data has as many elements as maximum I2C channels
+ */
+struct adapter_info {
+ struct i2c_algo_pch_data pch_data;
+ bool pch_i2c_suspended;
+};
+
+
+static int pch_i2c_speed = 100; /* I2C bus speed in Kbps */
+static int pch_clk = 50000; /* specifies I2C clock speed in KHz */
+static wait_queue_head_t pch_event;
+static DEFINE_MUTEX(pch_mutex);
+
+static struct pci_device_id __devinitdata pch_pcidev_id[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)},
+ {0,}
+};
+
+static irqreturn_t pch_i2c_handler(int irq, void *pData);
+
+static inline void pch_setbit(void __iomem *addr, u32 offset, u32 bitmask)
+{
+ u32 val;
+ val = ioread32(addr + offset);
+ val |= bitmask;
+ iowrite32(val, addr + offset);
+}
+
+static inline void pch_clrbit(void __iomem *addr, u32 offset, u32 bitmask)
+{
+ u32 val;
+ val = ioread32(addr + offset);
+ val &= (~bitmask);
+ iowrite32(val, addr + offset);
+}
+
+/**
+ * pch_i2c_init() - hardware initialization of I2C module
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_init(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ u32 pch_i2cbc;
+ u32 pch_i2ctmr;
+ u32 reg_value;
+
+ /* reset I2C controller */
+ iowrite32(0x01, p + PCH_I2CSRST);
+ msleep(20);
+ iowrite32(0x0, p + PCH_I2CSRST);
+
+ /* Initialize I2C registers */
+ iowrite32(0x21, p + PCH_I2CNF);
+
+ pch_setbit(adap->pch_base_address, PCH_I2CCTL,
+ PCH_I2CCTL_I2CMEN);
+
+ if (pch_i2c_speed != 400)
+ pch_i2c_speed = 100;
+
+ reg_value = PCH_I2CCTL_I2CMEN;
+ if (pch_i2c_speed == FAST_MODE_CLK) {
+ reg_value |= FAST_MODE_EN;
+ pch_dbg(adap, "Fast mode enabled\n");
+ }
+
+ if (pch_clk > PCH_MAX_CLK)
+ pch_clk = 62500;
+
+ pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / pch_i2c_speed * 8;
+ /* Set transfer speed in I2CBC */
+ iowrite32(pch_i2cbc, p + PCH_I2CBC);
+
+ pch_i2ctmr = (pch_clk) / 8;
+ iowrite32(pch_i2ctmr, p + PCH_I2CTMR);
+
+ reg_value |= NORMAL_INTR_ENBL; /* Enable interrupts in normal mode */
+ iowrite32(reg_value, p + PCH_I2CCTL);
+
+ pch_dbg(adap,
+ "I2CCTL=%x pch_i2cbc=%x pch_i2ctmr=%x Enable interrupts\n",
+ ioread32(p + PCH_I2CCTL), pch_i2cbc, pch_i2ctmr);
+
+ init_waitqueue_head(&pch_event);
+}
+
+static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
+{
+ return cmp1.tv64 < cmp2.tv64;
+}
+
+/**
+ * pch_i2c_wait_for_bus_idle() - check the status of bus.
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ * @timeout: waiting time counter (us).
+ */
+static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
+ s32 timeout)
+{
+ void __iomem *p = adap->pch_base_address;
+
+ /* MAX timeout value is timeout*1000*1000nsec */
+ ktime_t ns_val = ktime_add_ns(ktime_get(), timeout*1000*1000);
+ do {
+ if ((ioread32(p + PCH_I2CSR) & I2CMBB_BIT) == 0)
+ break;
+ msleep(20);
+ } while (ktime_lt(ktime_get(), ns_val));
+
+ pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR));
+
+ if (timeout == 0) {
+ pch_err(adap, "%s: Timeout Error.return%d\n", __func__, -ETIME);
+ return -ETIME;
+ }
+
+ return 0;
+}
+
+/**
+ * pch_i2c_start() - Generate I2C start condition in normal mode.
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ *
+ * Generate I2C start condition in normal mode by setting I2CCTL.I2CMSTA to 1.
+ */
+static void pch_i2c_start(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
+ pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
+}
+
+/**
+ * pch_i2c_wait_for_xfer_complete() - initiates a wait for the tx complete event
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
+{
+ s32 ret;
+ ret = wait_event_timeout(pch_event,
+ (adap->pch_event_flag != 0), msecs_to_jiffies(50));
+ if (ret < 0) {
+ pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
+ return ret;
+ }
+
+ if (ret == 0) {
+ pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
+ return -ETIMEDOUT;
+ }
+
+ if (adap->pch_event_flag & I2C_ERROR_MASK) {
+ pch_err(adap, "error bits set: %x\n", adap->pch_event_flag);
+ return -EIO;
+ }
+
+ adap->pch_event_flag = 0;
+
+ return 0;
+}
+
+/**
+ * pch_i2c_getack() - to confirm ACK/NACK
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static s32 pch_i2c_getack(struct i2c_algo_pch_data *adap)
+{
+ u32 reg_val;
+ void __iomem *p = adap->pch_base_address;
+ reg_val = ioread32(p + PCH_I2CSR) & PCH_GETACK;
+
+ if (reg_val != 0) {
+ pch_err(adap, "return%d\n", -EPROTO);
+ return -EPROTO;
+ }
+
+ return 0;
+}
+
+/**
+ * pch_i2c_stop() - generate stop condition in normal mode.
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_stop(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
+ /* clear the start bit */
+ pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
+}
+
+/**
+ * pch_i2c_repstart() - generate repeated start condition in normal mode
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_repstart(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
+ pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_REPSTART);
+}
+
+/**
+ * pch_i2c_writebytes() - write data to I2C bus in normal mode
+ * @i2c_adap: Pointer to the struct i2c_adapter.
+ * @last: specifies whether last message or not.
+ * In the case of compound mode it will be 1 for last message,
+ * otherwise 0.
+ * @first: specifies whether first message or not.
+ * 1 for first message otherwise 0.
+ */
+static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
+ struct i2c_msg *msgs, u32 last, u32 first)
+{
+ struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
+ u8 *buf;
+ u32 length;
+ u32 addr;
+ u32 addr_2_msb;
+ u32 addr_8_lsb;
+ s32 wrcount;
+ void __iomem *p = adap->pch_base_address;
+
+ length = msgs->len;
+ buf = msgs->buf;
+ addr = msgs->addr;
+
+ /* enable master tx */
+ pch_setbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
+
+ pch_dbg(adap, "I2CCTL = %x msgs->len = %d\n", ioread32(p + PCH_I2CCTL),
+ length);
+
+ if (first) {
+ if (pch_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -ETIME)
+ return -ETIME;
+ }
+
+ if (msgs->flags & I2C_M_TEN) {
+ addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7);
+ iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
+ if (first)
+ pch_i2c_start(adap);
+ if (pch_i2c_wait_for_xfer_complete(adap) == 0 &&
+ pch_i2c_getack(adap) == 0) {
+ addr_8_lsb = (addr & I2C_ADDR_MSK);
+ iowrite32(addr_8_lsb, p + PCH_I2CDR);
+ } else {
+ pch_i2c_stop(adap);
+ return -ETIME;
+ }
+ } else {
+ /* set 7 bit slave address and R/W bit as 0 */
+ iowrite32(addr << 1, p + PCH_I2CDR);
+ if (first)
+ pch_i2c_start(adap);
+ }
+
+ if ((pch_i2c_wait_for_xfer_complete(adap) == 0) &&
+ (pch_i2c_getack(adap) == 0)) {
+ for (wrcount = 0; wrcount < length; ++wrcount) {
+ /* write buffer value to I2C data register */
+ iowrite32(buf[wrcount], p + PCH_I2CDR);
+ pch_dbg(adap, "writing %x to Data register\n",
+ buf[wrcount]);
+
+ if (pch_i2c_wait_for_xfer_complete(adap) != 0)
+ return -ETIME;
+
+ if (pch_i2c_getack(adap))
+ return -EIO;
+ }
+
+ /* check if this is the last message */
+ if (last)
+ pch_i2c_stop(adap);
+ else
+ pch_i2c_repstart(adap);
+ } else {
+ pch_i2c_stop(adap);
+ return -EIO;
+ }
+
+ pch_dbg(adap, "return=%d\n", wrcount);
+
+ return wrcount;
+}
+
+/**
+ * pch_i2c_sendack() - send ACK
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_sendack(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
+ pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_ACK);
+}
+
+/**
+ * pch_i2c_sendnack() - send NACK
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+ pch_dbg(adap, "I2CCTL = %x\n", ioread32(p + PCH_I2CCTL));
+ pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_ACK);
+}
+
+/**
+ * pch_i2c_readbytes() - read data from I2C bus in normal mode.
+ * @i2c_adap: Pointer to the struct i2c_adapter.
+ * @msgs: Pointer to i2c_msg structure.
+ * @last: specifies whether last message or not.
+ * @first: specifies whether first message or not.
+ */
+s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+ u32 last, u32 first)
+{
+ struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
+
+ u8 *buf;
+ u32 count;
+ u32 length;
+ u32 addr;
+ u32 addr_2_msb;
+ void __iomem *p = adap->pch_base_address;
+
+ length = msgs->len;
+ buf = msgs->buf;
+ addr = msgs->addr;
+
+ /* enable master reception */
+ pch_clrbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
+
+ if (first) {
+ if (pch_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -ETIME)
+ return -ETIME;
+ }
+
+ if (msgs->flags & I2C_M_TEN) {
+ addr_2_msb = (((addr & I2C_MSB_2B_MSK) >> 7) | (I2C_RD));
+ iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
+
+ } else {
+ /* 7 address bits + R/W bit */
+ addr = (((addr) << 1) | (I2C_RD));
+ iowrite32(addr, p + PCH_I2CDR);
+ }
+
+ /* check if it is the first message */
+ if (first)
+ pch_i2c_start(adap);
+
+ if ((pch_i2c_wait_for_xfer_complete(adap) == 0) &&
+ (pch_i2c_getack(adap) == 0)) {
+ pch_dbg(adap, "return %d\n", 0);
+
+ if (length == 0) {
+ pch_i2c_stop(adap);
+ ioread32(p + PCH_I2CDR); /* Dummy read needs */
+
+ count = length;
+ } else {
+ int read_index;
+ int loop;
+ pch_i2c_sendack(adap);
+
+ /* Dummy read */
+ for (loop = 1, read_index = 0; loop < length; loop++) {
+ buf[read_index] = ioread32(p + PCH_I2CDR);
+
+ if (loop != 1)
+ read_index++;
+
+ if (pch_i2c_wait_for_xfer_complete(adap) != 0) {
+ pch_i2c_stop(adap);
+ return -ETIME;
+ }
+ } /* end for */
+
+ pch_i2c_sendnack(adap);
+
+ buf[read_index] = ioread32(p + PCH_I2CDR);
+
+ if (length != 1)
+ read_index++;
+
+ if (pch_i2c_wait_for_xfer_complete(adap) == 0) {
+ if (last)
+ pch_i2c_stop(adap);
+ else
+ pch_i2c_repstart(adap);
+
+ buf[read_index++] = ioread32(p + PCH_I2CDR);
+ count = read_index;
+ } else {
+ count = -ETIME;
+ }
+
+ }
+ } else {
+ count = -ETIME;
+ pch_i2c_stop(adap);
+ }
+
+ return count;
+}
+
+/**
+ * pch_i2c_cb_ch0() - Interrupt handler Call back function
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
+{
+ u32 sts;
+ void __iomem *p = adap->pch_base_address;
+
+ sts = ioread32(p + PCH_I2CSR);
+ sts &= (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT);
+ if (sts & I2CMAL_BIT)
+ adap->pch_event_flag |= I2CMAL_EVENT;
+
+ if (sts & I2CMCF_BIT)
+ adap->pch_event_flag |= I2CMCF_EVENT;
+
+ /* clear the applicable bits */
+ pch_clrbit(adap->pch_base_address, PCH_I2CSR, sts);
+
+ pch_dbg(adap, "PCH_I2CSR = %x\n", ioread32(p + PCH_I2CSR));
+
+ wake_up(&pch_event);
+}
+
+/**
+ * pch_i2c_handler() - interrupt handler for the PCH I2C controller
+ * @irq: irq number.
+ * @pData: cookie passed back to the handler function.
+ */
+static irqreturn_t pch_i2c_handler(int irq, void *pData)
+{
+ s32 reg_val;
+
+ struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData;
+ void __iomem *p = adap_data->pch_base_address;
+ u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE);
+
+ if (mode != NORMAL_MODE) {
+ pch_err(adap_data, "I2C mode is not supported\n");
+ return IRQ_NONE;
+ }
+
+ reg_val = ioread32(p + PCH_I2CSR);
+ if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
+ pch_i2c_cb_ch0(adap_data);
+ else
+ return IRQ_NONE;
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * pch_i2c_xfer() - Reading adnd writing data through I2C bus
+ * @i2c_adap: Pointer to the struct i2c_adapter.
+ * @msgs: Pointer to i2c_msg structure.
+ * @num: number of messages.
+ */
+static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg *msgs, s32 num)
+{
+ struct i2c_msg *pmsg;
+ u32 i = 0;
+ u32 status;
+ u32 msglen;
+ u32 subaddrlen;
+ s32 ret;
+
+ struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
+
+ ret = mutex_lock_interruptible(&pch_mutex);
+ if (ret)
+ return -ERESTARTSYS;
+
+ if (adap->p_adapter_info->pch_i2c_suspended) {
+ mutex_unlock(&pch_mutex);
+ return -EBUSY;
+ }
+
+ pch_dbg(adap, "adap->p_adapter_info->pch_i2c_suspended is %d\n",
+ adap->p_adapter_info->pch_i2c_suspended);
+ /* transfer not completed */
+ adap->pch_i2c_xfer_in_progress = true;
+
+ pmsg = &msgs[0];
+ pmsg->flags |= adap->pch_buff_mode_en;
+ status = pmsg->flags;
+ pch_dbg(adap,
+ "After invoking I2C_MODE_SEL :flag= 0x%x\n", status);
+ /* calculate sub address length and message length */
+ /* these are applicable only for buffer mode */
+ subaddrlen = pmsg->buf[0];
+ /* calculate actual message length excluding
+ * the sub address fields */
+ msglen = (pmsg->len) - (subaddrlen + 1);
+ if (status & (I2C_M_RD)) {
+ pch_dbg(adap, "invoking pch_i2c_readbytes\n");
+ ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num),
+ (i == 0));
+ } else {
+ pch_dbg(adap, "invoking pch_i2c_writebytes\n");
+ ret = pch_i2c_writebytes(i2c_adap, pmsg, (i + 1 == num),
+ (i == 0));
+ }
+
+ adap->pch_i2c_xfer_in_progress = false; /* transfer completed */
+
+ mutex_unlock(&pch_mutex);
+
+ return ret;
+}
+
+/**
+ * pch_i2c_func() - return the functionality of the I2C driver
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static u32 pch_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+}
+
+static struct i2c_algorithm pch_algorithm = {
+ .master_xfer = pch_i2c_xfer,
+ .functionality = pch_i2c_func
+};
+
+/**
+ * pch_i2c_disbl_int() - Disable PCH I2C interrupts
+ * @adap: Pointer to struct i2c_algo_pch_data.
+ */
+static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
+{
+ void __iomem *p = adap->pch_base_address;
+
+ pch_clrbit(adap->pch_base_address, PCH_I2CCTL, NORMAL_INTR_ENBL);
+
+ iowrite32(EEPROM_RST_INTR_DISBL, p + PCH_I2CESRMSK);
+
+ iowrite32(BUFFER_MODE_INTR_DISBL, p + PCH_I2CBUFMSK);
+}
+
+static int __devinit pch_i2c_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ void __iomem *base_addr;
+ s32 ret;
+ struct adapter_info *adap_info;
+
+ pch_pci_dbg(pdev, "Entered.\n");
+
+ adap_info = kzalloc((sizeof(struct adapter_info)), GFP_KERNEL);
+ if (adap_info == NULL) {
+ pch_pci_err(pdev, "Memory allocation FAILED\n");
+ return -ENOMEM;
+ }
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ pch_pci_err(pdev, "pci_enable_device FAILED\n");
+ goto err_pci_enable;
+ }
+
+ ret = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (ret) {
+ pch_pci_err(pdev, "pci_request_regions FAILED\n");
+ goto err_pci_req;
+ }
+
+ base_addr = pci_iomap(pdev, 1, 0);
+
+ if (base_addr == NULL) {
+ pch_pci_err(pdev, "pci_iomap FAILED\n");
+ ret = -ENOMEM;
+ goto err_pci_iomap;
+ }
+
+ adap_info->pch_i2c_suspended = false;
+
+ adap_info->pch_data.p_adapter_info = adap_info;
+
+ adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
+ adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
+ strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
+ adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
+ adap_info->pch_data.pch_adapter.algo_data =
+ &adap_info->pch_data;
+
+ /* (i * 0x80) + base_addr; */
+ adap_info->pch_data.pch_base_address = base_addr;
+
+ adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev;
+
+ ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter));
+
+ if (ret) {
+ pch_pci_err(pdev, "i2c_add_adapter FAILED\n");
+ goto err_i2c_add_adapter;
+ }
+
+ pch_i2c_init(&adap_info->pch_data);
+ ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
+ KBUILD_MODNAME, &adap_info->pch_data);
+ if (ret) {
+ pch_pci_err(pdev, "request_irq FAILED\n");
+ goto err_request_irq;
+ }
+
+ pci_set_drvdata(pdev, adap_info);
+ pch_pci_dbg(pdev, "returns %d.\n", ret);
+ return 0;
+
+err_request_irq:
+ i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
+err_i2c_add_adapter:
+ pci_iounmap(pdev, base_addr);
+err_pci_iomap:
+ pci_release_regions(pdev);
+err_pci_req:
+ pci_disable_device(pdev);
+err_pci_enable:
+ kfree(adap_info);
+ return ret;
+}
+
+static void __devexit pch_i2c_remove(struct pci_dev *pdev)
+{
+ struct adapter_info *adap_info = pci_get_drvdata(pdev);
+
+ pch_i2c_disbl_int(&adap_info->pch_data);
+ free_irq(pdev->irq, &adap_info->pch_data);
+ i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
+
+ if (adap_info->pch_data.pch_base_address) {
+ pci_iounmap(pdev, adap_info->pch_data.pch_base_address);
+ adap_info->pch_data.pch_base_address = 0;
+ }
+
+ pci_set_drvdata(pdev, NULL);
+
+ pci_release_regions(pdev);
+
+ pci_disable_device(pdev);
+ kfree(adap_info);
+}
+
+#ifdef CONFIG_PM
+static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ int ret;
+ struct adapter_info *adap_info = pci_get_drvdata(pdev);
+ void __iomem *p = adap_info->pch_data.pch_base_address;
+
+ adap_info->pch_i2c_suspended = true;
+
+ while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) {
+ /* Wait until all channel transfers are completed */
+ msleep(20);
+ }
+ /* Disable the i2c interrupts */
+ pch_i2c_disbl_int(&adap_info->pch_data);
+
+ pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
+ "invoked function pch_i2c_disbl_int successfully\n",
+ ioread32(p + PCH_I2CSR), ioread32(p + PCH_I2CBUFSTA),
+ ioread32(p + PCH_I2CESRSTA));
+
+ ret = pci_save_state(pdev);
+
+ if (ret) {
+ pch_pci_err(pdev, "pci_save_state\n");
+ return ret;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int pch_i2c_resume(struct pci_dev *pdev)
+{
+ struct adapter_info *adap_info = pci_get_drvdata(pdev);
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ if (pci_enable_device(pdev) < 0) {
+ pch_pci_err(pdev, "pch_i2c_resume:pci_enable_device FAILED\n");
+ return -EIO;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+
+ pch_i2c_init(&adap_info->pch_data);
+
+ adap_info->pch_i2c_suspended = false;
+
+ return 0;
+}
+#else
+#define pch_i2c_suspend NULL
+#define pch_i2c_resume NULL
+#endif
+
+static struct pci_driver pch_pcidriver = {
+ .name = KBUILD_MODNAME,
+ .id_table = pch_pcidev_id,
+ .probe = pch_i2c_probe,
+ .remove = __devexit_p(pch_i2c_remove),
+ .suspend = pch_i2c_suspend,
+ .resume = pch_i2c_resume
+};
+
+static int __init pch_pci_init(void)
+{
+ return pci_register_driver(&pch_pcidriver);
+}
+module_init(pch_pci_init);
+
+static void __exit pch_pci_exit(void)
+{
+ pci_unregister_driver(&pch_pcidriver);
+}
+module_exit(pch_pci_exit);
+
+MODULE_DESCRIPTION("PCH I2C PCI Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
+module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
+module_param(pch_clk, int, (S_IRUSR | S_IWUSR));
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 02835ce7ff4b..7979aef7ee7b 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -72,6 +72,7 @@
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
/* I801 SMBus address offsets */
#define SMBHSTSTS(p) (0 + (p)->smba)
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
index 80f70d3a744d..c71492782bbd 100644
--- a/drivers/i2c/busses/i2c-intel-mid.c
+++ b/drivers/i2c/busses/i2c-intel-mid.c
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
/* Initialize struct members */
snprintf(mrst->adap.name, sizeof(mrst->adap.name),
- "MRST/Medfield I2C at %lx", start);
+ "Intel MID I2C at %lx", start);
mrst->adap.owner = THIS_MODULE;
mrst->adap.algo = &intel_mid_i2c_algorithm;
mrst->adap.dev.parent = &dev->dev;
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 112c61f7b8cd..f09c9319a2ba 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -409,7 +409,7 @@ iop3xx_i2c_remove(struct platform_device *pdev)
IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE);
__raw_writel(cr, adapter_data->ioaddr + CR_OFFSET);
- iounmap((void __iomem*)adapter_data->ioaddr);
+ iounmap(adapter_data->ioaddr);
release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
kfree(adapter_data);
kfree(padapter);
@@ -453,7 +453,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
/* set the adapter enumeration # */
adapter_data->id = i2c_id++;
- adapter_data->ioaddr = (u32)ioremap(res->start, IOP3XX_I2C_IO_SIZE);
+ adapter_data->ioaddr = ioremap(res->start, IOP3XX_I2C_IO_SIZE);
if (!adapter_data->ioaddr) {
ret = -ENOMEM;
goto release_region;
@@ -498,7 +498,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
return 0;
unmap:
- iounmap((void __iomem*)adapter_data->ioaddr);
+ iounmap(adapter_data->ioaddr);
release_region:
release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
diff --git a/drivers/i2c/busses/i2c-iop3xx.h b/drivers/i2c/busses/i2c-iop3xx.h
index 8485861f6a36..097e270955d0 100644
--- a/drivers/i2c/busses/i2c-iop3xx.h
+++ b/drivers/i2c/busses/i2c-iop3xx.h
@@ -97,7 +97,7 @@
#define IOP3XX_I2C_IO_SIZE 0x18
struct i2c_algo_iop3xx_data {
- u32 ioaddr;
+ void __iomem *ioaddr;
wait_queue_head_t waitq;
spinlock_t lock;
u32 SR_enabled, SR_received;
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 16242063144f..a9941c65f226 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -59,6 +59,7 @@ enum {
MV64XXX_I2C_STATE_INVALID,
MV64XXX_I2C_STATE_IDLE,
MV64XXX_I2C_STATE_WAITING_FOR_START_COND,
+ MV64XXX_I2C_STATE_WAITING_FOR_RESTART,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
@@ -70,6 +71,7 @@ enum {
MV64XXX_I2C_ACTION_INVALID,
MV64XXX_I2C_ACTION_CONTINUE,
MV64XXX_I2C_ACTION_SEND_START,
+ MV64XXX_I2C_ACTION_SEND_RESTART,
MV64XXX_I2C_ACTION_SEND_ADDR_1,
MV64XXX_I2C_ACTION_SEND_ADDR_2,
MV64XXX_I2C_ACTION_SEND_DATA,
@@ -91,6 +93,7 @@ struct mv64xxx_i2c_data {
u32 addr2;
u32 bytes_left;
u32 byte_posn;
+ u32 send_stop;
u32 block;
int rc;
u32 freq_m;
@@ -159,8 +162,15 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
if ((drv_data->bytes_left == 0)
|| (drv_data->aborting
&& (drv_data->byte_posn != 0))) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
+ if (drv_data->send_stop) {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
+ drv_data->state = MV64XXX_I2C_STATE_IDLE;
+ } else {
+ drv_data->action =
+ MV64XXX_I2C_ACTION_SEND_RESTART;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_RESTART;
+ }
} else {
drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
drv_data->state =
@@ -228,6 +238,15 @@ static void
mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
{
switch(drv_data->action) {
+ case MV64XXX_I2C_ACTION_SEND_RESTART:
+ drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
+ drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
+ writel(drv_data->cntl_bits,
+ drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->block = 0;
+ wake_up_interruptible(&drv_data->waitq);
+ break;
+
case MV64XXX_I2C_ACTION_CONTINUE:
writel(drv_data->cntl_bits,
drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
@@ -386,7 +405,8 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
}
static int
-mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg)
+mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
+ int is_first, int is_last)
{
unsigned long flags;
@@ -406,10 +426,18 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg)
drv_data->bytes_left--;
}
} else {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
- drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+ if (is_first) {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+ } else {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
+ }
}
+ drv_data->send_stop = is_last;
drv_data->block = 1;
mv64xxx_i2c_do_action(drv_data);
spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -437,9 +465,12 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
int i, rc;
- for (i=0; i<num; i++)
- if ((rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i])) < 0)
+ for (i = 0; i < num; i++) {
+ rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i],
+ i == 0, i + 1 == num);
+ if (rc < 0)
return rc;
+ }
return num;
}
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index a605a5029cfe..ff1e127dfea8 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -432,7 +432,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
static void __devexit nforce2_remove(struct pci_dev *dev)
{
- struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);
+ struct nforce2_smbus *smbuses = pci_get_drvdata(dev);
nforce2_set_reference(NULL);
if (smbuses[0].base) {
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index c9fffd0389fe..f7148fdd46e0 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -872,6 +872,8 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &nmk_i2c_algo;
+ snprintf(adap->name, sizeof(adap->name),
+ "Nomadik I2C%d at %lx", pdev->id, (unsigned long)res->start);
/* fetch the controller id */
adap->nr = pdev->id;
@@ -891,8 +893,8 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)
goto err_init_hw;
}
- dev_dbg(&pdev->dev, "initialize I2C%d bus on virtual "
- "base %p\n", pdev->id, dev->virtbase);
+ dev_info(&pdev->dev, "initialize %s on virtual "
+ "base %p\n", adap->name, dev->virtbase);
ret = i2c_add_numbered_adapter(adap);
if (ret) {
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 0070371b29f3..ef3bcb1ce864 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -9,6 +9,41 @@
* kind, whether express or implied.
*/
+/*
+ * Device tree configuration:
+ *
+ * Required properties:
+ * - compatible : "opencores,i2c-ocores"
+ * - reg : bus address start and address range size of device
+ * - interrupts : interrupt number
+ * - regstep : size of device registers in bytes
+ * - clock-frequency : frequency of bus clock in Hz
+ *
+ * Example:
+ *
+ * i2c0: ocores@a0000000 {
+ * compatible = "opencores,i2c-ocores";
+ * reg = <0xa0000000 0x8>;
+ * interrupts = <10>;
+ *
+ * regstep = <1>;
+ * clock-frequency = <20000000>;
+ *
+ * -- Devices connected on this I2C bus get
+ * -- defined here; address- and size-cells
+ * -- apply to these child devices
+ *
+ * #address-cells = <1>;
+ * #size-cells = <0>;
+ *
+ * dummy@60 {
+ * compatible = "dummy";
+ * reg = <60>;
+ * };
+ * };
+ *
+ */
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -210,6 +245,32 @@ static struct i2c_adapter ocores_adapter = {
.algo = &ocores_algorithm,
};
+#ifdef CONFIG_OF
+static int ocores_i2c_of_probe(struct platform_device* pdev,
+ struct ocores_i2c* i2c)
+{
+ __be32* val;
+
+ val = of_get_property(pdev->dev.of_node, "regstep", NULL);
+ if (!val) {
+ dev_err(&pdev->dev, "Missing required parameter 'regstep'");
+ return -ENODEV;
+ }
+ i2c->regstep = be32_to_cpup(val);
+
+ val = of_get_property(pdev->dev.of_node, "clock-frequency", NULL);
+ if (!val) {
+ dev_err(&pdev->dev,
+ "Missing required parameter 'clock-frequency'");
+ return -ENODEV;
+ }
+ i2c->clock_khz = be32_to_cpup(val) / 1000;
+
+ return 0;
+}
+#else
+#define ocores_i2c_of_probe(pdev,i2c) -ENODEV
+#endif
static int __devinit ocores_i2c_probe(struct platform_device *pdev)
{
@@ -227,37 +288,41 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
if (!res2)
return -ENODEV;
- pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data;
- if (!pdata)
- return -ENODEV;
-
- i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
- if (!request_mem_region(res->start, resource_size(res),
- pdev->name)) {
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "Memory region busy\n");
- ret = -EBUSY;
- goto request_mem_failed;
+ return -EBUSY;
}
- i2c->base = ioremap(res->start, resource_size(res));
+ i2c->base = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
if (!i2c->base) {
dev_err(&pdev->dev, "Unable to map registers\n");
- ret = -EIO;
- goto map_failed;
+ return -EIO;
+ }
+
+ pdata = pdev->dev.platform_data;
+ if (pdata) {
+ i2c->regstep = pdata->regstep;
+ i2c->clock_khz = pdata->clock_khz;
+ } else {
+ ret = ocores_i2c_of_probe(pdev, i2c);
+ if (ret)
+ return ret;
}
- i2c->regstep = pdata->regstep;
- i2c->clock_khz = pdata->clock_khz;
ocores_init(i2c);
init_waitqueue_head(&i2c->wait);
- ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c);
+ ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0,
+ pdev->name, i2c);
if (ret) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
- goto request_irq_failed;
+ return ret;
}
/* hook up driver to tree */
@@ -265,36 +330,29 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
i2c->adap = ocores_adapter;
i2c_set_adapdata(&i2c->adap, i2c);
i2c->adap.dev.parent = &pdev->dev;
+#ifdef CONFIG_OF
+ i2c->adap.dev.of_node = pdev->dev.of_node;
+#endif
/* 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;
+ return ret;
}
/* add in known devices to the bus */
- for (i = 0; i < pdata->num_devices; i++)
- i2c_new_device(&i2c->adap, pdata->devices + i);
+ if (pdata) {
+ for (i = 0; i < pdata->num_devices; i++)
+ i2c_new_device(&i2c->adap, pdata->devices + i);
+ }
return 0;
-
-add_adapter_failed:
- free_irq(res2->start, i2c);
-request_irq_failed:
- iounmap(i2c->base);
-map_failed:
- release_mem_region(res->start, resource_size(res));
-request_mem_failed:
- kfree(i2c);
-
- return ret;
}
static int __devexit ocores_i2c_remove(struct platform_device* pdev)
{
struct ocores_i2c *i2c = platform_get_drvdata(pdev);
- struct resource *res;
/* disable i2c logic */
oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL)
@@ -304,18 +362,6 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev)
i2c_del_adapter(&i2c->adap);
platform_set_drvdata(pdev, NULL);
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res)
- free_irq(res->start, 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;
}
@@ -344,6 +390,16 @@ static int ocores_i2c_resume(struct platform_device *pdev)
#define ocores_i2c_resume NULL
#endif
+#ifdef CONFIG_OF
+static struct of_device_id ocores_i2c_match[] = {
+ {
+ .compatible = "opencores,i2c-ocores",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ocores_i2c_match);
+#endif
+
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:ocores-i2c");
@@ -355,6 +411,9 @@ static struct platform_driver ocores_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ocores-i2c",
+#ifdef CONFIG_OF
+ .of_match_table = ocores_i2c_match,
+#endif
},
};
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b33c78586bfc..b605ff3a1fa0 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -39,6 +39,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/i2c-omap.h>
+#include <linux/pm_runtime.h>
/* I2C controller revisions */
#define OMAP_I2C_REV_2 0x20
@@ -175,8 +176,6 @@ struct omap_i2c_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;
struct resource *ioarea;
u32 latency; /* maximum mpu wkup latency */
@@ -265,45 +264,18 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
-static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
+static void omap_i2c_unidle(struct omap_i2c_dev *dev)
{
- int ret;
-
- dev->iclk = clk_get(dev->dev, "ick");
- if (IS_ERR(dev->iclk)) {
- ret = PTR_ERR(dev->iclk);
- dev->iclk = NULL;
- return ret;
- }
+ struct platform_device *pdev;
+ struct omap_i2c_bus_platform_data *pdata;
- dev->fclk = clk_get(dev->dev, "fck");
- if (IS_ERR(dev->fclk)) {
- ret = PTR_ERR(dev->fclk);
- if (dev->iclk != NULL) {
- clk_put(dev->iclk);
- dev->iclk = NULL;
- }
- dev->fclk = NULL;
- return ret;
- }
-
- return 0;
-}
+ WARN_ON(!dev->idle);
-static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
-{
- clk_put(dev->fclk);
- dev->fclk = NULL;
- clk_put(dev->iclk);
- dev->iclk = NULL;
-}
+ pdev = to_platform_device(dev->dev);
+ pdata = pdev->dev.platform_data;
-static void omap_i2c_unidle(struct omap_i2c_dev *dev)
-{
- WARN_ON(!dev->idle);
+ pm_runtime_get_sync(&pdev->dev);
- clk_enable(dev->iclk);
- clk_enable(dev->fclk);
if (cpu_is_omap34xx()) {
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
@@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
static void omap_i2c_idle(struct omap_i2c_dev *dev)
{
+ struct platform_device *pdev;
+ struct omap_i2c_bus_platform_data *pdata;
u16 iv;
WARN_ON(dev->idle);
+ pdev = to_platform_device(dev->dev);
+ pdata = pdev->dev.platform_data;
+
dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
if (dev->rev >= OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
@@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
}
dev->idle = 1;
- clk_disable(dev->fclk);
- clk_disable(dev->iclk);
+
+ pm_runtime_put_sync(&pdev->dev);
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
unsigned long fclk_rate = 12000000;
unsigned long timeout;
unsigned long internal_clk = 0;
+ struct clk *fclk;
if (dev->rev >= OMAP_I2C_REV_2) {
/* Disable I2C controller before soft reset */
@@ -414,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* always returns 12MHz for the functional clock, we can
* do this bit unconditionally.
*/
- fclk_rate = clk_get_rate(dev->fclk);
+ fclk = clk_get(dev->dev, "fck");
+ fclk_rate = clk_get_rate(fclk);
+ clk_put(fclk);
/* TRM for 5912 says the I2C clock must be prescaled to be
* between 7 - 12 MHz. The XOR input clock is typically
@@ -443,7 +423,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
internal_clk = 9600;
else
internal_clk = 4000;
- fclk_rate = clk_get_rate(dev->fclk) / 1000;
+ fclk = clk_get(dev->dev, "fck");
+ fclk_rate = clk_get_rate(fclk) / 1000;
+ clk_put(fclk);
/* Compute prescaler divisor */
psc = fclk_rate / internal_clk;
@@ -616,12 +598,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
* REVISIT: We should abort the transfer on signals, but the bus goes
* into arbitration and we're currently unable to recover from it.
*/
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, dev->latency);
r = wait_for_completion_timeout(&dev->cmd_complete,
OMAP_I2C_TIMEOUT);
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, -1);
dev->buf_len = 0;
if (r < 0)
return r;
@@ -672,12 +650,18 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (r < 0)
goto out;
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, dev->latency);
+
for (i = 0; i < num; i++) {
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
if (r != 0)
break;
}
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, -1);
+
if (r == 0)
r = num;
@@ -1048,14 +1032,12 @@ omap_i2c_probe(struct platform_device *pdev)
else
dev->reg_shift = 2;
- if ((r = omap_i2c_get_clocks(dev)) != 0)
- goto err_iounmap;
-
if (cpu_is_omap44xx())
dev->regs = (u8 *) omap4_reg_map;
else
dev->regs = (u8 *) reg_map;
+ pm_runtime_enable(&pdev->dev);
omap_i2c_unidle(dev);
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
@@ -1127,8 +1109,6 @@ err_free_irq:
err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_idle(dev);
- omap_i2c_put_clocks(dev);
-err_iounmap:
iounmap(dev->base);
err_free_mem:
platform_set_drvdata(pdev, NULL);
@@ -1150,7 +1130,6 @@ omap_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_put_clocks(dev);
iounmap(dev->base);
kfree(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1162,7 +1141,7 @@ static struct platform_driver omap_i2c_driver = {
.probe = omap_i2c_probe,
.remove = omap_i2c_remove,
.driver = {
- .name = "i2c_omap",
+ .name = "omap_i2c",
.owner = THIS_MODULE,
},
};
@@ -1184,4 +1163,4 @@ module_exit(omap_i2c_exit_driver);
MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:i2c_omap");
+MODULE_ALIAS("platform:omap_i2c");
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 4d91d80bfd23..90b7a0163899 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -5,6 +5,18 @@
menu "Multiplexer I2C Chip support"
depends on I2C_MUX
+config I2C_MUX_GPIO
+ tristate "GPIO-based I2C multiplexer"
+ depends on GENERIC_GPIO
+ help
+ If you say yes to this option, support will be included for a
+ GPIO based I2C multiplexer. This driver provides access to
+ I2C busses connected through a MUX, which is controlled
+ through GPIO pins.
+
+ This driver can also be built as a module. If so, the module
+ will be called gpio-i2cmux.
+
config I2C_MUX_PCA9541
tristate "NXP PCA9541 I2C Master Selector"
depends on EXPERIMENTAL
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index d743806d9b42..4640436ea61f 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -1,6 +1,7 @@
#
# Makefile for multiplexer I2C chip drivers.
+obj-$(CONFIG_I2C_MUX_GPIO) += gpio-i2cmux.o
obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o
obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
diff --git a/drivers/i2c/muxes/gpio-i2cmux.c b/drivers/i2c/muxes/gpio-i2cmux.c
new file mode 100644
index 000000000000..7b6ce624cd6e
--- /dev/null
+++ b/drivers/i2c/muxes/gpio-i2cmux.c
@@ -0,0 +1,184 @@
+/*
+ * I2C multiplexer using GPIO API
+ *
+ * Peter Korsgaard <peter.korsgaard@barco.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/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/gpio-i2cmux.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+
+struct gpiomux {
+ struct i2c_adapter *parent;
+ struct i2c_adapter **adap; /* child busses */
+ struct gpio_i2cmux_platform_data data;
+};
+
+static void gpiomux_set(const struct gpiomux *mux, unsigned val)
+{
+ int i;
+
+ for (i = 0; i < mux->data.n_gpios; i++)
+ gpio_set_value(mux->data.gpios[i], val & (1 << i));
+}
+
+static int gpiomux_select(struct i2c_adapter *adap, void *data, u32 chan)
+{
+ struct gpiomux *mux = data;
+
+ gpiomux_set(mux, mux->data.values[chan]);
+
+ return 0;
+}
+
+static int gpiomux_deselect(struct i2c_adapter *adap, void *data, u32 chan)
+{
+ struct gpiomux *mux = data;
+
+ gpiomux_set(mux, mux->data.idle);
+
+ return 0;
+}
+
+static int __devinit gpiomux_probe(struct platform_device *pdev)
+{
+ struct gpiomux *mux;
+ struct gpio_i2cmux_platform_data *pdata;
+ struct i2c_adapter *parent;
+ int (*deselect) (struct i2c_adapter *, void *, u32);
+ unsigned initial_state;
+ int i, ret;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "Missing platform data\n");
+ return -ENODEV;
+ }
+
+ parent = i2c_get_adapter(pdata->parent);
+ if (!parent) {
+ dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
+ pdata->parent);
+ return -ENODEV;
+ }
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ mux->parent = parent;
+ mux->data = *pdata;
+ mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
+ GFP_KERNEL);
+ if (!mux->adap) {
+ ret = -ENOMEM;
+ goto alloc_failed2;
+ }
+
+ if (pdata->idle != GPIO_I2CMUX_NO_IDLE) {
+ initial_state = pdata->idle;
+ deselect = gpiomux_deselect;
+ } else {
+ initial_state = pdata->values[0];
+ deselect = NULL;
+ }
+
+ for (i = 0; i < pdata->n_gpios; i++) {
+ ret = gpio_request(pdata->gpios[i], "gpio-i2cmux");
+ if (ret)
+ goto err_request_gpio;
+ gpio_direction_output(pdata->gpios[i],
+ initial_state & (1 << i));
+ }
+
+ for (i = 0; i < pdata->n_values; i++) {
+ u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
+
+ mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i,
+ gpiomux_select, deselect);
+ if (!mux->adap[i]) {
+ ret = -ENODEV;
+ dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
+ goto add_adapter_failed;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d port mux on %s adapter\n",
+ pdata->n_values, parent->name);
+
+ platform_set_drvdata(pdev, mux);
+
+ return 0;
+
+add_adapter_failed:
+ for (; i > 0; i--)
+ i2c_del_mux_adapter(mux->adap[i - 1]);
+ i = pdata->n_gpios;
+err_request_gpio:
+ for (; i > 0; i--)
+ gpio_free(pdata->gpios[i - 1]);
+ kfree(mux->adap);
+alloc_failed2:
+ kfree(mux);
+alloc_failed:
+ i2c_put_adapter(parent);
+
+ return ret;
+}
+
+static int __devexit gpiomux_remove(struct platform_device *pdev)
+{
+ struct gpiomux *mux = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < mux->data.n_values; i++)
+ i2c_del_mux_adapter(mux->adap[i]);
+
+ for (i = 0; i < mux->data.n_gpios; i++)
+ gpio_free(mux->data.gpios[i]);
+
+ platform_set_drvdata(pdev, NULL);
+ i2c_put_adapter(mux->parent);
+ kfree(mux->adap);
+ kfree(mux);
+
+ return 0;
+}
+
+static struct platform_driver gpiomux_driver = {
+ .probe = gpiomux_probe,
+ .remove = __devexit_p(gpiomux_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "gpio-i2cmux",
+ },
+};
+
+static int __init gpiomux_init(void)
+{
+ return platform_driver_register(&gpiomux_driver);
+}
+
+static void __exit gpiomux_exit(void)
+{
+ platform_driver_unregister(&gpiomux_driver);
+}
+
+module_init(gpiomux_init);
+module_exit(gpiomux_exit);
+
+MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver");
+MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-i2cmux");
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 41665d2f9f93..94a652625ae2 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -122,7 +122,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
.driver_data = (void *) 0x00,
.flags = CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 1,
- .target_residency = 4,
+ .target_residency = 1,
.enter = &intel_idle },
{ /* MWAIT C2 */
.name = "SNB-C3",
@@ -130,7 +130,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
.driver_data = (void *) 0x10,
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 80,
- .target_residency = 160,
+ .target_residency = 211,
.enter = &intel_idle },
{ /* MWAIT C3 */
.name = "SNB-C6",
@@ -138,7 +138,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
.driver_data = (void *) 0x20,
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 104,
- .target_residency = 208,
+ .target_residency = 345,
.enter = &intel_idle },
{ /* MWAIT C4 */
.name = "SNB-C7",
@@ -146,7 +146,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
.driver_data = (void *) 0x30,
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 109,
- .target_residency = 300,
+ .target_residency = 345,
.enter = &intel_idle },
};
@@ -273,8 +273,6 @@ static int intel_idle_probe(void)
pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
- if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
- lapic_timer_reliable_states = 0xFFFFFFFF;
if (boot_cpu_data.x86 != 6) /* family 6 */
return -ENODEV;
@@ -286,8 +284,6 @@ static int intel_idle_probe(void)
case 0x1F: /* Core i7 and i5 Processor - Nehalem */
case 0x2E: /* Nehalem-EX Xeon */
case 0x2F: /* Westmere-EX Xeon */
- lapic_timer_reliable_states = (1 << 1); /* C1 */
-
case 0x25: /* Westmere */
case 0x2C: /* Westmere */
cpuidle_state_table = nehalem_cstates;
@@ -295,7 +291,6 @@ static int intel_idle_probe(void)
case 0x1C: /* 28 - Atom Processor */
case 0x26: /* 38 - Lincroft Atom Processor */
- lapic_timer_reliable_states = (1 << 1); /* C1 */
cpuidle_state_table = atom_cstates;
break;
@@ -303,10 +298,6 @@ static int intel_idle_probe(void)
case 0x2D: /* SNB Xeon */
cpuidle_state_table = snb_cstates;
break;
-#ifdef FUTURE_USE
- case 0x17: /* 23 - Core 2 Duo */
- lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
-#endif
default:
pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -314,6 +305,9 @@ static int intel_idle_probe(void)
return -ENODEV;
}
+ if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
+ lapic_timer_reliable_states = 0xFFFFFFFF;
+
pr_debug(PREFIX "v" INTEL_IDLE_VERSION
" model 0x%X\n", boot_cpu_data.x86_model);
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index a5ea1bce9689..8aba0ba57de5 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -130,8 +130,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, dev) {
if (ipv6_chk_addr(&init_net,
&((struct sockaddr_in6 *) addr)->sin6_addr,
dev, 1)) {
@@ -139,7 +139,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
break;
}
}
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
break;
#endif
}
@@ -200,7 +200,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = rt->rt_src;
- if (rt->idev->dev->flags & IFF_LOOPBACK) {
+ if (rt->dst.dev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
if (!ret)
memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
@@ -208,12 +208,12 @@ static int addr4_resolve(struct sockaddr_in *src_in,
}
/* If the device does ARP internally, return 'done' */
- if (rt->idev->dev->flags & IFF_NOARP) {
- rdma_copy_addr(addr, rt->idev->dev, NULL);
+ if (rt->dst.dev->flags & IFF_NOARP) {
+ rdma_copy_addr(addr, rt->dst.dev, NULL);
goto put;
}
- neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev);
+ neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
neigh_event_send(rt->dst.neighbour, NULL);
ret = -ENODATA;
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index bb7e19280821..9b737ff133e2 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -278,36 +278,6 @@ void ib_ud_header_init(int payload_bytes,
EXPORT_SYMBOL(ib_ud_header_init);
/**
- * ib_lrh_header_pack - Pack LRH header struct into wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_pack() packs the LRH header structure @lrh into
- * wire format in the buffer @buf.
- */
-int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf)
-{
- ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf);
- return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_pack);
-
-/**
- * ib_lrh_header_unpack - Unpack LRH structure from wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_unpack() unpacks the LRH header structure from
- * wire format (in buf) into @lrh.
- */
-int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
-{
- ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
- return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_unpack);
-
-/**
* ib_ud_header_pack - Pack UD header struct into wire format
* @header:UD header struct
* @buf:Buffer to pack into
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index b342248aec05..c42699285f8e 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -893,68 +893,81 @@ out:
return ret ? ret : in_len;
}
+static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+{
+ struct ib_uverbs_wc tmp;
+
+ tmp.wr_id = wc->wr_id;
+ tmp.status = wc->status;
+ tmp.opcode = wc->opcode;
+ tmp.vendor_err = wc->vendor_err;
+ tmp.byte_len = wc->byte_len;
+ tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data;
+ tmp.qp_num = wc->qp->qp_num;
+ tmp.src_qp = wc->src_qp;
+ tmp.wc_flags = wc->wc_flags;
+ tmp.pkey_index = wc->pkey_index;
+ tmp.slid = wc->slid;
+ tmp.sl = wc->sl;
+ tmp.dlid_path_bits = wc->dlid_path_bits;
+ tmp.port_num = wc->port_num;
+ tmp.reserved = 0;
+
+ if (copy_to_user(dest, &tmp, sizeof tmp))
+ return -EFAULT;
+
+ return 0;
+}
+
ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_poll_cq cmd;
- struct ib_uverbs_poll_cq_resp *resp;
+ struct ib_uverbs_poll_cq_resp resp;
+ u8 __user *header_ptr;
+ u8 __user *data_ptr;
struct ib_cq *cq;
- struct ib_wc *wc;
- int ret = 0;
- int i;
- int rsize;
+ struct ib_wc wc;
+ int ret;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
- if (!wc)
- return -ENOMEM;
-
- rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
- resp = kmalloc(rsize, GFP_KERNEL);
- if (!resp) {
- ret = -ENOMEM;
- goto out_wc;
- }
-
cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
- if (!cq) {
- ret = -EINVAL;
- goto out;
- }
+ if (!cq)
+ return -EINVAL;
- resp->count = ib_poll_cq(cq, cmd.ne, wc);
+ /* we copy a struct ib_uverbs_poll_cq_resp to user space */
+ header_ptr = (void __user *)(unsigned long) cmd.response;
+ data_ptr = header_ptr + sizeof resp;
- put_cq_read(cq);
+ memset(&resp, 0, sizeof resp);
+ while (resp.count < cmd.ne) {
+ ret = ib_poll_cq(cq, 1, &wc);
+ if (ret < 0)
+ goto out_put;
+ if (!ret)
+ break;
+
+ ret = copy_wc_to_user(data_ptr, &wc);
+ if (ret)
+ goto out_put;
- for (i = 0; i < resp->count; i++) {
- resp->wc[i].wr_id = wc[i].wr_id;
- resp->wc[i].status = wc[i].status;
- resp->wc[i].opcode = wc[i].opcode;
- resp->wc[i].vendor_err = wc[i].vendor_err;
- resp->wc[i].byte_len = wc[i].byte_len;
- resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data;
- resp->wc[i].qp_num = wc[i].qp->qp_num;
- resp->wc[i].src_qp = wc[i].src_qp;
- resp->wc[i].wc_flags = wc[i].wc_flags;
- resp->wc[i].pkey_index = wc[i].pkey_index;
- resp->wc[i].slid = wc[i].slid;
- resp->wc[i].sl = wc[i].sl;
- resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
- resp->wc[i].port_num = wc[i].port_num;
+ data_ptr += sizeof(struct ib_uverbs_wc);
+ ++resp.count;
}
- if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+ if (copy_to_user(header_ptr, &resp, sizeof resp)) {
ret = -EFAULT;
+ goto out_put;
+ }
-out:
- kfree(resp);
+ ret = in_len;
-out_wc:
- kfree(wc);
- return ret ? ret : in_len;
+out_put:
+ put_cq_read(cq);
+ return ret;
}
ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c
index 5440da0e59b4..1b1146f87124 100644
--- a/drivers/infiniband/core/uverbs_marshall.c
+++ b/drivers/infiniband/core/uverbs_marshall.c
@@ -40,18 +40,21 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
dst->grh.sgid_index = src->grh.sgid_index;
dst->grh.hop_limit = src->grh.hop_limit;
dst->grh.traffic_class = src->grh.traffic_class;
+ memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
dst->dlid = src->dlid;
dst->sl = src->sl;
dst->src_path_bits = src->src_path_bits;
dst->static_rate = src->static_rate;
dst->is_global = src->ah_flags & IB_AH_GRH ? 1 : 0;
dst->port_num = src->port_num;
+ dst->reserved = 0;
}
EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
struct ib_qp_attr *src)
{
+ dst->qp_state = src->qp_state;
dst->cur_qp_state = src->cur_qp_state;
dst->path_mtu = src->path_mtu;
dst->path_mig_state = src->path_mig_state;
@@ -83,6 +86,7 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
dst->rnr_retry = src->rnr_retry;
dst->alt_port_num = src->alt_port_num;
dst->alt_timeout = src->alt_timeout;
+ memset(dst->reserved, 0, sizeof(dst->reserved));
}
EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 8c8afc716b98..31ae1b108aea 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -277,18 +277,14 @@ static int remove_file(struct dentry *parent, char *name)
goto bail;
}
- spin_lock(&dcache_lock);
spin_lock(&tmp->d_lock);
if (!(d_unhashed(tmp) && tmp->d_inode)) {
- dget_locked(tmp);
+ dget_dlock(tmp);
__d_drop(tmp);
spin_unlock(&tmp->d_lock);
- spin_unlock(&dcache_lock);
simple_unlink(parent->d_inode, tmp);
- } else {
+ } else
spin_unlock(&tmp->d_lock);
- spin_unlock(&dcache_lock);
- }
ret = 0;
bail:
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index bf3e20cd0298..4c85224aeaa7 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -219,7 +219,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
struct net_device *ndev;
enum ib_mtu tmp;
- props->active_width = IB_WIDTH_4X;
+ props->active_width = IB_WIDTH_1X;
props->active_speed = 4;
props->port_cap_flags = IB_PORT_CM_SUP;
props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port];
@@ -242,7 +242,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
tmp = iboe_get_mtu(ndev->mtu);
props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256;
- props->state = netif_running(ndev) && netif_oper_up(ndev) ?
+ props->state = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
IB_PORT_ACTIVE : IB_PORT_DOWN;
props->phys_state = state_to_phys_state(props->state);
@@ -848,8 +848,8 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear)
goto out;
}
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, tmp) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, tmp) {
if (ndev && (tmp == ndev || rdma_vlan_dev_real_dev(tmp) == ndev)) {
gid.global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
vid = rdma_vlan_dev_vlan_id(tmp);
@@ -884,7 +884,7 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear)
}
}
}
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
for (i = 0; i < 128; ++i)
if (!hits[i]) {
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 9a7794ac34c1..2001f20a4361 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1816,6 +1816,11 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
MLX4_WQE_CTRL_FENCE : 0) | size;
+ if (be16_to_cpu(vlan) < 0x1000) {
+ ctrl->ins_vlan = 1 << 6;
+ ctrl->vlan_tag = vlan;
+ }
+
/*
* Make sure descriptor is fully written before
* setting ownership bit (because HW can start
@@ -1831,11 +1836,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
(ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh;
- if (be16_to_cpu(vlan) < 0x1000) {
- ctrl->ins_vlan = 1 << 6;
- ctrl->vlan_tag = vlan;
- }
-
stamp = ind + qp->sq_spare_wqes;
ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index f99bddc01716..df7fa251dcdc 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -453,17 +453,14 @@ static int remove_file(struct dentry *parent, char *name)
goto bail;
}
- spin_lock(&dcache_lock);
spin_lock(&tmp->d_lock);
if (!(d_unhashed(tmp) && tmp->d_inode)) {
- dget_locked(tmp);
+ dget_dlock(tmp);
__d_drop(tmp);
spin_unlock(&tmp->d_lock);
- spin_unlock(&dcache_lock);
simple_unlink(parent->d_inode, tmp);
} else {
spin_unlock(&tmp->d_lock);
- spin_unlock(&dcache_lock);
}
ret = 0;
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
index 9d9a9dc51f18..55855eeabae7 100644
--- a/drivers/infiniband/ulp/ipoib/Kconfig
+++ b/drivers/infiniband/ulp/ipoib/Kconfig
@@ -1,7 +1,6 @@
config INFINIBAND_IPOIB
tristate "IP-over-InfiniBand"
depends on NETDEVICES && INET && (IPV6 || IPV6=n)
- select INET_LRO
---help---
Support for the IP-over-InfiniBand protocol (IPoIB). This
transports IP packets over InfiniBand so you can use your IB
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983a5fdc..ab97f92fc257 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -50,7 +50,7 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_sa.h>
-#include <linux/inet_lro.h>
+#include <linux/sched.h>
/* constants */
@@ -100,9 +100,6 @@ enum {
IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */
IPOIB_MCAST_FLAG_ATTACHED = 3,
- IPOIB_MAX_LRO_DESCRIPTORS = 8,
- IPOIB_LRO_MAX_AGGR = 64,
-
MAX_SEND_CQE = 16,
IPOIB_CM_COPYBREAK = 256,
};
@@ -262,11 +259,6 @@ struct ipoib_ethtool_st {
u16 max_coalesced_frames;
};
-struct ipoib_lro {
- struct net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[IPOIB_MAX_LRO_DESCRIPTORS];
-};
-
/*
* Device private locking: network stack tx_lock protects members used
* in TX fast path, lock protects everything else. lock nests inside
@@ -352,8 +344,6 @@ struct ipoib_dev_priv {
int hca_caps;
struct ipoib_ethtool_st ethtool;
struct timer_list poll_timer;
-
- struct ipoib_lro lro;
};
struct ipoib_ah {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index bb1004114dec..c1c49f2d35b5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1480,6 +1480,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+ priv->dev->features |= NETIF_F_GRO;
if (priv->hca_caps & IB_DEVICE_UD_TSO)
dev->features |= NETIF_F_TSO;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index 1a1657c82edd..19f7f5206f78 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -106,63 +106,12 @@ static int ipoib_set_coalesce(struct net_device *dev,
return 0;
}
-static const char ipoib_stats_keys[][ETH_GSTRING_LEN] = {
- "LRO aggregated", "LRO flushed",
- "LRO avg aggr", "LRO no desc"
-};
-
-static void ipoib_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
-{
- switch (stringset) {
- case ETH_SS_STATS:
- memcpy(data, *ipoib_stats_keys, sizeof(ipoib_stats_keys));
- break;
- }
-}
-
-static int ipoib_get_sset_count(struct net_device *dev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return ARRAY_SIZE(ipoib_stats_keys);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static void ipoib_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
- int index = 0;
-
- /* Get LRO statistics */
- data[index++] = priv->lro.lro_mgr.stats.aggregated;
- data[index++] = priv->lro.lro_mgr.stats.flushed;
- if (priv->lro.lro_mgr.stats.flushed)
- data[index++] = priv->lro.lro_mgr.stats.aggregated /
- priv->lro.lro_mgr.stats.flushed;
- else
- data[index++] = 0;
- data[index++] = priv->lro.lro_mgr.stats.no_desc;
-}
-
-static int ipoib_set_flags(struct net_device *dev, u32 flags)
-{
- return ethtool_op_set_flags(dev, flags, ETH_FLAG_LRO);
-}
-
static const struct ethtool_ops ipoib_ethtool_ops = {
.get_drvinfo = ipoib_get_drvinfo,
.get_rx_csum = ipoib_get_rx_csum,
.set_tso = ipoib_set_tso,
.get_coalesce = ipoib_get_coalesce,
.set_coalesce = ipoib_set_coalesce,
- .get_flags = ethtool_op_get_flags,
- .set_flags = ipoib_set_flags,
- .get_strings = ipoib_get_strings,
- .get_sset_count = ipoib_get_sset_count,
- .get_ethtool_stats = ipoib_get_ethtool_stats,
};
void ipoib_set_ethtool_ops(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index dfa71903d6e4..806d0292dc39 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -295,10 +295,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (dev->features & NETIF_F_LRO)
- lro_receive_skb(&priv->lro.lro_mgr, skb, NULL);
- else
- netif_receive_skb(skb);
+ napi_gro_receive(&priv->napi, skb);
repost:
if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
@@ -450,9 +447,6 @@ poll_more:
}
if (done < budget) {
- if (dev->features & NETIF_F_LRO)
- lro_flush_all(&priv->lro.lro_mgr);
-
napi_complete(napi);
if (unlikely(ib_req_notify_cq(priv->recv_cq,
IB_CQ_NEXT_COMP |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 9ff7bc73ed95..7a07a728fe0d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -60,15 +60,6 @@ MODULE_PARM_DESC(send_queue_size, "Number of descriptors in send queue");
module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444);
MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue");
-static int lro;
-module_param(lro, bool, 0444);
-MODULE_PARM_DESC(lro, "Enable LRO (Large Receive Offload)");
-
-static int lro_max_aggr = IPOIB_LRO_MAX_AGGR;
-module_param(lro_max_aggr, int, 0644);
-MODULE_PARM_DESC(lro_max_aggr, "LRO: Max packets to be aggregated "
- "(default = 64)");
-
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
int ipoib_debug_level;
@@ -976,54 +967,6 @@ static const struct header_ops ipoib_header_ops = {
.create = ipoib_hard_header,
};
-static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
- void **tcph, u64 *hdr_flags, void *priv)
-{
- unsigned int ip_len;
- struct iphdr *iph;
-
- if (unlikely(skb->protocol != htons(ETH_P_IP)))
- return -1;
-
- /*
- * In the future we may add an else clause that verifies the
- * checksum and allows devices which do not calculate checksum
- * to use LRO.
- */
- if (unlikely(skb->ip_summed != CHECKSUM_UNNECESSARY))
- return -1;
-
- /* Check for non-TCP packet */
- skb_reset_network_header(skb);
- iph = ip_hdr(skb);
- if (iph->protocol != IPPROTO_TCP)
- return -1;
-
- ip_len = ip_hdrlen(skb);
- skb_set_transport_header(skb, ip_len);
- *tcph = tcp_hdr(skb);
-
- /* check if IP header and TCP header are complete */
- if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
- return -1;
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- *iphdr = iph;
-
- return 0;
-}
-
-static void ipoib_lro_setup(struct ipoib_dev_priv *priv)
-{
- priv->lro.lro_mgr.max_aggr = lro_max_aggr;
- priv->lro.lro_mgr.max_desc = IPOIB_MAX_LRO_DESCRIPTORS;
- priv->lro.lro_mgr.lro_arr = priv->lro.lro_desc;
- priv->lro.lro_mgr.get_skb_header = get_skb_hdr;
- priv->lro.lro_mgr.features = LRO_F_NAPI;
- priv->lro.lro_mgr.dev = priv->dev;
- priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-}
-
static const struct net_device_ops ipoib_netdev_ops = {
.ndo_open = ipoib_open,
.ndo_stop = ipoib_stop,
@@ -1067,8 +1010,6 @@ static void ipoib_setup(struct net_device *dev)
priv->dev = dev;
- ipoib_lro_setup(priv);
-
spin_lock_init(&priv->lock);
mutex_init(&priv->vlan_mutex);
@@ -1218,8 +1159,7 @@ int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
}
- if (lro)
- priv->dev->features |= NETIF_F_LRO;
+ priv->dev->features |= NETIF_F_GRO;
if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
priv->dev->features |= NETIF_F_TSO;
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 7ad212d31f99..09614ce74961 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -5,7 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT) += input-core.o
-input-core-objs := input.o input-compat.o ff-core.o
+input-core-y := input.o input-compat.o input-mt.o ff-core.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c
index 7d61a9660806..e90ee3d30613 100644
--- a/drivers/input/apm-power.c
+++ b/drivers/input/apm-power.c
@@ -9,6 +9,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/input.h>
#include <linux/slab.h>
@@ -23,8 +25,7 @@ static void system_power_event(unsigned int keycode)
switch (keycode) {
case KEY_SUSPEND:
apm_queue_event(APM_USER_SUSPEND);
-
- printk(KERN_INFO "apm-power: Requesting system suspend...\n");
+ pr_info("Requesting system suspend...\n");
break;
default:
break;
@@ -65,18 +66,15 @@ static int apmpower_connect(struct input_handler *handler,
error = input_register_handle(handle);
if (error) {
- printk(KERN_ERR
- "apm-power: Failed to register input power handler, "
- "error %d\n", error);
+ pr_err("Failed to register input power handler, error %d\n",
+ error);
kfree(handle);
return error;
}
error = input_open_device(handle);
if (error) {
- printk(KERN_ERR
- "apm-power: Failed to open input power device, "
- "error %d\n", error);
+ pr_err("Failed to open input power device, error %d\n", error);
input_unregister_handle(handle);
kfree(handle);
return error;
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c
index f7c5c14ec12a..cd4e6679d61a 100644
--- a/drivers/input/evbug.c
+++ b/drivers/input/evbug.c
@@ -26,6 +26,8 @@
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
@@ -38,8 +40,8 @@ MODULE_LICENSE("GPL");
static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
{
- printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
- dev_name(&handle->dev->dev), type, code, value);
+ printk(KERN_DEBUG pr_fmt("Event. Dev: %s, Type: %d, Code: %d, Value: %d\n"),
+ dev_name(&handle->dev->dev), type, code, value);
}
static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
@@ -64,10 +66,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
if (error)
goto err_unregister_handle;
- printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n",
- dev_name(&dev->dev),
- dev->name ?: "unknown",
- dev->phys ?: "unknown");
+ printk(KERN_DEBUG pr_fmt("Connected device: %s (%s at %s)\n"),
+ dev_name(&dev->dev),
+ dev->name ?: "unknown",
+ dev->phys ?: "unknown");
return 0;
@@ -80,8 +82,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
static void evbug_disconnect(struct input_handle *handle)
{
- printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n",
- dev_name(&handle->dev->dev));
+ printk(KERN_DEBUG pr_fmt("Disconnected device: %s\n"),
+ dev_name(&handle->dev->dev));
input_close_device(handle);
input_unregister_handle(handle);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index e3f7fc6f9565..c8471a2552e7 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -8,6 +8,8 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define EVDEV_MINOR_BASE 64
#define EVDEV_MINORS 32
#define EVDEV_MIN_BUFFER_SIZE 64U
@@ -522,88 +524,84 @@ static int handle_eviocgbit(struct input_dev *dev,
if (type == EV_KEY && size == OLD_KEY_MAX) {
len = OLD_KEY_MAX;
if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
- printk(KERN_WARNING
- "evdev.c(EVIOCGBIT): Suspicious buffer size %u, "
- "limiting output to %zu bytes. See "
- "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",
- OLD_KEY_MAX,
- BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
+ pr_warning("(EVIOCGBIT): Suspicious buffer size %u, "
+ "limiting output to %zu bytes. See "
+ "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",
+ OLD_KEY_MAX,
+ BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
}
return bits_to_user(bits, len, size, p, compat_mode);
}
#undef OLD_KEY_MAX
-static int evdev_handle_get_keycode(struct input_dev *dev,
- void __user *p, size_t size)
+static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p)
{
- struct input_keymap_entry ke;
+ struct input_keymap_entry ke = {
+ .len = sizeof(unsigned int),
+ .flags = 0,
+ };
+ int __user *ip = (int __user *)p;
int error;
- memset(&ke, 0, sizeof(ke));
+ /* legacy case */
+ if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+ return -EFAULT;
- if (size == sizeof(unsigned int[2])) {
- /* legacy case */
- int __user *ip = (int __user *)p;
-
- if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
- return -EFAULT;
+ error = input_get_keycode(dev, &ke);
+ if (error)
+ return error;
- ke.len = sizeof(unsigned int);
- ke.flags = 0;
+ if (put_user(ke.keycode, ip + 1))
+ return -EFAULT;
- error = input_get_keycode(dev, &ke);
- if (error)
- return error;
+ return 0;
+}
- if (put_user(ke.keycode, ip + 1))
- return -EFAULT;
+static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p)
+{
+ struct input_keymap_entry ke;
+ int error;
- } else {
- size = min(size, sizeof(ke));
+ if (copy_from_user(&ke, p, sizeof(ke)))
+ return -EFAULT;
- if (copy_from_user(&ke, p, size))
- return -EFAULT;
+ error = input_get_keycode(dev, &ke);
+ if (error)
+ return error;
- error = input_get_keycode(dev, &ke);
- if (error)
- return error;
+ if (copy_to_user(p, &ke, sizeof(ke)))
+ return -EFAULT;
- if (copy_to_user(p, &ke, size))
- return -EFAULT;
- }
return 0;
}
-static int evdev_handle_set_keycode(struct input_dev *dev,
- void __user *p, size_t size)
+static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p)
{
- struct input_keymap_entry ke;
-
- memset(&ke, 0, sizeof(ke));
+ struct input_keymap_entry ke = {
+ .len = sizeof(unsigned int),
+ .flags = 0,
+ };
+ int __user *ip = (int __user *)p;
- if (size == sizeof(unsigned int[2])) {
- /* legacy case */
- int __user *ip = (int __user *)p;
+ if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+ return -EFAULT;
- if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
- return -EFAULT;
-
- if (get_user(ke.keycode, ip + 1))
- return -EFAULT;
+ if (get_user(ke.keycode, ip + 1))
+ return -EFAULT;
- ke.len = sizeof(unsigned int);
- ke.flags = 0;
+ return input_set_keycode(dev, &ke);
+}
- } else {
- size = min(size, sizeof(ke));
+static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
+{
+ struct input_keymap_entry ke;
- if (copy_from_user(&ke, p, size))
- return -EFAULT;
+ if (copy_from_user(&ke, p, sizeof(ke)))
+ return -EFAULT;
- if (ke.len > sizeof(ke.scancode))
- return -EINVAL;
- }
+ if (ke.len > sizeof(ke.scancode))
+ return -EINVAL;
return input_set_keycode(dev, &ke);
}
@@ -669,6 +667,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return evdev_grab(evdev, client);
else
return evdev_ungrab(evdev, client);
+
+ case EVIOCGKEYCODE:
+ return evdev_handle_get_keycode(dev, p);
+
+ case EVIOCSKEYCODE:
+ return evdev_handle_set_keycode(dev, p);
+
+ case EVIOCGKEYCODE_V2:
+ return evdev_handle_get_keycode_v2(dev, p);
+
+ case EVIOCSKEYCODE_V2:
+ return evdev_handle_set_keycode_v2(dev, p);
}
size = _IOC_SIZE(cmd);
@@ -677,6 +687,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
switch (EVIOC_MASK_SIZE(cmd)) {
+ case EVIOCGPROP(0):
+ return bits_to_user(dev->propbit, INPUT_PROP_MAX,
+ size, p, compat_mode);
+
case EVIOCGKEY(0):
return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
@@ -708,12 +722,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
return error;
-
- case EVIOC_MASK_SIZE(EVIOCGKEYCODE):
- return evdev_handle_get_keycode(dev, p, size);
-
- case EVIOC_MASK_SIZE(EVIOCSKEYCODE):
- return evdev_handle_set_keycode(dev, p, size);
}
/* Multi-number variable-length handlers */
@@ -894,7 +902,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
break;
if (minor == EVDEV_MINORS) {
- printk(KERN_ERR "evdev: no more free evdev devices\n");
+ pr_err("no more free evdev devices\n");
return -ENFILE;
}
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 03078c08309a..3367f760d75a 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -23,7 +23,7 @@
/* #define DEBUG */
-#define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg)
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
#include <linux/input.h>
#include <linux/module.h>
@@ -116,7 +116,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
!test_bit(effect->type, dev->ffbit)) {
- debug("invalid or not supported effect type in upload");
+ pr_debug("invalid or not supported effect type in upload\n");
return -EINVAL;
}
@@ -124,7 +124,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
(effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
!test_bit(effect->u.periodic.waveform, dev->ffbit))) {
- debug("invalid or not supported wave form in upload");
+ pr_debug("invalid or not supported wave form in upload\n");
return -EINVAL;
}
@@ -246,7 +246,7 @@ static int flush_effects(struct input_dev *dev, struct file *file)
struct ff_device *ff = dev->ff;
int i;
- debug("flushing now");
+ pr_debug("flushing now\n");
mutex_lock(&ff->mutex);
@@ -315,8 +315,7 @@ int input_ff_create(struct input_dev *dev, int max_effects)
int i;
if (!max_effects) {
- printk(KERN_ERR
- "ff-core: cannot allocate device without any effects\n");
+ pr_err("cannot allocate device without any effects\n");
return -EINVAL;
}
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index 1d881c96ba8f..117a59aaa70e 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -23,7 +23,7 @@
/* #define DEBUG */
-#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/input.h>
@@ -129,7 +129,7 @@ static void ml_schedule_timer(struct ml_device *ml)
int events = 0;
int i;
- debug("calculating next timer");
+ pr_debug("calculating next timer\n");
for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
@@ -149,10 +149,10 @@ static void ml_schedule_timer(struct ml_device *ml)
}
if (!events) {
- debug("no actions");
+ pr_debug("no actions\n");
del_timer(&ml->timer);
} else {
- debug("timer set");
+ pr_debug("timer set\n");
mod_timer(&ml->timer, earliest);
}
}
@@ -173,8 +173,8 @@ static int apply_envelope(struct ml_effect_state *state, int value,
if (envelope->attack_length &&
time_before(now,
state->play_at + msecs_to_jiffies(envelope->attack_length))) {
- debug("value = 0x%x, attack_level = 0x%x", value,
- envelope->attack_level);
+ pr_debug("value = 0x%x, attack_level = 0x%x\n",
+ value, envelope->attack_level);
time_from_level = jiffies_to_msecs(now - state->play_at);
time_of_envelope = envelope->attack_length;
envelope_level = min_t(__s16, envelope->attack_level, 0x7fff);
@@ -191,13 +191,13 @@ static int apply_envelope(struct ml_effect_state *state, int value,
difference = abs(value) - envelope_level;
- debug("difference = %d", difference);
- debug("time_from_level = 0x%x", time_from_level);
- debug("time_of_envelope = 0x%x", time_of_envelope);
+ pr_debug("difference = %d\n", difference);
+ pr_debug("time_from_level = 0x%x\n", time_from_level);
+ pr_debug("time_of_envelope = 0x%x\n", time_of_envelope);
difference = difference * time_from_level / time_of_envelope;
- debug("difference = %d", difference);
+ pr_debug("difference = %d\n", difference);
return value < 0 ?
-(difference + envelope_level) : (difference + envelope_level);
@@ -215,8 +215,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type)
if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit))
return FF_RUMBLE;
- printk(KERN_ERR
- "ff-memless: invalid type in get_compatible_type()\n");
+ pr_err("invalid type in get_compatible_type()\n");
return 0;
}
@@ -312,7 +311,7 @@ static void ml_combine_effects(struct ff_effect *effect,
break;
default:
- printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n");
+ pr_err("invalid type in ml_combine_effects()\n");
break;
}
@@ -406,7 +405,7 @@ static void ml_effect_timer(unsigned long timer_data)
struct ml_device *ml = dev->ff->private;
unsigned long flags;
- debug("timer: updating effects");
+ pr_debug("timer: updating effects\n");
spin_lock_irqsave(&dev->event_lock, flags);
ml_play_effects(ml);
@@ -438,7 +437,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
struct ml_effect_state *state = &ml->states[effect_id];
if (value > 0) {
- debug("initiated play");
+ pr_debug("initiated play\n");
__set_bit(FF_EFFECT_STARTED, &state->flags);
state->count = value;
@@ -449,7 +448,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
state->adj_at = state->play_at;
} else {
- debug("initiated stop");
+ pr_debug("initiated stop\n");
if (test_bit(FF_EFFECT_PLAYING, &state->flags))
__set_bit(FF_EFFECT_ABORTING, &state->flags);
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 46239e47a260..dbf741c95835 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -18,13 +18,11 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/gameport.h>
-#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/kthread.h>
+#include <linux/workqueue.h>
#include <linux/sched.h> /* HZ */
#include <linux/mutex.h>
-#include <linux/freezer.h>
/*#include <asm/io.h>*/
@@ -234,58 +232,22 @@ struct gameport_event {
static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */
static LIST_HEAD(gameport_event_list);
-static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
-static struct task_struct *gameport_task;
-static int gameport_queue_event(void *object, struct module *owner,
- enum gameport_event_type event_type)
+static struct gameport_event *gameport_get_event(void)
{
+ struct gameport_event *event = NULL;
unsigned long flags;
- struct gameport_event *event;
- int retval = 0;
spin_lock_irqsave(&gameport_event_lock, flags);
- /*
- * Scan event list for the other events for the same gameport port,
- * starting with the most recent one. If event is the same we
- * do not need add new one. If event is of different type we
- * need to add this event and should not look further because
- * we need to preseve sequence of distinct events.
- */
- list_for_each_entry_reverse(event, &gameport_event_list, node) {
- if (event->object == object) {
- if (event->type == event_type)
- goto out;
- break;
- }
- }
-
- event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
- if (!event) {
- pr_err("Not enough memory to queue event %d\n", event_type);
- retval = -ENOMEM;
- goto out;
- }
-
- if (!try_module_get(owner)) {
- pr_warning("Can't get module reference, dropping event %d\n",
- event_type);
- kfree(event);
- retval = -EINVAL;
- goto out;
+ if (!list_empty(&gameport_event_list)) {
+ event = list_first_entry(&gameport_event_list,
+ struct gameport_event, node);
+ list_del_init(&event->node);
}
- event->type = event_type;
- event->object = object;
- event->owner = owner;
-
- list_add_tail(&event->node, &gameport_event_list);
- wake_up(&gameport_wait);
-
-out:
spin_unlock_irqrestore(&gameport_event_lock, flags);
- return retval;
+ return event;
}
static void gameport_free_event(struct gameport_event *event)
@@ -319,24 +281,8 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
spin_unlock_irqrestore(&gameport_event_lock, flags);
}
-static struct gameport_event *gameport_get_event(void)
-{
- struct gameport_event *event = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&gameport_event_lock, flags);
-
- if (!list_empty(&gameport_event_list)) {
- event = list_first_entry(&gameport_event_list,
- struct gameport_event, node);
- list_del_init(&event->node);
- }
-
- spin_unlock_irqrestore(&gameport_event_lock, flags);
- return event;
-}
-static void gameport_handle_event(void)
+static void gameport_handle_events(struct work_struct *work)
{
struct gameport_event *event;
@@ -368,6 +314,59 @@ static void gameport_handle_event(void)
mutex_unlock(&gameport_mutex);
}
+static DECLARE_WORK(gameport_event_work, gameport_handle_events);
+
+static int gameport_queue_event(void *object, struct module *owner,
+ enum gameport_event_type event_type)
+{
+ unsigned long flags;
+ struct gameport_event *event;
+ int retval = 0;
+
+ spin_lock_irqsave(&gameport_event_lock, flags);
+
+ /*
+ * Scan event list for the other events for the same gameport port,
+ * starting with the most recent one. If event is the same we
+ * do not need add new one. If event is of different type we
+ * need to add this event and should not look further because
+ * we need to preserve sequence of distinct events.
+ */
+ list_for_each_entry_reverse(event, &gameport_event_list, node) {
+ if (event->object == object) {
+ if (event->type == event_type)
+ goto out;
+ break;
+ }
+ }
+
+ event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
+ if (!event) {
+ pr_err("Not enough memory to queue event %d\n", event_type);
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ if (!try_module_get(owner)) {
+ pr_warning("Can't get module reference, dropping event %d\n",
+ event_type);
+ kfree(event);
+ retval = -EINVAL;
+ goto out;
+ }
+
+ event->type = event_type;
+ event->object = object;
+ event->owner = owner;
+
+ list_add_tail(&event->node, &gameport_event_list);
+ schedule_work(&gameport_event_work);
+
+out:
+ spin_unlock_irqrestore(&gameport_event_lock, flags);
+ return retval;
+}
+
/*
* Remove all events that have been submitted for a given object,
* be it a gameport port or a driver.
@@ -419,19 +418,6 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
return child;
}
-static int gameport_thread(void *nothing)
-{
- set_freezable();
- do {
- gameport_handle_event();
- wait_event_freezable(gameport_wait,
- kthread_should_stop() || !list_empty(&gameport_event_list));
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-
/*
* Gameport port operations
*/
@@ -814,13 +800,6 @@ static int __init gameport_init(void)
return error;
}
- gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
- if (IS_ERR(gameport_task)) {
- bus_unregister(&gameport_bus);
- error = PTR_ERR(gameport_task);
- pr_err("Failed to start kgameportd, error: %d\n", error);
- return error;
- }
return 0;
}
@@ -828,7 +807,12 @@ static int __init gameport_init(void)
static void __exit gameport_exit(void)
{
bus_unregister(&gameport_bus);
- kthread_stop(gameport_task);
+
+ /*
+ * There should not be any outstanding events but work may
+ * still be scheduled so simply cancel it.
+ */
+ cancel_work_sync(&gameport_event_work);
}
subsys_initcall(gameport_init);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
new file mode 100644
index 000000000000..c48c81f0308d
--- /dev/null
+++ b/drivers/input/input-mt.c
@@ -0,0 +1,170 @@
+/*
+ * Input Multitouch Library
+ *
+ * Copyright (c) 2008-2010 Henrik Rydberg
+ *
+ * This program is free software; you can 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/input/mt.h>
+#include <linux/slab.h>
+
+#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
+
+/**
+ * input_mt_init_slots() - initialize MT input slots
+ * @dev: input device supporting MT events and finger tracking
+ * @num_slots: number of slots used by the device
+ *
+ * This function allocates all necessary memory for MT slot handling
+ * in the input device, prepares the ABS_MT_SLOT and
+ * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
+ * May be called repeatedly. Returns -EINVAL if attempting to
+ * reinitialize with a different number of slots.
+ */
+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
+{
+ int i;
+
+ if (!num_slots)
+ return 0;
+ if (dev->mt)
+ return dev->mtsize != num_slots ? -EINVAL : 0;
+
+ dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
+ if (!dev->mt)
+ return -ENOMEM;
+
+ dev->mtsize = num_slots;
+ input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
+ input_set_events_per_packet(dev, 6 * num_slots);
+
+ /* Mark slots as 'unused' */
+ for (i = 0; i < num_slots; i++)
+ input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
+
+ return 0;
+}
+EXPORT_SYMBOL(input_mt_init_slots);
+
+/**
+ * input_mt_destroy_slots() - frees the MT slots of the input device
+ * @dev: input device with allocated MT slots
+ *
+ * This function is only needed in error path as the input core will
+ * automatically free the MT slots when the device is destroyed.
+ */
+void input_mt_destroy_slots(struct input_dev *dev)
+{
+ kfree(dev->mt);
+ dev->mt = NULL;
+ dev->mtsize = 0;
+ dev->slot = 0;
+ dev->trkid = 0;
+}
+EXPORT_SYMBOL(input_mt_destroy_slots);
+
+/**
+ * input_mt_report_slot_state() - report contact state
+ * @dev: input device with allocated MT slots
+ * @tool_type: the tool type to use in this slot
+ * @active: true if contact is active, false otherwise
+ *
+ * Reports a contact via ABS_MT_TRACKING_ID, and optionally
+ * ABS_MT_TOOL_TYPE. If active is true and the slot is currently
+ * inactive, or if the tool type is changed, a new tracking id is
+ * assigned to the slot. The tool type is only reported if the
+ * corresponding absbit field is set.
+ */
+void input_mt_report_slot_state(struct input_dev *dev,
+ unsigned int tool_type, bool active)
+{
+ struct input_mt_slot *mt;
+ int id;
+
+ if (!dev->mt || !active) {
+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+ return;
+ }
+
+ mt = &dev->mt[dev->slot];
+ id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
+ if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
+ id = input_mt_new_trkid(dev);
+
+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
+ input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
+}
+EXPORT_SYMBOL(input_mt_report_slot_state);
+
+/**
+ * input_mt_report_finger_count() - report contact count
+ * @dev: input device with allocated MT slots
+ * @count: the number of contacts
+ *
+ * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
+ * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.
+ *
+ * The input core ensures only the KEY events already setup for
+ * this device will produce output.
+ */
+void input_mt_report_finger_count(struct input_dev *dev, int count)
+{
+ input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
+ input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
+ input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
+ input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
+}
+EXPORT_SYMBOL(input_mt_report_finger_count);
+
+/**
+ * input_mt_report_pointer_emulation() - common pointer emulation
+ * @dev: input device with allocated MT slots
+ * @use_count: report number of active contacts as finger count
+ *
+ * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
+ * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
+ *
+ * The input core ensures only the KEY and ABS axes already setup for
+ * this device will produce output.
+ */
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
+{
+ struct input_mt_slot *oldest = 0;
+ int oldid = dev->trkid;
+ int count = 0;
+ int i;
+
+ for (i = 0; i < dev->mtsize; ++i) {
+ struct input_mt_slot *ps = &dev->mt[i];
+ int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
+
+ if (id < 0)
+ continue;
+ if ((id - oldid) & TRKID_SGN) {
+ oldest = ps;
+ oldid = id;
+ }
+ count++;
+ }
+
+ input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
+ if (use_count)
+ input_mt_report_finger_count(dev, count);
+
+ if (oldest) {
+ int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
+ int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
+ int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
+
+ input_event(dev, EV_ABS, ABS_X, x);
+ input_event(dev, EV_ABS, ABS_Y, y);
+ input_event(dev, EV_ABS, ABS_PRESSURE, p);
+ } else {
+ input_event(dev, EV_ABS, ABS_PRESSURE, 0);
+ }
+}
+EXPORT_SYMBOL(input_mt_report_pointer_emulation);
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index 10c9b0a845f0..0559e309bac9 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -8,6 +8,8 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/mutex.h>
@@ -33,8 +35,7 @@ static int input_polldev_start_workqueue(void)
if (!polldev_users) {
polldev_wq = create_singlethread_workqueue("ipolldevd");
if (!polldev_wq) {
- printk(KERN_ERR "input-polldev: failed to create "
- "ipolldevd workqueue\n");
+ pr_err("failed to create ipolldevd workqueue\n");
retval = -ENOMEM;
goto out;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index db409d6bd5d2..7985114beac7 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -10,9 +10,11 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
+
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
@@ -958,10 +960,8 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
error = handler->connect(handler, dev, id);
if (error && error != -ENODEV)
- printk(KERN_ERR
- "input: failed to attach handler %s to device %s, "
- "error: %d\n",
- handler->name, kobject_name(&dev->dev.kobj), error);
+ pr_err("failed to attach handler %s to device %s, error: %d\n",
+ handler->name, kobject_name(&dev->dev.kobj), error);
return error;
}
@@ -1109,6 +1109,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%s ", handle->name);
seq_putc(seq, '\n');
+ input_seq_print_bitmap(seq, "PROP", dev->propbit, INPUT_PROP_MAX);
+
input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX);
if (test_bit(EV_KEY, dev->evbit))
input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX);
@@ -1332,11 +1334,26 @@ static ssize_t input_dev_show_modalias(struct device *dev,
}
static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
+ int max, int add_cr);
+
+static ssize_t input_dev_show_properties(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input_dev = to_input_dev(dev);
+ int len = input_print_bitmap(buf, PAGE_SIZE, input_dev->propbit,
+ INPUT_PROP_MAX, true);
+ return min_t(int, len, PAGE_SIZE);
+}
+static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
+
static struct attribute *input_dev_attrs[] = {
&dev_attr_name.attr,
&dev_attr_phys.attr,
&dev_attr_uniq.attr,
&dev_attr_modalias.attr,
+ &dev_attr_properties.attr,
NULL
};
@@ -1470,7 +1487,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
{
int len;
- if (add_uevent_var(env, "%s=", name))
+ if (add_uevent_var(env, "%s", name))
return -ENOMEM;
len = input_print_bitmap(&env->buf[env->buflen - 1],
@@ -1536,6 +1553,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
if (dev->uniq)
INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
+ INPUT_ADD_HOTPLUG_BM_VAR("PROP=", dev->propbit, INPUT_PROP_MAX);
+
INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
if (test_bit(EV_KEY, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX);
@@ -1725,52 +1744,6 @@ void input_free_device(struct input_dev *dev)
EXPORT_SYMBOL(input_free_device);
/**
- * input_mt_create_slots() - create MT input slots
- * @dev: input device supporting MT events and finger tracking
- * @num_slots: number of slots used by the device
- *
- * This function allocates all necessary memory for MT slot handling in the
- * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
- * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
- */
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
-{
- int i;
-
- if (!num_slots)
- return 0;
-
- dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
- if (!dev->mt)
- return -ENOMEM;
-
- dev->mtsize = num_slots;
- input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
-
- /* Mark slots as 'unused' */
- for (i = 0; i < num_slots; i++)
- dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1;
-
- return 0;
-}
-EXPORT_SYMBOL(input_mt_create_slots);
-
-/**
- * input_mt_destroy_slots() - frees the MT slots of the input device
- * @dev: input device with allocated MT slots
- *
- * This function is only needed in error path as the input core will
- * automatically free the MT slots when the device is destroyed.
- */
-void input_mt_destroy_slots(struct input_dev *dev)
-{
- kfree(dev->mt);
- dev->mt = NULL;
- dev->mtsize = 0;
-}
-EXPORT_SYMBOL(input_mt_destroy_slots);
-
-/**
* input_set_capability - mark device as capable of a certain event
* @dev: device that is capable of emitting or accepting event
* @type: type of the event (EV_KEY, EV_REL, etc...)
@@ -1819,9 +1792,8 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
break;
default:
- printk(KERN_ERR
- "input_set_capability: unknown type %u (code %u)\n",
- type, code);
+ pr_err("input_set_capability: unknown type %u (code %u)\n",
+ type, code);
dump_stack();
return;
}
@@ -1903,8 +1875,9 @@ int input_register_device(struct input_dev *dev)
return error;
path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
- printk(KERN_INFO "input: %s as %s\n",
- dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
+ pr_info("%s as %s\n",
+ dev->name ? dev->name : "Unspecified device",
+ path ? path : "N/A");
kfree(path);
error = mutex_lock_interruptible(&input_mutex);
@@ -2186,7 +2159,7 @@ static int __init input_init(void)
err = class_register(&input_class);
if (err) {
- printk(KERN_ERR "input: unable to register input_dev class\n");
+ pr_err("unable to register input_dev class\n");
return err;
}
@@ -2196,7 +2169,7 @@ static int __init input_init(void)
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
if (err) {
- printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
+ pr_err("unable to register char major %d", INPUT_MAJOR);
goto fail2;
}
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9d424cebfd2c..3182c9cd1b0e 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -10,6 +10,8 @@
* (at your option) any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <asm/io.h>
#include <asm/system.h>
#include <linux/delay.h>
@@ -806,7 +808,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
break;
if (minor == JOYDEV_MINORS) {
- printk(KERN_ERR "joydev: no more free joydev devices\n");
+ pr_err("no more free joydev devices\n");
return -ENFILE;
}
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile
index 74daff49ab6e..bc5bda22f15e 100644
--- a/drivers/input/joystick/iforce/Makefile
+++ b/drivers/input/joystick/iforce/Makefile
@@ -4,17 +4,8 @@
# By Johann Deneux <johann.deneux@gmail.com>
#
-# Goal definition
-iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o
-
obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
-ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
- iforce-objs += iforce-serio.o
-endif
-
-ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
- iforce-objs += iforce-usb.o
-endif
-
-EXTRA_CFLAGS = -Werror-implicit-function-declaration
+iforce-y := iforce-ff.o iforce-main.o iforce-packets.o
+iforce-$(CONFIG_JOYSTICK_IFORCE_232) += iforce-serio.o
+iforce-$(CONFIG_JOYSTICK_IFORCE_USB) += iforce-usb.o
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index d53b9e900234..27b6a3ce18ca 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
goto err_free_tgfx;
}
+ parport_put_port(pp);
return tgfx;
err_free_dev:
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index f9fb7fa10af3..56abf3d0e911 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -543,21 +543,25 @@ exit:
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
{
struct usb_endpoint_descriptor *ep_irq_out;
- int error = -ENOMEM;
+ int error;
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
return 0;
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->odata_dma);
- if (!xpad->odata)
+ if (!xpad->odata) {
+ error = -ENOMEM;
goto fail1;
+ }
mutex_init(&xpad->odata_mutex);
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
- if (!xpad->irq_out)
+ if (!xpad->irq_out) {
+ error = -ENOMEM;
goto fail2;
+ }
ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
usb_fill_int_urb(xpad->irq_out, xpad->udev,
@@ -728,7 +732,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
if (xpad_led) {
led_classdev_unregister(&xpad_led->led_cdev);
- kfree(xpad_led->name);
+ kfree(xpad_led);
}
}
#else
@@ -756,8 +760,9 @@ static void xpad_close(struct input_dev *dev)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
- if(xpad->xtype != XTYPE_XBOX360W)
+ if (xpad->xtype != XTYPE_XBOX360W)
usb_kill_urb(xpad->irq_in);
+
xpad_stop_output(xpad);
}
@@ -789,8 +794,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_xpad *xpad;
struct input_dev *input_dev;
struct usb_endpoint_descriptor *ep_irq_in;
- int i;
- int error = -ENOMEM;
+ int i, error;
for (i = 0; xpad_device[i].idVendor; i++) {
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
@@ -800,17 +804,23 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
input_dev = input_allocate_device();
- if (!xpad || !input_dev)
+ if (!xpad || !input_dev) {
+ error = -ENOMEM;
goto fail1;
+ }
xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->idata_dma);
- if (!xpad->idata)
+ if (!xpad->idata) {
+ error = -ENOMEM;
goto fail1;
+ }
xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
- if (!xpad->irq_in)
+ if (!xpad->irq_in) {
+ error = -ENOMEM;
goto fail2;
+ }
xpad->udev = udev;
xpad->mapping = xpad_device[i].mapping;
@@ -887,15 +897,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
error = xpad_init_output(intf, xpad);
if (error)
- goto fail2;
+ goto fail3;
error = xpad_init_ff(xpad);
if (error)
- goto fail3;
+ goto fail4;
error = xpad_led_probe(xpad);
if (error)
- goto fail3;
+ goto fail5;
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
usb_fill_int_urb(xpad->irq_in, udev,
@@ -907,34 +917,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
error = input_register_device(xpad->dev);
if (error)
- goto fail4;
+ goto fail6;
usb_set_intfdata(intf, xpad);
- /*
- * Submit the int URB immediatly rather than waiting for open
- * because we get status messages from the device whether
- * or not any controllers are attached. In fact, it's
- * exactly the message that a controller has arrived that
- * we're waiting for.
- */
if (xpad->xtype == XTYPE_XBOX360W) {
- xpad->irq_in->dev = xpad->udev;
- error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
- if (error)
- goto fail4;
-
/*
* Setup the message to set the LEDs on the
* controller when it shows up
*/
xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
- if(!xpad->bulk_out)
- goto fail5;
+ if (!xpad->bulk_out) {
+ error = -ENOMEM;
+ goto fail7;
+ }
xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
- if(!xpad->bdata)
- goto fail6;
+ if (!xpad->bdata) {
+ error = -ENOMEM;
+ goto fail8;
+ }
xpad->bdata[2] = 0x08;
switch (intf->cur_altsetting->desc.bInterfaceNumber) {
@@ -955,14 +957,31 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
usb_fill_bulk_urb(xpad->bulk_out, udev,
usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
+
+ /*
+ * Submit the int URB immediately rather than waiting for open
+ * because we get status messages from the device whether
+ * or not any controllers are attached. In fact, it's
+ * exactly the message that a controller has arrived that
+ * we're waiting for.
+ */
+ xpad->irq_in->dev = xpad->udev;
+ error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
+ if (error)
+ goto fail9;
}
return 0;
- fail6: usb_free_urb(xpad->bulk_out);
- fail5: usb_kill_urb(xpad->irq_in);
- fail4: usb_free_urb(xpad->irq_in);
- fail3: xpad_deinit_output(xpad);
+ fail9: kfree(xpad->bdata);
+ fail8: usb_free_urb(xpad->bulk_out);
+ fail7: input_unregister_device(input_dev);
+ input_dev = NULL;
+ fail6: xpad_led_disconnect(xpad);
+ fail5: if (input_dev)
+ input_ff_destroy(input_dev);
+ fail4: xpad_deinit_output(xpad);
+ fail3: usb_free_urb(xpad->irq_in);
fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
fail1: input_free_device(input_dev);
kfree(xpad);
@@ -974,21 +993,24 @@ static void xpad_disconnect(struct usb_interface *intf)
{
struct usb_xpad *xpad = usb_get_intfdata (intf);
- usb_set_intfdata(intf, NULL);
- if (xpad) {
- xpad_led_disconnect(xpad);
- input_unregister_device(xpad->dev);
- xpad_deinit_output(xpad);
- if (xpad->xtype == XTYPE_XBOX360W) {
- usb_kill_urb(xpad->bulk_out);
- usb_free_urb(xpad->bulk_out);
- usb_kill_urb(xpad->irq_in);
- }
- usb_free_urb(xpad->irq_in);
- usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
- xpad->idata, xpad->idata_dma);
- kfree(xpad);
+ xpad_led_disconnect(xpad);
+ input_unregister_device(xpad->dev);
+ xpad_deinit_output(xpad);
+
+ if (xpad->xtype == XTYPE_XBOX360W) {
+ usb_kill_urb(xpad->bulk_out);
+ usb_free_urb(xpad->bulk_out);
+ usb_kill_urb(xpad->irq_in);
}
+
+ usb_free_urb(xpad->irq_in);
+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
+ xpad->idata, xpad->idata_dma);
+
+ kfree(xpad->bdata);
+ kfree(xpad);
+
+ usb_set_intfdata(intf, NULL);
}
static struct usb_driver xpad_driver = {
@@ -1000,10 +1022,7 @@ static struct usb_driver xpad_driver = {
static int __init usb_xpad_init(void)
{
- int result = usb_register(&xpad_driver);
- if (result == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
- return result;
+ return usb_register(&xpad_driver);
}
static void __exit usb_xpad_exit(void)
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b8c51b9781db..f829998fabe6 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -179,21 +179,39 @@ config KEYBOARD_GPIO
To compile this driver as a module, choose M here: the
module will be called gpio_keys.
+config KEYBOARD_GPIO_POLLED
+ tristate "Polled GPIO buttons"
+ depends on GENERIC_GPIO
+ select INPUT_POLLDEV
+ help
+ This driver implements support for buttons connected
+ to GPIO pins that are not capable of generating interrupts.
+
+ Say Y here if your device has buttons connected
+ directly to such GPIO pins. Your board-specific
+ setup logic must also provide a platform device,
+ with configuration data saying which GPIOs are used.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gpio_keys_polled.
+
config KEYBOARD_TCA6416
- tristate "TCA6416 Keypad Support"
+ tristate "TCA6416/TCA6408A Keypad Support"
depends on I2C
help
This driver implements basic keypad functionality
- for keys connected through TCA6416 IO expander
+ for keys connected through TCA6416/TCA6408A IO expanders.
Say Y here if your device has keys connected to
- TCA6416 IO expander. Your board-specific setup logic
+ TCA6416/TCA6408A IO expander. Your board-specific setup logic
must also provide pin-mask details(of which TCA6416 pins
are used for keypad).
- If enabled the complete TCA6416 device will be managed through
+ If enabled the entire TCA6416 device will be managed through
this driver.
+ To compile this driver as a module, choose M here: the
+ module will be called tca6416_keypad.
config KEYBOARD_MATRIX
tristate "GPIO driven matrix keypad support"
@@ -443,6 +461,25 @@ config KEYBOARD_OMAP4
To compile this driver as a module, choose M here: the
module will be called omap4-keypad.
+config KEYBOARD_SPEAR
+ tristate "ST SPEAR keyboard support"
+ depends on PLAT_SPEAR
+ help
+ Say Y here if you want to use the SPEAR keyboard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called spear-keboard.
+
+config KEYBOARD_TC3589X
+ tristate "TC3589X Keypad support"
+ depends on MFD_TC3589X
+ help
+ Say Y here if you want to use the keypad controller on
+ TC35892/3 I/O expander.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tc3589x-keypad.
+
config KEYBOARD_TNETV107X
tristate "TI TNETV107X keypad support"
depends on ARCH_DAVINCI_TNETV107X
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index a34452e8ebe2..8933e9ca938d 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
+obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
@@ -37,9 +38,11 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
+obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
+obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
new file mode 100644
index 000000000000..4c17aff20657
--- /dev/null
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -0,0 +1,261 @@
+/*
+ * Driver for buttons on GPIO lines not capable of generating interrupts
+ *
+ * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
+ *
+ * This file was based on: /drivers/input/misc/cobalt_btns.c
+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * also was based on: /drivers/input/keyboard/gpio_keys.c
+ * Copyright 2005 Phil Blundell
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#define DRV_NAME "gpio-keys-polled"
+
+struct gpio_keys_button_data {
+ int last_state;
+ int count;
+ int threshold;
+ int can_sleep;
+};
+
+struct gpio_keys_polled_dev {
+ struct input_polled_dev *poll_dev;
+ struct device *dev;
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button_data data[0];
+};
+
+static void gpio_keys_polled_check_state(struct input_dev *input,
+ struct gpio_keys_button *button,
+ struct gpio_keys_button_data *bdata)
+{
+ int state;
+
+ if (bdata->can_sleep)
+ state = !!gpio_get_value_cansleep(button->gpio);
+ else
+ state = !!gpio_get_value(button->gpio);
+
+ if (state != bdata->last_state) {
+ unsigned int type = button->type ?: EV_KEY;
+
+ input_event(input, type, button->code,
+ !!(state ^ button->active_low));
+ input_sync(input);
+ bdata->count = 0;
+ bdata->last_state = state;
+ }
+}
+
+static void gpio_keys_polled_poll(struct input_polled_dev *dev)
+{
+ struct gpio_keys_polled_dev *bdev = dev->private;
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ struct input_dev *input = dev->input;
+ int i;
+
+ for (i = 0; i < bdev->pdata->nbuttons; i++) {
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+
+ if (bdata->count < bdata->threshold)
+ bdata->count++;
+ else
+ gpio_keys_polled_check_state(input, &pdata->buttons[i],
+ bdata);
+ }
+}
+
+static void gpio_keys_polled_open(struct input_polled_dev *dev)
+{
+ struct gpio_keys_polled_dev *bdev = dev->private;
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+ if (pdata->enable)
+ pdata->enable(bdev->dev);
+}
+
+static void gpio_keys_polled_close(struct input_polled_dev *dev)
+{
+ struct gpio_keys_polled_dev *bdev = dev->private;
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+ if (pdata->disable)
+ pdata->disable(bdev->dev);
+}
+
+static int __devinit gpio_keys_polled_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct gpio_keys_polled_dev *bdev;
+ struct input_polled_dev *poll_dev;
+ struct input_dev *input;
+ int error;
+ int i;
+
+ if (!pdata || !pdata->poll_interval)
+ return -EINVAL;
+
+ bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
+ pdata->nbuttons * sizeof(struct gpio_keys_button_data),
+ GFP_KERNEL);
+ if (!bdev) {
+ dev_err(dev, "no memory for private data\n");
+ return -ENOMEM;
+ }
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ dev_err(dev, "no memory for polled device\n");
+ error = -ENOMEM;
+ goto err_free_bdev;
+ }
+
+ poll_dev->private = bdev;
+ poll_dev->poll = gpio_keys_polled_poll;
+ poll_dev->poll_interval = pdata->poll_interval;
+ poll_dev->open = gpio_keys_polled_open;
+ poll_dev->close = gpio_keys_polled_close;
+
+ input = poll_dev->input;
+
+ input->evbit[0] = BIT(EV_KEY);
+ input->name = pdev->name;
+ input->phys = DRV_NAME"/input0";
+ input->dev.parent = &pdev->dev;
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+ unsigned int gpio = button->gpio;
+ unsigned int type = button->type ?: EV_KEY;
+
+ if (button->wakeup) {
+ dev_err(dev, DRV_NAME " does not support wakeup\n");
+ error = -EINVAL;
+ goto err_free_gpio;
+ }
+
+ error = gpio_request(gpio,
+ button->desc ? button->desc : DRV_NAME);
+ if (error) {
+ dev_err(dev, "unable to claim gpio %u, err=%d\n",
+ gpio, error);
+ goto err_free_gpio;
+ }
+
+ error = gpio_direction_input(gpio);
+ if (error) {
+ dev_err(dev,
+ "unable to set direction on gpio %u, err=%d\n",
+ gpio, error);
+ goto err_free_gpio;
+ }
+
+ bdata->can_sleep = gpio_cansleep(gpio);
+ bdata->last_state = -1;
+ bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+ pdata->poll_interval);
+
+ input_set_capability(input, type, button->code);
+ }
+
+ bdev->poll_dev = poll_dev;
+ bdev->dev = dev;
+ bdev->pdata = pdata;
+ platform_set_drvdata(pdev, bdev);
+
+ error = input_register_polled_device(poll_dev);
+ if (error) {
+ dev_err(dev, "unable to register polled device, err=%d\n",
+ error);
+ goto err_free_gpio;
+ }
+
+ /* report initial state of the buttons */
+ for (i = 0; i < pdata->nbuttons; i++)
+ gpio_keys_polled_check_state(input, &pdata->buttons[i],
+ &bdev->data[i]);
+
+ return 0;
+
+err_free_gpio:
+ while (--i >= 0)
+ gpio_free(pdata->buttons[i].gpio);
+
+ input_free_polled_device(poll_dev);
+
+err_free_bdev:
+ kfree(bdev);
+
+ platform_set_drvdata(pdev, NULL);
+ return error;
+}
+
+static int __devexit gpio_keys_polled_remove(struct platform_device *pdev)
+{
+ struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ int i;
+
+ input_unregister_polled_device(bdev->poll_dev);
+
+ for (i = 0; i < pdata->nbuttons; i++)
+ gpio_free(pdata->buttons[i].gpio);
+
+ input_free_polled_device(bdev->poll_dev);
+
+ kfree(bdev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver gpio_keys_polled_driver = {
+ .probe = gpio_keys_polled_probe,
+ .remove = __devexit_p(gpio_keys_polled_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init gpio_keys_polled_init(void)
+{
+ return platform_driver_register(&gpio_keys_polled_driver);
+}
+
+static void __exit gpio_keys_polled_exit(void)
+{
+ platform_driver_unregister(&gpio_keys_polled_driver);
+}
+
+module_init(gpio_keys_polled_init);
+module_exit(gpio_keys_polled_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Polled GPIO Buttons driver");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index a72e61ddca91..0e2a19cb43d8 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -65,7 +65,6 @@ struct omap_kp {
static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
-static int *keymap;
static unsigned int *row_gpios;
static unsigned int *col_gpios;
@@ -162,20 +161,11 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
}
}
-static inline int omap_kp_find_key(int col, int row)
-{
- int i, key;
-
- key = KEY(col, row, 0);
- for (i = 0; keymap[i] != 0; i++)
- if ((keymap[i] & 0xff000000) == key)
- return keymap[i] & 0x00ffffff;
- return -1;
-}
-
static void omap_kp_tasklet(unsigned long data)
{
struct omap_kp *omap_kp_data = (struct omap_kp *) data;
+ unsigned short *keycodes = omap_kp_data->input->keycode;
+ unsigned int row_shift = get_count_order(omap_kp_data->cols);
unsigned char new_state[8], changed, key_down = 0;
int col, row;
int spurious = 0;
@@ -199,7 +189,7 @@ static void omap_kp_tasklet(unsigned long data)
row, (new_state[col] & (1 << row)) ?
"pressed" : "released");
#else
- key = omap_kp_find_key(col, row);
+ key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)];
if (key < 0) {
printk(KERN_WARNING
"omap-keypad: Spurious key event %d-%d\n",
@@ -298,13 +288,18 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
struct input_dev *input_dev;
struct omap_kp_platform_data *pdata = pdev->dev.platform_data;
int i, col_idx, row_idx, irq_idx, ret;
+ unsigned int row_shift, keycodemax;
- if (!pdata->rows || !pdata->cols || !pdata->keymap) {
- printk(KERN_ERR "No rows, cols or keymap from pdata\n");
+ if (!pdata->rows || !pdata->cols || !pdata->keymap_data) {
+ printk(KERN_ERR "No rows, cols or keymap_data from pdata\n");
return -EINVAL;
}
- omap_kp = kzalloc(sizeof(struct omap_kp), GFP_KERNEL);
+ row_shift = get_count_order(pdata->cols);
+ keycodemax = pdata->rows << row_shift;
+
+ omap_kp = kzalloc(sizeof(struct omap_kp) +
+ keycodemax * sizeof(unsigned short), GFP_KERNEL);
input_dev = input_allocate_device();
if (!omap_kp || !input_dev) {
kfree(omap_kp);
@@ -320,7 +315,9 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
if (!cpu_is_omap24xx())
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
- keymap = pdata->keymap;
+ input_dev->keycode = &omap_kp[1];
+ input_dev->keycodesize = sizeof(unsigned short);
+ input_dev->keycodemax = keycodemax;
if (pdata->rep)
__set_bit(EV_REP, input_dev->evbit);
@@ -374,8 +371,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
/* setup input device */
__set_bit(EV_KEY, input_dev->evbit);
- for (i = 0; keymap[i] != 0; i++)
- __set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
+ matrix_keypad_build_keymap(pdata->keymap_data, row_shift,
+ input_dev->keycode, input_dev->keybit);
input_dev->name = "omap-keypad";
input_dev->phys = "omap-keypad/input0";
input_dev->dev.parent = &pdev->dev;
@@ -416,7 +413,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
return 0;
err5:
for (i = irq_idx - 1; i >=0; i--)
- free_irq(row_gpios[i], 0);
+ free_irq(row_gpios[i], NULL);
err4:
input_unregister_device(omap_kp->input);
input_dev = NULL;
@@ -447,11 +444,11 @@ static int __devexit omap_kp_remove(struct platform_device *pdev)
gpio_free(col_gpios[i]);
for (i = 0; i < omap_kp->rows; i++) {
gpio_free(row_gpios[i]);
- free_irq(gpio_to_irq(row_gpios[i]), 0);
+ free_irq(gpio_to_irq(row_gpios[i]), NULL);
}
} else {
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
- free_irq(omap_kp->irq, 0);
+ free_irq(omap_kp->irq, NULL);
}
del_timer_sync(&omap_kp->timer);
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
new file mode 100644
index 000000000000..bee03d64c453
--- /dev/null
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -0,0 +1,344 @@
+/*
+ * SPEAr Keyboard Driver
+ * Based on omap-keypad driver
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <plat/keyboard.h>
+
+/* Keyboard Registers */
+#define MODE_REG 0x00 /* 16 bit reg */
+#define STATUS_REG 0x0C /* 2 bit reg */
+#define DATA_REG 0x10 /* 8 bit reg */
+#define INTR_MASK 0x54
+
+/* Register Values */
+/*
+ * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
+ * control register as 1010010(82MHZ)
+ */
+#define PCLK_FREQ_MSK 0xA400 /* 82 MHz */
+#define START_SCAN 0x0100
+#define SCAN_RATE_10 0x0000
+#define SCAN_RATE_20 0x0004
+#define SCAN_RATE_40 0x0008
+#define SCAN_RATE_80 0x000C
+#define MODE_KEYBOARD 0x0002
+#define DATA_AVAIL 0x2
+
+#define KEY_MASK 0xFF000000
+#define KEY_VALUE 0x00FFFFFF
+#define ROW_MASK 0xF0
+#define COLUMN_MASK 0x0F
+#define ROW_SHIFT 4
+
+struct spear_kbd {
+ struct input_dev *input;
+ struct resource *res;
+ void __iomem *io_base;
+ struct clk *clk;
+ unsigned int irq;
+ unsigned short last_key;
+ unsigned short keycodes[256];
+};
+
+static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
+{
+ struct spear_kbd *kbd = dev_id;
+ struct input_dev *input = kbd->input;
+ unsigned int key;
+ u8 sts, val;
+
+ sts = readb(kbd->io_base + STATUS_REG);
+ if (sts & DATA_AVAIL)
+ return IRQ_NONE;
+
+ if (kbd->last_key != KEY_RESERVED) {
+ input_report_key(input, kbd->last_key, 0);
+ kbd->last_key = KEY_RESERVED;
+ }
+
+ /* following reads active (row, col) pair */
+ val = readb(kbd->io_base + DATA_REG);
+ key = kbd->keycodes[val];
+
+ input_event(input, EV_MSC, MSC_SCAN, val);
+ input_report_key(input, key, 1);
+ input_sync(input);
+
+ kbd->last_key = key;
+
+ /* clear interrupt */
+ writeb(0, kbd->io_base + STATUS_REG);
+
+ return IRQ_HANDLED;
+}
+
+static int spear_kbd_open(struct input_dev *dev)
+{
+ struct spear_kbd *kbd = input_get_drvdata(dev);
+ int error;
+ u16 val;
+
+ kbd->last_key = KEY_RESERVED;
+
+ error = clk_enable(kbd->clk);
+ if (error)
+ return error;
+
+ /* program keyboard */
+ val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
+ writew(val, kbd->io_base + MODE_REG);
+ writeb(1, kbd->io_base + STATUS_REG);
+
+ /* start key scan */
+ val = readw(kbd->io_base + MODE_REG);
+ val |= START_SCAN;
+ writew(val, kbd->io_base + MODE_REG);
+
+ return 0;
+}
+
+static void spear_kbd_close(struct input_dev *dev)
+{
+ struct spear_kbd *kbd = input_get_drvdata(dev);
+ u16 val;
+
+ /* stop key scan */
+ val = readw(kbd->io_base + MODE_REG);
+ val &= ~START_SCAN;
+ writew(val, kbd->io_base + MODE_REG);
+
+ clk_disable(kbd->clk);
+
+ kbd->last_key = KEY_RESERVED;
+}
+
+static int __devinit spear_kbd_probe(struct platform_device *pdev)
+{
+ const struct kbd_platform_data *pdata = pdev->dev.platform_data;
+ const struct matrix_keymap_data *keymap;
+ struct spear_kbd *kbd;
+ struct input_dev *input_dev;
+ struct resource *res;
+ int irq;
+ int error;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "Invalid platform data\n");
+ return -EINVAL;
+ }
+
+ keymap = pdata->keymap;
+ if (!keymap) {
+ dev_err(&pdev->dev, "no keymap defined\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no keyboard resource defined\n");
+ return -EBUSY;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "not able to get irq for the device\n");
+ return irq;
+ }
+
+ kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!kbd || !input_dev) {
+ dev_err(&pdev->dev, "out of memory\n");
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ kbd->input = input_dev;
+ kbd->irq = irq;
+ kbd->res = request_mem_region(res->start, resource_size(res),
+ pdev->name);
+ if (!kbd->res) {
+ dev_err(&pdev->dev, "keyboard region already claimed\n");
+ error = -EBUSY;
+ goto err_free_mem;
+ }
+
+ kbd->io_base = ioremap(res->start, resource_size(res));
+ if (!kbd->io_base) {
+ dev_err(&pdev->dev, "ioremap failed for kbd_region\n");
+ error = -ENOMEM;
+ goto err_release_mem_region;
+ }
+
+ kbd->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(kbd->clk)) {
+ error = PTR_ERR(kbd->clk);
+ goto err_iounmap;
+ }
+
+ input_dev->name = "Spear Keyboard";
+ input_dev->phys = "keyboard/input0";
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->open = spear_kbd_open;
+ input_dev->close = spear_kbd_close;
+
+ __set_bit(EV_KEY, input_dev->evbit);
+ if (pdata->rep)
+ __set_bit(EV_REP, input_dev->evbit);
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ input_dev->keycode = kbd->keycodes;
+ input_dev->keycodesize = sizeof(kbd->keycodes[0]);
+ input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes);
+
+ matrix_keypad_build_keymap(keymap, ROW_SHIFT,
+ input_dev->keycode, input_dev->keybit);
+
+ input_set_drvdata(input_dev, kbd);
+
+ error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd);
+ if (error) {
+ dev_err(&pdev->dev, "request_irq fail\n");
+ goto err_put_clk;
+ }
+
+ error = input_register_device(input_dev);
+ if (error) {
+ dev_err(&pdev->dev, "Unable to register keyboard device\n");
+ goto err_free_irq;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+ platform_set_drvdata(pdev, kbd);
+
+ return 0;
+
+err_free_irq:
+ free_irq(kbd->irq, kbd);
+err_put_clk:
+ clk_put(kbd->clk);
+err_iounmap:
+ iounmap(kbd->io_base);
+err_release_mem_region:
+ release_mem_region(res->start, resource_size(res));
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(kbd);
+
+ return error;
+}
+
+static int __devexit spear_kbd_remove(struct platform_device *pdev)
+{
+ struct spear_kbd *kbd = platform_get_drvdata(pdev);
+
+ free_irq(kbd->irq, kbd);
+ input_unregister_device(kbd->input);
+ clk_put(kbd->clk);
+ iounmap(kbd->io_base);
+ release_mem_region(kbd->res->start, resource_size(kbd->res));
+ kfree(kbd);
+
+ device_init_wakeup(&pdev->dev, 1);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int spear_kbd_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct spear_kbd *kbd = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = kbd->input;
+
+ mutex_lock(&input_dev->mutex);
+
+ if (input_dev->users)
+ clk_enable(kbd->clk);
+
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(kbd->irq);
+
+ mutex_unlock(&input_dev->mutex);
+
+ return 0;
+}
+
+static int spear_kbd_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct spear_kbd *kbd = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = kbd->input;
+
+ mutex_lock(&input_dev->mutex);
+
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(kbd->irq);
+
+ if (input_dev->users)
+ clk_enable(kbd->clk);
+
+ mutex_unlock(&input_dev->mutex);
+
+ return 0;
+}
+
+static const struct dev_pm_ops spear_kbd_pm_ops = {
+ .suspend = spear_kbd_suspend,
+ .resume = spear_kbd_resume,
+};
+#endif
+
+static struct platform_driver spear_kbd_driver = {
+ .probe = spear_kbd_probe,
+ .remove = __devexit_p(spear_kbd_remove),
+ .driver = {
+ .name = "keyboard",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &spear_kbd_pm_ops,
+#endif
+ },
+};
+
+static int __init spear_kbd_init(void)
+{
+ return platform_driver_register(&spear_kbd_driver);
+}
+module_init(spear_kbd_init);
+
+static void __exit spear_kbd_exit(void)
+{
+ platform_driver_unregister(&spear_kbd_driver);
+}
+module_exit(spear_kbd_exit);
+
+MODULE_AUTHOR("Rajeev Kumar");
+MODULE_DESCRIPTION("SPEAr Keyboard Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c
new file mode 100644
index 000000000000..69dc0cb20a00
--- /dev/null
+++ b/drivers/input/keyboard/tc3589x-keypad.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ * License Terms: GNU General Public License, version 2
+ *
+ * TC35893 MFD Keypad Controller driver
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/mfd/tc3589x.h>
+
+/* Maximum supported keypad matrix row/columns size */
+#define TC3589x_MAX_KPROW 8
+#define TC3589x_MAX_KPCOL 12
+
+/* keypad related Constants */
+#define TC3589x_MAX_DEBOUNCE_SETTLE 0xFF
+#define DEDICATED_KEY_VAL 0xFF
+
+/* Pull up/down masks */
+#define TC3589x_NO_PULL_MASK 0x0
+#define TC3589x_PULL_DOWN_MASK 0x1
+#define TC3589x_PULL_UP_MASK 0x2
+#define TC3589x_PULLUP_ALL_MASK 0xAA
+#define TC3589x_IO_PULL_VAL(index, mask) ((mask)<<((index)%4)*2))
+
+/* Bit masks for IOCFG register */
+#define IOCFG_BALLCFG 0x01
+#define IOCFG_IG 0x08
+
+#define KP_EVCODE_COL_MASK 0x0F
+#define KP_EVCODE_ROW_MASK 0x70
+#define KP_RELEASE_EVT_MASK 0x80
+
+#define KP_ROW_SHIFT 4
+
+#define KP_NO_VALID_KEY_MASK 0x7F
+
+/* bit masks for RESTCTRL register */
+#define TC3589x_KBDRST 0x2
+#define TC3589x_IRQRST 0x10
+#define TC3589x_RESET_ALL 0x1B
+
+/* KBDMFS register bit mask */
+#define TC3589x_KBDMFS_EN 0x1
+
+/* CLKEN register bitmask */
+#define KPD_CLK_EN 0x1
+
+/* RSTINTCLR register bit mask */
+#define IRQ_CLEAR 0x1
+
+/* bit masks for keyboard interrupts*/
+#define TC3589x_EVT_LOSS_INT 0x8
+#define TC3589x_EVT_INT 0x4
+#define TC3589x_KBD_LOSS_INT 0x2
+#define TC3589x_KBD_INT 0x1
+
+/* bit masks for keyboard interrupt clear*/
+#define TC3589x_EVT_INT_CLR 0x2
+#define TC3589x_KBD_INT_CLR 0x1
+
+#define TC3589x_KBD_KEYMAP_SIZE 64
+
+/**
+ * struct tc_keypad - data structure used by keypad driver
+ * @input: pointer to input device object
+ * @board: keypad platform device
+ * @krow: number of rows
+ * @kcol: number of coloumns
+ * @keymap: matrix scan code table for keycodes
+ */
+struct tc_keypad {
+ struct tc3589x *tc3589x;
+ struct input_dev *input;
+ const struct tc3589x_keypad_platform_data *board;
+ unsigned int krow;
+ unsigned int kcol;
+ unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE];
+ bool keypad_stopped;
+};
+
+static int __devinit tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad)
+{
+ int ret;
+ struct tc3589x *tc3589x = keypad->tc3589x;
+ u8 settle_time = keypad->board->settle_time;
+ u8 dbounce_period = keypad->board->debounce_period;
+ u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */
+ u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */
+
+ /* validate platform configurations */
+ if (keypad->board->kcol > TC3589x_MAX_KPCOL ||
+ keypad->board->krow > TC3589x_MAX_KPROW ||
+ keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE ||
+ keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE)
+ return -EINVAL;
+
+ /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE,
+ (rows << KP_ROW_SHIFT) | column);
+ if (ret < 0)
+ return ret;
+
+ /* configure dedicated key config, no dedicated key selected */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL);
+ if (ret < 0)
+ return ret;
+
+ ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL);
+ if (ret < 0)
+ return ret;
+
+ /* Configure settle time */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time);
+ if (ret < 0)
+ return ret;
+
+ /* Configure debounce time */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period);
+ if (ret < 0)
+ return ret;
+
+ /* Start of initialise keypad GPIOs */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG);
+ if (ret < 0)
+ return ret;
+
+ /* Configure pull-up resistors for all row GPIOs */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB,
+ TC3589x_PULLUP_ALL_MASK);
+ if (ret < 0)
+ return ret;
+
+ ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB,
+ TC3589x_PULLUP_ALL_MASK);
+ if (ret < 0)
+ return ret;
+
+ /* Configure pull-up resistors for all column GPIOs */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB,
+ TC3589x_PULLUP_ALL_MASK);
+ if (ret < 0)
+ return ret;
+
+ ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB,
+ TC3589x_PULLUP_ALL_MASK);
+ if (ret < 0)
+ return ret;
+
+ ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB,
+ TC3589x_PULLUP_ALL_MASK);
+
+ return ret;
+}
+
+#define TC35893_DATA_REGS 4
+#define TC35893_KEYCODE_FIFO_EMPTY 0x7f
+#define TC35893_KEYCODE_FIFO_CLEAR 0xff
+#define TC35893_KEYPAD_ROW_SHIFT 0x3
+
+static irqreturn_t tc3589x_keypad_irq(int irq, void *dev)
+{
+ struct tc_keypad *keypad = dev;
+ struct tc3589x *tc3589x = keypad->tc3589x;
+ u8 i, row_index, col_index, kbd_code, up;
+ u8 code;
+
+ for (i = 0; i < TC35893_DATA_REGS * 2; i++) {
+ kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO);
+
+ /* loop till fifo is empty and no more keys are pressed */
+ if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY ||
+ kbd_code == TC35893_KEYCODE_FIFO_CLEAR)
+ continue;
+
+ /* valid key is found */
+ col_index = kbd_code & KP_EVCODE_COL_MASK;
+ row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT;
+ code = MATRIX_SCAN_CODE(row_index, col_index,
+ TC35893_KEYPAD_ROW_SHIFT);
+ up = kbd_code & KP_RELEASE_EVT_MASK;
+
+ input_event(keypad->input, EV_MSC, MSC_SCAN, code);
+ input_report_key(keypad->input, keypad->keymap[code], !up);
+ input_sync(keypad->input);
+ }
+
+ /* clear IRQ */
+ tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
+ 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
+ /* enable IRQ */
+ tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
+ 0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
+
+ return IRQ_HANDLED;
+}
+
+static int tc3589x_keypad_enable(struct tc_keypad *keypad)
+{
+ struct tc3589x *tc3589x = keypad->tc3589x;
+ int ret;
+
+ /* pull the keypad module out of reset */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0);
+ if (ret < 0)
+ return ret;
+
+ /* configure KBDMFS */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN);
+ if (ret < 0)
+ return ret;
+
+ /* enable the keypad clock */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN);
+ if (ret < 0)
+ return ret;
+
+ /* clear pending IRQs */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1);
+ if (ret < 0)
+ return ret;
+
+ /* enable the IRQs */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0,
+ TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
+ if (ret < 0)
+ return ret;
+
+ keypad->keypad_stopped = false;
+
+ return ret;
+}
+
+static int tc3589x_keypad_disable(struct tc_keypad *keypad)
+{
+ struct tc3589x *tc3589x = keypad->tc3589x;
+ int ret;
+
+ /* clear IRQ */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
+ 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
+ if (ret < 0)
+ return ret;
+
+ /* disable all interrupts */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
+ ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0);
+ if (ret < 0)
+ return ret;
+
+ /* disable the keypad module */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0);
+ if (ret < 0)
+ return ret;
+
+ /* put the keypad module into reset */
+ ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1);
+
+ keypad->keypad_stopped = true;
+
+ return ret;
+}
+
+static int tc3589x_keypad_open(struct input_dev *input)
+{
+ int error;
+ struct tc_keypad *keypad = input_get_drvdata(input);
+
+ /* enable the keypad module */
+ error = tc3589x_keypad_enable(keypad);
+ if (error < 0) {
+ dev_err(&input->dev, "failed to enable keypad module\n");
+ return error;
+ }
+
+ error = tc3589x_keypad_init_key_hardware(keypad);
+ if (error < 0) {
+ dev_err(&input->dev, "failed to configure keypad module\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static void tc3589x_keypad_close(struct input_dev *input)
+{
+ struct tc_keypad *keypad = input_get_drvdata(input);
+
+ /* disable the keypad module */
+ tc3589x_keypad_disable(keypad);
+}
+
+static int __devinit tc3589x_keypad_probe(struct platform_device *pdev)
+{
+ struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
+ struct tc_keypad *keypad;
+ struct input_dev *input;
+ const struct tc3589x_keypad_platform_data *plat;
+ int error, irq;
+
+ plat = tc3589x->pdata->keypad;
+ if (!plat) {
+ dev_err(&pdev->dev, "invalid keypad platform data\n");
+ return -EINVAL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!keypad || !input) {
+ dev_err(&pdev->dev, "failed to allocate keypad memory\n");
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ keypad->board = plat;
+ keypad->input = input;
+ keypad->tc3589x = tc3589x;
+
+ input->id.bustype = BUS_I2C;
+ input->name = pdev->name;
+ input->dev.parent = &pdev->dev;
+
+ input->keycode = keypad->keymap;
+ input->keycodesize = sizeof(keypad->keymap[0]);
+ input->keycodemax = ARRAY_SIZE(keypad->keymap);
+
+ input->open = tc3589x_keypad_open;
+ input->close = tc3589x_keypad_close;
+
+ input_set_drvdata(input, keypad);
+
+ input_set_capability(input, EV_MSC, MSC_SCAN);
+
+ __set_bit(EV_KEY, input->evbit);
+ if (!plat->no_autorepeat)
+ __set_bit(EV_REP, input->evbit);
+
+ matrix_keypad_build_keymap(plat->keymap_data, 0x3,
+ input->keycode, input->keybit);
+
+ error = request_threaded_irq(irq, NULL,
+ tc3589x_keypad_irq, plat->irqtype,
+ "tc3589x-keypad", keypad);
+ if (error < 0) {
+ dev_err(&pdev->dev,
+ "Could not allocate irq %d,error %d\n",
+ irq, error);
+ goto err_free_mem;
+ }
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(&pdev->dev, "Could not register input device\n");
+ goto err_free_irq;
+ }
+
+ /* let platform decide if keypad is a wakeup source or not */
+ device_init_wakeup(&pdev->dev, plat->enable_wakeup);
+ device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup);
+
+ platform_set_drvdata(pdev, keypad);
+
+ return 0;
+
+err_free_irq:
+ free_irq(irq, keypad);
+err_free_mem:
+ input_free_device(input);
+ kfree(keypad);
+ return error;
+}
+
+static int __devexit tc3589x_keypad_remove(struct platform_device *pdev)
+{
+ struct tc_keypad *keypad = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ if (!keypad->keypad_stopped)
+ tc3589x_keypad_disable(keypad);
+
+ free_irq(irq, keypad);
+
+ input_unregister_device(keypad->input);
+
+ kfree(keypad);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int tc3589x_keypad_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct tc_keypad *keypad = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ /* keypad is already off; we do nothing */
+ if (keypad->keypad_stopped)
+ return 0;
+
+ /* if device is not a wakeup source, disable it for powersave */
+ if (!device_may_wakeup(&pdev->dev))
+ tc3589x_keypad_disable(keypad);
+ else
+ enable_irq_wake(irq);
+
+ return 0;
+}
+
+static int tc3589x_keypad_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct tc_keypad *keypad = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ if (!keypad->keypad_stopped)
+ return 0;
+
+ /* enable the device to resume normal operations */
+ if (!device_may_wakeup(&pdev->dev))
+ tc3589x_keypad_enable(keypad);
+ else
+ disable_irq_wake(irq);
+
+ return 0;
+}
+
+static const SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops,
+ tc3589x_keypad_suspend, tc3589x_keypad_resume);
+#endif
+
+static struct platform_driver tc3589x_keypad_driver = {
+ .driver.name = "tc3589x-keypad",
+ .driver.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .driver.pm = &tc3589x_keypad_dev_pm_ops,
+#endif
+ .probe = tc3589x_keypad_probe,
+ .remove = __devexit_p(tc3589x_keypad_remove),
+};
+
+static int __init tc3589x_keypad_init(void)
+{
+ return platform_driver_register(&tc3589x_keypad_driver);
+}
+module_init(tc3589x_keypad_init);
+
+static void __exit tc3589x_keypad_exit(void)
+{
+ return platform_driver_unregister(&tc3589x_keypad_driver);
+}
+module_exit(tc3589x_keypad_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer");
+MODULE_DESCRIPTION("TC35893 Keypad Driver");
+MODULE_ALIAS("platform:tc3589x-keypad")
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 00137bebcf97..800fbccf1f0f 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -29,6 +29,7 @@
static const struct i2c_device_id tca6416_id[] = {
{ "tca6416-keys", 16, },
+ { "tca6408-keys", 8, },
{ }
};
MODULE_DEVICE_TABLE(i2c, tca6416_id);
@@ -46,8 +47,9 @@ struct tca6416_keypad_chip {
struct i2c_client *client;
struct input_dev *input;
struct delayed_work dwork;
- u16 pinmask;
+ int io_size;
int irqnum;
+ u16 pinmask;
bool use_polling;
struct tca6416_button buttons[0];
};
@@ -56,7 +58,9 @@ static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val)
{
int error;
- error = i2c_smbus_write_word_data(chip->client, reg << 1, val);
+ error = chip->io_size > 8 ?
+ i2c_smbus_write_word_data(chip->client, reg << 1, val) :
+ i2c_smbus_write_byte_data(chip->client, reg, val);
if (error < 0) {
dev_err(&chip->client->dev,
"%s failed, reg: %d, val: %d, error: %d\n",
@@ -71,7 +75,9 @@ static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val)
{
int retval;
- retval = i2c_smbus_read_word_data(chip->client, reg << 1);
+ retval = chip->io_size > 8 ?
+ i2c_smbus_read_word_data(chip->client, reg << 1) :
+ i2c_smbus_read_byte_data(chip->client, reg);
if (retval < 0) {
dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n",
__func__, reg, retval);
@@ -224,6 +230,7 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client,
chip->client = client;
chip->input = input;
+ chip->io_size = id->driver_data;
chip->pinmask = pdata->pinmask;
chip->use_polling = pdata->use_polling;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index b99b8cbde02f..b0c6772851a9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -294,24 +294,6 @@ config INPUT_SGI_BTNS
To compile this driver as a module, choose M here: the
module will be called sgi_btns.
-config INPUT_WINBOND_CIR
- tristate "Winbond IR remote control"
- depends on X86 && PNP
- select NEW_LEDS
- select LEDS_CLASS
- select LEDS_TRIGGERS
- select BITREVERSE
- help
- Say Y here if you want to use the IR remote functionality found
- in some Winbond SuperI/O chips. Currently only the WPCD376I
- chip is supported (included in some Intel Media series motherboards).
-
- IR Receive and wake-on-IR from suspend and power-off is currently
- supported.
-
- To compile this driver as a module, choose M here: the module will be
- called winbond_cir.
-
config HP_SDC_RTC
tristate "HP SDC Real Time Clock"
depends on (GSC || HP300) && SERIO
@@ -448,4 +430,28 @@ config INPUT_ADXL34X_SPI
To compile this driver as a module, choose M here: the
module will be called adxl34x-spi.
+config INPUT_CMA3000
+ tristate "VTI CMA3000 Tri-axis accelerometer"
+ help
+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer
+ driver
+
+ This driver currently only supports I2C interface to the
+ controller. Also select the I2C method.
+
+ If unsure, say N
+
+ To compile this driver as a module, choose M here: the
+ module will be called cma3000_d0x.
+
+config INPUT_CMA3000_I2C
+ tristate "Support I2C bus connection"
+ depends on INPUT_CMA3000 && I2C
+ help
+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer
+ through I2C interface.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cma3000_d0x_i2c.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 1fe1f6c8b737..9b4797112c9a 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -18,6 +18,8 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
+obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
+obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o
obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
@@ -38,7 +40,6 @@ 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
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
new file mode 100644
index 000000000000..1633b6342267
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -0,0 +1,398 @@
+/*
+ * VTI CMA3000_D0x Accelerometer driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ * Author: Hemanth V <hemanthv@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/cma3000.h>
+
+#include "cma3000_d0x.h"
+
+#define CMA3000_WHOAMI 0x00
+#define CMA3000_REVID 0x01
+#define CMA3000_CTRL 0x02
+#define CMA3000_STATUS 0x03
+#define CMA3000_RSTR 0x04
+#define CMA3000_INTSTATUS 0x05
+#define CMA3000_DOUTX 0x06
+#define CMA3000_DOUTY 0x07
+#define CMA3000_DOUTZ 0x08
+#define CMA3000_MDTHR 0x09
+#define CMA3000_MDFFTMR 0x0A
+#define CMA3000_FFTHR 0x0B
+
+#define CMA3000_RANGE2G (1 << 7)
+#define CMA3000_RANGE8G (0 << 7)
+#define CMA3000_BUSI2C (0 << 4)
+#define CMA3000_MODEMASK (7 << 1)
+#define CMA3000_GRANGEMASK (1 << 7)
+
+#define CMA3000_STATUS_PERR 1
+#define CMA3000_INTSTATUS_FFDET (1 << 2)
+
+/* Settling time delay in ms */
+#define CMA3000_SETDELAY 30
+
+/* Delay for clearing interrupt in us */
+#define CMA3000_INTDELAY 44
+
+
+/*
+ * Bit weights in mg for bit 0, other bits need
+ * multipy factor 2^n. Eight bit is the sign bit.
+ */
+#define BIT_TO_2G 18
+#define BIT_TO_8G 71
+
+struct cma3000_accl_data {
+ const struct cma3000_bus_ops *bus_ops;
+ const struct cma3000_platform_data *pdata;
+
+ struct device *dev;
+ struct input_dev *input_dev;
+
+ int bit_to_mg;
+ int irq;
+
+ int g_range;
+ u8 mode;
+
+ struct mutex mutex;
+ bool opened;
+ bool suspended;
+};
+
+#define CMA3000_READ(data, reg, msg) \
+ (data->bus_ops->read(data->dev, reg, msg))
+#define CMA3000_SET(data, reg, val, msg) \
+ ((data)->bus_ops->write(data->dev, reg, val, msg))
+
+/*
+ * Conversion for each of the eight modes to g, depending
+ * on G range i.e 2G or 8G. Some modes always operate in
+ * 8G.
+ */
+
+static int mode_to_mg[8][2] = {
+ { 0, 0 },
+ { BIT_TO_8G, BIT_TO_2G },
+ { BIT_TO_8G, BIT_TO_2G },
+ { BIT_TO_8G, BIT_TO_8G },
+ { BIT_TO_8G, BIT_TO_8G },
+ { BIT_TO_8G, BIT_TO_2G },
+ { BIT_TO_8G, BIT_TO_2G },
+ { 0, 0},
+};
+
+static void decode_mg(struct cma3000_accl_data *data, int *datax,
+ int *datay, int *dataz)
+{
+ /* Data in 2's complement, convert to mg */
+ *datax = ((s8)*datax) * data->bit_to_mg;
+ *datay = ((s8)*datay) * data->bit_to_mg;
+ *dataz = ((s8)*dataz) * data->bit_to_mg;
+}
+
+static irqreturn_t cma3000_thread_irq(int irq, void *dev_id)
+{
+ struct cma3000_accl_data *data = dev_id;
+ int datax, datay, dataz;
+ u8 ctrl, mode, range, intr_status;
+
+ intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status");
+ if (intr_status < 0)
+ return IRQ_NONE;
+
+ /* Check if free fall is detected, report immediately */
+ if (intr_status & CMA3000_INTSTATUS_FFDET) {
+ input_report_abs(data->input_dev, ABS_MISC, 1);
+ input_sync(data->input_dev);
+ } else {
+ input_report_abs(data->input_dev, ABS_MISC, 0);
+ }
+
+ datax = CMA3000_READ(data, CMA3000_DOUTX, "X");
+ datay = CMA3000_READ(data, CMA3000_DOUTY, "Y");
+ dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z");
+
+ ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl");
+ mode = (ctrl & CMA3000_MODEMASK) >> 1;
+ range = (ctrl & CMA3000_GRANGEMASK) >> 7;
+
+ data->bit_to_mg = mode_to_mg[mode][range];
+
+ /* Interrupt not for this device */
+ if (data->bit_to_mg == 0)
+ return IRQ_NONE;
+
+ /* Decode register values to milli g */
+ decode_mg(data, &datax, &datay, &dataz);
+
+ input_report_abs(data->input_dev, ABS_X, datax);
+ input_report_abs(data->input_dev, ABS_Y, datay);
+ input_report_abs(data->input_dev, ABS_Z, dataz);
+ input_sync(data->input_dev);
+
+ return IRQ_HANDLED;
+}
+
+static int cma3000_reset(struct cma3000_accl_data *data)
+{
+ int val;
+
+ /* Reset sequence */
+ CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset");
+ CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset");
+ CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset");
+
+ /* Settling time delay */
+ mdelay(10);
+
+ val = CMA3000_READ(data, CMA3000_STATUS, "Status");
+ if (val < 0) {
+ dev_err(data->dev, "Reset failed\n");
+ return val;
+ }
+
+ if (val & CMA3000_STATUS_PERR) {
+ dev_err(data->dev, "Parity Error\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int cma3000_poweron(struct cma3000_accl_data *data)
+{
+ const struct cma3000_platform_data *pdata = data->pdata;
+ u8 ctrl = 0;
+ int ret;
+
+ if (data->g_range == CMARANGE_2G) {
+ ctrl = (data->mode << 1) | CMA3000_RANGE2G;
+ } else if (data->g_range == CMARANGE_8G) {
+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;
+ } else {
+ dev_info(data->dev,
+ "Invalid G range specified, assuming 8G\n");
+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;
+ }
+
+ ctrl |= data->bus_ops->ctrl_mod;
+
+ CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr,
+ "Motion Detect Threshold");
+ CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr,
+ "Time register");
+ CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr,
+ "Free fall threshold");
+ ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting");
+ if (ret < 0)
+ return -EIO;
+
+ msleep(CMA3000_SETDELAY);
+
+ return 0;
+}
+
+static int cma3000_poweroff(struct cma3000_accl_data *data)
+{
+ int ret;
+
+ ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting");
+ msleep(CMA3000_SETDELAY);
+
+ return ret;
+}
+
+static int cma3000_open(struct input_dev *input_dev)
+{
+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);
+
+ mutex_lock(&data->mutex);
+
+ if (!data->suspended)
+ cma3000_poweron(data);
+
+ data->opened = true;
+
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static void cma3000_close(struct input_dev *input_dev)
+{
+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);
+
+ mutex_lock(&data->mutex);
+
+ if (!data->suspended)
+ cma3000_poweroff(data);
+
+ data->opened = false;
+
+ mutex_unlock(&data->mutex);
+}
+
+void cma3000_suspend(struct cma3000_accl_data *data)
+{
+ mutex_lock(&data->mutex);
+
+ if (!data->suspended && data->opened)
+ cma3000_poweroff(data);
+
+ data->suspended = true;
+
+ mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL(cma3000_suspend);
+
+
+void cma3000_resume(struct cma3000_accl_data *data)
+{
+ mutex_lock(&data->mutex);
+
+ if (data->suspended && data->opened)
+ cma3000_poweron(data);
+
+ data->suspended = false;
+
+ mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL(cma3000_resume);
+
+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
+ const struct cma3000_bus_ops *bops)
+{
+ const struct cma3000_platform_data *pdata = dev->platform_data;
+ struct cma3000_accl_data *data;
+ struct input_dev *input_dev;
+ int rev;
+ int error;
+
+ if (!pdata) {
+ dev_err(dev, "platform data not found\n");
+ error = -EINVAL;
+ goto err_out;
+ }
+
+
+ /* if no IRQ return error */
+ if (irq == 0) {
+ error = -EINVAL;
+ goto err_out;
+ }
+
+ data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!data || !input_dev) {
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ data->dev = dev;
+ data->input_dev = input_dev;
+ data->bus_ops = bops;
+ data->pdata = pdata;
+ data->irq = irq;
+ mutex_init(&data->mutex);
+
+ data->mode = pdata->mode;
+ if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) {
+ data->mode = CMAMODE_MOTDET;
+ dev_warn(dev,
+ "Invalid mode specified, assuming Motion Detect\n");
+ }
+
+ data->g_range = pdata->g_range;
+ if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) {
+ dev_info(dev,
+ "Invalid G range specified, assuming 8G\n");
+ data->g_range = CMARANGE_8G;
+ }
+
+ input_dev->name = "cma3000-accelerometer";
+ input_dev->id.bustype = bops->bustype;
+ input_dev->open = cma3000_open;
+ input_dev->close = cma3000_close;
+
+ __set_bit(EV_ABS, input_dev->evbit);
+
+ input_set_abs_params(input_dev, ABS_X,
+ -data->g_range, data->g_range, pdata->fuzz_x, 0);
+ input_set_abs_params(input_dev, ABS_Y,
+ -data->g_range, data->g_range, pdata->fuzz_y, 0);
+ input_set_abs_params(input_dev, ABS_Z,
+ -data->g_range, data->g_range, pdata->fuzz_z, 0);
+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
+
+ input_set_drvdata(input_dev, data);
+
+ error = cma3000_reset(data);
+ if (error)
+ goto err_free_mem;
+
+ rev = CMA3000_READ(data, CMA3000_REVID, "Revid");
+ if (rev < 0) {
+ error = rev;
+ goto err_free_mem;
+ }
+
+ pr_info("CMA3000 Accelerometer: Revision %x\n", rev);
+
+ error = request_threaded_irq(irq, NULL, cma3000_thread_irq,
+ pdata->irqflags | IRQF_ONESHOT,
+ "cma3000_d0x", data);
+ if (error) {
+ dev_err(dev, "request_threaded_irq failed\n");
+ goto err_free_mem;
+ }
+
+ error = input_register_device(data->input_dev);
+ if (error) {
+ dev_err(dev, "Unable to register input device\n");
+ goto err_free_irq;
+ }
+
+ return data;
+
+err_free_irq:
+ free_irq(irq, data);
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(data);
+err_out:
+ return ERR_PTR(error);
+}
+EXPORT_SYMBOL(cma3000_init);
+
+void cma3000_exit(struct cma3000_accl_data *data)
+{
+ free_irq(data->irq, data);
+ input_unregister_device(data->input_dev);
+ kfree(data);
+}
+EXPORT_SYMBOL(cma3000_exit);
+
+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
diff --git a/drivers/input/misc/cma3000_d0x.h b/drivers/input/misc/cma3000_d0x.h
new file mode 100644
index 000000000000..2304ce306e1c
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x.h
@@ -0,0 +1,42 @@
+/*
+ * VTI CMA3000_D0x Accelerometer driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ * Author: Hemanth V <hemanthv@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _INPUT_CMA3000_H
+#define _INPUT_CMA3000_H
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+struct device;
+struct cma3000_accl_data;
+
+struct cma3000_bus_ops {
+ u16 bustype;
+ u8 ctrl_mod;
+ int (*read)(struct device *, u8, char *);
+ int (*write)(struct device *, u8, u8, char *);
+};
+
+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
+ const struct cma3000_bus_ops *bops);
+void cma3000_exit(struct cma3000_accl_data *);
+void cma3000_suspend(struct cma3000_accl_data *);
+void cma3000_resume(struct cma3000_accl_data *);
+
+#endif
diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c
new file mode 100644
index 000000000000..d100cc5c5783
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x_i2c.c
@@ -0,0 +1,143 @@
+/*
+ * Implements I2C interface for VTI CMA300_D0x Accelerometer driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ * Author: Hemanth V <hemanthv@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/input/cma3000.h>
+#include "cma3000_d0x.h"
+
+static int cma3000_i2c_set(struct device *dev,
+ u8 reg, u8 val, char *msg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s failed (%s, %d)\n", __func__, msg, ret);
+ return ret;
+}
+
+static int cma3000_i2c_read(struct device *dev, u8 reg, char *msg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s failed (%s, %d)\n", __func__, msg, ret);
+ return ret;
+}
+
+static const struct cma3000_bus_ops cma3000_i2c_bops = {
+ .bustype = BUS_I2C,
+#define CMA3000_BUSI2C (0 << 4)
+ .ctrl_mod = CMA3000_BUSI2C,
+ .read = cma3000_i2c_read,
+ .write = cma3000_i2c_set,
+};
+
+static int __devinit cma3000_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct cma3000_accl_data *data;
+
+ data = cma3000_init(&client->dev, client->irq, &cma3000_i2c_bops);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ i2c_set_clientdata(client, data);
+
+ return 0;
+}
+
+static int __devexit cma3000_i2c_remove(struct i2c_client *client)
+{
+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
+
+ cma3000_exit(data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int cma3000_i2c_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
+
+ cma3000_suspend(data);
+
+ return 0;
+}
+
+static int cma3000_i2c_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
+
+ cma3000_resume(data);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cma3000_i2c_pm_ops = {
+ .suspend = cma3000_i2c_suspend,
+ .resume = cma3000_i2c_resume,
+};
+#endif
+
+static const struct i2c_device_id cma3000_i2c_id[] = {
+ { "cma3000_d01", 0 },
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id);
+
+static struct i2c_driver cma3000_i2c_driver = {
+ .probe = cma3000_i2c_probe,
+ .remove = __devexit_p(cma3000_i2c_remove),
+ .id_table = cma3000_i2c_id,
+ .driver = {
+ .name = "cma3000_i2c_accl",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &cma3000_i2c_pm_ops,
+#endif
+ },
+};
+
+static int __init cma3000_i2c_init(void)
+{
+ return i2c_add_driver(&cma3000_i2c_driver);
+}
+
+static void __exit cma3000_i2c_exit(void)
+{
+ i2c_del_driver(&cma3000_i2c_driver);
+}
+
+module_init(cma3000_i2c_init);
+module_exit(cma3000_i2c_exit);
+
+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer I2C Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c
index d1583aea1721..08be1a355956 100644
--- a/drivers/input/misc/pcf8574_keypad.c
+++ b/drivers/input/misc/pcf8574_keypad.c
@@ -169,19 +169,29 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client)
}
#ifdef CONFIG_PM
-static int pcf8574_kp_resume(struct i2c_client *client)
+static int pcf8574_kp_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
enable_irq(client->irq);
return 0;
}
-static int pcf8574_kp_suspend(struct i2c_client *client, pm_message_t mesg)
+static int pcf8574_kp_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
disable_irq(client->irq);
return 0;
}
+
+static const struct dev_pm_ops pcf8574_kp_pm_ops = {
+ .suspend = pcf8574_kp_suspend,
+ .resume = pcf8574_kp_resume,
+};
+
#else
# define pcf8574_kp_resume NULL
# define pcf8574_kp_suspend NULL
@@ -197,11 +207,12 @@ static struct i2c_driver pcf8574_kp_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &pcf8574_kp_pm_ops,
+#endif
},
.probe = pcf8574_kp_probe,
.remove = __devexit_p(pcf8574_kp_remove),
- .suspend = pcf8574_kp_suspend,
- .resume = pcf8574_kp_resume,
.id_table = pcf8574_kp_id,
};
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index b9410784e6a1..82542a1c1098 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uinput.h>
+#include <linux/input/mt.h>
#include "../input-compat.h"
static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -406,8 +407,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
goto exit;
if (test_bit(ABS_MT_SLOT, dev->absbit)) {
int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
- input_mt_create_slots(dev, nslot);
- input_set_events_per_packet(dev, 6 * nslot);
+ input_mt_init_slots(dev, nslot);
} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
input_set_events_per_packet(dev, 60);
}
@@ -680,6 +680,10 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
retval = uinput_set_bit(arg, swbit, SW_MAX);
break;
+ case UI_SET_PROPBIT:
+ retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
+ break;
+
case UI_SET_PHYS:
if (udev->state == UIST_CREATED) {
retval = -EINVAL;
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index b95231763911..ee82851afe3e 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -55,6 +55,14 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
+/* MacbookAir3,2 (unibody), aka wellspring5 */
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
+/* MacbookAir3,1 (unibody), aka wellspring4 */
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
#define BCM5974_DEVICE(prod) { \
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
@@ -80,6 +88,14 @@ static const struct usb_device_id bcm5974_table[] = {
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
+ /* MacbookAir3,2 */
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
+ /* MacbookAir3,1 */
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
+ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
/* Terminating entry */
{}
};
@@ -234,6 +250,30 @@ static const struct bcm5974_config bcm5974_config_table[] = {
{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
},
+ {
+ USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,
+ USB_DEVICE_ID_APPLE_WELLSPRING4_ISO,
+ USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,
+ HAS_INTEGRATED_BUTTON,
+ 0x84, sizeof(struct bt_data),
+ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+ { DIM_X, DIM_X / SN_COORD, -4620, 5140 },
+ { DIM_Y, DIM_Y / SN_COORD, -150, 6600 }
+ },
+ {
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,
+ USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,
+ HAS_INTEGRATED_BUTTON,
+ 0x84, sizeof(struct bt_data),
+ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+ { DIM_X, DIM_X / SN_COORD, -4616, 5112 },
+ { DIM_Y, DIM_Y / SN_COORD, -142, 5234 }
+ },
{}
};
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 1d2205b24800..95577c15ae56 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -40,6 +40,8 @@
#include "psmouse.h"
#include "hgpk.h"
+#define ILLEGAL_XY 999999
+
static bool tpdebug;
module_param(tpdebug, bool, 0644);
MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
@@ -47,48 +49,150 @@ MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
static int recalib_delta = 100;
module_param(recalib_delta, int, 0644);
MODULE_PARM_DESC(recalib_delta,
- "packets containing a delta this large will cause a recalibration.");
+ "packets containing a delta this large will be discarded, and a "
+ "recalibration may be scheduled.");
-static int jumpy_delay = 1000;
+static int jumpy_delay = 20;
module_param(jumpy_delay, int, 0644);
MODULE_PARM_DESC(jumpy_delay,
"delay (ms) before recal after jumpiness detected");
-static int spew_delay = 1000;
+static int spew_delay = 1;
module_param(spew_delay, int, 0644);
MODULE_PARM_DESC(spew_delay,
"delay (ms) before recal after packet spew detected");
-static int recal_guard_time = 2000;
+static int recal_guard_time;
module_param(recal_guard_time, int, 0644);
MODULE_PARM_DESC(recal_guard_time,
"interval (ms) during which recal will be restarted if packet received");
-static int post_interrupt_delay = 1000;
+static int post_interrupt_delay = 40;
module_param(post_interrupt_delay, int, 0644);
MODULE_PARM_DESC(post_interrupt_delay,
"delay (ms) before recal after recal interrupt detected");
+static bool autorecal = true;
+module_param(autorecal, bool, 0644);
+MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
+
+static char hgpk_mode_name[16];
+module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);
+MODULE_PARM_DESC(hgpk_mode,
+ "default hgpk mode: mouse, glidesensor or pentablet");
+
+static int hgpk_default_mode = HGPK_MODE_MOUSE;
+
+static const char * const hgpk_mode_names[] = {
+ [HGPK_MODE_MOUSE] = "Mouse",
+ [HGPK_MODE_GLIDESENSOR] = "GlideSensor",
+ [HGPK_MODE_PENTABLET] = "PenTablet",
+};
+
+static int hgpk_mode_from_name(const char *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {
+ const char *name = hgpk_mode_names[i];
+ if (strlen(name) == len && !strncasecmp(name, buf, len))
+ return i;
+ }
+
+ return HGPK_MODE_INVALID;
+}
+
+/*
+ * see if new value is within 20% of half of old value
+ */
+static int approx_half(int curr, int prev)
+{
+ int belowhalf, abovehalf;
+
+ if (curr < 5 || prev < 5)
+ return 0;
+
+ belowhalf = (prev * 8) / 20;
+ abovehalf = (prev * 12) / 20;
+
+ return belowhalf < curr && curr <= abovehalf;
+}
+
/*
- * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
- * above the pad and still have it send packets. This causes a jump cursor
- * when one places their finger on the pad. We can probably detect the
- * jump as we see a large deltas (>= 100px). In mouse mode, I've been
- * unable to even come close to 100px deltas during normal usage, so I think
- * this threshold is safe. If a large delta occurs, trigger a recalibration.
+ * Throw out oddly large delta packets, and any that immediately follow whose
+ * values are each approximately half of the previous. It seems that the ALPS
+ * firmware emits errant packets, and they get averaged out slowly.
*/
-static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)
+static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
{
struct hgpk_data *priv = psmouse->private;
+ int avx, avy;
+ bool do_recal = false;
+
+ avx = abs(x);
+ avy = abs(y);
+
+ /* discard if too big, or half that but > 4 times the prev delta */
+ if (avx > recalib_delta ||
+ (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
+ hgpk_err(psmouse, "detected %dpx jump in x\n", x);
+ priv->xbigj = avx;
+ } else if (approx_half(avx, priv->xbigj)) {
+ hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x);
+ priv->xbigj = avx;
+ priv->xsaw_secondary++;
+ } else {
+ if (priv->xbigj && priv->xsaw_secondary > 1)
+ do_recal = true;
+ priv->xbigj = 0;
+ priv->xsaw_secondary = 0;
+ }
+
+ if (avy > recalib_delta ||
+ (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
+ hgpk_err(psmouse, "detected %dpx jump in y\n", y);
+ priv->ybigj = avy;
+ } else if (approx_half(avy, priv->ybigj)) {
+ hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y);
+ priv->ybigj = avy;
+ priv->ysaw_secondary++;
+ } else {
+ if (priv->ybigj && priv->ysaw_secondary > 1)
+ do_recal = true;
+ priv->ybigj = 0;
+ priv->ysaw_secondary = 0;
+ }
- if (abs(x) > recalib_delta || abs(y) > recalib_delta) {
- hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",
- recalib_delta, x, y);
- /* My car gets forty rods to the hogshead and that's the
- * way I likes it! */
+ priv->xlast = avx;
+ priv->ylast = avy;
+
+ if (do_recal && jumpy_delay) {
+ hgpk_err(psmouse, "scheduling recalibration\n");
psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(jumpy_delay));
}
+
+ return priv->xbigj || priv->ybigj;
+}
+
+static void hgpk_reset_spew_detection(struct hgpk_data *priv)
+{
+ priv->spew_count = 0;
+ priv->dupe_count = 0;
+ priv->x_tally = 0;
+ priv->y_tally = 0;
+ priv->spew_flag = NO_SPEW;
+}
+
+static void hgpk_reset_hack_state(struct psmouse *psmouse)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ priv->abs_x = priv->abs_y = -1;
+ priv->xlast = priv->ylast = ILLEGAL_XY;
+ priv->xbigj = priv->ybigj = 0;
+ priv->xsaw_secondary = priv->ysaw_secondary = 0;
+ hgpk_reset_spew_detection(priv);
}
/*
@@ -116,20 +220,57 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
if (l || r)
return;
+ /* don't track spew if the workaround feature has been turned off */
+ if (!spew_delay)
+ return;
+
+ if (abs(x) > 3 || abs(y) > 3) {
+ /* no spew, or spew ended */
+ hgpk_reset_spew_detection(priv);
+ return;
+ }
+
+ /* Keep a tally of the overall delta to the cursor position caused by
+ * the spew */
priv->x_tally += x;
priv->y_tally += y;
- if (++priv->count > 100) {
+ switch (priv->spew_flag) {
+ case NO_SPEW:
+ /* we're not spewing, but this packet might be the start */
+ priv->spew_flag = MAYBE_SPEWING;
+
+ /* fall-through */
+
+ case MAYBE_SPEWING:
+ priv->spew_count++;
+
+ if (priv->spew_count < SPEW_WATCH_COUNT)
+ break;
+
+ /* excessive spew detected, request recalibration */
+ priv->spew_flag = SPEW_DETECTED;
+
+ /* fall-through */
+
+ case SPEW_DETECTED:
+ /* only recalibrate when the overall delta to the cursor
+ * is really small. if the spew is causing significant cursor
+ * movement, it is probably a case of the user moving the
+ * cursor very slowly across the screen. */
if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
- hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",
+ hgpk_err(psmouse, "packet spew detected (%d,%d)\n",
priv->x_tally, priv->y_tally);
+ priv->spew_flag = RECALIBRATING;
psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(spew_delay));
}
- /* reset every 100 packets */
- priv->count = 0;
- priv->x_tally = 0;
- priv->y_tally = 0;
+
+ break;
+ case RECALIBRATING:
+ /* we already detected a spew and requested a recalibration,
+ * just wait for the queue to kick into action. */
+ break;
}
}
@@ -143,25 +284,168 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
* swr/swl are the left/right buttons.
* x-neg/y-neg are the x and y delta negative bits
* x-over/y-over are the x and y overflow bits
+ *
+ * ---
+ *
+ * HGPK Advanced Mode - single-mode format
+ *
+ * byte 0(PT): 1 1 0 0 1 1 1 1
+ * byte 0(GS): 1 1 1 1 1 1 1 1
+ * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
+ * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0
+ * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw
+ * byte 3: 0 y9 y8 y7 1 0 swr swl
+ * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
+ * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
+ *
+ * ?'s are not defined in the protocol spec, may vary between models.
+ *
+ * swr/swl are the left/right buttons.
+ *
+ * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
+ * pen/finger
*/
-static int hgpk_validate_byte(unsigned char *packet)
+static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
{
- return (packet[0] & 0x0C) != 0x08;
+ struct hgpk_data *priv = psmouse->private;
+ int pktcnt = psmouse->pktcnt;
+ bool valid;
+
+ switch (priv->mode) {
+ case HGPK_MODE_MOUSE:
+ valid = (packet[0] & 0x0C) == 0x08;
+ break;
+
+ case HGPK_MODE_GLIDESENSOR:
+ valid = pktcnt == 1 ?
+ packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);
+ break;
+
+ case HGPK_MODE_PENTABLET:
+ valid = pktcnt == 1 ?
+ packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);
+ break;
+
+ default:
+ valid = false;
+ break;
+ }
+
+ if (!valid)
+ hgpk_dbg(psmouse,
+ "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n",
+ priv->mode, pktcnt,
+ psmouse->packet[0], psmouse->packet[1],
+ psmouse->packet[2], psmouse->packet[3],
+ psmouse->packet[4], psmouse->packet[5]);
+
+ return valid;
}
-static void hgpk_process_packet(struct psmouse *psmouse)
+static void hgpk_process_advanced_packet(struct psmouse *psmouse)
{
- struct input_dev *dev = psmouse->dev;
+ struct hgpk_data *priv = psmouse->private;
+ struct input_dev *idev = psmouse->dev;
unsigned char *packet = psmouse->packet;
- int x, y, left, right;
+ int down = !!(packet[2] & 2);
+ int left = !!(packet[3] & 1);
+ int right = !!(packet[3] & 2);
+ int x = packet[1] | ((packet[2] & 0x78) << 4);
+ int y = packet[4] | ((packet[3] & 0x70) << 3);
+
+ if (priv->mode == HGPK_MODE_GLIDESENSOR) {
+ int pt_down = !!(packet[2] & 1);
+ int finger_down = !!(packet[2] & 2);
+ int z = packet[5];
+
+ input_report_abs(idev, ABS_PRESSURE, z);
+ if (tpdebug)
+ hgpk_dbg(psmouse, "pd=%d fd=%d z=%d",
+ pt_down, finger_down, z);
+ } else {
+ /*
+ * PenTablet mode does not report pressure, so we don't
+ * report it here
+ */
+ if (tpdebug)
+ hgpk_dbg(psmouse, "pd=%d ", down);
+ }
+
+ if (tpdebug)
+ hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);
+
+ input_report_key(idev, BTN_TOUCH, down);
+ input_report_key(idev, BTN_LEFT, left);
+ input_report_key(idev, BTN_RIGHT, right);
+
+ /*
+ * If this packet says that the finger was removed, reset our position
+ * tracking so that we don't erroneously detect a jump on next press.
+ */
+ if (!down) {
+ hgpk_reset_hack_state(psmouse);
+ goto done;
+ }
+
+ /*
+ * Weed out duplicate packets (we get quite a few, and they mess up
+ * our jump detection)
+ */
+ if (x == priv->abs_x && y == priv->abs_y) {
+ if (++priv->dupe_count > SPEW_WATCH_COUNT) {
+ if (tpdebug)
+ hgpk_dbg(psmouse, "hard spew detected\n");
+ priv->spew_flag = RECALIBRATING;
+ psmouse_queue_work(psmouse, &priv->recalib_wq,
+ msecs_to_jiffies(spew_delay));
+ }
+ goto done;
+ }
- left = packet[0] & 1;
- right = (packet[0] >> 1) & 1;
+ /* not a duplicate, continue with position reporting */
+ priv->dupe_count = 0;
+
+ /* Don't apply hacks in PT mode, it seems reliable */
+ if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {
+ int x_diff = priv->abs_x - x;
+ int y_diff = priv->abs_y - y;
+ if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
+ if (tpdebug)
+ hgpk_dbg(psmouse, "discarding\n");
+ goto done;
+ }
+ hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
+ }
- x = packet[1] - ((packet[0] << 4) & 0x100);
- y = ((packet[0] << 3) & 0x100) - packet[2];
+ input_report_abs(idev, ABS_X, x);
+ input_report_abs(idev, ABS_Y, y);
+ priv->abs_x = x;
+ priv->abs_y = y;
+
+done:
+ input_sync(idev);
+}
+
+static void hgpk_process_simple_packet(struct psmouse *psmouse)
+{
+ struct input_dev *dev = psmouse->dev;
+ unsigned char *packet = psmouse->packet;
+ int left = packet[0] & 1;
+ int right = (packet[0] >> 1) & 1;
+ int x = packet[1] - ((packet[0] << 4) & 0x100);
+ int y = ((packet[0] << 3) & 0x100) - packet[2];
+
+ if (packet[0] & 0xc0)
+ hgpk_dbg(psmouse,
+ "overflow -- 0x%02x 0x%02x 0x%02x\n",
+ packet[0], packet[1], packet[2]);
+
+ if (hgpk_discard_decay_hack(psmouse, x, y)) {
+ if (tpdebug)
+ hgpk_dbg(psmouse, "discarding\n");
+ return;
+ }
- hgpk_jumpy_hack(psmouse, x, y);
hgpk_spewing_hack(psmouse, left, right, x, y);
if (tpdebug)
@@ -180,15 +464,14 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
{
struct hgpk_data *priv = psmouse->private;
- if (hgpk_validate_byte(psmouse->packet)) {
- hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",
- __func__, psmouse->pktcnt, psmouse->packet[0],
- psmouse->packet[1], psmouse->packet[2]);
+ if (!hgpk_is_byte_valid(psmouse, psmouse->packet))
return PSMOUSE_BAD_DATA;
- }
if (psmouse->pktcnt >= psmouse->pktsize) {
- hgpk_process_packet(psmouse);
+ if (priv->mode == HGPK_MODE_MOUSE)
+ hgpk_process_simple_packet(psmouse);
+ else
+ hgpk_process_advanced_packet(psmouse);
return PSMOUSE_FULL_PACKET;
}
@@ -210,33 +493,176 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
return PSMOUSE_GOOD_DATA;
}
+static int hgpk_select_mode(struct psmouse *psmouse)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ struct hgpk_data *priv = psmouse->private;
+ int i;
+ int cmd;
+
+ /*
+ * 4 disables to enable advanced mode
+ * then 3 0xf2 bytes as the preamble for GS/PT selection
+ */
+ const int advanced_init[] = {
+ PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
+ PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
+ 0xf2, 0xf2, 0xf2,
+ };
+
+ switch (priv->mode) {
+ case HGPK_MODE_MOUSE:
+ psmouse->pktsize = 3;
+ break;
+
+ case HGPK_MODE_GLIDESENSOR:
+ case HGPK_MODE_PENTABLET:
+ psmouse->pktsize = 6;
+
+ /* Switch to 'Advanced mode.', four disables in a row. */
+ for (i = 0; i < ARRAY_SIZE(advanced_init); i++)
+ if (ps2_command(ps2dev, NULL, advanced_init[i]))
+ return -EIO;
+
+ /* select between GlideSensor (mouse) or PenTablet */
+ cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?
+ PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;
+
+ if (ps2_command(ps2dev, NULL, cmd))
+ return -EIO;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void hgpk_setup_input_device(struct input_dev *input,
+ struct input_dev *old_input,
+ enum hgpk_mode mode)
+{
+ if (old_input) {
+ input->name = old_input->name;
+ input->phys = old_input->phys;
+ input->id = old_input->id;
+ input->dev.parent = old_input->dev.parent;
+ }
+
+ memset(input->evbit, 0, sizeof(input->evbit));
+ memset(input->relbit, 0, sizeof(input->relbit));
+ memset(input->keybit, 0, sizeof(input->keybit));
+
+ /* All modes report left and right buttons */
+ __set_bit(EV_KEY, input->evbit);
+ __set_bit(BTN_LEFT, input->keybit);
+ __set_bit(BTN_RIGHT, input->keybit);
+
+ switch (mode) {
+ case HGPK_MODE_MOUSE:
+ __set_bit(EV_REL, input->evbit);
+ __set_bit(REL_X, input->relbit);
+ __set_bit(REL_Y, input->relbit);
+ break;
+
+ case HGPK_MODE_GLIDESENSOR:
+ __set_bit(BTN_TOUCH, input->keybit);
+ __set_bit(BTN_TOOL_FINGER, input->keybit);
+
+ __set_bit(EV_ABS, input->evbit);
+
+ /* GlideSensor has pressure sensor, PenTablet does not */
+ input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);
+
+ /* From device specs */
+ input_set_abs_params(input, ABS_X, 0, 399, 0, 0);
+ input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);
+
+ /* Calculated by hand based on usable size (52mm x 38mm) */
+ input_abs_set_res(input, ABS_X, 8);
+ input_abs_set_res(input, ABS_Y, 8);
+ break;
+
+ case HGPK_MODE_PENTABLET:
+ __set_bit(BTN_TOUCH, input->keybit);
+ __set_bit(BTN_TOOL_FINGER, input->keybit);
+
+ __set_bit(EV_ABS, input->evbit);
+
+ /* From device specs */
+ input_set_abs_params(input, ABS_X, 0, 999, 0, 0);
+ input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);
+
+ /* Calculated by hand based on usable size (156mm x 38mm) */
+ input_abs_set_res(input, ABS_X, 6);
+ input_abs_set_res(input, ABS_Y, 8);
+ break;
+
+ default:
+ BUG();
+ }
+}
+
+static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
+{
+ int err;
+
+ psmouse_reset(psmouse);
+
+ if (recalibrate) {
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+ /* send the recalibrate request */
+ if (ps2_command(ps2dev, NULL, 0xf5) ||
+ ps2_command(ps2dev, NULL, 0xf5) ||
+ ps2_command(ps2dev, NULL, 0xe6) ||
+ ps2_command(ps2dev, NULL, 0xf5)) {
+ return -1;
+ }
+
+ /* according to ALPS, 150mS is required for recalibration */
+ msleep(150);
+ }
+
+ err = hgpk_select_mode(psmouse);
+ if (err) {
+ hgpk_err(psmouse, "failed to select mode\n");
+ return err;
+ }
+
+ hgpk_reset_hack_state(psmouse);
+
+ return 0;
+}
+
static int hgpk_force_recalibrate(struct psmouse *psmouse)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
struct hgpk_data *priv = psmouse->private;
+ int err;
/* C-series touchpads added the recalibrate command */
if (psmouse->model < HGPK_MODEL_C)
return 0;
+ if (!autorecal) {
+ hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n");
+ return 0;
+ }
+
+ hgpk_dbg(psmouse, "recalibrating touchpad..\n");
+
/* we don't want to race with the irq handler, nor with resyncs */
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
/* start by resetting the device */
- psmouse_reset(psmouse);
-
- /* send the recalibrate request */
- if (ps2_command(ps2dev, NULL, 0xf5) ||
- ps2_command(ps2dev, NULL, 0xf5) ||
- ps2_command(ps2dev, NULL, 0xe6) ||
- ps2_command(ps2dev, NULL, 0xf5)) {
- return -1;
- }
-
- /* according to ALPS, 150mS is required for recalibration */
- msleep(150);
+ err = hgpk_reset_device(psmouse, true);
+ if (err)
+ return err;
- /* XXX: If a finger is down during this delay, recalibration will
+ /*
+ * XXX: If a finger is down during this delay, recalibration will
* detect capacitance incorrectly. This is a hardware bug, and
* we don't have a good way to deal with it. The 2s window stuff
* (below) is our best option for now.
@@ -247,25 +673,35 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse)
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
- /* After we recalibrate, we shouldn't get any packets for 2s. If
- * we do, it's likely that someone's finger was on the touchpad.
- * If someone's finger *was* on the touchpad, it's probably
- * miscalibrated. So, we should schedule another recalibration
+ if (tpdebug)
+ hgpk_dbg(psmouse, "touchpad reactivated\n");
+
+ /*
+ * If we get packets right away after recalibrating, it's likely
+ * that a finger was on the touchpad. If so, it's probably
+ * miscalibrated, so we optionally schedule another.
*/
- priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time);
+ if (recal_guard_time)
+ priv->recalib_window = jiffies +
+ msecs_to_jiffies(recal_guard_time);
return 0;
}
/*
- * This kills power to the touchpad; according to ALPS, current consumption
- * goes down to 50uA after running this. To turn power back on, we drive
- * MS-DAT low.
+ * This puts the touchpad in a power saving mode; according to ALPS, current
+ * consumption goes down to 50uA after running this. To turn power back on,
+ * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that
+ * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this.
+ *
+ * We have no formal spec that details this operation -- the low-power
+ * sequence came from a long-lost email trail.
*/
-static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
+static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
int timeo;
+ int err;
/* Added on D-series touchpads */
if (psmouse->model < HGPK_MODEL_D)
@@ -279,24 +715,27 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
* the controller. Once we get an ACK back from it, it
* means we can continue with the touchpad re-init. ALPS
* tells us that 1s should be long enough, so set that as
- * the upper bound.
+ * the upper bound. (in practice, it takes about 3 loops.)
*/
for (timeo = 20; timeo > 0; timeo--) {
if (!ps2_sendbyte(&psmouse->ps2dev,
PSMOUSE_CMD_DISABLE, 20))
break;
- msleep(50);
+ msleep(25);
}
- psmouse_reset(psmouse);
+ err = hgpk_reset_device(psmouse, false);
+ if (err) {
+ hgpk_err(psmouse, "Failed to reset device!\n");
+ return err;
+ }
/* should be all set, enable the touchpad */
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
-
+ hgpk_dbg(psmouse, "Touchpad powered up.\n");
} else {
hgpk_dbg(psmouse, "Powering off touchpad.\n");
- psmouse_set_state(psmouse, PSMOUSE_IGNORE);
if (ps2_command(ps2dev, NULL, 0xec) ||
ps2_command(ps2dev, NULL, 0xec) ||
@@ -304,6 +743,8 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
return -1;
}
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+
/* probably won't see an ACK, the touchpad will be off */
ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
}
@@ -319,17 +760,20 @@ static int hgpk_poll(struct psmouse *psmouse)
static int hgpk_reconnect(struct psmouse *psmouse)
{
- /* During suspend/resume the ps2 rails remain powered. We don't want
+ struct hgpk_data *priv = psmouse->private;
+
+ /*
+ * During suspend/resume the ps2 rails remain powered. We don't want
* to do a reset because it's flush data out of buffers; however,
- * earlier prototypes (B1) had some brokenness that required a reset. */
+ * earlier prototypes (B1) had some brokenness that required a reset.
+ */
if (olpc_board_at_least(olpc_board(0xb2)))
if (psmouse->ps2dev.serio->dev.power.power_state.event !=
PM_EVENT_ON)
return 0;
- psmouse_reset(psmouse);
-
- return 0;
+ priv->powered = 1;
+ return hgpk_reset_device(psmouse, false);
}
static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
@@ -355,7 +799,7 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
* hgpk_toggle_power will deal w/ state so
* we're not racing w/ irq
*/
- err = hgpk_toggle_power(psmouse, value);
+ err = hgpk_toggle_powersave(psmouse, value);
if (!err)
priv->powered = value;
}
@@ -366,6 +810,65 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
hgpk_show_powered, hgpk_set_powered, false);
+static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);
+}
+
+static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,
+ const char *buf, size_t len)
+{
+ struct hgpk_data *priv = psmouse->private;
+ enum hgpk_mode old_mode = priv->mode;
+ enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);
+ struct input_dev *old_dev = psmouse->dev;
+ struct input_dev *new_dev;
+ int err;
+
+ if (new_mode == HGPK_MODE_INVALID)
+ return -EINVAL;
+
+ if (old_mode == new_mode)
+ return len;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
+ return -ENOMEM;
+
+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+ /* Switch device into the new mode */
+ priv->mode = new_mode;
+ err = hgpk_reset_device(psmouse, false);
+ if (err)
+ goto err_try_restore;
+
+ hgpk_setup_input_device(new_dev, old_dev, new_mode);
+
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+
+ err = input_register_device(new_dev);
+ if (err)
+ goto err_try_restore;
+
+ psmouse->dev = new_dev;
+ input_unregister_device(old_dev);
+
+ return len;
+
+err_try_restore:
+ input_free_device(new_dev);
+ priv->mode = old_mode;
+ hgpk_reset_device(psmouse, false);
+
+ return err;
+}
+
+PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,
+ attr_show_mode, attr_set_mode);
+
static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
void *data, char *buf)
{
@@ -401,6 +904,8 @@ static void hgpk_disconnect(struct psmouse *psmouse)
device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_hgpk_mode.dattr);
if (psmouse->model >= HGPK_MODEL_C)
device_remove_file(&psmouse->ps2dev.serio->dev,
@@ -416,14 +921,13 @@ static void hgpk_recalib_work(struct work_struct *work)
struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
struct psmouse *psmouse = priv->psmouse;
- hgpk_dbg(psmouse, "recalibrating touchpad..\n");
-
if (hgpk_force_recalibrate(psmouse))
hgpk_err(psmouse, "recalibration failed!\n");
}
static int hgpk_register(struct psmouse *psmouse)
{
+ struct hgpk_data *priv = psmouse->private;
int err;
/* register handlers */
@@ -431,13 +935,14 @@ static int hgpk_register(struct psmouse *psmouse)
psmouse->poll = hgpk_poll;
psmouse->disconnect = hgpk_disconnect;
psmouse->reconnect = hgpk_reconnect;
- psmouse->pktsize = 3;
/* Disable the idle resync. */
psmouse->resync_time = 0;
/* Reset after a lot of bad bytes. */
psmouse->resetafter = 1024;
+ hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);
+
err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
if (err) {
@@ -445,6 +950,13 @@ static int hgpk_register(struct psmouse *psmouse)
return err;
}
+ err = device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_hgpk_mode.dattr);
+ if (err) {
+ hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n");
+ goto err_remove_powered;
+ }
+
/* C-series touchpads added the recalibrate command */
if (psmouse->model >= HGPK_MODEL_C) {
err = device_create_file(&psmouse->ps2dev.serio->dev,
@@ -452,30 +964,40 @@ static int hgpk_register(struct psmouse *psmouse)
if (err) {
hgpk_err(psmouse,
"Failed creating 'recalibrate' sysfs node\n");
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_powered.dattr);
- return err;
+ goto err_remove_mode;
}
}
return 0;
+
+err_remove_mode:
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_hgpk_mode.dattr);
+err_remove_powered:
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_powered.dattr);
+ return err;
}
int hgpk_init(struct psmouse *psmouse)
{
struct hgpk_data *priv;
- int err = -ENOMEM;
+ int err;
priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
- if (!priv)
+ if (!priv) {
+ err = -ENOMEM;
goto alloc_fail;
+ }
psmouse->private = priv;
+
priv->psmouse = psmouse;
priv->powered = true;
+ priv->mode = hgpk_default_mode;
INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
- err = psmouse_reset(psmouse);
+ err = hgpk_reset_device(psmouse, false);
if (err)
goto init_fail;
@@ -531,3 +1053,14 @@ int hgpk_detect(struct psmouse *psmouse, bool set_properties)
return 0;
}
+
+void hgpk_module_init(void)
+{
+ hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,
+ strlen(hgpk_mode_name));
+ if (hgpk_default_mode == HGPK_MODE_INVALID) {
+ hgpk_default_mode = HGPK_MODE_MOUSE;
+ strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],
+ sizeof(hgpk_mode_name));
+ }
+}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
index d61cfd3ee9cb..311c0e87fcbf 100644
--- a/drivers/input/mouse/hgpk.h
+++ b/drivers/input/mouse/hgpk.h
@@ -5,6 +5,9 @@
#ifndef _HGPK_H
#define _HGPK_H
+#define HGPK_GS 0xff /* The GlideSensor */
+#define HGPK_PT 0xcf /* The PenTablet */
+
enum hgpk_model_t {
HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
@@ -13,12 +16,34 @@ enum hgpk_model_t {
HGPK_MODEL_D = 0x50, /* C1, mass production */
};
+enum hgpk_spew_flag {
+ NO_SPEW,
+ MAYBE_SPEWING,
+ SPEW_DETECTED,
+ RECALIBRATING,
+};
+
+#define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */
+
+enum hgpk_mode {
+ HGPK_MODE_MOUSE,
+ HGPK_MODE_GLIDESENSOR,
+ HGPK_MODE_PENTABLET,
+ HGPK_MODE_INVALID
+};
+
struct hgpk_data {
struct psmouse *psmouse;
+ enum hgpk_mode mode;
bool powered;
- int count, x_tally, y_tally; /* hardware workaround stuff */
+ enum hgpk_spew_flag spew_flag;
+ int spew_count, x_tally, y_tally; /* spew detection */
unsigned long recalib_window;
struct delayed_work recalib_wq;
+ int abs_x, abs_y;
+ int dupe_count;
+ int xbigj, ybigj, xlast, ylast; /* jumpiness detection */
+ int xsaw_secondary, ysaw_secondary; /* jumpiness detection */
};
#define hgpk_dbg(psmouse, format, arg...) \
@@ -33,9 +58,13 @@ struct hgpk_data {
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC
+void hgpk_module_init(void);
int hgpk_detect(struct psmouse *psmouse, bool set_properties);
int hgpk_init(struct psmouse *psmouse);
#else
+static inline void hgpk_module_init(void)
+{
+}
static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENODEV;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index cd9d0c97e429..3f74baee102b 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -1711,6 +1711,7 @@ static int __init psmouse_init(void)
lifebook_module_init();
synaptics_module_init();
+ hgpk_module_init();
kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
if (!kpsmoused_wq) {
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 2e300a460556..da392c22fc6c 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/dmi.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/serio.h>
#include <linux/libps2.h>
#include <linux/slab.h>
@@ -279,6 +279,25 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
synaptics_mode_cmd(psmouse, priv->mode);
}
+static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
+{
+ static unsigned char param = 0xc8;
+ struct synaptics_data *priv = psmouse->private;
+
+ if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
+ return 0;
+
+ if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
+ return -1;
+ if (ps2_command(&psmouse->ps2dev, &param, PSMOUSE_CMD_SETRATE))
+ return -1;
+
+ /* Advanced gesture mode also sends multi finger data */
+ priv->capabilities |= BIT(1);
+
+ return 0;
+}
+
/*****************************************************************************
* Synaptics pass-through PS/2 port support
****************************************************************************/
@@ -380,7 +399,9 @@ static void synaptics_pt_create(struct psmouse *psmouse)
* Functions to interpret the absolute mode packets
****************************************************************************/
-static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
+static int synaptics_parse_hw_state(const unsigned char buf[],
+ struct synaptics_data *priv,
+ struct synaptics_hw_state *hw)
{
memset(hw, 0, sizeof(struct synaptics_hw_state));
@@ -397,6 +418,14 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
((buf[0] & 0x04) >> 1) |
((buf[3] & 0x04) >> 2));
+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) {
+ /* Gesture packet: (x, y, z) at half resolution */
+ priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
+ priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
+ priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
+ return 1;
+ }
+
hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0;
@@ -452,6 +481,36 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0;
}
+
+ return 0;
+}
+
+static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y)
+{
+ input_mt_slot(dev, slot);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
+ if (active) {
+ input_report_abs(dev, ABS_MT_POSITION_X, x);
+ input_report_abs(dev, ABS_MT_POSITION_Y,
+ YMAX_NOMINAL + YMIN_NOMINAL - y);
+ }
+}
+
+static void synaptics_report_semi_mt_data(struct input_dev *dev,
+ const struct synaptics_hw_state *a,
+ const struct synaptics_hw_state *b,
+ int num_fingers)
+{
+ if (num_fingers >= 2) {
+ set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y));
+ set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y));
+ } else if (num_fingers == 1) {
+ set_slot(dev, 0, true, a->x, a->y);
+ set_slot(dev, 1, false, 0, 0);
+ } else {
+ set_slot(dev, 0, false, 0, 0);
+ set_slot(dev, 1, false, 0, 0);
+ }
}
/*
@@ -466,7 +525,8 @@ static void synaptics_process_packet(struct psmouse *psmouse)
int finger_width;
int i;
- synaptics_parse_hw_state(psmouse->packet, priv, &hw);
+ if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
+ return;
if (hw.scroll) {
priv->scroll += hw.scroll;
@@ -488,7 +548,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
return;
}
- if (hw.z > 0) {
+ if (hw.z > 0 && hw.x > 1) {
num_fingers = 1;
finger_width = 5;
if (SYN_CAP_EXTENDED(priv->capabilities)) {
@@ -512,6 +572,9 @@ static void synaptics_process_packet(struct psmouse *psmouse)
finger_width = 0;
}
+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
+ synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers);
+
/* Post events
* BTN_TOUCH has to be first as mousedev relies on it when doing
* absolute -> relative conversion
@@ -519,7 +582,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
- if (hw.z > 0) {
+ if (num_fingers > 0) {
input_report_abs(dev, ABS_X, hw.x);
input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
}
@@ -622,6 +685,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
{
int i;
+ __set_bit(INPUT_PROP_POINTER, dev->propbit);
+
__set_bit(EV_ABS, dev->evbit);
input_set_abs_params(dev, ABS_X,
XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0);
@@ -629,6 +694,15 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
+ __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
+ input_mt_init_slots(dev, 2);
+ input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL,
+ priv->x_max ?: XMAX_NOMINAL, 0, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL,
+ priv->y_max ?: YMAX_NOMINAL, 0, 0);
+ }
+
if (SYN_CAP_PALMDETECT(priv->capabilities))
input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
@@ -663,6 +737,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
input_abs_set_res(dev, ABS_Y, priv->y_res);
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
/* Clickpads report only left button */
__clear_bit(BTN_RIGHT, dev->keybit);
__clear_bit(BTN_MIDDLE, dev->keybit);
@@ -702,6 +777,11 @@ static int synaptics_reconnect(struct psmouse *psmouse)
return -1;
}
+ if (synaptics_set_advanced_gesture_mode(psmouse)) {
+ printk(KERN_ERR "Advanced gesture mode reconnect failed.\n");
+ return -1;
+ }
+
return 0;
}
@@ -744,15 +824,45 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
#endif
};
+static bool broken_olpc_ec;
+
+static const struct dmi_system_id __initconst olpc_dmi_table[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_OLPC)
+ {
+ /* OLPC XO-1 or XO-1.5 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "XO"),
+ },
+ },
+ { }
+#endif
+};
+
void __init synaptics_module_init(void)
{
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
+ broken_olpc_ec = dmi_check_system(olpc_dmi_table);
}
int synaptics_init(struct psmouse *psmouse)
{
struct synaptics_data *priv;
+ /*
+ * The OLPC XO has issues with Synaptics' absolute mode; similarly to
+ * the HGPK, it quickly degrades and the hardware becomes jumpy and
+ * overly sensitive. Not only that, but the constant packet spew
+ * (even at a lowered 40pps rate) overloads the EC such that key
+ * presses on the keyboard are missed. Given all of that, don't
+ * even attempt to use Synaptics mode. Relative mode seems to work
+ * just fine.
+ */
+ if (broken_olpc_ec) {
+ printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n");
+ return -ENODEV;
+ }
+
psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -769,6 +879,11 @@ int synaptics_init(struct psmouse *psmouse)
goto init_fail;
}
+ if (synaptics_set_advanced_gesture_mode(psmouse)) {
+ printk(KERN_ERR "Advanced gesture mode init failed.\n");
+ goto init_fail;
+ }
+
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
@@ -802,8 +917,8 @@ int synaptics_init(struct psmouse *psmouse)
/*
* Toshiba's KBC seems to have trouble handling data from
- * Synaptics as full rate, switch to lower rate which is roughly
- * thye same as rate of standard PS/2 mouse.
+ * Synaptics at full rate. Switch to a lower rate (roughly
+ * the same rate as a standard PS/2 mouse).
*/
if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 613a3652f98f..25e5d042a72c 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -51,8 +51,10 @@
#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
#define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16)
-#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100)
+#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
+#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */
#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000)
+#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
/* synaptics modes query bits */
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
@@ -112,6 +114,8 @@ struct synaptics_data {
int scroll;
struct serio *pt_port; /* Pass-through serio port */
+
+ struct synaptics_hw_state mt; /* current gesture packet */
};
void synaptics_module_init(void);
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 2a00ddf4f23a..7630273e9474 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -9,6 +9,8 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define MOUSEDEV_MINOR_BASE 32
#define MOUSEDEV_MINORS 32
#define MOUSEDEV_MIX 31
@@ -977,7 +979,7 @@ static int mousedev_connect(struct input_handler *handler,
break;
if (minor == MOUSEDEV_MINORS) {
- printk(KERN_ERR "mousedev: no more free mousedev devices\n");
+ pr_err("no more free mousedev devices\n");
return -ENFILE;
}
@@ -1087,13 +1089,13 @@ static int __init mousedev_init(void)
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
error = misc_register(&psaux_mouse);
if (error)
- printk(KERN_WARNING "mice: could not register psaux device, "
- "error: %d\n", error);
+ pr_warning("could not register psaux device, error: %d\n",
+ error);
else
psaux_registered = 1;
#endif
- printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
+ pr_info("PS/2 mouse device common for all mice\n");
return 0;
}
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 6256233d2bfb..bcb1fdedb595 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -214,7 +214,6 @@ config SERIO_AMS_DELTA
tristate "Amstrad Delta (E3) mailboard support"
depends on MACH_AMS_DELTA
default y
- select AMS_DELTA_FIQ
---help---
Say Y here if you have an E3 and want to use its mailboard,
or any standard AT keyboard connected to the mailboard port.
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 8f1770e1e08b..ebe955325677 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -172,6 +172,5 @@ static void __exit ams_delta_serio_exit(void)
free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0);
gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK);
gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA);
- kfree(ams_delta_serio);
}
module_exit(ams_delta_serio_exit);
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index 4a3084695c00..448c7724beb9 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -191,6 +191,9 @@ static int __devinit ct82c710_probe(struct platform_device *dev)
serio_register_port(ct82c710_port);
+ printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n",
+ (unsigned long long)CT82C710_DATA, CT82C710_IRQ);
+
return 0;
}
@@ -237,11 +240,6 @@ static int __init ct82c710_init(void)
if (error)
goto err_free_device;
- serio_register_port(ct82c710_port);
-
- printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n",
- (unsigned long long)CT82C710_DATA, CT82C710_IRQ);
-
return 0;
err_free_device:
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 3c287dd879d3..4225f5d6b15f 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev)
gscps2_reset(ps2port);
ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
- snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
+ snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->id.type = SERIO_8042;
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index e5624d8f1709..bfd3865d886b 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -932,6 +932,11 @@ int hil_mlc_register(hil_mlc *mlc)
hil_mlc_copy_di_scratch(mlc, i);
mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL);
mlc->serio[i] = mlc_serio;
+ if (!mlc->serio[i]) {
+ for (; i >= 0; i--)
+ kfree(mlc->serio[i]);
+ return -ENOMEM;
+ }
snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i);
snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i);
mlc_serio->id = hil_mlc_serio_id;
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index 7d2b820ef58d..d50f0678bf47 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -305,6 +305,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc)
static int __init hp_sdc_mlc_init(void)
{
hil_mlc *mlc = &hp_sdc_mlc;
+ int err;
#ifdef __mc68000__
if (!MACH_IS_HP300)
@@ -323,22 +324,21 @@ static int __init hp_sdc_mlc_init(void)
mlc->out = &hp_sdc_mlc_out;
mlc->priv = &hp_sdc_mlc_priv;
- if (hil_mlc_register(mlc)) {
+ err = hil_mlc_register(mlc);
+ if (err) {
printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");
- goto err0;
+ return err;
}
if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) {
printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n");
- goto err1;
+ if (hil_mlc_unregister(mlc))
+ printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
+ "This is bad. Could cause an oops.\n");
+ return -EBUSY;
}
+
return 0;
- err1:
- if (hil_mlc_unregister(mlc))
- printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
- "This is bad. Could cause an oops.\n");
- err0:
- return -EBUSY;
}
static void __exit hp_sdc_mlc_exit(void)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index a5475b577086..5ae0fc4578fe 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -553,6 +553,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
*/
static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
{
+ /* Acer Aspire 5100 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
+ },
+ },
+ {
/* Acer Aspire 5610 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -752,7 +759,7 @@ static int __init i8042_pnp_init(void)
#endif
if (i8042_nopnp) {
- printk(KERN_INFO "i8042: PNP detection disabled\n");
+ pr_info("PNP detection disabled\n");
return 0;
}
@@ -769,7 +776,7 @@ static int __init i8042_pnp_init(void)
#if defined(__ia64__)
return -ENODEV;
#else
- printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n");
+ pr_info("PNP: No PS/2 controller found. Probing ports directly.\n");
return 0;
#endif
}
@@ -781,7 +788,7 @@ static int __init i8042_pnp_init(void)
snprintf(aux_irq_str, sizeof(aux_irq_str),
"%d", i8042_pnp_aux_irq);
- printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
+ pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
i8042_pnp_aux_name,
i8042_pnp_data_reg, i8042_pnp_command_reg,
@@ -798,9 +805,7 @@ static int __init i8042_pnp_init(void)
if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
i8042_pnp_data_reg != i8042_data_reg) ||
!i8042_pnp_data_reg) {
- printk(KERN_WARNING
- "PNP: PS/2 controller has invalid data port %#x; "
- "using default %#x\n",
+ pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
i8042_pnp_data_reg, i8042_data_reg);
i8042_pnp_data_reg = i8042_data_reg;
pnp_data_busted = true;
@@ -809,33 +814,27 @@ static int __init i8042_pnp_init(void)
if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
i8042_pnp_command_reg != i8042_command_reg) ||
!i8042_pnp_command_reg) {
- printk(KERN_WARNING
- "PNP: PS/2 controller has invalid command port %#x; "
- "using default %#x\n",
+ pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
i8042_pnp_command_reg, i8042_command_reg);
i8042_pnp_command_reg = i8042_command_reg;
pnp_data_busted = true;
}
if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
- printk(KERN_WARNING
- "PNP: PS/2 controller doesn't have KBD irq; "
- "using default %d\n", i8042_kbd_irq);
+ pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
+ i8042_kbd_irq);
i8042_pnp_kbd_irq = i8042_kbd_irq;
pnp_data_busted = true;
}
if (!i8042_noaux && !i8042_pnp_aux_irq) {
if (!pnp_data_busted && i8042_pnp_kbd_irq) {
- printk(KERN_WARNING
- "PNP: PS/2 appears to have AUX port disabled, "
- "if this is incorrect please boot with "
- "i8042.nopnp\n");
+ pr_warn("PNP: PS/2 appears to have AUX port disabled, "
+ "if this is incorrect please boot with i8042.nopnp\n");
i8042_noaux = true;
} else {
- printk(KERN_WARNING
- "PNP: PS/2 controller doesn't have AUX irq; "
- "using default %d\n", i8042_aux_irq);
+ pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
+ i8042_aux_irq);
i8042_pnp_aux_irq = i8042_aux_irq;
}
}
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 18db5a8c7478..c04ff00a3663 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -10,6 +10,8 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
@@ -225,8 +227,8 @@ static int i8042_flush(void)
udelay(50);
data = i8042_read_data();
i++;
- dbg("%02x <- i8042 (flush, %s)", data,
- str & I8042_STR_AUXDATA ? "aux" : "kbd");
+ dbg("%02x <- i8042 (flush, %s)\n",
+ data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
}
spin_unlock_irqrestore(&i8042_lock, flags);
@@ -253,32 +255,32 @@ static int __i8042_command(unsigned char *param, int command)
if (error)
return error;
- dbg("%02x -> i8042 (command)", command & 0xff);
+ dbg("%02x -> i8042 (command)\n", command & 0xff);
i8042_write_command(command & 0xff);
for (i = 0; i < ((command >> 12) & 0xf); i++) {
error = i8042_wait_write();
if (error)
return error;
- dbg("%02x -> i8042 (parameter)", param[i]);
+ dbg("%02x -> i8042 (parameter)\n", param[i]);
i8042_write_data(param[i]);
}
for (i = 0; i < ((command >> 8) & 0xf); i++) {
error = i8042_wait_read();
if (error) {
- dbg(" -- i8042 (timeout)");
+ dbg(" -- i8042 (timeout)\n");
return error;
}
if (command == I8042_CMD_AUX_LOOP &&
!(i8042_read_status() & I8042_STR_AUXDATA)) {
- dbg(" -- i8042 (auxerr)");
+ dbg(" -- i8042 (auxerr)\n");
return -1;
}
param[i] = i8042_read_data();
- dbg("%02x <- i8042 (return)", param[i]);
+ dbg("%02x <- i8042 (return)\n", param[i]);
}
return 0;
@@ -309,7 +311,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c)
spin_lock_irqsave(&i8042_lock, flags);
if (!(retval = i8042_wait_write())) {
- dbg("%02x -> i8042 (kbd-data)", c);
+ dbg("%02x -> i8042 (kbd-data)\n", c);
i8042_write_data(c);
}
@@ -355,17 +357,14 @@ static void i8042_port_close(struct serio *serio)
i8042_ctr &= ~irq_bit;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
- printk(KERN_WARNING
- "i8042.c: Can't write CTR while closing %s port.\n",
- port_name);
+ pr_warn("Can't write CTR while closing %s port\n", port_name);
udelay(50);
i8042_ctr &= ~disable_bit;
i8042_ctr |= irq_bit;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
- printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n",
- port_name);
+ pr_err("Can't reactivate %s port\n", port_name);
/*
* See if there is any data appeared while we were messing with
@@ -456,7 +455,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
str = i8042_read_status();
if (unlikely(~str & I8042_STR_OBF)) {
spin_unlock_irqrestore(&i8042_lock, flags);
- if (irq) dbg("Interrupt %d, without any data", irq);
+ if (irq)
+ dbg("Interrupt %d, without any data\n", irq);
ret = 0;
goto out;
}
@@ -469,7 +469,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
dfl = 0;
if (str & I8042_STR_MUXERR) {
- dbg("MUX error, status is %02x, data is %02x", str, data);
+ dbg("MUX error, status is %02x, data is %02x\n",
+ str, data);
/*
* When MUXERR condition is signalled the data register can only contain
* 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
@@ -512,7 +513,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
port = &i8042_ports[port_no];
serio = port->exists ? port->serio : NULL;
- dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",
+ dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n",
data, port_no, irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
@@ -540,7 +541,7 @@ static int i8042_enable_kbd_port(void)
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
i8042_ctr &= ~I8042_CTR_KBDINT;
i8042_ctr |= I8042_CTR_KBDDIS;
- printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");
+ pr_err("Failed to enable KBD port\n");
return -EIO;
}
@@ -559,7 +560,7 @@ static int i8042_enable_aux_port(void)
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
i8042_ctr &= ~I8042_CTR_AUXINT;
i8042_ctr |= I8042_CTR_AUXDIS;
- printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");
+ pr_err("Failed to enable AUX port\n");
return -EIO;
}
@@ -641,7 +642,7 @@ static int __init i8042_check_mux(void)
if (i8042_set_mux_mode(true, &mux_version))
return -1;
- printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
+ pr_info("Detected active multiplexing controller, rev %d.%d\n",
(mux_version >> 4) & 0xf, mux_version & 0xf);
/*
@@ -651,7 +652,7 @@ static int __init i8042_check_mux(void)
i8042_ctr &= ~I8042_CTR_AUXINT;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
+ pr_err("Failed to disable AUX port, can't use MUX\n");
return -EIO;
}
@@ -676,8 +677,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
str = i8042_read_status();
if (str & I8042_STR_OBF) {
data = i8042_read_data();
- dbg("%02x <- i8042 (aux_test_irq, %s)",
- data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
+ dbg("%02x <- i8042 (aux_test_irq, %s)\n",
+ data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
if (i8042_irq_being_tested &&
data == 0xa5 && (str & I8042_STR_AUXDATA))
complete(&i8042_aux_irq_delivered);
@@ -770,8 +771,8 @@ static int __init i8042_check_aux(void)
*/
if (i8042_toggle_aux(false)) {
- printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
- printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
+ pr_warn("Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
+ pr_warn("If AUX port is really absent please use the 'i8042.noaux' option\n");
}
if (i8042_toggle_aux(true))
@@ -819,7 +820,7 @@ static int __init i8042_check_aux(void)
* AUX IRQ was never delivered so we need to flush the controller to
* get rid of the byte we put there; otherwise keyboard may not work.
*/
- dbg(" -- i8042 (aux irq test timeout)");
+ dbg(" -- i8042 (aux irq test timeout)\n");
i8042_flush();
retval = -1;
}
@@ -845,7 +846,7 @@ static int __init i8042_check_aux(void)
static int i8042_controller_check(void)
{
if (i8042_flush() == I8042_BUFFER_SIZE) {
- printk(KERN_ERR "i8042.c: No controller found.\n");
+ pr_err("No controller found\n");
return -ENODEV;
}
@@ -864,15 +865,15 @@ static int i8042_controller_selftest(void)
do {
if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
- printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+ pr_err("i8042 controller self test timeout\n");
return -ENODEV;
}
if (param == I8042_RET_CTL_TEST)
return 0;
- printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
- param, I8042_RET_CTL_TEST);
+ pr_err("i8042 controller selftest failed. (%#x != %#x)\n",
+ param, I8042_RET_CTL_TEST);
msleep(50);
} while (i++ < 5);
@@ -883,8 +884,7 @@ static int i8042_controller_selftest(void)
* and user will still get a working keyboard. This is especially
* important on netbooks. On other arches we trust hardware more.
*/
- printk(KERN_INFO
- "i8042: giving up on controller selftest, continuing anyway...\n");
+ pr_info("giving up on controller selftest, continuing anyway...\n");
return 0;
#else
return -EIO;
@@ -909,8 +909,7 @@ static int i8042_controller_init(void)
do {
if (n >= 10) {
- printk(KERN_ERR
- "i8042.c: Unable to get stable CTR read.\n");
+ pr_err("Unable to get stable CTR read\n");
return -EIO;
}
@@ -918,8 +917,7 @@ static int i8042_controller_init(void)
udelay(50);
if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
- printk(KERN_ERR
- "i8042.c: Can't read CTR while initializing i8042.\n");
+ pr_err("Can't read CTR while initializing i8042\n");
return -EIO;
}
@@ -943,7 +941,7 @@ static int i8042_controller_init(void)
if (i8042_unlock)
i8042_ctr |= I8042_CTR_IGNKEYLOCK;
else
- printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
+ pr_warn("Warning: Keylock active\n");
}
spin_unlock_irqrestore(&i8042_lock, flags);
@@ -970,7 +968,7 @@ static int i8042_controller_init(void)
*/
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
+ pr_err("Can't write CTR while initializing i8042\n");
return -EIO;
}
@@ -1000,7 +998,7 @@ static void i8042_controller_reset(void)
i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
- printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");
+ pr_warn("Can't write CTR while resetting\n");
/*
* Disable MUX mode if present.
@@ -1021,7 +1019,7 @@ static void i8042_controller_reset(void)
*/
if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
- printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
+ pr_warn("Can't restore CTR\n");
}
@@ -1045,14 +1043,14 @@ static long i8042_panic_blink(int state)
led = (state) ? 0x01 | 0x04 : 0;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
- dbg("%02x -> i8042 (panic blink)", 0xed);
+ dbg("%02x -> i8042 (panic blink)\n", 0xed);
i8042_suppress_kbd_ack = 2;
i8042_write_data(0xed); /* set leds */
DELAY;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
DELAY;
- dbg("%02x -> i8042 (panic blink)", led);
+ dbg("%02x -> i8042 (panic blink)\n", led);
i8042_write_data(led);
DELAY;
return delay;
@@ -1068,9 +1066,7 @@ static void i8042_dritek_enable(void)
error = i8042_command(&param, 0x1059);
if (error)
- printk(KERN_WARNING
- "Failed to enable DRITEK extension: %d\n",
- error);
+ pr_warn("Failed to enable DRITEK extension: %d\n", error);
}
#endif
@@ -1105,10 +1101,10 @@ static int i8042_controller_resume(bool force_reset)
i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n");
+ pr_warn("Can't write CTR to resume, retrying...\n");
msleep(50);
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
- printk(KERN_ERR "i8042: CTR write retry failed\n");
+ pr_err("CTR write retry failed\n");
return -EIO;
}
}
@@ -1121,9 +1117,7 @@ static int i8042_controller_resume(bool force_reset)
if (i8042_mux_present) {
if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports())
- printk(KERN_WARNING
- "i8042: failed to resume active multiplexor, "
- "mouse won't work.\n");
+ pr_warn("failed to resume active multiplexor, mouse won't work\n");
} else if (i8042_ports[I8042_AUX_PORT_NO].serio)
i8042_enable_aux_port();
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index cbc1beb66574..ac1d759d0f55 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -89,15 +89,19 @@
#ifdef DEBUG
static unsigned long i8042_start_time;
#define dbg_init() do { i8042_start_time = jiffies; } while (0)
-#define dbg(format, arg...) \
- do { \
+#define dbg(format, arg...) \
+ do { \
if (i8042_debug) \
- printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \
- ## arg, (int) (jiffies - i8042_start_time)); \
+ printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \
+ (int) (jiffies - i8042_start_time), ##arg); \
} while (0)
#else
#define dbg_init() do { } while (0)
-#define dbg(format, arg...) do {} while (0)
+#define dbg(format, arg...) \
+ do { \
+ if (0) \
+ printk(KERN_DEBUG pr_fmt(format), ##arg); \
+ } while (0)
#endif
#endif /* _I8042_H */
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c
index 6bce22e4e495..15aa81c9f1fb 100644
--- a/drivers/input/serio/ps2mult.c
+++ b/drivers/input/serio/ps2mult.c
@@ -207,7 +207,7 @@ static int ps2mult_connect(struct serio *serio, struct serio_driver *drv)
err_out:
while (--i >= 0)
kfree(psm->ports[i].serio);
- kfree(serio);
+ kfree(psm);
return error;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 405bf214527c..db5b0bca1a1a 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -32,10 +32,9 @@
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/errno.h>
-#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/kthread.h>
+#include <linux/workqueue.h>
#include <linux/mutex.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
@@ -44,7 +43,7 @@ MODULE_LICENSE("GPL");
/*
* serio_mutex protects entire serio subsystem and is taken every time
- * serio port or driver registrered or unregistered.
+ * serio port or driver registered or unregistered.
*/
static DEFINE_MUTEX(serio_mutex);
@@ -165,58 +164,22 @@ struct serio_event {
static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */
static LIST_HEAD(serio_event_list);
-static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
-static struct task_struct *serio_task;
-static int serio_queue_event(void *object, struct module *owner,
- enum serio_event_type event_type)
+static struct serio_event *serio_get_event(void)
{
+ struct serio_event *event = NULL;
unsigned long flags;
- struct serio_event *event;
- int retval = 0;
spin_lock_irqsave(&serio_event_lock, flags);
- /*
- * Scan event list for the other events for the same serio port,
- * starting with the most recent one. If event is the same we
- * do not need add new one. If event is of different type we
- * need to add this event and should not look further because
- * we need to preseve sequence of distinct events.
- */
- list_for_each_entry_reverse(event, &serio_event_list, node) {
- if (event->object == object) {
- if (event->type == event_type)
- goto out;
- break;
- }
- }
-
- event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
- if (!event) {
- pr_err("Not enough memory to queue event %d\n", event_type);
- retval = -ENOMEM;
- goto out;
- }
-
- if (!try_module_get(owner)) {
- pr_warning("Can't get module reference, dropping event %d\n",
- event_type);
- kfree(event);
- retval = -EINVAL;
- goto out;
+ if (!list_empty(&serio_event_list)) {
+ event = list_first_entry(&serio_event_list,
+ struct serio_event, node);
+ list_del_init(&event->node);
}
- event->type = event_type;
- event->object = object;
- event->owner = owner;
-
- list_add_tail(&event->node, &serio_event_list);
- wake_up(&serio_wait);
-
-out:
spin_unlock_irqrestore(&serio_event_lock, flags);
- return retval;
+ return event;
}
static void serio_free_event(struct serio_event *event)
@@ -250,25 +213,7 @@ static void serio_remove_duplicate_events(struct serio_event *event)
spin_unlock_irqrestore(&serio_event_lock, flags);
}
-
-static struct serio_event *serio_get_event(void)
-{
- struct serio_event *event = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&serio_event_lock, flags);
-
- if (!list_empty(&serio_event_list)) {
- event = list_first_entry(&serio_event_list,
- struct serio_event, node);
- list_del_init(&event->node);
- }
-
- spin_unlock_irqrestore(&serio_event_lock, flags);
- return event;
-}
-
-static void serio_handle_event(void)
+static void serio_handle_event(struct work_struct *work)
{
struct serio_event *event;
@@ -307,6 +252,59 @@ static void serio_handle_event(void)
mutex_unlock(&serio_mutex);
}
+static DECLARE_WORK(serio_event_work, serio_handle_event);
+
+static int serio_queue_event(void *object, struct module *owner,
+ enum serio_event_type event_type)
+{
+ unsigned long flags;
+ struct serio_event *event;
+ int retval = 0;
+
+ spin_lock_irqsave(&serio_event_lock, flags);
+
+ /*
+ * Scan event list for the other events for the same serio port,
+ * starting with the most recent one. If event is the same we
+ * do not need add new one. If event is of different type we
+ * need to add this event and should not look further because
+ * we need to preseve sequence of distinct events.
+ */
+ list_for_each_entry_reverse(event, &serio_event_list, node) {
+ if (event->object == object) {
+ if (event->type == event_type)
+ goto out;
+ break;
+ }
+ }
+
+ event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
+ if (!event) {
+ pr_err("Not enough memory to queue event %d\n", event_type);
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ if (!try_module_get(owner)) {
+ pr_warning("Can't get module reference, dropping event %d\n",
+ event_type);
+ kfree(event);
+ retval = -EINVAL;
+ goto out;
+ }
+
+ event->type = event_type;
+ event->object = object;
+ event->owner = owner;
+
+ list_add_tail(&event->node, &serio_event_list);
+ schedule_work(&serio_event_work);
+
+out:
+ spin_unlock_irqrestore(&serio_event_lock, flags);
+ return retval;
+}
+
/*
* Remove all events that have been submitted for a given
* object, be it serio port or driver.
@@ -356,18 +354,6 @@ static struct serio *serio_get_pending_child(struct serio *parent)
return child;
}
-static int serio_thread(void *nothing)
-{
- do {
- serio_handle_event();
- wait_event_interruptible(serio_wait,
- kthread_should_stop() || !list_empty(&serio_event_list));
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-
/*
* Serio port operations
*/
@@ -1040,21 +1026,18 @@ static int __init serio_init(void)
return error;
}
- serio_task = kthread_run(serio_thread, NULL, "kseriod");
- if (IS_ERR(serio_task)) {
- bus_unregister(&serio_bus);
- error = PTR_ERR(serio_task);
- pr_err("Failed to start kseriod, error: %d\n", error);
- return error;
- }
-
return 0;
}
static void __exit serio_exit(void)
{
bus_unregister(&serio_bus);
- kthread_stop(serio_task);
+
+ /*
+ * There should not be any outstanding events but work may
+ * still be scheduled so simply cancel it.
+ */
+ cancel_work_sync(&serio_event_work);
}
subsys_initcall(serio_init);
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index de5adb109030..23317bd09c82 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -103,6 +103,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
#define USB_VENDOR_ID_WACOM 0x056a
+#define USB_VENDOR_ID_LENOVO 0x17ef
struct wacom {
dma_addr_t data_dma;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index b3252ef1e279..518782999fea 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -14,6 +14,7 @@
#include "wacom_wac.h"
#include "wacom.h"
+#include <linux/input/mt.h>
static int wacom_penpartner_irq(struct wacom_wac *wacom)
{
@@ -862,19 +863,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
struct wacom_features *features = &wacom->features;
struct input_dev *input = wacom->input;
unsigned char *data = wacom->data;
- int sp = 0, sx = 0, sy = 0, count = 0;
int i;
for (i = 0; i < 2; i++) {
int p = data[9 * i + 2];
+ bool touch = p && !wacom->shared->stylus_in_proximity;
+
input_mt_slot(input, i);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
/*
* Touch events need to be disabled while stylus is
* in proximity because user's hand is resting on touchpad
* and sending unwanted events. User expects tablet buttons
* to continue working though.
*/
- if (p && !wacom->shared->stylus_in_proximity) {
+ if (touch) {
int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
@@ -884,23 +887,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
input_report_abs(input, ABS_MT_PRESSURE, p);
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
- if (wacom->id[i] < 0)
- wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
- if (!count++)
- sp = p, sx = x, sy = y;
- } else {
- wacom->id[i] = -1;
}
- input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
}
- input_report_key(input, BTN_TOUCH, count > 0);
- input_report_key(input, BTN_TOOL_FINGER, count == 1);
- input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
-
- input_report_abs(input, ABS_PRESSURE, sp);
- input_report_abs(input, ABS_X, sx);
- input_report_abs(input, ABS_Y, sy);
+ input_mt_report_pointer_emulation(input, true);
input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
@@ -1272,7 +1262,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
- input_mt_create_slots(input_dev, 2);
+ input_mt_init_slots(input_dev, 2);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
0, features->x_max,
features->x_fuzz, 0);
@@ -1282,8 +1272,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, features->pressure_max,
features->pressure_fuzz, 0);
- input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
- MAX_TRACKING_ID, 0, 0);
} else if (features->device_type == BTN_TOOL_PEN) {
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
@@ -1436,11 +1424,25 @@ static struct wacom_features wacom_features_0xD2 =
{ "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
static struct wacom_features wacom_features_0xD3 =
{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
+static const struct wacom_features wacom_features_0xD4 =
+ { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD8 =
+ { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDA =
+ { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDB =
+ { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
+static const struct wacom_features wacom_features_0x6004 =
+ { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC };
#define USB_DEVICE_WACOM(prod) \
USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \
.driver_info = (kernel_ulong_t)&wacom_features_##prod
+#define USB_DEVICE_LENOVO(prod) \
+ USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
+ .driver_info = (kernel_ulong_t)&wacom_features_##prod
+
const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x00) },
{ USB_DEVICE_WACOM(0x10) },
@@ -1504,6 +1506,10 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xD1) },
{ USB_DEVICE_WACOM(0xD2) },
{ USB_DEVICE_WACOM(0xD3) },
+ { USB_DEVICE_WACOM(0xD4) },
+ { USB_DEVICE_WACOM(0xD8) },
+ { USB_DEVICE_WACOM(0xDA) },
+ { USB_DEVICE_WACOM(0xDB) },
{ USB_DEVICE_WACOM(0xF0) },
{ USB_DEVICE_WACOM(0xCC) },
{ USB_DEVICE_WACOM(0x90) },
@@ -1513,6 +1519,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xE2) },
{ USB_DEVICE_WACOM(0xE3) },
{ USB_DEVICE_WACOM(0x47) },
+ { USB_DEVICE_LENOVO(0x6004) },
{ }
};
MODULE_DEVICE_TABLE(usb, wacom_ids);
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 00ca01541d89..b1310ec9720c 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -42,9 +42,6 @@
#define WACOM_QUIRK_MULTI_INPUT 0x0001
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
-/* largest reported tracking id */
-#define MAX_TRACKING_ID 0xfff
-
enum {
PENPARTNER = 0,
GRAPHIRE,
@@ -100,7 +97,6 @@ struct wacom_wac {
int id[3];
__u32 serial[2];
int last_finger;
- int trk_id;
struct wacom_features features;
struct wacom_shared *shared;
struct input_dev *input;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 06ea8da95c62..07ac77d393a4 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -659,17 +659,17 @@ config TOUCHSCREEN_PCAP
To compile this driver as a module, choose M here: the
module will be called pcap_ts.
-config TOUCHSCREEN_TPS6507X
- tristate "TPS6507x based touchscreens"
+config TOUCHSCREEN_ST1232
+ tristate "Sitronix ST1232 touchscreen controllers"
depends on I2C
help
- Say Y here if you have a TPS6507x based touchscreen
- controller.
+ Say Y here if you want to support Sitronix ST1232
+ touchscreen controller.
If unsure, say N.
To compile this driver as a module, choose M here: the
- module will be called tps6507x_ts.
+ module will be called st1232_ts.
config TOUCHSCREEN_STMPE
tristate "STMicroelectronics STMPE touchscreens"
@@ -681,4 +681,16 @@ config TOUCHSCREEN_STMPE
To compile this driver as a module, choose M here: the
module will be called stmpe-ts.
+config TOUCHSCREEN_TPS6507X
+ tristate "TPS6507x based touchscreens"
+ depends on I2C
+ help
+ Say Y here if you have a TPS6507x based touchscreen
+ controller.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tps6507x_ts.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 7cc1b4f4b677..718bcc814952 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o
obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
+obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 2ca9e5d66460..f7fa9ef4cd65 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -365,7 +365,7 @@ static int bu21013_init_chip(struct bu21013_ts_data *data)
}
retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG,
- BU21013_TH_OFF_4 || BU21013_TH_OFF_3);
+ BU21013_TH_OFF_4 | BU21013_TH_OFF_3);
if (retval < 0) {
dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n");
return retval;
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c
index 66b26ad3032a..4dcb0e872f6a 100644
--- a/drivers/input/touchscreen/qt602240_ts.c
+++ b/drivers/input/touchscreen/qt602240_ts.c
@@ -969,7 +969,7 @@ static int qt602240_initialize(struct qt602240_data *data)
return error;
data->object_table = kcalloc(info->object_num,
- sizeof(struct qt602240_data),
+ sizeof(struct qt602240_object),
GFP_KERNEL);
if (!data->object_table) {
dev_err(&client->dev, "Failed to allocate memory\n");
@@ -1324,8 +1324,9 @@ static int __devexit qt602240_remove(struct i2c_client *client)
}
#ifdef CONFIG_PM
-static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg)
+static int qt602240_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct qt602240_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
@@ -1339,8 +1340,9 @@ static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg)
return 0;
}
-static int qt602240_resume(struct i2c_client *client)
+static int qt602240_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct qt602240_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
@@ -1359,9 +1361,11 @@ static int qt602240_resume(struct i2c_client *client)
return 0;
}
-#else
-#define qt602240_suspend NULL
-#define qt602240_resume NULL
+
+static const struct dev_pm_ops qt602240_pm_ops = {
+ .suspend = qt602240_suspend,
+ .resume = qt602240_resume,
+};
#endif
static const struct i2c_device_id qt602240_id[] = {
@@ -1374,11 +1378,12 @@ static struct i2c_driver qt602240_driver = {
.driver = {
.name = "qt602240_ts",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &qt602240_pm_ops,
+#endif
},
.probe = qt602240_probe,
.remove = __devexit_p(qt602240_remove),
- .suspend = qt602240_suspend,
- .resume = qt602240_resume,
.id_table = qt602240_id,
};
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
new file mode 100644
index 000000000000..4ab371358b33
--- /dev/null
+++ b/drivers/input/touchscreen/st1232.c
@@ -0,0 +1,274 @@
+/*
+ * ST1232 Touchscreen Controller Driver
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * Tony SIM <chinyeow.sim.xt@renesas.com>
+ *
+ * Using code from:
+ * - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define ST1232_TS_NAME "st1232-ts"
+
+#define MIN_X 0x00
+#define MIN_Y 0x00
+#define MAX_X 0x31f /* (800 - 1) */
+#define MAX_Y 0x1df /* (480 - 1) */
+#define MAX_AREA 0xff
+#define MAX_FINGERS 2
+
+struct st1232_ts_finger {
+ u16 x;
+ u16 y;
+ u8 t;
+ bool is_valid;
+};
+
+struct st1232_ts_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct st1232_ts_finger finger[MAX_FINGERS];
+};
+
+static int st1232_ts_read_data(struct st1232_ts_data *ts)
+{
+ struct st1232_ts_finger *finger = ts->finger;
+ struct i2c_client *client = ts->client;
+ struct i2c_msg msg[2];
+ int error;
+ u8 start_reg;
+ u8 buf[10];
+
+ /* read touchscreen data from ST1232 */
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &start_reg;
+ start_reg = 0x10;
+
+ msg[1].addr = ts->client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = sizeof(buf);
+ msg[1].buf = buf;
+
+ error = i2c_transfer(client->adapter, msg, 2);
+ if (error < 0)
+ return error;
+
+ /* get "valid" bits */
+ finger[0].is_valid = buf[2] >> 7;
+ finger[1].is_valid = buf[5] >> 7;
+
+ /* get xy coordinate */
+ if (finger[0].is_valid) {
+ finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3];
+ finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4];
+ finger[0].t = buf[8];
+ }
+
+ if (finger[1].is_valid) {
+ finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6];
+ finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7];
+ finger[1].t = buf[9];
+ }
+
+ return 0;
+}
+
+static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
+{
+ struct st1232_ts_data *ts = dev_id;
+ struct st1232_ts_finger *finger = ts->finger;
+ struct input_dev *input_dev = ts->input_dev;
+ int count = 0;
+ int i, ret;
+
+ ret = st1232_ts_read_data(ts);
+ if (ret < 0)
+ goto end;
+
+ /* multi touch protocol */
+ for (i = 0; i < MAX_FINGERS; i++) {
+ if (!finger[i].is_valid)
+ continue;
+
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
+ input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
+ input_mt_sync(input_dev);
+ count++;
+ }
+
+ /* SYN_MT_REPORT only if no contact */
+ if (!count)
+ input_mt_sync(input_dev);
+
+ /* SYN_REPORT */
+ input_sync(input_dev);
+
+end:
+ return IRQ_HANDLED;
+}
+
+static int __devinit st1232_ts_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct st1232_ts_data *ts;
+ struct input_dev *input_dev;
+ int error;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "need I2C_FUNC_I2C\n");
+ return -EIO;
+ }
+
+ if (!client->irq) {
+ dev_err(&client->dev, "no IRQ?\n");
+ return -EINVAL;
+ }
+
+
+ ts = kzalloc(sizeof(struct st1232_ts_data), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ts || !input_dev) {
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ ts->client = client;
+ ts->input_dev = input_dev;
+
+ input_dev->name = "st1232-touchscreen";
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->dev.parent = &client->dev;
+
+ __set_bit(EV_SYN, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_ABS, input_dev->evbit);
+
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0);
+
+ error = request_threaded_irq(client->irq, NULL, st1232_ts_irq_handler,
+ IRQF_ONESHOT, client->name, ts);
+ if (error) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
+ goto err_free_mem;
+ }
+
+ error = input_register_device(ts->input_dev);
+ if (error) {
+ dev_err(&client->dev, "Unable to register %s input device\n",
+ input_dev->name);
+ goto err_free_irq;
+ }
+
+ i2c_set_clientdata(client, ts);
+ device_init_wakeup(&client->dev, 1);
+
+ return 0;
+
+err_free_irq:
+ free_irq(client->irq, ts);
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(ts);
+ return error;
+}
+
+static int __devexit st1232_ts_remove(struct i2c_client *client)
+{
+ struct st1232_ts_data *ts = i2c_get_clientdata(client);
+
+ device_init_wakeup(&client->dev, 0);
+ free_irq(client->irq, ts);
+ input_unregister_device(ts->input_dev);
+ kfree(ts);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int st1232_ts_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ if (device_may_wakeup(&client->dev))
+ enable_irq_wake(client->irq);
+ else
+ disable_irq(client->irq);
+
+ return 0;
+}
+
+static int st1232_ts_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ if (device_may_wakeup(&client->dev))
+ disable_irq_wake(client->irq);
+ else
+ enable_irq(client->irq);
+
+ return 0;
+}
+
+static const struct dev_pm_ops st1232_ts_pm_ops = {
+ .suspend = st1232_ts_suspend,
+ .resume = st1232_ts_resume,
+};
+#endif
+
+static const struct i2c_device_id st1232_ts_id[] = {
+ { ST1232_TS_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, st1232_ts_id);
+
+static struct i2c_driver st1232_ts_driver = {
+ .probe = st1232_ts_probe,
+ .remove = __devexit_p(st1232_ts_remove),
+ .id_table = st1232_ts_id,
+ .driver = {
+ .name = ST1232_TS_NAME,
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &st1232_ts_pm_ops,
+#endif
+ },
+};
+
+static int __init st1232_ts_init(void)
+{
+ return i2c_add_driver(&st1232_ts_driver);
+}
+module_init(st1232_ts_init);
+
+static void __exit st1232_ts_exit(void)
+{
+ i2c_del_driver(&st1232_ts_driver);
+}
+module_exit(st1232_ts_exit);
+
+MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>");
+MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index f45f80f6d336..73fd6642b681 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = {
#ifdef CONFIG_TOUCHSCREEN_USB_ITM
{USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
+ {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM},
#endif
#ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 9ae4c7b16ba7..8ed53aded2d3 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -15,10 +15,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
#define DRIVER_DESC "Wacom W8001 serial touchscreen driver"
@@ -37,6 +38,7 @@ MODULE_LICENSE("GPL");
#define W8001_QUERY_PACKET 0x20
+#define W8001_CMD_STOP '0'
#define W8001_CMD_START '1'
#define W8001_CMD_QUERY '*'
#define W8001_CMD_TOUCHQUERY '%'
@@ -48,8 +50,6 @@ MODULE_LICENSE("GPL");
#define W8001_PKTLEN_TPCCTL 11 /* control packet */
#define W8001_PKTLEN_TOUCH2FG 13
-#define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */
-
struct w8001_coord {
u8 rdy;
u8 tsw;
@@ -87,7 +87,6 @@ struct w8001 {
char phys[32];
int type;
unsigned int pktlen;
- int trkid[2];
};
static void parse_data(u8 *data, struct w8001_coord *coord)
@@ -116,28 +115,23 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
static void parse_touch(struct w8001 *w8001)
{
- static int trkid;
struct input_dev *dev = w8001->dev;
unsigned char *data = w8001->data;
int i;
for (i = 0; i < 2; i++) {
- input_mt_slot(dev, i);
+ bool touch = data[0] & (1 << i);
- if (data[0] & (1 << i)) {
+ input_mt_slot(dev, i);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
+ if (touch) {
int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]);
int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]);
/* data[5,6] and [11,12] is finger capacity */
input_report_abs(dev, ABS_MT_POSITION_X, x);
input_report_abs(dev, ABS_MT_POSITION_Y, y);
- input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
- if (w8001->trkid[i] < 0)
- w8001->trkid[i] = trkid++ & MAX_TRACKING_ID;
- } else {
- w8001->trkid[i] = -1;
}
- input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]);
}
input_sync(dev);
@@ -287,24 +281,46 @@ static int w8001_setup(struct w8001 *w8001)
struct w8001_coord coord;
int error;
- error = w8001_command(w8001, W8001_CMD_QUERY, true);
+ error = w8001_command(w8001, W8001_CMD_STOP, false);
if (error)
return error;
- parse_data(w8001->response, &coord);
+ msleep(250); /* wait 250ms before querying the device */
- input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
- input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
- input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
- input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
- input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
+ /* penabled? */
+ error = w8001_command(w8001, W8001_CMD_QUERY, true);
+ if (!error) {
+ __set_bit(BTN_TOOL_PEN, dev->keybit);
+ __set_bit(BTN_TOOL_RUBBER, dev->keybit);
+ __set_bit(BTN_STYLUS, dev->keybit);
+ __set_bit(BTN_STYLUS2, dev->keybit);
+ parse_data(w8001->response, &coord);
+
+ input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
+ input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
+ if (coord.tilt_x && coord.tilt_y) {
+ input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
+ input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
+ }
+ }
+ /* Touch enabled? */
error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true);
- if (!error) {
+
+ /*
+ * Some non-touch devices may reply to the touch query. But their
+ * second byte is empty, which indicates touch is not supported.
+ */
+ if (!error && w8001->response[1]) {
struct w8001_touch_query touch;
parse_touchquery(w8001->response, &touch);
+ input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
+ __set_bit(BTN_TOOL_FINGER, dev->keybit);
+
switch (touch.sensor_id) {
case 0:
case 2:
@@ -318,15 +334,13 @@ static int w8001_setup(struct w8001 *w8001)
case 5:
w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
- input_mt_create_slots(dev, 2);
- input_set_abs_params(dev, ABS_MT_TRACKING_ID,
- 0, MAX_TRACKING_ID, 0, 0);
+ input_mt_init_slots(dev, 2);
input_set_abs_params(dev, ABS_MT_POSITION_X,
0, touch.x, 0, 0);
input_set_abs_params(dev, ABS_MT_POSITION_Y,
0, touch.y, 0, 0);
input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
- 0, 0, 0, 0);
+ 0, MT_TOOL_MAX, 0, 0);
break;
}
}
@@ -372,7 +386,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
w8001->serio = serio;
w8001->id = serio->id.id;
w8001->dev = input_dev;
- w8001->trkid[0] = w8001->trkid[1] = -1;
init_completion(&w8001->cmd_done);
snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
@@ -385,11 +398,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
input_dev->dev.parent = &serio->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN);
- input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER);
- input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS);
- input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
serio_set_drvdata(serio, w8001);
err = serio_open(serio, drv);
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index e0c024db2ca5..7f85a862ad11 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -17,6 +17,8 @@
* Switch to grant tables together with xen-fbfront.c.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -84,9 +86,8 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_key(dev, event->key.keycode,
event->key.pressed);
else
- printk(KERN_WARNING
- "xenkbd: unhandled keycode 0x%x\n",
- event->key.keycode);
+ pr_warning("unhandled keycode 0x%x\n",
+ event->key.keycode);
break;
case XENKBD_TYPE_POS:
input_report_abs(dev, ABS_X, event->pos.abs_x);
@@ -292,8 +293,7 @@ InitWait:
ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,
"request-abs-pointer", "1");
if (ret)
- printk(KERN_WARNING
- "xenkbd: can't request abs-pointer");
+ pr_warning("can't request abs-pointer\n");
}
xenbus_switch_state(dev, XenbusStateConnected);
break;
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index bcc174e4f3b1..658e75f18d05 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -1900,6 +1900,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
if (b3skb == NULL) {
dev_err(cs->dev, "%s: out of memory\n", __func__);
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+ kfree(b3cmsg);
return;
}
capi_cmsg2message(b3cmsg,
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
index e90db8870b6c..bc0529ac88a1 100644
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -420,7 +420,7 @@ enable_hwirq(struct inf_hw *hw)
break;
case INF_NICCY:
val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
- val |= NICCY_IRQ_ENABLE;;
+ val |= NICCY_IRQ_ENABLE;
outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
break;
case INF_SCT_1:
@@ -924,7 +924,7 @@ setup_instance(struct inf_hw *card)
mISDNipac_init(&card->ipac, card);
if (card->ipac.isac.dch.dev.Bprotocols == 0)
- goto error_setup;;
+ goto error_setup;
err = mISDN_register_device(&card->ipac.isac.dch.dev,
&card->pdev->dev, card->name);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 38eb31439a73..d13fa5b119f5 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -264,7 +264,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
while (noc) {
val = le16_to_cpu(*sp++);
*mp++ = val >> 8;
- *mp++ = val & 0xFF;;
+ *mp++ = val & 0xFF;
noc--;
}
spin_lock_irqsave(isar->hwlock, flags);
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index fcf4ed1cb4b9..0e66af1decd4 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -314,7 +314,7 @@ hdlc_fill_fifo(struct BCState *bcs)
bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME;
}
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
- debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
+ debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len);
p = bcs->tx_skb->data;
ptr = (u_int *)p;
skb_pull(bcs->tx_skb, count);
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index f150330b5a23..37e685eafd24 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -65,7 +65,7 @@ hisax_findcard(int driverid)
return (struct IsdnCardState *) 0;
}
-static void
+static __attribute__((format(printf, 3, 4))) void
link_debug(struct Channel *chanp, int direction, char *fmt, ...)
{
va_list args;
@@ -1068,7 +1068,7 @@ init_d_st(struct Channel *chanp)
return 0;
}
-static void
+static __attribute__((format(printf, 2, 3))) void
callc_debug(struct FsmInst *fi, char *fmt, ...)
{
va_list args;
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index b133378d4dc9..c110f8679bab 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1917,7 +1917,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
#ifdef CONFIG_PCI
#include <linux/pci.h>
-static struct pci_device_id hisax_pci_tbl[] __devinitdata = {
+static struct pci_device_id hisax_pci_tbl[] __devinitdata __used = {
#ifdef CONFIG_HISAX_FRITZPCI
{PCI_VDEVICE(AVM, PCI_DEVICE_ID_AVM_A1) },
#endif
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 7250f56a5246..a16459a1332c 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -292,7 +292,7 @@ hfc_fill_fifo(struct BCState *bcs)
}
count = GetFreeFifoBytes_B(bcs);
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx",
+ debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx",
bcs->channel, bcs->tx_skb->len,
count, current->state);
if (count < bcs->tx_skb->len) {
@@ -719,7 +719,7 @@ hfc_fill_dfifo(struct IsdnCardState *cs)
}
count = GetFreeFifoBytes_D(cs);
if (cs->debug & L1_DEB_ISAC)
- debugl1(cs, "hfc_fill_Dfifo count(%ld/%d)",
+ debugl1(cs, "hfc_fill_Dfifo count(%u/%d)",
cs->tx_skb->len, count);
if (count < cs->tx_skb->len) {
if (cs->debug & L1_DEB_ISAC)
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index b1f6481e1193..626f85df302b 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -282,7 +282,7 @@ hfc_fill_fifo(struct BCState *bcs)
count += cs->hw.hfc.fifosize;
} /* L1_MODE_TRANS */
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)",
+ debugl1(cs, "hfc_fill_fifo %d count(%u/%d)",
bcs->channel, bcs->tx_skb->len,
count);
if (count < bcs->tx_skb->len) {
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 917cc84065bd..3147020d188b 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -550,7 +550,7 @@ hfcpci_fill_dfifo(struct IsdnCardState *cs)
count += D_FIFO_SIZE; /* count now contains available bytes */
if (cs->debug & L1_DEB_ISAC)
- debugl1(cs, "hfcpci_fill_Dfifo count(%ld/%d)",
+ debugl1(cs, "hfcpci_fill_Dfifo count(%u/%d)",
cs->tx_skb->len, count);
if (count < cs->tx_skb->len) {
if (cs->debug & L1_DEB_ISAC)
@@ -681,7 +681,7 @@ hfcpci_fill_fifo(struct BCState *bcs)
count += B_FIFO_SIZE; /* count now contains available bytes */
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "hfcpci_fill_fifo %d count(%ld/%d),%lx",
+ debugl1(cs, "hfcpci_fill_fifo %d count(%u/%d),%lx",
bcs->channel, bcs->tx_skb->len,
count, current->state);
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 5aa138eb0b3c..1235b7131ae1 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -179,7 +179,7 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans
count += fifo_size; /* count now contains available bytes */
if (cs->debug & L1_DEB_ISAC_FIFO)
- debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)",
+ debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)",
fifo, skb->len, count);
if (count < skb->len) {
if (cs->debug & L1_DEB_ISAC_FIFO)
@@ -265,7 +265,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
count++;
if (cs->debug & L1_DEB_ISAC_FIFO)
- debugl1(cs, "hfcsx_read_fifo %d count %ld)",
+ debugl1(cs, "hfcsx_read_fifo %d count %u)",
fifo, count);
if ((count > fifo_size) || (count < 4)) {
@@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
default:
spin_unlock_irqrestore(&cs->lock, flags);
if (cs->debug & L1_DEB_WARN)
- debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg);
+ debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg);
return;
}
cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 32ab3924aa73..de1c669c7b13 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1286,7 +1286,9 @@ int jiftime(char *s, long mark);
int HiSax_command(isdn_ctrl * ic);
int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
+__attribute__((format(printf, 3, 4)))
void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
+__attribute__((format(printf, 3, 0)))
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args);
void HiSax_reportcard(int cardnr, int sel);
int QuickHex(char *txt, u_char * p, int cnt);
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 751b25f2ff58..332104103e18 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -717,7 +717,7 @@ bch_mode(struct BCState *bcs, int mode, int bc)
bc = bc ? 1 : 0; // in case bc is greater than 1
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc);
+ debugl1(cs, "mode_bch() switch B-%d mode %d chan %d", hscx, mode, bc);
bcs->mode = mode;
bcs->channel = bc;
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 2e72227bd071..d4cce337add2 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -189,7 +189,7 @@ ISARVersion(struct IsdnCardState *cs, char *s)
static int
isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
{
- int ret, size, cnt, debug;
+ int cfu_ret, ret, size, cnt, debug;
u_char len, nom, noc;
u_short sadr, left, *sp;
u_char __user *p = buf;
@@ -212,9 +212,10 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
#endif
- if ((ret = copy_from_user(&size, p, sizeof(int)))) {
- printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
- return ret;
+ cfu_ret = copy_from_user(&size, p, sizeof(int));
+ if (cfu_ret) {
+ printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", cfu_ret);
+ return -EFAULT;
}
p += sizeof(int);
printk(KERN_DEBUG"isar_load_firmware size: %d\n", size);
@@ -953,7 +954,7 @@ isar_pump_statev_modem(struct BCState *bcs, u_char devt) {
break;
case PSEV_GSTN_CLR:
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "pump stev GSTN CLEAR", devt);
+ debugl1(cs, "pump stev GSTN CLEAR");
break;
default:
if (cs->debug & L1_DEB_HSCX)
@@ -1268,7 +1269,7 @@ isar_int_main(struct IsdnCardState *cs)
static void
ftimer_handler(struct BCState *bcs) {
if (bcs->cs->debug)
- debugl1(bcs->cs, "ftimer flags %04x",
+ debugl1(bcs->cs, "ftimer flags %04lx",
bcs->Flag);
test_and_clear_bit(BC_FLG_FTI_RUN, &bcs->Flag);
if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) {
@@ -1748,7 +1749,7 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
struct BCState *bcs;
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "isar_auxcmd cmd/ch %x/%d", ic->command, ic->arg);
+ debugl1(cs, "isar_auxcmd cmd/ch %x/%ld", ic->command, ic->arg);
switch (ic->command) {
case (ISDN_CMD_FAXCMD):
bcs = cs->channel[ic->arg].bcs;
diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h
index 172ad4c8c961..425d86116f2b 100644
--- a/drivers/isdn/hisax/isdnl1.h
+++ b/drivers/isdn/hisax/isdnl1.h
@@ -21,6 +21,7 @@
#define B_XMTBUFREADY 1
#define B_ACKPENDING 2
+__attribute__((format(printf, 2, 3)))
void debugl1(struct IsdnCardState *cs, char *fmt, ...);
void DChannel_proc_xmt(struct IsdnCardState *cs);
void DChannel_proc_rcv(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index fd0b643ab740..ad291f21b201 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -66,7 +66,7 @@ static char *strL3Event[] =
"EV_TIMEOUT",
};
-static void
+static __attribute__((format(printf, 2, 3))) void
l3m_debug(struct FsmInst *fi, char *fmt, ...)
{
va_list args;
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 5d7f0f2ff9b9..644891efc26f 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -254,7 +254,7 @@ static int make_raw_data(struct BCState *bcs) {
val >>= 1;
}
if (bcs->cs->debug & L1_DEB_HSCX)
- debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d",
+ debugl1(bcs->cs,"tiger make_raw: in %u out %d.%d",
bcs->tx_skb->len, s_cnt, bitcnt);
if (bitcnt) {
while (8>bitcnt++) {
@@ -361,7 +361,7 @@ static int make_raw_data_56k(struct BCState *bcs) {
val >>= 1;
}
if (bcs->cs->debug & L1_DEB_HSCX)
- debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d",
+ debugl1(bcs->cs,"tiger make_raw_56k: in %u out %d.%d",
bcs->tx_skb->len, s_cnt, bitcnt);
if (bitcnt) {
while (8>bitcnt++) {
@@ -612,7 +612,7 @@ void netjet_fill_dma(struct BCState *bcs)
if (!bcs->tx_skb)
return;
if (bcs->cs->debug & L1_DEB_HSCX)
- debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
+ debugl1(bcs->cs,"tiger fill_dma1: c%d %4lx", bcs->channel,
bcs->Flag);
if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
return;
@@ -625,7 +625,7 @@ void netjet_fill_dma(struct BCState *bcs)
return;
};
if (bcs->cs->debug & L1_DEB_HSCX)
- debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
+ debugl1(bcs->cs,"tiger fill_dma2: c%d %4lx", bcs->channel,
bcs->Flag);
if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
@@ -667,7 +667,7 @@ void netjet_fill_dma(struct BCState *bcs)
write_raw(bcs, p, cnt);
}
if (bcs->cs->debug & L1_DEB_HSCX)
- debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
+ debugl1(bcs->cs,"tiger fill_dma3: c%d %4lx", bcs->channel,
bcs->Flag);
}
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index b7876b19fe73..44082637a09f 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -167,7 +167,8 @@ static struct FsmNode L1FnList[] __initdata =
{ST_L1_F8, EV_IND_RSY, l1_ignore},
};
-static void l1m_debug(struct FsmInst *fi, char *fmt, ...)
+static __attribute__((format(printf, 2, 3)))
+void l1m_debug(struct FsmInst *fi, char *fmt, ...)
{
va_list args;
char buf[256];
@@ -269,7 +270,8 @@ static char *strDoutEvent[] =
"EV_DOUT_UNDERRUN",
};
-static void dout_debug(struct FsmInst *fi, char *fmt, ...)
+static __attribute__((format(printf, 2, 3)))
+void dout_debug(struct FsmInst *fi, char *fmt, ...)
{
va_list args;
char buf[256];
diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c
index 46048e55f241..d568689669f8 100644
--- a/drivers/isdn/i4l/isdn_concap.c
+++ b/drivers/isdn/i4l/isdn_concap.c
@@ -61,7 +61,7 @@ static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *
static int isdn_concap_dl_connect_req(struct concap_proto *concap)
{
struct net_device *ndev = concap -> net_dev;
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
+ isdn_net_local *lp = netdev_priv(ndev);
int ret;
IX25DEBUG( "isdn_concap_dl_connect_req: %s \n", ndev -> name);
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 26d44c3ca1d8..afeede7ee295 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -827,7 +827,7 @@ isdn_net_dial(void)
void
isdn_net_hangup(struct net_device *d)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(d);
+ isdn_net_local *lp = netdev_priv(d);
isdn_ctrl cmd;
#ifdef CONFIG_ISDN_X25
struct concap_proto *cprot = lp->netdev->cprot;
@@ -1052,7 +1052,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
{
isdn_net_dev *nd;
isdn_net_local *slp;
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
+ isdn_net_local *lp = netdev_priv(ndev);
int retv = NETDEV_TX_OK;
if (((isdn_net_local *) netdev_priv(ndev))->master) {
@@ -1116,7 +1116,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
static void
isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
if (!skb)
return;
if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
@@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
static void isdn_net_tx_timeout(struct net_device * ndev)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
+ isdn_net_local *lp = netdev_priv(ndev);
printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
if (!lp->dialstate){
@@ -1165,7 +1165,7 @@ static void isdn_net_tx_timeout(struct net_device * ndev)
static netdev_tx_t
isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
+ isdn_net_local *lp = netdev_priv(ndev);
#ifdef CONFIG_ISDN_X25
struct concap_proto * cprot = lp -> netdev -> cprot;
/* At this point hard_start_xmit() passes control to the encapsulation
@@ -1347,7 +1347,7 @@ isdn_net_close(struct net_device *dev)
static struct net_device_stats *
isdn_net_get_stats(struct net_device *dev)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
return &lp->stats;
}
@@ -1426,7 +1426,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
static int
isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
unsigned long len = 0;
unsigned long expires = 0;
int tmp = 0;
@@ -1493,7 +1493,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int isdn_net_ioctl(struct net_device *dev,
struct ifreq *ifr, int cmd)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
switch (lp->p_encap) {
#ifdef CONFIG_ISDN_PPP
@@ -1786,7 +1786,7 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
static void
isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
{
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
+ isdn_net_local *lp = netdev_priv(ndev);
isdn_net_local *olp = lp; /* original 'lp' */
#ifdef CONFIG_ISDN_X25
struct concap_proto *cprot = lp -> netdev -> cprot;
@@ -1800,7 +1800,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
* handle master's statistics and hangup-timeout
*/
ndev = lp->master;
- lp = (isdn_net_local *) netdev_priv(ndev);
+ lp = netdev_priv(ndev);
lp->stats.rx_packets++;
lp->stats.rx_bytes += skb->len;
}
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index fe824e0cbb25..9e8162c80bb0 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1147,15 +1147,14 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
}
if (is->pass_filter
- && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0) {
+ && sk_run_filter(skb, is->pass_filter) == 0) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: inbound frame filtered.\n");
kfree_skb(skb);
return;
}
if (!(is->active_filter
- && sk_run_filter(skb, is->active_filter,
- is->active_len) == 0)) {
+ && sk_run_filter(skb, is->active_filter) == 0)) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
lp->huptimer = 0;
@@ -1221,7 +1220,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
struct ippp_struct *ipt,*ipts;
int slot, retval = NETDEV_TX_OK;
- mlp = (isdn_net_local *) netdev_priv(netdev);
+ mlp = netdev_priv(netdev);
nd = mlp->netdev; /* get master lp */
slot = mlp->ppp_slot;
@@ -1294,15 +1293,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
}
if (ipt->pass_filter
- && sk_run_filter(skb, ipt->pass_filter, ipt->pass_len) == 0) {
+ && sk_run_filter(skb, ipt->pass_filter) == 0) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: outbound frame filtered.\n");
kfree_skb(skb);
goto unlock;
}
if (!(ipt->active_filter
- && sk_run_filter(skb, ipt->active_filter,
- ipt->active_len) == 0)) {
+ && sk_run_filter(skb, ipt->active_filter) == 0)) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
lp->huptimer = 0;
@@ -1492,9 +1490,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
}
drop |= is->pass_filter
- && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0;
+ && sk_run_filter(skb, is->pass_filter) == 0;
drop |= is->active_filter
- && sk_run_filter(skb, is->active_filter, is->active_len) == 0;
+ && sk_run_filter(skb, is->active_filter) == 0;
skb_push(skb, IPPP_MAX_HEADER - 4);
return drop;
@@ -1985,7 +1983,7 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
{
struct ppp_stats __user *res = ifr->ifr_data;
struct ppp_stats t;
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
if (!access_ok(VERIFY_WRITE, res, sizeof(struct ppp_stats)))
return -EFAULT;
@@ -2024,7 +2022,7 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
int error=0;
int len;
- isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
+ isdn_net_local *lp = netdev_priv(dev);
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
@@ -2091,7 +2089,7 @@ isdn_ppp_dial_slave(char *name)
sdev = lp->slave;
while (sdev) {
- isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev);
+ isdn_net_local *mlp = netdev_priv(sdev);
if (!(mlp->flags & ISDN_NET_CONNECTED))
break;
sdev = mlp->slave;
@@ -2099,7 +2097,7 @@ isdn_ppp_dial_slave(char *name)
if (!sdev)
return 2;
- isdn_net_dial_req((isdn_net_local *) netdev_priv(sdev));
+ isdn_net_dial_req(netdev_priv(sdev));
return 0;
#else
return -1;
@@ -2122,7 +2120,7 @@ isdn_ppp_hangup_slave(char *name)
sdev = lp->slave;
while (sdev) {
- isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev);
+ isdn_net_local *mlp = netdev_priv(sdev);
if (mlp->slave) { /* find last connected link in chain */
isdn_net_local *nlp = ISDN_SLAVE_PRIV(mlp);
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index ac4aa18c632b..5cc7c001c523 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -99,12 +99,16 @@ static void
l1m_debug(struct FsmInst *fi, char *fmt, ...)
{
struct layer1 *l1 = fi->userdata;
+ struct va_format vaf;
va_list va;
va_start(va, fmt);
- printk(KERN_DEBUG "%s: ", dev_name(&l1->dch->dev.dev));
- vprintk(fmt, va);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &va;
+
+ printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf);
+
va_end(va);
}
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index c97371788764..4ae75053c9d2 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -95,14 +95,20 @@ static void
l2m_debug(struct FsmInst *fi, char *fmt, ...)
{
struct layer2 *l2 = fi->userdata;
+ struct va_format vaf;
va_list va;
if (!(*debug & DEBUG_L2_FSM))
return;
+
va_start(va, fmt);
- printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei);
- vprintk(fmt, va);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &va;
+
+ printk(KERN_DEBUG "l2 (sapi %d tei %d): %pV\n",
+ l2->sapi, l2->tei, &vaf);
+
va_end(va);
}
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index 1b85d9d27496..687c9b6264ab 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -79,14 +79,19 @@ static void
da_debug(struct FsmInst *fi, char *fmt, ...)
{
struct manager *mgr = fi->userdata;
+ struct va_format vaf;
va_list va;
if (!(*debug & DEBUG_L2_TEIFSM))
return;
+
va_start(va, fmt);
- printk(KERN_DEBUG "mgr(%d): ", mgr->ch.st->dev->id);
- vprintk(fmt, va);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &va;
+
+ printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf);
+
va_end(va);
}
@@ -223,14 +228,20 @@ static void
tei_debug(struct FsmInst *fi, char *fmt, ...)
{
struct teimgr *tm = fi->userdata;
+ struct va_format vaf;
va_list va;
if (!(*debug & DEBUG_L2_TEIFSM))
return;
+
va_start(va, fmt);
- printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei);
- vprintk(fmt, va);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &va;
+
+ printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n",
+ tm->l2->sapi, tm->l2->tei, &vaf);
+
va_end(va);
}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 77b8fd20cd90..6f190f4cdbc0 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -7,20 +7,20 @@ menuconfig NEW_LEDS
This is not related to standard keyboard LEDs which are controlled
via the input system.
-if NEW_LEDS
-
config LEDS_CLASS
bool "LED Class Support"
+ depends on NEW_LEDS
help
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
+if NEW_LEDS
comment "LED drivers"
config LEDS_88PM860X
tristate "LED Support for Marvell 88PM860x PMIC"
+ depends on LEDS_CLASS
depends on MFD_88PM860X
help
This option enables support for on-chip LED drivers found on Marvell
@@ -28,6 +28,7 @@ config LEDS_88PM860X
config LEDS_ATMEL_PWM
tristate "LED Support using Atmel PWM outputs"
+ depends on LEDS_CLASS
depends on ATMEL_PWM
help
This option enables support for LEDs driven using outputs
@@ -35,6 +36,7 @@ config LEDS_ATMEL_PWM
config LEDS_LOCOMO
tristate "LED Support for Locomo device"
+ depends on LEDS_CLASS
depends on SHARP_LOCOMO
help
This option enables support for the LEDs on Sharp Locomo.
@@ -42,6 +44,7 @@ config LEDS_LOCOMO
config LEDS_MIKROTIK_RB532
tristate "LED Support for Mikrotik Routerboard 532"
+ depends on LEDS_CLASS
depends on MIKROTIK_RB532
help
This option enables support for the so called "User LED" of
@@ -49,6 +52,7 @@ config LEDS_MIKROTIK_RB532
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
+ depends on LEDS_CLASS
depends on ARCH_S3C2410
help
This option enables support for LEDs connected to GPIO lines
@@ -56,12 +60,14 @@ config LEDS_S3C24XX
config LEDS_AMS_DELTA
tristate "LED Support for the Amstrad Delta (E3)"
+ depends on LEDS_CLASS
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
depends on SCx200_GPIO
help
This option enables support for the Soekris net4801 and net4826 error
@@ -79,18 +85,21 @@ config LEDS_NET5501
config LEDS_FSG
tristate "LED Support for the Freecom FSG-3"
+ depends on LEDS_CLASS
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
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
depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
help
This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
@@ -98,12 +107,14 @@ config LEDS_ALIX2
config LEDS_H1940
tristate "LED Support for iPAQ H1940 device"
+ depends on LEDS_CLASS
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
depends on MIPS_COBALT
help
This option enables support for the front LED on Cobalt Qube series
@@ -117,6 +128,7 @@ config LEDS_COBALT_RAQ
config LEDS_SUNFIRE
tristate "LED support for SunFire servers."
+ depends on LEDS_CLASS
depends on SPARC64
select LEDS_TRIGGERS
help
@@ -125,6 +137,7 @@ config LEDS_SUNFIRE
config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
+ depends on LEDS_CLASS
depends on SH_HP6XX
help
This option enables LED support for the handheld
@@ -132,6 +145,7 @@ config LEDS_HP6XX
config LEDS_PCA9532
tristate "LED driver for PCA9532 dimmer"
+ depends on LEDS_CLASS
depends on I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
@@ -140,6 +154,7 @@ config LEDS_PCA9532
config LEDS_GPIO
tristate "LED Support for GPIO connected LEDs"
+ depends on LEDS_CLASS
depends on GENERIC_GPIO
help
This option enables support for the LEDs connected to GPIO
@@ -167,6 +182,7 @@ config LEDS_GPIO_OF
config LEDS_LP3944
tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
+ depends on LEDS_CLASS
depends on I2C
help
This option enables support for LEDs connected to the National
@@ -196,6 +212,7 @@ config LEDS_LP5523
config LEDS_CLEVO_MAIL
tristate "Mail LED on Clevo notebook"
+ depends on LEDS_CLASS
depends on X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
@@ -226,6 +243,7 @@ config LEDS_CLEVO_MAIL
config LEDS_PCA955X
tristate "LED Support for PCA955x I2C chips"
+ depends on LEDS_CLASS
depends on I2C
help
This option enables support for LEDs connected to PCA955x
@@ -234,6 +252,7 @@ config LEDS_PCA955X
config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs"
+ depends on LEDS_CLASS
depends on MFD_WM831X
help
This option enables support for the status LEDs of the WM831x
@@ -241,6 +260,7 @@ config LEDS_WM831X_STATUS
config LEDS_WM8350
tristate "LED Support for WM8350 AudioPlus PMIC"
+ depends on LEDS_CLASS
depends on MFD_WM8350
help
This option enables support for LEDs driven by the Wolfson
@@ -248,6 +268,7 @@ config LEDS_WM8350
config LEDS_DA903X
tristate "LED Support for DA9030/DA9034 PMIC"
+ depends on LEDS_CLASS
depends on PMIC_DA903X
help
This option enables support for on-chip LED drivers found
@@ -255,6 +276,7 @@ config LEDS_DA903X
config LEDS_DAC124S085
tristate "LED Support for DAC124S085 SPI DAC"
+ depends on LEDS_CLASS
depends on SPI
help
This option enables support for DAC124S085 SPI DAC from NatSemi,
@@ -262,18 +284,21 @@ config LEDS_DAC124S085
config LEDS_PWM
tristate "PWM driven LED Support"
+ depends on LEDS_CLASS
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
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
depends on I2C
help
This option enables support for BD2802GU RGB LED driver chips
@@ -281,6 +306,7 @@ config LEDS_BD2802
config LEDS_INTEL_SS4200
tristate "LED driver for Intel NAS SS4200 series"
+ depends on LEDS_CLASS
depends on PCI && DMI
help
This option enables support for the Intel SS4200 series of
@@ -290,6 +316,7 @@ config LEDS_INTEL_SS4200
config LEDS_LT3593
tristate "LED driver for LT3593 controllers"
+ depends on LEDS_CLASS
depends on GENERIC_GPIO
help
This option enables support for LEDs driven by a Linear Technology
@@ -298,6 +325,7 @@ config LEDS_LT3593
config LEDS_ADP5520
tristate "LED Support for ADP5520/ADP5501 PMIC"
+ depends on LEDS_CLASS
depends on PMIC_ADP5520
help
This option enables support for on-chip LED drivers found
@@ -308,6 +336,7 @@ config LEDS_ADP5520
config LEDS_DELL_NETBOOKS
tristate "External LED on Dell Business Netbooks"
+ depends on LEDS_CLASS
depends on X86 && ACPI_WMI
help
This adds support for the Latitude 2100 and similar
@@ -315,6 +344,7 @@ config LEDS_DELL_NETBOOKS
config LEDS_MC13783
tristate "LED Support for MC13783 PMIC"
+ depends on LEDS_CLASS
depends on MFD_MC13783
help
This option enable support for on-chip LED drivers found
@@ -322,6 +352,7 @@ config LEDS_MC13783
config LEDS_NS2
tristate "LED support for Network Space v2 GPIO LEDs"
+ depends on LEDS_CLASS
depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
default y
help
@@ -340,17 +371,17 @@ config LEDS_NETXBIG
config LEDS_TRIGGERS
bool "LED Trigger support"
+ depends on LEDS_CLASS
help
This option enables trigger support for the leds class.
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
@@ -362,12 +393,14 @@ config LEDS_TRIGGER_TIMER
config LEDS_TRIGGER_IDE_DISK
bool "LED IDE Disk Trigger"
depends on IDE_GD_ATA
+ depends on LEDS_TRIGGERS
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
@@ -376,6 +409,7 @@ 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.
@@ -384,6 +418,7 @@ 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
@@ -396,6 +431,7 @@ 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.
@@ -403,8 +439,4 @@ 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/led-class.c b/drivers/leds/led-class.c
index 211e21f34bd5..d5a4ade88991 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -267,7 +267,7 @@ void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_off)
{
if (led_cdev->blink_set &&
- led_cdev->blink_set(led_cdev, delay_on, delay_off))
+ !led_cdev->blink_set(led_cdev, delay_on, delay_off))
return;
/* blink with 1 Hz as default if nothing specified */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 04b22128a474..d21578ee95de 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -1137,7 +1137,7 @@ void free_guest_pagetable(struct lguest *lg)
*/
void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
{
- pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
+ pte_t *switcher_pte_page = __this_cpu_read(switcher_pte_pages);
pte_t regs_pte;
#ifdef CONFIG_X86_PAE
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index b4eb675a807e..9f1659c3d1f3 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -90,8 +90,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
* meanwhile). If that's not the case, we pretend everything in the
* Guest has changed.
*/
- if (__get_cpu_var(lg_last_cpu) != cpu || cpu->last_pages != pages) {
- __get_cpu_var(lg_last_cpu) = cpu;
+ if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) {
+ __this_cpu_write(lg_last_cpu, cpu);
cpu->last_pages = pages;
cpu->changed = CHANGED_ALL;
}
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 3d7355ff7308..fa51af11c6f1 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -102,6 +102,7 @@ config ADB_PMU_LED
config ADB_PMU_LED_IDE
bool "Use front LED as IDE LED by default"
depends on ADB_PMU_LED
+ depends on LEDS_CLASS
select LEDS_TRIGGERS
select LEDS_TRIGGER_IDE_DISK
help
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 067f9962f499..6a82388505f0 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -23,6 +23,8 @@ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
static struct input_dev *mac_hid_emumouse_dev;
+static DEFINE_MUTEX(mac_hid_emumouse_mutex);
+
static int mac_hid_create_emumouse(void)
{
static struct lock_class_key mac_hid_emumouse_dev_event_class;
@@ -187,6 +189,10 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write,
int old_val = *valp;
int rc;
+ rc = mutex_lock_killable(&mac_hid_emumouse_mutex);
+ if (rc)
+ return rc;
+
rc = proc_dointvec(table, write, buffer, lenp, ppos);
if (rc == 0 && write && *valp != old_val) {
@@ -202,6 +208,8 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write,
if (rc)
*valp = old_val;
+ mutex_unlock(&mac_hid_emumouse_mutex);
+
return rc;
}
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index b6e7ddc09d76..4daf9e5a7736 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -387,11 +387,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
/* Set the DMA ops to the ones from the PCI device, this could be
* fishy if we didn't know that on PowerMac it's always direct ops
* or iommu ops that will work fine
+ *
+ * To get all the fields, copy all archdata
*/
- dev->ofdev.dev.archdata.dma_ops =
- chip->lbus.pdev->dev.archdata.dma_ops;
- dev->ofdev.dev.archdata.dma_data =
- chip->lbus.pdev->dev.archdata.dma_data;
+ dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata;
#endif /* CONFIG_PCI */
#ifdef DEBUG
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 44549272333c..2e041fd0a00c 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -2213,6 +2213,9 @@ static void fcu_lookup_fans(struct device_node *fcu_node)
static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match)
{
state = state_detached;
+ of_dev = dev;
+
+ dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION);
/* Lookup the fans in the device tree */
fcu_lookup_fans(dev->dev.of_node);
@@ -2235,6 +2238,7 @@ static const struct of_device_id fcu_match[] =
},
{},
};
+MODULE_DEVICE_TABLE(of, fcu_match);
static struct of_platform_driver fcu_of_platform_driver =
{
@@ -2252,8 +2256,6 @@ static struct of_platform_driver fcu_of_platform_driver =
*/
static int __init therm_pm72_init(void)
{
- struct device_node *np;
-
rackmac = of_machine_is_compatible("RackMac3,1");
if (!of_machine_is_compatible("PowerMac7,2") &&
@@ -2261,34 +2263,12 @@ static int __init therm_pm72_init(void)
!rackmac)
return -ENODEV;
- printk(KERN_INFO "PowerMac G5 Thermal control driver %s\n", VERSION);
-
- np = of_find_node_by_type(NULL, "fcu");
- if (np == NULL) {
- /* Some machines have strangely broken device-tree */
- np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e");
- if (np == NULL) {
- printk(KERN_ERR "Can't find FCU in device-tree !\n");
- return -ENODEV;
- }
- }
- of_dev = of_platform_device_create(np, "temperature", NULL);
- if (of_dev == NULL) {
- printk(KERN_ERR "Can't register FCU platform device !\n");
- return -ENODEV;
- }
-
- of_register_platform_driver(&fcu_of_platform_driver);
-
- return 0;
+ return of_register_platform_driver(&fcu_of_platform_driver);
}
static void __exit therm_pm72_exit(void)
{
of_unregister_platform_driver(&fcu_of_platform_driver);
-
- if (of_dev)
- of_device_unregister(of_dev);
}
module_init(therm_pm72_init);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index d5b0e4c0e702..4c4408a2602f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -973,15 +973,15 @@ static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
static int crypt_set_key(struct crypt_config *cc, char *key)
{
- unsigned key_size = strlen(key) >> 1;
-
- if (cc->key_size && cc->key_size != key_size)
+ /* The key size may not be changed. */
+ if (cc->key_size != (strlen(key) >> 1))
return -EINVAL;
- cc->key_size = key_size; /* initial settings */
+ /* Hyphen (which gives a key_size of zero) means there is no key. */
+ if (!cc->key_size && strcmp(key, "-"))
+ return -EINVAL;
- if ((!key_size && strcmp(key, "-")) ||
- (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+ if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0)
return -EINVAL;
set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
@@ -1194,6 +1194,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->error = "Cannot allocate encryption context";
return -ENOMEM;
}
+ cc->key_size = key_size;
ti->private = cc;
ret = crypt_ctr_cipher(ti, argv[0], argv[1]);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 4b54618b4159..f3481d922206 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -295,19 +295,55 @@ retry:
DMWARN("remove_all left %d open device(s)", dev_skipped);
}
+/*
+ * Set the uuid of a hash_cell that isn't already set.
+ */
+static void __set_cell_uuid(struct hash_cell *hc, char *new_uuid)
+{
+ mutex_lock(&dm_hash_cells_mutex);
+ hc->uuid = new_uuid;
+ mutex_unlock(&dm_hash_cells_mutex);
+
+ list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_uuid));
+}
+
+/*
+ * Changes the name of a hash_cell and returns the old name for
+ * the caller to free.
+ */
+static char *__change_cell_name(struct hash_cell *hc, char *new_name)
+{
+ char *old_name;
+
+ /*
+ * Rename and move the name cell.
+ */
+ list_del(&hc->name_list);
+ old_name = hc->name;
+
+ mutex_lock(&dm_hash_cells_mutex);
+ hc->name = new_name;
+ mutex_unlock(&dm_hash_cells_mutex);
+
+ list_add(&hc->name_list, _name_buckets + hash_str(new_name));
+
+ return old_name;
+}
+
static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
const char *new)
{
- char *new_name, *old_name;
+ char *new_data, *old_name = NULL;
struct hash_cell *hc;
struct dm_table *table;
struct mapped_device *md;
+ unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0;
/*
* duplicate new.
*/
- new_name = kstrdup(new, GFP_KERNEL);
- if (!new_name)
+ new_data = kstrdup(new, GFP_KERNEL);
+ if (!new_data)
return ERR_PTR(-ENOMEM);
down_write(&_hash_lock);
@@ -315,13 +351,19 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
/*
* Is new free ?
*/
- hc = __get_name_cell(new);
+ if (change_uuid)
+ hc = __get_uuid_cell(new);
+ else
+ hc = __get_name_cell(new);
+
if (hc) {
- DMWARN("asked to rename to an already-existing name %s -> %s",
+ DMWARN("Unable to change %s on mapped device %s to one that "
+ "already exists: %s",
+ change_uuid ? "uuid" : "name",
param->name, new);
dm_put(hc->md);
up_write(&_hash_lock);
- kfree(new_name);
+ kfree(new_data);
return ERR_PTR(-EBUSY);
}
@@ -330,22 +372,30 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
*/
hc = __get_name_cell(param->name);
if (!hc) {
- DMWARN("asked to rename a non-existent device %s -> %s",
- param->name, new);
+ DMWARN("Unable to rename non-existent device, %s to %s%s",
+ param->name, change_uuid ? "uuid " : "", new);
up_write(&_hash_lock);
- kfree(new_name);
+ kfree(new_data);
return ERR_PTR(-ENXIO);
}
/*
- * rename and move the name cell.
+ * Does this device already have a uuid?
*/
- list_del(&hc->name_list);
- old_name = hc->name;
- mutex_lock(&dm_hash_cells_mutex);
- hc->name = new_name;
- mutex_unlock(&dm_hash_cells_mutex);
- list_add(&hc->name_list, _name_buckets + hash_str(new_name));
+ if (change_uuid && hc->uuid) {
+ DMWARN("Unable to change uuid of mapped device %s to %s "
+ "because uuid is already set to %s",
+ param->name, new, hc->uuid);
+ dm_put(hc->md);
+ up_write(&_hash_lock);
+ kfree(new_data);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (change_uuid)
+ __set_cell_uuid(hc, new_data);
+ else
+ old_name = __change_cell_name(hc, new_data);
/*
* Wake up any dm event waiters.
@@ -774,21 +824,24 @@ static int invalid_str(char *str, void *end)
static int dev_rename(struct dm_ioctl *param, size_t param_size)
{
int r;
- char *new_name = (char *) param + param->data_start;
+ char *new_data = (char *) param + param->data_start;
struct mapped_device *md;
+ unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0;
- if (new_name < param->data ||
- invalid_str(new_name, (void *) param + param_size) ||
- strlen(new_name) > DM_NAME_LEN - 1) {
- DMWARN("Invalid new logical volume name supplied.");
+ if (new_data < param->data ||
+ invalid_str(new_data, (void *) param + param_size) ||
+ strlen(new_data) > (change_uuid ? DM_UUID_LEN - 1 : DM_NAME_LEN - 1)) {
+ DMWARN("Invalid new mapped device name or uuid string supplied.");
return -EINVAL;
}
- r = check_name(new_name);
- if (r)
- return r;
+ if (!change_uuid) {
+ r = check_name(new_data);
+ if (r)
+ return r;
+ }
- md = dm_hash_rename(param, new_name);
+ md = dm_hash_rename(param, new_data);
if (IS_ERR(md))
return PTR_ERR(md);
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index d8587bac5682..5ad9231c8700 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -345,7 +345,7 @@ static int run_io_job(struct kcopyd_job *job)
{
int r;
struct dm_io_request io_req = {
- .bi_rw = job->rw | REQ_SYNC | REQ_UNPLUG,
+ .bi_rw = job->rw | REQ_UNPLUG,
.mem.type = DM_IO_PAGE_LIST,
.mem.ptr.pl = job->pages,
.mem.offset = job->offset,
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 1ed0094f064b..1c25ad3d02a2 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -181,8 +181,11 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR,
ctr_str, str_size, NULL, NULL);
- if (r == -ESRCH) {
- DMERR("Userspace log server not found");
+ if (r < 0) {
+ if (r == -ESRCH)
+ DMERR("Userspace log server not found");
+ else
+ DMERR("Userspace log server failed to create log");
goto out;
}
@@ -214,10 +217,9 @@ out:
static void userspace_dtr(struct dm_dirty_log *log)
{
- int r;
struct log_c *lc = log->context;
- r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
+ (void) dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
NULL, 0,
NULL, NULL);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 487ecda90ad4..406091f9692b 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -33,7 +33,6 @@ struct pgpath {
unsigned fail_count; /* Cumulative failure count */
struct dm_path path;
- struct work_struct deactivate_path;
struct work_struct activate_path;
};
@@ -116,7 +115,6 @@ static struct workqueue_struct *kmultipathd, *kmpath_handlerd;
static void process_queued_ios(struct work_struct *work);
static void trigger_event(struct work_struct *work);
static void activate_path(struct work_struct *work);
-static void deactivate_path(struct work_struct *work);
/*-----------------------------------------------
@@ -129,7 +127,6 @@ static struct pgpath *alloc_pgpath(void)
if (pgpath) {
pgpath->is_active = 1;
- INIT_WORK(&pgpath->deactivate_path, deactivate_path);
INIT_WORK(&pgpath->activate_path, activate_path);
}
@@ -141,14 +138,6 @@ static void free_pgpath(struct pgpath *pgpath)
kfree(pgpath);
}
-static void deactivate_path(struct work_struct *work)
-{
- struct pgpath *pgpath =
- container_of(work, struct pgpath, deactivate_path);
-
- blk_abort_queue(pgpath->path.dev->bdev->bd_disk->queue);
-}
-
static struct priority_group *alloc_priority_group(void)
{
struct priority_group *pg;
@@ -995,7 +984,6 @@ static int fail_path(struct pgpath *pgpath)
pgpath->path.dev->name, m->nr_valid_paths);
schedule_work(&m->trigger_event);
- queue_work(kmultipathd, &pgpath->deactivate_path);
out:
spin_unlock_irqrestore(&m->lock, flags);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 19a59b041c27..c87756eb7a21 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -261,7 +261,7 @@ static int mirror_flush(struct dm_target *ti)
struct dm_io_request io_req = {
.bi_rw = WRITE_FLUSH,
.mem.type = DM_IO_KMEM,
- .mem.ptr.bvec = NULL,
+ .mem.ptr.addr = NULL,
.client = ms->io_client,
};
@@ -637,6 +637,12 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
.client = ms->io_client,
};
+ if (bio->bi_rw & REQ_DISCARD) {
+ io_req.bi_rw |= REQ_DISCARD;
+ io_req.mem.type = DM_IO_KMEM;
+ io_req.mem.ptr.addr = NULL;
+ }
+
for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++)
map_region(dest++, m, bio);
@@ -670,7 +676,8 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- if (bio->bi_rw & REQ_FLUSH) {
+ if ((bio->bi_rw & REQ_FLUSH) ||
+ (bio->bi_rw & REQ_DISCARD)) {
bio_list_add(&sync, bio);
continue;
}
@@ -1076,6 +1083,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->private = ms;
ti->split_io = dm_rh_get_region_size(ms->rh);
ti->num_flush_requests = 1;
+ ti->num_discard_requests = 1;
ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
if (!ms->kmirrord_wq) {
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 90267f8d64ee..985c20a4f30e 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -325,15 +325,18 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev,
BUG_ON(d->dm_dev.bdev);
- bdev = open_by_devnum(dev, d->dm_dev.mode);
+ bdev = blkdev_get_by_dev(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr);
if (IS_ERR(bdev))
return PTR_ERR(bdev);
- r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md));
- if (r)
- blkdev_put(bdev, d->dm_dev.mode);
- else
- d->dm_dev.bdev = bdev;
- return r;
+
+ r = bd_link_disk_holder(bdev, dm_disk(md));
+ if (r) {
+ blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL);
+ return r;
+ }
+
+ d->dm_dev.bdev = bdev;
+ return 0;
}
/*
@@ -344,8 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
if (!d->dm_dev.bdev)
return;
- bd_release_from_disk(d->dm_dev.bdev, dm_disk(md));
- blkdev_put(d->dm_dev.bdev, d->dm_dev.mode);
+ blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL);
d->dm_dev.bdev = NULL;
}
@@ -517,9 +519,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
*/
if (q->merge_bvec_fn && !ti->type->merge)
- limits->max_sectors =
- min_not_zero(limits->max_sectors,
- (unsigned int) (PAGE_SIZE >> 9));
+ blk_limits_max_hw_sectors(limits,
+ (unsigned int) (PAGE_SIZE >> 9));
return 0;
}
EXPORT_SYMBOL_GPL(dm_set_device_limits);
@@ -1131,11 +1132,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
*/
q->limits = *limits;
- if (limits->no_cluster)
- queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
- else
- queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
-
if (!dm_table_supports_discards(t))
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
else
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7cb1352f7e7a..0a3ee08c1a89 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -32,7 +32,6 @@
#define DM_COOKIE_ENV_VAR_NAME "DM_COOKIE"
#define DM_COOKIE_LENGTH 24
-static DEFINE_MUTEX(dm_mutex);
static const char *_name = DM_NAME;
static unsigned int major = 0;
@@ -328,7 +327,6 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode)
{
struct mapped_device *md;
- mutex_lock(&dm_mutex);
spin_lock(&_minor_lock);
md = bdev->bd_disk->private_data;
@@ -346,7 +344,6 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode)
out:
spin_unlock(&_minor_lock);
- mutex_unlock(&dm_mutex);
return md ? 0 : -ENXIO;
}
@@ -355,10 +352,12 @@ static int dm_blk_close(struct gendisk *disk, fmode_t mode)
{
struct mapped_device *md = disk->private_data;
- mutex_lock(&dm_mutex);
+ spin_lock(&_minor_lock);
+
atomic_dec(&md->open_count);
dm_put(md);
- mutex_unlock(&dm_mutex);
+
+ spin_unlock(&_minor_lock);
return 0;
}
@@ -990,8 +989,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
if (r == DM_MAPIO_REMAPPED) {
/* the bio has been remapped so dispatch it */
- trace_block_remap(bdev_get_queue(clone->bi_bdev), clone,
- tio->io->bio->bi_bdev->bd_dev, sector);
+ trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone,
+ tio->io->bio->bi_bdev->bd_dev, sector);
generic_make_request(clone);
} else if (r < 0 || r == DM_MAPIO_REQUEUE) {
@@ -1992,13 +1991,14 @@ static void event_callback(void *context)
wake_up(&md->eventq);
}
+/*
+ * Protected by md->suspend_lock obtained by dm_swap_table().
+ */
static void __set_size(struct mapped_device *md, sector_t size)
{
set_capacity(md->disk, size);
- mutex_lock(&md->bdev->bd_inode->i_mutex);
i_size_write(md->bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
- mutex_unlock(&md->bdev->bd_inode->i_mutex);
}
/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 84c46a161927..7fc090ac9e28 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err)
bio_put(bio);
}
-static void submit_flushes(mddev_t *mddev)
+static void md_submit_flush_data(struct work_struct *ws);
+
+static void submit_flushes(struct work_struct *ws)
{
+ mddev_t *mddev = container_of(ws, mddev_t, flush_work);
mdk_rdev_t *rdev;
+ INIT_WORK(&mddev->flush_work, md_submit_flush_data);
+ atomic_set(&mddev->flush_pending, 1);
rcu_read_lock();
list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev)
rdev_dec_pending(rdev, mddev);
}
rcu_read_unlock();
+ if (atomic_dec_and_test(&mddev->flush_pending))
+ queue_work(md_wq, &mddev->flush_work);
}
static void md_submit_flush_data(struct work_struct *ws)
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws)
mddev_t *mddev = container_of(ws, mddev_t, flush_work);
struct bio *bio = mddev->flush_bio;
- atomic_set(&mddev->flush_pending, 1);
-
if (bio->bi_size == 0)
/* an empty barrier - all done */
bio_endio(bio, 0);
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws)
if (mddev->pers->make_request(mddev, bio))
generic_make_request(bio);
}
- if (atomic_dec_and_test(&mddev->flush_pending)) {
- mddev->flush_bio = NULL;
- wake_up(&mddev->sb_wait);
- }
+
+ mddev->flush_bio = NULL;
+ wake_up(&mddev->sb_wait);
}
void md_flush_request(mddev_t *mddev, struct bio *bio)
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
mddev->flush_bio = bio;
spin_unlock_irq(&mddev->write_lock);
- atomic_set(&mddev->flush_pending, 1);
- INIT_WORK(&mddev->flush_work, md_submit_flush_data);
-
- submit_flushes(mddev);
-
- if (atomic_dec_and_test(&mddev->flush_pending))
- queue_work(md_wq, &mddev->flush_work);
+ INIT_WORK(&mddev->flush_work, submit_flushes);
+ queue_work(md_wq, &mddev->flush_work);
}
EXPORT_SYMBOL(md_flush_request);
@@ -1880,7 +1879,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state");
list_add_rcu(&rdev->same_set, &mddev->disks);
- bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk);
+ bd_link_disk_holder(rdev->bdev, mddev->gendisk);
/* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0;
@@ -1907,7 +1906,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
MD_BUG();
return;
}
- bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk);
list_del_rcu(&rdev->same_set);
printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
rdev->mddev = NULL;
@@ -1935,19 +1933,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
struct block_device *bdev;
char b[BDEVNAME_SIZE];
- bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+ bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
+ shared ? (mdk_rdev_t *)lock_rdev : rdev);
if (IS_ERR(bdev)) {
printk(KERN_ERR "md: could not open %s.\n",
__bdevname(dev, b));
return PTR_ERR(bdev);
}
- err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev);
- if (err) {
- printk(KERN_ERR "md: could not bd_claim %s.\n",
- bdevname(bdev, b));
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
- return err;
- }
if (!shared)
set_bit(AllReserved, &rdev->flags);
rdev->bdev = bdev;
@@ -1960,8 +1952,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
rdev->bdev = NULL;
if (!bdev)
MD_BUG();
- bd_release(bdev);
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
void md_autodetect_dev(dev_t dev);
@@ -4296,9 +4287,6 @@ static int md_alloc(dev_t dev, char *name)
goto abort;
mddev->queue->queuedata = mddev;
- /* Can be unlocked because the queue is new: no concurrency */
- queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
-
blk_queue_make_request(mddev->queue, md_make_request);
disk = alloc_disk(1 << shift);
@@ -5160,7 +5148,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
PTR_ERR(rdev));
return PTR_ERR(rdev);
}
- /* set save_raid_disk if appropriate */
+ /* set saved_raid_disk if appropriate */
if (!mddev->persistent) {
if (info->state & (1<<MD_DISK_SYNC) &&
info->raid_disk < mddev->raid_disks)
@@ -5170,7 +5158,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
} else
super_types[mddev->major_version].
validate_super(mddev, rdev);
- rdev->saved_raid_disk = rdev->raid_disk;
+ if (test_bit(In_sync, &rdev->flags))
+ rdev->saved_raid_disk = rdev->raid_disk;
+ else
+ rdev->saved_raid_disk = -1;
clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
@@ -6042,9 +6033,8 @@ static int md_thread(void * arg)
|| kthread_should_stop(),
thread->timeout);
- clear_bit(THREAD_WAKEUP, &thread->flags);
-
- thread->run(thread->mddev);
+ if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+ thread->run(thread->mddev);
}
return 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c67aa54694ae..0641674827f0 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev)
return 0;
out_free_conf:
+ md_unregister_thread(mddev->thread);
if (conf->r10bio_pool)
mempool_destroy(conf->r10bio_pool);
safe_put_page(conf->tmppage);
kfree(conf->mirrors);
kfree(conf);
mddev->private = NULL;
- md_unregister_thread(mddev->thread);
out:
return -EIO;
}
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
deleted file mode 100644
index db591e421887..000000000000
--- a/drivers/media/IR/ir-functions.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or 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/string.h>
-#include <linux/jiffies.h>
-#include <media/ir-common.h>
-#include "ir-core-priv.h"
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static int repeat = 1;
-module_param(repeat, int, 0444);
-MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
-
-/* -------------------------------------------------------------------------- */
-
-static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
-{
- if (KEY_RESERVED == ir->keycode) {
- printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
- dev->name, ir->ir_key, ir->keypressed);
- return;
- }
- IR_dprintk(1,"%s: key event code=%d down=%d\n",
- dev->name,ir->keycode,ir->keypressed);
- input_report_key(dev,ir->keycode,ir->keypressed);
- input_sync(dev);
-}
-
-/* -------------------------------------------------------------------------- */
-
-int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
- const u64 ir_type)
-{
- ir->ir_type = ir_type;
-
- if (repeat)
- set_bit(EV_REP, dev->evbit);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_input_init);
-
-
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
-{
- if (ir->keypressed) {
- ir->keypressed = 0;
- ir_input_key_event(dev,ir);
- }
-}
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
- u32 ir_key)
-{
- u32 keycode = ir_g_keycode_from_table(dev, ir_key);
-
- if (ir->keypressed && ir->keycode != keycode) {
- ir->keypressed = 0;
- ir_input_key_event(dev,ir);
- }
- if (!ir->keypressed) {
- ir->ir_key = ir_key;
- ir->keycode = keycode;
- ir->keypressed = 1;
- ir_input_key_event(dev,ir);
- }
-}
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-/* -------------------------------------------------------------------------- */
-/* extract mask bits out of data and pack them into the result */
-u32 ir_extract_bits(u32 data, u32 mask)
-{
- u32 vbit = 1, value = 0;
-
- do {
- if (mask&1) {
- if (data&1)
- value |= vbit;
- vbit<<=1;
- }
- data>>=1;
- } while (mask>>=1);
-
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-
-static int inline getbit(u32 *samples, int bit)
-{
- return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
-}
-
-/* sump raw samples for visual debugging ;) */
-int ir_dump_samples(u32 *samples, int count)
-{
- int i, bit, start;
-
- printk(KERN_DEBUG "ir samples: ");
- start = 0;
- for (i = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit)
- start = 1;
- if (0 == start)
- continue;
- printk("%s", bit ? "#" : "_");
- }
- printk("\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-
-/* decode raw samples, pulse distance coding used by NEC remotes */
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
-{
- int i,last,bit,len;
- u32 curBit;
- u32 value;
-
- /* find start burst */
- for (i = len = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit) {
- len++;
- } else {
- if (len >= 29)
- break;
- len = 0;
- }
- }
-
- /* start burst to short */
- if (len < 29)
- return 0xffffffff;
-
- /* find start silence */
- for (len = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit) {
- break;
- } else {
- len++;
- }
- }
-
- /* silence to short */
- if (len < 7)
- return 0xffffffff;
-
- /* go decoding */
- len = 0;
- last = 1;
- value = 0; curBit = 1;
- for (; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (last) {
- if(bit) {
- continue;
- } else {
- len = 1;
- }
- } else {
- if (bit) {
- if (len > (low + high) /2)
- value |= curBit;
- curBit <<= 1;
- if (curBit == 1)
- break;
- } else {
- len++;
- }
- }
- last = bit;
- }
-
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-/* decode raw samples, biphase coding, used by rc5 for example */
-int ir_decode_biphase(u32 *samples, int count, int low, int high)
-{
- int i,last,bit,len,flips;
- u32 value;
-
- /* find start bit (1) */
- for (i = 0; i < 32; i++) {
- bit = getbit(samples,i);
- if (bit)
- break;
- }
-
- /* go decoding */
- len = 0;
- flips = 0;
- value = 1;
- for (; i < count * 32; i++) {
- if (len > high)
- break;
- if (flips > 1)
- break;
- last = bit;
- bit = getbit(samples,i);
- if (last == bit) {
- len++;
- continue;
- }
- if (len < low) {
- len++;
- flips++;
- continue;
- }
- value <<= 1;
- value |= bit;
- flips = 0;
- len = 1;
- }
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-
-/* RC5 decoding stuff, moved from bttv-input.c to share it with
- * saa7134 */
-
-/* decode raw bit pattern to RC5 code */
-u32 ir_rc5_decode(unsigned int code)
-{
- unsigned int org_code = code;
- unsigned int pair;
- unsigned int rc5 = 0;
- int i;
-
- for (i = 0; i < 14; ++i) {
- pair = code & 0x3;
- code >>= 2;
-
- rc5 <<= 1;
- switch (pair) {
- case 0:
- case 2:
- break;
- case 1:
- rc5 |= 1;
- break;
- case 3:
- IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
- return 0;
- }
- }
- IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
- "instr=%x\n", rc5, org_code, RC5_START(rc5),
- RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
- return rc5;
-}
-EXPORT_SYMBOL_GPL(ir_rc5_decode);
-
-void ir_rc5_timer_end(unsigned long data)
-{
- struct card_ir *ir = (struct card_ir *)data;
- struct timeval tv;
- unsigned long current_jiffies, timeout;
- u32 gap;
- u32 rc5 = 0;
-
- /* get time */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* signal we're ready to start a new code */
- ir->active = 0;
-
- /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
- if (gap < 28000) {
- IR_dprintk(1, "ir-common: spurious timer_end\n");
- return;
- }
-
- if (ir->last_bit < 20) {
- /* ignore spurious codes (caused by light/other remotes) */
- IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
- } else {
- ir->code = (ir->code << ir->shift_by) | 1;
- rc5 = ir_rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != ir->start) {
- IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == ir->addr) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code, decide if repeat/repress */
- if (toggle != RC5_TOGGLE(ir->last_rc5) ||
- instr != RC5_INSTR(ir->last_rc5)) {
- IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
- toggle);
- ir_input_nokey(ir->dev, &ir->ir);
- ir_input_keydown(ir->dev, &ir->ir, instr);
- }
-
- /* Set/reset key-up timer */
- timeout = current_jiffies +
- msecs_to_jiffies(ir->rc5_key_timeout);
- mod_timer(&ir->timer_keyup, timeout);
-
- /* Save code for repeat test */
- ir->last_rc5 = rc5;
- }
- }
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
-
-void ir_rc5_timer_keyup(unsigned long data)
-{
- struct card_ir *ir = (struct card_ir *)data;
-
- IR_dprintk(1, "ir-common: key released\n");
- ir_input_nokey(ir->dev, &ir->ir);
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
deleted file mode 100644
index f60107c3b091..000000000000
--- a/drivers/media/IR/ir-keytable.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/* ir-keytable.c - handle IR scancode->keycode tables
- *
- * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include "ir-core-priv.h"
-
-/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
-#define IR_TAB_MIN_SIZE 256
-#define IR_TAB_MAX_SIZE 8192
-
-/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
-#define IR_KEYPRESS_TIMEOUT 250
-
-/**
- * ir_create_table() - initializes a scancode table
- * @rc_tab: the ir_scancode_table to initialize
- * @name: name to assign to the table
- * @ir_type: ir type to assign to the new table
- * @size: initial size of the table
- * @return: zero on success or a negative error code
- *
- * This routine will initialize the ir_scancode_table and will allocate
- * memory to hold at least the specified number elements.
- */
-static int ir_create_table(struct ir_scancode_table *rc_tab,
- const char *name, u64 ir_type, size_t size)
-{
- rc_tab->name = name;
- rc_tab->ir_type = ir_type;
- rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode));
- rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
- rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL);
- if (!rc_tab->scan)
- return -ENOMEM;
-
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- rc_tab->size, rc_tab->alloc);
- return 0;
-}
-
-/**
- * ir_free_table() - frees memory allocated by a scancode table
- * @rc_tab: the table whose mappings need to be freed
- *
- * This routine will free memory alloctaed for key mappings used by given
- * scancode table.
- */
-static void ir_free_table(struct ir_scancode_table *rc_tab)
-{
- rc_tab->size = 0;
- kfree(rc_tab->scan);
- rc_tab->scan = NULL;
-}
-
-/**
- * ir_resize_table() - resizes a scancode table if necessary
- * @rc_tab: the ir_scancode_table to resize
- * @gfp_flags: gfp flags to use when allocating memory
- * @return: zero on success or a negative error code
- *
- * This routine will shrink the ir_scancode_table if it has lots of
- * unused entries and grow it if it is full.
- */
-static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags)
-{
- unsigned int oldalloc = rc_tab->alloc;
- unsigned int newalloc = oldalloc;
- struct ir_scancode *oldscan = rc_tab->scan;
- struct ir_scancode *newscan;
-
- if (rc_tab->size == rc_tab->len) {
- /* All entries in use -> grow keytable */
- if (rc_tab->alloc >= IR_TAB_MAX_SIZE)
- return -ENOMEM;
-
- newalloc *= 2;
- IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
- }
-
- if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
- /* Less than 1/3 of entries in use -> shrink keytable */
- newalloc /= 2;
- IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
- }
-
- if (newalloc == oldalloc)
- return 0;
-
- newscan = kmalloc(newalloc, gfp_flags);
- if (!newscan) {
- IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
- return -ENOMEM;
- }
-
- memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode));
- rc_tab->scan = newscan;
- rc_tab->alloc = newalloc;
- rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
- kfree(oldscan);
- return 0;
-}
-
-/**
- * ir_update_mapping() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @rc_tab: scancode table to be adjusted
- * @index: index of the mapping that needs to be updated
- * @keycode: the desired keycode
- * @return: previous keycode assigned to the mapping
- *
- * This routine is used to update scancode->keycopde mapping at given
- * position.
- */
-static unsigned int ir_update_mapping(struct input_dev *dev,
- struct ir_scancode_table *rc_tab,
- unsigned int index,
- unsigned int new_keycode)
-{
- int old_keycode = rc_tab->scan[index].keycode;
- int i;
-
- /* Did the user wish to remove the mapping? */
- if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
- IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
- index, rc_tab->scan[index].scancode);
- rc_tab->len--;
- memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1],
- (rc_tab->len - index) * sizeof(struct ir_scancode));
- } else {
- IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
- index,
- old_keycode == KEY_RESERVED ? "New" : "Replacing",
- rc_tab->scan[index].scancode, new_keycode);
- rc_tab->scan[index].keycode = new_keycode;
- __set_bit(new_keycode, dev->keybit);
- }
-
- if (old_keycode != KEY_RESERVED) {
- /* A previous mapping was updated... */
- __clear_bit(old_keycode, dev->keybit);
- /* ... but another scancode might use the same keycode */
- for (i = 0; i < rc_tab->len; i++) {
- if (rc_tab->scan[i].keycode == old_keycode) {
- __set_bit(old_keycode, dev->keybit);
- break;
- }
- }
-
- /* Possibly shrink the keytable, failure is not a problem */
- ir_resize_table(rc_tab, GFP_ATOMIC);
- }
-
- return old_keycode;
-}
-
-/**
- * ir_locate_scancode() - set a keycode in the scancode->keycode table
- * @ir_dev: the struct ir_input_dev device descriptor
- * @rc_tab: scancode table to be searched
- * @scancode: the desired scancode
- * @resize: controls whether we allowed to resize the table to
- * accomodate not yet present scancodes
- * @return: index of the mapping containing scancode in question
- * or -1U in case of failure.
- *
- * This routine is used to locate given scancode in ir_scancode_table.
- * If scancode is not yet present the routine will allocate a new slot
- * for it.
- */
-static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
- struct ir_scancode_table *rc_tab,
- unsigned int scancode,
- bool resize)
-{
- unsigned int i;
-
- /*
- * Unfortunately, some hardware-based IR decoders don't provide
- * all bits for the complete IR code. In general, they provide only
- * the command part of the IR code. Yet, as it is possible to replace
- * the provided IR with another one, it is needed to allow loading
- * IR tables from other remotes. So,
- */
- if (ir_dev->props && ir_dev->props->scanmask)
- scancode &= ir_dev->props->scanmask;
-
- /* First check if we already have a mapping for this ir command */
- for (i = 0; i < rc_tab->len; i++) {
- if (rc_tab->scan[i].scancode == scancode)
- return i;
-
- /* Keytable is sorted from lowest to highest scancode */
- if (rc_tab->scan[i].scancode >= scancode)
- break;
- }
-
- /* No previous mapping found, we might need to grow the table */
- if (rc_tab->size == rc_tab->len) {
- if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC))
- return -1U;
- }
-
- /* i is the proper index to insert our new keycode */
- if (i < rc_tab->len)
- memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
- (rc_tab->len - i) * sizeof(struct ir_scancode));
- rc_tab->scan[i].scancode = scancode;
- rc_tab->scan[i].keycode = KEY_RESERVED;
- rc_tab->len++;
-
- return i;
-}
-
-/**
- * ir_setkeycode() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: result
- * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
- *
- * This routine is used to handle evdev EVIOCSKEY ioctl.
- */
-static int ir_setkeycode(struct input_dev *dev,
- const struct input_keymap_entry *ke,
- unsigned int *old_keycode)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int index;
- unsigned int scancode;
- int retval;
- unsigned long flags;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
- index = ke->index;
- if (index >= rc_tab->len) {
- retval = -EINVAL;
- goto out;
- }
- } else {
- retval = input_scancode_to_scalar(ke, &scancode);
- if (retval)
- goto out;
-
- index = ir_establish_scancode(ir_dev, rc_tab, scancode, true);
- if (index >= rc_tab->len) {
- retval = -ENOMEM;
- goto out;
- }
- }
-
- *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode);
-
-out:
- spin_unlock_irqrestore(&rc_tab->lock, flags);
- return retval;
-}
-
-/**
- * ir_setkeytable() - sets several entries in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @to: the struct ir_scancode_table to copy entries to
- * @from: the struct ir_scancode_table to copy entries from
- * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
- *
- * This routine is used to handle table initialization.
- */
-static int ir_setkeytable(struct ir_input_dev *ir_dev,
- const struct ir_scancode_table *from)
-{
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int i, index;
- int rc;
-
- rc = ir_create_table(&ir_dev->rc_tab,
- from->name, from->ir_type, from->size);
- if (rc)
- return rc;
-
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- rc_tab->size, rc_tab->alloc);
-
- for (i = 0; i < from->size; i++) {
- index = ir_establish_scancode(ir_dev, rc_tab,
- from->scan[i].scancode, false);
- if (index >= rc_tab->len) {
- rc = -ENOMEM;
- break;
- }
-
- ir_update_mapping(ir_dev->input_dev, rc_tab, index,
- from->scan[i].keycode);
- }
-
- if (rc)
- ir_free_table(rc_tab);
-
- return rc;
-}
-
-/**
- * ir_lookup_by_scancode() - locate mapping by scancode
- * @rc_tab: the &struct ir_scancode_table to search
- * @scancode: scancode to look for in the table
- * @return: index in the table, -1U if not found
- *
- * This routine performs binary search in RC keykeymap table for
- * given scancode.
- */
-static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab,
- unsigned int scancode)
-{
- int start = 0;
- int end = rc_tab->len - 1;
- int mid;
-
- while (start <= end) {
- mid = (start + end) / 2;
- if (rc_tab->scan[mid].scancode < scancode)
- start = mid + 1;
- else if (rc_tab->scan[mid].scancode > scancode)
- end = mid - 1;
- else
- return mid;
- }
-
- return -1U;
-}
-
-/**
- * ir_getkeycode() - get a keycode from the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: used to return the keycode, if found, or KEY_RESERVED
- * @return: always returns zero.
- *
- * This routine is used to handle evdev EVIOCGKEY ioctl.
- */
-static int ir_getkeycode(struct input_dev *dev,
- struct input_keymap_entry *ke)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- struct ir_scancode *entry;
- unsigned long flags;
- unsigned int index;
- unsigned int scancode;
- int retval;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
- index = ke->index;
- } else {
- retval = input_scancode_to_scalar(ke, &scancode);
- if (retval)
- goto out;
-
- index = ir_lookup_by_scancode(rc_tab, scancode);
- }
-
- if (index >= rc_tab->len) {
- if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
- IR_dprintk(1, "unknown key for scancode 0x%04x\n",
- scancode);
- retval = -EINVAL;
- goto out;
- }
-
- entry = &rc_tab->scan[index];
-
- ke->index = index;
- ke->keycode = entry->keycode;
- ke->len = sizeof(entry->scancode);
- memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
-
- retval = 0;
-
-out:
- spin_unlock_irqrestore(&rc_tab->lock, flags);
- return retval;
-}
-
-/**
- * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
- * @input_dev: the struct input_dev descriptor of the device
- * @scancode: the scancode that we're seeking
- *
- * This routine is used by the input routines when a key is pressed at the
- * IR. The scancode is received and needs to be converted into a keycode.
- * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
- * corresponding keycode from the table.
- */
-u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int keycode;
- unsigned int index;
- unsigned long flags;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- index = ir_lookup_by_scancode(rc_tab, scancode);
- keycode = index < rc_tab->len ?
- rc_tab->scan[index].keycode : KEY_RESERVED;
-
- spin_unlock_irqrestore(&rc_tab->lock, flags);
-
- if (keycode != KEY_RESERVED)
- IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
- dev->name, scancode, keycode);
-
- return keycode;
-}
-EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
-
-/**
- * ir_keyup() - generates input event to cleanup a key press
- * @ir: the struct ir_input_dev descriptor of the device
- *
- * This routine is used to signal that a key has been released on the
- * remote control. It reports a keyup input event via input_report_key().
- */
-void ir_keyup(struct ir_input_dev *ir)
-{
- if (!ir->keypressed)
- return;
-
- IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
- input_report_key(ir->input_dev, ir->last_keycode, 0);
- input_sync(ir->input_dev);
- ir->keypressed = false;
-}
-EXPORT_SYMBOL_GPL(ir_keyup);
-
-/**
- * ir_timer_keyup() - generates a keyup event after a timeout
- * @cookie: a pointer to struct ir_input_dev passed to setup_timer()
- *
- * This routine will generate a keyup event some time after a keydown event
- * is generated when no further activity has been detected.
- */
-static void ir_timer_keyup(unsigned long cookie)
-{
- struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
- unsigned long flags;
-
- /*
- * ir->keyup_jiffies is used to prevent a race condition if a
- * hardware interrupt occurs at this point and the keyup timer
- * event is moved further into the future as a result.
- *
- * The timer will then be reactivated and this function called
- * again in the future. We need to exit gracefully in that case
- * to allow the input subsystem to do its auto-repeat magic or
- * a keyup event might follow immediately after the keydown.
- */
- spin_lock_irqsave(&ir->keylock, flags);
- if (time_is_before_eq_jiffies(ir->keyup_jiffies))
- ir_keyup(ir);
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-
-/**
- * ir_repeat() - notifies the IR core that a key is still pressed
- * @dev: the struct input_dev descriptor of the device
- *
- * This routine is used by IR decoders when a repeat message which does
- * not include the necessary bits to reproduce the scancode has been
- * received.
- */
-void ir_repeat(struct input_dev *dev)
-{
- unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
-
- spin_lock_irqsave(&ir->keylock, flags);
-
- input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode);
-
- if (!ir->keypressed)
- goto out;
-
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
-
-out:
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-EXPORT_SYMBOL_GPL(ir_repeat);
-
-/**
- * ir_keydown() - generates input event for a key press
- * @dev: the struct input_dev descriptor of the device
- * @scancode: the scancode that we're seeking
- * @toggle: the toggle value (protocol dependent, if the protocol doesn't
- * support toggle values, this should be set to zero)
- *
- * This routine is used by the input routines when a key is pressed at the
- * IR. It gets the keycode for a scancode and reports an input event via
- * input_report_key().
- */
-void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
-{
- unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
-
- u32 keycode = ir_g_keycode_from_table(dev, scancode);
-
- spin_lock_irqsave(&ir->keylock, flags);
-
- input_event(dev, EV_MSC, MSC_SCAN, scancode);
-
- /* Repeat event? */
- if (ir->keypressed &&
- ir->last_scancode == scancode &&
- ir->last_toggle == toggle)
- goto set_timer;
-
- /* Release old keypress */
- ir_keyup(ir);
-
- ir->last_scancode = scancode;
- ir->last_toggle = toggle;
- ir->last_keycode = keycode;
-
-
- if (keycode == KEY_RESERVED)
- goto out;
-
-
- /* Register a keypress */
- ir->keypressed = true;
- IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
- dev->name, keycode, scancode);
- input_report_key(dev, ir->last_keycode, 1);
- input_sync(dev);
-
-set_timer:
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
-out:
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-EXPORT_SYMBOL_GPL(ir_keydown);
-
-static int ir_open(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- return ir_dev->props->open(ir_dev->props->priv);
-}
-
-static void ir_close(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- ir_dev->props->close(ir_dev->props->priv);
-}
-
-/**
- * __ir_input_register() - sets the IR keycode table and add the handlers
- * for keymap table get/set
- * @input_dev: the struct input_dev descriptor of the device
- * @rc_tab: the struct ir_scancode_table table of scancode/keymap
- *
- * This routine is used to initialize the input infrastructure
- * to work with an IR.
- * It will register the input/evdev interface for the device and
- * register the syfs code for IR class
- */
-int __ir_input_register(struct input_dev *input_dev,
- const struct ir_scancode_table *rc_tab,
- struct ir_dev_props *props,
- const char *driver_name)
-{
- struct ir_input_dev *ir_dev;
- int rc;
-
- if (rc_tab->scan == NULL || !rc_tab->size)
- return -EINVAL;
-
- ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
- if (!ir_dev)
- return -ENOMEM;
-
- ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name);
- if (!ir_dev->driver_name) {
- rc = -ENOMEM;
- goto out_dev;
- }
-
- input_dev->getkeycode_new = ir_getkeycode;
- input_dev->setkeycode_new = ir_setkeycode;
- input_set_drvdata(input_dev, ir_dev);
- ir_dev->input_dev = input_dev;
-
- spin_lock_init(&ir_dev->rc_tab.lock);
- spin_lock_init(&ir_dev->keylock);
- setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
-
- if (props) {
- ir_dev->props = props;
- if (props->open)
- input_dev->open = ir_open;
- if (props->close)
- input_dev->close = ir_close;
- }
-
- set_bit(EV_KEY, input_dev->evbit);
- set_bit(EV_REP, input_dev->evbit);
- set_bit(EV_MSC, input_dev->evbit);
- set_bit(MSC_SCAN, input_dev->mscbit);
-
- rc = ir_setkeytable(ir_dev, rc_tab);
- if (rc)
- goto out_name;
-
- rc = ir_register_class(input_dev);
- if (rc < 0)
- goto out_table;
-
- if (ir_dev->props)
- if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
- rc = ir_raw_event_register(input_dev);
- if (rc < 0)
- goto out_event;
- }
-
- rc = ir_register_input(input_dev);
- if (rc < 0)
- goto out_event;
-
- IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
- driver_name, rc_tab->name,
- (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
- " in raw mode" : "");
-
- /*
- * Default delay of 250ms is too short for some protocols, expecially
- * since the timeout is currently set to 250ms. Increase it to 500ms,
- * to avoid wrong repetition of the keycodes.
- */
- input_dev->rep[REP_DELAY] = 500;
-
- return 0;
-
-out_event:
- ir_unregister_class(input_dev);
-out_table:
- ir_free_table(&ir_dev->rc_tab);
-out_name:
- kfree(ir_dev->driver_name);
-out_dev:
- kfree(ir_dev);
- return rc;
-}
-EXPORT_SYMBOL_GPL(__ir_input_register);
-
-/**
- * ir_input_unregister() - unregisters IR and frees resources
- * @input_dev: the struct input_dev descriptor of the device
-
- * This routine is used to free memory and de-register interfaces.
- */
-void ir_input_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- if (!ir_dev)
- return;
-
- IR_dprintk(1, "Freed keycode table\n");
-
- del_timer_sync(&ir_dev->timer_keyup);
- if (ir_dev->props)
- if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
- ir_raw_event_unregister(input_dev);
-
- ir_free_table(&ir_dev->rc_tab);
-
- ir_unregister_class(input_dev);
-
- kfree(ir_dev->driver_name);
- kfree(ir_dev);
-}
-EXPORT_SYMBOL_GPL(ir_input_unregister);
-
-int ir_core_debug; /* ir_debug level (0,1,2) */
-EXPORT_SYMBOL_GPL(ir_core_debug);
-module_param_named(debug, ir_core_debug, int, 0644);
-
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
deleted file mode 100644
index 38423a8da871..000000000000
--- a/drivers/media/IR/ir-sysfs.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
- *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/device.h>
-#include "ir-core-priv.h"
-
-#define IRRCV_NUM_DEVICES 256
-
-/* bit array to represent IR sysfs device number */
-static unsigned long ir_core_dev_number;
-
-/* class for /sys/class/rc */
-static char *ir_devnode(struct device *dev, mode_t *mode)
-{
- return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
-}
-
-static struct class ir_input_class = {
- .name = "rc",
- .devnode = ir_devnode,
-};
-
-static struct {
- u64 type;
- char *name;
-} proto_names[] = {
- { IR_TYPE_UNKNOWN, "unknown" },
- { IR_TYPE_RC5, "rc-5" },
- { IR_TYPE_NEC, "nec" },
- { IR_TYPE_RC6, "rc-6" },
- { IR_TYPE_JVC, "jvc" },
- { IR_TYPE_SONY, "sony" },
- { IR_TYPE_RC5_SZ, "rc-5-sz" },
- { IR_TYPE_LIRC, "lirc" },
-};
-
-#define PROTO_NONE "none"
-
-/**
- * show_protocols() - shows the current IR protocol(s)
- * @d: the device descriptor
- * @mattr: the device attribute struct (unused)
- * @buf: a pointer to the output buffer
- *
- * This routine is a callback routine for input read the IR protocol type(s).
- * it is trigged by reading /sys/class/rc/rc?/protocols.
- * It returns the protocol names of supported protocols.
- * Enabled protocols are printed in brackets.
- */
-static ssize_t show_protocols(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- u64 allowed, enabled;
- char *tmp = buf;
- int i;
-
- /* Device is being removed */
- if (!ir_dev)
- return -EINVAL;
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- enabled = ir_dev->rc_tab.ir_type;
- allowed = ir_dev->props->allowed_protos;
- } else if (ir_dev->raw) {
- enabled = ir_dev->raw->enabled_protocols;
- allowed = ir_raw_get_allowed_protocols();
- } else
- return sprintf(tmp, "[builtin]\n");
-
- IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
- (long long)allowed,
- (long long)enabled);
-
- for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
- if (allowed & enabled & proto_names[i].type)
- tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
- else if (allowed & proto_names[i].type)
- tmp += sprintf(tmp, "%s ", proto_names[i].name);
- }
-
- if (tmp != buf)
- tmp--;
- *tmp = '\n';
- return tmp + 1 - buf;
-}
-
-/**
- * store_protocols() - changes the current IR protocol(s)
- * @d: the device descriptor
- * @mattr: the device attribute struct (unused)
- * @buf: a pointer to the input buffer
- * @len: length of the input buffer
- *
- * This routine is a callback routine for changing the IR protocol type.
- * It is trigged by writing to /sys/class/rc/rc?/protocols.
- * Writing "+proto" will add a protocol to the list of enabled protocols.
- * Writing "-proto" will remove a protocol from the list of enabled protocols.
- * Writing "proto" will enable only "proto".
- * Writing "none" will disable all protocols.
- * Returns -EINVAL if an invalid protocol combination or unknown protocol name
- * is used, otherwise @len.
- */
-static ssize_t store_protocols(struct device *d,
- struct device_attribute *mattr,
- const char *data,
- size_t len)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- bool enable, disable;
- const char *tmp;
- u64 type;
- u64 mask;
- int rc, i, count = 0;
- unsigned long flags;
-
- /* Device is being removed */
- if (!ir_dev)
- return -EINVAL;
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
- type = ir_dev->rc_tab.ir_type;
- else if (ir_dev->raw)
- type = ir_dev->raw->enabled_protocols;
- else {
- IR_dprintk(1, "Protocol switching not supported\n");
- return -EINVAL;
- }
-
- while ((tmp = strsep((char **) &data, " \n")) != NULL) {
- if (!*tmp)
- break;
-
- if (*tmp == '+') {
- enable = true;
- disable = false;
- tmp++;
- } else if (*tmp == '-') {
- enable = false;
- disable = true;
- tmp++;
- } else {
- enable = false;
- disable = false;
- }
-
- if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
- tmp += sizeof(PROTO_NONE);
- mask = 0;
- count++;
- } else {
- for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
- if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
- tmp += strlen(proto_names[i].name);
- mask = proto_names[i].type;
- break;
- }
- }
- if (i == ARRAY_SIZE(proto_names)) {
- IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
- return -EINVAL;
- }
- count++;
- }
-
- if (enable)
- type |= mask;
- else if (disable)
- type &= ~mask;
- else
- type = mask;
- }
-
- if (!count) {
- IR_dprintk(1, "Protocol not specified\n");
- return -EINVAL;
- }
-
- if (ir_dev->props && ir_dev->props->change_protocol) {
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- type);
- if (rc < 0) {
- IR_dprintk(1, "Error setting protocols to 0x%llx\n",
- (long long)type);
- return -EINVAL;
- }
- }
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
- ir_dev->rc_tab.ir_type = type;
- spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
- } else {
- ir_dev->raw->enabled_protocols = type;
- }
-
- IR_dprintk(1, "Current protocol(s): 0x%llx\n",
- (long long)type);
-
- return len;
-}
-
-#define ADD_HOTPLUG_VAR(fmt, val...) \
- do { \
- int err = add_uevent_var(env, fmt, val); \
- if (err) \
- return err; \
- } while (0)
-
-static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(device);
-
- if (ir_dev->rc_tab.name)
- ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
- if (ir_dev->driver_name)
- ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
-
- return 0;
-}
-
-/*
- * Static device attribute struct with the sysfs attributes for IR's
- */
-static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
- show_protocols, store_protocols);
-
-static struct attribute *rc_dev_attrs[] = {
- &dev_attr_protocols.attr,
- NULL,
-};
-
-static struct attribute_group rc_dev_attr_grp = {
- .attrs = rc_dev_attrs,
-};
-
-static const struct attribute_group *rc_dev_attr_groups[] = {
- &rc_dev_attr_grp,
- NULL
-};
-
-static struct device_type rc_dev_type = {
- .groups = rc_dev_attr_groups,
- .uevent = rc_dev_uevent,
-};
-
-/**
- * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to register the syfs code for IR class
- */
-int ir_register_class(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int devno = find_first_zero_bit(&ir_core_dev_number,
- IRRCV_NUM_DEVICES);
-
- if (unlikely(devno < 0))
- return devno;
-
- ir_dev->dev.type = &rc_dev_type;
- ir_dev->devno = devno;
-
- ir_dev->dev.class = &ir_input_class;
- ir_dev->dev.parent = input_dev->dev.parent;
- input_dev->dev.parent = &ir_dev->dev;
- dev_set_name(&ir_dev->dev, "rc%d", devno);
- dev_set_drvdata(&ir_dev->dev, ir_dev);
- return device_register(&ir_dev->dev);
-};
-
-/**
- * ir_register_input - registers ir input device with input subsystem
- * @input_dev: the struct input_dev descriptor of the device
- */
-
-int ir_register_input(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int rc;
- const char *path;
-
-
- rc = input_register_device(input_dev);
- if (rc < 0) {
- device_del(&ir_dev->dev);
- return rc;
- }
-
- __module_get(THIS_MODULE);
-
- path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
- printk(KERN_INFO "%s: %s as %s\n",
- dev_name(&ir_dev->dev),
- input_dev->name ? input_dev->name : "Unspecified device",
- path ? path : "N/A");
- kfree(path);
-
- set_bit(ir_dev->devno, &ir_core_dev_number);
- return 0;
-}
-
-/**
- * ir_unregister_class() - removes the sysfs for sysfs for
- * /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to unregister the syfs code for IR class
- */
-void ir_unregister_class(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- input_set_drvdata(input_dev, NULL);
- clear_bit(ir_dev->devno, &ir_core_dev_number);
- input_unregister_device(input_dev);
- device_del(&ir_dev->dev);
-
- module_put(THIS_MODULE);
-}
-
-/*
- * Init/exit code for the module. Basically, creates/removes /sys/class/rc
- */
-
-static int __init ir_core_init(void)
-{
- int rc = class_register(&ir_input_class);
- if (rc) {
- printk(KERN_ERR "ir_core: unable to register rc class\n");
- return rc;
- }
-
- /* Initialize/load the decoders/keymap code that will be used */
- ir_raw_init();
- ir_rcmap_init();
-
- return 0;
-}
-
-static void __exit ir_core_exit(void)
-{
- class_unregister(&ir_input_class);
- ir_rcmap_cleanup();
-}
-
-module_init(ir_core_init);
-module_exit(ir_core_exit);
diff --git a/drivers/media/IR/keymaps/rc-tbs-nec.c b/drivers/media/IR/keymaps/rc-tbs-nec.c
deleted file mode 100644
index 3309631e6f80..000000000000
--- a/drivers/media/IR/keymaps/rc-tbs-nec.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* tbs-nec.h - Keytable for tbs_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <media/rc-map.h>
-
-static struct ir_scancode tbs_nec[] = {
- { 0x04, KEY_POWER2}, /*power*/
- { 0x14, KEY_MUTE}, /*mute*/
- { 0x07, KEY_1},
- { 0x06, KEY_2},
- { 0x05, KEY_3},
- { 0x0b, KEY_4},
- { 0x0a, KEY_5},
- { 0x09, KEY_6},
- { 0x0f, KEY_7},
- { 0x0e, KEY_8},
- { 0x0d, KEY_9},
- { 0x12, KEY_0},
- { 0x16, KEY_CHANNELUP}, /*ch+*/
- { 0x11, KEY_CHANNELDOWN},/*ch-*/
- { 0x13, KEY_VOLUMEUP}, /*vol+*/
- { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
- { 0x03, KEY_RECORD}, /*rec*/
- { 0x18, KEY_PAUSE}, /*pause*/
- { 0x19, KEY_OK}, /*ok*/
- { 0x1a, KEY_CAMERA}, /* snapshot */
- { 0x01, KEY_UP},
- { 0x10, KEY_LEFT},
- { 0x02, KEY_RIGHT},
- { 0x08, KEY_DOWN},
- { 0x15, KEY_FAVORITES},
- { 0x17, KEY_SUBTITLE},
- { 0x1d, KEY_ZOOM},
- { 0x1f, KEY_EXIT},
- { 0x1e, KEY_MENU},
- { 0x1c, KEY_EPG},
- { 0x00, KEY_PREVIOUS},
- { 0x1b, KEY_MODE},
-};
-
-static struct rc_keymap tbs_nec_map = {
- .map = {
- .scan = tbs_nec,
- .size = ARRAY_SIZE(tbs_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
- .name = RC_MAP_TBS_NEC,
- }
-};
-
-static int __init init_rc_map_tbs_nec(void)
-{
- return ir_register_map(&tbs_nec_map);
-}
-
-static void __exit exit_rc_map_tbs_nec(void)
-{
- ir_unregister_map(&tbs_nec_map);
-}
-
-module_init(init_rc_map_tbs_nec)
-module_exit(exit_rc_map_tbs_nec)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tt-1500.c b/drivers/media/IR/keymaps/rc-tt-1500.c
deleted file mode 100644
index bc88de011d5d..000000000000
--- a/drivers/media/IR/keymaps/rc-tt-1500.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* tt-1500.h - Keytable for tt_1500 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <media/rc-map.h>
-
-/* for the Technotrend 1500 bundled remotes (grey and black): */
-
-static struct ir_scancode tt_1500[] = {
- { 0x01, KEY_POWER },
- { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
- { 0x03, KEY_1 },
- { 0x04, KEY_2 },
- { 0x05, KEY_3 },
- { 0x06, KEY_4 },
- { 0x07, KEY_5 },
- { 0x08, KEY_6 },
- { 0x09, KEY_7 },
- { 0x0a, KEY_8 },
- { 0x0b, KEY_9 },
- { 0x0c, KEY_0 },
- { 0x0d, KEY_UP },
- { 0x0e, KEY_LEFT },
- { 0x0f, KEY_OK },
- { 0x10, KEY_RIGHT },
- { 0x11, KEY_DOWN },
- { 0x12, KEY_INFO },
- { 0x13, KEY_EXIT },
- { 0x14, KEY_RED },
- { 0x15, KEY_GREEN },
- { 0x16, KEY_YELLOW },
- { 0x17, KEY_BLUE },
- { 0x18, KEY_MUTE },
- { 0x19, KEY_TEXT },
- { 0x1a, KEY_MODE }, /* ? TV/Radio */
- { 0x21, KEY_OPTION },
- { 0x22, KEY_EPG },
- { 0x23, KEY_CHANNELUP },
- { 0x24, KEY_CHANNELDOWN },
- { 0x25, KEY_VOLUMEUP },
- { 0x26, KEY_VOLUMEDOWN },
- { 0x27, KEY_SETUP },
- { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
- { 0x3b, KEY_PLAY },
- { 0x3c, KEY_STOP },
- { 0x3d, KEY_REWIND },
- { 0x3e, KEY_PAUSE },
- { 0x3f, KEY_FORWARD },
-};
-
-static struct rc_keymap tt_1500_map = {
- .map = {
- .scan = tt_1500,
- .size = ARRAY_SIZE(tt_1500),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
- .name = RC_MAP_TT_1500,
- }
-};
-
-static int __init init_rc_map_tt_1500(void)
-{
- return ir_register_map(&tt_1500_map);
-}
-
-static void __exit exit_rc_map_tt_1500(void)
-{
- ir_unregister_map(&tt_1500_map);
-}
-
-module_init(init_rc_map_tt_1500)
-module_exit(exit_rc_map_tt_1500)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
deleted file mode 100644
index 689143f2fff0..000000000000
--- a/drivers/media/IR/rc-map.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ir-raw-event.c - handle IR Pulse/Space event
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <media/ir-core.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-/* Used to handle IR raw handler extensions */
-static LIST_HEAD(rc_map_list);
-static DEFINE_SPINLOCK(rc_map_lock);
-
-static struct rc_keymap *seek_rc_map(const char *name)
-{
- struct rc_keymap *map = NULL;
-
- spin_lock(&rc_map_lock);
- list_for_each_entry(map, &rc_map_list, list) {
- if (!strcmp(name, map->map.name)) {
- spin_unlock(&rc_map_lock);
- return map;
- }
- }
- spin_unlock(&rc_map_lock);
-
- return NULL;
-}
-
-struct ir_scancode_table *get_rc_map(const char *name)
-{
-
- struct rc_keymap *map;
-
- map = seek_rc_map(name);
-#ifdef MODULE
- if (!map) {
- int rc = request_module(name);
- if (rc < 0) {
- printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
- return NULL;
- }
- msleep(20); /* Give some time for IR to register */
-
- map = seek_rc_map(name);
- }
-#endif
- if (!map) {
- printk(KERN_ERR "IR keymap %s not found\n", name);
- return NULL;
- }
-
- printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
-
- return &map->map;
-}
-EXPORT_SYMBOL_GPL(get_rc_map);
-
-int ir_register_map(struct rc_keymap *map)
-{
- spin_lock(&rc_map_lock);
- list_add_tail(&map->list, &rc_map_list);
- spin_unlock(&rc_map_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_register_map);
-
-void ir_unregister_map(struct rc_keymap *map)
-{
- spin_lock(&rc_map_lock);
- list_del(&map->list);
- spin_unlock(&rc_map_lock);
-}
-EXPORT_SYMBOL_GPL(ir_unregister_map);
-
-
-static struct ir_scancode empty[] = {
- { 0x2a, KEY_COFFEE },
-};
-
-static struct rc_keymap empty_map = {
- .map = {
- .scan = empty,
- .size = ARRAY_SIZE(empty),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
- .name = RC_MAP_EMPTY,
- }
-};
-
-int ir_rcmap_init(void)
-{
- return ir_register_map(&empty_map);
-}
-
-void ir_rcmap_cleanup(void)
-{
- ir_unregister_map(&empty_map);
-}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index a28541b2b1a2..81b3ba83cc65 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -40,35 +40,6 @@ config VIDEO_V4L2_COMMON
depends on (I2C || I2C=n) && VIDEO_DEV
default (I2C || I2C=n) && VIDEO_DEV
-config VIDEO_ALLOW_V4L1
- bool "Enable Video For Linux API 1 (DEPRECATED)"
- depends on VIDEO_DEV && VIDEO_V4L2_COMMON
- default VIDEO_DEV && VIDEO_V4L2_COMMON
- ---help---
- Enables drivers based on the legacy V4L1 API.
-
- This api were developed to be used at Kernel 2.2 and 2.4, but
- lacks support for several video standards. There are several
- drivers at kernel that still depends on it.
-
- If you are unsure as to whether this is required, answer Y.
-
-config VIDEO_V4L1_COMPAT
- bool "Enable Video For Linux API 1 compatible Layer" if !VIDEO_ALLOW_V4L1
- depends on VIDEO_DEV
- default y
- ---help---
- Enables a compatibility API used by most V4L2 devices to allow
- its usage with legacy applications that supports only V4L1 api.
-
- Documentation for the original API is included in the file
- <Documentation/video4linux/API.html>.
-
- User tools for this are available from
- <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
-
- If you are unsure as to whether this is required, answer Y.
-
#
# DVB Core
#
@@ -99,7 +70,7 @@ config VIDEO_MEDIA
comment "Multimedia drivers"
source "drivers/media/common/Kconfig"
-source "drivers/media/IR/Kconfig"
+source "drivers/media/rc/Kconfig"
#
# Tuner drivers for DVB and V4L
@@ -121,26 +92,4 @@ source "drivers/media/radio/Kconfig"
source "drivers/media/dvb/Kconfig"
-config DAB
- boolean "DAB adapters"
- ---help---
- Allow selecting support for Digital Audio Broadcasting (DAB)
- Receiver adapters.
-
-if DAB
-config USB_DABUSB
- tristate "DABUSB driver"
- depends on USB
- ---help---
- A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
- brought to you by the DAB-Team
- <http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
- as an example for URB-based bulk, control, and isochronous
- transactions. URB's are explained in
- <Documentation/usb/URB.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called dabusb.
-endif # DAB
-
endif # MEDIA_SUPPORT
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 499b0810d019..b603ea645ede 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,7 +2,7 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y += common/ IR/ video/
+obj-y += common/ rc/ video/
obj-$(CONFIG_VIDEO_DEV) += radio/
obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index 05bde9ccb770..1d1d8d200755 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e
static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
{
struct saa7146_vv *vv = dev->vv_data;
- struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
int b_depth = vv->ov_fmt->depth;
int b_bpl = vv->ov_fb.fmt.bytesperline;
@@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
struct saa7146_vv *vv = dev->vv_data;
struct saa7146_video_dma vdma1;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
struct saa7146_video_dma vdma2;
struct saa7146_video_dma vdma3;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
{
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
struct saa7146_vv *vv = dev->vv_data;
u32 vdma1_prot_addr;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 741c5732b430..0ac5c619aecf 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -84,7 +84,7 @@ static struct saa7146_format formats[] = {
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
-struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
+struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
int i, j = NUM_FORMATS;
@@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
struct scatterlist *list = dma->sglist;
int length = dma->sglen;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
@@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh)
}
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return -EBUSY;
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
return -EPERM;
/* check args */
- fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -1129,35 +1129,6 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh,
core, g_chip_ident, chip);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
-{
- struct saa7146_fh *fh = __fh;
- struct videobuf_queue *q = &fh->video_q;
- int err, i;
-
- /* fixme: number of capture buffers and sizes for v4l apps */
- int gbuffers = 2;
- int gbufsize = 768 * 576 * 4;
-
- DEB_D(("VIDIOCGMBUF \n"));
-
- q = &fh->video_q;
- err = videobuf_mmap_setup(q, gbuffers, gbufsize,
- V4L2_MEMORY_MMAP);
- if (err < 0)
- return err;
-
- gbuffers = err;
- memset(mbuf, 0, sizeof(*mbuf));
- mbuf->frames = gbuffers;
- mbuf->size = gbuffers * gbufsize;
- for (i = 0; i < gbuffers; i++)
- mbuf->offsets[i] = i * gbufsize;
- return 0;
-}
-#endif
-
const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@@ -1186,9 +1157,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_parm = vidioc_g_parm,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
/*********************************************************************************/
@@ -1264,7 +1232,7 @@ static int buffer_prepare(struct videobuf_queue *q,
buf->fmt = &fh->video_fmt;
buf->vb.field = fh->video_fmt.field;
- sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
release_all_pagetables(dev, buf);
if( 0 != IS_PLANAR(sfmt->trans)) {
@@ -1378,7 +1346,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
fh->video_fmt.bytesperline = 0;
fh->video_fmt.field = V4L2_FIELD_ANY;
- sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
videobuf_queue_sg_init(&fh->video_q, &video_qops,
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 2385e6cca635..78b089526e02 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -31,7 +31,7 @@ config MEDIA_TUNER
select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-menuconfig MEDIA_TUNER_CUSTOMISE
+config MEDIA_TUNER_CUSTOMISE
bool "Customize analog and hybrid tuner modules to build"
depends on MEDIA_TUNER
default y if EMBEDDED
@@ -44,7 +44,8 @@ menuconfig MEDIA_TUNER_CUSTOMISE
If unsure say N.
-if MEDIA_TUNER_CUSTOMISE
+menu "Customize TV tuners"
+ visible if MEDIA_TUNER_CUSTOMISE
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
@@ -185,5 +186,4 @@ config MEDIA_TUNER_TDA18218
default m if MEDIA_TUNER_CUSTOMISE
help
NXP TDA18218 silicon tuner driver.
-
-endif # MEDIA_TUNER_CUSTOMISE
+endmenu
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
index 937e4b00d7ee..9883617b7862 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -52,13 +52,12 @@ static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
msg.addr = priv->config->i2c_address;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
- dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -EIO : 0;
@@ -78,14 +77,13 @@ static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
- dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
*p_data = b1[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+ dprintk("%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, b1[0]);
return 0;
}
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index a6ceb08f1183..f3de0a4d63f2 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -1,7 +1,6 @@
config DVB_DM1105
tristate "SDMC DM1105 based PCI cards"
depends on DVB_CORE && PCI && I2C
- depends on INPUT
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
@@ -9,7 +8,7 @@ config DVB_DM1105
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_DS3000 if !DVB_FE_CUSTOMISE
- depends on VIDEO_IR
+ depends on RC_CORE
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 5d404f1bf036..2d8b4044be36 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -26,9 +26,8 @@
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
-#include <linux/input.h>
#include <linux/slab.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "demux.h"
#include "dmxdev.h"
@@ -266,7 +265,7 @@ static void dm1105_card_list(struct pci_dev *pci)
/* infrared remote control */
struct infrared {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char input_phys[32];
struct work_struct work;
u32 ir_command;
@@ -532,7 +531,7 @@ static void dm1105_emit_key(struct work_struct *work)
data = (ircom >> 8) & 0x7f;
- ir_keydown(ir->input_dev, data, 0);
+ rc_keydown(ir->dev, data, 0);
}
/* work handler */
@@ -593,46 +592,47 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_DM1105_NEC;
+ struct rc_dev *dev;
int err = -ENOMEM;
- input_dev = input_allocate_device();
- if (!input_dev)
+ dev = rc_allocate_device();
+ if (!dev)
return -ENOMEM;
- dm1105->ir.input_dev = input_dev;
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->name = "DVB on-card IR receiver";
- input_dev->phys = dm1105->ir.input_phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_DM1105_NEC;
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->input_name = "DVB on-card IR receiver";
+ dev->input_phys = dm1105->ir.input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
- input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
- input_dev->id.product = dm1105->pdev->subsystem_device;
+ dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
+ dev->input_id.product = dm1105->pdev->subsystem_device;
} else {
- input_dev->id.vendor = dm1105->pdev->vendor;
- input_dev->id.product = dm1105->pdev->device;
+ dev->input_id.vendor = dm1105->pdev->vendor;
+ dev->input_id.product = dm1105->pdev->device;
}
-
- input_dev->dev.parent = &dm1105->pdev->dev;
+ dev->dev.parent = &dm1105->pdev->dev;
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
- err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err < 0) {
- input_free_device(input_dev);
+ rc_free_device(dev);
return err;
}
+ dm1105->ir.dev = dev;
return 0;
}
void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
{
- ir_input_unregister(dm1105->ir.input_dev);
+ rc_unregister_device(dm1105->ir.dev);
}
static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index ad1f61d301e1..e4b5c03ae516 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -572,13 +572,13 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
dmx_output_t otype;
int ret;
int ts_type;
- enum dmx_ts_pes ts_pes;
+ dmx_pes_type_t ts_pes;
struct dmx_ts_feed *tsfeed;
feed->ts = NULL;
otype = para->output;
- ts_pes = (enum dmx_ts_pes)para->pes_type;
+ ts_pes = para->pes_type;
if (ts_pes < DMX_PES_OTHER)
ts_type = TS_DECODER;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 2525d3b3c88d..3d48ba019342 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,6 +1,6 @@
config DVB_USB
tristate "Support for various USB DVB devices"
- depends on DVB_CORE && USB && I2C && IR_CORE
+ depends on DVB_CORE && USB && I2C && RC_CORE
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index a5c363727133..53b93a4b6f8a 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -37,7 +37,7 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
return 0;
}
-static struct ir_scancode ir_codes_a800_table[] = {
+static struct rc_map_table rc_map_a800_table[] = {
{ 0x0201, KEY_PROG1 }, /* SOURCE */
{ 0x0200, KEY_POWER }, /* POWER */
{ 0x0205, KEY_1 }, /* 1 */
@@ -148,8 +148,8 @@ static struct dvb_usb_device_properties a800_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_a800_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table),
+ .rc_map_table = rc_map_a800_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
.rc_query = a800_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index 696207fe37ec..c3bc64ed405c 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -33,7 +33,7 @@ MODULE_PARM_DESC(debug,
#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
-struct ir_scancode ir_codes_af9005_table[] = {
+struct rc_map_table rc_map_af9005_table[] = {
{0x01b7, KEY_POWER},
{0x01a7, KEY_VOLUMEUP},
@@ -74,7 +74,7 @@ struct ir_scancode ir_codes_af9005_table[] = {
{0x00d5, KEY_GOTO}, /* marked jump on the remote */
};
-int ir_codes_af9005_table_size = ARRAY_SIZE(ir_codes_af9005_table);
+int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
static int repeatable_keys[] = {
KEY_VOLUMEUP,
@@ -130,10 +130,10 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
deb_decode("code != inverted code\n");
return 0;
}
- for (i = 0; i < ir_codes_af9005_table_size; i++) {
- if (rc5_custom(&ir_codes_af9005_table[i]) == cust
- && rc5_data(&ir_codes_af9005_table[i]) == dat) {
- *event = ir_codes_af9005_table[i].keycode;
+ for (i = 0; i < rc_map_af9005_table_size; i++) {
+ if (rc5_custom(&rc_map_af9005_table[i]) == cust
+ && rc5_data(&rc_map_af9005_table[i]) == dat) {
+ *event = rc_map_af9005_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
deb_decode
("key pressed, event %x\n", *event);
@@ -146,8 +146,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
return 0;
}
-EXPORT_SYMBOL(ir_codes_af9005_table);
-EXPORT_SYMBOL(ir_codes_af9005_table_size);
+EXPORT_SYMBOL(rc_map_af9005_table);
+EXPORT_SYMBOL(rc_map_af9005_table_size);
EXPORT_SYMBOL(af9005_rc_decode);
MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
index 8ecba8848bcf..51f6439dcfd5 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -1027,8 +1027,8 @@ static struct dvb_usb_device_properties af9005_properties = {
.rc.legacy = {
.rc_interval = 200,
- .rc_key_map = NULL,
- .rc_key_map_size = 0,
+ .rc_map_table = NULL,
+ .rc_map_size = 0,
.rc_query = af9005_rc_query,
},
@@ -1070,14 +1070,14 @@ static int __init af9005_usb_module_init(void)
return result;
}
rc_decode = symbol_request(af9005_rc_decode);
- rc_keys = symbol_request(ir_codes_af9005_table);
- rc_keys_size = symbol_request(ir_codes_af9005_table_size);
+ rc_keys = symbol_request(rc_map_af9005_table);
+ rc_keys_size = symbol_request(rc_map_af9005_table_size);
if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
err("af9005_rc_decode function not found, disabling remote");
af9005_properties.rc.legacy.rc_query = NULL;
} else {
- af9005_properties.rc.legacy.rc_key_map = rc_keys;
- af9005_properties.rc.legacy.rc_key_map_size = *rc_keys_size;
+ af9005_properties.rc.legacy.rc_map_table = rc_keys;
+ af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
}
return 0;
@@ -1089,9 +1089,9 @@ static void __exit af9005_usb_module_exit(void)
if (rc_decode != NULL)
symbol_put(af9005_rc_decode);
if (rc_keys != NULL)
- symbol_put(ir_codes_af9005_table);
+ symbol_put(rc_map_af9005_table);
if (rc_keys_size != NULL)
- symbol_put(ir_codes_af9005_table_size);
+ symbol_put(rc_map_af9005_table_size);
/* deregister this driver from the USB subsystem */
usb_deregister(&af9005_usb_driver);
}
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
index 3c1fbd1c5d60..c71c77bd7f4b 100644
--- a/drivers/media/dvb/dvb-usb/af9005.h
+++ b/drivers/media/dvb/dvb-usb/af9005.h
@@ -3490,7 +3490,7 @@ extern u8 regmask[8];
/* remote control decoder */
extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
u32 * event, int *state);
-extern struct ir_scancode ir_codes_af9005_table[];
-extern int ir_codes_af9005_table_size;
+extern struct rc_map_table rc_map_af9005_table[];
+extern int rc_map_af9005_table_size;
#endif
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 31c0a0ed39f5..8671ca362c81 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -1041,13 +1041,13 @@ static int af9015_rc_query(struct dvb_usb_device *d)
priv->rc_keycode = buf[12] << 16 |
buf[13] << 8 | buf[14];
}
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
priv->rc_keycode = 0; /* clear just for sure */
}
} else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__);
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
deb_rc("%s: no key press\n", __func__);
}
@@ -1344,13 +1344,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@@ -1474,13 +1472,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@@ -1588,13 +1584,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 1759d26bca42..6b402e943539 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -394,7 +394,7 @@ static int anysee_rc_query(struct dvb_usb_device *d)
if (ircode[0]) {
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
- ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
+ rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
}
return 0;
@@ -476,7 +476,7 @@ static struct dvb_usb_device_properties anysee_properties = {
.rc.core = {
.rc_codes = RC_MAP_ANYSEE,
- .protocol = IR_TYPE_OTHER,
+ .protocol = RC_TYPE_OTHER,
.module_name = "anysee",
.rc_query = anysee_rc_query,
.rc_interval = 250, /* windows driver uses 500ms */
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
index 62c58288469f..57e2444d51ab 100644
--- a/drivers/media/dvb/dvb-usb/az6027.c
+++ b/drivers/media/dvb/dvb-usb/az6027.c
@@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
}
/* keys for the enclosed remote control */
-static struct ir_scancode ir_codes_az6027_table[] = {
+static struct rc_map_table rc_map_az6027_table[] = {
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
};
@@ -1089,6 +1089,7 @@ static struct usb_device_id az6027_usb_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
{ },
};
@@ -1126,15 +1127,15 @@ static struct dvb_usb_device_properties az6027_properties = {
.read_mac_address = az6027_read_mac_addr,
*/
.rc.legacy = {
- .rc_key_map = ir_codes_az6027_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table),
+ .rc_map_table = rc_map_az6027_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
.rc_interval = 400,
.rc_query = az6027_rc_query,
},
.i2c_algo = &az6027_i2c_algo,
- .num_device_descs = 5,
+ .num_device_descs = 6,
.devices = {
{
.name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
@@ -1156,6 +1157,10 @@ static struct dvb_usb_device_properties az6027_properties = {
.name = "Technisat SkyStar USB 2 HD CI",
.cold_ids = { &az6027_usb_table[4], NULL },
.warm_ids = { NULL },
+ }, {
+ .name = "Elgato EyeTV Sat",
+ .cold_ids = { &az6027_usb_table[5], NULL },
+ .warm_ids = { NULL },
},
{ NULL },
}
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index 4f5aa83fc1fc..16f2ce2bc15a 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -84,7 +84,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static struct ir_scancode ir_codes_cinergyt2_table[] = {
+static struct rc_map_table rc_map_cinergyt2_table[] = {
{ 0x0401, KEY_POWER },
{ 0x0402, KEY_1 },
{ 0x0403, KEY_2 },
@@ -219,8 +219,8 @@ static struct dvb_usb_device_properties cinergyt2_properties = {
.rc.legacy = {
.rc_interval = 50,
- .rc_key_map = ir_codes_cinergyt2_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table),
+ .rc_map_table = rc_map_cinergyt2_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
.rc_query = cinergyt2_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index cd9f362c37b2..acb5fb2d2e73 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -385,7 +385,7 @@ static int cxusb_d680_dmb_streaming_ctrl(
static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
@@ -394,7 +394,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[2] &&
rc5_data(&keymap[i]) == ircode[3]) {
*event = keymap[i].keycode;
@@ -410,7 +410,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
@@ -422,7 +422,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
return 0;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[1] &&
rc5_data(&keymap[i]) == ircode[2]) {
*event = keymap[i].keycode;
@@ -438,7 +438,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[2];
int i;
@@ -448,7 +448,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
return 0;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[0] &&
rc5_data(&keymap[i]) == ircode[1]) {
*event = keymap[i].keycode;
@@ -461,7 +461,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
}
-static struct ir_scancode ir_codes_dvico_mce_table[] = {
+static struct rc_map_table rc_map_dvico_mce_table[] = {
{ 0xfe02, KEY_TV },
{ 0xfe0e, KEY_MP3 },
{ 0xfe1a, KEY_DVD },
@@ -509,7 +509,7 @@ static struct ir_scancode ir_codes_dvico_mce_table[] = {
{ 0xfe4e, KEY_POWER },
};
-static struct ir_scancode ir_codes_dvico_portable_table[] = {
+static struct rc_map_table rc_map_dvico_portable_table[] = {
{ 0xfc02, KEY_SETUP }, /* Profile */
{ 0xfc43, KEY_POWER2 },
{ 0xfc06, KEY_EPG },
@@ -548,7 +548,7 @@ static struct ir_scancode ir_codes_dvico_portable_table[] = {
{ 0xfc00, KEY_UNKNOWN }, /* HD */
};
-static struct ir_scancode ir_codes_d680_dmb_table[] = {
+static struct rc_map_table rc_map_d680_dmb_table[] = {
{ 0x0038, KEY_UNKNOWN }, /* TV/AV */
{ 0x080c, KEY_ZOOM },
{ 0x0800, KEY_0 },
@@ -923,7 +923,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
return -EIO;
/* try to determine if there is no IR decoder on the I2C bus */
- for (i = 0; adap->dev->props.rc.legacy.rc_key_map != NULL && i < 5; i++) {
+ for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
msleep(20);
if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
goto no_IR;
@@ -931,7 +931,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
continue;
if (ircode[2] + ircode[3] != 0xff) {
no_IR:
- adap->dev->props.rc.legacy.rc_key_map = NULL;
+ adap->dev->props.rc.legacy.rc_map_table = NULL;
info("No IR receiver detected on this device.");
break;
}
@@ -1453,8 +1453,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1506,8 +1506,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
.rc.legacy = {
.rc_interval = 150,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@@ -1567,8 +1567,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1619,8 +1619,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1670,8 +1670,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@@ -1720,8 +1720,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@@ -1772,8 +1772,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1865,8 +1865,8 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@@ -1915,8 +1915,8 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_d680_dmb_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
+ .rc_map_table = rc_map_d680_dmb_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},
@@ -1966,8 +1966,8 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_d680_dmb_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
+ .rc_map_table = rc_map_d680_dmb_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index c2c9d236ec7e..3537d65c04bc 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -60,7 +60,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
extern struct i2c_algorithm dib0700_i2c_algo;
extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(void *priv, u64 ir_type);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
extern int dib0700_device_count;
extern int dvb_usb_dib0700_ir_proto;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 48397f103d32..8ca48f76dfa9 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -471,19 +471,19 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4);
}
-int dib0700_change_protocol(void *priv, u64 ir_type)
+int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
{
- struct dvb_usb_device *d = priv;
+ struct dvb_usb_device *d = rc->priv;
struct dib0700_state *st = d->priv;
u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
int new_proto, ret;
/* Set the IR mode */
- if (ir_type == IR_TYPE_RC5)
+ if (rc_type == RC_TYPE_RC5)
new_proto = 1;
- else if (ir_type == IR_TYPE_NEC)
+ else if (rc_type == RC_TYPE_NEC)
new_proto = 0;
- else if (ir_type == IR_TYPE_RC6) {
+ else if (rc_type == RC_TYPE_RC6) {
if (st->fw_version < 0x10200)
return -EINVAL;
@@ -499,7 +499,7 @@ int dib0700_change_protocol(void *priv, u64 ir_type)
return ret;
}
- d->props.rc.core.protocol = ir_type;
+ d->props.rc.core.protocol = rc_type;
return ret;
}
@@ -535,7 +535,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if (d == NULL)
return;
- if (d->rc_input_dev == NULL) {
+ if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
usb_free_urb(purb);
return;
@@ -562,7 +562,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
purb->actual_length);
switch (d->props.rc.core.protocol) {
- case IR_TYPE_NEC:
+ case RC_TYPE_NEC:
toggle = 0;
/* NEC protocol sends repeat code as 0 0 0 FF */
@@ -600,7 +600,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
goto resubmit;
}
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ rc_keydown(d->rc_dev, keycode, toggle);
resubmit:
/* Clean the buffer before we requeue */
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index e06acd1fecb6..defd83964ce2 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -510,7 +510,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = 0;
switch (d->props.rc.core.protocol) {
- case IR_TYPE_NEC:
+ case RC_TYPE_NEC:
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
(key[3] == 0xff))
@@ -520,13 +520,13 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = keycode;
}
- ir_keydown(d->rc_input_dev, keycode, 0);
+ rc_keydown(d->rc_dev, keycode, 0);
break;
default:
/* RC-5 protocol changes toggle bit on new keypress */
keycode = key[3-2] << 8 | key[3-3];
toggle = key[3-1];
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ rc_keydown(d->rc_dev, keycode, toggle);
break;
}
@@ -1924,12 +1924,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -1960,12 +1958,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2021,12 +2017,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2065,12 +2059,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2143,12 +2135,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2189,12 +2179,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2259,12 +2247,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2308,12 +2294,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2379,12 +2363,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2417,12 +2399,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2487,12 +2467,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2533,12 +2511,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 2,
@@ -2584,12 +2560,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2623,12 +2597,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
},
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index ba991aa21aff..956f7ae2e510 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -327,7 +327,7 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
/*
* common remote control stuff
*/
-struct ir_scancode ir_codes_dibusb_table[] = {
+struct rc_map_table rc_map_dibusb_table[] = {
/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
@@ -456,7 +456,7 @@ struct ir_scancode ir_codes_dibusb_table[] = {
{ 0x804e, KEY_ENTER },
{ 0x804f, KEY_VOLUMEDOWN },
};
-EXPORT_SYMBOL(ir_codes_dibusb_table);
+EXPORT_SYMBOL(rc_map_dibusb_table);
int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 8e3c0d2cce16..04d91bdd3562 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -213,8 +213,8 @@ static struct dvb_usb_device_properties dibusb1_1_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -299,8 +299,8 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -365,8 +365,8 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -424,8 +424,8 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 1cbc41cb4e8f..c1d9094b61e5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -83,8 +83,8 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* FIXME */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 61a6bf389472..e47c321b3ffc 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -124,7 +124,7 @@ extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
#define DEFAULT_RC_INTERVAL 150
//#define DEFAULT_RC_INTERVAL 100000
-extern struct ir_scancode ir_codes_dibusb_table[];
+extern struct rc_map_table rc_map_dibusb_table[];
extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 13d006bb19db..f2dbce7edb3b 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -161,7 +161,7 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static struct ir_scancode ir_codes_digitv_table[] = {
+static struct rc_map_table rc_map_digitv_table[] = {
{ 0x5f55, KEY_0 },
{ 0x6f55, KEY_1 },
{ 0x9f55, KEY_2 },
@@ -237,10 +237,10 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
/* if something is inside the buffer, simulate key press */
if (key[1] != 0)
{
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
- if (rc5_custom(&d->props.rc.legacy.rc_key_map[i]) == key[1] &&
- rc5_data(&d->props.rc.legacy.rc_key_map[i]) == key[2]) {
- *event = d->props.rc.legacy.rc_key_map[i].keycode;
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+ if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
+ rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
+ *event = d->props.rc.legacy.rc_map_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
return 0;
}
@@ -312,8 +312,8 @@ static struct dvb_usb_device_properties digitv_properties = {
.rc.legacy = {
.rc_interval = 1000,
- .rc_key_map = ir_codes_digitv_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table),
+ .rc_map_table = rc_map_digitv_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
.rc_query = digitv_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index ca495e07f35c..ecd86eca2548 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -57,7 +57,7 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
/* remote control */
/* key list for the tiny remote control (Yakumo, don't know about the others) */
-static struct ir_scancode ir_codes_dtt200u_table[] = {
+static struct rc_map_table rc_map_dtt200u_table[] = {
{ 0x8001, KEY_MUTE },
{ 0x8002, KEY_CHANNELDOWN },
{ 0x8003, KEY_VOLUMEDOWN },
@@ -163,8 +163,8 @@ static struct dvb_usb_device_properties dtt200u_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -210,8 +210,8 @@ static struct dvb_usb_device_properties wt220u_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -257,8 +257,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -304,8 +304,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 192a40ce583d..1a6310b61923 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -301,6 +301,7 @@
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
#define USB_PID_ELGATO_EYETV_DTT 0x0021
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
+#define USB_PID_ELGATO_EYETV_SAT 0x002a
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
#define USB_PID_FRIIO_WHITE 0x0001
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index b579fed3ab3f..c6498f536dff 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -13,11 +13,11 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* See if we can match the raw key code. */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
*keycode = keymap[i].keycode;
return 0;
@@ -28,7 +28,7 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
* otherwise, input core won't let legacy_dvb_usb_setkeycode
* to work
*/
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
*keycode = KEY_RESERVED;
@@ -43,18 +43,18 @@ static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* Search if it is replacing an existing keycode */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
keymap[i].keycode = keycode;
return 0;
}
/* Search if is there a clean entry. If so, use it */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
keymap[i].scancode = scancode;
@@ -106,10 +106,10 @@ static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(d->rc_input_dev, EV_KEY, event, 1);
- input_sync(d->rc_input_dev);
- input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(d->rc_input_dev);
+ input_event(d->input_dev, EV_KEY, event, 1);
+ input_sync(d->input_dev);
+ input_event(d->input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->input_dev);
break;
default:
break;
@@ -154,20 +154,32 @@ schedule:
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
}
-static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i, err, rc_interval;
+ struct input_dev *input_dev;
+
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->name = "IR-receiver inside an USB DVB receiver";
+ input_dev->phys = d->rc_phys;
+ usb_to_input_id(d->udev, &input_dev->id);
+ input_dev->dev.parent = &d->udev->dev;
+ d->input_dev = input_dev;
+ d->rc_dev = NULL;
input_dev->getkeycode = legacy_dvb_usb_getkeycode;
input_dev->setkeycode = legacy_dvb_usb_setkeycode;
/* set the bits for the keys */
- deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
deb_rc("setting bit for event %d item %d\n",
- d->props.rc.legacy.rc_key_map[i].keycode, i);
- set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
+ d->props.rc.legacy.rc_map_table[i].keycode, i);
+ set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
}
/* setting these two values to non-zero, we have to manage key repeats */
@@ -221,18 +233,34 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
msecs_to_jiffies(d->props.rc.core.rc_interval));
}
-static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int err, rc_interval;
+ struct rc_dev *dev;
+
+ dev = rc_allocate_device();
+ if (!dev)
+ return -ENOMEM;
- d->props.rc.core.rc_props.priv = d;
- err = ir_input_register(input_dev,
- d->props.rc.core.rc_codes,
- &d->props.rc.core.rc_props,
- d->props.rc.core.module_name);
- if (err < 0)
+ dev->driver_name = d->props.rc.core.module_name;
+ dev->map_name = d->props.rc.core.rc_codes;
+ dev->change_protocol = d->props.rc.core.change_protocol;
+ dev->allowed_protos = d->props.rc.core.allowed_protos;
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ usb_to_input_id(d->udev, &dev->input_id);
+ dev->input_name = "IR-receiver inside an USB DVB receiver";
+ dev->input_phys = d->rc_phys;
+ dev->dev.parent = &d->udev->dev;
+ dev->priv = d;
+
+ err = rc_register_device(dev);
+ if (err < 0) {
+ rc_free_device(dev);
return err;
+ }
+
+ d->input_dev = NULL;
+ d->rc_dev = dev;
if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
return 0;
@@ -251,13 +279,12 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
- struct input_dev *input_dev;
int err;
if (dvb_usb_disable_rc_polling)
return 0;
- if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
+ if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
d->props.rc.mode = DVB_RC_LEGACY;
else if (d->props.rc.core.rc_codes)
d->props.rc.mode = DVB_RC_CORE;
@@ -267,26 +294,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->name = "IR-receiver inside an USB DVB receiver";
- input_dev->phys = d->rc_phys;
- usb_to_input_id(d->udev, &input_dev->id);
- input_dev->dev.parent = &d->udev->dev;
-
/* Start the remote-control polling. */
if (d->props.rc.legacy.rc_interval < 40)
d->props.rc.legacy.rc_interval = 100; /* default */
- d->rc_input_dev = input_dev;
-
if (d->props.rc.mode == DVB_RC_LEGACY)
- err = legacy_dvb_usb_remote_init(d, input_dev);
+ err = legacy_dvb_usb_remote_init(d);
else
- err = rc_core_dvb_usb_remote_init(d, input_dev);
+ err = rc_core_dvb_usb_remote_init(d);
if (err)
return err;
@@ -301,9 +316,9 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work();
if (d->props.rc.mode == DVB_RC_LEGACY)
- input_unregister_device(d->rc_input_dev);
+ input_unregister_device(d->input_dev);
else
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
@@ -316,7 +331,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
u8 keybuf[5], u32 *event, int *state)
{
int i;
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
switch (keybuf[0]) {
@@ -329,7 +344,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
break;
}
/* See if we can match the raw key code. */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (rc5_custom(&keymap[i]) == keybuf[1] &&
rc5_data(&keymap[i]) == keybuf[3]) {
*event = keymap[i].keycode;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 34f7b3ba8cc7..65fa9268e7f7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -14,7 +14,7 @@
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/mutex.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "dvb_frontend.h"
#include "dvb_demux.h"
@@ -75,17 +75,17 @@ struct dvb_usb_device_description {
struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
};
-static inline u8 rc5_custom(struct ir_scancode *key)
+static inline u8 rc5_custom(struct rc_map_table *key)
{
return (key->scancode >> 8) & 0xff;
}
-static inline u8 rc5_data(struct ir_scancode *key)
+static inline u8 rc5_data(struct rc_map_table *key)
{
return key->scancode & 0xff;
}
-static inline u8 rc5_scan(struct ir_scancode *key)
+static inline u8 rc5_scan(struct rc_map_table *key)
{
return key->scancode & 0xffff;
}
@@ -159,9 +159,9 @@ struct dvb_usb_adapter_properties {
/**
* struct dvb_rc_legacy - old properties of remote controller
- * @rc_key_map: a hard-wired array of struct ir_scancode (NULL to disable
+ * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
* remote control handling).
- * @rc_key_map_size: number of items in @rc_key_map.
+ * @rc_map_size: number of items in @rc_map_table.
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
*/
@@ -170,8 +170,8 @@ struct dvb_rc_legacy {
#define REMOTE_NO_KEY_PRESSED 0x00
#define REMOTE_KEY_PRESSED 0x01
#define REMOTE_KEY_REPEAT 0x02
- struct ir_scancode *rc_key_map;
- int rc_key_map_size;
+ struct rc_map_table *rc_map_table;
+ int rc_map_size;
int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
int rc_interval;
};
@@ -180,18 +180,20 @@ struct dvb_rc_legacy {
* struct dvb_rc properties of remote controller, using rc-core
* @rc_codes: name of rc codes table
* @protocol: type of protocol(s) currently used by the driver
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
- * @rc_props: remote controller properties
* @bulk_mode: device supports bulk mode for RC (disable polling mode)
*/
struct dvb_rc {
char *rc_codes;
u64 protocol;
+ u64 allowed_protos;
+ int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
char *module_name;
int (*rc_query) (struct dvb_usb_device *d);
int rc_interval;
- struct ir_dev_props rc_props;
bool bulk_mode; /* uses bulk mode */
};
@@ -385,7 +387,8 @@ struct dvb_usb_adapter {
*
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
*
- * @rc_input_dev: input device for the remote control.
+ * @rc_dev: rc device for the remote control (rc-core mode)
+ * @input_dev: input device for the remote control (legacy mode)
* @rc_query_work: struct work_struct frequent rc queries
* @last_event: last triggered event
* @last_state: last state (no, pressed, repeat)
@@ -418,7 +421,8 @@ struct dvb_usb_device {
struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
/* remote control */
- struct input_dev *rc_input_dev;
+ struct rc_dev *rc_dev;
+ struct input_dev *input_dev;
char rc_phys[64];
struct delayed_work rc_query_work;
u32 last_event;
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 774df88dc6e3..2c307ba0d28b 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -73,8 +73,8 @@
"Please see linux/Documentation/dvb/ for more details " \
"on firmware-problems."
-struct ir_codes_dvb_usb_table_table {
- struct ir_scancode *rc_keys;
+struct rc_map_dvb_usb_table_table {
+ struct rc_map_table *rc_keys;
int rc_keys_size;
};
@@ -948,7 +948,7 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static struct ir_scancode ir_codes_dw210x_table[] = {
+static struct rc_map_table rc_map_dw210x_table[] = {
{ 0xf80a, KEY_Q }, /*power*/
{ 0xf80c, KEY_M }, /*mute*/
{ 0xf811, KEY_1 },
@@ -982,7 +982,7 @@ static struct ir_scancode ir_codes_dw210x_table[] = {
{ 0xf81b, KEY_B }, /*recall*/
};
-static struct ir_scancode ir_codes_tevii_table[] = {
+static struct rc_map_table rc_map_tevii_table[] = {
{ 0xf80a, KEY_POWER },
{ 0xf80c, KEY_MUTE },
{ 0xf811, KEY_1 },
@@ -1032,7 +1032,7 @@ static struct ir_scancode ir_codes_tevii_table[] = {
{ 0xf858, KEY_SWITCHVIDEOMODE },
};
-static struct ir_scancode ir_codes_tbs_table[] = {
+static struct rc_map_table rc_map_tbs_table[] = {
{ 0xf884, KEY_POWER },
{ 0xf894, KEY_MUTE },
{ 0xf887, KEY_1 },
@@ -1067,16 +1067,16 @@ static struct ir_scancode ir_codes_tbs_table[] = {
{ 0xf89b, KEY_MODE }
};
-static struct ir_codes_dvb_usb_table_table keys_tables[] = {
- { ir_codes_dw210x_table, ARRAY_SIZE(ir_codes_dw210x_table) },
- { ir_codes_tevii_table, ARRAY_SIZE(ir_codes_tevii_table) },
- { ir_codes_tbs_table, ARRAY_SIZE(ir_codes_tbs_table) },
+static struct rc_map_dvb_usb_table_table keys_tables[] = {
+ { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
+ { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
+ { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
};
static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
- int keymap_size = d->props.rc.legacy.rc_key_map_size;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+ int keymap_size = d->props.rc.legacy.rc_map_size;
u8 key[2];
struct i2c_msg msg = {
.addr = DW2102_RC_QUERY,
@@ -1185,14 +1185,14 @@ static int dw2102_load_firmware(struct usb_device *dev,
/* init registers */
switch (dev->descriptor.idProduct) {
case USB_PID_PROF_1100:
- s6x0_properties.rc.legacy.rc_key_map = ir_codes_tbs_table;
- s6x0_properties.rc.legacy.rc_key_map_size =
- ARRAY_SIZE(ir_codes_tbs_table);
+ s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
+ s6x0_properties.rc.legacy.rc_map_size =
+ ARRAY_SIZE(rc_map_tbs_table);
break;
case USB_PID_TEVII_S650:
- dw2104_properties.rc.legacy.rc_key_map = ir_codes_tevii_table;
- dw2104_properties.rc.legacy.rc_key_map_size =
- ARRAY_SIZE(ir_codes_tevii_table);
+ dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
+ dw2104_properties.rc.legacy.rc_map_size =
+ ARRAY_SIZE(rc_map_tevii_table);
case USB_PID_DW2104:
reset = 1;
dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
@@ -1257,8 +1257,8 @@ static struct dvb_usb_device_properties dw2102_properties = {
.i2c_algo = &dw2102_serit_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1310,8 +1310,8 @@ static struct dvb_usb_device_properties dw2104_properties = {
.i2c_algo = &dw2104_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1359,8 +1359,8 @@ static struct dvb_usb_device_properties dw3101_properties = {
.i2c_algo = &dw3101_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1404,8 +1404,8 @@ static struct dvb_usb_device_properties s6x0_properties = {
.i2c_algo = &s6x0_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_tevii_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table),
+ .rc_map_table = rc_map_tevii_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1468,8 +1468,8 @@ static int dw2102_probe(struct usb_interface *intf,
/* fill only different fields */
p7500->firmware = "dvb-usb-p7500.fw";
p7500->devices[0] = d7500;
- p7500->rc.legacy.rc_key_map = ir_codes_tbs_table;
- p7500->rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table);
+ p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
+ p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
p7500->adapter->frontend_attach = prof_7500_frontend_attach;
if (0 == dvb_usb_device_init(intf, &dw2102_properties,
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index c821293dbc22..1cb3d9a66e02 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -24,6 +24,33 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+ return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+ return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+ u8 fpga_vers, fw_vers[6];
+
+ if (!gp8psk_get_fw_version(d, fw_vers))
+ info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i",
+ fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+ 2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+ else
+ info("failed to get FW version");
+
+ if (!gp8psk_get_fpga_version(d, &fpga_vers))
+ info("FPGA Version = %i", fpga_vers);
+ else
+ info("failed to get FPGA version");
+}
+
int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
{
int ret = 0,try = 0;
@@ -146,6 +173,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
return -EINVAL;
+ gp8psk_info(d);
}
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
index e83a57506cfa..831749a518cb 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.h
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -25,7 +25,6 @@ extern int dvb_usb_gp8psk_debug;
#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
-/* gp8psk commands */
/* Twinhan Vendor requests */
#define TH_COMMAND_IN 0xC0
@@ -49,8 +48,10 @@ extern int dvb_usb_gp8psk_debug;
#define SET_DVB_MODE 0x8E
#define SET_DN_SWITCH 0x8F
#define GET_SIGNAL_LOCK 0x90 /* in */
+#define GET_FW_VERS 0x92
#define GET_SERIAL_NUMBER 0x93 /* in */
#define USE_EXTRA_VOLT 0x94
+#define GET_FPGA_VERS 0x95
#define CW3K_INIT 0x9d
/* PSK_configuration bits */
@@ -88,6 +89,11 @@ extern int dvb_usb_gp8psk_debug;
#define PRODUCT_STRING_READ 0x0D
#define FW_BCD_VERSION_READ 0x14
+/* firmware revision id's */
+#define GP8PSK_FW_REV1 0x020604
+#define GP8PSK_FW_REV2 0x020704
+#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
+
extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index d939fbbf9fe6..9eea4188303b 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -61,7 +61,7 @@
#define DVB_USB_LOG_PREFIX "LME2510(C)"
#include <linux/usb.h>
#include <linux/usb/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "dvb-usb.h"
#include "lmedm04.h"
@@ -112,7 +112,6 @@ struct lme2510_state {
u8 i2c_tuner_gate_r;
u8 i2c_tuner_addr;
u8 stream_on;
- u8 one_tune;
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
@@ -125,7 +124,7 @@ static int lme2510_bulk_write(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
- snd, len , &actual_l, 500);
+ snd, len , &actual_l, 100);
return ret;
}
@@ -135,7 +134,7 @@ static int lme2510_bulk_read(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
- rev, len , &actual_l, 500);
+ rev, len , &actual_l, 200);
return ret;
}
@@ -167,7 +166,7 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
- msleep(12);
+ msleep(10);
ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
@@ -182,15 +181,13 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
return (ret < 0) ? -ENODEV : 0;
}
-static int lme2510_usb_talk_restart(struct dvb_usb_device *d,
- u8 *wbuf, int wlen, u8 *rbuf, int rlen) {
+static int lme2510_stream_restart(struct dvb_usb_device *d)
+{
static u8 stream_on[] = LME_ST_ON_W;
int ret;
u8 rbuff[10];
- /*Send Normal Command*/
- ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
/*Restart Stream Command*/
- ret |= lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+ ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
rbuff, sizeof(rbuff));
return ret;
}
@@ -201,7 +198,7 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
deb_info(1, "INT Key Keypress =%04x", keypress);
if (keypress > 0)
- ir_keydown(d->rc_input_dev, keypress, 0);
+ rc_keydown(d->rc_dev, keypress, 0);
return 0;
}
@@ -254,11 +251,16 @@ static void lme2510_int_response(struct urb *lme_urb)
case TUNER_S7395:
/* Tweak for earlier firmware*/
if (ibuf[1] == 0x03) {
+ if (ibuf[2] > 1)
+ st->signal_lock = ibuf[2];
st->signal_level = ibuf[3];
st->signal_sn = ibuf[4];
} else {
st->signal_level = ibuf[4];
st->signal_sn = ibuf[5];
+ st->signal_lock =
+ (st->signal_lock & 0xf7) +
+ ((ibuf[2] & 0x01) << 0x03);
}
break;
default:
@@ -341,11 +343,10 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x10)) {
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
- msleep(80);
+ msleep(80);
}
}
break;
@@ -355,15 +356,12 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x8)) {
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
}
if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
msleep(5);
-
-
}
break;
default:
@@ -385,18 +383,16 @@ static int lme2510_msg(struct dvb_usb_device *d,
rbuf[0] = 0x55;
rbuf[1] = st->signal_sn;
break;
- /*DiSEqC functions as per TDA10086*/
- case 0x36:
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- if (wbuf[2] == 0x1c)
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ rbuf[0] = 0x55;
+ rbuf[1] = 0x00;
+ break;
default:
+ lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 1;
break;
}
break;
@@ -413,39 +409,22 @@ static int lme2510_msg(struct dvb_usb_device *d,
break;
case 0x24:
rbuf[0] = 0x55;
- rbuf[1] = (st->signal_level & 0x80)
- ? 0 : st->signal_lock;
- break;
- case 0x6:
- if (wbuf[2] == 0xd0)
- lme2510_usb_talk(d,
- wbuf, wlen, rbuf, rlen);
- break;
- case 0x1:
- if (st->one_tune > 0)
- break;
- st->one_tune++;
- st->i2c_talk_onoff = 1;
- /*DiSEqC functions as per STV0288*/
- case 0x5:
- case 0x7:
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- if (wbuf[2] == 0xd0)
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ rbuf[1] = st->signal_lock;
break;
- default:
+ case 0x2e:
+ case 0x26:
+ case 0x27:
rbuf[0] = 0x55;
rbuf[1] = 0x00;
break;
+ default:
+ lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 1;
+ break;
}
break;
default:
break;
-
}
deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
@@ -548,35 +527,26 @@ static int lme2510_identify_state(struct usb_device *udev,
static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct lme2510_state *st = adap->dev->priv;
- static u8 stream_on[] = LME_ST_ON_W;
static u8 clear_reg_3[] = LME_CLEAR_PID;
static u8 rbuf[1];
- static u8 timeout;
- int ret = 0, len = 2, rlen = sizeof(rbuf);
+ int ret = 0, rlen = sizeof(rbuf);
deb_info(1, "STM (%02x)", onoff);
- if (onoff == 1) {
- st->i2c_talk_onoff = 0;
- timeout = 0;
- /* wait for i2C to be free */
- while (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) {
- timeout++;
- if (timeout > 5)
- return -ENODEV;
- }
- msleep(100);
- ret |= lme2510_usb_talk(adap->dev,
- stream_on, len, rbuf, rlen);
+ /* Streaming is started by FE_HAS_LOCK */
+ if (onoff == 1)
st->stream_on = 1;
- st->one_tune = 0;
- mutex_unlock(&adap->dev->i2c_mutex);
- } else {
+ else {
deb_info(1, "STM Steam Off");
+ /* mutex is here only to avoid collision with I2C */
+ ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+
ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
+
+ mutex_unlock(&adap->dev->i2c_mutex);
}
return (ret < 0) ? -ENODEV : 0;
@@ -585,41 +555,40 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int lme2510_int_service(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap->dev;
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_LME2510;
- int ret = 0;
+ struct rc_dev *rc;
+ int ret;
info("STA Configuring Remote");
- usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-
- strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
- input_dev = input_allocate_device();
- if (!input_dev)
+ rc = rc_allocate_device();
+ if (!rc)
return -ENOMEM;
- input_dev->name = "LME2510 Remote Control";
- input_dev->phys = d->rc_phys;
-
- usb_to_input_id(d->udev, &input_dev->id);
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
+ rc->input_name = "LME2510 Remote Control";
+ rc->input_phys = d->rc_phys;
+ rc->map_name = RC_MAP_LME2510;
+ rc->driver_name = "LME 2510";
+ usb_to_input_id(d->udev, &rc->input_id);
+ ret = rc_register_device(rc);
if (ret) {
- input_free_device(input_dev);
+ rc_free_device(rc);
return ret;
}
+ d->rc_dev = rc;
- d->rc_input_dev = input_dev;
/* Start the Interupt */
ret = lme2510_int_read(adap);
-
if (ret < 0) {
- ir_input_unregister(input_dev);
- input_free_device(input_dev);
+ rc_unregister_device(rc);
+ info("INT Unable to start Interupt Service");
+ return -ENODEV;
}
- return (ret < 0) ? -ENODEV : 0;
+
+ return 0;
}
static u8 check_sum(u8 *p, u8 len)
@@ -668,6 +637,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
ret |= (data[0] == 0x88) ? 0 : -1;
}
}
+
usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
@@ -701,10 +671,11 @@ static void lme_coldreset(struct usb_device *dev)
info("FRM Firmware Cold Reset");
ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
ret |= lme2510_bulk_read(dev, data, len_in, 1);
+
return;
}
-static void lme_firmware_switch(struct usb_device *udev, int cold)
+static int lme_firmware_switch(struct usb_device *udev, int cold)
{
const struct firmware *fw = NULL;
char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
@@ -712,8 +683,10 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
char *firm_msg[] = {"Loading", "Switching to"};
int ret;
+ cold = (cold > 0) ? (cold & 1) : 0;
+
if (udev->descriptor.idProduct == 0x1122)
- return;
+ return 0;
switch (dvb_usb_lme2510_firmware) {
case 0:
@@ -740,22 +713,28 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
cold = 0;
break;
}
+
release_firmware(fw);
- if (cold)
+
+ if (cold) {
lme_coldreset(udev);
- return;
+ return -ENODEV;
+ }
+
+ return ret;
}
static int lme2510_kill_urb(struct usb_data_stream *stream)
{
int i;
+
for (i = 0; i < stream->urbs_submitted; i++) {
deb_info(3, "killing URB no. %d.", i);
-
/* stop the URB */
usb_kill_urb(stream->urb_list[i]);
}
stream->urbs_submitted = 0;
+
return 0;
}
@@ -783,18 +762,13 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct lme2510_state *st = adap->dev->priv;
static u8 voltage_low[] = LME_VOLTAGE_L;
static u8 voltage_high[] = LME_VOLTAGE_H;
- static u8 lnb_on[] = LNB_ON;
- static u8 lnb_off[] = LNB_OFF;
static u8 rbuf[1];
int ret = 0, len = 3, rlen = 1;
- if (st->stream_on == 1)
- return 0;
-
- ret |= lme2510_usb_talk(adap->dev, lnb_on, len, rbuf, rlen);
+ if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
+ return -EAGAIN;
switch (voltage) {
case SEC_VOLTAGE_18:
@@ -803,94 +777,143 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
break;
case SEC_VOLTAGE_OFF:
- ret |= lme2510_usb_talk(adap->dev,
- lnb_off, len, rbuf, rlen);
case SEC_VOLTAGE_13:
default:
ret |= lme2510_usb_talk(adap->dev,
voltage_low, len, rbuf, rlen);
break;
+ }
+ mutex_unlock(&adap->dev->i2c_mutex);
- };
- st->i2c_talk_onoff = 1;
return (ret < 0) ? -ENODEV : 0;
}
+static int lme_name(struct dvb_usb_adapter *adap)
+{
+ struct lme2510_state *st = adap->dev->priv;
+ const char *desc = adap->dev->desc->name;
+ char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"};
+ char *name = adap->fe->ops.info.name;
+
+ strlcpy(name, desc, 128);
+ strlcat(name, fe_name[st->tuner_config], 128);
+
+ return 0;
+}
+
static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
{
- int ret = 0;
struct lme2510_state *st = adap->dev->priv;
- /* Interupt Start */
- ret = lme2510_int_service(adap);
- if (ret < 0) {
- info("INT Unable to start Interupt Service");
- return -ENODEV;
- }
+ int ret = 0;
st->i2c_talk_onoff = 1;
- st->i2c_gate = 4;
+ st->i2c_gate = 4;
adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
&adap->dev->i2c_adap);
if (adap->fe) {
info("TUN Found Frontend TDA10086");
- memcpy(&adap->fe->ops.info.name,
- &"DM04_LG_TDQY-P001F DVB-S", 24);
- adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 4;
st->i2c_tuner_addr = 0xc0;
- if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
- &adap->dev->i2c_adap, 1)) {
- info("TUN TDA8263 Found");
- st->tuner_config = TUNER_LG;
- if (dvb_usb_lme2510_firmware != 1) {
- dvb_usb_lme2510_firmware = 1;
- lme_firmware_switch(adap->dev->udev, 1);
- }
- return 0;
- }
- kfree(adap->fe);
- adap->fe = NULL;
+ st->tuner_config = TUNER_LG;
+ if (dvb_usb_lme2510_firmware != 1) {
+ dvb_usb_lme2510_firmware = 1;
+ ret = lme_firmware_switch(adap->dev->udev, 1);
+ } else /*stops LG/Sharp multi tuner problems*/
+ dvb_usb_lme2510_firmware = 0;
+ goto end;
}
+
st->i2c_gate = 5;
adap->fe = dvb_attach(stv0288_attach, &lme_config,
&adap->dev->i2c_adap);
if (adap->fe) {
info("FE Found Stv0288");
- memcpy(&adap->fe->ops.info.name,
- &"DM04_SHARP:BS2F7HZ7395", 22);
- adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
- if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
- &adap->dev->i2c_adap)) {
- st->tuner_config = TUNER_S7395;
- info("TUN Sharp IX2505V silicon tuner");
- if (dvb_usb_lme2510_firmware != 0) {
- dvb_usb_lme2510_firmware = 0;
- lme_firmware_switch(adap->dev->udev, 1);
- }
- return 0;
+ st->tuner_config = TUNER_S7395;
+ if (dvb_usb_lme2510_firmware != 0) {
+ dvb_usb_lme2510_firmware = 0;
+ ret = lme_firmware_switch(adap->dev->udev, 1);
}
+ } else {
+ info("DM04 Not Supported");
+ return -ENODEV;
+ }
+
+end: if (ret) {
kfree(adap->fe);
adap->fe = NULL;
+ return -ENODEV;
}
- info("DM04 Not Supported");
- return -ENODEV;
+ adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
+ ret = lme_name(adap);
+
+ return ret;
+}
+
+static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
+{
+ struct lme2510_state *st = adap->dev->priv;
+ char *tun_msg[] = {"", "TDA8263", "IX2505V"};
+ int ret = 0;
+
+ switch (st->tuner_config) {
+ case TUNER_LG:
+ if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
+ &adap->dev->i2c_adap, 1))
+ ret = st->tuner_config;
+ break;
+ case TUNER_S7395:
+ if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
+ &adap->dev->i2c_adap))
+ ret = st->tuner_config;
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ info("TUN Found %s tuner", tun_msg[ret]);
+ else {
+ info("TUN No tuner found --- reseting device");
+ lme_coldreset(adap->dev->udev);
+ return -ENODEV;
+ }
+
+ /* Start the Interupt & Remote*/
+ ret = lme2510_int_service(adap);
+
+ return ret;
}
static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
{
struct lme2510_state *st = d->priv;
+ static u8 lnb_on[] = LNB_ON;
+ static u8 lnb_off[] = LNB_OFF;
+ static u8 rbuf[1];
+ int ret, len = 3, rlen = 1;
+
+ ret = mutex_lock_interruptible(&d->i2c_mutex);
+
+ if (onoff)
+ ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+ else
+ ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+
st->i2c_talk_onoff = 1;
- return 0;
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
}
/* DVB USB Driver stuff */
@@ -951,6 +974,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
{
.streaming_ctrl = lme2510_streaming_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
+ .tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
@@ -971,7 +995,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
.generic_bulk_ctrl_endpoint = 0,
.num_device_descs = 1,
.devices = {
- { "DM04 LME2510 DVB-S USB 2.0",
+ { "DM04_LME2510_DVB-S",
{ &lme2510_table[0], NULL },
},
@@ -989,6 +1013,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
{
.streaming_ctrl = lme2510_streaming_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
+ .tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
@@ -1009,7 +1034,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
.generic_bulk_ctrl_endpoint = 0,
.num_device_descs = 1,
.devices = {
- { "DM04 LME2510C USB2.0",
+ { "DM04_LME2510C_DVB-S",
{ &lme2510_table[1], NULL },
},
}
@@ -1036,7 +1061,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
usb_free_coherent(d->udev, 5000, st->buffer,
st->lme_urb->transfer_dma);
info("Interupt Service Stopped");
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
info("Remote Stopped");
}
return buffer;
@@ -1055,7 +1080,7 @@ void lme2510_exit(struct usb_interface *intf)
}
static struct usb_driver lme2510_driver = {
- .name = "LME2510C_DVBS",
+ .name = "LME2510C_DVB-S",
.probe = lme2510_probe,
.disconnect = lme2510_exit,
.id_table = lme2510_table,
@@ -1083,6 +1108,6 @@ module_init(lme2510_module_init);
module_exit(lme2510_module_exit);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.60");
+MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
+MODULE_VERSION("1.74");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index bdef1a18b664..da9dc91ce910 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -142,9 +142,9 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
goto unlock;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
- if (rc5_data(&d->props.rc.legacy.rc_key_map[i]) == rc_state[1]) {
- *event = d->props.rc.legacy.rc_key_map[i].keycode;
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
+ if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
+ *event = d->props.rc.legacy.rc_map_table[i].keycode;
switch(rc_state[0]) {
case 0x80:
@@ -589,7 +589,7 @@ static struct m920x_inits pinnacle310e_init[] = {
};
/* ir keymaps */
-static struct ir_scancode ir_codes_megasky_table[] = {
+static struct rc_map_table rc_map_megasky_table[] = {
{ 0x0012, KEY_POWER },
{ 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
{ 0x0002, KEY_CHANNELUP },
@@ -608,7 +608,7 @@ static struct ir_scancode ir_codes_megasky_table[] = {
{ 0x000e, KEY_COFFEE }, /* "MTS" */
};
-static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
+static struct rc_map_table rc_map_tvwalkertwin_table[] = {
{ 0x0001, KEY_ZOOM }, /* Full Screen */
{ 0x0002, KEY_CAMERA }, /* snapshot */
{ 0x0003, KEY_MUTE },
@@ -628,7 +628,7 @@ static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
{ 0x001e, KEY_VOLUMEUP },
};
-static struct ir_scancode ir_codes_pinnacle310e_table[] = {
+static struct rc_map_table rc_map_pinnacle310e_table[] = {
{ 0x16, KEY_POWER },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
@@ -786,8 +786,8 @@ static struct dvb_usb_device_properties megasky_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_megasky_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table),
+ .rc_map_table = rc_map_megasky_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
.rc_query = m920x_rc_query,
},
@@ -889,8 +889,8 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_tvwalkertwin_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table),
+ .rc_map_table = rc_map_tvwalkertwin_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
.rc_query = m920x_rc_query,
},
@@ -998,8 +998,8 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_pinnacle310e_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table),
+ .rc_map_table = rc_map_pinnacle310e_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
.rc_query = m920x_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 181f36a12e2a..9d3cd2de46fc 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -21,7 +21,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define deb_ee(args...) dprintk(debug,0x02,args)
/* Hauppauge NOVA-T USB2 keys */
-static struct ir_scancode ir_codes_haupp_table[] = {
+static struct rc_map_table rc_map_haupp_table[] = {
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
{ 0x1e02, KEY_2 },
@@ -91,14 +91,14 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
- for (i = 0; i < ARRAY_SIZE(ir_codes_haupp_table); i++) {
- if (rc5_data(&ir_codes_haupp_table[i]) == data &&
- rc5_custom(&ir_codes_haupp_table[i]) == custom) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
+ if (rc5_data(&rc_map_haupp_table[i]) == data &&
+ rc5_custom(&rc_map_haupp_table[i]) == custom) {
- deb_rc("c: %x, d: %x\n", rc5_data(&ir_codes_haupp_table[i]),
- rc5_custom(&ir_codes_haupp_table[i]));
+ deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
+ rc5_custom(&rc_map_haupp_table[i]));
- *event = ir_codes_haupp_table[i].keycode;
+ *event = rc_map_haupp_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
if (st->old_toggle == toggle) {
if (st->last_repeat_count++ < 2)
@@ -197,8 +197,8 @@ static struct dvb_usb_device_properties nova_t_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_haupp_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table),
+ .rc_map_table = rc_map_haupp_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
.rc_query = nova_t_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index f896337b4535..1f1b7d6980a5 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -35,7 +35,7 @@
struct opera1_state {
u32 last_key_pressed;
};
-struct ir_codes_opera_table {
+struct rc_map_opera_table {
u32 keycode;
u32 event;
};
@@ -331,7 +331,7 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
return 0;
}
-static struct ir_scancode ir_codes_opera1_table[] = {
+static struct rc_map_table rc_map_opera1_table[] = {
{0x5fa0, KEY_1},
{0x51af, KEY_2},
{0x5da2, KEY_3},
@@ -404,12 +404,12 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
send_key = (send_key & 0xffff) | 0x0100;
- for (i = 0; i < ARRAY_SIZE(ir_codes_opera1_table); i++) {
- if (rc5_scan(&ir_codes_opera1_table[i]) == (send_key & 0xffff)) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
+ if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_opera1_table[i].keycode;
+ *event = rc_map_opera1_table[i].keycode;
opst->last_key_pressed =
- ir_codes_opera1_table[i].keycode;
+ rc_map_opera1_table[i].keycode;
break;
}
opst->last_key_pressed = 0;
@@ -497,8 +497,8 @@ static struct dvb_usb_device_properties opera1_properties = {
.i2c_algo = &opera1_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_opera1_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table),
+ .rc_map_table = rc_map_opera1_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
.rc_interval = 200,
.rc_query = opera1_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 5c9f3275aaa0..7890e75600df 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -174,7 +174,7 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
}
/* keys for the enclosed remote control */
-static struct ir_scancode ir_codes_vp702x_table[] = {
+static struct rc_map_table rc_map_vp702x_table[] = {
{ 0x0001, KEY_1 },
{ 0x0002, KEY_2 },
};
@@ -197,10 +197,10 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
- for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++)
- if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
+ if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_vp702x_table[i].keycode;
+ *event = rc_map_vp702x_table[i].keycode;
break;
}
return 0;
@@ -284,8 +284,8 @@ static struct dvb_usb_device_properties vp702x_properties = {
.read_mac_address = vp702x_read_mac_addr,
.rc.legacy = {
- .rc_key_map = ir_codes_vp702x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table),
+ .rc_map_table = rc_map_vp702x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
.rc_interval = 400,
.rc_query = vp702x_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index f13791ca5994..ab0ab3c35e80 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -99,7 +99,7 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded. */
-static struct ir_scancode ir_codes_vp7045_table[] = {
+static struct rc_map_table rc_map_vp7045_table[] = {
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
{ 0x0003, KEY_1 },
@@ -165,10 +165,10 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
- for (i = 0; i < ARRAY_SIZE(ir_codes_vp7045_table); i++)
- if (rc5_data(&ir_codes_vp7045_table[i]) == key) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
+ if (rc5_data(&rc_map_vp7045_table[i]) == key) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_vp7045_table[i].keycode;
+ *event = rc_map_vp7045_table[i].keycode;
break;
}
return 0;
@@ -261,8 +261,8 @@ static struct dvb_usb_device_properties vp7045_properties = {
.rc.legacy = {
.rc_interval = 400,
- .rc_key_map = ir_codes_vp7045_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table),
+ .rc_map_table = rc_map_vp7045_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
.rc_query = vp7045_rc_query,
},
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index e9062b08a485..ef3e43a03199 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -12,9 +12,8 @@ config DVB_FE_CUSTOMISE
If unsure say N.
-if DVB_FE_CUSTOMISE
-
menu "Customise DVB Frontends"
+ visible if DVB_FE_CUSTOMISE
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -498,7 +497,7 @@ comment "ISDB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_S921
- tristate "Sharp S921 tuner"
+ tristate "Sharp S921 frontend"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@@ -513,6 +512,14 @@ config DVB_DIB8000
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
+config DVB_MB86A20S
+ tristate "Fujitsu mb86a20s"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
+ Say Y when you want to support this frontend.
+
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
@@ -619,5 +626,3 @@ config DVB_DUMMY_FE
tristate "Dummy frontend driver"
default n
endmenu
-
-endif
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 9a31985c0dfb..b1d9525aa7e3 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -5,7 +5,6 @@
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
EXTRA_CFLAGS += -Idrivers/media/common/tuners/
-s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
stv0900-objs = stv0900_core.o stv0900_sw.o
au8522-objs = au8522_dig.o au8522_decoder.o
@@ -82,4 +81,5 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o
obj-$(CONFIG_DVB_EC100) += ec100.o
obj-$(CONFIG_DVB_DS3000) += ds3000.o
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index e2a95c07bab4..ce222055526d 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -964,7 +964,7 @@ error:
static int af9013_update_signal_strength(struct dvb_frontend *fe)
{
struct af9013_state *state = fe->demodulator_priv;
- int ret;
+ int ret = 0;
u8 rf_gain, if_gain;
int signal_strength;
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
index 43aac2f85c2e..1539ea1f81ac 100644
--- a/drivers/media/dvb/frontends/atbm8830.c
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -50,8 +50,7 @@ static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
msg2.addr = dev_addr;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1)
@@ -77,8 +76,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1) {
- dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
@@ -88,7 +86,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
*p_data = buf2[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+ dprintk("%s: reg=0x%04X, data=0x%02X\n",
__func__, reg, buf2[0]);
return 0;
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 6d9c5943eb3d..b537891a4cc9 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -278,10 +278,18 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
- au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
- AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
- au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
- AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+ input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
+ } else {
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ }
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
@@ -347,9 +355,11 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+ /* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
- au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
- au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ /* Enable clamping control */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
@@ -366,14 +376,14 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
- /* It's not clear why they turn off the PGA before enabling the clamp
- control, but the Windows trace does it so we will too... */
+ /* It's not clear why we have to have the PGA in automatic mode while
+ enabling clamp control, but it's what Windows does */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
- /* Turn on the PGA */
+ /* Disable automatic PGA (since the CVBS is coming from the tuner) */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
@@ -396,7 +406,10 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
- /* Disable clamping control (required for S-video) */
+ /* PGA in automatic mode */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+ /* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
setup_decoder_defaults(state,
@@ -410,29 +423,15 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
static void disable_audio_input(struct au8522_state *state)
{
- /* This can probably be optimized */
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
- au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
- au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
-
- au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
- au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
- au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
- au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
- au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
-
- au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
- msleep(5);
- au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
- au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
- AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
}
/* 0=disable, 1=SIF */
@@ -622,7 +621,7 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return v4l2_ctrl_query_fill(qc, 0, 255, 1,
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_HUE:
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index 609cf04bc312..751e17d692a9 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -397,7 +397,9 @@ void au8522_release_state(struct au8522_state *state);
#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO 0x2a
#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO 0x15
#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 0f09fd31cb29..c7f5ccf54aa5 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -805,7 +805,7 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte
value = 0;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
- case /* 4K MODE */ 255: value |= (2 << 7); break;
+ case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
default:
case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
}
@@ -866,7 +866,7 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte
/* P_dvsy_sync_wait */
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_8K: value = 256; break;
- case /* 4K MODE */ 255: value = 128; break;
+ case TRANSMISSION_MODE_4K: value = 128; break;
case TRANSMISSION_MODE_2K:
default: value = 64; break;
}
@@ -1020,7 +1020,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (6 << 8) | 0x80;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
- case /* 4K MODE */ 255: value |= (8 << 12); break;
+ case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
default:
case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
}
@@ -1030,7 +1030,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= 0x6; break;
- case /* 4K MODE */ 255: value |= 0x7; break;
+ case TRANSMISSION_MODE_4K: value |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: value |= 0x8; break;
}
@@ -1040,7 +1040,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= 0x6; break;
- case /* 4K MODE */ 255: value |= 0x7; break;
+ case TRANSMISSION_MODE_4K: value |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: value |= 0x8; break;
}
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 3aed0d433921..6aa02cb80733 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -717,7 +717,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
value = 0;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
- case /* 4K MODE */ 255: value |= (2 << 7); break;
+ case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
default:
case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
}
@@ -770,7 +770,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
/* P_dvsy_sync_wait */
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_8K: value = 256; break;
- case /* 4K MODE */ 255: value = 128; break;
+ case TRANSMISSION_MODE_4K: value = 128; break;
case TRANSMISSION_MODE_2K:
default: value = 64; break;
}
@@ -994,7 +994,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (6 << 8) | 0x80;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
- case /* 4K MODE */ 255: tmp |= (8 << 12); break;
+ case TRANSMISSION_MODE_4K: tmp |= (8 << 12); break;
default:
case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
}
@@ -1004,7 +1004,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
- case /* 4K MODE */ 255: tmp |= 0x7; break;
+ case TRANSMISSION_MODE_4K: tmp |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
}
@@ -1014,7 +1014,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
- case /* 4K MODE */ 255: tmp |= 0x7; break;
+ case TRANSMISSION_MODE_4K: tmp |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
}
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
index 55f2eba7bc96..6360c681ded9 100644
--- a/drivers/media/dvb/frontends/ix2505v.c
+++ b/drivers/media/dvb/frontends/ix2505v.c
@@ -72,7 +72,7 @@ static int ix2505v_read_status_reg(struct ix2505v_state *state)
ret = i2c_transfer(state->i2c, msg, 1);
deb_i2c("Read %s ", __func__);
- return (ret = 1) ? (int) b2[0] : -1;
+ return (ret == 1) ? (int) b2[0] : -1;
}
static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index 0fcddc4569d2..1172b54689f8 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -60,13 +60,12 @@ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
msg.addr += 0x02;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
- dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
@@ -91,15 +90,13 @@ static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
- dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -1;
}
*p_data = b1[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, b1[0]);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
return 0;
}
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c
new file mode 100644
index 000000000000..d3ad3e75a35a
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.c
@@ -0,0 +1,615 @@
+/*
+ * Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * FIXME: Need to port to DVB v5.2 API
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "mb86a20s.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...) do { \
+ printk(KERN_ERR "mb86a20s: " args); \
+} while (0)
+
+#define dprintk(args...) \
+ do { \
+ if (debug) { \
+ printk(KERN_DEBUG "mb86a20s: %s: ", __func__); \
+ printk(args); \
+ } \
+ } while (0)
+
+struct mb86a20s_state {
+ struct i2c_adapter *i2c;
+ const struct mb86a20s_config *config;
+
+ struct dvb_frontend frontend;
+};
+
+struct regdata {
+ u8 reg;
+ u8 data;
+};
+
+/*
+ * Initialization sequence: Use whatevere default values that PV SBTVD
+ * does on its initialisation, obtained via USB snoop
+ */
+static struct regdata mb86a20s_init[] = {
+ { 0x70, 0x0f },
+ { 0x70, 0xff },
+ { 0x08, 0x01 },
+ { 0x09, 0x3e },
+ { 0x50, 0xd1 },
+ { 0x51, 0x22 },
+ { 0x39, 0x01 },
+ { 0x71, 0x00 },
+ { 0x28, 0x2a },
+ { 0x29, 0x00 },
+ { 0x2a, 0xff },
+ { 0x2b, 0x80 },
+ { 0x28, 0x20 },
+ { 0x29, 0x33 },
+ { 0x2a, 0xdf },
+ { 0x2b, 0xa9 },
+ { 0x3b, 0x21 },
+ { 0x3c, 0x3a },
+ { 0x01, 0x0d },
+ { 0x04, 0x08 },
+ { 0x05, 0x05 },
+ { 0x04, 0x0e },
+ { 0x05, 0x00 },
+ { 0x04, 0x0f },
+ { 0x05, 0x14 },
+ { 0x04, 0x0b },
+ { 0x05, 0x8c },
+ { 0x04, 0x00 },
+ { 0x05, 0x00 },
+ { 0x04, 0x01 },
+ { 0x05, 0x07 },
+ { 0x04, 0x02 },
+ { 0x05, 0x0f },
+ { 0x04, 0x03 },
+ { 0x05, 0xa0 },
+ { 0x04, 0x09 },
+ { 0x05, 0x00 },
+ { 0x04, 0x0a },
+ { 0x05, 0xff },
+ { 0x04, 0x27 },
+ { 0x05, 0x64 },
+ { 0x04, 0x28 },
+ { 0x05, 0x00 },
+ { 0x04, 0x1e },
+ { 0x05, 0xff },
+ { 0x04, 0x29 },
+ { 0x05, 0x0a },
+ { 0x04, 0x32 },
+ { 0x05, 0x0a },
+ { 0x04, 0x14 },
+ { 0x05, 0x02 },
+ { 0x04, 0x04 },
+ { 0x05, 0x00 },
+ { 0x04, 0x05 },
+ { 0x05, 0x22 },
+ { 0x04, 0x06 },
+ { 0x05, 0x0e },
+ { 0x04, 0x07 },
+ { 0x05, 0xd8 },
+ { 0x04, 0x12 },
+ { 0x05, 0x00 },
+ { 0x04, 0x13 },
+ { 0x05, 0xff },
+ { 0x52, 0x01 },
+ { 0x50, 0xa7 },
+ { 0x51, 0x00 },
+ { 0x50, 0xa8 },
+ { 0x51, 0xff },
+ { 0x50, 0xa9 },
+ { 0x51, 0xff },
+ { 0x50, 0xaa },
+ { 0x51, 0x00 },
+ { 0x50, 0xab },
+ { 0x51, 0xff },
+ { 0x50, 0xac },
+ { 0x51, 0xff },
+ { 0x50, 0xad },
+ { 0x51, 0x00 },
+ { 0x50, 0xae },
+ { 0x51, 0xff },
+ { 0x50, 0xaf },
+ { 0x51, 0xff },
+ { 0x5e, 0x07 },
+ { 0x50, 0xdc },
+ { 0x51, 0x01 },
+ { 0x50, 0xdd },
+ { 0x51, 0xf4 },
+ { 0x50, 0xde },
+ { 0x51, 0x01 },
+ { 0x50, 0xdf },
+ { 0x51, 0xf4 },
+ { 0x50, 0xe0 },
+ { 0x51, 0x01 },
+ { 0x50, 0xe1 },
+ { 0x51, 0xf4 },
+ { 0x50, 0xb0 },
+ { 0x51, 0x07 },
+ { 0x50, 0xb2 },
+ { 0x51, 0xff },
+ { 0x50, 0xb3 },
+ { 0x51, 0xff },
+ { 0x50, 0xb4 },
+ { 0x51, 0xff },
+ { 0x50, 0xb5 },
+ { 0x51, 0xff },
+ { 0x50, 0xb6 },
+ { 0x51, 0xff },
+ { 0x50, 0xb7 },
+ { 0x51, 0xff },
+ { 0x50, 0x50 },
+ { 0x51, 0x02 },
+ { 0x50, 0x51 },
+ { 0x51, 0x04 },
+ { 0x45, 0x04 },
+ { 0x48, 0x04 },
+ { 0x50, 0xd5 },
+ { 0x51, 0x01 }, /* Serial */
+ { 0x50, 0xd6 },
+ { 0x51, 0x1f },
+ { 0x50, 0xd2 },
+ { 0x51, 0x03 },
+ { 0x50, 0xd7 },
+ { 0x51, 0x3f },
+ { 0x1c, 0x01 },
+ { 0x28, 0x06 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x03 },
+ { 0x28, 0x07 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0d },
+ { 0x28, 0x08 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x02 },
+ { 0x28, 0x09 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x01 },
+ { 0x28, 0x0a },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x21 },
+ { 0x28, 0x0b },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x29 },
+ { 0x28, 0x0c },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x16 },
+ { 0x28, 0x0d },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x31 },
+ { 0x28, 0x0e },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0e },
+ { 0x28, 0x0f },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x4e },
+ { 0x28, 0x10 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x46 },
+ { 0x28, 0x11 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0f },
+ { 0x28, 0x12 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x56 },
+ { 0x28, 0x13 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x35 },
+ { 0x28, 0x14 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0xbe },
+ { 0x28, 0x15 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0x84 },
+ { 0x28, 0x16 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x03 },
+ { 0x2b, 0xee },
+ { 0x28, 0x17 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x98 },
+ { 0x28, 0x18 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x9f },
+ { 0x28, 0x19 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x07 },
+ { 0x2b, 0xb2 },
+ { 0x28, 0x1a },
+ { 0x29, 0x00 },
+ { 0x2a, 0x06 },
+ { 0x2b, 0xc2 },
+ { 0x28, 0x1b },
+ { 0x29, 0x00 },
+ { 0x2a, 0x07 },
+ { 0x2b, 0x4a },
+ { 0x28, 0x1c },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0xbc },
+ { 0x28, 0x1d },
+ { 0x29, 0x00 },
+ { 0x2a, 0x04 },
+ { 0x2b, 0xba },
+ { 0x28, 0x1e },
+ { 0x29, 0x00 },
+ { 0x2a, 0x06 },
+ { 0x2b, 0x14 },
+ { 0x50, 0x1e },
+ { 0x51, 0x5d },
+ { 0x50, 0x22 },
+ { 0x51, 0x00 },
+ { 0x50, 0x23 },
+ { 0x51, 0xc8 },
+ { 0x50, 0x24 },
+ { 0x51, 0x00 },
+ { 0x50, 0x25 },
+ { 0x51, 0xf0 },
+ { 0x50, 0x26 },
+ { 0x51, 0x00 },
+ { 0x50, 0x27 },
+ { 0x51, 0xc3 },
+ { 0x50, 0x39 },
+ { 0x51, 0x02 },
+ { 0x50, 0xd5 },
+ { 0x51, 0x01 },
+ { 0xd0, 0x00 },
+};
+
+static struct regdata mb86a20s_reset_reception[] = {
+ { 0x70, 0xf0 },
+ { 0x70, 0xff },
+ { 0x08, 0x01 },
+ { 0x08, 0x00 },
+};
+
+static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
+ u8 i2c_addr, int reg, int data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+ };
+ int rc;
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (rc != 1) {
+ printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+ " data == 0x%02x)\n", __func__, rc, reg, data);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
+ u8 i2c_addr, struct regdata *rd, int size)
+{
+ int i, rc;
+
+ for (i = 0; i < size; i++) {
+ rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
+ rd[i].data);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
+ u8 i2c_addr, u8 reg)
+{
+ u8 val;
+ int rc;
+ struct i2c_msg msg[] = {
+ { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+ };
+
+ rc = i2c_transfer(state->i2c, msg, 2);
+
+ if (rc != 2) {
+ rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+ return rc;
+ }
+
+ return val;
+}
+
+#define mb86a20s_readreg(state, reg) \
+ mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
+#define mb86a20s_writereg(state, reg, val) \
+ mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
+#define mb86a20s_writeregdata(state, regdata) \
+ mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
+ regdata, ARRAY_SIZE(regdata))
+
+static int mb86a20s_initfe(struct dvb_frontend *fe)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ int rc;
+ u8 regD5 = 1;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ /* Initialize the frontend */
+ rc = mb86a20s_writeregdata(state, mb86a20s_init);
+ if (rc < 0)
+ return rc;
+
+ if (!state->config->is_serial) {
+ regD5 &= ~1;
+
+ rc = mb86a20s_writereg(state, 0x50, 0xd5);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, regD5);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return 0;
+}
+
+static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ unsigned rf_max, rf_min, rf;
+ u8 val;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ /* Does a binary search to get RF strength */
+ rf_max = 0xfff;
+ rf_min = 0;
+ do {
+ rf = (rf_max + rf_min) / 2;
+ mb86a20s_writereg(state, 0x04, 0x1f);
+ mb86a20s_writereg(state, 0x05, rf >> 8);
+ mb86a20s_writereg(state, 0x04, 0x20);
+ mb86a20s_writereg(state, 0x04, rf);
+
+ val = mb86a20s_readreg(state, 0x02);
+ if (val & 0x08)
+ rf_min = (rf_max + rf_min) / 2;
+ else
+ rf_max = (rf_max + rf_min) / 2;
+ if (rf_max - rf_min < 4) {
+ *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
+ break;
+ }
+ } while (1);
+
+ dprintk("signal strength = %d\n", *strength);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return 0;
+}
+
+static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ u8 val;
+
+ dprintk("\n");
+ *status = 0;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ val = mb86a20s_readreg(state, 0x0a) & 0xf;
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ if (val >= 2)
+ *status |= FE_HAS_SIGNAL;
+
+ if (val >= 4)
+ *status |= FE_HAS_CARRIER;
+
+ if (val >= 5)
+ *status |= FE_HAS_VITERBI;
+
+ if (val >= 7)
+ *status |= FE_HAS_SYNC;
+
+ if (val >= 8) /* Maybe 9? */
+ *status |= FE_HAS_LOCK;
+
+ dprintk("val = %d, status = 0x%02x\n", val, *status);
+
+ return 0;
+}
+
+static int mb86a20s_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ fe->ops.tuner_ops.set_params(fe, p);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return rc;
+}
+
+static int mb86a20s_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+
+ /* FIXME: For now, it does nothing */
+
+ fe->dtv_property_cache.bandwidth_hz = 6000000;
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+ fe->dtv_property_cache.isdbt_partial_reception = 0;
+
+ return 0;
+}
+
+static int mb86a20s_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
+ unsigned int mode_flags,
+ unsigned int *delay,
+ fe_status_t *status)
+{
+ int rc = 0;
+
+ dprintk("\n");
+
+ if (params != NULL)
+ rc = mb86a20s_set_frontend(fe, params);
+
+ if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+ mb86a20s_read_status(fe, status);
+
+ return rc;
+}
+
+static void mb86a20s_release(struct dvb_frontend *fe)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+
+ dprintk("\n");
+
+ kfree(state);
+}
+
+static struct dvb_frontend_ops mb86a20s_ops;
+
+struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+ struct i2c_adapter *i2c)
+{
+ u8 rev;
+
+ /* allocate memory for the internal state */
+ struct mb86a20s_state *state =
+ kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
+
+ dprintk("\n");
+ if (state == NULL) {
+ rc("Unable to kzalloc\n");
+ goto error;
+ }
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &mb86a20s_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* Check if it is a mb86a20s frontend */
+ rev = mb86a20s_readreg(state, 0);
+
+ if (rev == 0x13) {
+ printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
+ } else {
+ printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
+ rev);
+ goto error;
+ }
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(mb86a20s_attach);
+
+static struct dvb_frontend_ops mb86a20s_ops = {
+ /* Use dib8000 values per default */
+ .info = {
+ .name = "Fujitsu mb86A20s",
+ .type = FE_OFDM,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+ /* Actually, those values depend on the used tuner */
+ .frequency_min = 45000000,
+ .frequency_max = 864000000,
+ .frequency_stepsize = 62500,
+ },
+
+ .release = mb86a20s_release,
+
+ .init = mb86a20s_initfe,
+ .set_frontend = mb86a20s_set_frontend,
+ .get_frontend = mb86a20s_get_frontend,
+ .read_status = mb86a20s_read_status,
+ .read_signal_strength = mb86a20s_read_signal_strength,
+ .tune = mb86a20s_tune,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb/frontends/mb86a20s.h
new file mode 100644
index 000000000000..bf22e77888b9
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.h
@@ -0,0 +1,52 @@
+/*
+ * Fujitsu mb86a20s driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 MB86A20S_H
+#define MB86A20S_H
+
+#include <linux/dvb/frontend.h>
+
+/**
+ * struct mb86a20s_config - Define the per-device attributes of the frontend
+ *
+ * @demod_address: the demodulator's i2c address
+ */
+
+struct mb86a20s_config {
+ u8 demod_address;
+ bool is_serial;
+};
+
+#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+ struct i2c_adapter *i2c);
+extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *mb86a20s_attach(
+ const struct mb86a20s_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static struct i2c_adapter *
+ mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* MB86A20S */
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c
new file mode 100644
index 000000000000..ca0103d5f148
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.c
@@ -0,0 +1,548 @@
+/*
+ * Sharp VA3A5JZ921 One Seg Broadcast Module driver
+ * This device is labeled as just S. 921 at the top of the frontend can
+ *
+ * Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * Developed for Leadership SBTVD 1seg device sold in Brazil
+ *
+ * Frontend module based on cx24123 driver, getting some info from
+ * the old s921 driver.
+ *
+ * FIXME: Need to port to DVB v5.2 API
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "s921.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...) do { \
+ printk(KERN_ERR "s921: " args); \
+} while (0)
+
+#define dprintk(args...) \
+ do { \
+ if (debug) { \
+ printk(KERN_DEBUG "s921: %s: ", __func__); \
+ printk(args); \
+ } \
+ } while (0)
+
+struct s921_state {
+ struct i2c_adapter *i2c;
+ const struct s921_config *config;
+
+ struct dvb_frontend frontend;
+
+ /* The Demod can't easily provide these, we cache them */
+ u32 currentfreq;
+};
+
+/*
+ * Various tuner defaults need to be established for a given frequency kHz.
+ * fixme: The bounds on the bands do not match the doc in real life.
+ * fixme: Some of them have been moved, other might need adjustment.
+ */
+static struct s921_bandselect_val {
+ u32 freq_low;
+ u8 band_reg;
+} s921_bandselect[] = {
+ { 0, 0x7b },
+ { 485140000, 0x5b },
+ { 515140000, 0x3b },
+ { 545140000, 0x1b },
+ { 599140000, 0xfb },
+ { 623140000, 0xdb },
+ { 659140000, 0xbb },
+ { 713140000, 0x9b },
+};
+
+struct regdata {
+ u8 reg;
+ u8 data;
+};
+
+static struct regdata s921_init[] = {
+ { 0x01, 0x80 }, /* Probably, a reset sequence */
+ { 0x01, 0x40 },
+ { 0x01, 0x80 },
+ { 0x01, 0x40 },
+
+ { 0x02, 0x00 },
+ { 0x03, 0x40 },
+ { 0x04, 0x01 },
+ { 0x05, 0x00 },
+ { 0x06, 0x00 },
+ { 0x07, 0x00 },
+ { 0x08, 0x00 },
+ { 0x09, 0x00 },
+ { 0x0a, 0x00 },
+ { 0x0b, 0x5a },
+ { 0x0c, 0x00 },
+ { 0x0d, 0x00 },
+ { 0x0f, 0x00 },
+ { 0x13, 0x1b },
+ { 0x14, 0x80 },
+ { 0x15, 0x40 },
+ { 0x17, 0x70 },
+ { 0x18, 0x01 },
+ { 0x19, 0x12 },
+ { 0x1a, 0x01 },
+ { 0x1b, 0x12 },
+ { 0x1c, 0xa0 },
+ { 0x1d, 0x00 },
+ { 0x1e, 0x0a },
+ { 0x1f, 0x08 },
+ { 0x20, 0x40 },
+ { 0x21, 0xff },
+ { 0x22, 0x4c },
+ { 0x23, 0x4e },
+ { 0x24, 0x4c },
+ { 0x25, 0x00 },
+ { 0x26, 0x00 },
+ { 0x27, 0xf4 },
+ { 0x28, 0x60 },
+ { 0x29, 0x88 },
+ { 0x2a, 0x40 },
+ { 0x2b, 0x40 },
+ { 0x2c, 0xff },
+ { 0x2d, 0x00 },
+ { 0x2e, 0xff },
+ { 0x2f, 0x00 },
+ { 0x30, 0x20 },
+ { 0x31, 0x06 },
+ { 0x32, 0x0c },
+ { 0x34, 0x0f },
+ { 0x37, 0xfe },
+ { 0x38, 0x00 },
+ { 0x39, 0x63 },
+ { 0x3a, 0x10 },
+ { 0x3b, 0x10 },
+ { 0x47, 0x00 },
+ { 0x49, 0xe5 },
+ { 0x4b, 0x00 },
+ { 0x50, 0xc0 },
+ { 0x52, 0x20 },
+ { 0x54, 0x5a },
+ { 0x55, 0x5b },
+ { 0x56, 0x40 },
+ { 0x57, 0x70 },
+ { 0x5c, 0x50 },
+ { 0x5d, 0x00 },
+ { 0x62, 0x17 },
+ { 0x63, 0x2f },
+ { 0x64, 0x6f },
+ { 0x68, 0x00 },
+ { 0x69, 0x89 },
+ { 0x6a, 0x00 },
+ { 0x6b, 0x00 },
+ { 0x6c, 0x00 },
+ { 0x6d, 0x00 },
+ { 0x6e, 0x00 },
+ { 0x70, 0x10 },
+ { 0x71, 0x00 },
+ { 0x75, 0x00 },
+ { 0x76, 0x30 },
+ { 0x77, 0x01 },
+ { 0xaf, 0x00 },
+ { 0xb0, 0xa0 },
+ { 0xb2, 0x3d },
+ { 0xb3, 0x25 },
+ { 0xb4, 0x8b },
+ { 0xb5, 0x4b },
+ { 0xb6, 0x3f },
+ { 0xb7, 0xff },
+ { 0xb8, 0xff },
+ { 0xb9, 0xfc },
+ { 0xba, 0x00 },
+ { 0xbb, 0x00 },
+ { 0xbc, 0x00 },
+ { 0xd0, 0x30 },
+ { 0xe4, 0x84 },
+ { 0xf0, 0x48 },
+ { 0xf1, 0x19 },
+ { 0xf2, 0x5a },
+ { 0xf3, 0x8e },
+ { 0xf4, 0x2d },
+ { 0xf5, 0x07 },
+ { 0xf6, 0x5a },
+ { 0xf7, 0xba },
+ { 0xf8, 0xd7 },
+};
+
+static struct regdata s921_prefreq[] = {
+ { 0x47, 0x60 },
+ { 0x68, 0x00 },
+ { 0x69, 0x89 },
+ { 0xf0, 0x48 },
+ { 0xf1, 0x19 },
+};
+
+static struct regdata s921_postfreq[] = {
+ { 0xf5, 0xae },
+ { 0xf6, 0xb7 },
+ { 0xf7, 0xba },
+ { 0xf8, 0xd7 },
+ { 0x68, 0x0a },
+ { 0x69, 0x09 },
+};
+
+static int s921_i2c_writereg(struct s921_state *state,
+ u8 i2c_addr, int reg, int data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+ };
+ int rc;
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (rc != 1) {
+ printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+ " data == 0x%02x)\n", __func__, rc, reg, data);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
+ struct regdata *rd, int size)
+{
+ int i, rc;
+
+ for (i = 0; i < size; i++) {
+ rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
+{
+ u8 val;
+ int rc;
+ struct i2c_msg msg[] = {
+ { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+ };
+
+ rc = i2c_transfer(state->i2c, msg, 2);
+
+ if (rc != 2) {
+ rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+ return rc;
+ }
+
+ return val;
+}
+
+#define s921_readreg(state, reg) \
+ s921_i2c_readreg(state, state->config->demod_address, reg)
+#define s921_writereg(state, reg, val) \
+ s921_i2c_writereg(state, state->config->demod_address, reg, val)
+#define s921_writeregdata(state, regdata) \
+ s921_i2c_writeregdata(state, state->config->demod_address, \
+ regdata, ARRAY_SIZE(regdata))
+
+static int s921_pll_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int band, rc, i;
+ unsigned long f_offset;
+ u8 f_switch;
+ u64 offset;
+
+ dprintk("frequency=%i\n", p->frequency);
+
+ for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
+ if (p->frequency < s921_bandselect[band].freq_low)
+ break;
+ band--;
+
+ if (band < 0) {
+ rc("%s: frequency out of range\n", __func__);
+ return -EINVAL;
+ }
+
+ f_switch = s921_bandselect[band].band_reg;
+
+ offset = ((u64)p->frequency) * 258;
+ do_div(offset, 6000000);
+ f_offset = ((unsigned long)offset) + 2321;
+
+ rc = s921_writeregdata(state, s921_prefreq);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf3, f_offset & 0xff);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf4, f_switch);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writeregdata(state, s921_postfreq);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0 ; i < 6; i++) {
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+ }
+ rc = s921_writereg(state, 0x01, 0x40);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_readreg(state, 0x01);
+ dprintk("status 0x01: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x32);
+ dprintk("status 0x32: %02x\n", rc);
+
+ dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
+
+ return 0;
+}
+
+static int s921_initfe(struct dvb_frontend *fe)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ rc = s921_writeregdata(state, s921_init);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int regstatus, rc;
+
+ *status = 0;
+
+ rc = s921_readreg(state, 0x81);
+ if (rc < 0)
+ return rc;
+
+ regstatus = rc << 8;
+
+ rc = s921_readreg(state, 0x82);
+ if (rc < 0)
+ return rc;
+
+ regstatus |= rc;
+
+ dprintk("status = %04x\n", regstatus);
+
+ /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
+ if ((regstatus & 0xff) == 0x40) {
+ *status = FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI |
+ FE_HAS_SYNC |
+ FE_HAS_LOCK;
+ } else if (regstatus & 0x40) {
+ /* This is close to Full Sync, but not enough to get useful info */
+ *status = FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI |
+ FE_HAS_SYNC;
+ }
+
+ return 0;
+}
+
+static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ fe_status_t status;
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ /* FIXME: Use the proper register for it... 0x80? */
+ rc = s921_read_status(fe, &status);
+ if (rc < 0)
+ return rc;
+
+ *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
+
+ dprintk("strength = 0x%04x\n", *strength);
+
+ rc = s921_readreg(state, 0x01);
+ dprintk("status 0x01: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x32);
+ dprintk("status 0x32: %02x\n", rc);
+
+ return 0;
+}
+
+static int s921_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ /* FIXME: We don't know how to use non-auto mode */
+
+ rc = s921_pll_tune(fe, p);
+ if (rc < 0)
+ return rc;
+
+ state->currentfreq = p->frequency;
+
+ return 0;
+}
+
+static int s921_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+
+ /* FIXME: Probably it is possible to get it from regs f1 and f2 */
+ p->frequency = state->currentfreq;
+
+ return 0;
+}
+
+static int s921_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
+ unsigned int mode_flags,
+ unsigned int *delay,
+ fe_status_t *status)
+{
+ int rc = 0;
+
+ dprintk("\n");
+
+ if (params != NULL)
+ rc = s921_set_frontend(fe, params);
+
+ if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+ s921_read_status(fe, status);
+
+ return rc;
+}
+
+static int s921_get_algo(struct dvb_frontend *fe)
+{
+ return 1; /* FE_ALGO_HW */
+}
+
+static void s921_release(struct dvb_frontend *fe)
+{
+ struct s921_state *state = fe->demodulator_priv;
+
+ dprintk("\n");
+ kfree(state);
+}
+
+static struct dvb_frontend_ops s921_ops;
+
+struct dvb_frontend *s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+ /* allocate memory for the internal state */
+ struct s921_state *state =
+ kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+
+ dprintk("\n");
+ if (state == NULL) {
+ rc("Unable to kzalloc\n");
+ goto rcor;
+ }
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &s921_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ return &state->frontend;
+
+rcor:
+ kfree(state);
+
+ return NULL;
+}
+EXPORT_SYMBOL(s921_attach);
+
+static struct dvb_frontend_ops s921_ops = {
+ /* Use dib8000 values per default */
+ .info = {
+ .name = "Sharp S921",
+ .type = FE_OFDM,
+ .frequency_min = 470000000,
+ /*
+ * Max should be 770MHz instead, according with Sharp docs,
+ * but Leadership doc says it works up to 806 MHz. This is
+ * required to get channel 69, used in Brazil
+ */
+ .frequency_max = 806000000,
+ .frequency_tolerance = 0,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = s921_release,
+
+ .init = s921_initfe,
+ .set_frontend = s921_set_frontend,
+ .get_frontend = s921_get_frontend,
+ .read_status = s921_read_status,
+ .read_signal_strength = s921_read_signal_strength,
+ .tune = s921_tune,
+ .get_frontend_algo = s921_get_algo,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb/frontends/s921.h
new file mode 100644
index 000000000000..f220d8299c81
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.h
@@ -0,0 +1,47 @@
+/*
+ * Sharp s921 driver
+ *
+ * Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 S921_H
+#define S921_H
+
+#include <linux/dvb/frontend.h>
+
+struct s921_config {
+ /* the demodulator's i2c address */
+ u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c);
+extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *s921_attach(
+ const struct s921_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static struct i2c_adapter *
+ s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c
deleted file mode 100644
index 974b52be9aea..000000000000
--- a/drivers/media/dvb/frontends/s921_core.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Driver for Sharp s921 driver
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
- *
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include "s921_core.h"
-
-static int s921_isdb_init(struct s921_isdb_t *dev);
-static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
-static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
-static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
-
-static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
- 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
- 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
- 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
- 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
- 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
- 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
- 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
- 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
- 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
- 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
- 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
- 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
- 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
- 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
- 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
- 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
- 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
- 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
- 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
- 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
- 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
- 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
- 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
- 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
- 0xf8, 0xd7 };
-
-static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
- 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
- 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
- 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
- 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
- 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
- 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
- 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
- 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
- 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
- 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
- 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
- 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
- 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
- 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
- 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
- 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
-
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
- switch(cmd) {
- case ISDB_T_CMD_INIT:
- s921_isdb_init(dev);
- break;
- case ISDB_T_CMD_SET_PARAM:
- s921_isdb_set_parameters(dev, data);
- break;
- case ISDB_T_CMD_TUNE:
- s921_isdb_tune(dev, data);
- break;
- case ISDB_T_CMD_GET_STATUS:
- s921_isdb_get_status(dev, data);
- break;
- default:
- printk("unhandled command\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int s921_isdb_init(struct s921_isdb_t *dev) {
- unsigned int i;
- unsigned int ret;
- printk("isdb_init\n");
- for (i = 0; i < sizeof(init_table); i+=2) {
- ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
- if (ret != 0) {
- printk("i2c write failed\n");
- return ret;
- }
- }
- return 0;
-}
-
-static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
-
- int ret;
- /* auto is sufficient for now, lateron this should be reflected in an extra interface */
-
-
-
- ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
- ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
-
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
- if (ret < 0)
- return -EINVAL;
-
- return E_OK;
-}
-
-static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
-
- int ret;
- int index;
-
- index = (params->frequency - 473143000)/6000000;
-
- if (index > 48) {
- return -EINVAL;
- }
-
- dev->i2c_write(dev->priv_dev, 0x47, 0x60);
-
- ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
- if (ret < 0)
- return -EINVAL;
-
- dev->i2c_write(dev->priv_dev, 0x01, 0x40);
- return 0;
-}
-
-static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
- unsigned int *ret = (unsigned int*)data;
- u8 ifagc_dt;
- u8 rfagc_dt;
-
- mdelay(10);
- ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
- rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
- if (rfagc_dt == 0x40) {
- *ret = 1;
- }
- return 0;
-}
diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h
deleted file mode 100644
index de2f10a44e72..000000000000
--- a/drivers/media/dvb/frontends/s921_core.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef _S921_CORE_H
-#define _S921_CORE_H
-//#define u8 unsigned int
-//#define u32 unsigned int
-
-
-
-//#define EINVAL -1
-#define E_OK 0
-
-struct s921_isdb_t {
- void *priv_dev;
- int (*i2c_write)(void *dev, u8 reg, u8 val);
- int (*i2c_read)(void *dev, u8 reg);
-};
-
-#define ISDB_T_CMD_INIT 0
-#define ISDB_T_CMD_SET_PARAM 1
-#define ISDB_T_CMD_TUNE 2
-#define ISDB_T_CMD_GET_STATUS 3
-
-struct s921_isdb_t_tune_params {
- u32 frequency;
-};
-
-struct s921_isdb_t_status {
-};
-
-struct s921_isdb_t_transmission_mode_params {
- u8 mode;
- u8 layer_a_mode;
-#define ISDB_T_LA_MODE_1 0
-#define ISDB_T_LA_MODE_2 1
-#define ISDB_T_LA_MODE_3 2
- u8 layer_a_carrier_modulation;
-#define ISDB_T_LA_CM_DQPSK 0
-#define ISDB_T_LA_CM_QPSK 1
-#define ISDB_T_LA_CM_16QAM 2
-#define ISDB_T_LA_CM_64QAM 3
-#define ISDB_T_LA_CM_NOLAYER 4
- u8 layer_a_code_rate;
-#define ISDB_T_LA_CR_1_2 0
-#define ISDB_T_LA_CR_2_3 1
-#define ISDB_T_LA_CR_3_4 2
-#define ISDB_T_LA_CR_5_6 4
-#define ISDB_T_LA_CR_7_8 8
-#define ISDB_T_LA_CR_NOLAYER 16
- u8 layer_a_time_interleave;
-#define ISDB_T_LA_TI_0 0
-#define ISDB_T_LA_TI_1 1
-#define ISDB_T_LA_TI_2 2
-#define ISDB_T_LA_TI_4 4
-#define ISDB_T_LA_TI_8 8
-#define ISDB_T_LA_TI_16 16
-#define ISDB_T_LA_TI_32 32
- u8 layer_a_nseg;
-
- u8 layer_b_mode;
-#define ISDB_T_LB_MODE_1 0
-#define ISDB_T_LB_MODE_2 1
-#define ISDB_T_LB_MODE_3 2
- u8 layer_b_carrier_modulation;
-#define ISDB_T_LB_CM_DQPSK 0
-#define ISDB_T_LB_CM_QPSK 1
-#define ISDB_T_LB_CM_16QAM 2
-#define ISDB_T_LB_CM_64QAM 3
-#define ISDB_T_LB_CM_NOLAYER 4
- u8 layer_b_code_rate;
-#define ISDB_T_LB_CR_1_2 0
-#define ISDB_T_LB_CR_2_3 1
-#define ISDB_T_LB_CR_3_4 2
-#define ISDB_T_LB_CR_5_6 4
-#define ISDB_T_LB_CR_7_8 8
-#define ISDB_T_LB_CR_NOLAYER 16
- u8 layer_b_time_interleave;
-#define ISDB_T_LB_TI_0 0
-#define ISDB_T_LB_TI_1 1
-#define ISDB_T_LB_TI_2 2
-#define ISDB_T_LB_TI_4 4
-#define ISDB_T_LB_TI_8 8
-#define ISDB_T_LB_TI_16 16
-#define ISDB_T_LB_TI_32 32
- u8 layer_b_nseg;
-
- u8 layer_c_mode;
-#define ISDB_T_LC_MODE_1 0
-#define ISDB_T_LC_MODE_2 1
-#define ISDB_T_LC_MODE_3 2
- u8 layer_c_carrier_modulation;
-#define ISDB_T_LC_CM_DQPSK 0
-#define ISDB_T_LC_CM_QPSK 1
-#define ISDB_T_LC_CM_16QAM 2
-#define ISDB_T_LC_CM_64QAM 3
-#define ISDB_T_LC_CM_NOLAYER 4
- u8 layer_c_code_rate;
-#define ISDB_T_LC_CR_1_2 0
-#define ISDB_T_LC_CR_2_3 1
-#define ISDB_T_LC_CR_3_4 2
-#define ISDB_T_LC_CR_5_6 4
-#define ISDB_T_LC_CR_7_8 8
-#define ISDB_T_LC_CR_NOLAYER 16
- u8 layer_c_time_interleave;
-#define ISDB_T_LC_TI_0 0
-#define ISDB_T_LC_TI_1 1
-#define ISDB_T_LC_TI_2 2
-#define ISDB_T_LC_TI_4 4
-#define ISDB_T_LC_TI_8 8
-#define ISDB_T_LC_TI_16 16
-#define ISDB_T_LC_TI_32 32
- u8 layer_c_nseg;
-};
-
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
-#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
deleted file mode 100644
index 0eefff61cc50..000000000000
--- a/drivers/media/dvb/frontends/s921_module.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Driver for Sharp s921 driver
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
- *
- * All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "s921_module.h"
-#include "s921_core.h"
-
-static unsigned int debug = 0;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"s921 debugging (default off)");
-
-#define dprintk(fmt, args...) if (debug) do {\
- printk("s921 debug: " fmt, ##args); } while (0)
-
-struct s921_state
-{
- struct dvb_frontend frontend;
- fe_modulation_t current_modulation;
- __u32 snr;
- __u32 current_frequency;
- __u8 addr;
- struct s921_isdb_t dev;
- struct i2c_adapter *i2c;
-};
-
-static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- struct s921_isdb_t_transmission_mode_params params;
- struct s921_isdb_t_tune_params tune_params;
-
- tune_params.frequency = param->frequency;
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
- mdelay(100);
- return 0;
-}
-
-static int s921_init(struct dvb_frontend *fe) {
- printk("s921 init\n");
- return 0;
-}
-
-static int s921_sleep(struct dvb_frontend *fe) {
- printk("s921 sleep\n");
- return 0;
-}
-
-static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- unsigned int ret;
- mdelay(5);
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
- *status = 0;
-
- printk("status: %02x\n", ret);
- if (ret == 1) {
- *status |= FE_HAS_CARRIER;
- *status |= FE_HAS_VITERBI;
- *status |= FE_HAS_LOCK;
- *status |= FE_HAS_SYNC;
- *status |= FE_HAS_SIGNAL;
- }
-
- return 0;
-}
-
-static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
-{
- dprintk("read ber\n");
- return 0;
-}
-
-static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
-{
- dprintk("read snr\n");
- return 0;
-}
-
-static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
-{
- dprintk("read ucblocks\n");
- return 0;
-}
-
-static void s921_release(struct dvb_frontend *fe)
-{
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- kfree(state);
-}
-
-static struct dvb_frontend_ops demod_s921={
- .info = {
- .name = "SHARP S921",
- .type = FE_OFDM,
- .frequency_min = 473143000,
- .frequency_max = 767143000,
- .frequency_stepsize = 6000000,
- .frequency_tolerance = 0,
- .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
- FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
- FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
- FE_CAN_MUTE_TS
- },
- .init = s921_init,
- .sleep = s921_sleep,
- .set_frontend = s921_set_parameters,
- .read_snr = s921_read_snr,
- .read_ber = s921_read_ber,
- .read_status = s921_read_status,
- .read_ucblocks = s921_read_ucblocks,
- .release = s921_release,
-};
-
-static int s921_write(void *dev, u8 reg, u8 val) {
- struct s921_state *state = dev;
- char buf[2]={reg,val};
- int err;
- struct i2c_msg i2cmsgs = {
- .addr = state->addr,
- .flags = 0,
- .len = 2,
- .buf = buf
- };
-
- if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
- printk("%s i2c_transfer error %d\n", __func__, err);
- if (err < 0)
- return err;
- else
- return -EREMOTEIO;
- }
-
- return 0;
-}
-
-static int s921_read(void *dev, u8 reg) {
- struct s921_state *state = dev;
- u8 b1;
- int ret;
- struct i2c_msg msg[2] = { { .addr = state->addr,
- .flags = 0,
- .buf = &reg, .len = 1 },
- { .addr = state->addr,
- .flags = I2C_M_RD,
- .buf = &b1, .len = 1 } };
-
- ret = i2c_transfer(state->i2c, msg, 2);
- if (ret != 2)
- return ret;
- return b1;
-}
-
-struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c)
-{
-
- struct s921_state *state;
- state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
- if (state == NULL)
- return NULL;
-
- state->addr = config->i2c_address;
- state->i2c = i2c;
- state->dev.i2c_write = &s921_write;
- state->dev.i2c_read = &s921_read;
- state->dev.priv_dev = state;
-
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
-
- memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
- state->frontend.demodulator_priv = state;
- return &state->frontend;
-}
-
-EXPORT_SYMBOL_GPL(s921_attach);
-MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
-MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h
deleted file mode 100644
index 78660424ba95..000000000000
--- a/drivers/media/dvb/frontends/s921_module.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Driver for DVB-T s921 demodulator
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.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., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef S921_MODULE_H
-#define S921_MODULE_H
-
-#include <linux/dvb/frontend.h>
-#include "s921_core.h"
-
-int s921_isdb_init(struct s921_isdb_t *dev);
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
-
-struct s921_config
-{
- /* demodulator's I2C address */
- u8 i2c_address;
-};
-
-#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
-extern struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-#endif /* CONFIG_DVB_S921 */
-
-#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 8e38fcee564e..37a222d9ddb3 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -714,7 +714,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-
+ msleep(100);
return 0;
}
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index 80a9e4cba631..64673b8b64a2 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -51,7 +51,7 @@ module_param(verbose, int, 0644);
if (x > y) \
printk(format, ##arg); \
} \
-} while(0)
+} while (0)
struct stb6100_lkup {
u32 val_low;
@@ -117,7 +117,10 @@ static const struct stb6100_regmask stb6100_template[] = {
[STB6100_TEST3] = { 0x00, 0xde },
};
-static void stb6100_normalise_regs(u8 regs[])
+/*
+ * Currently unused. Some boards might need it in the future
+ */
+static inline void stb6100_normalise_regs(u8 regs[])
{
int i;
@@ -157,13 +160,25 @@ static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
u8 regs[STB6100_NUMREGS];
int rc;
+ struct i2c_msg msg = {
+ .addr = state->config->tuner_address + reg,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = 1
+ };
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+
if (unlikely(reg >= STB6100_NUMREGS)) {
dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
return -EINVAL;
}
- if ((rc = stb6100_read_regs(state, regs)) < 0)
- return rc;
- return (unsigned int)regs[reg];
+ if (unlikely(verbose > FE_DEBUG)) {
+ dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
+ dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[reg], regs[0]);
+ }
+
+ return (unsigned int)regs[0];
}
static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
@@ -211,20 +226,17 @@ static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
return stb6100_write_reg_range(state, &data, reg, 1);
}
-static int stb6100_write_regs(struct stb6100_state *state, u8 regs[])
-{
- stb6100_normalise_regs(regs);
- return stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 1);
-}
static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
{
int rc;
struct stb6100_state *state = fe->tuner_priv;
- if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0)
+ rc = stb6100_read_reg(state, STB6100_LD);
+ if (rc < 0) {
+ dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
return rc;
-
+ }
return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
}
@@ -234,7 +246,8 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
u8 f;
struct stb6100_state *state = fe->tuner_priv;
- if ((rc = stb6100_read_reg(state, STB6100_F)) < 0)
+ rc = stb6100_read_reg(state, STB6100_F);
+ if (rc < 0)
return rc;
f = rc & STB6100_F_F;
@@ -265,14 +278,21 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
/* Turn on LPF bandwidth setting clock control,
* set bandwidth, wait 10ms, turn off.
*/
- if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0)
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
+ if (rc < 0)
return rc;
- if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0)
+ rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
+ if (rc < 0)
return rc;
- msleep(1);
- if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0)
+
+ msleep(5); /* This is dangerous as another (related) thread may start */
+
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+ if (rc < 0)
return rc;
+ msleep(10); /* This is dangerous as another (related) thread may start */
+
return 0;
}
@@ -284,7 +304,8 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
struct stb6100_state *state = fe->tuner_priv;
u8 regs[STB6100_NUMREGS];
- if ((rc = stb6100_read_regs(state, regs)) < 0)
+ rc = stb6100_read_regs(state, regs);
+ if (rc < 0)
return rc;
odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
@@ -312,8 +333,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
u8 regs[STB6100_NUMREGS];
u8 g, psd2, odiv;
- if ((rc = stb6100_read_regs(state, regs)) < 0)
- return rc;
+ dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
if (fe->ops.get_frontend) {
dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
@@ -321,96 +341,140 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
}
srate = p.u.qpsk.symbol_rate;
- regs[STB6100_DLB] = 0xdc;
- /* Disable LPEN */
- regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */
+ /* Set up tuner cleanly, LPF calibration on */
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
+ if (rc < 0)
+ return rc; /* allow LPF calibration */
- if ((rc = stb6100_write_regs(state, regs)) < 0)
+ /* PLL Loop disabled, bias on, VCO on, synth on */
+ regs[STB6100_LPEN] = 0xeb;
+ rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+ if (rc < 0)
return rc;
- /* Baseband gain. */
- if (srate >= 15000000)
- g = 9; // +4 dB
- else if (srate >= 5000000)
- g = 11; // +8 dB
- else
- g = 14; // +14 dB
-
- regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g;
- regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
- regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+ /* Program the registers with their data values */
/* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
if (frequency <= 1075000)
odiv = 1;
else
odiv = 0;
- regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT);
- if ((frequency > 1075000) && (frequency <= 1325000))
- psd2 = 0;
- else
- psd2 = 1;
- regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+ /* VCO enabled, seach clock off as per LL3.7, 3.4.1 */
+ regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
/* OSM */
for (ptr = lkup;
(ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
ptr++);
+
if (ptr->val_high == 0) {
printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
return -EINVAL;
}
regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
+ return rc;
+ if ((frequency > 1075000) && (frequency <= 1325000))
+ psd2 = 0;
+ else
+ psd2 = 1;
/* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
fvco = frequency << (1 + odiv);
/* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
nint = fvco / (state->reference << psd2);
/* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
- << (9 - psd2),
- state->reference);
+ << (9 - psd2), state->reference);
+
+ /* NI */
+ regs[STB6100_NI] = nint;
+ rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
+ if (rc < 0)
+ return rc;
+
+ /* NF */
+ regs[STB6100_NF_LSB] = nfrac;
+ rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
+ if (rc < 0)
+ return rc;
+
+ /* K */
+ regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+ regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
+ rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
+ if (rc < 0)
+ return rc;
+
+ /* G Baseband gain. */
+ if (srate >= 15000000)
+ g = 9; /* +4 dB */
+ else if (srate >= 5000000)
+ g = 11; /* +8 dB */
+ else
+ g = 14; /* +14 dB */
+
+ regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
+ regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
+ regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+ rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
+ if (rc < 0)
+ return rc;
+
+ /* F we don't write as it is set up in BW set */
+
+ /* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
+ regs[STB6100_DLB] = 0xcc;
+ rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
+ if (rc < 0)
+ return rc;
+
dprintk(verbose, FE_DEBUG, 1,
"frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
frequency, srate, (unsigned int)g, (unsigned int)odiv,
(unsigned int)psd2, state->reference,
ptr->reg, fvco, nint, nfrac);
- regs[STB6100_NI] = nint;
- regs[STB6100_NF_LSB] = nfrac;
- regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
- regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */
- regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */
- regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */
- regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */
- /* Power up. */
- regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN;
- msleep(2);
- if ((rc = stb6100_write_regs(state, regs)) < 0)
+ /* Set up the test registers */
+ regs[STB6100_TEST1] = 0x8f;
+ rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
+ if (rc < 0)
+ return rc;
+ regs[STB6100_TEST3] = 0xde;
+ rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
+ if (rc < 0)
return rc;
- msleep(2);
- regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */
- if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0)
+ /* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
+ regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
+ rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+ if (rc < 0)
return rc;
+ msleep(2);
+
+ /* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
- if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
return rc;
- msleep(10); /* wait for LO to lock */
+ msleep(10); /* This is dangerous as another (related) thread may start */ /* wait for LO to lock */
+
regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
- if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
- return rc;
- regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */
- stb6100_normalise_regs(regs);
- if ((rc = stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 3)) < 0)
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
return rc;
- msleep(100);
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+ if (rc < 0)
+ return rc; /* Stop LPF calibration */
+ msleep(10); /* This is dangerous as another (related) thread may start */
+ /* wait for stabilisation, (should not be necessary) */
return 0;
}
@@ -433,8 +497,8 @@ static int stb6100_init(struct dvb_frontend *fe)
state->bandwidth = status->bandwidth * 1000; /* Hz */
state->reference = status->refclock / 1000; /* kHz */
- /* Set default bandwidth. */
- return stb6100_set_bandwidth(fe, state->bandwidth);
+ /* Set default bandwidth. Modified, PN 13-May-10 */
+ return 0;
}
static int stb6100_get_state(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 425e7a43ae19..4e0fc2c8a41c 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -1483,8 +1483,8 @@ static int stv090x_start_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
goto err;
- if ((state->search_mode == STV090x_DVBS1) ||
- (state->search_mode == STV090x_DSS) ||
+ if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
+ (state->search_mode == STV090x_SEARCH_DSS) ||
(state->search_mode == STV090x_SEARCH_AUTO)) {
if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
@@ -2940,7 +2940,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
break;
- case STV090x_UNKNOWN:
+ case STV090x_ERROR:
default:
reg = STV090x_READ_DEMOD(state, DMDCFGMD);
STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
index fd0830ed10d8..a13a50503134 100644
--- a/drivers/media/dvb/mantis/Kconfig
+++ b/drivers/media/dvb/mantis/Kconfig
@@ -1,6 +1,6 @@
config MANTIS_CORE
tristate "Mantis/Hopper PCI bridge based devices"
- depends on PCI && I2C && INPUT && IR_CORE
+ depends on PCI && I2C && INPUT && RC_CORE
help
Support for PCI cards based on the Mantis and Hopper PCi bridge.
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc785189..70e73afefb3d 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -251,6 +251,8 @@ static struct pci_device_id hopper_pci_table[] = {
{ }
};
+MODULE_DEVICE_TABLE(pci, hopper_pci_table);
+
static struct pci_driver hopper_pci_driver = {
.name = DRIVER_NAME,
.id_table = hopper_pci_table,
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c
index 96674c78e86b..68a29f8bdf73 100644
--- a/drivers/media/dvb/mantis/hopper_vp3028.c
+++ b/drivers/media/dvb/mantis/hopper_vp3028.c
@@ -47,17 +47,17 @@ static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
struct mantis_hwconfig *config = mantis->hwconfig;
int err = 0;
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
err = mantis_frontend_power(mantis, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
err = mantis_frontend_power(mantis, POWER_ON);
if (err == 0) {
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
- fe = zl10353_attach(&hopper_vp3028_config, adapter);
+ fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter);
if (!fe)
return -1;
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39ffdaad..40da225098cc 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -281,6 +281,8 @@ static struct pci_device_id mantis_pci_table[] = {
{ }
};
+MODULE_DEVICE_TABLE(pci, mantis_pci_table);
+
static struct pci_driver mantis_pci_driver = {
.name = DRIVER_NAME,
.id_table = mantis_pci_table,
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a483c9..bd400d21b81f 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -171,7 +171,9 @@ struct mantis_pci {
struct work_struct uart_work;
spinlock_t uart_lock;
- struct input_dev *rc;
+ struct rc_dev *rc;
+ char input_name[80];
+ char input_phys[80];
};
#define MANTIS_HIF_STATUS (mantis->gpio_status)
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
index 99d82eec3b03..e5180e45d310 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -47,15 +47,15 @@ int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
switch (power) {
case POWER_ON:
dprintk(MANTIS_DEBUG, 1, "Power ON");
- gpio_set_bits(mantis, config->power, POWER_ON);
+ mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->power, POWER_ON);
+ mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
break;
case POWER_OFF:
dprintk(MANTIS_DEBUG, 1, "Power OFF");
- gpio_set_bits(mantis, config->power, POWER_OFF);
+ mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
msleep(100);
break;
@@ -73,13 +73,13 @@ void mantis_frontend_soft_reset(struct mantis_pci *mantis)
struct mantis_hwconfig *config = mantis->hwconfig;
dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
return;
@@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
if (mantis->feeds == 1) {
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
mantis_dma_start(mantis);
+ tasklet_enable(&mantis->tasklet);
}
return mantis->feeds;
@@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
mantis->feeds--;
if (mantis->feeds == 0) {
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
+ tasklet_disable(&mantis->tasklet);
mantis_dma_stop(mantis);
}
@@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
+ tasklet_disable(&mantis->tasklet);
if (mantis->hwconfig) {
result = config->frontend_init(mantis, mantis->fe);
if (result < 0) {
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index a99489b8418b..db6d54d3fec0 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -18,8 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/pci.h>
#include "dmxdev.h"
@@ -33,8 +32,9 @@
#include "mantis_uart.h"
#define MODULE_NAME "mantis_core"
+#define RC_MAP_MANTIS "rc-mantis"
-static struct ir_scancode mantis_ir_table[] = {
+static struct rc_map_table mantis_ir_table[] = {
{ 0x29, KEY_POWER },
{ 0x28, KEY_FAVORITES },
{ 0x30, KEY_TEXT },
@@ -95,53 +95,65 @@ static struct ir_scancode mantis_ir_table[] = {
{ 0x00, KEY_BLUE },
};
-struct ir_scancode_table ir_mantis = {
- .scan = mantis_ir_table,
- .size = ARRAY_SIZE(mantis_ir_table),
+static struct rc_map_list ir_mantis_map = {
+ .map = {
+ .scan = mantis_ir_table,
+ .size = ARRAY_SIZE(mantis_ir_table),
+ .rc_type = RC_TYPE_UNKNOWN,
+ .name = RC_MAP_MANTIS,
+ }
};
-EXPORT_SYMBOL_GPL(ir_mantis);
int mantis_input_init(struct mantis_pci *mantis)
{
- struct input_dev *rc;
- char name[80], dev[80];
+ struct rc_dev *dev;
int err;
- rc = input_allocate_device();
- if (!rc) {
- dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
- return -ENOMEM;
- }
+ err = rc_map_register(&ir_mantis_map);
+ if (err)
+ goto out;
- sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
- sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
+ dev = rc_allocate_device();
+ if (!dev) {
+ dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
+ err = -ENOMEM;
+ goto out_map;
+ }
- rc->name = name;
- rc->phys = dev;
+ sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
+ sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
- rc->id.bustype = BUS_PCI;
- rc->id.vendor = mantis->vendor_id;
- rc->id.product = mantis->device_id;
- rc->id.version = 1;
- rc->dev = mantis->pdev->dev;
+ dev->input_name = mantis->input_name;
+ dev->input_phys = mantis->input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.vendor = mantis->vendor_id;
+ dev->input_id.product = mantis->device_id;
+ dev->input_id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_MANTIS;
+ dev->dev.parent = &mantis->pdev->dev;
- err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err) {
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
- input_free_device(rc);
- return -ENODEV;
+ goto out_dev;
}
- mantis->rc = rc;
-
+ mantis->rc = dev;
return 0;
+
+out_dev:
+ rc_free_device(dev);
+out_map:
+ rc_map_unregister(&ir_mantis_map);
+out:
+ return err;
}
int mantis_exit(struct mantis_pci *mantis)
{
- struct input_dev *rc = mantis->rc;
-
- ir_input_unregister(rc);
-
+ rc_unregister_device(mantis->rc);
+ rc_map_unregister(&ir_mantis_map);
return 0;
}
+
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
index fe31cfb0b158..479086dbb9a8 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -75,7 +75,7 @@ int mantis_get_mac(struct mantis_pci *mantis)
EXPORT_SYMBOL_GPL(mantis_get_mac);
/* Turn the given bit on or off. */
-void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
{
u32 cur;
@@ -90,7 +90,7 @@ void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
mmwrite(0x00, MANTIS_GPIF_DOUT);
}
-EXPORT_SYMBOL_GPL(gpio_set_bits);
+EXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
{
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h
index 188fe5a81614..d56e002b2955 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.h
+++ b/drivers/media/dvb/mantis/mantis_ioc.h
@@ -44,7 +44,7 @@ enum mantis_stream_control {
};
extern int mantis_get_mac(struct mantis_pci *mantis);
-extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
+extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c
index 4a723bda0031..deec927c7f7a 100644
--- a/drivers/media/dvb/mantis/mantis_vp1033.c
+++ b/drivers/media/dvb/mantis/mantis_vp1033.c
@@ -173,7 +173,7 @@ static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
- fe = stv0299_attach(&lgtdqcs001f_config, adapter);
+ fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
if (fe) {
fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c
index 8e6ae558ee57..26bc0cbe84d4 100644
--- a/drivers/media/dvb/mantis/mantis_vp1034.c
+++ b/drivers/media/dvb/mantis/mantis_vp1034.c
@@ -50,13 +50,13 @@ int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
switch (voltage) {
case SEC_VOLTAGE_13:
dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
- gpio_set_bits(mantis, 13, 1);
- gpio_set_bits(mantis, 14, 0);
+ mantis_gpio_set_bits(mantis, 13, 1);
+ mantis_gpio_set_bits(mantis, 14, 0);
break;
case SEC_VOLTAGE_18:
dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
- gpio_set_bits(mantis, 13, 1);
- gpio_set_bits(mantis, 14, 1);
+ mantis_gpio_set_bits(mantis, 13, 1);
+ mantis_gpio_set_bits(mantis, 14, 1);
break;
case SEC_VOLTAGE_OFF:
dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
@@ -82,7 +82,7 @@ static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
- fe = mb86a16_attach(&vp1034_mb86a16_config, adapter);
+ fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter);
if (fe) {
dprintk(MANTIS_ERROR, 1,
"found MB86A16 DVB-S/DSS frontend @0x%02x",
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c
index d1aa2bc0c155..38a436ca2fdf 100644
--- a/drivers/media/dvb/mantis/mantis_vp1041.c
+++ b/drivers/media/dvb/mantis/mantis_vp1041.c
@@ -316,14 +316,14 @@ static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
if (err == 0) {
mantis_frontend_soft_reset(mantis);
msleep(250);
- mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter);
+ mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter);
if (mantis->fe) {
dprintk(MANTIS_ERROR, 1,
"found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
vp1041_stb0899_config.demod_address);
- if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) {
- if (!lnbp21_attach(mantis->fe, adapter, 0, 0))
+ if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) {
+ if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0))
dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
}
} else {
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c
index 10ce81790a8c..06da0ddf05a7 100644
--- a/drivers/media/dvb/mantis/mantis_vp2033.c
+++ b/drivers/media/dvb/mantis/mantis_vp2033.c
@@ -132,7 +132,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
- fe = tda10021_attach(&vp2033_tda1002x_cu1216_config,
+ fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@@ -141,7 +141,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2033_tda1002x_cu1216_config.demod_address);
} else {
- fe = tda10023_attach(&vp2033_tda10023_cu1216_config,
+ fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
adapter,
read_pwm(mantis));
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c
index a7ca233e800b..f72b137b7652 100644
--- a/drivers/media/dvb/mantis/mantis_vp2040.c
+++ b/drivers/media/dvb/mantis/mantis_vp2040.c
@@ -132,7 +132,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
- fe = tda10021_attach(&vp2040_tda1002x_cu1216_config,
+ fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@@ -141,7 +141,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2040_tda1002x_cu1216_config.demod_address);
} else {
- fe = tda10023_attach(&vp2040_tda10023_cu1216_config,
+ fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config,
adapter,
read_pwm(mantis));
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
index 1f4334214953..c09308cd3ac6 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.c
+++ b/drivers/media/dvb/mantis/mantis_vp3030.c
@@ -59,21 +59,21 @@ static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
struct mantis_hwconfig *config = mantis->hwconfig;
int err = 0;
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
err = mantis_frontend_power(mantis, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
if (err == 0) {
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
- fe = zl10353_attach(&mantis_vp3030_config, adapter);
+ fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter);
if (!fe)
return -1;
- tda665x_attach(fe, &env57h12d5_config, adapter);
+ dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter);
} else {
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
adapter->name,
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index 3a7ef71087be..be71f915e2a3 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -1515,7 +1515,7 @@ static int init_channels(struct ngene *dev)
void __devexit ngene_remove(struct pci_dev *pdev)
{
- struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
+ struct ngene *dev = pci_get_drvdata(pdev);
int i;
tasklet_kill(&dev->event_tasklet);
@@ -1536,12 +1536,11 @@ int __devinit ngene_probe(struct pci_dev *pci_dev,
if (pci_enable_device(pci_dev) < 0)
return -ENODEV;
- dev = vmalloc(sizeof(struct ngene));
+ dev = vzalloc(sizeof(struct ngene));
if (dev == NULL) {
stat = -ENOMEM;
goto fail0;
}
- memset(dev, 0, sizeof(struct ngene));
dev->pci_dev = pci_dev;
dev->card_info = (struct ngene_info *)id->driver_data;
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
index e520bceee0af..bc6456eb2c4f 100644
--- a/drivers/media/dvb/siano/Kconfig
+++ b/drivers/media/dvb/siano/Kconfig
@@ -4,7 +4,7 @@
config SMS_SIANO_MDTV
tristate "Siano SMS1xxx based MDTV receiver"
- depends on DVB_CORE && IR_CORE && HAS_DMA
+ depends on DVB_CORE && RC_CORE && HAS_DMA
---help---
Choose Y or M here if you have MDTV receiver with a Siano chipset.
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 135e45bd00c7..78765ed28063 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -438,7 +438,7 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
int rc;
void *buffer;
- coredev->ir.input_dev = NULL;
+ coredev->ir.dev = NULL;
ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
if (ir_io) {/* only if IR port exist we use IR sub-module */
sms_info("IR loading");
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
index a27c44a8af5a..37bc5c4b8ad8 100644
--- a/drivers/media/dvb/siano/smsir.c
+++ b/drivers/media/dvb/siano/smsir.c
@@ -45,25 +45,24 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
ev.pulse = (samples[i] > 0) ? false : true;
- ir_raw_event_store(coredev->ir.input_dev, &ev);
+ ir_raw_event_store(coredev->ir.dev, &ev);
}
- ir_raw_event_handle(coredev->ir.input_dev);
+ ir_raw_event_handle(coredev->ir.dev);
}
int sms_ir_init(struct smscore_device_t *coredev)
{
- struct input_dev *input_dev;
+ int err;
int board_id = smscore_get_board_id(coredev);
+ struct rc_dev *dev;
- sms_log("Allocating input device");
- input_dev = input_allocate_device();
- if (!input_dev) {
+ sms_log("Allocating rc device");
+ dev = rc_allocate_device();
+ if (!dev) {
sms_err("Not enough memory");
return -ENOMEM;
}
- coredev->ir.input_dev = input_dev;
-
coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms",
@@ -75,38 +74,41 @@ int sms_ir_init(struct smscore_device_t *coredev)
strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
- input_dev->name = coredev->ir.name;
- input_dev->phys = coredev->ir.phys;
- input_dev->dev.parent = coredev->device;
+ dev->input_name = coredev->ir.name;
+ dev->input_phys = coredev->ir.phys;
+ dev->dev.parent = coredev->device;
#if 0
/* TODO: properly initialize the parameters bellow */
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ dev->input_id.bustype = BUS_USB;
+ dev->input_id.version = 1;
+ dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif
- coredev->ir.props.priv = coredev;
- coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
- coredev->ir.props.allowed_protos = IR_TYPE_ALL;
+ dev->priv = coredev;
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->allowed_protos = RC_TYPE_ALL;
+ dev->map_name = sms_get_board(board_id)->rc_codes;
+ dev->driver_name = MODULE_NAME;
- sms_log("Input device (IR) %s is set for key events", input_dev->name);
+ sms_log("Input device (IR) %s is set for key events", dev->input_name);
- if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
- &coredev->ir.props, MODULE_NAME)) {
+ err = rc_register_device(dev);
+ if (err < 0) {
sms_err("Failed to register device");
- input_free_device(input_dev);
- return -EACCES;
+ rc_free_device(dev);
+ return err;
}
+ coredev->ir.dev = dev;
return 0;
}
void sms_ir_exit(struct smscore_device_t *coredev)
{
- if (coredev->ir.input_dev)
- ir_input_unregister(coredev->ir.input_dev);
+ if (coredev->ir.dev)
+ rc_unregister_device(coredev->ir.dev);
sms_log("");
}
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
index 926e247523bd..ae92b3a8587e 100644
--- a/drivers/media/dvb/siano/smsir.h
+++ b/drivers/media/dvb/siano/smsir.h
@@ -28,20 +28,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define __SMS_IR_H__
#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#define IR_DEFAULT_TIMEOUT 100
struct smscore_device_t;
struct ir_t {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char name[40];
char phys[32];
char *rc_codes;
u64 protocol;
- struct ir_dev_props props;
u32 timeout;
u32 controller;
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 50d4338610e0..0b8da57cf4c3 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -288,8 +288,7 @@ static int smsusb1_setmode(void *context, int mode)
static void smsusb_term_device(struct usb_interface *intf)
{
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *) usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
if (dev) {
smsusb_stop_streaming(dev);
@@ -445,8 +444,7 @@ static void smsusb_disconnect(struct usb_interface *intf)
static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
{
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *)usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
smsusb_stop_streaming(dev);
return 0;
@@ -455,8 +453,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
static int smsusb_resume(struct usb_interface *intf)
{
int rc, i;
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *)usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
printk(KERN_INFO "%s: Entering.\n", __func__);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index debea8d1d31c..44afab2fdc2d 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -89,7 +89,6 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_BUDGET_CORE && I2C
- depends on INPUT # due to IR
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
@@ -98,7 +97,7 @@ config DVB_BUDGET_CI
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
- depends on VIDEO_IR
+ depends on RC_CORE
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index ac20c5bbfa43..cdd31cae46c4 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -100,6 +100,7 @@ static struct v4l2_input inputs[4] = {
.tuner = 0, /* ignored */
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ .capabilities = V4L2_IN_CAP_STD,
}, {
.index = 1,
.name = "Television",
@@ -108,6 +109,7 @@ static struct v4l2_input inputs[4] = {
.tuner = 0,
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ .capabilities = V4L2_IN_CAP_STD,
}, {
.index = 2,
.name = "Video",
@@ -116,6 +118,7 @@ static struct v4l2_input inputs[4] = {
.tuner = 0,
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ .capabilities = V4L2_IN_CAP_STD,
}, {
.index = 3,
.name = "Y/C",
@@ -124,6 +127,7 @@ static struct v4l2_input inputs[4] = {
.tuner = 0,
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ .capabilities = V4L2_IN_CAP_STD,
}
};
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 97afc01f60d0..e957d7690bcc 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1406,8 +1406,10 @@ static int budget_av_detach(struct saa7146_dev *dev)
#define KNC1_INPUTS 2
static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
- {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
- {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+ { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
+ V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
+ V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
};
static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index a9c2c326df4b..b82756db5bd1 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -33,9 +33,8 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/spinlock.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "budget.h"
@@ -96,7 +95,7 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct budget_ci_ir {
- struct input_dev *dev;
+ struct rc_dev *dev;
struct tasklet_struct msp430_irq_tasklet;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32];
@@ -118,7 +117,7 @@ struct budget_ci {
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = budget_ci->ir.dev;
+ struct rc_dev *dev = budget_ci->ir.dev;
u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
/*
@@ -160,19 +159,17 @@ static void msp430_ir_interrupt(unsigned long data)
budget_ci->ir.rc5_device != (command & 0x1f))
return;
- ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
+ rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
}
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *input_dev = budget_ci->ir.dev;
+ struct rc_dev *dev;
int error;
- char *ir_codes = NULL;
-
- budget_ci->ir.dev = input_dev = input_allocate_device();
- if (!input_dev) {
+ dev = rc_allocate_device();
+ if (!dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
return -ENOMEM;
}
@@ -182,19 +179,20 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
"pci-%s/ir0", pci_name(saa->pci));
- input_dev->name = budget_ci->ir.name;
-
- input_dev->phys = budget_ci->ir.phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->input_name = budget_ci->ir.name;
+ dev->input_phys = budget_ci->ir.phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
+ dev->scanmask = 0xff;
if (saa->pci->subsystem_vendor) {
- input_dev->id.vendor = saa->pci->subsystem_vendor;
- input_dev->id.product = saa->pci->subsystem_device;
+ dev->input_id.vendor = saa->pci->subsystem_vendor;
+ dev->input_id.product = saa->pci->subsystem_device;
} else {
- input_dev->id.vendor = saa->pci->vendor;
- input_dev->id.product = saa->pci->device;
+ dev->input_id.vendor = saa->pci->vendor;
+ dev->input_id.product = saa->pci->device;
}
- input_dev->dev.parent = &saa->pci->dev;
+ dev->dev.parent = &saa->pci->dev;
if (rc5_device < 0)
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -208,7 +206,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1011:
case 0x1012:
/* The hauppauge keymap is a superset of these remotes */
- ir_codes = RC_MAP_HAUPPAUGE_NEW;
+ dev->map_name = RC_MAP_HAUPPAUGE_NEW;
if (rc5_device < 0)
budget_ci->ir.rc5_device = 0x1f;
@@ -218,23 +216,22 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1019:
case 0x101a:
/* for the Technotrend 1500 bundled remote */
- ir_codes = RC_MAP_TT_1500;
+ dev->map_name = RC_MAP_TT_1500;
break;
default:
/* unknown remote */
- ir_codes = RC_MAP_BUDGET_CI_OLD;
+ dev->map_name = RC_MAP_BUDGET_CI_OLD;
break;
}
- error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ error = rc_register_device(dev);
if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
+ rc_free_device(dev);
return error;
}
- /* note: these must be after input_register_device */
- input_dev->rep[REP_DELAY] = 400;
- input_dev->rep[REP_PERIOD] = 250;
+ budget_ci->ir.dev = dev;
tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci);
@@ -248,13 +245,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = budget_ci->ir.dev;
SAA7146_IER_DISABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
- ir_input_unregister(dev);
+ rc_unregister_device(budget_ci->ir.dev);
}
static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 83567b898d09..3c5a4739ed70 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -452,4 +452,20 @@ config RADIO_TIMBERDALE
found behind the Timberdale FPGA on the Russellville board.
Enabling this driver will automatically select the DSP and tuner.
+config RADIO_WL1273
+ tristate "Texas Instruments WL1273 I2C FM Radio"
+ depends on I2C && VIDEO_V4L2
+ select MFD_WL1273_CORE
+ select FW_LOADER
+ ---help---
+ Choose Y here if you have this FM radio chip.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video For Linux 2 API. Information on
+ this API and pointers to "v4l2" programs may be found at
+ <file:Documentation/video4linux/API.html>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-wl1273.
+
endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index f615583b4837..d2970748a69f 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
+obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 5bf4985daede..05e832f61c3e 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations rtrack_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
@@ -412,13 +412,6 @@ static int __init rtrack_init(void)
rt->vdev.release = video_device_release_empty;
video_set_drvdata(&rt->vdev, rt);
- if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(&rt->v4l2_dev);
- release_region(rt->io, 2);
- return -EINVAL;
- }
- v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
/* Set up the I/O locking */
mutex_init(&rt->lock);
@@ -430,6 +423,13 @@ static int __init rtrack_init(void)
sleep_delay(2000000); /* make sure it's totally down */
outb(0xc0, rt->io); /* steady volume, mute card */
+ if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
+
return 0;
}
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index c22311393624..dd8a6ab0d437 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
@@ -375,6 +375,8 @@ static int __init aztech_init(void)
az->vdev.ioctl_ops = &aztech_ioctl_ops;
az->vdev.release = video_device_release_empty;
video_set_drvdata(&az->vdev, az);
+ /* mute card - prevents noisy bootups */
+ outb(0, az->io);
if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
@@ -383,8 +385,6 @@ static int __init aztech_init(void)
}
v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
- /* mute card - prevents noisy bootups */
- outb(0, az->io);
return 0;
}
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index b701ea6e7c73..bc9ad0897c55 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
unsigned char readbuf[RDS_BUFFER];
int i = 0;
+ mutex_lock(&dev->lock);
if (dev->rdsstat == 0) {
- mutex_lock(&dev->lock);
dev->rdsstat = 1;
outb(0x80, dev->io); /* Select RDS fifo */
- mutex_unlock(&dev->lock);
init_timer(&dev->readtimer);
dev->readtimer.function = cadet_handler;
dev->readtimer.data = (unsigned long)dev;
@@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
add_timer(&dev->readtimer);
}
if (dev->rdsin == dev->rdsout) {
+ mutex_unlock(&dev->lock);
if (file->f_flags & O_NONBLOCK)
return -EWOULDBLOCK;
interruptible_sleep_on(&dev->read_queue);
+ mutex_lock(&dev->lock);
}
while (i < count && dev->rdsin != dev->rdsout)
readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+ mutex_unlock(&dev->lock);
if (copy_to_user(data, readbuf, i))
return -EFAULT;
@@ -525,9 +527,11 @@ static int cadet_open(struct file *file)
{
struct cadet *dev = video_drvdata(file);
+ mutex_lock(&dev->lock);
dev->users++;
if (1 == dev->users)
init_waitqueue_head(&dev->read_queue);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -535,11 +539,13 @@ static int cadet_release(struct file *file)
{
struct cadet *dev = video_drvdata(file);
+ mutex_lock(&dev->lock);
dev->users--;
if (0 == dev->users) {
del_timer_sync(&dev->readtimer);
dev->rdsstat = 0;
}
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = {
.open = cadet_open,
.release = cadet_release,
.read = cadet_read,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = cadet_poll,
};
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 79039674a0e0..28fa85ba2087 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
@@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev
card->vdev.release = video_device_release_empty;
video_set_drvdata(&card->vdev, card);
+ gemtek_pci_mute(card);
+
if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
goto err_video;
- gemtek_pci_mute(card);
-
v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
pdev->revision, card->iobase, card->iobase + card->length - 1);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 73985f641f07..259936422e49 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt)
static const struct v4l2_file_operations gemtek_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int vidioc_querycap(struct file *file, void *priv,
@@ -577,12 +577,6 @@ static int __init gemtek_init(void)
gt->vdev.release = video_device_release_empty;
video_set_drvdata(&gt->vdev, gt);
- if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(gt->io, 1);
- return -EBUSY;
- }
-
/* Set defaults */
gt->lastfreq = GEMTEK_LOWFREQ;
gt->bu2614data = 0;
@@ -590,6 +584,12 @@ static int __init gemtek_init(void)
if (initmute)
gemtek_mute(gt);
+ if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(gt->io, 1);
+ return -EBUSY;
+ }
+
return 0;
}
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 08f1051979ca..6af61bfeb178 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations maestro_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
@@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+ if (!radio_power_on(dev)) {
+ retval = -EIO;
+ goto errfr1;
+ }
+
retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
if (retval) {
v4l2_err(v4l2_dev, "can't register video device!\n");
goto errfr1;
}
- if (!radio_power_on(dev)) {
- retval = -EIO;
- goto errunr;
- }
-
v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
return 0;
-errunr:
- video_unregister_device(&dev->vdev);
errfr1:
v4l2_device_unregister(v4l2_dev);
errfr:
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 255d40df4b46..6459a220b0dd 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static const struct v4l2_file_operations maxiradio_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index 4ff885445fd4..3fb76e3834c9 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -33,6 +33,7 @@ struct pcm20 {
unsigned long freq;
int muted;
struct snd_miro_aci *aci;
+ struct mutex lock;
};
static struct pcm20 pcm20_card = {
@@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
static const struct v4l2_file_operations pcm20_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int vidioc_querycap(struct file *file, void *priv,
@@ -229,7 +230,7 @@ static int __init pcm20_init(void)
return -ENODEV;
}
strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
-
+ mutex_init(&dev->lock);
res = v4l2_device_register(NULL, v4l2_dev);
if (res < 0) {
@@ -242,6 +243,7 @@ static int __init pcm20_init(void)
dev->vdev.fops = &pcm20_fops;
dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
dev->vdev.release = video_device_release_empty;
+ dev->vdev.lock = &dev->lock;
video_set_drvdata(&dev->vdev, dev);
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index a79296aac9a9..8d6ea591bd18 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
@@ -315,6 +315,10 @@ static int __init rtrack2_init(void)
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+ /* mute card - prevents noisy bootups */
+ outb(1, dev->io);
+ dev->muted = 1;
+
mutex_init(&dev->lock);
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
@@ -324,10 +328,6 @@ static int __init rtrack2_init(void)
v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
- /* mute card - prevents noisy bootups */
- outb(1, dev->io);
- dev->muted = 1;
-
return 0;
}
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 985359d18aa5..b5a5f89e238a 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
@@ -382,6 +382,9 @@ static int __init fmi_init(void)
mutex_init(&fmi->lock);
+ /* mute card - prevents noisy bootups */
+ fmi_mute(fmi);
+
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
release_region(fmi->io, 2);
@@ -391,8 +394,6 @@ static int __init fmi_init(void)
}
v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
- /* mute card - prevents noisy bootups */
- fmi_mute(fmi);
return 0;
}
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 52c7bbb32b8b..dc3f04c52d5e 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations fmr2_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
@@ -424,6 +424,10 @@ static int __init fmr2_init(void)
fmr2->vdev.release = video_device_release_empty;
video_set_drvdata(&fmr2->vdev, fmr2);
+ /* mute card - prevents noisy bootups */
+ fmr2_mute(fmr2->io);
+ fmr2_product_info(fmr2);
+
if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
release_region(fmr2->io, 2);
@@ -431,11 +435,6 @@ static int __init fmr2_init(void)
}
v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
- /* mute card - prevents noisy bootups */
- mutex_lock(&fmr2->lock);
- fmr2_mute(fmr2->io);
- fmr2_product_info(fmr2);
- mutex_unlock(&fmr2->lock);
debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
return 0;
}
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 6a435786b63d..726d367ad8d0 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -53,7 +53,8 @@ struct radio_si4713_device {
/* radio_si4713_fops - file operations interface */
static const struct v4l2_file_operations radio_si4713_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ /* Note: locking is done at the subdev level in the i2c driver. */
+ .unlocked_ioctl = video_ioctl2,
};
/* Video4Linux Interface */
@@ -291,7 +292,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
goto unregister_v4l2_dev;
}
- sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL,
+ sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter,
pdata->subdev_board_info, NULL);
if (!sd) {
dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 789d2ec66e19..0e71d816c725 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -142,7 +142,6 @@ struct tea5764_device {
struct video_device *videodev;
struct tea5764_regs regs;
struct mutex mutex;
- int users;
};
/* I2C code related */
@@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv,
return 0;
}
-static int tea5764_open(struct file *file)
-{
- /* Currently we support only one device */
- struct tea5764_device *radio = video_drvdata(file);
-
- mutex_lock(&radio->mutex);
- /* Only exclusive access */
- if (radio->users) {
- mutex_unlock(&radio->mutex);
- return -EBUSY;
- }
- radio->users++;
- mutex_unlock(&radio->mutex);
- file->private_data = radio;
- return 0;
-}
-
-static int tea5764_close(struct file *file)
-{
- struct tea5764_device *radio = video_drvdata(file);
-
- if (!radio)
- return -ENODEV;
- mutex_lock(&radio->mutex);
- radio->users--;
- mutex_unlock(&radio->mutex);
- return 0;
-}
-
/* File system interface */
static const struct v4l2_file_operations tea5764_fops = {
.owner = THIS_MODULE,
- .open = tea5764_open,
- .release = tea5764_close,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
@@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
int ret;
PDEBUG("probe");
- radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL);
+ radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL);
if (!radio)
return -ENOMEM;
@@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, radio);
video_set_drvdata(radio->videodev, radio);
-
- ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
- if (ret < 0) {
- PWARN("Could not register video device!");
- goto errrel;
- }
+ radio->videodev->lock = &radio->mutex;
/* initialize and power off the chip */
tea5764_i2c_read(radio);
@@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
tea5764_mute(radio, 1);
tea5764_power_down(radio);
+ ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (ret < 0) {
+ PWARN("Could not register video device!");
+ goto errrel;
+ }
+
PINFO("registered.");
return 0;
errrel:
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index fc1c860fd438..a32663917059 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations terratec_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
@@ -389,6 +389,9 @@ static int __init terratec_init(void)
mutex_init(&tt->lock);
+ /* mute card - prevents noisy bootups */
+ tt_write_vol(tt, 0);
+
if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(&tt->v4l2_dev);
release_region(tt->io, 2);
@@ -396,9 +399,6 @@ static int __init terratec_init(void)
}
v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
-
- /* mute card - prevents noisy bootups */
- tt_write_vol(tt, 0);
return 0;
}
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index b8bb3ef47df5..a185610b376b 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -34,6 +34,7 @@ struct timbradio {
struct v4l2_subdev *sd_dsp;
struct video_device video_dev;
struct v4l2_device v4l2_dev;
+ struct mutex lock;
};
@@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
static const struct v4l2_file_operations timbradio_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int __devinit timbradio_probe(struct platform_device *pdev)
@@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
}
tr->pdata = *pdata;
+ mutex_init(&tr->lock);
strlcpy(tr->video_dev.name, "Timberdale Radio",
sizeof(tr->video_dev.name));
@@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
tr->video_dev.release = video_device_release_empty;
tr->video_dev.minor = -1;
+ tr->video_dev.lock = &tr->lock;
strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
err = v4l2_device_register(NULL, &tr->v4l2_dev);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 9d6dcf8af5b0..22fa9cc28abe 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations trust_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops trust_ioctl_ops = {
@@ -396,14 +396,6 @@ static int __init trust_init(void)
tr->vdev.release = video_device_release_empty;
video_set_drvdata(&tr->vdev, tr);
- if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(tr->io, 2);
- return -EINVAL;
- }
-
- v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
-
write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
@@ -418,6 +410,14 @@ static int __init trust_init(void)
/* mute card - prevents noisy bootups */
tr_setmute(tr, 1);
+ if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(tr->io, 2);
+ return -EINVAL;
+ }
+
+ v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
+
return 0;
}
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index b1f630527dc1..8dbbf08f2207 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv)
static const struct v4l2_file_operations typhoon_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
@@ -344,18 +344,18 @@ static int __init typhoon_init(void)
strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
dev->io = io;
- dev->curfreq = dev->mutefreq = mutefreq;
if (dev->io == -1) {
v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
return -EINVAL;
}
- if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+ if (mutefreq < 87000 || mutefreq > 108500) {
v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
return -EINVAL;
}
+ dev->curfreq = dev->mutefreq = mutefreq << 4;
mutex_init(&dev->lock);
if (!request_region(dev->io, 8, "typhoon")) {
@@ -378,17 +378,17 @@ static int __init typhoon_init(void)
dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+
+ /* mute card - prevents noisy bootups */
+ typhoon_mute(dev);
+
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(&dev->v4l2_dev);
release_region(dev->io, 8);
return -EINVAL;
}
v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
- v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
- dev->mutefreq <<= 4;
-
- /* mute card - prevents noisy bootups */
- typhoon_mute(dev);
+ v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
return 0;
}
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
new file mode 100644
index 000000000000..dd6bd364efa0
--- /dev/null
+++ b/drivers/media/radio/radio-wl1273.c
@@ -0,0 +1,2330 @@
+/*
+ * Driver for the Texas Instruments WL1273 FM radio.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Author: Matti J. Aaltonen <matti.j.aaltonen@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/wl1273-core.h>
+#include <linux/slab.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+#define DRIVER_DESC "Wl1273 FM Radio"
+
+#define WL1273_POWER_SET_OFF 0
+#define WL1273_POWER_SET_FM BIT(0)
+#define WL1273_POWER_SET_RDS BIT(1)
+#define WL1273_POWER_SET_RETENTION BIT(4)
+
+#define WL1273_PUPD_SET_OFF 0x00
+#define WL1273_PUPD_SET_ON 0x01
+#define WL1273_PUPD_SET_RETENTION 0x10
+
+#define WL1273_FREQ(x) (x * 10000 / 625)
+#define WL1273_INV_FREQ(x) (x * 625 / 10000)
+
+/*
+ * static int radio_nr - The number of the radio device
+ *
+ * The default is 0.
+ */
+static int radio_nr;
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(radio_nr, "The number of the radio device. Default = 0");
+
+struct wl1273_device {
+ char *bus_type;
+
+ u8 forbidden;
+ unsigned int preemphasis;
+ unsigned int spacing;
+ unsigned int tx_power;
+ unsigned int rx_frequency;
+ unsigned int tx_frequency;
+ unsigned int rangelow;
+ unsigned int rangehigh;
+ unsigned int band;
+ bool stereo;
+
+ /* RDS */
+ unsigned int rds_on;
+ struct delayed_work work;
+
+ wait_queue_head_t read_queue;
+ struct mutex lock; /* for serializing fm radio operations */
+ struct completion busy;
+
+ unsigned char *buffer;
+ unsigned int buf_size;
+ unsigned int rd_index;
+ unsigned int wr_index;
+
+ /* Selected interrupts */
+ u16 irq_flags;
+ u16 irq_received;
+
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_device v4l2dev;
+ struct video_device videodev;
+ struct device *dev;
+ struct wl1273_core *core;
+ struct file *owner;
+ char *write_buf;
+ unsigned int rds_users;
+};
+
+#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \
+ WL1273_POW_ENB_EVENT)
+
+/*
+ * static unsigned int rds_buf - the number of RDS buffer blocks used.
+ *
+ * The default number is 100.
+ */
+static unsigned int rds_buf = 100;
+module_param(rds_buf, uint, 0);
+MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
+
+static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
+{
+ struct i2c_client *client = core->client;
+ u8 b[2];
+ int r;
+
+ r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
+ if (r != 2) {
+ dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
+ return -EREMOTEIO;
+ }
+
+ *value = (u16)b[0] << 8 | b[1];
+
+ return 0;
+}
+
+static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
+{
+ struct i2c_client *client = core->client;
+ u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
+ int r;
+
+ r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
+ if (r) {
+ dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
+ return r;
+ }
+
+ return 0;
+}
+
+static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
+{
+ struct i2c_client *client = core->client;
+ struct i2c_msg msg;
+ int r;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.buf = data;
+ msg.len = len;
+
+ r = i2c_transfer(client->adapter, &msg, 1);
+ if (r != 1) {
+ dev_err(&client->dev, "%s: write error.\n", __func__);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int wl1273_fm_write_fw(struct wl1273_core *core,
+ __u8 *fw, int len)
+{
+ struct i2c_client *client = core->client;
+ struct i2c_msg msg;
+ int i, r = 0;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+
+ for (i = 0; i <= len; i++) {
+ msg.len = fw[0];
+ msg.buf = fw + 1;
+
+ fw += msg.len + 1;
+ dev_dbg(&client->dev, "%s:len[%d]: %d\n", __func__, i, msg.len);
+
+ r = i2c_transfer(client->adapter, &msg, 1);
+ if (r < 0 && i < len + 1)
+ break;
+ }
+
+ dev_dbg(&client->dev, "%s: i: %d\n", __func__, i);
+ dev_dbg(&client->dev, "%s: len + 1: %d\n", __func__, len + 1);
+
+ /* Last transfer always fails. */
+ if (i == len || r == 1)
+ r = 0;
+
+ return r;
+}
+
+/**
+ * wl1273_fm_set_audio() - Set audio mode.
+ * @core: A pointer to the device struct.
+ * @new_mode: The new audio mode.
+ *
+ * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
+ */
+static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
+{
+ int r = 0;
+
+ if (core->mode == WL1273_MODE_OFF ||
+ core->mode == WL1273_MODE_SUSPENDED)
+ return -EPERM;
+
+ if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
+ r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
+ WL1273_PCM_DEF_MODE);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
+ core->i2s_mode);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
+ WL1273_AUDIO_ENABLE_I2S);
+ if (r)
+ goto out;
+
+ } else if (core->mode == WL1273_MODE_RX &&
+ new_mode == WL1273_AUDIO_ANALOG) {
+ r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
+ WL1273_AUDIO_ENABLE_ANALOG);
+ if (r)
+ goto out;
+
+ } else if (core->mode == WL1273_MODE_TX &&
+ new_mode == WL1273_AUDIO_DIGITAL) {
+ r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
+ core->i2s_mode);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
+ WL1273_AUDIO_IO_SET_I2S);
+ if (r)
+ goto out;
+
+ } else if (core->mode == WL1273_MODE_TX &&
+ new_mode == WL1273_AUDIO_ANALOG) {
+ r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
+ WL1273_AUDIO_IO_SET_ANALOG);
+ if (r)
+ goto out;
+ }
+
+ core->audio_mode = new_mode;
+out:
+ return r;
+}
+
+/**
+ * wl1273_fm_set_volume() - Set volume.
+ * @core: A pointer to the device struct.
+ * @volume: The new volume value.
+ */
+static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
+{
+ u16 val;
+ int r;
+
+ if (volume > WL1273_MAX_VOLUME)
+ return -EINVAL;
+
+ if (core->volume == volume)
+ return 0;
+
+ val = volume;
+ r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
+ if (r)
+ return r;
+
+ core->volume = volume;
+ return 0;
+}
+
+#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
+#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
+#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
+
+static int wl1273_fm_rds(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ struct i2c_client *client = core->client;
+ u16 val;
+ u8 b0 = WL1273_RDS_DATA_GET, status;
+ struct v4l2_rds_data rds = { 0, 0, 0 };
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = &b0,
+ .len = 1,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .buf = (u8 *) &rds,
+ .len = sizeof(rds),
+ }
+ };
+ int r;
+
+ if (core->mode != WL1273_MODE_RX)
+ return 0;
+
+ r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
+ if (r)
+ return r;
+
+ if ((val & 0x01) == 0) {
+ /* RDS decoder not synchronized */
+ return -EAGAIN;
+ }
+
+ /* copy all four RDS blocks to internal buffer */
+ do {
+ r = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+ if (r != ARRAY_SIZE(msg)) {
+ dev_err(radio->dev, WL1273_FM_DRIVER_NAME
+ ": %s: read_rds error r == %i)\n",
+ __func__, r);
+ }
+
+ status = rds.block;
+
+ if (!WL1273_FIFO_HAS_DATA(status))
+ break;
+
+ /* copy bits 0-2 (the block ID) to bits 3-5 */
+ rds.block = V4L2_RDS_BLOCK_MSK & status;
+ rds.block |= rds.block << 3;
+
+ /* copy the error bits to standard positions */
+ if (WL1273_RDS_UNCORRECTABLE_ERROR & status) {
+ rds.block |= V4L2_RDS_BLOCK_ERROR;
+ rds.block &= ~V4L2_RDS_BLOCK_CORRECTED;
+ } else if (WL1273_RDS_CORRECTABLE_ERROR & status) {
+ rds.block &= ~V4L2_RDS_BLOCK_ERROR;
+ rds.block |= V4L2_RDS_BLOCK_CORRECTED;
+ }
+
+ /* copy RDS block to internal buffer */
+ memcpy(&radio->buffer[radio->wr_index], &rds, RDS_BLOCK_SIZE);
+ radio->wr_index += 3;
+
+ /* wrap write pointer */
+ if (radio->wr_index >= radio->buf_size)
+ radio->wr_index = 0;
+
+ /* check for overflow & start over */
+ if (radio->wr_index == radio->rd_index) {
+ dev_dbg(radio->dev, "RDS OVERFLOW");
+
+ radio->rd_index = 0;
+ radio->wr_index = 0;
+ break;
+ }
+ } while (WL1273_FIFO_HAS_DATA(status));
+
+ /* wake up read queue */
+ if (radio->wr_index != radio->rd_index)
+ wake_up_interruptible(&radio->read_queue);
+
+ return 0;
+}
+
+static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
+{
+ struct wl1273_device *radio = dev_id;
+ struct wl1273_core *core = radio->core;
+ u16 flags;
+ int r;
+
+ r = wl1273_fm_read_reg(core, WL1273_FLAG_GET, &flags);
+ if (r)
+ goto out;
+
+ if (flags & WL1273_BL_EVENT) {
+ radio->irq_received = flags;
+ dev_dbg(radio->dev, "IRQ: BL\n");
+ }
+
+ if (flags & WL1273_RDS_EVENT) {
+ msleep(200);
+
+ wl1273_fm_rds(radio);
+ }
+
+ if (flags & WL1273_BBLK_EVENT)
+ dev_dbg(radio->dev, "IRQ: BBLK\n");
+
+ if (flags & WL1273_LSYNC_EVENT)
+ dev_dbg(radio->dev, "IRQ: LSYNC\n");
+
+ if (flags & WL1273_LEV_EVENT) {
+ u16 level;
+
+ r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &level);
+ if (r)
+ goto out;
+
+ if (level > 14)
+ dev_dbg(radio->dev, "IRQ: LEV: 0x%x04\n", level);
+ }
+
+ if (flags & WL1273_IFFR_EVENT)
+ dev_dbg(radio->dev, "IRQ: IFFR\n");
+
+ if (flags & WL1273_PI_EVENT)
+ dev_dbg(radio->dev, "IRQ: PI\n");
+
+ if (flags & WL1273_PD_EVENT)
+ dev_dbg(radio->dev, "IRQ: PD\n");
+
+ if (flags & WL1273_STIC_EVENT)
+ dev_dbg(radio->dev, "IRQ: STIC\n");
+
+ if (flags & WL1273_MAL_EVENT)
+ dev_dbg(radio->dev, "IRQ: MAL\n");
+
+ if (flags & WL1273_POW_ENB_EVENT) {
+ complete(&radio->busy);
+ dev_dbg(radio->dev, "NOT BUSY\n");
+ dev_dbg(radio->dev, "IRQ: POW_ENB\n");
+ }
+
+ if (flags & WL1273_SCAN_OVER_EVENT)
+ dev_dbg(radio->dev, "IRQ: SCAN_OVER\n");
+
+ if (flags & WL1273_ERROR_EVENT)
+ dev_dbg(radio->dev, "IRQ: ERROR\n");
+
+ if (flags & WL1273_FR_EVENT) {
+ u16 freq;
+
+ dev_dbg(radio->dev, "IRQ: FR:\n");
+
+ if (core->mode == WL1273_MODE_RX) {
+ r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
+ TUNER_MODE_STOP_SEARCH);
+ if (r) {
+ dev_err(radio->dev,
+ "%s: TUNER_MODE_SET fails: %d\n",
+ __func__, r);
+ goto out;
+ }
+
+ r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &freq);
+ if (r)
+ goto out;
+
+ if (radio->band == WL1273_BAND_JAPAN)
+ radio->rx_frequency = WL1273_BAND_JAPAN_LOW +
+ freq * 50;
+ else
+ radio->rx_frequency = WL1273_BAND_OTHER_LOW +
+ freq * 50;
+ /*
+ * The driver works better with this msleep,
+ * the documentation doesn't mention it.
+ */
+ usleep_range(10000, 15000);
+
+ dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
+
+ } else {
+ r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &freq);
+ if (r)
+ goto out;
+
+ dev_dbg(radio->dev, "%dkHz\n", freq);
+ }
+ dev_dbg(radio->dev, "%s: NOT BUSY\n", __func__);
+ }
+
+out:
+ wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
+ radio->irq_flags);
+ complete(&radio->busy);
+
+ return IRQ_HANDLED;
+}
+
+static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
+{
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ if (freq < WL1273_BAND_TX_LOW) {
+ dev_err(radio->dev,
+ "Frequency out of range: %d < %d\n", freq,
+ WL1273_BAND_TX_LOW);
+ return -ERANGE;
+ }
+
+ if (freq > WL1273_BAND_TX_HIGH) {
+ dev_err(radio->dev,
+ "Frequency out of range: %d > %d\n", freq,
+ WL1273_BAND_TX_HIGH);
+ return -ERANGE;
+ }
+
+ /*
+ * The driver works better with this sleep,
+ * the documentation doesn't mention it.
+ */
+ usleep_range(5000, 10000);
+
+ dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
+
+ /* Set the current tx channel */
+ r = wl1273_fm_write_cmd(core, WL1273_CHANL_SET, freq / 10);
+ if (r)
+ return r;
+
+ INIT_COMPLETION(radio->busy);
+
+ /* wait for the FR IRQ */
+ r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));
+ if (!r)
+ return -ETIMEDOUT;
+
+ dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);
+
+ /* Enable the output power */
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_ENB_SET, 1);
+ if (r)
+ return r;
+
+ INIT_COMPLETION(radio->busy);
+
+ /* wait for the POWER_ENB IRQ */
+ r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));
+ if (!r)
+ return -ETIMEDOUT;
+
+ radio->tx_frequency = freq;
+ dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %d\n", r);
+
+ return 0;
+}
+
+static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
+{
+ struct wl1273_core *core = radio->core;
+ int r, f;
+
+ if (freq < radio->rangelow) {
+ dev_err(radio->dev,
+ "Frequency out of range: %d < %d\n", freq,
+ radio->rangelow);
+ r = -ERANGE;
+ goto err;
+ }
+
+ if (freq > radio->rangehigh) {
+ dev_err(radio->dev,
+ "Frequency out of range: %d > %d\n", freq,
+ radio->rangehigh);
+ r = -ERANGE;
+ goto err;
+ }
+
+ dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
+
+ wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
+
+ if (radio->band == WL1273_BAND_JAPAN)
+ f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
+ else
+ f = (freq - WL1273_BAND_OTHER_LOW) / 50;
+
+ r = wl1273_fm_write_cmd(core, WL1273_FREQ_SET, f);
+ if (r) {
+ dev_err(radio->dev, "FREQ_SET fails\n");
+ goto err;
+ }
+
+ r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
+ if (r) {
+ dev_err(radio->dev, "TUNER_MODE_SET fails\n");
+ goto err;
+ }
+
+ INIT_COMPLETION(radio->busy);
+
+ r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));
+ if (!r) {
+ dev_err(radio->dev, "%s: TIMEOUT\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ radio->rd_index = 0;
+ radio->wr_index = 0;
+ radio->rx_frequency = freq;
+ return 0;
+err:
+ return r;
+}
+
+static int wl1273_fm_get_freq(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ unsigned int freq;
+ u16 f;
+ int r;
+
+ if (core->mode == WL1273_MODE_RX) {
+ r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &f);
+ if (r)
+ return r;
+
+ dev_dbg(radio->dev, "Freq get: 0x%04x\n", f);
+ if (radio->band == WL1273_BAND_JAPAN)
+ freq = WL1273_BAND_JAPAN_LOW + 50 * f;
+ else
+ freq = WL1273_BAND_OTHER_LOW + 50 * f;
+ } else {
+ r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &f);
+ if (r)
+ return r;
+
+ freq = f * 10;
+ }
+
+ return freq;
+}
+
+/**
+ * wl1273_fm_upload_firmware_patch() - Upload the firmware.
+ * @radio: A pointer to the device struct.
+ *
+ * The firmware file consists of arrays of bytes where the first byte
+ * gives the array length. The first byte in the file gives the
+ * number of these arrays.
+ */
+static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ unsigned int packet_num;
+ const struct firmware *fw_p;
+ const char *fw_name = "radio-wl1273-fw.bin";
+ struct device *dev = radio->dev;
+ __u8 *ptr;
+ int r;
+
+ dev_dbg(dev, "%s:\n", __func__);
+
+ /*
+ * Uploading the firmware patch is not always necessary,
+ * so we only print an info message.
+ */
+ if (request_firmware(&fw_p, fw_name, dev)) {
+ dev_info(dev, "%s - %s not found\n", __func__, fw_name);
+
+ return 0;
+ }
+
+ ptr = (__u8 *) fw_p->data;
+ packet_num = ptr[0];
+ dev_dbg(dev, "%s: packets: %d\n", __func__, packet_num);
+
+ r = wl1273_fm_write_fw(core, ptr + 1, packet_num);
+ if (r) {
+ dev_err(dev, "FW upload error: %d\n", r);
+ goto out;
+ }
+
+ /* ignore possible error here */
+ wl1273_fm_write_cmd(core, WL1273_RESET, 0);
+
+ dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
+out:
+ release_firmware(fw_p);
+ return r;
+}
+
+static int wl1273_fm_stop(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+
+ if (core->mode == WL1273_MODE_RX) {
+ int r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
+ WL1273_POWER_SET_OFF);
+ if (r)
+ dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
+ __func__, r);
+ } else if (core->mode == WL1273_MODE_TX) {
+ int r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
+ WL1273_PUPD_SET_OFF);
+ if (r)
+ dev_err(radio->dev,
+ "%s: PUPD_SET fails: %d\n", __func__, r);
+ }
+
+ if (core->pdata->disable) {
+ core->pdata->disable();
+ dev_dbg(radio->dev, "Back to reset\n");
+ }
+
+ return 0;
+}
+
+static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
+{
+ struct wl1273_core *core = radio->core;
+ struct wl1273_fm_platform_data *pdata = core->pdata;
+ struct device *dev = radio->dev;
+ int r = -EINVAL;
+
+ if (pdata->enable && core->mode == WL1273_MODE_OFF) {
+ dev_dbg(radio->dev, "Out of reset\n");
+
+ pdata->enable();
+ msleep(250);
+ }
+
+ if (new_mode == WL1273_MODE_RX) {
+ u16 val = WL1273_POWER_SET_FM;
+
+ if (radio->rds_on)
+ val |= WL1273_POWER_SET_RDS;
+
+ /* If this fails try again */
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
+ if (r) {
+ msleep(100);
+
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
+ if (r) {
+ dev_err(dev, "%s: POWER_SET fails\n", __func__);
+ goto fail;
+ }
+ }
+
+ /* rds buffer configuration */
+ radio->wr_index = 0;
+ radio->rd_index = 0;
+
+ } else if (new_mode == WL1273_MODE_TX) {
+ /* If this fails try again once */
+ r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
+ WL1273_PUPD_SET_ON);
+ if (r) {
+ msleep(100);
+ r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
+ WL1273_PUPD_SET_ON);
+ if (r) {
+ dev_err(dev, "%s: PUPD_SET fails\n", __func__);
+ goto fail;
+ }
+ }
+
+ if (radio->rds_on)
+ r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1);
+ else
+ r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0);
+ } else {
+ dev_warn(dev, "%s: Illegal mode.\n", __func__);
+ }
+
+ if (core->mode == WL1273_MODE_OFF) {
+ r = wl1273_fm_upload_firmware_patch(radio);
+ if (r)
+ dev_warn(dev, "Firmware upload failed.\n");
+
+ /*
+ * Sometimes the chip is in a wrong power state at this point.
+ * So we set the power once again.
+ */
+ if (new_mode == WL1273_MODE_RX) {
+ u16 val = WL1273_POWER_SET_FM;
+
+ if (radio->rds_on)
+ val |= WL1273_POWER_SET_RDS;
+
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
+ if (r) {
+ dev_err(dev, "%s: POWER_SET fails\n", __func__);
+ goto fail;
+ }
+ } else if (new_mode == WL1273_MODE_TX) {
+ r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
+ WL1273_PUPD_SET_ON);
+ if (r) {
+ dev_err(dev, "%s: PUPD_SET fails\n", __func__);
+ goto fail;
+ }
+ }
+ }
+
+ return 0;
+fail:
+ if (pdata->disable)
+ pdata->disable();
+
+ dev_dbg(dev, "%s: return: %d\n", __func__, r);
+ return r;
+}
+
+static int wl1273_fm_suspend(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ /* Cannot go from OFF to SUSPENDED */
+ if (core->mode == WL1273_MODE_RX)
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
+ WL1273_POWER_SET_RETENTION);
+ else if (core->mode == WL1273_MODE_TX)
+ r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
+ WL1273_PUPD_SET_RETENTION);
+ else
+ r = -EINVAL;
+
+ if (r) {
+ dev_err(radio->dev, "%s: POWER_SET fails: %d\n", __func__, r);
+ goto out;
+ }
+
+out:
+ return r;
+}
+
+static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
+{
+ struct wl1273_core *core = radio->core;
+ struct device *dev = radio->dev;
+ int old_mode;
+ int r;
+
+ dev_dbg(dev, "%s\n", __func__);
+ dev_dbg(dev, "Forbidden modes: 0x%02x\n", radio->forbidden);
+
+ old_mode = core->mode;
+ if (mode & radio->forbidden) {
+ r = -EPERM;
+ goto out;
+ }
+
+ switch (mode) {
+ case WL1273_MODE_RX:
+ case WL1273_MODE_TX:
+ r = wl1273_fm_start(radio, mode);
+ if (r) {
+ dev_err(dev, "%s: Cannot start.\n", __func__);
+ wl1273_fm_stop(radio);
+ goto out;
+ }
+
+ core->mode = mode;
+ r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
+ radio->irq_flags);
+ if (r) {
+ dev_err(dev, "INT_MASK_SET fails.\n");
+ goto out;
+ }
+
+ /* remember previous settings */
+ if (mode == WL1273_MODE_RX) {
+ r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
+ if (r) {
+ dev_err(dev, "set freq fails: %d.\n", r);
+ goto out;
+ }
+
+ r = core->set_volume(core, core->volume);
+ if (r) {
+ dev_err(dev, "set volume fails: %d.\n", r);
+ goto out;
+ }
+
+ dev_dbg(dev, "%s: Set vol: %d.\n", __func__,
+ core->volume);
+ } else {
+ r = wl1273_fm_set_tx_freq(radio, radio->tx_frequency);
+ if (r) {
+ dev_err(dev, "set freq fails: %d.\n", r);
+ goto out;
+ }
+ }
+
+ dev_dbg(radio->dev, "%s: Set audio mode.\n", __func__);
+
+ r = core->set_audio(core, core->audio_mode);
+ if (r)
+ dev_err(dev, "Cannot set audio mode.\n");
+ break;
+
+ case WL1273_MODE_OFF:
+ r = wl1273_fm_stop(radio);
+ if (r)
+ dev_err(dev, "%s: Off fails: %d\n", __func__, r);
+ else
+ core->mode = WL1273_MODE_OFF;
+
+ break;
+
+ case WL1273_MODE_SUSPENDED:
+ r = wl1273_fm_suspend(radio);
+ if (r)
+ dev_err(dev, "%s: Suspend fails: %d\n", __func__, r);
+ else
+ core->mode = WL1273_MODE_SUSPENDED;
+
+ break;
+
+ default:
+ dev_err(dev, "%s: Unknown mode: %d\n", __func__, mode);
+ r = -EINVAL;
+ break;
+ }
+out:
+ if (r)
+ core->mode = old_mode;
+
+ return r;
+}
+
+static int wl1273_fm_set_seek(struct wl1273_device *radio,
+ unsigned int wrap_around,
+ unsigned int seek_upward,
+ int level)
+{
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+ unsigned int dir = (seek_upward == 0) ? 0 : 1;
+ unsigned int f;
+
+ f = radio->rx_frequency;
+ dev_dbg(radio->dev, "rx_frequency: %d\n", f);
+
+ if (dir && f + radio->spacing <= radio->rangehigh)
+ r = wl1273_fm_set_rx_freq(radio, f + radio->spacing);
+ else if (dir && wrap_around)
+ r = wl1273_fm_set_rx_freq(radio, radio->rangelow);
+ else if (f - radio->spacing >= radio->rangelow)
+ r = wl1273_fm_set_rx_freq(radio, f - radio->spacing);
+ else if (wrap_around)
+ r = wl1273_fm_set_rx_freq(radio, radio->rangehigh);
+
+ if (r)
+ goto out;
+
+ if (level < SCHAR_MIN || level > SCHAR_MAX)
+ return -EINVAL;
+
+ INIT_COMPLETION(radio->busy);
+ dev_dbg(radio->dev, "%s: BUSY\n", __func__);
+
+ r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
+ if (r)
+ goto out;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ r = wl1273_fm_write_cmd(core, WL1273_SEARCH_LVL_SET, level);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_write_cmd(core, WL1273_SEARCH_DIR_SET, dir);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
+ TUNER_MODE_AUTO_SEEK);
+ if (r)
+ goto out;
+
+ wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));
+ if (!(radio->irq_received & WL1273_BL_EVENT))
+ goto out;
+
+ radio->irq_received &= ~WL1273_BL_EVENT;
+
+ if (!wrap_around)
+ goto out;
+
+ /* Wrap around */
+ dev_dbg(radio->dev, "Wrap around in HW seek.\n");
+
+ if (seek_upward)
+ f = radio->rangelow;
+ else
+ f = radio->rangehigh;
+
+ r = wl1273_fm_set_rx_freq(radio, f);
+ if (r)
+ goto out;
+
+ INIT_COMPLETION(radio->busy);
+ dev_dbg(radio->dev, "%s: BUSY\n", __func__);
+
+ r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
+ TUNER_MODE_AUTO_SEEK);
+ if (r)
+ goto out;
+
+ wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));
+out:
+ dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r);
+ return r;
+}
+
+/**
+ * wl1273_fm_get_tx_ctune() - Get the TX tuning capacitor value.
+ * @radio: A pointer to the device struct.
+ */
+static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ struct device *dev = radio->dev;
+ u16 val;
+ int r;
+
+ if (core->mode == WL1273_MODE_OFF ||
+ core->mode == WL1273_MODE_SUSPENDED)
+ return -EPERM;
+
+ r = wl1273_fm_read_reg(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
+ if (r) {
+ dev_err(dev, "%s: read error: %d\n", __func__, r);
+ goto out;
+ }
+
+out:
+ return val;
+}
+
+/**
+ * wl1273_fm_set_preemphasis() - Set the TX pre-emphasis value.
+ * @radio: A pointer to the device struct.
+ * @preemphasis: The new pre-amphasis value.
+ *
+ * Possible pre-emphasis values are: V4L2_PREEMPHASIS_DISABLED,
+ * V4L2_PREEMPHASIS_50_uS and V4L2_PREEMPHASIS_75_uS.
+ */
+static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
+ unsigned int preemphasis)
+{
+ struct wl1273_core *core = radio->core;
+ int r;
+ u16 em;
+
+ if (core->mode == WL1273_MODE_OFF ||
+ core->mode == WL1273_MODE_SUSPENDED)
+ return -EPERM;
+
+ mutex_lock(&core->lock);
+
+ switch (preemphasis) {
+ case V4L2_PREEMPHASIS_DISABLED:
+ em = 1;
+ break;
+ case V4L2_PREEMPHASIS_50_uS:
+ em = 0;
+ break;
+ case V4L2_PREEMPHASIS_75_uS:
+ em = 2;
+ break;
+ default:
+ r = -EINVAL;
+ goto out;
+ }
+
+ r = wl1273_fm_write_cmd(core, WL1273_PREMPH_SET, em);
+ if (r)
+ goto out;
+
+ radio->preemphasis = preemphasis;
+
+out:
+ mutex_unlock(&core->lock);
+ return r;
+}
+
+static int wl1273_fm_rds_on(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ int r;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+ if (radio->rds_on)
+ return 0;
+
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
+ WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
+ if (r)
+ dev_err(radio->dev, "set freq fails: %d.\n", r);
+out:
+ return r;
+}
+
+static int wl1273_fm_rds_off(struct wl1273_device *radio)
+{
+ struct wl1273_core *core = radio->core;
+ int r;
+
+ if (!radio->rds_on)
+ return 0;
+
+ radio->irq_flags &= ~WL1273_RDS_EVENT;
+
+ r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
+ if (r)
+ goto out;
+
+ /* stop rds reception */
+ cancel_delayed_work(&radio->work);
+
+ /* Service pending read */
+ wake_up_interruptible(&radio->read_queue);
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
+ if (r)
+ dev_err(radio->dev, "set freq fails: %d.\n", r);
+out:
+ dev_dbg(radio->dev, "%s: exiting...\n", __func__);
+
+ return r;
+}
+
+static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
+{
+ int r = 0;
+ struct wl1273_core *core = radio->core;
+
+ if (core->mode == WL1273_MODE_OFF ||
+ core->mode == WL1273_MODE_SUSPENDED)
+ return -EPERM;
+
+ if (new_mode == WL1273_RDS_RESET) {
+ r = wl1273_fm_write_cmd(core, WL1273_RDS_CNTRL_SET, 1);
+ return r;
+ }
+
+ if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
+ r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0);
+ } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
+ r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1);
+ } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
+ r = wl1273_fm_rds_off(radio);
+ } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
+ r = wl1273_fm_rds_on(radio);
+ } else {
+ dev_err(radio->dev, "%s: Unknown mode: %d\n",
+ __func__, new_mode);
+ r = -EINVAL;
+ }
+
+ if (!r)
+ radio->rds_on = (new_mode == WL1273_RDS_ON) ? true : false;
+
+ return r;
+}
+
+static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ u16 val;
+ int r;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (radio->core->mode != WL1273_MODE_TX)
+ return count;
+
+ if (radio->rds_users == 0) {
+ dev_warn(radio->dev, "%s: RDS not on.\n", __func__);
+ return 0;
+ }
+
+ if (mutex_lock_interruptible(&radio->core->lock))
+ return -EINTR;
+ /*
+ * Multiple processes can open the device, but only
+ * one gets to write to it.
+ */
+ if (radio->owner && radio->owner != file) {
+ r = -EBUSY;
+ goto out;
+ }
+ radio->owner = file;
+
+ /* Manual Mode */
+ if (count > 255)
+ val = 255;
+ else
+ val = count;
+
+ wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val);
+
+ if (copy_from_user(radio->write_buf + 1, buf, val)) {
+ r = -EFAULT;
+ goto out;
+ }
+
+ dev_dbg(radio->dev, "Count: %d\n", val);
+ dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
+
+ radio->write_buf[0] = WL1273_RDS_DATA_SET;
+ wl1273_fm_write_data(radio->core, radio->write_buf, val + 1);
+
+ r = val;
+out:
+ mutex_unlock(&radio->core->lock);
+
+ return r;
+}
+
+static unsigned int wl1273_fm_fops_poll(struct file *file,
+ struct poll_table_struct *pts)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+
+ if (radio->owner && radio->owner != file)
+ return -EBUSY;
+
+ radio->owner = file;
+
+ if (core->mode == WL1273_MODE_RX) {
+ poll_wait(file, &radio->read_queue, pts);
+
+ if (radio->rd_index != radio->wr_index)
+ return POLLIN | POLLRDNORM;
+
+ } else if (core->mode == WL1273_MODE_TX) {
+ return POLLOUT | POLLWRNORM;
+ }
+
+ return 0;
+}
+
+static int wl1273_fm_fops_open(struct file *file)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (core->mode == WL1273_MODE_RX && radio->rds_on &&
+ !radio->rds_users) {
+ dev_dbg(radio->dev, "%s: Mode: %d\n", __func__, core->mode);
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ radio->irq_flags |= WL1273_RDS_EVENT;
+
+ r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
+ radio->irq_flags);
+ if (r) {
+ mutex_unlock(&core->lock);
+ goto out;
+ }
+
+ radio->rds_users++;
+
+ mutex_unlock(&core->lock);
+ }
+out:
+ return r;
+}
+
+static int wl1273_fm_fops_release(struct file *file)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (radio->rds_users > 0) {
+ radio->rds_users--;
+ if (radio->rds_users == 0) {
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ radio->irq_flags &= ~WL1273_RDS_EVENT;
+
+ if (core->mode == WL1273_MODE_RX) {
+ r = wl1273_fm_write_cmd(core,
+ WL1273_INT_MASK_SET,
+ radio->irq_flags);
+ if (r) {
+ mutex_unlock(&core->lock);
+ goto out;
+ }
+ }
+ mutex_unlock(&core->lock);
+ }
+ }
+
+ if (file == radio->owner)
+ radio->owner = NULL;
+out:
+ return r;
+}
+
+static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int r = 0;
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ unsigned int block_count = 0;
+ u16 val;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (radio->core->mode != WL1273_MODE_RX)
+ return 0;
+
+ if (radio->rds_users == 0) {
+ dev_warn(radio->dev, "%s: RDS not on.\n", __func__);
+ return 0;
+ }
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ /*
+ * Multiple processes can open the device, but only
+ * one at a time gets read access.
+ */
+ if (radio->owner && radio->owner != file) {
+ r = -EBUSY;
+ goto out;
+ }
+ radio->owner = file;
+
+ r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
+ if (r) {
+ dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
+ goto out;
+ } else if (val == 0) {
+ dev_info(radio->dev, "RDS_SYNC: Not synchronized\n");
+ r = -ENODATA;
+ goto out;
+ }
+
+ /* block if no new data available */
+ while (radio->wr_index == radio->rd_index) {
+ if (file->f_flags & O_NONBLOCK) {
+ r = -EWOULDBLOCK;
+ goto out;
+ }
+
+ dev_dbg(radio->dev, "%s: Wait for RDS data.\n", __func__);
+ if (wait_event_interruptible(radio->read_queue,
+ radio->wr_index !=
+ radio->rd_index) < 0) {
+ r = -EINTR;
+ goto out;
+ }
+ }
+
+ /* calculate block count from byte count */
+ count /= RDS_BLOCK_SIZE;
+
+ /* copy RDS blocks from the internal buffer and to user buffer */
+ while (block_count < count) {
+ if (radio->rd_index == radio->wr_index)
+ break;
+
+ /* always transfer complete RDS blocks */
+ if (copy_to_user(buf, &radio->buffer[radio->rd_index],
+ RDS_BLOCK_SIZE))
+ break;
+
+ /* increment and wrap the read pointer */
+ radio->rd_index += RDS_BLOCK_SIZE;
+ if (radio->rd_index >= radio->buf_size)
+ radio->rd_index = 0;
+
+ /* increment counters */
+ block_count++;
+ buf += RDS_BLOCK_SIZE;
+ r += RDS_BLOCK_SIZE;
+ }
+
+out:
+ dev_dbg(radio->dev, "%s: exit\n", __func__);
+ mutex_unlock(&core->lock);
+
+ return r;
+}
+
+static const struct v4l2_file_operations wl1273_fops = {
+ .owner = THIS_MODULE,
+ .read = wl1273_fm_fops_read,
+ .write = wl1273_fm_fops_write,
+ .poll = wl1273_fm_fops_poll,
+ .ioctl = video_ioctl2,
+ .open = wl1273_fm_fops_open,
+ .release = wl1273_fm_fops_release,
+};
+
+static int wl1273_fm_vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *capability)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ strlcpy(capability->driver, WL1273_FM_DRIVER_NAME,
+ sizeof(capability->driver));
+ strlcpy(capability->card, "Texas Instruments Wl1273 FM Radio",
+ sizeof(capability->card));
+ strlcpy(capability->bus_info, radio->bus_type,
+ sizeof(capability->bus_info));
+
+ capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
+ V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_AUDIO |
+ V4L2_CAP_RDS_CAPTURE | V4L2_CAP_MODULATOR |
+ V4L2_CAP_RDS_OUTPUT;
+
+ return 0;
+}
+
+static int wl1273_fm_vidioc_g_input(struct file *file, void *priv,
+ unsigned int *i)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ *i = 0;
+
+ return 0;
+}
+
+static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
+ unsigned int i)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (i != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * wl1273_fm_set_tx_power() - Set the transmission power value.
+ * @core: A pointer to the device struct.
+ * @power: The new power value.
+ */
+static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
+{
+ int r;
+
+ if (radio->core->mode == WL1273_MODE_OFF ||
+ radio->core->mode == WL1273_MODE_SUSPENDED)
+ return -EPERM;
+
+ mutex_lock(&radio->core->lock);
+
+ /* Convert the dBuV value to chip presentation */
+ r = wl1273_fm_write_cmd(radio->core, WL1273_POWER_LEV_SET, 122 - power);
+ if (r)
+ goto out;
+
+ radio->tx_power = power;
+
+out:
+ mutex_unlock(&radio->core->lock);
+ return r;
+}
+
+#define WL1273_SPACING_50kHz 1
+#define WL1273_SPACING_100kHz 2
+#define WL1273_SPACING_200kHz 4
+
+static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
+ unsigned int spacing)
+{
+ int r;
+
+ if (spacing == 0) {
+ r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
+ WL1273_SPACING_100kHz);
+ radio->spacing = 100;
+ } else if (spacing - 50000 < 25000) {
+ r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
+ WL1273_SPACING_50kHz);
+ radio->spacing = 50;
+ } else if (spacing - 100000 < 50000) {
+ r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
+ WL1273_SPACING_100kHz);
+ radio->spacing = 100;
+ } else {
+ r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
+ WL1273_SPACING_200kHz);
+ radio->spacing = 200;
+ }
+
+ return r;
+}
+
+static int wl1273_fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct wl1273_device *radio = ctrl->priv;
+ struct wl1273_core *core = radio->core;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ switch (ctrl->id) {
+ case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+ ctrl->val = wl1273_fm_get_tx_ctune(radio);
+ break;
+
+ default:
+ dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",
+ __func__, ctrl->id);
+ break;
+ }
+
+ mutex_unlock(&core->lock);
+
+ return 0;
+}
+
+#define WL1273_MUTE_SOFT_ENABLE (1 << 0)
+#define WL1273_MUTE_AC (1 << 1)
+#define WL1273_MUTE_HARD_LEFT (1 << 2)
+#define WL1273_MUTE_HARD_RIGHT (1 << 3)
+#define WL1273_MUTE_SOFT_FORCE (1 << 4)
+
+static inline struct wl1273_device *to_radio(struct v4l2_ctrl *ctrl)
+{
+ return container_of(ctrl->handler, struct wl1273_device, ctrl_handler);
+}
+
+static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct wl1273_device *radio = to_radio(ctrl);
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ if (core->mode == WL1273_MODE_RX && ctrl->val)
+ r = wl1273_fm_write_cmd(core,
+ WL1273_MUTE_STATUS_SET,
+ WL1273_MUTE_HARD_LEFT |
+ WL1273_MUTE_HARD_RIGHT);
+ else if (core->mode == WL1273_MODE_RX)
+ r = wl1273_fm_write_cmd(core,
+ WL1273_MUTE_STATUS_SET, 0x0);
+ else if (core->mode == WL1273_MODE_TX && ctrl->val)
+ r = wl1273_fm_write_cmd(core, WL1273_MUTE, 1);
+ else if (core->mode == WL1273_MODE_TX)
+ r = wl1273_fm_write_cmd(core, WL1273_MUTE, 0);
+
+ mutex_unlock(&core->lock);
+ break;
+
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->val == 0)
+ r = wl1273_fm_set_mode(radio, WL1273_MODE_OFF);
+ else
+ r = core->set_volume(core, core->volume);
+ break;
+
+ case V4L2_CID_TUNE_PREEMPHASIS:
+ r = wl1273_fm_set_preemphasis(radio, ctrl->val);
+ break;
+
+ case V4L2_CID_TUNE_POWER_LEVEL:
+ r = wl1273_fm_set_tx_power(radio, ctrl->val);
+ break;
+
+ default:
+ dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",
+ __func__, ctrl->id);
+ break;
+ }
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+ return r;
+}
+
+static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (audio->index > 1)
+ return -EINVAL;
+
+ strlcpy(audio->name, "Radio", sizeof(audio->name));
+ audio->capability = V4L2_AUDCAP_STEREO;
+
+ return 0;
+}
+
+static int wl1273_fm_vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (audio->index != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define WL1273_RDS_NOT_SYNCHRONIZED 0
+#define WL1273_RDS_SYNCHRONIZED 1
+
+static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *tuner)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ u16 val;
+ int r;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (tuner->index > 0)
+ return -EINVAL;
+
+ strlcpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name));
+ tuner->type = V4L2_TUNER_RADIO;
+
+ tuner->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
+ tuner->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);
+
+ tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;
+
+ if (radio->stereo)
+ tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ tuner->audmode = V4L2_TUNER_MODE_MONO;
+
+ if (core->mode != WL1273_MODE_RX)
+ return 0;
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val);
+ if (r)
+ goto out;
+
+ if (val == 1)
+ tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
+ else
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+ r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val);
+ if (r)
+ goto out;
+
+ tuner->signal = (s16) val;
+ dev_dbg(radio->dev, "Signal: %d\n", tuner->signal);
+
+ tuner->afc = 0;
+
+ r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
+ if (r)
+ goto out;
+
+ if (val == WL1273_RDS_SYNCHRONIZED)
+ tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
+out:
+ mutex_unlock(&core->lock);
+
+ return r;
+}
+
+static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *tuner)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+ dev_dbg(radio->dev, "tuner->index: %d\n", tuner->index);
+ dev_dbg(radio->dev, "tuner->name: %s\n", tuner->name);
+ dev_dbg(radio->dev, "tuner->capability: 0x%04x\n", tuner->capability);
+ dev_dbg(radio->dev, "tuner->rxsubchans: 0x%04x\n", tuner->rxsubchans);
+ dev_dbg(radio->dev, "tuner->rangelow: %d\n", tuner->rangelow);
+ dev_dbg(radio->dev, "tuner->rangehigh: %d\n", tuner->rangehigh);
+
+ if (tuner->index > 0)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);
+ if (r)
+ goto out;
+
+ if (tuner->rxsubchans & V4L2_TUNER_SUB_RDS)
+ r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);
+ else
+ r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
+
+ if (r)
+ dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
+
+ if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
+ r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET,
+ WL1273_RX_MONO);
+ if (r < 0) {
+ dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
+ __func__, r);
+ goto out;
+ }
+ radio->stereo = false;
+ } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
+ r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET,
+ WL1273_RX_STEREO);
+ if (r < 0) {
+ dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
+ __func__, r);
+ goto out;
+ }
+ radio->stereo = true;
+ } else {
+ dev_err(radio->dev, "%s: tuner->audmode: %d\n",
+ __func__, tuner->audmode);
+ r = -EINVAL;
+ goto out;
+ }
+
+out:
+ mutex_unlock(&core->lock);
+
+ return r;
+}
+
+static int wl1273_fm_vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ freq->type = V4L2_TUNER_RADIO;
+ freq->frequency = WL1273_FREQ(wl1273_fm_get_freq(radio));
+
+ mutex_unlock(&core->lock);
+
+ return 0;
+}
+
+static int wl1273_fm_vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r;
+
+ dev_dbg(radio->dev, "%s: %d\n", __func__, freq->frequency);
+
+ if (freq->type != V4L2_TUNER_RADIO) {
+ dev_dbg(radio->dev,
+ "freq->type != V4L2_TUNER_RADIO: %d\n", freq->type);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ if (core->mode == WL1273_MODE_RX) {
+ dev_dbg(radio->dev, "freq: %d\n", freq->frequency);
+
+ r = wl1273_fm_set_rx_freq(radio,
+ WL1273_INV_FREQ(freq->frequency));
+ if (r)
+ dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
+ ": set frequency failed with %d\n", r);
+ } else {
+ r = wl1273_fm_set_tx_freq(radio,
+ WL1273_INV_FREQ(freq->frequency));
+ if (r)
+ dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
+ ": set frequency failed with %d\n", r);
+ }
+
+ mutex_unlock(&core->lock);
+
+ dev_dbg(radio->dev, "wl1273_vidioc_s_frequency: DONE\n");
+ return r;
+}
+
+#define WL1273_DEFAULT_SEEK_LEVEL 7
+
+static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv,
+ struct v4l2_hw_freq_seek *seek)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (seek->tuner != 0 || seek->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);
+ if (r)
+ goto out;
+
+ r = wl1273_fm_tx_set_spacing(radio, seek->spacing);
+ if (r)
+ dev_warn(radio->dev, "HW seek failed: %d\n", r);
+
+ r = wl1273_fm_set_seek(radio, seek->wrap_around, seek->seek_upward,
+ WL1273_DEFAULT_SEEK_LEVEL);
+ if (r)
+ dev_warn(radio->dev, "HW seek failed: %d\n", r);
+
+out:
+ mutex_unlock(&core->lock);
+ return r;
+}
+
+static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
+ struct v4l2_modulator *modulator)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ int r = 0;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ if (modulator->index > 0)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ r = wl1273_fm_set_mode(radio, WL1273_MODE_TX);
+ if (r)
+ goto out;
+
+ if (modulator->txsubchans & V4L2_TUNER_SUB_RDS)
+ r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);
+ else
+ r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
+
+ if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
+ r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, WL1273_TX_MONO);
+ else
+ r = wl1273_fm_write_cmd(core, WL1273_MONO_SET,
+ WL1273_RX_STEREO);
+ if (r < 0)
+ dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
+ "MONO_SET fails: %d\n", r);
+out:
+ mutex_unlock(&core->lock);
+
+ return r;
+}
+
+static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
+ struct v4l2_modulator *modulator)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ u16 val;
+ int r;
+
+ dev_dbg(radio->dev, "%s\n", __func__);
+
+ strlcpy(modulator->name, WL1273_FM_DRIVER_NAME,
+ sizeof(modulator->name));
+
+ modulator->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
+ modulator->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);
+
+ modulator->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;
+
+ if (core->mode != WL1273_MODE_TX)
+ return 0;
+
+ if (mutex_lock_interruptible(&core->lock))
+ return -EINTR;
+
+ r = wl1273_fm_read_reg(core, WL1273_MONO_SET, &val);
+ if (r)
+ goto out;
+
+ if (val == WL1273_TX_STEREO)
+ modulator->txsubchans = V4L2_TUNER_SUB_STEREO;
+ else
+ modulator->txsubchans = V4L2_TUNER_SUB_MONO;
+
+ if (radio->rds_on)
+ modulator->txsubchans |= V4L2_TUNER_SUB_RDS;
+out:
+ mutex_unlock(&core->lock);
+
+ return 0;
+}
+
+static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
+{
+ struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
+ struct wl1273_core *core = radio->core;
+ struct device *dev = radio->dev;
+ u16 val;
+ int r;
+
+ dev_info(dev, DRIVER_DESC);
+
+ if (core->mode == WL1273_MODE_OFF) {
+ dev_info(dev, "Mode: Off\n");
+ return 0;
+ }
+
+ if (core->mode == WL1273_MODE_SUSPENDED) {
+ dev_info(dev, "Mode: Suspended\n");
+ return 0;
+ }
+
+ r = wl1273_fm_read_reg(core, WL1273_ASIC_ID_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
+ else
+ dev_info(dev, "ASIC_ID: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_ASIC_VER_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
+ else
+ dev_info(dev, "ASIC Version: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_FIRM_VER_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
+ else
+ dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
+
+ r = wl1273_fm_read_reg(core, WL1273_BAND_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get BAND fails.\n", __func__);
+ else
+ dev_info(dev, "BAND: %d\n", val);
+
+ if (core->mode == WL1273_MODE_TX) {
+ r = wl1273_fm_read_reg(core, WL1273_PUPD_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get PUPD fails.\n", __func__);
+ else
+ dev_info(dev, "PUPD: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get CHANL fails.\n", __func__);
+ else
+ dev_info(dev, "Tx frequency: %dkHz\n", val*10);
+ } else if (core->mode == WL1273_MODE_RX) {
+ int bf = radio->rangelow;
+
+ r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get FREQ fails.\n", __func__);
+ else
+ dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
+
+ r = wl1273_fm_read_reg(core, WL1273_MOST_MODE_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get MOST_MODE fails.\n",
+ __func__);
+ else if (val == 0)
+ dev_info(dev, "MOST_MODE: Stereo according to blend\n");
+ else if (val == 1)
+ dev_info(dev, "MOST_MODE: Force mono output\n");
+ else
+ dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_MOST_BLEND_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
+ else if (val == 0)
+ dev_info(dev,
+ "MOST_BLEND: Switched blend & hysteresis.\n");
+ else if (val == 1)
+ dev_info(dev, "MOST_BLEND: Soft blend.\n");
+ else
+ dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get STEREO fails.\n", __func__);
+ else if (val == 0)
+ dev_info(dev, "STEREO: Not detected\n");
+ else if (val == 1)
+ dev_info(dev, "STEREO: Detected\n");
+ else
+ dev_info(dev, "STEREO: Unexpected value: %d\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
+ else
+ dev_info(dev, "RX signal strength: %d\n", (s16) val);
+
+ r = wl1273_fm_read_reg(core, WL1273_POWER_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get POWER fails.\n", __func__);
+ else
+ dev_info(dev, "POWER: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_INT_MASK_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
+ else
+ dev_info(dev, "INT_MASK: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
+ if (r)
+ dev_err(dev, "%s: Get RDS_SYNC fails.\n",
+ __func__);
+ else if (val == 0)
+ dev_info(dev, "RDS_SYNC: Not synchronized\n");
+
+ else if (val == 1)
+ dev_info(dev, "RDS_SYNC: Synchronized\n");
+ else
+ dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_I2S_MODE_CONFIG_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
+ __func__);
+ else
+ dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
+
+ r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
+ if (r)
+ dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
+ else
+ dev_info(dev, "VOLUME: 0x%04x\n", val);
+ }
+
+ return 0;
+}
+
+static void wl1273_vdev_release(struct video_device *dev)
+{
+}
+
+static const struct v4l2_ctrl_ops wl1273_ctrl_ops = {
+ .s_ctrl = wl1273_fm_vidioc_s_ctrl,
+ .g_volatile_ctrl = wl1273_fm_g_volatile_ctrl,
+};
+
+static const struct v4l2_ioctl_ops wl1273_ioctl_ops = {
+ .vidioc_querycap = wl1273_fm_vidioc_querycap,
+ .vidioc_g_input = wl1273_fm_vidioc_g_input,
+ .vidioc_s_input = wl1273_fm_vidioc_s_input,
+ .vidioc_g_audio = wl1273_fm_vidioc_g_audio,
+ .vidioc_s_audio = wl1273_fm_vidioc_s_audio,
+ .vidioc_g_tuner = wl1273_fm_vidioc_g_tuner,
+ .vidioc_s_tuner = wl1273_fm_vidioc_s_tuner,
+ .vidioc_g_frequency = wl1273_fm_vidioc_g_frequency,
+ .vidioc_s_frequency = wl1273_fm_vidioc_s_frequency,
+ .vidioc_s_hw_freq_seek = wl1273_fm_vidioc_s_hw_freq_seek,
+ .vidioc_g_modulator = wl1273_fm_vidioc_g_modulator,
+ .vidioc_s_modulator = wl1273_fm_vidioc_s_modulator,
+ .vidioc_log_status = wl1273_fm_vidioc_log_status,
+};
+
+static struct video_device wl1273_viddev_template = {
+ .fops = &wl1273_fops,
+ .ioctl_ops = &wl1273_ioctl_ops,
+ .name = WL1273_FM_DRIVER_NAME,
+ .release = wl1273_vdev_release,
+};
+
+static int wl1273_fm_radio_remove(struct platform_device *pdev)
+{
+ struct wl1273_device *radio = platform_get_drvdata(pdev);
+ struct wl1273_core *core = radio->core;
+
+ dev_info(&pdev->dev, "%s.\n", __func__);
+
+ free_irq(core->client->irq, radio);
+ core->pdata->free_resources();
+
+ v4l2_ctrl_handler_free(&radio->ctrl_handler);
+ video_unregister_device(&radio->videodev);
+ v4l2_device_unregister(&radio->v4l2dev);
+ kfree(radio->buffer);
+ kfree(radio->write_buf);
+ kfree(radio);
+
+ return 0;
+}
+
+static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
+{
+ struct wl1273_core **core = pdev->dev.platform_data;
+ struct wl1273_device *radio;
+ struct v4l2_ctrl *ctrl;
+ int r = 0;
+
+ pr_debug("%s\n", __func__);
+
+ if (!core) {
+ dev_err(&pdev->dev, "No platform data.\n");
+ r = -EINVAL;
+ goto pdata_err;
+ }
+
+ radio = kzalloc(sizeof(*radio), GFP_KERNEL);
+ if (!radio) {
+ r = -ENOMEM;
+ goto pdata_err;
+ }
+
+ /* RDS buffer allocation */
+ radio->buf_size = rds_buf * RDS_BLOCK_SIZE;
+ radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
+ if (!radio->buffer) {
+ pr_err("Cannot allocate memory for RDS buffer.\n");
+ r = -ENOMEM;
+ goto err_kmalloc;
+ }
+
+ radio->core = *core;
+ radio->irq_flags = WL1273_IRQ_MASK;
+ radio->dev = &radio->core->client->dev;
+ radio->rds_on = false;
+ radio->core->mode = WL1273_MODE_OFF;
+ radio->tx_power = 118;
+ radio->core->audio_mode = WL1273_AUDIO_ANALOG;
+ radio->band = WL1273_BAND_OTHER;
+ radio->core->i2s_mode = WL1273_I2S_DEF_MODE;
+ radio->core->channel_number = 2;
+ radio->core->volume = WL1273_DEFAULT_VOLUME;
+ radio->rx_frequency = WL1273_BAND_OTHER_LOW;
+ radio->tx_frequency = WL1273_BAND_OTHER_HIGH;
+ radio->rangelow = WL1273_BAND_OTHER_LOW;
+ radio->rangehigh = WL1273_BAND_OTHER_HIGH;
+ radio->stereo = true;
+ radio->bus_type = "I2C";
+
+ radio->core->write = wl1273_fm_write_cmd;
+ radio->core->set_audio = wl1273_fm_set_audio;
+ radio->core->set_volume = wl1273_fm_set_volume;
+
+ if (radio->core->pdata->request_resources) {
+ r = radio->core->pdata->request_resources(radio->core->client);
+ if (r) {
+ dev_err(radio->dev, WL1273_FM_DRIVER_NAME
+ ": Cannot get platform data\n");
+ goto err_resources;
+ }
+
+ dev_dbg(radio->dev, "irq: %d\n", radio->core->client->irq);
+
+ r = request_threaded_irq(radio->core->client->irq, NULL,
+ wl1273_fm_irq_thread_handler,
+ IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
+ "wl1273-fm", radio);
+ if (r < 0) {
+ dev_err(radio->dev, WL1273_FM_DRIVER_NAME
+ ": Unable to register IRQ handler: %d\n", r);
+ goto err_request_irq;
+ }
+ } else {
+ dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ"
+ " not configured");
+ r = -EINVAL;
+ goto err_resources;
+ }
+
+ init_completion(&radio->busy);
+ init_waitqueue_head(&radio->read_queue);
+
+ radio->write_buf = kmalloc(256, GFP_KERNEL);
+ if (!radio->write_buf) {
+ r = -ENOMEM;
+ goto write_buf_err;
+ }
+
+ radio->dev = &pdev->dev;
+ radio->v4l2dev.ctrl_handler = &radio->ctrl_handler;
+ radio->rds_users = 0;
+
+ r = v4l2_device_register(&pdev->dev, &radio->v4l2dev);
+ if (r) {
+ dev_err(&pdev->dev, "Cannot register v4l2_device.\n");
+ goto device_register_err;
+ }
+
+ /* V4L2 configuration */
+ memcpy(&radio->videodev, &wl1273_viddev_template,
+ sizeof(wl1273_viddev_template));
+
+ radio->videodev.v4l2_dev = &radio->v4l2dev;
+
+ v4l2_ctrl_handler_init(&radio->ctrl_handler, 6);
+
+ /* add in ascending ID order */
+ v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
+ V4L2_CID_AUDIO_VOLUME, 0, WL1273_MAX_VOLUME, 1,
+ WL1273_DEFAULT_VOLUME);
+
+ v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+
+ v4l2_ctrl_new_std_menu(&radio->ctrl_handler, &wl1273_ctrl_ops,
+ V4L2_CID_TUNE_PREEMPHASIS,
+ V4L2_PREEMPHASIS_75_uS, 0x03,
+ V4L2_PREEMPHASIS_50_uS);
+
+ v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
+ V4L2_CID_TUNE_POWER_LEVEL, 91, 122, 1, 118);
+
+ ctrl = v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
+ V4L2_CID_TUNE_ANTENNA_CAPACITOR,
+ 0, 255, 1, 255);
+ if (ctrl)
+ ctrl->is_volatile = 1;
+
+ if (radio->ctrl_handler.error) {
+ r = radio->ctrl_handler.error;
+ dev_err(&pdev->dev, "Ctrl handler error: %d\n", r);
+ goto handler_init_err;
+ }
+
+ video_set_drvdata(&radio->videodev, radio);
+ platform_set_drvdata(pdev, radio);
+
+ /* register video device */
+ r = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (r) {
+ dev_err(&pdev->dev, WL1273_FM_DRIVER_NAME
+ ": Could not register video device\n");
+ goto handler_init_err;
+ }
+
+ return 0;
+
+handler_init_err:
+ v4l2_ctrl_handler_free(&radio->ctrl_handler);
+ v4l2_device_unregister(&radio->v4l2dev);
+device_register_err:
+ kfree(radio->write_buf);
+write_buf_err:
+ free_irq(radio->core->client->irq, radio);
+err_request_irq:
+ radio->core->pdata->free_resources();
+err_resources:
+ kfree(radio->buffer);
+err_kmalloc:
+ kfree(radio);
+pdata_err:
+ return r;
+}
+
+MODULE_ALIAS("platform:wl1273_fm_radio");
+
+static struct platform_driver wl1273_fm_radio_driver = {
+ .probe = wl1273_fm_radio_probe,
+ .remove = __devexit_p(wl1273_fm_radio_remove),
+ .driver = {
+ .name = "wl1273_fm_radio",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init wl1273_fm_module_init(void)
+{
+ pr_info("%s\n", __func__);
+ return platform_driver_register(&wl1273_fm_radio_driver);
+}
+module_init(wl1273_fm_module_init);
+
+static void __exit wl1273_fm_module_exit(void)
+{
+ flush_scheduled_work();
+ platform_driver_unregister(&wl1273_fm_radio_driver);
+ pr_info(DRIVER_DESC ", Exiting.\n");
+}
+module_exit(wl1273_fm_module_exit);
+
+MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index f31eab99c943..af99c5bd88c1 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
@@ -424,20 +424,6 @@ static int __init zoltrix_init(void)
return res;
}
- strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
- zol->vdev.v4l2_dev = v4l2_dev;
- zol->vdev.fops = &zoltrix_fops;
- zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
- zol->vdev.release = video_device_release_empty;
- video_set_drvdata(&zol->vdev, zol);
-
- if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(zol->io, 2);
- return -EINVAL;
- }
- v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
-
mutex_init(&zol->lock);
/* mute card - prevents noisy bootups */
@@ -452,6 +438,20 @@ static int __init zoltrix_init(void)
zol->curvol = 0;
zol->stereo = 1;
+ strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+ zol->vdev.v4l2_dev = v4l2_dev;
+ zol->vdev.fops = &zoltrix_fops;
+ zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+ zol->vdev.release = video_device_release_empty;
+ video_set_drvdata(&zol->vdev, zol);
+
+ if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(zol->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
+
return 0;
}
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index b9914d7a0c9f..4a4e908db04c 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -37,7 +37,6 @@
#include <linux/mutex.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <media/rds.h>
#include <asm/unaligned.h>
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index a6e6f1987a3a..0fab6f8f7e24 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -27,6 +27,8 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
@@ -43,6 +45,11 @@ MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
MODULE_VERSION("0.0.1");
+static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
+ "vio",
+ "vdd",
+};
+
#define DEFAULT_RDS_PI 0x00
#define DEFAULT_RDS_PTY 0x00
#define DEFAULT_RDS_PS_NAME ""
@@ -369,7 +376,17 @@ static int si4713_powerup(struct si4713_device *sdev)
if (sdev->power_state)
return 0;
- sdev->platform_data->set_power(1);
+ err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err) {
+ v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
+ return err;
+ }
+ if (gpio_is_valid(sdev->gpio_reset)) {
+ udelay(50);
+ gpio_set_value(sdev->gpio_reset, 1);
+ }
+
err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
args, ARRAY_SIZE(args),
resp, ARRAY_SIZE(resp),
@@ -384,7 +401,13 @@ static int si4713_powerup(struct si4713_device *sdev)
err = si4713_write_property(sdev, SI4713_GPO_IEN,
SI4713_STC_INT | SI4713_CTS);
} else {
- sdev->platform_data->set_power(0);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_set_value(sdev->gpio_reset, 0);
+ err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err)
+ v4l2_err(&sdev->sd,
+ "Failed to disable supplies: %d\n", err);
}
return err;
@@ -411,7 +434,13 @@ static int si4713_powerdown(struct si4713_device *sdev)
v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
resp[0]);
v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
- sdev->platform_data->set_power(0);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_set_value(sdev->gpio_reset, 0);
+ err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err)
+ v4l2_err(&sdev->sd,
+ "Failed to disable supplies: %d\n", err);
sdev->power_state = POWER_OFF;
}
@@ -1967,7 +1996,8 @@ static int si4713_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct si4713_device *sdev;
- int rval;
+ struct si4713_platform_data *pdata = client->dev.platform_data;
+ int rval, i;
sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
if (!sdev) {
@@ -1976,11 +2006,26 @@ static int si4713_probe(struct i2c_client *client,
goto exit;
}
- sdev->platform_data = client->dev.platform_data;
- if (!sdev->platform_data) {
- v4l2_err(&sdev->sd, "No platform data registered.\n");
- rval = -ENODEV;
- goto free_sdev;
+ sdev->gpio_reset = -1;
+ if (pdata && gpio_is_valid(pdata->gpio_reset)) {
+ rval = gpio_request(pdata->gpio_reset, "si4713 reset");
+ if (rval) {
+ dev_err(&client->dev,
+ "Failed to request gpio: %d\n", rval);
+ goto free_sdev;
+ }
+ sdev->gpio_reset = pdata->gpio_reset;
+ gpio_direction_output(sdev->gpio_reset, 0);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++)
+ sdev->supplies[i].supply = si4713_supply_names[i];
+
+ rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (rval) {
+ dev_err(&client->dev, "Cannot get regulators: %d\n", rval);
+ goto free_gpio;
}
v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
@@ -1994,7 +2039,7 @@ static int si4713_probe(struct i2c_client *client,
client->name, sdev);
if (rval < 0) {
v4l2_err(&sdev->sd, "Could not request IRQ\n");
- goto free_sdev;
+ goto put_reg;
}
v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
} else {
@@ -2012,6 +2057,11 @@ static int si4713_probe(struct i2c_client *client,
free_irq:
if (client->irq)
free_irq(client->irq, sdev);
+put_reg:
+ regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
+free_gpio:
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_free(sdev->gpio_reset);
free_sdev:
kfree(sdev);
exit:
@@ -2031,7 +2081,9 @@ static int si4713_remove(struct i2c_client *client)
free_irq(client->irq, sdev);
v4l2_device_unregister_subdev(sd);
-
+ regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_free(sdev->gpio_reset);
kfree(sdev);
return 0;
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h
index faf8cff124f1..c6dfa7fb101c 100644
--- a/drivers/media/radio/si4713-i2c.h
+++ b/drivers/media/radio/si4713-i2c.h
@@ -211,6 +211,8 @@ struct acomp_info {
u32 enabled;
};
+#define SI4713_NUM_SUPPLIES 2
+
/*
* si4713_device - private data
*/
@@ -220,11 +222,12 @@ struct si4713_device {
/* private data structures */
struct mutex mutex;
struct completion work;
- struct si4713_platform_data *platform_data;
struct rds_info rds_info;
struct limiter_info limiter_info;
struct pilot_info pilot_info;
struct acomp_info acomp_info;
+ struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES];
+ int gpio_reset;
u32 frequency;
u32 preemphasis;
u32 mute;
diff --git a/drivers/media/IR/Kconfig b/drivers/media/rc/Kconfig
index aa4163eb7a83..3785162f928e 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -1,21 +1,17 @@
-menuconfig IR_CORE
- tristate "Infrared remote controller adapters"
+menuconfig RC_CORE
+ tristate "Remote Controller adapters"
depends on INPUT
default INPUT
---help---
Enable support for Remote Controllers on Linux. This is
needed in order to support several video capture adapters.
+ Currently, all supported devices use InfraRed.
Enable this option if you have a video capture board even
if you don't need IR, as otherwise, you may not be able to
compile the driver for your adapter.
-config VIDEO_IR
- tristate
- depends on IR_CORE
- default IR_CORE
-
-if IR_CORE
+if RC_CORE
config LIRC
tristate
@@ -28,11 +24,11 @@ config LIRC
LIRC daemon handles protocol decoding for IR reception and
encoding for IR transmitting (aka "blasting").
-source "drivers/media/IR/keymaps/Kconfig"
+source "drivers/media/rc/keymaps/Kconfig"
config IR_NEC_DECODER
tristate "Enable IR raw decoder for the NEC protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -42,7 +38,7 @@ config IR_NEC_DECODER
config IR_RC5_DECODER
tristate "Enable IR raw decoder for the RC-5 protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -52,7 +48,7 @@ config IR_RC5_DECODER
config IR_RC6_DECODER
tristate "Enable IR raw decoder for the RC6 protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -62,7 +58,7 @@ config IR_RC6_DECODER
config IR_JVC_DECODER
tristate "Enable IR raw decoder for the JVC protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -72,7 +68,7 @@ config IR_JVC_DECODER
config IR_SONY_DECODER
tristate "Enable IR raw decoder for the Sony protocol"
- depends on IR_CORE
+ depends on RC_CORE
default y
---help---
@@ -81,7 +77,7 @@ config IR_SONY_DECODER
config IR_RC5_SZ_DECODER
tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -93,7 +89,7 @@ config IR_RC5_SZ_DECODER
config IR_LIRC_CODEC
tristate "Enable IR to LIRC bridge"
- depends on IR_CORE
+ depends on RC_CORE
depends on LIRC
default y
@@ -104,7 +100,7 @@ config IR_LIRC_CODEC
config IR_ENE
tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)"
depends on PNP
- depends on IR_CORE
+ depends on RC_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transceiver made by ENE.
@@ -118,7 +114,7 @@ config IR_ENE
config IR_IMON
tristate "SoundGraph iMON Receiver and Display"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
@@ -130,7 +126,7 @@ config IR_IMON
config IR_MCEUSB
tristate "Windows Media Center Ed. eHome Infrared Transceiver"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a Windows Media Center Edition
@@ -142,7 +138,7 @@ config IR_MCEUSB
config IR_NUVOTON
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
depends on PNP
- depends on IR_CORE
+ depends on RC_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transciever made by Nuvoton (formerly Winbond). This chip is
@@ -155,7 +151,7 @@ config IR_NUVOTON
config IR_STREAMZAP
tristate "Streamzap PC Remote IR Receiver"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a Streamzap PC Remote
@@ -164,4 +160,34 @@ config IR_STREAMZAP
To compile this driver as a module, choose M here: the
module will be called streamzap.
-endif #IR_CORE
+config IR_WINBOND_CIR
+ tristate "Winbond IR remote control"
+ depends on X86 && PNP
+ depends on RC_CORE
+ select NEW_LEDS
+ select LEDS_CLASS
+ select LEDS_TRIGGERS
+ select BITREVERSE
+ ---help---
+ Say Y here if you want to use the IR remote functionality found
+ in some Winbond SuperI/O chips. Currently only the WPCD376I
+ chip is supported (included in some Intel Media series
+ motherboards).
+
+ To compile this driver as a module, choose M here: the module will
+ be called winbond_cir.
+
+config RC_LOOPBACK
+ tristate "Remote Control Loopback Driver"
+ depends on RC_CORE
+ ---help---
+ Say Y here if you want support for the remote control loopback
+ driver which allows TX data to be sent back as RX data.
+ This is mostly useful for debugging purposes.
+
+ If you're not sure, select N here.
+
+ To compile this driver as a module, choose M here: the module will
+ be called rc_loopback.
+
+endif #RC_CORE
diff --git a/drivers/media/IR/Makefile b/drivers/media/rc/Makefile
index f9574adab82a..67b4f7fe2577 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,10 +1,8 @@
-ir-common-objs := ir-functions.o
-ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o
+rc-core-objs := rc-main.o ir-raw.o
obj-y += keymaps/
-obj-$(CONFIG_IR_CORE) += ir-core.o
-obj-$(CONFIG_VIDEO_IR) += ir-common.o
+obj-$(CONFIG_RC_CORE) += rc-core.o
obj-$(CONFIG_LIRC) += lirc_dev.o
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
@@ -20,3 +18,5 @@ obj-$(CONFIG_IR_MCEUSB) += mceusb.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_ENE) += ene_ir.o
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
+obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
+obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/rc/ene_ir.c
index 7637babcd262..80b3c319f698 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -37,9 +37,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include "ene_ir.h"
static int sample_period;
@@ -357,7 +355,7 @@ void ene_rx_sense_carrier(struct ene_device *dev)
ev.carrier_report = true;
ev.carrier = carrier;
ev.duty_cycle = duty_cycle;
- ir_raw_event_store(dev->idev, &ev);
+ ir_raw_event_store(dev->rdev, &ev);
}
}
@@ -448,32 +446,32 @@ static void ene_rx_setup(struct ene_device *dev)
select_timeout:
if (dev->rx_fan_input_inuse) {
- dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
+ dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
/* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */
- dev->props->min_timeout = dev->props->max_timeout =
+ dev->rdev->min_timeout = dev->rdev->max_timeout =
MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
ENE_FW_SAMPLE_PERIOD_FAN);
} else {
- dev->props->rx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->rx_resolution = MS_TO_NS(sample_period);
/* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it
* would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32.
*/
- dev->props->min_timeout = MS_TO_NS(127 * sample_period);
- dev->props->max_timeout = MS_TO_NS(200000);
+ dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
+ dev->rdev->max_timeout = MS_TO_NS(200000);
}
if (dev->hw_learning_and_tx_capable)
- dev->props->tx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->tx_resolution = MS_TO_NS(sample_period);
- if (dev->props->timeout > dev->props->max_timeout)
- dev->props->timeout = dev->props->max_timeout;
- if (dev->props->timeout < dev->props->min_timeout)
- dev->props->timeout = dev->props->min_timeout;
+ if (dev->rdev->timeout > dev->rdev->max_timeout)
+ dev->rdev->timeout = dev->rdev->max_timeout;
+ if (dev->rdev->timeout < dev->rdev->min_timeout)
+ dev->rdev->timeout = dev->rdev->min_timeout;
}
/* Enable the device for receive */
@@ -504,7 +502,7 @@ static void ene_rx_enable(struct ene_device *dev)
ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
/* enter idle mode */
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = true;
}
@@ -518,7 +516,7 @@ static void ene_rx_disable(struct ene_device *dev)
/* disable hardware IRQ and firmware flag */
ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = false;
}
@@ -805,10 +803,10 @@ static irqreturn_t ene_isr(int irq, void *data)
ev.duration = MS_TO_NS(hw_sample);
ev.pulse = pulse;
- ir_raw_event_store_with_filter(dev->idev, &ev);
+ ir_raw_event_store_with_filter(dev->rdev, &ev);
}
- ir_raw_event_handle(dev->idev);
+ ir_raw_event_handle(dev->rdev);
unlock:
spin_unlock_irqrestore(&dev->hw_lock, flags);
return retval;
@@ -823,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev)
dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
- dev->props->timeout = MS_TO_NS(150000);
+ dev->rdev->timeout = MS_TO_NS(150000);
}
/* Upload all hardware settings at once. Used at load and resume time */
@@ -838,9 +836,9 @@ static void ene_setup_hw_settings(struct ene_device *dev)
}
/* outside interface: called on first open*/
-static int ene_open(void *data)
+static int ene_open(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
@@ -850,9 +848,9 @@ static int ene_open(void *data)
}
/* outside interface: called on device close*/
-static void ene_close(void *data)
+static void ene_close(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
@@ -861,9 +859,9 @@ static void ene_close(void *data)
}
/* outside interface: set transmitter mask */
-static int ene_set_tx_mask(void *data, u32 tx_mask)
+static int ene_set_tx_mask(struct rc_dev *rdev, u32 tx_mask)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: attempt to set transmitter mask %02x", tx_mask);
/* invalid txmask */
@@ -879,9 +877,9 @@ static int ene_set_tx_mask(void *data, u32 tx_mask)
}
/* outside interface : set tx carrier */
-static int ene_set_tx_carrier(void *data, u32 carrier)
+static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
u32 period = 2000000 / carrier;
dbg("TX: attempt to set tx carrier to %d kHz", carrier);
@@ -900,9 +898,9 @@ static int ene_set_tx_carrier(void *data, u32 carrier)
}
/*outside interface : set tx duty cycle */
-static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
+static int ene_set_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: setting duty cycle to %d%%", duty_cycle);
dev->tx_duty_cycle = duty_cycle;
ene_tx_set_carrier(dev);
@@ -910,9 +908,9 @@ static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
}
/* outside interface: enable learning mode */
-static int ene_set_learning_mode(void *data, int enable)
+static int ene_set_learning_mode(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->learning_mode_enabled)
return 0;
@@ -926,9 +924,9 @@ static int ene_set_learning_mode(void *data, int enable)
return 0;
}
-static int ene_set_carrier_report(void *data, int enable)
+static int ene_set_carrier_report(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->carrier_detect_enabled)
@@ -944,18 +942,20 @@ static int ene_set_carrier_report(void *data, int enable)
}
/* outside interface: enable or disable idle mode */
-static void ene_set_idle(void *data, bool idle)
+static void ene_set_idle(struct rc_dev *rdev, bool idle)
{
+ struct ene_device *dev = rdev->priv;
+
if (idle) {
- ene_rx_reset((struct ene_device *)data);
+ ene_rx_reset(dev);
dbg("RX: end of data");
}
}
/* outside interface: transmit */
-static int ene_transmit(void *data, int *buf, u32 n)
+static int ene_transmit(struct rc_dev *rdev, int *buf, u32 n)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
dev->tx_buffer = buf;
@@ -992,16 +992,13 @@ static int ene_transmit(void *data, int *buf, u32 n)
static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
{
int error = -ENOMEM;
- struct ir_dev_props *ir_props;
- struct input_dev *input_dev;
+ struct rc_dev *rdev;
struct ene_device *dev;
/* allocate memory */
- input_dev = input_allocate_device();
- ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-
- if (!input_dev || !ir_props || !dev)
+ rdev = rc_allocate_device();
+ if (!dev || !rdev)
goto error1;
/* validate resources */
@@ -1054,24 +1051,25 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (!dev->hw_learning_and_tx_capable)
learning_mode_force = false;
- ir_props->driver_type = RC_DRIVER_IR_RAW;
- ir_props->allowed_protos = IR_TYPE_ALL;
- ir_props->priv = dev;
- ir_props->open = ene_open;
- ir_props->close = ene_close;
- ir_props->s_idle = ene_set_idle;
-
- dev->props = ir_props;
- dev->idev = input_dev;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->priv = dev;
+ rdev->open = ene_open;
+ rdev->close = ene_close;
+ rdev->s_idle = ene_set_idle;
+ rdev->driver_name = ENE_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
+ rdev->input_name = "ENE eHome Infrared Remote Receiver";
if (dev->hw_learning_and_tx_capable) {
- ir_props->s_learning_mode = ene_set_learning_mode;
+ rdev->s_learning_mode = ene_set_learning_mode;
init_completion(&dev->tx_complete);
- ir_props->tx_ir = ene_transmit;
- ir_props->s_tx_mask = ene_set_tx_mask;
- ir_props->s_tx_carrier = ene_set_tx_carrier;
- ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
- ir_props->s_carrier_report = ene_set_carrier_report;
+ rdev->tx_ir = ene_transmit;
+ rdev->s_tx_mask = ene_set_tx_mask;
+ rdev->s_tx_carrier = ene_set_tx_carrier;
+ rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle;
+ rdev->s_carrier_report = ene_set_carrier_report;
+ rdev->input_name = "ENE eHome Infrared Remote Transceiver";
}
ene_rx_setup_hw_buffer(dev);
@@ -1081,16 +1079,11 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
device_set_wakeup_capable(&pnp_dev->dev, true);
device_set_wakeup_enable(&pnp_dev->dev, true);
- if (dev->hw_learning_and_tx_capable)
- input_dev->name = "ENE eHome Infrared Remote Transceiver";
- else
- input_dev->name = "ENE eHome Infrared Remote Receiver";
-
- error = -ENODEV;
- if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
- ENE_DRIVER_NAME))
+ error = rc_register_device(rdev);
+ if (error < 0)
goto error;
+ dev->rdev = rdev;
ene_notice("driver has been succesfully loaded");
return 0;
error:
@@ -1099,8 +1092,7 @@ error:
if (dev && dev->hw_io >= 0)
release_region(dev->hw_io, ENE_IO_SIZE);
error1:
- input_free_device(input_dev);
- kfree(ir_props);
+ rc_free_device(rdev);
kfree(dev);
return error;
}
@@ -1118,8 +1110,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
free_irq(dev->irq, dev);
release_region(dev->hw_io, ENE_IO_SIZE);
- ir_input_unregister(dev->idev);
- kfree(dev->props);
+ rc_unregister_device(dev->rdev);
kfree(dev);
}
diff --git a/drivers/media/IR/ene_ir.h b/drivers/media/rc/ene_ir.h
index f5870667a433..c179baf34cb4 100644
--- a/drivers/media/IR/ene_ir.h
+++ b/drivers/media/rc/ene_ir.h
@@ -205,8 +205,7 @@
struct ene_device {
struct pnp_dev *pnp_dev;
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* hw IO settings */
long hw_io;
diff --git a/drivers/media/IR/imon.c b/drivers/media/rc/imon.c
index bc118066bc38..6811512b4e83 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/rc/imon.c
@@ -38,7 +38,7 @@
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/time.h>
#include <linux/timer.h>
@@ -88,7 +88,6 @@ static ssize_t lcd_write(struct file *file, const char *buf,
struct imon_context {
struct device *dev;
- struct ir_dev_props *props;
/* Newer devices have two interfaces */
struct usb_device *usbdev_intf0;
struct usb_device *usbdev_intf1;
@@ -123,7 +122,7 @@ struct imon_context {
u16 vendor; /* usb vendor ID */
u16 product; /* usb product ID */
- struct input_dev *rdev; /* input device for remote */
+ struct rc_dev *rdev; /* rc-core device for remote */
struct input_dev *idev; /* input device for panel & IR mouse */
struct input_dev *touch; /* input device for touchscreen */
@@ -132,7 +131,7 @@ struct imon_context {
u32 last_keycode; /* last reported input keycode */
u32 rc_scancode; /* the computed remote scancode */
u8 rc_toggle; /* the computed remote toggle bit */
- u64 ir_type; /* iMON or MCE (RC6) IR protocol? */
+ u64 rc_type; /* iMON or MCE (RC6) IR protocol? */
bool release_code; /* some keys send a release code */
u8 display_type; /* store the display type */
@@ -984,27 +983,27 @@ static void imon_touch_display_timeout(unsigned long data)
* really just RC-6), but only one or the other at a time, as the signals
* are decoded onboard the receiver.
*/
-int imon_ir_change_protocol(void *priv, u64 ir_type)
+static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
int retval;
- struct imon_context *ictx = priv;
+ struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
bool pad_mouse;
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
- if (ir_type && !(ir_type & ictx->props->allowed_protos))
+ if (rc_type && !(rc_type & rc->allowed_protos))
dev_warn(dev, "Looks like you're trying to use an IR protocol "
"this device does not support\n");
- switch (ir_type) {
- case IR_TYPE_RC6:
+ switch (rc_type) {
+ case RC_TYPE_RC6:
dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
ir_proto_packet[0] = 0x01;
pad_mouse = false;
break;
- case IR_TYPE_UNKNOWN:
- case IR_TYPE_OTHER:
+ case RC_TYPE_UNKNOWN:
+ case RC_TYPE_OTHER:
dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
if (pad_stabilize && !nomouse)
pad_mouse = true;
@@ -1013,7 +1012,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
break;
default:
dev_warn(dev, "Unsupported IR protocol specified, overriding "
@@ -1025,7 +1024,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
break;
}
@@ -1035,7 +1034,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
if (retval)
goto out;
- ictx->ir_type = ir_type;
+ ictx->rc_type = rc_type;
ictx->pad_mouse = pad_mouse;
out:
@@ -1147,14 +1146,14 @@ static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode)
bool is_release_code = false;
/* Look for the initial press of a button */
- keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
+ keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
ictx->rc_toggle = 0x0;
ictx->rc_scancode = scancode;
/* Look for the release of a button */
if (keycode == KEY_RESERVED) {
release = scancode & ~0x4000;
- keycode = ir_g_keycode_from_table(ictx->rdev, release);
+ keycode = rc_g_keycode_from_table(ictx->rdev, release);
if (keycode != KEY_RESERVED)
is_release_code = true;
}
@@ -1183,7 +1182,7 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
ictx->rc_scancode = scancode;
- keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
+ keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
/* not used in mce mode, but make sure we know its false */
ictx->release_code = false;
@@ -1307,7 +1306,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
rel_x = buf[2];
rel_y = buf[3];
- if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
+ if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
dir = stabilize((int)rel_x, (int)rel_y,
timeout, threshold);
@@ -1374,7 +1373,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
buf[0] = 0x01;
buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
- if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
+ if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
dir = stabilize((int)rel_x, (int)rel_y,
timeout, threshold);
if (!dir) {
@@ -1479,17 +1478,12 @@ static void imon_incoming_packet(struct imon_context *ictx,
bool norelease = false;
int i;
u64 scancode;
- struct input_dev *rdev = NULL;
- struct ir_input_dev *irdev = NULL;
int press_type = 0;
int msec;
struct timeval t;
static struct timeval prev_time = { 0, 0 };
u8 ktype;
- rdev = ictx->rdev;
- irdev = input_get_drvdata(rdev);
-
/* filter out junk data on the older 0xffdc imon devices */
if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
return;
@@ -1501,7 +1495,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
kc = imon_panel_key_lookup(scancode);
} else {
scancode = be32_to_cpu(*((u32 *)buf));
- if (ictx->ir_type == IR_TYPE_RC6) {
+ if (ictx->rc_type == RC_TYPE_RC6) {
ktype = IMON_KEY_IMON;
if (buf[0] == 0x80)
ktype = IMON_KEY_MCE;
@@ -1570,9 +1564,9 @@ static void imon_incoming_packet(struct imon_context *ictx,
if (ktype != IMON_KEY_PANEL) {
if (press_type == 0)
- ir_keyup(irdev);
+ rc_keyup(ictx->rdev);
else {
- ir_keydown(rdev, ictx->rc_scancode, ictx->rc_toggle);
+ rc_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle);
spin_lock_irqsave(&ictx->kc_lock, flags);
ictx->last_keycode = ictx->kc;
spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1715,7 +1709,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
{
u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
- u64 allowed_protos = IR_TYPE_OTHER;
+ u64 allowed_protos = RC_TYPE_OTHER;
switch (ffdc_cfg_byte) {
/* iMON Knob, no display, iMON IR + vol knob */
@@ -1744,13 +1738,13 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
case 0x9e:
dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
- allowed_protos = IR_TYPE_RC6;
+ allowed_protos = RC_TYPE_RC6;
break;
/* iMON LCD, MCE IR */
case 0x9f:
dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
detected_display_type = IMON_DISPLAY_TYPE_LCD;
- allowed_protos = IR_TYPE_RC6;
+ allowed_protos = RC_TYPE_RC6;
break;
default:
dev_info(ictx->dev, "Unknown 0xffdc device, "
@@ -1762,8 +1756,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
ictx->display_type = detected_display_type;
- ictx->props->allowed_protos = allowed_protos;
- ictx->ir_type = allowed_protos;
+ ictx->rdev->allowed_protos = allowed_protos;
+ ictx->rc_type = allowed_protos;
}
static void imon_set_display_type(struct imon_context *ictx)
@@ -1816,18 +1810,15 @@ static void imon_set_display_type(struct imon_context *ictx)
ictx->display_type = configured_display_type;
}
-static struct input_dev *imon_init_rdev(struct imon_context *ictx)
+static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
{
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
int ret;
- char *ir_codes = NULL;
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88 };
- rdev = input_allocate_device();
- props = kzalloc(sizeof(*props), GFP_KERNEL);
- if (!rdev || !props) {
+ rdev = rc_allocate_device();
+ if (!rdev) {
dev_err(ictx->dev, "remote control dev allocation failed\n");
goto out;
}
@@ -1838,18 +1829,20 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
sizeof(ictx->phys_rdev));
strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));
- rdev->name = ictx->name_rdev;
- rdev->phys = ictx->phys_rdev;
- usb_to_input_id(ictx->usbdev_intf0, &rdev->id);
+ rdev->input_name = ictx->name_rdev;
+ rdev->input_phys = ictx->phys_rdev;
+ usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id);
rdev->dev.parent = ictx->dev;
- rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- input_set_drvdata(rdev, ictx);
- props->priv = ictx;
- props->driver_type = RC_DRIVER_SCANCODE;
- props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
- props->change_protocol = imon_ir_change_protocol;
- ictx->props = props;
+ rdev->priv = ictx;
+ rdev->driver_type = RC_DRIVER_SCANCODE;
+ rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
+ rdev->change_protocol = imon_ir_change_protocol;
+ rdev->driver_name = MOD_NAME;
+ if (ictx->rc_type == RC_TYPE_RC6)
+ rdev->map_name = RC_MAP_IMON_MCE;
+ else
+ rdev->map_name = RC_MAP_IMON_PAD;
/* Enable front-panel buttons and/or knobs */
memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
@@ -1863,12 +1856,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
imon_set_display_type(ictx);
- if (ictx->ir_type == IR_TYPE_RC6)
- ir_codes = RC_MAP_IMON_MCE;
- else
- ir_codes = RC_MAP_IMON_PAD;
-
- ret = ir_input_register(rdev, ir_codes, props, MOD_NAME);
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(ictx->dev, "remote input dev register failed\n");
goto out;
@@ -1877,8 +1865,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
return rdev;
out:
- kfree(props);
- input_free_device(rdev);
+ rc_free_device(rdev);
return NULL;
}
@@ -2149,7 +2136,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
return ictx;
urb_submit_failed:
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
rdev_setup_failed:
input_unregister_device(ictx->idev);
idev_setup_failed:
@@ -2287,7 +2274,7 @@ static int __devinit imon_probe(struct usb_interface *interface,
mutex_lock(&driver_lock);
first_if = usb_ifnum_to_if(usbdev, 0);
- first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if);
+ first_if_ctx = usb_get_intfdata(first_if);
if (ifnum == 0) {
ictx = imon_init_intf0(interface);
@@ -2376,7 +2363,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
input_unregister_device(ictx->idev);
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
if (ictx->display_supported) {
if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
usb_deregister_dev(interface, &imon_lcd_class);
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 63dca6e5458b..624449afaa61 100644
--- a/drivers/media/IR/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define JVC_NBITS 16 /* dev(8) + func(8) */
#define JVC_UNIT 525000 /* ns */
@@ -37,17 +37,16 @@ enum jvc_state {
/**
* ir_jvc_decode() - Decode one JVC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct jvc_dec *data = &ir_dev->raw->jvc;
+ struct jvc_dec *data = &dev->raw->jvc;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_JVC))
return 0;
if (!is_timing_event(ev)) {
@@ -140,12 +139,12 @@ again:
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
- ir_keydown(input_dev, scancode, data->toggle);
+ rc_keydown(dev, scancode, data->toggle);
data->first = false;
data->old_bits = data->bits;
} else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n");
- ir_repeat(input_dev);
+ rc_repeat(dev);
} else {
IR_dprintk(1, "JVC invalid repeat msg\n");
break;
@@ -174,7 +173,7 @@ out:
}
static struct ir_raw_handler jvc_handler = {
- .protocols = IR_TYPE_JVC,
+ .protocols = RC_TYPE_JVC,
.decode = ir_jvc_decode,
};
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 9fc0db9d344d..f011c5d9dea1 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -16,29 +16,28 @@
#include <linux/wait.h>
#include <media/lirc.h>
#include <media/lirc_dev.h>
-#include <media/ir-core.h>
-#include "ir-core-priv.h"
+#include <media/rc-core.h>
+#include "rc-core-priv.h"
#define LIRCBUF_SIZE 256
/**
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
* lircd userspace daemon for decoding.
- * @input_dev: the struct input_dev descriptor of the device
+ * @input_dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the lirc interfaces aren't wired up.
*/
-static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
int sample;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_LIRC))
return 0;
- if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
+ if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
return -EINVAL;
/* Packet start */
@@ -79,7 +78,7 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
(u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration);
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &gap_sample);
lirc->gap = false;
}
@@ -88,9 +87,9 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
LIRC_SPACE(ev.duration / 1000);
}
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &sample);
- wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
+ wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
return 0;
}
@@ -99,9 +98,10 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
size_t n, loff_t *ppos)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int *txbuf; /* buffer with values to transmit */
- int ret = 0, count;
+ int ret = 0;
+ size_t count;
lirc = lirc_get_pdata(file);
if (!lirc)
@@ -111,21 +111,21 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
return -EINVAL;
count = n / sizeof(int);
- if (count > LIRCBUF_SIZE || count % 2 == 0)
+ if (count > LIRCBUF_SIZE || count % 2 == 0 || n % sizeof(int) != 0)
return -EINVAL;
txbuf = memdup_user(buf, n);
if (IS_ERR(txbuf))
return PTR_ERR(txbuf);
- ir_dev = lirc->ir_dev;
- if (!ir_dev) {
+ dev = lirc->dev;
+ if (!dev) {
ret = -EFAULT;
goto out;
}
- if (ir_dev->props && ir_dev->props->tx_ir)
- ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
+ if (dev->tx_ir)
+ ret = dev->tx_ir(dev, txbuf, (u32)n);
out:
kfree(txbuf);
@@ -136,21 +136,18 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
unsigned long __user arg)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int ret = 0;
- void *drv_data;
__u32 val = 0, tmp;
lirc = lirc_get_pdata(filep);
if (!lirc)
return -EFAULT;
- ir_dev = lirc->ir_dev;
- if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
+ dev = lirc->dev;
+ if (!dev)
return -EFAULT;
- drv_data = ir_dev->props->priv;
-
if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = get_user(val, (__u32 *)arg);
if (ret)
@@ -171,84 +168,85 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
- if (!ir_dev->props->s_tx_mask)
+ if (!dev->s_tx_mask)
return -EINVAL;
- return ir_dev->props->s_tx_mask(drv_data, val);
+ return dev->s_tx_mask(dev, val);
case LIRC_SET_SEND_CARRIER:
- if (!ir_dev->props->s_tx_carrier)
+ if (!dev->s_tx_carrier)
return -EINVAL;
- return ir_dev->props->s_tx_carrier(drv_data, val);
+ return dev->s_tx_carrier(dev, val);
case LIRC_SET_SEND_DUTY_CYCLE:
- if (!ir_dev->props->s_tx_duty_cycle)
+ if (!dev->s_tx_duty_cycle)
return -ENOSYS;
if (val <= 0 || val >= 100)
return -EINVAL;
- return ir_dev->props->s_tx_duty_cycle(drv_data, val);
+ return dev->s_tx_duty_cycle(dev, val);
/* RX settings */
case LIRC_SET_REC_CARRIER:
- if (!ir_dev->props->s_rx_carrier_range)
+ if (!dev->s_rx_carrier_range)
return -ENOSYS;
if (val <= 0)
return -EINVAL;
- return ir_dev->props->s_rx_carrier_range(drv_data,
- ir_dev->raw->lirc.carrier_low, val);
+ return dev->s_rx_carrier_range(dev,
+ dev->raw->lirc.carrier_low,
+ val);
case LIRC_SET_REC_CARRIER_RANGE:
if (val <= 0)
return -EINVAL;
- ir_dev->raw->lirc.carrier_low = val;
+ dev->raw->lirc.carrier_low = val;
return 0;
case LIRC_GET_REC_RESOLUTION:
- val = ir_dev->props->rx_resolution;
+ val = dev->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
- if (!ir_dev->props->s_learning_mode)
+ if (!dev->s_learning_mode)
return -ENOSYS;
- return ir_dev->props->s_learning_mode(drv_data, !!val);
+ return dev->s_learning_mode(dev, !!val);
case LIRC_SET_MEASURE_CARRIER_MODE:
- if (!ir_dev->props->s_carrier_report)
+ if (!dev->s_carrier_report)
return -ENOSYS;
- return ir_dev->props->s_carrier_report(drv_data, !!val);
+ return dev->s_carrier_report(dev, !!val);
/* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->min_timeout / 1000;
+ val = dev->min_timeout / 1000;
break;
case LIRC_GET_MAX_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->max_timeout / 1000;
+ val = dev->max_timeout / 1000;
break;
case LIRC_SET_REC_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
tmp = val * 1000;
- if (tmp < ir_dev->props->min_timeout ||
- tmp > ir_dev->props->max_timeout)
+ if (tmp < dev->min_timeout ||
+ tmp > dev->max_timeout)
return -EINVAL;
- ir_dev->props->timeout = tmp;
+ dev->timeout = tmp;
break;
case LIRC_SET_REC_TIMEOUT_REPORTS:
@@ -289,9 +287,8 @@ static struct file_operations lirc_fops = {
.llseek = no_llseek,
};
-static int ir_lirc_register(struct input_dev *input_dev)
+static int ir_lirc_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct lirc_driver *drv;
struct lirc_buffer *rbuf;
int rc = -ENOMEM;
@@ -310,44 +307,40 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto rbuf_init_failed;
features = LIRC_CAN_REC_MODE2;
- if (ir_dev->props->tx_ir) {
-
+ if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE;
- if (ir_dev->props->s_tx_mask)
+ if (dev->s_tx_mask)
features |= LIRC_CAN_SET_TRANSMITTER_MASK;
- if (ir_dev->props->s_tx_carrier)
+ if (dev->s_tx_carrier)
features |= LIRC_CAN_SET_SEND_CARRIER;
-
- if (ir_dev->props->s_tx_duty_cycle)
+ if (dev->s_tx_duty_cycle)
features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
}
- if (ir_dev->props->s_rx_carrier_range)
+ if (dev->s_rx_carrier_range)
features |= LIRC_CAN_SET_REC_CARRIER |
LIRC_CAN_SET_REC_CARRIER_RANGE;
- if (ir_dev->props->s_learning_mode)
+ if (dev->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
- if (ir_dev->props->s_carrier_report)
+ if (dev->s_carrier_report)
features |= LIRC_CAN_MEASURE_CARRIER;
-
- if (ir_dev->props->max_timeout)
+ if (dev->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;
-
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
- ir_dev->driver_name);
+ dev->driver_name);
drv->minor = -1;
drv->features = features;
- drv->data = &ir_dev->raw->lirc;
+ drv->data = &dev->raw->lirc;
drv->rbuf = rbuf;
drv->set_use_inc = &ir_lirc_open;
drv->set_use_dec = &ir_lirc_close;
drv->code_length = sizeof(struct ir_raw_event) * 8;
drv->fops = &lirc_fops;
- drv->dev = &ir_dev->dev;
+ drv->dev = &dev->dev;
drv->owner = THIS_MODULE;
drv->minor = lirc_register_driver(drv);
@@ -356,8 +349,8 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto lirc_register_failed;
}
- ir_dev->raw->lirc.drv = drv;
- ir_dev->raw->lirc.ir_dev = ir_dev;
+ dev->raw->lirc.drv = drv;
+ dev->raw->lirc.dev = dev;
return 0;
lirc_register_failed:
@@ -369,10 +362,9 @@ rbuf_alloc_failed:
return rc;
}
-static int ir_lirc_unregister(struct input_dev *input_dev)
+static int ir_lirc_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor);
lirc_buffer_free(lirc->drv->rbuf);
@@ -382,7 +374,7 @@ static int ir_lirc_unregister(struct input_dev *input_dev)
}
static struct ir_raw_handler lirc_handler = {
- .protocols = IR_TYPE_LIRC,
+ .protocols = RC_TYPE_LIRC,
.decode = ir_lirc_decode,
.raw_register = ir_lirc_register,
.raw_unregister = ir_lirc_unregister,
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 70993f79c8a2..7b58b4a1729b 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define NEC_NBITS 32
#define NEC_UNIT 562500 /* ns */
@@ -39,19 +39,18 @@ enum nec_state {
/**
* ir_nec_decode() - Decode one NEC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct nec_dec *data = &ir_dev->raw->nec;
+ struct nec_dec *data = &dev->raw->nec;
u32 scancode;
u8 address, not_address, command, not_command;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
return 0;
if (!is_timing_event(ev)) {
@@ -89,9 +88,13 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
data->state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
- ir_repeat(input_dev);
- IR_dprintk(1, "Repeat last key\n");
- data->state = STATE_TRAILER_PULSE;
+ if (!dev->keypressed) {
+ IR_dprintk(1, "Discarding last key repeat: event after key up\n");
+ } else {
+ rc_repeat(dev);
+ IR_dprintk(1, "Repeat last key\n");
+ data->state = STATE_TRAILER_PULSE;
+ }
return 0;
}
@@ -115,7 +118,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
geq_margin(ev.duration,
NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
IR_dprintk(1, "Repeat last key\n");
- ir_repeat(input_dev);
+ rc_repeat(dev);
data->state = STATE_INACTIVE;
return 0;
@@ -179,7 +182,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->is_nec_x)
data->necx_repeat = true;
- ir_keydown(input_dev, scancode, 0);
+ rc_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
@@ -191,7 +194,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
}
static struct ir_raw_handler nec_handler = {
- .protocols = IR_TYPE_NEC,
+ .protocols = RC_TYPE_NEC,
.decode = ir_nec_decode,
};
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/rc/ir-raw.c
index a06a07e4e0b1..185baddcbf14 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/rc/ir-raw.c
@@ -1,4 +1,4 @@
-/* ir-raw-event.c - handle IR Pulse/Space event
+/* ir-raw.c - handle IR pulse/space events
*
* Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
@@ -16,7 +16,7 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/freezer.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
/* Define the max number of pulse/space transitions to buffer */
#define MAX_IR_EVENT_SIZE 512
@@ -64,7 +64,7 @@ static int ir_raw_event_thread(void *data)
mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list)
- handler->decode(raw->input_dev, ev);
+ handler->decode(raw->dev, ev);
raw->prev_ev = ev;
mutex_unlock(&ir_raw_handler_lock);
}
@@ -74,7 +74,7 @@ static int ir_raw_event_thread(void *data)
/**
* ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This routine (which may be called from an interrupt context) stores a
@@ -82,17 +82,15 @@ static int ir_raw_event_thread(void *data)
* signalled as positive values and spaces as negative values. A zero value
* will reset the decoding state machines.
*/
-int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
-
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
IR_dprintk(2, "sample: (%05dus %s)\n",
- TO_US(ev->duration), TO_STR(ev->pulse));
+ TO_US(ev->duration), TO_STR(ev->pulse));
- if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
+ if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
return -ENOMEM;
return 0;
@@ -101,7 +99,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
/**
* ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) is used to
@@ -110,50 +108,49 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
* hardware which does not provide durations directly but only interrupts
* (or similar events) on state change.
*/
-int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
ktime_t now;
s64 delta; /* ns */
struct ir_raw_event ev;
int rc = 0;
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
+ delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
/* Check for a long duration since last event or if we're
* being called for the first time, note that delta can't
* possibly be negative.
*/
ev.duration = 0;
- if (delta > IR_MAX_DURATION || !ir->raw->last_type)
+ if (delta > IR_MAX_DURATION || !dev->raw->last_type)
type |= IR_START_EVENT;
else
ev.duration = delta;
if (type & IR_START_EVENT)
- ir_raw_event_reset(input_dev);
- else if (ir->raw->last_type & IR_SPACE) {
+ ir_raw_event_reset(dev);
+ else if (dev->raw->last_type & IR_SPACE) {
ev.pulse = false;
- rc = ir_raw_event_store(input_dev, &ev);
- } else if (ir->raw->last_type & IR_PULSE) {
+ rc = ir_raw_event_store(dev, &ev);
+ } else if (dev->raw->last_type & IR_PULSE) {
ev.pulse = true;
- rc = ir_raw_event_store(input_dev, &ev);
+ rc = ir_raw_event_store(dev, &ev);
} else
return 0;
- ir->raw->last_event = now;
- ir->raw->last_type = type;
+ dev->raw->last_event = now;
+ dev->raw->last_type = type;
return rc;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) works
@@ -161,84 +158,76 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
* This routine is intended for devices with limited internal buffer
* It automerges samples of same type, and handles timeouts
*/
-int ir_raw_event_store_with_filter(struct input_dev *input_dev,
- struct ir_raw_event *ev)
+int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!raw || !ir->props)
+ if (!dev->raw)
return -EINVAL;
/* Ignore spaces in idle mode */
- if (ir->idle && !ev->pulse)
+ if (dev->idle && !ev->pulse)
return 0;
- else if (ir->idle)
- ir_raw_event_set_idle(input_dev, false);
-
- if (!raw->this_ev.duration) {
- raw->this_ev = *ev;
- } else if (ev->pulse == raw->this_ev.pulse) {
- raw->this_ev.duration += ev->duration;
- } else {
- ir_raw_event_store(input_dev, &raw->this_ev);
- raw->this_ev = *ev;
+ else if (dev->idle)
+ ir_raw_event_set_idle(dev, false);
+
+ if (!dev->raw->this_ev.duration)
+ dev->raw->this_ev = *ev;
+ else if (ev->pulse == dev->raw->this_ev.pulse)
+ dev->raw->this_ev.duration += ev->duration;
+ else {
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ dev->raw->this_ev = *ev;
}
/* Enter idle mode if nessesary */
- if (!ev->pulse && ir->props->timeout &&
- raw->this_ev.duration >= ir->props->timeout) {
- ir_raw_event_set_idle(input_dev, true);
- }
+ if (!ev->pulse && dev->timeout &&
+ dev->raw->this_ev.duration >= dev->timeout)
+ ir_raw_event_set_idle(dev, true);
+
return 0;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
/**
- * ir_raw_event_set_idle() - hint the ir core if device is receiving
- * IR data or not
- * @input_dev: the struct input_dev device descriptor
- * @idle: the hint value
+ * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
+ * @dev: the struct rc_dev device descriptor
+ * @idle: whether the device is idle or not
*/
-void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!ir->props || !ir->raw)
+ if (!dev->raw)
return;
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) {
- raw->this_ev.timeout = true;
- ir_raw_event_store(input_dev, &raw->this_ev);
- init_ir_raw_event(&raw->this_ev);
+ dev->raw->this_ev.timeout = true;
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ init_ir_raw_event(&dev->raw->this_ev);
}
- if (ir->props->s_idle)
- ir->props->s_idle(ir->props->priv, idle);
- ir->idle = idle;
+ if (dev->s_idle)
+ dev->s_idle(dev, idle);
+
+ dev->idle = idle;
}
EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
/**
* ir_raw_event_handle() - schedules the decoding of stored ir data
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
*
- * This routine will signal the workqueue to start decoding stored ir data.
+ * This routine will tell rc-core to start decoding stored ir data.
*/
-void ir_raw_event_handle(struct input_dev *input_dev)
+void ir_raw_event_handle(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
unsigned long flags;
- if (!ir->raw)
+ if (!dev->raw)
return;
- spin_lock_irqsave(&ir->raw->lock, flags);
- wake_up_process(ir->raw->thread);
- spin_unlock_irqrestore(&ir->raw->lock, flags);
+ spin_lock_irqsave(&dev->raw->lock, flags);
+ wake_up_process(dev->raw->thread);
+ spin_unlock_irqrestore(&dev->raw->lock, flags);
}
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
@@ -256,69 +245,69 @@ ir_raw_get_allowed_protocols()
/*
* Used to (un)register raw event clients
*/
-int ir_raw_event_register(struct input_dev *input_dev)
+int ir_raw_event_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
int rc;
struct ir_raw_handler *handler;
- ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
- if (!ir->raw)
- return -ENOMEM;
+ if (!dev)
+ return -EINVAL;
- ir->raw->input_dev = input_dev;
+ dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
+ if (!dev->raw)
+ return -ENOMEM;
- ir->raw->enabled_protocols = ~0;
- rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
+ dev->raw->dev = dev;
+ dev->raw->enabled_protocols = ~0;
+ rc = kfifo_alloc(&dev->raw->kfifo,
+ sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL);
- if (rc < 0) {
- kfree(ir->raw);
- ir->raw = NULL;
- return rc;
- }
+ if (rc < 0)
+ goto out;
- spin_lock_init(&ir->raw->lock);
- ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
- "rc%u", (unsigned int)ir->devno);
+ spin_lock_init(&dev->raw->lock);
+ dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
+ "rc%ld", dev->devno);
- if (IS_ERR(ir->raw->thread)) {
- int ret = PTR_ERR(ir->raw->thread);
-
- kfree(ir->raw);
- ir->raw = NULL;
- return ret;
+ if (IS_ERR(dev->raw->thread)) {
+ rc = PTR_ERR(dev->raw->thread);
+ goto out;
}
mutex_lock(&ir_raw_handler_lock);
- list_add_tail(&ir->raw->list, &ir_raw_client_list);
+ list_add_tail(&dev->raw->list, &ir_raw_client_list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_register)
- handler->raw_register(ir->raw->input_dev);
+ handler->raw_register(dev);
mutex_unlock(&ir_raw_handler_lock);
return 0;
+
+out:
+ kfree(dev->raw);
+ dev->raw = NULL;
+ return rc;
}
-void ir_raw_event_unregister(struct input_dev *input_dev)
+void ir_raw_event_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
struct ir_raw_handler *handler;
- if (!ir->raw)
+ if (!dev || !dev->raw)
return;
- kthread_stop(ir->raw->thread);
+ kthread_stop(dev->raw->thread);
mutex_lock(&ir_raw_handler_lock);
- list_del(&ir->raw->list);
+ list_del(&dev->raw->list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_unregister)
- handler->raw_unregister(ir->raw->input_dev);
+ handler->raw_unregister(dev);
mutex_unlock(&ir_raw_handler_lock);
- kfifo_free(&ir->raw->kfifo);
- kfree(ir->raw);
- ir->raw = NULL;
+ kfifo_free(&dev->raw->kfifo);
+ kfree(dev->raw);
+ dev->raw = NULL;
}
/*
@@ -333,7 +322,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
if (ir_raw_handler->raw_register)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_register(raw->input_dev);
+ ir_raw_handler->raw_register(raw->dev);
available_protocols |= ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
@@ -349,7 +338,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
list_del(&ir_raw_handler->list);
if (ir_raw_handler->raw_unregister)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_unregister(raw->input_dev);
+ ir_raw_handler->raw_unregister(raw->dev);
available_protocols &= ~ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
}
@@ -368,7 +357,7 @@ static void init_decoders(struct work_struct *work)
load_lirc_codec();
/* If needed, we may later add some init code. In this case,
- it is needed to change the CONFIG_MODULE test at ir-core.h
+ it is needed to change the CONFIG_MODULE test at rc-core.h
*/
}
#endif
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 572ed4ca8c68..ebdba5539916 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -20,7 +20,7 @@
* the first two bits are start bits, and a third one is a filing bit
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define RC5_NBITS 14
#define RC5X_NBITS 20
@@ -40,19 +40,18 @@ enum rc5_state {
/**
* ir_rc5_decode() - Decode one RC-5 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_dec *data = &ir_dev->raw->rc5;
+ struct rc5_dec *data = &dev->raw->rc5;
u8 toggle;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC5))
return 0;
if (!is_timing_event(ev)) {
@@ -96,7 +95,7 @@ again:
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -151,7 +150,7 @@ again:
scancode, toggle);
}
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -164,7 +163,7 @@ out:
}
static struct ir_raw_handler rc5_handler = {
- .protocols = IR_TYPE_RC5,
+ .protocols = RC_TYPE_RC5,
.decode = ir_rc5_decode,
};
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c
index 7c413501a3f7..90aa8868629a 100644
--- a/drivers/media/IR/ir-rc5-sz-decoder.c
+++ b/drivers/media/rc/ir-rc5-sz-decoder.c
@@ -20,7 +20,7 @@
* the first two bits are start bits, and a third one is a filing bit
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define RC5_SZ_NBITS 15
#define RC5_UNIT 888888 /* ns */
@@ -36,19 +36,18 @@ enum rc5_sz_state {
/**
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
+ struct rc5_sz_dec *data = &dev->raw->rc5_sz;
u8 toggle, command, system;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ))
return 0;
if (!is_timing_event(ev)) {
@@ -91,7 +90,7 @@ again:
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -115,7 +114,7 @@ again:
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
scancode, toggle);
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -128,7 +127,7 @@ out:
}
static struct ir_raw_handler rc5_sz_handler = {
- .protocols = IR_TYPE_RC5_SZ,
+ .protocols = RC_TYPE_RC5_SZ,
.decode = ir_rc5_sz_decode,
};
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index d25da91f44ff..755dafa3871b 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
/*
* This decoder currently supports:
@@ -70,19 +70,18 @@ static enum rc6_mode rc6_mode(struct rc6_dec *data)
/**
* ir_rc6_decode() - Decode one RC6 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc6_dec *data = &ir_dev->raw->rc6;
+ struct rc6_dec *data = &dev->raw->rc6;
u32 scancode;
u8 toggle;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC6))
return 0;
if (!is_timing_event(ev)) {
@@ -139,7 +138,7 @@ again:
return 0;
case STATE_HEADER_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == RC6_HEADER_NBITS)
@@ -159,7 +158,7 @@ again:
return 0;
case STATE_TOGGLE_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
+ if (!is_transition(&ev, &dev->raw->prev_ev) ||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break;
@@ -204,7 +203,7 @@ again:
return 0;
case STATE_BODY_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -243,7 +242,7 @@ again:
goto out;
}
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -256,7 +255,7 @@ out:
}
static struct ir_raw_handler rc6_handler = {
- .protocols = IR_TYPE_RC6,
+ .protocols = RC_TYPE_RC6,
.decode = ir_rc6_decode,
};
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index 2d15730822bc..a92de80c48db 100644
--- a/drivers/media/IR/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define SONY_UNIT 600000 /* ns */
#define SONY_HEADER_PULSE (4 * SONY_UNIT)
@@ -33,19 +33,18 @@ enum sony_state {
/**
* ir_sony_decode() - Decode one Sony pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct sony_dec *data = &ir_dev->raw->sony;
+ struct sony_dec *data = &dev->raw->sony;
u32 scancode;
u8 device, subdevice, function;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_SONY))
return 0;
if (!is_timing_event(ev)) {
@@ -144,7 +143,7 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
scancode = device << 16 | subdevice << 8 | function;
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
- ir_keydown(input_dev, scancode, 0);
+ rc_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
@@ -157,7 +156,7 @@ out:
}
static struct ir_raw_handler sony_handler = {
- .protocols = IR_TYPE_SONY,
+ .protocols = RC_TYPE_SONY,
.decode = ir_sony_decode,
};
diff --git a/drivers/media/IR/keymaps/Kconfig b/drivers/media/rc/keymaps/Kconfig
index 14b22f58f823..8e615fd55852 100644
--- a/drivers/media/IR/keymaps/Kconfig
+++ b/drivers/media/rc/keymaps/Kconfig
@@ -1,6 +1,6 @@
config RC_MAP
tristate "Compile Remote Controller keymap modules"
- depends on IR_CORE
+ depends on RC_CORE
default y
---help---
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 3194d391bbd4..0659e9f50144 100644
--- a/drivers/media/IR/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-pinnacle-pctv-hd.o \
rc-pixelview.o \
rc-pixelview-mk12.o \
+ rc-pixelview-002t.o \
rc-pixelview-new.o \
rc-powercolor-real-angel.o \
rc-proteus-2309.o \
@@ -80,6 +81,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-trekstor.o \
rc-tt-1500.o \
rc-twinhan1027.o \
+ rc-videomate-m1f.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
rc-winfast.o \
diff --git a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index b17283176ecd..136d3952dedc 100644
--- a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -14,7 +14,7 @@
/* ADS Tech Instant TV DVB-T PCI Remote */
-static struct ir_scancode adstech_dvb_t_pci[] = {
+static struct rc_map_table adstech_dvb_t_pci[] = {
/* Keys 0 to 9 */
{ 0x4d, KEY_0 },
{ 0x57, KEY_1 },
@@ -63,23 +63,23 @@ static struct ir_scancode adstech_dvb_t_pci[] = {
{ 0x1c, KEY_VOLUMEDOWN },
};
-static struct rc_keymap adstech_dvb_t_pci_map = {
+static struct rc_map_list adstech_dvb_t_pci_map = {
.map = {
.scan = adstech_dvb_t_pci,
.size = ARRAY_SIZE(adstech_dvb_t_pci),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ADSTECH_DVB_T_PCI,
}
};
static int __init init_rc_map_adstech_dvb_t_pci(void)
{
- return ir_register_map(&adstech_dvb_t_pci_map);
+ return rc_map_register(&adstech_dvb_t_pci_map);
}
static void __exit exit_rc_map_adstech_dvb_t_pci(void)
{
- ir_unregister_map(&adstech_dvb_t_pci_map);
+ rc_map_unregister(&adstech_dvb_t_pci_map);
}
module_init(init_rc_map_adstech_dvb_t_pci)
diff --git a/drivers/media/IR/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c
index ddfee7f8093d..fe652e928dc0 100644
--- a/drivers/media/IR/keymaps/rc-alink-dtu-m.c
+++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c
@@ -21,7 +21,7 @@
#include <media/rc-map.h>
/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
-static struct ir_scancode alink_dtu_m[] = {
+static struct rc_map_table alink_dtu_m[] = {
{ 0x0800, KEY_VOLUMEUP },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_3 },
@@ -42,23 +42,23 @@ static struct ir_scancode alink_dtu_m[] = {
{ 0x081d, KEY_CHANNELDOWN },
};
-static struct rc_keymap alink_dtu_m_map = {
+static struct rc_map_list alink_dtu_m_map = {
.map = {
.scan = alink_dtu_m,
.size = ARRAY_SIZE(alink_dtu_m),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_ALINK_DTU_M,
}
};
static int __init init_rc_map_alink_dtu_m(void)
{
- return ir_register_map(&alink_dtu_m_map);
+ return rc_map_register(&alink_dtu_m_map);
}
static void __exit exit_rc_map_alink_dtu_m(void)
{
- ir_unregister_map(&alink_dtu_m_map);
+ rc_map_unregister(&alink_dtu_m_map);
}
module_init(init_rc_map_alink_dtu_m)
diff --git a/drivers/media/IR/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c
index 30d70498cfed..884f1b51a8ee 100644
--- a/drivers/media/IR/keymaps/rc-anysee.c
+++ b/drivers/media/rc/keymaps/rc-anysee.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode anysee[] = {
+static struct rc_map_table anysee[] = {
{ 0x0800, KEY_0 },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_2 },
@@ -67,23 +67,23 @@ static struct ir_scancode anysee[] = {
{ 0x0851, KEY_PAUSE },
};
-static struct rc_keymap anysee_map = {
+static struct rc_map_list anysee_map = {
.map = {
.scan = anysee,
.size = ARRAY_SIZE(anysee),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_ANYSEE,
}
};
static int __init init_rc_map_anysee(void)
{
- return ir_register_map(&anysee_map);
+ return rc_map_register(&anysee_map);
}
static void __exit exit_rc_map_anysee(void)
{
- ir_unregister_map(&anysee_map);
+ rc_map_unregister(&anysee_map);
}
module_init(init_rc_map_anysee)
diff --git a/drivers/media/IR/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
index 0ef2b562baf0..7af188209ff9 100644
--- a/drivers/media/IR/keymaps/rc-apac-viewcomp.c
+++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
@@ -14,7 +14,7 @@
/* Attila Kondoros <attila.kondoros@chello.hu> */
-static struct ir_scancode apac_viewcomp[] = {
+static struct rc_map_table apac_viewcomp[] = {
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -54,23 +54,23 @@ static struct ir_scancode apac_viewcomp[] = {
{ 0x18, KEY_KPMINUS }, /* fine tune <<<< */
};
-static struct rc_keymap apac_viewcomp_map = {
+static struct rc_map_list apac_viewcomp_map = {
.map = {
.scan = apac_viewcomp,
.size = ARRAY_SIZE(apac_viewcomp),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_APAC_VIEWCOMP,
}
};
static int __init init_rc_map_apac_viewcomp(void)
{
- return ir_register_map(&apac_viewcomp_map);
+ return rc_map_register(&apac_viewcomp_map);
}
static void __exit exit_rc_map_apac_viewcomp(void)
{
- ir_unregister_map(&apac_viewcomp_map);
+ rc_map_unregister(&apac_viewcomp_map);
}
module_init(init_rc_map_apac_viewcomp)
diff --git a/drivers/media/IR/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c
index 2996e0a3b8d5..b2481154491b 100644
--- a/drivers/media/IR/keymaps/rc-asus-pc39.c
+++ b/drivers/media/rc/keymaps/rc-asus-pc39.c
@@ -18,7 +18,7 @@
* which has a label saying is "Model PC-39"
*/
-static struct ir_scancode asus_pc39[] = {
+static struct rc_map_table asus_pc39[] = {
/* Keys 0 to 9 */
{ 0x082a, KEY_0 },
{ 0x0816, KEY_1 },
@@ -65,23 +65,23 @@ static struct ir_scancode asus_pc39[] = {
{ 0x083e, KEY_DVD }, /* dvd */
};
-static struct rc_keymap asus_pc39_map = {
+static struct rc_map_list asus_pc39_map = {
.map = {
.scan = asus_pc39,
.size = ARRAY_SIZE(asus_pc39),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_ASUS_PC39,
}
};
static int __init init_rc_map_asus_pc39(void)
{
- return ir_register_map(&asus_pc39_map);
+ return rc_map_register(&asus_pc39_map);
}
static void __exit exit_rc_map_asus_pc39(void)
{
- ir_unregister_map(&asus_pc39_map);
+ rc_map_unregister(&asus_pc39_map);
}
module_init(init_rc_map_asus_pc39)
diff --git a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
index 8edfd293d010..f766b24b0158 100644
--- a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
+++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -16,7 +16,7 @@
Devin Heitmueller <devin.heitmueller@gmail.com>
*/
-static struct ir_scancode ati_tv_wonder_hd_600[] = {
+static struct rc_map_table ati_tv_wonder_hd_600[] = {
{ 0x00, KEY_RECORD}, /* Row 1 */
{ 0x01, KEY_PLAYPAUSE},
{ 0x02, KEY_STOP},
@@ -43,23 +43,23 @@ static struct ir_scancode ati_tv_wonder_hd_600[] = {
{ 0x17, KEY_VOLUMEDOWN},
};
-static struct rc_keymap ati_tv_wonder_hd_600_map = {
+static struct rc_map_list ati_tv_wonder_hd_600_map = {
.map = {
.scan = ati_tv_wonder_hd_600,
.size = ARRAY_SIZE(ati_tv_wonder_hd_600),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ATI_TV_WONDER_HD_600,
}
};
static int __init init_rc_map_ati_tv_wonder_hd_600(void)
{
- return ir_register_map(&ati_tv_wonder_hd_600_map);
+ return rc_map_register(&ati_tv_wonder_hd_600_map);
}
static void __exit exit_rc_map_ati_tv_wonder_hd_600(void)
{
- ir_unregister_map(&ati_tv_wonder_hd_600_map);
+ rc_map_unregister(&ati_tv_wonder_hd_600_map);
}
module_init(init_rc_map_ati_tv_wonder_hd_600)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
index 12f043587f2e..ec9beeebd410 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-a16d.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode avermedia_a16d[] = {
+static struct rc_map_table avermedia_a16d[] = {
{ 0x20, KEY_LIST},
{ 0x00, KEY_POWER},
{ 0x28, KEY_1},
@@ -49,23 +49,23 @@ static struct ir_scancode avermedia_a16d[] = {
{ 0x2a, KEY_MENU},
};
-static struct rc_keymap avermedia_a16d_map = {
+static struct rc_map_list avermedia_a16d_map = {
.map = {
.scan = avermedia_a16d,
.size = ARRAY_SIZE(avermedia_a16d),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_A16D,
}
};
static int __init init_rc_map_avermedia_a16d(void)
{
- return ir_register_map(&avermedia_a16d_map);
+ return rc_map_register(&avermedia_a16d_map);
}
static void __exit exit_rc_map_avermedia_a16d(void)
{
- ir_unregister_map(&avermedia_a16d_map);
+ rc_map_unregister(&avermedia_a16d_map);
}
module_init(init_rc_map_avermedia_a16d)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
index 2a945b02e8ca..bdf97b74cf90 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
@@ -14,7 +14,7 @@
/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
-static struct ir_scancode avermedia_cardbus[] = {
+static struct rc_map_table avermedia_cardbus[] = {
{ 0x00, KEY_POWER },
{ 0x01, KEY_TUNER }, /* TV/FM */
{ 0x03, KEY_TEXT }, /* Teletext */
@@ -71,23 +71,23 @@ static struct ir_scancode avermedia_cardbus[] = {
{ 0x43, KEY_CHANNELUP }, /* Channel up */
};
-static struct rc_keymap avermedia_cardbus_map = {
+static struct rc_map_list avermedia_cardbus_map = {
.map = {
.scan = avermedia_cardbus,
.size = ARRAY_SIZE(avermedia_cardbus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_CARDBUS,
}
};
static int __init init_rc_map_avermedia_cardbus(void)
{
- return ir_register_map(&avermedia_cardbus_map);
+ return rc_map_register(&avermedia_cardbus_map);
}
static void __exit exit_rc_map_avermedia_cardbus(void)
{
- ir_unregister_map(&avermedia_cardbus_map);
+ rc_map_unregister(&avermedia_cardbus_map);
}
module_init(init_rc_map_avermedia_cardbus)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index 39dde6222875..3ddb41bc075e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -14,7 +14,7 @@
/* Matt Jesson <dvb@jesson.eclipse.co.uk */
-static struct ir_scancode avermedia_dvbt[] = {
+static struct rc_map_table avermedia_dvbt[] = {
{ 0x28, KEY_0 }, /* '0' / 'enter' */
{ 0x22, KEY_1 }, /* '1' */
{ 0x12, KEY_2 }, /* '2' / 'up arrow' */
@@ -52,23 +52,23 @@ static struct ir_scancode avermedia_dvbt[] = {
{ 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
};
-static struct rc_keymap avermedia_dvbt_map = {
+static struct rc_map_list avermedia_dvbt_map = {
.map = {
.scan = avermedia_dvbt,
.size = ARRAY_SIZE(avermedia_dvbt),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_DVBT,
}
};
static int __init init_rc_map_avermedia_dvbt(void)
{
- return ir_register_map(&avermedia_dvbt_map);
+ return rc_map_register(&avermedia_dvbt_map);
}
static void __exit exit_rc_map_avermedia_dvbt(void)
{
- ir_unregister_map(&avermedia_dvbt_map);
+ rc_map_unregister(&avermedia_dvbt_map);
}
module_init(init_rc_map_avermedia_dvbt)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index e4471fb2ad1e..357fea58a46e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -22,7 +22,7 @@
* codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
-static struct ir_scancode avermedia_m135a[] = {
+static struct rc_map_table avermedia_m135a[] = {
/* RM-JX */
{ 0x0200, KEY_POWER2 },
{ 0x022e, KEY_DOT }, /* '.' */
@@ -121,23 +121,23 @@ static struct ir_scancode avermedia_m135a[] = {
{ 0x041e, KEY_NEXT },
};
-static struct rc_keymap avermedia_m135a_map = {
+static struct rc_map_list avermedia_m135a_map = {
.map = {
.scan = avermedia_m135a,
.size = ARRAY_SIZE(avermedia_m135a),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M135A,
}
};
static int __init init_rc_map_avermedia_m135a(void)
{
- return ir_register_map(&avermedia_m135a_map);
+ return rc_map_register(&avermedia_m135a_map);
}
static void __exit exit_rc_map_avermedia_m135a(void)
{
- ir_unregister_map(&avermedia_m135a_map);
+ rc_map_unregister(&avermedia_m135a_map);
}
module_init(init_rc_map_avermedia_m135a)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
index cf8d45717cb3..e694e6eac37e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
@@ -16,7 +16,7 @@
* Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
-static struct ir_scancode avermedia_m733a_rm_k6[] = {
+static struct rc_map_table avermedia_m733a_rm_k6[] = {
{ 0x0401, KEY_POWER2 },
{ 0x0406, KEY_MUTE },
{ 0x0408, KEY_MODE }, /* TV/FM */
@@ -69,23 +69,23 @@ static struct ir_scancode avermedia_m733a_rm_k6[] = {
{ 0x041e, KEY_NEXT },
};
-static struct rc_keymap avermedia_m733a_rm_k6_map = {
+static struct rc_map_list avermedia_m733a_rm_k6_map = {
.map = {
.scan = avermedia_m733a_rm_k6,
.size = ARRAY_SIZE(avermedia_m733a_rm_k6),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M733A_RM_K6,
}
};
static int __init init_rc_map_avermedia_m733a_rm_k6(void)
{
- return ir_register_map(&avermedia_m733a_rm_k6_map);
+ return rc_map_register(&avermedia_m733a_rm_k6_map);
}
static void __exit exit_rc_map_avermedia_m733a_rm_k6(void)
{
- ir_unregister_map(&avermedia_m733a_rm_k6_map);
+ rc_map_unregister(&avermedia_m733a_rm_k6_map);
}
module_init(init_rc_map_avermedia_m733a_rm_k6)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
index 9ee60906c861..f4ca1fff455d 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
@@ -23,7 +23,7 @@
/* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net>
and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
/* FIXME: mappings are not 100% correct? */
-static struct ir_scancode avermedia_rm_ks[] = {
+static struct rc_map_table avermedia_rm_ks[] = {
{ 0x0501, KEY_POWER2 },
{ 0x0502, KEY_CHANNELUP },
{ 0x0503, KEY_CHANNELDOWN },
@@ -53,23 +53,23 @@ static struct ir_scancode avermedia_rm_ks[] = {
{ 0x0556, KEY_ZOOM },
};
-static struct rc_keymap avermedia_rm_ks_map = {
+static struct rc_map_list avermedia_rm_ks_map = {
.map = {
.scan = avermedia_rm_ks,
.size = ARRAY_SIZE(avermedia_rm_ks),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_RM_KS,
}
};
static int __init init_rc_map_avermedia_rm_ks(void)
{
- return ir_register_map(&avermedia_rm_ks_map);
+ return rc_map_register(&avermedia_rm_ks_map);
}
static void __exit exit_rc_map_avermedia_rm_ks(void)
{
- ir_unregister_map(&avermedia_rm_ks_map);
+ rc_map_unregister(&avermedia_rm_ks_map);
}
module_init(init_rc_map_avermedia_rm_ks)
diff --git a/drivers/media/IR/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c
index 21effd5bfb0d..edfa71506d3e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia.c
+++ b/drivers/media/rc/keymaps/rc-avermedia.c
@@ -14,7 +14,7 @@
/* Alex Hermann <gaaf@gmx.net> */
-static struct ir_scancode avermedia[] = {
+static struct rc_map_table avermedia[] = {
{ 0x28, KEY_1 },
{ 0x18, KEY_2 },
{ 0x38, KEY_3 },
@@ -60,23 +60,23 @@ static struct ir_scancode avermedia[] = {
{ 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
};
-static struct rc_keymap avermedia_map = {
+static struct rc_map_list avermedia_map = {
.map = {
.scan = avermedia,
.size = ARRAY_SIZE(avermedia),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA,
}
};
static int __init init_rc_map_avermedia(void)
{
- return ir_register_map(&avermedia_map);
+ return rc_map_register(&avermedia_map);
}
static void __exit exit_rc_map_avermedia(void)
{
- ir_unregister_map(&avermedia_map);
+ rc_map_unregister(&avermedia_map);
}
module_init(init_rc_map_avermedia)
diff --git a/drivers/media/IR/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c
index 971c59d6f9d6..32e94988dc94 100644
--- a/drivers/media/IR/keymaps/rc-avertv-303.c
+++ b/drivers/media/rc/keymaps/rc-avertv-303.c
@@ -14,7 +14,7 @@
/* AVERTV STUDIO 303 Remote */
-static struct ir_scancode avertv_303[] = {
+static struct rc_map_table avertv_303[] = {
{ 0x2a, KEY_1 },
{ 0x32, KEY_2 },
{ 0x3a, KEY_3 },
@@ -59,23 +59,23 @@ static struct ir_scancode avertv_303[] = {
{ 0x1b, KEY_UP },
};
-static struct rc_keymap avertv_303_map = {
+static struct rc_map_list avertv_303_map = {
.map = {
.scan = avertv_303,
.size = ARRAY_SIZE(avertv_303),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERTV_303,
}
};
static int __init init_rc_map_avertv_303(void)
{
- return ir_register_map(&avertv_303_map);
+ return rc_map_register(&avertv_303_map);
}
static void __exit exit_rc_map_avertv_303(void)
{
- ir_unregister_map(&avertv_303_map);
+ rc_map_unregister(&avertv_303_map);
}
module_init(init_rc_map_avertv_303)
diff --git a/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
index e0876147d471..c3f6d62ac892 100644
--- a/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c
+++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode azurewave_ad_tu700[] = {
+static struct rc_map_table azurewave_ad_tu700[] = {
{ 0x0000, KEY_TAB }, /* Tab */
{ 0x0001, KEY_2 },
{ 0x0002, KEY_CHANNELDOWN },
@@ -76,23 +76,23 @@ static struct ir_scancode azurewave_ad_tu700[] = {
{ 0x005f, KEY_BLUE },
};
-static struct rc_keymap azurewave_ad_tu700_map = {
+static struct rc_map_list azurewave_ad_tu700_map = {
.map = {
.scan = azurewave_ad_tu700,
.size = ARRAY_SIZE(azurewave_ad_tu700),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AZUREWAVE_AD_TU700,
}
};
static int __init init_rc_map_azurewave_ad_tu700(void)
{
- return ir_register_map(&azurewave_ad_tu700_map);
+ return rc_map_register(&azurewave_ad_tu700_map);
}
static void __exit exit_rc_map_azurewave_ad_tu700(void)
{
- ir_unregister_map(&azurewave_ad_tu700_map);
+ rc_map_unregister(&azurewave_ad_tu700_map);
}
module_init(init_rc_map_azurewave_ad_tu700)
diff --git a/drivers/media/IR/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index 9f56c98fef5b..4b787fa94f08 100644
--- a/drivers/media/IR/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -21,7 +21,7 @@
* helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode behold_columbus[] = {
+static struct rc_map_table behold_columbus[] = {
/* 0x13 0x11 0x1C 0x12 *
* Mute Source TV/FM Power *
@@ -82,23 +82,23 @@ static struct ir_scancode behold_columbus[] = {
};
-static struct rc_keymap behold_columbus_map = {
+static struct rc_map_list behold_columbus_map = {
.map = {
.scan = behold_columbus,
.size = ARRAY_SIZE(behold_columbus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_BEHOLD_COLUMBUS,
}
};
static int __init init_rc_map_behold_columbus(void)
{
- return ir_register_map(&behold_columbus_map);
+ return rc_map_register(&behold_columbus_map);
}
static void __exit exit_rc_map_behold_columbus(void)
{
- ir_unregister_map(&behold_columbus_map);
+ rc_map_unregister(&behold_columbus_map);
}
module_init(init_rc_map_behold_columbus)
diff --git a/drivers/media/IR/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index abc140b2098b..0ee1f149364c 100644
--- a/drivers/media/IR/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -24,13 +24,13 @@
* helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode behold[] = {
+static struct rc_map_table behold[] = {
/* 0x1c 0x12 *
* TV/FM POWER *
* */
- { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
- { 0x12, KEY_POWER },
+ { 0x6b861c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
+ { 0x6b8612, KEY_POWER },
/* 0x01 0x02 0x03 *
* 1 2 3 *
@@ -41,28 +41,28 @@ static struct ir_scancode behold[] = {
* 0x07 0x08 0x09 *
* 7 8 9 *
* */
- { 0x01, KEY_1 },
- { 0x02, KEY_2 },
- { 0x03, KEY_3 },
- { 0x04, KEY_4 },
- { 0x05, KEY_5 },
- { 0x06, KEY_6 },
- { 0x07, KEY_7 },
- { 0x08, KEY_8 },
- { 0x09, KEY_9 },
+ { 0x6b8601, KEY_1 },
+ { 0x6b8602, KEY_2 },
+ { 0x6b8603, KEY_3 },
+ { 0x6b8604, KEY_4 },
+ { 0x6b8605, KEY_5 },
+ { 0x6b8606, KEY_6 },
+ { 0x6b8607, KEY_7 },
+ { 0x6b8608, KEY_8 },
+ { 0x6b8609, KEY_9 },
/* 0x0a 0x00 0x17 *
* RECALL 0 MODE *
* */
- { 0x0a, KEY_AGAIN },
- { 0x00, KEY_0 },
- { 0x17, KEY_MODE },
+ { 0x6b860a, KEY_AGAIN },
+ { 0x6b8600, KEY_0 },
+ { 0x6b8617, KEY_MODE },
/* 0x14 0x10 *
* ASPECT FULLSCREEN *
* */
- { 0x14, KEY_SCREEN },
- { 0x10, KEY_ZOOM },
+ { 0x6b8614, KEY_SCREEN },
+ { 0x6b8610, KEY_ZOOM },
/* 0x0b *
* Up *
@@ -73,17 +73,17 @@ static struct ir_scancode behold[] = {
* 0x015 *
* Down *
* */
- { 0x0b, KEY_CHANNELUP },
- { 0x18, KEY_VOLUMEDOWN },
- { 0x16, KEY_OK }, /* XXX KEY_ENTER */
- { 0x0c, KEY_VOLUMEUP },
- { 0x15, KEY_CHANNELDOWN },
+ { 0x6b860b, KEY_CHANNELUP },
+ { 0x6b8618, KEY_VOLUMEDOWN },
+ { 0x6b8616, KEY_OK }, /* XXX KEY_ENTER */
+ { 0x6b860c, KEY_VOLUMEUP },
+ { 0x6b8615, KEY_CHANNELDOWN },
/* 0x11 0x0d *
* MUTE INFO *
* */
- { 0x11, KEY_MUTE },
- { 0x0d, KEY_INFO },
+ { 0x6b8611, KEY_MUTE },
+ { 0x6b860d, KEY_INFO },
/* 0x0f 0x1b 0x1a *
* RECORD PLAY/PAUSE STOP *
@@ -92,46 +92,46 @@ static struct ir_scancode behold[] = {
*TELETEXT AUDIO SOURCE *
* RED YELLOW *
* */
- { 0x0f, KEY_RECORD },
- { 0x1b, KEY_PLAYPAUSE },
- { 0x1a, KEY_STOP },
- { 0x0e, KEY_TEXT },
- { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
- { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
+ { 0x6b860f, KEY_RECORD },
+ { 0x6b861b, KEY_PLAYPAUSE },
+ { 0x6b861a, KEY_STOP },
+ { 0x6b860e, KEY_TEXT },
+ { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
+ { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */
/* 0x1d 0x13 0x19 *
* SLEEP PREVIEW DVB *
* GREEN BLUE *
* */
- { 0x1d, KEY_SLEEP },
- { 0x13, KEY_GREEN },
- { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
+ { 0x6b861d, KEY_SLEEP },
+ { 0x6b8613, KEY_GREEN },
+ { 0x6b8619, KEY_BLUE }, /* XXX KEY_SAT */
/* 0x58 0x5c *
* FREEZE SNAPSHOT *
* */
- { 0x58, KEY_SLOW },
- { 0x5c, KEY_CAMERA },
+ { 0x6b8658, KEY_SLOW },
+ { 0x6b865c, KEY_CAMERA },
};
-static struct rc_keymap behold_map = {
+static struct rc_map_list behold_map = {
.map = {
.scan = behold,
.size = ARRAY_SIZE(behold),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_BEHOLD,
}
};
static int __init init_rc_map_behold(void)
{
- return ir_register_map(&behold_map);
+ return rc_map_register(&behold_map);
}
static void __exit exit_rc_map_behold(void)
{
- ir_unregister_map(&behold_map);
+ rc_map_unregister(&behold_map);
}
module_init(init_rc_map_behold)
diff --git a/drivers/media/IR/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 64c2ac913338..97fc3862f608 100644
--- a/drivers/media/IR/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -18,7 +18,7 @@
* This is a "middle of the road" approach, differences are noted
*/
-static struct ir_scancode budget_ci_old[] = {
+static struct rc_map_table budget_ci_old[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -66,23 +66,23 @@ static struct ir_scancode budget_ci_old[] = {
{ 0x3e, KEY_TUNER },
};
-static struct rc_keymap budget_ci_old_map = {
+static struct rc_map_list budget_ci_old_map = {
.map = {
.scan = budget_ci_old,
.size = ARRAY_SIZE(budget_ci_old),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_BUDGET_CI_OLD,
}
};
static int __init init_rc_map_budget_ci_old(void)
{
- return ir_register_map(&budget_ci_old_map);
+ return rc_map_register(&budget_ci_old_map);
}
static void __exit exit_rc_map_budget_ci_old(void)
{
- ir_unregister_map(&budget_ci_old_map);
+ rc_map_unregister(&budget_ci_old_map);
}
module_init(init_rc_map_budget_ci_old)
diff --git a/drivers/media/IR/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c
index 074f2c2c2c61..284534b67e7d 100644
--- a/drivers/media/IR/keymaps/rc-cinergy-1400.c
+++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c
@@ -14,7 +14,7 @@
/* Cinergy 1400 DVB-T */
-static struct ir_scancode cinergy_1400[] = {
+static struct rc_map_table cinergy_1400[] = {
{ 0x01, KEY_POWER },
{ 0x02, KEY_1 },
{ 0x03, KEY_2 },
@@ -58,23 +58,23 @@ static struct ir_scancode cinergy_1400[] = {
{ 0x5c, KEY_NEXT },
};
-static struct rc_keymap cinergy_1400_map = {
+static struct rc_map_list cinergy_1400_map = {
.map = {
.scan = cinergy_1400,
.size = ARRAY_SIZE(cinergy_1400),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_CINERGY_1400,
}
};
static int __init init_rc_map_cinergy_1400(void)
{
- return ir_register_map(&cinergy_1400_map);
+ return rc_map_register(&cinergy_1400_map);
}
static void __exit exit_rc_map_cinergy_1400(void)
{
- ir_unregister_map(&cinergy_1400_map);
+ rc_map_unregister(&cinergy_1400_map);
}
module_init(init_rc_map_cinergy_1400)
diff --git a/drivers/media/IR/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index cf84c3dba742..99520ff65b61 100644
--- a/drivers/media/IR/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode cinergy[] = {
+static struct rc_map_table cinergy[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -52,23 +52,23 @@ static struct ir_scancode cinergy[] = {
{ 0x23, KEY_STOP },
};
-static struct rc_keymap cinergy_map = {
+static struct rc_map_list cinergy_map = {
.map = {
.scan = cinergy,
.size = ARRAY_SIZE(cinergy),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_CINERGY,
}
};
static int __init init_rc_map_cinergy(void)
{
- return ir_register_map(&cinergy_map);
+ return rc_map_register(&cinergy_map);
}
static void __exit exit_rc_map_cinergy(void)
{
- ir_unregister_map(&cinergy_map);
+ rc_map_unregister(&cinergy_map);
}
module_init(init_rc_map_cinergy)
diff --git a/drivers/media/IR/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c
index ae1832038fbe..c59851b203da 100644
--- a/drivers/media/IR/keymaps/rc-dib0700-nec.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c
@@ -17,7 +17,7 @@
#include <media/rc-map.h>
-static struct ir_scancode dib0700_nec_table[] = {
+static struct rc_map_table dib0700_nec_table[] = {
/* Key codes for the Pixelview SBTVD remote */
{ 0x8613, KEY_MUTE },
{ 0x8612, KEY_POWER },
@@ -98,23 +98,23 @@ static struct ir_scancode dib0700_nec_table[] = {
{ 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */
};
-static struct rc_keymap dib0700_nec_map = {
+static struct rc_map_list dib0700_nec_map = {
.map = {
.scan = dib0700_nec_table,
.size = ARRAY_SIZE(dib0700_nec_table),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIB0700_NEC_TABLE,
}
};
static int __init init_rc_map(void)
{
- return ir_register_map(&dib0700_nec_map);
+ return rc_map_register(&dib0700_nec_map);
}
static void __exit exit_rc_map(void)
{
- ir_unregister_map(&dib0700_nec_map);
+ rc_map_unregister(&dib0700_nec_map);
}
module_init(init_rc_map)
diff --git a/drivers/media/IR/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
index 4a4797cfd77d..4af12e45dfba 100644
--- a/drivers/media/IR/keymaps/rc-dib0700-rc5.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
@@ -17,7 +17,7 @@
#include <media/rc-map.h>
-static struct ir_scancode dib0700_rc5_table[] = {
+static struct rc_map_table dib0700_rc5_table[] = {
/* Key codes for the tiny Pinnacle remote*/
{ 0x0700, KEY_MUTE },
{ 0x0701, KEY_MENU }, /* Pinnacle logo */
@@ -209,23 +209,23 @@ static struct ir_scancode dib0700_rc5_table[] = {
{ 0x1d3d, KEY_POWER },
};
-static struct rc_keymap dib0700_rc5_map = {
+static struct rc_map_list dib0700_rc5_map = {
.map = {
.scan = dib0700_rc5_table,
.size = ARRAY_SIZE(dib0700_rc5_table),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_DIB0700_RC5_TABLE,
}
};
static int __init init_rc_map(void)
{
- return ir_register_map(&dib0700_rc5_map);
+ return rc_map_register(&dib0700_rc5_map);
}
static void __exit exit_rc_map(void)
{
- ir_unregister_map(&dib0700_rc5_map);
+ rc_map_unregister(&dib0700_rc5_map);
}
module_init(init_rc_map)
diff --git a/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
index 63e469e2dd21..f68b450f5593 100644
--- a/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c
+++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode digitalnow_tinytwin[] = {
+static struct rc_map_table digitalnow_tinytwin[] = {
{ 0x0000, KEY_MUTE }, /* [symbol speaker] */
{ 0x0001, KEY_VOLUMEUP },
{ 0x0002, KEY_POWER2 }, /* TV [power button] */
@@ -72,23 +72,23 @@ static struct ir_scancode digitalnow_tinytwin[] = {
{ 0x005a, KEY_PREVIOUS }, /* REPLAY */
};
-static struct rc_keymap digitalnow_tinytwin_map = {
+static struct rc_map_list digitalnow_tinytwin_map = {
.map = {
.scan = digitalnow_tinytwin,
.size = ARRAY_SIZE(digitalnow_tinytwin),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIGITALNOW_TINYTWIN,
}
};
static int __init init_rc_map_digitalnow_tinytwin(void)
{
- return ir_register_map(&digitalnow_tinytwin_map);
+ return rc_map_register(&digitalnow_tinytwin_map);
}
static void __exit exit_rc_map_digitalnow_tinytwin(void)
{
- ir_unregister_map(&digitalnow_tinytwin_map);
+ rc_map_unregister(&digitalnow_tinytwin_map);
}
module_init(init_rc_map_digitalnow_tinytwin)
diff --git a/drivers/media/IR/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c
index 5dece78e19c5..21d49871f2a3 100644
--- a/drivers/media/IR/keymaps/rc-digittrade.c
+++ b/drivers/media/rc/keymaps/rc-digittrade.c
@@ -25,7 +25,7 @@
Initial keytable was from Alain Kalker <miki@dds.nl> */
/* Digittrade DVB-T USB Stick */
-static struct ir_scancode digittrade[] = {
+static struct rc_map_table digittrade[] = {
{ 0x0000, KEY_9 },
{ 0x0001, KEY_EPG }, /* EPG */
{ 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */
@@ -56,23 +56,23 @@ static struct ir_scancode digittrade[] = {
{ 0x0054, KEY_0 },
};
-static struct rc_keymap digittrade_map = {
+static struct rc_map_list digittrade_map = {
.map = {
.scan = digittrade,
.size = ARRAY_SIZE(digittrade),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIGITTRADE,
}
};
static int __init init_rc_map_digittrade(void)
{
- return ir_register_map(&digittrade_map);
+ return rc_map_register(&digittrade_map);
}
static void __exit exit_rc_map_digittrade(void)
{
- ir_unregister_map(&digittrade_map);
+ rc_map_unregister(&digittrade_map);
}
module_init(init_rc_map_digittrade)
diff --git a/drivers/media/IR/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c
index 90684d0efea3..d024fbf88bc4 100644
--- a/drivers/media/IR/keymaps/rc-dm1105-nec.c
+++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c
@@ -16,7 +16,7 @@
Igor M. Liplianin <liplianin@me.by>
*/
-static struct ir_scancode dm1105_nec[] = {
+static struct rc_map_table dm1105_nec[] = {
{ 0x0a, KEY_POWER2}, /* power */
{ 0x0c, KEY_MUTE}, /* mute */
{ 0x11, KEY_1},
@@ -50,23 +50,23 @@ static struct ir_scancode dm1105_nec[] = {
{ 0x1b, KEY_B}, /* recall */
};
-static struct rc_keymap dm1105_nec_map = {
+static struct rc_map_list dm1105_nec_map = {
.map = {
.scan = dm1105_nec,
.size = ARRAY_SIZE(dm1105_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DM1105_NEC,
}
};
static int __init init_rc_map_dm1105_nec(void)
{
- return ir_register_map(&dm1105_nec_map);
+ return rc_map_register(&dm1105_nec_map);
}
static void __exit exit_rc_map_dm1105_nec(void)
{
- ir_unregister_map(&dm1105_nec_map);
+ rc_map_unregister(&dm1105_nec_map);
}
module_init(init_rc_map_dm1105_nec)
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 8a4027af964a..43912bd02a9e 100644
--- a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -14,7 +14,7 @@
/* DigitalNow DNTV Live DVB-T Remote */
-static struct ir_scancode dntv_live_dvb_t[] = {
+static struct rc_map_table dntv_live_dvb_t[] = {
{ 0x00, KEY_ESC }, /* 'go up a level?' */
/* Keys 0 to 9 */
{ 0x0a, KEY_0 },
@@ -52,23 +52,23 @@ static struct ir_scancode dntv_live_dvb_t[] = {
{ 0x1f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap dntv_live_dvb_t_map = {
+static struct rc_map_list dntv_live_dvb_t_map = {
.map = {
.scan = dntv_live_dvb_t,
.size = ARRAY_SIZE(dntv_live_dvb_t),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DNTV_LIVE_DVB_T,
}
};
static int __init init_rc_map_dntv_live_dvb_t(void)
{
- return ir_register_map(&dntv_live_dvb_t_map);
+ return rc_map_register(&dntv_live_dvb_t_map);
}
static void __exit exit_rc_map_dntv_live_dvb_t(void)
{
- ir_unregister_map(&dntv_live_dvb_t_map);
+ rc_map_unregister(&dntv_live_dvb_t_map);
}
module_init(init_rc_map_dntv_live_dvb_t)
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
index 6f4d60764d59..015e99de06de 100644
--- a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
@@ -14,7 +14,7 @@
/* DigitalNow DNTV Live! DVB-T Pro Remote */
-static struct ir_scancode dntv_live_dvbt_pro[] = {
+static struct rc_map_table dntv_live_dvbt_pro[] = {
{ 0x16, KEY_POWER },
{ 0x5b, KEY_HOME },
@@ -71,23 +71,23 @@ static struct ir_scancode dntv_live_dvbt_pro[] = {
{ 0x5d, KEY_BLUE },
};
-static struct rc_keymap dntv_live_dvbt_pro_map = {
+static struct rc_map_list dntv_live_dvbt_pro_map = {
.map = {
.scan = dntv_live_dvbt_pro,
.size = ARRAY_SIZE(dntv_live_dvbt_pro),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DNTV_LIVE_DVBT_PRO,
}
};
static int __init init_rc_map_dntv_live_dvbt_pro(void)
{
- return ir_register_map(&dntv_live_dvbt_pro_map);
+ return rc_map_register(&dntv_live_dvbt_pro_map);
}
static void __exit exit_rc_map_dntv_live_dvbt_pro(void)
{
- ir_unregister_map(&dntv_live_dvbt_pro_map);
+ rc_map_unregister(&dntv_live_dvbt_pro_map);
}
module_init(init_rc_map_dntv_live_dvbt_pro)
diff --git a/drivers/media/IR/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c
index 3130c9c29e6b..269d4299da34 100644
--- a/drivers/media/IR/keymaps/rc-em-terratec.c
+++ b/drivers/media/rc/keymaps/rc-em-terratec.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode em_terratec[] = {
+static struct rc_map_table em_terratec[] = {
{ 0x01, KEY_CHANNEL },
{ 0x02, KEY_SELECT },
{ 0x03, KEY_MUTE },
@@ -43,23 +43,23 @@ static struct ir_scancode em_terratec[] = {
{ 0x40, KEY_ZOOM },
};
-static struct rc_keymap em_terratec_map = {
+static struct rc_map_list em_terratec_map = {
.map = {
.scan = em_terratec,
.size = ARRAY_SIZE(em_terratec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EM_TERRATEC,
}
};
static int __init init_rc_map_em_terratec(void)
{
- return ir_register_map(&em_terratec_map);
+ return rc_map_register(&em_terratec_map);
}
static void __exit exit_rc_map_em_terratec(void)
{
- ir_unregister_map(&em_terratec_map);
+ rc_map_unregister(&em_terratec_map);
}
module_init(init_rc_map_em_terratec)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
index 4b816967877e..e388698a0697 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode encore_enltv_fm53[] = {
+static struct rc_map_table encore_enltv_fm53[] = {
{ 0x10, KEY_POWER2},
{ 0x06, KEY_MUTE},
@@ -55,23 +55,23 @@ static struct ir_scancode encore_enltv_fm53[] = {
{ 0x47, KEY_SLEEP}, /* shutdown */
};
-static struct rc_keymap encore_enltv_fm53_map = {
+static struct rc_map_list encore_enltv_fm53_map = {
.map = {
.scan = encore_enltv_fm53,
.size = ARRAY_SIZE(encore_enltv_fm53),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV_FM53,
}
};
static int __init init_rc_map_encore_enltv_fm53(void)
{
- return ir_register_map(&encore_enltv_fm53_map);
+ return rc_map_register(&encore_enltv_fm53_map);
}
static void __exit exit_rc_map_encore_enltv_fm53(void)
{
- ir_unregister_map(&encore_enltv_fm53_map);
+ rc_map_unregister(&encore_enltv_fm53_map);
}
module_init(init_rc_map_encore_enltv_fm53)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index 9fabffd28cc9..afa4e92284ef 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -15,7 +15,7 @@
/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
Juan Pablo Sormani <sorman@gmail.com> */
-static struct ir_scancode encore_enltv[] = {
+static struct rc_map_table encore_enltv[] = {
/* Power button does nothing, neither in Windows app,
although it sends data (used for BIOS wakeup?) */
@@ -86,23 +86,23 @@ static struct ir_scancode encore_enltv[] = {
{ 0x57, KEY_BLUE }, /* AP4 */
};
-static struct rc_keymap encore_enltv_map = {
+static struct rc_map_list encore_enltv_map = {
.map = {
.scan = encore_enltv,
.size = ARRAY_SIZE(encore_enltv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV,
}
};
static int __init init_rc_map_encore_enltv(void)
{
- return ir_register_map(&encore_enltv_map);
+ return rc_map_register(&encore_enltv_map);
}
static void __exit exit_rc_map_encore_enltv(void)
{
- ir_unregister_map(&encore_enltv_map);
+ rc_map_unregister(&encore_enltv_map);
}
module_init(init_rc_map_encore_enltv)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index efefd5166618..7d5b00ed4ff2 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -15,7 +15,7 @@
/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
Mauro Carvalho Chehab <mchehab@infradead.org> */
-static struct ir_scancode encore_enltv2[] = {
+static struct rc_map_table encore_enltv2[] = {
{ 0x4c, KEY_POWER2 },
{ 0x4a, KEY_TUNER },
{ 0x40, KEY_1 },
@@ -64,23 +64,23 @@ static struct ir_scancode encore_enltv2[] = {
{ 0x79, KEY_STOP },
};
-static struct rc_keymap encore_enltv2_map = {
+static struct rc_map_list encore_enltv2_map = {
.map = {
.scan = encore_enltv2,
.size = ARRAY_SIZE(encore_enltv2),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV2,
}
};
static int __init init_rc_map_encore_enltv2(void)
{
- return ir_register_map(&encore_enltv2_map);
+ return rc_map_register(&encore_enltv2_map);
}
static void __exit exit_rc_map_encore_enltv2(void)
{
- ir_unregister_map(&encore_enltv2_map);
+ rc_map_unregister(&encore_enltv2_map);
}
module_init(init_rc_map_encore_enltv2)
diff --git a/drivers/media/IR/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c
index 3f3fb13813b3..a2bf24f6dfbb 100644
--- a/drivers/media/IR/keymaps/rc-evga-indtube.c
+++ b/drivers/media/rc/keymaps/rc-evga-indtube.c
@@ -16,7 +16,7 @@
Devin Heitmueller <devin.heitmueller@gmail.com>
*/
-static struct ir_scancode evga_indtube[] = {
+static struct rc_map_table evga_indtube[] = {
{ 0x12, KEY_POWER},
{ 0x02, KEY_MODE}, /* TV */
{ 0x14, KEY_MUTE},
@@ -35,23 +35,23 @@ static struct ir_scancode evga_indtube[] = {
{ 0x13, KEY_CAMERA},
};
-static struct rc_keymap evga_indtube_map = {
+static struct rc_map_list evga_indtube_map = {
.map = {
.scan = evga_indtube,
.size = ARRAY_SIZE(evga_indtube),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EVGA_INDTUBE,
}
};
static int __init init_rc_map_evga_indtube(void)
{
- return ir_register_map(&evga_indtube_map);
+ return rc_map_register(&evga_indtube_map);
}
static void __exit exit_rc_map_evga_indtube(void)
{
- ir_unregister_map(&evga_indtube_map);
+ rc_map_unregister(&evga_indtube_map);
}
module_init(init_rc_map_evga_indtube)
diff --git a/drivers/media/IR/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c
index 660907a78db9..1e8e5b2d6e36 100644
--- a/drivers/media/IR/keymaps/rc-eztv.c
+++ b/drivers/media/rc/keymaps/rc-eztv.c
@@ -15,7 +15,7 @@
/* Alfons Geser <a.geser@cox.net>
* updates from Job D. R. Borges <jobdrb@ig.com.br> */
-static struct ir_scancode eztv[] = {
+static struct rc_map_table eztv[] = {
{ 0x12, KEY_POWER },
{ 0x01, KEY_TV }, /* DVR */
{ 0x15, KEY_DVD }, /* DVD */
@@ -70,23 +70,23 @@ static struct ir_scancode eztv[] = {
{ 0x21, KEY_DOT }, /* . (decimal dot) */
};
-static struct rc_keymap eztv_map = {
+static struct rc_map_list eztv_map = {
.map = {
.scan = eztv,
.size = ARRAY_SIZE(eztv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EZTV,
}
};
static int __init init_rc_map_eztv(void)
{
- return ir_register_map(&eztv_map);
+ return rc_map_register(&eztv_map);
}
static void __exit exit_rc_map_eztv(void)
{
- ir_unregister_map(&eztv_map);
+ rc_map_unregister(&eztv_map);
}
module_init(init_rc_map_eztv)
diff --git a/drivers/media/IR/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index a173c81035f4..aea2f4acf7d8 100644
--- a/drivers/media/IR/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode flydvb[] = {
+static struct rc_map_table flydvb[] = {
{ 0x01, KEY_ZOOM }, /* Full Screen */
{ 0x00, KEY_POWER }, /* Power */
@@ -51,23 +51,23 @@ static struct ir_scancode flydvb[] = {
{ 0x0e, KEY_NEXT }, /* End >>| */
};
-static struct rc_keymap flydvb_map = {
+static struct rc_map_list flydvb_map = {
.map = {
.scan = flydvb,
.size = ARRAY_SIZE(flydvb),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FLYDVB,
}
};
static int __init init_rc_map_flydvb(void)
{
- return ir_register_map(&flydvb_map);
+ return rc_map_register(&flydvb_map);
}
static void __exit exit_rc_map_flydvb(void)
{
- ir_unregister_map(&flydvb_map);
+ rc_map_unregister(&flydvb_map);
}
module_init(init_rc_map_flydvb)
diff --git a/drivers/media/IR/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c
index 9c73043cbdba..5bbe68371756 100644
--- a/drivers/media/IR/keymaps/rc-flyvideo.c
+++ b/drivers/media/rc/keymaps/rc-flyvideo.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode flyvideo[] = {
+static struct rc_map_table flyvideo[] = {
{ 0x0f, KEY_0 },
{ 0x03, KEY_1 },
{ 0x04, KEY_2 },
@@ -44,23 +44,23 @@ static struct ir_scancode flyvideo[] = {
{ 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
};
-static struct rc_keymap flyvideo_map = {
+static struct rc_map_list flyvideo_map = {
.map = {
.scan = flyvideo,
.size = ARRAY_SIZE(flyvideo),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FLYVIDEO,
}
};
static int __init init_rc_map_flyvideo(void)
{
- return ir_register_map(&flyvideo_map);
+ return rc_map_register(&flyvideo_map);
}
static void __exit exit_rc_map_flyvideo(void)
{
- ir_unregister_map(&flyvideo_map);
+ rc_map_unregister(&flyvideo_map);
}
module_init(init_rc_map_flyvideo)
diff --git a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
index cdb10389b10e..c80b25c65b57 100644
--- a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
+++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
@@ -14,7 +14,7 @@
/* DViCO FUSION HDTV MCE remote */
-static struct ir_scancode fusionhdtv_mce[] = {
+static struct rc_map_table fusionhdtv_mce[] = {
{ 0x0b, KEY_1 },
{ 0x17, KEY_2 },
@@ -72,23 +72,23 @@ static struct ir_scancode fusionhdtv_mce[] = {
{ 0x4e, KEY_POWER },
};
-static struct rc_keymap fusionhdtv_mce_map = {
+static struct rc_map_list fusionhdtv_mce_map = {
.map = {
.scan = fusionhdtv_mce,
.size = ARRAY_SIZE(fusionhdtv_mce),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FUSIONHDTV_MCE,
}
};
static int __init init_rc_map_fusionhdtv_mce(void)
{
- return ir_register_map(&fusionhdtv_mce_map);
+ return rc_map_register(&fusionhdtv_mce_map);
}
static void __exit exit_rc_map_fusionhdtv_mce(void)
{
- ir_unregister_map(&fusionhdtv_mce_map);
+ rc_map_unregister(&fusionhdtv_mce_map);
}
module_init(init_rc_map_fusionhdtv_mce)
diff --git a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
index c16c0d1263ac..068c9ead98dd 100644
--- a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
+++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
@@ -16,7 +16,7 @@
Shine Liu <shinel@foxmail.com>
*/
-static struct ir_scancode gadmei_rm008z[] = {
+static struct rc_map_table gadmei_rm008z[] = {
{ 0x14, KEY_POWER2}, /* POWER OFF */
{ 0x0c, KEY_MUTE}, /* MUTE */
@@ -55,23 +55,23 @@ static struct ir_scancode gadmei_rm008z[] = {
{ 0x15, KEY_ENTER}, /* OK */
};
-static struct rc_keymap gadmei_rm008z_map = {
+static struct rc_map_list gadmei_rm008z_map = {
.map = {
.scan = gadmei_rm008z,
.size = ARRAY_SIZE(gadmei_rm008z),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GADMEI_RM008Z,
}
};
static int __init init_rc_map_gadmei_rm008z(void)
{
- return ir_register_map(&gadmei_rm008z_map);
+ return rc_map_register(&gadmei_rm008z_map);
}
static void __exit exit_rc_map_gadmei_rm008z(void)
{
- ir_unregister_map(&gadmei_rm008z_map);
+ rc_map_unregister(&gadmei_rm008z_map);
}
module_init(init_rc_map_gadmei_rm008z)
diff --git a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
index 89f8e384e52a..cdbbed467926 100644
--- a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
+++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
@@ -17,7 +17,7 @@
* Adrian Pardini <pardo.bsso@gmail.com>
*/
-static struct ir_scancode genius_tvgo_a11mce[] = {
+static struct rc_map_table genius_tvgo_a11mce[] = {
/* Keys 0 to 9 */
{ 0x48, KEY_0 },
{ 0x09, KEY_1 },
@@ -58,23 +58,23 @@ static struct ir_scancode genius_tvgo_a11mce[] = {
{ 0x50, KEY_BLUE },
};
-static struct rc_keymap genius_tvgo_a11mce_map = {
+static struct rc_map_list genius_tvgo_a11mce_map = {
.map = {
.scan = genius_tvgo_a11mce,
.size = ARRAY_SIZE(genius_tvgo_a11mce),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GENIUS_TVGO_A11MCE,
}
};
static int __init init_rc_map_genius_tvgo_a11mce(void)
{
- return ir_register_map(&genius_tvgo_a11mce_map);
+ return rc_map_register(&genius_tvgo_a11mce_map);
}
static void __exit exit_rc_map_genius_tvgo_a11mce(void)
{
- ir_unregister_map(&genius_tvgo_a11mce_map);
+ rc_map_unregister(&genius_tvgo_a11mce_map);
}
module_init(init_rc_map_genius_tvgo_a11mce)
diff --git a/drivers/media/IR/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c
index 52f025bb35f6..a38bdde8c140 100644
--- a/drivers/media/IR/keymaps/rc-gotview7135.c
+++ b/drivers/media/rc/keymaps/rc-gotview7135.c
@@ -14,7 +14,7 @@
/* Mike Baikov <mike@baikov.com> */
-static struct ir_scancode gotview7135[] = {
+static struct rc_map_table gotview7135[] = {
{ 0x11, KEY_POWER },
{ 0x35, KEY_TV },
@@ -53,23 +53,23 @@ static struct ir_scancode gotview7135[] = {
{ 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
};
-static struct rc_keymap gotview7135_map = {
+static struct rc_map_list gotview7135_map = {
.map = {
.scan = gotview7135,
.size = ARRAY_SIZE(gotview7135),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GOTVIEW7135,
}
};
static int __init init_rc_map_gotview7135(void)
{
- return ir_register_map(&gotview7135_map);
+ return rc_map_register(&gotview7135_map);
}
static void __exit exit_rc_map_gotview7135(void)
{
- ir_unregister_map(&gotview7135_map);
+ rc_map_unregister(&gotview7135_map);
}
module_init(init_rc_map_gotview7135)
diff --git a/drivers/media/IR/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c
index c6f8cd7c5186..bd11da46e56a 100644
--- a/drivers/media/IR/keymaps/rc-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c
@@ -16,7 +16,7 @@
* slightly different versions), shipped with cx88+ivtv cards.
* almost rc5 coding, but some non-standard keys */
-static struct ir_scancode hauppauge_new[] = {
+static struct rc_map_table hauppauge_new[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -74,23 +74,23 @@ static struct ir_scancode hauppauge_new[] = {
{ 0x3d, KEY_POWER }, /* system power (green button) */
};
-static struct rc_keymap hauppauge_new_map = {
+static struct rc_map_list hauppauge_new_map = {
.map = {
.scan = hauppauge_new,
.size = ARRAY_SIZE(hauppauge_new),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_HAUPPAUGE_NEW,
}
};
static int __init init_rc_map_hauppauge_new(void)
{
- return ir_register_map(&hauppauge_new_map);
+ return rc_map_register(&hauppauge_new_map);
}
static void __exit exit_rc_map_hauppauge_new(void)
{
- ir_unregister_map(&hauppauge_new_map);
+ rc_map_unregister(&hauppauge_new_map);
}
module_init(init_rc_map_hauppauge_new)
diff --git a/drivers/media/IR/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c
index e49f350e3a0d..cb67184e015c 100644
--- a/drivers/media/IR/keymaps/rc-imon-mce.c
+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
/* mce-mode imon mce remote key table */
-static struct ir_scancode imon_mce[] = {
+static struct rc_map_table imon_mce[] = {
/* keys sorted mostly by frequency of use to optimize lookups */
{ 0x800ff415, KEY_REWIND },
{ 0x800ff414, KEY_FASTFORWARD },
@@ -115,24 +115,24 @@ static struct ir_scancode imon_mce[] = {
};
-static struct rc_keymap imon_mce_map = {
+static struct rc_map_list imon_mce_map = {
.map = {
.scan = imon_mce,
.size = ARRAY_SIZE(imon_mce),
/* its RC6, but w/a hardware decoder */
- .ir_type = IR_TYPE_RC6,
+ .rc_type = RC_TYPE_RC6,
.name = RC_MAP_IMON_MCE,
}
};
static int __init init_rc_map_imon_mce(void)
{
- return ir_register_map(&imon_mce_map);
+ return rc_map_register(&imon_mce_map);
}
static void __exit exit_rc_map_imon_mce(void)
{
- ir_unregister_map(&imon_mce_map);
+ rc_map_unregister(&imon_mce_map);
}
module_init(init_rc_map_imon_mce)
diff --git a/drivers/media/IR/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c
index bc4db72f02e6..eef46b73ca7b 100644
--- a/drivers/media/IR/keymaps/rc-imon-pad.c
+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
@@ -17,7 +17,7 @@
* same remote to different hex codes, and the silkscreened names
* vary a bit between the SoundGraph and Antec remotes... ugh.
*/
-static struct ir_scancode imon_pad[] = {
+static struct rc_map_table imon_pad[] = {
/* keys sorted mostly by frequency of use to optimize lookups */
{ 0x2a8195b7, KEY_REWIND },
{ 0x298315b7, KEY_REWIND },
@@ -129,24 +129,24 @@ static struct ir_scancode imon_pad[] = {
{ 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
};
-static struct rc_keymap imon_pad_map = {
+static struct rc_map_list imon_pad_map = {
.map = {
.scan = imon_pad,
.size = ARRAY_SIZE(imon_pad),
/* actual protocol details unknown, hardware decoder */
- .ir_type = IR_TYPE_OTHER,
+ .rc_type = RC_TYPE_OTHER,
.name = RC_MAP_IMON_PAD,
}
};
static int __init init_rc_map_imon_pad(void)
{
- return ir_register_map(&imon_pad_map);
+ return rc_map_register(&imon_pad_map);
}
static void __exit exit_rc_map_imon_pad(void)
{
- ir_unregister_map(&imon_pad_map);
+ rc_map_unregister(&imon_pad_map);
}
module_init(init_rc_map_imon_pad)
diff --git a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
index ef6600259fc0..1f59e163f75d 100644
--- a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
+++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
@@ -14,7 +14,7 @@
/* IO-DATA BCTV7E Remote */
-static struct ir_scancode iodata_bctv7e[] = {
+static struct rc_map_table iodata_bctv7e[] = {
{ 0x40, KEY_TV },
{ 0x20, KEY_RADIO }, /* FM */
{ 0x60, KEY_EPG },
@@ -62,23 +62,23 @@ static struct ir_scancode iodata_bctv7e[] = {
{ 0x01, KEY_NEXT }, /* skip >| */
};
-static struct rc_keymap iodata_bctv7e_map = {
+static struct rc_map_list iodata_bctv7e_map = {
.map = {
.scan = iodata_bctv7e,
.size = ARRAY_SIZE(iodata_bctv7e),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_IODATA_BCTV7E,
}
};
static int __init init_rc_map_iodata_bctv7e(void)
{
- return ir_register_map(&iodata_bctv7e_map);
+ return rc_map_register(&iodata_bctv7e_map);
}
static void __exit exit_rc_map_iodata_bctv7e(void)
{
- ir_unregister_map(&iodata_bctv7e_map);
+ rc_map_unregister(&iodata_bctv7e_map);
}
module_init(init_rc_map_iodata_bctv7e)
diff --git a/drivers/media/IR/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c
index 4c7883ba0f15..f31dc5c1ad9c 100644
--- a/drivers/media/IR/keymaps/rc-kaiomy.c
+++ b/drivers/media/rc/keymaps/rc-kaiomy.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode kaiomy[] = {
+static struct rc_map_table kaiomy[] = {
{ 0x43, KEY_POWER2},
{ 0x01, KEY_LIST},
{ 0x0b, KEY_ZOOM},
@@ -61,23 +61,23 @@ static struct ir_scancode kaiomy[] = {
{ 0x1f, KEY_BLUE},
};
-static struct rc_keymap kaiomy_map = {
+static struct rc_map_list kaiomy_map = {
.map = {
.scan = kaiomy,
.size = ARRAY_SIZE(kaiomy),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_KAIOMY,
}
};
static int __init init_rc_map_kaiomy(void)
{
- return ir_register_map(&kaiomy_map);
+ return rc_map_register(&kaiomy_map);
}
static void __exit exit_rc_map_kaiomy(void)
{
- ir_unregister_map(&kaiomy_map);
+ rc_map_unregister(&kaiomy_map);
}
module_init(init_rc_map_kaiomy)
diff --git a/drivers/media/IR/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 618c817374e6..3ce6ef79fc34 100644
--- a/drivers/media/IR/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -15,7 +15,7 @@
/* Kworld 315U
*/
-static struct ir_scancode kworld_315u[] = {
+static struct rc_map_table kworld_315u[] = {
{ 0x6143, KEY_POWER },
{ 0x6101, KEY_TUNER }, /* source */
{ 0x610b, KEY_ZOOM },
@@ -57,23 +57,23 @@ static struct ir_scancode kworld_315u[] = {
{ 0x611f, KEY_BLUE },
};
-static struct rc_keymap kworld_315u_map = {
+static struct rc_map_list kworld_315u_map = {
.map = {
.scan = kworld_315u,
.size = ARRAY_SIZE(kworld_315u),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_KWORLD_315U,
}
};
static int __init init_rc_map_kworld_315u(void)
{
- return ir_register_map(&kworld_315u_map);
+ return rc_map_register(&kworld_315u_map);
}
static void __exit exit_rc_map_kworld_315u(void)
{
- ir_unregister_map(&kworld_315u_map);
+ rc_map_unregister(&kworld_315u_map);
}
module_init(init_rc_map_kworld_315u)
diff --git a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index 366732f1f7b7..e45f0b8759d0 100644
--- a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode kworld_plus_tv_analog[] = {
+static struct rc_map_table kworld_plus_tv_analog[] = {
{ 0x0c, KEY_PROG1 }, /* Kworld key */
{ 0x16, KEY_CLOSECD }, /* -> ) */
{ 0x1d, KEY_POWER2 },
@@ -73,23 +73,23 @@ static struct ir_scancode kworld_plus_tv_analog[] = {
{ 0x23, KEY_GREEN}, /* C */
};
-static struct rc_keymap kworld_plus_tv_analog_map = {
+static struct rc_map_list kworld_plus_tv_analog_map = {
.map = {
.scan = kworld_plus_tv_analog,
.size = ARRAY_SIZE(kworld_plus_tv_analog),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_KWORLD_PLUS_TV_ANALOG,
}
};
static int __init init_rc_map_kworld_plus_tv_analog(void)
{
- return ir_register_map(&kworld_plus_tv_analog_map);
+ return rc_map_register(&kworld_plus_tv_analog_map);
}
static void __exit exit_rc_map_kworld_plus_tv_analog(void)
{
- ir_unregister_map(&kworld_plus_tv_analog_map);
+ rc_map_unregister(&kworld_plus_tv_analog_map);
}
module_init(init_rc_map_kworld_plus_tv_analog)
diff --git a/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
index 7521315fd876..8faa54ff16e6 100644
--- a/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c
+++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode leadtek_y04g0051[] = {
+static struct rc_map_table leadtek_y04g0051[] = {
{ 0x0300, KEY_POWER2 },
{ 0x0303, KEY_SCREEN },
{ 0x0304, KEY_RIGHT },
@@ -73,23 +73,23 @@ static struct ir_scancode leadtek_y04g0051[] = {
{ 0x035f, KEY_CHANNELDOWN },
};
-static struct rc_keymap leadtek_y04g0051_map = {
+static struct rc_map_list leadtek_y04g0051_map = {
.map = {
.scan = leadtek_y04g0051,
.size = ARRAY_SIZE(leadtek_y04g0051),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_LEADTEK_Y04G0051,
}
};
static int __init init_rc_map_leadtek_y04g0051(void)
{
- return ir_register_map(&leadtek_y04g0051_map);
+ return rc_map_register(&leadtek_y04g0051_map);
}
static void __exit exit_rc_map_leadtek_y04g0051(void)
{
- ir_unregister_map(&leadtek_y04g0051_map);
+ rc_map_unregister(&leadtek_y04g0051_map);
}
module_init(init_rc_map_leadtek_y04g0051)
diff --git a/drivers/media/IR/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c
index 43fcf9035082..e8e23e233c39 100644
--- a/drivers/media/IR/keymaps/rc-lirc.c
+++ b/drivers/media/rc/keymaps/rc-lirc.c
@@ -9,29 +9,29 @@
* (at your option) any later version.
*/
-#include <media/ir-core.h>
+#include <media/rc-core.h>
-static struct ir_scancode lirc[] = {
+static struct rc_map_table lirc[] = {
{ },
};
-static struct rc_keymap lirc_map = {
+static struct rc_map_list lirc_map = {
.map = {
.scan = lirc,
.size = ARRAY_SIZE(lirc),
- .ir_type = IR_TYPE_LIRC,
+ .rc_type = RC_TYPE_LIRC,
.name = RC_MAP_LIRC,
}
};
static int __init init_rc_map_lirc(void)
{
- return ir_register_map(&lirc_map);
+ return rc_map_register(&lirc_map);
}
static void __exit exit_rc_map_lirc(void)
{
- ir_unregister_map(&lirc_map);
+ rc_map_unregister(&lirc_map);
}
module_init(init_rc_map_lirc)
diff --git a/drivers/media/IR/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c
index 40dcf0b4e21a..875cd81477c7 100644
--- a/drivers/media/IR/keymaps/rc-lme2510.c
+++ b/drivers/media/rc/keymaps/rc-lme2510.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode lme2510_rc[] = {
+static struct rc_map_table lme2510_rc[] = {
{ 0xba45, KEY_0 },
{ 0xa05f, KEY_1 },
{ 0xaf50, KEY_2 },
@@ -42,23 +42,23 @@ static struct ir_scancode lme2510_rc[] = {
};
-static struct rc_keymap lme2510_map = {
+static struct rc_map_list lme2510_map = {
.map = {
.scan = lme2510_rc,
.size = ARRAY_SIZE(lme2510_rc),
- .ir_type = IR_TYPE_UNKNOWN,
+ .rc_type = RC_TYPE_UNKNOWN,
.name = RC_MAP_LME2510,
}
};
static int __init init_rc_lme2510_map(void)
{
- return ir_register_map(&lme2510_map);
+ return rc_map_register(&lme2510_map);
}
static void __exit exit_rc_lme2510_map(void)
{
- ir_unregister_map(&lme2510_map);
+ rc_map_unregister(&lme2510_map);
}
module_init(init_rc_lme2510_map)
diff --git a/drivers/media/IR/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c
index 0f590b3d01c0..23b2d04e7a9f 100644
--- a/drivers/media/IR/keymaps/rc-manli.c
+++ b/drivers/media/rc/keymaps/rc-manli.c
@@ -21,7 +21,7 @@
helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode manli[] = {
+static struct rc_map_table manli[] = {
/* 0x1c 0x12 *
* FUNCTION POWER *
@@ -108,23 +108,23 @@ static struct ir_scancode manli[] = {
/* 0x1d unused ? */
};
-static struct rc_keymap manli_map = {
+static struct rc_map_list manli_map = {
.map = {
.scan = manli,
.size = ARRAY_SIZE(manli),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MANLI,
}
};
static int __init init_rc_map_manli(void)
{
- return ir_register_map(&manli_map);
+ return rc_map_register(&manli_map);
}
static void __exit exit_rc_map_manli(void)
{
- ir_unregister_map(&manli_map);
+ rc_map_unregister(&manli_map);
}
module_init(init_rc_map_manli)
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
index 67237fbf9e4b..7b9a01b6e4cf 100644
--- a/drivers/media/IR/keymaps/rc-msi-digivox-ii.c
+++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode msi_digivox_ii[] = {
+static struct rc_map_table msi_digivox_ii[] = {
{ 0x0002, KEY_2 },
{ 0x0003, KEY_UP }, /* up */
{ 0x0004, KEY_3 },
@@ -41,23 +41,23 @@ static struct ir_scancode msi_digivox_ii[] = {
{ 0x001f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap msi_digivox_ii_map = {
+static struct rc_map_list msi_digivox_ii_map = {
.map = {
.scan = msi_digivox_ii,
.size = ARRAY_SIZE(msi_digivox_ii),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_II,
}
};
static int __init init_rc_map_msi_digivox_ii(void)
{
- return ir_register_map(&msi_digivox_ii_map);
+ return rc_map_register(&msi_digivox_ii_map);
}
static void __exit exit_rc_map_msi_digivox_ii(void)
{
- ir_unregister_map(&msi_digivox_ii_map);
+ rc_map_unregister(&msi_digivox_ii_map);
}
module_init(init_rc_map_msi_digivox_ii)
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c
index 882056e52ef9..ae9d06b39157 100644
--- a/drivers/media/IR/keymaps/rc-msi-digivox-iii.c
+++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c
@@ -24,7 +24,7 @@
/* Uses NEC extended 0x61d6. */
/* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote
since rc-kworld-315u.c lacks NEC extended address byte. */
-static struct ir_scancode msi_digivox_iii[] = {
+static struct rc_map_table msi_digivox_iii[] = {
{ 0x61d601, KEY_VIDEO }, /* Source */
{ 0x61d602, KEY_3 },
{ 0x61d603, KEY_POWER }, /* ShutDown */
@@ -59,23 +59,23 @@ static struct ir_scancode msi_digivox_iii[] = {
{ 0x61d643, KEY_POWER2 }, /* [red power button] */
};
-static struct rc_keymap msi_digivox_iii_map = {
+static struct rc_map_list msi_digivox_iii_map = {
.map = {
.scan = msi_digivox_iii,
.size = ARRAY_SIZE(msi_digivox_iii),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_III,
}
};
static int __init init_rc_map_msi_digivox_iii(void)
{
- return ir_register_map(&msi_digivox_iii_map);
+ return rc_map_register(&msi_digivox_iii_map);
}
static void __exit exit_rc_map_msi_digivox_iii(void)
{
- ir_unregister_map(&msi_digivox_iii_map);
+ rc_map_unregister(&msi_digivox_iii_map);
}
module_init(init_rc_map_msi_digivox_iii)
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index eb8e42c18ff9..fa8fd0ab94c7 100644
--- a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -26,7 +26,7 @@
Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
*/
-static struct ir_scancode msi_tvanywhere_plus[] = {
+static struct rc_map_table msi_tvanywhere_plus[] = {
/* ---- Remote Button Layout ----
@@ -97,23 +97,23 @@ static struct ir_scancode msi_tvanywhere_plus[] = {
{ 0x1d, KEY_RESTART }, /* Reset */
};
-static struct rc_keymap msi_tvanywhere_plus_map = {
+static struct rc_map_list msi_tvanywhere_plus_map = {
.map = {
.scan = msi_tvanywhere_plus,
.size = ARRAY_SIZE(msi_tvanywhere_plus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MSI_TVANYWHERE_PLUS,
}
};
static int __init init_rc_map_msi_tvanywhere_plus(void)
{
- return ir_register_map(&msi_tvanywhere_plus_map);
+ return rc_map_register(&msi_tvanywhere_plus_map);
}
static void __exit exit_rc_map_msi_tvanywhere_plus(void)
{
- ir_unregister_map(&msi_tvanywhere_plus_map);
+ rc_map_unregister(&msi_tvanywhere_plus_map);
}
module_init(init_rc_map_msi_tvanywhere_plus)
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
index ef411854f067..18b37facb0dd 100644
--- a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
@@ -14,7 +14,7 @@
/* MSI TV@nywhere MASTER remote */
-static struct ir_scancode msi_tvanywhere[] = {
+static struct rc_map_table msi_tvanywhere[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -43,23 +43,23 @@ static struct ir_scancode msi_tvanywhere[] = {
{ 0x1f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap msi_tvanywhere_map = {
+static struct rc_map_list msi_tvanywhere_map = {
.map = {
.scan = msi_tvanywhere,
.size = ARRAY_SIZE(msi_tvanywhere),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MSI_TVANYWHERE,
}
};
static int __init init_rc_map_msi_tvanywhere(void)
{
- return ir_register_map(&msi_tvanywhere_map);
+ return rc_map_register(&msi_tvanywhere_map);
}
static void __exit exit_rc_map_msi_tvanywhere(void)
{
- ir_unregister_map(&msi_tvanywhere_map);
+ rc_map_unregister(&msi_tvanywhere_map);
}
module_init(init_rc_map_msi_tvanywhere)
diff --git a/drivers/media/IR/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index ccc50eb402ec..3e6f077eb700 100644
--- a/drivers/media/IR/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode nebula[] = {
+static struct rc_map_table nebula[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -70,23 +70,23 @@ static struct ir_scancode nebula[] = {
{ 0x36, KEY_PC },
};
-static struct rc_keymap nebula_map = {
+static struct rc_map_list nebula_map = {
.map = {
.scan = nebula,
.size = ARRAY_SIZE(nebula),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NEBULA,
}
};
static int __init init_rc_map_nebula(void)
{
- return ir_register_map(&nebula_map);
+ return rc_map_register(&nebula_map);
}
static void __exit exit_rc_map_nebula(void)
{
- ir_unregister_map(&nebula_map);
+ rc_map_unregister(&nebula_map);
}
module_init(init_rc_map_nebula)
diff --git a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index e1b54d20db60..26f114c5c0de 100644
--- a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@redhat.com>
*/
-static struct ir_scancode nec_terratec_cinergy_xs[] = {
+static struct rc_map_table nec_terratec_cinergy_xs[] = {
{ 0x1441, KEY_HOME},
{ 0x1401, KEY_POWER2},
@@ -79,23 +79,23 @@ static struct ir_scancode nec_terratec_cinergy_xs[] = {
{ 0x145c, KEY_NEXT},
};
-static struct rc_keymap nec_terratec_cinergy_xs_map = {
+static struct rc_map_list nec_terratec_cinergy_xs_map = {
.map = {
.scan = nec_terratec_cinergy_xs,
.size = ARRAY_SIZE(nec_terratec_cinergy_xs),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_NEC_TERRATEC_CINERGY_XS,
}
};
static int __init init_rc_map_nec_terratec_cinergy_xs(void)
{
- return ir_register_map(&nec_terratec_cinergy_xs_map);
+ return rc_map_register(&nec_terratec_cinergy_xs_map);
}
static void __exit exit_rc_map_nec_terratec_cinergy_xs(void)
{
- ir_unregister_map(&nec_terratec_cinergy_xs_map);
+ rc_map_unregister(&nec_terratec_cinergy_xs_map);
}
module_init(init_rc_map_nec_terratec_cinergy_xs)
diff --git a/drivers/media/IR/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index e5849a6b3f05..629ee9d84537 100644
--- a/drivers/media/IR/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -16,7 +16,7 @@
By Peter Naulls <peter@chocky.org>
Key comments are the functions given in the manual */
-static struct ir_scancode norwood[] = {
+static struct rc_map_table norwood[] = {
/* Keys 0 to 9 */
{ 0x20, KEY_0 },
{ 0x21, KEY_1 },
@@ -59,23 +59,23 @@ static struct ir_scancode norwood[] = {
{ 0x65, KEY_POWER }, /* Computer power */
};
-static struct rc_keymap norwood_map = {
+static struct rc_map_list norwood_map = {
.map = {
.scan = norwood,
.size = ARRAY_SIZE(norwood),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NORWOOD,
}
};
static int __init init_rc_map_norwood(void)
{
- return ir_register_map(&norwood_map);
+ return rc_map_register(&norwood_map);
}
static void __exit exit_rc_map_norwood(void)
{
- ir_unregister_map(&norwood_map);
+ rc_map_unregister(&norwood_map);
}
module_init(init_rc_map_norwood)
diff --git a/drivers/media/IR/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c
index b9ece1e90296..4aa588bf6d69 100644
--- a/drivers/media/IR/keymaps/rc-npgtech.c
+++ b/drivers/media/rc/keymaps/rc-npgtech.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode npgtech[] = {
+static struct rc_map_table npgtech[] = {
{ 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
{ 0x2a, KEY_FRONT },
@@ -54,23 +54,23 @@ static struct ir_scancode npgtech[] = {
};
-static struct rc_keymap npgtech_map = {
+static struct rc_map_list npgtech_map = {
.map = {
.scan = npgtech,
.size = ARRAY_SIZE(npgtech),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NPGTECH,
}
};
static int __init init_rc_map_npgtech(void)
{
- return ir_register_map(&npgtech_map);
+ return rc_map_register(&npgtech_map);
}
static void __exit exit_rc_map_npgtech(void)
{
- ir_unregister_map(&npgtech_map);
+ rc_map_unregister(&npgtech_map);
}
module_init(init_rc_map_npgtech)
diff --git a/drivers/media/IR/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index 4129bb44a25b..fa5ae5981eb8 100644
--- a/drivers/media/IR/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -17,7 +17,7 @@
Pavel Mihaylov <bin@bash.info>
Also for the remote bundled with Kozumi KTV-01C card */
-static struct ir_scancode pctv_sedna[] = {
+static struct rc_map_table pctv_sedna[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -54,23 +54,23 @@ static struct ir_scancode pctv_sedna[] = {
{ 0x1f, KEY_PLAY }, /* Play */
};
-static struct rc_keymap pctv_sedna_map = {
+static struct rc_map_list pctv_sedna_map = {
.map = {
.scan = pctv_sedna,
.size = ARRAY_SIZE(pctv_sedna),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PCTV_SEDNA,
}
};
static int __init init_rc_map_pctv_sedna(void)
{
- return ir_register_map(&pctv_sedna_map);
+ return rc_map_register(&pctv_sedna_map);
}
static void __exit exit_rc_map_pctv_sedna(void)
{
- ir_unregister_map(&pctv_sedna_map);
+ rc_map_unregister(&pctv_sedna_map);
}
module_init(init_rc_map_pctv_sedna)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c
index 326e023ce126..23b8c505c6aa 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-color.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pinnacle_color[] = {
+static struct rc_map_table pinnacle_color[] = {
{ 0x59, KEY_MUTE },
{ 0x4a, KEY_POWER },
@@ -68,23 +68,23 @@ static struct ir_scancode pinnacle_color[] = {
{ 0x0a, KEY_BACKSPACE },
};
-static struct rc_keymap pinnacle_color_map = {
+static struct rc_map_list pinnacle_color_map = {
.map = {
.scan = pinnacle_color,
.size = ARRAY_SIZE(pinnacle_color),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_COLOR,
}
};
static int __init init_rc_map_pinnacle_color(void)
{
- return ir_register_map(&pinnacle_color_map);
+ return rc_map_register(&pinnacle_color_map);
}
static void __exit exit_rc_map_pinnacle_color(void)
{
- ir_unregister_map(&pinnacle_color_map);
+ rc_map_unregister(&pinnacle_color_map);
}
module_init(init_rc_map_pinnacle_color)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
index 14cb772515c6..6ba8c368d10a 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-grey.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pinnacle_grey[] = {
+static struct rc_map_table pinnacle_grey[] = {
{ 0x3a, KEY_0 },
{ 0x31, KEY_1 },
{ 0x32, KEY_2 },
@@ -63,23 +63,23 @@ static struct ir_scancode pinnacle_grey[] = {
{ 0x18, KEY_EPG },
};
-static struct rc_keymap pinnacle_grey_map = {
+static struct rc_map_list pinnacle_grey_map = {
.map = {
.scan = pinnacle_grey,
.size = ARRAY_SIZE(pinnacle_grey),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_GREY,
}
};
static int __init init_rc_map_pinnacle_grey(void)
{
- return ir_register_map(&pinnacle_grey_map);
+ return rc_map_register(&pinnacle_grey_map);
}
static void __exit exit_rc_map_pinnacle_grey(void)
{
- ir_unregister_map(&pinnacle_grey_map);
+ rc_map_unregister(&pinnacle_grey_map);
}
module_init(init_rc_map_pinnacle_grey)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
index 835bf4ef8de7..bb10ffe086b4 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
@@ -14,7 +14,7 @@
/* Pinnacle PCTV HD 800i mini remote */
-static struct ir_scancode pinnacle_pctv_hd[] = {
+static struct rc_map_table pinnacle_pctv_hd[] = {
{ 0x0f, KEY_1 },
{ 0x15, KEY_2 },
@@ -47,23 +47,23 @@ static struct ir_scancode pinnacle_pctv_hd[] = {
{ 0x3f, KEY_EPG }, /* Labeled "?" */
};
-static struct rc_keymap pinnacle_pctv_hd_map = {
+static struct rc_map_list pinnacle_pctv_hd_map = {
.map = {
.scan = pinnacle_pctv_hd,
.size = ARRAY_SIZE(pinnacle_pctv_hd),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_PCTV_HD,
}
};
static int __init init_rc_map_pinnacle_pctv_hd(void)
{
- return ir_register_map(&pinnacle_pctv_hd_map);
+ return rc_map_register(&pinnacle_pctv_hd_map);
}
static void __exit exit_rc_map_pinnacle_pctv_hd(void)
{
- ir_unregister_map(&pinnacle_pctv_hd_map);
+ rc_map_unregister(&pinnacle_pctv_hd_map);
}
module_init(init_rc_map_pinnacle_pctv_hd)
diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c
new file mode 100644
index 000000000000..e5ab071f635a
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c
@@ -0,0 +1,77 @@
+/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
+ *
+ * keymap imported from ir-keymaps.c
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+/*
+ * Keytable for 002-T IR remote provided together with Pixelview
+ * SBTVD Hybrid Remote Controller. Uses NEC extended format.
+ */
+static struct rc_map_table pixelview_002t[] = {
+ { 0x866b13, KEY_MUTE },
+ { 0x866b12, KEY_POWER2 }, /* power */
+
+ { 0x866b01, KEY_1 },
+ { 0x866b02, KEY_2 },
+ { 0x866b03, KEY_3 },
+ { 0x866b04, KEY_4 },
+ { 0x866b05, KEY_5 },
+ { 0x866b06, KEY_6 },
+ { 0x866b07, KEY_7 },
+ { 0x866b08, KEY_8 },
+ { 0x866b09, KEY_9 },
+ { 0x866b00, KEY_0 },
+
+ { 0x866b0d, KEY_CHANNELUP },
+ { 0x866b19, KEY_CHANNELDOWN },
+ { 0x866b10, KEY_VOLUMEUP }, /* vol + */
+ { 0x866b0c, KEY_VOLUMEDOWN }, /* vol - */
+
+ { 0x866b0a, KEY_CAMERA }, /* snapshot */
+ { 0x866b0b, KEY_ZOOM }, /* zoom */
+
+ { 0x866b1b, KEY_BACKSPACE },
+ { 0x866b15, KEY_ENTER },
+
+ { 0x866b1d, KEY_UP },
+ { 0x866b1e, KEY_DOWN },
+ { 0x866b0e, KEY_LEFT },
+ { 0x866b0f, KEY_RIGHT },
+
+ { 0x866b18, KEY_RECORD },
+ { 0x866b1a, KEY_STOP },
+};
+
+static struct rc_map_list pixelview_map = {
+ .map = {
+ .scan = pixelview_002t,
+ .size = ARRAY_SIZE(pixelview_002t),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_PIXELVIEW_002T,
+ }
+};
+
+static int __init init_rc_map_pixelview(void)
+{
+ return rc_map_register(&pixelview_map);
+}
+
+static void __exit exit_rc_map_pixelview(void)
+{
+ rc_map_unregister(&pixelview_map);
+}
+
+module_init(init_rc_map_pixelview)
+module_exit(exit_rc_map_pixelview)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 5a735d569a8b..8d9f664e0a2d 100644
--- a/drivers/media/IR/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -16,7 +16,7 @@
* Keytable for MK-F12 IR remote provided together with Pixelview
* Ultra Pro Remote Controller. Uses NEC extended format.
*/
-static struct ir_scancode pixelview_mk12[] = {
+static struct rc_map_table pixelview_mk12[] = {
{ 0x866b03, KEY_TUNER }, /* Timeshift */
{ 0x866b1e, KEY_POWER2 }, /* power */
@@ -57,23 +57,23 @@ static struct ir_scancode pixelview_mk12[] = {
{ 0x866b07, KEY_RADIO }, /* FM */
};
-static struct rc_keymap pixelview_map = {
+static struct rc_map_list pixelview_map = {
.map = {
.scan = pixelview_mk12,
.size = ARRAY_SIZE(pixelview_mk12),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_PIXELVIEW_MK12,
}
};
static int __init init_rc_map_pixelview(void)
{
- return ir_register_map(&pixelview_map);
+ return rc_map_register(&pixelview_map);
}
static void __exit exit_rc_map_pixelview(void)
{
- ir_unregister_map(&pixelview_map);
+ rc_map_unregister(&pixelview_map);
}
module_init(init_rc_map_pixelview)
diff --git a/drivers/media/IR/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index 7bbbbf5735e6..777a70076be2 100644
--- a/drivers/media/IR/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -17,7 +17,7 @@
present on PV MPEG 8000GT
*/
-static struct ir_scancode pixelview_new[] = {
+static struct rc_map_table pixelview_new[] = {
{ 0x3c, KEY_TIME }, /* Timeshift */
{ 0x12, KEY_POWER },
@@ -57,23 +57,23 @@ static struct ir_scancode pixelview_new[] = {
{ 0x34, KEY_RADIO },
};
-static struct rc_keymap pixelview_new_map = {
+static struct rc_map_list pixelview_new_map = {
.map = {
.scan = pixelview_new,
.size = ARRAY_SIZE(pixelview_new),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PIXELVIEW_NEW,
}
};
static int __init init_rc_map_pixelview_new(void)
{
- return ir_register_map(&pixelview_new_map);
+ return rc_map_register(&pixelview_new_map);
}
static void __exit exit_rc_map_pixelview_new(void)
{
- ir_unregister_map(&pixelview_new_map);
+ rc_map_unregister(&pixelview_new_map);
}
module_init(init_rc_map_pixelview_new)
diff --git a/drivers/media/IR/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index 82ff12e182a0..0ec5988916b9 100644
--- a/drivers/media/IR/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pixelview[] = {
+static struct rc_map_table pixelview[] = {
{ 0x1e, KEY_POWER }, /* power */
{ 0x07, KEY_MEDIA }, /* source */
@@ -56,23 +56,23 @@ static struct ir_scancode pixelview[] = {
{ 0x18, KEY_MUTE }, /* mute/unmute */
};
-static struct rc_keymap pixelview_map = {
+static struct rc_map_list pixelview_map = {
.map = {
.scan = pixelview,
.size = ARRAY_SIZE(pixelview),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PIXELVIEW,
}
};
static int __init init_rc_map_pixelview(void)
{
- return ir_register_map(&pixelview_map);
+ return rc_map_register(&pixelview_map);
}
static void __exit exit_rc_map_pixelview(void)
{
- ir_unregister_map(&pixelview_map);
+ rc_map_unregister(&pixelview_map);
}
module_init(init_rc_map_pixelview)
diff --git a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
index 7cef8190a224..5f9d546a86c4 100644
--- a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
+++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
@@ -17,7 +17,7 @@
* Daniel Fraga <fragabr@gmail.com>
*/
-static struct ir_scancode powercolor_real_angel[] = {
+static struct rc_map_table powercolor_real_angel[] = {
{ 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
{ 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
{ 0x00, KEY_0 },
@@ -55,23 +55,23 @@ static struct ir_scancode powercolor_real_angel[] = {
{ 0x25, KEY_POWER }, /* power */
};
-static struct rc_keymap powercolor_real_angel_map = {
+static struct rc_map_list powercolor_real_angel_map = {
.map = {
.scan = powercolor_real_angel,
.size = ARRAY_SIZE(powercolor_real_angel),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_POWERCOLOR_REAL_ANGEL,
}
};
static int __init init_rc_map_powercolor_real_angel(void)
{
- return ir_register_map(&powercolor_real_angel_map);
+ return rc_map_register(&powercolor_real_angel_map);
}
static void __exit exit_rc_map_powercolor_real_angel(void)
{
- ir_unregister_map(&powercolor_real_angel_map);
+ rc_map_unregister(&powercolor_real_angel_map);
}
module_init(init_rc_map_powercolor_real_angel)
diff --git a/drivers/media/IR/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c
index 22e92d39dee5..8a3a643879d4 100644
--- a/drivers/media/IR/keymaps/rc-proteus-2309.c
+++ b/drivers/media/rc/keymaps/rc-proteus-2309.c
@@ -14,7 +14,7 @@
/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
-static struct ir_scancode proteus_2309[] = {
+static struct rc_map_table proteus_2309[] = {
/* numeric */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -43,23 +43,23 @@ static struct ir_scancode proteus_2309[] = {
{ 0x14, KEY_F1 },
};
-static struct rc_keymap proteus_2309_map = {
+static struct rc_map_list proteus_2309_map = {
.map = {
.scan = proteus_2309,
.size = ARRAY_SIZE(proteus_2309),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PROTEUS_2309,
}
};
static int __init init_rc_map_proteus_2309(void)
{
- return ir_register_map(&proteus_2309_map);
+ return rc_map_register(&proteus_2309_map);
}
static void __exit exit_rc_map_proteus_2309(void)
{
- ir_unregister_map(&proteus_2309_map);
+ rc_map_unregister(&proteus_2309_map);
}
module_init(init_rc_map_proteus_2309)
diff --git a/drivers/media/IR/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c
index 4e20fc2269f7..ef90296bfd68 100644
--- a/drivers/media/IR/keymaps/rc-purpletv.c
+++ b/drivers/media/rc/keymaps/rc-purpletv.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode purpletv[] = {
+static struct rc_map_table purpletv[] = {
{ 0x03, KEY_POWER },
{ 0x6f, KEY_MUTE },
{ 0x10, KEY_BACKSPACE }, /* Recall */
@@ -55,23 +55,23 @@ static struct ir_scancode purpletv[] = {
};
-static struct rc_keymap purpletv_map = {
+static struct rc_map_list purpletv_map = {
.map = {
.scan = purpletv,
.size = ARRAY_SIZE(purpletv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PURPLETV,
}
};
static int __init init_rc_map_purpletv(void)
{
- return ir_register_map(&purpletv_map);
+ return rc_map_register(&purpletv_map);
}
static void __exit exit_rc_map_purpletv(void)
{
- ir_unregister_map(&purpletv_map);
+ rc_map_unregister(&purpletv_map);
}
module_init(init_rc_map_purpletv)
diff --git a/drivers/media/IR/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index 36679e706cf3..83a418de12c6 100644
--- a/drivers/media/IR/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -14,7 +14,7 @@
/* Mark Phalan <phalanm@o2.ie> */
-static struct ir_scancode pv951[] = {
+static struct rc_map_table pv951[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -52,23 +52,23 @@ static struct ir_scancode pv951[] = {
{ 0x1c, KEY_MEDIA }, /* PC/TV */
};
-static struct rc_keymap pv951_map = {
+static struct rc_map_list pv951_map = {
.map = {
.scan = pv951,
.size = ARRAY_SIZE(pv951),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PV951,
}
};
static int __init init_rc_map_pv951(void)
{
- return ir_register_map(&pv951_map);
+ return rc_map_register(&pv951_map);
}
static void __exit exit_rc_map_pv951(void)
{
- ir_unregister_map(&pv951_map);
+ rc_map_unregister(&pv951_map);
}
module_init(init_rc_map_pv951)
diff --git a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
index cc6b8f548747..dfc9b15f43a9 100644
--- a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
@@ -19,7 +19,7 @@
* This table contains the complete RC5 code, instead of just the data part
*/
-static struct ir_scancode rc5_hauppauge_new[] = {
+static struct rc_map_table rc5_hauppauge_new[] = {
/* Keys 0 to 9 */
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
@@ -75,25 +75,63 @@ static struct ir_scancode rc5_hauppauge_new[] = {
{ 0x1e3b, KEY_SELECT }, /* top right button */
{ 0x1e3c, KEY_ZOOM }, /* full */
{ 0x1e3d, KEY_POWER }, /* system power (green button) */
+
+ /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */
+ { 0x1d00, KEY_0 },
+ { 0x1d01, KEY_1 },
+ { 0x1d02, KEY_2 },
+ { 0x1d03, KEY_3 },
+ { 0x1d04, KEY_4 },
+ { 0x1d05, KEY_5 },
+ { 0x1d06, KEY_6 },
+ { 0x1d07, KEY_7 },
+ { 0x1d08, KEY_8 },
+ { 0x1d09, KEY_9 },
+ { 0x1d0a, KEY_TEXT },
+ { 0x1d0d, KEY_MENU },
+ { 0x1d0f, KEY_MUTE },
+ { 0x1d10, KEY_VOLUMEUP },
+ { 0x1d11, KEY_VOLUMEDOWN },
+ { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */
+ { 0x1d14, KEY_UP },
+ { 0x1d15, KEY_DOWN },
+ { 0x1d16, KEY_LEFT },
+ { 0x1d17, KEY_RIGHT },
+ { 0x1d1c, KEY_TV },
+ { 0x1d1e, KEY_NEXT }, /* >| */
+ { 0x1d1f, KEY_EXIT },
+ { 0x1d20, KEY_CHANNELUP },
+ { 0x1d21, KEY_CHANNELDOWN },
+ { 0x1d24, KEY_LAST }, /* <| */
+ { 0x1d25, KEY_OK },
+ { 0x1d30, KEY_PAUSE },
+ { 0x1d32, KEY_REWIND },
+ { 0x1d34, KEY_FASTFORWARD },
+ { 0x1d35, KEY_PLAY },
+ { 0x1d36, KEY_STOP },
+ { 0x1d37, KEY_RECORD },
+ { 0x1d3b, KEY_GOTO },
+ { 0x1d3d, KEY_POWER },
+ { 0x1d3f, KEY_HOME },
};
-static struct rc_keymap rc5_hauppauge_new_map = {
+static struct rc_map_list rc5_hauppauge_new_map = {
.map = {
.scan = rc5_hauppauge_new,
.size = ARRAY_SIZE(rc5_hauppauge_new),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_RC5_HAUPPAUGE_NEW,
}
};
static int __init init_rc_map_rc5_hauppauge_new(void)
{
- return ir_register_map(&rc5_hauppauge_new_map);
+ return rc_map_register(&rc5_hauppauge_new_map);
}
static void __exit exit_rc_map_rc5_hauppauge_new(void)
{
- ir_unregister_map(&rc5_hauppauge_new_map);
+ rc_map_unregister(&rc5_hauppauge_new_map);
}
module_init(init_rc_map_rc5_hauppauge_new)
diff --git a/drivers/media/IR/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c
index 73cce2f8ddfb..4fcef9f1f721 100644
--- a/drivers/media/IR/keymaps/rc-rc5-tv.c
+++ b/drivers/media/rc/keymaps/rc-rc5-tv.c
@@ -16,7 +16,7 @@
/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
/* used by old (black) Hauppauge remotes */
-static struct ir_scancode rc5_tv[] = {
+static struct rc_map_table rc5_tv[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -55,23 +55,23 @@ static struct ir_scancode rc5_tv[] = {
};
-static struct rc_keymap rc5_tv_map = {
+static struct rc_map_list rc5_tv_map = {
.map = {
.scan = rc5_tv,
.size = ARRAY_SIZE(rc5_tv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_RC5_TV,
}
};
static int __init init_rc_map_rc5_tv(void)
{
- return ir_register_map(&rc5_tv_map);
+ return rc_map_register(&rc5_tv_map);
}
static void __exit exit_rc_map_rc5_tv(void)
{
- ir_unregister_map(&rc5_tv_map);
+ rc_map_unregister(&rc5_tv_map);
}
module_init(init_rc_map_rc5_tv)
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
index 1b7adabbcee9..3bf3337875d1 100644
--- a/drivers/media/IR/keymaps/rc-rc6-mce.c
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
@@ -11,7 +11,7 @@
#include <media/rc-map.h>
-static struct ir_scancode rc6_mce[] = {
+static struct rc_map_table rc6_mce[] = {
{ 0x800f0400, KEY_NUMERIC_0 },
{ 0x800f0401, KEY_NUMERIC_1 },
@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f040a, KEY_DELETE },
{ 0x800f040b, KEY_ENTER },
- { 0x800f040c, KEY_POWER },
- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+ { 0x800f040c, KEY_POWER }, /* PC Power */
+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f040e, KEY_MUTE },
{ 0x800f040f, KEY_INFO },
@@ -56,53 +56,54 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
{ 0x800f0424, KEY_DVD },
- { 0x800f0425, KEY_TUNER }, /* LiveTV */
- { 0x800f0426, KEY_EPG }, /* Guide */
- { 0x800f0427, KEY_ZOOM }, /* Aspect */
+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
+ { 0x800f0426, KEY_EPG }, /* Guide */
+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV },
- { 0x800f0447, KEY_AUDIO }, /* My Music */
- { 0x800f0448, KEY_PVR }, /* RecordedTV */
+ { 0x800f0447, KEY_AUDIO }, /* My Music */
+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO },
{ 0x800f044c, KEY_LANGUAGE },
{ 0x800f044d, KEY_TITLE },
- { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
+ { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f0450, KEY_RADIO },
- { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE },
+ { 0x800f0465, KEY_POWER2 }, /* TV Power */
{ 0x800f046e, KEY_PLAYPAUSE },
- { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
+ { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0481, KEY_PLAYPAUSE },
};
-static struct rc_keymap rc6_mce_map = {
+static struct rc_map_list rc6_mce_map = {
.map = {
.scan = rc6_mce,
.size = ARRAY_SIZE(rc6_mce),
- .ir_type = IR_TYPE_RC6,
+ .rc_type = RC_TYPE_RC6,
.name = RC_MAP_RC6_MCE,
}
};
static int __init init_rc_map_rc6_mce(void)
{
- return ir_register_map(&rc6_mce_map);
+ return rc_map_register(&rc6_mce_map);
}
static void __exit exit_rc_map_rc6_mce(void)
{
- ir_unregister_map(&rc6_mce_map);
+ rc_map_unregister(&rc6_mce_map);
}
module_init(init_rc_map_rc6_mce)
diff --git a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index ab1a6d2baf72..2d14598592d8 100644
--- a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -14,7 +14,7 @@
/* Zogis Real Audio 220 - 32 keys IR */
-static struct ir_scancode real_audio_220_32_keys[] = {
+static struct rc_map_table real_audio_220_32_keys[] = {
{ 0x1c, KEY_RADIO},
{ 0x12, KEY_POWER2},
@@ -52,23 +52,23 @@ static struct ir_scancode real_audio_220_32_keys[] = {
};
-static struct rc_keymap real_audio_220_32_keys_map = {
+static struct rc_map_list real_audio_220_32_keys_map = {
.map = {
.scan = real_audio_220_32_keys,
.size = ARRAY_SIZE(real_audio_220_32_keys),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_REAL_AUDIO_220_32_KEYS,
}
};
static int __init init_rc_map_real_audio_220_32_keys(void)
{
- return ir_register_map(&real_audio_220_32_keys_map);
+ return rc_map_register(&real_audio_220_32_keys_map);
}
static void __exit exit_rc_map_real_audio_220_32_keys(void)
{
- ir_unregister_map(&real_audio_220_32_keys_map);
+ rc_map_unregister(&real_audio_220_32_keys_map);
}
module_init(init_rc_map_real_audio_220_32_keys)
diff --git a/drivers/media/IR/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c
index df32013a321c..92cc10d2f9cd 100644
--- a/drivers/media/IR/keymaps/rc-streamzap.c
+++ b/drivers/media/rc/keymaps/rc-streamzap.c
@@ -11,7 +11,7 @@
#include <media/rc-map.h>
-static struct ir_scancode streamzap[] = {
+static struct rc_map_table streamzap[] = {
/*
* The Streamzap remote is almost, but not quite, RC-5, as it has an extra
* bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
@@ -56,23 +56,23 @@ static struct ir_scancode streamzap[] = {
};
-static struct rc_keymap streamzap_map = {
+static struct rc_map_list streamzap_map = {
.map = {
.scan = streamzap,
.size = ARRAY_SIZE(streamzap),
- .ir_type = IR_TYPE_RC5_SZ,
+ .rc_type = RC_TYPE_RC5_SZ,
.name = RC_MAP_STREAMZAP,
}
};
static int __init init_rc_map_streamzap(void)
{
- return ir_register_map(&streamzap_map);
+ return rc_map_register(&streamzap_map);
}
static void __exit exit_rc_map_streamzap(void)
{
- ir_unregister_map(&streamzap_map);
+ rc_map_unregister(&streamzap_map);
}
module_init(init_rc_map_streamzap)
diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c
new file mode 100644
index 000000000000..7242ee66f6e0
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tbs-nec.c
@@ -0,0 +1,75 @@
+/* tbs-nec.h - Keytable for tbs_nec Remote Controller
+ *
+ * keymap imported from ir-keymaps.c
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table tbs_nec[] = {
+ { 0x84, KEY_POWER2}, /* power */
+ { 0x94, KEY_MUTE}, /* mute */
+ { 0x87, KEY_1},
+ { 0x86, KEY_2},
+ { 0x85, KEY_3},
+ { 0x8b, KEY_4},
+ { 0x8a, KEY_5},
+ { 0x89, KEY_6},
+ { 0x8f, KEY_7},
+ { 0x8e, KEY_8},
+ { 0x8d, KEY_9},
+ { 0x92, KEY_0},
+ { 0xc0, KEY_10CHANNELSUP}, /* 10+ */
+ { 0xd0, KEY_10CHANNELSDOWN}, /* 10- */
+ { 0x96, KEY_CHANNELUP}, /* ch+ */
+ { 0x91, KEY_CHANNELDOWN}, /* ch- */
+ { 0x93, KEY_VOLUMEUP}, /* vol+ */
+ { 0x8c, KEY_VOLUMEDOWN}, /* vol- */
+ { 0x83, KEY_RECORD}, /* rec */
+ { 0x98, KEY_PAUSE}, /* pause, yellow */
+ { 0x99, KEY_OK}, /* ok */
+ { 0x9a, KEY_CAMERA}, /* snapshot */
+ { 0x81, KEY_UP},
+ { 0x90, KEY_LEFT},
+ { 0x82, KEY_RIGHT},
+ { 0x88, KEY_DOWN},
+ { 0x95, KEY_FAVORITES}, /* blue */
+ { 0x97, KEY_SUBTITLE}, /* green */
+ { 0x9d, KEY_ZOOM},
+ { 0x9f, KEY_EXIT},
+ { 0x9e, KEY_MENU},
+ { 0x9c, KEY_EPG},
+ { 0x80, KEY_PREVIOUS}, /* red */
+ { 0x9b, KEY_MODE},
+};
+
+static struct rc_map_list tbs_nec_map = {
+ .map = {
+ .scan = tbs_nec,
+ .size = ARRAY_SIZE(tbs_nec),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_TBS_NEC,
+ }
+};
+
+static int __init init_rc_map_tbs_nec(void)
+{
+ return rc_map_register(&tbs_nec_map);
+}
+
+static void __exit exit_rc_map_tbs_nec(void)
+{
+ rc_map_unregister(&tbs_nec_map);
+}
+
+module_init(init_rc_map_tbs_nec)
+module_exit(exit_rc_map_tbs_nec)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
index 5326a0b444c1..bc38e34b9fda 100644
--- a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
@@ -16,7 +16,7 @@
Devin Heitmueller <dheitmueller@linuxtv.org>
*/
-static struct ir_scancode terratec_cinergy_xs[] = {
+static struct rc_map_table terratec_cinergy_xs[] = {
{ 0x41, KEY_HOME},
{ 0x01, KEY_POWER},
{ 0x42, KEY_MENU},
@@ -66,23 +66,23 @@ static struct ir_scancode terratec_cinergy_xs[] = {
{ 0x5c, KEY_NEXT},
};
-static struct rc_keymap terratec_cinergy_xs_map = {
+static struct rc_map_list terratec_cinergy_xs_map = {
.map = {
.scan = terratec_cinergy_xs,
.size = ARRAY_SIZE(terratec_cinergy_xs),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TERRATEC_CINERGY_XS,
}
};
static int __init init_rc_map_terratec_cinergy_xs(void)
{
- return ir_register_map(&terratec_cinergy_xs_map);
+ return rc_map_register(&terratec_cinergy_xs_map);
}
static void __exit exit_rc_map_terratec_cinergy_xs(void)
{
- ir_unregister_map(&terratec_cinergy_xs_map);
+ rc_map_unregister(&terratec_cinergy_xs_map);
}
module_init(init_rc_map_terratec_cinergy_xs)
diff --git a/drivers/media/IR/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c
index 10dee4c1deff..1abafa5fd303 100644
--- a/drivers/media/IR/keymaps/rc-terratec-slim.c
+++ b/drivers/media/rc/keymaps/rc-terratec-slim.c
@@ -22,7 +22,7 @@
/* TerraTec slim remote, 7 rows, 4 columns. */
/* Uses NEC extended 0x02bd. */
-static struct ir_scancode terratec_slim[] = {
+static struct rc_map_table terratec_slim[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
@@ -53,23 +53,23 @@ static struct ir_scancode terratec_slim[] = {
{ 0x02bd45, KEY_POWER2 }, /* [red power button] */
};
-static struct rc_keymap terratec_slim_map = {
+static struct rc_map_list terratec_slim_map = {
.map = {
.scan = terratec_slim,
.size = ARRAY_SIZE(terratec_slim),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TERRATEC_SLIM,
}
};
static int __init init_rc_map_terratec_slim(void)
{
- return ir_register_map(&terratec_slim_map);
+ return rc_map_register(&terratec_slim_map);
}
static void __exit exit_rc_map_terratec_slim(void)
{
- ir_unregister_map(&terratec_slim_map);
+ rc_map_unregister(&terratec_slim_map);
}
module_init(init_rc_map_terratec_slim)
diff --git a/drivers/media/IR/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c
index e30d411c07bb..ef5ba3f32735 100644
--- a/drivers/media/IR/keymaps/rc-tevii-nec.c
+++ b/drivers/media/rc/keymaps/rc-tevii-nec.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode tevii_nec[] = {
+static struct rc_map_table tevii_nec[] = {
{ 0x0a, KEY_POWER2},
{ 0x0c, KEY_MUTE},
{ 0x11, KEY_1},
@@ -62,23 +62,23 @@ static struct ir_scancode tevii_nec[] = {
{ 0x58, KEY_SWITCHVIDEOMODE},
};
-static struct rc_keymap tevii_nec_map = {
+static struct rc_map_list tevii_nec_map = {
.map = {
.scan = tevii_nec,
.size = ARRAY_SIZE(tevii_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TEVII_NEC,
}
};
static int __init init_rc_map_tevii_nec(void)
{
- return ir_register_map(&tevii_nec_map);
+ return rc_map_register(&tevii_nec_map);
}
static void __exit exit_rc_map_tevii_nec(void)
{
- ir_unregister_map(&tevii_nec_map);
+ rc_map_unregister(&tevii_nec_map);
}
module_init(init_rc_map_tevii_nec)
diff --git a/drivers/media/IR/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c
index fd1985763781..20ac4e19fb3f 100644
--- a/drivers/media/IR/keymaps/rc-total-media-in-hand.c
+++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c
@@ -21,7 +21,7 @@
#include <media/rc-map.h>
/* Uses NEC extended 0x02bd */
-static struct ir_scancode total_media_in_hand[] = {
+static struct rc_map_table total_media_in_hand[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
@@ -59,23 +59,23 @@ static struct ir_scancode total_media_in_hand[] = {
{ 0x02bd45, KEY_INFO }, /* [red (I)] */
};
-static struct rc_keymap total_media_in_hand_map = {
+static struct rc_map_list total_media_in_hand_map = {
.map = {
.scan = total_media_in_hand,
.size = ARRAY_SIZE(total_media_in_hand),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TOTAL_MEDIA_IN_HAND,
}
};
static int __init init_rc_map_total_media_in_hand(void)
{
- return ir_register_map(&total_media_in_hand_map);
+ return rc_map_register(&total_media_in_hand_map);
}
static void __exit exit_rc_map_total_media_in_hand(void)
{
- ir_unregister_map(&total_media_in_hand_map);
+ rc_map_unregister(&total_media_in_hand_map);
}
module_init(init_rc_map_total_media_in_hand)
diff --git a/drivers/media/IR/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c
index 91092caca452..f8190ead2e32 100644
--- a/drivers/media/IR/keymaps/rc-trekstor.c
+++ b/drivers/media/rc/keymaps/rc-trekstor.c
@@ -23,7 +23,7 @@
/* TrekStor DVB-T USB Stick remote controller. */
/* Imported from af9015.h.
Initial keytable was from Marc Schneider <macke@macke.org> */
-static struct ir_scancode trekstor[] = {
+static struct rc_map_table trekstor[] = {
{ 0x0084, KEY_0 },
{ 0x0085, KEY_MUTE }, /* Mute */
{ 0x0086, KEY_HOMEPAGE }, /* Home */
@@ -54,23 +54,23 @@ static struct ir_scancode trekstor[] = {
{ 0x009f, KEY_LEFT }, /* Left */
};
-static struct rc_keymap trekstor_map = {
+static struct rc_map_list trekstor_map = {
.map = {
.scan = trekstor,
.size = ARRAY_SIZE(trekstor),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TREKSTOR,
}
};
static int __init init_rc_map_trekstor(void)
{
- return ir_register_map(&trekstor_map);
+ return rc_map_register(&trekstor_map);
}
static void __exit exit_rc_map_trekstor(void)
{
- ir_unregister_map(&trekstor_map);
+ rc_map_unregister(&trekstor_map);
}
module_init(init_rc_map_trekstor)
diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c
new file mode 100644
index 000000000000..295f3738e301
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tt-1500.c
@@ -0,0 +1,82 @@
+/* tt-1500.h - Keytable for tt_1500 Remote Controller
+ *
+ * keymap imported from ir-keymaps.c
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+/* for the Technotrend 1500 bundled remotes (grey and black): */
+
+static struct rc_map_table tt_1500[] = {
+ { 0x1501, KEY_POWER },
+ { 0x1502, KEY_SHUFFLE }, /* ? double-arrow key */
+ { 0x1503, KEY_1 },
+ { 0x1504, KEY_2 },
+ { 0x1505, KEY_3 },
+ { 0x1506, KEY_4 },
+ { 0x1507, KEY_5 },
+ { 0x1508, KEY_6 },
+ { 0x1509, KEY_7 },
+ { 0x150a, KEY_8 },
+ { 0x150b, KEY_9 },
+ { 0x150c, KEY_0 },
+ { 0x150d, KEY_UP },
+ { 0x150e, KEY_LEFT },
+ { 0x150f, KEY_OK },
+ { 0x1510, KEY_RIGHT },
+ { 0x1511, KEY_DOWN },
+ { 0x1512, KEY_INFO },
+ { 0x1513, KEY_EXIT },
+ { 0x1514, KEY_RED },
+ { 0x1515, KEY_GREEN },
+ { 0x1516, KEY_YELLOW },
+ { 0x1517, KEY_BLUE },
+ { 0x1518, KEY_MUTE },
+ { 0x1519, KEY_TEXT },
+ { 0x151a, KEY_MODE }, /* ? TV/Radio */
+ { 0x1521, KEY_OPTION },
+ { 0x1522, KEY_EPG },
+ { 0x1523, KEY_CHANNELUP },
+ { 0x1524, KEY_CHANNELDOWN },
+ { 0x1525, KEY_VOLUMEUP },
+ { 0x1526, KEY_VOLUMEDOWN },
+ { 0x1527, KEY_SETUP },
+ { 0x153a, KEY_RECORD }, /* these keys are only in the black remote */
+ { 0x153b, KEY_PLAY },
+ { 0x153c, KEY_STOP },
+ { 0x153d, KEY_REWIND },
+ { 0x153e, KEY_PAUSE },
+ { 0x153f, KEY_FORWARD },
+};
+
+static struct rc_map_list tt_1500_map = {
+ .map = {
+ .scan = tt_1500,
+ .size = ARRAY_SIZE(tt_1500),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_TT_1500,
+ }
+};
+
+static int __init init_rc_map_tt_1500(void)
+{
+ return rc_map_register(&tt_1500_map);
+}
+
+static void __exit exit_rc_map_tt_1500(void)
+{
+ rc_map_unregister(&tt_1500_map);
+}
+
+module_init(init_rc_map_tt_1500)
+module_exit(exit_rc_map_tt_1500)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c
index 0b5d356c2d84..8bf8df64b081 100644
--- a/drivers/media/IR/keymaps/rc-twinhan1027.c
+++ b/drivers/media/rc/keymaps/rc-twinhan1027.c
@@ -1,6 +1,6 @@
#include <media/rc-map.h>
-static struct ir_scancode twinhan_vp1027[] = {
+static struct rc_map_table twinhan_vp1027[] = {
{ 0x16, KEY_POWER2 },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
@@ -61,23 +61,23 @@ static struct ir_scancode twinhan_vp1027[] = {
{ 0x5f, KEY_BLUE },
};
-static struct rc_keymap twinhan_vp1027_map = {
+static struct rc_map_list twinhan_vp1027_map = {
.map = {
.scan = twinhan_vp1027,
.size = ARRAY_SIZE(twinhan_vp1027),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TWINHAN_VP1027_DVBS,
}
};
static int __init init_rc_map_twinhan_vp1027(void)
{
- return ir_register_map(&twinhan_vp1027_map);
+ return rc_map_register(&twinhan_vp1027_map);
}
static void __exit exit_rc_map_twinhan_vp1027(void)
{
- ir_unregister_map(&twinhan_vp1027_map);
+ rc_map_unregister(&twinhan_vp1027_map);
}
module_init(init_rc_map_twinhan_vp1027)
diff --git a/drivers/media/rc/keymaps/rc-videomate-m1f.c b/drivers/media/rc/keymaps/rc-videomate-m1f.c
new file mode 100644
index 000000000000..4994d405c0a1
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-videomate-m1f.c
@@ -0,0 +1,92 @@
+/* videomate-m1f.h - Keytable for videomate_m1f Remote Controller
+ *
+ * keymap imported from ir-keymaps.c
+ *
+ * Copyright (c) 2010 by Pavel Osnova <pvosnova@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table videomate_m1f[] = {
+ { 0x01, KEY_POWER },
+ { 0x31, KEY_TUNER },
+ { 0x33, KEY_VIDEO },
+ { 0x2f, KEY_RADIO },
+ { 0x30, KEY_CAMERA },
+ { 0x2d, KEY_NEW }, /* TV record button */
+ { 0x17, KEY_CYCLEWINDOWS },
+ { 0x2c, KEY_ANGLE },
+ { 0x2b, KEY_LANGUAGE },
+ { 0x32, KEY_SEARCH }, /* '...' button */
+ { 0x11, KEY_UP },
+ { 0x13, KEY_LEFT },
+ { 0x15, KEY_OK },
+ { 0x14, KEY_RIGHT },
+ { 0x12, KEY_DOWN },
+ { 0x16, KEY_BACKSPACE },
+ { 0x02, KEY_ZOOM }, /* WIN key */
+ { 0x04, KEY_INFO },
+ { 0x05, KEY_VOLUMEUP },
+ { 0x03, KEY_MUTE },
+ { 0x07, KEY_CHANNELUP },
+ { 0x06, KEY_VOLUMEDOWN },
+ { 0x08, KEY_CHANNELDOWN },
+ { 0x0c, KEY_RECORD },
+ { 0x0e, KEY_STOP },
+ { 0x0a, KEY_BACK },
+ { 0x0b, KEY_PLAY },
+ { 0x09, KEY_FORWARD },
+ { 0x10, KEY_PREVIOUS },
+ { 0x0d, KEY_PAUSE },
+ { 0x0f, KEY_NEXT },
+ { 0x1e, KEY_1 },
+ { 0x1f, KEY_2 },
+ { 0x20, KEY_3 },
+ { 0x21, KEY_4 },
+ { 0x22, KEY_5 },
+ { 0x23, KEY_6 },
+ { 0x24, KEY_7 },
+ { 0x25, KEY_8 },
+ { 0x26, KEY_9 },
+ { 0x2a, KEY_NUMERIC_STAR }, /* * key */
+ { 0x1d, KEY_0 },
+ { 0x29, KEY_SUBTITLE }, /* # key */
+ { 0x27, KEY_CLEAR },
+ { 0x34, KEY_SCREEN },
+ { 0x28, KEY_ENTER },
+ { 0x19, KEY_RED },
+ { 0x1a, KEY_GREEN },
+ { 0x1b, KEY_YELLOW },
+ { 0x1c, KEY_BLUE },
+ { 0x18, KEY_TEXT },
+};
+
+static struct rc_map_list videomate_m1f_map = {
+ .map = {
+ .scan = videomate_m1f,
+ .size = ARRAY_SIZE(videomate_m1f),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_VIDEOMATE_M1F,
+ }
+};
+
+static int __init init_rc_map_videomate_m1f(void)
+{
+ return rc_map_register(&videomate_m1f_map);
+}
+
+static void __exit exit_rc_map_videomate_m1f(void)
+{
+ rc_map_unregister(&videomate_m1f_map);
+}
+
+module_init(init_rc_map_videomate_m1f)
+module_exit(exit_rc_map_videomate_m1f)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pavel Osnova <pvosnova@gmail.com>");
diff --git a/drivers/media/IR/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c
index 4df7fcd1d2fc..9e474a6024e5 100644
--- a/drivers/media/IR/keymaps/rc-videomate-s350.c
+++ b/drivers/media/rc/keymaps/rc-videomate-s350.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode videomate_s350[] = {
+static struct rc_map_table videomate_s350[] = {
{ 0x00, KEY_TV},
{ 0x01, KEY_DVD},
{ 0x04, KEY_RECORD},
@@ -59,23 +59,23 @@ static struct ir_scancode videomate_s350[] = {
{ 0x20, KEY_TEXT},
};
-static struct rc_keymap videomate_s350_map = {
+static struct rc_map_list videomate_s350_map = {
.map = {
.scan = videomate_s350,
.size = ARRAY_SIZE(videomate_s350),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_VIDEOMATE_S350,
}
};
static int __init init_rc_map_videomate_s350(void)
{
- return ir_register_map(&videomate_s350_map);
+ return rc_map_register(&videomate_s350_map);
}
static void __exit exit_rc_map_videomate_s350(void)
{
- ir_unregister_map(&videomate_s350_map);
+ rc_map_unregister(&videomate_s350_map);
}
module_init(init_rc_map_videomate_s350)
diff --git a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
index 776b0a638d87..5f2a46e1f8f6 100644
--- a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
+++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode videomate_tv_pvr[] = {
+static struct rc_map_table videomate_tv_pvr[] = {
{ 0x14, KEY_MUTE },
{ 0x24, KEY_ZOOM },
@@ -61,23 +61,23 @@ static struct ir_scancode videomate_tv_pvr[] = {
{ 0x21, KEY_SLEEP },
};
-static struct rc_keymap videomate_tv_pvr_map = {
+static struct rc_map_list videomate_tv_pvr_map = {
.map = {
.scan = videomate_tv_pvr,
.size = ARRAY_SIZE(videomate_tv_pvr),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_VIDEOMATE_TV_PVR,
}
};
static int __init init_rc_map_videomate_tv_pvr(void)
{
- return ir_register_map(&videomate_tv_pvr_map);
+ return rc_map_register(&videomate_tv_pvr_map);
}
static void __exit exit_rc_map_videomate_tv_pvr(void)
{
- ir_unregister_map(&videomate_tv_pvr_map);
+ rc_map_unregister(&videomate_tv_pvr_map);
}
module_init(init_rc_map_videomate_tv_pvr)
diff --git a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
index 9d2d550aaa90..bd8d021f40aa 100644
--- a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
+++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
@@ -16,7 +16,7 @@
Magnus Alm <magnus.alm@gmail.com>
*/
-static struct ir_scancode winfast_usbii_deluxe[] = {
+static struct rc_map_table winfast_usbii_deluxe[] = {
{ 0x62, KEY_0},
{ 0x75, KEY_1},
{ 0x76, KEY_2},
@@ -56,23 +56,23 @@ static struct ir_scancode winfast_usbii_deluxe[] = {
};
-static struct rc_keymap winfast_usbii_deluxe_map = {
+static struct rc_map_list winfast_usbii_deluxe_map = {
.map = {
.scan = winfast_usbii_deluxe,
.size = ARRAY_SIZE(winfast_usbii_deluxe),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_WINFAST_USBII_DELUXE,
}
};
static int __init init_rc_map_winfast_usbii_deluxe(void)
{
- return ir_register_map(&winfast_usbii_deluxe_map);
+ return rc_map_register(&winfast_usbii_deluxe_map);
}
static void __exit exit_rc_map_winfast_usbii_deluxe(void)
{
- ir_unregister_map(&winfast_usbii_deluxe_map);
+ rc_map_unregister(&winfast_usbii_deluxe_map);
}
module_init(init_rc_map_winfast_usbii_deluxe)
diff --git a/drivers/media/IR/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 0e90a3bd9499..2747db43b70c 100644
--- a/drivers/media/IR/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -14,7 +14,7 @@
/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-static struct ir_scancode winfast[] = {
+static struct rc_map_table winfast[] = {
/* Keys 0 to 9 */
{ 0x12, KEY_0 },
{ 0x05, KEY_1 },
@@ -76,23 +76,23 @@ static struct ir_scancode winfast[] = {
{ 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
};
-static struct rc_keymap winfast_map = {
+static struct rc_map_list winfast_map = {
.map = {
.scan = winfast,
.size = ARRAY_SIZE(winfast),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_WINFAST,
}
};
static int __init init_rc_map_winfast(void)
{
- return ir_register_map(&winfast_map);
+ return rc_map_register(&winfast_map);
}
static void __exit exit_rc_map_winfast(void)
{
- ir_unregister_map(&winfast_map);
+ rc_map_unregister(&winfast_map);
}
module_init(init_rc_map_winfast)
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 8418b14ee4d2..fd237ab120bb 100644
--- a/drivers/media/IR/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -178,7 +178,9 @@ static int lirc_cdev_add(struct irctl *ir)
cdev_init(cdev, &lirc_dev_fops);
cdev->owner = THIS_MODULE;
}
- kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
+ retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
+ if (retval)
+ return retval;
retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
if (retval)
@@ -522,10 +524,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
- if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
+ if (!ir->attached)
return POLLERR;
- }
poll_wait(file, &ir->buf->wait_poll, wait);
@@ -629,7 +629,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
EXPORT_SYMBOL(lirc_dev_fop_ioctl);
ssize_t lirc_dev_fop_read(struct file *file,
- char *buffer,
+ char __user *buffer,
size_t length,
loff_t *ppos)
{
@@ -649,18 +649,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
if (!buf)
return -ENOMEM;
- if (mutex_lock_interruptible(&ir->irctl_lock))
- return -ERESTARTSYS;
+ if (mutex_lock_interruptible(&ir->irctl_lock)) {
+ ret = -ERESTARTSYS;
+ goto out_unlocked;
+ }
if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out_locked;
}
if (length % ir->chunk_size) {
- dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
- ir->d.name, ir->d.minor);
- mutex_unlock(&ir->irctl_lock);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_locked;
}
/*
@@ -711,18 +711,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
lirc_buffer_read(ir->buf, buf);
ret = copy_to_user((void *)buffer+written, buf,
ir->buf->chunk_size);
- written += ir->buf->chunk_size;
+ if (!ret)
+ written += ir->buf->chunk_size;
+ else
+ ret = -EFAULT;
}
}
remove_wait_queue(&ir->buf->wait_poll, &wait);
set_current_state(TASK_RUNNING);
+
+out_locked:
mutex_unlock(&ir->irctl_lock);
out_unlocked:
kfree(buf);
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
- ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
+ ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret);
return ret ? ret : written;
}
@@ -744,7 +749,7 @@ void *lirc_get_pdata(struct file *file)
EXPORT_SYMBOL(lirc_get_pdata);
-ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
+ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer,
size_t length, loff_t *ppos)
{
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/rc/mceusb.c
index 9dce684fd231..0fef6efad537 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -36,9 +36,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
#define DRIVER_VERSION "1.91"
#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
@@ -49,6 +48,7 @@
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
+#define MS_TO_NS(msec) ((msec) * 1000)
/* MCE constants */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
@@ -74,6 +74,7 @@
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+#define MCE_CMD_SIG_END 0x01 /* End of signal */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
@@ -91,6 +92,7 @@
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
+#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
@@ -146,14 +148,16 @@ enum mceusb_model_type {
MCE_GEN3,
MCE_GEN2_TX_INV,
POLARIS_EVK,
+ CX_HYBRID_TV,
};
struct mceusb_model {
u32 mce_gen1:1;
u32 mce_gen2:1;
u32 mce_gen3:1;
- u32 tx_mask_inverted:1;
+ u32 tx_mask_normal:1;
u32 is_polaris:1;
+ u32 no_tx:1;
const char *rc_map; /* Allow specify a per-board map */
const char *name; /* per-board name */
@@ -162,18 +166,18 @@ struct mceusb_model {
static const struct mceusb_model mceusb_model[] = {
[MCE_GEN1] = {
.mce_gen1 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[MCE_GEN2] = {
.mce_gen2 = 1,
},
[MCE_GEN2_TX_INV] = {
.mce_gen2 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[MCE_GEN3] = {
.mce_gen3 = 1,
- .tx_mask_inverted = 1,
+ .tx_mask_normal = 1,
},
[POLARIS_EVK] = {
.is_polaris = 1,
@@ -183,7 +187,12 @@ static const struct mceusb_model mceusb_model[] = {
* to allow testing it
*/
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
- .name = "cx231xx MCE IR",
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
+ },
+ [CX_HYBRID_TV] = {
+ .is_polaris = 1,
+ .no_tx = 1, /* tx isn't wired up at all */
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
},
};
@@ -273,6 +282,8 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
/* Formosa Industrial Computing */
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
+ /* Fintek eHome Infrared Transceiver (HP branded) */
+ { USB_DEVICE(VENDOR_FINTEK, 0x5168) },
/* Fintek eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_FINTEK, 0x0602) },
/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
@@ -292,9 +303,12 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
/* TiVo PC IR Receiver */
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
- /* Conexant SDK */
+ /* Conexant Hybrid TV "Shelby" Polaris SDK */
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
.driver_info = POLARIS_EVK },
+ /* Conexant Hybrid TV RDU253S Polaris */
+ { USB_DEVICE(VENDOR_CONEXANT, 0x58a5),
+ .driver_info = CX_HYBRID_TV },
/* Terminating entry */
{ }
};
@@ -302,12 +316,14 @@ static struct usb_device_id mceusb_dev_table[] = {
/* data structure for each usb transceiver */
struct mceusb_dev {
/* ir-core bits */
- struct ir_dev_props *props;
- struct ir_raw_event rawir;
+ struct rc_dev *rc;
+
+ /* optional features we can enable */
+ bool carrier_report_enabled;
+ bool learning_enabled;
/* core device bits */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
@@ -318,6 +334,8 @@ struct mceusb_dev {
/* buffers and dma */
unsigned char *buf_in;
unsigned int len_in;
+ dma_addr_t dma_in;
+ dma_addr_t dma_out;
enum {
CMD_HEADER = 0,
@@ -325,15 +343,14 @@ struct mceusb_dev {
CMD_DATA,
PARSE_IRDATA,
} parser_state;
- u8 cmd, rem; /* Remaining IR data bytes in packet */
- dma_addr_t dma_in;
- dma_addr_t dma_out;
+ u8 cmd, rem; /* Remaining IR data bytes in packet */
struct {
u32 connected:1;
- u32 tx_mask_inverted:1;
+ u32 tx_mask_normal:1;
u32 microsoft_gen1:1;
+ u32 no_tx:1;
} flags;
/* transmit support */
@@ -408,9 +425,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
case MCE_CMD_UNKNOWN:
case MCE_CMD_S_CARRIER:
case MCE_CMD_S_TIMEOUT:
- case MCE_CMD_G_RXSENSOR:
+ case MCE_RSP_PULSE_COUNT:
datasize = 2;
break;
+ case MCE_CMD_SIG_END:
case MCE_CMD_S_TXMASK:
case MCE_CMD_S_RXSENSOR:
datasize = 1;
@@ -433,7 +451,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
return;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
- if (ir->flags.microsoft_gen1 && !out)
+ if (ir->flags.microsoft_gen1 && !out && !offset)
skip = 2;
if (len <= skip)
@@ -491,6 +509,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_COMMAND_HEADER:
switch (subcmd) {
+ case MCE_CMD_SIG_END:
+ dev_info(dev, "End of signal\n");
+ break;
case MCE_CMD_PING:
dev_info(dev, "Ping\n");
break;
@@ -525,10 +546,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
inout, data1 == 0x02 ? "short" : "long");
break;
case MCE_CMD_G_RXSENSOR:
- if (len == 2)
+ /* aka MCE_RSP_PULSE_COUNT */
+ if (out)
dev_info(dev, "Get receive sensor\n");
- else
- dev_info(dev, "Received pulse count is %d\n",
+ else if (ir->learning_enabled)
+ dev_info(dev, "RX pulse count: %d\n",
((data1 << 8) | data2));
break;
case MCE_RSP_CMD_INVALID:
@@ -639,9 +661,9 @@ static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
}
/* Send data out the IR blaster port(s) */
-static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
+static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int i, ret = 0;
int count, cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */
@@ -724,24 +746,24 @@ out:
return ret ? ret : n;
}
-/* Sets active IR outputs -- mce devices typically (all?) have two */
-static int mceusb_set_tx_mask(void *priv, u32 mask)
+/* Sets active IR outputs -- mce devices typically have two */
+static int mceusb_set_tx_mask(struct rc_dev *dev, u32 mask)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
- if (ir->flags.tx_mask_inverted)
+ if (ir->flags.tx_mask_normal)
+ ir->tx_mask = mask;
+ else
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
- else
- ir->tx_mask = mask;
return 0;
}
/* Sets the send carrier frequency and mode */
-static int mceusb_set_tx_carrier(void *priv, u32 carrier)
+static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
@@ -752,7 +774,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
if (carrier == 0) {
ir->carrier = carrier;
- cmdbuf[2] = 0x01;
+ cmdbuf[2] = MCE_CMD_SIG_END;
cmdbuf[3] = MCE_IRDATA_TRAILER;
dev_dbg(ir->dev, "%s: disabling carrier "
"modulation\n", __func__);
@@ -782,6 +804,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
return carrier;
}
+/*
+ * We don't do anything but print debug spew for many of the command bits
+ * we receive from the hardware, but some of them are useful information
+ * we want to store so that we can use them.
+ */
+static void mceusb_handle_command(struct mceusb_dev *ir, int index)
+{
+ u8 hi = ir->buf_in[index + 1] & 0xff;
+ u8 lo = ir->buf_in[index + 2] & 0xff;
+
+ switch (ir->buf_in[index]) {
+ /* 2-byte return value commands */
+ case MCE_CMD_S_TIMEOUT:
+ ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+ break;
+
+ /* 1-byte return value commands */
+ case MCE_CMD_S_TXMASK:
+ ir->tx_mask = hi;
+ break;
+ case MCE_CMD_S_RXSENSOR:
+ ir->learning_enabled = (hi == 0x02);
+ break;
+ default:
+ break;
+ }
+}
+
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
{
DEFINE_IR_RAW_EVENT(rawir);
@@ -791,39 +841,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
if (ir->flags.microsoft_gen1)
i = 2;
+ /* if there's no data, just return now */
+ if (buf_len <= i)
+ return;
+
for (; i < buf_len; i++) {
switch (ir->parser_state) {
case SUBCMD:
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
ir->rem + 2, false);
+ mceusb_handle_command(ir, i);
ir->parser_state = CMD_DATA;
break;
case PARSE_IRDATA:
ir->rem--;
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
- * MCE_TIME_UNIT * 1000;
-
- if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
- if (ir->rawir.pulse == rawir.pulse) {
- ir->rawir.duration += rawir.duration;
- } else {
- ir->rawir.duration = rawir.duration;
- ir->rawir.pulse = rawir.pulse;
- }
- if (ir->rem)
- break;
- }
- rawir.duration += ir->rawir.duration;
- ir->rawir.duration = 0;
- ir->rawir.pulse = rawir.pulse;
+ * MS_TO_NS(MCE_TIME_UNIT);
dev_dbg(ir->dev, "Storing %s with duration %d\n",
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store(ir->idev, &rawir);
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
break;
case CMD_DATA:
ir->rem--;
@@ -839,17 +880,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
continue;
}
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
- mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
- if (ir->rem) {
+ mceusb_dev_printdata(ir, ir->buf_in,
+ i, ir->rem + 1, false);
+ if (ir->rem)
ir->parser_state = PARSE_IRDATA;
- break;
- }
- /*
- * a package with len=0 (e. g. 0x80) means end of
- * data. We could use it to do the call to
- * ir_raw_event_handle(). For now, we don't need to
- * use it.
- */
break;
}
@@ -857,7 +891,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
ir->parser_state = CMD_HEADER;
}
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
- ir_raw_event_handle(ir->idev);
+ ir_raw_event_handle(ir->rc);
}
static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
@@ -984,9 +1018,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
mce_sync_in(ir, NULL, maxp);
- /* get the transmitter bitmask */
- mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
- mce_sync_in(ir, NULL, maxp);
+ if (!ir->flags.no_tx) {
+ /* get the transmitter bitmask */
+ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+ mce_sync_in(ir, NULL, maxp);
+ }
/* get receiver timeout value */
mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
@@ -997,66 +1033,54 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_sync_in(ir, NULL, maxp);
}
-static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
+static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
struct device *dev = ir->dev;
- const char *rc_map = RC_MAP_RC6_MCE;
- const char *name = "Media Center Ed. eHome Infrared Remote Transceiver";
- int ret = -ENODEV;
-
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
+ struct rc_dev *rc;
+ int ret;
- ret = -ENOMEM;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rc = rc_allocate_device();
+ if (!rc) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
- if (mceusb_model[ir->model].name)
- name = mceusb_model[ir->model].name;
-
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
- name,
+ mceusb_model[ir->model].name ?
+ mceusb_model[ir->model].name :
+ "Media Center Ed. eHome Infrared Remote Transceiver",
le16_to_cpu(ir->usbdev->descriptor.idVendor),
le16_to_cpu(ir->usbdev->descriptor.idProduct));
- idev->name = ir->name;
usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
- idev->phys = ir->phys;
-
- props->priv = ir;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->s_tx_mask = mceusb_set_tx_mask;
- props->s_tx_carrier = mceusb_set_tx_carrier;
- props->tx_ir = mceusb_tx_ir;
- ir->props = props;
-
- if (mceusb_model[ir->model].rc_map)
- rc_map = mceusb_model[ir->model].rc_map;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ usb_to_input_id(ir->usbdev, &rc->input_id);
+ rc->dev.parent = dev;
+ rc->priv = ir;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = RC_TYPE_ALL;
+ rc->timeout = MS_TO_NS(1000);
+ if (!ir->flags.no_tx) {
+ rc->s_tx_mask = mceusb_set_tx_mask;
+ rc->s_tx_carrier = mceusb_set_tx_carrier;
+ rc->tx_ir = mceusb_tx_ir;
+ }
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = mceusb_model[ir->model].rc_map ?
+ mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
- ret = ir_input_register(idev, rc_map, props, DRIVER_NAME);
+ ret = rc_register_device(rc);
if (ret < 0) {
- dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ dev_err(dev, "remote dev registration failed\n");
+ goto out;
}
- return idev;
+ return rc;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rc);
return NULL;
}
@@ -1074,16 +1098,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
enum mceusb_model_type model = id->driver_info;
bool is_gen3;
bool is_microsoft_gen1;
- bool tx_mask_inverted;
+ bool tx_mask_normal;
bool is_polaris;
- dev_dbg(&intf->dev, ": %s called\n", __func__);
+ dev_dbg(&intf->dev, "%s called\n", __func__);
idesc = intf->cur_altsetting;
is_gen3 = mceusb_model[model].mce_gen3;
is_microsoft_gen1 = mceusb_model[model].mce_gen1;
- tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
+ tx_mask_normal = mceusb_model[model].tx_mask_normal;
is_polaris = mceusb_model[model].is_polaris;
if (is_polaris) {
@@ -1107,7 +1131,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_in = ep;
ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_in->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable inbound endpoint "
+ dev_dbg(&intf->dev, "acceptable inbound endpoint "
"found\n");
}
@@ -1122,12 +1146,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_out = ep;
ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_out->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable outbound endpoint "
+ dev_dbg(&intf->dev, "acceptable outbound endpoint "
"found\n");
}
}
if (ep_in == NULL) {
- dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
+ dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
return -ENODEV;
}
@@ -1150,11 +1174,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ir->dev = &intf->dev;
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
- ir->flags.tx_mask_inverted = tx_mask_inverted;
+ ir->flags.tx_mask_normal = tx_mask_normal;
+ ir->flags.no_tx = mceusb_model[model].no_tx;
ir->model = model;
- init_ir_raw_event(&ir->rawir);
-
/* Saving usb interface data for use by the transmitter routine */
ir->usb_ep_in = ep_in;
ir->usb_ep_out = ep_out;
@@ -1169,9 +1192,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- ir->idev = mceusb_init_input_dev(ir);
- if (!ir->idev)
- goto input_dev_fail;
+ ir->rc = mceusb_init_rc_dev(ir);
+ if (!ir->rc)
+ goto rc_dev_fail;
/* flush buffers on the device */
mce_sync_in(ir, NULL, maxp);
@@ -1191,7 +1214,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
- mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+ if (!ir->flags.no_tx)
+ mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK);
usb_set_intfdata(intf, ir);
@@ -1201,7 +1225,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
return 0;
/* Error-handling path */
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(ir->urb_in);
urb_in_alloc_fail:
usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
@@ -1225,7 +1249,7 @@ static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
return;
ir->usbdev = NULL;
- ir_input_unregister(ir->idev);
+ rc_unregister_device(ir->rc);
usb_kill_urb(ir->urb_in);
usb_free_urb(ir->urb_in);
usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 301be53aee85..dd4caf8ef80b 100644
--- a/drivers/media/IR/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -32,8 +32,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/pci_ids.h>
#include "nuvoton-cir.h"
@@ -249,9 +248,12 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor);
- if (chip_major != CHIP_ID_HIGH &&
- (chip_minor != CHIP_ID_LOW || chip_minor != CHIP_ID_LOW2))
+ if (chip_major != CHIP_ID_HIGH ||
+ (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) {
+ nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x",
+ chip_id, chip_major, chip_minor);
ret = -ENODEV;
+ }
nvt_efm_disable(nvt);
@@ -476,9 +478,9 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
* always set CP as 0x81
* set CC by SPEC, CC = 3MHz/carrier - 1
*/
-static int nvt_set_tx_carrier(void *data, u32 carrier)
+static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct nvt_dev *nvt = data;
+ struct nvt_dev *nvt = dev->priv;
u16 val;
nvt_cir_reg_write(nvt, 1, CIR_CP);
@@ -509,9 +511,9 @@ static int nvt_set_tx_carrier(void *data, u32 carrier)
* number may larger than TXFCONT (0xff). So in interrupt_handler, it has to
* set TXFCONT as 0xff, until buf_count less than 0xff.
*/
-static int nvt_tx_ir(void *priv, int *txbuf, u32 n)
+static int nvt_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct nvt_dev *nvt = priv;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
size_t cur_count;
unsigned int i;
@@ -603,6 +605,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
count = nvt->pkts;
nvt_dbg_verbose("Processing buffer of len %d", count);
+ init_ir_raw_event(&rawir);
+
for (i = 0; i < count; i++) {
nvt->pkts--;
sample = nvt->buf[i];
@@ -643,11 +647,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
* indicates end of IR signal, but new data incoming. In both
* cases, it means we're ready to call ir_raw_event_handle
*/
- if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) &&
- (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE))
+ if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
+ nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
ir_raw_event_handle(nvt->rdev);
+ }
}
+ nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
+ ir_raw_event_handle(nvt->rdev);
+
if (nvt->pkts) {
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
nvt->pkts = 0;
@@ -942,9 +950,9 @@ static void nvt_disable_cir(struct nvt_dev *nvt)
nvt_efm_disable(nvt);
}
-static int nvt_open(void *data)
+static int nvt_open(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -955,9 +963,9 @@ static int nvt_open(void *data)
return 0;
}
-static void nvt_close(void *data)
+static void nvt_close(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -969,21 +977,16 @@ static void nvt_close(void *data)
/* Allocate memory, probe hardware, and initialize everything */
static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
{
- struct nvt_dev *nvt = NULL;
- struct input_dev *rdev = NULL;
- struct ir_dev_props *props = NULL;
+ struct nvt_dev *nvt;
+ struct rc_dev *rdev;
int ret = -ENOMEM;
nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL);
if (!nvt)
return ret;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props)
- goto failure;
-
/* input device for IR remote (and tx) */
- rdev = input_allocate_device();
+ rdev = rc_allocate_device();
if (!rdev)
goto failure;
@@ -1057,41 +1060,38 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
nvt_cir_regs_init(nvt);
nvt_cir_wake_regs_init(nvt);
- /* Set up ir-core props */
- props->priv = nvt;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->open = nvt_open;
- props->close = nvt_close;
+ /* Set up the rc device */
+ rdev->priv = nvt;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->open = nvt_open;
+ rdev->close = nvt_close;
+ rdev->tx_ir = nvt_tx_ir;
+ rdev->s_tx_carrier = nvt_set_tx_carrier;
+ rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
+ rdev->input_id.bustype = BUS_HOST;
+ rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2;
+ rdev->input_id.product = nvt->chip_major;
+ rdev->input_id.version = nvt->chip_minor;
+ rdev->driver_name = NVT_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
#if 0
- props->min_timeout = XYZ;
- props->max_timeout = XYZ;
- props->timeout = XYZ;
+ rdev->min_timeout = XYZ;
+ rdev->max_timeout = XYZ;
+ rdev->timeout = XYZ;
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
- props->rx_resolution = XYZ;
-
+ rdev->rx_resolution = XYZ;
/* tx bits */
- props->tx_resolution = XYZ;
+ rdev->tx_resolution = XYZ;
#endif
- props->tx_ir = nvt_tx_ir;
- props->s_tx_carrier = nvt_set_tx_carrier;
-
- rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver";
- rdev->id.bustype = BUS_HOST;
- rdev->id.vendor = PCI_VENDOR_ID_WINBOND2;
- rdev->id.product = nvt->chip_major;
- rdev->id.version = nvt->chip_minor;
- nvt->props = props;
- nvt->rdev = rdev;
-
- device_set_wakeup_capable(&pdev->dev, 1);
- device_set_wakeup_enable(&pdev->dev, 1);
-
- ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME);
+ ret = rc_register_device(rdev);
if (ret)
goto failure;
+ device_set_wakeup_capable(&pdev->dev, 1);
+ device_set_wakeup_enable(&pdev->dev, 1);
+ nvt->rdev = rdev;
nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
if (debug) {
cir_dump_regs(nvt);
@@ -1111,8 +1111,7 @@ failure:
if (nvt->cir_wake_addr)
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- input_free_device(rdev);
- kfree(props);
+ rc_free_device(rdev);
kfree(nvt);
return ret;
@@ -1137,9 +1136,8 @@ static void __devexit nvt_remove(struct pnp_dev *pdev)
release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- ir_input_unregister(nvt->rdev);
+ rc_unregister_device(nvt->rdev);
- kfree(nvt->props);
kfree(nvt);
}
diff --git a/drivers/media/IR/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
index 62dc53017c8e..1df82351cb03 100644
--- a/drivers/media/IR/nuvoton-cir.h
+++ b/drivers/media/rc/nuvoton-cir.h
@@ -66,8 +66,7 @@ static int debug;
struct nvt_dev {
struct pnp_dev *pdev;
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct ir_raw_event rawir;
spinlock_t nvt_lock;
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 81c936bd793f..873b38789751 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -13,22 +13,22 @@
* GNU General Public License for more details.
*/
-#ifndef _IR_RAW_EVENT
-#define _IR_RAW_EVENT
+#ifndef _RC_CORE_PRIV
+#define _RC_CORE_PRIV
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
struct ir_raw_handler {
struct list_head list;
u64 protocols; /* which are handled by this handler */
- int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+ int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
/* These two should only be used by the lirc decoder */
- int (*raw_register)(struct input_dev *input_dev);
- int (*raw_unregister)(struct input_dev *input_dev);
+ int (*raw_register)(struct rc_dev *dev);
+ int (*raw_unregister)(struct rc_dev *dev);
};
struct ir_raw_event_ctrl {
@@ -38,7 +38,7 @@ struct ir_raw_event_ctrl {
struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */
- struct input_dev *input_dev; /* pointer to the parent input_dev */
+ struct rc_dev *dev; /* pointer to the parent rc_dev */
u64 enabled_protocols; /* enabled raw protocol decoders */
/* raw decoder state follows */
@@ -85,7 +85,7 @@ struct ir_raw_event_ctrl {
unsigned wanted_bits;
} rc5_sz;
struct lirc_codec {
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
struct lirc_driver *drv;
int carrier_low;
@@ -129,27 +129,17 @@ static inline bool is_timing_event(struct ir_raw_event ev)
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
-/*
- * Routines from ir-sysfs.c - Meant to be called only internally inside
- * ir-core
- */
-int ir_register_input(struct input_dev *input_dev);
-
-int ir_register_class(struct input_dev *input_dev);
-void ir_unregister_class(struct input_dev *input_dev);
/*
- * Routines from ir-raw-event.c to be used internally and by decoders
+ * Routines from rc-raw.c to be used internally and by decoders
*/
u64 ir_raw_get_allowed_protocols(void);
-int ir_raw_event_register(struct input_dev *input_dev);
-void ir_raw_event_unregister(struct input_dev *input_dev);
+int ir_raw_event_register(struct rc_dev *dev);
+void ir_raw_event_unregister(struct rc_dev *dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
void ir_raw_init(void);
-int ir_rcmap_init(void);
-void ir_rcmap_cleanup(void);
/*
* Decoder initialization code
*
@@ -200,4 +190,4 @@ void ir_rcmap_cleanup(void);
#endif
-#endif /* _IR_RAW_EVENT */
+#endif /* _RC_CORE_PRIV */
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
new file mode 100644
index 000000000000..49cee61d79c6
--- /dev/null
+++ b/drivers/media/rc/rc-loopback.c
@@ -0,0 +1,260 @@
+/*
+ * Loopback driver for rc-core,
+ *
+ * Copyright (c) 2010 David Härdeman <david@hardeman.nu>
+ *
+ * This driver receives TX data and passes it back as RX data,
+ * which is useful for (scripted) debugging of rc-core without
+ * having to use actual hardware.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <media/rc-core.h>
+
+#define DRIVER_NAME "rc-loopback"
+#define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x)
+#define RXMASK_REGULAR 0x1
+#define RXMASK_LEARNING 0x2
+
+static bool debug;
+
+struct loopback_dev {
+ struct rc_dev *dev;
+ u32 txmask;
+ u32 txcarrier;
+ u32 txduty;
+ bool idle;
+ bool learning;
+ bool carrierreport;
+ u32 rxcarriermin;
+ u32 rxcarriermax;
+};
+
+static struct loopback_dev loopdev;
+
+static int loop_set_tx_mask(struct rc_dev *dev, u32 mask)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) {
+ dprintk("invalid tx mask: %u\n", mask);
+ return -EINVAL;
+ }
+
+ dprintk("setting tx mask: %u\n", mask);
+ lodev->txmask = mask;
+ return 0;
+}
+
+static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ dprintk("setting tx carrier: %u\n", carrier);
+ lodev->txcarrier = carrier;
+ return 0;
+}
+
+static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (duty_cycle < 1 || duty_cycle > 99) {
+ dprintk("invalid duty cycle: %u\n", duty_cycle);
+ return -EINVAL;
+ }
+
+ dprintk("setting duty cycle: %u\n", duty_cycle);
+ lodev->txduty = duty_cycle;
+ return 0;
+}
+
+static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (min < 1 || min > max) {
+ dprintk("invalid rx carrier range %u to %u\n", min, max);
+ return -EINVAL;
+ }
+
+ dprintk("setting rx carrier range %u to %u\n", min, max);
+ lodev->rxcarriermin = min;
+ lodev->rxcarriermax = max;
+ return 0;
+}
+
+static int loop_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
+{
+ struct loopback_dev *lodev = dev->priv;
+ u32 rxmask;
+ unsigned count;
+ unsigned total_duration = 0;
+ unsigned i;
+ DEFINE_IR_RAW_EVENT(rawir);
+
+ if (n == 0 || n % sizeof(int)) {
+ dprintk("invalid tx buffer size\n");
+ return -EINVAL;
+ }
+
+ count = n / sizeof(int);
+ for (i = 0; i < count; i++)
+ total_duration += abs(txbuf[i]);
+
+ if (total_duration == 0) {
+ dprintk("invalid tx data, total duration zero\n");
+ return -EINVAL;
+ }
+
+ if (lodev->txcarrier < lodev->rxcarriermin ||
+ lodev->txcarrier > lodev->rxcarriermax) {
+ dprintk("ignoring tx, carrier out of range\n");
+ goto out;
+ }
+
+ if (lodev->learning)
+ rxmask = RXMASK_LEARNING;
+ else
+ rxmask = RXMASK_REGULAR;
+
+ if (!(rxmask & lodev->txmask)) {
+ dprintk("ignoring tx, rx mask mismatch\n");
+ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ rawir.pulse = i % 2 ? false : true;
+ rawir.duration = abs(txbuf[i]) * 1000;
+ if (rawir.duration)
+ ir_raw_event_store_with_filter(dev, &rawir);
+ }
+ ir_raw_event_handle(dev);
+
+out:
+ /* Lirc expects this function to take as long as the total duration */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(usecs_to_jiffies(total_duration));
+ return n;
+}
+
+static void loop_set_idle(struct rc_dev *dev, bool enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->idle != enable) {
+ dprintk("%sing idle mode\n", enable ? "enter" : "exit");
+ lodev->idle = enable;
+ }
+}
+
+static int loop_set_learning_mode(struct rc_dev *dev, int enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->learning != enable) {
+ dprintk("%sing learning mode\n", enable ? "enter" : "exit");
+ lodev->learning = !!enable;
+ }
+
+ return 0;
+}
+
+static int loop_set_carrier_report(struct rc_dev *dev, int enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->carrierreport != enable) {
+ dprintk("%sabling carrier reports\n", enable ? "en" : "dis");
+ lodev->carrierreport = !!enable;
+ }
+
+ return 0;
+}
+
+static int __init loop_init(void)
+{
+ struct rc_dev *rc;
+ int ret;
+
+ rc = rc_allocate_device();
+ if (!rc) {
+ printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
+ return -ENOMEM;
+ }
+
+ rc->input_name = "rc-core loopback device";
+ rc->input_phys = "rc-core/virtual";
+ rc->input_id.bustype = BUS_VIRTUAL;
+ rc->input_id.version = 1;
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = RC_MAP_EMPTY;
+ rc->priv = &loopdev;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = RC_TYPE_ALL;
+ rc->timeout = 100 * 1000 * 1000; /* 100 ms */
+ rc->min_timeout = 1;
+ rc->max_timeout = UINT_MAX;
+ rc->rx_resolution = 1000;
+ rc->tx_resolution = 1000;
+ rc->s_tx_mask = loop_set_tx_mask;
+ rc->s_tx_carrier = loop_set_tx_carrier;
+ rc->s_tx_duty_cycle = loop_set_tx_duty_cycle;
+ rc->s_rx_carrier_range = loop_set_rx_carrier_range;
+ rc->tx_ir = loop_tx_ir;
+ rc->s_idle = loop_set_idle;
+ rc->s_learning_mode = loop_set_learning_mode;
+ rc->s_carrier_report = loop_set_carrier_report;
+ rc->priv = &loopdev;
+
+ loopdev.txmask = RXMASK_REGULAR;
+ loopdev.txcarrier = 36000;
+ loopdev.txduty = 50;
+ loopdev.rxcarriermin = 1;
+ loopdev.rxcarriermax = ~0;
+ loopdev.idle = true;
+ loopdev.learning = false;
+ loopdev.carrierreport = false;
+
+ ret = rc_register_device(rc);
+ if (ret < 0) {
+ printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
+ rc_free_device(rc);
+ return ret;
+ }
+
+ loopdev.dev = rc;
+ return 0;
+}
+
+static void __exit loop_exit(void)
+{
+ rc_unregister_device(loopdev.dev);
+}
+
+module_init(loop_init);
+module_exit(loop_exit);
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debug messages");
+
+MODULE_DESCRIPTION("Loopback device for rc-core debugging");
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
new file mode 100644
index 000000000000..72be8a02118c
--- /dev/null
+++ b/drivers/media/rc/rc-main.c
@@ -0,0 +1,1135 @@
+/* rc-main.c - Remote Controller core module
+ *
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <media/rc-core.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include "rc-core-priv.h"
+
+/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
+#define IR_TAB_MIN_SIZE 256
+#define IR_TAB_MAX_SIZE 8192
+
+/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
+#define IR_KEYPRESS_TIMEOUT 250
+
+/* Used to keep track of known keymaps */
+static LIST_HEAD(rc_map_list);
+static DEFINE_SPINLOCK(rc_map_lock);
+
+static struct rc_map_list *seek_rc_map(const char *name)
+{
+ struct rc_map_list *map = NULL;
+
+ spin_lock(&rc_map_lock);
+ list_for_each_entry(map, &rc_map_list, list) {
+ if (!strcmp(name, map->map.name)) {
+ spin_unlock(&rc_map_lock);
+ return map;
+ }
+ }
+ spin_unlock(&rc_map_lock);
+
+ return NULL;
+}
+
+struct rc_map *rc_map_get(const char *name)
+{
+
+ struct rc_map_list *map;
+
+ map = seek_rc_map(name);
+#ifdef MODULE
+ if (!map) {
+ int rc = request_module(name);
+ if (rc < 0) {
+ printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
+ return NULL;
+ }
+ msleep(20); /* Give some time for IR to register */
+
+ map = seek_rc_map(name);
+ }
+#endif
+ if (!map) {
+ printk(KERN_ERR "IR keymap %s not found\n", name);
+ return NULL;
+ }
+
+ printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
+
+ return &map->map;
+}
+EXPORT_SYMBOL_GPL(rc_map_get);
+
+int rc_map_register(struct rc_map_list *map)
+{
+ spin_lock(&rc_map_lock);
+ list_add_tail(&map->list, &rc_map_list);
+ spin_unlock(&rc_map_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rc_map_register);
+
+void rc_map_unregister(struct rc_map_list *map)
+{
+ spin_lock(&rc_map_lock);
+ list_del(&map->list);
+ spin_unlock(&rc_map_lock);
+}
+EXPORT_SYMBOL_GPL(rc_map_unregister);
+
+
+static struct rc_map_table empty[] = {
+ { 0x2a, KEY_COFFEE },
+};
+
+static struct rc_map_list empty_map = {
+ .map = {
+ .scan = empty,
+ .size = ARRAY_SIZE(empty),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_EMPTY,
+ }
+};
+
+/**
+ * ir_create_table() - initializes a scancode table
+ * @rc_map: the rc_map to initialize
+ * @name: name to assign to the table
+ * @rc_type: ir type to assign to the new table
+ * @size: initial size of the table
+ * @return: zero on success or a negative error code
+ *
+ * This routine will initialize the rc_map and will allocate
+ * memory to hold at least the specified number of elements.
+ */
+static int ir_create_table(struct rc_map *rc_map,
+ const char *name, u64 rc_type, size_t size)
+{
+ rc_map->name = name;
+ rc_map->rc_type = rc_type;
+ rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table));
+ rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
+ rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL);
+ if (!rc_map->scan)
+ return -ENOMEM;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_map->size, rc_map->alloc);
+ return 0;
+}
+
+/**
+ * ir_free_table() - frees memory allocated by a scancode table
+ * @rc_map: the table whose mappings need to be freed
+ *
+ * This routine will free memory alloctaed for key mappings used by given
+ * scancode table.
+ */
+static void ir_free_table(struct rc_map *rc_map)
+{
+ rc_map->size = 0;
+ kfree(rc_map->scan);
+ rc_map->scan = NULL;
+}
+
+/**
+ * ir_resize_table() - resizes a scancode table if necessary
+ * @rc_map: the rc_map to resize
+ * @gfp_flags: gfp flags to use when allocating memory
+ * @return: zero on success or a negative error code
+ *
+ * This routine will shrink the rc_map if it has lots of
+ * unused entries and grow it if it is full.
+ */
+static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags)
+{
+ unsigned int oldalloc = rc_map->alloc;
+ unsigned int newalloc = oldalloc;
+ struct rc_map_table *oldscan = rc_map->scan;
+ struct rc_map_table *newscan;
+
+ if (rc_map->size == rc_map->len) {
+ /* All entries in use -> grow keytable */
+ if (rc_map->alloc >= IR_TAB_MAX_SIZE)
+ return -ENOMEM;
+
+ newalloc *= 2;
+ IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
+ }
+
+ if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
+ /* Less than 1/3 of entries in use -> shrink keytable */
+ newalloc /= 2;
+ IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
+ }
+
+ if (newalloc == oldalloc)
+ return 0;
+
+ newscan = kmalloc(newalloc, gfp_flags);
+ if (!newscan) {
+ IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
+ return -ENOMEM;
+ }
+
+ memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table));
+ rc_map->scan = newscan;
+ rc_map->alloc = newalloc;
+ rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
+ kfree(oldscan);
+ return 0;
+}
+
+/**
+ * ir_update_mapping() - set a keycode in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @rc_map: scancode table to be adjusted
+ * @index: index of the mapping that needs to be updated
+ * @keycode: the desired keycode
+ * @return: previous keycode assigned to the mapping
+ *
+ * This routine is used to update scancode->keycode mapping at given
+ * position.
+ */
+static unsigned int ir_update_mapping(struct rc_dev *dev,
+ struct rc_map *rc_map,
+ unsigned int index,
+ unsigned int new_keycode)
+{
+ int old_keycode = rc_map->scan[index].keycode;
+ int i;
+
+ /* Did the user wish to remove the mapping? */
+ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
+ IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
+ index, rc_map->scan[index].scancode);
+ rc_map->len--;
+ memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
+ (rc_map->len - index) * sizeof(struct rc_map_table));
+ } else {
+ IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
+ index,
+ old_keycode == KEY_RESERVED ? "New" : "Replacing",
+ rc_map->scan[index].scancode, new_keycode);
+ rc_map->scan[index].keycode = new_keycode;
+ __set_bit(new_keycode, dev->input_dev->keybit);
+ }
+
+ if (old_keycode != KEY_RESERVED) {
+ /* A previous mapping was updated... */
+ __clear_bit(old_keycode, dev->input_dev->keybit);
+ /* ... but another scancode might use the same keycode */
+ for (i = 0; i < rc_map->len; i++) {
+ if (rc_map->scan[i].keycode == old_keycode) {
+ __set_bit(old_keycode, dev->input_dev->keybit);
+ break;
+ }
+ }
+
+ /* Possibly shrink the keytable, failure is not a problem */
+ ir_resize_table(rc_map, GFP_ATOMIC);
+ }
+
+ return old_keycode;
+}
+
+/**
+ * ir_establish_scancode() - set a keycode in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @rc_map: scancode table to be searched
+ * @scancode: the desired scancode
+ * @resize: controls whether we allowed to resize the table to
+ * accomodate not yet present scancodes
+ * @return: index of the mapping containing scancode in question
+ * or -1U in case of failure.
+ *
+ * This routine is used to locate given scancode in rc_map.
+ * If scancode is not yet present the routine will allocate a new slot
+ * for it.
+ */
+static unsigned int ir_establish_scancode(struct rc_dev *dev,
+ struct rc_map *rc_map,
+ unsigned int scancode,
+ bool resize)
+{
+ unsigned int i;
+
+ /*
+ * Unfortunately, some hardware-based IR decoders don't provide
+ * all bits for the complete IR code. In general, they provide only
+ * the command part of the IR code. Yet, as it is possible to replace
+ * the provided IR with another one, it is needed to allow loading
+ * IR tables from other remotes. So, we support specifying a mask to
+ * indicate the valid bits of the scancodes.
+ */
+ if (dev->scanmask)
+ scancode &= dev->scanmask;
+
+ /* First check if we already have a mapping for this ir command */
+ for (i = 0; i < rc_map->len; i++) {
+ if (rc_map->scan[i].scancode == scancode)
+ return i;
+
+ /* Keytable is sorted from lowest to highest scancode */
+ if (rc_map->scan[i].scancode >= scancode)
+ break;
+ }
+
+ /* No previous mapping found, we might need to grow the table */
+ if (rc_map->size == rc_map->len) {
+ if (!resize || ir_resize_table(rc_map, GFP_ATOMIC))
+ return -1U;
+ }
+
+ /* i is the proper index to insert our new keycode */
+ if (i < rc_map->len)
+ memmove(&rc_map->scan[i + 1], &rc_map->scan[i],
+ (rc_map->len - i) * sizeof(struct rc_map_table));
+ rc_map->scan[i].scancode = scancode;
+ rc_map->scan[i].keycode = KEY_RESERVED;
+ rc_map->len++;
+
+ return i;
+}
+
+/**
+ * ir_setkeycode() - set a keycode in the scancode->keycode table
+ * @idev: the struct input_dev device descriptor
+ * @scancode: the desired scancode
+ * @keycode: result
+ * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
+ *
+ * This routine is used to handle evdev EVIOCSKEY ioctl.
+ */
+static int ir_setkeycode(struct input_dev *idev,
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct rc_map *rc_map = &rdev->rc_map;
+ unsigned int index;
+ unsigned int scancode;
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ if (index >= rc_map->len) {
+ retval = -EINVAL;
+ goto out;
+ }
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_establish_scancode(rdev, rc_map, scancode, true);
+ if (index >= rc_map->len) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ }
+
+ *old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode);
+
+out:
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+ return retval;
+}
+
+/**
+ * ir_setkeytable() - sets several entries in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @to: the struct rc_map to copy entries to
+ * @from: the struct rc_map to copy entries from
+ * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
+ *
+ * This routine is used to handle table initialization.
+ */
+static int ir_setkeytable(struct rc_dev *dev,
+ const struct rc_map *from)
+{
+ struct rc_map *rc_map = &dev->rc_map;
+ unsigned int i, index;
+ int rc;
+
+ rc = ir_create_table(rc_map, from->name,
+ from->rc_type, from->size);
+ if (rc)
+ return rc;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_map->size, rc_map->alloc);
+
+ for (i = 0; i < from->size; i++) {
+ index = ir_establish_scancode(dev, rc_map,
+ from->scan[i].scancode, false);
+ if (index >= rc_map->len) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ ir_update_mapping(dev, rc_map, index,
+ from->scan[i].keycode);
+ }
+
+ if (rc)
+ ir_free_table(rc_map);
+
+ return rc;
+}
+
+/**
+ * ir_lookup_by_scancode() - locate mapping by scancode
+ * @rc_map: the struct rc_map to search
+ * @scancode: scancode to look for in the table
+ * @return: index in the table, -1U if not found
+ *
+ * This routine performs binary search in RC keykeymap table for
+ * given scancode.
+ */
+static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
+ unsigned int scancode)
+{
+ int start = 0;
+ int end = rc_map->len - 1;
+ int mid;
+
+ while (start <= end) {
+ mid = (start + end) / 2;
+ if (rc_map->scan[mid].scancode < scancode)
+ start = mid + 1;
+ else if (rc_map->scan[mid].scancode > scancode)
+ end = mid - 1;
+ else
+ return mid;
+ }
+
+ return -1U;
+}
+
+/**
+ * ir_getkeycode() - get a keycode from the scancode->keycode table
+ * @idev: the struct input_dev device descriptor
+ * @scancode: the desired scancode
+ * @keycode: used to return the keycode, if found, or KEY_RESERVED
+ * @return: always returns zero.
+ *
+ * This routine is used to handle evdev EVIOCGKEY ioctl.
+ */
+static int ir_getkeycode(struct input_dev *idev,
+ struct input_keymap_entry *ke)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct rc_map *rc_map = &rdev->rc_map;
+ struct rc_map_table *entry;
+ unsigned long flags;
+ unsigned int index;
+ unsigned int scancode;
+ int retval;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_lookup_by_scancode(rc_map, scancode);
+ }
+
+ if (index >= rc_map->len) {
+ if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
+ IR_dprintk(1, "unknown key for scancode 0x%04x\n",
+ scancode);
+ retval = -EINVAL;
+ goto out;
+ }
+
+ entry = &rc_map->scan[index];
+
+ ke->index = index;
+ ke->keycode = entry->keycode;
+ ke->len = sizeof(entry->scancode);
+ memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
+
+ retval = 0;
+
+out:
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+ return retval;
+}
+
+/**
+ * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode to look for
+ * @return: the corresponding keycode, or KEY_RESERVED
+ *
+ * This routine is used by drivers which need to convert a scancode to a
+ * keycode. Normally it should not be used since drivers should have no
+ * interest in keycodes.
+ */
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
+{
+ struct rc_map *rc_map = &dev->rc_map;
+ unsigned int keycode;
+ unsigned int index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ index = ir_lookup_by_scancode(rc_map, scancode);
+ keycode = index < rc_map->len ?
+ rc_map->scan[index].keycode : KEY_RESERVED;
+
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+
+ if (keycode != KEY_RESERVED)
+ IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
+ dev->input_name, scancode, keycode);
+
+ return keycode;
+}
+EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);
+
+/**
+ * ir_do_keyup() - internal function to signal the release of a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This function is used internally to release a keypress, it must be
+ * called with keylock held.
+ */
+static void ir_do_keyup(struct rc_dev *dev)
+{
+ if (!dev->keypressed)
+ return;
+
+ IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
+ input_report_key(dev->input_dev, dev->last_keycode, 0);
+ input_sync(dev->input_dev);
+ dev->keypressed = false;
+}
+
+/**
+ * rc_keyup() - signals the release of a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This routine is used to signal that a key has been released on the
+ * remote control.
+ */
+void rc_keyup(struct rc_dev *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keyup);
+
+/**
+ * ir_timer_keyup() - generates a keyup event after a timeout
+ * @cookie: a pointer to the struct rc_dev for the device
+ *
+ * This routine will generate a keyup event some time after a keydown event
+ * is generated when no further activity has been detected.
+ */
+static void ir_timer_keyup(unsigned long cookie)
+{
+ struct rc_dev *dev = (struct rc_dev *)cookie;
+ unsigned long flags;
+
+ /*
+ * ir->keyup_jiffies is used to prevent a race condition if a
+ * hardware interrupt occurs at this point and the keyup timer
+ * event is moved further into the future as a result.
+ *
+ * The timer will then be reactivated and this function called
+ * again in the future. We need to exit gracefully in that case
+ * to allow the input subsystem to do its auto-repeat magic or
+ * a keyup event might follow immediately after the keydown.
+ */
+ spin_lock_irqsave(&dev->keylock, flags);
+ if (time_is_before_eq_jiffies(dev->keyup_jiffies))
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+
+/**
+ * rc_repeat() - signals that a key is still pressed
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This routine is used by IR decoders when a repeat message which does
+ * not include the necessary bits to reproduce the scancode has been
+ * received.
+ */
+void rc_repeat(struct rc_dev *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->keylock, flags);
+
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
+
+ if (!dev->keypressed)
+ goto out;
+
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+
+out:
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_repeat);
+
+/**
+ * ir_do_keydown() - internal function to process a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode of the keypress
+ * @keycode: the keycode of the keypress
+ * @toggle: the toggle value of the keypress
+ *
+ * This function is used internally to register a keypress, it must be
+ * called with keylock held.
+ */
+static void ir_do_keydown(struct rc_dev *dev, int scancode,
+ u32 keycode, u8 toggle)
+{
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+
+ /* Repeat event? */
+ if (dev->keypressed &&
+ dev->last_scancode == scancode &&
+ dev->last_toggle == toggle)
+ return;
+
+ /* Release old keypress */
+ ir_do_keyup(dev);
+
+ dev->last_scancode = scancode;
+ dev->last_toggle = toggle;
+ dev->last_keycode = keycode;
+
+ if (keycode == KEY_RESERVED)
+ return;
+
+ /* Register a keypress */
+ dev->keypressed = true;
+ IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
+ dev->input_name, keycode, scancode);
+ input_report_key(dev->input_dev, dev->last_keycode, 1);
+ input_sync(dev->input_dev);
+}
+
+/**
+ * rc_keydown() - generates input event for a key press
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode that we're seeking
+ * @toggle: the toggle value (protocol dependent, if the protocol doesn't
+ * support toggle values, this should be set to zero)
+ *
+ * This routine is used to signal that a key has been pressed on the
+ * remote control.
+ */
+void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle)
+{
+ unsigned long flags;
+ u32 keycode = rc_g_keycode_from_table(dev, scancode);
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keydown(dev, scancode, keycode, toggle);
+
+ if (dev->keypressed) {
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+ }
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keydown);
+
+/**
+ * rc_keydown_notimeout() - generates input event for a key press without
+ * an automatic keyup event at a later time
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode that we're seeking
+ * @toggle: the toggle value (protocol dependent, if the protocol doesn't
+ * support toggle values, this should be set to zero)
+ *
+ * This routine is used to signal that a key has been pressed on the
+ * remote control. The driver must manually call rc_keyup() at a later stage.
+ */
+void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle)
+{
+ unsigned long flags;
+ u32 keycode = rc_g_keycode_from_table(dev, scancode);
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keydown(dev, scancode, keycode, toggle);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
+
+static int ir_open(struct input_dev *idev)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+
+ return rdev->open(rdev);
+}
+
+static void ir_close(struct input_dev *idev)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+
+ rdev->close(rdev);
+}
+
+/* class for /sys/class/rc */
+static char *ir_devnode(struct device *dev, mode_t *mode)
+{
+ return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
+}
+
+static struct class ir_input_class = {
+ .name = "rc",
+ .devnode = ir_devnode,
+};
+
+static struct {
+ u64 type;
+ char *name;
+} proto_names[] = {
+ { RC_TYPE_UNKNOWN, "unknown" },
+ { RC_TYPE_RC5, "rc-5" },
+ { RC_TYPE_NEC, "nec" },
+ { RC_TYPE_RC6, "rc-6" },
+ { RC_TYPE_JVC, "jvc" },
+ { RC_TYPE_SONY, "sony" },
+ { RC_TYPE_RC5_SZ, "rc-5-sz" },
+ { RC_TYPE_LIRC, "lirc" },
+};
+
+#define PROTO_NONE "none"
+
+/**
+ * show_protocols() - shows the current IR protocol(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the output buffer
+ *
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * It returns the protocol names of supported protocols.
+ * Enabled protocols are printed in brackets.
+ */
+static ssize_t show_protocols(struct device *device,
+ struct device_attribute *mattr, char *buf)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+ u64 allowed, enabled;
+ char *tmp = buf;
+ int i;
+
+ /* Device is being removed */
+ if (!dev)
+ return -EINVAL;
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ enabled = dev->rc_map.rc_type;
+ allowed = dev->allowed_protos;
+ } else {
+ enabled = dev->raw->enabled_protocols;
+ allowed = ir_raw_get_allowed_protocols();
+ }
+
+ IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
+ (long long)allowed,
+ (long long)enabled);
+
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (allowed & enabled & proto_names[i].type)
+ tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
+ else if (allowed & proto_names[i].type)
+ tmp += sprintf(tmp, "%s ", proto_names[i].name);
+ }
+
+ if (tmp != buf)
+ tmp--;
+ *tmp = '\n';
+ return tmp + 1 - buf;
+}
+
+/**
+ * store_protocols() - changes the current IR protocol(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the input buffer
+ * @len: length of the input buffer
+ *
+ * This routine is for changing the IR protocol type.
+ * It is trigged by writing to /sys/class/rc/rc?/protocols.
+ * Writing "+proto" will add a protocol to the list of enabled protocols.
+ * Writing "-proto" will remove a protocol from the list of enabled protocols.
+ * Writing "proto" will enable only "proto".
+ * Writing "none" will disable all protocols.
+ * Returns -EINVAL if an invalid protocol combination or unknown protocol name
+ * is used, otherwise @len.
+ */
+static ssize_t store_protocols(struct device *device,
+ struct device_attribute *mattr,
+ const char *data,
+ size_t len)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+ bool enable, disable;
+ const char *tmp;
+ u64 type;
+ u64 mask;
+ int rc, i, count = 0;
+ unsigned long flags;
+
+ /* Device is being removed */
+ if (!dev)
+ return -EINVAL;
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ type = dev->rc_map.rc_type;
+ else if (dev->raw)
+ type = dev->raw->enabled_protocols;
+ else {
+ IR_dprintk(1, "Protocol switching not supported\n");
+ return -EINVAL;
+ }
+
+ while ((tmp = strsep((char **) &data, " \n")) != NULL) {
+ if (!*tmp)
+ break;
+
+ if (*tmp == '+') {
+ enable = true;
+ disable = false;
+ tmp++;
+ } else if (*tmp == '-') {
+ enable = false;
+ disable = true;
+ tmp++;
+ } else {
+ enable = false;
+ disable = false;
+ }
+
+ if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
+ tmp += sizeof(PROTO_NONE);
+ mask = 0;
+ count++;
+ } else {
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
+ tmp += strlen(proto_names[i].name);
+ mask = proto_names[i].type;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(proto_names)) {
+ IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
+ return -EINVAL;
+ }
+ count++;
+ }
+
+ if (enable)
+ type |= mask;
+ else if (disable)
+ type &= ~mask;
+ else
+ type = mask;
+ }
+
+ if (!count) {
+ IR_dprintk(1, "Protocol not specified\n");
+ return -EINVAL;
+ }
+
+ if (dev->change_protocol) {
+ rc = dev->change_protocol(dev, type);
+ if (rc < 0) {
+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
+ (long long)type);
+ return -EINVAL;
+ }
+ }
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ spin_lock_irqsave(&dev->rc_map.lock, flags);
+ dev->rc_map.rc_type = type;
+ spin_unlock_irqrestore(&dev->rc_map.lock, flags);
+ } else {
+ dev->raw->enabled_protocols = type;
+ }
+
+ IR_dprintk(1, "Current protocol(s): 0x%llx\n",
+ (long long)type);
+
+ return len;
+}
+
+static void rc_dev_release(struct device *device)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+#define ADD_HOTPLUG_VAR(fmt, val...) \
+ do { \
+ int err = add_uevent_var(env, fmt, val); \
+ if (err) \
+ return err; \
+ } while (0)
+
+static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+
+ if (dev->rc_map.name)
+ ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
+ if (dev->driver_name)
+ ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
+
+ return 0;
+}
+
+/*
+ * Static device attribute struct with the sysfs attributes for IR's
+ */
+static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
+ show_protocols, store_protocols);
+
+static struct attribute *rc_dev_attrs[] = {
+ &dev_attr_protocols.attr,
+ NULL,
+};
+
+static struct attribute_group rc_dev_attr_grp = {
+ .attrs = rc_dev_attrs,
+};
+
+static const struct attribute_group *rc_dev_attr_groups[] = {
+ &rc_dev_attr_grp,
+ NULL
+};
+
+static struct device_type rc_dev_type = {
+ .groups = rc_dev_attr_groups,
+ .release = rc_dev_release,
+ .uevent = rc_dev_uevent,
+};
+
+struct rc_dev *rc_allocate_device(void)
+{
+ struct rc_dev *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->input_dev = input_allocate_device();
+ if (!dev->input_dev) {
+ kfree(dev);
+ return NULL;
+ }
+
+ dev->input_dev->getkeycode_new = ir_getkeycode;
+ dev->input_dev->setkeycode_new = ir_setkeycode;
+ input_set_drvdata(dev->input_dev, dev);
+
+ spin_lock_init(&dev->rc_map.lock);
+ spin_lock_init(&dev->keylock);
+ setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
+
+ dev->dev.type = &rc_dev_type;
+ dev->dev.class = &ir_input_class;
+ device_initialize(&dev->dev);
+
+ __module_get(THIS_MODULE);
+ return dev;
+}
+EXPORT_SYMBOL_GPL(rc_allocate_device);
+
+void rc_free_device(struct rc_dev *dev)
+{
+ if (dev) {
+ input_free_device(dev->input_dev);
+ put_device(&dev->dev);
+ }
+}
+EXPORT_SYMBOL_GPL(rc_free_device);
+
+int rc_register_device(struct rc_dev *dev)
+{
+ static atomic_t devno = ATOMIC_INIT(0);
+ struct rc_map *rc_map;
+ const char *path;
+ int rc;
+
+ if (!dev || !dev->map_name)
+ return -EINVAL;
+
+ rc_map = rc_map_get(dev->map_name);
+ if (!rc_map)
+ rc_map = rc_map_get(RC_MAP_EMPTY);
+ if (!rc_map || !rc_map->scan || rc_map->size == 0)
+ return -EINVAL;
+
+ set_bit(EV_KEY, dev->input_dev->evbit);
+ set_bit(EV_REP, dev->input_dev->evbit);
+ set_bit(EV_MSC, dev->input_dev->evbit);
+ set_bit(MSC_SCAN, dev->input_dev->mscbit);
+ if (dev->open)
+ dev->input_dev->open = ir_open;
+ if (dev->close)
+ dev->input_dev->close = ir_close;
+
+ dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
+ dev_set_name(&dev->dev, "rc%ld", dev->devno);
+ dev_set_drvdata(&dev->dev, dev);
+ rc = device_add(&dev->dev);
+ if (rc)
+ return rc;
+
+ rc = ir_setkeytable(dev, rc_map);
+ if (rc)
+ goto out_dev;
+
+ dev->input_dev->dev.parent = &dev->dev;
+ memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
+ dev->input_dev->phys = dev->input_phys;
+ dev->input_dev->name = dev->input_name;
+ rc = input_register_device(dev->input_dev);
+ if (rc)
+ goto out_table;
+
+ /*
+ * Default delay of 250ms is too short for some protocols, expecially
+ * since the timeout is currently set to 250ms. Increase it to 500ms,
+ * to avoid wrong repetition of the keycodes. Note that this must be
+ * set after the call to input_register_device().
+ */
+ dev->input_dev->rep[REP_DELAY] = 500;
+
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
+ printk(KERN_INFO "%s: %s as %s\n",
+ dev_name(&dev->dev),
+ dev->input_name ? dev->input_name : "Unspecified device",
+ path ? path : "N/A");
+ kfree(path);
+
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
+ rc = ir_raw_event_register(dev);
+ if (rc < 0)
+ goto out_input;
+ }
+
+ if (dev->change_protocol) {
+ rc = dev->change_protocol(dev, rc_map->rc_type);
+ if (rc < 0)
+ goto out_raw;
+ }
+
+ IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n",
+ dev->devno,
+ dev->driver_name ? dev->driver_name : "unknown",
+ rc_map->name ? rc_map->name : "unknown",
+ dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");
+
+ return 0;
+
+out_raw:
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ ir_raw_event_unregister(dev);
+out_input:
+ input_unregister_device(dev->input_dev);
+ dev->input_dev = NULL;
+out_table:
+ ir_free_table(&dev->rc_map);
+out_dev:
+ device_del(&dev->dev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(rc_register_device);
+
+void rc_unregister_device(struct rc_dev *dev)
+{
+ if (!dev)
+ return;
+
+ del_timer_sync(&dev->timer_keyup);
+
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ ir_raw_event_unregister(dev);
+
+ input_unregister_device(dev->input_dev);
+ dev->input_dev = NULL;
+
+ ir_free_table(&dev->rc_map);
+ IR_dprintk(1, "Freed keycode table\n");
+
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(rc_unregister_device);
+
+/*
+ * Init/exit code for the module. Basically, creates/removes /sys/class/rc
+ */
+
+static int __init rc_core_init(void)
+{
+ int rc = class_register(&ir_input_class);
+ if (rc) {
+ printk(KERN_ERR "rc_core: unable to register rc class\n");
+ return rc;
+ }
+
+ /* Initialize/load the decoders/keymap code that will be used */
+ ir_raw_init();
+ rc_map_register(&empty_map);
+
+ return 0;
+}
+
+static void __exit rc_core_exit(void)
+{
+ class_unregister(&ir_input_class);
+ rc_map_unregister(&empty_map);
+}
+
+module_init(rc_core_init);
+module_exit(rc_core_exit);
+
+int rc_core_debug; /* ir_debug level (0,1,2) */
+EXPORT_SYMBOL_GPL(rc_core_debug);
+module_param_named(debug, rc_core_debug, int, 0644);
+
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/rc/streamzap.c
index 548381c35bfd..6e2911c2abfb 100644
--- a/drivers/media/IR/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -35,8 +35,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
@@ -73,7 +73,7 @@ MODULE_DEVICE_TABLE(usb, streamzap_table);
#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
#else
-#define load_rc5_sz_decode() 0
+#define load_rc5_sz_decode() {}
#endif
enum StreamzapDecoderState {
@@ -85,13 +85,11 @@ enum StreamzapDecoderState {
/* structure to hold our device specific stuff */
struct streamzap_ir {
-
/* ir-core */
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* core device info */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
@@ -140,7 +138,9 @@ static struct usb_driver streamzap_driver = {
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
- ir_raw_event_store(sz->idev, &rawir);
+ dev_dbg(sz->dev, "Storing %s with duration %u us\n",
+ (rawir.pulse ? "pulse" : "space"), rawir.duration);
+ ir_raw_event_store_with_filter(sz->rdev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
@@ -167,7 +167,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
}
- dev_dbg(sz->dev, "ls %u\n", rawir.duration);
sz_push(sz, rawir);
sz->idle = false;
@@ -180,7 +179,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
- dev_dbg(sz->dev, "p %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -200,7 +198,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
- dev_dbg(sz->dev, "s %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -221,8 +218,6 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz;
unsigned int i;
int len;
- static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
- IR_MAX_DURATION) | 0x03000000);
if (!urb)
return;
@@ -246,7 +241,7 @@ static void streamzap_callback(struct urb *urb)
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
for (i = 0; i < len; i++) {
- dev_dbg(sz->dev, "sz idx %d: %x\n",
+ dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
i, (unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) {
case PulseSpace:
@@ -273,11 +268,11 @@ static void streamzap_callback(struct urb *urb)
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
- rawir.duration = timeout;
+ rawir.duration = sz->rdev->timeout;
sz->idle = true;
if (sz->timeout_enabled)
sz_push(sz, rawir);
- ir_raw_event_handle(sz->idev);
+ ir_raw_event_handle(sz->rdev);
} else {
sz_push_full_space(sz, sz->buf_in[i]);
}
@@ -300,54 +295,45 @@ static void streamzap_callback(struct urb *urb)
return;
}
-static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
+static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct device *dev = sz->dev;
int ret;
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
-
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rdev = rc_allocate_device();
+ if (!rdev) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
"Receiver (%04x:%04x)",
le16_to_cpu(sz->usbdev->descriptor.idVendor),
le16_to_cpu(sz->usbdev->descriptor.idProduct));
-
- idev->name = sz->name;
usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
strlcat(sz->phys, "/input0", sizeof(sz->phys));
- idev->phys = sz->phys;
-
- props->priv = sz;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- sz->props = props;
-
- ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
+ rdev->input_name = sz->name;
+ rdev->input_phys = sz->phys;
+ usb_to_input_id(sz->usbdev, &rdev->input_id);
+ rdev->dev.parent = dev;
+ rdev->priv = sz;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->driver_name = DRIVER_NAME;
+ rdev->map_name = RC_MAP_STREAMZAP;
+
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ goto out;
}
- return idev;
+ return rdev;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rdev);
return NULL;
}
@@ -436,14 +422,16 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- sz->idev = streamzap_init_input_dev(sz);
- if (!sz->idev)
- goto input_dev_fail;
+ sz->rdev = streamzap_init_rc_dev(sz);
+ if (!sz->rdev)
+ goto rc_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
+ sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+ IR_MAX_DURATION) | 0x03000000);
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
@@ -473,7 +461,7 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
return 0;
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@@ -504,7 +492,7 @@ static void streamzap_disconnect(struct usb_interface *interface)
return;
sz->usbdev = NULL;
- ir_input_unregister(sz->idev);
+ rc_unregister_device(sz->rdev);
usb_kill_urb(sz->urb_in);
usb_free_urb(sz->urb_in);
usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 64f1de7960c6..186de5522001 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -7,10 +7,10 @@
* with minor modifications.
*
* Original Author: David Härdeman <david@hardeman.nu>
- * Copyright (C) 2009 David Härdeman <david@hardeman.nu>
+ * Copyright (C) 2009 - 2010 David Härdeman <david@hardeman.nu>
*
- * Dedicated to Matilda, my newborn daughter, without whose loving attention
- * this driver would have been finished in half the time and with a fraction
+ * Dedicated to my daughter Matilda, without whose loving attention this
+ * driver would have been finished in half the time and with a fraction
* of the bugs.
*
* Written using:
@@ -19,15 +19,11 @@
* o DSDT dumps
*
* Supported features:
- * o RC6
* o Wake-On-CIR functionality
*
* To do:
- * o Test NEC and RC5
- *
- * Left as an exercise for the reader:
- * o Learning (I have neither the hardware, nor the need)
- * o IR Transmit (ibid)
+ * o Learning
+ * o IR Transmit
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,15 +44,13 @@
#include <linux/pnp.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/input.h>
#include <linux/leds.h>
-#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/pci_ids.h>
#include <linux/io.h>
#include <linux/bitrev.h>
-#include <linux/bitops.h>
#include <linux/slab.h>
+#include <media/rc-core.h>
#define DRVNAME "winbond-cir"
@@ -108,7 +102,7 @@
#define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */
/* Bank 6 */
#define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */
-#define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */
+#define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */
/* Bank 7 */
#define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */
#define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */
@@ -153,7 +147,7 @@ enum wbcir_bank {
WBCIR_BANK_7 = 0xF4,
};
-/* Supported IR Protocols */
+/* Supported power-on IR Protocols */
enum wbcir_protocol {
IR_PROTOCOL_RC5 = 0x0,
IR_PROTOCOL_NEC = 0x1,
@@ -164,113 +158,35 @@ enum wbcir_protocol {
#define WBCIR_NAME "Winbond CIR"
#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */
#define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */
-#define IR_KEYPRESS_TIMEOUT 250 /* FIXME: should be per-protocol? */
#define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */
#define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */
#define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */
#define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */
-#define WBCIR_MAX_IDLE_BYTES 10
-
-static DEFINE_SPINLOCK(wbcir_lock);
-static DEFINE_RWLOCK(keytable_lock);
-struct wbcir_key {
- u32 scancode;
- unsigned int keycode;
-};
-
-struct wbcir_keyentry {
- struct wbcir_key key;
- struct list_head list;
-};
-
-static struct wbcir_key rc6_def_keymap[] = {
- { 0x800F0400, KEY_NUMERIC_0 },
- { 0x800F0401, KEY_NUMERIC_1 },
- { 0x800F0402, KEY_NUMERIC_2 },
- { 0x800F0403, KEY_NUMERIC_3 },
- { 0x800F0404, KEY_NUMERIC_4 },
- { 0x800F0405, KEY_NUMERIC_5 },
- { 0x800F0406, KEY_NUMERIC_6 },
- { 0x800F0407, KEY_NUMERIC_7 },
- { 0x800F0408, KEY_NUMERIC_8 },
- { 0x800F0409, KEY_NUMERIC_9 },
- { 0x800F041D, KEY_NUMERIC_STAR },
- { 0x800F041C, KEY_NUMERIC_POUND },
- { 0x800F0410, KEY_VOLUMEUP },
- { 0x800F0411, KEY_VOLUMEDOWN },
- { 0x800F0412, KEY_CHANNELUP },
- { 0x800F0413, KEY_CHANNELDOWN },
- { 0x800F040E, KEY_MUTE },
- { 0x800F040D, KEY_VENDOR }, /* Vista Logo Key */
- { 0x800F041E, KEY_UP },
- { 0x800F041F, KEY_DOWN },
- { 0x800F0420, KEY_LEFT },
- { 0x800F0421, KEY_RIGHT },
- { 0x800F0422, KEY_OK },
- { 0x800F0423, KEY_ESC },
- { 0x800F040F, KEY_INFO },
- { 0x800F040A, KEY_CLEAR },
- { 0x800F040B, KEY_ENTER },
- { 0x800F045B, KEY_RED },
- { 0x800F045C, KEY_GREEN },
- { 0x800F045D, KEY_YELLOW },
- { 0x800F045E, KEY_BLUE },
- { 0x800F045A, KEY_TEXT },
- { 0x800F0427, KEY_SWITCHVIDEOMODE },
- { 0x800F040C, KEY_POWER },
- { 0x800F0450, KEY_RADIO },
- { 0x800F0448, KEY_PVR },
- { 0x800F0447, KEY_AUDIO },
- { 0x800F0426, KEY_EPG },
- { 0x800F0449, KEY_CAMERA },
- { 0x800F0425, KEY_TV },
- { 0x800F044A, KEY_VIDEO },
- { 0x800F0424, KEY_DVD },
- { 0x800F0416, KEY_PLAY },
- { 0x800F0418, KEY_PAUSE },
- { 0x800F0419, KEY_STOP },
- { 0x800F0414, KEY_FASTFORWARD },
- { 0x800F041A, KEY_NEXT },
- { 0x800F041B, KEY_PREVIOUS },
- { 0x800F0415, KEY_REWIND },
- { 0x800F0417, KEY_RECORD },
-};
-
-/* Registers and other state is protected by wbcir_lock */
+/* Per-device data */
struct wbcir_data {
+ spinlock_t spinlock;
+
unsigned long wbase; /* Wake-Up Baseaddr */
unsigned long ebase; /* Enhanced Func. Baseaddr */
unsigned long sbase; /* Serial Port Baseaddr */
unsigned int irq; /* Serial Port IRQ */
- struct input_dev *input_dev;
- struct timer_list timer_keyup;
+ struct rc_dev *dev;
+
struct led_trigger *rxtrigger;
struct led_trigger *txtrigger;
struct led_classdev led;
- u32 last_scancode;
- unsigned int last_keycode;
- u8 last_toggle;
- u8 keypressed;
- unsigned long keyup_jiffies;
- unsigned int idle_count;
-
- /* RX irdata and parsing state */
- unsigned long irdata[30];
- unsigned int irdata_count;
- unsigned int irdata_idle;
- unsigned int irdata_off;
- unsigned int irdata_error;
-
- /* Protected by keytable_lock */
- struct list_head keytable;
+ /* RX irdata state */
+ bool irdata_active;
+ bool irdata_error;
+ struct ir_raw_event ev;
};
static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
module_param(protocol, uint, 0444);
-MODULE_PARM_DESC(protocol, "IR protocol to use "
+MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command "
"(0 = RC5, 1 = NEC, 2 = RC6A, default)");
static int invert; /* default = 0 */
@@ -327,7 +243,7 @@ wbcir_led_brightness_get(struct led_classdev *led_cdev)
static void
wbcir_led_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness brightness)
+ enum led_brightness brightness)
{
struct wbcir_data *data = container_of(led_cdev,
struct wbcir_data,
@@ -338,7 +254,7 @@ wbcir_led_brightness_set(struct led_classdev *led_cdev,
WBCIR_LED_ENABLE);
}
-/* Manchester encodes bits to RC6 message cells (see wbcir_parse_rc6) */
+/* Manchester encodes bits to RC6 message cells (see wbcir_shutdown) */
static u8
wbcir_to_rc6cells(u8 val)
{
@@ -357,579 +273,6 @@ wbcir_to_rc6cells(u8 val)
return coded;
}
-
-
-/*****************************************************************************
- *
- * INPUT FUNCTIONS
- *
- *****************************************************************************/
-
-static unsigned int
-wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
-{
- struct wbcir_keyentry *keyentry;
- unsigned int keycode = KEY_RESERVED;
- unsigned long flags;
-
- read_lock_irqsave(&keytable_lock, flags);
-
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.scancode == scancode) {
- keycode = keyentry->key.keycode;
- break;
- }
- }
-
- read_unlock_irqrestore(&keytable_lock, flags);
- return keycode;
-}
-
-static int
-wbcir_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct wbcir_data *data = input_get_drvdata(dev);
-
- *keycode = wbcir_do_getkeycode(data, scancode);
- return 0;
-}
-
-static int
-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;
-
- new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
- if (!new_keyentry)
- return -ENOMEM;
-
- write_lock_irqsave(&keytable_lock, flags);
-
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.scancode != scancode)
- continue;
-
- old_keycode = keyentry->key.keycode;
- keyentry->key.keycode = keycode;
-
- if (keyentry->key.keycode == KEY_RESERVED) {
- list_del(&keyentry->list);
- kfree(keyentry);
- }
-
- break;
- }
-
- set_bit(keycode, dev->keybit);
-
- if (old_keycode == KEY_RESERVED) {
- new_keyentry->key.scancode = scancode;
- new_keyentry->key.keycode = keycode;
- list_add(&new_keyentry->list, &data->keytable);
- } else {
- kfree(new_keyentry);
- clear_bit(old_keycode, dev->keybit);
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.keycode == old_keycode) {
- set_bit(old_keycode, dev->keybit);
- break;
- }
- }
- }
-
- write_unlock_irqrestore(&keytable_lock, flags);
- return 0;
-}
-
-/*
- * Timer function to report keyup event some time after keydown is
- * reported by the ISR.
- */
-static void
-wbcir_keyup(unsigned long cookie)
-{
- struct wbcir_data *data = (struct wbcir_data *)cookie;
- unsigned long flags;
-
- /*
- * data->keyup_jiffies is used to prevent a race condition if a
- * hardware interrupt occurs at this point and the keyup timer
- * event is moved further into the future as a result.
- *
- * The timer will then be reactivated and this function called
- * again in the future. We need to exit gracefully in that case
- * to allow the input subsystem to do its auto-repeat magic or
- * a keyup event might follow immediately after the keydown.
- */
-
- spin_lock_irqsave(&wbcir_lock, flags);
-
- if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) {
- data->keypressed = 0;
- led_trigger_event(data->rxtrigger, LED_OFF);
- input_report_key(data->input_dev, data->last_keycode, 0);
- input_sync(data->input_dev);
- }
-
- spin_unlock_irqrestore(&wbcir_lock, flags);
-}
-
-static void
-wbcir_keydown(struct wbcir_data *data, u32 scancode, u8 toggle)
-{
- unsigned int keycode;
-
- /* Repeat? */
- if (data->last_scancode == scancode &&
- data->last_toggle == toggle &&
- data->keypressed)
- goto set_timer;
- data->last_scancode = scancode;
-
- /* Do we need to release an old keypress? */
- if (data->keypressed) {
- input_report_key(data->input_dev, data->last_keycode, 0);
- input_sync(data->input_dev);
- data->keypressed = 0;
- }
-
- /* Report scancode */
- input_event(data->input_dev, EV_MSC, MSC_SCAN, (int)scancode);
-
- /* Do we know this scancode? */
- keycode = wbcir_do_getkeycode(data, scancode);
- if (keycode == KEY_RESERVED)
- goto set_timer;
-
- /* Register a keypress */
- input_report_key(data->input_dev, keycode, 1);
- data->keypressed = 1;
- data->last_keycode = keycode;
- data->last_toggle = toggle;
-
-set_timer:
- input_sync(data->input_dev);
- led_trigger_event(data->rxtrigger,
- data->keypressed ? LED_FULL : LED_OFF);
- data->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&data->timer_keyup, data->keyup_jiffies);
-}
-
-
-
-/*****************************************************************************
- *
- * IR PARSING FUNCTIONS
- *
- *****************************************************************************/
-
-/* Resets all irdata */
-static void
-wbcir_reset_irdata(struct wbcir_data *data)
-{
- memset(data->irdata, 0, sizeof(data->irdata));
- data->irdata_count = 0;
- data->irdata_off = 0;
- data->irdata_error = 0;
- data->idle_count = 0;
-}
-
-/* Adds one bit of irdata */
-static void
-add_irdata_bit(struct wbcir_data *data, int set)
-{
- if (data->irdata_count >= sizeof(data->irdata) * 8) {
- data->irdata_error = 1;
- return;
- }
-
- if (set)
- __set_bit(data->irdata_count, data->irdata);
- data->irdata_count++;
-}
-
-/* Gets count bits of irdata */
-static u16
-get_bits(struct wbcir_data *data, int count)
-{
- u16 val = 0x0;
-
- if (data->irdata_count - data->irdata_off < count) {
- data->irdata_error = 1;
- return 0x0;
- }
-
- while (count > 0) {
- val <<= 1;
- if (test_bit(data->irdata_off, data->irdata))
- val |= 0x1;
- count--;
- data->irdata_off++;
- }
-
- return val;
-}
-
-/* Reads 16 cells and converts them to a byte */
-static u8
-wbcir_rc6cells_to_byte(struct wbcir_data *data)
-{
- u16 raw = get_bits(data, 16);
- u8 val = 0x00;
- int bit;
-
- for (bit = 0; bit < 8; bit++) {
- switch (raw & 0x03) {
- case 0x01:
- break;
- case 0x02:
- val |= (0x01 << bit);
- break;
- default:
- data->irdata_error = 1;
- break;
- }
- raw >>= 2;
- }
-
- return val;
-}
-
-/* Decodes a number of bits from raw RC5 data */
-static u8
-wbcir_get_rc5bits(struct wbcir_data *data, unsigned int count)
-{
- u16 raw = get_bits(data, count * 2);
- u8 val = 0x00;
- int bit;
-
- for (bit = 0; bit < count; bit++) {
- switch (raw & 0x03) {
- case 0x01:
- val |= (0x01 << bit);
- break;
- case 0x02:
- break;
- default:
- data->irdata_error = 1;
- break;
- }
- raw >>= 2;
- }
-
- return val;
-}
-
-static void
-wbcir_parse_rc6(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Normal bits are manchester coded as follows:
- * cell0 + cell1 = logic "0"
- * cell1 + cell0 = logic "1"
- *
- * The IR pulse has the following components:
- *
- * Leader - 6 * cell1 - discarded
- * Gap - 2 * cell0 - discarded
- * Start bit - Normal Coding - always "1"
- * Mode Bit 2 - 0 - Normal Coding
- * Toggle bit - Normal Coding with double bit time,
- * e.g. cell0 + cell0 + cell1 + cell1
- * means logic "0".
- *
- * The rest depends on the mode, the following modes are known:
- *
- * MODE 0:
- * Address Bit 7 - 0 - Normal Coding
- * Command Bit 7 - 0 - Normal Coding
- *
- * MODE 6:
- * The above Toggle Bit is used as a submode bit, 0 = A, 1 = B.
- * Submode B is for pointing devices, only remotes using submode A
- * are supported.
- *
- * Customer range bit - 0 => Customer = 7 bits, 0...127
- * 1 => Customer = 15 bits, 32768...65535
- * Customer Bits - Normal Coding
- *
- * Customer codes are allocated by Philips. The rest of the bits
- * are customer dependent. The following is commonly used (and the
- * only supported config):
- *
- * Toggle Bit - Normal Coding
- * Address Bit 6 - 0 - Normal Coding
- * Command Bit 7 - 0 - Normal Coding
- *
- * All modes are followed by at least 6 * cell0.
- *
- * MODE 0 msglen:
- * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (toggle) +
- * 8 * 2 (address) + 8 * 2 (command) =
- * 44 cells
- *
- * MODE 6A msglen:
- * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (submode) +
- * 1 * 2 (customer range bit) + 7/15 * 2 (customer bits) +
- * 1 * 2 (toggle bit) + 7 * 2 (address) + 8 * 2 (command) =
- * 60 - 76 cells
- */
- u8 mode;
- u8 toggle;
- u16 customer = 0x0;
- u8 address;
- u8 command;
- u32 scancode;
-
- /* Leader mark */
- while (get_bits(data, 1) && !data->irdata_error)
- /* Do nothing */;
-
- /* Leader space */
- if (get_bits(data, 1)) {
- dev_dbg(dev, "RC6 - Invalid leader space\n");
- return;
- }
-
- /* Start bit */
- if (get_bits(data, 2) != 0x02) {
- dev_dbg(dev, "RC6 - Invalid start bit\n");
- return;
- }
-
- /* Mode */
- mode = get_bits(data, 6);
- switch (mode) {
- case 0x15: /* 010101 = b000 */
- mode = 0;
- break;
- case 0x29: /* 101001 = b110 */
- mode = 6;
- break;
- default:
- dev_dbg(dev, "RC6 - Invalid mode\n");
- return;
- }
-
- /* Toggle bit / Submode bit */
- toggle = get_bits(data, 4);
- switch (toggle) {
- case 0x03:
- toggle = 0;
- break;
- case 0x0C:
- toggle = 1;
- break;
- default:
- dev_dbg(dev, "RC6 - Toggle bit error\n");
- break;
- }
-
- /* Customer */
- if (mode == 6) {
- if (toggle != 0) {
- dev_dbg(dev, "RC6B - Not Supported\n");
- return;
- }
-
- customer = wbcir_rc6cells_to_byte(data);
-
- if (customer & 0x80) {
- /* 15 bit customer value */
- customer <<= 8;
- customer |= wbcir_rc6cells_to_byte(data);
- }
- }
-
- /* Address */
- address = wbcir_rc6cells_to_byte(data);
- if (mode == 6) {
- toggle = address >> 7;
- address &= 0x7F;
- }
-
- /* Command */
- command = wbcir_rc6cells_to_byte(data);
-
- /* Create scancode */
- scancode = command;
- scancode |= address << 8;
- scancode |= customer << 16;
-
- /* Last sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "RC6 - Cell error(s)\n");
- return;
- }
-
- dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
- "toggle %u mode %u scan 0x%08X\n",
- address,
- command,
- customer,
- (unsigned int)toggle,
- (unsigned int)mode,
- scancode);
-
- wbcir_keydown(data, scancode, toggle);
-}
-
-static void
-wbcir_parse_rc5(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Bits are manchester coded as follows:
- * cell1 + cell0 = logic "0"
- * cell0 + cell1 = logic "1"
- * (i.e. the reverse of RC6)
- *
- * Start bit 1 - "1" - discarded
- * Start bit 2 - Must be inverted to get command bit 6
- * Toggle bit
- * Address Bit 4 - 0
- * Command Bit 5 - 0
- */
- u8 toggle;
- u8 address;
- u8 command;
- u32 scancode;
-
- /* Start bit 1 */
- if (!get_bits(data, 1)) {
- dev_dbg(dev, "RC5 - Invalid start bit\n");
- return;
- }
-
- /* Start bit 2 */
- if (!wbcir_get_rc5bits(data, 1))
- command = 0x40;
- else
- command = 0x00;
-
- toggle = wbcir_get_rc5bits(data, 1);
- address = wbcir_get_rc5bits(data, 5);
- command |= wbcir_get_rc5bits(data, 6);
- scancode = address << 7 | command;
-
- /* Last sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "RC5 - Invalid message\n");
- return;
- }
-
- dev_dbg(dev, "IR-RC5 ad %u cm %u t %u s %u\n",
- (unsigned int)address,
- (unsigned int)command,
- (unsigned int)toggle,
- (unsigned int)scancode);
-
- wbcir_keydown(data, scancode, toggle);
-}
-
-static void
-wbcir_parse_nec(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Each bit represents 560 us.
- *
- * Leader - 9 ms burst
- * Gap - 4.5 ms silence
- * Address1 bit 0 - 7 - Address 1
- * Address2 bit 0 - 7 - Address 2
- * Command1 bit 0 - 7 - Command 1
- * Command2 bit 0 - 7 - Command 2
- *
- * Note the bit order!
- *
- * With the old NEC protocol, Address2 was the inverse of Address1
- * and Command2 was the inverse of Command1 and were used as
- * an error check.
- *
- * With NEC extended, Address1 is the LSB of the Address and
- * Address2 is the MSB, Command parsing remains unchanged.
- *
- * A repeat message is coded as:
- * Leader - 9 ms burst
- * Gap - 2.25 ms silence
- * Repeat - 560 us active
- */
- u8 address1;
- u8 address2;
- u8 command1;
- u8 command2;
- u16 address;
- u32 scancode;
-
- /* Leader mark */
- while (get_bits(data, 1) && !data->irdata_error)
- /* Do nothing */;
-
- /* Leader space */
- if (get_bits(data, 4)) {
- dev_dbg(dev, "NEC - Invalid leader space\n");
- return;
- }
-
- /* Repeat? */
- if (get_bits(data, 1)) {
- if (!data->keypressed) {
- dev_dbg(dev, "NEC - Stray repeat message\n");
- return;
- }
-
- dev_dbg(dev, "IR-NEC repeat s %u\n",
- (unsigned int)data->last_scancode);
-
- wbcir_keydown(data, data->last_scancode, data->last_toggle);
- return;
- }
-
- /* Remaining leader space */
- if (get_bits(data, 3)) {
- dev_dbg(dev, "NEC - Invalid leader space\n");
- return;
- }
-
- address1 = bitrev8(get_bits(data, 8));
- address2 = bitrev8(get_bits(data, 8));
- command1 = bitrev8(get_bits(data, 8));
- command2 = bitrev8(get_bits(data, 8));
-
- /* Sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "NEC - Invalid message\n");
- return;
- }
-
- /* Check command validity */
- if (command1 != ~command2) {
- dev_dbg(dev, "NEC - Command bytes mismatch\n");
- return;
- }
-
- /* Check for extended NEC protocol */
- address = address1;
- if (address1 != ~address2)
- address |= address2 << 8;
-
- scancode = address << 8 | command1;
-
- dev_dbg(dev, "IR-NEC ad %u cm %u s %u\n",
- (unsigned int)address,
- (unsigned int)command1,
- (unsigned int)scancode);
-
- wbcir_keydown(data, scancode, !data->last_toggle);
-}
-
-
-
/*****************************************************************************
*
* INTERRUPT FUNCTIONS
@@ -941,75 +284,88 @@ wbcir_irq_handler(int irqno, void *cookie)
{
struct pnp_dev *device = cookie;
struct wbcir_data *data = pnp_get_drvdata(device);
- struct device *dev = &device->dev;
- u8 status;
unsigned long flags;
u8 irdata[8];
+ u8 disable = true;
+ u8 status;
int i;
- unsigned int hw;
- spin_lock_irqsave(&wbcir_lock, flags);
+ spin_lock_irqsave(&data->spinlock, flags);
wbcir_select_bank(data, WBCIR_BANK_0);
status = inb(data->sbase + WBCIR_REG_SP3_EIR);
if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) {
- spin_unlock_irqrestore(&wbcir_lock, flags);
+ spin_unlock_irqrestore(&data->spinlock, flags);
return IRQ_NONE;
}
- if (status & WBCIR_IRQ_ERR)
- data->irdata_error = 1;
+ /* Check for e.g. buffer overflow */
+ if (status & WBCIR_IRQ_ERR) {
+ data->irdata_error = true;
+ ir_raw_event_reset(data->dev);
+ }
if (!(status & WBCIR_IRQ_RX))
goto out;
+ if (!data->irdata_active) {
+ data->irdata_active = true;
+ led_trigger_event(data->rxtrigger, LED_FULL);
+ }
+
/* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8);
- for (i = 0; i < sizeof(irdata); i++) {
- hw = hweight8(irdata[i]);
- if (hw > 4)
- add_irdata_bit(data, 0);
- else
- add_irdata_bit(data, 1);
+ for (i = 0; i < 8; i++) {
+ u8 pulse;
+ u32 duration;
- if (hw == 8)
- data->idle_count++;
- else
- data->idle_count = 0;
+ if (irdata[i] != 0xFF && irdata[i] != 0x00)
+ disable = false;
+
+ if (data->irdata_error)
+ continue;
+
+ pulse = irdata[i] & 0x80 ? false : true;
+ duration = (irdata[i] & 0x7F) * 10000; /* ns */
+
+ if (data->ev.pulse != pulse) {
+ if (data->ev.duration != 0) {
+ ir_raw_event_store(data->dev, &data->ev);
+ data->ev.duration = 0;
+ }
+
+ data->ev.pulse = pulse;
+ }
+
+ data->ev.duration += duration;
}
- if (data->idle_count > WBCIR_MAX_IDLE_BYTES) {
- /* Set RXINACTIVE... */
+ if (disable) {
+ if (data->ev.duration != 0 && !data->irdata_error) {
+ ir_raw_event_store(data->dev, &data->ev);
+ data->ev.duration = 0;
+ }
+
+ /* Set RXINACTIVE */
outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
- /* ...and drain the FIFO */
+ /* Drain the FIFO */
while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL)
inb(data->sbase + WBCIR_REG_SP3_RXDATA);
- dev_dbg(dev, "IRDATA:\n");
- for (i = 0; i < data->irdata_count; i += BITS_PER_LONG)
- dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]);
-
- switch (protocol) {
- case IR_PROTOCOL_RC5:
- wbcir_parse_rc5(dev, data);
- break;
- case IR_PROTOCOL_RC6:
- wbcir_parse_rc6(dev, data);
- break;
- case IR_PROTOCOL_NEC:
- wbcir_parse_nec(dev, data);
- break;
- }
-
- wbcir_reset_irdata(data);
+ ir_raw_event_reset(data->dev);
+ data->irdata_error = false;
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
}
+ ir_raw_event_handle(data->dev);
+
out:
- spin_unlock_irqrestore(&wbcir_lock, flags);
+ spin_unlock_irqrestore(&data->spinlock, flags);
return IRQ_HANDLED;
}
@@ -1199,6 +555,10 @@ finish:
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+ /* Disable LED */
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
+
/*
* ACPI will set the HW disable bit for SP3 which means that the
* output signals are left in an undefined state which may cause
@@ -1323,8 +683,15 @@ wbcir_init_hw(struct wbcir_data *data)
/* Clear AUX status bits */
outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
+ /* Clear IR decoding state */
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
+ data->irdata_error = false;
+ data->ev.duration = 0;
+ ir_raw_event_reset(data->dev);
+ ir_raw_event_handle(data->dev);
+
/* Enable interrupts */
- wbcir_reset_irdata(data);
outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
}
@@ -1361,6 +728,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
pnp_set_drvdata(device, data);
+ spin_lock_init(&data->spinlock);
data->ebase = pnp_port_start(device, 0);
data->wbase = pnp_port_start(device, 1);
data->sbase = pnp_port_start(device, 2);
@@ -1426,43 +794,25 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
if (err)
goto exit_unregister_rxtrigger;
- data->input_dev = input_allocate_device();
- if (!data->input_dev) {
+ data->dev = rc_allocate_device();
+ if (!data->dev) {
err = -ENOMEM;
goto exit_unregister_led;
}
- data->input_dev->evbit[0] = BIT(EV_KEY);
- data->input_dev->name = WBCIR_NAME;
- data->input_dev->phys = "wbcir/cir0";
- data->input_dev->id.bustype = BUS_HOST;
- data->input_dev->id.vendor = PCI_VENDOR_ID_WINBOND;
- data->input_dev->id.product = WBCIR_ID_FAMILY;
- data->input_dev->id.version = WBCIR_ID_CHIP;
- data->input_dev->getkeycode = wbcir_getkeycode;
- data->input_dev->setkeycode = wbcir_setkeycode;
- input_set_capability(data->input_dev, EV_MSC, MSC_SCAN);
- input_set_drvdata(data->input_dev, data);
-
- err = input_register_device(data->input_dev);
+ data->dev->driver_name = WBCIR_NAME;
+ data->dev->input_name = WBCIR_NAME;
+ data->dev->input_phys = "wbcir/cir0";
+ data->dev->input_id.bustype = BUS_HOST;
+ data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
+ data->dev->input_id.product = WBCIR_ID_FAMILY;
+ data->dev->input_id.version = WBCIR_ID_CHIP;
+ data->dev->priv = data;
+ data->dev->dev.parent = &device->dev;
+
+ err = rc_register_device(data->dev);
if (err)
- goto exit_free_input;
-
- data->last_scancode = INVALID_SCANCODE;
- INIT_LIST_HEAD(&data->keytable);
- setup_timer(&data->timer_keyup, wbcir_keyup, (unsigned long)data);
-
- /* Load default keymaps */
- if (protocol == IR_PROTOCOL_RC6) {
- int i;
- for (i = 0; i < ARRAY_SIZE(rc6_def_keymap); i++) {
- err = wbcir_setkeycode(data->input_dev,
- (int)rc6_def_keymap[i].scancode,
- (int)rc6_def_keymap[i].keycode);
- if (err)
- goto exit_unregister_keys;
- }
- }
+ goto exit_free_rc;
device_init_wakeup(&device->dev, 1);
@@ -1470,21 +820,8 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
return 0;
-exit_unregister_keys:
- if (!list_empty(&data->keytable)) {
- struct wbcir_keyentry *key;
- struct wbcir_keyentry *keytmp;
-
- list_for_each_entry_safe(key, keytmp, &data->keytable, list) {
- list_del(&key->list);
- kfree(key);
- }
- }
- input_unregister_device(data->input_dev);
- /* Can't call input_free_device on an unregistered device */
- data->input_dev = NULL;
-exit_free_input:
- input_free_device(data->input_dev);
+exit_free_rc:
+ rc_free_device(data->dev);
exit_unregister_led:
led_classdev_unregister(&data->led);
exit_unregister_rxtrigger:
@@ -1510,15 +847,11 @@ static void __devexit
wbcir_remove(struct pnp_dev *device)
{
struct wbcir_data *data = pnp_get_drvdata(device);
- struct wbcir_keyentry *key;
- struct wbcir_keyentry *keytmp;
/* Disable interrupts */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
- del_timer_sync(&data->timer_keyup);
-
free_irq(data->irq, device);
/* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */
@@ -1530,8 +863,7 @@ wbcir_remove(struct pnp_dev *device)
/* Clear BUFF_EN, END_EN, MATCH_EN */
wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
- /* This will generate a keyup event if necessary */
- input_unregister_device(data->input_dev);
+ rc_unregister_device(data->dev);
led_trigger_unregister_simple(data->rxtrigger);
led_trigger_unregister_simple(data->txtrigger);
@@ -1544,11 +876,6 @@ wbcir_remove(struct pnp_dev *device)
release_region(data->ebase, EHFUNC_IOMEM_LEN);
release_region(data->sbase, SP_IOMEM_LEN);
- list_for_each_entry_safe(key, keytmp, &data->keytable, list) {
- list_del(&key->list);
- kfree(key);
- }
-
kfree(data);
pnp_set_drvdata(device, NULL);
@@ -1581,8 +908,7 @@ wbcir_init(void)
case IR_PROTOCOL_RC6:
break;
default:
- printk(KERN_ERR DRVNAME ": Invalid protocol argument\n");
- return -EINVAL;
+ printk(KERN_ERR DRVNAME ": Invalid power-on protocol\n");
}
ret = pnp_register_driver(&wbcir_driver);
@@ -1598,11 +924,9 @@ wbcir_exit(void)
pnp_unregister_driver(&wbcir_driver);
}
-MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
-MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver");
-MODULE_LICENSE("GPL");
-
module_init(wbcir_init);
module_exit(wbcir_exit);
-
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ac16e815e275..eb875af05e79 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,11 +7,6 @@ config VIDEO_V4L2
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
default VIDEO_DEV && VIDEO_V4L2_COMMON
-config VIDEO_V4L1
- tristate
- depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
- default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
-
config VIDEOBUF_GEN
tristate
@@ -96,7 +91,7 @@ config VIDEO_HELPER_CHIPS_AUTO
config VIDEO_IR_I2C
tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO
- depends on I2C && VIDEO_IR
+ depends on I2C && RC_CORE
default y
---help---
Most boards have an IR chip directly connected via GPIO. However,
@@ -112,7 +107,7 @@ config VIDEO_IR_I2C
#
menu "Encoders/decoders and other helper chips"
- depends on !VIDEO_HELPER_CHIPS_AUTO
+ visible if !VIDEO_HELPER_CHIPS_AUTO
comment "Audio decoders"
@@ -666,6 +661,16 @@ config VIDEO_HEXIUM_GEMINI
To compile this driver as a module, choose M here: the
module will be called hexium_gemini.
+config VIDEO_TIMBERDALE
+ tristate "Support for timberdale Video In/LogiWIN"
+ depends on VIDEO_V4L2 && I2C
+ select DMA_ENGINE
+ select TIMB_DMA
+ select VIDEO_ADV7180
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ Add support for the Video In peripherial of the timberdale FPGA.
+
source "drivers/media/video/cx88/Kconfig"
source "drivers/media/video/cx23885/Kconfig"
@@ -789,6 +794,12 @@ config SOC_CAMERA_PLATFORM
help
This is a generic SoC camera platform driver, useful for testing
+config SOC_CAMERA_OV2640
+ tristate "ov2640 camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov2640 camera driver
+
config SOC_CAMERA_OV6650
tristate "ov6650 sensor support"
depends on SOC_CAMERA && I2C
@@ -905,21 +916,8 @@ source "drivers/media/video/cx231xx/Kconfig"
source "drivers/media/video/usbvision/Kconfig"
-source "drivers/media/video/usbvideo/Kconfig"
-
source "drivers/media/video/et61x251/Kconfig"
-config USB_SE401
- tristate "USB SE401 Camera support"
- depends on VIDEO_V4L1
- ---help---
- Say Y here if you want to connect this type of camera to your
- computer's USB port. See <file:Documentation/video4linux/se401.txt>
- for more information and for a list of supported cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called se401.
-
source "drivers/media/video/sn9c102/Kconfig"
source "drivers/media/video/pwc/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index af79d476a4c8..81e38cb0b846 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -22,10 +22,6 @@ endif
obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
-ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
- obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
-endif
-
# All i2c modules must come first:
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
@@ -79,6 +75,7 @@ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
@@ -106,6 +103,7 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_MXB) += mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
+obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
@@ -124,8 +122,6 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
-obj-$(CONFIG_USB_DABUSB) += dabusb.o
-obj-$(CONFIG_USB_SE401) += se401.o
obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
@@ -136,10 +132,6 @@ obj-$(CONFIG_USB_GSPCA) += gspca/
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
-obj-$(CONFIG_USB_IBMCAM) += usbvideo/
-obj-$(CONFIG_USB_KONICAWC) += usbvideo/
-obj-$(CONFIG_USB_VICAM) += usbvideo/
-obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
obj-$(CONFIG_USB_S2255) += s2255drv.o
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 31e7a123d19a..f989f2820d88 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar)
static const struct v4l2_file_operations ar_fops = {
.owner = THIS_MODULE,
.read = ar_read,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops ar_ioctl_ops = {
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 0453816d4ec3..01be89fa5c78 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
be abstracted out if we ever need to support a different
demod) */
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "au8522", 0x8e >> 1, NULL);
+ "au8522", 0x8e >> 1, NULL);
if (sd == NULL)
printk(KERN_ERR "analog subdev registration failed\n");
}
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
if (dev->board.tuner_type != TUNER_ABSENT) {
/* Load the tuner module, which does the attach */
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->board.tuner_addr, NULL);
+ "tuner", dev->board.tuner_addr, NULL);
if (sd == NULL)
printk(KERN_ERR "tuner subdev registration fail\n");
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 162fd5f9d448..e41e4ad5cc40 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -122,6 +122,7 @@ static void au0828_irq_callback(struct urb *urb)
{
struct au0828_dmaqueue *dma_q = urb->context;
struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+ unsigned long flags = 0;
int rc, i;
switch (urb->status) {
@@ -139,9 +140,9 @@ static void au0828_irq_callback(struct urb *urb)
}
/* Copy data from URB */
- spin_lock(&dev->slock);
+ spin_lock_irqsave(&dev->slock, flags);
rc = dev->isoc_ctl.isoc_copy(dev, urb);
- spin_unlock(&dev->slock);
+ spin_unlock_irqrestore(&dev->slock, flags);
/* Reset urb buffers */
for (i = 0; i < urb->number_of_packets; i++) {
@@ -576,7 +577,7 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
p += 4;
au0828_isocdbg("Video frame %s\n",
(fbyte & 0x40) ? "odd" : "even");
- if (!(fbyte & 0x40)) {
+ if (fbyte & 0x40) {
/* VBI */
if (vbi_buf != NULL)
vbi_buffer_filled(dev,
@@ -597,6 +598,15 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
outp = NULL;
else
outp = videobuf_to_vmalloc(&buf->vb);
+
+ /* As long as isoc traffic is arriving, keep
+ resetting the timer */
+ if (dev->vid_timeout_running)
+ mod_timer(&dev->vid_timeout,
+ jiffies + (HZ / 10));
+ if (dev->vbi_timeout_running)
+ mod_timer(&dev->vbi_timeout,
+ jiffies + (HZ / 10));
}
if (buf != NULL) {
@@ -907,6 +917,57 @@ static int get_ressource(struct au0828_fh *fh)
}
}
+/* This function ensures that video frames continue to be delivered even if
+ the ITU-656 input isn't receiving any data (thereby preventing applications
+ such as tvtime from hanging) */
+void au0828_vid_buffer_timeout(unsigned long data)
+{
+ struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dmaqueue *dma_q = &dev->vidq;
+ struct au0828_buffer *buf;
+ unsigned char *vid_data;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&dev->slock, flags);
+
+ buf = dev->isoc_ctl.buf;
+ if (buf != NULL) {
+ vid_data = videobuf_to_vmalloc(&buf->vb);
+ memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
+ buffer_filled(dev, dma_q, buf);
+ }
+ get_next_buf(dma_q, &buf);
+
+ if (dev->vid_timeout_running == 1)
+ mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
+
+ spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+void au0828_vbi_buffer_timeout(unsigned long data)
+{
+ struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dmaqueue *dma_q = &dev->vbiq;
+ struct au0828_buffer *buf;
+ unsigned char *vbi_data;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&dev->slock, flags);
+
+ buf = dev->isoc_ctl.vbi_buf;
+ if (buf != NULL) {
+ vbi_data = videobuf_to_vmalloc(&buf->vb);
+ memset(vbi_data, 0x00, buf->vb.size);
+ vbi_buffer_filled(dev, dma_q, buf);
+ }
+ vbi_get_next_buf(dma_q, &buf);
+
+ if (dev->vbi_timeout_running == 1)
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+
static int au0828_v4l2_open(struct file *filp)
{
int ret = 0;
@@ -976,7 +1037,6 @@ static int au0828_v4l2_open(struct file *filp)
V4L2_FIELD_SEQ_TB,
sizeof(struct au0828_buffer), fh, NULL);
-
return ret;
}
@@ -987,11 +1047,19 @@ static int au0828_v4l2_close(struct file *filp)
struct au0828_dev *dev = fh->dev;
if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
+ /* Cancel timeout thread in case they didn't call streamoff */
+ dev->vid_timeout_running = 0;
+ del_timer_sync(&dev->vid_timeout);
+
videobuf_stop(&fh->vb_vidq);
res_free(fh, AU0828_RESOURCE_VIDEO);
}
if (res_check(fh, AU0828_RESOURCE_VBI)) {
+ /* Cancel timeout thread in case they didn't call streamoff */
+ dev->vbi_timeout_running = 0;
+ del_timer_sync(&dev->vbi_timeout);
+
videobuf_stop(&fh->vb_vbiq);
res_free(fh, AU0828_RESOURCE_VBI);
}
@@ -1048,6 +1116,13 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
if (!res_get(fh, AU0828_RESOURCE_VBI))
return -EBUSY;
+ if (dev->vbi_timeout_running == 0) {
+ /* Handle case where caller tries to read without
+ calling streamon first */
+ dev->vbi_timeout_running = 1;
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ }
+
return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
}
@@ -1577,10 +1652,15 @@ static int vidioc_streamon(struct file *file, void *priv,
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
}
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
rc = videobuf_streamon(&fh->vb_vidq);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ dev->vid_timeout_running = 1;
+ mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
rc = videobuf_streamon(&fh->vb_vbiq);
+ dev->vbi_timeout_running = 1;
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ }
return rc;
}
@@ -1607,6 +1687,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
fh, type, fh->resources, dev->resources);
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dev->vid_timeout_running = 0;
+ del_timer_sync(&dev->vid_timeout);
+
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
rc = au0828_stream_interrupt(dev);
if (rc != 0)
@@ -1621,6 +1704,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
videobuf_streamoff(&fh->vb_vidq);
res_free(fh, AU0828_RESOURCE_VIDEO);
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ dev->vbi_timeout_running = 0;
+ del_timer_sync(&dev->vbi_timeout);
+
videobuf_streamoff(&fh->vb_vbiq);
res_free(fh, AU0828_RESOURCE_VBI);
}
@@ -1723,15 +1809,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct au0828_fh *fh = priv;
-
- return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
-}
-#endif
-
static struct v4l2_file_operations au0828_v4l_fops = {
.owner = THIS_MODULE,
.open = au0828_v4l2_open,
@@ -1775,9 +1852,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_register = vidioc_s_register,
#endif
.vidioc_g_chip_ident = vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static const struct video_device au0828_video_template = {
@@ -1840,6 +1914,14 @@ int au0828_analog_register(struct au0828_dev *dev,
INIT_LIST_HEAD(&dev->vbiq.active);
INIT_LIST_HEAD(&dev->vbiq.queued);
+ dev->vid_timeout.function = au0828_vid_buffer_timeout;
+ dev->vid_timeout.data = (unsigned long) dev;
+ init_timer(&dev->vid_timeout);
+
+ dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
+ dev->vbi_timeout.data = (unsigned long) dev;
+ init_timer(&dev->vbi_timeout);
+
dev->width = NTSC_STD_W;
dev->height = NTSC_STD_H;
dev->field_size = dev->width * dev->height;
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 9905bc4f5f59..9cde35321824 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -53,7 +53,7 @@
/* Defination for AU0828 USB transfer */
#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
-#define AU0828_ISO_PACKETS_PER_URB 10
+#define AU0828_ISO_PACKETS_PER_URB 128
#define AU0828_MIN_BUF 4
#define AU0828_DEF_BUF 8
@@ -204,6 +204,10 @@ struct au0828_dev {
unsigned int resources; /* resources in use */
struct video_device *vdev;
struct video_device *vbi_dev;
+ struct timer_list vid_timeout;
+ int vid_timeout_running;
+ struct timer_list vbi_timeout;
+ int vbi_timeout_running;
int width;
int height;
int vbi_width;
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 1a4a89fdf767..7da5c2e1fc12 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,10 +1,10 @@
config VIDEO_BT848
tristate "BT848 Video For Linux"
- depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
+ depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 87d8b006ef77..49efcf660ba6 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "saa6588", 0, addrs);
+ &btv->c.i2c_adap, "saa6588", 0, addrs);
btv->has_saa6588 = (sd != NULL);
}
@@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400", 0, addrs);
+ &btv->c.i2c_adap, "msp3400", 0, addrs);
if (btv->sd_msp34xx)
return;
goto no_audio;
@@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+ &btv->c.i2c_adap, "tda7432", 0, addrs))
return;
goto no_audio;
}
@@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
case 3: {
/* The user specified that we should probe for tvaudio */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+ &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
if (btv->sd_tvaudio)
return;
goto no_audio;
@@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv)
found is really something else (e.g. a tea6300). */
if (!bttv_tvcards[btv->c.type].no_msp34xx) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400",
+ &btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
} else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400",
+ &btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
}
@@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+ &btv->c.i2c_adap, "tda7432", 0, addrs))
return;
}
/* Now see if we can find one of the tvaudio devices. */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+ &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
if (btv->sd_tvaudio)
return;
@@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv)
/* Load tuner module before issuing tuner config call! */
if (bttv_tvcards[btv->c.type].has_radio)
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index a529619e51f6..849cd170b821 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -55,7 +55,7 @@
#include <asm/io.h>
#include <asm/byteorder.h>
-#include <media/rds.h>
+#include <media/saa6588.h>
unsigned int bttv_num; /* number of Bt848s in use */
@@ -854,7 +854,6 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM;
/* is it free? */
- mutex_lock(&btv->lock);
if (btv->resources & xbits) {
/* no, someone else uses it */
goto fail;
@@ -884,11 +883,9 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
/* it's free, grab it */
fh->resources |= bit;
btv->resources |= bit;
- mutex_unlock(&btv->lock);
return 1;
fail:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -940,7 +937,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
/* trying to free ressources not allocated by us ... */
printk("bttv: BUG! (btres)\n");
}
- mutex_lock(&btv->lock);
fh->resources &= ~bits;
btv->resources &= ~bits;
@@ -951,8 +947,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
if (0 == (bits & VBI_RESOURCES))
disclaim_vbi_lines(btv);
-
- mutex_unlock(&btv->lock);
}
/* ----------------------------------------------------------------------- */
@@ -1713,28 +1707,20 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
/* Make sure tvnorm and vbi_end remain consistent
until we're done. */
- mutex_lock(&btv->lock);
norm = btv->tvnorm;
/* In this mode capturing always starts at defrect.top
(default VDELAY), ignoring cropping parameters. */
if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) {
- mutex_unlock(&btv->lock);
return -EINVAL;
}
- mutex_unlock(&btv->lock);
-
c.rect = bttv_tvnorms[norm].cropcap.defrect;
} else {
- mutex_lock(&btv->lock);
-
norm = btv->tvnorm;
c = btv->crop[!!fh->do_crop];
- mutex_unlock(&btv->lock);
-
if (width < c.min_scaled_width ||
width > c.max_scaled_width ||
height < c.min_scaled_height)
@@ -1858,7 +1844,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
unsigned int i;
int err;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (err)
goto err;
@@ -1874,7 +1859,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
set_tvnorm(btv, i);
err:
- mutex_unlock(&btv->lock);
return err;
}
@@ -1898,7 +1882,6 @@ static int bttv_enum_input(struct file *file, void *priv,
struct bttv *btv = fh->btv;
int rc = 0;
- mutex_lock(&btv->lock);
if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
rc = -EINVAL;
goto err;
@@ -1928,7 +1911,6 @@ static int bttv_enum_input(struct file *file, void *priv,
i->std = BTTV_NORMS;
err:
- mutex_unlock(&btv->lock);
return rc;
}
@@ -1938,9 +1920,7 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
*i = btv->input;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -1952,7 +1932,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
int err;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (unlikely(err))
goto err;
@@ -1965,7 +1944,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
set_input(btv, i, btv->tvnorm);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -1979,7 +1957,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
if (unlikely(0 != t->index))
return -EINVAL;
- mutex_lock(&btv->lock);
if (unlikely(btv->tuner_type == TUNER_ABSENT)) {
err = -EINVAL;
goto err;
@@ -1995,7 +1972,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
btv->audio_mode_gpio(btv, t, 1);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2006,10 +1982,8 @@ static int bttv_g_frequency(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = btv->freq;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2024,7 +1998,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
if (unlikely(f->tuner != 0))
return -EINVAL;
- mutex_lock(&btv->lock);
err = v4l2_prio_check(&btv->prio, fh->prio);
if (unlikely(err))
goto err;
@@ -2039,7 +2012,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv, btv->freq);
err:
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2172,7 +2144,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
/* Make sure tvnorm, vbi_end and the current cropping parameters
remain consistent until we're done. */
- mutex_lock(&btv->lock);
b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
@@ -2250,7 +2221,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
rc = 0; /* success */
fail:
- mutex_unlock(&btv->lock);
return rc;
}
@@ -2282,9 +2252,7 @@ verify_window_lock (struct bttv_fh * fh,
if (V4L2_FIELD_ANY == field) {
__s32 height2;
- mutex_lock(&fh->btv->lock);
height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1;
- mutex_unlock(&fh->btv->lock);
field = (win->w.height > height2)
? V4L2_FIELD_INTERLACED
: V4L2_FIELD_TOP;
@@ -2360,7 +2328,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
}
}
- mutex_lock(&fh->cap.vb_lock);
/* clip against screen */
if (NULL != btv->fbuf.base)
n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
@@ -2391,13 +2358,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
fh->ov.field = win->field;
fh->ov.setup_ok = 1;
- /*
- * FIXME: btv is protected by btv->lock mutex, while btv->init
- * is protected by fh->cap.vb_lock. This seems to open the
- * possibility for some race situations. Maybe the better would
- * be to unify those locks or to use another way to store the
- * init values that will be consumed by videobuf callbacks
- */
btv->init.ov.w.width = win->w.width;
btv->init.ov.w.height = win->w.height;
btv->init.ov.field = win->field;
@@ -2412,7 +2372,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
retval = bttv_switch_overlay(btv,fh,new);
}
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2526,9 +2485,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
if (V4L2_FIELD_ANY == field) {
__s32 height2;
- mutex_lock(&btv->lock);
height2 = btv->crop[!!fh->do_crop].rect.height >> 1;
- mutex_unlock(&btv->lock);
field = (f->fmt.pix.height > height2)
? V4L2_FIELD_INTERLACED
: V4L2_FIELD_BOTTOM;
@@ -2614,7 +2571,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
/* update our state informations */
- mutex_lock(&fh->cap.vb_lock);
fh->fmt = fmt;
fh->cap.field = f->fmt.pix.field;
fh->cap.last = V4L2_FIELD_NONE;
@@ -2623,7 +2579,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
btv->init.fmt = fmt;
btv->init.width = f->fmt.pix.width;
btv->init.height = f->fmt.pix.height;
- mutex_unlock(&fh->cap.vb_lock);
return 0;
}
@@ -2642,34 +2597,6 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,
return setup_window_lock(fh, btv, &f->fmt.win, 1);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- int retval;
- unsigned int i;
- struct bttv_fh *fh = priv;
-
- mutex_lock(&fh->cap.vb_lock);
- retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
- V4L2_MEMORY_MMAP);
- if (retval < 0) {
- mutex_unlock(&fh->cap.vb_lock);
- return retval;
- }
-
- gbuffers = retval;
- memset(mbuf, 0, sizeof(*mbuf));
- mbuf->frames = gbuffers;
- mbuf->size = gbuffers * gbufsize;
-
- for (i = 0; i < gbuffers; i++)
- mbuf->offsets[i] = i * gbufsize;
-
- mutex_unlock(&fh->cap.vb_lock);
- return 0;
-}
-#endif
-
static int bttv_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@@ -2775,10 +2702,8 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
int retval = 0;
if (on) {
- mutex_lock(&fh->cap.vb_lock);
/* verify args */
if (unlikely(!btv->fbuf.base)) {
- mutex_unlock(&fh->cap.vb_lock);
return -EINVAL;
}
if (unlikely(!fh->ov.setup_ok)) {
@@ -2787,13 +2712,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
}
if (retval)
return retval;
- mutex_unlock(&fh->cap.vb_lock);
}
if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY))
return -EBUSY;
- mutex_lock(&fh->cap.vb_lock);
if (on) {
fh->ov.tvnorm = btv->tvnorm;
new = videobuf_sg_alloc(sizeof(*new));
@@ -2805,7 +2728,6 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
/* switch over */
retval = bttv_switch_overlay(btv, fh, new);
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2844,7 +2766,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
}
/* ok, accept it */
- mutex_lock(&fh->cap.vb_lock);
btv->fbuf.base = fb->base;
btv->fbuf.fmt.width = fb->fmt.width;
btv->fbuf.fmt.height = fb->fmt.height;
@@ -2876,7 +2797,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
retval = bttv_switch_overlay(btv, fh, new);
}
}
- mutex_unlock(&fh->cap.vb_lock);
return retval;
}
@@ -2955,7 +2875,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
c->id >= V4L2_CID_PRIVATE_LASTP1))
return -EINVAL;
- mutex_lock(&btv->lock);
if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
*c = no_ctl;
else {
@@ -2963,7 +2882,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
*c = (NULL != ctrl) ? *ctrl : no_ctl;
}
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2974,10 +2892,8 @@ static int bttv_g_parm(struct file *file, void *f,
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
&parm->parm.capture.timeperframe);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -2993,7 +2909,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- mutex_lock(&btv->lock);
t->rxsubchans = V4L2_TUNER_SUB_MONO;
bttv_call_all(btv, tuner, g_tuner, t);
strcpy(t->name, "Television");
@@ -3005,7 +2920,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3014,9 +2928,7 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p)
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
*p = v4l2_prio_max(&btv->prio);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3028,9 +2940,7 @@ static int bttv_s_priority(struct file *file, void *f,
struct bttv *btv = fh->btv;
int rc;
- mutex_lock(&btv->lock);
rc = v4l2_prio_change(&btv->prio, &fh->prio, prio);
- mutex_unlock(&btv->lock);
return rc;
}
@@ -3045,9 +2955,7 @@ static int bttv_cropcap(struct file *file, void *priv,
cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
- mutex_lock(&btv->lock);
*cap = bttv_tvnorms[btv->tvnorm].cropcap;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3065,9 +2973,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
inconsistent with fh->width or fh->height and apps
do not expect a change here. */
- mutex_lock(&btv->lock);
crop->c = btv->crop[!!fh->do_crop].rect;
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3091,17 +2997,14 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
/* Make sure tvnorm, vbi_end and the current cropping
parameters remain consistent until we're done. Note
read() may change vbi_end in check_alloc_btres_lock(). */
- mutex_lock(&btv->lock);
retval = v4l2_prio_check(&btv->prio, fh->prio);
if (0 != retval) {
- mutex_unlock(&btv->lock);
return retval;
}
retval = -EBUSY;
if (locked_btres(fh->btv, VIDEO_RESOURCES)) {
- mutex_unlock(&btv->lock);
return retval;
}
@@ -3113,7 +3016,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
b_top = max(b->top, btv->vbi_end);
if (b_top + 32 >= b_bottom) {
- mutex_unlock(&btv->lock);
return retval;
}
@@ -3136,12 +3038,8 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
btv->crop[1] = c;
- mutex_unlock(&btv->lock);
-
fh->do_crop = 1;
- mutex_lock(&fh->cap.vb_lock);
-
if (fh->width < c.min_scaled_width) {
fh->width = c.min_scaled_width;
btv->init.width = c.min_scaled_width;
@@ -3158,8 +3056,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
btv->init.height = c.max_scaled_height;
}
- mutex_unlock(&fh->cap.vb_lock);
-
return 0;
}
@@ -3227,7 +3123,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
return videobuf_poll_stream(file, &fh->vbi, wait);
}
- mutex_lock(&fh->cap.vb_lock);
if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
/* streaming capture */
if (list_empty(&fh->cap.stream))
@@ -3262,7 +3157,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
else
rc = 0;
err:
- mutex_unlock(&fh->cap.vb_lock);
return rc;
}
@@ -3293,23 +3187,11 @@ static int bttv_open(struct file *file)
return -ENOMEM;
file->private_data = fh;
- /*
- * btv is protected by btv->lock mutex, while btv->init and other
- * streaming vars are protected by fh->cap.vb_lock. We need to take
- * care of both locks to avoid troubles. However, vb_lock is used also
- * inside videobuf, without calling buf->lock. So, it is a very bad
- * idea to hold both locks at the same time.
- * Let's first copy btv->init at fh, holding cap.vb_lock, and then work
- * with the rest of init, holding btv->lock.
- */
- mutex_lock(&fh->cap.vb_lock);
*fh = btv->init;
- mutex_unlock(&fh->cap.vb_lock);
fh->type = type;
fh->ov.setup_ok = 0;
- mutex_lock(&btv->lock);
v4l2_prio_open(&btv->prio, &fh->prio);
videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
@@ -3317,13 +3199,13 @@ static int bttv_open(struct file *file)
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct bttv_buffer),
- fh, NULL);
+ fh, &btv->lock);
videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
&btv->c.pci->dev, &btv->s_lock,
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB,
sizeof(struct bttv_buffer),
- fh, NULL);
+ fh, &btv->lock);
set_tvnorm(btv,btv->tvnorm);
set_input(btv, btv->input, btv->tvnorm);
@@ -3346,7 +3228,6 @@ static int bttv_open(struct file *file)
bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
bttv_field_count(btv);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3355,7 +3236,6 @@ static int bttv_release(struct file *file)
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
- mutex_lock(&btv->lock);
/* turn off overlay */
if (check_btres(fh, RESOURCE_OVERLAY))
bttv_switch_overlay(btv,fh,NULL);
@@ -3381,14 +3261,8 @@ static int bttv_release(struct file *file)
/* free stuff */
- /*
- * videobuf uses cap.vb_lock - we should avoid holding btv->lock,
- * otherwise we may have dead lock conditions
- */
- mutex_unlock(&btv->lock);
videobuf_mmap_free(&fh->cap);
videobuf_mmap_free(&fh->vbi);
- mutex_lock(&btv->lock);
v4l2_prio_close(&btv->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
@@ -3398,7 +3272,6 @@ static int bttv_release(struct file *file)
if (!btv->users)
audio_mute(btv, 1);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3456,9 +3329,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
.vidioc_streamoff = bttv_streamoff,
.vidioc_g_tuner = bttv_g_tuner,
.vidioc_s_tuner = bttv_s_tuner,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
.vidioc_g_crop = bttv_g_crop,
.vidioc_s_crop = bttv_s_crop,
.vidioc_g_fbuf = bttv_g_fbuf,
@@ -3502,11 +3372,8 @@ static int radio_open(struct file *file)
if (unlikely(!fh))
return -ENOMEM;
file->private_data = fh;
- mutex_lock(&fh->cap.vb_lock);
*fh = btv->init;
- mutex_unlock(&fh->cap.vb_lock);
- mutex_lock(&btv->lock);
v4l2_prio_open(&btv->prio, &fh->prio);
btv->radio_user++;
@@ -3514,7 +3381,6 @@ static int radio_open(struct file *file)
bttv_call_all(btv, tuner, s_radio);
audio_input(btv,TVAUDIO_INPUT_RADIO);
- mutex_unlock(&btv->lock);
return 0;
}
@@ -3522,17 +3388,15 @@ static int radio_release(struct file *file)
{
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
- struct rds_command cmd;
+ struct saa6588_command cmd;
- mutex_lock(&btv->lock);
v4l2_prio_close(&btv->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
btv->radio_user--;
- bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
- mutex_unlock(&btv->lock);
+ bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
return 0;
}
@@ -3561,7 +3425,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
- mutex_lock(&btv->lock);
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
@@ -3570,8 +3433,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
- mutex_unlock(&btv->lock);
-
return 0;
}
@@ -3662,13 +3523,13 @@ static ssize_t radio_read(struct file *file, char __user *data,
{
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
- struct rds_command cmd;
+ struct saa6588_command cmd;
cmd.block_count = count/3;
cmd.buffer = data;
cmd.instance = file;
cmd.result = -ENODEV;
- bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
+ bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd);
return cmd.result;
}
@@ -3677,11 +3538,11 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
{
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
- struct rds_command cmd;
+ struct saa6588_command cmd;
cmd.instance = file;
cmd.event_list = wait;
cmd.result = -ENODEV;
- bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
+ bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
return cmd.result;
}
@@ -3692,7 +3553,7 @@ static const struct v4l2_file_operations radio_fops =
.open = radio_open,
.read = radio_read,
.release = radio_release,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = radio_poll,
};
@@ -4152,9 +4013,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btv=(struct bttv *)dev_id;
- if (btv->custom_irq)
- handled = btv->custom_irq(btv);
-
count=0;
while (1) {
/* get/clear interrupt status bits */
@@ -4190,7 +4048,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btv->field_count++;
if ((astat & BT848_INT_GPINT) && btv->remote) {
- wake_up(&btv->gpioq);
bttv_input_irq(btv);
}
@@ -4395,7 +4252,6 @@ static int __devinit bttv_probe(struct pci_dev *dev,
mutex_init(&btv->lock);
spin_lock_init(&btv->s_lock);
spin_lock_init(&btv->gpio_lock);
- init_waitqueue_head(&btv->gpioq);
init_waitqueue_head(&btv->i2c_queue);
INIT_LIST_HEAD(&btv->c.subs);
INIT_LIST_HEAD(&btv->capture);
@@ -4583,7 +4439,6 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
/* tell gpio modules we are leaving ... */
btv->shutdown=1;
- wake_up(&btv->gpioq);
bttv_input_fini(btv);
bttv_sub_del_devices(&btv->c);
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 6bf05a7dc5f9..97793b960600 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -31,15 +31,9 @@
static int ir_debug;
module_param(ir_debug, int, 0644);
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644);
-static int ir_rc5_key_timeout = 200;
-module_param(ir_rc5_key_timeout, int, 0644);
#undef dprintk
#define dprintk(arg...) do { \
@@ -55,7 +49,7 @@ module_param(ir_rc5_key_timeout, int, 0644);
static void ir_handle_key(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
u32 gpio,data;
/* read gpio value */
@@ -74,23 +68,22 @@ static void ir_handle_key(struct bttv *btv)
(gpio & ir->mask_keydown) ? " down" : "",
(gpio & ir->mask_keyup) ? " up" : "");
- if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
- (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
+ if ((ir->mask_keydown && (gpio & ir->mask_keydown)) ||
+ (ir->mask_keyup && !(gpio & ir->mask_keyup))) {
+ rc_keydown_notimeout(ir->dev, data, 0);
} else {
/* HACK: Probably, ir->mask_keydown is missing
for this board */
if (btv->c.type == BTTV_BOARD_WINFAST2000)
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
- ir_input_nokey(ir->dev,&ir->ir);
+ rc_keyup(ir->dev);
}
-
}
static void ir_enltv_handle_key(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
u32 gpio, data, keyup;
/* read gpio value */
@@ -107,9 +100,9 @@ static void ir_enltv_handle_key(struct bttv *btv)
gpio, data,
(gpio & ir->mask_keyup) ? " up" : "up/down");
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
if (keyup)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
} else {
if ((ir->last_gpio & 1 << 31) == keyup)
return;
@@ -119,26 +112,30 @@ static void ir_enltv_handle_key(struct bttv *btv)
(gpio & ir->mask_keyup) ? " up" : "down");
if (keyup)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
else
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
}
ir->last_gpio = data | keyup;
}
+static int bttv_rc5_irq(struct bttv *btv);
+
void bttv_input_irq(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
- if (!ir->polling)
+ if (ir->rc5_gpio)
+ bttv_rc5_irq(btv);
+ else if (!ir->polling)
ir_handle_key(btv);
}
static void bttv_input_timer(unsigned long data)
{
struct bttv *btv = (struct bttv*)data;
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
ir_enltv_handle_key(btv);
@@ -147,11 +144,109 @@ static void bttv_input_timer(unsigned long data)
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
}
-/* ---------------------------------------------------------------*/
+/*
+ * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying
+ * on the rc-core way. As we need to be sure that both IRQ transitions are
+ * properly triggered, Better to touch it only with this hardware for
+ * testing.
+ */
+
+#define RC5_START(x) (((x) >> 12) & 3)
+#define RC5_TOGGLE(x) (((x) >> 11) & 1)
+#define RC5_ADDR(x) (((x) >> 6) & 31)
+#define RC5_INSTR(x) ((x) & 63)
+
+/* decode raw bit pattern to RC5 code */
+static u32 bttv_rc5_decode(unsigned int code)
+{
+ unsigned int org_code = code;
+ unsigned int pair;
+ unsigned int rc5 = 0;
+ int i;
+
+ for (i = 0; i < 14; ++i) {
+ pair = code & 0x3;
+ code >>= 2;
+
+ rc5 <<= 1;
+ switch (pair) {
+ case 0:
+ case 2:
+ break;
+ case 1:
+ rc5 |= 1;
+ break;
+ case 3:
+ dprintk(KERN_INFO DEVNAME ":rc5_decode(%x) bad code\n",
+ org_code);
+ return 0;
+ }
+ }
+ dprintk(KERN_INFO DEVNAME ":"
+ "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+ "instr=%x\n", rc5, org_code, RC5_START(rc5),
+ RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+ return rc5;
+}
+
+static void bttv_rc5_timer_end(unsigned long data)
+{
+ struct bttv_ir *ir = (struct bttv_ir *)data;
+ struct timeval tv;
+ unsigned long current_jiffies;
+ u32 gap;
+ u32 rc5 = 0;
+
+ /* get time */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* signal we're ready to start a new code */
+ ir->active = false;
+
+ /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
+ if (gap < 28000) {
+ dprintk(KERN_INFO DEVNAME ": spurious timer_end\n");
+ return;
+ }
+
+ if (ir->last_bit < 20) {
+ /* ignore spurious codes (caused by light/other remotes) */
+ dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code);
+ } else {
+ ir->code = (ir->code << ir->shift_by) | 1;
+ rc5 = bttv_rc5_decode(ir->code);
+
+ /* two start bits? */
+ if (RC5_START(rc5) != ir->start) {
+ printk(KERN_INFO DEVNAME ":"
+ " rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+ /* right address? */
+ } else if (RC5_ADDR(rc5) == ir->addr) {
+ u32 toggle = RC5_TOGGLE(rc5);
+ u32 instr = RC5_INSTR(rc5);
+
+ /* Good code */
+ rc_keydown(ir->dev, instr, toggle);
+ dprintk(KERN_INFO DEVNAME ":"
+ " instruction %x, toggle %x\n",
+ instr, toggle);
+ }
+ }
+}
static int bttv_rc5_irq(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
struct timeval tv;
u32 gpio;
u32 gap;
@@ -160,10 +255,6 @@ static int bttv_rc5_irq(struct bttv *btv)
/* read gpio port */
gpio = bttv_gpio_read(&btv->c);
- /* remote IRQ? */
- if (!(gpio & 0x20))
- return 0;
-
/* get time of bit */
current_jiffies = jiffies;
do_gettimeofday(&tv);
@@ -176,6 +267,13 @@ static int bttv_rc5_irq(struct bttv *btv)
tv.tv_usec - ir->base_time.tv_usec;
}
+ dprintk(KERN_INFO DEVNAME ": RC5 IRQ: gap %d us for %s\n",
+ gap, (gpio & 0x20) ? "mark" : "space");
+
+ /* remote IRQ? */
+ if (!(gpio & 0x20))
+ return 0;
+
/* active code => add bit */
if (ir->active) {
/* only if in the code (otherwise spurious IRQ or timer
@@ -187,13 +285,12 @@ static int bttv_rc5_irq(struct bttv *btv)
}
/* starting new code */
} else {
- ir->active = 1;
+ ir->active = true;
ir->code = 0;
ir->base_time = tv;
ir->last_bit = 0;
- mod_timer(&ir->timer_end,
- current_jiffies + msecs_to_jiffies(30));
+ mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30));
}
/* toggle GPIO pin 4 to reset the irq */
@@ -204,7 +301,7 @@ static int bttv_rc5_irq(struct bttv *btv)
/* ---------------------------------------------------------------------- */
-static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
+static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
{
if (ir->polling) {
setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
@@ -212,17 +309,10 @@ static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
add_timer(&ir->timer);
} else if (ir->rc5_gpio) {
/* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_rc5_timer_end;
- ir->timer_end.data = (unsigned long)ir;
-
- init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = ir_rc5_timer_keyup;
- ir->timer_keyup.data = (unsigned long)ir;
+ setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
ir->shift_by = 1;
ir->start = 3;
ir->addr = 0x0;
- ir->rc5_key_timeout = ir_rc5_key_timeout;
ir->rc5_remote_gap = ir_rc5_remote_gap;
}
}
@@ -237,7 +327,7 @@ static void bttv_ir_stop(struct bttv *btv)
if (btv->remote->rc5_gpio) {
u32 gpio;
- del_timer_sync(&btv->remote->timer_end);
+ del_timer_sync(&btv->remote->timer);
flush_scheduled_work();
gpio = bttv_gpio_read(&btv->c);
@@ -264,6 +354,18 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 0;
dprintk(KERN_INFO DEVNAME ": key %02x\n", b);
+ /*
+ * NOTE:
+ * lirc_i2c maps the pv951 code as:
+ * addr = 0x61D6
+ * cmd = bit_reverse (b)
+ * So, it seems that this device uses NEC extended
+ * I decided to not fix the table, due to two reasons:
+ * 1) Without the actual device, this is only a guess;
+ * 2) As the addr is not reported via I2C, nor can be changed,
+ * the device is bound to the vendor-provided RC.
+ */
+
*ir_key = b;
*ir_raw = b;
return 1;
@@ -290,16 +392,15 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv)
btv->init_data.name = "PV951";
btv->init_data.get_key = get_key_pv951;
btv->init_data.ir_codes = RC_MAP_PV951;
- btv->init_data.type = IR_TYPE_OTHER;
info.addr = 0x4b;
break;
default:
/*
* The external IR receiver is at i2c address 0x34 (0x35 for
- * reads). Future Hauppauge cards will have an internal
- * receiver at 0x30 (0x31 for reads). In theory, both can be
- * fitted, and Hauppauge suggest an external overrides an
- * internal.
+ * reads). Future Hauppauge cards will have an internal
+ * receiver at 0x30 (0x31 for reads). In theory, both can be
+ * fitted, and Hauppauge suggest an external overrides an
+ * internal.
* That's why we probe 0x1a (~0x34) first. CB
*/
@@ -324,18 +425,17 @@ int __devexit fini_bttv_i2c(struct bttv *btv)
int bttv_input_init(struct bttv *btv)
{
- struct card_ir *ir;
+ struct bttv_ir *ir;
char *ir_codes = NULL;
- struct input_dev *input_dev;
- u64 ir_type = IR_TYPE_OTHER;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (!btv->has_remote)
return -ENODEV;
ir = kzalloc(sizeof(*ir),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* detect & configure */
@@ -398,8 +498,7 @@ int bttv_input_init(struct bttv *btv)
break;
case BTTV_BOARD_NEBULA_DIGITV:
ir_codes = RC_MAP_NEBULA;
- btv->custom_irq = bttv_rc5_irq;
- ir->rc5_gpio = 1;
+ ir->rc5_gpio = true;
break;
case BTTV_BOARD_MACHTV_MAGICTV:
ir_codes = RC_MAP_APAC_VIEWCOMP;
@@ -441,48 +540,43 @@ int bttv_input_init(struct bttv *btv)
}
/* init input device */
- ir->dev = input_dev;
+ ir->dev = rc;
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
btv->c.type);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(btv->c.pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (btv->c.pci->subsystem_vendor) {
- input_dev->id.vendor = btv->c.pci->subsystem_vendor;
- input_dev->id.product = btv->c.pci->subsystem_device;
+ rc->input_id.vendor = btv->c.pci->subsystem_vendor;
+ rc->input_id.product = btv->c.pci->subsystem_device;
} else {
- input_dev->id.vendor = btv->c.pci->vendor;
- input_dev->id.product = btv->c.pci->device;
+ rc->input_id.vendor = btv->c.pci->vendor;
+ rc->input_id.product = btv->c.pci->device;
}
- input_dev->dev.parent = &btv->c.pci->dev;
+ rc->dev.parent = &btv->c.pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
btv->remote = ir;
bttv_ir_start(btv, ir);
/* all done */
- err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_stop:
bttv_ir_stop(btv);
btv->remote = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -493,7 +587,7 @@ void bttv_input_fini(struct bttv *btv)
return;
bttv_ir_stop(btv);
- ir_input_unregister(btv->remote->dev);
+ rc_unregister_device(btv->remote->dev);
kfree(btv->remote);
btv->remote = NULL;
}
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 6fd2a8ebda1e..fd62bf15d779 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -17,7 +17,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/ir-common.h>
#include <media/i2c-addr.h>
#include <media/tuner.h>
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index d1e26a448ed2..9b776faf0741 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -41,7 +41,7 @@
#include <linux/device.h>
#include <media/videobuf-dma-sg.h>
#include <media/tveeprom.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include "bt848.h"
@@ -120,6 +120,33 @@ struct bttv_format {
int hshift,vshift; /* for planar modes */
};
+struct bttv_ir {
+ struct rc_dev *dev;
+ struct timer_list timer;
+
+ char name[32];
+ char phys[32];
+
+ /* Usual gpio signalling */
+ u32 mask_keycode;
+ u32 mask_keydown;
+ u32 mask_keyup;
+ u32 polling;
+ u32 last_gpio;
+ int shift_by;
+ int start; // What should RC5_START() be
+ int addr; // What RC5_ADDR() should be.
+ int rc5_remote_gap;
+
+ /* RC5 gpio */
+ bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */
+ u32 last_bit; /* last raw bit seen */
+ u32 code; /* raw code under construction */
+ struct timeval base_time; /* time of last seen code */
+ bool active; /* building raw code */
+};
+
+
/* ---------------------------------------------------------- */
struct bttv_geometry {
@@ -305,7 +332,6 @@ struct bttv_pll_info {
/* for gpio-connected remote control */
struct bttv_input {
struct input_dev *dev;
- struct ir_input_state ir;
char name[32];
char phys[32];
u32 mask_keycode;
@@ -338,12 +364,10 @@ struct bttv {
struct bttv_pll_info pll;
int triton1;
int gpioirq;
- int (*custom_irq)(struct bttv *btv);
int use_i2c_hw;
/* old gpio interface */
- wait_queue_head_t gpioq;
int shutdown;
void (*volume_gpio)(struct bttv *btv, __u16 volume);
@@ -368,7 +392,7 @@ struct bttv {
/* infrared remote */
int has_remote;
- struct card_ir *remote;
+ struct bttv_ir *remote;
/* I2C remote data */
struct IR_i2c_init_data init_data;
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 935e0c9a9674..c1193506131c 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = qcam_read,
};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 6e4b19698c13..24fc00965a12 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = qcam_read,
};
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7bc36670071a..49f1b8f1418e 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -859,8 +859,6 @@ static int cafe_cam_configure(struct cafe_camera *cam)
struct v4l2_mbus_framefmt mbus_fmt;
int ret;
- if (cam->state != S_IDLE)
- return -EINVAL;
v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
ret = sensor_call(cam, core, init, 0);
if (ret == 0)
@@ -1775,7 +1773,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = {
.read = cafe_v4l_read,
.poll = cafe_v4l_poll,
.mmap = cafe_v4l_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
@@ -2066,8 +2064,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam->sensor_addr = 0x42;
cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
- "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr,
- NULL);
+ "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
if (cam->sensor == NULL) {
ret = -ENODEV;
goto out_smbus;
@@ -2187,9 +2184,7 @@ static int cafe_pci_resume(struct pci_dev *pdev)
struct cafe_camera *cam = to_cam(v4l2_dev);
int ret = 0;
- ret = pci_restore_state(pdev);
- if (ret)
- return ret;
+ pci_restore_state(pdev);
ret = pci_enable_device(pdev);
if (ret) {
@@ -2197,12 +2192,13 @@ static int cafe_pci_resume(struct pci_dev *pdev)
return ret;
}
cafe_ctlr_init(cam);
- cafe_ctlr_power_down(cam);
mutex_lock(&cam->s_mutex);
if (cam->users > 0) {
cafe_ctlr_power_up(cam);
__cafe_cam_reset(cam);
+ } else {
+ cafe_ctlr_power_down(cam);
}
mutex_unlock(&cam->s_mutex);
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 46b433bbf2c1..7edf80b0d01a 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -419,28 +419,6 @@ static int sync(struct camera_data *cam, int frame_nr)
/******************************************************************************
*
- * ioctl_get_mbuf
- *
- *****************************************************************************/
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int ioctl_get_mbuf(void *arg, struct camera_data *cam)
-{
- struct video_mbuf *vm;
- int i;
- vm = arg;
-
- memset(vm, 0, sizeof(*vm));
- vm->size = cam->frame_size*cam->num_frames;
- vm->frames = cam->num_frames;
- for (i = 0; i < cam->num_frames; i++)
- vm->offsets[i] = cam->frame_size * i;
-
- return 0;
-}
-#endif
-
-/******************************************************************************
- *
* ioctl_set_gpio
*
*****************************************************************************/
@@ -1380,17 +1358,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
break;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGMBUF:
- {
- struct cpia2_fh *fh = file->private_data;
- if(fh->prio != V4L2_PRIORITY_RECORD) {
- mutex_unlock(&cam->busy_lock);
- return -EBUSY;
- }
- break;
- }
-#endif
default:
break;
}
@@ -1400,11 +1367,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case CPIA2_IOC_SET_GPIO:
retval = ioctl_set_gpio(arg, cam);
break;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGMBUF: /* mmap interface */
- retval = ioctl_get_mbuf(arg, cam);
- break;
-#endif
case VIDIOC_QUERYCAP:
retval = ioctl_querycap(arg,cam);
break;
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 76c054d1eef9..d9d2f6ad6ffb 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -1,9 +1,8 @@
config VIDEO_CX18
tristate "Conexant cx23418 MPEG encoder support"
depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
- depends on INPUT # due to VIDEO_IR
select I2C_ALGOBIT
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
index 8f55692db36d..82d195be9197 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
- return snd_pcm_lib_ioctl(substream, cmd, arg);
+ struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+ int ret;
+
+ snd_cx18_lock(cxsc);
+ ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+ snd_cx18_unlock(cxsc);
+ return ret;
}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index fe1090940b01..87177733cf92 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -39,7 +39,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
.tv = { 0x61, 0x60, I2C_CLIENT_END },
};
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
+/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
This keeps the PCI ID database up to date. Note that the entries
must be added under vendor 0x4444 (Conexant) as subsystem IDs.
New vendor IDs should still be added to the vendor ID list. */
@@ -251,6 +251,66 @@ static const struct cx18_card cx18_card_mpc718 = {
/* ------------------------------------------------------------------------- */
+/* GoTView PCI */
+
+static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = {
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 },
+ { 0, 0, 0 }
+};
+
+static const struct cx18_card cx18_card_gotview_dvd3 = {
+ .type = CX18_CARD_GOTVIEW_PCI_DVD3,
+ .name = "GoTView PCI DVD3 Hybrid",
+ .comment = "Experimenters needed for device to work well.\n"
+ "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
+ .v4l2_capabilities = CX18_CAP_ENCODER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
+ .video_inputs = {
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
+ { CX18_CARD_INPUT_SVIDEO1, 1,
+ CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
+ { CX18_CARD_INPUT_SVIDEO2, 2,
+ CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
+ },
+ .audio_inputs = {
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
+ },
+ .tuners = {
+ /* XC3028 tuner */
+ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+ },
+ /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
+ .ddr = {
+ /* Hynix HY5DU283222B DDR RAM */
+ .chip_config = 0x303,
+ .refresh = 0x3bd,
+ .timing1 = 0x36320966,
+ .timing2 = 0x1f,
+ .tune_lane = 0,
+ .initial_emrs = 2,
+ },
+ .gpio_init.initial_value = 0x1,
+ .gpio_init.direction = 0x3,
+
+ .gpio_audio_input = { .mask = 0x3,
+ .tuner = 0x1,
+ .linein = 0x2,
+ .radio = 0x1 },
+ .xceive_pin = 0,
+ .pci_list = cx18_pci_gotview_dvd3,
+ .i2c = &cx18_i2c_std,
+};
+
+/* ------------------------------------------------------------------------- */
+
/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
@@ -463,6 +523,7 @@ static const struct cx18_card *cx18_card_list[] = {
&cx18_card_toshiba_qosmio_dvbt,
&cx18_card_leadtek_pvr2100,
&cx18_card_leadtek_dvr3100h,
+ &cx18_card_gotview_dvd3
};
const struct cx18_card *cx18_get_card(u16 index)
@@ -485,7 +546,6 @@ int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
"Component 1"
};
- memset(input, 0, sizeof(*input));
if (index >= cx->nof_inputs)
return -EINVAL;
input->index = index;
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 67043c7b452b..97d7b7e100a3 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -108,7 +108,7 @@ static int cx18_try_ctrl(struct file *file, void *fh,
struct v4l2_ext_control *vctrl)
{
struct v4l2_queryctrl qctrl;
- const char **menu_items = NULL;
+ const char * const *menu_items = NULL;
int err;
qctrl.id = vctrl->id;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index df60f27337cf..676e5bef89eb 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -156,6 +156,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
"\t\t\t 7 = Leadtek WinFast PVR2100\n"
"\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
+ "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -333,6 +334,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
tveeprom_hauppauge_analog(&c, tv, eedata);
break;
case CX18_CARD_YUAN_MPC718:
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
tv->model = 0x718;
cx18_eeprom_dump(cx, eedata, sizeof(eedata));
CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
@@ -923,8 +925,13 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
CX18_MEM_SIZE);
if (!cx->enc_mem) {
- CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
- CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
+ CX18_ERR("ioremap failed. Can't get a window into CX23418 "
+ "memory and register space\n");
+ CX18_ERR("Each capture card with a CX23418 needs 64 MB of "
+ "vmalloc address space for the window\n");
+ CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
+ CX18_ERR("Use the vmalloc= kernel command line option to set "
+ "VmallocTotal to a larger value\n");
retval = -ENOMEM;
goto free_mem;
}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 77be58c1096b..f6f3e50d4bdf 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -84,7 +84,8 @@
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
-#define CX18_CARD_LAST 7
+#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
+#define CX18_CARD_LAST 8
#define CX18_ENC_STREAM_TYPE_MPG 0
#define CX18_ENC_STREAM_TYPE_TS 1
@@ -106,6 +107,7 @@
#define CX18_PCI_ID_CONEXANT 0x14f1
#define CX18_PCI_ID_TOSHIBA 0x1179
#define CX18_PCI_ID_LEADTEK 0x107D
+#define CX18_PCI_ID_GOTVIEW 0x5854
/* ======================================================================== */
/* ========================== START USER SETTABLE DMA VARIABLES =========== */
@@ -323,7 +325,10 @@ struct cx18_queue {
spinlock_t lock;
};
+struct cx18_stream; /* forward reference */
+
struct cx18_dvb {
+ struct cx18_stream *stream;
struct dmx_frontend hw_frontend;
struct dmx_frontend mem_frontend;
struct dmxdev dmxdev;
@@ -363,9 +368,10 @@ struct cx18_in_work_order {
#define CX18_INVALID_TASK_HANDLE 0xffffffff
struct cx18_stream {
- /* These first four fields are always set, even if the stream
+ /* These first five fields are always set, even if the stream
is not actually created. */
struct video_device *video_dev; /* NULL when stream not created */
+ struct cx18_dvb *dvb; /* DVB / Digital Transport */
struct cx18 *cx; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -395,9 +401,6 @@ struct cx18_stream {
struct cx18_queue q_idle; /* idle - not in rotation */
struct work_struct out_work_order;
-
- /* DVB / Digital Transport */
- struct cx18_dvb dvb;
};
struct cx18_open_id {
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 6d19f040d70f..f0381d62518d 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -137,7 +137,7 @@ static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
{
struct cx18_dvb *dvb = container_of(fe->dvb,
struct cx18_dvb, dvb_adapter);
- struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb);
+ struct cx18_stream *stream = dvb->stream;
const struct firmware *fw = NULL;
int ret;
int i;
@@ -203,6 +203,14 @@ static struct zl10353_config yuan_mpc718_zl10353_demod = {
.disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
};
+static struct zl10353_config gotview_dvd3_zl10353_demod = {
+ .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
+ .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
+ .parallel_ts = 1, /* Not a serial TS */
+ .no_tuner = 1, /* XC3028 is not behind the gate */
+ .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
+};
+
static int dvb_register(struct cx18_stream *stream);
/* Kernel DVB framework calls this when the feed needs to start.
@@ -247,6 +255,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
case CX18_CARD_LEADTEK_DVR3100H:
case CX18_CARD_YUAN_MPC718:
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
default:
/* Assumption - Parallel transport - Signalling
* undefined or default.
@@ -257,22 +266,22 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;
- mutex_lock(&stream->dvb.feedlock);
- if (stream->dvb.feeding++ == 0) {
+ mutex_lock(&stream->dvb->feedlock);
+ if (stream->dvb->feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n");
mutex_lock(&cx->serialize_lock);
set_bit(CX18_F_S_STREAMING, &stream->s_flags);
ret = cx18_start_v4l2_encode_stream(stream);
if (ret < 0) {
CX18_DEBUG_INFO("Failed to start Transport DMA\n");
- stream->dvb.feeding--;
- if (stream->dvb.feeding == 0)
+ stream->dvb->feeding--;
+ if (stream->dvb->feeding == 0)
clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
}
mutex_unlock(&cx->serialize_lock);
} else
ret = 0;
- mutex_unlock(&stream->dvb.feedlock);
+ mutex_unlock(&stream->dvb->feedlock);
return ret;
}
@@ -290,15 +299,15 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
feed->pid, feed->index);
- mutex_lock(&stream->dvb.feedlock);
- if (--stream->dvb.feeding == 0) {
+ mutex_lock(&stream->dvb->feedlock);
+ if (--stream->dvb->feeding == 0) {
CX18_DEBUG_INFO("Stopping Transport DMA\n");
mutex_lock(&cx->serialize_lock);
ret = cx18_stop_v4l2_encode_stream(stream, 0);
mutex_unlock(&cx->serialize_lock);
} else
ret = 0;
- mutex_unlock(&stream->dvb.feedlock);
+ mutex_unlock(&stream->dvb->feedlock);
}
return ret;
@@ -307,7 +316,7 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
int cx18_dvb_register(struct cx18_stream *stream)
{
struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = &stream->dvb;
+ struct cx18_dvb *dvb = stream->dvb;
struct dvb_adapter *dvb_adapter;
struct dvb_demux *dvbdemux;
struct dmx_demux *dmx;
@@ -316,6 +325,9 @@ int cx18_dvb_register(struct cx18_stream *stream)
if (!dvb)
return -EINVAL;
+ dvb->enabled = 0;
+ dvb->stream = stream;
+
ret = dvb_register_adapter(&dvb->dvb_adapter,
CX18_DRIVER_NAME,
THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
@@ -369,7 +381,7 @@ int cx18_dvb_register(struct cx18_stream *stream)
CX18_INFO("DVB Frontend registered\n");
CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
- stream->dvb.dvb_adapter.num, stream->name,
+ stream->dvb->dvb_adapter.num, stream->name,
stream->buffers, stream->buf_size/1024,
(stream->buf_size * 100 / 1024) % 100);
@@ -396,13 +408,16 @@ err_out:
void cx18_dvb_unregister(struct cx18_stream *stream)
{
struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = &stream->dvb;
+ struct cx18_dvb *dvb = stream->dvb;
struct dvb_adapter *dvb_adapter;
struct dvb_demux *dvbdemux;
struct dmx_demux *dmx;
CX18_INFO("unregister DVB\n");
+ if (dvb == NULL || !dvb->enabled)
+ return;
+
dvb_adapter = &dvb->dvb_adapter;
dvbdemux = &dvb->demux;
dmx = &dvbdemux->dmx;
@@ -423,7 +438,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
*/
static int dvb_register(struct cx18_stream *stream)
{
- struct cx18_dvb *dvb = &stream->dvb;
+ struct cx18_dvb *dvb = stream->dvb;
struct cx18 *cx = stream->cx;
int ret = 0;
@@ -495,6 +510,29 @@ static int dvb_register(struct cx18_stream *stream)
fe->ops.tuner_ops.set_config(fe, &ctrl);
}
break;
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
+ dvb->fe = dvb_attach(zl10353_attach,
+ &gotview_dvd3_zl10353_demod,
+ &cx->i2c_adap[1]);
+ if (dvb->fe != NULL) {
+ struct dvb_frontend *fe;
+ struct xc2028_config cfg = {
+ .i2c_adap = &cx->i2c_adap[1],
+ .i2c_addr = 0xc2 >> 1,
+ .ctrl = NULL,
+ };
+ static struct xc2028_ctrl ctrl = {
+ .fname = XC2028_DEFAULT_FIRMWARE,
+ .max_len = 64,
+ .demod = XC3028_FE_ZARLINK456,
+ .type = XC2028_AUTO,
+ };
+
+ fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
+ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
+ fe->ops.tuner_ops.set_config(fe, &ctrl);
+ }
+ break;
default:
/* No Digital Tv Support */
break;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index a09caf883170..c330fb917b50 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -98,7 +98,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
case CX18_HW_Z8F0811_IR_RX_HAUP:
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
init_data->name = cx->card_name;
info.platform_data = init_data;
break;
@@ -122,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
if (hw == CX18_HW_TUNER) {
/* special tuner group handling */
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->radio);
+ adap, type, 0, cx->card_i2c->radio);
if (sd != NULL)
sd->grp_id = hw;
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->demod);
+ adap, type, 0, cx->card_i2c->demod);
if (sd != NULL)
sd->grp_id = hw;
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->tv);
+ adap, type, 0, cx->card_i2c->tv);
if (sd != NULL)
sd->grp_id = hw;
return sd != NULL ? 0 : -1;
@@ -144,7 +144,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
return -1;
/* It's an I2C device other than an analog tuner or IR chip */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx],
+ sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
NULL);
if (sd != NULL)
sd->grp_id = hw;
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 956aa190ecca..c545f3beef78 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -136,7 +136,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
{
struct cx18_buffer *buf;
- if (!s->dvb.enabled || mdl->bytesused == 0)
+ if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
return;
/* We ignore mdl and buf readpos accounting here - it doesn't matter */
@@ -146,7 +146,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
list);
if (buf->bytesused)
- dvb_dmx_swfilter(&s->dvb.demux,
+ dvb_dmx_swfilter(&s->dvb->demux,
buf->buf, buf->bytesused);
return;
}
@@ -154,7 +154,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
list_for_each_entry(buf, &mdl->buf_list, list) {
if (buf->bytesused == 0)
break;
- dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
+ dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
}
}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 9045f1ece0eb..94f5d7967c5c 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
.read = cx18_v4l2_read,
.open = cx18_v4l2_open,
/* FIXME change to video_ioctl2 if serialization lock can be removed */
- .ioctl = cx18_v4l2_ioctl,
+ .unlocked_ioctl = cx18_v4l2_ioctl,
.release = cx18_v4l2_close,
.poll = cx18_v4l2_enc_poll,
};
@@ -107,6 +107,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
s->video_dev = video_dev;
/* initialize cx18_stream fields */
+ s->dvb = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
@@ -140,10 +141,15 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
int num_offset = cx18_stream_info[type].num_offset;
int num = cx->instance + cx18_first_minor + num_offset;
- /* These four fields are always initialized. If video_dev == NULL, then
- this stream is not in use. In that case no other fields but these
- four can be used. */
+ /*
+ * These five fields are always initialized.
+ * For analog capture related streams, if video_dev == NULL then the
+ * stream is not in use.
+ * For the TS stream, if dvb == NULL then the stream is not in use.
+ * In those cases no other fields but these four can be used.
+ */
s->video_dev = NULL;
+ s->dvb = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
@@ -167,6 +173,21 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
cx18_stream_init(cx, type);
+ /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
+ if (type == CX18_ENC_STREAM_TYPE_TS) {
+ if (cx->card->hw_all & CX18_HW_DVB) {
+ s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
+ if (s->dvb == NULL) {
+ CX18_ERR("Couldn't allocate cx18_dvb structure"
+ " for %s\n", s->name);
+ return -ENOMEM;
+ }
+ } else {
+ /* Don't need buffers for the TS, if there is no DVB */
+ s->buffers = 0;
+ }
+ }
+
if (num_offset == -1)
return 0;
@@ -222,13 +243,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
const char *name;
int num, ret;
- /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
- * We need a VFL_TYPE_TS defined.
- */
- if (strcmp("TS", s->name) == 0) {
- /* just return if no DVB is supported */
- if ((cx->card->hw_all & CX18_HW_DVB) == 0)
- return 0;
+ if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
ret = cx18_dvb_register(s);
if (ret < 0) {
CX18_ERR("DVB failed to register\n");
@@ -320,11 +335,13 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
/* Teardown all streams */
for (type = 0; type < CX18_MAX_STREAMS; type++) {
- /* No struct video_device, but can have buffers allocated */
+ /* The TS has a cx18_dvb structure, not a video_device */
if (type == CX18_ENC_STREAM_TYPE_TS) {
- if (cx->streams[type].dvb.enabled) {
- cx18_dvb_unregister(&cx->streams[type]);
- cx->streams[type].dvb.enabled = false;
+ if (cx->streams[type].dvb != NULL) {
+ if (unregister)
+ cx18_dvb_unregister(&cx->streams[type]);
+ kfree(cx->streams[type].dvb);
+ cx->streams[type].dvb = NULL;
cx18_stream_free(&cx->streams[type]);
}
continue;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 77412bee5963..51765eb12d39 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -33,7 +33,8 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
static inline bool cx18_stream_enabled(struct cx18_stream *s)
{
- return s->video_dev || s->dvb.enabled ||
+ return s->video_dev ||
+ (s->dvb && s->dvb->enabled) ||
(s->type == CX18_ENC_STREAM_TYPE_IDX &&
s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
}
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig
index bb04914983fd..ae85a7a7bd73 100644
--- a/drivers/media/video/cx231xx/Kconfig
+++ b/drivers/media/video/cx231xx/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_CX231XX
tristate "Conexant cx231xx USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT
+ depends on VIDEO_DEV && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select VIDEO_CX25840
select VIDEO_CX2341X
@@ -14,6 +14,19 @@ config VIDEO_CX231XX
To compile this driver as a module, choose M here: the
module will be called cx231xx
+config VIDEO_CX231XX_RC
+ bool "Conexant cx231xx Remote Controller additional support"
+ depends on RC_CORE
+ depends on VIDEO_CX231XX
+ default y
+ ---help---
+ cx231xx hardware has a builtin RX/TX support. However, a few
+ designs opted to not use it, but, instead, some other hardware.
+ This module enables the usage of those other hardware, like the
+ ones used with ISDB-T boards.
+
+ On most cases, all you need for IR is mceusb module.
+
config VIDEO_CX231XX_ALSA
tristate "Conexant Cx231xx ALSA audio module"
depends on VIDEO_CX231XX && SND
@@ -30,6 +43,8 @@ config VIDEO_CX231XX_DVB
depends on VIDEO_CX231XX && DVB_CORE
select VIDEOBUF_DVB
select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE
+ select DVB_MB86A20S if !DVB_FE_CUSTOMISE
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile
index a6bc4cc54677..2c2484355449 100644
--- a/drivers/media/video/cx231xx/Makefile
+++ b/drivers/media/video/cx231xx/Makefile
@@ -1,5 +1,6 @@
-cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \
- cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o
+cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o
cx231xx-alsa-objs := cx231xx-audio.o
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index 4c7cac3b6254..fc9526a5b746 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -940,14 +940,14 @@ static int cx231xx_load_firmware(struct cx231xx *dev)
u16 _buffer_size = 4096;
u8 *p_buffer;
- p_current_fw = (u32 *)vmalloc(1884180*4);
+ p_current_fw = vmalloc(1884180 * 4);
p_fw = p_current_fw;
if (p_current_fw == 0) {
dprintk(2, "FAIL!!!\n");
return -1;
}
- p_buffer = (u8 *)vmalloc(4096);
+ p_buffer = vmalloc(4096);
if (p_buffer == 0) {
dprintk(2, "FAIL!!!\n");
return -1;
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index cf50fafa8abb..c53e97295a0d 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -274,7 +274,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
if (ch1_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch1_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH1, value);
@@ -282,7 +282,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
if (ch2_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch2_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH2, value);
@@ -292,7 +292,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
7 less than the input number */
if (ch3_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch3_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH3, value);
@@ -354,6 +354,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev,
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
FLD_PWRDN_ENABLE_PLL)) {
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 56c2d8195ac6..6905607ffca3 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -34,6 +34,7 @@
#include <media/cx25840.h>
#include "dvb-usb-ids.h"
#include "xc5000.h"
+#include "tda18271.h"
#include "cx231xx.h"
@@ -395,6 +396,45 @@ struct cx231xx_board cx231xx_boards[] = {
.gpio = 0,
} },
},
+ [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
+ .name = "Pixelview PlayTV USB Hybrid",
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60,
+ .decoder = CX231XX_AVDECODER,
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
+ .tuner_sif_gpio = -1,
+ .tuner_scl_gpio = -1,
+ .tuner_sda_gpio = -1,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 2,
+ .demod_i2c_master = 1,
+ .ir_i2c_master = 2,
+ .rc_map_name = RC_MAP_PIXELVIEW_002T,
+ .has_dvb = 1,
+ .demod_addr = 0x10,
+ .norm = V4L2_STD_PAL_M,
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ } },
+ },
};
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
@@ -402,8 +442,6 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
struct usb_device_id cx231xx_id_table[] = {
{USB_DEVICE(0x0572, 0x5A3C),
.driver_info = CX231XX_BOARD_UNKNOWN},
- {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
- .driver_info = CX231XX_BOARD_UNKNOWN},
{USB_DEVICE(0x0572, 0x58A2),
.driver_info = CX231XX_BOARD_CNXT_CARRAERA},
{USB_DEVICE(0x0572, 0x58A1),
@@ -424,6 +462,8 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
{USB_DEVICE(0x2040, 0xc200),
.driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
+ {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
+ .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
{},
};
@@ -453,6 +493,16 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
1);
msleep(10);
}
+ } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
+ switch (command) {
+ case TDA18271_CALLBACK_CMD_AGC_ENABLE:
+ if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
+ rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
}
return rc;
}
@@ -560,7 +610,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
if (dev->board.decoder == CX231XX_AVDECODER) {
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[0].i2c_adap,
- NULL, "cx25840", 0x88 >> 1, NULL);
+ "cx25840", 0x88 >> 1, NULL);
if (dev->sd_cx25840 == NULL)
cx231xx_info("cx25840 subdev registration failure\n");
cx25840_call(dev, core, load_fw);
@@ -571,7 +621,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
if (dev->board.tuner_type != TUNER_ABSENT) {
dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- NULL, "tuner",
+ "tuner",
dev->tuner_addr, NULL);
if (dev->sd_tuner == NULL)
cx231xx_info("tuner subdev registration failure\n");
@@ -615,8 +665,11 @@ void cx231xx_release_resources(struct cx231xx *dev)
cx231xx_remove_from_devlist(dev);
+ /* Release I2C buses */
cx231xx_dev_uninit(dev);
+ cx231xx_ir_exit(dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -731,16 +784,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
retval = cx231xx_register_analog_devices(dev);
if (retval < 0) {
cx231xx_release_resources(dev);
- goto fail_reg_devices;
+ return retval;
}
+ cx231xx_ir_init(dev);
+
cx231xx_init_extension(dev);
return 0;
-
-fail_reg_devices:
- mutex_unlock(&dev->lock);
- return retval;
}
#if defined(CONFIG_MODULES) && defined(MODULE)
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 4af46fca9b0a..7d62d58617f5 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -740,6 +740,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
break;
default:
@@ -1288,7 +1289,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
/* Internal Master 3 Bus */
dev->i2c_bus[2].nr = 2;
dev->i2c_bus[2].dev = dev;
- dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */
+ dev->i2c_bus[2].i2c_period = I2C_SPEED_100K; /* 100kHz */
dev->i2c_bus[2].i2c_nostop = 0;
dev->i2c_bus[2].i2c_reserve = 0;
@@ -1381,6 +1382,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
break;
default:
@@ -1513,7 +1515,7 @@ int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
if (saddr_len == 0)
saddr = 0;
- else if (saddr_len == 0)
+ else if (saddr_len == 1)
saddr &= 0xff;
/* prepare xfer_data struct */
@@ -1564,7 +1566,7 @@ int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
if (saddr_len == 0)
saddr = 0;
- else if (saddr_len == 0)
+ else if (saddr_len == 1)
saddr &= 0xff;
/* prepare xfer_data struct */
@@ -1598,7 +1600,7 @@ int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
if (saddr_len == 0)
saddr = 0;
- else if (saddr_len == 0)
+ else if (saddr_len == 1)
saddr &= 0xff;
/* prepare xfer_data struct */
@@ -1639,7 +1641,7 @@ int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
if (saddr_len == 0)
saddr = 0;
- else if (saddr_len == 0)
+ else if (saddr_len == 1)
saddr &= 0xff;
/* prepare xfer_data struct */
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 5feb3ee640d9..fe59a1c3f064 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -33,6 +33,7 @@
#include "tda18271.h"
#include "s5h1411.h"
#include "lgdt3305.h"
+#include "mb86a20s.h"
MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
@@ -88,6 +89,11 @@ static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
.if_lvl = 1, .rfagc_top = 0x37, },
};
+static struct tda18271_std_map mb86a20s_tda18271_config = {
+ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+ .if_lvl = 7, .rfagc_top = 0x37, },
+};
+
static struct tda18271_config cnxt_rde253s_tunerconfig = {
.std_map = &cnxt_rde253s_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
@@ -135,6 +141,17 @@ static struct tda18271_config hcw_tda18271_config = {
.gate = TDA18271_GATE_DIGITAL,
};
+static const struct mb86a20s_config pv_mb86a20s_config = {
+ .demod_address = 0x10,
+ .is_serial = true,
+};
+
+static struct tda18271_config pv_tda18271_config = {
+ .std_map = &mb86a20s_tda18271_config,
+ .gate = TDA18271_GATE_DIGITAL,
+ .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
+};
+
static inline void print_err_status(struct cx231xx *dev, int packet, int status)
{
char *errmsg = "Unknown";
@@ -687,6 +704,29 @@ static int dvb_init(struct cx231xx *dev)
&hcw_tda18271_config);
break;
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+
+ printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
+ __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
+
+ dev->dvb->frontend = dvb_attach(mb86a20s_attach,
+ &pv_mb86a20s_config,
+ &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach mb86a20s demod\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ dvb_attach(tda18271_attach, dev->dvb->frontend,
+ 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
+ &pv_tda18271_config);
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
new file mode 100644
index 000000000000..45e14cac4622
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -0,0 +1,112 @@
+/*
+ * cx231xx IR glue driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * Polaris (cx231xx) has its support for IR's with a design close to MCE.
+ * however, a few designs are using an external I2C chip for IR, instead
+ * of using the one provided by the chip.
+ * This driver provides support for those extra devices
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include "cx231xx.h"
+#include <linux/usb.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "cx231xx-input"
+
+static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key,
+ u32 *ir_raw)
+{
+ u8 cmd, scancode;
+
+ dev_dbg(&ir->rc->input_dev->dev, "%s\n", __func__);
+
+ /* poll IR chip */
+ if (1 != i2c_master_recv(ir->c, &cmd, 1))
+ return -EIO;
+
+ /* it seems that 0xFE indicates that a button is still hold
+ down, while 0xff indicates that no button is hold
+ down. 0xfe sequences are sometimes interrupted by 0xFF */
+
+ if (cmd == 0xff)
+ return 0;
+
+ scancode =
+ ((cmd & 0x01) ? 0x80 : 0) |
+ ((cmd & 0x02) ? 0x40 : 0) |
+ ((cmd & 0x04) ? 0x20 : 0) |
+ ((cmd & 0x08) ? 0x10 : 0) |
+ ((cmd & 0x10) ? 0x08 : 0) |
+ ((cmd & 0x20) ? 0x04 : 0) |
+ ((cmd & 0x40) ? 0x02 : 0) |
+ ((cmd & 0x80) ? 0x01 : 0);
+
+ dev_dbg(&ir->rc->input_dev->dev, "cmd %02x, scan = %02x\n",
+ cmd, scancode);
+
+ *ir_key = scancode;
+ *ir_raw = scancode;
+ return 1;
+}
+
+int cx231xx_ir_init(struct cx231xx *dev)
+{
+ struct i2c_board_info info;
+ u8 ir_i2c_bus;
+
+ dev_dbg(&dev->udev->dev, "%s\n", __func__);
+
+ /* Only initialize if a rc keycode map is defined */
+ if (!cx231xx_boards[dev->model].rc_map_name)
+ return -ENODEV;
+
+ request_module("ir-kbd-i2c");
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&dev->init_data, 0, sizeof(dev->init_data));
+ dev->init_data.rc_dev = rc_allocate_device();
+ if (!dev->init_data.rc_dev)
+ return -ENOMEM;
+
+ dev->init_data.name = cx231xx_boards[dev->model].name;
+
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ info.platform_data = &dev->init_data;
+
+ /*
+ * Board-dependent values
+ *
+ * For now, there's just one type of hardware design using
+ * an i2c device.
+ */
+ dev->init_data.get_key = get_key_isdbt;
+ dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name;
+ /* The i2c micro-controller only outputs the cmd part of NEC protocol */
+ dev->init_data.rc_dev->scanmask = 0xff;
+ dev->init_data.rc_dev->driver_name = "cx231xx";
+ dev->init_data.type = RC_TYPE_NEC;
+ info.addr = 0x30;
+
+ /* Load and bind ir-kbd-i2c */
+ ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
+ dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
+ ir_i2c_bus, info.addr);
+ i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info);
+
+ return 0;
+}
+
+void cx231xx_ir_exit(struct cx231xx *dev)
+{
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index b13b69fb2af6..7e3e8c4f19b7 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2044,15 +2044,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct cx231xx_fh *fh = priv;
-
- return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
-}
-#endif
-
/* ----------------------------------------------------------- */
/* RADIO ESPECIFIC IOCTLS */
/* ----------------------------------------------------------- */
@@ -2507,9 +2498,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static struct video_device cx231xx_vbi_template;
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index d067df9b81e7..72bbea2bcd56 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -34,7 +34,8 @@
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
+#include <media/ir-kbd-i2c.h>
#include <media/videobuf-dvb.h>
#include "cx231xx-reg.h"
@@ -62,6 +63,7 @@
#define CX231XX_BOARD_CNXT_RDU_250 7
#define CX231XX_BOARD_HAUPPAUGE_EXETER 8
#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
+#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
/* Limits minimum and default number of buffers */
#define CX231XX_MIN_BUF 4
@@ -344,6 +346,10 @@ struct cx231xx_board {
/* i2c masters */
u8 tuner_i2c_master;
u8 demod_i2c_master;
+ u8 ir_i2c_master;
+
+ /* for devices with I2C chips for IR */
+ char *rc_map_name;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
@@ -356,7 +362,7 @@ struct cx231xx_board {
struct cx231xx_input input[MAX_CX231XX_INPUT];
struct cx231xx_input radio;
- struct ir_scancode_table *ir_codes;
+ struct rc_map *ir_codes;
};
/* device states */
@@ -605,6 +611,9 @@ struct cx231xx {
struct cx231xx_board board;
+ /* For I2C IR support */
+ struct IR_i2c_init_data init_data;
+
unsigned int stream_on:1; /* Locks streams */
unsigned int vbi_stream_on:1; /* Locks streams for VBI */
unsigned int has_audio_class:1;
@@ -616,8 +625,6 @@ struct cx231xx {
struct v4l2_subdev *sd_cx25840;
struct v4l2_subdev *sd_tuner;
- struct cx231xx_IR *ir;
-
struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
atomic_t stream_started; /* stream should be running if true */
@@ -954,6 +961,17 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
extern int cx231xx_417_register(struct cx231xx *dev);
extern void cx231xx_417_unregister(struct cx231xx *dev);
+/* cx23885-input.c */
+
+#if defined(CONFIG_VIDEO_CX231XX_RC)
+int cx231xx_ir_init(struct cx231xx *dev);
+void cx231xx_ir_exit(struct cx231xx *dev);
+#else
+#define cx231xx_ir_init(dev) (0)
+#define cx231xx_ir_exit(dev) (0)
+#endif
+
+
/* printk macros */
#define cx231xx_err(fmt, arg...) do {\
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index e5c3c8da4be3..103ef6bad2e2 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -853,9 +853,9 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
}
EXPORT_SYMBOL(cx2341x_ctrl_query);
-const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
+const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
{
- static const char *mpeg_stream_type_without_ts[] = {
+ static const char * const mpeg_stream_type_without_ts[] = {
"MPEG-2 Program Stream",
"",
"MPEG-1 System Stream",
@@ -952,7 +952,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
struct v4l2_queryctrl qctrl;
- const char **menu_items = NULL;
+ const char * const *menu_items = NULL;
qctrl.id = ctrl->id;
err = cx2341x_ctrl_query(params, &qctrl);
@@ -1135,7 +1135,7 @@ EXPORT_SYMBOL(cx2341x_update);
static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
{
- const char **menu = cx2341x_ctrl_get_menu(p, id);
+ const char * const *menu = cx2341x_ctrl_get_menu(p, id);
struct v4l2_ext_control ctrl;
if (menu == NULL)
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index e1367b35647a..6b4a516addfe 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_CX23885
select VIDEO_BTCX
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on IR_CORE
+ depends on RC_CORE
select VIDEOBUF_DVB
select VIDEOBUF_DMA_SG
select VIDEO_CX25840
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index db054004e462..b298b730943c 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -309,6 +309,26 @@ struct cx23885_board cx23885_boards[] = {
CX25840_COMPONENT_ON,
} },
},
+ [CX23885_BOARD_GOTVIEW_X5_3D_HYBRID] = {
+ .name = "GoTView X5 3D Hybrid",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x64,
+ .porta = CX23885_ANALOG_VIDEO,
+ .portb = CX23885_MPEG_DVB,
+ .input = {{
+ .type = CX23885_VMUX_TELEVISION,
+ .vmux = CX25840_VIN2_CH1 |
+ CX25840_VIN5_CH2,
+ .gpio0 = 0x02,
+ }, {
+ .type = CX23885_VMUX_COMPOSITE1,
+ .vmux = CX23885_VMUX_COMPOSITE1,
+ }, {
+ .type = CX23885_VMUX_SVIDEO,
+ .vmux = CX25840_SVIDEO_LUMA3 |
+ CX25840_SVIDEO_CHROMA4,
+ } },
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -496,6 +516,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x107d,
.subdevice = 0x6f22,
.card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200,
+ }, {
+ .subvendor = 0x5654,
+ .subdevice = 0x2390,
+ .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -712,6 +736,10 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
else if (port->nr == 2)
bitmask = 0x04;
break;
+ case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
+ /* Tuner Reset Command */
+ bitmask = 0x02;
+ break;
}
if (bitmask) {
@@ -967,6 +995,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
/* CX24228 GPIO */
/* Connected to IF / Mux */
break;
+ case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
+ cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
+ break;
}
}
@@ -1218,6 +1249,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1850:
case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
case CX23885_BOARD_HAUPPAUGE_HVR1290:
+ case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
default:
ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -1245,9 +1277,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_MAGICPRO_PROHDTVE2:
case CX23885_BOARD_HAUPPAUGE_HVR1290:
case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
+ case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap,
- NULL, "cx25840", 0x88 >> 1, NULL);
+ "cx25840", 0x88 >> 1, NULL);
if (dev->sd_cx25840) {
dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index bb61870b8d6e..0b0d0664382a 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -35,9 +35,8 @@
* 02110-1301, USA.
*/
-#include <linux/input.h>
#include <linux/slab.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <media/v4l2-subdev.h>
#include "cx23885.h"
@@ -62,16 +61,16 @@ static void cx23885_input_process_measurements(struct cx23885_dev *dev,
count = num / sizeof(struct ir_raw_event);
for (i = 0; i < count; i++) {
- ir_raw_event_store(kernel_ir->inp_dev,
+ ir_raw_event_store(kernel_ir->rc,
&ir_core_event[i]);
handle = true;
}
} while (num != 0);
if (overrun)
- ir_raw_event_reset(kernel_ir->inp_dev);
+ ir_raw_event_reset(kernel_ir->rc);
else if (handle)
- ir_raw_event_handle(kernel_ir->inp_dev);
+ ir_raw_event_handle(kernel_ir->rc);
}
void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
@@ -197,9 +196,9 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)
return 0;
}
-static int cx23885_input_ir_open(void *priv)
+static int cx23885_input_ir_open(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx == NULL)
return -ENODEV;
@@ -234,9 +233,9 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev)
flush_scheduled_work();
}
-static void cx23885_input_ir_close(void *priv)
+static void cx23885_input_ir_close(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx != NULL)
cx23885_input_ir_stop(kernel_ir->cx);
@@ -245,9 +244,7 @@ static void cx23885_input_ir_close(void *priv)
int cx23885_input_init(struct cx23885_dev *dev)
{
struct cx23885_kernel_ir *kernel_ir;
- struct input_dev *inp_dev;
- struct ir_dev_props *props;
-
+ struct rc_dev *rc;
char *rc_map;
enum rc_driver_type driver_type;
unsigned long allowed_protos;
@@ -267,14 +264,14 @@ int cx23885_input_init(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1250:
/* Integrated CX2388[58] IR controller */
driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = IR_TYPE_ALL;
+ allowed_protos = RC_TYPE_ALL;
/* The grey Hauppauge RC-5 remote */
rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
break;
case CX23885_BOARD_TEVII_S470:
/* Integrated CX23885 IR controller */
driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = IR_TYPE_ALL;
+ allowed_protos = RC_TYPE_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TEVII_NEC;
break;
@@ -294,37 +291,36 @@ int cx23885_input_init(struct cx23885_dev *dev)
pci_name(dev->pci));
/* input device */
- inp_dev = input_allocate_device();
- if (inp_dev == NULL) {
+ rc = rc_allocate_device();
+ if (!rc) {
ret = -ENOMEM;
goto err_out_free;
}
- kernel_ir->inp_dev = inp_dev;
- inp_dev->name = kernel_ir->name;
- inp_dev->phys = kernel_ir->phys;
- inp_dev->id.bustype = BUS_PCI;
- inp_dev->id.version = 1;
+ kernel_ir->rc = rc;
+ rc->input_name = kernel_ir->name;
+ rc->input_phys = kernel_ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- inp_dev->id.vendor = dev->pci->subsystem_vendor;
- inp_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- inp_dev->id.vendor = dev->pci->vendor;
- inp_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- inp_dev->dev.parent = &dev->pci->dev;
-
- /* kernel ir device properties */
- props = &kernel_ir->props;
- props->driver_type = driver_type;
- props->allowed_protos = allowed_protos;
- props->priv = kernel_ir;
- props->open = cx23885_input_ir_open;
- props->close = cx23885_input_ir_close;
+ rc->dev.parent = &dev->pci->dev;
+ rc->driver_type = driver_type;
+ rc->allowed_protos = allowed_protos;
+ rc->priv = kernel_ir;
+ rc->open = cx23885_input_ir_open;
+ rc->close = cx23885_input_ir_close;
+ rc->map_name = rc_map;
+ rc->driver_name = MODULE_NAME;
/* Go */
dev->kernel_ir = kernel_ir;
- ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
+ ret = rc_register_device(rc);
if (ret)
goto err_out_stop;
@@ -333,7 +329,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
err_out_stop:
cx23885_input_ir_stop(dev);
dev->kernel_ir = NULL;
- /* TODO: double check clean-up of kernel_ir->inp_dev */
+ rc_free_device(rc);
err_out_free:
kfree(kernel_ir->phys);
kfree(kernel_ir->name);
@@ -348,7 +344,7 @@ void cx23885_input_fini(struct cx23885_dev *dev)
if (dev->kernel_ir == NULL)
return;
- ir_input_unregister(dev->kernel_ir->inp_dev);
+ rc_unregister_device(dev->kernel_ir->rc);
kfree(dev->kernel_ir->phys);
kfree(dev->kernel_ir->name);
kfree(dev->kernel_ir);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 3cc9f462d08d..644fcb808c0b 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1024,35 +1024,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv,
- struct video_mbuf *mbuf)
-{
- struct cx23885_fh *fh = priv;
- struct videobuf_queue *q;
- struct v4l2_requestbuffers req;
- unsigned int i;
- int err;
-
- q = get_queue(fh);
- memset(&req, 0, sizeof(req));
- req.type = q->type;
- req.count = 8;
- req.memory = V4L2_MEMORY_MMAP;
- err = videobuf_reqbufs(q, &req);
- if (err < 0)
- return err;
-
- mbuf->frames = req.count;
- mbuf->size = 0;
- for (i = 0; i < mbuf->frames; i++) {
- mbuf->offsets[i] = q->bufs[i]->boff;
- mbuf->size += q->bufs[i]->bsize;
- }
- return 0;
-}
-#endif
-
static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
@@ -1155,7 +1126,6 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
if (0 == INPUT(n)->type)
return -EINVAL;
- memset(i, 0, sizeof(*i));
i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, iname[INPUT(n)->type]);
@@ -1427,9 +1397,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
@@ -1507,10 +1474,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
if (dev->tuner_addr)
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[1].i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
else
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[1].i2c_adap, NULL,
+ &dev->i2c_bus[1].i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
if (sd) {
struct tuner_setup tun_setup;
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index ed94b17dd8a5..62e41ab65810 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -30,7 +30,7 @@
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "btcx-risc.h"
#include "cx23885-reg.h"
@@ -84,6 +84,7 @@
#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
#define CX23885_BOARD_MYGICA_X8558PRO 27
#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
+#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002
@@ -310,8 +311,7 @@ struct cx23885_kernel_ir {
char *name;
char *phys;
- struct input_dev *inp_dev;
- struct ir_dev_props props;
+ struct rc_dev *rc;
};
struct cx23885_dev {
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index e78e3e4c8112..e37be6fcf67d 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -26,7 +26,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "cx23885.h"
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index dfb198d0415b..f16461844c5c 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1989,8 +1989,23 @@ static int cx25840_probe(struct i2c_client *client,
v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
V4L2_CID_HUE, -128, 127, 1, 0);
if (!is_cx2583x(state)) {
- default_volume = 228 - cx25840_read(client, 0x8d4);
- default_volume = ((default_volume / 2) + 23) << 9;
+ default_volume = cx25840_read(client, 0x8d4);
+ /*
+ * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume
+ * scale mapping limits to avoid -ERANGE errors when
+ * initializing the volume control
+ */
+ if (default_volume > 228) {
+ /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
+ default_volume = 228;
+ cx25840_write(client, 0x8d4, 228);
+ }
+ else if (default_volume < 20) {
+ /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
+ default_volume = 20;
+ cx25840_write(client, 0x8d4, 20);
+ }
+ default_volume = (((228 - default_volume) >> 1) + 23) << 9;
state->volume = v4l2_ctrl_new_std(&state->hdl,
&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c
index 97a4e9b25fe4..627926f6bde8 100644
--- a/drivers/media/video/cx25840/cx25840-ir.c
+++ b/drivers/media/video/cx25840/cx25840-ir.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <media/cx25840.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "cx25840-core.h"
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 0fa85cbefbb1..5c42abdf422f 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -1,12 +1,11 @@
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
- depends on VIDEO_DEV && PCI && I2C && INPUT
+ depends on VIDEO_DEV && PCI && I2C && RC_CORE
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Conexant 2388x based
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 4aaa47c0eabf..54b7fcd469a8 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -40,7 +40,6 @@
#include <sound/control.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#include <media/wm8775.h>
#include "cx88.h"
#include "cx88-reg.h"
@@ -587,47 +586,26 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
int left, right, v, b;
int changed = 0;
u32 old;
- struct v4l2_control client_ctl;
-
- /* Pass volume & balance onto any WM8775 */
- if (value->value.integer.value[0] >= value->value.integer.value[1]) {
- v = value->value.integer.value[0] << 10;
- b = value->value.integer.value[0] ?
- (0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] :
- 0x8000;
- } else {
- v = value->value.integer.value[1] << 10;
- b = value->value.integer.value[1] ?
- 0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] :
- 0x8000;
- }
- client_ctl.value = v;
- client_ctl.id = V4L2_CID_AUDIO_VOLUME;
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
- client_ctl.value = b;
- client_ctl.id = V4L2_CID_AUDIO_BALANCE;
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
left = value->value.integer.value[0] & 0x3f;
right = value->value.integer.value[1] & 0x3f;
b = right - left;
if (b < 0) {
- v = 0x3f - left;
- b = (-b) | 0x40;
+ v = 0x3f - left;
+ b = (-b) | 0x40;
} else {
- v = 0x3f - right;
+ v = 0x3f - right;
}
/* Do we really know this will always be called with IRQs on? */
spin_lock_irq(&chip->reg_lock);
old = cx_read(AUD_VOL_CTL);
if (v != (old & 0x3f)) {
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
- changed = 1;
+ cx_write(AUD_VOL_CTL, (old & ~0x3f) | v);
+ changed = 1;
}
- if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
- cx_write(AUD_BAL_CTL, b);
- changed = 1;
+ if (cx_read(AUD_BAL_CTL) != b) {
+ cx_write(AUD_BAL_CTL, b);
+ changed = 1;
}
spin_unlock_irq(&chip->reg_lock);
@@ -640,7 +618,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .name = "Analog-TV Volume",
+ .name = "Playback Volume",
.info = snd_cx88_volume_info,
.get = snd_cx88_volume_get,
.put = snd_cx88_volume_put,
@@ -671,14 +649,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
vol = cx_read(AUD_VOL_CTL);
if (value->value.integer.value[0] != !(vol & bit)) {
vol ^= bit;
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
- /* Pass mute onto any WM8775 */
- if ((1<<6) == bit) {
- struct v4l2_control client_ctl;
- client_ctl.value = 0 != (vol & bit);
- client_ctl.id = V4L2_CID_AUDIO_MUTE;
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
- }
+ cx_write(AUD_VOL_CTL, vol);
ret = 1;
}
spin_unlock_irq(&chip->reg_lock);
@@ -687,7 +658,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
static const struct snd_kcontrol_new snd_cx88_dac_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Audio-Out Switch",
+ .name = "Playback Switch",
.info = snd_ctl_boolean_mono_info,
.get = snd_cx88_switch_get,
.put = snd_cx88_switch_put,
@@ -696,49 +667,13 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = {
static const struct snd_kcontrol_new snd_cx88_source_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog-TV Switch",
+ .name = "Capture Switch",
.info = snd_ctl_boolean_mono_info,
.get = snd_cx88_switch_get,
.put = snd_cx88_switch_put,
.private_value = (1<<6),
};
-static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- struct v4l2_control client_ctl;
-
- client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
- call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
- value->value.integer.value[0] = client_ctl.value ? 1 : 0;
-
- return 0;
-}
-
-static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- struct v4l2_control client_ctl;
-
- client_ctl.value = 0 != value->value.integer.value[0];
- client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
- return 0;
-}
-
-static struct snd_kcontrol_new snd_cx88_alc_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line-In ALC Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_cx88_alc_get,
- .put = snd_cx88_alc_put,
-};
-
/****************************************************************************
Basic Flow for Sound Devices
****************************************************************************/
@@ -860,7 +795,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
{
struct snd_card *card;
snd_cx88_card_t *chip;
- struct v4l2_subdev *sd;
int err;
if (devno >= SNDRV_CARDS)
@@ -896,15 +830,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
if (err < 0)
goto error;
- /* If there's a wm8775 then add a Line-In ALC switch */
- list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) {
- if (WM8775_GID == sd->grp_id) {
- snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch,
- chip));
- break;
- }
- }
-
strcpy (card->driver, "CX88x");
sprintf(card->shortname, "Conexant CX%x", pci->device);
sprintf(card->longname, "%s at %#llx",
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index d7c94848249e..bca307eb1e24 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1064,7 +1064,7 @@ static int mpeg_open(struct file *file)
err = drv->request_acquire(drv);
if(err != 0) {
dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
- mutex_unlock(&dev->core->lock);;
+ mutex_unlock(&dev->core->lock);
return err;
}
}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index b26fcba8600c..4e6ee5584cb3 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(latency,"pci latency timer");
static int disable_ir;
module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(latency, "Disable IR support");
+MODULE_PARM_DESC(disable_ir, "Disable IR support");
#define info_printk(core, fmt, arg...) \
printk(KERN_INFO "%s: " fmt, core->name , ## arg)
@@ -1007,15 +1007,22 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .audio_chip = V4L2_IDENT_WM8775,
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
+ /* 2: Line-In */
+ .audioroute = 2,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
+ /* 2: Line-In */
+ .audioroute = 2,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
+ /* 2: Line-In */
+ .audioroute = 2,
}},
.mpeg = CX88_MPEG_DVB,
},
@@ -3515,19 +3522,18 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
later code configures a tea5767.
*/
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
if (has_demod)
v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, NULL, "tuner",
+ &core->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (core->board.tuner_addr == ADDR_UNSET) {
v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, NULL, "tuner",
+ &core->i2c_adap, "tuner",
0, has_demod ? tv_addrs + 4 : tv_addrs);
} else {
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "tuner", core->board.tuner_addr, NULL);
+ "tuner", core->board.tuner_addr, NULL);
}
}
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 367a653f4c95..90717ee944ec 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -67,6 +67,10 @@ static unsigned int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
+static unsigned int dvb_buf_tscnt = 32;
+module_param(dvb_buf_tscnt, int, 0644);
+MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
+
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define dprintk(level,fmt, arg...) if (debug >= level) \
@@ -80,10 +84,10 @@ static int dvb_buf_setup(struct videobuf_queue *q,
struct cx8802_dev *dev = q->priv_data;
dev->ts_packet_size = 188 * 4;
- dev->ts_packet_count = 32;
+ dev->ts_packet_count = dvb_buf_tscnt;
*size = dev->ts_packet_size * dev->ts_packet_count;
- *count = 32;
+ *count = dvb_buf_tscnt;
return 0;
}
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index f53836bb6a5a..a1fe0abb6e43 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -146,7 +146,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
core->i2c_adap.dev.parent = &pci->dev;
strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
core->i2c_adap.owner = THIS_MODULE;
- core->i2c_adap.id = I2C_HW_B_CX2388x;
core->i2c_algo.udelay = i2c_udelay;
core->i2c_algo.data = core;
i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index fc777bc6e716..06f7d1d00944 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -24,14 +24,12 @@
#include <linux/init.h>
#include <linux/hrtimer.h>
-#include <linux/input.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "cx88.h"
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#define MODULE_NAME "cx88xx"
@@ -39,9 +37,7 @@
struct cx88_IR {
struct cx88_core *core;
- struct input_dev *input;
- struct ir_dev_props props;
- u64 ir_type;
+ struct rc_dev *dev;
int users;
@@ -50,8 +46,6 @@ struct cx88_IR {
/* sample from gpio pin 16 */
u32 sampling;
- u32 samples[16];
- int scount;
/* poll external decoder */
int polling;
@@ -63,6 +57,10 @@ struct cx88_IR {
u32 mask_keyup;
};
+static unsigned ir_samplerate = 4;
+module_param(ir_samplerate, uint, 0444);
+MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4");
+
static int ir_debug;
module_param(ir_debug, int, 0644); /* debug level [IR] */
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
@@ -70,6 +68,9 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define ir_dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
+#define dprintk(fmt, arg...) if (ir_debug) \
+ printk(KERN_DEBUG "cx88 IR: " fmt , ##arg)
+
/* ---------------------------------------------------------------------- */
static void cx88_ir_handle_key(struct cx88_IR *ir)
@@ -125,21 +126,26 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
data = (data << 4) | ((gpio_key & 0xf0) >> 4);
- ir_keydown(ir->input, data, 0);
+ rc_keydown(ir->dev, data, 0);
} else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown)
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ else
+ rc_keyup(ir->dev);
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup))
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ else
+ rc_keyup(ir->dev);
} else {
/* can't distinguish keydown/up :-/ */
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keyup(ir->dev);
}
}
@@ -176,8 +182,8 @@ static int __cx88_ir_start(void *priv)
}
if (ir->sampling) {
core->pci_irqmask |= PCI_INT_IR_SMPINT;
- cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */
- cx_write(MO_DDSCFG_IO, 0x5); /* enable */
+ cx_write(MO_DDS_IO, 0x33F286 * ir_samplerate); /* samplerate */
+ cx_write(MO_DDSCFG_IO, 0x5); /* enable */
}
return 0;
}
@@ -214,17 +220,17 @@ void cx88_ir_stop(struct cx88_core *core)
__cx88_ir_stop(core);
}
-static int cx88_ir_open(void *priv)
+static int cx88_ir_open(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users++;
return __cx88_ir_start(core);
}
-static void cx88_ir_close(void *priv)
+static void cx88_ir_close(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users--;
if (!core->ir->users)
@@ -236,20 +242,20 @@ static void cx88_ir_close(void *priv)
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
{
struct cx88_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char *ir_codes = NULL;
- u64 ir_type = IR_TYPE_OTHER;
+ u64 rc_type = RC_TYPE_OTHER;
int err = -ENOMEM;
u32 hardware_mask = 0; /* For devices with a hardware mask, when
* used with a full-code IR table
*/
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ dev = rc_allocate_device();
+ if (!ir || !dev)
goto err_out_free;
- ir->input = input_dev;
+ ir->dev = dev;
/* detect & configure */
switch (core->boardnr) {
@@ -264,7 +270,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
ir_codes = RC_MAP_CINERGY_1400;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xeb04; /* address */
break;
case CX88_BOARD_HAUPPAUGE:
@@ -279,7 +284,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_PCHDTV_HD5500:
case CX88_BOARD_HAUPPAUGE_IRONLY:
ir_codes = RC_MAP_HAUPPAUGE_NEW;
- ir_type = IR_TYPE_RC5;
ir->sampling = 1;
break;
case CX88_BOARD_WINFAST_DTV2000H:
@@ -367,18 +371,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_PROF_7301:
case CX88_BOARD_PROF_6200:
ir_codes = RC_MAP_TBS_NEC;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_TEVII_S460:
case CX88_BOARD_TEVII_S420:
ir_codes = RC_MAP_TEVII_NEC;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_NORWOOD_MICRO:
@@ -396,7 +397,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
ir_codes = RC_MAP_PINNACLE_PCTV_HD;
- ir_type = IR_TYPE_RC5;
ir->sampling = 1;
break;
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
@@ -407,12 +407,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_TWINHAN_VP1027_DVBS:
ir_codes = RC_MAP_TWINHAN_VP1027_DVBS;
- ir_type = IR_TYPE_NEC;
+ rc_type = RC_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
}
- if (NULL == ir_codes) {
+ if (!ir_codes) {
err = -ENODEV;
goto err_out_free;
}
@@ -436,37 +436,45 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- ir->ir_type = ir_type;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->input_name = ir->name;
+ dev->input_phys = ir->phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (pci->subsystem_vendor) {
- input_dev->id.vendor = pci->subsystem_vendor;
- input_dev->id.product = pci->subsystem_device;
+ dev->input_id.vendor = pci->subsystem_vendor;
+ dev->input_id.product = pci->subsystem_device;
} else {
- input_dev->id.vendor = pci->vendor;
- input_dev->id.product = pci->device;
+ dev->input_id.vendor = pci->vendor;
+ dev->input_id.product = pci->device;
}
- input_dev->dev.parent = &pci->dev;
- /* record handles to ourself */
+ dev->dev.parent = &pci->dev;
+ dev->map_name = ir_codes;
+ dev->driver_name = MODULE_NAME;
+ dev->priv = core;
+ dev->open = cx88_ir_open;
+ dev->close = cx88_ir_close;
+ dev->scanmask = hardware_mask;
+
+ if (ir->sampling) {
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->timeout = 10 * 1000 * 1000; /* 10 ms */
+ } else {
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->allowed_protos = rc_type;
+ }
+
ir->core = core;
core->ir = ir;
- ir->props.priv = core;
- ir->props.open = cx88_ir_open;
- ir->props.close = cx88_ir_close;
- ir->props.scanmask = hardware_mask;
-
/* all done */
- err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(dev);
if (err)
goto err_out_free;
return 0;
- err_out_free:
+err_out_free:
+ rc_free_device(dev);
core->ir = NULL;
kfree(ir);
return err;
@@ -481,7 +489,7 @@ int cx88_ir_fini(struct cx88_core *core)
return 0;
cx88_ir_stop(core);
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->dev);
kfree(ir);
/* done */
@@ -494,135 +502,75 @@ int cx88_ir_fini(struct cx88_core *core)
void cx88_ir_irq(struct cx88_core *core)
{
struct cx88_IR *ir = core->ir;
- u32 samples, ircode;
- int i, start, range, toggle, dev, code;
+ u32 samples;
+ unsigned todo, bits;
+ struct ir_raw_event ev;
- if (NULL == ir)
- return;
- if (!ir->sampling)
+ if (!ir || !ir->sampling)
return;
+ /*
+ * Samples are stored in a 32 bit register, oldest sample in
+ * the msb. A set bit represents space and an unset bit
+ * represents a pulse.
+ */
samples = cx_read(MO_SAMPLE_IO);
- if (0 != samples && 0xffffffff != samples) {
- /* record sample data */
- if (ir->scount < ARRAY_SIZE(ir->samples))
- ir->samples[ir->scount++] = samples;
- return;
- }
- if (!ir->scount) {
- /* nothing to sample */
- return;
- }
-
- /* have a complete sample */
- if (ir->scount < ARRAY_SIZE(ir->samples))
- ir->samples[ir->scount++] = samples;
- for (i = 0; i < ir->scount; i++)
- ir->samples[i] = ~ir->samples[i];
- if (ir_debug)
- ir_dump_samples(ir->samples, ir->scount);
- /* decode it */
- switch (core->boardnr) {
- case CX88_BOARD_TEVII_S460:
- case CX88_BOARD_TEVII_S420:
- case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
- case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
- case CX88_BOARD_OMICOM_SS4_PCI:
- case CX88_BOARD_SATTRADE_ST4200:
- case CX88_BOARD_TBS_8920:
- case CX88_BOARD_TBS_8910:
- case CX88_BOARD_PROF_7300:
- case CX88_BOARD_PROF_7301:
- case CX88_BOARD_PROF_6200:
- case CX88_BOARD_TWINHAN_VP1027_DVBS:
- ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
-
- if (ircode == 0xffffffff) { /* decoding error */
- ir_dprintk("pulse distance decoding error\n");
- break;
- }
-
- ir_dprintk("pulse distance decoded: %x\n", ircode);
+ if (samples == 0xff && ir->dev->idle)
+ return;
- if (ircode == 0) { /* key still pressed */
- ir_dprintk("pulse distance decoded repeat code\n");
- ir_repeat(ir->input);
- break;
- }
+ init_ir_raw_event(&ev);
+ for (todo = 32; todo > 0; todo -= bits) {
+ ev.pulse = samples & 0x80000000 ? false : true;
+ bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
+ ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate);
+ ir_raw_event_store_with_filter(ir->dev, &ev);
+ samples <<= bits;
+ }
+ ir_raw_event_handle(ir->dev);
+}
- if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
- ir_dprintk("pulse distance decoded wrong address\n");
- break;
- }
+static int get_key_pvr2000(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ int flags, code;
- if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
- ir_dprintk("pulse distance decoded wrong check sum\n");
- break;
- }
+ /* poll IR chip */
+ flags = i2c_smbus_read_byte_data(ir->c, 0x10);
+ if (flags < 0) {
+ dprintk("read error\n");
+ return 0;
+ }
+ /* key pressed ? */
+ if (0 == (flags & 0x80))
+ return 0;
- ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff);
- ir_keydown(ir->input, (ircode >> 16) & 0xff, 0);
- break;
- case CX88_BOARD_HAUPPAUGE:
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_HVR1100:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- case CX88_BOARD_PCHDTV_HD3000:
- case CX88_BOARD_PCHDTV_HD5500:
- case CX88_BOARD_HAUPPAUGE_IRONLY:
- ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", ircode);
- /*
- * RC5 has an extension bit which adds a new range
- * of available codes, this is detected here. Also
- * hauppauge remotes (black/silver) always use
- * specific device ids. If we do not filter the
- * device ids then messages destined for devices
- * such as TVs (id=0) will get through to the
- * device causing mis-fired events.
- */
- /* split rc5 data block ... */
- start = (ircode & 0x2000) >> 13;
- range = (ircode & 0x1000) >> 12;
- toggle= (ircode & 0x0800) >> 11;
- dev = (ircode & 0x07c0) >> 6;
- code = (ircode & 0x003f) | ((range << 6) ^ 0x0040);
- if( start != 1)
- /* no key pressed */
- break;
- if ( dev != 0x1e && dev != 0x1f )
- /* not a hauppauge remote */
- break;
- ir_keydown(ir->input, code, toggle);
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", ircode);
- if ((ircode & 0xfffff000) != 0x3000)
- break;
- /* Note: bit 0x800 being the toggle is assumed, not checked
- with real hardware */
- ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0);
- break;
+ /* read actual key code */
+ code = i2c_smbus_read_byte_data(ir->c, 0x00);
+ if (code < 0) {
+ dprintk("read error\n");
+ return 0;
}
- ir->scount = 0;
- return;
-}
+ dprintk("IR Key/Flags: (0x%02x/0x%02x)\n",
+ code & 0xff, flags & 0xff);
+ *ir_key = code & 0xff;
+ *ir_raw = code;
+ return 1;
+}
void cx88_i2c_init_ir(struct cx88_core *core)
{
struct i2c_board_info info;
- const unsigned short addr_list[] = {
+ const unsigned short default_addr_list[] = {
0x18, 0x6b, 0x71,
I2C_CLIENT_END
};
+ const unsigned short pvr2000_addr_list[] = {
+ 0x18, 0x1a,
+ I2C_CLIENT_END
+ };
+ const unsigned short *addr_list = default_addr_list;
const unsigned short *addrp;
/* Instantiate the IR receiver device, if present */
if (0 != core->i2c_rc)
@@ -631,6 +579,16 @@ void cx88_i2c_init_ir(struct cx88_core *core)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ switch (core->boardnr) {
+ case CX88_BOARD_LEADTEK_PVR2000:
+ addr_list = pvr2000_addr_list;
+ core->init_data.name = "cx88 Leadtek PVR 2000 remote";
+ core->init_data.type = RC_TYPE_UNKNOWN;
+ core->init_data.get_key = get_key_pvr2000;
+ core->init_data.ir_codes = RC_MAP_EMPTY;
+ break;
+ }
+
/*
* We can't call i2c_new_probed_device() because it uses
* quick writes for probing and at least some RC receiver
@@ -646,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
/* Hauppauge XVR */
core->init_data.name = "cx88 Hauppauge XVR remote";
core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW;
- core->init_data.type = IR_TYPE_RC5;
+ core->init_data.type = RC_TYPE_RC5;
core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
info.platform_data = &core->init_data;
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 88b51194f917..508dabbed986 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -40,7 +40,6 @@
#include "cx88.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <media/wm8775.h>
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -977,7 +976,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
const struct cx88_ctrl *c = NULL;
u32 value,mask;
int i;
- struct v4l2_control client_ctl;
for (i = 0; i < CX8800_CTLS; i++) {
if (cx8800_ctls[i].v.id == ctl->id) {
@@ -991,27 +989,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
ctl->value = c->v.minimum;
if (ctl->value > c->v.maximum)
ctl->value = c->v.maximum;
-
- /* Pass changes onto any WM8775 */
- client_ctl.id = ctl->id;
- switch (ctl->id) {
- case V4L2_CID_AUDIO_MUTE:
- client_ctl.value = ctl->value;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- client_ctl.value = (ctl->value) ?
- (0x90 + ctl->value) << 8 : 0;
- break;
- case V4L2_CID_AUDIO_BALANCE:
- client_ctl.value = ctl->value << 9;
- break;
- default:
- client_ctl.id = 0;
- break;
- }
- if (client_ctl.id)
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
mask=c->mask;
switch (ctl->id) {
case V4L2_CID_AUDIO_BALANCE:
@@ -1179,15 +1156,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct cx8800_fh *fh = priv;
-
- return videobuf_cgmbuf (get_queue(fh), mbuf, 8);
-}
-#endif
-
static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
{
struct cx8800_fh *fh = priv;
@@ -1558,9 +1526,7 @@ static int radio_queryctrl (struct file *file, void *priv,
if (c->id < V4L2_CID_BASE ||
c->id >= V4L2_CID_LASTP1)
return -EINVAL;
- if (c->id == V4L2_CID_AUDIO_MUTE ||
- c->id == V4L2_CID_AUDIO_VOLUME ||
- c->id == V4L2_CID_AUDIO_BALANCE) {
+ if (c->id == V4L2_CID_AUDIO_MUTE) {
for (i = 0; i < CX8800_CTLS; i++) {
if (cx8800_ctls[i].v.id == c->id)
break;
@@ -1731,9 +1697,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
@@ -1895,14 +1858,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
if (core->board.audio_chip == V4L2_IDENT_WM8775)
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "wm8775", 0x36 >> 1, NULL);
+ "wm8775", 0x36 >> 1, NULL);
if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
/* This probes for a tda9874 as is used on some
Pixelview Ultra boards. */
- v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap,
- NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
+ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+ "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
}
switch (core->boardnr) {
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index ec5476d8b10b..d77f8ecab9d7 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -125,7 +125,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
strlcpy(vp3054_i2c->adap.name, core->name,
sizeof(vp3054_i2c->adap.name));
vp3054_i2c->adap.owner = THIS_MODULE;
- vp3054_i2c->adap.id = I2C_HW_B_CX2388x;
vp3054_i2c->algo.data = dev;
i2c_set_adapdata(&vp3054_i2c->adap, dev);
vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index e8c732e7ae4f..c9981e77416a 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -398,19 +398,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
}
-#define call_hw(core, grpid, o, f, args...) \
+#define call_all(core, o, f, args...) \
do { \
if (!core->i2c_rc) { \
if (core->gate_ctrl) \
core->gate_ctrl(core, 1); \
- v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
+ v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
if (core->gate_ctrl) \
core->gate_ctrl(core, 0); \
} \
} while (0)
-#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
-
struct cx8800_dev;
struct cx8802_dev;
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index d8e38cc4ec40..353eadaa823e 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1276,7 +1276,7 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
vb->field = field;
- ret = videobuf_iolock(vq, vb, NULL);;
+ ret = videobuf_iolock(vq, vb, NULL);
if (ret < 0)
return ret;
@@ -1986,7 +1986,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
vpfe_dev->sd[i] =
v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
i2c_adap,
- NULL,
&sdinfo->board_info,
NULL);
if (vpfe_dev->sd[i]) {
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 6ac6acd16352..193abab6b355 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -2013,7 +2013,6 @@ static __init int vpif_probe(struct platform_device *pdev)
vpif_obj.sd[i] =
v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
i2c_adap,
- NULL,
&subdevdata->board_info,
NULL);
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 685f6a6ee603..412c65d54fe1 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -1553,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev)
for (i = 0; i < subdev_count; i++) {
vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
- i2c_adap, NULL,
+ i2c_adap,
&subdevdata[i].board_info,
NULL);
if (!vpif_obj.sd[i]) {
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 66aefd6eef55..985100ea17a4 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_EM28XX
tristate "Empia EM28xx USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT
+ depends on VIDEO_DEV && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
@@ -37,6 +37,7 @@ config VIDEO_EM28XX_DVB
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select DVB_S921 if !DVB_FE_CUSTOMISE
select VIDEOBUF_DVB
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 54859233f311..8af302b425b3 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -268,6 +268,20 @@ static struct em28xx_reg_seq dikom_dk300_digital[] = {
};
+/* Reset for the most [digital] boards */
+static struct em28xx_reg_seq leadership_digital[] = {
+ {EM2874_R80_GPIO, 0x70, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq leadership_reset[] = {
+ {EM2874_R80_GPIO, 0xf0, 0xff, 10},
+ {EM2874_R80_GPIO, 0xb0, 0xff, 10},
+ {EM2874_R80_GPIO, 0xf0, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+
/*
* Board definitions
*/
@@ -1224,6 +1238,19 @@ struct em28xx_board em28xx_boards[] = {
.vmux = SAA7115_COMPOSITE0,
} },
},
+
+ [EM2874_LEADERSHIP_ISDBT] = {
+ .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
+ EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_FREQ_100_KHZ,
+ .xclk = EM28XX_XCLK_FREQUENCY_10MHZ,
+ .name = "EM2874 Leadership ISDBT",
+ .tuner_type = TUNER_ABSENT,
+ .tuner_gpio = leadership_reset,
+ .dvb_gpio = leadership_digital,
+ .has_dvb = 1,
+ },
+
[EM2880_BOARD_MSI_DIGIVOX_AD] = {
.name = "MSI DigiVox A/D",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -1469,7 +1496,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
- .name = "Terratec Hybrid XS (em2882)",
+ .name = "Terratec Cinnergy Hybrid T USB XS (em2882)",
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.mts_firmware = 1,
@@ -1633,11 +1660,11 @@ struct em28xx_board em28xx_boards[] = {
.input = { {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO2,
+ .amux = EM28XX_AMUX_LINE_IN,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_VIDEO2,
+ .amux = EM28XX_AMUX_LINE_IN,
} },
},
[EM2860_BOARD_TERRATEC_AV350] = {
@@ -1754,6 +1781,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2868),
.driver_info = EM2820_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2875),
+ .driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
{ USB_DEVICE(0xeb1a, 0xe303),
@@ -1791,7 +1820,7 @@ struct usb_device_id em28xx_id_table[] = {
{ USB_DEVICE(0x0ccd, 0x005e),
.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
{ USB_DEVICE(0x0ccd, 0x0042),
- .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+ .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
{ USB_DEVICE(0x0ccd, 0x0043),
.driver_info = EM2870_BOARD_TERRATEC_XS },
{ USB_DEVICE(0x0ccd, 0x0047),
@@ -1873,6 +1902,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
{0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
+ {0x6b800080, EM2874_LEADERSHIP_ISDBT, TUNER_ABSENT},
};
/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@ -2408,7 +2438,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
dev->init_data.get_key = em28xx_get_key_em_haup;
dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
- dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;;
+ dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
break;
@@ -2430,8 +2460,36 @@ void em28xx_card_setup(struct em28xx *dev)
dev->board.is_webcam = 0;
else
dev->progressive = 1;
- } else
- em28xx_set_model(dev);
+ }
+
+ if (!dev->board.is_webcam) {
+ switch (dev->model) {
+ case EM2820_BOARD_UNKNOWN:
+ case EM2800_BOARD_UNKNOWN:
+ /*
+ * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
+ *
+ * This occurs because they share identical USB vendor and
+ * product IDs.
+ *
+ * What we do here is look up the EEPROM hash of the K-WORLD
+ * and if it is found then we decide that we do not have
+ * a DIGIVOX and reset the device to the K-WORLD instead.
+ *
+ * This solution is only valid if they do not share eeprom
+ * hash identities which has not been determined as yet.
+ */
+ if (em28xx_hint_board(dev) < 0)
+ em28xx_errdev("Board not discovered\n");
+ else {
+ em28xx_set_model(dev);
+ em28xx_pre_card_setup(dev);
+ }
+ break;
+ default:
+ em28xx_set_model(dev);
+ }
+ }
em28xx_info("Identified as %s (card=%d)\n",
dev->board.name, dev->model);
@@ -2554,39 +2612,39 @@ void em28xx_card_setup(struct em28xx *dev)
/* request some modules */
if (dev->board.has_msp34xx)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "msp3400", 0, msp3400_addrs);
+ "msp3400", 0, msp3400_addrs);
if (dev->board.decoder == EM28XX_SAA711X)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "saa7115_auto", 0, saa711x_addrs);
+ "saa7115_auto", 0, saa711x_addrs);
if (dev->board.decoder == EM28XX_TVP5150)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvp5150", 0, tvp5150_addrs);
+ "tvp5150", 0, tvp5150_addrs);
if (dev->em28xx_sensor == EM28XX_MT9V011) {
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs);
+ &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
}
if (dev->board.adecoder == EM28XX_TVAUDIO)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvaudio", dev->board.tvaudio_addr, NULL);
+ "tvaudio", dev->board.tvaudio_addr, NULL);
if (dev->board.tuner_type != TUNER_ABSENT) {
int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
if (dev->board.radio.type)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->board.radio_addr, NULL);
+ "tuner", dev->board.radio_addr, NULL);
if (has_demod)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (dev->tuner_addr == 0) {
enum v4l2_i2c_tuner_type type =
@@ -2594,14 +2652,14 @@ void em28xx_card_setup(struct em28xx *dev)
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(type));
if (sd)
dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
} else {
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
}
}
@@ -2749,8 +2807,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_pre_card_setup(dev);
if (!dev->board.is_em2800) {
- /* Sets I2C speed to 100 KHz */
- retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+ /* Resets I2C speed */
+ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_regs_req failed!"
" retval [%d]\n",
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 3ac8d3025fea..c7c04bf712aa 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -37,6 +37,7 @@
#include "mt352_priv.h" /* FIXME */
#include "tda1002x.h"
#include "tda18271.h"
+#include "s921.h"
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -245,6 +246,10 @@ static struct lgdt3305_config em2870_lgdt3304_dev = {
.qam_if_khz = 4000,
};
+static struct s921_config sharp_isdbt = {
+ .demod_address = 0x30 >> 1
+};
+
static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
@@ -481,6 +486,7 @@ static int dvb_init(struct em28xx *dev)
if (!dev->board.has_dvb) {
/* This device does not support the extension */
+ printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n");
return 0;
}
@@ -496,6 +502,16 @@ static int dvb_init(struct em28xx *dev)
em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
+ case EM2874_LEADERSHIP_ISDBT:
+ dvb->frontend = dvb_attach(s921_attach,
+ &sharp_isdbt, &dev->i2c_adap);
+
+ if (!dvb->frontend) {
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ break;
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 6759cd5570dd..29cc74441a7d 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/usb.h>
#include <linux/slab.h>
@@ -64,7 +63,7 @@ struct em28xx_ir_poll_result {
struct em28xx_IR {
struct em28xx *dev;
- struct input_dev *input;
+ struct rc_dev *rc;
char name[32];
char phys[32];
@@ -75,10 +74,6 @@ struct em28xx_IR {
unsigned int last_readcount;
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
-
- /* IR device properties */
-
- struct ir_dev_props props;
};
/**********************************************************
@@ -302,12 +297,12 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
poll_result.toggle_bit, poll_result.read_count,
poll_result.rc_address, poll_result.rc_data[0]);
if (ir->full_code)
- ir_keydown(ir->input,
+ rc_keydown(ir->rc,
poll_result.rc_address << 8 |
poll_result.rc_data[0],
poll_result.toggle_bit);
else
- ir_keydown(ir->input,
+ rc_keydown(ir->rc,
poll_result.rc_data[0],
poll_result.toggle_bit);
@@ -331,9 +326,9 @@ static void em28xx_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int em28xx_ir_start(void *priv)
+static int em28xx_ir_start(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
schedule_delayed_work(&ir->work, 0);
@@ -341,30 +336,30 @@ static int em28xx_ir_start(void *priv)
return 0;
}
-static void em28xx_ir_stop(void *priv)
+static void em28xx_ir_stop(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int em28xx_ir_change_protocol(void *priv, u64 ir_type)
+int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
{
int rc = 0;
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc_dev->priv;
struct em28xx *dev = ir->dev;
u8 ir_config = EM2874_IR_RC5;
/* Adjust xclk based o IR table for RC5/NEC tables */
- if (ir_type == IR_TYPE_RC5) {
+ if (rc_type == RC_TYPE_RC5) {
dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
ir->full_code = 1;
- } else if (ir_type == IR_TYPE_NEC) {
+ } else if (rc_type == RC_TYPE_NEC) {
dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
ir_config = EM2874_IR_NEC;
ir->full_code = 1;
- } else if (ir_type != IR_TYPE_UNKNOWN)
+ } else if (rc_type != RC_TYPE_UNKNOWN)
rc = -EINVAL;
em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
@@ -391,7 +386,7 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type)
int em28xx_ir_init(struct em28xx *dev)
{
struct em28xx_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (dev->board.ir_codes == NULL) {
@@ -400,28 +395,27 @@ int em28xx_ir_init(struct em28xx *dev)
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = input_dev;
+ ir->rc = rc;
/*
* em2874 supports more protocols. For now, let's just announce
* the two protocols that were already tested
*/
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = em28xx_ir_change_protocol;
- ir->props.open = em28xx_ir_start;
- ir->props.close = em28xx_ir_stop;
+ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = em28xx_ir_change_protocol;
+ rc->open = em28xx_ir_start;
+ rc->close = em28xx_ir_stop;
/* By default, keep protocol field untouched */
- err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
+ err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
if (err)
goto err_out_free;
@@ -435,27 +429,27 @@ int em28xx_ir_init(struct em28xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
-
- input_dev->dev.parent = &dev->udev->dev;
-
-
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->dev.parent = &dev->udev->dev;
+ rc->map_name = dev->board.ir_codes;
+ rc->driver_name = MODULE_NAME;
/* all done */
- err = ir_input_register(ir->input, dev->board.ir_codes,
- &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
return 0;
+
err_out_stop:
dev->ir = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -468,8 +462,8 @@ int em28xx_ir_fini(struct em28xx *dev)
if (!ir)
return 0;
- em28xx_ir_stop(ir);
- ir_input_unregister(ir->input);
+ em28xx_ir_stop(ir->rc);
+ rc_unregister_device(ir->rc);
kfree(ir);
/* done */
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
index 7f1c4a2173b6..2b4c9cba2d67 100644
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/hardirq.h>
#include <linux/init.h>
#include "em28xx.h"
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 908e3bc88303..f34d524ccb09 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1434,7 +1434,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
/* It isn't an AC97 control. Sends it to the v4l2 dev interface */
if (rc == 1) {
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
+ rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
/*
* In the case of non-AC97 volume controls, we still need
@@ -1708,11 +1708,15 @@ static int vidioc_streamoff(struct file *file, void *priv,
fh, type, fh->resources, dev->resources);
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh, EM28XX_RESOURCE_VIDEO);
+ if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh, EM28XX_RESOURCE_VIDEO);
+ }
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- videobuf_streamoff(&fh->vb_vbiq);
- res_free(fh, EM28XX_RESOURCE_VBI);
+ if (res_check(fh, EM28XX_RESOURCE_VBI)) {
+ videobuf_streamoff(&fh->vb_vbiq);
+ res_free(fh, EM28XX_RESOURCE_VBI);
+ }
}
return 0;
@@ -1934,19 +1938,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
O_NONBLOCK);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct em28xx_fh *fh = priv;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
- else
- return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8);
-}
-#endif
-
-
/* ----------------------------------------------------------- */
/* RADIO ESPECIFIC IOCTLS */
/* ----------------------------------------------------------- */
@@ -2359,9 +2350,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_register = vidioc_s_register,
.vidioc_g_chip_ident = vidioc_g_chip_ident,
#endif
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static const struct video_device em28xx_video_template = {
@@ -2377,7 +2365,7 @@ static const struct v4l2_file_operations radio_fops = {
.owner = THIS_MODULE,
.open = em28xx_v4l2_open,
.release = em28xx_v4l2_close,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6a75e6a4fc21..6f2795a3d4b7 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -33,7 +33,7 @@
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/ir-kbd-i2c.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
#include <media/videobuf-dvb.h>
#endif
@@ -117,6 +117,8 @@
#define EM2800_BOARD_VC211A 74
#define EM2882_BOARD_DIKOM_DK300 75
#define EM2870_BOARD_KWORLD_A340 76
+#define EM2874_LEADERSHIP_ISDBT 77
+
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index a5cfc76b40b7..a982750dcef1 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1610,6 +1610,7 @@ et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg)
memset(&i, 0, sizeof(i));
strcpy(i.name, "Camera");
i.type = V4L2_INPUT_TYPE_CAMERA;
+ i.capabilities = V4L2_IN_CAP_STD;
if (copy_to_user(arg, &i, sizeof(i)))
return -EFAULT;
@@ -2530,7 +2531,7 @@ static const struct v4l2_file_operations et61x251_fops = {
.owner = THIS_MODULE,
.open = et61x251_open,
.release = et61x251_release,
- .ioctl = et61x251_ioctl,
+ .unlocked_ioctl = et61x251_ioctl,
.read = et61x251_read,
.poll = et61x251_poll,
.mmap = et61x251_mmap,
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 9a075d83dd1f..e4bba88254c7 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -194,6 +194,8 @@ struct viu_dev {
/* decoder */
struct v4l2_subdev *decoder;
+
+ v4l2_std_id std;
};
struct viu_fh {
@@ -915,6 +917,8 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
if (fh->type != i)
return -EINVAL;
+ viu_start_dma(fh->dev);
+
return videobuf_streamon(&fh->vb_vidq);
}
@@ -927,20 +931,39 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
if (fh->type != i)
return -EINVAL;
+ viu_stop_dma(fh->dev);
+
return videobuf_streamoff(&fh->vb_vidq);
}
#define decoder_call(viu, o, f, args...) \
v4l2_subdev_call(viu->decoder, o, f, ##args)
+static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+ struct viu_fh *fh = priv;
+
+ decoder_call(fh->dev, video, querystd, std_id);
+ return 0;
+}
+
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
{
struct viu_fh *fh = priv;
+ fh->dev->std = *id;
decoder_call(fh->dev, core, s_std, *id);
return 0;
}
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+ struct viu_fh *fh = priv;
+
+ *std_id = fh->dev->std;
+ return 0;
+}
+
/* only one input in this driver */
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
@@ -1331,6 +1354,7 @@ static int viu_release(struct file *file)
viu_stop_dma(dev);
videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
kfree(fh);
@@ -1397,7 +1421,9 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_g_std = vidioc_g_std,
.vidioc_s_std = vidioc_s_std,
+ .vidioc_querystd = vidioc_querystd,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1486,7 +1512,7 @@ static int __devinit viu_of_probe(struct platform_device *op,
ad = i2c_get_adapter(0);
viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
- NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
+ "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
viu_dev->vidq.timeout.function = viu_vid_timeout;
viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 9b121681d135..c1ae05f4661f 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -37,7 +37,7 @@ MODULE_LICENSE("GPL");
/* constant value's */
#define MAGIC_0 0x19
#define MAGIC_1 0x68
-#define DATA_IN 0xC0
+#define DATA_IN 0xc0
#define DATA_OUT 0x40
#define VIDEOSIZE_QCIF 0 /* 176x144 */
#define VIDEOSIZE_CIF 1 /* 352x288 */
@@ -660,9 +660,9 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
if (sd->params.qx3.button) {
/* button pressed - unlock the latch */
do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xDF, 0xDF, 0);
+ 3, 0xdf, 0xdf, 0);
do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xFF, 0xFF, 0);
+ 3, 0xff, 0xff, 0);
}
/* test whether microscope is cradled */
@@ -829,7 +829,7 @@ static int goto_low_power(struct gspca_dev *gspca_dev)
if (ret)
return ret;
- do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+ ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
if (ret)
return ret;
@@ -1110,12 +1110,12 @@ static int command_setlights(struct gspca_dev *gspca_dev)
p2 = (sd->params.qx3.toplight == 0) << 3;
ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
- 0x90, 0x8F, 0x50, 0);
+ 0x90, 0x8f, 0x50, 0);
if (ret)
return ret;
return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
- p1 | p2 | 0xE0, 0);
+ p1 | p2 | 0xe0, 0);
}
static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 8fe8fb486d62..442970073e8a 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 10, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -224,12 +224,12 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
buffer, buffer_len,
int_irq, (void *)gspca_dev, interval);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- gspca_dev->int_urb = urb;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) {
PDEBUG(D_ERR, "submit int URB failed with error %i", ret);
goto error_submit;
}
+ gspca_dev->int_urb = urb;
return ret;
error_submit:
@@ -318,14 +318,9 @@ static void fill_frame(struct gspca_dev *gspca_dev,
}
pkt_scan = gspca_dev->sd_desc->pkt_scan;
for (i = 0; i < urb->number_of_packets; i++) {
+ len = urb->iso_frame_desc[i].actual_length;
/* check the packet status and length */
- len = urb->iso_frame_desc[i].actual_length;
- if (len == 0) {
- if (gspca_dev->empty_packet == 0)
- gspca_dev->empty_packet = 1;
- continue;
- }
st = urb->iso_frame_desc[i].status;
if (st) {
err("ISOC data error: [%d] len=%d, status=%d",
@@ -333,6 +328,11 @@ static void fill_frame(struct gspca_dev *gspca_dev,
gspca_dev->last_packet_type = DISCARD_PACKET;
continue;
}
+ if (len == 0) {
+ if (gspca_dev->empty_packet == 0)
+ gspca_dev->empty_packet = 1;
+ continue;
+ }
/* let the packet be analyzed by the subdriver */
PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
@@ -652,16 +652,12 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
: USB_ENDPOINT_XFER_ISOC;
i = gspca_dev->alt; /* previous alt setting */
if (gspca_dev->cam.reverse_alts) {
- if (gspca_dev->audio && i < gspca_dev->nbalt - 2)
- i++;
while (++i < gspca_dev->nbalt) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
}
} else {
- if (gspca_dev->audio && i > 1)
- i--;
while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
@@ -676,13 +672,11 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
i, ep->desc.bEndpointAddress);
gspca_dev->alt = i; /* memorize the current alt setting */
if (gspca_dev->nbalt > 1) {
- gspca_input_destroy_urb(gspca_dev);
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
if (ret < 0) {
err("set alt %d err %d", i, ret);
ep = NULL;
}
- gspca_input_create_urb(gspca_dev);
}
return ep;
}
@@ -759,7 +753,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
}
} else { /* bulk */
urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,
- ep->desc.bEndpointAddress),
+ ep->desc.bEndpointAddress);
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
urb->complete = bulk_irq;
}
@@ -781,7 +775,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (!gspca_dev->present) {
ret = -ENODEV;
- goto out;
+ goto unlock;
}
/* reset the streaming variables */
@@ -802,8 +796,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (gspca_dev->sd_desc->isoc_init) {
ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
if (ret < 0)
- goto out;
+ goto unlock;
}
+
+ gspca_input_destroy_urb(gspca_dev);
ep = get_ep(gspca_dev);
if (ep == NULL) {
ret = -EIO;
@@ -873,6 +869,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
}
}
out:
+ gspca_input_create_urb(gspca_dev);
+unlock:
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1299,17 +1297,19 @@ static int vidioc_querycap(struct file *file, void *priv,
ret = -ENODEV;
goto out;
}
- strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
+ strncpy((char *) cap->driver, gspca_dev->sd_desc->name,
+ sizeof cap->driver);
if (gspca_dev->dev->product != NULL) {
- strncpy(cap->card, gspca_dev->dev->product,
+ strncpy((char *) cap->card, gspca_dev->dev->product,
sizeof cap->card);
} else {
- snprintf(cap->card, sizeof cap->card,
+ snprintf((char *) cap->card, sizeof cap->card,
"USB Camera (%04x:%04x)",
le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
}
- usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
+ usb_make_path(gspca_dev->dev, (char *) cap->bus_info,
+ sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
@@ -1710,12 +1710,13 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
- if (gspca_dev->present)
- ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
- parm);
- else
+ if (gspca_dev->present) {
+ gspca_dev->usb_err = 0;
+ gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+ ret = gspca_dev->usb_err;
+ } else {
ret = -ENODEV;
+ }
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1740,12 +1741,13 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
- if (gspca_dev->present)
- ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
- parm);
- else
+ if (gspca_dev->present) {
+ gspca_dev->usb_err = 0;
+ gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+ ret = gspca_dev->usb_err;
+ } else {
ret = -ENODEV;
+ }
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index d4d210b56b49..97b77a26a2eb 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -62,7 +62,7 @@ struct gspca_ctrl {
/* device information - set at probe time */
struct cam {
const struct v4l2_pix_format *cam_mode; /* size nmodes */
- const struct framerates *mode_framerates; /* must have size nmode,
+ const struct framerates *mode_framerates; /* must have size nmodes,
* just like cam_mode */
struct gspca_ctrl *ctrls; /* control table - size nctrls */
/* may be NULL */
@@ -93,7 +93,7 @@ typedef int (*cam_reg_op) (struct gspca_dev *,
struct v4l2_dbg_register *);
typedef int (*cam_ident_op) (struct gspca_dev *,
struct v4l2_dbg_chip_ident *);
-typedef int (*cam_streamparm_op) (struct gspca_dev *,
+typedef void (*cam_streamparm_op) (struct gspca_dev *,
struct v4l2_streamparm *);
typedef int (*cam_qmnu_op) (struct gspca_dev *,
struct v4l2_querymenu *);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 8ded8b100576..703d48670a24 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -624,7 +624,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
/* Mask away all uninteresting bits */
i2c_data = ((val & 0x0300) >> 2) |
- (i2c_data & 0x3F);
+ (i2c_data & 0x3f);
err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
if (err < 0)
return err;
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 6cf6855aa506..e1c3b9328ace 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -75,14 +75,14 @@ struct sd {
struct gspca_ctrl ctrls[NCTRL];
- __u8 packet_nr;
+ u8 packet_nr;
char bridge;
#define BRIDGE_OV511 0
#define BRIDGE_OV511PLUS 1
#define BRIDGE_OV518 2
#define BRIDGE_OV518PLUS 3
-#define BRIDGE_OV519 4
+#define BRIDGE_OV519 4 /* = ov530 */
#define BRIDGE_OVFX2 5
#define BRIDGE_W9968CF 6
#define BRIDGE_MASK 7
@@ -94,42 +94,44 @@ struct sd {
char snapshot_needs_reset;
/* Determined by sensor type */
- __u8 sif;
+ u8 sif;
- __u8 quality;
+ u8 quality;
#define QUALITY_MIN 50
#define QUALITY_MAX 70
#define QUALITY_DEF 50
- __u8 stopped; /* Streaming is temporarily paused */
- __u8 first_frame;
-
- __u8 frame_rate; /* current Framerate */
- __u8 clockdiv; /* clockdiv override */
-
- char sensor; /* Type of image sensor chip (SEN_*) */
-#define SEN_UNKNOWN 0
-#define SEN_OV2610 1
-#define SEN_OV3610 2
-#define SEN_OV6620 3
-#define SEN_OV6630 4
-#define SEN_OV66308AF 5
-#define SEN_OV7610 6
-#define SEN_OV7620 7
-#define SEN_OV7620AE 8
-#define SEN_OV7640 9
-#define SEN_OV7648 10
-#define SEN_OV7670 11
-#define SEN_OV76BE 12
-#define SEN_OV8610 13
+ u8 stopped; /* Streaming is temporarily paused */
+ u8 first_frame;
+
+ u8 frame_rate; /* current Framerate */
+ u8 clockdiv; /* clockdiv override */
+
+ s8 sensor; /* Type of image sensor chip (SEN_*) */
u8 sensor_addr;
- int sensor_width;
- int sensor_height;
- int sensor_reg_cache[256];
+ u16 sensor_width;
+ u16 sensor_height;
+ s16 sensor_reg_cache[256];
u8 jpeg_hdr[JPEG_HDR_SZ];
};
+enum sensors {
+ SEN_OV2610,
+ SEN_OV3610,
+ SEN_OV6620,
+ SEN_OV6630,
+ SEN_OV66308AF,
+ SEN_OV7610,
+ SEN_OV7620,
+ SEN_OV7620AE,
+ SEN_OV7640,
+ SEN_OV7648,
+ SEN_OV7660,
+ SEN_OV7670,
+ SEN_OV76BE,
+ SEN_OV8610,
+};
/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
the ov sensors which is already present here. When we have the time we
@@ -182,7 +184,7 @@ static const struct ctrl sd_ctrls[] = {
},
.set_control = setcolors,
},
-/* The flip controls work with ov7670 only */
+/* The flip controls work for sensors ov7660 and ov7670 only */
[HFLIP] = {
{
.id = V4L2_CID_HFLIP,
@@ -225,7 +227,7 @@ static const struct ctrl sd_ctrls[] = {
.type = V4L2_CTRL_TYPE_MENU,
.name = "Light frequency filter",
.minimum = 0,
- .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
+ .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
.step = 1,
.default_value = 0,
},
@@ -233,6 +235,53 @@ static const struct ctrl sd_ctrls[] = {
},
};
+/* table of the disabled controls */
+static const unsigned ctrl_dis[] = {
+[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */
+
+[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
+
+[SEN_OV6620] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV6630] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV66308AF] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7610] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7620] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7620AE] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7640] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << AUTOBRIGHT) |
+ (1 << CONTRAST),
+
+[SEN_OV7648] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << AUTOBRIGHT) |
+ (1 << CONTRAST),
+
+[SEN_OV7660] = (1 << AUTOBRIGHT),
+
+[SEN_OV7670] = (1 << COLORS) |
+ (1 << AUTOBRIGHT),
+
+[SEN_OV76BE] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV8610] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << FREQ),
+};
+
static const struct v4l2_pix_format ov519_vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
@@ -412,7 +461,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
.priv = 0},
};
-
/* Registers common to OV511 / OV518 */
#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
#define R51x_SYS_RESET 0x50
@@ -420,7 +468,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV511_RESET_OMNICE 0x08
#define R51x_SYS_INIT 0x53
#define R51x_SYS_SNAP 0x52
-#define R51x_SYS_CUST_ID 0x5F
+#define R51x_SYS_CUST_ID 0x5f
#define R51x_COMP_LUT_BEGIN 0x80
/* OV511 Camera interface register numbers */
@@ -435,13 +483,13 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define R511_CAM_OPTS 0x18
#define R511_SNAP_FRAME 0x19
-#define R511_SNAP_PXCNT 0x1A
-#define R511_SNAP_LNCNT 0x1B
-#define R511_SNAP_PXDIV 0x1C
-#define R511_SNAP_LNDIV 0x1D
-#define R511_SNAP_UV_EN 0x1E
-#define R511_SNAP_UV_EN 0x1E
-#define R511_SNAP_OPTS 0x1F
+#define R511_SNAP_PXCNT 0x1a
+#define R511_SNAP_LNCNT 0x1b
+#define R511_SNAP_PXDIV 0x1c
+#define R511_SNAP_LNDIV 0x1d
+#define R511_SNAP_UV_EN 0x1e
+#define R511_SNAP_UV_EN 0x1e
+#define R511_SNAP_OPTS 0x1f
#define R511_DRAM_FLOW_CTL 0x20
#define R511_FIFO_OPTS 0x31
@@ -466,13 +514,14 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV519_R25_FORMAT 0x25
/* OV519 System Controller register numbers */
-#define OV519_SYS_RESET1 0x51
-#define OV519_SYS_EN_CLK1 0x54
+#define OV519_R51_RESET1 0x51
+#define OV519_R54_EN_CLK1 0x54
+#define OV519_R57_SNAPSHOT 0x57
#define OV519_GPIO_DATA_OUT0 0x71
#define OV519_GPIO_IO_CTRL0 0x72
-#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
+/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
/*
* The FX2 chip does not give us a zero length read at end of frame.
@@ -526,80 +575,81 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
#define OV7610_REG_COM_I 0x29 /* misc settings */
-/* OV7670 registers */
-#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
-#define OV7670_REG_BLUE 0x01 /* blue gain */
-#define OV7670_REG_RED 0x02 /* red gain */
-#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
-#define OV7670_REG_COM1 0x04 /* Control 1 */
-#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
-#define OV7670_REG_COM3 0x0c /* Control 3 */
-#define OV7670_REG_COM4 0x0d /* Control 4 */
-#define OV7670_REG_COM5 0x0e /* All "reserved" */
-#define OV7670_REG_COM6 0x0f /* Control 6 */
-#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
-#define OV7670_REG_CLKRC 0x11 /* Clock control */
-#define OV7670_REG_COM7 0x12 /* Control 7 */
-#define OV7670_COM7_FMT_VGA 0x00
-#define OV7670_COM7_YUV 0x00 /* YUV */
-#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
-#define OV7670_COM7_FMT_MASK 0x38
-#define OV7670_COM7_RESET 0x80 /* Register reset */
-#define OV7670_REG_COM8 0x13 /* Control 8 */
-#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
-#define OV7670_COM8_AWB 0x02 /* White balance enable */
-#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
-#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
-#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
-#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
-#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
-#define OV7670_REG_COM10 0x15 /* Control 10 */
-#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
-#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
-#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
-#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
-#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
-#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
-#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
-#define OV7670_REG_AEW 0x24 /* AGC upper limit */
-#define OV7670_REG_AEB 0x25 /* AGC lower limit */
-#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
-#define OV7670_REG_HREF 0x32 /* HREF pieces */
-#define OV7670_REG_TSLB 0x3a /* lots of stuff */
-#define OV7670_REG_COM11 0x3b /* Control 11 */
-#define OV7670_COM11_EXP 0x02
-#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
-#define OV7670_REG_COM12 0x3c /* Control 12 */
-#define OV7670_REG_COM13 0x3d /* Control 13 */
-#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
-#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
-#define OV7670_REG_COM14 0x3e /* Control 14 */
-#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
-#define OV7670_REG_COM15 0x40 /* Control 15 */
-#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
-#define OV7670_REG_COM16 0x41 /* Control 16 */
-#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
-#define OV7670_REG_BRIGHT 0x55 /* Brightness */
-#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
-#define OV7670_REG_GFIX 0x69 /* Fix gain control */
-#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
-#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
-#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
-#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
-#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
-#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
-#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
-#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
-#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
-#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
+/* OV7660 and OV7670 registers */
+#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
+#define OV7670_R01_BLUE 0x01 /* blue gain */
+#define OV7670_R02_RED 0x02 /* red gain */
+#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
+#define OV7670_R04_COM1 0x04 /* Control 1 */
+/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
+#define OV7670_R0C_COM3 0x0c /* Control 3 */
+#define OV7670_R0D_COM4 0x0d /* Control 4 */
+#define OV7670_R0E_COM5 0x0e /* All "reserved" */
+#define OV7670_R0F_COM6 0x0f /* Control 6 */
+#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
+#define OV7670_R11_CLKRC 0x11 /* Clock control */
+#define OV7670_R12_COM7 0x12 /* Control 7 */
+#define OV7670_COM7_FMT_VGA 0x00
+/*#define OV7670_COM7_YUV 0x00 * YUV */
+#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
+#define OV7670_COM7_FMT_MASK 0x38
+#define OV7670_COM7_RESET 0x80 /* Register reset */
+#define OV7670_R13_COM8 0x13 /* Control 8 */
+#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
+#define OV7670_COM8_AWB 0x02 /* White balance enable */
+#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
+#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
+#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
+#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
+#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
+#define OV7670_R15_COM10 0x15 /* Control 10 */
+#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
+#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
+#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
+#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
+#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
+#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
+#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
+#define OV7670_R24_AEW 0x24 /* AGC upper limit */
+#define OV7670_R25_AEB 0x25 /* AGC lower limit */
+#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
+#define OV7670_R32_HREF 0x32 /* HREF pieces */
+#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
+#define OV7670_R3B_COM11 0x3b /* Control 11 */
+#define OV7670_COM11_EXP 0x02
+#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
+#define OV7670_R3C_COM12 0x3c /* Control 12 */
+#define OV7670_R3D_COM13 0x3d /* Control 13 */
+#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
+#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
+#define OV7670_R3E_COM14 0x3e /* Control 14 */
+#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
+#define OV7670_R40_COM15 0x40 /* Control 15 */
+/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
+#define OV7670_R41_COM16 0x41 /* Control 16 */
+#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
+/* end of ov7660 common registers */
+#define OV7670_R55_BRIGHT 0x55 /* Brightness */
+#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
+#define OV7670_R69_GFIX 0x69 /* Fix gain control */
+/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
+#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
+#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
+#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
+#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
+#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
+#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
+#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
+#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
+#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
struct ov_regvals {
- __u8 reg;
- __u8 val;
+ u8 reg;
+ u8 val;
};
struct ov_i2c_regvals {
- __u8 reg;
- __u8 val;
+ u8 reg;
+ u8 val;
};
/* Settings for OV2610 camera chip */
@@ -617,7 +667,6 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* "wait 4096 external clock ... to make sure the sensor is
* stable and ready to access registers" i.e. 160us at 24MHz
*/
-
{ 0x12, 0x80 }, /* COMH reset */
{ 0x12, 0x00 }, /* QXGA, master */
@@ -650,7 +699,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMI[0] "Exposure control"
* = 0 (0x00) .......0 "Manual"
*/
- { 0x13, 0xC0 },
+ { 0x13, 0xc0 },
/*
* 09 COMC "Common Control C"
@@ -706,7 +755,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COME[0] "Auto zero circuit select"
* = 1 (0x01) .......1 "On"
*/
- { 0x0d, 0xA1 },
+ { 0x0d, 0xa1 },
/*
* 0E COMF "Common Control F"
@@ -770,7 +819,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMJ[0] "Reserved"
* = 0 (0x00) .......0
*/
- { 0x14, 0xC6 },
+ { 0x14, 0xc6 },
/*
* 15 COMK "Common Control K"
@@ -876,7 +925,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* FVOPT[7:0] "Range"
* = 31 (0x1F) 00011111
*/
- { 0x3c, 0x1F },
+ { 0x3c, 0x1f },
/*
* 44 Undocumented = 0 (0x00) 00000000
@@ -925,7 +974,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* 48[7:0] "It's a secret"
* = 192 (0xC0) 11000000
*/
- { 0x48, 0xC0 },
+ { 0x48, 0xc0 },
/*
* 49 Undocumented = 25 (0x19) 00011001
@@ -939,18 +988,18 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* 4B[7:0] "It's a secret"
* = 128 (0x80) 10000000
*/
- { 0x4B, 0x80 },
+ { 0x4b, 0x80 },
/*
* 4D Undocumented = 196 (0xC4) 11000100
* 4D[7:0] "It's a secret"
* = 196 (0xC4) 11000100
*/
- { 0x4D, 0xC4 },
+ { 0x4d, 0xc4 },
/*
* 35 VREF "Reference Voltage Control"
- * = 76 (0x4C) 01001100
+ * = 76 (0x4c) 01001100
* VREF[7:5] "Column high reference control"
* = 2 (0x02) 010..... "higher voltage"
* VREF[4:2] "Column low reference control"
@@ -958,21 +1007,21 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* VREF[1:0] "Reserved"
* = 0 (0x00) ......00
*/
- { 0x35, 0x4C },
+ { 0x35, 0x4c },
/*
* 3D Undocumented = 0 (0x00) 00000000
* 3D[7:0] "It's a secret"
* = 0 (0x00) 00000000
*/
- { 0x3D, 0x00 },
+ { 0x3d, 0x00 },
/*
* 3E Undocumented = 0 (0x00) 00000000
* 3E[7:0] "It's a secret"
* = 0 (0x00) 00000000
*/
- { 0x3E, 0x00 },
+ { 0x3e, 0x00 },
/*
* 3B FREFB "Internal Reference Adjustment"
@@ -1012,7 +1061,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* VBLM[3:0] "Sensor current control"
* = 10 (0x0A) ....1010
*/
- { 0x34, 0x5A },
+ { 0x34, 0x5a },
/*
* 3B FREFB "Internal Reference Adjustment"
@@ -1078,7 +1127,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFST[7:0] "Horizontal window start, 8 MSBs"
* = 31 (0x1F) 00011111
*/
- { 0x17, 0x1F },
+ { 0x17, 0x1f },
/*
* 18 HREFEND "Horizontal window end"
@@ -1086,7 +1135,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFEND[7:0] "Horizontal Window End, 8 MSBs"
* = 95 (0x5F) 01011111
*/
- { 0x18, 0x5F },
+ { 0x18, 0x5f },
/*
* 19 VSTRT "Vertical window start"
@@ -1126,7 +1175,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMA[1:0] "Vertical window start line control 2 LSBs"
* = 2 (0x02) ......10
*/
- { 0x03, 0x4A },
+ { 0x03, 0x4a },
/*
* 11 CLKRC "Clock Rate Control"
@@ -1183,7 +1232,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFST[7:0] "Horizontal window start, 8 MSBs"
* = 31 (0x1F) 00011111
*/
- { 0x17, 0x1F },
+ { 0x17, 0x1f },
/*
* 18 HREFEND "Horizontal window end"
@@ -1191,7 +1240,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFEND[7:0] "Horizontal Window End, 8 MSBs"
* = 95 (0x5F) 01011111
*/
- { 0x18, 0x5F },
+ { 0x18, 0x5f },
/*
* 19 VSTRT "Vertical window start"
@@ -1231,7 +1280,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMA[1:0] "Vertical window start line control 2 LSBs"
* = 2 (0x02) ......10
*/
- { 0x03, 0x4A },
+ { 0x03, 0x4a },
/*
* 02 RED "Red Gain Control"
@@ -1241,7 +1290,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* RED[6:0] "Value"
* = 47 (0x2F) .0101111
*/
- { 0x02, 0xAF },
+ { 0x02, 0xaf },
/*
* 2D ADDVSL "VSYNC Pulse Width"
@@ -1249,7 +1298,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* ADDVSL[7:0] "VSYNC pulse width, LSB"
* = 210 (0xD2) 11010010
*/
- { 0x2d, 0xD2 },
+ { 0x2d, 0xd2 },
/*
* 00 GAIN = 24 (0x18) 00011000
@@ -1272,7 +1321,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* BLUE[6:0] "Value"
* = 112 (0x70) .1110000
*/
- { 0x01, 0xF0 },
+ { 0x01, 0xf0 },
/*
* 10 AEC "Automatic Exposure Control"
@@ -1280,14 +1329,14 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* AEC[7:0] "Automatic Exposure Control, 8 MSBs"
* = 10 (0x0A) 00001010
*/
- { 0x10, 0x0A },
-
- { 0xE1, 0x67 },
- { 0xE3, 0x03 },
- { 0xE4, 0x26 },
- { 0xE5, 0x3E },
- { 0xF8, 0x01 },
- { 0xFF, 0x01 },
+ { 0x10, 0x0a },
+
+ { 0xe1, 0x67 },
+ { 0xe3, 0x03 },
+ { 0xe4, 0x26 },
+ { 0xe5, 0x3e },
+ { 0xf8, 0x01 },
+ { 0xff, 0x01 },
};
static const struct ov_i2c_regvals norm_6x20[] = {
@@ -1296,7 +1345,7 @@ static const struct ov_i2c_regvals norm_6x20[] = {
{ 0x03, 0x60 },
{ 0x05, 0x7f }, /* For when autoadjust is off */
{ 0x07, 0xa8 },
- /* The ratio of 0x0c and 0x0d controls the white point */
+ /* The ratio of 0x0c and 0x0d controls the white point */
{ 0x0c, 0x24 },
{ 0x0d, 0x24 },
{ 0x0f, 0x15 }, /* COMS */
@@ -1464,7 +1513,7 @@ static const struct ov_i2c_regvals norm_7620[] = {
{ 0x00, 0x00 }, /* gain */
{ 0x01, 0x80 }, /* blue gain */
{ 0x02, 0x80 }, /* red gain */
- { 0x03, 0xc0 }, /* OV7670_REG_VREF */
+ { 0x03, 0xc0 }, /* OV7670_R03_VREF */
{ 0x06, 0x60 },
{ 0x07, 0x00 },
{ 0x0c, 0x24 },
@@ -1532,33 +1581,177 @@ static const struct ov_i2c_regvals norm_7640[] = {
{ 0x12, 0x14 },
};
+static const struct ov_regvals init_519_ov7660[] = {
+ { 0x5d, 0x03 }, /* Turn off suspend mode */
+ { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
+ { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { 0xa2, 0x20 }, /* a2-a5 are undocumented */
+ { 0xa3, 0x18 },
+ { 0xa4, 0x04 },
+ { 0xa5, 0x28 },
+ { 0x37, 0x00 }, /* SetUsbInit */
+ { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
+ /* Enable both fields, YUV Input, disable defect comp (why?) */
+ { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
+ { 0x21, 0x38 },
+ { 0x22, 0x1d },
+ { 0x17, 0x50 }, /* undocumented */
+ { 0x37, 0x00 }, /* undocumented */
+ { 0x40, 0xff }, /* I2C timeout counter */
+ { 0x46, 0x00 }, /* I2C clock prescaler */
+};
+static const struct ov_i2c_regvals norm_7660[] = {
+ {OV7670_R12_COM7, OV7670_COM7_RESET},
+ {OV7670_R11_CLKRC, 0x81},
+ {0x92, 0x00}, /* DM_LNL */
+ {0x93, 0x00}, /* DM_LNH */
+ {0x9d, 0x4c}, /* BD50ST */
+ {0x9e, 0x3f}, /* BD60ST */
+ {OV7670_R3B_COM11, 0x02},
+ {OV7670_R13_COM8, 0xf5},
+ {OV7670_R10_AECH, 0x00},
+ {OV7670_R00_GAIN, 0x00},
+ {OV7670_R01_BLUE, 0x7c},
+ {OV7670_R02_RED, 0x9d},
+ {OV7670_R12_COM7, 0x00},
+ {OV7670_R04_COM1, 00},
+ {OV7670_R18_HSTOP, 0x01},
+ {OV7670_R17_HSTART, 0x13},
+ {OV7670_R32_HREF, 0x92},
+ {OV7670_R19_VSTART, 0x02},
+ {OV7670_R1A_VSTOP, 0x7a},
+ {OV7670_R03_VREF, 0x00},
+ {OV7670_R0E_COM5, 0x04},
+ {OV7670_R0F_COM6, 0x62},
+ {OV7670_R15_COM10, 0x00},
+ {0x16, 0x02}, /* RSVD */
+ {0x1b, 0x00}, /* PSHFT */
+ {OV7670_R1E_MVFP, 0x01},
+ {0x29, 0x3c}, /* RSVD */
+ {0x33, 0x00}, /* CHLF */
+ {0x34, 0x07}, /* ARBLM */
+ {0x35, 0x84}, /* RSVD */
+ {0x36, 0x00}, /* RSVD */
+ {0x37, 0x04}, /* ADC */
+ {0x39, 0x43}, /* OFON */
+ {OV7670_R3A_TSLB, 0x00},
+ {OV7670_R3C_COM12, 0x6c},
+ {OV7670_R3D_COM13, 0x98},
+ {OV7670_R3F_EDGE, 0x23},
+ {OV7670_R40_COM15, 0xc1},
+ {OV7670_R41_COM16, 0x22},
+ {0x6b, 0x0a}, /* DBLV */
+ {0xa1, 0x08}, /* RSVD */
+ {0x69, 0x80}, /* HV */
+ {0x43, 0xf0}, /* RSVD.. */
+ {0x44, 0x10},
+ {0x45, 0x78},
+ {0x46, 0xa8},
+ {0x47, 0x60},
+ {0x48, 0x80},
+ {0x59, 0xba},
+ {0x5a, 0x9a},
+ {0x5b, 0x22},
+ {0x5c, 0xb9},
+ {0x5d, 0x9b},
+ {0x5e, 0x10},
+ {0x5f, 0xe0},
+ {0x60, 0x85},
+ {0x61, 0x60},
+ {0x9f, 0x9d}, /* RSVD */
+ {0xa0, 0xa0}, /* DSPC2 */
+ {0x4f, 0x60}, /* matrix */
+ {0x50, 0x64},
+ {0x51, 0x04},
+ {0x52, 0x18},
+ {0x53, 0x3c},
+ {0x54, 0x54},
+ {0x55, 0x40},
+ {0x56, 0x40},
+ {0x57, 0x40},
+ {0x58, 0x0d}, /* matrix sign */
+ {0x8b, 0xcc}, /* RSVD */
+ {0x8c, 0xcc},
+ {0x8d, 0xcf},
+ {0x6c, 0x40}, /* gamma curve */
+ {0x6d, 0xe0},
+ {0x6e, 0xa0},
+ {0x6f, 0x80},
+ {0x70, 0x70},
+ {0x71, 0x80},
+ {0x72, 0x60},
+ {0x73, 0x60},
+ {0x74, 0x50},
+ {0x75, 0x40},
+ {0x76, 0x38},
+ {0x77, 0x3c},
+ {0x78, 0x32},
+ {0x79, 0x1a},
+ {0x7a, 0x28},
+ {0x7b, 0x24},
+ {0x7c, 0x04}, /* gamma curve */
+ {0x7d, 0x12},
+ {0x7e, 0x26},
+ {0x7f, 0x46},
+ {0x80, 0x54},
+ {0x81, 0x64},
+ {0x82, 0x70},
+ {0x83, 0x7c},
+ {0x84, 0x86},
+ {0x85, 0x8e},
+ {0x86, 0x9c},
+ {0x87, 0xab},
+ {0x88, 0xc4},
+ {0x89, 0xd1},
+ {0x8a, 0xe5},
+ {OV7670_R14_COM9, 0x1e},
+ {OV7670_R24_AEW, 0x80},
+ {OV7670_R25_AEB, 0x72},
+ {OV7670_R26_VPT, 0xb3},
+ {0x62, 0x80}, /* LCC1 */
+ {0x63, 0x80}, /* LCC2 */
+ {0x64, 0x06}, /* LCC3 */
+ {0x65, 0x00}, /* LCC4 */
+ {0x66, 0x01}, /* LCC5 */
+ {0x94, 0x0e}, /* RSVD.. */
+ {0x95, 0x14},
+ {OV7670_R13_COM8, OV7670_COM8_FASTAEC
+ | OV7670_COM8_AECSTEP
+ | OV7670_COM8_BFILT
+ | 0x10
+ | OV7670_COM8_AGC
+ | OV7670_COM8_AWB
+ | OV7670_COM8_AEC},
+ {0xa1, 0xc8}
+};
+
/* 7670. Defaults taken from OmniVision provided data,
* as provided by Jonathan Corbet of OLPC */
static const struct ov_i2c_regvals norm_7670[] = {
- { OV7670_REG_COM7, OV7670_COM7_RESET },
- { OV7670_REG_TSLB, 0x04 }, /* OV */
- { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
- { OV7670_REG_CLKRC, 0x01 },
+ { OV7670_R12_COM7, OV7670_COM7_RESET },
+ { OV7670_R3A_TSLB, 0x04 }, /* OV */
+ { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
+ { OV7670_R11_CLKRC, 0x01 },
/*
* Set the hardware window. These values from OV don't entirely
* make sense - hstop is less than hstart. But they work...
*/
- { OV7670_REG_HSTART, 0x13 },
- { OV7670_REG_HSTOP, 0x01 },
- { OV7670_REG_HREF, 0xb6 },
- { OV7670_REG_VSTART, 0x02 },
- { OV7670_REG_VSTOP, 0x7a },
- { OV7670_REG_VREF, 0x0a },
-
- { OV7670_REG_COM3, 0x00 },
- { OV7670_REG_COM14, 0x00 },
+ { OV7670_R17_HSTART, 0x13 },
+ { OV7670_R18_HSTOP, 0x01 },
+ { OV7670_R32_HREF, 0xb6 },
+ { OV7670_R19_VSTART, 0x02 },
+ { OV7670_R1A_VSTOP, 0x7a },
+ { OV7670_R03_VREF, 0x0a },
+
+ { OV7670_R0C_COM3, 0x00 },
+ { OV7670_R3E_COM14, 0x00 },
/* Mystery scaling numbers */
{ 0x70, 0x3a },
{ 0x71, 0x35 },
{ 0x72, 0x11 },
{ 0x73, 0xf0 },
{ 0xa2, 0x02 },
-/* { OV7670_REG_COM10, 0x0 }, */
+/* { OV7670_R15_COM10, 0x0 }, */
/* Gamma curve values */
{ 0x7a, 0x20 },
@@ -1580,37 +1773,37 @@ static const struct ov_i2c_regvals norm_7670[] = {
/* AGC and AEC parameters. Note we start by disabling those features,
then turn them only after tweaking the values. */
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT },
- { OV7670_REG_GAIN, 0x00 },
- { OV7670_REG_AECH, 0x00 },
- { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
- { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
- { OV7670_REG_BD50MAX, 0x05 },
- { OV7670_REG_BD60MAX, 0x07 },
- { OV7670_REG_AEW, 0x95 },
- { OV7670_REG_AEB, 0x33 },
- { OV7670_REG_VPT, 0xe3 },
- { OV7670_REG_HAECC1, 0x78 },
- { OV7670_REG_HAECC2, 0x68 },
+ { OV7670_R00_GAIN, 0x00 },
+ { OV7670_R10_AECH, 0x00 },
+ { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
+ { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
+ { OV7670_RA5_BD50MAX, 0x05 },
+ { OV7670_RAB_BD60MAX, 0x07 },
+ { OV7670_R24_AEW, 0x95 },
+ { OV7670_R25_AEB, 0x33 },
+ { OV7670_R26_VPT, 0xe3 },
+ { OV7670_R9F_HAECC1, 0x78 },
+ { OV7670_RA0_HAECC2, 0x68 },
{ 0xa1, 0x03 }, /* magic */
- { OV7670_REG_HAECC3, 0xd8 },
- { OV7670_REG_HAECC4, 0xd8 },
- { OV7670_REG_HAECC5, 0xf0 },
- { OV7670_REG_HAECC6, 0x90 },
- { OV7670_REG_HAECC7, 0x94 },
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_RA6_HAECC3, 0xd8 },
+ { OV7670_RA7_HAECC4, 0xd8 },
+ { OV7670_RA8_HAECC5, 0xf0 },
+ { OV7670_RA9_HAECC6, 0x90 },
+ { OV7670_RAA_HAECC7, 0x94 },
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT
| OV7670_COM8_AGC
| OV7670_COM8_AEC },
/* Almost all of these are magic "reserved" values. */
- { OV7670_REG_COM5, 0x61 },
- { OV7670_REG_COM6, 0x4b },
+ { OV7670_R0E_COM5, 0x61 },
+ { OV7670_R0F_COM6, 0x4b },
{ 0x16, 0x02 },
- { OV7670_REG_MVFP, 0x07 },
+ { OV7670_R1E_MVFP, 0x07 },
{ 0x21, 0x02 },
{ 0x22, 0x91 },
{ 0x29, 0x07 },
@@ -1619,10 +1812,10 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x37, 0x1d },
{ 0x38, 0x71 },
{ 0x39, 0x2a },
- { OV7670_REG_COM12, 0x78 },
+ { OV7670_R3C_COM12, 0x78 },
{ 0x4d, 0x40 },
{ 0x4e, 0x20 },
- { OV7670_REG_GFIX, 0x00 },
+ { OV7670_R69_GFIX, 0x00 },
{ 0x6b, 0x4a },
{ 0x74, 0x10 },
{ 0x8d, 0x4f },
@@ -1657,9 +1850,9 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x6f, 0x9f },
/* "9e for advance AWB" */
{ 0x6a, 0x40 },
- { OV7670_REG_BLUE, 0x40 },
- { OV7670_REG_RED, 0x60 },
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_R01_BLUE, 0x40 },
+ { OV7670_R02_RED, 0x60 },
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT
| OV7670_COM8_AGC
@@ -1675,22 +1868,22 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x54, 0x80 },
{ 0x58, 0x9e },
- { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
- { OV7670_REG_EDGE, 0x00 },
+ { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
+ { OV7670_R3F_EDGE, 0x00 },
{ 0x75, 0x05 },
{ 0x76, 0xe1 },
{ 0x4c, 0x00 },
{ 0x77, 0x01 },
- { OV7670_REG_COM13, OV7670_COM13_GAMMA
+ { OV7670_R3D_COM13, OV7670_COM13_GAMMA
| OV7670_COM13_UVSAT
| 2}, /* was 3 */
{ 0x4b, 0x09 },
{ 0xc9, 0x60 },
- { OV7670_REG_COM16, 0x38 },
+ { OV7670_R41_COM16, 0x38 },
{ 0x56, 0x40 },
{ 0x34, 0x11 },
- { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
+ { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
{ 0xa4, 0x88 },
{ 0x96, 0x00 },
{ 0x97, 0x30 },
@@ -1825,10 +2018,13 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
}
/* Write a OV519 register */
-static int reg_w(struct sd *sd, __u16 index, __u16 value)
+static void reg_w(struct sd *sd, u16 index, u16 value)
{
int ret, req = 0;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
@@ -1838,6 +2034,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
req = 0x0a;
/* fall through */
case BRIDGE_W9968CF:
+ PDEBUG(D_USBO, "SET %02x %04x %04x",
+ req, value, index);
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
req,
@@ -1848,6 +2046,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
req = 1;
}
+ PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
+ req, index, value);
sd->gspca_dev.usb_buf[0] = value;
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -1857,22 +2057,22 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
sd->gspca_dev.usb_buf, 1, 500);
leave:
if (ret < 0) {
- err("Write reg 0x%04x -> [0x%02x] failed",
- value, index);
- return ret;
+ err("reg_w %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ return;
}
-
- PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
- return 0;
}
/* Read from a OV519 register, note not valid for the w9968cf!! */
/* returns: negative is error, pos or zero is data */
-static int reg_r(struct sd *sd, __u16 index)
+static int reg_r(struct sd *sd, u16 index)
{
int ret;
int req;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
@@ -1893,29 +2093,37 @@ static int reg_r(struct sd *sd, __u16 index)
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
- } else
- err("Read reg [0x%02x] failed", index);
+ PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
+ req, index, ret);
+ } else {
+ err("reg_r %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
/* Read 8 values from a OV519 register */
static int reg_r8(struct sd *sd,
- __u16 index)
+ u16 index)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, sd->gspca_dev.usb_buf, 8, 500);
- if (ret >= 0)
+ if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- else
- err("Read reg 8 [0x%02x] failed", index);
+ } else {
+ err("reg_r8 %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
@@ -1926,34 +2134,37 @@ static int reg_r8(struct sd *sd,
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
-static int reg_w_mask(struct sd *sd,
- __u16 index,
- __u8 value,
- __u8 mask)
+static void reg_w_mask(struct sd *sd,
+ u16 index,
+ u8 value,
+ u8 mask)
{
int ret;
- __u8 oldval;
+ u8 oldval;
if (mask != 0xff) {
value &= mask; /* Enforce mask on value */
ret = reg_r(sd, index);
if (ret < 0)
- return ret;
+ return;
oldval = ret & ~mask; /* Clear the masked bits */
value |= oldval; /* Set the desired bits */
}
- return reg_w(sd, index, value);
+ reg_w(sd, index, value);
}
/*
* Writes multiple (n) byte value to a single register. Only valid with certain
* registers (0x30 and 0xc4 - 0xce).
*/
-static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
+static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
*((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1963,69 +2174,55 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
0, index,
sd->gspca_dev.usb_buf, n, 500);
if (ret < 0) {
- err("Write reg32 [%02x] %08x failed", index, value);
- return ret;
+ err("reg_w32 %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
-static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
{
int rc, retries;
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+ PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
/* Three byte write cycle */
for (retries = 6; ; ) {
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_3, reg);
/* Write "value" to I2C data port of OV511 */
- rc = reg_w(sd, R51x_I2C_DATA, value);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_DATA, value);
/* Initiate 3-byte write cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x01);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x01);
do {
rc = reg_r(sd, R511_I2C_CTL);
} while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
if (rc < 0)
- return rc;
+ return;
if ((rc & 2) == 0) /* Ack? */
break;
if (--retries < 0) {
PDEBUG(D_USBO, "i2c write retries exhausted");
- return -1;
+ return;
}
}
-
- return 0;
}
-static int ov511_i2c_r(struct sd *sd, __u8 reg)
+static int ov511_i2c_r(struct sd *sd, u8 reg)
{
int rc, value, retries;
/* Two byte write cycle */
for (retries = 6; ; ) {
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_2, reg);
/* Initiate 2-byte write cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x03);
do {
rc = reg_r(sd, R511_I2C_CTL);
@@ -2049,9 +2246,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
/* Two byte read cycle */
for (retries = 6; ; ) {
/* Initiate 2-byte read cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x05);
do {
rc = reg_r(sd, R511_I2C_CTL);
@@ -2064,9 +2259,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
break;
/* I2C abort */
- rc = reg_w(sd, R511_I2C_CTL, 0x10);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x10);
if (--retries < 0) {
PDEBUG(D_USBI, "i2c read retries exhausted");
@@ -2076,12 +2269,10 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
/* This is needed to make i2c_w() work */
- rc = reg_w(sd, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x05);
return value;
}
@@ -2091,32 +2282,24 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
* This is normally only called from i2c_w(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
-static int ov518_i2c_w(struct sd *sd,
- __u8 reg,
- __u8 value)
+static void ov518_i2c_w(struct sd *sd,
+ u8 reg,
+ u8 value)
{
- int rc;
-
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+ PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_3, reg);
/* Write "value" to I2C data port of OV511 */
- rc = reg_w(sd, R51x_I2C_DATA, value);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_DATA, value);
/* Initiate 3-byte write cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x01);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x01);
/* wait for write complete */
msleep(4);
- return reg_r8(sd, R518_I2C_CTL);
+ reg_r8(sd, R518_I2C_CTL);
}
/*
@@ -2126,105 +2309,102 @@ static int ov518_i2c_w(struct sd *sd,
* This is normally only called from i2c_r(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
-static int ov518_i2c_r(struct sd *sd, __u8 reg)
+static int ov518_i2c_r(struct sd *sd, u8 reg)
{
- int rc, value;
+ int value;
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_2, reg);
/* Initiate 2-byte write cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x03);
/* Initiate 2-byte read cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x05);
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
return value;
}
-static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16)value, (__u16)reg, NULL, 0, 500);
+ (u16) value, (u16) reg, NULL, 0, 500);
if (ret < 0) {
- err("i2c 0x%02x -> [0x%02x] failed", value, reg);
- return ret;
+ err("ovfx2_i2c_w %02x failed %d", reg, ret);
+ sd->gspca_dev.usb_err = ret;
}
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
- return 0;
+ PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
}
-static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
+static int ovfx2_i2c_r(struct sd *sd, u8 reg)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
+ 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
- } else
- err("i2c read [0x%02x] failed", reg);
+ PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
+ } else {
+ err("ovfx2_i2c_r %02x failed %d", reg, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
-static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void i2c_w(struct sd *sd, u8 reg, u8 value)
{
- int ret = -1;
-
if (sd->sensor_reg_cache[reg] == value)
- return 0;
+ return;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_i2c_w(sd, reg, value);
+ ov511_i2c_w(sd, reg, value);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
case BRIDGE_OV519:
- ret = ov518_i2c_w(sd, reg, value);
+ ov518_i2c_w(sd, reg, value);
break;
case BRIDGE_OVFX2:
- ret = ovfx2_i2c_w(sd, reg, value);
+ ovfx2_i2c_w(sd, reg, value);
break;
case BRIDGE_W9968CF:
- ret = w9968cf_i2c_w(sd, reg, value);
+ w9968cf_i2c_w(sd, reg, value);
break;
}
- if (ret >= 0) {
+ if (sd->gspca_dev.usb_err >= 0) {
/* Up on sensor reset empty the register cache */
if (reg == 0x12 && (value & 0x80))
memset(sd->sensor_reg_cache, -1,
- sizeof(sd->sensor_reg_cache));
+ sizeof(sd->sensor_reg_cache));
else
sd->sensor_reg_cache[reg] = value;
}
-
- return ret;
}
-static int i2c_r(struct sd *sd, __u8 reg)
+static int i2c_r(struct sd *sd, u8 reg)
{
int ret = -1;
@@ -2260,95 +2440,99 @@ static int i2c_r(struct sd *sd, __u8 reg)
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
-static int i2c_w_mask(struct sd *sd,
- __u8 reg,
- __u8 value,
- __u8 mask)
+static void i2c_w_mask(struct sd *sd,
+ u8 reg,
+ u8 value,
+ u8 mask)
{
int rc;
- __u8 oldval;
+ u8 oldval;
value &= mask; /* Enforce mask on value */
rc = i2c_r(sd, reg);
if (rc < 0)
- return rc;
+ return;
oldval = rc & ~mask; /* Clear the masked bits */
value |= oldval; /* Set the desired bits */
- return i2c_w(sd, reg, value);
+ i2c_w(sd, reg, value);
}
/* Temporarily stops OV511 from functioning. Must do this before changing
* registers while the camera is streaming */
-static inline int ov51x_stop(struct sd *sd)
+static inline void ov51x_stop(struct sd *sd)
{
PDEBUG(D_STREAM, "stopping");
sd->stopped = 1;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- return reg_w(sd, R51x_SYS_RESET, 0x3d);
+ reg_w(sd, R51x_SYS_RESET, 0x3d);
+ break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+ reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+ break;
case BRIDGE_OV519:
- return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x00);
+ reg_w(sd, 0x22, 0x00); /* FRAR */
+ break;
case BRIDGE_OVFX2:
- return reg_w_mask(sd, 0x0f, 0x00, 0x02);
+ reg_w_mask(sd, 0x0f, 0x00, 0x02);
+ break;
case BRIDGE_W9968CF:
- return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+ reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+ break;
}
-
- return 0;
}
/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
* actually stopped (for performance). */
-static inline int ov51x_restart(struct sd *sd)
+static inline void ov51x_restart(struct sd *sd)
{
- int rc;
-
PDEBUG(D_STREAM, "restarting");
if (!sd->stopped)
- return 0;
+ return;
sd->stopped = 0;
/* Reinitialize the stream */
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- return reg_w(sd, R51x_SYS_RESET, 0x00);
+ reg_w(sd, R51x_SYS_RESET, 0x00);
+ break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- rc = reg_w(sd, 0x2f, 0x80);
- if (rc < 0)
- return rc;
- return reg_w(sd, R51x_SYS_RESET, 0x00);
+ reg_w(sd, 0x2f, 0x80);
+ reg_w(sd, R51x_SYS_RESET, 0x00);
+ break;
case BRIDGE_OV519:
- return reg_w(sd, OV519_SYS_RESET1, 0x00);
+ reg_w(sd, OV519_R51_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x00);
+ reg_w(sd, 0x22, 0x1d); /* FRAR */
+ break;
case BRIDGE_OVFX2:
- return reg_w_mask(sd, 0x0f, 0x02, 0x02);
+ reg_w_mask(sd, 0x0f, 0x02, 0x02);
+ break;
case BRIDGE_W9968CF:
- return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+ reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+ break;
}
-
- return 0;
}
-static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
+static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
/* This does an initial reset of an OmniVision sensor and ensures that I2C
* is synchronized. Returns <0 on failure.
*/
-static int init_ov_sensor(struct sd *sd, __u8 slave)
+static int init_ov_sensor(struct sd *sd, u8 slave)
{
int i;
- if (ov51x_set_slave_ids(sd, slave) < 0)
- return -EIO;
+ ov51x_set_slave_ids(sd, slave);
/* Reset the sensor */
- if (i2c_w(sd, 0x12, 0x80) < 0)
- return -EIO;
+ i2c_w(sd, 0x12, 0x80);
/* Wait for it to initialize */
msleep(150);
@@ -2361,15 +2545,16 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
}
/* Reset the sensor */
- if (i2c_w(sd, 0x12, 0x80) < 0)
- return -EIO;
+ i2c_w(sd, 0x12, 0x80);
+
/* Wait for it to initialize */
msleep(150);
+
/* Dummy read to sync I2C */
if (i2c_r(sd, 0x00) < 0)
- return -EIO;
+ return -1;
}
- return -EIO;
+ return -1;
}
/* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -2377,53 +2562,40 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
* This should not be called from outside the i2c I/O functions.
* Sets I2C read and write slave IDs. Returns <0 for error
*/
-static int ov51x_set_slave_ids(struct sd *sd,
- __u8 slave)
+static void ov51x_set_slave_ids(struct sd *sd,
+ u8 slave)
{
- int rc;
-
switch (sd->bridge) {
case BRIDGE_OVFX2:
- return reg_w(sd, OVFX2_I2C_ADDR, slave);
+ reg_w(sd, OVFX2_I2C_ADDR, slave);
+ return;
case BRIDGE_W9968CF:
sd->sensor_addr = slave;
- return 0;
+ return;
}
- rc = reg_w(sd, R51x_I2C_W_SID, slave);
- if (rc < 0)
- return rc;
- return reg_w(sd, R51x_I2C_R_SID, slave + 1);
+ reg_w(sd, R51x_I2C_W_SID, slave);
+ reg_w(sd, R51x_I2C_R_SID, slave + 1);
}
-static int write_regvals(struct sd *sd,
+static void write_regvals(struct sd *sd,
const struct ov_regvals *regvals,
int n)
{
- int rc;
-
while (--n >= 0) {
- rc = reg_w(sd, regvals->reg, regvals->val);
- if (rc < 0)
- return rc;
+ reg_w(sd, regvals->reg, regvals->val);
regvals++;
}
- return 0;
}
-static int write_i2c_regvals(struct sd *sd,
- const struct ov_i2c_regvals *regvals,
- int n)
+static void write_i2c_regvals(struct sd *sd,
+ const struct ov_i2c_regvals *regvals,
+ int n)
{
- int rc;
-
while (--n >= 0) {
- rc = i2c_w(sd, regvals->reg, regvals->val);
- if (rc < 0)
- return rc;
+ i2c_w(sd, regvals->reg, regvals->val);
regvals++;
}
- return 0;
}
/****************************************************************************
@@ -2433,13 +2605,13 @@ static int write_i2c_regvals(struct sd *sd,
***************************************************************************/
/* This initializes the OV2x10 / OV3610 / OV3620 */
-static int ov_hires_configure(struct sd *sd)
+static void ov_hires_configure(struct sd *sd)
{
int high, low;
if (sd->bridge != BRIDGE_OVFX2) {
err("error hires sensors only supported with ovfx2");
- return -1;
+ return;
}
PDEBUG(D_PROBE, "starting ov hires configuration");
@@ -2455,20 +2627,15 @@ static int ov_hires_configure(struct sd *sd)
PDEBUG(D_PROBE, "Sensor is an OV3610");
sd->sensor = SEN_OV3610;
} else {
- err("Error unknown sensor type: 0x%02x%02x",
- high, low);
- return -1;
+ err("Error unknown sensor type: %02x%02x",
+ high, low);
}
-
- /* Set sensor-specific vars */
- return 0;
}
-
/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
* the same register settings as the OV8610, since they are very similar.
*/
-static int ov8xx0_configure(struct sd *sd)
+static void ov8xx0_configure(struct sd *sd)
{
int rc;
@@ -2478,27 +2645,21 @@ static int ov8xx0_configure(struct sd *sd)
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
- if ((rc & 3) == 1) {
+ if ((rc & 3) == 1)
sd->sensor = SEN_OV8610;
- } else {
+ else
err("Unknown image sensor version: %d", rc & 3);
- return -1;
- }
-
- /* Set sensor-specific vars */
- return 0;
}
/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
* the same register settings as the OV7610, since they are very similar.
*/
-static int ov7xx0_configure(struct sd *sd)
+static void ov7xx0_configure(struct sd *sd)
{
int rc, high, low;
-
PDEBUG(D_PROBE, "starting OV7xx0 configuration");
/* Detect sensor (sub)type */
@@ -2508,15 +2669,15 @@ static int ov7xx0_configure(struct sd *sd)
* it appears to be wrongly detected as a 7610 by default */
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
if ((rc & 3) == 3) {
/* quick hack to make OV7670s work */
high = i2c_r(sd, 0x0a);
low = i2c_r(sd, 0x0b);
/* info("%x, %x", high, low); */
- if (high == 0x76 && low == 0x73) {
- PDEBUG(D_PROBE, "Sensor is an OV7670");
+ if (high == 0x76 && (low & 0xf0) == 0x70) {
+ PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
sd->sensor = SEN_OV7670;
} else {
PDEBUG(D_PROBE, "Sensor is an OV7610");
@@ -2536,19 +2697,19 @@ static int ov7xx0_configure(struct sd *sd)
high = i2c_r(sd, 0x0a);
if (high < 0) {
PDEBUG(D_ERR, "Error detecting camera chip PID");
- return high;
+ return;
}
low = i2c_r(sd, 0x0b);
if (low < 0) {
PDEBUG(D_ERR, "Error detecting camera chip VER");
- return low;
+ return;
}
if (high == 0x76) {
switch (low) {
case 0x30:
err("Sensor is an OV7630/OV7635");
err("7630 is not supported by this driver");
- return -1;
+ return;
case 0x40:
PDEBUG(D_PROBE, "Sensor is an OV7645");
sd->sensor = SEN_OV7640; /* FIXME */
@@ -2561,9 +2722,14 @@ static int ov7xx0_configure(struct sd *sd)
PDEBUG(D_PROBE, "Sensor is an OV7648");
sd->sensor = SEN_OV7648;
break;
+ case 0x60:
+ PDEBUG(D_PROBE, "Sensor is a OV7660");
+ sd->sensor = SEN_OV7660;
+ sd->invert_led = 0;
+ break;
default:
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
- return -1;
+ return;
}
} else {
PDEBUG(D_PROBE, "Sensor is an OV7620");
@@ -2571,15 +2737,11 @@ static int ov7xx0_configure(struct sd *sd)
}
} else {
err("Unknown image sensor version: %d", rc & 3);
- return -1;
}
-
- /* Set sensor-specific vars */
- return 0;
}
/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
-static int ov6xx0_configure(struct sd *sd)
+static void ov6xx0_configure(struct sd *sd)
{
int rc;
PDEBUG(D_PROBE, "starting OV6xx0 configuration");
@@ -2588,7 +2750,7 @@ static int ov6xx0_configure(struct sd *sd)
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
/* Ugh. The first two bits are the version bits, but
@@ -2619,13 +2781,11 @@ static int ov6xx0_configure(struct sd *sd)
break;
default:
err("FATAL: Unknown sensor version: 0x%02x", rc);
- return -1;
+ return;
}
/* Set sensor-specific vars */
sd->sif = 1;
-
- return 0;
}
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
@@ -2637,14 +2797,14 @@ static void ov51x_led_control(struct sd *sd, int on)
switch (sd->bridge) {
/* OV511 has no LED control */
case BRIDGE_OV511PLUS:
- reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
+ reg_w(sd, R511_SYS_LED_CTL, on);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
+ reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
break;
case BRIDGE_OV519:
- reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
+ reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
break;
}
}
@@ -2679,7 +2839,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
}
}
-static int ov51x_upload_quan_tables(struct sd *sd)
+static void ov51x_upload_quan_tables(struct sd *sd)
{
const unsigned char yQuanTable511[] = {
0, 1, 1, 2, 2, 3, 3, 4,
@@ -2710,7 +2870,6 @@ static int ov51x_upload_quan_tables(struct sd *sd)
6, 6, 6, 6, 7, 7, 7, 8,
7, 7, 6, 7, 7, 7, 8, 8
};
-
const unsigned char uvQuanTable518[] = {
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 7,
@@ -2720,18 +2879,18 @@ static int ov51x_upload_quan_tables(struct sd *sd)
const unsigned char *pYTable, *pUVTable;
unsigned char val0, val1;
- int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
+ int i, size, reg = R51x_COMP_LUT_BEGIN;
PDEBUG(D_PROBE, "Uploading quantization tables");
if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
pYTable = yQuanTable511;
pUVTable = uvQuanTable511;
- size = 32;
+ size = 32;
} else {
pYTable = yQuanTable518;
pUVTable = uvQuanTable518;
- size = 16;
+ size = 16;
}
for (i = 0; i < size; i++) {
@@ -2740,30 +2899,23 @@ static int ov51x_upload_quan_tables(struct sd *sd)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = reg_w(sd, reg, val0);
- if (rc < 0)
- return rc;
+ reg_w(sd, reg, val0);
val0 = *pUVTable++;
val1 = *pUVTable++;
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = reg_w(sd, reg + size, val0);
- if (rc < 0)
- return rc;
+ reg_w(sd, reg + size, val0);
reg++;
}
-
- return 0;
}
/* This initializes the OV511/OV511+ and the sensor */
-static int ov511_configure(struct gspca_dev *gspca_dev)
+static void ov511_configure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int rc;
/* For 511 and 511+ */
const struct ov_regvals init_511[] = {
@@ -2809,42 +2961,27 @@ static int ov511_configure(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
- rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
- if (rc < 0)
- return rc;
+ write_regvals(sd, init_511, ARRAY_SIZE(init_511));
switch (sd->bridge) {
case BRIDGE_OV511:
- rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
break;
case BRIDGE_OV511PLUS:
- rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
break;
}
/* Init compression */
- rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
- if (rc < 0)
- return rc;
-
- rc = ov51x_upload_quan_tables(sd);
- if (rc < 0) {
- PDEBUG(D_ERR, "Error uploading quantization tables");
- return rc;
- }
+ write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
- return 0;
+ ov51x_upload_quan_tables(sd);
}
/* This initializes the OV518/OV518+ and the sensor */
-static int ov518_configure(struct gspca_dev *gspca_dev)
+static void ov518_configure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int rc;
/* For 518 and 518+ */
const struct ov_regvals init_518[] = {
@@ -2892,65 +3029,49 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
/* First 5 bits of custom ID reg are a revision ID on OV518 */
PDEBUG(D_PROBE, "Device revision %d",
- 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
+ 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
- rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
- if (rc < 0)
- return rc;
+ write_regvals(sd, init_518, ARRAY_SIZE(init_518));
/* Set LED GPIO pin to output mode */
- rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
- if (rc < 0)
- return rc;
+ reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
switch (sd->bridge) {
case BRIDGE_OV518:
- rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
break;
case BRIDGE_OV518PLUS:
- rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
break;
}
- rc = ov51x_upload_quan_tables(sd);
- if (rc < 0) {
- PDEBUG(D_ERR, "Error uploading quantization tables");
- return rc;
- }
+ ov51x_upload_quan_tables(sd);
- rc = reg_w(sd, 0x2f, 0x80);
- if (rc < 0)
- return rc;
-
- return 0;
+ reg_w(sd, 0x2f, 0x80);
}
-static int ov519_configure(struct sd *sd)
+static void ov519_configure(struct sd *sd)
{
static const struct ov_regvals init_519[] = {
- { 0x5a, 0x6d }, /* EnableSystem */
- { 0x53, 0x9b },
- { 0x54, 0xff }, /* set bit2 to enable jpeg */
- { 0x5d, 0x03 },
- { 0x49, 0x01 },
- { 0x48, 0x00 },
+ { 0x5a, 0x6d }, /* EnableSystem */
+ { 0x53, 0x9b },
+ { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
+ { 0x5d, 0x03 },
+ { 0x49, 0x01 },
+ { 0x48, 0x00 },
/* Set LED pin to output mode. Bit 4 must be cleared or sensor
* detection will fail. This deserves further investigation. */
{ OV519_GPIO_IO_CTRL0, 0xee },
- { 0x51, 0x0f }, /* SetUsbInit */
- { 0x51, 0x00 },
- { 0x22, 0x00 },
+ { OV519_R51_RESET1, 0x0f },
+ { OV519_R51_RESET1, 0x00 },
+ { 0x22, 0x00 },
/* windows reads 0x55 at this point*/
};
- return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
+ write_regvals(sd, init_519, ARRAY_SIZE(init_519));
}
-static int ovfx2_configure(struct sd *sd)
+static void ovfx2_configure(struct sd *sd)
{
static const struct ov_regvals init_fx2[] = {
{ 0x00, 0x60 },
@@ -2964,7 +3085,92 @@ static int ovfx2_configure(struct sd *sd)
sd->stopped = 1;
- return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+ write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+}
+
+/* set the mode */
+/* This function works for ov7660 only */
+static void ov519_set_mode(struct sd *sd)
+{
+ static const struct ov_regvals bridge_ov7660[2][10] = {
+ {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
+ {0x25, 0x01}, {0x26, 0x00}},
+ {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
+ {0x25, 0x03}, {0x26, 0x00}}
+ };
+ static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
+ {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
+ {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
+ };
+ static const struct ov_i2c_regvals sensor_ov7660_2[] = {
+ {OV7670_R17_HSTART, 0x13},
+ {OV7670_R18_HSTOP, 0x01},
+ {OV7670_R32_HREF, 0x92},
+ {OV7670_R19_VSTART, 0x02},
+ {OV7670_R1A_VSTOP, 0x7a},
+ {OV7670_R03_VREF, 0x00},
+/* {0x33, 0x00}, */
+/* {0x34, 0x07}, */
+/* {0x36, 0x00}, */
+/* {0x6b, 0x0a}, */
+ };
+
+ write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
+ ARRAY_SIZE(bridge_ov7660[0]));
+ write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
+ ARRAY_SIZE(sensor_ov7660[0]));
+ write_i2c_regvals(sd, sensor_ov7660_2,
+ ARRAY_SIZE(sensor_ov7660_2));
+}
+
+/* set the frame rate */
+/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
+static void ov519_set_fr(struct sd *sd)
+{
+ int fr;
+ u8 clock;
+ /* frame rate table with indices:
+ * - mode = 0: 320x240, 1: 640x480
+ * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
+ * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
+ */
+ static const u8 fr_tb[2][6][3] = {
+ {{0x04, 0xff, 0x00},
+ {0x04, 0x1f, 0x00},
+ {0x04, 0x1b, 0x00},
+ {0x04, 0x15, 0x00},
+ {0x04, 0x09, 0x00},
+ {0x04, 0x01, 0x00}},
+ {{0x0c, 0xff, 0x00},
+ {0x0c, 0x1f, 0x00},
+ {0x0c, 0x1b, 0x00},
+ {0x04, 0xff, 0x01},
+ {0x04, 0x1f, 0x01},
+ {0x04, 0x1b, 0x01}},
+ };
+
+ if (frame_rate > 0)
+ sd->frame_rate = frame_rate;
+ if (sd->frame_rate >= 30)
+ fr = 0;
+ else if (sd->frame_rate >= 25)
+ fr = 1;
+ else if (sd->frame_rate >= 20)
+ fr = 2;
+ else if (sd->frame_rate >= 15)
+ fr = 3;
+ else if (sd->frame_rate >= 10)
+ fr = 4;
+ else
+ fr = 5;
+ reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
+ reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
+ clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
+ if (sd->sensor == SEN_OV7660)
+ clock |= 0x80; /* enable double clock */
+ ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
}
/* this function is called at probe time */
@@ -2973,99 +3179,119 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
- int ret = 0;
sd->bridge = id->driver_info & BRIDGE_MASK;
- sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
+ sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_configure(gspca_dev);
+ cam->cam_mode = ov511_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- ret = ov518_configure(gspca_dev);
+ cam->cam_mode = ov518_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
break;
case BRIDGE_OV519:
- ret = ov519_configure(sd);
+ cam->cam_mode = ov519_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+ sd->invert_led = !sd->invert_led;
break;
case BRIDGE_OVFX2:
- ret = ovfx2_configure(sd);
+ cam->cam_mode = ov519_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
cam->bulk_size = OVFX2_BULK_SIZE;
cam->bulk_nurbs = MAX_NURBS;
cam->bulk = 1;
break;
case BRIDGE_W9968CF:
- ret = w9968cf_configure(sd);
+ cam->cam_mode = w9968cf_vga_mode;
+ cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
cam->reverse_alts = 1;
break;
}
- if (ret)
- goto error;
+ gspca_dev->cam.ctrls = sd->ctrls;
+ sd->quality = QUALITY_DEF;
- ov51x_led_control(sd, 0); /* turn LED off */
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam = &gspca_dev->cam;
+
+ switch (sd->bridge) {
+ case BRIDGE_OV511:
+ case BRIDGE_OV511PLUS:
+ ov511_configure(gspca_dev);
+ break;
+ case BRIDGE_OV518:
+ case BRIDGE_OV518PLUS:
+ ov518_configure(gspca_dev);
+ break;
+ case BRIDGE_OV519:
+ ov519_configure(sd);
+ break;
+ case BRIDGE_OVFX2:
+ ovfx2_configure(sd);
+ break;
+ case BRIDGE_W9968CF:
+ w9968cf_configure(sd);
+ break;
+ }
/* The OV519 must be more aggressive about sensor detection since
* I2C write will never fail if the sensor is not present. We have
* to try to initialize the sensor to detect its presence */
+ sd->sensor = -1;
/* Test for 76xx */
if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
- if (ov7xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV7xx0");
- goto error;
- }
+ ov7xx0_configure(sd);
+
/* Test for 6xx0 */
} else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
- if (ov6xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV6xx0");
- goto error;
- }
+ ov6xx0_configure(sd);
+
/* Test for 8xx0 */
} else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
- if (ov8xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV8xx0");
- goto error;
- }
+ ov8xx0_configure(sd);
+
/* Test for 3xxx / 2xxx */
} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
- if (ov_hires_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure high res OV");
- goto error;
- }
+ ov_hires_configure(sd);
} else {
err("Can't determine sensor slave IDs");
goto error;
}
+ if (sd->sensor < 0)
+ goto error;
+
+ ov51x_led_control(sd, 0); /* turn LED off */
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- if (!sd->sif) {
- cam->cam_mode = ov511_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov511_sif_mode;
cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
}
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- if (!sd->sif) {
- cam->cam_mode = ov518_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov518_sif_mode;
cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
}
break;
case BRIDGE_OV519:
- if (!sd->sif) {
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov519_sif_mode;
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
@@ -3077,118 +3303,107 @@ static int sd_config(struct gspca_dev *gspca_dev,
} else if (sd->sensor == SEN_OV3610) {
cam->cam_mode = ovfx2_ov3610_mode;
cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
- } else if (!sd->sif) {
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- } else {
+ } else if (sd->sif) {
cam->cam_mode = ov519_sif_mode;
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
break;
case BRIDGE_W9968CF:
- cam->cam_mode = w9968cf_vga_mode;
- cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
if (sd->sif)
- cam->nmodes--;
+ cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
/* w9968cf needs initialisation once the sensor is known */
- if (w9968cf_init(sd) < 0)
- goto error;
+ w9968cf_init(sd);
break;
}
- gspca_dev->cam.ctrls = sd->ctrls;
- if (sd->sensor == SEN_OV7670)
- gspca_dev->ctrl_dis = 1 << COLORS;
- else
- gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
- sd->quality = QUALITY_DEF;
- if (sd->sensor == SEN_OV7640 ||
- sd->sensor == SEN_OV7648)
- gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST);
- if (sd->sensor == SEN_OV7670)
- gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT;
- /* OV8610 Frequency filter control should work but needs testing */
- if (sd->sensor == SEN_OV8610)
- gspca_dev->ctrl_dis |= 1 << FREQ;
- /* No controls for the OV2610/OV3610 */
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- gspca_dev->ctrl_dis |= (1 << NCTRL) - 1;
- return 0;
-error:
- PDEBUG(D_ERR, "OV519 Config failed");
- return -EBUSY;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
+ gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
/* initialize the sensor */
switch (sd->sensor) {
case SEN_OV2610:
- if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
- return -EIO;
+ write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
+
/* Enable autogain, autoexpo, awb, bandfilter */
- if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
- return -EIO;
+ i2c_w_mask(sd, 0x13, 0x27, 0x27);
break;
case SEN_OV3610:
- if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
- return -EIO;
+ write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
+
/* Enable autogain, autoexpo, awb, bandfilter */
- if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
- return -EIO;
+ i2c_w_mask(sd, 0x13, 0x27, 0x27);
break;
case SEN_OV6620:
- if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
- return -EIO;
+ write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
break;
case SEN_OV6630:
case SEN_OV66308AF:
sd->ctrls[CONTRAST].def = 200;
/* The default is too low for the ov6630 */
- if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
- return -EIO;
+ write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
break;
default:
/* case SEN_OV7610: */
/* case SEN_OV76BE: */
- if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
- return -EIO;
- if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
- return -EIO;
+ write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
+ i2c_w_mask(sd, 0x0e, 0x00, 0x40);
break;
case SEN_OV7620:
case SEN_OV7620AE:
- if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
break;
case SEN_OV7640:
case SEN_OV7648:
- if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
+ break;
+ case SEN_OV7660:
+ i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
+ msleep(14);
+ reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
+ write_regvals(sd, init_519_ov7660,
+ ARRAY_SIZE(init_519_ov7660));
+ write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
+ sd->gspca_dev.curr_mode = 1; /* 640x480 */
+ sd->frame_rate = 15;
+ ov519_set_mode(sd);
+ ov519_set_fr(sd);
+ sd->ctrls[COLORS].max = 4; /* 0..4 */
+ sd->ctrls[COLORS].val =
+ sd->ctrls[COLORS].def = 2;
+ setcolors(gspca_dev);
+ sd->ctrls[CONTRAST].max = 6; /* 0..6 */
+ sd->ctrls[CONTRAST].val =
+ sd->ctrls[CONTRAST].def = 3;
+ setcontrast(gspca_dev);
+ sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
+ sd->ctrls[BRIGHTNESS].val =
+ sd->ctrls[BRIGHTNESS].def = 3;
+ setbrightness(gspca_dev);
+ sd_reset_snapshot(gspca_dev);
+ ov51x_restart(sd);
+ ov51x_stop(sd); /* not in win traces */
+ ov51x_led_control(sd, 0);
break;
case SEN_OV7670:
sd->ctrls[FREQ].max = 3; /* auto */
sd->ctrls[FREQ].def = 3;
- if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
break;
case SEN_OV8610:
- if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
- return -EIO;
+ write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
break;
}
- return 0;
+ return gspca_dev->usb_err;
+error:
+ PDEBUG(D_ERR, "OV519 Config failed");
+ return -EINVAL;
}
/* Set up the OV511/OV511+ with the given image parameters.
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov511_mode_init_regs(struct sd *sd)
+static void ov511_mode_init_regs(struct sd *sd)
{
int hsegs, vsegs, packet_size, fps, needed;
int interlaced = 0;
@@ -3199,7 +3414,8 @@ static int ov511_mode_init_regs(struct sd *sd)
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
err("Couldn't get altsetting");
- return -EIO;
+ sd->gspca_dev.usb_err = -EIO;
+ return;
}
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
@@ -3302,8 +3518,6 @@ static int ov511_mode_init_regs(struct sd *sd)
reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
reg_w(sd, R51x_SYS_RESET, 0);
-
- return 0;
}
/* Sets up the OV518/OV518+ with the given image parameters
@@ -3313,7 +3527,7 @@ static int ov511_mode_init_regs(struct sd *sd)
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov518_mode_init_regs(struct sd *sd)
+static void ov518_mode_init_regs(struct sd *sd)
{
int hsegs, vsegs, packet_size;
struct usb_host_interface *alt;
@@ -3323,14 +3537,14 @@ static int ov518_mode_init_regs(struct sd *sd)
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
err("Couldn't get altsetting");
- return -EIO;
+ sd->gspca_dev.usb_err = -EIO;
+ return;
}
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
/******** Set the mode ********/
-
reg_w(sd, 0x2b, 0);
reg_w(sd, 0x2c, 0);
reg_w(sd, 0x2d, 0);
@@ -3364,7 +3578,7 @@ static int ov518_mode_init_regs(struct sd *sd)
/* Windows driver does this here; who knows why */
reg_w(sd, 0x2f, 0x80);
- /******** Set the framerate ********/
+ /******** Set the framerate ********/
sd->clockdiv = 1;
/* Mode independent, but framerate dependent, regs */
@@ -3427,11 +3641,8 @@ static int ov518_mode_init_regs(struct sd *sd)
}
reg_w(sd, 0x2f, 0x80);
-
- return 0;
}
-
/* Sets up the OV519 with the given image parameters
*
* OV519 needs a completely different approach, until we can figure out what
@@ -3439,12 +3650,12 @@ static int ov518_mode_init_regs(struct sd *sd)
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov519_mode_init_regs(struct sd *sd)
+static void ov519_mode_init_regs(struct sd *sd)
{
static const struct ov_regvals mode_init_519_ov7670[] = {
{ 0x5d, 0x03 }, /* Turn off suspend mode */
{ 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
{ 0xa2, 0x20 }, /* a2-a5 are undocumented */
{ 0xa3, 0x18 },
{ 0xa4, 0x04 },
@@ -3467,7 +3678,7 @@ static int ov519_mode_init_regs(struct sd *sd)
static const struct ov_regvals mode_init_519[] = {
{ 0x5d, 0x03 }, /* Turn off suspend mode */
{ 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
{ 0xa2, 0x20 }, /* a2-a5 are undocumented */
{ 0xa3, 0x18 },
{ 0xa4, 0x04 },
@@ -3486,19 +3697,21 @@ static int ov519_mode_init_regs(struct sd *sd)
};
/******** Set the mode ********/
- if (sd->sensor != SEN_OV7670) {
- if (write_regvals(sd, mode_init_519,
- ARRAY_SIZE(mode_init_519)))
- return -EIO;
+ switch (sd->sensor) {
+ default:
+ write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
if (sd->sensor == SEN_OV7640 ||
sd->sensor == SEN_OV7648) {
/* Select 8-bit input mode */
reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
}
- } else {
- if (write_regvals(sd, mode_init_519_ov7670,
- ARRAY_SIZE(mode_init_519_ov7670)))
- return -EIO;
+ break;
+ case SEN_OV7660:
+ return; /* done by ov519_set_mode/fr() */
+ case SEN_OV7670:
+ write_regvals(sd, mode_init_519_ov7670,
+ ARRAY_SIZE(mode_init_519_ov7670));
+ break;
}
reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
@@ -3594,17 +3807,16 @@ static int ov519_mode_init_regs(struct sd *sd)
}
break;
}
- return 0;
}
-static int mode_init_ov_sensor_regs(struct sd *sd)
+static void mode_init_ov_sensor_regs(struct sd *sd)
{
struct gspca_dev *gspca_dev;
int qvga, xstart, xend, ystart, yend;
- __u8 v;
+ u8 v;
gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
+ qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
/******** Mode (VGA/QVGA) and sensor specific regs ********/
switch (sd->sensor) {
@@ -3616,7 +3828,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
- return 0;
+ return;
case SEN_OV3610:
if (qvga) {
xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3640,7 +3852,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w(sd, 0x18, xend >> 4);
i2c_w(sd, 0x19, ystart >> 3);
i2c_w(sd, 0x1a, yend >> 3);
- return 0;
+ return;
case SEN_OV8610:
/* For OV8610 qvga means qsvga */
i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
@@ -3687,11 +3899,11 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
/* set COM7_FMT_VGA or COM7_FMT_QVGA
* do we need to set anything else?
* HSTART etc are set in set_ov_sensor_window itself */
- i2c_w_mask(sd, OV7670_REG_COM7,
+ i2c_w_mask(sd, OV7670_R12_COM7,
qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
OV7670_COM7_FMT_MASK);
i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
OV7670_COM8_AWB);
if (qvga) { /* QVGA from ov7670.c by
* Jonathan Corbet */
@@ -3707,21 +3919,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
}
/* OV7670 hardware window registers are split across
* multiple locations */
- i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
- i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
- v = i2c_r(sd, OV7670_REG_HREF);
+ i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
+ i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
+ v = i2c_r(sd, OV7670_R32_HREF);
v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
msleep(10); /* need to sleep between read and write to
* same reg! */
- i2c_w(sd, OV7670_REG_HREF, v);
+ i2c_w(sd, OV7670_R32_HREF, v);
- i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
- i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
- v = i2c_r(sd, OV7670_REG_VREF);
+ i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
+ i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
+ v = i2c_r(sd, OV7670_R03_VREF);
v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
msleep(10); /* need to sleep between read and write to
* same reg! */
- i2c_w(sd, OV7670_REG_VREF, v);
+ i2c_w(sd, OV7670_R03_VREF, v);
break;
case SEN_OV6620:
i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -3734,46 +3946,50 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
break;
default:
- return -EINVAL;
+ return;
}
/******** Clock programming ********/
i2c_w(sd, 0x11, sd->clockdiv);
-
- return 0;
}
+/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
static void sethvflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->sensor != SEN_OV7670)
- return;
if (sd->gspca_dev.streaming)
- ov51x_stop(sd);
- i2c_w_mask(sd, OV7670_REG_MVFP,
+ reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
+ i2c_w_mask(sd, OV7670_R1E_MVFP,
OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
| OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
if (sd->gspca_dev.streaming)
- ov51x_restart(sd);
+ reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
}
-static int set_ov_sensor_window(struct sd *sd)
+static void set_ov_sensor_window(struct sd *sd)
{
struct gspca_dev *gspca_dev;
int qvga, crop;
int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
- int ret;
/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
- sd->sensor == SEN_OV7670)
- return mode_init_ov_sensor_regs(sd);
+ switch (sd->sensor) {
+ case SEN_OV2610:
+ case SEN_OV3610:
+ case SEN_OV7670:
+ mode_init_ov_sensor_regs(sd);
+ return;
+ case SEN_OV7660:
+ ov519_set_mode(sd);
+ ov519_set_fr(sd);
+ return;
+ }
gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
- crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
+ qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
+ crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
/* The different sensor ICs handle setting up of window differently.
* IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
@@ -3820,7 +4036,7 @@ static int set_ov_sensor_window(struct sd *sd)
vwsbase = vwebase = 0x03;
break;
default:
- return -EINVAL;
+ return;
}
switch (sd->sensor) {
@@ -3855,23 +4071,18 @@ static int set_ov_sensor_window(struct sd *sd)
}
}
- ret = mode_init_ov_sensor_regs(sd);
- if (ret < 0)
- return ret;
+ mode_init_ov_sensor_regs(sd);
i2c_w(sd, 0x17, hwsbase);
i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
i2c_w(sd, 0x19, vwsbase);
i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
-
- return 0;
}
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int ret = 0;
/* Default for most bridges, allow bridge_mode_init_regs to override */
sd->sensor_width = sd->gspca_dev.width;
@@ -3880,50 +4091,46 @@ static int sd_start(struct gspca_dev *gspca_dev)
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_mode_init_regs(sd);
+ ov511_mode_init_regs(sd);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- ret = ov518_mode_init_regs(sd);
+ ov518_mode_init_regs(sd);
break;
case BRIDGE_OV519:
- ret = ov519_mode_init_regs(sd);
+ ov519_mode_init_regs(sd);
break;
/* case BRIDGE_OVFX2: nothing to do */
case BRIDGE_W9968CF:
- ret = w9968cf_mode_init_regs(sd);
+ w9968cf_mode_init_regs(sd);
break;
}
- if (ret < 0)
- goto out;
-
- ret = set_ov_sensor_window(sd);
- if (ret < 0)
- goto out;
-
- setcontrast(gspca_dev);
- setbrightness(gspca_dev);
- setcolors(gspca_dev);
- sethvflip(gspca_dev);
- setautobright(gspca_dev);
- setfreq_i(sd);
+
+ set_ov_sensor_window(sd);
+
+ if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
+ setcontrast(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
+ setbrightness(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
+ setcolors(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
+ sethvflip(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
+ setautobright(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
+ setfreq_i(sd);
/* Force clear snapshot state in case the snapshot button was
pressed while we weren't streaming */
sd->snapshot_needs_reset = 1;
sd_reset_snapshot(gspca_dev);
- sd->snapshot_pressed = 0;
sd->first_frame = 3;
- ret = ov51x_restart(sd);
- if (ret < 0)
- goto out;
+ ov51x_restart(sd);
ov51x_led_control(sd, 1);
- return 0;
-out:
- PDEBUG(D_ERR, "camera start error:%d", ret);
- return ret;
+ return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -3938,8 +4145,21 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ if (!sd->gspca_dev.present)
+ return;
if (sd->bridge == BRIDGE_W9968CF)
w9968cf_stop0(sd);
+
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ /* If the last button state is pressed, release it now! */
+ if (sd->snapshot_pressed) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+ input_sync(gspca_dev->input_dev);
+ sd->snapshot_pressed = 0;
+ }
+#endif
+ if (sd->bridge == BRIDGE_OV519)
+ reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
}
static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
@@ -4160,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals brit_7660[][7] = {
+ {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
+ {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
+ {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
+ {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
+ {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
+ {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
+ {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
+ {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
+ {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
+ {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
+ {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
+ {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
+ {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
+ {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
+ };
val = sd->ctrls[BRIGHTNESS].val;
switch (sd->sensor) {
@@ -4179,10 +4415,14 @@ static void setbrightness(struct gspca_dev *gspca_dev)
if (!sd->ctrls[AUTOBRIGHT].val)
i2c_w(sd, OV7610_REG_BRT, val);
break;
+ case SEN_OV7660:
+ write_i2c_regvals(sd, brit_7660[val],
+ ARRAY_SIZE(brit_7660[0]));
+ break;
case SEN_OV7670:
/*win trace
- * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
- i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
+ * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
+ i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
break;
}
}
@@ -4191,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals contrast_7660[][31] = {
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
+ {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
+ {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
+ {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
+ {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
+ {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
+ {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
+ {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
+ {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
+ {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
+ {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
+ {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
+ {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
+ {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
+ {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
+ {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
+ {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
+ {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
+ {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
+ {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
+ {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
+ {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
+ {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
+ {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
+ {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
+ {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
+ {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
+ {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
+ {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
+ {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
+ {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
+ {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
+ {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
+ {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
+ {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
+ {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
+ {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
+ {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
+ {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
+ {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
+ {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
+ {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
+ {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
+ {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
+ {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
+ };
val = sd->ctrls[CONTRAST].val;
switch (sd->sensor) {
@@ -4203,7 +4501,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
break;
case SEN_OV8610: {
- static const __u8 ctab[] = {
+ static const u8 ctab[] = {
0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
};
@@ -4213,7 +4511,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
case SEN_OV7620:
case SEN_OV7620AE: {
- static const __u8 ctab[] = {
+ static const u8 ctab[] = {
0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
};
@@ -4222,9 +4520,13 @@ static void setcontrast(struct gspca_dev *gspca_dev)
i2c_w(sd, 0x64, ctab[val >> 4]);
break;
}
+ case SEN_OV7660:
+ write_i2c_regvals(sd, contrast_7660[val],
+ ARRAY_SIZE(contrast_7660[0]));
+ break;
case SEN_OV7670:
/* check that this isn't just the same as ov7610 */
- i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
+ i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
break;
}
}
@@ -4233,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals colors_7660[][6] = {
+ {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
+ {0x53, 0x19}, {0x54, 0x23}},
+ {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
+ {0x53, 0x2c}, {0x54, 0x3e}},
+ {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
+ {0x53, 0x40}, {0x54, 0x59}},
+ {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
+ {0x53, 0x53}, {0x54, 0x73}},
+ {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
+ {0x53, 0x66}, {0x54, 0x8e}},
+ };
val = sd->ctrls[COLORS].val;
switch (sd->sensor) {
@@ -4256,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
case SEN_OV7648:
i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
break;
+ case SEN_OV7660:
+ write_i2c_regvals(sd, colors_7660[val],
+ ARRAY_SIZE(colors_7660[0]));
+ break;
case SEN_OV7670:
/* supported later once I work out how to do it
* transparently fail now! */
@@ -4268,38 +4586,31 @@ static void setautobright(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
- sd->sensor == SEN_OV7670 ||
- sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- return;
-
i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
}
static void setfreq_i(struct sd *sd)
{
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- return;
-
- if (sd->sensor == SEN_OV7670) {
+ if (sd->sensor == SEN_OV7660
+ || sd->sensor == SEN_OV7670) {
switch (sd->ctrls[FREQ].val) {
case 0: /* Banding filter disabled */
- i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
+ i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
break;
case 1: /* 50 hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
+ i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
break;
case 2: /* 60 hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
+ i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
break;
- case 3: /* Auto hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ case 3: /* Auto hz - ov7670 only */
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
+ i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
0x18);
break;
}
@@ -4443,14 +4754,14 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4064),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4068),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x054c, 0x0155),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
@@ -4464,7 +4775,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
- {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
+ {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
{}
};
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 88ef03f6235b..0edf93973b1c 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1243,34 +1243,26 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
}
/* get stream parameters (framerate) */
-static int sd_get_streamparm(struct gspca_dev *gspca_dev,
+static void sd_get_streamparm(struct gspca_dev *gspca_dev,
struct v4l2_streamparm *parm)
{
struct v4l2_captureparm *cp = &parm->parm.capture;
struct v4l2_fract *tpf = &cp->timeperframe;
struct sd *sd = (struct sd *) gspca_dev;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
cp->capability |= V4L2_CAP_TIMEPERFRAME;
tpf->numerator = 1;
tpf->denominator = sd->frame_rate;
-
- return 0;
}
/* set stream parameters (framerate) */
-static int sd_set_streamparm(struct gspca_dev *gspca_dev,
+static void sd_set_streamparm(struct gspca_dev *gspca_dev,
struct v4l2_streamparm *parm)
{
struct v4l2_captureparm *cp = &parm->parm.capture;
struct v4l2_fract *tpf = &cp->timeperframe;
struct sd *sd = (struct sd *) gspca_dev;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
/* Set requested framerate */
sd->frame_rate = tpf->denominator / tpf->numerator;
if (gspca_dev->streaming)
@@ -1279,8 +1271,6 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
/* Return the actual framerate */
tpf->numerator = 1;
tpf->denominator = sd->frame_rate;
-
- return 0;
}
/* sub-driver description */
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
index e831f0d280ea..c5244b4b4777 100644
--- a/drivers/media/video/gspca/ov534_9.c
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -945,7 +945,6 @@ static void setautogain(struct gspca_dev *gspca_dev)
u8 val;
/*fixme: should adjust agc/awb/aec by different controls */
- val = sd->autogain;
val = sccb_read(gspca_dev, 0x13); /* com8 */
sccb_write(gspca_dev, 0xff, 0x00);
if (sd->autogain)
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 15e97fa4c337..96f9986305b4 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -162,7 +162,7 @@ static const __u8 pac207_sensor_init[][8] = {
{0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
{0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
{0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
- {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
+ {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00},
};
static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
@@ -228,7 +228,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
- idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
+ idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4);
idreg[1] = idreg[1] & 0x0f;
PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
idreg[0], idreg[1]);
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index 55fbea7381b0..2700975abce5 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -393,7 +393,7 @@ static const __u8 page3_7302[] = {
static void reg_w_buf(struct gspca_dev *gspca_dev,
__u8 index,
- const char *buffer, int len)
+ const u8 *buffer, int len)
{
int ret;
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 7657b43b3203..6820f5d58b19 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -261,7 +261,7 @@ static const __u8 page4_7311[] = {
static void reg_w_buf(struct gspca_dev *gspca_dev,
__u8 index,
- const char *buffer, int len)
+ const u8 *buffer, int len)
{
int ret;
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 6b155ae3a746..cb08d00d0a31 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -33,6 +33,14 @@ MODULE_LICENSE("GPL");
#define MODULE_NAME "sn9c20x"
+/*
+ * Pixel format private data
+ */
+#define SCALE_MASK 0x0f
+#define SCALE_160x120 0
+#define SCALE_320x240 1
+#define SCALE_640x480 2
+#define SCALE_1280x1024 3
#define MODE_RAW 0x10
#define MODE_JPEG 0x20
#define MODE_SXGA 0x80
@@ -348,47 +356,47 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 4 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0 | MODE_JPEG},
+ .priv = SCALE_160x120 | MODE_JPEG},
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0 | MODE_RAW},
+ .priv = SCALE_160x120 | MODE_RAW},
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 240 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
+ .priv = SCALE_160x120},
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1 | MODE_JPEG},
+ .priv = SCALE_320x240 | MODE_JPEG},
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW},
+ .priv = SCALE_320x240 | MODE_RAW},
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 480 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
+ .priv = SCALE_320x240},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2 | MODE_JPEG},
+ .priv = SCALE_640x480 | MODE_JPEG},
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2 | MODE_RAW},
+ .priv = SCALE_640x480 | MODE_RAW},
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 960 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
+ .priv = SCALE_640x480},
};
static const struct v4l2_pix_format sxga_mode[] = {
@@ -396,52 +404,75 @@ static const struct v4l2_pix_format sxga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 4 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0 | MODE_JPEG},
+ .priv = SCALE_160x120 | MODE_JPEG},
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0 | MODE_RAW},
+ .priv = SCALE_160x120 | MODE_RAW},
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 240 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
+ .priv = SCALE_160x120},
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1 | MODE_JPEG},
+ .priv = SCALE_320x240 | MODE_JPEG},
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW},
+ .priv = SCALE_320x240 | MODE_RAW},
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 480 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
+ .priv = SCALE_320x240},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2 | MODE_JPEG},
+ .priv = SCALE_640x480 | MODE_JPEG},
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2 | MODE_RAW},
+ .priv = SCALE_640x480 | MODE_RAW},
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 960 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
+ .priv = SCALE_640x480},
{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 1280,
.sizeimage = 1280 * 1024,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3 | MODE_RAW | MODE_SXGA},
+ .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
+};
+
+static const struct v4l2_pix_format mono_mode[] = {
+ {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_160x120 | MODE_RAW},
+ {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 ,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_320x240 | MODE_RAW},
+ {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_640x480 | MODE_RAW},
+ {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
};
static const s16 hsv_red_x[] = {
@@ -1029,16 +1060,19 @@ static struct i2c_reg_u16 mt9v011_init[] = {
};
static struct i2c_reg_u16 mt9m001_init[] = {
- {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
- {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
- {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
- {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
- {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
- {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
- {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
- {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
- {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
- {0x2e, 0x0029}, {0x07, 0x0002},
+ {0x0d, 0x0001},
+ {0x0d, 0x0000},
+ {0x04, 0x0500}, /* hres = 1280 */
+ {0x03, 0x0400}, /* vres = 1024 */
+ {0x20, 0x1100},
+ {0x06, 0x0010},
+ {0x2b, 0x0024},
+ {0x2e, 0x0024},
+ {0x35, 0x0024},
+ {0x2d, 0x0020},
+ {0x2c, 0x0020},
+ {0x09, 0x0ad4},
+ {0x35, 0x0057},
};
static struct i2c_reg_u16 mt9m111_init[] = {
@@ -1224,8 +1258,17 @@ static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
{
int i;
+ u16 id;
struct sd *sd = (struct sd *) gspca_dev;
+ if (i2c_r2(gspca_dev, 0x1c, &id) < 0)
+ return -EINVAL;
+
+ if (id != 0x7fa2) {
+ err("sensor id for ov9650 doesn't match (0x%04x)", id);
+ return -ENODEV;
+ }
+
for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
if (i2c_w1(gspca_dev, ov9650_init[i].reg,
ov9650_init[i].val) < 0) {
@@ -1425,6 +1468,25 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
+ u16 id;
+
+ if (i2c_r2(gspca_dev, 0x00, &id) < 0)
+ return -EINVAL;
+
+ /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
+ switch (id) {
+ case 0x8411:
+ case 0x8421:
+ info("MT9M001 color sensor detected");
+ break;
+ case 0x8431:
+ info("MT9M001 mono sensor detected");
+ break;
+ default:
+ err("No MT9M001 chip detected, ID = %x\n", id);
+ return -ENODEV;
+ }
+
for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
mt9m001_init[i].val) < 0) {
@@ -1434,8 +1496,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
}
/* disable hflip and vflip */
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
- sd->hstart = 2;
- sd->vstart = 2;
+ sd->hstart = 1;
+ sd->vstart = 1;
return 0;
}
@@ -1977,6 +2039,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sxga_mode;
cam->nmodes = ARRAY_SIZE(sxga_mode);
break;
+ case SENSOR_MT9M001:
+ cam->cam_mode = mono_mode;
+ cam->nmodes = ARRAY_SIZE(mono_mode);
+ break;
default:
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2075,7 +2141,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
case SENSOR_MT9M001:
if (mt9m001_init_sensor(gspca_dev) < 0)
return -ENODEV;
- info("MT9M001 sensor detected");
break;
case SENSOR_HV7131R:
if (hv7131r_init_sensor(gspca_dev) < 0)
@@ -2173,22 +2238,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
else if (mode & MODE_JPEG)
fmt = 0x2c;
else
- fmt = 0x2f;
+ fmt = 0x2f; /* YUV 420 */
- switch (mode & 0x0f) {
- case 3:
+ switch (mode & SCALE_MASK) {
+ case SCALE_1280x1024:
scale = 0xc0;
info("Set 1280x1024");
break;
- case 2:
+ case SCALE_640x480:
scale = 0x80;
info("Set 640x480");
break;
- case 1:
+ case SCALE_320x240:
scale = 0x90;
info("Set 320x240");
break;
- case 0:
+ case SCALE_160x120:
scale = 0xa0;
info("Set 160x120");
break;
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 706f96f92654..73504a3f87b7 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -56,6 +56,8 @@ struct sd {
int prev_avg_lum;
int exp_too_low_cnt;
int exp_too_high_cnt;
+ int header_read;
+ u8 header[12]; /* Header without sof marker */
unsigned short exposure;
unsigned char gain;
@@ -71,14 +73,15 @@ struct sd {
#define BRIDGE_103 1
__u8 sensor; /* Type of image sensor chip */
-#define SENSOR_HV7131R 0
-#define SENSOR_OV6650 1
-#define SENSOR_OV7630 2
-#define SENSOR_PAS106 3
-#define SENSOR_PAS202 4
-#define SENSOR_TAS5110C 5
-#define SENSOR_TAS5110D 6
-#define SENSOR_TAS5130CXX 7
+#define SENSOR_HV7131D 0
+#define SENSOR_HV7131R 1
+#define SENSOR_OV6650 2
+#define SENSOR_OV7630 3
+#define SENSOR_PAS106 4
+#define SENSOR_PAS202 5
+#define SENSOR_TAS5110C 6
+#define SENSOR_TAS5110D 7
+#define SENSOR_TAS5130CXX 8
__u8 reg11;
};
@@ -303,14 +306,29 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-static const __u8 initHv7131[] = {
+static const __u8 initHv7131d[] = {
+ 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
+ 0x28, 0x1e, 0x60, 0x8e, 0x42,
+ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
+};
+static const __u8 hv7131d_sensor_init[][8] = {
+ {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
+ {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
+ {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
+ {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
+ {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
+};
+
+static const __u8 initHv7131r[] = {
0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
0x28, 0x1e, 0x60, 0x8a, 0x20,
0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
};
-static const __u8 hv7131_sensor_init[][8] = {
+static const __u8 hv7131r_sensor_init[][8] = {
{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
{0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
{0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
@@ -340,7 +358,7 @@ static const __u8 ov6650_sensor_init[][8] = {
* but blue wont be there. Avoid this data ... */
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
- {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
+ {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
/* Enable rgb brightness control */
{0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
/* HDG: Note windows uses the line below, which sets both register 0x60
@@ -505,7 +523,7 @@ static const __u8 pas202_sensor_init[][8] = {
{0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
{0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
{0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
- {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
+ {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
{0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
{0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
{0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
@@ -551,7 +569,8 @@ static const __u8 tas5130_sensor_init[][8] = {
};
static struct sensor_data sensor_data[] = {
-SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
+SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
F_GAIN, 0, 0x21),
@@ -701,7 +720,18 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
unsigned char gain = sd->gain;
switch (sd->sensor) {
+ case SENSOR_HV7131D: {
+ __u8 i2c[] =
+ {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
+ i2c[3] = 0x3f - (sd->gain / 4);
+ i2c[4] = 0x3f - (sd->gain / 4);
+ i2c[5] = 0x3f - (sd->gain / 4);
+
+ if (i2c_w(gspca_dev, i2c) < 0)
+ goto err;
+ break;
+ }
case SENSOR_TAS5110C:
case SENSOR_TAS5110D: {
__u8 i2c[] =
@@ -788,6 +818,23 @@ static void setexposure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
switch (sd->sensor) {
+ case SENSOR_HV7131D: {
+ /* Note the datasheet wrongly says line mode exposure uses reg
+ 0x26 and 0x27, testing has shown 0x25 + 0x26 */
+ __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
+ /* The HV7131D's exposure goes from 0 - 65535, we scale our
+ exposure of 0-1023 to 0-6138. There are 2 reasons for this:
+ 1) This puts our exposure knee of 200 at approx the point
+ where the framerate starts dropping
+ 2) At 6138 the framerate has already dropped to 2 fps,
+ going any lower makes little sense */
+ __u16 reg = sd->exposure * 6;
+ i2c[3] = reg >> 8;
+ i2c[4] = reg & 0xff;
+ if (i2c_w(gspca_dev, i2c) != 0)
+ goto err;
+ break;
+ }
case SENSOR_TAS5110C:
case SENSOR_TAS5110D: {
/* register 19's high nibble contains the sn9c10x clock divider
@@ -1177,13 +1224,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
sd_init(gspca_dev);
}
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
+static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
{
- int i;
struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
+ int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
/* frames start with:
* ff ff 00 c4 c4 96 synchro
@@ -1194,58 +1238,84 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
* ll mm brightness sum outside auto exposure
* (xx xx xx xx xx) audio values for snc103
*/
- if (len > 6 && len < 24) {
- for (i = 0; i < len - 6; i++) {
- if (data[0 + i] == 0xff
- && data[1 + i] == 0xff
- && data[2 + i] == 0x00
- && data[3 + i] == 0xc4
- && data[4 + i] == 0xc4
- && data[5 + i] == 0x96) { /* start of frame */
- int lum = -1;
- int pkt_type = LAST_PACKET;
- int fr_h_sz = (sd->bridge == BRIDGE_103) ?
- 18 : 12;
-
- if (len - i < fr_h_sz) {
- PDEBUG(D_STREAM, "packet too short to"
- " get avg brightness");
- } else if (sd->bridge == BRIDGE_103) {
- lum = data[i + 9] +
- (data[i + 10] << 8);
- } else {
- lum = data[i + 8] + (data[i + 9] << 8);
- }
- /* When exposure changes midway a frame we
- get a lum of 0 in this case drop 2 frames
- as the frames directly after an exposure
- change have an unstable image. Sometimes lum
- *really* is 0 (cam used in low light with
- low exposure setting), so do not drop frames
- if the previous lum was 0 too. */
- if (lum == 0 && sd->prev_avg_lum != 0) {
- lum = -1;
- sd->frames_to_drop = 2;
- sd->prev_avg_lum = 0;
- } else
- sd->prev_avg_lum = lum;
- atomic_set(&sd->avg_lum, lum);
-
- if (sd->frames_to_drop) {
- sd->frames_to_drop--;
- pkt_type = DISCARD_PACKET;
- }
-
- gspca_frame_add(gspca_dev, pkt_type,
- NULL, 0);
- data += i + fr_h_sz;
- len -= i + fr_h_sz;
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data, len);
- return;
+ for (i = 0; i < len; i++) {
+ switch (sd->header_read) {
+ case 0:
+ if (data[i] == 0xff)
+ sd->header_read++;
+ break;
+ case 1:
+ if (data[i] == 0xff)
+ sd->header_read++;
+ else
+ sd->header_read = 0;
+ break;
+ case 2:
+ if (data[i] == 0x00)
+ sd->header_read++;
+ else if (data[i] != 0xff)
+ sd->header_read = 0;
+ break;
+ case 3:
+ if (data[i] == 0xc4)
+ sd->header_read++;
+ else if (data[i] == 0xff)
+ sd->header_read = 1;
+ else
+ sd->header_read = 0;
+ break;
+ case 4:
+ if (data[i] == 0xc4)
+ sd->header_read++;
+ else if (data[i] == 0xff)
+ sd->header_read = 1;
+ else
+ sd->header_read = 0;
+ break;
+ case 5:
+ if (data[i] == 0x96)
+ sd->header_read++;
+ else if (data[i] == 0xff)
+ sd->header_read = 1;
+ else
+ sd->header_read = 0;
+ break;
+ default:
+ sd->header[sd->header_read - 6] = data[i];
+ sd->header_read++;
+ if (sd->header_read == header_size) {
+ sd->header_read = 0;
+ return data + i + 1;
}
}
}
+ return NULL;
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam = &gspca_dev->cam;
+ u8 *sof;
+
+ sof = find_sof(gspca_dev, data, len);
+ if (sof) {
+ if (sd->bridge == BRIDGE_103) {
+ fr_h_sz = 18;
+ lum_offset = 3;
+ } else {
+ fr_h_sz = 12;
+ lum_offset = 2;
+ }
+
+ len_after_sof = len - (sof - data);
+ len = (sof - data) - fr_h_sz;
+ if (len < 0)
+ len = 0;
+ }
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
/* In raw mode we sometimes get some garbage after the frame
@@ -1259,6 +1329,33 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+
+ if (sof) {
+ int lum = sd->header[lum_offset] +
+ (sd->header[lum_offset + 1] << 8);
+
+ /* When exposure changes midway a frame we
+ get a lum of 0 in this case drop 2 frames
+ as the frames directly after an exposure
+ change have an unstable image. Sometimes lum
+ *really* is 0 (cam used in low light with
+ low exposure setting), so do not drop frames
+ if the previous lum was 0 too. */
+ if (lum == 0 && sd->prev_avg_lum != 0) {
+ lum = -1;
+ sd->frames_to_drop = 2;
+ sd->prev_avg_lum = 0;
+ } else
+ sd->prev_avg_lum = lum;
+ atomic_set(&sd->avg_lum, lum);
+
+ if (sd->frames_to_drop)
+ sd->frames_to_drop--;
+ else
+ gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+
+ gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
+ }
}
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -1431,9 +1528,7 @@ static const struct sd_desc sd_desc = {
static const struct usb_device_id device_table[] __devinitconst = {
{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
-#endif
{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
@@ -1444,9 +1539,12 @@ static const struct usb_device_id device_table[] __devinitconst = {
#endif
{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
+ {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
+ /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
+ /* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 330dadc00106..2d0bb17a30a2 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -63,7 +63,10 @@ struct sd {
#define QUALITY_DEF 80
u8 jpegqual; /* webcam quality */
+ u8 reg01;
+ u8 reg17;
u8 reg18;
+ u8 flags;
s8 ag_cnt;
#define AG_CNT_START 13
@@ -96,6 +99,22 @@ enum sensors {
SENSOR_SP80708,
};
+/* device flags */
+#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */
+
+/* sn9c1xx definitions */
+/* register 0x01 */
+#define S_PWR_DN 0x01 /* sensor power down */
+#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
+#define V_TX_EN 0x04 /* video transfer enable */
+#define LED 0x08 /* output to pin LED */
+#define SCL_SEL_OD 0x20 /* open-drain mode */
+#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
+/* register 0x17 */
+#define MCK_SIZE_MASK 0x1f /* sensor master clock */
+#define SEN_CLK_EN 0x20 /* enable sensor clock */
+#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
+
/* V4L2 controls supported by the driver */
static void setbrightness(struct gspca_dev *gspca_dev);
static void setcontrast(struct gspca_dev *gspca_dev);
@@ -1579,22 +1598,22 @@ static void i2c_w_seq(struct gspca_dev *gspca_dev,
}
}
+/* check the ID of the hv7131 sensor */
+/* this sequence is needed because it activates the sensor */
static void hv7131r_probe(struct gspca_dev *gspca_dev)
{
- i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
+ i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
- reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
+ reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
msleep(10);
- i2c_r(gspca_dev, 0, 5); /* read sensor id */
- if (gspca_dev->usb_buf[0] == 0x02
+ i2c_r(gspca_dev, 0, 5); /* read sensor id */
+ if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
&& gspca_dev->usb_buf[1] == 0x09
- && gspca_dev->usb_buf[2] == 0x01
- && gspca_dev->usb_buf[3] == 0x00
- && gspca_dev->usb_buf[4] == 0x00) {
- PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
+ && gspca_dev->usb_buf[2] == 0x01) {
+ PDEBUG(D_PROBE, "Sensor HV7131R found");
return;
}
- PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
+ warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x",
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
gspca_dev->usb_buf[2]);
}
@@ -1755,141 +1774,6 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
}
}
-static void bridge_init(struct gspca_dev *gspca_dev,
- const u8 *sn9c1xx)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 reg0102[2];
- const u8 *reg9a;
- static const u8 reg9a_def[] =
- {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
- static const u8 reg9a_spec[] =
- {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const u8 regd4[] = {0x60, 0x00, 0x00};
-
- /* sensor clock already enabled in sd_init */
- /* reg_w1(gspca_dev, 0xf1, 0x00); */
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-
- /* configure gpio */
- reg0102[0] = sn9c1xx[1];
- reg0102[1] = sn9c1xx[2];
- if (gspca_dev->audio)
- reg0102[1] |= 0x04; /* keep the audio connection */
- reg_w(gspca_dev, 0x01, reg0102, 2);
- reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
- reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
- switch (sd->sensor) {
- case SENSOR_GC0307:
- case SENSOR_OV7660:
- case SENSOR_PO1030:
- case SENSOR_PO2030N:
- case SENSOR_SOI768:
- case SENSOR_SP80708:
- reg9a = reg9a_spec;
- break;
- default:
- reg9a = reg9a_def;
- break;
- }
- reg_w(gspca_dev, 0x9a, reg9a, 6);
-
- reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
-
- reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
-
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- reg_w1(gspca_dev, 0x01, 0x43);
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_GC0307:
- msleep(50);
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x22);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- msleep(50);
- break;
- case SENSOR_MI0360B:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x60);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_MT9V111:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x61);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_OM6802:
- msleep(10);
- reg_w1(gspca_dev, 0x02, 0x73);
- reg_w1(gspca_dev, 0x17, 0x60);
- reg_w1(gspca_dev, 0x01, 0x22);
- msleep(100);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x17, 0x64);
- reg_w1(gspca_dev, 0x17, 0x64);
- reg_w1(gspca_dev, 0x01, 0x42);
- msleep(10);
- reg_w1(gspca_dev, 0x01, 0x42);
- i2c_w8(gspca_dev, om6802_init0[0]);
- i2c_w8(gspca_dev, om6802_init0[1]);
- msleep(15);
- reg_w1(gspca_dev, 0x02, 0x71);
- msleep(150);
- break;
- case SENSOR_OV7630:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0xe2);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_OV7648:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_PO1030:
- case SENSOR_SOI768:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
- case SENSOR_PO2030N:
- case SENSOR_OV7660:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- break;
- case SENSOR_SP80708:
- reg_w1(gspca_dev, 0x01, 0x63);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x62);
- reg_w1(gspca_dev, 0x01, 0x42);
- msleep(100);
- reg_w1(gspca_dev, 0x02, 0x62);
- break;
- default:
-/* case SENSOR_HV7131R: */
-/* case SENSOR_MI0360: */
-/* case SENSOR_MO4000: */
- reg_w1(gspca_dev, 0x01, 0x43);
- reg_w1(gspca_dev, 0x17, 0x61);
- reg_w1(gspca_dev, 0x01, 0x42);
- if (sd->sensor == SENSOR_HV7131R)
- hv7131r_probe(gspca_dev);
- break;
- }
-}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1898,7 +1782,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
sd->bridge = id->driver_info >> 16;
- sd->sensor = id->driver_info;
+ sd->sensor = id->driver_info >> 8;
+ sd->flags = id->driver_info;
cam = &gspca_dev->cam;
if (sd->sensor == SENSOR_ADCM1700) {
@@ -1929,7 +1814,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
reg_r(gspca_dev, 0x00, 1);
- reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
+ reg_w1(gspca_dev, 0xf1, 0x00);
reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
regF1 = gspca_dev->usb_buf[0];
if (gspca_dev->usb_err < 0)
@@ -2423,10 +2308,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- u8 reg1, reg17;
+ u8 reg01, reg17;
+ u8 reg0102[2];
const u8 *sn9c1xx;
const u8 (*init)[8];
+ const u8 *reg9a;
int mode;
+ static const u8 reg9a_def[] =
+ {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
+ static const u8 reg9a_spec[] =
+ {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
static const u8 CA_adcm1700[] =
@@ -2448,7 +2340,85 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* initialize the bridge */
sn9c1xx = sn_tb[sd->sensor];
- bridge_init(gspca_dev, sn9c1xx);
+
+ /* sensor clock already enabled in sd_init */
+ /* reg_w1(gspca_dev, 0xf1, 0x00); */
+ reg01 = sn9c1xx[1];
+ if (sd->flags & PDN_INV)
+ reg01 ^= S_PDN_INV; /* power down inverted */
+ reg_w1(gspca_dev, 0x01, reg01);
+
+ /* configure gpio */
+ reg0102[0] = reg01;
+ reg0102[1] = sn9c1xx[2];
+ if (gspca_dev->audio)
+ reg0102[1] |= 0x04; /* keep the audio connection */
+ reg_w(gspca_dev, 0x01, reg0102, 2);
+ reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
+ reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
+ switch (sd->sensor) {
+ case SENSOR_GC0307:
+ case SENSOR_OV7660:
+ case SENSOR_PO1030:
+ case SENSOR_PO2030N:
+ case SENSOR_SOI768:
+ case SENSOR_SP80708:
+ reg9a = reg9a_spec;
+ break;
+ default:
+ reg9a = reg9a_def;
+ break;
+ }
+ reg_w(gspca_dev, 0x9a, reg9a, 6);
+
+ reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
+
+ reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
+
+ reg17 = sn9c1xx[0x17];
+ switch (sd->sensor) {
+ case SENSOR_GC0307:
+ msleep(50); /*fixme: is it useful? */
+ break;
+ case SENSOR_OM6802:
+ msleep(10);
+ reg_w1(gspca_dev, 0x02, 0x73);
+ reg17 |= SEN_CLK_EN;
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg_w1(gspca_dev, 0x01, 0x22);
+ msleep(100);
+ reg01 = SCL_SEL_OD | S_PDN_INV;
+ reg17 &= MCK_SIZE_MASK;
+ reg17 |= 0x04; /* clock / 4 */
+ break;
+ }
+ reg01 |= SYS_SEL_48M;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg17 |= SEN_CLK_EN;
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg01 &= ~S_PWR_DN; /* sensor power on */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 &= ~SYS_SEL_48M;
+ reg_w1(gspca_dev, 0x01, reg01);
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ hv7131r_probe(gspca_dev); /*fixme: is it useful? */
+ break;
+ case SENSOR_OM6802:
+ msleep(10);
+ reg_w1(gspca_dev, 0x01, reg01);
+ i2c_w8(gspca_dev, om6802_init0[0]);
+ i2c_w8(gspca_dev, om6802_init0[1]);
+ msleep(15);
+ reg_w1(gspca_dev, 0x02, 0x71);
+ msleep(150);
+ break;
+ case SENSOR_SP80708:
+ msleep(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
+ }
/* initialize the sensor */
i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
@@ -2476,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
- case SENSOR_GC0307:
- reg17 = 0xa2;
- break;
- case SENSOR_MT9V111:
- case SENSOR_MI0360B:
- reg17 = 0xe0;
- break;
- case SENSOR_ADCM1700:
- case SENSOR_OV7630:
- reg17 = 0xe2;
- break;
- case SENSOR_OV7648:
- reg17 = 0x20;
- break;
- case SENSOR_OV7660:
- case SENSOR_SOI768:
- reg17 = 0xa0;
- break;
- case SENSOR_PO1030:
- case SENSOR_PO2030N:
- reg17 = 0xa0;
+ case SENSOR_OM6802:
+/* case SENSOR_OV7648: * fixme: sometimes */
break;
default:
- reg17 = 0x60;
+ reg17 |= DEF_EN;
break;
}
reg_w1(gspca_dev, 0x17, reg17);
@@ -2546,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev)
init = NULL;
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- if (mode)
- reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
- else
- reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
- reg17 = 0x61; /* 0x:20: enable sensor clock */
+ reg01 |= SYS_SEL_48M | V_TX_EN;
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x02; /* clock / 2 */
switch (sd->sensor) {
case SENSOR_ADCM1700:
init = adcm1700_sensor_param1;
- reg1 = 0x46;
- reg17 = 0xe2;
break;
case SENSOR_GC0307:
init = gc0307_sensor_param1;
- reg17 = 0xa2;
- reg1 = 0x44;
+ break;
+ case SENSOR_HV7131R:
+ case SENSOR_MI0360:
+ if (mode)
+ reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */
+ else
+ reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
break;
case SENSOR_MI0360B:
init = mi0360b_sensor_param1;
- reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */
- reg17 = 0xe2;
break;
case SENSOR_MO4000:
- if (mode) {
-/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
- reg1 = 0x06; /* clk 24Mz */
- } else {
- reg17 = 0x22; /* 640 MCKSIZE */
-/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ if (mode) { /* if 320x240 */
+ reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
}
break;
case SENSOR_MT9V111:
init = mt9v111_sensor_param1;
- if (mode) {
- reg1 = 0x04; /* 320 clk 48Mhz */
- } else {
-/* reg1 = 0x06; * 640 clk 24Mz (done) */
- reg17 = 0xc2;
- }
break;
case SENSOR_OM6802:
init = om6802_sensor_param1;
- reg17 = 0x64; /* 640 MCKSIZE */
+ if (!mode) { /* if 640x480 */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x04; /* clock / 4 */
+ }
break;
case SENSOR_OV7630:
init = ov7630_sensor_param1;
- reg17 = 0xe2;
- reg1 = 0x44;
break;
case SENSOR_OV7648:
init = ov7648_sensor_param1;
- reg17 = 0x21;
-/* reg1 = 0x42; * 42 - 46? */
+ reg17 &= ~MCK_SIZE_MASK;
+ reg17 |= 0x01; /* clock / 1 */
break;
case SENSOR_OV7660:
init = ov7660_sensor_param1;
- if (sd->bridge == BRIDGE_SN9C120) {
- if (mode) { /* 320x240 - 160x120 */
- reg17 = 0xa2;
- reg1 = 0x44; /* 48 Mhz, video trf eneble */
- }
- } else {
- reg17 = 0x22;
- reg1 = 0x06; /* 24 Mhz, video trf eneble
- * inverse power down */
- }
break;
case SENSOR_PO1030:
init = po1030_sensor_param1;
- reg17 = 0xa2;
- reg1 = 0x44;
break;
case SENSOR_PO2030N:
init = po2030n_sensor_param1;
- reg1 = 0x46;
- reg17 = 0xa2;
break;
case SENSOR_SOI768:
init = soi768_sensor_param1;
- reg1 = 0x44;
- reg17 = 0xa2;
break;
case SENSOR_SP80708:
init = sp80708_sensor_param1;
- if (mode) {
-/*?? reg1 = 0x04; * 320 clk 48Mhz */
- } else {
- reg1 = 0x46; /* 640 clk 48Mz */
- reg17 = 0xa2;
- }
break;
}
@@ -2684,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
setjpegqual(gspca_dev);
reg_w1(gspca_dev, 0x17, reg17);
- reg_w1(gspca_dev, 0x01, reg1);
+ reg_w1(gspca_dev, 0x01, reg01);
+ sd->reg01 = reg01;
+ sd->reg17 = reg17;
sethvflip(gspca_dev);
setbrightness(gspca_dev);
@@ -2706,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
static const u8 stopsoi768[] =
{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
- u8 data;
- const u8 *sn9c1xx;
+ u8 reg01;
+ u8 reg17;
- data = 0x0b;
+ reg01 = sd->reg01;
+ reg17 = sd->reg17 & ~SEN_CLK_EN;
switch (sd->sensor) {
+ case SENSOR_ADCM1700:
case SENSOR_GC0307:
- data = 0x29;
+ case SENSOR_PO2030N:
+ case SENSOR_SP80708:
+ reg01 |= LED;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 &= ~(LED | V_TX_EN);
+ reg_w1(gspca_dev, 0x01, reg01);
+/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
break;
case SENSOR_HV7131R:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
i2c_w8(gspca_dev, stophv7131);
- data = 0x2b;
break;
case SENSOR_MI0360:
case SENSOR_MI0360B:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
i2c_w8(gspca_dev, stopmi0360);
- data = 0x29;
break;
- case SENSOR_OV7648:
- i2c_w8(gspca_dev, stopov7648);
- /* fall thru */
case SENSOR_MT9V111:
- case SENSOR_OV7630:
+ case SENSOR_OM6802:
case SENSOR_PO1030:
- data = 0x29;
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+ break;
+ case SENSOR_OV7630:
+ case SENSOR_OV7648:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
+ i2c_w8(gspca_dev, stopov7648);
+ break;
+ case SENSOR_OV7660:
+ reg01 &= ~V_TX_EN;
+ reg_w1(gspca_dev, 0x01, reg01);
break;
case SENSOR_SOI768:
i2c_w8(gspca_dev, stopsoi768);
- data = 0x29;
break;
}
- sn9c1xx = sn_tb[sd->sensor];
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
- reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
- reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
- reg_w1(gspca_dev, 0x01, data);
+
+ reg01 |= SCL_SEL_OD;
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 |= S_PWR_DN; /* sensor power down */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
+ reg_w1(gspca_dev, 0x01, reg01);
+ reg01 |= LED;
+ reg_w1(gspca_dev, 0x01, reg01);
/* Don't disable sensor clock as that disables the button on the cam */
/* reg_w1(gspca_dev, 0xf1, 0x01); */
}
@@ -2954,14 +2902,18 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
#define BS(bridge, sensor) \
.driver_info = (BRIDGE_ ## bridge << 16) \
- | SENSOR_ ## sensor
+ | (SENSOR_ ## sensor << 8)
+#define BSF(bridge, sensor, flags) \
+ .driver_info = (BRIDGE_ ## bridge << 16) \
+ | (SENSOR_ ## sensor << 8) \
+ | (flags)
static const __devinitdata struct usb_device_id device_table[] = {
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
#endif
- {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
- {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
+ {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
+ {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index ad73f4812c05..3a162c6d5466 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -597,7 +597,7 @@ static void setgain(struct gspca_dev *gspca_dev)
else if (sd->gain < 128)
gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
else
- gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
+ gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
gspca_dev->usb_buf[1] = 0;
reg_w_buf(gspca_dev, 0x8335, 2);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index c2e88b5303cb..8ba199543856 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -301,6 +301,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x2770, 0x905c)},
{USB_DEVICE(0x2770, 0x9050)},
+ {USB_DEVICE(0x2770, 0x9051)},
{USB_DEVICE(0x2770, 0x9052)},
{USB_DEVICE(0x2770, 0x913d)},
{}
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
index 3e4b0b94c700..a4a98811b9e3 100644
--- a/drivers/media/video/gspca/sq930x.c
+++ b/drivers/media/video/gspca/sq930x.c
@@ -687,10 +687,19 @@ static void cmos_probe(struct gspca_dev *gspca_dev)
if (gspca_dev->usb_buf[0] != 0)
break;
}
- if (i >= ARRAY_SIZE(probe_order))
+ if (i >= ARRAY_SIZE(probe_order)) {
err("Unknown sensor");
- else
- sd->sensor = probe_order[i];
+ gspca_dev->usb_err = -EINVAL;
+ return;
+ }
+ sd->sensor = probe_order[i];
+ switch (sd->sensor) {
+ case SENSOR_OV7660:
+ case SENSOR_OV9630:
+ err("Sensor %s not yet treated", sensor_tb[sd->sensor].name);
+ gspca_dev->usb_err = -EINVAL;
+ break;
+ }
}
static void mt9v111_init(struct gspca_dev *gspca_dev)
@@ -867,6 +876,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
*/
reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
+ if (gspca_dev->usb_err < 0)
+ return gspca_dev->usb_err;
+
/* it returns:
* 03 00 12 93 0b f6 c9 00 live! ultra
* 03 00 07 93 0b f6 ca 00 live! ultra for notebook
@@ -900,15 +912,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_MI0360) {
/* no sensor probe for icam tracer */
- if (gspca_dev->usb_buf[5] == 0xf6) /* if CMOS */
+ if (gspca_dev->usb_buf[5] == 0xf6) /* if ccd */
sd->sensor = SENSOR_ICX098BQ;
else
cmos_probe(gspca_dev);
}
-
- PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
-
- global_init(sd, 1);
+ if (gspca_dev->usb_err >= 0) {
+ PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
+ global_init(sd, 1);
+ }
return gspca_dev->usb_err;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 086de44a6e57..28ea4175b80e 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -263,7 +263,21 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
static int stv06xx_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int err;
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
+ int err, packet_size;
+
+ intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+ if (!alt) {
+ PDEBUG(D_ERR, "Couldn't get altsetting");
+ return -EIO;
+ }
+
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+ err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
+ if (err < 0)
+ return err;
/* Prepare the sensor for start */
err = sd->sensor->start(sd);
@@ -282,6 +296,43 @@ out:
return (err < 0) ? err : 0;
}
+static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_interface *alt;
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ alt->endpoint[0].desc.wMaxPacketSize =
+ cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
+
+ return 0;
+}
+
+static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
+{
+ int ret, packet_size, min_packet_size;
+ struct usb_host_interface *alt;
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+ min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
+ if (packet_size <= min_packet_size)
+ return -EIO;
+
+ packet_size -= 100;
+ if (packet_size < min_packet_size)
+ packet_size = min_packet_size;
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
+
+ ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret);
+
+ return ret;
+}
+
static void stv06xx_stopN(struct gspca_dev *gspca_dev)
{
int err;
@@ -349,7 +400,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
}
/* First byte seem to be 02=data 2nd byte is unknown??? */
- if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200)
+ if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200)
goto frame_data;
switch (id) {
@@ -462,6 +513,8 @@ static const struct sd_desc sd_desc = {
.start = stv06xx_start,
.stopN = stv06xx_stopN,
.pkt_scan = stv06xx_pkt_scan,
+ .isoc_init = stv06xx_isoc_init,
+ .isoc_nego = stv06xx_isoc_nego,
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
.int_pkt_scan = sd_int_pkt_scan,
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index cf3d0ccc1121..b538dce96f78 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -146,6 +146,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
+ /* FIXME (see if we can lower min_packet_size, needs testing, and also
+ adjusting framerate when the bandwidth gets lower) */
+ .min_packet_size = { 847 },
+ .max_packet_size = { 847 },
+
.init = hdcs_init,
.probe = hdcs_probe_1x00,
.start = hdcs_start,
@@ -160,6 +165,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
+ /* FIXME (see if we can lower min_packet_size, needs testing, and also
+ adjusting framerate when the bandwidthm gets lower) */
+ .min_packet_size = { 847 },
+ .max_packet_size = { 847 },
+
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
@@ -177,7 +187,6 @@ static const u16 stv_bridge_init[][2] = {
{STV_REG04, 0x07},
{STV_SCAN_RATE, 0x20},
- {STV_ISO_SIZE_L, 847},
{STV_Y_CTRL, 0x01},
{STV_X_CTRL, 0x0a}
};
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index 285221e6b390..ac47b4c94388 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -208,11 +208,24 @@ static int pb0100_probe(struct sd *sd)
static int pb0100_start(struct sd *sd)
{
- int err;
+ int err, packet_size, max_packet_size;
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
struct cam *cam = &sd->gspca_dev.cam;
s32 *sensor_settings = sd->sensor_priv;
u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+ intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+
+ /* If we don't have enough bandwidth use a lower framerate */
+ max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
+ if (packet_size < max_packet_size)
+ stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
+ else
+ stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
+
/* Setup sensor window */
if (mode & PB0100_CROP_TO_VGA) {
stv06xx_write_sensor(sd, PB_RSTART, 30);
@@ -328,9 +341,6 @@ static int pb0100_init(struct sd *sd)
stv06xx_write_bridge(sd, STV_REG03, 0x45);
stv06xx_write_bridge(sd, STV_REG04, 0x07);
- /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
- stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
-
/* Scan/timing for the sensor */
stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
stv06xx_write_sensor(sd, PB_CFILLIN, 14);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 4de4fa5ebc57..757de246dc75 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -138,6 +138,9 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
+ .min_packet_size = { 635, 847 },
+ .max_packet_size = { 847, 923 },
+
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index 934b9cebc1ab..fb229d8ded58 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -53,6 +53,10 @@ struct stv06xx_sensor {
/* length of an i2c word */
u8 i2c_len;
+ /* Isoc packet size (per mode) */
+ int min_packet_size[4];
+ int max_packet_size[4];
+
/* Probes if the sensor is connected */
int (*probe)(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 3af53264a364..8a456de4970a 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -28,6 +28,20 @@
#include "stv06xx_st6422.h"
+/* controls */
+enum e_ctrl {
+ BRIGHTNESS,
+ CONTRAST,
+ GAIN,
+ EXPOSURE,
+ NCTRLS /* number of controls */
+};
+
+/* sensor settings */
+struct st6422_settings {
+ struct gspca_ctrl ctrls[NCTRLS];
+};
+
static struct v4l2_pix_format st6422_mode[] = {
/* Note we actually get 124 lines of data, of which we skip the 4st
4 as they are garbage */
@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = {
},
};
-static const struct ctrl st6422_ctrl[] = {
-#define BRIGHTNESS_IDX 0
- {
+/* V4L2 controls supported by the driver */
+static void st6422_set_brightness(struct gspca_dev *gspca_dev);
+static void st6422_set_contrast(struct gspca_dev *gspca_dev);
+static void st6422_set_gain(struct gspca_dev *gspca_dev);
+static void st6422_set_exposure(struct gspca_dev *gspca_dev);
+
+static const struct ctrl st6422_ctrl[NCTRLS] = {
+[BRIGHTNESS] = {
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1,
.default_value = 3
},
- .set = st6422_set_brightness,
- .get = st6422_get_brightness
+ .set_control = st6422_set_brightness
},
-#define CONTRAST_IDX 1
- {
+[CONTRAST] = {
{
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1,
.default_value = 11
},
- .set = st6422_set_contrast,
- .get = st6422_get_contrast
+ .set_control = st6422_set_contrast
},
-#define GAIN_IDX 2
- {
+[GAIN] = {
{
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1,
.default_value = 64
},
- .set = st6422_set_gain,
- .get = st6422_get_gain
+ .set_control = st6422_set_gain
},
-#define EXPOSURE_IDX 3
- {
+[EXPOSURE] = {
{
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Exposure",
.minimum = 0,
- .maximum = 1023,
+#define EXPOSURE_MAX 1023
+ .maximum = EXPOSURE_MAX,
.step = 1,
.default_value = 256
},
- .set = st6422_set_exposure,
- .get = st6422_get_exposure
+ .set_control = st6422_set_exposure
},
};
static int st6422_probe(struct sd *sd)
{
- int i;
- s32 *sensor_settings;
+ struct st6422_settings *sensor_settings;
if (sd->bridge != BRIDGE_ST6422)
return -ENODEV;
info("st6422 sensor detected");
- sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32),
- GFP_KERNEL);
+ sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL);
if (!sensor_settings)
return -ENOMEM;
sd->gspca_dev.cam.cam_mode = st6422_mode;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
+ sd->gspca_dev.cam.ctrls = sensor_settings->ctrls;
sd->desc.ctrls = st6422_ctrl;
sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
sd->sensor_priv = sensor_settings;
- for (i = 0; i < sd->desc.nctrls; i++)
- sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
-
return 0;
}
@@ -151,11 +160,11 @@ static int st6422_init(struct sd *sd)
{ STV_ISO_ENABLE, 0x00 }, /* disable capture */
{ 0x1436, 0x00 },
{ 0x1432, 0x03 }, /* 0x00-0x1F brightness */
- { 0x143a, 0xF9 }, /* 0x00-0x0F contrast */
+ { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */
{ 0x0509, 0x38 }, /* R */
{ 0x050a, 0x38 }, /* G */
{ 0x050b, 0x38 }, /* B */
- { 0x050c, 0x2A },
+ { 0x050c, 0x2a },
{ 0x050d, 0x01 },
@@ -213,7 +222,6 @@ static int st6422_init(struct sd *sd)
{ 0x150e, 0x8e },
{ 0x150f, 0x37 },
{ 0x15c0, 0x00 },
- { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */
{ 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */
@@ -235,91 +243,92 @@ static void st6422_disconnect(struct sd *sd)
kfree(sd->sensor_priv);
}
-static int st6422_start(struct sd *sd)
+static int setbrightness(struct sd *sd)
{
- int err, packet_size;
- struct cam *cam = &sd->gspca_dev.cam;
- s32 *sensor_settings = sd->sensor_priv;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- err("Couldn't get altsetting");
- return -EIO;
- }
+ struct st6422_settings *sensor_settings = sd->sensor_priv;
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- err = stv06xx_write_bridge(sd, 0x15c1, packet_size);
- if (err < 0)
- return err;
+ /* val goes from 0 -> 31 */
+ return stv06xx_write_bridge(sd, 0x1432,
+ sensor_settings->ctrls[BRIGHTNESS].val);
+}
- if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
- err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
- else
- err = stv06xx_write_bridge(sd, 0x1505, 0x02);
- if (err < 0)
- return err;
+static int setcontrast(struct sd *sd)
+{
+ struct st6422_settings *sensor_settings = sd->sensor_priv;
+
+ /* Val goes from 0 -> 15 */
+ return stv06xx_write_bridge(sd, 0x143a,
+ sensor_settings->ctrls[CONTRAST].val | 0xf0);
+}
+
+static int setgain(struct sd *sd)
+{
+ struct st6422_settings *sensor_settings = sd->sensor_priv;
+ u8 gain;
+ int err;
+
+ gain = sensor_settings->ctrls[GAIN].val;
- err = st6422_set_brightness(&sd->gspca_dev,
- sensor_settings[BRIGHTNESS_IDX]);
+ /* Set red, green, blue, gain */
+ err = stv06xx_write_bridge(sd, 0x0509, gain);
if (err < 0)
return err;
- err = st6422_set_contrast(&sd->gspca_dev,
- sensor_settings[CONTRAST_IDX]);
+ err = stv06xx_write_bridge(sd, 0x050a, gain);
if (err < 0)
return err;
- err = st6422_set_exposure(&sd->gspca_dev,
- sensor_settings[EXPOSURE_IDX]);
+ err = stv06xx_write_bridge(sd, 0x050b, gain);
if (err < 0)
return err;
- err = st6422_set_gain(&sd->gspca_dev,
- sensor_settings[GAIN_IDX]);
+ /* 2 mystery writes */
+ err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
if (err < 0)
return err;
- PDEBUG(D_STREAM, "Starting stream");
-
- return 0;
+ return stv06xx_write_bridge(sd, 0x050d, 0x01);
}
-static int st6422_stop(struct sd *sd)
+static int setexposure(struct sd *sd)
{
- PDEBUG(D_STREAM, "Halting stream");
-
- return 0;
-}
-
-static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[BRIGHTNESS_IDX];
+ struct st6422_settings *sensor_settings = sd->sensor_priv;
+ u16 expo;
+ int err;
- PDEBUG(D_V4L2, "Read brightness %d", *val);
+ expo = sensor_settings->ctrls[EXPOSURE].val;
+ err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
+ if (err < 0)
+ return err;
- return 0;
+ return stv06xx_write_bridge(sd, 0x143e, expo >> 8);
}
-static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+static int st6422_start(struct sd *sd)
{
int err;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
+ struct cam *cam = &sd->gspca_dev.cam;
- sensor_settings[BRIGHTNESS_IDX] = val;
+ if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
+ err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
+ else
+ err = stv06xx_write_bridge(sd, 0x1505, 0x02);
+ if (err < 0)
+ return err;
- if (!gspca_dev->streaming)
- return 0;
+ err = setbrightness(sd);
+ if (err < 0)
+ return err;
- /* val goes from 0 -> 31 */
- PDEBUG(D_V4L2, "Set brightness to %d", val);
- err = stv06xx_write_bridge(sd, 0x1432, val);
+ err = setcontrast(sd);
+ if (err < 0)
+ return err;
+
+ err = setexposure(sd);
+ if (err < 0)
+ return err;
+
+ err = setgain(sd);
if (err < 0)
return err;
@@ -328,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
return (err < 0) ? err : 0;
}
-static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val)
+static int st6422_stop(struct sd *sd)
{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[CONTRAST_IDX];
-
- PDEBUG(D_V4L2, "Read contrast %d", *val);
+ PDEBUG(D_STREAM, "Halting stream");
return 0;
}
-static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_brightness(struct gspca_dev *gspca_dev)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[CONTRAST_IDX] = val;
- if (!gspca_dev->streaming)
- return 0;
-
- /* Val goes from 0 -> 15 */
- PDEBUG(D_V4L2, "Set contrast to %d\n", val);
- err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
- if (err < 0)
- return err;
+ err = setbrightness(sd);
/* commit settings */
- err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return (err < 0) ? err : 0;
-}
-
-static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
-
- PDEBUG(D_V4L2, "Read gain %d", *val);
+ if (err >= 0)
+ err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return 0;
+ gspca_dev->usb_err = err;
}
-static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_contrast(struct gspca_dev *gspca_dev)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[GAIN_IDX] = val;
-
- if (!gspca_dev->streaming)
- return 0;
-
- PDEBUG(D_V4L2, "Set gain to %d", val);
- /* Set red, green, blue, gain */
- err = stv06xx_write_bridge(sd, 0x0509, val);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x050a, val);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x050b, val);
- if (err < 0)
- return err;
-
- /* 2 mystery writes */
- err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x050d, 0x01);
- if (err < 0)
- return err;
+ err = setcontrast(sd);
/* commit settings */
- err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return (err < 0) ? err : 0;
+ if (err >= 0)
+ err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+
+ gspca_dev->usb_err = err;
}
-static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static void st6422_set_gain(struct gspca_dev *gspca_dev)
{
+ int err;
struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- *val = sensor_settings[EXPOSURE_IDX];
+ err = setgain(sd);
- PDEBUG(D_V4L2, "Read exposure %d", *val);
+ /* commit settings */
+ if (err >= 0)
+ err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return 0;
+ gspca_dev->usb_err = err;
}
-static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_exposure(struct gspca_dev *gspca_dev)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[EXPOSURE_IDX] = val;
- if (!gspca_dev->streaming)
- return 0;
-
- PDEBUG(D_V4L2, "Set exposure to %d\n", val);
- err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x143e, val >> 8);
- if (err < 0)
- return err;
+ err = setexposure(sd);
/* commit settings */
- err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return (err < 0) ? err : 0;
+ if (err >= 0)
+ err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+
+ gspca_dev->usb_err = err;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
index b2d45fe50522..d7498e06432b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
@@ -37,18 +37,11 @@ static int st6422_init(struct sd *sd);
static int st6422_stop(struct sd *sd);
static void st6422_disconnect(struct sd *sd);
-/* V4L2 controls supported by the driver */
-static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-
const struct stv06xx_sensor stv06xx_sensor_st6422 = {
.name = "ST6422",
+ /* No known way to lower framerate in case of less bandwidth */
+ .min_packet_size = { 300, 847 },
+ .max_packet_size = { 300, 847 },
.init = st6422_init,
.probe = st6422_probe,
.start = st6422_start,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index b3b5508473bc..7fe3587f5f71 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -197,6 +197,10 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.i2c_flush = 5,
.i2c_addr = 0x20,
.i2c_len = 1,
+ /* FIXME (see if we can lower packet_size-s, needs testing, and also
+ adjusting framerate when the bandwidth gets lower) */
+ .min_packet_size = { 1023 },
+ .max_packet_size = { 1023 },
.init = vv6410_init,
.probe = vv6410_probe,
.start = vv6410_start,
@@ -220,10 +224,6 @@ static const u8 x1536[] = { /* 0x1536 - 0x153b */
0x02, 0x00, 0x60, 0x01, 0x20, 0x01
};
-static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */
- 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */
-};
-
static const struct stv_init stv_bridge_init[] = {
/* This reg is written twice. Some kind of reset? */
{NULL, 0x1620, 0x80},
@@ -232,7 +232,6 @@ static const struct stv_init stv_bridge_init[] = {
{NULL, 0x1423, 0x04},
{x1500, 0x1500, ARRAY_SIZE(x1500)},
{x1536, 0x1536, ARRAY_SIZE(x1536)},
- {x15c1, 0x15c1, ARRAY_SIZE(x15c1)}
};
static const u8 vv6410_sensor_init[][2] = {
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index b45f4d0f3997..8f0c33116e0d 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -487,7 +487,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = {
{0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
0xff},
- {0x00, 0x04, 0x0B, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
+ {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
0xff},
{0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index d9e3c6050781..38c22f0a4263 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -132,7 +132,7 @@ static const struct v4l2_pix_format sif_mode[] = {
#define R36_PID 0x36
#define R37_PIDH 0x37
#define R39_Test1 0x39 /* GPIO */
-#define R3B_Test3 0x3B /* GPIO */
+#define R3B_Test3 0x3b /* GPIO */
#define R83_AD_IDH 0x83
#define R91_AD_SLOPEREG 0x91
#define R94_AD_BITCONTROL 0x94
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 38a6efe1a5f9..9b2ae1b6cc75 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -47,24 +47,29 @@ struct sd {
u8 image_offset;
u8 bridge;
-#define BRIDGE_VC0321 0
-#define BRIDGE_VC0323 1
u8 sensor;
-#define SENSOR_HV7131R 0
-#define SENSOR_MI0360 1
-#define SENSOR_MI1310_SOC 2
-#define SENSOR_MI1320 3
-#define SENSOR_MI1320_SOC 4
-#define SENSOR_OV7660 5
-#define SENSOR_OV7670 6
-#define SENSOR_PO1200 7
-#define SENSOR_PO3130NC 8
-#define SENSOR_POxxxx 9
u8 flags;
#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
#define FL_HFLIP 0x02 /* mirrored by default */
#define FL_VFLIP 0x04 /* vertical flipped by default */
};
+enum bridges {
+ BRIDGE_VC0321,
+ BRIDGE_VC0323,
+};
+enum sensors {
+ SENSOR_HV7131R,
+ SENSOR_MI0360,
+ SENSOR_MI1310_SOC,
+ SENSOR_MI1320,
+ SENSOR_MI1320_SOC,
+ SENSOR_OV7660,
+ SENSOR_OV7670,
+ SENSOR_PO1200,
+ SENSOR_PO3130NC,
+ SENSOR_POxxxx,
+ NSENSORS
+};
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -260,56 +265,56 @@ static const struct ctrl sd_ctrls[] = {
};
/* table of the disabled controls */
-static u32 ctrl_dis[] = {
-/* SENSOR_HV7131R 0 */
+static u32 ctrl_dis[NSENSORS] = {
+ [SENSOR_HV7131R] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
| (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_MI0360 1 */
+ [SENSOR_MI0360] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
| (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_MI1310_SOC 2 */
+ [SENSOR_MI1310_SOC] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_MI1320 3 */
+ [SENSOR_MI1320] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_MI1320_SOC 4 */
+ [SENSOR_MI1320_SOC] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_OV7660 5 */
+ [SENSOR_OV7660] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_OV7670 6 */
+ [SENSOR_OV7670] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_PO1200 7 */
+ [SENSOR_PO1200] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << LIGHTFREQ_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_PO3130NC 8 */
+ [SENSOR_PO3130NC] =
(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
| (1 << SHARPNESS_IDX)
| (1 << GAIN_IDX) | (1 << EXPOSURE_IDX)
| (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX),
-/* SENSOR_POxxxx 9 */
+ [SENSOR_POxxxx] =
(1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX),
};
@@ -3420,17 +3425,18 @@ static int sd_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
int sensor;
- static u8 npkt[] = { /* number of packets per ISOC message */
- 64, /* HV7131R 0 */
- 32, /* MI0360 1 */
- 32, /* MI1310_SOC 2 */
- 64, /* MI1320 3 */
- 128, /* MI1320_SOC 4 */
- 32, /* OV7660 5 */
- 64, /* OV7670 6 */
- 128, /* PO1200 7 */
- 128, /* PO3130NC 8 */
- 128, /* POxxxx 9 */
+ /* number of packets per ISOC message */
+ static u8 npkt[NSENSORS] = {
+ [SENSOR_HV7131R] = 64,
+ [SENSOR_MI0360] = 32,
+ [SENSOR_MI1310_SOC] = 32,
+ [SENSOR_MI1320] = 64,
+ [SENSOR_MI1320_SOC] = 128,
+ [SENSOR_OV7660] = 32,
+ [SENSOR_OV7670] = 64,
+ [SENSOR_PO1200] = 128,
+ [SENSOR_PO3130NC] = 128,
+ [SENSOR_POxxxx] = 128,
};
if (sd->sensor != SENSOR_POxxxx)
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
index 4066ac8c45a0..4a9e622e5e1b 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -59,18 +59,21 @@ static const struct v4l2_pix_format w9968cf_vga_mode[] = {
.colorspace = V4L2_COLORSPACE_JPEG},
};
-static int reg_w(struct sd *sd, __u16 index, __u16 value);
+static void reg_w(struct sd *sd, u16 index, u16 value);
/*--------------------------------------------------------------------------
Write 64-bit data to the fast serial bus registers.
Return 0 on success, -1 otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_write_fsb(struct sd *sd, u16* data)
+static void w9968cf_write_fsb(struct sd *sd, u16* data)
{
struct usb_device *udev = sd->gspca_dev.dev;
u16 value;
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
value = *data++;
memcpy(sd->gspca_dev.usb_buf, data, 6);
@@ -79,20 +82,21 @@ static int w9968cf_write_fsb(struct sd *sd, u16* data)
value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
if (ret < 0) {
err("Write FSB registers failed (%d)", ret);
- return ret;
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
/*--------------------------------------------------------------------------
Write data to the serial bus control register.
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_write_sb(struct sd *sd, u16 value)
+static void w9968cf_write_sb(struct sd *sd, u16 value)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
/* We don't use reg_w here, as that would cause all writes when
bitbanging i2c to be logged, making the logs impossible to read */
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -105,10 +109,8 @@ static int w9968cf_write_sb(struct sd *sd, u16 value)
if (ret < 0) {
err("Write SB reg [01] %04x failed", value);
- return ret;
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
/*--------------------------------------------------------------------------
@@ -119,6 +121,9 @@ static int w9968cf_read_sb(struct sd *sd)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
/* We don't use reg_r here, as the w9968cf is special and has 16
bit registers instead of 8 bit */
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -126,11 +131,13 @@ static int w9968cf_read_sb(struct sd *sd)
1,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
- if (ret >= 0)
+ if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0] |
(sd->gspca_dev.usb_buf[1] << 8);
- else
+ } else {
err("Read SB reg [01] failed");
+ sd->gspca_dev.usb_err = ret;
+ }
udelay(W9968CF_I2C_BUS_DELAY);
@@ -142,22 +149,20 @@ static int w9968cf_read_sb(struct sd *sd)
This function is called by w9968cf_start_transfer().
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_upload_quantizationtables(struct sd *sd)
+static void w9968cf_upload_quantizationtables(struct sd *sd)
{
u16 a, b;
- int ret = 0, i, j;
+ int i, j;
- ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
+ reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
for (i = 0, j = 0; i < 32; i++, j += 2) {
- a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
- b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
- ret += reg_w(sd, 0x40+i, a);
- ret += reg_w(sd, 0x60+i, b);
+ a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
+ b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
+ reg_w(sd, 0x40 + i, a);
+ reg_w(sd, 0x60 + i, b);
}
- ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
-
- return ret;
+ reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
}
/****************************************************************************
@@ -168,50 +173,39 @@ static int w9968cf_upload_quantizationtables(struct sd *sd)
* i2c_adap_read_byte() *
****************************************************************************/
-static int w9968cf_smbus_start(struct sd *sd)
+static void w9968cf_smbus_start(struct sd *sd)
{
- int ret = 0;
-
- ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+ w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
}
-static int w9968cf_smbus_stop(struct sd *sd)
+static void w9968cf_smbus_stop(struct sd *sd)
{
- int ret = 0;
-
- ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+ w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
}
-static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
+static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
{
u8 bit;
- int ret = 0, sda;
+ int sda;
for (bit = 0 ; bit < 8 ; bit++) {
sda = (v & 0x80) ? 2 : 0;
v <<= 1;
/* SDE=1, SDA=sda, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x10 | sda);
+ w9968cf_write_sb(sd, 0x10 | sda);
/* SDE=1, SDA=sda, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x11 | sda);
+ w9968cf_write_sb(sd, 0x11 | sda);
/* SDE=1, SDA=sda, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x10 | sda);
+ w9968cf_write_sb(sd, 0x10 | sda);
}
-
- return ret;
}
-static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
+static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
{
u8 bit;
- int ret = 0;
/* No need to ensure SDA is high as we are always called after
read_ack which ends with SDA high */
@@ -219,51 +213,40 @@ static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
for (bit = 0 ; bit < 8 ; bit++) {
*v <<= 1;
/* SDE=1, SDA=1, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0013);
+ w9968cf_write_sb(sd, 0x0013);
*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
/* SDE=1, SDA=1, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0012);
+ w9968cf_write_sb(sd, 0x0012);
}
-
- return ret;
}
-static int w9968cf_smbus_write_nack(struct sd *sd)
+static void w9968cf_smbus_write_nack(struct sd *sd)
{
- int ret = 0;
-
/* No need to ensure SDA is high as we are always called after
read_byte which ends with SDA high */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
}
-static int w9968cf_smbus_read_ack(struct sd *sd)
+static void w9968cf_smbus_read_ack(struct sd *sd)
{
- int ret = 0, sda;
+ int sda;
/* Ensure SDA is high before raising clock to avoid a spurious stop */
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
sda = w9968cf_read_sb(sd);
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- if (sda < 0)
- ret += sda;
- else if (sda & 0x08) {
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+ if (sda >= 0 && (sda & 0x08)) {
PDEBUG(D_USBI, "Did not receive i2c ACK");
- ret += -1;
+ sd->gspca_dev.usb_err = -EIO;
}
-
- return ret;
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
-static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
+static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
{
u16* data = (u16 *)sd->gspca_dev.usb_buf;
- int ret = 0;
data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
@@ -276,7 +259,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
@@ -290,7 +273,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
data[3] = 0x001d;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
data[0] |= (value & 0x40) ? 0x0540 : 0x0;
@@ -304,14 +287,9 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[2] |= (value & 0x01) ? 0x5400 : 0x0;
data[3] = 0xfe1d;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
- if (!ret)
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
- else
- PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
-
- return ret;
+ PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
@@ -321,28 +299,28 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
u8 value;
/* Fast serial bus data control disable */
- ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
-
- ret += w9968cf_smbus_start(sd);
- ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_write_byte(sd, reg);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_stop(sd);
- ret += w9968cf_smbus_start(sd);
- ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_read_byte(sd, &value);
+ w9968cf_write_sb(sd, 0x0013); /* don't change ! */
+
+ w9968cf_smbus_start(sd);
+ w9968cf_smbus_write_byte(sd, sd->sensor_addr);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_write_byte(sd, reg);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_stop(sd);
+ w9968cf_smbus_start(sd);
+ w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_read_byte(sd, &value);
/* signal we don't want to read anymore, the v4l1 driver used to
send an ack here which is very wrong! (and then fixed
the issues this gave by retrying reads) */
- ret += w9968cf_smbus_write_nack(sd);
- ret += w9968cf_smbus_stop(sd);
+ w9968cf_smbus_write_nack(sd);
+ w9968cf_smbus_stop(sd);
/* Fast serial bus data control re-enable */
- ret += w9968cf_write_sb(sd, 0x0030);
+ w9968cf_write_sb(sd, 0x0030);
- if (!ret) {
+ if (sd->gspca_dev.usb_err >= 0) {
ret = value;
PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
} else
@@ -351,79 +329,68 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
return ret;
}
-
/*--------------------------------------------------------------------------
Turn on the LED on some webcams. A beep should be heard too.
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_configure(struct sd *sd)
+static void w9968cf_configure(struct sd *sd)
{
- int ret = 0;
-
- ret += reg_w(sd, 0x00, 0xff00); /* power-down */
- ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
- ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
- ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
- ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
- ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
- ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
-
- if (ret)
- PDEBUG(D_ERR, "Couldn't turn on the LED");
+ reg_w(sd, 0x00, 0xff00); /* power-down */
+ reg_w(sd, 0x00, 0xbf17); /* reset everything */
+ reg_w(sd, 0x00, 0xbf10); /* normal operation */
+ reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
+ reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
+ reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
+ reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
sd->stopped = 1;
-
- return ret;
}
-static int w9968cf_init(struct sd *sd)
+static void w9968cf_init(struct sd *sd)
{
- int ret = 0;
unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
y0 = 0x0000,
- u0 = y0 + hw_bufsize/2,
- v0 = u0 + hw_bufsize/4,
- y1 = v0 + hw_bufsize/4,
- u1 = y1 + hw_bufsize/2,
- v1 = u1 + hw_bufsize/4;
-
- ret += reg_w(sd, 0x00, 0xff00); /* power off */
- ret += reg_w(sd, 0x00, 0xbf10); /* power on */
-
- ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
- ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
-
- ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
- ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
- ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
- ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
- ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
- ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
-
- ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
- ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
- ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
- ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
- ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
- ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
-
- ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
- ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
-
- ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
- ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
-
- ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
- ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
- ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
- ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
-
- return ret;
+ u0 = y0 + hw_bufsize / 2,
+ v0 = u0 + hw_bufsize / 4,
+ y1 = v0 + hw_bufsize / 4,
+ u1 = y1 + hw_bufsize / 2,
+ v1 = u1 + hw_bufsize / 4;
+
+ reg_w(sd, 0x00, 0xff00); /* power off */
+ reg_w(sd, 0x00, 0xbf10); /* power on */
+
+ reg_w(sd, 0x03, 0x405d); /* DRAM timings */
+ reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
+
+ reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
+ reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
+ reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
+ reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
+ reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
+ reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
+
+ reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
+ reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
+ reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
+ reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
+ reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
+ reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
+
+ reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
+ reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
+
+ reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
+ reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
+
+ reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
+ reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
+ reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
+ reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
}
-static int w9968cf_set_crop_window(struct sd *sd)
+static void w9968cf_set_crop_window(struct sd *sd)
{
- int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
+ int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
max_width, max_height;
if (sd->sif) {
@@ -456,8 +423,8 @@ static int w9968cf_set_crop_window(struct sd *sd)
fw = SC(sd->gspca_dev.width) / max_width;
fh = SC(sd->gspca_dev.height) / max_height;
- cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
- ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
+ cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh;
+ ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height;
sd->sensor_width = max_width;
sd->sensor_height = max_height;
@@ -465,42 +432,40 @@ static int w9968cf_set_crop_window(struct sd *sd)
x = (max_width - cw) / 2;
y = (max_height - ch) / 2;
- ret += reg_w(sd, 0x10, start_cropx + x);
- ret += reg_w(sd, 0x11, start_cropy + y);
- ret += reg_w(sd, 0x12, start_cropx + x + cw);
- ret += reg_w(sd, 0x13, start_cropy + y + ch);
-
- return ret;
+ reg_w(sd, 0x10, start_cropx + x);
+ reg_w(sd, 0x11, start_cropy + y);
+ reg_w(sd, 0x12, start_cropx + x + cw);
+ reg_w(sd, 0x13, start_cropy + y + ch);
}
-static int w9968cf_mode_init_regs(struct sd *sd)
+static void w9968cf_mode_init_regs(struct sd *sd)
{
- int ret = 0, val, vs_polarity, hs_polarity;
+ int val, vs_polarity, hs_polarity;
- ret += w9968cf_set_crop_window(sd);
+ w9968cf_set_crop_window(sd);
- ret += reg_w(sd, 0x14, sd->gspca_dev.width);
- ret += reg_w(sd, 0x15, sd->gspca_dev.height);
+ reg_w(sd, 0x14, sd->gspca_dev.width);
+ reg_w(sd, 0x15, sd->gspca_dev.height);
/* JPEG width & height */
- ret += reg_w(sd, 0x30, sd->gspca_dev.width);
- ret += reg_w(sd, 0x31, sd->gspca_dev.height);
+ reg_w(sd, 0x30, sd->gspca_dev.width);
+ reg_w(sd, 0x31, sd->gspca_dev.height);
/* Y & UV frame buffer strides (in WORD) */
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) {
- ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
- ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
+ reg_w(sd, 0x2c, sd->gspca_dev.width / 2);
+ reg_w(sd, 0x2d, sd->gspca_dev.width / 4);
} else
- ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
+ reg_w(sd, 0x2c, sd->gspca_dev.width);
- ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
- ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+ reg_w(sd, 0x00, 0xbf17); /* reset everything */
+ reg_w(sd, 0x00, 0xbf10); /* normal operation */
/* Transfer size in WORDS (for UYVY format only) */
val = sd->gspca_dev.width * sd->gspca_dev.height;
- ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
- ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
+ reg_w(sd, 0x3d, val & 0xffff); /* low bits */
+ reg_w(sd, 0x3e, val >> 16); /* high bits */
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) {
@@ -508,7 +473,7 @@ static int w9968cf_mode_init_regs(struct sd *sd)
jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
sd->gspca_dev.width, 0x22); /* JPEG 420 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
- ret += w9968cf_upload_quantizationtables(sd);
+ w9968cf_upload_quantizationtables(sd);
}
/* Video Capture Control Register */
@@ -540,19 +505,15 @@ static int w9968cf_mode_init_regs(struct sd *sd)
val |= 0x8000; /* capt. enable */
- ret += reg_w(sd, 0x16, val);
+ reg_w(sd, 0x16, val);
sd->gspca_dev.empty_packet = 0;
-
- return ret;
}
static void w9968cf_stop0(struct sd *sd)
{
- if (sd->gspca_dev.present) {
- reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
- reg_w(sd, 0x16, 0x0000); /* stop video capture */
- }
+ reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
+ reg_w(sd, 0x16, 0x0000); /* stop video capture */
}
/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
index 8715577bc2d8..5b5039a02031 100644
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ b/drivers/media/video/gspca/xirlink_cit.c
@@ -29,6 +29,7 @@
#define MODULE_NAME "xirlink-cit"
+#include <linux/input.h>
#include "gspca.h"
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
@@ -58,6 +59,7 @@ struct sd {
#define CIT_MODEL4 4
#define CIT_IBM_NETCAM_PRO 5
u8 input_index;
+ u8 button_state;
u8 stop_on_control_change;
u8 sof_read;
u8 sof_len;
@@ -185,60 +187,60 @@ static const struct ctrl sd_ctrls[] = {
static const struct v4l2_pix_format cif_yuv_mode[] = {
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2,
+ .sizeimage = 352 * 288 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format vga_yuv_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
+ .sizeimage = 320 * 240 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2,
+ .sizeimage = 640 * 480 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format model0_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
+ .sizeimage = 320 * 240 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format model2_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240,
+ .sizeimage = 320 * 240 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
.bytesperline = 352,
- .sizeimage = 352 * 288,
+ .sizeimage = 352 * 288 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
@@ -804,7 +806,7 @@ static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
return 0;
}
-static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index)
+static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
{
struct usb_device *udev = gspca_dev->dev;
__u8 *buf = gspca_dev->usb_buf;
@@ -819,10 +821,8 @@ static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index)
return res;
}
- PDEBUG(D_PROBE,
- "Register %04x value: %02x %02x %02x %02x %02x %02x %02x %02x",
- index,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+ if (verbose)
+ PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]);
return 0;
}
@@ -907,7 +907,7 @@ static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
cit_send_x_00_05(gspca_dev, 0x0089);
cit_send_x_00(gspca_dev, fkey);
cit_send_00_04_06(gspca_dev);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 0);
cit_send_FF_04_02(gspca_dev);
}
@@ -1074,12 +1074,12 @@ static int cit_init_model0(struct gspca_dev *gspca_dev)
static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
{
- cit_read_reg(gspca_dev, 0x128);
+ cit_read_reg(gspca_dev, 0x128, 1);
cit_write_reg(gspca_dev, 0x0003, 0x0133);
cit_write_reg(gspca_dev, 0x0000, 0x0117);
cit_write_reg(gspca_dev, 0x0008, 0x0123);
cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x0000, 0x0133);
@@ -1098,7 +1098,7 @@ static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x00ff, 0x0130);
cit_write_reg(gspca_dev, 0xcd41, 0x0124);
cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 1);
cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
@@ -1557,18 +1557,20 @@ static int cit_restart_stream(struct gspca_dev *gspca_dev)
switch (sd->model) {
case CIT_MODEL0:
case CIT_MODEL1:
- case CIT_MODEL3:
- case CIT_IBM_NETCAM_PRO:
cit_write_reg(gspca_dev, 0x0001, 0x0114);
/* Fall through */
case CIT_MODEL2:
case CIT_MODEL4:
cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* This happens repeatedly while streaming with the ibm netcam
- pro and the ibmcam driver did it for model3 after changing
- settings, but it does not seem to have any effect. */
- /* cit_write_reg(gspca_dev, 0x0001, 0x0113); */
+ break;
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ cit_write_reg(gspca_dev, 0x0001, 0x0114);
+ cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
+ /* Clear button events from while we were not streaming */
+ cit_write_reg(gspca_dev, 0x0001, 0x0113);
break;
}
@@ -1680,23 +1682,23 @@ static int cit_start_model1(struct gspca_dev *gspca_dev)
if (clock_div < 0)
return clock_div;
- cit_read_reg(gspca_dev, 0x0128);
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0128, 1);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
cit_write_reg(gspca_dev, 0x01, 0x0108);
cit_write_reg(gspca_dev, 0x03, 0x0112);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x06, 0x0115);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x44, 0x0116);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x40, 0x0116);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x0e, 0x0115);
cit_write_reg(gspca_dev, 0x19, 0x012c);
@@ -1878,7 +1880,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
int clock_div = 0;
cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x00bc, 0x012c);
@@ -2070,10 +2072,10 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
/* HDG not in ibmcam driver, added to see if it helps with
auto-detecting between model3 and ibm netcamera pro */
- cit_read_reg(gspca_dev, 0x128);
+ cit_read_reg(gspca_dev, 0x128, 1);
cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x0000, 0x0123);
@@ -2083,7 +2085,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0115);
cit_write_reg(gspca_dev, 0x0003, 0x0115);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x000b, 0x0115);
/* TESTME HDG not in ibmcam driver, added to see if it helps with
@@ -2096,7 +2098,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x00ff, 0x0130);
cit_write_reg(gspca_dev, 0xcd41, 0x0124);
cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 1);
}
cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
@@ -2293,7 +2295,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
if (rca_input) {
for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
else
cit_write_reg(gspca_dev, rca_initdata[i][1],
rca_initdata[i][2]);
@@ -2712,7 +2714,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
if (rca_input) {
for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
else
cit_write_reg(gspca_dev, rca_initdata[i][1],
rca_initdata[i][2]);
@@ -2769,16 +2771,55 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_interface *alt;
+ int max_packet_size;
+
+ switch (gspca_dev->width) {
+ case 160:
+ max_packet_size = 450;
+ break;
+ case 176:
+ max_packet_size = 600;
+ break;
+ default:
+ max_packet_size = 1022;
+ break;
+ }
+
+ /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
+
+ return 0;
+}
+
static int sd_isoc_nego(struct gspca_dev *gspca_dev)
{
- int ret, packet_size;
+ int ret, packet_size, min_packet_size;
struct usb_host_interface *alt;
+ switch (gspca_dev->width) {
+ case 160:
+ min_packet_size = 200;
+ break;
+ case 176:
+ min_packet_size = 266;
+ break;
+ default:
+ min_packet_size = 400;
+ break;
+ }
+
alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- packet_size -= 100;
- if (packet_size < 300)
+ if (packet_size <= min_packet_size)
return -EIO;
+
+ packet_size -= 100;
+ if (packet_size < min_packet_size)
+ packet_size = min_packet_size;
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -2796,15 +2837,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_host_interface *alt;
/* We cannot use gspca_dev->present here as that is not set when
sd_init gets called and we get called from sd_init */
if (!gspca_dev->dev)
return;
- alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
-
switch (sd->model) {
case CIT_MODEL0:
/* HDG windows does this, but it causes the cams autogain to
@@ -2815,7 +2853,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
break;
case CIT_MODEL1:
cit_send_FF_04_02(gspca_dev);
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
break;
case CIT_MODEL2:
@@ -2834,9 +2872,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
case CIT_MODEL3:
cit_write_reg(gspca_dev, 0x0006, 0x012c);
cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0064, 0x0116);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x0003, 0x0115);
cit_write_reg(gspca_dev, 0x0008, 0x0123);
cit_write_reg(gspca_dev, 0x0000, 0x0117);
@@ -2859,12 +2897,17 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
restarting the stream after this */
/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
cit_write_reg(gspca_dev, 0x00c0, 0x0100);
-
- /* Start isoc bandwidth "negotiation" at max isoc bandwith
- next stream start */
- alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022);
break;
}
+
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ /* If the last button state is pressed, release it now! */
+ if (sd->button_state) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+ input_sync(gspca_dev->input_dev);
+ sd->button_state = 0;
+ }
+#endif
}
static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
@@ -3158,6 +3201,38 @@ static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+static void cit_check_button(struct gspca_dev *gspca_dev)
+{
+ int new_button_state;
+ struct sd *sd = (struct sd *)gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ break;
+ default: /* TEST ME unknown if this works on other models too */
+ return;
+ }
+
+ /* Read the button state */
+ cit_read_reg(gspca_dev, 0x0113, 0);
+ new_button_state = !gspca_dev->usb_buf[0];
+
+ /* Tell the cam we've seen the button press, notice that this
+ is a nop (iow the cam keeps reporting pressed) until the
+ button is actually released. */
+ if (new_button_state)
+ cit_write_reg(gspca_dev, 0x01, 0x0113);
+
+ if (sd->button_state != new_button_state) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA,
+ new_button_state);
+ input_sync(gspca_dev->input_dev);
+ sd->button_state = new_button_state;
+ }
+}
+#endif
/* sub-driver description */
static const struct sd_desc sd_desc = {
@@ -3170,6 +3245,10 @@ static const struct sd_desc sd_desc = {
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ .dq_callback = cit_check_button,
+ .other_input = 1,
+#endif
};
static const struct sd_desc sd_desc_isoc_nego = {
@@ -3179,10 +3258,15 @@ static const struct sd_desc sd_desc_isoc_nego = {
.config = sd_config,
.init = sd_init,
.start = sd_start,
+ .isoc_init = sd_isoc_init,
.isoc_nego = sd_isoc_nego,
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ .dq_callback = cit_check_button,
+ .other_input = 1,
+#endif
};
/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index c7e1970ca284..14b85d483163 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -35,16 +35,23 @@ static int force_sensor = -1;
#define QUANT_VAL 1 /* quantization table */
#include "zc3xx-reg.h"
+/* controls */
+enum e_ctrl {
+ BRIGHTNESS,
+ CONTRAST,
+ GAMMA,
+ AUTOGAIN,
+ LIGHTFREQ,
+ SHARPNESS,
+ NCTRLS /* number of controls */
+};
+
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- u8 brightness;
- u8 contrast;
- u8 gamma;
- u8 autogain;
- u8 lightfreq;
- u8 sharpness;
+ struct gspca_ctrl ctrls[NCTRLS];
+
u8 quality; /* image quality */
#define QUALITY_MIN 50
#define QUALITY_MAX 80
@@ -64,6 +71,7 @@ enum sensors {
SENSOR_ADCM2700,
SENSOR_CS2102,
SENSOR_CS2102K,
+ SENSOR_GC0303,
SENSOR_GC0305,
SENSOR_HDCS2020b,
SENSOR_HV7131B,
@@ -79,26 +87,17 @@ enum sensors {
SENSOR_PB0330,
SENSOR_PO2030,
SENSOR_TAS5130C,
- SENSOR_TAS5130C_VF0250,
SENSOR_MAX
};
/* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
-
-static const struct ctrl sd_ctrls[] = {
- {
+static void setcontrast(struct gspca_dev *gspca_dev);
+static void setautogain(struct gspca_dev *gspca_dev);
+static void setlightfreq(struct gspca_dev *gspca_dev);
+static void setsharpness(struct gspca_dev *gspca_dev);
+
+static const struct ctrl sd_ctrls[NCTRLS] = {
+[BRIGHTNESS] = {
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -106,13 +105,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
-#define BRIGHTNESS_DEF 128
- .default_value = BRIGHTNESS_DEF,
+ .default_value = 128,
},
- .set = sd_setbrightness,
- .get = sd_getbrightness,
+ .set_control = setcontrast
},
- {
+[CONTRAST] = {
{
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -120,13 +117,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
-#define CONTRAST_DEF 128
- .default_value = CONTRAST_DEF,
+ .default_value = 128,
},
- .set = sd_setcontrast,
- .get = sd_getcontrast,
+ .set_control = setcontrast
},
- {
+[GAMMA] = {
{
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -136,10 +131,9 @@ static const struct ctrl sd_ctrls[] = {
.step = 1,
.default_value = 4,
},
- .set = sd_setgamma,
- .get = sd_getgamma,
+ .set_control = setcontrast
},
- {
+[AUTOGAIN] = {
{
.id = V4L2_CID_AUTOGAIN,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -147,14 +141,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
-#define AUTOGAIN_DEF 1
- .default_value = AUTOGAIN_DEF,
+ .default_value = 1,
},
- .set = sd_setautogain,
- .get = sd_getautogain,
+ .set_control = setautogain
},
-#define LIGHTFREQ_IDX 4
- {
+[LIGHTFREQ] = {
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
.type = V4L2_CTRL_TYPE_MENU,
@@ -162,13 +153,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
.step = 1,
-#define FREQ_DEF 0
- .default_value = FREQ_DEF,
+ .default_value = 0,
},
- .set = sd_setfreq,
- .get = sd_getfreq,
+ .set_control = setlightfreq
},
- {
+[SHARPNESS] = {
{
.id = V4L2_CID_SHARPNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -176,11 +165,9 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 3,
.step = 1,
-#define SHARPNESS_DEF 2
- .default_value = SHARPNESS_DEF,
+ .default_value = 2,
},
- .set = sd_setsharpness,
- .get = sd_getsharpness,
+ .set_control = setsharpness
},
};
@@ -4499,7 +4486,7 @@ static const struct usb_action mt9v111_3_Initial[] = {
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -5406,7 +5393,7 @@ static const struct usb_action tas5130c_NoFlikerScale[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_InitialScale[] = {
+static const struct usb_action gc0303_InitialScale[] = {
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5473,7 +5460,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_Initial[] = {
+static const struct usb_action gc0303_Initial[] = {
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5538,7 +5525,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = {
{0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
{}
};
-static const struct usb_action tas5130c_vf0250_50HZScale[] = {
+static const struct usb_action gc0303_50HZScale[] = {
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
{0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */
@@ -5562,7 +5549,7 @@ static const struct usb_action tas5130c_vf0250_50HZScale[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_50HZ[] = {
+static const struct usb_action gc0303_50HZ[] = {
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0003}, /* 00,83,03,aa */
{0xaa, 0x84, 0x0054}, /* 00,84,54,aa */
@@ -5586,7 +5573,7 @@ static const struct usb_action tas5130c_vf0250_50HZ[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_60HZScale[] = {
+static const struct usb_action gc0303_60HZScale[] = {
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
{0xaa, 0x84, 0x0062}, /* 00,84,62,aa */
@@ -5610,7 +5597,7 @@ static const struct usb_action tas5130c_vf0250_60HZScale[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_60HZ[] = {
+static const struct usb_action gc0303_60HZ[] = {
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
{0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */
@@ -5634,7 +5621,7 @@ static const struct usb_action tas5130c_vf0250_60HZ[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
+static const struct usb_action gc0303_NoFlikerScale[] = {
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5656,7 +5643,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{}
};
-static const struct usb_action tas5130c_vf0250_NoFliker[] = {
+static const struct usb_action gc0303_NoFliker[] = {
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5833,12 +5820,13 @@ static void setmatrix(struct gspca_dev *gspca_dev)
{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
static const u8 tas5130c_matrix[9] =
{0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
- static const u8 vf0250_matrix[9] =
+ static const u8 gc0303_matrix[9] =
{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
static const u8 *matrix_tb[SENSOR_MAX] = {
[SENSOR_ADCM2700] = adcm2700_matrix,
[SENSOR_CS2102] = ov7620_matrix,
[SENSOR_CS2102K] = NULL,
+ [SENSOR_GC0303] = gc0303_matrix,
[SENSOR_GC0305] = gc0305_matrix,
[SENSOR_HDCS2020b] = NULL,
[SENSOR_HV7131B] = NULL,
@@ -5854,7 +5842,6 @@ static void setmatrix(struct gspca_dev *gspca_dev)
[SENSOR_PB0330] = gc0305_matrix,
[SENSOR_PO2030] = po2030_matrix,
[SENSOR_TAS5130C] = tas5130c_matrix,
- [SENSOR_TAS5130C_VF0250] = vf0250_matrix,
};
matrix = matrix_tb[sd->sensor];
@@ -5875,7 +5862,7 @@ static void setsharpness(struct gspca_dev *gspca_dev)
{0x10, 0x1e}
};
- sharpness = sd->sharpness;
+ sharpness = sd->ctrls[SHARPNESS].val;
reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6);
reg_r(gspca_dev, 0x01c8);
reg_r(gspca_dev, 0x01c9);
@@ -5910,10 +5897,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
};
- Tgamma = gamma_tb[sd->gamma - 1];
+ Tgamma = gamma_tb[sd->ctrls[GAMMA].val - 1];
- contrast = ((int) sd->contrast - 128); /* -128 / 127 */
- brightness = ((int) sd->brightness - 128); /* -128 / 92 */
+ contrast = ((int) sd->ctrls[CONTRAST].val - 128); /* -128 / 127 */
+ brightness = ((int) sd->ctrls[BRIGHTNESS].val - 128); /* -128 / 92 */
adj = 0;
gp1 = gp2 = 0;
for (i = 0; i < 16; i++) {
@@ -5994,6 +5981,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
{cs2102_NoFliker, cs2102_NoFlikerScale,
NULL, NULL, /* currently disabled */
NULL, NULL},
+ [SENSOR_GC0303] =
+ {gc0303_NoFliker, gc0303_NoFlikerScale,
+ gc0303_50HZ, gc0303_50HZScale,
+ gc0303_60HZ, gc0303_60HZScale},
[SENSOR_GC0305] =
{gc0305_NoFliker, gc0305_NoFliker,
gc0305_50HZ, gc0305_50HZ,
@@ -6054,14 +6045,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
{tas5130c_NoFliker, tas5130c_NoFlikerScale,
tas5130c_50HZ, tas5130c_50HZScale,
tas5130c_60HZ, tas5130c_60HZScale},
- [SENSOR_TAS5130C_VF0250] =
- {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
- tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
- tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
};
- i = sd->lightfreq * 2;
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ i = sd->ctrls[LIGHTFREQ].val * 2;
+ mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
if (mode)
i++; /* 320x240 */
zc3_freq = freq_tb[sd->sensor][i];
@@ -6070,14 +6057,14 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
usb_exchange(gspca_dev, zc3_freq);
switch (sd->sensor) {
case SENSOR_GC0305:
- if (mode /* if 320x240 */
- && sd->lightfreq == 1) /* and 50Hz */
+ if (mode /* if 320x240 */
+ && sd->ctrls[LIGHTFREQ].val == 1) /* and 50Hz */
reg_w(gspca_dev, 0x85, 0x018d);
/* win: 0x80, 0x018d */
break;
case SENSOR_OV7620:
- if (!mode) { /* if 640x480 */
- if (sd->lightfreq != 0) /* and 50 or 60 Hz */
+ if (!mode) { /* if 640x480 */
+ if (sd->ctrls[LIGHTFREQ].val != 0) /* and filter */
reg_w(gspca_dev, 0x40, 0x0002);
else
reg_w(gspca_dev, 0x44, 0x0002);
@@ -6094,7 +6081,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
u8 autoval;
- if (sd->autogain)
+ if (sd->ctrls[AUTOGAIN].val)
autoval = 0x42;
else
autoval = 0x02;
@@ -6330,8 +6317,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
retword = i2c_read(gspca_dev, 0x00);
if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
- if (retword == 0x0011) /* VF0250 */
- return 0x0250;
+ if (retword == 0x0011) /* gc0303 */
+ return 0x0303;
if (retword == 0x0029) /* gc0305 */
send_unknown(gspca_dev, SENSOR_GC0305);
return retword;
@@ -6392,7 +6379,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_MC501CB:
return -1; /* don't probe */
- case SENSOR_TAS5130C_VF0250:
+ case SENSOR_GC0303:
/* may probe but with no write in reg 0x0010 */
return -1; /* don't probe */
case SENSOR_PAS106:
@@ -6421,11 +6408,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* define some sensors from the vendor/product */
sd->sensor = id->driver_info;
- sd->sharpness = SHARPNESS_DEF;
- sd->brightness = BRIGHTNESS_DEF;
- sd->contrast = CONTRAST_DEF;
- sd->autogain = AUTOGAIN_DEF;
- sd->lightfreq = FREQ_DEF;
+ gspca_dev->cam.ctrls = sd->ctrls;
sd->quality = QUALITY_DEF;
return 0;
@@ -6441,6 +6424,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_ADCM2700] = 4,
[SENSOR_CS2102] = 4,
[SENSOR_CS2102K] = 5,
+ [SENSOR_GC0303] = 3,
[SENSOR_GC0305] = 4,
[SENSOR_HDCS2020b] = 4,
[SENSOR_HV7131B] = 4,
@@ -6456,12 +6440,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_PB0330] = 4,
[SENSOR_PO2030] = 4,
[SENSOR_TAS5130C] = 3,
- [SENSOR_TAS5130C_VF0250] = 3,
};
static const u8 mode_tb[SENSOR_MAX] = {
[SENSOR_ADCM2700] = 2,
[SENSOR_CS2102] = 1,
[SENSOR_CS2102K] = 1,
+ [SENSOR_GC0303] = 1,
[SENSOR_GC0305] = 1,
[SENSOR_HDCS2020b] = 1,
[SENSOR_HV7131B] = 1,
@@ -6477,7 +6461,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_PB0330] = 1,
[SENSOR_PO2030] = 1,
[SENSOR_TAS5130C] = 1,
- [SENSOR_TAS5130C_VF0250] = 1,
};
sensor = zcxx_probeSensor(gspca_dev);
@@ -6493,8 +6476,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
case SENSOR_MC501CB:
PDEBUG(D_PROBE, "Sensor MC501CB");
break;
- case SENSOR_TAS5130C_VF0250:
- PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)");
+ case SENSOR_GC0303:
+ PDEBUG(D_PROBE, "Sensor GC0303");
break;
default:
warn("Unknown sensor - set to TAS5130C");
@@ -6581,14 +6564,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
break;
- case 0x0250:
- PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)");
- sd->sensor = SENSOR_TAS5130C_VF0250;
+ case 0x0303:
+ PDEBUG(D_PROBE, "Sensor GC0303");
+ sd->sensor = SENSOR_GC0303;
break;
case 0x2030:
PDEBUG(D_PROBE, "Find Sensor PO2030");
sd->sensor = SENSOR_PO2030;
- sd->sharpness = 0; /* from win traces */
+ sd->ctrls[SHARPNESS].def = 0; /* from win traces */
break;
case 0x7620:
PDEBUG(D_PROBE, "Find Sensor OV7620");
@@ -6629,11 +6612,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
cam->nmodes = ARRAY_SIZE(broken_vga_mode);
break;
}
- sd->gamma = gamma[sd->sensor];
+
+ sd->ctrls[GAMMA].def = gamma[sd->sensor];
switch (sd->sensor) {
case SENSOR_OV7630C:
- gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
+ gspca_dev->ctrl_dis = (1 << LIGHTFREQ);
break;
}
@@ -6653,6 +6637,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
{cs2102_Initial, cs2102_InitialScale},
[SENSOR_CS2102K] =
{cs2102K_Initial, cs2102K_InitialScale},
+ [SENSOR_GC0303] =
+ {gc0303_Initial, gc0303_InitialScale},
[SENSOR_GC0305] =
{gc0305_Initial, gc0305_InitialScale},
[SENSOR_HDCS2020b] =
@@ -6683,8 +6669,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
{po2030_Initial, po2030_InitialScale},
[SENSOR_TAS5130C] =
{tas5130c_Initial, tas5130c_InitialScale},
- [SENSOR_TAS5130C_VF0250] =
- {tas5130c_vf0250_Initial, tas5130c_vf0250_InitialScale},
};
/* create the JPEG header */
@@ -6709,7 +6693,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_OV7620:
case SENSOR_PO2030:
case SENSOR_TAS5130C:
- case SENSOR_TAS5130C_VF0250:
+ case SENSOR_GC0303:
/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */
@@ -6843,114 +6827,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->brightness;
- return 0;
-}
-
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->autogain = val;
- if (gspca_dev->streaming)
- setautogain(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->autogain;
- return 0;
-}
-
-static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->gamma = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->gamma;
- return 0;
-}
-
-static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->lightfreq = val;
- if (gspca_dev->streaming)
- setlightfreq(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->lightfreq;
- return 0;
-}
-
-static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->sharpness = val;
- if (gspca_dev->streaming)
- setsharpness(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->sharpness;
- return 0;
-}
-
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu)
{
@@ -7045,8 +6921,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x041e, 0x4036)},
{USB_DEVICE(0x041e, 0x403a)},
- {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
- {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
+ {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_GC0303},
+ {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_GC0303},
{USB_DEVICE(0x0458, 0x7007)},
{USB_DEVICE(0x0458, 0x700c)},
{USB_DEVICE(0x0458, 0x700f)},
@@ -7066,8 +6942,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x046d, 0x08af)},
{USB_DEVICE(0x046d, 0x08b9)},
{USB_DEVICE(0x046d, 0x08d7)},
- {USB_DEVICE(0x046d, 0x08d9)},
{USB_DEVICE(0x046d, 0x08d8)},
+ {USB_DEVICE(0x046d, 0x08d9)},
{USB_DEVICE(0x046d, 0x08da)},
{USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
{USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106},
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index b70d6afc9fec..f7d1ee55185a 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -385,6 +385,11 @@ static int hdpvr_probe(struct usb_interface *interface,
v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
goto error;
}
+
+ /* until i2c is working properly */
+ retval = 0; /* hdpvr_register_i2c_ir(dev); */
+ if (retval < 0)
+ v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
#endif /* CONFIG_I2C */
/* let the user know what node this device is now attached to */
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index 409de11096d4..24966aa02a70 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -4,6 +4,9 @@
*
* Copyright (C) 2008 Janne Grunau (j@jannau.net)
*
+ * IR device registration code is
+ * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.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, version 2.
@@ -22,6 +25,56 @@
#define REQTYPE_I2C_WRITE 0xb0
#define REQTYPE_I2C_WRITE_STATT 0xd0
+#define Z8F0811_IR_TX_I2C_ADDR 0x70
+#define Z8F0811_IR_RX_I2C_ADDR 0x71
+
+static const u8 ir_i2c_addrs[] = {
+ Z8F0811_IR_TX_I2C_ADDR,
+ Z8F0811_IR_RX_I2C_ADDR,
+};
+
+static const char * const ir_devicenames[] = {
+ "ir_tx_z8f0811_hdpvr",
+ "ir_rx_z8f0811_hdpvr",
+};
+
+static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap,
+ const char *type, u8 addr)
+{
+ struct i2c_board_info info;
+ struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
+ unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, type, I2C_NAME_SIZE);
+
+ /* Our default information for ir-kbd-i2c.c to use */
+ switch (addr) {
+ case Z8F0811_IR_RX_I2C_ADDR:
+ init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
+ init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+ init_data->type = RC_TYPE_RC5;
+ init_data->name = "HD PVR";
+ info.platform_data = init_data;
+ break;
+ }
+
+ return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
+ -1 : 0;
+}
+
+int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++)
+ ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter,
+ ir_devicenames[i], ir_i2c_addrs[i]);
+
+ return ret;
+}
+
static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
char *data, int len)
{
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 5efc963f9164..37f1e4c7675d 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -16,6 +16,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
+#include <media/ir-kbd-i2c.h>
#define HDPVR_MAJOR_VERSION 0
#define HDPVR_MINOR_VERSION 2
@@ -109,6 +110,9 @@ struct hdpvr_device {
/* I2C lock */
struct mutex i2c_mutex;
+ /* For passing data to ir-kbd-i2c */
+ struct IR_i2c_init_data ir_i2c_init_data;
+
/* usb control transfer buffer and lock */
struct mutex usbc_mutex;
u8 *usbc_buf;
@@ -306,6 +310,8 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
/* i2c adapter registration */
int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
+int hdpvr_register_i2c_ir(struct hdpvr_device *dev);
+
/*========================================================================*/
/* buffer management */
int hdpvr_free_buffers(struct hdpvr_device *dev);
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 7ae96367b3ab..cdf8b191f710 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -37,15 +37,15 @@ static int hexium_num;
#define HEXIUM_INPUTS 9
static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
- { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
+ { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
};
#define HEXIUM_AUDIOS 0
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index b72d0f0b8310..6ad7e1c8b922 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -38,15 +38,15 @@ static int hexium_num;
#define HEXIUM_INPUTS 9
static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
- { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
+ { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
};
#define HEXIUM_AUDIOS 0
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 27b5dfdfbb93..1a1169115716 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -467,7 +467,6 @@ static int imx074_remove(struct i2c_client *client)
icd->ops = NULL;
if (icl->free_bus)
icl->free_bus(icl);
- client->driver = NULL;
kfree(priv);
return 0;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index ce4a75375909..c87b6bc45555 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -46,7 +46,7 @@
#include <linux/i2c.h>
#include <linux/workqueue.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
/* ----------------------------------------------------------------------- */
@@ -252,7 +252,7 @@ static void ir_key_poll(struct IR_i2c *ir)
}
if (rc)
- ir_keydown(ir->input, ir_key, 0);
+ rc_keydown(ir->rc, ir_key, 0);
}
static void ir_work(struct work_struct *work)
@@ -269,22 +269,18 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
char *ir_codes = NULL;
const char *name = NULL;
- u64 ir_type = 0;
+ u64 rc_type = RC_TYPE_UNKNOWN;
struct IR_i2c *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc = NULL;
struct i2c_adapter *adap = client->adapter;
unsigned short addr = client->addr;
int err;
- ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
- err = -ENOMEM;
- goto err_out_free;
- }
+ ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
ir->c = client;
- ir->input = input_dev;
ir->polling_interval = DEFAULT_POLLING_INTERVAL;
i2c_set_clientdata(client, ir);
@@ -292,7 +288,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x64:
name = "Pixelview";
ir->get_key = get_key_pixelview;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_EMPTY;
break;
case 0x18:
@@ -300,7 +296,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x1a:
name = "Hauppauge";
ir->get_key = get_key_haup;
- ir_type = IR_TYPE_RC5;
+ rc_type = RC_TYPE_RC5;
if (hauppauge == 1) {
ir_codes = RC_MAP_HAUPPAUGE_NEW;
} else {
@@ -310,19 +306,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x30:
name = "KNC One";
ir->get_key = get_key_knc1;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_EMPTY;
break;
case 0x6b:
name = "FusionHDTV";
ir->get_key = get_key_fusionhdtv;
- ir_type = IR_TYPE_RC5;
+ rc_type = RC_TYPE_RC5;
ir_codes = RC_MAP_FUSIONHDTV_MCE;
break;
case 0x40:
name = "AVerMedia Cardbus remote";
ir->get_key = get_key_avermedia_cardbus;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
break;
}
@@ -333,9 +329,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
client->dev.platform_data;
ir_codes = init_data->ir_codes;
+ rc = init_data->rc_dev;
+
name = init_data->name;
if (init_data->type)
- ir_type = init_data->type;
+ rc_type = init_data->type;
if (init_data->polling_interval)
ir->polling_interval = init_data->polling_interval;
@@ -366,8 +364,21 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
+ if (!rc) {
+ /*
+ * If platform_data doesn't specify rc_dev, initilize it
+ * internally
+ */
+ rc = rc_allocate_device();
+ if (!rc) {
+ err = -ENOMEM;
+ goto err_out_free;
+ }
+ }
+ ir->rc = rc;
+
/* Make sure we are all setup before going on */
- if (!name || !ir->get_key || !ir_type || !ir_codes) {
+ if (!name || !ir->get_key || !rc_type || !ir_codes) {
dprintk(1, ": Unsupported device at address 0x%02x\n",
addr);
err = -ENODEV;
@@ -382,18 +393,28 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_name(&adap->dev),
dev_name(&client->dev));
- /* init + register input device */
- ir->ir_type = ir_type;
- input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
+ /*
+ * Initialize input_dev fields
+ * It doesn't make sense to allow overriding them via platform_data
+ */
+ rc->input_id.bustype = BUS_I2C;
+ rc->input_phys = ir->phys;
+ rc->input_name = ir->name;
+
+ /*
+ * Initialize the other fields of rc_dev
+ */
+ rc->map_name = ir->ir_codes;
+ rc->allowed_protos = rc_type;
+ if (!rc->driver_name)
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->input, ir->ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
printk(MODULE_NAME ": %s detected at %s [%s]\n",
- ir->input->name, ir->input->phys, adap->name);
+ ir->name, ir->phys, adap->name);
/* start polling via eventd */
INIT_DELAYED_WORK(&ir->work, ir_work);
@@ -402,6 +423,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0;
err_out_free:
+ /* Only frees rc if it were allocated internally */
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -414,7 +437,7 @@ static int ir_remove(struct i2c_client *client)
cancel_delayed_work_sync(&ir->work);
/* unregister device */
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->rc);
/* free memory */
kfree(ir);
@@ -426,6 +449,7 @@ static const struct i2c_device_id ir_kbd_id[] = {
{ "ir_video", 0 },
/* IR device specific entries should be added here */
{ "ir_rx_z8f0811_haup", 0 },
+ { "ir_rx_z8f0811_hdpvr", 0 },
{ }
};
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index be4af1fa557e..89f65914cc8e 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,9 +1,8 @@
config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
depends on VIDEO_V4L2 && PCI && I2C
- depends on INPUT # due to VIDEO_IR
select I2C_ALGOBIT
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 87afbbee2063..145e4749a69d 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -405,7 +405,8 @@ static const struct ivtv_card ivtv_card_avc2410 = {
.hw_audio_ctrl = IVTV_HW_MSP34XX,
.hw_muxer = IVTV_HW_CS53L32A,
.hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A |
- IVTV_HW_SAA7115 | IVTV_HW_TUNER,
+ IVTV_HW_SAA7115 | IVTV_HW_TUNER |
+ IVTV_HW_I2C_IR_RX_ADAPTEC,
.video_inputs = {
{ IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
{ IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
@@ -1313,7 +1314,6 @@ int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
"Composite 3"
};
- memset(input, 0, sizeof(*input));
if (index >= itv->nof_inputs)
return -EINVAL;
input->index = index;
@@ -1331,7 +1331,6 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
{
const struct ivtv_card_output *card_output = itv->card->video_outputs + index;
- memset(output, 0, sizeof(*output));
if (index >= itv->card->nof_outputs)
return -EINVAL;
output->index = index;
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 78eca992e1fd..e6f5c02981f1 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -111,6 +111,7 @@
#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
+#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21)
#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
IVTV_HW_Z8F0811_IR_TX_HAUP)
@@ -120,7 +121,8 @@
#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
IVTV_HW_I2C_IR_RX_HAUP_EXT | \
IVTV_HW_I2C_IR_RX_HAUP_INT | \
- IVTV_HW_Z8F0811_IR_RX_HAUP)
+ IVTV_HW_Z8F0811_IR_RX_HAUP | \
+ IVTV_HW_I2C_IR_RX_ADAPTEC)
#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e421d15b0f5c..39946420b301 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1029,8 +1029,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET,
IVTV_ENCODER_SIZE);
if (!itv->enc_mem) {
- IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
- IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
+ IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
+ "encoder memory\n");
+ IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of "
+ "vmalloc address space for this window\n");
+ IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
+ IVTV_ERR("Use the vmalloc= kernel command line option to set "
+ "VmallocTotal to a larger value\n");
retval = -ENOMEM;
goto free_mem;
}
@@ -1041,8 +1046,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET,
IVTV_DECODER_SIZE);
if (!itv->dec_mem) {
- IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
- IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
+ IVTV_ERR("ioremap failed. Can't get a window into "
+ "CX23415 decoder memory\n");
+ IVTV_ERR("Each capture card with a CX23415 needs 8 MB "
+ "of vmalloc address space for this window\n");
+ IVTV_ERR("Check the output of 'grep Vmalloc "
+ "/proc/meminfo'\n");
+ IVTV_ERR("Use the vmalloc= kernel command line option "
+ "to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
goto free_mem;
}
@@ -1057,8 +1068,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
itv->reg_mem =
ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
if (!itv->reg_mem) {
- IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
- IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
+ IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
+ "register space\n");
+ IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of "
+ "vmalloc address space for this window\n");
+ IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
+ IVTV_ERR("Use the vmalloc= kernel command line option to set "
+ "VmallocTotal to a larger value\n");
retval = -ENOMEM;
goto free_io;
}
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index d727485da886..c57a58523ca8 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -570,8 +570,8 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
int elems = count / sizeof(struct v4l2_sliced_vbi_data);
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- ivtv_write_vbi(itv, (const struct v4l2_sliced_vbi_data *)user_buf, elems);
- return elems * sizeof(struct v4l2_sliced_vbi_data);
+ return ivtv_write_vbi_from_user(itv,
+ (const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
}
mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9e8039ac909e..e103b8fc7452 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -94,6 +94,7 @@
#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
+#define IVTV_ADAPTEC_IR_ADDR 0x6b
/* This array should match the IVTV_HW_ defines */
static const u8 hw_addrs[] = {
@@ -118,6 +119,7 @@ static const u8 hw_addrs[] = {
IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
+ IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */
};
/* This array should match the IVTV_HW_ defines */
@@ -143,8 +145,34 @@ static const char * const hw_devicenames[] = {
"ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
"ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
"ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
+ "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */
};
+static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char keybuf[4];
+
+ keybuf[0] = 0x00;
+ i2c_master_send(ir->c, keybuf, 1);
+ /* poll IR chip */
+ if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) {
+ return 0;
+ }
+
+ /* key pressed ? */
+ if (keybuf[2] == 0xff)
+ return 0;
+
+ /* remove repeat bit */
+ keybuf[2] &= 0x7f;
+ keybuf[3] |= 0x80;
+
+ *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
+ *ir_raw = *ir_key;
+
+ return 1;
+}
+
static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
{
struct i2c_board_info info;
@@ -172,7 +200,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
init_data->internal_get_key_func =
IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
- init_data->type = IR_TYPE_OTHER;
+ init_data->type = RC_TYPE_OTHER;
init_data->name = "AVerMedia AVerTV card";
break;
case IVTV_HW_I2C_IR_RX_HAUP_EXT:
@@ -180,15 +208,22 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
/* Default to old black remote */
init_data->ir_codes = RC_MAP_RC5_TV;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
init_data->name = itv->card_name;
break;
case IVTV_HW_Z8F0811_IR_RX_HAUP:
/* Default to grey remote */
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
+ init_data->name = itv->card_name;
+ break;
+ case IVTV_HW_I2C_IR_RX_ADAPTEC:
+ init_data->get_key = get_key_adaptec;
init_data->name = itv->card_name;
+ /* FIXME: The protocol and RC_MAP needs to be corrected */
+ init_data->ir_codes = RC_MAP_EMPTY;
+ init_data->type = RC_TYPE_UNKNOWN;
break;
}
@@ -218,8 +253,6 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
const unsigned short addr_list[] = {
0x1a, /* Hauppauge IR external - collides with WM8739 */
0x18, /* Hauppauge IR internal */
- 0x71, /* Hauppauge IR (PVR150) */
- 0x6b, /* Adaptec IR */
I2C_CLIENT_END
};
@@ -239,19 +272,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
return -1;
if (hw == IVTV_HW_TUNER) {
/* special tuner handling */
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->radio);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->radio);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->demod);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->demod);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->tv);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->tv);
if (sd)
sd->grp_id = 1 << idx;
return sd ? 0 : -1;
@@ -267,17 +297,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
/* It's an I2C device other than an analog tuner or IR chip */
if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx]));
+ adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
} else if (hw == IVTV_HW_CX25840) {
struct cx25840_platform_data pdata;
pdata.pvr150_workaround = itv->pvr150_workaround;
sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
- adap, NULL, type, 0, &pdata, hw_addrs[idx],
- NULL);
+ adap, type, 0, &pdata, hw_addrs[idx], NULL);
} else {
sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type, hw_addrs[idx], NULL);
+ adap, type, hw_addrs[idx], NULL);
}
if (sd)
sd->grp_id = 1 << idx;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index e1c347e5ebd8..2dfa957b0fd5 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -92,54 +92,97 @@ static int odd_parity(u8 c)
return c & 1;
}
-void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
+static void ivtv_write_vbi_line(struct ivtv *itv,
+ const struct v4l2_sliced_vbi_data *d,
+ struct vbi_cc *cc, int *found_cc)
{
struct vbi_info *vi = &itv->vbi;
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
- int found_cc = 0;
- size_t i;
-
- for (i = 0; i < cnt; i++) {
- const struct v4l2_sliced_vbi_data *d = sliced + i;
- if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
- if (d->field) {
- cc.even[0] = d->data[0];
- cc.even[1] = d->data[1];
- } else {
- cc.odd[0] = d->data[0];
- cc.odd[1] = d->data[1];
- }
- found_cc = 1;
+ if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
+ if (d->field) {
+ cc->even[0] = d->data[0];
+ cc->even[1] = d->data[1];
+ } else {
+ cc->odd[0] = d->data[0];
+ cc->odd[1] = d->data[1];
}
- else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
- struct vbi_vps vps;
-
- vps.data[0] = d->data[2];
- vps.data[1] = d->data[8];
- vps.data[2] = d->data[9];
- vps.data[3] = d->data[10];
- vps.data[4] = d->data[11];
- if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
- vi->vps_payload = vps;
- set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
- }
+ *found_cc = 1;
+ } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
+ struct vbi_vps vps;
+
+ vps.data[0] = d->data[2];
+ vps.data[1] = d->data[8];
+ vps.data[2] = d->data[9];
+ vps.data[3] = d->data[10];
+ vps.data[4] = d->data[11];
+ if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
+ vi->vps_payload = vps;
+ set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
}
- else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
- int wss = d->data[0] | d->data[1] << 8;
+ } else if (d->id == V4L2_SLICED_WSS_625 &&
+ d->line == 23 && d->field == 0) {
+ int wss = d->data[0] | d->data[1] << 8;
- if (vi->wss_payload != wss) {
- vi->wss_payload = wss;
- set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
- }
+ if (vi->wss_payload != wss) {
+ vi->wss_payload = wss;
+ set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
}
}
- if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
- vi->cc_payload[vi->cc_payload_idx++] = cc;
+}
+
+static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
+{
+ struct vbi_info *vi = &itv->vbi;
+
+ if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
+ memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
+ sizeof(struct vbi_cc));
+ vi->cc_payload_idx++;
set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
}
}
+static void ivtv_write_vbi(struct ivtv *itv,
+ const struct v4l2_sliced_vbi_data *sliced,
+ size_t cnt)
+{
+ struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
+ int found_cc = 0;
+ size_t i;
+
+ for (i = 0; i < cnt; i++)
+ ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
+
+ if (found_cc)
+ ivtv_write_vbi_cc_lines(itv, &cc);
+}
+
+ssize_t
+ivtv_write_vbi_from_user(struct ivtv *itv,
+ const struct v4l2_sliced_vbi_data __user *sliced,
+ size_t cnt)
+{
+ struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
+ int found_cc = 0;
+ size_t i;
+ struct v4l2_sliced_vbi_data d;
+ ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
+
+ for (i = 0; i < cnt; i++) {
+ if (copy_from_user(&d, sliced + i,
+ sizeof(struct v4l2_sliced_vbi_data))) {
+ ret = -EFAULT;
+ break;
+ }
+ ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
+ }
+
+ if (found_cc)
+ ivtv_write_vbi_cc_lines(itv, &cc);
+
+ return ret;
+}
+
static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
{
int line = 0;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
index 970567b9194d..166dd0b75d0f 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -20,7 +20,10 @@
#ifndef IVTV_VBI_H
#define IVTV_VBI_H
-void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t count);
+ssize_t
+ivtv_write_vbi_from_user(struct ivtv *itv,
+ const struct v4l2_sliced_vbi_data __user *sliced,
+ size_t count);
void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
u64 pts_stamp, int streamtype);
int ivtv_used_line(struct ivtv *itv, int line, int field);
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 3b19f5b25a72..c179041d91f8 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -524,7 +524,6 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
{
struct m2mtest_q_data *q_data;
struct videobuf_queue *vq;
- int ret = 0;
vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
if (!vq)
@@ -534,12 +533,9 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
if (!q_data)
return -EINVAL;
- mutex_lock(&vq->vb_lock);
-
if (videobuf_queue_is_busy(vq)) {
v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
+ return -EBUSY;
}
q_data->fmt = find_format(f);
@@ -553,9 +549,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
-out:
- mutex_unlock(&vq->vb_lock);
- return ret;
+ return 0;
}
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
@@ -845,10 +839,12 @@ static void queue_init(void *priv, struct videobuf_queue *vq,
enum v4l2_buf_type type)
{
struct m2mtest_ctx *ctx = priv;
+ struct m2mtest_dev *dev = ctx->dev;
- videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev,
- &ctx->dev->irqlock, type, V4L2_FIELD_NONE,
- sizeof(struct m2mtest_buffer), priv, NULL);
+ videobuf_queue_vmalloc_init(vq, &m2mtest_qops, dev->v4l2_dev.dev,
+ &dev->irqlock, type, V4L2_FIELD_NONE,
+ sizeof(struct m2mtest_buffer), priv,
+ &dev->dev_mutex);
}
@@ -920,7 +916,7 @@ static const struct v4l2_file_operations m2mtest_fops = {
.open = m2mtest_open,
.release = m2mtest_release,
.poll = m2mtest_poll,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.mmap = m2mtest_mmap,
};
@@ -965,6 +961,7 @@ static int m2mtest_probe(struct platform_device *pdev)
}
*vfd = m2mtest_videodev;
+ vfd->lock = &dev->dev_mutex;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 2be23bccd3c8..48d2c2419c13 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = {
.open = meye_open,
.release = meye_release,
.mmap = meye_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = meye_poll,
};
@@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
msleep(1);
mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
- if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
- video_nr) < 0) {
- v4l2_err(v4l2_dev, "video_register_device failed\n");
- goto outvideoreg;
- }
-
mutex_init(&meye.lock);
init_waitqueue_head(&meye.proc_list);
meye.brightness = 32 << 10;
@@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
+ if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
+ video_nr) < 0) {
+ v4l2_err(v4l2_dev, "video_register_device failed\n");
+ goto outvideoreg;
+ }
+
v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
MEYE_DRIVER_VERSION);
v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index fcb4cd941853..f7fc88d240e6 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -798,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client)
icd->ops = NULL;
mt9m001_video_remove(icd);
- client->driver = NULL;
kfree(mt9m001);
return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 525a16e73285..53fa2a7bf156 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -1092,7 +1092,6 @@ static int mt9m111_remove(struct i2c_client *client)
struct soc_camera_device *icd = client->dev.platform_data;
icd->ops = NULL;
- client->driver = NULL;
kfree(mt9m111);
return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 9bd44a816ea1..7ce279c3751d 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -896,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client)
if (icd)
icd->ops = NULL;
- client->driver = NULL;
kfree(mt9t031);
return 0;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index b96171cc79f9..6a784c87e5ff 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -930,7 +930,6 @@ static int mt9v022_remove(struct i2c_client *client)
icd->ops = NULL;
mt9v022_video_remove(icd);
- client->driver = NULL;
kfree(mt9v022);
return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 5e486a88ad7c..bc0c23a1009c 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -382,10 +382,9 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
struct mx1_camera_dev *pcdev = ici->priv;
videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent,
- &pcdev->lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE,
- sizeof(struct mx1_buffer), icd, NULL);
+ &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_NONE,
+ sizeof(struct mx1_buffer), icd, &icd->video_lock);
}
static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 072bd2d1cfad..4eab1c620318 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -683,7 +683,8 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q,
videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev,
&pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE, sizeof(struct mx2_buffer), icd, NULL);
+ V4L2_FIELD_NONE, sizeof(struct mx2_buffer),
+ icd, &icd->video_lock);
}
#define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \
@@ -807,8 +808,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE;
- if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
- csicr1 |= CSICR1_INV_PCLK;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index aa871c2936b3..b9cb4a436959 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -443,7 +443,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_NONE,
sizeof(struct mx3_camera_buffer), icd,
- NULL);
+ &icd->video_lock);
}
/* First part of ipu_csi_init_interface() */
@@ -1186,13 +1186,12 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
goto egetres;
}
- mx3_cam = vmalloc(sizeof(*mx3_cam));
+ mx3_cam = vzalloc(sizeof(*mx3_cam));
if (!mx3_cam) {
dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
err = -ENOMEM;
goto ealloc;
}
- memset(mx3_cam, 0, sizeof(*mx3_cam));
mx3_cam->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(mx3_cam->clk)) {
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 94ba698d0ad4..e8846a09b026 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -59,10 +59,10 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
enum { TUNER, AUX1, AUX3, AUX3_YC };
static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
- { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
+ { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+ { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
};
/* this array holds the information, which port of the saa7146 each
@@ -185,17 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev)
}
mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "saa7111", I2C_SAA7111A, NULL);
+ "saa7111", I2C_SAA7111A, NULL);
mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6420", I2C_TEA6420_1, NULL);
+ "tea6420", I2C_TEA6420_1, NULL);
mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6420", I2C_TEA6420_2, NULL);
+ "tea6420", I2C_TEA6420_2, NULL);
mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6415c", I2C_TEA6415C, NULL);
+ "tea6415c", I2C_TEA6415C, NULL);
mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tda9840", I2C_TDA9840, NULL);
+ "tda9840", I2C_TDA9840, NULL);
mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tuner", I2C_TUNER, NULL);
+ "tuner", I2C_TUNER, NULL);
/* check if all devices are present */
if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 15f8793e325b..83de97ad971e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -2230,7 +2230,6 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
- /* need to register for a VID_HARDWARE_* ID in videodev.h */
vfd->fops = &omap_vout_fops;
vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
mutex_init(&vout->lock);
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index cbfd07f2d9da..0a2fb2bfdbfb 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -1365,12 +1365,12 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q,
videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops,
icd->dev.parent, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct omap1_cam_buf), icd, NULL);
+ sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
else
videobuf_queue_sg_init(q, &omap1_videobuf_ops,
icd->dev.parent, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct omap1_cam_buf), icd, NULL);
+ sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
/* use videobuf mode (auto)selected with the module parameter */
pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG;
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
new file mode 100644
index 000000000000..0cea0cf36679
--- /dev/null
+++ b/drivers/media/video/ov2640.c
@@ -0,0 +1,1205 @@
+/*
+ * ov2640 Camera Driver
+ *
+ * Copyright (C) 2010 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *
+ * Based on ov772x, ov9640 drivers and previous non merged implementations.
+ *
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2006, OmniVision
+ *
+ * This program is free software; you can 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/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-subdev.h>
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+
+#define VAL_SET(x, mask, rshift, lshift) \
+ ((((x) >> rshift) & mask) << lshift)
+/*
+ * DSP registers
+ * register offset for BANK_SEL == BANK_SEL_DSP
+ */
+#define R_BYPASS 0x05 /* Bypass DSP */
+#define R_BYPASS_DSP_BYPAS 0x01 /* Bypass DSP, sensor out directly */
+#define R_BYPASS_USE_DSP 0x00 /* Use the internal DSP */
+#define QS 0x44 /* Quantization Scale Factor */
+#define CTRLI 0x50
+#define CTRLI_LP_DP 0x80
+#define CTRLI_ROUND 0x40
+#define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3)
+#define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0)
+#define HSIZE 0x51 /* H_SIZE[7:0] (real/4) */
+#define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0)
+#define VSIZE 0x52 /* V_SIZE[7:0] (real/4) */
+#define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0)
+#define XOFFL 0x53 /* OFFSET_X[7:0] */
+#define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0)
+#define YOFFL 0x54 /* OFFSET_Y[7:0] */
+#define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0)
+#define VHYX 0x55 /* Offset and size completion */
+#define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7)
+#define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3)
+#define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4)
+#define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0)
+#define DPRP 0x56
+#define TEST 0x57 /* Horizontal size completion */
+#define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7)
+#define ZMOW 0x5A /* Zoom: Out Width OUTW[7:0] (real/4) */
+#define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0)
+#define ZMOH 0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */
+#define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0)
+#define ZMHH 0x5C /* Zoom: Speed and H&W completion */
+#define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4)
+#define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2)
+#define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0)
+#define BPADDR 0x7C /* SDE Indirect Register Access: Address */
+#define BPDATA 0x7D /* SDE Indirect Register Access: Data */
+#define CTRL2 0x86 /* DSP Module enable 2 */
+#define CTRL2_DCW_EN 0x20
+#define CTRL2_SDE_EN 0x10
+#define CTRL2_UV_ADJ_EN 0x08
+#define CTRL2_UV_AVG_EN 0x04
+#define CTRL2_CMX_EN 0x01
+#define CTRL3 0x87 /* DSP Module enable 3 */
+#define CTRL3_BPC_EN 0x80
+#define CTRL3_WPC_EN 0x40
+#define SIZEL 0x8C /* Image Size Completion */
+#define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6)
+#define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3)
+#define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0)
+#define HSIZE8 0xC0 /* Image Horizontal Size HSIZE[10:3] */
+#define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0)
+#define VSIZE8 0xC1 /* Image Vertical Size VSIZE[10:3] */
+#define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0)
+#define CTRL0 0xC2 /* DSP Module enable 0 */
+#define CTRL0_AEC_EN 0x80
+#define CTRL0_AEC_SEL 0x40
+#define CTRL0_STAT_SEL 0x20
+#define CTRL0_VFIRST 0x10
+#define CTRL0_YUV422 0x08
+#define CTRL0_YUV_EN 0x04
+#define CTRL0_RGB_EN 0x02
+#define CTRL0_RAW_EN 0x01
+#define CTRL1 0xC3 /* DSP Module enable 1 */
+#define CTRL1_CIP 0x80
+#define CTRL1_DMY 0x40
+#define CTRL1_RAW_GMA 0x20
+#define CTRL1_DG 0x10
+#define CTRL1_AWB 0x08
+#define CTRL1_AWB_GAIN 0x04
+#define CTRL1_LENC 0x02
+#define CTRL1_PRE 0x01
+#define R_DVP_SP 0xD3 /* DVP output speed control */
+#define R_DVP_SP_AUTO_MODE 0x80
+#define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0);
+ * = sysclk (48)/(2*[6:0]) (RAW);*/
+#define IMAGE_MODE 0xDA /* Image Output Format Select */
+#define IMAGE_MODE_Y8_DVP_EN 0x40
+#define IMAGE_MODE_JPEG_EN 0x10
+#define IMAGE_MODE_YUV422 0x00
+#define IMAGE_MODE_RAW10 0x04 /* (DVP) */
+#define IMAGE_MODE_RGB565 0x08
+#define IMAGE_MODE_HREF_VSYNC 0x02 /* HREF timing select in DVP JPEG output
+ * mode (0 for HREF is same as sensor) */
+#define IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP
+ * 1: Low byte first UYVY (C2[4] =0)
+ * VYUY (C2[4] =1)
+ * 0: High byte first YUYV (C2[4]=0)
+ * YVYU (C2[4] = 1) */
+#define RESET 0xE0 /* Reset */
+#define RESET_MICROC 0x40
+#define RESET_SCCB 0x20
+#define RESET_JPEG 0x10
+#define RESET_DVP 0x04
+#define RESET_IPU 0x02
+#define RESET_CIF 0x01
+#define REGED 0xED /* Register ED */
+#define REGED_CLK_OUT_DIS 0x10
+#define MS_SP 0xF0 /* SCCB Master Speed */
+#define SS_ID 0xF7 /* SCCB Slave ID */
+#define SS_CTRL 0xF8 /* SCCB Slave Control */
+#define SS_CTRL_ADD_AUTO_INC 0x20
+#define SS_CTRL_EN 0x08
+#define SS_CTRL_DELAY_CLK 0x04
+#define SS_CTRL_ACC_EN 0x02
+#define SS_CTRL_SEN_PASS_THR 0x01
+#define MC_BIST 0xF9 /* Microcontroller misc register */
+#define MC_BIST_RESET 0x80 /* Microcontroller Reset */
+#define MC_BIST_BOOT_ROM_SEL 0x40
+#define MC_BIST_12KB_SEL 0x20
+#define MC_BIST_12KB_MASK 0x30
+#define MC_BIST_512KB_SEL 0x08
+#define MC_BIST_512KB_MASK 0x0C
+#define MC_BIST_BUSY_BIT_R 0x02
+#define MC_BIST_MC_RES_ONE_SH_W 0x02
+#define MC_BIST_LAUNCH 0x01
+#define BANK_SEL 0xFF /* Register Bank Select */
+#define BANK_SEL_DSP 0x00
+#define BANK_SEL_SENS 0x01
+
+/*
+ * Sensor registers
+ * register offset for BANK_SEL == BANK_SEL_SENS
+ */
+#define GAIN 0x00 /* AGC - Gain control gain setting */
+#define COM1 0x03 /* Common control 1 */
+#define COM1_1_DUMMY_FR 0x40
+#define COM1_3_DUMMY_FR 0x80
+#define COM1_7_DUMMY_FR 0xC0
+#define COM1_VWIN_LSB_UXGA 0x0F
+#define COM1_VWIN_LSB_SVGA 0x0A
+#define COM1_VWIN_LSB_CIF 0x06
+#define REG04 0x04 /* Register 04 */
+#define REG04_DEF 0x20 /* Always set */
+#define REG04_HFLIP_IMG 0x80 /* Horizontal mirror image ON/OFF */
+#define REG04_VFLIP_IMG 0x40 /* Vertical flip image ON/OFF */
+#define REG04_VREF_EN 0x10
+#define REG04_HREF_EN 0x08
+#define REG04_AEC_SET(x) VAL_SET(x, 0x3, 0, 0)
+#define REG08 0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */
+#define COM2 0x09 /* Common control 2 */
+#define COM2_SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */
+ /* Output drive capability */
+#define COM2_OCAP_Nx_SET(N) (((N) - 1) & 0x03) /* N = [1x .. 4x] */
+#define PID 0x0A /* Product ID Number MSB */
+#define VER 0x0B /* Product ID Number LSB */
+#define COM3 0x0C /* Common control 3 */
+#define COM3_BAND_50H 0x04 /* 0 For Banding at 60H */
+#define COM3_BAND_AUTO 0x02 /* Auto Banding */
+#define COM3_SING_FR_SNAPSH 0x01 /* 0 For enable live video output after the
+ * snapshot sequence*/
+#define AEC 0x10 /* AEC[9:2] Exposure Value */
+#define CLKRC 0x11 /* Internal clock */
+#define CLKRC_EN 0x80
+#define CLKRC_DIV_SET(x) (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */
+#define COM7 0x12 /* Common control 7 */
+#define COM7_SRST 0x80 /* Initiates system reset. All registers are
+ * set to factory default values after which
+ * the chip resumes normal operation */
+#define COM7_RES_UXGA 0x00 /* Resolution selectors for UXGA */
+#define COM7_RES_SVGA 0x40 /* SVGA */
+#define COM7_RES_CIF 0x20 /* CIF */
+#define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */
+#define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */
+#define COM8 0x13 /* Common control 8 */
+#define COM8_DEF 0xC0 /* Banding filter ON/OFF */
+#define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */
+#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */
+#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */
+#define COM9 0x14 /* Common control 9
+ * Automatic gain ceiling - maximum AGC value [7:5]*/
+#define COM9_AGC_GAIN_2x 0x00 /* 000 : 2x */
+#define COM9_AGC_GAIN_4x 0x20 /* 001 : 4x */
+#define COM9_AGC_GAIN_8x 0x40 /* 010 : 8x */
+#define COM9_AGC_GAIN_16x 0x60 /* 011 : 16x */
+#define COM9_AGC_GAIN_32x 0x80 /* 100 : 32x */
+#define COM9_AGC_GAIN_64x 0xA0 /* 101 : 64x */
+#define COM9_AGC_GAIN_128x 0xC0 /* 110 : 128x */
+#define COM10 0x15 /* Common control 10 */
+#define COM10_PCLK_HREF 0x20 /* PCLK output qualified by HREF */
+#define COM10_PCLK_RISE 0x10 /* Data is updated at the rising edge of
+ * PCLK (user can latch data at the next
+ * falling edge of PCLK).
+ * 0 otherwise. */
+#define COM10_HREF_INV 0x08 /* Invert HREF polarity:
+ * HREF negative for valid data*/
+#define COM10_VSINC_INV 0x02 /* Invert VSYNC polarity */
+#define HSTART 0x17 /* Horizontal Window start MSB 8 bit */
+#define HEND 0x18 /* Horizontal Window end MSB 8 bit */
+#define VSTART 0x19 /* Vertical Window start MSB 8 bit */
+#define VEND 0x1A /* Vertical Window end MSB 8 bit */
+#define MIDH 0x1C /* Manufacturer ID byte - high */
+#define MIDL 0x1D /* Manufacturer ID byte - low */
+#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
+#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
+#define VV 0x26 /* AGC/AEC Fast mode operating region */
+#define VV_HIGH_TH_SET(x) VAL_SET(x, 0xF, 0, 4)
+#define VV_LOW_TH_SET(x) VAL_SET(x, 0xF, 0, 0)
+#define REG2A 0x2A /* Dummy pixel insert MSB */
+#define FRARL 0x2B /* Dummy pixel insert LSB */
+#define ADDVFL 0x2D /* LSB of insert dummy lines in Vertical direction */
+#define ADDVFH 0x2E /* MSB of insert dummy lines in Vertical direction */
+#define YAVG 0x2F /* Y/G Channel Average value */
+#define REG32 0x32 /* Common Control 32 */
+#define REG32_PCLK_DIV_2 0x80 /* PCLK freq divided by 2 */
+#define REG32_PCLK_DIV_4 0xC0 /* PCLK freq divided by 4 */
+#define ARCOM2 0x34 /* Zoom: Horizontal start point */
+#define REG45 0x45 /* Register 45 */
+#define FLL 0x46 /* Frame Length Adjustment LSBs */
+#define FLH 0x47 /* Frame Length Adjustment MSBs */
+#define COM19 0x48 /* Zoom: Vertical start point */
+#define ZOOMS 0x49 /* Zoom: Vertical start point */
+#define COM22 0x4B /* Flash light control */
+#define COM25 0x4E /* For Banding operations */
+#define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */
+#define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */
+#define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */
+#define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */
+#define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */
+#define REG60 0x60 /* AVGsel[31:24], 16-zone average weight option */
+#define HISTO_LOW 0x61 /* Histogram Algorithm Low Level */
+#define HISTO_HIGH 0x62 /* Histogram Algorithm High Level */
+
+/*
+ * ID
+ */
+#define MANUFACTURER_ID 0x7FA2
+#define PID_OV2640 0x2642
+#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF))
+
+/*
+ * Struct
+ */
+struct regval_list {
+ u8 reg_num;
+ u8 value;
+};
+
+/* Supported resolutions */
+enum ov2640_width {
+ W_QCIF = 176,
+ W_QVGA = 320,
+ W_CIF = 352,
+ W_VGA = 640,
+ W_SVGA = 800,
+ W_XGA = 1024,
+ W_SXGA = 1280,
+ W_UXGA = 1600,
+};
+
+enum ov2640_height {
+ H_QCIF = 144,
+ H_QVGA = 240,
+ H_CIF = 288,
+ H_VGA = 480,
+ H_SVGA = 600,
+ H_XGA = 768,
+ H_SXGA = 1024,
+ H_UXGA = 1200,
+};
+
+struct ov2640_win_size {
+ char *name;
+ enum ov2640_width width;
+ enum ov2640_height height;
+ const struct regval_list *regs;
+};
+
+
+struct ov2640_priv {
+ struct v4l2_subdev subdev;
+ struct ov2640_camera_info *info;
+ enum v4l2_mbus_pixelcode cfmt_code;
+ const struct ov2640_win_size *win;
+ int model;
+ u16 flag_vflip:1;
+ u16 flag_hflip:1;
+};
+
+/*
+ * Registers settings
+ */
+
+#define ENDMARKER { 0xff, 0xff }
+
+static const struct regval_list ov2640_init_regs[] = {
+ { BANK_SEL, BANK_SEL_DSP },
+ { 0x2c, 0xff },
+ { 0x2e, 0xdf },
+ { BANK_SEL, BANK_SEL_SENS },
+ { 0x3c, 0x32 },
+ { CLKRC, CLKRC_DIV_SET(1) },
+ { COM2, COM2_OCAP_Nx_SET(3) },
+ { REG04, REG04_DEF | REG04_HREF_EN },
+ { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN },
+ { COM9, COM9_AGC_GAIN_8x | 0x08},
+ { 0x2c, 0x0c },
+ { 0x33, 0x78 },
+ { 0x3a, 0x33 },
+ { 0x3b, 0xfb },
+ { 0x3e, 0x00 },
+ { 0x43, 0x11 },
+ { 0x16, 0x10 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x23, 0x00 },
+ { ARCOM2, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+ { 0x4c, 0x00 },
+ { 0x4a, 0x81 },
+ { 0x21, 0x99 },
+ { AEW, 0x40 },
+ { AEB, 0x38 },
+ { VV, VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) },
+ { 0x5c, 0x00 },
+ { 0x63, 0x00 },
+ { FLL, 0x22 },
+ { COM3, 0x38 | COM3_BAND_AUTO },
+ { REG5D, 0x55 },
+ { REG5E, 0x7d },
+ { REG5F, 0x7d },
+ { REG60, 0x55 },
+ { HISTO_LOW, 0x70 },
+ { HISTO_HIGH, 0x80 },
+ { 0x7c, 0x05 },
+ { 0x20, 0x80 },
+ { 0x28, 0x30 },
+ { 0x6c, 0x00 },
+ { 0x6d, 0x80 },
+ { 0x6e, 0x00 },
+ { 0x70, 0x02 },
+ { 0x71, 0x94 },
+ { 0x73, 0xc1 },
+ { 0x3d, 0x34 },
+ { COM7, COM7_RES_UXGA | COM7_ZOOM_EN },
+ { 0x5a, 0x57 },
+ { BD50, 0xbb },
+ { BD60, 0x9c },
+ { BANK_SEL, BANK_SEL_DSP },
+ { 0xe5, 0x7f },
+ { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL },
+ { 0x41, 0x24 },
+ { RESET, RESET_JPEG | RESET_DVP },
+ { 0x76, 0xff },
+ { 0x33, 0xa0 },
+ { 0x42, 0x20 },
+ { 0x43, 0x18 },
+ { 0x4c, 0x00 },
+ { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 },
+ { 0x88, 0x3f },
+ { 0xd7, 0x03 },
+ { 0xd9, 0x10 },
+ { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 },
+ { 0xc8, 0x08 },
+ { 0xc9, 0x80 },
+ { BPADDR, 0x00 },
+ { BPDATA, 0x00 },
+ { BPADDR, 0x03 },
+ { BPDATA, 0x48 },
+ { BPDATA, 0x48 },
+ { BPADDR, 0x08 },
+ { BPDATA, 0x20 },
+ { BPDATA, 0x10 },
+ { BPDATA, 0x0e },
+ { 0x90, 0x00 },
+ { 0x91, 0x0e },
+ { 0x91, 0x1a },
+ { 0x91, 0x31 },
+ { 0x91, 0x5a },
+ { 0x91, 0x69 },
+ { 0x91, 0x75 },
+ { 0x91, 0x7e },
+ { 0x91, 0x88 },
+ { 0x91, 0x8f },
+ { 0x91, 0x96 },
+ { 0x91, 0xa3 },
+ { 0x91, 0xaf },
+ { 0x91, 0xc4 },
+ { 0x91, 0xd7 },
+ { 0x91, 0xe8 },
+ { 0x91, 0x20 },
+ { 0x92, 0x00 },
+ { 0x93, 0x06 },
+ { 0x93, 0xe3 },
+ { 0x93, 0x03 },
+ { 0x93, 0x03 },
+ { 0x93, 0x00 },
+ { 0x93, 0x02 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x96, 0x00 },
+ { 0x97, 0x08 },
+ { 0x97, 0x19 },
+ { 0x97, 0x02 },
+ { 0x97, 0x0c },
+ { 0x97, 0x24 },
+ { 0x97, 0x30 },
+ { 0x97, 0x28 },
+ { 0x97, 0x26 },
+ { 0x97, 0x02 },
+ { 0x97, 0x98 },
+ { 0x97, 0x80 },
+ { 0x97, 0x00 },
+ { 0x97, 0x00 },
+ { 0xa4, 0x00 },
+ { 0xa8, 0x00 },
+ { 0xc5, 0x11 },
+ { 0xc6, 0x51 },
+ { 0xbf, 0x80 },
+ { 0xc7, 0x10 },
+ { 0xb6, 0x66 },
+ { 0xb8, 0xA5 },
+ { 0xb7, 0x64 },
+ { 0xb9, 0x7C },
+ { 0xb3, 0xaf },
+ { 0xb4, 0x97 },
+ { 0xb5, 0xFF },
+ { 0xb0, 0xC5 },
+ { 0xb1, 0x94 },
+ { 0xb2, 0x0f },
+ { 0xc4, 0x5c },
+ { 0xa6, 0x00 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x1b },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x00 },
+ { 0xa7, 0x18 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x19 },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x00 },
+ { 0xa7, 0x18 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x19 },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x00 },
+ { 0xa7, 0x18 },
+ { 0x7f, 0x00 },
+ { 0xe5, 0x1f },
+ { 0xe1, 0x77 },
+ { 0xdd, 0x7f },
+ { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN },
+ ENDMARKER,
+};
+
+/*
+ * Register settings for window size
+ * The preamble, setup the internal DSP to input an UXGA (1600x1200) image.
+ * Then the different zooming configurations will setup the output image size.
+ */
+static const struct regval_list ov2640_size_change_preamble_regs[] = {
+ { BANK_SEL, BANK_SEL_DSP },
+ { RESET, RESET_DVP },
+ { HSIZE8, HSIZE8_SET(W_UXGA) },
+ { VSIZE8, VSIZE8_SET(H_UXGA) },
+ { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN |
+ CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN },
+ { HSIZE, HSIZE_SET(W_UXGA) },
+ { VSIZE, VSIZE_SET(H_UXGA) },
+ { XOFFL, XOFFL_SET(0) },
+ { YOFFL, YOFFL_SET(0) },
+ { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) |
+ VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)},
+ { TEST, TEST_HSIZE_SET(W_UXGA) },
+ ENDMARKER,
+};
+
+#define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div) \
+ { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \
+ CTRLI_H_DIV_SET(h_div)}, \
+ { ZMOW, ZMOW_OUTW_SET(x) }, \
+ { ZMOH, ZMOH_OUTH_SET(y) }, \
+ { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) }, \
+ { R_DVP_SP, pclk_div }, \
+ { RESET, 0x00}
+
+static const struct regval_list ov2640_qcif_regs[] = {
+ PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4),
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_qvga_regs[] = {
+ PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4),
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_cif_regs[] = {
+ PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8),
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_vga_regs[] = {
+ PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2),
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_svga_regs[] = {
+ PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2),
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_xga_regs[] = {
+ PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2),
+ { CTRLI, 0x00},
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_sxga_regs[] = {
+ PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2),
+ { CTRLI, 0x00},
+ { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE },
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_uxga_regs[] = {
+ PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0),
+ { CTRLI, 0x00},
+ { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE },
+ ENDMARKER,
+};
+
+#define OV2640_SIZE(n, w, h, r) \
+ {.name = n, .width = w , .height = h, .regs = r }
+
+static const struct ov2640_win_size ov2640_supported_win_sizes[] = {
+ OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs),
+ OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs),
+ OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs),
+ OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs),
+ OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs),
+ OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs),
+ OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs),
+ OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs),
+};
+
+/*
+ * Register settings for pixel formats
+ */
+static const struct regval_list ov2640_format_change_preamble_regs[] = {
+ { BANK_SEL, BANK_SEL_DSP },
+ { R_BYPASS, R_BYPASS_USE_DSP },
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_yuv422_regs[] = {
+ { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
+ { 0xD7, 0x01 },
+ { 0x33, 0xa0 },
+ { 0xe1, 0x67 },
+ { RESET, 0x00 },
+ { R_BYPASS, R_BYPASS_USE_DSP },
+ ENDMARKER,
+};
+
+static const struct regval_list ov2640_rgb565_regs[] = {
+ { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
+ { 0xd7, 0x03 },
+ { RESET, 0x00 },
+ { R_BYPASS, R_BYPASS_USE_DSP },
+ ENDMARKER,
+};
+
+static enum v4l2_mbus_pixelcode ov2640_codes[] = {
+ V4L2_MBUS_FMT_UYVY8_2X8,
+ V4L2_MBUS_FMT_RGB565_2X8_LE,
+};
+
+/*
+ * Supported controls
+ */
+static const struct v4l2_queryctrl ov2640_controls[] = {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Vertically",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+};
+
+/*
+ * General functions
+ */
+static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
+{
+ return container_of(i2c_get_clientdata(client), struct ov2640_priv,
+ subdev);
+}
+
+static int ov2640_write_array(struct i2c_client *client,
+ const struct regval_list *vals)
+{
+ int ret;
+
+ while ((vals->reg_num != 0xff) || (vals->value != 0xff)) {
+ ret = i2c_smbus_write_byte_data(client,
+ vals->reg_num, vals->value);
+ dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x",
+ vals->reg_num, vals->value);
+
+ if (ret < 0)
+ return ret;
+ vals++;
+ }
+ return 0;
+}
+
+static int ov2640_mask_set(struct i2c_client *client,
+ u8 reg, u8 mask, u8 set)
+{
+ s32 val = i2c_smbus_read_byte_data(client, reg);
+ if (val < 0)
+ return val;
+
+ val &= ~mask;
+ val |= set & mask;
+
+ dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val);
+
+ return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int ov2640_reset(struct i2c_client *client)
+{
+ int ret;
+ const struct regval_list reset_seq[] = {
+ {BANK_SEL, BANK_SEL_SENS},
+ {COM7, COM7_SRST},
+ ENDMARKER,
+ };
+
+ ret = ov2640_write_array(client, reset_seq);
+ if (ret)
+ goto err;
+
+ msleep(5);
+err:
+ dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret);
+ return ret;
+}
+
+/*
+ * soc_camera_ops functions
+ */
+static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ return 0;
+}
+
+static int ov2640_set_bus_param(struct soc_camera_device *icd,
+ unsigned long flags)
+{
+ struct soc_camera_link *icl = to_soc_camera_link(icd);
+ unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
+
+ /* Only one width bit may be set */
+ if (!is_power_of_2(width_flag))
+ return -EINVAL;
+
+ if (icl->set_bus_param)
+ return icl->set_bus_param(icl, width_flag);
+
+ /*
+ * Without board specific bus width settings we support only the
+ * sensors native bus width witch are tested working
+ */
+ if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8))
+ return 0;
+
+ return 0;
+}
+
+static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd)
+{
+ struct soc_camera_link *icl = to_soc_camera_link(icd);
+ unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
+ SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_DATA_ACTIVE_HIGH;
+
+ if (icl->query_bus_param)
+ flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
+ else
+ flags |= SOCAM_DATAWIDTH_10;
+
+ return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov2640_priv *priv = to_ov2640(client);
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ ctrl->value = priv->flag_vflip;
+ break;
+ case V4L2_CID_HFLIP:
+ ctrl->value = priv->flag_hflip;
+ break;
+ }
+ return 0;
+}
+
+static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov2640_priv *priv = to_ov2640(client);
+ int ret = 0;
+ u8 val;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ val = ctrl->value ? REG04_VFLIP_IMG : 0x00;
+ priv->flag_vflip = ctrl->value ? 1 : 0;
+ ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
+ break;
+ case V4L2_CID_HFLIP:
+ val = ctrl->value ? REG04_HFLIP_IMG : 0x00;
+ priv->flag_hflip = ctrl->value ? 1 : 0;
+ ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
+ break;
+ }
+
+ return ret;
+}
+
+static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *id)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov2640_priv *priv = to_ov2640(client);
+
+ id->ident = priv->model;
+ id->revision = 0;
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov2640_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+ reg->size = 1;
+ if (reg->reg > 0xff)
+ return -EINVAL;
+
+ ret = i2c_smbus_read_byte_data(client, reg->reg);
+ if (ret < 0)
+ return ret;
+
+ reg->val = ret;
+
+ return 0;
+}
+
+static int ov2640_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (reg->reg > 0xff ||
+ reg->val > 0xff)
+ return -EINVAL;
+
+ return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
+}
+#endif
+
+/* Select the nearest higher resolution for capture */
+static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
+{
+ int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
+
+ for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
+ if (ov2640_supported_win_sizes[i].width >= *width &&
+ ov2640_supported_win_sizes[i].height >= *height) {
+ *width = ov2640_supported_win_sizes[i].width;
+ *height = ov2640_supported_win_sizes[i].height;
+ return &ov2640_supported_win_sizes[i];
+ }
+ }
+
+ *width = ov2640_supported_win_sizes[default_size].width;
+ *height = ov2640_supported_win_sizes[default_size].height;
+ return &ov2640_supported_win_sizes[default_size];
+}
+
+static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
+ enum v4l2_mbus_pixelcode code)
+{
+ struct ov2640_priv *priv = to_ov2640(client);
+ const struct regval_list *selected_cfmt_regs;
+ int ret;
+
+ /* select win */
+ priv->win = ov2640_select_win(width, height);
+
+ /* select format */
+ priv->cfmt_code = 0;
+ switch (code) {
+ case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__);
+ selected_cfmt_regs = ov2640_rgb565_regs;
+ break;
+ default:
+ case V4L2_MBUS_FMT_UYVY8_2X8:
+ dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__);
+ selected_cfmt_regs = ov2640_yuv422_regs;
+ }
+
+ /* reset hardware */
+ ov2640_reset(client);
+
+ /* initialize the sensor with default data */
+ dev_dbg(&client->dev, "%s: Init default", __func__);
+ ret = ov2640_write_array(client, ov2640_init_regs);
+ if (ret < 0)
+ goto err;
+
+ /* select preamble */
+ dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
+ ret = ov2640_write_array(client, ov2640_size_change_preamble_regs);
+ if (ret < 0)
+ goto err;
+
+ /* set size win */
+ ret = ov2640_write_array(client, priv->win->regs);
+ if (ret < 0)
+ goto err;
+
+ /* cfmt preamble */
+ dev_dbg(&client->dev, "%s: Set cfmt", __func__);
+ ret = ov2640_write_array(client, ov2640_format_change_preamble_regs);
+ if (ret < 0)
+ goto err;
+
+ /* set cfmt */
+ ret = ov2640_write_array(client, selected_cfmt_regs);
+ if (ret < 0)
+ goto err;
+
+ priv->cfmt_code = code;
+ *width = priv->win->width;
+ *height = priv->win->height;
+
+ return 0;
+
+err:
+ dev_err(&client->dev, "%s: Error %d", __func__, ret);
+ ov2640_reset(client);
+ priv->win = NULL;
+
+ return ret;
+}
+
+static int ov2640_g_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov2640_priv *priv = to_ov2640(client);
+
+ if (!priv->win) {
+ u32 width = W_SVGA, height = H_SVGA;
+ int ret = ov2640_set_params(client, &width, &height,
+ V4L2_MBUS_FMT_UYVY8_2X8);
+ if (ret < 0)
+ return ret;
+ }
+
+ mf->width = priv->win->width;
+ mf->height = priv->win->height;
+ mf->code = priv->cfmt_code;
+
+ switch (mf->code) {
+ case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+ break;
+ default:
+ case V4L2_MBUS_FMT_UYVY8_2X8:
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ }
+ mf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static int ov2640_s_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+
+ switch (mf->code) {
+ case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+ break;
+ default:
+ mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+ case V4L2_MBUS_FMT_UYVY8_2X8:
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ }
+
+ ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
+
+ return ret;
+}
+
+static int ov2640_try_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ const struct ov2640_win_size *win;
+
+ /*
+ * select suitable win
+ */
+ win = ov2640_select_win(&mf->width, &mf->height);
+
+ mf->field = V4L2_FIELD_NONE;
+
+ switch (mf->code) {
+ case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+ break;
+ default:
+ mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+ case V4L2_MBUS_FMT_UYVY8_2X8:
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ }
+
+ return 0;
+}
+
+static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ if (index >= ARRAY_SIZE(ov2640_codes))
+ return -EINVAL;
+
+ *code = ov2640_codes[index];
+ return 0;
+}
+
+static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+ a->c.left = 0;
+ a->c.top = 0;
+ a->c.width = W_UXGA;
+ a->c.height = H_UXGA;
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ return 0;
+}
+
+static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+ a->bounds.left = 0;
+ a->bounds.top = 0;
+ a->bounds.width = W_UXGA;
+ a->bounds.height = H_UXGA;
+ a->defrect = a->bounds;
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ a->pixelaspect.numerator = 1;
+ a->pixelaspect.denominator = 1;
+
+ return 0;
+}
+
+static int ov2640_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ struct ov2640_priv *priv = to_ov2640(client);
+ u8 pid, ver, midh, midl;
+ const char *devname;
+ int ret;
+
+ /*
+ * we must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant.
+ */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
+ dev_err(&client->dev, "Parent missing or invalid!\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /*
+ * check and show product ID and manufacturer ID
+ */
+ i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
+ pid = i2c_smbus_read_byte_data(client, PID);
+ ver = i2c_smbus_read_byte_data(client, VER);
+ midh = i2c_smbus_read_byte_data(client, MIDH);
+ midl = i2c_smbus_read_byte_data(client, MIDL);
+
+ switch (VERSION(pid, ver)) {
+ case PID_OV2640:
+ devname = "ov2640";
+ priv->model = V4L2_IDENT_OV2640;
+ break;
+ default:
+ dev_err(&client->dev,
+ "Product ID error %x:%x\n", pid, ver);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ dev_info(&client->dev,
+ "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+ devname, pid, ver, midh, midl);
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static struct soc_camera_ops ov2640_ops = {
+ .set_bus_param = ov2640_set_bus_param,
+ .query_bus_param = ov2640_query_bus_param,
+ .controls = ov2640_controls,
+ .num_controls = ARRAY_SIZE(ov2640_controls),
+};
+
+static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
+ .g_ctrl = ov2640_g_ctrl,
+ .s_ctrl = ov2640_s_ctrl,
+ .g_chip_ident = ov2640_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov2640_g_register,
+ .s_register = ov2640_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
+ .s_stream = ov2640_s_stream,
+ .g_mbus_fmt = ov2640_g_fmt,
+ .s_mbus_fmt = ov2640_s_fmt,
+ .try_mbus_fmt = ov2640_try_fmt,
+ .cropcap = ov2640_cropcap,
+ .g_crop = ov2640_g_crop,
+ .enum_mbus_fmt = ov2640_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov2640_subdev_ops = {
+ .core = &ov2640_subdev_core_ops,
+ .video = &ov2640_subdev_video_ops,
+};
+
+/*
+ * i2c_driver functions
+ */
+static int ov2640_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct ov2640_priv *priv;
+ struct soc_camera_device *icd = client->dev.platform_data;
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct soc_camera_link *icl;
+ int ret;
+
+ if (!icd) {
+ dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n");
+ return -EINVAL;
+ }
+
+ icl = to_soc_camera_link(icd);
+ if (!icl) {
+ dev_err(&adapter->dev,
+ "OV2640: Missing platform_data for driver\n");
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(&adapter->dev,
+ "OV2640: I2C-Adapter doesn't support SMBUS\n");
+ return -EIO;
+ }
+
+ priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&adapter->dev,
+ "Failed to allocate memory for private data!\n");
+ return -ENOMEM;
+ }
+
+ priv->info = icl->priv;
+
+ v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
+
+ icd->ops = &ov2640_ops;
+
+ ret = ov2640_video_probe(icd, client);
+ if (ret) {
+ icd->ops = NULL;
+ kfree(priv);
+ } else {
+ dev_info(&adapter->dev, "OV2640 Probed\n");
+ }
+
+ return ret;
+}
+
+static int ov2640_remove(struct i2c_client *client)
+{
+ struct ov2640_priv *priv = to_ov2640(client);
+ struct soc_camera_device *icd = client->dev.platform_data;
+
+ icd->ops = NULL;
+ kfree(priv);
+ return 0;
+}
+
+static const struct i2c_device_id ov2640_id[] = {
+ { "ov2640", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ov2640_id);
+
+static struct i2c_driver ov2640_i2c_driver = {
+ .driver = {
+ .name = "ov2640",
+ },
+ .probe = ov2640_probe,
+ .remove = ov2640_remove,
+ .id_table = ov2640_id,
+};
+
+/*
+ * Module functions
+ */
+static int __init ov2640_module_init(void)
+{
+ return i2c_add_driver(&ov2640_i2c_driver);
+}
+
+static void __exit ov2640_module_exit(void)
+{
+ i2c_del_driver(&ov2640_i2c_driver);
+}
+
+module_init(ov2640_module_init);
+module_exit(ov2640_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
+MODULE_AUTHOR("Alberto Panizzo");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index a84b770352f9..48895ef863ff 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -600,7 +600,7 @@ static int ov772x_reset(struct i2c_client *client)
static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
if (!enable) {
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
@@ -645,8 +645,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
switch (ctrl->id) {
case V4L2_CID_VFLIP:
@@ -665,7 +664,7 @@ static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
int ret = 0;
u8 val;
@@ -715,8 +714,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
id->ident = priv->model;
id->revision = 0;
@@ -955,7 +953,7 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
if (!priv->win || !priv->cfmt) {
u32 width = VGA_WIDTH, height = VGA_HEIGHT;
@@ -978,7 +976,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
int ret = ov772x_set_params(client, &mf->width, &mf->height,
mf->code);
@@ -991,8 +989,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd,
static int ov772x_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
const struct ov772x_win_size *win;
int i;
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 99e9e1d3c83b..53d88a2ab920 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -31,6 +31,8 @@
#include "ov9640.h"
+#define to_ov9640_sensor(sd) container_of(sd, struct ov9640_priv, subdev)
+
/* default register setup */
static const struct ov9640_reg ov9640_regs_dflt[] = {
{ OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
@@ -308,9 +310,7 @@ static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
/* Get status of additional camera capabilities */
static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
- struct ov9640_priv, subdev);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
switch (ctrl->id) {
case V4L2_CID_VFLIP:
@@ -327,8 +327,7 @@ static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
- struct ov9640_priv, subdev);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
int ret = 0;
@@ -360,9 +359,7 @@ static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
- struct ov9640_priv, subdev);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
id->ident = priv->model;
id->revision = priv->revision;
@@ -654,7 +651,8 @@ static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int ov9640_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
{
- struct ov9640_priv *priv = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
u8 pid, ver, midh, midl;
const char *devname;
int ret = 0;
@@ -791,7 +789,8 @@ static int ov9640_probe(struct i2c_client *client,
static int ov9640_remove(struct i2c_client *client)
{
- struct ov9640_priv *priv = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
kfree(priv);
return 0;
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 7129b50757db..7551907f8c28 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations pms_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = pms_read,
};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 55ea914c7fcd..7d5a7139a45a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -203,7 +203,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
*blen = 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
if (cptr->info->type == pvr2_ctl_enum) {
- const char **names;
+ const char * const *names;
names = cptr->info->def.type_enum.value_names;
if (pvr2_ctrl_range_check(cptr,val) == 0) {
if (names[val]) {
@@ -367,7 +367,7 @@ static const char *boolNames[] = {
static int parse_token(const char *ptr,unsigned int len,
int *valptr,
- const char **names,unsigned int namecnt)
+ const char * const *names, unsigned int namecnt)
{
char buf[33];
unsigned int slen;
@@ -559,7 +559,7 @@ int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
*len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
ret = 0;
} else if (cptr->info->type == pvr2_ctl_enum) {
- const char **names;
+ const char * const *names;
names = cptr->info->def.type_enum.value_names;
if ((val >= 0) &&
(val < cptr->info->def.type_enum.count)) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index cb4057bb07a0..ac94a8bf883e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -115,7 +115,7 @@ struct pvr2_ctl_info {
} type_int;
struct { /* enumerated control */
unsigned int count; /* enum value count */
- const char **value_names; /* symbol names */
+ const char * const *value_names; /* symbol names */
} type_enum;
struct { /* bitmask control */
unsigned int valid_bits; /* bits in use */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index bef202752cc8..66ad516bdfd9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2088,16 +2088,14 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
" Setting up with specified i2c address 0x%x",
mid, i2caddr[0]);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- NULL, fname,
- i2caddr[0], NULL);
+ fname, i2caddr[0], NULL);
} else {
pvr2_trace(PVR2_TRACE_INIT,
"Module ID %u:"
" Setting up with address probe list",
mid);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- NULL, fname,
- 0, i2caddr);
+ fname, 0, i2caddr);
}
if (!sd) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 3d7e5aab547f..281806b2df62 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -647,7 +647,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"device_register failed");
- kfree(class_dev);
+ put_device(class_dev);
return;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index aaafa0398fd5..58617fc656c2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -852,8 +852,8 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
#endif
default :
- ret = v4l_compat_translate_ioctl(file, cmd,
- arg, pvr2_v4l2_do_ioctl);
+ ret = -EINVAL;
+ break;
}
pvr2_hdw_commit_ctl(hdw);
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 6b8fbddc0747..1593f8deb810 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1386,11 +1386,16 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
{
ARG_DEF(int, qual)
+ if (pdev->iso_init) {
+ ret = -EBUSY;
+ break;
+ }
+
ARG_IN(qual)
if (ARGR(qual) < 0 || ARGR(qual) > 3)
ret = -EINVAL;
else
- ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
+ ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
if (ret >= 0)
pdev->vcompression = ARGR(qual);
break;
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3dc89da4c4e..bd1519a4ecb4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -287,14 +287,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
/* create frame buffers, and make circular ring */
for (i = 0; i < default_fbufs; i++) {
if (pdev->fbuf[i].data == NULL) {
- kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
+ kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
if (kbuf == NULL) {
PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
return -ENOMEM;
}
PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
pdev->fbuf[i].data = kbuf;
- memset(kbuf, 0, PWC_FRAME_SIZE);
}
}
@@ -899,10 +898,13 @@ int pwc_isoc_init(struct pwc_device *pdev)
/* link */
for (i = 0; i < MAX_ISO_BUFS; i++) {
ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
- if (ret)
+ if (ret) {
PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
- else
- PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
+ pdev->iso_init = 1;
+ pwc_isoc_cleanup(pdev);
+ return ret;
+ }
+ PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
}
/* All is done... */
@@ -958,7 +960,7 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
/* Stop camera, but only if we are sure the camera is still there (unplug
is signalled by EPIPE)
*/
- if (pdev->error_status && pdev->error_status != EPIPE) {
+ if (pdev->error_status != EPIPE) {
PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
usb_set_interface(pdev->udev, 0, 0);
}
@@ -967,36 +969,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
}
-int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
-{
- int ret, start;
-
- /* Stop isoc stuff */
- pwc_isoc_cleanup(pdev);
- /* Reset parameters */
- pwc_reset_buffers(pdev);
- /* Try to set video mode... */
- start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
- if (ret) {
- PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
- /* That failed... restore old mode (we know that worked) */
- start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
- if (start) {
- PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
- }
- }
- if (start == 0)
- {
- if (pwc_isoc_init(pdev) < 0)
- {
- PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
- ret = -EAGAIN; /* let's try again, who knows if it works a second time */
- }
- }
- pdev->drop_frames++; /* try to avoid garbage during switch */
- return ret; /* Return original error code */
-}
-
/*********
* sysfs
*********/
@@ -1176,7 +1148,7 @@ static int pwc_video_open(struct file *file)
/* Set some defaults */
pdev->vsnapshot = 0;
- /* Start iso pipe for video; first try the last used video size
+ /* Set video size, first try the last used video size
(or the default one); if that fails try QCIF/10 or QSIF/10;
it that fails too, give up.
*/
@@ -1203,15 +1175,6 @@ static int pwc_video_open(struct file *file)
return i;
}
- i = pwc_isoc_init(pdev);
- if (i) {
- PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
- pwc_isoc_cleanup(pdev);
- pwc_free_buffers(pdev);
- mutex_unlock(&pdev->modlock);
- return i;
- }
-
/* Initialize the webcam to sane value */
pwc_set_brightness(pdev, 0x7fff);
pwc_set_agc(pdev, 1, 0);
@@ -1326,6 +1289,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
goto err_out;
}
+ /* Start the stream (if not already started) */
+ rv = pwc_isoc_init(pdev);
+ if (rv)
+ goto err_out;
+
/* In case we're doing partial reads, we don't have to wait for a frame */
if (pdev->image_read_pos == 0) {
/* Do wait queueing according to the (doc)book */
@@ -1395,6 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
{
struct video_device *vdev = file->private_data;
struct pwc_device *pdev;
+ int ret;
if (vdev == NULL)
return -EFAULT;
@@ -1402,6 +1371,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
if (pdev == NULL)
return -EFAULT;
+ /* Start the stream (if not already started) */
+ mutex_lock(&pdev->modlock);
+ ret = pwc_isoc_init(pdev);
+ mutex_unlock(&pdev->modlock);
+ if (ret)
+ return ret;
+
poll_wait(file, &pdev->frameq, wait);
if (pdev->error_status)
return POLLERR;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 7061a03f5cf1..8ca4d22b4384 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -309,7 +309,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
pixelformat != V4L2_PIX_FMT_PWC2)
return -EINVAL;
- PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d "
+ if (pdev->iso_init)
+ return -EBUSY;
+
+ PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
"compression=%d snapshot=%d format=%c%c%c%c\n",
f->fmt.pix.width, f->fmt.pix.height, fps,
compression, snapshot,
@@ -318,14 +321,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
(pixelformat>>16)&255,
(pixelformat>>24)&255);
- ret = pwc_try_video_mode(pdev,
+ ret = pwc_set_video_mode(pdev,
f->fmt.pix.width,
f->fmt.pix.height,
fps,
compression,
snapshot);
- PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret);
+ PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
if (ret)
return ret;
@@ -359,23 +362,6 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* mmap() functions */
- case VIDIOCGMBUF:
- {
- /* Tell the user program how much memory is needed for a mmap() */
- struct video_mbuf *vm = arg;
- int i;
-
- memset(vm, 0, sizeof(*vm));
- vm->size = pwc_mbufs * pdev->len_per_image;
- vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */
- for (i = 0; i < pwc_mbufs; i++)
- vm->offsets[i] = i * pdev->len_per_image;
- break;
- }
-#endif
-
/* V4L2 Layer */
case VIDIOC_QUERYCAP:
{
@@ -882,9 +868,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_STREAMON:
{
- /* WARNING: pwc_try_video_mode() called pwc_isoc_init */
- pwc_isoc_init(pdev);
- return 0;
+ return pwc_isoc_init(pdev);
}
case VIDIOC_STREAMOFF:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 36a9c83b5f5d..16bbc6df9b07 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -275,7 +275,6 @@ extern int pwc_trace;
extern int pwc_mbufs;
/** functions in pwc-if.c */
-int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
int pwc_handle_frame(struct pwc_device *pdev);
void pwc_next_image(struct pwc_device *pdev);
int pwc_isoc_init(struct pwc_device *pdev);
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c143ed0a5270..02686771740d 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -852,7 +852,7 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
*/
videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct pxa_buffer), icd, NULL);
+ sizeof(struct pxa_buffer), icd, &icd->video_lock);
}
static u32 mclk_get_divisor(struct platform_device *pdev,
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index d2fa2d43ff19..57e11b6f19fb 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -1460,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client)
icd->ops = NULL;
if (icl->free_bus)
icl->free_bus(icl);
- client->driver = NULL;
kfree(rj54n1);
return 0;
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index a845753665c1..b63f8cafa671 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -268,7 +268,7 @@ struct s2255_dev {
struct v4l2_device v4l2_dev;
atomic_t num_channels;
int frames;
- struct mutex lock;
+ struct mutex lock; /* channels[].vdev.lock */
struct mutex open_lock;
struct usb_device *udev;
struct usb_interface *interface;
@@ -780,20 +780,14 @@ static struct videobuf_queue_ops s2255_video_qops = {
static int res_get(struct s2255_fh *fh)
{
- struct s2255_dev *dev = fh->dev;
- /* is it free? */
struct s2255_channel *channel = fh->channel;
- mutex_lock(&dev->lock);
- if (channel->resources) {
- /* no, someone else uses it */
- mutex_unlock(&dev->lock);
- return 0;
- }
+ /* is it free? */
+ if (channel->resources)
+ return 0; /* no, someone else uses it */
/* it's free, grab it */
channel->resources = 1;
fh->resources = 1;
dprintk(1, "s2255: res: get\n");
- mutex_unlock(&dev->lock);
return 1;
}
@@ -811,11 +805,8 @@ static int res_check(struct s2255_fh *fh)
static void res_free(struct s2255_fh *fh)
{
struct s2255_channel *channel = fh->channel;
- struct s2255_dev *dev = fh->dev;
- mutex_lock(&dev->lock);
channel->resources = 0;
fh->resources = 0;
- mutex_unlock(&dev->lock);
dprintk(1, "res: put\n");
}
@@ -1106,15 +1097,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
return rc;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct s2255_fh *fh = priv;
-
- return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
-}
-#endif
-
/* write to the configuration pipe, synchronously */
static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
int size)
@@ -1218,7 +1200,6 @@ static int s2255_set_mode(struct s2255_channel *channel,
__le32 *buffer;
unsigned long chn_rev;
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- mutex_lock(&dev->lock);
chn_rev = G_chnmap[channel->idx];
dprintk(3, "%s channel: %d\n", __func__, channel->idx);
/* if JPEG, set the quality */
@@ -1235,7 +1216,6 @@ static int s2255_set_mode(struct s2255_channel *channel,
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
- mutex_unlock(&dev->lock);
return -ENOMEM;
}
/* set the mode */
@@ -1260,7 +1240,6 @@ static int s2255_set_mode(struct s2255_channel *channel,
}
/* clear the restart flag */
channel->mode.restart = 0;
- mutex_unlock(&dev->lock);
dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
return res;
}
@@ -1271,13 +1250,11 @@ static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
__le32 *buffer;
u32 chn_rev;
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- mutex_lock(&dev->lock);
chn_rev = G_chnmap[channel->idx];
dprintk(4, "%s chan %d\n", __func__, channel->idx);
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
- mutex_unlock(&dev->lock);
return -ENOMEM;
}
/* form the get vid status command */
@@ -1297,7 +1274,6 @@ static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
}
*pstatus = channel->vidstatus;
dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
- mutex_unlock(&dev->lock);
return res;
}
@@ -1816,7 +1792,8 @@ static int s2255_open(struct file *file)
NULL, &dev->slock,
fh->type,
V4L2_FIELD_INTERLACED,
- sizeof(struct s2255_buffer), fh, NULL);
+ sizeof(struct s2255_buffer),
+ fh, vdev->lock);
return 0;
}
@@ -1899,7 +1876,7 @@ static const struct v4l2_file_operations s2255_fops_v4l = {
.open = s2255_open,
.release = s2255_release,
.poll = s2255_poll,
- .ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
.mmap = s2255_mmap_v4l,
};
@@ -1923,9 +1900,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidioc_cgmbuf,
-#endif
.vidioc_s_jpegcomp = vidioc_s_jpegcomp,
.vidioc_g_jpegcomp = vidioc_g_jpegcomp,
.vidioc_s_parm = vidioc_s_parm,
@@ -1969,6 +1943,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
channel->vidq.dev = dev;
/* register 4 video devices */
channel->vdev = template;
+ channel->vdev.lock = &dev->lock;
channel->vdev.v4l2_dev = &dev->v4l2_dev;
video_set_drvdata(&channel->vdev, channel);
if (video_nr == -1)
@@ -2675,7 +2650,9 @@ static void s2255_disconnect(struct usb_interface *interface)
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
int i;
int channels = atomic_read(&dev->num_channels);
+ mutex_lock(&dev->lock);
v4l2_device_disconnect(&dev->v4l2_dev);
+ mutex_unlock(&dev->lock);
/*see comments in the uvc_driver.c usb disconnect function */
atomic_inc(&dev->num_channels);
/* unregister each video device. */
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index e8f13d3e2df1..2f500809f53d 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
return ERR_PTR(-ENOMEM);
sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap,
- MODULE_NAME, isp_info->board_info, NULL);
+ isp_info->board_info, NULL);
if (!sd) {
v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n");
return NULL;
@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
fimc->vid_cap.active_buf_cnt = 0;
fimc->vid_cap.frame_count = 0;
+ fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
set_bit(ST_CAPT_PEND, &fimc->state);
ret = videobuf_streamon(&fimc->vid_cap.vbq);
@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
return ret;
}
+static int fimc_cap_cropcap(struct file *file, void *fh,
+ struct v4l2_cropcap *cr)
+{
+ struct fimc_frame *f;
+ struct fimc_ctx *ctx = fh;
+ struct fimc_dev *fimc = ctx->fimc_dev;
+
+ if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
+ f = &ctx->s_frame;
+ cr->bounds.left = 0;
+ cr->bounds.top = 0;
+ cr->bounds.width = f->o_width;
+ cr->bounds.height = f->o_height;
+ cr->defrect = cr->bounds;
+
+ mutex_unlock(&fimc->lock);
+ return 0;
+}
+
+static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+{
+ struct fimc_frame *f;
+ struct fimc_ctx *ctx = file->private_data;
+ struct fimc_dev *fimc = ctx->fimc_dev;
+
+
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
+ f = &ctx->s_frame;
+ cr->c.left = f->offs_h;
+ cr->c.top = f->offs_v;
+ cr->c.width = f->width;
+ cr->c.height = f->height;
+
+ mutex_unlock(&fimc->lock);
+ return 0;
+}
+
static int fimc_cap_s_crop(struct file *file, void *fh,
struct v4l2_crop *cr)
{
@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_cap_s_ctrl,
- .vidioc_g_crop = fimc_vidioc_g_crop,
+ .vidioc_g_crop = fimc_cap_g_crop,
.vidioc_s_crop = fimc_cap_s_crop,
- .vidioc_cropcap = fimc_vidioc_cropcap,
+ .vidioc_cropcap = fimc_cap_cropcap,
.vidioc_enum_input = fimc_cap_enum_input,
.vidioc_s_input = fimc_cap_s_input,
@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
vid_cap->v4l2_dev.dev, &fimc->irqlock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct fimc_vid_buffer), (void *)ctx);
+ sizeof(struct fimc_vid_buffer), (void *)ctx, NULL);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 2e7c547894b6..817aa66627f6 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = {
.planes_cnt = 1,
.flags = FMT_FLAGS_M2M,
}, {
- .name = "XRGB-8-8-8-8, 24 bpp",
- .fourcc = V4L2_PIX_FMT_RGB24,
+ .name = "XRGB-8-8-8-8, 32 bpp",
+ .fourcc = V4L2_PIX_FMT_RGB32,
.depth = 32,
.color = S5P_FIMC_RGB888,
.buff_cnt = 1,
@@ -543,7 +543,7 @@ static void fimc_dma_run(void *priv)
unsigned long flags;
u32 ret;
- if (WARN(!ctx, "null hardware context"))
+ if (WARN(!ctx, "null hardware context\n"))
return;
fimc = ctx->fimc_dev;
@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
{
struct fimc_ctx *ctx = priv;
struct v4l2_queryctrl *c;
+ int ret = -EINVAL;
c = get_ctrl(qc->id);
if (c) {
@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
return 0;
}
- if (ctx->state & FIMC_CTX_CAP)
- return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
+ if (ctx->state & FIMC_CTX_CAP) {
+ if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
+ return -ERESTARTSYS;
+ ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
core, queryctrl, qc);
- return -EINVAL;
+ mutex_unlock(&ctx->fimc_dev->lock);
+ }
+ return ret;
}
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
@@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
return 0;
}
-int fimc_vidioc_cropcap(struct file *file, void *fh,
+static int fimc_m2m_cropcap(struct file *file, void *fh,
struct v4l2_cropcap *cr)
{
struct fimc_frame *frame;
@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh,
return 0;
}
-int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
{
struct fimc_frame *frame;
struct fimc_ctx *ctx = file->private_data;
@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
struct fimc_frame *f;
u32 min_size, halign;
- f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
- &ctx->s_frame : &ctx->d_frame;
-
if (cr->c.top < 0 || cr->c.left < 0) {
v4l2_err(&fimc->m2m.v4l2_dev,
"doesn't support negative values for top & left\n");
return -EINVAL;
}
- f = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
+ if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame;
+ else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ ctx->state & FIMC_CTX_M2M)
+ f = &ctx->s_frame;
+ else
+ return -EINVAL;
- min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- ? fimc->variant->min_inp_pixsize
- : fimc->variant->min_out_pixsize;
+ min_size = (f == &ctx->s_frame) ?
+ fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
if (ctx->state & FIMC_CTX_M2M) {
if (fimc->id == 1 && fimc->variant->pix_hoff)
@@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
&ctx->s_frame : &ctx->d_frame;
+ if (mutex_lock_interruptible(&fimc->lock))
+ return -ERESTARTSYS;
+
spin_lock_irqsave(&ctx->slock, flags);
if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
/* Check to see if scaling ratio is within supported range */
@@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
else
ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
if (ret) {
- spin_unlock_irqrestore(&ctx->slock, flags);
v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
- return -EINVAL;
+ ret = -EINVAL;
+ goto scr_unlock;
}
}
ctx->state |= FIMC_PARAMS;
@@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
f->width = cr->c.width;
f->height = cr->c.height;
+scr_unlock:
spin_unlock_irqrestore(&ctx->slock, flags);
+ mutex_unlock(&fimc->lock);
return 0;
}
@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
.vidioc_s_ctrl = fimc_m2m_s_ctrl,
- .vidioc_g_crop = fimc_vidioc_g_crop,
+ .vidioc_g_crop = fimc_m2m_g_crop,
.vidioc_s_crop = fimc_m2m_s_crop,
- .vidioc_cropcap = fimc_vidioc_cropcap
+ .vidioc_cropcap = fimc_m2m_cropcap
};
@@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = {
.open = fimc_m2m_open,
.release = fimc_m2m_release,
.poll = fimc_m2m_poll,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.mmap = fimc_m2m_mmap,
};
@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
.pix_hoff = 1,
.has_inp_rot = 1,
.has_out_rot = 1,
+ .has_cistatus2 = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 1,
@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
.pix_hoff = 1,
+ .has_cistatus2 = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 1,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 3e1078516560..4f047d35f8ad 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -13,13 +13,15 @@
/*#define DEBUG*/
+#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/videodev2.h>
#include <media/videobuf-core.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-mediabus.h>
#include <media/s3c_fimc.h>
-#include <linux/videodev2.h>
+
#include "regs-fimc.h"
#define err(fmt, args...) \
@@ -369,6 +371,7 @@ struct fimc_pix_limit {
* @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
* @has_inp_rot: set if has input rotator
* @has_out_rot: set if has output rotator
+ * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
* @pix_limit: pixel size constraints for the scaler
* @min_inp_pixsize: minimum input pixel size
* @min_out_pixsize: minimum output pixel size
@@ -379,6 +382,7 @@ struct samsung_fimc_variant {
unsigned int pix_hoff:1;
unsigned int has_inp_rot:1;
unsigned int has_out_rot:1;
+ unsigned int has_cistatus2:1;
struct fimc_pix_limit *pix_limit;
u16 min_inp_pixsize;
u16 min_out_pixsize;
@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
return frame;
}
+/* Return an index to the buffer actually being written. */
static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
{
- u32 reg = readl(dev->regs + S5P_CISTATUS);
- return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
- S5P_CISTATUS_FRAMECNT_SHIFT;
+ u32 reg;
+
+ if (dev->variant->has_cistatus2) {
+ reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
+ return reg > 0 ? --reg : reg;
+ } else {
+ reg = readl(dev->regs + S5P_CISTATUS);
+ return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
+ S5P_CISTATUS_FRAMECNT_SHIFT;
+ }
}
/* -----------------------------------------------------*/
@@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv,
struct v4l2_format *f);
int fimc_vidioc_try_fmt(struct file *file, void *priv,
struct v4l2_format *f);
-int fimc_vidioc_g_crop(struct file *file, void *fh,
- struct v4l2_crop *cr);
-int fimc_vidioc_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cr);
int fimc_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc);
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
index a57daedb5b5c..57e33f84fcfa 100644
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ b/drivers/media/video/s5p-fimc/regs-fimc.h
@@ -165,6 +165,9 @@
#define S5P_CISTATUS_VVALID_A (1 << 15)
#define S5P_CISTATUS_VVALID_B (1 << 14)
+/* Indexes to the last and the currently processed buffer. */
+#define S5P_CISTATUS2 0x68
+
/* Image capture control */
#define S5P_CIIMGCPT 0xc0
#define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 984c0feb2a4e..99a2ac16f9e5 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,7 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
-#include <media/rds.h>
+#include <media/saa6588.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
@@ -181,7 +181,7 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
return 1;
}
-static void read_from_buf(struct saa6588 *s, struct rds_command *a)
+static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
{
unsigned long flags;
@@ -392,25 +392,25 @@ static void saa6588_configure(struct saa6588 *s)
static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
struct saa6588 *s = to_saa6588(sd);
- struct rds_command *a = arg;
+ struct saa6588_command *a = arg;
switch (cmd) {
/* --- open() for /dev/radio --- */
- case RDS_CMD_OPEN:
+ case SAA6588_CMD_OPEN:
a->result = 0; /* return error if chip doesn't work ??? */
break;
/* --- close() for /dev/radio --- */
- case RDS_CMD_CLOSE:
+ case SAA6588_CMD_CLOSE:
s->data_available_for_read = 1;
wake_up_interruptible(&s->read_queue);
a->result = 0;
break;
/* --- read() for /dev/radio --- */
- case RDS_CMD_READ:
+ case SAA6588_CMD_READ:
read_from_buf(s, a);
break;
/* --- poll() for /dev/radio --- */
- case RDS_CMD_POLL:
+ case SAA6588_CMD_POLL:
a->result = 0;
if (s->data_available_for_read) {
a->result |= POLLIN | POLLRDNORM;
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 301c62b88cad..f35459d1f42f 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1348,8 +1348,17 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
int reg1e;
*std = V4L2_STD_ALL;
- if (state->ident != V4L2_IDENT_SAA7115)
+ if (state->ident != V4L2_IDENT_SAA7115) {
+ int reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
+
+ if (reg1f & 0x20)
+ *std = V4L2_STD_525_60;
+ else
+ *std = V4L2_STD_625_50;
+
return 0;
+ }
+
reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
switch (reg1e & 0x03) {
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 3fe71be41a1f..380f1b28cfcc 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -26,7 +26,7 @@ config VIDEO_SAA7134_ALSA
config VIDEO_SAA7134_RC
bool "Philips SAA7134 Remote Controller support"
- depends on VIDEO_IR
+ depends on RC_CORE
depends on VIDEO_SAA7134
default y
---help---
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0911cb580e18..e7aa588c6c5a 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5176,6 +5176,58 @@ struct saa7134_board saa7134_boards[] = {
.amux = 2,
},
},
+ [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
+ .name = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
+ .audio_clock = 0x00187de7,
+#if 0
+ /*
+ * FIXME: Analog mode doesn't work, if digital is enabled. The proper
+ * fix is to use tda8290 driver, but Kworld seems to use an
+ * unsupported version of tda8295.
+ */
+ .tuner_type = TUNER_NXP_TDA18271, /* TUNER_PHILIPS_TDA8290 */
+ .tuner_addr = 0x60,
+#else
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+#endif
+ .radio_type = UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x8e054000,
+ .mpeg = SAA7134_MPEG_DVB,
+ .ts_type = SAA7134_MPEG_TS_PARALLEL,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+#if 0 /* FIXME */
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x200,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x200,
+#endif
+ } },
+#if 0
+ .radio = {
+ .name = name_radio,
+ .vmux = 1,
+ .amux = LINE1,
+ .gpio = 0x100,
+ },
+#endif
+ .mute = {
+ .name = name_mute,
+ .vmux = 0,
+ .amux = TV,
+ },
+ },
[SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = {
.name = "Avermedia AVerTV GO 007 FM Plus",
.audio_clock = 0x00187de7,
@@ -5486,6 +5538,37 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
} },
},
+ [SAA7134_BOARD_VIDEOMATE_M1F] = {
+ /* Pavel Osnova <pvosnova@gmail.com> */
+ .name = "Compro VideoMate Vista M1F",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = 0x60,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ },
+ },
};
@@ -6615,6 +6698,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
}, {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0xb136,
+ .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0xf31d,
.driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
@@ -6673,6 +6762,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x7090,
.driver_data = SAA7134_BOARD_BEHOLD_A7,
}, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .subvendor = 0x185b,
+ .subdevice = 0xc900,
+ .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
+ }, {
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6831,6 +6926,23 @@ static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
return 0;
}
+static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
+ enum tda18271_mode mode)
+{
+ /* toggle AGC switch through GPIO 27 */
+ switch (mode) {
+ case TDA18271_ANALOG:
+ saa7134_set_gpio(dev, 27, 0);
+ break;
+ case TDA18271_DIGITAL:
+ saa7134_set_gpio(dev, 27, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
int command, int arg)
{
@@ -6843,6 +6955,9 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
break;
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg);
+ break;
default:
break;
}
@@ -6863,6 +6978,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
case SAA7134_BOARD_HAUPPAUGE_HVR1150:
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
case SAA7134_BOARD_AVERMEDIA_M733A:
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
/* tda8290 + tda18271 */
ret = saa7134_tda8290_18271_callback(dev, command, arg);
break;
@@ -6967,6 +7083,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
+ case SAA7134_BOARD_VIDEOMATE_M1F:
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
@@ -7541,6 +7658,37 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name);
break;
}
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ {
+ struct i2c_msg msg = { .addr = 0x4b, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ {0x30, 0x31},
+ {0xff, 0x00},
+ {0x41, 0x03},
+ {0x41, 0x1a},
+ {0xff, 0x02},
+ {0x34, 0x00},
+ {0x45, 0x97},
+ {0x45, 0xc1},
+ };
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
+
+ /*
+ * FIXME: identify what device is at addr 0x4b and what means
+ * this initialization
+ */
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
} /* switch() */
/* initialize tuner */
@@ -7551,22 +7699,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
so we do not need to probe for a radio tuner device. */
if (dev->radio_type != UNSET)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
dev->radio_addr, NULL);
if (has_demod)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (dev->tuner_addr == ADDR_UNSET) {
enum v4l2_i2c_tuner_type type =
has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(type));
} else {
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
dev->tuner_addr, NULL);
}
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 764d7d219fed..756a27812260 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (card_is_empress(dev)) {
struct v4l2_subdev *sd =
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "saa6752hs",
+ "saa6752hs",
saa7134_boards[dev->board].empress_addr, NULL);
if (sd)
@@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "saa6588",
+ &dev->i2c_adap, "saa6588",
0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
if (sd) {
printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index beb95e21d109..3315a48a848b 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -52,6 +52,7 @@
#include "tda18271.h"
#include "lgdt3305.h"
#include "tda8290.h"
+#include "mb86a20s.h"
#include "zl10353.h"
@@ -228,6 +229,20 @@ static struct mt352_config avermedia_xc3028_mt352_dev = {
.demod_init = mt352_avermedia_xc3028_init,
};
+static struct tda18271_std_map mb86a20s_tda18271_std_map = {
+ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+ .if_lvl = 7, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config kworld_tda18271_config = {
+ .std_map = &mb86a20s_tda18271_std_map,
+ .gate = TDA18271_GATE_DIGITAL,
+};
+
+static const struct mb86a20s_config kworld_mb86a20s_config = {
+ .demod_address = 0x10,
+};
+
/* ==================================================================
* tda1004x based DVB-T cards, helper functions
*/
@@ -608,6 +623,37 @@ static struct tda827x_config tda827x_cfg_2_sw42 = {
/* ------------------------------------------------------------------ */
+static int __kworld_sbtvd_i2c_gate_ctrl(struct saa7134_dev *dev, int enable)
+{
+ unsigned char initmsg[] = {0x45, 0x97};
+ unsigned char msg_enable[] = {0x45, 0xc1};
+ unsigned char msg_disable[] = {0x45, 0x81};
+ struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2};
+
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+ wprintk("could not access the I2C gate\n");
+ return -EIO;
+ }
+ if (enable)
+ msg.buf = msg_enable;
+ else
+ msg.buf = msg_disable;
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+ wprintk("could not access the I2C gate\n");
+ return -EIO;
+ }
+ msleep(20);
+ return 0;
+}
+static int kworld_sbtvd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+
+ return __kworld_sbtvd_i2c_gate_ctrl(dev, enable);
+}
+
+/* ------------------------------------------------------------------ */
+
static struct tda1004x_config tda827x_lifeview_config = {
.demod_address = 0x08,
.invert = 1,
@@ -1613,6 +1659,29 @@ static int dvb_init(struct saa7134_dev *dev)
&dtv1000s_tda18271_config);
}
break;
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ __kworld_sbtvd_i2c_gate_ctrl(dev, 0);
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
+ msleep(20);
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
+ msleep(20);
+ fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
+ &kworld_mb86a20s_config,
+ &dev->i2c_adap);
+ __kworld_sbtvd_i2c_gate_ctrl(dev, 1);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_adap,
+ &kworld_tda18271_config);
+ /*
+ * Only after success, it can initialize the gate, otherwise
+ * an OOPS will hit, due to kfree(fe0->dvb.frontend)
+ */
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_i2c_gate_ctrl;
+ }
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 46d31dfca7a3..dc646e65edb7 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/slab.h>
#include "saa7134-reg.h"
@@ -42,41 +41,19 @@ static int pinnacle_remote;
module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */
MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)");
-static int ir_rc5_remote_gap = 885;
-module_param(ir_rc5_remote_gap, int, 0644);
-static int ir_rc5_key_timeout = 115;
-module_param(ir_rc5_key_timeout, int, 0644);
-
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
-MODULE_PARM_DESC(repeat_period, "repeat period between "
- "keypresses when key is down");
-
-static unsigned int disable_other_ir;
-module_param(disable_other_ir, int, 0644);
-MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
- "alternative remotes from other manufacturers");
-
#define dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
#define i2cdprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
-/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
-static int saa7134_rc5_irq(struct saa7134_dev *dev);
-static int saa7134_nec_irq(struct saa7134_dev *dev);
+/* Helper function for raw decoding at GPIO16 or GPIO18 */
static int saa7134_raw_decode_irq(struct saa7134_dev *dev);
-static void nec_task(unsigned long data);
-static void saa7134_nec_timer(unsigned long data);
/* -------------------- GPIO generic keycode builder -------------------- */
static int build_key(struct saa7134_dev *dev)
{
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
u32 gpio, data;
/* here comes the additional handshake steps for some cards */
@@ -104,25 +81,25 @@ static int build_key(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
if (data == ir->mask_keycode)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
else
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
return 0;
}
if (ir->polling) {
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
} else {
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
}
}
else { /* IRQ driven mode - handle key press and release in one go */
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keyup(ir->dev);
}
}
@@ -300,22 +277,12 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
i2cdprintk("read error\n");
return -EIO;
}
- /* IR of this card normally decode signals NEC-standard from
- * - Sven IHOO MT 5.1R remote. xxyye718
- * - Sven DVD HD-10xx remote. xxyyf708
- * - BBK ...
- * - mayby others
- * So, skip not our, if disable full codes mode.
- */
- if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir)
- return 0;
- /* Wrong data decode fix */
if (data[9] != (unsigned char)(~data[8]))
return 0;
- *ir_key = data[9];
- *ir_raw = data[9];
+ *ir_raw = ((data[10] << 16) | (data[11] << 8) | (data[9] << 0));
+ *ir_key = *ir_raw;
return 1;
}
@@ -400,7 +367,7 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
void saa7134_input_irq(struct saa7134_dev *dev)
{
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
if (!dev || !dev->remote)
return;
@@ -409,12 +376,8 @@ void saa7134_input_irq(struct saa7134_dev *dev)
if (!ir->running)
return;
- if (ir->nec_gpio) {
- saa7134_nec_irq(dev);
- } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) {
+ if (!ir->polling && !ir->raw_decode) {
build_key(dev);
- } else if (ir->rc5_gpio) {
- saa7134_rc5_irq(dev);
} else if (ir->raw_decode) {
saa7134_raw_decode_irq(dev);
}
@@ -423,7 +386,7 @@ void saa7134_input_irq(struct saa7134_dev *dev)
static void saa7134_input_timer(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
build_key(dev);
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
@@ -432,57 +395,37 @@ static void saa7134_input_timer(unsigned long data)
static void ir_raw_decode_timer_end(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
ir_raw_event_handle(dev->remote->dev);
- ir->active = 0;
+ ir->active = false;
}
static int __saa7134_ir_start(void *priv)
{
struct saa7134_dev *dev = priv;
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
- if (!dev)
+ if (!dev || !dev->remote)
return -EINVAL;
ir = dev->remote;
- if (!ir)
- return -EINVAL;
-
if (ir->running)
return 0;
- ir->running = 1;
+ ir->running = true;
+ ir->active = false;
+
if (ir->polling) {
setup_timer(&ir->timer, saa7134_input_timer,
(unsigned long)dev);
- ir->timer.expires = jiffies + HZ;
+ ir->timer.expires = jiffies + HZ;
add_timer(&ir->timer);
- } else if (ir->rc5_gpio) {
- /* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_rc5_timer_end;
- ir->timer_end.data = (unsigned long)ir;
- init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = ir_rc5_timer_keyup;
- ir->timer_keyup.data = (unsigned long)ir;
- ir->shift_by = 2;
- ir->start = 0x2;
- ir->addr = 0x17;
- ir->rc5_key_timeout = ir_rc5_key_timeout;
- ir->rc5_remote_gap = ir_rc5_remote_gap;
- } else if (ir->nec_gpio) {
- setup_timer(&ir->timer_keyup, saa7134_nec_timer,
- (unsigned long)dev);
- tasklet_init(&ir->tlet, nec_task, (unsigned long)dev);
} else if (ir->raw_decode) {
/* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_raw_decode_timer_end;
- ir->timer_end.data = (unsigned long)dev;
- ir->active = 0;
+ setup_timer(&ir->timer, ir_raw_decode_timer_end,
+ (unsigned long)dev);
}
return 0;
@@ -491,29 +434,20 @@ static int __saa7134_ir_start(void *priv)
static void __saa7134_ir_stop(void *priv)
{
struct saa7134_dev *dev = priv;
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
- if (!dev)
+ if (!dev || !dev->remote)
return;
ir = dev->remote;
- if (!ir)
- return;
-
if (!ir->running)
return;
- if (dev->remote->polling)
- del_timer_sync(&dev->remote->timer);
- else if (ir->rc5_gpio)
- del_timer_sync(&ir->timer_end);
- else if (ir->nec_gpio)
- tasklet_kill(&ir->tlet);
- else if (ir->raw_decode) {
- del_timer_sync(&ir->timer_end);
- ir->active = 0;
- }
- ir->running = 0;
+ if (ir->polling || ir->raw_decode)
+ del_timer_sync(&ir->timer);
+
+ ir->active = false;
+ ir->running = false;
return;
}
@@ -532,71 +466,33 @@ void saa7134_ir_stop(struct saa7134_dev *dev)
__saa7134_ir_stop(dev);
}
-static int saa7134_ir_open(void *priv)
+static int saa7134_ir_open(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users++;
return __saa7134_ir_start(dev);
}
-static void saa7134_ir_close(void *priv)
+static void saa7134_ir_close(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users--;
if (!dev->remote->users)
__saa7134_ir_stop(dev);
}
-
-static int saa7134_ir_change_protocol(void *priv, u64 ir_type)
-{
- struct saa7134_dev *dev = priv;
- struct card_ir *ir = dev->remote;
- u32 nec_gpio, rc5_gpio;
-
- if (ir_type == IR_TYPE_RC5) {
- dprintk("Changing protocol to RC5\n");
- nec_gpio = 0;
- rc5_gpio = 1;
- } else if (ir_type == IR_TYPE_NEC) {
- dprintk("Changing protocol to NEC\n");
- nec_gpio = 1;
- rc5_gpio = 0;
- } else {
- dprintk("IR protocol type %ud is not supported\n",
- (unsigned)ir_type);
- return -EINVAL;
- }
-
- if (ir->running) {
- saa7134_ir_stop(dev);
- ir->nec_gpio = nec_gpio;
- ir->rc5_gpio = rc5_gpio;
- saa7134_ir_start(dev);
- } else {
- ir->nec_gpio = nec_gpio;
- ir->rc5_gpio = rc5_gpio;
- }
-
- return 0;
-}
-
int saa7134_input_init1(struct saa7134_dev *dev)
{
- struct card_ir *ir;
- struct input_dev *input_dev;
+ struct saa7134_card_ir *ir;
+ struct rc_dev *rc;
char *ir_codes = NULL;
u32 mask_keycode = 0;
u32 mask_keydown = 0;
u32 mask_keyup = 0;
- int polling = 0;
- int rc5_gpio = 0;
- int nec_gpio = 0;
- int raw_decode = 0;
- int allow_protocol_change = 0;
- u64 ir_type = IR_TYPE_OTHER;
+ unsigned polling = 0;
+ bool raw_decode = false;
int err;
if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -661,14 +557,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_AVERMEDIA_M733A:
ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6;
mask_keydown = 0x0040000;
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_AVERMEDIA_777:
case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -775,7 +671,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_ENCORE_ENLTV:
case SAA7134_BOARD_ENCORE_ENLTV_FM:
@@ -786,9 +682,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ENCORE_ENLTV_FM53:
ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
- mask_keydown = 0x0040000;
- mask_keycode = 0x00007f;
- nec_gpio = 1;
+ mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
+ mask_keyup = 0x0040000;
+ mask_keycode = 0xffff;
+ raw_decode = true;
break;
case SAA7134_BOARD_10MOONSTVMASTER3:
ir_codes = RC_MAP_ENCORE_ENLTV;
@@ -824,6 +721,11 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keyup = 0x020000;
polling = 50; /* ms */
break;
+ case SAA7134_BOARD_VIDEOMATE_M1F:
+ ir_codes = RC_MAP_VIDEOMATE_M1F;
+ mask_keycode = 0x0ff00;
+ mask_keyup = 0x040000;
+ break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
@@ -832,24 +734,20 @@ int saa7134_input_init1(struct saa7134_dev *dev)
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
+ rc = rc_allocate_device();
+ if (!ir || !rc) {
err = -ENOMEM;
goto err_out_free;
}
- ir->dev = input_dev;
+ ir->dev = rc;
dev->remote = ir;
- ir->running = 0;
-
/* init hardware-specific stuff */
ir->mask_keycode = mask_keycode;
ir->mask_keydown = mask_keydown;
ir->mask_keyup = mask_keyup;
ir->polling = polling;
- ir->rc5_gpio = rc5_gpio;
- ir->nec_gpio = nec_gpio;
ir->raw_decode = raw_decode;
/* init input device */
@@ -858,47 +756,35 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci));
-
- ir->props.priv = dev;
- ir->props.open = saa7134_ir_open;
- ir->props.close = saa7134_ir_close;
-
+ rc->priv = dev;
+ rc->open = saa7134_ir_open;
+ rc->close = saa7134_ir_close;
if (raw_decode)
- ir->props.driver_type = RC_DRIVER_IR_RAW;
-
- if (!raw_decode && allow_protocol_change) {
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.change_protocol = saa7134_ir_change_protocol;
- }
-
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
+ rc->driver_type = RC_DRIVER_IR_RAW;
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- input_dev->id.vendor = dev->pci->subsystem_vendor;
- input_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- input_dev->id.vendor = dev->pci->vendor;
- input_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- input_dev->dev.parent = &dev->pci->dev;
+ rc->dev.parent = &dev->pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_free:
+ rc_free_device(rc);
dev->remote = NULL;
kfree(ir);
return err;
@@ -910,7 +796,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
return;
saa7134_ir_stop(dev);
- ir_input_unregister(dev->remote->dev);
+ rc_unregister_device(dev->remote->dev);
kfree(dev->remote);
dev->remote = NULL;
}
@@ -918,14 +804,12 @@ void saa7134_input_fini(struct saa7134_dev *dev)
void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
{
struct i2c_board_info info;
-
struct i2c_msg msg_msi = {
.addr = 0x50,
.flags = I2C_M_RD,
.len = 0,
.buf = NULL,
};
-
int rc;
if (disable_ir) {
@@ -972,7 +856,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
an existing device. Weird...
REVISIT: might no longer be needed */
rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
- dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+ dprintk("probe 0x%02x @ %s: %s\n",
msg_msi.addr, dev->i2c_adap.name,
(1 == rc) ? "yes" : "no");
break;
@@ -1000,7 +884,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
dev->init_data.name = "BeholdTV";
dev->init_data.get_key = get_key_beholdm6xx;
dev->init_data.ir_codes = RC_MAP_BEHOLD;
- dev->init_data.type = IR_TYPE_NEC;
+ dev->init_data.type = RC_TYPE_NEC;
info.addr = 0x2d;
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
@@ -1025,8 +909,8 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
{
- struct card_ir *ir = dev->remote;
- unsigned long timeout;
+ struct saa7134_card_ir *ir = dev->remote;
+ unsigned long timeout;
int space;
/* Generate initial event */
@@ -1035,7 +919,6 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
-
/*
* Wait 15 ms from the start of the first IR event before processing
* the event. This time is enough for NEC protocol. May need adjustments
@@ -1043,173 +926,9 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
*/
if (!ir->active) {
timeout = jiffies + jiffies_to_msecs(15);
- mod_timer(&ir->timer_end, timeout);
- ir->active = 1;
+ mod_timer(&ir->timer, timeout);
+ ir->active = true;
}
return 1;
}
-
-static int saa7134_rc5_irq(struct saa7134_dev *dev)
-{
- struct card_ir *ir = dev->remote;
- struct timeval tv;
- u32 gap;
- unsigned long current_jiffies, timeout;
-
- /* get time of bit */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* active code => add bit */
- if (ir->active) {
- /* only if in the code (otherwise spurious IRQ or timer
- late) */
- if (ir->last_bit < 28) {
- ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
- ir_rc5_remote_gap;
- ir->code |= 1 << ir->last_bit;
- }
- /* starting new code */
- } else {
- ir->active = 1;
- ir->code = 0;
- ir->base_time = tv;
- ir->last_bit = 0;
-
- timeout = current_jiffies + (500 + 30 * HZ) / 1000;
- mod_timer(&ir->timer_end, timeout);
- }
-
- return 1;
-}
-
-/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms
- The first pulse (start) has 9 + 4.5 ms
- */
-
-static void saa7134_nec_timer(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *) data;
- struct card_ir *ir = dev->remote;
-
- dprintk("Cancel key repeat\n");
-
- ir_input_nokey(ir->dev, &ir->ir);
-}
-
-static void nec_task(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *) data;
- struct card_ir *ir;
- struct timeval tv;
- int count, pulse, oldpulse, gap;
- u32 ircode = 0, not_code = 0;
- int ngap = 0;
-
- if (!data) {
- printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n");
- /* GPIO will be kept disabled */
- return;
- }
-
- ir = dev->remote;
-
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
- pulse = oldpulse;
-
- do_gettimeofday(&tv);
- ir->base_time = tv;
-
- /* Decode NEC pulsecode. This code can take up to 76.5 ms to run.
- Unfortunately, using IRQ to decode pulse didn't work, since it uses
- a pulse train of 38KHz. This means one pulse on each 52 us
- */
- do {
- /* Wait until the end of pulse/space or 5 ms */
- for (count = 0; count < 500; count++) {
- udelay(10);
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)
- & ir->mask_keydown;
- if (pulse != oldpulse)
- break;
- }
-
- do_gettimeofday(&tv);
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
-
- if (!pulse) {
- /* Bit 0 has 560 us, while bit 1 has 1120 us.
- Do something only if bit == 1
- */
- if (ngap && (gap > 560 + 280)) {
- unsigned int shift = ngap - 1;
-
- /* Address first, then command */
- if (shift < 8) {
- shift += 8;
- ircode |= 1 << shift;
- } else if (shift < 16) {
- not_code |= 1 << shift;
- } else if (shift < 24) {
- shift -= 16;
- ircode |= 1 << shift;
- } else {
- shift -= 24;
- not_code |= 1 << shift;
- }
- }
- ngap++;
- }
-
-
- ir->base_time = tv;
-
- /* TIMEOUT - Long pulse */
- if (gap >= 5000)
- break;
- oldpulse = pulse;
- } while (ngap < 32);
-
- if (ngap == 32) {
- /* FIXME: should check if not_code == ~ircode */
- ir->code = ir_extract_bits(ircode, ir->mask_keycode);
-
- dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
- ir->code, ircode, not_code);
-
- ir_input_keydown(ir->dev, &ir->ir, ir->code);
- } else
- dprintk("Repeat last key\n");
-
- /* Keep repeating the last key */
- mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150));
-
- saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
-}
-
-static int saa7134_nec_irq(struct saa7134_dev *dev)
-{
- struct card_ir *ir = dev->remote;
-
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
- tasklet_schedule(&ir->tlet);
-
- return 1;
-}
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 3e7d2fd1688f..57e646bb48b3 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -550,16 +550,16 @@ static int tvaudio_thread(void *data)
} else if (0 != dev->last_carrier) {
/* no carrier -- try last detected one as fallback */
carrier = dev->last_carrier;
- dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
- "using %d.%03d MHz [last detected]\n",
- dev->name, carrier/1000, carrier%1000);
+ dprintk("audio carrier scan failed, "
+ "using %d.%03d MHz [last detected]\n",
+ carrier/1000, carrier%1000);
} else {
/* no carrier + no fallback -- use default */
carrier = default_carrier;
- dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
- "using %d.%03d MHz [default]\n",
- dev->name, carrier/1000, carrier%1000);
+ dprintk("audio carrier scan failed, "
+ "using %d.%03d MHz [default]\n",
+ carrier/1000, carrier%1000);
}
tvaudio_setcarrier(dev,carrier,carrier);
dev->automute = 0;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index f0b1573137f4..776ba2dd7f9f 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,7 +30,7 @@
#include "saa7134-reg.h"
#include "saa7134.h"
#include <media/v4l2-common.h>
-#include <media/rds.h>
+#include <media/saa6588.h>
/* ------------------------------------------------------------------ */
@@ -1459,7 +1459,7 @@ static int video_release(struct file *file)
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
- struct rds_command cmd;
+ struct saa6588_command cmd;
unsigned long flags;
/* turn off overlay */
@@ -1494,7 +1494,7 @@ static int video_release(struct file *file)
saa_call_all(dev, core, s_power, 0);
if (fh->radio)
- saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
+ saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
/* free stuff */
videobuf_mmap_free(&fh->cap);
@@ -1520,14 +1520,14 @@ static ssize_t radio_read(struct file *file, char __user *data,
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
- struct rds_command cmd;
+ struct saa6588_command cmd;
cmd.block_count = count/3;
cmd.buffer = data;
cmd.instance = file;
cmd.result = -ENODEV;
- saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd);
+ saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
return cmd.result;
}
@@ -1536,12 +1536,12 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
- struct rds_command cmd;
+ struct saa6588_command cmd;
cmd.instance = file;
cmd.event_list = wait;
cmd.result = -ENODEV;
- saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd);
+ saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
return cmd.result;
}
@@ -1748,7 +1748,6 @@ static int saa7134_enum_input(struct file *file, void *priv,
return -EINVAL;
if (NULL == card_in(dev, i->index).name)
return -EINVAL;
- memset(i, 0, sizeof(*i));
i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, card_in(dev, n).name);
@@ -2211,14 +2210,6 @@ static int saa7134_overlay(struct file *file, void *f, unsigned int on)
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct saa7134_fh *fh = file->private_data;
- return videobuf_cgmbuf(saa7134_queue(fh), mbuf, 8);
-}
-#endif
-
static int saa7134_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
@@ -2456,9 +2447,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_streamoff = saa7134_streamoff,
.vidioc_g_tuner = saa7134_g_tuner,
.vidioc_s_tuner = saa7134_s_tuner,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
.vidioc_g_crop = saa7134_g_crop,
.vidioc_s_crop = saa7134_s_crop,
.vidioc_g_fbuf = saa7134_g_fbuf,
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index d3b6a196e5dc..5b0a347b0b8f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -37,7 +37,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/tuner.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include <media/videobuf-dma-sg.h>
#include <sound/core.h>
@@ -119,6 +119,26 @@ struct saa7134_format {
unsigned int uvswap:1;
};
+struct saa7134_card_ir {
+ struct rc_dev *dev;
+
+ char name[32];
+ char phys[32];
+ unsigned users;
+
+ u32 polling;
+ u32 last_gpio;
+ u32 mask_keycode, mask_keydown, mask_keyup;
+
+ bool running;
+ bool active;
+
+ struct timer_list timer;
+
+ /* IR core raw decoding */
+ u32 raw_decode;
+};
+
/* ----------------------------------------------------------- */
/* card configuration */
@@ -305,6 +325,8 @@ struct saa7134_format {
#define SAA7134_BOARD_BEHOLD_A7 179
#define SAA7134_BOARD_AVERMEDIA_M733A 180
#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
+#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
+#define SAA7134_BOARD_VIDEOMATE_M1F 183
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -529,7 +551,7 @@ struct saa7134_dev {
/* infrared remote */
int has_remote;
- struct card_ir *remote;
+ struct saa7134_card_ir *remote;
/* pci i/o */
char name[32];
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index ad3bc4154176..bd86d970f4c2 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -40,9 +40,8 @@ int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
ret = saa7164_cmd_send(dev, 0, GET_CUR,
GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
@@ -63,14 +62,15 @@ int saa7164_api_collect_debug(struct saa7164_dev *dev)
ret = saa7164_cmd_send(dev, 0, GET_CUR,
GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n",
+ __func__, ret);
if (d.dwResult != SAA_OK)
break;
- printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData);
+ printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
+ d.ucDebugData);
}
return 0;
@@ -86,9 +86,9 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
/* Retrieve current state */
ret = saa7164_cmd_send(dev, 0, GET_CUR,
SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
+
dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
lvl.dwDebugLevel = level;
@@ -96,9 +96,8 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
/* set new state */
ret = saa7164_cmd_send(dev, 0, SET_CUR,
SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
return ret;
}
@@ -152,8 +151,10 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
- dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
- dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex);
+ dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
+ rsp.bFormatIndex);
+ dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
+ rsp.bFrameIndex);
} else
printk(KERN_ERR "%s() compare failed\n", __func__);
}
@@ -210,14 +211,17 @@ int saa7164_api_set_encoder(struct saa7164_port *port)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
/* Establish video bitrates */
- if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ if (port->encoder_params.bitrate_mode ==
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
else
vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
vb.dwVideoBitRate = port->encoder_params.bitrate;
vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_VIDEO_BIT_RATE_CONTROL, sizeof(struct tmComResEncVideoBitRate), &vb);
+ EU_VIDEO_BIT_RATE_CONTROL,
+ sizeof(struct tmComResEncVideoBitRate),
+ &vb);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -226,9 +230,12 @@ int saa7164_api_set_encoder(struct saa7164_port *port)
ab.dwAudioBitRate = 384000;
ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_AUDIO_BIT_RATE_CONTROL, sizeof(struct tmComResEncAudioBitRate), &ab);
+ EU_AUDIO_BIT_RATE_CONTROL,
+ sizeof(struct tmComResEncAudioBitRate),
+ &ab);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
+ ret);
saa7164_api_set_aspect_ratio(port);
saa7164_api_set_gop_size(port);
@@ -244,7 +251,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
struct tmComResEncVideoInputAspectRatio ar;
int ret;
- dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);
+ dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
+ port->hwcfg.sourceid);
port->encoder_profile = 0;
port->video_format = 0;
@@ -257,7 +265,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution);
+ EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
+ &port->video_resolution);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -294,13 +303,20 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
- dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);
- dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);
- dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);
+ dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
+ v.ucVideoBitRateMode);
+ dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n",
+ v.dwVideoBitRate);
+ dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
+ v.dwVideoBitRatePeak);
+ dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
+ a.ucAudioBitRateMode);
+ dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n",
+ a.dwAudioBitRate);
+ dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
+ a.dwAudioBitRatePeak);
+ dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
+ ar.width, ar.height);
return ret;
}
@@ -439,7 +455,8 @@ int saa7164_api_set_videomux(struct saa7164_port *port)
/* Audio Mux */
ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
- SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[port->mux_input - 1]);
+ SU_INPUT_SELECT_CONTROL, sizeof(u8),
+ &inputs[port->mux_input - 1]);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -492,7 +509,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
+ dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
+ level, min, max, v);
v = level;
if (v < min)
@@ -517,7 +535,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
+ dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
+ level, min, max, v);
return ret;
}
@@ -539,7 +558,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port)
lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), &lvl);
+ AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
+ &lvl);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -555,7 +575,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port)
ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
+ __func__, ret);
return ret;
}
@@ -575,7 +596,9 @@ int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR
+ "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
+ __func__, ret);
return ret;
}
@@ -646,9 +669,9 @@ int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
EXU_REGISTER_ACCESS_CONTROL, len, &buf);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
-
- //saa7164_dumphex16(dev, buf, 16);
-
+#if 0
+ saa7164_dumphex16(dev, buf, 16);
+#endif
return ret == SAA_OK ? 0 : -EIO;
}
@@ -696,7 +719,8 @@ int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
} else {
/* Unknown standard, assume DTV */
dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
- saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */
+ /* Undefinded Video Standard */
+ saa7164_api_set_dif(port, 0x00, 0x80);
agc_disable = 1;
}
@@ -933,7 +957,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
if (hdr->type != CS_INTERFACE)
return SAA_ERR_NOT_SUPPORTED;
- dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
+ dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
switch (hdr->subtype) {
case GENERAL_REQUEST:
dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
@@ -1085,7 +1109,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
vbiport = &dev->ports[SAA7164_PORT_VBI2];
memcpy(&vbiport->hwcfg, vcoutputtermhdr,
sizeof(*vcoutputtermhdr));
- memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt));
+ memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
+ sizeof(*vbifmt));
saa7164_api_configure_port_vbi(dev,
vbiport);
break;
@@ -1134,7 +1159,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->tunerunit, tunerunithdr,
sizeof(struct tmComResTunerDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d] tuner)\n",
+ encport->nr);
}
break;
case VC_SELECTOR_UNIT:
@@ -1163,7 +1190,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->vidproc, pdh,
sizeof(struct tmComResProcDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case FEATURE_UNIT:
@@ -1181,15 +1209,18 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->audfeat, afd,
sizeof(struct tmComResAFeatureDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
+ encport->nr);
break;
case ENCODER_UNIT:
edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
dprintk(DBGLVL_API, " ENCODER_UNIT\n");
dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
- dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid);
- dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid);
+ dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
+ edh->vsourceid);
+ dprintk(DBGLVL_API, " asourceid = 0x%x\n",
+ edh->asourceid);
dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
if (edh->iunit == edh->unitid) {
if (currpath == 1)
@@ -1198,7 +1229,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->encunit, edh,
sizeof(struct tmComResEncoderDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case EXTENSION_UNIT:
@@ -1262,7 +1295,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->ifunit, exthdr,
sizeof(struct tmComResExtDevDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case PVC_INFRARED_UNIT:
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index 7230912acc7d..ddd25211c9e8 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -24,46 +24,46 @@
#include "saa7164.h"
/* The PCI address space for buffer handling looks like this:
-
- +-u32 wide-------------+
- | +
- +-u64 wide------------------------------------+
- + +
- +----------------------+
- | CurrentBufferPtr + Pointer to current PCI buffer >-+
- +----------------------+ |
- | Unused + |
- +----------------------+ |
- | Pitch + = 188 (bytes) |
- +----------------------+ |
- | PCI buffer size + = pitch * number of lines (312) |
- +----------------------+ |
- |0| Buf0 Write Offset + |
- +----------------------+ v
- |1| Buf1 Write Offset + |
- +----------------------+ |
- |2| Buf2 Write Offset + |
- +----------------------+ |
- |3| Buf3 Write Offset + |
- +----------------------+ |
- ... More write offsets |
- +---------------------------------------------+ |
- +0| set of ptrs to PCI pagetables + |
- +---------------------------------------------+ |
- +1| set of ptrs to PCI pagetables + <--------+
- +---------------------------------------------+
- +2| set of ptrs to PCI pagetables +
- +---------------------------------------------+
- +3| set of ptrs to PCI pagetables + >--+
- +---------------------------------------------+ |
- ... More buffer pointers | +----------------+
- +->| pt[0] TS data |
- | +----------------+
- |
- | +----------------+
- +->| pt[1] TS data |
- | +----------------+
- | etc
+ *
+ * +-u32 wide-------------+
+ * | +
+ * +-u64 wide------------------------------------+
+ * + +
+ * +----------------------+
+ * | CurrentBufferPtr + Pointer to current PCI buffer >-+
+ * +----------------------+ |
+ * | Unused + |
+ * +----------------------+ |
+ * | Pitch + = 188 (bytes) |
+ * +----------------------+ |
+ * | PCI buffer size + = pitch * number of lines (312) |
+ * +----------------------+ |
+ * |0| Buf0 Write Offset + |
+ * +----------------------+ v
+ * |1| Buf1 Write Offset + |
+ * +----------------------+ |
+ * |2| Buf2 Write Offset + |
+ * +----------------------+ |
+ * |3| Buf3 Write Offset + |
+ * +----------------------+ |
+ * ... More write offsets |
+ * +---------------------------------------------+ |
+ * +0| set of ptrs to PCI pagetables + |
+ * +---------------------------------------------+ |
+ * +1| set of ptrs to PCI pagetables + <--------+
+ * +---------------------------------------------+
+ * +2| set of ptrs to PCI pagetables +
+ * +---------------------------------------------+
+ * +3| set of ptrs to PCI pagetables + >--+
+ * +---------------------------------------------+ |
+ * ... More buffer pointers | +----------------+
+ * +->| pt[0] TS data |
+ * | +----------------+
+ * |
+ * | +----------------+
+ * +->| pt[1] TS data |
+ * | +----------------+
+ * | etc
*/
void saa7164_buffer_display(struct saa7164_buffer *buf)
@@ -283,7 +283,8 @@ int saa7164_buffer_cfg_port(struct saa7164_port *port)
return 0;
}
-struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len)
+struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
+ u32 len)
{
struct saa7164_user_buffer *buf;
@@ -313,12 +314,9 @@ void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
if (!buf)
return;
- if (buf->data) {
- kfree(buf->data);
- buf->data = 0;
- }
+ kfree(buf->data);
+ buf->data = 0;
- if (buf)
- kfree(buf);
+ kfree(buf);
}
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
index 30d5283da41e..b2b0d97101d0 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -43,7 +43,8 @@ int saa7164_bus_setup(struct saa7164_dev *dev)
b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
- b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64));
+ b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) +
+ (2 * sizeof(u64));
b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32));
b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32));
@@ -105,7 +106,8 @@ void saa7164_bus_verify(struct saa7164_dev *dev)
}
}
-void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *buf)
+void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m,
+ void *buf)
{
dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
@@ -129,7 +131,8 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *
* SAA_OK The function executed successfully.
* < 0 One or more members are not initialized.
*/
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf)
+int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf)
{
struct tmComResBusInfo *bus = &dev->bus;
u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp;
@@ -294,14 +297,15 @@ out:
/*
* Receive a command or a response from the bus. The implementation does not
* know if it is a command or a response it simply dequeues the data,
- * depending on the bus information given in the struct tmComResBusInfo structure.
+ * depending on the bus information given in the struct tmComResBusInfo
+ * structure.
*
* Return Value:
* 0 The function executed successfully.
* < 0 One or more members are not initialized.
*/
-int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf,
- int peekonly)
+int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf, int peekonly)
{
struct tmComResBusInfo *bus = &dev->bus;
u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
index 4cb634e952a6..69822a4e7275 100644
--- a/drivers/media/video/saa7164/saa7164-cards.c
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -482,7 +482,7 @@ void saa7164_gpio_setup(struct saa7164_dev *dev)
saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
- msleep(10);
+ msleep(20);
saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
index 301a9e302f45..a97ae17b36c2 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -122,8 +122,8 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
return ret;
}
- /* It's unlikely to have more than 4 or 5 pending messages, ensure we exit
- * at some point regardles.
+ /* It's unlikely to have more than 4 or 5 pending messages,
+ * ensure we exit at some point regardless.
*/
} while (i++ < 32);
@@ -186,7 +186,8 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev)
return SAA_OK;
}
-int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf)
+int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
+ void *buf)
{
struct tmComResBusInfo *bus = &dev->bus;
u8 cmd_sent;
@@ -292,7 +293,8 @@ int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
* We typically are signalled in < 50ms but it can
* take MUCH longer.
*/
- wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
+ wait_event_timeout(*q, dev->cmds[seqno].signalled,
+ (HZ * waitsecs));
r = time_before(jiffies, stamp + (HZ * waitsecs));
if (r)
ret = SAA_OK;
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index e1bac5051460..d6bf3f82cc34 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -40,12 +40,12 @@ MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
MODULE_LICENSE("GPL");
/*
- 1 Basic
- 2
- 4 i2c
- 8 api
- 16 cmd
- 32 bus
+ * 1 Basic
+ * 2
+ * 4 i2c
+ * 8 api
+ * 16 cmd
+ * 32 bus
*/
unsigned int saa_debug;
@@ -82,7 +82,8 @@ MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
unsigned int guard_checking = 1;
module_param(guard_checking, int, 0644);
-MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns");
+MODULE_PARM_DESC(guard_checking,
+ "enable dma sanity checking for buffer overruns");
static unsigned int saa7164_devcount;
@@ -123,7 +124,9 @@ static void saa7164_pack_verifier(struct saa7164_buffer *buf)
if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
(*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) {
printk(KERN_ERR "No pack at 0x%x\n", i);
-// saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
+#if 0
+ saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
+#endif
}
}
}
@@ -199,19 +202,16 @@ static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
strcpy(hg->name, name);
/* First 30ms x 1ms */
- for (i = 0; i < 30; i++) {
+ for (i = 0; i < 30; i++)
hg->counter1[0 + i].val = i;
- }
/* 30 - 200ms x 10ms */
- for (i = 0; i < 18; i++) {
+ for (i = 0; i < 18; i++)
hg->counter1[30 + i].val = 30 + (i * 10);
- }
/* 200 - 2000ms x 100ms */
- for (i = 0; i < 15; i++) {
+ for (i = 0; i < 15; i++)
hg->counter1[48 + i].val = 200 + (i * 200);
- }
/* Catch all massive value (2secs) */
hg->counter1[55].val = 2000;
@@ -315,7 +315,9 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
(*(p + buf->actual_size + 0x13) != 0xff)) {
printk(KERN_ERR "%s() buf %p guard buffer breach\n",
__func__, buf);
-// saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
+#if 0
+ saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
+#endif
}
}
@@ -961,9 +963,7 @@ static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
/* We need a deferred interrupt handler for cmd handling */
INIT_WORK(&port->workenc, saa7164_work_enchandler);
- }
- else
- if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
+ } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
port->type = SAA7164_MPEG_VBI;
/* We need a deferred interrupt handler for cmd handling */
@@ -1001,7 +1001,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
atomic_inc(&dev->refcount);
dev->nr = saa7164_devcount++;
- sprintf(dev->name, "saa7164[%d]", dev->nr);
+ snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr);
mutex_lock(&devlist);
list_add_tail(&dev->devlist, &saa7164_devlist);
@@ -1169,7 +1169,7 @@ static int saa7164_proc_open(struct inode *inode, struct file *filp)
return single_open(filp, saa7164_proc_show, NULL);
}
-static struct file_operations saa7164_proc_fops = {
+static const struct file_operations saa7164_proc_fops = {
.open = saa7164_proc_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index cbb53d0ee979..1838408cd5cb 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -125,16 +125,22 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
dprintk(DBGLVL_ENC, "%s()\n", __func__);
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
- dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__);
+ if (port->encoder_params.stream_type ==
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
+ dprintk(DBGLVL_ENC,
+ "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n",
+ __func__);
params->samplesperline = 128;
params->numberoflines = 256;
params->pitch = 128;
params->numpagetables = 2 +
((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
} else
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
- dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__);
+ if (port->encoder_params.stream_type ==
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
+ dprintk(DBGLVL_ENC,
+ "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n",
+ __func__);
params->samplesperline = 188;
params->numberoflines = 312;
params->pitch = 188;
@@ -826,7 +832,8 @@ static int fill_queryctrl(struct saa7164_encoder_params *params,
return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
return v4l2_ctrl_query_fill(c,
@@ -1113,7 +1120,9 @@ struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
if (crc_checking) {
crc = crc32(0, ubuf->data, ubuf->actual_size);
if (crc != ubuf->crc) {
- printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
+ printk(KERN_ERR
+ "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
+ __func__,
ubuf, ubuf->crc, crc);
}
}
@@ -1201,9 +1210,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
buffer += cnt;
ret += cnt;
- if (ubuf->pos > ubuf->actual_size) {
+ if (ubuf->pos > ubuf->actual_size)
printk(KERN_ERR "read() pos > actual, huh?\n");
- }
if (ubuf->pos == ubuf->actual_size) {
@@ -1227,16 +1235,16 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
}
}
err:
- if (!ret && !ubuf) {
+ if (!ret && !ubuf)
ret = -EAGAIN;
- }
return ret;
}
static unsigned int fops_poll(struct file *file, poll_table *wait)
{
- struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data;
+ struct saa7164_encoder_fh *fh =
+ (struct saa7164_encoder_fh *)file->private_data;
struct saa7164_port *port = fh->port;
struct saa7164_user_buffer *ubuf;
unsigned int mask = 0;
@@ -1249,9 +1257,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
saa7164_histogram_update(&port->poll_interval,
port->last_poll_msecs_diff);
- if (!video_is_registered(port->v4l_device)) {
+ if (!video_is_registered(port->v4l_device))
return -EIO;
- }
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&port->v4l_reader_count) == 1) {
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
index 484533c32bb1..ebed6f786a23 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -178,7 +178,7 @@ int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
goto out;
}
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (timeout++ > 60)
break;
}
@@ -235,7 +235,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
__func__, err_flags);
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
printk(KERN_ERR "%s() firmware corrupt\n",
@@ -294,7 +294,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
__func__, err_flags);
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
printk(KERN_ERR
@@ -365,7 +365,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
first_timeout = SAA_DEVICE_TIMEOUT;
while (first_timeout) {
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
version =
saa7164_getcurrentfirmwareversion(dev);
@@ -608,8 +608,6 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
ret = 0;
out:
- if (fw)
- release_firmware(fw);
-
+ release_firmware(fw);
return ret;
}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
index b5167d33650a..26148f76cba2 100644
--- a/drivers/media/video/saa7164/saa7164-i2c.c
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -23,7 +23,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include "saa7164.h"
@@ -65,7 +65,7 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
}
return num;
- err:
+err:
return retval;
}
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index 323c7cdca37b..8abbe6d661e4 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -51,11 +51,15 @@ static void saa7164_vbi_configure(struct saa7164_port *port)
/* Set up the DIF (enable it) for analog mode by default */
saa7164_api_initialize_dif(port);
-// /* Configure the correct video standard */
-// saa7164_api_configure_dif(port, port->encodernorm.id);
+ /* Configure the correct video standard */
+#if 0
+ saa7164_api_configure_dif(port, port->encodernorm.id);
+#endif
-// /* Ensure the audio decoder is correct configured */
-// saa7164_api_set_audio_std(port);
+#if 0
+ /* Ensure the audio decoder is correct configured */
+ saa7164_api_set_audio_std(port);
+#endif
dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
}
@@ -919,8 +923,10 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port)
saa7164_vbi_buffers_alloc(port);
/* Configure the encoder with any cache values */
-// saa7164_api_set_encoder(port);
-// saa7164_api_get_encoder(port);
+#if 0
+ saa7164_api_set_encoder(port);
+ saa7164_api_get_encoder(port);
+#endif
/* Place the empty buffers on the hardware */
saa7164_buffer_cfg_port(port);
@@ -1060,7 +1066,8 @@ struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
if (crc_checking) {
crc = crc32(0, ubuf->data, ubuf->actual_size);
if (crc != ubuf->crc) {
- printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
+ printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
+ __func__,
ubuf, ubuf->crc, crc);
}
}
@@ -1148,9 +1155,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
buffer += cnt;
ret += cnt;
- if (ubuf->pos > ubuf->actual_size) {
+ if (ubuf->pos > ubuf->actual_size)
printk(KERN_ERR "read() pos > actual, huh?\n");
- }
if (ubuf->pos == ubuf->actual_size) {
@@ -1197,9 +1203,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
saa7164_histogram_update(&port->poll_interval,
port->last_poll_msecs_diff);
- if (!video_is_registered(port->v4l_device)) {
+ if (!video_is_registered(port->v4l_device))
return -EIO;
- }
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&port->v4l_reader_count) == 1) {
@@ -1257,10 +1262,14 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_log_status = vidioc_log_status,
.vidioc_queryctrl = vidioc_queryctrl,
-// .vidioc_g_chip_ident = saa7164_g_chip_ident,
+#if 0
+ .vidioc_g_chip_ident = saa7164_g_chip_ident,
+#endif
#ifdef CONFIG_VIDEO_ADV_DEBUG
-// .vidioc_g_register = saa7164_g_register,
-// .vidioc_s_register = saa7164_s_register,
+#if 0
+ .vidioc_g_register = saa7164_g_register,
+ .vidioc_s_register = saa7164_s_register,
+#endif
#endif
.vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
index 041ae8e20f68..16745d2fb349 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -113,7 +113,8 @@
#define DBGLVL_THR 4096
#define DBGLVL_CPU 8192
-#define SAA7164_NORMS (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
+#define SAA7164_NORMS \
+ (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
enum port_t {
SAA7164_MPEG_UNDEFINED = 0,
@@ -182,15 +183,11 @@ struct saa7164_subid {
struct saa7164_encoder_fh {
struct saa7164_port *port;
-// u32 freq;
-// u32 tuner_type;
atomic_t v4l_reading;
};
struct saa7164_vbi_fh {
struct saa7164_port *port;
-// u32 freq;
-// u32 tuner_type;
atomic_t v4l_reading;
};
@@ -265,8 +262,6 @@ struct saa7164_ctrl {
struct saa7164_tvnorm {
char *name;
v4l2_std_id id;
-// u32 cxiformat;
-// u32 cxoformat;
};
struct saa7164_encoder_params {
@@ -447,7 +442,7 @@ struct saa7164_dev {
int nr;
int hwrevision;
u32 board;
- char name[32];
+ char name[16];
/* firmware status */
struct saa7164_fw_status fw_status;
@@ -510,7 +505,8 @@ extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
/* saa7164-bus.c */
int saa7164_bus_setup(struct saa7164_dev *dev);
void saa7164_bus_dump(struct saa7164_dev *dev);
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf);
+int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf);
int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
void *buf, int peekonly);
@@ -552,7 +548,8 @@ int saa7164_api_get_videomux(struct saa7164_port *port);
int saa7164_api_set_vbi_format(struct saa7164_port *port);
int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
int saa7164_api_collect_debug(struct saa7164_dev *dev);
-int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i);
+int saa7164_api_get_load_info(struct saa7164_dev *dev,
+ struct tmFwInfoStruct *i);
/* ----------------------------------------------------------- */
/* saa7164-cards.c */
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 5c209afb0ac8..954222bc3458 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -1786,7 +1786,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
pcdev->field,
sizeof(struct sh_mobile_ceu_buffer),
- icd, NULL);
+ icd, &icd->video_lock);
}
static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
* we complete the completion.
*/
- if (!csi2->driver || !csi2->driver->owner) {
+ if (!csi2->driver) {
complete(&wait.completion);
/* Either too late, or probing failed */
bus_unregister_notifier(&platform_bus_type, &wait.notifier);
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
index 0f4906136b8f..07cf0c6c7c1f 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/video/sh_vou.c
@@ -75,6 +75,7 @@ struct sh_vou_device {
int pix_idx;
struct videobuf_buffer *active;
enum sh_vou_status status;
+ struct mutex fop_lock;
};
struct sh_vou_file {
@@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
vb->state = VIDEOBUF_NEEDS_INIT;
}
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
@@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
return 0;
}
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
static int sh_vou_buf_prepare(struct videobuf_queue *vq,
struct videobuf_buffer *vb,
enum v4l2_field field)
@@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
return 0;
}
-/* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */
+/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
static void sh_vou_buf_queue(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
@@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file)
V4L2_BUF_TYPE_VIDEO_OUTPUT,
V4L2_FIELD_NONE,
sizeof(struct videobuf_buffer), vdev,
- NULL);
+ &vou_dev->fop_lock);
return 0;
}
@@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = {
.owner = THIS_MODULE,
.open = sh_vou_open,
.release = sh_vou_release,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.mmap = sh_vou_mmap,
.poll = sh_vou_poll,
};
@@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&vou_dev->queue);
spin_lock_init(&vou_dev->lock);
+ mutex_init(&vou_dev->fop_lock);
atomic_set(&vou_dev->use_count, 0);
vou_dev->pdata = vou_pdata;
vou_dev->status = SH_VOU_IDLE;
@@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
vdev->tvnorms |= V4L2_STD_PAL;
vdev->v4l2_dev = &vou_dev->v4l2_dev;
vdev->release = video_device_release;
+ vdev->lock = &vou_dev->fop_lock;
vou_dev->vdev = vdev;
video_set_drvdata(vdev, vou_dev);
@@ -1406,7 +1409,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
goto ereset;
subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
- NULL, vou_pdata->board_info, NULL);
+ vou_pdata->board_info, NULL);
if (!subdev) {
ret = -ENOMEM;
goto ei2cnd;
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 28e19daadec9..84984f64b234 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2189,6 +2189,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
memset(&i, 0, sizeof(i));
strcpy(i.name, "Camera");
i.type = V4L2_INPUT_TYPE_CAMERA;
+ i.capabilities = V4L2_IN_CAP_STD;
if (copy_to_user(arg, &i, sizeof(i)))
return -EFAULT;
@@ -3238,7 +3239,7 @@ static const struct v4l2_file_operations sn9c102_fops = {
.owner = THIS_MODULE,
.open = sn9c102_open,
.release = sn9c102_release,
- .ioctl = sn9c102_ioctl,
+ .unlocked_ioctl = sn9c102_ioctl,
.read = sn9c102_read,
.poll = sn9c102_poll,
.mmap = sn9c102_mmap,
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index ccfa59c54552..41064c7b5ef8 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -43,9 +43,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
-#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
@@ -56,8 +54,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
-#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
+#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 43848a751d11..a66811b43710 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/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/vmalloc.h>
@@ -43,6 +44,51 @@ static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
+static int soc_camera_power_set(struct soc_camera_device *icd,
+ struct soc_camera_link *icl,
+ int power_on)
+{
+ int ret;
+
+ if (power_on) {
+ ret = regulator_bulk_enable(icl->num_regulators,
+ icl->regulators);
+ if (ret < 0) {
+ dev_err(&icd->dev, "Cannot enable regulators\n");
+ return ret;
+ }
+
+ if (icl->power)
+ ret = icl->power(icd->pdev, power_on);
+ if (ret < 0) {
+ dev_err(&icd->dev,
+ "Platform failed to power-on the camera.\n");
+
+ regulator_bulk_disable(icl->num_regulators,
+ icl->regulators);
+ return ret;
+ }
+ } else {
+ ret = 0;
+ if (icl->power)
+ ret = icl->power(icd->pdev, 0);
+ if (ret < 0) {
+ dev_err(&icd->dev,
+ "Platform failed to power-off the camera.\n");
+ return ret;
+ }
+
+ ret = regulator_bulk_disable(icl->num_regulators,
+ icl->regulators);
+ if (ret < 0) {
+ dev_err(&icd->dev, "Cannot disable regulators\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
struct soc_camera_device *icd, unsigned int fourcc)
{
@@ -352,12 +398,6 @@ static int soc_camera_open(struct file *file)
return -EINVAL;
}
- /*
- * Protect against icd->ops->remove() until we module_get() both
- * drivers.
- */
- mutex_lock(&icd->video_lock);
-
icd->use_count++;
/* Now we really have to activate the camera */
@@ -375,11 +415,9 @@ static int soc_camera_open(struct file *file)
},
};
- if (icl->power) {
- ret = icl->power(icd->pdev, 1);
- if (ret < 0)
- goto epower;
- }
+ ret = soc_camera_power_set(icd, icl, 1);
+ if (ret < 0)
+ goto epower;
/* The camera could have been already on, try to reset */
if (icl->reset)
@@ -405,15 +443,13 @@ static int soc_camera_open(struct file *file)
ret = soc_camera_set_fmt(icd, &f);
if (ret < 0)
goto esfmt;
+
+ ici->ops->init_videobuf(&icd->vb_vidq, icd);
}
file->private_data = icd;
dev_dbg(&icd->dev, "camera device open\n");
- ici->ops->init_videobuf(&icd->vb_vidq, icd);
-
- mutex_unlock(&icd->video_lock);
-
return 0;
/*
@@ -425,11 +461,9 @@ esfmt:
eresume:
ici->ops->remove(icd);
eiciadd:
- if (icl->power)
- icl->power(icd->pdev, 0);
+ soc_camera_power_set(icd, icl, 0);
epower:
icd->use_count--;
- mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
return ret;
@@ -440,7 +474,6 @@ static int soc_camera_close(struct file *file)
struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- mutex_lock(&icd->video_lock);
icd->use_count--;
if (!icd->use_count) {
struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -450,15 +483,12 @@ static int soc_camera_close(struct file *file)
ici->ops->remove(icd);
- if (icl->power)
- icl->power(icd->pdev, 0);
+ soc_camera_power_set(icd, icl, 0);
}
if (icd->streamer == file)
icd->streamer = NULL;
- mutex_unlock(&icd->video_lock);
-
module_put(ici->ops->owner);
dev_dbg(&icd->dev, "camera device close\n");
@@ -517,7 +547,7 @@ static struct v4l2_file_operations soc_camera_fops = {
.owner = THIS_MODULE,
.open = soc_camera_open,
.release = soc_camera_close,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = soc_camera_read,
.mmap = soc_camera_mmap,
.poll = soc_camera_poll,
@@ -534,12 +564,9 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
if (icd->streamer && icd->streamer != file)
return -EBUSY;
- mutex_lock(&icd->vb_vidq.vb_lock);
-
if (icd->vb_vidq.bufs[0]) {
dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
- ret = -EBUSY;
- goto unlock;
+ return -EBUSY;
}
ret = soc_camera_set_fmt(icd, f);
@@ -547,9 +574,6 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
if (!ret && !icd->streamer)
icd->streamer = file;
-unlock:
- mutex_unlock(&icd->vb_vidq.vb_lock);
-
return ret;
}
@@ -622,15 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv,
if (icd->streamer != file)
return -EBUSY;
- mutex_lock(&icd->video_lock);
-
v4l2_subdev_call(sd, video, s_stream, 1);
/* This calls buf_queue from host driver's videobuf_queue_ops */
ret = videobuf_streamon(&icd->vb_vidq);
- mutex_unlock(&icd->video_lock);
-
return ret;
}
@@ -648,8 +668,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
if (icd->streamer != file)
return -EBUSY;
- mutex_lock(&icd->video_lock);
-
/*
* This calls buf_release from host driver's videobuf_queue_ops for all
* remaining buffers. When the last buffer is freed, stop capture
@@ -658,8 +676,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
v4l2_subdev_call(sd, video, s_stream, 0);
- mutex_unlock(&icd->video_lock);
-
return 0;
}
@@ -748,9 +764,7 @@ static int soc_camera_g_crop(struct file *file, void *fh,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
int ret;
- mutex_lock(&icd->vb_vidq.vb_lock);
ret = ici->ops->get_crop(icd, a);
- mutex_unlock(&icd->vb_vidq.vb_lock);
return ret;
}
@@ -775,9 +789,6 @@ static int soc_camera_s_crop(struct file *file, void *fh,
dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n",
rect->width, rect->height, rect->left, rect->top);
- /* Cropping is allowed during a running capture, guard consistency */
- mutex_lock(&icd->vb_vidq.vb_lock);
-
/* If get_crop fails, we'll let host and / or client drivers decide */
ret = ici->ops->get_crop(icd, &current_crop);
@@ -795,8 +806,6 @@ static int soc_camera_s_crop(struct file *file, void *fh,
ret = ici->ops->set_crop(icd, a);
}
- mutex_unlock(&icd->vb_vidq.vb_lock);
-
return ret;
}
@@ -896,7 +905,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
icl->board_info->platform_data = icd;
subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
- NULL, icl->board_info, NULL);
+ icl->board_info, NULL);
if (!subdev)
goto ei2cnd;
@@ -941,14 +950,14 @@ static int soc_camera_probe(struct device *dev)
dev_info(dev, "Probing %s\n", dev_name(dev));
- if (icl->power) {
- ret = icl->power(icd->pdev, 1);
- if (ret < 0) {
- dev_err(dev,
- "Platform failed to power-on the camera.\n");
- goto epower;
- }
- }
+ ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
+ icl->regulators);
+ if (ret < 0)
+ goto ereg;
+
+ ret = soc_camera_power_set(icd, icl, 1);
+ if (ret < 0)
+ goto epower;
/* The camera could have been already on, try to reset */
if (icl->reset)
@@ -998,7 +1007,13 @@ static int soc_camera_probe(struct device *dev)
icd->field = V4L2_FIELD_ANY;
- /* ..._video_start() will create a device node, so we have to protect */
+ icd->vdev->lock = &icd->video_lock;
+
+ /*
+ * ..._video_start() will create a device node, video_register_device()
+ * itself is protected against concurrent open() calls, but we also have
+ * to protect our data.
+ */
mutex_lock(&icd->video_lock);
ret = soc_camera_video_start(icd);
@@ -1021,8 +1036,7 @@ static int soc_camera_probe(struct device *dev)
ici->ops->remove(icd);
- if (icl->power)
- icl->power(icd->pdev, 0);
+ soc_camera_power_set(icd, icl, 0);
mutex_unlock(&icd->video_lock);
@@ -1044,9 +1058,10 @@ eadddev:
evdc:
ici->ops->remove(icd);
eadd:
- if (icl->power)
- icl->power(icd->pdev, 0);
+ soc_camera_power_set(icd, icl, 0);
epower:
+ regulator_bulk_free(icl->num_regulators, icl->regulators);
+ereg:
return ret;
}
@@ -1063,10 +1078,8 @@ static int soc_camera_remove(struct device *dev)
BUG_ON(!dev->parent);
if (vdev) {
- mutex_lock(&icd->video_lock);
video_unregister_device(vdev);
icd->vdev = NULL;
- mutex_unlock(&icd->video_lock);
}
if (icl->board_info) {
@@ -1081,6 +1094,8 @@ static int soc_camera_remove(struct device *dev)
}
soc_camera_free_user_formats(icd);
+ regulator_bulk_free(icl->num_regulators, icl->regulators);
+
return 0;
}
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c
index c9dc67aba980..864696b7a006 100644
--- a/drivers/media/video/sr030pc30.c
+++ b/drivers/media/video/sr030pc30.c
@@ -735,7 +735,7 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on)
const struct sr030pc30_platform_data *pdata = info->pdata;
int ret;
- if (WARN(pdata == NULL, "No platform data!"))
+ if (WARN(pdata == NULL, "No platform data!\n"))
return -ENOMEM;
/*
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index b5afe5f841ce..d1a2cefbf55b 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -230,120 +230,6 @@ static int stk_initialise(struct stk_camera *dev)
return -1;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-
-/* sysfs functions */
-/*FIXME cleanup this */
-
-static ssize_t show_brightness(struct device *class,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- return sprintf(buf, "%X\n", dev->vsettings.brightness);
-}
-
-static ssize_t store_brightness(struct device *class,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- char *endp;
- unsigned long value;
- int ret;
-
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- value = simple_strtoul(buf, &endp, 16);
-
- dev->vsettings.brightness = (int) value;
-
- ret = stk_sensor_set_brightness(dev, value >> 8);
- if (ret)
- return ret;
- else
- return count;
-}
-
-static ssize_t show_hflip(struct device *class,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- return sprintf(buf, "%d\n", dev->vsettings.hflip);
-}
-
-static ssize_t store_hflip(struct device *class,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- if (strncmp(buf, "1", 1) == 0)
- dev->vsettings.hflip = 1;
- else if (strncmp(buf, "0", 1) == 0)
- dev->vsettings.hflip = 0;
- else
- return -EINVAL;
-
- return strlen(buf);
-}
-
-static ssize_t show_vflip(struct device *class,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- return sprintf(buf, "%d\n", dev->vsettings.vflip);
-}
-
-static ssize_t store_vflip(struct device *class,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct video_device *vdev = to_video_device(class);
- struct stk_camera *dev = vdev_to_camera(vdev);
-
- if (strncmp(buf, "1", 1) == 0)
- dev->vsettings.vflip = 1;
- else if (strncmp(buf, "0", 1) == 0)
- dev->vsettings.vflip = 0;
- else
- return -EINVAL;
-
- return strlen(buf);
-}
-
-static DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO,
- show_brightness, store_brightness);
-static DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip);
-static DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip);
-
-static int stk_create_sysfs_files(struct video_device *vdev)
-{
- int ret;
-
- ret = device_create_file(&vdev->dev, &dev_attr_brightness);
- ret += device_create_file(&vdev->dev, &dev_attr_hflip);
- ret += device_create_file(&vdev->dev, &dev_attr_vflip);
- if (ret)
- STK_WARNING("Could not create sysfs files\n");
- return ret;
-}
-
-static void stk_remove_sysfs_files(struct video_device *vdev)
-{
- device_remove_file(&vdev->dev, &dev_attr_brightness);
- device_remove_file(&vdev->dev, &dev_attr_hflip);
- device_remove_file(&vdev->dev, &dev_attr_vflip);
-}
-
-#else
-#define stk_create_sysfs_files(a)
-#define stk_remove_sysfs_files(a)
-#endif
-
/* *********************************************** */
/*
* This function is called as an URB transfert is complete (Isochronous pipe).
@@ -878,7 +764,24 @@ static struct v4l2_queryctrl stk_controls[] = {
.step = 0x0100,
.default_value = 0x6000,
},
- /*TODO: get more controls to work */
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Horizontal Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Vertical Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
};
static int stk_vidioc_queryctrl(struct file *filp,
@@ -906,6 +809,12 @@ static int stk_vidioc_g_ctrl(struct file *filp,
case V4L2_CID_BRIGHTNESS:
c->value = dev->vsettings.brightness;
break;
+ case V4L2_CID_HFLIP:
+ c->value = dev->vsettings.hflip;
+ break;
+ case V4L2_CID_VFLIP:
+ c->value = dev->vsettings.vflip;
+ break;
default:
return -EINVAL;
}
@@ -920,6 +829,12 @@ static int stk_vidioc_s_ctrl(struct file *filp,
case V4L2_CID_BRIGHTNESS:
dev->vsettings.brightness = c->value;
return stk_sensor_set_brightness(dev, c->value >> 8);
+ case V4L2_CID_HFLIP:
+ dev->vsettings.hflip = c->value;
+ return 0;
+ case V4L2_CID_VFLIP:
+ dev->vsettings.vflip = c->value;
+ return 0;
default:
return -EINVAL;
}
@@ -1394,8 +1309,6 @@ static int stk_camera_probe(struct usb_interface *interface,
goto error;
}
- stk_create_sysfs_files(&dev->vdev);
-
return 0;
error:
@@ -1411,7 +1324,6 @@ static void stk_camera_disconnect(struct usb_interface *interface)
unset_present(dev);
wake_up_interruptible(&dev->wait_frame);
- stk_remove_sysfs_files(&dev->vdev);
STK_INFO("Syntek USB2.0 Camera release resources device %s\n",
video_device_node_name(&dev->vdev));
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 3e99cea8e4dc..19621ed523ec 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -148,7 +148,7 @@ static int tea6415c_probe(struct i2c_client *client,
/* let's see whether this adapter can support what we need */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
- return 0;
+ return -EIO;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
new file mode 100644
index 000000000000..fc611ebeb82c
--- /dev/null
+++ b/drivers/media/video/timblogiw.c
@@ -0,0 +1,893 @@
+/*
+ * timblogiw.c timberdale FPGA LogiWin Video In driver
+ * 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.
+ */
+
+/* Supports:
+ * Timberdale FPGA LogiWin Video In
+ */
+
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/timb_video.h>
+
+#define DRIVER_NAME "timb-video"
+
+#define TIMBLOGIWIN_NAME "Timberdale Video-In"
+#define TIMBLOGIW_VERSION_CODE 0x04
+
+#define TIMBLOGIW_LINES_PER_DESC 44
+#define TIMBLOGIW_MAX_VIDEO_MEM 16
+
+#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name)
+
+
+struct timblogiw {
+ struct video_device video_dev;
+ struct v4l2_device v4l2_dev; /* mutual exclusion */
+ struct mutex lock;
+ struct device *dev;
+ struct timb_video_platform_data pdata;
+ struct v4l2_subdev *sd_enc; /* encoder */
+ bool opened;
+};
+
+struct timblogiw_tvnorm {
+ v4l2_std_id std;
+ u16 width;
+ u16 height;
+ u8 fps;
+};
+
+struct timblogiw_fh {
+ struct videobuf_queue vb_vidq;
+ struct timblogiw_tvnorm const *cur_norm;
+ struct list_head capture;
+ struct dma_chan *chan;
+ spinlock_t queue_lock; /* mutual exclusion */
+ unsigned int frame_count;
+};
+
+struct timblogiw_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ struct scatterlist sg[16];
+ dma_cookie_t cookie;
+ struct timblogiw_fh *fh;
+};
+
+const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
+ {
+ .std = V4L2_STD_PAL,
+ .width = 720,
+ .height = 576,
+ .fps = 25
+ },
+ {
+ .std = V4L2_STD_NTSC,
+ .width = 720,
+ .height = 480,
+ .fps = 30
+ }
+};
+
+static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
+{
+ return norm->width * 2;
+}
+
+
+static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
+{
+ return norm->height * timblogiw_bytes_per_line(norm);
+}
+
+static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
+ if (timblogiw_tvnorms[i].std & std)
+ return timblogiw_tvnorms + i;
+
+ /* default to first element */
+ return timblogiw_tvnorms;
+}
+
+static void timblogiw_dma_cb(void *data)
+{
+ struct timblogiw_buffer *buf = data;
+ struct timblogiw_fh *fh = buf->fh;
+ struct videobuf_buffer *vb = &buf->vb;
+
+ spin_lock(&fh->queue_lock);
+
+ /* mark the transfer done */
+ buf->cookie = -1;
+
+ fh->frame_count++;
+
+ if (vb->state != VIDEOBUF_ERROR) {
+ list_del(&vb->queue);
+ do_gettimeofday(&vb->ts);
+ vb->field_count = fh->frame_count * 2;
+ vb->state = VIDEOBUF_DONE;
+
+ wake_up(&vb->done);
+ }
+
+ if (!list_empty(&fh->capture)) {
+ vb = list_entry(fh->capture.next, struct videobuf_buffer,
+ queue);
+ vb->state = VIDEOBUF_ACTIVE;
+ }
+
+ spin_unlock(&fh->queue_lock);
+}
+
+static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param)
+{
+ return chan->chan_id == (uintptr_t)filter_param;
+}
+
+/* IOCTL functions */
+
+static int timblogiw_g_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ mutex_lock(&lw->lock);
+
+ format->fmt.pix.width = fh->cur_norm->width;
+ format->fmt.pix.height = fh->cur_norm->height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm);
+ format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm);
+ format->fmt.pix.field = V4L2_FIELD_NONE;
+
+ mutex_unlock(&lw->lock);
+
+ return 0;
+}
+
+static int timblogiw_try_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_pix_format *pix = &format->fmt.pix;
+
+ dev_dbg(&vdev->dev,
+ "%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
+ "bytes per line %d, size image: %d, colorspace: %d\n",
+ __func__,
+ pix->width, pix->height, pix->pixelformat, pix->field,
+ pix->bytesperline, pix->sizeimage, pix->colorspace);
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (pix->field != V4L2_FIELD_NONE)
+ return -EINVAL;
+
+ if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int timblogiw_s_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+ struct v4l2_pix_format *pix = &format->fmt.pix;
+ int err;
+
+ mutex_lock(&lw->lock);
+
+ err = timblogiw_try_fmt(file, priv, format);
+ if (err)
+ goto out;
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dev_err(&vdev->dev, "%s queue busy\n", __func__);
+ err = -EBUSY;
+ goto out;
+ }
+
+ pix->width = fh->cur_norm->width;
+ pix->height = fh->cur_norm->height;
+
+out:
+ mutex_unlock(&lw->lock);
+ return err;
+}
+
+static int timblogiw_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+ memset(cap, 0, sizeof(*cap));
+ strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
+ strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
+ strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
+ cap->version = TIMBLOGIW_VERSION_CODE;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+ V4L2_CAP_READWRITE;
+
+ return 0;
+}
+
+static int timblogiw_enum_fmt(struct file *file, void *priv,
+ struct v4l2_fmtdesc *fmt)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index);
+
+ if (fmt->index != 0)
+ return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = 0;
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ strncpy(fmt->description, "4:2:2, packed, YUYV",
+ sizeof(fmt->description)-1);
+ fmt->pixelformat = V4L2_PIX_FMT_UYVY;
+
+ return 0;
+}
+
+static int timblogiw_g_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *sp)
+{
+ struct timblogiw_fh *fh = priv;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
+
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+ cp->timeperframe.numerator = 1;
+ cp->timeperframe.denominator = fh->cur_norm->fps;
+
+ return 0;
+}
+
+static int timblogiw_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int timblogiw_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int timblogiw_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ *std = fh->cur_norm->std;
+ return 0;
+}
+
+static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+ int err = 0;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ mutex_lock(&lw->lock);
+
+ if (TIMBLOGIW_HAS_DECODER(lw))
+ err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std);
+
+ if (!err)
+ fh->cur_norm = timblogiw_get_norm(*std);
+
+ mutex_unlock(&lw->lock);
+
+ return err;
+}
+
+static int timblogiw_enuminput(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ struct video_device *vdev = video_devdata(file);
+ int i;
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ if (inp->index != 0)
+ return -EINVAL;
+
+ inp->index = 0;
+
+ strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+
+ inp->std = 0;
+ for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
+ inp->std |= timblogiw_tvnorms[i].std;
+
+ return 0;
+}
+
+static int timblogiw_g_input(struct file *file, void *priv,
+ unsigned int *input)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ *input = 0;
+
+ return 0;
+}
+
+static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ if (input != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dev_dbg(&vdev->dev, "%s - No capture device\n", __func__);
+ return -EINVAL;
+ }
+
+ fh->frame_count = 0;
+ return videobuf_streamon(&fh->vb_vidq);
+}
+
+static int timblogiw_streamoff(struct file *file, void *priv,
+ unsigned int type)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ return videobuf_streamoff(&fh->vb_vidq);
+}
+
+static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (TIMBLOGIW_HAS_DECODER(lw))
+ return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
+ else {
+ *std = fh->cur_norm->std;
+ return 0;
+ }
+}
+
+static int timblogiw_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__,
+ fsize->index, fsize->pixel_format);
+
+ if ((fsize->index != 0) ||
+ (fsize->pixel_format != V4L2_PIX_FMT_UYVY))
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fh->cur_norm->width;
+ fsize->discrete.height = fh->cur_norm->height;
+
+ return 0;
+}
+
+/* Video buffer functions */
+
+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+
+ *size = timblogiw_frame_size(fh->cur_norm);
+
+ if (!*count)
+ *count = 32;
+
+ while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024)
+ (*count)--;
+
+ return 0;
+}
+
+static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+ unsigned int data_size = timblogiw_frame_size(fh->cur_norm);
+ int err = 0;
+
+ if (vb->baddr && vb->bsize < data_size)
+ /* User provided buffer, but it is too small */
+ return -ENOMEM;
+
+ vb->size = data_size;
+ vb->width = fh->cur_norm->width;
+ vb->height = fh->cur_norm->height;
+ vb->field = field;
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ int i;
+ unsigned int size;
+ unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
+ timblogiw_bytes_per_line(fh->cur_norm);
+ dma_addr_t addr;
+
+ sg_init_table(buf->sg, ARRAY_SIZE(buf->sg));
+
+ err = videobuf_iolock(vq, vb, NULL);
+ if (err)
+ goto err;
+
+ addr = videobuf_to_dma_contig(vb);
+ for (i = 0, size = 0; size < data_size; i++) {
+ sg_dma_address(buf->sg + i) = addr + size;
+ size += bytes_per_desc;
+ sg_dma_len(buf->sg + i) = (size > data_size) ?
+ (bytes_per_desc - (size - data_size)) :
+ bytes_per_desc;
+ }
+
+ vb->state = VIDEOBUF_PREPARED;
+ buf->cookie = -1;
+ buf->fh = fh;
+ }
+
+ return 0;
+
+err:
+ videobuf_dma_contig_free(vq, vb);
+ vb->state = VIDEOBUF_NEEDS_INIT;
+ return err;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+ struct dma_async_tx_descriptor *desc;
+ int sg_elems;
+ int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
+ timblogiw_bytes_per_line(fh->cur_norm);
+
+ sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc;
+ sg_elems +=
+ (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0;
+
+ if (list_empty(&fh->capture))
+ vb->state = VIDEOBUF_ACTIVE;
+ else
+ vb->state = VIDEOBUF_QUEUED;
+
+ list_add_tail(&vb->queue, &fh->capture);
+
+ spin_unlock_irq(&fh->queue_lock);
+
+ desc = fh->chan->device->device_prep_slave_sg(fh->chan,
+ buf->sg, sg_elems, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+ if (!desc) {
+ spin_lock_irq(&fh->queue_lock);
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_PREPARED;
+ return;
+ }
+
+ desc->callback_param = buf;
+ desc->callback = timblogiw_dma_cb;
+
+ buf->cookie = desc->tx_submit(desc);
+
+ spin_lock_irq(&fh->queue_lock);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+
+ videobuf_waiton(vq, vb, 0, 0);
+ if (buf->cookie >= 0)
+ dma_sync_wait(fh->chan, buf->cookie);
+
+ videobuf_dma_contig_free(vq, vb);
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops timblogiw_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/* Device Operations functions */
+
+static int timblogiw_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh;
+ v4l2_std_id std;
+ dma_cap_mask_t mask;
+ int err = 0;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ mutex_lock(&lw->lock);
+ if (lw->opened) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) {
+ struct i2c_adapter *adapt;
+
+ /* find the video decoder */
+ adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
+ if (!adapt) {
+ dev_err(&vdev->dev, "No I2C bus #%d\n",
+ lw->pdata.i2c_adapter);
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* now find the encoder */
+ lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt,
+ lw->pdata.encoder.info, NULL);
+
+ i2c_put_adapter(adapt);
+
+ if (!lw->sd_enc) {
+ dev_err(&vdev->dev, "Failed to get encoder: %s\n",
+ lw->pdata.encoder.module_name);
+ err = -ENODEV;
+ goto out;
+ }
+ }
+
+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ if (!fh) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ fh->cur_norm = timblogiw_tvnorms;
+ timblogiw_querystd(file, fh, &std);
+ fh->cur_norm = timblogiw_get_norm(std);
+
+ INIT_LIST_HEAD(&fh->capture);
+ spin_lock_init(&fh->queue_lock);
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+
+ /* find the DMA channel */
+ fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn,
+ (void *)(uintptr_t)lw->pdata.dma_channel);
+ if (!fh->chan) {
+ dev_err(&vdev->dev, "Failed to get DMA channel\n");
+ kfree(fh);
+ err = -ENODEV;
+ goto out;
+ }
+
+ file->private_data = fh;
+ videobuf_queue_dma_contig_init(&fh->vb_vidq,
+ &timblogiw_video_qops, lw->dev, &fh->queue_lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
+ sizeof(struct timblogiw_buffer), fh, NULL);
+
+ lw->opened = true;
+out:
+ mutex_unlock(&lw->lock);
+
+ return err;
+}
+
+static int timblogiw_close(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ dma_release_channel(fh->chan);
+
+ kfree(fh);
+
+ mutex_lock(&lw->lock);
+ lw->opened = false;
+ mutex_unlock(&lw->lock);
+ return 0;
+}
+
+static ssize_t timblogiw_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
+ file->f_flags & O_NONBLOCK);
+}
+
+static unsigned int timblogiw_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_poll_stream(file, &fh->vb_vidq, wait);
+}
+
+static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_mmap_mapper(&fh->vb_vidq, vma);
+}
+
+/* Platform device functions */
+
+static __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
+ .vidioc_querycap = timblogiw_querycap,
+ .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
+ .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
+ .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
+ .vidioc_s_fmt_vid_cap = timblogiw_s_fmt,
+ .vidioc_g_parm = timblogiw_g_parm,
+ .vidioc_reqbufs = timblogiw_reqbufs,
+ .vidioc_querybuf = timblogiw_querybuf,
+ .vidioc_qbuf = timblogiw_qbuf,
+ .vidioc_dqbuf = timblogiw_dqbuf,
+ .vidioc_g_std = timblogiw_g_std,
+ .vidioc_s_std = timblogiw_s_std,
+ .vidioc_enum_input = timblogiw_enuminput,
+ .vidioc_g_input = timblogiw_g_input,
+ .vidioc_s_input = timblogiw_s_input,
+ .vidioc_streamon = timblogiw_streamon,
+ .vidioc_streamoff = timblogiw_streamoff,
+ .vidioc_querystd = timblogiw_querystd,
+ .vidioc_enum_framesizes = timblogiw_enum_framesizes,
+};
+
+static __devinitconst struct v4l2_file_operations timblogiw_fops = {
+ .owner = THIS_MODULE,
+ .open = timblogiw_open,
+ .release = timblogiw_close,
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .mmap = timblogiw_mmap,
+ .read = timblogiw_read,
+ .poll = timblogiw_poll,
+};
+
+static __devinitconst struct video_device timblogiw_template = {
+ .name = TIMBLOGIWIN_NAME,
+ .fops = &timblogiw_fops,
+ .ioctl_ops = &timblogiw_ioctl_ops,
+ .release = video_device_release_empty,
+ .minor = -1,
+ .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
+};
+
+static int __devinit timblogiw_probe(struct platform_device *pdev)
+{
+ int err;
+ struct timblogiw *lw = NULL;
+ struct timb_video_platform_data *pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data\n");
+ err = -EINVAL;
+ goto err;
+ }
+
+ if (!pdata->encoder.module_name)
+ dev_info(&pdev->dev, "Running without decoder\n");
+
+ lw = kzalloc(sizeof(*lw), GFP_KERNEL);
+ if (!lw) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ if (pdev->dev.parent)
+ lw->dev = pdev->dev.parent;
+ else
+ lw->dev = &pdev->dev;
+
+ memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
+
+ mutex_init(&lw->lock);
+
+ lw->video_dev = timblogiw_template;
+
+ strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name));
+ err = v4l2_device_register(NULL, &lw->v4l2_dev);
+ if (err)
+ goto err_register;
+
+ lw->video_dev.v4l2_dev = &lw->v4l2_dev;
+
+ platform_set_drvdata(pdev, lw);
+ video_set_drvdata(&lw->video_dev, lw);
+
+ err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0);
+ if (err) {
+ dev_err(&pdev->dev, "Error reg video: %d\n", err);
+ goto err_request;
+ }
+
+
+ return 0;
+
+err_request:
+ platform_set_drvdata(pdev, NULL);
+ v4l2_device_unregister(&lw->v4l2_dev);
+err_register:
+ kfree(lw);
+err:
+ dev_err(&pdev->dev, "Failed to register: %d\n", err);
+
+ return err;
+}
+
+static int __devexit timblogiw_remove(struct platform_device *pdev)
+{
+ struct timblogiw *lw = platform_get_drvdata(pdev);
+
+ video_unregister_device(&lw->video_dev);
+
+ v4l2_device_unregister(&lw->v4l2_dev);
+
+ kfree(lw);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver timblogiw_platform_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = timblogiw_probe,
+ .remove = __devexit_p(timblogiw_remove),
+};
+
+/* Module functions */
+
+static int __init timblogiw_init(void)
+{
+ return platform_driver_register(&timblogiw_platform_driver);
+}
+
+static void __exit timblogiw_exit(void)
+{
+ platform_driver_unregister(&timblogiw_platform_driver);
+}
+
+module_init(timblogiw_init);
+module_exit(timblogiw_exit);
+
+MODULE_DESCRIPTION(TIMBLOGIWIN_NAME);
+MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig
index 1686ebfa6951..645d915267e6 100644
--- a/drivers/media/video/tlg2300/Kconfig
+++ b/drivers/media/video/tlg2300/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_TLG2300
tristate "Telegent TLG2300 USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE
+ depends on VIDEO_DEV && I2C && SND && DVB_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select SND_PCM
select VIDEOBUF_DVB
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
deleted file mode 100644
index dfa7fc68a657..000000000000
--- a/drivers/media/video/usbvideo/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config VIDEO_USBVIDEO
- tristate
-
-config USB_VICAM
- tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
- depends on VIDEO_V4L1 && EXPERIMENTAL
- select VIDEO_USBVIDEO
- ---help---
- Say Y here if you have 3com homeconnect camera (vicam).
-
- To compile this driver as a module, choose M here: the
- module will be called vicam.
-
-config USB_IBMCAM
- tristate "USB IBM (Xirlink) C-it Camera support (DEPRECATED)"
- depends on VIDEO_V4L1
- select VIDEO_USBVIDEO
- ---help---
- This driver is DEPRECATED please use the gspca xirlink_cit module
- instead.
-
- Say Y here if you want to connect a IBM "C-It" camera, also known as
- "Xirlink PC Camera" to your computer's USB port.
-
- To compile this driver as a module, choose M here: the
- module will be called ibmcam.
-
- This camera has several configuration options which
- can be specified when you load the module. Read
- <file:Documentation/video4linux/ibmcam.txt> to learn more.
-
-config USB_KONICAWC
- tristate "USB Konica Webcam support (DEPRECATED)"
- depends on VIDEO_V4L1
- select VIDEO_USBVIDEO
- ---help---
- This driver is DEPRECATED (and known to crash) please use the
- gspca konica module instead.
-
- Say Y here if you want support for webcams based on a Konica
- chipset. This is known to work with the Intel YC76 webcam.
-
- To compile this driver as a module, choose M here: the
- module will be called konicawc.
-
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile
deleted file mode 100644
index bb52eb8dc2f9..000000000000
--- a/drivers/media/video/usbvideo/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
-obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o
-obj-$(CONFIG_USB_KONICAWC) += konicawc.o
-obj-$(CONFIG_USB_VICAM) += vicam.o
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
deleted file mode 100644
index b08549661781..000000000000
--- a/drivers/media/video/usbvideo/ibmcam.c
+++ /dev/null
@@ -1,3977 +0,0 @@
-/*
- * USB IBM C-It Video Camera driver
- *
- * Supports Xirlink C-It Video Camera, IBM PC Camera,
- * IBM NetCamera and Veo Stingray.
- *
- * This driver is based on earlier work of:
- *
- * (C) Copyright 1999 Johannes Erdfelt
- * (C) Copyright 1999 Randy Dunlap
- *
- * 5/24/00 Removed optional (and unnecessary) locking of the driver while
- * the device remains plugged in. Corrected race conditions in ibmcam_open
- * and ibmcam_probe() routines using this as a guideline:
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "usbvideo.h"
-
-#define IBMCAM_VENDOR_ID 0x0545
-#define IBMCAM_PRODUCT_ID 0x8080
-#define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */
-#define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */
-#define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */
-
-#define MAX_IBMCAM 4 /* How many devices we allow to connect */
-#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
-
-/* Header signatures */
-
-/* Model 1 header: 00 FF 00 xx */
-#define HDRSIG_MODEL1_128x96 0x06 /* U Y V Y ... */
-#define HDRSIG_MODEL1_176x144 0x0e /* U Y V Y ... */
-#define HDRSIG_MODEL1_352x288 0x00 /* V Y U Y ... */
-
-#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */
-#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */
-#define IBMCAM_MODEL_3 3 /* KSX-X9902, 2 interfaces, rev. 3.01 */
-#define IBMCAM_MODEL_4 4 /* IBM NetCamera, 0545/8002/3.0a */
-
-/* Video sizes supported */
-#define VIDEOSIZE_128x96 VIDEOSIZE(128, 96)
-#define VIDEOSIZE_176x144 VIDEOSIZE(176,144)
-#define VIDEOSIZE_352x288 VIDEOSIZE(352,288)
-#define VIDEOSIZE_320x240 VIDEOSIZE(320,240)
-#define VIDEOSIZE_352x240 VIDEOSIZE(352,240)
-#define VIDEOSIZE_640x480 VIDEOSIZE(640,480)
-#define VIDEOSIZE_160x120 VIDEOSIZE(160,120)
-
-/* Video sizes supported */
-enum {
- SIZE_128x96 = 0,
- SIZE_160x120,
- SIZE_176x144,
- SIZE_320x240,
- SIZE_352x240,
- SIZE_352x288,
- SIZE_640x480,
- /* Add/remove/rearrange items before this line */
- SIZE_LastItem
-};
-
-/*
- * This structure lives in uvd->user field.
- */
-typedef struct {
- int initialized; /* Had we already sent init sequence? */
- int camera_model; /* What type of IBM camera we got? */
- int has_hdr;
-} ibmcam_t;
-#define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data))
-
-static struct usbvideo *cams;
-
-static int debug;
-
-static int flags; /* = FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
-
-static const int min_canvasWidth = 8;
-static const int min_canvasHeight = 4;
-
-static int lighting = 1; /* Medium */
-
-#define SHARPNESS_MIN 0
-#define SHARPNESS_MAX 6
-static int sharpness = 4; /* Low noise, good details */
-
-#define FRAMERATE_MIN 0
-#define FRAMERATE_MAX 6
-static int framerate = -1;
-
-static int size = SIZE_352x288;
-
-/*
- * Here we define several initialization variables. They may
- * be used to automatically set color, hue, brightness and
- * contrast to desired values. This is particularly useful in
- * case of webcams (which have no controls and no on-screen
- * output) and also when a client V4L software is used that
- * does not have some of those controls. In any case it's
- * good to have startup values as options.
- *
- * These values are all in [0..255] range. This simplifies
- * operation. Note that actual values of V4L variables may
- * be scaled up (as much as << 8). User can see that only
- * on overlay output, however, or through a V4L client.
- */
-static int init_brightness = 128;
-static int init_contrast = 192;
-static int init_color = 128;
-static int init_hue = 128;
-static int hue_correction = 128;
-
-/* Settings for camera model 2 */
-static int init_model2_rg2 = -1;
-static int init_model2_sat = -1;
-static int init_model2_yb = -1;
-
-/* 01.01.08 - Added for RCA video in support -LO */
-/* Settings for camera model 3 */
-static int init_model3_input;
-
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
-module_param(flags, int, 0);
-MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=separate frames, 6=clean frames");
-module_param(framerate, int, 0);
-MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
-module_param(lighting, int, 0);
-MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
-module_param(sharpness, int, 0);
-MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
-module_param(size, int, 0);
-MODULE_PARM_DESC(size, "Image size: 0=128x96 1=160x120 2=176x144 3=320x240 4=352x240 5=352x288 6=640x480 (default=5)");
-module_param(init_brightness, int, 0);
-MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
-module_param(init_contrast, int, 0);
-MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
-module_param(init_color, int, 0);
-MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
-module_param(init_hue, int, 0);
-MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
-module_param(hue_correction, int, 0);
-MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
-
-module_param(init_model2_rg2, int, 0);
-MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)");
-module_param(init_model2_sat, int, 0);
-MODULE_PARM_DESC(init_model2_sat, "Model2 preconfiguration: 0-255 (default=52)");
-module_param(init_model2_yb, int, 0);
-MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)");
-
-/* 01.01.08 - Added for RCA video in support -LO */
-module_param(init_model3_input, int, 0);
-MODULE_PARM_DESC(init_model3_input, "Model3 input: 0=CCD 1=RCA");
-
-MODULE_AUTHOR ("Dmitri");
-MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
-MODULE_LICENSE("GPL");
-
-/* Still mysterious i2c commands */
-static const unsigned short unknown_88 = 0x0088;
-static const unsigned short unknown_89 = 0x0089;
-static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 };
-static const unsigned short contrast_14 = 0x0014;
-static const unsigned short light_27 = 0x0027;
-static const unsigned short sharp_13 = 0x0013;
-
-/* i2c commands for Model 2 cameras */
-static const unsigned short mod2_brightness = 0x001a; /* $5b .. $ee; default=$5a */
-static const unsigned short mod2_set_framerate = 0x001c; /* 0 (fast).. $1F (slow) */
-static const unsigned short mod2_color_balance_rg2 = 0x001e; /* 0 (red) .. $7F (green) */
-static const unsigned short mod2_saturation = 0x0020; /* 0 (b/w) - $7F (full color) */
-static const unsigned short mod2_color_balance_yb = 0x0022; /* 0..$7F, $50 is about right */
-static const unsigned short mod2_hue = 0x0024; /* 0..$7F, $70 is about right */
-static const unsigned short mod2_sensitivity = 0x0028; /* 0 (min) .. $1F (max) */
-
-struct struct_initData {
- unsigned char req;
- unsigned short value;
- unsigned short index;
-};
-
-/*
- * ibmcam_size_to_videosize()
- *
- * This procedure converts module option 'size' into the actual
- * videosize_t that defines the image size in pixels. We need
- * simplified 'size' because user wants a simple enumerated list
- * of choices, not an infinite set of possibilities.
- */
-static videosize_t ibmcam_size_to_videosize(int size)
-{
- videosize_t vs = VIDEOSIZE_352x288;
- RESTRICT_TO_RANGE(size, 0, (SIZE_LastItem-1));
- switch (size) {
- case SIZE_128x96:
- vs = VIDEOSIZE_128x96;
- break;
- case SIZE_160x120:
- vs = VIDEOSIZE_160x120;
- break;
- case SIZE_176x144:
- vs = VIDEOSIZE_176x144;
- break;
- case SIZE_320x240:
- vs = VIDEOSIZE_320x240;
- break;
- case SIZE_352x240:
- vs = VIDEOSIZE_352x240;
- break;
- case SIZE_352x288:
- vs = VIDEOSIZE_352x288;
- break;
- case SIZE_640x480:
- vs = VIDEOSIZE_640x480;
- break;
- default:
- err("size=%d. is not valid", size);
- break;
- }
- return vs;
-}
-
-/*
- * ibmcam_find_header()
- *
- * Locate one of supported header markers in the queue.
- * Once found, remove all preceding bytes AND the marker (4 bytes)
- * from the data pump queue. Whatever follows must be video lines.
- *
- * History:
- * 1/21/00 Created.
- */
-static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame here */
-{
- struct usbvideo_frame *frame;
- ibmcam_t *icam;
-
- if ((uvd->curframe) < 0 || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
- err("ibmcam_find_header: Illegal frame %d.", uvd->curframe);
- return scan_EndParse;
- }
- icam = IBMCAM_T(uvd);
- assert(icam != NULL);
- frame = &uvd->frame[uvd->curframe];
- icam->has_hdr = 0;
- switch (icam->camera_model) {
- case IBMCAM_MODEL_1:
- {
- const int marker_len = 4;
- while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
- if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
- (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00))
- {
-#if 0 /* This code helps to detect new frame markers */
- dev_info(&uvd->dev->dev,
- "Header sig: 00 FF 00 %02X\n",
- RING_QUEUE_PEEK(&uvd->dp, 3));
-#endif
- frame->header = RING_QUEUE_PEEK(&uvd->dp, 3);
- if ((frame->header == HDRSIG_MODEL1_128x96) ||
- (frame->header == HDRSIG_MODEL1_176x144) ||
- (frame->header == HDRSIG_MODEL1_352x288))
- {
-#if 0
- dev_info(&uvd->dev->dev,
- "Header found.\n");
-#endif
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
- icam->has_hdr = 1;
- break;
- }
- }
- /* If we are still here then this doesn't look like a header */
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
- }
- break;
- }
- case IBMCAM_MODEL_2:
-case IBMCAM_MODEL_4:
- {
- int marker_len = 0;
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- marker_len = 10;
- break;
- default:
- marker_len = 2;
- break;
- }
- while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
- if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF))
- {
-#if 0
- dev_info(&uvd->dev->dev, "Header found.\n");
-#endif
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
- icam->has_hdr = 1;
- frame->header = HDRSIG_MODEL1_176x144;
- break;
- }
- /* If we are still here then this doesn't look like a header */
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
- }
- break;
- }
- case IBMCAM_MODEL_3:
- { /*
- * Headers: (one precedes every frame). nc=no compression,
- * bq=best quality bf=best frame rate.
- *
- * 176x144: 00 FF 02 { 0A=nc CA=bq EA=bf }
- * 320x240: 00 FF 02 { 08=nc 28=bq 68=bf }
- * 640x480: 00 FF 03 { 08=nc 28=bq 68=bf }
- *
- * Bytes '00 FF' seem to indicate header. Other two bytes
- * encode the frame type. This is a set of bit fields that
- * encode image size, compression type etc. These fields
- * do NOT contain frame number because all frames carry
- * the same header.
- */
- const int marker_len = 4;
- while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
- if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
- (RING_QUEUE_PEEK(&uvd->dp, 2) != 0xFF))
- {
- /*
- * Combine 2 bytes of frame type into one
- * easy to use value
- */
- unsigned long byte3, byte4;
-
- byte3 = RING_QUEUE_PEEK(&uvd->dp, 2);
- byte4 = RING_QUEUE_PEEK(&uvd->dp, 3);
- frame->header = (byte3 << 8) | byte4;
-#if 0
- dev_info(&uvd->dev->dev, "Header found.\n");
-#endif
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
- icam->has_hdr = 1;
- break;
- }
- /* If we are still here then this doesn't look like a header */
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
- }
- break;
- }
- default:
- break;
- }
- if (!icam->has_hdr) {
- if (uvd->debug > 2)
- dev_info(&uvd->dev->dev,
- "Skipping frame, no header\n");
- return scan_EndParse;
- }
-
- /* Header found */
- icam->has_hdr = 1;
- uvd->stats.header_count++;
- frame->scanstate = ScanState_Lines;
- frame->curline = 0;
-
- if (flags & FLAGS_FORCE_TESTPATTERN) {
- usbvideo_TestPattern(uvd, 1, 1);
- return scan_NextFrame;
- }
- return scan_Continue;
-}
-
-/*
- * ibmcam_parse_lines()
- *
- * Parse one line (interlaced) from the buffer, put
- * decoded RGB value into the current frame buffer
- * and add the written number of bytes (RGB) to
- * the *pcopylen.
- *
- * History:
- * 21-Jan-2000 Created.
- * 12-Oct-2000 Reworked to reflect interlaced nature of the data.
- */
-static enum ParseState ibmcam_parse_lines(
- struct uvd *uvd,
- struct usbvideo_frame *frame,
- long *pcopylen)
-{
- unsigned char *f;
- ibmcam_t *icam;
- unsigned int len, scanLength, scanHeight, order_uv, order_yc;
- int v4l_linesize; /* V4L line offset */
- const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
- const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
- const int ccm = 128; /* Color correction median - see below */
- int y, u, v, i, frame_done=0, color_corr;
- static unsigned char lineBuffer[640*3];
- unsigned const char *chromaLine, *lumaLine;
-
- assert(uvd != NULL);
- assert(frame != NULL);
- icam = IBMCAM_T(uvd);
- assert(icam != NULL);
- color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
- RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
-
- v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
-
- if (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_4) {
- /* Model 4 frame markers do not carry image size identification */
- switch (uvd->videosize) {
- case VIDEOSIZE_128x96:
- case VIDEOSIZE_160x120:
- case VIDEOSIZE_176x144:
- scanLength = VIDEOSIZE_X(uvd->videosize);
- scanHeight = VIDEOSIZE_Y(uvd->videosize);
- break;
- default:
- err("ibmcam_parse_lines: Wrong mode.");
- return scan_Out;
- }
- order_yc = 1; /* order_yc: true=Yc false=cY ('c'=either U or V) */
- order_uv = 1; /* Always true in this algorithm */
- } else {
- switch (frame->header) {
- case HDRSIG_MODEL1_128x96:
- scanLength = 128;
- scanHeight = 96;
- order_uv = 1; /* U Y V Y ... */
- break;
- case HDRSIG_MODEL1_176x144:
- scanLength = 176;
- scanHeight = 144;
- order_uv = 1; /* U Y V Y ... */
- break;
- case HDRSIG_MODEL1_352x288:
- scanLength = 352;
- scanHeight = 288;
- order_uv = 0; /* Y V Y V ... */
- break;
- default:
- err("Unknown header signature 00 FF 00 %02lX", frame->header);
- return scan_NextFrame;
- }
- /* order_yc: true=Yc false=cY ('c'=either U or V) */
- order_yc = (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_2);
- }
-
- len = scanLength * 3;
- assert(len <= sizeof(lineBuffer));
-
- /*
- * Lines are organized this way:
- *
- * I420:
- * ~~~~
- * <scanLength->
- * ___________________________________
- * |-----Y-----|---UVUVUV...UVUV-----| \
- * |-----------+---------------------| \
- * |<-- 176 -->|<------ 176*2 ------>| Total 72. lines (interlaced)
- * |... ... | ... | /
- * |<-- 352 -->|<------ 352*2 ------>| Total 144. lines (interlaced)
- * |___________|_____________________| /
- * \ \
- * lumaLine chromaLine
- */
-
- /* Make sure there's enough data for the entire line */
- if (RingQueue_GetLength(&uvd->dp) < len)
- return scan_Out;
-
- /* Suck one line out of the ring queue */
- RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
-
- /*
- * Make sure that our writing into output buffer
- * will not exceed the buffer. Mind that we may write
- * not into current output scanline but in several after
- * it as well (if we enlarge image vertically.)
- */
- if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
- return scan_NextFrame;
-
- /*
- * Now we are sure that entire line (representing all 'scanLength'
- * pixels from the camera) is available in the buffer. We
- * start copying the line left-aligned to the V4L buffer.
- * If the camera line is shorter then we should pad the V4L
- * buffer with something (black) to complete the line.
- */
- assert(frame->data != NULL);
- f = frame->data + (v4l_linesize * frame->curline);
-
- /*
- * To obtain chrominance data from the 'chromaLine' use this:
- * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...
- * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...
- *
- * Indices must be calculated this way:
- * v_index = (i >> 1) << 2;
- * u_index = (i >> 1) << 2 + 2;
- *
- * where 'i' is the column number [0..VIDEOSIZE_X(frame->request)-1]
- */
- lumaLine = lineBuffer;
- chromaLine = lineBuffer + scanLength;
- for (i = 0; i < VIDEOSIZE_X(frame->request); i++)
- {
- unsigned char rv, gv, bv; /* RGB components */
-
- /* Check for various visual debugging hints (colorized pixels) */
- if ((flags & FLAGS_DISPLAY_HINTS) && (icam->has_hdr)) {
- /*
- * This is bad and should not happen. This means that
- * we somehow overshoot the line and encountered new
- * frame! Obviously our camera/V4L frame size is out
- * of whack. This cyan dot will help you to figure
- * out where exactly the new frame arrived.
- */
- if (icam->has_hdr == 1) {
- bv = 0; /* Yellow marker */
- gv = 0xFF;
- rv = 0xFF;
- } else {
- bv = 0xFF; /* Cyan marker */
- gv = 0xFF;
- rv = 0;
- }
- icam->has_hdr = 0;
- goto make_pixel;
- }
-
- /*
- * Check if we are still in range. We may be out of range if our
- * V4L canvas is wider or taller than the camera "native" image.
- * Then we quickly fill the remainder of the line with zeros to
- * make black color and quit the horizontal scanning loop.
- */
- if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
- const int j = i * V4L_BYTES_PER_PIXEL;
-#if USES_IBMCAM_PUTPIXEL
- /* Refresh 'f' because we don't use it much with PUTPIXEL */
- f = frame->data + (v4l_linesize * frame->curline) + j;
-#endif
- memset(f, 0, v4l_linesize - j);
- break;
- }
-
- y = lumaLine[i];
- if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
- rv = gv = bv = y;
- else {
- int off_0, off_2;
-
- off_0 = (i >> 1) << 2;
- off_2 = off_0 + 2;
-
- if (order_yc) {
- off_0++;
- off_2++;
- }
- if (!order_uv) {
- off_0 += 2;
- off_2 -= 2;
- }
- u = chromaLine[off_0] + hue_corr;
- v = chromaLine[off_2] + hue2_corr;
-
- /* Apply color correction */
- if (color_corr != 0) {
- /* Magnify up to 2 times, reduce down to zero saturation */
- u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
- v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
- }
- YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
- }
-
- make_pixel:
- /*
- * The purpose of creating the pixel here, in one,
- * dedicated place is that we may need to make the
- * pixel wider and taller than it actually is. This
- * may be used if camera generates small frames for
- * sake of frame rate (or any other reason.)
- *
- * The output data consists of B, G, R bytes
- * (in this order).
- */
-#if USES_IBMCAM_PUTPIXEL
- RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
-#else
- *f++ = bv;
- *f++ = gv;
- *f++ = rv;
-#endif
- /*
- * Typically we do not decide within a legitimate frame
- * that we want to end the frame. However debugging code
- * may detect marker of new frame within the data. Then
- * this condition activates. The 'data' pointer is already
- * pointing at the new marker, so we'd better leave it as is.
- */
- if (frame_done)
- break; /* End scanning of lines */
- }
- /*
- * Account for number of bytes that we wrote into output V4L frame.
- * We do it here, after we are done with the scanline, because we
- * may fill more than one output scanline if we do vertical
- * enlargement.
- */
- frame->curline += 2;
- if (pcopylen != NULL)
- *pcopylen += 2 * v4l_linesize;
- frame->deinterlace = Deinterlace_FillOddLines;
-
- if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
- return scan_NextFrame;
- else
- return scan_Continue;
-}
-
-/*
- * ibmcam_model2_320x240_parse_lines()
- *
- * This procedure deals with a weird RGB format that is produced by IBM
- * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175,
- * depending on horizontal size of the picture:
- *
- * <--- 160 or 176 pairs of RA,RB bytes ----->
- * *-----------------------------------------* \
- * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx | \ This is pair of horizontal lines,
- * |-----+-----+-----+-----+ ... +-----+-----| *- or one interlaced line, total
- * | B0 | G0 | B1 | G1 | ... | Bx | Gx | / 120 or 144 such pairs which yield
- * |=====+=====+=====+=====+ ... +=====+=====| / 240 or 288 lines after deinterlacing.
- *
- * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1
- * defines ONE pixel. Therefore this format yields 176x144 "decoded"
- * resolution at best. I do not know why camera sends such format - the
- * previous model (1) just used interlaced I420 and everyone was happy.
- *
- * I do not know what is the difference between RAi and RBi bytes. Both
- * seemingly represent R component, but slightly vary in value (so that
- * the picture looks a bit colored if one or another is used). I use
- * them both as R component in attempt to at least partially recover the
- * lost resolution.
- */
-static enum ParseState ibmcam_model2_320x240_parse_lines(
- struct uvd *uvd,
- struct usbvideo_frame *frame,
- long *pcopylen)
-{
- unsigned char *f, *la, *lb;
- unsigned int len;
- int v4l_linesize; /* V4L line offset */
- int i, j, frame_done=0, color_corr;
- int scanLength, scanHeight;
- static unsigned char lineBuffer[352*2];
-
- switch (uvd->videosize) {
- case VIDEOSIZE_320x240:
- case VIDEOSIZE_352x240:
- case VIDEOSIZE_352x288:
- scanLength = VIDEOSIZE_X(uvd->videosize);
- scanHeight = VIDEOSIZE_Y(uvd->videosize);
- break;
- default:
- err("ibmcam_model2_320x240_parse_lines: Wrong mode.");
- return scan_Out;
- }
-
- color_corr = (uvd->vpic.colour) >> 8; /* 0..+255 */
- v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
-
- len = scanLength * 2; /* See explanation above */
- assert(len <= sizeof(lineBuffer));
-
- /* Make sure there's enough data for the entire line */
- if (RingQueue_GetLength(&uvd->dp) < len)
- return scan_Out;
-
- /* Suck one line out of the ring queue */
- RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
-
- /*
- * Make sure that our writing into output buffer
- * will not exceed the buffer. Mind that we may write
- * not into current output scanline but in several after
- * it as well (if we enlarge image vertically.)
- */
- if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
- return scan_NextFrame;
-
- la = lineBuffer;
- lb = lineBuffer + scanLength;
-
- /*
- * Now we are sure that entire line (representing all
- * VIDEOSIZE_X(frame->request)
- * pixels from the camera) is available in the scratch buffer. We
- * start copying the line left-aligned to the V4L buffer (which
- * might be larger - not smaller, hopefully). If the camera
- * line is shorter then we should pad the V4L buffer with something
- * (black in this case) to complete the line.
- */
- f = frame->data + (v4l_linesize * frame->curline);
-
- /* Fill the 2-line strip */
- for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
- int y, rv, gv, bv; /* RGB components */
-
- j = i & (~1);
-
- /* Check for various visual debugging hints (colorized pixels) */
- if ((flags & FLAGS_DISPLAY_HINTS) && (IBMCAM_T(uvd)->has_hdr)) {
- if (IBMCAM_T(uvd)->has_hdr == 1) {
- bv = 0; /* Yellow marker */
- gv = 0xFF;
- rv = 0xFF;
- } else {
- bv = 0xFF; /* Cyan marker */
- gv = 0xFF;
- rv = 0;
- }
- IBMCAM_T(uvd)->has_hdr = 0;
- goto make_pixel;
- }
-
- /*
- * Check if we are still in range. We may be out of range if our
- * V4L canvas is wider or taller than the camera "native" image.
- * Then we quickly fill the remainder of the line with zeros to
- * make black color and quit the horizontal scanning loop.
- */
- if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
- const int offset = i * V4L_BYTES_PER_PIXEL;
-#if USES_IBMCAM_PUTPIXEL
- /* Refresh 'f' because we don't use it much with PUTPIXEL */
- f = frame->data + (v4l_linesize * frame->curline) + offset;
-#endif
- memset(f, 0, v4l_linesize - offset);
- break;
- }
-
- /*
- * Here I use RA and RB components, one per physical pixel.
- * This causes fine vertical grid on the picture but may improve
- * horizontal resolution. If you prefer replicating, use this:
- * rv = la[j + 0]; ... or ... rv = la[j + 1];
- * then the pixel will be replicated.
- */
- rv = la[i];
- gv = lb[j + 1];
- bv = lb[j + 0];
-
- y = (rv + gv + bv) / 3; /* Brightness (badly calculated) */
-
- if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
- rv = gv = bv = y;
- else if (color_corr != 128) {
-
- /* Calculate difference between color and brightness */
- rv -= y;
- gv -= y;
- bv -= y;
-
- /* Scale differences */
- rv = (rv * color_corr) / 128;
- gv = (gv * color_corr) / 128;
- bv = (bv * color_corr) / 128;
-
- /* Reapply brightness */
- rv += y;
- gv += y;
- bv += y;
-
- /* Watch for overflows */
- RESTRICT_TO_RANGE(rv, 0, 255);
- RESTRICT_TO_RANGE(gv, 0, 255);
- RESTRICT_TO_RANGE(bv, 0, 255);
- }
-
- make_pixel:
- RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
- }
- /*
- * Account for number of bytes that we wrote into output V4L frame.
- * We do it here, after we are done with the scanline, because we
- * may fill more than one output scanline if we do vertical
- * enlargement.
- */
- frame->curline += 2;
- *pcopylen += v4l_linesize * 2;
- frame->deinterlace = Deinterlace_FillOddLines;
-
- if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
- return scan_NextFrame;
- else
- return scan_Continue;
-}
-
-/*
- * ibmcam_model3_parse_lines()
- *
- * | Even lines | Odd Lines |
- * -----------------------------------|
- * |YYY........Y|UYVYUYVY.........UYVY|
- * |YYY........Y|UYVYUYVY.........UYVY|
- * |............|.....................|
- * |YYY........Y|UYVYUYVY.........UYVY|
- * |------------+---------------------|
- *
- * There is one (U, V) chroma pair for every four luma (Y) values. This
- * function reads a pair of lines at a time and obtains missing chroma values
- * from adjacent pixels.
- */
-static enum ParseState ibmcam_model3_parse_lines(
- struct uvd *uvd,
- struct usbvideo_frame *frame,
- long *pcopylen)
-{
- unsigned char *data;
- const unsigned char *color;
- unsigned int len;
- int v4l_linesize; /* V4L line offset */
- const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
- const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
- const int ccm = 128; /* Color correction median - see below */
- int i, u, v, rw, data_w=0, data_h=0, color_corr;
- static unsigned char lineBuffer[640*3];
- int line;
-
- color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
- RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
-
- v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
-
- /* The header tells us what sort of data is in this frame */
- switch (frame->header) {
- /*
- * Uncompressed modes (that are easy to decode).
- */
- case 0x0308:
- data_w = 640;
- data_h = 480;
- break;
- case 0x0208:
- data_w = 320;
- data_h = 240;
- break;
- case 0x020A:
- data_w = 160;
- data_h = 120;
- break;
- /*
- * Compressed modes (ViCE - that I don't know how to decode).
- */
- case 0x0328: /* 640x480, best quality compression */
- case 0x0368: /* 640x480, best frame rate compression */
- case 0x0228: /* 320x240, best quality compression */
- case 0x0268: /* 320x240, best frame rate compression */
- case 0x02CA: /* 160x120, best quality compression */
- case 0x02EA: /* 160x120, best frame rate compression */
- /* Do nothing with this - not supported */
- err("Unsupported mode $%04lx", frame->header);
- return scan_NextFrame;
- default:
- /* Catch unknown headers, may help in learning new headers */
- err("Strange frame->header=$%08lx", frame->header);
- return scan_NextFrame;
- }
-
- /*
- * Make sure that our writing into output buffer
- * will not exceed the buffer. Note that we may write
- * not into current output scanline but in several after
- * it as well (if we enlarge image vertically.)
- */
- if ((frame->curline + 1) >= data_h) {
- if (uvd->debug >= 3)
- dev_info(&uvd->dev->dev,
- "Reached line %d. (frame is done)\n",
- frame->curline);
- return scan_NextFrame;
- }
-
- /* Make sure that lineBuffer can store two lines of data */
- len = 3 * data_w; /* <y-data> <uyvy-data> */
- assert(len <= sizeof(lineBuffer));
-
- /* Make sure there's enough data for two lines */
- if (RingQueue_GetLength(&uvd->dp) < len)
- return scan_Out;
-
- /* Suck two lines of data out of the ring queue */
- RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
-
- data = lineBuffer;
- color = data + data_w; /* Point to where color planes begin */
-
- /* Bottom-to-top scanning */
- rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;
- RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);
-
- /* Iterate over two lines. */
- for (line = 0; line < 2; line++) {
- for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
- int y;
- int rv, gv, bv; /* RGB components */
-
- if (i >= data_w) {
- RGB24_PUTPIXEL(frame, i, rw, 0, 0, 0);
- continue;
- }
-
- /* first line is YYY...Y; second is UYVY...UYVY */
- y = data[(line == 0) ? i : (i*2 + 1)];
-
- /* Apply static color correction */
- u = color[(i/2)*4] + hue_corr;
- v = color[(i/2)*4 + 2] + hue2_corr;
-
- /* Apply color correction */
- if (color_corr != 0) {
- /* Magnify up to 2 times, reduce down to zero saturation */
- u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
- v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
- }
-
-
- YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
- RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* No deinterlacing */
- }
-
- /* Check for the end of requested data */
- if (rw == 0)
- break;
-
- /* Prepare for the second line */
- rw--;
- data = lineBuffer + data_w;
- }
- frame->deinterlace = Deinterlace_None;
-
- /*
- * Account for number of bytes that we wrote into output V4L frame.
- * We do it here, after we are done with the scanline, because we
- * may fill more than one output scanline if we do vertical
- * enlargement.
- */
- frame->curline += 2;
- *pcopylen += 2 * v4l_linesize;
-
- if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
- if (uvd->debug >= 3) {
- dev_info(&uvd->dev->dev,
- "All requested lines (%ld.) done.\n",
- VIDEOSIZE_Y(frame->request));
- }
- return scan_NextFrame;
- } else
- return scan_Continue;
-}
-
-/*
- * ibmcam_model4_128x96_parse_lines()
- *
- * This decoder is for one strange data format that is produced by Model 4
- * camera only in 128x96 mode. This is RGB format and here is its description.
- * First of all, this is non-interlaced stream, meaning that all scan lines
- * are present in the datastream. There are 96 consecutive blocks of data
- * that describe all 96 lines of the image. Each block is 5*128 bytes long
- * and carries R, G, B components. The format of the block is shown in the
- * code below. First 128*2 bytes are interleaved R and G components. Then
- * we have a gap (junk data) 64 bytes long. Then follow B and something
- * else, also interleaved (this makes another 128*2 bytes). After that
- * probably another 64 bytes of junk follow.
- *
- * History:
- * 10-Feb-2001 Created.
- */
-static enum ParseState ibmcam_model4_128x96_parse_lines(
- struct uvd *uvd,
- struct usbvideo_frame *frame,
- long *pcopylen)
-{
- const unsigned char *data_rv, *data_gv, *data_bv;
- unsigned int len;
- int i, v4l_linesize; /* V4L line offset */
- const int data_w=128, data_h=96;
- static unsigned char lineBuffer[128*5];
-
- v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
-
- /*
- * Make sure that our writing into output buffer
- * will not exceed the buffer. Note that we may write
- * not into current output scanline but in several after
- * it as well (if we enlarge image vertically.)
- */
- if ((frame->curline + 1) >= data_h) {
- if (uvd->debug >= 3)
- dev_info(&uvd->dev->dev,
- "Reached line %d. (frame is done)\n",
- frame->curline);
- return scan_NextFrame;
- }
-
- /*
- * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________
- * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 --->
- */
-
- /* Make sure there's enough data for the entire line */
- len = 5 * data_w;
- assert(len <= sizeof(lineBuffer));
-
- /* Make sure there's enough data for the entire line */
- if (RingQueue_GetLength(&uvd->dp) < len)
- return scan_Out;
-
- /* Suck one line out of the ring queue */
- RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
-
- data_rv = lineBuffer;
- data_gv = lineBuffer + 1;
- data_bv = lineBuffer + data_w*2 + data_w/2;
- for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
- int rv, gv, bv; /* RGB components */
- if (i < data_w) {
- const int j = i * 2;
- gv = data_rv[j];
- rv = data_gv[j];
- bv = data_bv[j];
- if (flags & FLAGS_MONOCHROME) {
- unsigned long y;
- y = rv + gv + bv;
- y /= 3;
- if (y > 0xFF)
- y = 0xFF;
- rv = gv = bv = (unsigned char) y;
- }
- } else {
- rv = gv = bv = 0;
- }
- RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
- }
- frame->deinterlace = Deinterlace_None;
- frame->curline++;
- *pcopylen += v4l_linesize;
-
- if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
- if (uvd->debug >= 3) {
- dev_info(&uvd->dev->dev,
- "All requested lines (%ld.) done.\n",
- VIDEOSIZE_Y(frame->request));
- }
- return scan_NextFrame;
- } else
- return scan_Continue;
-}
-
-/*
- * ibmcam_ProcessIsocData()
- *
- * Generic routine to parse the ring queue data. It employs either
- * ibmcam_find_header() or ibmcam_parse_lines() to do most
- * of work.
- *
- * History:
- * 1/21/00 Created.
- */
-static void ibmcam_ProcessIsocData(struct uvd *uvd,
- struct usbvideo_frame *frame)
-{
- enum ParseState newstate;
- long copylen = 0;
- int mod = IBMCAM_T(uvd)->camera_model;
-
- while (1) {
- newstate = scan_Out;
- if (RingQueue_GetLength(&uvd->dp) > 0) {
- if (frame->scanstate == ScanState_Scanning) {
- newstate = ibmcam_find_header(uvd);
- } else if (frame->scanstate == ScanState_Lines) {
- if ((mod == IBMCAM_MODEL_2) &&
- ((uvd->videosize == VIDEOSIZE_352x288) ||
- (uvd->videosize == VIDEOSIZE_320x240) ||
- (uvd->videosize == VIDEOSIZE_352x240)))
- {
- newstate = ibmcam_model2_320x240_parse_lines(
- uvd, frame, &copylen);
- } else if (mod == IBMCAM_MODEL_4) {
- /*
- * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB)
- * for 320x240 and above; 160x120 and 176x144 uses Model 1
- * decoder (YUV), and 128x96 mode uses ???
- */
- if ((uvd->videosize == VIDEOSIZE_352x288) ||
- (uvd->videosize == VIDEOSIZE_320x240) ||
- (uvd->videosize == VIDEOSIZE_352x240))
- {
- newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, &copylen);
- } else if (uvd->videosize == VIDEOSIZE_128x96) {
- newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, &copylen);
- } else {
- newstate = ibmcam_parse_lines(uvd, frame, &copylen);
- }
- } else if (mod == IBMCAM_MODEL_3) {
- newstate = ibmcam_model3_parse_lines(uvd, frame, &copylen);
- } else {
- newstate = ibmcam_parse_lines(uvd, frame, &copylen);
- }
- }
- }
- if (newstate == scan_Continue)
- continue;
- else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
- break;
- else
- return; /* scan_EndParse */
- }
-
- if (newstate == scan_NextFrame) {
- frame->frameState = FrameState_Done;
- uvd->curframe = -1;
- uvd->stats.frame_num++;
- if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) {
- /* Need software contrast adjustment for those cameras */
- frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST;
- }
- }
-
- /* Update the frame's uncompressed length. */
- frame->seqRead_Length += copylen;
-
-#if 0
- {
- static unsigned char j=0;
- memset(frame->data, j++, uvd->max_frame_size);
- frame->frameState = FrameState_Ready;
- }
-#endif
-}
-
-/*
- * ibmcam_veio()
- *
- * History:
- * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
- */
-static int ibmcam_veio(
- struct uvd *uvd,
- unsigned char req,
- unsigned short value,
- unsigned short index)
-{
- static const char proc[] = "ibmcam_veio";
- unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
- int i;
-
- if (!CAMERA_IS_OPERATIONAL(uvd))
- return 0;
-
- if (req == 1) {
- i = usb_control_msg(
- uvd->dev,
- usb_rcvctrlpipe(uvd->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- value,
- index,
- cp,
- sizeof(cp),
- 1000);
-#if 0
- dev_info(&uvd->dev->dev,
- "USB => %02x%02x%02x%02x%02x%02x%02x%02x "
- "(req=$%02x val=$%04x ind=$%04x)\n",
- cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
- req, value, index);
-#endif
- } else {
- i = usb_control_msg(
- uvd->dev,
- usb_sndctrlpipe(uvd->dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- value,
- index,
- NULL,
- 0,
- 1000);
- }
- if (i < 0) {
- err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
- proc, i);
- uvd->last_error = i;
- }
- return i;
-}
-
-/*
- * ibmcam_calculate_fps()
- *
- * This procedure roughly calculates the real frame rate based
- * on FPS code (framerate=NNN option). Actual FPS differs
- * slightly depending on lighting conditions, so that actual frame
- * rate is determined by the camera. Since I don't know how to ask
- * the camera what FPS is now I have to use the FPS code instead.
- *
- * The FPS code is in range [0..6], 0 is slowest, 6 is fastest.
- * Corresponding real FPS should be in range [3..30] frames per second.
- * The conversion formula is obvious:
- *
- * real_fps = 3 + (fps_code * 4.5)
- *
- * History:
- * 1/18/00 Created.
- */
-static int ibmcam_calculate_fps(struct uvd *uvd)
-{
- return 3 + framerate*4 + framerate/2;
-}
-
-/*
- * ibmcam_send_FF_04_02()
- *
- * This procedure sends magic 3-command prefix to the camera.
- * The purpose of this prefix is not known.
- *
- * History:
- * 1/2/00 Created.
- */
-static void ibmcam_send_FF_04_02(struct uvd *uvd)
-{
- ibmcam_veio(uvd, 0, 0x00FF, 0x0127);
- ibmcam_veio(uvd, 0, 0x0004, 0x0124);
- ibmcam_veio(uvd, 0, 0x0002, 0x0124);
-}
-
-static void ibmcam_send_00_04_06(struct uvd *uvd)
-{
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x0004, 0x0124);
- ibmcam_veio(uvd, 0, 0x0006, 0x0124);
-}
-
-static void ibmcam_send_x_00(struct uvd *uvd, unsigned short x)
-{
- ibmcam_veio(uvd, 0, x, 0x0127);
- ibmcam_veio(uvd, 0, 0x0000, 0x0124);
-}
-
-static void ibmcam_send_x_00_05(struct uvd *uvd, unsigned short x)
-{
- ibmcam_send_x_00(uvd, x);
- ibmcam_veio(uvd, 0, 0x0005, 0x0124);
-}
-
-static void ibmcam_send_x_00_05_02(struct uvd *uvd, unsigned short x)
-{
- ibmcam_veio(uvd, 0, x, 0x0127);
- ibmcam_veio(uvd, 0, 0x0000, 0x0124);
- ibmcam_veio(uvd, 0, 0x0005, 0x0124);
- ibmcam_veio(uvd, 0, 0x0002, 0x0124);
-}
-
-static void ibmcam_send_x_01_00_05(struct uvd *uvd, unsigned short x)
-{
- ibmcam_veio(uvd, 0, x, 0x0127);
- ibmcam_veio(uvd, 0, 0x0001, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0124);
- ibmcam_veio(uvd, 0, 0x0005, 0x0124);
-}
-
-static void ibmcam_send_x_00_05_02_01(struct uvd *uvd, unsigned short x)
-{
- ibmcam_veio(uvd, 0, x, 0x0127);
- ibmcam_veio(uvd, 0, 0x0000, 0x0124);
- ibmcam_veio(uvd, 0, 0x0005, 0x0124);
- ibmcam_veio(uvd, 0, 0x0002, 0x0124);
- ibmcam_veio(uvd, 0, 0x0001, 0x0124);
-}
-
-static void ibmcam_send_x_00_05_02_08_01(struct uvd *uvd, unsigned short x)
-{
- ibmcam_veio(uvd, 0, x, 0x0127);
- ibmcam_veio(uvd, 0, 0x0000, 0x0124);
- ibmcam_veio(uvd, 0, 0x0005, 0x0124);
- ibmcam_veio(uvd, 0, 0x0002, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0124);
- ibmcam_veio(uvd, 0, 0x0001, 0x0124);
-}
-
-static void ibmcam_Packet_Format1(struct uvd *uvd, unsigned char fkey, unsigned char val)
-{
- ibmcam_send_x_01_00_05(uvd, unknown_88);
- ibmcam_send_x_00_05(uvd, fkey);
- ibmcam_send_x_00_05_02_08_01(uvd, val);
- ibmcam_send_x_00_05(uvd, unknown_88);
- ibmcam_send_x_00_05_02_01(uvd, fkey);
- ibmcam_send_x_00_05(uvd, unknown_89);
- ibmcam_send_x_00(uvd, fkey);
- ibmcam_send_00_04_06(uvd);
- ibmcam_veio(uvd, 1, 0x0000, 0x0126);
- ibmcam_send_FF_04_02(uvd);
-}
-
-static void ibmcam_PacketFormat2(struct uvd *uvd, unsigned char fkey, unsigned char val)
-{
- ibmcam_send_x_01_00_05 (uvd, unknown_88);
- ibmcam_send_x_00_05 (uvd, fkey);
- ibmcam_send_x_00_05_02 (uvd, val);
-}
-
-static void ibmcam_model2_Packet2(struct uvd *uvd)
-{
- ibmcam_veio(uvd, 0, 0x00ff, 0x012d);
- ibmcam_veio(uvd, 0, 0xfea3, 0x0124);
-}
-
-static void ibmcam_model2_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
-{
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x00ff, 0x012e);
- ibmcam_veio(uvd, 0, v1, 0x012f);
- ibmcam_veio(uvd, 0, 0x00ff, 0x0130);
- ibmcam_veio(uvd, 0, 0xc719, 0x0124);
- ibmcam_veio(uvd, 0, v2, 0x0127);
-
- ibmcam_model2_Packet2(uvd);
-}
-
-/*
- * ibmcam_model3_Packet1()
- *
- * 00_0078_012d
- * 00_0097_012f
- * 00_d141_0124
- * 00_0096_0127
- * 00_fea8_0124
-*/
-static void ibmcam_model3_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
-{
- ibmcam_veio(uvd, 0, 0x0078, 0x012d);
- ibmcam_veio(uvd, 0, v1, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, v2, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
-}
-
-static void ibmcam_model4_BrightnessPacket(struct uvd *uvd, int i)
-{
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0026, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, i, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0038, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
-}
-
-/*
- * ibmcam_adjust_contrast()
- *
- * The contrast value changes from 0 (high contrast) to 15 (low contrast).
- * This is in reverse to usual order of things (such as TV controls), so
- * we reverse it again here.
- *
- * TODO: we probably don't need to send the setup 5 times...
- *
- * History:
- * 1/2/00 Created.
- */
-static void ibmcam_adjust_contrast(struct uvd *uvd)
-{
- unsigned char a_contrast = uvd->vpic.contrast >> 12;
- unsigned char new_contrast;
-
- if (a_contrast >= 16)
- a_contrast = 15;
- new_contrast = 15 - a_contrast;
- if (new_contrast == uvd->vpic_old.contrast)
- return;
- uvd->vpic_old.contrast = new_contrast;
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- {
- const int ntries = 5;
- int i;
- for (i=0; i < ntries; i++) {
- ibmcam_Packet_Format1(uvd, contrast_14, new_contrast);
- ibmcam_send_FF_04_02(uvd);
- }
- break;
- }
- case IBMCAM_MODEL_2:
- case IBMCAM_MODEL_4:
- /* Models 2, 4 do not have this control; implemented in software. */
- break;
- case IBMCAM_MODEL_3:
- { /* Preset hardware values */
- static const struct {
- unsigned short cv1;
- unsigned short cv2;
- unsigned short cv3;
- } cv[7] = {
- { 0x05, 0x05, 0x0f }, /* Minimum */
- { 0x04, 0x04, 0x16 },
- { 0x02, 0x03, 0x16 },
- { 0x02, 0x08, 0x16 },
- { 0x01, 0x0c, 0x16 },
- { 0x01, 0x0e, 0x16 },
- { 0x01, 0x10, 0x16 } /* Maximum */
- };
- int i = a_contrast / 2;
- RESTRICT_TO_RANGE(i, 0, 6);
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
- ibmcam_model3_Packet1(uvd, 0x0067, cv[i].cv1);
- ibmcam_model3_Packet1(uvd, 0x005b, cv[i].cv2);
- ibmcam_model3_Packet1(uvd, 0x005c, cv[i].cv3);
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
- break;
- }
- default:
- break;
- }
-}
-
-/*
- * ibmcam_change_lighting_conditions()
- *
- * Camera model 1:
- * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
- *
- * Camera model 2:
- * We have 16 levels of lighting, 0 for bright light and up to 15 for
- * low light. But values above 5 or so are useless because camera is
- * not really capable to produce anything worth viewing at such light.
- * This setting may be altered only in certain camera state.
- *
- * Low lighting forces slower FPS. Lighting is set as a module parameter.
- *
- * History:
- * 1/5/00 Created.
- * 2/20/00 Added support for Model 2 cameras.
- */
-static void ibmcam_change_lighting_conditions(struct uvd *uvd)
-{
- if (debug > 0)
- dev_info(&uvd->dev->dev,
- "%s: Set lighting to %hu.\n", __func__, lighting);
-
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- {
- const int ntries = 5;
- int i;
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, light_27, (unsigned short) lighting);
- break;
- }
- case IBMCAM_MODEL_2:
-#if 0
- /*
- * This command apparently requires camera to be stopped. My
- * experiments showed that it -is- possible to alter the lighting
- * conditions setting "on the fly", but why bother? This setting does
- * not work reliably in all cases, so I decided simply to leave the
- * setting where Xirlink put it - in the camera setup phase. This code
- * is commented out because it does not work at -any- moment, so its
- * presence makes no sense. You may use it for experiments.
- */
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop camera */
- ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Start camera */
-#endif
- break;
- case IBMCAM_MODEL_3:
- case IBMCAM_MODEL_4:
- default:
- break;
- }
-}
-
-/*
- * ibmcam_set_sharpness()
- *
- * Cameras model 1 have internal smoothing feature. It is controlled by value in
- * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
- * Recommended value is 4. Cameras model 2 do not have this feature at all.
- */
-static void ibmcam_set_sharpness(struct uvd *uvd)
-{
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- {
- static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
- unsigned short i, sv;
-
- RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
- if (debug > 0)
- dev_info(&uvd->dev->dev, "%s: Set sharpness to %hu.\n",
- __func__, sharpness);
-
- sv = sa[sharpness - SHARPNESS_MIN];
- for (i=0; i < 2; i++) {
- ibmcam_send_x_01_00_05 (uvd, unknown_88);
- ibmcam_send_x_00_05 (uvd, sharp_13);
- ibmcam_send_x_00_05_02 (uvd, sv);
- }
- break;
- }
- case IBMCAM_MODEL_2:
- case IBMCAM_MODEL_4:
- /* Models 2, 4 do not have this control */
- break;
- case IBMCAM_MODEL_3:
- { /*
- * "Use a table of magic numbers.
- * This setting doesn't really change much.
- * But that's how Windows does it."
- */
- static const struct {
- unsigned short sv1;
- unsigned short sv2;
- unsigned short sv3;
- unsigned short sv4;
- } sv[7] = {
- { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
- { 0x01, 0x04, 0x05, 0x14 },
- { 0x02, 0x04, 0x05, 0x14 },
- { 0x03, 0x04, 0x05, 0x14 },
- { 0x03, 0x05, 0x05, 0x14 },
- { 0x03, 0x06, 0x05, 0x14 },
- { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
- };
- RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
- RESTRICT_TO_RANGE(sharpness, 0, 6);
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
- ibmcam_model3_Packet1(uvd, 0x0060, sv[sharpness].sv1);
- ibmcam_model3_Packet1(uvd, 0x0061, sv[sharpness].sv2);
- ibmcam_model3_Packet1(uvd, 0x0062, sv[sharpness].sv3);
- ibmcam_model3_Packet1(uvd, 0x0063, sv[sharpness].sv4);
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
- ibmcam_veio(uvd, 0, 0x0001, 0x0113);
- break;
- }
- default:
- break;
- }
-}
-
-/*
- * ibmcam_set_brightness()
- *
- * This procedure changes brightness of the picture.
- */
-static void ibmcam_set_brightness(struct uvd *uvd)
-{
- static const unsigned short n = 1;
-
- if (debug > 0)
- dev_info(&uvd->dev->dev, "%s: Set brightness to %hu.\n",
- __func__, uvd->vpic.brightness);
-
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- {
- unsigned short i, j, bv[3];
- bv[0] = bv[1] = bv[2] = uvd->vpic.brightness >> 10;
- if (bv[0] == (uvd->vpic_old.brightness >> 10))
- return;
- uvd->vpic_old.brightness = bv[0];
- for (j=0; j < 3; j++)
- for (i=0; i < n; i++)
- ibmcam_Packet_Format1(uvd, bright_3x[j], bv[j]);
- break;
- }
- case IBMCAM_MODEL_2:
- {
- unsigned short i, j;
- i = uvd->vpic.brightness >> 12; /* 0 .. 15 */
- j = 0x60 + i * ((0xee - 0x60) / 16); /* 0x60 .. 0xee or so */
- if (uvd->vpic_old.brightness == j)
- break;
- uvd->vpic_old.brightness = j;
- ibmcam_model2_Packet1(uvd, mod2_brightness, j);
- break;
- }
- case IBMCAM_MODEL_3:
- {
- /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
- unsigned short i =
- 0x0C + (uvd->vpic.brightness / (0xFFFF / (0x3F - 0x0C + 1)));
- RESTRICT_TO_RANGE(i, 0x0C, 0x3F);
- if (uvd->vpic_old.brightness == i)
- break;
- uvd->vpic_old.brightness = i;
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
- ibmcam_model3_Packet1(uvd, 0x0036, i);
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
- ibmcam_veio(uvd, 0, 0x0001, 0x0113);
- break;
- }
- case IBMCAM_MODEL_4:
- {
- /* Model 4: Brightness range 'i' in [0x04..0xb4] */
- unsigned short i = 0x04 + (uvd->vpic.brightness / (0xFFFF / (0xb4 - 0x04 + 1)));
- RESTRICT_TO_RANGE(i, 0x04, 0xb4);
- if (uvd->vpic_old.brightness == i)
- break;
- uvd->vpic_old.brightness = i;
- ibmcam_model4_BrightnessPacket(uvd, i);
- break;
- }
- default:
- break;
- }
-}
-
-static void ibmcam_set_hue(struct uvd *uvd)
-{
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_2:
- {
- unsigned short hue = uvd->vpic.hue >> 9; /* 0 .. 7F */
- if (uvd->vpic_old.hue == hue)
- return;
- uvd->vpic_old.hue = hue;
- ibmcam_model2_Packet1(uvd, mod2_hue, hue);
- /* ibmcam_model2_Packet1(uvd, mod2_saturation, sat); */
- break;
- }
- case IBMCAM_MODEL_3:
- {
-#if 0 /* This seems not to work. No problem, will fix programmatically */
- unsigned short hue = 0x05 + (uvd->vpic.hue / (0xFFFF / (0x37 - 0x05 + 1)));
- RESTRICT_TO_RANGE(hue, 0x05, 0x37);
- if (uvd->vpic_old.hue == hue)
- return;
- uvd->vpic_old.hue = hue;
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
- ibmcam_model3_Packet1(uvd, 0x007e, hue);
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
- ibmcam_veio(uvd, 0, 0x0001, 0x0113);
-#endif
- break;
- }
- case IBMCAM_MODEL_4:
- {
- unsigned short r_gain, g_gain, b_gain, hue;
-
- /*
- * I am not sure r/g/b_gain variables exactly control gain
- * of those channels. Most likely they subtly change some
- * very internal image processing settings in the camera.
- * In any case, here is what they do, and feel free to tweak:
- *
- * r_gain: seriously affects red gain
- * g_gain: seriously affects green gain
- * b_gain: seriously affects blue gain
- * hue: changes average color from violet (0) to red (0xFF)
- *
- * These settings are preset for a decent white balance in
- * 320x240, 352x288 modes. Low-res modes exhibit higher contrast
- * and therefore may need different values here.
- */
- hue = 20 + (uvd->vpic.hue >> 9);
- switch (uvd->videosize) {
- case VIDEOSIZE_128x96:
- r_gain = 90;
- g_gain = 166;
- b_gain = 175;
- break;
- case VIDEOSIZE_160x120:
- r_gain = 70;
- g_gain = 166;
- b_gain = 185;
- break;
- case VIDEOSIZE_176x144:
- r_gain = 160;
- g_gain = 175;
- b_gain = 185;
- break;
- default:
- r_gain = 120;
- g_gain = 166;
- b_gain = 175;
- break;
- }
- RESTRICT_TO_RANGE(hue, 1, 0x7f);
-
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, g_gain, 0x0127); /* Green gain */
- ibmcam_veio(uvd, 0, r_gain, 0x012e); /* Red gain */
- ibmcam_veio(uvd, 0, b_gain, 0x0130); /* Blue gain */
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, hue, 0x012d); /* Hue */
- ibmcam_veio(uvd, 0, 0xf545, 0x0124);
- break;
- }
- default:
- break;
- }
-}
-
-/*
- * ibmcam_adjust_picture()
- *
- * This procedure gets called from V4L interface to update picture settings.
- * Here we change brightness and contrast.
- */
-static void ibmcam_adjust_picture(struct uvd *uvd)
-{
- ibmcam_adjust_contrast(uvd);
- ibmcam_set_brightness(uvd);
- ibmcam_set_hue(uvd);
-}
-
-static int ibmcam_model1_setup(struct uvd *uvd)
-{
- const int ntries = 5;
- int i;
-
- ibmcam_veio(uvd, 1, 0x00, 0x0128);
- ibmcam_veio(uvd, 1, 0x00, 0x0100);
- ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
- ibmcam_veio(uvd, 1, 0x00, 0x0100);
- ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
- ibmcam_veio(uvd, 1, 0x00, 0x0100);
- ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
- ibmcam_veio(uvd, 0, 0x01, 0x0108);
-
- ibmcam_veio(uvd, 0, 0x03, 0x0112);
- ibmcam_veio(uvd, 1, 0x00, 0x0115);
- ibmcam_veio(uvd, 0, 0x06, 0x0115);
- ibmcam_veio(uvd, 1, 0x00, 0x0116);
- ibmcam_veio(uvd, 0, 0x44, 0x0116);
- ibmcam_veio(uvd, 1, 0x00, 0x0116);
- ibmcam_veio(uvd, 0, 0x40, 0x0116);
- ibmcam_veio(uvd, 1, 0x00, 0x0115);
- ibmcam_veio(uvd, 0, 0x0e, 0x0115);
- ibmcam_veio(uvd, 0, 0x19, 0x012c);
-
- ibmcam_Packet_Format1(uvd, 0x00, 0x1e);
- ibmcam_Packet_Format1(uvd, 0x39, 0x0d);
- ibmcam_Packet_Format1(uvd, 0x39, 0x09);
- ibmcam_Packet_Format1(uvd, 0x3b, 0x00);
- ibmcam_Packet_Format1(uvd, 0x28, 0x22);
- ibmcam_Packet_Format1(uvd, light_27, 0);
- ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
- ibmcam_Packet_Format1(uvd, 0x39, 0x08);
-
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x2c, 0x00);
-
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x30, 0x14);
-
- ibmcam_PacketFormat2(uvd, 0x39, 0x02);
- ibmcam_PacketFormat2(uvd, 0x01, 0xe1);
- ibmcam_PacketFormat2(uvd, 0x02, 0xcd);
- ibmcam_PacketFormat2(uvd, 0x03, 0xcd);
- ibmcam_PacketFormat2(uvd, 0x04, 0xfa);
- ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
- ibmcam_PacketFormat2(uvd, 0x39, 0x00);
-
- ibmcam_PacketFormat2(uvd, 0x39, 0x02);
- ibmcam_PacketFormat2(uvd, 0x0a, 0x37);
- ibmcam_PacketFormat2(uvd, 0x0b, 0xb8);
- ibmcam_PacketFormat2(uvd, 0x0c, 0xf3);
- ibmcam_PacketFormat2(uvd, 0x0d, 0xe3);
- ibmcam_PacketFormat2(uvd, 0x0e, 0x0d);
- ibmcam_PacketFormat2(uvd, 0x0f, 0xf2);
- ibmcam_PacketFormat2(uvd, 0x10, 0xd5);
- ibmcam_PacketFormat2(uvd, 0x11, 0xba);
- ibmcam_PacketFormat2(uvd, 0x12, 0x53);
- ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
- ibmcam_PacketFormat2(uvd, 0x39, 0x00);
-
- ibmcam_PacketFormat2(uvd, 0x39, 0x02);
- ibmcam_PacketFormat2(uvd, 0x16, 0x00);
- ibmcam_PacketFormat2(uvd, 0x17, 0x28);
- ibmcam_PacketFormat2(uvd, 0x18, 0x7d);
- ibmcam_PacketFormat2(uvd, 0x19, 0xbe);
- ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
- ibmcam_PacketFormat2(uvd, 0x39, 0x00);
-
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x00, 0x18);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x13, 0x18);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x14, 0x06);
-
- /* This is default brightness */
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x31, 0x37);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x32, 0x46);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x33, 0x55);
-
- ibmcam_Packet_Format1(uvd, 0x2e, 0x04);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x2d, 0x04);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x29, 0x80);
- ibmcam_Packet_Format1(uvd, 0x2c, 0x01);
- ibmcam_Packet_Format1(uvd, 0x30, 0x17);
- ibmcam_Packet_Format1(uvd, 0x39, 0x08);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x34, 0x00);
-
- ibmcam_veio(uvd, 0, 0x00, 0x0101);
- ibmcam_veio(uvd, 0, 0x00, 0x010a);
-
- switch (uvd->videosize) {
- case VIDEOSIZE_128x96:
- ibmcam_veio(uvd, 0, 0x80, 0x0103);
- ibmcam_veio(uvd, 0, 0x60, 0x0105);
- ibmcam_veio(uvd, 0, 0x0c, 0x010b);
- ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x0b, 0x011d);
- ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x00, 0x0129);
- break;
- case VIDEOSIZE_176x144:
- ibmcam_veio(uvd, 0, 0xb0, 0x0103);
- ibmcam_veio(uvd, 0, 0x8f, 0x0105);
- ibmcam_veio(uvd, 0, 0x06, 0x010b);
- ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x0d, 0x011d);
- ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x03, 0x0129);
- break;
- case VIDEOSIZE_352x288:
- ibmcam_veio(uvd, 0, 0xb0, 0x0103);
- ibmcam_veio(uvd, 0, 0x90, 0x0105);
- ibmcam_veio(uvd, 0, 0x02, 0x010b);
- ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x05, 0x011d);
- ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x00, 0x0129);
- break;
- }
-
- ibmcam_veio(uvd, 0, 0xff, 0x012b);
-
- /* This is another brightness - don't know why */
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x31, 0xc3);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x32, 0xd2);
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, 0x33, 0xe1);
-
- /* Default contrast */
- for (i=0; i < ntries; i++)
- ibmcam_Packet_Format1(uvd, contrast_14, 0x0a);
-
- /* Default sharpness */
- for (i=0; i < 2; i++)
- ibmcam_PacketFormat2(uvd, sharp_13, 0x1a); /* Level 4 FIXME */
-
- /* Default lighting conditions */
- ibmcam_Packet_Format1(uvd, light_27, lighting); /* 0=Bright 2=Low */
-
- /* Assorted init */
-
- switch (uvd->videosize) {
- case VIDEOSIZE_128x96:
- ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
- ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x36, 0x0102);
- ibmcam_veio(uvd, 0, 0x1a, 0x0104);
- ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x2b, 0x011c);
- ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
-#if 0
- ibmcam_veio(uvd, 0, 0x00, 0x0106);
- ibmcam_veio(uvd, 0, 0x38, 0x0107);
-#else
- ibmcam_veio(uvd, 0, 0x02, 0x0106);
- ibmcam_veio(uvd, 0, 0x2a, 0x0107);
-#endif
- break;
- case VIDEOSIZE_176x144:
- ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
- ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x04, 0x0102);
- ibmcam_veio(uvd, 0, 0x02, 0x0104);
- ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x2b, 0x011c);
- ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x01, 0x0106);
- ibmcam_veio(uvd, 0, 0xca, 0x0107);
- break;
- case VIDEOSIZE_352x288:
- ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
- ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x08, 0x0102);
- ibmcam_veio(uvd, 0, 0x01, 0x0104);
- ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x2f, 0x011c);
- ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
- ibmcam_veio(uvd, 0, 0x03, 0x0106);
- ibmcam_veio(uvd, 0, 0xf6, 0x0107);
- break;
- }
- return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
-}
-
-static int ibmcam_model2_setup(struct uvd *uvd)
-{
- ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
- ibmcam_veio(uvd, 1, 0x0000, 0x0116);
- ibmcam_veio(uvd, 0, 0x0060, 0x0116);
- ibmcam_veio(uvd, 0, 0x0002, 0x0112);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0008, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
- ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
- ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
- ibmcam_veio(uvd, 0, 0x00b9, 0x010a); /* Unique to this mode */
- ibmcam_veio(uvd, 0, 0x0038, 0x0119); /* Unique to this mode */
- ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
- ibmcam_veio(uvd, 0, 0x0090, 0x0107); /* Unique to every mode*/
- break;
- case VIDEOSIZE_320x240:
- ibmcam_veio(uvd, 0, 0x0028, 0x0103); /* Unique to this mode */
- ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
- ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
- ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
- ibmcam_veio(uvd, 0, 0x0098, 0x0107); /* Unique to every mode*/
- break;
- case VIDEOSIZE_352x240:
- ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
- ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
- ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
- ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
- ibmcam_veio(uvd, 0, 0x00da, 0x0107); /* Unique to every mode*/
- break;
- case VIDEOSIZE_352x288:
- ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
- ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
- ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
- ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
- ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
- ibmcam_veio(uvd, 0, 0x00fe, 0x0107); /* Unique to every mode*/
- break;
- }
- return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
-}
-
-/*
- * ibmcam_model1_setup_after_video_if()
- *
- * This code adds finishing touches to the video data interface.
- * Here we configure the frame rate and turn on the LED.
- */
-static void ibmcam_model1_setup_after_video_if(struct uvd *uvd)
-{
- unsigned short internal_frame_rate;
-
- RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
- internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */
- ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
- ibmcam_veio(uvd, 0, internal_frame_rate, 0x0111);
- ibmcam_veio(uvd, 0, 0x01, 0x0114);
- ibmcam_veio(uvd, 0, 0xc0, 0x010c);
-}
-
-static void ibmcam_model2_setup_after_video_if(struct uvd *uvd)
-{
- unsigned short setup_model2_rg2, setup_model2_sat, setup_model2_yb;
-
- ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
-
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- ibmcam_veio(uvd, 0, 0x0050, 0x0111);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
- break;
- case VIDEOSIZE_320x240:
- case VIDEOSIZE_352x240:
- case VIDEOSIZE_352x288:
- ibmcam_veio(uvd, 0, 0x0040, 0x0111);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- break;
- }
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
-
- /*
- * Hardware settings, may affect CMOS sensor; not user controls!
- * -------------------------------------------------------------
- * 0x0004: no effect
- * 0x0006: hardware effect
- * 0x0008: no effect
- * 0x000a: stops video stream, probably important h/w setting
- * 0x000c: changes color in hardware manner (not user setting)
- * 0x0012: changes number of colors (does not affect speed)
- * 0x002a: no effect
- * 0x002c: hardware setting (related to scan lines)
- * 0x002e: stops video stream, probably important h/w setting
- */
- ibmcam_model2_Packet1(uvd, 0x000a, 0x005c);
- ibmcam_model2_Packet1(uvd, 0x0004, 0x0000);
- ibmcam_model2_Packet1(uvd, 0x0006, 0x00fb);
- ibmcam_model2_Packet1(uvd, 0x0008, 0x0000);
- ibmcam_model2_Packet1(uvd, 0x000c, 0x0009);
- ibmcam_model2_Packet1(uvd, 0x0012, 0x000a);
- ibmcam_model2_Packet1(uvd, 0x002a, 0x0000);
- ibmcam_model2_Packet1(uvd, 0x002c, 0x0000);
- ibmcam_model2_Packet1(uvd, 0x002e, 0x0008);
-
- /*
- * Function 0x0030 pops up all over the place. Apparently
- * it is a hardware control register, with every bit assigned to
- * do something.
- */
- ibmcam_model2_Packet1(uvd, 0x0030, 0x0000);
-
- /*
- * Magic control of CMOS sensor. Only lower values like
- * 0-3 work, and picture shifts left or right. Don't change.
- */
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- ibmcam_model2_Packet1(uvd, 0x0014, 0x0002);
- ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
- ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
- break;
- case VIDEOSIZE_320x240:
- ibmcam_model2_Packet1(uvd, 0x0014, 0x0009);
- ibmcam_model2_Packet1(uvd, 0x0016, 0x0005); /* Horizontal shift */
- ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Another hardware setting */
- break;
- case VIDEOSIZE_352x240:
- /* This mode doesn't work as Windows programs it; changed to work */
- ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); /* Windows sets this to 8 */
- ibmcam_model2_Packet1(uvd, 0x0016, 0x0003); /* Horizontal shift */
- ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
- break;
- case VIDEOSIZE_352x288:
- ibmcam_model2_Packet1(uvd, 0x0014, 0x0003);
- ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
- ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
- break;
- }
-
- ibmcam_model2_Packet1(uvd, mod2_brightness, 0x005a);
-
- /*
- * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest).
- * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the
- * slowest setting. However for all practical reasons high settings make no
- * sense because USB is not fast enough to support high FPS. Be aware that
- * the picture datastream will be severely disrupted if you ask for
- * frame rate faster than allowed for the video size - see below:
- *
- * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
- * -----------------------------------------------------------------
- * 176x144: [6..31]
- * 320x240: [8..31]
- * 352x240: [10..31]
- * 352x288: [16..31] I have to raise lower threshold for stability...
- *
- * As usual, slower FPS provides better sensitivity.
- */
- {
- short hw_fps=31, i_framerate;
-
- RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
- i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN;
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- hw_fps = 6 + i_framerate*4;
- break;
- case VIDEOSIZE_320x240:
- hw_fps = 8 + i_framerate*3;
- break;
- case VIDEOSIZE_352x240:
- hw_fps = 10 + i_framerate*2;
- break;
- case VIDEOSIZE_352x288:
- hw_fps = 28 + i_framerate/2;
- break;
- }
- if (uvd->debug > 0)
- dev_info(&uvd->dev->dev, "Framerate (hardware): %hd.\n",
- hw_fps);
- RESTRICT_TO_RANGE(hw_fps, 0, 31);
- ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps);
- }
-
- /*
- * This setting does not visibly affect pictures; left it here
- * because it was present in Windows USB data stream. This function
- * does not allow arbitrary values and apparently is a bit mask, to
- * be activated only at appropriate time. Don't change it randomly!
- */
- switch (uvd->videosize) {
- case VIDEOSIZE_176x144:
- ibmcam_model2_Packet1(uvd, 0x0026, 0x00c2);
- break;
- case VIDEOSIZE_320x240:
- ibmcam_model2_Packet1(uvd, 0x0026, 0x0044);
- break;
- case VIDEOSIZE_352x240:
- ibmcam_model2_Packet1(uvd, 0x0026, 0x0046);
- break;
- case VIDEOSIZE_352x288:
- ibmcam_model2_Packet1(uvd, 0x0026, 0x0048);
- break;
- }
-
- ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
-
- if (init_model2_rg2 >= 0) {
- RESTRICT_TO_RANGE(init_model2_rg2, 0, 255);
- setup_model2_rg2 = init_model2_rg2;
- } else
- setup_model2_rg2 = 0x002f;
-
- if (init_model2_sat >= 0) {
- RESTRICT_TO_RANGE(init_model2_sat, 0, 255);
- setup_model2_sat = init_model2_sat;
- } else
- setup_model2_sat = 0x0034;
-
- if (init_model2_yb >= 0) {
- RESTRICT_TO_RANGE(init_model2_yb, 0, 255);
- setup_model2_yb = init_model2_yb;
- } else
- setup_model2_yb = 0x00a0;
-
- ibmcam_model2_Packet1(uvd, mod2_color_balance_rg2, setup_model2_rg2);
- ibmcam_model2_Packet1(uvd, mod2_saturation, setup_model2_sat);
- ibmcam_model2_Packet1(uvd, mod2_color_balance_yb, setup_model2_yb);
- ibmcam_model2_Packet1(uvd, mod2_hue, uvd->vpic.hue >> 9); /* 0 .. 7F */;
-
- /* Hardware control command */
- ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
-
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go camera, go! */
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
-}
-
-static void ibmcam_model4_setup_after_video_if(struct uvd *uvd)
-{
- switch (uvd->videosize) {
- case VIDEOSIZE_128x96:
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0080, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x000a, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x005c, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x000c, 0x0127);
- ibmcam_veio(uvd, 0, 0x0009, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0012, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x002a, 0x012d);
- ibmcam_veio(uvd, 0, 0x0000, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0034, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0070, 0x0119);
- ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x005e, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
- ibmcam_veio(uvd, 0, 0x0039, 0x010a);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- ibmcam_veio(uvd, 0, 0x0028, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0104);
- ibmcam_veio(uvd, 0, 0x001e, 0x0105);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0016, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x000a, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0014, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
- ibmcam_veio(uvd, 0, 0x001a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
- ibmcam_veio(uvd, 0, 0x005a, 0x012d);
- ibmcam_veio(uvd, 0, 0x9545, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
- ibmcam_veio(uvd, 0, 0x0018, 0x012e);
- ibmcam_veio(uvd, 0, 0x0043, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x001c, 0x0127);
- ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0032, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0036, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0017, 0x0127);
- ibmcam_veio(uvd, 0, 0x0013, 0x012e);
- ibmcam_veio(uvd, 0, 0x0031, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x0017, 0x012d);
- ibmcam_veio(uvd, 0, 0x0078, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0004, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- break;
- case VIDEOSIZE_160x120:
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0080, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x000a, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x005c, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x000c, 0x0127);
- ibmcam_veio(uvd, 0, 0x0009, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0012, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x002a, 0x012d);
- ibmcam_veio(uvd, 0, 0x0000, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0034, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0038, 0x0119);
- ibmcam_veio(uvd, 0, 0x00d8, 0x0107);
- ibmcam_veio(uvd, 0, 0x0002, 0x0106);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- ibmcam_veio(uvd, 0, 0x0028, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0104);
- ibmcam_veio(uvd, 0, 0x001e, 0x0105);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0016, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x000b, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0014, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
- ibmcam_veio(uvd, 0, 0x001a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
- ibmcam_veio(uvd, 0, 0x005a, 0x012d);
- ibmcam_veio(uvd, 0, 0x9545, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
- ibmcam_veio(uvd, 0, 0x0018, 0x012e);
- ibmcam_veio(uvd, 0, 0x0043, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x001c, 0x0127);
- ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0032, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0025, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0036, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0048, 0x0127);
- ibmcam_veio(uvd, 0, 0x0035, 0x012e);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x0048, 0x012d);
- ibmcam_veio(uvd, 0, 0x0090, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x0001, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0004, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- break;
- case VIDEOSIZE_176x144:
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0080, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x000a, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x005c, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x000c, 0x0127);
- ibmcam_veio(uvd, 0, 0x0009, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0012, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x002a, 0x012d);
- ibmcam_veio(uvd, 0, 0x0000, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0034, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0038, 0x0119);
- ibmcam_veio(uvd, 0, 0x00d6, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x0018, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- ibmcam_veio(uvd, 0, 0x002c, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0104);
- ibmcam_veio(uvd, 0, 0x0024, 0x0105);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0016, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0007, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0014, 0x012d);
- ibmcam_veio(uvd, 0, 0x0001, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
- ibmcam_veio(uvd, 0, 0x001a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
- ibmcam_veio(uvd, 0, 0x005e, 0x012d);
- ibmcam_veio(uvd, 0, 0x9545, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
- ibmcam_veio(uvd, 0, 0x0018, 0x012e);
- ibmcam_veio(uvd, 0, 0x0049, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x001c, 0x0127);
- ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0032, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0028, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0036, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0010, 0x0127);
- ibmcam_veio(uvd, 0, 0x0013, 0x012e);
- ibmcam_veio(uvd, 0, 0x002a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x0010, 0x012d);
- ibmcam_veio(uvd, 0, 0x006d, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x0001, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0004, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- break;
- case VIDEOSIZE_320x240:
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0080, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x000a, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x005c, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x000c, 0x0127);
- ibmcam_veio(uvd, 0, 0x0009, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0012, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x002a, 0x012d);
- ibmcam_veio(uvd, 0, 0x0000, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0034, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0070, 0x0119);
- ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x005e, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
- ibmcam_veio(uvd, 0, 0x0039, 0x010a);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- ibmcam_veio(uvd, 0, 0x0028, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0104);
- ibmcam_veio(uvd, 0, 0x001e, 0x0105);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0016, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x000a, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0014, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
- ibmcam_veio(uvd, 0, 0x001a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
- ibmcam_veio(uvd, 0, 0x005a, 0x012d);
- ibmcam_veio(uvd, 0, 0x9545, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
- ibmcam_veio(uvd, 0, 0x0018, 0x012e);
- ibmcam_veio(uvd, 0, 0x0043, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x001c, 0x0127);
- ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0032, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0036, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0017, 0x0127);
- ibmcam_veio(uvd, 0, 0x0013, 0x012e);
- ibmcam_veio(uvd, 0, 0x0031, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x0017, 0x012d);
- ibmcam_veio(uvd, 0, 0x0078, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0004, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- break;
- case VIDEOSIZE_352x288:
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
- ibmcam_veio(uvd, 0, 0x0080, 0x012b);
- ibmcam_veio(uvd, 0, 0x0000, 0x0108);
- ibmcam_veio(uvd, 0, 0x0001, 0x0133);
- ibmcam_veio(uvd, 0, 0x009b, 0x010f);
- ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x000a, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x005c, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0004, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x000c, 0x0127);
- ibmcam_veio(uvd, 0, 0x0009, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0012, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0008, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x002a, 0x012d);
- ibmcam_veio(uvd, 0, 0x0000, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0034, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0070, 0x0119);
- ibmcam_veio(uvd, 0, 0x00f2, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x008c, 0x0107);
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
- ibmcam_veio(uvd, 0, 0x0039, 0x010a);
- ibmcam_veio(uvd, 0, 0x0001, 0x0102);
- ibmcam_veio(uvd, 0, 0x002c, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0104);
- ibmcam_veio(uvd, 0, 0x0024, 0x0105);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0016, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0006, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0014, 0x012d);
- ibmcam_veio(uvd, 0, 0x0002, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
- ibmcam_veio(uvd, 0, 0x001a, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
- ibmcam_veio(uvd, 0, 0x005e, 0x012d);
- ibmcam_veio(uvd, 0, 0x9545, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
- ibmcam_veio(uvd, 0, 0x0018, 0x012e);
- ibmcam_veio(uvd, 0, 0x0049, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
- ibmcam_veio(uvd, 0, 0xd055, 0x0124);
- ibmcam_veio(uvd, 0, 0x001c, 0x0127);
- ibmcam_veio(uvd, 0, 0x00cf, 0x012e);
- ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0032, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
- ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
- ibmcam_veio(uvd, 0, 0x0036, 0x012d);
- ibmcam_veio(uvd, 0, 0x0008, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x001e, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0010, 0x0127);
- ibmcam_veio(uvd, 0, 0x0013, 0x012e);
- ibmcam_veio(uvd, 0, 0x0025, 0x0130);
- ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
- ibmcam_veio(uvd, 0, 0x0010, 0x012d);
- ibmcam_veio(uvd, 0, 0x0048, 0x012f);
- ibmcam_veio(uvd, 0, 0xd145, 0x0124);
- ibmcam_veio(uvd, 0, 0x0000, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
- ibmcam_veio(uvd, 0, 0x0038, 0x012f);
- ibmcam_veio(uvd, 0, 0xd141, 0x0124);
- ibmcam_veio(uvd, 0, 0x0004, 0x0127);
- ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- break;
- }
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
-}
-
-static void ibmcam_model3_setup_after_video_if(struct uvd *uvd)
-{
- int i;
- /*
- * 01.01.08 - Added for RCA video in support -LO
- * This struct is used to init the Model3 cam to use the RCA video in port
- * instead of the CCD sensor.
- */
- static const struct struct_initData initData[] = {
- {0, 0x0000, 0x010c},
- {0, 0x0006, 0x012c},
- {0, 0x0078, 0x012d},
- {0, 0x0046, 0x012f},
- {0, 0xd141, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfea8, 0x0124},
- {1, 0x0000, 0x0116},
- {0, 0x0064, 0x0116},
- {1, 0x0000, 0x0115},
- {0, 0x0003, 0x0115},
- {0, 0x0008, 0x0123},
- {0, 0x0000, 0x0117},
- {0, 0x0000, 0x0112},
- {0, 0x0080, 0x0100},
- {0, 0x0000, 0x0100},
- {1, 0x0000, 0x0116},
- {0, 0x0060, 0x0116},
- {0, 0x0002, 0x0112},
- {0, 0x0000, 0x0123},
- {0, 0x0001, 0x0117},
- {0, 0x0040, 0x0108},
- {0, 0x0019, 0x012c},
- {0, 0x0040, 0x0116},
- {0, 0x000a, 0x0115},
- {0, 0x000b, 0x0115},
- {0, 0x0078, 0x012d},
- {0, 0x0046, 0x012f},
- {0, 0xd141, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfea8, 0x0124},
- {0, 0x0064, 0x0116},
- {0, 0x0000, 0x0115},
- {0, 0x0001, 0x0115},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00aa, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f2, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x000f, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f8, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00fc, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f9, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x003c, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0027, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0019, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0021, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0006, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0045, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002a, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x000e, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002b, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f4, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002c, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0004, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002d, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0014, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002e, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0003, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002f, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0003, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0014, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0053, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0x0000, 0x0101},
- {0, 0x00a0, 0x0103},
- {0, 0x0078, 0x0105},
- {0, 0x0000, 0x010a},
- {0, 0x0024, 0x010b},
- {0, 0x0028, 0x0119},
- {0, 0x0088, 0x011b},
- {0, 0x0002, 0x011d},
- {0, 0x0003, 0x011e},
- {0, 0x0000, 0x0129},
- {0, 0x00fc, 0x012b},
- {0, 0x0008, 0x0102},
- {0, 0x0000, 0x0104},
- {0, 0x0008, 0x011a},
- {0, 0x0028, 0x011c},
- {0, 0x0021, 0x012a},
- {0, 0x0000, 0x0118},
- {0, 0x0000, 0x0132},
- {0, 0x0000, 0x0109},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0031, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00dc, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0032, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0020, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0030, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0008, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0x0003, 0x0106},
- {0, 0x0062, 0x0107},
- {0, 0x0003, 0x0111},
- };
-#define NUM_INIT_DATA
-
- unsigned short compression = 0; /* 0=none, 7=best frame rate */
- int f_rate; /* 0=Fastest 7=slowest */
-
- if (IBMCAM_T(uvd)->initialized)
- return;
-
- /* Internal frame rate is controlled by f_rate value */
- f_rate = 7 - framerate;
- RESTRICT_TO_RANGE(f_rate, 0, 7);
-
- ibmcam_veio(uvd, 0, 0x0000, 0x0100);
- ibmcam_veio(uvd, 1, 0x0000, 0x0116);
- ibmcam_veio(uvd, 0, 0x0060, 0x0116);
- ibmcam_veio(uvd, 0, 0x0002, 0x0112);
- ibmcam_veio(uvd, 0, 0x0000, 0x0123);
- ibmcam_veio(uvd, 0, 0x0001, 0x0117);
- ibmcam_veio(uvd, 0, 0x0040, 0x0108);
- ibmcam_veio(uvd, 0, 0x0019, 0x012c);
- ibmcam_veio(uvd, 0, 0x0060, 0x0116);
- ibmcam_veio(uvd, 0, 0x0002, 0x0115);
- ibmcam_veio(uvd, 0, 0x0003, 0x0115);
- ibmcam_veio(uvd, 1, 0x0000, 0x0115);
- ibmcam_veio(uvd, 0, 0x000b, 0x0115);
- ibmcam_model3_Packet1(uvd, 0x000a, 0x0040);
- ibmcam_model3_Packet1(uvd, 0x000b, 0x00f6);
- ibmcam_model3_Packet1(uvd, 0x000c, 0x0002);
- ibmcam_model3_Packet1(uvd, 0x000d, 0x0020);
- ibmcam_model3_Packet1(uvd, 0x000e, 0x0033);
- ibmcam_model3_Packet1(uvd, 0x000f, 0x0007);
- ibmcam_model3_Packet1(uvd, 0x0010, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0011, 0x0070);
- ibmcam_model3_Packet1(uvd, 0x0012, 0x0030);
- ibmcam_model3_Packet1(uvd, 0x0013, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0014, 0x0001);
- ibmcam_model3_Packet1(uvd, 0x0015, 0x0001);
- ibmcam_model3_Packet1(uvd, 0x0016, 0x0001);
- ibmcam_model3_Packet1(uvd, 0x0017, 0x0001);
- ibmcam_model3_Packet1(uvd, 0x0018, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x001e, 0x00c3);
- ibmcam_model3_Packet1(uvd, 0x0020, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0028, 0x0010);
- ibmcam_model3_Packet1(uvd, 0x0029, 0x0054);
- ibmcam_model3_Packet1(uvd, 0x002a, 0x0013);
- ibmcam_model3_Packet1(uvd, 0x002b, 0x0007);
- ibmcam_model3_Packet1(uvd, 0x002d, 0x0028);
- ibmcam_model3_Packet1(uvd, 0x002e, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0031, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0032, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0033, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0034, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0035, 0x0038);
- ibmcam_model3_Packet1(uvd, 0x003a, 0x0001);
- ibmcam_model3_Packet1(uvd, 0x003c, 0x001e);
- ibmcam_model3_Packet1(uvd, 0x003f, 0x000a);
- ibmcam_model3_Packet1(uvd, 0x0041, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0046, 0x003f);
- ibmcam_model3_Packet1(uvd, 0x0047, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0050, 0x0005);
- ibmcam_model3_Packet1(uvd, 0x0052, 0x001a);
- ibmcam_model3_Packet1(uvd, 0x0053, 0x0003);
- ibmcam_model3_Packet1(uvd, 0x005a, 0x006b);
- ibmcam_model3_Packet1(uvd, 0x005d, 0x001e);
- ibmcam_model3_Packet1(uvd, 0x005e, 0x0030);
- ibmcam_model3_Packet1(uvd, 0x005f, 0x0041);
- ibmcam_model3_Packet1(uvd, 0x0064, 0x0008);
- ibmcam_model3_Packet1(uvd, 0x0065, 0x0015);
- ibmcam_model3_Packet1(uvd, 0x0068, 0x000f);
- ibmcam_model3_Packet1(uvd, 0x0079, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x007a, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x007c, 0x003f);
- ibmcam_model3_Packet1(uvd, 0x0082, 0x000f);
- ibmcam_model3_Packet1(uvd, 0x0085, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x0099, 0x0000);
- ibmcam_model3_Packet1(uvd, 0x009b, 0x0023);
- ibmcam_model3_Packet1(uvd, 0x009c, 0x0022);
- ibmcam_model3_Packet1(uvd, 0x009d, 0x0096);
- ibmcam_model3_Packet1(uvd, 0x009e, 0x0096);
- ibmcam_model3_Packet1(uvd, 0x009f, 0x000a);
-
- switch (uvd->videosize) {
- case VIDEOSIZE_160x120:
- ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
- ibmcam_veio(uvd, 0, 0x0024, 0x010b); /* Differs everywhere */
- ibmcam_veio(uvd, 0, 0x00a9, 0x0119);
- ibmcam_veio(uvd, 0, 0x0016, 0x011b);
- ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
- ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
- ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
- ibmcam_veio(uvd, 0, 0x0018, 0x0102);
- ibmcam_veio(uvd, 0, 0x0004, 0x0104);
- ibmcam_veio(uvd, 0, 0x0004, 0x011a);
- ibmcam_veio(uvd, 0, 0x0028, 0x011c);
- ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
- ibmcam_veio(uvd, 0, 0x0000, 0x0118);
- ibmcam_veio(uvd, 0, 0x0000, 0x0132);
- ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
- ibmcam_veio(uvd, 0, compression, 0x0109);
- break;
- case VIDEOSIZE_320x240:
- ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
- ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
- ibmcam_veio(uvd, 0, 0x0028, 0x010b); /* Differs everywhere */
- ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same */
- ibmcam_veio(uvd, 0, 0x0000, 0x011e);
- ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
- ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
- /* 4 commands from 160x120 skipped */
- ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
- ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
- ibmcam_veio(uvd, 0, compression, 0x0109);
- ibmcam_veio(uvd, 0, 0x00d9, 0x0119);
- ibmcam_veio(uvd, 0, 0x0006, 0x011b);
- ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x0010, 0x0104);
- ibmcam_veio(uvd, 0, 0x0004, 0x011a);
- ibmcam_veio(uvd, 0, 0x003f, 0x011c);
- ibmcam_veio(uvd, 0, 0x001c, 0x0118);
- ibmcam_veio(uvd, 0, 0x0000, 0x0132);
- break;
- case VIDEOSIZE_640x480:
- ibmcam_veio(uvd, 0, 0x00f0, 0x0105);
- ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
- ibmcam_veio(uvd, 0, 0x0038, 0x010b); /* Differs everywhere */
- ibmcam_veio(uvd, 0, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x0004, 0x011d); /* NC */
- ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
- ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
- ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
- ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x0016, 0x0104); /* NC */
- ibmcam_veio(uvd, 0, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
- ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
- ibmcam_veio(uvd, 0, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
- ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
- ibmcam_veio(uvd, 0, compression, 0x0109);
- ibmcam_veio(uvd, 0, 0x0040, 0x0101);
- ibmcam_veio(uvd, 0, 0x0040, 0x0103);
- ibmcam_veio(uvd, 0, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
- break;
- }
- ibmcam_model3_Packet1(uvd, 0x007e, 0x000e); /* Hue */
- ibmcam_model3_Packet1(uvd, 0x0036, 0x0011); /* Brightness */
- ibmcam_model3_Packet1(uvd, 0x0060, 0x0002); /* Sharpness */
- ibmcam_model3_Packet1(uvd, 0x0061, 0x0004); /* Sharpness */
- ibmcam_model3_Packet1(uvd, 0x0062, 0x0005); /* Sharpness */
- ibmcam_model3_Packet1(uvd, 0x0063, 0x0014); /* Sharpness */
- ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
- ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
- ibmcam_model3_Packet1(uvd, 0x0067, 0x0001); /* Contrast */
- ibmcam_model3_Packet1(uvd, 0x005b, 0x000c); /* Contrast */
- ibmcam_model3_Packet1(uvd, 0x005c, 0x0016); /* Contrast */
- ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
- ibmcam_model3_Packet1(uvd, 0x002c, 0x0003); /* Was 1, broke 640x480 */
- ibmcam_model3_Packet1(uvd, 0x002f, 0x002a);
- ibmcam_model3_Packet1(uvd, 0x0030, 0x0029);
- ibmcam_model3_Packet1(uvd, 0x0037, 0x0002);
- ibmcam_model3_Packet1(uvd, 0x0038, 0x0059);
- ibmcam_model3_Packet1(uvd, 0x003d, 0x002e);
- ibmcam_model3_Packet1(uvd, 0x003e, 0x0028);
- ibmcam_model3_Packet1(uvd, 0x0078, 0x0005);
- ibmcam_model3_Packet1(uvd, 0x007b, 0x0011);
- ibmcam_model3_Packet1(uvd, 0x007d, 0x004b);
- ibmcam_model3_Packet1(uvd, 0x007f, 0x0022);
- ibmcam_model3_Packet1(uvd, 0x0080, 0x000c);
- ibmcam_model3_Packet1(uvd, 0x0081, 0x000b);
- ibmcam_model3_Packet1(uvd, 0x0083, 0x00fd);
- ibmcam_model3_Packet1(uvd, 0x0086, 0x000b);
- ibmcam_model3_Packet1(uvd, 0x0087, 0x000b);
- ibmcam_model3_Packet1(uvd, 0x007e, 0x000e);
- ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
- ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
- ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
-
- switch (uvd->videosize) {
- case VIDEOSIZE_160x120:
- ibmcam_veio(uvd, 0, 0x0002, 0x0106);
- ibmcam_veio(uvd, 0, 0x0008, 0x0107);
- ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
- ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
- ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
- ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
- ibmcam_model3_Packet1(uvd, 0x0040, 0x000a);
- ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
- break;
- case VIDEOSIZE_320x240:
- ibmcam_veio(uvd, 0, 0x0003, 0x0106);
- ibmcam_veio(uvd, 0, 0x0062, 0x0107);
- ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
- ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
- ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
- ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
- ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
- ibmcam_model3_Packet1(uvd, 0x0051, 0x000b);
- break;
- case VIDEOSIZE_640x480:
- ibmcam_veio(uvd, 0, 0x0002, 0x0106); /* Adjustments */
- ibmcam_veio(uvd, 0, 0x00b4, 0x0107); /* Adjustments */
- ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
- ibmcam_model3_Packet1(uvd, 0x001f, 0x0002); /* !Same */
- ibmcam_model3_Packet1(uvd, 0x0039, 0x003e); /* !Same */
- ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
- ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
- break;
- }
-
- /* 01.01.08 - Added for RCA video in support -LO */
- if(init_model3_input) {
- if (debug > 0)
- dev_info(&uvd->dev->dev, "Setting input to RCA.\n");
- for (i=0; i < ARRAY_SIZE(initData); i++) {
- ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
- }
- }
-
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
-}
-
-/*
- * ibmcam_video_stop()
- *
- * This code tells camera to stop streaming. The interface remains
- * configured and bandwidth - claimed.
- */
-static void ibmcam_video_stop(struct uvd *uvd)
-{
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- ibmcam_veio(uvd, 0, 0x00, 0x010c);
- ibmcam_veio(uvd, 0, 0x00, 0x010c);
- ibmcam_veio(uvd, 0, 0x01, 0x0114);
- ibmcam_veio(uvd, 0, 0xc0, 0x010c);
- ibmcam_veio(uvd, 0, 0x00, 0x010c);
- ibmcam_send_FF_04_02(uvd);
- ibmcam_veio(uvd, 1, 0x00, 0x0100);
- ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
- break;
- case IBMCAM_MODEL_2:
-case IBMCAM_MODEL_4:
- ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop the camera */
-
- ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
-
- ibmcam_veio(uvd, 0, 0x0080, 0x0100); /* LED Off */
- ibmcam_veio(uvd, 0, 0x0020, 0x0111);
- ibmcam_veio(uvd, 0, 0x00a0, 0x0111);
-
- ibmcam_model2_Packet1(uvd, 0x0030, 0x0002);
-
- ibmcam_veio(uvd, 0, 0x0020, 0x0111);
- ibmcam_veio(uvd, 0, 0x0000, 0x0112);
- break;
- case IBMCAM_MODEL_3:
-#if 1
- ibmcam_veio(uvd, 0, 0x0000, 0x010c);
-
- /* Here we are supposed to select video interface alt. setting 0 */
- ibmcam_veio(uvd, 0, 0x0006, 0x012c);
-
- ibmcam_model3_Packet1(uvd, 0x0046, 0x0000);
-
- ibmcam_veio(uvd, 1, 0x0000, 0x0116);
- ibmcam_veio(uvd, 0, 0x0064, 0x0116);
- ibmcam_veio(uvd, 1, 0x0000, 0x0115);
- ibmcam_veio(uvd, 0, 0x0003, 0x0115);
- ibmcam_veio(uvd, 0, 0x0008, 0x0123);
- ibmcam_veio(uvd, 0, 0x0000, 0x0117);
- ibmcam_veio(uvd, 0, 0x0000, 0x0112);
- ibmcam_veio(uvd, 0, 0x0080, 0x0100);
- IBMCAM_T(uvd)->initialized = 0;
-#endif
- break;
- } /* switch */
-}
-
-/*
- * ibmcam_reinit_iso()
- *
- * This procedure sends couple of commands to the camera and then
- * resets the video pipe. This sequence was observed to reinit the
- * camera or, at least, to initiate ISO data stream.
- *
- * History:
- * 1/2/00 Created.
- */
-static void ibmcam_reinit_iso(struct uvd *uvd, int do_stop)
-{
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- if (do_stop)
- ibmcam_video_stop(uvd);
- ibmcam_veio(uvd, 0, 0x0001, 0x0114);
- ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
- usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
- ibmcam_model1_setup_after_video_if(uvd);
- break;
- case IBMCAM_MODEL_2:
- ibmcam_model2_setup_after_video_if(uvd);
- break;
- case IBMCAM_MODEL_3:
- ibmcam_video_stop(uvd);
- ibmcam_model3_setup_after_video_if(uvd);
- break;
- case IBMCAM_MODEL_4:
- ibmcam_model4_setup_after_video_if(uvd);
- break;
- }
-}
-
-static void ibmcam_video_start(struct uvd *uvd)
-{
- ibmcam_change_lighting_conditions(uvd);
- ibmcam_set_sharpness(uvd);
- ibmcam_reinit_iso(uvd, 0);
-}
-
-/*
- * Return negative code on failure, 0 on success.
- */
-static int ibmcam_setup_on_open(struct uvd *uvd)
-{
- int setup_ok = 0; /* Success by default */
- /* Send init sequence only once, it's large! */
- if (!IBMCAM_T(uvd)->initialized) { /* FIXME rename */
- switch (IBMCAM_T(uvd)->camera_model) {
- case IBMCAM_MODEL_1:
- setup_ok = ibmcam_model1_setup(uvd);
- break;
- case IBMCAM_MODEL_2:
- setup_ok = ibmcam_model2_setup(uvd);
- break;
- case IBMCAM_MODEL_3:
- case IBMCAM_MODEL_4:
- /* We do all setup when Isoc stream is requested */
- break;
- }
- IBMCAM_T(uvd)->initialized = (setup_ok != 0);
- }
- return setup_ok;
-}
-
-static void ibmcam_configure_video(struct uvd *uvd)
-{
- if (uvd == NULL)
- return;
-
- RESTRICT_TO_RANGE(init_brightness, 0, 255);
- RESTRICT_TO_RANGE(init_contrast, 0, 255);
- RESTRICT_TO_RANGE(init_color, 0, 255);
- RESTRICT_TO_RANGE(init_hue, 0, 255);
- RESTRICT_TO_RANGE(hue_correction, 0, 255);
-
- memset(&uvd->vpic, 0, sizeof(uvd->vpic));
- memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
-
- uvd->vpic.colour = init_color << 8;
- uvd->vpic.hue = init_hue << 8;
- uvd->vpic.brightness = init_brightness << 8;
- uvd->vpic.contrast = init_contrast << 8;
- uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
- uvd->vpic.depth = 24;
- uvd->vpic.palette = VIDEO_PALETTE_RGB24;
-
- memset(&uvd->vcap, 0, sizeof(uvd->vcap));
- strcpy(uvd->vcap.name, "IBM USB Camera");
- uvd->vcap.type = VID_TYPE_CAPTURE;
- uvd->vcap.channels = 1;
- uvd->vcap.audios = 0;
- uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
- uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
- uvd->vcap.minwidth = min_canvasWidth;
- uvd->vcap.minheight = min_canvasHeight;
-
- memset(&uvd->vchan, 0, sizeof(uvd->vchan));
- uvd->vchan.flags = 0;
- uvd->vchan.tuners = 0;
- uvd->vchan.channel = 0;
- uvd->vchan.type = VIDEO_TYPE_CAMERA;
- strcpy(uvd->vchan.name, "Camera");
-}
-
-/*
- * ibmcam_probe()
- *
- * This procedure queries device descriptor and accepts the interface
- * if it looks like IBM C-it camera.
- *
- * History:
- * 22-Jan-2000 Moved camera init code to ibmcam_open()
- * 27=Jan-2000 Changed to use static structures, added locking.
- * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
- * 03-Jul-2000 Fixed endianness bug.
- * 12-Nov-2000 Reworked to comply with new probe() signature.
- * 23-Jan-2001 Added compatibility with 2.2.x kernels.
- */
-static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct uvd *uvd = NULL;
- int ix, i, nas, model=0, canvasX=0, canvasY=0;
- int actInterface=-1, inactInterface=-1, maxPS=0;
- __u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
- unsigned char video_ep = 0;
-
- if (debug >= 1)
- dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum);
-
- /* We don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- /* Check the version/revision */
- switch (le16_to_cpu(dev->descriptor.bcdDevice)) {
- case 0x0002:
- if (ifnum != 2)
- return -ENODEV;
- model = IBMCAM_MODEL_1;
- break;
- case 0x030A:
- if (ifnum != 0)
- return -ENODEV;
- if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) ||
- (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID))
- model = IBMCAM_MODEL_4;
- else
- model = IBMCAM_MODEL_2;
- break;
- case 0x0301:
- if (ifnum != 0)
- return -ENODEV;
- model = IBMCAM_MODEL_3;
- break;
- default:
- err("IBM camera with revision 0x%04x is not supported.",
- le16_to_cpu(dev->descriptor.bcdDevice));
- return -ENODEV;
- }
-
- /* Print detailed info on what we found so far */
- do {
- char *brand = NULL;
- switch (le16_to_cpu(dev->descriptor.idProduct)) {
- case NETCAM_PRODUCT_ID:
- brand = "IBM NetCamera";
- break;
- case VEO_800C_PRODUCT_ID:
- brand = "Veo Stingray [800C]";
- break;
- case VEO_800D_PRODUCT_ID:
- brand = "Veo Stingray [800D]";
- break;
- case IBMCAM_PRODUCT_ID:
- default:
- brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
- break;
- }
- dev_info(&dev->dev,
- "%s USB camera found (model %d, rev. 0x%04x)\n",
- brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
- } while (0);
-
- /* Validate found interface: must have one ISO endpoint */
- nas = intf->num_altsetting;
- if (debug > 0)
- dev_info(&dev->dev, "Number of alternate settings=%d.\n",
- nas);
- if (nas < 2) {
- err("Too few alternate settings for this camera!");
- return -ENODEV;
- }
- /* Validate all alternate settings */
- for (ix=0; ix < nas; ix++) {
- const struct usb_host_interface *interface;
- const struct usb_endpoint_descriptor *endpoint;
-
- interface = &intf->altsetting[ix];
- i = interface->desc.bAlternateSetting;
- if (interface->desc.bNumEndpoints != 1) {
- err("Interface %d. has %u. endpoints!",
- ifnum, (unsigned)(interface->desc.bNumEndpoints));
- return -ENODEV;
- }
- endpoint = &interface->endpoint[0].desc;
- if (video_ep == 0)
- video_ep = endpoint->bEndpointAddress;
- else if (video_ep != endpoint->bEndpointAddress) {
- err("Alternate settings have different endpoint addresses!");
- return -ENODEV;
- }
- if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("Interface %d. has non-ISO endpoint!", ifnum);
- return -ENODEV;
- }
- if (usb_endpoint_dir_out(endpoint)) {
- err("Interface %d. has ISO OUT endpoint!", ifnum);
- return -ENODEV;
- }
- if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
- if (inactInterface < 0)
- inactInterface = i;
- else {
- err("More than one inactive alt. setting!");
- return -ENODEV;
- }
- } else {
- if (actInterface < 0) {
- actInterface = i;
- maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
- if (debug > 0)
- dev_info(&dev->dev,
- "Active setting=%d. "
- "maxPS=%d.\n", i, maxPS);
- } else
- err("More than one active alt. setting! Ignoring #%d.", i);
- }
- }
- if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
- err("Failed to recognize the camera!");
- return -ENODEV;
- }
-
- /* Validate options */
- switch (model) {
- case IBMCAM_MODEL_1:
- RESTRICT_TO_RANGE(lighting, 0, 2);
- RESTRICT_TO_RANGE(size, SIZE_128x96, SIZE_352x288);
- if (framerate < 0)
- framerate = 2;
- canvasX = 352;
- canvasY = 288;
- break;
- case IBMCAM_MODEL_2:
- RESTRICT_TO_RANGE(lighting, 0, 15);
- RESTRICT_TO_RANGE(size, SIZE_176x144, SIZE_352x240);
- if (framerate < 0)
- framerate = 2;
- canvasX = 352;
- canvasY = 240;
- break;
- case IBMCAM_MODEL_3:
- RESTRICT_TO_RANGE(lighting, 0, 15); /* FIXME */
- switch (size) {
- case SIZE_160x120:
- canvasX = 160;
- canvasY = 120;
- if (framerate < 0)
- framerate = 2;
- RESTRICT_TO_RANGE(framerate, 0, 5);
- break;
- default:
- dev_info(&dev->dev, "IBM camera: using 320x240\n");
- size = SIZE_320x240;
- /* No break here */
- case SIZE_320x240:
- canvasX = 320;
- canvasY = 240;
- if (framerate < 0)
- framerate = 3;
- RESTRICT_TO_RANGE(framerate, 0, 5);
- break;
- case SIZE_640x480:
- canvasX = 640;
- canvasY = 480;
- framerate = 0; /* Slowest, and maybe even that is too fast */
- break;
- }
- break;
- case IBMCAM_MODEL_4:
- RESTRICT_TO_RANGE(lighting, 0, 2);
- switch (size) {
- case SIZE_128x96:
- canvasX = 128;
- canvasY = 96;
- break;
- case SIZE_160x120:
- canvasX = 160;
- canvasY = 120;
- break;
- default:
- dev_info(&dev->dev, "IBM NetCamera: using 176x144\n");
- size = SIZE_176x144;
- /* No break here */
- case SIZE_176x144:
- canvasX = 176;
- canvasY = 144;
- break;
- case SIZE_320x240:
- canvasX = 320;
- canvasY = 240;
- break;
- case SIZE_352x288:
- canvasX = 352;
- canvasY = 288;
- break;
- }
- break;
- default:
- err("IBM camera: Model %d. not supported!", model);
- return -ENODEV;
- }
-
- uvd = usbvideo_AllocateDevice(cams);
- if (uvd != NULL) {
- /* Here uvd is a fully allocated uvd object */
- uvd->flags = flags;
- uvd->debug = debug;
- uvd->dev = dev;
- uvd->iface = ifnum;
- uvd->ifaceAltInactive = inactInterface;
- uvd->ifaceAltActive = actInterface;
- uvd->video_endp = video_ep;
- uvd->iso_packet_len = maxPS;
- uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
- uvd->defaultPalette = VIDEO_PALETTE_RGB24;
- uvd->canvas = VIDEOSIZE(canvasX, canvasY);
- uvd->videosize = ibmcam_size_to_videosize(size);
-
- /* Initialize ibmcam-specific data */
- assert(IBMCAM_T(uvd) != NULL);
- IBMCAM_T(uvd)->camera_model = model;
- IBMCAM_T(uvd)->initialized = 0;
-
- ibmcam_configure_video(uvd);
-
- i = usbvideo_RegisterVideoDevice(uvd);
- if (i != 0) {
- err("usbvideo_RegisterVideoDevice() failed.");
- uvd = NULL;
- }
- }
- usb_set_intfdata (intf, uvd);
- return 0;
-}
-
-
-static struct usb_device_id id_table[] = {
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
- { } /* Terminating entry */
-};
-
-/*
- * ibmcam_init()
- *
- * This code is run to initialize the driver.
- *
- * History:
- * 1/27/00 Reworked to use statically allocated ibmcam structures.
- * 21/10/00 Completely redesigned to use usbvideo services.
- */
-static int __init ibmcam_init(void)
-{
- struct usbvideo_cb cbTbl;
- memset(&cbTbl, 0, sizeof(cbTbl));
- cbTbl.probe = ibmcam_probe;
- cbTbl.setupOnOpen = ibmcam_setup_on_open;
- cbTbl.videoStart = ibmcam_video_start;
- cbTbl.videoStop = ibmcam_video_stop;
- cbTbl.processData = ibmcam_ProcessIsocData;
- cbTbl.postProcess = usbvideo_DeinterlaceFrame;
- cbTbl.adjustPicture = ibmcam_adjust_picture;
- cbTbl.getFPS = ibmcam_calculate_fps;
- return usbvideo_register(
- &cams,
- MAX_IBMCAM,
- sizeof(ibmcam_t),
- "ibmcam",
- &cbTbl,
- THIS_MODULE,
- id_table);
-}
-
-static void __exit ibmcam_cleanup(void)
-{
- usbvideo_Deregister(&cams);
-}
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-module_init(ibmcam_init);
-module_exit(ibmcam_cleanup);
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
deleted file mode 100644
index 562e1d170be0..000000000000
--- a/drivers/media/video/usbvideo/konicawc.c
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * konicawc.c - konica webcam driver
- *
- * Author: Simon Evans <spse@secret.org.uk>
- *
- * Copyright (C) 2002 Simon Evans
- *
- * Licence: GPL
- *
- * Driver for USB webcams based on Konica chipset. This
- * chipset is used in Intel YC76 camera.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <linux/gfp.h>
-
-#include "usbvideo.h"
-
-#define MAX_BRIGHTNESS 108
-#define MAX_CONTRAST 108
-#define MAX_SATURATION 108
-#define MAX_SHARPNESS 108
-#define MAX_WHITEBAL 372
-#define MAX_SPEED 6
-
-
-#define MAX_CAMERAS 1
-
-#define DRIVER_VERSION "v1.4"
-#define DRIVER_DESC "Konica Webcam driver"
-
-enum ctrl_req {
- SetWhitebal = 0x01,
- SetBrightness = 0x02,
- SetSharpness = 0x03,
- SetContrast = 0x04,
- SetSaturation = 0x05,
-};
-
-
-enum frame_sizes {
- SIZE_160X120 = 0,
- SIZE_160X136 = 1,
- SIZE_176X144 = 2,
- SIZE_320X240 = 3,
-
-};
-
-#define MAX_FRAME_SIZE SIZE_320X240
-
-static struct usbvideo *cams;
-
-#ifdef CONFIG_USB_DEBUG
-static int debug;
-#define DEBUG(n, format, arg...) \
- if (n <= debug) { \
- printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
- }
-#else
-#define DEBUG(n, arg...)
-static const int debug;
-#endif
-
-
-/* Some default values for initial camera settings,
- can be set by modprobe */
-
-static int size;
-static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */
-static int brightness = MAX_BRIGHTNESS/2;
-static int contrast = MAX_CONTRAST/2;
-static int saturation = MAX_SATURATION/2;
-static int sharpness = MAX_SHARPNESS/2;
-static int whitebal = 3*(MAX_WHITEBAL/4);
-
-static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
-
-/* These FPS speeds are from the windows config box. They are
- * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
- * real fps.
- */
-
-static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
- { 24, 40, 48, 60, 72, 80, 100 },
- { 18, 30, 36, 45, 54, 60, 75 },
- { 6, 10, 12, 15, 18, 21, 25 } };
-
-struct cam_size {
- u16 width;
- u16 height;
- u8 cmd;
-};
-
-static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
- { 160, 136, 0xa },
- { 176, 144, 0x4 },
- { 320, 240, 0x5 } };
-
-struct konicawc {
- u8 brightness; /* camera uses 0 - 9, x11 for real value */
- u8 contrast; /* as above */
- u8 saturation; /* as above */
- u8 sharpness; /* as above */
- u8 white_bal; /* 0 - 33, x11 for real value */
- u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */
- u8 size; /* Frame Size */
- int height;
- int width;
- struct urb *sts_urb[USBVIDEO_NUMSBUF];
- u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC];
- struct urb *last_data_urb;
- int lastframe;
- int cur_frame_size; /* number of bytes in current frame size */
- int maxline; /* number of lines per frame */
- int yplanesz; /* Number of bytes in the Y plane */
- unsigned int buttonsts:1;
-#ifdef CONFIG_INPUT
- struct input_dev *input;
- char input_physname[64];
-#endif
-};
-
-
-#define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0)
-#define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz)
-#define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0)
-
-
-static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
-{
- int retval = usb_control_msg(uvd->dev,
- dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0),
- request, 0x40 | dir, value, index, buf, len, 1000);
- return retval < 0 ? retval : 0;
-}
-
-
-static inline void konicawc_camera_on(struct uvd *uvd)
-{
- DEBUG(0, "camera on");
- konicawc_set_misc(uvd, 0x2, 1, 0x0b);
-}
-
-
-static inline void konicawc_camera_off(struct uvd *uvd)
-{
- DEBUG(0, "camera off");
- konicawc_set_misc(uvd, 0x2, 0, 0x0b);
-}
-
-
-static void konicawc_set_camera_size(struct uvd *uvd)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08);
- cam->width = camera_sizes[cam->size].width;
- cam->height = camera_sizes[cam->size].height;
- cam->yplanesz = cam->height * cam->width;
- cam->cur_frame_size = (cam->yplanesz * 3) / 2;
- cam->maxline = cam->yplanesz / 256;
- uvd->videosize = VIDEOSIZE(cam->width, cam->height);
-}
-
-
-static int konicawc_setup_on_open(struct uvd *uvd)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
- cam->brightness * 11);
- konicawc_set_value(uvd, cam->brightness, SetBrightness);
- DEBUG(1, "setting white balance to %d (%d)", cam->white_bal,
- cam->white_bal * 11);
- konicawc_set_value(uvd, cam->white_bal, SetWhitebal);
- DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
- cam->contrast * 11);
- konicawc_set_value(uvd, cam->contrast, SetContrast);
- DEBUG(1, "setting saturation to %d (%d)", cam->saturation,
- cam->saturation * 11);
- konicawc_set_value(uvd, cam->saturation, SetSaturation);
- DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness,
- cam->sharpness * 11);
- konicawc_set_value(uvd, cam->sharpness, SetSharpness);
- konicawc_set_camera_size(uvd);
- cam->lastframe = -2;
- cam->buttonsts = 0;
- return 0;
-}
-
-
-static void konicawc_adjust_picture(struct uvd *uvd)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- konicawc_camera_off(uvd);
- DEBUG(1, "new brightness: %d", uvd->vpic.brightness);
- uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness;
- if(cam->brightness != uvd->vpic.brightness / 11) {
- cam->brightness = uvd->vpic.brightness / 11;
- DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
- cam->brightness * 11);
- konicawc_set_value(uvd, cam->brightness, SetBrightness);
- }
-
- DEBUG(1, "new contrast: %d", uvd->vpic.contrast);
- uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast;
- if(cam->contrast != uvd->vpic.contrast / 11) {
- cam->contrast = uvd->vpic.contrast / 11;
- DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
- cam->contrast * 11);
- konicawc_set_value(uvd, cam->contrast, SetContrast);
- }
- konicawc_camera_on(uvd);
-}
-
-#ifdef CONFIG_INPUT
-
-static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev)
-{
- struct input_dev *input_dev;
- int error;
-
- usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
- strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
-
- cam->input = input_dev = input_allocate_device();
- if (!input_dev) {
- dev_warn(&dev->dev,
- "Not enough memory for camera's input device\n");
- return;
- }
-
- input_dev->name = "Konicawc snapshot button";
- input_dev->phys = cam->input_physname;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &dev->dev;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
-
- error = input_register_device(cam->input);
- if (error) {
- dev_warn(&dev->dev,
- "Failed to register camera's input device, err: %d\n",
- error);
- input_free_device(cam->input);
- cam->input = NULL;
- }
-}
-
-static void konicawc_unregister_input(struct konicawc *cam)
-{
- if (cam->input) {
- input_unregister_device(cam->input);
- cam->input = NULL;
- }
-}
-
-static void konicawc_report_buttonstat(struct konicawc *cam)
-{
- if (cam->input) {
- input_report_key(cam->input, KEY_CAMERA, cam->buttonsts);
- input_sync(cam->input);
- }
-}
-
-#else
-
-static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { }
-static inline void konicawc_unregister_input(struct konicawc *cam) { }
-static inline void konicawc_report_buttonstat(struct konicawc *cam) { }
-
-#endif /* CONFIG_INPUT */
-
-static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
-{
- char *cdata;
- int i, totlen = 0;
- unsigned char *status = stsurb->transfer_buffer;
- int keep = 0, discard = 0, bad = 0;
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- for (i = 0; i < dataurb->number_of_packets; i++) {
- int button = cam->buttonsts;
- unsigned char sts;
- int n = dataurb->iso_frame_desc[i].actual_length;
- int st = dataurb->iso_frame_desc[i].status;
- cdata = dataurb->transfer_buffer +
- dataurb->iso_frame_desc[i].offset;
-
- /* Detect and ignore errored packets */
- if (st < 0) {
- DEBUG(1, "Data error: packet=%d. len=%d. status=%d.",
- i, n, st);
- uvd->stats.iso_err_count++;
- continue;
- }
-
- /* Detect and ignore empty packets */
- if (n <= 0) {
- uvd->stats.iso_skip_count++;
- continue;
- }
-
- /* See what the status data said about the packet */
- sts = *(status+stsurb->iso_frame_desc[i].offset);
-
- /* sts: 0x80-0xff: frame start with frame number (ie 0-7f)
- * otherwise:
- * bit 0 0: keep packet
- * 1: drop packet (padding data)
- *
- * bit 4 0 button not clicked
- * 1 button clicked
- * button is used to `take a picture' (in software)
- */
-
- if(sts < 0x80) {
- button = !!(sts & 0x40);
- sts &= ~0x40;
- }
-
- /* work out the button status, but don't do
- anything with it for now */
-
- if(button != cam->buttonsts) {
- DEBUG(2, "button: %sclicked", button ? "" : "un");
- cam->buttonsts = button;
- konicawc_report_buttonstat(cam);
- }
-
- if(sts == 0x01) { /* drop frame */
- discard++;
- continue;
- }
-
- if((sts > 0x01) && (sts < 0x80)) {
- dev_info(&uvd->dev->dev, "unknown status %2.2x\n",
- sts);
- bad++;
- continue;
- }
- if(!sts && cam->lastframe == -2) {
- DEBUG(2, "dropping frame looking for image start");
- continue;
- }
-
- keep++;
- if(sts & 0x80) { /* frame start */
- unsigned char marker[] = { 0, 0xff, 0, 0x00 };
-
- if(cam->lastframe == -2) {
- DEBUG(2, "found initial image");
- cam->lastframe = -1;
- }
-
- marker[3] = sts & 0x7F;
- RingQueue_Enqueue(&uvd->dp, marker, 4);
- totlen += 4;
- }
-
- totlen += n; /* Little local accounting */
- RingQueue_Enqueue(&uvd->dp, cdata, n);
- }
- DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes",
- keep, discard, bad, totlen);
- return totlen;
-}
-
-
-static void resubmit_urb(struct uvd *uvd, struct urb *urb)
-{
- int i, ret;
- for (i = 0; i < FRAMES_PER_DESC; i++) {
- urb->iso_frame_desc[i].status = 0;
- }
- urb->dev = uvd->dev;
- urb->status = 0;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length);
- if(ret)
- err("usb_submit_urb error (%d)", ret);
-
-}
-
-
-static void konicawc_isoc_irq(struct urb *urb)
-{
- struct uvd *uvd = urb->context;
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- /* We don't want to do anything if we are about to be removed! */
- if (!CAMERA_IS_OPERATIONAL(uvd))
- return;
-
- if (!uvd->streaming) {
- DEBUG(1, "Not streaming, but interrupt!");
- return;
- }
-
- DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length);
-
- uvd->stats.urb_count++;
-
- if (urb->transfer_buffer_length > 32) {
- cam->last_data_urb = urb;
- return;
- }
- /* Copy the data received into ring queue */
- if(cam->last_data_urb) {
- int len = 0;
- if(urb->start_frame != cam->last_data_urb->start_frame)
- err("Lost sync on frames");
- else if (!urb->status && !cam->last_data_urb->status)
- len = konicawc_compress_iso(uvd, cam->last_data_urb, urb);
-
- resubmit_urb(uvd, cam->last_data_urb);
- resubmit_urb(uvd, urb);
- cam->last_data_urb = NULL;
- uvd->stats.urb_length = len;
- uvd->stats.data_count += len;
- if(len)
- RingQueue_WakeUpInterruptible(&uvd->dp);
- return;
- }
- return;
-}
-
-
-static int konicawc_start_data(struct uvd *uvd)
-{
- struct usb_device *dev = uvd->dev;
- int i, errFlag;
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
- int pktsz;
- struct usb_interface *intf;
- struct usb_host_interface *interface = NULL;
-
- intf = usb_ifnum_to_if(dev, uvd->iface);
- if (intf)
- interface = usb_altnum_to_altsetting(intf,
- spd_to_iface[cam->speed]);
- if (!interface)
- return -ENXIO;
- pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize);
- DEBUG(1, "pktsz = %d", pktsz);
- if (!CAMERA_IS_OPERATIONAL(uvd)) {
- err("Camera is not operational");
- return -EFAULT;
- }
- uvd->curframe = -1;
- konicawc_camera_on(uvd);
- /* Alternate interface 1 is is the biggest frame size */
- i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
- if (i < 0) {
- err("usb_set_interface error");
- uvd->last_error = i;
- return -EBUSY;
- }
-
- /* We double buffer the Iso lists */
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- int j, k;
- struct urb *urb = uvd->sbuf[i].urb;
- urb->dev = dev;
- urb->context = uvd;
- urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
- urb->interval = 1;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = uvd->sbuf[i].data;
- urb->complete = konicawc_isoc_irq;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
- for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length = pktsz;
- }
-
- urb = cam->sts_urb[i];
- urb->dev = dev;
- urb->context = uvd;
- urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
- urb->interval = 1;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = cam->sts_buf[i];
- urb->complete = konicawc_isoc_irq;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = FRAMES_PER_DESC;
- for (j=0; j < FRAMES_PER_DESC; j++) {
- urb->iso_frame_desc[j].offset = j;
- urb->iso_frame_desc[j].length = 1;
- }
- }
-
- cam->last_data_urb = NULL;
-
- /* Submit all URBs */
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL);
- if (errFlag)
- err("usb_submit_isoc(%d) ret %d", i, errFlag);
-
- errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
- if (errFlag)
- err ("usb_submit_isoc(%d) ret %d", i, errFlag);
- }
-
- uvd->streaming = 1;
- DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp);
- return 0;
-}
-
-
-static void konicawc_stop_data(struct uvd *uvd)
-{
- int i, j;
- struct konicawc *cam;
-
- if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
- return;
-
- konicawc_camera_off(uvd);
- uvd->streaming = 0;
- cam = (struct konicawc *)uvd->user_data;
- cam->last_data_urb = NULL;
-
- /* Unschedule all of the iso td's */
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- usb_kill_urb(uvd->sbuf[i].urb);
- usb_kill_urb(cam->sts_urb[i]);
- }
-
- if (!uvd->remove_pending) {
- /* Set packet size to 0 */
- j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
- if (j < 0) {
- err("usb_set_interface() error %d.", j);
- uvd->last_error = j;
- }
- }
-}
-
-
-static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
- int maxline = cam->maxline;
- int yplanesz = cam->yplanesz;
-
- assert(frame != NULL);
-
- DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz);
- DEBUG(3, "Frame state = %d", frame->scanstate);
-
- if(frame->scanstate == ScanState_Scanning) {
- int drop = 0;
- int curframe;
- int fdrops = 0;
- DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
- while(RingQueue_GetLength(&uvd->dp) >= 4) {
- if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
- (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
- curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
- if(cam->lastframe >= 0) {
- fdrops = (0x80 + curframe - cam->lastframe) & 0x7F;
- fdrops--;
- if(fdrops) {
- dev_info(&uvd->dev->dev,
- "Dropped %d frames "
- "(%d -> %d)\n",
- fdrops,
- cam->lastframe,
- curframe);
- }
- }
- cam->lastframe = curframe;
- frame->curline = 0;
- frame->scanstate = ScanState_Lines;
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
- break;
- }
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
- drop++;
- }
- if(drop)
- DEBUG(2, "dropped %d bytes looking for new frame", drop);
- }
-
- if(frame->scanstate == ScanState_Scanning)
- return;
-
- /* Try to move data from queue into frame buffer
- * We get data in blocks of 384 bytes made up of:
- * 256 Y, 64 U, 64 V.
- * This needs to be written out as a Y plane, a U plane and a V plane.
- */
-
- while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) {
- /* Y */
- RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
- /* U */
- RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
- /* V */
- RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
- frame->seqRead_Length += 384;
- frame->curline++;
- }
- /* See if we filled the frame */
- if (frame->curline == maxline) {
- DEBUG(5, "got whole frame");
-
- frame->frameState = FrameState_Done_Hold;
- frame->curline = 0;
- uvd->curframe = -1;
- uvd->stats.frame_num++;
- }
-}
-
-
-static int konicawc_find_fps(int size, int fps)
-{
- int i;
-
- fps *= 3;
- DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps);
- if(fps <= spd_to_fps[size][0])
- return 0;
-
- if(fps >= spd_to_fps[size][MAX_SPEED])
- return MAX_SPEED;
-
- for(i = 0; i < MAX_SPEED; i++) {
- if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) {
- DEBUG(2, "fps %d between %d and %d", fps, i, i+1);
- if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps))
- return i;
- else
- return i+1;
- }
- }
- return MAX_SPEED+1;
-}
-
-
-static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
- int newspeed = cam->speed;
- int newsize;
- int x = vw->width;
- int y = vw->height;
- int fps = vw->flags;
-
- if(x > 0 && y > 0) {
- DEBUG(2, "trying to find size %d,%d", x, y);
- for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
- if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y))
- break;
- }
- } else {
- newsize = cam->size;
- }
-
- if(newsize > MAX_FRAME_SIZE) {
- DEBUG(1, "couldn't find size %d,%d", x, y);
- return -EINVAL;
- }
-
- if(fps > 0) {
- DEBUG(1, "trying to set fps to %d", fps);
- newspeed = konicawc_find_fps(newsize, fps);
- DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]);
- }
-
- if(newspeed > MAX_SPEED)
- return -EINVAL;
-
- DEBUG(1, "setting size to %d speed to %d", newsize, newspeed);
- if((newsize == cam->size) && (newspeed == cam->speed)) {
- DEBUG(1, "Nothing to do");
- return 0;
- }
- DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width,
- camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3);
-
- konicawc_stop_data(uvd);
- uvd->ifaceAltActive = spd_to_iface[newspeed];
- DEBUG(1, "new interface = %d", uvd->ifaceAltActive);
- cam->speed = newspeed;
-
- if(cam->size != newsize) {
- cam->size = newsize;
- konicawc_set_camera_size(uvd);
- }
-
- /* Flush the input queue and clear any current frame in progress */
-
- RingQueue_Flush(&uvd->dp);
- cam->lastframe = -2;
- if(uvd->curframe != -1) {
- uvd->frame[uvd->curframe].curline = 0;
- uvd->frame[uvd->curframe].seqRead_Length = 0;
- uvd->frame[uvd->curframe].seqRead_Index = 0;
- }
-
- konicawc_start_data(uvd);
- return 0;
-}
-
-
-static int konicawc_calculate_fps(struct uvd *uvd)
-{
- struct konicawc *cam = uvd->user_data;
- return spd_to_fps[cam->size][cam->speed]/3;
-}
-
-
-static void konicawc_configure_video(struct uvd *uvd)
-{
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
- u8 buf[2];
-
- memset(&uvd->vpic, 0, sizeof(uvd->vpic));
- memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
-
- RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS);
- RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST);
- RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION);
- RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS);
- RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL);
-
- cam->brightness = brightness / 11;
- cam->contrast = contrast / 11;
- cam->saturation = saturation / 11;
- cam->sharpness = sharpness / 11;
- cam->white_bal = whitebal / 11;
-
- uvd->vpic.colour = 108;
- uvd->vpic.hue = 108;
- uvd->vpic.brightness = brightness;
- uvd->vpic.contrast = contrast;
- uvd->vpic.whiteness = whitebal;
- uvd->vpic.depth = 6;
- uvd->vpic.palette = VIDEO_PALETTE_YUV420P;
-
- memset(&uvd->vcap, 0, sizeof(uvd->vcap));
- strcpy(uvd->vcap.name, "Konica Webcam");
- uvd->vcap.type = VID_TYPE_CAPTURE;
- uvd->vcap.channels = 1;
- uvd->vcap.audios = 0;
- uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
- uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
- uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
- uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
-
- memset(&uvd->vchan, 0, sizeof(uvd->vchan));
- uvd->vchan.flags = 0 ;
- uvd->vchan.tuners = 0;
- uvd->vchan.channel = 0;
- uvd->vchan.type = VIDEO_TYPE_CAMERA;
- strcpy(uvd->vchan.name, "Camera");
-
- /* Talk to device */
- DEBUG(1, "device init");
- if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
- DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
- if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
- DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
- if(konicawc_set_misc(uvd, 0x2, 0, 0xd))
- DEBUG(2, "2,0,d failed");
- DEBUG(1, "setting initial values");
-}
-
-static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct uvd *uvd = NULL;
- int ix, i, nas;
- int actInterface=-1, inactInterface=-1, maxPS=0;
- unsigned char video_ep = 0;
-
- DEBUG(1, "konicawc_probe(%p)", intf);
-
- /* We don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- dev_info(&intf->dev, "Konica Webcam (rev. 0x%04x)\n",
- le16_to_cpu(dev->descriptor.bcdDevice));
- RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
-
- /* Validate found interface: must have one ISO endpoint */
- nas = intf->num_altsetting;
- if (nas != 8) {
- err("Incorrect number of alternate settings (%d) for this camera!", nas);
- return -ENODEV;
- }
- /* Validate all alternate settings */
- for (ix=0; ix < nas; ix++) {
- const struct usb_host_interface *interface;
- const struct usb_endpoint_descriptor *endpoint;
-
- interface = &intf->altsetting[ix];
- i = interface->desc.bAlternateSetting;
- if (interface->desc.bNumEndpoints != 2) {
- err("Interface %d. has %u. endpoints!",
- interface->desc.bInterfaceNumber,
- (unsigned)(interface->desc.bNumEndpoints));
- return -ENODEV;
- }
- endpoint = &interface->endpoint[1].desc;
- DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
- endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize));
- if (video_ep == 0)
- video_ep = endpoint->bEndpointAddress;
- else if (video_ep != endpoint->bEndpointAddress) {
- err("Alternate settings have different endpoint addresses!");
- return -ENODEV;
- }
- if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("Interface %d. has non-ISO endpoint!",
- interface->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (usb_endpoint_dir_out(endpoint)) {
- err("Interface %d. has ISO OUT endpoint!",
- interface->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
- if (inactInterface < 0)
- inactInterface = i;
- else {
- err("More than one inactive alt. setting!");
- return -ENODEV;
- }
- } else {
- if (i == spd_to_iface[speed]) {
- /* This one is the requested one */
- actInterface = i;
- }
- }
- if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS)
- maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
- }
- if(actInterface == -1) {
- err("Cant find required endpoint");
- return -ENODEV;
- }
-
- DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
-
- uvd = usbvideo_AllocateDevice(cams);
- if (uvd != NULL) {
- struct konicawc *cam = (struct konicawc *)(uvd->user_data);
- /* Here uvd is a fully allocated uvd object */
- for(i = 0; i < USBVIDEO_NUMSBUF; i++) {
- cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if(cam->sts_urb[i] == NULL) {
- while(i--) {
- usb_free_urb(cam->sts_urb[i]);
- }
- err("can't allocate urbs");
- return -ENOMEM;
- }
- }
- cam->speed = speed;
- RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
- cam->width = camera_sizes[size].width;
- cam->height = camera_sizes[size].height;
- cam->size = size;
-
- uvd->flags = 0;
- uvd->debug = debug;
- uvd->dev = dev;
- uvd->iface = intf->altsetting->desc.bInterfaceNumber;
- uvd->ifaceAltInactive = inactInterface;
- uvd->ifaceAltActive = actInterface;
- uvd->video_endp = video_ep;
- uvd->iso_packet_len = maxPS;
- uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P;
- uvd->defaultPalette = VIDEO_PALETTE_YUV420P;
- uvd->canvas = VIDEOSIZE(320, 240);
- uvd->videosize = VIDEOSIZE(cam->width, cam->height);
-
- /* Initialize konicawc specific data */
- konicawc_configure_video(uvd);
-
- i = usbvideo_RegisterVideoDevice(uvd);
- uvd->max_frame_size = (320 * 240 * 3)/2;
- if (i != 0) {
- err("usbvideo_RegisterVideoDevice() failed.");
- uvd = NULL;
- }
-
- konicawc_register_input(cam, dev);
- }
-
- if (uvd) {
- usb_set_intfdata (intf, uvd);
- return 0;
- }
- return -EIO;
-}
-
-
-static void konicawc_free_uvd(struct uvd *uvd)
-{
- int i;
- struct konicawc *cam = (struct konicawc *)uvd->user_data;
-
- konicawc_unregister_input(cam);
-
- for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
- usb_free_urb(cam->sts_urb[i]);
- cam->sts_urb[i] = NULL;
- }
-}
-
-
-static struct usb_device_id id_table[] = {
- { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */
- { } /* Terminating entry */
-};
-
-
-static int __init konicawc_init(void)
-{
- struct usbvideo_cb cbTbl;
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
- memset(&cbTbl, 0, sizeof(cbTbl));
- cbTbl.probe = konicawc_probe;
- cbTbl.setupOnOpen = konicawc_setup_on_open;
- cbTbl.processData = konicawc_process_isoc;
- cbTbl.getFPS = konicawc_calculate_fps;
- cbTbl.setVideoMode = konicawc_set_video_mode;
- cbTbl.startDataPump = konicawc_start_data;
- cbTbl.stopDataPump = konicawc_stop_data;
- cbTbl.adjustPicture = konicawc_adjust_picture;
- cbTbl.userFree = konicawc_free_uvd;
- return usbvideo_register(
- &cams,
- MAX_CAMERAS,
- sizeof(struct konicawc),
- "konicawc",
- &cbTbl,
- THIS_MODULE,
- id_table);
-}
-
-
-static void __exit konicawc_cleanup(void)
-{
- usbvideo_Deregister(&cams);
-}
-
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-module_param(speed, int, 0);
-MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)");
-module_param(size, int, 0);
-MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240");
-module_param(brightness, int, 0);
-MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108");
-module_param(contrast, int, 0);
-MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108");
-module_param(saturation, int, 0);
-MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108");
-module_param(sharpness, int, 0);
-MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108");
-module_param(whitebal, int, 0);
-MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363");
-
-#ifdef CONFIG_USB_DEBUG
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
-#endif
-
-module_init(konicawc_init);
-module_exit(konicawc_cleanup);
diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/media/video/usbvideo/ultracam.c
deleted file mode 100644
index fbd1b6392290..000000000000
--- a/drivers/media/video/usbvideo/ultracam.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * USB NB Camera driver
- *
- * HISTORY:
- * 25-Dec-2002 Dmitri Removed lighting, sharpness parameters, methods.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "usbvideo.h"
-
-#define ULTRACAM_VENDOR_ID 0x0461
-#define ULTRACAM_PRODUCT_ID 0x0813
-
-#define MAX_CAMERAS 4 /* How many devices we allow to connect */
-
-/*
- * This structure lives in uvd_t->user field.
- */
-typedef struct {
- int initialized; /* Had we already sent init sequence? */
- int camera_model; /* What type of IBM camera we got? */
- int has_hdr;
-} ultracam_t;
-#define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data))
-
-static struct usbvideo *cams = NULL;
-
-static int debug;
-
-static int flags; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
-
-static const int min_canvasWidth = 8;
-static const int min_canvasHeight = 4;
-
-#define FRAMERATE_MIN 0
-#define FRAMERATE_MAX 6
-static int framerate = -1;
-
-/*
- * Here we define several initialization variables. They may
- * be used to automatically set color, hue, brightness and
- * contrast to desired values. This is particularly useful in
- * case of webcams (which have no controls and no on-screen
- * output) and also when a client V4L software is used that
- * does not have some of those controls. In any case it's
- * good to have startup values as options.
- *
- * These values are all in [0..255] range. This simplifies
- * operation. Note that actual values of V4L variables may
- * be scaled up (as much as << 8). User can see that only
- * on overlay output, however, or through a V4L client.
- */
-static int init_brightness = 128;
-static int init_contrast = 192;
-static int init_color = 128;
-static int init_hue = 128;
-static int hue_correction = 128;
-
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
-module_param(flags, int, 0);
-MODULE_PARM_DESC(flags,
- "Bitfield: 0=VIDIOCSYNC, "
- "1=B/W, "
- "2=show hints, "
- "3=show stats, "
- "4=test pattern, "
- "5=separate frames, "
- "6=clean frames");
-module_param(framerate, int, 0);
-MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
-
-module_param(init_brightness, int, 0);
-MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
-module_param(init_contrast, int, 0);
-MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
-module_param(init_color, int, 0);
-MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
-module_param(init_hue, int, 0);
-MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
-module_param(hue_correction, int, 0);
-MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
-
-/*
- * ultracam_ProcessIsocData()
- *
- * Generic routine to parse the ring queue data. It employs either
- * ultracam_find_header() or ultracam_parse_lines() to do most
- * of work.
- *
- * 02-Nov-2000 First (mostly dummy) version.
- * 06-Nov-2000 Rewrote to dump all data into frame.
- */
-static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame)
-{
- int n;
-
- assert(uvd != NULL);
- assert(frame != NULL);
-
- /* Try to move data from queue into frame buffer */
- n = RingQueue_GetLength(&uvd->dp);
- if (n > 0) {
- int m;
- /* See how much spare we have left */
- m = uvd->max_frame_size - frame->seqRead_Length;
- if (n > m)
- n = m;
- /* Now move that much data into frame buffer */
- RingQueue_Dequeue(
- &uvd->dp,
- frame->data + frame->seqRead_Length,
- m);
- frame->seqRead_Length += m;
- }
- /* See if we filled the frame */
- if (frame->seqRead_Length >= uvd->max_frame_size) {
- frame->frameState = FrameState_Done;
- uvd->curframe = -1;
- uvd->stats.frame_num++;
- }
-}
-
-/*
- * ultracam_veio()
- *
- * History:
- * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
- */
-static int ultracam_veio(
- struct uvd *uvd,
- unsigned char req,
- unsigned short value,
- unsigned short index,
- int is_out)
-{
- static const char proc[] = "ultracam_veio";
- unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
- int i;
-
- if (!CAMERA_IS_OPERATIONAL(uvd))
- return 0;
-
- if (!is_out) {
- i = usb_control_msg(
- uvd->dev,
- usb_rcvctrlpipe(uvd->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- cp,
- sizeof(cp),
- 1000);
-#if 1
- dev_info(&uvd->dev->dev,
- "USB => %02x%02x%02x%02x%02x%02x%02x%02x "
- "(req=$%02x val=$%04x ind=$%04x)\n",
- cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
- req, value, index);
-#endif
- } else {
- i = usb_control_msg(
- uvd->dev,
- usb_sndctrlpipe(uvd->dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- NULL,
- 0,
- 1000);
- }
- if (i < 0) {
- err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
- proc, i);
- uvd->last_error = i;
- }
- return i;
-}
-
-/*
- * ultracam_calculate_fps()
- */
-static int ultracam_calculate_fps(struct uvd *uvd)
-{
- return 3 + framerate*4 + framerate/2;
-}
-
-/*
- * ultracam_adjust_contrast()
- */
-static void ultracam_adjust_contrast(struct uvd *uvd)
-{
-}
-
-/*
- * ultracam_set_brightness()
- *
- * This procedure changes brightness of the picture.
- */
-static void ultracam_set_brightness(struct uvd *uvd)
-{
-}
-
-static void ultracam_set_hue(struct uvd *uvd)
-{
-}
-
-/*
- * ultracam_adjust_picture()
- *
- * This procedure gets called from V4L interface to update picture settings.
- * Here we change brightness and contrast.
- */
-static void ultracam_adjust_picture(struct uvd *uvd)
-{
- ultracam_adjust_contrast(uvd);
- ultracam_set_brightness(uvd);
- ultracam_set_hue(uvd);
-}
-
-/*
- * ultracam_video_stop()
- *
- * This code tells camera to stop streaming. The interface remains
- * configured and bandwidth - claimed.
- */
-static void ultracam_video_stop(struct uvd *uvd)
-{
-}
-
-/*
- * ultracam_reinit_iso()
- *
- * This procedure sends couple of commands to the camera and then
- * resets the video pipe. This sequence was observed to reinit the
- * camera or, at least, to initiate ISO data stream.
- */
-static void ultracam_reinit_iso(struct uvd *uvd, int do_stop)
-{
-}
-
-static void ultracam_video_start(struct uvd *uvd)
-{
- ultracam_reinit_iso(uvd, 0);
-}
-
-static int ultracam_resetPipe(struct uvd *uvd)
-{
- usb_clear_halt(uvd->dev, uvd->video_endp);
- return 0;
-}
-
-static int ultracam_alternateSetting(struct uvd *uvd, int setting)
-{
- static const char proc[] = "ultracam_alternateSetting";
- int i;
- i = usb_set_interface(uvd->dev, uvd->iface, setting);
- if (i < 0) {
- err("%s: usb_set_interface error", proc);
- uvd->last_error = i;
- return -EBUSY;
- }
- return 0;
-}
-
-/*
- * Return negative code on failure, 0 on success.
- */
-static int ultracam_setup_on_open(struct uvd *uvd)
-{
- int setup_ok = 0; /* Success by default */
- /* Send init sequence only once, it's large! */
- if (!ULTRACAM_T(uvd)->initialized) {
- ultracam_alternateSetting(uvd, 0x04);
- ultracam_alternateSetting(uvd, 0x00);
- ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1);
- ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1);
- ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
- ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1);
- ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1);
- ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1);
- ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1);
- ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1);
- ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1);
- ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1);
- ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1);
- ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1);
- ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1);
- ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1);
- ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1);
- ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
- ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
- ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
- ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
- ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
- ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
- ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
- ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
- ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1);
- ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1);
- ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1);
- ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1);
- ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1);
- ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1);
- ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1);
- ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1);
- ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1);
- ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1);
- ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1);
- ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1);
- ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1);
- ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1);
- ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1);
- ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1);
- ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1);
- ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1);
- ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1);
- ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1);
- ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1);
- ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1);
- ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0004, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0002, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0020, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0040, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0017, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
- ultracam_veio(uvd, 0x00, 0x00c0, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_veio(uvd, 0x02, 0xc040, 0x0001, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0008, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0009, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000b, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000c, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000d, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000e, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000f, 0);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0010, 0);
- ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
- ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
- ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
- ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
- ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
- ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
- ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
- ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
- ultracam_veio(uvd, 0x01, 0x0000, 0x0001, 0);
- ultracam_veio(uvd, 0x01, 0x0064, 0x0001, 1);
- ultracam_veio(uvd, 0x01, 0x0059, 0x0051, 1);
- ultracam_veio(uvd, 0x01, 0x003f, 0x0052, 1);
- ultracam_veio(uvd, 0x01, 0x0094, 0x0053, 1);
- ultracam_veio(uvd, 0x01, 0x00ff, 0x0011, 1);
- ultracam_veio(uvd, 0x01, 0x0003, 0x0012, 1);
- ultracam_veio(uvd, 0x01, 0x00f7, 0x0013, 1);
- ultracam_veio(uvd, 0x00, 0x0009, 0x0011, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0001, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
- ultracam_veio(uvd, 0x00, 0x0020, 0x00c1, 1);
- ultracam_veio(uvd, 0x00, 0x0010, 0x00c2, 1);
- ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
- ultracam_alternateSetting(uvd, 0x04);
- ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
- ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
- ultracam_veio(uvd, 0x02, 0x0000, 0x0006, 1);
- ultracam_veio(uvd, 0x02, 0x9000, 0x0007, 1);
- ultracam_veio(uvd, 0x02, 0x0042, 0x0001, 1);
- ultracam_veio(uvd, 0x02, 0x0000, 0x000b, 0);
- ultracam_resetPipe(uvd);
- ULTRACAM_T(uvd)->initialized = (setup_ok != 0);
- }
- return setup_ok;
-}
-
-static void ultracam_configure_video(struct uvd *uvd)
-{
- if (uvd == NULL)
- return;
-
- RESTRICT_TO_RANGE(init_brightness, 0, 255);
- RESTRICT_TO_RANGE(init_contrast, 0, 255);
- RESTRICT_TO_RANGE(init_color, 0, 255);
- RESTRICT_TO_RANGE(init_hue, 0, 255);
- RESTRICT_TO_RANGE(hue_correction, 0, 255);
-
- memset(&uvd->vpic, 0, sizeof(uvd->vpic));
- memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
-
- uvd->vpic.colour = init_color << 8;
- uvd->vpic.hue = init_hue << 8;
- uvd->vpic.brightness = init_brightness << 8;
- uvd->vpic.contrast = init_contrast << 8;
- uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
- uvd->vpic.depth = 24;
- uvd->vpic.palette = VIDEO_PALETTE_RGB24;
-
- memset(&uvd->vcap, 0, sizeof(uvd->vcap));
- strcpy(uvd->vcap.name, "IBM Ultra Camera");
- uvd->vcap.type = VID_TYPE_CAPTURE;
- uvd->vcap.channels = 1;
- uvd->vcap.audios = 0;
- uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
- uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
- uvd->vcap.minwidth = min_canvasWidth;
- uvd->vcap.minheight = min_canvasHeight;
-
- memset(&uvd->vchan, 0, sizeof(uvd->vchan));
- uvd->vchan.flags = 0;
- uvd->vchan.tuners = 0;
- uvd->vchan.channel = 0;
- uvd->vchan.type = VIDEO_TYPE_CAMERA;
- strcpy(uvd->vchan.name, "Camera");
-}
-
-/*
- * ultracam_probe()
- *
- * This procedure queries device descriptor and accepts the interface
- * if it looks like our camera.
- *
- * History:
- * 12-Nov-2000 Reworked to comply with new probe() signature.
- * 23-Jan-2001 Added compatibility with 2.2.x kernels.
- */
-static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct uvd *uvd = NULL;
- int ix, i, nas;
- int actInterface=-1, inactInterface=-1, maxPS=0;
- unsigned char video_ep = 0;
-
- if (debug >= 1)
- dev_info(&intf->dev, "ultracam_probe\n");
-
- /* We don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- dev_info(&intf->dev, "IBM Ultra camera found (rev. 0x%04x)\n",
- le16_to_cpu(dev->descriptor.bcdDevice));
-
- /* Validate found interface: must have one ISO endpoint */
- nas = intf->num_altsetting;
- if (debug > 0)
- dev_info(&intf->dev, "Number of alternate settings=%d.\n",
- nas);
- if (nas < 8) {
- err("Too few alternate settings for this camera!");
- return -ENODEV;
- }
- /* Validate all alternate settings */
- for (ix=0; ix < nas; ix++) {
- const struct usb_host_interface *interface;
- const struct usb_endpoint_descriptor *endpoint;
-
- interface = &intf->altsetting[ix];
- i = interface->desc.bAlternateSetting;
- if (interface->desc.bNumEndpoints != 1) {
- err("Interface %d. has %u. endpoints!",
- interface->desc.bInterfaceNumber,
- (unsigned)(interface->desc.bNumEndpoints));
- return -ENODEV;
- }
- endpoint = &interface->endpoint[0].desc;
- if (video_ep == 0)
- video_ep = endpoint->bEndpointAddress;
- else if (video_ep != endpoint->bEndpointAddress) {
- err("Alternate settings have different endpoint addresses!");
- return -ENODEV;
- }
- if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("Interface %d. has non-ISO endpoint!",
- interface->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (usb_endpoint_dir_out(endpoint)) {
- err("Interface %d. has ISO OUT endpoint!",
- interface->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
- if (inactInterface < 0)
- inactInterface = i;
- else {
- err("More than one inactive alt. setting!");
- return -ENODEV;
- }
- } else {
- if (actInterface < 0) {
- actInterface = i;
- maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
- if (debug > 0)
- dev_info(&intf->dev,
- "Active setting=%d. "
- "maxPS=%d.\n", i, maxPS);
- } else {
- /* Got another active alt. setting */
- if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) {
- /* This one is better! */
- actInterface = i;
- maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
- if (debug > 0) {
- dev_info(&intf->dev,
- "Even better ctive "
- "setting=%d. "
- "maxPS=%d.\n",
- i, maxPS);
- }
- }
- }
- }
- }
- if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
- err("Failed to recognize the camera!");
- return -ENODEV;
- }
-
- uvd = usbvideo_AllocateDevice(cams);
- if (uvd != NULL) {
- /* Here uvd is a fully allocated uvd object */
- uvd->flags = flags;
- uvd->debug = debug;
- uvd->dev = dev;
- uvd->iface = intf->altsetting->desc.bInterfaceNumber;
- uvd->ifaceAltInactive = inactInterface;
- uvd->ifaceAltActive = actInterface;
- uvd->video_endp = video_ep;
- uvd->iso_packet_len = maxPS;
- uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
- uvd->defaultPalette = VIDEO_PALETTE_RGB24;
- uvd->canvas = VIDEOSIZE(640, 480); /* FIXME */
- uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/
-
- /* Initialize ibmcam-specific data */
- assert(ULTRACAM_T(uvd) != NULL);
- ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */
- ULTRACAM_T(uvd)->initialized = 0;
-
- ultracam_configure_video(uvd);
-
- i = usbvideo_RegisterVideoDevice(uvd);
- if (i != 0) {
- err("usbvideo_RegisterVideoDevice() failed.");
- uvd = NULL;
- }
- }
-
- if (uvd) {
- usb_set_intfdata (intf, uvd);
- return 0;
- }
- return -EIO;
-}
-
-
-static struct usb_device_id id_table[] = {
- { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-
-/*
- * ultracam_init()
- *
- * This code is run to initialize the driver.
- */
-static int __init ultracam_init(void)
-{
- struct usbvideo_cb cbTbl;
- memset(&cbTbl, 0, sizeof(cbTbl));
- cbTbl.probe = ultracam_probe;
- cbTbl.setupOnOpen = ultracam_setup_on_open;
- cbTbl.videoStart = ultracam_video_start;
- cbTbl.videoStop = ultracam_video_stop;
- cbTbl.processData = ultracam_ProcessIsocData;
- cbTbl.postProcess = usbvideo_DeinterlaceFrame;
- cbTbl.adjustPicture = ultracam_adjust_picture;
- cbTbl.getFPS = ultracam_calculate_fps;
- return usbvideo_register(
- &cams,
- MAX_CAMERAS,
- sizeof(ultracam_t),
- "ultracam",
- &cbTbl,
- THIS_MODULE,
- id_table);
-}
-
-static void __exit ultracam_cleanup(void)
-{
- usbvideo_Deregister(&cams);
-}
-
-MODULE_DEVICE_TABLE(usb, id_table);
-MODULE_LICENSE("GPL");
-
-module_init(ultracam_init);
-module_exit(ultracam_cleanup);
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index 503b13beb922..68b998bd203f 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -32,1072 +32,1072 @@
/* Supported Devices: A table for usbvision.c*/
struct usbvision_device_data_st usbvision_device_data[] = {
[XANBOO] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 4,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Xanboo",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 4,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Xanboo",
},
[BELKIN_VIDEOBUS_II] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Belkin USB VideoBus II Adapter",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Belkin USB VideoBus II Adapter",
},
[BELKIN_VIDEOBUS] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Belkin Components USB VideoBus",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Belkin Components USB VideoBus",
},
[BELKIN_USB_VIDEOBUS_II] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Belkin USB VideoBus II",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Belkin USB VideoBus II",
},
[ECHOFX_INTERVIEW_LITE] = {
- .Interface = 0,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = -1,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "echoFX InterView Lite",
+ .interface = 0,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = -1,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "echoFX InterView Lite",
},
[USBGEAR_USBG_V1] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "USBGear USBG-V1 resp. HAMA USB",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "USBGear USBG-V1 resp. HAMA USB",
},
[D_LINK_V100] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 4,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "D-Link V100",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 4,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "D-Link V100",
},
[X10_USB_CAMERA] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "X10 USB Camera",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "X10 USB Camera",
},
[HPG_WINTV_LIVE_PAL_BG] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = -1,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Live (PAL B/G)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = -1,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Live (PAL B/G)",
},
[HPG_WINTV_LIVE_PRO_NTSC_MN] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
},
[ZORAN_PMD_NOGATECH] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 2,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 2,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
},
[NOGATECH_USB_TV_NTSC_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = 20,
- .ModelString = "Nogatech USB-TV (NTSC) FM",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = 20,
+ .model_string = "Nogatech USB-TV (NTSC) FM",
},
[PNY_USB_TV_NTSC_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = 20,
- .ModelString = "PNY USB-TV (NTSC) FM",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = 20,
+ .model_string = "PNY USB-TV (NTSC) FM",
},
[PV_PLAYTV_USB_PRO_PAL_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "PixelView PlayTv-USB PRO (PAL) FM",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "PixelView PlayTv-USB PRO (PAL) FM",
},
[ZT_721] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "ZTV ZT-721 2.4GHz USB A/V Receiver",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "ZTV ZT-721 2.4GHz USB A/V Receiver",
},
[HPG_WINTV_NTSC_MN] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = 20,
- .ModelString = "Hauppauge WinTV USB (NTSC M/N)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = 20,
+ .model_string = "Hauppauge WinTV USB (NTSC M/N)",
},
[HPG_WINTV_PAL_BG] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL B/G)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL B/G)",
},
[HPG_WINTV_PAL_I] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL I)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL I)",
},
[HPG_WINTV_PAL_SECAM_L] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_SECAM,
- .X_Offset = 0x80,
- .Y_Offset = 0x16,
- .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .x_offset = 0x80,
+ .y_offset = 0x16,
+ .model_string = "Hauppauge WinTV USB (PAL/SECAM L)",
},
[HPG_WINTV_PAL_D_K] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL D/K)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL D/K)",
},
[HPG_WINTV_NTSC_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (NTSC FM)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (NTSC FM)",
},
[HPG_WINTV_PAL_BG_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL B/G FM)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL B/G FM)",
},
[HPG_WINTV_PAL_I_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL I FM)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL I FM)",
},
[HPG_WINTV_PAL_D_K_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTV USB (PAL D/K FM)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTV USB (PAL D/K FM)",
},
[HPG_WINTV_PRO_NTSC_MN] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_MICROTUNE_4049FM5,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_MICROTUNE_4049FM5,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (NTSC M/N)",
},
[HPG_WINTV_PRO_NTSC_MN_V2] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_MICROTUNE_4049FM5,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_MICROTUNE_4049FM5,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
},
[HPG_WINTV_PRO_PAL] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
},
[HPG_WINTV_PRO_NTSC_MN_V3] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
},
[HPG_WINTV_PRO_PAL_BG] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL B/G)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL B/G)",
},
[HPG_WINTV_PRO_PAL_I] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL I)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL I)",
},
[HPG_WINTV_PRO_PAL_SECAM_L] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_SECAM,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
},
[HPG_WINTV_PRO_PAL_D_K] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL D/K)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL D/K)",
},
[HPG_WINTV_PRO_PAL_SECAM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_SECAM,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
},
[HPG_WINTV_PRO_PAL_SECAM_V2] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_SECAM,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
},
[HPG_WINTV_PRO_PAL_BG_V2] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_ALPS_TSBE1_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL B/G) V2",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_ALPS_TSBE1_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL B/G) V2",
},
[HPG_WINTV_PRO_PAL_BG_D_K] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_ALPS_TSBE1_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_ALPS_TSBE1_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
},
[HPG_WINTV_PRO_PAL_I_D_K] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_LG_PAL_NEW_TAPC,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL I,D/K)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL I,D/K)",
},
[HPG_WINTV_PRO_NTSC_MN_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
},
[HPG_WINTV_PRO_PAL_BG_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL B/G FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL B/G FM)",
},
[HPG_WINTV_PRO_PAL_I_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL I FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL I FM)",
},
[HPG_WINTV_PRO_PAL_D_K_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL D/K FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL D/K FM)",
},
[HPG_WINTV_PRO_TEMIC_PAL_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_MICROTUNE_4049FM5,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_MICROTUNE_4049FM5,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
},
[HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_MICROTUNE_4049FM5,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_MICROTUNE_4049FM5,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
},
[HPG_WINTV_PRO_PAL_FM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
},
[HPG_WINTV_PRO_NTSC_MN_FM_V2] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
},
[CAMTEL_TVB330] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = 5,
- .Y_Offset = 5,
- .ModelString = "Camtel Technology USB TV Genie Pro FM Model TVB330",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = 5,
+ .y_offset = 5,
+ .model_string = "Camtel Technology USB TV Genie Pro FM Model TVB330",
},
[DIGITAL_VIDEO_CREATOR_I] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Digital Video Creator I",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Digital Video Creator I",
},
[GLOBAL_VILLAGE_GV_007_NTSC] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 82,
- .Y_Offset = 20,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Global Village GV-007 (NTSC)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 82,
+ .y_offset = 20,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Global Village GV-007 (NTSC)",
},
[DAZZLE_DVC_50_REV_1_NTSC] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
},
[DAZZLE_DVC_80_REV_1_PAL] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
},
[DAZZLE_DVC_90_REV_1_SECAM] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 0,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 0,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
},
[ESKAPE_LABS_MYTV2GO] = {
- .Interface = 0,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Eskape Labs MyTV2Go",
+ .interface = 0,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Eskape Labs MyTV2Go",
},
[PINNA_PCTV_USB_PAL] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 0,
- .Tuner = 1,
- .TunerType = TUNER_TEMIC_4066FY5_PAL_I,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Pinnacle Studio PCTV USB (PAL)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 0,
+ .tuner = 1,
+ .tuner_type = TUNER_TEMIC_4066FY5_PAL_I,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Pinnacle Studio PCTV USB (PAL)",
},
[PINNA_PCTV_USB_SECAM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_SECAM,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_SECAM,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Pinnacle Studio PCTV USB (SECAM)",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_SECAM,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Pinnacle Studio PCTV USB (SECAM)",
},
[PINNA_PCTV_USB_PAL_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = 128,
- .Y_Offset = 23,
- .ModelString = "Pinnacle Studio PCTV USB (PAL) FM",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = 128,
+ .y_offset = 23,
+ .model_string = "Pinnacle Studio PCTV USB (PAL) FM",
},
[MIRO_PCTV_USB] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_PAL,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Miro PCTV USB",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Miro PCTV USB",
},
[PINNA_PCTV_USB_NTSC_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Pinnacle Studio PCTV USB (NTSC) FM",
},
[PINNA_PCTV_USB_NTSC_FM_V3] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V3",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V3",
},
[PINNA_PCTV_USB_PAL_FM_V2] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_TEMIC_4009FR5_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V2",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_TEMIC_4009FR5_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle Studio PCTV USB (PAL) FM V2",
},
[PINNA_PCTV_USB_NTSC_FM_V2] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_TEMIC_4039FR5_NTSC,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V2",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_TEMIC_4039FR5_NTSC,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V2",
},
[PINNA_PCTV_USB_PAL_FM_V3] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_TEMIC_4009FR5_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V3",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_TEMIC_4009FR5_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle Studio PCTV USB (PAL) FM V3",
},
[PINNA_LINX_VD_IN_CAB_NTSC] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle Studio Linx Video input cable (NTSC)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle Studio Linx Video input cable (NTSC)",
},
[PINNA_LINX_VD_IN_CAB_PAL] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 2,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 0,
- .TunerType = 0,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle Studio Linx Video input cable (PAL)",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 2,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 0,
+ .tuner_type = 0,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle Studio Linx Video input cable (PAL)",
},
[PINNA_PCTV_BUNGEE_PAL_FM] = {
- .Interface = -1,
- .Codec = CODEC_SAA7113,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_PAL,
- .AudioChannels = 1,
- .Radio = 1,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_TEMIC_4009FR5_PAL,
- .X_Offset = 0,
- .Y_Offset = 3,
- .Dvi_yuv_override = 1,
- .Dvi_yuv = 7,
- .ModelString = "Pinnacle PCTV Bungee USB (PAL) FM",
+ .interface = -1,
+ .codec = CODEC_SAA7113,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_PAL,
+ .audio_channels = 1,
+ .radio = 1,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_TEMIC_4009FR5_PAL,
+ .x_offset = 0,
+ .y_offset = 3,
+ .dvi_yuv_override = 1,
+ .dvi_yuv = 7,
+ .model_string = "Pinnacle PCTV Bungee USB (PAL) FM",
},
[HPG_WINTV] = {
- .Interface = -1,
- .Codec = CODEC_SAA7111,
- .VideoChannels = 3,
- .VideoNorm = V4L2_STD_NTSC,
- .AudioChannels = 1,
- .Radio = 0,
- .vbi = 1,
- .Tuner = 1,
- .TunerType = TUNER_PHILIPS_NTSC_M,
- .X_Offset = -1,
- .Y_Offset = -1,
- .ModelString = "Hauppauge WinTv-USB",
+ .interface = -1,
+ .codec = CODEC_SAA7111,
+ .video_channels = 3,
+ .video_norm = V4L2_STD_NTSC,
+ .audio_channels = 1,
+ .radio = 0,
+ .vbi = 1,
+ .tuner = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .x_offset = -1,
+ .y_offset = -1,
+ .model_string = "Hauppauge WinTv-USB",
},
};
-const int usbvision_device_data_size=ARRAY_SIZE(usbvision_device_data);
+const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
/* Supported Devices */
-struct usb_device_id usbvision_table [] = {
- { USB_DEVICE(0x0a6f, 0x0400), .driver_info=XANBOO },
- { USB_DEVICE(0x050d, 0x0106), .driver_info=BELKIN_VIDEOBUS_II },
- { USB_DEVICE(0x050d, 0x0207), .driver_info=BELKIN_VIDEOBUS },
- { USB_DEVICE(0x050d, 0x0208), .driver_info=BELKIN_USB_VIDEOBUS_II },
- { USB_DEVICE(0x0571, 0x0002), .driver_info=ECHOFX_INTERVIEW_LITE },
- { USB_DEVICE(0x0573, 0x0003), .driver_info=USBGEAR_USBG_V1 },
- { USB_DEVICE(0x0573, 0x0400), .driver_info=D_LINK_V100 },
- { USB_DEVICE(0x0573, 0x2000), .driver_info=X10_USB_CAMERA },
- { USB_DEVICE(0x0573, 0x2d00), .driver_info=HPG_WINTV_LIVE_PAL_BG },
- { USB_DEVICE(0x0573, 0x2d01), .driver_info=HPG_WINTV_LIVE_PRO_NTSC_MN },
- { USB_DEVICE(0x0573, 0x2101), .driver_info=ZORAN_PMD_NOGATECH },
- { USB_DEVICE(0x0573, 0x4100), .driver_info=NOGATECH_USB_TV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4110), .driver_info=PNY_USB_TV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4450), .driver_info=PV_PLAYTV_USB_PRO_PAL_FM },
- { USB_DEVICE(0x0573, 0x4550), .driver_info=ZT_721 },
- { USB_DEVICE(0x0573, 0x4d00), .driver_info=HPG_WINTV_NTSC_MN },
- { USB_DEVICE(0x0573, 0x4d01), .driver_info=HPG_WINTV_PAL_BG },
- { USB_DEVICE(0x0573, 0x4d02), .driver_info=HPG_WINTV_PAL_I },
- { USB_DEVICE(0x0573, 0x4d03), .driver_info=HPG_WINTV_PAL_SECAM_L },
- { USB_DEVICE(0x0573, 0x4d04), .driver_info=HPG_WINTV_PAL_D_K },
- { USB_DEVICE(0x0573, 0x4d10), .driver_info=HPG_WINTV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4d11), .driver_info=HPG_WINTV_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d12), .driver_info=HPG_WINTV_PAL_I_FM },
- { USB_DEVICE(0x0573, 0x4d14), .driver_info=HPG_WINTV_PAL_D_K_FM },
- { USB_DEVICE(0x0573, 0x4d2a), .driver_info=HPG_WINTV_PRO_NTSC_MN },
- { USB_DEVICE(0x0573, 0x4d2b), .driver_info=HPG_WINTV_PRO_NTSC_MN_V2 },
- { USB_DEVICE(0x0573, 0x4d2c), .driver_info=HPG_WINTV_PRO_PAL },
+struct usb_device_id usbvision_table[] = {
+ { USB_DEVICE(0x0a6f, 0x0400), .driver_info = XANBOO },
+ { USB_DEVICE(0x050d, 0x0106), .driver_info = BELKIN_VIDEOBUS_II },
+ { USB_DEVICE(0x050d, 0x0207), .driver_info = BELKIN_VIDEOBUS },
+ { USB_DEVICE(0x050d, 0x0208), .driver_info = BELKIN_USB_VIDEOBUS_II },
+ { USB_DEVICE(0x0571, 0x0002), .driver_info = ECHOFX_INTERVIEW_LITE },
+ { USB_DEVICE(0x0573, 0x0003), .driver_info = USBGEAR_USBG_V1 },
+ { USB_DEVICE(0x0573, 0x0400), .driver_info = D_LINK_V100 },
+ { USB_DEVICE(0x0573, 0x2000), .driver_info = X10_USB_CAMERA },
+ { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
+ { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
+ { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4550), .driver_info = ZT_721 },
+ { USB_DEVICE(0x0573, 0x4d00), .driver_info = HPG_WINTV_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d01), .driver_info = HPG_WINTV_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d02), .driver_info = HPG_WINTV_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d03), .driver_info = HPG_WINTV_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d04), .driver_info = HPG_WINTV_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d10), .driver_info = HPG_WINTV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4d11), .driver_info = HPG_WINTV_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d12), .driver_info = HPG_WINTV_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d14), .driver_info = HPG_WINTV_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d2a), .driver_info = HPG_WINTV_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d2b), .driver_info = HPG_WINTV_PRO_NTSC_MN_V2 },
+ { USB_DEVICE(0x0573, 0x4d2c), .driver_info = HPG_WINTV_PRO_PAL },
{ USB_DEVICE(0x0573, 0x4d20), .driver_info = HPG_WINTV_PRO_NTSC_MN_V3 },
- { USB_DEVICE(0x0573, 0x4d21), .driver_info=HPG_WINTV_PRO_PAL_BG },
- { USB_DEVICE(0x0573, 0x4d22), .driver_info=HPG_WINTV_PRO_PAL_I },
- { USB_DEVICE(0x0573, 0x4d23), .driver_info=HPG_WINTV_PRO_PAL_SECAM_L },
- { USB_DEVICE(0x0573, 0x4d24), .driver_info=HPG_WINTV_PRO_PAL_D_K },
- { USB_DEVICE(0x0573, 0x4d25), .driver_info=HPG_WINTV_PRO_PAL_SECAM },
- { USB_DEVICE(0x0573, 0x4d26), .driver_info=HPG_WINTV_PRO_PAL_SECAM_V2 },
- { USB_DEVICE(0x0573, 0x4d27), .driver_info=HPG_WINTV_PRO_PAL_BG_V2 },
- { USB_DEVICE(0x0573, 0x4d28), .driver_info=HPG_WINTV_PRO_PAL_BG_D_K },
- { USB_DEVICE(0x0573, 0x4d29), .driver_info=HPG_WINTV_PRO_PAL_I_D_K },
- { USB_DEVICE(0x0573, 0x4d30), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM },
- { USB_DEVICE(0x0573, 0x4d31), .driver_info=HPG_WINTV_PRO_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d32), .driver_info=HPG_WINTV_PRO_PAL_I_FM },
- { USB_DEVICE(0x0573, 0x4d34), .driver_info=HPG_WINTV_PRO_PAL_D_K_FM },
- { USB_DEVICE(0x0573, 0x4d35), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_FM },
- { USB_DEVICE(0x0573, 0x4d36), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d37), .driver_info=HPG_WINTV_PRO_PAL_FM },
- { USB_DEVICE(0x0573, 0x4d38), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM_V2 },
- { USB_DEVICE(0x0768, 0x0006), .driver_info=CAMTEL_TVB330 },
- { USB_DEVICE(0x07d0, 0x0001), .driver_info=DIGITAL_VIDEO_CREATOR_I },
- { USB_DEVICE(0x07d0, 0x0002), .driver_info=GLOBAL_VILLAGE_GV_007_NTSC },
- { USB_DEVICE(0x07d0, 0x0003), .driver_info=DAZZLE_DVC_50_REV_1_NTSC },
- { USB_DEVICE(0x07d0, 0x0004), .driver_info=DAZZLE_DVC_80_REV_1_PAL },
- { USB_DEVICE(0x07d0, 0x0005), .driver_info=DAZZLE_DVC_90_REV_1_SECAM },
- { USB_DEVICE(0x07f8, 0x9104), .driver_info=ESKAPE_LABS_MYTV2GO },
- { USB_DEVICE(0x2304, 0x010d), .driver_info=PINNA_PCTV_USB_PAL },
- { USB_DEVICE(0x2304, 0x0109), .driver_info=PINNA_PCTV_USB_SECAM },
- { USB_DEVICE(0x2304, 0x0110), .driver_info=PINNA_PCTV_USB_PAL_FM },
- { USB_DEVICE(0x2304, 0x0111), .driver_info=MIRO_PCTV_USB },
- { USB_DEVICE(0x2304, 0x0112), .driver_info=PINNA_PCTV_USB_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4d21), .driver_info = HPG_WINTV_PRO_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d22), .driver_info = HPG_WINTV_PRO_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d23), .driver_info = HPG_WINTV_PRO_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d24), .driver_info = HPG_WINTV_PRO_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d25), .driver_info = HPG_WINTV_PRO_PAL_SECAM },
+ { USB_DEVICE(0x0573, 0x4d26), .driver_info = HPG_WINTV_PRO_PAL_SECAM_V2 },
+ { USB_DEVICE(0x0573, 0x4d27), .driver_info = HPG_WINTV_PRO_PAL_BG_V2 },
+ { USB_DEVICE(0x0573, 0x4d28), .driver_info = HPG_WINTV_PRO_PAL_BG_D_K },
+ { USB_DEVICE(0x0573, 0x4d29), .driver_info = HPG_WINTV_PRO_PAL_I_D_K },
+ { USB_DEVICE(0x0573, 0x4d30), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM },
+ { USB_DEVICE(0x0573, 0x4d31), .driver_info = HPG_WINTV_PRO_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d32), .driver_info = HPG_WINTV_PRO_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d34), .driver_info = HPG_WINTV_PRO_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d35), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d36), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d37), .driver_info = HPG_WINTV_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d38), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM_V2 },
+ { USB_DEVICE(0x0768, 0x0006), .driver_info = CAMTEL_TVB330 },
+ { USB_DEVICE(0x07d0, 0x0001), .driver_info = DIGITAL_VIDEO_CREATOR_I },
+ { USB_DEVICE(0x07d0, 0x0002), .driver_info = GLOBAL_VILLAGE_GV_007_NTSC },
+ { USB_DEVICE(0x07d0, 0x0003), .driver_info = DAZZLE_DVC_50_REV_1_NTSC },
+ { USB_DEVICE(0x07d0, 0x0004), .driver_info = DAZZLE_DVC_80_REV_1_PAL },
+ { USB_DEVICE(0x07d0, 0x0005), .driver_info = DAZZLE_DVC_90_REV_1_SECAM },
+ { USB_DEVICE(0x07f8, 0x9104), .driver_info = ESKAPE_LABS_MYTV2GO },
+ { USB_DEVICE(0x2304, 0x010d), .driver_info = PINNA_PCTV_USB_PAL },
+ { USB_DEVICE(0x2304, 0x0109), .driver_info = PINNA_PCTV_USB_SECAM },
+ { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
+ { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
+ { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
{ USB_DEVICE(0x2304, 0x0113),
.driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
- { USB_DEVICE(0x2304, 0x0210), .driver_info=PINNA_PCTV_USB_PAL_FM_V2 },
- { USB_DEVICE(0x2304, 0x0212), .driver_info=PINNA_PCTV_USB_NTSC_FM_V2 },
- { USB_DEVICE(0x2304, 0x0214), .driver_info=PINNA_PCTV_USB_PAL_FM_V3 },
- { USB_DEVICE(0x2304, 0x0300), .driver_info=PINNA_LINX_VD_IN_CAB_NTSC },
- { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
- { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
- { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
+ { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
+ { USB_DEVICE(0x2304, 0x0300), .driver_info = PINNA_LINX_VD_IN_CAB_NTSC },
+ { USB_DEVICE(0x2304, 0x0301), .driver_info = PINNA_LINX_VD_IN_CAB_PAL },
+ { USB_DEVICE(0x2304, 0x0419), .driver_info = PINNA_PCTV_BUNGEE_PAL_FM },
+ { USB_DEVICE(0x2400, 0x4200), .driver_info = HPG_WINTV },
{ }, /* terminate list */
};
-MODULE_DEVICE_TABLE (usb, usbvision_table);
+MODULE_DEVICE_TABLE(usb, usbvision_table);
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index b9dd74fde212..c8feb0d6fccf 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -33,7 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
@@ -46,30 +46,30 @@
#include "usbvision.h"
static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
static unsigned int force_testpattern;
-module_param(force_testpattern,int,0644);
-MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]");
+module_param(force_testpattern, int, 0644);
+MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]");
-static int adjustCompression = 1; /* Set the compression to be adaptive */
-module_param(adjustCompression, int, 0444);
-MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)");
+static int adjust_compression = 1; /* Set the compression to be adaptive */
+module_param(adjust_compression, int, 0444);
+MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)");
/* To help people with Black and White output with using s-video input.
* Some cables and input device are wired differently. */
-static int SwitchSVideoInput;
-module_param(SwitchSVideoInput, int, 0444);
-MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)");
+static int switch_svideo_input;
+module_param(switch_svideo_input, int, 0444);
+MODULE_PARM_DESC(switch_svideo_input, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)");
-static unsigned int adjust_X_Offset = -1;
-module_param(adjust_X_Offset, int, 0644);
-MODULE_PARM_DESC(adjust_X_Offset, "adjust X offset display [core]");
+static unsigned int adjust_x_offset = -1;
+module_param(adjust_x_offset, int, 0644);
+MODULE_PARM_DESC(adjust_x_offset, "adjust X offset display [core]");
-static unsigned int adjust_Y_Offset = -1;
-module_param(adjust_Y_Offset, int, 0644);
-MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]");
+static unsigned int adjust_y_offset = -1;
+module_param(adjust_y_offset, int, 0644);
+MODULE_PARM_DESC(adjust_y_offset, "adjust Y offset display [core]");
#define ENABLE_HEXDUMP 0 /* Enable if you need it */
@@ -82,15 +82,15 @@ MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]");
__func__, __LINE__ , ## args); \
}
#else
- #define PDEBUG(level, fmt, args...) do {} while(0)
+ #define PDEBUG(level, fmt, args...) do {} while (0)
#endif
-#define DBG_HEADER 1<<0
-#define DBG_IRQ 1<<1
-#define DBG_ISOC 1<<2
-#define DBG_PARSE 1<<3
-#define DBG_SCRATCH 1<<4
-#define DBG_FUNC 1<<5
+#define DBG_HEADER (1 << 0)
+#define DBG_IRQ (1 << 1)
+#define DBG_ISOC (1 << 2)
+#define DBG_PARSE (1 << 3)
+#define DBG_SCRATCH (1 << 4)
+#define DBG_FUNC (1 << 5)
static const int max_imgwidth = MAX_FRAME_WIDTH;
static const int max_imgheight = MAX_FRAME_HEIGHT;
@@ -103,14 +103,14 @@ static const int min_imgheight = MIN_FRAME_HEIGHT;
* to work with. This setting can be adjusted, but the default value
* should be OK for most desktop users.
*/
-#define DEFAULT_SCRATCH_BUF_SIZE (0x20000) // 128kB memory scratch buffer
+#define DEFAULT_SCRATCH_BUF_SIZE (0x20000) /* 128kB memory scratch buffer */
static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE;
-// Function prototypes
-static int usbvision_request_intra (struct usb_usbvision *usbvision);
-static int usbvision_unrequest_intra (struct usb_usbvision *usbvision);
-static int usbvision_adjust_compression (struct usb_usbvision *usbvision);
-static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);
+/* Function prototypes */
+static int usbvision_request_intra(struct usb_usbvision *usbvision);
+static int usbvision_unrequest_intra(struct usb_usbvision *usbvision);
+static int usbvision_adjust_compression(struct usb_usbvision *usbvision);
+static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision);
/*******************************/
/* Memory management functions */
@@ -176,19 +176,19 @@ static void usbvision_hexdump(const unsigned char *data, int len)
k += sprintf(&tmp[k], "%02x ", data[i]);
}
if (k > 0)
- printk("%s\n", tmp);
+ printk(KERN_CONT "%s\n", tmp);
}
#endif
/********************************
* scratch ring buffer handling
********************************/
-static int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */
+static int scratch_len(struct usb_usbvision *usbvision) /* This returns the amount of data actually in the buffer */
{
int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
- if (len < 0) {
+
+ if (len < 0)
len += scratch_buf_size;
- }
PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len);
return len;
@@ -199,9 +199,8 @@ static int scratch_len(struct usb_usbvision *usbvision) /*This returns the am
static int scratch_free(struct usb_usbvision *usbvision)
{
int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr;
- if (free <= 0) {
+ if (free <= 0)
free += scratch_buf_size;
- }
if (free) {
free -= 1; /* at least one byte in the buffer must */
/* left blank, otherwise there is no chance to differ between full and empty */
@@ -221,14 +220,12 @@ static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data,
if (usbvision->scratch_write_ptr + len < scratch_buf_size) {
memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len);
usbvision->scratch_write_ptr += len;
- }
- else {
+ } else {
len_part = scratch_buf_size - usbvision->scratch_write_ptr;
memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part);
if (len == len_part) {
usbvision->scratch_write_ptr = 0; /* just set write_ptr to zero */
- }
- else {
+ } else {
memcpy(usbvision->scratch, data + len_part, len - len_part);
usbvision->scratch_write_ptr = len - len_part;
}
@@ -255,17 +252,16 @@ static int scratch_get_extra(struct usb_usbvision *usbvision,
unsigned char *data, int *ptr, int len)
{
int len_part;
+
if (*ptr + len < scratch_buf_size) {
memcpy(data, usbvision->scratch + *ptr, len);
*ptr += len;
- }
- else {
+ } else {
len_part = scratch_buf_size - *ptr;
memcpy(data, usbvision->scratch + *ptr, len_part);
if (len == len_part) {
*ptr = 0; /* just set the y_ptr to zero */
- }
- else {
+ } else {
memcpy(data + len_part, usbvision->scratch, len - len_part);
*ptr = len - len_part;
}
@@ -281,13 +277,13 @@ static int scratch_get_extra(struct usb_usbvision *usbvision,
static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr,
int len)
{
- *ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size;
+ *ptr = (usbvision->scratch_read_ptr + len) % scratch_buf_size;
PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
}
-/*This increments the scratch extra read pointer */
+/* This increments the scratch extra read pointer */
static void scratch_inc_extra_ptr(int *ptr, int len)
{
*ptr = (*ptr + len) % scratch_buf_size;
@@ -301,17 +297,16 @@ static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
int len)
{
int len_part;
+
if (usbvision->scratch_read_ptr + len < scratch_buf_size) {
memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len);
usbvision->scratch_read_ptr += len;
- }
- else {
+ } else {
len_part = scratch_buf_size - usbvision->scratch_read_ptr;
memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part);
if (len == len_part) {
usbvision->scratch_read_ptr = 0; /* just set the read_ptr to zero */
- }
- else {
+ } else {
memcpy(data + len_part, usbvision->scratch, len - len_part);
usbvision->scratch_read_ptr = len - len_part;
}
@@ -327,7 +322,7 @@ static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
static int scratch_get_header(struct usb_usbvision *usbvision,
struct usbvision_frame_header *header)
{
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr);
@@ -340,29 +335,28 @@ static int scratch_get_header(struct usb_usbvision *usbvision,
scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH);
if ((header->magic_1 == USBVISION_MAGIC_1)
&& (header->magic_2 == USBVISION_MAGIC_2)
- && (header->headerLength == USBVISION_HEADER_LENGTH)) {
- errCode = USBVISION_HEADER_LENGTH;
- header->frameWidth = header->frameWidthLo + (header->frameWidthHi << 8);
- header->frameHeight = header->frameHeightLo + (header->frameHeightHi << 8);
+ && (header->header_length == USBVISION_HEADER_LENGTH)) {
+ err_code = USBVISION_HEADER_LENGTH;
+ header->frame_width = header->frame_width_lo + (header->frame_width_hi << 8);
+ header->frame_height = header->frame_height_lo + (header->frame_height_hi << 8);
break;
}
}
- return errCode;
+ return err_code;
}
-/*This removes len bytes of old data from the buffer */
+/* This removes len bytes of old data from the buffer */
static void scratch_rm_old(struct usb_usbvision *usbvision, int len)
{
-
usbvision->scratch_read_ptr += len;
usbvision->scratch_read_ptr %= scratch_buf_size;
PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr);
}
-/*This resets the buffer - kills all data in it too */
+/* This resets the buffer - kills all data in it too */
static void scratch_reset(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_SCRATCH, "\n");
@@ -371,14 +365,14 @@ static void scratch_reset(struct usb_usbvision *usbvision)
usbvision->scratch_write_ptr = 0;
usbvision->scratch_headermarker_read_ptr = 0;
usbvision->scratch_headermarker_write_ptr = 0;
- usbvision->isocstate = IsocState_NoFrame;
+ usbvision->isocstate = isoc_state_no_frame;
}
int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
{
usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
- if(usbvision->scratch == NULL) {
+ if (usbvision->scratch == NULL) {
dev_err(&usbvision->dev->dev,
"%s: unable to allocate %d bytes for scratch\n",
__func__, scratch_buf_size);
@@ -391,7 +385,6 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision)
{
vfree(usbvision->scratch);
usbvision->scratch = NULL;
-
}
/*
@@ -420,13 +413,13 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision,
printk(KERN_ERR "%s: usbvision == NULL\n", proc);
return;
}
- if (usbvision->curFrame == NULL) {
- printk(KERN_ERR "%s: usbvision->curFrame is NULL.\n", proc);
+ if (usbvision->cur_frame == NULL) {
+ printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
return;
}
/* Grab the current frame */
- frame = usbvision->curFrame;
+ frame = usbvision->cur_frame;
/* Optionally start at the beginning */
if (fullframe) {
@@ -473,10 +466,9 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision,
}
}
- frame->grabstate = FrameState_Done;
+ frame->grabstate = frame_state_done;
frame->scanlength += scan_length;
++num_pass;
-
}
/*
@@ -487,8 +479,9 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision,
int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
{
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
- usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
- if (usbvision->IntraFrameBuffer == NULL) {
+
+ usbvision->intra_frame_buffer = vmalloc_32(IFB_size);
+ if (usbvision->intra_frame_buffer == NULL) {
dev_err(&usbvision->dev->dev,
"%s: unable to allocate %d for compr. frame buffer\n",
__func__, IFB_size);
@@ -504,8 +497,8 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
*/
void usbvision_decompress_free(struct usb_usbvision *usbvision)
{
- vfree(usbvision->IntraFrameBuffer);
- usbvision->IntraFrameBuffer = NULL;
+ vfree(usbvision->intra_frame_buffer);
+ usbvision->intra_frame_buffer = NULL;
}
@@ -517,117 +510,111 @@ void usbvision_decompress_free(struct usb_usbvision *usbvision)
*
* Locate one of supported header markers in the scratch buffer.
*/
-static enum ParseState usbvision_find_header(struct usb_usbvision *usbvision)
+static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
{
struct usbvision_frame *frame;
- int foundHeader = 0;
+ int found_header = 0;
- frame = usbvision->curFrame;
+ frame = usbvision->cur_frame;
- while (scratch_get_header(usbvision, &frame->isocHeader) == USBVISION_HEADER_LENGTH) {
- // found header in scratch
+ while (scratch_get_header(usbvision, &frame->isoc_header) == USBVISION_HEADER_LENGTH) {
+ /* found header in scratch */
PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u",
- frame->isocHeader.magic_2,
- frame->isocHeader.magic_1,
- frame->isocHeader.headerLength,
- frame->isocHeader.frameNum,
- frame->isocHeader.framePhase,
- frame->isocHeader.frameLatency,
- frame->isocHeader.dataFormat,
- frame->isocHeader.formatParam,
- frame->isocHeader.frameWidth,
- frame->isocHeader.frameHeight);
-
- if (usbvision->requestIntra) {
- if (frame->isocHeader.formatParam & 0x80) {
- foundHeader = 1;
- usbvision->lastIsocFrameNum = -1; // do not check for lost frames this time
+ frame->isoc_header.magic_2,
+ frame->isoc_header.magic_1,
+ frame->isoc_header.header_length,
+ frame->isoc_header.frame_num,
+ frame->isoc_header.frame_phase,
+ frame->isoc_header.frame_latency,
+ frame->isoc_header.data_format,
+ frame->isoc_header.format_param,
+ frame->isoc_header.frame_width,
+ frame->isoc_header.frame_height);
+
+ if (usbvision->request_intra) {
+ if (frame->isoc_header.format_param & 0x80) {
+ found_header = 1;
+ usbvision->last_isoc_frame_num = -1; /* do not check for lost frames this time */
usbvision_unrequest_intra(usbvision);
break;
}
- }
- else {
- foundHeader = 1;
+ } else {
+ found_header = 1;
break;
}
}
- if (foundHeader) {
- frame->frmwidth = frame->isocHeader.frameWidth * usbvision->stretch_width;
- frame->frmheight = frame->isocHeader.frameHeight * usbvision->stretch_height;
- frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth)>> 3;
- }
- else { // no header found
+ if (found_header) {
+ frame->frmwidth = frame->isoc_header.frame_width * usbvision->stretch_width;
+ frame->frmheight = frame->isoc_header.frame_height * usbvision->stretch_height;
+ frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth) >> 3;
+ } else { /* no header found */
PDEBUG(DBG_HEADER, "skipping scratch data, no header");
scratch_reset(usbvision);
- return ParseState_EndParse;
+ return parse_state_end_parse;
}
- // found header
- if (frame->isocHeader.dataFormat==ISOC_MODE_COMPRESS) {
- //check isocHeader.frameNum for lost frames
- if (usbvision->lastIsocFrameNum >= 0) {
- if (((usbvision->lastIsocFrameNum + 1) % 32) != frame->isocHeader.frameNum) {
- // unexpected frame drop: need to request new intra frame
- PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isocHeader.frameNum);
+ /* found header */
+ if (frame->isoc_header.data_format == ISOC_MODE_COMPRESS) {
+ /* check isoc_header.frame_num for lost frames */
+ if (usbvision->last_isoc_frame_num >= 0) {
+ if (((usbvision->last_isoc_frame_num + 1) % 32) != frame->isoc_header.frame_num) {
+ /* unexpected frame drop: need to request new intra frame */
+ PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isoc_header.frame_num);
usbvision_request_intra(usbvision);
- return ParseState_NextFrame;
+ return parse_state_next_frame;
}
}
- usbvision->lastIsocFrameNum = frame->isocHeader.frameNum;
+ usbvision->last_isoc_frame_num = frame->isoc_header.frame_num;
}
usbvision->header_count++;
- frame->scanstate = ScanState_Lines;
+ frame->scanstate = scan_state_lines;
frame->curline = 0;
if (force_testpattern) {
usbvision_testpattern(usbvision, 1, 1);
- return ParseState_NextFrame;
+ return parse_state_next_frame;
}
- return ParseState_Continue;
+ return parse_state_continue;
}
-static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision,
+static enum parse_state usbvision_parse_lines_422(struct usb_usbvision *usbvision,
long *pcopylen)
{
volatile struct usbvision_frame *frame;
unsigned char *f;
int len;
int i;
- unsigned char yuyv[4]={180, 128, 10, 128}; // YUV components
- unsigned char rv, gv, bv; // RGB components
+ unsigned char yuyv[4] = { 180, 128, 10, 128 }; /* YUV components */
+ unsigned char rv, gv, bv; /* RGB components */
int clipmask_index, bytes_per_pixel;
int stretch_bytes, clipmask_add;
- frame = usbvision->curFrame;
+ frame = usbvision->cur_frame;
f = frame->data + (frame->v4l2_linesize * frame->curline);
/* Make sure there's enough data for the entire line */
- len = (frame->isocHeader.frameWidth * 2)+5;
+ len = (frame->isoc_header.frame_width * 2) + 5;
if (scratch_len(usbvision) < len) {
PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len);
- return ParseState_Out;
+ return parse_state_out;
}
- if ((frame->curline + 1) >= frame->frmheight) {
- return ParseState_NextFrame;
- }
+ if ((frame->curline + 1) >= frame->frmheight)
+ return parse_state_next_frame;
bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
clipmask_index = frame->curline * MAX_FRAME_WIDTH;
clipmask_add = usbvision->stretch_width;
- for (i = 0; i < frame->frmwidth; i+=(2 * usbvision->stretch_width)) {
-
+ for (i = 0; i < frame->frmwidth; i += (2 * usbvision->stretch_width)) {
scratch_get(usbvision, &yuyv[0], 4);
if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = yuyv[0]; // Y
- *f++ = yuyv[3]; // U
- }
- else {
-
+ *f++ = yuyv[0]; /* Y */
+ *f++ = yuyv[3]; /* U */
+ } else {
YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);
switch (frame->v4l2_format.format) {
case V4L2_PIX_FMT_RGB565:
@@ -659,11 +646,9 @@ static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision
f += stretch_bytes;
if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = yuyv[2]; // Y
- *f++ = yuyv[1]; // V
- }
- else {
-
+ *f++ = yuyv[2]; /* Y */
+ *f++ = yuyv[1]; /* V */
+ } else {
YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);
switch (frame->v4l2_format.format) {
case V4L2_PIX_FMT_RGB565:
@@ -698,100 +683,94 @@ static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision
frame->curline += usbvision->stretch_height;
*pcopylen += frame->v4l2_linesize * usbvision->stretch_height;
- if (frame->curline >= frame->frmheight) {
- return ParseState_NextFrame;
- }
- else {
- return ParseState_Continue;
- }
+ if (frame->curline >= frame->frmheight)
+ return parse_state_next_frame;
+ return parse_state_continue;
}
/* The decompression routine */
-static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *Compressed,
- unsigned char *Decompressed, int *StartPos,
- int *BlockTypeStartPos, int Len)
+static int usbvision_decompress(struct usb_usbvision *usbvision, unsigned char *compressed,
+ unsigned char *decompressed, int *start_pos,
+ int *block_typestart_pos, int len)
{
- int RestPixel, Idx, MaxPos, Pos, ExtraPos, BlockLen, BlockTypePos, BlockTypeLen;
- unsigned char BlockByte, BlockCode, BlockType, BlockTypeByte, Integrator;
-
- Integrator = 0;
- Pos = *StartPos;
- BlockTypePos = *BlockTypeStartPos;
- MaxPos = 396; //Pos + Len;
- ExtraPos = Pos;
- BlockLen = 0;
- BlockByte = 0;
- BlockCode = 0;
- BlockType = 0;
- BlockTypeByte = 0;
- BlockTypeLen = 0;
- RestPixel = Len;
-
- for (Idx = 0; Idx < Len; Idx++) {
-
- if (BlockLen == 0) {
- if (BlockTypeLen==0) {
- BlockTypeByte = Compressed[BlockTypePos];
- BlockTypePos++;
- BlockTypeLen = 4;
+ int rest_pixel, idx, max_pos, pos, extra_pos, block_len, block_type_pos, block_type_len;
+ unsigned char block_byte, block_code, block_type, block_type_byte, integrator;
+
+ integrator = 0;
+ pos = *start_pos;
+ block_type_pos = *block_typestart_pos;
+ max_pos = 396; /* pos + len; */
+ extra_pos = pos;
+ block_len = 0;
+ block_byte = 0;
+ block_code = 0;
+ block_type = 0;
+ block_type_byte = 0;
+ block_type_len = 0;
+ rest_pixel = len;
+
+ for (idx = 0; idx < len; idx++) {
+ if (block_len == 0) {
+ if (block_type_len == 0) {
+ block_type_byte = compressed[block_type_pos];
+ block_type_pos++;
+ block_type_len = 4;
}
- BlockType = (BlockTypeByte & 0xC0) >> 6;
+ block_type = (block_type_byte & 0xC0) >> 6;
- //statistic:
- usbvision->ComprBlockTypes[BlockType]++;
+ /* statistic: */
+ usbvision->compr_block_types[block_type]++;
- Pos = ExtraPos;
- if (BlockType == 0) {
- if(RestPixel >= 24) {
- Idx += 23;
- RestPixel -= 24;
- Integrator = Decompressed[Idx];
+ pos = extra_pos;
+ if (block_type == 0) {
+ if (rest_pixel >= 24) {
+ idx += 23;
+ rest_pixel -= 24;
+ integrator = decompressed[idx];
} else {
- Idx += RestPixel - 1;
- RestPixel = 0;
+ idx += rest_pixel - 1;
+ rest_pixel = 0;
}
} else {
- BlockCode = Compressed[Pos];
- Pos++;
- if (RestPixel >= 24) {
- BlockLen = 24;
- } else {
- BlockLen = RestPixel;
- }
- RestPixel -= BlockLen;
- ExtraPos = Pos + (BlockLen / 4);
+ block_code = compressed[pos];
+ pos++;
+ if (rest_pixel >= 24)
+ block_len = 24;
+ else
+ block_len = rest_pixel;
+ rest_pixel -= block_len;
+ extra_pos = pos + (block_len / 4);
}
- BlockTypeByte <<= 2;
- BlockTypeLen -= 1;
+ block_type_byte <<= 2;
+ block_type_len -= 1;
}
- if (BlockLen > 0) {
- if ((BlockLen%4) == 0) {
- BlockByte = Compressed[Pos];
- Pos++;
+ if (block_len > 0) {
+ if ((block_len % 4) == 0) {
+ block_byte = compressed[pos];
+ pos++;
}
- if (BlockType == 1) { //inter Block
- Integrator = Decompressed[Idx];
- }
- switch (BlockByte & 0xC0) {
- case 0x03<<6:
- Integrator += Compressed[ExtraPos];
- ExtraPos++;
- break;
- case 0x02<<6:
- Integrator += BlockCode;
- break;
- case 0x00:
- Integrator -= BlockCode;
- break;
+ if (block_type == 1) /* inter Block */
+ integrator = decompressed[idx];
+ switch (block_byte & 0xC0) {
+ case 0x03 << 6:
+ integrator += compressed[extra_pos];
+ extra_pos++;
+ break;
+ case 0x02 << 6:
+ integrator += block_code;
+ break;
+ case 0x00:
+ integrator -= block_code;
+ break;
}
- Decompressed[Idx] = Integrator;
- BlockByte <<= 2;
- BlockLen -= 1;
+ decompressed[idx] = integrator;
+ block_byte <<= 2;
+ block_len -= 1;
}
}
- *StartPos = ExtraPos;
- *BlockTypeStartPos = BlockTypePos;
- return Idx;
+ *start_pos = extra_pos;
+ *block_typestart_pos = block_type_pos;
+ return idx;
}
@@ -803,7 +782,7 @@ static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *C
* number of bytes (RGB) to the *pcopylen.
*
*/
-static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision,
+static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision,
long *pcopylen)
{
#define USBVISION_STRIP_MAGIC 0x5A
@@ -811,191 +790,165 @@ static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision,
#define USBVISION_STRIP_HEADER_LEN 3
struct usbvision_frame *frame;
- unsigned char *f,*u = NULL ,*v = NULL;
- unsigned char StripData[USBVISION_STRIP_LEN_MAX];
- unsigned char StripHeader[USBVISION_STRIP_HEADER_LEN];
- int Idx, IdxEnd, StripLen, StripPtr, StartBlockPos, BlockPos, BlockTypePos;
+ unsigned char *f, *u = NULL, *v = NULL;
+ unsigned char strip_data[USBVISION_STRIP_LEN_MAX];
+ unsigned char strip_header[USBVISION_STRIP_HEADER_LEN];
+ int idx, idx_end, strip_len, strip_ptr, startblock_pos, block_pos, block_type_pos;
int clipmask_index, bytes_per_pixel, rc;
- int imageSize;
+ int image_size;
unsigned char rv, gv, bv;
static unsigned char *Y, *U, *V;
- frame = usbvision->curFrame;
- imageSize = frame->frmwidth * frame->frmheight;
- if ( (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) ||
- (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) ) { // this is a planar format
- //... v4l2_linesize not used here.
+ frame = usbvision->cur_frame;
+ image_size = frame->frmwidth * frame->frmheight;
+ if ((frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) ||
+ (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420)) { /* this is a planar format */
+ /* ... v4l2_linesize not used here. */
f = frame->data + (frame->width * frame->curline);
} else
f = frame->data + (frame->v4l2_linesize * frame->curline);
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV){ //initialise u and v pointers
- // get base of u and b planes add halfoffset
-
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { /* initialise u and v pointers */
+ /* get base of u and b planes add halfoffset */
u = frame->data
- + imageSize
- + (frame->frmwidth >>1) * frame->curline ;
- v = u + (imageSize >>1 );
-
- } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420){
-
- v = frame->data + imageSize + ((frame->curline* (frame->width))>>2) ;
- u = v + (imageSize >>2) ;
+ + image_size
+ + (frame->frmwidth >> 1) * frame->curline;
+ v = u + (image_size >> 1);
+ } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
+ v = frame->data + image_size + ((frame->curline * (frame->width)) >> 2);
+ u = v + (image_size >> 2);
}
- if (frame->curline == 0) {
+ if (frame->curline == 0)
usbvision_adjust_compression(usbvision);
- }
- if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN) {
- return ParseState_Out;
- }
+ if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN)
+ return parse_state_out;
- //get strip header without changing the scratch_read_ptr
- scratch_set_extra_ptr(usbvision, &StripPtr, 0);
- scratch_get_extra(usbvision, &StripHeader[0], &StripPtr,
+ /* get strip header without changing the scratch_read_ptr */
+ scratch_set_extra_ptr(usbvision, &strip_ptr, 0);
+ scratch_get_extra(usbvision, &strip_header[0], &strip_ptr,
USBVISION_STRIP_HEADER_LEN);
- if (StripHeader[0] != USBVISION_STRIP_MAGIC) {
- // wrong strip magic
- usbvision->stripMagicErrors++;
- return ParseState_NextFrame;
+ if (strip_header[0] != USBVISION_STRIP_MAGIC) {
+ /* wrong strip magic */
+ usbvision->strip_magic_errors++;
+ return parse_state_next_frame;
}
- if (frame->curline != (int)StripHeader[2]) {
- //line number missmatch error
- usbvision->stripLineNumberErrors++;
+ if (frame->curline != (int)strip_header[2]) {
+ /* line number mismatch error */
+ usbvision->strip_line_number_errors++;
}
- StripLen = 2 * (unsigned int)StripHeader[1];
- if (StripLen > USBVISION_STRIP_LEN_MAX) {
- // strip overrun
- // I think this never happens
+ strip_len = 2 * (unsigned int)strip_header[1];
+ if (strip_len > USBVISION_STRIP_LEN_MAX) {
+ /* strip overrun */
+ /* I think this never happens */
usbvision_request_intra(usbvision);
}
- if (scratch_len(usbvision) < StripLen) {
- //there is not enough data for the strip
- return ParseState_Out;
+ if (scratch_len(usbvision) < strip_len) {
+ /* there is not enough data for the strip */
+ return parse_state_out;
}
- if (usbvision->IntraFrameBuffer) {
- Y = usbvision->IntraFrameBuffer + frame->frmwidth * frame->curline;
- U = usbvision->IntraFrameBuffer + imageSize + (frame->frmwidth / 2) * (frame->curline / 2);
- V = usbvision->IntraFrameBuffer + imageSize / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2);
- }
- else {
- return ParseState_NextFrame;
+ if (usbvision->intra_frame_buffer) {
+ Y = usbvision->intra_frame_buffer + frame->frmwidth * frame->curline;
+ U = usbvision->intra_frame_buffer + image_size + (frame->frmwidth / 2) * (frame->curline / 2);
+ V = usbvision->intra_frame_buffer + image_size / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2);
+ } else {
+ return parse_state_next_frame;
}
bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
clipmask_index = frame->curline * MAX_FRAME_WIDTH;
- scratch_get(usbvision, StripData, StripLen);
+ scratch_get(usbvision, strip_data, strip_len);
- IdxEnd = frame->frmwidth;
- BlockTypePos = USBVISION_STRIP_HEADER_LEN;
- StartBlockPos = BlockTypePos + (IdxEnd - 1) / 96 + (IdxEnd / 2 - 1) / 96 + 2;
- BlockPos = StartBlockPos;
+ idx_end = frame->frmwidth;
+ block_type_pos = USBVISION_STRIP_HEADER_LEN;
+ startblock_pos = block_type_pos + (idx_end - 1) / 96 + (idx_end / 2 - 1) / 96 + 2;
+ block_pos = startblock_pos;
- usbvision->BlockPos = BlockPos;
+ usbvision->block_pos = block_pos;
- if ((rc = usbvision_decompress(usbvision, StripData, Y, &BlockPos, &BlockTypePos, IdxEnd)) != IdxEnd) {
- //return ParseState_Continue;
- }
- if (StripLen > usbvision->maxStripLen) {
- usbvision->maxStripLen = StripLen;
- }
+ rc = usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end);
+ if (strip_len > usbvision->max_strip_len)
+ usbvision->max_strip_len = strip_len;
- if (frame->curline%2) {
- if ((rc = usbvision_decompress(usbvision, StripData, V, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) {
- //return ParseState_Continue;
- }
- }
- else {
- if ((rc = usbvision_decompress(usbvision, StripData, U, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) {
- //return ParseState_Continue;
- }
- }
+ if (frame->curline % 2)
+ rc = usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end / 2);
+ else
+ rc = usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end / 2);
- if (BlockPos > usbvision->comprBlockPos) {
- usbvision->comprBlockPos = BlockPos;
- }
- if (BlockPos > StripLen) {
- usbvision->stripLenErrors++;
- }
+ if (block_pos > usbvision->comprblock_pos)
+ usbvision->comprblock_pos = block_pos;
+ if (block_pos > strip_len)
+ usbvision->strip_len_errors++;
- for (Idx = 0; Idx < IdxEnd; Idx++) {
- if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = Y[Idx];
- *f++ = Idx & 0x01 ? U[Idx/2] : V[Idx/2];
- }
- else if(frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) {
- *f++ = Y[Idx];
- if ( Idx & 0x01)
- *u++ = U[Idx>>1] ;
+ for (idx = 0; idx < idx_end; idx++) {
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
+ *f++ = Y[idx];
+ *f++ = idx & 0x01 ? U[idx / 2] : V[idx / 2];
+ } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) {
+ *f++ = Y[idx];
+ if (idx & 0x01)
+ *u++ = U[idx >> 1];
else
- *v++ = V[Idx>>1];
- }
- else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
- *f++ = Y [Idx];
- if ( !(( Idx & 0x01 ) | ( frame->curline & 0x01 )) ){
-
-/* only need do this for 1 in 4 pixels */
-/* intraframe buffer is YUV420 format */
-
- *u++ = U[Idx >>1];
- *v++ = V[Idx >>1];
+ *v++ = V[idx >> 1];
+ } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
+ *f++ = Y[idx];
+ if (!((idx & 0x01) | (frame->curline & 0x01))) {
+ /* only need do this for 1 in 4 pixels */
+ /* intraframe buffer is YUV420 format */
+ *u++ = U[idx >> 1];
+ *v++ = V[idx >> 1];
}
-
- }
- else {
- YUV_TO_RGB_BY_THE_BOOK(Y[Idx], U[Idx/2], V[Idx/2], rv, gv, bv);
+ } else {
+ YUV_TO_RGB_BY_THE_BOOK(Y[idx], U[idx / 2], V[idx / 2], rv, gv, bv);
switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_GREY:
- *f++ = Y[Idx];
- break;
- case V4L2_PIX_FMT_RGB555:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x03 & (gv >> 3)) |
- (0x7C & (bv << 2));
- break;
- case V4L2_PIX_FMT_RGB565:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x07 & (gv >> 3)) |
- (0xF8 & bv);
- break;
- case V4L2_PIX_FMT_RGB24:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- break;
- case V4L2_PIX_FMT_RGB32:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- f++;
- break;
+ case V4L2_PIX_FMT_GREY:
+ *f++ = Y[idx];
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ *f++ = (0x1F & rv) |
+ (0xE0 & (gv << 5));
+ *f++ = (0x03 & (gv >> 3)) |
+ (0x7C & (bv << 2));
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ *f++ = (0x1F & rv) |
+ (0xE0 & (gv << 5));
+ *f++ = (0x07 & (gv >> 3)) |
+ (0xF8 & bv);
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ *f++ = rv;
+ *f++ = gv;
+ *f++ = bv;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ *f++ = rv;
+ *f++ = gv;
+ *f++ = bv;
+ f++;
+ break;
}
}
clipmask_index++;
}
/* Deal with non-integer no. of bytes for YUV420P */
- if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420 )
+ if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420)
*pcopylen += frame->v4l2_linesize;
else
*pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1;
frame->curline += 1;
- if (frame->curline >= frame->frmheight) {
- return ParseState_NextFrame;
- }
- else {
- return ParseState_Continue;
- }
+ if (frame->curline >= frame->frmheight)
+ return parse_state_next_frame;
+ return parse_state_continue;
}
@@ -1008,7 +961,7 @@ static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision,
* number of bytes (RGB) to the *pcopylen.
*
*/
-static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision,
+static enum parse_state usbvision_parse_lines_420(struct usb_usbvision *usbvision,
long *pcopylen)
{
struct usbvision_frame *frame;
@@ -1016,11 +969,11 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
unsigned int pixel_per_line, block;
int pixel, block_split;
int y_ptr, u_ptr, v_ptr, y_odd_offset;
- const int y_block_size = 128;
- const int uv_block_size = 64;
+ const int y_block_size = 128;
+ const int uv_block_size = 64;
const int sub_block_size = 32;
- const int y_step[] = { 0, 0, 0, 2 }, y_step_size = 4;
- const int uv_step[]= { 0, 0, 0, 4 }, uv_step_size = 4;
+ const int y_step[] = { 0, 0, 0, 2 }, y_step_size = 4;
+ const int uv_step[] = { 0, 0, 0, 4 }, uv_step_size = 4;
unsigned char y[2], u, v; /* YUV components */
int y_, u_, v_, vb, uvg, ur;
int r_, g_, b_; /* RGB components */
@@ -1028,7 +981,7 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
int clipmask_even_index, clipmask_odd_index, bytes_per_pixel;
int clipmask_add, stretch_bytes;
- frame = usbvision->curFrame;
+ frame = usbvision->cur_frame;
f_even = frame->data + (frame->v4l2_linesize * frame->curline);
f_odd = f_even + frame->v4l2_linesize * usbvision->stretch_height;
@@ -1040,18 +993,17 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
clipmask_even_index = frame->curline * MAX_FRAME_WIDTH;
clipmask_odd_index = clipmask_even_index + MAX_FRAME_WIDTH;
clipmask_add = usbvision->stretch_width;
- pixel_per_line = frame->isocHeader.frameWidth;
+ pixel_per_line = frame->isoc_header.frame_width;
if (scratch_len(usbvision) < (int)pixel_per_line * 3) {
- //printk(KERN_DEBUG "out of data, need %d\n", len);
- return ParseState_Out;
+ /* printk(KERN_DEBUG "out of data, need %d\n", len); */
+ return parse_state_out;
}
- if ((frame->curline + 1) >= frame->frmheight) {
- return ParseState_NextFrame;
- }
+ if ((frame->curline + 1) >= frame->frmheight)
+ return parse_state_next_frame;
- block_split = (pixel_per_line%y_block_size) ? 1 : 0; //are some blocks splitted into different lines?
+ block_split = (pixel_per_line%y_block_size) ? 1 : 0; /* are some blocks splitted into different lines? */
y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size)
+ block_split * uv_block_size;
@@ -1061,31 +1013,27 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset
+ (4 - block_split) * sub_block_size);
- for (block = 0; block < (pixel_per_line / sub_block_size);
- block++) {
-
-
- for (pixel = 0; pixel < sub_block_size; pixel +=2) {
+ for (block = 0; block < (pixel_per_line / sub_block_size); block++) {
+ for (pixel = 0; pixel < sub_block_size; pixel += 2) {
scratch_get(usbvision, &y[0], 2);
scratch_get_extra(usbvision, &u, &u_ptr, 1);
scratch_get_extra(usbvision, &v, &v_ptr, 1);
- //I don't use the YUV_TO_RGB macro for better performance
+ /* I don't use the YUV_TO_RGB macro for better performance */
v_ = v - 128;
u_ = u - 128;
- vb = 132252 * v_;
- uvg= -53281 * u_ - 25625 * v_;
+ vb = 132252 * v_;
+ uvg = -53281 * u_ - 25625 * v_;
ur = 104595 * u_;
- if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
*f_even++ = y[0];
*f_even++ = v;
- }
- else {
+ } else {
y_ = 76284 * (y[0] - 16);
b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg)>> 16;
+ g_ = (y_ + uvg) >> 16;
r_ = (y_ + ur) >> 16;
switch (frame->v4l2_format.format) {
@@ -1121,15 +1069,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
clipmask_even_index += clipmask_add;
f_even += stretch_bytes;
- if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
*f_even++ = y[1];
*f_even++ = u;
- }
- else {
+ } else {
y_ = 76284 * (y[1] - 16);
b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg)>> 16;
+ g_ = (y_ + uvg) >> 16;
r_ = (y_ + ur) >> 16;
switch (frame->v4l2_format.format) {
@@ -1167,15 +1114,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
scratch_get_extra(usbvision, &y[0], &y_ptr, 2);
- if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
*f_odd++ = y[0];
*f_odd++ = v;
- }
- else {
+ } else {
y_ = 76284 * (y[0] - 16);
b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg)>> 16;
+ g_ = (y_ + uvg) >> 16;
r_ = (y_ + ur) >> 16;
switch (frame->v4l2_format.format) {
@@ -1211,15 +1157,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
clipmask_odd_index += clipmask_add;
f_odd += stretch_bytes;
- if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
+ if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
*f_odd++ = y[1];
*f_odd++ = u;
- }
- else {
+ } else {
y_ = 76284 * (y[1] - 16);
b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg)>> 16;
+ g_ = (y_ + uvg) >> 16;
r_ = (y_ + ur) >> 16;
switch (frame->v4l2_format.format) {
@@ -1256,7 +1201,7 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
f_odd += stretch_bytes;
}
- scratch_rm_old(usbvision,y_step[block % y_step_size] * sub_block_size);
+ scratch_rm_old(usbvision, y_step[block % y_step_size] * sub_block_size);
scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size]
* sub_block_size);
scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size]
@@ -1272,9 +1217,8 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
*pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height;
if (frame->curline >= frame->frmheight)
- return ParseState_NextFrame;
- else
- return ParseState_Continue;
+ return parse_state_next_frame;
+ return parse_state_continue;
}
/*
@@ -1288,53 +1232,43 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision
static void usbvision_parse_data(struct usb_usbvision *usbvision)
{
struct usbvision_frame *frame;
- enum ParseState newstate;
+ enum parse_state newstate;
long copylen = 0;
unsigned long lock_flags;
- frame = usbvision->curFrame;
+ frame = usbvision->cur_frame;
PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision));
while (1) {
-
- newstate = ParseState_Out;
+ newstate = parse_state_out;
if (scratch_len(usbvision)) {
- if (frame->scanstate == ScanState_Scanning) {
+ if (frame->scanstate == scan_state_scanning) {
newstate = usbvision_find_header(usbvision);
- }
- else if (frame->scanstate == ScanState_Lines) {
- if (usbvision->isocMode == ISOC_MODE_YUV420) {
+ } else if (frame->scanstate == scan_state_lines) {
+ if (usbvision->isoc_mode == ISOC_MODE_YUV420)
newstate = usbvision_parse_lines_420(usbvision, &copylen);
- }
- else if (usbvision->isocMode == ISOC_MODE_YUV422) {
+ else if (usbvision->isoc_mode == ISOC_MODE_YUV422)
newstate = usbvision_parse_lines_422(usbvision, &copylen);
- }
- else if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
+ else if (usbvision->isoc_mode == ISOC_MODE_COMPRESS)
newstate = usbvision_parse_compress(usbvision, &copylen);
- }
-
}
}
- if (newstate == ParseState_Continue) {
+ if (newstate == parse_state_continue)
continue;
- }
- else if ((newstate == ParseState_NextFrame) || (newstate == ParseState_Out)) {
+ if ((newstate == parse_state_next_frame) || (newstate == parse_state_out))
break;
- }
- else {
- return; /* ParseState_EndParse */
- }
+ return; /* parse_state_end_parse */
}
- if (newstate == ParseState_NextFrame) {
- frame->grabstate = FrameState_Done;
+ if (newstate == parse_state_next_frame) {
+ frame->grabstate = frame_state_done;
do_gettimeofday(&(frame->timestamp));
frame->sequence = usbvision->frame_num;
spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
list_move_tail(&(frame->frame), &usbvision->outqueue);
- usbvision->curFrame = NULL;
+ usbvision->cur_frame = NULL;
spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
usbvision->frame_num++;
@@ -1344,10 +1278,9 @@ static void usbvision_parse_data(struct usb_usbvision *usbvision)
PDEBUG(DBG_PARSE, "Wake up !");
wake_up_interruptible(&usbvision->wait_frame);
}
+ } else {
+ frame->grabstate = frame_state_grabbing;
}
- else
- frame->grabstate = FrameState_Grabbing;
-
/* Update the frame's uncompressed length. */
frame->scanlength += copylen;
@@ -1370,34 +1303,32 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
/* Detect and ignore errored packets */
- if (packet_stat) { // packet_stat != 0 ?????????????
+ if (packet_stat) { /* packet_stat != 0 ????????????? */
PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat);
- usbvision->isocErrCount++;
+ usbvision->isoc_err_count++;
continue;
}
/* Detect and ignore empty packets */
if (packet_len < 0) {
PDEBUG(DBG_ISOC, "error packet [%d]", i);
- usbvision->isocSkipCount++;
+ usbvision->isoc_skip_count++;
continue;
- }
- else if (packet_len == 0) { /* Frame end ????? */
+ } else if (packet_len == 0) { /* Frame end ????? */
PDEBUG(DBG_ISOC, "null packet [%d]", i);
- usbvision->isocstate=IsocState_NoFrame;
- usbvision->isocSkipCount++;
+ usbvision->isocstate = isoc_state_no_frame;
+ usbvision->isoc_skip_count++;
continue;
- }
- else if (packet_len > usbvision->isocPacketSize) {
- PDEBUG(DBG_ISOC, "packet[%d] > isocPacketSize", i);
- usbvision->isocSkipCount++;
+ } else if (packet_len > usbvision->isoc_packet_size) {
+ PDEBUG(DBG_ISOC, "packet[%d] > isoc_packet_size", i);
+ usbvision->isoc_skip_count++;
continue;
}
PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len);
- if (usbvision->isocstate==IsocState_NoFrame) { //new frame begins
- usbvision->isocstate=IsocState_InFrame;
+ if (usbvision->isocstate == isoc_state_no_frame) { /* new frame begins */
+ usbvision->isocstate = isoc_state_in_frame;
scratch_mark_header(usbvision);
usbvision_measure_bandwidth(usbvision);
PDEBUG(DBG_ISOC, "packet with header");
@@ -1412,7 +1343,6 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
* your favorite evil here.
*/
if (scratch_free(usbvision) < packet_len) {
-
usbvision->scratch_ovf_count++;
PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d",
scratch_len(usbvision), packet_len);
@@ -1422,12 +1352,13 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
/* Now we know that there is enough room in scratch buffer */
scratch_put(usbvision, packet_data, packet_len);
totlen += packet_len;
- usbvision->isocDataCount += packet_len;
- usbvision->isocPacketCount++;
+ usbvision->isoc_data_count += packet_len;
+ usbvision->isoc_packet_count++;
}
#if ENABLE_HEXDUMP
if (totlen > 0) {
static int foo;
+
if (foo < 1) {
printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen);
usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen);
@@ -1435,16 +1366,16 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
}
}
#endif
- return totlen;
+ return totlen;
}
-static void usbvision_isocIrq(struct urb *urb)
+static void usbvision_isoc_irq(struct urb *urb)
{
- int errCode = 0;
+ int err_code = 0;
int len;
struct usb_usbvision *usbvision = urb->context;
int i;
- unsigned long startTime = jiffies;
+ unsigned long start_time = jiffies;
struct usbvision_frame **f;
/* We don't want to do anything if we are about to be removed! */
@@ -1452,18 +1383,17 @@ static void usbvision_isocIrq(struct urb *urb)
return;
/* any urb with wrong status is ignored without acknowledgement */
- if (urb->status == -ENOENT) {
+ if (urb->status == -ENOENT)
return;
- }
- f = &usbvision->curFrame;
+ f = &usbvision->cur_frame;
/* Manage streaming interruption */
- if (usbvision->streaming == Stream_Interrupt) {
- usbvision->streaming = Stream_Idle;
+ if (usbvision->streaming == stream_interrupt) {
+ usbvision->streaming = stream_idle;
if ((*f)) {
- (*f)->grabstate = FrameState_Ready;
- (*f)->scanstate = ScanState_Scanning;
+ (*f)->grabstate = frame_state_ready;
+ (*f)->scanstate = scan_state_scanning;
}
PDEBUG(DBG_IRQ, "stream interrupted");
wake_up_interruptible(&usbvision->wait_stream);
@@ -1472,35 +1402,32 @@ static void usbvision_isocIrq(struct urb *urb)
/* Copy the data received into our scratch buffer */
len = usbvision_compress_isochronous(usbvision, urb);
- usbvision->isocUrbCount++;
+ usbvision->isoc_urb_count++;
usbvision->urb_length = len;
- if (usbvision->streaming == Stream_On) {
-
+ if (usbvision->streaming == stream_on) {
/* If we collected enough data let's parse! */
- if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
- (!list_empty(&(usbvision->inqueue))) ) {
+ if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH &&
+ !list_empty(&(usbvision->inqueue))) {
if (!(*f)) {
(*f) = list_entry(usbvision->inqueue.next,
struct usbvision_frame,
frame);
}
usbvision_parse_data(usbvision);
- }
- else {
- /*If we don't have a frame
+ } else {
+ /* If we don't have a frame
we're current working on, complain */
PDEBUG(DBG_IRQ,
"received data, but no one needs it");
scratch_reset(usbvision);
}
- }
- else {
+ } else {
PDEBUG(DBG_IRQ, "received data, but no one needs it");
scratch_reset(usbvision);
}
- usbvision->timeInIrq += jiffies - startTime;
+ usbvision->time_in_irq += jiffies - start_time;
for (i = 0; i < USBVISION_URB_FRAMES; i++) {
urb->iso_frame_desc[i].status = 0;
@@ -1509,12 +1436,12 @@ static void usbvision_isocIrq(struct urb *urb)
urb->status = 0;
urb->dev = usbvision->dev;
- errCode = usb_submit_urb (urb, GFP_ATOMIC);
+ err_code = usb_submit_urb(urb, GFP_ATOMIC);
- if(errCode) {
+ if (err_code) {
dev_err(&usbvision->dev->dev,
"%s: usb_submit_urb failed: error %d\n",
- __func__, errCode);
+ __func__, err_code);
}
return;
@@ -1533,21 +1460,21 @@ static void usbvision_isocIrq(struct urb *urb)
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
{
- int errCode = 0;
+ int err_code = 0;
unsigned char buffer[1];
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -1;
- errCode = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1),
+ err_code = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
0, (__u16) reg, buffer, 1, HZ);
- if (errCode < 0) {
+ if (err_code < 0) {
dev_err(&usbvision->dev->dev,
- "%s: failed: error %d\n", __func__, errCode);
- return errCode;
+ "%s: failed: error %d\n", __func__, err_code);
+ return err_code;
}
return buffer[0];
}
@@ -1563,179 +1490,176 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
unsigned char value)
{
- int errCode = 0;
+ int err_code = 0;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
- errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
+ err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_OUT | USB_TYPE_VENDOR |
USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
- if (errCode < 0) {
+ if (err_code < 0) {
dev_err(&usbvision->dev->dev,
- "%s: failed: error %d\n", __func__, errCode);
+ "%s: failed: error %d\n", __func__, err_code);
}
- return errCode;
+ return err_code;
}
-static void usbvision_ctrlUrb_complete(struct urb *urb)
+static void usbvision_ctrl_urb_complete(struct urb *urb)
{
struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context;
PDEBUG(DBG_IRQ, "");
- usbvision->ctrlUrbBusy = 0;
- if (waitqueue_active(&usbvision->ctrlUrb_wq)) {
- wake_up_interruptible(&usbvision->ctrlUrb_wq);
- }
+ usbvision->ctrl_urb_busy = 0;
+ if (waitqueue_active(&usbvision->ctrl_urb_wq))
+ wake_up_interruptible(&usbvision->ctrl_urb_wq);
}
-static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address,
- unsigned char *data, int len)
+static int usbvision_write_reg_irq(struct usb_usbvision *usbvision, int address,
+ unsigned char *data, int len)
{
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_IRQ, "");
- if (len > 8) {
+ if (len > 8)
return -EFAULT;
- }
- if (usbvision->ctrlUrbBusy) {
+ if (usbvision->ctrl_urb_busy)
return -EBUSY;
- }
- usbvision->ctrlUrbBusy = 1;
-
- usbvision->ctrlUrbSetup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
- usbvision->ctrlUrbSetup.bRequest = USBVISION_OP_CODE;
- usbvision->ctrlUrbSetup.wValue = 0;
- usbvision->ctrlUrbSetup.wIndex = cpu_to_le16(address);
- usbvision->ctrlUrbSetup.wLength = cpu_to_le16(len);
- usb_fill_control_urb (usbvision->ctrlUrb, usbvision->dev,
+ usbvision->ctrl_urb_busy = 1;
+
+ usbvision->ctrl_urb_setup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+ usbvision->ctrl_urb_setup.bRequest = USBVISION_OP_CODE;
+ usbvision->ctrl_urb_setup.wValue = 0;
+ usbvision->ctrl_urb_setup.wIndex = cpu_to_le16(address);
+ usbvision->ctrl_urb_setup.wLength = cpu_to_le16(len);
+ usb_fill_control_urb(usbvision->ctrl_urb, usbvision->dev,
usb_sndctrlpipe(usbvision->dev, 1),
- (unsigned char *)&usbvision->ctrlUrbSetup,
- (void *)usbvision->ctrlUrbBuffer, len,
- usbvision_ctrlUrb_complete,
+ (unsigned char *)&usbvision->ctrl_urb_setup,
+ (void *)usbvision->ctrl_urb_buffer, len,
+ usbvision_ctrl_urb_complete,
(void *)usbvision);
- memcpy(usbvision->ctrlUrbBuffer, data, len);
+ memcpy(usbvision->ctrl_urb_buffer, data, len);
- errCode = usb_submit_urb(usbvision->ctrlUrb, GFP_ATOMIC);
- if (errCode < 0) {
- // error in usb_submit_urb()
- usbvision->ctrlUrbBusy = 0;
+ err_code = usb_submit_urb(usbvision->ctrl_urb, GFP_ATOMIC);
+ if (err_code < 0) {
+ /* error in usb_submit_urb() */
+ usbvision->ctrl_urb_busy = 0;
}
- PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, errCode);
- return errCode;
+ PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, err_code);
+ return err_code;
}
static int usbvision_init_compression(struct usb_usbvision *usbvision)
{
- int errCode = 0;
-
- usbvision->lastIsocFrameNum = -1;
- usbvision->isocDataCount = 0;
- usbvision->isocPacketCount = 0;
- usbvision->isocSkipCount = 0;
- usbvision->comprLevel = 50;
- usbvision->lastComprLevel = -1;
- usbvision->isocUrbCount = 0;
- usbvision->requestIntra = 1;
- usbvision->isocMeasureBandwidthCount = 0;
-
- return errCode;
+ int err_code = 0;
+
+ usbvision->last_isoc_frame_num = -1;
+ usbvision->isoc_data_count = 0;
+ usbvision->isoc_packet_count = 0;
+ usbvision->isoc_skip_count = 0;
+ usbvision->compr_level = 50;
+ usbvision->last_compr_level = -1;
+ usbvision->isoc_urb_count = 0;
+ usbvision->request_intra = 1;
+ usbvision->isoc_measure_bandwidth_count = 0;
+
+ return err_code;
}
/* this function measures the used bandwidth since last call
* return: 0 : no error
- * sets usedBandwidth to 1-100 : 1-100% of full bandwidth resp. to isocPacketSize
+ * sets used_bandwidth to 1-100 : 1-100% of full bandwidth resp. to isoc_packet_size
*/
-static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision)
+static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision)
{
- int errCode = 0;
-
- if (usbvision->isocMeasureBandwidthCount < 2) { // this gives an average bandwidth of 3 frames
- usbvision->isocMeasureBandwidthCount++;
- return errCode;
- }
- if ((usbvision->isocPacketSize > 0) && (usbvision->isocPacketCount > 0)) {
- usbvision->usedBandwidth = usbvision->isocDataCount /
- (usbvision->isocPacketCount + usbvision->isocSkipCount) *
- 100 / usbvision->isocPacketSize;
- }
- usbvision->isocMeasureBandwidthCount = 0;
- usbvision->isocDataCount = 0;
- usbvision->isocPacketCount = 0;
- usbvision->isocSkipCount = 0;
- return errCode;
+ int err_code = 0;
+
+ if (usbvision->isoc_measure_bandwidth_count < 2) { /* this gives an average bandwidth of 3 frames */
+ usbvision->isoc_measure_bandwidth_count++;
+ return err_code;
+ }
+ if ((usbvision->isoc_packet_size > 0) && (usbvision->isoc_packet_count > 0)) {
+ usbvision->used_bandwidth = usbvision->isoc_data_count /
+ (usbvision->isoc_packet_count + usbvision->isoc_skip_count) *
+ 100 / usbvision->isoc_packet_size;
+ }
+ usbvision->isoc_measure_bandwidth_count = 0;
+ usbvision->isoc_data_count = 0;
+ usbvision->isoc_packet_count = 0;
+ usbvision->isoc_skip_count = 0;
+ return err_code;
}
-static int usbvision_adjust_compression (struct usb_usbvision *usbvision)
+static int usbvision_adjust_compression(struct usb_usbvision *usbvision)
{
- int errCode = 0;
+ int err_code = 0;
unsigned char buffer[6];
PDEBUG(DBG_IRQ, "");
- if ((adjustCompression) && (usbvision->usedBandwidth > 0)) {
- usbvision->comprLevel += (usbvision->usedBandwidth - 90) / 2;
- RESTRICT_TO_RANGE(usbvision->comprLevel, 0, 100);
- if (usbvision->comprLevel != usbvision->lastComprLevel) {
- int distorsion;
- if (usbvision->bridgeType == BRIDGE_NT1004 || usbvision->bridgeType == BRIDGE_NT1005) {
- buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100); // PCM Threshold 1
- buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100); // PCM Threshold 2
- distorsion = 7 + 248 * usbvision->comprLevel / 100;
- buffer[2] = (unsigned char)(distorsion & 0xFF); // Average distorsion Threshold (inter)
- buffer[3] = (unsigned char)(distorsion & 0xFF); // Average distorsion Threshold (intra)
- distorsion = 1 + 42 * usbvision->comprLevel / 100;
- buffer[4] = (unsigned char)(distorsion & 0xFF); // Maximum distorsion Threshold (inter)
- buffer[5] = (unsigned char)(distorsion & 0xFF); // Maximum distorsion Threshold (intra)
- }
- else { //BRIDGE_NT1003
- buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100); // PCM threshold 1
- buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100); // PCM threshold 2
- distorsion = 2 + 253 * usbvision->comprLevel / 100;
- buffer[2] = (unsigned char)(distorsion & 0xFF); // distorsion threshold bit0-7
- buffer[3] = 0; //(unsigned char)((distorsion >> 8) & 0x0F); // distorsion threshold bit 8-11
- distorsion = 0 + 43 * usbvision->comprLevel / 100;
- buffer[4] = (unsigned char)(distorsion & 0xFF); // maximum distorsion bit0-7
- buffer[5] = 0; //(unsigned char)((distorsion >> 8) & 0x01); // maximum distorsion bit 8
+ if ((adjust_compression) && (usbvision->used_bandwidth > 0)) {
+ usbvision->compr_level += (usbvision->used_bandwidth - 90) / 2;
+ RESTRICT_TO_RANGE(usbvision->compr_level, 0, 100);
+ if (usbvision->compr_level != usbvision->last_compr_level) {
+ int distortion;
+
+ if (usbvision->bridge_type == BRIDGE_NT1004 || usbvision->bridge_type == BRIDGE_NT1005) {
+ buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM Threshold 1 */
+ buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM Threshold 2 */
+ distortion = 7 + 248 * usbvision->compr_level / 100;
+ buffer[2] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (inter) */
+ buffer[3] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (intra) */
+ distortion = 1 + 42 * usbvision->compr_level / 100;
+ buffer[4] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (inter) */
+ buffer[5] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (intra) */
+ } else { /* BRIDGE_NT1003 */
+ buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM threshold 1 */
+ buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM threshold 2 */
+ distortion = 2 + 253 * usbvision->compr_level / 100;
+ buffer[2] = (unsigned char)(distortion & 0xFF); /* distortion threshold bit0-7 */
+ buffer[3] = 0; /* (unsigned char)((distortion >> 8) & 0x0F); distortion threshold bit 8-11 */
+ distortion = 0 + 43 * usbvision->compr_level / 100;
+ buffer[4] = (unsigned char)(distortion & 0xFF); /* maximum distortion bit0-7 */
+ buffer[5] = 0; /* (unsigned char)((distortion >> 8) & 0x01); maximum distortion bit 8 */
}
- errCode = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6);
- if (errCode == 0){
+ err_code = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6);
+ if (err_code == 0) {
PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0],
buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
- usbvision->lastComprLevel = usbvision->comprLevel;
+ usbvision->last_compr_level = usbvision->compr_level;
}
}
}
- return errCode;
+ return err_code;
}
-static int usbvision_request_intra (struct usb_usbvision *usbvision)
+static int usbvision_request_intra(struct usb_usbvision *usbvision)
{
- int errCode = 0;
+ int err_code = 0;
unsigned char buffer[1];
PDEBUG(DBG_IRQ, "");
- usbvision->requestIntra = 1;
+ usbvision->request_intra = 1;
buffer[0] = 1;
usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return errCode;
+ return err_code;
}
-static int usbvision_unrequest_intra (struct usb_usbvision *usbvision)
+static int usbvision_unrequest_intra(struct usb_usbvision *usbvision)
{
- int errCode = 0;
+ int err_code = 0;
unsigned char buffer[1];
PDEBUG(DBG_IRQ, "");
- usbvision->requestIntra = 0;
+ usbvision->request_intra = 0;
buffer[0] = 0;
usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return errCode;
+ return err_code;
}
/*******************************
@@ -1744,16 +1668,15 @@ static int usbvision_unrequest_intra (struct usb_usbvision *usbvision)
int usbvision_power_off(struct usb_usbvision *usbvision)
{
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_FUNC, "");
- errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
- if (errCode == 1) {
+ err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
+ if (err_code == 1)
usbvision->power = 0;
- }
- PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode!=1)?"ERROR":"power is off", errCode);
- return errCode;
+ PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code != 1) ? "ERROR" : "power is off", err_code);
+ return err_code;
}
/*
@@ -1769,7 +1692,7 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
- PDEBUG(DBG_FUNC, "isocMode %#02x", format);
+ PDEBUG(DBG_FUNC, "isoc_mode %#02x", format);
if ((format != ISOC_MODE_YUV422)
&& (format != ISOC_MODE_YUV420)
@@ -1778,8 +1701,8 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma
format);
format = ISOC_MODE_YUV420;
}
- value[0] = 0x0A; //TODO: See the effect of the filter
- value[1] = format; // Sets the VO_MODE register which follows FILT_CONT
+ value[0] = 0x0A; /* TODO: See the effect of the filter */
+ value[1] = format; /* Sets the VO_MODE register which follows FILT_CONT */
rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_OUT | USB_TYPE_VENDOR |
@@ -1790,7 +1713,7 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma
printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - "
"reconnect or reload driver.\n", proc, rc);
}
- usbvision->isocMode = format;
+ usbvision->isoc_mode = format;
return rc;
}
@@ -1802,96 +1725,88 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma
int usbvision_set_output(struct usb_usbvision *usbvision, int width,
int height)
{
- int errCode = 0;
- int UsbWidth, UsbHeight;
- unsigned int frameRate=0, frameDrop=0;
+ int err_code = 0;
+ int usb_width, usb_height;
+ unsigned int frame_rate = 0, frame_drop = 0;
unsigned char value[4];
- if (!USBVISION_IS_OPERATIONAL(usbvision)) {
+ if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
- }
if (width > MAX_USB_WIDTH) {
- UsbWidth = width / 2;
+ usb_width = width / 2;
usbvision->stretch_width = 2;
- }
- else {
- UsbWidth = width;
+ } else {
+ usb_width = width;
usbvision->stretch_width = 1;
}
if (height > MAX_USB_HEIGHT) {
- UsbHeight = height / 2;
+ usb_height = height / 2;
usbvision->stretch_height = 2;
- }
- else {
- UsbHeight = height;
+ } else {
+ usb_height = height;
usbvision->stretch_height = 1;
}
- RESTRICT_TO_RANGE(UsbWidth, MIN_FRAME_WIDTH, MAX_USB_WIDTH);
- UsbWidth &= ~(MIN_FRAME_WIDTH-1);
- RESTRICT_TO_RANGE(UsbHeight, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT);
- UsbHeight &= ~(1);
+ RESTRICT_TO_RANGE(usb_width, MIN_FRAME_WIDTH, MAX_USB_WIDTH);
+ usb_width &= ~(MIN_FRAME_WIDTH-1);
+ RESTRICT_TO_RANGE(usb_height, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT);
+ usb_height &= ~(1);
PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d",
- UsbWidth, UsbHeight, width, height,
+ usb_width, usb_height, width, height,
usbvision->stretch_width, usbvision->stretch_height);
/* I'll not rewrite the same values */
- if ((UsbWidth != usbvision->curwidth) || (UsbHeight != usbvision->curheight)) {
- value[0] = UsbWidth & 0xff; //LSB
- value[1] = (UsbWidth >> 8) & 0x03; //MSB
- value[2] = UsbHeight & 0xff; //LSB
- value[3] = (UsbHeight >> 8) & 0x03; //MSB
+ if ((usb_width != usbvision->curwidth) || (usb_height != usbvision->curheight)) {
+ value[0] = usb_width & 0xff; /* LSB */
+ value[1] = (usb_width >> 8) & 0x03; /* MSB */
+ value[2] = usb_height & 0xff; /* LSB */
+ value[3] = (usb_height >> 8) & 0x03; /* MSB */
- errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
+ err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
- if (errCode < 0) {
+ if (err_code < 0) {
dev_err(&usbvision->dev->dev,
- "%s failed: error %d\n", __func__, errCode);
- return errCode;
+ "%s failed: error %d\n", __func__, err_code);
+ return err_code;
}
- usbvision->curwidth = usbvision->stretch_width * UsbWidth;
- usbvision->curheight = usbvision->stretch_height * UsbHeight;
+ usbvision->curwidth = usbvision->stretch_width * usb_width;
+ usbvision->curheight = usbvision->stretch_height * usb_height;
}
- if (usbvision->isocMode == ISOC_MODE_YUV422) {
- frameRate = (usbvision->isocPacketSize * 1000) / (UsbWidth * UsbHeight * 2);
- }
- else if (usbvision->isocMode == ISOC_MODE_YUV420) {
- frameRate = (usbvision->isocPacketSize * 1000) / ((UsbWidth * UsbHeight * 12) / 8);
- }
- else {
- frameRate = FRAMERATE_MAX;
- }
+ if (usbvision->isoc_mode == ISOC_MODE_YUV422)
+ frame_rate = (usbvision->isoc_packet_size * 1000) / (usb_width * usb_height * 2);
+ else if (usbvision->isoc_mode == ISOC_MODE_YUV420)
+ frame_rate = (usbvision->isoc_packet_size * 1000) / ((usb_width * usb_height * 12) / 8);
+ else
+ frame_rate = FRAMERATE_MAX;
- if (usbvision->tvnormId & V4L2_STD_625_50) {
- frameDrop = frameRate * 32 / 25 - 1;
- }
- else if (usbvision->tvnormId & V4L2_STD_525_60) {
- frameDrop = frameRate * 32 / 30 - 1;
- }
+ if (usbvision->tvnorm_id & V4L2_STD_625_50)
+ frame_drop = frame_rate * 32 / 25 - 1;
+ else if (usbvision->tvnorm_id & V4L2_STD_525_60)
+ frame_drop = frame_rate * 32 / 30 - 1;
- RESTRICT_TO_RANGE(frameDrop, FRAMERATE_MIN, FRAMERATE_MAX);
+ RESTRICT_TO_RANGE(frame_drop, FRAMERATE_MIN, FRAMERATE_MAX);
- PDEBUG(DBG_FUNC, "frameRate %d fps, frameDrop %d", frameRate, frameDrop);
+ PDEBUG(DBG_FUNC, "frame_rate %d fps, frame_drop %d", frame_rate, frame_drop);
- frameDrop = FRAMERATE_MAX; // We can allow the maximum here, because dropping is controlled
+ frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
- /* frameDrop = 7; => framePhase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
- => frameSkip = 4;
- => frameRate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
+ /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
+ => frame_skip = 4;
+ => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
- frameDrop = 9; => framePhase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ...
- => frameSkip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ...
- => frameRate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125;
+ frame_drop = 9; => frame_phase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ...
+ => frame_skip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ...
+ => frame_rate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125;
*/
- errCode = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frameDrop);
- return errCode;
+ err_code = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frame_drop);
+ return err_code;
}
@@ -1903,8 +1818,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
{
int i;
- /*needs to be page aligned cause the buffers can be mapped individually! */
- usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth *
+ /* needs to be page aligned cause the buffers can be mapped individually! */
+ usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth *
usbvision->curheight *
usbvision->palette.bytes_per_pixel);
@@ -1912,9 +1827,9 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
usbvision->num_frames = number_of_frames;
while (usbvision->num_frames > 0) {
usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size;
- if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) {
+ usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size);
+ if (usbvision->fbuf)
break;
- }
usbvision->num_frames--;
}
@@ -1925,7 +1840,7 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
/* Allocate all buffers */
for (i = 0; i < usbvision->num_frames; i++) {
usbvision->frame[i].index = i;
- usbvision->frame[i].grabstate = FrameState_Unused;
+ usbvision->frame[i].grabstate = frame_state_unused;
usbvision->frame[i].data = usbvision->fbuf +
i * usbvision->max_frame_size;
/*
@@ -1937,7 +1852,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
usbvision->frame[i].height = usbvision->curheight;
usbvision->frame[i].bytes_read = 0;
}
- PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size);
+ PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",
+ usbvision->num_frames, usbvision->max_frame_size);
return usbvision->num_frames;
}
@@ -1948,7 +1864,7 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
void usbvision_frames_free(struct usb_usbvision *usbvision)
{
/* Have to free all that memory */
- PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames);
+ PDEBUG(DBG_FUNC, "free %d frames", usbvision->num_frames);
if (usbvision->fbuf != NULL) {
usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
@@ -1969,7 +1885,7 @@ void usbvision_empty_framequeues(struct usb_usbvision *usbvision)
INIT_LIST_HEAD(&(usbvision->outqueue));
for (i = 0; i < USBVISION_NUMFRAMES; i++) {
- usbvision->frame[i].grabstate = FrameState_Unused;
+ usbvision->frame[i].grabstate = frame_state_unused;
usbvision->frame[i].bytes_read = 0;
}
}
@@ -1984,9 +1900,9 @@ int usbvision_stream_interrupt(struct usb_usbvision *usbvision)
/* stop reading from the device */
- usbvision->streaming = Stream_Interrupt;
+ usbvision->streaming = stream_interrupt;
ret = wait_event_timeout(usbvision->wait_stream,
- (usbvision->streaming == Stream_Idle),
+ (usbvision->streaming == stream_idle),
msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
return ret;
}
@@ -2002,19 +1918,19 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
int rc;
unsigned char value[6];
- value[0] = 0x0F; // Intra-Compression cycle
- value[1] = 0x01; // Reg.45 one line per strip
- value[2] = 0x00; // Reg.46 Force intra mode on all new frames
- value[3] = 0x00; // Reg.47 FORCE_UP <- 0 normal operation (not force)
- value[4] = 0xA2; // Reg.48 BUF_THR I'm not sure if this does something in not compressed mode.
- value[5] = 0x00; // Reg.49 DVI_YUV This has nothing to do with compression
-
- //catched values for NT1004
- // value[0] = 0xFF; // Never apply intra mode automatically
- // value[1] = 0xF1; // Use full frame height for virtual strip width; One line per strip
- // value[2] = 0x01; // Force intra mode on all new frames
- // value[3] = 0x00; // Strip size 400 Bytes; do not force up
- // value[4] = 0xA2; //
+ value[0] = 0x0F; /* Intra-Compression cycle */
+ value[1] = 0x01; /* Reg.45 one line per strip */
+ value[2] = 0x00; /* Reg.46 Force intra mode on all new frames */
+ value[3] = 0x00; /* Reg.47 FORCE_UP <- 0 normal operation (not force) */
+ value[4] = 0xA2; /* Reg.48 BUF_THR I'm not sure if this does something in not compressed mode. */
+ value[5] = 0x00; /* Reg.49 DVI_YUV This has nothing to do with compression */
+
+ /* catched values for NT1004 */
+ /* value[0] = 0xFF; Never apply intra mode automatically */
+ /* value[1] = 0xF1; Use full frame height for virtual strip width; One line per strip */
+ /* value[2] = 0x01; Force intra mode on all new frames */
+ /* value[3] = 0x00; Strip size 400 Bytes; do not force up */
+ /* value[4] = 0xA2; */
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
@@ -2030,21 +1946,20 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
return rc;
}
- if (usbvision->bridgeType == BRIDGE_NT1004) {
- value[0] = 20; // PCM Threshold 1
- value[1] = 12; // PCM Threshold 2
- value[2] = 255; // Distorsion Threshold inter
- value[3] = 255; // Distorsion Threshold intra
- value[4] = 43; // Max Distorsion inter
- value[5] = 43; // Max Distorsion intra
- }
- else {
- value[0] = 20; // PCM Threshold 1
- value[1] = 12; // PCM Threshold 2
- value[2] = 255; // Distorsion Threshold d7-d0
- value[3] = 0; // Distorsion Threshold d11-d8
- value[4] = 43; // Max Distorsion d7-d0
- value[5] = 0; // Max Distorsion d8
+ if (usbvision->bridge_type == BRIDGE_NT1004) {
+ value[0] = 20; /* PCM Threshold 1 */
+ value[1] = 12; /* PCM Threshold 2 */
+ value[2] = 255; /* Distortion Threshold inter */
+ value[3] = 255; /* Distortion Threshold intra */
+ value[4] = 43; /* Max Distortion inter */
+ value[5] = 43; /* Max Distortion intra */
+ } else {
+ value[0] = 20; /* PCM Threshold 1 */
+ value[1] = 12; /* PCM Threshold 2 */
+ value[2] = 255; /* Distortion Threshold d7-d0 */
+ value[3] = 0; /* Distortion Threshold d11-d8 */
+ value[4] = 43; /* Max Distortion d7-d0 */
+ value[5] = 0; /* Max Distortion d8 */
}
if (!USBVISION_IS_OPERATIONAL(usbvision))
@@ -2059,10 +1974,7 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
if (rc < 0) {
printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
"reconnect or reload driver.\n", proc, rc);
- return rc;
}
-
-
return rc;
}
@@ -2085,9 +1997,9 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
return 0;
/* Set input format expected from decoder*/
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) {
- value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1;
- } else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
+ if (usbvision_device_data[usbvision->dev_model].vin_reg1_override) {
+ value[0] = usbvision_device_data[usbvision->dev_model].vin_reg1;
+ } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
/* SAA7113 uses 8 bit output */
value[0] = USBVISION_8_422_SYNC;
} else {
@@ -2105,53 +2017,53 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
}
- if (usbvision->tvnormId & V4L2_STD_PAL) {
+ if (usbvision->tvnorm_id & V4L2_STD_PAL) {
value[0] = 0xC0;
- value[1] = 0x02; //0x02C0 -> 704 Input video line length
+ value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */
value[2] = 0x20;
- value[3] = 0x01; //0x0120 -> 288 Input video n. of lines
+ value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */
value[4] = 0x60;
- value[5] = 0x00; //0x0060 -> 96 Input video h offset
+ value[5] = 0x00; /* 0x0060 -> 96 Input video h offset */
value[6] = 0x16;
- value[7] = 0x00; //0x0016 -> 22 Input video v offset
- } else if (usbvision->tvnormId & V4L2_STD_SECAM) {
+ value[7] = 0x00; /* 0x0016 -> 22 Input video v offset */
+ } else if (usbvision->tvnorm_id & V4L2_STD_SECAM) {
value[0] = 0xC0;
- value[1] = 0x02; //0x02C0 -> 704 Input video line length
+ value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */
value[2] = 0x20;
- value[3] = 0x01; //0x0120 -> 288 Input video n. of lines
+ value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */
value[4] = 0x01;
- value[5] = 0x00; //0x0001 -> 01 Input video h offset
+ value[5] = 0x00; /* 0x0001 -> 01 Input video h offset */
value[6] = 0x01;
- value[7] = 0x00; //0x0001 -> 01 Input video v offset
+ value[7] = 0x00; /* 0x0001 -> 01 Input video v offset */
} else { /* V4L2_STD_NTSC */
value[0] = 0xD0;
- value[1] = 0x02; //0x02D0 -> 720 Input video line length
+ value[1] = 0x02; /* 0x02D0 -> 720 Input video line length */
value[2] = 0xF0;
- value[3] = 0x00; //0x00F0 -> 240 Input video number of lines
+ value[3] = 0x00; /* 0x00F0 -> 240 Input video number of lines */
value[4] = 0x50;
- value[5] = 0x00; //0x0050 -> 80 Input video h offset
+ value[5] = 0x00; /* 0x0050 -> 80 Input video h offset */
value[6] = 0x10;
- value[7] = 0x00; //0x0010 -> 16 Input video v offset
+ value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
}
- if (usbvision_device_data[usbvision->DevModel].X_Offset >= 0) {
- value[4]=usbvision_device_data[usbvision->DevModel].X_Offset & 0xff;
- value[5]=(usbvision_device_data[usbvision->DevModel].X_Offset & 0x0300) >> 8;
+ if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
+ value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
+ value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
}
- if (adjust_X_Offset != -1) {
- value[4] = adjust_X_Offset & 0xff;
- value[5] = (adjust_X_Offset & 0x0300) >> 8;
+ if (adjust_x_offset != -1) {
+ value[4] = adjust_x_offset & 0xff;
+ value[5] = (adjust_x_offset & 0x0300) >> 8;
}
- if (usbvision_device_data[usbvision->DevModel].Y_Offset >= 0) {
- value[6]=usbvision_device_data[usbvision->DevModel].Y_Offset & 0xff;
- value[7]=(usbvision_device_data[usbvision->DevModel].Y_Offset & 0x0300) >> 8;
+ if (usbvision_device_data[usbvision->dev_model].y_offset >= 0) {
+ value[6] = usbvision_device_data[usbvision->dev_model].y_offset & 0xff;
+ value[7] = (usbvision_device_data[usbvision->dev_model].y_offset & 0x0300) >> 8;
}
- if (adjust_Y_Offset != -1) {
- value[6] = adjust_Y_Offset & 0xff;
- value[7] = (adjust_Y_Offset & 0x0300) >> 8;
+ if (adjust_y_offset != -1) {
+ value[6] = adjust_y_offset & 0xff;
+ value[7] = (adjust_y_offset & 0x0300) >> 8;
}
rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
@@ -2167,15 +2079,14 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */
- if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){
- dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv;
- }
- else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
- /* This changes as the fine sync control changes. Further investigation necessary */
+ if (usbvision_device_data[usbvision->dev_model].dvi_yuv_override) {
+ dvi_yuv_value = usbvision_device_data[usbvision->dev_model].dvi_yuv;
+ } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
+ /* This changes as the fine sync control changes. Further investigation necessary */
dvi_yuv_value = 0x06;
}
- return (usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value));
+ return usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value);
}
@@ -2192,7 +2103,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
int rc;
unsigned char value[8];
- if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
+ if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
value[0] = 0x42;
value[1] = 0x71;
value[2] = 0xff;
@@ -2201,11 +2112,10 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
value[5] = 0xe0;
value[6] = 0x71;
value[7] = 0xff;
- // UR: 0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte)
- // FDL: 0x00000-0x0E099 = 57498 Words
- // VDW: 0x0E3FF-0x3FFFF
- }
- else {
+ /* UR: 0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte) */
+ /* FDL: 0x00000-0x0E099 = 57498 Words */
+ /* VDW: 0x0E3FF-0x3FFFF */
+ } else {
value[0] = 0x42;
value[1] = 0x00;
value[2] = 0xff;
@@ -2218,14 +2128,14 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
/* These are the values of the address of the video buffer,
* they have to be loaded into the USBVISION_DRM_PRM1-8
*
- * Start address of video output buffer for read: drm_prm1-2 -> 0x00000
- * End address of video output buffer for read: drm_prm1-3 -> 0x1ffff
- * Start address of video frame delay buffer: drm_prm1-4 -> 0x20000
+ * Start address of video output buffer for read: drm_prm1-2 -> 0x00000
+ * End address of video output buffer for read: drm_prm1-3 -> 0x1ffff
+ * Start address of video frame delay buffer: drm_prm1-4 -> 0x20000
* Only used in compressed mode
- * End address of video frame delay buffer: drm_prm1-5-6 -> 0x3ffff
+ * End address of video frame delay buffer: drm_prm1-5-6 -> 0x3ffff
* Only used in compressed mode
- * Start address of video output buffer for write: drm_prm1-7 -> 0x00000
- * End address of video output buffer for write: drm_prm1-8 -> 0x1ffff
+ * Start address of video output buffer for write: drm_prm1-7 -> 0x00000
+ * End address of video output buffer for write: drm_prm1-8 -> 0x1ffff
*/
if (!USBVISION_IS_OPERATIONAL(usbvision))
@@ -2243,8 +2153,9 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
}
/* Restart the video buffer logic */
- if ((rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR |
- USBVISION_RES_FDL | USBVISION_RES_VDW)) < 0)
+ rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR |
+ USBVISION_RES_FDL | USBVISION_RES_VDW);
+ if (rc < 0)
return rc;
rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00);
@@ -2261,23 +2172,22 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
int usbvision_power_on(struct usb_usbvision *usbvision)
{
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_FUNC, "");
usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_RES2);
+ USBVISION_SSPND_EN | USBVISION_RES2);
usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID);
- errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
- if (errCode == 1) {
+ USBVISION_SSPND_EN | USBVISION_PWR_VID);
+ err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
+ USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
+ if (err_code == 1)
usbvision->power = 1;
- }
- PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode<0)?"ERROR":"power is on", errCode);
- return errCode;
+ PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code < 0) ? "ERROR" : "power is on", err_code);
+ return err_code;
}
@@ -2285,53 +2195,50 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
* usbvision timer stuff
*/
-// to call usbvision_power_off from task queue
+/* to call usbvision_power_off from task queue */
static void call_usbvision_power_off(struct work_struct *work)
{
- struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, powerOffWork);
+ struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work);
PDEBUG(DBG_FUNC, "");
- if(mutex_lock_interruptible(&usbvision->lock)) {
+ if (mutex_lock_interruptible(&usbvision->v4l2_lock))
return;
- }
-
- if(usbvision->user == 0) {
+ if (usbvision->user == 0) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
- mutex_unlock(&usbvision->lock);
+ mutex_unlock(&usbvision->v4l2_lock);
}
-static void usbvision_powerOffTimer(unsigned long data)
+static void usbvision_power_off_timer(unsigned long data)
{
- struct usb_usbvision *usbvision = (void *) data;
+ struct usb_usbvision *usbvision = (void *)data;
PDEBUG(DBG_FUNC, "");
- del_timer(&usbvision->powerOffTimer);
- INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off);
- (void) schedule_work(&usbvision->powerOffWork);
+ del_timer(&usbvision->power_off_timer);
+ INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off);
+ (void) schedule_work(&usbvision->power_off_work);
}
-void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision)
+void usbvision_init_power_off_timer(struct usb_usbvision *usbvision)
{
- init_timer(&usbvision->powerOffTimer);
- usbvision->powerOffTimer.data = (long) usbvision;
- usbvision->powerOffTimer.function = usbvision_powerOffTimer;
+ init_timer(&usbvision->power_off_timer);
+ usbvision->power_off_timer.data = (long)usbvision;
+ usbvision->power_off_timer.function = usbvision_power_off_timer;
}
-void usbvision_set_powerOffTimer(struct usb_usbvision *usbvision)
+void usbvision_set_power_off_timer(struct usb_usbvision *usbvision)
{
- mod_timer(&usbvision->powerOffTimer, jiffies + USBVISION_POWEROFF_TIME);
+ mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME);
}
-void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision)
+void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision)
{
- if (timer_pending(&usbvision->powerOffTimer)) {
- del_timer(&usbvision->powerOffTimer);
- }
+ if (timer_pending(&usbvision->power_off_timer))
+ del_timer(&usbvision->power_off_timer);
}
/*
@@ -2341,14 +2248,10 @@ void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision)
*/
int usbvision_begin_streaming(struct usb_usbvision *usbvision)
{
- int errCode = 0;
-
- if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
+ if (usbvision->isoc_mode == ISOC_MODE_COMPRESS)
usbvision_init_compression(usbvision);
- }
- errCode = usbvision_write_reg(usbvision, USBVISION_VIN_REG2, USBVISION_NOHVALID |
- usbvision->Vin_Reg2_Preset);
- return errCode;
+ return usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
+ USBVISION_NOHVALID | usbvision->vin_reg2_preset);
}
/*
@@ -2360,25 +2263,24 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision)
{
int ret;
- if (
- (ret =
- usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID)) < 0)
+ ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
+ USBVISION_SSPND_EN | USBVISION_PWR_VID);
+ if (ret < 0)
return ret;
- if (
- (ret =
- usbvision_write_reg(usbvision, USBVISION_PWR_REG,
+ ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
USBVISION_SSPND_EN | USBVISION_PWR_VID |
- USBVISION_RES2)) < 0)
+ USBVISION_RES2);
+ if (ret < 0)
return ret;
- if (
- (ret =
- usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
+ ret = usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
USBVISION_KEEP_BLANK | USBVISION_NOHVALID |
- usbvision->Vin_Reg2_Preset)) < 0) return ret;
+ usbvision->vin_reg2_preset);
+ if (ret < 0)
+ return ret;
/* TODO: schedule timeout */
- while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1);
+ while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1)
+ ;
return 0;
}
@@ -2386,27 +2288,27 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision)
int usbvision_audio_off(struct usb_usbvision *usbvision)
{
if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) {
- printk(KERN_ERR "usbvision_audio_off: can't wirte reg\n");
+ printk(KERN_ERR "usbvision_audio_off: can't write reg\n");
return -1;
}
- usbvision->AudioMute = 0;
- usbvision->AudioChannel = USBVISION_AUDIO_MUTE;
+ usbvision->audio_mute = 0;
+ usbvision->audio_channel = USBVISION_AUDIO_MUTE;
return 0;
}
-int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel)
+int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
{
- if (!usbvision->AudioMute) {
- if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, AudioChannel) < 0) {
+ if (!usbvision->audio_mute) {
+ if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, audio_channel) < 0) {
printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n");
return -1;
}
}
- usbvision->AudioChannel = AudioChannel;
+ usbvision->audio_channel = audio_channel;
return 0;
}
-int usbvision_setup(struct usb_usbvision *usbvision,int format)
+int usbvision_setup(struct usb_usbvision *usbvision, int format)
{
usbvision_set_video_format(usbvision, format);
usbvision_set_dram_settings(usbvision);
@@ -2421,27 +2323,28 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format)
int usbvision_set_alternate(struct usb_usbvision *dev)
{
- int errCode, prev_alt = dev->ifaceAlt;
+ int err_code, prev_alt = dev->iface_alt;
int i;
- dev->ifaceAlt=0;
- for(i=0;i< dev->num_alt; i++)
- if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt])
- dev->ifaceAlt=i;
-
- if (dev->ifaceAlt != prev_alt) {
- dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt];
- PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
- errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
- if (errCode < 0) {
+ dev->iface_alt = 0;
+ for (i = 0; i < dev->num_alt; i++)
+ if (dev->alt_max_pkt_size[i] > dev->alt_max_pkt_size[dev->iface_alt])
+ dev->iface_alt = i;
+
+ if (dev->iface_alt != prev_alt) {
+ dev->isoc_packet_size = dev->alt_max_pkt_size[dev->iface_alt];
+ PDEBUG(DBG_FUNC, "setting alternate %d with max_packet_size=%u",
+ dev->iface_alt, dev->isoc_packet_size);
+ err_code = usb_set_interface(dev->dev, dev->iface, dev->iface_alt);
+ if (err_code < 0) {
dev_err(&dev->dev->dev,
"cannot change alternate number to %d (error=%i)\n",
- dev->ifaceAlt, errCode);
- return errCode;
+ dev->iface_alt, err_code);
+ return err_code;
}
}
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize);
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isoc_packet_size);
return 0;
}
@@ -2453,27 +2356,27 @@ int usbvision_set_alternate(struct usb_usbvision *dev)
int usbvision_init_isoc(struct usb_usbvision *usbvision)
{
struct usb_device *dev = usbvision->dev;
- int bufIdx, errCode, regValue;
+ int buf_idx, err_code, reg_value;
int sb_size;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -EFAULT;
- usbvision->curFrame = NULL;
+ usbvision->cur_frame = NULL;
scratch_reset(usbvision);
/* Alternate interface 1 is is the biggest frame size */
- errCode = usbvision_set_alternate(usbvision);
- if (errCode < 0) {
- usbvision->last_error = errCode;
+ err_code = usbvision_set_alternate(usbvision);
+ if (err_code < 0) {
+ usbvision->last_error = err_code;
return -EBUSY;
}
- sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
+ sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
- regValue = (16 - usbvision_read_reg(usbvision,
+ reg_value = (16 - usbvision_read_reg(usbvision,
USBVISION_ALTER_REG)) & 0x0F;
- usbvision->usb_bandwidth = regValue >> 1;
+ usbvision->usb_bandwidth = reg_value >> 1;
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
usbvision->usb_bandwidth);
@@ -2481,7 +2384,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
/* We double buffer the Iso lists */
- for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
+ for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
int j, k;
struct urb *urb;
@@ -2491,8 +2394,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
"%s: usb_alloc_urb() failed\n", __func__);
return -ENOMEM;
}
- usbvision->sbuf[bufIdx].urb = urb;
- usbvision->sbuf[bufIdx].data =
+ usbvision->sbuf[buf_idx].urb = urb;
+ usbvision->sbuf[buf_idx].data =
usb_alloc_coherent(usbvision->dev,
sb_size,
GFP_KERNEL,
@@ -2502,31 +2405,31 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
urb->interval = 1;
- urb->transfer_buffer = usbvision->sbuf[bufIdx].data;
- urb->complete = usbvision_isocIrq;
+ urb->transfer_buffer = usbvision->sbuf[buf_idx].data;
+ urb->complete = usbvision_isoc_irq;
urb->number_of_packets = USBVISION_URB_FRAMES;
urb->transfer_buffer_length =
- usbvision->isocPacketSize * USBVISION_URB_FRAMES;
+ usbvision->isoc_packet_size * USBVISION_URB_FRAMES;
for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
- k += usbvision->isocPacketSize) {
+ k += usbvision->isoc_packet_size) {
urb->iso_frame_desc[j].offset = k;
urb->iso_frame_desc[j].length =
- usbvision->isocPacketSize;
+ usbvision->isoc_packet_size;
}
}
/* Submit all URBs */
- for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
- errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
+ for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
+ err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb,
GFP_KERNEL);
- if (errCode) {
+ if (err_code) {
dev_err(&usbvision->dev->dev,
"%s: usb_submit_urb(%d) failed: error %d\n",
- __func__, bufIdx, errCode);
+ __func__, buf_idx, err_code);
}
}
- usbvision->streaming = Stream_Idle;
+ usbvision->streaming = stream_idle;
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
__func__,
usbvision->video_endp);
@@ -2542,47 +2445,46 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
*/
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
{
- int bufIdx, errCode, regValue;
- int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
+ int buf_idx, err_code, reg_value;
+ int sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
- if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
+ if ((usbvision->streaming == stream_off) || (usbvision->dev == NULL))
return;
/* Unschedule all of the iso td's */
- for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
- usb_kill_urb(usbvision->sbuf[bufIdx].urb);
- if (usbvision->sbuf[bufIdx].data){
+ for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
+ usb_kill_urb(usbvision->sbuf[buf_idx].urb);
+ if (usbvision->sbuf[buf_idx].data) {
usb_free_coherent(usbvision->dev,
sb_size,
- usbvision->sbuf[bufIdx].data,
- usbvision->sbuf[bufIdx].urb->transfer_dma);
+ usbvision->sbuf[buf_idx].data,
+ usbvision->sbuf[buf_idx].urb->transfer_dma);
}
- usb_free_urb(usbvision->sbuf[bufIdx].urb);
- usbvision->sbuf[bufIdx].urb = NULL;
+ usb_free_urb(usbvision->sbuf[buf_idx].urb);
+ usbvision->sbuf[buf_idx].urb = NULL;
}
- PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__);
- usbvision->streaming = Stream_Off;
+ PDEBUG(DBG_ISOC, "%s: streaming=stream_off\n", __func__);
+ usbvision->streaming = stream_off;
if (!usbvision->remove_pending) {
-
/* Set packet size to 0 */
- usbvision->ifaceAlt=0;
- errCode = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->ifaceAlt);
- if (errCode < 0) {
+ usbvision->iface_alt = 0;
+ err_code = usb_set_interface(usbvision->dev, usbvision->iface,
+ usbvision->iface_alt);
+ if (err_code < 0) {
dev_err(&usbvision->dev->dev,
"%s: usb_set_interface() failed: error %d\n",
- __func__, errCode);
- usbvision->last_error = errCode;
+ __func__, err_code);
+ usbvision->last_error = err_code;
}
- regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize =
- (regValue == 0) ? 0 : (regValue * 64) - 1;
+ reg_value = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+ usbvision->isoc_packet_size =
+ (reg_value == 0) ? 0 : (reg_value * 64) - 1;
PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
- usbvision->isocPacketSize);
+ usbvision->isoc_packet_size);
- usbvision->usb_bandwidth = regValue >> 1;
+ usbvision->usb_bandwidth = reg_value >> 1;
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
usbvision->usb_bandwidth);
}
@@ -2592,39 +2494,38 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
{
/* inputs #0 and #3 are constant for every SAA711x. */
/* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
- int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
- int audio[]= {1, 0, 0, 0};
- //channel 0 is TV with audiochannel 1 (tuner mono)
- //channel 1 is Composite with audio channel 0 (line in)
- //channel 2 is S-Video with audio channel 0 (line in)
- //channel 3 is additional video inputs to the device with audio channel 0 (line in)
+ int mode[4] = { SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3 };
+ int audio[] = { 1, 0, 0, 0 };
+ /* channel 0 is TV with audiochannel 1 (tuner mono) */
+ /* channel 1 is Composite with audio channel 0 (line in) */
+ /* channel 2 is S-Video with audio channel 0 (line in) */
+ /* channel 3 is additional video inputs to the device with audio channel 0 (line in) */
RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs);
usbvision->ctl_input = channel;
- // set the new channel
- // Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video
- // Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red
-
- switch (usbvision_device_data[usbvision->DevModel].Codec) {
- case CODEC_SAA7113:
- mode[1] = SAA7115_COMPOSITE2;
- if (SwitchSVideoInput) {
- /* To handle problems with S-Video Input for
- * some devices. Use SwitchSVideoInput
- * parameter when loading the module.*/
- mode[2] = SAA7115_COMPOSITE1;
- }
- else {
- mode[2] = SAA7115_SVIDEO1;
- }
- break;
- case CODEC_SAA7111:
- default:
- /* modes for saa7111 */
- mode[1] = SAA7115_COMPOSITE1;
+ /* set the new channel */
+ /* Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video */
+ /* Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red */
+
+ switch (usbvision_device_data[usbvision->dev_model].codec) {
+ case CODEC_SAA7113:
+ mode[1] = SAA7115_COMPOSITE2;
+ if (switch_svideo_input) {
+ /* To handle problems with S-Video Input for
+ * some devices. Use switch_svideo_input
+ * parameter when loading the module.*/
+ mode[2] = SAA7115_COMPOSITE1;
+ } else {
mode[2] = SAA7115_SVIDEO1;
- break;
+ }
+ break;
+ case CODEC_SAA7111:
+ default:
+ /* modes for saa7111 */
+ mode[1] = SAA7115_COMPOSITE1;
+ mode[2] = SAA7115_SVIDEO1;
+ break;
}
call_all(usbvision, video, s_routing, mode[channel], 0, 0);
usbvision_set_audio(usbvision, audio[channel]);
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index e3bbae26e3ce..05b1344181cd 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -28,18 +28,18 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include "usbvision.h"
-#define DBG_I2C 1<<0
+#define DBG_I2C (1 << 0)
static int i2c_debug;
-module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver
+module_param(i2c_debug, int, 0644); /* debug_i2c_usb mode of the device driver */
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
#define PDEBUG(level, fmt, args...) { \
@@ -72,8 +72,8 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_I2C,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C, "Maybe there's no device at this address");
}
return ret;
}
@@ -96,8 +96,8 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_I2C,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C, "Maybe there's no device at this address");
}
return ret;
}
@@ -143,9 +143,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
else
ret = try_write_address(i2c_adap, addr, retries);
- if (ret != 1) {
+ if (ret != 1)
return -EREMOTEIO;
- }
}
return 0;
}
@@ -164,22 +163,20 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
pmsg = &msgs[i];
ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
if (ret != 0) {
- PDEBUG(DBG_I2C,"got NAK from device, message #%d", i);
+ PDEBUG(DBG_I2C, "got NAK from device, message #%d", i);
return (ret < 0) ? ret : -EREMOTEIO;
}
if (pmsg->flags & I2C_M_RD) {
/* read bytes into buffer */
ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
- if (ret < pmsg->len) {
+ if (ret < pmsg->len)
return (ret < 0) ? ret : -EREMOTEIO;
- }
} else {
/* write bytes from buffer */
ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
- if (ret < pmsg->len) {
+ if (ret < pmsg->len)
return (ret < 0) ? ret : -EREMOTEIO;
- }
}
}
return num;
@@ -219,7 +216,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name,
usbvision->dev->bus->busnum, usbvision->dev->devpath);
- PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
+ PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name);
usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
@@ -244,31 +241,31 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
/* Request the load of the i2c modules we need */
- switch (usbvision_device_data[usbvision->DevModel].Codec) {
+ switch (usbvision_device_data[usbvision->dev_model].codec) {
case CODEC_SAA7113:
case CODEC_SAA7111:
/* Without this delay the detection of the saa711x is
hit-and-miss. */
mdelay(10);
v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"saa7115_auto", 0, saa711x_addrs);
break;
}
- if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
+ if (usbvision_device_data[usbvision->dev_model].tuner == 1) {
struct v4l2_subdev *sd;
enum v4l2_i2c_tuner_type type;
struct tuner_setup tun_setup;
sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
/* depending on whether we found a demod or not, select
the tuner type. */
type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(type));
if (sd == NULL)
@@ -293,7 +290,7 @@ int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
i2c_del_adapter(&(usbvision->i2c_adap));
usbvision->registered_i2c = 0;
- PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
+ PDEBUG(DBG_I2C, "i2c bus for %s unregistered", usbvision->i2c_adap.name);
return 0;
}
@@ -355,9 +352,9 @@ usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
if (i2c_debug & DBG_I2C) {
int idx;
- for (idx = 0; idx < len; idx++) {
- PDEBUG(DBG_I2C,"read %x from address %x", (unsigned char)buf[idx], addr);
- }
+
+ for (idx = 0; idx < len; idx++)
+ PDEBUG(DBG_I2C, "read %x from address %x", (unsigned char)buf[idx], addr);
}
return len;
}
@@ -416,9 +413,9 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
if (i2c_debug & DBG_I2C) {
int idx;
- for (idx = 0; idx < len; idx++) {
- PDEBUG(DBG_I2C,"wrote %x at address %x", (unsigned char)buf[idx], addr);
- }
+
+ for (idx = 0; idx < len; idx++)
+ PDEBUG(DBG_I2C, "wrote %x at address %x", (unsigned char)buf[idx], addr);
}
return len;
}
@@ -426,18 +423,18 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len)
{
- char *bufPtr = buf;
+ char *buf_ptr = buf;
int retval;
int wrcount = 0;
int count;
- int maxLen = 4;
+ int max_len = 4;
while (len > 0) {
- count = (len > maxLen) ? maxLen : len;
- retval = usbvision_i2c_write_max4(usbvision, addr, bufPtr, count);
+ count = (len > max_len) ? max_len : len;
+ retval = usbvision_i2c_write_max4(usbvision, addr, buf_ptr, count);
if (retval > 0) {
len -= count;
- bufPtr += count;
+ buf_ptr += count;
wrcount += count;
} else
return (retval < 0) ? retval : -EFAULT;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 011c0c386995..6083137f0bf8 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -56,7 +56,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
@@ -70,8 +70,8 @@
#include "usbvision.h"
#include "usbvision-cards.h"
-#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>,\
- Dwaine Garden <DwaineGarden@rogers.com>"
+#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, \
+Dwaine Garden <DwaineGarden@rogers.com>"
#define DRIVER_NAME "usbvision"
#define DRIVER_ALIAS "USBVision"
#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
@@ -82,9 +82,9 @@
#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\
USBVISION_DRIVER_VERSION_MINOR,\
USBVISION_DRIVER_VERSION_PATCHLEVEL)
-#define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR)\
- "." __stringify(USBVISION_DRIVER_VERSION_MINOR)\
- "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL)
+#define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR) \
+"." __stringify(USBVISION_DRIVER_VERSION_MINOR) \
+"." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL)
#define ENABLE_HEXDUMP 0 /* Enable if you need it */
@@ -96,16 +96,16 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL)
__func__, __LINE__ , ## args); \
}
#else
- #define PDEBUG(level, fmt, args...) do {} while(0)
+ #define PDEBUG(level, fmt, args...) do {} while (0)
#endif
-#define DBG_IO 1<<1
-#define DBG_PROBE 1<<2
-#define DBG_MMAP 1<<3
+#define DBG_IO (1 << 1)
+#define DBG_PROBE (1 << 2)
+#define DBG_MMAP (1 << 3)
-//String operations
-#define rmspace(str) while(*str==' ') str++;
-#define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++;
+/* String operations */
+#define rmspace(str) while (*str == ' ') str++;
+#define goto2next(str) while (*str != ' ') str++; while (*str == ' ') str++;
/* sequential number of usbvision device */
@@ -118,7 +118,7 @@ static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {
{ 1, 4, 32, V4L2_PIX_FMT_RGB32 , "RGB32" },
{ 1, 2, 16, V4L2_PIX_FMT_RGB555 , "RGB555" },
{ 1, 2, 16, V4L2_PIX_FMT_YUYV , "YUV422" },
- { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, // 1.5 !
+ { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, /* 1.5 ! */
{ 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" }
};
@@ -127,11 +127,11 @@ static void usbvision_release(struct usb_usbvision *usbvision);
/* Default initialization of device driver parameters */
/* Set the default format for ISOC endpoint */
-static int isocMode = ISOC_MODE_COMPRESS;
+static int isoc_mode = ISOC_MODE_COMPRESS;
/* Set the default Debug Mode of the device driver */
static int video_debug;
/* Set the default device to power on at startup */
-static int PowerOnAtOpen = 1;
+static int power_on_at_open = 1;
/* Sequential Number of Video Device */
static int video_nr = -1;
/* Sequential Number of Radio Device */
@@ -140,20 +140,20 @@ static int radio_nr = -1;
/* Grab parameters for the device driver */
/* Showing parameters under SYSFS */
-module_param(isocMode, int, 0444);
+module_param(isoc_mode, int, 0444);
module_param(video_debug, int, 0444);
-module_param(PowerOnAtOpen, int, 0444);
+module_param(power_on_at_open, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
-MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
+MODULE_PARM_DESC(isoc_mode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
-MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)");
+MODULE_PARM_DESC(power_on_at_open, " Set the default device to power on when device is opened. Default: 1 (On)");
MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
-// Misc stuff
+/* Misc stuff */
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
@@ -192,7 +192,7 @@ static ssize_t show_model(struct device *cd,
container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
- usbvision_device_data[usbvision->DevModel].ModelString);
+ usbvision_device_data[usbvision->dev_model].model_string);
}
static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
@@ -205,7 +205,7 @@ static ssize_t show_hue(struct device *cd,
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_HUE;
ctrl.value = 0;
- if(usbvision->user)
+ if (usbvision->user)
call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
@@ -220,7 +220,7 @@ static ssize_t show_contrast(struct device *cd,
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTRAST;
ctrl.value = 0;
- if(usbvision->user)
+ if (usbvision->user)
call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
@@ -235,7 +235,7 @@ static ssize_t show_brightness(struct device *cd,
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = 0;
- if(usbvision->user)
+ if (usbvision->user)
call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
@@ -250,7 +250,7 @@ static ssize_t show_saturation(struct device *cd,
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_SATURATION;
ctrl.value = 0;
- if(usbvision->user)
+ if (usbvision->user)
call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
@@ -263,7 +263,7 @@ static ssize_t show_streaming(struct device *cd,
container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
- YES_NO(usbvision->streaming==Stream_On?1:0));
+ YES_NO(usbvision->streaming == stream_on ? 1 : 0));
}
static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
@@ -274,7 +274,7 @@ static ssize_t show_compression(struct device *cd,
container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
- YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
+ YES_NO(usbvision->isoc_mode == ISOC_MODE_COMPRESS));
}
static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
@@ -284,42 +284,43 @@ static ssize_t show_device_bridge(struct device *cd,
struct video_device *vdev =
container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%d\n", usbvision->bridgeType);
+ return sprintf(buf, "%d\n", usbvision->bridge_type);
}
static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
static void usbvision_create_sysfs(struct video_device *vdev)
{
int res;
+
if (!vdev)
return;
do {
res = device_create_file(&vdev->dev, &dev_attr_version);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_model);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_hue);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_contrast);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_brightness);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_saturation);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_streaming);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_compression);
- if (res<0)
+ if (res < 0)
break;
res = device_create_file(&vdev->dev, &dev_attr_bridge);
- if (res>=0)
+ if (res >= 0)
return;
} while (0);
@@ -352,24 +353,23 @@ static void usbvision_remove_sysfs(struct video_device *vdev)
static int usbvision_v4l2_open(struct file *file)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_IO, "open");
- mutex_lock(&usbvision->lock);
- usbvision_reset_powerOffTimer(usbvision);
+ usbvision_reset_power_off_timer(usbvision);
if (usbvision->user)
- errCode = -EBUSY;
+ err_code = -EBUSY;
else {
/* Allocate memory for the scratch ring buffer */
- errCode = usbvision_scratch_alloc(usbvision);
- if (isocMode==ISOC_MODE_COMPRESS) {
+ err_code = usbvision_scratch_alloc(usbvision);
+ if (isoc_mode == ISOC_MODE_COMPRESS) {
/* Allocate intermediate decompression buffers
only if needed */
- errCode = usbvision_decompress_alloc(usbvision);
+ err_code = usbvision_decompress_alloc(usbvision);
}
- if (errCode) {
+ if (err_code) {
/* Deallocate all buffers if trouble */
usbvision_scratch_free(usbvision);
usbvision_decompress_free(usbvision);
@@ -377,7 +377,7 @@ static int usbvision_v4l2_open(struct file *file)
}
/* If so far no errors then we shall start the camera */
- if (!errCode) {
+ if (!err_code) {
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
usbvision_i2c_register(usbvision);
@@ -386,21 +386,21 @@ static int usbvision_v4l2_open(struct file *file)
/* Send init sequence only once, it's large! */
if (!usbvision->initialized) {
int setup_ok = 0;
- setup_ok = usbvision_setup(usbvision,isocMode);
+ setup_ok = usbvision_setup(usbvision, isoc_mode);
if (setup_ok)
usbvision->initialized = 1;
else
- errCode = -EBUSY;
+ err_code = -EBUSY;
}
- if (!errCode) {
+ if (!err_code) {
usbvision_begin_streaming(usbvision);
- errCode = usbvision_init_isoc(usbvision);
+ err_code = usbvision_init_isoc(usbvision);
/* device must be initialized before isoc transfer */
- usbvision_muxsel(usbvision,0);
+ usbvision_muxsel(usbvision, 0);
usbvision->user++;
} else {
- if (PowerOnAtOpen) {
+ if (power_on_at_open) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
@@ -412,8 +412,7 @@ static int usbvision_v4l2_open(struct file *file)
usbvision_empty_framequeues(usbvision);
PDEBUG(DBG_IO, "success");
- mutex_unlock(&usbvision->lock);
- return errCode;
+ return err_code;
}
/*
@@ -429,7 +428,6 @@ static int usbvision_v4l2_close(struct file *file)
struct usb_usbvision *usbvision = video_drvdata(file);
PDEBUG(DBG_IO, "close");
- mutex_lock(&usbvision->lock);
usbvision_audio_off(usbvision);
usbvision_restart_isoc(usbvision);
@@ -442,15 +440,13 @@ static int usbvision_v4l2_close(struct file *file)
usbvision->user--;
- if (PowerOnAtOpen) {
+ if (power_on_at_open) {
/* power off in a little while
to avoid off/on every close/open short sequences */
- usbvision_set_powerOffTimer(usbvision);
+ usbvision_set_power_off_timer(usbvision);
usbvision->initialized = 0;
}
- mutex_unlock(&usbvision->lock);
-
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
@@ -468,55 +464,55 @@ static int usbvision_v4l2_close(struct file *file)
*
*/
#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register (struct file *file, void *priv,
+static int vidioc_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int errCode;
+ int err_code;
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
/* NT100x has a 8-bit register space */
- errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
- if (errCode < 0) {
+ err_code = usbvision_read_reg(usbvision, reg->reg&0xff);
+ if (err_code < 0) {
dev_err(&usbvision->vdev->dev,
"%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
- __func__, errCode);
- return errCode;
+ __func__, err_code);
+ return err_code;
}
- reg->val = errCode;
+ reg->val = err_code;
reg->size = 1;
return 0;
}
-static int vidioc_s_register (struct file *file, void *priv,
+static int vidioc_s_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int errCode;
+ int err_code;
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
/* NT100x has a 8-bit register space */
- errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
- if (errCode < 0) {
+ err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val);
+ if (err_code < 0) {
dev_err(&usbvision->vdev->dev,
"%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
- __func__, errCode);
- return errCode;
+ __func__, err_code);
+ return err_code;
}
return 0;
}
#endif
-static int vidioc_querycap (struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *vc)
{
struct usb_usbvision *usbvision = video_drvdata(file);
strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
strlcpy(vc->card,
- usbvision_device_data[usbvision->DevModel].ModelString,
+ usbvision_device_data[usbvision->dev_model].model_string,
sizeof(vc->card));
usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
@@ -528,7 +524,7 @@ static int vidioc_querycap (struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_input (struct file *file, void *priv,
+static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *vi)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -536,16 +532,16 @@ static int vidioc_enum_input (struct file *file, void *priv,
if (vi->index >= usbvision->video_inputs)
return -EINVAL;
- if (usbvision->have_tuner) {
+ if (usbvision->have_tuner)
chan = vi->index;
- } else {
- chan = vi->index + 1; /*skip Television string*/
- }
+ else
+ chan = vi->index + 1; /* skip Television string*/
+
/* Determine the requested input characteristics
specific for each usbvision card model */
- switch(chan) {
+ switch (chan) {
case 0:
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ if (usbvision_device_data[usbvision->dev_model].video_channels == 4) {
strcpy(vi->name, "White Video Input");
} else {
strcpy(vi->name, "Television");
@@ -557,20 +553,18 @@ static int vidioc_enum_input (struct file *file, void *priv,
break;
case 1:
vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
strcpy(vi->name, "Green Video Input");
- } else {
+ else
strcpy(vi->name, "Composite Video Input");
- }
vi->std = V4L2_STD_PAL;
break;
case 2:
vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) {
+ if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
strcpy(vi->name, "Yellow Video Input");
- } else {
+ else
strcpy(vi->name, "S-Video Input");
- }
vi->std = V4L2_STD_PAL;
break;
case 3:
@@ -582,7 +576,7 @@ static int vidioc_enum_input (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_input (struct file *file, void *priv, unsigned int *input)
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -590,46 +584,42 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *input)
return 0;
}
-static int vidioc_s_input (struct file *file, void *priv, unsigned int input)
+static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
{
struct usb_usbvision *usbvision = video_drvdata(file);
if (input >= usbvision->video_inputs)
return -EINVAL;
- mutex_lock(&usbvision->lock);
usbvision_muxsel(usbvision, input);
usbvision_set_input(usbvision);
usbvision_set_output(usbvision,
usbvision->curwidth,
usbvision->curheight);
- mutex_unlock(&usbvision->lock);
return 0;
}
-static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- usbvision->tvnormId=*id;
+ usbvision->tvnorm_id = *id;
- mutex_lock(&usbvision->lock);
- call_all(usbvision, core, s_std, usbvision->tvnormId);
- mutex_unlock(&usbvision->lock);
+ call_all(usbvision, core, s_std, usbvision->tvnorm_id);
/* propagate the change to the decoder */
usbvision_muxsel(usbvision, usbvision->ctl_input);
return 0;
}
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *vt)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- if (!usbvision->have_tuner || vt->index) // Only tuner 0
+ if (!usbvision->have_tuner || vt->index) /* Only tuner 0 */
return -EINVAL;
- if(usbvision->radio) {
+ if (usbvision->radio) {
strcpy(vt->name, "Radio");
vt->type = V4L2_TUNER_RADIO;
} else {
@@ -641,12 +631,12 @@ static int vidioc_g_tuner (struct file *file, void *priv,
return 0;
}
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *vt)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- // Only no or one tuner for now
+ /* Only no or one tuner for now */
if (!usbvision->have_tuner || vt->index)
return -EINVAL;
/* let clients handle this */
@@ -655,28 +645,27 @@ static int vidioc_s_tuner (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *freq)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- freq->tuner = 0; // Only one tuner
- if(usbvision->radio) {
+ freq->tuner = 0; /* Only one tuner */
+ if (usbvision->radio)
freq->type = V4L2_TUNER_RADIO;
- } else {
+ else
freq->type = V4L2_TUNER_ANALOG_TV;
- }
freq->frequency = usbvision->freq;
return 0;
}
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *freq)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- // Only no or one tuner for now
+ /* Only no or one tuner for now */
if (!usbvision->have_tuner || freq->tuner)
return -EINVAL;
@@ -686,30 +675,27 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- if(usbvision->radio) {
- strcpy(a->name,"Radio");
- } else {
+ if (usbvision->radio)
+ strcpy(a->name, "Radio");
+ else
strcpy(a->name, "TV");
- }
return 0;
}
-static int vidioc_s_audio (struct file *file, void *fh,
+static int vidioc_s_audio(struct file *file, void *fh,
struct v4l2_audio *a)
{
- if(a->index) {
+ if (a->index)
return -EINVAL;
- }
-
return 0;
}
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -722,52 +708,53 @@ static int vidioc_queryctrl (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
+static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_all(usbvision, core, g_ctrl, ctrl);
+ call_all(usbvision, core, g_ctrl, ctrl);
return 0;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
+static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_all(usbvision, core, s_ctrl, ctrl);
+ call_all(usbvision, core, s_ctrl, ctrl);
return 0;
}
-static int vidioc_reqbufs (struct file *file,
+static int vidioc_reqbufs(struct file *file,
void *priv, struct v4l2_requestbuffers *vr)
{
struct usb_usbvision *usbvision = video_drvdata(file);
int ret;
- RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES);
+ RESTRICT_TO_RANGE(vr->count, 1, USBVISION_NUMFRAMES);
/* Check input validity:
the user must do a VIDEO CAPTURE and MMAP method. */
if (vr->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if(usbvision->streaming == Stream_On) {
- if ((ret = usbvision_stream_interrupt(usbvision)))
+ if (usbvision->streaming == stream_on) {
+ ret = usbvision_stream_interrupt(usbvision);
+ if (ret)
return ret;
}
usbvision_frames_free(usbvision);
usbvision_empty_framequeues(usbvision);
- vr->count = usbvision_frames_alloc(usbvision,vr->count);
+ vr->count = usbvision_frames_alloc(usbvision, vr->count);
- usbvision->curFrame = NULL;
+ usbvision->cur_frame = NULL;
return 0;
}
-static int vidioc_querybuf (struct file *file,
+static int vidioc_querybuf(struct file *file,
void *priv, struct v4l2_buffer *vb)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -775,52 +762,49 @@ static int vidioc_querybuf (struct file *file,
/* FIXME : must control
that buffers are mapped (VIDIOC_REQBUFS has been called) */
- if(vb->index>=usbvision->num_frames) {
+ if (vb->index >= usbvision->num_frames)
return -EINVAL;
- }
/* Updating the corresponding frame state */
vb->flags = 0;
frame = &usbvision->frame[vb->index];
- if(frame->grabstate >= FrameState_Ready)
+ if (frame->grabstate >= frame_state_ready)
vb->flags |= V4L2_BUF_FLAG_QUEUED;
- if(frame->grabstate >= FrameState_Done)
+ if (frame->grabstate >= frame_state_done)
vb->flags |= V4L2_BUF_FLAG_DONE;
- if(frame->grabstate == FrameState_Unused)
+ if (frame->grabstate == frame_state_unused)
vb->flags |= V4L2_BUF_FLAG_MAPPED;
vb->memory = V4L2_MEMORY_MMAP;
- vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size);
+ vb->m.offset = vb->index * PAGE_ALIGN(usbvision->max_frame_size);
vb->memory = V4L2_MEMORY_MMAP;
vb->field = V4L2_FIELD_NONE;
- vb->length = usbvision->curwidth*
- usbvision->curheight*
+ vb->length = usbvision->curwidth *
+ usbvision->curheight *
usbvision->palette.bytes_per_pixel;
vb->timestamp = usbvision->frame[vb->index].timestamp;
vb->sequence = usbvision->frame[vb->index].sequence;
return 0;
}
-static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *vb)
{
struct usb_usbvision *usbvision = video_drvdata(file);
struct usbvision_frame *frame;
unsigned long lock_flags;
/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
- if(vb->index>=usbvision->num_frames) {
+ if (vb->index >= usbvision->num_frames)
return -EINVAL;
- }
frame = &usbvision->frame[vb->index];
- if (frame->grabstate != FrameState_Unused) {
+ if (frame->grabstate != frame_state_unused)
return -EAGAIN;
- }
/* Mark it as ready and enqueue frame */
- frame->grabstate = FrameState_Ready;
- frame->scanstate = ScanState_Scanning;
+ frame->grabstate = frame_state_ready;
+ frame->scanstate = scan_state_scanning;
frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */
vb->flags &= ~V4L2_BUF_FLAG_DONE;
@@ -835,7 +819,7 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
return 0;
}
-static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb)
{
struct usb_usbvision *usbvision = video_drvdata(file);
int ret;
@@ -843,7 +827,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
unsigned long lock_flags;
if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == Stream_Idle)
+ if (usbvision->streaming == stream_idle)
return -EINVAL;
ret = wait_event_interruptible
(usbvision->wait_frame,
@@ -858,7 +842,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
list_del(usbvision->outqueue.next);
spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
- f->grabstate = FrameState_Unused;
+ f->grabstate = frame_state_unused;
vb->memory = V4L2_MEMORY_MMAP;
vb->flags = V4L2_BUF_FLAG_MAPPED |
@@ -877,7 +861,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- usbvision->streaming = Stream_On;
+ usbvision->streaming = stream_on;
call_all(usbvision, video, s_stream, 1);
return 0;
@@ -891,7 +875,7 @@ static int vidioc_streamoff(struct file *file,
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- if(usbvision->streaming == Stream_On) {
+ if (usbvision->streaming == stream_on) {
usbvision_stream_interrupt(usbvision);
/* Stop all video streamings */
call_all(usbvision, video, s_stream, 0);
@@ -901,18 +885,17 @@ static int vidioc_streamoff(struct file *file,
return 0;
}
-static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *vfd)
{
- if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
+ if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1)
return -EINVAL;
- }
- strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
+ strcpy(vfd->description, usbvision_v4l2_format[vfd->index].desc);
vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
return 0;
}
-static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *vf)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -920,32 +903,31 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
vf->fmt.pix.height = usbvision->curheight;
vf->fmt.pix.pixelformat = usbvision->palette.format;
vf->fmt.pix.bytesperline =
- usbvision->curwidth*usbvision->palette.bytes_per_pixel;
- vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight;
+ usbvision->curwidth * usbvision->palette.bytes_per_pixel;
+ vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline * usbvision->curheight;
vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */
return 0;
}
-static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *vf)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int formatIdx;
+ int format_idx;
/* Find requested format in available ones */
- for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) {
- if(vf->fmt.pix.pixelformat ==
- usbvision_v4l2_format[formatIdx].format) {
- usbvision->palette = usbvision_v4l2_format[formatIdx];
+ for (format_idx = 0; format_idx < USBVISION_SUPPORTED_PALETTES; format_idx++) {
+ if (vf->fmt.pix.pixelformat ==
+ usbvision_v4l2_format[format_idx].format) {
+ usbvision->palette = usbvision_v4l2_format[format_idx];
break;
}
}
/* robustness */
- if(formatIdx == USBVISION_SUPPORTED_PALETTES) {
+ if (format_idx == USBVISION_SUPPORTED_PALETTES)
return -EINVAL;
- }
RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
@@ -962,24 +944,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct usb_usbvision *usbvision = video_drvdata(file);
int ret;
- if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) {
+ ret = vidioc_try_fmt_vid_cap(file, priv, vf);
+ if (ret)
return ret;
- }
/* stop io in case it is already in progress */
- if(usbvision->streaming == Stream_On) {
- if ((ret = usbvision_stream_interrupt(usbvision)))
+ if (usbvision->streaming == stream_on) {
+ ret = usbvision_stream_interrupt(usbvision);
+ if (ret)
return ret;
}
usbvision_frames_free(usbvision);
usbvision_empty_framequeues(usbvision);
- usbvision->curFrame = NULL;
+ usbvision->cur_frame = NULL;
/* by now we are committed to the new data... */
- mutex_lock(&usbvision->lock);
usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height);
- mutex_unlock(&usbvision->lock);
return 0;
}
@@ -990,8 +971,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
struct usb_usbvision *usbvision = video_drvdata(file);
int noblock = file->f_flags & O_NONBLOCK;
unsigned long lock_flags;
-
- int ret,i;
+ int ret, i;
struct usbvision_frame *frame;
PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__,
@@ -1003,28 +983,28 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
/* This entry point is compatible with the mmap routines
so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF
to get frames or call read on the device. */
- if(!usbvision->num_frames) {
+ if (!usbvision->num_frames) {
/* First, allocate some frames to work with
if this has not been done with VIDIOC_REQBUF */
usbvision_frames_free(usbvision);
usbvision_empty_framequeues(usbvision);
- usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES);
+ usbvision_frames_alloc(usbvision, USBVISION_NUMFRAMES);
}
- if(usbvision->streaming != Stream_On) {
+ if (usbvision->streaming != stream_on) {
/* no stream is running, make it running ! */
- usbvision->streaming = Stream_On;
+ usbvision->streaming = stream_on;
call_all(usbvision, video, s_stream, 1);
}
/* Then, enqueue as many frames as possible
(like a user of VIDIOC_QBUF would do) */
- for(i=0;i<usbvision->num_frames;i++) {
+ for (i = 0; i < usbvision->num_frames; i++) {
frame = &usbvision->frame[i];
- if(frame->grabstate == FrameState_Unused) {
+ if (frame->grabstate == frame_state_unused) {
/* Mark it as ready and enqueue frame */
- frame->grabstate = FrameState_Ready;
- frame->scanstate = ScanState_Scanning;
+ frame->grabstate = frame_state_ready;
+ frame->scanstate = scan_state_scanning;
/* Accumulated in usbvision_parse_data() */
frame->scanlength = 0;
@@ -1040,7 +1020,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
/* Then try to steal a frame (like a VIDIOC_DQBUF would do) */
if (list_empty(&(usbvision->outqueue))) {
- if(noblock)
+ if (noblock)
return -EAGAIN;
ret = wait_event_interruptible
@@ -1057,7 +1037,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
/* An error returns an empty frame */
- if (frame->grabstate == FrameState_Error) {
+ if (frame->grabstate == frame_state_error) {
frame->bytes_read = 0;
return 0;
}
@@ -1070,9 +1050,8 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
if ((count + frame->bytes_read) > (unsigned long)frame->scanlength)
count = frame->scanlength - frame->bytes_read;
- if (copy_to_user(buf, frame->data + frame->bytes_read, count)) {
+ if (copy_to_user(buf, frame->data + frame->bytes_read, count))
return -EFAULT;
- }
frame->bytes_read += count;
PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld",
@@ -1080,12 +1059,12 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
(unsigned long)count, frame->bytes_read);
/* For now, forget the frame if it has not been read in one shot. */
-/* if (frame->bytes_read >= frame->scanlength) {// All data has been read */
+/* if (frame->bytes_read >= frame->scanlength) {*/ /* All data has been read */
frame->bytes_read = 0;
/* Mark it as available to be used again. */
- frame->grabstate = FrameState_Unused;
-/* } */
+ frame->grabstate = frame_state_unused;
+/* } */
return count;
}
@@ -1100,16 +1079,11 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
PDEBUG(DBG_MMAP, "mmap");
- mutex_lock(&usbvision->lock);
-
- if (!USBVISION_IS_OPERATIONAL(usbvision)) {
- mutex_unlock(&usbvision->lock);
+ if (!USBVISION_IS_OPERATIONAL(usbvision))
return -EFAULT;
- }
if (!(vma->vm_flags & VM_WRITE) ||
size != PAGE_ALIGN(usbvision->max_frame_size)) {
- mutex_unlock(&usbvision->lock);
return -EINVAL;
}
@@ -1121,7 +1095,6 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
if (i == usbvision->num_frames) {
PDEBUG(DBG_MMAP,
"mmap: user supplied mapping address is out of range");
- mutex_unlock(&usbvision->lock);
return -EINVAL;
}
@@ -1131,10 +1104,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
pos = usbvision->frame[i].data;
while (size > 0) {
-
if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed");
- mutex_unlock(&usbvision->lock);
return -EAGAIN;
}
start += PAGE_SIZE;
@@ -1142,7 +1113,6 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
size -= PAGE_SIZE;
}
- mutex_unlock(&usbvision->lock);
return 0;
}
@@ -1154,21 +1124,18 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
static int usbvision_radio_open(struct file *file)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_IO, "%s:", __func__);
- mutex_lock(&usbvision->lock);
-
if (usbvision->user) {
dev_err(&usbvision->rdev->dev,
"%s: Someone tried to open an already opened USBVision Radio!\n",
__func__);
- errCode = -EBUSY;
- }
- else {
- if(PowerOnAtOpen) {
- usbvision_reset_powerOffTimer(usbvision);
+ err_code = -EBUSY;
+ } else {
+ if (power_on_at_open) {
+ usbvision_reset_power_off_timer(usbvision);
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
usbvision_i2c_register(usbvision);
@@ -1176,80 +1143,73 @@ static int usbvision_radio_open(struct file *file)
}
/* Alternate interface 1 is is the biggest frame size */
- errCode = usbvision_set_alternate(usbvision);
- if (errCode < 0) {
- usbvision->last_error = errCode;
- errCode = -EBUSY;
+ err_code = usbvision_set_alternate(usbvision);
+ if (err_code < 0) {
+ usbvision->last_error = err_code;
+ err_code = -EBUSY;
goto out;
}
- // If so far no errors then we shall start the radio
+ /* If so far no errors then we shall start the radio */
usbvision->radio = 1;
call_all(usbvision, tuner, s_radio);
usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
usbvision->user++;
}
- if (errCode) {
- if (PowerOnAtOpen) {
+ if (err_code) {
+ if (power_on_at_open) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
}
out:
- mutex_unlock(&usbvision->lock);
- return errCode;
+ return err_code;
}
static int usbvision_radio_close(struct file *file)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int errCode = 0;
+ int err_code = 0;
PDEBUG(DBG_IO, "");
- mutex_lock(&usbvision->lock);
-
/* Set packet size to 0 */
- usbvision->ifaceAlt=0;
- errCode = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->ifaceAlt);
+ usbvision->iface_alt = 0;
+ err_code = usb_set_interface(usbvision->dev, usbvision->iface,
+ usbvision->iface_alt);
usbvision_audio_off(usbvision);
- usbvision->radio=0;
+ usbvision->radio = 0;
usbvision->user--;
- if (PowerOnAtOpen) {
- usbvision_set_powerOffTimer(usbvision);
+ if (power_on_at_open) {
+ usbvision_set_power_off_timer(usbvision);
usbvision->initialized = 0;
}
- mutex_unlock(&usbvision->lock);
-
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
}
PDEBUG(DBG_IO, "success");
- return errCode;
+ return err_code;
}
-//
-// Video registration stuff
-//
+/* Video registration stuff */
-// Video template
+/* Video template */
static const struct v4l2_file_operations usbvision_fops = {
.owner = THIS_MODULE,
.open = usbvision_v4l2_open,
.release = usbvision_v4l2_close,
.read = usbvision_v4l2_read,
.mmap = usbvision_v4l2_mmap,
- .ioctl = video_ioctl2,
-/* .poll = video_poll, */
+ .unlocked_ioctl = video_ioctl2,
+/* .poll = video_poll, */
};
static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
@@ -1273,9 +1233,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* .vidiocgmbuf = vidiocgmbuf, */
-#endif
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
@@ -1288,20 +1245,20 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
static struct video_device usbvision_video_template = {
.fops = &usbvision_fops,
- .ioctl_ops = &usbvision_ioctl_ops,
+ .ioctl_ops = &usbvision_ioctl_ops,
.name = "usbvision-video",
.release = video_device_release,
- .tvnorms = USBVISION_NORMS,
- .current_norm = V4L2_STD_PAL
+ .tvnorms = USBVISION_NORMS,
+ .current_norm = V4L2_STD_PAL
};
-// Radio template
+/* Radio template */
static const struct v4l2_file_operations usbvision_radio_fops = {
.owner = THIS_MODULE,
.open = usbvision_radio_open,
.release = usbvision_radio_close,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
@@ -1322,9 +1279,9 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
static struct video_device usbvision_radio_template = {
.fops = &usbvision_radio_fops,
- .name = "usbvision-radio",
+ .name = "usbvision-radio",
.release = video_device_release,
- .ioctl_ops = &usbvision_radio_ioctl_ops,
+ .ioctl_ops = &usbvision_radio_ioctl_ops,
.tvnorms = USBVISION_NORMS,
.current_norm = V4L2_STD_PAL
@@ -1345,80 +1302,70 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
}
vdev = video_device_alloc();
- if (NULL == vdev) {
+ if (NULL == vdev)
return NULL;
- }
*vdev = *vdev_template;
+ vdev->lock = &usbvision->v4l2_lock;
vdev->v4l2_dev = &usbvision->v4l2_dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
video_set_drvdata(vdev, usbvision);
return vdev;
}
-// unregister video4linux devices
+/* unregister video4linux devices */
static void usbvision_unregister_video(struct usb_usbvision *usbvision)
{
- // Radio Device:
+ /* Radio Device: */
if (usbvision->rdev) {
PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
video_device_node_name(usbvision->rdev));
- if (video_is_registered(usbvision->rdev)) {
+ if (video_is_registered(usbvision->rdev))
video_unregister_device(usbvision->rdev);
- } else {
+ else
video_device_release(usbvision->rdev);
- }
usbvision->rdev = NULL;
}
- // Video Device:
+ /* Video Device: */
if (usbvision->vdev) {
PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
video_device_node_name(usbvision->vdev));
- if (video_is_registered(usbvision->vdev)) {
+ if (video_is_registered(usbvision->vdev))
video_unregister_device(usbvision->vdev);
- } else {
+ else
video_device_release(usbvision->vdev);
- }
usbvision->vdev = NULL;
}
}
-// register video4linux devices
+/* register video4linux devices */
static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
{
- // Video Device:
+ /* Video Device: */
usbvision->vdev = usbvision_vdev_init(usbvision,
&usbvision_video_template,
"USBVision Video");
- if (usbvision->vdev == NULL) {
+ if (usbvision->vdev == NULL)
goto err_exit;
- }
- if (video_register_device(usbvision->vdev,
- VFL_TYPE_GRABBER,
- video_nr)<0) {
+ if (video_register_device(usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
goto err_exit;
- }
printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
usbvision->nr, video_device_node_name(usbvision->vdev));
- // Radio Device:
- if (usbvision_device_data[usbvision->DevModel].Radio) {
- // usbvision has radio
+ /* Radio Device: */
+ if (usbvision_device_data[usbvision->dev_model].radio) {
+ /* usbvision has radio */
usbvision->rdev = usbvision_vdev_init(usbvision,
&usbvision_radio_template,
"USBVision Radio");
- if (usbvision->rdev == NULL) {
+ if (usbvision->rdev == NULL)
goto err_exit;
- }
- if (video_register_device(usbvision->rdev,
- VFL_TYPE_RADIO,
- radio_nr)<0) {
+ if (video_register_device(usbvision->rdev, VFL_TYPE_RADIO, radio_nr) < 0)
goto err_exit;
- }
printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n",
usbvision->nr, video_device_node_name(usbvision->rdev));
}
- // all done
+ /* all done */
return 0;
err_exit:
@@ -1451,15 +1398,15 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
goto err_free;
- mutex_init(&usbvision->lock); /* available */
+ mutex_init(&usbvision->v4l2_lock);
- // prepare control urb for control messages during interrupts
- usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
- if (usbvision->ctrlUrb == NULL)
+ /* prepare control urb for control messages during interrupts */
+ usbvision->ctrl_urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
+ if (usbvision->ctrl_urb == NULL)
goto err_unreg;
- init_waitqueue_head(&usbvision->ctrlUrb_wq);
+ init_waitqueue_head(&usbvision->ctrl_urb_wq);
- usbvision_init_powerOffTimer(usbvision);
+ usbvision_init_power_off_timer(usbvision);
return usbvision;
@@ -1481,20 +1428,14 @@ static void usbvision_release(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_PROBE, "");
- mutex_lock(&usbvision->lock);
-
- usbvision_reset_powerOffTimer(usbvision);
+ usbvision_reset_power_off_timer(usbvision);
usbvision->initialized = 0;
- mutex_unlock(&usbvision->lock);
-
usbvision_remove_sysfs(usbvision->vdev);
usbvision_unregister_video(usbvision);
- if (usbvision->ctrlUrb) {
- usb_free_urb(usbvision->ctrlUrb);
- }
+ usb_free_urb(usbvision->ctrl_urb);
v4l2_device_unregister(&usbvision->v4l2_dev);
kfree(usbvision);
@@ -1512,25 +1453,25 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
if (usbvision == NULL)
return;
- model = usbvision->DevModel;
- usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24;
+ model = usbvision->dev_model;
+ usbvision->palette = usbvision_v4l2_format[2]; /* V4L2_PIX_FMT_RGB24; */
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) {
- usbvision->Vin_Reg2_Preset =
- usbvision_device_data[usbvision->DevModel].Vin_Reg2;
+ if (usbvision_device_data[usbvision->dev_model].vin_reg2_override) {
+ usbvision->vin_reg2_preset =
+ usbvision_device_data[usbvision->dev_model].vin_reg2;
} else {
- usbvision->Vin_Reg2_Preset = 0;
+ usbvision->vin_reg2_preset = 0;
}
- usbvision->tvnormId = usbvision_device_data[model].VideoNorm;
+ usbvision->tvnorm_id = usbvision_device_data[model].video_norm;
- usbvision->video_inputs = usbvision_device_data[model].VideoChannels;
+ usbvision->video_inputs = usbvision_device_data[model].video_channels;
usbvision->ctl_input = 0;
/* This should be here to make i2c clients to be able to register */
/* first switch off audio */
usbvision_audio_off(usbvision);
- if (!PowerOnAtOpen) {
+ if (!power_on_at_open) {
/* and then power up the noisy tuner */
usbvision_power_on(usbvision);
usbvision_i2c_register(usbvision);
@@ -1553,25 +1494,24 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
const struct usb_host_interface *interface;
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
- int model,i;
+ int model, i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor,
dev->descriptor.idProduct, ifnum);
model = devid->driver_info;
- if ( (model<0) || (model>=usbvision_device_data_size) ) {
- PDEBUG(DBG_PROBE, "model out of bounds %d",model);
+ if (model < 0 || model >= usbvision_device_data_size) {
+ PDEBUG(DBG_PROBE, "model out of bounds %d", model);
return -ENODEV;
}
printk(KERN_INFO "%s: %s found\n", __func__,
- usbvision_device_data[model].ModelString);
+ usbvision_device_data[model].model_string);
- if (usbvision_device_data[model].Interface >= 0) {
- interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0];
- } else {
+ if (usbvision_device_data[model].interface >= 0)
+ interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
+ else
interface = &dev->actconfig->interface[ifnum]->altsetting[0];
- }
endpoint = &interface->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint)) {
dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
@@ -1592,59 +1532,52 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
return -ENOMEM;
}
- if (dev->descriptor.bNumConfigurations > 1) {
- usbvision->bridgeType = BRIDGE_NT1004;
- } else if (model == DAZZLE_DVC_90_REV_1_SECAM) {
- usbvision->bridgeType = BRIDGE_NT1005;
- } else {
- usbvision->bridgeType = BRIDGE_NT1003;
- }
- PDEBUG(DBG_PROBE, "bridgeType %d", usbvision->bridgeType);
-
- mutex_lock(&usbvision->lock);
+ if (dev->descriptor.bNumConfigurations > 1)
+ usbvision->bridge_type = BRIDGE_NT1004;
+ else if (model == DAZZLE_DVC_90_REV_1_SECAM)
+ usbvision->bridge_type = BRIDGE_NT1005;
+ else
+ usbvision->bridge_type = BRIDGE_NT1003;
+ PDEBUG(DBG_PROBE, "bridge_type %d", usbvision->bridge_type);
/* compute alternate max packet sizes */
uif = dev->actconfig->interface[0];
- usbvision->num_alt=uif->num_altsetting;
- PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt);
- usbvision->alt_max_pkt_size = kmalloc(32*
- usbvision->num_alt,GFP_KERNEL);
+ usbvision->num_alt = uif->num_altsetting;
+ PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt);
+ usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
dev_err(&intf->dev, "usbvision: out of memory!\n");
- mutex_unlock(&usbvision->lock);
return -ENOMEM;
}
- for (i = 0; i < usbvision->num_alt ; i++) {
+ for (i = 0; i < usbvision->num_alt; i++) {
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
wMaxPacketSize);
usbvision->alt_max_pkt_size[i] =
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i,
+ PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i", i,
usbvision->alt_max_pkt_size[i]);
}
usbvision->nr = usbvision_nr++;
- usbvision->have_tuner = usbvision_device_data[model].Tuner;
- if (usbvision->have_tuner) {
- usbvision->tuner_type = usbvision_device_data[model].TunerType;
- }
+ usbvision->have_tuner = usbvision_device_data[model].tuner;
+ if (usbvision->have_tuner)
+ usbvision->tuner_type = usbvision_device_data[model].tuner_type;
- usbvision->DevModel = model;
+ usbvision->dev_model = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
- usbvision->ifaceAlt = 0;
+ usbvision->iface_alt = 0;
usbvision->video_endp = endpoint->bEndpointAddress;
- usbvision->isocPacketSize = 0;
+ usbvision->isoc_packet_size = 0;
usbvision->usb_bandwidth = 0;
usbvision->user = 0;
- usbvision->streaming = Stream_Off;
+ usbvision->streaming = stream_off;
usbvision_configure_video(usbvision);
usbvision_register_video(usbvision);
- mutex_unlock(&usbvision->lock);
usbvision_create_sysfs(usbvision->vdev);
@@ -1672,9 +1605,9 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
return;
}
- mutex_lock(&usbvision->lock);
+ mutex_lock(&usbvision->v4l2_lock);
- // At this time we ask to cancel outstanding URBs
+ /* At this time we ask to cancel outstanding URBs */
usbvision_stop_isoc(usbvision);
v4l2_device_disconnect(&usbvision->v4l2_dev);
@@ -1683,12 +1616,12 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
}
- usbvision->remove_pending = 1; // Now all ISO data will be ignored
+ usbvision->remove_pending = 1; /* Now all ISO data will be ignored */
usb_put_dev(usbvision->dev);
- usbvision->dev = NULL; // USB device is no more
+ usbvision->dev = NULL; /* USB device is no more */
- mutex_unlock(&usbvision->lock);
+ mutex_unlock(&usbvision->v4l2_lock);
if (usbvision->user) {
printk(KERN_INFO "%s: In use, disconnect pending\n",
@@ -1717,7 +1650,7 @@ static struct usb_driver usbvision_driver = {
*/
static int __init usbvision_init(void)
{
- int errCode;
+ int err_code;
PDEBUG(DBG_PROBE, "");
@@ -1726,27 +1659,27 @@ static int __init usbvision_init(void)
PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]");
/* disable planar mode support unless compression enabled */
- if (isocMode != ISOC_MODE_COMPRESS ) {
- // FIXME : not the right way to set supported flag
- usbvision_v4l2_format[6].supported = 0; // V4L2_PIX_FMT_YVU420
- usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P
+ if (isoc_mode != ISOC_MODE_COMPRESS) {
+ /* FIXME : not the right way to set supported flag */
+ usbvision_v4l2_format[6].supported = 0; /* V4L2_PIX_FMT_YVU420 */
+ usbvision_v4l2_format[7].supported = 0; /* V4L2_PIX_FMT_YUV422P */
}
- errCode = usb_register(&usbvision_driver);
+ err_code = usb_register(&usbvision_driver);
- if (errCode == 0) {
+ if (err_code == 0) {
printk(KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING "\n");
PDEBUG(DBG_PROBE, "success");
}
- return errCode;
+ return err_code;
}
static void __exit usbvision_exit(void)
{
- PDEBUG(DBG_PROBE, "");
+ PDEBUG(DBG_PROBE, "");
- usb_deregister(&usbvision_driver);
- PDEBUG(DBG_PROBE, "success");
+ usb_deregister(&usbvision_driver);
+ PDEBUG(DBG_PROBE, "success");
}
module_init(usbvision_init);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index cc4e96c8cd6c..8074787fd1ac 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -132,15 +132,15 @@
#define MAX_BYTES_PER_PIXEL 4
#define MIN_FRAME_WIDTH 64
-#define MAX_USB_WIDTH 320 //384
-#define MAX_FRAME_WIDTH 320 //384 /*streching sometimes causes crashes*/
+#define MAX_USB_WIDTH 320 /* 384 */
+#define MAX_FRAME_WIDTH 320 /* 384 */ /* streching sometimes causes crashes*/
#define MIN_FRAME_HEIGHT 48
-#define MAX_USB_HEIGHT 240 //288
-#define MAX_FRAME_HEIGHT 240 //288 /*Streching sometimes causes crashes*/
+#define MAX_USB_HEIGHT 240 /* 288 */
+#define MAX_FRAME_HEIGHT 240 /* 288 */ /* Streching sometimes causes crashes*/
-#define MAX_FRAME_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL)
-#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
+#define MAX_FRAME_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL)
+#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) /* bytesize of clipmask */
#define USBVISION_URB_FRAMES 32
@@ -148,7 +148,7 @@
#define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */
#define USBVISION_NUMSBUF 2 /* Dimensioning the USB S buffering */
-#define USBVISION_POWEROFF_TIME 3 * (HZ) // 3 seconds
+#define USBVISION_POWEROFF_TIME (3 * HZ) /* 3 seconds */
#define FRAMERATE_MIN 0
@@ -161,7 +161,8 @@ enum {
};
/* This macro restricts an int variable to an inclusive range */
-#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
+#define RESTRICT_TO_RANGE(v, mi, ma) \
+ { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
/*
* We use macros to do YUV -> RGB conversion because this is
@@ -183,18 +184,18 @@ enum {
* Make sure the output values are within [0..255] range.
*/
#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
-#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
- int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
- mm_y = (my) - 16; \
- mm_u = (mu) - 128; \
- mm_v = (mv) - 128; \
- mm_yc= mm_y * 76284; \
- mm_b = (mm_yc + 132252*mm_v ) >> 16; \
- mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
- mm_r = (mm_yc + 104595*mm_u ) >> 16; \
- mb = LIMIT_RGB(mm_b); \
- mg = LIMIT_RGB(mm_g); \
- mr = LIMIT_RGB(mm_r); \
+#define YUV_TO_RGB_BY_THE_BOOK(my, mu, mv, mr, mg, mb) { \
+ int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
+ mm_y = (my) - 16; \
+ mm_u = (mu) - 128; \
+ mm_v = (mv) - 128; \
+ mm_yc = mm_y * 76284; \
+ mm_b = (mm_yc + 132252 * mm_v) >> 16; \
+ mm_g = (mm_yc - 53281 * mm_u - 25625 * mm_v) >> 16; \
+ mm_r = (mm_yc + 104595 * mm_u) >> 16; \
+ mb = LIMIT_RGB(mm_b); \
+ mg = LIMIT_RGB(mm_g); \
+ mr = LIMIT_RGB(mm_r); \
}
/* Debugging aid */
@@ -202,7 +203,7 @@ enum {
wait_queue_head_t wq; \
init_waitqueue_head(&wq); \
printk(KERN_INFO "Say: %s\n", what); \
- interruptible_sleep_on_timeout (&wq, HZ*3); \
+ interruptible_sleep_on_timeout(&wq, HZ * 3); \
}
/*
@@ -223,39 +224,39 @@ enum {
/* ----------------------------------------------------------------- */
/* usbvision video structures */
/* ----------------------------------------------------------------- */
-enum ScanState {
- ScanState_Scanning, /* Scanning for header */
- ScanState_Lines /* Parsing lines */
+enum scan_state {
+ scan_state_scanning, /* Scanning for header */
+ scan_state_lines /* Parsing lines */
};
/* Completion states of the data parser */
-enum ParseState {
- ParseState_Continue, /* Just parse next item */
- ParseState_NextFrame, /* Frame done, send it to V4L */
- ParseState_Out, /* Not enough data for frame */
- ParseState_EndParse /* End parsing */
+enum parse_state {
+ parse_state_continue, /* Just parse next item */
+ parse_state_next_frame, /* Frame done, send it to V4L */
+ parse_state_out, /* Not enough data for frame */
+ parse_state_end_parse /* End parsing */
};
-enum FrameState {
- FrameState_Unused, /* Unused (no MCAPTURE) */
- FrameState_Ready, /* Ready to start grabbing */
- FrameState_Grabbing, /* In the process of being grabbed into */
- FrameState_Done, /* Finished grabbing, but not been synced yet */
- FrameState_DoneHold, /* Are syncing or reading */
- FrameState_Error, /* Something bad happened while processing */
+enum frame_state {
+ frame_state_unused, /* Unused (no MCAPTURE) */
+ frame_state_ready, /* Ready to start grabbing */
+ frame_state_grabbing, /* In the process of being grabbed into */
+ frame_state_done, /* Finished grabbing, but not been synced yet */
+ frame_state_done_hold, /* Are syncing or reading */
+ frame_state_error, /* Something bad happened while processing */
};
/* stream states */
-enum StreamState {
- Stream_Off, /* Driver streaming is completely OFF */
- Stream_Idle, /* Driver streaming is ready to be put ON by the application */
- Stream_Interrupt, /* Driver streaming must be interrupted */
- Stream_On, /* Driver streaming is put ON by the application */
+enum stream_state {
+ stream_off, /* Driver streaming is completely OFF */
+ stream_idle, /* Driver streaming is ready to be put ON by the application */
+ stream_interrupt, /* Driver streaming must be interrupted */
+ stream_on, /* Driver streaming is put ON by the application */
};
-enum IsocState {
- IsocState_InFrame, /* Isoc packet is member of frame */
- IsocState_NoFrame, /* Isoc packet is not member of any frame */
+enum isoc_state {
+ isoc_state_in_frame, /* Isoc packet is member of frame */
+ isoc_state_no_frame, /* Isoc packet is not member of any frame */
};
struct usb_device;
@@ -265,8 +266,8 @@ struct usbvision_sbuf {
struct urb *urb;
};
-#define USBVISION_MAGIC_1 0x55
-#define USBVISION_MAGIC_2 0xAA
+#define USBVISION_MAGIC_1 0x55
+#define USBVISION_MAGIC_2 0xAA
#define USBVISION_HEADER_LENGTH 0x0c
#define USBVISION_SAA7111_ADDR 0x48
#define USBVISION_SAA7113_ADDR 0x4a
@@ -286,23 +287,23 @@ struct usbvision_v4l2_format_st {
struct usbvision_frame_header {
unsigned char magic_1; /* 0 magic */
unsigned char magic_2; /* 1 magic */
- unsigned char headerLength; /* 2 */
- unsigned char frameNum; /* 3 */
- unsigned char framePhase; /* 4 */
- unsigned char frameLatency; /* 5 */
- unsigned char dataFormat; /* 6 */
- unsigned char formatParam; /* 7 */
- unsigned char frameWidthLo; /* 8 */
- unsigned char frameWidthHi; /* 9 */
- unsigned char frameHeightLo; /* 10 */
- unsigned char frameHeightHi; /* 11 */
- __u16 frameWidth; /* 8 - 9 after endian correction*/
- __u16 frameHeight; /* 10 - 11 after endian correction*/
+ unsigned char header_length; /* 2 */
+ unsigned char frame_num; /* 3 */
+ unsigned char frame_phase; /* 4 */
+ unsigned char frame_latency; /* 5 */
+ unsigned char data_format; /* 6 */
+ unsigned char format_param; /* 7 */
+ unsigned char frame_width_lo; /* 8 */
+ unsigned char frame_width_hi; /* 9 */
+ unsigned char frame_height_lo; /* 10 */
+ unsigned char frame_height_hi; /* 11 */
+ __u16 frame_width; /* 8 - 9 after endian correction*/
+ __u16 frame_height; /* 10 - 11 after endian correction*/
};
struct usbvision_frame {
char *data; /* Frame buffer */
- struct usbvision_frame_header isocHeader; /* Header from stream */
+ struct usbvision_frame_header isoc_header; /* Header from stream */
int width; /* Width application is expecting */
int height; /* Height */
@@ -322,7 +323,7 @@ struct usbvision_frame {
struct usbvision_v4l2_format_st v4l2_format; /* format the user needs*/
int v4l2_linesize; /* bytes for one videoline*/
struct timeval timestamp;
- int sequence; // How many video frames we send to user
+ int sequence; /* How many video frames we send to user */
};
#define CODEC_SAA7113 7113
@@ -332,24 +333,24 @@ struct usbvision_frame {
#define BRIDGE_NT1005 1005
struct usbvision_device_data_st {
- __u64 VideoNorm;
- const char *ModelString;
- int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
- __u16 Codec;
- unsigned VideoChannels:3;
- unsigned AudioChannels:2;
- unsigned Radio:1;
+ __u64 video_norm;
+ const char *model_string;
+ int interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
+ __u16 codec;
+ unsigned video_channels:3;
+ unsigned audio_channels:2;
+ unsigned radio:1;
unsigned vbi:1;
- unsigned Tuner:1;
- unsigned Vin_Reg1_override:1; /* Override default value with */
- unsigned Vin_Reg2_override:1; /* Vin_Reg1, Vin_Reg2, etc. */
- unsigned Dvi_yuv_override:1;
- __u8 Vin_Reg1;
- __u8 Vin_Reg2;
- __u8 Dvi_yuv;
- __u8 TunerType;
- __s16 X_Offset;
- __s16 Y_Offset;
+ unsigned tuner:1;
+ unsigned vin_reg1_override:1; /* Override default value with */
+ unsigned vin_reg2_override:1; /* vin_reg1, vin_reg2, etc. */
+ unsigned dvi_yuv_override:1;
+ __u8 vin_reg1;
+ __u8 vin_reg2;
+ __u8 dvi_yuv;
+ __u8 tuner_type;
+ __s16 x_offset;
+ __s16 y_offset;
};
/* Declared on usbvision-cards.c */
@@ -358,50 +359,50 @@ extern struct usb_device_id usbvision_table[];
struct usb_usbvision {
struct v4l2_device v4l2_dev;
- struct video_device *vdev; /* Video Device */
- struct video_device *rdev; /* Radio Device */
+ struct video_device *vdev; /* Video Device */
+ struct video_device *rdev; /* Radio Device */
/* i2c Declaration Section*/
struct i2c_adapter i2c_adap;
int registered_i2c;
- struct urb *ctrlUrb;
- unsigned char ctrlUrbBuffer[8];
- int ctrlUrbBusy;
- struct usb_ctrlrequest ctrlUrbSetup;
- wait_queue_head_t ctrlUrb_wq; // Processes waiting
+ struct urb *ctrl_urb;
+ unsigned char ctrl_urb_buffer[8];
+ int ctrl_urb_busy;
+ struct usb_ctrlrequest ctrl_urb_setup;
+ wait_queue_head_t ctrl_urb_wq; /* Processes waiting */
/* configuration part */
int have_tuner;
int tuner_type;
- int bridgeType; // NT1003, NT1004, NT1005
+ int bridge_type; /* NT1003, NT1004, NT1005 */
int radio;
- int video_inputs; // # of inputs
+ int video_inputs; /* # of inputs */
unsigned long freq;
- int AudioMute;
- int AudioChannel;
- int isocMode; // format of video data for the usb isoc-transfer
- unsigned int nr; // Number of the device
+ int audio_mute;
+ int audio_channel;
+ int isoc_mode; /* format of video data for the usb isoc-transfer */
+ unsigned int nr; /* Number of the device */
/* Device structure */
struct usb_device *dev;
/* usb transfer */
int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ unsigned int *alt_max_pkt_size; /* array of max_packet_size */
unsigned char iface; /* Video interface number */
- unsigned char ifaceAlt; /* Alt settings */
- unsigned char Vin_Reg2_Preset;
- struct mutex lock;
- struct timer_list powerOffTimer;
- struct work_struct powerOffWork;
+ unsigned char iface_alt; /* Alt settings */
+ unsigned char vin_reg2_preset;
+ struct mutex v4l2_lock;
+ struct timer_list power_off_timer;
+ struct work_struct power_off_work;
int power; /* is the device powered on? */
int user; /* user count for exclusive use */
int initialized; /* Had we already sent init sequence? */
- int DevModel; /* What type of USBVISION device we got? */
- enum StreamState streaming; /* Are we streaming Isochronous? */
+ int dev_model; /* What type of USBVISION device we got? */
+ enum stream_state streaming; /* Are we streaming Isochronous? */
int last_error; /* What calamity struck us? */
int curwidth; /* width of the frame the device is currently set to*/
- int curheight; /* height of the frame the device is currently set to*/
+ int curheight; /* height of the frame the device is currently set to*/
int stretch_width; /* stretch-factor for frame width (from usb to screen)*/
int stretch_height; /* stretch-factor for frame height (from usb to screen)*/
char *fbuf; /* Videodev buffer area for mmap*/
@@ -411,10 +412,10 @@ struct usb_usbvision {
struct list_head inqueue, outqueue; /* queued frame list and ready to dequeue frame list */
wait_queue_head_t wait_frame; /* Processes waiting */
wait_queue_head_t wait_stream; /* Processes waiting */
- struct usbvision_frame *curFrame; // pointer to current frame, set by usbvision_find_header
- struct usbvision_frame frame[USBVISION_NUMFRAMES]; // frame buffer
- int num_frames; // number of frames allocated
- struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; // S buffering
+ struct usbvision_frame *cur_frame; /* pointer to current frame, set by usbvision_find_header */
+ struct usbvision_frame frame[USBVISION_NUMFRAMES]; /* frame buffer */
+ int num_frames; /* number of frames allocated */
+ struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; /* S buffering */
volatile int remove_pending; /* If set then about to exit */
/* Scratch space from the Isochronous Pipe.*/
@@ -424,43 +425,43 @@ struct usb_usbvision {
int scratch_headermarker[USBVISION_NUM_HEADERMARKER];
int scratch_headermarker_read_ptr;
int scratch_headermarker_write_ptr;
- enum IsocState isocstate;
+ enum isoc_state isocstate;
struct usbvision_v4l2_format_st palette;
struct v4l2_capability vcap; /* Video capabilities */
unsigned int ctl_input; /* selected input */
- v4l2_std_id tvnormId; /* selected tv norm */
+ v4l2_std_id tvnorm_id; /* selected tv norm */
unsigned char video_endp; /* 0x82 for USBVISION devices based */
- // Decompression stuff:
- unsigned char *IntraFrameBuffer; /* Buffer for reference frame */
- int BlockPos; //for test only
- int requestIntra; // 0 = normal; 1 = intra frame is requested;
- int lastIsocFrameNum; // check for lost isoc frames
- int isocPacketSize; // need to calculate usedBandwidth
- int usedBandwidth; // used bandwidth 0-100%, need to set comprLevel
- int comprLevel; // How strong (100) or weak (0) is compression
- int lastComprLevel; // How strong (100) or weak (0) was compression
+ /* Decompression stuff: */
+ unsigned char *intra_frame_buffer; /* Buffer for reference frame */
+ int block_pos; /* for test only */
+ int request_intra; /* 0 = normal; 1 = intra frame is requested; */
+ int last_isoc_frame_num; /* check for lost isoc frames */
+ int isoc_packet_size; /* need to calculate used_bandwidth */
+ int used_bandwidth; /* used bandwidth 0-100%, need to set compr_level */
+ int compr_level; /* How strong (100) or weak (0) is compression */
+ int last_compr_level; /* How strong (100) or weak (0) was compression */
int usb_bandwidth; /* Mbit/s */
/* Statistics that can be overlayed on the screen */
- unsigned long isocUrbCount; // How many URBs we received so far
+ unsigned long isoc_urb_count; /* How many URBs we received so far */
unsigned long urb_length; /* Length of last URB */
- unsigned long isocDataCount; /* How many bytes we received */
+ unsigned long isoc_data_count; /* How many bytes we received */
unsigned long header_count; /* How many frame headers we found */
unsigned long scratch_ovf_count; /* How many times we overflowed scratch */
- unsigned long isocSkipCount; /* How many empty ISO packets received */
- unsigned long isocErrCount; /* How many bad ISO packets received */
- unsigned long isocPacketCount; // How many packets we totally got
- unsigned long timeInIrq; // How long do we need for interrupt
- int isocMeasureBandwidthCount;
- int frame_num; // How many video frames we send to user
- int maxStripLen; // How big is the biggest strip
- int comprBlockPos;
- int stripLenErrors; // How many times was BlockPos greater than StripLen
- int stripMagicErrors;
- int stripLineNumberErrors;
- int ComprBlockTypes[4];
+ unsigned long isoc_skip_count; /* How many empty ISO packets received */
+ unsigned long isoc_err_count; /* How many bad ISO packets received */
+ unsigned long isoc_packet_count; /* How many packets we totally got */
+ unsigned long time_in_irq; /* How long do we need for interrupt */
+ int isoc_measure_bandwidth_count;
+ int frame_num; /* How many video frames we send to user */
+ int max_strip_len; /* How big is the biggest strip */
+ int comprblock_pos;
+ int strip_len_errors; /* How many times was block_pos greater than strip_len */
+ int strip_magic_errors;
+ int strip_line_number_errors;
+ int compr_block_types[4];
};
static inline struct usb_usbvision *to_usbvision(struct v4l2_device *v4l2_dev)
@@ -494,13 +495,13 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision);
int usbvision_decompress_alloc(struct usb_usbvision *usbvision);
void usbvision_decompress_free(struct usb_usbvision *usbvision);
-int usbvision_setup(struct usb_usbvision *usbvision,int format);
+int usbvision_setup(struct usb_usbvision *usbvision, int format);
int usbvision_init_isoc(struct usb_usbvision *usbvision);
int usbvision_restart_isoc(struct usb_usbvision *usbvision);
void usbvision_stop_isoc(struct usb_usbvision *usbvision);
int usbvision_set_alternate(struct usb_usbvision *dev);
-int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel);
+int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel);
int usbvision_audio_off(struct usb_usbvision *usbvision);
int usbvision_begin_streaming(struct usb_usbvision *usbvision);
@@ -511,9 +512,9 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel);
int usbvision_set_input(struct usb_usbvision *usbvision);
int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height);
-void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision);
-void usbvision_set_powerOffTimer(struct usb_usbvision *usbvision);
-void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision);
+void usbvision_init_power_off_timer(struct usb_usbvision *usbvision);
+void usbvision_set_power_off_timer(struct usb_usbvision *usbvision);
+void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision);
int usbvision_power_off(struct usb_usbvision *usbvision);
int usbvision_power_on(struct usb_usbvision *usbvision);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index f169f7736677..59f8a9ad3796 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
}
}
-struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
+static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
__u32 v4l2_id, struct uvc_control_mapping **mapping)
{
struct uvc_control *ctrl = NULL;
@@ -944,6 +944,52 @@ done:
return ret;
}
+/*
+ * Mapping V4L2 controls to UVC controls can be straighforward if done well.
+ * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
+ * must be grouped (for instance the Red Balance, Blue Balance and Do White
+ * Balance V4L2 controls use the White Balance Component UVC control) or
+ * otherwise translated. The approach we take here is to use a translation
+ * table for the controls that can be mapped directly, and handle the others
+ * manually.
+ */
+int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+ struct v4l2_querymenu *query_menu)
+{
+ struct uvc_menu_info *menu_info;
+ struct uvc_control_mapping *mapping;
+ struct uvc_control *ctrl;
+ u32 index = query_menu->index;
+ u32 id = query_menu->id;
+ int ret;
+
+ memset(query_menu, 0, sizeof(*query_menu));
+ query_menu->id = id;
+ query_menu->index = index;
+
+ ret = mutex_lock_interruptible(&chain->ctrl_mutex);
+ if (ret < 0)
+ return -ERESTARTSYS;
+
+ ctrl = uvc_find_control(chain, query_menu->id, &mapping);
+ if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (query_menu->index >= mapping->menu_count) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ menu_info = &mapping->menu_info[query_menu->index];
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
+
+done:
+ mutex_unlock(&chain->ctrl_mutex);
+ return ret;
+}
+
/* --------------------------------------------------------------------------
* Control transactions
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index ed6d5449741c..f14581bd707f 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
}
/*
+ * Free the video buffers.
+ *
+ * This function must be called with the queue lock held.
+ */
+static int __uvc_free_buffers(struct uvc_video_queue *queue)
+{
+ unsigned int i;
+
+ for (i = 0; i < queue->count; ++i) {
+ if (queue->buffer[i].vma_use_count != 0)
+ return -EBUSY;
+ }
+
+ if (queue->count) {
+ vfree(queue->mem);
+ queue->count = 0;
+ }
+
+ return 0;
+}
+
+int uvc_free_buffers(struct uvc_video_queue *queue)
+{
+ int ret;
+
+ mutex_lock(&queue->mutex);
+ ret = __uvc_free_buffers(queue);
+ mutex_unlock(&queue->mutex);
+
+ return ret;
+}
+
+/*
* Allocate the video buffers.
*
* Pages are reserved to make sure they will not be swapped, as they will be
@@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
mutex_lock(&queue->mutex);
- if ((ret = uvc_free_buffers(queue)) < 0)
+ if ((ret = __uvc_free_buffers(queue)) < 0)
goto done;
/* Bail out if no buffers should be allocated. */
@@ -152,28 +185,6 @@ done:
}
/*
- * Free the video buffers.
- *
- * This function must be called with the queue lock held.
- */
-int uvc_free_buffers(struct uvc_video_queue *queue)
-{
- unsigned int i;
-
- for (i = 0; i < queue->count; ++i) {
- if (queue->buffer[i].vma_use_count != 0)
- return -EBUSY;
- }
-
- if (queue->count) {
- vfree(queue->mem);
- queue->count = 0;
- }
-
- return 0;
-}
-
-/*
* Check if buffers have been allocated.
*/
int uvc_queue_allocated(struct uvc_video_queue *queue)
@@ -369,6 +380,82 @@ done:
}
/*
+ * VMA operations.
+ */
+static void uvc_vm_open(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count++;
+}
+
+static void uvc_vm_close(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count--;
+}
+
+static const struct vm_operations_struct uvc_vm_ops = {
+ .open = uvc_vm_open,
+ .close = uvc_vm_close,
+};
+
+/*
+ * Memory-map a video buffer.
+ *
+ * This function implements video buffers memory mapping and is intended to be
+ * used by the device mmap handler.
+ */
+int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
+{
+ struct uvc_buffer *uninitialized_var(buffer);
+ struct page *page;
+ unsigned long addr, start, size;
+ unsigned int i;
+ int ret = 0;
+
+ start = vma->vm_start;
+ size = vma->vm_end - vma->vm_start;
+
+ mutex_lock(&queue->mutex);
+
+ for (i = 0; i < queue->count; ++i) {
+ buffer = &queue->buffer[i];
+ if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+ break;
+ }
+
+ if (i == queue->count || size != queue->buf_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /*
+ * VM_IO marks the area as being an mmaped region for I/O to a
+ * device. It also prevents the region from being core dumped.
+ */
+ vma->vm_flags |= VM_IO;
+
+ addr = (unsigned long)queue->mem + buffer->buf.m.offset;
+ while (size > 0) {
+ page = vmalloc_to_page((void *)addr);
+ if ((ret = vm_insert_page(vma, start, page)) < 0)
+ goto done;
+
+ start += PAGE_SIZE;
+ addr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vma->vm_ops = &uvc_vm_ops;
+ vma->vm_private_data = buffer;
+ uvc_vm_open(vma);
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
* Poll the video queue.
*
* This function implements video queue polling and is intended to be used by
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 6d15de9b5204..9005a8d9d5f8 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -101,40 +101,6 @@ done:
*/
/*
- * Mapping V4L2 controls to UVC controls can be straighforward if done well.
- * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
- * must be grouped (for instance the Red Balance, Blue Balance and Do White
- * Balance V4L2 controls use the White Balance Component UVC control) or
- * otherwise translated. The approach we take here is to use a translation
- * table for the controls that can be mapped directly, and handle the others
- * manually.
- */
-static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
- struct v4l2_querymenu *query_menu)
-{
- struct uvc_menu_info *menu_info;
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl;
- u32 index = query_menu->index;
- u32 id = query_menu->id;
-
- ctrl = uvc_find_control(chain, query_menu->id, &mapping);
- if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
- return -EINVAL;
-
- if (query_menu->index >= mapping->menu_count)
- return -EINVAL;
-
- memset(query_menu, 0, sizeof(*query_menu));
- query_menu->id = id;
- query_menu->index = index;
-
- menu_info = &mapping->menu_info[query_menu->index];
- strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
- return 0;
-}
-
-/*
* Find the frame interval closest to the requested frame interval for the
* given frame format and size. This should be done by the device as part of
* the Video Probe and Commit negotiation, but some hardware don't implement
@@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
* developers test their webcams with the Linux driver as well as with
* the Windows driver).
*/
+ mutex_lock(&stream->mutex);
if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
probe->dwMaxVideoFrameSize =
stream->ctrl.dwMaxVideoFrameSize;
/* Probe the device. */
ret = uvc_probe_video(stream, probe);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
goto done;
@@ -289,14 +257,21 @@ done:
static int uvc_v4l2_get_format(struct uvc_streaming *stream,
struct v4l2_format *fmt)
{
- struct uvc_format *format = stream->cur_format;
- struct uvc_frame *frame = stream->cur_frame;
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+ int ret = 0;
if (fmt->type != stream->type)
return -EINVAL;
- if (format == NULL || frame == NULL)
- return -EINVAL;
+ mutex_lock(&stream->mutex);
+ format = stream->cur_format;
+ frame = stream->cur_frame;
+
+ if (format == NULL || frame == NULL) {
+ ret = -EINVAL;
+ goto done;
+ }
fmt->fmt.pix.pixelformat = format->fcc;
fmt->fmt.pix.width = frame->wWidth;
@@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
fmt->fmt.pix.colorspace = format->colorspace;
fmt->fmt.pix.priv = 0;
- return 0;
+done:
+ mutex_unlock(&stream->mutex);
+ return ret;
}
static int uvc_v4l2_set_format(struct uvc_streaming *stream,
@@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
if (fmt->type != stream->type)
return -EINVAL;
- if (uvc_queue_allocated(&stream->queue))
- return -EBUSY;
-
ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
if (ret < 0)
return ret;
+ mutex_lock(&stream->mutex);
+
+ if (uvc_queue_allocated(&stream->queue)) {
+ ret = -EBUSY;
+ goto done;
+ }
+
memcpy(&stream->ctrl, &probe, sizeof probe);
stream->cur_format = format;
stream->cur_frame = frame;
- return 0;
+done:
+ mutex_unlock(&stream->mutex);
+ return ret;
}
static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
@@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
if (parm->type != stream->type)
return -EINVAL;
+ mutex_lock(&stream->mutex);
numerator = stream->ctrl.dwFrameInterval;
+ mutex_unlock(&stream->mutex);
+
denominator = 10000000;
uvc_simplify_fraction(&numerator, &denominator, 8, 333);
@@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
struct v4l2_streamparm *parm)
{
- struct uvc_frame *frame = stream->cur_frame;
struct uvc_streaming_control probe;
struct v4l2_fract timeperframe;
uint32_t interval;
@@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
if (parm->type != stream->type)
return -EINVAL;
- if (uvc_queue_streaming(&stream->queue))
- return -EBUSY;
-
if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
timeperframe = parm->parm.capture.timeperframe;
else
timeperframe = parm->parm.output.timeperframe;
- memcpy(&probe, &stream->ctrl, sizeof probe);
interval = uvc_fraction_to_interval(timeperframe.numerator,
timeperframe.denominator);
-
uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
timeperframe.numerator, timeperframe.denominator, interval);
- probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
+
+ mutex_lock(&stream->mutex);
+
+ if (uvc_queue_streaming(&stream->queue)) {
+ mutex_unlock(&stream->mutex);
+ return -EBUSY;
+ }
+
+ memcpy(&probe, &stream->ctrl, sizeof probe);
+ probe.dwFrameInterval =
+ uvc_try_frame_interval(stream->cur_frame, interval);
/* Probe the device with the new settings. */
ret = uvc_probe_video(stream, &probe);
- if (ret < 0)
+ if (ret < 0) {
+ mutex_unlock(&stream->mutex);
return ret;
+ }
memcpy(&stream->ctrl, &probe, sizeof probe);
+ mutex_unlock(&stream->mutex);
/* Return the actual frame period. */
timeperframe.numerator = probe.dwFrameInterval;
@@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file)
if (uvc_has_privileges(handle)) {
uvc_video_enable(stream, 0);
- mutex_lock(&stream->queue.mutex);
if (uvc_free_buffers(&stream->queue) < 0)
uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
"free buffers.\n");
- mutex_unlock(&stream->queue.mutex);
}
/* Release the file handle. */
@@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
case VIDIOC_QUERYMENU:
- return uvc_v4l2_query_menu(chain, arg);
+ return uvc_query_v4l2_menu(chain, arg);
case VIDIOC_G_EXT_CTRLS:
{
@@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_CROPCAP:
{
struct v4l2_cropcap *ccap = arg;
- struct uvc_frame *frame = stream->cur_frame;
if (ccap->type != stream->type)
return -EINVAL;
ccap->bounds.left = 0;
ccap->bounds.top = 0;
- ccap->bounds.width = frame->wWidth;
- ccap->bounds.height = frame->wHeight;
+
+ mutex_lock(&stream->mutex);
+ ccap->bounds.width = stream->cur_frame->wWidth;
+ ccap->bounds.height = stream->cur_frame->wHeight;
+ mutex_unlock(&stream->mutex);
ccap->defrect = ccap->bounds;
@@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_REQBUFS:
{
struct v4l2_requestbuffers *rb = arg;
- unsigned int bufsize =
- stream->ctrl.dwMaxVideoFrameSize;
if (rb->type != stream->type ||
rb->memory != V4L2_MEMORY_MMAP)
@@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if ((ret = uvc_acquire_privileges(handle)) < 0)
return ret;
- ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
+ mutex_lock(&stream->mutex);
+ ret = uvc_alloc_buffers(&stream->queue, rb->count,
+ stream->ctrl.dwMaxVideoFrameSize);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
return ret;
@@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if (!uvc_has_privileges(handle))
return -EBUSY;
+ mutex_lock(&stream->mutex);
ret = uvc_video_enable(stream, 1);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
return ret;
break;
@@ -1039,11 +1035,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return uvc_xu_ctrl_query(chain, arg, 1);
default:
- if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
- uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
- uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
- cmd);
- return ret;
+ uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
+ return -EINVAL;
}
return ret;
@@ -1068,79 +1061,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
return -EINVAL;
}
-/*
- * VMA operations.
- */
-static void uvc_vm_open(struct vm_area_struct *vma)
-{
- struct uvc_buffer *buffer = vma->vm_private_data;
- buffer->vma_use_count++;
-}
-
-static void uvc_vm_close(struct vm_area_struct *vma)
-{
- struct uvc_buffer *buffer = vma->vm_private_data;
- buffer->vma_use_count--;
-}
-
-static const struct vm_operations_struct uvc_vm_ops = {
- .open = uvc_vm_open,
- .close = uvc_vm_close,
-};
-
static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct uvc_fh *handle = file->private_data;
struct uvc_streaming *stream = handle->stream;
- struct uvc_video_queue *queue = &stream->queue;
- struct uvc_buffer *uninitialized_var(buffer);
- struct page *page;
- unsigned long addr, start, size;
- unsigned int i;
- int ret = 0;
uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
- start = vma->vm_start;
- size = vma->vm_end - vma->vm_start;
-
- mutex_lock(&queue->mutex);
-
- for (i = 0; i < queue->count; ++i) {
- buffer = &queue->buffer[i];
- if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
-
- if (i == queue->count || size != queue->buf_size) {
- ret = -EINVAL;
- goto done;
- }
-
- /*
- * VM_IO marks the area as being an mmaped region for I/O to a
- * device. It also prevents the region from being core dumped.
- */
- vma->vm_flags |= VM_IO;
-
- addr = (unsigned long)queue->mem + buffer->buf.m.offset;
- while (size > 0) {
- page = vmalloc_to_page((void *)addr);
- if ((ret = vm_insert_page(vma, start, page)) < 0)
- goto done;
-
- start += PAGE_SIZE;
- addr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &uvc_vm_ops;
- vma->vm_private_data = buffer;
- uvc_vm_open(vma);
-
-done:
- mutex_unlock(&queue->mutex);
- return ret;
+ return uvc_queue_mmap(&stream->queue, vma);
}
static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
@@ -1157,7 +1085,7 @@ const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open = uvc_v4l2_open,
.release = uvc_v4l2_release,
- .ioctl = uvc_v4l2_ioctl,
+ .unlocked_ioctl = uvc_v4l2_ioctl,
.read = uvc_v4l2_read,
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5555f0102838..5673d673504b 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
unsigned int i;
int ret;
- mutex_lock(&stream->mutex);
-
/* Perform probing. The device should adjust the requested values
* according to its capabilities. However, some devices, namely the
* first generation UVC Logitech webcams, don't implement the Video
@@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
}
done:
- mutex_unlock(&stream->mutex);
return ret;
}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index d97cf6d6a4f9..45f01e7e13d2 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -436,7 +436,9 @@ struct uvc_streaming {
struct uvc_streaming_control ctrl;
struct uvc_format *cur_format;
struct uvc_frame *cur_frame;
-
+ /* Protect access to ctrl, cur_format, cur_frame and hardware video
+ * probe control.
+ */
struct mutex mutex;
unsigned int frozen : 1;
@@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
+extern int uvc_queue_mmap(struct uvc_video_queue *queue,
+ struct vm_area_struct *vma);
extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
struct file *file, poll_table *wait);
extern int uvc_queue_allocated(struct uvc_video_queue *queue);
@@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev);
extern int uvc_status_resume(struct uvc_device *dev);
/* Controls */
-extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
- __u32 v4l2_id, struct uvc_control_mapping **mapping);
extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
struct v4l2_queryctrl *v4l2_ctrl);
+extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+ struct v4l2_querymenu *query_menu);
extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
const struct uvc_control_mapping *mapping);
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
deleted file mode 100644
index d4ac751036a2..000000000000
--- a/drivers/media/video/v4l1-compat.c
+++ /dev/null
@@ -1,1277 +0,0 @@
-/*
- *
- * Video for Linux Two
- * Backward Compatibility Layer
- *
- * Support subroutines for providing V4L2 drivers with backward
- * compatibility with applications using the old API.
- *
- * This program is free software; you can redistribute it and/or
- * 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.
- *
- * Author: Bill Dirks <bill@thedirks.org>
- * et al.
- *
- */
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-MODULE_AUTHOR("Bill Dirks");
-MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
-MODULE_LICENSE("GPL");
-
-#define dprintk(fmt, arg...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\
- } while (0)
-
-/*
- * I O C T L T R A N S L A T I O N
- *
- * From here on down is the code for translating the numerous
- * ioctl commands from the old API to the new API.
- */
-
-static int
-get_v4l_control(struct file *file,
- int cid,
- v4l2_kioctl drv)
-{
- struct v4l2_queryctrl qctrl2;
- struct v4l2_control ctrl2;
- int err;
-
- qctrl2.id = cid;
- err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
- if (err < 0)
- dprintk("VIDIOC_QUERYCTRL: %d\n", err);
- if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl2.id = qctrl2.id;
- err = drv(file, VIDIOC_G_CTRL, &ctrl2);
- if (err < 0) {
- dprintk("VIDIOC_G_CTRL: %d\n", err);
- return 0;
- }
- return DIV_ROUND_CLOSEST((ctrl2.value-qctrl2.minimum) * 65535,
- qctrl2.maximum - qctrl2.minimum);
- }
- return 0;
-}
-
-static int
-set_v4l_control(struct file *file,
- int cid,
- int value,
- v4l2_kioctl drv)
-{
- struct v4l2_queryctrl qctrl2;
- struct v4l2_control ctrl2;
- int err;
-
- qctrl2.id = cid;
- err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
- if (err < 0)
- dprintk("VIDIOC_QUERYCTRL: %d\n", err);
- if (err == 0 &&
- !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
- !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) {
- if (value < 0)
- value = 0;
- if (value > 65535)
- value = 65535;
- if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
- value = 65535;
- ctrl2.id = qctrl2.id;
- ctrl2.value =
- (value * (qctrl2.maximum - qctrl2.minimum)
- + 32767)
- / 65535;
- ctrl2.value += qctrl2.minimum;
- err = drv(file, VIDIOC_S_CTRL, &ctrl2);
- if (err < 0)
- dprintk("VIDIOC_S_CTRL: %d\n", err);
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------- */
-
-static const unsigned int palette2pixelformat[] = {
- [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
- [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
- [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
- [VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24,
- [VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32,
- /* yuv packed pixel */
- [VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV,
- [VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV,
- [VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY,
- /* yuv planar */
- [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
- [VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420,
- [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
- [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
- [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
-};
-
-static unsigned int __pure
-palette_to_pixelformat(unsigned int palette)
-{
- if (palette < ARRAY_SIZE(palette2pixelformat))
- return palette2pixelformat[palette];
- else
- return 0;
-}
-
-static unsigned int __attribute_const__
-pixelformat_to_palette(unsigned int pixelformat)
-{
- int palette = 0;
- switch (pixelformat) {
- case V4L2_PIX_FMT_GREY:
- palette = VIDEO_PALETTE_GREY;
- break;
- case V4L2_PIX_FMT_RGB555:
- palette = VIDEO_PALETTE_RGB555;
- break;
- case V4L2_PIX_FMT_RGB565:
- palette = VIDEO_PALETTE_RGB565;
- break;
- case V4L2_PIX_FMT_BGR24:
- palette = VIDEO_PALETTE_RGB24;
- break;
- case V4L2_PIX_FMT_BGR32:
- palette = VIDEO_PALETTE_RGB32;
- break;
- /* yuv packed pixel */
- case V4L2_PIX_FMT_YUYV:
- palette = VIDEO_PALETTE_YUYV;
- break;
- case V4L2_PIX_FMT_UYVY:
- palette = VIDEO_PALETTE_UYVY;
- break;
- /* yuv planar */
- case V4L2_PIX_FMT_YUV410:
- palette = VIDEO_PALETTE_YUV420;
- break;
- case V4L2_PIX_FMT_YUV420:
- palette = VIDEO_PALETTE_YUV420;
- break;
- case V4L2_PIX_FMT_YUV411P:
- palette = VIDEO_PALETTE_YUV411P;
- break;
- case V4L2_PIX_FMT_YUV422P:
- palette = VIDEO_PALETTE_YUV422P;
- break;
- }
- return palette;
-}
-
-/* ----------------------------------------------------------------- */
-
-static int poll_one(struct file *file, struct poll_wqueues *pwq)
-{
- int retval = 1;
- poll_table *table;
-
- poll_initwait(pwq);
- table = &pwq->pt;
- for (;;) {
- int mask;
- mask = file->f_op->poll(file, table);
- if (mask & POLLIN)
- break;
- table = NULL;
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- poll_schedule(pwq, TASK_INTERRUPTIBLE);
- }
- poll_freewait(pwq);
- return retval;
-}
-
-static int count_inputs(
- struct file *file,
- v4l2_kioctl drv)
-{
- struct v4l2_input input2;
- int i;
-
- for (i = 0;; i++) {
- memset(&input2, 0, sizeof(input2));
- input2.index = i;
- if (0 != drv(file, VIDIOC_ENUMINPUT, &input2))
- break;
- }
- return i;
-}
-
-static int check_size(
- struct file *file,
- v4l2_kioctl drv,
- int *maxw,
- int *maxh)
-{
- struct v4l2_fmtdesc desc2;
- struct v4l2_format fmt2;
-
- memset(&desc2, 0, sizeof(desc2));
- memset(&fmt2, 0, sizeof(fmt2));
-
- desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (0 != drv(file, VIDIOC_ENUM_FMT, &desc2))
- goto done;
-
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt2.fmt.pix.width = 10000;
- fmt2.fmt.pix.height = 10000;
- fmt2.fmt.pix.pixelformat = desc2.pixelformat;
- if (0 != drv(file, VIDIOC_TRY_FMT, &fmt2))
- goto done;
-
- *maxw = fmt2.fmt.pix.width;
- *maxh = fmt2.fmt.pix.height;
-
-done:
- return 0;
-}
-
-/* ----------------------------------------------------------------- */
-
-static noinline long v4l1_compat_get_capabilities(
- struct video_capability *cap,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_framebuffer fbuf;
- struct v4l2_capability *cap2;
-
- cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);
- if (!cap2) {
- err = -ENOMEM;
- return err;
- }
- memset(cap, 0, sizeof(*cap));
- memset(&fbuf, 0, sizeof(fbuf));
-
- err = drv(file, VIDIOC_QUERYCAP, cap2);
- if (err < 0) {
- dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %ld\n", err);
- goto done;
- }
- if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
- err = drv(file, VIDIOC_G_FBUF, &fbuf);
- if (err < 0) {
- dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %ld\n", err);
- memset(&fbuf, 0, sizeof(fbuf));
- }
- err = 0;
- }
-
- memcpy(cap->name, cap2->card,
- min(sizeof(cap->name), sizeof(cap2->card)));
- cap->name[sizeof(cap->name) - 1] = 0;
- if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
- cap->type |= VID_TYPE_CAPTURE;
- if (cap2->capabilities & V4L2_CAP_TUNER)
- cap->type |= VID_TYPE_TUNER;
- if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
- cap->type |= VID_TYPE_TELETEXT;
- if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
- cap->type |= VID_TYPE_OVERLAY;
- if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
- cap->type |= VID_TYPE_CLIPPING;
-
- cap->channels = count_inputs(file, drv);
- check_size(file, drv,
- &cap->maxwidth, &cap->maxheight);
- cap->audios = 0; /* FIXME */
- cap->minwidth = 48; /* FIXME */
- cap->minheight = 32; /* FIXME */
-
-done:
- kfree(cap2);
- return err;
-}
-
-static noinline long v4l1_compat_get_frame_buffer(
- struct video_buffer *buffer,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_framebuffer fbuf;
-
- memset(buffer, 0, sizeof(*buffer));
- memset(&fbuf, 0, sizeof(fbuf));
-
- err = drv(file, VIDIOC_G_FBUF, &fbuf);
- if (err < 0) {
- dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %ld\n", err);
- goto done;
- }
- buffer->base = fbuf.base;
- buffer->height = fbuf.fmt.height;
- buffer->width = fbuf.fmt.width;
-
- switch (fbuf.fmt.pixelformat) {
- case V4L2_PIX_FMT_RGB332:
- buffer->depth = 8;
- break;
- case V4L2_PIX_FMT_RGB555:
- buffer->depth = 15;
- break;
- case V4L2_PIX_FMT_RGB565:
- buffer->depth = 16;
- break;
- case V4L2_PIX_FMT_BGR24:
- buffer->depth = 24;
- break;
- case V4L2_PIX_FMT_BGR32:
- buffer->depth = 32;
- break;
- default:
- buffer->depth = 0;
- }
- if (fbuf.fmt.bytesperline) {
- buffer->bytesperline = fbuf.fmt.bytesperline;
- if (!buffer->depth && buffer->width)
- buffer->depth = ((fbuf.fmt.bytesperline<<3)
- + (buffer->width-1))
- / buffer->width;
- } else {
- buffer->bytesperline =
- (buffer->width * buffer->depth + 7) & 7;
- buffer->bytesperline >>= 3;
- }
-done:
- return err;
-}
-
-static noinline long v4l1_compat_set_frame_buffer(
- struct video_buffer *buffer,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_framebuffer fbuf;
-
- memset(&fbuf, 0, sizeof(fbuf));
- fbuf.base = buffer->base;
- fbuf.fmt.height = buffer->height;
- fbuf.fmt.width = buffer->width;
- switch (buffer->depth) {
- case 8:
- fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
- break;
- case 15:
- fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
- break;
- case 16:
- fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
- break;
- case 24:
- fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
- break;
- case 32:
- fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
- break;
- }
- fbuf.fmt.bytesperline = buffer->bytesperline;
- err = drv(file, VIDIOC_S_FBUF, &fbuf);
- if (err < 0)
- dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %ld\n", err);
- return err;
-}
-
-static noinline long v4l1_compat_get_win_cap_dimensions(
- struct video_window *win,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_format *fmt;
-
- fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
- if (!fmt) {
- err = -ENOMEM;
- return err;
- }
- memset(win, 0, sizeof(*win));
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
- err = drv(file, VIDIOC_G_FMT, fmt);
- if (err < 0)
- dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %ld\n", err);
- if (err == 0) {
- win->x = fmt->fmt.win.w.left;
- win->y = fmt->fmt.win.w.top;
- win->width = fmt->fmt.win.w.width;
- win->height = fmt->fmt.win.w.height;
- win->chromakey = fmt->fmt.win.chromakey;
- win->clips = NULL;
- win->clipcount = 0;
- goto done;
- }
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_G_FMT, fmt);
- if (err < 0) {
- dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %ld\n", err);
- goto done;
- }
- win->x = 0;
- win->y = 0;
- win->width = fmt->fmt.pix.width;
- win->height = fmt->fmt.pix.height;
- win->chromakey = 0;
- win->clips = NULL;
- win->clipcount = 0;
-done:
- kfree(fmt);
- return err;
-}
-
-static noinline long v4l1_compat_set_win_cap_dimensions(
- struct video_window *win,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err, err1, err2;
- struct v4l2_format *fmt;
-
- fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
- if (!fmt) {
- err = -ENOMEM;
- return err;
- }
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- drv(file, VIDIOC_STREAMOFF, &fmt->type);
- err1 = drv(file, VIDIOC_G_FMT, fmt);
- if (err1 < 0)
- dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %ld\n", err1);
- if (err1 == 0) {
- fmt->fmt.pix.width = win->width;
- fmt->fmt.pix.height = win->height;
- fmt->fmt.pix.field = V4L2_FIELD_ANY;
- fmt->fmt.pix.bytesperline = 0;
- err = drv(file, VIDIOC_S_FMT, fmt);
- if (err < 0)
- dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %ld\n",
- err);
- win->width = fmt->fmt.pix.width;
- win->height = fmt->fmt.pix.height;
- }
-
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
- fmt->fmt.win.w.left = win->x;
- fmt->fmt.win.w.top = win->y;
- fmt->fmt.win.w.width = win->width;
- fmt->fmt.win.w.height = win->height;
- fmt->fmt.win.chromakey = win->chromakey;
- fmt->fmt.win.clips = (void __user *)win->clips;
- fmt->fmt.win.clipcount = win->clipcount;
- err2 = drv(file, VIDIOC_S_FMT, fmt);
- if (err2 < 0)
- dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %ld\n", err2);
-
- if (err1 != 0 && err2 != 0)
- err = err1;
- else
- err = 0;
- kfree(fmt);
- return err;
-}
-
-static noinline long v4l1_compat_turn_preview_on_off(
- int *on,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- if (0 == *on) {
- /* dirty hack time. But v4l1 has no STREAMOFF
- * equivalent in the API, and this one at
- * least comes close ... */
- drv(file, VIDIOC_STREAMOFF, &captype);
- }
- err = drv(file, VIDIOC_OVERLAY, on);
- if (err < 0)
- dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld\n", err);
- return err;
-}
-
-static noinline long v4l1_compat_get_input_info(
- struct video_channel *chan,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_input input2;
- v4l2_std_id sid;
-
- memset(&input2, 0, sizeof(input2));
- input2.index = chan->channel;
- err = drv(file, VIDIOC_ENUMINPUT, &input2);
- if (err < 0) {
- dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
- "channel=%d err=%ld\n", chan->channel, err);
- goto done;
- }
- chan->channel = input2.index;
- memcpy(chan->name, input2.name,
- min(sizeof(chan->name), sizeof(input2.name)));
- chan->name[sizeof(chan->name) - 1] = 0;
- chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
- chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
- switch (input2.type) {
- case V4L2_INPUT_TYPE_TUNER:
- chan->type = VIDEO_TYPE_TV;
- break;
- default:
- case V4L2_INPUT_TYPE_CAMERA:
- chan->type = VIDEO_TYPE_CAMERA;
- break;
- }
- chan->norm = 0;
- /* Note: G_STD might not be present for radio receivers,
- * so we should ignore any errors. */
- if (drv(file, VIDIOC_G_STD, &sid) == 0) {
- if (sid & V4L2_STD_PAL)
- chan->norm = VIDEO_MODE_PAL;
- if (sid & V4L2_STD_NTSC)
- chan->norm = VIDEO_MODE_NTSC;
- if (sid & V4L2_STD_SECAM)
- chan->norm = VIDEO_MODE_SECAM;
- if (sid == V4L2_STD_ALL)
- chan->norm = VIDEO_MODE_AUTO;
- }
-done:
- return err;
-}
-
-static noinline long v4l1_compat_set_input(
- struct video_channel *chan,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- v4l2_std_id sid = 0;
-
- err = drv(file, VIDIOC_S_INPUT, &chan->channel);
- if (err < 0)
- dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %ld\n", err);
- switch (chan->norm) {
- case VIDEO_MODE_PAL:
- sid = V4L2_STD_PAL;
- break;
- case VIDEO_MODE_NTSC:
- sid = V4L2_STD_NTSC;
- break;
- case VIDEO_MODE_SECAM:
- sid = V4L2_STD_SECAM;
- break;
- case VIDEO_MODE_AUTO:
- sid = V4L2_STD_ALL;
- break;
- }
- if (0 != sid) {
- err = drv(file, VIDIOC_S_STD, &sid);
- if (err < 0)
- dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err);
- }
- return err;
-}
-
-static noinline long v4l1_compat_get_picture(
- struct video_picture *pict,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_format *fmt;
-
- fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
- if (!fmt) {
- err = -ENOMEM;
- return err;
- }
-
- pict->brightness = get_v4l_control(file,
- V4L2_CID_BRIGHTNESS, drv);
- pict->hue = get_v4l_control(file,
- V4L2_CID_HUE, drv);
- pict->contrast = get_v4l_control(file,
- V4L2_CID_CONTRAST, drv);
- pict->colour = get_v4l_control(file,
- V4L2_CID_SATURATION, drv);
- pict->whiteness = get_v4l_control(file,
- V4L2_CID_WHITENESS, drv);
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_G_FMT, fmt);
- if (err < 0) {
- dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err);
- goto done;
- }
-
- if (fmt->fmt.pix.width)
- {
- pict->depth = ((fmt->fmt.pix.bytesperline << 3)
- + (fmt->fmt.pix.width - 1))
- / fmt->fmt.pix.width;
- } else {
- err = -EINVAL;
- goto done;
- }
-
- pict->palette = pixelformat_to_palette(
- fmt->fmt.pix.pixelformat);
-done:
- kfree(fmt);
- return err;
-}
-
-static noinline long v4l1_compat_set_picture(
- struct video_picture *pict,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_framebuffer fbuf;
- int mem_err = 0, ovl_err = 0;
- struct v4l2_format *fmt;
-
- fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
- if (!fmt) {
- err = -ENOMEM;
- return err;
- }
- memset(&fbuf, 0, sizeof(fbuf));
-
- set_v4l_control(file,
- V4L2_CID_BRIGHTNESS, pict->brightness, drv);
- set_v4l_control(file,
- V4L2_CID_HUE, pict->hue, drv);
- set_v4l_control(file,
- V4L2_CID_CONTRAST, pict->contrast, drv);
- set_v4l_control(file,
- V4L2_CID_SATURATION, pict->colour, drv);
- set_v4l_control(file,
- V4L2_CID_WHITENESS, pict->whiteness, drv);
- /*
- * V4L1 uses this ioctl to set both memory capture and overlay
- * pixel format, while V4L2 has two different ioctls for this.
- * Some cards may not support one or the other, and may support
- * different pixel formats for memory vs overlay.
- */
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_G_FMT, fmt);
- /* If VIDIOC_G_FMT failed, then the driver likely doesn't
- support memory capture. Trying to set the memory capture
- parameters would be pointless. */
- if (err < 0) {
- dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err);
- mem_err = -1000; /* didn't even try */
- } else if (fmt->fmt.pix.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
- fmt->fmt.pix.pixelformat = palette_to_pixelformat(
- pict->palette);
- mem_err = drv(file, VIDIOC_S_FMT, fmt);
- if (mem_err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
- mem_err);
- }
-
- err = drv(file, VIDIOC_G_FBUF, &fbuf);
- /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
- support overlay. Trying to set the overlay parameters
- would be quite pointless. */
- if (err < 0) {
- dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err);
- ovl_err = -1000; /* didn't even try */
- } else if (fbuf.fmt.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
- fbuf.fmt.pixelformat = palette_to_pixelformat(
- pict->palette);
- ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf);
- if (ovl_err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
- ovl_err);
- }
- if (ovl_err < 0 && mem_err < 0) {
- /* ioctl failed, couldn't set either parameter */
- if (mem_err != -1000)
- err = mem_err;
- else if (ovl_err == -EPERM)
- err = 0;
- else
- err = ovl_err;
- } else
- err = 0;
- kfree(fmt);
- return err;
-}
-
-static noinline long v4l1_compat_get_tuner(
- struct video_tuner *tun,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- int i;
- struct v4l2_tuner tun2;
- struct v4l2_standard std2;
- v4l2_std_id sid;
-
- memset(&tun2, 0, sizeof(tun2));
- err = drv(file, VIDIOC_G_TUNER, &tun2);
- if (err < 0) {
- dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err);
- goto done;
- }
- memcpy(tun->name, tun2.name,
- min(sizeof(tun->name), sizeof(tun2.name)));
- tun->name[sizeof(tun->name) - 1] = 0;
- tun->rangelow = tun2.rangelow;
- tun->rangehigh = tun2.rangehigh;
- tun->flags = 0;
- tun->mode = VIDEO_MODE_AUTO;
-
- for (i = 0; i < 64; i++) {
- memset(&std2, 0, sizeof(std2));
- std2.index = i;
- if (0 != drv(file, VIDIOC_ENUMSTD, &std2))
- break;
- if (std2.id & V4L2_STD_PAL)
- tun->flags |= VIDEO_TUNER_PAL;
- if (std2.id & V4L2_STD_NTSC)
- tun->flags |= VIDEO_TUNER_NTSC;
- if (std2.id & V4L2_STD_SECAM)
- tun->flags |= VIDEO_TUNER_SECAM;
- }
-
- /* Note: G_STD might not be present for radio receivers,
- * so we should ignore any errors. */
- if (drv(file, VIDIOC_G_STD, &sid) == 0) {
- if (sid & V4L2_STD_PAL)
- tun->mode = VIDEO_MODE_PAL;
- if (sid & V4L2_STD_NTSC)
- tun->mode = VIDEO_MODE_NTSC;
- if (sid & V4L2_STD_SECAM)
- tun->mode = VIDEO_MODE_SECAM;
- }
-
- if (tun2.capability & V4L2_TUNER_CAP_LOW)
- tun->flags |= VIDEO_TUNER_LOW;
- if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
- tun->flags |= VIDEO_TUNER_STEREO_ON;
- tun->signal = tun2.signal;
-done:
- return err;
-}
-
-static noinline long v4l1_compat_select_tuner(
- struct video_tuner *tun,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_tuner t;/*84 bytes on x86_64*/
- memset(&t, 0, sizeof(t));
-
- t.index = tun->tuner;
-
- err = drv(file, VIDIOC_S_TUNER, &t);
- if (err < 0)
- dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err);
- return err;
-}
-
-static noinline long v4l1_compat_get_frequency(
- unsigned long *freq,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_frequency freq2;
- memset(&freq2, 0, sizeof(freq2));
-
- freq2.tuner = 0;
- err = drv(file, VIDIOC_G_FREQUENCY, &freq2);
- if (err < 0)
- dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err);
- if (0 == err)
- *freq = freq2.frequency;
- return err;
-}
-
-static noinline long v4l1_compat_set_frequency(
- unsigned long *freq,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_frequency freq2;
- memset(&freq2, 0, sizeof(freq2));
-
- drv(file, VIDIOC_G_FREQUENCY, &freq2);
- freq2.frequency = *freq;
- err = drv(file, VIDIOC_S_FREQUENCY, &freq2);
- if (err < 0)
- dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err);
- return err;
-}
-
-static noinline long v4l1_compat_get_audio(
- struct video_audio *aud,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- int i;
- struct v4l2_queryctrl qctrl2;
- struct v4l2_audio aud2;
- struct v4l2_tuner tun2;
- memset(&aud2, 0, sizeof(aud2));
-
- err = drv(file, VIDIOC_G_AUDIO, &aud2);
- if (err < 0) {
- dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err);
- goto done;
- }
- memcpy(aud->name, aud2.name,
- min(sizeof(aud->name), sizeof(aud2.name)));
- aud->name[sizeof(aud->name) - 1] = 0;
- aud->audio = aud2.index;
- aud->flags = 0;
- i = get_v4l_control(file, V4L2_CID_AUDIO_VOLUME, drv);
- if (i >= 0) {
- aud->volume = i;
- aud->flags |= VIDEO_AUDIO_VOLUME;
- }
- i = get_v4l_control(file, V4L2_CID_AUDIO_BASS, drv);
- if (i >= 0) {
- aud->bass = i;
- aud->flags |= VIDEO_AUDIO_BASS;
- }
- i = get_v4l_control(file, V4L2_CID_AUDIO_TREBLE, drv);
- if (i >= 0) {
- aud->treble = i;
- aud->flags |= VIDEO_AUDIO_TREBLE;
- }
- i = get_v4l_control(file, V4L2_CID_AUDIO_BALANCE, drv);
- if (i >= 0) {
- aud->balance = i;
- aud->flags |= VIDEO_AUDIO_BALANCE;
- }
- i = get_v4l_control(file, V4L2_CID_AUDIO_MUTE, drv);
- if (i >= 0) {
- if (i)
- aud->flags |= VIDEO_AUDIO_MUTE;
- aud->flags |= VIDEO_AUDIO_MUTABLE;
- }
- aud->step = 1;
- qctrl2.id = V4L2_CID_AUDIO_VOLUME;
- if (drv(file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
- !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
- aud->step = qctrl2.step;
- aud->mode = 0;
-
- memset(&tun2, 0, sizeof(tun2));
- err = drv(file, VIDIOC_G_TUNER, &tun2);
- if (err < 0) {
- dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err);
- err = 0;
- goto done;
- }
-
- if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
- aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
- aud->mode = VIDEO_SOUND_STEREO;
- else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
- aud->mode = VIDEO_SOUND_MONO;
-done:
- return err;
-}
-
-static noinline long v4l1_compat_set_audio(
- struct video_audio *aud,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_audio aud2;
- struct v4l2_tuner tun2;
-
- memset(&aud2, 0, sizeof(aud2));
- memset(&tun2, 0, sizeof(tun2));
-
- aud2.index = aud->audio;
- err = drv(file, VIDIOC_S_AUDIO, &aud2);
- if (err < 0) {
- dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err);
- goto done;
- }
-
- set_v4l_control(file, V4L2_CID_AUDIO_VOLUME,
- aud->volume, drv);
- set_v4l_control(file, V4L2_CID_AUDIO_BASS,
- aud->bass, drv);
- set_v4l_control(file, V4L2_CID_AUDIO_TREBLE,
- aud->treble, drv);
- set_v4l_control(file, V4L2_CID_AUDIO_BALANCE,
- aud->balance, drv);
- set_v4l_control(file, V4L2_CID_AUDIO_MUTE,
- !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
-
- err = drv(file, VIDIOC_G_TUNER, &tun2);
- if (err < 0)
- dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err);
- if (err == 0) {
- switch (aud->mode) {
- default:
- case VIDEO_SOUND_MONO:
- case VIDEO_SOUND_LANG1:
- tun2.audmode = V4L2_TUNER_MODE_MONO;
- break;
- case VIDEO_SOUND_STEREO:
- tun2.audmode = V4L2_TUNER_MODE_STEREO;
- break;
- case VIDEO_SOUND_LANG2:
- tun2.audmode = V4L2_TUNER_MODE_LANG2;
- break;
- }
- err = drv(file, VIDIOC_S_TUNER, &tun2);
- if (err < 0)
- dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err);
- }
- err = 0;
-done:
- return err;
-}
-
-static noinline long v4l1_compat_capture_frame(
- struct video_mmap *mm,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- struct v4l2_buffer buf;
- struct v4l2_format *fmt;
-
- fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
- if (!fmt) {
- err = -ENOMEM;
- return err;
- }
- memset(&buf, 0, sizeof(buf));
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_G_FMT, fmt);
- if (err < 0) {
- dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err);
- goto done;
- }
- if (mm->width != fmt->fmt.pix.width ||
- mm->height != fmt->fmt.pix.height ||
- palette_to_pixelformat(mm->format) !=
- fmt->fmt.pix.pixelformat) {
- /* New capture format... */
- fmt->fmt.pix.width = mm->width;
- fmt->fmt.pix.height = mm->height;
- fmt->fmt.pix.pixelformat =
- palette_to_pixelformat(mm->format);
- fmt->fmt.pix.field = V4L2_FIELD_ANY;
- fmt->fmt.pix.bytesperline = 0;
- err = drv(file, VIDIOC_S_FMT, fmt);
- if (err < 0) {
- dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err);
- goto done;
- }
- }
- buf.index = mm->frame;
- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_QUERYBUF, &buf);
- if (err < 0) {
- dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err);
- goto done;
- }
- err = drv(file, VIDIOC_QBUF, &buf);
- if (err < 0) {
- dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err);
- goto done;
- }
- err = drv(file, VIDIOC_STREAMON, &captype);
- if (err < 0)
- dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err);
-done:
- kfree(fmt);
- return err;
-}
-
-static noinline long v4l1_compat_sync(
- int *i,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- struct v4l2_buffer buf;
- struct poll_wqueues *pwq;
-
- memset(&buf, 0, sizeof(buf));
- buf.index = *i;
- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(file, VIDIOC_QUERYBUF, &buf);
- if (err < 0) {
- /* No such buffer */
- dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
- goto done;
- }
- if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) {
- /* Buffer is not mapped */
- err = -EINVAL;
- goto done;
- }
-
- /* make sure capture actually runs so we don't block forever */
- err = drv(file, VIDIOC_STREAMON, &captype);
- if (err < 0) {
- dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err);
- goto done;
- }
-
- pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
- /* Loop as long as the buffer is queued, but not done */
- while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
- == V4L2_BUF_FLAG_QUEUED) {
- err = poll_one(file, pwq);
- if (err < 0 || /* error or sleep was interrupted */
- err == 0) /* timeout? Shouldn't occur. */
- break;
- err = drv(file, VIDIOC_QUERYBUF, &buf);
- if (err < 0)
- dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err);
- }
- kfree(pwq);
- if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
- goto done;
- do {
- err = drv(file, VIDIOC_DQBUF, &buf);
- if (err < 0)
- dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err);
- } while (err == 0 && buf.index != *i);
-done:
- return err;
-}
-
-static noinline long v4l1_compat_get_vbi_format(
- struct vbi_format *fmt,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_format *fmt2;
-
- fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
- if (!fmt2) {
- err = -ENOMEM;
- return err;
- }
- fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
-
- err = drv(file, VIDIOC_G_FMT, fmt2);
- if (err < 0) {
- dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err);
- goto done;
- }
- if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
- err = -EINVAL;
- goto done;
- }
- memset(fmt, 0, sizeof(*fmt));
- fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
- fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
- fmt->sample_format = VIDEO_PALETTE_RAW;
- fmt->start[0] = fmt2->fmt.vbi.start[0];
- fmt->count[0] = fmt2->fmt.vbi.count[0];
- fmt->start[1] = fmt2->fmt.vbi.start[1];
- fmt->count[1] = fmt2->fmt.vbi.count[1];
- fmt->flags = fmt2->fmt.vbi.flags & 0x03;
-done:
- kfree(fmt2);
- return err;
-}
-
-static noinline long v4l1_compat_set_vbi_format(
- struct vbi_format *fmt,
- struct file *file,
- v4l2_kioctl drv)
-{
- long err;
- struct v4l2_format *fmt2 = NULL;
-
- if (VIDEO_PALETTE_RAW != fmt->sample_format) {
- err = -EINVAL;
- return err;
- }
-
- fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
- if (!fmt2) {
- err = -ENOMEM;
- return err;
- }
- fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
- fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
- fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate;
- fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- fmt2->fmt.vbi.start[0] = fmt->start[0];
- fmt2->fmt.vbi.count[0] = fmt->count[0];
- fmt2->fmt.vbi.start[1] = fmt->start[1];
- fmt2->fmt.vbi.count[1] = fmt->count[1];
- fmt2->fmt.vbi.flags = fmt->flags;
- err = drv(file, VIDIOC_TRY_FMT, fmt2);
- if (err < 0) {
- dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err);
- goto done;
- }
-
- if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
- fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
- fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY ||
- fmt2->fmt.vbi.start[0] != fmt->start[0] ||
- fmt2->fmt.vbi.count[0] != fmt->count[0] ||
- fmt2->fmt.vbi.start[1] != fmt->start[1] ||
- fmt2->fmt.vbi.count[1] != fmt->count[1] ||
- fmt2->fmt.vbi.flags != fmt->flags) {
- err = -EINVAL;
- goto done;
- }
- err = drv(file, VIDIOC_S_FMT, fmt2);
- if (err < 0)
- dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err);
-done:
- kfree(fmt2);
- return err;
-}
-
-/*
- * This function is exported.
- */
-long
-v4l_compat_translate_ioctl(struct file *file,
- int cmd,
- void *arg,
- v4l2_kioctl drv)
-{
- long err;
-
- switch (cmd) {
- case VIDIOCGCAP: /* capability */
- err = v4l1_compat_get_capabilities(arg, file, drv);
- break;
- case VIDIOCGFBUF: /* get frame buffer */
- err = v4l1_compat_get_frame_buffer(arg, file, drv);
- break;
- case VIDIOCSFBUF: /* set frame buffer */
- err = v4l1_compat_set_frame_buffer(arg, file, drv);
- break;
- case VIDIOCGWIN: /* get window or capture dimensions */
- err = v4l1_compat_get_win_cap_dimensions(arg, file, drv);
- break;
- case VIDIOCSWIN: /* set window and/or capture dimensions */
- err = v4l1_compat_set_win_cap_dimensions(arg, file, drv);
- break;
- case VIDIOCCAPTURE: /* turn on/off preview */
- err = v4l1_compat_turn_preview_on_off(arg, file, drv);
- break;
- case VIDIOCGCHAN: /* get input information */
- err = v4l1_compat_get_input_info(arg, file, drv);
- break;
- case VIDIOCSCHAN: /* set input */
- err = v4l1_compat_set_input(arg, file, drv);
- break;
- case VIDIOCGPICT: /* get tone controls & partial capture format */
- err = v4l1_compat_get_picture(arg, file, drv);
- break;
- case VIDIOCSPICT: /* set tone controls & partial capture format */
- err = v4l1_compat_set_picture(arg, file, drv);
- break;
- case VIDIOCGTUNER: /* get tuner information */
- err = v4l1_compat_get_tuner(arg, file, drv);
- break;
- case VIDIOCSTUNER: /* select a tuner input */
- err = v4l1_compat_select_tuner(arg, file, drv);
- break;
- case VIDIOCGFREQ: /* get frequency */
- err = v4l1_compat_get_frequency(arg, file, drv);
- break;
- case VIDIOCSFREQ: /* set frequency */
- err = v4l1_compat_set_frequency(arg, file, drv);
- break;
- case VIDIOCGAUDIO: /* get audio properties/controls */
- err = v4l1_compat_get_audio(arg, file, drv);
- break;
- case VIDIOCSAUDIO: /* set audio controls */
- err = v4l1_compat_set_audio(arg, file, drv);
- break;
- case VIDIOCMCAPTURE: /* capture a frame */
- err = v4l1_compat_capture_frame(arg, file, drv);
- break;
- case VIDIOCSYNC: /* wait for a frame */
- err = v4l1_compat_sync(arg, file, drv);
- break;
- case VIDIOCGVBIFMT: /* query VBI data capture format */
- err = v4l1_compat_get_vbi_format(arg, file, drv);
- break;
- case VIDIOCSVBIFMT:
- err = v4l1_compat_set_vbi_format(arg, file, drv);
- break;
- default:
- err = -ENOIOCTLCMD;
- break;
- }
-
- return err;
-}
-EXPORT_SYMBOL(v4l_compat_translate_ioctl);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 9294282b5add..3f0871b550ad 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -150,7 +150,7 @@ EXPORT_SYMBOL(v4l2_prio_check);
struct v4l2_queryctrl and the available menu items. Note that
menu_items may be NULL, in that case it is ignored. */
int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
- const char **menu_items)
+ const char * const *menu_items)
{
if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
return -EINVAL;
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill);
If menu_items is NULL, then the menu items are retrieved using
v4l2_ctrl_get_menu. */
int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
- const char **menu_items)
+ const char * const *menu_items)
{
int i;
@@ -222,7 +222,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu);
Use this if there are 'holes' in the list of valid menu items. */
int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
{
- const char **menu_items = v4l2_ctrl_get_menu(qmenu->id);
+ const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id);
qmenu->reserved = 0;
if (menu_items == NULL || ids == NULL)
@@ -368,18 +368,15 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
/* Load an i2c sub-device. */
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter, const char *module_name,
- struct i2c_board_info *info, const unsigned short *probe_addrs)
+ struct i2c_adapter *adapter, struct i2c_board_info *info,
+ const unsigned short *probe_addrs)
{
struct v4l2_subdev *sd = NULL;
struct i2c_client *client;
BUG_ON(!v4l2_dev);
- if (module_name)
- request_module(module_name);
- else
- request_module(I2C_MODULE_PREFIX "%s", info->type);
+ request_module(I2C_MODULE_PREFIX "%s", info->type);
/* Create the i2c client */
if (info->addr == 0 && probe_addrs)
@@ -432,8 +429,7 @@ error:
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter,
- const char *module_name, const char *client_type,
+ struct i2c_adapter *adapter, const char *client_type,
int irq, void *platform_data,
u8 addr, const unsigned short *probe_addrs)
{
@@ -447,8 +443,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
info.irq = irq;
info.platform_data = platform_data;
- return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
- &info, probe_addrs);
+ return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index e30e8dfb6205..65e6f133dd35 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -15,219 +15,12 @@
#include <linux/compat.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls*/
-#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/v4l2-ioctl.h>
#ifdef CONFIG_COMPAT
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-struct video_tuner32 {
- compat_int_t tuner;
- char name[32];
- compat_ulong_t rangelow, rangehigh;
- u32 flags; /* It is really u32 in videodev.h */
- u16 mode, signal;
-};
-
-static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
-{
- if (!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||
- get_user(kp->tuner, &up->tuner) ||
- copy_from_user(kp->name, up->name, 32) ||
- get_user(kp->rangelow, &up->rangelow) ||
- get_user(kp->rangehigh, &up->rangehigh) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->mode, &up->mode) ||
- get_user(kp->signal, &up->signal))
- return -EFAULT;
- return 0;
-}
-
-static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||
- put_user(kp->tuner, &up->tuner) ||
- copy_to_user(up->name, kp->name, 32) ||
- put_user(kp->rangelow, &up->rangelow) ||
- put_user(kp->rangehigh, &up->rangehigh) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->mode, &up->mode) ||
- put_user(kp->signal, &up->signal))
- return -EFAULT;
- return 0;
-}
-
-struct video_buffer32 {
- compat_caddr_t base;
- compat_int_t height, width, depth, bytesperline;
-};
-
-static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
-{
- u32 tmp;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct video_buffer32)) ||
- get_user(tmp, &up->base) ||
- get_user(kp->height, &up->height) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->depth, &up->depth) ||
- get_user(kp->bytesperline, &up->bytesperline))
- return -EFAULT;
-
- /* This is actually a physical address stored
- * as a void pointer.
- */
- kp->base = (void *)(unsigned long) tmp;
-
- return 0;
-}
-
-static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
-{
- u32 tmp = (u32)((unsigned long)kp->base);
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||
- put_user(tmp, &up->base) ||
- put_user(kp->height, &up->height) ||
- put_user(kp->width, &up->width) ||
- put_user(kp->depth, &up->depth) ||
- put_user(kp->bytesperline, &up->bytesperline))
- return -EFAULT;
- return 0;
-}
-
-struct video_clip32 {
- s32 x, y, width, height; /* It's really s32 in videodev.h */
- compat_caddr_t next;
-};
-
-struct video_window32 {
- u32 x, y, width, height, chromakey, flags;
- compat_caddr_t clips;
- compat_int_t clipcount;
-};
-
-static int get_video_window32(struct video_window *kp, struct video_window32 __user *up)
-{
- struct video_clip __user *uclips;
- struct video_clip __user *kclips;
- compat_caddr_t p;
- int nclips;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)))
- return -EFAULT;
-
- if (get_user(nclips, &up->clipcount))
- return -EFAULT;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)) ||
- get_user(kp->x, &up->x) ||
- get_user(kp->y, &up->y) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->height, &up->height) ||
- get_user(kp->chromakey, &up->chromakey) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->clipcount, &up->clipcount))
- return -EFAULT;
-
- nclips = kp->clipcount;
- kp->clips = NULL;
-
- if (nclips == 0)
- return 0;
- if (get_user(p, &up->clips))
- return -EFAULT;
- uclips = compat_ptr(p);
-
- /* If nclips < 0, then it is a clipping bitmap of size
- VIDEO_CLIPMAP_SIZE */
- if (nclips < 0) {
- if (!access_ok(VERIFY_READ, uclips, VIDEO_CLIPMAP_SIZE))
- return -EFAULT;
- kp->clips = compat_alloc_user_space(VIDEO_CLIPMAP_SIZE);
- if (copy_in_user(kp->clips, uclips, VIDEO_CLIPMAP_SIZE))
- return -EFAULT;
- return 0;
- }
-
- /* Otherwise it is an array of video_clip structs. */
- if (!access_ok(VERIFY_READ, uclips, nclips * sizeof(struct video_clip)))
- return -EFAULT;
-
- kp->clips = compat_alloc_user_space(nclips * sizeof(struct video_clip));
- kclips = kp->clips;
- while (nclips--) {
- int err;
-
- err = copy_in_user(&kclips->x, &uclips->x, sizeof(kclips->x));
- err |= copy_in_user(&kclips->y, &uclips->y, sizeof(kclips->y));
- err |= copy_in_user(&kclips->width, &uclips->width, sizeof(kclips->width));
- err |= copy_in_user(&kclips->height, &uclips->height, sizeof(kclips->height));
- kclips->next = NULL;
- if (err)
- return -EFAULT;
- kclips++;
- uclips++;
- }
- return 0;
-}
-
-/* You get back everything except the clips... */
-static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||
- put_user(kp->x, &up->x) ||
- put_user(kp->y, &up->y) ||
- put_user(kp->width, &up->width) ||
- put_user(kp->height, &up->height) ||
- put_user(kp->chromakey, &up->chromakey) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->clipcount, &up->clipcount))
- return -EFAULT;
- return 0;
-}
-
-struct video_code32 {
- char loadwhat[16]; /* name or tag of file being passed */
- compat_int_t datasize;
- compat_uptr_t data;
-};
-
-static struct video_code __user *get_microcode32(struct video_code32 *kp)
-{
- struct video_code __user *up;
-
- up = compat_alloc_user_space(sizeof(*up));
-
- /*
- * NOTE! We don't actually care if these fail. If the
- * user address is invalid, the native ioctl will do
- * the error handling for us
- */
- (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat));
- (void) put_user(kp->datasize, &up->datasize);
- (void) put_user(compat_ptr(kp->data), &up->data);
- return up;
-}
-
-#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
-#define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32)
-#define VIDIOCGWIN32 _IOR('v', 9, struct video_window32)
-#define VIDIOCSWIN32 _IOW('v', 10, struct video_window32)
-#define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32)
-#define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32)
-#define VIDIOCGFREQ32 _IOR('v', 14, u32)
-#define VIDIOCSFREQ32 _IOW('v', 15, u32)
-#define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32)
-
-#define VIDIOCCAPTURE32 _IOW('v', 8, s32)
-#define VIDIOCSYNC32 _IOW('v', 18, s32)
-#define VIDIOCSWRITEMODE32 _IOW('v', 25, s32)
-
-#endif
-
static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = -ENOIOCTLCMD;
@@ -741,13 +534,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
union {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- struct video_tuner vt;
- struct video_buffer vb;
- struct video_window vw;
- struct video_code32 vc;
- struct video_audio va;
-#endif
struct v4l2_format v2f;
struct v4l2_buffer v2b;
struct v4l2_framebuffer v2fb;
@@ -763,17 +549,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
/* First, convert the command. */
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
- case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
- case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
- case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
- case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
- case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
- case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
- case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
- case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break;
-#endif
case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
@@ -800,46 +575,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
}
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCSTUNER:
- case VIDIOCGTUNER:
- err = get_video_tuner32(&karg.vt, up);
- compatible_arg = 0;
- break;
-
- case VIDIOCSFBUF:
- err = get_video_buffer32(&karg.vb, up);
- compatible_arg = 0;
- break;
-
- case VIDIOCSWIN:
- err = get_video_window32(&karg.vw, up);
- compatible_arg = 0;
- break;
-
- case VIDIOCGWIN:
- case VIDIOCGFBUF:
- case VIDIOCGFREQ:
- compatible_arg = 0;
- break;
-
- case VIDIOCSMICROCODE:
- /* Copy the 32-bit "video_code32" to kernel space */
- if (copy_from_user(&karg.vc, up, sizeof(karg.vc)))
- return -EFAULT;
- /* Convert the 32-bit version to a 64-bit version in user space */
- up = get_microcode32(&karg.vc);
- break;
-
- case VIDIOCSFREQ:
- err = get_user(karg.vx, (u32 __user *)up);
- compatible_arg = 0;
- break;
-
- case VIDIOCCAPTURE:
- case VIDIOCSYNC:
- case VIDIOCSWRITEMODE:
-#endif
case VIDIOC_OVERLAY:
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
@@ -922,23 +657,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
return err;
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGTUNER:
- err = put_video_tuner32(&karg.vt, up);
- break;
-
- case VIDIOCGWIN:
- err = put_video_window32(&karg.vw, up);
- break;
-
- case VIDIOCGFBUF:
- err = put_video_buffer32(&karg.vb, up);
- break;
-
- case VIDIOCGFREQ:
- err = put_user(((u32)karg.vx), (u32 __user *)up);
- break;
-#endif
case VIDIOC_S_INPUT:
case VIDIOC_S_OUTPUT:
case VIDIOC_G_INPUT:
@@ -981,37 +699,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGCAP:
- case VIDIOCGCHAN:
- case VIDIOCSCHAN:
- case VIDIOCGTUNER32:
- case VIDIOCSTUNER32:
- case VIDIOCGPICT:
- case VIDIOCSPICT:
- case VIDIOCCAPTURE32:
- case VIDIOCGWIN32:
- case VIDIOCSWIN32:
- case VIDIOCGFBUF32:
- case VIDIOCSFBUF32:
- case VIDIOCKEY:
- case VIDIOCGFREQ32:
- case VIDIOCSFREQ32:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- case VIDIOCSYNC32:
- case VIDIOCMCAPTURE:
- case VIDIOCGMBUF:
- case VIDIOCGUNIT:
- case VIDIOCGCAPTURE:
- case VIDIOCSCAPTURE:
- case VIDIOCSPLAYMODE:
- case VIDIOCSWRITEMODE32:
- case VIDIOCGPLAYINFO:
- case VIDIOCSMICROCODE32:
- case VIDIOCGVBIFMT:
- case VIDIOCSVBIFMT:
-#endif
#ifdef __OLD_VIDIOC_
case VIDIOC_OVERLAY32_OLD:
case VIDIOC_S_PARM_OLD:
@@ -1096,19 +783,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
ret = do_video_ioctl(file, cmd, arg);
break;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* BTTV specific... */
- case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]):
- case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]):
- case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int):
- case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */
- case _IOR('v' , BASE_VIDIOCPRIVATE+4, int):
- case _IOR('v' , BASE_VIDIOCPRIVATE+5, int):
- case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
- case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
- ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
- break;
-#endif
default:
printk(KERN_WARNING "compat_ioctl32: "
"unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 9d2502cd03ff..8f81efcfcf56 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -38,15 +38,15 @@ struct ctrl_helper {
the given control ID. The pointer array ends with a NULL pointer.
An empty string signifies a menu entry that is invalid. This allows
drivers to disable certain options if it is not supported. */
-const char **v4l2_ctrl_get_menu(u32 id)
+const char * const *v4l2_ctrl_get_menu(u32 id)
{
- static const char *mpeg_audio_sampling_freq[] = {
+ static const char * const mpeg_audio_sampling_freq[] = {
"44.1 kHz",
"48 kHz",
"32 kHz",
NULL
};
- static const char *mpeg_audio_encoding[] = {
+ static const char * const mpeg_audio_encoding[] = {
"MPEG-1/2 Layer I",
"MPEG-1/2 Layer II",
"MPEG-1/2 Layer III",
@@ -54,7 +54,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
"AC-3",
NULL
};
- static const char *mpeg_audio_l1_bitrate[] = {
+ static const char * const mpeg_audio_l1_bitrate[] = {
"32 kbps",
"64 kbps",
"96 kbps",
@@ -71,7 +71,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
"448 kbps",
NULL
};
- static const char *mpeg_audio_l2_bitrate[] = {
+ static const char * const mpeg_audio_l2_bitrate[] = {
"32 kbps",
"48 kbps",
"56 kbps",
@@ -88,7 +88,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
"384 kbps",
NULL
};
- static const char *mpeg_audio_l3_bitrate[] = {
+ static const char * const mpeg_audio_l3_bitrate[] = {
"32 kbps",
"40 kbps",
"48 kbps",
@@ -105,7 +105,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
"320 kbps",
NULL
};
- static const char *mpeg_audio_ac3_bitrate[] = {
+ static const char * const mpeg_audio_ac3_bitrate[] = {
"32 kbps",
"40 kbps",
"48 kbps",
@@ -127,50 +127,50 @@ const char **v4l2_ctrl_get_menu(u32 id)
"640 kbps",
NULL
};
- static const char *mpeg_audio_mode[] = {
+ static const char * const mpeg_audio_mode[] = {
"Stereo",
"Joint Stereo",
"Dual",
"Mono",
NULL
};
- static const char *mpeg_audio_mode_extension[] = {
+ static const char * const mpeg_audio_mode_extension[] = {
"Bound 4",
"Bound 8",
"Bound 12",
"Bound 16",
NULL
};
- static const char *mpeg_audio_emphasis[] = {
+ static const char * const mpeg_audio_emphasis[] = {
"No Emphasis",
"50/15 us",
"CCITT J17",
NULL
};
- static const char *mpeg_audio_crc[] = {
+ static const char * const mpeg_audio_crc[] = {
"No CRC",
"16-bit CRC",
NULL
};
- static const char *mpeg_video_encoding[] = {
+ static const char * const mpeg_video_encoding[] = {
"MPEG-1",
"MPEG-2",
"MPEG-4 AVC",
NULL
};
- static const char *mpeg_video_aspect[] = {
+ static const char * const mpeg_video_aspect[] = {
"1x1",
"4x3",
"16x9",
"2.21x1",
NULL
};
- static const char *mpeg_video_bitrate_mode[] = {
+ static const char * const mpeg_video_bitrate_mode[] = {
"Variable Bitrate",
"Constant Bitrate",
NULL
};
- static const char *mpeg_stream_type[] = {
+ static const char * const mpeg_stream_type[] = {
"MPEG-2 Program Stream",
"MPEG-2 Transport Stream",
"MPEG-1 System Stream",
@@ -179,25 +179,25 @@ const char **v4l2_ctrl_get_menu(u32 id)
"MPEG-2 SVCD-compatible Stream",
NULL
};
- static const char *mpeg_stream_vbi_fmt[] = {
+ static const char * const mpeg_stream_vbi_fmt[] = {
"No VBI",
"Private packet, IVTV format",
NULL
};
- static const char *camera_power_line_frequency[] = {
+ static const char * const camera_power_line_frequency[] = {
"Disabled",
"50 Hz",
"60 Hz",
NULL
};
- static const char *camera_exposure_auto[] = {
+ static const char * const camera_exposure_auto[] = {
"Auto Mode",
"Manual Mode",
"Shutter Priority Mode",
"Aperture Priority Mode",
NULL
};
- static const char *colorfx[] = {
+ static const char * const colorfx[] = {
"None",
"Black & White",
"Sepia",
@@ -210,7 +210,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
"Vivid",
NULL
};
- static const char *tune_preemphasis[] = {
+ static const char * const tune_preemphasis[] = {
"No preemphasis",
"50 useconds",
"75 useconds",
@@ -952,7 +952,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, const char *name, enum v4l2_ctrl_type type,
s32 min, s32 max, u32 step, s32 def,
- u32 flags, const char **qmenu, void *priv)
+ u32 flags, const char * const *qmenu, void *priv)
{
struct v4l2_ctrl *ctrl;
unsigned sz_extra = 0;
@@ -962,13 +962,20 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
/* Sanity checks */
if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE ||
- def < min || def > max || max < min ||
+ max < min ||
(type == V4L2_CTRL_TYPE_INTEGER && step == 0) ||
(type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
(type == V4L2_CTRL_TYPE_STRING && max == 0)) {
handler_set_err(hdl, -ERANGE);
return NULL;
}
+ if ((type == V4L2_CTRL_TYPE_INTEGER ||
+ type == V4L2_CTRL_TYPE_MENU ||
+ type == V4L2_CTRL_TYPE_BOOLEAN) &&
+ (def < min || def > max)) {
+ handler_set_err(hdl, -ERANGE);
+ return NULL;
+ }
if (type == V4L2_CTRL_TYPE_BUTTON)
flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -1019,7 +1026,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
bool is_menu;
struct v4l2_ctrl *ctrl;
const char *name = cfg->name;
- const char **qmenu = cfg->qmenu;
+ const char * const *qmenu = cfg->qmenu;
enum v4l2_ctrl_type type = cfg->type;
u32 flags = cfg->flags;
s32 min = cfg->min;
@@ -1075,7 +1082,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 mask, s32 def)
{
- const char **qmenu = v4l2_ctrl_get_menu(id);
+ const char * const *qmenu = v4l2_ctrl_get_menu(id);
const char *name;
enum v4l2_ctrl_type type;
s32 min;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 03f7f4670e9b..359e23290a7e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
size_t sz, loff_t *off)
{
struct video_device *vdev = video_devdata(filp);
- int ret = -EIO;
+ int ret = -ENODEV;
if (!vdev->fops->read)
return -EINVAL;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->read(filp, buf, sz, off);
if (vdev->lock)
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
size_t sz, loff_t *off)
{
struct video_device *vdev = video_devdata(filp);
- int ret = -EIO;
+ int ret = -ENODEV;
if (!vdev->fops->write)
return -EINVAL;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->write(filp, buf, sz, off);
if (vdev->lock)
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
{
struct video_device *vdev = video_devdata(filp);
- int ret = DEFAULT_POLLMASK;
+ int ret = POLLERR | POLLHUP;
if (!vdev->fops->poll)
- return ret;
+ return DEFAULT_POLLMASK;
if (vdev->lock)
mutex_lock(vdev->lock);
if (video_is_registered(vdev))
@@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
int ret = -ENODEV;
if (vdev->fops->unlocked_ioctl) {
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
if (vdev->lock)
mutex_unlock(vdev->lock);
} else if (vdev->fops->ioctl) {
- /* TODO: convert all drivers to unlocked_ioctl */
+ /* This code path is a replacement for the BKL. It is a major
+ * hack but it will have to do for those drivers that are not
+ * yet converted to use unlocked_ioctl.
+ *
+ * There are two options: if the driver implements struct
+ * v4l2_device, then the lock defined there is used to
+ * serialize the ioctls. Otherwise the v4l2 core lock defined
+ * below is used. This lock is really bad since it serializes
+ * completely independent devices.
+ *
+ * Both variants suffer from the same problem: if the driver
+ * sleeps, then it blocks all ioctls since the lock is still
+ * held. This is very common for VIDIOC_DQBUF since that
+ * normally waits for a frame to arrive. As a result any other
+ * ioctl calls will proceed very, very slowly since each call
+ * will have to wait for the VIDIOC_QBUF to finish. Things that
+ * should take 0.01s may now take 10-20 seconds.
+ *
+ * The workaround is to *not* take the lock for VIDIOC_DQBUF.
+ * This actually works OK for videobuf-based drivers, since
+ * videobuf will take its own internal lock.
+ */
static DEFINE_MUTEX(v4l2_ioctl_mutex);
+ struct mutex *m = vdev->v4l2_dev ?
+ &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
- mutex_lock(&v4l2_ioctl_mutex);
+ if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->ioctl(filp, cmd, arg);
- mutex_unlock(&v4l2_ioctl_mutex);
+ if (cmd != VIDIOC_DQBUF)
+ mutex_unlock(m);
} else
ret = -ENOTTY;
@@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
if (!vdev->fops->mmap)
return ret;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->mmap(filp, vm);
if (vdev->lock)
@@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
mutex_lock(&videodev_lock);
vdev = video_devdata(filp);
/* return ENODEV if the video device has already been removed. */
- if (vdev == NULL) {
+ if (vdev == NULL || !video_is_registered(vdev)) {
mutex_unlock(&videodev_lock);
return -ENODEV;
}
@@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
video_get(vdev);
mutex_unlock(&videodev_lock);
if (vdev->fops->open) {
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
+ ret = -ERESTARTSYS;
+ goto err;
+ }
if (video_is_registered(vdev))
ret = vdev->fops->open(filp);
else
@@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
mutex_unlock(vdev->lock);
}
+err:
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
@@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev)
if (!vdev || !video_is_registered(vdev))
return;
+ mutex_lock(&videodev_lock);
+ /* This must be in a critical section to prevent a race with v4l2_open.
+ * Once this bit has been cleared video_get may never be called again.
+ */
clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
+ mutex_unlock(&videodev_lock);
device_unregister(&vdev->dev);
}
EXPORT_SYMBOL(video_unregister_device);
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 0b08f96b74a5..7fe6f92af480 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
+ mutex_init(&v4l2_dev->ioctl_lock);
v4l2_dev->dev = dev;
if (dev == NULL) {
/* If dev == NULL, then name must be filled in by the caller */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index dd9283fcb564..7e47f15f350d 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -18,12 +18,8 @@
#include <linux/kernel.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls */
-#include <linux/videodev.h>
#include <linux/videodev2.h>
-#ifdef CONFIG_VIDEO_V4L1
-#include <linux/videodev.h>
-#endif
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
@@ -183,42 +179,6 @@ static const char *v4l2_memory_names[] = {
/* ------------------------------------------------------------------ */
/* debug help functions */
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static const char *v4l1_ioctls[] = {
- [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
- [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
- [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
- [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
- [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
- [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
- [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
- [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
- [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
- [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
- [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
- [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
- [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
- [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
- [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
- [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
- [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
- [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
- [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
- [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
- [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
- [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
- [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
- [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
- [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
- [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
- [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
- [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
- [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
-};
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-#endif
-
static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
[_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
@@ -310,15 +270,6 @@ void v4l_printk_ioctl(unsigned int cmd)
case 'd':
type = "v4l2_int";
break;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case 'v':
- if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
- type = "v4l1";
- break;
- }
- printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
- return;
-#endif
case 'V':
if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
type = "v4l2";
@@ -622,20 +573,6 @@ static long __video_do_ioctl(struct file *file,
return -EINVAL;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /********************************************************
- All other V4L1 calls are handled by v4l1_compat module.
- Those calls will be translated into V4L2 calls, and
- __video_do_ioctl will be called again, with one or more
- V4L2 ioctls.
- ********************************************************/
- if (_IOC_TYPE(cmd) == 'v' && cmd != VIDIOCGMBUF &&
- _IOC_NR(cmd) < BASE_VIDIOCPRIVATE) {
- return v4l_compat_translate_ioctl(file, cmd, arg,
- __video_do_ioctl);
- }
-#endif
-
if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
v4l_print_ioctl(vfd->name, cmd);
@@ -644,29 +581,6 @@ static long __video_do_ioctl(struct file *file,
switch (cmd) {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /***********************************************************
- Handles calls to the obsoleted V4L1 API
- Due to the nature of VIDIOCGMBUF, each driver that supports
- V4L1 should implement its own handler for this ioctl.
- ***********************************************************/
-
- /* --- streaming capture ------------------------------------- */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *p = arg;
-
- if (!ops->vidiocgmbuf)
- break;
- ret = ops->vidiocgmbuf(file, fh, p);
- if (!ret)
- dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
- p->size, p->frames,
- (unsigned long)p->offsets);
- break;
- }
-#endif
-
/* --- capabilities ------------------------------------------ */
case VIDIOC_QUERYCAP:
{
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 02a21bccae18..e25aca5759fb 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -1161,16 +1161,6 @@ out:
return ret;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int viacam_vidiocgmbuf(struct file *filp, void *priv,
- struct video_mbuf *mbuf)
-{
- struct via_camera *cam = priv;
-
- return videobuf_cgmbuf(&cam->vb_queue, mbuf, 6);
-}
-#endif
-
/* G/S_PARM */
static int viacam_g_parm(struct file *filp, void *priv,
@@ -1251,9 +1241,6 @@ static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
.vidioc_s_parm = viacam_s_parm,
.vidioc_enum_framesizes = viacam_enum_framesizes,
.vidioc_enum_frameintervals = viacam_enum_frameintervals,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = viacam_vidiocgmbuf,
-#endif
};
/*----------------------------------------------------------------------------*/
@@ -1360,7 +1347,7 @@ static __devinit int viacam_probe(struct platform_device *pdev)
*/
sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter,
- "ov7670", "ov7670", 0x42 >> 1, NULL);
+ "ov7670", 0x42 >> 1, NULL);
if (cam->sensor == NULL) {
dev_err(&pdev->dev, "Unable to find the sensor!\n");
ret = -ENODEV;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 8979f91fa8e5..de4fa4eb8844 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -1202,33 +1202,3 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
return rc;
}
EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-int videobuf_cgmbuf(struct videobuf_queue *q,
- struct video_mbuf *mbuf, int count)
-{
- struct v4l2_requestbuffers req;
- int rc, i;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- memset(&req, 0, sizeof(req));
- req.type = q->type;
- req.count = count;
- req.memory = V4L2_MEMORY_MMAP;
- rc = videobuf_reqbufs(q, &req);
- if (rc < 0)
- return rc;
-
- mbuf->frames = req.count;
- mbuf->size = 0;
- for (i = 0; i < mbuf->frames; i++) {
- mbuf->offsets[i] = q->bufs[i]->boff;
- mbuf->size += PAGE_ALIGN(q->bufs[i]->bsize);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
-#endif
-
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 20f227ee2b3e..ddb8f4b46c03 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -69,10 +69,9 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt,
struct page *pg;
int i;
- sglist = vmalloc(nr_pages * sizeof(*sglist));
+ sglist = vzalloc(nr_pages * sizeof(*sglist));
if (NULL == sglist)
return NULL;
- memset(sglist, 0, nr_pages * sizeof(*sglist));
sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
@@ -544,14 +543,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
retval = -EINVAL;
- /* This function maintains backwards compatibility with V4L1 and will
- * map more than one buffer if the vma length is equal to the combined
- * size of multiple buffers than it will map them together. See
- * VIDIOCGMBUF in the v4l spec
- *
- * TODO: Allow drivers to specify if they support this mode
- */
-
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
@@ -571,29 +562,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
}
last = first;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- if (size != (vma->vm_end - vma->vm_start)) {
- /* look for last buffer to map */
- for (last = first + 1; last < VIDEO_MAX_FRAME; last++) {
- if (NULL == q->bufs[last])
- continue;
- if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
- continue;
- if (q->bufs[last]->map) {
- retval = -EBUSY;
- goto done;
- }
- size += PAGE_ALIGN(q->bufs[last]->bsize);
- if (size == (vma->vm_end - vma->vm_start))
- break;
- }
- if (VIDEO_MAX_FRAME == last) {
- dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n",
- (vma->vm_end - vma->vm_start));
- goto done;
- }
- }
-#endif
/* create mapping + update buffer list */
retval = -ENOMEM;
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index e5e005dc1554..d63e9d978493 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -2954,9 +2954,6 @@ static int vino_enum_input(struct file *file, void *__fh,
if (input == VINO_INPUT_NONE)
return -EINVAL;
- memset(i, 0, sizeof(struct v4l2_input));
-
- i->index = index;
i->type = V4L2_INPUT_TYPE_CAMERA;
i->std = vino_inputs[input].std;
strcpy(i->name, vino_inputs[input].name);
@@ -4334,10 +4331,10 @@ static int __init vino_module_init(void)
vino_drvdata->decoder =
v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- NULL, "saa7191", 0, I2C_ADDRS(0x45));
+ "saa7191", 0, I2C_ADDRS(0x45));
vino_drvdata->camera =
v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- NULL, "indycam", 0, I2C_ADDRS(0x2b));
+ "indycam", 0, I2C_ADDRS(0x2b));
dprintk("init complete!\n");
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 9797e5a69265..c49c39386bd0 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -870,15 +870,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
file->f_flags & O_NONBLOCK);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct vivi_dev *dev = video_drvdata(file);
-
- return videobuf_cgmbuf(&dev->vb_vidq, mbuf, 8);
-}
-#endif
-
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct vivi_dev *dev = video_drvdata(file);
@@ -1105,9 +1096,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
.vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_s_ctrl = vidioc_s_ctrl,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static struct video_device vivi_template = {
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 635420d8d84a..019ee206cbee 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -815,7 +815,7 @@ out:
static const struct v4l2_file_operations w9966_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = w9966_v4l_read,
};
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 135525649086..fe8ef6419f83 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -35,7 +35,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
-#include <media/wm8775.h>
MODULE_DESCRIPTION("wm8775 driver");
MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
@@ -51,16 +50,10 @@ enum {
TOT_REGS
};
-#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
-#define ALC_EN 0x100 /* R17: ALC enable */
-
struct wm8775_state {
struct v4l2_subdev sd;
struct v4l2_ctrl_handler hdl;
struct v4l2_ctrl *mute;
- struct v4l2_ctrl *vol;
- struct v4l2_ctrl *bal;
- struct v4l2_ctrl *loud;
u8 input; /* Last selected input (0-0xf) */
};
@@ -92,30 +85,6 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
return -1;
}
-static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
-{
- struct wm8775_state *state = to_state(sd);
- u8 vol_l, vol_r;
- int muted = 0 != state->mute->val;
- u16 volume = (u16)state->vol->val;
- u16 balance = (u16)state->bal->val;
-
- /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
- vol_l = (min(65536 - balance, 32768) * volume) >> 23;
- vol_r = (min(balance, (u16)32768) * volume) >> 23;
-
- /* Mute */
- if (muted || quietly)
- wm8775_write(sd, R21, 0x0c0 | state->input);
-
- wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
- wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
-
- /* Un-mute */
- if (!muted)
- wm8775_write(sd, R21, state->input);
-}
-
static int wm8775_s_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{
@@ -133,26 +102,25 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
state->input = input;
if (!v4l2_ctrl_g_ctrl(state->mute))
return 0;
- if (!v4l2_ctrl_g_ctrl(state->vol))
- return 0;
- if (!v4l2_ctrl_g_ctrl(state->bal))
- return 0;
- wm8775_set_audio(sd, 1);
+ wm8775_write(sd, R21, 0x0c0);
+ wm8775_write(sd, R14, 0x1d4);
+ wm8775_write(sd, R15, 0x1d4);
+ wm8775_write(sd, R21, 0x100 + state->input);
return 0;
}
static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct v4l2_subdev *sd = to_sd(ctrl);
+ struct wm8775_state *state = to_state(sd);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BALANCE:
- wm8775_set_audio(sd, 0);
- return 0;
- case V4L2_CID_AUDIO_LOUDNESS:
- wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
+ wm8775_write(sd, R21, 0x0c0);
+ wm8775_write(sd, R14, 0x1d4);
+ wm8775_write(sd, R15, 0x1d4);
+ if (!ctrl->val)
+ wm8775_write(sd, R21, 0x100 + state->input);
return 0;
}
return -EINVAL;
@@ -176,7 +144,16 @@ static int wm8775_log_status(struct v4l2_subdev *sd)
static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
{
- wm8775_set_audio(sd, 0);
+ struct wm8775_state *state = to_state(sd);
+
+ /* If I remove this, then it can happen that I have no
+ sound the first time I tune from static to a valid channel.
+ It's difficult to reproduce and is almost certainly related
+ to the zero cross detect circuit. */
+ wm8775_write(sd, R21, 0x0c0);
+ wm8775_write(sd, R14, 0x1d4);
+ wm8775_write(sd, R15, 0x1d4);
+ wm8775_write(sd, R21, 0x100 + state->input);
return 0;
}
@@ -226,7 +203,6 @@ static int wm8775_probe(struct i2c_client *client,
{
struct wm8775_state *state;
struct v4l2_subdev *sd;
- int err;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -240,21 +216,15 @@ static int wm8775_probe(struct i2c_client *client,
return -ENOMEM;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
- sd->grp_id = WM8775_GID; /* subdev group id */
state->input = 2;
- v4l2_ctrl_handler_init(&state->hdl, 4);
+ v4l2_ctrl_handler_init(&state->hdl, 1);
state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
- state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
- state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
sd->ctrl_handler = &state->hdl;
- err = state->hdl.error;
- if (err) {
+ if (state->hdl.error) {
+ int err = state->hdl.error;
+
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return err;
@@ -266,25 +236,29 @@ static int wm8775_probe(struct i2c_client *client,
wm8775_write(sd, R23, 0x000);
/* Disable zero cross detect timeout */
wm8775_write(sd, R7, 0x000);
- /* HPF enable, I2S mode, 24-bit */
- wm8775_write(sd, R11, 0x022);
+ /* Left justified, 24-bit mode */
+ wm8775_write(sd, R11, 0x021);
/* Master mode, clock ratio 256fs */
wm8775_write(sd, R12, 0x102);
/* Powered up */
wm8775_write(sd, R13, 0x000);
- /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
- wm8775_write(sd, R16, 0x1bb);
- /* Set ALC mode and hold time */
- wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
+ /* ADC gain +2.5dB, enable zero cross */
+ wm8775_write(sd, R14, 0x1d4);
+ /* ADC gain +2.5dB, enable zero cross */
+ wm8775_write(sd, R15, 0x1d4);
+ /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
+ wm8775_write(sd, R16, 0x1bf);
+ /* Enable gain control, use zero cross detection,
+ ALC hold time 42.6 ms */
+ wm8775_write(sd, R17, 0x185);
/* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
wm8775_write(sd, R18, 0x0a2);
/* Enable noise gate, threshold -72dBfs */
wm8775_write(sd, R19, 0x005);
- /* Transient window 4ms, ALC min gain -5dB */
- wm8775_write(sd, R20, 0x0fb);
-
- wm8775_set_audio(sd, 1); /* set volume/mute/mux */
-
+ /* Transient window 4ms, lower PGA gain limit -1dB */
+ wm8775_write(sd, R20, 0x07a);
+ /* LRBOTH = 1, use input 2. */
+ wm8775_write(sd, R21, 0x102);
return 0;
}
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index 27f05551183f..4bb368e6fd47 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -33,15 +33,6 @@
#include <media/v4l2-device.h>
-#define ZORAN_VIDMODE_PAL 0
-#define ZORAN_VIDMODE_NTSC 1
-#define ZORAN_VIDMODE_SECAM 2
-
-struct zoran_requestbuffers {
- unsigned long count; /* Number of buffers for MJPEG grabbing */
- unsigned long size; /* Size PER BUFFER in bytes */
-};
-
struct zoran_sync {
unsigned long frame; /* number of buffer that has been free'd */
unsigned long length; /* number of code bytes in buffer (capture only) */
@@ -49,102 +40,6 @@ struct zoran_sync {
struct timeval timestamp; /* timestamp */
};
-struct zoran_status {
- int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
- int signal; /* Returned: 1 if valid video signal detected */
- int norm; /* Returned: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
- int color; /* Returned: 1 if color signal detected */
-};
-
-struct zoran_params {
-
- /* The following parameters can only be queried */
-
- int major_version; /* Major version number of driver */
- int minor_version; /* Minor version number of driver */
-
- /* Main control parameters */
-
- int input; /* Input channel: 0 = Composite, 1 = S-VHS */
- int norm; /* Norm: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
- int decimation; /* decimation of captured video,
- * enlargement of video played back.
- * Valid values are 1, 2, 4 or 0.
- * 0 is a special value where the user
- * has full control over video scaling */
-
- /* The following parameters only have to be set if decimation==0,
- * for other values of decimation they provide the data how the image is captured */
-
- int HorDcm; /* Horizontal decimation: 1, 2 or 4 */
- int VerDcm; /* Vertical decimation: 1 or 2 */
- int TmpDcm; /* Temporal decimation: 1 or 2,
- * if TmpDcm==2 in capture every second frame is dropped,
- * in playback every frame is played twice */
- int field_per_buff; /* Number of fields per buffer: 1 or 2 */
- int img_x; /* start of image in x direction */
- int img_y; /* start of image in y direction */
- int img_width; /* image width BEFORE decimation,
- * must be a multiple of HorDcm*16 */
- int img_height; /* image height BEFORE decimation,
- * must be a multiple of VerDcm*8 */
-
- /* --- End of parameters for decimation==0 only --- */
-
- /* JPEG control parameters */
-
- int quality; /* Measure for quality of compressed images.
- * Scales linearly with the size of the compressed images.
- * Must be beetween 0 and 100, 100 is a compression
- * ratio of 1:4 */
-
- int odd_even; /* Which field should come first ??? */
-
- int APPn; /* Number of APP segment to be written, must be 0..15 */
- int APP_len; /* Length of data in JPEG APPn segment */
- char APP_data[60]; /* Data in the JPEG APPn segment. */
-
- int COM_len; /* Length of data in JPEG COM segment */
- char COM_data[60]; /* Data in JPEG COM segment */
-
- unsigned long jpeg_markers; /* Which markers should go into the JPEG output.
- * Unless you exactly know what you do, leave them untouched.
- * Inluding less markers will make the resulting code
- * smaller, but there will be fewer applications
- * which can read it.
- * The presence of the APP and COM marker is
- * influenced by APP0_len and COM_len ONLY! */
-#define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
-#define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
-#define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
-#define JPEG_MARKER_COM (1<<6) /* Comment segment */
-#define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */
-
- int VFIFO_FB; /* Flag for enabling Video Fifo Feedback.
- * If this flag is turned on and JPEG decompressing
- * is going to the screen, the decompress process
- * is stopped every time the Video Fifo is full.
- * This enables a smooth decompress to the screen
- * but the video output signal will get scrambled */
-
- /* Misc */
-
- char reserved[312]; /* Makes 512 bytes for this structure */
-};
-
-/*
-Private IOCTL to set up for displaying MJPEG
-*/
-#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOC_PRIVATE+0, struct zoran_params)
-#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOC_PRIVATE+1, struct zoran_params)
-#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOC_PRIVATE+2, struct zoran_requestbuffers)
-#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOC_PRIVATE+3, int)
-#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOC_PRIVATE+4, int)
-#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOC_PRIVATE+5, struct zoran_sync)
-#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOC_PRIVATE+6, struct zoran_status)
-
-
-#ifdef __KERNEL__
#define MAJOR_VERSION 0 /* driver major version */
#define MINOR_VERSION 10 /* driver minor version */
@@ -507,6 +402,4 @@ static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-#endif /* __kernel__ */
-
#endif
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 7e6d62467eaa..9cdc3bb15b15 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -943,7 +943,7 @@ zoran_open_init_params (struct zoran *zr)
memset(zr->jpg_settings.jpg_comp.COM_data, 0,
sizeof(zr->jpg_settings.jpg_comp.COM_data));
zr->jpg_settings.jpg_comp.jpeg_markers =
- JPEG_MARKER_DHT | JPEG_MARKER_DQT;
+ V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT;
i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
if (i)
dprintk(1, KERN_ERR "%s: %s internal error\n",
@@ -1343,13 +1343,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
}
zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter, NULL, zr->card.i2c_decoder,
+ &zr->i2c_adapter, zr->card.i2c_decoder,
0, zr->card.addrs_decoder);
if (zr->card.i2c_encoder)
zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter,
- NULL, zr->card.i2c_encoder,
+ &zr->i2c_adapter, zr->card.i2c_encoder,
0, zr->card.addrs_encoder);
dprintk(2,
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index b02007e42150..e8a27844bf39 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -1523,7 +1523,7 @@ zoran_irq (int irq,
zr->JPEG_missed > 25 ||
zr->JPEG_error == 1 ||
((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
- (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
+ (zr->frame_num && (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
error_handler(zr, astat, stat);
}
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 67a52e844ae6..fe84f17c65c4 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1528,323 +1528,6 @@ zoran_set_input (struct zoran *zr,
* ioctl routine
*/
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- struct zoran_jpg_settings settings;
-
- switch (cmd) {
- case BUZIOC_G_PARAMS:
- {
- struct zoran_params *bparams = arg;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr));
-
- memset(bparams, 0, sizeof(struct zoran_params));
- bparams->major_version = MAJOR_VERSION;
- bparams->minor_version = MINOR_VERSION;
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->norm & V4L2_STD_NTSC)
- bparams->norm = ZORAN_VIDMODE_NTSC;
- else if (zr->norm & V4L2_STD_SECAM)
- bparams->norm = ZORAN_VIDMODE_SECAM;
- else
- bparams->norm = ZORAN_VIDMODE_PAL;
-
- bparams->input = zr->input;
-
- bparams->decimation = fh->jpg_settings.decimation;
- bparams->HorDcm = fh->jpg_settings.HorDcm;
- bparams->VerDcm = fh->jpg_settings.VerDcm;
- bparams->TmpDcm = fh->jpg_settings.TmpDcm;
- bparams->field_per_buff = fh->jpg_settings.field_per_buff;
- bparams->img_x = fh->jpg_settings.img_x;
- bparams->img_y = fh->jpg_settings.img_y;
- bparams->img_width = fh->jpg_settings.img_width;
- bparams->img_height = fh->jpg_settings.img_height;
- bparams->odd_even = fh->jpg_settings.odd_even;
-
- bparams->quality = fh->jpg_settings.jpg_comp.quality;
- bparams->APPn = fh->jpg_settings.jpg_comp.APPn;
- bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len;
- memcpy(bparams->APP_data,
- fh->jpg_settings.jpg_comp.APP_data,
- sizeof(bparams->APP_data));
- bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len;
- memcpy(bparams->COM_data,
- fh->jpg_settings.jpg_comp.COM_data,
- sizeof(bparams->COM_data));
- bparams->jpeg_markers =
- fh->jpg_settings.jpg_comp.jpeg_markers;
-
- mutex_unlock(&zr->resource_lock);
-
- bparams->VFIFO_FB = 0;
-
- return 0;
- }
-
- case BUZIOC_S_PARAMS:
- {
- struct zoran_params *bparams = arg;
- int res = 0;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
-
- settings.decimation = bparams->decimation;
- settings.HorDcm = bparams->HorDcm;
- settings.VerDcm = bparams->VerDcm;
- settings.TmpDcm = bparams->TmpDcm;
- settings.field_per_buff = bparams->field_per_buff;
- settings.img_x = bparams->img_x;
- settings.img_y = bparams->img_y;
- settings.img_width = bparams->img_width;
- settings.img_height = bparams->img_height;
- settings.odd_even = bparams->odd_even;
-
- settings.jpg_comp.quality = bparams->quality;
- settings.jpg_comp.APPn = bparams->APPn;
- settings.jpg_comp.APP_len = bparams->APP_len;
- memcpy(settings.jpg_comp.APP_data, bparams->APP_data,
- sizeof(bparams->APP_data));
- settings.jpg_comp.COM_len = bparams->COM_len;
- memcpy(settings.jpg_comp.COM_data, bparams->COM_data,
- sizeof(bparams->COM_data));
- settings.jpg_comp.jpeg_markers = bparams->jpeg_markers;
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto sparams_unlock_and_return;
- }
-
- /* Check the params first before overwriting our
- * nternal values */
- if (zoran_check_jpg_settings(zr, &settings, 0)) {
- res = -EINVAL;
- goto sparams_unlock_and_return;
- }
-
- fh->jpg_settings = settings;
-sparams_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_REQBUFS:
- {
- struct zoran_requestbuffers *breq = arg;
- int res = 0;
-
- dprintk(3,
- KERN_DEBUG
- "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n",
- ZR_DEVNAME(zr), breq->count, breq->size);
-
- /* Enforce reasonable lower and upper limits */
- if (breq->count < 4)
- breq->count = 4; /* Could be choosen smaller */
- if (breq->count > jpg_nbufs)
- breq->count = jpg_nbufs;
- breq->size = PAGE_ALIGN(breq->size);
- if (breq->size < 8192)
- breq->size = 8192; /* Arbitrary */
- /* breq->size is limited by 1 page for the stat_com
- * tables to a Maximum of 2 MB */
- if (breq->size > jpg_bufsize)
- breq->size = jpg_bufsize;
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_REQBUFS - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto jpgreqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the MJPEG buffers - could
- * also be *_PLAY, but it doesn't matter here */
- map_mode_jpg(fh, 0);
- fh->buffers.num_buffers = breq->count;
- fh->buffers.buffer_size = breq->size;
-
- if (jpg_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto jpgreqbuf_unlock_and_return;
- }
-
-jpgreqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_QBUF_CAPT:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_QBUF_PLAY:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_SYNC:
- {
- struct zoran_sync *bsync = arg;
- int res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
- dprintk(2, KERN_WARNING
- "%s: %s - not in jpg capture mode\n",
- ZR_DEVNAME(zr), __func__);
- res = -EINVAL;
- } else {
- res = jpg_sync(fh, bsync);
- }
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_G_STATUS:
- {
- struct zoran_status *bstat = arg;
- int status = 0, res = 0;
- v4l2_std_id norm;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto gstat_unlock_and_return;
- }
-
- decoder_call(zr, video, s_routing,
- zr->card.input[bstat->input].muxsel, 0, 0);
-
- /* sleep 1 second */
- ssleep(1);
-
- /* Get status of video decoder */
- decoder_call(zr, video, querystd, &norm);
- decoder_call(zr, video, g_input_status, &status);
-
- /* restore previous input and norm */
- decoder_call(zr, video, s_routing,
- zr->card.input[zr->input].muxsel, 0, 0);
-gstat_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- if (!res) {
- bstat->signal =
- (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
- if (norm & V4L2_STD_NTSC)
- bstat->norm = ZORAN_VIDMODE_NTSC;
- else if (norm & V4L2_STD_SECAM)
- bstat->norm = ZORAN_VIDMODE_SECAM;
- else
- bstat->norm = ZORAN_VIDMODE_PAL;
-
- bstat->color =
- (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
- }
-
- return res;
- }
-
- default:
- return -EINVAL;
- }
-}
-
-static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int i, res = 0;
-
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGMBUF - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the V4L buffers */
- map_mode_raw(fh);
-
- if (v4l_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
- vmbuf->frames = fh->buffers.num_buffers;
- for (i = 0; i < vmbuf->frames; i++)
- vmbuf->offsets[i] = i * fh->buffers.buffer_size;
-
-v4l1reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-#endif
-
static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
{
struct zoran_fh *fh = __fh;
@@ -2766,11 +2449,6 @@ static int zoran_enum_input(struct file *file, void *__fh,
if (inp->index >= zr->card.inputs)
return -EINVAL;
- else {
- int id = inp->index;
- memset(inp, 0, sizeof(*inp));
- inp->index = id;
- }
strncpy(inp->name, zr->card.input[inp->index].name,
sizeof(inp->name) - 1);
@@ -2820,7 +2498,6 @@ static int zoran_enum_output(struct file *file, void *__fh,
if (outp->index != 0)
return -EINVAL;
- memset(outp, 0, sizeof(*outp));
outp->index = 0;
outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
@@ -3364,10 +3041,6 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
.vidioc_queryctrl = zoran_queryctrl,
.vidioc_s_ctrl = zoran_s_ctrl,
.vidioc_g_ctrl = zoran_g_ctrl,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidioc_default = zoran_default,
- .vidiocgmbuf = zoran_vidiocgmbuf,
-#endif
};
/* please use zr->resource_lock consistently and kill this wrapper */
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3a1493b8b5e5..da9d2971102e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -218,12 +218,12 @@ config MFD_STMPE
Keypad: stmpe-keypad
Touchscreen: stmpe-ts
-config MFD_TC35892
- bool "Support Toshiba TC35892"
+config MFD_TC3589X
+ bool "Support Toshiba TC35892 and variants"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
help
- Support for the Toshiba TC35892 I/O Expander.
+ Support for the Toshiba TC35892 and variants I/O Expander.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the
@@ -606,6 +606,16 @@ config MFD_VX855
VIA VX855/VX875 south bridge. You will need to enable the vx855_spi
and/or vx855_gpio drivers for this to do anything useful.
+config MFD_WL1273_CORE
+ tristate
+ depends on I2C
+ select MFD_CORE
+ default n
+ help
+ This is the core driver for the TI WL1273 FM radio. This MFD
+ driver connects the radio-wl1273 V4L2 module and the wl1273
+ audio codec.
+
endif # MFD_SUPPORT
menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f54b3659abbb..848e7eac75aa 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_STMPE) += stmpe.o
-obj-$(CONFIG_MFD_TC35892) += tc35892.o
+obj-$(CONFIG_MFD_TC3589X) += tc3589x.o
obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o
obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o
@@ -81,3 +81,4 @@ obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
+obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index dbe1c93c1af3..d9640a623ff4 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -303,7 +303,7 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
continue;
do {
- int bit = __ffs(status);
+ int bit = __ffs(value);
int line = i * 8 + bit;
handle_nested_irq(ab8500->irq_base + line);
diff --git a/drivers/mfd/tc35892.c b/drivers/mfd/tc35892.c
deleted file mode 100644
index e619e2a55997..000000000000
--- a/drivers/mfd/tc35892.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License Terms: GNU General Public License, version 2
- * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tc35892.h>
-
-/**
- * tc35892_reg_read() - read a single TC35892 register
- * @tc35892: Device to read from
- * @reg: Register to read
- */
-int tc35892_reg_read(struct tc35892 *tc35892, u8 reg)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(tc35892->i2c, reg);
- if (ret < 0)
- dev_err(tc35892->dev, "failed to read reg %#x: %d\n",
- reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tc35892_reg_read);
-
-/**
- * tc35892_reg_read() - write a single TC35892 register
- * @tc35892: Device to write to
- * @reg: Register to read
- * @data: Value to write
- */
-int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(tc35892->i2c, reg, data);
- if (ret < 0)
- dev_err(tc35892->dev, "failed to write reg %#x: %d\n",
- reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tc35892_reg_write);
-
-/**
- * tc35892_block_read() - read multiple TC35892 registers
- * @tc35892: Device to read from
- * @reg: First register
- * @length: Number of registers
- * @values: Buffer to write to
- */
-int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length, u8 *values)
-{
- int ret;
-
- ret = i2c_smbus_read_i2c_block_data(tc35892->i2c, reg, length, values);
- if (ret < 0)
- dev_err(tc35892->dev, "failed to read regs %#x: %d\n",
- reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tc35892_block_read);
-
-/**
- * tc35892_block_write() - write multiple TC35892 registers
- * @tc35892: Device to write to
- * @reg: First register
- * @length: Number of registers
- * @values: Values to write
- */
-int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length,
- const u8 *values)
-{
- int ret;
-
- ret = i2c_smbus_write_i2c_block_data(tc35892->i2c, reg, length,
- values);
- if (ret < 0)
- dev_err(tc35892->dev, "failed to write regs %#x: %d\n",
- reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tc35892_block_write);
-
-/**
- * tc35892_set_bits() - set the value of a bitfield in a TC35892 register
- * @tc35892: Device to write to
- * @reg: Register to write
- * @mask: Mask of bits to set
- * @values: Value to set
- */
-int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val)
-{
- int ret;
-
- mutex_lock(&tc35892->lock);
-
- ret = tc35892_reg_read(tc35892, reg);
- if (ret < 0)
- goto out;
-
- ret &= ~mask;
- ret |= val;
-
- ret = tc35892_reg_write(tc35892, reg, ret);
-
-out:
- mutex_unlock(&tc35892->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(tc35892_set_bits);
-
-static struct resource gpio_resources[] = {
- {
- .start = TC35892_INT_GPIIRQ,
- .end = TC35892_INT_GPIIRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mfd_cell tc35892_devs[] = {
- {
- .name = "tc35892-gpio",
- .num_resources = ARRAY_SIZE(gpio_resources),
- .resources = &gpio_resources[0],
- },
-};
-
-static irqreturn_t tc35892_irq(int irq, void *data)
-{
- struct tc35892 *tc35892 = data;
- int status;
-
- status = tc35892_reg_read(tc35892, TC35892_IRQST);
- if (status < 0)
- return IRQ_NONE;
-
- while (status) {
- int bit = __ffs(status);
-
- handle_nested_irq(tc35892->irq_base + bit);
- status &= ~(1 << bit);
- }
-
- /*
- * A dummy read or write (to any register) appears to be necessary to
- * have the last interrupt clear (for example, GPIO IC write) take
- * effect.
- */
- tc35892_reg_read(tc35892, TC35892_IRQST);
-
- return IRQ_HANDLED;
-}
-
-static void tc35892_irq_dummy(unsigned int irq)
-{
- /* No mask/unmask at this level */
-}
-
-static struct irq_chip tc35892_irq_chip = {
- .name = "tc35892",
- .mask = tc35892_irq_dummy,
- .unmask = tc35892_irq_dummy,
-};
-
-static int tc35892_irq_init(struct tc35892 *tc35892)
-{
- int base = tc35892->irq_base;
- int irq;
-
- for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) {
- set_irq_chip_data(irq, tc35892);
- set_irq_chip_and_handler(irq, &tc35892_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
- }
-
- return 0;
-}
-
-static void tc35892_irq_remove(struct tc35892 *tc35892)
-{
- int base = tc35892->irq_base;
- int irq;
-
- for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) {
-#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
-#endif
- set_irq_chip_and_handler(irq, NULL, NULL);
- set_irq_chip_data(irq, NULL);
- }
-}
-
-static int tc35892_chip_init(struct tc35892 *tc35892)
-{
- int manf, ver, ret;
-
- manf = tc35892_reg_read(tc35892, TC35892_MANFCODE);
- if (manf < 0)
- return manf;
-
- ver = tc35892_reg_read(tc35892, TC35892_VERSION);
- if (ver < 0)
- return ver;
-
- if (manf != TC35892_MANFCODE_MAGIC) {
- dev_err(tc35892->dev, "unknown manufacturer: %#x\n", manf);
- return -EINVAL;
- }
-
- dev_info(tc35892->dev, "manufacturer: %#x, version: %#x\n", manf, ver);
-
- /* Put everything except the IRQ module into reset */
- ret = tc35892_reg_write(tc35892, TC35892_RSTCTRL,
- TC35892_RSTCTRL_TIMRST
- | TC35892_RSTCTRL_ROTRST
- | TC35892_RSTCTRL_KBDRST
- | TC35892_RSTCTRL_GPIRST);
- if (ret < 0)
- return ret;
-
- /* Clear the reset interrupt. */
- return tc35892_reg_write(tc35892, TC35892_RSTINTCLR, 0x1);
-}
-
-static int __devinit tc35892_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct tc35892_platform_data *pdata = i2c->dev.platform_data;
- struct tc35892 *tc35892;
- int ret;
-
- if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
- | I2C_FUNC_SMBUS_I2C_BLOCK))
- return -EIO;
-
- tc35892 = kzalloc(sizeof(struct tc35892), GFP_KERNEL);
- if (!tc35892)
- return -ENOMEM;
-
- mutex_init(&tc35892->lock);
-
- tc35892->dev = &i2c->dev;
- tc35892->i2c = i2c;
- tc35892->pdata = pdata;
- tc35892->irq_base = pdata->irq_base;
- tc35892->num_gpio = id->driver_data;
-
- i2c_set_clientdata(i2c, tc35892);
-
- ret = tc35892_chip_init(tc35892);
- if (ret)
- goto out_free;
-
- ret = tc35892_irq_init(tc35892);
- if (ret)
- goto out_free;
-
- ret = request_threaded_irq(tc35892->i2c->irq, NULL, tc35892_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "tc35892", tc35892);
- if (ret) {
- dev_err(tc35892->dev, "failed to request IRQ: %d\n", ret);
- goto out_removeirq;
- }
-
- ret = mfd_add_devices(tc35892->dev, -1, tc35892_devs,
- ARRAY_SIZE(tc35892_devs), NULL,
- tc35892->irq_base);
- if (ret) {
- dev_err(tc35892->dev, "failed to add children\n");
- goto out_freeirq;
- }
-
- return 0;
-
-out_freeirq:
- free_irq(tc35892->i2c->irq, tc35892);
-out_removeirq:
- tc35892_irq_remove(tc35892);
-out_free:
- kfree(tc35892);
- return ret;
-}
-
-static int __devexit tc35892_remove(struct i2c_client *client)
-{
- struct tc35892 *tc35892 = i2c_get_clientdata(client);
-
- mfd_remove_devices(tc35892->dev);
-
- free_irq(tc35892->i2c->irq, tc35892);
- tc35892_irq_remove(tc35892);
-
- kfree(tc35892);
-
- return 0;
-}
-
-static const struct i2c_device_id tc35892_id[] = {
- { "tc35892", 24 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tc35892_id);
-
-static struct i2c_driver tc35892_driver = {
- .driver.name = "tc35892",
- .driver.owner = THIS_MODULE,
- .probe = tc35892_probe,
- .remove = __devexit_p(tc35892_remove),
- .id_table = tc35892_id,
-};
-
-static int __init tc35892_init(void)
-{
- return i2c_add_driver(&tc35892_driver);
-}
-subsys_initcall(tc35892_init);
-
-static void __exit tc35892_exit(void)
-{
- i2c_del_driver(&tc35892_driver);
-}
-module_exit(tc35892_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("TC35892 MFD core driver");
-MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
new file mode 100644
index 000000000000..729dbeed2ce0
--- /dev/null
+++ b/drivers/mfd/tc3589x.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License, version 2
+ * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tc3589x.h>
+
+#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0
+#define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0)
+
+/**
+ * tc3589x_reg_read() - read a single TC3589x register
+ * @tc3589x: Device to read from
+ * @reg: Register to read
+ */
+int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg);
+ if (ret < 0)
+ dev_err(tc3589x->dev, "failed to read reg %#x: %d\n",
+ reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tc3589x_reg_read);
+
+/**
+ * tc3589x_reg_read() - write a single TC3589x register
+ * @tc3589x: Device to write to
+ * @reg: Register to read
+ * @data: Value to write
+ */
+int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data);
+ if (ret < 0)
+ dev_err(tc3589x->dev, "failed to write reg %#x: %d\n",
+ reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tc3589x_reg_write);
+
+/**
+ * tc3589x_block_read() - read multiple TC3589x registers
+ * @tc3589x: Device to read from
+ * @reg: First register
+ * @length: Number of registers
+ * @values: Buffer to write to
+ */
+int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values)
+{
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values);
+ if (ret < 0)
+ dev_err(tc3589x->dev, "failed to read regs %#x: %d\n",
+ reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tc3589x_block_read);
+
+/**
+ * tc3589x_block_write() - write multiple TC3589x registers
+ * @tc3589x: Device to write to
+ * @reg: First register
+ * @length: Number of registers
+ * @values: Values to write
+ */
+int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length,
+ const u8 *values)
+{
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length,
+ values);
+ if (ret < 0)
+ dev_err(tc3589x->dev, "failed to write regs %#x: %d\n",
+ reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tc3589x_block_write);
+
+/**
+ * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register
+ * @tc3589x: Device to write to
+ * @reg: Register to write
+ * @mask: Mask of bits to set
+ * @values: Value to set
+ */
+int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val)
+{
+ int ret;
+
+ mutex_lock(&tc3589x->lock);
+
+ ret = tc3589x_reg_read(tc3589x, reg);
+ if (ret < 0)
+ goto out;
+
+ ret &= ~mask;
+ ret |= val;
+
+ ret = tc3589x_reg_write(tc3589x, reg, ret);
+
+out:
+ mutex_unlock(&tc3589x->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tc3589x_set_bits);
+
+static struct resource gpio_resources[] = {
+ {
+ .start = TC3589x_INT_GPIIRQ,
+ .end = TC3589x_INT_GPIIRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource keypad_resources[] = {
+ {
+ .start = TC3589x_INT_KBDIRQ,
+ .end = TC3589x_INT_KBDIRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell tc3589x_dev_gpio[] = {
+ {
+ .name = "tc3589x-gpio",
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ .resources = &gpio_resources[0],
+ },
+};
+
+static struct mfd_cell tc3589x_dev_keypad[] = {
+ {
+ .name = "tc3589x-keypad",
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resources = &keypad_resources[0],
+ },
+};
+
+static irqreturn_t tc3589x_irq(int irq, void *data)
+{
+ struct tc3589x *tc3589x = data;
+ int status;
+
+again:
+ status = tc3589x_reg_read(tc3589x, TC3589x_IRQST);
+ if (status < 0)
+ return IRQ_NONE;
+
+ while (status) {
+ int bit = __ffs(status);
+
+ handle_nested_irq(tc3589x->irq_base + bit);
+ status &= ~(1 << bit);
+ }
+
+ /*
+ * A dummy read or write (to any register) appears to be necessary to
+ * have the last interrupt clear (for example, GPIO IC write) take
+ * effect. In such a case, recheck for any interrupt which is still
+ * pending.
+ */
+ status = tc3589x_reg_read(tc3589x, TC3589x_IRQST);
+ if (status)
+ goto again;
+
+ return IRQ_HANDLED;
+}
+
+static int tc3589x_irq_init(struct tc3589x *tc3589x)
+{
+ int base = tc3589x->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
+ set_irq_chip_data(irq, tc3589x);
+ set_irq_chip_and_handler(irq, &dummy_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
+ }
+
+ return 0;
+}
+
+static void tc3589x_irq_remove(struct tc3589x *tc3589x)
+{
+ int base = tc3589x->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip_and_handler(irq, NULL, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
+}
+
+static int tc3589x_chip_init(struct tc3589x *tc3589x)
+{
+ int manf, ver, ret;
+
+ manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE);
+ if (manf < 0)
+ return manf;
+
+ ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION);
+ if (ver < 0)
+ return ver;
+
+ if (manf != TC3589x_MANFCODE_MAGIC) {
+ dev_err(tc3589x->dev, "unknown manufacturer: %#x\n", manf);
+ return -EINVAL;
+ }
+
+ dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x\n", manf, ver);
+
+ /*
+ * Put everything except the IRQ module into reset;
+ * also spare the GPIO module for any pin initialization
+ * done during pre-kernel boot
+ */
+ ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL,
+ TC3589x_RSTCTRL_TIMRST
+ | TC3589x_RSTCTRL_ROTRST
+ | TC3589x_RSTCTRL_KBDRST);
+ if (ret < 0)
+ return ret;
+
+ /* Clear the reset interrupt. */
+ return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1);
+}
+
+static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
+{
+ int ret = 0;
+ unsigned int blocks = tc3589x->pdata->block;
+
+ if (blocks & TC3589x_BLOCK_GPIO) {
+ ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
+ ARRAY_SIZE(tc3589x_dev_gpio), NULL,
+ tc3589x->irq_base);
+ if (ret) {
+ dev_err(tc3589x->dev, "failed to add gpio child\n");
+ return ret;
+ }
+ dev_info(tc3589x->dev, "added gpio block\n");
+ }
+
+ if (blocks & TC3589x_BLOCK_KEYPAD) {
+ ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
+ ARRAY_SIZE(tc3589x_dev_keypad), NULL,
+ tc3589x->irq_base);
+ if (ret) {
+ dev_err(tc3589x->dev, "failed to keypad child\n");
+ return ret;
+ }
+ dev_info(tc3589x->dev, "added keypad block\n");
+ }
+
+ return ret;
+}
+
+static int __devinit tc3589x_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
+ struct tc3589x *tc3589x;
+ int ret;
+
+ if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL);
+ if (!tc3589x)
+ return -ENOMEM;
+
+ mutex_init(&tc3589x->lock);
+
+ tc3589x->dev = &i2c->dev;
+ tc3589x->i2c = i2c;
+ tc3589x->pdata = pdata;
+ tc3589x->irq_base = pdata->irq_base;
+ tc3589x->num_gpio = id->driver_data;
+
+ i2c_set_clientdata(i2c, tc3589x);
+
+ ret = tc3589x_chip_init(tc3589x);
+ if (ret)
+ goto out_free;
+
+ ret = tc3589x_irq_init(tc3589x);
+ if (ret)
+ goto out_free;
+
+ ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "tc3589x", tc3589x);
+ if (ret) {
+ dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
+ goto out_removeirq;
+ }
+
+ ret = tc3589x_device_init(tc3589x);
+ if (ret) {
+ dev_err(tc3589x->dev, "failed to add child devices\n");
+ goto out_freeirq;
+ }
+
+ return 0;
+
+out_freeirq:
+ free_irq(tc3589x->i2c->irq, tc3589x);
+out_removeirq:
+ tc3589x_irq_remove(tc3589x);
+out_free:
+ kfree(tc3589x);
+ return ret;
+}
+
+static int __devexit tc3589x_remove(struct i2c_client *client)
+{
+ struct tc3589x *tc3589x = i2c_get_clientdata(client);
+
+ mfd_remove_devices(tc3589x->dev);
+
+ free_irq(tc3589x->i2c->irq, tc3589x);
+ tc3589x_irq_remove(tc3589x);
+
+ kfree(tc3589x);
+
+ return 0;
+}
+
+static int tc3589x_suspend(struct device *dev)
+{
+ struct tc3589x *tc3589x = dev_get_drvdata(dev);
+ struct i2c_client *client = tc3589x->i2c;
+ int ret = 0;
+
+ /* put the system to sleep mode */
+ if (!device_may_wakeup(&client->dev))
+ ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
+ TC3589x_CLKMODE_MODCTL_SLEEP);
+
+ return ret;
+}
+
+static int tc3589x_resume(struct device *dev)
+{
+ struct tc3589x *tc3589x = dev_get_drvdata(dev);
+ struct i2c_client *client = tc3589x->i2c;
+ int ret = 0;
+
+ /* enable the system into operation */
+ if (!device_may_wakeup(&client->dev))
+ ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE,
+ TC3589x_CLKMODE_MODCTL_OPERATION);
+
+ return ret;
+}
+
+static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend,
+ tc3589x_resume);
+
+static const struct i2c_device_id tc3589x_id[] = {
+ { "tc3589x", 24 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tc3589x_id);
+
+static struct i2c_driver tc3589x_driver = {
+ .driver.name = "tc3589x",
+ .driver.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .driver.pm = &tc3589x_dev_pm_ops,
+#endif
+ .probe = tc3589x_probe,
+ .remove = __devexit_p(tc3589x_remove),
+ .id_table = tc3589x_id,
+};
+
+static int __init tc3589x_init(void)
+{
+ return i2c_add_driver(&tc3589x_driver);
+}
+subsys_initcall(tc3589x_init);
+
+static void __exit tc3589x_exit(void)
+{
+ i2c_del_driver(&tc3589x_driver);
+}
+module_exit(tc3589x_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TC3589x MFD core driver");
+MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 727f62c15a60..6ad8a7f8d390 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -40,6 +40,7 @@
#include <linux/spi/mc33880.h>
#include <media/timb_radio.h>
+#include <media/timb_video.h>
#include <linux/timb_dma.h>
@@ -246,7 +247,23 @@ static const __devinitconst struct resource timberdale_uartlite_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_radio_resources[] = {
+static __devinitdata struct i2c_board_info timberdale_adv7180_i2c_board_info = {
+ /* Requires jumper JP9 to be off */
+ I2C_BOARD_INFO("adv7180", 0x42 >> 1),
+ .irq = IRQ_TIMBERDALE_ADV7180
+};
+
+static __devinitdata struct timb_video_platform_data
+ timberdale_video_platform_data = {
+ .dma_channel = DMA_VIDEO_RX,
+ .i2c_adapter = 0,
+ .encoder = {
+ .info = &timberdale_adv7180_i2c_board_info
+ }
+};
+
+static const __devinitconst struct resource
+timberdale_radio_resources[] = {
{
.start = RDSOFFSET,
.end = RDSEND,
@@ -271,15 +288,25 @@ static __devinitdata struct timb_radio_platform_data
timberdale_radio_platform_data = {
.i2c_adapter = 0,
.tuner = {
- .module_name = "tef6862",
.info = &timberdale_tef6868_i2c_board_info
},
.dsp = {
- .module_name = "saa7706h",
.info = &timberdale_saa7706_i2c_board_info
}
};
+static const __devinitconst struct resource timberdale_video_resources[] = {
+ {
+ .start = LOGIWOFFSET,
+ .end = LOGIWEND,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ note that the "frame buffer" is located in DMA area
+ starting at 0x1200000
+ */
+};
+
static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
.nr_channels = 10,
.channels = {
@@ -380,6 +407,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -440,6 +474,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
.resources = timberdale_mlogicore_resources,
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -490,6 +531,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -533,6 +581,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
diff --git a/drivers/mfd/timberdale.h b/drivers/mfd/timberdale.h
index c11bf6ebfe00..4412acd826fa 100644
--- a/drivers/mfd/timberdale.h
+++ b/drivers/mfd/timberdale.h
@@ -23,7 +23,7 @@
#ifndef MFD_TIMBERDALE_H
#define MFD_TIMBERDALE_H
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
/* This driver only support versions >= 3.8 and < 4.0 */
#define TIMB_SUPPORTED_MAJOR 3
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
new file mode 100644
index 000000000000..d2ecc2435736
--- /dev/null
+++ b/drivers/mfd/wl1273-core.c
@@ -0,0 +1,148 @@
+/*
+ * MFD driver for wl1273 FM radio and audio codec submodules.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Author: Matti Aaltonen <matti.j.aaltonen@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/mfd/wl1273-core.h>
+#include <linux/slab.h>
+
+#define DRIVER_DESC "WL1273 FM Radio Core"
+
+static struct i2c_device_id wl1273_driver_id_table[] = {
+ { WL1273_FM_DRIVER_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
+
+static int wl1273_core_remove(struct i2c_client *client)
+{
+ struct wl1273_core *core = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ mfd_remove_devices(&client->dev);
+ i2c_set_clientdata(client, NULL);
+ kfree(core);
+
+ return 0;
+}
+
+static int __devinit wl1273_core_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
+ struct wl1273_core *core;
+ struct mfd_cell *cell;
+ int children = 0;
+ int r = 0;
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ if (!pdata) {
+ dev_err(&client->dev, "No platform data.\n");
+ return -EINVAL;
+ }
+
+ if (!(pdata->children & WL1273_RADIO_CHILD)) {
+ dev_err(&client->dev, "Cannot function without radio child.\n");
+ return -EINVAL;
+ }
+
+ core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (!core)
+ return -ENOMEM;
+
+ core->pdata = pdata;
+ core->client = client;
+ mutex_init(&core->lock);
+
+ i2c_set_clientdata(client, core);
+
+ dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
+
+ cell = &core->cells[children];
+ cell->name = "wl1273_fm_radio";
+ cell->platform_data = &core;
+ cell->data_size = sizeof(core);
+ children++;
+
+ if (pdata->children & WL1273_CODEC_CHILD) {
+ cell = &core->cells[children];
+
+ dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
+ cell->name = "wl1273-codec";
+ cell->platform_data = &core;
+ cell->data_size = sizeof(core);
+ children++;
+ }
+
+ dev_dbg(&client->dev, "%s: number of children: %d.\n",
+ __func__, children);
+
+ r = mfd_add_devices(&client->dev, -1, core->cells,
+ children, NULL, 0);
+ if (r)
+ goto err;
+
+ return 0;
+
+err:
+ i2c_set_clientdata(client, NULL);
+ pdata->free_resources();
+ kfree(core);
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ return r;
+}
+
+static struct i2c_driver wl1273_core_driver = {
+ .driver = {
+ .name = WL1273_FM_DRIVER_NAME,
+ },
+ .probe = wl1273_core_probe,
+ .id_table = wl1273_driver_id_table,
+ .remove = __devexit_p(wl1273_core_remove),
+};
+
+static int __init wl1273_core_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wl1273_core_driver);
+ if (r) {
+ pr_err(WL1273_FM_DRIVER_NAME
+ ": driver registration failed\n");
+ return r;
+ }
+
+ return r;
+}
+
+static void __exit wl1273_core_exit(void)
+{
+ i2c_del_driver(&wl1273_core_driver);
+}
+late_initcall(wl1273_core_init);
+module_exit(wl1273_core_exit);
+
+MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 7d2563fc15c6..76cadcf3b1fe 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1455,7 +1455,11 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
goto err;
}
- if (ret != 0x6204) {
+ switch (ret) {
+ case 0x6204:
+ case 0x6246:
+ break;
+ default:
dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
ret = -EINVAL;
goto err;
@@ -1620,7 +1624,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
case WM8325:
ret = mfd_add_devices(wm831x->dev, -1,
wm8320_devs, ARRAY_SIZE(wm8320_devs),
- NULL, 0);
+ NULL, wm831x->irq_base);
break;
default:
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index b3b2aaf89dbe..8d221ba5e38d 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -218,6 +218,18 @@ static const char *wm8994_main_supplies[] = {
"SPKVDD2",
};
+static const char *wm8958_main_supplies[] = {
+ "DBVDD1",
+ "DBVDD2",
+ "DBVDD3",
+ "DCVDD",
+ "AVDD1",
+ "AVDD2",
+ "CPVDD",
+ "SPKVDD1",
+ "SPKVDD2",
+};
+
#ifdef CONFIG_PM
static int wm8994_device_suspend(struct device *dev)
{
@@ -239,7 +251,7 @@ static int wm8994_device_suspend(struct device *dev)
if (ret < 0)
dev_err(dev, "Failed to save LDO registers: %d\n", ret);
- ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ ret = regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(dev, "Failed to disable supplies: %d\n", ret);
@@ -254,7 +266,7 @@ 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),
+ ret = regulator_bulk_enable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(dev, "Failed to enable supplies: %d\n", ret);
@@ -305,9 +317,10 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
/*
* Instantiate the generic non-control parts of the device.
*/
-static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
+static int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ const char *devname;
int ret, i;
mutex_init(&wm8994->io_lock);
@@ -323,25 +336,48 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
goto err;
}
+ switch (wm8994->type) {
+ case WM8994:
+ wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
+ break;
+ case WM8958:
+ wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
- ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->num_supplies,
GFP_KERNEL);
if (!wm8994->supplies) {
ret = -ENOMEM;
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),
+ switch (wm8994->type) {
+ case WM8994:
+ for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
+ wm8994->supplies[i].supply = wm8994_main_supplies[i];
+ break;
+ case WM8958:
+ for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)
+ wm8994->supplies[i].supply = wm8958_main_supplies[i];
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ ret = regulator_bulk_get(wm8994->dev, wm8994->num_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),
+ ret = regulator_bulk_enable(wm8994->num_supplies,
wm8994->supplies);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
@@ -353,7 +389,22 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
dev_err(wm8994->dev, "Failed to read ID register\n");
goto err_enable;
}
- if (ret != 0x8994) {
+ switch (ret) {
+ case 0x8994:
+ devname = "WM8994";
+ if (wm8994->type != WM8994)
+ dev_warn(wm8994->dev, "Device registered as type %d\n",
+ wm8994->type);
+ wm8994->type = WM8994;
+ break;
+ case 0x8958:
+ devname = "WM8958";
+ if (wm8994->type != WM8958)
+ dev_warn(wm8994->dev, "Device registered as type %d\n",
+ wm8994->type);
+ wm8994->type = WM8958;
+ break;
+ default:
dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
ret);
ret = -EINVAL;
@@ -370,14 +421,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
switch (ret) {
case 0:
case 1:
- dev_warn(wm8994->dev, "revision %c not fully supported\n",
- 'A' + ret);
+ if (wm8994->type == WM8994)
+ dev_warn(wm8994->dev,
+ "revision %c not fully supported\n",
+ 'A' + ret);
break;
default:
- dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
break;
}
+ dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret);
if (pdata) {
wm8994->irq_base = pdata->irq_base;
@@ -423,10 +476,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
err_irq:
wm8994_irq_exit(wm8994);
err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+ regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
err_supplies:
kfree(wm8994->supplies);
err:
@@ -439,9 +492,9 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
{
mfd_remove_devices(wm8994->dev);
wm8994_irq_exit(wm8994);
- regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+ regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
kfree(wm8994->supplies);
kfree(wm8994);
}
@@ -506,8 +559,9 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
wm8994->read_dev = wm8994_i2c_read_device;
wm8994->write_dev = wm8994_i2c_write_device;
wm8994->irq = i2c->irq;
+ wm8994->type = id->driver_data;
- return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
+ return wm8994_device_init(wm8994, i2c->irq);
}
static int wm8994_i2c_remove(struct i2c_client *i2c)
@@ -535,7 +589,8 @@ static int wm8994_i2c_resume(struct i2c_client *i2c)
#endif
static const struct i2c_device_id wm8994_i2c_id[] = {
- { "wm8994", 0 },
+ { "wm8994", WM8994 },
+ { "wm8958", WM8958 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 5ec02a536c5d..20ec06d744e7 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -503,6 +503,12 @@ config MMC_SH_MMCIF
This driver supports MMCIF in sh7724/sh7757/sh7372.
+config SH_MMCIF_DMA
+ bool "Use DMA for MMCIF"
+ depends on MMC_SH_MMCIF
+ help
+ Use SH dma-engine driver for data transfer
+
config MMC_JZ4740
tristate "JZ4740 SD/Multimedia Card Interface support"
depends on MACH_JZ4740
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 87b4fc6c98c2..563022825667 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -19,6 +19,7 @@
#include <linux/highmem.h>
#include <linux/log2.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
#include <linux/amba/bus.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>
@@ -45,6 +46,12 @@ static unsigned int fmax = 515633;
* is asserted (likewise for RX)
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
* is asserted (likewise for RX)
+ * @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
+ * and will not work at all.
+ * @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
+ * using DMA.
+ * @sdio: variant supports SDIO
+ * @st_clkdiv: true if using a ST-specific clock divider algorithm
*/
struct variant_data {
unsigned int clkreg;
@@ -52,6 +59,10 @@ struct variant_data {
unsigned int datalength_bits;
unsigned int fifosize;
unsigned int fifohalfsize;
+ bool broken_blockend;
+ bool broken_blockend_dma;
+ bool sdio;
+ bool st_clkdiv;
};
static struct variant_data variant_arm = {
@@ -65,6 +76,8 @@ static struct variant_data variant_u300 = {
.fifohalfsize = 8 * 4,
.clkreg_enable = 1 << 13, /* HWFCEN */
.datalength_bits = 16,
+ .broken_blockend_dma = true,
+ .sdio = true,
};
static struct variant_data variant_ux500 = {
@@ -73,7 +86,11 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable = 1 << 14, /* HWFCEN */
.datalength_bits = 24,
+ .broken_blockend = true,
+ .sdio = true,
+ .st_clkdiv = true,
};
+
/*
* This must be called with host->lock held
*/
@@ -86,7 +103,22 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
host->cclk = host->mclk;
+ } else if (variant->st_clkdiv) {
+ /*
+ * DB8500 TRM says f = mclk / (clkdiv + 2)
+ * => clkdiv = (mclk / f) - 2
+ * Round the divider up so we don't exceed the max
+ * frequency
+ */
+ clk = DIV_ROUND_UP(host->mclk, desired) - 2;
+ if (clk >= 256)
+ clk = 255;
+ host->cclk = host->mclk / (clk + 2);
} else {
+ /*
+ * PL180 TRM says f = mclk / (2 * (clkdiv + 1))
+ * => clkdiv = mclk / (2 * f) - 1
+ */
clk = host->mclk / (2 * desired) - 1;
if (clk >= 256)
clk = 255;
@@ -129,10 +161,26 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
spin_lock(&host->lock);
}
+static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
+{
+ void __iomem *base = host->base;
+
+ if (host->singleirq) {
+ unsigned int mask0 = readl(base + MMCIMASK0);
+
+ mask0 &= ~MCI_IRQ1MASK;
+ mask0 |= mask;
+
+ writel(mask0, base + MMCIMASK0);
+ }
+
+ writel(mask, base + MMCIMASK1);
+}
+
static void mmci_stop_data(struct mmci_host *host)
{
writel(0, host->base + MMCIDATACTRL);
- writel(0, host->base + MMCIMASK1);
+ mmci_set_mask1(host, 0);
host->data = NULL;
}
@@ -162,6 +210,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
host->data = data;
host->size = data->blksz * data->blocks;
host->data_xfered = 0;
+ host->blockend = false;
+ host->dataend = false;
mmci_init_sg(host, data);
@@ -196,9 +246,14 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
irqmask = MCI_TXFIFOHALFEMPTYMASK;
}
+ /* The ST Micro variants has a special bit to enable SDIO */
+ if (variant->sdio && host->mmc->card)
+ if (mmc_card_sdio(host->mmc->card))
+ datactrl |= MCI_ST_DPSM_SDIOEN;
+
writel(datactrl, base + MMCIDATACTRL);
writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
- writel(irqmask, base + MMCIMASK1);
+ mmci_set_mask1(host, irqmask);
}
static void
@@ -233,20 +288,9 @@ static void
mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
unsigned int status)
{
- if (status & MCI_DATABLOCKEND) {
- host->data_xfered += data->blksz;
-#ifdef CONFIG_ARCH_U300
- /*
- * On the U300 some signal or other is
- * badly routed so that a data write does
- * not properly terminate with a MCI_DATAEND
- * status flag. This quirk will make writes
- * work again.
- */
- if (data->flags & MMC_DATA_WRITE)
- status |= MCI_DATAEND;
-#endif
- }
+ struct variant_data *variant = host->variant;
+
+ /* First check for errors */
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
if (status & MCI_DATACRCFAIL)
@@ -255,7 +299,10 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
data->error = -ETIMEDOUT;
else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
data->error = -EIO;
- status |= MCI_DATAEND;
+
+ /* Force-complete the transaction */
+ host->blockend = true;
+ host->dataend = true;
/*
* We hit an error condition. Ensure that any data
@@ -273,9 +320,64 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
local_irq_restore(flags);
}
}
- if (status & MCI_DATAEND) {
+
+ /*
+ * On ARM variants in PIO mode, MCI_DATABLOCKEND
+ * is always sent first, and we increase the
+ * transfered number of bytes for that IRQ. Then
+ * MCI_DATAEND follows and we conclude the transaction.
+ *
+ * On the Ux500 single-IRQ variant MCI_DATABLOCKEND
+ * doesn't seem to immediately clear from the status,
+ * so we can't use it keep count when only one irq is
+ * used because the irq will hit for other reasons, and
+ * then the flag is still up. So we use the MCI_DATAEND
+ * IRQ at the end of the entire transfer because
+ * MCI_DATABLOCKEND is broken.
+ *
+ * In the U300, the IRQs can arrive out-of-order,
+ * e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
+ * so for this case we use the flags "blockend" and
+ * "dataend" to make sure both IRQs have arrived before
+ * concluding the transaction. (This does not apply
+ * to the Ux500 which doesn't fire MCI_DATABLOCKEND
+ * at all.) In DMA mode it suffers from the same problem
+ * as the Ux500.
+ */
+ if (status & MCI_DATABLOCKEND) {
+ /*
+ * Just being a little over-cautious, we do not
+ * use this progressive update if the hardware blockend
+ * flag is unreliable: since it can stay high between
+ * IRQs it will corrupt the transfer counter.
+ */
+ if (!variant->broken_blockend)
+ host->data_xfered += data->blksz;
+ host->blockend = true;
+ }
+
+ if (status & MCI_DATAEND)
+ host->dataend = true;
+
+ /*
+ * On variants with broken blockend we shall only wait for dataend,
+ * on others we must sync with the blockend signal since they can
+ * appear out-of-order.
+ */
+ if (host->dataend && (host->blockend || variant->broken_blockend)) {
mmci_stop_data(host);
+ /* Reset these flags */
+ host->blockend = false;
+ host->dataend = false;
+
+ /*
+ * Variants with broken blockend flags need to handle the
+ * end of the entire transfer here.
+ */
+ if (variant->broken_blockend && !data->error)
+ host->data_xfered += data->blksz * data->blocks;
+
if (!data->stop) {
mmci_request_end(host, data->mrq);
} else {
@@ -356,7 +458,32 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
variant->fifosize : variant->fifohalfsize;
count = min(remain, maxcnt);
- writesl(base + MMCIFIFO, ptr, count >> 2);
+ /*
+ * The ST Micro variant for SDIO transfer sizes
+ * less then 8 bytes should have clock H/W flow
+ * control disabled.
+ */
+ if (variant->sdio &&
+ mmc_card_sdio(host->mmc->card)) {
+ if (count < 8)
+ writel(readl(host->base + MMCICLOCK) &
+ ~variant->clkreg_enable,
+ host->base + MMCICLOCK);
+ else
+ writel(readl(host->base + MMCICLOCK) |
+ variant->clkreg_enable,
+ host->base + MMCICLOCK);
+ }
+
+ /*
+ * SDIO especially may want to send something that is
+ * not divisible by 4 (as opposed to card sectors
+ * etc), and the FIFO only accept full 32-bit writes.
+ * So compensate by adding +3 on the count, a single
+ * byte become a 32bit write, 7 bytes will be two
+ * 32bit writes etc.
+ */
+ writesl(base + MMCIFIFO, ptr, (count + 3) >> 2);
ptr += count;
remain -= count;
@@ -437,7 +564,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
* "any data available" mode.
*/
if (status & MCI_RXACTIVE && host->size < variant->fifosize)
- writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1);
+ mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
/*
* If we run out of data, disable the data IRQs; this
@@ -446,7 +573,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
* stops us racing with our data end IRQ.
*/
if (host->size == 0) {
- writel(0, base + MMCIMASK1);
+ mmci_set_mask1(host, 0);
writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
}
@@ -469,6 +596,14 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
struct mmc_data *data;
status = readl(host->base + MMCISTATUS);
+
+ if (host->singleirq) {
+ if (status & readl(host->base + MMCIMASK1))
+ mmci_pio_irq(irq, dev_id);
+
+ status &= ~MCI_IRQ1MASK;
+ }
+
status &= readl(host->base + MMCIMASK0);
writel(status, host->base + MMCICLEAR);
@@ -635,6 +770,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
struct variant_data *variant = id->data;
struct mmci_host *host;
struct mmc_host *mmc;
+ unsigned int mask;
int ret;
/* must have platform data */
@@ -806,20 +942,30 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
if (ret)
goto unmap;
- ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host);
- if (ret)
- goto irq0_free;
+ if (dev->irq[1] == NO_IRQ)
+ host->singleirq = true;
+ else {
+ ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
+ DRIVER_NAME " (pio)", host);
+ if (ret)
+ goto irq0_free;
+ }
- writel(MCI_IRQENABLE, host->base + MMCIMASK0);
+ mask = MCI_IRQENABLE;
+ /* Don't use the datablockend flag if it's broken */
+ if (variant->broken_blockend)
+ mask &= ~MCI_DATABLOCKEND;
- amba_set_drvdata(dev, mmc);
+ writel(mask, host->base + MMCIMASK0);
- mmc_add_host(mmc);
+ amba_set_drvdata(dev, mmc);
- dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
- mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
+ dev_info(&dev->dev, "%s: PL%03x rev%u at 0x%08llx irq %d,%d\n",
+ mmc_hostname(mmc), amba_part(dev), amba_rev(dev),
(unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
+ mmc_add_host(mmc);
+
return 0;
irq0_free:
@@ -864,7 +1010,8 @@ static int __devexit mmci_remove(struct amba_device *dev)
writel(0, host->base + MMCIDATACTRL);
free_irq(dev->irq[0], host);
- free_irq(dev->irq[1], host);
+ if (!host->singleirq)
+ free_irq(dev->irq[1], host);
if (host->gpio_wp != -ENOSYS)
gpio_free(host->gpio_wp);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 4ae887fc0189..df06f01aac89 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -139,6 +139,11 @@
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
+/* These interrupts are directed to IRQ1 when two IRQ lines are available */
+#define MCI_IRQ1MASK \
+ (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \
+ MCI_TXFIFOHALFEMPTYMASK)
+
#define NR_SG 16
struct clk;
@@ -154,6 +159,7 @@ struct mmci_host {
int gpio_cd;
int gpio_wp;
int gpio_cd_irq;
+ bool singleirq;
unsigned int data_xfered;
@@ -171,6 +177,9 @@ struct mmci_host {
struct timer_list timer;
unsigned int oldstat;
+ bool blockend;
+ bool dataend;
+
/* pio stuff */
struct sg_mapping_iter sg_miter;
unsigned int size;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 1290d14c5839..5decfd0bd61d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -44,6 +44,7 @@
#include <mach/mmc.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
+#include <mach/clk.h>
#include "msm_sdcc.h"
@@ -126,6 +127,40 @@ static void
msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
u32 c);
+static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
+{
+ u32 mci_clk = 0;
+ u32 mci_mask0 = 0;
+ int ret = 0;
+
+ /* Save the controller state */
+ mci_clk = readl(host->base + MMCICLOCK);
+ mci_mask0 = readl(host->base + MMCIMASK0);
+
+ /* Reset the controller */
+ ret = clk_reset(host->clk, CLK_RESET_ASSERT);
+ if (ret)
+ pr_err("%s: Clock assert failed at %u Hz with err %d\n",
+ mmc_hostname(host->mmc), host->clk_rate, ret);
+
+ ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
+ if (ret)
+ pr_err("%s: Clock deassert failed at %u Hz with err %d\n",
+ mmc_hostname(host->mmc), host->clk_rate, ret);
+
+ pr_info("%s: Controller has been re-initialiazed\n",
+ mmc_hostname(host->mmc));
+
+ /* Restore the contoller state */
+ writel(host->pwr, host->base + MMCIPOWER);
+ writel(mci_clk, host->base + MMCICLOCK);
+ writel(mci_mask0, host->base + MMCIMASK0);
+ ret = clk_set_rate(host->clk, host->clk_rate);
+ if (ret)
+ pr_err("%s: Failed to set clk rate %u Hz (%d)\n",
+ mmc_hostname(host->mmc), host->clk_rate, ret);
+}
+
static void
msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
{
@@ -155,7 +190,7 @@ static void
msmsdcc_stop_data(struct msmsdcc_host *host)
{
host->curr.data = NULL;
- host->curr.got_dataend = host->curr.got_datablkend = 0;
+ host->curr.got_dataend = 0;
}
uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
@@ -189,42 +224,42 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
}
static void
-msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
- unsigned int result,
- struct msm_dmov_errdata *err)
+msmsdcc_dma_complete_tlet(unsigned long data)
{
- struct msmsdcc_dma_data *dma_data =
- container_of(cmd, struct msmsdcc_dma_data, hdr);
- struct msmsdcc_host *host = dma_data->host;
+ struct msmsdcc_host *host = (struct msmsdcc_host *)data;
unsigned long flags;
struct mmc_request *mrq;
+ struct msm_dmov_errdata err;
spin_lock_irqsave(&host->lock, flags);
host->dma.active = 0;
+ err = host->dma.err;
mrq = host->curr.mrq;
BUG_ON(!mrq);
WARN_ON(!mrq->data);
- if (!(result & DMOV_RSLT_VALID)) {
+ if (!(host->dma.result & DMOV_RSLT_VALID)) {
pr_err("msmsdcc: Invalid DataMover result\n");
goto out;
}
- if (result & DMOV_RSLT_DONE) {
+ if (host->dma.result & DMOV_RSLT_DONE) {
host->curr.data_xfered = host->curr.xfer_size;
} else {
/* Error or flush */
- if (result & DMOV_RSLT_ERROR)
+ if (host->dma.result & DMOV_RSLT_ERROR)
pr_err("%s: DMA error (0x%.8x)\n",
- mmc_hostname(host->mmc), result);
- if (result & DMOV_RSLT_FLUSH)
+ mmc_hostname(host->mmc), host->dma.result);
+ if (host->dma.result & DMOV_RSLT_FLUSH)
pr_err("%s: DMA channel flushed (0x%.8x)\n",
- mmc_hostname(host->mmc), result);
- if (err)
- pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n",
- err->flush[0], err->flush[1], err->flush[2],
- err->flush[3], err->flush[4], err->flush[5]);
+ mmc_hostname(host->mmc), host->dma.result);
+
+ pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n",
+ err.flush[0], err.flush[1], err.flush[2],
+ err.flush[3], err.flush[4], err.flush[5]);
+
+ msmsdcc_reset_and_restore(host);
if (!mrq->data->error)
mrq->data->error = -EIO;
}
@@ -242,8 +277,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
host->dma.sg = NULL;
host->dma.busy = 0;
- if ((host->curr.got_dataend && host->curr.got_datablkend)
- || mrq->data->error) {
+ if (host->curr.got_dataend || mrq->data->error) {
/*
* If we've already gotten our DATAEND / DATABLKEND
@@ -273,6 +307,22 @@ out:
return;
}
+static void
+msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
+ unsigned int result,
+ struct msm_dmov_errdata *err)
+{
+ struct msmsdcc_dma_data *dma_data =
+ container_of(cmd, struct msmsdcc_dma_data, hdr);
+ struct msmsdcc_host *host = dma_data->host;
+
+ dma_data->result = result;
+ if (err)
+ memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata));
+
+ tasklet_schedule(&host->dma_tlet);
+}
+
static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data)
{
if (host->dma.channel == -1)
@@ -424,6 +474,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
(cmd->opcode == 53))
*c |= MCI_CSPM_DATCMD;
+ if (host->prog_scan && (cmd->opcode == 12)) {
+ *c |= MCI_CPSM_PROGENA;
+ host->prog_enable = true;
+ }
+
if (cmd == cmd->mrq->stop)
*c |= MCI_CSPM_MCIABORT;
@@ -450,7 +505,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
host->curr.xfer_remain = host->curr.xfer_size;
host->curr.data_xfered = 0;
host->curr.got_dataend = 0;
- host->curr.got_datablkend = 0;
memset(&host->pio, 0, sizeof(host->pio));
@@ -494,6 +548,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
host->cmd_c = c;
}
msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
+ if (data->flags & MMC_DATA_WRITE)
+ host->prog_scan = true;
} else {
msmsdcc_writel(host, timeout, MMCIDATATIMER);
@@ -555,6 +611,9 @@ msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain)
uint32_t *ptr = (uint32_t *) buffer;
int count = 0;
+ if (remain % 4)
+ remain = ((remain >> 2) + 1) << 2;
+
while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) {
*ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE));
ptr++;
@@ -575,13 +634,14 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer,
char *ptr = buffer;
do {
- unsigned int count, maxcnt;
+ unsigned int count, maxcnt, sz;
maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE :
MCI_FIFOHALFSIZE;
count = min(remain, maxcnt);
- writesl(base + MMCIFIFO, ptr, count >> 2);
+ sz = count % 4 ? (count >> 2) + 1 : (count >> 2);
+ writesl(base + MMCIFIFO, ptr, sz);
ptr += count;
remain -= count;
@@ -702,10 +762,26 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
msm_dmov_stop_cmd(host->dma.channel,
&host->dma.hdr, 0);
else if (host->curr.data) { /* Non DMA */
+ msmsdcc_reset_and_restore(host);
msmsdcc_stop_data(host);
msmsdcc_request_end(host, cmd->mrq);
- } else /* host->data == NULL */
- msmsdcc_request_end(host, cmd->mrq);
+ } else { /* host->data == NULL */
+ if (!cmd->error && host->prog_enable) {
+ if (status & MCI_PROGDONE) {
+ host->prog_scan = false;
+ host->prog_enable = false;
+ msmsdcc_request_end(host, cmd->mrq);
+ } else {
+ host->curr.cmd = cmd;
+ }
+ } else {
+ if (host->prog_enable) {
+ host->prog_scan = false;
+ host->prog_enable = false;
+ }
+ msmsdcc_request_end(host, cmd->mrq);
+ }
+ }
} else if (cmd->data)
if (!(cmd->data->flags & MMC_DATA_READ))
msmsdcc_start_data(host, cmd->data,
@@ -719,7 +795,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
struct mmc_data *data = host->curr.data;
if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
- MCI_CMDTIMEOUT) && host->curr.cmd) {
+ MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
msmsdcc_do_cmdirq(host, status);
}
@@ -735,6 +811,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
msm_dmov_stop_cmd(host->dma.channel,
&host->dma.hdr, 0);
else {
+ msmsdcc_reset_and_restore(host);
if (host->curr.data)
msmsdcc_stop_data(host);
if (!data->stop)
@@ -748,14 +825,10 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
if (!host->curr.got_dataend && (status & MCI_DATAEND))
host->curr.got_dataend = 1;
- if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND))
- host->curr.got_datablkend = 1;
-
/*
* If DMA is still in progress, we complete via the completion handler
*/
- if (host->curr.got_dataend && host->curr.got_datablkend &&
- !host->dma.busy) {
+ if (host->curr.got_dataend && !host->dma.busy) {
/*
* There appears to be an issue in the controller where
* if you request a small block transfer (< fifo size),
@@ -792,8 +865,7 @@ msmsdcc_irq(int irq, void *dev_id)
do {
status = msmsdcc_readl(host, MMCISTATUS);
- status &= (msmsdcc_readl(host, MMCIMASK0) |
- MCI_DATABLOCKENDMASK);
+ status &= msmsdcc_readl(host, MMCIMASK0);
msmsdcc_writel(host, status, MMCICLEAR);
if (status & MCI_SDIOINTR)
@@ -1118,6 +1190,9 @@ msmsdcc_probe(struct platform_device *pdev)
host->dmares = dmares;
spin_lock_init(&host->lock);
+ tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet,
+ (unsigned long)host);
+
/*
* Setup DMA
*/
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ff2b0f74f6f4..939557af266d 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -138,7 +138,7 @@
#define MCI_IRQENABLE \
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
- MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK)
+ MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
/*
* The size of the FIFO in bytes.
@@ -172,6 +172,8 @@ struct msmsdcc_dma_data {
struct msmsdcc_host *host;
int busy; /* Set if DM is busy */
int active;
+ unsigned int result;
+ struct msm_dmov_errdata err;
};
struct msmsdcc_pio_data {
@@ -188,7 +190,6 @@ struct msmsdcc_curr_req {
unsigned int xfer_remain; /* Bytes remaining to send */
unsigned int data_xfered; /* Bytes acked by BLKEND irq */
int got_dataend;
- int got_datablkend;
int user_pages;
};
@@ -235,6 +236,7 @@ struct msmsdcc_host {
int cmdpoll;
struct msmsdcc_stats stats;
+ struct tasklet_struct dma_tlet;
/* Command parameters */
unsigned int cmd_timeout;
unsigned int cmd_pio_irqmask;
@@ -242,6 +244,8 @@ struct msmsdcc_host {
struct mmc_command *cmd_cmd;
u32 cmd_c;
+ bool prog_scan;
+ bool prog_enable;
};
#endif
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index ddd09840520b..d09a2b38eeeb 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -16,16 +16,19 @@
*
*/
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/mmc/host.h>
+#include <linux/dmaengine.h>
#include <linux/mmc/card.h>
#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/pagemap.h>
+#include <linux/platform_device.h>
#define DRIVER_NAME "sh_mmcif"
#define DRIVER_VERSION "2010-04-28"
@@ -62,25 +65,6 @@
/* CE_BLOCK_SET */
#define BLOCK_SIZE_MASK 0x0000ffff
-/* CE_CLK_CTRL */
-#define CLK_ENABLE (1 << 24) /* 1: output mmc clock */
-#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
-#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
-#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */
-#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \
- (1 << 9) | (1 << 8)) /* resp busy timeout */
-#define SRWDTO_29 ((1 << 7) | (1 << 6) | \
- (1 << 5) | (1 << 4)) /* read/write timeout */
-#define SCCSTO_29 ((1 << 3) | (1 << 2) | \
- (1 << 1) | (1 << 0)) /* ccs timeout */
-
-/* CE_BUF_ACC */
-#define BUF_ACC_DMAWEN (1 << 25)
-#define BUF_ACC_DMAREN (1 << 24)
-#define BUF_ACC_BUSW_32 (0 << 17)
-#define BUF_ACC_BUSW_16 (1 << 17)
-#define BUF_ACC_ATYP (1 << 16)
-
/* CE_INT */
#define INT_CCSDE (1 << 29)
#define INT_CMD12DRE (1 << 26)
@@ -165,10 +149,6 @@
STS2_AC12BSYTO | STS2_RSPBSYTO | \
STS2_AC12RSPTO | STS2_RSPTO)
-/* CE_VERSION */
-#define SOFT_RST_ON (1 << 31)
-#define SOFT_RST_OFF (0 << 31)
-
#define CLKDEV_EMMC_DATA 52000000 /* 52MHz */
#define CLKDEV_MMC_DATA 20000000 /* 20MHz */
#define CLKDEV_INIT 400000 /* 400 KHz */
@@ -176,18 +156,21 @@
struct sh_mmcif_host {
struct mmc_host *mmc;
struct mmc_data *data;
- struct mmc_command *cmd;
struct platform_device *pd;
struct clk *hclk;
unsigned int clk;
int bus_width;
- u16 wait_int;
- u16 sd_error;
+ bool sd_error;
long timeout;
void __iomem *addr;
- wait_queue_head_t intr_wait;
-};
+ struct completion intr_wait;
+ /* DMA support */
+ struct dma_chan *chan_rx;
+ struct dma_chan *chan_tx;
+ struct completion dma_complete;
+ unsigned int dma_sglen;
+};
static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
unsigned int reg, u32 val)
@@ -201,6 +184,208 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
writel(~val & readl(host->addr + reg), host->addr + reg);
}
+#ifdef CONFIG_SH_MMCIF_DMA
+static void mmcif_dma_complete(void *arg)
+{
+ struct sh_mmcif_host *host = arg;
+ dev_dbg(&host->pd->dev, "Command completed\n");
+
+ if (WARN(!host->data, "%s: NULL data in DMA completion!\n",
+ dev_name(&host->pd->dev)))
+ return;
+
+ if (host->data->flags & MMC_DATA_READ)
+ dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen,
+ DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen,
+ DMA_TO_DEVICE);
+
+ complete(&host->dma_complete);
+}
+
+static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+{
+ struct scatterlist *sg = host->data->sg;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_rx;
+ dma_cookie_t cookie = -EINVAL;
+ int ret;
+
+ ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_FROM_DEVICE);
+ if (ret > 0) {
+ host->dma_sglen = ret;
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+ DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ }
+
+ if (desc) {
+ desc->callback = mmcif_dma_complete;
+ desc->callback_param = host;
+ cookie = desc->tx_submit(desc);
+ if (cookie < 0) {
+ desc = NULL;
+ ret = cookie;
+ } else {
+ sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN);
+ chan->device->device_issue_pending(chan);
+ }
+ }
+ dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
+ __func__, host->data->sg_len, ret, cookie);
+
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_rx = NULL;
+ host->dma_sglen = 0;
+ dma_release_channel(chan);
+ /* Free the Tx channel too */
+ chan = host->chan_tx;
+ if (chan) {
+ host->chan_tx = NULL;
+ dma_release_channel(chan);
+ }
+ dev_warn(&host->pd->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ }
+
+ dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
+ desc, cookie, host->data->sg_len);
+}
+
+static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+{
+ struct scatterlist *sg = host->data->sg;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_tx;
+ dma_cookie_t cookie = -EINVAL;
+ int ret;
+
+ ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_TO_DEVICE);
+ if (ret > 0) {
+ host->dma_sglen = ret;
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+ DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ }
+
+ if (desc) {
+ desc->callback = mmcif_dma_complete;
+ desc->callback_param = host;
+ cookie = desc->tx_submit(desc);
+ if (cookie < 0) {
+ desc = NULL;
+ ret = cookie;
+ } else {
+ sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAWEN);
+ chan->device->device_issue_pending(chan);
+ }
+ }
+ dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
+ __func__, host->data->sg_len, ret, cookie);
+
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_tx = NULL;
+ host->dma_sglen = 0;
+ dma_release_channel(chan);
+ /* Free the Rx channel too */
+ chan = host->chan_rx;
+ if (chan) {
+ host->chan_rx = NULL;
+ dma_release_channel(chan);
+ }
+ dev_warn(&host->pd->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ }
+
+ dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d\n", __func__,
+ desc, cookie);
+}
+
+static bool sh_mmcif_filter(struct dma_chan *chan, void *arg)
+{
+ dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
+ chan->private = arg;
+ return true;
+}
+
+static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+ struct sh_mmcif_plat_data *pdata)
+{
+ host->dma_sglen = 0;
+
+ /* We can only either use DMA for both Tx and Rx or not use it at all */
+ if (pdata->dma) {
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ host->chan_tx = dma_request_channel(mask, sh_mmcif_filter,
+ &pdata->dma->chan_priv_tx);
+ dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
+ host->chan_tx);
+
+ if (!host->chan_tx)
+ return;
+
+ host->chan_rx = dma_request_channel(mask, sh_mmcif_filter,
+ &pdata->dma->chan_priv_rx);
+ dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
+ host->chan_rx);
+
+ if (!host->chan_rx) {
+ dma_release_channel(host->chan_tx);
+ host->chan_tx = NULL;
+ return;
+ }
+
+ init_completion(&host->dma_complete);
+ }
+}
+
+static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
+{
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ /* Descriptors are freed automatically */
+ if (host->chan_tx) {
+ struct dma_chan *chan = host->chan_tx;
+ host->chan_tx = NULL;
+ dma_release_channel(chan);
+ }
+ if (host->chan_rx) {
+ struct dma_chan *chan = host->chan_rx;
+ host->chan_rx = NULL;
+ dma_release_channel(chan);
+ }
+
+ host->dma_sglen = 0;
+}
+#else
+static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+{
+}
+
+static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+{
+}
+
+static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+ struct sh_mmcif_plat_data *pdata)
+{
+ /* host->chan_tx, host->chan_tx and host->dma_sglen are all zero */
+}
+
+static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
+{
+}
+#endif
static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
{
@@ -239,13 +424,12 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
u32 state1, state2;
int ret, timeout = 10000000;
- host->sd_error = 0;
- host->wait_int = 0;
+ host->sd_error = false;
state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1);
state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2);
- pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1);
- pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2);
+ dev_dbg(&host->pd->dev, "ERR HOST_STS1 = %08x\n", state1);
+ dev_dbg(&host->pd->dev, "ERR HOST_STS2 = %08x\n", state2);
if (state1 & STS1_CMDSEQ) {
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
@@ -253,8 +437,8 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
while (1) {
timeout--;
if (timeout < 0) {
- pr_err(DRIVER_NAME": Forceed end of " \
- "command sequence timeout err\n");
+ dev_err(&host->pd->dev,
+ "Forceed end of command sequence timeout err\n");
return -EIO;
}
if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
@@ -263,18 +447,18 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
mdelay(1);
}
sh_mmcif_sync_reset(host);
- pr_debug(DRIVER_NAME": Forced end of command sequence\n");
+ dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
return -EIO;
}
if (state2 & STS2_CRC_ERR) {
- pr_debug(DRIVER_NAME": Happened CRC error\n");
+ dev_dbg(&host->pd->dev, ": Happened CRC error\n");
ret = -EIO;
} else if (state2 & STS2_TIMEOUT_ERR) {
- pr_debug(DRIVER_NAME": Happened Timeout error\n");
+ dev_dbg(&host->pd->dev, ": Happened Timeout error\n");
ret = -ETIMEDOUT;
} else {
- pr_debug(DRIVER_NAME": Happened End/Index error\n");
+ dev_dbg(&host->pd->dev, ": Happened End/Index error\n");
ret = -EIO;
}
return ret;
@@ -287,17 +471,13 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
long time;
u32 blocksize, i, *p = sg_virt(data->sg);
- host->wait_int = 0;
-
/* buf read enable */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK &
sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++)
@@ -305,13 +485,11 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
/* buffer read end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
return 0;
}
@@ -326,19 +504,15 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
MMCIF_CE_BLOCK_SET);
for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg);
- host->wait_int = 0;
for (sec = 0; sec < data->sg->length / blocksize; sec++) {
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
/* buf read enable */
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
- if (host->wait_int != 1 &&
- (time == 0 || host->sd_error != 0))
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++)
*p++ = sh_mmcif_readl(host->addr,
MMCIF_CE_DATA);
@@ -356,17 +530,14 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
long time;
u32 blocksize, i, *p = sg_virt(data->sg);
- host->wait_int = 0;
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
/* buf write enable */
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK &
sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++)
@@ -375,13 +546,11 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
/* buffer write end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
return 0;
}
@@ -397,19 +566,15 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg);
- host->wait_int = 0;
for (sec = 0; sec < data->sg->length / blocksize; sec++) {
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
/* buf write enable*/
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
- if (host->wait_int != 1 &&
- (time == 0 || host->sd_error != 0))
+ if (time <= 0 || host->sd_error)
return sh_mmcif_error_manage(host);
- host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++)
sh_mmcif_writel(host->addr,
MMCIF_CE_DATA, *p++);
@@ -457,7 +622,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
tmp |= CMD_SET_RTYP_17B;
break;
default:
- pr_err(DRIVER_NAME": Not support type response.\n");
+ dev_err(&host->pd->dev, "Unsupported response type.\n");
break;
}
switch (opc) {
@@ -485,7 +650,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
tmp |= CMD_SET_DATW_8;
break;
default:
- pr_err(DRIVER_NAME": Not support bus width.\n");
+ dev_err(&host->pd->dev, "Unsupported bus width.\n");
break;
}
}
@@ -513,10 +678,10 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
return opc = ((opc << 24) | tmp);
}
-static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
+static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
struct mmc_request *mrq, u32 opc)
{
- u32 ret;
+ int ret;
switch (opc) {
case MMC_READ_MULTIPLE_BLOCK:
@@ -533,7 +698,7 @@ static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
ret = sh_mmcif_single_read(host, mrq);
break;
default:
- pr_err(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc);
+ dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
ret = -EINVAL;
break;
}
@@ -547,8 +712,6 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
int ret = 0, mask = 0;
u32 opc = cmd->opcode;
- host->cmd = cmd;
-
switch (opc) {
/* respons busy check */
case MMC_SWITCH:
@@ -579,13 +742,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
/* set arg */
sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
- host->wait_int = 0;
/* set cmd */
sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 || host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && time == 0) {
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0) {
cmd->error = sh_mmcif_error_manage(host);
return;
}
@@ -597,26 +759,34 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
cmd->error = -ETIMEDOUT;
break;
default:
- pr_debug("%s: Cmd(d'%d) err\n",
- DRIVER_NAME, cmd->opcode);
+ dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n",
+ cmd->opcode);
cmd->error = sh_mmcif_error_manage(host);
break;
}
- host->sd_error = 0;
- host->wait_int = 0;
+ host->sd_error = false;
return;
}
if (!(cmd->flags & MMC_RSP_PRESENT)) {
- cmd->error = ret;
- host->wait_int = 0;
+ cmd->error = 0;
return;
}
- if (host->wait_int == 1) {
- sh_mmcif_get_response(host, cmd);
- host->wait_int = 0;
- }
+ sh_mmcif_get_response(host, cmd);
if (host->data) {
- ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
+ if (!host->dma_sglen) {
+ ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
+ } else {
+ long time =
+ wait_for_completion_interruptible_timeout(&host->dma_complete,
+ host->timeout);
+ if (!time)
+ ret = -ETIMEDOUT;
+ else if (time < 0)
+ ret = time;
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
+ BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ host->dma_sglen = 0;
+ }
if (ret < 0)
mrq->data->bytes_xfered = 0;
else
@@ -636,20 +806,18 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
else {
- pr_err(DRIVER_NAME": not support stop cmd\n");
+ dev_err(&host->pd->dev, "unsupported stop cmd\n");
cmd->error = sh_mmcif_error_manage(host);
return;
}
- time = wait_event_interruptible_timeout(host->intr_wait,
- host->wait_int == 1 ||
- host->sd_error == 1, host->timeout);
- if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) {
+ time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+ host->timeout);
+ if (time <= 0 || host->sd_error) {
cmd->error = sh_mmcif_error_manage(host);
return;
}
sh_mmcif_get_cmd12response(host, cmd);
- host->wait_int = 0;
cmd->error = 0;
}
@@ -676,6 +844,15 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
break;
}
host->data = mrq->data;
+ if (mrq->data) {
+ if (mrq->data->flags & MMC_DATA_READ) {
+ if (host->chan_rx)
+ sh_mmcif_start_dma_rx(host);
+ } else {
+ if (host->chan_tx)
+ sh_mmcif_start_dma_tx(host);
+ }
+ }
sh_mmcif_start_cmd(host, mrq, mrq->cmd);
host->data = NULL;
@@ -735,7 +912,7 @@ static void sh_mmcif_detect(struct mmc_host *mmc)
static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
{
struct sh_mmcif_host *host = dev_id;
- u32 state = 0;
+ u32 state;
int err = 0;
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
@@ -774,17 +951,19 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1;
} else {
- pr_debug("%s: Not support int\n", DRIVER_NAME);
+ dev_dbg(&host->pd->dev, "Not support int\n");
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1;
}
if (err) {
- host->sd_error = 1;
- pr_debug("%s: int err state = %08x\n", DRIVER_NAME, state);
+ host->sd_error = true;
+ dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
}
- host->wait_int = 1;
- wake_up(&host->intr_wait);
+ if (state & ~(INT_CMD12RBE | INT_CMD12CRE))
+ complete(&host->intr_wait);
+ else
+ dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state);
return IRQ_HANDLED;
}
@@ -793,8 +972,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
{
int ret = 0, irq[2];
struct mmc_host *mmc;
- struct sh_mmcif_host *host = NULL;
- struct sh_mmcif_plat_data *pd = NULL;
+ struct sh_mmcif_host *host;
+ struct sh_mmcif_plat_data *pd;
struct resource *res;
void __iomem *reg;
char clk_name[8];
@@ -802,7 +981,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
irq[0] = platform_get_irq(pdev, 0);
irq[1] = platform_get_irq(pdev, 1);
if (irq[0] < 0 || irq[1] < 0) {
- pr_err(DRIVER_NAME": Get irq error\n");
+ dev_err(&pdev->dev, "Get irq error\n");
return -ENXIO;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -815,7 +994,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "ioremap error.\n");
return -ENOMEM;
}
- pd = (struct sh_mmcif_plat_data *)(pdev->dev.platform_data);
+ pd = pdev->dev.platform_data;
if (!pd) {
dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
ret = -ENXIO;
@@ -842,7 +1021,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
host->clk = clk_get_rate(host->hclk);
host->pd = pdev;
- init_waitqueue_head(&host->intr_wait);
+ init_completion(&host->intr_wait);
mmc->ops = &sh_mmcif_ops;
mmc->f_max = host->clk;
@@ -858,33 +1037,37 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_MMC_HIGHSPEED;
if (pd->caps)
mmc->caps |= pd->caps;
- mmc->max_segs = 128;
+ mmc->max_segs = 32;
mmc->max_blk_size = 512;
- mmc->max_blk_count = 65535;
- mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs;
+ mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
mmc->max_seg_size = mmc->max_req_size;
sh_mmcif_sync_reset(host);
platform_set_drvdata(pdev, host);
+
+ /* See if we also get DMA */
+ sh_mmcif_request_dma(host, pd);
+
mmc_add_host(mmc);
ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
if (ret) {
- pr_err(DRIVER_NAME": request_irq error (sh_mmc:error)\n");
+ dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
goto clean_up2;
}
ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
if (ret) {
free_irq(irq[0], host);
- pr_err(DRIVER_NAME": request_irq error (sh_mmc:int)\n");
+ dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
goto clean_up2;
}
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
sh_mmcif_detect(host->mmc);
- pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION);
- pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME,
+ dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
+ dev_dbg(&pdev->dev, "chip ver H'%04x\n",
sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
return ret;
@@ -903,20 +1086,22 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
int irq[2];
- sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
-
- irq[0] = platform_get_irq(pdev, 0);
- irq[1] = platform_get_irq(pdev, 1);
+ mmc_remove_host(host->mmc);
+ sh_mmcif_release_dma(host);
if (host->addr)
iounmap(host->addr);
- platform_set_drvdata(pdev, NULL);
- mmc_remove_host(host->mmc);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
+ irq[0] = platform_get_irq(pdev, 0);
+ irq[1] = platform_get_irq(pdev, 1);
free_irq(irq[0], host);
free_irq(irq[1], host);
+ platform_set_drvdata(pdev, NULL);
+
clk_disable(host->hclk);
mmc_free_host(host->mmc);
@@ -947,5 +1132,5 @@ module_exit(sh_mmcif_exit);
MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS(DRIVER_NAME);
+MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("Yusuke Goda <yusuke.goda.sx@renesas.com>");
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 1e2cbf5d9aa1..77414702cb00 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -53,9 +53,10 @@ config MTD_PARTITIONS
devices. Partitioning on NFTL 'devices' is a different - that's the
'normal' form of partitioning used on a block device.
+if MTD_PARTITIONS
+
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
- depends on MTD_PARTITIONS
---help---
RedBoot is a ROM monitor and bootloader which deals with multiple
'images' in flash devices by putting a table one of the erase
@@ -72,9 +73,10 @@ config MTD_REDBOOT_PARTS
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
example.
+if MTD_REDBOOT_PARTS
+
config MTD_REDBOOT_DIRECTORY_BLOCK
int "Location of RedBoot partition table"
- depends on MTD_REDBOOT_PARTS
default "-1"
---help---
This option is the Linux counterpart to the
@@ -91,18 +93,18 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
config MTD_REDBOOT_PARTS_UNALLOCATED
bool "Include unallocated flash regions"
- depends on MTD_REDBOOT_PARTS
help
If you need to register each unallocated flash region as a MTD
'partition', enable this option.
config MTD_REDBOOT_PARTS_READONLY
bool "Force read-only for RedBoot system images"
- depends on MTD_REDBOOT_PARTS
help
If you need to force read-only for 'RedBoot', 'RedBoot Config' and
'FIS directory' images, enable this option.
+endif # MTD_REDBOOT_PARTS
+
config MTD_CMDLINE_PARTS
bool "Command line partition table parsing"
depends on MTD_PARTITIONS = "y" && MTD = "y"
@@ -142,7 +144,7 @@ config MTD_CMDLINE_PARTS
config MTD_AFS_PARTS
tristate "ARM Firmware Suite partition parsing"
- depends on ARM && MTD_PARTITIONS
+ depends on ARM
---help---
The ARM Firmware Suite allows the user to divide flash devices into
multiple 'images'. Each such image has a header containing its name
@@ -158,8 +160,8 @@ config MTD_AFS_PARTS
example.
config MTD_OF_PARTS
- tristate "Flash partition map based on OF description"
- depends on (MICROBLAZE || PPC_OF) && MTD_PARTITIONS
+ def_bool y
+ depends on OF
help
This provides a partition parsing function which derives
the partition map from the children of the flash node,
@@ -167,10 +169,11 @@ config MTD_OF_PARTS
config MTD_AR7_PARTS
tristate "TI AR7 partitioning support"
- depends on MTD_PARTITIONS
---help---
TI AR7 partitioning support
+endif # MTD_PARTITIONS
+
comment "User Modules And Translation Layers"
config MTD_CHAR
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 760abc533395..d4e7f25b1ebb 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -6,13 +6,13 @@
obj-$(CONFIG_MTD) += mtd.o
mtd-y := mtdcore.o mtdsuper.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
+mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
-obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index ad9268b44416..44cbfc093ecc 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -162,7 +162,7 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
#endif
/* Atmel chips don't use the same PRI format as Intel chips */
-static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
+static void fixup_convert_atmel_pri(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -202,7 +202,7 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
cfi->cfiq->BufWriteTimeoutMax = 0;
}
-static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param)
+static void fixup_at49bv640dx_lock(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -214,7 +214,7 @@ static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param)
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
-static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
+static void fixup_intel_strataflash(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -227,7 +227,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
#endif
#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
-static void fixup_no_write_suspend(struct mtd_info *mtd, void* param)
+static void fixup_no_write_suspend(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -240,7 +240,7 @@ static void fixup_no_write_suspend(struct mtd_info *mtd, void* param)
}
#endif
-static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
+static void fixup_st_m28w320ct(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -249,7 +249,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
}
-static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
+static void fixup_st_m28w320cb(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -259,7 +259,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
(cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
};
-static void fixup_use_point(struct mtd_info *mtd, void *param)
+static void fixup_use_point(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
if (!mtd->point && map_is_linear(map)) {
@@ -268,7 +268,7 @@ static void fixup_use_point(struct mtd_info *mtd, void *param)
}
}
-static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
+static void fixup_use_write_buffers(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -282,7 +282,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
/*
* Some chips power-up with all sectors locked by default.
*/
-static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param)
+static void fixup_unlock_powerup_lock(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -295,31 +295,31 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param)
}
static struct cfi_fixup cfi_fixup_table[] = {
- { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
- { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL },
- { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL },
+ { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri },
+ { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock },
+ { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock },
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash },
#endif
#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend },
#endif
#if !FORCE_WORD_WRITE
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL },
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
#endif
- { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL },
- { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL },
- { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, },
- { 0, 0, NULL, NULL }
+ { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct },
+ { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb },
+ { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock },
+ { 0, 0, NULL }
};
static struct cfi_fixup jedec_fixup_table[] = {
- { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, },
- { 0, 0, NULL, NULL }
+ { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock },
+ { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock },
+ { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock },
+ { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock },
+ { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock },
+ { 0, 0, NULL }
};
static struct cfi_fixup fixup_table[] = {
/* The CFI vendor ids and the JEDEC vendor IDs appear
@@ -327,8 +327,8 @@ static struct cfi_fixup fixup_table[] = {
* well. This table is to pick all cases where
* we know that is the case.
*/
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL },
- { 0, 0, NULL, NULL }
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point },
+ { 0, 0, NULL }
};
static void cfi_fixup_major_minor(struct cfi_private *cfi,
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 3b8e32d87977..9d68ab919f31 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -134,7 +134,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
#ifdef AMD_BOOTLOC_BUG
/* Wheee. Bring me the head of someone at AMD. */
-static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
+static void fixup_amd_bootblock(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -186,7 +186,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
}
#endif
-static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
+static void fixup_use_write_buffers(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -197,7 +197,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
}
/* Atmel chips don't use the same PRI format as AMD chips */
-static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
+static void fixup_convert_atmel_pri(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -228,14 +228,14 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
cfi->cfiq->BufWriteTimeoutMax = 0;
}
-static void fixup_use_secsi(struct mtd_info *mtd, void *param)
+static void fixup_use_secsi(struct mtd_info *mtd)
{
/* Setup for chips with a secsi area */
mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
}
-static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
+static void fixup_use_erase_chip(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -250,7 +250,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
* Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors
* locked by default.
*/
-static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
+static void fixup_use_atmel_lock(struct mtd_info *mtd)
{
mtd->lock = cfi_atmel_lock;
mtd->unlock = cfi_atmel_unlock;
@@ -271,7 +271,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd)
cfi->cfiq->NumEraseRegions = 1;
}
-static void fixup_sst39vf(struct mtd_info *mtd, void *param)
+static void fixup_sst39vf(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -282,7 +282,7 @@ static void fixup_sst39vf(struct mtd_info *mtd, void *param)
cfi->addr_unlock2 = 0x2AAA;
}
-static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param)
+static void fixup_sst39vf_rev_b(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -295,12 +295,12 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param)
cfi->sector_erase_cmd = CMD(0x50);
}
-static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param)
+static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
- fixup_sst39vf_rev_b(mtd, param);
+ fixup_sst39vf_rev_b(mtd);
/*
* CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where
@@ -310,7 +310,7 @@ static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param)
pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name);
}
-static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
+static void fixup_s29gl064n_sectors(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -321,7 +321,7 @@ static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
}
}
-static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
+static void fixup_s29gl032n_sectors(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
@@ -334,47 +334,47 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
/* Used to fix CFI-Tables of chips without Extended Query Tables */
static struct cfi_fixup cfi_nopri_fixup_table[] = {
- { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, /* SST39VF1602 */
- { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, /* SST39VF1601 */
- { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, /* SST39VF3202 */
- { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, /* SST39VF3201 */
- { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3202B */
- { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3201B */
- { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6402B */
- { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6401B */
- { 0, 0, NULL, NULL }
+ { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */
+ { CFI_MFR_SST, 0x234b, fixup_sst39vf }, /* SST39VF1601 */
+ { CFI_MFR_SST, 0x235a, fixup_sst39vf }, /* SST39VF3202 */
+ { CFI_MFR_SST, 0x235b, fixup_sst39vf }, /* SST39VF3201 */
+ { CFI_MFR_SST, 0x235c, fixup_sst39vf_rev_b }, /* SST39VF3202B */
+ { CFI_MFR_SST, 0x235d, fixup_sst39vf_rev_b }, /* SST39VF3201B */
+ { CFI_MFR_SST, 0x236c, fixup_sst39vf_rev_b }, /* SST39VF6402B */
+ { CFI_MFR_SST, 0x236d, fixup_sst39vf_rev_b }, /* SST39VF6401B */
+ { 0, 0, NULL }
};
static struct cfi_fixup cfi_fixup_table[] = {
- { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+ { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri },
#ifdef AMD_BOOTLOC_BUG
- { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
- { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL },
+ { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock },
+ { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock },
#endif
- { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, },
- { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, },
- { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
- { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
- { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
- { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */
- { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */
- { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */
- { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */
+ { CFI_MFR_AMD, 0x0050, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x0053, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x0055, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x0056, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x005C, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x005F, fixup_use_secsi },
+ { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors },
+ { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors },
+ { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors },
+ { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors },
+ { CFI_MFR_SST, 0x536a, fixup_sst38vf640x_sectorsize }, /* SST38VF6402 */
+ { CFI_MFR_SST, 0x536b, fixup_sst38vf640x_sectorsize }, /* SST38VF6401 */
+ { CFI_MFR_SST, 0x536c, fixup_sst38vf640x_sectorsize }, /* SST38VF6404 */
+ { CFI_MFR_SST, 0x536d, fixup_sst38vf640x_sectorsize }, /* SST38VF6403 */
#if !FORCE_WORD_WRITE
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
#endif
- { 0, 0, NULL, NULL }
+ { 0, 0, NULL }
};
static struct cfi_fixup jedec_fixup_table[] = {
- { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock, NULL, },
- { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
- { 0, 0, NULL, NULL }
+ { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock },
+ { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock },
+ { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock },
+ { 0, 0, NULL }
};
static struct cfi_fixup fixup_table[] = {
@@ -383,9 +383,9 @@ static struct cfi_fixup fixup_table[] = {
* well. This table is to pick all cases where
* we know that is the case.
*/
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL },
- { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL },
- { 0, 0, NULL, NULL }
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip },
+ { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock },
+ { 0, 0, NULL }
};
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 360525c637d2..6ae3d111e1e7 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -156,7 +156,7 @@ void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup *fixups)
for (f=fixups; f->fixup; f++) {
if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
((f->id == CFI_ID_ANY) || (f->id == cfi->id))) {
- f->fixup(mtd, f->param);
+ f->fixup(mtd);
}
}
}
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index d18064977192..5e3cc80128aa 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -98,7 +98,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return ret;
}
-static void fixup_use_fwh_lock(struct mtd_info *mtd, void *param)
+static void fixup_use_fwh_lock(struct mtd_info *mtd)
{
printk(KERN_NOTICE "using fwh lock/unlock method\n");
/* Setup for the chips with the fwh lock method */
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 2cf0cc6a4189..f29a6f9df6e7 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
if (dev->blkdev) {
invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
0, -1);
- close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
kfree(dev);
@@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
/* FIXME: ensure that mtd->size % erase_size == 0 */
static struct block2mtd_dev *add_device(char *devname, int erase_size)
{
+ const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
struct block_device *bdev;
struct block2mtd_dev *dev;
char *name;
@@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
return NULL;
/* Get a handle on the device */
- bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL);
+ bdev = blkdev_get_by_path(devname, mode, dev);
#ifndef MODULE
if (IS_ERR(bdev)) {
@@ -254,9 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
to resolve the device name by other means. */
dev_t devt = name_to_dev_t(devname);
- if (devt) {
- bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
- }
+ if (devt)
+ bdev = blkdev_get_by_dev(devt, mode, dev);
}
#endif
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index bf5a002209bd..eabe5fb071c6 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -51,6 +51,10 @@
#define OPCODE_WRDI 0x04 /* Write disable */
#define OPCODE_AAI_WP 0xad /* Auto address increment word program */
+/* Used for Macronix flashes only. */
+#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */
+#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */
+
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
#define SR_WEL 2 /* Write enable latch */
@@ -62,7 +66,7 @@
/* Define max times to check status register before we give up. */
#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
-#define MAX_CMD_SIZE 4
+#define MAX_CMD_SIZE 5
#ifdef CONFIG_M25PXX_USE_FAST_READ
#define OPCODE_READ OPCODE_FAST_READ
@@ -152,6 +156,16 @@ static inline int write_disable(struct m25p *flash)
}
/*
+ * Enable/disable 4-byte addressing mode.
+ */
+static inline int set_4byte(struct m25p *flash, int enable)
+{
+ u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B;
+
+ return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
+}
+
+/*
* Service routine to read status register until ready, or timeout occurs.
* Returns non-zero if error.
*/
@@ -207,6 +221,7 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
cmd[1] = addr >> (flash->addr_width * 8 - 8);
cmd[2] = addr >> (flash->addr_width * 8 - 16);
cmd[3] = addr >> (flash->addr_width * 8 - 24);
+ cmd[4] = addr >> (flash->addr_width * 8 - 32);
}
static int m25p_cmdsz(struct m25p *flash)
@@ -607,7 +622,6 @@ struct flash_info {
.sector_size = (_sector_size), \
.n_sectors = (_n_sectors), \
.page_size = 256, \
- .addr_width = 3, \
.flags = (_flags), \
})
@@ -653,6 +667,8 @@ static const struct spi_device_id m25p_ids[] = {
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
@@ -764,6 +780,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
return &m25p_ids[tmp];
}
}
+ dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
return ERR_PTR(-ENODEV);
}
@@ -883,7 +900,17 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->mtd.dev.parent = &spi->dev;
flash->page_size = info->page_size;
- flash->addr_width = info->addr_width;
+
+ if (info->addr_width)
+ flash->addr_width = info->addr_width;
+ else {
+ /* enable 4-byte addressing if the device exceeds 16MiB */
+ if (flash->mtd.size > 0x1000000) {
+ flash->addr_width = 4;
+ set_4byte(flash, 1);
+ } else
+ flash->addr_width = 3;
+ }
dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
(long long)flash->mtd.size >> 10);
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 684247a8a5ed..c163e619abc9 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -335,7 +335,7 @@ out:
return ret;
}
-static struct flash_info *__init sst25l_match_device(struct spi_device *spi)
+static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi)
{
struct flash_info *flash_info = NULL;
struct spi_message m;
@@ -375,7 +375,7 @@ static struct flash_info *__init sst25l_match_device(struct spi_device *spi)
return flash_info;
}
-static int __init sst25l_probe(struct spi_device *spi)
+static int __devinit sst25l_probe(struct spi_device *spi)
{
struct flash_info *flash_info;
struct sst25l_flash *flash;
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 19fe92db0c46..77d64ce19e9f 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -149,11 +149,8 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
if (request_resource(&iomem_resource, &window->rsrc)) {
window->rsrc.parent = NULL;
printk(KERN_ERR MOD_NAME
- " %s(): Unable to register resource"
- " 0x%.16llx-0x%.16llx - kernel bug?\n",
- __func__,
- (unsigned long long)window->rsrc.start,
- (unsigned long long)window->rsrc.end);
+ " %s(): Unable to register resource %pR - kernel bug?\n",
+ __func__, &window->rsrc);
}
diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
index d175c120ee84..1f3049590d9e 100644
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -196,10 +196,15 @@ static int bcm963xx_probe(struct platform_device *pdev)
bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
if (!bcm963xx_mtd_info) {
dev_err(&pdev->dev, "failed to probe using CFI\n");
+ bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map);
+ if (bcm963xx_mtd_info)
+ goto probe_ok;
+ dev_err(&pdev->dev, "failed to probe using JEDEC\n");
err = -EIO;
goto err_probe;
}
+probe_ok:
bcm963xx_mtd_info->owner = THIS_MODULE;
/* This is mutually exclusive */
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index ddb462bea9b5..5fdb7b26cea3 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -178,11 +178,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
if (request_resource(&iomem_resource, &window->rsrc)) {
window->rsrc.parent = NULL;
printk(KERN_ERR MOD_NAME
- " %s(): Unable to register resource"
- " 0x%.016llx-0x%.016llx - kernel bug?\n",
- __func__,
- (unsigned long long)window->rsrc.start,
- (unsigned long long)window->rsrc.end);
+ " %s(): Unable to register resource %pR - kernel bug?\n",
+ __func__, &window->rsrc);
}
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index d12c93dc1aad..4feb7507ab7c 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -242,12 +242,9 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (request_resource(&iomem_resource, &window->rsrc)) {
window->rsrc.parent = NULL;
- printk(KERN_DEBUG MOD_NAME
- ": %s(): Unable to register resource"
- " 0x%.08llx-0x%.08llx - kernel bug?\n",
- __func__,
- (unsigned long long)window->rsrc.start,
- (unsigned long long)window->rsrc.end);
+ printk(KERN_DEBUG MOD_NAME ": "
+ "%s(): Unable to register resource %pR - kernel bug?\n",
+ __func__, &window->rsrc);
}
/* Map the firmware hub into my address space. */
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index f102bf243a74..1337a4191a0c 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -175,12 +175,9 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (request_resource(&iomem_resource, &window->rsrc)) {
window->rsrc.parent = NULL;
- printk(KERN_DEBUG MOD_NAME
- ": %s(): Unable to register resource"
- " 0x%.16llx-0x%.16llx - kernel bug?\n",
- __func__,
- (unsigned long long)window->rsrc.start,
- (unsigned long long)window->rsrc.end);
+ printk(KERN_DEBUG MOD_NAME ": "
+ "%s(): Unable to register resource %pR - kernel bug?\n",
+ __func__, &window->rsrc);
}
/* Map the firmware hub into my address space. */
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 9861814aa027..8506578e6a35 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -274,9 +274,7 @@ static int __devinit of_flash_probe(struct platform_device *dev,
continue;
}
- dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
- (unsigned long long)res.start,
- (unsigned long long)res.end);
+ dev_dbg(&dev->dev, "of_flash device: %pR\n", &res);
err = -EBUSY;
res_size = resource_size(&res);
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index dd90880048cf..d8ae634d347e 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int __init pxa2xx_flash_probe(struct platform_device *pdev)
+static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
{
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index b5391ebb736e..027e628a4f1d 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -166,9 +166,8 @@ static int __init init_scx200_docflash(void)
outl(pmr, scx200_cb_base + SCx200_PMR);
}
- printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n",
- (unsigned long long)docmem.start,
- (unsigned long long)docmem.end, width);
+ printk(KERN_INFO NAME ": DOCCS mapped at %pR, width %d\n",
+ &docmem, width);
scx200_docflash_map.size = size;
if (width == 8)
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 60146984f4be..c08e140d40ed 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -139,7 +139,7 @@ static int __init init_tqm_mtd(void)
goto error_mem;
}
- map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
+ map_banks[idx]->name = kmalloc(16, GFP_KERNEL);
if (!map_banks[idx]->name) {
ret = -ENOMEM;
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 4759d827e8c7..f7f760f303cc 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -522,10 +522,6 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- /* Only master mtd device must be used to control partitions */
- if (!mtd_is_master(mtd))
- return -EINVAL;
-
if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
return -EFAULT;
@@ -535,6 +531,10 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd,
switch (a.op) {
case BLKPG_ADD_PARTITION:
+ /* Only master mtd device must be used to add partitions */
+ if (mtd_is_partition(mtd))
+ return -EINVAL;
+
return mtd_add_partition(mtd, p.devname, p.start, p.length);
case BLKPG_DEL_PARTITION:
@@ -601,6 +601,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
}
case MEMGETINFO:
+ memset(&info, 0, sizeof(info));
info.type = mtd->type;
info.flags = mtd->flags;
info.size = mtd->size;
@@ -609,7 +610,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
info.oobsize = mtd->oobsize;
/* The below fields are obsolete */
info.ecctype = -1;
- info.eccsize = 0;
if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
return -EFAULT;
break;
@@ -1201,7 +1201,7 @@ err_unregister_chdev:
static void __exit cleanup_mtdchar(void)
{
unregister_mtd_user(&mtdchar_notifier);
- mntput(mtd_inode_mnt);
+ mntput_long(mtd_inode_mnt);
unregister_filesystem(&mtd_inodefs_type);
__unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 79e3689f1e16..1047ff0a4f55 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -720,19 +720,19 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
}
EXPORT_SYMBOL_GPL(parse_mtd_partitions);
-int mtd_is_master(struct mtd_info *mtd)
+int mtd_is_partition(struct mtd_info *mtd)
{
struct mtd_part *part;
- int nopart = 0;
+ int ispart = 0;
mutex_lock(&mtd_partitions_mutex);
list_for_each_entry(part, &mtd_partitions, list)
if (&part->mtd == mtd) {
- nopart = 1;
+ ispart = 1;
break;
}
mutex_unlock(&mtd_partitions_mutex);
- return nopart;
+ return ispart;
}
-EXPORT_SYMBOL_GPL(mtd_is_master);
+EXPORT_SYMBOL_GPL(mtd_is_partition);
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index c141b07b25d1..7a13d42cbabd 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -388,6 +388,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
"page_addr: 0x%x, column: 0x%x.\n",
page_addr, column);
+ elbc_fcm_ctrl->column = column;
+ elbc_fcm_ctrl->oob = 0;
elbc_fcm_ctrl->use_mdr = 1;
fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 02edfba25b0c..205b10b9f9b9 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -31,6 +31,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/mtd/fsmc.h>
+#include <linux/amba/bus.h>
#include <mtd/mtd-abi.h>
static struct nand_ecclayout fsmc_ecc1_layout = {
@@ -119,21 +120,36 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
}
};
-/*
- * Default partition tables to be used if the partition information not
- * provided through platform data
- */
-#define PARTITION(n, off, sz) {.name = n, .offset = off, .size = sz}
+#ifdef CONFIG_MTD_PARTITIONS
/*
+ * Default partition tables to be used if the partition information not
+ * provided through platform data.
+ *
* Default partition layout for small page(= 512 bytes) devices
* Size for "Root file system" is updated in driver based on actual device size
*/
static struct mtd_partition partition_info_16KB_blk[] = {
- PARTITION("X-loader", 0, 4 * 0x4000),
- PARTITION("U-Boot", 0x10000, 20 * 0x4000),
- PARTITION("Kernel", 0x60000, 256 * 0x4000),
- PARTITION("Root File System", 0x460000, 0),
+ {
+ .name = "X-loader",
+ .offset = 0,
+ .size = 4*0x4000,
+ },
+ {
+ .name = "U-Boot",
+ .offset = 0x10000,
+ .size = 20*0x4000,
+ },
+ {
+ .name = "Kernel",
+ .offset = 0x60000,
+ .size = 256*0x4000,
+ },
+ {
+ .name = "Root File System",
+ .offset = 0x460000,
+ .size = 0,
+ },
};
/*
@@ -141,19 +157,37 @@ static struct mtd_partition partition_info_16KB_blk[] = {
* Size for "Root file system" is updated in driver based on actual device size
*/
static struct mtd_partition partition_info_128KB_blk[] = {
- PARTITION("X-loader", 0, 4 * 0x20000),
- PARTITION("U-Boot", 0x80000, 12 * 0x20000),
- PARTITION("Kernel", 0x200000, 48 * 0x20000),
- PARTITION("Root File System", 0x800000, 0),
+ {
+ .name = "X-loader",
+ .offset = 0,
+ .size = 4*0x20000,
+ },
+ {
+ .name = "U-Boot",
+ .offset = 0x80000,
+ .size = 12*0x20000,
+ },
+ {
+ .name = "Kernel",
+ .offset = 0x200000,
+ .size = 48*0x20000,
+ },
+ {
+ .name = "Root File System",
+ .offset = 0x800000,
+ .size = 0,
+ },
};
#ifdef CONFIG_MTD_CMDLINE_PARTS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif
+#endif
/**
- * struct fsmc_nand_data - atructure for FSMC NAND device state
+ * struct fsmc_nand_data - structure for FSMC NAND device state
*
+ * @pid: Part ID on the AMBA PrimeCell format
* @mtd: MTD info for a NAND flash.
* @nand: Chip related info for a NAND flash.
* @partitions: Partition info for a NAND Flash.
@@ -169,6 +203,7 @@ const char *part_probes[] = { "cmdlinepart", NULL };
* @regs_va: FSMC regs base address.
*/
struct fsmc_nand_data {
+ u32 pid;
struct mtd_info mtd;
struct nand_chip nand;
struct mtd_partition *partitions;
@@ -508,7 +543,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
struct nand_chip *nand;
struct fsmc_regs *regs;
struct resource *res;
- int nr_parts, ret = 0;
+ int ret = 0;
+ u32 pid;
+ int i;
if (!pdata) {
dev_err(&pdev->dev, "platform data is NULL\n");
@@ -598,6 +635,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
if (ret)
goto err_probe1;
+ /*
+ * This device ID is actually a common AMBA ID as used on the
+ * AMBA PrimeCell bus. However it is not a PrimeCell.
+ */
+ for (pid = 0, i = 0; i < 4; i++)
+ pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
+ host->pid = pid;
+ dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, "
+ "revision %02x, config %02x\n",
+ AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
+ AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
+
host->bank = pdata->bank;
host->select_chip = pdata->select_bank;
regs = host->regs_va;
@@ -625,7 +674,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
- if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+ if (AMBA_REV_BITS(host->pid) >= 8) {
nand->ecc.read_page = fsmc_read_page_hwecc;
nand->ecc.calculate = fsmc_read_hwecc_ecc4;
nand->ecc.correct = fsmc_correct_data;
@@ -645,7 +694,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
goto err_probe;
}
- if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+ if (AMBA_REV_BITS(host->pid) >= 8) {
if (host->mtd.writesize == 512) {
nand->ecc.layout = &fsmc_ecc4_sp_layout;
host->ecc_place = &fsmc_ecc4_sp_place;
@@ -676,11 +725,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
* Check if partition info passed via command line
*/
host->mtd.name = "nand";
- nr_parts = parse_mtd_partitions(&host->mtd, part_probes,
+ host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes,
&host->partitions, 0);
- if (nr_parts > 0) {
- host->nr_partitions = nr_parts;
- } else {
+ if (host->nr_partitions <= 0) {
#endif
/*
* Check if partition info passed via command line
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index 67343fc31bd5..cea38a5d4ac5 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -251,58 +251,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
return 0;
}
-
-/* Copy paste of nand_read_page_hwecc_oob_first except for different eccpos
- * handling. The ecc area is for 4k chips 72 bytes long and thus does not fit
- * into the eccpos array. */
-static int jz_nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
- struct nand_chip *chip, uint8_t *buf, int page)
-{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- unsigned int ecc_offset = chip->page_shift;
-
- /* Read the OOB area first */
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
- chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
- for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
-
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
-
- stat = chip->ecc.correct(mtd, p, &chip->oob_poi[i], NULL);
- if (stat < 0)
- mtd->ecc_stats.failed++;
- else
- mtd->ecc_stats.corrected += stat;
- }
- return 0;
-}
-
-/* Copy-and-paste of nand_write_page_hwecc with different eccpos handling. */
-static void jz_nand_write_page_hwecc(struct mtd_info *mtd,
- struct nand_chip *chip, const uint8_t *buf)
-{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- const uint8_t *p = buf;
- unsigned int ecc_offset = chip->page_shift;
-
- for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
- chip->write_buf(mtd, p, eccsize);
- chip->ecc.calculate(mtd, p, &chip->oob_poi[i]);
- }
-
- chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-}
-
#ifdef CONFIG_MTD_CMDLINE_PARTS
static const char *part_probes[] = {"cmdline", NULL};
#endif
@@ -393,9 +341,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
chip->ecc.size = 512;
chip->ecc.bytes = 9;
- chip->ecc.read_page = jz_nand_read_page_hwecc_oob_first;
- chip->ecc.write_page = jz_nand_write_page_hwecc;
-
if (pdata)
chip->ecc.layout = pdata->ecc_layout;
@@ -489,7 +434,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev)
return 0;
}
-struct platform_driver jz_nand_driver = {
+static struct platform_driver jz_nand_driver = {
.probe = jz_nand_probe,
.remove = __devexit_p(jz_nand_remove),
.driver = {
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 214b03afdd48..ef932ba55a0b 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1009,7 +1009,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
struct mxc_nand_host *host;
struct resource *res;
- int err = 0, nr_parts = 0;
+ int err = 0, __maybe_unused nr_parts = 0;
struct nand_ecclayout *oob_smallpage, *oob_largepage;
/* Allocate memory for MTD device structure and private data */
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1f75a1b1f7c3..33550c43acc2 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1782,6 +1782,13 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
else
len = mtd->oobsize;
+ /* Do not allow read past end of page */
+ if ((ops->ooboffs + readlen) > len) {
+ DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to read "
+ "past end of page\n", __func__);
+ return -EINVAL;
+ }
+
if (unlikely(ops->ooboffs >= len)) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read "
"outside oob\n", __func__);
@@ -2377,7 +2384,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
return -EINVAL;
}
- /* Do not allow reads past end of device */
+ /* Do not allow write past end of device */
if (unlikely(to >= mtd->size ||
ops->ooboffs + ops->ooblen >
((mtd->size >> chip->page_shift) -
@@ -2887,7 +2894,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
mtd->writesize = le32_to_cpu(p->byte_per_page);
mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
- chip->chipsize = le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
+ chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
busw = 0;
if (le16_to_cpu(p->features) & 1)
busw = NAND_BUSWIDTH_16;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 586b981f0e61..6ebd869993aa 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1092,7 +1092,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
/**
* verify_bbt_descr - verify the bad block description
- * @bd: the table to verify
+ * @mtd: MTD device structure
+ * @bd: the table to verify
*
* This functions performs a few sanity checks on the bad block description
* table.
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index a6a73aab1253..a5aa99f014ba 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -210,12 +210,12 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d
#define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */
#define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */
#define STATE_CMD_READSTART 0x00000003 /* read data second command (large page devices) */
-#define STATE_CMD_PAGEPROG 0x00000004 /* start page programm */
+#define STATE_CMD_PAGEPROG 0x00000004 /* start page program */
#define STATE_CMD_READOOB 0x00000005 /* read OOB area */
#define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */
#define STATE_CMD_STATUS 0x00000007 /* read status */
#define STATE_CMD_STATUS_M 0x00000008 /* read multi-plane status (isn't implemented) */
-#define STATE_CMD_SEQIN 0x00000009 /* sequential data imput */
+#define STATE_CMD_SEQIN 0x00000009 /* sequential data input */
#define STATE_CMD_READID 0x0000000A /* read ID */
#define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */
#define STATE_CMD_RESET 0x0000000C /* reset */
@@ -230,7 +230,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d
#define STATE_ADDR_ZERO 0x00000040 /* one byte zero address was accepted */
#define STATE_ADDR_MASK 0x00000070 /* address states mask */
-/* Durind data input/output the simulator is in these states */
+/* During data input/output the simulator is in these states */
#define STATE_DATAIN 0x00000100 /* waiting for data input */
#define STATE_DATAIN_MASK 0x00000100 /* data input states mask */
@@ -248,7 +248,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d
/* Simulator's actions bit masks */
#define ACTION_CPY 0x00100000 /* copy page/OOB to the internal buffer */
-#define ACTION_PRGPAGE 0x00200000 /* programm the internal buffer to flash */
+#define ACTION_PRGPAGE 0x00200000 /* program the internal buffer to flash */
#define ACTION_SECERASE 0x00300000 /* erase sector */
#define ACTION_ZEROOFF 0x00400000 /* don't add any offset to address */
#define ACTION_HALFOFF 0x00500000 /* add to address half of page */
@@ -263,18 +263,18 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d
#define OPT_PAGE512 0x00000002 /* 512-byte page chips */
#define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */
#define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */
-#define OPT_AUTOINCR 0x00000020 /* page number auto inctimentation is possible */
+#define OPT_AUTOINCR 0x00000020 /* page number auto incrementation is possible */
#define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */
#define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */
#define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */
#define OPT_SMALLPAGE (OPT_PAGE256 | OPT_PAGE512) /* 256 and 512-byte page chips */
-/* Remove action bits ftom state */
+/* Remove action bits from state */
#define NS_STATE(x) ((x) & ~ACTION_MASK)
/*
* Maximum previous states which need to be saved. Currently saving is
- * only needed for page programm operation with preceeded read command
+ * only needed for page program operation with preceded read command
* (which is only valid for 512-byte pages).
*/
#define NS_MAX_PREVSTATES 1
@@ -380,16 +380,16 @@ static struct nandsim_operations {
/* Read OOB */
{OPT_SMALLPAGE, {STATE_CMD_READOOB | ACTION_OOBOFF, STATE_ADDR_PAGE | ACTION_CPY,
STATE_DATAOUT, STATE_READY}},
- /* Programm page starting from the beginning */
+ /* Program page starting from the beginning */
{OPT_ANY, {STATE_CMD_SEQIN, STATE_ADDR_PAGE, STATE_DATAIN,
STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
- /* Programm page starting from the beginning */
+ /* Program page starting from the beginning */
{OPT_SMALLPAGE, {STATE_CMD_READ0, STATE_CMD_SEQIN | ACTION_ZEROOFF, STATE_ADDR_PAGE,
STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
- /* Programm page starting from the second half */
+ /* Program page starting from the second half */
{OPT_PAGE512, {STATE_CMD_READ1, STATE_CMD_SEQIN | ACTION_HALFOFF, STATE_ADDR_PAGE,
STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
- /* Programm OOB */
+ /* Program OOB */
{OPT_SMALLPAGE, {STATE_CMD_READOOB, STATE_CMD_SEQIN | ACTION_OOBOFF, STATE_ADDR_PAGE,
STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
/* Erase sector */
@@ -470,7 +470,7 @@ static int alloc_device(struct nandsim *ns)
err = -EINVAL;
goto err_close;
}
- ns->pages_written = vmalloc(ns->geom.pgnum);
+ ns->pages_written = vzalloc(ns->geom.pgnum);
if (!ns->pages_written) {
NS_ERR("alloc_device: unable to allocate pages written array\n");
err = -ENOMEM;
@@ -483,7 +483,6 @@ static int alloc_device(struct nandsim *ns)
goto err_free;
}
ns->cfile = cfile;
- memset(ns->pages_written, 0, ns->geom.pgnum);
return 0;
}
@@ -1171,9 +1170,9 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status)
* of supported operations.
*
* Operation can be unknown because of the following.
- * 1. New command was accepted and this is the firs call to find the
+ * 1. New command was accepted and this is the first call to find the
* correspondent states chain. In this case ns->npstates = 0;
- * 2. There is several operations which begin with the same command(s)
+ * 2. There are several operations which begin with the same command(s)
* (for example program from the second half and read from the
* second half operations both begin with the READ1 command). In this
* case the ns->pstates[] array contains previous states.
@@ -1186,7 +1185,7 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status)
* ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
* zeroed).
*
- * If there are several maches, the current state is pushed to the
+ * If there are several matches, the current state is pushed to the
* ns->pstates.
*
* The operation can be unknown only while commands are input to the chip.
@@ -1195,10 +1194,10 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status)
* operation is searched using the following pattern:
* ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
*
- * It is supposed that this pattern must either match one operation on
+ * It is supposed that this pattern must either match one operation or
* none. There can't be ambiguity in that case.
*
- * If no matches found, the functions does the following:
+ * If no matches found, the function does the following:
* 1. if there are saved states present, try to ignore them and search
* again only using the last command. If nothing was found, switch
* to the STATE_READY state.
@@ -1668,7 +1667,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
case ACTION_PRGPAGE:
/*
- * Programm page - move internal buffer data to the page.
+ * Program page - move internal buffer data to the page.
*/
if (ns->lines.wp) {
@@ -1933,7 +1932,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd)
NS_DBG("read_byte: all bytes were read\n");
/*
- * The OPT_AUTOINCR allows to read next conseqitive pages without
+ * The OPT_AUTOINCR allows to read next consecutive pages without
* new read operation cycle.
*/
if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index cd41c58b5bbd..15682ec8530e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -7,7 +7,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define CONFIG_MTD_NAND_OMAP_HWECC
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c
index 6ddb2461d740..bb277a54986f 100644
--- a/drivers/mtd/nand/pasemi_nand.c
+++ b/drivers/mtd/nand/pasemi_nand.c
@@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev,
if (pasemi_nand_mtd)
return -ENODEV;
- pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end);
+ pr_debug("pasemi_nand at %pR\n", &res);
/* Allocate memory for MTD device structure and private data */
pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) +
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 9f322f1a7f22..2d482b045b4d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -108,8 +108,9 @@ static void wait_warn(char *msg, int state, unsigned int ctrl,
static int omap2_onenand_wait(struct mtd_info *mtd, int state)
{
struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ struct onenand_chip *this = mtd->priv;
unsigned int intr = 0;
- unsigned int ctrl;
+ unsigned int ctrl, ctrl_mask;
unsigned long timeout;
u32 syscfg;
@@ -180,7 +181,8 @@ retry:
if (result == 0) {
/* Timeout after 20ms */
ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
- if (ctrl & ONENAND_CTRL_ONGO) {
+ if (ctrl & ONENAND_CTRL_ONGO &&
+ !this->ongoing) {
/*
* The operation seems to be still going
* so give it some more time.
@@ -269,7 +271,11 @@ retry:
return -EIO;
}
- if (ctrl & 0xFE9F)
+ ctrl_mask = 0xFE9F;
+ if (this->ongoing)
+ ctrl_mask &= ~0x8000;
+
+ if (ctrl & ctrl_mask)
wait_warn("unexpected controller status", state, ctrl, intr);
return 0;
@@ -721,6 +727,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
case 3:
c->freq = 83;
break;
+ case 4:
+ c->freq = 104;
+ break;
}
#ifdef CONFIG_MTD_PARTITIONS
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 6b3a875647c9..c38bf9c54a11 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -400,8 +400,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
value = onenand_bufferram_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
- if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this) ||
- ONENAND_IS_4KB_PAGE(this))
+ if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this))
/* It is always BufferRAM0 */
ONENAND_SET_BUFFERRAM0(this);
else
@@ -430,7 +429,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
case FLEXONENAND_CMD_RECOVER_LSB:
case ONENAND_CMD_READ:
case ONENAND_CMD_READOOB:
- if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
+ if (ONENAND_IS_4KB_PAGE(this))
/* It is always BufferRAM0 */
dataram = ONENAND_SET_BUFFERRAM0(this);
else
@@ -1353,7 +1352,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
stats = mtd->ecc_stats;
- readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+ readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
while (read < len) {
cond_resched();
@@ -1429,7 +1428,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
int ret;
onenand_get_device(mtd, FL_READING);
- ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
+ ret = ONENAND_IS_4KB_PAGE(this) ?
onenand_mlc_read_ops_nolock(mtd, from, &ops) :
onenand_read_ops_nolock(mtd, from, &ops);
onenand_release_device(mtd);
@@ -1464,7 +1463,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
onenand_get_device(mtd, FL_READING);
if (ops->datbuf)
- ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
+ ret = ONENAND_IS_4KB_PAGE(this) ?
onenand_mlc_read_ops_nolock(mtd, from, ops) :
onenand_read_ops_nolock(mtd, from, ops);
else
@@ -1558,7 +1557,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
column = from & (mtd->oobsize - 1);
- readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+ readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
while (read < len) {
cond_resched();
@@ -1612,7 +1611,7 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
u_char *oob_buf = this->oob_buf;
int status, i, readcmd;
- readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+ readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
this->command(mtd, readcmd, to, mtd->oobsize);
onenand_update_bufferram(mtd, to, 0);
@@ -1845,7 +1844,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
const u_char *buf = ops->datbuf;
const u_char *oob = ops->oobbuf;
u_char *oobbuf;
- int ret = 0;
+ int ret = 0, cmd;
DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
__func__, (unsigned int) to, (int) len);
@@ -1954,7 +1953,19 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
ONENAND_SET_NEXT_BUFFERRAM(this);
}
- this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
+ this->ongoing = 0;
+ cmd = ONENAND_CMD_PROG;
+
+ /* Exclude 1st OTP and OTP blocks for cache program feature */
+ if (ONENAND_IS_CACHE_PROGRAM(this) &&
+ likely(onenand_block(this, to) != 0) &&
+ ONENAND_IS_4KB_PAGE(this) &&
+ ((written + thislen) < len)) {
+ cmd = ONENAND_CMD_2X_CACHE_PROG;
+ this->ongoing = 1;
+ }
+
+ this->command(mtd, cmd, to, mtd->writesize);
/*
* 2 PLANE, MLC, and Flex-OneNAND wait here
@@ -2067,7 +2078,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
oobbuf = this->oob_buf;
- oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
+ oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
/* Loop until all data write */
while (written < len) {
@@ -2086,7 +2097,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
memcpy(oobbuf + column, buf, thislen);
this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
- if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) {
+ if (ONENAND_IS_4KB_PAGE(this)) {
/* Set main area of DataRAM to 0xff*/
memset(this->page_buf, 0xff, mtd->writesize);
this->write_bufferram(mtd, ONENAND_DATARAM,
@@ -3029,7 +3040,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
this->wait(mtd, FL_OTPING);
- ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ?
+ ret = ONENAND_IS_4KB_PAGE(this) ?
onenand_mlc_read_ops_nolock(mtd, from, &ops) :
onenand_read_ops_nolock(mtd, from, &ops);
@@ -3377,8 +3388,10 @@ static void onenand_check_features(struct mtd_info *mtd)
case ONENAND_DEVICE_DENSITY_4Gb:
if (ONENAND_IS_DDP(this))
this->options |= ONENAND_HAS_2PLANE;
- else if (numbufs == 1)
+ else if (numbufs == 1) {
this->options |= ONENAND_HAS_4KB_PAGE;
+ this->options |= ONENAND_HAS_CACHE_PROGRAM;
+ }
case ONENAND_DEVICE_DENSITY_2Gb:
/* 2Gb DDP does not have 2 plane */
@@ -3399,7 +3412,11 @@ static void onenand_check_features(struct mtd_info *mtd)
break;
}
- if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
+ /* The MLC has 4KiB pagesize. */
+ if (ONENAND_IS_MLC(this))
+ this->options |= ONENAND_HAS_4KB_PAGE;
+
+ if (ONENAND_IS_4KB_PAGE(this))
this->options &= ~ONENAND_HAS_2PLANE;
if (FLEXONENAND(this)) {
@@ -3415,6 +3432,8 @@ static void onenand_check_features(struct mtd_info *mtd)
printk(KERN_DEBUG "Chip has 2 plane\n");
if (this->options & ONENAND_HAS_4KB_PAGE)
printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
+ if (this->options & ONENAND_HAS_CACHE_PROGRAM)
+ printk(KERN_DEBUG "Chip has cache program feature\n");
}
/**
@@ -3831,7 +3850,7 @@ static int onenand_probe(struct mtd_info *mtd)
/* The data buffer size is equal to page size */
mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
/* We use the full BufferRAM */
- if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this))
+ if (ONENAND_IS_4KB_PAGE(this))
mtd->writesize <<= 1;
mtd->oobsize = mtd->writesize >> 5;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 01ab5b3c453b..905209bf9465 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -91,13 +91,15 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
for (j = 0; j < len; j++) {
/* No need to read pages fully,
* just read required OOB bytes */
- ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
+ ret = onenand_bbt_read_oob(mtd,
+ from + j * this->writesize + bd->offs, &ops);
/* If it is a initial bad block, just ignore it */
if (ret == ONENAND_BBT_READ_FATAL_ERROR)
return -EIO;
- if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
+ if (ret || check_short_pattern(&buf[j * scanlen],
+ scanlen, this->writesize, bd)) {
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index 0de7a05e6de0..a4c74a9ba430 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -651,7 +651,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
void __iomem *p;
void *buf = (void *) buffer;
dma_addr_t dma_src, dma_dst;
- int err, page_dma = 0;
+ int err, ofs, page_dma = 0;
struct device *dev = &onenand->pdev->dev;
p = this->base + area;
@@ -677,10 +677,13 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
if (!page)
goto normal;
+ /* Page offset */
+ ofs = ((size_t) buf & ~PAGE_MASK);
page_dma = 1;
+
/* DMA routine */
dma_src = onenand->phys_base + (p - this->base);
- dma_dst = dma_map_page(dev, page, 0, count, DMA_FROM_DEVICE);
+ dma_dst = dma_map_page(dev, page, ofs, count, DMA_FROM_DEVICE);
} else {
/* DMA routine */
dma_src = onenand->phys_base + (p - this->base);
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index c2960ac9f39c..811775aa8ee8 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -482,10 +482,17 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
uint32_t data = 0;
struct ubi_vid_hdr vid_hdr;
- addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
+ /*
+ * It is important to first invalidate the EC header, and then the VID
+ * header. Otherwise a power cut may lead to valid EC header and
+ * invalid VID header, in which case UBI will treat this PEB as
+ * corrupted and will try to preserve it, and print scary warnings (see
+ * the header comment in scan.c for more information).
+ */
+ addr = (loff_t)pnum * ubi->peb_size;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
if (!err) {
- addr -= ubi->vid_hdr_aloffset;
+ addr += ubi->vid_hdr_aloffset;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
(void *)&data);
if (!err)
@@ -494,18 +501,24 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
/*
* We failed to write to the media. This was observed with Spansion
- * S29GL512N NOR flash. Most probably the eraseblock erasure was
- * interrupted at a very inappropriate moment, so it became unwritable.
- * In this case we probably anyway have garbage in this PEB.
+ * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+ * was interrupted at a very inappropriate moment, so it became
+ * unwritable. In this case we probably anyway have garbage in this
+ * PEB.
*/
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
- if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
- /*
- * The VID header is corrupted, so we can safely erase this
- * PEB and not afraid that it will be treated as a valid PEB in
- * case of an unclean reboot.
- */
- return 0;
+ if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) {
+ struct ubi_ec_hdr ec_hdr;
+
+ err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
+ if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
+ /*
+ * Both VID and EC headers are corrupted, so we can
+ * safely erase this PEB and not afraid that it will be
+ * treated as a valid PEB in case of an unclean reboot.
+ */
+ return 0;
+ }
/*
* The PEB contains a valid VID header, but we cannot invalidate it.
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 204345be8e62..79ca304fc4db 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -953,6 +953,10 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
* impossible to distinguish it from a PEB which just
* contains garbage because of a power cut during erase
* operation. So we just schedule this PEB for erasure.
+ *
+ * Besides, in case of NOR flash, we deliberatly
+ * corrupt both headers because NOR flash erasure is
+ * slow and can start from the end.
*/
err = 0;
else
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index fcdb7f65fe0b..0b8141fc5c26 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -425,12 +425,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
/* Read both LEB 0 and LEB 1 into memory */
ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) {
- leb[seb->lnum] = vmalloc(ubi->vtbl_size);
+ leb[seb->lnum] = vzalloc(ubi->vtbl_size);
if (!leb[seb->lnum]) {
err = -ENOMEM;
goto out_free;
}
- memset(leb[seb->lnum], 0, ubi->vtbl_size);
err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
ubi->vtbl_size);
@@ -516,10 +515,9 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
int i;
struct ubi_vtbl_record *vtbl;
- vtbl = vmalloc(ubi->vtbl_size);
+ vtbl = vzalloc(ubi->vtbl_size);
if (!vtbl)
return ERR_PTR(-ENOMEM);
- memset(vtbl, 0, ubi->vtbl_size);
for (i = 0; i < ubi->vtbl_slots; i++)
memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE);
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 1776ab61b05f..9e1c03eb97ae 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -158,8 +158,8 @@ static int mem_start;
struct net_device * __init el1_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static unsigned ports[] = { 0x280, 0x300, 0};
- unsigned *port;
+ static const unsigned ports[] = { 0x280, 0x300, 0};
+ const unsigned *port;
int err = 0;
if (!dev)
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 4777a1cbcd8d..d84f6e8903a5 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -392,8 +392,8 @@ el2_open(struct net_device *dev)
int retval;
if (dev->irq < 2) {
- int irqlist[] = {5, 9, 3, 4, 0};
- int *irqp = irqlist;
+ static const int irqlist[] = {5, 9, 3, 4, 0};
+ const int *irqp = irqlist;
outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
do {
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index ea9b7a098c9b..1e945551c144 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -201,7 +201,7 @@ struct net_local {
#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
#define RX_BUF_END (dev->mem_end - dev->mem_start)
-#define TX_TIMEOUT 5
+#define TX_TIMEOUT (HZ/20)
/*
That's it: only 86 bytes to set up the beast, including every extra
@@ -311,8 +311,8 @@ static int mem_start;
struct net_device * __init el16_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
- unsigned *port;
+ static const unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
+ const unsigned *port;
int err = -ENODEV;
if (!dev)
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index cdf7226a7c43..d2bb4b254c57 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -98,7 +98,7 @@ static int rx_nocopy, rx_copy, queued_packet;
#define WAIT_TX_AVAIL 200
/* Operational parameter that usually are not changed. */
-#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */
+#define TX_TIMEOUT ((4*HZ)/10) /* Time in jiffies before concluding Tx hung */
/* The size here is somewhat misleading: the Corkscrew also uses the ISA
aliased registers at <base>+0x400.
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index 013b7c396663..8c094bae8bf3 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -317,13 +317,13 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
u8 POS;
u32 base;
struct mc32_local *lp = netdev_priv(dev);
- static u16 mca_io_bases[]={
+ static const u16 mca_io_bases[] = {
0x7280,0x7290,
0x7680,0x7690,
0x7A80,0x7A90,
0x7E80,0x7E90
};
- static u32 mca_mem_bases[]={
+ static const u32 mca_mem_bases[] = {
0x00C0000,
0x00C4000,
0x00C8000,
@@ -333,7 +333,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
0x00D8000,
0x00DC000
};
- static char *failures[]={
+ static const char * const failures[] = {
"Processor instruction",
"Processor data bus",
"Processor data bus",
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index f5166dccd8df..98517a373473 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1092,10 +1092,11 @@ err_out:
static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
assert (dev != NULL);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&tp->thread);
unregister_netdev (dev);
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index e2c9c5b949f9..be1f1970c842 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -191,7 +191,7 @@ enum commands {
#define RX_SUSPEND 0x0030
#define RX_ABORT 0x0040
-#define TX_TIMEOUT 5
+#define TX_TIMEOUT (HZ/20)
struct i596_reg {
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755bddf6b..3fda24a28d2f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1533,7 +1533,7 @@ config E100
<http://support.intel.com/support/network/adapter/pro100/21397.htm>
- to identify the adapter.
+ to identify the adapter.
For the latest Intel PRO/100 network driver for Linux, see:
@@ -1786,17 +1786,17 @@ config KS8842
tristate "Micrel KSZ8841/42 with generic bus interface"
depends on HAS_IOMEM && DMA_ENGINE
help
- This platform driver is for KSZ8841(1-port) / KS8842(2-port)
- ethernet switch chip (managed, VLAN, QoS) from Micrel or
- Timberdale(FPGA).
+ This platform driver is for KSZ8841(1-port) / KS8842(2-port)
+ ethernet switch chip (managed, VLAN, QoS) from Micrel or
+ Timberdale(FPGA).
config KS8851
- tristate "Micrel KS8851 SPI"
- depends on SPI
- select MII
+ tristate "Micrel KS8851 SPI"
+ depends on SPI
+ select MII
select CRC32
- help
- SPI driver for Micrel KS8851 SPI attached network chip.
+ help
+ SPI driver for Micrel KS8851 SPI attached network chip.
config KS8851_MLL
tristate "Micrel KS8851 MLL"
@@ -2133,25 +2133,25 @@ config IP1000
will be called ipg. This is recommended.
config IGB
- tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
- depends on PCI
- ---help---
- This driver supports Intel(R) 82575/82576 gigabit ethernet family of
- adapters. For more information on how to identify your adapter, go
- to the Adapter & Driver ID Guide at:
+ tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
+ depends on PCI
+ ---help---
+ This driver supports Intel(R) 82575/82576 gigabit ethernet family of
+ adapters. For more information on how to identify your adapter, go
+ to the Adapter & Driver ID Guide at:
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+ <http://support.intel.com/support/network/adapter/pro100/21397.htm>
- For general information and support, go to the Intel support
- website at:
+ For general information and support, go to the Intel support
+ website at:
- <http://support.intel.com>
+ <http://support.intel.com>
- More specific information on configuring the driver is in
- <file:Documentation/networking/e1000.txt>.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/e1000.txt>.
- To compile this driver as a module, choose M here. The module
- will be called igb.
+ To compile this driver as a module, choose M here. The module
+ will be called igb.
config IGB_DCA
bool "Direct Cache Access (DCA) Support"
@@ -2163,25 +2163,25 @@ config IGB_DCA
is used, with the intent of lessening the impact of cache misses.
config IGBVF
- tristate "Intel(R) 82576 Virtual Function Ethernet support"
- depends on PCI
- ---help---
- This driver supports Intel(R) 82576 virtual functions. For more
- information on how to identify your adapter, go to the Adapter &
- Driver ID Guide at:
+ tristate "Intel(R) 82576 Virtual Function Ethernet support"
+ depends on PCI
+ ---help---
+ This driver supports Intel(R) 82576 virtual functions. For more
+ information on how to identify your adapter, go to the Adapter &
+ Driver ID Guide at:
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+ <http://support.intel.com/support/network/adapter/pro100/21397.htm>
- For general information and support, go to the Intel support
- website at:
+ For general information and support, go to the Intel support
+ website at:
- <http://support.intel.com>
+ <http://support.intel.com>
- More specific information on configuring the driver is in
- <file:Documentation/networking/e1000.txt>.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/e1000.txt>.
- To compile this driver as a module, choose M here. The module
- will be called igbvf.
+ To compile this driver as a module, choose M here. The module
+ will be called igbvf.
source "drivers/net/ixp2000/Kconfig"
@@ -2233,6 +2233,7 @@ config YELLOWFIN
config R8169
tristate "Realtek 8169 gigabit ethernet support"
depends on PCI
+ select FW_LOADER
select CRC32
select MII
---help---
@@ -2300,14 +2301,14 @@ config SKGE
will be called skge. This is recommended.
config SKGE_DEBUG
- bool "Debugging interface"
- depends on SKGE && DEBUG_FS
- help
- This option adds the ability to dump driver state for debugging.
- The file /sys/kernel/debug/skge/ethX displays the state of the internal
- transmit and receive rings.
+ bool "Debugging interface"
+ depends on SKGE && DEBUG_FS
+ help
+ This option adds the ability to dump driver state for debugging.
+ The file /sys/kernel/debug/skge/ethX displays the state of the internal
+ transmit and receive rings.
- If unsure, say N.
+ If unsure, say N.
config SKY2
tristate "SysKonnect Yukon2 support"
@@ -2326,14 +2327,14 @@ config SKY2
will be called sky2. This is recommended.
config SKY2_DEBUG
- bool "Debugging interface"
- depends on SKY2 && DEBUG_FS
- help
- This option adds the ability to dump driver state for debugging.
- The file /sys/kernel/debug/sky2/ethX displays the state of the internal
- transmit and receive rings.
+ bool "Debugging interface"
+ depends on SKY2 && DEBUG_FS
+ help
+ This option adds the ability to dump driver state for debugging.
+ The file /sys/kernel/debug/sky2/ethX displays the state of the internal
+ transmit and receive rings.
- If unsure, say N.
+ If unsure, say N.
config VIA_VELOCITY
tristate "VIA Velocity support"
@@ -2389,12 +2390,12 @@ config SPIDER_NET
Cell Processor-Based Blades from IBM.
config TSI108_ETH
- tristate "Tundra TSI108 gigabit Ethernet support"
- depends on TSI108_BRIDGE
- help
- This driver supports Tundra TSI108 gigabit Ethernet ports.
- To compile this driver as a module, choose M here: the module
- will be called tsi108_eth.
+ tristate "Tundra TSI108 gigabit Ethernet support"
+ depends on TSI108_BRIDGE
+ help
+ This driver supports Tundra TSI108 gigabit Ethernet ports.
+ To compile this driver as a module, choose M here: the module
+ will be called tsi108_eth.
config GELIC_NET
tristate "PS3 Gigabit Ethernet driver"
@@ -2573,32 +2574,32 @@ config MDIO
tristate
config CHELSIO_T1
- tristate "Chelsio 10Gb Ethernet support"
- depends on PCI
+ tristate "Chelsio 10Gb Ethernet support"
+ depends on PCI
select CRC32
select MDIO
- help
- This driver supports Chelsio gigabit and 10-gigabit
- Ethernet cards. More information about adapter features and
+ help
+ This driver supports Chelsio gigabit and 10-gigabit
+ Ethernet cards. More information about adapter features and
performance tuning is in <file:Documentation/networking/cxgb.txt>.
- For general information about Chelsio and our products, visit
- our website at <http://www.chelsio.com>.
+ 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.html>.
+ For customer support, please visit our customer support page at
+ <http://www.chelsio.com/support.html>.
- Please send feedback to <linux-bugs@chelsio.com>.
+ Please send feedback to <linux-bugs@chelsio.com>.
- To compile this driver as a module, choose M here: the module
- will be called cxgb.
+ To compile this driver as a module, choose M here: the module
+ will be called cxgb.
config CHELSIO_T1_1G
- bool "Chelsio gigabit Ethernet support"
- depends on CHELSIO_T1
- help
- Enables support for Chelsio's gigabit Ethernet PCI cards. If you
- are using only 10G cards say 'N' here.
+ bool "Chelsio gigabit Ethernet support"
+ depends on CHELSIO_T1
+ help
+ Enables support for Chelsio's gigabit Ethernet PCI cards. If you
+ are using only 10G cards say 'N' here.
config CHELSIO_T3_DEPENDS
tristate
@@ -2728,26 +2729,26 @@ config IXGBE_DCB
If unsure, say N.
config IXGBEVF
- tristate "Intel(R) 82599 Virtual Function Ethernet support"
- depends on PCI_MSI
- ---help---
- This driver supports Intel(R) 82599 virtual functions. For more
- information on how to identify your adapter, go to the Adapter &
- Driver ID Guide at:
+ tristate "Intel(R) 82599 Virtual Function Ethernet support"
+ depends on PCI_MSI
+ ---help---
+ This driver supports Intel(R) 82599 virtual functions. For more
+ information on how to identify your adapter, go to the Adapter &
+ Driver ID Guide at:
- <http://support.intel.com/support/network/sb/CS-008441.htm>
+ <http://support.intel.com/support/network/sb/CS-008441.htm>
- For general information and support, go to the Intel support
- website at:
+ For general information and support, go to the Intel support
+ website at:
- <http://support.intel.com>
+ <http://support.intel.com>
- More specific information on configuring the driver is in
- <file:Documentation/networking/ixgbevf.txt>.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/ixgbevf.txt>.
- To compile this driver as a module, choose M here. The module
- will be called ixgbevf. MSI-X interrupt support is required
- for this driver to work correctly.
+ To compile this driver as a module, choose M here. The module
+ will be called ixgbevf. MSI-X interrupt support is required
+ for this driver to work correctly.
config IXGB
tristate "Intel(R) PRO/10GbE support"
@@ -2772,29 +2773,38 @@ config IXGB
will be called ixgb.
config S2IO
- tristate "S2IO 10Gbe XFrame NIC"
+ tristate "Exar Xframe 10Gb Ethernet Adapter"
depends on PCI
---help---
- This driver supports the 10Gbe XFrame NIC of S2IO.
+ This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
+
More specific information on configuring the driver is in
<file:Documentation/networking/s2io.txt>.
+ To compile this driver as a module, choose M here. The module
+ will be called s2io.
+
config VXGE
- tristate "Neterion X3100 Series 10GbE PCIe Server Adapter"
+ tristate "Exar X3100 Series 10GbE PCIe Server Adapter"
depends on PCI && INET
---help---
- This driver supports Neterion Inc's X3100 Series 10 GbE PCIe
+ This driver supports Exar Corp's X3100 Series 10 GbE PCIe
I/O Virtualized Server Adapter.
+
More specific information on configuring the driver is in
<file:Documentation/networking/vxge.txt>.
+ To compile this driver as a module, choose M here. The module
+ will be called vxge.
+
config VXGE_DEBUG_TRACE_ALL
bool "Enabling All Debug trace statments in driver"
default n
depends on VXGE
---help---
Say Y here if you want to enabling all the debug trace statements in
- driver. By default only few debug trace statements are enabled.
+ the vxge driver. By default only few debug trace statements are
+ enabled.
config MYRI10GE
tristate "Myricom Myri-10G Ethernet support"
@@ -2906,18 +2916,18 @@ config QLGE
will be called qlge.
config BNA
- tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
- depends on PCI
- ---help---
- This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
- cards.
- To compile this driver as a module, choose M here: the module
- will be called bna.
+ tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
+ depends on PCI
+ ---help---
+ This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
+ cards.
+ To compile this driver as a module, choose M here: the module
+ will be called bna.
- For general information and support, go to the Brocade support
- website at:
+ For general information and support, go to the Brocade support
+ website at:
- <http://support.brocade.com>
+ <http://support.brocade.com>
source "drivers/net/sfc/Kconfig"
@@ -3239,18 +3249,18 @@ config PPP_BSDCOMP
modules once you have said "make modules". If unsure, say N.
config PPP_MPPE
- tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
- depends on PPP && EXPERIMENTAL
- select CRYPTO
- select CRYPTO_SHA1
- select CRYPTO_ARC4
- select CRYPTO_ECB
- ---help---
- Support for the MPPE Encryption protocol, as employed by the
- Microsoft Point-to-Point Tunneling Protocol.
-
- See http://pptpclient.sourceforge.net/ for information on
- configuring PPTP clients and servers to utilize this method.
+ tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
+ depends on PPP && EXPERIMENTAL
+ select CRYPTO
+ select CRYPTO_SHA1
+ select CRYPTO_ARC4
+ select CRYPTO_ECB
+ ---help---
+ Support for the MPPE Encryption protocol, as employed by the
+ Microsoft Point-to-Point Tunneling Protocol.
+
+ See http://pptpclient.sourceforge.net/ for information on
+ configuring PPTP clients and servers to utilize this method.
config PPPOE
tristate "PPP over Ethernet (EXPERIMENTAL)"
@@ -3409,14 +3419,14 @@ config VIRTIO_NET
depends on EXPERIMENTAL && VIRTIO
---help---
This is the virtual network driver for virtio. It can be used with
- lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
+ lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
config VMXNET3
- tristate "VMware VMXNET3 ethernet driver"
- depends on PCI && INET
- help
- This driver supports VMware's vmxnet3 virtual ethernet NIC.
- To compile this driver as a module, choose M here: the
- module will be called vmxnet3.
+ tristate "VMware VMXNET3 ethernet driver"
+ depends on PCI && INET
+ help
+ This driver supports VMware's vmxnet3 virtual ethernet NIC.
+ To compile this driver as a module, choose M here: the
+ module will be called vmxnet3.
endif # NETDEVICES
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 9bb405bd664e..068c3563e00f 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -55,8 +55,6 @@ extern struct net_device *eth16i_probe(int unit);
extern struct net_device *i82596_probe(int unit);
extern struct net_device *ewrk3_probe(int unit);
extern struct net_device *el1_probe(int unit);
-extern struct net_device *wavelan_probe(int unit);
-extern struct net_device *arlan_probe(int unit);
extern struct net_device *el16_probe(int unit);
extern struct net_device *elmc_probe(int unit);
extern struct net_device *elplus_probe(int unit);
@@ -68,7 +66,6 @@ extern struct net_device *ni5010_probe(int unit);
extern struct net_device *ni52_probe(int unit);
extern struct net_device *ni65_probe(int unit);
extern struct net_device *sonic_probe(int unit);
-extern struct net_device *SK_init(int unit);
extern struct net_device *seeq8005_probe(int unit);
extern struct net_device *smc_init(int unit);
extern struct net_device *atarilance_probe(int unit);
@@ -76,8 +73,6 @@ extern struct net_device *sun3lance_probe(int unit);
extern struct net_device *sun3_82586_probe(int unit);
extern struct net_device *apne_probe(int unit);
extern struct net_device *cs89x0_probe(int unit);
-extern struct net_device *hplance_probe(int unit);
-extern struct net_device *bagetlance_probe(int unit);
extern struct net_device *mvme147lance_probe(int unit);
extern struct net_device *tc515_probe(int unit);
extern struct net_device *lance_probe(int unit);
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 62f21106efec..0c9217f48b72 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -340,14 +340,6 @@ am79c961_close(struct net_device *dev)
return 0;
}
-/*
- * Get the current statistics.
- */
-static struct net_device_stats *am79c961_getstats (struct net_device *dev)
-{
- return &dev->stats;
-}
-
static void am79c961_mc_hash(char *addr, unsigned short *hash)
{
if (addr[0] & 0x01) {
@@ -665,7 +657,6 @@ static const struct net_device_ops am79c961_netdev_ops = {
.ndo_open = am79c961_open,
.ndo_stop = am79c961_close,
.ndo_start_xmit = am79c961_sendpacket,
- .ndo_get_stats = am79c961_getstats,
.ndo_set_multicast_list = am79c961_setmulticastlist,
.ndo_tx_timeout = am79c961_timeout,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c
index 4545d5a06c24..bfea499a3513 100644
--- a/drivers/net/arm/w90p910_ether.c
+++ b/drivers/net/arm/w90p910_ether.c
@@ -117,7 +117,7 @@
#define TX_DESC_SIZE 10
#define MAX_RBUFF_SZ 0x600
#define MAX_TBUFF_SZ 0x600
-#define TX_TIMEOUT 50
+#define TX_TIMEOUT (HZ/2)
#define DELAY 1000
#define CAM0 0x0
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 89876897a6fe..f4744fc89768 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -150,7 +150,7 @@ struct net_local {
#define PORT_OFFSET(o) (o)
-#define TX_TIMEOUT 10
+#define TX_TIMEOUT (HZ/10)
/* Index to functions, as function prototypes. */
@@ -270,9 +270,9 @@ static const struct net_device_ops at1700_netdev_ops = {
static int __init at1700_probe1(struct net_device *dev, int ioaddr)
{
- char fmv_irqmap[4] = {3, 7, 10, 15};
- char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
- char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
+ static const char fmv_irqmap[4] = {3, 7, 10, 15};
+ static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
+ static const char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
int slot, ret = -ENODEV;
struct net_local *lp = netdev_priv(dev);
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 8cb27cb7bca1..ce0091eb06f5 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -116,7 +116,7 @@ MODULE_LICENSE("GPL");
#define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5)
#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define TX_TIMEOUT 20
+#define TX_TIMEOUT (HZ/5)
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 09b099bfab2b..a699bbf20eb5 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -702,6 +702,7 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
adapter->wol = 0;
+ device_set_wakeup_enable(&pdev->dev, false);
adapter->link_speed = SPEED_0;
adapter->link_duplex = FULL_DUPLEX;
adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
@@ -2078,7 +2079,7 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter,
check_sum:
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
u8 css, cso;
- cso = skb_transport_offset(skb);
+ cso = skb_checksum_start_offset(skb);
if (unlikely(cso & 0x1)) {
if (netif_msg_tx_err(adapter))
@@ -2444,8 +2445,9 @@ static int atl1c_close(struct net_device *netdev)
return 0;
}
-static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
+static int atl1c_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
@@ -2454,7 +2456,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
u32 wol_ctrl_data = 0;
u16 mii_intr_status_data = 0;
u32 wufc = adapter->wol;
- int retval = 0;
atl1c_disable_l0s_l1(hw);
if (netif_running(netdev)) {
@@ -2462,9 +2463,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
atl1c_down(adapter);
}
netif_device_detach(netdev);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
if (wufc)
if (atl1c_phy_power_saving(hw) != 0)
@@ -2525,12 +2523,8 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
- /* pcie patch */
- device_set_wakeup_enable(&pdev->dev, 1);
-
AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
GPHY_CTRL_EXT_RESET);
- pci_prepare_to_sleep(pdev);
} else {
AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING);
master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS;
@@ -2540,25 +2534,17 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
hw->phy_configured = false; /* re-init PHY when resume */
- 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;
}
-static int atl1c_resume(struct pci_dev *pdev)
+static int atl1c_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1c_adapter *adapter = netdev_priv(netdev);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
ATL1C_PCIE_PHY_RESET);
@@ -2582,7 +2568,12 @@ static int atl1c_resume(struct pci_dev *pdev)
static void atl1c_shutdown(struct pci_dev *pdev)
{
- atl1c_suspend(pdev, PMSG_SUSPEND);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ atl1c_suspend(&pdev->dev);
+ pci_wake_from_d3(pdev, adapter->wol);
+ pci_set_power_state(pdev, PCI_D3hot);
}
static const struct net_device_ops atl1c_netdev_ops = {
@@ -2886,16 +2877,16 @@ static struct pci_error_handlers atl1c_err_handler = {
.resume = atl1c_io_resume,
};
+static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume);
+
static struct pci_driver atl1c_driver = {
.name = atl1c_driver_name,
.id_table = atl1c_pci_tbl,
.probe = atl1c_probe,
.remove = __devexit_p(atl1c_remove),
- /* Power Managment Hooks */
- .suspend = atl1c_suspend,
- .resume = atl1c_resume,
.shutdown = atl1c_shutdown,
- .err_handler = &atl1c_err_handler
+ .err_handler = &atl1c_err_handler,
+ .driver.pm = &atl1c_pm_ops,
};
/*
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index ef6349bf3b33..e28f8baf394e 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1649,7 +1649,7 @@ check_sum:
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
u8 css, cso;
- cso = skb_transport_offset(skb);
+ cso = skb_checksum_start_offset(skb);
if (unlikely(cso & 0x1)) {
netdev_err(adapter->netdev,
"payload offset should not ant event number\n");
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 53363108994e..3b527687c28f 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2174,7 +2174,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
u8 css, cso;
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
- css = (u8) (skb->csum_start - skb_headroom(skb));
+ css = skb_checksum_start_offset(skb);
cso = css + (u8) skb->csum_offset;
if (unlikely(css & 0x1)) {
/* L1 hardware requires an even number here */
@@ -3504,6 +3504,8 @@ static int atl1_set_ringparam(struct net_device *netdev,
struct atl1_rfd_ring rfd_old, rfd_new;
struct atl1_rrd_ring rrd_old, rrd_new;
struct atl1_ring_header rhdr_old, rhdr_new;
+ struct atl1_smb smb;
+ struct atl1_cmb cmb;
int err;
tpd_old = adapter->tpd_ring;
@@ -3544,11 +3546,19 @@ static int atl1_set_ringparam(struct net_device *netdev,
adapter->rrd_ring = rrd_old;
adapter->tpd_ring = tpd_old;
adapter->ring_header = rhdr_old;
+ /*
+ * Save SMB and CMB, since atl1_free_ring_resources
+ * will clear them.
+ */
+ smb = adapter->smb;
+ cmb = adapter->cmb;
atl1_free_ring_resources(adapter);
adapter->rfd_ring = rfd_new;
adapter->rrd_ring = rrd_new;
adapter->tpd_ring = tpd_new;
adapter->ring_header = rhdr_new;
+ adapter->smb = smb;
+ adapter->cmb = cmb;
err = atl1_up(adapter);
if (err)
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 35b14bec1207..4e6f4e95a5a0 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1504,8 +1504,8 @@ static void __devexit atl2_remove(struct pci_dev *pdev)
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_config_timer);
-
- flush_scheduled_work();
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->link_chg_task);
unregister_netdev(netdev);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 53eff9ba6e95..b9debcfb61a0 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -106,8 +106,6 @@ MODULE_VERSION(DRV_VERSION);
* complete immediately.
*/
-struct au1000_private *au_macs[NUM_ETH_INTERFACES];
-
/*
* board-specific configurations
*
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index b6da4cf3694b..4bebff3faeab 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -325,7 +325,7 @@ static void ax_block_output(struct net_device *dev, int count,
static void
ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
unsigned int memr;
@@ -364,7 +364,7 @@ ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
static unsigned int
ax_phy_ei_inbits(struct net_device *dev, int no)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
unsigned int memr;
unsigned int result = 0;
@@ -412,7 +412,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
static int
ax_phy_read(struct net_device *dev, int phy_addr, int reg)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
unsigned int result;
@@ -435,7 +435,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg)
static void
ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
{
- struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei = netdev_priv(dev);
struct ax_device *ax = to_ax_dev(dev);
unsigned long flags;
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c6e86315b3f8..2e2b76258ab4 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
__b44_set_flow_ctrl(bp, pause_enab);
}
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
static void b44_wap54g10_workaround(struct b44 *bp)
{
- const char *str;
+ char buf[20];
u32 val;
int err;
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
* see https://dev.openwrt.org/ticket/146
* check and reset bit "isolate"
*/
- str = nvram_get("boardnum");
- if (!str)
+ if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
return;
- if (simple_strtoul(str, NULL, 0) == 2) {
+ if (simple_strtoul(buf, NULL, 0) == 2) {
err = __b44_readphy(bp, 0, MII_BMCR, &val);
if (err)
goto error;
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index ecfef240a303..e94a966af418 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -1097,7 +1097,7 @@ static int bcm_enet_stop(struct net_device *dev)
enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
/* make sure no mib update is scheduled */
- flush_scheduled_work();
+ cancel_work_sync(&priv->mib_update_task);
/* disable dma & mac */
bcm_enet_disable_dma(priv, priv->tx_chan);
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 4594a28b1f66..add0b93350dd 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -38,14 +38,17 @@
#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
#define OC_NAME "Emulex OneConnect 10Gbps NIC"
-#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)"
+#define OC_NAME_BE OC_NAME "(be3)"
+#define OC_NAME_LANCER OC_NAME "(Lancer)"
#define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver"
#define BE_VENDOR_ID 0x19a2
+#define EMULEX_VENDOR_ID 0x10df
#define BE_DEVICE_ID1 0x211
#define BE_DEVICE_ID2 0x221
-#define OC_DEVICE_ID1 0x700
-#define OC_DEVICE_ID2 0x710
+#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */
+#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
+#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
static inline char *nic_name(struct pci_dev *pdev)
{
@@ -53,7 +56,9 @@ static inline char *nic_name(struct pci_dev *pdev)
case OC_DEVICE_ID1:
return OC_NAME;
case OC_DEVICE_ID2:
- return OC_NAME1;
+ return OC_NAME_BE;
+ case OC_DEVICE_ID3:
+ return OC_NAME_LANCER;
case BE_DEVICE_ID2:
return BE3_NAME;
default:
@@ -149,6 +154,7 @@ struct be_eq_obj {
u16 min_eqd; /* in usecs */
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
+ u8 msix_vec_idx;
struct napi_struct napi;
};
@@ -214,7 +220,9 @@ struct be_rx_obj {
struct be_rx_stats stats;
u8 rss_id;
bool rx_post_starved; /* Zero rx frags have been posted to BE */
- u32 cache_line_barrier[16];
+ u16 last_frag_index;
+ u16 rsvd;
+ u32 cache_line_barrier[15];
};
struct be_vf_cfg {
@@ -234,7 +242,7 @@ struct be_adapter {
u8 __iomem *db; /* Door Bell */
u8 __iomem *pcicfg; /* PCI config space */
- spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */
+ struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
* is stored for freeing purpose */
@@ -260,6 +268,8 @@ struct be_adapter {
u32 num_rx_qs;
u32 big_page_size; /* Compounded page size shared by rx wrbs */
+ u8 msix_vec_next_idx;
+
struct vlan_group *vlan_grp;
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
@@ -299,8 +309,8 @@ struct be_adapter {
bool sriov_enabled;
struct be_vf_cfg vf_cfg[BE_MAX_VF];
- u8 base_eq_id;
u8 is_virtfn;
+ u32 sli_family;
};
#define be_physfn(adapter) (!adapter->is_virtfn)
@@ -309,6 +319,8 @@ struct be_adapter {
#define BE_GEN2 2
#define BE_GEN3 3
+#define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3)
+
extern const struct ethtool_ops be_ethtool_ops;
#define tx_stats(adapter) (&adapter->tx_stats)
@@ -416,10 +428,17 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
{
u8 data;
-
- pci_write_config_byte(adapter->pdev, 0xFE, 0xAA);
- pci_read_config_byte(adapter->pdev, 0xFE, &data);
- adapter->is_virtfn = (data != 0xAA);
+ u32 sli_intf;
+
+ if (lancer_chip(adapter)) {
+ pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET,
+ &sli_intf);
+ adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
+ } else {
+ pci_write_config_byte(adapter->pdev, 0xFE, 0xAA);
+ pci_read_config_byte(adapter->pdev, 0xFE, &data);
+ adapter->is_virtfn = (data != 0xAA);
+ }
}
static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 36eca1ce75d4..0c7811faf72c 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -323,7 +323,12 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
{
- u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
+ u32 sem;
+
+ if (lancer_chip(adapter))
+ sem = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET);
+ else
+ sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
*stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK)
@@ -462,7 +467,8 @@ int be_cmd_fw_init(struct be_adapter *adapter)
u8 *wrb;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = (u8 *)wrb_from_mbox(adapter);
*wrb++ = 0xFF;
@@ -476,7 +482,7 @@ int be_cmd_fw_init(struct be_adapter *adapter)
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -491,7 +497,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
if (adapter->eeh_err)
return -EIO;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = (u8 *)wrb_from_mbox(adapter);
*wrb++ = 0xFF;
@@ -505,7 +512,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
int be_cmd_eq_create(struct be_adapter *adapter,
@@ -516,7 +523,8 @@ int be_cmd_eq_create(struct be_adapter *adapter,
struct be_dma_mem *q_mem = &eq->dma_mem;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -546,7 +554,7 @@ int be_cmd_eq_create(struct be_adapter *adapter,
eq->created = true;
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -558,7 +566,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
struct be_cmd_req_mac_query *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -583,7 +592,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -667,7 +676,8 @@ int be_cmd_cq_create(struct be_adapter *adapter,
void *ctxt;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -680,16 +690,36 @@ int be_cmd_cq_create(struct be_adapter *adapter,
OPCODE_COMMON_CQ_CREATE, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+ if (lancer_chip(adapter)) {
+ req->hdr.version = 1;
+ req->page_size = 1; /* 1 for 4K */
+ AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt,
+ coalesce_wm);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt,
+ no_delay);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt,
+ __ilog2_u32(cq->len/256));
+ AMAP_SET_BITS(struct amap_cq_context_lancer, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, eventable,
+ ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, eqid,
+ ctxt, eq->id);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1);
+ } else {
+ AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
+ coalesce_wm);
+ AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
+ ctxt, no_delay);
+ AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
+ __ilog2_u32(cq->len/256));
+ AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_be, solevent,
+ ctxt, sol_evts);
+ AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
+ AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1);
+ }
- AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
- AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
- AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
- __ilog2_u32(cq->len/256));
- AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
- AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
- 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);
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -701,7 +731,7 @@ int be_cmd_cq_create(struct be_adapter *adapter,
cq->created = true;
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -724,7 +754,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
void *ctxt;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -737,13 +768,27 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+ if (lancer_chip(adapter)) {
+ req->hdr.version = 1;
+ req->cq_id = cpu_to_le16(cq->id);
+
+ AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt,
+ be_encoded_q_len(mccq->len));
+ AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id,
+ ctxt, cq->id);
+ AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid,
+ ctxt, 1);
+
+ } else {
+ AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
+ be_encoded_q_len(mccq->len));
+ AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
+ }
- 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));
- AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
- req->async_event_bitmap[0] |= 0x00000022;
+ req->async_event_bitmap[0] = cpu_to_le32(0x00000022);
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -754,7 +799,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
mccq->id = le16_to_cpu(resp->id);
mccq->created = true;
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -769,7 +814,8 @@ int be_cmd_txq_create(struct be_adapter *adapter,
void *ctxt;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -801,7 +847,7 @@ int be_cmd_txq_create(struct be_adapter *adapter,
txq->created = true;
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -816,7 +862,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_dma_mem *q_mem = &rxq->dma_mem;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -843,7 +890,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
*rss_id = resp->rss_id;
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -862,7 +909,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
if (adapter->eeh_err)
return -EIO;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -899,7 +947,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -915,7 +963,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
struct be_cmd_req_if_create *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -941,7 +990,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
*pmac_id = le32_to_cpu(resp->pmac_id);
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -955,7 +1004,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
if (adapter->eeh_err)
return -EIO;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -970,7 +1020,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -1060,7 +1110,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
struct be_cmd_req_get_fw_version *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -1077,7 +1128,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -1235,7 +1286,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
i = 0;
netdev_for_each_mc_addr(ha, netdev)
- memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
+ memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
} else {
req->promiscuous = 1;
}
@@ -1322,7 +1373,8 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
struct be_cmd_req_query_fw_cfg *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -1341,7 +1393,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
*caps = le32_to_cpu(resp->function_caps);
}
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -1352,7 +1404,8 @@ int be_cmd_reset_function(struct be_adapter *adapter)
struct be_cmd_req_hdr *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -1365,7 +1418,7 @@ int be_cmd_reset_function(struct be_adapter *adapter)
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
@@ -1376,7 +1429,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
u32 myhash[10];
int status;
- spin_lock(&adapter->mbox_lock);
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
wrb = wrb_from_mbox(adapter);
req = embedded_payload(wrb);
@@ -1396,7 +1450,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
status = be_mbox_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ mutex_unlock(&adapter->mbox_lock);
return status;
}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 8469ff061f30..83d15c8a9fa3 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -309,7 +309,7 @@ struct be_cmd_req_pmac_del {
/******************** Create CQ ***************************/
/* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field */
-struct amap_cq_context {
+struct amap_cq_context_be {
u8 cidx[11]; /* dword 0*/
u8 rsvd0; /* dword 0*/
u8 coalescwm[2]; /* dword 0*/
@@ -332,14 +332,32 @@ struct amap_cq_context {
u8 rsvd5[32]; /* dword 3*/
} __packed;
+struct amap_cq_context_lancer {
+ u8 rsvd0[12]; /* dword 0*/
+ u8 coalescwm[2]; /* dword 0*/
+ u8 nodelay; /* dword 0*/
+ u8 rsvd1[12]; /* dword 0*/
+ u8 count[2]; /* dword 0*/
+ u8 valid; /* dword 0*/
+ u8 rsvd2; /* dword 0*/
+ u8 eventable; /* dword 0*/
+ u8 eqid[16]; /* dword 1*/
+ u8 rsvd3[15]; /* dword 1*/
+ u8 armed; /* dword 1*/
+ u8 rsvd4[32]; /* dword 2*/
+ u8 rsvd5[32]; /* dword 3*/
+} __packed;
+
struct be_cmd_req_cq_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
- u16 rsvd0;
- u8 context[sizeof(struct amap_cq_context) / 8];
+ u8 page_size;
+ u8 rsvd0;
+ u8 context[sizeof(struct amap_cq_context_be) / 8];
struct phys_addr pages[8];
} __packed;
+
struct be_cmd_resp_cq_create {
struct be_cmd_resp_hdr hdr;
u16 cq_id;
@@ -349,7 +367,7 @@ struct be_cmd_resp_cq_create {
/******************** Create MCCQ ***************************/
/* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field */
-struct amap_mcc_context {
+struct amap_mcc_context_be {
u8 con_index[14];
u8 rsvd0[2];
u8 ring_size[4];
@@ -364,12 +382,23 @@ struct amap_mcc_context {
u8 rsvd2[32];
} __packed;
+struct amap_mcc_context_lancer {
+ u8 async_cq_id[16];
+ u8 ring_size[4];
+ u8 rsvd0[12];
+ u8 rsvd1[31];
+ u8 valid;
+ u8 async_cq_valid[1];
+ u8 rsvd2[31];
+ u8 rsvd3[32];
+} __packed;
+
struct be_cmd_req_mcc_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
- u16 rsvd0;
+ u16 cq_id;
u32 async_event_bitmap[1];
- u8 context[sizeof(struct amap_mcc_context) / 8];
+ u8 context[sizeof(struct amap_mcc_context_be) / 8];
struct phys_addr pages[8];
} __packed;
@@ -605,6 +634,7 @@ struct be_hw_stats {
struct be_rxf_stats rxf;
u32 rsvd[48];
struct be_erx_stats erx;
+ u32 rsvd1[6];
};
struct be_cmd_req_get_stats {
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 0f46366ecc48..b4be0271efe0 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -549,7 +549,9 @@ be_test_ddr_dma(struct be_adapter *adapter)
{
int ret, i;
struct be_dma_mem ddrdma_cmd;
- u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL};
+ static const 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 a2ec5df0d733..4096d9778234 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -32,10 +32,12 @@
#define MPU_EP_CONTROL 0
/********** MPU semphore ******************/
-#define MPU_EP_SEMAPHORE_OFFSET 0xac
-#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF
-#define EP_SEMAPHORE_POST_ERR_MASK 0x1
-#define EP_SEMAPHORE_POST_ERR_SHIFT 31
+#define MPU_EP_SEMAPHORE_OFFSET 0xac
+#define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400
+#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF
+#define EP_SEMAPHORE_POST_ERR_MASK 0x1
+#define EP_SEMAPHORE_POST_ERR_SHIFT 31
+
/* MPU semphore POST stage values */
#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */
#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */
@@ -66,6 +68,28 @@
#define PCICFG_UE_STATUS_LOW_MASK 0xA8
#define PCICFG_UE_STATUS_HI_MASK 0xAC
+/******** SLI_INTF ***********************/
+#define SLI_INTF_REG_OFFSET 0x58
+#define SLI_INTF_VALID_MASK 0xE0000000
+#define SLI_INTF_VALID 0xC0000000
+#define SLI_INTF_HINT2_MASK 0x1F000000
+#define SLI_INTF_HINT2_SHIFT 24
+#define SLI_INTF_HINT1_MASK 0x00FF0000
+#define SLI_INTF_HINT1_SHIFT 16
+#define SLI_INTF_FAMILY_MASK 0x00000F00
+#define SLI_INTF_FAMILY_SHIFT 8
+#define SLI_INTF_IF_TYPE_MASK 0x0000F000
+#define SLI_INTF_IF_TYPE_SHIFT 12
+#define SLI_INTF_REV_MASK 0x000000F0
+#define SLI_INTF_REV_SHIFT 4
+#define SLI_INTF_FT_MASK 0x00000001
+
+
+/* SLI family */
+#define BE_SLI_FAMILY 0x0
+#define LANCER_A0_SLI_FAMILY 0xA
+
+
/********* ISR0 Register offset **********/
#define CEV_ISR0_OFFSET 0xC18
#define CEV_ISR_SIZE 4
@@ -73,6 +97,9 @@
/********* Event Q door bell *************/
#define DB_EQ_OFFSET DB_CQ_OFFSET
#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
+#define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */
+#define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */
+
/* Clear the interrupt for this eq */
#define DB_EQ_CLR_SHIFT (9) /* bit 9 */
/* Must be 1 */
@@ -85,6 +112,10 @@
/********* Compl Q door bell *************/
#define DB_CQ_OFFSET 0x120
#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
+#define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */
+#define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14
+ placing at 11-15 */
+
/* Number of event entries processed */
#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
/* Rearm bit */
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 93354eee2cfd..de40d3b7152f 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -41,6 +41,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+ { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
{ 0 }
};
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -188,6 +189,8 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid,
{
u32 val = 0;
val |= qid & DB_EQ_RING_ID_MASK;
+ val |= ((qid & DB_EQ_RING_ID_EXT_MASK) <<
+ DB_EQ_RING_ID_EXT_MASK_SHIFT);
if (adapter->eeh_err)
return;
@@ -205,6 +208,8 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
{
u32 val = 0;
val |= qid & DB_CQ_RING_ID_MASK;
+ val |= ((qid & DB_CQ_RING_ID_EXT_MASK) <<
+ DB_CQ_RING_ID_EXT_MASK_SHIFT);
if (adapter->eeh_err)
return;
@@ -404,7 +409,8 @@ static void be_tx_stats_update(struct be_adapter *adapter,
}
/* Determine number of WRB entries needed to xmit data in an skb */
-static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
+static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb,
+ bool *dummy)
{
int cnt = (skb->len > skb->data_len);
@@ -412,12 +418,13 @@ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
/* to account for hdr wrb */
cnt++;
- if (cnt & 1) {
+ if (lancer_chip(adapter) || !(cnt & 1)) {
+ *dummy = false;
+ } else {
/* add a dummy to make it an even num */
cnt++;
*dummy = true;
- } else
- *dummy = false;
+ }
BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
return cnt;
}
@@ -443,8 +450,18 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
hdr, skb_shinfo(skb)->gso_size);
- if (skb_is_gso_v6(skb))
+ if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
+ if (lancer_chip(adapter) && adapter->sli_family ==
+ LANCER_A0_SLI_FAMILY) {
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1);
+ if (is_tcp_pkt(skb))
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb,
+ tcpcs, hdr, 1);
+ else if (is_udp_pkt(skb))
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb,
+ udpcs, hdr, 1);
+ }
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (is_tcp_pkt(skb))
AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
@@ -566,7 +583,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
u32 start = txq->head;
bool dummy_wrb, stopped = false;
- wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb);
+ wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb);
copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb);
if (copied) {
@@ -894,11 +911,17 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
- for (i = 0; i < num_rcvd; i++) {
- page_info = get_rx_page_info(adapter, rxo, rxq_idx);
- put_page(page_info->page);
- memset(page_info, 0, sizeof(*page_info));
- index_inc(&rxq_idx, rxq->len);
+ /* Skip out-of-buffer compl(lancer) or flush compl(BE) */
+ if (likely(rxq_idx != rxo->last_frag_index && num_rcvd != 0)) {
+
+ rxo->last_frag_index = rxq_idx;
+
+ for (i = 0; i < num_rcvd; i++) {
+ page_info = get_rx_page_info(adapter, rxo, rxq_idx);
+ put_page(page_info->page);
+ memset(page_info, 0, sizeof(*page_info));
+ index_inc(&rxq_idx, rxq->len);
+ }
}
}
@@ -999,9 +1022,6 @@ static void be_rx_compl_process(struct be_adapter *adapter,
u8 vtm;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
- /* Is it a flush compl that has no data */
- if (unlikely(num_rcvd == 0))
- return;
skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
if (unlikely(!skb)) {
@@ -1035,7 +1055,8 @@ static void be_rx_compl_process(struct be_adapter *adapter,
return;
}
vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
- vid = swab16(vid);
+ if (!lancer_chip(adapter))
+ vid = swab16(vid);
vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
} else {
netif_receive_skb(skb);
@@ -1057,10 +1078,6 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
u8 pkt_type;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
- /* Is it a flush compl that has no data */
- if (unlikely(num_rcvd == 0))
- return;
-
pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
@@ -1113,7 +1130,8 @@ 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 = swab16(vid);
+ if (!lancer_chip(adapter))
+ vid = swab16(vid);
if (!adapter->vlan_grp || adapter->vlans_added == 0)
return;
@@ -1330,7 +1348,7 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
be_rx_compl_discard(adapter, rxo, rxcp);
be_rx_compl_reset(rxcp);
- be_cq_notify(adapter, rx_cq->id, true, 1);
+ be_cq_notify(adapter, rx_cq->id, false, 1);
}
/* Then free posted rx buffer that were not used */
@@ -1381,7 +1399,8 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
sent_skb = sent_skbs[txq->tail];
end_idx = txq->tail;
index_adv(&end_idx,
- wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len);
+ wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
+ txq->len);
be_tx_compl_process(adapter, end_idx);
}
}
@@ -1476,7 +1495,9 @@ static int be_tx_queues_create(struct be_adapter *adapter)
/* Ask BE to create Tx Event queue */
if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
goto tx_eq_free;
- adapter->base_eq_id = adapter->tx_eq.q.id;
+
+ adapter->tx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
+
/* Alloc TX eth compl queue */
cq = &adapter->tx_obj.cq;
@@ -1554,6 +1575,9 @@ static int be_rx_queues_create(struct be_adapter *adapter)
adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
for_all_rx_queues(adapter, rxo, i) {
rxo->adapter = adapter;
+ /* Init last_frag_index so that the frag index in the first
+ * completion will never match */
+ rxo->last_frag_index = 0xffff;
rxo->rx_eq.max_eqd = BE_MAX_EQD;
rxo->rx_eq.enable_aic = true;
@@ -1568,6 +1592,8 @@ static int be_rx_queues_create(struct be_adapter *adapter)
if (rc)
goto err;
+ rxo->rx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
+
/* CQ */
cq = &rxo->cq;
rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
@@ -1578,7 +1604,6 @@ static int be_rx_queues_create(struct be_adapter *adapter)
rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
if (rc)
goto err;
-
/* Rx Q */
q = &rxo->q;
rc = be_queue_alloc(adapter, q, RX_Q_LEN,
@@ -1611,29 +1636,45 @@ err:
return -1;
}
-/* 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)
+static bool event_peek(struct be_eq_obj *eq_obj)
{
- return eq_id - adapter->base_eq_id;
+ struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
+ if (!eqe->evt)
+ return false;
+ else
+ return true;
}
static irqreturn_t be_intx(int irq, void *dev)
{
struct be_adapter *adapter = dev;
struct be_rx_obj *rxo;
- int isr, i;
+ int isr, i, tx = 0 , rx = 0;
- isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
- (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE);
- if (!isr)
- return IRQ_NONE;
+ if (lancer_chip(adapter)) {
+ if (event_peek(&adapter->tx_eq))
+ tx = event_handle(adapter, &adapter->tx_eq);
+ for_all_rx_queues(adapter, rxo, i) {
+ if (event_peek(&rxo->rx_eq))
+ rx |= event_handle(adapter, &rxo->rx_eq);
+ }
- if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr))
- event_handle(adapter, &adapter->tx_eq);
+ if (!(tx || rx))
+ return IRQ_NONE;
- for_all_rx_queues(adapter, rxo, i) {
- if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr))
- event_handle(adapter, &rxo->rx_eq);
+ } else {
+ isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
+ (adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE);
+ if (!isr)
+ return IRQ_NONE;
+
+ if ((1 << adapter->tx_eq.msix_vec_idx & isr))
+ event_handle(adapter, &adapter->tx_eq);
+
+ for_all_rx_queues(adapter, rxo, i) {
+ if ((1 << rxo->rx_eq.msix_vec_idx & isr))
+ event_handle(adapter, &rxo->rx_eq);
+ }
}
return IRQ_HANDLED;
@@ -1658,10 +1699,9 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
return IRQ_HANDLED;
}
-static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo,
- struct be_eth_rx_compl *rxcp)
+static inline bool do_gro(struct be_rx_obj *rxo,
+ struct be_eth_rx_compl *rxcp, u8 err)
{
- int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
if (err)
@@ -1678,6 +1718,8 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
struct be_queue_info *rx_cq = &rxo->cq;
struct be_eth_rx_compl *rxcp;
u32 work_done;
+ u16 frag_index, num_rcvd;
+ u8 err;
rxo->stats.rx_polls++;
for (work_done = 0; work_done < budget; work_done++) {
@@ -1685,10 +1727,22 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
if (!rxcp)
break;
- if (do_gro(adapter, rxo, rxcp))
- be_rx_compl_process_gro(adapter, rxo, rxcp);
- else
- be_rx_compl_process(adapter, rxo, rxcp);
+ err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
+ frag_index = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx,
+ rxcp);
+ num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags,
+ rxcp);
+
+ /* Skip out-of-buffer compl(lancer) or flush compl(BE) */
+ if (likely(frag_index != rxo->last_frag_index &&
+ num_rcvd != 0)) {
+ rxo->last_frag_index = frag_index;
+
+ if (do_gro(rxo, rxcp, err))
+ be_rx_compl_process_gro(adapter, rxo, rxcp);
+ else
+ be_rx_compl_process(adapter, rxo, rxcp);
+ }
be_rx_compl_reset(rxcp);
}
@@ -1830,8 +1884,7 @@ static void be_worker(struct work_struct *work)
be_post_rx_frags(rxo);
}
}
-
- if (!adapter->ue_detected)
+ if (!adapter->ue_detected && !lancer_chip(adapter))
be_detect_dump_ue(adapter);
reschedule:
@@ -1910,10 +1963,10 @@ static void be_sriov_disable(struct be_adapter *adapter)
#endif
}
-static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
+static inline int be_msix_vec_get(struct be_adapter *adapter,
+ struct be_eq_obj *eq_obj)
{
- return adapter->msix_entries[
- be_evt_bit_get(adapter, eq_id)].vector;
+ return adapter->msix_entries[eq_obj->msix_vec_idx].vector;
}
static int be_request_irq(struct be_adapter *adapter,
@@ -1924,14 +1977,14 @@ static int be_request_irq(struct be_adapter *adapter,
int vec;
sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
- vec = be_msix_vec_get(adapter, eq_obj->q.id);
+ vec = be_msix_vec_get(adapter, eq_obj);
return request_irq(vec, handler, 0, eq_obj->desc, context);
}
static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj,
void *context)
{
- int vec = be_msix_vec_get(adapter, eq_obj->q.id);
+ int vec = be_msix_vec_get(adapter, eq_obj);
free_irq(vec, context);
}
@@ -2036,14 +2089,15 @@ static int be_close(struct net_device *netdev)
netif_carrier_off(netdev);
adapter->link_up = false;
- be_intr_set(adapter, false);
+ if (!lancer_chip(adapter))
+ be_intr_set(adapter, false);
if (adapter->msix_enabled) {
- vec = be_msix_vec_get(adapter, tx_eq->q.id);
+ vec = be_msix_vec_get(adapter, tx_eq);
synchronize_irq(vec);
for_all_rx_queues(adapter, rxo, i) {
- vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id);
+ vec = be_msix_vec_get(adapter, &rxo->rx_eq);
synchronize_irq(vec);
}
} else {
@@ -2082,7 +2136,8 @@ static int be_open(struct net_device *netdev)
be_irq_register(adapter);
- be_intr_set(adapter, true);
+ if (!lancer_chip(adapter))
+ be_intr_set(adapter, true);
/* The evt queues are created in unarmed state; arm them */
for_all_rx_queues(adapter, rxo, i) {
@@ -2343,10 +2398,10 @@ static int be_flash_data(struct be_adapter *adapter,
int num_bytes;
const u8 *p = fw->data;
struct be_cmd_write_flashrom *req = flash_cmd->va;
- struct flash_comp *pflashcomp;
+ const struct flash_comp *pflashcomp;
int num_comp;
- struct flash_comp gen3_flash_types[9] = {
+ static const 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,
@@ -2366,7 +2421,7 @@ static int be_flash_data(struct be_adapter *adapter,
{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
FLASH_NCSI_IMAGE_MAX_SIZE_g3}
};
- struct flash_comp gen2_flash_types[8] = {
+ static const struct flash_comp gen2_flash_types[8] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g2},
{ FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
@@ -2388,11 +2443,11 @@ 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;
+ num_comp = ARRAY_SIZE(gen3_flash_types);
} else {
pflashcomp = gen2_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g2);
- num_comp = 8;
+ num_comp = ARRAY_SIZE(gen2_flash_types);
}
for (i = 0; i < num_comp; i++) {
if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
@@ -2543,10 +2598,15 @@ static void be_netdev_init(struct net_device *netdev)
int i;
netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_GRO | NETIF_F_TSO6;
- netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ if (lancer_chip(adapter))
+ netdev->vlan_features |= NETIF_F_TSO6;
netdev->flags |= IFF_MULTICAST;
@@ -2587,6 +2647,15 @@ static int be_map_pci_bars(struct be_adapter *adapter)
u8 __iomem *addr;
int pcicfg_reg, db_reg;
+ if (lancer_chip(adapter)) {
+ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0),
+ pci_resource_len(adapter->pdev, 0));
+ if (addr == NULL)
+ return -ENOMEM;
+ adapter->db = addr;
+ return 0;
+ }
+
if (be_physfn(adapter)) {
addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
pci_resource_len(adapter->pdev, 2));
@@ -2677,7 +2746,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
}
memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
- spin_lock_init(&adapter->mbox_lock);
+ mutex_init(&adapter->mbox_lock);
spin_lock_init(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_cq_lock);
@@ -2783,6 +2852,44 @@ static int be_get_config(struct be_adapter *adapter)
return 0;
}
+static int be_dev_family_check(struct be_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ u32 sli_intf = 0, if_type;
+
+ switch (pdev->device) {
+ case BE_DEVICE_ID1:
+ case OC_DEVICE_ID1:
+ adapter->generation = BE_GEN2;
+ break;
+ case BE_DEVICE_ID2:
+ case OC_DEVICE_ID2:
+ adapter->generation = BE_GEN3;
+ break;
+ case OC_DEVICE_ID3:
+ pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+ if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
+ SLI_INTF_IF_TYPE_SHIFT;
+
+ if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
+ if_type != 0x02) {
+ dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
+ return -EINVAL;
+ }
+ if (num_vfs > 0) {
+ dev_err(&pdev->dev, "VFs not supported\n");
+ return -EINVAL;
+ }
+ adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
+ SLI_INTF_FAMILY_SHIFT);
+ adapter->generation = BE_GEN3;
+ break;
+ default:
+ adapter->generation = 0;
+ }
+ return 0;
+}
+
static int __devinit be_probe(struct pci_dev *pdev,
const struct pci_device_id *pdev_id)
{
@@ -2805,22 +2912,13 @@ static int __devinit be_probe(struct pci_dev *pdev,
goto rel_reg;
}
adapter = netdev_priv(netdev);
-
- switch (pdev->device) {
- case BE_DEVICE_ID1:
- case OC_DEVICE_ID1:
- adapter->generation = BE_GEN2;
- break;
- case BE_DEVICE_ID2:
- case OC_DEVICE_ID2:
- adapter->generation = BE_GEN3;
- break;
- default:
- adapter->generation = 0;
- }
-
adapter->pdev = pdev;
pci_set_drvdata(pdev, adapter);
+
+ status = be_dev_family_check(adapter);
+ if (status)
+ goto free_netdev;
+
adapter->netdev = netdev;
SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -2895,7 +2993,7 @@ ctrl_clean:
be_ctrl_cleanup(adapter);
free_netdev:
be_sriov_disable(adapter);
- free_netdev(adapter->netdev);
+ free_netdev(netdev);
pci_set_drvdata(pdev, NULL);
rel_reg:
pci_release_regions(pdev);
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index 29c1b8de2c2d..2ea0dfe1cedc 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -112,16 +112,18 @@ struct bfa_ioc_pci_attr {
* IOC states
*/
enum bfa_ioc_state {
- BFA_IOC_RESET = 1, /*!< IOC is in reset state */
- BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */
- BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */
- BFA_IOC_GETATTR = 4, /*!< IOC is being configured */
- BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */
- BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */
- BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */
- BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */
- BFA_IOC_DISABLED = 9, /*!< IOC is disabled */
- BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */
+ BFA_IOC_UNINIT = 1, /*!< IOC is in uninit state */
+ BFA_IOC_RESET = 2, /*!< IOC is in reset state */
+ BFA_IOC_SEMWAIT = 3, /*!< Waiting for IOC h/w semaphore */
+ BFA_IOC_HWINIT = 4, /*!< IOC h/w is being initialized */
+ BFA_IOC_GETATTR = 5, /*!< IOC is being configured */
+ BFA_IOC_OPERATIONAL = 6, /*!< IOC is operational */
+ BFA_IOC_INITFAIL = 7, /*!< IOC hardware failure */
+ BFA_IOC_FAIL = 8, /*!< IOC heart-beat failure */
+ BFA_IOC_DISABLING = 9, /*!< IOC is being disabled */
+ BFA_IOC_DISABLED = 10, /*!< IOC is disabled */
+ BFA_IOC_FWMISMATCH = 11, /*!< IOC f/w different from drivers */
+ BFA_IOC_ENABLING = 12, /*!< IOC is being enabled */
};
/**
diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h
index 987978fcb3fe..fdd677618361 100644
--- a/drivers/net/bna/bfa_defs_mfg_comm.h
+++ b/drivers/net/bna/bfa_defs_mfg_comm.h
@@ -95,28 +95,6 @@ enum {
(type) == BFA_MFG_TYPE_CNA10P1 || \
bfa_mfg_is_mezz(type)))
-/**
- * Check if the card having old wwn/mac handling
- */
-#define bfa_mfg_is_old_wwn_mac_model(type) (( \
- (type) == BFA_MFG_TYPE_FC8P2 || \
- (type) == BFA_MFG_TYPE_FC8P1 || \
- (type) == BFA_MFG_TYPE_FC4P2 || \
- (type) == BFA_MFG_TYPE_FC4P1 || \
- (type) == BFA_MFG_TYPE_CNA10P2 || \
- (type) == BFA_MFG_TYPE_CNA10P1 || \
- (type) == BFA_MFG_TYPE_JAYHAWK || \
- (type) == BFA_MFG_TYPE_WANCHESE))
-
-#define bfa_mfg_increment_wwn_mac(m, i) \
-do { \
- u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \
- t += (i); \
- (m)[0] = (t >> 16) & 0xFF; \
- (m)[1] = (t >> 8) & 0xFF; \
- (m)[2] = t & 0xFF; \
-} while (0)
-
#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \
do { \
switch ((card_type)) { \
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index e94e5aa97515..34933cb9569f 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -26,25 +26,6 @@
* IOC local definitions
*/
-#define bfa_ioc_timer_start(__ioc) \
- mod_timer(&(__ioc)->ioc_timer, jiffies + \
- msecs_to_jiffies(BFA_IOC_TOV))
-#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer)
-
-#define bfa_ioc_recovery_timer_start(__ioc) \
- mod_timer(&(__ioc)->ioc_timer, jiffies + \
- msecs_to_jiffies(BFA_IOC_TOV_RECOVER))
-
-#define bfa_sem_timer_start(__ioc) \
- mod_timer(&(__ioc)->sem_timer, jiffies + \
- msecs_to_jiffies(BFA_IOC_HWSEM_TOV))
-#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer)
-
-#define bfa_hb_timer_start(__ioc) \
- mod_timer(&(__ioc)->hb_timer, jiffies + \
- msecs_to_jiffies(BFA_IOC_HB_TOV))
-#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer)
-
/**
* Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
*/
@@ -55,11 +36,16 @@
((__ioc)->ioc_hwif->ioc_firmware_unlock(__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))
-
-#define bfa_ioc_is_optrom(__ioc) \
- (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
+#define bfa_ioc_notify_fail(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
+#define bfa_ioc_sync_join(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
+#define bfa_ioc_sync_leave(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
+#define bfa_ioc_sync_ack(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
+#define bfa_ioc_sync_complete(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
#define bfa_ioc_mbox_cmd_pending(__ioc) \
(!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
@@ -85,6 +71,12 @@ static void bfa_ioc_recover(struct bfa_ioc *ioc);
static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
+static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_initfailed(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_param);
static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
@@ -101,72 +93,173 @@ static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc,
char *manufacturer);
static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model);
static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc);
-static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc);
/**
- * IOC state machine events
+ * IOC state machine definitions/declarations
*/
enum ioc_event {
- IOC_E_ENABLE = 1, /*!< IOC enable request */
- IOC_E_DISABLE = 2, /*!< IOC disable request */
- IOC_E_TIMEOUT = 3, /*!< f/w response timeout */
- IOC_E_FWREADY = 4, /*!< f/w initialization done */
- IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */
- IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */
- IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */
- IOC_E_HBFAIL = 8, /*!< heartbeat failure */
- IOC_E_HWERROR = 9, /*!< hardware error interrupt */
- IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */
- IOC_E_DETACH = 11, /*!< driver detach cleanup */
+ IOC_E_RESET = 1, /*!< IOC reset request */
+ IOC_E_ENABLE = 2, /*!< IOC enable request */
+ IOC_E_DISABLE = 3, /*!< IOC disable request */
+ IOC_E_DETACH = 4, /*!< driver detach cleanup */
+ IOC_E_ENABLED = 5, /*!< f/w enabled */
+ IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */
+ IOC_E_DISABLED = 7, /*!< f/w disabled */
+ IOC_E_INITFAILED = 8, /*!< failure notice by iocpf sm */
+ IOC_E_PFAILED = 9, /*!< failure notice by iocpf sm */
+ IOC_E_HBFAIL = 10, /*!< heartbeat failure */
+ IOC_E_HWERROR = 11, /*!< hardware error interrupt */
+ IOC_E_TIMEOUT = 12, /*!< timeout */
};
+bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
static struct bfa_sm_table ioc_sm_table[] = {
+ {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
{BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
- {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
- {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
- {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
- {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
- {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
{BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
{BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
- {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
- {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
+ {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
+ {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
{BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
{BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
};
/**
+ * IOCPF state machine definitions/declarations
+ */
+
+/*
+ * Forward declareations for iocpf state machine
+ */
+static void bfa_iocpf_enable(struct bfa_ioc *ioc);
+static void bfa_iocpf_disable(struct bfa_ioc *ioc);
+static void bfa_iocpf_fail(struct bfa_ioc *ioc);
+static void bfa_iocpf_initfail(struct bfa_ioc *ioc);
+static void bfa_iocpf_getattrfail(struct bfa_ioc *ioc);
+static void bfa_iocpf_stop(struct bfa_ioc *ioc);
+
+/**
+ * IOCPF state machine events
+ */
+enum iocpf_event {
+ IOCPF_E_ENABLE = 1, /*!< IOCPF enable request */
+ IOCPF_E_DISABLE = 2, /*!< IOCPF disable request */
+ IOCPF_E_STOP = 3, /*!< stop on driver detach */
+ IOCPF_E_FWREADY = 4, /*!< f/w initialization done */
+ IOCPF_E_FWRSP_ENABLE = 5, /*!< enable f/w response */
+ IOCPF_E_FWRSP_DISABLE = 6, /*!< disable f/w response */
+ IOCPF_E_FAIL = 7, /*!< failure notice by ioc sm */
+ IOCPF_E_INITFAIL = 8, /*!< init fail notice by ioc sm */
+ IOCPF_E_GETATTRFAIL = 9, /*!< init fail notice by ioc sm */
+ IOCPF_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */
+ IOCPF_E_TIMEOUT = 11, /*!< f/w response timeout */
+};
+
+/**
+ * IOCPF states
+ */
+enum bfa_iocpf_state {
+ BFA_IOCPF_RESET = 1, /*!< IOC is in reset state */
+ BFA_IOCPF_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */
+ BFA_IOCPF_HWINIT = 3, /*!< IOC h/w is being initialized */
+ BFA_IOCPF_READY = 4, /*!< IOCPF is initialized */
+ BFA_IOCPF_INITFAIL = 5, /*!< IOCPF failed */
+ BFA_IOCPF_FAIL = 6, /*!< IOCPF failed */
+ BFA_IOCPF_DISABLING = 7, /*!< IOCPF is being disabled */
+ BFA_IOCPF_DISABLED = 8, /*!< IOCPF is disabled */
+ BFA_IOCPF_FWMISMATCH = 9, /*!< IOC f/w different from drivers */
+};
+
+bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf,
+ enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf,
+ enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event);
+
+static struct bfa_sm_table iocpf_sm_table[] = {
+ {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
+ {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
+ {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
+ {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
+ {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
+ {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
+ {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
+ {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
+ {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
+ {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
+ {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
+ {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
+ {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
+ {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
+};
+
+/**
+ * IOC State Machine
+ */
+
+/**
+ * Beginning state. IOC uninit state.
+ */
+static void
+bfa_ioc_sm_uninit_entry(struct bfa_ioc *ioc)
+{
+}
+
+/**
+ * IOC is in uninit state.
+ */
+static void
+bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_RESET:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
* Reset entry actions -- initialize state machine
*/
static void
bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc)
{
- ioc->retry_count = 0;
- ioc->auto_recover = bfa_nw_auto_recover;
+ bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
}
/**
- * Beginning state. IOC is in reset state.
+ * IOC is in reset state.
*/
static void
bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
case IOC_E_ENABLE:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
break;
case IOC_E_DISABLE:
@@ -174,6 +267,7 @@ bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
break;
case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
break;
default:
@@ -181,42 +275,43 @@ bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
}
}
-/**
- * Semaphore should be acquired for version check.
- */
static void
-bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc)
+bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc)
{
- bfa_ioc_hw_sem_get(ioc);
+ bfa_iocpf_enable(ioc);
}
/**
- * Awaiting h/w semaphore to continue with version check.
+ * Host IOC function is being enabled, awaiting response from firmware.
+ * Semaphore is acquired.
*/
static void
-bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
- case IOC_E_SEMLOCKED:
- if (bfa_ioc_firmware_lock(ioc)) {
- ioc->retry_count = 0;
- bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
- } else {
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
- }
+ case IOC_E_ENABLED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
+ break;
+
+ case IOC_E_PFAILED:
+ /* !!! fall through !!! */
+ case IOC_E_HWERROR:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ if (event != IOC_E_PFAILED)
+ bfa_iocpf_initfail(ioc);
break;
case IOC_E_DISABLE:
- bfa_ioc_disable_comp(ioc);
- /* fall through */
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
case IOC_E_DETACH:
- bfa_ioc_hw_sem_get_cancel(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_iocpf_stop(ioc);
break;
- case IOC_E_FWREADY:
+ case IOC_E_ENABLE:
break;
default:
@@ -225,41 +320,85 @@ bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event)
}
/**
- * Notify enable completion callback and generate mismatch AEN.
+ * Semaphore should be acquired for version check.
*/
static void
-bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc)
+bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc)
{
- /**
- * Provide enable completion callback and AEN notification only once.
- */
- if (ioc->retry_count == 0)
- ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
- ioc->retry_count++;
- bfa_ioc_timer_start(ioc);
+ mod_timer(&ioc->ioc_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV));
+ bfa_ioc_send_getattr(ioc);
}
/**
- * Awaiting firmware version match.
+ * IOC configuration in progress. Timer is active.
*/
static void
-bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
+ case IOC_E_FWRSP_GETATTR:
+ del_timer(&ioc->ioc_timer);
+ bfa_ioc_check_attr_wwns(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ break;
+
+ case IOC_E_PFAILED:
+ case IOC_E_HWERROR:
+ del_timer(&ioc->ioc_timer);
+ /* fall through */
case IOC_E_TIMEOUT:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ if (event != IOC_E_PFAILED)
+ bfa_iocpf_getattrfail(ioc);
break;
case IOC_E_DISABLE:
- bfa_ioc_disable_comp(ioc);
- /* fall through */
+ del_timer(&ioc->ioc_timer);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
- case IOC_E_DETACH:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ case IOC_E_ENABLE:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
+ bfa_ioc_hb_monitor(ioc);
+}
+
+static void
+bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hb_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
- case IOC_E_FWREADY:
+ case IOC_E_PFAILED:
+ case IOC_E_HWERROR:
+ bfa_ioc_hb_stop(ioc);
+ /* !!! fall through !!! */
+ case IOC_E_HBFAIL:
+ bfa_ioc_fail_notify(ioc);
+ if (ioc->iocpf.auto_recover)
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ else
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+
+ if (event != IOC_E_PFAILED)
+ bfa_iocpf_fail(ioc);
break;
default:
@@ -267,30 +406,61 @@ bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event)
}
}
+static void
+bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc)
+{
+ bfa_iocpf_disable(ioc);
+}
+
/**
- * Request for semaphore.
+ * IOC is being desabled
*/
static void
-bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc)
+bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
{
- bfa_ioc_hw_sem_get(ioc);
+ switch (event) {
+ case IOC_E_DISABLED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_HWERROR:
+ /*
+ * No state change. Will move to disabled state
+ * after iocpf sm completes failure processing and
+ * moves to disabled state.
+ */
+ bfa_iocpf_fail(ioc);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
}
/**
- * Awaiting semaphore for h/w initialzation.
+ * IOC desable completion entry.
*/
static void
-bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_disable_comp(ioc);
+}
+
+static void
+bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
- case IOC_E_SEMLOCKED:
- ioc->retry_count = 0;
- bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
break;
case IOC_E_DISABLE:
- bfa_ioc_hw_sem_get_cancel(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_iocpf_stop(ioc);
break;
default:
@@ -299,46 +469,45 @@ bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc)
+bfa_ioc_sm_fail_retry_entry(struct bfa_ioc *ioc)
{
- bfa_ioc_timer_start(ioc);
- bfa_ioc_reset(ioc, false);
}
/**
- * @brief
- * Hardware is being initialized. Interrupts are enabled.
- * Holding hardware semaphore lock.
+ * Hardware initialization retry.
*/
static void
-bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
- case IOC_E_FWREADY:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
+ case IOC_E_ENABLED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
break;
+ case IOC_E_PFAILED:
case IOC_E_HWERROR:
- bfa_ioc_timer_stop(ioc);
- /* fall through */
+ /**
+ * Initialization retry failed.
+ */
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ if (event != IOC_E_PFAILED)
+ bfa_iocpf_initfail(ioc);
+ break;
- case IOC_E_TIMEOUT:
- ioc->retry_count++;
- if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
- bfa_ioc_timer_start(ioc);
- bfa_ioc_reset(ioc, true);
- break;
- }
+ case IOC_E_INITFAILED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+ break;
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ case IOC_E_ENABLE:
break;
case IOC_E_DISABLE:
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_iocpf_stop(ioc);
break;
default:
@@ -347,51 +516,248 @@ bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc)
+bfa_ioc_sm_fail_entry(struct bfa_ioc *ioc)
{
- bfa_ioc_timer_start(ioc);
- bfa_ioc_send_enable(ioc);
}
/**
- * Host IOC function is being enabled, awaiting response from firmware.
- * Semaphore is acquired.
+ * IOC failure.
*/
static void
-bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
- case IOC_E_FWRSP_ENABLE:
- bfa_ioc_timer_stop(ioc);
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
+ case IOC_E_ENABLE:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_iocpf_stop(ioc);
break;
case IOC_E_HWERROR:
- bfa_ioc_timer_stop(ioc);
- /* fall through */
+ /* HB failure notification, ignore. */
+ break;
- case IOC_E_TIMEOUT:
- ioc->retry_count++;
- if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
- writel(BFI_IOC_UNINIT,
- ioc->ioc_regs.ioc_fwstate);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
- break;
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * IOCPF State Machine
+ */
+
+/**
+ * Reset entry actions -- initialize state machine
+ */
+static void
+bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf)
+{
+ iocpf->retry_count = 0;
+ iocpf->auto_recover = bfa_nw_auto_recover;
+}
+
+/**
+ * Beginning state. IOC is in reset state.
+ */
+static void
+bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ switch (event) {
+ case IOCPF_E_ENABLE:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
+ break;
+
+ case IOCPF_E_STOP:
+ break;
+
+ default:
+ bfa_sm_fault(iocpf->ioc, event);
+ }
+}
+
+/**
+ * Semaphore should be acquired for version check.
+ */
+static void
+bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf)
+{
+ bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/**
+ * Awaiting h/w semaphore to continue with version check.
+ */
+static void
+bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ if (bfa_ioc_firmware_lock(ioc)) {
+ if (bfa_ioc_sync_complete(ioc)) {
+ iocpf->retry_count = 0;
+ bfa_ioc_sync_join(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ } else {
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ mod_timer(&ioc->sem_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
+ }
+ } else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
}
+ break;
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ case IOCPF_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ bfa_ioc_pf_disabled(ioc);
break;
- case IOC_E_DISABLE:
- bfa_ioc_timer_stop(ioc);
+ case IOCPF_E_STOP:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Notify enable completion callback
+ */
+static void
+bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
+{
+ /* Call only the first time sm enters fwmismatch state. */
+ if (iocpf->retry_count == 0)
+ bfa_ioc_pf_fwmismatch(iocpf->ioc);
+
+ iocpf->retry_count++;
+ mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV));
+}
+
+/**
+ * Awaiting firmware version match.
+ */
+static void
+bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
+ switch (event) {
+ case IOCPF_E_TIMEOUT:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
+ break;
+
+ case IOCPF_E_DISABLE:
+ del_timer(&ioc->iocpf_timer);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ bfa_ioc_pf_disabled(ioc);
+ break;
+
+ case IOCPF_E_STOP:
+ del_timer(&ioc->iocpf_timer);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Request for semaphore.
+ */
+static void
+bfa_iocpf_sm_semwait_entry(struct bfa_iocpf *iocpf)
+{
+ bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/**
+ * Awaiting semaphore for h/w initialzation.
+ */
+static void
+bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ if (bfa_ioc_sync_complete(ioc)) {
+ bfa_ioc_sync_join(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ } else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ mod_timer(&ioc->sem_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
+ }
+ break;
+
+ case IOCPF_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf)
+{
+ mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV));
+ bfa_ioc_reset(iocpf->ioc, 0);
+}
+
+/**
+ * Hardware is being initialized. Interrupts are enabled.
+ * Holding hardware semaphore lock.
+ */
+static void
+bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
+ switch (event) {
+ case IOCPF_E_FWREADY:
+ del_timer(&ioc->iocpf_timer);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
+ break;
+
+ case IOCPF_E_INITFAIL:
+ del_timer(&ioc->iocpf_timer);
+ /*
+ * !!! fall through !!!
+ */
+
+ case IOCPF_E_TIMEOUT:
bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ if (event == IOCPF_E_TIMEOUT)
+ bfa_ioc_pf_failed(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
- case IOC_E_FWREADY:
- bfa_ioc_send_enable(ioc);
+ case IOCPF_E_DISABLE:
+ del_timer(&ioc->iocpf_timer);
+ bfa_ioc_sync_leave(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
default:
@@ -400,37 +766,49 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
{
- bfa_ioc_timer_start(ioc);
- bfa_ioc_send_getattr(ioc);
+ mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV));
+ bfa_ioc_send_enable(iocpf->ioc);
}
/**
- * @brief
- * IOC configuration in progress. Timer is active.
+ * Host IOC function is being enabled, awaiting response from firmware.
+ * Semaphore is acquired.
*/
static void
-bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
switch (event) {
- case IOC_E_FWRSP_GETATTR:
- bfa_ioc_timer_stop(ioc);
- bfa_ioc_check_attr_wwns(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ case IOCPF_E_FWRSP_ENABLE:
+ del_timer(&ioc->iocpf_timer);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
break;
- case IOC_E_HWERROR:
- bfa_ioc_timer_stop(ioc);
- /* fall through */
+ case IOCPF_E_INITFAIL:
+ del_timer(&ioc->iocpf_timer);
+ /*
+ * !!! fall through !!!
+ */
+ case IOCPF_E_TIMEOUT:
+ bfa_nw_ioc_hw_sem_release(ioc);
+ if (event == IOCPF_E_TIMEOUT)
+ bfa_ioc_pf_failed(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
+ break;
- case IOC_E_TIMEOUT:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ case IOCPF_E_DISABLE:
+ del_timer(&ioc->iocpf_timer);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
- case IOC_E_DISABLE:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ case IOCPF_E_FWREADY:
+ bfa_ioc_send_enable(ioc);
break;
default:
@@ -438,36 +816,42 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
}
}
+static bool
+bfa_nw_ioc_is_operational(struct bfa_ioc *ioc)
+{
+ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
+}
+
static void
-bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
{
- ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
- bfa_ioc_hb_monitor(ioc);
+ bfa_ioc_pf_enabled(iocpf->ioc);
}
static void
-bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
switch (event) {
- case IOC_E_ENABLE:
+ case IOCPF_E_DISABLE:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
- case IOC_E_DISABLE:
- bfa_ioc_hb_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ case IOCPF_E_GETATTRFAIL:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
- case IOC_E_HWERROR:
- case IOC_E_FWREADY:
- /**
- * Hard error or IOC recovery by other function.
- * Treat it same as heartbeat failure.
- */
- bfa_ioc_hb_stop(ioc);
- /* !!! fall through !!! */
+ case IOCPF_E_FAIL:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
+ break;
- case IOC_E_HBFAIL:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
+ case IOCPF_E_FWREADY:
+ bfa_ioc_pf_failed(ioc);
+ if (bfa_nw_ioc_is_operational(ioc))
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
+ else
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
default:
@@ -476,33 +860,40 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf)
{
- bfa_ioc_timer_start(ioc);
- bfa_ioc_send_disable(ioc);
+ mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV));
+ bfa_ioc_send_disable(iocpf->ioc);
}
/**
* IOC is being disabled
*/
static void
-bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
switch (event) {
- case IOC_E_FWRSP_DISABLE:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ case IOCPF_E_FWRSP_DISABLE:
+ case IOCPF_E_FWREADY:
+ del_timer(&ioc->iocpf_timer);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
- case IOC_E_HWERROR:
- bfa_ioc_timer_stop(ioc);
+ case IOCPF_E_FAIL:
+ del_timer(&ioc->iocpf_timer);
/*
* !!! fall through !!!
*/
- case IOC_E_TIMEOUT:
+ case IOCPF_E_TIMEOUT:
writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+ break;
+
+ case IOCPF_E_FWRSP_ENABLE:
break;
default:
@@ -510,33 +901,58 @@ bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
}
}
-/**
- * IOC disable completion entry.
- */
static void
-bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf *iocpf)
{
- bfa_ioc_disable_comp(ioc);
+ bfa_ioc_hw_sem_get(iocpf->ioc);
}
+/**
+ * IOC hb ack request is being removed.
+ */
static void
-bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
switch (event) {
- case IOC_E_ENABLE:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ case IOCPF_E_SEMLOCKED:
+ bfa_ioc_sync_leave(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
- case IOC_E_DISABLE:
- ioc->cbfn->disable_cbfn(ioc->bfa);
+ case IOCPF_E_FAIL:
break;
- case IOC_E_FWREADY:
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * IOC disable completion entry.
+ */
+static void
+bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf)
+{
+ bfa_ioc_pf_disabled(iocpf->ioc);
+}
+
+static void
+bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
+ switch (event) {
+ case IOCPF_E_ENABLE:
+ iocpf->retry_count = 0;
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
break;
- case IOC_E_DETACH:
+ case IOCPF_E_STOP:
bfa_ioc_firmware_unlock(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
default:
@@ -545,33 +961,50 @@ bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf *iocpf)
{
- ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
- bfa_ioc_timer_start(ioc);
+ bfa_ioc_hw_sem_get(iocpf->ioc);
}
/**
- * @brief
* Hardware initialization failed.
*/
static void
-bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
+ struct bfa_ioc *ioc = iocpf->ioc;
+
switch (event) {
- case IOC_E_DISABLE:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ case IOCPF_E_SEMLOCKED:
+ bfa_ioc_notify_fail(ioc);
+ bfa_ioc_sync_ack(ioc);
+ iocpf->retry_count++;
+ if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
+ bfa_ioc_sync_leave(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+ } else {
+ if (bfa_ioc_sync_complete(ioc))
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+ }
+ }
break;
- case IOC_E_DETACH:
- bfa_ioc_timer_stop(ioc);
+ case IOCPF_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+ break;
+
+ case IOCPF_E_STOP:
+ bfa_ioc_hw_sem_get_cancel(ioc);
bfa_ioc_firmware_unlock(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
- case IOC_E_TIMEOUT:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ case IOCPF_E_FAIL:
break;
default:
@@ -580,80 +1013,108 @@ bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event)
}
static void
-bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc)
+bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf)
{
- struct list_head *qe;
- struct bfa_ioc_hbfail_notify *notify;
+ bfa_ioc_pf_initfailed(iocpf->ioc);
+}
- /**
- * Mark IOC as failed in hardware and stop firmware.
- */
- bfa_ioc_lpu_stop(ioc);
- writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+/**
+ * Hardware initialization failed.
+ */
+static void
+bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc *ioc = iocpf->ioc;
- /**
- * Notify other functions on HB failure.
- */
- bfa_ioc_notify_hbfail(ioc);
+ switch (event) {
+ case IOCPF_E_DISABLE:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+ break;
- /**
- * Notify driver and common modules registered for notification.
- */
- ioc->cbfn->hbfail_cbfn(ioc->bfa);
- list_for_each(qe, &ioc->hb_notify_q) {
- notify = (struct bfa_ioc_hbfail_notify *) qe;
- notify->cbfn(notify->cbarg);
+ case IOCPF_E_STOP:
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
}
+}
+static void
+bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf)
+{
/**
- * Flush any queued up mailbox requests.
+ * Mark IOC as failed in hardware and stop firmware.
*/
- bfa_ioc_mbox_hbfail(ioc);
+ bfa_ioc_lpu_stop(iocpf->ioc);
/**
- * Trigger auto-recovery after a delay.
+ * Flush any queued up mailbox requests.
*/
- if (ioc->auto_recover)
- mod_timer(&ioc->ioc_timer, jiffies +
- msecs_to_jiffies(BFA_IOC_TOV_RECOVER));
+ bfa_ioc_mbox_hbfail(iocpf->ioc);
+ bfa_ioc_hw_sem_get(iocpf->ioc);
}
/**
- * @brief
- * IOC heartbeat failure.
+ * IOC is in failed state.
*/
static void
-bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event)
+bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
- switch (event) {
+ struct bfa_ioc *ioc = iocpf->ioc;
- case IOC_E_ENABLE:
- ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ iocpf->retry_count = 0;
+ bfa_ioc_sync_ack(ioc);
+ bfa_ioc_notify_fail(ioc);
+ if (!iocpf->auto_recover) {
+ bfa_ioc_sync_leave(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ } else {
+ if (bfa_ioc_sync_complete(ioc))
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+ }
+ }
break;
- case IOC_E_DISABLE:
- if (ioc->auto_recover)
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ case IOCPF_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
- case IOC_E_TIMEOUT:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ case IOCPF_E_FAIL:
break;
- case IOC_E_FWREADY:
- /**
- * Recovery is already initiated by other function.
- */
- break;
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
- case IOC_E_HWERROR:
- /*
- * HB failure notification, ignore.
- */
+static void
+bfa_iocpf_sm_fail_entry(struct bfa_iocpf *iocpf)
+{
+}
+
+/**
+ * @brief
+ * IOC is in failed state.
+ */
+static void
+bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
+{
+ switch (event) {
+ case IOCPF_E_DISABLE:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
+
default:
- bfa_sm_fault(ioc, event);
+ bfa_sm_fault(iocpf->ioc, event);
}
}
@@ -678,14 +1139,6 @@ bfa_ioc_disable_comp(struct bfa_ioc *ioc)
}
}
-void
-bfa_nw_ioc_sem_timeout(void *ioc_arg)
-{
- struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
-
- bfa_ioc_hw_sem_get(ioc);
-}
-
bool
bfa_nw_ioc_sem_get(void __iomem *sem_reg)
{
@@ -725,7 +1178,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
*/
r32 = readl(ioc->ioc_regs.ioc_sem_reg);
if (r32 == 0) {
- bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
return;
}
@@ -865,12 +1318,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc)
{
struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr;
- /**
- * If bios/efi boot (flash based) -- return true
- */
- if (bfa_ioc_is_optrom(ioc))
- return true;
-
bfa_nw_ioc_fwver_get(ioc, &fwhdr);
drv_fwhdr = (struct bfi_ioc_image_hdr *)
bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
@@ -934,20 +1381,15 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
/**
* If IOC function is disabled and firmware version is same,
* just re-enable IOC.
- *
- * If option rom, IOC must not be in operational state. With
- * convergence, IOC will be in operational state when 2nd driver
- * is loaded.
*/
- if (ioc_fwstate == BFI_IOC_DISABLED ||
- (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
+ if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
/**
* When using MSI-X any pending firmware ready event should
* be flushed. Otherwise MSI-X interrupts are not delivered.
*/
bfa_ioc_msgflush(ioc);
ioc->cbfn->reset_cbfn(ioc->bfa);
- bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
return;
}
@@ -1033,7 +1475,6 @@ bfa_nw_ioc_hb_check(void *cbarg)
hb_count = readl(ioc->ioc_regs.heartbeat);
if (ioc->hb_count == hb_count) {
- pr_crit("Firmware heartbeat failure at %d", hb_count);
bfa_ioc_recover(ioc);
return;
} else {
@@ -1078,11 +1519,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
*/
bfa_ioc_lmem_init(ioc);
- /**
- * Flash based firmware boot
- */
- if (bfa_ioc_is_optrom(ioc))
- boot_type = BFI_BOOT_TYPE_FLASH;
fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
@@ -1209,6 +1645,55 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
bfa_q_deq(&mod->cmd_q, &cmd);
}
+static void
+bfa_ioc_fail_notify(struct bfa_ioc *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify *notify;
+
+ /**
+ * Notify driver and common modules registered for notification.
+ */
+ ioc->cbfn->hbfail_cbfn(ioc->bfa);
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+}
+
+static void
+bfa_ioc_pf_enabled(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_ENABLED);
+}
+
+static void
+bfa_ioc_pf_disabled(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_DISABLED);
+}
+
+static void
+bfa_ioc_pf_initfailed(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_INITFAILED);
+}
+
+static void
+bfa_ioc_pf_failed(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_PFAILED);
+}
+
+static void
+bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc)
+{
+ /**
+ * Provide enable completion callback and AEN notification.
+ */
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+}
+
/**
* IOC public
*/
@@ -1304,6 +1789,7 @@ static void
bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
{
union bfi_ioc_i2h_msg_u *msg;
+ struct bfa_iocpf *iocpf = &ioc->iocpf;
msg = (union bfi_ioc_i2h_msg_u *) m;
@@ -1314,15 +1800,15 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
break;
case BFI_IOC_I2H_READY_EVENT:
- bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY);
break;
case BFI_IOC_I2H_ENABLE_REPLY:
- bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
+ bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
break;
case BFI_IOC_I2H_DISABLE_REPLY:
- bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
+ bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
break;
case BFI_IOC_I2H_GETATTR_REPLY:
@@ -1348,11 +1834,13 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
ioc->fcmode = false;
ioc->pllinit = false;
ioc->dbg_fwsave_once = true;
+ ioc->iocpf.ioc = ioc;
bfa_ioc_mbox_attach(ioc);
INIT_LIST_HEAD(&ioc->hb_notify_q);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_fsm_send_event(ioc, IOC_E_RESET);
}
/**
@@ -1657,7 +2145,40 @@ bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model)
static enum bfa_ioc_state
bfa_ioc_get_state(struct bfa_ioc *ioc)
{
- return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+ enum bfa_iocpf_state iocpf_st;
+ enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+
+ if (ioc_st == BFA_IOC_ENABLING ||
+ ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
+
+ iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
+
+ switch (iocpf_st) {
+ case BFA_IOCPF_SEMWAIT:
+ ioc_st = BFA_IOC_SEMWAIT;
+ break;
+
+ case BFA_IOCPF_HWINIT:
+ ioc_st = BFA_IOC_HWINIT;
+ break;
+
+ case BFA_IOCPF_FWMISMATCH:
+ ioc_st = BFA_IOC_FWMISMATCH;
+ break;
+
+ case BFA_IOCPF_FAIL:
+ ioc_st = BFA_IOC_FAIL;
+ break;
+
+ case BFA_IOCPF_INITFAIL:
+ ioc_st = BFA_IOC_INITFAIL;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ioc_st;
}
void
@@ -1689,28 +2210,7 @@ bfa_ioc_get_pwwn(struct bfa_ioc *ioc)
mac_t
bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
{
- /*
- * Currently mfg mac is used as FCoE enode mac (not configured by PBC)
- */
- if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
- return bfa_ioc_get_mfg_mac(ioc);
- else
- return ioc->attr->mac;
-}
-
-static mac_t
-bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc)
-{
- mac_t m;
-
- m = ioc->attr->mfg_mac;
- if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
- m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
- else
- bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
- bfa_ioc_pcifn(ioc));
-
- return m;
+ return ioc->attr->mac;
}
/**
@@ -1719,8 +2219,13 @@ bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc)
static void
bfa_ioc_recover(struct bfa_ioc *ioc)
{
- bfa_ioc_stats(ioc, ioc_hbfails);
- bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
+ u16 bdf;
+
+ bdf = (ioc->pcidev.pci_slot << 8 | ioc->pcidev.pci_func << 3 |
+ ioc->pcidev.device_id);
+
+ pr_crit("Firmware heartbeat failure at %d", bdf);
+ BUG_ON(1);
}
static void
@@ -1728,5 +2233,61 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
{
if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
return;
+}
+
+/**
+ * @dg hal_iocpf_pvt BFA IOC PF private functions
+ * @{
+ */
+
+static void
+bfa_iocpf_enable(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
+}
+
+static void
+bfa_iocpf_disable(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
+}
+
+static void
+bfa_iocpf_fail(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
+}
+
+static void
+bfa_iocpf_initfail(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
+}
+
+static void
+bfa_iocpf_getattrfail(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
+}
+
+static void
+bfa_iocpf_stop(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
+}
+void
+bfa_nw_iocpf_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
+}
+
+void
+bfa_nw_iocpf_sem_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_ioc_hw_sem_get(ioc);
}
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index a73d84ec808c..e4974bc24ef6 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -26,16 +26,7 @@
#define BFA_IOC_TOV 3000 /* msecs */
#define BFA_IOC_HWSEM_TOV 500 /* msecs */
#define BFA_IOC_HB_TOV 500 /* msecs */
-#define BFA_IOC_HWINIT_MAX 2
-#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
-
-/**
- * Generic Scatter Gather Element used by driver
- */
-struct bfa_sge {
- u32 sg_len;
- void *sg_addr;
-};
+#define BFA_IOC_HWINIT_MAX 5
/**
* PCI device information required by IOC
@@ -65,19 +56,6 @@ struct bfa_dma {
#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */
/**
- * @brief BFA dma address assignment macro
- */
-#define bfa_dma_addr_set(dma_addr, pa) \
- __bfa_dma_addr_set(&dma_addr, (u64)pa)
-
-static inline void
-__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
-{
- dma_addr->a32.addr_lo = (u32) pa;
- dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa));
-}
-
-/**
* @brief BFA dma address assignment macro. (big endian format)
*/
#define bfa_dma_be_addr_set(dma_addr, pa) \
@@ -105,8 +83,11 @@ struct bfa_ioc_regs {
void __iomem *host_page_num_fn;
void __iomem *heartbeat;
void __iomem *ioc_fwstate;
+ void __iomem *alt_ioc_fwstate;
void __iomem *ll_halt;
+ void __iomem *alt_ll_halt;
void __iomem *err_set;
+ void __iomem *ioc_fail_sync;
void __iomem *shirq_isr_next;
void __iomem *shirq_msk_next;
void __iomem *smem_page_start;
@@ -165,16 +146,22 @@ struct bfa_ioc_hbfail_notify {
(__notify)->cbarg = (__cbarg); \
} while (0)
+struct bfa_iocpf {
+ bfa_fsm_t fsm;
+ struct bfa_ioc *ioc;
+ u32 retry_count;
+ bool auto_recover;
+};
+
struct bfa_ioc {
bfa_fsm_t fsm;
struct bfa *bfa;
struct bfa_pcidev pcidev;
- struct bfa_timer_mod *timer_mod;
struct timer_list ioc_timer;
+ struct timer_list iocpf_timer;
struct timer_list sem_timer;
struct timer_list hb_timer;
u32 hb_count;
- u32 retry_count;
struct list_head hb_notify_q;
void *dbg_fwsave;
int dbg_fwsave_len;
@@ -182,7 +169,6 @@ struct bfa_ioc {
enum bfi_mclass ioc_mc;
struct bfa_ioc_regs ioc_regs;
struct bfa_ioc_drv_stats stats;
- bool auto_recover;
bool fcmode;
bool ctdev;
bool cna;
@@ -195,6 +181,7 @@ struct bfa_ioc {
struct bfa_ioc_cbfn *cbfn;
struct bfa_ioc_mbox_mod mbox_mod;
struct bfa_ioc_hwif *ioc_hwif;
+ struct bfa_iocpf iocpf;
};
struct bfa_ioc_hwif {
@@ -205,8 +192,12 @@ struct bfa_ioc_hwif {
void (*ioc_map_port) (struct bfa_ioc *ioc);
void (*ioc_isr_mode_set) (struct bfa_ioc *ioc,
bool msix);
- void (*ioc_notify_hbfail) (struct bfa_ioc *ioc);
+ void (*ioc_notify_fail) (struct bfa_ioc *ioc);
void (*ioc_ownership_reset) (struct bfa_ioc *ioc);
+ void (*ioc_sync_join) (struct bfa_ioc *ioc);
+ void (*ioc_sync_leave) (struct bfa_ioc *ioc);
+ void (*ioc_sync_ack) (struct bfa_ioc *ioc);
+ bool (*ioc_sync_complete) (struct bfa_ioc *ioc);
};
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -271,7 +262,6 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
void bfa_nw_ioc_disable(struct bfa_ioc *ioc);
void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
-
void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
struct bfa_ioc_hbfail_notify *notify);
@@ -289,7 +279,8 @@ mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc);
*/
void bfa_nw_ioc_timeout(void *ioc);
void bfa_nw_ioc_hb_check(void *ioc);
-void bfa_nw_ioc_sem_timeout(void *ioc);
+void bfa_nw_iocpf_timeout(void *ioc);
+void bfa_nw_iocpf_sem_timeout(void *ioc);
/*
* F/W Image Size & Chunk
diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c
index 121cfd6d48b1..469997c4ffd1 100644
--- a/drivers/net/bna/bfa_ioc_ct.c
+++ b/drivers/net/bna/bfa_ioc_ct.c
@@ -22,6 +22,15 @@
#include "bfi_ctreg.h"
#include "bfa_defs.h"
+#define bfa_ioc_ct_sync_pos(__ioc) \
+ ((u32) (1 << bfa_ioc_pcifn(__ioc)))
+#define BFA_IOC_SYNC_REQD_SH 16
+#define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff)
+#define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000)
+#define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH)
+#define bfa_ioc_ct_sync_reqd_pos(__ioc) \
+ (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH)
+
/*
* forward declarations
*/
@@ -30,8 +39,12 @@ static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc);
static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc);
static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc);
static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix);
-static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc);
static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_sync_join(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc);
+static bool bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc);
static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode);
static struct bfa_ioc_hwif nw_hwif_ct;
@@ -48,8 +61,12 @@ bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
- nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ nw_hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail;
nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+ nw_hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join;
+ nw_hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave;
+ nw_hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack;
+ nw_hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete;
ioc->ioc_hwif = &nw_hwif_ct;
}
@@ -86,6 +103,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
if (usecnt == 0) {
writel(1, ioc->ioc_regs.ioc_usage_reg);
bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_fail_sync);
return true;
}
@@ -149,12 +167,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
* Notify other functions on HB failure.
*/
static void
-bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc)
+bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc)
{
if (ioc->cna) {
writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+ writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
/* Wait for halt to take effect */
readl(ioc->ioc_regs.ll_halt);
+ readl(ioc->ioc_regs.alt_ll_halt);
} else {
writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
readl(ioc->ioc_regs.err_set);
@@ -206,15 +226,19 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
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.alt_ioc_fwstate = rb + BFA_IOC1_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;
+ ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
} else {
ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_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;
+ ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
}
/*
@@ -232,6 +256,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
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);
+ ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC);
/**
* sram memory access
@@ -317,6 +342,77 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
bfa_nw_ioc_hw_sem_release(ioc);
}
+/**
+ * Synchronized IOC failure processing routines
+ */
+static void
+bfa_ioc_ct_sync_join(struct bfa_ioc *ioc)
+{
+ u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ u32 sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc);
+
+ writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static void
+bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc)
+{
+ u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ u32 sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) |
+ bfa_ioc_ct_sync_pos(ioc);
+
+ writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static void
+bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc)
+{
+ u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+
+ writel((r32 | bfa_ioc_ct_sync_pos(ioc)), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static bool
+bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc)
+{
+ u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ u32 sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
+ u32 sync_ackd = bfa_ioc_ct_get_sync_ackd(r32);
+ u32 tmp_ackd;
+
+ if (sync_ackd == 0)
+ return true;
+
+ /**
+ * The check below is to see whether any other PCI fn
+ * has reinitialized the ASIC (reset sync_ackd bits)
+ * and failed again while this IOC was waiting for hw
+ * semaphore (in bfa_iocpf_sm_semwait()).
+ */
+ tmp_ackd = sync_ackd;
+ if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) &&
+ !(sync_ackd & bfa_ioc_ct_sync_pos(ioc)))
+ sync_ackd |= bfa_ioc_ct_sync_pos(ioc);
+
+ if (sync_reqd == sync_ackd) {
+ writel(bfa_ioc_ct_clear_sync_ackd(r32),
+ ioc->ioc_regs.ioc_fail_sync);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate);
+ return true;
+ }
+
+ /**
+ * If another PCI fn reinitialized and failed again while
+ * this IOC was waiting for hw sem, the sync_ackd bit for
+ * this IOC need to be set again to allow reinitialization.
+ */
+ if (tmp_ackd != sync_ackd)
+ writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync);
+
+ return false;
+}
+
static enum bfa_status
bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
{
diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h
index 404ea351d4a1..5130d7918660 100644
--- a/drivers/net/bna/bfi_ctreg.h
+++ b/drivers/net/bna/bfi_ctreg.h
@@ -535,6 +535,7 @@ enum {
#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC HOST_SEM5_INFO_REG
#define CPE_DEPTH_Q(__n) \
(CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
@@ -552,22 +553,30 @@ enum {
(RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
#define RME_CI_PTR_Q(__n) \
(RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
-#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \
- * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
-#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \
- * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
-#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \
- * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
-#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \
- * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
-#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \
- * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
-#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \
- * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
-#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \
- * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
-#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \
- * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
+#define HQM_QSET_RXQ_DRBL_P0(__n) \
+ (HQM_QSET0_RXQ_DRBL_P0 + (__n) * \
+ (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
+#define HQM_QSET_TXQ_DRBL_P0(__n) \
+ (HQM_QSET0_TXQ_DRBL_P0 + (__n) * \
+ (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
+#define HQM_QSET_IB_DRBL_1_P0(__n) \
+ (HQM_QSET0_IB_DRBL_1_P0 + (__n) * \
+ (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
+#define HQM_QSET_IB_DRBL_2_P0(__n) \
+ (HQM_QSET0_IB_DRBL_2_P0 + (__n) * \
+ (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
+#define HQM_QSET_RXQ_DRBL_P1(__n) \
+ (HQM_QSET0_RXQ_DRBL_P1 + (__n) * \
+ (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
+#define HQM_QSET_TXQ_DRBL_P1(__n) \
+ (HQM_QSET0_TXQ_DRBL_P1 + (__n) * \
+ (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
+#define HQM_QSET_IB_DRBL_1_P1(__n) \
+ (HQM_QSET0_IB_DRBL_1_P1 + (__n) * \
+ (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
+#define HQM_QSET_IB_DRBL_2_P1(__n) \
+ (HQM_QSET0_IB_DRBL_2_P1 + (__n) * \
+ (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h
index df6676bbc84e..a287f89b0289 100644
--- a/drivers/net/bna/bna.h
+++ b/drivers/net/bna/bna.h
@@ -32,8 +32,6 @@ extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
/* Log string size */
#define BNA_MESSAGE_SIZE 256
-#define bna_device_timer(_dev) bfa_timer_beat(&((_dev)->timer_mod))
-
/* MBOX API for PORT, TX, RX */
#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \
do { \
@@ -390,8 +388,8 @@ void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe);
/* API for RX */
int bna_port_mtu_get(struct bna_port *port);
-void bna_llport_admin_up(struct bna_llport *llport);
-void bna_llport_admin_down(struct bna_llport *llport);
+void bna_llport_rx_started(struct bna_llport *llport);
+void bna_llport_rx_stopped(struct bna_llport *llport);
/* API for BNAD */
void bna_port_enable(struct bna_port *port);
diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c
index 07b26598546e..e1527472b961 100644
--- a/drivers/net/bna/bna_ctrl.c
+++ b/drivers/net/bna/bna_ctrl.c
@@ -59,14 +59,70 @@ bna_port_cb_link_down(struct bna_port *port, int status)
port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN);
}
+static inline int
+llport_can_be_up(struct bna_llport *llport)
+{
+ int ready = 0;
+ if (llport->type == BNA_PORT_T_REGULAR)
+ ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
+ (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
+ (llport->flags & BNA_LLPORT_F_PORT_ENABLED));
+ else
+ ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
+ (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
+ !(llport->flags & BNA_LLPORT_F_PORT_ENABLED));
+ return ready;
+}
+
+#define llport_is_up llport_can_be_up
+
+enum bna_llport_event {
+ LLPORT_E_START = 1,
+ LLPORT_E_STOP = 2,
+ LLPORT_E_FAIL = 3,
+ LLPORT_E_UP = 4,
+ LLPORT_E_DOWN = 5,
+ LLPORT_E_FWRESP_UP_OK = 6,
+ LLPORT_E_FWRESP_UP_FAIL = 7,
+ LLPORT_E_FWRESP_DOWN = 8
+};
+
+static void
+bna_llport_cb_port_enabled(struct bna_llport *llport)
+{
+ llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
+
+ if (llport_can_be_up(llport))
+ bfa_fsm_send_event(llport, LLPORT_E_UP);
+}
+
+static void
+bna_llport_cb_port_disabled(struct bna_llport *llport)
+{
+ int llport_up = llport_is_up(llport);
+
+ llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
+
+ if (llport_up)
+ bfa_fsm_send_event(llport, LLPORT_E_DOWN);
+}
+
/**
* MBOX
*/
static int
bna_is_aen(u8 msg_id)
{
- return msg_id == BFI_LL_I2H_LINK_DOWN_AEN ||
- msg_id == BFI_LL_I2H_LINK_UP_AEN;
+ switch (msg_id) {
+ case BFI_LL_I2H_LINK_DOWN_AEN:
+ case BFI_LL_I2H_LINK_UP_AEN:
+ case BFI_LL_I2H_PORT_ENABLE_AEN:
+ case BFI_LL_I2H_PORT_DISABLE_AEN:
+ return 1;
+
+ default:
+ return 0;
+ }
}
static void
@@ -81,6 +137,12 @@ bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg)
case BFI_LL_I2H_LINK_DOWN_AEN:
bna_port_cb_link_down(&bna->port, aen->reason);
break;
+ case BFI_LL_I2H_PORT_ENABLE_AEN:
+ bna_llport_cb_port_enabled(&bna->port.llport);
+ break;
+ case BFI_LL_I2H_PORT_DISABLE_AEN:
+ bna_llport_cb_port_disabled(&bna->port.llport);
+ break;
default:
break;
}
@@ -251,16 +313,6 @@ static void bna_llport_start(struct bna_llport *llport);
static void bna_llport_stop(struct bna_llport *llport);
static void bna_llport_fail(struct bna_llport *llport);
-enum bna_llport_event {
- LLPORT_E_START = 1,
- LLPORT_E_STOP = 2,
- LLPORT_E_FAIL = 3,
- LLPORT_E_UP = 4,
- LLPORT_E_DOWN = 5,
- LLPORT_E_FWRESP_UP = 6,
- LLPORT_E_FWRESP_DOWN = 7
-};
-
enum bna_llport_state {
BNA_LLPORT_STOPPED = 1,
BNA_LLPORT_DOWN = 2,
@@ -320,7 +372,7 @@ bna_llport_sm_stopped(struct bna_llport *llport,
/* No-op */
break;
- case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_UP_OK:
case LLPORT_E_FWRESP_DOWN:
/**
* These events are received due to flushing of mbox when
@@ -366,6 +418,7 @@ bna_llport_sm_down(struct bna_llport *llport,
static void
bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport)
{
+ BUG_ON(!llport_can_be_up(llport));
/**
* NOTE: Do not call bna_fw_llport_up() here. That will over step
* mbox due to down_resp_wait -> up_resp_wait transition on event
@@ -390,10 +443,14 @@ bna_llport_sm_up_resp_wait(struct bna_llport *llport,
bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
break;
- case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_UP_OK:
bfa_fsm_set_state(llport, bna_llport_sm_up);
break;
+ case LLPORT_E_FWRESP_UP_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_down);
+ break;
+
case LLPORT_E_FWRESP_DOWN:
/* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */
bna_fw_llport_up(llport);
@@ -431,11 +488,12 @@ bna_llport_sm_down_resp_wait(struct bna_llport *llport,
bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
break;
- case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_UP_OK:
/* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */
bna_fw_llport_down(llport);
break;
+ case LLPORT_E_FWRESP_UP_FAIL:
case LLPORT_E_FWRESP_DOWN:
bfa_fsm_set_state(llport, bna_llport_sm_down);
break;
@@ -496,11 +554,12 @@ bna_llport_sm_last_resp_wait(struct bna_llport *llport,
/* No-op */
break;
- case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_UP_OK:
/* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */
bna_fw_llport_down(llport);
break;
+ case LLPORT_E_FWRESP_UP_FAIL:
case LLPORT_E_FWRESP_DOWN:
bfa_fsm_set_state(llport, bna_llport_sm_stopped);
break;
@@ -541,7 +600,14 @@ bna_fw_cb_llport_up(void *arg, int status)
struct bna_llport *llport = (struct bna_llport *)arg;
bfa_q_qe_init(&llport->mbox_qe.qe);
- bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP);
+ if (status == BFI_LL_CMD_FAIL) {
+ if (llport->type == BNA_PORT_T_REGULAR)
+ llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
+ else
+ llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_FAIL);
+ } else
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_OK);
}
static void
@@ -588,13 +654,14 @@ bna_port_cb_llport_stopped(struct bna_port *port,
static void
bna_llport_init(struct bna_llport *llport, struct bna *bna)
{
- llport->flags |= BNA_LLPORT_F_ENABLED;
+ llport->flags |= BNA_LLPORT_F_ADMIN_UP;
+ llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
llport->type = BNA_PORT_T_REGULAR;
llport->bna = bna;
llport->link_status = BNA_LINK_DOWN;
- llport->admin_up_count = 0;
+ llport->rx_started_count = 0;
llport->stop_cbfn = NULL;
@@ -606,7 +673,8 @@ bna_llport_init(struct bna_llport *llport, struct bna *bna)
static void
bna_llport_uninit(struct bna_llport *llport)
{
- llport->flags &= ~BNA_LLPORT_F_ENABLED;
+ llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
+ llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
llport->bna = NULL;
}
@@ -628,6 +696,8 @@ bna_llport_stop(struct bna_llport *llport)
static void
bna_llport_fail(struct bna_llport *llport)
{
+ /* Reset the physical port status to enabled */
+ llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
bfa_fsm_send_event(llport, LLPORT_E_FAIL);
}
@@ -638,25 +708,31 @@ bna_llport_state_get(struct bna_llport *llport)
}
void
-bna_llport_admin_up(struct bna_llport *llport)
+bna_llport_rx_started(struct bna_llport *llport)
{
- llport->admin_up_count++;
+ llport->rx_started_count++;
- if (llport->admin_up_count == 1) {
- llport->flags |= BNA_LLPORT_F_RX_ENABLED;
- if (llport->flags & BNA_LLPORT_F_ENABLED)
+ if (llport->rx_started_count == 1) {
+
+ llport->flags |= BNA_LLPORT_F_RX_STARTED;
+
+ if (llport_can_be_up(llport))
bfa_fsm_send_event(llport, LLPORT_E_UP);
}
}
void
-bna_llport_admin_down(struct bna_llport *llport)
+bna_llport_rx_stopped(struct bna_llport *llport)
{
- llport->admin_up_count--;
+ int llport_up = llport_is_up(llport);
+
+ llport->rx_started_count--;
- if (llport->admin_up_count == 0) {
- llport->flags &= ~BNA_LLPORT_F_RX_ENABLED;
- if (llport->flags & BNA_LLPORT_F_ENABLED)
+ if (llport->rx_started_count == 0) {
+
+ llport->flags &= ~BNA_LLPORT_F_RX_STARTED;
+
+ if (llport_up)
bfa_fsm_send_event(llport, LLPORT_E_DOWN);
}
}
@@ -2056,37 +2132,6 @@ rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status)
bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
}
-static void
-__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status)
-{
- struct bna_rx_fndb_ram *rx_fndb_ram;
- u32 ctrl_flags;
- int i;
-
- rx_fndb_ram = (struct bna_rx_fndb_ram *)
- BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva,
- RX_FNDB_RAM_BASE_OFFSET);
-
- for (i = 0; i < BFI_MAX_RXF; i++) {
- if (status == BNA_STATUS_T_ENABLED) {
- if (i == rxf->rxf_id)
- continue;
-
- ctrl_flags =
- readl(&rx_fndb_ram[i].control_flags);
- ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
- writel(ctrl_flags,
- &rx_fndb_ram[i].control_flags);
- } else {
- ctrl_flags =
- readl(&rx_fndb_ram[i].control_flags);
- ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
- writel(ctrl_flags,
- &rx_fndb_ram[i].control_flags);
- }
- }
-}
-
int
rxf_process_packet_filter_ucast(struct bna_rxf *rxf)
{
@@ -2153,46 +2198,6 @@ rxf_process_packet_filter_promisc(struct bna_rxf *rxf)
}
int
-rxf_process_packet_filter_default(struct bna_rxf *rxf)
-{
- struct bna *bna = rxf->rx->bna;
-
- /* Enable/disable default mode */
- if (is_default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask)) {
- /* move default configuration from pending -> active */
- default_inactive(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active |= BNA_RXMODE_DEFAULT;
-
- /* Disable VLAN filter to allow all VLANs */
- __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
- /* Redirect all other RxF vlan filtering to this one */
- __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED);
- rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
- BNA_STATUS_T_ENABLED);
- return 1;
- } else if (is_default_disable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask)) {
- /* move default configuration from pending -> active */
- default_inactive(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
- bna->rxf_default_id = BFI_MAX_RXF;
-
- /* Revert VLAN filter */
- __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
- /* Stop RxF vlan filter table redirection */
- __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
- rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
- BNA_STATUS_T_DISABLED);
- return 1;
- }
-
- return 0;
-}
-
-int
rxf_process_packet_filter_allmulti(struct bna_rxf *rxf)
{
/* Enable/disable allmulti mode */
@@ -2289,48 +2294,6 @@ rxf_clear_packet_filter_promisc(struct bna_rxf *rxf)
}
int
-rxf_clear_packet_filter_default(struct bna_rxf *rxf)
-{
- struct bna *bna = rxf->rx->bna;
-
- /* 8. Execute pending default mode disable command */
- if (is_default_disable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask)) {
- /* move default configuration from pending -> active */
- default_inactive(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
- bna->rxf_default_id = BFI_MAX_RXF;
-
- /* Revert VLAN filter */
- __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
- /* Stop RxF vlan filter table redirection */
- __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
- rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
- BNA_STATUS_T_DISABLED);
- return 1;
- }
-
- /* 9. Clear active default mode; move it to pending enable */
- if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
- /* move default configuration from active -> pending */
- default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
-
- /* Revert VLAN filter */
- __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
- /* Stop RxF vlan filter table redirection */
- __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
- rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
- BNA_STATUS_T_DISABLED);
- return 1;
- }
-
- return 0;
-}
-
-int
rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf)
{
/* 10. Execute pending allmulti mode disable command */
@@ -2405,28 +2368,6 @@ rxf_reset_packet_filter_promisc(struct bna_rxf *rxf)
}
void
-rxf_reset_packet_filter_default(struct bna_rxf *rxf)
-{
- struct bna *bna = rxf->rx->bna;
-
- /* 8. Clear pending default mode disable */
- if (is_default_disable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask)) {
- default_inactive(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
- bna->rxf_default_id = BFI_MAX_RXF;
- }
-
- /* 9. Move default mode config from active -> pending */
- if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
- default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
- }
-}
-
-void
rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf)
{
/* 10. Clear pending allmulti mode disable */
@@ -2523,76 +2464,6 @@ rxf_promisc_disable(struct bna_rxf *rxf)
* 1 = need h/w change
*/
static int
-rxf_default_enable(struct bna_rxf *rxf)
-{
- struct bna *bna = rxf->rx->bna;
- int ret = 0;
-
- /* There can not be any pending disable command */
-
- /* Do nothing if pending enable or already enabled */
- if (is_default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask) ||
- (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) {
- /* Schedule enable */
- } else {
- /* Default mode should not be active in the system */
- default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- bna->rxf_default_id = rxf->rxf_id;
- ret = 1;
- }
-
- return ret;
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- * Returns:
- * 0 = no h/w change
- * 1 = need h/w change
- */
-static int
-rxf_default_disable(struct bna_rxf *rxf)
-{
- struct bna *bna = rxf->rx->bna;
- int ret = 0;
-
- /* There can not be any pending disable */
-
- /* Turn off pending enable command , if any */
- if (is_default_enable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask)) {
- /* Promisc mode should not be active */
- /* system default state should be pending */
- default_inactive(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- /* Remove the default state from the system */
- bna->rxf_default_id = BFI_MAX_RXF;
-
- /* Schedule disable */
- } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
- /* Default mode should be active in the system */
- default_disable(rxf->rxmode_pending,
- rxf->rxmode_pending_bitmask);
- ret = 1;
-
- /* Do nothing if already disabled */
- } else {
- }
-
- return ret;
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- * Returns:
- * 0 = no h/w change
- * 1 = need h/w change
- */
-static int
rxf_allmulti_enable(struct bna_rxf *rxf)
{
int ret = 0;
@@ -2654,38 +2525,13 @@ bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
struct bna_rxf *rxf = &rx->rxf;
int need_hw_config = 0;
- /* Error checks */
+ /* Process the commands */
if (is_promisc_enable(new_mode, bitmask)) {
/* If promisc mode is already enabled elsewhere in the system */
if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) &&
(rx->bna->rxf_promisc_id != rxf->rxf_id))
goto err_return;
-
- /* If default mode is already enabled in the system */
- if (rx->bna->rxf_default_id != BFI_MAX_RXF)
- goto err_return;
-
- /* Trying to enable promiscuous and default mode together */
- if (is_default_enable(new_mode, bitmask))
- goto err_return;
- }
-
- if (is_default_enable(new_mode, bitmask)) {
- /* If default mode is already enabled elsewhere in the system */
- if ((rx->bna->rxf_default_id != BFI_MAX_RXF) &&
- (rx->bna->rxf_default_id != rxf->rxf_id)) {
- goto err_return;
- }
-
- /* If promiscuous mode is already enabled in the system */
- if (rx->bna->rxf_promisc_id != BFI_MAX_RXF)
- goto err_return;
- }
-
- /* Process the commands */
-
- if (is_promisc_enable(new_mode, bitmask)) {
if (rxf_promisc_enable(rxf))
need_hw_config = 1;
} else if (is_promisc_disable(new_mode, bitmask)) {
@@ -2693,14 +2539,6 @@ bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
need_hw_config = 1;
}
- if (is_default_enable(new_mode, bitmask)) {
- if (rxf_default_enable(rxf))
- need_hw_config = 1;
- } else if (is_default_disable(new_mode, bitmask)) {
- if (rxf_default_disable(rxf))
- need_hw_config = 1;
- }
-
if (is_allmulti_enable(new_mode, bitmask)) {
if (rxf_allmulti_enable(rxf))
need_hw_config = 1;
@@ -3126,7 +2964,6 @@ bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev,
bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
- bna->rxf_default_id = BFI_MAX_RXF;
bna->rxf_promisc_id = BFI_MAX_RXF;
/* Mbox q element for posting stat request to f/w */
diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c
index ad93fdb0f427..58c7664040dc 100644
--- a/drivers/net/bna/bna_txrx.c
+++ b/drivers/net/bna/bna_txrx.c
@@ -1226,8 +1226,7 @@ rxf_process_packet_filter_vlan(struct bna_rxf *rxf)
/* Apply the VLAN filter */
if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) {
rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING;
- if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) &&
- !(rxf->rxmode_active & BNA_RXMODE_DEFAULT))
+ if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC))
__rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
}
@@ -1276,9 +1275,6 @@ rxf_process_packet_filter(struct bna_rxf *rxf)
if (rxf_process_packet_filter_promisc(rxf))
return 1;
- if (rxf_process_packet_filter_default(rxf))
- return 1;
-
if (rxf_process_packet_filter_allmulti(rxf))
return 1;
@@ -1340,9 +1336,6 @@ rxf_clear_packet_filter(struct bna_rxf *rxf)
if (rxf_clear_packet_filter_promisc(rxf))
return 1;
- if (rxf_clear_packet_filter_default(rxf))
- return 1;
-
if (rxf_clear_packet_filter_allmulti(rxf))
return 1;
@@ -1389,8 +1382,6 @@ rxf_reset_packet_filter(struct bna_rxf *rxf)
rxf_reset_packet_filter_promisc(rxf);
- rxf_reset_packet_filter_default(rxf);
-
rxf_reset_packet_filter_allmulti(rxf);
}
@@ -1441,12 +1432,16 @@ bna_rxf_init(struct bna_rxf *rxf,
memset(rxf->vlan_filter_table, 0,
(sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)));
+ /* Set up VLAN 0 for pure priority tagged packets */
+ rxf->vlan_filter_table[0] |= 1;
+
bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
}
static void
bna_rxf_uninit(struct bna_rxf *rxf)
{
+ struct bna *bna = rxf->rx->bna;
struct bna_mac *mac;
bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment);
@@ -1473,6 +1468,27 @@ bna_rxf_uninit(struct bna_rxf *rxf)
bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
}
+ /* Turn off pending promisc mode */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* system promisc state should be pending */
+ BUG_ON(!(bna->rxf_promisc_id == rxf->rxf_id));
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+ }
+ /* Promisc mode should not be active */
+ BUG_ON(rxf->rxmode_active & BNA_RXMODE_PROMISC);
+
+ /* Turn off pending all-multi mode */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ }
+ /* Allmulti mode should not be active */
+ BUG_ON(rxf->rxmode_active & BNA_RXMODE_ALLMULTI);
+
rxf->rx = NULL;
}
@@ -1947,7 +1963,7 @@ bna_rx_sm_started_entry(struct bna_rx *rx)
bna_ib_ack(&rxp->cq.ib->door_bell, 0);
}
- bna_llport_admin_up(&rx->bna->port.llport);
+ bna_llport_rx_started(&rx->bna->port.llport);
}
void
@@ -1955,13 +1971,13 @@ bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
{
switch (event) {
case RX_E_FAIL:
- bna_llport_admin_down(&rx->bna->port.llport);
+ bna_llport_rx_stopped(&rx->bna->port.llport);
bfa_fsm_set_state(rx, bna_rx_sm_stopped);
rx_ib_fail(rx);
bna_rxf_fail(&rx->rxf);
break;
case RX_E_STOP:
- bna_llport_admin_down(&rx->bna->port.llport);
+ bna_llport_rx_stopped(&rx->bna->port.llport);
bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
break;
default:
@@ -3373,7 +3389,7 @@ __bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
- (txq->priority & 0x3));
+ (txq->priority & 0x7));
txq_cfg.wvc_n_cquota_n_rquota =
((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
(BFI_TX_MAX_WRR_QUOTA & 0xfff));
diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h
index 6877310f6ef4..b9c134f7ad31 100644
--- a/drivers/net/bna/bna_types.h
+++ b/drivers/net/bna/bna_types.h
@@ -165,8 +165,7 @@ enum bna_rxp_type {
enum bna_rxmode {
BNA_RXMODE_PROMISC = 1,
- BNA_RXMODE_DEFAULT = 2,
- BNA_RXMODE_ALLMULTI = 4
+ BNA_RXMODE_ALLMULTI = 2
};
enum bna_rx_event {
@@ -249,8 +248,9 @@ enum bna_link_status {
};
enum bna_llport_flags {
- BNA_LLPORT_F_ENABLED = 1,
- BNA_LLPORT_F_RX_ENABLED = 2
+ BNA_LLPORT_F_ADMIN_UP = 1,
+ BNA_LLPORT_F_PORT_ENABLED = 2,
+ BNA_LLPORT_F_RX_STARTED = 4
};
enum bna_port_flags {
@@ -405,7 +405,7 @@ struct bna_llport {
enum bna_link_status link_status;
- int admin_up_count;
+ int rx_started_count;
void (*stop_cbfn)(struct bna_port *, enum bna_cb_status);
@@ -1117,7 +1117,6 @@ struct bna {
struct bna_rit_mod rit_mod;
- int rxf_default_id;
int rxf_promisc_id;
struct bna_mbox_qe mbox_qe;
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 7e839b9cec22..fad912656fe4 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -70,6 +70,8 @@ do { \
(sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \
} while (0)
+#define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */
+
/*
* Reinitialize completions in CQ, once Rx is taken down
*/
@@ -107,7 +109,7 @@ static void
bnad_free_all_txbufs(struct bnad *bnad,
struct bna_tcb *tcb)
{
- u16 unmap_cons;
+ u32 unmap_cons;
struct bnad_unmap_q *unmap_q = tcb->unmap_q;
struct bnad_skb_unmap *unmap_array;
struct sk_buff *skb = NULL;
@@ -130,7 +132,9 @@ bnad_free_all_txbufs(struct bnad *bnad,
PCI_DMA_TODEVICE);
pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
- unmap_cons++;
+ if (++unmap_cons >= unmap_q->q_depth)
+ break;
+
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
pci_unmap_page(bnad->pcidev,
pci_unmap_addr(&unmap_array[unmap_cons],
@@ -139,7 +143,8 @@ bnad_free_all_txbufs(struct bnad *bnad,
PCI_DMA_TODEVICE);
pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
0);
- unmap_cons++;
+ if (++unmap_cons >= unmap_q->q_depth)
+ break;
}
dev_kfree_skb_any(skb);
}
@@ -167,11 +172,11 @@ bnad_free_txbufs(struct bnad *bnad,
/*
* Just return if TX is stopped. This check is useful
* when bnad_free_txbufs() runs out of a tasklet scheduled
- * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit
+ * before bnad_cb_tx_cleanup() cleared BNAD_TXQ_TX_STARTED bit
* but this routine runs actually after the cleanup has been
* executed.
*/
- if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
+ if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
return 0;
updated_hw_cons = *(tcb->hw_consumer_index);
@@ -239,7 +244,7 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr)
{
struct bnad *bnad = (struct bnad *)bnad_ptr;
struct bna_tcb *tcb;
- u32 acked;
+ u32 acked = 0;
int i, j;
for (i = 0; i < bnad->num_tx; i++) {
@@ -252,10 +257,26 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr)
(!test_and_set_bit(BNAD_TXQ_FREE_SENT,
&tcb->flags))) {
acked = bnad_free_txbufs(bnad, tcb);
- bna_ib_ack(tcb->i_dbell, acked);
+ if (likely(test_bit(BNAD_TXQ_TX_STARTED,
+ &tcb->flags)))
+ bna_ib_ack(tcb->i_dbell, acked);
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
}
+ if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED,
+ &tcb->flags)))
+ continue;
+ if (netif_queue_stopped(bnad->netdev)) {
+ if (acked && netif_carrier_ok(bnad->netdev) &&
+ BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
+ BNAD_NETIF_WAKE_THRESHOLD) {
+ netif_wake_queue(bnad->netdev);
+ /* TODO */
+ /* Counters for individual TxQs? */
+ BNAD_UPDATE_CTR(bnad,
+ netif_queue_wakeup);
+ }
+ }
}
}
}
@@ -264,7 +285,7 @@ static u32
bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
{
struct net_device *netdev = bnad->netdev;
- u32 sent;
+ u32 sent = 0;
if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
return 0;
@@ -275,12 +296,15 @@ bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
netif_carrier_ok(netdev) &&
BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
BNAD_NETIF_WAKE_THRESHOLD) {
- netif_wake_queue(netdev);
- BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) {
+ netif_wake_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
}
+ }
+
+ if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
bna_ib_ack(tcb->i_dbell, sent);
- } else
- bna_ib_ack(tcb->i_dbell, 0);
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
@@ -313,25 +337,24 @@ bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
}
static void
-bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
{
struct bnad_unmap_q *unmap_q;
struct sk_buff *skb;
+ int unmap_cons;
unmap_q = rcb->unmap_q;
- while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) {
- skb = unmap_q->unmap_array[unmap_q->consumer_index].skb;
- BUG_ON(!(skb));
- unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL;
+ for (unmap_cons = 0; unmap_cons < unmap_q->q_depth; unmap_cons++) {
+ skb = unmap_q->unmap_array[unmap_cons].skb;
+ if (!skb)
+ continue;
+ unmap_q->unmap_array[unmap_cons].skb = NULL;
pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q->
- unmap_array[unmap_q->consumer_index],
- dma_addr), rcb->rxq->buffer_size +
- NET_IP_ALIGN, PCI_DMA_FROMDEVICE);
+ unmap_array[unmap_cons],
+ dma_addr), rcb->rxq->buffer_size,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb(skb);
- BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth);
- BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth);
}
-
bnad_reset_rcb(bnad, rcb);
}
@@ -385,43 +408,11 @@ finishing:
unmap_q->producer_index = unmap_prod;
rcb->producer_index = unmap_prod;
smp_mb();
- bna_rxq_prod_indx_doorbell(rcb);
+ if (likely(test_bit(BNAD_RXQ_STARTED, &rcb->flags)))
+ bna_rxq_prod_indx_doorbell(rcb);
}
}
-/*
- * Locking is required in the enable path
- * because it is called from a napi poll
- * context, where the bna_lock is not held
- * unlike the IRQ context.
- */
-static void
-bnad_enable_txrx_irqs(struct bnad *bnad)
-{
- struct bna_tcb *tcb;
- struct bna_ccb *ccb;
- int i, j;
- unsigned long flags;
-
- spin_lock_irqsave(&bnad->bna_lock, flags);
- for (i = 0; i < bnad->num_tx; i++) {
- for (j = 0; j < bnad->num_txq_per_tx; j++) {
- tcb = bnad->tx_info[i].tcb[j];
- bna_ib_coalescing_timer_set(tcb->i_dbell,
- tcb->txq->ib->ib_config.coalescing_timeo);
- bna_ib_ack(tcb->i_dbell, 0);
- }
- }
-
- for (i = 0; i < bnad->num_rx; i++) {
- for (j = 0; j < bnad->num_rxp_per_rx; j++) {
- ccb = bnad->rx_info[i].rx_ctrl[j].ccb;
- bnad_enable_rx_irq_unsafe(ccb);
- }
- }
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
-}
-
static inline void
bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
{
@@ -448,6 +439,9 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
u32 qid0 = ccb->rcb[0]->rxq->rxq_id;
struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
+ if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))
+ return 0;
+
prefetch(bnad->netdev);
BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
wi_range);
@@ -544,12 +538,15 @@ next:
BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
if (likely(ccb)) {
- bna_ib_ack(ccb->i_dbell, packets);
+ if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
+ bna_ib_ack(ccb->i_dbell, packets);
bnad_refill_rxq(bnad, ccb->rcb[0]);
if (ccb->rcb[1])
bnad_refill_rxq(bnad, ccb->rcb[1]);
- } else
- bna_ib_ack(ccb->i_dbell, 0);
+ } else {
+ if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
+ bna_ib_ack(ccb->i_dbell, 0);
+ }
return packets;
}
@@ -557,6 +554,9 @@ next:
static void
bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
{
+ if (unlikely(!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
+ return;
+
bna_ib_coalescing_timer_set(ccb->i_dbell, 0);
bna_ib_ack(ccb->i_dbell, 0);
}
@@ -566,7 +566,8 @@ bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
{
unsigned long flags;
- spin_lock_irqsave(&bnad->bna_lock, flags); /* Because of polling context */
+ /* Because of polling context */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
bnad_enable_rx_irq_unsafe(ccb);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
}
@@ -575,9 +576,11 @@ static void
bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb)
{
struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
- if (likely(napi_schedule_prep((&rx_ctrl->napi)))) {
+ struct napi_struct *napi = &rx_ctrl->napi;
+
+ if (likely(napi_schedule_prep(napi))) {
bnad_disable_rx_irq(bnad, ccb);
- __napi_schedule((&rx_ctrl->napi));
+ __napi_schedule(napi);
}
BNAD_UPDATE_CTR(bnad, netif_rx_schedule);
}
@@ -602,12 +605,11 @@ bnad_msix_mbox_handler(int irq, void *data)
{
u32 intr_status;
unsigned long flags;
- struct net_device *netdev = data;
- struct bnad *bnad;
+ struct bnad *bnad = (struct bnad *)data;
- bnad = netdev_priv(netdev);
+ if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
+ return IRQ_HANDLED;
- /* BNA_ISR_GET(bnad); Inc Ref count */
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_intr_status_get(&bnad->bna, intr_status);
@@ -617,7 +619,6 @@ bnad_msix_mbox_handler(int irq, void *data)
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- /* BNAD_ISR_PUT(bnad); Dec Ref count */
return IRQ_HANDLED;
}
@@ -627,8 +628,7 @@ bnad_isr(int irq, void *data)
int i, j;
u32 intr_status;
unsigned long flags;
- struct net_device *netdev = data;
- struct bnad *bnad = netdev_priv(netdev);
+ struct bnad *bnad = (struct bnad *)data;
struct bnad_rx_info *rx_info;
struct bnad_rx_ctrl *rx_ctrl;
@@ -642,16 +642,21 @@ bnad_isr(int irq, void *data)
spin_lock_irqsave(&bnad->bna_lock, flags);
- if (BNA_IS_MBOX_ERR_INTR(intr_status)) {
+ if (BNA_IS_MBOX_ERR_INTR(intr_status))
bna_mbox_handler(&bnad->bna, intr_status);
- if (!BNA_IS_INTX_DATA_INTR(intr_status)) {
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
- goto done;
- }
- }
+
spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (!BNA_IS_INTX_DATA_INTR(intr_status))
+ return IRQ_HANDLED;
+
/* Process data interrupts */
+ /* Tx processing */
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++)
+ bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ }
+ /* Rx processing */
for (i = 0; i < bnad->num_rx; i++) {
rx_info = &bnad->rx_info[i];
if (!rx_info->rx)
@@ -663,7 +668,6 @@ bnad_isr(int irq, void *data)
rx_ctrl->ccb);
}
}
-done:
return IRQ_HANDLED;
}
@@ -674,11 +678,7 @@ done:
static void
bnad_enable_mbox_irq(struct bnad *bnad)
{
- int irq = BNAD_GET_MBOX_IRQ(bnad);
-
- if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
- if (bnad->cfg_flags & BNAD_CF_MSIX)
- enable_irq(irq);
+ clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags);
BNAD_UPDATE_CTR(bnad, mbox_intr_enabled);
}
@@ -690,14 +690,19 @@ bnad_enable_mbox_irq(struct bnad *bnad)
static void
bnad_disable_mbox_irq(struct bnad *bnad)
{
- int irq = BNAD_GET_MBOX_IRQ(bnad);
+ set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags);
+ BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
+}
- if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
- if (bnad->cfg_flags & BNAD_CF_MSIX)
- disable_irq_nosync(irq);
+static void
+bnad_set_netdev_perm_addr(struct bnad *bnad)
+{
+ struct net_device *netdev = bnad->netdev;
- BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
+ memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len);
+ if (is_zero_ether_addr(netdev->dev_addr))
+ memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len);
}
/* Control Path Handlers */
@@ -755,11 +760,14 @@ bnad_cb_port_link_status(struct bnad *bnad,
if (link_up) {
if (!netif_carrier_ok(bnad->netdev)) {
+ struct bna_tcb *tcb = bnad->tx_info[0].tcb[0];
+ if (!tcb)
+ return;
pr_warn("bna: %s link up\n",
bnad->netdev->name);
netif_carrier_on(bnad->netdev);
BNAD_UPDATE_CTR(bnad, link_toggle);
- if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) {
+ if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) {
/* Force an immediate Transmit Schedule */
pr_info("bna: %s TX_STARTED\n",
bnad->netdev->name);
@@ -807,6 +815,18 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
{
struct bnad_tx_info *tx_info =
(struct bnad_tx_info *)tcb->txq->tx->priv;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+
+ while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ cpu_relax();
+
+ bnad_free_all_txbufs(bnad, tcb);
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
tx_info->tcb[tcb->id] = NULL;
}
@@ -822,6 +842,12 @@ bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb)
}
static void
+bnad_cb_rcb_destroy(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ bnad_free_all_rxbufs(bnad, rcb);
+}
+
+static void
bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
{
struct bnad_rx_info *rx_info =
@@ -849,7 +875,7 @@ bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb)
if (tx_info != &bnad->tx_info[0])
return;
- clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags);
+ clear_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
netif_stop_queue(bnad->netdev);
pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name);
}
@@ -857,30 +883,15 @@ bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb)
static void
bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb)
{
- if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
- return;
-
- if (netif_carrier_ok(bnad->netdev)) {
- pr_info("bna: %s TX_STARTED\n", bnad->netdev->name);
- netif_wake_queue(bnad->netdev);
- BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
- }
-}
-
-static void
-bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
-{
- struct bnad_unmap_q *unmap_q;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
- if (!tcb || (!tcb->unmap_q))
+ if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
return;
- unmap_q = tcb->unmap_q;
- if (!unmap_q->unmap_array)
- return;
+ clear_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags);
- if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
- return;
+ while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ cpu_relax();
bnad_free_all_txbufs(bnad, tcb);
@@ -889,21 +900,45 @@ bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+
+ /*
+ * Workaround for first device enable failure & we
+ * get a 0 MAC address. We try to get the MAC address
+ * again here.
+ */
+ if (is_zero_ether_addr(&bnad->perm_addr.mac[0])) {
+ bna_port_mac_get(&bnad->bna.port, &bnad->perm_addr);
+ bnad_set_netdev_perm_addr(bnad);
+ }
+
+ set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
+
+ if (netif_carrier_ok(bnad->netdev)) {
+ pr_info("bna: %s TX_STARTED\n", bnad->netdev->name);
+ netif_wake_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+}
+
+static void
+bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ /* Delay only once for the whole Tx Path Shutdown */
+ if (!test_and_set_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags))
+ mdelay(BNAD_TXRX_SYNC_MDELAY);
}
static void
bnad_cb_rx_cleanup(struct bnad *bnad,
struct bna_ccb *ccb)
{
- bnad_cq_cmpl_init(bnad, ccb);
-
- bnad_free_rxbufs(bnad, ccb->rcb[0]);
clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags);
- if (ccb->rcb[1]) {
- bnad_free_rxbufs(bnad, ccb->rcb[1]);
+ if (ccb->rcb[1])
clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
- }
+
+ if (!test_and_set_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags))
+ mdelay(BNAD_TXRX_SYNC_MDELAY);
}
static void
@@ -911,6 +946,13 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb)
{
struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+ clear_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags);
+
+ if (rcb == rcb->cq->ccb->rcb[0])
+ bnad_cq_cmpl_init(bnad, rcb->cq->ccb);
+
+ bnad_free_all_rxbufs(bnad, rcb);
+
set_bit(BNAD_RXQ_STARTED, &rcb->flags);
/* Now allocate & post buffers for this RCB */
@@ -1047,7 +1089,7 @@ bnad_mbox_irq_free(struct bnad *bnad,
spin_unlock_irqrestore(&bnad->bna_lock, flags);
irq = BNAD_GET_MBOX_IRQ(bnad);
- free_irq(irq, bnad->netdev);
+ free_irq(irq, bnad);
kfree(intr_info->idl);
}
@@ -1061,7 +1103,7 @@ static int
bnad_mbox_irq_alloc(struct bnad *bnad,
struct bna_intr_info *intr_info)
{
- int err;
+ int err = 0;
unsigned long flags;
u32 irq;
irq_handler_t irq_handler;
@@ -1096,22 +1138,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
*/
set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags);
+ BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
+
err = request_irq(irq, irq_handler, flags,
- bnad->mbox_irq_name, bnad->netdev);
+ bnad->mbox_irq_name, bnad);
if (err) {
kfree(intr_info->idl);
intr_info->idl = NULL;
- return err;
}
- spin_lock_irqsave(&bnad->bna_lock, flags);
-
- if (bnad->cfg_flags & BNAD_CF_MSIX)
- disable_irq_nosync(irq);
-
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
- return 0;
+ return err;
}
static void
@@ -1388,13 +1425,24 @@ bnad_ioc_hb_check(unsigned long data)
}
static void
-bnad_ioc_sem_timeout(unsigned long data)
+bnad_iocpf_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_iocpf_timeout((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_iocpf_sem_timeout(unsigned long data)
{
struct bnad *bnad = (struct bnad *)data;
unsigned long flags;
spin_lock_irqsave(&bnad->bna_lock, flags);
- bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc);
+ bfa_nw_iocpf_sem_timeout((void *) &bnad->bna.device.ioc);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
}
@@ -1555,62 +1603,19 @@ poll_exit:
return rcvd;
}
-static int
-bnad_napi_poll_txrx(struct napi_struct *napi, int budget)
-{
- struct bnad_rx_ctrl *rx_ctrl =
- container_of(napi, struct bnad_rx_ctrl, napi);
- struct bna_ccb *ccb;
- struct bnad *bnad;
- int rcvd = 0;
- int i, j;
-
- ccb = rx_ctrl->ccb;
-
- bnad = ccb->bnad;
-
- if (!netif_carrier_ok(bnad->netdev))
- goto poll_exit;
-
- /* Handle Tx Completions, if any */
- for (i = 0; i < bnad->num_tx; i++) {
- for (j = 0; j < bnad->num_txq_per_tx; j++)
- bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
- }
-
- /* Handle Rx Completions */
- rcvd = bnad_poll_cq(bnad, ccb, budget);
- if (rcvd == budget)
- return rcvd;
-poll_exit:
- napi_complete((napi));
-
- BNAD_UPDATE_CTR(bnad, netif_rx_complete);
-
- bnad_enable_txrx_irqs(bnad);
- return rcvd;
-}
-
static void
bnad_napi_enable(struct bnad *bnad, u32 rx_id)
{
- int (*napi_poll) (struct napi_struct *, int);
struct bnad_rx_ctrl *rx_ctrl;
int i;
- unsigned long flags;
-
- spin_lock_irqsave(&bnad->bna_lock, flags);
- if (bnad->cfg_flags & BNAD_CF_MSIX)
- napi_poll = bnad_napi_poll_rx;
- else
- napi_poll = bnad_napi_poll_txrx;
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
/* Initialize & enable NAPI */
for (i = 0; i < bnad->num_rxp_per_rx; i++) {
rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
+
netif_napi_add(bnad->netdev, &rx_ctrl->napi,
- napi_poll, 64);
+ bnad_napi_poll_rx, 64);
+
napi_enable(&rx_ctrl->napi);
}
}
@@ -1825,6 +1830,7 @@ bnad_setup_rx(struct bnad *bnad, uint rx_id)
/* Initialize the Rx event handlers */
rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup;
+ rx_cbfn.rcb_destroy_cbfn = bnad_cb_rcb_destroy;
rx_cbfn.rcb_destroy_cbfn = NULL;
rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup;
rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy;
@@ -1968,6 +1974,27 @@ bnad_enable_default_bcast(struct bnad *bnad)
return 0;
}
+/* Called with bnad_conf_lock() held */
+static void
+bnad_restore_vlans(struct bnad *bnad, u32 rx_id)
+{
+ u16 vlan_id;
+ unsigned long flags;
+
+ if (!bnad->vlan_grp)
+ return;
+
+ BUG_ON(!(VLAN_N_VID == (BFI_MAX_VLAN + 1)));
+
+ for (vlan_id = 0; vlan_id < VLAN_N_VID; vlan_id++) {
+ if (!vlan_group_get_device(bnad->vlan_grp, vlan_id))
+ continue;
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vlan_id);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ }
+}
+
/* Statistics utilities */
void
bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
@@ -2152,16 +2179,6 @@ bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
bnad->num_rxp_per_rx = 1;
}
-static void
-bnad_set_netdev_perm_addr(struct bnad *bnad)
-{
- struct net_device *netdev = bnad->netdev;
-
- memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len);
- if (is_zero_ether_addr(netdev->dev_addr))
- memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len);
-}
-
/* Enable / disable device */
static void
bnad_device_disable(struct bnad *bnad)
@@ -2353,6 +2370,9 @@ bnad_open(struct net_device *netdev)
/* Enable broadcast */
bnad_enable_default_bcast(bnad);
+ /* Restore VLANs, if any */
+ bnad_restore_vlans(bnad, 0);
+
/* Set the UCAST address */
spin_lock_irqsave(&bnad->bna_lock, flags);
bnad_mac_addr_set_locked(bnad, netdev->dev_addr);
@@ -2433,21 +2453,21 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
+ tx_id = 0;
+
+ tx_info = &bnad->tx_info[tx_id];
+ tcb = tx_info->tcb[tx_id];
+ unmap_q = tcb->unmap_q;
+
/*
* Takes care of the Tx that is scheduled between clearing the flag
* and the netif_stop_queue() call.
*/
- if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) {
+ if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
- tx_id = 0;
-
- tx_info = &bnad->tx_info[tx_id];
- tcb = tx_info->tcb[tx_id];
- unmap_q = tcb->unmap_q;
-
vectors = 1 + skb_shinfo(skb)->nr_frags;
if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) {
dev_kfree_skb(skb);
@@ -2462,7 +2482,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
tcb->consumer_index &&
!test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
acked = bnad_free_txbufs(bnad, tcb);
- bna_ib_ack(tcb->i_dbell, acked);
+ if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
+ bna_ib_ack(tcb->i_dbell, acked);
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
} else {
@@ -2624,6 +2645,10 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
tcb->producer_index = txq_prod;
smp_mb();
+
+ if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
+ return NETDEV_TX_OK;
+
bna_txq_prod_indx_doorbell(tcb);
if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
@@ -3032,7 +3057,7 @@ static int __devinit
bnad_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pcidev_id)
{
- bool using_dac;
+ bool using_dac = false;
int err;
struct bnad *bnad;
struct bna *bna;
@@ -3066,7 +3091,7 @@ bnad_pci_probe(struct pci_dev *pdev,
/*
* PCI initialization
* Output : using_dac = 1 for 64 bit DMA
- * = 0 for 32 bit DMA
+ * = 0 for 32 bit DMA
*/
err = bnad_pci_init(bnad, pdev, &using_dac);
if (err)
@@ -3084,6 +3109,9 @@ bnad_pci_probe(struct pci_dev *pdev,
/* Initialize netdev structure, set up ethtool ops */
bnad_netdev_init(bnad, using_dac);
+ /* Set link to down state */
+ netif_carrier_off(netdev);
+
bnad_enable_msix(bnad);
/* Get resource requirement form bna */
@@ -3115,11 +3143,13 @@ bnad_pci_probe(struct pci_dev *pdev,
((unsigned long)bnad));
setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check,
((unsigned long)bnad));
- setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout,
+ setup_timer(&bnad->bna.device.ioc.iocpf_timer, bnad_iocpf_timeout,
+ ((unsigned long)bnad));
+ setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_iocpf_sem_timeout,
((unsigned long)bnad));
/* Now start the timer before calling IOC */
- mod_timer(&bnad->bna.device.ioc.ioc_timer,
+ mod_timer(&bnad->bna.device.ioc.iocpf_timer,
jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ));
/*
@@ -3137,11 +3167,6 @@ bnad_pci_probe(struct pci_dev *pdev,
mutex_unlock(&bnad->conf_mutex);
- /*
- * Make sure the link appears down to the stack
- */
- netif_carrier_off(netdev);
-
/* Finally, reguister with net_device layer */
err = register_netdev(netdev);
if (err) {
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index ebc3a9078642..8b1d51557def 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -51,6 +51,7 @@
*/
struct bnad_rx_ctrl {
struct bna_ccb *ccb;
+ unsigned long flags;
struct napi_struct napi;
};
@@ -64,7 +65,7 @@ struct bnad_rx_ctrl {
#define BNAD_NAME "bna"
#define BNAD_NAME_LEN 64
-#define BNAD_VERSION "2.3.2.0"
+#define BNAD_VERSION "2.3.2.3"
#define BNAD_MAILBOX_MSIX_VECTORS 1
@@ -82,6 +83,7 @@ struct bnad_rx_ctrl {
/* Bit positions for tcb->flags */
#define BNAD_TXQ_FREE_SENT 0
+#define BNAD_TXQ_TX_STARTED 1
/* Bit positions for rcb->flags */
#define BNAD_RXQ_REFILL 0
@@ -124,6 +126,7 @@ struct bnad_completion {
struct bnad_drv_stats {
u64 netif_queue_stop;
u64 netif_queue_wakeup;
+ u64 netif_queue_stopped;
u64 tso4;
u64 tso6;
u64 tso_err;
@@ -199,12 +202,12 @@ struct bnad_unmap_q {
/* Set, tested & cleared using xxx_bit() functions */
/* Values indicated bit positions */
#define BNAD_RF_CEE_RUNNING 1
-#define BNAD_RF_HW_ERROR 2
-#define BNAD_RF_MBOX_IRQ_DISABLED 3
-#define BNAD_RF_TX_STARTED 4
-#define BNAD_RF_RX_STARTED 5
-#define BNAD_RF_DIM_TIMER_RUNNING 6
-#define BNAD_RF_STATS_TIMER_RUNNING 7
+#define BNAD_RF_MBOX_IRQ_DISABLED 2
+#define BNAD_RF_RX_STARTED 3
+#define BNAD_RF_DIM_TIMER_RUNNING 4
+#define BNAD_RF_STATS_TIMER_RUNNING 5
+#define BNAD_RF_TX_SHUTDOWN_DELAYED 6
+#define BNAD_RF_RX_SHUTDOWN_DELAYED 7
struct bnad {
struct net_device *netdev;
@@ -306,8 +309,10 @@ extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id);
extern void bnad_dim_timer_start(struct bnad *bnad);
/* Statistics */
-extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
-extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
+extern void bnad_netdev_qstats_fill(struct bnad *bnad,
+ struct rtnl_link_stats64 *stats);
+extern void bnad_netdev_hwstats_fill(struct bnad *bnad,
+ struct rtnl_link_stats64 *stats);
/**
* MACROS
@@ -320,9 +325,11 @@ extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64
#define bnad_enable_rx_irq_unsafe(_ccb) \
{ \
- bna_ib_coalescing_timer_set((_ccb)->i_dbell, \
- (_ccb)->rx_coalescing_timeo); \
- bna_ib_ack((_ccb)->i_dbell, 0); \
+ if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) {\
+ bna_ib_coalescing_timer_set((_ccb)->i_dbell, \
+ (_ccb)->rx_coalescing_timeo); \
+ bna_ib_ack((_ccb)->i_dbell, 0); \
+ } \
}
#define bnad_dim_timer_running(_bnad) \
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
index 11fa2ea842c1..99be5ae91991 100644
--- a/drivers/net/bna/bnad_ethtool.c
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -68,6 +68,7 @@ static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
"netif_queue_stop",
"netif_queue_wakeup",
+ "netif_queue_stopped",
"tso4",
"tso6",
"tso_err",
@@ -330,10 +331,6 @@ do { \
BNAD_GET_REG(PCIE_MISC_REG);
- BNAD_GET_REG(HOST_SEM0_REG);
- BNAD_GET_REG(HOST_SEM1_REG);
- BNAD_GET_REG(HOST_SEM2_REG);
- BNAD_GET_REG(HOST_SEM3_REG);
BNAD_GET_REG(HOST_SEM0_INFO_REG);
BNAD_GET_REG(HOST_SEM1_INFO_REG);
BNAD_GET_REG(HOST_SEM2_INFO_REG);
@@ -1184,6 +1181,9 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
bi = sizeof(*net_stats64) / sizeof(u64);
+ /* Get netif_queue_stopped from stack */
+ bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev);
+
/* Fill driver stats into ethtool buffers */
stats64 = (u64 *)&bnad->stats.drv_stats;
for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 062600be073b..df99edf3464a 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,11 +56,11 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.0.18"
-#define DRV_MODULE_RELDATE "Oct 7, 2010"
-#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw"
+#define DRV_MODULE_VERSION "2.0.21"
+#define DRV_MODULE_RELDATE "Dec 23, 2010"
+#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
-#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw"
+#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1.fw"
#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw"
@@ -766,13 +766,10 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
int j;
rxr->rx_buf_ring =
- vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
+ vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
if (rxr->rx_buf_ring == NULL)
return -ENOMEM;
- memset(rxr->rx_buf_ring, 0,
- SW_RXBD_RING_SIZE * bp->rx_max_ring);
-
for (j = 0; j < bp->rx_max_ring; j++) {
rxr->rx_desc_ring[j] =
dma_alloc_coherent(&bp->pdev->dev,
@@ -785,13 +782,11 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
}
if (bp->rx_pg_ring_size) {
- rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
+ rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE *
bp->rx_max_pg_ring);
if (rxr->rx_pg_ring == NULL)
return -ENOMEM;
- memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
- bp->rx_max_pg_ring);
}
for (j = 0; j < bp->rx_max_pg_ring; j++) {
@@ -4645,13 +4640,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Wait for the current PCI transaction to complete before
* issuing a reset. */
- REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
- BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
- val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
- udelay(5);
+ if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+ (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+ REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+ BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+ val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+ udelay(5);
+ } else { /* 5709 */
+ val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+ val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+ REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+ val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+
+ for (i = 0; i < 100; i++) {
+ msleep(1);
+ val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL);
+ if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND))
+ break;
+ }
+ }
/* Wait for the firmware to tell us it is ok to issue a reset. */
bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
@@ -4673,7 +4683,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
+ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
} else {
val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
@@ -6086,7 +6096,7 @@ bnx2_request_irq(struct bnx2 *bp)
}
static void
-bnx2_free_irq(struct bnx2 *bp)
+__bnx2_free_irq(struct bnx2 *bp)
{
struct bnx2_irq *irq;
int i;
@@ -6097,6 +6107,13 @@ bnx2_free_irq(struct bnx2 *bp)
free_irq(irq->vector, &bp->bnx2_napi[i]);
irq->requested = 0;
}
+}
+
+static void
+bnx2_free_irq(struct bnx2 *bp)
+{
+
+ __bnx2_free_irq(bp);
if (bp->flags & BNX2_FLAG_USING_MSI)
pci_disable_msi(bp->pdev);
else if (bp->flags & BNX2_FLAG_USING_MSIX)
@@ -6801,28 +6818,30 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
u32 *p = _p, i, offset;
u8 *orig_p = _p;
struct bnx2 *bp = netdev_priv(dev);
- u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c,
- 0x0800, 0x0880, 0x0c00, 0x0c10,
- 0x0c30, 0x0d08, 0x1000, 0x101c,
- 0x1040, 0x1048, 0x1080, 0x10a4,
- 0x1400, 0x1490, 0x1498, 0x14f0,
- 0x1500, 0x155c, 0x1580, 0x15dc,
- 0x1600, 0x1658, 0x1680, 0x16d8,
- 0x1800, 0x1820, 0x1840, 0x1854,
- 0x1880, 0x1894, 0x1900, 0x1984,
- 0x1c00, 0x1c0c, 0x1c40, 0x1c54,
- 0x1c80, 0x1c94, 0x1d00, 0x1d84,
- 0x2000, 0x2030, 0x23c0, 0x2400,
- 0x2800, 0x2820, 0x2830, 0x2850,
- 0x2b40, 0x2c10, 0x2fc0, 0x3058,
- 0x3c00, 0x3c94, 0x4000, 0x4010,
- 0x4080, 0x4090, 0x43c0, 0x4458,
- 0x4c00, 0x4c18, 0x4c40, 0x4c54,
- 0x4fc0, 0x5010, 0x53c0, 0x5444,
- 0x5c00, 0x5c18, 0x5c80, 0x5c90,
- 0x5fc0, 0x6000, 0x6400, 0x6428,
- 0x6800, 0x6848, 0x684c, 0x6860,
- 0x6888, 0x6910, 0x8000 };
+ static const u32 reg_boundaries[] = {
+ 0x0000, 0x0098, 0x0400, 0x045c,
+ 0x0800, 0x0880, 0x0c00, 0x0c10,
+ 0x0c30, 0x0d08, 0x1000, 0x101c,
+ 0x1040, 0x1048, 0x1080, 0x10a4,
+ 0x1400, 0x1490, 0x1498, 0x14f0,
+ 0x1500, 0x155c, 0x1580, 0x15dc,
+ 0x1600, 0x1658, 0x1680, 0x16d8,
+ 0x1800, 0x1820, 0x1840, 0x1854,
+ 0x1880, 0x1894, 0x1900, 0x1984,
+ 0x1c00, 0x1c0c, 0x1c40, 0x1c54,
+ 0x1c80, 0x1c94, 0x1d00, 0x1d84,
+ 0x2000, 0x2030, 0x23c0, 0x2400,
+ 0x2800, 0x2820, 0x2830, 0x2850,
+ 0x2b40, 0x2c10, 0x2fc0, 0x3058,
+ 0x3c00, 0x3c94, 0x4000, 0x4010,
+ 0x4080, 0x4090, 0x43c0, 0x4458,
+ 0x4c00, 0x4c18, 0x4c40, 0x4c54,
+ 0x4fc0, 0x5010, 0x53c0, 0x5444,
+ 0x5c00, 0x5c18, 0x5c80, 0x5c90,
+ 0x5fc0, 0x6000, 0x6400, 0x6428,
+ 0x6800, 0x6848, 0x684c, 0x6860,
+ 0x6888, 0x6910, 0x8000
+ };
regs->version = 0;
@@ -7080,6 +7099,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+ __bnx2_free_irq(bp);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
}
@@ -7092,6 +7112,9 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
rc = bnx2_alloc_mem(bp);
if (!rc)
+ rc = bnx2_request_irq(bp);
+
+ if (!rc)
rc = bnx2_init_nic(bp, 0);
if (rc) {
@@ -7914,15 +7937,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_release;
}
+ bnx2_set_power_state(bp, PCI_D0);
+
/* Configure byte swap and enable write to the reg_window registers.
* Rely on CPU to do target byte swapping on big endian systems
* The chip's target access swapping will not swap all accesses
*/
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
- BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
- BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
-
- bnx2_set_power_state(bp, PCI_D0);
+ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG,
+ BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
@@ -8383,8 +8406,6 @@ bnx2_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
- flush_scheduled_work();
-
unregister_netdev(dev);
if (bp->mips_firmware)
@@ -8421,7 +8442,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
if (!netif_running(dev))
return 0;
- flush_scheduled_work();
+ cancel_work_sync(&bp->reset_task);
bnx2_netif_stop(bp, true);
netif_device_detach(dev);
del_timer_sync(&bp->timer);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index bf4c3421067d..5488a2e82fe9 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -461,6 +461,8 @@ struct l2_fhdr {
#define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090
#define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094
+#define BNX2_PCICFG_DEVICE_CONTROL 0x000000b4
+#define BNX2_PCICFG_DEVICE_STATUS_NO_PEND ((1L<<5)<<16)
/*
* pci_reg definition
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index 084afce89ae9..bb83a2961273 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_BNX2X) += bnx2x.o
-bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o
+bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 863e73a85fbe..77d6c8d6d86b 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -13,6 +13,8 @@
#ifndef BNX2X_H
#define BNX2X_H
+#include <linux/netdevice.h>
+#include <linux/types.h>
/* compilation time flags */
@@ -20,15 +22,17 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.60.00-4"
-#define DRV_MODULE_RELDATE "2010/11/01"
+#define DRV_MODULE_VERSION "1.62.00-3"
+#define DRV_MODULE_RELDATE "2010/12/21"
#define BNX2X_BC_VER 0x040200
#define BNX2X_MULTI_QUEUE
#define BNX2X_NEW_NAPI
-
+#if defined(CONFIG_DCB)
+#define BCM_DCB
+#endif
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
#include "../cnic_if.h"
@@ -48,6 +52,7 @@
#include "bnx2x_fw_defs.h"
#include "bnx2x_hsi.h"
#include "bnx2x_link.h"
+#include "bnx2x_dcb.h"
#include "bnx2x_stats.h"
/* error/debug prints */
@@ -199,10 +204,25 @@ void bnx2x_panic_dump(struct bnx2x *bp);
/* EQ completions */
#define HC_SP_INDEX_EQ_CONS 7
+/* FCoE L2 connection completions */
+#define HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS 6
+#define HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS 4
/* iSCSI L2 */
#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5
#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1
+/* Special clients parameters */
+
+/* SB indices */
+/* FCoE L2 */
+#define BNX2X_FCOE_L2_RX_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS])
+
+#define BNX2X_FCOE_L2_TX_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS])
+
/**
* CIDs and CLIDs:
* CLIDs below is a CLID for func 0, then the CLID for other
@@ -215,12 +235,19 @@ void bnx2x_panic_dump(struct bnx2x *bp);
#define BNX2X_ISCSI_ETH_CL_ID 17
#define BNX2X_ISCSI_ETH_CID 17
+/* FCoE L2 */
+#define BNX2X_FCOE_ETH_CL_ID 18
+#define BNX2X_FCOE_ETH_CID 18
+
/** Additional rings budgeting */
#ifdef BCM_CNIC
#define CNIC_CONTEXT_USE 1
+#define FCOE_CONTEXT_USE 1
#else
#define CNIC_CONTEXT_USE 0
+#define FCOE_CONTEXT_USE 0
#endif /* BCM_CNIC */
+#define NONE_ETH_CONTEXT_USE (FCOE_CONTEXT_USE)
#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
@@ -401,6 +428,17 @@ struct bnx2x_fastpath {
};
#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
+#ifdef BCM_CNIC
+/* FCoE L2 `fastpath' is right after the eth entries */
+#define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp)
+#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX])
+#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var)
+#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX)
+#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX)
+#else
+#define IS_FCOE_FP(fp) false
+#define IS_FCOE_IDX(idx) false
+#endif
/* MC hsi */
@@ -669,8 +707,14 @@ struct bnx2x_port {
enum {
CAM_ETH_LINE = 0,
CAM_ISCSI_ETH_LINE,
- CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE
+ CAM_FIP_ETH_LINE,
+ CAM_FIP_MCAST_LINE,
+ CAM_MAX_PF_LINE = CAM_FIP_MCAST_LINE
};
+/* number of MACs per function in NIG memory - used for SI mode */
+#define NIG_LLH_FUNC_MEM_SIZE 16
+/* number of entries in NIG_REG_LLHX_FUNC_MEM */
+#define NIG_LLH_FUNC_MEM_MAX_OFFSET 8
#define BNX2X_VF_ID_INVALID 0xFF
@@ -710,6 +754,14 @@ enum {
*/
#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE)
+/*
+ * The number of FP-SB allocated by the driver == max number of regular L2
+ * queues + 1 for the CNIC which also consumes an FP-SB
+ */
+#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE)
+#define NUM_IGU_SB_REQUIRED(cid_cnt) \
+ (FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE)
+
union cdu_context {
struct eth_context eth;
char pad[1024];
@@ -722,7 +774,8 @@ union cdu_context {
#ifdef BCM_CNIC
#define CNIC_ISCSI_CID_MAX 256
-#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX)
+#define CNIC_FCOE_CID_MAX 2048
+#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX)
#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS)
#endif
@@ -770,6 +823,8 @@ struct bnx2x_slowpath {
u32 wb_comp;
u32 wb_data[4];
+ /* pfc configuration for DCBX ramrod */
+ struct flow_control_configuration pfc_config;
};
#define bnx2x_sp(bp, var) (&bp->slowpath->var)
@@ -918,6 +973,10 @@ struct bnx2x {
#define DISABLE_MSI_FLAG 0x200
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
#define MF_FUNC_DIS 0x1000
+#define FCOE_MACS_SET 0x2000
+#define NO_FCOE_FLAG 0x4000
+
+#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG)
int pf_num; /* absolute PF number */
int pfid; /* per-path PF number */
@@ -967,6 +1026,8 @@ struct bnx2x {
u16 mf_ov;
u8 mf_mode;
#define IS_MF(bp) (bp->mf_mode != 0)
+#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI)
+#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD)
u8 wol;
@@ -1010,6 +1071,7 @@ struct bnx2x {
#define BNX2X_ACCEPT_ALL_UNICAST 0x0004
#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008
#define BNX2X_ACCEPT_BROADCAST 0x0010
+#define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020
#define BNX2X_PROMISCUOUS_MODE 0x10000
u32 rx_mode;
@@ -1062,7 +1124,8 @@ struct bnx2x {
u16 cnic_kwq_pending;
u16 cnic_spq_pending;
struct mutex cnic_mutex;
- u8 iscsi_mac[6];
+ u8 iscsi_mac[ETH_ALEN];
+ u8 fip_mac[ETH_ALEN];
#endif
int dmae_ready;
@@ -1122,6 +1185,31 @@ struct bnx2x {
char fw_ver[32];
const struct firmware *firmware;
+ /* LLDP params */
+ struct bnx2x_config_lldp_params lldp_config_params;
+
+ /* DCB support on/off */
+ u16 dcb_state;
+#define BNX2X_DCB_STATE_OFF 0
+#define BNX2X_DCB_STATE_ON 1
+
+ /* DCBX engine mode */
+ int dcbx_enabled;
+#define BNX2X_DCBX_ENABLED_OFF 0
+#define BNX2X_DCBX_ENABLED_ON_NEG_OFF 1
+#define BNX2X_DCBX_ENABLED_ON_NEG_ON 2
+#define BNX2X_DCBX_ENABLED_INVALID (-1)
+
+ bool dcbx_mode_uset;
+
+ struct bnx2x_config_dcbx_params dcbx_config_params;
+
+ struct bnx2x_dcbx_port_params dcbx_port_params;
+ int dcb_version;
+
+ /* DCBX Negotation results */
+ struct dcbx_features dcbx_local_feat;
+ u32 dcbx_error;
};
/**
@@ -1152,10 +1240,17 @@ struct bnx2x {
#define RSS_IPV6_TCP_CAP 0x0008
#define BNX2X_NUM_QUEUES(bp) (bp->num_queues)
+#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE)
+
+/* ethtool statistics are displayed for all regular ethernet queues and the
+ * fcoe L2 queue if not disabled
+ */
+#define BNX2X_NUM_STAT_QUEUES(bp) (NO_FCOE(bp) ? BNX2X_NUM_ETH_QUEUES(bp) : \
+ (BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE))
+
#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE)
-#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1)
#define RSS_IPV4_CAP_MASK \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY
@@ -1248,6 +1343,7 @@ struct bnx2x_client_ramrod_params {
u16 cl_id;
u32 cid;
u8 poll;
+#define CLIENT_IS_FCOE 0x01
#define CLIENT_IS_LEADING_RSS 0x02
u8 flags;
};
@@ -1280,11 +1376,54 @@ struct bnx2x_func_init_params {
u16 spq_prod; /* valid iff FUNC_FLG_SPQ */
};
+#define for_each_eth_queue(bp, var) \
+ for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++)
+
+#define for_each_nondefault_eth_queue(bp, var) \
+ for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++)
+
+#define for_each_napi_queue(bp, var) \
+ for (var = 0; \
+ var < BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE; var++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
#define for_each_queue(bp, var) \
- for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
+ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_rx_queue(bp, var) \
+ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \
+ if (skip_rx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_tx_queue(bp, var) \
+ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \
+ if (skip_tx_queue(bp, var)) \
+ continue; \
+ else
+
#define for_each_nondefault_queue(bp, var) \
- for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
+ for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
+/* skip rx queue
+ * if FCOE l2 support is diabled and this is the fcoe L2 queue
+ */
+#define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+/* skip tx queue
+ * if FCOE l2 support is diabled and this is the fcoe L2 queue
+ */
+#define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+
+#define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
#define WAIT_RAMROD_POLL 0x01
#define WAIT_RAMROD_COMMON 0x02
@@ -1329,7 +1468,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define BNX2X_ILT_ZALLOC(x, y, size) \
do { \
- x = pci_alloc_consistent(bp->pdev, size, y); \
+ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
if (x) \
memset(x, 0, size); \
} while (0)
@@ -1337,7 +1476,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define BNX2X_ILT_FREE(x, y, size) \
do { \
if (x) { \
- pci_free_consistent(bp->pdev, size, x, y); \
+ dma_free_coherent(&bp->pdev->dev, size, x, y); \
x = NULL; \
y = 0; \
} \
@@ -1608,10 +1747,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \
(T_ETH_MAC_COMMAND_INVALIDATE))
-#define CAM_INVALIDATE(x) \
- (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
-
-
/* Number of u32 elements in MC hash array */
#define MC_HASH_SIZE 8
#define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 94d5f59d5a6f..710ce5d04c53 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -698,6 +698,29 @@ void bnx2x_release_phy_lock(struct bnx2x *bp)
mutex_unlock(&bp->port.phy_mutex);
}
+/* calculates MF speed according to current linespeed and MF configuration */
+u16 bnx2x_get_mf_speed(struct bnx2x *bp)
+{
+ u16 line_speed = bp->link_vars.line_speed;
+ if (IS_MF(bp)) {
+ u16 maxCfg = (bp->mf_config[BP_VN(bp)] &
+ FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT;
+ /* Calculate the current MAX line speed limit for the DCC
+ * capable devices
+ */
+ if (IS_MF_SD(bp)) {
+ u16 vn_max_rate = maxCfg * 100;
+
+ if (vn_max_rate < line_speed)
+ line_speed = vn_max_rate;
+ } else /* IS_MF_SI(bp)) */
+ line_speed = (line_speed * maxCfg) / 100;
+ }
+
+ return line_speed;
+}
+
void bnx2x_link_report(struct bnx2x *bp)
{
if (bp->flags & MF_FUNC_DIS) {
@@ -713,17 +736,8 @@ void bnx2x_link_report(struct bnx2x *bp)
netif_carrier_on(bp->dev);
netdev_info(bp->dev, "NIC Link is Up, ");
- line_speed = bp->link_vars.line_speed;
- if (IS_MF(bp)) {
- u16 vn_max_rate;
+ line_speed = bnx2x_get_mf_speed(bp);
- vn_max_rate =
- ((bp->mf_config[BP_VN(bp)] &
- FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
- if (vn_max_rate < line_speed)
- line_speed = vn_max_rate;
- }
pr_cont("%d Mbps ", line_speed);
if (bp->link_vars.duplex == DUPLEX_FULL)
@@ -813,7 +827,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
DP(NETIF_MSG_IFUP,
"mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
if (!fp->disable_tpa) {
@@ -866,7 +880,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
}
}
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
fp->rx_bd_cons = 0;
@@ -897,7 +911,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
u16 bd_cons = fp->tx_bd_cons;
@@ -915,7 +929,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 0; i < NUM_RX_BD; i++) {
@@ -956,7 +970,7 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
#ifdef BCM_CNIC
offset++;
#endif
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
"state %x\n", i, bp->msix_table[i + offset].vector,
bnx2x_fp(bp, i, state));
@@ -990,14 +1004,14 @@ int bnx2x_enable_msix(struct bnx2x *bp)
bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry);
msix_vec++;
#endif
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
bp->msix_table[msix_vec].entry = msix_vec;
DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
"(fastpath #%u)\n", msix_vec, msix_vec, i);
msix_vec++;
}
- req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1;
+ req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_CONTEXT_USE + 1;
rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt);
@@ -1053,7 +1067,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
#ifdef BCM_CNIC
offset++;
#endif
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
bp->dev->name, i);
@@ -1070,7 +1084,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
fp->state = BNX2X_FP_STATE_IRQ;
}
- i = BNX2X_NUM_QUEUES(bp);
+ i = BNX2X_NUM_ETH_QUEUES(bp);
offset = 1 + CNIC_CONTEXT_USE;
netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d"
" ... fp[%d] %d\n",
@@ -1117,7 +1131,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_napi_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
}
@@ -1125,7 +1139,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_napi_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
}
@@ -1153,6 +1167,35 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
netif_tx_disable(bp->dev);
}
+u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+#ifdef BCM_CNIC
+ struct bnx2x *bp = netdev_priv(dev);
+ if (NO_FCOE(bp))
+ return skb_tx_hash(dev, skb);
+ else {
+ struct ethhdr *hdr = (struct ethhdr *)skb->data;
+ u16 ether_type = ntohs(hdr->h_proto);
+
+ /* Skip VLAN tag if present */
+ if (ether_type == ETH_P_8021Q) {
+ struct vlan_ethhdr *vhdr =
+ (struct vlan_ethhdr *)skb->data;
+
+ ether_type = ntohs(vhdr->h_vlan_encapsulated_proto);
+ }
+
+ /* If ethertype is FCoE or FIP - use FCoE ring */
+ if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP))
+ return bnx2x_fcoe(bp, index);
+ }
+#endif
+ /* Select a none-FCoE queue: if FCoE is enabled, exclude FCoE L2 ring
+ */
+ return __skb_tx_hash(dev, skb,
+ dev->real_num_tx_queues - FCOE_CONTEXT_USE);
+}
+
void bnx2x_set_num_queues(struct bnx2x *bp)
{
switch (bp->multi_mode) {
@@ -1167,8 +1210,23 @@ void bnx2x_set_num_queues(struct bnx2x *bp)
bp->num_queues = 1;
break;
}
+
+ /* Add special queues */
+ bp->num_queues += NONE_ETH_CONTEXT_USE;
}
+#ifdef BCM_CNIC
+static inline void bnx2x_set_fcoe_eth_macs(struct bnx2x *bp)
+{
+ if (!NO_FCOE(bp)) {
+ if (!IS_MF_SD(bp))
+ bnx2x_set_fip_eth_mac_addr(bp, 1);
+ bnx2x_set_all_enode_macs(bp, 1);
+ bp->flags |= FCOE_MACS_SET;
+ }
+}
+#endif
+
static void bnx2x_release_firmware(struct bnx2x *bp)
{
kfree(bp->init_ops_offsets);
@@ -1177,6 +1235,20 @@ static void bnx2x_release_firmware(struct bnx2x *bp)
release_firmware(bp->firmware);
}
+static inline int bnx2x_set_real_num_queues(struct bnx2x *bp)
+{
+ int rc, num = bp->num_queues;
+
+#ifdef BCM_CNIC
+ if (NO_FCOE(bp))
+ num -= FCOE_CONTEXT_USE;
+
+#endif
+ netif_set_real_num_tx_queues(bp->dev, num);
+ rc = netif_set_real_num_rx_queues(bp->dev, num);
+ return rc;
+}
+
/* must be called with rtnl_lock */
int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
@@ -1203,10 +1275,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
- netif_set_real_num_tx_queues(bp->dev, bp->num_queues);
- rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues);
+ rc = bnx2x_set_real_num_queues(bp);
if (rc) {
- BNX2X_ERR("Unable to update real_num_rx_queues\n");
+ BNX2X_ERR("Unable to set real_num_queues\n");
goto load_error0;
}
@@ -1214,6 +1285,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_fp(bp, i, disable_tpa) =
((bp->flags & TPA_ENABLE_FLAG) == 0);
+#ifdef BCM_CNIC
+ /* We don't want TPA on FCoE L2 ring */
+ bnx2x_fcoe(bp, disable_tpa) = 1;
+#endif
bnx2x_napi_enable(bp);
/* Send LOAD_REQUEST command to MCP
@@ -1296,6 +1371,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
}
}
+ bnx2x_dcbx_init(bp);
+
bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
rc = bnx2x_func_start(bp);
@@ -1344,6 +1421,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/* Now when Clients are configured we are ready to work */
bp->state = BNX2X_STATE_OPEN;
+#ifdef BCM_CNIC
+ bnx2x_set_fcoe_eth_macs(bp);
+#endif
+
bnx2x_set_eth_mac(bp, 1);
if (bp->port.pmf)
@@ -1402,7 +1483,7 @@ load_error3:
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
/* Release IRQs */
@@ -1473,7 +1554,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
bnx2x_free_mem(bp);
@@ -1577,6 +1658,17 @@ int bnx2x_poll(struct napi_struct *napi, int budget)
/* Fall out from the NAPI loop if needed */
if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+#ifdef BCM_CNIC
+ /* No need to update SB for FCoE L2 ring as long as
+ * it's connected to the default SB and the SB
+ * has been updated when NAPI was scheduled.
+ */
+ if (IS_FCOE_FP(fp)) {
+ napi_complete(napi);
+ break;
+ }
+#endif
+
bnx2x_update_fpsb_idx(fp);
/* bnx2x_has_rx_work() reads the status block,
* thus we need to ensure that status block indices
@@ -1692,11 +1784,10 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
}
}
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
- rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP);
-
- else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
- rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6);
+ if (skb_is_gso_v6(skb))
+ rc |= XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6;
+ else if (skb_is_gso(skb))
+ rc |= XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP;
return rc;
}
@@ -1782,15 +1873,15 @@ exit_lbl:
}
#endif
-static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
- struct eth_tx_parse_bd_e2 *pbd,
- u32 xmit_type)
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+ u32 xmit_type)
{
- pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
- ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+ *parsing_data |= (skb_shinfo(skb)->gso_size <<
+ ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+ ETH_TX_PARSE_BD_E2_LSO_MSS;
if ((xmit_type & XMIT_GSO_V6) &&
(ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
- pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+ *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
}
/**
@@ -1835,15 +1926,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
* @return header len
*/
static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
- struct eth_tx_parse_bd_e2 *pbd,
- u32 xmit_type)
+ u32 *parsing_data, u32 xmit_type)
{
- pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
- ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+ *parsing_data |= ((tcp_hdrlen(skb)/4) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
- pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
- skb->data) / 2) <<
- ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+ *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
}
@@ -1912,6 +2003,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+ u32 pbd_e2_parsing_data = 0;
u16 pkt_prod, bd_prod;
int nbd, fp_index;
dma_addr_t mapping;
@@ -2033,8 +2125,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
/* Set PBD in checksum offload case */
if (xmit_type & XMIT_CSUM)
- hlen = bnx2x_set_pbd_csum_e2(bp,
- skb, pbd_e2, xmit_type);
+ hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+ &pbd_e2_parsing_data,
+ xmit_type);
} else {
pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
@@ -2076,10 +2169,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
hlen, bd_prod, ++nbd);
if (CHIP_IS_E2(bp))
- bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+ bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+ xmit_type);
else
bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
}
+
+ /* Set the PBD's parsing_data field if not zero
+ * (for the chips newer than 57711).
+ */
+ if (pbd_e2_parsing_data)
+ pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
/* Handle fragmented skb */
@@ -2232,7 +2333,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp)
bp->fp = fp;
/* msix table */
- tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl),
+ tbl = kzalloc((FP_SB_COUNT(bp->l2_cid_count) + 1) * sizeof(*tbl),
GFP_KERNEL);
if (!tbl)
goto alloc_err;
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 6b28739c5302..03eb4d68e6bb 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -73,6 +73,16 @@ void bnx2x__link_status_update(struct bnx2x *bp);
void bnx2x_link_report(struct bnx2x *bp);
/**
+ * calculates MF speed according to current linespeed and MF
+ * configuration
+ *
+ * @param bp
+ *
+ * @return u16
+ */
+u16 bnx2x_get_mf_speed(struct bnx2x *bp);
+
+/**
* MSI-X slowpath interrupt handler
*
* @param irq
@@ -232,6 +242,30 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
*/
void bnx2x_set_eth_mac(struct bnx2x *bp, int set);
+#ifdef BCM_CNIC
+/**
+ * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH
+ * MAC(s). This function will wait until the ramdord completion
+ * returns.
+ *
+ * @param bp driver handle
+ * @param set set or clear the CAM entry
+ *
+ * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ */
+int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set);
+
+/**
+ * Set/Clear ALL_ENODE mcast MAC.
+ *
+ * @param bp
+ * @param set
+ *
+ * @return int
+ */
+int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set);
+#endif
+
/**
* Set MAC filtering configurations.
*
@@ -290,6 +324,13 @@ int bnx2x_func_start(struct bnx2x *bp);
void bnx2x_ilt_set_info(struct bnx2x *bp);
/**
+ * Inintialize dcbx protocol
+ *
+ * @param bp
+ */
+void bnx2x_dcbx_init(struct bnx2x *bp);
+
+/**
* Set power state to the requested value. Currently only D0 and
* D3hot are supported.
*
@@ -309,6 +350,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode);
/* hard_xmit callback */
netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
+/* select_queue callback */
+u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
+
int bnx2x_change_mac_addr(struct net_device *dev, void *p);
/* NAPI poll Rx part */
@@ -685,7 +729,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp)
int i;
/* Add NAPI objects */
- for_each_queue(bp, i)
+ for_each_napi_queue(bp, i)
netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
bnx2x_poll, BNX2X_NAPI_WEIGHT);
}
@@ -694,7 +738,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_napi_queue(bp, i)
netif_napi_del(&bnx2x_fp(bp, i, napi));
}
@@ -860,7 +904,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_tx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -939,7 +983,30 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
}
}
+#ifdef BCM_CNIC
+static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
+{
+ bnx2x_fcoe(bp, cl_id) = BNX2X_FCOE_ETH_CL_ID +
+ BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE;
+ bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID;
+ bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID;
+ bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id;
+ bnx2x_fcoe(bp, bp) = bp;
+ bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED;
+ bnx2x_fcoe(bp, index) = FCOE_IDX;
+ bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX;
+ bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX;
+ /* qZone id equals to FW (per path) client id */
+ bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fcoe(bp, cl_id) +
+ BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 :
+ ETH_MAX_RX_CLIENTS_E1H);
+ /* init shortcut */
+ bnx2x_fcoe(bp, ustorm_rx_prods_offset) = CHIP_IS_E2(bp) ?
+ USTORM_RX_PRODS_E2_OFFSET(bnx2x_fcoe(bp, cl_qzone_id)) :
+ USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), bnx2x_fcoe_fp(bp)->cl_id);
+}
+#endif
static inline void __storm_memset_struct(struct bnx2x *bp,
u32 addr, size_t size, u32 *data)
diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c
new file mode 100644
index 000000000000..fb60021f81fb
--- /dev/null
+++ b/drivers/net/bnx2x/bnx2x_dcb.c
@@ -0,0 +1,2118 @@
+/* bnx2x_dcb.c: Broadcom Everest network driver.
+ *
+ * Copyright 2009-2010 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Dmitry Kravkov
+ *
+ */
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+
+#include "bnx2x.h"
+#include "bnx2x_cmn.h"
+#include "bnx2x_dcb.h"
+
+
+/* forward declarations of dcbx related functions */
+static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
+static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
+static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp);
+static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
+static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
+ u32 *set_configuration_ets_pg,
+ u32 *pri_pg_tbl);
+static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
+ u32 *pg_pri_orginal_spread,
+ struct pg_help_data *help_data);
+static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ u32 *pg_pri_orginal_spread);
+static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ struct dcbx_ets_feature *ets);
+static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp);
+
+
+static void bnx2x_pfc_set(struct bnx2x *bp)
+{
+ struct bnx2x_nig_brb_pfc_port_params pfc_params = {0};
+ u32 pri_bit, val = 0;
+ u8 pri;
+
+ /* Tx COS configuration */
+ if (bp->dcbx_port_params.ets.cos_params[0].pauseable)
+ pfc_params.rx_cos0_priority_mask =
+ bp->dcbx_port_params.ets.cos_params[0].pri_bitmask;
+ if (bp->dcbx_port_params.ets.cos_params[1].pauseable)
+ pfc_params.rx_cos1_priority_mask =
+ bp->dcbx_port_params.ets.cos_params[1].pri_bitmask;
+
+
+ /**
+ * Rx COS configuration
+ * Changing PFC RX configuration .
+ * In RX COS0 will always be configured to lossy and COS1 to lossless
+ */
+ for (pri = 0 ; pri < MAX_PFC_PRIORITIES ; pri++) {
+ pri_bit = 1 << pri;
+
+ if (pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp))
+ val |= 1 << (pri * 4);
+ }
+
+ pfc_params.pkt_priority_to_cos = val;
+
+ /* RX COS0 */
+ pfc_params.llfc_low_priority_classes = 0;
+ /* RX COS1 */
+ pfc_params.llfc_high_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp);
+
+ /* BRB configuration */
+ pfc_params.cos0_pauseable = false;
+ pfc_params.cos1_pauseable = true;
+
+ bnx2x_acquire_phy_lock(bp);
+ bp->link_params.feature_config_flags |= FEATURE_CONFIG_PFC_ENABLED;
+ bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &pfc_params);
+ bnx2x_release_phy_lock(bp);
+}
+
+static void bnx2x_pfc_clear(struct bnx2x *bp)
+{
+ struct bnx2x_nig_brb_pfc_port_params nig_params = {0};
+ nig_params.pause_enable = 1;
+#ifdef BNX2X_SAFC
+ if (bp->flags & SAFC_TX_FLAG) {
+ u32 high = 0, low = 0;
+ int i;
+
+ for (i = 0; i < BNX2X_MAX_PRIORITY; i++) {
+ if (bp->pri_map[i] == 1)
+ high |= (1 << i);
+ if (bp->pri_map[i] == 0)
+ low |= (1 << i);
+ }
+
+ nig_params.llfc_low_priority_classes = high;
+ nig_params.llfc_low_priority_classes = low;
+
+ nig_params.pause_enable = 0;
+ nig_params.llfc_enable = 1;
+ nig_params.llfc_out_en = 1;
+ }
+#endif /* BNX2X_SAFC */
+ bnx2x_acquire_phy_lock(bp);
+ bp->link_params.feature_config_flags &= ~FEATURE_CONFIG_PFC_ENABLED;
+ bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &nig_params);
+ bnx2x_release_phy_lock(bp);
+}
+
+static void bnx2x_dump_dcbx_drv_param(struct bnx2x *bp,
+ struct dcbx_features *features,
+ u32 error)
+{
+ u8 i = 0;
+ DP(NETIF_MSG_LINK, "local_mib.error %x\n", error);
+
+ /* PG */
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.enabled %x\n", features->ets.enabled);
+ for (i = 0; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++)
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.pg_bw_tbl[%d] %d\n", i,
+ DCBX_PG_BW_GET(features->ets.pg_bw_tbl, i));
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++)
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.pri_pg_tbl[%d] %d\n", i,
+ DCBX_PRI_PG_GET(features->ets.pri_pg_tbl, i));
+
+ /* pfc */
+ DP(NETIF_MSG_LINK, "dcbx_features.pfc.pri_en_bitmap %x\n",
+ features->pfc.pri_en_bitmap);
+ DP(NETIF_MSG_LINK, "dcbx_features.pfc.pfc_caps %x\n",
+ features->pfc.pfc_caps);
+ DP(NETIF_MSG_LINK, "dcbx_features.pfc.enabled %x\n",
+ features->pfc.enabled);
+
+ DP(NETIF_MSG_LINK, "dcbx_features.app.default_pri %x\n",
+ features->app.default_pri);
+ DP(NETIF_MSG_LINK, "dcbx_features.app.tc_supported %x\n",
+ features->app.tc_supported);
+ DP(NETIF_MSG_LINK, "dcbx_features.app.enabled %x\n",
+ features->app.enabled);
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+ DP(NETIF_MSG_LINK,
+ "dcbx_features.app.app_pri_tbl[%x].app_id %x\n",
+ i, features->app.app_pri_tbl[i].app_id);
+ DP(NETIF_MSG_LINK,
+ "dcbx_features.app.app_pri_tbl[%x].pri_bitmap %x\n",
+ i, features->app.app_pri_tbl[i].pri_bitmap);
+ DP(NETIF_MSG_LINK,
+ "dcbx_features.app.app_pri_tbl[%x].appBitfield %x\n",
+ i, features->app.app_pri_tbl[i].appBitfield);
+ }
+}
+
+static void bnx2x_dcbx_get_ap_priority(struct bnx2x *bp,
+ u8 pri_bitmap,
+ u8 llfc_traf_type)
+{
+ u32 pri = MAX_PFC_PRIORITIES;
+ u32 index = MAX_PFC_PRIORITIES - 1;
+ u32 pri_mask;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+
+ /* Choose the highest priority */
+ while ((MAX_PFC_PRIORITIES == pri) && (0 != index)) {
+ pri_mask = 1 << index;
+ if (GET_FLAGS(pri_bitmap, pri_mask))
+ pri = index ;
+ index--;
+ }
+
+ if (pri < MAX_PFC_PRIORITIES)
+ ttp[llfc_traf_type] = max_t(u32, ttp[llfc_traf_type], pri);
+}
+
+static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp,
+ struct dcbx_app_priority_feature *app,
+ u32 error) {
+ u8 index;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+
+ if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR))
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n");
+
+ if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) {
+
+ bp->dcbx_port_params.app.enabled = true;
+
+ for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++)
+ ttp[index] = 0;
+
+ if (app->default_pri < MAX_PFC_PRIORITIES)
+ ttp[LLFC_TRAFFIC_TYPE_NW] = app->default_pri;
+
+ for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) {
+ struct dcbx_app_priority_entry *entry =
+ app->app_pri_tbl;
+
+ if (GET_FLAGS(entry[index].appBitfield,
+ DCBX_APP_SF_ETH_TYPE) &&
+ ETH_TYPE_FCOE == entry[index].app_id)
+ bnx2x_dcbx_get_ap_priority(bp,
+ entry[index].pri_bitmap,
+ LLFC_TRAFFIC_TYPE_FCOE);
+
+ if (GET_FLAGS(entry[index].appBitfield,
+ DCBX_APP_SF_PORT) &&
+ TCP_PORT_ISCSI == entry[index].app_id)
+ bnx2x_dcbx_get_ap_priority(bp,
+ entry[index].pri_bitmap,
+ LLFC_TRAFFIC_TYPE_ISCSI);
+ }
+ } else {
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_DISABLED\n");
+ bp->dcbx_port_params.app.enabled = false;
+ for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++)
+ ttp[index] = INVALID_TRAFFIC_TYPE_PRIORITY;
+ }
+}
+
+static void bnx2x_dcbx_get_ets_feature(struct bnx2x *bp,
+ struct dcbx_ets_feature *ets,
+ u32 error) {
+ int i = 0;
+ u32 pg_pri_orginal_spread[DCBX_MAX_NUM_PG_BW_ENTRIES] = {0};
+ struct pg_help_data pg_help_data;
+ struct bnx2x_dcbx_cos_params *cos_params =
+ bp->dcbx_port_params.ets.cos_params;
+
+ memset(&pg_help_data, 0, sizeof(struct pg_help_data));
+
+
+ if (GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR))
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ERROR\n");
+
+
+ /* Clean up old settings of ets on COS */
+ for (i = 0; i < E2_NUM_OF_COS ; i++) {
+
+ cos_params[i].pauseable = false;
+ cos_params[i].strict = BNX2X_DCBX_COS_NOT_STRICT;
+ cos_params[i].bw_tbl = DCBX_INVALID_COS_BW;
+ cos_params[i].pri_bitmask = DCBX_PFC_PRI_GET_NON_PAUSE(bp, 0);
+ }
+
+ if (bp->dcbx_port_params.app.enabled &&
+ !GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR) &&
+ ets->enabled) {
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ENABLE\n");
+ bp->dcbx_port_params.ets.enabled = true;
+
+ bnx2x_dcbx_get_ets_pri_pg_tbl(bp,
+ pg_pri_orginal_spread,
+ ets->pri_pg_tbl);
+
+ bnx2x_dcbx_get_num_pg_traf_type(bp,
+ pg_pri_orginal_spread,
+ &pg_help_data);
+
+ bnx2x_dcbx_fill_cos_params(bp, &pg_help_data,
+ ets, pg_pri_orginal_spread);
+
+ } else {
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_DISABLED\n");
+ bp->dcbx_port_params.ets.enabled = false;
+ ets->pri_pg_tbl[0] = 0;
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES ; i++)
+ DCBX_PG_BW_SET(ets->pg_bw_tbl, i, 1);
+ }
+}
+
+static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp,
+ struct dcbx_pfc_feature *pfc, u32 error)
+{
+
+ if (GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR))
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n");
+
+ if (bp->dcbx_port_params.app.enabled &&
+ !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) &&
+ pfc->enabled) {
+ bp->dcbx_port_params.pfc.enabled = true;
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask =
+ ~(pfc->pri_en_bitmap);
+ } else {
+ DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_DISABLED\n");
+ bp->dcbx_port_params.pfc.enabled = false;
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask = 0;
+ }
+}
+
+static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp,
+ struct dcbx_features *features,
+ u32 error)
+{
+ bnx2x_dcbx_get_ap_feature(bp, &features->app, error);
+
+ bnx2x_dcbx_get_pfc_feature(bp, &features->pfc, error);
+
+ bnx2x_dcbx_get_ets_feature(bp, &features->ets, error);
+}
+
+#define DCBX_LOCAL_MIB_MAX_TRY_READ (100)
+static int bnx2x_dcbx_read_mib(struct bnx2x *bp,
+ u32 *base_mib_addr,
+ u32 offset,
+ int read_mib_type)
+{
+ int max_try_read = 0, i;
+ u32 *buff, mib_size, prefix_seq_num, suffix_seq_num;
+ struct lldp_remote_mib *remote_mib ;
+ struct lldp_local_mib *local_mib;
+
+
+ switch (read_mib_type) {
+ case DCBX_READ_LOCAL_MIB:
+ mib_size = sizeof(struct lldp_local_mib);
+ break;
+ case DCBX_READ_REMOTE_MIB:
+ mib_size = sizeof(struct lldp_remote_mib);
+ break;
+ default:
+ return 1; /*error*/
+ }
+
+ offset += BP_PORT(bp) * mib_size;
+
+ do {
+ buff = base_mib_addr;
+ for (i = 0; i < mib_size; i += 4, buff++)
+ *buff = REG_RD(bp, offset + i);
+
+ max_try_read++;
+
+ switch (read_mib_type) {
+ case DCBX_READ_LOCAL_MIB:
+ local_mib = (struct lldp_local_mib *) base_mib_addr;
+ prefix_seq_num = local_mib->prefix_seq_num;
+ suffix_seq_num = local_mib->suffix_seq_num;
+ break;
+ case DCBX_READ_REMOTE_MIB:
+ remote_mib = (struct lldp_remote_mib *) base_mib_addr;
+ prefix_seq_num = remote_mib->prefix_seq_num;
+ suffix_seq_num = remote_mib->suffix_seq_num;
+ break;
+ default:
+ return 1; /*error*/
+ }
+ } while ((prefix_seq_num != suffix_seq_num) &&
+ (max_try_read < DCBX_LOCAL_MIB_MAX_TRY_READ));
+
+ if (max_try_read >= DCBX_LOCAL_MIB_MAX_TRY_READ) {
+ BNX2X_ERR("MIB could not be read\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static void bnx2x_pfc_set_pfc(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp)) {
+ if (BP_PORT(bp)) {
+ BNX2X_ERR("4 port mode is not supported");
+ return;
+ }
+
+ if (bp->dcbx_port_params.pfc.enabled)
+
+ /* 1. Fills up common PFC structures if required.*/
+ /* 2. Configure NIG, MAC and BRB via the elink:
+ * elink must first check if BMAC is not in reset
+ * and only then configures the BMAC
+ * Or, configure EMAC.
+ */
+ bnx2x_pfc_set(bp);
+
+ else
+ bnx2x_pfc_clear(bp);
+ }
+}
+
+static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
+{
+ DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n");
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC,
+ 0 /* connectionless */,
+ 0 /* dataHi is zero */,
+ 0 /* dataLo is zero */,
+ 1 /* common */);
+}
+
+static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
+{
+ bnx2x_pfc_fw_struct_e2(bp);
+ DP(NETIF_MSG_LINK, "sending START TRAFFIC\n");
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC,
+ 0, /* connectionless */
+ U64_HI(bnx2x_sp_mapping(bp, pfc_config)),
+ U64_LO(bnx2x_sp_mapping(bp, pfc_config)),
+ 1 /* commmon */);
+}
+
+static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
+{
+ struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets);
+ u8 status = 0;
+
+ bnx2x_ets_disabled(&bp->link_params);
+
+ if (!ets->enabled)
+ return;
+
+ if ((ets->num_of_cos == 0) || (ets->num_of_cos > E2_NUM_OF_COS)) {
+ BNX2X_ERR("illegal num of cos= %x", ets->num_of_cos);
+ return;
+ }
+
+ /* valid COS entries */
+ if (ets->num_of_cos == 1) /* no ETS */
+ return;
+
+ /* sanity */
+ if (((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[0].strict) &&
+ (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) ||
+ ((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[1].strict) &&
+ (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) {
+ BNX2X_ERR("all COS should have at least bw_limit or strict"
+ "ets->cos_params[0].strict= %x"
+ "ets->cos_params[0].bw_tbl= %x"
+ "ets->cos_params[1].strict= %x"
+ "ets->cos_params[1].bw_tbl= %x",
+ ets->cos_params[0].strict,
+ ets->cos_params[0].bw_tbl,
+ ets->cos_params[1].strict,
+ ets->cos_params[1].bw_tbl);
+ return;
+ }
+ /* If we join a group and there is bw_tbl and strict then bw rules */
+ if ((DCBX_INVALID_COS_BW != ets->cos_params[0].bw_tbl) &&
+ (DCBX_INVALID_COS_BW != ets->cos_params[1].bw_tbl)) {
+ u32 bw_tbl_0 = ets->cos_params[0].bw_tbl;
+ u32 bw_tbl_1 = ets->cos_params[1].bw_tbl;
+ /* Do not allow 0-100 configuration
+ * since PBF does not support it
+ * force 1-99 instead
+ */
+ if (bw_tbl_0 == 0) {
+ bw_tbl_0 = 1;
+ bw_tbl_1 = 99;
+ } else if (bw_tbl_1 == 0) {
+ bw_tbl_1 = 1;
+ bw_tbl_0 = 99;
+ }
+
+ bnx2x_ets_bw_limit(&bp->link_params, bw_tbl_0, bw_tbl_1);
+ } else {
+ if (ets->cos_params[0].strict == BNX2X_DCBX_COS_HIGH_STRICT)
+ status = bnx2x_ets_strict(&bp->link_params, 0);
+ else if (ets->cos_params[1].strict
+ == BNX2X_DCBX_COS_HIGH_STRICT)
+ status = bnx2x_ets_strict(&bp->link_params, 1);
+
+ if (status)
+ BNX2X_ERR("update_ets_params failed\n");
+ }
+}
+
+static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
+{
+ struct lldp_local_mib local_mib = {0};
+ u32 dcbx_neg_res_offset = SHMEM2_RD(bp, dcbx_neg_res_offset);
+ int rc;
+
+ DP(NETIF_MSG_LINK, "dcbx_neg_res_offset 0x%x\n", dcbx_neg_res_offset);
+
+ if (SHMEM_DCBX_NEG_RES_NONE == dcbx_neg_res_offset) {
+ BNX2X_ERR("FW doesn't support dcbx_neg_res_offset\n");
+ return -EINVAL;
+ }
+ rc = bnx2x_dcbx_read_mib(bp, (u32 *)&local_mib, dcbx_neg_res_offset,
+ DCBX_READ_LOCAL_MIB);
+
+ if (rc) {
+ BNX2X_ERR("Faild to read local mib from FW\n");
+ return rc;
+ }
+
+ /* save features and error */
+ bp->dcbx_local_feat = local_mib.features;
+ bp->dcbx_error = local_mib.error;
+ return 0;
+}
+
+void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
+{
+ switch (state) {
+ case BNX2X_DCBX_STATE_NEG_RECEIVED:
+ {
+ DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
+
+ /* Read neg results if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_neg_results(bp))
+ return;
+
+ bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+
+ bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+
+ if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+ bnx2x_dcbx_stop_hw_tx(bp);
+ return;
+ }
+ /* fall through */
+ }
+ case BNX2X_DCBX_STATE_TX_PAUSED:
+ DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n");
+ bnx2x_pfc_set_pfc(bp);
+
+ bnx2x_dcbx_update_ets_params(bp);
+ if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+ bnx2x_dcbx_resume_hw_tx(bp);
+ return;
+ }
+ /* fall through */
+ case BNX2X_DCBX_STATE_TX_RELEASED:
+ DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n");
+ if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD)
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0);
+
+ return;
+ default:
+ BNX2X_ERR("Unknown DCBX_STATE\n");
+ }
+}
+
+
+#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\
+ sizeof(struct lldp_dcbx_stat))
+
+/* calculate struct offset in array according to chip information */
+#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params))
+
+#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \
+ BP_PORT(bp)*sizeof(struct lldp_admin_mib))
+
+static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp,
+ u32 dcbx_lldp_params_offset)
+{
+ struct lldp_params lldp_params = {0};
+ u32 i = 0, *buff = NULL;
+ u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp);
+
+ DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset);
+
+ if ((bp->lldp_config_params.overwrite_settings ==
+ BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) {
+ /* Read the data first */
+ buff = (u32 *)&lldp_params;
+ for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++)
+ *buff = REG_RD(bp, (offset + i));
+
+ lldp_params.msg_tx_hold =
+ (u8)bp->lldp_config_params.msg_tx_hold;
+ lldp_params.msg_fast_tx_interval =
+ (u8)bp->lldp_config_params.msg_fast_tx;
+ lldp_params.tx_crd_max =
+ (u8)bp->lldp_config_params.tx_credit_max;
+ lldp_params.msg_tx_interval =
+ (u8)bp->lldp_config_params.msg_tx_interval;
+ lldp_params.tx_fast =
+ (u8)bp->lldp_config_params.tx_fast;
+
+ /* Write the data.*/
+ buff = (u32 *)&lldp_params;
+ for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++)
+ REG_WR(bp, (offset + i) , *buff);
+
+
+ } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE ==
+ bp->lldp_config_params.overwrite_settings)
+ bp->lldp_config_params.overwrite_settings =
+ BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID;
+}
+
+static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,
+ u32 dcbx_lldp_params_offset)
+{
+ struct lldp_admin_mib admin_mib;
+ u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0;
+ u32 *buff;
+ u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp);
+
+ /*shortcuts*/
+ struct dcbx_features *af = &admin_mib.features;
+ struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params;
+
+ memset(&admin_mib, 0, sizeof(struct lldp_admin_mib));
+ buff = (u32 *)&admin_mib;
+ /* Read the data first */
+ for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++)
+ *buff = REG_RD(bp, (offset + i));
+
+ if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
+
+ if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE ==
+ dp->overwrite_settings)) {
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK);
+ admin_mib.ver_cfg_flags |=
+ (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) &
+ DCBX_CEE_VERSION_MASK;
+
+ af->ets.enabled = (u8)dp->admin_ets_enable;
+
+ af->pfc.enabled = (u8)dp->admin_pfc_enable;
+
+ /* FOR IEEE dp->admin_tc_supported_tx_enable */
+ if (dp->admin_ets_configuration_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_ETS_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_ETS_CONFIG_TX_ENABLED);
+ /* For IEEE admin_ets_recommendation_tx_enable */
+ if (dp->admin_pfc_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_PFC_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_PFC_CONFIG_TX_ENABLED);
+
+ if (dp->admin_application_priority_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_APP_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_APP_CONFIG_TX_ENABLED);
+
+ if (dp->admin_ets_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING);
+ /* For IEEE admin_ets_reco_valid */
+ if (dp->admin_pfc_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING);
+
+ if (dp->admin_app_priority_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING);
+
+ for (i = 0 ; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) {
+ DCBX_PG_BW_SET(af->ets.pg_bw_tbl, i,
+ (u8)dp->admin_configuration_bw_precentage[i]);
+
+ DP(NETIF_MSG_LINK, "pg_bw_tbl[%d] = %02x\n",
+ i, DCBX_PG_BW_GET(af->ets.pg_bw_tbl, i));
+ }
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) {
+ DCBX_PRI_PG_SET(af->ets.pri_pg_tbl, i,
+ (u8)dp->admin_configuration_ets_pg[i]);
+
+ DP(NETIF_MSG_LINK, "pri_pg_tbl[%d] = %02x\n",
+ i, DCBX_PRI_PG_GET(af->ets.pri_pg_tbl, i));
+ }
+
+ /*For IEEE admin_recommendation_bw_precentage
+ *For IEEE admin_recommendation_ets_pg */
+ af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap;
+ for (i = 0; i < 4; i++) {
+ if (dp->admin_priority_app_table[i].valid) {
+ struct bnx2x_admin_priority_app_table *table =
+ dp->admin_priority_app_table;
+ if ((ETH_TYPE_FCOE == table[i].app_id) &&
+ (TRAFFIC_TYPE_ETH == table[i].traffic_type))
+ traf_type = FCOE_APP_IDX;
+ else if ((TCP_PORT_ISCSI == table[i].app_id) &&
+ (TRAFFIC_TYPE_PORT == table[i].traffic_type))
+ traf_type = ISCSI_APP_IDX;
+ else
+ traf_type = other_traf_type++;
+
+ af->app.app_pri_tbl[traf_type].app_id =
+ table[i].app_id;
+
+ af->app.app_pri_tbl[traf_type].pri_bitmap =
+ (u8)(1 << table[i].priority);
+
+ af->app.app_pri_tbl[traf_type].appBitfield =
+ (DCBX_APP_ENTRY_VALID);
+
+ af->app.app_pri_tbl[traf_type].appBitfield |=
+ (TRAFFIC_TYPE_ETH == table[i].traffic_type) ?
+ DCBX_APP_SF_ETH_TYPE : DCBX_APP_SF_PORT;
+ }
+ }
+
+ af->app.default_pri = (u8)dp->admin_default_priority;
+
+ } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE ==
+ dp->overwrite_settings)
+ dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID;
+
+ /* Write the data. */
+ buff = (u32 *)&admin_mib;
+ for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++)
+ REG_WR(bp, (offset + i), *buff);
+}
+
+void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled)
+{
+ if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp)) {
+ bp->dcb_state = dcb_on;
+ bp->dcbx_enabled = dcbx_enabled;
+ } else {
+ bp->dcb_state = false;
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_INVALID;
+ }
+ DP(NETIF_MSG_LINK, "DCB state [%s:%s]\n",
+ dcb_on ? "ON" : "OFF",
+ dcbx_enabled == BNX2X_DCBX_ENABLED_OFF ? "user-mode" :
+ dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF ? "on-chip static" :
+ dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON ?
+ "on-chip with negotiation" : "invalid");
+}
+
+void bnx2x_dcbx_init_params(struct bnx2x *bp)
+{
+ bp->dcbx_config_params.admin_dcbx_version = 0x0; /* 0 - CEE; 1 - IEEE */
+ bp->dcbx_config_params.admin_ets_willing = 1;
+ bp->dcbx_config_params.admin_pfc_willing = 1;
+ bp->dcbx_config_params.overwrite_settings = 1;
+ bp->dcbx_config_params.admin_ets_enable = 1;
+ bp->dcbx_config_params.admin_pfc_enable = 1;
+ bp->dcbx_config_params.admin_tc_supported_tx_enable = 1;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+ bp->dcbx_config_params.admin_pfc_tx_enable = 1;
+ bp->dcbx_config_params.admin_application_priority_tx_enable = 1;
+ bp->dcbx_config_params.admin_ets_reco_valid = 1;
+ bp->dcbx_config_params.admin_app_priority_willing = 1;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[0] = 00;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[1] = 50;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[2] = 50;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[3] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[4] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[5] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[6] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[7] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[0] = 1;
+ bp->dcbx_config_params.admin_configuration_ets_pg[1] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[2] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[3] = 2;
+ bp->dcbx_config_params.admin_configuration_ets_pg[4] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[5] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[6] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[7] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[0] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[1] = 1;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[2] = 2;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[3] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[4] = 7;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[5] = 5;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[6] = 6;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[7] = 7;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[0] = 0;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[1] = 1;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[2] = 2;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[3] = 3;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[4] = 4;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[5] = 5;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[6] = 6;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[7] = 7;
+ bp->dcbx_config_params.admin_pfc_bitmap = 0x8; /* FCoE(3) enable */
+ bp->dcbx_config_params.admin_priority_app_table[0].valid = 1;
+ bp->dcbx_config_params.admin_priority_app_table[1].valid = 1;
+ bp->dcbx_config_params.admin_priority_app_table[2].valid = 0;
+ bp->dcbx_config_params.admin_priority_app_table[3].valid = 0;
+ bp->dcbx_config_params.admin_priority_app_table[0].priority = 3;
+ bp->dcbx_config_params.admin_priority_app_table[1].priority = 0;
+ bp->dcbx_config_params.admin_priority_app_table[2].priority = 0;
+ bp->dcbx_config_params.admin_priority_app_table[3].priority = 0;
+ bp->dcbx_config_params.admin_priority_app_table[0].traffic_type = 0;
+ bp->dcbx_config_params.admin_priority_app_table[1].traffic_type = 1;
+ bp->dcbx_config_params.admin_priority_app_table[2].traffic_type = 0;
+ bp->dcbx_config_params.admin_priority_app_table[3].traffic_type = 0;
+ bp->dcbx_config_params.admin_priority_app_table[0].app_id = 0x8906;
+ bp->dcbx_config_params.admin_priority_app_table[1].app_id = 3260;
+ bp->dcbx_config_params.admin_priority_app_table[2].app_id = 0;
+ bp->dcbx_config_params.admin_priority_app_table[3].app_id = 0;
+ bp->dcbx_config_params.admin_default_priority =
+ bp->dcbx_config_params.admin_priority_app_table[1].priority;
+}
+
+void bnx2x_dcbx_init(struct bnx2x *bp)
+{
+ u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE;
+
+ if (bp->dcbx_enabled <= 0)
+ return;
+
+ /* validate:
+ * chip of good for dcbx version,
+ * dcb is wanted
+ * the function is pmf
+ * shmem2 contains DCBX support fields
+ */
+ DP(NETIF_MSG_LINK, "dcb_state %d bp->port.pmf %d\n",
+ bp->dcb_state, bp->port.pmf);
+
+ if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf &&
+ SHMEM2_HAS(bp, dcbx_lldp_params_offset)) {
+ dcbx_lldp_params_offset =
+ SHMEM2_RD(bp, dcbx_lldp_params_offset);
+
+ DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n",
+ dcbx_lldp_params_offset);
+
+ if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) {
+ bnx2x_dcbx_lldp_updated_params(bp,
+ dcbx_lldp_params_offset);
+
+ bnx2x_dcbx_admin_mib_updated_params(bp,
+ dcbx_lldp_params_offset);
+
+ /* set default configuration BC has */
+ bnx2x_dcbx_set_params(bp,
+ BNX2X_DCBX_STATE_NEG_RECEIVED);
+
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0);
+ }
+ }
+}
+
+void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp)
+{
+ struct priority_cos pricos[MAX_PFC_TRAFFIC_TYPES];
+ u32 i = 0, addr;
+ memset(pricos, 0, sizeof(pricos));
+ /* Default initialization */
+ for (i = 0; i < MAX_PFC_TRAFFIC_TYPES; i++)
+ pricos[i].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED;
+
+ /* Store per port struct to internal memory */
+ addr = BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) +
+ offsetof(struct cmng_struct_per_port,
+ traffic_type_to_priority_cos);
+ __storm_memset_struct(bp, addr, sizeof(pricos), (u32 *)pricos);
+
+
+ /* LLFC disabled.*/
+ REG_WR8(bp , BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) +
+ offsetof(struct cmng_struct_per_port, llfc_mode),
+ LLFC_MODE_NONE);
+
+ /* DCBX disabled.*/
+ REG_WR8(bp , BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) +
+ offsetof(struct cmng_struct_per_port, dcb_enabled),
+ DCB_DISABLED);
+}
+
+static void
+bnx2x_dcbx_print_cos_params(struct bnx2x *bp,
+ struct flow_control_configuration *pfc_fw_cfg)
+{
+ u8 pri = 0;
+ u8 cos = 0;
+
+ DP(NETIF_MSG_LINK,
+ "pfc_fw_cfg->dcb_version %x\n", pfc_fw_cfg->dcb_version);
+ DP(NETIF_MSG_LINK,
+ "pdev->params.dcbx_port_params.pfc."
+ "priority_non_pauseable_mask %x\n",
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask);
+
+ for (cos = 0 ; cos < bp->dcbx_port_params.ets.num_of_cos ; cos++) {
+ DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets."
+ "cos_params[%d].pri_bitmask %x\n", cos,
+ bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask);
+
+ DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets."
+ "cos_params[%d].bw_tbl %x\n", cos,
+ bp->dcbx_port_params.ets.cos_params[cos].bw_tbl);
+
+ DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets."
+ "cos_params[%d].strict %x\n", cos,
+ bp->dcbx_port_params.ets.cos_params[cos].strict);
+
+ DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets."
+ "cos_params[%d].pauseable %x\n", cos,
+ bp->dcbx_port_params.ets.cos_params[cos].pauseable);
+ }
+
+ for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) {
+ DP(NETIF_MSG_LINK,
+ "pfc_fw_cfg->traffic_type_to_priority_cos[%d]."
+ "priority %x\n", pri,
+ pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority);
+
+ DP(NETIF_MSG_LINK,
+ "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n",
+ pri, pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos);
+ }
+}
+
+/* fills help_data according to pg_info */
+static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
+ u32 *pg_pri_orginal_spread,
+ struct pg_help_data *help_data)
+{
+ bool pg_found = false;
+ u32 i, traf_type, add_traf_type, add_pg;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ struct pg_entry_help_data *data = help_data->data; /*shotcut*/
+
+ /* Set to invalid */
+ for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++)
+ data[i].pg = DCBX_ILLEGAL_PG;
+
+ for (add_traf_type = 0;
+ add_traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; add_traf_type++) {
+ pg_found = false;
+ if (ttp[add_traf_type] < MAX_PFC_PRIORITIES) {
+ add_pg = (u8)pg_pri_orginal_spread[ttp[add_traf_type]];
+ for (traf_type = 0;
+ traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+ traf_type++) {
+ if (data[traf_type].pg == add_pg) {
+ if (!(data[traf_type].pg_priority &
+ (1 << ttp[add_traf_type])))
+ data[traf_type].
+ num_of_dif_pri++;
+ data[traf_type].pg_priority |=
+ (1 << ttp[add_traf_type]);
+ pg_found = true;
+ break;
+ }
+ }
+ if (false == pg_found) {
+ data[help_data->num_of_pg].pg = add_pg;
+ data[help_data->num_of_pg].pg_priority =
+ (1 << ttp[add_traf_type]);
+ data[help_data->num_of_pg].num_of_dif_pri = 1;
+ help_data->num_of_pg++;
+ }
+ }
+ DP(NETIF_MSG_LINK,
+ "add_traf_type %d pg_found %s num_of_pg %d\n",
+ add_traf_type, (false == pg_found) ? "NO" : "YES",
+ help_data->num_of_pg);
+ }
+}
+
+
+/*******************************************************************************
+ * Description: single priority group
+ *
+ * Return:
+ ******************************************************************************/
+static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 pri_join_mask)
+{
+ /* Only one priority than only one COS */
+ cos_data->data[0].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+ cos_data->data[0].pri_join_mask = pri_join_mask;
+ cos_data->data[0].cos_bw = 100;
+ cos_data->num_of_cos = 1;
+}
+
+/*******************************************************************************
+ * Description: updating the cos bw
+ *
+ * Return:
+ ******************************************************************************/
+static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
+ struct cos_entry_help_data *data,
+ u8 pg_bw)
+{
+ if (data->cos_bw == DCBX_INVALID_COS_BW)
+ data->cos_bw = pg_bw;
+ else
+ data->cos_bw += pg_bw;
+}
+
+/*******************************************************************************
+ * Description: single priority group
+ *
+ * Return:
+ ******************************************************************************/
+static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ struct dcbx_ets_feature *ets)
+{
+ u32 pri_tested = 0;
+ u8 i = 0;
+ u8 entry = 0;
+ u8 pg_entry = 0;
+ u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+
+ cos_data->data[0].pausable = true;
+ cos_data->data[1].pausable = false;
+ cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0;
+
+ for (i = 0 ; i < num_of_pri ; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+
+ if (pri_tested & DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) {
+ cos_data->data[1].pri_join_mask |= pri_tested;
+ entry = 1;
+ } else {
+ cos_data->data[0].pri_join_mask |= pri_tested;
+ entry = 0;
+ }
+ pg_entry = (u8)pg_pri_orginal_spread[bp->dcbx_port_params.
+ app.traffic_type_priority[i]];
+ /* There can be only one strict pg */
+ if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES)
+ bnx2x_dcbx_add_to_cos_bw(bp, &cos_data->data[entry],
+ DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry));
+ else
+ /* If we join a group and one is strict
+ * than the bw rulls */
+ cos_data->data[entry].strict =
+ BNX2X_DCBX_COS_HIGH_STRICT;
+ }
+ if ((0 == cos_data->data[0].pri_join_mask) &&
+ (0 == cos_data->data[1].pri_join_mask))
+ BNX2X_ERR("dcbx error: Both groups must have priorities\n");
+}
+
+
+#ifndef POWER_OF_2
+#define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1))))
+#endif
+
+static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct cos_help_data *cos_data,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u32 pri_tested = 0;
+ u32 pri_mask_without_pri = 0;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ /*debug*/
+ if (num_of_dif_pri == 1) {
+ bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, pri_join_mask);
+ return;
+ }
+ /* single priority group */
+ if (pg_help_data->data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) {
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and
+ * the non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pauseable.*/
+ cos_data->data[1].pausable = false;
+
+ if (2 == num_of_dif_pri) {
+ cos_data->data[0].cos_bw = 50;
+ cos_data->data[1].cos_bw = 50;
+ }
+
+ if (3 == num_of_dif_pri) {
+ if (POWER_OF_2(DCBX_PFC_PRI_GET_PAUSE(bp,
+ pri_join_mask))) {
+ cos_data->data[0].cos_bw = 33;
+ cos_data->data[1].cos_bw = 67;
+ } else {
+ cos_data->data[0].cos_bw = 67;
+ cos_data->data[1].cos_bw = 33;
+ }
+ }
+
+ } else if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask)) {
+ /* If there are only pauseable priorities,
+ * then one/two priorities go to the first queue
+ * and one priority goes to the second queue.
+ */
+ if (2 == num_of_dif_pri) {
+ cos_data->data[0].cos_bw = 50;
+ cos_data->data[1].cos_bw = 50;
+ } else {
+ cos_data->data[0].cos_bw = 67;
+ cos_data->data[1].cos_bw = 33;
+ }
+ cos_data->data[1].pausable = true;
+ cos_data->data[0].pausable = true;
+ /* All priorities except FCOE */
+ cos_data->data[0].pri_join_mask = (pri_join_mask &
+ ((u8)~(1 << ttp[LLFC_TRAFFIC_TYPE_FCOE])));
+ /* Only FCOE priority.*/
+ cos_data->data[1].pri_join_mask =
+ (1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]);
+ } else
+ /* If there are only non-pauseable priorities,
+ * they will all go to the same queue.
+ */
+ bnx2x_dcbx_ets_disabled_entry_data(bp,
+ cos_data, pri_join_mask);
+ } else {
+ /* priority group which is not BW limited (PG#15):*/
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ /* If there are both pauseable and non-pauseable
+ * priorities, the pauseable priorities go to the first
+ * queue and the non-pauseable priorities
+ * go to the second queue.
+ */
+ if (DCBX_PFC_PRI_GET_PAUSE(bp, pri_join_mask) >
+ DCBX_PFC_PRI_GET_NON_PAUSE(bp, pri_join_mask)) {
+ cos_data->data[0].strict =
+ BNX2X_DCBX_COS_HIGH_STRICT;
+ cos_data->data[1].strict =
+ BNX2X_DCBX_COS_LOW_STRICT;
+ } else {
+ cos_data->data[0].strict =
+ BNX2X_DCBX_COS_LOW_STRICT;
+ cos_data->data[1].strict =
+ BNX2X_DCBX_COS_HIGH_STRICT;
+ }
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pause-able.*/
+ cos_data->data[1].pausable = false;
+ } else {
+ /* If there are only pauseable priorities or
+ * only non-pauseable,* the lower priorities go
+ * to the first queue and the higherpriorities go
+ * to the second queue.
+ */
+ cos_data->data[0].pausable =
+ cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+
+ for (i = 0 ; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+ /* Remove priority tested */
+ pri_mask_without_pri =
+ (pri_join_mask & ((u8)(~pri_tested)));
+ if (pri_mask_without_pri < pri_tested)
+ break;
+ }
+
+ if (i == LLFC_DRIVER_TRAFFIC_TYPE_MAX)
+ BNX2X_ERR("Invalid value for pri_join_mask -"
+ " could not find a priority\n");
+
+ cos_data->data[0].pri_join_mask = pri_mask_without_pri;
+ cos_data->data[1].pri_join_mask = pri_tested;
+ /* Both queues are strict priority,
+ * and that with the highest priority
+ * gets the highest strict priority in the arbiter.
+ */
+ cos_data->data[0].strict = BNX2X_DCBX_COS_LOW_STRICT;
+ cos_data->data[1].strict = BNX2X_DCBX_COS_HIGH_STRICT;
+ }
+ }
+}
+
+static void bnx2x_dcbx_two_pg_to_cos_params(
+ struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u8 pg[E2_NUM_OF_COS] = {0};
+
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and
+ * the non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp,
+ pg_help_data->data[0].pg_priority) ||
+ IS_DCBX_PFC_PRI_MIX_PAUSE(bp,
+ pg_help_data->data[1].pg_priority)) {
+ /* If one PG contains both pauseable and
+ * non-pauseable priorities then ETS is disabled.
+ */
+ bnx2x_dcbx_separate_pauseable_from_non(bp, cos_data,
+ pg_pri_orginal_spread, ets);
+ bp->dcbx_port_params.ets.enabled = false;
+ return;
+ }
+
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pauseable. */
+ cos_data->data[1].pausable = false;
+ if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp,
+ pg_help_data->data[0].pg_priority)) {
+ /* 0 is pauseable */
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[0] = pg_help_data->data[0].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[1] = pg_help_data->data[1].pg;
+ } else {/* 1 is pauseable */
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[0] = pg_help_data->data[1].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[1] = pg_help_data->data[0].pg;
+ }
+ } else {
+ /* If there are only pauseable priorities or
+ * only non-pauseable, each PG goes to a queue.
+ */
+ cos_data->data[0].pausable = cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[0] = pg_help_data->data[0].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[1] = pg_help_data->data[1].pg;
+ }
+
+ /* There can be only one strict pg */
+ for (i = 0 ; i < E2_NUM_OF_COS; i++) {
+ if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES)
+ cos_data->data[i].cos_bw =
+ DCBX_PG_BW_GET(ets->pg_bw_tbl, pg[i]);
+ else
+ cos_data->data[i].strict = BNX2X_DCBX_COS_HIGH_STRICT;
+ }
+}
+
+/*******************************************************************************
+ * Description: Still
+ *
+ * Return:
+ ******************************************************************************/
+static void bnx2x_dcbx_three_pg_to_cos_params(
+ struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u32 pri_tested = 0;
+ u8 entry = 0;
+ u8 pg_entry = 0;
+ bool b_found_strict = false;
+ u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+
+ cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0;
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and the
+ * non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask))
+ bnx2x_dcbx_separate_pauseable_from_non(bp,
+ cos_data, pg_pri_orginal_spread, ets);
+ else {
+ /* If two BW-limited PG-s were combined to one queue,
+ * the BW is their sum.
+ *
+ * If there are only pauseable priorities or only non-pauseable,
+ * and there are both BW-limited and non-BW-limited PG-s,
+ * the BW-limited PG/s go to one queue and the non-BW-limited
+ * PG/s go to the second queue.
+ *
+ * If there are only pauseable priorities or only non-pauseable
+ * and all are BW limited, then two priorities go to the first
+ * queue and one priority goes to the second queue.
+ *
+ * We will join this two cases:
+ * if one is BW limited it will go to the secoend queue
+ * otherwise the last priority will get it
+ */
+
+ cos_data->data[0].pausable = cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+
+ for (i = 0 ; i < num_of_pri; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+ pg_entry = (u8)pg_pri_orginal_spread[bp->
+ dcbx_port_params.app.traffic_type_priority[i]];
+
+ if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) {
+ entry = 0;
+
+ if (i == (num_of_pri-1) &&
+ false == b_found_strict)
+ /* last entry will be handled separately
+ * If no priority is strict than last
+ * enty goes to last queue.*/
+ entry = 1;
+ cos_data->data[entry].pri_join_mask |=
+ pri_tested;
+ bnx2x_dcbx_add_to_cos_bw(bp,
+ &cos_data->data[entry],
+ DCBX_PG_BW_GET(ets->pg_bw_tbl,
+ pg_entry));
+ } else {
+ b_found_strict = true;
+ cos_data->data[1].pri_join_mask |= pri_tested;
+ /* If we join a group and one is strict
+ * than the bw rulls */
+ cos_data->data[1].strict =
+ BNX2X_DCBX_COS_HIGH_STRICT;
+ }
+ }
+ }
+}
+
+
+static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ u32 *pg_pri_orginal_spread)
+{
+ struct cos_help_data cos_data ;
+ u8 i = 0;
+ u32 pri_join_mask = 0;
+ u8 num_of_dif_pri = 0;
+
+ memset(&cos_data, 0, sizeof(cos_data));
+ /* Validate the pg value */
+ for (i = 0; i < help_data->num_of_pg ; i++) {
+ if (DCBX_STRICT_PRIORITY != help_data->data[i].pg &&
+ DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg)
+ BNX2X_ERR("Invalid pg[%d] data %x\n", i,
+ help_data->data[i].pg);
+ pri_join_mask |= help_data->data[i].pg_priority;
+ num_of_dif_pri += help_data->data[i].num_of_dif_pri;
+ }
+
+ /* default settings */
+ cos_data.num_of_cos = 2;
+ for (i = 0; i < E2_NUM_OF_COS ; i++) {
+ cos_data.data[i].pri_join_mask = pri_join_mask;
+ cos_data.data[i].pausable = false;
+ cos_data.data[i].strict = BNX2X_DCBX_COS_NOT_STRICT;
+ cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW;
+ }
+
+ switch (help_data->num_of_pg) {
+ case 1:
+
+ bxn2x_dcbx_single_pg_to_cos_params(
+ bp,
+ help_data,
+ &cos_data,
+ pri_join_mask,
+ num_of_dif_pri);
+ break;
+ case 2:
+ bnx2x_dcbx_two_pg_to_cos_params(
+ bp,
+ help_data,
+ ets,
+ &cos_data,
+ pg_pri_orginal_spread,
+ pri_join_mask,
+ num_of_dif_pri);
+ break;
+
+ case 3:
+ bnx2x_dcbx_three_pg_to_cos_params(
+ bp,
+ help_data,
+ ets,
+ &cos_data,
+ pg_pri_orginal_spread,
+ pri_join_mask,
+ num_of_dif_pri);
+
+ break;
+ default:
+ BNX2X_ERR("Wrong pg_help_data.num_of_pg\n");
+ bnx2x_dcbx_ets_disabled_entry_data(bp,
+ &cos_data, pri_join_mask);
+ }
+
+ for (i = 0; i < cos_data.num_of_cos ; i++) {
+ struct bnx2x_dcbx_cos_params *params =
+ &bp->dcbx_port_params.ets.cos_params[i];
+
+ params->pauseable = cos_data.data[i].pausable;
+ params->strict = cos_data.data[i].strict;
+ params->bw_tbl = cos_data.data[i].cos_bw;
+ if (params->pauseable) {
+ params->pri_bitmask =
+ DCBX_PFC_PRI_GET_PAUSE(bp,
+ cos_data.data[i].pri_join_mask);
+ DP(NETIF_MSG_LINK, "COS %d PAUSABLE prijoinmask 0x%x\n",
+ i, cos_data.data[i].pri_join_mask);
+ } else {
+ params->pri_bitmask =
+ DCBX_PFC_PRI_GET_NON_PAUSE(bp,
+ cos_data.data[i].pri_join_mask);
+ DP(NETIF_MSG_LINK, "COS %d NONPAUSABLE prijoinmask "
+ "0x%x\n",
+ i, cos_data.data[i].pri_join_mask);
+ }
+ }
+
+ bp->dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ;
+}
+
+static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
+ u32 *set_configuration_ets_pg,
+ u32 *pri_pg_tbl)
+{
+ int i;
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) {
+ set_configuration_ets_pg[i] = DCBX_PRI_PG_GET(pri_pg_tbl, i);
+
+ DP(NETIF_MSG_LINK, "set_configuration_ets_pg[%d] = 0x%x\n",
+ i, set_configuration_ets_pg[i]);
+ }
+}
+
+/*******************************************************************************
+ * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
+ *
+ * Return:
+ ******************************************************************************/
+static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
+{
+ struct flow_control_configuration *pfc_fw_cfg = NULL;
+ u16 pri_bit = 0;
+ u8 cos = 0, pri = 0;
+ struct priority_cos *tt2cos;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+
+ pfc_fw_cfg = (struct flow_control_configuration *)
+ bnx2x_sp(bp, pfc_config);
+ memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration));
+
+ /*shortcut*/
+ tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos;
+
+ /* Fw version should be incremented each update */
+ pfc_fw_cfg->dcb_version = ++bp->dcb_version;
+ pfc_fw_cfg->dcb_enabled = DCB_ENABLED;
+
+ /* Default initialization */
+ for (pri = 0; pri < MAX_PFC_TRAFFIC_TYPES ; pri++) {
+ tt2cos[pri].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED;
+ tt2cos[pri].cos = 0;
+ }
+
+ /* Fill priority parameters */
+ for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) {
+ tt2cos[pri].priority = ttp[pri];
+ pri_bit = 1 << tt2cos[pri].priority;
+
+ /* Fill COS parameters based on COS calculated to
+ * make it more generally for future use */
+ for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++)
+ if (bp->dcbx_port_params.ets.cos_params[cos].
+ pri_bitmask & pri_bit)
+ tt2cos[pri].cos = cos;
+ }
+ bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg);
+}
+/* DCB netlink */
+#ifdef BCM_DCB
+#include <linux/dcbnl.h>
+
+#define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \
+ DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
+
+static inline bool bnx2x_dcbnl_set_valid(struct bnx2x *bp)
+{
+ /* validate dcbnl call that may change HW state:
+ * DCB is on and DCBX mode was SUCCESSFULLY set by the user.
+ */
+ return bp->dcb_state && bp->dcbx_mode_uset;
+}
+
+static u8 bnx2x_dcbnl_get_state(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "state = %d\n", bp->dcb_state);
+ return bp->dcb_state;
+}
+
+static u8 bnx2x_dcbnl_set_state(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off");
+
+ bnx2x_dcbx_set_state(bp, (state ? true : false), bp->dcbx_enabled);
+ return 0;
+}
+
+static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev,
+ u8 *perm_addr)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "GET-PERM-ADDR\n");
+
+ /* first the HW mac address */
+ memcpy(perm_addr, netdev->dev_addr, netdev->addr_len);
+
+#ifdef BCM_CNIC
+ /* second SAN address */
+ memcpy(perm_addr+netdev->addr_len, bp->fip_mac, netdev->addr_len);
+#endif
+}
+
+static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio,
+ u8 prio_type, u8 pgid, u8 bw_pct,
+ u8 up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, pgid);
+ if (!bnx2x_dcbnl_set_valid(bp) || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
+ return;
+
+ /**
+ * bw_pct ingnored - band-width percentage devision between user
+ * priorities within the same group is not
+ * standard and hence not supported
+ *
+ * prio_type igonred - priority levels within the same group are not
+ * standard and hence are not supported. According
+ * to the standard pgid 15 is dedicated to strict
+ * prioirty traffic (on the port level).
+ *
+ * up_map ignored
+ */
+
+ bp->dcbx_config_params.admin_configuration_ets_pg[prio] = pgid;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+}
+
+static void bnx2x_dcbnl_set_pg_bwgcfg_tx(struct net_device *netdev,
+ int pgid, u8 bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "pgid[%d] = %d\n", pgid, bw_pct);
+
+ if (!bnx2x_dcbnl_set_valid(bp) || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
+ return;
+
+ bp->dcbx_config_params.admin_configuration_bw_precentage[pgid] = bw_pct;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+}
+
+static void bnx2x_dcbnl_set_pg_tccfg_rx(struct net_device *netdev, int prio,
+ u8 prio_type, u8 pgid, u8 bw_pct,
+ u8 up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n");
+}
+
+static void bnx2x_dcbnl_set_pg_bwgcfg_rx(struct net_device *netdev,
+ int pgid, u8 bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n");
+}
+
+static void bnx2x_dcbnl_get_pg_tccfg_tx(struct net_device *netdev, int prio,
+ u8 *prio_type, u8 *pgid, u8 *bw_pct,
+ u8 *up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "prio = %d\n", prio);
+
+ /**
+ * bw_pct ingnored - band-width percentage devision between user
+ * priorities within the same group is not
+ * standard and hence not supported
+ *
+ * prio_type igonred - priority levels within the same group are not
+ * standard and hence are not supported. According
+ * to the standard pgid 15 is dedicated to strict
+ * prioirty traffic (on the port level).
+ *
+ * up_map ignored
+ */
+ *up_map = *bw_pct = *prio_type = *pgid = 0;
+
+ if (!bp->dcb_state || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
+ return;
+
+ *pgid = DCBX_PRI_PG_GET(bp->dcbx_local_feat.ets.pri_pg_tbl, prio);
+}
+
+static void bnx2x_dcbnl_get_pg_bwgcfg_tx(struct net_device *netdev,
+ int pgid, u8 *bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "pgid = %d\n", pgid);
+
+ *bw_pct = 0;
+
+ if (!bp->dcb_state || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
+ return;
+
+ *bw_pct = DCBX_PG_BW_GET(bp->dcbx_local_feat.ets.pg_bw_tbl, pgid);
+}
+
+static void bnx2x_dcbnl_get_pg_tccfg_rx(struct net_device *netdev, int prio,
+ u8 *prio_type, u8 *pgid, u8 *bw_pct,
+ u8 *up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n");
+
+ *prio_type = *pgid = *bw_pct = *up_map = 0;
+}
+
+static void bnx2x_dcbnl_get_pg_bwgcfg_rx(struct net_device *netdev,
+ int pgid, u8 *bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n");
+
+ *bw_pct = 0;
+}
+
+static void bnx2x_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio,
+ u8 setting)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, setting);
+
+ if (!bnx2x_dcbnl_set_valid(bp) || prio >= MAX_PFC_PRIORITIES)
+ return;
+
+ bp->dcbx_config_params.admin_pfc_bitmap |= ((setting ? 1 : 0) << prio);
+
+ if (setting)
+ bp->dcbx_config_params.admin_pfc_tx_enable = 1;
+}
+
+static void bnx2x_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
+ u8 *setting)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "prio = %d\n", prio);
+
+ *setting = 0;
+
+ if (!bp->dcb_state || prio >= MAX_PFC_PRIORITIES)
+ return;
+
+ *setting = (bp->dcbx_local_feat.pfc.pri_en_bitmap >> prio) & 0x1;
+}
+
+static u8 bnx2x_dcbnl_set_all(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ int rc = 0;
+
+ DP(NETIF_MSG_LINK, "SET-ALL\n");
+
+ if (!bnx2x_dcbnl_set_valid(bp))
+ return 1;
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ netdev_err(bp->dev, "Handling parity error recovery. "
+ "Try again later\n");
+ return 1;
+ }
+ if (netif_running(bp->dev)) {
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ }
+ DP(NETIF_MSG_LINK, "set_dcbx_params done (%d)\n", rc);
+ if (rc)
+ return 1;
+
+ return 0;
+}
+
+static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ if (bp->dcb_state) {
+ switch (capid) {
+ case DCB_CAP_ATTR_PG:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_PFC:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_UP2TC:
+ *cap = false;
+ break;
+ case DCB_CAP_ATTR_PG_TCS:
+ *cap = 0x80; /* 8 priorities for PGs */
+ break;
+ case DCB_CAP_ATTR_PFC_TCS:
+ *cap = 0x80; /* 8 priorities for PFC */
+ break;
+ case DCB_CAP_ATTR_GSP:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_BCN:
+ *cap = false;
+ break;
+ case DCB_CAP_ATTR_DCBX:
+ *cap = BNX2X_DCBX_CAPS;
+ default:
+ rval = -EINVAL;
+ break;
+ }
+ } else
+ rval = -EINVAL;
+
+ DP(NETIF_MSG_LINK, "capid %d:%x\n", capid, *cap);
+ return rval;
+}
+
+static u8 bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(NETIF_MSG_LINK, "tcid %d\n", tcid);
+
+ if (bp->dcb_state) {
+ switch (tcid) {
+ case DCB_NUMTCS_ATTR_PG:
+ *num = E2_NUM_OF_COS;
+ break;
+ case DCB_NUMTCS_ATTR_PFC:
+ *num = E2_NUM_OF_COS;
+ break;
+ default:
+ rval = -EINVAL;
+ break;
+ }
+ } else
+ rval = -EINVAL;
+
+ return rval;
+}
+
+static u8 bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "num tcs = %d; Not supported\n", num);
+ return -EINVAL;
+}
+
+static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
+
+ if (!bp->dcb_state)
+ return 0;
+
+ return bp->dcbx_local_feat.pfc.enabled;
+}
+
+static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off");
+
+ if (!bnx2x_dcbnl_set_valid(bp))
+ return;
+
+ bp->dcbx_config_params.admin_pfc_tx_enable =
+ bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0);
+}
+
+static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent,
+ u8 idtype, u16 idval)
+{
+ if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID))
+ return false;
+
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
+ DCBX_APP_SF_ETH_TYPE)
+ return false;
+ break;
+ case DCB_APP_IDTYPE_PORTNUM:
+ if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
+ DCBX_APP_SF_PORT)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ if (app_ent->app_id != idval)
+ return false;
+
+ return true;
+}
+
+static void bnx2x_admin_app_set_ent(
+ struct bnx2x_admin_priority_app_table *app_ent,
+ u8 idtype, u16 idval, u8 up)
+{
+ app_ent->valid = 1;
+
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ app_ent->traffic_type = TRAFFIC_TYPE_ETH;
+ break;
+ case DCB_APP_IDTYPE_PORTNUM:
+ app_ent->traffic_type = TRAFFIC_TYPE_PORT;
+ break;
+ default:
+ break; /* never gets here */
+ }
+ app_ent->app_id = idval;
+ app_ent->priority = up;
+}
+
+static bool bnx2x_admin_app_is_equal(
+ struct bnx2x_admin_priority_app_table *app_ent,
+ u8 idtype, u16 idval)
+{
+ if (!app_ent->valid)
+ return false;
+
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ if (app_ent->traffic_type != TRAFFIC_TYPE_ETH)
+ return false;
+ break;
+ case DCB_APP_IDTYPE_PORTNUM:
+ if (app_ent->traffic_type != TRAFFIC_TYPE_PORT)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ if (app_ent->app_id != idval)
+ return false;
+
+ return true;
+}
+
+static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
+{
+ int i, ff;
+
+ /* iterate over the app entries looking for idtype and idval */
+ for (i = 0, ff = -1; i < 4; i++) {
+ struct bnx2x_admin_priority_app_table *app_ent =
+ &bp->dcbx_config_params.admin_priority_app_table[i];
+ if (bnx2x_admin_app_is_equal(app_ent, idtype, idval))
+ break;
+
+ if (ff < 0 && !app_ent->valid)
+ ff = i;
+ }
+ if (i < 4)
+ /* if found overwrite up */
+ bp->dcbx_config_params.
+ admin_priority_app_table[i].priority = up;
+ else if (ff >= 0)
+ /* not found use first-free */
+ bnx2x_admin_app_set_ent(
+ &bp->dcbx_config_params.admin_priority_app_table[ff],
+ idtype, idval, up);
+ else
+ /* app table is full */
+ return -EBUSY;
+
+ /* up configured, if not 0 make sure feature is enabled */
+ if (up)
+ bp->dcbx_config_params.admin_application_priority_tx_enable = 1;
+
+ return 0;
+}
+
+static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
+ u16 idval, u8 up)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(NETIF_MSG_LINK, "app_type %d, app_id %x, prio bitmap %d\n",
+ idtype, idval, up);
+
+ if (!bnx2x_dcbnl_set_valid(bp))
+ return -EINVAL;
+
+ /* verify idtype */
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ case DCB_APP_IDTYPE_PORTNUM:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return bnx2x_set_admin_app_up(bp, idtype, idval, up);
+}
+
+static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype,
+ u16 idval)
+{
+ int i;
+ u8 up = 0;
+
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval);
+
+ /* iterate over the app entries looking for idtype and idval */
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+ if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i],
+ idtype, idval))
+ break;
+
+ if (i < DCBX_MAX_APP_PROTOCOL)
+ /* if found return up */
+ up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap;
+ else
+ DP(NETIF_MSG_LINK, "app not found\n");
+
+ return up;
+}
+
+static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 state;
+
+ state = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE;
+
+ if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF)
+ state |= DCB_CAP_DCBX_STATIC;
+
+ return state;
+}
+
+static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(NETIF_MSG_LINK, "state = %02x\n", state);
+
+ /* set dcbx mode */
+
+ if ((state & BNX2X_DCBX_CAPS) != state) {
+ BNX2X_ERR("Requested DCBX mode %x is beyond advertised "
+ "capabilities\n", state);
+ return 1;
+ }
+
+ if (bp->dcb_state != BNX2X_DCB_STATE_ON) {
+ BNX2X_ERR("DCB turned off, DCBX configuration is invalid\n");
+ return 1;
+ }
+
+ if (state & DCB_CAP_DCBX_STATIC)
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_OFF;
+ else
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_ON;
+
+ bp->dcbx_mode_uset = true;
+ return 0;
+}
+
+
+static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
+ u8 *flags)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(NETIF_MSG_LINK, "featid %d\n", featid);
+
+ if (bp->dcb_state) {
+ *flags = 0;
+ switch (featid) {
+ case DCB_FEATCFG_ATTR_PG:
+ if (bp->dcbx_local_feat.ets.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & DCBX_LOCAL_ETS_ERROR)
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ case DCB_FEATCFG_ATTR_PFC:
+ if (bp->dcbx_local_feat.pfc.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR |
+ DCBX_LOCAL_PFC_MISMATCH))
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ case DCB_FEATCFG_ATTR_APP:
+ if (bp->dcbx_local_feat.app.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR |
+ DCBX_LOCAL_APP_MISMATCH))
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ default:
+ rval = -EINVAL;
+ break;
+ }
+ } else
+ rval = -EINVAL;
+
+ return rval;
+}
+
+static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
+ u8 flags)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(NETIF_MSG_LINK, "featid = %d flags = %02x\n", featid, flags);
+
+ /* ignore the 'advertise' flag */
+ if (bnx2x_dcbnl_set_valid(bp)) {
+ switch (featid) {
+ case DCB_FEATCFG_ATTR_PG:
+ bp->dcbx_config_params.admin_ets_enable =
+ flags & DCB_FEATCFG_ENABLE ? 1 : 0;
+ bp->dcbx_config_params.admin_ets_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ case DCB_FEATCFG_ATTR_PFC:
+ bp->dcbx_config_params.admin_pfc_enable =
+ flags & DCB_FEATCFG_ENABLE ? 1 : 0;
+ bp->dcbx_config_params.admin_pfc_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ case DCB_FEATCFG_ATTR_APP:
+ /* ignore enable, always enabled */
+ bp->dcbx_config_params.admin_app_priority_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ default:
+ rval = -EINVAL;
+ break;
+ }
+ } else
+ rval = -EINVAL;
+
+ return rval;
+}
+
+const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
+ .getstate = bnx2x_dcbnl_get_state,
+ .setstate = bnx2x_dcbnl_set_state,
+ .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
+ .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
+ .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
+ .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
+ .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
+ .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
+ .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
+ .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
+ .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
+ .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
+ .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
+ .setall = bnx2x_dcbnl_set_all,
+ .getcap = bnx2x_dcbnl_get_cap,
+ .getnumtcs = bnx2x_dcbnl_get_numtcs,
+ .setnumtcs = bnx2x_dcbnl_set_numtcs,
+ .getpfcstate = bnx2x_dcbnl_get_pfc_state,
+ .setpfcstate = bnx2x_dcbnl_set_pfc_state,
+ .getapp = bnx2x_dcbnl_get_app_up,
+ .setapp = bnx2x_dcbnl_set_app_up,
+ .getdcbx = bnx2x_dcbnl_get_dcbx,
+ .setdcbx = bnx2x_dcbnl_set_dcbx,
+ .getfeatcfg = bnx2x_dcbnl_get_featcfg,
+ .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+};
+
+#endif /* BCM_DCB */
diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h
new file mode 100644
index 000000000000..f650f98e4092
--- /dev/null
+++ b/drivers/net/bnx2x/bnx2x_dcb.h
@@ -0,0 +1,196 @@
+/* bnx2x_dcb.h: Broadcom Everest network driver.
+ *
+ * Copyright 2009-2010 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Dmitry Kravkov
+ *
+ */
+#ifndef BNX2X_DCB_H
+#define BNX2X_DCB_H
+
+#include "bnx2x_hsi.h"
+
+#define LLFC_DRIVER_TRAFFIC_TYPE_MAX 3 /* NW, iSCSI, FCoE */
+struct bnx2x_dcbx_app_params {
+ u32 enabled;
+ u32 traffic_type_priority[LLFC_DRIVER_TRAFFIC_TYPE_MAX];
+};
+
+#define E2_NUM_OF_COS 2
+#define BNX2X_DCBX_COS_NOT_STRICT 0
+#define BNX2X_DCBX_COS_LOW_STRICT 1
+#define BNX2X_DCBX_COS_HIGH_STRICT 2
+
+struct bnx2x_dcbx_cos_params {
+ u32 bw_tbl;
+ u32 pri_bitmask;
+ u8 strict;
+ u8 pauseable;
+};
+
+struct bnx2x_dcbx_pg_params {
+ u32 enabled;
+ u8 num_of_cos; /* valid COS entries */
+ struct bnx2x_dcbx_cos_params cos_params[E2_NUM_OF_COS];
+};
+
+struct bnx2x_dcbx_pfc_params {
+ u32 enabled;
+ u32 priority_non_pauseable_mask;
+};
+
+struct bnx2x_dcbx_port_params {
+ struct bnx2x_dcbx_pfc_params pfc;
+ struct bnx2x_dcbx_pg_params ets;
+ struct bnx2x_dcbx_app_params app;
+};
+
+#define BNX2X_DCBX_CONFIG_INV_VALUE (0xFFFFFFFF)
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_DISABLE 0
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE)
+
+/*******************************************************************************
+ * LLDP protocol configuration parameters.
+ ******************************************************************************/
+struct bnx2x_config_lldp_params {
+ u32 overwrite_settings;
+ u32 msg_tx_hold;
+ u32 msg_fast_tx;
+ u32 tx_credit_max;
+ u32 msg_tx_interval;
+ u32 tx_fast;
+};
+
+struct bnx2x_admin_priority_app_table {
+ u32 valid;
+ u32 priority;
+#define INVALID_TRAFFIC_TYPE_PRIORITY (0xFFFFFFFF)
+ u32 traffic_type;
+#define TRAFFIC_TYPE_ETH 0
+#define TRAFFIC_TYPE_PORT 1
+ u32 app_id;
+};
+
+/*******************************************************************************
+ * DCBX protocol configuration parameters.
+ ******************************************************************************/
+struct bnx2x_config_dcbx_params {
+ u32 overwrite_settings;
+ u32 admin_dcbx_version;
+ u32 admin_ets_enable;
+ u32 admin_pfc_enable;
+ u32 admin_tc_supported_tx_enable;
+ u32 admin_ets_configuration_tx_enable;
+ u32 admin_ets_recommendation_tx_enable;
+ u32 admin_pfc_tx_enable;
+ u32 admin_application_priority_tx_enable;
+ u32 admin_ets_willing;
+ u32 admin_ets_reco_valid;
+ u32 admin_pfc_willing;
+ u32 admin_app_priority_willing;
+ u32 admin_configuration_bw_precentage[8];
+ u32 admin_configuration_ets_pg[8];
+ u32 admin_recommendation_bw_precentage[8];
+ u32 admin_recommendation_ets_pg[8];
+ u32 admin_pfc_bitmap;
+ struct bnx2x_admin_priority_app_table admin_priority_app_table[4];
+ u32 admin_default_priority;
+};
+
+#define GET_FLAGS(flags, bits) ((flags) & (bits))
+#define SET_FLAGS(flags, bits) ((flags) |= (bits))
+#define RESET_FLAGS(flags, bits) ((flags) &= ~(bits))
+
+enum {
+ DCBX_READ_LOCAL_MIB,
+ DCBX_READ_REMOTE_MIB
+};
+
+#define ETH_TYPE_FCOE (0x8906)
+#define TCP_PORT_ISCSI (0xCBC)
+
+#define PFC_VALUE_FRAME_SIZE (512)
+#define PFC_QUANTA_IN_NANOSEC_FROM_SPEED_MEGA(mega_speed) \
+ ((1000 * PFC_VALUE_FRAME_SIZE)/(mega_speed))
+
+#define PFC_BRB1_REG_HIGH_LLFC_LOW_THRESHOLD 130
+#define PFC_BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD 170
+
+
+
+struct cos_entry_help_data {
+ u32 pri_join_mask;
+ u32 cos_bw;
+ u8 strict;
+ bool pausable;
+};
+
+struct cos_help_data {
+ struct cos_entry_help_data data[E2_NUM_OF_COS];
+ u8 num_of_cos;
+};
+
+#define DCBX_ILLEGAL_PG (0xFF)
+#define DCBX_PFC_PRI_MASK (0xFF)
+#define DCBX_STRICT_PRIORITY (15)
+#define DCBX_INVALID_COS_BW (0xFFFFFFFF)
+#define DCBX_PFC_PRI_NON_PAUSE_MASK(bp) \
+ ((bp)->dcbx_port_params.pfc.priority_non_pauseable_mask)
+#define DCBX_PFC_PRI_PAUSE_MASK(bp) \
+ ((u8)~DCBX_PFC_PRI_NON_PAUSE_MASK(bp))
+#define DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri) \
+ ((pg_pri) & (DCBX_PFC_PRI_PAUSE_MASK(bp)))
+#define DCBX_PFC_PRI_GET_NON_PAUSE(bp, pg_pri) \
+ (DCBX_PFC_PRI_NON_PAUSE_MASK(bp) & (pg_pri))
+#define IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pg_pri) \
+ (pg_pri == DCBX_PFC_PRI_GET_PAUSE((bp), (pg_pri)))
+#define IS_DCBX_PFC_PRI_ONLY_NON_PAUSE(bp, pg_pri)\
+ ((pg_pri) == DCBX_PFC_PRI_GET_NON_PAUSE((bp), (pg_pri)))
+#define IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pg_pri) \
+ (!(IS_DCBX_PFC_PRI_ONLY_NON_PAUSE((bp), (pg_pri)) || \
+ IS_DCBX_PFC_PRI_ONLY_PAUSE((bp), (pg_pri))))
+
+
+struct pg_entry_help_data {
+ u8 num_of_dif_pri;
+ u8 pg;
+ u32 pg_priority;
+};
+
+struct pg_help_data {
+ struct pg_entry_help_data data[LLFC_DRIVER_TRAFFIC_TYPE_MAX];
+ u8 num_of_pg;
+};
+
+/* forward DCB/PFC related declarations */
+struct bnx2x;
+void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp);
+void bnx2x_dcbx_update(struct work_struct *work);
+void bnx2x_dcbx_init_params(struct bnx2x *bp);
+void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled);
+
+enum {
+ BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
+ BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
+ BNX2X_DCBX_STATE_TX_RELEASED = 0x4
+};
+void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
+
+/* DCB netlink */
+#ifdef BCM_DCB
+extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops;
+#endif /* BCM_DCB */
+
+#endif /* BNX2X_DCB_H */
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index d02ffbdc9f0e..99c672d894ca 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -25,6 +25,143 @@
#include "bnx2x_cmn.h"
#include "bnx2x_dump.h"
+/* Note: in the format strings below %s is replaced by the queue-name which is
+ * either its index or 'fcoe' for the fcoe queue. Make sure the format string
+ * length does not exceed ETH_GSTRING_LEN - MAX_QUEUE_NAME_LEN + 2
+ */
+#define MAX_QUEUE_NAME_LEN 4
+static const struct {
+ long offset;
+ int size;
+ char string[ETH_GSTRING_LEN];
+} bnx2x_q_stats_arr[] = {
+/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%s]: rx_bytes" },
+ { Q_STATS_OFFSET32(error_bytes_received_hi),
+ 8, "[%s]: rx_error_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, "[%s]: rx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, "[%s]: rx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, "[%s]: rx_bcast_packets" },
+ { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%s]: rx_discards" },
+ { Q_STATS_OFFSET32(rx_err_discard_pkt),
+ 4, "[%s]: rx_phy_ip_err_discards"},
+ { Q_STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, "[%s]: rx_skb_alloc_discard" },
+ { Q_STATS_OFFSET32(hw_csum_err), 4, "[%s]: rx_csum_offload_errors" },
+
+/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, "[%s]: tx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ 8, "[%s]: tx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ 8, "[%s]: tx_bcast_packets" }
+};
+
+#define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr)
+
+static const struct {
+ long offset;
+ int size;
+ u32 flags;
+#define STATS_FLAGS_PORT 1
+#define STATS_FLAGS_FUNC 2
+#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
+ char string[ETH_GSTRING_LEN];
+} bnx2x_stats_arr[] = {
+/* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bytes" },
+ { STATS_OFFSET32(error_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
+ { STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
+ { STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
+ { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
+ 8, STATS_FLAGS_PORT, "rx_crc_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
+ 8, STATS_FLAGS_PORT, "rx_align_errors" },
+ { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
+ { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
+/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+ 8, STATS_FLAGS_PORT, "rx_fragments" },
+ { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
+ 8, STATS_FLAGS_PORT, "rx_jabbers" },
+ { STATS_OFFSET32(no_buff_discard_hi),
+ 8, STATS_FLAGS_BOTH, "rx_discards" },
+ { STATS_OFFSET32(mac_filter_discard),
+ 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
+ { STATS_OFFSET32(xxoverflow_discard),
+ 4, STATS_FLAGS_PORT, "rx_fw_discards" },
+ { STATS_OFFSET32(brb_drop_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_discard" },
+ { STATS_OFFSET32(brb_truncate_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
+ { STATS_OFFSET32(pause_frames_received_hi),
+ 8, STATS_FLAGS_PORT, "rx_pause_frames" },
+ { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+ 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
+ { STATS_OFFSET32(nig_timer_max),
+ 4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
+/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
+ 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
+ { STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
+ { STATS_OFFSET32(hw_csum_err),
+ 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
+
+ { STATS_OFFSET32(total_bytes_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bytes" },
+ { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
+ 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_ucast_packets" },
+ { STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_mcast_packets" },
+ { STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bcast_packets" },
+ { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_mac_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
+/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
+ 8, STATS_FLAGS_PORT, "tx_single_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
+ 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+ 8, STATS_FLAGS_PORT, "tx_deferred" },
+ { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_late_collisions" },
+ { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_total_collisions" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
+/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
+ { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
+ { STATS_OFFSET32(etherstatspktsover1522octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
+ { STATS_OFFSET32(pause_frames_sent_hi),
+ 8, STATS_FLAGS_PORT, "tx_pause_frames" }
+};
+
+#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr)
+
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -45,14 +182,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->speed = bp->link_params.req_line_speed[cfg_idx];
cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
- if (IS_MF(bp)) {
- u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] &
- FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) *
- 100;
- if (vn_max_rate < cmd->speed)
- cmd->speed = vn_max_rate;
- }
+ if (IS_MF(bp))
+ cmd->speed = bnx2x_get_mf_speed(bp);
if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
@@ -87,18 +219,57 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config;
+ u32 speed;
- if (IS_MF(bp))
+ if (IS_MF_SD(bp))
return 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
- DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
- DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ " supported 0x%x advertising 0x%x speed %d speed_hi %d\n"
+ " duplex %d port %d phy_address %d transceiver %d\n"
+ " autoneg %d maxtxpkt %d maxrxpkt %d\n",
cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+ cmd->speed_hi,
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+ speed = cmd->speed;
+ speed |= (cmd->speed_hi << 16);
+
+ if (IS_MF_SI(bp)) {
+ u32 param = 0;
+ u32 line_speed = bp->link_vars.line_speed;
+
+ /* use 10G if no link detected */
+ if (!line_speed)
+ line_speed = 10000;
+
+ if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) {
+ BNX2X_DEV_INFO("To set speed BC %X or higher "
+ "is required, please upgrade BC\n",
+ REQ_BC_VER_4_SET_MF_BW);
+ return -EINVAL;
+ }
+ if (line_speed < speed) {
+ BNX2X_DEV_INFO("New speed should be less or equal "
+ "to actual line speed\n");
+ return -EINVAL;
+ }
+ /* load old values */
+ param = bp->mf_config[BP_VN(bp)];
+
+ /* leave only MIN value */
+ param &= FUNC_MF_CFG_MIN_BW_MASK;
+
+ /* set new MAX value */
+ param |= (((speed * 100) / line_speed)
+ << FUNC_MF_CFG_MAX_BW_SHIFT)
+ & FUNC_MF_CFG_MAX_BW_MASK;
+
+ bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param);
+ return 0;
+ }
+
cfg_idx = bnx2x_get_link_cfg_idx(bp);
old_multi_phy_config = bp->link_params.multi_phy_config;
switch (cmd->port) {
@@ -168,8 +339,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
} else { /* forced speed */
/* advertise the requested speed and duplex if supported */
- u32 speed = cmd->speed;
- speed |= (cmd->speed_hi << 16);
switch (speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
@@ -1286,7 +1455,7 @@ static int bnx2x_test_registers(struct bnx2x *bp)
save_val = REG_RD(bp, offset);
- REG_WR(bp, offset, (wr_val & mask));
+ REG_WR(bp, offset, wr_val & mask);
val = REG_RD(bp, offset);
@@ -1499,8 +1668,15 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
* updates that have been performed while interrupts were
* disabled.
*/
- if (bp->common.int_block == INT_BLOCK_IGU)
+ if (bp->common.int_block == INT_BLOCK_IGU) {
+ /* Disable local BHes to prevent a dead-lock situation between
+ * sch_direct_xmit() and bnx2x_run_loopback() (calling
+ * bnx2x_tx_int()), as both are taking netif_tx_lock().
+ */
+ local_bh_disable();
bnx2x_tx_int(fp_tx);
+ local_bh_enable();
+ }
rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
if (rx_idx != rx_start_idx + num_pkts)
@@ -1650,7 +1826,7 @@ static int bnx2x_test_intr(struct bnx2x *bp)
config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
- bp->set_mac_pending++;
+ bp->set_mac_pending = 1;
smp_wmb();
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
@@ -1748,134 +1924,6 @@ static void bnx2x_self_test(struct net_device *dev,
#endif
}
-static const struct {
- long offset;
- int size;
- u8 string[ETH_GSTRING_LEN];
-} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
-/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
- { Q_STATS_OFFSET32(error_bytes_received_hi),
- 8, "[%d]: rx_error_bytes" },
- { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
- 8, "[%d]: rx_ucast_packets" },
- { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
- 8, "[%d]: rx_mcast_packets" },
- { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
- 8, "[%d]: rx_bcast_packets" },
- { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" },
- { Q_STATS_OFFSET32(rx_err_discard_pkt),
- 4, "[%d]: rx_phy_ip_err_discards"},
- { Q_STATS_OFFSET32(rx_skb_alloc_failed),
- 4, "[%d]: rx_skb_alloc_discard" },
- { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
-
-/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" },
- { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- 8, "[%d]: tx_ucast_packets" },
- { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi),
- 8, "[%d]: tx_mcast_packets" },
- { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
- 8, "[%d]: tx_bcast_packets" }
-};
-
-static const struct {
- long offset;
- int size;
- u32 flags;
-#define STATS_FLAGS_PORT 1
-#define STATS_FLAGS_FUNC 2
-#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
- u8 string[ETH_GSTRING_LEN];
-} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
-/* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
- 8, STATS_FLAGS_BOTH, "rx_bytes" },
- { STATS_OFFSET32(error_bytes_received_hi),
- 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
- { STATS_OFFSET32(total_unicast_packets_received_hi),
- 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
- { STATS_OFFSET32(total_multicast_packets_received_hi),
- 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
- { STATS_OFFSET32(total_broadcast_packets_received_hi),
- 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
- { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
- 8, STATS_FLAGS_PORT, "rx_crc_errors" },
- { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
- 8, STATS_FLAGS_PORT, "rx_align_errors" },
- { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
- 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
- { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
- 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
-/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
- 8, STATS_FLAGS_PORT, "rx_fragments" },
- { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
- 8, STATS_FLAGS_PORT, "rx_jabbers" },
- { STATS_OFFSET32(no_buff_discard_hi),
- 8, STATS_FLAGS_BOTH, "rx_discards" },
- { STATS_OFFSET32(mac_filter_discard),
- 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
- { STATS_OFFSET32(xxoverflow_discard),
- 4, STATS_FLAGS_PORT, "rx_fw_discards" },
- { STATS_OFFSET32(brb_drop_hi),
- 8, STATS_FLAGS_PORT, "rx_brb_discard" },
- { STATS_OFFSET32(brb_truncate_hi),
- 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
- { STATS_OFFSET32(pause_frames_received_hi),
- 8, STATS_FLAGS_PORT, "rx_pause_frames" },
- { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
- { STATS_OFFSET32(nig_timer_max),
- 4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
-/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
- 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
- { STATS_OFFSET32(rx_skb_alloc_failed),
- 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
- { STATS_OFFSET32(hw_csum_err),
- 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
-
- { STATS_OFFSET32(total_bytes_transmitted_hi),
- 8, STATS_FLAGS_BOTH, "tx_bytes" },
- { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
- 8, STATS_FLAGS_PORT, "tx_error_bytes" },
- { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- 8, STATS_FLAGS_BOTH, "tx_ucast_packets" },
- { STATS_OFFSET32(total_multicast_packets_transmitted_hi),
- 8, STATS_FLAGS_BOTH, "tx_mcast_packets" },
- { STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
- 8, STATS_FLAGS_BOTH, "tx_bcast_packets" },
- { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
- 8, STATS_FLAGS_PORT, "tx_mac_errors" },
- { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
- 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
-/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
- 8, STATS_FLAGS_PORT, "tx_single_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
- 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
- 8, STATS_FLAGS_PORT, "tx_deferred" },
- { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_late_collisions" },
- { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_total_collisions" },
- { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
- 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
- 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
- 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
- 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
-/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
- 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
- { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
- 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
- { STATS_OFFSET32(etherstatspktsover1522octets_hi),
- 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
- { STATS_OFFSET32(pause_frames_sent_hi),
- 8, STATS_FLAGS_PORT, "tx_pause_frames" }
-};
-
#define IS_PORT_STAT(i) \
((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
@@ -1890,7 +1938,8 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
switch (stringset) {
case ETH_SS_STATS:
if (is_multi(bp)) {
- num_stats = BNX2X_NUM_Q_STATS * bp->num_queues;
+ num_stats = BNX2X_NUM_STAT_QUEUES(bp) *
+ BNX2X_NUM_Q_STATS;
if (!IS_MF_MODE_STAT(bp))
num_stats += BNX2X_NUM_STATS;
} else {
@@ -1916,15 +1965,25 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
int i, j, k;
+ char queue_name[MAX_QUEUE_NAME_LEN+1];
switch (stringset) {
case ETH_SS_STATS:
if (is_multi(bp)) {
k = 0;
- for_each_queue(bp, i) {
+ for_each_napi_queue(bp, i) {
+ memset(queue_name, 0, sizeof(queue_name));
+
+ if (IS_FCOE_IDX(i))
+ sprintf(queue_name, "fcoe");
+ else
+ sprintf(queue_name, "%d", i);
+
for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
- sprintf(buf + (k + j)*ETH_GSTRING_LEN,
- bnx2x_q_stats_arr[j].string, i);
+ snprintf(buf + (k + j)*ETH_GSTRING_LEN,
+ ETH_GSTRING_LEN,
+ bnx2x_q_stats_arr[j].string,
+ queue_name);
k += BNX2X_NUM_Q_STATS;
}
if (IS_MF_MODE_STAT(bp))
@@ -1958,7 +2017,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
if (is_multi(bp)) {
k = 0;
- for_each_queue(bp, i) {
+ for_each_napi_queue(bp, i) {
hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
if (bnx2x_q_stats_arr[j].size == 0) {
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index 4cfd4e9b5586..6238d4f63989 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -434,7 +434,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
-#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_MASK 0x00000700
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_SHIFT 8
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED 0x00000000
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF 0x00000100
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200
+#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300
};
@@ -679,7 +684,7 @@ struct shm_dev_info { /* size */
#define E1VN_MAX 1
#define E1HVN_MAX 4
-
+#define E2_VF_MAX 64
/* This value (in milliseconds) determines the frequency of the driver
* issuing the PULSE message code. The firmware monitors this periodic
* pulse to determine when to switch to an OS-absent mode. */
@@ -815,6 +820,11 @@ struct drv_func_mb {
#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000
#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234
+#define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000
+#define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000
+#define DRV_MSG_CODE_SET_MF_BW 0xe0000000
+#define REQ_BC_VER_4_SET_MF_BW 0x00060202
+#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000
@@ -888,6 +898,7 @@ struct drv_func_mb {
u32 drv_status;
#define DRV_STATUS_PMF 0x00000001
+#define DRV_STATUS_SET_MF_BW 0x00000004
#define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00
#define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100
@@ -896,6 +907,8 @@ struct drv_func_mb {
#define DRV_STATUS_DCC_RESERVED1 0x00000800
#define DRV_STATUS_DCC_SET_PROTOCOL 0x00001000
#define DRV_STATUS_DCC_SET_PRIORITY 0x00002000
+#define DRV_STATUS_DCBX_EVENT_MASK 0x000f0000
+#define DRV_STATUS_DCBX_NEGOTIATION_RESULTS 0x00010000
u32 virt_mac_upper;
#define VIRT_MAC_SIGN_MASK 0xffff0000
@@ -988,12 +1001,43 @@ struct func_mf_cfg {
};
+/* This structure is not applicable and should not be accessed on 57711 */
+struct func_ext_cfg {
+ u32 func_cfg;
+#define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF
+#define MACP_FUNC_CFG_FLAGS_SHIFT 0
+#define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001
+#define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002
+#define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004
+#define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008
+
+ u32 iscsi_mac_addr_upper;
+ u32 iscsi_mac_addr_lower;
+
+ u32 fcoe_mac_addr_upper;
+ u32 fcoe_mac_addr_lower;
+
+ u32 fcoe_wwn_port_name_upper;
+ u32 fcoe_wwn_port_name_lower;
+
+ u32 fcoe_wwn_node_name_upper;
+ u32 fcoe_wwn_node_name_lower;
+
+ u32 preserve_data;
+#define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0)
+#define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1)
+#define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2)
+#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3)
+#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4)
+};
+
struct mf_cfg {
struct shared_mf_cfg shared_mf_config;
struct port_mf_cfg port_mf_config[PORT_MAX];
struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
+ struct func_ext_cfg func_ext_config[E1H_FUNC_MAX];
};
@@ -1049,6 +1093,251 @@ struct fw_flr_mb {
struct fw_flr_ack ack;
};
+/**** SUPPORT FOR SHMEM ARRRAYS ***
+ * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to
+ * define arrays with storage types smaller then unsigned dwords.
+ * The macros below add generic support for SHMEM arrays with numeric elements
+ * that can span 2,4,8 or 16 bits. The array underlying type is a 32 bit dword
+ * array with individual bit-filed elements accessed using shifts and masks.
+ *
+ */
+
+/* eb is the bitwidth of a single element */
+#define SHMEM_ARRAY_MASK(eb) ((1<<(eb))-1)
+#define SHMEM_ARRAY_ENTRY(i, eb) ((i)/(32/(eb)))
+
+/* the bit-position macro allows the used to flip the order of the arrays
+ * elements on a per byte or word boundary.
+ *
+ * example: an array with 8 entries each 4 bit wide. This array will fit into
+ * a single dword. The diagrmas below show the array order of the nibbles.
+ *
+ * SHMEM_ARRAY_BITPOS(i, 4, 4) defines the stadard ordering:
+ *
+ * | | | |
+ * 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+ * | | | |
+ *
+ * SHMEM_ARRAY_BITPOS(i, 4, 8) defines a flip ordering per byte:
+ *
+ * | | | |
+ * 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 |
+ * | | | |
+ *
+ * SHMEM_ARRAY_BITPOS(i, 4, 16) defines a flip ordering per word:
+ *
+ * | | | |
+ * 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 |
+ * | | | |
+ */
+#define SHMEM_ARRAY_BITPOS(i, eb, fb) \
+ ((((32/(fb)) - 1 - ((i)/((fb)/(eb))) % (32/(fb))) * (fb)) + \
+ (((i)%((fb)/(eb))) * (eb)))
+
+#define SHMEM_ARRAY_GET(a, i, eb, fb) \
+ ((a[SHMEM_ARRAY_ENTRY(i, eb)] >> SHMEM_ARRAY_BITPOS(i, eb, fb)) & \
+ SHMEM_ARRAY_MASK(eb))
+
+#define SHMEM_ARRAY_SET(a, i, eb, fb, val) \
+do { \
+ a[SHMEM_ARRAY_ENTRY(i, eb)] &= ~(SHMEM_ARRAY_MASK(eb) << \
+ SHMEM_ARRAY_BITPOS(i, eb, fb)); \
+ a[SHMEM_ARRAY_ENTRY(i, eb)] |= (((val) & SHMEM_ARRAY_MASK(eb)) << \
+ SHMEM_ARRAY_BITPOS(i, eb, fb)); \
+} while (0)
+
+
+/****START OF DCBX STRUCTURES DECLARATIONS****/
+#define DCBX_MAX_NUM_PRI_PG_ENTRIES 8
+#define DCBX_PRI_PG_BITWIDTH 4
+#define DCBX_PRI_PG_FBITS 8
+#define DCBX_PRI_PG_GET(a, i) \
+ SHMEM_ARRAY_GET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS)
+#define DCBX_PRI_PG_SET(a, i, val) \
+ SHMEM_ARRAY_SET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS, val)
+#define DCBX_MAX_NUM_PG_BW_ENTRIES 8
+#define DCBX_BW_PG_BITWIDTH 8
+#define DCBX_PG_BW_GET(a, i) \
+ SHMEM_ARRAY_GET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH)
+#define DCBX_PG_BW_SET(a, i, val) \
+ SHMEM_ARRAY_SET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH, val)
+#define DCBX_STRICT_PRI_PG 15
+#define DCBX_MAX_APP_PROTOCOL 16
+#define FCOE_APP_IDX 0
+#define ISCSI_APP_IDX 1
+#define PREDEFINED_APP_IDX_MAX 2
+
+struct dcbx_ets_feature {
+ u32 enabled;
+ u32 pg_bw_tbl[2];
+ u32 pri_pg_tbl[1];
+};
+
+struct dcbx_pfc_feature {
+#ifdef __BIG_ENDIAN
+ u8 pri_en_bitmap;
+#define DCBX_PFC_PRI_0 0x01
+#define DCBX_PFC_PRI_1 0x02
+#define DCBX_PFC_PRI_2 0x04
+#define DCBX_PFC_PRI_3 0x08
+#define DCBX_PFC_PRI_4 0x10
+#define DCBX_PFC_PRI_5 0x20
+#define DCBX_PFC_PRI_6 0x40
+#define DCBX_PFC_PRI_7 0x80
+ u8 pfc_caps;
+ u8 reserved;
+ u8 enabled;
+#elif defined(__LITTLE_ENDIAN)
+ u8 enabled;
+ u8 reserved;
+ u8 pfc_caps;
+ u8 pri_en_bitmap;
+#define DCBX_PFC_PRI_0 0x01
+#define DCBX_PFC_PRI_1 0x02
+#define DCBX_PFC_PRI_2 0x04
+#define DCBX_PFC_PRI_3 0x08
+#define DCBX_PFC_PRI_4 0x10
+#define DCBX_PFC_PRI_5 0x20
+#define DCBX_PFC_PRI_6 0x40
+#define DCBX_PFC_PRI_7 0x80
+#endif
+};
+
+struct dcbx_app_priority_entry {
+#ifdef __BIG_ENDIAN
+ u16 app_id;
+ u8 pri_bitmap;
+ u8 appBitfield;
+#define DCBX_APP_ENTRY_VALID 0x01
+#define DCBX_APP_ENTRY_SF_MASK 0x30
+#define DCBX_APP_ENTRY_SF_SHIFT 4
+#define DCBX_APP_SF_ETH_TYPE 0x10
+#define DCBX_APP_SF_PORT 0x20
+#elif defined(__LITTLE_ENDIAN)
+ u8 appBitfield;
+#define DCBX_APP_ENTRY_VALID 0x01
+#define DCBX_APP_ENTRY_SF_MASK 0x30
+#define DCBX_APP_ENTRY_SF_SHIFT 4
+#define DCBX_APP_SF_ETH_TYPE 0x10
+#define DCBX_APP_SF_PORT 0x20
+ u8 pri_bitmap;
+ u16 app_id;
+#endif
+};
+
+struct dcbx_app_priority_feature {
+#ifdef __BIG_ENDIAN
+ u8 reserved;
+ u8 default_pri;
+ u8 tc_supported;
+ u8 enabled;
+#elif defined(__LITTLE_ENDIAN)
+ u8 enabled;
+ u8 tc_supported;
+ u8 default_pri;
+ u8 reserved;
+#endif
+ struct dcbx_app_priority_entry app_pri_tbl[DCBX_MAX_APP_PROTOCOL];
+};
+
+struct dcbx_features {
+ struct dcbx_ets_feature ets;
+ struct dcbx_pfc_feature pfc;
+ struct dcbx_app_priority_feature app;
+};
+
+struct lldp_params {
+#ifdef __BIG_ENDIAN
+ u8 msg_fast_tx_interval;
+ u8 msg_tx_hold;
+ u8 msg_tx_interval;
+ u8 admin_status;
+#define LLDP_TX_ONLY 0x01
+#define LLDP_RX_ONLY 0x02
+#define LLDP_TX_RX 0x03
+#define LLDP_DISABLED 0x04
+ u8 reserved1;
+ u8 tx_fast;
+ u8 tx_crd_max;
+ u8 tx_crd;
+#elif defined(__LITTLE_ENDIAN)
+ u8 admin_status;
+#define LLDP_TX_ONLY 0x01
+#define LLDP_RX_ONLY 0x02
+#define LLDP_TX_RX 0x03
+#define LLDP_DISABLED 0x04
+ u8 msg_tx_interval;
+ u8 msg_tx_hold;
+ u8 msg_fast_tx_interval;
+ u8 tx_crd;
+ u8 tx_crd_max;
+ u8 tx_fast;
+ u8 reserved1;
+#endif
+#define REM_CHASSIS_ID_STAT_LEN 4
+#define REM_PORT_ID_STAT_LEN 4
+ u32 peer_chassis_id[REM_CHASSIS_ID_STAT_LEN];
+ u32 peer_port_id[REM_PORT_ID_STAT_LEN];
+};
+
+struct lldp_dcbx_stat {
+#define LOCAL_CHASSIS_ID_STAT_LEN 2
+#define LOCAL_PORT_ID_STAT_LEN 2
+ u32 local_chassis_id[LOCAL_CHASSIS_ID_STAT_LEN];
+ u32 local_port_id[LOCAL_PORT_ID_STAT_LEN];
+ u32 num_tx_dcbx_pkts;
+ u32 num_rx_dcbx_pkts;
+};
+
+struct lldp_admin_mib {
+ u32 ver_cfg_flags;
+#define DCBX_ETS_CONFIG_TX_ENABLED 0x00000001
+#define DCBX_PFC_CONFIG_TX_ENABLED 0x00000002
+#define DCBX_APP_CONFIG_TX_ENABLED 0x00000004
+#define DCBX_ETS_RECO_TX_ENABLED 0x00000008
+#define DCBX_ETS_RECO_VALID 0x00000010
+#define DCBX_ETS_WILLING 0x00000020
+#define DCBX_PFC_WILLING 0x00000040
+#define DCBX_APP_WILLING 0x00000080
+#define DCBX_VERSION_CEE 0x00000100
+#define DCBX_VERSION_IEEE 0x00000200
+#define DCBX_DCBX_ENABLED 0x00000400
+#define DCBX_CEE_VERSION_MASK 0x0000f000
+#define DCBX_CEE_VERSION_SHIFT 12
+#define DCBX_CEE_MAX_VERSION_MASK 0x000f0000
+#define DCBX_CEE_MAX_VERSION_SHIFT 16
+ struct dcbx_features features;
+};
+
+struct lldp_remote_mib {
+ u32 prefix_seq_num;
+ u32 flags;
+#define DCBX_ETS_TLV_RX 0x00000001
+#define DCBX_PFC_TLV_RX 0x00000002
+#define DCBX_APP_TLV_RX 0x00000004
+#define DCBX_ETS_RX_ERROR 0x00000010
+#define DCBX_PFC_RX_ERROR 0x00000020
+#define DCBX_APP_RX_ERROR 0x00000040
+#define DCBX_ETS_REM_WILLING 0x00000100
+#define DCBX_PFC_REM_WILLING 0x00000200
+#define DCBX_APP_REM_WILLING 0x00000400
+#define DCBX_REMOTE_ETS_RECO_VALID 0x00001000
+ struct dcbx_features features;
+ u32 suffix_seq_num;
+};
+
+struct lldp_local_mib {
+ u32 prefix_seq_num;
+ u32 error;
+#define DCBX_LOCAL_ETS_ERROR 0x00000001
+#define DCBX_LOCAL_PFC_ERROR 0x00000002
+#define DCBX_LOCAL_APP_ERROR 0x00000004
+#define DCBX_LOCAL_PFC_MISMATCH 0x00000010
+#define DCBX_LOCAL_APP_MISMATCH 0x00000020
+ struct dcbx_features features;
+ u32 suffix_seq_num;
+};
+/***END OF DCBX STRUCTURES DECLARATIONS***/
struct shmem2_region {
@@ -1072,7 +1361,12 @@ struct shmem2_region {
#define SHMEM_MF_CFG_ADDR_NONE 0x00000000
struct fw_flr_mb flr_mb;
- u32 reserved[3];
+ u32 dcbx_lldp_params_offset;
+#define SHMEM_LLDP_DCBX_PARAMS_NONE 0x00000000
+ u32 dcbx_neg_res_offset;
+#define SHMEM_DCBX_NEG_RES_NONE 0x00000000
+ u32 dcbx_remote_mib_offset;
+#define SHMEM_DCBX_REMOTE_MIB_NONE 0x00000000
/*
* The other shmemX_base_addr holds the other path's shmem address
* required for example in case of common phy init, or for path1 to know
@@ -1081,6 +1375,10 @@ struct shmem2_region {
*/
u32 other_shmem_base_addr;
u32 other_shmem2_base_addr;
+ u32 reserved1[E2_VF_MAX / 32];
+ u32 reserved2[E2_FUNC_MAX][E2_VF_MAX / 32];
+ u32 dcbx_lldp_dcbx_stat_offset;
+#define SHMEM_LLDP_DCBX_STAT_NONE 0x00000000
};
@@ -1534,8 +1832,8 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 6
-#define BCM_5710_FW_MINOR_VERSION 0
-#define BCM_5710_FW_REVISION_VERSION 34
+#define BCM_5710_FW_MINOR_VERSION 2
+#define BCM_5710_FW_REVISION_VERSION 5
#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
@@ -2983,6 +3281,25 @@ struct fairness_vars_per_vn {
/*
+ * The data for flow control configuration
+ */
+struct flow_control_configuration {
+ struct priority_cos
+ traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES];
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 dcb_version;
+ u8 dcb_enabled;
+#elif defined(__LITTLE_ENDIAN)
+ u8 dcb_enabled;
+ u8 dcb_version;
+ u16 reserved1;
+#endif
+ u32 reserved2;
+};
+
+
+/*
* FW version stored in the Xstorm RAM
*/
struct fw_version {
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index a306b0e46b61..66df29fcf751 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
/****************************************************************************
* SRC initializations
****************************************************************************/
-
+#ifdef BCM_CNIC
/* called during init func stage */
static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
U64_HI((u64)t2_mapping +
(src_cid_count-1) * sizeof(struct src_ent)));
}
-
+#endif
#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 580919619252..43b0de24f391 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -164,7 +164,8 @@
#define EDC_MODE_PASSIVE_DAC 0x0055
-
+#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
+#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
/**********************************************************/
/* INTERFACE */
/**********************************************************/
@@ -205,6 +206,270 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
return val;
}
+/******************************************************************/
+/* ETS section */
+/******************************************************************/
+void bnx2x_ets_disabled(struct link_params *params)
+{
+ /* ETS disabled configuration*/
+ struct bnx2x *bp = params->bp;
+
+ DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
+
+ /**
+ * mapping between entry priority to client number (0,1,2 -debug and
+ * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
+ * 3bits client num.
+ * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
+ * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
+ */
+
+ REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
+ /**
+ * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ * as strict. Bits 0,1,2 - debug and management entries, 3 -
+ * COS0 entry, 4 - COS1 entry.
+ * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
+ * bit4 bit3 bit2 bit1 bit0
+ * MCP and debug are strict
+ */
+
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
+ /* defines which entries (clients) are subjected to WFQ arbitration */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
+ /**
+ * For strict priority entries defines the number of consecutive
+ * slots for the highest priority.
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
+ /**
+ * mapping between the CREDIT_WEIGHT registers and actual client
+ * numbers
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
+
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
+ REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
+ /* ETS mode disable */
+ REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
+ /**
+ * If ETS mode is enabled (there is no strict priority) defines a WFQ
+ * weight for COS0/COS1.
+ */
+ REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
+ REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
+ /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
+ REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
+ REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
+ /* Defines the number of consecutive slots for the strict priority */
+ REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
+}
+
+void bnx2x_ets_bw_limit_common(const struct link_params *params)
+{
+ /* ETS disabled configuration */
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
+ /**
+ * defines which entries (clients) are subjected to WFQ arbitration
+ * COS0 0x8
+ * COS1 0x10
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
+ /**
+ * mapping between the ARB_CREDIT_WEIGHT registers and actual
+ * client numbers (WEIGHT_0 does not actually have to represent
+ * client 0)
+ * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
+ * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
+
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
+ ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
+ ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
+
+ /* ETS mode enabled*/
+ REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
+
+ /* Defines the number of consecutive slots for the strict priority */
+ REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
+ /**
+ * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
+ * entry, 4 - COS1 entry.
+ * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
+ * bit4 bit3 bit2 bit1 bit0
+ * MCP and debug are strict
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
+
+ /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
+ REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
+ ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
+ REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
+ ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
+}
+
+void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
+ const u32 cos1_bw)
+{
+ /* ETS disabled configuration*/
+ struct bnx2x *bp = params->bp;
+ const u32 total_bw = cos0_bw + cos1_bw;
+ u32 cos0_credit_weight = 0;
+ u32 cos1_credit_weight = 0;
+
+ DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
+
+ if ((0 == total_bw) ||
+ (0 == cos0_bw) ||
+ (0 == cos1_bw)) {
+ DP(NETIF_MSG_LINK,
+ "bnx2x_ets_bw_limit: Total BW can't be zero\n");
+ return;
+ }
+
+ cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
+ total_bw;
+ cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
+ total_bw;
+
+ bnx2x_ets_bw_limit_common(params);
+
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
+
+ REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
+ REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
+}
+
+u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
+{
+ /* ETS disabled configuration*/
+ struct bnx2x *bp = params->bp;
+ u32 val = 0;
+
+ DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
+ /**
+ * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ * as strict. Bits 0,1,2 - debug and management entries,
+ * 3 - COS0 entry, 4 - COS1 entry.
+ * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
+ * bit4 bit3 bit2 bit1 bit0
+ * MCP and debug are strict
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
+ /**
+ * For strict priority entries defines the number of consecutive slots
+ * for the highest priority.
+ */
+ REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
+ /* ETS mode disable */
+ REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
+ /* Defines the number of consecutive slots for the strict priority */
+ REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
+
+ /* Defines the number of consecutive slots for the strict priority */
+ REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
+
+ /**
+ * mapping between entry priority to client number (0,1,2 -debug and
+ * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
+ * 3bits client num.
+ * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
+ * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
+ * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
+ */
+ val = (0 == strict_cos) ? 0x2318 : 0x22E0;
+ REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
+
+ return 0;
+}
+/******************************************************************/
+/* ETS section */
+/******************************************************************/
+
+static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
+ u32 pfc_frames_sent[2],
+ u32 pfc_frames_received[2])
+{
+ /* Read pfc statistic */
+ struct bnx2x *bp = params->bp;
+ u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+
+ DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
+
+ REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
+ pfc_frames_sent, 2);
+
+ REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
+ pfc_frames_received, 2);
+
+}
+static void bnx2x_emac_get_pfc_stat(struct link_params *params,
+ u32 pfc_frames_sent[2],
+ u32 pfc_frames_received[2])
+{
+ /* Read pfc statistic */
+ struct bnx2x *bp = params->bp;
+ u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u32 val_xon = 0;
+ u32 val_xoff = 0;
+
+ DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
+
+ /* PFC received frames */
+ val_xoff = REG_RD(bp, emac_base +
+ EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
+ val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
+ val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
+ val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
+
+ pfc_frames_received[0] = val_xon + val_xoff;
+
+ /* PFC received sent */
+ val_xoff = REG_RD(bp, emac_base +
+ EMAC_REG_RX_PFC_STATS_XOFF_SENT);
+ val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
+ val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
+ val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
+
+ pfc_frames_sent[0] = val_xon + val_xoff;
+}
+
+void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
+ u32 pfc_frames_sent[2],
+ u32 pfc_frames_received[2])
+{
+ /* Read pfc statistic */
+ struct bnx2x *bp = params->bp;
+ u32 val = 0;
+ DP(NETIF_MSG_LINK, "pfc statistic\n");
+
+ if (!vars->link_up)
+ return;
+
+ val = REG_RD(bp, MISC_REG_RESET_REG_2);
+ if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
+ == 0) {
+ DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
+ bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
+ pfc_frames_received);
+ } else {
+ DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
+ bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
+ pfc_frames_received);
+ }
+}
+/******************************************************************/
+/* MAC/PBF section */
+/******************************************************************/
static void bnx2x_emac_init(struct link_params *params,
struct link_vars *vars)
{
@@ -315,24 +580,55 @@ static u8 bnx2x_emac_enable(struct link_params *params,
/* pause enable/disable */
bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
EMAC_RX_MODE_FLOW_EN);
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
- bnx2x_bits_en(bp, emac_base +
- EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
- bnx2x_bits_en(bp, emac_base +
- EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
+ (EMAC_TX_MODE_EXT_PAUSE_EN |
+ EMAC_TX_MODE_FLOW_EN));
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED)) {
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ bnx2x_bits_en(bp, emac_base +
+ EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_FLOW_EN);
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ bnx2x_bits_en(bp, emac_base +
+ EMAC_REG_EMAC_TX_MODE,
+ (EMAC_TX_MODE_EXT_PAUSE_EN |
+ EMAC_TX_MODE_FLOW_EN));
+ } else
+ bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_FLOW_EN);
}
/* KEEP_VLAN_TAG, promiscuous */
val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
+
+ /**
+ * Setting this bit causes MAC control frames (except for pause
+ * frames) to be passed on for processing. This setting has no
+ * affect on the operation of the pause frames. This bit effects
+ * all packets regardless of RX Parser packet sorting logic.
+ * Turn the PFC off to make sure we are in Xon state before
+ * enabling it.
+ */
+ EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
+ DP(NETIF_MSG_LINK, "PFC is enabled\n");
+ /* Enable PFC again */
+ EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
+ EMAC_REG_RX_PFC_MODE_RX_EN |
+ EMAC_REG_RX_PFC_MODE_TX_EN |
+ EMAC_REG_RX_PFC_MODE_PRIORITIES);
+
+ EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
+ ((0x0101 <<
+ EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
+ (0x00ff <<
+ EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
+ val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
+ }
EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
/* Set Loopback */
@@ -362,7 +658,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
/* enable the NIG in/out to the emac */
REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
val = 0;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED) ||
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
val = 1;
REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
@@ -383,9 +681,38 @@ static u8 bnx2x_emac_enable(struct link_params *params,
return 0;
}
-static void bnx2x_update_bmac2(struct link_params *params,
- struct link_vars *vars,
- u8 is_lb)
+static void bnx2x_update_pfc_bmac1(struct link_params *params,
+ struct link_vars *vars)
+{
+ u32 wb_data[2];
+ struct bnx2x *bp = params->bp;
+ u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+
+ u32 val = 0x14;
+ if ((!(params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED)) &&
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
+ /* Enable BigMAC to react on received Pause packets */
+ val |= (1<<5);
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
+
+ /* tx control */
+ val = 0xc0;
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED) &&
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
+ val |= 0x800000;
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
+}
+
+static void bnx2x_update_pfc_bmac2(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
{
/*
* Set rx control: Strip CRC and enable BigMAC to relay
@@ -397,7 +724,9 @@ static void bnx2x_update_bmac2(struct link_params *params,
NIG_REG_INGRESS_BMAC0_MEM;
u32 val = 0x14;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ if ((!(params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED)) &&
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
/* Enable BigMAC to react on received Pause packets */
val |= (1<<5);
wb_data[0] = val;
@@ -408,14 +737,47 @@ static void bnx2x_update_bmac2(struct link_params *params,
/* Tx control */
val = 0xc0;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED) &&
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
val |= 0x800000;
wb_data[0] = val;
wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL,
- wb_data, 2);
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
+
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
+ DP(NETIF_MSG_LINK, "PFC is enabled\n");
+ /* Enable PFC RX & TX & STATS and set 8 COS */
+ wb_data[0] = 0x0;
+ wb_data[0] |= (1<<0); /* RX */
+ wb_data[0] |= (1<<1); /* TX */
+ wb_data[0] |= (1<<2); /* Force initial Xon */
+ wb_data[0] |= (1<<3); /* 8 cos */
+ wb_data[0] |= (1<<5); /* STATS */
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
+ wb_data, 2);
+ /* Clear the force Xon */
+ wb_data[0] &= ~(1<<2);
+ } else {
+ DP(NETIF_MSG_LINK, "PFC is disabled\n");
+ /* disable PFC RX & TX & STATS and set 8 COS */
+ wb_data[0] = 0x8;
+ wb_data[1] = 0;
+ }
+
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
+ /**
+ * Set Time (based unit is 512 bit time) between automatic
+ * re-sending of PP packets amd enable automatic re-send of
+ * Per-Priroity Packet as long as pp_gen is asserted and
+ * pp_disable is low.
+ */
val = 0x8000;
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+ val |= (1<<16); /* enable automatic re-send */
+
wb_data[0] = val;
wb_data[1] = 0;
REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
@@ -427,6 +789,9 @@ static void bnx2x_update_bmac2(struct link_params *params,
val |= 0x4; /* Local loopback */
DP(NETIF_MSG_LINK, "enable bmac loopback\n");
}
+ /* When PFC enabled, Pass pause frames towards the NIG. */
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+ val |= ((1<<6)|(1<<5));
wb_data[0] = val;
wb_data[1] = 0;
@@ -434,6 +799,239 @@ static void bnx2x_update_bmac2(struct link_params *params,
wb_data, 2);
}
+static void bnx2x_update_pfc_brb(struct link_params *params,
+ struct link_vars *vars,
+ struct bnx2x_nig_brb_pfc_port_params *pfc_params)
+{
+ struct bnx2x *bp = params->bp;
+ int set_pfc = params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED;
+
+ /* default - pause configuration */
+ u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
+ u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
+ u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
+ u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
+
+ if (set_pfc && pfc_params)
+ /* First COS */
+ if (!pfc_params->cos0_pauseable) {
+ pause_xoff_th =
+ PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
+ pause_xon_th =
+ PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
+ full_xoff_th =
+ PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
+ full_xon_th =
+ PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
+ }
+ /* The number of free blocks below which the pause signal to class 0
+ of MAC #n is asserted. n=0,1 */
+ REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
+ /* The number of free blocks above which the pause signal to class 0
+ of MAC #n is de-asserted. n=0,1 */
+ REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
+ /* The number of free blocks below which the full signal to class 0
+ of MAC #n is asserted. n=0,1 */
+ REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
+ /* The number of free blocks above which the full signal to class 0
+ of MAC #n is de-asserted. n=0,1 */
+ REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
+
+ if (set_pfc && pfc_params) {
+ /* Second COS */
+ if (pfc_params->cos1_pauseable) {
+ pause_xoff_th =
+ PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
+ pause_xon_th =
+ PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
+ full_xoff_th =
+ PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
+ full_xon_th =
+ PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
+ } else {
+ pause_xoff_th =
+ PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
+ pause_xon_th =
+ PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
+ full_xoff_th =
+ PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
+ full_xon_th =
+ PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
+ }
+ /**
+ * The number of free blocks below which the pause signal to
+ * class 1 of MAC #n is asserted. n=0,1
+ **/
+ REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
+ /**
+ * The number of free blocks above which the pause signal to
+ * class 1 of MAC #n is de-asserted. n=0,1
+ **/
+ REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
+ /**
+ * The number of free blocks below which the full signal to
+ * class 1 of MAC #n is asserted. n=0,1
+ **/
+ REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
+ /**
+ * The number of free blocks above which the full signal to
+ * class 1 of MAC #n is de-asserted. n=0,1
+ **/
+ REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
+ }
+}
+
+static void bnx2x_update_pfc_nig(struct link_params *params,
+ struct link_vars *vars,
+ struct bnx2x_nig_brb_pfc_port_params *nig_params)
+{
+ u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
+ u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
+ u32 pkt_priority_to_cos = 0;
+ u32 val;
+ struct bnx2x *bp = params->bp;
+ int port = params->port;
+ int set_pfc = params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED;
+ DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
+
+ /**
+ * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
+ * MAC control frames (that are not pause packets)
+ * will be forwarded to the XCM.
+ */
+ xcm_mask = REG_RD(bp,
+ port ? NIG_REG_LLH1_XCM_MASK :
+ NIG_REG_LLH0_XCM_MASK);
+ /**
+ * nig params will override non PFC params, since it's possible to
+ * do transition from PFC to SAFC
+ */
+ if (set_pfc) {
+ pause_enable = 0;
+ llfc_out_en = 0;
+ llfc_enable = 0;
+ ppp_enable = 1;
+ xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
+ NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
+ xcm0_out_en = 0;
+ p0_hwpfc_enable = 1;
+ } else {
+ if (nig_params) {
+ llfc_out_en = nig_params->llfc_out_en;
+ llfc_enable = nig_params->llfc_enable;
+ pause_enable = nig_params->pause_enable;
+ } else /*defaul non PFC mode - PAUSE */
+ pause_enable = 1;
+
+ xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
+ NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
+ xcm0_out_en = 1;
+ }
+
+ REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
+ NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
+ REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
+ NIG_REG_LLFC_ENABLE_0, llfc_enable);
+ REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
+ NIG_REG_PAUSE_ENABLE_0, pause_enable);
+
+ REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
+ NIG_REG_PPP_ENABLE_0, ppp_enable);
+
+ REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
+ NIG_REG_LLH0_XCM_MASK, xcm_mask);
+
+ REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
+
+ /* output enable for RX_XCM # IF */
+ REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
+
+ /* HW PFC TX enable */
+ REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
+
+ /* 0x2 = BMAC, 0x1= EMAC */
+ switch (vars->mac_type) {
+ case MAC_TYPE_EMAC:
+ val = 1;
+ break;
+ case MAC_TYPE_BMAC:
+ val = 0;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
+
+ if (nig_params) {
+ pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
+
+ REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
+ NIG_REG_P0_RX_COS0_PRIORITY_MASK,
+ nig_params->rx_cos0_priority_mask);
+
+ REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
+ NIG_REG_P0_RX_COS1_PRIORITY_MASK,
+ nig_params->rx_cos1_priority_mask);
+
+ REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
+ NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
+ nig_params->llfc_high_priority_classes);
+
+ REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
+ NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
+ nig_params->llfc_low_priority_classes);
+ }
+ REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
+ NIG_REG_P0_PKT_PRIORITY_TO_COS,
+ pkt_priority_to_cos);
+}
+
+
+void bnx2x_update_pfc(struct link_params *params,
+ struct link_vars *vars,
+ struct bnx2x_nig_brb_pfc_port_params *pfc_params)
+{
+ /**
+ * The PFC and pause are orthogonal to one another, meaning when
+ * PFC is enabled, the pause are disabled, and when PFC is
+ * disabled, pause are set according to the pause result.
+ */
+ u32 val;
+ struct bnx2x *bp = params->bp;
+
+ /* update NIG params */
+ bnx2x_update_pfc_nig(params, vars, pfc_params);
+
+ /* update BRB params */
+ bnx2x_update_pfc_brb(params, vars, pfc_params);
+
+ if (!vars->link_up)
+ return;
+
+ val = REG_RD(bp, MISC_REG_RESET_REG_2);
+ if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
+ == 0) {
+ DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
+ bnx2x_emac_enable(params, vars, 0);
+ return;
+ }
+
+ DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
+ if (CHIP_IS_E2(bp))
+ bnx2x_update_pfc_bmac2(params, vars, 0);
+ else
+ bnx2x_update_pfc_bmac1(params, vars);
+
+ val = 0;
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED) ||
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
+ val = 1;
+ REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
+}
static u8 bnx2x_bmac1_enable(struct link_params *params,
struct link_vars *vars,
@@ -465,15 +1063,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
wb_data, 2);
- /* tx control */
- val = 0xc0;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
- val |= 0x800000;
- wb_data[0] = val;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
- wb_data, 2);
-
/* mac control */
val = 0x3;
if (is_lb) {
@@ -491,14 +1080,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
wb_data, 2);
- /* rx control set to don't strip crc */
- val = 0x14;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
- val |= 0x20;
- wb_data[0] = val;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
- wb_data, 2);
+ bnx2x_update_pfc_bmac1(params, vars);
/* set tx mtu */
wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
@@ -595,7 +1177,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params,
REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
wb_data, 2);
udelay(30);
- bnx2x_update_bmac2(params, vars, is_lb);
+ bnx2x_update_pfc_bmac2(params, vars, is_lb);
return 0;
}
@@ -627,7 +1209,9 @@ static u8 bnx2x_bmac_enable(struct link_params *params,
REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
val = 0;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_PFC_ENABLED) ||
+ (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
val = 1;
REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
@@ -3904,7 +4488,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
- return 0;;
+ return 0;
msleep(1);
}
return -EINVAL;
@@ -3988,7 +4572,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
- return 0;;
+ return 0;
msleep(1);
}
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h
index 171abf8097ee..bedab1a942c4 100644
--- a/drivers/net/bnx2x/bnx2x_link.h
+++ b/drivers/net/bnx2x/bnx2x_link.h
@@ -65,6 +65,22 @@
#define FW_PARAM_MDIO_CTRL_OFFSET 16
#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
(phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET)
+
+#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE 170
+#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE 0
+
+#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE 250
+#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE 0
+
+#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE 10
+#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE 90
+
+#define PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE 50
+#define PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE 250
+
+#define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170
+#define PFC_BRB_FULL_LB_XON_THRESHOLD 250
+
/***********************************************************/
/* Structs */
/***********************************************************/
@@ -216,6 +232,7 @@ struct link_params {
u32 feature_config_flags;
#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
+#define FEATURE_CONFIG_PFC_ENABLED (1<<1)
#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
/* Will be populated during common init */
@@ -332,4 +349,43 @@ u8 bnx2x_phy_probe(struct link_params *params);
u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base,
u32 shmem2_base, u8 port);
+/* PFC port configuration params */
+struct bnx2x_nig_brb_pfc_port_params {
+ /* NIG */
+ u32 pause_enable;
+ u32 llfc_out_en;
+ u32 llfc_enable;
+ u32 pkt_priority_to_cos;
+ u32 rx_cos0_priority_mask;
+ u32 rx_cos1_priority_mask;
+ u32 llfc_high_priority_classes;
+ u32 llfc_low_priority_classes;
+ /* BRB */
+ u32 cos0_pauseable;
+ u32 cos1_pauseable;
+};
+
+/**
+ * Used to update the PFC attributes in EMAC, BMAC, NIG and BRB
+ * when link is already up
+ */
+void bnx2x_update_pfc(struct link_params *params,
+ struct link_vars *vars,
+ struct bnx2x_nig_brb_pfc_port_params *pfc_params);
+
+
+/* Used to configure the ETS to disable */
+void bnx2x_ets_disabled(struct link_params *params);
+
+/* Used to configure the ETS to BW limited */
+void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
+ const u32 cos1_bw);
+
+/* Used to configure the ETS to strict */
+u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos);
+
+/* Read pfc statistic*/
+void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
+ u32 pfc_frames_sent[2],
+ u32 pfc_frames_received[2]);
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 9709b8569666..489a5512a04d 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -55,6 +55,7 @@
#include "bnx2x_init.h"
#include "bnx2x_init_ops.h"
#include "bnx2x_cmn.h"
+#include "bnx2x_dcb.h"
#include <linux/firmware.h>
#include "bnx2x_fw_file_hdr.h"
@@ -121,6 +122,10 @@ MODULE_PARM_DESC(debug, " Default debug msglevel");
static struct workqueue_struct *bnx2x_wq;
+#ifdef BCM_CNIC
+static u8 ALL_ENODE_MACS[] = {0x01, 0x10, 0x18, 0x01, 0x00, 0x01};
+#endif
+
enum bnx2x_board_type {
BCM57710 = 0,
BCM57711 = 1,
@@ -921,7 +926,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
sp_sb_data.p_func.vf_valid);
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
int loop;
struct hc_status_block_data_e2 sb_data_e2;
@@ -961,6 +966,10 @@ void bnx2x_panic_dump(struct bnx2x *bp)
/* host sb data */
+#ifdef BCM_CNIC
+ if (IS_FCOE_FP(fp))
+ continue;
+#endif
BNX2X_ERR(" run indexes (");
for (j = 0; j < HC_SB_MAX_SM; j++)
pr_cont("0x%x%s",
@@ -1029,7 +1038,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
#ifdef BNX2X_STOP_ON_ERROR
/* Rings */
/* Rx */
- for_each_queue(bp, i) {
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
@@ -1063,7 +1072,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
}
/* Tx */
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
@@ -1298,7 +1307,7 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
#ifdef BCM_CNIC
offset++;
#endif
- for_each_queue(bp, i)
+ for_each_eth_queue(bp, i)
synchronize_irq(bp->msix_table[i + offset].vector);
} else
synchronize_irq(bp->pdev->irq);
@@ -1420,7 +1429,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
return IRQ_HANDLED;
#endif
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
mask = 0x2 << (fp->index + CNIC_CONTEXT_USE);
@@ -2026,13 +2035,28 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
static void bnx2x_read_mf_cfg(struct bnx2x *bp)
{
- int vn;
+ int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1);
if (BP_NOMCP(bp))
return; /* what should be the default bvalue in this case */
+ /* For 2 port configuration the absolute function number formula
+ * is:
+ * abs_func = 2 * vn + BP_PORT + BP_PATH
+ *
+ * and there are 4 functions per port
+ *
+ * For 4 port configuration it is
+ * abs_func = 4 * vn + 2 * BP_PORT + BP_PATH
+ *
+ * and there are 2 functions per port
+ */
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
- int /*abs*/func = 2*vn + BP_PORT(bp);
+ int /*abs*/func = n * (2 * vn + BP_PORT(bp)) + BP_PATH(bp);
+
+ if (func >= E1H_FUNC_MAX)
+ break;
+
bp->mf_config[vn] =
MF_CFG_RD(bp, func_mf_config[func].config);
}
@@ -2238,6 +2262,15 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
return rc;
}
+static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp)
+{
+#ifdef BCM_CNIC
+ if (IS_FCOE_FP(fp) && IS_MF(bp))
+ return false;
+#endif
+ return true;
+}
+
/* must be called under rtnl_lock */
static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters)
{
@@ -2248,10 +2281,21 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters)
u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0;
u8 unmatched_unicast = 0;
+ if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST)
+ unmatched_unicast = 1;
+
if (filters & BNX2X_PROMISCUOUS_MODE) {
/* promiscious - accept all, drop none */
drop_all_ucast = drop_all_bcast = drop_all_mcast = 0;
accp_all_ucast = accp_all_bcast = accp_all_mcast = 1;
+ if (IS_MF_SI(bp)) {
+ /*
+ * SI mode defines to accept in promiscuos mode
+ * only unmatched packets
+ */
+ unmatched_unicast = 1;
+ accp_all_ucast = 0;
+ }
}
if (filters & BNX2X_ACCEPT_UNICAST) {
/* accept matched ucast */
@@ -2260,6 +2304,11 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters)
if (filters & BNX2X_ACCEPT_MULTICAST) {
/* accept matched mcast */
drop_all_mcast = 0;
+ if (IS_MF_SI(bp))
+ /* since mcast addresses won't arrive with ovlan,
+ * fw needs to accept all of them in
+ * switch-independent mode */
+ accp_all_mcast = 1;
}
if (filters & BNX2X_ACCEPT_ALL_UNICAST) {
/* accept all mcast */
@@ -2372,7 +2421,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp,
/* calculate queue flags */
flags |= QUEUE_FLG_CACHE_ALIGN;
flags |= QUEUE_FLG_HC;
- flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
+ flags |= IS_MF_SD(bp) ? QUEUE_FLG_OV : 0;
flags |= QUEUE_FLG_VLAN;
DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
@@ -2380,7 +2429,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp,
if (!fp->disable_tpa)
flags |= QUEUE_FLG_TPA;
- flags |= QUEUE_FLG_STATS;
+ flags = stat_counter_valid(bp, fp) ?
+ (flags | QUEUE_FLG_STATS) : (flags & ~QUEUE_FLG_STATS);
return flags;
}
@@ -2440,7 +2490,10 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp,
rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT;
rxq_init->fw_sb_id = fp->fw_sb_id;
- rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX;
+ if (IS_FCOE_FP(fp))
+ rxq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS;
+ else
+ rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX;
rxq_init->cid = HW_CID(bp, fp->cid);
@@ -2460,6 +2513,12 @@ static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp,
txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX;
txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW;
txq_init->fw_sb_id = fp->fw_sb_id;
+
+ if (IS_FCOE_FP(fp)) {
+ txq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS;
+ txq_init->traffic_type = LLFC_TRAFFIC_TYPE_FCOE;
+ }
+
txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0;
}
@@ -2573,6 +2632,26 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
*/
}
+/* called due to MCP event (on pmf):
+ * reread new bandwidth configuration
+ * configure FW
+ * notify others function about the change
+ */
+static inline void bnx2x_config_mf_bw(struct bnx2x *bp)
+{
+ if (bp->link_vars.link_up) {
+ bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX);
+ bnx2x_link_sync_notify(bp);
+ }
+ storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
+}
+
+static inline void bnx2x_set_mf_bw(struct bnx2x *bp)
+{
+ bnx2x_config_mf_bw(bp);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0);
+}
+
static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
{
DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
@@ -2598,10 +2677,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF;
}
if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) {
-
- bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX);
- bnx2x_link_sync_notify(bp);
- storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
+ bnx2x_config_mf_bw(bp);
dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION;
}
@@ -3022,10 +3098,20 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
if (val & DRV_STATUS_DCC_EVENT_MASK)
bnx2x_dcc_event(bp,
(val & DRV_STATUS_DCC_EVENT_MASK));
+
+ if (val & DRV_STATUS_SET_MF_BW)
+ bnx2x_set_mf_bw(bp);
+
bnx2x__link_status_update(bp);
if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
bnx2x_pmf_update(bp);
+ if (bp->port.pmf &&
+ (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) &&
+ bp->dcbx_enabled > 0)
+ /* start dcbx state machine */
+ bnx2x_dcbx_set_params(bp,
+ BNX2X_DCBX_STATE_NEG_RECEIVED);
} else if (attn & BNX2X_MC_ASSERT_BITS) {
BNX2X_ERR("MC assert!\n");
@@ -3637,11 +3723,23 @@ static void bnx2x_eq_int(struct bnx2x *bp)
#ifdef BCM_CNIC
if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem))
goto next_spqe;
+ if (cid == BNX2X_FCOE_ETH_CID)
+ bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED;
+ else
#endif
- bnx2x_fp(bp, cid, state) =
+ bnx2x_fp(bp, cid, state) =
BNX2X_FP_STATE_CLOSED;
goto next_spqe;
+
+ case EVENT_RING_OPCODE_STOP_TRAFFIC:
+ DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n");
+ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED);
+ goto next_spqe;
+ case EVENT_RING_OPCODE_START_TRAFFIC:
+ DP(NETIF_MSG_IFUP, "got START TRAFFIC\n");
+ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED);
+ goto next_spqe;
}
switch (opcode | bp->state) {
@@ -3714,7 +3812,13 @@ static void bnx2x_sp_task(struct work_struct *work)
/* SP events: STAT_QUERY and others */
if (status & BNX2X_DEF_SB_IDX) {
+#ifdef BCM_CNIC
+ struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp);
+ if ((!NO_FCOE(bp)) &&
+ (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp)))
+ napi_schedule(&bnx2x_fcoe(bp, napi));
+#endif
/* Handle EQ completions */
bnx2x_eq_int(bp);
@@ -4097,7 +4201,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_eth_queue(bp, i)
bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id,
bp->rx_ticks, bp->tx_ticks);
}
@@ -4145,13 +4249,16 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
REG_WR8(bp, BAR_TSTRORM_INTMEM +
TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
- bp->fp->cl_id + (i % bp->num_queues));
+ bp->fp->cl_id + (i % (bp->num_queues -
+ NONE_ETH_CONTEXT_USE)));
}
void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
{
int mode = bp->rx_mode;
+ int port = BP_PORT(bp);
u16 cl_id;
+ u32 def_q_filters = 0;
/* All but management unicast packets should pass to the host as well */
u32 llh_mask =
@@ -4162,30 +4269,42 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
switch (mode) {
case BNX2X_RX_MODE_NONE: /* no Rx */
- cl_id = BP_L_ID(bp);
- bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
+ def_q_filters = BNX2X_ACCEPT_NONE;
+#ifdef BCM_CNIC
+ if (!NO_FCOE(bp)) {
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
+ }
+#endif
break;
case BNX2X_RX_MODE_NORMAL:
- cl_id = BP_L_ID(bp);
- bnx2x_rxq_set_mac_filters(bp, cl_id,
- BNX2X_ACCEPT_UNICAST |
- BNX2X_ACCEPT_BROADCAST |
- BNX2X_ACCEPT_MULTICAST);
+ def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
+ BNX2X_ACCEPT_MULTICAST;
+#ifdef BCM_CNIC
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_MULTICAST);
+#endif
break;
case BNX2X_RX_MODE_ALLMULTI:
- cl_id = BP_L_ID(bp);
- bnx2x_rxq_set_mac_filters(bp, cl_id,
- BNX2X_ACCEPT_UNICAST |
- BNX2X_ACCEPT_BROADCAST |
- BNX2X_ACCEPT_ALL_MULTICAST);
+ def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
+ BNX2X_ACCEPT_ALL_MULTICAST;
+#ifdef BCM_CNIC
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_MULTICAST);
+#endif
break;
case BNX2X_RX_MODE_PROMISC:
- cl_id = BP_L_ID(bp);
- bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE);
-
+ def_q_filters |= BNX2X_PROMISCUOUS_MODE;
+#ifdef BCM_CNIC
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_MULTICAST);
+#endif
/* pass management unicast packets as well */
llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
break;
@@ -4195,20 +4314,24 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
break;
}
+ cl_id = BP_L_ID(bp);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters);
+
REG_WR(bp,
- BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK :
- NIG_REG_LLH0_BRB1_DRV_MASK,
- llh_mask);
+ (port ? NIG_REG_LLH1_BRB1_DRV_MASK :
+ NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask);
DP(NETIF_MSG_IFUP, "rx mode %d\n"
"drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n"
- "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode,
+ "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n"
+ "unmatched_ucast 0x%x\n", mode,
bp->mac_filters.ucast_drop_all,
bp->mac_filters.mcast_drop_all,
bp->mac_filters.bcast_drop_all,
bp->mac_filters.ucast_accept_all,
bp->mac_filters.mcast_accept_all,
- bp->mac_filters.bcast_accept_all
+ bp->mac_filters.bcast_accept_all,
+ bp->mac_filters.unmatched_unicast
);
storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp));
@@ -4232,6 +4355,15 @@ static void bnx2x_init_internal_common(struct bnx2x *bp)
bp->mf_mode);
}
+ if (IS_MF_SI(bp))
+ /*
+ * In switch independent mode, the TSTORM needs to accept
+ * packets that failed classification, since approximate match
+ * mac addresses aren't written to NIG LLH
+ */
+ REG_WR8(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2);
+
/* Zero this manually as its initialization is
currently missing in the initTool */
for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
@@ -4247,6 +4379,7 @@ static void bnx2x_init_internal_common(struct bnx2x *bp)
static void bnx2x_init_internal_port(struct bnx2x *bp)
{
/* port */
+ bnx2x_dcb_init_intmem_pfc(bp);
}
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
@@ -4308,9 +4441,11 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
{
int i;
- for_each_queue(bp, i)
+ for_each_eth_queue(bp, i)
bnx2x_init_fp_sb(bp, i);
#ifdef BCM_CNIC
+ if (!NO_FCOE(bp))
+ bnx2x_init_fcoe_fp(bp);
bnx2x_init_sb(bp, bp->cnic_sb_mapping,
BNX2X_VF_ID_INVALID, false,
@@ -5048,12 +5183,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code)
REG_WR(bp, PRS_REG_NIC_MODE, 1);
#endif
if (!CHIP_IS_E1(bp))
- REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp));
+ REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF_SD(bp));
if (CHIP_IS_E2(bp)) {
/* Bit-map indicating which L2 hdrs may appear after the
basic Ethernet header */
- int has_ovlan = IS_MF(bp);
+ int has_ovlan = IS_MF_SD(bp);
REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6));
REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0));
}
@@ -5087,7 +5222,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code)
bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
if (CHIP_IS_E2(bp)) {
- int has_ovlan = IS_MF(bp);
+ int has_ovlan = IS_MF_SD(bp);
REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6));
REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0));
}
@@ -5164,12 +5299,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code)
bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
if (!CHIP_IS_E1(bp)) {
REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp));
- REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp));
+ REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp));
}
if (CHIP_IS_E2(bp)) {
/* Bit-map indicating which L2 hdrs may appear after the
basic Ethernet header */
- REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6));
+ REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF_SD(bp) ? 7 : 6));
}
if (CHIP_REV_IS_SLOW(bp))
@@ -5370,8 +5505,10 @@ static int bnx2x_init_hw_port(struct bnx2x *bp)
* - SF mode: bits 3-7 are masked. only bits 0-2 are in use
* - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
* bits 4-7 are used for "per vn group attention" */
- REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4,
- (IS_MF(bp) ? 0xF7 : 0x7));
+ val = IS_MF(bp) ? 0xF7 : 0x7;
+ /* Enable DCBX attention for all but E1 */
+ val |= CHIP_IS_E1(bp) ? 0 : 0x10;
+ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val);
bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
@@ -5386,7 +5523,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp)
if (!CHIP_IS_E1(bp)) {
/* 0x2 disable mf_ov, 0x1 enable */
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
- (IS_MF(bp) ? 0x1 : 0x2));
+ (IS_MF_SD(bp) ? 0x1 : 0x2));
if (CHIP_IS_E2(bp)) {
val = 0;
@@ -5816,6 +5953,15 @@ void bnx2x_free_mem(struct bnx2x *bp)
/* fastpath */
/* Common */
for_each_queue(bp, i) {
+#ifdef BCM_CNIC
+ /* FCoE client uses default status block */
+ if (IS_FCOE_IDX(i)) {
+ union host_hc_status_block *sb =
+ &bnx2x_fp(bp, i, status_blk);
+ memset(sb, 0, sizeof(union host_hc_status_block));
+ bnx2x_fp(bp, i, status_blk_mapping) = 0;
+ } else {
+#endif
/* status blocks */
if (CHIP_IS_E2(bp))
BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb),
@@ -5825,9 +5971,12 @@ void bnx2x_free_mem(struct bnx2x *bp)
BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb),
bnx2x_fp(bp, i, status_blk_mapping),
sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
}
/* Rx */
- for_each_queue(bp, i) {
+ for_each_rx_queue(bp, i) {
/* fastpath rx rings: rx_buf rx_desc rx_comp */
BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
@@ -5847,7 +5996,7 @@ void bnx2x_free_mem(struct bnx2x *bp)
BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
}
/* Tx */
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
/* fastpath tx rings: tx_buf tx_desc */
BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
@@ -5931,15 +6080,20 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk);
bnx2x_fp(bp, i, bp) = bp;
/* status blocks */
- if (CHIP_IS_E2(bp))
- BNX2X_PCI_ALLOC(sb->e2_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_ALLOC(sb->e1x_sb,
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
-
+#ifdef BCM_CNIC
+ if (!IS_FCOE_IDX(i)) {
+#endif
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_ALLOC(sb->e2_sb,
+ &bnx2x_fp(bp, i, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_ALLOC(sb->e1x_sb,
+ &bnx2x_fp(bp, i, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+ }
+#endif
set_sb_shortcuts(bp, i);
}
/* Rx */
@@ -6055,7 +6209,7 @@ static int bnx2x_func_stop(struct bnx2x *bp)
* @param cam_offset offset in a CAM to use
* @param is_bcast is the set MAC a broadcast address (for E1 only)
*/
-static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac,
+static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
u32 cl_bit_vec, u8 cam_offset,
u8 is_bcast)
{
@@ -6170,6 +6324,70 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset)
return BP_VN(bp) * 32 + rel_offset;
}
+/**
+ * LLH CAM line allocations: currently only iSCSI and ETH macs are
+ * relevant. In addition, current implementation is tuned for a
+ * single ETH MAC.
+ *
+ * When multiple unicast ETH MACs PF configuration in switch
+ * independent mode is required (NetQ, multiple netdev MACs,
+ * etc.), consider better utilisation of 16 per function MAC
+ * entries in the LLH memory.
+ */
+enum {
+ LLH_CAM_ISCSI_ETH_LINE = 0,
+ LLH_CAM_ETH_LINE,
+ LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE
+};
+
+static void bnx2x_set_mac_in_nig(struct bnx2x *bp,
+ int set,
+ unsigned char *dev_addr,
+ int index)
+{
+ u32 wb_data[2];
+ u32 mem_offset, ena_offset, mem_index;
+ /**
+ * indexes mapping:
+ * 0..7 - goes to MEM
+ * 8..15 - goes to MEM2
+ */
+
+ if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE)
+ return;
+
+ /* calculate memory start offset according to the mapping
+ * and index in the memory */
+ if (index < NIG_LLH_FUNC_MEM_MAX_OFFSET) {
+ mem_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM :
+ NIG_REG_LLH0_FUNC_MEM;
+ ena_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE :
+ NIG_REG_LLH0_FUNC_MEM_ENABLE;
+ mem_index = index;
+ } else {
+ mem_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2 :
+ NIG_REG_P0_LLH_FUNC_MEM2;
+ ena_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE :
+ NIG_REG_P0_LLH_FUNC_MEM2_ENABLE;
+ mem_index = index - NIG_LLH_FUNC_MEM_MAX_OFFSET;
+ }
+
+ if (set) {
+ /* LLH_FUNC_MEM is a u64 WB register */
+ mem_offset += 8*mem_index;
+
+ wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) |
+ (dev_addr[4] << 8) | dev_addr[5]);
+ wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]);
+
+ REG_WR_DMAE(bp, mem_offset, wb_data, 2);
+ }
+
+ /* enable/disable the entry */
+ REG_WR(bp, ena_offset + 4*mem_index, set);
+
+}
+
void bnx2x_set_eth_mac(struct bnx2x *bp, int set)
{
u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) :
@@ -6179,9 +6397,13 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set)
bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr,
(1 << bp->fp->cl_id), cam_offset , 0);
+ bnx2x_set_mac_in_nig(bp, set, bp->dev->dev_addr, LLH_CAM_ETH_LINE);
+
if (CHIP_IS_E1(bp)) {
/* broadcast MAC */
- u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ static const u8 bcast[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1);
}
}
@@ -6283,12 +6505,59 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
{
u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) :
bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE));
- u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID;
+ u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID +
+ BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE;
u32 cl_bit_vec = (1 << iscsi_l2_cl_id);
/* Send a SET_MAC ramrod */
bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec,
cam_offset, 0);
+
+ bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE);
+
+ return 0;
+}
+
+/**
+ * Set FCoE L2 MAC(s) at the next enties in the CAM after the
+ * ETH MAC(s). This function will wait until the ramdord
+ * completion returns.
+ *
+ * @param bp driver handle
+ * @param set set or clear the CAM entry
+ *
+ * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ */
+int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set)
+{
+ u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id));
+ /**
+ * CAM allocation for E1H
+ * eth unicasts: by func number
+ * iscsi: by func number
+ * fip unicast: by func number
+ * fip multicast: by func number
+ */
+ bnx2x_set_mac_addr_gen(bp, set, bp->fip_mac,
+ cl_bit_vec, bnx2x_e1h_cam_offset(bp, CAM_FIP_ETH_LINE), 0);
+
+ return 0;
+}
+
+int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set)
+{
+ u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id));
+
+ /**
+ * CAM allocation for E1H
+ * eth unicasts: by func number
+ * iscsi: by func number
+ * fip unicast: by func number
+ * fip multicast: by func number
+ */
+ bnx2x_set_mac_addr_gen(bp, set, ALL_ENODE_MACS, cl_bit_vec,
+ bnx2x_e1h_cam_offset(bp, CAM_FIP_MCAST_LINE), 0);
+
return 0;
}
#endif
@@ -6306,6 +6575,8 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp,
data->general.statistics_counter_id = params->rxq_params.stat_id;
data->general.statistics_en_flg =
(params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0;
+ data->general.is_fcoe_flg =
+ (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0;
data->general.activate_flg = activate;
data->general.sp_client_id = params->rxq_params.spcl_id;
@@ -6374,7 +6645,9 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp,
data->fc.safc_group_num = params->txq_params.cos;
data->fc.safc_group_en_flg =
(params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0;
- data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW;
+ data->fc.traffic_type =
+ (params->ramrod_params.flags & CLIENT_IS_FCOE) ?
+ LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW;
}
static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid)
@@ -6473,7 +6746,7 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
bnx2x_enable_msi(bp);
/* falling through... */
case INT_MODE_INTx:
- bp->num_queues = 1;
+ bp->num_queues = 1 + NONE_ETH_CONTEXT_USE;
DP(NETIF_MSG_IFUP, "set number of queues to 1\n");
break;
default:
@@ -6496,8 +6769,8 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
"enable MSI-X (%d), "
"set number of queues to %d\n",
bp->num_queues,
- 1);
- bp->num_queues = 1;
+ 1 + NONE_ETH_CONTEXT_USE);
+ bp->num_queues = 1 + NONE_ETH_CONTEXT_USE;
if (!(bp->flags & DISABLE_MSI_FLAG))
bnx2x_enable_msi(bp);
@@ -6618,7 +6891,9 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct bnx2x_client_init_params params = { {0} };
int rc;
- bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0,
+ /* reset IGU state skip FCoE L2 queue */
+ if (!IS_FCOE_FP(fp))
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0,
IGU_INT_ENABLE, 0);
params.ramrod_params.pstate = &fp->state;
@@ -6626,6 +6901,12 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
params.ramrod_params.index = fp->index;
params.ramrod_params.cid = fp->cid;
+#ifdef BCM_CNIC
+ if (IS_FCOE_FP(fp))
+ params.ramrod_params.flags |= CLIENT_IS_FCOE;
+
+#endif
+
if (is_leading)
params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS;
@@ -6710,7 +6991,7 @@ static void bnx2x_reset_func(struct bnx2x *bp)
REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0);
/* FP SBs */
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
REG_WR8(bp,
BAR_CSTRORM_INTMEM +
@@ -6830,6 +7111,20 @@ static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
}
}
+#ifdef BCM_CNIC
+static inline void bnx2x_del_fcoe_eth_macs(struct bnx2x *bp)
+{
+ if (bp->flags & FCOE_MACS_SET) {
+ if (!IS_MF_SD(bp))
+ bnx2x_set_fip_eth_mac_addr(bp, 0);
+
+ bnx2x_set_all_enode_macs(bp, 0);
+
+ bp->flags &= ~FCOE_MACS_SET;
+ }
+}
+#endif
+
void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
{
int port = BP_PORT(bp);
@@ -6837,7 +7132,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
int i, cnt, rc;
/* Wait until tx fastpath tasks complete */
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
cnt = 1000;
@@ -6877,13 +7172,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
}
#ifdef BCM_CNIC
- /* Clear iSCSI L2 MAC */
- mutex_lock(&bp->cnic_mutex);
- if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
- bnx2x_set_iscsi_eth_mac_addr(bp, 0);
- bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
- }
- mutex_unlock(&bp->cnic_mutex);
+ bnx2x_del_fcoe_eth_macs(bp);
#endif
if (unload_mode == UNLOAD_NORMAL)
@@ -7736,7 +8025,7 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
bp->igu_sb_cnt = 0;
if (CHIP_INT_MODE_IS_BC(bp)) {
bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x,
- bp->l2_cid_count);
+ NUM_IGU_SB_REQUIRED(bp->l2_cid_count));
bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) *
FP_SB_MAX_E1x;
@@ -7767,7 +8056,8 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
}
}
}
- bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count);
+ bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt,
+ NUM_IGU_SB_REQUIRED(bp->l2_cid_count));
if (bp->igu_sb_cnt == 0)
BNX2X_ERR("CAM configuration error\n");
}
@@ -8076,9 +8366,8 @@ static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{
int port = BP_PORT(bp);
- u32 val, val2;
u32 config;
- u32 ext_phy_type, ext_phy_config;;
+ u32 ext_phy_type, ext_phy_config;
bp->link_params.bp = bp;
bp->link_params.port = port;
@@ -8135,25 +8424,73 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
(ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
bp->mdio.prtad =
XGXS_EXT_PHY_ADDR(ext_phy_config);
+}
+
+static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
+{
+ u32 val, val2;
+ int func = BP_ABS_FUNC(bp);
+ int port = BP_PORT(bp);
+
+ if (BP_NOMCP(bp)) {
+ BNX2X_ERROR("warning: random MAC workaround active\n");
+ random_ether_addr(bp->dev->dev_addr);
+ } else if (IS_MF(bp)) {
+ val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper);
+ val = MF_CFG_RD(bp, func_mf_config[func].mac_lower);
+ if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) &&
+ (val != FUNC_MF_CFG_LOWERMAC_DEFAULT))
+ bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2);
+
+#ifdef BCM_CNIC
+ /* iSCSI NPAR MAC */
+ if (IS_MF_SI(bp)) {
+ u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg);
+ if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) {
+ val2 = MF_CFG_RD(bp, func_ext_config[func].
+ iscsi_mac_addr_upper);
+ val = MF_CFG_RD(bp, func_ext_config[func].
+ iscsi_mac_addr_lower);
+ bnx2x_set_mac_buf(bp->iscsi_mac, val, val2);
+ }
+ }
+#endif
+ } else {
+ /* in SF read MACs from port configuration */
+ val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
+ val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
+ bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2);
+
+#ifdef BCM_CNIC
+ val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].
+ iscsi_mac_upper);
+ val = SHMEM_RD(bp, dev_info.port_hw_config[port].
+ iscsi_mac_lower);
+ bnx2x_set_mac_buf(bp->iscsi_mac, val, val2);
+#endif
+ }
- val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
- val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
- bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2);
memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
#ifdef BCM_CNIC
- val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper);
- val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower);
- bnx2x_set_mac_buf(bp->iscsi_mac, val, val2);
+ /* Inform the upper layers about FCoE MAC */
+ if (!CHIP_IS_E1x(bp)) {
+ if (IS_MF_SD(bp))
+ memcpy(bp->fip_mac, bp->dev->dev_addr,
+ sizeof(bp->fip_mac));
+ else
+ memcpy(bp->fip_mac, bp->iscsi_mac,
+ sizeof(bp->fip_mac));
+ }
#endif
}
static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
{
- int func = BP_ABS_FUNC(bp);
- int vn;
- u32 val, val2;
+ int /*abs*/func = BP_ABS_FUNC(bp);
+ int vn, port;
+ u32 val = 0;
int rc = 0;
bnx2x_get_common_hwinfo(bp);
@@ -8163,7 +8500,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
bp->igu_dsb_id = DEF_SB_IGU_ID;
bp->igu_base_sb = 0;
- bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count);
+ bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x,
+ NUM_IGU_SB_REQUIRED(bp->l2_cid_count));
} else {
bp->common.int_block = INT_BLOCK_IGU;
val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION);
@@ -8186,44 +8524,99 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
bp->mf_ov = 0;
bp->mf_mode = 0;
vn = BP_E1HVN(bp);
+ port = BP_PORT(bp);
+
if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
+ DP(NETIF_MSG_PROBE,
+ "shmem2base 0x%x, size %d, mfcfg offset %d\n",
+ bp->common.shmem2_base, SHMEM2_RD(bp, size),
+ (u32)offsetof(struct shmem2_region, mf_cfg_addr));
if (SHMEM2_HAS(bp, mf_cfg_addr))
bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr);
else
bp->common.mf_cfg_base = bp->common.shmem_base +
offsetof(struct shmem_region, func_mb) +
E1H_FUNC_MAX * sizeof(struct drv_func_mb);
- bp->mf_config[vn] =
- MF_CFG_RD(bp, func_mf_config[func].config);
+ /*
+ * get mf configuration:
+ * 1. existance of MF configuration
+ * 2. MAC address must be legal (check only upper bytes)
+ * for Switch-Independent mode;
+ * OVLAN must be legal for Switch-Dependent mode
+ * 3. SF_MODE configures specific MF mode
+ */
+ if (bp->common.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE) {
+ /* get mf configuration */
+ val = SHMEM_RD(bp,
+ dev_info.shared_feature_config.config);
+ val &= SHARED_FEAT_CFG_FORCE_SF_MODE_MASK;
+
+ switch (val) {
+ case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT:
+ val = MF_CFG_RD(bp, func_mf_config[func].
+ mac_upper);
+ /* check for legal mac (upper bytes)*/
+ if (val != 0xffff) {
+ bp->mf_mode = MULTI_FUNCTION_SI;
+ bp->mf_config[vn] = MF_CFG_RD(bp,
+ func_mf_config[func].config);
+ } else
+ DP(NETIF_MSG_PROBE, "illegal MAC "
+ "address for SI\n");
+ break;
+ case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED:
+ /* get OV configuration */
+ val = MF_CFG_RD(bp,
+ func_mf_config[FUNC_0].e1hov_tag);
+ val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
+
+ if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
+ bp->mf_mode = MULTI_FUNCTION_SD;
+ bp->mf_config[vn] = MF_CFG_RD(bp,
+ func_mf_config[func].config);
+ } else
+ DP(NETIF_MSG_PROBE, "illegal OV for "
+ "SD\n");
+ break;
+ default:
+ /* Unknown configuration: reset mf_config */
+ bp->mf_config[vn] = 0;
+ DP(NETIF_MSG_PROBE, "Unkown MF mode 0x%x\n",
+ val);
+ }
+ }
- val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) &
- FUNC_MF_CFG_E1HOV_TAG_MASK);
- if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT)
- bp->mf_mode = 1;
BNX2X_DEV_INFO("%s function mode\n",
IS_MF(bp) ? "multi" : "single");
- if (IS_MF(bp)) {
- val = (MF_CFG_RD(bp, func_mf_config[func].
- e1hov_tag) &
- FUNC_MF_CFG_E1HOV_TAG_MASK);
+ switch (bp->mf_mode) {
+ case MULTI_FUNCTION_SD:
+ val = MF_CFG_RD(bp, func_mf_config[func].e1hov_tag) &
+ FUNC_MF_CFG_E1HOV_TAG_MASK;
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
bp->mf_ov = val;
- BNX2X_DEV_INFO("MF OV for func %d is %d "
- "(0x%04x)\n",
- func, bp->mf_ov, bp->mf_ov);
+ BNX2X_DEV_INFO("MF OV for func %d is %d"
+ " (0x%04x)\n", func,
+ bp->mf_ov, bp->mf_ov);
} else {
- BNX2X_ERROR("No valid MF OV for func %d,"
- " aborting\n", func);
+ BNX2X_ERR("No valid MF OV for func %d,"
+ " aborting\n", func);
rc = -EPERM;
}
- } else {
- if (BP_VN(bp)) {
- BNX2X_ERROR("VN %d in single function mode,"
- " aborting\n", BP_E1HVN(bp));
+ break;
+ case MULTI_FUNCTION_SI:
+ BNX2X_DEV_INFO("func %d is in MF "
+ "switch-independent mode\n", func);
+ break;
+ default:
+ if (vn) {
+ BNX2X_ERR("VN %d in single function mode,"
+ " aborting\n", vn);
rc = -EPERM;
}
+ break;
}
+
}
/* adjust igu_sb_cnt to MF for E1x */
@@ -8248,32 +8641,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
}
- if (IS_MF(bp)) {
- val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper);
- val = MF_CFG_RD(bp, func_mf_config[func].mac_lower);
- if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) &&
- (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) {
- bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
- bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
- bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
- bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
- bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
- bp->dev->dev_addr[5] = (u8)(val & 0xff);
- memcpy(bp->link_params.mac_addr, bp->dev->dev_addr,
- ETH_ALEN);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr,
- ETH_ALEN);
- }
-
- return rc;
- }
-
- if (BP_NOMCP(bp)) {
- /* only supposed to happen on emulation/FPGA */
- BNX2X_ERROR("warning: random MAC workaround active\n");
- random_ether_addr(bp->dev->dev_addr);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
- }
+ /* Get MAC addresses */
+ bnx2x_get_mac_hwinfo(bp);
return rc;
}
@@ -8427,6 +8796,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->timer.data = (unsigned long) bp;
bp->timer.function = bnx2x_timer;
+ bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON);
+ bnx2x_dcbx_init_params(bp);
+
return rc;
}
@@ -8629,6 +9001,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_open = bnx2x_open,
.ndo_stop = bnx2x_close,
.ndo_start_xmit = bnx2x_start_xmit,
+ .ndo_select_queue = bnx2x_select_queue,
.ndo_set_multicast_list = bnx2x_set_rx_mode,
.ndo_set_mac_address = bnx2x_change_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -8761,7 +9134,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->netdev_ops = &bnx2x_netdev_ops;
bnx2x_set_ethtool_ops(dev);
dev->features |= NETIF_F_SG;
- dev->features |= NETIF_F_HW_CSUM;
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
if (bp->flags & USING_DAC_FLAG)
dev->features |= NETIF_F_HIGHDMA;
dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
@@ -8769,12 +9142,16 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
dev->vlan_features |= NETIF_F_SG;
- dev->vlan_features |= NETIF_F_HW_CSUM;
+ dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
if (bp->flags & USING_DAC_FLAG)
dev->vlan_features |= NETIF_F_HIGHDMA;
dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
dev->vlan_features |= NETIF_F_TSO6;
+#ifdef BCM_DCB
+ dev->dcbnl_ops = &bnx2x_dcbnl_ops;
+#endif
+
/* get_port_hwinfo() will set prtad and mmds properly */
bp->mdio.prtad = MDIO_PRTAD_NONE;
bp->mdio.mmds = 0;
@@ -9067,7 +9444,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
return -ENODEV;
}
- cid_count += CNIC_CONTEXT_USE;
+ cid_count += NONE_ETH_CONTEXT_USE + CNIC_CONTEXT_USE;
/* dev zeroed in init_etherdev */
dev = alloc_etherdev_mq(sizeof(*bp), cid_count);
@@ -9096,11 +9473,12 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
/* calc qm_cid_count */
bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count);
- rc = register_netdev(dev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device\n");
- goto init_one_exit;
- }
+#ifdef BCM_CNIC
+ /* disable FCOE L2 queue for E1x*/
+ if (CHIP_IS_E1x(bp))
+ bp->flags |= NO_FCOE_FLAG;
+
+#endif
/* Configure interupt mode: try to enable MSI-X/MSI if
* needed, set bp->num_queues appropriately.
@@ -9110,6 +9488,21 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
/* Add all NAPI objects */
bnx2x_add_all_napi(bp);
+ rc = register_netdev(dev);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register net device\n");
+ goto init_one_exit;
+ }
+
+#ifdef BCM_CNIC
+ if (!NO_FCOE(bp)) {
+ /* Add storage MAC address */
+ rtnl_lock();
+ dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN);
+ rtnl_unlock();
+ }
+#endif
+
bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx,"
@@ -9153,6 +9546,15 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
}
bp = netdev_priv(dev);
+#ifdef BCM_CNIC
+ /* Delete storage MAC address */
+ if (!NO_FCOE(bp)) {
+ rtnl_lock();
+ dev_addr_del(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN);
+ rtnl_unlock();
+ }
+#endif
+
unregister_netdev(dev);
/* Delete all NAPI objects */
@@ -9202,7 +9604,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
bnx2x_free_mem(bp);
@@ -9429,7 +9831,8 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
break;
else
atomic_dec(&bp->spq_left);
- } else if (type == ISCSI_CONNECTION_TYPE) {
+ } else if ((type == ISCSI_CONNECTION_TYPE) ||
+ (type == FCOE_CONNECTION_TYPE)) {
if (bp->cnic_spq_pending >=
bp->cnic_eth_dev.max_kwqe_pending)
break;
@@ -9576,6 +9979,9 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
case DRV_CTL_START_L2_CMD: {
u32 cli = ctl->data.ring.client_id;
+ /* Clear FCoE FIP and ALL ENODE MACs addresses first */
+ bnx2x_del_fcoe_eth_macs(bp);
+
/* Set iSCSI MAC address */
bnx2x_set_iscsi_eth_mac_addr(bp, 1);
@@ -9697,10 +10103,6 @@ static int bnx2x_unregister_cnic(struct net_device *dev)
struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
mutex_lock(&bp->cnic_mutex);
- if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
- bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
- bnx2x_set_iscsi_eth_mac_addr(bp, 0);
- }
cp->drv_state = 0;
rcu_assign_pointer(bp->cnic_ops, NULL);
mutex_unlock(&bp->cnic_mutex);
@@ -9731,7 +10133,9 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
cp->drv_ctl = bnx2x_drv_ctl;
cp->drv_register_cnic = bnx2x_register_cnic;
cp->drv_unregister_cnic = bnx2x_unregister_cnic;
- cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID;
+ cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID;
+ cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID +
+ BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE;
cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID;
DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, "
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index 1cefe489a955..bfd875b72906 100644
--- a/drivers/net/bnx2x/bnx2x_reg.h
+++ b/drivers/net/bnx2x/bnx2x_reg.h
@@ -1615,6 +1615,8 @@
#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4)
#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2)
#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3)
+#define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0)
+#define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15)
@@ -1744,12 +1746,16 @@
~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same
port */
#define NIG_REG_LLFC_ENABLE_0 0x16208
+#define NIG_REG_LLFC_ENABLE_1 0x1620c
/* [RW 16] classes are high-priority for port0 */
#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058
+#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 0x1605c
/* [RW 16] classes are low-priority for port0 */
#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060
+#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 0x16064
/* [RW 1] Output enable of message to LLFC BMAC IF for port0 */
#define NIG_REG_LLFC_OUT_EN_0 0x160c8
+#define NIG_REG_LLFC_OUT_EN_1 0x160cc
#define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c
#define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154
#define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244
@@ -1774,6 +1780,8 @@
/* [RW 8] event id for llh0 */
#define NIG_REG_LLH0_EVENT_ID 0x10084
#define NIG_REG_LLH0_FUNC_EN 0x160fc
+#define NIG_REG_LLH0_FUNC_MEM 0x16180
+#define NIG_REG_LLH0_FUNC_MEM_ENABLE 0x16140
#define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100
/* [RW 1] Determine the IP version to look for in
~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */
@@ -1797,6 +1805,9 @@
#define NIG_REG_LLH1_ERROR_MASK 0x10090
/* [RW 8] event id for llh1 */
#define NIG_REG_LLH1_EVENT_ID 0x10088
+#define NIG_REG_LLH1_FUNC_MEM 0x161c0
+#define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160
+#define NIG_REG_LLH1_FUNC_MEM_SIZE 16
/* [RW 8] init credit counter for port1 in LLH */
#define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564
#define NIG_REG_LLH1_XCM_MASK 0x10134
@@ -1907,11 +1918,17 @@
~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same
port */
#define NIG_REG_PAUSE_ENABLE_0 0x160c0
+#define NIG_REG_PAUSE_ENABLE_1 0x160c4
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
/* [RW 1] Value of this register will be transmitted to port swap when
~nig_registers_strap_override.strap_override =1 */
#define NIG_REG_PORT_SWAP 0x10394
+/* [RW 1] PPP enable for port0. This register may get 1 only when
+ * ~safc_enable.safc_enable = 0 and pause_enable.pause_enable =0 for the
+ * same port */
+#define NIG_REG_PPP_ENABLE_0 0x160b0
+#define NIG_REG_PPP_ENABLE_1 0x160b4
/* [RW 1] output enable for RX parser descriptor IF */
#define NIG_REG_PRS_EOP_OUT_EN 0x10104
/* [RW 1] Input enable for RX parser request IF */
@@ -1978,6 +1995,14 @@
#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15)
#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18)
#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18
+/* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter. */
+#define PBF_REG_COS0_UPPER_BOUND 0x15c05c
+/* [RW 31] The weight of COS0 in the ETS command arbiter. */
+#define PBF_REG_COS0_WEIGHT 0x15c054
+/* [RW 31] The upper bound of the weight of COS1 in the ETS command arbiter. */
+#define PBF_REG_COS1_UPPER_BOUND 0x15c060
+/* [RW 31] The weight of COS1 in the ETS command arbiter. */
+#define PBF_REG_COS1_WEIGHT 0x15c058
/* [RW 1] Disable processing further tasks from port 0 (after ending the
current task in process). */
#define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c
@@ -1988,9 +2013,16 @@
current task in process). */
#define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c
#define PBF_REG_DISABLE_PF 0x1402e8
+/* [RW 1] Indicates that ETS is performed between the COSes in the command
+ * arbiter. If reset strict priority w/ anti-starvation will be performed
+ * w/o WFQ. */
+#define PBF_REG_ETS_ENABLED 0x15c050
/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic
* Ethernet header. */
#define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8
+/* [RW 1] Indicates which COS is conncted to the highest priority in the
+ * command arbiter. */
+#define PBF_REG_HIGH_PRIORITY_COS_NUM 0x15c04c
#define PBF_REG_IF_ENABLE_REG 0x140044
/* [RW 1] Init bit. When set the initial credits are copied to the credit
registers (except the port credits). Should be set and then reset after
@@ -2016,6 +2048,10 @@
#define PBF_REG_MAC_LB_ENABLE 0x140040
/* [RW 6] Bit-map indicating which headers must appear in the packet */
#define PBF_REG_MUST_HAVE_HDRS 0x15c0c4
+/* [RW 16] The number of strict priority arbitration slots between 2 RR
+ * arbitration slots. A value of 0 means no strict priority cycles; i.e. the
+ * strict-priority w/ anti-starvation arbiter is a RR arbiter. */
+#define PBF_REG_NUM_STRICT_ARB_SLOTS 0x15c064
/* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause
not suppoterd. */
#define PBF_REG_P0_ARB_THRSH 0x1400e4
@@ -4970,7 +5006,23 @@
#define EMAC_REG_EMAC_TX_MODE 0xbc
#define EMAC_REG_EMAC_TX_STAT_AC 0x280
#define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22
+#define EMAC_REG_RX_PFC_MODE 0x320
+#define EMAC_REG_RX_PFC_MODE_PRIORITIES (1L<<2)
+#define EMAC_REG_RX_PFC_MODE_RX_EN (1L<<1)
+#define EMAC_REG_RX_PFC_MODE_TX_EN (1L<<0)
+#define EMAC_REG_RX_PFC_PARAM 0x324
+#define EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT 0
+#define EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT 16
+#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD 0x328
+#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT (0xffff<<0)
+#define EMAC_REG_RX_PFC_STATS_XOFF_SENT 0x330
+#define EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT (0xffff<<0)
+#define EMAC_REG_RX_PFC_STATS_XON_RCVD 0x32c
+#define EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT (0xffff<<0)
+#define EMAC_REG_RX_PFC_STATS_XON_SENT 0x334
+#define EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT (0xffff<<0)
#define EMAC_RX_MODE_FLOW_EN (1L<<2)
+#define EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3)
#define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10)
#define EMAC_RX_MODE_PROMISCUOUS (1L<<8)
#define EMAC_RX_MODE_RESET (1L<<0)
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index 4733c835dad9..6e4d9b144cc4 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -160,7 +160,7 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
ramrod_data.drv_counter = bp->stats_counter++;
ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
- for_each_queue(bp, i)
+ for_each_eth_queue(bp, i)
ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0,
@@ -766,7 +766,7 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
estats->no_buff_discard_hi = 0;
estats->no_buff_discard_lo = 0;
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
int cl_id = fp->cl_id;
struct tstorm_per_client_stats *tclient =
@@ -996,7 +996,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
tmp = estats->mac_discard;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
nstats->rx_dropped = tmp;
@@ -1087,7 +1087,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
bp->dev->name,
estats->brb_drop_lo, estats->brb_truncate_lo);
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
@@ -1101,7 +1101,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
fp->rx_calls, fp->rx_pkt);
}
- for_each_queue(bp, i) {
+ for_each_eth_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
struct netdev_queue *txq =
@@ -1381,7 +1381,8 @@ void bnx2x_stats_init(struct bnx2x *bp)
memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
}
- for_each_queue(bp, i) {
+ /* FW stats are currently collected for ETH clients only */
+ for_each_eth_queue(bp, i) {
/* Set initial stats counter in the stats ramrod data to -1 */
int cl_id = bp->fp[i].cl_id;
diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h
index afd15efa429a..596798c47452 100644
--- a/drivers/net/bnx2x/bnx2x_stats.h
+++ b/drivers/net/bnx2x/bnx2x_stats.h
@@ -53,7 +53,6 @@ struct bnx2x_eth_q_stats {
u32 hw_csum_err;
};
-#define BNX2X_NUM_Q_STATS 13
#define Q_STATS_OFFSET32(stat_name) \
(offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
@@ -225,7 +224,6 @@ struct bnx2x_eth_stats {
u32 nig_timer_max;
};
-#define BNX2X_NUM_STATS 43
#define STATS_OFFSET32(stat_name) \
(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 6f9c6faef24c..0e2737eac8b7 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -4,7 +4,7 @@
obj-$(CONFIG_BONDING) += bonding.o
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o
ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
bonding-objs += $(ipv6-y)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 881914bc4e9c..48cf24ff4e6f 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2474,8 +2474,7 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
goto out;
read_lock(&bond->lock);
- slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev),
- orig_dev);
+ slave = bond_get_slave_by_dev(netdev_priv(dev), orig_dev);
if (!slave)
goto out_unlock;
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 26bb118c4533..f4e638c65129 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -44,42 +44,6 @@
#include "bond_alb.h"
-#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
-#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
- * Used for division - never set
- * to zero !!!
- */
-#define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of
- * learning packets to the switch
- */
-
-#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
- * Note that this value MUST NOT be smaller
- * because the key hash table is BYTE wide !
- */
-
-
-#define TLB_NULL_INDEX 0xffffffff
-#define MAX_LP_BURST 3
-
-/* rlb defs */
-#define RLB_HASH_TABLE_SIZE 256
-#define RLB_NULL_INDEX 0xffffffff
-#define RLB_UPDATE_DELAY 2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */
-#define RLB_ARP_BURST_SIZE 2
-#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
- * rebalance interval (5 min).
- */
-/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
- * promiscuous after failover
- */
-#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC
#ifndef __long_aligned
#define __long_aligned __attribute__((aligned((sizeof(long)))))
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 50968f8196cf..118c28aa471e 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -31,6 +31,44 @@ struct slave;
#define BOND_ALB_INFO(bond) ((bond)->alb_info)
#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)
+#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
+#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
+ * Used for division - never set
+ * to zero !!!
+ */
+#define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of
+ * learning packets to the switch
+ */
+
+#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
+ * Note that this value MUST NOT be smaller
+ * because the key hash table is BYTE wide !
+ */
+
+
+#define TLB_NULL_INDEX 0xffffffff
+#define MAX_LP_BURST 3
+
+/* rlb defs */
+#define RLB_HASH_TABLE_SIZE 256
+#define RLB_NULL_INDEX 0xffffffff
+#define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
+#define RLB_ARP_BURST_SIZE 2
+#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
+ * rebalance interval (5 min).
+ */
+/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
+ * promiscuous after failover
+ */
+#define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC)
+
+
struct tlb_client_info {
struct slave *tx_slave; /* A pointer to slave used for transmiting
* packets to a Client that the Hash function
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c
new file mode 100644
index 000000000000..3680aa251dea
--- /dev/null
+++ b/drivers/net/bonding/bond_debugfs.c
@@ -0,0 +1,146 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+
+#include "bonding.h"
+#include "bond_alb.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static struct dentry *bonding_debug_root;
+
+/*
+ * Show RLB hash table
+ */
+static int bond_debug_rlb_hash_show(struct seq_file *m, void *v)
+{
+ struct bonding *bond = m->private;
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct rlb_client_info *client_info;
+ u32 hash_index;
+
+ if (bond->params.mode != BOND_MODE_ALB)
+ return 0;
+
+ seq_printf(m, "SourceIP DestinationIP "
+ "Destination MAC DEV\n");
+
+ spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+ hash_index = bond_info->rx_hashtbl_head;
+ for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+ client_info = &(bond_info->rx_hashtbl[hash_index]);
+ seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n",
+ &client_info->ip_src,
+ &client_info->ip_dst,
+ &client_info->mac_dst,
+ client_info->slave->dev->name);
+ }
+
+ spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+ return 0;
+}
+
+static int bond_debug_rlb_hash_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, bond_debug_rlb_hash_show, inode->i_private);
+}
+
+static const struct file_operations bond_debug_rlb_hash_fops = {
+ .owner = THIS_MODULE,
+ .open = bond_debug_rlb_hash_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+void bond_debug_register(struct bonding *bond)
+{
+ if (!bonding_debug_root)
+ return;
+
+ bond->debug_dir =
+ debugfs_create_dir(bond->dev->name, bonding_debug_root);
+
+ if (!bond->debug_dir) {
+ pr_warning("%s: Warning: failed to register to debugfs\n",
+ bond->dev->name);
+ return;
+ }
+
+ debugfs_create_file("rlb_hash_table", 0400, bond->debug_dir,
+ bond, &bond_debug_rlb_hash_fops);
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+ if (!bonding_debug_root)
+ return;
+
+ debugfs_remove_recursive(bond->debug_dir);
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+ struct dentry *d;
+
+ if (!bonding_debug_root)
+ return;
+
+ d = debugfs_rename(bonding_debug_root, bond->debug_dir,
+ bonding_debug_root, bond->dev->name);
+ if (d) {
+ bond->debug_dir = d;
+ } else {
+ pr_warning("%s: Warning: failed to reregister, "
+ "so just unregister old one\n",
+ bond->dev->name);
+ bond_debug_unregister(bond);
+ }
+}
+
+void bond_create_debugfs(void)
+{
+ bonding_debug_root = debugfs_create_dir("bonding", NULL);
+
+ if (!bonding_debug_root) {
+ pr_warning("Warning: Cannot create bonding directory"
+ " in debugfs\n");
+ }
+}
+
+void bond_destroy_debugfs(void)
+{
+ debugfs_remove_recursive(bonding_debug_root);
+ bonding_debug_root = NULL;
+}
+
+
+#else /* !CONFIG_DEBUG_FS */
+
+void bond_debug_register(struct bonding *bond)
+{
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+}
+
+void bond_create_debugfs(void)
+{
+}
+
+void bond_destroy_debugfs(void)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
index 121b073a6c3f..84fbd4ebd778 100644
--- a/drivers/net/bonding/bond_ipv6.c
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -88,7 +88,12 @@ static void bond_na_send(struct net_device *slave_dev,
}
if (vlan_id) {
- skb = vlan_put_tag(skb, vlan_id);
+ /* The Ethernet header is not present yet, so it is
+ * too early to insert a VLAN tag. Force use of an
+ * out-of-line tag here and let dev_hard_start_xmit()
+ * insert it if the slave hardware can't.
+ */
+ skb = __vlan_hwaccel_put_tag(skb, vlan_id);
if (!skb) {
pr_err("failed to insert VLAN tag\n");
return;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 71a169740d05..b1025b85acf1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
/*----------------------------- Global variables ----------------------------*/
#ifdef CONFIG_NET_POLL_CONTROLLER
-cpumask_var_t netpoll_block_tx;
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
#endif
static const char * const version =
@@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
* @bond: bond device that got this skb for tx.
* @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff
- *
- * When the bond gets an skb to transmit that is
- * already hardware accelerated VLAN tagged, and it
- * needs to relay this skb to a slave that is not
- * hw accel capable, the skb needs to be "unaccelerated",
- * i.e. strip the hwaccel tag and re-insert it as part
- * of the payload.
*/
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
struct net_device *slave_dev)
{
- unsigned short uninitialized_var(vlan_id);
-
- /* Test vlan_list not vlgrp to catch and handle 802.1p tags */
- if (!list_empty(&bond->vlan_list) &&
- !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
- vlan_get_tag(skb, &vlan_id) == 0) {
- skb->dev = slave_dev;
- skb = vlan_put_tag(skb, vlan_id);
- if (!skb) {
- /* vlan_put_tag() frees the skb in case of error,
- * so return success here so the calling functions
- * won't attempt to free is again.
- */
- return 0;
- }
- } else {
- skb->dev = slave_dev;
- }
-
+ skb->dev = slave_dev;
skb->priority = 1;
#ifdef CONFIG_NET_POLL_CONTROLLER
if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
@@ -873,17 +848,11 @@ static void bond_mc_del(struct bonding *bond, void *addr)
static void __bond_resend_igmp_join_requests(struct net_device *dev)
{
struct in_device *in_dev;
- struct ip_mc_list *im;
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
- if (in_dev) {
- read_lock(&in_dev->mc_list_lock);
- for (im = in_dev->mc_list; im; im = im->next)
- ip_mc_rejoin_group(im);
- read_unlock(&in_dev->mc_list_lock);
- }
-
+ if (in_dev)
+ ip_mc_rejoin_groups(in_dev);
rcu_read_unlock();
}
@@ -1203,11 +1172,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_do_fail_over_mac(bond, new_active,
old_active);
- bond->send_grat_arp = bond->params.num_grat_arp;
- bond_send_gratuitous_arp(bond);
+ if (netif_running(bond->dev)) {
+ bond->send_grat_arp = bond->params.num_grat_arp;
+ bond_send_gratuitous_arp(bond);
- bond->send_unsol_na = bond->params.num_unsol_na;
- bond_send_unsolicited_na(bond);
+ bond->send_unsol_na = bond->params.num_unsol_na;
+ bond_send_unsolicited_na(bond);
+ }
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
@@ -1221,8 +1192,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
/* resend IGMP joins since active slave has changed or
* all were sent on curr_active_slave */
- if ((USES_PRIMARY(bond->params.mode) && new_active) ||
- bond->params.mode == BOND_MODE_ROUNDROBIN) {
+ if (((USES_PRIMARY(bond->params.mode) && new_active) ||
+ bond->params.mode == BOND_MODE_ROUNDROBIN) &&
+ netif_running(bond->dev)) {
bond->igmp_retrans = bond->params.resend_igmp;
queue_delayed_work(bond->wq, &bond->mcast_work, 0);
}
@@ -1576,7 +1548,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* If this is the first slave, then we need to set the master's hardware
* address to be the same as the slave's. */
- if (bond->slave_cnt == 0)
+ if (is_zero_ether_addr(bond->dev->dev_addr))
memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
slave_dev->addr_len);
@@ -3211,7 +3183,7 @@ out:
#ifdef CONFIG_PROC_FS
static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(&dev_base_lock)
+ __acquires(RCU)
__acquires(&bond->lock)
{
struct bonding *bond = seq->private;
@@ -3220,7 +3192,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
int i;
/* make sure the bond won't be taken away */
- read_lock(&dev_base_lock);
+ rcu_read_lock();
read_lock(&bond->lock);
if (*pos == 0)
@@ -3250,12 +3222,12 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void bond_info_seq_stop(struct seq_file *seq, void *v)
__releases(&bond->lock)
- __releases(&dev_base_lock)
+ __releases(RCU)
{
struct bonding *bond = seq->private;
read_unlock(&bond->lock);
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
}
static void bond_info_show_master(struct seq_file *seq)
@@ -3509,6 +3481,8 @@ static int bond_event_changename(struct bonding *bond)
bond_remove_proc_entry(bond);
bond_create_proc_entry(bond);
+ bond_debug_reregister(bond);
+
return NOTIFY_DONE;
}
@@ -4791,6 +4765,8 @@ static void bond_uninit(struct net_device *bond_dev)
bond_remove_proc_entry(bond);
+ bond_debug_unregister(bond);
+
__hw_addr_flush(&bond->mc_list);
list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) {
@@ -5193,6 +5169,8 @@ static int bond_init(struct net_device *bond_dev)
bond_prepare_sysfs_group(bond);
+ bond_debug_register(bond);
+
__hw_addr_init(&bond->mc_list);
return 0;
}
@@ -5299,13 +5277,6 @@ static int __init bonding_init(void)
if (res)
goto out;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
- res = -ENOMEM;
- goto out;
- }
-#endif
-
res = register_pernet_subsys(&bond_net_ops);
if (res)
goto out;
@@ -5314,6 +5285,8 @@ static int __init bonding_init(void)
if (res)
goto err_link;
+ bond_create_debugfs();
+
for (i = 0; i < max_bonds; i++) {
res = bond_create(&init_net, NULL);
if (res)
@@ -5324,7 +5297,6 @@ static int __init bonding_init(void)
if (res)
goto err;
-
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
bond_register_ipv6_notifier();
@@ -5334,9 +5306,6 @@ err:
rtnl_link_unregister(&bond_link_ops);
err_link:
unregister_pernet_subsys(&bond_net_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- free_cpumask_var(netpoll_block_tx);
-#endif
goto out;
}
@@ -5348,12 +5317,16 @@ static void __exit bonding_exit(void)
bond_unregister_ipv6_notifier();
bond_destroy_sysfs();
+ bond_destroy_debugfs();
rtnl_link_unregister(&bond_link_ops);
unregister_pernet_subsys(&bond_net_ops);
#ifdef CONFIG_NET_POLL_CONTROLLER
- free_cpumask_var(netpoll_block_tx);
+ /*
+ * Make sure we don't have an imbalance on our netpoll blocking
+ */
+ WARN_ON(atomic_read(&netpoll_block_tx));
#endif
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4eedb12df6ca..4da384cc7603 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -119,26 +119,22 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
-extern cpumask_var_t netpoll_block_tx;
+extern atomic_t netpoll_block_tx;
static inline void block_netpoll_tx(void)
{
- preempt_disable();
- BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
- netpoll_block_tx));
+ atomic_inc(&netpoll_block_tx);
}
static inline void unblock_netpoll_tx(void)
{
- BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
- netpoll_block_tx));
- preempt_enable();
+ atomic_dec(&netpoll_block_tx);
}
static inline int is_netpoll_tx_blocked(struct net_device *dev)
{
if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
- return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+ return atomic_read(&netpoll_block_tx);
return 0;
}
#else
@@ -259,6 +255,10 @@ struct bonding {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct in6_addr master_ipv6;
#endif
+#ifdef CONFIG_DEBUG_FS
+ /* debugging suport via debugfs */
+ struct dentry *debug_dir;
+#endif /* CONFIG_DEBUG_FS */
};
/**
@@ -273,11 +273,11 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n
bond_for_each_slave(bond, slave, i) {
if (slave->dev == slave_dev) {
- break;
+ return slave;
}
}
- return slave;
+ return 0;
}
static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
@@ -286,7 +286,7 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
return NULL;
}
- return (struct bonding *)netdev_priv(slave->dev->master);
+ return netdev_priv(slave->dev->master);
}
static inline bool bond_is_lb(const struct bonding *bond)
@@ -380,6 +380,11 @@ void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
void bond_register_arp(struct bonding *);
void bond_unregister_arp(struct bonding *);
+void bond_create_debugfs(void);
+void bond_destroy_debugfs(void);
+void bond_debug_register(struct bonding *bond);
+void bond_debug_unregister(struct bonding *bond);
+void bond_debug_reregister(struct bonding *bond);
struct bond_net {
struct net * net; /* Associated network namespace */
diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c
index 1cd90da86f13..5f771ab712c4 100644
--- a/drivers/net/caif/caif_shm_u5500.c
+++ b/drivers/net/caif/caif_shm_u5500.c
@@ -5,13 +5,13 @@
* License terms: GNU General Public License (GPL) version 2
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
-#include <mach/mbox.h>
+#include <mach/mbox-db5500.h>
#include <net/caif/caif_shm.h>
MODULE_LICENSE("GPL");
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c
index 19f9c0656667..80511167f35b 100644
--- a/drivers/net/caif/caif_shmcore.c
+++ b/drivers/net/caif/caif_shmcore.c
@@ -6,7 +6,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
#include <linux/spinlock.h>
#include <linux/sched.h>
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 080574b0fff0..d5a9db60ade9 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -12,6 +12,27 @@ config CAN_VCAN
This driver can also be built as a module. If so, the module
will be called vcan.
+config CAN_SLCAN
+ tristate "Serial / USB serial CAN Adaptors (slcan)"
+ depends on CAN
+ default N
+ ---help---
+ CAN driver for several 'low cost' CAN interfaces that are attached
+ via serial lines or via USB-to-serial adapters using the LAWICEL
+ ASCII protocol. The driver implements the tty linediscipline N_SLCAN.
+
+ As only the sending and receiving of CAN frames is implemented, this
+ driver should work with the (serial/USB) CAN hardware from:
+ www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de
+
+ Userspace tools to attach the SLCAN line discipline (slcan_attach,
+ slcand) can be found in the can-utils at the SocketCAN SVN, see
+ http://developer.berlios.de/projects/socketcan for details.
+
+ The slcan driver supports up to 10 CAN netdevices by default which
+ can be changed by the 'maxdev=xx' module option. This driver can
+ also be built as a module. If so, the module will be called slcan.
+
config CAN_DEV
tristate "Platform CAN drivers with Netlink support"
depends on CAN
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 90af15a4f106..07ca159ba3f9 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -3,6 +3,7 @@
#
obj-$(CONFIG_CAN_VCAN) += vcan.o
+obj-$(CONFIG_CAN_SLCAN) += slcan.o
obj-$(CONFIG_CAN_DEV) += can-dev.o
can-dev-y := dev.o
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 6e533dcc36c0..b9a6d7a5a739 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1114,11 +1114,6 @@ static bool ican3_txok(struct ican3_dev *mod)
/*
* Recieve one CAN frame from the hardware
*
- * This works like the core of a NAPI function, but is intended to be called
- * from workqueue context instead. This driver already needs a workqueue to
- * process control messages, so we use the workqueue instead of using NAPI.
- * This was done to simplify locking.
- *
* CONTEXT: must be called from user context
*/
static int ican3_recv_skb(struct ican3_dev *mod)
@@ -1251,7 +1246,6 @@ static irqreturn_t ican3_irq(int irq, void *dev_id)
* Reset an ICAN module to its power-on state
*
* CONTEXT: no network device registered
- * LOCKING: work function disabled
*/
static int ican3_reset_module(struct ican3_dev *mod)
{
@@ -1262,9 +1256,6 @@ static int ican3_reset_module(struct ican3_dev *mod)
/* disable interrupts so no more work is scheduled */
iowrite8(1 << mod->num, &mod->ctrl->int_disable);
- /* flush any pending work */
- flush_scheduled_work();
-
/* the first unallocated page in the DPM is #9 */
mod->free_page = DPM_FREE_START;
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 64c378cd0c34..74cd880c7e06 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -182,7 +182,7 @@ static int mscan_restart(struct net_device *dev)
priv->can.state = CAN_STATE_ERROR_ACTIVE;
WARN(!(in_8(&regs->canmisc) & MSCAN_BOHOLD),
- "bus-off state expected");
+ "bus-off state expected\n");
out_8(&regs->canmisc, MSCAN_BOHOLD);
/* Re-enable receive interrupts. */
out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 672718261c68..c42e97268248 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 - 2010 Intel Corporation.
- * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,106 +32,115 @@
#include <linux/can/dev.h>
#include <linux/can/error.h>
-#define MAX_MSG_OBJ 32
-#define MSG_OBJ_RX 0 /* The receive message object flag. */
-#define MSG_OBJ_TX 1 /* The transmit message object flag. */
-
-#define ENABLE 1 /* The enable flag */
-#define DISABLE 0 /* The disable flag */
-#define CAN_CTRL_INIT 0x0001 /* The INIT bit of CANCONT register. */
-#define CAN_CTRL_IE 0x0002 /* The IE bit of CAN control register */
-#define CAN_CTRL_IE_SIE_EIE 0x000e
-#define CAN_CTRL_CCE 0x0040
-#define CAN_CTRL_OPT 0x0080 /* The OPT bit of CANCONT register. */
-#define CAN_OPT_SILENT 0x0008 /* The Silent bit of CANOPT reg. */
-#define CAN_OPT_LBACK 0x0010 /* The LoopBack bit of CANOPT reg. */
-#define CAN_CMASK_RX_TX_SET 0x00f3
-#define CAN_CMASK_RX_TX_GET 0x0073
-#define CAN_CMASK_ALL 0xff
-#define CAN_CMASK_RDWR 0x80
-#define CAN_CMASK_ARB 0x20
-#define CAN_CMASK_CTRL 0x10
-#define CAN_CMASK_MASK 0x40
-#define CAN_CMASK_NEWDAT 0x04
-#define CAN_CMASK_CLRINTPND 0x08
-
-#define CAN_IF_MCONT_NEWDAT 0x8000
-#define CAN_IF_MCONT_INTPND 0x2000
-#define CAN_IF_MCONT_UMASK 0x1000
-#define CAN_IF_MCONT_TXIE 0x0800
-#define CAN_IF_MCONT_RXIE 0x0400
-#define CAN_IF_MCONT_RMTEN 0x0200
-#define CAN_IF_MCONT_TXRQXT 0x0100
-#define CAN_IF_MCONT_EOB 0x0080
-#define CAN_IF_MCONT_DLC 0x000f
-#define CAN_IF_MCONT_MSGLOST 0x4000
-#define CAN_MASK2_MDIR_MXTD 0xc000
-#define CAN_ID2_DIR 0x2000
-#define CAN_ID_MSGVAL 0x8000
-
-#define CAN_STATUS_INT 0x8000
-#define CAN_IF_CREQ_BUSY 0x8000
-#define CAN_ID2_XTD 0x4000
-
-#define CAN_REC 0x00007f00
-#define CAN_TEC 0x000000ff
-
-#define PCH_RX_OK 0x00000010
-#define PCH_TX_OK 0x00000008
-#define PCH_BUS_OFF 0x00000080
-#define PCH_EWARN 0x00000040
-#define PCH_EPASSIV 0x00000020
-#define PCH_LEC0 0x00000001
-#define PCH_LEC1 0x00000002
-#define PCH_LEC2 0x00000004
-#define PCH_LEC_ALL (PCH_LEC0 | PCH_LEC1 | PCH_LEC2)
-#define PCH_STUF_ERR PCH_LEC0
-#define PCH_FORM_ERR PCH_LEC1
-#define PCH_ACK_ERR (PCH_LEC0 | PCH_LEC1)
-#define PCH_BIT1_ERR PCH_LEC2
-#define PCH_BIT0_ERR (PCH_LEC0 | PCH_LEC2)
-#define PCH_CRC_ERR (PCH_LEC1 | PCH_LEC2)
+#define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */
+#define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */
+#define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1))
+#define PCH_CTRL_CCE BIT(6)
+#define PCH_CTRL_OPT BIT(7) /* The OPT bit of CANCONT register. */
+#define PCH_OPT_SILENT BIT(3) /* The Silent bit of CANOPT reg. */
+#define PCH_OPT_LBACK BIT(4) /* The LoopBack bit of CANOPT reg. */
+
+#define PCH_CMASK_RX_TX_SET 0x00f3
+#define PCH_CMASK_RX_TX_GET 0x0073
+#define PCH_CMASK_ALL 0xff
+#define PCH_CMASK_NEWDAT BIT(2)
+#define PCH_CMASK_CLRINTPND BIT(3)
+#define PCH_CMASK_CTRL BIT(4)
+#define PCH_CMASK_ARB BIT(5)
+#define PCH_CMASK_MASK BIT(6)
+#define PCH_CMASK_RDWR BIT(7)
+#define PCH_IF_MCONT_NEWDAT BIT(15)
+#define PCH_IF_MCONT_MSGLOST BIT(14)
+#define PCH_IF_MCONT_INTPND BIT(13)
+#define PCH_IF_MCONT_UMASK BIT(12)
+#define PCH_IF_MCONT_TXIE BIT(11)
+#define PCH_IF_MCONT_RXIE BIT(10)
+#define PCH_IF_MCONT_RMTEN BIT(9)
+#define PCH_IF_MCONT_TXRQXT BIT(8)
+#define PCH_IF_MCONT_EOB BIT(7)
+#define PCH_IF_MCONT_DLC (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define PCH_MASK2_MDIR_MXTD (BIT(14) | BIT(15))
+#define PCH_ID2_DIR BIT(13)
+#define PCH_ID2_XTD BIT(14)
+#define PCH_ID_MSGVAL BIT(15)
+#define PCH_IF_CREQ_BUSY BIT(15)
+
+#define PCH_STATUS_INT 0x8000
+#define PCH_REC 0x00007f00
+#define PCH_TEC 0x000000ff
+
+#define PCH_TX_OK BIT(3)
+#define PCH_RX_OK BIT(4)
+#define PCH_EPASSIV BIT(5)
+#define PCH_EWARN BIT(6)
+#define PCH_BUS_OFF BIT(7)
/* bit position of certain controller bits. */
-#define BIT_BITT_BRP 0
-#define BIT_BITT_SJW 6
-#define BIT_BITT_TSEG1 8
-#define BIT_BITT_TSEG2 12
-#define BIT_IF1_MCONT_RXIE 10
-#define BIT_IF2_MCONT_TXIE 11
-#define BIT_BRPE_BRPE 6
-#define BIT_ES_TXERRCNT 0
-#define BIT_ES_RXERRCNT 8
-#define MSK_BITT_BRP 0x3f
-#define MSK_BITT_SJW 0xc0
-#define MSK_BITT_TSEG1 0xf00
-#define MSK_BITT_TSEG2 0x7000
-#define MSK_BRPE_BRPE 0x3c0
-#define MSK_BRPE_GET 0x0f
-#define MSK_CTRL_IE_SIE_EIE 0x07
-#define MSK_MCONT_TXIE 0x08
-#define MSK_MCONT_RXIE 0x10
-#define PCH_CAN_NO_TX_BUFF 1
-#define COUNTER_LIMIT 10
+#define PCH_BIT_BRP_SHIFT 0
+#define PCH_BIT_SJW_SHIFT 6
+#define PCH_BIT_TSEG1_SHIFT 8
+#define PCH_BIT_TSEG2_SHIFT 12
+#define PCH_BIT_BRPE_BRPE_SHIFT 6
+
+#define PCH_MSK_BITT_BRP 0x3f
+#define PCH_MSK_BRPE_BRPE 0x3c0
+#define PCH_MSK_CTRL_IE_SIE_EIE 0x07
+#define PCH_COUNTER_LIMIT 10
#define PCH_CAN_CLK 50000000 /* 50MHz */
-/* Define the number of message object.
+/*
+ * Define the number of message object.
* PCH CAN communications are done via Message RAM.
- * The Message RAM consists of 32 message objects. */
-#define PCH_RX_OBJ_NUM 26 /* 1~ PCH_RX_OBJ_NUM is Rx*/
-#define PCH_TX_OBJ_NUM 6 /* PCH_RX_OBJ_NUM is RX ~ Tx*/
-#define PCH_OBJ_NUM (PCH_TX_OBJ_NUM + PCH_RX_OBJ_NUM)
+ * The Message RAM consists of 32 message objects.
+ */
+#define PCH_RX_OBJ_NUM 26
+#define PCH_TX_OBJ_NUM 6
+#define PCH_RX_OBJ_START 1
+#define PCH_RX_OBJ_END PCH_RX_OBJ_NUM
+#define PCH_TX_OBJ_START (PCH_RX_OBJ_END + 1)
+#define PCH_TX_OBJ_END (PCH_RX_OBJ_NUM + PCH_TX_OBJ_NUM)
#define PCH_FIFO_THRESH 16
+/* TxRqst2 show status of MsgObjNo.17~32 */
+#define PCH_TREQ2_TX_MASK (((1 << PCH_TX_OBJ_NUM) - 1) <<\
+ (PCH_RX_OBJ_END - 16))
+
+enum pch_ifreg {
+ PCH_RX_IFREG,
+ PCH_TX_IFREG,
+};
+
+enum pch_can_err {
+ PCH_STUF_ERR = 1,
+ PCH_FORM_ERR,
+ PCH_ACK_ERR,
+ PCH_BIT1_ERR,
+ PCH_BIT0_ERR,
+ PCH_CRC_ERR,
+ PCH_LEC_ALL,
+};
+
enum pch_can_mode {
PCH_CAN_ENABLE,
PCH_CAN_DISABLE,
PCH_CAN_ALL,
PCH_CAN_NONE,
PCH_CAN_STOP,
- PCH_CAN_RUN
+ PCH_CAN_RUN,
+};
+
+struct pch_can_if_regs {
+ u32 creq;
+ u32 cmask;
+ u32 mask1;
+ u32 mask2;
+ u32 id1;
+ u32 id2;
+ u32 mcont;
+ u32 data[4];
+ u32 rsv[13];
};
struct pch_can_regs {
@@ -142,57 +151,36 @@ struct pch_can_regs {
u32 intr;
u32 opt;
u32 brpe;
- u32 reserve1;
- u32 if1_creq;
- u32 if1_cmask;
- u32 if1_mask1;
- u32 if1_mask2;
- u32 if1_id1;
- u32 if1_id2;
- u32 if1_mcont;
- u32 if1_dataa1;
- u32 if1_dataa2;
- u32 if1_datab1;
- u32 if1_datab2;
- u32 reserve2;
- u32 reserve3[12];
- u32 if2_creq;
- u32 if2_cmask;
- u32 if2_mask1;
- u32 if2_mask2;
- u32 if2_id1;
- u32 if2_id2;
- u32 if2_mcont;
- u32 if2_dataa1;
- u32 if2_dataa2;
- u32 if2_datab1;
- u32 if2_datab2;
- u32 reserve4;
- u32 reserve5[20];
+ u32 reserve;
+ struct pch_can_if_regs ifregs[2]; /* [0]=if1 [1]=if2 */
+ u32 reserve1[8];
u32 treq1;
u32 treq2;
- u32 reserve6[2];
- u32 reserve7[56];
- u32 reserve8[3];
+ u32 reserve2[6];
+ u32 data1;
+ u32 data2;
+ u32 reserve3[6];
+ u32 canipend1;
+ u32 canipend2;
+ u32 reserve4[6];
+ u32 canmval1;
+ u32 canmval2;
+ u32 reserve5[37];
u32 srst;
};
struct pch_can_priv {
struct can_priv can;
- unsigned int can_num;
struct pci_dev *dev;
- unsigned int tx_enable[MAX_MSG_OBJ];
- unsigned int rx_enable[MAX_MSG_OBJ];
- unsigned int rx_link[MAX_MSG_OBJ];
- unsigned int int_enables;
- unsigned int int_stat;
+ u32 tx_enable[PCH_TX_OBJ_END];
+ u32 rx_enable[PCH_TX_OBJ_END];
+ u32 rx_link[PCH_TX_OBJ_END];
+ u32 int_enables;
struct net_device *ndev;
- spinlock_t msgif_reg_lock; /* Message Interface Registers Access Lock*/
- unsigned int msg_obj[MAX_MSG_OBJ];
struct pch_can_regs __iomem *regs;
struct napi_struct napi;
- unsigned int tx_obj; /* Point next Tx Obj index */
- unsigned int use_msi;
+ int tx_obj; /* Point next Tx Obj index */
+ int use_msi;
};
static struct can_bittiming_const pch_can_bittiming_const = {
@@ -228,15 +216,15 @@ static void pch_can_set_run_mode(struct pch_can_priv *priv,
{
switch (mode) {
case PCH_CAN_RUN:
- pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_INIT);
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_INIT);
break;
case PCH_CAN_STOP:
- pch_can_bit_set(&priv->regs->cont, CAN_CTRL_INIT);
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_INIT);
break;
default:
- dev_err(&priv->ndev->dev, "%s -> Invalid Mode.\n", __func__);
+ netdev_err(priv->ndev, "%s -> Invalid Mode.\n", __func__);
break;
}
}
@@ -246,357 +234,184 @@ static void pch_can_set_optmode(struct pch_can_priv *priv)
u32 reg_val = ioread32(&priv->regs->opt);
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
- reg_val |= CAN_OPT_SILENT;
+ reg_val |= PCH_OPT_SILENT;
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
- reg_val |= CAN_OPT_LBACK;
+ reg_val |= PCH_OPT_LBACK;
- pch_can_bit_set(&priv->regs->cont, CAN_CTRL_OPT);
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_OPT);
iowrite32(reg_val, &priv->regs->opt);
}
-static void pch_can_set_int_custom(struct pch_can_priv *priv)
+static void pch_can_rw_msg_obj(void __iomem *creq_addr, u32 num)
{
- /* Clearing the IE, SIE and EIE bits of Can control register. */
- pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE);
-
- /* Appropriately setting them. */
- pch_can_bit_set(&priv->regs->cont,
- ((priv->int_enables & MSK_CTRL_IE_SIE_EIE) << 1));
-}
+ int counter = PCH_COUNTER_LIMIT;
+ u32 ifx_creq;
-/* This function retrieves interrupt enabled for the CAN device. */
-static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables)
-{
- /* Obtaining the status of IE, SIE and EIE interrupt bits. */
- *enables = ((ioread32(&priv->regs->cont) & CAN_CTRL_IE_SIE_EIE) >> 1);
+ iowrite32(num, creq_addr);
+ while (counter) {
+ ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY;
+ if (!ifx_creq)
+ break;
+ counter--;
+ udelay(1);
+ }
+ if (!counter)
+ pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__);
}
static void pch_can_set_int_enables(struct pch_can_priv *priv,
enum pch_can_mode interrupt_no)
{
switch (interrupt_no) {
- case PCH_CAN_ENABLE:
- pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE);
- break;
-
case PCH_CAN_DISABLE:
- pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE);
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE);
break;
case PCH_CAN_ALL:
- pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE);
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
break;
case PCH_CAN_NONE:
- pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE);
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
break;
default:
- dev_err(&priv->ndev->dev, "Invalid interrupt number.\n");
+ netdev_err(priv->ndev, "Invalid interrupt number.\n");
break;
}
}
-static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num)
-{
- u32 counter = COUNTER_LIMIT;
- u32 ifx_creq;
-
- iowrite32(num, creq_addr);
- while (counter) {
- ifx_creq = ioread32(creq_addr) & CAN_IF_CREQ_BUSY;
- if (!ifx_creq)
- break;
- counter--;
- udelay(1);
- }
- if (!counter)
- pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__);
-}
-
-static void pch_can_set_rx_enable(struct pch_can_priv *priv, u32 buff_num,
- u32 set)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- /* Reading the receive buffer data from RAM to Interface1 registers */
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
-
- /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if1_cmask);
-
- if (set == ENABLE) {
- /* Setting the MsgVal and RxIE bits */
- pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE);
- pch_can_bit_set(&priv->regs->if1_id2, CAN_ID_MSGVAL);
-
- } else if (set == DISABLE) {
- /* Resetting the MsgVal and RxIE bits */
- pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE);
- pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID_MSGVAL);
- }
-
- pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
-}
-
-static void pch_can_rx_enable_all(struct pch_can_priv *priv)
+static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num,
+ int set, enum pch_ifreg dir)
{
- int i;
+ u32 ie;
- /* Traversing to obtain the object configured as receivers. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_RX)
- pch_can_set_rx_enable(priv, i + 1, ENABLE);
- }
-}
+ if (dir)
+ ie = PCH_IF_MCONT_TXIE;
+ else
+ ie = PCH_IF_MCONT_RXIE;
-static void pch_can_rx_disable_all(struct pch_can_priv *priv)
-{
- int i;
+ /* Reading the Msg buffer from Message RAM to IF1/2 registers. */
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
- /* Traversing to obtain the object configured as receivers. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_RX)
- pch_can_set_rx_enable(priv, i + 1, DISABLE);
- }
-}
+ /* Setting the IF1/2MASK1 register to access MsgVal and RxIE bits */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[dir].cmask);
-static void pch_can_set_tx_enable(struct pch_can_priv *priv, u32 buff_num,
- u32 set)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- /* Reading the Msg buffer from Message RAM to Interface2 registers. */
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
-
- /* Setting the IF2CMASK register for accessing the
- MsgVal and TxIE bits */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if2_cmask);
-
- if (set == ENABLE) {
- /* Setting the MsgVal and TxIE bits */
- pch_can_bit_set(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE);
- pch_can_bit_set(&priv->regs->if2_id2, CAN_ID_MSGVAL);
- } else if (set == DISABLE) {
- /* Resetting the MsgVal and TxIE bits. */
- pch_can_bit_clear(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE);
- pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID_MSGVAL);
+ if (set) {
+ /* Setting the MsgVal and RxIE/TxIE bits */
+ pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie);
+ pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
+ } else {
+ /* Clearing the MsgVal and RxIE/TxIE bits */
+ pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie);
+ pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
}
- pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
}
-static void pch_can_tx_enable_all(struct pch_can_priv *priv)
+static void pch_can_set_rx_all(struct pch_can_priv *priv, int set)
{
int i;
- /* Traversing to obtain the object configured as transmit object. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_TX)
- pch_can_set_tx_enable(priv, i + 1, ENABLE);
- }
+ /* Traversing to obtain the object configured as receivers. */
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, set, PCH_RX_IFREG);
}
-static void pch_can_tx_disable_all(struct pch_can_priv *priv)
+static void pch_can_set_tx_all(struct pch_can_priv *priv, int set)
{
int i;
/* Traversing to obtain the object configured as transmit object. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_TX)
- pch_can_set_tx_enable(priv, i + 1, DISABLE);
- }
-}
-
-static void pch_can_get_rx_enable(struct pch_can_priv *priv, u32 buff_num,
- u32 *enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
-
- if (((ioread32(&priv->regs->if1_id2)) & CAN_ID_MSGVAL) &&
- ((ioread32(&priv->regs->if1_mcont)) &
- CAN_IF_MCONT_RXIE))
- *enable = ENABLE;
- else
- *enable = DISABLE;
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
-}
-
-static void pch_can_get_tx_enable(struct pch_can_priv *priv, u32 buff_num,
- u32 *enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
-
- if (((ioread32(&priv->regs->if2_id2)) & CAN_ID_MSGVAL) &&
- ((ioread32(&priv->regs->if2_mcont)) &
- CAN_IF_MCONT_TXIE)) {
- *enable = ENABLE;
- } else {
- *enable = DISABLE;
- }
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG);
}
-static int pch_can_int_pending(struct pch_can_priv *priv)
+static u32 pch_can_int_pending(struct pch_can_priv *priv)
{
return ioread32(&priv->regs->intr) & 0xffff;
}
-static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
- u32 buffer_num, u32 set)
+static void pch_can_clear_if_buffers(struct pch_can_priv *priv)
{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL, &priv->regs->if1_cmask);
- if (set == ENABLE)
- pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB);
- else
- pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB);
-
- pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
-}
-
-static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv,
- u32 buffer_num, u32 *link)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
-
- if (ioread32(&priv->regs->if1_mcont) & CAN_IF_MCONT_EOB)
- *link = DISABLE;
- else
- *link = ENABLE;
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
-}
-
-static void pch_can_clear_buffers(struct pch_can_priv *priv)
-{
- int i;
-
- for (i = 0; i < PCH_RX_OBJ_NUM; i++) {
- iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if1_cmask);
- iowrite32(0xffff, &priv->regs->if1_mask1);
- iowrite32(0xffff, &priv->regs->if1_mask2);
- iowrite32(0x0, &priv->regs->if1_id1);
- iowrite32(0x0, &priv->regs->if1_id2);
- iowrite32(0x0, &priv->regs->if1_mcont);
- iowrite32(0x0, &priv->regs->if1_dataa1);
- iowrite32(0x0, &priv->regs->if1_dataa2);
- iowrite32(0x0, &priv->regs->if1_datab1);
- iowrite32(0x0, &priv->regs->if1_datab2);
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
- CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
- }
-
- for (i = i; i < PCH_OBJ_NUM; i++) {
- iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if2_cmask);
- iowrite32(0xffff, &priv->regs->if2_mask1);
- iowrite32(0xffff, &priv->regs->if2_mask2);
- iowrite32(0x0, &priv->regs->if2_id1);
- iowrite32(0x0, &priv->regs->if2_id2);
- iowrite32(0x0, &priv->regs->if2_mcont);
- iowrite32(0x0, &priv->regs->if2_dataa1);
- iowrite32(0x0, &priv->regs->if2_dataa2);
- iowrite32(0x0, &priv->regs->if2_datab1);
- iowrite32(0x0, &priv->regs->if2_datab2);
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
- CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
+ int i; /* Msg Obj ID (1~32) */
+
+ for (i = PCH_RX_OBJ_START; i <= PCH_TX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask);
+ iowrite32(0xffff, &priv->regs->ifregs[0].mask1);
+ iowrite32(0xffff, &priv->regs->ifregs[0].mask2);
+ iowrite32(0x0, &priv->regs->ifregs[0].id1);
+ iowrite32(0x0, &priv->regs->ifregs[0].id2);
+ iowrite32(0x0, &priv->regs->ifregs[0].mcont);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[0]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[1]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[2]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[3]);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
+ PCH_CMASK_ARB | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
}
}
static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv)
{
int i;
- unsigned long flags;
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_RX) {
- iowrite32(CAN_CMASK_RX_TX_GET,
- &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
+ iowrite32(0x0, &priv->regs->ifregs[0].id1);
+ iowrite32(0x0, &priv->regs->ifregs[0].id2);
- iowrite32(0x0, &priv->regs->if1_id1);
- iowrite32(0x0, &priv->regs->if1_id2);
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_UMASK);
- pch_can_bit_set(&priv->regs->if1_mcont,
- CAN_IF_MCONT_UMASK);
+ /* In case FIFO mode, Last EoB of Rx Obj must be 1 */
+ if (i == PCH_RX_OBJ_END)
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
+ else
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
- /* Set FIFO mode set to 0 except last Rx Obj*/
- pch_can_bit_clear(&priv->regs->if1_mcont,
- CAN_IF_MCONT_EOB);
- /* In case FIFO mode, Last EoB of Rx Obj must be 1 */
- if (i == (PCH_RX_OBJ_NUM - 1))
- pch_can_bit_set(&priv->regs->if1_mcont,
- CAN_IF_MCONT_EOB);
+ iowrite32(0, &priv->regs->ifregs[0].mask1);
+ pch_can_bit_clear(&priv->regs->ifregs[0].mask2,
+ 0x1fff | PCH_MASK2_MDIR_MXTD);
- iowrite32(0, &priv->regs->if1_mask1);
- pch_can_bit_clear(&priv->regs->if1_mask2,
- 0x1fff | CAN_MASK2_MDIR_MXTD);
+ /* Setting CMASK for writing */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB |
+ PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask);
- /* Setting CMASK for writing */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
- CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if1_cmask);
-
- pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
- } else if (priv->msg_obj[i] == MSG_OBJ_TX) {
- iowrite32(CAN_CMASK_RX_TX_GET,
- &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
+ }
- /* Resetting DIR bit for reception */
- iowrite32(0x0, &priv->regs->if2_id1);
- iowrite32(0x0, &priv->regs->if2_id2);
- pch_can_bit_set(&priv->regs->if2_id2, CAN_ID2_DIR);
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i);
- /* Setting EOB bit for transmitter */
- iowrite32(CAN_IF_MCONT_EOB, &priv->regs->if2_mcont);
+ /* Resetting DIR bit for reception */
+ iowrite32(0x0, &priv->regs->ifregs[1].id1);
+ iowrite32(PCH_ID2_DIR, &priv->regs->ifregs[1].id2);
- pch_can_bit_set(&priv->regs->if2_mcont,
- CAN_IF_MCONT_UMASK);
+ /* Setting EOB bit for transmitter */
+ iowrite32(PCH_IF_MCONT_EOB | PCH_IF_MCONT_UMASK,
+ &priv->regs->ifregs[1].mcont);
- iowrite32(0, &priv->regs->if2_mask1);
- pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff);
+ iowrite32(0, &priv->regs->ifregs[1].mask1);
+ pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff);
- /* Setting CMASK for writing */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
- CAN_CMASK_ARB | CAN_CMASK_CTRL,
- &priv->regs->if2_cmask);
+ /* Setting CMASK for writing */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB |
+ PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
- }
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i);
}
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
}
static void pch_can_init(struct pch_can_priv *priv)
@@ -605,7 +420,7 @@ static void pch_can_init(struct pch_can_priv *priv)
pch_can_set_run_mode(priv, PCH_CAN_STOP);
/* Clearing all the message object buffers. */
- pch_can_clear_buffers(priv);
+ pch_can_clear_if_buffers(priv);
/* Configuring the respective message object as either rx/tx object. */
pch_can_config_rx_tx_buffers(priv);
@@ -623,57 +438,47 @@ static void pch_can_release(struct pch_can_priv *priv)
pch_can_set_int_enables(priv, PCH_CAN_NONE);
/* Disabling all the receive object. */
- pch_can_rx_disable_all(priv);
+ pch_can_set_rx_all(priv, 0);
/* Disabling all the transmit object. */
- pch_can_tx_disable_all(priv);
+ pch_can_set_tx_all(priv, 0);
}
/* This function clears interrupt(s) from the CAN device. */
static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask)
{
- if (mask == CAN_STATUS_INT) {
- ioread32(&priv->regs->stat);
- return;
- }
-
/* Clear interrupt for transmit object */
- if (priv->msg_obj[mask - 1] == MSG_OBJ_TX) {
- /* Setting CMASK for clearing interrupts for
- frame transmission. */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB,
- &priv->regs->if2_cmask);
-
- /* Resetting the ID registers. */
- pch_can_bit_set(&priv->regs->if2_id2,
- CAN_ID2_DIR | (0x7ff << 2));
- iowrite32(0x0, &priv->regs->if2_id1);
-
- /* Claring NewDat, TxRqst & IntPnd */
- pch_can_bit_clear(&priv->regs->if2_mcont,
- CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND |
- CAN_IF_MCONT_TXRQXT);
- pch_can_check_if_busy(&priv->regs->if2_creq, mask);
- } else if (priv->msg_obj[mask - 1] == MSG_OBJ_RX) {
+ if ((mask >= PCH_RX_OBJ_START) && (mask <= PCH_RX_OBJ_END)) {
/* Setting CMASK for clearing the reception interrupts. */
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB,
- &priv->regs->if1_cmask);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
+ &priv->regs->ifregs[0].cmask);
/* Clearing the Dir bit. */
- pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR);
+ pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR);
/* Clearing NewDat & IntPnd */
- pch_can_bit_clear(&priv->regs->if1_mcont,
- CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND);
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND);
- pch_can_check_if_busy(&priv->regs->if1_creq, mask);
- }
-}
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, mask);
+ } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) {
+ /*
+ * Setting CMASK for clearing interrupts for frame transmission.
+ */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
+ &priv->regs->ifregs[1].cmask);
-static int pch_can_get_buffer_status(struct pch_can_priv *priv)
-{
- return (ioread32(&priv->regs->treq1) & 0xffff) |
- ((ioread32(&priv->regs->treq2) & 0xffff) << 16);
+ /* Resetting the ID registers. */
+ pch_can_bit_set(&priv->regs->ifregs[1].id2,
+ PCH_ID2_DIR | (0x7ff << 2));
+ iowrite32(0x0, &priv->regs->ifregs[1].id1);
+
+ /* Claring NewDat, TxRqst & IntPnd */
+ pch_can_bit_clear(&priv->regs->ifregs[1].mcont,
+ PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND |
+ PCH_IF_MCONT_TXRQXT);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, mask);
+ }
}
static void pch_can_reset(struct pch_can_priv *priv)
@@ -688,7 +493,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
struct sk_buff *skb;
struct pch_can_priv *priv = netdev_priv(ndev);
struct can_frame *cf;
- u32 errc;
+ u32 errc, lec;
struct net_device_stats *stats = &(priv->ndev->stats);
enum can_state state = priv->can.state;
@@ -697,26 +502,24 @@ static void pch_can_error(struct net_device *ndev, u32 status)
return;
if (status & PCH_BUS_OFF) {
- pch_can_tx_disable_all(priv);
- pch_can_rx_disable_all(priv);
+ pch_can_set_tx_all(priv, 0);
+ pch_can_set_rx_all(priv, 0);
state = CAN_STATE_BUS_OFF;
cf->can_id |= CAN_ERR_BUSOFF;
can_bus_off(ndev);
- pch_can_set_run_mode(priv, PCH_CAN_RUN);
- dev_err(&ndev->dev, "%s -> Bus Off occurres.\n", __func__);
}
+ errc = ioread32(&priv->regs->errc);
/* Warning interrupt. */
if (status & PCH_EWARN) {
state = CAN_STATE_ERROR_WARNING;
priv->can.can_stats.error_warning++;
cf->can_id |= CAN_ERR_CRTL;
- errc = ioread32(&priv->regs->errc);
- if (((errc & CAN_REC) >> 8) > 96)
+ if (((errc & PCH_REC) >> 8) > 96)
cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
- if ((errc & CAN_TEC) > 96)
+ if ((errc & PCH_TEC) > 96)
cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
- dev_warn(&ndev->dev,
+ netdev_dbg(ndev,
"%s -> Error Counter is more than 96.\n", __func__);
}
/* Error passive interrupt. */
@@ -724,46 +527,52 @@ static void pch_can_error(struct net_device *ndev, u32 status)
priv->can.can_stats.error_passive++;
state = CAN_STATE_ERROR_PASSIVE;
cf->can_id |= CAN_ERR_CRTL;
- errc = ioread32(&priv->regs->errc);
- if (((errc & CAN_REC) >> 8) > 127)
+ if (((errc & PCH_REC) >> 8) > 127)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
- if ((errc & CAN_TEC) > 127)
+ if ((errc & PCH_TEC) > 127)
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
- dev_err(&ndev->dev,
+ netdev_dbg(ndev,
"%s -> CAN controller is ERROR PASSIVE .\n", __func__);
}
- if (status & PCH_LEC_ALL) {
+ lec = status & PCH_LEC_ALL;
+ switch (lec) {
+ case PCH_STUF_ERR:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
priv->can.can_stats.bus_error++;
stats->rx_errors++;
- switch (status & PCH_LEC_ALL) {
- case PCH_STUF_ERR:
- cf->data[2] |= CAN_ERR_PROT_STUFF;
- break;
- case PCH_FORM_ERR:
- cf->data[2] |= CAN_ERR_PROT_FORM;
- break;
- case PCH_ACK_ERR:
- cf->data[2] |= CAN_ERR_PROT_LOC_ACK |
- CAN_ERR_PROT_LOC_ACK_DEL;
- break;
- case PCH_BIT1_ERR:
- case PCH_BIT0_ERR:
- cf->data[2] |= CAN_ERR_PROT_BIT;
- break;
- case PCH_CRC_ERR:
- cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
- CAN_ERR_PROT_LOC_CRC_DEL;
- break;
- default:
- iowrite32(status | PCH_LEC_ALL, &priv->regs->stat);
- break;
- }
-
+ break;
+ case PCH_FORM_ERR:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_ACK_ERR:
+ cf->can_id |= CAN_ERR_ACK;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_BIT1_ERR:
+ case PCH_BIT0_ERR:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_CRC_ERR:
+ cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_LEC_ALL: /* Written by CPU. No error status */
+ break;
}
+ cf->data[6] = errc & PCH_TEC;
+ cf->data[7] = (errc & PCH_REC) >> 8;
+
priv->can.state = state;
- netif_rx(skb);
+ netif_receive_skb(skb);
stats->rx_packets++;
stats->rx_bytes += cf->can_dlc;
@@ -774,204 +583,202 @@ static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
struct net_device *ndev = (struct net_device *)dev_id;
struct pch_can_priv *priv = netdev_priv(ndev);
- pch_can_set_int_enables(priv, PCH_CAN_NONE);
+ if (!pch_can_int_pending(priv))
+ return IRQ_NONE;
+ pch_can_set_int_enables(priv, PCH_CAN_NONE);
napi_schedule(&priv->napi);
-
return IRQ_HANDLED;
}
-static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat)
+static void pch_fifo_thresh(struct pch_can_priv *priv, int obj_id)
+{
+ if (obj_id < PCH_FIFO_THRESH) {
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL |
+ PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask);
+
+ /* Clearing the Dir bit. */
+ pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR);
+
+ /* Clearing NewDat & IntPnd */
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_INTPND);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id);
+ } else if (obj_id > PCH_FIFO_THRESH) {
+ pch_can_int_clr(priv, obj_id);
+ } else if (obj_id == PCH_FIFO_THRESH) {
+ int cnt;
+ for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++)
+ pch_can_int_clr(priv, cnt + 1);
+ }
+}
+
+static void pch_can_rx_msg_lost(struct net_device *ndev, int obj_id)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &(priv->ndev->stats);
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ netdev_dbg(priv->ndev, "Msg Obj is overwritten.\n");
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_MSGLOST);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id);
+
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb)
+ return;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+
+ netif_receive_skb(skb);
+}
+
+static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
{
u32 reg;
canid_t id;
- u32 ide;
- u32 rtr;
- int i, j, k;
int rcv_pkts = 0;
struct sk_buff *skb;
struct can_frame *cf;
struct pch_can_priv *priv = netdev_priv(ndev);
struct net_device_stats *stats = &(priv->ndev->stats);
+ int i;
+ u32 id2;
+ u16 data_reg;
+
+ do {
+ /* Reading the messsage object from the Message RAM */
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num);
- /* Reading the messsage object from the Message RAM */
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, int_stat);
+ /* Reading the MCONT register. */
+ reg = ioread32(&priv->regs->ifregs[0].mcont);
- /* Reading the MCONT register. */
- reg = ioread32(&priv->regs->if1_mcont);
- reg &= 0xffff;
+ if (reg & PCH_IF_MCONT_EOB)
+ break;
- for (k = int_stat; !(reg & CAN_IF_MCONT_EOB); k++) {
/* If MsgLost bit set. */
- if (reg & CAN_IF_MCONT_MSGLOST) {
- dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n");
- pch_can_bit_clear(&priv->regs->if1_mcont,
- CAN_IF_MCONT_MSGLOST);
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL,
- &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, k);
-
- skb = alloc_can_err_skb(ndev, &cf);
- if (!skb)
- return -ENOMEM;
-
- priv->can.can_stats.error_passive++;
- priv->can.state = CAN_STATE_ERROR_PASSIVE;
- cf->can_id |= CAN_ERR_CRTL;
- cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
- cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
- stats->rx_packets++;
- stats->rx_bytes += cf->can_dlc;
-
- netif_receive_skb(skb);
+ if (reg & PCH_IF_MCONT_MSGLOST) {
+ pch_can_rx_msg_lost(ndev, obj_num);
rcv_pkts++;
- goto RX_NEXT;
+ quota--;
+ obj_num++;
+ continue;
+ } else if (!(reg & PCH_IF_MCONT_NEWDAT)) {
+ obj_num++;
+ continue;
}
- if (!(reg & CAN_IF_MCONT_NEWDAT))
- goto RX_NEXT;
skb = alloc_can_skb(priv->ndev, &cf);
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ netdev_err(ndev, "alloc_can_skb Failed\n");
+ return rcv_pkts;
+ }
/* Get Received data */
- ide = ((ioread32(&priv->regs->if1_id2)) & CAN_ID2_XTD) >> 14;
- if (ide) {
- id = (ioread32(&priv->regs->if1_id1) & 0xffff);
- id |= (((ioread32(&priv->regs->if1_id2)) &
- 0x1fff) << 16);
- cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ id2 = ioread32(&priv->regs->ifregs[0].id2);
+ if (id2 & PCH_ID2_XTD) {
+ id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff);
+ id |= (((id2) & 0x1fff) << 16);
+ cf->can_id = id | CAN_EFF_FLAG;
} else {
- id = (((ioread32(&priv->regs->if1_id2)) &
- (CAN_SFF_MASK << 2)) >> 2);
- cf->can_id = (id & CAN_SFF_MASK);
+ id = (id2 >> 2) & CAN_SFF_MASK;
+ cf->can_id = id;
}
- rtr = (ioread32(&priv->regs->if1_id2) & CAN_ID2_DIR);
- if (rtr) {
- cf->can_dlc = 0;
+ if (id2 & PCH_ID2_DIR)
cf->can_id |= CAN_RTR_FLAG;
- } else {
- cf->can_dlc = ((ioread32(&priv->regs->if1_mcont)) &
- 0x0f);
- }
- for (i = 0, j = 0; i < cf->can_dlc; j++) {
- reg = ioread32(&priv->regs->if1_dataa1 + j*4);
- cf->data[i++] = cpu_to_le32(reg & 0xff);
- if (i == cf->can_dlc)
- break;
- cf->data[i++] = cpu_to_le32((reg >> 8) & 0xff);
+ cf->can_dlc = get_can_dlc((ioread32(&priv->regs->
+ ifregs[0].mcont)) & 0xF);
+
+ for (i = 0; i < cf->can_dlc; i += 2) {
+ data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]);
+ cf->data[i] = data_reg;
+ cf->data[i + 1] = data_reg >> 8;
}
netif_receive_skb(skb);
rcv_pkts++;
stats->rx_packets++;
+ quota--;
stats->rx_bytes += cf->can_dlc;
- if (k < PCH_FIFO_THRESH) {
- iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL |
- CAN_CMASK_ARB, &priv->regs->if1_cmask);
-
- /* Clearing the Dir bit. */
- pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR);
-
- /* Clearing NewDat & IntPnd */
- pch_can_bit_clear(&priv->regs->if1_mcont,
- CAN_IF_MCONT_INTPND);
- pch_can_check_if_busy(&priv->regs->if1_creq, k);
- } else if (k > PCH_FIFO_THRESH) {
- pch_can_int_clr(priv, k);
- } else if (k == PCH_FIFO_THRESH) {
- int cnt;
- for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++)
- pch_can_int_clr(priv, cnt+1);
- }
-RX_NEXT:
- /* Reading the messsage object from the Message RAM */
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
- pch_can_check_if_busy(&priv->regs->if1_creq, k + 1);
- reg = ioread32(&priv->regs->if1_mcont);
- }
+ pch_fifo_thresh(priv, obj_num);
+ obj_num++;
+ } while (quota > 0);
return rcv_pkts;
}
-static int pch_can_rx_poll(struct napi_struct *napi, int quota)
+
+static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat)
{
- struct net_device *ndev = napi->dev;
struct pch_can_priv *priv = netdev_priv(ndev);
struct net_device_stats *stats = &(priv->ndev->stats);
u32 dlc;
+
+ can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1);
+ iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND,
+ &priv->regs->ifregs[1].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, int_stat);
+ dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) &
+ PCH_IF_MCONT_DLC);
+ stats->tx_bytes += dlc;
+ stats->tx_packets++;
+ if (int_stat == PCH_TX_OBJ_END)
+ netif_wake_queue(ndev);
+}
+
+static int pch_can_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *ndev = napi->dev;
+ struct pch_can_priv *priv = netdev_priv(ndev);
u32 int_stat;
- int rcv_pkts = 0;
u32 reg_stat;
- unsigned long flags;
+ int quota_save = quota;
int_stat = pch_can_int_pending(priv);
if (!int_stat)
- return 0;
+ goto end;
-INT_STAT:
- if (int_stat == CAN_STATUS_INT) {
+ if (int_stat == PCH_STATUS_INT) {
reg_stat = ioread32(&priv->regs->stat);
- if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) {
- if ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)
- pch_can_error(ndev, reg_stat);
- }
- if (reg_stat & PCH_TX_OK) {
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq,
- ioread32(&priv->regs->intr));
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
- pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK);
+ if ((reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) &&
+ ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)) {
+ pch_can_error(ndev, reg_stat);
+ quota--;
}
- if (reg_stat & PCH_RX_OK)
- pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK);
+ if (reg_stat & (PCH_TX_OK | PCH_RX_OK))
+ pch_can_bit_clear(&priv->regs->stat,
+ reg_stat & (PCH_TX_OK | PCH_RX_OK));
int_stat = pch_can_int_pending(priv);
- if (int_stat == CAN_STATUS_INT)
- goto INT_STAT;
}
-MSG_OBJ:
- if ((int_stat >= 1) && (int_stat <= PCH_RX_OBJ_NUM)) {
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- rcv_pkts = pch_can_rx_normal(ndev, int_stat);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
- if (rcv_pkts < 0)
- return 0;
- } else if ((int_stat > PCH_RX_OBJ_NUM) && (int_stat <= PCH_OBJ_NUM)) {
- if (priv->msg_obj[int_stat - 1] == MSG_OBJ_TX) {
- /* Handle transmission interrupt */
- can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1);
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
- iowrite32(CAN_CMASK_RX_TX_GET | CAN_CMASK_CLRINTPND,
- &priv->regs->if2_cmask);
- dlc = ioread32(&priv->regs->if2_mcont) &
- CAN_IF_MCONT_DLC;
- pch_can_check_if_busy(&priv->regs->if2_creq, int_stat);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
- if (dlc > 8)
- dlc = 8;
- stats->tx_bytes += dlc;
- stats->tx_packets++;
- }
- }
+ if (quota == 0)
+ goto end;
- int_stat = pch_can_int_pending(priv);
- if (int_stat == CAN_STATUS_INT)
- goto INT_STAT;
- else if (int_stat >= 1 && int_stat <= 32)
- goto MSG_OBJ;
+ if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) {
+ quota -= pch_can_rx_normal(ndev, int_stat, quota);
+ } else if ((int_stat >= PCH_TX_OBJ_START) &&
+ (int_stat <= PCH_TX_OBJ_END)) {
+ /* Handle transmission interrupt */
+ pch_can_tx_complete(ndev, int_stat);
+ }
+end:
napi_complete(napi);
pch_can_set_int_enables(priv, PCH_CAN_ALL);
- return rcv_pkts;
+ return quota_save - quota;
}
static int pch_set_bittiming(struct net_device *ndev)
@@ -980,20 +787,18 @@ static int pch_set_bittiming(struct net_device *ndev)
const struct can_bittiming *bt = &priv->can.bittiming;
u32 canbit;
u32 bepe;
- u32 brp;
/* Setting the CCE bit for accessing the Can Timing register. */
- pch_can_bit_set(&priv->regs->cont, CAN_CTRL_CCE);
-
- brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1;
- canbit = brp & MSK_BITT_BRP;
- canbit |= (bt->sjw - 1) << BIT_BITT_SJW;
- canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << BIT_BITT_TSEG1;
- canbit |= (bt->phase_seg2 - 1) << BIT_BITT_TSEG2;
- bepe = (brp & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE;
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE);
+
+ canbit = (bt->brp - 1) & PCH_MSK_BITT_BRP;
+ canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT;
+ canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT;
+ canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT;
+ bepe = ((bt->brp - 1) & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT;
iowrite32(canbit, &priv->regs->bitt);
iowrite32(bepe, &priv->regs->brpe);
- pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_CCE);
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE);
return 0;
}
@@ -1008,8 +813,8 @@ static void pch_can_start(struct net_device *ndev)
pch_set_bittiming(ndev);
pch_can_set_optmode(priv);
- pch_can_tx_enable_all(priv);
- pch_can_rx_enable_all(priv);
+ pch_can_set_tx_all(priv, 1);
+ pch_can_set_rx_all(priv, 1);
/* Setting the CAN to run mode. */
pch_can_set_run_mode(priv, PCH_CAN_RUN);
@@ -1041,27 +846,18 @@ static int pch_can_open(struct net_device *ndev)
struct pch_can_priv *priv = netdev_priv(ndev);
int retval;
- retval = pci_enable_msi(priv->dev);
- if (retval) {
- dev_info(&ndev->dev, "PCH CAN opened without MSI\n");
- priv->use_msi = 0;
- } else {
- dev_info(&ndev->dev, "PCH CAN opened with MSI\n");
- priv->use_msi = 1;
- }
-
- /* Regsitering the interrupt. */
+ /* Regstering the interrupt. */
retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED,
ndev->name, ndev);
if (retval) {
- dev_err(&ndev->dev, "request_irq failed.\n");
+ netdev_err(ndev, "request_irq failed.\n");
goto req_irq_err;
}
/* Open common can device */
retval = open_candev(ndev);
if (retval) {
- dev_err(ndev->dev.parent, "open_candev() failed %d\n", retval);
+ netdev_err(ndev, "open_candev() failed %d\n", retval);
goto err_open_candev;
}
@@ -1075,9 +871,6 @@ static int pch_can_open(struct net_device *ndev)
err_open_candev:
free_irq(priv->dev->irq, ndev);
req_irq_err:
- if (priv->use_msi)
- pci_disable_msi(priv->dev);
-
pch_can_release(priv);
return retval;
@@ -1091,102 +884,65 @@ static int pch_close(struct net_device *ndev)
napi_disable(&priv->napi);
pch_can_release(priv);
free_irq(priv->dev->irq, ndev);
- if (priv->use_msi)
- pci_disable_msi(priv->dev);
close_candev(ndev);
priv->can.state = CAN_STATE_STOPPED;
return 0;
}
-static int pch_get_msg_obj_sts(struct net_device *ndev, u32 obj_id)
-{
- u32 buffer_status = 0;
- struct pch_can_priv *priv = netdev_priv(ndev);
-
- /* Getting the message object status. */
- buffer_status = (u32) pch_can_get_buffer_status(priv);
-
- return buffer_status & obj_id;
-}
-
-
static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
{
- int i, j;
- unsigned long flags;
struct pch_can_priv *priv = netdev_priv(ndev);
struct can_frame *cf = (struct can_frame *)skb->data;
- int tx_buffer_avail = 0;
+ int tx_obj_no;
+ int i;
+ u32 id2;
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
- if (priv->tx_obj == (PCH_OBJ_NUM + 1)) { /* Point tail Obj */
- while (pch_get_msg_obj_sts(ndev, (((1 << PCH_TX_OBJ_NUM)-1) <<
- PCH_RX_OBJ_NUM)))
- udelay(500);
+ tx_obj_no = priv->tx_obj;
+ if (priv->tx_obj == PCH_TX_OBJ_END) {
+ if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK)
+ netif_stop_queue(ndev);
- priv->tx_obj = PCH_RX_OBJ_NUM + 1; /* Point head of Tx Obj ID */
- tx_buffer_avail = priv->tx_obj; /* Point Tail of Tx Obj */
+ priv->tx_obj = PCH_TX_OBJ_START;
} else {
- tx_buffer_avail = priv->tx_obj;
+ priv->tx_obj++;
}
- priv->tx_obj++;
-
- /* Attaining the lock. */
- spin_lock_irqsave(&priv->msgif_reg_lock, flags);
-
- /* Reading the Msg Obj from the Msg RAM to the Interface register. */
- iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
- pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail);
/* Setting the CMASK register. */
- pch_can_bit_set(&priv->regs->if2_cmask, CAN_CMASK_ALL);
+ pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL);
/* If ID extended is set. */
- pch_can_bit_clear(&priv->regs->if2_id1, 0xffff);
- pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | CAN_ID2_XTD);
if (cf->can_id & CAN_EFF_FLAG) {
- pch_can_bit_set(&priv->regs->if2_id1, cf->can_id & 0xffff);
- pch_can_bit_set(&priv->regs->if2_id2,
- ((cf->can_id >> 16) & 0x1fff) | CAN_ID2_XTD);
+ iowrite32(cf->can_id & 0xffff, &priv->regs->ifregs[1].id1);
+ id2 = ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD;
} else {
- pch_can_bit_set(&priv->regs->if2_id1, 0);
- pch_can_bit_set(&priv->regs->if2_id2,
- (cf->can_id & CAN_SFF_MASK) << 2);
+ iowrite32(0, &priv->regs->ifregs[1].id1);
+ id2 = (cf->can_id & CAN_SFF_MASK) << 2;
}
- /* If remote frame has to be transmitted.. */
- if (cf->can_id & CAN_RTR_FLAG)
- pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID2_DIR);
+ id2 |= PCH_ID_MSGVAL;
- for (i = 0, j = 0; i < cf->can_dlc; j++) {
- iowrite32(le32_to_cpu(cf->data[i++]),
- (&priv->regs->if2_dataa1) + j*4);
- if (i == cf->can_dlc)
- break;
- iowrite32(le32_to_cpu(cf->data[i++] << 8),
- (&priv->regs->if2_dataa1) + j*4);
- }
-
- can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_NUM - 1);
+ /* If remote frame has to be transmitted.. */
+ if (!(cf->can_id & CAN_RTR_FLAG))
+ id2 |= PCH_ID2_DIR;
- /* Updating the size of the data. */
- pch_can_bit_clear(&priv->regs->if2_mcont, 0x0f);
- pch_can_bit_set(&priv->regs->if2_mcont, cf->can_dlc);
+ iowrite32(id2, &priv->regs->ifregs[1].id2);
- /* Clearing IntPend, NewDat & TxRqst */
- pch_can_bit_clear(&priv->regs->if2_mcont,
- CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND |
- CAN_IF_MCONT_TXRQXT);
+ /* Copy data to register */
+ for (i = 0; i < cf->can_dlc; i += 2) {
+ iowrite16(cf->data[i] | (cf->data[i + 1] << 8),
+ &priv->regs->ifregs[1].data[i / 2]);
+ }
- /* Setting NewDat, TxRqst bits */
- pch_can_bit_set(&priv->regs->if2_mcont,
- CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_TXRQXT);
+ can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1);
- pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail);
+ /* Set the size of the data. Update if2_mcont */
+ iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT |
+ PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont);
- spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no);
return NETDEV_TX_OK;
}
@@ -1203,21 +959,98 @@ static void __devexit pch_can_remove(struct pci_dev *pdev)
struct pch_can_priv *priv = netdev_priv(ndev);
unregister_candev(priv->ndev);
- free_candev(priv->ndev);
pci_iounmap(pdev, priv->regs);
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
pch_can_reset(priv);
+ free_candev(priv->ndev);
}
#ifdef CONFIG_PM
+static void pch_can_set_int_custom(struct pch_can_priv *priv)
+{
+ /* Clearing the IE, SIE and EIE bits of Can control register. */
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
+
+ /* Appropriately setting them. */
+ pch_can_bit_set(&priv->regs->cont,
+ ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1));
+}
+
+/* This function retrieves interrupt enabled for the CAN device. */
+static u32 pch_can_get_int_enables(struct pch_can_priv *priv)
+{
+ /* Obtaining the status of IE, SIE and EIE interrupt bits. */
+ return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1;
+}
+
+static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num,
+ enum pch_ifreg dir)
+{
+ u32 ie, enable;
+
+ if (dir)
+ ie = PCH_IF_MCONT_RXIE;
+ else
+ ie = PCH_IF_MCONT_TXIE;
+
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
+
+ if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) &&
+ ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie))
+ enable = 1;
+ else
+ enable = 0;
+
+ return enable;
+}
+
+static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
+ u32 buffer_num, int set)
+{
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ if (set)
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
+ else
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+}
+
+static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num)
+{
+ u32 link;
+
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+
+ if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB)
+ link = 0;
+ else
+ link = 1;
+ return link;
+}
+
+static int pch_can_get_buffer_status(struct pch_can_priv *priv)
+{
+ return (ioread32(&priv->regs->treq1) & 0xffff) |
+ (ioread32(&priv->regs->treq2) << 16);
+}
+
static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
{
- int i; /* Counter variable. */
- int retval; /* Return value. */
+ int i;
+ int retval;
u32 buf_stat; /* Variable for reading the transmit buffer status. */
- u32 counter = 0xFFFFFF;
+ int counter = PCH_COUNTER_LIMIT;
struct net_device *dev = pci_get_drvdata(pdev);
struct pch_can_priv *priv = netdev_priv(dev);
@@ -1226,7 +1059,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
pch_can_set_run_mode(priv, PCH_CAN_STOP);
/* Indicate that we are aboutto/in suspend */
- priv->can.state = CAN_STATE_SLEEPING;
+ priv->can.state = CAN_STATE_STOPPED;
/* Waiting for all transmission to complete. */
while (counter) {
@@ -1240,31 +1073,26 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
dev_err(&pdev->dev, "%s -> Transmission time out.\n", __func__);
/* Save interrupt configuration and then disable them */
- pch_can_get_int_enables(priv, &(priv->int_enables));
+ priv->int_enables = pch_can_get_int_enables(priv);
pch_can_set_int_enables(priv, PCH_CAN_DISABLE);
/* Save Tx buffer enable state */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_TX)
- pch_can_get_tx_enable(priv, i + 1,
- &(priv->tx_enable[i]));
- }
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ priv->tx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i,
+ PCH_TX_IFREG);
/* Disable all Transmit buffers */
- pch_can_tx_disable_all(priv);
+ pch_can_set_tx_all(priv, 0);
/* Save Rx buffer enable state */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_RX) {
- pch_can_get_rx_enable(priv, i + 1,
- &(priv->rx_enable[i]));
- pch_can_get_rx_buffer_link(priv, i + 1,
- &(priv->rx_link[i]));
- }
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ priv->rx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i,
+ PCH_RX_IFREG);
+ priv->rx_link[i - 1] = pch_can_get_rx_buffer_link(priv, i);
}
/* Disable all Receive buffers */
- pch_can_rx_disable_all(priv);
+ pch_can_set_rx_all(priv, 0);
retval = pci_save_state(pdev);
if (retval) {
dev_err(&pdev->dev, "pci_save_state failed.\n");
@@ -1279,8 +1107,8 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
static int pch_can_resume(struct pci_dev *pdev)
{
- int i; /* Counter variable. */
- int retval; /* Return variable. */
+ int i;
+ int retval;
struct net_device *dev = pci_get_drvdata(pdev);
struct pch_can_priv *priv = netdev_priv(dev);
@@ -1312,23 +1140,16 @@ static int pch_can_resume(struct pci_dev *pdev)
pch_can_set_optmode(priv);
/* Enabling the transmit buffer. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_TX) {
- pch_can_set_tx_enable(priv, i + 1,
- priv->tx_enable[i]);
- }
- }
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, priv->tx_enable[i - 1], PCH_TX_IFREG);
/* Configuring the receive buffer and enabling them. */
- for (i = 0; i < PCH_OBJ_NUM; i++) {
- if (priv->msg_obj[i] == MSG_OBJ_RX) {
- /* Restore buffer link */
- pch_can_set_rx_buffer_link(priv, i + 1,
- priv->rx_link[i]);
-
- /* Restore buffer enables */
- pch_can_set_rx_enable(priv, i + 1, priv->rx_enable[i]);
- }
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ /* Restore buffer link */
+ pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i - 1]);
+
+ /* Restore buffer enables */
+ pch_can_set_rxtx(priv, i, priv->rx_enable[i - 1], PCH_RX_IFREG);
}
/* Enable CAN Interrupts */
@@ -1348,9 +1169,10 @@ static int pch_can_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
{
struct pch_can_priv *priv = netdev_priv(dev);
+ u32 errc = ioread32(&priv->regs->errc);
- bec->txerr = ioread32(&priv->regs->errc) & CAN_TEC;
- bec->rxerr = (ioread32(&priv->regs->errc) & CAN_REC) >> 8;
+ bec->txerr = errc & PCH_TEC;
+ bec->rxerr = (errc & PCH_REC) >> 8;
return 0;
}
@@ -1361,7 +1183,6 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
struct net_device *ndev;
struct pch_can_priv *priv;
int rc;
- int index;
void __iomem *addr;
rc = pci_enable_device(pdev);
@@ -1383,7 +1204,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
goto probe_exit_ipmap;
}
- ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_NUM);
+ ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_END);
if (!ndev) {
rc = -ENOMEM;
dev_err(&pdev->dev, "Failed alloc_candev\n");
@@ -1399,7 +1220,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
priv->can.do_get_berr_counter = pch_can_get_berr_counter;
priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_LOOPBACK;
- priv->tx_obj = PCH_RX_OBJ_NUM + 1; /* Point head of Tx Obj */
+ priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj */
ndev->irq = pdev->irq;
ndev->flags |= IFF_ECHO;
@@ -1407,15 +1228,18 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->netdev_ops = &pch_can_netdev_ops;
-
priv->can.clock.freq = PCH_CAN_CLK; /* Hz */
- for (index = 0; index < PCH_RX_OBJ_NUM;)
- priv->msg_obj[index++] = MSG_OBJ_RX;
- for (index = index; index < PCH_OBJ_NUM;)
- priv->msg_obj[index++] = MSG_OBJ_TX;
+ netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END);
- netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_NUM);
+ rc = pci_enable_msi(priv->dev);
+ if (rc) {
+ netdev_err(ndev, "PCH CAN opened without MSI\n");
+ priv->use_msi = 0;
+ } else {
+ netdev_err(ndev, "PCH CAN opened with MSI\n");
+ priv->use_msi = 1;
+ }
rc = register_candev(ndev);
if (rc) {
@@ -1426,6 +1250,8 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
return 0;
probe_exit_reg_candev:
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
free_candev(ndev);
probe_exit_alloc_candev:
pci_iounmap(pdev, addr);
@@ -1458,6 +1284,6 @@ static void __exit pch_can_pci_exit(void)
}
module_exit(pch_can_pci_exit);
-MODULE_DESCRIPTION("Controller Area Network Driver");
+MODULE_DESCRIPTION("Intel EG20T PCH CAN(Controller Area Network) Driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.94");
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index 437b5c716a24..231385b8e08f 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -383,7 +383,7 @@ static void plx_pci_reset_marathon(struct pci_dev *pdev)
{
void __iomem *reset_addr;
int i;
- int reset_bar[2] = {3, 5};
+ static const int reset_bar[2] = {3, 5};
plx_pci_reset_common(pdev);
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
index 5bfccfdf3bbb..09c3e9db9316 100644
--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -107,17 +107,13 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev,
res_size = resource_size(&res);
if (!request_mem_region(res.start, res_size, DRV_NAME)) {
- dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n",
- (unsigned long long)res.start,
- (unsigned long long)res.end);
+ dev_err(&ofdev->dev, "couldn't request %pR\n", &res);
return -EBUSY;
}
base = ioremap_nocache(res.start, res_size);
if (!base) {
- dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n",
- (unsigned long long)res.start,
- (unsigned long long)res.end);
+ dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res);
err = -ENOMEM;
goto exit_release_mem;
}
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
new file mode 100644
index 000000000000..b423965a78d1
--- /dev/null
+++ b/drivers/net/can/slcan.c
@@ -0,0 +1,756 @@
+/*
+ * slcan.c - serial line CAN interface driver (using tty line discipline)
+ *
+ * This file is derived from linux/drivers/net/slip.c
+ *
+ * slip.c Authors : Laurence Culhane <loz@holmes.demon.co.uk>
+ * Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
+ * slcan.c Author : Oliver Hartkopp <socketcan@hartkopp.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. You can also get it
+ * at http://www.gnu.org/licenses/gpl.html
+ *
+ * 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.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <asm/system.h>
+#include <linux/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/can.h>
+
+static __initdata const char banner[] =
+ KERN_INFO "slcan: serial line CAN interface driver\n";
+
+MODULE_ALIAS_LDISC(N_SLCAN);
+MODULE_DESCRIPTION("serial line CAN interface");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
+
+#define SLCAN_MAGIC 0x53CA
+
+static int maxdev = 10; /* MAX number of SLCAN channels;
+ This can be overridden with
+ insmod slcan.ko maxdev=nnn */
+module_param(maxdev, int, 0);
+MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
+
+/* maximum rx buffer len: extended CAN frame with timestamp */
+#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
+
+struct slcan {
+ int magic;
+
+ /* Various fields. */
+ struct tty_struct *tty; /* ptr to TTY structure */
+ struct net_device *dev; /* easy for intr handling */
+ spinlock_t lock;
+
+ /* These are pointers to the malloc()ed frame buffers. */
+ unsigned char rbuff[SLC_MTU]; /* receiver buffer */
+ int rcount; /* received chars counter */
+ unsigned char xbuff[SLC_MTU]; /* transmitter buffer */
+ unsigned char *xhead; /* pointer to next XMIT byte */
+ int xleft; /* bytes left in XMIT queue */
+
+ unsigned long flags; /* Flag values/ mode etc */
+#define SLF_INUSE 0 /* Channel in use */
+#define SLF_ERROR 1 /* Parity, etc. error */
+
+ unsigned char leased;
+ dev_t line;
+ pid_t pid;
+};
+
+static struct net_device **slcan_devs;
+
+ /************************************************************************
+ * SLCAN ENCAPSULATION FORMAT *
+ ************************************************************************/
+
+/*
+ * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
+ * frame format) a data length code (can_dlc) which can be from 0 to 8
+ * and up to <can_dlc> data bytes as payload.
+ * Additionally a CAN frame may become a remote transmission frame if the
+ * RTR-bit is set. This causes another ECU to send a CAN frame with the
+ * given can_id.
+ *
+ * The SLCAN ASCII representation of these different frame types is:
+ * <type> <id> <dlc> <data>*
+ *
+ * Extended frames (29 bit) are defined by capital characters in the type.
+ * RTR frames are defined as 'r' types - normal frames have 't' type:
+ * t => 11 bit data frame
+ * r => 11 bit RTR frame
+ * T => 29 bit data frame
+ * R => 29 bit RTR frame
+ *
+ * The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64).
+ * The <dlc> is a one byte ASCII number ('0' - '8')
+ * The <data> section has at much ASCII Hex bytes as defined by the <dlc>
+ *
+ * Examples:
+ *
+ * t1230 : can_id 0x123, can_dlc 0, no data
+ * t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
+ * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
+ * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request
+ *
+ */
+
+ /************************************************************************
+ * STANDARD SLCAN DECAPSULATION *
+ ************************************************************************/
+
+static int asc2nibble(char c)
+{
+
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+
+ if ((c >= 'A') && (c <= 'F'))
+ return c - 'A' + 10;
+
+ if ((c >= 'a') && (c <= 'f'))
+ return c - 'a' + 10;
+
+ return 16; /* error */
+}
+
+/* Send one completely decapsulated can_frame to the network layer */
+static void slc_bump(struct slcan *sl)
+{
+ struct sk_buff *skb;
+ struct can_frame cf;
+ int i, dlc_pos, tmp;
+ unsigned long ultmp;
+ char cmd = sl->rbuff[0];
+
+ if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R'))
+ return;
+
+ if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */
+ dlc_pos = 4; /* dlc position tiiid */
+ else
+ dlc_pos = 9; /* dlc position Tiiiiiiiid */
+
+ if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9')))
+ return;
+
+ cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */
+
+ sl->rbuff[dlc_pos] = 0; /* terminate can_id string */
+
+ if (strict_strtoul(sl->rbuff+1, 16, &ultmp))
+ return;
+
+ cf.can_id = ultmp;
+
+ if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */
+ cf.can_id |= CAN_EFF_FLAG;
+
+ if ((cmd | 0x20) == 'r') /* RTR frame */
+ cf.can_id |= CAN_RTR_FLAG;
+
+ *(u64 *) (&cf.data) = 0; /* clear payload */
+
+ for (i = 0, dlc_pos++; i < cf.can_dlc; i++) {
+
+ tmp = asc2nibble(sl->rbuff[dlc_pos++]);
+ if (tmp > 0x0F)
+ return;
+ cf.data[i] = (tmp << 4);
+ tmp = asc2nibble(sl->rbuff[dlc_pos++]);
+ if (tmp > 0x0F)
+ return;
+ cf.data[i] |= tmp;
+ }
+
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (!skb)
+ return;
+
+ skb->dev = sl->dev;
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ memcpy(skb_put(skb, sizeof(struct can_frame)),
+ &cf, sizeof(struct can_frame));
+ netif_rx(skb);
+
+ sl->dev->stats.rx_packets++;
+ sl->dev->stats.rx_bytes += cf.can_dlc;
+}
+
+/* parse tty input stream */
+static void slcan_unesc(struct slcan *sl, unsigned char s)
+{
+
+ if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+ (sl->rcount > 4)) {
+ slc_bump(sl);
+ }
+ sl->rcount = 0;
+ } else {
+ if (!test_bit(SLF_ERROR, &sl->flags)) {
+ if (sl->rcount < SLC_MTU) {
+ sl->rbuff[sl->rcount++] = s;
+ return;
+ } else {
+ sl->dev->stats.rx_over_errors++;
+ set_bit(SLF_ERROR, &sl->flags);
+ }
+ }
+ }
+}
+
+ /************************************************************************
+ * STANDARD SLCAN ENCAPSULATION *
+ ************************************************************************/
+
+/* Encapsulate one can_frame and stuff into a TTY queue. */
+static void slc_encaps(struct slcan *sl, struct can_frame *cf)
+{
+ int actual, idx, i;
+ char cmd;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ cmd = 'R'; /* becomes 'r' in standard frame format */
+ else
+ cmd = 'T'; /* becomes 't' in standard frame format */
+
+ if (cf->can_id & CAN_EFF_FLAG)
+ sprintf(sl->xbuff, "%c%08X%d", cmd,
+ cf->can_id & CAN_EFF_MASK, cf->can_dlc);
+ else
+ sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20,
+ cf->can_id & CAN_SFF_MASK, cf->can_dlc);
+
+ idx = strlen(sl->xbuff);
+
+ for (i = 0; i < cf->can_dlc; i++)
+ sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]);
+
+ strcat(sl->xbuff, "\r"); /* add terminating character */
+
+ /* Order of next two lines is *very* important.
+ * When we are sending a little amount of data,
+ * the transfer may be completed inside the ops->write()
+ * routine, because it's running with interrupts enabled.
+ * In this case we *never* got WRITE_WAKEUP event,
+ * if we did not request it before write operation.
+ * 14 Oct 1994 Dmitry Gorodchanin.
+ */
+ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff));
+ sl->xleft = strlen(sl->xbuff) - actual;
+ sl->xhead = sl->xbuff + actual;
+ sl->dev->stats.tx_bytes += cf->can_dlc;
+}
+
+/*
+ * Called by the driver when there's room for more data. If we have
+ * more packets to send, we send them here.
+ */
+static void slcan_write_wakeup(struct tty_struct *tty)
+{
+ int actual;
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+
+ /* First make sure we're connected. */
+ if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+ return;
+
+ if (sl->xleft <= 0) {
+ /* Now serial buffer is almost free & we can start
+ * transmission of another packet */
+ sl->dev->stats.tx_packets++;
+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ netif_wake_queue(sl->dev);
+ return;
+ }
+
+ actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+ sl->xleft -= actual;
+ sl->xhead += actual;
+}
+
+/* Send a can_frame to a TTY queue. */
+static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ if (skb->len != sizeof(struct can_frame))
+ goto out;
+
+ spin_lock(&sl->lock);
+ if (!netif_running(dev)) {
+ spin_unlock(&sl->lock);
+ printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
+ goto out;
+ }
+ if (sl->tty == NULL) {
+ spin_unlock(&sl->lock);
+ goto out;
+ }
+
+ netif_stop_queue(sl->dev);
+ slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
+ spin_unlock(&sl->lock);
+
+out:
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+
+/******************************************
+ * Routines looking at netdevice side.
+ ******************************************/
+
+/* Netdevice UP -> DOWN routine */
+static int slc_close(struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ spin_lock_bh(&sl->lock);
+ if (sl->tty) {
+ /* TTY discipline is running. */
+ clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ }
+ netif_stop_queue(dev);
+ sl->rcount = 0;
+ sl->xleft = 0;
+ spin_unlock_bh(&sl->lock);
+
+ return 0;
+}
+
+/* Netdevice DOWN -> UP routine */
+static int slc_open(struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ if (sl->tty == NULL)
+ return -ENODEV;
+
+ sl->flags &= (1 << SLF_INUSE);
+ netif_start_queue(dev);
+ return 0;
+}
+
+/* Hook the destructor so we can free slcan devs at the right point in time */
+static void slc_free_netdev(struct net_device *dev)
+{
+ int i = dev->base_addr;
+ free_netdev(dev);
+ slcan_devs[i] = NULL;
+}
+
+static const struct net_device_ops slc_netdev_ops = {
+ .ndo_open = slc_open,
+ .ndo_stop = slc_close,
+ .ndo_start_xmit = slc_xmit,
+};
+
+static void slc_setup(struct net_device *dev)
+{
+ dev->netdev_ops = &slc_netdev_ops;
+ dev->destructor = slc_free_netdev;
+
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->tx_queue_len = 10;
+
+ dev->mtu = sizeof(struct can_frame);
+ dev->type = ARPHRD_CAN;
+
+ /* New-style flags. */
+ dev->flags = IFF_NOARP;
+ dev->features = NETIF_F_NO_CSUM;
+}
+
+/******************************************
+ Routines looking at TTY side.
+ ******************************************/
+
+/*
+ * Handle the 'receiver data ready' interrupt.
+ * This function is called by the 'tty_io' module in the kernel when
+ * a block of SLCAN data has been received, which can now be decapsulated
+ * and sent on to some IP layer for further processing. This will not
+ * be re-entered while running but other ldisc functions may be called
+ * in parallel
+ */
+
+static void slcan_receive_buf(struct tty_struct *tty,
+ const unsigned char *cp, char *fp, int count)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+
+ if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+ return;
+
+ /* Read the characters out of the buffer */
+ while (count--) {
+ if (fp && *fp++) {
+ if (!test_and_set_bit(SLF_ERROR, &sl->flags))
+ sl->dev->stats.rx_errors++;
+ cp++;
+ continue;
+ }
+ slcan_unesc(sl, *cp++);
+ }
+}
+
+/************************************
+ * slcan_open helper routines.
+ ************************************/
+
+/* Collect hanged up channels */
+static void slc_sync(void)
+{
+ int i;
+ struct net_device *dev;
+ struct slcan *sl;
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (dev == NULL)
+ break;
+
+ sl = netdev_priv(dev);
+ if (sl->tty || sl->leased)
+ continue;
+ if (dev->flags & IFF_UP)
+ dev_close(dev);
+ }
+}
+
+/* Find a free SLCAN channel, and link in this `tty' line. */
+static struct slcan *slc_alloc(dev_t line)
+{
+ int i;
+ struct net_device *dev = NULL;
+ struct slcan *sl;
+
+ if (slcan_devs == NULL)
+ return NULL; /* Master array missing ! */
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (dev == NULL)
+ break;
+
+ }
+
+ /* Sorry, too many, all slots in use */
+ if (i >= maxdev)
+ return NULL;
+
+ if (dev) {
+ sl = netdev_priv(dev);
+ if (test_bit(SLF_INUSE, &sl->flags)) {
+ unregister_netdevice(dev);
+ dev = NULL;
+ slcan_devs[i] = NULL;
+ }
+ }
+
+ if (!dev) {
+ char name[IFNAMSIZ];
+ sprintf(name, "slcan%d", i);
+
+ dev = alloc_netdev(sizeof(*sl), name, slc_setup);
+ if (!dev)
+ return NULL;
+ dev->base_addr = i;
+ }
+
+ sl = netdev_priv(dev);
+
+ /* Initialize channel control data */
+ sl->magic = SLCAN_MAGIC;
+ sl->dev = dev;
+ spin_lock_init(&sl->lock);
+ slcan_devs[i] = dev;
+
+ return sl;
+}
+
+/*
+ * Open the high-level part of the SLCAN channel.
+ * This function is called by the TTY module when the
+ * SLCAN line discipline is called for. Because we are
+ * sure the tty line exists, we only have to link it to
+ * a free SLCAN channel...
+ *
+ * Called in process context serialized from other ldisc calls.
+ */
+
+static int slcan_open(struct tty_struct *tty)
+{
+ struct slcan *sl;
+ int err;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
+ /* RTnetlink lock is misused here to serialize concurrent
+ opens of slcan channels. There are better ways, but it is
+ the simplest one.
+ */
+ rtnl_lock();
+
+ /* Collect hanged up channels. */
+ slc_sync();
+
+ sl = tty->disc_data;
+
+ err = -EEXIST;
+ /* First make sure we're not already connected. */
+ if (sl && sl->magic == SLCAN_MAGIC)
+ goto err_exit;
+
+ /* OK. Find a free SLCAN channel to use. */
+ err = -ENFILE;
+ sl = slc_alloc(tty_devnum(tty));
+ if (sl == NULL)
+ goto err_exit;
+
+ sl->tty = tty;
+ tty->disc_data = sl;
+ sl->line = tty_devnum(tty);
+ sl->pid = current->pid;
+
+ if (!test_bit(SLF_INUSE, &sl->flags)) {
+ /* Perform the low-level SLCAN initialization. */
+ sl->rcount = 0;
+ sl->xleft = 0;
+
+ set_bit(SLF_INUSE, &sl->flags);
+
+ err = register_netdevice(sl->dev);
+ if (err)
+ goto err_free_chan;
+ }
+
+ /* Done. We have linked the TTY line to a channel. */
+ rtnl_unlock();
+ tty->receive_room = 65536; /* We don't flow control */
+ return sl->dev->base_addr;
+
+err_free_chan:
+ sl->tty = NULL;
+ tty->disc_data = NULL;
+ clear_bit(SLF_INUSE, &sl->flags);
+
+err_exit:
+ rtnl_unlock();
+
+ /* Count references from TTY module */
+ return err;
+}
+
+/*
+ * Close down a SLCAN channel.
+ * This means flushing out any pending queues, and then returning. This
+ * call is serialized against other ldisc functions.
+ *
+ * We also use this method for a hangup event.
+ */
+
+static void slcan_close(struct tty_struct *tty)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+
+ /* First make sure we're connected. */
+ if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
+ return;
+
+ tty->disc_data = NULL;
+ sl->tty = NULL;
+ if (!sl->leased)
+ sl->line = 0;
+
+ /* Flush network side */
+ unregister_netdev(sl->dev);
+ /* This will complete via sl_free_netdev */
+}
+
+static int slcan_hangup(struct tty_struct *tty)
+{
+ slcan_close(tty);
+ return 0;
+}
+
+/* Perform I/O control on an active SLCAN channel. */
+static int slcan_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+ unsigned int tmp;
+
+ /* First make sure we're connected. */
+ if (!sl || sl->magic != SLCAN_MAGIC)
+ return -EINVAL;
+
+ switch (cmd) {
+ case SIOCGIFNAME:
+ tmp = strlen(sl->dev->name) + 1;
+ if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
+ return -EFAULT;
+ return 0;
+
+ case SIOCSIFHWADDR:
+ return -EINVAL;
+
+ default:
+ return tty_mode_ioctl(tty, file, cmd, arg);
+ }
+}
+
+static struct tty_ldisc_ops slc_ldisc = {
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "slcan",
+ .open = slcan_open,
+ .close = slcan_close,
+ .hangup = slcan_hangup,
+ .ioctl = slcan_ioctl,
+ .receive_buf = slcan_receive_buf,
+ .write_wakeup = slcan_write_wakeup,
+};
+
+static int __init slcan_init(void)
+{
+ int status;
+
+ if (maxdev < 4)
+ maxdev = 4; /* Sanity */
+
+ printk(banner);
+ printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
+
+ slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
+ if (!slcan_devs) {
+ printk(KERN_ERR "slcan: can't allocate slcan device array!\n");
+ return -ENOMEM;
+ }
+
+ /* Fill in our line protocol discipline, and register it */
+ status = tty_register_ldisc(N_SLCAN, &slc_ldisc);
+ if (status) {
+ printk(KERN_ERR "slcan: can't register line discipline\n");
+ kfree(slcan_devs);
+ }
+ return status;
+}
+
+static void __exit slcan_exit(void)
+{
+ int i;
+ struct net_device *dev;
+ struct slcan *sl;
+ unsigned long timeout = jiffies + HZ;
+ int busy = 0;
+
+ if (slcan_devs == NULL)
+ return;
+
+ /* First of all: check for active disciplines and hangup them.
+ */
+ do {
+ if (busy)
+ msleep_interruptible(100);
+
+ busy = 0;
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (!dev)
+ continue;
+ sl = netdev_priv(dev);
+ spin_lock_bh(&sl->lock);
+ if (sl->tty) {
+ busy++;
+ tty_hangup(sl->tty);
+ }
+ spin_unlock_bh(&sl->lock);
+ }
+ } while (busy && time_before(jiffies, timeout));
+
+ /* FIXME: hangup is async so we should wait when doing this second
+ phase */
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (!dev)
+ continue;
+ slcan_devs[i] = NULL;
+
+ sl = netdev_priv(dev);
+ if (sl->tty) {
+ printk(KERN_ERR "%s: tty discipline still running\n",
+ dev->name);
+ /* Intentionally leak the control block. */
+ dev->destructor = NULL;
+ }
+
+ unregister_netdev(dev);
+ }
+
+ kfree(slcan_devs);
+ slcan_devs = NULL;
+
+ i = tty_unregister_ldisc(N_SLCAN);
+ if (i)
+ printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i);
+}
+
+module_init(slcan_init);
+module_exit(slcan_exit);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index d6b6d6aa565a..73502fef8769 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2788,7 +2788,7 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring,
ctrl = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- const u64 csum_start_off = skb_transport_offset(skb);
+ const u64 csum_start_off = skb_checksum_start_offset(skb);
const u64 csum_stuff_off = csum_start_off + skb->csum_offset;
ctrl = TX_DESC_CSUM_EN |
@@ -3880,7 +3880,7 @@ static int cas_change_mtu(struct net_device *dev, int new_mtu)
schedule_work(&cp->reset_task);
#endif
- flush_scheduled_work();
+ flush_work_sync(&cp->reset_task);
return 0;
}
@@ -5177,7 +5177,7 @@ static void __devexit cas_remove_one(struct pci_dev *pdev)
vfree(cp->fw_data);
mutex_lock(&cp->pm_mutex);
- flush_scheduled_work();
+ cancel_work_sync(&cp->reset_task);
if (cp->hw_running)
cas_shutdown(cp);
mutex_unlock(&cp->pm_mutex);
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 70221ca32683..f778b15ad3fd 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -273,6 +273,10 @@ struct sge {
struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp;
};
+static const u8 ch_mac_addr[ETH_ALEN] = {
+ 0x0, 0x7, 0x43, 0x0, 0x0, 0x0
+};
+
/*
* stop tasklet and free all pending skb's
*/
@@ -2012,10 +2016,6 @@ static void espibug_workaround_t204(unsigned long data)
continue;
if (!skb->cb[0]) {
- u8 ch_mac_addr[ETH_ALEN] = {
- 0x0, 0x7, 0x43, 0x0, 0x0, 0x0
- };
-
skb_copy_to_linear_data_offset(skb,
sizeof(struct cpl_tx_pkt),
ch_mac_addr,
@@ -2048,8 +2048,6 @@ static void espibug_workaround(unsigned long data)
if ((seop & 0xfff0fff) == 0xfff && skb) {
if (!skb->cb[0]) {
- u8 ch_mac_addr[ETH_ALEN] =
- {0x0, 0x7, 0x43, 0x0, 0x0, 0x0};
skb_copy_to_linear_data_offset(skb,
sizeof(struct cpl_tx_pkt),
ch_mac_addr,
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 92bac19ad60a..aa5016ad9e19 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -59,6 +59,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II CNIC Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(CNIC_MODULE_VERSION);
+/* cnic_dev_list modifications are protected by both rtnl and cnic_dev_lock */
static LIST_HEAD(cnic_dev_list);
static LIST_HEAD(cnic_udev_list);
static DEFINE_RWLOCK(cnic_dev_lock);
@@ -278,6 +279,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type,
u32 msg_type = ISCSI_KEVENT_IF_DOWN;
struct cnic_ulp_ops *ulp_ops;
struct cnic_uio_dev *udev = cp->udev;
+ int rc = 0, retry = 0;
if (!udev || udev->uio_dev == -1)
return -ENODEV;
@@ -302,14 +304,26 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type,
path_req.pmtu = csk->mtu;
}
- rcu_read_lock();
- ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]);
- if (ulp_ops)
- ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len);
- rcu_read_unlock();
+ while (retry < 3) {
+ rc = 0;
+ rcu_read_lock();
+ ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]);
+ if (ulp_ops)
+ rc = ulp_ops->iscsi_nl_send_msg(
+ cp->ulp_handle[CNIC_ULP_ISCSI],
+ msg_type, buf, len);
+ rcu_read_unlock();
+ if (rc == 0 || msg_type != ISCSI_KEVENT_PATH_REQ)
+ break;
+
+ msleep(100);
+ retry++;
+ }
return 0;
}
+static void cnic_cm_upcall(struct cnic_local *, struct cnic_sock *, u8);
+
static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
char *buf, u16 len)
{
@@ -339,7 +353,9 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
}
csk = &cp->csk_tbl[l5_cid];
csk_hold(csk);
- if (cnic_in_use(csk)) {
+ if (cnic_in_use(csk) &&
+ test_bit(SK_F_CONNECT_START, &csk->flags)) {
+
memcpy(csk->ha, path_resp->mac_addr, 6);
if (test_bit(SK_F_IPV6, &csk->flags))
memcpy(&csk->src_ip[0], &path_resp->src.v6_addr,
@@ -347,8 +363,16 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
else
memcpy(&csk->src_ip[0], &path_resp->src.v4_addr,
sizeof(struct in_addr));
- if (is_valid_ether_addr(csk->ha))
+
+ if (is_valid_ether_addr(csk->ha)) {
cnic_cm_set_pg(csk);
+ } else if (!test_bit(SK_F_OFFLD_SCHED, &csk->flags) &&
+ !test_bit(SK_F_OFFLD_COMPLETE, &csk->flags)) {
+
+ cnic_cm_upcall(cp, csk,
+ L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE);
+ clear_bit(SK_F_CONNECT_START, &csk->flags);
+ }
}
csk_put(csk);
rcu_read_unlock();
@@ -402,19 +426,6 @@ static int cnic_abort_prep(struct cnic_sock *csk)
return 0;
}
-static void cnic_uio_stop(void)
-{
- struct cnic_dev *dev;
-
- read_lock(&cnic_dev_lock);
- list_for_each_entry(dev, &cnic_dev_list, list) {
- struct cnic_local *cp = dev->cnic_priv;
-
- cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
- }
- read_unlock(&cnic_dev_lock);
-}
-
int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
{
struct cnic_dev *dev;
@@ -445,14 +456,12 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
/* Prevent race conditions with netdev_event */
rtnl_lock();
- read_lock(&cnic_dev_lock);
list_for_each_entry(dev, &cnic_dev_list, list) {
struct cnic_local *cp = dev->cnic_priv;
if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[ulp_type]))
ulp_ops->cnic_init(dev);
}
- read_unlock(&cnic_dev_lock);
rtnl_unlock();
return 0;
@@ -488,9 +497,6 @@ int cnic_unregister_driver(int ulp_type)
}
read_unlock(&cnic_dev_lock);
- if (ulp_type == CNIC_ULP_ISCSI)
- cnic_uio_stop();
-
rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL);
mutex_unlock(&cnic_lock);
@@ -574,6 +580,9 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
}
mutex_unlock(&cnic_lock);
+ if (ulp_type == CNIC_ULP_ISCSI)
+ cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+
synchronize_rcu();
while (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]) &&
@@ -821,12 +830,14 @@ static void cnic_free_resc(struct cnic_dev *dev)
cnic_free_dma(dev, &cp->conn_buf_info);
cnic_free_dma(dev, &cp->kwq_info);
cnic_free_dma(dev, &cp->kwq_16_data_info);
+ cnic_free_dma(dev, &cp->kcq2.dma);
cnic_free_dma(dev, &cp->kcq1.dma);
kfree(cp->iscsi_tbl);
cp->iscsi_tbl = NULL;
kfree(cp->ctx_tbl);
cp->ctx_tbl = NULL;
+ cnic_free_id_tbl(&cp->fcoe_cid_tbl);
cnic_free_id_tbl(&cp->cid_tbl);
}
@@ -940,7 +951,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
&udev->l2_ring_map,
GFP_KERNEL | __GFP_COMP);
if (!udev->l2_ring)
- return -ENOMEM;
+ goto err_udev;
udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
@@ -948,7 +959,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
&udev->l2_buf_map,
GFP_KERNEL | __GFP_COMP);
if (!udev->l2_buf)
- return -ENOMEM;
+ goto err_dma;
write_lock(&cnic_dev_lock);
list_add(&udev->list, &cnic_udev_list);
@@ -959,6 +970,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
cp->udev = udev;
return 0;
+ err_dma:
+ dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
+ udev->l2_ring, udev->l2_ring_map);
+ err_udev:
+ kfree(udev);
+ return -ENOMEM;
}
static int cnic_init_uio(struct cnic_dev *dev)
@@ -1114,12 +1131,22 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->iro_arr = ethdev->iro_arr;
- cp->max_cid_space = MAX_ISCSI_TBL_SZ;
+ cp->max_cid_space = MAX_ISCSI_TBL_SZ + BNX2X_FCOE_NUM_CONNECTIONS;
cp->iscsi_start_cid = start_cid;
+ cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ;
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ cp->max_cid_space += BNX2X_FCOE_NUM_CONNECTIONS;
+ cp->fcoe_init_cid = ethdev->fcoe_init_cid;
+ if (!cp->fcoe_init_cid)
+ cp->fcoe_init_cid = 0x10;
+ }
+
if (start_cid < BNX2X_ISCSI_START_CID) {
u32 delta = BNX2X_ISCSI_START_CID - start_cid;
cp->iscsi_start_cid = BNX2X_ISCSI_START_CID;
+ cp->fcoe_start_cid += delta;
cp->max_cid_space += delta;
}
@@ -1138,6 +1165,9 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_ISCSI;
}
+ for (i = MAX_ISCSI_TBL_SZ; i < cp->max_cid_space; i++)
+ cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_FCOE;
+
pages = PAGE_ALIGN(cp->max_cid_space * CNIC_KWQ16_DATA_SIZE) /
PAGE_SIZE;
@@ -1161,6 +1191,12 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
if (ret)
goto error;
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ ret = cnic_alloc_kcq(dev, &cp->kcq2);
+ if (ret)
+ goto error;
+ }
+
pages = PAGE_ALIGN(BNX2X_ISCSI_NUM_CONNECTIONS *
BNX2X_ISCSI_CONN_BUF_SIZE) / PAGE_SIZE;
ret = cnic_alloc_dma(dev, &cp->conn_buf_info, pages, 1);
@@ -1425,8 +1461,11 @@ static void cnic_free_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid)
cnic_free_dma(dev, &iscsi->hq_info);
cnic_free_dma(dev, &iscsi->r2tq_info);
cnic_free_dma(dev, &iscsi->task_array_info);
+ cnic_free_id(&cp->cid_tbl, ctx->cid);
+ } else {
+ cnic_free_id(&cp->fcoe_cid_tbl, ctx->cid);
}
- cnic_free_id(&cp->cid_tbl, ctx->cid);
+
ctx->cid = 0;
}
@@ -1438,6 +1477,16 @@ static int cnic_alloc_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid)
struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
struct cnic_iscsi *iscsi = ctx->proto.iscsi;
+ if (ctx->ulp_proto_id == CNIC_ULP_FCOE) {
+ cid = cnic_alloc_new_id(&cp->fcoe_cid_tbl);
+ if (cid == -1) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ ctx->cid = cid;
+ return 0;
+ }
+
cid = cnic_alloc_new_id(&cp->cid_tbl);
if (cid == -1) {
ret = -ENOMEM;
@@ -1695,7 +1744,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
*work = num;
return -EINVAL;
}
- *work = 2 + req2->num_additional_wqes;;
+ *work = 2 + req2->num_additional_wqes;
l5_cid = req1->iscsi_conn_id;
if (l5_cid >= MAX_ISCSI_TBL_SZ)
@@ -2078,8 +2127,307 @@ static int cnic_bnx2x_update_pg(struct cnic_dev *dev, struct kwqe *kwqe)
return 0;
}
-static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
- u32 num_wqes)
+static int cnic_bnx2x_fcoe_stat(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+ struct fcoe_kwqe_stat *req;
+ struct fcoe_stat_ramrod_params *fcoe_stat;
+ union l5cm_specific_data l5_data;
+ struct cnic_local *cp = dev->cnic_priv;
+ int ret;
+ u32 cid;
+
+ req = (struct fcoe_kwqe_stat *) kwqe;
+ cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid);
+
+ fcoe_stat = cnic_get_kwqe_16_data(cp, BNX2X_FCOE_L5_CID_BASE, &l5_data);
+ if (!fcoe_stat)
+ return -ENOMEM;
+
+ memset(fcoe_stat, 0, sizeof(*fcoe_stat));
+ memcpy(&fcoe_stat->stat_kwqe, req, sizeof(*req));
+
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_STAT, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_init1(struct cnic_dev *dev, struct kwqe *wqes[],
+ u32 num, int *work)
+{
+ int ret;
+ struct cnic_local *cp = dev->cnic_priv;
+ u32 cid;
+ struct fcoe_init_ramrod_params *fcoe_init;
+ struct fcoe_kwqe_init1 *req1;
+ struct fcoe_kwqe_init2 *req2;
+ struct fcoe_kwqe_init3 *req3;
+ union l5cm_specific_data l5_data;
+
+ if (num < 3) {
+ *work = num;
+ return -EINVAL;
+ }
+ req1 = (struct fcoe_kwqe_init1 *) wqes[0];
+ req2 = (struct fcoe_kwqe_init2 *) wqes[1];
+ req3 = (struct fcoe_kwqe_init3 *) wqes[2];
+ if (req2->hdr.op_code != FCOE_KWQE_OPCODE_INIT2) {
+ *work = 1;
+ return -EINVAL;
+ }
+ if (req3->hdr.op_code != FCOE_KWQE_OPCODE_INIT3) {
+ *work = 2;
+ return -EINVAL;
+ }
+
+ if (sizeof(*fcoe_init) > CNIC_KWQ16_DATA_SIZE) {
+ netdev_err(dev->netdev, "fcoe_init size too big\n");
+ return -ENOMEM;
+ }
+ fcoe_init = cnic_get_kwqe_16_data(cp, BNX2X_FCOE_L5_CID_BASE, &l5_data);
+ if (!fcoe_init)
+ return -ENOMEM;
+
+ memset(fcoe_init, 0, sizeof(*fcoe_init));
+ memcpy(&fcoe_init->init_kwqe1, req1, sizeof(*req1));
+ memcpy(&fcoe_init->init_kwqe2, req2, sizeof(*req2));
+ memcpy(&fcoe_init->init_kwqe3, req3, sizeof(*req3));
+ fcoe_init->eq_addr.lo = cp->kcq2.dma.pg_map_arr[0] & 0xffffffff;
+ fcoe_init->eq_addr.hi = (u64) cp->kcq2.dma.pg_map_arr[0] >> 32;
+ fcoe_init->eq_next_page_addr.lo =
+ cp->kcq2.dma.pg_map_arr[1] & 0xffffffff;
+ fcoe_init->eq_next_page_addr.hi =
+ (u64) cp->kcq2.dma.pg_map_arr[1] >> 32;
+
+ fcoe_init->sb_num = cp->status_blk_num;
+ fcoe_init->eq_prod = MAX_KCQ_IDX;
+ fcoe_init->sb_id = HC_INDEX_FCOE_EQ_CONS;
+ cp->kcq2.sw_prod_idx = 0;
+
+ cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid);
+ printk(KERN_ERR "bdbg: submitting INIT RAMROD \n");
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_INIT, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ *work = 3;
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
+ u32 num, int *work)
+{
+ int ret = 0;
+ u32 cid = -1, l5_cid;
+ struct cnic_local *cp = dev->cnic_priv;
+ struct fcoe_kwqe_conn_offload1 *req1;
+ struct fcoe_kwqe_conn_offload2 *req2;
+ struct fcoe_kwqe_conn_offload3 *req3;
+ struct fcoe_kwqe_conn_offload4 *req4;
+ struct fcoe_conn_offload_ramrod_params *fcoe_offload;
+ struct cnic_context *ctx;
+ struct fcoe_context *fctx;
+ struct regpair ctx_addr;
+ union l5cm_specific_data l5_data;
+ struct fcoe_kcqe kcqe;
+ struct kcqe *cqes[1];
+
+ if (num < 4) {
+ *work = num;
+ return -EINVAL;
+ }
+ req1 = (struct fcoe_kwqe_conn_offload1 *) wqes[0];
+ req2 = (struct fcoe_kwqe_conn_offload2 *) wqes[1];
+ req3 = (struct fcoe_kwqe_conn_offload3 *) wqes[2];
+ req4 = (struct fcoe_kwqe_conn_offload4 *) wqes[3];
+
+ *work = 4;
+
+ l5_cid = req1->fcoe_conn_id;
+ if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS)
+ goto err_reply;
+
+ l5_cid += BNX2X_FCOE_L5_CID_BASE;
+
+ ctx = &cp->ctx_tbl[l5_cid];
+ if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
+ goto err_reply;
+
+ ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid);
+ if (ret) {
+ ret = 0;
+ goto err_reply;
+ }
+ cid = ctx->cid;
+
+ fctx = cnic_get_bnx2x_ctx(dev, cid, 1, &ctx_addr);
+ if (fctx) {
+ u32 hw_cid = BNX2X_HW_CID(cp, cid);
+ u32 val;
+
+ val = CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_XCM_AG,
+ FCOE_CONNECTION_TYPE);
+ fctx->xstorm_ag_context.cdu_reserved = val;
+ val = CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_UCM_AG,
+ FCOE_CONNECTION_TYPE);
+ fctx->ustorm_ag_context.cdu_usage = val;
+ }
+ if (sizeof(*fcoe_offload) > CNIC_KWQ16_DATA_SIZE) {
+ netdev_err(dev->netdev, "fcoe_offload size too big\n");
+ goto err_reply;
+ }
+ fcoe_offload = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
+ if (!fcoe_offload)
+ goto err_reply;
+
+ memset(fcoe_offload, 0, sizeof(*fcoe_offload));
+ memcpy(&fcoe_offload->offload_kwqe1, req1, sizeof(*req1));
+ memcpy(&fcoe_offload->offload_kwqe2, req2, sizeof(*req2));
+ memcpy(&fcoe_offload->offload_kwqe3, req3, sizeof(*req3));
+ memcpy(&fcoe_offload->offload_kwqe4, req4, sizeof(*req4));
+
+ cid = BNX2X_HW_CID(cp, cid);
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ if (!ret)
+ set_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
+
+ return ret;
+
+err_reply:
+ if (cid != -1)
+ cnic_free_bnx2x_conn_resc(dev, l5_cid);
+
+ memset(&kcqe, 0, sizeof(kcqe));
+ kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN;
+ kcqe.fcoe_conn_id = req1->fcoe_conn_id;
+ kcqe.completion_status = FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE;
+
+ cqes[0] = (struct kcqe *) &kcqe;
+ cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_FCOE, cqes, 1);
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_enable(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+ struct fcoe_kwqe_conn_enable_disable *req;
+ struct fcoe_conn_enable_disable_ramrod_params *fcoe_enable;
+ union l5cm_specific_data l5_data;
+ int ret;
+ u32 cid, l5_cid;
+ struct cnic_local *cp = dev->cnic_priv;
+
+ req = (struct fcoe_kwqe_conn_enable_disable *) kwqe;
+ cid = req->context_id;
+ l5_cid = req->conn_id + BNX2X_FCOE_L5_CID_BASE;
+
+ if (sizeof(*fcoe_enable) > CNIC_KWQ16_DATA_SIZE) {
+ netdev_err(dev->netdev, "fcoe_enable size too big\n");
+ return -ENOMEM;
+ }
+ fcoe_enable = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
+ if (!fcoe_enable)
+ return -ENOMEM;
+
+ memset(fcoe_enable, 0, sizeof(*fcoe_enable));
+ memcpy(&fcoe_enable->enable_disable_kwqe, req, sizeof(*req));
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_ENABLE_CONN, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_disable(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+ struct fcoe_kwqe_conn_enable_disable *req;
+ struct fcoe_conn_enable_disable_ramrod_params *fcoe_disable;
+ union l5cm_specific_data l5_data;
+ int ret;
+ u32 cid, l5_cid;
+ struct cnic_local *cp = dev->cnic_priv;
+
+ req = (struct fcoe_kwqe_conn_enable_disable *) kwqe;
+ cid = req->context_id;
+ l5_cid = req->conn_id;
+ if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS)
+ return -EINVAL;
+
+ l5_cid += BNX2X_FCOE_L5_CID_BASE;
+
+ if (sizeof(*fcoe_disable) > CNIC_KWQ16_DATA_SIZE) {
+ netdev_err(dev->netdev, "fcoe_disable size too big\n");
+ return -ENOMEM;
+ }
+ fcoe_disable = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
+ if (!fcoe_disable)
+ return -ENOMEM;
+
+ memset(fcoe_disable, 0, sizeof(*fcoe_disable));
+ memcpy(&fcoe_disable->enable_disable_kwqe, req, sizeof(*req));
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DISABLE_CONN, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+ struct fcoe_kwqe_conn_destroy *req;
+ union l5cm_specific_data l5_data;
+ int ret;
+ u32 cid, l5_cid;
+ struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_context *ctx;
+ struct fcoe_kcqe kcqe;
+ struct kcqe *cqes[1];
+
+ req = (struct fcoe_kwqe_conn_destroy *) kwqe;
+ cid = req->context_id;
+ l5_cid = req->conn_id;
+ if (l5_cid >= BNX2X_FCOE_NUM_CONNECTIONS)
+ return -EINVAL;
+
+ l5_cid += BNX2X_FCOE_L5_CID_BASE;
+
+ ctx = &cp->ctx_tbl[l5_cid];
+
+ init_waitqueue_head(&ctx->waitq);
+ ctx->wait_cond = 0;
+
+ memset(&l5_data, 0, sizeof(l5_data));
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_TERMINATE_CONN, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ if (ret == 0) {
+ wait_event(ctx->waitq, ctx->wait_cond);
+ set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags);
+ queue_delayed_work(cnic_wq, &cp->delete_task,
+ msecs_to_jiffies(2000));
+ }
+
+ memset(&kcqe, 0, sizeof(kcqe));
+ kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_CONN;
+ kcqe.fcoe_conn_id = req->conn_id;
+ kcqe.fcoe_conn_context_id = cid;
+
+ cqes[0] = (struct kcqe *) &kcqe;
+ cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_FCOE, cqes, 1);
+ return ret;
+}
+
+static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+ struct fcoe_kwqe_destroy *req;
+ union l5cm_specific_data l5_data;
+ struct cnic_local *cp = dev->cnic_priv;
+ int ret;
+ u32 cid;
+
+ req = (struct fcoe_kwqe_destroy *) kwqe;
+ cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid);
+
+ memset(&l5_data, 0, sizeof(l5_data));
+ ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DESTROY, cid,
+ FCOE_CONNECTION_TYPE, &l5_data);
+ return ret;
+}
+
+static int cnic_submit_bnx2x_iscsi_kwqes(struct cnic_dev *dev,
+ struct kwqe *wqes[], u32 num_wqes)
{
int i, work, ret;
u32 opcode;
@@ -2143,6 +2491,98 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
return 0;
}
+static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev,
+ struct kwqe *wqes[], u32 num_wqes)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ int i, work, ret;
+ u32 opcode;
+ struct kwqe *kwqe;
+
+ if (!test_bit(CNIC_F_CNIC_UP, &dev->flags))
+ return -EAGAIN; /* bnx2 is down */
+
+ if (BNX2X_CHIP_NUM(cp->chip_id) == BNX2X_CHIP_NUM_57710)
+ return -EINVAL;
+
+ for (i = 0; i < num_wqes; ) {
+ kwqe = wqes[i];
+ opcode = KWQE_OPCODE(kwqe->kwqe_op_flag);
+ work = 1;
+
+ switch (opcode) {
+ case FCOE_KWQE_OPCODE_INIT1:
+ ret = cnic_bnx2x_fcoe_init1(dev, &wqes[i],
+ num_wqes - i, &work);
+ break;
+ case FCOE_KWQE_OPCODE_OFFLOAD_CONN1:
+ ret = cnic_bnx2x_fcoe_ofld1(dev, &wqes[i],
+ num_wqes - i, &work);
+ break;
+ case FCOE_KWQE_OPCODE_ENABLE_CONN:
+ ret = cnic_bnx2x_fcoe_enable(dev, kwqe);
+ break;
+ case FCOE_KWQE_OPCODE_DISABLE_CONN:
+ ret = cnic_bnx2x_fcoe_disable(dev, kwqe);
+ break;
+ case FCOE_KWQE_OPCODE_DESTROY_CONN:
+ ret = cnic_bnx2x_fcoe_destroy(dev, kwqe);
+ break;
+ case FCOE_KWQE_OPCODE_DESTROY:
+ ret = cnic_bnx2x_fcoe_fw_destroy(dev, kwqe);
+ break;
+ case FCOE_KWQE_OPCODE_STAT:
+ ret = cnic_bnx2x_fcoe_stat(dev, kwqe);
+ break;
+ default:
+ ret = 0;
+ netdev_err(dev->netdev, "Unknown type of KWQE(0x%x)\n",
+ opcode);
+ break;
+ }
+ if (ret < 0)
+ netdev_err(dev->netdev, "KWQE(0x%x) failed\n",
+ opcode);
+ i += work;
+ }
+ return 0;
+}
+
+static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
+ u32 num_wqes)
+{
+ int ret = -EINVAL;
+ u32 layer_code;
+
+ if (!test_bit(CNIC_F_CNIC_UP, &dev->flags))
+ return -EAGAIN; /* bnx2x is down */
+
+ if (!num_wqes)
+ return 0;
+
+ layer_code = wqes[0]->kwqe_op_flag & KWQE_LAYER_MASK;
+ switch (layer_code) {
+ case KWQE_FLAGS_LAYER_MASK_L5_ISCSI:
+ case KWQE_FLAGS_LAYER_MASK_L4:
+ case KWQE_FLAGS_LAYER_MASK_L2:
+ ret = cnic_submit_bnx2x_iscsi_kwqes(dev, wqes, num_wqes);
+ break;
+
+ case KWQE_FLAGS_LAYER_MASK_L5_FCOE:
+ ret = cnic_submit_bnx2x_fcoe_kwqes(dev, wqes, num_wqes);
+ break;
+ }
+ return ret;
+}
+
+static inline u32 cnic_get_kcqe_layer_mask(u32 opflag)
+{
+ if (unlikely(KCQE_OPCODE(opflag) == FCOE_RAMROD_CMD_ID_TERMINATE_CONN))
+ return KCQE_FLAGS_LAYER_MASK_L4;
+
+ return opflag & KCQE_FLAGS_LAYER_MASK;
+}
+
static void service_kcqes(struct cnic_dev *dev, int num_cqes)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -2154,7 +2594,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
struct cnic_ulp_ops *ulp_ops;
int ulp_type;
u32 kcqe_op_flag = cp->completed_kcq[i]->kcqe_op_flag;
- u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK;
+ u32 kcqe_layer = cnic_get_kcqe_layer_mask(kcqe_op_flag);
if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION))
comp++;
@@ -2162,7 +2602,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
while (j < num_cqes) {
u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag;
- if ((next_op & KCQE_FLAGS_LAYER_MASK) != kcqe_layer)
+ if (cnic_get_kcqe_layer_mask(next_op) != kcqe_layer)
break;
if (unlikely(next_op & KCQE_RAMROD_COMPLETION))
@@ -2174,6 +2614,8 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
ulp_type = CNIC_ULP_RDMA;
else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L5_ISCSI)
ulp_type = CNIC_ULP_ISCSI;
+ else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L5_FCOE)
+ ulp_type = CNIC_ULP_FCOE;
else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L4)
ulp_type = CNIC_ULP_L4;
else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L2)
@@ -2342,11 +2784,12 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev)
static int cnic_service_bnx2(void *data, void *status_blk)
{
struct cnic_dev *dev = data;
- struct cnic_local *cp = dev->cnic_priv;
- u32 status_idx = *cp->kcq1.status_idx_ptr;
- if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
- return status_idx;
+ if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+ struct status_block *sblk = status_blk;
+
+ return sblk->status_idx;
+ }
return cnic_service_bnx2_queues(dev);
}
@@ -2365,9 +2808,10 @@ static void cnic_service_bnx2_msix(unsigned long data)
static void cnic_doirq(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- u16 prod = cp->kcq1.sw_prod_idx & MAX_KCQ_IDX;
if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+ u16 prod = cp->kcq1.sw_prod_idx & MAX_KCQ_IDX;
+
prefetch(cp->status_blk.gen);
prefetch(&cp->kcq1.kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
@@ -2469,12 +2913,19 @@ static void cnic_service_bnx2x_bh(unsigned long data)
status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1);
CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
- if (BNX2X_CHIP_IS_E2(cp->chip_id))
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2);
+
+ CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx +
+ MAX_KCQ_IDX);
+
cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF,
status_idx, IGU_INT_ENABLE, 1);
- else
+ } else {
cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID,
status_idx, IGU_INT_ENABLE, 1);
+ }
}
static int cnic_service_bnx2x(void *data, void *status_blk)
@@ -2883,7 +3334,7 @@ static void cnic_cm_cleanup(struct cnic_sock *csk)
struct cnic_dev *dev = csk->dev;
struct cnic_local *cp = dev->cnic_priv;
- cnic_free_id(&cp->csk_port_tbl, csk->src_port);
+ cnic_free_id(&cp->csk_port_tbl, be16_to_cpu(csk->src_port));
csk->src_port = 0;
}
}
@@ -3014,7 +3465,8 @@ static int cnic_get_route(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
int is_v6, rc = 0;
struct dst_entry *dst = NULL;
struct net_device *realdev;
- u32 local_port;
+ __be16 local_port;
+ u32 port_id;
if (saddr->local.v6.sin6_family == AF_INET6 &&
saddr->remote.v6.sin6_family == AF_INET6)
@@ -3054,19 +3506,21 @@ static int cnic_get_route(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
}
}
- if (local_port >= CNIC_LOCAL_PORT_MIN &&
- local_port < CNIC_LOCAL_PORT_MAX) {
- if (cnic_alloc_id(&cp->csk_port_tbl, local_port))
- local_port = 0;
+ port_id = be16_to_cpu(local_port);
+ if (port_id >= CNIC_LOCAL_PORT_MIN &&
+ port_id < CNIC_LOCAL_PORT_MAX) {
+ if (cnic_alloc_id(&cp->csk_port_tbl, port_id))
+ port_id = 0;
} else
- local_port = 0;
+ port_id = 0;
- if (!local_port) {
- local_port = cnic_alloc_new_id(&cp->csk_port_tbl);
- if (local_port == -1) {
+ if (!port_id) {
+ port_id = cnic_alloc_new_id(&cp->csk_port_tbl);
+ if (port_id == -1) {
rc = -ENOMEM;
goto err_out;
}
+ local_port = cpu_to_be16(port_id);
}
csk->src_port = local_port;
@@ -3208,6 +3662,18 @@ done:
csk_put(csk);
}
+static void cnic_process_fcoe_term_conn(struct cnic_dev *dev, struct kcqe *kcqe)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct fcoe_kcqe *fc_kcqe = (struct fcoe_kcqe *) kcqe;
+ u32 l5_cid = fc_kcqe->fcoe_conn_id + BNX2X_FCOE_L5_CID_BASE;
+ struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+
+ ctx->timestamp = jiffies;
+ ctx->wait_cond = 1;
+ wake_up(&ctx->waitq);
+}
+
static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -3216,6 +3682,10 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
u32 l5_cid;
struct cnic_sock *csk;
+ if (opcode == FCOE_RAMROD_CMD_ID_TERMINATE_CONN) {
+ cnic_process_fcoe_term_conn(dev, kcqe);
+ return;
+ }
if (opcode == L4_KCQE_OPCODE_VALUE_OFFLOAD_PG ||
opcode == L4_KCQE_OPCODE_VALUE_UPDATE_PG) {
cnic_cm_process_offld_pg(dev, l4kcqe);
@@ -3852,7 +4322,7 @@ static void cnic_shutdown_bnx2_rx_ring(struct cnic_dev *dev)
memset(&l2kwqe, 0, sizeof(l2kwqe));
wqes[0] = &l2kwqe;
- l2kwqe.kwqe_op_flag = (L2_LAYER_CODE << KWQE_FLAGS_LAYER_SHIFT) |
+ l2kwqe.kwqe_op_flag = (L2_LAYER_CODE << KWQE_LAYER_SHIFT) |
(L2_KWQE_OPCODE_VALUE_FLUSH <<
KWQE_OPCODE_SHIFT) | 2;
dev->submit_kwqes(dev, wqes, 1);
@@ -4106,7 +4576,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev,
struct host_sp_status_block *sb = cp->bnx2x_def_status_blk;
int port = CNIC_PORT(cp);
int i;
- int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ u32 cli = cp->ethdev->iscsi_l2_client_id;
u32 val;
memset(txbd, 0, BCM_PAGE_SIZE);
@@ -4167,7 +4637,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev,
struct host_sp_status_block *sb = cp->bnx2x_def_status_blk;
int i;
int port = CNIC_PORT(cp);
- int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ u32 cli = cp->ethdev->iscsi_l2_client_id;
int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli);
u32 val;
dma_addr_t ring_map = udev->l2_ring_map;
@@ -4231,12 +4701,39 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev,
cp->rx_cons_ptr =
&sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS];
+ cp->rx_cons = *cp->rx_cons_ptr;
+}
+
+static int cnic_read_bnx2x_iscsi_mac(struct cnic_dev *dev, u32 upper_addr,
+ u32 lower_addr)
+{
+ u32 val;
+ u8 mac[6];
+
+ val = CNIC_RD(dev, upper_addr);
+
+ mac[0] = (u8) (val >> 8);
+ mac[1] = (u8) val;
+
+ val = CNIC_RD(dev, lower_addr);
+
+ mac[2] = (u8) (val >> 24);
+ mac[3] = (u8) (val >> 16);
+ mac[4] = (u8) (val >> 8);
+ mac[5] = (u8) val;
+
+ if (is_valid_ether_addr(mac)) {
+ memcpy(dev->mac_addr, mac, 6);
+ return 0;
+ } else {
+ return -EINVAL;
+ }
}
static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- u32 base, base2, addr, val;
+ u32 base, base2, addr, addr1, val;
int port = CNIC_PORT(cp);
dev->max_iscsi_conn = 0;
@@ -4249,20 +4746,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
addr = BNX2X_SHMEM_ADDR(base,
dev_info.port_hw_config[port].iscsi_mac_upper);
- val = CNIC_RD(dev, addr);
-
- dev->mac_addr[0] = (u8) (val >> 8);
- dev->mac_addr[1] = (u8) val;
-
- addr = BNX2X_SHMEM_ADDR(base,
+ addr1 = BNX2X_SHMEM_ADDR(base,
dev_info.port_hw_config[port].iscsi_mac_lower);
- val = CNIC_RD(dev, addr);
-
- dev->mac_addr[2] = (u8) (val >> 24);
- dev->mac_addr[3] = (u8) (val >> 16);
- dev->mac_addr[4] = (u8) (val >> 8);
- dev->mac_addr[5] = (u8) val;
+ cnic_read_bnx2x_iscsi_mac(dev, addr, addr1);
addr = BNX2X_SHMEM_ADDR(base, validity_map[port]);
val = CNIC_RD(dev, addr);
@@ -4278,6 +4765,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
val16 ^= 0x1e1e;
dev->max_iscsi_conn = val16;
}
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id))
+ dev->max_fcoe_conn = BNX2X_FCOE_NUM_CONNECTIONS;
+
if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) {
int func = CNIC_FUNC(cp);
u32 mf_cfg_addr;
@@ -4288,21 +4779,90 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
else
mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET;
- addr = mf_cfg_addr +
- offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag);
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ /* Must determine if the MF is SD vs SI mode */
+ addr = BNX2X_SHMEM_ADDR(base,
+ dev_info.shared_feature_config.config);
+ val = CNIC_RD(dev, addr);
+ if ((val & SHARED_FEAT_CFG_FORCE_SF_MODE_MASK) ==
+ SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT) {
+ int rc;
+
+ /* MULTI_FUNCTION_SI mode */
+ addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
+ func_ext_config[func].func_cfg);
+ val = CNIC_RD(dev, addr);
+ if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD))
+ dev->max_iscsi_conn = 0;
+
+ if (!(val & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD))
+ dev->max_fcoe_conn = 0;
+
+ addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
+ func_ext_config[func].
+ iscsi_mac_addr_upper);
+ addr1 = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
+ func_ext_config[func].
+ iscsi_mac_addr_lower);
+ rc = cnic_read_bnx2x_iscsi_mac(dev, addr,
+ addr1);
+ if (rc && func > 1)
+ dev->max_iscsi_conn = 0;
+
+ return;
+ }
+ }
+
+ addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
+ func_mf_config[func].e1hov_tag);
val = CNIC_RD(dev, addr);
val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
- addr = mf_cfg_addr +
- offsetof(struct mf_cfg,
- func_mf_config[func].config);
- val = CNIC_RD(dev, addr);
- val &= FUNC_MF_CFG_PROTOCOL_MASK;
- if (val != FUNC_MF_CFG_PROTOCOL_ISCSI)
- dev->max_iscsi_conn = 0;
+ dev->max_fcoe_conn = 0;
+ dev->max_iscsi_conn = 0;
}
}
+ if (!is_valid_ether_addr(dev->mac_addr))
+ dev->max_iscsi_conn = 0;
+}
+
+static void cnic_init_bnx2x_kcq(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ u32 pfid = cp->pfid;
+
+ cp->kcq1.io_addr = BAR_CSTRORM_INTMEM +
+ CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0);
+ cp->kcq1.sw_prod_idx = 0;
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ struct host_hc_status_block_e2 *sb = cp->status_blk.gen;
+
+ cp->kcq1.hw_prod_idx_ptr =
+ &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
+ cp->kcq1.status_idx_ptr =
+ &sb->sb.running_index[SM_RX_ID];
+ } else {
+ struct host_hc_status_block_e1x *sb = cp->status_blk.gen;
+
+ cp->kcq1.hw_prod_idx_ptr =
+ &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
+ cp->kcq1.status_idx_ptr =
+ &sb->sb.running_index[SM_RX_ID];
+ }
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ struct host_hc_status_block_e2 *sb = cp->status_blk.gen;
+
+ cp->kcq2.io_addr = BAR_USTRORM_INTMEM +
+ USTORM_FCOE_EQ_PROD_OFFSET(pfid);
+ cp->kcq2.sw_prod_idx = 0;
+ cp->kcq2.hw_prod_idx_ptr =
+ &sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS];
+ cp->kcq2.status_idx_ptr =
+ &sb->sb.running_index[SM_RX_ID];
+ }
}
static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
@@ -4335,28 +4895,19 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
if (ret)
return -ENOMEM;
- cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2;
-
- cp->kcq1.io_addr = BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0);
- cp->kcq1.sw_prod_idx = 0;
-
if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
- struct host_hc_status_block_e2 *sb = cp->status_blk.gen;
-
- cp->kcq1.hw_prod_idx_ptr =
- &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
- cp->kcq1.status_idx_ptr =
- &sb->sb.running_index[SM_RX_ID];
- } else {
- struct host_hc_status_block_e1x *sb = cp->status_blk.gen;
+ ret = cnic_init_id_tbl(&cp->fcoe_cid_tbl,
+ BNX2X_FCOE_NUM_CONNECTIONS,
+ cp->fcoe_start_cid);
- cp->kcq1.hw_prod_idx_ptr =
- &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
- cp->kcq1.status_idx_ptr =
- &sb->sb.running_index[SM_RX_ID];
+ if (ret)
+ return -ENOMEM;
}
+ cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2;
+
+ cnic_init_bnx2x_kcq(dev);
+
cnic_get_bnx2x_iscsi_info(dev);
/* Only 1 EQ */
@@ -4424,7 +4975,8 @@ static void cnic_init_rings(struct cnic_dev *dev)
cnic_init_bnx2_rx_ring(dev);
set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
- u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ u32 cli = cp->ethdev->iscsi_l2_client_id;
+ u32 cid = cp->ethdev->iscsi_l2_cid;
u32 cl_qzone_id, type;
struct client_init_ramrod_data *data;
union l5cm_specific_data l5_data;
@@ -4465,7 +5017,7 @@ static void cnic_init_rings(struct cnic_dev *dev)
set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP,
- BNX2X_ISCSI_L2_CID, type, &l5_data);
+ cid, type, &l5_data);
i = 0;
while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) &&
@@ -4476,7 +5028,7 @@ static void cnic_init_rings(struct cnic_dev *dev)
netdev_err(dev->netdev,
"iSCSI CLIENT_SETUP did not complete\n");
cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1);
- cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1);
+ cnic_ring_ctl(dev, cid, cli, 1);
}
}
@@ -4491,19 +5043,20 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
cnic_shutdown_bnx2_rx_ring(dev);
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
struct cnic_local *cp = dev->cnic_priv;
- u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ u32 cli = cp->ethdev->iscsi_l2_client_id;
+ u32 cid = cp->ethdev->iscsi_l2_cid;
union l5cm_specific_data l5_data;
int i;
u32 type;
- cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0);
+ cnic_ring_ctl(dev, cid, cli, 0);
set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
l5_data.phy_address.lo = cli;
l5_data.phy_address.hi = 0;
cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_HALT,
- BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
+ cid, ETH_CONNECTION_TYPE, &l5_data);
i = 0;
while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) &&
++i < 10)
@@ -4520,7 +5073,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) &
SPE_HDR_FUNCTION_ID);
cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL,
- BNX2X_ISCSI_L2_CID, type, &l5_data);
+ cid, type, &l5_data);
msleep(10);
}
clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h
index 6a4a0ae5cfe3..b328f6c924c3 100644
--- a/drivers/net/cnic.h
+++ b/drivers/net/cnic.h
@@ -82,7 +82,7 @@ struct cnic_redirect_entry {
#define MAX_ISCSI_TBL_SZ 256
#define CNIC_LOCAL_PORT_MIN 60000
-#define CNIC_LOCAL_PORT_MAX 61000
+#define CNIC_LOCAL_PORT_MAX 61024
#define CNIC_LOCAL_PORT_RANGE (CNIC_LOCAL_PORT_MAX - CNIC_LOCAL_PORT_MIN)
#define KWQE_CNT (BCM_PAGE_SIZE / sizeof(struct kwqe))
@@ -258,6 +258,7 @@ struct cnic_local {
u16 kwq_con_idx;
struct kcq_info kcq1;
+ struct kcq_info kcq2;
union {
void *gen;
@@ -290,6 +291,10 @@ struct cnic_local {
atomic_t iscsi_conn;
u32 iscsi_start_cid;
+ u32 fcoe_init_cid;
+ u32 fcoe_start_cid;
+ struct cnic_id_tbl fcoe_cid_tbl;
+
u32 max_cid_space;
/* per connection parameters */
@@ -356,11 +361,6 @@ struct bnx2x_bd_chain_next {
#define BNX2X_CONTEXT_MEM_SIZE 1024
#define BNX2X_FCOE_CID 16
-/* iSCSI client IDs are 17, 19, 21, 23 */
-#define BNX2X_ISCSI_BASE_CL_ID 17
-#define BNX2X_ISCSI_CL_ID(vn) (BNX2X_ISCSI_BASE_CL_ID + ((vn) << 1))
-
-#define BNX2X_ISCSI_L2_CID 17
#define BNX2X_ISCSI_START_CID 18
#define BNX2X_ISCSI_NUM_CONNECTIONS 128
#define BNX2X_ISCSI_TASK_CONTEXT_SIZE 128
@@ -372,6 +372,10 @@ struct bnx2x_bd_chain_next {
#define BNX2X_ISCSI_PBL_NOT_CACHED 0xff
#define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff
+#define BNX2X_FCOE_NUM_CONNECTIONS 128
+
+#define BNX2X_FCOE_L5_CID_BASE MAX_ISCSI_TBL_SZ
+
#define BNX2X_CHIP_NUM_57710 0x164e
#define BNX2X_CHIP_NUM_57711 0x164f
#define BNX2X_CHIP_NUM_57711E 0x1650
@@ -427,6 +431,13 @@ struct bnx2x_bd_chain_next {
(CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \
offsetof(struct shmem2_region, field)))
+#define BNX2X_MF_CFG_ADDR(base, field) \
+ ((base) + offsetof(struct mf_cfg, field))
+
+#ifndef ETH_MAX_RX_CLIENTS_E2
+#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H
+#endif
+
#define CNIC_PORT(cp) ((cp)->pfid & 1)
#define CNIC_FUNC(cp) ((cp)->func)
#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\
@@ -439,7 +450,9 @@ struct bnx2x_bd_chain_next {
#define BNX2X_SW_CID(x) (x & 0x1ffff)
#define BNX2X_CL_QZONE_ID(cp, cli) \
- (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H))
+ (cli + (CNIC_PORT(cp) * (BNX2X_CHIP_IS_E2(cp->chip_id) ?\
+ ETH_MAX_RX_CLIENTS_E2 : \
+ ETH_MAX_RX_CLIENTS_E1H)))
#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4)
#endif
diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h
index 328e8b2765a3..fdbc00415603 100644
--- a/drivers/net/cnic_defs.h
+++ b/drivers/net/cnic_defs.h
@@ -35,6 +35,40 @@
#define L5CM_RAMROD_CMD_ID_SEARCHER_DELETE (L5CM_RAMROD_CMD_ID_BASE + 14)
#define L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD (L5CM_RAMROD_CMD_ID_BASE + 15)
+#define FCOE_KCQE_OPCODE_INIT_FUNC (0x10)
+#define FCOE_KCQE_OPCODE_DESTROY_FUNC (0x11)
+#define FCOE_KCQE_OPCODE_STAT_FUNC (0x12)
+#define FCOE_KCQE_OPCODE_OFFLOAD_CONN (0x15)
+#define FCOE_KCQE_OPCODE_ENABLE_CONN (0x16)
+#define FCOE_KCQE_OPCODE_DISABLE_CONN (0x17)
+#define FCOE_KCQE_OPCODE_DESTROY_CONN (0x18)
+#define FCOE_KCQE_OPCODE_CQ_EVENT_NOTIFICATION (0x20)
+#define FCOE_KCQE_OPCODE_FCOE_ERROR (0x21)
+
+#define FCOE_RAMROD_CMD_ID_INIT (FCOE_KCQE_OPCODE_INIT_FUNC)
+#define FCOE_RAMROD_CMD_ID_DESTROY (FCOE_KCQE_OPCODE_DESTROY_FUNC)
+#define FCOE_RAMROD_CMD_ID_OFFLOAD_CONN (FCOE_KCQE_OPCODE_OFFLOAD_CONN)
+#define FCOE_RAMROD_CMD_ID_ENABLE_CONN (FCOE_KCQE_OPCODE_ENABLE_CONN)
+#define FCOE_RAMROD_CMD_ID_DISABLE_CONN (FCOE_KCQE_OPCODE_DISABLE_CONN)
+#define FCOE_RAMROD_CMD_ID_DESTROY_CONN (FCOE_KCQE_OPCODE_DESTROY_CONN)
+#define FCOE_RAMROD_CMD_ID_STAT (FCOE_KCQE_OPCODE_STAT_FUNC)
+#define FCOE_RAMROD_CMD_ID_TERMINATE_CONN (0x81)
+
+#define FCOE_KWQE_OPCODE_INIT1 (0)
+#define FCOE_KWQE_OPCODE_INIT2 (1)
+#define FCOE_KWQE_OPCODE_INIT3 (2)
+#define FCOE_KWQE_OPCODE_OFFLOAD_CONN1 (3)
+#define FCOE_KWQE_OPCODE_OFFLOAD_CONN2 (4)
+#define FCOE_KWQE_OPCODE_OFFLOAD_CONN3 (5)
+#define FCOE_KWQE_OPCODE_OFFLOAD_CONN4 (6)
+#define FCOE_KWQE_OPCODE_ENABLE_CONN (7)
+#define FCOE_KWQE_OPCODE_DISABLE_CONN (8)
+#define FCOE_KWQE_OPCODE_DESTROY_CONN (9)
+#define FCOE_KWQE_OPCODE_DESTROY (10)
+#define FCOE_KWQE_OPCODE_STAT (11)
+
+#define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3)
+
/* KCQ (kernel completion queue) response op codes */
#define L4_KCQE_OPCODE_VALUE_CLOSE_COMP (53)
#define L4_KCQE_OPCODE_VALUE_RESET_COMP (54)
@@ -683,6 +717,1496 @@ struct cstorm_iscsi_ag_context {
};
/*
+ * Parameters initialized during offloaded according to FLOGI/PLOGI/PRLI and used in FCoE context section
+ */
+struct ustorm_fcoe_params {
+#if defined(__BIG_ENDIAN)
+ u16 fcoe_conn_id;
+ u16 flags;
+#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0)
+#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0
+#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1)
+#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1
+#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2)
+#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2
+#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3)
+#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3
+#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4)
+#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4
+#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5)
+#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5
+#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6)
+#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6
+#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7)
+#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7
+#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8)
+#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8
+#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9)
+#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9
+#elif defined(__LITTLE_ENDIAN)
+ u16 flags;
+#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0)
+#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0
+#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1)
+#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1
+#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2)
+#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2
+#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3)
+#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3
+#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4)
+#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4
+#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5)
+#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5
+#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6)
+#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6
+#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7)
+#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7
+#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8)
+#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8
+#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9)
+#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9
+ u16 fcoe_conn_id;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 hc_csdm_byte_en;
+ u8 func_id;
+ u8 port_id;
+ u8 vnic_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 vnic_id;
+ u8 port_id;
+ u8 func_id;
+ u8 hc_csdm_byte_en;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 rx_total_conc_seqs;
+ u16 rx_max_fc_pay_len;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rx_max_fc_pay_len;
+ u16 rx_total_conc_seqs;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 ox_id;
+ u16 rx_max_conc_seqs;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rx_max_conc_seqs;
+ u16 ox_id;
+#endif
+};
+
+/*
+ * FCoE 16-bits index structure
+ */
+struct fcoe_idx16_fields {
+ u16 fields;
+#define FCOE_IDX16_FIELDS_IDX (0x7FFF<<0)
+#define FCOE_IDX16_FIELDS_IDX_SHIFT 0
+#define FCOE_IDX16_FIELDS_MSB (0x1<<15)
+#define FCOE_IDX16_FIELDS_MSB_SHIFT 15
+};
+
+/*
+ * FCoE 16-bits index union
+ */
+union fcoe_idx16_field_union {
+ struct fcoe_idx16_fields fields;
+ u16 val;
+};
+
+/*
+ * 4 regs size
+ */
+struct fcoe_bd_ctx {
+ u32 buf_addr_hi;
+ u32 buf_addr_lo;
+#if defined(__BIG_ENDIAN)
+ u16 rsrv0;
+ u16 buf_len;
+#elif defined(__LITTLE_ENDIAN)
+ u16 buf_len;
+ u16 rsrv0;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 rsrv1;
+ u16 flags;
+#elif defined(__LITTLE_ENDIAN)
+ u16 flags;
+ u16 rsrv1;
+#endif
+};
+
+/*
+ * Parameters required for placement according to SGL
+ */
+struct ustorm_fcoe_data_place {
+#if defined(__BIG_ENDIAN)
+ u16 cached_sge_off;
+ u8 cached_num_sges;
+ u8 cached_sge_idx;
+#elif defined(__LITTLE_ENDIAN)
+ u8 cached_sge_idx;
+ u8 cached_num_sges;
+ u16 cached_sge_off;
+#endif
+ struct fcoe_bd_ctx cached_sge[3];
+};
+
+struct fcoe_task_ctx_entry_txwr_rxrd {
+#if defined(__BIG_ENDIAN)
+ u16 verify_tx_seq;
+ u8 init_flags;
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6
+ u8 tx_flags;
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4
+#elif defined(__LITTLE_ENDIAN)
+ u8 tx_flags;
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4
+ u8 init_flags;
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6)
+#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6
+ u16 verify_tx_seq;
+#endif
+};
+
+struct fcoe_fcp_cmd_payload {
+ u32 opaque[8];
+};
+
+struct fcoe_fc_hdr {
+#if defined(__BIG_ENDIAN)
+ u8 cs_ctl;
+ u8 s_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 s_id[3];
+ u8 cs_ctl;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 r_ctl;
+ u8 d_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 d_id[3];
+ u8 r_ctl;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 seq_id;
+ u8 df_ctl;
+ u16 seq_cnt;
+#elif defined(__LITTLE_ENDIAN)
+ u16 seq_cnt;
+ u8 df_ctl;
+ u8 seq_id;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 type;
+ u8 f_ctl[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 f_ctl[3];
+ u8 type;
+#endif
+ u32 parameters;
+#if defined(__BIG_ENDIAN)
+ u16 ox_id;
+ u16 rx_id;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rx_id;
+ u16 ox_id;
+#endif
+};
+
+struct fcoe_fc_frame {
+ struct fcoe_fc_hdr fc_hdr;
+ u32 reserved0[2];
+};
+
+union fcoe_cmd_flow_info {
+ struct fcoe_fcp_cmd_payload fcp_cmd_payload;
+ struct fcoe_fc_frame mp_fc_frame;
+};
+
+struct fcoe_read_flow_info {
+ struct fcoe_fc_hdr fc_data_in_hdr;
+ u32 reserved[2];
+};
+
+struct fcoe_fcp_xfr_rdy_payload {
+ u32 burst_len;
+ u32 data_ro;
+};
+
+struct fcoe_write_flow_info {
+ struct fcoe_fc_hdr fc_data_out_hdr;
+ struct fcoe_fcp_xfr_rdy_payload fcp_xfr_payload;
+};
+
+struct fcoe_fcp_rsp_flags {
+ u8 flags;
+#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID (0x1<<0)
+#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID_SHIFT 0
+#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID (0x1<<1)
+#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID_SHIFT 1
+#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER (0x1<<2)
+#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER_SHIFT 2
+#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER (0x1<<3)
+#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER_SHIFT 3
+#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ (0x1<<4)
+#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ_SHIFT 4
+#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS (0x7<<5)
+#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS_SHIFT 5
+};
+
+struct fcoe_fcp_rsp_payload {
+ struct regpair reserved0;
+ u32 fcp_resid;
+#if defined(__BIG_ENDIAN)
+ u16 retry_delay_timer;
+ struct fcoe_fcp_rsp_flags fcp_flags;
+ u8 scsi_status_code;
+#elif defined(__LITTLE_ENDIAN)
+ u8 scsi_status_code;
+ struct fcoe_fcp_rsp_flags fcp_flags;
+ u16 retry_delay_timer;
+#endif
+ u32 fcp_rsp_len;
+ u32 fcp_sns_len;
+};
+
+/*
+ * Fixed size structure in order to plant it in Union structure
+ */
+struct fcoe_fcp_rsp_union {
+ struct fcoe_fcp_rsp_payload payload;
+ struct regpair reserved0;
+};
+
+/*
+ * Fixed size structure in order to plant it in Union structure
+ */
+struct fcoe_abts_rsp_union {
+ u32 r_ctl;
+ u32 abts_rsp_payload[7];
+};
+
+union fcoe_rsp_flow_info {
+ struct fcoe_fcp_rsp_union fcp_rsp;
+ struct fcoe_abts_rsp_union abts_rsp;
+};
+
+struct fcoe_cleanup_flow_info {
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u16 task_id;
+#elif defined(__LITTLE_ENDIAN)
+ u16 task_id;
+ u16 reserved1;
+#endif
+ u32 reserved2[7];
+};
+
+/*
+ * 32 bytes used for general purposes
+ */
+union fcoe_general_task_ctx {
+ union fcoe_cmd_flow_info cmd_info;
+ struct fcoe_read_flow_info read_info;
+ struct fcoe_write_flow_info write_info;
+ union fcoe_rsp_flow_info rsp_info;
+ struct fcoe_cleanup_flow_info cleanup_info;
+ u32 comp_info[8];
+};
+
+struct fcoe_s_stat_ctx {
+ u8 flags;
+#define FCOE_S_STAT_CTX_ACTIVE (0x1<<0)
+#define FCOE_S_STAT_CTX_ACTIVE_SHIFT 0
+#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND (0x1<<1)
+#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND_SHIFT 1
+#define FCOE_S_STAT_CTX_ABTS_PERFORMED (0x1<<2)
+#define FCOE_S_STAT_CTX_ABTS_PERFORMED_SHIFT 2
+#define FCOE_S_STAT_CTX_SEQ_TIMEOUT (0x1<<3)
+#define FCOE_S_STAT_CTX_SEQ_TIMEOUT_SHIFT 3
+#define FCOE_S_STAT_CTX_P_RJT (0x1<<4)
+#define FCOE_S_STAT_CTX_P_RJT_SHIFT 4
+#define FCOE_S_STAT_CTX_ACK_EOFT (0x1<<5)
+#define FCOE_S_STAT_CTX_ACK_EOFT_SHIFT 5
+#define FCOE_S_STAT_CTX_RSRV1 (0x3<<6)
+#define FCOE_S_STAT_CTX_RSRV1_SHIFT 6
+};
+
+/*
+ * Common section. Both TX and RX processing might write and read from it in different flows
+ */
+struct fcoe_task_ctx_entry_tx_rx_cmn {
+ u32 data_2_trns;
+ union fcoe_general_task_ctx general;
+#if defined(__BIG_ENDIAN)
+ u16 tx_low_seq_cnt;
+ struct fcoe_s_stat_ctx tx_s_stat;
+ u8 tx_seq_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 tx_seq_id;
+ struct fcoe_s_stat_ctx tx_s_stat;
+ u16 tx_low_seq_cnt;
+#endif
+ u32 common_flags;
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID (0xFFFFFF<<0)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID (0x1<<24)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT 24
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT (0x1<<25)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT_SHIFT 25
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER (0x1<<26)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER_SHIFT 26
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF (0x1<<27)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF_SHIFT 27
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME (0x1<<28)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT 28
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV (0x7<<29)
+#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV_SHIFT 29
+};
+
+struct fcoe_task_ctx_entry_rxwr_txrd {
+#if defined(__BIG_ENDIAN)
+ u16 rx_id;
+ u16 rx_flags;
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9
+#elif defined(__LITTLE_ENDIAN)
+ u16 rx_flags;
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9)
+#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9
+ u16 rx_id;
+#endif
+};
+
+struct fcoe_seq_ctx {
+#if defined(__BIG_ENDIAN)
+ u16 low_seq_cnt;
+ struct fcoe_s_stat_ctx s_stat;
+ u8 seq_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 seq_id;
+ struct fcoe_s_stat_ctx s_stat;
+ u16 low_seq_cnt;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 err_seq_cnt;
+ u16 high_seq_cnt;
+#elif defined(__LITTLE_ENDIAN)
+ u16 high_seq_cnt;
+ u16 err_seq_cnt;
+#endif
+ u32 low_exp_ro;
+ u32 high_exp_ro;
+};
+
+struct fcoe_single_sge_ctx {
+ struct regpair cur_buf_addr;
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u16 cur_buf_rem;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cur_buf_rem;
+ u16 reserved0;
+#endif
+};
+
+struct fcoe_mul_sges_ctx {
+ struct regpair cur_sge_addr;
+#if defined(__BIG_ENDIAN)
+ u8 sgl_size;
+ u8 cur_sge_idx;
+ u16 cur_sge_off;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cur_sge_off;
+ u8 cur_sge_idx;
+ u8 sgl_size;
+#endif
+};
+
+union fcoe_sgl_ctx {
+ struct fcoe_single_sge_ctx single_sge;
+ struct fcoe_mul_sges_ctx mul_sges;
+};
+
+struct fcoe_task_ctx_entry_rx_only {
+ struct fcoe_seq_ctx seq_ctx;
+ struct fcoe_seq_ctx ooo_seq_ctx;
+ u32 rsrv3;
+ union fcoe_sgl_ctx sgl_ctx;
+};
+
+struct ustorm_fcoe_task_ctx_entry_rd {
+ struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd;
+ struct fcoe_task_ctx_entry_tx_rx_cmn cmn;
+ struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd;
+ struct fcoe_task_ctx_entry_rx_only rx_wr;
+ u32 reserved;
+};
+
+/*
+ * Ustorm FCoE Storm Context
+ */
+struct ustorm_fcoe_st_context {
+ struct ustorm_fcoe_params fcoe_params;
+ struct regpair task_addr;
+ struct regpair cq_base_addr;
+ struct regpair rq_pbl_base;
+ struct regpair rq_cur_page_addr;
+ struct regpair confq_pbl_base_addr;
+ struct regpair conn_db_base;
+ struct regpair xfrq_base_addr;
+ struct regpair lcq_base_addr;
+#if defined(__BIG_ENDIAN)
+ union fcoe_idx16_field_union rq_cons;
+ union fcoe_idx16_field_union rq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ union fcoe_idx16_field_union rq_prod;
+ union fcoe_idx16_field_union rq_cons;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 xfrq_prod;
+ u16 cq_cons;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cq_cons;
+ u16 xfrq_prod;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 lcq_cons;
+ u16 hc_cram_address;
+#elif defined(__LITTLE_ENDIAN)
+ u16 hc_cram_address;
+ u16 lcq_cons;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 sq_xfrq_lcq_confq_size;
+ u16 confq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 confq_prod;
+ u16 sq_xfrq_lcq_confq_size;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 hc_csdm_agg_int;
+ u8 flags;
+#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0)
+#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0
+#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1)
+#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1
+#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2)
+#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2
+#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3)
+#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3
+ u8 available_rqes;
+ u8 sp_q_flush_cnt;
+#elif defined(__LITTLE_ENDIAN)
+ u8 sp_q_flush_cnt;
+ u8 available_rqes;
+ u8 flags;
+#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0)
+#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0
+#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1)
+#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1
+#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2)
+#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2
+#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3)
+#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3
+ u8 hc_csdm_agg_int;
+#endif
+ struct ustorm_fcoe_data_place data_place;
+ struct ustorm_fcoe_task_ctx_entry_rd tce;
+};
+
+/*
+ * The FCoE non-aggregative context of Tstorm
+ */
+struct tstorm_fcoe_st_context {
+ struct regpair reserved0;
+ struct regpair reserved1;
+};
+
+/*
+ * The fcoe aggregative context section of Xstorm
+ */
+struct xstorm_fcoe_extra_ag_context_section {
+#if defined(__BIG_ENDIAN)
+ u8 tcp_agg_vars1;
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51 (0x3<<0)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4)
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7
+ u8 __reserved_da_cnt;
+ u16 __mtu;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __mtu;
+ u8 __reserved_da_cnt;
+ u8 tcp_agg_vars1;
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51 (0x3<<0)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4)
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7
+#endif
+ u32 __task_addr_lo;
+ u32 __task_addr_hi;
+ u32 __reserved55;
+ u32 __tx_prods;
+#if defined(__BIG_ENDIAN)
+ u8 __agg_val8_th;
+ u8 __agg_val8;
+ u16 tcp_agg_vars2;
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57_SHIFT 0
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58 (0x1<<1)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58_SHIFT 1
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59 (0x1<<2)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59_SHIFT 2
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60 (0x1<<5)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7)
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14
+#elif defined(__LITTLE_ENDIAN)
+ u16 tcp_agg_vars2;
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57_SHIFT 0
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58 (0x1<<1)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED58_SHIFT 1
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59 (0x1<<2)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED59_SHIFT 2
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60 (0x1<<5)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7)
+#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14)
+#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14
+ u8 __agg_val8;
+ u8 __agg_val8_th;
+#endif
+ u32 __sq_base_addr_lo;
+ u32 __sq_base_addr_hi;
+ u32 __xfrq_base_addr_lo;
+ u32 __xfrq_base_addr_hi;
+#if defined(__BIG_ENDIAN)
+ u16 __xfrq_cons;
+ u16 __xfrq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __xfrq_prod;
+ u16 __xfrq_cons;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 __tcp_agg_vars5;
+ u8 __tcp_agg_vars4;
+ u8 __tcp_agg_vars3;
+ u8 __reserved_force_pure_ack_cnt;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __reserved_force_pure_ack_cnt;
+ u8 __tcp_agg_vars3;
+ u8 __tcp_agg_vars4;
+ u8 __tcp_agg_vars5;
+#endif
+ u32 __tcp_agg_vars6;
+#if defined(__BIG_ENDIAN)
+ u16 __agg_misc6;
+ u16 __tcp_agg_vars7;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __tcp_agg_vars7;
+ u16 __agg_misc6;
+#endif
+ u32 __agg_val10;
+ u32 __agg_val10_th;
+#if defined(__BIG_ENDIAN)
+ u16 __reserved3;
+ u8 __reserved2;
+ u8 __da_only_cnt;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __da_only_cnt;
+ u8 __reserved2;
+ u16 __reserved3;
+#endif
+};
+
+/*
+ * The fcoe aggregative context of Xstorm
+ */
+struct xstorm_fcoe_ag_context {
+#if defined(__BIG_ENDIAN)
+ u16 agg_val1;
+ u8 agg_vars1;
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51 (0x1<<2)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51_SHIFT 2
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52 (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN (0x1<<5)
+#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN_SHIFT 5
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN (0x1<<7)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN_SHIFT 7
+ u8 __state;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __state;
+ u8 agg_vars1;
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define __XSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51 (0x1<<2)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED51_SHIFT 2
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52 (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED52_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN (0x1<<5)
+#define XSTORM_FCOE_AG_CONTEXT_NAGLE_EN_SHIFT 5
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN (0x1<<7)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED_UNA_GT_NXT_EN_SHIFT 7
+ u16 agg_val1;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 cdu_reserved;
+ u8 __agg_vars4;
+ u8 agg_vars3;
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF (0x3<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF_SHIFT 6
+ u8 agg_vars2;
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF (0x3<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2
+#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG (0x1<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1 (0x3<<5)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1_SHIFT 5
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+#elif defined(__LITTLE_ENDIAN)
+ u8 agg_vars2;
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF (0x3<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2
+#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX8_FLAG_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG (0x1<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX9_FLAG_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1 (0x3<<5)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE1_SHIFT 5
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __XSTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+ u8 agg_vars3;
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF (0x3<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX19_CF_SHIFT 6
+ u8 __agg_vars4;
+ u8 cdu_reserved;
+#endif
+ u32 more_to_send;
+#if defined(__BIG_ENDIAN)
+ u16 agg_vars5;
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5 (0x3<<0)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5_SHIFT 0
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8
+#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE (0x3<<14)
+#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE_SHIFT 14
+ u16 sq_cons;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sq_cons;
+ u16 agg_vars5;
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5 (0x3<<0)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE5_SHIFT 0
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8)
+#define XSTORM_FCOE_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8
+#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE (0x3<<14)
+#define __XSTORM_FCOE_AG_CONTEXT_CONFQ_DEC_RULE_SHIFT 14
+#endif
+ struct xstorm_fcoe_extra_ag_context_section __extra_section;
+#if defined(__BIG_ENDIAN)
+ u16 agg_vars7;
+#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF (0x3<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3_SHIFT 6
+#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF (0x3<<8)
+#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF_SHIFT 8
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62 (0x1<<10)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62_SHIFT 10
+#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<11)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 11
+#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG (0x1<<12)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG_SHIFT 12
+#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG (0x1<<13)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG_SHIFT 13
+#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG (0x1<<14)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG_SHIFT 14
+#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG (0x1<<15)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+ u8 agg_val3_th;
+ u8 agg_vars6;
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6 (0x7<<0)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE (0x7<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE (0x3<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE_SHIFT 6
+#elif defined(__LITTLE_ENDIAN)
+ u8 agg_vars6;
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6 (0x7<<0)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE6_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE (0x7<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_XFRQ_DEC_RULE_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE (0x3<<6)
+#define __XSTORM_FCOE_AG_CONTEXT_SQ_DEC_RULE_SHIFT 6
+ u8 agg_val3_th;
+ u16 agg_vars7;
+#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
+#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG (0x1<<3)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX13_FLAG_SHIFT 3
+#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF (0x3<<4)
+#define __XSTORM_FCOE_AG_CONTEXT_QUEUE0_CF_SHIFT 4
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
+#define XSTORM_FCOE_AG_CONTEXT_DECISION_RULE3_SHIFT 6
+#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF (0x3<<8)
+#define XSTORM_FCOE_AG_CONTEXT_AUX1_CF_SHIFT 8
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62 (0x1<<10)
+#define __XSTORM_FCOE_AG_CONTEXT_RESERVED62_SHIFT 10
+#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<11)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 11
+#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG (0x1<<12)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX10_FLAG_SHIFT 12
+#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG (0x1<<13)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX11_FLAG_SHIFT 13
+#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG (0x1<<14)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX12_FLAG_SHIFT 14
+#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG (0x1<<15)
+#define __XSTORM_FCOE_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __agg_val11_th;
+ u16 __agg_val11;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __agg_val11;
+ u16 __agg_val11_th;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 __reserved1;
+ u8 __agg_val6_th;
+ u16 __confq_tx_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __confq_tx_prod;
+ u8 __agg_val6_th;
+ u8 __reserved1;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 confq_cons;
+ u16 confq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 confq_prod;
+ u16 confq_cons;
+#endif
+ u32 agg_vars8;
+#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX (0xFFFFFF<<0)
+#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX_SHIFT 0
+#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3 (0xFF<<24)
+#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3_SHIFT 24
+#if defined(__BIG_ENDIAN)
+ u16 ox_id;
+ u16 sq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sq_prod;
+ u16 ox_id;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 agg_val3;
+ u8 agg_val6;
+ u8 agg_val5_th;
+ u8 agg_val5;
+#elif defined(__LITTLE_ENDIAN)
+ u8 agg_val5;
+ u8 agg_val5_th;
+ u8 agg_val6;
+ u8 agg_val3;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __pbf_tx_seq_ack;
+ u16 agg_limit1;
+#elif defined(__LITTLE_ENDIAN)
+ u16 agg_limit1;
+ u16 __pbf_tx_seq_ack;
+#endif
+ u32 completion_seq;
+ u32 confq_pbl_base_lo;
+ u32 confq_pbl_base_hi;
+};
+
+/*
+ * The fcoe extra aggregative context section of Tstorm
+ */
+struct tstorm_fcoe_extra_ag_context_section {
+ u32 __agg_val1;
+#if defined(__BIG_ENDIAN)
+ u8 __tcp_agg_vars2;
+ u8 __agg_val3;
+ u16 __agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __agg_val2;
+ u8 __agg_val3;
+ u8 __tcp_agg_vars2;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __agg_val5;
+ u8 __agg_val6;
+ u8 __tcp_agg_vars3;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __tcp_agg_vars3;
+ u8 __agg_val6;
+ u16 __agg_val5;
+#endif
+ u32 __lcq_prod;
+ u32 rtt_seq;
+ u32 rtt_time;
+ u32 __reserved66;
+ u32 wnd_right_edge;
+ u32 tcp_agg_vars1;
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN (0x1<<9)
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN_SHIFT 9
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19)
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20)
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21)
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22)
+#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28)
+#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28
+ u32 snd_max;
+ u32 __lcq_cons;
+ u32 __reserved2;
+};
+
+/*
+ * The fcoe aggregative context of Tstorm
+ */
+struct tstorm_fcoe_ag_context {
+#if defined(__BIG_ENDIAN)
+ u16 ulp_credit;
+ u8 agg_vars1;
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4)
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4
+#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+ u8 state;
+#elif defined(__LITTLE_ENDIAN)
+ u8 state;
+ u8 agg_vars1;
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4)
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4
+#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+ u16 ulp_credit;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __agg_val4;
+ u16 agg_vars2;
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11)
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11
+#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
+#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
+#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
+#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
+#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
+#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
+#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15
+#elif defined(__LITTLE_ENDIAN)
+ u16 agg_vars2;
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10)
+#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11)
+#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11
+#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
+#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
+#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
+#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
+#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
+#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
+#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15
+ u16 __agg_val4;
+#endif
+ struct tstorm_fcoe_extra_ag_context_section __extra_section;
+};
+
+/*
+ * The fcoe aggregative context of Ustorm
+ */
+struct ustorm_fcoe_ag_context {
+#if defined(__BIG_ENDIAN)
+ u8 __aux_counter_flags;
+ u8 agg_vars2;
+#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0)
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2)
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2
+#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4)
+#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7
+ u8 agg_vars1;
+#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4)
+#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6)
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6
+ u8 state;
+#elif defined(__LITTLE_ENDIAN)
+ u8 state;
+ u8 agg_vars1;
+#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4)
+#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6)
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6
+ u8 agg_vars2;
+#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0)
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2)
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2
+#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4)
+#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7
+ u8 __aux_counter_flags;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 cdu_usage;
+ u8 agg_misc2;
+ u16 pbf_tx_seq_ack;
+#elif defined(__LITTLE_ENDIAN)
+ u16 pbf_tx_seq_ack;
+ u8 agg_misc2;
+ u8 cdu_usage;
+#endif
+ u32 agg_misc4;
+#if defined(__BIG_ENDIAN)
+ u8 agg_val3_th;
+ u8 agg_val3;
+ u16 agg_misc3;
+#elif defined(__LITTLE_ENDIAN)
+ u16 agg_misc3;
+ u8 agg_val3;
+ u8 agg_val3_th;
+#endif
+ u32 expired_task_id;
+ u32 agg_misc4_th;
+#if defined(__BIG_ENDIAN)
+ u16 cq_prod;
+ u16 cq_cons;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cq_cons;
+ u16 cq_prod;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __reserved2;
+ u8 decision_rules;
+#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0)
+#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
+#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6)
+#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7
+ u8 decision_rule_enable_bits;
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0)
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1)
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2)
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3)
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3
+#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4)
+#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4
+#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5)
+#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5
+#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6)
+#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6
+#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+#elif defined(__LITTLE_ENDIAN)
+ u8 decision_rule_enable_bits;
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0)
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1)
+#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2)
+#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3)
+#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3
+#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4)
+#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4
+#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5)
+#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5
+#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6)
+#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6
+#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+ u8 decision_rules;
+#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0)
+#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
+#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
+#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6)
+#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7)
+#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7
+ u16 __reserved2;
+#endif
+};
+
+/*
+ * Ethernet context section
+ */
+struct xstorm_fcoe_eth_context_section {
+#if defined(__BIG_ENDIAN)
+ u8 remote_addr_4;
+ u8 remote_addr_5;
+ u8 local_addr_0;
+ u8 local_addr_1;
+#elif defined(__LITTLE_ENDIAN)
+ u8 local_addr_1;
+ u8 local_addr_0;
+ u8 remote_addr_5;
+ u8 remote_addr_4;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 remote_addr_0;
+ u8 remote_addr_1;
+ u8 remote_addr_2;
+ u8 remote_addr_3;
+#elif defined(__LITTLE_ENDIAN)
+ u8 remote_addr_3;
+ u8 remote_addr_2;
+ u8 remote_addr_1;
+ u8 remote_addr_0;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 reserved_vlan_type;
+ u16 params;
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13
+#elif defined(__LITTLE_ENDIAN)
+ u16 params;
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13)
+#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13
+ u16 reserved_vlan_type;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 local_addr_2;
+ u8 local_addr_3;
+ u8 local_addr_4;
+ u8 local_addr_5;
+#elif defined(__LITTLE_ENDIAN)
+ u8 local_addr_5;
+ u8 local_addr_4;
+ u8 local_addr_3;
+ u8 local_addr_2;
+#endif
+};
+
+/*
+ * Flags used in FCoE context section - 1 byte
+ */
+struct xstorm_fcoe_context_flags {
+ u8 flags;
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q (0x3<<0)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q_SHIFT 0
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ (0x1<<2)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ_SHIFT 2
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED (0x1<<3)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED_SHIFT 3
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT (0x1<<4)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT_SHIFT 4
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE (0x1<<5)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE_SHIFT 5
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE (0x1<<6)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE_SHIFT 6
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED (0x1<<7)
+#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED_SHIFT 7
+};
+
+/*
+ * FCoE SQ element
+ */
+struct fcoe_sqe {
+ u16 wqe;
+#define FCOE_SQE_TASK_ID (0x7FFF<<0)
+#define FCOE_SQE_TASK_ID_SHIFT 0
+#define FCOE_SQE_TOGGLE_BIT (0x1<<15)
+#define FCOE_SQE_TOGGLE_BIT_SHIFT 15
+};
+
+/*
+ * FCoE XFRQ element
+ */
+struct fcoe_xfrqe {
+ u16 wqe;
+#define FCOE_XFRQE_TASK_ID (0x7FFF<<0)
+#define FCOE_XFRQE_TASK_ID_SHIFT 0
+#define FCOE_XFRQE_TOGGLE_BIT (0x1<<15)
+#define FCOE_XFRQE_TOGGLE_BIT_SHIFT 15
+};
+
+/*
+ * FCoE SQ\XFRQ element
+ */
+struct fcoe_cached_wqe {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_xfrqe xfrqe;
+ struct fcoe_sqe sqe;
+#elif defined(__LITTLE_ENDIAN)
+ struct fcoe_sqe sqe;
+ struct fcoe_xfrqe xfrqe;
+#endif
+};
+
+struct fcoe_task_ctx_entry_tx_only {
+ union fcoe_sgl_ctx sgl_ctx;
+};
+
+struct xstorm_fcoe_task_ctx_entry_rd {
+ struct fcoe_task_ctx_entry_tx_only tx_wr;
+ struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd;
+ struct fcoe_task_ctx_entry_tx_rx_cmn cmn;
+ struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd;
+};
+
+/*
+ * Cached SGEs
+ */
+struct common_fcoe_sgl {
+ struct fcoe_bd_ctx sge[2];
+};
+
+/*
+ * FCP_DATA parameters required for transmission
+ */
+struct xstorm_fcoe_fcp_data {
+ u32 io_rem;
+#if defined(__BIG_ENDIAN)
+ u16 cached_sge_off;
+ u8 cached_num_sges;
+ u8 cached_sge_idx;
+#elif defined(__LITTLE_ENDIAN)
+ u8 cached_sge_idx;
+ u8 cached_num_sges;
+ u16 cached_sge_off;
+#endif
+ struct common_fcoe_sgl cached_sgl;
+};
+
+/*
+ * FCoE context section
+ */
+struct xstorm_fcoe_context_section {
+#if defined(__BIG_ENDIAN)
+ u8 vlan_flag;
+ u8 s_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 s_id[3];
+ u8 vlan_flag;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 func_id;
+ u8 d_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 d_id[3];
+ u8 func_id;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 sq_xfrq_lcq_confq_size;
+ u16 tx_max_fc_pay_len;
+#elif defined(__LITTLE_ENDIAN)
+ u16 tx_max_fc_pay_len;
+ u16 sq_xfrq_lcq_confq_size;
+#endif
+ u32 lcq_prod;
+#if defined(__BIG_ENDIAN)
+ u8 port_id;
+ u8 tx_max_conc_seqs_c3;
+ u8 seq_id;
+ struct xstorm_fcoe_context_flags tx_flags;
+#elif defined(__LITTLE_ENDIAN)
+ struct xstorm_fcoe_context_flags tx_flags;
+ u8 seq_id;
+ u8 tx_max_conc_seqs_c3;
+ u8 port_id;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 verify_tx_seq;
+ u8 func_mode;
+ u8 vnic_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 vnic_id;
+ u8 func_mode;
+ u16 verify_tx_seq;
+#endif
+ struct regpair confq_curr_page_addr;
+ struct fcoe_cached_wqe cached_wqe[8];
+ struct regpair lcq_base_addr;
+ struct xstorm_fcoe_task_ctx_entry_rd tce;
+ struct xstorm_fcoe_fcp_data fcp_data;
+#if defined(__BIG_ENDIAN)
+ u16 fcoe_tx_stat_params_ram_addr;
+ u16 cmng_port_ram_addr;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cmng_port_ram_addr;
+ u16 fcoe_tx_stat_params_ram_addr;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 fcp_cmd_pb_cmd_size;
+ u8 eth_hdr_size;
+ u16 pbf_addr;
+#elif defined(__LITTLE_ENDIAN)
+ u16 pbf_addr;
+ u8 eth_hdr_size;
+ u8 fcp_cmd_pb_cmd_size;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 reserved2[2];
+ u8 cos;
+ u8 dcb_version;
+#elif defined(__LITTLE_ENDIAN)
+ u8 dcb_version;
+ u8 cos;
+ u8 reserved2[2];
+#endif
+ u32 reserved3;
+ struct regpair reserved4[2];
+};
+
+/*
+ * Xstorm FCoE Storm Context
+ */
+struct xstorm_fcoe_st_context {
+ struct xstorm_fcoe_eth_context_section eth;
+ struct xstorm_fcoe_context_section fcoe;
+};
+
+/*
+ * Fcoe connection context
+ */
+struct fcoe_context {
+ struct ustorm_fcoe_st_context ustorm_st_context;
+ struct tstorm_fcoe_st_context tstorm_st_context;
+ struct xstorm_fcoe_ag_context xstorm_ag_context;
+ struct tstorm_fcoe_ag_context tstorm_ag_context;
+ struct ustorm_fcoe_ag_context ustorm_ag_context;
+ struct timers_block_context timers_context;
+ struct xstorm_fcoe_st_context xstorm_st_context;
+};
+
+/*
* iSCSI context region, used only in iSCSI
*/
struct ustorm_iscsi_rq_db {
@@ -2268,6 +3792,577 @@ struct iscsi_context {
};
/*
+ * FCoE KCQ CQE parameters
+ */
+union fcoe_kcqe_params {
+ u32 reserved0[4];
+};
+
+/*
+ * FCoE KCQ CQE
+ */
+struct fcoe_kcqe {
+ u32 fcoe_conn_id;
+ u32 completion_status;
+ u32 fcoe_conn_context_id;
+ union fcoe_kcqe_params params;
+#if defined(__BIG_ENDIAN)
+ u8 flags;
+#define FCOE_KCQE_RESERVED0 (0x7<<0)
+#define FCOE_KCQE_RESERVED0_SHIFT 0
+#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3)
+#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3
+#define FCOE_KCQE_LAYER_CODE (0x7<<4)
+#define FCOE_KCQE_LAYER_CODE_SHIFT 4
+#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7)
+#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7
+ u8 op_code;
+ u16 qe_self_seq;
+#elif defined(__LITTLE_ENDIAN)
+ u16 qe_self_seq;
+ u8 op_code;
+ u8 flags;
+#define FCOE_KCQE_RESERVED0 (0x7<<0)
+#define FCOE_KCQE_RESERVED0_SHIFT 0
+#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3)
+#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3
+#define FCOE_KCQE_LAYER_CODE (0x7<<4)
+#define FCOE_KCQE_LAYER_CODE_SHIFT 4
+#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7)
+#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7
+#endif
+};
+
+/*
+ * FCoE KWQE header
+ */
+struct fcoe_kwqe_header {
+#if defined(__BIG_ENDIAN)
+ u8 flags;
+#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0)
+#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0
+#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4)
+#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4
+#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7)
+#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7
+ u8 op_code;
+#elif defined(__LITTLE_ENDIAN)
+ u8 op_code;
+ u8 flags;
+#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0)
+#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0
+#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4)
+#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4
+#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7)
+#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7
+#endif
+};
+
+/*
+ * FCoE firmware init request 1
+ */
+struct fcoe_kwqe_init1 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 num_tasks;
+#elif defined(__LITTLE_ENDIAN)
+ u16 num_tasks;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 task_list_pbl_addr_lo;
+ u32 task_list_pbl_addr_hi;
+ u32 dummy_buffer_addr_lo;
+ u32 dummy_buffer_addr_hi;
+#if defined(__BIG_ENDIAN)
+ u16 rq_num_wqes;
+ u16 sq_num_wqes;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sq_num_wqes;
+ u16 rq_num_wqes;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 cq_num_wqes;
+ u16 rq_buffer_log_size;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rq_buffer_log_size;
+ u16 cq_num_wqes;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 flags;
+#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0)
+#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0
+#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4)
+#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4
+#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7)
+#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7
+ u8 num_sessions_log;
+ u16 mtu;
+#elif defined(__LITTLE_ENDIAN)
+ u16 mtu;
+ u8 num_sessions_log;
+ u8 flags;
+#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0)
+#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0
+#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4)
+#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4
+#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7)
+#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7
+#endif
+};
+
+/*
+ * FCoE firmware init request 2
+ */
+struct fcoe_kwqe_init2 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 hash_tbl_pbl_addr_lo;
+ u32 hash_tbl_pbl_addr_hi;
+ u32 t2_hash_tbl_addr_lo;
+ u32 t2_hash_tbl_addr_hi;
+ u32 t2_ptr_hash_tbl_addr_lo;
+ u32 t2_ptr_hash_tbl_addr_hi;
+ u32 free_list_count;
+};
+
+/*
+ * FCoE firmware init request 3
+ */
+struct fcoe_kwqe_init3 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 error_bit_map_lo;
+ u32 error_bit_map_hi;
+#if defined(__BIG_ENDIAN)
+ u8 reserved21[3];
+ u8 cached_session_enable;
+#elif defined(__LITTLE_ENDIAN)
+ u8 cached_session_enable;
+ u8 reserved21[3];
+#endif
+ u32 reserved2[4];
+};
+
+/*
+ * FCoE connection offload request 1
+ */
+struct fcoe_kwqe_conn_offload1 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 fcoe_conn_id;
+#elif defined(__LITTLE_ENDIAN)
+ u16 fcoe_conn_id;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 sq_addr_lo;
+ u32 sq_addr_hi;
+ u32 rq_pbl_addr_lo;
+ u32 rq_pbl_addr_hi;
+ u32 rq_first_pbe_addr_lo;
+ u32 rq_first_pbe_addr_hi;
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u16 rq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rq_prod;
+ u16 reserved0;
+#endif
+};
+
+/*
+ * FCoE connection offload request 2
+ */
+struct fcoe_kwqe_conn_offload2 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 tx_max_fc_pay_len;
+#elif defined(__LITTLE_ENDIAN)
+ u16 tx_max_fc_pay_len;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 cq_addr_lo;
+ u32 cq_addr_hi;
+ u32 xferq_addr_lo;
+ u32 xferq_addr_hi;
+ u32 conn_db_addr_lo;
+ u32 conn_db_addr_hi;
+ u32 reserved1;
+};
+
+/*
+ * FCoE connection offload request 3
+ */
+struct fcoe_kwqe_conn_offload3 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 vlan_tag;
+#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0)
+#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0
+#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12)
+#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12
+#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13)
+#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13
+#elif defined(__LITTLE_ENDIAN)
+ u16 vlan_tag;
+#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0)
+#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0
+#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12)
+#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12
+#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13)
+#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13
+ struct fcoe_kwqe_header hdr;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 tx_max_conc_seqs_c3;
+ u8 s_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 s_id[3];
+ u8 tx_max_conc_seqs_c3;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 flags;
+#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0
+#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3
+#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4
+#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5
+#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6
+#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7
+ u8 d_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 d_id[3];
+ u8 flags;
+#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0
+#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3
+#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4
+#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5
+#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6
+#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7)
+#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7
+#endif
+ u32 reserved;
+ u32 confq_first_pbe_addr_lo;
+ u32 confq_first_pbe_addr_hi;
+#if defined(__BIG_ENDIAN)
+ u16 rx_max_fc_pay_len;
+ u16 tx_total_conc_seqs;
+#elif defined(__LITTLE_ENDIAN)
+ u16 tx_total_conc_seqs;
+ u16 rx_max_fc_pay_len;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 rx_open_seqs_exch_c3;
+ u8 rx_max_conc_seqs_c3;
+ u16 rx_total_conc_seqs;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rx_total_conc_seqs;
+ u8 rx_max_conc_seqs_c3;
+ u8 rx_open_seqs_exch_c3;
+#endif
+};
+
+/*
+ * FCoE connection offload request 4
+ */
+struct fcoe_kwqe_conn_offload4 {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u8 reserved2;
+ u8 e_d_tov_timer_val;
+#elif defined(__LITTLE_ENDIAN)
+ u8 e_d_tov_timer_val;
+ u8 reserved2;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u8 src_mac_addr_lo32[4];
+#if defined(__BIG_ENDIAN)
+ u8 dst_mac_addr_hi16[2];
+ u8 src_mac_addr_hi16[2];
+#elif defined(__LITTLE_ENDIAN)
+ u8 src_mac_addr_hi16[2];
+ u8 dst_mac_addr_hi16[2];
+#endif
+ u8 dst_mac_addr_lo32[4];
+ u32 lcq_addr_lo;
+ u32 lcq_addr_hi;
+ u32 confq_pbl_base_addr_lo;
+ u32 confq_pbl_base_addr_hi;
+};
+
+/*
+ * FCoE connection enable request
+ */
+struct fcoe_kwqe_conn_enable_disable {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u8 src_mac_addr_lo32[4];
+#if defined(__BIG_ENDIAN)
+ u16 vlan_tag;
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13
+ u8 src_mac_addr_hi16[2];
+#elif defined(__LITTLE_ENDIAN)
+ u8 src_mac_addr_hi16[2];
+ u16 vlan_tag;
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13)
+#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13
+#endif
+ u8 dst_mac_addr_lo32[4];
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 dst_mac_addr_hi16[2];
+#elif defined(__LITTLE_ENDIAN)
+ u8 dst_mac_addr_hi16[2];
+ u16 reserved1;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 vlan_flag;
+ u8 s_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 s_id[3];
+ u8 vlan_flag;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 reserved3;
+ u8 d_id[3];
+#elif defined(__LITTLE_ENDIAN)
+ u8 d_id[3];
+ u8 reserved3;
+#endif
+ u32 context_id;
+ u32 conn_id;
+ u32 reserved4;
+};
+
+/*
+ * FCoE connection destroy request
+ */
+struct fcoe_kwqe_conn_destroy {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 context_id;
+ u32 conn_id;
+ u32 reserved1[5];
+};
+
+/*
+ * FCoe destroy request
+ */
+struct fcoe_kwqe_destroy {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 reserved1[7];
+};
+
+/*
+ * FCoe statistics request
+ */
+struct fcoe_kwqe_stat {
+#if defined(__BIG_ENDIAN)
+ struct fcoe_kwqe_header hdr;
+ u16 reserved0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 reserved0;
+ struct fcoe_kwqe_header hdr;
+#endif
+ u32 stat_params_addr_lo;
+ u32 stat_params_addr_hi;
+ u32 reserved1[5];
+};
+
+/*
+ * FCoE KWQ WQE
+ */
+union fcoe_kwqe {
+ struct fcoe_kwqe_init1 init1;
+ struct fcoe_kwqe_init2 init2;
+ struct fcoe_kwqe_init3 init3;
+ struct fcoe_kwqe_conn_offload1 conn_offload1;
+ struct fcoe_kwqe_conn_offload2 conn_offload2;
+ struct fcoe_kwqe_conn_offload3 conn_offload3;
+ struct fcoe_kwqe_conn_offload4 conn_offload4;
+ struct fcoe_kwqe_conn_enable_disable conn_enable_disable;
+ struct fcoe_kwqe_conn_destroy conn_destroy;
+ struct fcoe_kwqe_destroy destroy;
+ struct fcoe_kwqe_stat statistics;
+};
+
+struct fcoe_task_ctx_entry {
+ struct fcoe_task_ctx_entry_tx_only tx_wr_only;
+ struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd;
+ struct fcoe_task_ctx_entry_tx_rx_cmn cmn;
+ struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd;
+ struct fcoe_task_ctx_entry_rx_only rx_wr_only;
+ u32 reserved[4];
+};
+
+/*
+ * FCoE connection enable\disable params passed by driver to FW in FCoE enable ramrod
+ */
+struct fcoe_conn_enable_disable_ramrod_params {
+ struct fcoe_kwqe_conn_enable_disable enable_disable_kwqe;
+};
+
+
+/*
+ * FCoE connection offload params passed by driver to FW in FCoE offload ramrod
+ */
+struct fcoe_conn_offload_ramrod_params {
+ struct fcoe_kwqe_conn_offload1 offload_kwqe1;
+ struct fcoe_kwqe_conn_offload2 offload_kwqe2;
+ struct fcoe_kwqe_conn_offload3 offload_kwqe3;
+ struct fcoe_kwqe_conn_offload4 offload_kwqe4;
+};
+
+/*
+ * FCoE init params passed by driver to FW in FCoE init ramrod
+ */
+struct fcoe_init_ramrod_params {
+ struct fcoe_kwqe_init1 init_kwqe1;
+ struct fcoe_kwqe_init2 init_kwqe2;
+ struct fcoe_kwqe_init3 init_kwqe3;
+ struct regpair eq_addr;
+ struct regpair eq_next_page_addr;
+#if defined(__BIG_ENDIAN)
+ u16 sb_num;
+ u16 eq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 eq_prod;
+ u16 sb_num;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 reserved0;
+ u8 sb_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 sb_id;
+ u8 reserved0;
+ u16 reserved1;
+#endif
+};
+
+
+/*
+ * FCoE statistics params buffer passed by driver to FW in FCoE statistics ramrod
+ */
+struct fcoe_stat_ramrod_params {
+ struct fcoe_kwqe_stat stat_kwqe;
+};
+
+
+/*
+ * FCoE 16-bits vlan structure
+ */
+struct fcoe_vlan_fields {
+ u16 fields;
+#define FCOE_VLAN_FIELDS_VID (0xFFF<<0)
+#define FCOE_VLAN_FIELDS_VID_SHIFT 0
+#define FCOE_VLAN_FIELDS_CLI (0x1<<12)
+#define FCOE_VLAN_FIELDS_CLI_SHIFT 12
+#define FCOE_VLAN_FIELDS_PRI (0x7<<13)
+#define FCOE_VLAN_FIELDS_PRI_SHIFT 13
+};
+
+
+/*
+ * FCoE 16-bits vlan union
+ */
+union fcoe_vlan_field_union {
+ struct fcoe_vlan_fields fields;
+ u16 val;
+};
+
+/*
+ * Parameters used for Class 2 verifications
+ */
+struct ustorm_fcoe_c2_params {
+#if defined(__BIG_ENDIAN)
+ u16 e2e_credit;
+ u16 con_seq;
+#elif defined(__LITTLE_ENDIAN)
+ u16 con_seq;
+ u16 e2e_credit;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 ackq_prod;
+ u16 open_seq_per_exch;
+#elif defined(__LITTLE_ENDIAN)
+ u16 open_seq_per_exch;
+ u16 ackq_prod;
+#endif
+ struct regpair ackq_pbl_base;
+ struct regpair ackq_cur_seg;
+};
+
+/*
+ * Parameters used for Class 2 verifications
+ */
+struct xstorm_fcoe_c2_params {
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u8 ackq_x_prod;
+ u8 max_conc_seqs_c2;
+#elif defined(__LITTLE_ENDIAN)
+ u8 max_conc_seqs_c2;
+ u8 ackq_x_prod;
+ u16 reserved0;
+#endif
+ struct regpair ackq_pbl_base;
+ struct regpair ackq_cur_seg;
+};
+
+/*
* Buffer per connection, used in Tstorm
*/
struct iscsi_conn_buf {
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index 0dbeaec4f03a..9f44e0ffe003 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -1,6 +1,6 @@
/* cnic_if.h: Broadcom CNIC core network driver.
*
- * Copyright (c) 2006-2010 Broadcom Corporation
+ * Copyright (c) 2006-2011 Broadcom 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
@@ -12,22 +12,31 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.2.6"
-#define CNIC_MODULE_RELDATE "Oct 12, 2010"
+#define CNIC_MODULE_VERSION "2.2.12"
+#define CNIC_MODULE_RELDATE "Jan 03, 2011"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
-#define CNIC_ULP_L4 2
-#define MAX_CNIC_ULP_TYPE_EXT 2
-#define MAX_CNIC_ULP_TYPE 3
+#define CNIC_ULP_FCOE 2
+#define CNIC_ULP_L4 3
+#define MAX_CNIC_ULP_TYPE_EXT 3
+#define MAX_CNIC_ULP_TYPE 4
struct kwqe {
u32 kwqe_op_flag;
+#define KWQE_QID_SHIFT 8
#define KWQE_OPCODE_MASK 0x00ff0000
#define KWQE_OPCODE_SHIFT 16
-#define KWQE_FLAGS_LAYER_SHIFT 28
#define KWQE_OPCODE(x) ((x & KWQE_OPCODE_MASK) >> KWQE_OPCODE_SHIFT)
+#define KWQE_LAYER_MASK 0x70000000
+#define KWQE_LAYER_SHIFT 28
+#define KWQE_FLAGS_LAYER_MASK_L2 (2<<28)
+#define KWQE_FLAGS_LAYER_MASK_L3 (3<<28)
+#define KWQE_FLAGS_LAYER_MASK_L4 (4<<28)
+#define KWQE_FLAGS_LAYER_MASK_L5_RDMA (5<<28)
+#define KWQE_FLAGS_LAYER_MASK_L5_ISCSI (6<<28)
+#define KWQE_FLAGS_LAYER_MASK_L5_FCOE (7<<28)
u32 kwqe_info0;
u32 kwqe_info1;
@@ -62,6 +71,7 @@ struct kcqe {
#define KCQE_FLAGS_LAYER_MASK_L4 (4<<28)
#define KCQE_FLAGS_LAYER_MASK_L5_RDMA (5<<28)
#define KCQE_FLAGS_LAYER_MASK_L5_ISCSI (6<<28)
+ #define KCQE_FLAGS_LAYER_MASK_L5_FCOE (7<<28)
#define KCQE_FLAGS_NEXT (1<<31)
#define KCQE_FLAGS_OPCODE_MASK (0xff<<16)
#define KCQE_FLAGS_OPCODE_SHIFT (16)
@@ -301,7 +311,7 @@ struct cnic_ulp_ops {
void (*cm_abort_complete)(struct cnic_sock *);
void (*cm_remote_close)(struct cnic_sock *);
void (*cm_remote_abort)(struct cnic_sock *);
- void (*iscsi_nl_send_msg)(struct cnic_dev *dev, u32 msg_type,
+ int (*iscsi_nl_send_msg)(void *ulp_ctx, u32 msg_type,
char *data, u16 data_size);
struct module *owner;
atomic_t ref_count;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 81475cc80e1c..80c2feeefec5 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -59,7 +59,6 @@ static struct sockaddr default_mac = {
/* Information that need to be kept for each board. */
struct net_local {
- struct net_device_stats stats;
struct mii_if_info mii_if;
/* Tx control lock. This protects the transmit buffer ring
@@ -1059,7 +1058,7 @@ e100_tx_timeout(struct net_device *dev)
/* remember we got an error */
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* reset the TX DMA in case it has hung on something */
@@ -1157,7 +1156,7 @@ e100rxtx_interrupt(int irq, void *dev_id)
* allocate a new buffer to put a packet in.
*/
e100_rx(dev);
- np->stats.rx_packets++;
+ dev->stats.rx_packets++;
/* restart/continue on the channel, for safety */
*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
/* clear dma channel 1 eop/descr irq bits */
@@ -1173,8 +1172,8 @@ e100rxtx_interrupt(int irq, void *dev_id)
/* Report any packets that have been sent */
while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST &&
(netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) {
- np->stats.tx_bytes += myFirstTxDesc->skb->len;
- np->stats.tx_packets++;
+ dev->stats.tx_bytes += myFirstTxDesc->skb->len;
+ dev->stats.tx_packets++;
/* dma is ready with the transmission of the data in tx_skb, so now
we can release the skb memory */
@@ -1197,7 +1196,6 @@ static irqreturn_t
e100nw_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct net_local *np = netdev_priv(dev);
unsigned long irqbits = *R_IRQ_MASK0_RD;
/* check for underrun irq */
@@ -1205,13 +1203,13 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet receiver underrun!\n"));
}
/* check for overrun irq */
if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) {
- update_rx_stats(&np->stats); /* this will ack the irq */
+ update_rx_stats(&dev->stats); /* this will ack the irq */
D(printk("ethernet receiver overrun!\n"));
}
/* check for excessive collision irq */
@@ -1219,7 +1217,7 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet excessive collisions!\n"));
}
return IRQ_HANDLED;
@@ -1250,7 +1248,7 @@ e100_rx(struct net_device *dev)
spin_unlock(&np->led_lock);
length = myNextRxDesc->descr.hw_len - 4;
- np->stats.rx_bytes += length;
+ dev->stats.rx_bytes += length;
#ifdef ETHDEBUG
printk("Got a packet of length %d:\n", length);
@@ -1268,7 +1266,7 @@ e100_rx(struct net_device *dev)
/* Small packet, copy data */
skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
if (!skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1294,7 +1292,7 @@ e100_rx(struct net_device *dev)
int align;
struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
if (!new_skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1333,8 +1331,6 @@ e100_rx(struct net_device *dev)
static int
e100_close(struct net_device *dev)
{
- struct net_local *np = netdev_priv(dev);
-
printk(KERN_INFO "Closing %s.\n", dev->name);
netif_stop_queue(dev);
@@ -1366,8 +1362,8 @@ e100_close(struct net_device *dev)
/* Update the statistics here. */
- update_rx_stats(&np->stats);
- update_tx_stats(&np->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
/* Stop speed/duplex timers */
del_timer(&speed_timer);
@@ -1545,11 +1541,11 @@ e100_get_stats(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- update_rx_stats(&lp->stats);
- update_tx_stats(&lp->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
spin_unlock_irqrestore(&lp->lock, flags);
- return &lp->stats;
+ return &dev->stats;
}
/*
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 35cd36729155..2028da95afa1 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -292,7 +292,7 @@ unknown:
*/
static int ael2005_setup_sr_edc(struct cphy *phy)
{
- static struct reg_val regs[] = {
+ static const struct reg_val regs[] = {
{ MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
{ MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
@@ -324,11 +324,11 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{
- static struct reg_val regs[] = {
+ static const struct reg_val regs[] = {
{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
{ 0, 0, 0, 0 }
};
- static struct reg_val preemphasis[] = {
+ static const struct reg_val preemphasis[] = {
{ MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 },
{ MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
{ 0, 0, 0, 0 }
@@ -393,7 +393,7 @@ static int ael2005_intr_clear(struct cphy *phy)
static int ael2005_reset(struct cphy *phy, int wait)
{
- static struct reg_val regs0[] = {
+ static const struct reg_val regs0[] = {
{ MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 },
{ MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 },
{ MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 },
@@ -403,7 +403,7 @@ static int ael2005_reset(struct cphy *phy, int wait)
{ MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 },
{ 0, 0, 0, 0 }
};
- static struct reg_val regs1[] = {
+ static const struct reg_val regs1[] = {
{ MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 },
{ MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 },
{ 0, 0, 0, 0 }
@@ -522,7 +522,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
*/
static int ael2020_setup_sr_edc(struct cphy *phy)
{
- static struct reg_val regs[] = {
+ static const struct reg_val regs[] = {
/* set CDR offset to 10 */
{ MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a },
@@ -551,20 +551,20 @@ static int ael2020_setup_sr_edc(struct cphy *phy)
static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
{
/* set uC to 40MHz */
- static struct reg_val uCclock40MHz[] = {
+ static const struct reg_val uCclock40MHz[] = {
{ MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 },
{ MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 },
{ 0, 0, 0, 0 }
};
/* activate uC clock */
- static struct reg_val uCclockActivate[] = {
+ static const struct reg_val uCclockActivate[] = {
{ MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 },
{ 0, 0, 0, 0 }
};
/* set PC to start of SRAM and activate uC */
- static struct reg_val uCactivate[] = {
+ static const struct reg_val uCactivate[] = {
{ MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 },
{ MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 },
{ 0, 0, 0, 0 }
@@ -624,7 +624,7 @@ static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
*/
static int ael2020_intr_enable(struct cphy *phy)
{
- struct reg_val regs[] = {
+ static const struct reg_val regs[] = {
/* output Module's Loss Of Signal (LOS) to LED */
{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
0xffff, 0x4 },
@@ -664,7 +664,7 @@ static int ael2020_intr_enable(struct cphy *phy)
*/
static int ael2020_intr_disable(struct cphy *phy)
{
- struct reg_val regs[] = {
+ static const struct reg_val regs[] = {
/* reset "link status" LED to "off" */
{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
@@ -701,7 +701,7 @@ static int ael2020_intr_clear(struct cphy *phy)
return err ? err : t3_phy_lasi_intr_clear(phy);
}
-static struct reg_val ael2020_reset_regs[] = {
+static const struct reg_val ael2020_reset_regs[] = {
/* Erratum #2: CDRLOL asserted, causing PMA link down status */
{ MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 046d846c652d..4d538a4e9d55 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1359,6 +1359,7 @@ out:
static int offload_close(struct t3cdev *tdev)
{
struct adapter *adapter = tdev2adap(tdev);
+ struct t3c_data *td = T3C_DATA(tdev);
if (!test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
return 0;
@@ -1369,7 +1370,7 @@ static int offload_close(struct t3cdev *tdev)
sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
/* Flush work scheduled while releasing TIDs */
- flush_scheduled_work();
+ flush_work_sync(&td->tid_release_task);
tdev->lldev = NULL;
cxgb3_set_dummy_ops(tdev);
@@ -3006,12 +3007,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct adapter *adapter = pci_get_drvdata(pdev);
- int ret;
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
- ret = t3_adapter_error(adapter, 0, 0);
+ t3_adapter_error(adapter, 0, 0);
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index bcf07532953d..ef02aa68c926 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1164,12 +1164,10 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
*/
void *cxgb_alloc_mem(unsigned long size)
{
- void *p = kmalloc(size, GFP_KERNEL);
+ void *p = kzalloc(size, GFP_KERNEL);
if (!p)
- p = vmalloc(size);
- if (p)
- memset(p, 0, size);
+ p = vzalloc(size);
return p;
}
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 3a6adf0b3e9d..ec8579a0a808 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1562,7 +1562,7 @@ static void tp_intr_handler(struct adapter *adapter)
{0}
};
- static struct intr_info tp_intr_info_t3c[] = {
+ static const struct intr_info tp_intr_info_t3c[] = {
{0x1fffffff, "TP parity error", -1, 1},
{F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1},
{F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1},
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 3d4253d311eb..01d49eaa44d2 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -482,11 +482,9 @@ struct adapter {
void __iomem *regs;
struct pci_dev *pdev;
struct device *pdev_dev;
- unsigned long registered_device_map;
unsigned int fn;
unsigned int flags;
- const char *name;
int msg_enable;
struct adapter_params params;
@@ -497,7 +495,7 @@ struct adapter {
struct {
unsigned short vec;
- char desc[14];
+ char desc[IFNAMSIZ + 10];
} msix_info[MAX_INGQ + 1];
struct sge sge;
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index f50bc98310f8..059c1eec8c3f 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -522,39 +522,33 @@ static irqreturn_t t4_nondata_intr(int irq, void *cookie)
*/
static void name_msix_vecs(struct adapter *adap)
{
- int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1;
+ int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc);
/* non-data interrupts */
- snprintf(adap->msix_info[0].desc, n, "%s", adap->name);
- adap->msix_info[0].desc[n] = 0;
+ snprintf(adap->msix_info[0].desc, n, "%s", adap->port[0]->name);
/* FW events */
- snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name);
- adap->msix_info[1].desc[n] = 0;
+ snprintf(adap->msix_info[1].desc, n, "%s-FWeventq",
+ adap->port[0]->name);
/* 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++) {
+ 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;
- }
+ for_each_ofldrxq(&adap->sge, i)
+ snprintf(adap->msix_info[msi_idx++].desc, n, "%s-ofld%d",
+ adap->port[0]->name, i);
+
+ for_each_rdmarxq(&adap->sge, i)
+ snprintf(adap->msix_info[msi_idx++].desc, n, "%s-rdma%d",
+ adap->port[0]->name, i);
}
static int request_msix_queue_irqs(struct adapter *adap)
@@ -868,12 +862,10 @@ out: release_firmware(fw);
*/
void *t4_alloc_mem(size_t size)
{
- void *p = kmalloc(size, GFP_KERNEL);
+ void *p = kzalloc(size, GFP_KERNEL);
if (!p)
- p = vmalloc(size);
- if (p)
- memset(p, 0, size);
+ p = vzalloc(size);
return p;
}
@@ -1377,7 +1369,12 @@ static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
} else if (type == FW_PORT_TYPE_KR)
v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
else if (type == FW_PORT_TYPE_BP_AP)
- v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC;
+ v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC |
+ SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full;
+ else if (type == FW_PORT_TYPE_BP4_AP)
+ v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC |
+ SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full |
+ SUPPORTED_10000baseKX4_Full;
else if (type == FW_PORT_TYPE_FIBER_XFI ||
type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP)
v |= SUPPORTED_FIBRE;
@@ -2668,7 +2665,7 @@ static int cxgb_up(struct adapter *adap)
} else {
err = request_irq(adap->pdev->irq, t4_intr_handler(adap),
(adap->flags & USING_MSI) ? 0 : IRQF_SHARED,
- adap->name, adap);
+ adap->port[0]->name, adap);
if (err)
goto irq_err;
}
@@ -2719,10 +2716,6 @@ static int cxgb_open(struct net_device *dev)
return err;
}
- netif_set_real_num_tx_queues(dev, pi->nqsets);
- err = netif_set_real_num_rx_queues(dev, pi->nqsets);
- if (err)
- return err;
err = link_start(dev);
if (!err)
netif_tx_start_all_queues(dev);
@@ -3491,49 +3484,53 @@ static int __devinit init_rss(struct adapter *adap)
return 0;
}
-static void __devinit print_port_info(struct adapter *adap)
+static void __devinit print_port_info(const struct net_device *dev)
{
static const char *base[] = {
"R XFI", "R XAUI", "T SGMII", "T XFI", "T XAUI", "KX4", "CX4",
- "KX", "KR", "KR SFP+", "KR FEC"
+ "KX", "KR", "R SFP+", "KR/KX", "KR/KX/KX4"
};
- int i;
char buf[80];
+ char *bufp = buf;
const char *spd = "";
+ const struct port_info *pi = netdev_priv(dev);
+ const struct adapter *adap = pi->adapter;
if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_2_5GB)
spd = " 2.5 GT/s";
else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB)
spd = " 5 GT/s";
- for_each_port(adap, i) {
- struct net_device *dev = adap->port[i];
- const struct port_info *pi = netdev_priv(dev);
- char *bufp = buf;
+ 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]);
- if (!test_bit(i, &adap->registered_device_map))
- continue;
+ netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n",
+ adap->params.vpd.id, adap->params.rev, buf,
+ is_offload(adap) ? "R" : "", adap->params.pci.width, spd,
+ (adap->flags & USING_MSIX) ? " MSI-X" :
+ (adap->flags & USING_MSI) ? " MSI" : "");
+ netdev_info(dev, "S/N: %s, E/C: %s\n",
+ adap->params.vpd.sn, adap->params.vpd.ec);
+}
- 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]);
+static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev)
+{
+ u16 v;
+ int pos;
- netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n",
- adap->params.vpd.id, adap->params.rev,
- buf, is_offload(adap) ? "R" : "",
- adap->params.pci.width, spd,
- (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);
+ pos = pci_pcie_cap(dev);
+ if (pos > 0) {
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v);
+ v |= PCI_EXP_DEVCTL_RELAX_EN;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v);
}
}
@@ -3611,6 +3608,7 @@ static int __devinit init_one(struct pci_dev *pdev,
}
pci_enable_pcie_error_reporting(pdev);
+ enable_pcie_relaxed_ordering(pdev);
pci_set_master(pdev);
pci_save_state(pdev);
@@ -3630,7 +3628,6 @@ static int __devinit init_one(struct pci_dev *pdev,
adapter->pdev = pdev;
adapter->pdev_dev = &pdev->dev;
adapter->fn = func;
- adapter->name = pci_name(pdev);
adapter->msg_enable = dflt_msg_enable;
memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
@@ -3721,27 +3718,24 @@ static int __devinit init_one(struct pci_dev *pdev,
* register at least one net device.
*/
for_each_port(adapter, i) {
+ pi = adap2pinfo(adapter, i);
+ netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets);
+ netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets);
+
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;
- }
+ break;
+ adapter->chan_map[pi->tx_chan] = i;
+ print_port_info(adapter->port[i]);
}
- if (!adapter->registered_device_map) {
+ if (i == 0) {
dev_err(&pdev->dev, "could not register any net devices\n");
goto out_free_dev;
}
+ if (err) {
+ dev_warn(&pdev->dev, "only %d net devices registered\n", i);
+ err = 0;
+ };
if (cxgb4_debugfs_root) {
adapter->debugfs_root = debugfs_create_dir(pci_name(pdev),
@@ -3752,8 +3746,6 @@ static int __devinit init_one(struct pci_dev *pdev,
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)
@@ -3792,7 +3784,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
detach_ulds(adapter);
for_each_port(adapter, i)
- if (test_bit(i, &adapter->registered_device_map))
+ if (adapter->port[i]->reg_state == NETREG_REGISTERED)
unregister_netdev(adapter->port[i]);
if (adapter->debugfs_root)
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
index 17022258ed68..311471b439a8 100644
--- a/drivers/net/cxgb4/sge.c
+++ b/drivers/net/cxgb4/sge.c
@@ -579,6 +579,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
* @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
+ * @node: preferred node for memory allocations
*
* Allocates resources for an SGE descriptor ring, such as Tx queues,
* free buffer lists, or response queues. Each SGE ring requires
@@ -590,7 +591,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
*/
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 stat_size, int node)
{
size_t len = nelem * elem_size + stat_size;
void *s = NULL;
@@ -599,7 +600,7 @@ static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size,
if (!p)
return NULL;
if (sw_size) {
- s = kcalloc(nelem, sw_size, GFP_KERNEL);
+ s = kzalloc_node(nelem * sw_size, GFP_KERNEL, node);
if (!s) {
dma_free_coherent(dev, len, p, *phys);
@@ -1982,7 +1983,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
iq->size = roundup(iq->size, 16);
iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0,
- &iq->phys_addr, NULL, 0);
+ &iq->phys_addr, NULL, 0, NUMA_NO_NODE);
if (!iq->desc)
return -ENOMEM;
@@ -2008,12 +2009,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
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);
+ &fl->sdesc, STAT_LEN, NUMA_NO_NODE);
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_FL0FETCHRO(1) |
+ FW_IQ_CMD_FL0DATARO(1) |
FW_IQ_CMD_FL0PADEN);
c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) |
FW_IQ_CMD_FL0FBMAX(3));
@@ -2093,7 +2096,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
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);
+ &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN,
+ netdev_queue_numa_node_read(netdevq));
if (!txq->q.desc)
return -ENOMEM;
@@ -2106,6 +2110,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
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_FETCHRO(1) |
FW_EQ_ETH_CMD_IQID(iqid));
c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) |
FW_EQ_ETH_CMD_FBMAX(3) |
@@ -2144,7 +2149,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
txq->q.desc = alloc_ring(adap->pdev_dev, nentries,
sizeof(struct tx_desc), 0, &txq->q.phys_addr,
- NULL, 0);
+ NULL, 0, NUMA_NO_NODE);
if (!txq->q.desc)
return -ENOMEM;
@@ -2158,6 +2163,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
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_FETCHRO |
FW_EQ_CTRL_CMD_IQID(iqid));
c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) |
FW_EQ_CTRL_CMD_FBMAX(3) |
@@ -2194,7 +2200,8 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
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);
+ &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN,
+ NUMA_NO_NODE);
if (!txq->q.desc)
return -ENOMEM;
@@ -2207,6 +2214,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
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_FETCHRO(1) |
FW_EQ_OFLD_CMD_IQID(iqid));
c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) |
FW_EQ_OFLD_CMD_FBMAX(3) |
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index bb813d94aea8..b9fd8a6f2cc4 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -183,7 +183,7 @@ static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg)
int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
void *rpl, bool sleep_ok)
{
- static int delay[] = {
+ static const int delay[] = {
1, 1, 3, 5, 10, 10, 20, 50, 100, 200
};
@@ -330,18 +330,6 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
return 0;
}
-/*
- * Partial EEPROM Vital Product Data structure. Includes only the ID and
- * VPD-R header.
- */
-struct t4_vpd_hdr {
- u8 id_tag;
- u8 id_len[2];
- u8 id_data[ID_LEN];
- u8 vpdr_tag;
- u8 vpdr_len[2];
-};
-
#define EEPROM_STAT_ADDR 0x7bfc
#define VPD_BASE 0
#define VPD_LEN 512
@@ -370,25 +358,38 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
{
int i, ret;
- int ec, sn, v2;
+ int ec, sn;
u8 vpd[VPD_LEN], csum;
- unsigned int vpdr_len;
- const struct t4_vpd_hdr *v;
+ unsigned int vpdr_len, kw_offset, id_len;
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd);
if (ret < 0)
return ret;
- v = (const struct t4_vpd_hdr *)vpd;
- vpdr_len = pci_vpd_lrdt_size(&v->vpdr_tag);
- if (vpdr_len + sizeof(struct t4_vpd_hdr) > VPD_LEN) {
+ if (vpd[0] != PCI_VPD_LRDT_ID_STRING) {
+ dev_err(adapter->pdev_dev, "missing VPD ID string\n");
+ return -EINVAL;
+ }
+
+ id_len = pci_vpd_lrdt_size(vpd);
+ if (id_len > ID_LEN)
+ id_len = ID_LEN;
+
+ i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+ if (i < 0) {
+ dev_err(adapter->pdev_dev, "missing VPD-R section\n");
+ return -EINVAL;
+ }
+
+ vpdr_len = pci_vpd_lrdt_size(&vpd[i]);
+ kw_offset = i + PCI_VPD_LRDT_TAG_SIZE;
+ if (vpdr_len + kw_offset > VPD_LEN) {
dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
return -EINVAL;
}
#define FIND_VPD_KW(var, name) do { \
- var = pci_vpd_find_info_keyword(&v->id_tag, sizeof(struct t4_vpd_hdr), \
- vpdr_len, name); \
+ var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \
if (var < 0) { \
dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
return -EINVAL; \
@@ -408,11 +409,9 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
FIND_VPD_KW(ec, "EC");
FIND_VPD_KW(sn, "SN");
- FIND_VPD_KW(v2, "V2");
#undef FIND_VPD_KW
- p->cclk = simple_strtoul(vpd + v2, NULL, 10);
- memcpy(p->id, v->id_data, ID_LEN);
+ memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len);
strim(p->id);
memcpy(p->ec, vpd + ec, EC_LEN);
strim(p->ec);
@@ -919,7 +918,7 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
*/
static void pcie_intr_handler(struct adapter *adapter)
{
- static struct intr_info sysbus_intr_info[] = {
+ static const 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 },
@@ -927,7 +926,7 @@ static void pcie_intr_handler(struct adapter *adapter)
{ RFTP, "RXFT array parity error", -1, 1 },
{ 0 }
};
- static struct intr_info pcie_port_intr_info[] = {
+ static const 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 },
@@ -939,7 +938,7 @@ static void pcie_intr_handler(struct adapter *adapter)
{ TDUE, "Tx uncorrectable data error", -1, 1 },
{ 0 }
};
- static struct intr_info pcie_intr_info[] = {
+ static const 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 },
@@ -991,7 +990,7 @@ static void pcie_intr_handler(struct adapter *adapter)
*/
static void tp_intr_handler(struct adapter *adapter)
{
- static struct intr_info tp_intr_info[] = {
+ static const struct intr_info tp_intr_info[] = {
{ 0x3fffffff, "TP parity error", -1, 1 },
{ FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 },
{ 0 }
@@ -1008,7 +1007,7 @@ static void sge_intr_handler(struct adapter *adapter)
{
u64 v;
- static struct intr_info sge_intr_info[] = {
+ static const struct intr_info sge_intr_info[] = {
{ ERR_CPL_EXCEED_IQE_SIZE,
"SGE received CPL exceeding IQE size", -1, 1 },
{ ERR_INVALID_CIDX_INC,
@@ -1053,7 +1052,7 @@ static void sge_intr_handler(struct adapter *adapter)
*/
static void cim_intr_handler(struct adapter *adapter)
{
- static struct intr_info cim_intr_info[] = {
+ static const 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 },
@@ -1063,7 +1062,7 @@ static void cim_intr_handler(struct adapter *adapter)
{ TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 },
{ 0 }
};
- static struct intr_info cim_upintr_info[] = {
+ static const 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 },
@@ -1110,7 +1109,7 @@ static void cim_intr_handler(struct adapter *adapter)
*/
static void ulprx_intr_handler(struct adapter *adapter)
{
- static struct intr_info ulprx_intr_info[] = {
+ static const struct intr_info ulprx_intr_info[] = {
{ 0x1800000, "ULPRX context error", -1, 1 },
{ 0x7fffff, "ULPRX parity error", -1, 1 },
{ 0 }
@@ -1125,7 +1124,7 @@ static void ulprx_intr_handler(struct adapter *adapter)
*/
static void ulptx_intr_handler(struct adapter *adapter)
{
- static struct intr_info ulptx_intr_info[] = {
+ static const 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,
@@ -1147,7 +1146,7 @@ static void ulptx_intr_handler(struct adapter *adapter)
*/
static void pmtx_intr_handler(struct adapter *adapter)
{
- static struct intr_info pmtx_intr_info[] = {
+ static const 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 },
@@ -1169,7 +1168,7 @@ static void pmtx_intr_handler(struct adapter *adapter)
*/
static void pmrx_intr_handler(struct adapter *adapter)
{
- static struct intr_info pmrx_intr_info[] = {
+ static const 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 },
@@ -1188,7 +1187,7 @@ static void pmrx_intr_handler(struct adapter *adapter)
*/
static void cplsw_intr_handler(struct adapter *adapter)
{
- static struct intr_info cplsw_intr_info[] = {
+ static const 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 },
@@ -1207,7 +1206,7 @@ static void cplsw_intr_handler(struct adapter *adapter)
*/
static void le_intr_handler(struct adapter *adap)
{
- static struct intr_info le_intr_info[] = {
+ static const 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 },
@@ -1225,11 +1224,11 @@ static void le_intr_handler(struct adapter *adap)
*/
static void mps_intr_handler(struct adapter *adapter)
{
- static struct intr_info mps_rx_intr_info[] = {
+ static const struct intr_info mps_rx_intr_info[] = {
{ 0xffffff, "MPS Rx parity error", -1, 1 },
{ 0 }
};
- static struct intr_info mps_tx_intr_info[] = {
+ static const 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 },
@@ -1239,25 +1238,25 @@ static void mps_intr_handler(struct adapter *adapter)
{ FRMERR, "MPS Tx framing error", -1, 1 },
{ 0 }
};
- static struct intr_info mps_trc_intr_info[] = {
+ static const 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[] = {
+ static const 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[] = {
+ static const 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[] = {
+ static const 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[] = {
+ static const 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 },
@@ -1356,7 +1355,7 @@ static void ma_intr_handler(struct adapter *adap)
*/
static void smb_intr_handler(struct adapter *adap)
{
- static struct intr_info smb_intr_info[] = {
+ static const 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 },
@@ -1372,7 +1371,7 @@ static void smb_intr_handler(struct adapter *adap)
*/
static void ncsi_intr_handler(struct adapter *adap)
{
- static struct intr_info ncsi_intr_info[] = {
+ static const 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 },
@@ -1410,7 +1409,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port)
*/
static void pl_intr_handler(struct adapter *adap)
{
- static struct intr_info pl_intr_info[] = {
+ static const struct intr_info pl_intr_info[] = {
{ FATALPERR, "T4 fatal parity error", -1, 1 },
{ PERRVFID, "PL VFID_MAP parity error", -1, 1 },
{ 0 }
@@ -2408,7 +2407,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
if (index < NEXACT_MAC)
ret++;
else if (hash)
- *hash |= (1 << hash_mac_addr(addr[i]));
+ *hash |= (1ULL << hash_mac_addr(addr[i]));
}
return ret;
}
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
index 940584a8a640..edcfd7ec7802 100644
--- a/drivers/net/cxgb4/t4fw_api.h
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -1239,6 +1239,7 @@ enum fw_port_type {
FW_PORT_TYPE_KR,
FW_PORT_TYPE_SFP,
FW_PORT_TYPE_BP_AP,
+ FW_PORT_TYPE_BP4_AP,
FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK
};
diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h
index 8ea01962e045..4766b4116b41 100644
--- a/drivers/net/cxgb4vf/adapter.h
+++ b/drivers/net/cxgb4vf/adapter.h
@@ -60,7 +60,7 @@ enum {
* MSI-X interrupt index usage.
*/
MSIX_FW = 0, /* MSI-X index for firmware Q */
- MSIX_NIQFLINT = 1, /* MSI-X index base for Ingress Qs */
+ MSIX_IQFLINT = 1, /* MSI-X index base for Ingress Qs */
MSIX_EXTRAS = 1,
MSIX_ENTRIES = MAX_ETH_QSETS + MSIX_EXTRAS,
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index d887a76cd39d..3c403f895750 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -280,9 +280,7 @@ static void name_msix_vecs(struct adapter *adapter)
const struct port_info *pi = netdev_priv(dev);
int qs, msi;
- for (qs = 0, msi = MSIX_NIQFLINT;
- qs < pi->nqsets;
- qs++, msi++) {
+ for (qs = 0, msi = MSIX_IQFLINT; qs < pi->nqsets; qs++, msi++) {
snprintf(adapter->msix_info[msi].desc, namelen,
"%s-%d", dev->name, qs);
adapter->msix_info[msi].desc[namelen] = 0;
@@ -309,7 +307,7 @@ static int request_msix_queue_irqs(struct adapter *adapter)
/*
* Ethernet queues.
*/
- msi = MSIX_NIQFLINT;
+ msi = MSIX_IQFLINT;
for_each_ethrxq(s, rxq) {
err = request_irq(adapter->msix_info[msi].vec,
t4vf_sge_intr_msix, 0,
@@ -337,7 +335,7 @@ static void free_msix_queue_irqs(struct adapter *adapter)
int rxq, msi;
free_irq(adapter->msix_info[MSIX_FW].vec, &s->fw_evtq);
- msi = MSIX_NIQFLINT;
+ msi = MSIX_IQFLINT;
for_each_ethrxq(s, rxq)
free_irq(adapter->msix_info[msi++].vec,
&s->ethrxq[rxq].rspq);
@@ -527,7 +525,7 @@ static int setup_sge_queues(struct adapter *adapter)
* brought up at which point lots of things get nailed down
* permanently ...
*/
- msix = MSIX_NIQFLINT;
+ msix = MSIX_IQFLINT;
for_each_port(adapter, pidx) {
struct net_device *dev = adapter->port[pidx];
struct port_info *pi = netdev_priv(dev);
@@ -1365,6 +1363,8 @@ struct queue_port_stats {
u64 rx_csum;
u64 vlan_ex;
u64 vlan_ins;
+ u64 lro_pkts;
+ u64 lro_merged;
};
/*
@@ -1402,6 +1402,8 @@ static const char stats_strings[][ETH_GSTRING_LEN] = {
"RxCsumGood ",
"VLANextractions ",
"VLANinsertions ",
+ "GROPackets ",
+ "GROMerged ",
};
/*
@@ -1451,6 +1453,8 @@ static void collect_sge_port_stats(const struct adapter *adapter,
stats->rx_csum += rxq->stats.rx_cso;
stats->vlan_ex += rxq->stats.vlan_ex;
stats->vlan_ins += txq->vlan_ins;
+ stats->lro_pkts += rxq->stats.lro_pkts;
+ stats->lro_merged += rxq->stats.lro_merged;
}
}
@@ -1547,14 +1551,19 @@ static void cxgb4vf_get_wol(struct net_device *dev,
}
/*
+ * TCP Segmentation Offload flags which we support.
+ */
+#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
+
+/*
* Set TCP Segmentation Offloading feature capabilities.
*/
static int cxgb4vf_set_tso(struct net_device *dev, u32 tso)
{
if (tso)
- dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+ dev->features |= TSO_FLAGS;
else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+ dev->features &= ~TSO_FLAGS;
return 0;
}
@@ -2045,7 +2054,7 @@ static int __devinit setup_debugfs(struct adapter *adapter)
* Tear down the /sys/kernel/debug/cxgb4vf sub-nodes created above. We leave
* it to our caller to tear down the directory (debugfs_root).
*/
-static void __devexit cleanup_debugfs(struct adapter *adapter)
+static void cleanup_debugfs(struct adapter *adapter)
{
BUG_ON(adapter->debugfs_root == NULL);
@@ -2063,7 +2072,7 @@ static void __devexit cleanup_debugfs(struct adapter *adapter)
* adapter parameters we're going to be using and initialize basic adapter
* hardware support.
*/
-static int adap_init0(struct adapter *adapter)
+static int __devinit adap_init0(struct adapter *adapter)
{
struct vf_resources *vfres = &adapter->params.vfres;
struct sge_params *sge_params = &adapter->params.sge;
@@ -2269,6 +2278,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
{
struct sge *s = &adapter->sge;
int q10g, n10g, qidx, pidx, qs;
+ size_t iqe_size;
/*
* We should not be called till we know how many Queue Sets we can
@@ -2313,6 +2323,13 @@ static void __devinit cfg_queues(struct adapter *adapter)
s->ethqsets = qidx;
/*
+ * The Ingress Queue Entry Size for our various Response Queues needs
+ * to be big enough to accommodate the largest message we can receive
+ * from the chip/firmware; which is 64 bytes ...
+ */
+ iqe_size = 64;
+
+ /*
* Set up default Queue Set parameters ... Start off with the
* shortest interrupt holdoff timer.
*/
@@ -2320,7 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
struct sge_eth_rxq *rxq = &s->ethrxq[qs];
struct sge_eth_txq *txq = &s->ethtxq[qs];
- init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES);
+ init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size);
rxq->fl.size = 72;
txq->q.size = 1024;
}
@@ -2329,8 +2346,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
* The firmware event queue is used for link state changes and
* notifications of TX DMA completions.
*/
- init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512,
- L1_CACHE_BYTES);
+ init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size);
/*
* The forwarded interrupt queue is used when we're in MSI interrupt
@@ -2346,7 +2362,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
* any time ...
*/
init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1,
- L1_CACHE_BYTES);
+ iqe_size);
}
/*
@@ -2487,7 +2503,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
version_printed = 1;
}
-
/*
* Initialize generic PCI device state.
*/
@@ -2624,7 +2639,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
netdev->irq = pdev->irq;
- netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+ netdev->features = (NETIF_F_SG | TSO_FLAGS |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
NETIF_F_GRO);
diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index ecf0770bf0ff..e0b3d1bc2fdf 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -1568,6 +1568,9 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
} else
skb_checksum_none_assert(skb);
+ /*
+ * Deliver the packet to the stack.
+ */
if (unlikely(pkt->vlan_ex)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -2143,7 +2146,7 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq,
/*
* Calculate the size of the hardware free list ring plus
- * status page (which the SGE will place at the end of the
+ * Status Page (which the SGE will place after the end of the
* free list ring) in Egress Queue Units.
*/
flsz = (fl->size / FL_PER_EQ_UNIT +
@@ -2240,8 +2243,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq,
struct port_info *pi = netdev_priv(dev);
/*
- * Calculate the size of the hardware TX Queue (including the
- * status age on the end) in units of TX Descriptors.
+ * Calculate the size of the hardware TX Queue (including the Status
+ * Page on the end of the TX Queue) in units of TX Descriptors.
*/
nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c
index 19520afe1a12..e4bec78c8e3f 100644
--- a/drivers/net/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/cxgb4vf/t4vf_hw.c
@@ -116,7 +116,7 @@ static void dump_mbox(struct adapter *adapter, const char *tag, u32 mbox_data)
int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size,
void *rpl, bool sleep_ok)
{
- static int delay[] = {
+ static const int delay[] = {
1, 1, 3, 5, 10, 10, 20, 50, 100
};
@@ -1300,7 +1300,7 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid)
*/
int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
{
- struct fw_cmd_hdr *cmd_hdr = (struct fw_cmd_hdr *)rpl;
+ const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl;
u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi));
switch (opcode) {
@@ -1308,7 +1308,8 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
/*
* Link/module state change message.
*/
- const struct fw_port_cmd *port_cmd = (void *)rpl;
+ const struct fw_port_cmd *port_cmd =
+ (const struct fw_port_cmd *)rpl;
u32 word;
int action, port_id, link_ok, speed, fc, pidx;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 91b3846ffc8a..1b48b68ad4fd 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1513,7 +1513,7 @@ static enum depca_type __init depca_shmem_probe (ulong *mem_start)
return adapter;
}
-static int __init depca_isa_probe (struct platform_device *device)
+static int __devinit depca_isa_probe (struct platform_device *device)
{
struct net_device *dev;
struct depca_private *lp;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 9f6aeefa06bf..2d4c4fc1d900 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1675,7 +1675,7 @@ dm9000_drv_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
- dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev));
+ dm9000_release_board(pdev, netdev_priv(ndev));
free_netdev(ndev); /* free device structure */
dev_dbg(&pdev->dev, "released and freed device\n");
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index c7e242b69a18..77d08e697b74 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -4892,11 +4892,11 @@ static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
} else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
u16 cur_agc_value;
u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
- u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- { IGP01E1000_PHY_AGC_A,
- IGP01E1000_PHY_AGC_B,
- IGP01E1000_PHY_AGC_C,
- IGP01E1000_PHY_AGC_D
+ static const u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
+ IGP01E1000_PHY_AGC_A,
+ IGP01E1000_PHY_AGC_B,
+ IGP01E1000_PHY_AGC_C,
+ IGP01E1000_PHY_AGC_D
};
/* Read the AGC registers for all channels */
for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
@@ -5071,11 +5071,11 @@ static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
{
s32 ret_val;
u16 phy_data, phy_saved_data, speed, duplex, i;
- u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- { IGP01E1000_PHY_AGC_PARAM_A,
- IGP01E1000_PHY_AGC_PARAM_B,
- IGP01E1000_PHY_AGC_PARAM_C,
- IGP01E1000_PHY_AGC_PARAM_D
+ static const u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
+ IGP01E1000_PHY_AGC_PARAM_A,
+ IGP01E1000_PHY_AGC_PARAM_B,
+ IGP01E1000_PHY_AGC_PARAM_C,
+ IGP01E1000_PHY_AGC_PARAM_D
};
u16 min_length, max_length;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 4d62f7bfa036..340e12d2e4a9 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -971,11 +971,13 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
*/
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
pci_using_dac = 1;
- } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
- dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
} else {
- pr_err("No usable DMA config, aborting\n");
- goto err_dma;
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (err) {
+ pr_err("No usable DMA config, aborting\n");
+ goto err_dma;
+ }
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
}
netdev->netdev_ops = &e1000_netdev_ops;
@@ -1429,13 +1431,12 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
int size;
size = sizeof(struct e1000_buffer) * txdr->count;
- txdr->buffer_info = vmalloc(size);
+ txdr->buffer_info = vzalloc(size);
if (!txdr->buffer_info) {
e_err(probe, "Unable to allocate memory for the Tx descriptor "
"ring\n");
return -ENOMEM;
}
- memset(txdr->buffer_info, 0, size);
/* round up to nearest 4K */
@@ -1625,13 +1626,12 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
int size, desc_len;
size = sizeof(struct e1000_buffer) * rxdr->count;
- rxdr->buffer_info = vmalloc(size);
+ rxdr->buffer_info = vzalloc(size);
if (!rxdr->buffer_info) {
e_err(probe, "Unable to allocate memory for the Rx descriptor "
"ring\n");
return -ENOMEM;
}
- memset(rxdr->buffer_info, 0, size);
desc_len = sizeof(struct e1000_rx_desc);
@@ -2726,7 +2726,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
break;
}
- css = skb_transport_offset(skb);
+ css = skb_checksum_start_offset(skb);
i = tx_ring->next_to_use;
buffer_info = &tx_ring->buffer_info[i];
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 10d8d98bb797..1301eba8b57a 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -352,12 +352,13 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
{ /* Flow Control */
- struct e1000_opt_list fc_list[] =
- {{ E1000_FC_NONE, "Flow Control Disabled" },
- { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
- { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
- { E1000_FC_FULL, "Flow Control Enabled" },
- { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
+ static const struct e1000_opt_list fc_list[] = {
+ { E1000_FC_NONE, "Flow Control Disabled" },
+ { E1000_FC_RX_PAUSE, "Flow Control Receive Only" },
+ { E1000_FC_TX_PAUSE, "Flow Control Transmit Only" },
+ { E1000_FC_FULL, "Flow Control Enabled" },
+ { E1000_FC_DEFAULT, "Flow Control Hardware Default" }
+ };
opt = (struct e1000_option) {
.type = list_option,
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 7236f1a53ba0..e57e4097ef1b 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -52,6 +52,7 @@
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */
#define E1000_BASE1000T_STATUS 10
#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
#define E1000_RECEIVE_ERROR_COUNTER 21
@@ -74,6 +75,9 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
static s32 e1000_led_on_82574(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
/**
* e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -107,6 +111,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
case e1000_82574:
case e1000_82583:
phy->type = e1000_phy_bm;
+ phy->ops.acquire = e1000_get_hw_semaphore_82574;
+ phy->ops.release = e1000_put_hw_semaphore_82574;
break;
default:
return -E1000_ERR_PHY;
@@ -200,6 +206,17 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
break;
}
+ /* Function Pointers */
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
+ nvm->ops.acquire = e1000_get_hw_semaphore_82574;
+ nvm->ops.release = e1000_put_hw_semaphore_82574;
+ break;
+ default:
+ break;
+ }
+
return 0;
}
@@ -542,6 +559,94 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
ew32(SWSM, swsm);
}
+/**
+ * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore during reset.
+ *
+ **/
+static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
+{
+ u32 extcnf_ctrl;
+ s32 ret_val = 0;
+ s32 i = 0;
+
+ extcnf_ctrl = er32(EXTCNF_CTRL);
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+ do {
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
+ extcnf_ctrl = er32(EXTCNF_CTRL);
+
+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
+ break;
+
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+
+ msleep(2);
+ i++;
+ } while (i < MDIO_OWNERSHIP_TIMEOUT);
+
+ if (i == MDIO_OWNERSHIP_TIMEOUT) {
+ /* Release semaphores */
+ e1000_put_hw_semaphore_82573(hw);
+ e_dbg("Driver can't access the PHY\n");
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_put_hw_semaphore_82573 - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used during reset.
+ *
+ **/
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
+{
+ u32 extcnf_ctrl;
+
+ extcnf_ctrl = er32(EXTCNF_CTRL);
+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
+}
+
+static DEFINE_MUTEX(swflag_mutex);
+
+/**
+ * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore to access the PHY or NVM.
+ *
+ **/
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
+{
+ s32 ret_val;
+
+ mutex_lock(&swflag_mutex);
+ ret_val = e1000_get_hw_semaphore_82573(hw);
+ if (ret_val)
+ mutex_unlock(&swflag_mutex);
+ return ret_val;
+}
+
+/**
+ * e1000_put_hw_semaphore_82574 - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used to access the PHY or NVM
+ *
+ **/
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
+{
+ e1000_put_hw_semaphore_82573(hw);
+ mutex_unlock(&swflag_mutex);
+}
/**
* e1000_acquire_nvm_82571 - Request for access to the EEPROM
@@ -562,8 +667,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82573:
- case e1000_82574:
- case e1000_82583:
break;
default:
ret_val = e1000e_acquire_nvm(hw);
@@ -853,9 +956,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
**/
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
{
- u32 ctrl, extcnf_ctrl, ctrl_ext, icr;
+ u32 ctrl, ctrl_ext, icr;
s32 ret_val;
- u16 i = 0;
/*
* Prevent the PCI-E bus from sticking if there is no TLP connection
@@ -880,33 +982,33 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
*/
switch (hw->mac.type) {
case e1000_82573:
+ ret_val = e1000_get_hw_semaphore_82573(hw);
+ break;
case e1000_82574:
case e1000_82583:
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- do {
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = er32(EXTCNF_CTRL);
-
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
- break;
-
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- msleep(2);
- i++;
- } while (i < MDIO_OWNERSHIP_TIMEOUT);
+ ret_val = e1000_get_hw_semaphore_82574(hw);
break;
default:
break;
}
+ if (ret_val)
+ e_dbg("Cannot acquire MDIO ownership\n");
ctrl = er32(CTRL);
e_dbg("Issuing a global reset to MAC\n");
ew32(CTRL, ctrl | E1000_CTRL_RST);
+ /* Must release MDIO ownership and mutex after MAC reset. */
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
+ e1000_put_hw_semaphore_82574(hw);
+ break;
+ default:
+ break;
+ }
+
if (hw->nvm.type == e1000_nvm_flash_hw) {
udelay(10);
ctrl_ext = er32(CTRL_EXT);
@@ -1402,6 +1504,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
u32 rxcw;
u32 ctrl;
u32 status;
+ u32 txcw;
+ u32 i;
s32 ret_val = 0;
ctrl = er32(CTRL);
@@ -1422,8 +1526,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = false;
e_dbg("AN_UP -> AN_PROG\n");
+ } else {
+ mac->serdes_has_link = true;
}
- break;
+ break;
case e1000_serdes_link_forced_up:
/*
@@ -1431,8 +1537,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
* auto-negotiation in the TXCW register and disable
* forced link in the Device Control register in an
* attempt to auto-negotiate with our link partner.
+ * If the partner code word is null, stop forcing
+ * and restart auto negotiation.
*/
- if (rxcw & E1000_RXCW_C) {
+ if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) {
/* Enable autoneg, and unforce link up */
ew32(TXCW, mac->txcw);
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
@@ -1440,6 +1548,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = false;
e_dbg("FORCED_UP -> AN_PROG\n");
+ } else {
+ mac->serdes_has_link = true;
}
break;
@@ -1495,6 +1605,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
mac->serdes_link_state =
e1000_serdes_link_autoneg_progress;
+ mac->serdes_has_link = false;
e_dbg("DOWN -> AN_PROG\n");
break;
}
@@ -1505,16 +1616,32 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
e_dbg("ANYSTATE -> DOWN\n");
} else {
/*
- * We have sync, and can tolerate one invalid (IV)
- * codeword before declaring link down, so reread
- * to look again.
+ * Check several times, if Sync and Config
+ * both are consistently 1 then simply ignore
+ * the Invalid bit and restart Autoneg
*/
- udelay(10);
- rxcw = er32(RXCW);
- if (rxcw & E1000_RXCW_IV) {
- mac->serdes_link_state = e1000_serdes_link_down;
+ for (i = 0; i < AN_RETRY_COUNT; i++) {
+ udelay(10);
+ rxcw = er32(RXCW);
+ if ((rxcw & E1000_RXCW_IV) &&
+ !((rxcw & E1000_RXCW_SYNCH) &&
+ (rxcw & E1000_RXCW_C))) {
+ mac->serdes_has_link = false;
+ mac->serdes_link_state =
+ e1000_serdes_link_down;
+ e_dbg("ANYSTATE -> DOWN\n");
+ break;
+ }
+ }
+
+ if (i == AN_RETRY_COUNT) {
+ txcw = er32(TXCW);
+ txcw |= E1000_TXCW_ANE;
+ ew32(TXCW, txcw);
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = false;
- e_dbg("ANYSTATE -> DOWN\n");
+ e_dbg("ANYSTATE -> AN_PROG\n");
}
}
}
@@ -1897,7 +2024,7 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
.flags2 = FLAG2_CHECK_PHY_HANG,
- .pba = 36,
+ .pba = 32,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
@@ -1914,7 +2041,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
- .pba = 36,
+ .pba = 32,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index d3f7a9c3f973..7245dc2e0b7c 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -488,6 +488,9 @@
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
+#define E1000_ERR_INVALID_ARGUMENT 16
+#define E1000_ERR_NO_SPACE 17
+#define E1000_ERR_NVM_PBA_SECTION 18
/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT 50
@@ -516,6 +519,7 @@
#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
/* Receive Configuration Word */
+#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
#define E1000_RXCW_C 0x20000000 /* Receive config */
#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
@@ -649,13 +653,16 @@
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define NVM_COMPAT_LOM 0x0800
+/* length of string needed to store PBA number */
+#define E1000_PBANUM_LENGTH 11
+
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
/* PBA (printed board assembly) number words */
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
-
+#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6
/* NVM Commands - SPI */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index fdc67fead4ea..2c913b8e9116 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -482,6 +482,7 @@ extern const char e1000e_driver_version[];
extern void e1000e_check_options(struct e1000_adapter *adapter);
extern void e1000e_set_ethtool_ops(struct net_device *netdev);
+extern void e1000e_led_blink_task(struct work_struct *work);
extern int e1000e_up(struct e1000_adapter *adapter);
extern void e1000e_down(struct e1000_adapter *adapter);
@@ -513,7 +514,8 @@ extern struct e1000_info e1000_pch_info;
extern struct e1000_info e1000_pch2_info;
extern struct e1000_info e1000_es2_info;
-extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
+extern s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
+ u32 pba_num_size);
extern s32 e1000e_commit_phy(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 24f8ac9cf703..b18c644e13d1 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -100,8 +100,8 @@
* with a lower bound at "index" and the upper bound at
* "index + 5".
*/
-static const u16 e1000_gg82563_cable_length_table[] =
- { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };
+static const u16 e1000_gg82563_cable_length_table[] = {
+ 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };
#define GG82563_CABLE_LENGTH_TABLE_SIZE \
ARRAY_SIZE(e1000_gg82563_cable_length_table)
@@ -426,8 +426,8 @@ static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
- while (e1000e_get_hw_semaphore(hw) != 0);
- /* Empty */
+ while (e1000e_get_hw_semaphore(hw) != 0)
+ ; /* Empty */
swfw_sync = er32(SW_FW_SYNC);
swfw_sync &= ~mask;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 8984d165a39b..affcacf6f5a9 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -45,63 +45,67 @@ struct e1000_stats {
int stat_offset;
};
-#define E1000_STAT(m) E1000_STATS, \
- sizeof(((struct e1000_adapter *)0)->m), \
- offsetof(struct e1000_adapter, m)
-#define E1000_NETDEV_STAT(m) NETDEV_STATS, \
- sizeof(((struct net_device *)0)->m), \
- offsetof(struct net_device, m)
+#define E1000_STAT(str, m) { \
+ .stat_string = str, \
+ .type = E1000_STATS, \
+ .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \
+ .stat_offset = offsetof(struct e1000_adapter, m) }
+#define E1000_NETDEV_STAT(str, m) { \
+ .stat_string = str, \
+ .type = NETDEV_STATS, \
+ .sizeof_stat = sizeof(((struct net_device *)0)->m), \
+ .stat_offset = offsetof(struct net_device, m) }
static const struct e1000_stats e1000_gstrings_stats[] = {
- { "rx_packets", E1000_STAT(stats.gprc) },
- { "tx_packets", E1000_STAT(stats.gptc) },
- { "rx_bytes", E1000_STAT(stats.gorc) },
- { "tx_bytes", E1000_STAT(stats.gotc) },
- { "rx_broadcast", E1000_STAT(stats.bprc) },
- { "tx_broadcast", E1000_STAT(stats.bptc) },
- { "rx_multicast", E1000_STAT(stats.mprc) },
- { "tx_multicast", E1000_STAT(stats.mptc) },
- { "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) },
- { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) },
- { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
- { "multicast", E1000_STAT(stats.mprc) },
- { "collisions", E1000_STAT(stats.colc) },
- { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) },
- { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
- { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
- { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
- { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
- { "rx_missed_errors", E1000_STAT(stats.mpc) },
- { "tx_aborted_errors", E1000_STAT(stats.ecol) },
- { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
- { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
- { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
- { "tx_window_errors", E1000_STAT(stats.latecol) },
- { "tx_abort_late_coll", E1000_STAT(stats.latecol) },
- { "tx_deferred_ok", E1000_STAT(stats.dc) },
- { "tx_single_coll_ok", E1000_STAT(stats.scc) },
- { "tx_multi_coll_ok", E1000_STAT(stats.mcc) },
- { "tx_timeout_count", E1000_STAT(tx_timeout_count) },
- { "tx_restart_queue", E1000_STAT(restart_queue) },
- { "rx_long_length_errors", E1000_STAT(stats.roc) },
- { "rx_short_length_errors", E1000_STAT(stats.ruc) },
- { "rx_align_errors", E1000_STAT(stats.algnerrc) },
- { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) },
- { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) },
- { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) },
- { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) },
- { "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
- { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
- { "rx_long_byte_count", E1000_STAT(stats.gorc) },
- { "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
- { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
- { "rx_header_split", E1000_STAT(rx_hdr_split) },
- { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) },
- { "tx_smbus", E1000_STAT(stats.mgptc) },
- { "rx_smbus", E1000_STAT(stats.mgprc) },
- { "dropped_smbus", E1000_STAT(stats.mgpdc) },
- { "rx_dma_failed", E1000_STAT(rx_dma_failed) },
- { "tx_dma_failed", E1000_STAT(tx_dma_failed) },
+ E1000_STAT("rx_packets", stats.gprc),
+ E1000_STAT("tx_packets", stats.gptc),
+ E1000_STAT("rx_bytes", stats.gorc),
+ E1000_STAT("tx_bytes", stats.gotc),
+ E1000_STAT("rx_broadcast", stats.bprc),
+ E1000_STAT("tx_broadcast", stats.bptc),
+ E1000_STAT("rx_multicast", stats.mprc),
+ E1000_STAT("tx_multicast", stats.mptc),
+ E1000_NETDEV_STAT("rx_errors", stats.rx_errors),
+ E1000_NETDEV_STAT("tx_errors", stats.tx_errors),
+ E1000_NETDEV_STAT("tx_dropped", stats.tx_dropped),
+ E1000_STAT("multicast", stats.mprc),
+ E1000_STAT("collisions", stats.colc),
+ E1000_NETDEV_STAT("rx_length_errors", stats.rx_length_errors),
+ E1000_NETDEV_STAT("rx_over_errors", stats.rx_over_errors),
+ E1000_STAT("rx_crc_errors", stats.crcerrs),
+ E1000_NETDEV_STAT("rx_frame_errors", stats.rx_frame_errors),
+ E1000_STAT("rx_no_buffer_count", stats.rnbc),
+ E1000_STAT("rx_missed_errors", stats.mpc),
+ E1000_STAT("tx_aborted_errors", stats.ecol),
+ E1000_STAT("tx_carrier_errors", stats.tncrs),
+ E1000_NETDEV_STAT("tx_fifo_errors", stats.tx_fifo_errors),
+ E1000_NETDEV_STAT("tx_heartbeat_errors", stats.tx_heartbeat_errors),
+ E1000_STAT("tx_window_errors", stats.latecol),
+ E1000_STAT("tx_abort_late_coll", stats.latecol),
+ E1000_STAT("tx_deferred_ok", stats.dc),
+ E1000_STAT("tx_single_coll_ok", stats.scc),
+ E1000_STAT("tx_multi_coll_ok", stats.mcc),
+ E1000_STAT("tx_timeout_count", tx_timeout_count),
+ E1000_STAT("tx_restart_queue", restart_queue),
+ E1000_STAT("rx_long_length_errors", stats.roc),
+ E1000_STAT("rx_short_length_errors", stats.ruc),
+ E1000_STAT("rx_align_errors", stats.algnerrc),
+ E1000_STAT("tx_tcp_seg_good", stats.tsctc),
+ E1000_STAT("tx_tcp_seg_failed", stats.tsctfc),
+ E1000_STAT("rx_flow_control_xon", stats.xonrxc),
+ E1000_STAT("rx_flow_control_xoff", stats.xoffrxc),
+ E1000_STAT("tx_flow_control_xon", stats.xontxc),
+ E1000_STAT("tx_flow_control_xoff", stats.xofftxc),
+ E1000_STAT("rx_long_byte_count", stats.gorc),
+ E1000_STAT("rx_csum_offload_good", hw_csum_good),
+ E1000_STAT("rx_csum_offload_errors", hw_csum_err),
+ E1000_STAT("rx_header_split", rx_hdr_split),
+ E1000_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed),
+ E1000_STAT("tx_smbus", stats.mgptc),
+ E1000_STAT("rx_smbus", stats.mgprc),
+ E1000_STAT("dropped_smbus", stats.mgpdc),
+ E1000_STAT("rx_dma_failed", rx_dma_failed),
+ E1000_STAT("tx_dma_failed", tx_dma_failed),
};
#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
@@ -194,20 +198,6 @@ static int e1000_get_settings(struct net_device *netdev,
return 0;
}
-static u32 e1000_get_link(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- /*
- * Avoid touching hardware registers when possible, otherwise
- * link negotiation can get messed up when user-level scripts
- * are rapidly polling the driver to see if link is up.
- */
- return netif_running(netdev) ? netif_carrier_ok(netdev) :
- !!(er32(STATUS) & E1000_STATUS_LU);
-}
-
static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
{
struct e1000_mac_info *mac = &adapter->hw.mac;
@@ -763,8 +753,8 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
int reg, int offset, u32 mask, u32 write)
{
u32 pat, val;
- static const u32 test[] =
- {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+ static const u32 test[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (pat = 0; pat < ARRAY_SIZE(test); pat++) {
E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset,
(test[pat] & write));
@@ -1263,6 +1253,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
u32 ctrl_reg = 0;
u32 stat_reg = 0;
u16 phy_reg = 0;
+ s32 ret_val = 0;
hw->mac.autoneg = 0;
@@ -1322,7 +1313,13 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
case e1000_phy_82577:
case e1000_phy_82578:
/* Workaround: K1 must be disabled for stable 1Gbps operation */
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val) {
+ e_err("Cannot setup 1Gbps loopback.\n");
+ return ret_val;
+ }
e1000_configure_k1_ich8lan(hw, false);
+ hw->phy.ops.release(hw);
break;
case e1000_phy_82579:
/* Disable PHY energy detect power down */
@@ -1860,7 +1857,7 @@ static int e1000_set_wol(struct net_device *netdev,
/* bit defines for adapter->led_status */
#define E1000_LED_ON 0
-static void e1000e_led_blink_task(struct work_struct *work)
+void e1000e_led_blink_task(struct work_struct *work)
{
struct e1000_adapter *adapter = container_of(work,
struct e1000_adapter, led_blink_task);
@@ -1892,7 +1889,6 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
(hw->mac.type == e1000_pch2lan) ||
(hw->mac.type == e1000_82583) ||
(hw->mac.type == e1000_82574)) {
- INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function =
@@ -1986,6 +1982,9 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
p = (char *) adapter +
e1000_gstrings_stats[i].stat_offset;
break;
+ default:
+ data[i] = 0;
+ continue;
}
data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
@@ -2024,7 +2023,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_msglevel = e1000_get_msglevel,
.set_msglevel = e1000_set_msglevel,
.nway_reset = e1000_nway_reset,
- .get_link = e1000_get_link,
+ .get_link = ethtool_op_get_link,
.get_eeprom_len = e1000_get_eeprom_len,
.get_eeprom = e1000_get_eeprom,
.set_eeprom = e1000_set_eeprom,
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index e3374d9a2472..d86cc0832720 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -338,12 +338,17 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
}
phy->id = e1000_phy_unknown;
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- goto out;
- if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) {
+ switch (hw->mac.type) {
+ default:
+ ret_val = e1000e_get_phy_id(hw);
+ if (ret_val)
+ goto out;
+ if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
+ break;
+ /* fall-through */
+ case e1000_pch2lan:
/*
- * In case the PHY needs to be in mdio slow mode (eg. 82577),
+ * In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again.
*/
ret_val = e1000_set_mdio_slow_mode_hv(hw);
@@ -352,6 +357,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
ret_val = e1000e_get_phy_id(hw);
if (ret_val)
goto out;
+ break;
}
phy->type = e1000e_get_phy_type_from_id(phy->id);
@@ -2303,11 +2309,10 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
*/
if (ret_val == 0) {
flash_data = er32flash(ICH_FLASH_FDATA0);
- if (size == 1) {
+ if (size == 1)
*data = (u8)(flash_data & 0x000000FF);
- } else if (size == 2) {
+ else if (size == 2)
*data = (u16)(flash_data & 0x0000FFFF);
- }
break;
} else {
/*
@@ -3591,7 +3596,7 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
ew32(PHY_CTRL, phy_ctrl);
if (hw->mac.type >= e1000_pchlan) {
- e1000_oem_bits_config_ich8lan(hw, true);
+ e1000_oem_bits_config_ich8lan(hw, false);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 0fd4eb5ac5fb..7e55170a601e 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -493,9 +493,8 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
* different link partner.
*/
ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val) {
+ if (ret_val)
e_dbg("Error configuring flow control\n");
- }
return ret_val;
}
@@ -1496,9 +1495,8 @@ s32 e1000e_setup_led_generic(struct e1000_hw *hw)
{
u32 ledctl;
- if (hw->mac.ops.setup_led != e1000e_setup_led_generic) {
+ if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
return -E1000_ERR_CONFIG;
- }
if (hw->phy.media_type == e1000_media_type_fiber) {
ledctl = er32(LEDCTL);
@@ -2139,6 +2137,119 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
}
/**
+ * e1000_read_pba_string_generic - Read device part number
+ * @hw: pointer to the HW structure
+ * @pba_num: pointer to device part number
+ * @pba_num_size: size of part number buffer
+ *
+ * Reads the product board assembly (PBA) number from the EEPROM and stores
+ * the value in pba_num.
+ **/
+s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
+ u32 pba_num_size)
+{
+ s32 ret_val;
+ u16 nvm_data;
+ u16 pba_ptr;
+ u16 offset;
+ u16 length;
+
+ if (pba_num == NULL) {
+ e_dbg("PBA string buffer was null\n");
+ ret_val = E1000_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+ if (ret_val) {
+ e_dbg("NVM Read Error\n");
+ goto out;
+ }
+
+ ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
+ if (ret_val) {
+ e_dbg("NVM Read Error\n");
+ goto out;
+ }
+
+ /*
+ * if nvm_data is not ptr guard the PBA must be in legacy format which
+ * means pba_ptr is actually our second data word for the PBA number
+ * and we can decode it into an ascii string
+ */
+ if (nvm_data != NVM_PBA_PTR_GUARD) {
+ e_dbg("NVM PBA number is not stored as string\n");
+
+ /* we will need 11 characters to store the PBA */
+ if (pba_num_size < 11) {
+ e_dbg("PBA string buffer too small\n");
+ return E1000_ERR_NO_SPACE;
+ }
+
+ /* extract hex string from data and pba_ptr */
+ pba_num[0] = (nvm_data >> 12) & 0xF;
+ pba_num[1] = (nvm_data >> 8) & 0xF;
+ pba_num[2] = (nvm_data >> 4) & 0xF;
+ pba_num[3] = nvm_data & 0xF;
+ pba_num[4] = (pba_ptr >> 12) & 0xF;
+ pba_num[5] = (pba_ptr >> 8) & 0xF;
+ pba_num[6] = '-';
+ pba_num[7] = 0;
+ pba_num[8] = (pba_ptr >> 4) & 0xF;
+ pba_num[9] = pba_ptr & 0xF;
+
+ /* put a null character on the end of our string */
+ pba_num[10] = '\0';
+
+ /* switch all the data but the '-' to hex char */
+ for (offset = 0; offset < 10; offset++) {
+ if (pba_num[offset] < 0xA)
+ pba_num[offset] += '0';
+ else if (pba_num[offset] < 0x10)
+ pba_num[offset] += 'A' - 0xA;
+ }
+
+ goto out;
+ }
+
+ ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
+ if (ret_val) {
+ e_dbg("NVM Read Error\n");
+ goto out;
+ }
+
+ if (length == 0xFFFF || length == 0) {
+ e_dbg("NVM PBA number section invalid length\n");
+ ret_val = E1000_ERR_NVM_PBA_SECTION;
+ goto out;
+ }
+ /* check if pba_num buffer is big enough */
+ if (pba_num_size < (((u32)length * 2) - 1)) {
+ e_dbg("PBA string buffer too small\n");
+ ret_val = E1000_ERR_NO_SPACE;
+ goto out;
+ }
+
+ /* trim pba length from start of string */
+ pba_ptr++;
+ length--;
+
+ for (offset = 0; offset < length; offset++) {
+ ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
+ if (ret_val) {
+ e_dbg("NVM Read Error\n");
+ goto out;
+ }
+ pba_num[offset * 2] = (u8)(nvm_data >> 8);
+ pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
+ }
+ pba_num[offset * 2] = '\0';
+
+out:
+ return ret_val;
+}
+
+/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
@@ -2579,25 +2690,3 @@ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
out:
return ret_val;
}
-
-s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
-{
- s32 ret_val;
- u16 nvm_data;
-
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
- if (ret_val) {
- e_dbg("NVM Read Error\n");
- return ret_val;
- }
- *pba_num = (u32)(nvm_data << 16);
-
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
- if (ret_val) {
- e_dbg("NVM Read Error\n");
- return ret_val;
- }
- *pba_num |= nvm_data;
-
- return 0;
-}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c4ca1629f532..fe50242aa9e6 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -54,7 +54,7 @@
#define DRV_EXTRAVERSION "-k2"
-#define DRV_VERSION "1.2.7" DRV_EXTRAVERSION
+#define DRV_VERSION "1.2.20" DRV_EXTRAVERSION
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
@@ -1325,7 +1325,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
goto next_desc;
}
-#define rxtop rx_ring->rx_skb_top
+#define rxtop (rx_ring->rx_skb_top)
if (!(status & E1000_RXD_STAT_EOP)) {
/* this descriptor is only the beginning (or middle) */
if (!rxtop) {
@@ -1806,9 +1806,8 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
err = pci_enable_msix(adapter->pdev,
adapter->msix_entries,
adapter->num_vectors);
- if (err == 0) {
+ if (err == 0)
return;
- }
}
/* MSI-X failed, so fall through and try MSI */
e_err("Failed to initialize MSI-X interrupts. "
@@ -2059,10 +2058,9 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
int err = -ENOMEM, size;
size = sizeof(struct e1000_buffer) * tx_ring->count;
- tx_ring->buffer_info = vmalloc(size);
+ tx_ring->buffer_info = vzalloc(size);
if (!tx_ring->buffer_info)
goto err;
- memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
@@ -2095,10 +2093,9 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
int i, size, desc_len, err = -ENOMEM;
size = sizeof(struct e1000_buffer) * rx_ring->count;
- rx_ring->buffer_info = vmalloc(size);
+ rx_ring->buffer_info = vzalloc(size);
if (!rx_ring->buffer_info)
goto err;
- memset(rx_ring->buffer_info, 0, size);
for (i = 0; i < rx_ring->count; i++) {
buffer_info = &rx_ring->buffer_info[i];
@@ -2132,7 +2129,7 @@ err_pages:
}
err:
vfree(rx_ring->buffer_info);
- e_err("Unable to allocate memory for the transmit descriptor ring\n");
+ e_err("Unable to allocate memory for the receive descriptor ring\n");
return err;
}
@@ -2200,9 +2197,8 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
e1000_clean_rx_ring(adapter);
- for (i = 0; i < rx_ring->count; i++) {
+ for (i = 0; i < rx_ring->count; i++)
kfree(rx_ring->buffer_info[i].ps_pages);
- }
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
@@ -2242,20 +2238,18 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
/* handle TSO and jumbo frames */
if (bytes/packets > 8000)
retval = bulk_latency;
- else if ((packets < 5) && (bytes > 512)) {
+ else if ((packets < 5) && (bytes > 512))
retval = low_latency;
- }
break;
case low_latency: /* 50 usec aka 20000 ints/s */
if (bytes > 10000) {
/* this if handles the TSO accounting */
- if (bytes/packets > 8000) {
+ if (bytes/packets > 8000)
retval = bulk_latency;
- } else if ((packets < 10) || ((bytes/packets) > 1200)) {
+ else if ((packets < 10) || ((bytes/packets) > 1200))
retval = bulk_latency;
- } else if ((packets > 35)) {
+ else if ((packets > 35))
retval = lowest_latency;
- }
} else if (bytes/packets > 2000) {
retval = bulk_latency;
} else if (packets <= 2 && bytes < 512) {
@@ -2264,9 +2258,8 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
break;
case bulk_latency: /* 250 usec aka 4000 ints/s */
if (bytes > 25000) {
- if (packets > 35) {
+ if (packets > 35)
retval = low_latency;
- }
} else if (bytes < 6000) {
retval = low_latency;
}
@@ -4475,7 +4468,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
break;
}
- css = skb_transport_offset(skb);
+ css = skb_checksum_start_offset(skb);
i = tx_ring->next_to_use;
buffer_info = &tx_ring->buffer_info[i];
@@ -4595,7 +4588,7 @@ dma_error:
i += tx_ring->count;
i--;
buffer_info = &tx_ring->buffer_info[i];
- e1000_put_txbuf(adapter, buffer_info);;
+ e1000_put_txbuf(adapter, buffer_info);
}
return 0;
@@ -4631,7 +4624,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
i = tx_ring->next_to_use;
- while (count--) {
+ do {
buffer_info = &tx_ring->buffer_info[i];
tx_desc = E1000_TX_DESC(*tx_ring, i);
tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -4642,7 +4635,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
i++;
if (i == tx_ring->count)
i = 0;
- }
+ } while (--count > 0);
tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
@@ -5465,6 +5458,36 @@ static void e1000_shutdown(struct pci_dev *pdev)
}
#ifdef CONFIG_NET_POLL_CONTROLLER
+
+static irqreturn_t e1000_intr_msix(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ int vector, msix_irq;
+
+ if (adapter->msix_entries) {
+ vector = 0;
+ msix_irq = adapter->msix_entries[vector].vector;
+ disable_irq(msix_irq);
+ e1000_intr_msix_rx(msix_irq, netdev);
+ enable_irq(msix_irq);
+
+ vector++;
+ msix_irq = adapter->msix_entries[vector].vector;
+ disable_irq(msix_irq);
+ e1000_intr_msix_tx(msix_irq, netdev);
+ enable_irq(msix_irq);
+
+ vector++;
+ msix_irq = adapter->msix_entries[vector].vector;
+ disable_irq(msix_irq);
+ e1000_msix_other(msix_irq, netdev);
+ enable_irq(msix_irq);
+ }
+
+ return IRQ_HANDLED;
+}
+
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
@@ -5474,10 +5497,21 @@ static void e1000_netpoll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
- disable_irq(adapter->pdev->irq);
- e1000_intr(adapter->pdev->irq, netdev);
-
- enable_irq(adapter->pdev->irq);
+ switch (adapter->int_mode) {
+ case E1000E_INT_MODE_MSIX:
+ e1000_intr_msix(adapter->pdev->irq, netdev);
+ break;
+ case E1000E_INT_MODE_MSI:
+ disable_irq(adapter->pdev->irq);
+ e1000_intr_msi(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+ break;
+ default: /* E1000E_INT_MODE_LEGACY */
+ disable_irq(adapter->pdev->irq);
+ e1000_intr(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+ break;
+ }
}
#endif
@@ -5587,7 +5621,8 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- u32 pba_num;
+ u32 ret_val;
+ u8 pba_str[E1000_PBANUM_LENGTH];
/* print bus type/speed/width info */
e_info("(PCI Express:2.5GB/s:%s) %pM\n",
@@ -5598,9 +5633,12 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
netdev->dev_addr);
e_info("Intel(R) PRO/%s Network Connection\n",
(hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
- e1000e_read_pba_num(hw, &pba_num);
- e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
+ ret_val = e1000_read_pba_string_generic(hw, pba_str,
+ E1000_PBANUM_LENGTH);
+ if (ret_val)
+ strcpy(pba_str, "Unknown");
+ e_info("MAC: %d, PHY: %d, PBA No: %s\n",
+ hw->mac.type, hw->phy.type, pba_str);
}
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
@@ -5864,6 +5902,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
+ INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
/* Initialize link parameters. User can change them with ethtool */
adapter->hw.mac.autoneg = 1;
@@ -5984,8 +6023,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
bool down = test_bit(__E1000_DOWN, &adapter->state);
/*
- * flush_scheduled work may reschedule our watchdog task, so
- * explicitly disable watchdog tasks from being rescheduled
+ * The timers may be rescheduled, so explicitly disable them
+ * from being rescheduled.
*/
if (!down)
set_bit(__E1000_DOWN, &adapter->state);
@@ -5996,8 +6035,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->downshift_task);
cancel_work_sync(&adapter->update_phy_task);
+ cancel_work_sync(&adapter->led_blink_task);
cancel_work_sync(&adapter->print_hang_task);
- flush_scheduled_work();
if (!(netdev->flags & IFF_UP))
e1000_power_down_phy(adapter);
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 3d36911f77f3..a9612b0e4bca 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -421,7 +421,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
static const struct e1000_option opt = {
.type = enable_option,
.name = "CRC Stripping",
- .err = "defaulting to enabled",
+ .err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 3d3dc0c82355..1781efeb55e3 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -42,20 +42,20 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
u16 *data, bool read);
/* Cable length tables */
-static const u16 e1000_m88_cable_length_table[] =
- { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+static const u16 e1000_m88_cable_length_table[] = {
+ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
ARRAY_SIZE(e1000_m88_cable_length_table)
-static const u16 e1000_igp_2_cable_length_table[] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
- 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
- 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
- 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
- 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
- 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
- 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
- 124};
+static const u16 e1000_igp_2_cable_length_table[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
+ 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
+ 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
+ 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
+ 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
+ 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
+ 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
+ 124};
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
ARRAY_SIZE(e1000_igp_2_cable_length_table)
@@ -226,6 +226,13 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
}
*data = (u16) mdic;
+ /*
+ * Allow some time after each MDIC transaction to avoid
+ * reading duplicate data in the next MDIC transaction.
+ */
+ if (hw->mac.type == e1000_pch2lan)
+ udelay(100);
+
return 0;
}
@@ -279,6 +286,13 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
return -E1000_ERR_PHY;
}
+ /*
+ * Allow some time after each MDIC transaction to avoid
+ * reading duplicate data in the next MDIC transaction.
+ */
+ if (hw->mac.type == e1000_pch2lan)
+ udelay(100);
+
return 0;
}
@@ -1043,9 +1057,8 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
- if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
+ if (phy->autoneg_mask & ADVERTISE_1000_FULL)
ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
- }
return ret_val;
}
@@ -1840,11 +1853,12 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
u16 phy_data, i, agc_value = 0;
u16 cur_agc_index, max_agc_index = 0;
u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
- u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
- {IGP02E1000_PHY_AGC_A,
- IGP02E1000_PHY_AGC_B,
- IGP02E1000_PHY_AGC_C,
- IGP02E1000_PHY_AGC_D};
+ static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
+ IGP02E1000_PHY_AGC_A,
+ IGP02E1000_PHY_AGC_B,
+ IGP02E1000_PHY_AGC_C,
+ IGP02E1000_PHY_AGC_D
+ };
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index 06e72fbef862..94ec973b2bdc 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -216,7 +216,7 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
printk(" %02X", station_addr[i]);
if (dev->irq < 2) {
- int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
+ static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
for (i = 0; i < ARRAY_SIZE(irqlist); i++)
if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
dev->irq = irqlist[i];
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 7c826319ee5a..4fa8d2a4aef3 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -302,7 +302,7 @@ struct eepro_local {
#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
#define ee_id_eepro10p1 0x31
-#define TX_TIMEOUT 40
+#define TX_TIMEOUT ((4*HZ)/10)
/* Index to functions, as function prototypes. */
@@ -891,12 +891,13 @@ err:
there is non-reboot way to recover if something goes wrong.
*/
-static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
-static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};
+static const char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
+static const char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};
static int eepro_grab_irq(struct net_device *dev)
{
- int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };
- int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
+ static const int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };
+ const int *irqp = irqlist;
+ int temp_reg, ioaddr = dev->base_addr;
eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 12c37d264108..48ee51bb9e50 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -1103,7 +1103,7 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
{
- static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
+ static const char irqmap[] = { 0, 9, 3, 4, 5, 10, 11, 0 };
unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
/* Use the IRQ from EEPROM if none was given */
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 8e745e74828d..a724a2d14506 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -130,19 +130,6 @@
/* utility functions */
-#define ehea_info(fmt, args...) \
- printk(KERN_INFO DRV_NAME ": " fmt "\n", ## args)
-
-#define ehea_error(fmt, args...) \
- printk(KERN_ERR DRV_NAME ": Error in %s: " fmt "\n", __func__, ## args)
-
-#ifdef DEBUG
-#define ehea_debug(fmt, args...) \
- printk(KERN_DEBUG DRV_NAME ": " fmt, ## args)
-#else
-#define ehea_debug(fmt, args...) do {} while (0)
-#endif
-
void ehea_dump(void *adr, int len, char *msg);
#define EHEA_BMASK(pos, length) (((pos) << 16) + (length))
@@ -515,6 +502,4 @@ void ehea_set_ethtool_ops(struct net_device *netdev);
int ehea_sense_port_attr(struct ehea_port *port);
int ehea_set_portspeed(struct ehea_port *port, u32 port_speed);
-extern struct work_struct ehea_rereg_mr_task;
-
#endif /* __EHEA_H__ */
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 75b099ce49c9..3e2e734fecb7 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -26,6 +26,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "ehea.h"
#include "ehea_phyp.h"
@@ -118,10 +120,10 @@ doit:
ret = ehea_set_portspeed(port, sp);
if (!ret)
- ehea_info("%s: Port speed successfully set: %dMbps "
- "%s Duplex",
- port->netdev->name, port->port_speed,
- port->full_duplex == 1 ? "Full" : "Half");
+ netdev_info(dev,
+ "Port speed successfully set: %dMbps %s Duplex\n",
+ port->port_speed,
+ port->full_duplex == 1 ? "Full" : "Half");
out:
return ret;
}
@@ -134,10 +136,10 @@ static int ehea_nway_reset(struct net_device *dev)
ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG);
if (!ret)
- ehea_info("%s: Port speed successfully set: %dMbps "
- "%s Duplex",
- port->netdev->name, port->port_speed,
- port->full_duplex == 1 ? "Full" : "Half");
+ netdev_info(port->netdev,
+ "Port speed successfully set: %dMbps %s Duplex\n",
+ port->port_speed,
+ port->full_duplex == 1 ? "Full" : "Half");
return ret;
}
@@ -261,6 +263,20 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
}
+static int ehea_set_flags(struct net_device *dev, u32 data)
+{
+ /* Avoid changing the VLAN flags */
+ if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
+ (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
+ ETH_FLAG_TXVLAN))){
+ return -EINVAL;
+ }
+
+ return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
+ | ETH_FLAG_TXVLAN
+ | ETH_FLAG_RXVLAN);
+}
+
const struct ethtool_ops ehea_ethtool_ops = {
.get_settings = ehea_get_settings,
.get_drvinfo = ehea_get_drvinfo,
@@ -273,6 +289,8 @@ const struct ethtool_ops ehea_ethtool_ops = {
.get_ethtool_stats = ehea_get_ethtool_stats,
.get_rx_csum = ehea_get_rx_csum,
.set_settings = ehea_set_settings,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ehea_set_flags,
.nway_reset = ehea_nway_reset, /* Restart autonegotiation */
};
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 3d0af08483a1..1032b5bbe238 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -26,6 +26,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -101,7 +103,6 @@ MODULE_PARM_DESC(use_lro, " Large Receive Offload, 1: enable, 0: disable, "
static int port_name_cnt;
static LIST_HEAD(adapter_list);
static unsigned long ehea_driver_flags;
-struct work_struct ehea_rereg_mr_task;
static DEFINE_MUTEX(dlpar_mem_lock);
struct ehea_fw_handle_array ehea_fw_handles;
struct ehea_bcmc_reg_array ehea_bcmc_regs;
@@ -136,8 +137,8 @@ void ehea_dump(void *adr, int len, char *msg)
int x;
unsigned char *deb = adr;
for (x = 0; x < len; x += 16) {
- printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg,
- deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8]));
+ pr_info("%s adr=%p ofs=%04x %016llx %016llx\n",
+ msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8]));
deb += 16;
}
}
@@ -337,7 +338,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
cb2 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb2) {
- ehea_error("no mem for cb2");
+ netdev_err(dev, "no mem for cb2\n");
goto out;
}
@@ -345,7 +346,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
port->logical_port_id,
H_PORT_CB2, H_PORT_CB2_ALL, cb2);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_port failed");
+ netdev_err(dev, "query_ehea_port failed\n");
goto out_herr;
}
@@ -400,7 +401,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
skb_arr_rq1[index] = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[index]) {
- ehea_info("Unable to allocate enough skb in the array\n");
+ netdev_info(dev, "Unable to allocate enough skb in the array\n");
pr->rq1_skba.os_skbs = fill_wqes - i;
break;
}
@@ -424,14 +425,14 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
int i;
if (nr_rq1a > pr->rq1_skba.len) {
- ehea_error("NR_RQ1A bigger than skb array len\n");
+ netdev_err(dev, "NR_RQ1A bigger than skb array len\n");
return;
}
for (i = 0; i < nr_rq1a; i++) {
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[i]) {
- ehea_info("No enough memory to allocate skb array\n");
+ netdev_info(dev, "Not enough memory to allocate skb array\n");
break;
}
}
@@ -469,8 +470,9 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
if (!skb) {
q_skba->os_skbs = fill_wqes - i;
if (q_skba->os_skbs == q_skba->len - 2) {
- ehea_info("%s: rq%i ran dry - no mem for skb",
- pr->port->netdev->name, rq_nr);
+ netdev_info(pr->port->netdev,
+ "rq%i ran dry - no mem for skb\n",
+ rq_nr);
ret = -ENOMEM;
}
break;
@@ -635,8 +637,8 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq,
if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) {
if (netif_msg_rx_err(pr->port)) {
- ehea_error("Critical receive error for QP %d. "
- "Resetting port.", pr->qp->init_attr.qp_nr);
+ pr_err("Critical receive error for QP %d. Resetting port.\n",
+ pr->qp->init_attr.qp_nr);
ehea_dump(cqe, sizeof(*cqe), "CQE");
}
ehea_schedule_port_reset(pr->port);
@@ -683,7 +685,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
pr->port->vgrp);
- if (use_lro) {
+ if (skb->dev->features & NETIF_F_LRO) {
if (vlan_extracted)
lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb,
pr->port->vgrp,
@@ -738,13 +740,13 @@ static int ehea_proc_rwqes(struct net_device *dev,
skb_arr_rq1_len,
wqe_index);
if (unlikely(!skb)) {
- if (netif_msg_rx_err(port))
- ehea_error("LL rq1: skb=NULL");
+ netif_info(port, rx_err, dev,
+ "LL rq1: skb=NULL\n");
skb = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
if (!skb) {
- ehea_info("Not enough memory to allocate skb\n");
+ netdev_err(dev, "Not enough memory to allocate skb\n");
break;
}
}
@@ -756,8 +758,8 @@ static int ehea_proc_rwqes(struct net_device *dev,
skb = get_skb_by_index(skb_arr_rq2,
skb_arr_rq2_len, cqe);
if (unlikely(!skb)) {
- if (netif_msg_rx_err(port))
- ehea_error("rq2: skb=NULL");
+ netif_err(port, rx_err, dev,
+ "rq2: skb=NULL\n");
break;
}
ehea_fill_skb(dev, skb, cqe);
@@ -767,8 +769,8 @@ static int ehea_proc_rwqes(struct net_device *dev,
skb = get_skb_by_index(skb_arr_rq3,
skb_arr_rq3_len, cqe);
if (unlikely(!skb)) {
- if (netif_msg_rx_err(port))
- ehea_error("rq3: skb=NULL");
+ netif_err(port, rx_err, dev,
+ "rq3: skb=NULL\n");
break;
}
ehea_fill_skb(dev, skb, cqe);
@@ -787,7 +789,7 @@ static int ehea_proc_rwqes(struct net_device *dev,
}
cqe = ehea_poll_rq1(qp, &wqe_index);
}
- if (use_lro)
+ if (dev->features & NETIF_F_LRO)
lro_flush_all(&pr->lro_mgr);
pr->rx_packets += processed;
@@ -840,7 +842,7 @@ static void check_sqs(struct ehea_port *port)
msecs_to_jiffies(100));
if (!ret) {
- ehea_error("HW/SW queues out of sync");
+ pr_err("HW/SW queues out of sync\n");
ehea_schedule_port_reset(pr->port);
return;
}
@@ -873,14 +875,14 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
}
if (cqe->status & EHEA_CQE_STAT_ERR_MASK) {
- ehea_error("Bad send completion status=0x%04X",
- cqe->status);
+ pr_err("Bad send completion status=0x%04X\n",
+ cqe->status);
if (netif_msg_tx_err(pr->port))
ehea_dump(cqe, sizeof(*cqe), "Send CQE");
if (cqe->status & EHEA_CQE_STAT_RESET_MASK) {
- ehea_error("Resetting port");
+ pr_err("Resetting port\n");
ehea_schedule_port_reset(pr->port);
break;
}
@@ -998,8 +1000,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
while (eqe) {
qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry);
- ehea_error("QP aff_err: entry=0x%llx, token=0x%x",
- eqe->entry, qp_token);
+ pr_err("QP aff_err: entry=0x%llx, token=0x%x\n",
+ eqe->entry, qp_token);
qp = port->port_res[qp_token].qp;
@@ -1017,7 +1019,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
}
if (reset_port) {
- ehea_error("Resetting port");
+ pr_err("Resetting port\n");
ehea_schedule_port_reset(port);
}
@@ -1045,7 +1047,7 @@ int ehea_sense_port_attr(struct ehea_port *port)
/* may be called via ehea_neq_tasklet() */
cb0 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb0) {
- ehea_error("no mem for cb0");
+ pr_err("no mem for cb0\n");
ret = -ENOMEM;
goto out;
}
@@ -1137,7 +1139,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
- ehea_error("no mem for cb4");
+ pr_err("no mem for cb4\n");
ret = -ENOMEM;
goto out;
}
@@ -1188,16 +1190,16 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
break;
}
} else {
- ehea_error("Failed sensing port speed");
+ pr_err("Failed sensing port speed\n");
ret = -EIO;
}
} else {
if (hret == H_AUTHORITY) {
- ehea_info("Hypervisor denied setting port speed");
+ pr_info("Hypervisor denied setting port speed\n");
ret = -EPERM;
} else {
ret = -EIO;
- ehea_error("Failed setting port speed");
+ pr_err("Failed setting port speed\n");
}
}
if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
@@ -1214,80 +1216,78 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
u8 ec;
u8 portnum;
struct ehea_port *port;
+ struct net_device *dev;
ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe);
portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe);
port = ehea_get_port(adapter, portnum);
+ dev = port->netdev;
switch (ec) {
case EHEA_EC_PORTSTATE_CHG: /* port state change */
if (!port) {
- ehea_error("unknown portnum %x", portnum);
+ netdev_err(dev, "unknown portnum %x\n", portnum);
break;
}
if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) {
- if (!netif_carrier_ok(port->netdev)) {
+ if (!netif_carrier_ok(dev)) {
ret = ehea_sense_port_attr(port);
if (ret) {
- ehea_error("failed resensing port "
- "attributes");
+ netdev_err(dev, "failed resensing port attributes\n");
break;
}
- if (netif_msg_link(port))
- ehea_info("%s: Logical port up: %dMbps "
- "%s Duplex",
- port->netdev->name,
- port->port_speed,
- port->full_duplex ==
- 1 ? "Full" : "Half");
+ netif_info(port, link, dev,
+ "Logical port up: %dMbps %s Duplex\n",
+ port->port_speed,
+ port->full_duplex == 1 ?
+ "Full" : "Half");
- netif_carrier_on(port->netdev);
- netif_wake_queue(port->netdev);
+ netif_carrier_on(dev);
+ netif_wake_queue(dev);
}
} else
- if (netif_carrier_ok(port->netdev)) {
- if (netif_msg_link(port))
- ehea_info("%s: Logical port down",
- port->netdev->name);
- netif_carrier_off(port->netdev);
- netif_stop_queue(port->netdev);
+ if (netif_carrier_ok(dev)) {
+ netif_info(port, link, dev,
+ "Logical port down\n");
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
}
if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) {
port->phy_link = EHEA_PHY_LINK_UP;
- if (netif_msg_link(port))
- ehea_info("%s: Physical port up",
- port->netdev->name);
+ netif_info(port, link, dev,
+ "Physical port up\n");
if (prop_carrier_state)
- netif_carrier_on(port->netdev);
+ netif_carrier_on(dev);
} else {
port->phy_link = EHEA_PHY_LINK_DOWN;
- if (netif_msg_link(port))
- ehea_info("%s: Physical port down",
- port->netdev->name);
+ netif_info(port, link, dev,
+ "Physical port down\n");
if (prop_carrier_state)
- netif_carrier_off(port->netdev);
+ netif_carrier_off(dev);
}
if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe))
- ehea_info("External switch port is primary port");
+ netdev_info(dev,
+ "External switch port is primary port\n");
else
- ehea_info("External switch port is backup port");
+ netdev_info(dev,
+ "External switch port is backup port\n");
break;
case EHEA_EC_ADAPTER_MALFUNC:
- ehea_error("Adapter malfunction");
+ netdev_err(dev, "Adapter malfunction\n");
break;
case EHEA_EC_PORT_MALFUNC:
- ehea_info("Port malfunction: Device: %s", port->netdev->name);
- netif_carrier_off(port->netdev);
- netif_stop_queue(port->netdev);
+ netdev_info(dev, "Port malfunction\n");
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
break;
default:
- ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe);
+ netdev_err(dev, "unknown event code %x, eqe=0x%llX\n", ec, eqe);
break;
}
}
@@ -1299,13 +1299,13 @@ static void ehea_neq_tasklet(unsigned long data)
u64 event_mask;
eqe = ehea_poll_eq(adapter->neq);
- ehea_debug("eqe=%p", eqe);
+ pr_debug("eqe=%p\n", eqe);
while (eqe) {
- ehea_debug("*eqe=%lx", eqe->entry);
+ pr_debug("*eqe=%lx\n", (unsigned long) eqe->entry);
ehea_parse_eqe(adapter, eqe->entry);
eqe = ehea_poll_eq(adapter->neq);
- ehea_debug("next eqe=%p", eqe);
+ pr_debug("next eqe=%p\n", eqe);
}
event_mask = EHEA_BMASK_SET(NELR_PORTSTATE_CHG, 1)
@@ -1354,14 +1354,14 @@ static int ehea_reg_interrupts(struct net_device *dev)
ehea_qp_aff_irq_handler,
IRQF_DISABLED, port->int_aff_name, port);
if (ret) {
- ehea_error("failed registering irq for qp_aff_irq_handler:"
- "ist=%X", port->qp_eq->attr.ist1);
+ netdev_err(dev, "failed registering irq for qp_aff_irq_handler:ist=%X\n",
+ port->qp_eq->attr.ist1);
goto out_free_qpeq;
}
- if (netif_msg_ifup(port))
- ehea_info("irq_handle 0x%X for function qp_aff_irq_handler "
- "registered", port->qp_eq->attr.ist1);
+ netif_info(port, ifup, dev,
+ "irq_handle 0x%X for function qp_aff_irq_handler registered\n",
+ port->qp_eq->attr.ist1);
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
@@ -1373,14 +1373,13 @@ static int ehea_reg_interrupts(struct net_device *dev)
IRQF_DISABLED, pr->int_send_name,
pr);
if (ret) {
- ehea_error("failed registering irq for ehea_queue "
- "port_res_nr:%d, ist=%X", i,
- pr->eq->attr.ist1);
+ netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n",
+ i, pr->eq->attr.ist1);
goto out_free_req;
}
- if (netif_msg_ifup(port))
- ehea_info("irq_handle 0x%X for function ehea_queue_int "
- "%d registered", pr->eq->attr.ist1, i);
+ netif_info(port, ifup, dev,
+ "irq_handle 0x%X for function ehea_queue_int %d registered\n",
+ pr->eq->attr.ist1, i);
}
out:
return ret;
@@ -1411,16 +1410,16 @@ static void ehea_free_interrupts(struct net_device *dev)
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
pr = &port->port_res[i];
ibmebus_free_irq(pr->eq->attr.ist1, pr);
- if (netif_msg_intr(port))
- ehea_info("free send irq for res %d with handle 0x%X",
- i, pr->eq->attr.ist1);
+ netif_info(port, intr, dev,
+ "free send irq for res %d with handle 0x%X\n",
+ i, pr->eq->attr.ist1);
}
/* associated events */
ibmebus_free_irq(port->qp_eq->attr.ist1, port);
- if (netif_msg_intr(port))
- ehea_info("associated event interrupt for handle 0x%X freed",
- port->qp_eq->attr.ist1);
+ netif_info(port, intr, dev,
+ "associated event interrupt for handle 0x%X freed\n",
+ port->qp_eq->attr.ist1);
}
static int ehea_configure_port(struct ehea_port *port)
@@ -1489,7 +1488,7 @@ int ehea_gen_smrs(struct ehea_port_res *pr)
out_free:
ehea_rem_mr(&pr->send_mr);
out:
- ehea_error("Generating SMRS failed\n");
+ pr_err("Generating SMRS failed\n");
return -EIO;
}
@@ -1506,12 +1505,10 @@ static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries)
{
int arr_size = sizeof(void *) * max_q_entries;
- q_skba->arr = vmalloc(arr_size);
+ q_skba->arr = vzalloc(arr_size);
if (!q_skba->arr)
return -ENOMEM;
- memset(q_skba->arr, 0, arr_size);
-
q_skba->len = max_q_entries;
q_skba->index = 0;
q_skba->os_skbs = 0;
@@ -1546,7 +1543,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0);
if (!pr->eq) {
- ehea_error("create_eq failed (eq)");
+ pr_err("create_eq failed (eq)\n");
goto out_free;
}
@@ -1554,7 +1551,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
pr->eq->fw_handle,
port->logical_port_id);
if (!pr->recv_cq) {
- ehea_error("create_cq failed (cq_recv)");
+ pr_err("create_cq failed (cq_recv)\n");
goto out_free;
}
@@ -1562,19 +1559,19 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
pr->eq->fw_handle,
port->logical_port_id);
if (!pr->send_cq) {
- ehea_error("create_cq failed (cq_send)");
+ pr_err("create_cq failed (cq_send)\n");
goto out_free;
}
if (netif_msg_ifup(port))
- ehea_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d",
- pr->send_cq->attr.act_nr_of_cqes,
- pr->recv_cq->attr.act_nr_of_cqes);
+ pr_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d\n",
+ pr->send_cq->attr.act_nr_of_cqes,
+ pr->recv_cq->attr.act_nr_of_cqes);
init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL);
if (!init_attr) {
ret = -ENOMEM;
- ehea_error("no mem for ehea_qp_init_attr");
+ pr_err("no mem for ehea_qp_init_attr\n");
goto out_free;
}
@@ -1599,18 +1596,18 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
pr->qp = ehea_create_qp(adapter, adapter->pd, init_attr);
if (!pr->qp) {
- ehea_error("create_qp failed");
+ pr_err("create_qp failed\n");
ret = -EIO;
goto out_free;
}
if (netif_msg_ifup(port))
- ehea_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n "
- "nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d", init_attr->qp_nr,
- init_attr->act_nr_send_wqes,
- init_attr->act_nr_rwqes_rq1,
- init_attr->act_nr_rwqes_rq2,
- init_attr->act_nr_rwqes_rq3);
+ pr_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d\n",
+ init_attr->qp_nr,
+ init_attr->act_nr_send_wqes,
+ init_attr->act_nr_rwqes_rq1,
+ init_attr->act_nr_rwqes_rq2,
+ init_attr->act_nr_rwqes_rq3);
pr->sq_skba_size = init_attr->act_nr_send_wqes + 1;
@@ -1761,7 +1758,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
swqe->descriptors++;
}
} else
- ehea_error("cannot handle fragmented headers");
+ pr_err("cannot handle fragmented headers\n");
}
static void write_swqe2_nonTSO(struct sk_buff *skb,
@@ -1857,8 +1854,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
port->logical_port_id,
reg_type, port->mac_addr, 0, hcallid);
if (hret != H_SUCCESS) {
- ehea_error("%sregistering bc address failed (tagged)",
- hcallid == H_REG_BCMC ? "" : "de");
+ pr_err("%sregistering bc address failed (tagged)\n",
+ hcallid == H_REG_BCMC ? "" : "de");
ret = -EIO;
goto out_herr;
}
@@ -1869,8 +1866,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
port->logical_port_id,
reg_type, port->mac_addr, 0, hcallid);
if (hret != H_SUCCESS) {
- ehea_error("%sregistering bc address failed (vlan)",
- hcallid == H_REG_BCMC ? "" : "de");
+ pr_err("%sregistering bc address failed (vlan)\n",
+ hcallid == H_REG_BCMC ? "" : "de");
ret = -EIO;
}
out_herr:
@@ -1892,7 +1889,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
- ehea_error("no mem for cb0");
+ pr_err("no mem for cb0\n");
ret = -ENOMEM;
goto out;
}
@@ -1940,11 +1937,11 @@ out:
static void ehea_promiscuous_error(u64 hret, int enable)
{
if (hret == H_AUTHORITY)
- ehea_info("Hypervisor denied %sabling promiscuous mode",
- enable == 1 ? "en" : "dis");
+ pr_info("Hypervisor denied %sabling promiscuous mode\n",
+ enable == 1 ? "en" : "dis");
else
- ehea_error("failed %sabling promiscuous mode",
- enable == 1 ? "en" : "dis");
+ pr_err("failed %sabling promiscuous mode\n",
+ enable == 1 ? "en" : "dis");
}
static void ehea_promiscuous(struct net_device *dev, int enable)
@@ -1958,7 +1955,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
cb7 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb7) {
- ehea_error("no mem for cb7");
+ pr_err("no mem for cb7\n");
goto out;
}
@@ -2018,7 +2015,7 @@ static int ehea_drop_multicast_list(struct net_device *dev)
hret = ehea_multicast_reg_helper(port, mc_entry->macaddr,
H_DEREG_BCMC);
if (hret) {
- ehea_error("failed deregistering mcast MAC");
+ pr_err("failed deregistering mcast MAC\n");
ret = -EIO;
}
@@ -2041,7 +2038,8 @@ static void ehea_allmulti(struct net_device *dev, int enable)
if (!hret)
port->allmulti = 1;
else
- ehea_error("failed enabling IFF_ALLMULTI");
+ netdev_err(dev,
+ "failed enabling IFF_ALLMULTI\n");
}
} else
if (!enable) {
@@ -2050,7 +2048,8 @@ static void ehea_allmulti(struct net_device *dev, int enable)
if (!hret)
port->allmulti = 0;
else
- ehea_error("failed disabling IFF_ALLMULTI");
+ netdev_err(dev,
+ "failed disabling IFF_ALLMULTI\n");
}
}
@@ -2061,7 +2060,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC);
if (!ehea_mcl_entry) {
- ehea_error("no mem for mcl_entry");
+ pr_err("no mem for mcl_entry\n");
return;
}
@@ -2074,7 +2073,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
if (!hret)
list_add(&ehea_mcl_entry->list, &port->mc_list->list);
else {
- ehea_error("failed registering mcast MAC");
+ pr_err("failed registering mcast MAC\n");
kfree(ehea_mcl_entry);
}
}
@@ -2107,9 +2106,8 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
if (netdev_mc_count(dev) > port->adapter->max_mc_mac) {
- ehea_info("Mcast registration limit reached (0x%llx). "
- "Use ALLMULTI!",
- port->adapter->max_mc_mac);
+ pr_info("Mcast registration limit reached (0x%llx). Use ALLMULTI!\n",
+ port->adapter->max_mc_mac);
goto out;
}
@@ -2315,10 +2313,10 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
pr->swqe_id_counter += 1;
- if (netif_msg_tx_queued(port)) {
- ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr);
+ netif_info(port, tx_queued, dev,
+ "post swqe on QP %d\n", pr->qp->init_attr.qp_nr);
+ if (netif_msg_tx_queued(port))
ehea_dump(swqe, 512, "swqe");
- }
if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) {
netif_stop_queue(dev);
@@ -2354,14 +2352,14 @@ static void ehea_vlan_rx_register(struct net_device *dev,
cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
- ehea_error("no mem for cb1");
+ pr_err("no mem for cb1\n");
goto out;
}
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
if (hret != H_SUCCESS)
- ehea_error("modify_ehea_port failed");
+ pr_err("modify_ehea_port failed\n");
free_page((unsigned long)cb1);
out:
@@ -2378,14 +2376,14 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
- ehea_error("no mem for cb1");
+ pr_err("no mem for cb1\n");
goto out;
}
hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_port failed");
+ pr_err("query_ehea_port failed\n");
goto out;
}
@@ -2395,7 +2393,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
if (hret != H_SUCCESS)
- ehea_error("modify_ehea_port failed");
+ pr_err("modify_ehea_port failed\n");
out:
free_page((unsigned long)cb1);
return;
@@ -2413,14 +2411,14 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
- ehea_error("no mem for cb1");
+ pr_err("no mem for cb1\n");
goto out;
}
hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_port failed");
+ pr_err("query_ehea_port failed\n");
goto out;
}
@@ -2430,7 +2428,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
if (hret != H_SUCCESS)
- ehea_error("modify_ehea_port failed");
+ pr_err("modify_ehea_port failed\n");
out:
free_page((unsigned long)cb1);
}
@@ -2452,7 +2450,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (1)");
+ pr_err("query_ehea_qp failed (1)\n");
goto out;
}
@@ -2461,14 +2459,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0,
&dummy64, &dummy64, &dummy16, &dummy16);
if (hret != H_SUCCESS) {
- ehea_error("modify_ehea_qp failed (1)");
+ pr_err("modify_ehea_qp failed (1)\n");
goto out;
}
hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (2)");
+ pr_err("query_ehea_qp failed (2)\n");
goto out;
}
@@ -2477,14 +2475,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0,
&dummy64, &dummy64, &dummy16, &dummy16);
if (hret != H_SUCCESS) {
- ehea_error("modify_ehea_qp failed (2)");
+ pr_err("modify_ehea_qp failed (2)\n");
goto out;
}
hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (3)");
+ pr_err("query_ehea_qp failed (3)\n");
goto out;
}
@@ -2493,14 +2491,14 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0,
&dummy64, &dummy64, &dummy16, &dummy16);
if (hret != H_SUCCESS) {
- ehea_error("modify_ehea_qp failed (3)");
+ pr_err("modify_ehea_qp failed (3)\n");
goto out;
}
hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (4)");
+ pr_err("query_ehea_qp failed (4)\n");
goto out;
}
@@ -2521,7 +2519,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps,
EHEA_MAX_ENTRIES_EQ, 1);
if (!port->qp_eq) {
ret = -EINVAL;
- ehea_error("ehea_create_eq failed (qp_eq)");
+ pr_err("ehea_create_eq failed (qp_eq)\n");
goto out_kill_eq;
}
@@ -2602,27 +2600,27 @@ static int ehea_up(struct net_device *dev)
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
- ehea_error("port_res_failed");
+ netdev_err(dev, "port_res_failed\n");
goto out;
}
/* Set default QP for this port */
ret = ehea_configure_port(port);
if (ret) {
- ehea_error("ehea_configure_port failed. ret:%d", ret);
+ netdev_err(dev, "ehea_configure_port failed. ret:%d\n", ret);
goto out_clean_pr;
}
ret = ehea_reg_interrupts(dev);
if (ret) {
- ehea_error("reg_interrupts failed. ret:%d", ret);
+ netdev_err(dev, "reg_interrupts failed. ret:%d\n", ret);
goto out_clean_pr;
}
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
ret = ehea_activate_qp(port->adapter, port->port_res[i].qp);
if (ret) {
- ehea_error("activate_qp failed");
+ netdev_err(dev, "activate_qp failed\n");
goto out_free_irqs;
}
}
@@ -2630,7 +2628,7 @@ static int ehea_up(struct net_device *dev)
for (i = 0; i < port->num_def_qps; i++) {
ret = ehea_fill_port_res(&port->port_res[i]);
if (ret) {
- ehea_error("out_free_irqs");
+ netdev_err(dev, "out_free_irqs\n");
goto out_free_irqs;
}
}
@@ -2653,7 +2651,7 @@ out_clean_pr:
ehea_clean_all_portres(port);
out:
if (ret)
- ehea_info("Failed starting %s. ret=%i", dev->name, ret);
+ netdev_info(dev, "Failed starting. ret=%i\n", ret);
ehea_update_bcmc_registrations();
ehea_update_firmware_handles();
@@ -2684,8 +2682,7 @@ static int ehea_open(struct net_device *dev)
mutex_lock(&port->port_lock);
- if (netif_msg_ifup(port))
- ehea_info("enabling port %s", dev->name);
+ netif_info(port, ifup, dev, "enabling port\n");
ret = ehea_up(dev);
if (!ret) {
@@ -2720,8 +2717,7 @@ static int ehea_down(struct net_device *dev)
ret = ehea_clean_all_portres(port);
if (ret)
- ehea_info("Failed freeing resources for %s. ret=%i",
- dev->name, ret);
+ netdev_info(dev, "Failed freeing resources. ret=%i\n", ret);
ehea_update_firmware_handles();
@@ -2733,8 +2729,7 @@ static int ehea_stop(struct net_device *dev)
int ret;
struct ehea_port *port = netdev_priv(dev);
- if (netif_msg_ifdown(port))
- ehea_info("disabling port %s", dev->name);
+ netif_info(port, ifdown, dev, "disabling port\n");
set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags);
cancel_work_sync(&port->reset_task);
@@ -2775,7 +2770,7 @@ static void ehea_flush_sq(struct ehea_port *port)
msecs_to_jiffies(100));
if (!ret) {
- ehea_error("WARNING: sq not flushed completely");
+ pr_err("WARNING: sq not flushed completely\n");
break;
}
}
@@ -2811,7 +2806,7 @@ int ehea_stop_qps(struct net_device *dev)
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (1)");
+ pr_err("query_ehea_qp failed (1)\n");
goto out;
}
@@ -2823,7 +2818,7 @@ int ehea_stop_qps(struct net_device *dev)
1), cb0, &dummy64,
&dummy64, &dummy16, &dummy16);
if (hret != H_SUCCESS) {
- ehea_error("modify_ehea_qp failed (1)");
+ pr_err("modify_ehea_qp failed (1)\n");
goto out;
}
@@ -2831,14 +2826,14 @@ int ehea_stop_qps(struct net_device *dev)
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (2)");
+ pr_err("query_ehea_qp failed (2)\n");
goto out;
}
/* deregister shared memory regions */
dret = ehea_rem_smrs(pr);
if (dret) {
- ehea_error("unreg shared memory region failed");
+ pr_err("unreg shared memory region failed\n");
goto out;
}
}
@@ -2907,7 +2902,7 @@ int ehea_restart_qps(struct net_device *dev)
ret = ehea_gen_smrs(pr);
if (ret) {
- ehea_error("creation of shared memory regions failed");
+ netdev_err(dev, "creation of shared memory regions failed\n");
goto out;
}
@@ -2918,7 +2913,7 @@ int ehea_restart_qps(struct net_device *dev)
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (1)");
+ netdev_err(dev, "query_ehea_qp failed (1)\n");
goto out;
}
@@ -2930,7 +2925,7 @@ int ehea_restart_qps(struct net_device *dev)
1), cb0, &dummy64,
&dummy64, &dummy16, &dummy16);
if (hret != H_SUCCESS) {
- ehea_error("modify_ehea_qp failed (1)");
+ netdev_err(dev, "modify_ehea_qp failed (1)\n");
goto out;
}
@@ -2938,7 +2933,7 @@ int ehea_restart_qps(struct net_device *dev)
EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
cb0);
if (hret != H_SUCCESS) {
- ehea_error("query_ehea_qp failed (2)");
+ netdev_err(dev, "query_ehea_qp failed (2)\n");
goto out;
}
@@ -2975,8 +2970,7 @@ static void ehea_reset_port(struct work_struct *work)
ehea_set_multicast_list(dev);
- if (netif_msg_timer(port))
- ehea_info("Device %s resetted successfully", dev->name);
+ netif_info(port, timer, dev, "reset successful\n");
port_napi_enable(port);
@@ -2986,12 +2980,12 @@ out:
mutex_unlock(&dlpar_mem_lock);
}
-static void ehea_rereg_mrs(struct work_struct *work)
+static void ehea_rereg_mrs(void)
{
int ret, i;
struct ehea_adapter *adapter;
- ehea_info("LPAR memory changed - re-initializing driver");
+ pr_info("LPAR memory changed - re-initializing driver\n");
list_for_each_entry(adapter, &adapter_list, list)
if (adapter->active_ports) {
@@ -3023,8 +3017,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
/* Unregister old memory region */
ret = ehea_rem_mr(&adapter->mr);
if (ret) {
- ehea_error("unregister MR failed - driver"
- " inoperable!");
+ pr_err("unregister MR failed - driver inoperable!\n");
goto out;
}
}
@@ -3036,8 +3029,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
/* Register new memory region */
ret = ehea_reg_kernel_mr(adapter, &adapter->mr);
if (ret) {
- ehea_error("register MR failed - driver"
- " inoperable!");
+ pr_err("register MR failed - driver inoperable!\n");
goto out;
}
@@ -3060,7 +3052,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
}
}
}
- ehea_info("re-initializing driver complete");
+ pr_info("re-initializing driver complete\n");
out:
return;
}
@@ -3113,7 +3105,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
/* (Try to) enable *jumbo frames */
cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
- ehea_error("no mem for cb4");
+ pr_err("no mem for cb4\n");
ret = -ENOMEM;
goto out;
} else {
@@ -3175,13 +3167,13 @@ static struct device *ehea_register_port(struct ehea_port *port,
ret = of_device_register(&port->ofdev);
if (ret) {
- ehea_error("failed to register device. ret=%d", ret);
+ pr_err("failed to register device. ret=%d\n", ret);
goto out;
}
ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
if (ret) {
- ehea_error("failed to register attributes, ret=%d", ret);
+ pr_err("failed to register attributes, ret=%d\n", ret);
goto out_unreg_of_dev;
}
@@ -3231,7 +3223,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev = alloc_etherdev(sizeof(struct ehea_port));
if (!dev) {
- ehea_error("no mem for net_device");
+ pr_err("no mem for net_device\n");
ret = -ENOMEM;
goto out_err;
}
@@ -3278,11 +3270,14 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
| NETIF_F_LLTX;
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
+ if (use_lro)
+ dev->features |= NETIF_F_LRO;
+
INIT_WORK(&port->reset_task, ehea_reset_port);
ret = register_netdev(dev);
if (ret) {
- ehea_error("register_netdev failed. ret=%d", ret);
+ pr_err("register_netdev failed. ret=%d\n", ret);
goto out_unreg_port;
}
@@ -3290,11 +3285,10 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
ret = ehea_get_jumboframe_status(port, &jumbo);
if (ret)
- ehea_error("failed determining jumbo frame status for %s",
- port->netdev->name);
+ netdev_err(dev, "failed determining jumbo frame status\n");
- ehea_info("%s: Jumbo frames are %sabled", dev->name,
- jumbo == 1 ? "en" : "dis");
+ netdev_info(dev, "Jumbo frames are %sabled\n",
+ jumbo == 1 ? "en" : "dis");
adapter->active_ports++;
@@ -3310,14 +3304,16 @@ out_free_ethdev:
free_netdev(dev);
out_err:
- ehea_error("setting up logical port with id=%d failed, ret=%d",
- logical_port_id, ret);
+ pr_err("setting up logical port with id=%d failed, ret=%d\n",
+ logical_port_id, ret);
return NULL;
}
static void ehea_shutdown_single_port(struct ehea_port *port)
{
struct ehea_adapter *adapter = port->adapter;
+
+ cancel_work_sync(&port->reset_task);
unregister_netdev(port->netdev);
ehea_unregister_port(port);
kfree(port->mc_list);
@@ -3339,13 +3335,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
NULL);
if (!dn_log_port_id) {
- ehea_error("bad device node: eth_dn name=%s",
- eth_dn->full_name);
+ pr_err("bad device node: eth_dn name=%s\n",
+ eth_dn->full_name);
continue;
}
if (ehea_add_adapter_mr(adapter)) {
- ehea_error("creating MR failed");
+ pr_err("creating MR failed\n");
of_node_put(eth_dn);
return -EIO;
}
@@ -3354,9 +3350,8 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
*dn_log_port_id,
eth_dn);
if (adapter->port[i])
- ehea_info("%s -> logical port id #%d",
- adapter->port[i]->netdev->name,
- *dn_log_port_id);
+ netdev_info(adapter->port[i]->netdev,
+ "logical port id #%d\n", *dn_log_port_id);
else
ehea_remove_adapter_mr(adapter);
@@ -3401,21 +3396,20 @@ static ssize_t ehea_probe_port(struct device *dev,
port = ehea_get_port(adapter, logical_port_id);
if (port) {
- ehea_info("adding port with logical port id=%d failed. port "
- "already configured as %s.", logical_port_id,
- port->netdev->name);
+ netdev_info(port->netdev, "adding port with logical port id=%d failed: port already configured\n",
+ logical_port_id);
return -EINVAL;
}
eth_dn = ehea_get_eth_dn(adapter, logical_port_id);
if (!eth_dn) {
- ehea_info("no logical port with id %d found", logical_port_id);
+ pr_info("no logical port with id %d found\n", logical_port_id);
return -EINVAL;
}
if (ehea_add_adapter_mr(adapter)) {
- ehea_error("creating MR failed");
+ pr_err("creating MR failed\n");
return -EIO;
}
@@ -3430,8 +3424,8 @@ static ssize_t ehea_probe_port(struct device *dev,
break;
}
- ehea_info("added %s (logical port id=%d)", port->netdev->name,
- logical_port_id);
+ netdev_info(port->netdev, "added: (logical port id=%d)\n",
+ logical_port_id);
} else {
ehea_remove_adapter_mr(adapter);
return -EIO;
@@ -3454,8 +3448,8 @@ static ssize_t ehea_remove_port(struct device *dev,
port = ehea_get_port(adapter, logical_port_id);
if (port) {
- ehea_info("removed %s (logical port id=%d)", port->netdev->name,
- logical_port_id);
+ netdev_info(port->netdev, "removed: (logical port id=%d)\n",
+ logical_port_id);
ehea_shutdown_single_port(port);
@@ -3465,8 +3459,8 @@ static ssize_t ehea_remove_port(struct device *dev,
break;
}
} else {
- ehea_error("removing port with logical port id=%d failed. port "
- "not configured.", logical_port_id);
+ pr_err("removing port with logical port id=%d failed. port not configured.\n",
+ logical_port_id);
return -EINVAL;
}
@@ -3503,7 +3497,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
int ret;
if (!dev || !dev->dev.of_node) {
- ehea_error("Invalid ibmebus device probed");
+ pr_err("Invalid ibmebus device probed\n");
return -EINVAL;
}
@@ -3607,8 +3601,6 @@ static int __devexit ehea_remove(struct platform_device *dev)
ehea_remove_device_sysfs(dev);
- flush_scheduled_work();
-
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
@@ -3651,21 +3643,21 @@ static int ehea_mem_notifier(struct notifier_block *nb,
switch (action) {
case MEM_CANCEL_OFFLINE:
- ehea_info("memory offlining canceled");
+ pr_info("memory offlining canceled");
/* Readd canceled memory block */
case MEM_ONLINE:
- ehea_info("memory is going online");
+ pr_info("memory is going online");
set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
goto out_unlock;
- ehea_rereg_mrs(NULL);
+ ehea_rereg_mrs();
break;
case MEM_GOING_OFFLINE:
- ehea_info("memory is going offline");
+ pr_info("memory is going offline");
set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
goto out_unlock;
- ehea_rereg_mrs(NULL);
+ ehea_rereg_mrs();
break;
default:
break;
@@ -3687,7 +3679,7 @@ static int ehea_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *unused)
{
if (action == SYS_RESTART) {
- ehea_info("Reboot: freeing all eHEA resources");
+ pr_info("Reboot: freeing all eHEA resources\n");
ibmebus_unregister_driver(&ehea_driver);
}
return NOTIFY_DONE;
@@ -3703,22 +3695,22 @@ static int check_module_parm(void)
if ((rq1_entries < EHEA_MIN_ENTRIES_QP) ||
(rq1_entries > EHEA_MAX_ENTRIES_RQ1)) {
- ehea_info("Bad parameter: rq1_entries");
+ pr_info("Bad parameter: rq1_entries\n");
ret = -EINVAL;
}
if ((rq2_entries < EHEA_MIN_ENTRIES_QP) ||
(rq2_entries > EHEA_MAX_ENTRIES_RQ2)) {
- ehea_info("Bad parameter: rq2_entries");
+ pr_info("Bad parameter: rq2_entries\n");
ret = -EINVAL;
}
if ((rq3_entries < EHEA_MIN_ENTRIES_QP) ||
(rq3_entries > EHEA_MAX_ENTRIES_RQ3)) {
- ehea_info("Bad parameter: rq3_entries");
+ pr_info("Bad parameter: rq3_entries\n");
ret = -EINVAL;
}
if ((sq_entries < EHEA_MIN_ENTRIES_QP) ||
(sq_entries > EHEA_MAX_ENTRIES_SQ)) {
- ehea_info("Bad parameter: sq_entries");
+ pr_info("Bad parameter: sq_entries\n");
ret = -EINVAL;
}
@@ -3738,11 +3730,8 @@ int __init ehea_module_init(void)
{
int ret;
- printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n",
- DRV_VERSION);
-
+ pr_info("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION);
- INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
@@ -3759,27 +3748,27 @@ int __init ehea_module_init(void)
ret = register_reboot_notifier(&ehea_reboot_nb);
if (ret)
- ehea_info("failed registering reboot notifier");
+ pr_info("failed registering reboot notifier\n");
ret = register_memory_notifier(&ehea_mem_nb);
if (ret)
- ehea_info("failed registering memory remove notifier");
+ pr_info("failed registering memory remove notifier\n");
ret = crash_shutdown_register(ehea_crash_handler);
if (ret)
- ehea_info("failed registering crash handler");
+ pr_info("failed registering crash handler\n");
ret = ibmebus_register_driver(&ehea_driver);
if (ret) {
- ehea_error("failed registering eHEA device driver on ebus");
+ pr_err("failed registering eHEA device driver on ebus\n");
goto out2;
}
ret = driver_create_file(&ehea_driver.driver,
&driver_attr_capabilities);
if (ret) {
- ehea_error("failed to register capabilities attribute, ret=%d",
- ret);
+ pr_err("failed to register capabilities attribute, ret=%d\n",
+ ret);
goto out3;
}
@@ -3799,13 +3788,12 @@ static void __exit ehea_module_exit(void)
{
int ret;
- flush_scheduled_work();
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
ret = crash_shutdown_unregister(ehea_crash_handler);
if (ret)
- ehea_info("failed unregistering crash handler");
+ pr_info("failed unregistering crash handler\n");
unregister_memory_notifier(&ehea_mem_nb);
kfree(ehea_fw_handles.arr);
kfree(ehea_bcmc_regs.arr);
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index 8fe9dcaa7538..0506967b9044 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -26,6 +26,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "ehea_phyp.h"
@@ -67,12 +69,11 @@ static long ehea_plpar_hcall_norets(unsigned long opcode,
}
if (ret < H_SUCCESS)
- ehea_error("opcode=%lx ret=%lx"
- " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
- " arg5=%lx arg6=%lx arg7=%lx ",
- opcode, ret,
- arg1, arg2, arg3, arg4, arg5,
- arg6, arg7);
+ pr_err("opcode=%lx ret=%lx"
+ " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+ " arg5=%lx arg6=%lx arg7=%lx\n",
+ opcode, ret,
+ arg1, arg2, arg3, arg4, arg5, arg6, arg7);
return ret;
}
@@ -114,19 +115,18 @@ static long ehea_plpar_hcall9(unsigned long opcode,
&& (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO)
|| (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7)
&& (arg3 == H_PORT_CB7_DUCQPN)))))
- ehea_error("opcode=%lx ret=%lx"
- " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
- " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
- " arg9=%lx"
- " out1=%lx out2=%lx out3=%lx out4=%lx"
- " out5=%lx out6=%lx out7=%lx out8=%lx"
- " out9=%lx",
- opcode, ret,
- arg1, arg2, arg3, arg4, arg5,
- arg6, arg7, arg8, arg9,
- outs[0], outs[1], outs[2], outs[3],
- outs[4], outs[5], outs[6], outs[7],
- outs[8]);
+ pr_err("opcode=%lx ret=%lx"
+ " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+ " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
+ " arg9=%lx"
+ " out1=%lx out2=%lx out3=%lx out4=%lx"
+ " out5=%lx out6=%lx out7=%lx out8=%lx"
+ " out9=%lx\n",
+ opcode, ret,
+ arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8, arg9,
+ outs[0], outs[1], outs[2], outs[3], outs[4],
+ outs[5], outs[6], outs[7], outs[8]);
return ret;
}
@@ -515,7 +515,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle,
const u64 log_pageaddr, const u64 count)
{
if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) {
- ehea_error("not on pageboundary");
+ pr_err("not on pageboundary\n");
return H_PARAMETER;
}
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 89128b6373e3..cd44bb8017d9 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -26,6 +26,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/mm.h>
#include <linux/slab.h>
#include "ehea.h"
@@ -45,7 +47,7 @@ static void *hw_qpageit_get_inc(struct hw_queue *queue)
queue->current_q_offset -= queue->pagesize;
retvalue = NULL;
} else if (((u64) retvalue) & (EHEA_PAGESIZE-1)) {
- ehea_error("not on pageboundary");
+ pr_err("not on pageboundary\n");
retvalue = NULL;
}
return retvalue;
@@ -58,15 +60,15 @@ static int hw_queue_ctor(struct hw_queue *queue, const u32 nr_of_pages,
int i, k;
if ((pagesize > PAGE_SIZE) || (!pages_per_kpage)) {
- ehea_error("pagesize conflict! kernel pagesize=%d, "
- "ehea pagesize=%d", (int)PAGE_SIZE, (int)pagesize);
+ pr_err("pagesize conflict! kernel pagesize=%d, ehea pagesize=%d\n",
+ (int)PAGE_SIZE, (int)pagesize);
return -EINVAL;
}
queue->queue_length = nr_of_pages * pagesize;
queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
if (!queue->queue_pages) {
- ehea_error("no mem for queue_pages");
+ pr_err("no mem for queue_pages\n");
return -ENOMEM;
}
@@ -130,7 +132,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
cq = kzalloc(sizeof(*cq), GFP_KERNEL);
if (!cq) {
- ehea_error("no mem for cq");
+ pr_err("no mem for cq\n");
goto out_nomem;
}
@@ -147,7 +149,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
hret = ehea_h_alloc_resource_cq(adapter->handle, &cq->attr,
&cq->fw_handle, &cq->epas);
if (hret != H_SUCCESS) {
- ehea_error("alloc_resource_cq failed");
+ pr_err("alloc_resource_cq failed\n");
goto out_freemem;
}
@@ -159,7 +161,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
for (counter = 0; counter < cq->attr.nr_pages; counter++) {
vpage = hw_qpageit_get_inc(&cq->hw_queue);
if (!vpage) {
- ehea_error("hw_qpageit_get_inc failed");
+ pr_err("hw_qpageit_get_inc failed\n");
goto out_kill_hwq;
}
@@ -168,9 +170,8 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
0, EHEA_CQ_REGISTER_ORIG,
cq->fw_handle, rpage, 1);
if (hret < H_SUCCESS) {
- ehea_error("register_rpage_cq failed ehea_cq=%p "
- "hret=%llx counter=%i act_pages=%i",
- cq, hret, counter, cq->attr.nr_pages);
+ pr_err("register_rpage_cq failed ehea_cq=%p hret=%llx counter=%i act_pages=%i\n",
+ cq, hret, counter, cq->attr.nr_pages);
goto out_kill_hwq;
}
@@ -178,14 +179,14 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
vpage = hw_qpageit_get_inc(&cq->hw_queue);
if ((hret != H_SUCCESS) || (vpage)) {
- ehea_error("registration of pages not "
- "complete hret=%llx\n", hret);
+ pr_err("registration of pages not complete hret=%llx\n",
+ hret);
goto out_kill_hwq;
}
} else {
if (hret != H_PAGE_REGISTERED) {
- ehea_error("CQ: registration of page failed "
- "hret=%llx\n", hret);
+ pr_err("CQ: registration of page failed hret=%llx\n",
+ hret);
goto out_kill_hwq;
}
}
@@ -241,7 +242,7 @@ int ehea_destroy_cq(struct ehea_cq *cq)
}
if (hret != H_SUCCESS) {
- ehea_error("destroy CQ failed");
+ pr_err("destroy CQ failed\n");
return -EIO;
}
@@ -259,7 +260,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
eq = kzalloc(sizeof(*eq), GFP_KERNEL);
if (!eq) {
- ehea_error("no mem for eq");
+ pr_err("no mem for eq\n");
return NULL;
}
@@ -272,21 +273,21 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
hret = ehea_h_alloc_resource_eq(adapter->handle,
&eq->attr, &eq->fw_handle);
if (hret != H_SUCCESS) {
- ehea_error("alloc_resource_eq failed");
+ pr_err("alloc_resource_eq failed\n");
goto out_freemem;
}
ret = hw_queue_ctor(&eq->hw_queue, eq->attr.nr_pages,
EHEA_PAGESIZE, sizeof(struct ehea_eqe));
if (ret) {
- ehea_error("can't allocate eq pages");
+ pr_err("can't allocate eq pages\n");
goto out_freeres;
}
for (i = 0; i < eq->attr.nr_pages; i++) {
vpage = hw_qpageit_get_inc(&eq->hw_queue);
if (!vpage) {
- ehea_error("hw_qpageit_get_inc failed");
+ pr_err("hw_qpageit_get_inc failed\n");
hret = H_RESOURCE;
goto out_kill_hwq;
}
@@ -370,7 +371,7 @@ int ehea_destroy_eq(struct ehea_eq *eq)
}
if (hret != H_SUCCESS) {
- ehea_error("destroy EQ failed");
+ pr_err("destroy EQ failed\n");
return -EIO;
}
@@ -395,7 +396,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue,
for (cnt = 0; cnt < nr_pages; cnt++) {
vpage = hw_qpageit_get_inc(hw_queue);
if (!vpage) {
- ehea_error("hw_qpageit_get_inc failed");
+ pr_err("hw_qpageit_get_inc failed\n");
goto out_kill_hwq;
}
rpage = virt_to_abs(vpage);
@@ -403,7 +404,7 @@ int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue,
0, h_call_q_selector,
qp->fw_handle, rpage, 1);
if (hret < H_SUCCESS) {
- ehea_error("register_rpage_qp failed");
+ pr_err("register_rpage_qp failed\n");
goto out_kill_hwq;
}
}
@@ -432,7 +433,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
qp = kzalloc(sizeof(*qp), GFP_KERNEL);
if (!qp) {
- ehea_error("no mem for qp");
+ pr_err("no mem for qp\n");
return NULL;
}
@@ -441,7 +442,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
hret = ehea_h_alloc_resource_qp(adapter->handle, init_attr, pd,
&qp->fw_handle, &qp->epas);
if (hret != H_SUCCESS) {
- ehea_error("ehea_h_alloc_resource_qp failed");
+ pr_err("ehea_h_alloc_resource_qp failed\n");
goto out_freemem;
}
@@ -455,7 +456,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
init_attr->act_wqe_size_enc_sq, adapter,
0);
if (ret) {
- ehea_error("can't register for sq ret=%x", ret);
+ pr_err("can't register for sq ret=%x\n", ret);
goto out_freeres;
}
@@ -465,7 +466,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
init_attr->act_wqe_size_enc_rq1,
adapter, 1);
if (ret) {
- ehea_error("can't register for rq1 ret=%x", ret);
+ pr_err("can't register for rq1 ret=%x\n", ret);
goto out_kill_hwsq;
}
@@ -476,7 +477,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
init_attr->act_wqe_size_enc_rq2,
adapter, 2);
if (ret) {
- ehea_error("can't register for rq2 ret=%x", ret);
+ pr_err("can't register for rq2 ret=%x\n", ret);
goto out_kill_hwr1q;
}
}
@@ -488,7 +489,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
init_attr->act_wqe_size_enc_rq3,
adapter, 3);
if (ret) {
- ehea_error("can't register for rq3 ret=%x", ret);
+ pr_err("can't register for rq3 ret=%x\n", ret);
goto out_kill_hwr2q;
}
}
@@ -553,7 +554,7 @@ int ehea_destroy_qp(struct ehea_qp *qp)
}
if (hret != H_SUCCESS) {
- ehea_error("destroy QP failed");
+ pr_err("destroy QP failed\n");
return -EIO;
}
@@ -842,7 +843,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
(hret != H_PAGE_REGISTERED)) {
ehea_h_free_resource(adapter->handle, mr->handle,
FORCE_FREE);
- ehea_error("register_rpage_mr failed");
+ pr_err("register_rpage_mr failed\n");
return hret;
}
}
@@ -896,7 +897,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
pt = (void *)get_zeroed_page(GFP_KERNEL);
if (!pt) {
- ehea_error("no mem");
+ pr_err("no mem\n");
ret = -ENOMEM;
goto out;
}
@@ -906,14 +907,14 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
&mr->handle, &mr->lkey);
if (hret != H_SUCCESS) {
- ehea_error("alloc_resource_mr failed");
+ pr_err("alloc_resource_mr failed\n");
ret = -EIO;
goto out;
}
if (!ehea_bmap) {
ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
- ehea_error("no busmap available");
+ pr_err("no busmap available\n");
ret = -EIO;
goto out;
}
@@ -929,7 +930,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
if (hret != H_SUCCESS) {
ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
- ehea_error("registering mr failed");
+ pr_err("registering mr failed\n");
ret = -EIO;
goto out;
}
@@ -952,7 +953,7 @@ int ehea_rem_mr(struct ehea_mr *mr)
hret = ehea_h_free_resource(mr->adapter->handle, mr->handle,
FORCE_FREE);
if (hret != H_SUCCESS) {
- ehea_error("destroy MR failed");
+ pr_err("destroy MR failed\n");
return -EIO;
}
@@ -987,14 +988,14 @@ void print_error_data(u64 *data)
length = EHEA_PAGESIZE;
if (type == EHEA_AER_RESTYPE_QP)
- ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, "
- "port=%llX", resource, data[6], data[12], data[22]);
+ pr_err("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, port=%llX\n",
+ resource, data[6], data[12], data[22]);
else if (type == EHEA_AER_RESTYPE_CQ)
- ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource,
- data[6]);
+ pr_err("CQ (resource=%llX) state: AER=0x%llX\n",
+ resource, data[6]);
else if (type == EHEA_AER_RESTYPE_EQ)
- ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource,
- data[6]);
+ pr_err("EQ (resource=%llX) state: AER=0x%llX\n",
+ resource, data[6]);
ehea_dump(data, length, "error data");
}
@@ -1008,7 +1009,7 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle,
rblock = (void *)get_zeroed_page(GFP_KERNEL);
if (!rblock) {
- ehea_error("Cannot allocate rblock memory.");
+ pr_err("Cannot allocate rblock memory\n");
goto out;
}
@@ -1020,9 +1021,9 @@ u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle,
*aerr = rblock[12];
print_error_data(rblock);
} else if (ret == H_R_STATE) {
- ehea_error("No error data available: %llX.", res_handle);
+ pr_err("No error data available: %llX\n", res_handle);
} else
- ehea_error("Error data could not be fetched: %llX", res_handle);
+ pr_err("Error data could not be fetched: %llX\n", res_handle);
free_page((unsigned long)rblock);
out:
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index c91d364c5527..a937f49d9db7 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.4.1.6"
+#define DRV_VERSION "1.4.1.10"
#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -61,6 +61,8 @@ struct enic_port_profile {
char name[PORT_PROFILE_MAX];
u8 instance_uuid[PORT_UUID_MAX];
u8 host_uuid[PORT_UUID_MAX];
+ u8 vf_mac[ETH_ALEN];
+ u8 mac_addr[ETH_ALEN];
};
/* Per-instance private data structure */
@@ -78,8 +80,10 @@ struct enic {
spinlock_t devcmd_lock;
u8 mac_addr[ETH_ALEN];
u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
+ u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
unsigned int flags;
unsigned int mc_count;
+ unsigned int uc_count;
int csum_rx_enabled;
u32 port_mtu;
u32 rx_coalesce_usecs;
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index a466ef91dd43..a0af48c51fb3 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -702,7 +702,7 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
{
unsigned int head_len = skb_headlen(skb);
unsigned int len_left = skb->len - head_len;
- unsigned int hdr_len = skb_transport_offset(skb);
+ unsigned int hdr_len = skb_checksum_start_offset(skb);
unsigned int csum_offset = hdr_len + skb->csum_offset;
int eop = (len_left == 0);
@@ -1002,7 +1002,7 @@ static int enic_dev_packet_filter(struct enic *enic, int directed,
return err;
}
-static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
+static int enic_dev_add_addr(struct enic *enic, u8 *addr)
{
int err;
@@ -1013,7 +1013,7 @@ static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
return err;
}
-static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
+static int enic_dev_del_addr(struct enic *enic, u8 *addr)
{
int err;
@@ -1024,29 +1024,19 @@ static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
return err;
}
-/* netif_tx_lock held, BHs disabled */
-static void enic_set_multicast_list(struct net_device *netdev)
+static void enic_add_multicast_addr_list(struct enic *enic)
{
- struct enic *enic = netdev_priv(netdev);
+ struct net_device *netdev = enic->netdev;
struct netdev_hw_addr *ha;
- int directed = 1;
- int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
- int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
- int promisc = (netdev->flags & IFF_PROMISC) ? 1 : 0;
unsigned int mc_count = netdev_mc_count(netdev);
- int allmulti = (netdev->flags & IFF_ALLMULTI) ||
- mc_count > ENIC_MULTICAST_PERFECT_FILTERS;
- unsigned int flags = netdev->flags | (allmulti ? IFF_ALLMULTI : 0);
u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
unsigned int i, j;
- if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS)
+ if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) {
+ netdev_warn(netdev, "Registering only %d out of %d "
+ "multicast addresses\n",
+ ENIC_MULTICAST_PERFECT_FILTERS, mc_count);
mc_count = ENIC_MULTICAST_PERFECT_FILTERS;
-
- if (enic->flags != flags) {
- enic->flags = flags;
- enic_dev_packet_filter(enic, directed,
- multicast, broadcast, promisc, allmulti);
}
/* Is there an easier way? Trying to minimize to
@@ -1068,7 +1058,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
mc_addr[j]) == 0)
break;
if (j == mc_count)
- enic_dev_del_multicast_addr(enic, enic->mc_addr[i]);
+ enic_dev_del_addr(enic, enic->mc_addr[i]);
}
for (i = 0; i < mc_count; i++) {
@@ -1077,7 +1067,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
enic->mc_addr[j]) == 0)
break;
if (j == enic->mc_count)
- enic_dev_add_multicast_addr(enic, mc_addr[i]);
+ enic_dev_add_addr(enic, mc_addr[i]);
}
/* Save the list to compare against next time
@@ -1089,6 +1079,89 @@ static void enic_set_multicast_list(struct net_device *netdev)
enic->mc_count = mc_count;
}
+static void enic_add_unicast_addr_list(struct enic *enic)
+{
+ struct net_device *netdev = enic->netdev;
+ struct netdev_hw_addr *ha;
+ unsigned int uc_count = netdev_uc_count(netdev);
+ u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
+ unsigned int i, j;
+
+ if (uc_count > ENIC_UNICAST_PERFECT_FILTERS) {
+ netdev_warn(netdev, "Registering only %d out of %d "
+ "unicast addresses\n",
+ ENIC_UNICAST_PERFECT_FILTERS, uc_count);
+ uc_count = ENIC_UNICAST_PERFECT_FILTERS;
+ }
+
+ /* Is there an easier way? Trying to minimize to
+ * calls to add/del unicast addrs. We keep the
+ * addrs from the last call in enic->uc_addr and
+ * look for changes to add/del.
+ */
+
+ i = 0;
+ netdev_for_each_uc_addr(ha, netdev) {
+ if (i == uc_count)
+ break;
+ memcpy(uc_addr[i++], ha->addr, ETH_ALEN);
+ }
+
+ for (i = 0; i < enic->uc_count; i++) {
+ for (j = 0; j < uc_count; j++)
+ if (compare_ether_addr(enic->uc_addr[i],
+ uc_addr[j]) == 0)
+ break;
+ if (j == uc_count)
+ enic_dev_del_addr(enic, enic->uc_addr[i]);
+ }
+
+ for (i = 0; i < uc_count; i++) {
+ for (j = 0; j < enic->uc_count; j++)
+ if (compare_ether_addr(uc_addr[i],
+ enic->uc_addr[j]) == 0)
+ break;
+ if (j == enic->uc_count)
+ enic_dev_add_addr(enic, uc_addr[i]);
+ }
+
+ /* Save the list to compare against next time
+ */
+
+ for (i = 0; i < uc_count; i++)
+ memcpy(enic->uc_addr[i], uc_addr[i], ETH_ALEN);
+
+ enic->uc_count = uc_count;
+}
+
+/* netif_tx_lock held, BHs disabled */
+static void enic_set_rx_mode(struct net_device *netdev)
+{
+ struct enic *enic = netdev_priv(netdev);
+ int directed = 1;
+ int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
+ int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
+ int promisc = (netdev->flags & IFF_PROMISC) ||
+ netdev_uc_count(netdev) > ENIC_UNICAST_PERFECT_FILTERS;
+ int allmulti = (netdev->flags & IFF_ALLMULTI) ||
+ netdev_mc_count(netdev) > ENIC_MULTICAST_PERFECT_FILTERS;
+ unsigned int flags = netdev->flags |
+ (allmulti ? IFF_ALLMULTI : 0) |
+ (promisc ? IFF_PROMISC : 0);
+
+ if (enic->flags != flags) {
+ enic->flags = flags;
+ enic_dev_packet_filter(enic, directed,
+ multicast, broadcast, promisc, allmulti);
+ }
+
+ if (!promisc) {
+ enic_add_unicast_addr_list(enic);
+ if (!allmulti)
+ enic_add_multicast_addr_list(enic);
+ }
+}
+
/* rtnl lock is held */
static void enic_vlan_rx_register(struct net_device *netdev,
struct vlan_group *vlan_group)
@@ -1158,11 +1231,31 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error)
return err;
}
+static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+{
+ struct enic *enic = netdev_priv(netdev);
+
+ if (vf != PORT_SELF_VF)
+ return -EOPNOTSUPP;
+
+ /* Ignore the vf argument for now. We can assume the request
+ * is coming on a vf.
+ */
+ if (is_valid_ether_addr(mac)) {
+ memcpy(enic->pp.vf_mac, mac, ETH_ALEN);
+ return 0;
+ } else
+ return -EINVAL;
+}
+
static int enic_set_port_profile(struct enic *enic, u8 *mac)
{
struct vic_provinfo *vp;
u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
+ u16 os_type = VIC_GENERIC_PROV_OS_TYPE_LINUX;
char uuid_str[38];
+ char client_mac_str[18];
+ u8 *client_mac;
int err;
err = enic_vnic_dev_deinit(enic);
@@ -1180,46 +1273,63 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
return -EADDRNOTAVAIL;
vp = vic_provinfo_alloc(GFP_KERNEL, oui,
- VIC_PROVINFO_LINUX_TYPE);
+ VIC_PROVINFO_GENERIC_TYPE);
if (!vp)
return -ENOMEM;
vic_provinfo_add_tlv(vp,
- VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
+ VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
strlen(enic->pp.name) + 1, enic->pp.name);
+ if (!is_zero_ether_addr(enic->pp.mac_addr))
+ client_mac = enic->pp.mac_addr;
+ else
+ client_mac = mac;
+
+ vic_provinfo_add_tlv(vp,
+ VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
+ ETH_ALEN, client_mac);
+
+ sprintf(client_mac_str, "%pM", client_mac);
vic_provinfo_add_tlv(vp,
- VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
- ETH_ALEN, mac);
+ VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
+ sizeof(client_mac_str), client_mac_str);
if (enic->pp.set & ENIC_SET_INSTANCE) {
sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
vic_provinfo_add_tlv(vp,
- VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
+ VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
sizeof(uuid_str), uuid_str);
}
if (enic->pp.set & ENIC_SET_HOST) {
sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
vic_provinfo_add_tlv(vp,
- VIC_LINUX_PROV_TLV_HOST_UUID_STR,
+ VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
sizeof(uuid_str), uuid_str);
}
+ os_type = htons(os_type);
+ vic_provinfo_add_tlv(vp,
+ VIC_GENERIC_PROV_TLV_OS_TYPE,
+ sizeof(os_type), &os_type);
+
err = enic_dev_init_prov(enic, vp);
vic_provinfo_free(vp);
if (err)
return err;
+
+ enic->pp.set |= ENIC_SET_APPLIED;
break;
case PORT_REQUEST_DISASSOCIATE:
+ enic->pp.set &= ~ENIC_SET_APPLIED;
break;
default:
return -EINVAL;
}
- enic->pp.set |= ENIC_SET_APPLIED;
return 0;
}
@@ -1227,29 +1337,31 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
struct nlattr *port[])
{
struct enic *enic = netdev_priv(netdev);
+ struct enic_port_profile new_pp;
+ int err = 0;
- memset(&enic->pp, 0, sizeof(enic->pp));
+ memset(&new_pp, 0, sizeof(new_pp));
if (port[IFLA_PORT_REQUEST]) {
- enic->pp.set |= ENIC_SET_REQUEST;
- enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+ new_pp.set |= ENIC_SET_REQUEST;
+ new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
}
if (port[IFLA_PORT_PROFILE]) {
- enic->pp.set |= ENIC_SET_NAME;
- memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+ new_pp.set |= ENIC_SET_NAME;
+ memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]),
PORT_PROFILE_MAX);
}
if (port[IFLA_PORT_INSTANCE_UUID]) {
- enic->pp.set |= ENIC_SET_INSTANCE;
- memcpy(enic->pp.instance_uuid,
+ new_pp.set |= ENIC_SET_INSTANCE;
+ memcpy(new_pp.instance_uuid,
nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
}
if (port[IFLA_PORT_HOST_UUID]) {
- enic->pp.set |= ENIC_SET_HOST;
- memcpy(enic->pp.host_uuid,
+ new_pp.set |= ENIC_SET_HOST;
+ memcpy(new_pp.host_uuid,
nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
}
@@ -1257,21 +1369,39 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
if (vf != PORT_SELF_VF)
return -EOPNOTSUPP;
- if (!(enic->pp.set & ENIC_SET_REQUEST))
+ if (!(new_pp.set & ENIC_SET_REQUEST))
return -EOPNOTSUPP;
- if (enic->pp.request == PORT_REQUEST_ASSOCIATE) {
-
- /* If the interface mac addr hasn't been assigned,
- * assign a random mac addr before setting port-
- * profile.
- */
+ if (new_pp.request == PORT_REQUEST_ASSOCIATE) {
+ /* Special case handling */
+ if (!is_zero_ether_addr(enic->pp.vf_mac))
+ memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN);
if (is_zero_ether_addr(netdev->dev_addr))
random_ether_addr(netdev->dev_addr);
+ } else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) {
+ if (!is_zero_ether_addr(enic->pp.mac_addr))
+ enic_dev_del_addr(enic, enic->pp.mac_addr);
}
- return enic_set_port_profile(enic, netdev->dev_addr);
+ memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
+
+ err = enic_set_port_profile(enic, netdev->dev_addr);
+ if (err)
+ goto set_port_profile_cleanup;
+
+ if (!is_zero_ether_addr(enic->pp.mac_addr))
+ enic_dev_add_addr(enic, enic->pp.mac_addr);
+
+set_port_profile_cleanup:
+ memset(enic->pp.vf_mac, 0, ETH_ALEN);
+
+ if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
+ memset(netdev->dev_addr, 0, ETH_ALEN);
+ memset(enic->pp.mac_addr, 0, ETH_ALEN);
+ }
+
+ return err;
}
static int enic_get_vf_port(struct net_device *netdev, int vf,
@@ -1851,8 +1981,11 @@ static int enic_open(struct net_device *netdev)
for (i = 0; i < enic->rq_count; i++)
vnic_rq_enable(&enic->rq[i]);
- enic_dev_add_station_addr(enic);
- enic_set_multicast_list(netdev);
+ if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
+ enic_dev_add_addr(enic, enic->pp.mac_addr);
+ else
+ enic_dev_add_station_addr(enic);
+ enic_set_rx_mode(netdev);
netif_wake_queue(netdev);
@@ -1899,7 +2032,10 @@ static int enic_stop(struct net_device *netdev)
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- enic_dev_del_station_addr(enic);
+ if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
+ enic_dev_del_addr(enic, enic->pp.mac_addr);
+ else
+ enic_dev_del_station_addr(enic);
for (i = 0; i < enic->wq_count; i++) {
err = vnic_wq_disable(&enic->wq[i]);
@@ -1962,7 +2098,8 @@ static void enic_poll_controller(struct net_device *netdev)
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->rq_count; i++) {
intr = enic_msix_rq_intr(enic, i);
- enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+ enic_isr_msix_rq(enic->msix_entry[intr].vector,
+ &enic->napi[i]);
}
intr = enic_msix_wq_intr(enic, i);
enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
@@ -2042,7 +2179,7 @@ static int enic_dev_hang_reset(struct enic *enic)
static int enic_set_rsskey(struct enic *enic)
{
- u64 rss_key_buf_pa;
+ dma_addr_t rss_key_buf_pa;
union vnic_rss_key *rss_key_buf_va = NULL;
union vnic_rss_key rss_key = {
.key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101},
@@ -2073,7 +2210,7 @@ static int enic_set_rsskey(struct enic *enic)
static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits)
{
- u64 rss_cpu_buf_pa;
+ dma_addr_t rss_cpu_buf_pa;
union vnic_rss_cpu *rss_cpu_buf_va = NULL;
unsigned int i;
int err;
@@ -2328,7 +2465,8 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
.ndo_start_xmit = enic_hard_start_xmit,
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_set_rx_mode = enic_set_rx_mode,
+ .ndo_set_multicast_list = enic_set_rx_mode,
.ndo_set_mac_address = enic_set_mac_address_dynamic,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
@@ -2337,6 +2475,9 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
.ndo_tx_timeout = enic_tx_timeout,
.ndo_set_vf_port = enic_set_vf_port,
.ndo_get_vf_port = enic_get_vf_port,
+#ifdef IFLA_VF_MAX
+ .ndo_set_vf_mac = enic_set_vf_mac,
+#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = enic_poll_controller,
#endif
@@ -2349,7 +2490,8 @@ static const struct net_device_ops enic_netdev_ops = {
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = enic_set_mac_address,
- .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_set_rx_mode = enic_set_rx_mode,
+ .ndo_set_multicast_list = enic_set_rx_mode,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
.ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
@@ -2693,7 +2835,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
if (netdev) {
struct enic *enic = netdev_priv(netdev);
- flush_scheduled_work();
+ cancel_work_sync(&enic->reset);
unregister_netdev(netdev);
enic_dev_deinit(enic);
vnic_dev_close(enic->vdev);
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 9a103d9ef9e2..25be2734c3fe 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -34,6 +34,7 @@
#define ENIC_MAX_MTU 9000
#define ENIC_MULTICAST_PERFECT_FILTERS 32
+#define ENIC_UNICAST_PERFECT_FILTERS 32
#define ENIC_NON_TSO_MAX_DESC 16
diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h
index 7e46e5e8600f..f700f5d9e81d 100644
--- a/drivers/net/enic/vnic_vic.h
+++ b/drivers/net/enic/vnic_vic.h
@@ -24,14 +24,29 @@
/* Note: String field lengths include null char */
#define VIC_PROVINFO_CISCO_OUI { 0x00, 0x00, 0x0c }
-#define VIC_PROVINFO_LINUX_TYPE 0x2
-
-enum vic_linux_prov_tlv_type {
- VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR = 0,
- VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR = 1, /* u8[6] */
- VIC_LINUX_PROV_TLV_CLIENT_NAME_STR = 2,
- VIC_LINUX_PROV_TLV_HOST_UUID_STR = 8,
- VIC_LINUX_PROV_TLV_CLIENT_UUID_STR = 9,
+#define VIC_PROVINFO_GENERIC_TYPE 0x4
+
+enum vic_generic_prov_tlv_type {
+ VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR = 0,
+ VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR = 1,
+ VIC_GENERIC_PROV_TLV_CLIENT_NAME_STR = 2,
+ VIC_GENERIC_PROV_TLV_CLUSTER_PORT_NAME_STR = 3,
+ VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR = 4,
+ VIC_GENERIC_PROV_TLV_CLUSTER_UUID_STR = 5,
+ VIC_GENERIC_PROV_TLV_CLUSTER_NAME_STR = 7,
+ VIC_GENERIC_PROV_TLV_HOST_UUID_STR = 8,
+ VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR = 9,
+ VIC_GENERIC_PROV_TLV_INCARNATION_NUMBER = 10,
+ VIC_GENERIC_PROV_TLV_OS_TYPE = 11,
+ VIC_GENERIC_PROV_TLV_OS_VENDOR = 12,
+ VIC_GENERIC_PROV_TLV_CLIENT_TYPE = 15,
+};
+
+enum vic_generic_prov_os_type {
+ VIC_GENERIC_PROV_OS_TYPE_UNKNOWN = 0,
+ VIC_GENERIC_PROV_OS_TYPE_ESX = 1,
+ VIC_GENERIC_PROV_OS_TYPE_LINUX = 2,
+ VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3,
};
struct vic_provinfo {
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index aa56963ad558..c353bf3113cc 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -935,7 +935,7 @@ static void epic_init_ring(struct net_device *dev)
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2);
ep->rx_skbuff[i] = skb;
if (skb == NULL)
break;
@@ -1233,7 +1233,7 @@ static int epic_rx(struct net_device *dev, int budget)
entry = ep->dirty_rx % RX_RING_SIZE;
if (ep->rx_skbuff[entry] == NULL) {
struct sk_buff *skb;
- skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz);
+ skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2);
if (skb == NULL)
break;
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index c5a2fe099a8d..b79d7e1555d5 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <net/ethoc.h>
static int buffer_size = 0x8000; /* 32 KBytes */
@@ -184,7 +185,6 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
* @netdev: pointer to network device structure
* @napi: NAPI structure
* @msg_enable: device state flags
- * @rx_lock: receive lock
* @lock: device lock
* @phy: attached PHY
* @mdio: MDIO bus for PHY access
@@ -209,7 +209,6 @@ struct ethoc {
struct napi_struct napi;
u32 msg_enable;
- spinlock_t rx_lock;
spinlock_t lock;
struct phy_device *phy;
@@ -413,10 +412,21 @@ static int ethoc_rx(struct net_device *dev, int limit)
unsigned int entry;
struct ethoc_bd bd;
- entry = priv->num_tx + (priv->cur_rx % priv->num_rx);
+ entry = priv->num_tx + priv->cur_rx;
ethoc_read_bd(priv, entry, &bd);
- if (bd.stat & RX_BD_EMPTY)
- break;
+ if (bd.stat & RX_BD_EMPTY) {
+ ethoc_ack_irq(priv, INT_MASK_RX);
+ /* If packet (interrupt) came in between checking
+ * BD_EMTPY and clearing the interrupt source, then we
+ * risk missing the packet as the RX interrupt won't
+ * trigger right away when we reenable it; hence, check
+ * BD_EMTPY here again to make sure there isn't such a
+ * packet waiting for us...
+ */
+ ethoc_read_bd(priv, entry, &bd);
+ if (bd.stat & RX_BD_EMPTY)
+ break;
+ }
if (ethoc_update_rx_stats(priv, &bd) == 0) {
int size = bd.stat >> 16;
@@ -446,13 +456,14 @@ static int ethoc_rx(struct net_device *dev, int limit)
bd.stat &= ~RX_BD_STATS;
bd.stat |= RX_BD_EMPTY;
ethoc_write_bd(priv, entry, &bd);
- priv->cur_rx++;
+ if (++priv->cur_rx == priv->num_rx)
+ priv->cur_rx = 0;
}
return count;
}
-static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd)
+static void ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd)
{
struct net_device *netdev = dev->netdev;
@@ -482,32 +493,44 @@ static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd)
netdev->stats.collisions += (bd->stat >> 4) & 0xf;
netdev->stats.tx_bytes += bd->stat >> 16;
netdev->stats.tx_packets++;
- return 0;
}
-static void ethoc_tx(struct net_device *dev)
+static int ethoc_tx(struct net_device *dev, int limit)
{
struct ethoc *priv = netdev_priv(dev);
+ int count;
+ struct ethoc_bd bd;
- spin_lock(&priv->lock);
+ for (count = 0; count < limit; ++count) {
+ unsigned int entry;
- while (priv->dty_tx != priv->cur_tx) {
- unsigned int entry = priv->dty_tx % priv->num_tx;
- struct ethoc_bd bd;
+ entry = priv->dty_tx & (priv->num_tx-1);
ethoc_read_bd(priv, entry, &bd);
- if (bd.stat & TX_BD_READY)
- break;
- entry = (++priv->dty_tx) % priv->num_tx;
- (void)ethoc_update_tx_stats(priv, &bd);
+ if (bd.stat & TX_BD_READY || (priv->dty_tx == priv->cur_tx)) {
+ ethoc_ack_irq(priv, INT_MASK_TX);
+ /* If interrupt came in between reading in the BD
+ * and clearing the interrupt source, then we risk
+ * missing the event as the TX interrupt won't trigger
+ * right away when we reenable it; hence, check
+ * BD_EMPTY here again to make sure there isn't such an
+ * event pending...
+ */
+ ethoc_read_bd(priv, entry, &bd);
+ if (bd.stat & TX_BD_READY ||
+ (priv->dty_tx == priv->cur_tx))
+ break;
+ }
+
+ ethoc_update_tx_stats(priv, &bd);
+ priv->dty_tx++;
}
if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2))
netif_wake_queue(dev);
- ethoc_ack_irq(priv, INT_MASK_TX);
- spin_unlock(&priv->lock);
+ return count;
}
static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
@@ -515,32 +538,38 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct ethoc *priv = netdev_priv(dev);
u32 pending;
-
- ethoc_disable_irq(priv, INT_MASK_ALL);
+ u32 mask;
+
+ /* Figure out what triggered the interrupt...
+ * The tricky bit here is that the interrupt source bits get
+ * set in INT_SOURCE for an event irregardless of whether that
+ * event is masked or not. Thus, in order to figure out what
+ * triggered the interrupt, we need to remove the sources
+ * for all events that are currently masked. This behaviour
+ * is not particularly well documented but reasonable...
+ */
+ mask = ethoc_read(priv, INT_MASK);
pending = ethoc_read(priv, INT_SOURCE);
+ pending &= mask;
+
if (unlikely(pending == 0)) {
- ethoc_enable_irq(priv, INT_MASK_ALL);
return IRQ_NONE;
}
ethoc_ack_irq(priv, pending);
+ /* We always handle the dropped packet interrupt */
if (pending & INT_MASK_BUSY) {
dev_err(&dev->dev, "packet dropped\n");
dev->stats.rx_dropped++;
}
- if (pending & INT_MASK_RX) {
- if (napi_schedule_prep(&priv->napi))
- __napi_schedule(&priv->napi);
- } else {
- ethoc_enable_irq(priv, INT_MASK_RX);
+ /* Handle receive/transmit event by switching to polling */
+ if (pending & (INT_MASK_TX | INT_MASK_RX)) {
+ ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX);
+ napi_schedule(&priv->napi);
}
- if (pending & INT_MASK_TX)
- ethoc_tx(dev);
-
- ethoc_enable_irq(priv, INT_MASK_ALL & ~INT_MASK_RX);
return IRQ_HANDLED;
}
@@ -566,26 +595,29 @@ static int ethoc_get_mac_address(struct net_device *dev, void *addr)
static int ethoc_poll(struct napi_struct *napi, int budget)
{
struct ethoc *priv = container_of(napi, struct ethoc, napi);
- int work_done = 0;
+ int rx_work_done = 0;
+ int tx_work_done = 0;
+
+ rx_work_done = ethoc_rx(priv->netdev, budget);
+ tx_work_done = ethoc_tx(priv->netdev, budget);
- work_done = ethoc_rx(priv->netdev, budget);
- if (work_done < budget) {
- ethoc_enable_irq(priv, INT_MASK_RX);
+ if (rx_work_done < budget && tx_work_done < budget) {
napi_complete(napi);
+ ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX);
}
- return work_done;
+ return rx_work_done;
}
static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
{
- unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
struct ethoc *priv = bus->priv;
+ int i;
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
- while (time_before(jiffies, timeout)) {
+ for (i=0; i < 5; i++) {
u32 status = ethoc_read(priv, MIISTATUS);
if (!(status & MIISTATUS_BUSY)) {
u32 data = ethoc_read(priv, MIIRX_DATA);
@@ -593,8 +625,7 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
ethoc_write(priv, MIICOMMAND, 0);
return data;
}
-
- schedule();
+ usleep_range(100,200);
}
return -EBUSY;
@@ -602,22 +633,21 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
{
- unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
struct ethoc *priv = bus->priv;
+ int i;
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
ethoc_write(priv, MIITX_DATA, val);
ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
- while (time_before(jiffies, timeout)) {
+ for (i=0; i < 5; i++) {
u32 stat = ethoc_read(priv, MIISTATUS);
if (!(stat & MIISTATUS_BUSY)) {
/* reset MII command register */
ethoc_write(priv, MIICOMMAND, 0);
return 0;
}
-
- schedule();
+ usleep_range(100,200);
}
return -EBUSY;
@@ -971,9 +1001,17 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
/* calculate the number of TX/RX buffers, maximum 128 supported */
num_bd = min_t(unsigned int,
128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ);
- priv->num_tx = max(2, num_bd / 4);
+ if (num_bd < 4) {
+ ret = -ENODEV;
+ goto error;
+ }
+ /* num_tx must be a power of two */
+ priv->num_tx = rounddown_pow_of_two(num_bd >> 1);
priv->num_rx = num_bd - priv->num_tx;
+ dev_dbg(&pdev->dev, "ethoc: num_tx: %d num_rx: %d\n",
+ priv->num_tx, priv->num_rx);
+
priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL);
if (!priv->vma) {
ret = -ENOMEM;
@@ -982,10 +1020,23 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
/* Allow the platform setup code to pass in a MAC address. */
if (pdev->dev.platform_data) {
- struct ethoc_platform_data *pdata =
- (struct ethoc_platform_data *)pdev->dev.platform_data;
+ struct ethoc_platform_data *pdata = pdev->dev.platform_data;
memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN);
priv->phy_id = pdata->phy_id;
+ } else {
+ priv->phy_id = -1;
+
+#ifdef CONFIG_OF
+ {
+ const uint8_t* mac;
+
+ mac = of_get_property(pdev->dev.of_node,
+ "local-mac-address",
+ NULL);
+ if (mac)
+ memcpy(netdev->dev_addr, mac, IFHWADDRLEN);
+ }
+#endif
}
/* Check that the given MAC address is valid. If it isn't, read the
@@ -1046,7 +1097,6 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
/* setup NAPI */
netif_napi_add(netdev, &priv->napi, ethoc_poll, 64);
- spin_lock_init(&priv->rx_lock);
spin_lock_init(&priv->lock);
ret = register_netdev(netdev);
@@ -1113,6 +1163,16 @@ static int ethoc_resume(struct platform_device *pdev)
# define ethoc_resume NULL
#endif
+#ifdef CONFIG_OF
+static struct of_device_id ethoc_match[] = {
+ {
+ .compatible = "opencores,ethoc",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ethoc_match);
+#endif
+
static struct platform_driver ethoc_driver = {
.probe = ethoc_probe,
.remove = __devexit_p(ethoc_remove),
@@ -1120,6 +1180,10 @@ static struct platform_driver ethoc_driver = {
.resume = ethoc_resume,
.driver = {
.name = "ethoc",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = ethoc_match,
+#endif
},
};
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index e9f5d030bc26..50c1213f61fe 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -366,9 +366,8 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
while (bcom_buffer_done(priv->tx_dmatsk)) {
struct sk_buff *skb;
struct bcom_fec_bd *bd;
@@ -379,7 +378,7 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
dev_kfree_skb_irq(skb);
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
netif_wake_queue(dev);
@@ -395,9 +394,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
struct bcom_fec_bd *bd;
u32 status, physaddr;
int length;
- unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
while (bcom_buffer_done(priv->rx_dmatsk)) {
@@ -429,7 +427,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
/* Process the received skb - Drop the spin lock while
* calling into the network stack */
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
dma_unmap_single(dev->dev.parent, physaddr, rskb->len,
DMA_FROM_DEVICE);
@@ -438,10 +436,10 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
rskb->protocol = eth_type_trans(rskb, dev);
netif_rx(rskb);
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
return IRQ_HANDLED;
}
@@ -452,7 +450,6 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
struct mpc52xx_fec __iomem *fec = priv->fec;
u32 ievent;
- unsigned long flags;
ievent = in_be32(&fec->ievent);
@@ -470,9 +467,9 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
mpc52xx_fec_reset(dev);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
return IRQ_HANDLED;
}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 0fa1776563a3..cd2d72d825df 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -39,6 +39,9 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define FORCEDETH_VERSION "0.64"
#define DRV_NAME "forcedeth"
@@ -60,18 +63,12 @@
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/system.h>
-#if 0
-#define dprintk printk
-#else
-#define dprintk(x...) do { } while (0)
-#endif
-
#define TX_WORK_PER_LOOP 64
#define RX_WORK_PER_LOOP 64
@@ -186,9 +183,9 @@ enum {
NvRegSlotTime = 0x9c,
#define NVREG_SLOTTIME_LEGBF_ENABLED 0x80000000
#define NVREG_SLOTTIME_10_100_FULL 0x00007f00
-#define NVREG_SLOTTIME_1000_FULL 0x0003ff00
+#define NVREG_SLOTTIME_1000_FULL 0x0003ff00
#define NVREG_SLOTTIME_HALF 0x0000ff00
-#define NVREG_SLOTTIME_DEFAULT 0x00007f00
+#define NVREG_SLOTTIME_DEFAULT 0x00007f00
#define NVREG_SLOTTIME_MASK 0x000000ff
NvRegTxDeferral = 0xA0,
@@ -297,7 +294,7 @@ enum {
#define NVREG_WAKEUPFLAGS_ENABLE 0x1111
NvRegMgmtUnitGetVersion = 0x204,
-#define NVREG_MGMTUNITGETVERSION 0x01
+#define NVREG_MGMTUNITGETVERSION 0x01
NvRegMgmtUnitVersion = 0x208,
#define NVREG_MGMTUNITVERSION 0x08
NvRegPowerCap = 0x268,
@@ -368,8 +365,8 @@ struct ring_desc_ex {
};
union ring_type {
- struct ring_desc* orig;
- struct ring_desc_ex* ex;
+ struct ring_desc *orig;
+ struct ring_desc_ex *ex;
};
#define FLAG_MASK_V1 0xffff0000
@@ -444,10 +441,10 @@ union ring_type {
#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF)
/* Miscelaneous hardware related defines: */
-#define NV_PCI_REGSZ_VER1 0x270
-#define NV_PCI_REGSZ_VER2 0x2d4
-#define NV_PCI_REGSZ_VER3 0x604
-#define NV_PCI_REGSZ_MAX 0x604
+#define NV_PCI_REGSZ_VER1 0x270
+#define NV_PCI_REGSZ_VER2 0x2d4
+#define NV_PCI_REGSZ_VER3 0x604
+#define NV_PCI_REGSZ_MAX 0x604
/* various timeout delays: all in usec */
#define NV_TXRX_RESET_DELAY 4
@@ -717,7 +714,7 @@ static const struct register_test nv_registers_test[] = {
{ NvRegMulticastAddrA, 0xffffffff },
{ NvRegTxWatermark, 0x0ff },
{ NvRegWakeUpFlags, 0x07777 },
- { 0,0 }
+ { 0, 0 }
};
struct nv_skb_map {
@@ -911,7 +908,7 @@ static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED;
* Power down phy when interface is down (persists through reboot;
* older Linux and other OSes may not power it up again)
*/
-static int phy_power_down = 0;
+static int phy_power_down;
static inline struct fe_priv *get_nvpriv(struct net_device *dev)
{
@@ -948,7 +945,7 @@ static bool nv_optimized(struct fe_priv *np)
}
static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
- int delay, int delaymax, const char *msg)
+ int delay, int delaymax)
{
u8 __iomem *base = get_hwbase(dev);
@@ -956,11 +953,8 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
do {
udelay(delay);
delaymax -= delay;
- if (delaymax < 0) {
- if (msg)
- printk("%s", msg);
+ if (delaymax < 0)
return 1;
- }
} while ((readl(base + offset) & mask) != target);
return 0;
}
@@ -984,12 +978,10 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
u8 __iomem *base = get_hwbase(dev);
if (!nv_optimized(np)) {
- if (rxtx_flags & NV_SETUP_RX_RING) {
+ if (rxtx_flags & NV_SETUP_RX_RING)
writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
- }
- if (rxtx_flags & NV_SETUP_TX_RING) {
+ if (rxtx_flags & NV_SETUP_TX_RING)
writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
- }
} else {
if (rxtx_flags & NV_SETUP_RX_RING) {
writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
@@ -1015,10 +1007,8 @@ static void free_rings(struct net_device *dev)
pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size),
np->rx_ring.ex, np->ring_addr);
}
- if (np->rx_skb)
- kfree(np->rx_skb);
- if (np->tx_skb)
- kfree(np->tx_skb);
+ kfree(np->rx_skb);
+ kfree(np->tx_skb);
}
static int using_multi_irqs(struct net_device *dev)
@@ -1145,23 +1135,15 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
writel(reg, base + NvRegMIIControl);
if (reg_delay(dev, NvRegMIIControl, NVREG_MIICTL_INUSE, 0,
- NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) {
- dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d timed out.\n",
- dev->name, miireg, addr);
+ NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX)) {
retval = -1;
} else if (value != MII_READ) {
/* it was a write operation - fewer failures are detectable */
- dprintk(KERN_DEBUG "%s: mii_rw wrote 0x%x to reg %d at PHY %d\n",
- dev->name, value, miireg, addr);
retval = 0;
} else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) {
- dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d failed.\n",
- dev->name, miireg, addr);
retval = -1;
} else {
retval = readl(base + NvRegMIIData);
- dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n",
- dev->name, miireg, addr, retval);
}
return retval;
@@ -1174,16 +1156,15 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup)
unsigned int tries = 0;
miicontrol = BMCR_RESET | bmcr_setup;
- if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) {
+ if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol))
return -1;
- }
/* wait for 500ms */
msleep(500);
/* must wait till reset is deasserted */
while (miicontrol & BMCR_RESET) {
- msleep(10);
+ usleep_range(10000, 20000);
miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
/* FIXME: 100 tries seem excessive */
if (tries++ > 100)
@@ -1192,106 +1173,239 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup)
return 0;
}
+static int init_realtek_8211b(struct net_device *dev, struct fe_priv *np)
+{
+ static const struct {
+ int reg;
+ int init;
+ } ri[] = {
+ { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1 },
+ { PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2 },
+ { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3 },
+ { PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4 },
+ { PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5 },
+ { PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6 },
+ { PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1 },
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ri); i++) {
+ if (mii_rw(dev, np->phyaddr, ri[i].reg, ri[i].init))
+ return PHY_ERROR;
+ }
+
+ return 0;
+}
+
+static int init_realtek_8211c(struct net_device *dev, struct fe_priv *np)
+{
+ u32 reg;
+ u8 __iomem *base = get_hwbase(dev);
+ u32 powerstate = readl(base + NvRegPowerState2);
+
+ /* need to perform hw phy reset */
+ powerstate |= NVREG_POWERSTATE2_PHY_RESET;
+ writel(powerstate, base + NvRegPowerState2);
+ msleep(25);
+
+ powerstate &= ~NVREG_POWERSTATE2_PHY_RESET;
+ writel(powerstate, base + NvRegPowerState2);
+ msleep(25);
+
+ reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
+ reg |= PHY_REALTEK_INIT9;
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10))
+ return PHY_ERROR;
+ reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ);
+ if (!(reg & PHY_REALTEK_INIT11)) {
+ reg |= PHY_REALTEK_INIT11;
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg))
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1))
+ return PHY_ERROR;
+
+ return 0;
+}
+
+static int init_realtek_8201(struct net_device *dev, struct fe_priv *np)
+{
+ u32 phy_reserved;
+
+ if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG6, MII_READ);
+ phy_reserved |= PHY_REALTEK_INIT7;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG6, phy_reserved))
+ return PHY_ERROR;
+ }
+
+ return 0;
+}
+
+static int init_realtek_8201_cross(struct net_device *dev, struct fe_priv *np)
+{
+ u32 phy_reserved;
+
+ if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) {
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG2, MII_READ);
+ phy_reserved &= ~PHY_REALTEK_INIT_MSK1;
+ phy_reserved |= PHY_REALTEK_INIT3;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG2, phy_reserved))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1))
+ return PHY_ERROR;
+ }
+
+ return 0;
+}
+
+static int init_cicada(struct net_device *dev, struct fe_priv *np,
+ u32 phyinterface)
+{
+ u32 phy_reserved;
+
+ if (phyinterface & PHY_RGMII) {
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
+ phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
+ phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
+ if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
+ phy_reserved |= PHY_CICADA_INIT5;
+ if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved))
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
+ phy_reserved |= PHY_CICADA_INIT6;
+ if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved))
+ return PHY_ERROR;
+
+ return 0;
+}
+
+static int init_vitesse(struct net_device *dev, struct fe_priv *np)
+{
+ u32 phy_reserved;
+
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG4, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG3, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+ phy_reserved |= PHY_VITESSE_INIT3;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG4, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+ phy_reserved |= PHY_VITESSE_INIT3;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG3, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG4, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved))
+ return PHY_ERROR;
+ phy_reserved = mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG3, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK2;
+ phy_reserved |= PHY_VITESSE_INIT8;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9))
+ return PHY_ERROR;
+ if (mii_rw(dev, np->phyaddr,
+ PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10))
+ return PHY_ERROR;
+
+ return 0;
+}
+
static int phy_init(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
u8 __iomem *base = get_hwbase(dev);
- u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg;
+ u32 phyinterface;
+ u32 mii_status, mii_control, mii_control_1000, reg;
/* phy errata for E3016 phy */
if (np->phy_model == PHY_MODEL_MARVELL_E3016) {
reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
reg &= ~PHY_MARVELL_E3016_INITMASK;
if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) {
- printk(KERN_INFO "%s: phy write to errata reg failed.\n", pci_name(np->pci_dev));
+ netdev_info(dev, "%s: phy write to errata reg failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
}
if (np->phy_oui == PHY_OUI_REALTEK) {
if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
np->phy_rev == PHY_REV_REALTEK_8211B) {
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ if (init_realtek_8211b(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ } else if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
+ np->phy_rev == PHY_REV_REALTEK_8211C) {
+ if (init_realtek_8211c(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ } else if (np->phy_model == PHY_MODEL_REALTEK_8201) {
+ if (init_realtek_8201(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
- np->phy_rev == PHY_REV_REALTEK_8211C) {
- u32 powerstate = readl(base + NvRegPowerState2);
-
- /* need to perform hw phy reset */
- powerstate |= NVREG_POWERSTATE2_PHY_RESET;
- writel(powerstate, base + NvRegPowerState2);
- msleep(25);
-
- powerstate &= ~NVREG_POWERSTATE2_PHY_RESET;
- writel(powerstate, base + NvRegPowerState2);
- msleep(25);
-
- reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
- reg |= PHY_REALTEK_INIT9;
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ);
- if (!(reg & PHY_REALTEK_INIT11)) {
- reg |= PHY_REALTEK_INIT11;
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (np->phy_model == PHY_MODEL_REALTEK_8201) {
- if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
- phy_reserved |= PHY_REALTEK_INIT7;
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
}
}
/* set advertise register */
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
- reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP);
+ reg |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL |
+ ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) {
- printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev));
+ netdev_info(dev, "%s: phy write to advertise failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
@@ -1302,7 +1416,8 @@ static int phy_init(struct net_device *dev)
mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
if (mii_status & PHY_GIGABIT) {
np->gigabit = PHY_GIGABIT;
- mii_control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ);
+ mii_control_1000 = mii_rw(dev, np->phyaddr,
+ MII_CTRL1000, MII_READ);
mii_control_1000 &= ~ADVERTISE_1000HALF;
if (phyinterface & PHY_RGMII)
mii_control_1000 |= ADVERTISE_1000FULL;
@@ -1310,11 +1425,11 @@ static int phy_init(struct net_device *dev)
mii_control_1000 &= ~ADVERTISE_1000FULL;
if (mii_rw(dev, np->phyaddr, MII_CTRL1000, mii_control_1000)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- }
- else
+ } else
np->gigabit = 0;
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
@@ -1326,7 +1441,8 @@ static int phy_init(struct net_device *dev)
/* start autoneg since we already performed hw reset above */
mii_control |= BMCR_ANRESTART;
if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
- printk(KERN_INFO "%s: phy init failed\n", pci_name(np->pci_dev));
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
} else {
@@ -1334,165 +1450,42 @@ static int phy_init(struct net_device *dev)
* (certain phys need bmcr to be setup with reset)
*/
if (phy_reset(dev, mii_control)) {
- printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
+ netdev_info(dev, "%s: phy reset failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
}
/* phy vendor specific configuration */
- if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
- phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
- phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
- phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
- if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
- phy_reserved |= PHY_CICADA_INIT5;
- if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (np->phy_oui == PHY_OUI_CICADA) {
- phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
- phy_reserved |= PHY_CICADA_INIT6;
- if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (np->phy_oui == PHY_OUI_VITESSE) {
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
- phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
- phy_reserved |= PHY_VITESSE_INIT3;
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
- phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
- phy_reserved |= PHY_VITESSE_INIT3;
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ if ((np->phy_oui == PHY_OUI_CICADA)) {
+ if (init_cicada(dev, np, phyinterface)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ } else if (np->phy_oui == PHY_OUI_VITESSE) {
+ if (init_vitesse(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
- phy_reserved &= ~PHY_VITESSE_INIT_MSK2;
- phy_reserved |= PHY_VITESSE_INIT8;
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (np->phy_oui == PHY_OUI_REALTEK) {
+ } else if (np->phy_oui == PHY_OUI_REALTEK) {
if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
np->phy_rev == PHY_REV_REALTEK_8211B) {
/* reset could have cleared these out, set them back */
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ if (init_realtek_8211b(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ } else if (np->phy_model == PHY_MODEL_REALTEK_8201) {
+ if (init_realtek_8201(dev, np) ||
+ init_realtek_8201_cross(dev, np)) {
+ netdev_info(dev, "%s: phy init failed\n",
+ pci_name(np->pci_dev));
return PHY_ERROR;
}
}
- if (np->phy_model == PHY_MODEL_REALTEK_8201) {
- if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
- phy_reserved |= PHY_REALTEK_INIT7;
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) {
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ);
- phy_reserved &= ~PHY_REALTEK_INIT_MSK1;
- phy_reserved |= PHY_REALTEK_INIT3;
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
- printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
- return PHY_ERROR;
- }
- }
- }
}
/* some phys clear out pause advertisment on reset, set it back */
@@ -1501,12 +1494,10 @@ static int phy_init(struct net_device *dev)
/* restart auto negotiation, power down phy */
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
- if (phy_power_down) {
+ if (phy_power_down)
mii_control |= BMCR_PDOWN;
- }
- if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
+ if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control))
return PHY_ERROR;
- }
return 0;
}
@@ -1517,7 +1508,6 @@ static void nv_start_rx(struct net_device *dev)
u8 __iomem *base = get_hwbase(dev);
u32 rx_ctrl = readl(base + NvRegReceiverControl);
- dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
/* Already running? Stop it. */
if ((readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) && !np->mac_in_use) {
rx_ctrl &= ~NVREG_RCVCTL_START;
@@ -1526,12 +1516,10 @@ static void nv_start_rx(struct net_device *dev)
}
writel(np->linkspeed, base + NvRegLinkSpeed);
pci_push(base);
- rx_ctrl |= NVREG_RCVCTL_START;
- if (np->mac_in_use)
+ rx_ctrl |= NVREG_RCVCTL_START;
+ if (np->mac_in_use)
rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN;
writel(rx_ctrl, base + NvRegReceiverControl);
- dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n",
- dev->name, np->duplex, np->linkspeed);
pci_push(base);
}
@@ -1541,15 +1529,15 @@ static void nv_stop_rx(struct net_device *dev)
u8 __iomem *base = get_hwbase(dev);
u32 rx_ctrl = readl(base + NvRegReceiverControl);
- dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name);
if (!np->mac_in_use)
rx_ctrl &= ~NVREG_RCVCTL_START;
else
rx_ctrl |= NVREG_RCVCTL_RX_PATH_EN;
writel(rx_ctrl, base + NvRegReceiverControl);
- reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
- NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
- KERN_INFO "nv_stop_rx: ReceiverStatus remained busy");
+ if (reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
+ NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX))
+ netdev_info(dev, "%s: ReceiverStatus remained busy\n",
+ __func__);
udelay(NV_RXSTOP_DELAY2);
if (!np->mac_in_use)
@@ -1562,7 +1550,6 @@ static void nv_start_tx(struct net_device *dev)
u8 __iomem *base = get_hwbase(dev);
u32 tx_ctrl = readl(base + NvRegTransmitterControl);
- dprintk(KERN_DEBUG "%s: nv_start_tx\n", dev->name);
tx_ctrl |= NVREG_XMITCTL_START;
if (np->mac_in_use)
tx_ctrl &= ~NVREG_XMITCTL_TX_PATH_EN;
@@ -1576,15 +1563,15 @@ static void nv_stop_tx(struct net_device *dev)
u8 __iomem *base = get_hwbase(dev);
u32 tx_ctrl = readl(base + NvRegTransmitterControl);
- dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name);
if (!np->mac_in_use)
tx_ctrl &= ~NVREG_XMITCTL_START;
else
tx_ctrl |= NVREG_XMITCTL_TX_PATH_EN;
writel(tx_ctrl, base + NvRegTransmitterControl);
- reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
- NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
- KERN_INFO "nv_stop_tx: TransmitterStatus remained busy");
+ if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
+ NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX))
+ netdev_info(dev, "%s: TransmitterStatus remained busy\n",
+ __func__);
udelay(NV_TXSTOP_DELAY2);
if (!np->mac_in_use)
@@ -1609,7 +1596,6 @@ static void nv_txrx_reset(struct net_device *dev)
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
udelay(NV_TXRX_RESET_DELAY);
@@ -1623,8 +1609,6 @@ static void nv_mac_reset(struct net_device *dev)
u8 __iomem *base = get_hwbase(dev);
u32 temp1, temp2, temp3;
- dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
-
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
@@ -1745,7 +1729,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
static int nv_alloc_rx(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
- struct ring_desc* less_rx;
+ struct ring_desc *less_rx;
less_rx = np->get_rx.orig;
if (less_rx-- == np->first_rx.orig)
@@ -1767,9 +1751,8 @@ static int nv_alloc_rx(struct net_device *dev)
np->put_rx.orig = np->first_rx.orig;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else {
+ } else
return 1;
- }
}
return 0;
}
@@ -1777,7 +1760,7 @@ static int nv_alloc_rx(struct net_device *dev)
static int nv_alloc_rx_optimized(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
- struct ring_desc_ex* less_rx;
+ struct ring_desc_ex *less_rx;
less_rx = np->get_rx.ex;
if (less_rx-- == np->first_rx.ex)
@@ -1800,9 +1783,8 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
np->put_rx.ex = np->first_rx.ex;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else {
+ } else
return 1;
- }
}
return 0;
}
@@ -2018,24 +2000,24 @@ static void nv_legacybackoff_reseed(struct net_device *dev)
/* Known Good seed sets */
static const u32 main_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = {
- {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
- {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974},
- {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
- {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974},
- {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984},
- {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984},
- {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84},
- {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}};
+ {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
+ {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974},
+ {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
+ {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974},
+ {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984},
+ {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984},
+ {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84},
+ {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184} };
static const u32 gear_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = {
- {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
- {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
- {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397},
- {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
- {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
- {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
- {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
- {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}};
+ {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
+ {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+ {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397},
+ {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
+ {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
+ {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+ {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+ {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395} };
static void nv_gear_backoff_reseed(struct net_device *dev)
{
@@ -2083,13 +2065,12 @@ static void nv_gear_backoff_reseed(struct net_device *dev)
temp = NVREG_BKOFFCTRL_DEFAULT | (0 << NVREG_BKOFFCTRL_SELECT);
temp |= combinedSeed & NVREG_BKOFFCTRL_SEED_MASK;
temp |= combinedSeed >> NVREG_BKOFFCTRL_GEAR;
- writel(temp,base + NvRegBackOffControl);
+ writel(temp, base + NvRegBackOffControl);
- /* Setup seeds for all gear LFSRs. */
+ /* Setup seeds for all gear LFSRs. */
get_random_bytes(&seedset, sizeof(seedset));
seedset = seedset % BACKOFF_SEEDSET_ROWS;
- for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++)
- {
+ for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) {
temp = NVREG_BKOFFCTRL_DEFAULT | (i << NVREG_BKOFFCTRL_SELECT);
temp |= main_seedset[seedset][i-1] & 0x3ff;
temp |= ((gear_seedset[seedset][i-1] & 0x3ff) << NVREG_BKOFFCTRL_GEAR);
@@ -2113,10 +2094,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 size = skb_headlen(skb);
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
- struct ring_desc* put_tx;
- struct ring_desc* start_tx;
- struct ring_desc* prev_tx;
- struct nv_skb_map* prev_tx_ctx;
+ struct ring_desc *put_tx;
+ struct ring_desc *start_tx;
+ struct ring_desc *prev_tx;
+ struct nv_skb_map *prev_tx_ctx;
unsigned long flags;
/* add fragments to entries count */
@@ -2204,18 +2185,6 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&np->lock, flags);
- dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n",
- dev->name, entries, tx_flags_extra);
- {
- int j;
- for (j=0; j<64; j++) {
- if ((j%16) == 0)
- dprintk("\n%03x:", j);
- dprintk(" %02x", ((unsigned char*)skb->data)[j]);
- }
- dprintk("\n");
- }
-
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
return NETDEV_TX_OK;
}
@@ -2233,11 +2202,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
u32 size = skb_headlen(skb);
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
- struct ring_desc_ex* put_tx;
- struct ring_desc_ex* start_tx;
- struct ring_desc_ex* prev_tx;
- struct nv_skb_map* prev_tx_ctx;
- struct nv_skb_map* start_tx_ctx;
+ struct ring_desc_ex *put_tx;
+ struct ring_desc_ex *start_tx;
+ struct ring_desc_ex *prev_tx;
+ struct nv_skb_map *prev_tx_ctx;
+ struct nv_skb_map *start_tx_ctx;
unsigned long flags;
/* add fragments to entries count */
@@ -2355,18 +2324,6 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
spin_unlock_irqrestore(&np->lock, flags);
- dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n",
- dev->name, entries, tx_flags_extra);
- {
- int j;
- for (j=0; j<64; j++) {
- if ((j%16) == 0)
- dprintk("\n%03x:", j);
- dprintk(" %02x", ((unsigned char*)skb->data)[j]);
- }
- dprintk("\n");
- }
-
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
return NETDEV_TX_OK;
}
@@ -2399,15 +2356,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
struct fe_priv *np = netdev_priv(dev);
u32 flags;
int tx_work = 0;
- struct ring_desc* orig_get_tx = np->get_tx.orig;
+ struct ring_desc *orig_get_tx = np->get_tx.orig;
while ((np->get_tx.orig != np->put_tx.orig) &&
!((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) &&
(tx_work < limit)) {
- dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n",
- dev->name, flags);
-
nv_unmap_txskb(np, np->get_tx_ctx);
if (np->desc_ver == DESC_VER_1) {
@@ -2464,15 +2418,12 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
struct fe_priv *np = netdev_priv(dev);
u32 flags;
int tx_work = 0;
- struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
+ struct ring_desc_ex *orig_get_tx = np->get_tx.ex;
while ((np->get_tx.ex != np->put_tx.ex) &&
!((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) &&
(tx_work < limit)) {
- dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
- dev->name, flags);
-
nv_unmap_txskb(np, np->get_tx_ctx);
if (flags & NV_TX2_LASTPACKET) {
@@ -2491,9 +2442,8 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
np->get_tx_ctx->skb = NULL;
tx_work++;
- if (np->tx_limit) {
+ if (np->tx_limit)
nv_tx_flip_ownership(dev);
- }
}
if (unlikely(np->get_tx.ex++ == np->last_tx.ex))
np->get_tx.ex = np->first_tx.ex;
@@ -2518,57 +2468,56 @@ static void nv_tx_timeout(struct net_device *dev)
u32 status;
union ring_type put_tx;
int saved_tx_limit;
+ int i;
if (np->msi_flags & NV_MSI_X_ENABLED)
status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
else
status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, status);
-
- {
- int i;
-
- printk(KERN_INFO "%s: Ring at %lx\n",
- dev->name, (unsigned long)np->ring_addr);
- printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
- for (i=0;i<=np->register_size;i+= 32) {
- printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- i,
- readl(base + i + 0), readl(base + i + 4),
- readl(base + i + 8), readl(base + i + 12),
- readl(base + i + 16), readl(base + i + 20),
- readl(base + i + 24), readl(base + i + 28));
- }
- printk(KERN_INFO "%s: Dumping tx ring\n", dev->name);
- for (i=0;i<np->tx_ring_size;i+= 4) {
- if (!nv_optimized(np)) {
- printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n",
- i,
- le32_to_cpu(np->tx_ring.orig[i].buf),
- le32_to_cpu(np->tx_ring.orig[i].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+1].buf),
- le32_to_cpu(np->tx_ring.orig[i+1].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+2].buf),
- le32_to_cpu(np->tx_ring.orig[i+2].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+3].buf),
- le32_to_cpu(np->tx_ring.orig[i+3].flaglen));
- } else {
- printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n",
- i,
- le32_to_cpu(np->tx_ring.ex[i].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i].buflow),
- le32_to_cpu(np->tx_ring.ex[i].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+1].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+1].buflow),
- le32_to_cpu(np->tx_ring.ex[i+1].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+2].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+2].buflow),
- le32_to_cpu(np->tx_ring.ex[i+2].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+3].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+3].buflow),
- le32_to_cpu(np->tx_ring.ex[i+3].flaglen));
- }
+ netdev_info(dev, "Got tx_timeout. irq: %08x\n", status);
+
+ netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr);
+ netdev_info(dev, "Dumping tx registers\n");
+ for (i = 0; i <= np->register_size; i += 32) {
+ netdev_info(dev,
+ "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ i,
+ readl(base + i + 0), readl(base + i + 4),
+ readl(base + i + 8), readl(base + i + 12),
+ readl(base + i + 16), readl(base + i + 20),
+ readl(base + i + 24), readl(base + i + 28));
+ }
+ netdev_info(dev, "Dumping tx ring\n");
+ for (i = 0; i < np->tx_ring_size; i += 4) {
+ if (!nv_optimized(np)) {
+ netdev_info(dev,
+ "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n",
+ i,
+ le32_to_cpu(np->tx_ring.orig[i].buf),
+ le32_to_cpu(np->tx_ring.orig[i].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+1].buf),
+ le32_to_cpu(np->tx_ring.orig[i+1].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+2].buf),
+ le32_to_cpu(np->tx_ring.orig[i+2].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+3].buf),
+ le32_to_cpu(np->tx_ring.orig[i+3].flaglen));
+ } else {
+ netdev_info(dev,
+ "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n",
+ i,
+ le32_to_cpu(np->tx_ring.ex[i].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i].buflow),
+ le32_to_cpu(np->tx_ring.ex[i].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+1].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+1].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+1].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+2].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+2].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+2].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+3].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+3].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+3].flaglen));
}
}
@@ -2616,15 +2565,13 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
int protolen; /* length as stored in the proto field */
/* 1) calculate len according to header */
- if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) {
- protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto );
+ if (((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) {
+ protolen = ntohs(((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto);
hdrlen = VLAN_HLEN;
} else {
- protolen = ntohs( ((struct ethhdr *)packet)->h_proto);
+ protolen = ntohs(((struct ethhdr *)packet)->h_proto);
hdrlen = ETH_HLEN;
}
- dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n",
- dev->name, datalen, protolen, hdrlen);
if (protolen > ETH_DATA_LEN)
return datalen; /* Value in proto field not a len, no checks possible */
@@ -2635,26 +2582,18 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
/* more data on wire than in 802 header, trim of
* additional data.
*/
- dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
- dev->name, protolen);
return protolen;
} else {
/* less data on wire than mentioned in header.
* Discard the packet.
*/
- dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n",
- dev->name);
return -1;
}
} else {
/* short packet. Accept only if 802 values are also short */
if (protolen > ETH_ZLEN) {
- dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n",
- dev->name);
return -1;
}
- dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
- dev->name, datalen);
return datalen;
}
}
@@ -2667,13 +2606,10 @@ static int nv_rx_process(struct net_device *dev, int limit)
struct sk_buff *skb;
int len;
- while((np->get_rx.orig != np->put_rx.orig) &&
+ while ((np->get_rx.orig != np->put_rx.orig) &&
!((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) &&
(rx_work < limit)) {
- dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
- dev->name, flags);
-
/*
* the packet is for us - immediately tear down the pci mapping.
* TODO: check if a prefetch of the first cacheline improves
@@ -2685,16 +2621,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
skb = np->get_rx_ctx->skb;
np->get_rx_ctx->skb = NULL;
- {
- int j;
- dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags);
- for (j=0; j<64; j++) {
- if ((j%16) == 0)
- dprintk("\n%03x:", j);
- dprintk(" %02x", ((unsigned char*)skb->data)[j]);
- }
- dprintk("\n");
- }
/* look at what we actually got: */
if (np->desc_ver == DESC_VER_1) {
if (likely(flags & NV_RX_DESCRIPTORVALID)) {
@@ -2710,9 +2636,8 @@ static int nv_rx_process(struct net_device *dev, int limit)
}
/* framing errors are soft errors */
else if ((flags & NV_RX_ERROR_MASK) == NV_RX_FRAMINGERR) {
- if (flags & NV_RX_SUBSTRACT1) {
+ if (flags & NV_RX_SUBSTRACT1)
len--;
- }
}
/* the rest are hard errors */
else {
@@ -2745,9 +2670,8 @@ static int nv_rx_process(struct net_device *dev, int limit)
}
/* framing errors are soft errors */
else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
- if (flags & NV_RX2_SUBSTRACT1) {
+ if (flags & NV_RX2_SUBSTRACT1)
len--;
- }
}
/* the rest are hard errors */
else {
@@ -2771,8 +2695,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
/* got a valid packet - forward it to the network core */
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
- dprintk(KERN_DEBUG "%s: nv_rx_process: %d bytes, proto %d accepted.\n",
- dev->name, len, skb->protocol);
napi_gro_receive(&np->napi, skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
@@ -2797,13 +2719,10 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
struct sk_buff *skb;
int len;
- while((np->get_rx.ex != np->put_rx.ex) &&
+ while ((np->get_rx.ex != np->put_rx.ex) &&
!((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
(rx_work < limit)) {
- dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
- dev->name, flags);
-
/*
* the packet is for us - immediately tear down the pci mapping.
* TODO: check if a prefetch of the first cacheline improves
@@ -2815,16 +2734,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
skb = np->get_rx_ctx->skb;
np->get_rx_ctx->skb = NULL;
- {
- int j;
- dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags);
- for (j=0; j<64; j++) {
- if ((j%16) == 0)
- dprintk("\n%03x:", j);
- dprintk(" %02x", ((unsigned char*)skb->data)[j]);
- }
- dprintk("\n");
- }
/* look at what we actually got: */
if (likely(flags & NV_RX2_DESCRIPTORVALID)) {
len = flags & LEN_MASK_V2;
@@ -2838,9 +2747,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
}
/* framing errors are soft errors */
else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
- if (flags & NV_RX2_SUBSTRACT1) {
+ if (flags & NV_RX2_SUBSTRACT1)
len--;
- }
}
/* the rest are hard errors */
else {
@@ -2858,9 +2766,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
skb->protocol = eth_type_trans(skb, dev);
prefetch(skb->data);
- dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: %d bytes, proto %d accepted.\n",
- dev->name, len, skb->protocol);
-
if (likely(!np->vlangrp)) {
napi_gro_receive(&np->napi, skb);
} else {
@@ -2949,7 +2854,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
/* reinit nic view of the rx queue */
writel(np->rx_buf_sz, base + NvRegOffloadConfig);
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
@@ -2986,7 +2891,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev)
static int nv_set_mac_address(struct net_device *dev, void *addr)
{
struct fe_priv *np = netdev_priv(dev);
- struct sockaddr *macaddr = (struct sockaddr*)addr;
+ struct sockaddr *macaddr = (struct sockaddr *)addr;
if (!is_valid_ether_addr(macaddr->sa_data))
return -EADDRNOTAVAIL;
@@ -3076,8 +2981,6 @@ static void nv_set_multicast(struct net_device *dev)
writel(mask[0], base + NvRegMulticastMaskA);
writel(mask[1], base + NvRegMulticastMaskB);
writel(pff, base + NvRegPacketFilterFlags);
- dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n",
- dev->name);
nv_start_rx(dev);
spin_unlock_irq(&np->lock);
}
@@ -3152,8 +3055,6 @@ static int nv_update_linkspeed(struct net_device *dev)
mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
if (!(mii_status & BMSR_LSTATUS)) {
- dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n",
- dev->name);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
retval = 0;
@@ -3161,8 +3062,6 @@ static int nv_update_linkspeed(struct net_device *dev)
}
if (np->autoneg == 0) {
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: autoneg off, PHY set to 0x%04x.\n",
- dev->name, np->fixed_mode);
if (np->fixed_mode & LPA_100FULL) {
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
newdup = 1;
@@ -3185,14 +3084,11 @@ static int nv_update_linkspeed(struct net_device *dev)
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
retval = 0;
- dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name);
goto set_speed;
}
adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ);
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n",
- dev->name, adv, lpa);
retval = 1;
if (np->gigabit == PHY_GIGABIT) {
@@ -3201,8 +3097,6 @@ static int nv_update_linkspeed(struct net_device *dev)
if ((control_1000 & ADVERTISE_1000FULL) &&
(status_1000 & LPA_1000FULL)) {
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
- dev->name);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000;
newdup = 1;
goto set_speed;
@@ -3224,7 +3118,6 @@ static int nv_update_linkspeed(struct net_device *dev)
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
} else {
- dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, adv_lpa);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
}
@@ -3233,9 +3126,6 @@ set_speed:
if (np->duplex == newdup && np->linkspeed == newls)
return retval;
- dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n",
- dev->name, np->linkspeed, np->duplex, newls, newdup);
-
np->duplex = newdup;
np->linkspeed = newls;
@@ -3302,7 +3192,7 @@ set_speed:
}
writel(txreg, base + NvRegTxWatermark);
- writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
+ writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD),
base + NvRegMisc1);
pci_push(base);
writel(np->linkspeed, base + NvRegLinkSpeed);
@@ -3312,8 +3202,8 @@ set_speed:
/* setup pause frame */
if (np->duplex != 0) {
if (np->autoneg && np->pause_flags & NV_PAUSEFRAME_AUTONEG) {
- adv_pause = adv & (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM);
- lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM);
+ adv_pause = adv & (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+ lpa_pause = lpa & (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
switch (adv_pause) {
case ADVERTISE_PAUSE_CAP:
@@ -3324,22 +3214,17 @@ set_speed:
}
break;
case ADVERTISE_PAUSE_ASYM:
- if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM))
- {
+ if (lpa_pause == (LPA_PAUSE_CAP | LPA_PAUSE_ASYM))
pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
- }
break;
- case ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM:
- if (lpa_pause & LPA_PAUSE_CAP)
- {
+ case ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM:
+ if (lpa_pause & LPA_PAUSE_CAP) {
pause_flags |= NV_PAUSEFRAME_RX_ENABLE;
if (np->pause_flags & NV_PAUSEFRAME_TX_REQ)
pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
}
if (lpa_pause == LPA_PAUSE_ASYM)
- {
pause_flags |= NV_PAUSEFRAME_RX_ENABLE;
- }
break;
}
} else {
@@ -3361,14 +3246,14 @@ static void nv_linkchange(struct net_device *dev)
if (nv_update_linkspeed(dev)) {
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
- printk(KERN_INFO "%s: link up.\n", dev->name);
+ netdev_info(dev, "link up\n");
nv_txrx_gate(dev, false);
nv_start_rx(dev);
}
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
- printk(KERN_INFO "%s: link down.\n", dev->name);
+ netdev_info(dev, "link down\n");
nv_txrx_gate(dev, true);
nv_stop_rx(dev);
}
@@ -3382,11 +3267,9 @@ static void nv_link_irq(struct net_device *dev)
miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus);
- dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);
if (miistat & (NVREG_MIISTAT_LINKCHANGE))
nv_linkchange(dev);
- dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
}
static void nv_msi_workaround(struct fe_priv *np)
@@ -3437,8 +3320,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name);
-
if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
np->events = readl(base + NvRegIrqStatus);
writel(np->events, base + NvRegIrqStatus);
@@ -3446,7 +3327,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
np->events = readl(base + NvRegMSIXIrqStatus);
writel(np->events, base + NvRegMSIXIrqStatus);
}
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
if (!(np->events & np->irqmask))
return IRQ_NONE;
@@ -3460,8 +3340,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
__napi_schedule(&np->napi);
}
- dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name);
-
return IRQ_HANDLED;
}
@@ -3476,8 +3354,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name);
-
if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
np->events = readl(base + NvRegIrqStatus);
writel(np->events, base + NvRegIrqStatus);
@@ -3485,7 +3361,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
np->events = readl(base + NvRegMSIXIrqStatus);
writel(np->events, base + NvRegMSIXIrqStatus);
}
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
if (!(np->events & np->irqmask))
return IRQ_NONE;
@@ -3498,7 +3373,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
writel(0, base + NvRegIrqMask);
__napi_schedule(&np->napi);
}
- dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name);
return IRQ_HANDLED;
}
@@ -3512,12 +3386,9 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
int i;
unsigned long flags;
- dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name);
-
- for (i=0; ; i++) {
+ for (i = 0;; i++) {
events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL;
writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus);
- dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events);
if (!(events & np->irqmask))
break;
@@ -3536,12 +3407,12 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
spin_unlock_irqrestore(&np->lock, flags);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
+ netdev_dbg(dev, "%s: too many iterations (%d)\n",
+ __func__, i);
break;
}
}
- dprintk(KERN_DEBUG "%s: nv_nic_irq_tx completed\n", dev->name);
return IRQ_RETVAL(i);
}
@@ -3553,7 +3424,7 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
int retcode;
- int rx_count, tx_work=0, rx_work=0;
+ int rx_count, tx_work = 0, rx_work = 0;
do {
if (!nv_optimized(np)) {
@@ -3626,12 +3497,9 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
int i;
unsigned long flags;
- dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name);
-
- for (i=0; ; i++) {
+ for (i = 0;; i++) {
events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
- dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events);
if (!(events & np->irqmask))
break;
@@ -3655,11 +3523,11 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
spin_unlock_irqrestore(&np->lock, flags);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
+ netdev_dbg(dev, "%s: too many iterations (%d)\n",
+ __func__, i);
break;
}
}
- dprintk(KERN_DEBUG "%s: nv_nic_irq_rx completed\n", dev->name);
return IRQ_RETVAL(i);
}
@@ -3673,12 +3541,9 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
int i;
unsigned long flags;
- dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name);
-
- for (i=0; ; i++) {
+ for (i = 0;; i++) {
events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER;
writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus);
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
if (!(events & np->irqmask))
break;
@@ -3723,12 +3588,12 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
spin_unlock_irqrestore(&np->lock, flags);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
+ netdev_dbg(dev, "%s: too many iterations (%d)\n",
+ __func__, i);
break;
}
}
- dprintk(KERN_DEBUG "%s: nv_nic_irq_other completed\n", dev->name);
return IRQ_RETVAL(i);
}
@@ -3740,8 +3605,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
u8 __iomem *base = get_hwbase(dev);
u32 events;
- dprintk(KERN_DEBUG "%s: nv_nic_irq_test\n", dev->name);
-
if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus);
@@ -3750,7 +3613,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
}
pci_push(base);
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
if (!(events & NVREG_IRQ_TIMER))
return IRQ_RETVAL(0);
@@ -3760,8 +3622,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
np->intr_test = 1;
spin_unlock(&np->lock);
- dprintk(KERN_DEBUG "%s: nv_nic_irq_test completed\n", dev->name);
-
return IRQ_RETVAL(1);
}
@@ -3776,17 +3636,15 @@ static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask)
* the remaining 8 interrupts.
*/
for (i = 0; i < 8; i++) {
- if ((irqmask >> i) & 0x1) {
+ if ((irqmask >> i) & 0x1)
msixmap |= vector << (i << 2);
- }
}
writel(readl(base + NvRegMSIXMap0) | msixmap, base + NvRegMSIXMap0);
msixmap = 0;
for (i = 0; i < 8; i++) {
- if ((irqmask >> (i + 8)) & 0x1) {
+ if ((irqmask >> (i + 8)) & 0x1)
msixmap |= vector << (i << 2);
- }
}
writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1);
}
@@ -3809,17 +3667,19 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
}
if (np->msi_flags & NV_MSI_X_CAPABLE) {
- for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
+ for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++)
np->msi_x_entry[i].entry = i;
- }
- if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) {
+ ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK));
+ if (ret == 0) {
np->msi_flags |= NV_MSI_X_ENABLED;
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) {
/* Request irq for rx handling */
sprintf(np->name_rx, "%s-rx", dev->name);
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector,
nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
- printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
+ netdev_info(dev,
+ "request_irq failed for rx %d\n",
+ ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_err;
@@ -3828,7 +3688,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
sprintf(np->name_tx, "%s-tx", dev->name);
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector,
nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
- printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
+ netdev_info(dev,
+ "request_irq failed for tx %d\n",
+ ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_free_rx;
@@ -3837,7 +3699,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
sprintf(np->name_other, "%s-other", dev->name);
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector,
nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
- printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
+ netdev_info(dev,
+ "request_irq failed for link %d\n",
+ ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_free_tx;
@@ -3851,7 +3715,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
} else {
/* Request irq for all interrupts */
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, handler, IRQF_SHARED, dev->name, dev) != 0) {
- printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
+ netdev_info(dev,
+ "request_irq failed %d\n",
+ ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_err;
@@ -3864,11 +3730,13 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
}
}
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
- if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
+ ret = pci_enable_msi(np->pci_dev);
+ if (ret == 0) {
np->msi_flags |= NV_MSI_ENABLED;
dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
- printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
+ netdev_info(dev, "request_irq failed %d\n",
+ ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
dev->irq = np->pci_dev->irq;
@@ -3903,9 +3771,8 @@ static void nv_free_irq(struct net_device *dev)
int i;
if (np->msi_flags & NV_MSI_X_ENABLED) {
- for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
+ for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++)
free_irq(np->msi_x_entry[i].vector, dev);
- }
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
} else {
@@ -3954,7 +3821,7 @@ static void nv_do_nic_poll(unsigned long data)
if (np->recover_error) {
np->recover_error = 0;
- printk(KERN_INFO "%s: MAC in recoverable error state\n", dev->name);
+ netdev_info(dev, "MAC in recoverable error state\n");
if (netif_running(dev)) {
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
@@ -3975,7 +3842,7 @@ static void nv_do_nic_poll(unsigned long data)
/* reinit nic view of the rx queue */
writel(np->rx_buf_sz, base + NvRegOffloadConfig);
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
@@ -4105,7 +3972,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
}
if (netif_carrier_ok(dev)) {
- switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) {
+ switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) {
case NVREG_LINKSPEED_10:
ecmd->speed = SPEED_10;
break;
@@ -4250,14 +4117,14 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
}
if (netif_running(dev))
- printk(KERN_INFO "%s: link down.\n", dev->name);
+ netdev_info(dev, "link down\n");
bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
if (np->phy_model == PHY_MODEL_MARVELL_E3016) {
bmcr |= BMCR_ANENABLE;
/* reset the phy in order for settings to stick,
* and cause autoneg to start */
if (phy_reset(dev, bmcr)) {
- printk(KERN_INFO "%s: phy reset failed\n", dev->name);
+ netdev_info(dev, "phy reset failed\n");
return -EINVAL;
}
} else {
@@ -4306,7 +4173,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if (np->phy_oui == PHY_OUI_MARVELL) {
/* reset the phy in order for forced mode settings to stick */
if (phy_reset(dev, bmcr)) {
- printk(KERN_INFO "%s: phy reset failed\n", dev->name);
+ netdev_info(dev, "phy reset failed\n");
return -EINVAL;
}
} else {
@@ -4344,7 +4211,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
regs->version = FORCEDETH_REGS_VER;
spin_lock_irq(&np->lock);
- for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ for (i = 0; i <= np->register_size/sizeof(u32); i++)
rbuf[i] = readl(base + i*sizeof(u32));
spin_unlock_irq(&np->lock);
}
@@ -4368,7 +4235,7 @@ static int nv_nway_reset(struct net_device *dev)
spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
- printk(KERN_INFO "%s: link down.\n", dev->name);
+ netdev_info(dev, "link down\n");
}
bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
@@ -4376,7 +4243,7 @@ static int nv_nway_reset(struct net_device *dev)
bmcr |= BMCR_ANENABLE;
/* reset the phy in order for settings to stick*/
if (phy_reset(dev, bmcr)) {
- printk(KERN_INFO "%s: phy reset failed\n", dev->name);
+ netdev_info(dev, "phy reset failed\n");
return -EINVAL;
}
} else {
@@ -4464,10 +4331,9 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending),
rxtx_ring, ring_addr);
}
- if (rx_skbuff)
- kfree(rx_skbuff);
- if (tx_skbuff)
- kfree(tx_skbuff);
+
+ kfree(rx_skbuff);
+ kfree(tx_skbuff);
goto exit;
}
@@ -4491,14 +4357,14 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
np->tx_ring_size = ring->tx_pending;
if (!nv_optimized(np)) {
- np->rx_ring.orig = (struct ring_desc*)rxtx_ring;
+ np->rx_ring.orig = (struct ring_desc *)rxtx_ring;
np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size];
} else {
- np->rx_ring.ex = (struct ring_desc_ex*)rxtx_ring;
+ np->rx_ring.ex = (struct ring_desc_ex *)rxtx_ring;
np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size];
}
- np->rx_skb = (struct nv_skb_map*)rx_skbuff;
- np->tx_skb = (struct nv_skb_map*)tx_skbuff;
+ np->rx_skb = (struct nv_skb_map *)rx_skbuff;
+ np->tx_skb = (struct nv_skb_map *)tx_skbuff;
np->ring_addr = ring_addr;
memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size);
@@ -4515,7 +4381,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
/* reinit nic view of the queues */
writel(np->rx_buf_sz, base + NvRegOffloadConfig);
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
@@ -4550,12 +4416,11 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
if ((!np->autoneg && np->duplex == 0) ||
(np->autoneg && !pause->autoneg && np->duplex == 0)) {
- printk(KERN_INFO "%s: can not set pause settings when forced link is in half duplex.\n",
- dev->name);
+ netdev_info(dev, "can not set pause settings when forced link is in half duplex\n");
return -EINVAL;
}
if (pause->tx_pause && !(np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE)) {
- printk(KERN_INFO "%s: hardware does not support tx pause frames.\n", dev->name);
+ netdev_info(dev, "hardware does not support tx pause frames\n");
return -EINVAL;
}
@@ -4590,7 +4455,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv);
if (netif_running(dev))
- printk(KERN_INFO "%s: link down.\n", dev->name);
+ netdev_info(dev, "link down\n");
bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
mii_rw(dev, np->phyaddr, MII_BMCR, bmcr);
@@ -4841,7 +4706,7 @@ static int nv_loopback_test(struct net_device *dev)
/* reinit nic view of the rx queue */
writel(np->rx_buf_sz, base + NvRegOffloadConfig);
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
@@ -4852,8 +4717,7 @@ static int nv_loopback_test(struct net_device *dev)
pkt_len = ETH_DATA_LEN;
tx_skb = dev_alloc_skb(pkt_len);
if (!tx_skb) {
- printk(KERN_ERR "dev_alloc_skb() failed during loopback test"
- " of %s\n", dev->name);
+ netdev_err(dev, "dev_alloc_skb() failed during loopback test\n");
ret = 0;
goto out;
}
@@ -4893,29 +4757,22 @@ static int nv_loopback_test(struct net_device *dev)
if (flags & NV_RX_ERROR)
ret = 0;
} else {
- if (flags & NV_RX2_ERROR) {
+ if (flags & NV_RX2_ERROR)
ret = 0;
- }
}
if (ret) {
if (len != pkt_len) {
ret = 0;
- dprintk(KERN_DEBUG "%s: loopback len mismatch %d vs %d\n",
- dev->name, len, pkt_len);
} else {
rx_skb = np->rx_skb[0].skb;
for (i = 0; i < pkt_len; i++) {
if (rx_skb->data[i] != (u8)(i & 0xff)) {
ret = 0;
- dprintk(KERN_DEBUG "%s: loopback pattern check failed on byte %d\n",
- dev->name, i);
break;
}
}
}
- } else {
- dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name);
}
pci_unmap_single(np->pci_dev, test_dma_addr,
@@ -4958,11 +4815,10 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
netif_addr_lock(dev);
spin_lock_irq(&np->lock);
nv_disable_hw_interrupts(dev, np->irqmask);
- if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
- } else {
+ else
writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
- }
/* stop engines */
nv_stop_rxtx(dev);
nv_txrx_reset(dev);
@@ -5003,7 +4859,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
/* reinit nic view of the rx queue */
writel(np->rx_buf_sz, base + NvRegOffloadConfig);
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
@@ -5106,8 +4962,7 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) {
np->mgmt_sema = 1;
return 1;
- }
- else
+ } else
udelay(50);
}
@@ -5167,8 +5022,6 @@ static int nv_open(struct net_device *dev)
int oom, i;
u32 low;
- dprintk(KERN_DEBUG "nv_open: begin\n");
-
/* power up phy */
mii_rw(dev, np->phyaddr, MII_BMCR,
mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN);
@@ -5204,7 +5057,7 @@ static int nv_open(struct net_device *dev)
/* give hw rings */
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
- writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
+ writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
writel(np->linkspeed, base + NvRegLinkSpeed);
@@ -5216,9 +5069,11 @@ static int nv_open(struct net_device *dev)
writel(np->vlanctl_bits, base + NvRegVlanControl);
pci_push(base);
writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
- reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
- NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
- KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
+ if (reg_delay(dev, NvRegUnknownSetupReg5,
+ NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
+ NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX))
+ netdev_info(dev,
+ "%s: SetupReg5, Bit 31 remained off\n", __func__);
writel(0, base + NvRegMIIMask);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
@@ -5251,8 +5106,7 @@ static int nv_open(struct net_device *dev)
writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval);
else
writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);
- }
- else
+ } else
writel(poll_interval & 0xFFFF, base + NvRegPollingInterval);
writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,
@@ -5263,7 +5117,7 @@ static int nv_open(struct net_device *dev)
writel(NVREG_WAKEUPFLAGS_ENABLE , base + NvRegWakeUpFlags);
i = readl(base + NvRegPowerState);
- if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0)
+ if ((i & NVREG_POWERSTATE_POWEREDUP) == 0)
writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState);
pci_push(base);
@@ -5276,9 +5130,8 @@ static int nv_open(struct net_device *dev)
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
pci_push(base);
- if (nv_request_irq(dev, 0)) {
+ if (nv_request_irq(dev, 0))
goto out_drain;
- }
/* ask for interrupts */
nv_enable_hw_interrupts(dev, np->irqmask);
@@ -5296,7 +5149,6 @@ static int nv_open(struct net_device *dev)
u32 miistat;
miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
- dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat);
}
/* set linkspeed to invalid value, thus force nv_update_linkspeed
* to init hw */
@@ -5309,7 +5161,7 @@ static int nv_open(struct net_device *dev)
if (ret) {
netif_carrier_on(dev);
} else {
- printk(KERN_INFO "%s: no link during initialization.\n", dev->name);
+ netdev_info(dev, "no link during initialization\n");
netif_carrier_off(dev);
}
if (oom)
@@ -5352,7 +5204,6 @@ static int nv_close(struct net_device *dev)
base = get_hwbase(dev);
nv_disable_hw_interrupts(dev, np->irqmask);
pci_push(base);
- dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
spin_unlock_irq(&np->lock);
@@ -5421,8 +5272,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
static int printed_version;
if (!printed_version++)
- printk(KERN_INFO "%s: Reverse Engineered nForce ethernet"
- " driver. Version %s.\n", DRV_NAME, FORCEDETH_VERSION);
+ pr_info("Reverse Engineered nForce ethernet driver. Version %s.\n",
+ FORCEDETH_VERSION);
dev = alloc_etherdev(sizeof(struct fe_priv));
err = -ENOMEM;
@@ -5465,10 +5316,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
err = -EINVAL;
addr = 0;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
- dprintk(KERN_DEBUG "%s: resource %d start %p len %ld flags 0x%08lx.\n",
- pci_name(pci_dev), i, (void*)pci_resource_start(pci_dev, i),
- pci_resource_len(pci_dev, i),
- pci_resource_flags(pci_dev, i));
if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM &&
pci_resource_len(pci_dev, i) >= np->register_size) {
addr = pci_resource_start(pci_dev, i);
@@ -5476,8 +5323,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
}
}
if (i == DEVICE_COUNT_RESOURCE) {
- dev_printk(KERN_INFO, &pci_dev->dev,
- "Couldn't find register window\n");
+ dev_info(&pci_dev->dev, "Couldn't find register window\n");
goto out_relreg;
}
@@ -5493,13 +5339,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
if (dma_64bit) {
if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(39)))
- dev_printk(KERN_INFO, &pci_dev->dev,
- "64-bit DMA failed, using 32-bit addressing\n");
+ dev_info(&pci_dev->dev,
+ "64-bit DMA failed, using 32-bit addressing\n");
else
dev->features |= NETIF_F_HIGHDMA;
if (pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(39))) {
- dev_printk(KERN_INFO, &pci_dev->dev,
- "64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
+ dev_info(&pci_dev->dev,
+ "64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
}
}
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
@@ -5620,7 +5466,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
- printk(KERN_DEBUG "nv_probe: set workaround bit for reversed mac addr\n");
+ dev_dbg(&pci_dev->dev,
+ "%s: set workaround bit for reversed mac addr\n",
+ __func__);
}
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
@@ -5629,17 +5477,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
*/
- dev_printk(KERN_ERR, &pci_dev->dev,
- "Invalid Mac address detected: %pM\n",
- dev->dev_addr);
- dev_printk(KERN_ERR, &pci_dev->dev,
- "Please complain to your hardware vendor. Switching to a random MAC.\n");
+ dev_err(&pci_dev->dev,
+ "Invalid MAC address detected: %pM - Please complain to your hardware vendor.\n",
+ dev->dev_addr);
random_ether_addr(dev->dev_addr);
+ dev_err(&pci_dev->dev,
+ "Using random MAC address: %pM\n", dev->dev_addr);
}
- dprintk(KERN_DEBUG "%s: MAC Address %pM\n",
- pci_name(pci_dev), dev->dev_addr);
-
/* set mac address */
nv_copy_mac_to_hw(dev);
@@ -5663,16 +5508,15 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
writel(powerstate, base + NvRegPowerState2);
}
- if (np->desc_ver == DESC_VER_1) {
+ if (np->desc_ver == DESC_VER_1)
np->tx_flags = NV_TX_VALID;
- } else {
+ else
np->tx_flags = NV_TX2_VALID;
- }
np->msi_flags = 0;
- if ((id->driver_data & DEV_HAS_MSI) && msi) {
+ if ((id->driver_data & DEV_HAS_MSI) && msi)
np->msi_flags |= NV_MSI_CAPABLE;
- }
+
if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
/* msix has had reported issues when modifying irqmask
as in the case of napi, therefore, disable for now
@@ -5702,11 +5546,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (id->driver_data & DEV_NEED_TIMERIRQ)
np->irqmask |= NVREG_IRQ_TIMER;
if (id->driver_data & DEV_NEED_LINKTIMER) {
- dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev));
np->need_linktimer = 1;
np->link_timeout = jiffies + LINK_TIMEOUT;
} else {
- dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev));
np->need_linktimer = 0;
}
@@ -5735,19 +5577,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
nv_mgmt_acquire_sema(dev) &&
nv_mgmt_get_version(dev)) {
np->mac_in_use = 1;
- if (np->mgmt_version > 0) {
+ if (np->mgmt_version > 0)
np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE;
- }
- dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n",
- pci_name(pci_dev), np->mac_in_use);
/* management unit setup the phy already? */
if (np->mac_in_use &&
((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
NVREG_XMITCTL_SYNC_PHY_INIT)) {
/* phy is inited by mgmt unit */
phyinitialized = 1;
- dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n",
- pci_name(pci_dev));
} else {
/* we need to init the phy */
}
@@ -5773,8 +5610,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->phy_model = id2 & PHYID2_MODEL_MASK;
id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
- dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
- pci_name(pci_dev), id1, id2, phyaddr);
np->phyaddr = phyaddr;
np->phy_oui = id1 | id2;
@@ -5788,8 +5623,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
break;
}
if (i == 33) {
- dev_printk(KERN_INFO, &pci_dev->dev,
- "open: Could not find a valid PHY.\n");
+ dev_info(&pci_dev->dev, "open: Could not find a valid PHY\n");
goto out_error;
}
@@ -5799,9 +5633,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
} else {
/* see if it is a gigabit phy */
u32 mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
- if (mii_status & PHY_GIGABIT) {
+ if (mii_status & PHY_GIGABIT)
np->gigabit = PHY_GIGABIT;
- }
}
/* set default link speed settings */
@@ -5811,37 +5644,27 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
err = register_netdev(dev);
if (err) {
- dev_printk(KERN_INFO, &pci_dev->dev,
- "unable to register netdev: %d\n", err);
+ dev_info(&pci_dev->dev, "unable to register netdev: %d\n", err);
goto out_error;
}
- dev_printk(KERN_INFO, &pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, "
- "addr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- dev->name,
- np->phy_oui,
- np->phyaddr,
- dev->dev_addr[0],
- dev->dev_addr[1],
- dev->dev_addr[2],
- dev->dev_addr[3],
- dev->dev_addr[4],
- dev->dev_addr[5]);
-
- dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
- dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
- dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ?
- "csum " : "",
- dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
- "vlan " : "",
- id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "",
- id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "",
- id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "",
- np->gigabit == PHY_GIGABIT ? "gbit " : "",
- np->need_linktimer ? "lnktim " : "",
- np->msi_flags & NV_MSI_CAPABLE ? "msi " : "",
- np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "",
- np->desc_ver);
+ dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n",
+ dev->name, np->phy_oui, np->phyaddr, dev->dev_addr);
+
+ dev_info(&pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
+ dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
+ dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ?
+ "csum " : "",
+ dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
+ "vlan " : "",
+ id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "",
+ id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "",
+ id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "",
+ np->gigabit == PHY_GIGABIT ? "gbit " : "",
+ np->need_linktimer ? "lnktim " : "",
+ np->msi_flags & NV_MSI_CAPABLE ? "msi " : "",
+ np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "",
+ np->desc_ver);
return 0;
@@ -5931,13 +5754,13 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state)
int i;
if (netif_running(dev)) {
- // Gross.
+ /* Gross. */
nv_close(dev);
}
netif_device_detach(dev);
/* save non-pci configuration space */
- for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ for (i = 0; i <= np->register_size/sizeof(u32); i++)
np->saved_config_space[i] = readl(base + i*sizeof(u32));
pci_save_state(pdev);
@@ -5960,7 +5783,7 @@ static int nv_resume(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D0, 0);
/* restore non-pci configuration space */
- for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ for (i = 0; i <= np->register_size/sizeof(u32); i++)
writel(np->saved_config_space[i], base+i*sizeof(u32));
if (np->driver_data & DEV_NEED_MSI_FIX)
@@ -5990,9 +5813,8 @@ static void nv_shutdown(struct pci_dev *pdev)
* If we really go for poweroff, we must not restore the MAC,
* otherwise the MAC for WOL will be reversed at least on some boards.
*/
- if (system_state != SYSTEM_POWER_OFF) {
+ if (system_state != SYSTEM_POWER_OFF)
nv_restore_mac_addr(pdev);
- }
pci_disable_device(pdev);
/*
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index d1bec6269173..45c4b7bfcf39 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -143,7 +143,8 @@ void gfar_halt(struct net_device *dev);
static void gfar_halt_nodisable(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
-static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
+static void gfar_set_mac_for_addr(struct net_device *dev, int num,
+ const u8 *addr);
static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
MODULE_AUTHOR("Freescale Semiconductor, Inc");
@@ -3094,10 +3095,10 @@ static void gfar_set_multi(struct net_device *dev)
static void gfar_clear_exact_match(struct net_device *dev)
{
int idx;
- u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0};
+ static const u8 zero_arr[MAC_ADDR_LEN] = {0, 0, 0, 0, 0, 0};
for(idx = 1;idx < GFAR_EM_NUM + 1;idx++)
- gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr);
+ gfar_set_mac_for_addr(dev, idx, zero_arr);
}
/* Set the appropriate hash bit for the given addr */
@@ -3132,7 +3133,8 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
/* There are multiple MAC Address register pairs on some controllers
* This function sets the numth pair to a given address
*/
-static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
+static void gfar_set_mac_for_addr(struct net_device *dev, int num,
+ const u8 *addr)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = priv->gfargrp[0].regs;
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 9a6485892b3d..80d25ed53344 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1202,7 +1202,7 @@ static void hamachi_init_ring(struct net_device *dev)
}
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
hmp->rx_skbuff[i] = skb;
if (skb == NULL)
break;
@@ -1669,7 +1669,7 @@ static int hamachi_rx(struct net_device *dev)
entry = hmp->dirty_rx % RX_RING_SIZE;
desc = &(hmp->rx_ring[entry]);
if (hmp->rx_skbuff[entry] == NULL) {
- struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
hmp->rx_skbuff[entry] = skb;
if (skb == NULL)
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index d15d2f2ba78e..ef2014375e62 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -162,9 +162,9 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
/* Snarf the interrupt now. Someday this could be moved to open(). */
if (dev->irq < 2) {
- int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
- int irq_8list[] = { 7, 5, 3, 4, 9, 0};
- int *irqp = wordmode ? irq_16list : irq_8list;
+ static const int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
+ static const int irq_8list[] = { 7, 5, 3, 4, 9, 0};
+ const int *irqp = wordmode ? irq_16list : irq_8list;
do {
int irq = *irqp;
if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) {
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 06bb9b799458..8f11d29a5828 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2950,7 +2950,7 @@ static int __devexit emac_remove(struct platform_device *ofdev)
unregister_netdev(dev->ndev);
- flush_scheduled_work();
+ cancel_work_sync(&dev->reset_work);
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
tah_detach(dev->tah_dev, dev->tah_port);
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index c454b45ca7ec..5522d459654c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -729,11 +729,6 @@ static void netdev_get_drvinfo(struct net_device *dev,
sizeof(info->version) - 1);
}
-static u32 netdev_get_link(struct net_device *dev)
-{
- return 1;
-}
-
static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
@@ -918,7 +913,7 @@ static void ibmveth_get_ethtool_stats(struct net_device *dev,
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
.get_settings = netdev_get_settings,
- .get_link = netdev_get_link,
+ .get_link = ethtool_op_get_link,
.set_tx_csum = ibmveth_set_tx_csum,
.get_rx_csum = ibmveth_get_rx_csum,
.set_rx_csum = ibmveth_set_rx_csum,
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ab9f675c5b8b..e07d487f015a 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -36,22 +36,10 @@
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
-#define TX_TIMEOUT (2*HZ)
-
#define TX_Q_LIMIT 32
struct ifb_private {
struct tasklet_struct ifb_tasklet;
int tasklet_pending;
- /* mostly debug stats leave in for now */
- unsigned long st_task_enter; /* tasklet entered */
- unsigned long st_txq_refl_try; /* transmit queue refill attempt */
- unsigned long st_rxq_enter; /* receive queue entered */
- unsigned long st_rx2tx_tran; /* receive to trasmit transfers */
- unsigned long st_rxq_notenter; /*receiveQ not entered, resched */
- unsigned long st_rx_frm_egr; /* received from egress path */
- unsigned long st_rx_frm_ing; /* received from ingress path */
- unsigned long st_rxq_check;
- unsigned long st_rxq_rsch;
struct sk_buff_head rq;
struct sk_buff_head tq;
};
@@ -73,24 +61,17 @@ static void ri_tasklet(unsigned long dev)
struct sk_buff *skb;
txq = netdev_get_tx_queue(_dev, 0);
- dp->st_task_enter++;
if ((skb = skb_peek(&dp->tq)) == NULL) {
- dp->st_txq_refl_try++;
if (__netif_tx_trylock(txq)) {
- dp->st_rxq_enter++;
- while ((skb = skb_dequeue(&dp->rq)) != NULL) {
- skb_queue_tail(&dp->tq, skb);
- dp->st_rx2tx_tran++;
- }
+ skb_queue_splice_tail_init(&dp->rq, &dp->tq);
__netif_tx_unlock(txq);
} else {
/* reschedule */
- dp->st_rxq_notenter++;
goto resched;
}
}
- while ((skb = skb_dequeue(&dp->tq)) != NULL) {
+ while ((skb = __skb_dequeue(&dp->tq)) != NULL) {
u32 from = G_TC_FROM(skb->tc_verd);
skb->tc_verd = 0;
@@ -104,30 +85,28 @@ static void ri_tasklet(unsigned long dev)
rcu_read_unlock();
dev_kfree_skb(skb);
stats->tx_dropped++;
+ if (skb_queue_len(&dp->tq) != 0)
+ goto resched;
break;
}
rcu_read_unlock();
skb->skb_iif = _dev->ifindex;
if (from & AT_EGRESS) {
- dp->st_rx_frm_egr++;
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
- dp->st_rx_frm_ing++;
skb_pull(skb, skb->dev->hard_header_len);
- netif_rx(skb);
+ netif_receive_skb(skb);
} else
BUG();
}
if (__netif_tx_trylock(txq)) {
- dp->st_rxq_check++;
if ((skb = skb_peek(&dp->rq)) == NULL) {
dp->tasklet_pending = 0;
if (netif_queue_stopped(_dev))
netif_wake_queue(_dev);
} else {
- dp->st_rxq_rsch++;
__netif_tx_unlock(txq);
goto resched;
}
@@ -147,6 +126,10 @@ static const struct net_device_ops ifb_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
+#define IFB_FEATURES (NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \
+ NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \
+ NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_TX)
+
static void ifb_setup(struct net_device *dev)
{
/* Initialize the device structure. */
@@ -157,6 +140,9 @@ static void ifb_setup(struct net_device *dev)
ether_setup(dev);
dev->tx_queue_len = TX_Q_LIMIT;
+ dev->features |= IFB_FEATURES;
+ dev->vlan_features |= IFB_FEATURES;
+
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
@@ -182,7 +168,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
}
- skb_queue_tail(&dp->rq, skb);
+ __skb_queue_tail(&dp->rq, skb);
if (!dp->tasklet_pending) {
dp->tasklet_pending = 1;
tasklet_schedule(&dp->ifb_tasklet);
@@ -197,8 +183,8 @@ static int ifb_close(struct net_device *dev)
tasklet_kill(&dp->ifb_tasklet);
netif_stop_queue(dev);
- skb_queue_purge(&dp->rq);
- skb_queue_purge(&dp->tq);
+ __skb_queue_purge(&dp->rq);
+ __skb_queue_purge(&dp->tq);
return 0;
}
@@ -207,8 +193,8 @@ static int ifb_open(struct net_device *dev)
struct ifb_private *dp = netdev_priv(dev);
tasklet_init(&dp->ifb_tasklet, ri_tasklet, (unsigned long)dev);
- skb_queue_head_init(&dp->rq);
- skb_queue_head_init(&dp->tq);
+ __skb_queue_head_init(&dp->rq);
+ __skb_queue_head_init(&dp->tq);
netif_start_queue(dev);
return 0;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index bc183f5487cb..0a2368fa6bc6 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -134,6 +134,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_82580_COPPER_DUAL:
case E1000_DEV_ID_DH89XXCC_SGMII:
case E1000_DEV_ID_DH89XXCC_SERDES:
+ case E1000_DEV_ID_DH89XXCC_BACKPLANE:
+ case E1000_DEV_ID_DH89XXCC_SFP:
mac->type = e1000_82580;
break;
case E1000_DEV_ID_I350_COPPER:
@@ -1478,6 +1480,39 @@ out:
}
/**
+ * igb_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ * @pf: Physical Function pool - do not set anti-spoofing for the PF
+ *
+ * enables/disables L2 switch anti-spoofing functionality.
+ **/
+void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
+{
+ u32 dtxswc;
+
+ switch (hw->mac.type) {
+ case e1000_82576:
+ case e1000_i350:
+ dtxswc = rd32(E1000_DTXSWC);
+ if (enable) {
+ dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+ E1000_DTXSWC_VLAN_SPOOF_MASK);
+ /* The PF can spoof - it has to in order to
+ * support emulation mode NICs */
+ dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+ } else {
+ dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+ E1000_DTXSWC_VLAN_SPOOF_MASK);
+ }
+ wr32(E1000_DTXSWC, dtxswc);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
* igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
* @hw: pointer to the hardware struct
* @enable: state to enter, either enabled or disabled
@@ -1578,7 +1613,7 @@ static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw)
{
s32 ret_val = 0;
u32 mdicnfg;
- u16 nvm_data;
+ u16 nvm_data = 0;
if (hw->mac.type != e1000_82580)
goto out;
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index cbd1e1259e4d..1d01af2472e7 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -194,6 +194,10 @@ struct e1000_adv_tx_context_desc {
#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
+#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
+#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
+#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
+#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
/* Easy defines for setting default pool, would normally be left a zero */
@@ -243,6 +247,7 @@ struct e1000_adv_tx_context_desc {
/* RX packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
+void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int);
void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 data);
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 62222796a8b3..6319ed902bc0 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -419,6 +419,9 @@
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
#define E1000_ERR_MBX 15
+#define E1000_ERR_INVALID_ARGUMENT 16
+#define E1000_ERR_NO_SPACE 17
+#define E1000_ERR_NVM_PBA_SECTION 18
/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
@@ -580,11 +583,15 @@
/* Mask bits for fields in Word 0x1a of the NVM */
+/* length of string needed to store part num */
+#define E1000_PBANUM_LENGTH 11
+
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
+#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6
/* NVM Commands - Microwire */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index c0b017f8d782..e2638afb8cdc 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -54,8 +54,10 @@ struct e1000_hw;
#define E1000_DEV_ID_82580_SERDES 0x1510
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
-#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436
-#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438
+#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
+#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
+#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
+#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
#define E1000_DEV_ID_I350_COPPER 0x1521
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index d83b77fa4038..6b5cc2cc453d 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -445,31 +445,112 @@ out:
}
/**
- * igb_read_part_num - Read device part number
+ * igb_read_part_string - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
+ * @part_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
-s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
+s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size)
{
- s32 ret_val;
+ s32 ret_val;
u16 nvm_data;
+ u16 pointer;
+ u16 offset;
+ u16 length;
+
+ if (part_num == NULL) {
+ hw_dbg("PBA string buffer was null\n");
+ ret_val = E1000_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
- *part_num = (u32)(nvm_data << 16);
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pointer);
+ if (ret_val) {
+ hw_dbg("NVM Read Error\n");
+ goto out;
+ }
+
+ /*
+ * if nvm_data is not ptr guard the PBA must be in legacy format which
+ * means pointer is actually our second data word for the PBA number
+ * and we can decode it into an ascii string
+ */
+ if (nvm_data != NVM_PBA_PTR_GUARD) {
+ hw_dbg("NVM PBA number is not stored as string\n");
+
+ /* we will need 11 characters to store the PBA */
+ if (part_num_size < 11) {
+ hw_dbg("PBA string buffer too small\n");
+ return E1000_ERR_NO_SPACE;
+ }
+
+ /* extract hex string from data and pointer */
+ part_num[0] = (nvm_data >> 12) & 0xF;
+ part_num[1] = (nvm_data >> 8) & 0xF;
+ part_num[2] = (nvm_data >> 4) & 0xF;
+ part_num[3] = nvm_data & 0xF;
+ part_num[4] = (pointer >> 12) & 0xF;
+ part_num[5] = (pointer >> 8) & 0xF;
+ part_num[6] = '-';
+ part_num[7] = 0;
+ part_num[8] = (pointer >> 4) & 0xF;
+ part_num[9] = pointer & 0xF;
+
+ /* put a null character on the end of our string */
+ part_num[10] = '\0';
+
+ /* switch all the data but the '-' to hex char */
+ for (offset = 0; offset < 10; offset++) {
+ if (part_num[offset] < 0xA)
+ part_num[offset] += '0';
+ else if (part_num[offset] < 0x10)
+ part_num[offset] += 'A' - 0xA;
+ }
+
+ goto out;
+ }
+
+ ret_val = hw->nvm.ops.read(hw, pointer, 1, &length);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
- *part_num |= nvm_data;
+
+ if (length == 0xFFFF || length == 0) {
+ hw_dbg("NVM PBA number section invalid length\n");
+ ret_val = E1000_ERR_NVM_PBA_SECTION;
+ goto out;
+ }
+ /* check if part_num buffer is big enough */
+ if (part_num_size < (((u32)length * 2) - 1)) {
+ hw_dbg("PBA string buffer too small\n");
+ ret_val = E1000_ERR_NO_SPACE;
+ goto out;
+ }
+
+ /* trim pba length from start of string */
+ pointer++;
+ length--;
+
+ for (offset = 0; offset < length; offset++) {
+ ret_val = hw->nvm.ops.read(hw, pointer + offset, 1, &nvm_data);
+ if (ret_val) {
+ hw_dbg("NVM Read Error\n");
+ goto out;
+ }
+ part_num[offset * 2] = (u8)(nvm_data >> 8);
+ part_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
+ }
+ part_num[offset * 2] = '\0';
out:
return ret_val;
diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h
index 1041c34dcbe1..29c956a84bd0 100644
--- a/drivers/net/igb/e1000_nvm.h
+++ b/drivers/net/igb/e1000_nvm.h
@@ -32,6 +32,8 @@ s32 igb_acquire_nvm(struct e1000_hw *hw);
void igb_release_nvm(struct e1000_hw *hw);
s32 igb_read_mac_addr(struct e1000_hw *hw);
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
+s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
+ u32 part_num_size);
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index ddd036a78999..6694bf3e5ad9 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1757,11 +1757,12 @@ s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
u16 phy_data, i, agc_value = 0;
u16 cur_agc_index, max_agc_index = 0;
u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
- u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
- {IGP02E1000_PHY_AGC_A,
- IGP02E1000_PHY_AGC_B,
- IGP02E1000_PHY_AGC_C,
- IGP02E1000_PHY_AGC_D};
+ static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
+ IGP02E1000_PHY_AGC_A,
+ IGP02E1000_PHY_AGC_B,
+ IGP02E1000_PHY_AGC_C,
+ IGP02E1000_PHY_AGC_D
+ };
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index abb7333a1fbf..8ac83c5190d5 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -301,6 +301,7 @@
#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
+#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index edab9c442399..92a4ef09e55c 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -324,6 +324,7 @@ struct igb_adapter {
unsigned int vfs_allocated_count;
struct vf_data_storage *vf_data;
u32 rss_queues;
+ u32 wvbr;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 892d196f17ac..58c665b7513d 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -73,6 +73,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_BACKPLANE), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SFP), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
@@ -1654,7 +1656,7 @@ void igb_reset(struct igb_adapter *adapter)
if (adapter->vfs_allocated_count) {
int i;
for (i = 0 ; i < adapter->vfs_allocated_count; i++)
- adapter->vf_data[i].flags = 0;
+ adapter->vf_data[i].flags &= IGB_VF_FLAG_PF_SET_MAC;
/* ping all the active vfs to let them know we are going down */
igb_ping_all_vfs(adapter);
@@ -1729,12 +1731,13 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct igb_adapter *adapter;
struct e1000_hw *hw;
u16 eeprom_data = 0;
+ s32 ret_val;
static int global_quad_port_a; /* global quad port a indication */
const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len;
int err, pci_using_dac;
u16 eeprom_apme_mask = IGB_EEPROM_APME;
- u32 part_num;
+ u8 part_str[E1000_PBANUM_LENGTH];
/* Catch broken hardware that put the wrong VF device ID in
* the PCIe SR-IOV capability.
@@ -2000,10 +2003,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
"unknown"),
netdev->dev_addr);
- igb_read_part_num(hw, &part_num);
- dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name,
- (part_num >> 8), (part_num & 0xff));
-
+ ret_val = igb_read_part_string(hw, part_str, E1000_PBANUM_LENGTH);
+ if (ret_val)
+ strcpy(part_str, "Unknown");
+ dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str);
dev_info(&pdev->dev,
"Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
adapter->msix_entries ? "MSI-X" :
@@ -2049,13 +2052,16 @@ static void __devexit igb_remove(struct pci_dev *pdev)
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- /* flush_scheduled work may reschedule our watchdog task, so
- * explicitly disable watchdog tasks from being rescheduled */
+ /*
+ * The watchdog timer may be rescheduled, so explicitly
+ * disable watchdog from being rescheduled.
+ */
set_bit(__IGB_DOWN, &adapter->state);
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
- flush_scheduled_work();
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->watchdog_task);
#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
@@ -2436,10 +2442,9 @@ int igb_setup_tx_resources(struct igb_ring *tx_ring)
int size;
size = sizeof(struct igb_buffer) * tx_ring->count;
- tx_ring->buffer_info = vmalloc(size);
+ tx_ring->buffer_info = vzalloc(size);
if (!tx_ring->buffer_info)
goto err;
- memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
@@ -2587,10 +2592,9 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
int size, desc_len;
size = sizeof(struct igb_buffer) * rx_ring->count;
- rx_ring->buffer_info = vmalloc(size);
+ rx_ring->buffer_info = vzalloc(size);
if (!rx_ring->buffer_info)
goto err;
- memset(rx_ring->buffer_info, 0, size);
desc_len = sizeof(union e1000_adv_rx_desc);
@@ -3362,6 +3366,45 @@ static void igb_set_rx_mode(struct net_device *netdev)
igb_restore_vf_multicasts(adapter);
}
+static void igb_check_wvbr(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 wvbr = 0;
+
+ switch (hw->mac.type) {
+ case e1000_82576:
+ case e1000_i350:
+ if (!(wvbr = rd32(E1000_WVBR)))
+ return;
+ break;
+ default:
+ break;
+ }
+
+ adapter->wvbr |= wvbr;
+}
+
+#define IGB_STAGGERED_QUEUE_OFFSET 8
+
+static void igb_spoof_check(struct igb_adapter *adapter)
+{
+ int j;
+
+ if (!adapter->wvbr)
+ return;
+
+ for(j = 0; j < adapter->vfs_allocated_count; j++) {
+ if (adapter->wvbr & (1 << j) ||
+ adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) {
+ dev_warn(&adapter->pdev->dev,
+ "Spoof event(s) detected on VF %d\n", j);
+ adapter->wvbr &=
+ ~((1 << j) |
+ (1 << (j + IGB_STAGGERED_QUEUE_OFFSET)));
+ }
+ }
+}
+
/* Need to wait a few seconds after link up to get diagnostic information from
* the phy */
static void igb_update_phy_info(unsigned long data)
@@ -3521,6 +3564,8 @@ static void igb_watchdog_task(struct work_struct *work)
wr32(E1000_ICS, E1000_ICS_RXDMT0);
}
+ igb_spoof_check(adapter);
+
/* Reset the timer */
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer,
@@ -4517,6 +4562,10 @@ static irqreturn_t igb_msix_other(int irq, void *data)
if (icr & E1000_ICR_DOUTSYNC) {
/* HW is reporting DMA is out of sync */
adapter->stats.doosync++;
+ /* The DMA Out of Sync is also indication of a spoof event
+ * in IOV mode. Check the Wrong VM Behavior register to
+ * see if it is really a spoof event. */
+ igb_check_wvbr(adapter);
}
/* Check for a mailbox event */
@@ -4969,8 +5018,8 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
{
- /* clear flags */
- adapter->vf_data[vf].flags &= ~(IGB_VF_FLAG_PF_SET_MAC);
+ /* clear flags - except flag that indicates PF has set the MAC */
+ adapter->vf_data[vf].flags &= IGB_VF_FLAG_PF_SET_MAC;
adapter->vf_data[vf].last_nack = jiffies;
/* reset offloads to defaults */
@@ -5024,7 +5073,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
reg = rd32(E1000_VFRE);
wr32(E1000_VFRE, reg | (1 << vf));
- adapter->vf_data[vf].flags = IGB_VF_FLAG_CTS;
+ adapter->vf_data[vf].flags |= IGB_VF_FLAG_CTS;
/* reply to reset with ack and vf mac address */
msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
@@ -5103,7 +5152,14 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
switch ((msgbuf[0] & 0xFFFF)) {
case E1000_VF_SET_MAC_ADDR:
- retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
+ retval = -EINVAL;
+ if (!(vf_data->flags & IGB_VF_FLAG_PF_SET_MAC))
+ retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
+ else
+ dev_warn(&pdev->dev,
+ "VF %d attempted to override administratively "
+ "set MAC address\nReload the VF driver to "
+ "resume operations\n", vf);
break;
case E1000_VF_SET_PROMISC:
retval = igb_set_vf_promisc(adapter, msgbuf, vf);
@@ -5115,8 +5171,12 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
break;
case E1000_VF_SET_VLAN:
- if (adapter->vf_data[vf].pf_vlan)
- retval = -1;
+ retval = -1;
+ if (vf_data->pf_vlan)
+ dev_warn(&pdev->dev,
+ "VF %d attempted to override administratively "
+ "set VLAN tag\nReload the VF driver to "
+ "resume operations\n", vf);
else
retval = igb_set_vf_vlan(adapter, msgbuf, vf);
break;
@@ -6580,6 +6640,8 @@ static void igb_vmm_control(struct igb_adapter *adapter)
if (adapter->vfs_allocated_count) {
igb_vmdq_set_loopback_pf(hw, true);
igb_vmdq_set_replication_pf(hw, true);
+ igb_vmdq_set_anti_spoofing_pf(hw, true,
+ adapter->vfs_allocated_count);
} else {
igb_vmdq_set_loopback_pf(hw, false);
igb_vmdq_set_replication_pf(hw, false);
diff --git a/drivers/net/igbvf/Makefile b/drivers/net/igbvf/Makefile
index c2f150d8f2d9..0fa3db3dd8b6 100644
--- a/drivers/net/igbvf/Makefile
+++ b/drivers/net/igbvf/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel(R) 82576 Virtual Function Linux driver
-# Copyright(c) 2009 Intel Corporation.
+# Copyright(c) 2009 - 2010 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/igbvf/defines.h b/drivers/net/igbvf/defines.h
index 88a47537518a..79f2604673fe 100644
--- a/drivers/net/igbvf/defines.h
+++ b/drivers/net/igbvf/defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 33add708bcbe..ed6e3d910247 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -110,11 +110,6 @@ static int igbvf_get_settings(struct net_device *netdev,
return 0;
}
-static u32 igbvf_get_link(struct net_device *netdev)
-{
- return netif_carrier_ok(netdev);
-}
-
static int igbvf_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
@@ -515,7 +510,7 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
.get_msglevel = igbvf_get_msglevel,
.set_msglevel = igbvf_set_msglevel,
.nway_reset = igbvf_nway_reset,
- .get_link = igbvf_get_link,
+ .get_link = ethtool_op_get_link,
.get_eeprom_len = igbvf_get_eeprom_len,
.get_eeprom = igbvf_get_eeprom,
.set_eeprom = igbvf_set_eeprom,
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
index debeee2dc717..990c329e6c3b 100644
--- a/drivers/net/igbvf/igbvf.h
+++ b/drivers/net/igbvf/igbvf.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -97,6 +97,7 @@ struct igbvf_adapter;
enum igbvf_boards {
board_vf,
+ board_i350_vf,
};
struct igbvf_queue_stats {
@@ -126,7 +127,6 @@ struct igbvf_buffer {
unsigned int page_offset;
};
};
- struct page *page;
};
union igbvf_desc {
diff --git a/drivers/net/igbvf/mbx.c b/drivers/net/igbvf/mbx.c
index 819a8ec901dc..3d6f4cc3998a 100644
--- a/drivers/net/igbvf/mbx.c
+++ b/drivers/net/igbvf/mbx.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/igbvf/mbx.h b/drivers/net/igbvf/mbx.h
index 4938609dbfb5..c2883c45d477 100644
--- a/drivers/net/igbvf/mbx.h
+++ b/drivers/net/igbvf/mbx.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 28af019c97bb..6352c8158e6d 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -44,12 +44,13 @@
#include "igbvf.h"
-#define DRV_VERSION "1.0.0-k0"
+#define DRV_VERSION "1.0.8-k0"
char igbvf_driver_name[] = "igbvf";
const char igbvf_driver_version[] = DRV_VERSION;
static const char igbvf_driver_string[] =
"Intel(R) Virtual Function Network Driver";
-static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+static const char igbvf_copyright[] =
+ "Copyright (c) 2009 - 2010 Intel Corporation.";
static int igbvf_poll(struct napi_struct *napi, int budget);
static void igbvf_reset(struct igbvf_adapter *);
@@ -63,8 +64,16 @@ static struct igbvf_info igbvf_vf_info = {
.init_ops = e1000_init_function_pointers_vf,
};
+static struct igbvf_info igbvf_i350_vf_info = {
+ .mac = e1000_vfadapt_i350,
+ .flags = 0,
+ .pba = 10,
+ .init_ops = e1000_init_function_pointers_vf,
+};
+
static const struct igbvf_info *igbvf_info_tbl[] = {
[board_vf] = &igbvf_vf_info,
+ [board_i350_vf] = &igbvf_i350_vf_info,
};
/**
@@ -429,10 +438,9 @@ int igbvf_setup_tx_resources(struct igbvf_adapter *adapter,
int size;
size = sizeof(struct igbvf_buffer) * tx_ring->count;
- tx_ring->buffer_info = vmalloc(size);
+ tx_ring->buffer_info = vzalloc(size);
if (!tx_ring->buffer_info)
goto err;
- memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
@@ -469,10 +477,9 @@ int igbvf_setup_rx_resources(struct igbvf_adapter *adapter,
int size, desc_len;
size = sizeof(struct igbvf_buffer) * rx_ring->count;
- rx_ring->buffer_info = vmalloc(size);
+ rx_ring->buffer_info = vzalloc(size);
if (!rx_ring->buffer_info)
goto err;
- memset(rx_ring->buffer_info, 0, size);
desc_len = sizeof(union e1000_adv_rx_desc);
@@ -1851,8 +1858,6 @@ static void igbvf_watchdog_task(struct work_struct *work)
if (link) {
if (!netif_carrier_ok(netdev)) {
- bool txb2b = 1;
-
mac->ops.get_link_up_info(&adapter->hw,
&adapter->link_speed,
&adapter->link_duplex);
@@ -1862,11 +1867,9 @@ static void igbvf_watchdog_task(struct work_struct *work)
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
- txb2b = 0;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
- txb2b = 0;
/* maybe add some timeout factor ? */
break;
}
@@ -2830,13 +2833,14 @@ static void __devexit igbvf_remove(struct pci_dev *pdev)
struct e1000_hw *hw = &adapter->hw;
/*
- * flush_scheduled work may reschedule our watchdog task, so
- * explicitly disable watchdog tasks from being rescheduled
+ * The watchdog timer may be rescheduled, so explicitly
+ * disable it from being rescheduled.
*/
set_bit(__IGBVF_DOWN, &adapter->state);
del_timer_sync(&adapter->watchdog_timer);
- flush_scheduled_work();
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->watchdog_task);
unregister_netdev(netdev);
@@ -2869,6 +2873,7 @@ static struct pci_error_handlers igbvf_err_handler = {
static DEFINE_PCI_DEVICE_TABLE(igbvf_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_VF), board_i350_vf },
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl);
diff --git a/drivers/net/igbvf/regs.h b/drivers/net/igbvf/regs.h
index b9e24ed70d0a..77e18d3d6b15 100644
--- a/drivers/net/igbvf/regs.h
+++ b/drivers/net/igbvf/regs.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c
index a9a61efa964c..74486a8b009a 100644
--- a/drivers/net/igbvf/vf.c
+++ b/drivers/net/igbvf/vf.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -362,8 +362,8 @@ static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
* or a virtual function reset
*/
- /* If we were hit with a reset drop the link */
- if (!mbx->ops.check_for_rst(hw))
+ /* If we were hit with a reset or timeout drop the link */
+ if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
mac->get_link_status = true;
if (!mac->get_link_status)
diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h
index 1e8ce3741a67..d7ed58fcd9bb 100644
--- a/drivers/net/igbvf/vf.h
+++ b/drivers/net/igbvf/vf.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) 82576 Virtual Function Linux driver
- Copyright(c) 2009 Intel Corporation.
+ Copyright(c) 2009 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -39,6 +39,7 @@
struct e1000_hw;
#define E1000_DEV_ID_82576_VF 0x10CA
+#define E1000_DEV_ID_I350_VF 0x1520
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
#define E1000_REVISION_2 2
@@ -133,6 +134,7 @@ struct e1000_adv_tx_context_desc {
enum e1000_mac_type {
e1000_undefined = 0,
e1000_vfadapt,
+ e1000_vfadapt_i350,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
diff --git a/drivers/net/irda/act200l-sir.c b/drivers/net/irda/act200l-sir.c
index 37ab8c855719..8ff084f1d236 100644
--- a/drivers/net/irda/act200l-sir.c
+++ b/drivers/net/irda/act200l-sir.c
@@ -199,7 +199,7 @@ static int act200l_reset(struct sir_dev *dev)
{
unsigned state = dev->fsm.substate;
unsigned delay = 0;
- u8 control[9] = {
+ static const u8 control[9] = {
ACT200L_REG15,
ACT200L_REG13 | ACT200L_SHDW,
ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h
index b54a6f08db45..e3b285a67734 100644
--- a/drivers/net/irda/bfin_sir.h
+++ b/drivers/net/irda/bfin_sir.h
@@ -26,6 +26,8 @@
#include <asm/cacheflush.h>
#include <asm/dma.h>
#include <asm/portmux.h>
+#include <mach/bfin_serial_5xx.h>
+#undef DRIVER_NAME
#ifdef CONFIG_SIR_BFIN_DMA
struct dma_rx_buf {
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index b626cccbccd1..f81d944fc360 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -818,9 +818,9 @@ toshoboe_probe (struct toshoboe_cb *self)
{
int i, j, n;
#ifdef USE_MIR
- int bauds[] = { 9600, 115200, 4000000, 1152000 };
+ static const int bauds[] = { 9600, 115200, 4000000, 1152000 };
#else
- int bauds[] = { 9600, 115200, 4000000 };
+ static const int bauds[] = { 9600, 115200, 4000000 };
#endif
unsigned long flags;
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 74b20f179cea..cc821de2c966 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -959,7 +959,7 @@ static void mcs_disconnect(struct usb_interface *intf)
if (!mcs)
return;
- flush_scheduled_work();
+ cancel_work_sync(&mcs->work);
unregister_netdev(mcs->netdev);
free_netdev(mcs->netdev);
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 8c57bfb5f098..1c1677cfea29 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -376,7 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
static int pnp_driver_registered;
#ifdef CONFIG_PNP
-static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
+static int __devinit smsc_ircc_pnp_probe(struct pnp_dev *dev,
const struct pnp_device_id *dev_id)
{
unsigned int firbase, sirbase;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 8df645e78f2e..9ece1fd9889d 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -885,17 +885,8 @@ static void veth_stop_connection(struct veth_lpar_connection *cnx)
veth_kick_statemachine(cnx);
spin_unlock_irq(&cnx->lock);
- /* There's a slim chance the reset code has just queued the
- * statemachine to run in five seconds. If so we need to cancel
- * that and requeue the work to run now. */
- if (cancel_delayed_work(&cnx->statemachine_wq)) {
- spin_lock_irq(&cnx->lock);
- veth_kick_statemachine(cnx);
- spin_unlock_irq(&cnx->lock);
- }
-
- /* Wait for the state machine to run. */
- flush_scheduled_work();
+ /* ensure the statemachine runs now and waits for its completion */
+ flush_delayed_work_sync(&cnx->statemachine_wq);
}
static void veth_destroy_connection(struct veth_lpar_connection *cnx)
@@ -1009,15 +1000,10 @@ static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
return 0;
}
-static u32 veth_get_link(struct net_device *dev)
-{
- return 1;
-}
-
static const struct ethtool_ops ops = {
.get_drvinfo = veth_get_drvinfo,
.get_settings = veth_get_settings,
- .get_link = veth_get_link,
+ .get_link = ethtool_op_get_link,
};
static const struct net_device_ops veth_netdev_ops = {
@@ -1605,7 +1591,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
}
veth_dev[i] = dev;
- port = (struct veth_port*)netdev_priv(dev);
+ port = netdev_priv(dev);
/* Start the state machine on each connection on this vlan. If we're
* the first dev to do so this will commence link negotiation */
@@ -1658,15 +1644,14 @@ static void __exit veth_module_cleanup(void)
/* Disconnect our "irq" to stop events coming from the Hypervisor. */
HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
- /* Make sure any work queued from Hypervisor callbacks is finished. */
- flush_scheduled_work();
-
for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
cnx = veth_cnx[i];
if (!cnx)
continue;
+ /* Cancel work queued from Hypervisor callbacks */
+ cancel_delayed_work_sync(&cnx->statemachine_wq);
/* Remove the connection from sysfs */
kobject_del(&cnx->kobject);
/* Drop the driver's reference to the connection */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index caa8192fff2a..5639cccb4935 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -98,6 +98,8 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);
static void ixgb_tx_timeout(struct net_device *dev);
static void ixgb_tx_timeout_task(struct work_struct *work);
+static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter);
+static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter);
static void ixgb_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
@@ -525,7 +527,7 @@ ixgb_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev_priv(netdev);
- flush_scheduled_work();
+ cancel_work_sync(&adapter->tx_timeout_task);
unregister_netdev(netdev);
@@ -669,13 +671,12 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
int size;
size = sizeof(struct ixgb_buffer) * txdr->count;
- txdr->buffer_info = vmalloc(size);
+ txdr->buffer_info = vzalloc(size);
if (!txdr->buffer_info) {
netif_err(adapter, probe, adapter->netdev,
"Unable to allocate transmit descriptor ring memory\n");
return -ENOMEM;
}
- memset(txdr->buffer_info, 0, size);
/* round up to nearest 4K */
@@ -759,13 +760,12 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
int size;
size = sizeof(struct ixgb_buffer) * rxdr->count;
- rxdr->buffer_info = vmalloc(size);
+ rxdr->buffer_info = vzalloc(size);
if (!rxdr->buffer_info) {
netif_err(adapter, probe, adapter->netdev,
"Unable to allocate receive descriptor ring\n");
return -ENOMEM;
}
- memset(rxdr->buffer_info, 0, size);
/* Round up to nearest 4K */
@@ -1078,6 +1078,8 @@ ixgb_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
+ /* disable VLAN filtering */
+ rctl &= ~IXGB_RCTL_CFIEN;
rctl &= ~IXGB_RCTL_VFE;
} else {
if (netdev->flags & IFF_ALLMULTI) {
@@ -1086,7 +1088,9 @@ ixgb_set_multi(struct net_device *netdev)
} else {
rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
}
+ /* enable VLAN filtering */
rctl |= IXGB_RCTL_VFE;
+ rctl &= ~IXGB_RCTL_CFIEN;
}
if (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
@@ -1105,6 +1109,12 @@ ixgb_set_multi(struct net_device *netdev)
ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0);
}
+
+ if (netdev->features & NETIF_F_HW_VLAN_RX)
+ ixgb_vlan_strip_enable(adapter);
+ else
+ ixgb_vlan_strip_disable(adapter);
+
}
/**
@@ -1252,7 +1262,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
struct ixgb_buffer *buffer_info;
- css = skb_transport_offset(skb);
+ css = skb_checksum_start_offset(skb);
cso = css + skb->csum_offset;
i = adapter->tx_ring.next_to_use;
@@ -2152,33 +2162,30 @@ static void
ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
- u32 ctrl, rctl;
- ixgb_irq_disable(adapter);
adapter->vlgrp = grp;
+}
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
- ctrl |= IXGB_CTRL0_VME;
- IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
-
- /* enable VLAN receive filtering */
+static void
+ixgb_vlan_strip_enable(struct ixgb_adapter *adapter)
+{
+ u32 ctrl;
- rctl = IXGB_READ_REG(&adapter->hw, RCTL);
- rctl &= ~IXGB_RCTL_CFIEN;
- IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
- } else {
- /* disable VLAN tag insert/strip */
+ /* enable VLAN tag insert/strip */
+ ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
+ ctrl |= IXGB_CTRL0_VME;
+ IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
+}
- ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
- ctrl &= ~IXGB_CTRL0_VME;
- IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
- }
+static void
+ixgb_vlan_strip_disable(struct ixgb_adapter *adapter)
+{
+ u32 ctrl;
- /* don't enable interrupts unless we are UP */
- if (adapter->netdev->flags & IFF_UP)
- ixgb_irq_enable(adapter);
+ /* disable VLAN tag insert/strip */
+ ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
+ ctrl &= ~IXGB_CTRL0_VME;
+ IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
}
static void
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index 88a08f056241..dd7fbeb1f7d1 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -191,9 +191,9 @@ struct ixgb_option {
} r;
struct { /* list_option info */
int nr;
- struct ixgb_opt_list {
+ const struct ixgb_opt_list {
int i;
- char *str;
+ const char *str;
} *p;
} l;
} arg;
@@ -226,7 +226,7 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
break;
case list_option: {
int i;
- struct ixgb_opt_list *ent;
+ const struct ixgb_opt_list *ent;
for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
@@ -322,14 +322,15 @@ ixgb_check_options(struct ixgb_adapter *adapter)
}
{ /* Flow Control */
- struct ixgb_opt_list fc_list[] =
- {{ ixgb_fc_none, "Flow Control Disabled" },
- { ixgb_fc_rx_pause,"Flow Control Receive Only" },
- { ixgb_fc_tx_pause,"Flow Control Transmit Only" },
- { ixgb_fc_full, "Flow Control Enabled" },
- { ixgb_fc_default, "Flow Control Hardware Default" }};
+ static const struct ixgb_opt_list fc_list[] = {
+ { ixgb_fc_none, "Flow Control Disabled" },
+ { ixgb_fc_rx_pause, "Flow Control Receive Only" },
+ { ixgb_fc_tx_pause, "Flow Control Transmit Only" },
+ { ixgb_fc_full, "Flow Control Enabled" },
+ { ixgb_fc_default, "Flow Control Hardware Default" }
+ };
- const struct ixgb_option opt = {
+ static const struct ixgb_option opt = {
.type = list_option,
.name = "Flow Control",
.err = "reading default settings from EEPROM",
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 8f81efb49169..7d7387fbdecd 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
- ixgbe_mbx.o
+ ixgbe_mbx.o ixgbe_x540.o
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index ed8703cfffb7..3ae30b8cb7d6 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -61,10 +61,8 @@
#define IXGBE_MIN_RXD 64
/* flow control */
-#define IXGBE_DEFAULT_FCRTL 0x10000
#define IXGBE_MIN_FCRTL 0x40
#define IXGBE_MAX_FCRTL 0x7FF80
-#define IXGBE_DEFAULT_FCRTH 0x20000
#define IXGBE_MIN_FCRTH 0x600
#define IXGBE_MAX_FCRTH 0x7FFF0
#define IXGBE_DEFAULT_FCPAUSE 0xFFFF
@@ -130,7 +128,9 @@ struct ixgbe_tx_buffer {
unsigned long time_stamp;
u16 length;
u16 next_to_watch;
- u16 mapped_as_page;
+ unsigned int bytecount;
+ u16 gso_segs;
+ u8 mapped_as_page;
};
struct ixgbe_rx_buffer {
@@ -146,12 +146,56 @@ struct ixgbe_queue_stats {
u64 bytes;
};
+struct ixgbe_tx_queue_stats {
+ u64 restart_queue;
+ u64 tx_busy;
+ u64 completed;
+ u64 tx_done_old;
+};
+
+struct ixgbe_rx_queue_stats {
+ u64 rsc_count;
+ u64 rsc_flush;
+ u64 non_eop_descs;
+ u64 alloc_rx_page_failed;
+ u64 alloc_rx_buff_failed;
+};
+
+enum ixbge_ring_state_t {
+ __IXGBE_TX_FDIR_INIT_DONE,
+ __IXGBE_TX_DETECT_HANG,
+ __IXGBE_HANG_CHECK_ARMED,
+ __IXGBE_RX_PS_ENABLED,
+ __IXGBE_RX_RSC_ENABLED,
+};
+
+#define ring_is_ps_enabled(ring) \
+ test_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
+#define set_ring_ps_enabled(ring) \
+ set_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
+#define clear_ring_ps_enabled(ring) \
+ clear_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
+#define check_for_tx_hang(ring) \
+ test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
+#define set_check_for_tx_hang(ring) \
+ set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
+#define clear_check_for_tx_hang(ring) \
+ clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
+#define ring_is_rsc_enabled(ring) \
+ test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
+#define set_ring_rsc_enabled(ring) \
+ set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
+#define clear_ring_rsc_enabled(ring) \
+ clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
struct ixgbe_ring {
void *desc; /* descriptor ring memory */
+ struct device *dev; /* device for DMA mapping */
+ struct net_device *netdev; /* netdev ring belongs to */
union {
struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info;
};
+ unsigned long state;
u8 atr_sample_rate;
u8 atr_count;
u16 count; /* amount of descriptors */
@@ -160,38 +204,30 @@ struct ixgbe_ring {
u16 next_to_clean;
u8 queue_index; /* needed for multiqueue queue management */
-
-#define IXGBE_RING_RX_PS_ENABLED (u8)(1)
- u8 flags; /* per ring feature flags */
- u16 head;
- u16 tail;
-
- unsigned int total_bytes;
- unsigned int total_packets;
-
-#ifdef CONFIG_IXGBE_DCA
- /* cpu for tx queue */
- int cpu;
-#endif
-
- u16 work_limit; /* max work per interrupt */
- u16 reg_idx; /* holds the special value that gets
+ u8 reg_idx; /* holds the special value that gets
* the hardware register offset
* associated with this ring, which is
* different for DCB and RSS modes
*/
+ u16 work_limit; /* max work per interrupt */
+
+ u8 __iomem *tail;
+
+ unsigned int total_bytes;
+ unsigned int total_packets;
+
struct ixgbe_queue_stats stats;
struct u64_stats_sync syncp;
+ union {
+ struct ixgbe_tx_queue_stats tx_stats;
+ struct ixgbe_rx_queue_stats rx_stats;
+ };
int numa_node;
- unsigned long reinit_state;
- u64 rsc_count; /* stat for coalesced packets */
- u64 rsc_flush; /* stats for flushed packets */
- u32 restart_queue; /* track tx queue restarts */
- u32 non_eop_descs; /* track hardware descriptor chaining */
-
unsigned int size; /* length in bytes */
dma_addr_t dma; /* phys. address of descriptor ring */
+ struct rcu_head rcu;
+ struct ixgbe_q_vector *q_vector; /* back-pointer to host q_vector */
} ____cacheline_internodealigned_in_smp;
enum ixgbe_ring_f_enum {
@@ -237,6 +273,9 @@ struct ixgbe_q_vector {
unsigned int v_idx; /* index of q_vector within array, also used for
* finding the bit in EICR and friends that
* represents the vector for this ring */
+#ifdef CONFIG_IXGBE_DCA
+ int cpu; /* CPU for DCA */
+#endif
struct napi_struct napi;
DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
@@ -246,6 +285,7 @@ struct ixgbe_q_vector {
u8 rx_itr;
u32 eitr;
cpumask_var_t affinity_mask;
+ char name[IFNAMSIZ + 9];
};
/* Helper macros to switch between ints/sec and what the register uses.
@@ -294,7 +334,6 @@ struct ixgbe_adapter {
u16 bd_number;
struct work_struct reset_task;
struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
- char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
u8 dcb_set_bitmap;
@@ -417,6 +456,7 @@ struct ixgbe_adapter {
int node;
struct work_struct check_overtemp_task;
u32 interrupt_event;
+ char lsc_int_name[IFNAMSIZ + 9];
/* SR-IOV */
DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
@@ -428,17 +468,25 @@ enum ixbge_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
- __IXGBE_FDIR_INIT_DONE,
__IXGBE_SFP_MODULE_NOT_FOUND
};
+struct ixgbe_rsc_cb {
+ dma_addr_t dma;
+ u16 skb_cnt;
+ bool delay_unmap;
+};
+#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
+
enum ixgbe_boards {
board_82598,
board_82599,
+ board_X540,
};
extern struct ixgbe_info ixgbe_82598_info;
extern struct ixgbe_info ixgbe_82599_info;
+extern struct ixgbe_info ixgbe_X540_info;
#ifdef CONFIG_IXGBE_DCB
extern const struct dcbnl_rtnl_ops dcbnl_ops;
extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
@@ -454,26 +502,24 @@ extern void ixgbe_down(struct ixgbe_adapter *adapter);
extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
extern void ixgbe_reset(struct ixgbe_adapter *adapter);
extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
-extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
-extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
-extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
-extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern int ixgbe_setup_rx_resources(struct ixgbe_ring *);
+extern int ixgbe_setup_tx_resources(struct ixgbe_ring *);
+extern void ixgbe_free_rx_resources(struct ixgbe_ring *);
+extern void ixgbe_free_tx_resources(struct ixgbe_ring *);
extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *,
- struct net_device *,
struct ixgbe_adapter *,
struct ixgbe_ring *);
-extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *,
+extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *,
struct ixgbe_tx_buffer *);
-extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int cleaned_count);
+extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16);
extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
extern int ethtool_ioctl(struct ifreq *ifr);
+extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index);
extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
@@ -498,6 +544,10 @@ extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input,
u16 flex_byte);
extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input,
u8 l4type);
+extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring);
+extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring);
extern void ixgbe_set_rx_mode(struct net_device *netdev);
#ifdef IXGBE_FCOE
extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 9c02d6014cc4..d0f1d9d2c416 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -38,9 +38,6 @@
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
-static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
@@ -156,7 +153,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_82598;
+ &ixgbe_get_copper_link_capabilities_generic;
}
switch (hw->phy.type) {
@@ -274,37 +271,6 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
}
/**
- * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg)
-{
- s32 status = IXGBE_ERR_LINK_SETUP;
- u16 speed_ability;
-
- *speed = 0;
- *autoneg = true;
-
- status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
- &speed_ability);
-
- if (status == 0) {
- if (speed_ability & MDIO_SPEED_10G)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & MDIO_PMA_SPEED_1000)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- }
-
- return status;
-}
-
-/**
* ixgbe_get_media_type_82598 - Determines media type
* @hw: pointer to hardware structure
*
@@ -357,6 +323,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
u32 fctrl_reg;
u32 rmcs_reg;
u32 reg;
+ u32 rx_pba_size;
u32 link_speed = 0;
bool link_up;
@@ -459,16 +426,18 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
/* Set up and enable Rx high/low water mark thresholds, enable XON. */
if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
- if (hw->fc.send_xon) {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- (hw->fc.low_water | IXGBE_FCRTL_XONE));
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- hw->fc.low_water);
- }
+ rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+ rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+
+ reg = (rx_pba_size - hw->fc.low_water) << 6;
+ if (hw->fc.send_xon)
+ reg |= IXGBE_FCRTL_XONE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);
+
+ reg = (rx_pba_size - hw->fc.high_water) << 10;
+ reg |= IXGBE_FCRTH_FCEN;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
- (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
}
/* Configure pause time (2 TCs per register) */
@@ -1222,6 +1191,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic,
+ .calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
};
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 0bd8fbb5bfd0..bfd3c227cd4a 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -56,9 +56,6 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete);
-static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg);
static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
@@ -68,9 +65,9 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
- if (hw->phy.multispeed_fiber) {
- /* Set up dual speed SFP+ support */
- mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+
+ /* enable the laser control functions for SFP+ fiber */
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
mac->ops.disable_tx_laser =
&ixgbe_disable_tx_laser_multispeed_fiber;
mac->ops.enable_tx_laser =
@@ -80,6 +77,12 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
mac->ops.disable_tx_laser = NULL;
mac->ops.enable_tx_laser = NULL;
mac->ops.flap_tx_laser = NULL;
+ }
+
+ if (hw->phy.multispeed_fiber) {
+ /* Set up dual speed SFP+ support */
+ mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+ } else {
if ((mac->ops.get_media_type(hw) ==
ixgbe_media_type_backplane) &&
(hw->phy.smart_speed == ixgbe_smart_speed_auto ||
@@ -93,6 +96,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
{
s32 ret_val = 0;
+ u32 reg_anlp1 = 0;
+ u32 i = 0;
u16 list_offset, data_offset, data_value;
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
@@ -119,14 +124,34 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
IXGBE_WRITE_FLUSH(hw);
hw->eeprom.ops.read(hw, ++data_offset, &data_value);
}
- /* Now restart DSP by setting Restart_AN */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
- (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART));
/* Release the semaphore */
ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
/* Delay obtaining semaphore again to allow FW access */
msleep(hw->eeprom.semaphore_delay);
+
+ /* Now restart DSP by setting Restart_AN and clearing LMS */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
+ IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
+ IXGBE_AUTOC_AN_RESTART));
+
+ /* Wait for AN to leave state 0 */
+ for (i = 0; i < 10; i++) {
+ msleep(4);
+ reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+ if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
+ break;
+ }
+ if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
+ hw_dbg(hw, "sfp module setup not complete\n");
+ ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
+ goto setup_sfp_out;
+ }
+
+ /* Restart DSP by setting Restart_AN and return to SFI mode */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
+ IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
+ IXGBE_AUTOC_AN_RESTART));
}
setup_sfp_out:
@@ -174,7 +199,7 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_82599;
+ &ixgbe_get_copper_link_capabilities_generic;
}
/* Set necessary function pointers based on phy type */
@@ -184,6 +209,10 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
phy->ops.get_firmware_version =
&ixgbe_get_phy_firmware_version_tnx;
break;
+ case ixgbe_phy_aq:
+ phy->ops.get_firmware_version =
+ &ixgbe_get_phy_firmware_version_generic;
+ break;
default:
break;
}
@@ -290,37 +319,6 @@ out:
}
/**
- * ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg)
-{
- s32 status = IXGBE_ERR_LINK_SETUP;
- u16 speed_ability;
-
- *speed = 0;
- *autoneg = true;
-
- status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
- &speed_ability);
-
- if (status == 0) {
- if (speed_ability & MDIO_SPEED_10G)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & MDIO_PMA_SPEED_1000)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- }
-
- return status;
-}
-
-/**
* ixgbe_get_media_type_82599 - Get media type
* @hw: pointer to hardware structure
*
@@ -332,7 +330,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
/* Detect if there is a copper PHY attached. */
if (hw->phy.type == ixgbe_phy_cu_unknown ||
- hw->phy.type == ixgbe_phy_tn) {
+ hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_aq) {
media_type = ixgbe_media_type_copper;
goto out;
}
@@ -342,11 +341,13 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_KX4_MEZZ:
case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
case IXGBE_DEV_ID_82599_KR:
+ case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
case IXGBE_DEV_ID_82599_XAUI_LOM:
/* Default device ID is mezzanine card KX/KX4 */
media_type = ixgbe_media_type_backplane;
break;
case IXGBE_DEV_ID_82599_SFP:
+ case IXGBE_DEV_ID_82599_SFP_FCOE:
case IXGBE_DEV_ID_82599_SFP_EM:
media_type = ixgbe_media_type_fiber;
break;
@@ -1924,6 +1925,7 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
hw->phy.ops.identify(hw);
if (hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_aq ||
hw->phy.type == ixgbe_phy_cu_unknown) {
hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
&ext_ability);
@@ -2125,51 +2127,6 @@ fw_version_out:
return status;
}
-/**
- * ixgbe_get_wwn_prefix_82599 - Get alternative WWNN/WWPN prefix from
- * the EEPROM
- * @hw: pointer to hardware structure
- * @wwnn_prefix: the alternative WWNN prefix
- * @wwpn_prefix: the alternative WWPN prefix
- *
- * This function will read the EEPROM from the alternative SAN MAC address
- * block to check the support for the alternative WWNN/WWPN prefix support.
- **/
-static s32 ixgbe_get_wwn_prefix_82599(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix)
-{
- u16 offset, caps;
- u16 alt_san_mac_blk_offset;
-
- /* clear output first */
- *wwnn_prefix = 0xFFFF;
- *wwpn_prefix = 0xFFFF;
-
- /* check if alternative SAN MAC is supported */
- hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
- &alt_san_mac_blk_offset);
-
- if ((alt_san_mac_blk_offset == 0) ||
- (alt_san_mac_blk_offset == 0xFFFF))
- goto wwn_prefix_out;
-
- /* check capability in alternative san mac address block */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
- hw->eeprom.ops.read(hw, offset, &caps);
- if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
- goto wwn_prefix_out;
-
- /* get the corresponding prefix for WWNN/WWPN */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwnn_prefix);
-
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwpn_prefix);
-
-wwn_prefix_out:
- return 0;
-}
-
static struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599,
@@ -2181,7 +2138,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
.get_device_caps = &ixgbe_get_device_caps_82599,
- .get_wwn_prefix = &ixgbe_get_wwn_prefix_82599,
+ .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
@@ -2208,12 +2165,15 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.fc_enable = &ixgbe_fc_enable_generic,
.init_uta_tables = &ixgbe_init_uta_tables_generic,
.setup_sfp = &ixgbe_setup_sfp_modules_82599,
+ .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing,
+ .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
};
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic,
.write = &ixgbe_write_eeprom_generic,
+ .calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
};
@@ -2240,5 +2200,5 @@ struct ixgbe_info ixgbe_82599_info = {
.mac_ops = &mac_ops_82599,
.eeprom_ops = &eeprom_ops_82599,
.phy_ops = &phy_ops_82599,
- .mbx_ops = &mbx_ops_82599,
+ .mbx_ops = &mbx_ops_generic,
};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index e3eca1316389..d5ede2df3e42 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -45,14 +45,12 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
-static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
-static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -198,30 +196,110 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_read_pba_num_generic - Reads part number from EEPROM
+ * ixgbe_read_pba_string_generic - Reads part number string from EEPROM
* @hw: pointer to hardware structure
- * @pba_num: stores the part number from the EEPROM
+ * @pba_num: stores the part number string from the EEPROM
+ * @pba_num_size: part number string buffer length
*
- * Reads the part number from the EEPROM.
+ * Reads the part number string from the EEPROM.
**/
-s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
+s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
+ u32 pba_num_size)
{
s32 ret_val;
u16 data;
+ u16 pba_ptr;
+ u16 offset;
+ u16 length;
+
+ if (pba_num == NULL) {
+ hw_dbg(hw, "PBA string buffer was null\n");
+ return IXGBE_ERR_INVALID_ARGUMENT;
+ }
ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
return ret_val;
}
- *pba_num = (u32)(data << 16);
- ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
+ ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
return ret_val;
}
- *pba_num |= data;
+
+ /*
+ * if data is not ptr guard the PBA must be in legacy format which
+ * means pba_ptr is actually our second data word for the PBA number
+ * and we can decode it into an ascii string
+ */
+ if (data != IXGBE_PBANUM_PTR_GUARD) {
+ hw_dbg(hw, "NVM PBA number is not stored as string\n");
+
+ /* we will need 11 characters to store the PBA */
+ if (pba_num_size < 11) {
+ hw_dbg(hw, "PBA string buffer too small\n");
+ return IXGBE_ERR_NO_SPACE;
+ }
+
+ /* extract hex string from data and pba_ptr */
+ pba_num[0] = (data >> 12) & 0xF;
+ pba_num[1] = (data >> 8) & 0xF;
+ pba_num[2] = (data >> 4) & 0xF;
+ pba_num[3] = data & 0xF;
+ pba_num[4] = (pba_ptr >> 12) & 0xF;
+ pba_num[5] = (pba_ptr >> 8) & 0xF;
+ pba_num[6] = '-';
+ pba_num[7] = 0;
+ pba_num[8] = (pba_ptr >> 4) & 0xF;
+ pba_num[9] = pba_ptr & 0xF;
+
+ /* put a null character on the end of our string */
+ pba_num[10] = '\0';
+
+ /* switch all the data but the '-' to hex char */
+ for (offset = 0; offset < 10; offset++) {
+ if (pba_num[offset] < 0xA)
+ pba_num[offset] += '0';
+ else if (pba_num[offset] < 0x10)
+ pba_num[offset] += 'A' - 0xA;
+ }
+
+ return 0;
+ }
+
+ ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+
+ if (length == 0xFFFF || length == 0) {
+ hw_dbg(hw, "NVM PBA number section invalid length\n");
+ return IXGBE_ERR_PBA_SECTION;
+ }
+
+ /* check if pba_num buffer is big enough */
+ if (pba_num_size < (((u32)length * 2) - 1)) {
+ hw_dbg(hw, "PBA string buffer too small\n");
+ return IXGBE_ERR_NO_SPACE;
+ }
+
+ /* trim pba length from start of string */
+ pba_ptr++;
+ length--;
+
+ for (offset = 0; offset < length; offset++) {
+ ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ pba_num[offset * 2] = (u8)(data >> 8);
+ pba_num[(offset * 2) + 1] = (u8)(data & 0xFF);
+ }
+ pba_num[offset * 2] = '\0';
return 0;
}
@@ -638,7 +716,7 @@ out:
* Polls the status bit (bit 1) of the EERD or EEWR to determine when the
* read or write is done respectively.
**/
-static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
+s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
{
u32 i;
u32 reg;
@@ -1009,7 +1087,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
* ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
* @hw: pointer to hardware structure
**/
-static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
+u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
{
u16 i;
u16 j;
@@ -1072,7 +1150,7 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status == 0) {
- checksum = ixgbe_calc_eeprom_checksum(hw);
+ checksum = hw->eeprom.ops.calc_checksum(hw);
hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
@@ -1110,7 +1188,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status == 0) {
- checksum = ixgbe_calc_eeprom_checksum(hw);
+ checksum = hw->eeprom.ops.calc_checksum(hw);
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
checksum);
} else {
@@ -1595,6 +1673,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
u32 mflcn_reg, fccfg_reg;
u32 reg;
u32 rx_pba_size;
+ u32 fcrtl, fcrth;
#ifdef CONFIG_DCB
if (hw->fc.requested_mode == ixgbe_fc_pfc)
@@ -1671,41 +1750,21 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
- reg = IXGBE_READ_REG(hw, IXGBE_MTQC);
- /* Thresholds are different for link flow control when in DCB mode */
- if (reg & IXGBE_MTQC_RT_ENA) {
- rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+ rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+ rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
- /* Always disable XON for LFC when in DCB mode */
- reg = (rx_pba_size >> 5) & 0xFFE0;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg);
+ fcrth = (rx_pba_size - hw->fc.high_water) << 10;
+ fcrtl = (rx_pba_size - hw->fc.low_water) << 10;
- reg = (rx_pba_size >> 2) & 0xFFE0;
- if (hw->fc.current_mode & ixgbe_fc_tx_pause)
- reg |= IXGBE_FCRTH_FCEN;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg);
- } else {
- /*
- * Set up and enable Rx high/low water mark thresholds,
- * enable XON.
- */
- if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
- if (hw->fc.send_xon) {
- IXGBE_WRITE_REG(hw,
- IXGBE_FCRTL_82599(packetbuf_num),
- (hw->fc.low_water |
- IXGBE_FCRTL_XONE));
- } else {
- IXGBE_WRITE_REG(hw,
- IXGBE_FCRTL_82599(packetbuf_num),
- hw->fc.low_water);
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
- (hw->fc.high_water | IXGBE_FCRTH_FCEN));
- }
+ if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+ fcrth |= IXGBE_FCRTH_FCEN;
+ if (hw->fc.send_xon)
+ fcrtl |= IXGBE_FCRTL_XONE;
}
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl);
+
/* Configure pause time (2 TCs per register) */
reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
if ((packetbuf_num & 1) == 0)
@@ -2705,3 +2764,112 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
return 0;
}
+
+/**
+ * ixgbe_get_wwn_prefix_generic Get alternative WWNN/WWPN prefix from
+ * the EEPROM
+ * @hw: pointer to hardware structure
+ * @wwnn_prefix: the alternative WWNN prefix
+ * @wwpn_prefix: the alternative WWPN prefix
+ *
+ * This function will read the EEPROM from the alternative SAN MAC address
+ * block to check the support for the alternative WWNN/WWPN prefix support.
+ **/
+s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
+ u16 *wwpn_prefix)
+{
+ u16 offset, caps;
+ u16 alt_san_mac_blk_offset;
+
+ /* clear output first */
+ *wwnn_prefix = 0xFFFF;
+ *wwpn_prefix = 0xFFFF;
+
+ /* check if alternative SAN MAC is supported */
+ hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
+ &alt_san_mac_blk_offset);
+
+ if ((alt_san_mac_blk_offset == 0) ||
+ (alt_san_mac_blk_offset == 0xFFFF))
+ goto wwn_prefix_out;
+
+ /* check capability in alternative san mac address block */
+ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
+ hw->eeprom.ops.read(hw, offset, &caps);
+ if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
+ goto wwn_prefix_out;
+
+ /* get the corresponding prefix for WWNN/WWPN */
+ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
+ hw->eeprom.ops.read(hw, offset, wwnn_prefix);
+
+ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
+ hw->eeprom.ops.read(hw, offset, wwpn_prefix);
+
+wwn_prefix_out:
+ return 0;
+}
+
+/**
+ * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable switch for anti-spoofing
+ * @pf: Physical Function pool - do not enable anti-spoofing for the PF
+ *
+ **/
+void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf)
+{
+ int j;
+ int pf_target_reg = pf >> 3;
+ int pf_target_shift = pf % 8;
+ u32 pfvfspoof = 0;
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ if (enable)
+ pfvfspoof = IXGBE_SPOOF_MACAS_MASK;
+
+ /*
+ * PFVFSPOOF register array is size 8 with 8 bits assigned to
+ * MAC anti-spoof enables in each register array element.
+ */
+ for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++)
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof);
+
+ /* If not enabling anti-spoofing then done */
+ if (!enable)
+ return;
+
+ /*
+ * The PF should be allowed to spoof so that it can support
+ * emulation mode NICs. Reset the bit assigned to the PF
+ */
+ pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg));
+ pfvfspoof ^= (1 << pf_target_shift);
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof);
+}
+
+/**
+ * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable switch for VLAN anti-spoofing
+ * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
+ *
+ **/
+void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
+{
+ int vf_target_reg = vf >> 3;
+ int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT;
+ u32 pfvfspoof;
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
+ if (enable)
+ pfvfspoof |= (1 << vf_target_shift);
+ else
+ pfvfspoof &= ~(1 << vf_target_shift);
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 424c223437dc..66ed045a8cf0 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -35,7 +35,8 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
-s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
+s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
+ u32 pba_num_size);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
@@ -49,9 +50,11 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
+u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
u16 *checksum_val);
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
+s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
@@ -81,9 +84,12 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
bool *link_up, bool link_up_wait_to_complete);
-
+s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
+ u16 *wwpn_prefix);
s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
+void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf);
+void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index 0d44c6470ca3..d16c260c1f50 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -42,7 +42,8 @@
* It should be called only after the rules are checked by
* ixgbe_dcb_check_config().
*/
-s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
+s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config,
int max_frame, u8 direction)
{
struct tc_bw_alloc *p;
@@ -124,7 +125,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
* credit may not be enough to send out a TSO
* packet in descriptor plane arbitration.
*/
- if (credit_max &&
+ if ((hw->mac.type == ixgbe_mac_82598EB) &&
+ credit_max &&
(credit_max < MINIMUM_CREDIT_FOR_TSO))
credit_max = MINIMUM_CREDIT_FOR_TSO;
@@ -150,10 +152,17 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
- else if (hw->mac.type == ixgbe_mac_82599EB)
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
ret = ixgbe_dcb_hw_config_82599(hw, dcb_config);
+ break;
+ default:
+ break;
+ }
return ret;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h
index 0208a87b129e..1cfe38ee1644 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.h
+++ b/drivers/net/ixgbe/ixgbe_dcb.h
@@ -150,7 +150,8 @@ struct ixgbe_dcb_config {
/* DCB driver APIs */
/* DCB credits calculation */
-s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8);
+s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *,
+ struct ixgbe_dcb_config *, int, u8);
/* DCB hw initialization */
s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 50288bcadc59..9a5e89c12e05 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -256,21 +256,17 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
* for each traffic class.
*/
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
- if (dcb_config->rx_pba_cfg == pba_equal) {
- rx_pba_size = IXGBE_RXPBSIZE_64KB;
- } else {
- rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
- : IXGBE_RXPBSIZE_48KB;
- }
+ rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
+ rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+ reg = (rx_pba_size - hw->fc.low_water) << 10;
- reg = ((rx_pba_size >> 5) & 0xFFF0);
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
reg |= IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
- reg = ((rx_pba_size >> 2) & 0xFFF0);
+ reg = (rx_pba_size - hw->fc.high_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
reg |= IXGBE_FCRTH_FCEN;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 05f224715073..374e1f74d0f5 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -251,19 +251,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
/* Configure PFC Tx thresholds per TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
- if (dcb_config->rx_pba_cfg == pba_equal)
- rx_pba_size = IXGBE_RXPBSIZE_64KB;
- else
- rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
- : IXGBE_RXPBSIZE_48KB;
+ rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
+ rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+
+ reg = (rx_pba_size - hw->fc.low_water) << 10;
- reg = ((rx_pba_size >> 5) & 0xFFE0);
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
reg |= IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
- reg = ((rx_pba_size >> 2) & 0xFFE0);
+ reg = (rx_pba_size - hw->fc.high_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
reg |= IXGBE_FCRTH_FCEN;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index b53b465e24af..bf566e8a455e 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -130,15 +130,21 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
adapter->last_lfc_mode = adapter->hw.fc.current_mode;
adapter->hw.fc.requested_mode = ixgbe_fc_none;
- }
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+ break;
+ default:
+ break;
}
+
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
@@ -155,8 +161,14 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
adapter->dcb_cfg.pfc_mode_enable = false;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ break;
+ default:
+ break;
+ }
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
@@ -178,9 +190,14 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
for (i = 0; i < netdev->addr_len; i++)
perm_addr[i] = adapter->hw.mac.perm_addr[i];
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
for (j = 0; j < netdev->addr_len; j++, i++)
perm_addr[i] = adapter->hw.mac.san_addr[j];
+ break;
+ default:
+ break;
}
}
@@ -366,15 +383,29 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
}
if (adapter->dcb_cfg.pfc_mode_enable) {
- if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
- (adapter->hw.fc.current_mode != ixgbe_fc_pfc))
- adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ if (adapter->hw.fc.current_mode != ixgbe_fc_pfc)
+ adapter->last_lfc_mode =
+ adapter->hw.fc.current_mode;
+ break;
+ default:
+ break;
+ }
adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
} else {
- if (adapter->hw.mac.type != ixgbe_mac_82598EB)
- adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
- else
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
adapter->hw.fc.requested_mode = ixgbe_fc_none;
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ break;
+ default:
+ break;
+ }
}
if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 3dc731c22ff2..23ff23e8b393 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -185,6 +185,16 @@ static int ixgbe_get_settings(struct net_device *netdev,
ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
ecmd->autoneg = AUTONEG_DISABLE;
+ } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE) ||
+ (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) {
+ ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE);
+ ecmd->advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_Autoneg |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
} else {
ecmd->supported |= (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE);
@@ -204,6 +214,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
/* Get PHY type */
switch (adapter->hw.phy.type) {
case ixgbe_phy_tn:
+ case ixgbe_phy_aq:
case ixgbe_phy_cu_unknown:
/* Copper 10G-BASET */
ecmd->port = PORT_TP;
@@ -332,13 +343,6 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
else
pause->autoneg = 1;
-#ifdef CONFIG_DCB
- if (hw->fc.current_mode == ixgbe_fc_pfc) {
- pause->rx_pause = 0;
- pause->tx_pause = 0;
- }
-
-#endif
if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
pause->rx_pause = 1;
} else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
@@ -346,6 +350,11 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
} else if (hw->fc.current_mode == ixgbe_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
+#ifdef CONFIG_DCB
+ } else if (hw->fc.current_mode == ixgbe_fc_pfc) {
+ pause->rx_pause = 0;
+ pause->tx_pause = 0;
+#endif
}
}
@@ -363,7 +372,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
return -EINVAL;
#endif
-
fc = hw->fc;
if (pause->autoneg != AUTONEG_ENABLE)
@@ -412,11 +420,6 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
else
adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
- else
- ixgbe_reset(adapter);
-
return 0;
}
@@ -428,16 +431,21 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev)
static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ u32 feature_list;
- if (data) {
- netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
- netdev->features |= NETIF_F_SCTP_CSUM;
- } else {
- netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
- netdev->features &= ~NETIF_F_SCTP_CSUM;
+ feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ feature_list |= NETIF_F_SCTP_CSUM;
+ break;
+ default:
+ break;
}
+ if (data)
+ netdev->features |= feature_list;
+ else
+ netdev->features &= ~feature_list;
return 0;
}
@@ -530,10 +538,20 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[32] = IXGBE_READ_REG(hw, IXGBE_FCTTV(1));
regs_buff[33] = IXGBE_READ_REG(hw, IXGBE_FCTTV(2));
regs_buff[34] = IXGBE_READ_REG(hw, IXGBE_FCTTV(3));
- for (i = 0; i < 8; i++)
- regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i));
- for (i = 0; i < 8; i++)
- regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i));
+ for (i = 0; i < 8; i++) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i));
+ regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i));
+ break;
+ case ixgbe_mac_82599EB:
+ regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i));
+ regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i));
+ break;
+ default:
+ break;
+ }
+ }
regs_buff[51] = IXGBE_READ_REG(hw, IXGBE_FCRTV);
regs_buff[52] = IXGBE_READ_REG(hw, IXGBE_TFCS);
@@ -615,6 +633,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
+ /* DCB */
regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
@@ -820,9 +839,10 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
char firmware_version[32];
- strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
+ strncpy(drvinfo->driver, ixgbe_driver_name,
+ sizeof(drvinfo->driver) - 1);
strncpy(drvinfo->version, ixgbe_driver_version,
- sizeof(drvinfo->version));
+ sizeof(drvinfo->version) - 1);
snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d",
(adapter->eeprom_version & 0xF000) >> 12,
@@ -905,13 +925,11 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
memcpy(&temp_tx_ring[i], adapter->tx_ring[i],
sizeof(struct ixgbe_ring));
temp_tx_ring[i].count = new_tx_count;
- err = ixgbe_setup_tx_resources(adapter,
- &temp_tx_ring[i]);
+ err = ixgbe_setup_tx_resources(&temp_tx_ring[i]);
if (err) {
while (i) {
i--;
- ixgbe_free_tx_resources(adapter,
- &temp_tx_ring[i]);
+ ixgbe_free_tx_resources(&temp_tx_ring[i]);
}
goto clear_reset;
}
@@ -930,13 +948,11 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
memcpy(&temp_rx_ring[i], adapter->rx_ring[i],
sizeof(struct ixgbe_ring));
temp_rx_ring[i].count = new_rx_count;
- err = ixgbe_setup_rx_resources(adapter,
- &temp_rx_ring[i]);
+ err = ixgbe_setup_rx_resources(&temp_rx_ring[i]);
if (err) {
while (i) {
i--;
- ixgbe_free_rx_resources(adapter,
- &temp_rx_ring[i]);
+ ixgbe_free_rx_resources(&temp_rx_ring[i]);
}
goto err_setup;
}
@@ -951,8 +967,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
/* tx */
if (new_tx_count != adapter->tx_ring_count) {
for (i = 0; i < adapter->num_tx_queues; i++) {
- ixgbe_free_tx_resources(adapter,
- adapter->tx_ring[i]);
+ ixgbe_free_tx_resources(adapter->tx_ring[i]);
memcpy(adapter->tx_ring[i], &temp_tx_ring[i],
sizeof(struct ixgbe_ring));
}
@@ -962,8 +977,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
/* rx */
if (new_rx_count != adapter->rx_ring_count) {
for (i = 0; i < adapter->num_rx_queues; i++) {
- ixgbe_free_rx_resources(adapter,
- adapter->rx_ring[i]);
+ ixgbe_free_rx_resources(adapter->rx_ring[i]);
memcpy(adapter->rx_ring[i], &temp_rx_ring[i],
sizeof(struct ixgbe_ring));
}
@@ -1144,7 +1158,7 @@ struct ixgbe_reg_test {
#define TABLE64_TEST_HI 6
/* default 82599 register test */
-static struct ixgbe_reg_test reg_test_82599[] = {
+static const struct ixgbe_reg_test reg_test_82599[] = {
{ IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
{ IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
{ IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -1168,7 +1182,7 @@ static struct ixgbe_reg_test reg_test_82599[] = {
};
/* default 82598 register test */
-static struct ixgbe_reg_test reg_test_82598[] = {
+static const struct ixgbe_reg_test reg_test_82598[] = {
{ IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
{ IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
{ IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -1195,18 +1209,22 @@ static struct ixgbe_reg_test reg_test_82598[] = {
{ 0, 0, 0, 0 }
};
+static const u32 register_test_patterns[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
+};
+
#define REG_PATTERN_TEST(R, M, W) \
{ \
u32 pat, val, before; \
- const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
- for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \
+ for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \
before = readl(adapter->hw.hw_addr + R); \
- writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \
+ writel((register_test_patterns[pat] & W), \
+ (adapter->hw.hw_addr + R)); \
val = readl(adapter->hw.hw_addr + R); \
- if (val != (_test[pat] & W & M)) { \
- e_err(drv, "pattern test reg %04X failed: got " \
- "0x%08X expected 0x%08X\n", \
- R, val, (_test[pat] & W & M)); \
+ if (val != (register_test_patterns[pat] & W & M)) { \
+ e_err(drv, "pattern test reg %04X failed: got " \
+ "0x%08X expected 0x%08X\n", \
+ R, val, (register_test_patterns[pat] & W & M)); \
*data = R; \
writel(before, adapter->hw.hw_addr + R); \
return 1; \
@@ -1233,16 +1251,24 @@ static struct ixgbe_reg_test reg_test_82598[] = {
static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
{
- struct ixgbe_reg_test *test;
+ const struct ixgbe_reg_test *test;
u32 value, before, after;
u32 i, toggle;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- toggle = 0x7FFFF30F;
- test = reg_test_82599;
- } else {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
toggle = 0x7FFFF3FF;
test = reg_test_82598;
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ toggle = 0x7FFFF30F;
+ test = reg_test_82599;
+ break;
+ default:
+ *data = 1;
+ return 1;
+ break;
}
/*
@@ -1460,16 +1486,21 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl);
- if (hw->mac.type == ixgbe_mac_82599EB) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_ctl &= ~IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
+ break;
+ default:
+ break;
}
ixgbe_reset(adapter);
- ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring);
- ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring);
+ ixgbe_free_tx_resources(&adapter->test_tx_ring);
+ ixgbe_free_rx_resources(&adapter->test_rx_ring);
}
static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
@@ -1483,17 +1514,24 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
/* Setup Tx descriptor ring and Tx buffers */
tx_ring->count = IXGBE_DEFAULT_TXD;
tx_ring->queue_index = 0;
+ tx_ring->dev = &adapter->pdev->dev;
+ tx_ring->netdev = adapter->netdev;
tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx;
tx_ring->numa_node = adapter->node;
- err = ixgbe_setup_tx_resources(adapter, tx_ring);
+ err = ixgbe_setup_tx_resources(tx_ring);
if (err)
return 1;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
reg_data |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
+ break;
+ default:
+ break;
}
ixgbe_configure_tx_ring(adapter, tx_ring);
@@ -1501,11 +1539,13 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
/* Setup Rx Descriptor ring and Rx buffers */
rx_ring->count = IXGBE_DEFAULT_RXD;
rx_ring->queue_index = 0;
+ rx_ring->dev = &adapter->pdev->dev;
+ rx_ring->netdev = adapter->netdev;
rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx;
rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048;
rx_ring->numa_node = adapter->node;
- err = ixgbe_setup_rx_resources(adapter, rx_ring);
+ err = ixgbe_setup_rx_resources(rx_ring);
if (err) {
ret_val = 4;
goto err_nomem;
@@ -1604,8 +1644,7 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb,
return 13;
}
-static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
+static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring,
struct ixgbe_ring *tx_ring,
unsigned int size)
{
@@ -1627,7 +1666,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc];
/* unmap Rx buffer, will be remapped by alloc_rx_buffers */
- dma_unmap_single(&adapter->pdev->dev,
+ dma_unmap_single(rx_ring->dev,
rx_buffer_info->dma,
bufsz,
DMA_FROM_DEVICE);
@@ -1639,7 +1678,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
/* unmap buffer on Tx side */
tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc];
- ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+ ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
/* increment Rx/Tx next to clean counters */
rx_ntc++;
@@ -1655,7 +1694,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
}
/* re-map buffers to ring, store next to clean values */
- ixgbe_alloc_rx_buffers(adapter, rx_ring, count);
+ ixgbe_alloc_rx_buffers(rx_ring, count);
rx_ring->next_to_clean = rx_ntc;
tx_ring->next_to_clean = tx_ntc;
@@ -1699,7 +1738,6 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
for (i = 0; i < 64; i++) {
skb_get(skb);
tx_ret_val = ixgbe_xmit_frame_ring(skb,
- adapter->netdev,
adapter,
tx_ring);
if (tx_ret_val == NETDEV_TX_OK)
@@ -1714,8 +1752,7 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
/* allow 200 milliseconds for packets to go from Tx to Rx */
msleep(200);
- good_cnt = ixgbe_clean_test_rings(adapter, rx_ring,
- tx_ring, size);
+ good_cnt = ixgbe_clean_test_rings(rx_ring, tx_ring, size);
if (good_cnt != 64) {
ret_val = 13;
break;
@@ -1847,7 +1884,25 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
struct ixgbe_hw *hw = &adapter->hw;
int retval = 1;
+ /* WOL not supported except for the following */
switch(hw->device_id) {
+ case IXGBE_DEV_ID_82599_SFP:
+ /* Only this subdevice supports WOL */
+ if (hw->subsystem_device_id != IXGBE_SUBDEV_ID_82599_SFP) {
+ wol->supported = 0;
+ break;
+ }
+ retval = 0;
+ break;
+ case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+ /* All except this subdevice support WOL */
+ if (hw->subsystem_device_id ==
+ IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) {
+ wol->supported = 0;
+ break;
+ }
+ retval = 0;
+ break;
case IXGBE_DEV_ID_82599_KX4:
retval = 0;
break;
@@ -1985,6 +2040,41 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
return 0;
}
+/*
+ * this function must be called before setting the new value of
+ * rx_itr_setting
+ */
+static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter,
+ struct ethtool_coalesce *ec)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE))
+ return false;
+
+ /* if interrupt rate is too high then disable RSC */
+ if (ec->rx_coalesce_usecs != 1 &&
+ ec->rx_coalesce_usecs <= 1000000/IXGBE_MAX_RSC_INT_RATE) {
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
+ e_info(probe, "rx-usecs set too low, "
+ "disabling RSC\n");
+ adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
+ return true;
+ }
+ } else {
+ /* check the feature flag value and enable RSC if necessary */
+ if ((netdev->features & NETIF_F_LRO) &&
+ !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
+ e_info(probe, "rx-usecs set to %d, "
+ "re-enabling RSC\n",
+ ec->rx_coalesce_usecs);
+ adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
+ return true;
+ }
+ }
+ return false;
+}
+
static int ixgbe_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
@@ -2002,17 +2092,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq;
if (ec->rx_coalesce_usecs > 1) {
- u32 max_int;
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
- max_int = IXGBE_MAX_RSC_INT_RATE;
- else
- max_int = IXGBE_MAX_INT_RATE;
-
/* check the limits */
- if ((1000000/ec->rx_coalesce_usecs > max_int) ||
+ if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
(1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
return -EINVAL;
+ /* check the old value and enable RSC if necessary */
+ need_reset = ixgbe_update_rsc(adapter, ec);
+
/* store the value in ints/second */
adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;
@@ -2021,32 +2108,21 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
/* clear the lower bit as its used for dynamic state */
adapter->rx_itr_setting &= ~1;
} else if (ec->rx_coalesce_usecs == 1) {
+ /* check the old value and enable RSC if necessary */
+ need_reset = ixgbe_update_rsc(adapter, ec);
+
/* 1 means dynamic mode */
adapter->rx_eitr_param = 20000;
adapter->rx_itr_setting = 1;
} else {
+ /* check the old value and enable RSC if necessary */
+ need_reset = ixgbe_update_rsc(adapter, ec);
/*
* any other value means disable eitr, which is best
* served by setting the interrupt rate very high
*/
adapter->rx_eitr_param = IXGBE_MAX_INT_RATE;
adapter->rx_itr_setting = 0;
-
- /*
- * if hardware RSC is enabled, disable it when
- * setting low latency mode, to avoid errata, assuming
- * that when the user set low latency mode they want
- * it at the cost of anything else
- */
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
- if (netdev->features & NETIF_F_LRO) {
- netdev->features &= ~NETIF_F_LRO;
- e_info(probe, "rx-usecs set to 0, "
- "disabling RSC\n");
- }
- need_reset = true;
- }
}
if (ec->tx_coalesce_usecs > 1) {
@@ -2127,34 +2203,45 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
need_reset = (data & ETH_FLAG_RXVLAN) !=
(netdev->features & NETIF_F_HW_VLAN_RX);
- rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO |
+ rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
if (rc)
return rc;
/* if state changes we need to update adapter->flags and reset */
- if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
- /*
- * cast both to bool and verify if they are set the same
- * but only enable RSC if itr is non-zero, as
- * itr=0 and RSC are mutually exclusive
- */
- if (((!!(data & ETH_FLAG_LRO)) !=
- (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) &&
- adapter->rx_itr_setting) {
+ if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
+ (!!(data & ETH_FLAG_LRO) !=
+ !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
+ if ((data & ETH_FLAG_LRO) &&
+ (!adapter->rx_itr_setting ||
+ (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) {
+ e_info(probe, "rx-usecs set too low, "
+ "not enabling RSC.\n");
+ } else {
adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
need_reset = true;
break;
+ case ixgbe_mac_X540: {
+ int i;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct ixgbe_ring *ring =
+ adapter->rx_ring[i];
+ if (adapter->flags2 &
+ IXGBE_FLAG2_RSC_ENABLED) {
+ ixgbe_configure_rscctl(adapter,
+ ring);
+ } else {
+ ixgbe_clear_rscctl(adapter,
+ ring);
+ }
+ }
+ }
+ break;
default:
break;
}
- } else if (!adapter->rx_itr_setting) {
- netdev->features &= ~NETIF_F_LRO;
- if (data & ETH_FLAG_LRO)
- e_info(probe, "rx-usecs set to 0, "
- "LRO/RSC cannot be enabled.\n");
}
}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 05efa6a8ce8e..6342d4859790 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -68,7 +68,7 @@ static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc)
static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp)
{
ddp->len = 0;
- ddp->err = 0;
+ ddp->err = 1;
ddp->udl = NULL;
ddp->udp = 0UL;
ddp->sgl = NULL;
@@ -92,6 +92,7 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
struct ixgbe_fcoe *fcoe;
struct ixgbe_adapter *adapter;
struct ixgbe_fcoe_ddp *ddp;
+ u32 fcbuff;
if (!netdev)
goto out_ddp_put;
@@ -115,7 +116,14 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW,
(xid | IXGBE_FCDMARW_WE));
+
+ /* guaranteed to be invalidated after 100us */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW,
+ (xid | IXGBE_FCDMARW_RE));
+ fcbuff = IXGBE_READ_REG(&adapter->hw, IXGBE_FCBUFF);
spin_unlock_bh(&fcoe->lock);
+ if (fcbuff & IXGBE_FCBUFF_VALID)
+ udelay(100);
}
if (ddp->sgl)
pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc,
@@ -168,6 +176,11 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
return 0;
}
+ /* no DDP if we are already down or resetting */
+ if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+ test_bit(__IXGBE_RESETTING, &adapter->state))
+ return 0;
+
fcoe = &adapter->fcoe;
if (!fcoe->pool) {
e_warn(drv, "xid=0x%x no ddp pool for fcoe\n", xid);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index fbad4d819608..38ab4f3f8197 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -52,13 +52,14 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "2.0.84-k2"
+#define DRV_VERSION "3.0.12-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
[board_82598] = &ixgbe_82598_info,
[board_82599] = &ixgbe_82599_info,
+ [board_X540] = &ixgbe_X540_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -108,10 +109,16 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE),
+ board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE),
+ board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM),
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE),
board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T),
+ board_X540 },
/* required last entry */
{0, }
@@ -560,6 +567,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
break;
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
if (direction == -1) {
/* other causes */
msix_vector |= IXGBE_IVAR_ALLOC_VAL;
@@ -589,29 +597,34 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
{
u32 mask;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
- } else {
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
mask = (qmask & 0xFFFFFFFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
mask = (qmask >> 32);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask);
+ break;
+ default:
+ break;
}
}
-void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
- struct ixgbe_tx_buffer
- *tx_buffer_info)
+void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
+ struct ixgbe_tx_buffer *tx_buffer_info)
{
if (tx_buffer_info->dma) {
if (tx_buffer_info->mapped_as_page)
- dma_unmap_page(&adapter->pdev->dev,
+ dma_unmap_page(tx_ring->dev,
tx_buffer_info->dma,
tx_buffer_info->length,
DMA_TO_DEVICE);
else
- dma_unmap_single(&adapter->pdev->dev,
+ dma_unmap_single(tx_ring->dev,
tx_buffer_info->dma,
tx_buffer_info->length,
DMA_TO_DEVICE);
@@ -626,92 +639,166 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
}
/**
- * ixgbe_tx_xon_state - check the tx ring xon state
- * @adapter: the ixgbe adapter
- * @tx_ring: the corresponding tx_ring
+ * ixgbe_dcb_txq_to_tc - convert a reg index to a traffic class
+ * @adapter: driver private struct
+ * @index: reg idx of queue to query (0-127)
*
- * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
- * corresponding TC of this tx_ring when checking TFCS.
+ * Helper function to determine the traffic index for a paticular
+ * register index.
*
- * Returns : true if in xon state (currently not paused)
+ * Returns : a tc index for use in range 0-7, or 0-3
*/
-static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
{
- u32 txoff = IXGBE_TFCS_TXOFF;
+ int tc = -1;
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
-#ifdef CONFIG_IXGBE_DCB
- if (adapter->dcb_cfg.pfc_mode_enable) {
- int tc;
- int reg_idx = tx_ring->reg_idx;
- int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+ /* if DCB is not enabled the queues have no TC */
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
+ return tc;
+
+ /* check valid range */
+ if (reg_idx >= adapter->hw.mac.max_tx_queues)
+ return tc;
+
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
+ tc = reg_idx >> 2;
+ break;
+ default:
+ if (dcb_i != 4 && dcb_i != 8)
+ break;
+
+ /* if VMDq is enabled the lowest order bits determine TC */
+ if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED |
+ IXGBE_FLAG_VMDQ_ENABLED)) {
+ tc = reg_idx & (dcb_i - 1);
+ break;
+ }
+
+ /*
+ * Convert the reg_idx into the correct TC. This bitmask
+ * targets the last full 32 ring traffic class and assigns
+ * it a value of 1. From there the rest of the rings are
+ * based on shifting the mask further up to include the
+ * reg_idx / 16 and then reg_idx / 8. It assumes dcB_i
+ * will only ever be 8 or 4 and that reg_idx will never
+ * be greater then 128. The code without the power of 2
+ * optimizations would be:
+ * (((reg_idx % 32) + 32) * dcb_i) >> (9 - reg_idx / 32)
+ */
+ tc = ((reg_idx & 0X1F) + 0x20) * dcb_i;
+ tc >>= 9 - (reg_idx >> 5);
+ }
+
+ return tc;
+}
+
+static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_hw_stats *hwstats = &adapter->stats;
+ u32 data = 0;
+ u32 xoff[8] = {0};
+ int i;
- switch (adapter->hw.mac.type) {
+ if ((hw->fc.current_mode == ixgbe_fc_full) ||
+ (hw->fc.current_mode == ixgbe_fc_rx_pause)) {
+ switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- tc = reg_idx >> 2;
- txoff = IXGBE_TFCS_TXOFF0;
+ data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
break;
- case ixgbe_mac_82599EB:
- tc = 0;
- txoff = IXGBE_TFCS_TXOFF;
- if (dcb_i == 8) {
- /* TC0, TC1 */
- tc = reg_idx >> 5;
- if (tc == 2) /* TC2, TC3 */
- tc += (reg_idx - 64) >> 4;
- else if (tc == 3) /* TC4, TC5, TC6, TC7 */
- tc += 1 + ((reg_idx - 96) >> 3);
- } else if (dcb_i == 4) {
- /* TC0, TC1 */
- tc = reg_idx >> 6;
- if (tc == 1) {
- tc += (reg_idx - 64) >> 5;
- if (tc == 2) /* TC2, TC3 */
- tc += (reg_idx - 96) >> 4;
- }
- }
+ default:
+ data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ }
+ hwstats->lxoffrxc += data;
+
+ /* refill credits (no tx hang) if we received xoff */
+ if (!data)
+ return;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ clear_bit(__IXGBE_HANG_CHECK_ARMED,
+ &adapter->tx_ring[i]->state);
+ return;
+ } else if (!(adapter->dcb_cfg.pfc_mode_enable))
+ return;
+
+ /* update stats for each tc, only valid with PFC enabled */
+ for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
break;
default:
- tc = 0;
+ xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
}
- txoff <<= tc;
+ hwstats->pxoffrxc[i] += xoff[i];
+ }
+
+ /* disarm tx queues that have received xoff frames */
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+ u32 tc = ixgbe_dcb_txq_to_tc(adapter, tx_ring->reg_idx);
+
+ if (xoff[tc])
+ clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state);
}
-#endif
- return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
}
-static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- unsigned int eop)
+static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring)
{
+ return ring->tx_stats.completed;
+}
+
+static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(ring->netdev);
struct ixgbe_hw *hw = &adapter->hw;
- /* Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of eop */
- adapter->detect_tx_hung = false;
- if (tx_ring->tx_buffer_info[eop].time_stamp &&
- time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
- ixgbe_tx_xon_state(adapter, tx_ring)) {
- /* detected Tx unit hang */
- union ixgbe_adv_tx_desc *tx_desc;
- tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
- e_err(drv, "Detected Tx Unit Hang\n"
- " Tx Queue <%d>\n"
- " TDH, TDT <%x>, <%x>\n"
- " next_to_use <%x>\n"
- " next_to_clean <%x>\n"
- "tx_buffer_info[next_to_clean]\n"
- " time_stamp <%lx>\n"
- " jiffies <%lx>\n",
- tx_ring->queue_index,
- IXGBE_READ_REG(hw, tx_ring->head),
- IXGBE_READ_REG(hw, tx_ring->tail),
- tx_ring->next_to_use, eop,
- tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
- return true;
+ u32 head = IXGBE_READ_REG(hw, IXGBE_TDH(ring->reg_idx));
+ u32 tail = IXGBE_READ_REG(hw, IXGBE_TDT(ring->reg_idx));
+
+ if (head != tail)
+ return (head < tail) ?
+ tail - head : (tail + ring->count - head);
+
+ return 0;
+}
+
+static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
+{
+ u32 tx_done = ixgbe_get_tx_completed(tx_ring);
+ u32 tx_done_old = tx_ring->tx_stats.tx_done_old;
+ u32 tx_pending = ixgbe_get_tx_pending(tx_ring);
+ bool ret = false;
+
+ clear_check_for_tx_hang(tx_ring);
+
+ /*
+ * Check for a hung queue, but be thorough. This verifies
+ * that a transmit has been completed since the previous
+ * check AND there is at least one packet pending. The
+ * ARMED bit is set to indicate a potential hang. The
+ * bit is cleared if a pause frame is received to remove
+ * false hang detection due to PFC or 802.3x frames. By
+ * requiring this to fail twice we avoid races with
+ * pfc clearing the ARMED bit and conditions where we
+ * run the check_tx_hang logic with a transmit completion
+ * pending but without time to complete it yet.
+ */
+ if ((tx_done_old == tx_done) && tx_pending) {
+ /* make sure it is true for two checks in a row */
+ ret = test_and_set_bit(__IXGBE_HANG_CHECK_ARMED,
+ &tx_ring->state);
+ } else {
+ /* update completed stats and continue */
+ tx_ring->tx_stats.tx_done_old = tx_done;
+ /* reset the countdown */
+ clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state);
}
- return false;
+ return ret;
}
#define IXGBE_MAX_TXD_PWR 14
@@ -734,11 +821,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *tx_ring)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct net_device *netdev = adapter->netdev;
union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
struct ixgbe_tx_buffer *tx_buffer_info;
- unsigned int i, eop, count = 0;
unsigned int total_bytes = 0, total_packets = 0;
+ u16 i, eop, count = 0;
i = tx_ring->next_to_clean;
eop = tx_ring->tx_buffer_info[i].next_to_watch;
@@ -749,148 +835,182 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
bool cleaned = false;
rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
- struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- cleaned = (i == eop);
- skb = tx_buffer_info->skb;
-
- if (cleaned && skb) {
- unsigned int segs, bytecount;
- unsigned int hlen = skb_headlen(skb);
-
- /* gso_segs is currently only valid for tcp */
- segs = skb_shinfo(skb)->gso_segs ?: 1;
-#ifdef IXGBE_FCOE
- /* adjust for FCoE Sequence Offload */
- if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
- && skb_is_gso(skb)
- && vlan_get_protocol(skb) ==
- htons(ETH_P_FCOE)) {
- hlen = skb_transport_offset(skb) +
- sizeof(struct fc_frame_header) +
- sizeof(struct fcoe_crc_eof);
- segs = DIV_ROUND_UP(skb->len - hlen,
- skb_shinfo(skb)->gso_size);
- }
-#endif /* IXGBE_FCOE */
- /* multiply data chunks by size of headers */
- bytecount = ((segs - 1) * hlen) + skb->len;
- total_packets += segs;
- total_bytes += bytecount;
- }
-
- ixgbe_unmap_and_free_tx_resource(adapter,
- tx_buffer_info);
tx_desc->wb.status = 0;
+ cleaned = (i == eop);
i++;
if (i == tx_ring->count)
i = 0;
+
+ if (cleaned && tx_buffer_info->skb) {
+ total_bytes += tx_buffer_info->bytecount;
+ total_packets += tx_buffer_info->gso_segs;
+ }
+
+ ixgbe_unmap_and_free_tx_resource(tx_ring,
+ tx_buffer_info);
}
+ tx_ring->tx_stats.completed++;
eop = tx_ring->tx_buffer_info[i].next_to_watch;
eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
}
tx_ring->next_to_clean = i;
+ tx_ring->total_bytes += total_bytes;
+ tx_ring->total_packets += total_packets;
+ u64_stats_update_begin(&tx_ring->syncp);
+ tx_ring->stats.packets += total_packets;
+ tx_ring->stats.bytes += total_bytes;
+ u64_stats_update_end(&tx_ring->syncp);
+
+ if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
+ /* schedule immediate reset if we believe we hung */
+ struct ixgbe_hw *hw = &adapter->hw;
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
+ e_err(drv, "Detected Tx Unit Hang\n"
+ " Tx Queue <%d>\n"
+ " TDH, TDT <%x>, <%x>\n"
+ " next_to_use <%x>\n"
+ " next_to_clean <%x>\n"
+ "tx_buffer_info[next_to_clean]\n"
+ " time_stamp <%lx>\n"
+ " jiffies <%lx>\n",
+ tx_ring->queue_index,
+ IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
+ IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
+ tx_ring->next_to_use, eop,
+ tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
+
+ netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
+
+ e_info(probe,
+ "tx hang %d detected on queue %d, resetting adapter\n",
+ adapter->tx_timeout_count + 1, tx_ring->queue_index);
+
+ /* schedule immediate reset if we believe we hung */
+ ixgbe_tx_timeout(adapter->netdev);
+
+ /* the adapter is about to reset, no point in enabling stuff */
+ return true;
+ }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
- if (unlikely(count && netif_carrier_ok(netdev) &&
+ if (unlikely(count && netif_carrier_ok(tx_ring->netdev) &&
(IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
smp_mb();
- if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
+ if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) &&
!test_bit(__IXGBE_DOWN, &adapter->state)) {
- netif_wake_subqueue(netdev, tx_ring->queue_index);
- ++tx_ring->restart_queue;
- }
- }
-
- if (adapter->detect_tx_hung) {
- if (ixgbe_check_tx_hang(adapter, tx_ring, i)) {
- /* schedule immediate reset if we believe we hung */
- e_info(probe, "tx hang %d detected, resetting "
- "adapter\n", adapter->tx_timeout_count + 1);
- ixgbe_tx_timeout(adapter->netdev);
+ netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index);
+ ++tx_ring->tx_stats.restart_queue;
}
}
- /* re-arm the interrupt */
- if (count >= tx_ring->work_limit)
- ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx));
-
- tx_ring->total_bytes += total_bytes;
- tx_ring->total_packets += total_packets;
- u64_stats_update_begin(&tx_ring->syncp);
- tx_ring->stats.packets += total_packets;
- tx_ring->stats.bytes += total_bytes;
- u64_stats_update_end(&tx_ring->syncp);
return count < tx_ring->work_limit;
}
#ifdef CONFIG_IXGBE_DCA
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring,
+ int cpu)
{
+ struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl;
- int cpu = get_cpu();
- int q = rx_ring->reg_idx;
-
- if (rx_ring->cpu != cpu) {
- rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
- rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
- rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
- } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
- rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
- }
- rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
- rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
- rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
- rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
- rx_ring->cpu = cpu;
+ u8 reg_idx = rx_ring->reg_idx;
+
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(reg_idx));
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
+ rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
+ rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+ break;
+ default:
+ break;
}
- put_cpu();
+ rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
+ rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring,
+ int cpu)
{
+ struct ixgbe_hw *hw = &adapter->hw;
u32 txctrl;
+ u8 reg_idx = tx_ring->reg_idx;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(reg_idx));
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
+ txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+ txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx));
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
+ txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+ txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector)
+{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
int cpu = get_cpu();
- int q = tx_ring->reg_idx;
- struct ixgbe_hw *hw = &adapter->hw;
+ long r_idx;
+ int i;
- if (tx_ring->cpu != cpu) {
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q));
- txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
- txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
- txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl);
- } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
- txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
- txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
- txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
- }
- tx_ring->cpu = cpu;
+ if (q_vector->cpu == cpu)
+ goto out_no_update;
+
+ r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+ for (i = 0; i < q_vector->txr_count; i++) {
+ ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu);
+ r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+ r_idx + 1);
+ }
+
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu);
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
}
+
+ q_vector->cpu = cpu;
+out_no_update:
put_cpu();
}
static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
{
+ int num_q_vectors;
int i;
if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
@@ -899,22 +1019,25 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
/* always use CB2 mode, difference is masked in the CB driver */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
- for (i = 0; i < adapter->num_tx_queues; i++) {
- adapter->tx_ring[i]->cpu = -1;
- ixgbe_update_tx_dca(adapter, adapter->tx_ring[i]);
- }
- for (i = 0; i < adapter->num_rx_queues; i++) {
- adapter->rx_ring[i]->cpu = -1;
- ixgbe_update_rx_dca(adapter, adapter->rx_ring[i]);
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+ num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ else
+ num_q_vectors = 1;
+
+ for (i = 0; i < num_q_vectors; i++) {
+ adapter->q_vector[i]->cpu = -1;
+ ixgbe_update_dca(adapter->q_vector[i]);
}
}
static int __ixgbe_notify_dca(struct device *dev, void *data)
{
- struct net_device *netdev = dev_get_drvdata(dev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = dev_get_drvdata(dev);
unsigned long event = *(unsigned long *)data;
+ if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
+ return 0;
+
switch (event) {
case DCA_PROVIDER_ADD:
/* if we're already enabled, don't do it again */
@@ -1013,8 +1136,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
-static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
- struct ixgbe_ring *rx_ring, u32 val)
+static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
{
/*
* Force memory writes to complete before letting h/w
@@ -1023,72 +1145,81 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
* such as IA-64).
*/
wmb();
- IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val);
+ writel(val, rx_ring->tail);
}
/**
* ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
- * @adapter: address of board private structure
+ * @rx_ring: ring to place buffers on
+ * @cleaned_count: number of buffers to replace
**/
-void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int cleaned_count)
+void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
- unsigned int i;
- unsigned int bufsz = rx_ring->rx_buf_len;
+ struct sk_buff *skb;
+ u16 i = rx_ring->next_to_use;
- i = rx_ring->next_to_use;
- bi = &rx_ring->rx_buffer_info[i];
+ /* do nothing if no valid netdev defined */
+ if (!rx_ring->netdev)
+ return;
while (cleaned_count--) {
rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
+ bi = &rx_ring->rx_buffer_info[i];
+ skb = bi->skb;
- if (!bi->page_dma &&
- (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) {
- if (!bi->page) {
- bi->page = netdev_alloc_page(netdev);
- if (!bi->page) {
- adapter->alloc_rx_page_failed++;
- goto no_buffers;
- }
- bi->page_offset = 0;
- } else {
- /* use a half page if we're re-using */
- bi->page_offset ^= (PAGE_SIZE / 2);
- }
-
- bi->page_dma = dma_map_page(&pdev->dev, bi->page,
- bi->page_offset,
- (PAGE_SIZE / 2),
- DMA_FROM_DEVICE);
- }
-
- if (!bi->skb) {
- struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev,
- bufsz);
- bi->skb = skb;
-
+ if (!skb) {
+ skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+ rx_ring->rx_buf_len);
if (!skb) {
- adapter->alloc_rx_buff_failed++;
+ rx_ring->rx_stats.alloc_rx_buff_failed++;
goto no_buffers;
}
/* initialize queue mapping */
skb_record_rx_queue(skb, rx_ring->queue_index);
+ bi->skb = skb;
}
if (!bi->dma) {
- bi->dma = dma_map_single(&pdev->dev,
- bi->skb->data,
+ bi->dma = dma_map_single(rx_ring->dev,
+ skb->data,
rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
+ if (dma_mapping_error(rx_ring->dev, bi->dma)) {
+ rx_ring->rx_stats.alloc_rx_buff_failed++;
+ bi->dma = 0;
+ goto no_buffers;
+ }
}
- /* Refresh the desc even if buffer_addrs didn't change because
- * each write-back erases this info. */
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+
+ if (ring_is_ps_enabled(rx_ring)) {
+ if (!bi->page) {
+ bi->page = netdev_alloc_page(rx_ring->netdev);
+ if (!bi->page) {
+ rx_ring->rx_stats.alloc_rx_page_failed++;
+ goto no_buffers;
+ }
+ }
+
+ if (!bi->page_dma) {
+ /* use a half page if we're re-using */
+ bi->page_offset ^= PAGE_SIZE / 2;
+ bi->page_dma = dma_map_page(rx_ring->dev,
+ bi->page,
+ bi->page_offset,
+ PAGE_SIZE / 2,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(rx_ring->dev,
+ bi->page_dma)) {
+ rx_ring->rx_stats.alloc_rx_page_failed++;
+ bi->page_dma = 0;
+ goto no_buffers;
+ }
+ }
+
+ /* Refresh the desc even if buffer_addrs didn't change
+ * because each write-back erases this info. */
rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
} else {
@@ -1099,56 +1230,48 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
i++;
if (i == rx_ring->count)
i = 0;
- bi = &rx_ring->rx_buffer_info[i];
}
no_buffers:
if (rx_ring->next_to_use != i) {
rx_ring->next_to_use = i;
- if (i-- == 0)
- i = (rx_ring->count - 1);
-
- ixgbe_release_rx_desc(&adapter->hw, rx_ring, i);
+ ixgbe_release_rx_desc(rx_ring, i);
}
}
-static inline u16 ixgbe_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc)
-{
- return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
-}
-
-static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
-{
- return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
-}
-
-static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
+static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc)
{
- return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
- IXGBE_RXDADV_RSCCNT_MASK) >>
- IXGBE_RXDADV_RSCCNT_SHIFT;
+ /* HW will not DMA in data larger than the given buffer, even if it
+ * parses the (NFS, of course) header to be larger. In that case, it
+ * fills the header buffer and spills the rest into the page.
+ */
+ u16 hdr_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info);
+ u16 hlen = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
+ IXGBE_RXDADV_HDRBUFLEN_SHIFT;
+ if (hlen > IXGBE_RX_HDR_SIZE)
+ hlen = IXGBE_RX_HDR_SIZE;
+ return hlen;
}
/**
* ixgbe_transform_rsc_queue - change rsc queue into a full packet
* @skb: pointer to the last skb in the rsc queue
- * @count: pointer to number of packets coalesced in this context
*
* This function changes a queue full of hw rsc buffers into a completed
* packet. It uses the ->prev pointers to find the first packet and then
* turns it into the frag list owner.
**/
-static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
- u64 *count)
+static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
{
unsigned int frag_list_size = 0;
+ unsigned int skb_cnt = 1;
while (skb->prev) {
struct sk_buff *prev = skb->prev;
frag_list_size += skb->len;
skb->prev = NULL;
skb = prev;
- *count += 1;
+ skb_cnt++;
}
skb_shinfo(skb)->frag_list = skb->next;
@@ -1156,68 +1279,59 @@ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
skb->len += frag_list_size;
skb->data_len += frag_list_size;
skb->truesize += frag_list_size;
+ IXGBE_RSC_CB(skb)->skb_cnt = skb_cnt;
+
return skb;
}
-struct ixgbe_rsc_cb {
- dma_addr_t dma;
- bool delay_unmap;
-};
-
-#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
+static inline bool ixgbe_get_rsc_state(union ixgbe_adv_rx_desc *rx_desc)
+{
+ return !!(le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
+ IXGBE_RXDADV_RSCCNT_MASK);
+}
-static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
+static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
struct sk_buff *skb;
- unsigned int i, rsc_count = 0;
- u32 len, staterr;
- u16 hdr_info;
- bool cleaned = false;
- int cleaned_count = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+ const int current_node = numa_node_id();
#ifdef IXGBE_FCOE
int ddp_bytes = 0;
#endif /* IXGBE_FCOE */
+ u32 staterr;
+ u16 i;
+ u16 cleaned_count = 0;
+ bool pkt_is_rsc = false;
i = rx_ring->next_to_clean;
rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
- rx_buffer_info = &rx_ring->rx_buffer_info[i];
while (staterr & IXGBE_RXD_STAT_DD) {
u32 upper_len = 0;
- if (*work_done >= work_to_do)
- break;
- (*work_done)++;
rmb(); /* read descriptor and rx_buffer_info after status DD */
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
- hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
- len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
- IXGBE_RXDADV_HDRBUFLEN_SHIFT;
- upper_len = le16_to_cpu(rx_desc->wb.upper.length);
- if ((len > IXGBE_RX_HDR_SIZE) ||
- (upper_len && !(hdr_info & IXGBE_RXDADV_SPH)))
- len = IXGBE_RX_HDR_SIZE;
- } else {
- len = le16_to_cpu(rx_desc->wb.upper.length);
- }
- cleaned = true;
+ rx_buffer_info = &rx_ring->rx_buffer_info[i];
+
skb = rx_buffer_info->skb;
- prefetch(skb->data);
rx_buffer_info->skb = NULL;
+ prefetch(skb->data);
+ if (ring_is_rsc_enabled(rx_ring))
+ pkt_is_rsc = ixgbe_get_rsc_state(rx_desc);
+
+ /* if this is a skb from previous receive DMA will be 0 */
if (rx_buffer_info->dma) {
- if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
- (!(staterr & IXGBE_RXD_STAT_EOP)) &&
- (!(skb->prev))) {
+ u16 hlen;
+ if (pkt_is_rsc &&
+ !(staterr & IXGBE_RXD_STAT_EOP) &&
+ !skb->prev) {
/*
* When HWRSC is enabled, delay unmapping
* of the first packet. It carries the
@@ -1228,29 +1342,42 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
IXGBE_RSC_CB(skb)->delay_unmap = true;
IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
} else {
- dma_unmap_single(&pdev->dev,
+ dma_unmap_single(rx_ring->dev,
rx_buffer_info->dma,
rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
}
rx_buffer_info->dma = 0;
- skb_put(skb, len);
+
+ if (ring_is_ps_enabled(rx_ring)) {
+ hlen = ixgbe_get_hlen(rx_desc);
+ upper_len = le16_to_cpu(rx_desc->wb.upper.length);
+ } else {
+ hlen = le16_to_cpu(rx_desc->wb.upper.length);
+ }
+
+ skb_put(skb, hlen);
+ } else {
+ /* assume packet split since header is unmapped */
+ upper_len = le16_to_cpu(rx_desc->wb.upper.length);
}
if (upper_len) {
- dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma,
- PAGE_SIZE / 2, DMA_FROM_DEVICE);
+ dma_unmap_page(rx_ring->dev,
+ rx_buffer_info->page_dma,
+ PAGE_SIZE / 2,
+ DMA_FROM_DEVICE);
rx_buffer_info->page_dma = 0;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
rx_buffer_info->page,
rx_buffer_info->page_offset,
upper_len);
- if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
- (page_count(rx_buffer_info->page) != 1))
- rx_buffer_info->page = NULL;
- else
+ if ((page_count(rx_buffer_info->page) == 1) &&
+ (page_to_nid(rx_buffer_info->page) == current_node))
get_page(rx_buffer_info->page);
+ else
+ rx_buffer_info->page = NULL;
skb->len += upper_len;
skb->data_len += upper_len;
@@ -1265,10 +1392,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
prefetch(next_rxd);
cleaned_count++;
- if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
- rsc_count = ixgbe_get_rsc_count(rx_desc);
-
- if (rsc_count) {
+ if (pkt_is_rsc) {
u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
IXGBE_RXDADV_NEXTP_SHIFT;
next_buffer = &rx_ring->rx_buffer_info[nextp];
@@ -1276,32 +1400,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
next_buffer = &rx_ring->rx_buffer_info[i];
}
- if (staterr & IXGBE_RXD_STAT_EOP) {
- 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)->delay_unmap) {
- dma_unmap_single(&pdev->dev,
- IXGBE_RSC_CB(skb)->dma,
- rx_ring->rx_buf_len,
- DMA_FROM_DEVICE);
- IXGBE_RSC_CB(skb)->dma = 0;
- IXGBE_RSC_CB(skb)->delay_unmap = false;
- }
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
- rx_ring->rsc_count +=
- skb_shinfo(skb)->nr_frags;
- else
- rx_ring->rsc_count++;
- rx_ring->rsc_flush++;
- }
- u64_stats_update_begin(&rx_ring->syncp);
- rx_ring->stats.packets++;
- rx_ring->stats.bytes += skb->len;
- u64_stats_update_end(&rx_ring->syncp);
- } else {
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+ if (!(staterr & IXGBE_RXD_STAT_EOP)) {
+ if (ring_is_ps_enabled(rx_ring)) {
rx_buffer_info->skb = next_buffer->skb;
rx_buffer_info->dma = next_buffer->dma;
next_buffer->skb = skb;
@@ -1310,12 +1410,45 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
skb->next = next_buffer->skb;
skb->next->prev = skb;
}
- rx_ring->non_eop_descs++;
+ rx_ring->rx_stats.non_eop_descs++;
goto next_desc;
}
+ if (skb->prev) {
+ skb = ixgbe_transform_rsc_queue(skb);
+ /* if we got here without RSC the packet is invalid */
+ if (!pkt_is_rsc) {
+ __pskb_trim(skb, 0);
+ rx_buffer_info->skb = skb;
+ goto next_desc;
+ }
+ }
+
+ if (ring_is_rsc_enabled(rx_ring)) {
+ if (IXGBE_RSC_CB(skb)->delay_unmap) {
+ dma_unmap_single(rx_ring->dev,
+ IXGBE_RSC_CB(skb)->dma,
+ rx_ring->rx_buf_len,
+ DMA_FROM_DEVICE);
+ IXGBE_RSC_CB(skb)->dma = 0;
+ IXGBE_RSC_CB(skb)->delay_unmap = false;
+ }
+ }
+ if (pkt_is_rsc) {
+ if (ring_is_ps_enabled(rx_ring))
+ rx_ring->rx_stats.rsc_count +=
+ skb_shinfo(skb)->nr_frags;
+ else
+ rx_ring->rx_stats.rsc_count +=
+ IXGBE_RSC_CB(skb)->skb_cnt;
+ rx_ring->rx_stats.rsc_flush++;
+ }
+
+ /* ERR_MASK will only have valid bits if EOP set */
if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) {
- dev_kfree_skb_irq(skb);
+ /* trim packet back to size 0 and recycle it */
+ __pskb_trim(skb, 0);
+ rx_buffer_info->skb = skb;
goto next_desc;
}
@@ -1325,7 +1458,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
total_rx_bytes += skb->len;
total_rx_packets++;
- skb->protocol = eth_type_trans(skb, adapter->netdev);
+ skb->protocol = eth_type_trans(skb, rx_ring->netdev);
#ifdef IXGBE_FCOE
/* if ddp, not passing to ULD unless for FCP_RSP or error */
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
@@ -1339,16 +1472,18 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
next_desc:
rx_desc->wb.upper.status_error = 0;
+ (*work_done)++;
+ if (*work_done >= work_to_do)
+ break;
+
/* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) {
- ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+ ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
cleaned_count = 0;
}
/* use prefetched values */
rx_desc = next_rxd;
- rx_buffer_info = &rx_ring->rx_buffer_info[i];
-
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
@@ -1356,14 +1491,14 @@ next_desc:
cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
if (cleaned_count)
- ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+ ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
#ifdef IXGBE_FCOE
/* include DDPed FCoE data */
if (ddp_bytes > 0) {
unsigned int mss;
- mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) -
+ mss = rx_ring->netdev->mtu - sizeof(struct fcoe_hdr) -
sizeof(struct fc_frame_header) -
sizeof(struct fcoe_crc_eof);
if (mss > 512)
@@ -1375,8 +1510,10 @@ next_desc:
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
-
- return cleaned;
+ u64_stats_update_begin(&rx_ring->syncp);
+ rx_ring->stats.packets += total_rx_packets;
+ rx_ring->stats.bytes += total_rx_bytes;
+ u64_stats_update_end(&rx_ring->syncp);
}
static int ixgbe_clean_rxonly(struct napi_struct *, int);
@@ -1390,7 +1527,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *, int);
static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
{
struct ixgbe_q_vector *q_vector;
- int i, j, q_vectors, v_idx, r_idx;
+ int i, q_vectors, v_idx, r_idx;
u32 mask;
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -1406,8 +1543,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
- j = adapter->rx_ring[r_idx]->reg_idx;
- ixgbe_set_ivar(adapter, 0, j, v_idx);
+ u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx;
+ ixgbe_set_ivar(adapter, 0, reg_idx, v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
adapter->num_rx_queues,
r_idx + 1);
@@ -1416,8 +1553,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
- j = adapter->tx_ring[r_idx]->reg_idx;
- ixgbe_set_ivar(adapter, 1, j, v_idx);
+ u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx;
+ ixgbe_set_ivar(adapter, 1, reg_idx, v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
adapter->num_tx_queues,
r_idx + 1);
@@ -1448,11 +1585,19 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
}
}
- if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
v_idx);
- else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
ixgbe_set_ivar(adapter, -1, 1, v_idx);
+ break;
+
+ default:
+ break;
+ }
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
/* set up to autoclear timer, and the vectors */
@@ -1548,12 +1693,15 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
int v_idx = q_vector->v_idx;
u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr);
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
/* must write high and low 16 bits to reset counter */
itr_reg |= (itr_reg << 16);
- } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
/*
- * 82599 can support a value of zero, so allow it for
+ * 82599 and X540 can support a value of zero, so allow it for
* max interrupt rate, but there is an errata where it can
* not be zero with RSC
*/
@@ -1566,6 +1714,9 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
* immediate assertion of the interrupt
*/
itr_reg |= IXGBE_EITR_CNT_WDIS;
+ break;
+ default:
+ break;
}
IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg);
}
@@ -1573,14 +1724,13 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
+ int i, r_idx;
u32 new_itr;
u8 current_itr, ret_itr;
- int i, r_idx;
- struct ixgbe_ring *rx_ring, *tx_ring;
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
- tx_ring = adapter->tx_ring[r_idx];
+ struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
q_vector->tx_itr,
tx_ring->total_packets,
@@ -1595,7 +1745,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
- rx_ring = adapter->rx_ring[r_idx];
+ struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
q_vector->rx_itr,
rx_ring->total_packets,
@@ -1626,7 +1776,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
if (new_itr != q_vector->eitr) {
/* do an exponential smoothing */
- new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
+ new_itr = ((q_vector->eitr * 9) + new_itr)/10;
/* save the algorithm value here, not the smoothed one */
q_vector->eitr = new_itr;
@@ -1694,17 +1844,18 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
{
struct ixgbe_hw *hw = &adapter->hw;
+ if (eicr & IXGBE_EICR_GPI_SDP2) {
+ /* Clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ schedule_work(&adapter->sfp_config_module_task);
+ }
+
if (eicr & IXGBE_EICR_GPI_SDP1) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
- schedule_work(&adapter->multispeed_fiber_task);
- } else if (eicr & IXGBE_EICR_GPI_SDP2) {
- /* Clear the interrupt */
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
- schedule_work(&adapter->sfp_config_module_task);
- } else {
- /* Interrupt isn't for us... */
- return;
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ schedule_work(&adapter->multispeed_fiber_task);
}
}
@@ -1744,16 +1895,16 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
if (eicr & IXGBE_EICR_MAILBOX)
ixgbe_msg_task(adapter);
- if (hw->mac.type == ixgbe_mac_82598EB)
- ixgbe_check_fan_failure(adapter, eicr);
-
- if (hw->mac.type == ixgbe_mac_82599EB) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
ixgbe_check_sfp_event(adapter, eicr);
- adapter->interrupt_event = eicr;
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
- ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC)))
+ ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+ adapter->interrupt_event = eicr;
schedule_work(&adapter->check_overtemp_task);
-
+ }
+ /* now fallthrough to handle Flow Director */
+ case ixgbe_mac_X540:
/* Handle Flow Director Full threshold interrupt */
if (eicr & IXGBE_EICR_FLOW_DIR) {
int i;
@@ -1763,12 +1914,18 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring =
adapter->tx_ring[i];
- if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state))
+ if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
+ &tx_ring->state))
schedule_work(&adapter->fdir_reinit_task);
}
}
+ break;
+ default:
+ break;
}
+
+ ixgbe_check_fan_failure(adapter, eicr);
+
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1779,15 +1936,24 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
u64 qmask)
{
u32 mask;
+ struct ixgbe_hw *hw = &adapter->hw;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- } else {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
mask = (qmask & 0xFFFFFFFF);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask);
+ if (mask)
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
mask = (qmask >> 32);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask);
+ if (mask)
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
+ break;
+ default:
+ break;
}
/* skip the flush */
}
@@ -1796,15 +1962,24 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
u64 qmask)
{
u32 mask;
+ struct ixgbe_hw *hw = &adapter->hw;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask);
- } else {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
mask = (qmask & 0xFFFFFFFF);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask);
+ if (mask)
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
mask = (qmask >> 32);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask);
+ if (mask)
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
+ break;
+ default:
+ break;
}
/* skip the flush */
}
@@ -1847,8 +2022,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
int r_idx;
int i;
+#ifdef CONFIG_IXGBE_DCA
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_dca(q_vector);
+#endif
+
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
- for (i = 0; i < q_vector->rxr_count; i++) {
+ for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = adapter->rx_ring[r_idx];
rx_ring->total_bytes = 0;
rx_ring->total_packets = 0;
@@ -1859,7 +2039,6 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
if (!q_vector->rxr_count)
return IRQ_HANDLED;
- /* disable interrupts on this vector only */
/* EIAM disabled interrupts (on this vector) for us */
napi_schedule(&q_vector->napi);
@@ -1918,13 +2097,14 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
int work_done = 0;
long r_idx;
- r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
- rx_ring = adapter->rx_ring[r_idx];
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_rx_dca(adapter, rx_ring);
+ ixgbe_update_dca(q_vector);
#endif
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ rx_ring = adapter->rx_ring[r_idx];
+
ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
/* If all Rx work done, exit the polling mode */
@@ -1958,13 +2138,14 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
long r_idx;
bool tx_clean_complete = true;
+#ifdef CONFIG_IXGBE_DCA
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_dca(q_vector);
+#endif
+
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
ring = adapter->tx_ring[r_idx];
-#ifdef CONFIG_IXGBE_DCA
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_tx_dca(adapter, ring);
-#endif
tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
r_idx + 1);
@@ -1977,10 +2158,6 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
ring = adapter->rx_ring[r_idx];
-#ifdef CONFIG_IXGBE_DCA
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_rx_dca(adapter, ring);
-#endif
ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
r_idx + 1);
@@ -2019,13 +2196,14 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
int work_done = 0;
long r_idx;
- r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
- tx_ring = adapter->tx_ring[r_idx];
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_tx_dca(adapter, tx_ring);
+ ixgbe_update_dca(q_vector);
#endif
+ r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+ tx_ring = adapter->tx_ring[r_idx];
+
if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
work_done = budget;
@@ -2046,24 +2224,27 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
int r_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+ struct ixgbe_ring *rx_ring = a->rx_ring[r_idx];
set_bit(r_idx, q_vector->rxr_idx);
q_vector->rxr_count++;
+ rx_ring->q_vector = q_vector;
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
int t_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+ struct ixgbe_ring *tx_ring = a->tx_ring[t_idx];
set_bit(t_idx, q_vector->txr_idx);
q_vector->txr_count++;
+ tx_ring->q_vector = q_vector;
}
/**
* ixgbe_map_rings_to_vectors - Maps descriptor rings to vectors
* @adapter: board private structure to initialize
- * @vectors: allotted vector count for descriptor rings
*
* This function maps descriptor rings to the queue-specific vectors
* we were allotted through the MSI-X enabling code. Ideally, we'd have
@@ -2071,9 +2252,9 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
* group the rings as "efficiently" as possible. You would add new
* mapping configurations in here.
**/
-static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter)
{
+ int q_vectors;
int v_start = 0;
int rxr_idx = 0, txr_idx = 0;
int rxr_remaining = adapter->num_rx_queues;
@@ -2086,11 +2267,13 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
goto out;
+ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
/*
* The ideal configuration...
* We have enough vectors to map one per queue.
*/
- if (vectors == adapter->num_rx_queues + adapter->num_tx_queues) {
+ if (q_vectors == adapter->num_rx_queues + adapter->num_tx_queues) {
for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++)
map_vector_to_rxq(adapter, v_start, rxr_idx);
@@ -2106,23 +2289,20 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
* multiple queues per vector.
*/
/* Re-adjusting *qpv takes care of the remainder. */
- for (i = v_start; i < vectors; i++) {
- rqpv = DIV_ROUND_UP(rxr_remaining, vectors - i);
+ for (i = v_start; i < q_vectors; i++) {
+ rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - i);
for (j = 0; j < rqpv; j++) {
map_vector_to_rxq(adapter, i, rxr_idx);
rxr_idx++;
rxr_remaining--;
}
- }
- for (i = v_start; i < vectors; i++) {
- tqpv = DIV_ROUND_UP(txr_remaining, vectors - i);
+ tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - i);
for (j = 0; j < tqpv; j++) {
map_vector_to_txq(adapter, i, txr_idx);
txr_idx++;
txr_remaining--;
}
}
-
out:
return err;
}
@@ -2144,30 +2324,36 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
/* Decrement for Other and TCP Timer vectors */
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- /* Map the Tx/Rx rings to the vectors we were allotted. */
- err = ixgbe_map_rings_to_vectors(adapter, q_vectors);
+ err = ixgbe_map_rings_to_vectors(adapter);
if (err)
- goto out;
+ return err;
-#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
- (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
- &ixgbe_msix_clean_many)
+#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \
+ ? &ixgbe_msix_clean_many : \
+ (_v)->rxr_count ? &ixgbe_msix_clean_rx : \
+ (_v)->txr_count ? &ixgbe_msix_clean_tx : \
+ NULL)
for (vector = 0; vector < q_vectors; vector++) {
- handler = SET_HANDLER(adapter->q_vector[vector]);
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[vector];
+ handler = SET_HANDLER(q_vector);
if (handler == &ixgbe_msix_clean_rx) {
- sprintf(adapter->name[vector], "%s-%s-%d",
- netdev->name, "rx", ri++);
+ snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+ "%s-%s-%d", netdev->name, "rx", ri++);
} else if (handler == &ixgbe_msix_clean_tx) {
- sprintf(adapter->name[vector], "%s-%s-%d",
- netdev->name, "tx", ti++);
- } else
- sprintf(adapter->name[vector], "%s-%s-%d",
- netdev->name, "TxRx", vector);
-
+ snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+ "%s-%s-%d", netdev->name, "tx", ti++);
+ } else if (handler == &ixgbe_msix_clean_many) {
+ snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+ "%s-%s-%d", netdev->name, "TxRx", ri++);
+ ti++;
+ } else {
+ /* skip this unused q_vector */
+ continue;
+ }
err = request_irq(adapter->msix_entries[vector].vector,
- handler, 0, adapter->name[vector],
- adapter->q_vector[vector]);
+ handler, 0, q_vector->name,
+ q_vector);
if (err) {
e_err(probe, "request_irq failed for MSIX interrupt "
"Error: %d\n", err);
@@ -2175,9 +2361,9 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
}
}
- sprintf(adapter->name[vector], "%s:lsc", netdev->name);
+ sprintf(adapter->lsc_int_name, "%s:lsc", netdev->name);
err = request_irq(adapter->msix_entries[vector].vector,
- ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+ ixgbe_msix_lsc, 0, adapter->lsc_int_name, netdev);
if (err) {
e_err(probe, "request_irq for msix_lsc failed: %d\n", err);
goto free_queue_irqs;
@@ -2193,17 +2379,16 @@ free_queue_irqs:
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
-out:
return err;
}
static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
{
struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
- u8 current_itr;
- u32 new_itr = q_vector->eitr;
struct ixgbe_ring *rx_ring = adapter->rx_ring[0];
struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
+ u32 new_itr = q_vector->eitr;
+ u8 current_itr;
q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
q_vector->tx_itr,
@@ -2233,9 +2418,9 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
if (new_itr != q_vector->eitr) {
/* do an exponential smoothing */
- new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
+ new_itr = ((q_vector->eitr * 9) + new_itr)/10;
- /* save the algorithm value here, not the smoothed one */
+ /* save the algorithm value here */
q_vector->eitr = new_itr;
ixgbe_write_eitr(q_vector);
@@ -2256,12 +2441,17 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
mask |= IXGBE_EIMS_GPI_SDP0;
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
mask |= IXGBE_EIMS_ECC;
mask |= IXGBE_EIMS_GPI_SDP1;
mask |= IXGBE_EIMS_GPI_SDP2;
if (adapter->num_vfs)
mask |= IXGBE_EIMS_MAILBOX;
+ break;
+ default:
+ break;
}
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
@@ -2317,13 +2507,20 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
- if (hw->mac.type == ixgbe_mac_82599EB)
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
ixgbe_check_sfp_event(adapter, eicr);
+ if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+ ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+ adapter->interrupt_event = eicr;
+ schedule_work(&adapter->check_overtemp_task);
+ }
+ break;
+ default:
+ break;
+ }
ixgbe_check_fan_failure(adapter, eicr);
- if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
- ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC)))
- schedule_work(&adapter->check_overtemp_task);
if (napi_schedule_prep(&(q_vector->napi))) {
adapter->tx_ring[0]->total_packets = 0;
@@ -2416,14 +2613,20 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
**/
static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
{
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
- } else {
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
if (adapter->num_vfs > 32)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0);
+ break;
+ default:
+ break;
}
IXGBE_WRITE_FLUSH(&adapter->hw);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -2469,7 +2672,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
u64 tdba = ring->dma;
int wait_loop = 10;
u32 txdctl;
- u16 reg_idx = ring->reg_idx;
+ u8 reg_idx = ring->reg_idx;
/* disable queue to avoid issues while updating state */
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
@@ -2484,8 +2687,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
ring->count * sizeof(union ixgbe_adv_tx_desc));
IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0);
IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0);
- ring->head = IXGBE_TDH(reg_idx);
- ring->tail = IXGBE_TDT(reg_idx);
+ ring->tail = hw->hw_addr + IXGBE_TDT(reg_idx);
/* configure fetching thresholds */
if (adapter->rx_itr_setting == 0) {
@@ -2501,7 +2703,16 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
}
/* reinitialize flowdirector state */
- set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state);
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) &&
+ adapter->atr_sample_rate) {
+ ring->atr_sample_rate = adapter->atr_sample_rate;
+ ring->atr_count = 0;
+ set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state);
+ } else {
+ ring->atr_sample_rate = 0;
+ }
+
+ clear_bit(__IXGBE_HANG_CHECK_ARMED, &ring->state);
/* enable queue */
txdctl |= IXGBE_TXDCTL_ENABLE;
@@ -2592,16 +2803,22 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *rx_ring)
{
u32 srrctl;
- int index;
- struct ixgbe_ring_feature *feature = adapter->ring_feature;
+ u8 reg_idx = rx_ring->reg_idx;
- index = rx_ring->reg_idx;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
- unsigned long mask;
- mask = (unsigned long) feature[RING_F_RSS].mask;
- index = index & mask;
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB: {
+ struct ixgbe_ring_feature *feature = adapter->ring_feature;
+ const int mask = feature[RING_F_RSS].mask;
+ reg_idx = reg_idx & mask;
+ }
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ default:
+ break;
}
- srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index));
+
+ srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx));
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
@@ -2611,7 +2828,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
IXGBE_SRRCTL_BSIZEHDR_MASK;
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+ if (ring_is_ps_enabled(rx_ring)) {
#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
#else
@@ -2624,7 +2841,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx), srrctl);
}
static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
@@ -2694,19 +2911,36 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
}
/**
+ * ixgbe_clear_rscctl - disable RSC for the indicated ring
+ * @adapter: address of board private structure
+ * @ring: structure containing ring specific data
+ **/
+void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rscctrl;
+ u8 reg_idx = ring->reg_idx;
+
+ rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx));
+ rscctrl &= ~IXGBE_RSCCTL_RSCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
+}
+
+/**
* ixgbe_configure_rscctl - enable RSC for the indicated ring
* @adapter: address of board private structure
* @index: index of ring to set
**/
-static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
+void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 rscctrl;
int rx_buf_len;
- u16 reg_idx = ring->reg_idx;
+ u8 reg_idx = ring->reg_idx;
- if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
+ if (!ring_is_rsc_enabled(ring))
return;
rx_buf_len = ring->rx_buf_len;
@@ -2717,7 +2951,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
* total size of max desc * buf_len is not greater
* than 65535
*/
- if (ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+ if (ring_is_ps_enabled(ring)) {
#if (MAX_SKB_FRAGS > 16)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
#elif (MAX_SKB_FRAGS > 8)
@@ -2770,9 +3004,9 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
{
struct ixgbe_hw *hw = &adapter->hw;
- int reg_idx = ring->reg_idx;
int wait_loop = IXGBE_MAX_RX_DESC_POLL;
u32 rxdctl;
+ u8 reg_idx = ring->reg_idx;
/* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
if (hw->mac.type == ixgbe_mac_82598EB &&
@@ -2796,7 +3030,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
struct ixgbe_hw *hw = &adapter->hw;
u64 rdba = ring->dma;
u32 rxdctl;
- u16 reg_idx = ring->reg_idx;
+ u8 reg_idx = ring->reg_idx;
/* disable queue to avoid issues while updating state */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
@@ -2810,8 +3044,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
ring->count * sizeof(union ixgbe_adv_rx_desc));
IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0);
IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0);
- ring->head = IXGBE_RDH(reg_idx);
- ring->tail = IXGBE_RDT(reg_idx);
+ ring->tail = hw->hw_addr + IXGBE_RDT(reg_idx);
ixgbe_configure_srrctl(adapter, ring);
ixgbe_configure_rscctl(adapter, ring);
@@ -2833,7 +3066,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
- ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring));
+ ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring));
}
static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
@@ -2899,6 +3132,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* enable Tx loopback for VF/PF communication */
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+ /* Enable MAC Anti-Spoofing */
+ hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
+ adapter->num_vfs);
}
static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
@@ -2956,24 +3192,32 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
rx_ring->rx_buf_len = rx_buf_len;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
- rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED;
+ set_ring_ps_enabled(rx_ring);
+ else
+ clear_ring_ps_enabled(rx_ring);
+
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
+ set_ring_rsc_enabled(rx_ring);
else
- rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
+ clear_ring_rsc_enabled(rx_ring);
#ifdef IXGBE_FCOE
if (netdev->features & NETIF_F_FCOE_MTU) {
struct ixgbe_ring_feature *f;
f = &adapter->ring_feature[RING_F_FCOE];
if ((i >= f->mask) && (i < f->mask + f->indices)) {
- rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
+ clear_ring_ps_enabled(rx_ring);
if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)
rx_ring->rx_buf_len =
IXGBE_FCOE_JUMBO_FRAME_SIZE;
+ } else if (!ring_is_rsc_enabled(rx_ring) &&
+ !ring_is_ps_enabled(rx_ring)) {
+ rx_ring->rx_buf_len =
+ IXGBE_FCOE_JUMBO_FRAME_SIZE;
}
}
#endif /* IXGBE_FCOE */
}
-
}
static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
@@ -2996,6 +3240,7 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
rdrxctl |= IXGBE_RDRXCTL_MVMEN;
break;
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
/* Disable RSC for ACK packets */
IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
(IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
@@ -3123,6 +3368,7 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -3152,6 +3398,7 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -3349,8 +3596,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- u32 txdctl;
- int i, j;
if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) {
if (hw->mac.type == ixgbe_mac_82598EB)
@@ -3366,25 +3611,18 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif
- ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame,
+ ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame,
DCB_TX_CONFIG);
- ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame,
+ ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame,
DCB_RX_CONFIG);
- /* reconfigure the hardware */
- ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg);
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- /* PThresh workaround for Tx hang with DFP enabled. */
- txdctl |= 32;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
- }
/* Enable VLAN tag insert/strip */
adapter->netdev->features |= NETIF_F_HW_VLAN_RX;
hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
+
+ /* reconfigure the hardware */
+ ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg);
}
#endif
@@ -3516,8 +3754,9 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
case ixgbe_mac_82598EB:
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
break;
- default:
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ default:
IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF);
IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF);
break;
@@ -3561,13 +3800,24 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
else
ixgbe_configure_msi_and_legacy(adapter);
- /* enable the optics */
- if (hw->phy.multispeed_fiber)
+ /* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */
+ if (hw->mac.ops.enable_tx_laser &&
+ ((hw->phy.multispeed_fiber) ||
+ ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ (hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.enable_tx_laser(hw);
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
+ if (ixgbe_is_sfp(hw)) {
+ ixgbe_sfp_link_config(adapter);
+ } else {
+ err = ixgbe_non_sfp_link_config(hw);
+ if (err)
+ e_err(probe, "link_config FAILED %d\n", err);
+ }
+
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
ixgbe_irq_enable(adapter, true, true);
@@ -3590,26 +3840,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
* If we're not hot-pluggable SFP+, we just need to configure link
* and bring it up.
*/
- if (hw->phy.type == ixgbe_phy_unknown) {
- err = hw->phy.ops.identify(hw);
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- /*
- * Take the device down and schedule the sfp tasklet
- * which will unregister_netdev and log it.
- */
- ixgbe_down(adapter);
- schedule_work(&adapter->sfp_config_module_task);
- return err;
- }
- }
-
- if (ixgbe_is_sfp(hw)) {
- ixgbe_sfp_link_config(adapter);
- } else {
- err = ixgbe_non_sfp_link_config(hw);
- if (err)
- e_err(probe, "link_config FAILED %d\n", err);
- }
+ if (hw->phy.type == ixgbe_phy_unknown)
+ schedule_work(&adapter->sfp_config_module_task);
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
@@ -3687,15 +3919,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
/**
* ixgbe_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
* @rx_ring: ring to free buffers from
**/
-static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct device *dev = rx_ring->dev;
unsigned long size;
- unsigned int i;
+ u16 i;
/* ring already cleared, nothing to do */
if (!rx_ring->rx_buffer_info)
@@ -3707,7 +3937,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
- dma_unmap_single(&pdev->dev, rx_buffer_info->dma,
+ dma_unmap_single(rx_ring->dev, rx_buffer_info->dma,
rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
rx_buffer_info->dma = 0;
@@ -3718,7 +3948,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
do {
struct sk_buff *this = skb;
if (IXGBE_RSC_CB(this)->delay_unmap) {
- dma_unmap_single(&pdev->dev,
+ dma_unmap_single(dev,
IXGBE_RSC_CB(this)->dma,
rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
@@ -3732,7 +3962,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
if (!rx_buffer_info->page)
continue;
if (rx_buffer_info->page_dma) {
- dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma,
+ dma_unmap_page(dev, rx_buffer_info->page_dma,
PAGE_SIZE / 2, DMA_FROM_DEVICE);
rx_buffer_info->page_dma = 0;
}
@@ -3749,24 +3979,17 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
-
- if (rx_ring->head)
- writel(0, adapter->hw.hw_addr + rx_ring->head);
- if (rx_ring->tail)
- writel(0, adapter->hw.hw_addr + rx_ring->tail);
}
/**
* ixgbe_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
* @tx_ring: ring to be cleaned
**/
-static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned long size;
- unsigned int i;
+ u16 i;
/* ring already cleared, nothing to do */
if (!tx_ring->tx_buffer_info)
@@ -3775,7 +3998,7 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
/* Free all the Tx ring sk_buffs */
for (i = 0; i < tx_ring->count; i++) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+ ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
}
size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
@@ -3786,11 +4009,6 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
-
- if (tx_ring->head)
- writel(0, adapter->hw.hw_addr + tx_ring->head);
- if (tx_ring->tail)
- writel(0, adapter->hw.hw_addr + tx_ring->tail);
}
/**
@@ -3802,7 +4020,7 @@ static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_clean_rx_ring(adapter, adapter->rx_ring[i]);
+ ixgbe_clean_rx_ring(adapter->rx_ring[i]);
}
/**
@@ -3814,7 +4032,7 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- ixgbe_clean_tx_ring(adapter, adapter->tx_ring[i]);
+ ixgbe_clean_tx_ring(adapter->tx_ring[i]);
}
void ixgbe_down(struct ixgbe_adapter *adapter)
@@ -3823,7 +4041,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl;
u32 txdctl;
- int i, j;
+ int i;
int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
/* signal that we are down to the interrupt handler */
@@ -3881,26 +4099,36 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
/* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
+ u8 reg_idx = adapter->tx_ring[i]->reg_idx;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
(txdctl & ~IXGBE_TXDCTL_ENABLE));
}
/* Disable the Tx DMA engine on 82599 */
- if (hw->mac.type == ixgbe_mac_82599EB)
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
~IXGBE_DMATXCTL_TE));
-
- /* power down the optics */
- if (hw->phy.multispeed_fiber)
- hw->mac.ops.disable_tx_laser(hw);
+ break;
+ default:
+ break;
+ }
/* clear n-tuple filters that are cached */
ethtool_ntuple_flush(netdev);
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
+
+ /* power down the optics for multispeed fiber and 82599 SFP+ fiber */
+ if (hw->mac.ops.disable_tx_laser &&
+ ((hw->phy.multispeed_fiber) ||
+ ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ (hw->mac.type == ixgbe_mac_82599EB))))
+ hw->mac.ops.disable_tx_laser(hw);
+
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
@@ -3925,10 +4153,8 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
int tx_clean_complete, work_done = 0;
#ifdef CONFIG_IXGBE_DCA
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
- ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]);
- ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]);
- }
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_dca(q_vector);
#endif
tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]);
@@ -3956,6 +4182,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ adapter->tx_timeout_count++;
+
/* Do the reset outside of interrupt context */
schedule_work(&adapter->reset_task);
}
@@ -3970,8 +4198,6 @@ static void ixgbe_reset_task(struct work_struct *work)
test_bit(__IXGBE_RESETTING, &adapter->state))
return;
- adapter->tx_timeout_count++;
-
ixgbe_dump(adapter);
netdev_err(adapter->netdev, "Reset adapter\n");
ixgbe_reinit_locked(adapter);
@@ -4221,19 +4447,16 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
{
int i;
- bool ret = false;
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i]->reg_idx = i;
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i]->reg_idx = i;
- ret = true;
- } else {
- ret = false;
- }
+ if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+ return false;
- return ret;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i]->reg_idx = i;
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i]->reg_idx = i;
+
+ return true;
}
#ifdef CONFIG_IXGBE_DCB
@@ -4250,71 +4473,67 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
bool ret = false;
int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
- /* the number of queues is assumed to be symmetric */
- for (i = 0; i < dcb_i; i++) {
- adapter->rx_ring[i]->reg_idx = i << 3;
- adapter->tx_ring[i]->reg_idx = i << 2;
- }
- ret = true;
- } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- if (dcb_i == 8) {
- /*
- * Tx TC0 starts at: descriptor queue 0
- * Tx TC1 starts at: descriptor queue 32
- * Tx TC2 starts at: descriptor queue 64
- * Tx TC3 starts at: descriptor queue 80
- * Tx TC4 starts at: descriptor queue 96
- * Tx TC5 starts at: descriptor queue 104
- * Tx TC6 starts at: descriptor queue 112
- * Tx TC7 starts at: descriptor queue 120
- *
- * Rx TC0-TC7 are offset by 16 queues each
- */
- for (i = 0; i < 3; i++) {
- adapter->tx_ring[i]->reg_idx = i << 5;
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
- for ( ; i < 5; i++) {
- adapter->tx_ring[i]->reg_idx =
- ((i + 2) << 4);
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
- for ( ; i < dcb_i; i++) {
- adapter->tx_ring[i]->reg_idx =
- ((i + 8) << 3);
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
+ return false;
- ret = true;
- } else if (dcb_i == 4) {
- /*
- * Tx TC0 starts at: descriptor queue 0
- * Tx TC1 starts at: descriptor queue 64
- * Tx TC2 starts at: descriptor queue 96
- * Tx TC3 starts at: descriptor queue 112
- *
- * Rx TC0-TC3 are offset by 32 queues each
- */
- adapter->tx_ring[0]->reg_idx = 0;
- adapter->tx_ring[1]->reg_idx = 64;
- adapter->tx_ring[2]->reg_idx = 96;
- adapter->tx_ring[3]->reg_idx = 112;
- for (i = 0 ; i < dcb_i; i++)
- adapter->rx_ring[i]->reg_idx = i << 5;
-
- ret = true;
- } else {
- ret = false;
+ /* the number of queues is assumed to be symmetric */
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
+ for (i = 0; i < dcb_i; i++) {
+ adapter->rx_ring[i]->reg_idx = i << 3;
+ adapter->tx_ring[i]->reg_idx = i << 2;
+ }
+ ret = true;
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ if (dcb_i == 8) {
+ /*
+ * Tx TC0 starts at: descriptor queue 0
+ * Tx TC1 starts at: descriptor queue 32
+ * Tx TC2 starts at: descriptor queue 64
+ * Tx TC3 starts at: descriptor queue 80
+ * Tx TC4 starts at: descriptor queue 96
+ * Tx TC5 starts at: descriptor queue 104
+ * Tx TC6 starts at: descriptor queue 112
+ * Tx TC7 starts at: descriptor queue 120
+ *
+ * Rx TC0-TC7 are offset by 16 queues each
+ */
+ for (i = 0; i < 3; i++) {
+ adapter->tx_ring[i]->reg_idx = i << 5;
+ adapter->rx_ring[i]->reg_idx = i << 4;
}
- } else {
- ret = false;
+ for ( ; i < 5; i++) {
+ adapter->tx_ring[i]->reg_idx = ((i + 2) << 4);
+ adapter->rx_ring[i]->reg_idx = i << 4;
+ }
+ for ( ; i < dcb_i; i++) {
+ adapter->tx_ring[i]->reg_idx = ((i + 8) << 3);
+ adapter->rx_ring[i]->reg_idx = i << 4;
+ }
+ ret = true;
+ } else if (dcb_i == 4) {
+ /*
+ * Tx TC0 starts at: descriptor queue 0
+ * Tx TC1 starts at: descriptor queue 64
+ * Tx TC2 starts at: descriptor queue 96
+ * Tx TC3 starts at: descriptor queue 112
+ *
+ * Rx TC0-TC3 are offset by 32 queues each
+ */
+ adapter->tx_ring[0]->reg_idx = 0;
+ adapter->tx_ring[1]->reg_idx = 64;
+ adapter->tx_ring[2]->reg_idx = 96;
+ adapter->tx_ring[3]->reg_idx = 112;
+ for (i = 0 ; i < dcb_i; i++)
+ adapter->rx_ring[i]->reg_idx = i << 5;
+ ret = true;
}
- } else {
- ret = false;
+ break;
+ default:
+ break;
}
-
return ret;
}
#endif
@@ -4354,55 +4573,55 @@ static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
*/
static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter)
{
- int i, fcoe_rx_i = 0, fcoe_tx_i = 0;
- bool ret = false;
struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+ int i;
+ u8 fcoe_rx_i = 0, fcoe_tx_i = 0;
+
+ if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
+ return false;
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
- ixgbe_cache_ring_dcb(adapter);
- /* find out queues in TC for FCoE */
- fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1;
- fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1;
- /*
- * In 82599, the number of Tx queues for each traffic
- * class for both 8-TC and 4-TC modes are:
- * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7
- * 8 TCs: 32 32 16 16 8 8 8 8
- * 4 TCs: 64 64 32 32
- * We have max 8 queues for FCoE, where 8 the is
- * FCoE redirection table size. If TC for FCoE is
- * less than or equal to TC3, we have enough queues
- * to add max of 8 queues for FCoE, so we start FCoE
- * tx descriptor from the next one, i.e., reg_idx + 1.
- * If TC for FCoE is above TC3, implying 8 TC mode,
- * and we need 8 for FCoE, we have to take all queues
- * in that traffic class for FCoE.
- */
- if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3))
- fcoe_tx_i--;
- }
+ ixgbe_cache_ring_dcb(adapter);
+ /* find out queues in TC for FCoE */
+ fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1;
+ fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1;
+ /*
+ * In 82599, the number of Tx queues for each traffic
+ * class for both 8-TC and 4-TC modes are:
+ * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7
+ * 8 TCs: 32 32 16 16 8 8 8 8
+ * 4 TCs: 64 64 32 32
+ * We have max 8 queues for FCoE, where 8 the is
+ * FCoE redirection table size. If TC for FCoE is
+ * less than or equal to TC3, we have enough queues
+ * to add max of 8 queues for FCoE, so we start FCoE
+ * Tx queue from the next one, i.e., reg_idx + 1.
+ * If TC for FCoE is above TC3, implying 8 TC mode,
+ * and we need 8 for FCoE, we have to take all queues
+ * in that traffic class for FCoE.
+ */
+ if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3))
+ fcoe_tx_i--;
+ }
#endif /* CONFIG_IXGBE_DCB */
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
- (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
- ixgbe_cache_ring_fdir(adapter);
- else
- ixgbe_cache_ring_rss(adapter);
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
+ ixgbe_cache_ring_fdir(adapter);
+ else
+ ixgbe_cache_ring_rss(adapter);
- fcoe_rx_i = f->mask;
- fcoe_tx_i = f->mask;
- }
- for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) {
- adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i;
- adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i;
- }
- ret = true;
+ fcoe_rx_i = f->mask;
+ fcoe_tx_i = f->mask;
}
- return ret;
+ for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) {
+ adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i;
+ adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i;
+ }
+ return true;
}
#endif /* IXGBE_FCOE */
@@ -4471,65 +4690,55 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
**/
static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
{
- int i;
- int orig_node = adapter->node;
+ int rx = 0, tx = 0, nid = adapter->node;
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *ring = adapter->tx_ring[i];
- if (orig_node == -1) {
- int cur_node = next_online_node(adapter->node);
- if (cur_node == MAX_NUMNODES)
- cur_node = first_online_node;
- adapter->node = cur_node;
- }
- ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ if (nid < 0 || !node_online(nid))
+ nid = first_online_node;
+
+ for (; tx < adapter->num_tx_queues; tx++) {
+ struct ixgbe_ring *ring;
+
+ ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid);
if (!ring)
- ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
+ ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
- goto err_tx_ring_allocation;
+ goto err_allocation;
ring->count = adapter->tx_ring_count;
- ring->queue_index = i;
- ring->numa_node = adapter->node;
+ ring->queue_index = tx;
+ ring->numa_node = nid;
+ ring->dev = &adapter->pdev->dev;
+ ring->netdev = adapter->netdev;
- adapter->tx_ring[i] = ring;
+ adapter->tx_ring[tx] = ring;
}
- /* Restore the adapter's original node */
- adapter->node = orig_node;
+ for (; rx < adapter->num_rx_queues; rx++) {
+ struct ixgbe_ring *ring;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- struct ixgbe_ring *ring = adapter->rx_ring[i];
- if (orig_node == -1) {
- int cur_node = next_online_node(adapter->node);
- if (cur_node == MAX_NUMNODES)
- cur_node = first_online_node;
- adapter->node = cur_node;
- }
- ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid);
if (!ring)
- ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
+ ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
- goto err_rx_ring_allocation;
+ goto err_allocation;
ring->count = adapter->rx_ring_count;
- ring->queue_index = i;
- ring->numa_node = adapter->node;
+ ring->queue_index = rx;
+ ring->numa_node = nid;
+ ring->dev = &adapter->pdev->dev;
+ ring->netdev = adapter->netdev;
- adapter->rx_ring[i] = ring;
+ adapter->rx_ring[rx] = ring;
}
- /* Restore the adapter's original node */
- adapter->node = orig_node;
-
ixgbe_cache_ring_register(adapter);
return 0;
-err_rx_ring_allocation:
- for (i = 0; i < adapter->num_tx_queues; i++)
- kfree(adapter->tx_ring[i]);
-err_tx_ring_allocation:
+err_allocation:
+ while (tx)
+ kfree(adapter->tx_ring[--tx]);
+
+ while (rx)
+ kfree(adapter->rx_ring[--rx]);
return -ENOMEM;
}
@@ -4751,6 +4960,11 @@ err_set_interrupt:
return err;
}
+static void ring_free_rcu(struct rcu_head *head)
+{
+ kfree(container_of(head, struct ixgbe_ring, rcu));
+}
+
/**
* ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
* @adapter: board private structure to clear interrupt scheme on
@@ -4767,10 +4981,18 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
adapter->tx_ring[i] = NULL;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
- kfree(adapter->rx_ring[i]);
+ struct ixgbe_ring *ring = adapter->rx_ring[i];
+
+ /* ixgbe_get_stats64() might access this ring, we must wait
+ * a grace period before freeing it.
+ */
+ call_rcu(&ring->rcu, ring_free_rcu);
adapter->rx_ring[i] = NULL;
}
+ adapter->num_tx_queues = 0;
+ adapter->num_rx_queues = 0;
+
ixgbe_free_q_vectors(adapter);
ixgbe_reset_interrupt_capability(adapter);
}
@@ -4844,6 +5066,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
int j;
struct tc_configuration *tc;
#endif
+ int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
/* PCI config space info */
@@ -4858,11 +5081,14 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
- if (hw->mac.type == ixgbe_mac_82598EB) {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
if (hw->device_id == IXGBE_DEV_ID_82598AT)
adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
- } else if (hw->mac.type == ixgbe_mac_82599EB) {
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
@@ -4891,6 +5117,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->fcoe.up = IXGBE_FCOE_DEFTC;
#endif
#endif /* IXGBE_FCOE */
+ break;
+ default:
+ break;
}
#ifdef CONFIG_IXGBE_DCB
@@ -4920,8 +5149,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
#ifdef CONFIG_DCB
adapter->last_lfc_mode = hw->fc.current_mode;
#endif
- hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
- hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
+ hw->fc.high_water = FC_HIGH_WATER(max_frame);
+ hw->fc.low_water = FC_LOW_WATER(max_frame);
hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
hw->fc.send_xon = true;
hw->fc.disable_fc_autoneg = false;
@@ -4959,30 +5188,27 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/**
* ixgbe_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
* @tx_ring: tx descriptor ring (for a specific queue) to setup
*
* Return 0 on success, negative on failure
**/
-int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct device *dev = tx_ring->dev;
int size;
size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
- tx_ring->tx_buffer_info = vmalloc_node(size, tx_ring->numa_node);
+ tx_ring->tx_buffer_info = vzalloc_node(size, tx_ring->numa_node);
if (!tx_ring->tx_buffer_info)
- tx_ring->tx_buffer_info = vmalloc(size);
+ tx_ring->tx_buffer_info = vzalloc(size);
if (!tx_ring->tx_buffer_info)
goto err;
- memset(tx_ring->tx_buffer_info, 0, size);
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
- tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
+ tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
&tx_ring->dma, GFP_KERNEL);
if (!tx_ring->desc)
goto err;
@@ -4995,7 +5221,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
err:
vfree(tx_ring->tx_buffer_info);
tx_ring->tx_buffer_info = NULL;
- e_err(probe, "Unable to allocate memory for the Tx descriptor ring\n");
+ dev_err(dev, "Unable to allocate memory for the Tx descriptor ring\n");
return -ENOMEM;
}
@@ -5014,7 +5240,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
int i, err = 0;
for (i = 0; i < adapter->num_tx_queues; i++) {
- err = ixgbe_setup_tx_resources(adapter, adapter->tx_ring[i]);
+ err = ixgbe_setup_tx_resources(adapter->tx_ring[i]);
if (!err)
continue;
e_err(probe, "Allocation for Tx Queue %u failed\n", i);
@@ -5026,48 +5252,40 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
/**
* ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
- * @adapter: board private structure
* @rx_ring: rx descriptor ring (for a specific queue) to setup
*
* Returns 0 on success, negative on failure
**/
-int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct device *dev = rx_ring->dev;
int size;
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
- rx_ring->rx_buffer_info = vmalloc_node(size, adapter->node);
+ rx_ring->rx_buffer_info = vzalloc_node(size, rx_ring->numa_node);
if (!rx_ring->rx_buffer_info)
- rx_ring->rx_buffer_info = vmalloc(size);
- if (!rx_ring->rx_buffer_info) {
- e_err(probe, "vmalloc allocation failed for the Rx "
- "descriptor ring\n");
- goto alloc_failed;
- }
- memset(rx_ring->rx_buffer_info, 0, size);
+ rx_ring->rx_buffer_info = vzalloc(size);
+ if (!rx_ring->rx_buffer_info)
+ goto err;
/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
- rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
+ rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
&rx_ring->dma, GFP_KERNEL);
- if (!rx_ring->desc) {
- e_err(probe, "Memory allocation failed for the Rx "
- "descriptor ring\n");
- vfree(rx_ring->rx_buffer_info);
- goto alloc_failed;
- }
+ if (!rx_ring->desc)
+ goto err;
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
return 0;
-
-alloc_failed:
+err:
+ vfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+ dev_err(dev, "Unable to allocate memory for the Rx descriptor ring\n");
return -ENOMEM;
}
@@ -5081,13 +5299,12 @@ alloc_failed:
*
* Return 0 on success, negative on failure
**/
-
static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
{
int i, err = 0;
for (i = 0; i < adapter->num_rx_queues; i++) {
- err = ixgbe_setup_rx_resources(adapter, adapter->rx_ring[i]);
+ err = ixgbe_setup_rx_resources(adapter->rx_ring[i]);
if (!err)
continue;
e_err(probe, "Allocation for Rx Queue %u failed\n", i);
@@ -5099,23 +5316,23 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
/**
* ixgbe_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
* @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
-void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+void ixgbe_free_tx_resources(struct ixgbe_ring *tx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
-
- ixgbe_clean_tx_ring(adapter, tx_ring);
+ ixgbe_clean_tx_ring(tx_ring);
vfree(tx_ring->tx_buffer_info);
tx_ring->tx_buffer_info = NULL;
- dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
- tx_ring->dma);
+ /* if not set, then don't free */
+ if (!tx_ring->desc)
+ return;
+
+ dma_free_coherent(tx_ring->dev, tx_ring->size,
+ tx_ring->desc, tx_ring->dma);
tx_ring->desc = NULL;
}
@@ -5132,28 +5349,28 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
for (i = 0; i < adapter->num_tx_queues; i++)
if (adapter->tx_ring[i]->desc)
- ixgbe_free_tx_resources(adapter, adapter->tx_ring[i]);
+ ixgbe_free_tx_resources(adapter->tx_ring[i]);
}
/**
* ixgbe_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
* @rx_ring: ring to clean the resources from
*
* Free all receive software resources
**/
-void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+void ixgbe_free_rx_resources(struct ixgbe_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
-
- ixgbe_clean_rx_ring(adapter, rx_ring);
+ ixgbe_clean_rx_ring(rx_ring);
vfree(rx_ring->rx_buffer_info);
rx_ring->rx_buffer_info = NULL;
- dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
- rx_ring->dma);
+ /* if not set, then don't free */
+ if (!rx_ring->desc)
+ return;
+
+ dma_free_coherent(rx_ring->dev, rx_ring->size,
+ rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
}
@@ -5170,7 +5387,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++)
if (adapter->rx_ring[i]->desc)
- ixgbe_free_rx_resources(adapter, adapter->rx_ring[i]);
+ ixgbe_free_rx_resources(adapter->rx_ring[i]);
}
/**
@@ -5183,6 +5400,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
/* MTU < 68 is an error and causes problems on some kernels */
@@ -5193,6 +5411,9 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
/* must set new MTU before calling down or up */
netdev->mtu = new_mtu;
+ hw->fc.high_water = FC_HIGH_WATER(max_frame);
+ hw->fc.low_water = FC_LOW_WATER(max_frame);
+
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);
@@ -5288,8 +5509,8 @@ static int ixgbe_close(struct net_device *netdev)
#ifdef CONFIG_PM
static int ixgbe_resume(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
u32 err;
pci_set_power_state(pdev, PCI_D0);
@@ -5320,7 +5541,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
if (netif_running(netdev)) {
- err = ixgbe_open(adapter->netdev);
+ err = ixgbe_open(netdev);
if (err)
return err;
}
@@ -5333,8 +5554,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
u32 ctrl, fctrl;
u32 wufc = adapter->wol;
@@ -5351,6 +5572,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
ixgbe_free_all_rx_resources(adapter);
}
+ ixgbe_clear_interrupt_scheme(adapter);
+
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
if (retval)
@@ -5377,15 +5600,20 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
}
- if (wufc && hw->mac.type == ixgbe_mac_82599EB)
- pci_wake_from_d3(pdev, true);
- else
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
pci_wake_from_d3(pdev, false);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ pci_wake_from_d3(pdev, !!wufc);
+ break;
+ default:
+ break;
+ }
*enable_wake = !!wufc;
- ixgbe_clear_interrupt_scheme(adapter);
-
ixgbe_release_hw_control(adapter);
pci_disable_device(pdev);
@@ -5434,10 +5662,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_hw_stats *hwstats = &adapter->stats;
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
- u64 non_eop_descs = 0, restart_queue = 0;
- struct ixgbe_hw_stats *hwstats = &adapter->stats;
+ u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0;
+ u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0;
+ u64 bytes = 0, packets = 0;
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
@@ -5450,21 +5680,41 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
adapter->hw_rx_no_dma_resources +=
IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
for (i = 0; i < adapter->num_rx_queues; i++) {
- rsc_count += adapter->rx_ring[i]->rsc_count;
- rsc_flush += adapter->rx_ring[i]->rsc_flush;
+ rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count;
+ rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush;
}
adapter->rsc_total_count = rsc_count;
adapter->rsc_total_flush = rsc_flush;
}
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct ixgbe_ring *rx_ring = adapter->rx_ring[i];
+ non_eop_descs += rx_ring->rx_stats.non_eop_descs;
+ alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
+ alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
+ bytes += rx_ring->stats.bytes;
+ packets += rx_ring->stats.packets;
+ }
+ adapter->non_eop_descs = non_eop_descs;
+ adapter->alloc_rx_page_failed = alloc_rx_page_failed;
+ adapter->alloc_rx_buff_failed = alloc_rx_buff_failed;
+ netdev->stats.rx_bytes = bytes;
+ netdev->stats.rx_packets = packets;
+
+ bytes = 0;
+ packets = 0;
/* gather some stats to the adapter struct that are per queue */
- for (i = 0; i < adapter->num_tx_queues; i++)
- restart_queue += adapter->tx_ring[i]->restart_queue;
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+ restart_queue += tx_ring->tx_stats.restart_queue;
+ tx_busy += tx_ring->tx_stats.tx_busy;
+ bytes += tx_ring->stats.bytes;
+ packets += tx_ring->stats.packets;
+ }
adapter->restart_queue = restart_queue;
-
- for (i = 0; i < adapter->num_rx_queues; i++)
- non_eop_descs += adapter->rx_ring[i]->non_eop_descs;
- adapter->non_eop_descs = non_eop_descs;
+ adapter->tx_busy = tx_busy;
+ netdev->stats.tx_bytes = bytes;
+ netdev->stats.tx_packets = packets;
hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
for (i = 0; i < 8; i++) {
@@ -5479,17 +5729,18 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- if (hw->mac.type == ixgbe_mac_82599EB) {
- hwstats->pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
- hwstats->pxoffrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
- hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
- } else {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
hwstats->pxonrxc[i] +=
IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
- hwstats->pxoffrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ hwstats->pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
+ break;
+ default:
+ break;
}
hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
@@ -5498,21 +5749,25 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
/* work around hardware counting issue */
hwstats->gprc -= missed_rx;
+ ixgbe_update_xoff_received(adapter);
+
/* 82598 hardware only has a 32 bit counter in the high register */
- if (hw->mac.type == ixgbe_mac_82599EB) {
- u64 tmp;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+ hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF;
- /* 4 high bits of GORC */
- hwstats->gorc += (tmp << 32);
+ IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF;
- /* 4 high bits of GOTC */
- hwstats->gotc += (tmp << 32);
+ IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL);
- IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+ IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
- hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
#ifdef IXGBE_FCOE
@@ -5523,12 +5778,9 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
#endif /* IXGBE_FCOE */
- } else {
- hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ break;
+ default:
+ break;
}
bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
hwstats->bprc += bprc;
@@ -5701,8 +5953,8 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work)
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++)
- set_bit(__IXGBE_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->reinit_state));
+ set_bit(__IXGBE_TX_FDIR_INIT_DONE,
+ &(adapter->tx_ring[i]->state));
} else {
e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n");
@@ -5711,6 +5963,26 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work)
netif_tx_start_all_queues(adapter->netdev);
}
+static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
+{
+ u32 ssvpc;
+
+ /* Do not perform spoof check for 82598 */
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ return;
+
+ ssvpc = IXGBE_READ_REG(&adapter->hw, IXGBE_SSVPC);
+
+ /*
+ * ssvpc register is cleared on read, if zero then no
+ * spoofed packets in the last interval.
+ */
+ if (!ssvpc)
+ return;
+
+ e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
+}
+
static DEFINE_MUTEX(ixgbe_watchdog_lock);
/**
@@ -5764,17 +6036,27 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (!netif_carrier_ok(netdev)) {
bool flow_rx, flow_tx;
- if (hw->mac.type == ixgbe_mac_82599EB) {
- u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
- flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
- flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
- } else {
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB: {
u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
}
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540: {
+ u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
+ flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
+ }
+ break;
+ default:
+ flow_tx = false;
+ flow_rx = false;
+ break;
+ }
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
@@ -5788,7 +6070,10 @@ static void ixgbe_watchdog_task(struct work_struct *work)
netif_carrier_on(netdev);
} else {
/* Force detection of hung controller */
- adapter->detect_tx_hung = true;
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ tx_ring = adapter->tx_ring[i];
+ set_check_for_tx_hang(tx_ring);
+ }
}
} else {
adapter->link_up = false;
@@ -5818,6 +6103,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
}
}
+ ixgbe_spoof_check(adapter);
ixgbe_update_stats(adapter);
mutex_unlock(&ixgbe_watchdog_lock);
}
@@ -6000,15 +6286,17 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring,
struct sk_buff *skb, u32 tx_flags,
- unsigned int first)
+ unsigned int first, const u8 hdr_len)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct device *dev = tx_ring->dev;
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned int len;
unsigned int total = skb->len;
unsigned int offset = 0, size, count = 0, i;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
+ unsigned int bytecount = skb->len;
+ u16 gso_segs = 1;
i = tx_ring->next_to_use;
@@ -6023,10 +6311,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
tx_buffer_info->length = size;
tx_buffer_info->mapped_as_page = false;
- tx_buffer_info->dma = dma_map_single(&pdev->dev,
+ tx_buffer_info->dma = dma_map_single(dev,
skb->data + offset,
size, DMA_TO_DEVICE);
- if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma))
+ if (dma_mapping_error(dev, tx_buffer_info->dma))
goto dma_error;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -6059,12 +6347,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
tx_buffer_info->length = size;
- tx_buffer_info->dma = dma_map_page(&adapter->pdev->dev,
+ tx_buffer_info->dma = dma_map_page(dev,
frag->page,
offset, size,
DMA_TO_DEVICE);
tx_buffer_info->mapped_as_page = true;
- if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma))
+ if (dma_mapping_error(dev, tx_buffer_info->dma))
goto dma_error;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -6078,6 +6366,19 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
break;
}
+ if (tx_flags & IXGBE_TX_FLAGS_TSO)
+ gso_segs = skb_shinfo(skb)->gso_segs;
+#ifdef IXGBE_FCOE
+ /* adjust for FCoE Sequence Offload */
+ else if (tx_flags & IXGBE_TX_FLAGS_FSO)
+ gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
+ skb_shinfo(skb)->gso_size);
+#endif /* IXGBE_FCOE */
+ bytecount += (gso_segs - 1) * hdr_len;
+
+ /* multiply data chunks by size of headers */
+ tx_ring->tx_buffer_info[i].bytecount = bytecount;
+ tx_ring->tx_buffer_info[i].gso_segs = gso_segs;
tx_ring->tx_buffer_info[i].skb = skb;
tx_ring->tx_buffer_info[first].next_to_watch = i;
@@ -6099,14 +6400,13 @@ dma_error:
i += tx_ring->count;
i--;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+ ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
}
return 0;
}
-static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
+static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring,
int tx_flags, int count, u32 paylen, u8 hdr_len)
{
union ixgbe_adv_tx_desc *tx_desc = NULL;
@@ -6171,60 +6471,46 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
wmb();
tx_ring->next_to_use = i;
- writel(i, adapter->hw.hw_addr + tx_ring->tail);
+ writel(i, tx_ring->tail);
}
static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
- int queue, u32 tx_flags, __be16 protocol)
+ u8 queue, u32 tx_flags, __be16 protocol)
{
struct ixgbe_atr_input atr_input;
- struct tcphdr *th;
struct iphdr *iph = ip_hdr(skb);
struct ethhdr *eth = (struct ethhdr *)skb->data;
- u16 vlan_id, src_port, dst_port, flex_bytes;
- u32 src_ipv4_addr, dst_ipv4_addr;
- u8 l4type = 0;
+ struct tcphdr *th;
+ u16 vlan_id;
- /* Right now, we support IPv4 only */
- if (protocol != htons(ETH_P_IP))
- return;
- /* check if we're UDP or TCP */
- if (iph->protocol == IPPROTO_TCP) {
- th = tcp_hdr(skb);
- src_port = th->source;
- dst_port = th->dest;
- l4type |= IXGBE_ATR_L4TYPE_TCP;
- /* l4type IPv4 type is 0, no need to assign */
- } else {
- /* Unsupported L4 header, just bail here */
+ /* Right now, we support IPv4 w/ TCP only */
+ if (protocol != htons(ETH_P_IP) ||
+ iph->protocol != IPPROTO_TCP)
return;
- }
memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >>
IXGBE_TX_FLAGS_VLAN_SHIFT;
- src_ipv4_addr = iph->saddr;
- dst_ipv4_addr = iph->daddr;
- flex_bytes = eth->h_proto;
+
+ th = tcp_hdr(skb);
ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id);
- ixgbe_atr_set_src_port_82599(&atr_input, dst_port);
- ixgbe_atr_set_dst_port_82599(&atr_input, src_port);
- ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes);
- ixgbe_atr_set_l4type_82599(&atr_input, l4type);
+ ixgbe_atr_set_src_port_82599(&atr_input, th->dest);
+ ixgbe_atr_set_dst_port_82599(&atr_input, th->source);
+ ixgbe_atr_set_flex_byte_82599(&atr_input, eth->h_proto);
+ ixgbe_atr_set_l4type_82599(&atr_input, IXGBE_ATR_L4TYPE_TCP);
/* src and dst are inverted, think how the receiver sees them */
- ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr);
- ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr);
+ ixgbe_atr_set_src_ipv4_82599(&atr_input, iph->daddr);
+ ixgbe_atr_set_dst_ipv4_82599(&atr_input, iph->saddr);
/* This assumes the Rx queue and Tx queue are bound to the same CPU */
ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue);
}
-static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size)
{
- netif_stop_subqueue(netdev, tx_ring->queue_index);
+ netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
/* Herbert's original patch had:
* smp_mb__after_netif_stop_queue();
* but since that doesn't exist yet, just open code it. */
@@ -6236,17 +6522,16 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
return -EBUSY;
/* A reprieve! - use start_queue because it doesn't call schedule */
- netif_start_subqueue(netdev, tx_ring->queue_index);
- ++tx_ring->restart_queue;
+ netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
+ ++tx_ring->tx_stats.restart_queue;
return 0;
}
-static int ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size)
{
if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
return 0;
- return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
+ return __ixgbe_maybe_stop_tx(tx_ring, size);
}
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
@@ -6291,10 +6576,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
return skb_tx_hash(dev, skb);
}
-netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev,
+netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring)
{
+ struct net_device *netdev = tx_ring->netdev;
struct netdev_queue *txq;
unsigned int first;
unsigned int tx_flags = 0;
@@ -6352,8 +6638,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
- if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
- adapter->tx_busy++;
+ if (ixgbe_maybe_stop_tx(tx_ring, count)) {
+ tx_ring->tx_stats.tx_busy++;
return NETDEV_TX_BUSY;
}
@@ -6387,14 +6673,14 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
tx_flags |= IXGBE_TX_FLAGS_CSUM;
}
- count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first);
+ count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first, hdr_len);
if (count) {
/* add the ATR filter if ATR is on */
if (tx_ring->atr_sample_rate) {
++tx_ring->atr_count;
if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
- test_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state)) {
+ test_bit(__IXGBE_TX_FDIR_INIT_DONE,
+ &tx_ring->state)) {
ixgbe_atr(adapter, skb, tx_ring->queue_index,
tx_flags, protocol);
tx_ring->atr_count = 0;
@@ -6403,9 +6689,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
txq = netdev_get_tx_queue(netdev, tx_ring->queue_index);
txq->tx_bytes += skb->len;
txq->tx_packets++;
- ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
- hdr_len);
- ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+ ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len);
+ ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
} else {
dev_kfree_skb_any(skb);
@@ -6422,7 +6707,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netd
struct ixgbe_ring *tx_ring;
tx_ring = adapter->tx_ring[skb->queue_mapping];
- return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring);
+ return ixgbe_xmit_frame_ring(skb, adapter, tx_ring);
}
/**
@@ -6563,20 +6848,23 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
/* accurate rx/tx bytes/packets stats */
dev_txq_stats_fold(netdev, stats);
+ rcu_read_lock();
for (i = 0; i < adapter->num_rx_queues; i++) {
- struct ixgbe_ring *ring = adapter->rx_ring[i];
+ struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]);
u64 bytes, packets;
unsigned int start;
- do {
- start = u64_stats_fetch_begin_bh(&ring->syncp);
- packets = ring->stats.packets;
- bytes = ring->stats.bytes;
- } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
- stats->rx_packets += packets;
- stats->rx_bytes += bytes;
+ if (ring) {
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->syncp);
+ packets = ring->stats.packets;
+ bytes = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
+ stats->rx_packets += packets;
+ stats->rx_bytes += bytes;
+ }
}
-
+ rcu_read_unlock();
/* following stats updated by ixgbe_watchdog_task() */
stats->multicast = netdev->stats.multicast;
stats->rx_errors = netdev->stats.rx_errors;
@@ -6625,7 +6913,7 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
struct ixgbe_hw *hw = &adapter->hw;
int err;
- if (hw->mac.type != ixgbe_mac_82599EB || !max_vfs)
+ if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
return;
/* The 82599 supports up to 64 VFs per physical function
@@ -6691,11 +6979,12 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
static int cards_found;
int i, err, pci_using_dac;
+ u8 part_str[IXGBE_PBANUM_LENGTH];
unsigned int indices = num_possible_cpus();
#ifdef IXGBE_FCOE
u16 device_caps;
#endif
- u32 part_num, eec;
+ u32 eec;
/* Catch broken hardware that put the wrong VF device ID in
* the PCIe SR-IOV capability.
@@ -6758,8 +7047,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
SET_NETDEV_DEV(netdev, &pdev->dev);
- pci_set_drvdata(pdev, netdev);
adapter = netdev_priv(netdev);
+ pci_set_drvdata(pdev, adapter);
adapter->netdev = netdev;
adapter->pdev = pdev;
@@ -6782,7 +7071,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->netdev_ops = &ixgbe_netdev_ops;
ixgbe_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
adapter->bd_number = cards_found;
@@ -6832,8 +7121,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_sw_init;
/* Make it possible the adapter to be woken up via WOL */
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
+ break;
+ default:
+ break;
+ }
/*
* If there is a fan on this device and it has failed log the
@@ -6941,8 +7236,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_eeprom;
}
- /* power down the optics */
- if (hw->phy.multispeed_fiber)
+ /* power down the optics for multispeed fiber and 82599 SFP+ fiber */
+ if (hw->mac.ops.disable_tx_laser &&
+ ((hw->phy.multispeed_fiber) ||
+ ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ (hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw);
init_timer(&adapter->watchdog_timer);
@@ -6957,6 +7255,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_sw_init;
switch (pdev->device) {
+ case IXGBE_DEV_ID_82599_SFP:
+ /* Only this subdevice supports WOL */
+ if (pdev->subsystem_device == IXGBE_SUBDEV_ID_82599_SFP)
+ adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
+ IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+ break;
+ case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+ /* All except this subdevice support WOL */
+ if (pdev->subsystem_device != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ)
+ adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
+ IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+ break;
case IXGBE_DEV_ID_82599_KX4:
adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
IXGBE_WUFC_MC | IXGBE_WUFC_BC);
@@ -6980,16 +7290,17 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" :
"Unknown"),
netdev->dev_addr);
- ixgbe_read_pba_num_generic(hw, &part_num);
+
+ err = ixgbe_read_pba_string_generic(hw, part_str, IXGBE_PBANUM_LENGTH);
+ if (err)
+ strncpy(part_str, "Unknown", IXGBE_PBANUM_LENGTH);
if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
- e_dev_info("MAC: %d, PHY: %d, SFP+: %d, "
- "PBA No: %06x-%03x\n",
+ e_dev_info("MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n",
hw->mac.type, hw->phy.type, hw->phy.sfp_type,
- (part_num >> 8), (part_num & 0xff));
+ part_str);
else
- e_dev_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type,
- (part_num >> 8), (part_num & 0xff));
+ e_dev_info("MAC: %d, PHY: %d, PBA No: %s\n",
+ hw->mac.type, hw->phy.type, part_str);
if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
e_dev_warn("PCI-Express bandwidth available for this card is "
@@ -7082,17 +7393,19 @@ err_dma:
**/
static void __devexit ixgbe_remove(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
set_bit(__IXGBE_DOWN, &adapter->state);
- /* clear the module not found bit to make sure the worker won't
- * reschedule
+
+ /*
+ * The timers may be rescheduled, so explicitly disable them
+ * from being rescheduled.
*/
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->watchdog_timer);
-
del_timer_sync(&adapter->sfp_timer);
+
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->sfp_task);
cancel_work_sync(&adapter->multispeed_fiber_task);
@@ -7100,7 +7413,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
- flush_scheduled_work();
+ if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
+ cancel_work_sync(&adapter->check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
@@ -7153,8 +7467,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev);
@@ -7177,8 +7491,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
*/
static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
pci_ers_result_t result;
int err;
@@ -7216,8 +7529,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
*/
static void ixgbe_io_resume(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
if (netif_running(netdev)) {
if (ixgbe_up(adapter)) {
@@ -7282,6 +7595,7 @@ static void __exit ixgbe_exit_module(void)
dca_unregister_notify(&dca_notifier);
#endif
pci_unregister_driver(&ixgbe_driver);
+ rcu_barrier(); /* Wait for completion of call_rcu()'s */
}
#ifdef CONFIG_IXGBE_DCA
diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c
index 471f0f2cdb98..ea82c5a1cd3e 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ixgbe/ixgbe_mbx.c
@@ -319,8 +319,16 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
u32 vflre = 0;
s32 ret_val = IXGBE_ERR_MBX;
- if (hw->mac.type == ixgbe_mac_82599EB)
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
+ break;
+ case ixgbe_mac_X540:
+ vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
+ break;
+ default:
+ break;
+ }
if (vflre & (1 << vf_shift)) {
ret_val = 0;
@@ -439,22 +447,26 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- if (hw->mac.type != ixgbe_mac_82599EB)
- return;
-
- mbx->timeout = 0;
- mbx->usec_delay = 0;
-
- mbx->size = IXGBE_VFMAILBOX_SIZE;
-
- mbx->stats.msgs_tx = 0;
- mbx->stats.msgs_rx = 0;
- mbx->stats.reqs = 0;
- mbx->stats.acks = 0;
- mbx->stats.rsts = 0;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ mbx->timeout = 0;
+ mbx->usec_delay = 0;
+
+ mbx->size = IXGBE_VFMAILBOX_SIZE;
+
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+ break;
+ default:
+ break;
+ }
}
-struct ixgbe_mbx_operations mbx_ops_82599 = {
+struct ixgbe_mbx_operations mbx_ops_generic = {
.read = ixgbe_read_mbx_pf,
.write = ixgbe_write_mbx_pf,
.read_posted = ixgbe_read_posted_mbx,
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index 7e0d08ff5b53..3df9b1590218 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -88,6 +88,6 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
-extern struct ixgbe_mbx_operations mbx_ops_82599;
+extern struct ixgbe_mbx_operations mbx_ops_generic;
#endif /* _IXGBE_MBX_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 6c0d42e33f21..8f7123e8fc0a 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -115,6 +115,9 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
case TN1010_PHY_ID:
phy_type = ixgbe_phy_tn;
break;
+ case X540_PHY_ID:
+ phy_type = ixgbe_phy_aq;
+ break;
case QT2022_PHY_ID:
phy_type = ixgbe_phy_qt;
break;
@@ -425,6 +428,39 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
}
/**
+ * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: boolean auto-negotiation value
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ */
+s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
+{
+ s32 status = IXGBE_ERR_LINK_SETUP;
+ u16 speed_ability;
+
+ *speed = 0;
+ *autoneg = true;
+
+ status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
+ &speed_ability);
+
+ if (status == 0) {
+ if (speed_ability & MDIO_SPEED_10G)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (speed_ability & MDIO_PMA_SPEED_1000)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ if (speed_ability & MDIO_PMA_SPEED_100)
+ *speed |= IXGBE_LINK_SPEED_100_FULL;
+ }
+
+ return status;
+}
+
+/**
* ixgbe_reset_phy_nl - Performs a PHY reset
* @hw: pointer to hardware structure
**/
@@ -1378,6 +1414,22 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
}
/**
+ * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
+ * @hw: pointer to hardware structure
+ * @firmware_version: pointer to the PHY Firmware Version
+**/
+s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
+ u16 *firmware_version)
+{
+ s32 status = 0;
+
+ status = hw->phy.ops.read_reg(hw, AQ_FW_REV, MDIO_MMD_VEND1,
+ firmware_version);
+
+ return status;
+}
+
+/**
* ixgbe_tn_check_overtemp - Checks if an overtemp occured.
* @hw: pointer to hardware structure
*
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index fb3898f12fc5..e2c6b7eac641 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -96,6 +96,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete);
+s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
/* PHY specific */
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
@@ -103,6 +106,8 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
bool *link_up);
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
u16 *firmware_version);
+s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
+ u16 *firmware_version);
s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 5428153af8f3..47b15738b009 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -68,7 +68,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
* addresses
*/
for (i = 0; i < entries; i++) {
- vfinfo->vf_mc_hashes[i] = hash_list[i];;
+ vfinfo->vf_mc_hashes[i] = hash_list[i];
}
for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) {
@@ -178,8 +178,7 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
{
unsigned char vf_mac_addr[6];
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
unsigned int vfn = (event_mask & 0x3f);
bool enable = ((event_mask & 0x10000000U) != 0);
@@ -216,6 +215,11 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
reg |= (reg | (1 << vf_shift));
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg);
+ /* Enable counting of spoofed packets in the SSVPC register */
+ reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset));
+ reg |= (1 << vf_shift);
+ IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg);
+
ixgbe_vf_reset_event(adapter, vf);
}
@@ -228,6 +232,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
int entries;
u16 *hash_list;
int add, vid;
+ u8 *new_mac;
retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -245,15 +250,22 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
if (msgbuf[0] == IXGBE_VF_RESET) {
unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses;
- u8 *addr = (u8 *)(&msgbuf[1]);
+ new_mac = (u8 *)(&msgbuf[1]);
e_info(probe, "VF Reset msg received from vf %d\n", vf);
adapter->vfinfo[vf].clear_to_send = false;
ixgbe_vf_reset_msg(adapter, vf);
adapter->vfinfo[vf].clear_to_send = true;
+ if (is_valid_ether_addr(new_mac) &&
+ !adapter->vfinfo[vf].pf_set_mac)
+ ixgbe_set_vf_mac(adapter, vf, vf_mac);
+ else
+ ixgbe_set_vf_mac(adapter,
+ vf, adapter->vfinfo[vf].vf_mac_addresses);
+
/* reply to reset with ack and vf mac address */
msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK;
- memcpy(addr, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS);
+ memcpy(new_mac, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS);
/*
* Piggyback the multicast filter type so VF can compute the
* correct vectors
@@ -272,14 +284,16 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
switch ((msgbuf[0] & 0xFFFF)) {
case IXGBE_VF_SET_MAC_ADDR:
- {
- u8 *new_mac = ((u8 *)(&msgbuf[1]));
- if (is_valid_ether_addr(new_mac) &&
- !adapter->vfinfo[vf].pf_set_mac)
- ixgbe_set_vf_mac(adapter, vf, new_mac);
- else
- ixgbe_set_vf_mac(adapter,
- vf, adapter->vfinfo[vf].vf_mac_addresses);
+ new_mac = ((u8 *)(&msgbuf[1]));
+ if (is_valid_ether_addr(new_mac) &&
+ !adapter->vfinfo[vf].pf_set_mac) {
+ ixgbe_set_vf_mac(adapter, vf, new_mac);
+ } else if (memcmp(adapter->vfinfo[vf].vf_mac_addresses,
+ new_mac, ETH_ALEN)) {
+ e_warn(drv, "VF %d attempted to override "
+ "administratively set MAC address\nReload "
+ "the VF driver to resume operations\n", vf);
+ retval = -1;
}
break;
case IXGBE_VF_SET_MULTICAST:
@@ -296,7 +310,15 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK)
>> IXGBE_VT_MSGINFO_SHIFT;
vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
- retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
+ if (adapter->vfinfo[vf].pf_vlan) {
+ e_warn(drv, "VF %d attempted to override "
+ "administratively set VLAN configuration\n"
+ "Reload the VF driver to resume operations\n",
+ vf);
+ retval = -1;
+ } else {
+ retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
+ }
break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
@@ -395,6 +417,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
{
int err = 0;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
return -EINVAL;
@@ -403,7 +426,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
if (err)
goto out;
ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
- ixgbe_set_vmolr(&adapter->hw, vf, false);
+ ixgbe_set_vmolr(hw, vf, false);
+ hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
adapter->vfinfo[vf].pf_vlan = vlan;
adapter->vfinfo[vf].pf_qos = qos;
dev_info(&adapter->pdev->dev,
@@ -420,7 +444,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
err = ixgbe_set_vf_vlan(adapter, false,
adapter->vfinfo[vf].pf_vlan, vf);
ixgbe_set_vmvir(adapter, vlan, vf);
- ixgbe_set_vmolr(&adapter->hw, vf, true);
+ ixgbe_set_vmolr(hw, vf, true);
+ hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
adapter->vfinfo[vf].pf_vlan = 0;
adapter->vfinfo[vf].pf_qos = 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index d3cc6ce7c973..446f3467d3c7 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -54,9 +54,14 @@
#define IXGBE_DEV_ID_82599_T3_LOM 0x151C
#define IXGBE_DEV_ID_82599_CX4 0x10F9
#define IXGBE_DEV_ID_82599_SFP 0x10FB
+#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152a
+#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
+#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
+#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
+#define IXGBE_DEV_ID_X540T 0x1528
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -225,6 +230,7 @@
#define IXGBE_VT_CTL 0x051B0
#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
+#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4))
#define IXGBE_QDE 0x2F04
#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
@@ -279,7 +285,8 @@
#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
#define IXGBE_DTXCTL 0x07E00
-#define IXGBE_DMATXCTL 0x04A80
+#define IXGBE_DMATXCTL 0x04A80
+#define IXGBE_PFVFSPOOF(_i) (0x08200 + ((_i) * 4)) /* 8 of these 0 - 7 */
#define IXGBE_PFDTXGSWC 0x08220
#define IXGBE_DTXMXSZRQ 0x08100
#define IXGBE_DTXTCPFLGL 0x04A88
@@ -293,6 +300,13 @@
#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */
#define IXGBE_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */
+
+/* Anti-spoofing defines */
+#define IXGBE_SPOOF_MACAS_MASK 0xFF
+#define IXGBE_SPOOF_VLANAS_MASK 0xFF00
+#define IXGBE_SPOOF_VLANAS_SHIFT 8
+#define IXGBE_PFVFSPOOF_REG_COUNT 8
+
#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
/* Tx DCA Control register : 128 of these (0-127) */
#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40))
@@ -994,8 +1008,10 @@
/* PHY IDs*/
#define TN1010_PHY_ID 0x00A19410
#define TNX_FW_REV 0xB
+#define X540_PHY_ID 0x01540200
#define QT2022_PHY_ID 0x0043A400
#define ATH_PHY_ID 0x03429050
+#define AQ_FW_REV 0x20
/* PHY Types */
#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
@@ -1463,6 +1479,8 @@
#define IXGBE_ANLP1_PAUSE 0x0C00
#define IXGBE_ANLP1_SYM_PAUSE 0x0400
#define IXGBE_ANLP1_ASM_PAUSE 0x0800
+#define IXGBE_ANLP1_AN_STATE_MASK 0x000f0000
+
/* SW Semaphore Register bitmasks */
#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
@@ -1491,6 +1509,7 @@
#define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */
#define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */
#define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */
+#define IXGBE_EEC_SEC1VAL 0x02000000 /* Sector 1 Valid */
#define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */
/* EEPROM Addressing bits based on type (0-small, 1-large) */
#define IXGBE_EEC_ADDR_SIZE 0x00000400
@@ -1500,12 +1519,18 @@
#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6
#define IXGBE_EEPROM_OPCODE_BITS 8
+/* Part Number String Length */
+#define IXGBE_PBANUM_LENGTH 11
+
/* Checksum and EEPROM pointers */
+#define IXGBE_PBANUM_PTR_GUARD 0xFAFA
#define IXGBE_EEPROM_CHECKSUM 0x3F
#define IXGBE_EEPROM_SUM 0xBABA
#define IXGBE_PCIE_ANALOG_PTR 0x03
#define IXGBE_ATLAS0_CONFIG_PTR 0x04
+#define IXGBE_PHY_PTR 0x04
#define IXGBE_ATLAS1_CONFIG_PTR 0x05
+#define IXGBE_OPTION_ROM_PTR 0x05
#define IXGBE_PCIE_GENERAL_PTR 0x06
#define IXGBE_PCIE_CONFIG0_PTR 0x07
#define IXGBE_PCIE_CONFIG1_PTR 0x08
@@ -2113,6 +2138,14 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
+/* Flow Control Macros */
+#define PAUSE_RTT 8
+#define PAUSE_MTU(MTU) ((MTU + 1024 - 1) / 1024)
+
+#define FC_HIGH_WATER(MTU) ((((PAUSE_RTT + PAUSE_MTU(MTU)) * 144) + 99) / 100 +\
+ PAUSE_MTU(MTU))
+#define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT))
+
/* Software ATR hash keys */
#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D
#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17
@@ -2164,6 +2197,7 @@ struct ixgbe_atr_input_masks {
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
ixgbe_eeprom_spi,
+ ixgbe_flash,
ixgbe_eeprom_none /* No NVM support */
};
@@ -2171,12 +2205,14 @@ enum ixgbe_mac_type {
ixgbe_mac_unknown = 0,
ixgbe_mac_82598EB,
ixgbe_mac_82599EB,
+ ixgbe_mac_X540,
ixgbe_num_macs
};
enum ixgbe_phy_type {
ixgbe_phy_unknown = 0,
ixgbe_phy_tn,
+ ixgbe_phy_aq,
ixgbe_phy_cu_unknown,
ixgbe_phy_qt,
ixgbe_phy_xaui,
@@ -2405,6 +2441,7 @@ struct ixgbe_eeprom_operations {
s32 (*write)(struct ixgbe_hw *, u16, u16);
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
s32 (*update_checksum)(struct ixgbe_hw *);
+ u16 (*calc_checksum)(struct ixgbe_hw *);
};
struct ixgbe_mac_operations {
@@ -2454,6 +2491,8 @@ struct ixgbe_mac_operations {
s32 (*clear_vfta)(struct ixgbe_hw *);
s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
s32 (*init_uta_tables)(struct ixgbe_hw *);
+ void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
+ void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);
/* Flow Control */
s32 (*fc_enable)(struct ixgbe_hw *, s32);
@@ -2574,6 +2613,7 @@ struct ixgbe_hw {
u16 subsystem_vendor_id;
u8 revision_id;
bool adapter_stopped;
+ bool force_full_reset;
};
struct ixgbe_info {
@@ -2614,6 +2654,9 @@ struct ixgbe_info {
#define IXGBE_ERR_NO_SPACE -25
#define IXGBE_ERR_OVERTEMP -26
#define IXGBE_ERR_RAR_INDEX -27
+#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30
+#define IXGBE_ERR_PBA_SECTION -31
+#define IXGBE_ERR_INVALID_ARGUMENT -32
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c
new file mode 100644
index 000000000000..3a8923993ce3
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_x540.c
@@ -0,0 +1,724 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2010 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include "ixgbe.h"
+#include "ixgbe_phy.h"
+//#include "ixgbe_mbx.h"
+
+#define IXGBE_X540_MAX_TX_QUEUES 128
+#define IXGBE_X540_MAX_RX_QUEUES 128
+#define IXGBE_X540_RAR_ENTRIES 128
+#define IXGBE_X540_MC_TBL_SIZE 128
+#define IXGBE_X540_VFT_TBL_SIZE 128
+
+static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
+static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
+static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
+static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
+static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
+static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
+
+static enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
+{
+ return ixgbe_media_type_copper;
+}
+
+static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy_generic(hw);
+
+ mac->mcft_size = IXGBE_X540_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_X540_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ **/
+static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ return hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
+}
+
+/**
+ * ixgbe_reset_hw_X540 - Perform hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks
+ * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ * reset.
+ **/
+static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
+{
+ ixgbe_link_speed link_speed;
+ s32 status = 0;
+ u32 ctrl;
+ u32 ctrl_ext;
+ u32 reset_bit;
+ u32 i;
+ u32 autoc;
+ u32 autoc2;
+ bool link_up = false;
+
+ /* Call adapter stop to disable tx/rx and clear interrupts */
+ hw->mac.ops.stop_adapter(hw);
+
+ /*
+ * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+ * access and verify no pending requests before reset
+ */
+ status = ixgbe_disable_pcie_master(hw);
+ if (status != 0) {
+ status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+ }
+
+ /*
+ * Issue global reset to the MAC. Needs to be SW reset if link is up.
+ * If link reset is used when link is up, it might reset the PHY when
+ * mng is using it. If link is down or the flag to force full link
+ * reset is set, then perform link reset.
+ */
+ if (hw->force_full_reset) {
+ reset_bit = IXGBE_CTRL_LNK_RST;
+ } else {
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+ if (!link_up)
+ reset_bit = IXGBE_CTRL_LNK_RST;
+ else
+ reset_bit = IXGBE_CTRL_RST;
+ }
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Poll for reset bit to self-clear indicating reset is complete */
+ for (i = 0; i < 10; i++) {
+ udelay(1);
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ if (!(ctrl & IXGBE_CTRL_RST))
+ break;
+ }
+ if (ctrl & IXGBE_CTRL_RST) {
+ status = IXGBE_ERR_RESET_FAILED;
+ hw_dbg(hw, "Reset polling failed to complete.\n");
+ }
+
+ /* Clear PF Reset Done bit so PF/VF Mail Ops can work */
+ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+ ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+ msleep(50);
+
+ /* Set the Rx packet buffer size. */
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
+
+ /* Store the permanent mac address */
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+ /*
+ * Store the original AUTOC/AUTOC2 values if they have not been
+ * stored off yet. Otherwise restore the stored original
+ * values since the reset operation sets back to defaults.
+ */
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ if (hw->mac.orig_link_settings_stored == false) {
+ hw->mac.orig_autoc = autoc;
+ hw->mac.orig_autoc2 = autoc2;
+ hw->mac.orig_link_settings_stored = true;
+ } else {
+ if (autoc != hw->mac.orig_autoc)
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
+ IXGBE_AUTOC_AN_RESTART));
+
+ if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
+ (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
+ autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
+ autoc2 |= (hw->mac.orig_autoc2 &
+ IXGBE_AUTOC2_UPPER_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+ }
+ }
+
+ /*
+ * Store MAC address from RAR0, clear receive address registers, and
+ * clear the multicast table. Also reset num_rar_entries to 128,
+ * since we modify this value when programming the SAN MAC address.
+ */
+ hw->mac.num_rar_entries = 128;
+ hw->mac.ops.init_rx_addrs(hw);
+
+ /* Store the permanent mac address */
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+ /* Store the permanent SAN mac address */
+ hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
+
+ /* Add the SAN MAC address to the RAR only if it's a valid address */
+ if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
+ hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
+ hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+ /* Reserve the last RAR for the SAN MAC address */
+ hw->mac.num_rar_entries--;
+ }
+
+ /* Store the alternative WWNN/WWPN prefix */
+ hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
+ &hw->mac.wwpn_prefix);
+
+ return status;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
+{
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u16 ext_ability = 0;
+
+ hw->phy.ops.identify(hw);
+
+ hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+ &ext_ability);
+ if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+
+ return physical_layer;
+}
+
+/**
+ * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
+ * @hw: pointer to hardware structure
+ **/
+static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
+{
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ u32 eec;
+ u16 eeprom_size;
+
+ if (eeprom->type == ixgbe_eeprom_uninitialized) {
+ eeprom->semaphore_delay = 10;
+ eeprom->type = ixgbe_flash;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
+ IXGBE_EEC_SIZE_SHIFT);
+ eeprom->word_size = 1 << (eeprom_size +
+ IXGBE_EEPROM_WORD_SIZE_SHIFT);
+
+ hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
+ eeprom->type, eeprom->word_size);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_eerd_X540 - Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EERPOM
+ **/
+static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
+{
+ s32 status;
+
+ if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0)
+ status = ixgbe_read_eerd_generic(hw, offset, data);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
+
+ ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
+
+/**
+ * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ u32 eewr;
+ s32 status;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ (data << IXGBE_EEPROM_RW_REG_DATA) |
+ IXGBE_EEPROM_RW_REG_START;
+
+ if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0) {
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
+ } else {
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+out:
+ ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
+
+/**
+ * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
+ * @hw: pointer to hardware structure
+ **/
+static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
+{
+ u16 i;
+ u16 j;
+ u16 checksum = 0;
+ u16 length = 0;
+ u16 pointer = 0;
+ u16 word = 0;
+
+ /* Include 0x0-0x3F in the checksum */
+ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
+ if (hw->eeprom.ops.read(hw, i, &word) != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ break;
+ }
+ checksum += word;
+ }
+
+ /*
+ * Include all data from pointers 0x3, 0x6-0xE. This excludes the
+ * FW, PHY module, and PCIe Expansion/Option ROM pointers.
+ */
+ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
+ if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
+ continue;
+
+ if (hw->eeprom.ops.read(hw, i, &pointer) != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ break;
+ }
+
+ /* Skip pointer section if the pointer is invalid. */
+ if (pointer == 0xFFFF || pointer == 0 ||
+ pointer >= hw->eeprom.word_size)
+ continue;
+
+ if (hw->eeprom.ops.read(hw, pointer, &length) != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ break;
+ }
+
+ /* Skip pointer section if length is invalid. */
+ if (length == 0xFFFF || length == 0 ||
+ (pointer + length) >= hw->eeprom.word_size)
+ continue;
+
+ for (j = pointer+1; j <= pointer+length; j++) {
+ if (hw->eeprom.ops.read(hw, j, &word) != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ break;
+ }
+ checksum += word;
+ }
+ }
+
+ checksum = (u16)IXGBE_EEPROM_SUM - checksum;
+
+ return checksum;
+}
+
+/**
+ * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
+ * @hw: pointer to hardware structure
+ *
+ * After writing EEPROM to shadow RAM using EEWR register, software calculates
+ * checksum and updates the EEPROM and instructs the hardware to update
+ * the flash.
+ **/
+static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ status = ixgbe_update_eeprom_checksum_generic(hw);
+
+ if (status)
+ status = ixgbe_update_flash_X540(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
+ * @hw: pointer to hardware structure
+ *
+ * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
+ * EEPROM from shadow RAM to the flash device.
+ **/
+static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
+{
+ u32 flup;
+ s32 status = IXGBE_ERR_EEPROM;
+
+ status = ixgbe_poll_flash_update_done_X540(hw);
+ if (status == IXGBE_ERR_EEPROM) {
+ hw_dbg(hw, "Flash update time out\n");
+ goto out;
+ }
+
+ flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
+
+ status = ixgbe_poll_flash_update_done_X540(hw);
+ if (status)
+ hw_dbg(hw, "Flash update complete\n");
+ else
+ hw_dbg(hw, "Flash update time out\n");
+
+ if (hw->revision_id == 0) {
+ flup = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ if (flup & IXGBE_EEC_SEC1VAL) {
+ flup |= IXGBE_EEC_FLUP;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
+ }
+
+ status = ixgbe_poll_flash_update_done_X540(hw);
+ if (status)
+ hw_dbg(hw, "Flash update complete\n");
+ else
+ hw_dbg(hw, "Flash update time out\n");
+
+ }
+out:
+ return status;
+}
+
+/**
+ * ixgbe_poll_flash_update_done_X540 - Poll flash update status
+ * @hw: pointer to hardware structure
+ *
+ * Polls the FLUDONE (bit 26) of the EEC Register to determine when the
+ * flash update is done.
+ **/
+static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
+{
+ u32 i;
+ u32 reg;
+ s32 status = IXGBE_ERR_EEPROM;
+
+ for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
+ reg = IXGBE_READ_REG(hw, IXGBE_EEC);
+ if (reg & IXGBE_EEC_FLUDONE) {
+ status = 0;
+ break;
+ }
+ udelay(5);
+ }
+ return status;
+}
+
+/**
+ * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to acquire
+ *
+ * Acquires the SWFW semaphore thought the SW_FW_SYNC register for
+ * the specified function (CSR, PHY0, PHY1, NVM, Flash)
+ **/
+static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+ u32 swmask = mask;
+ u32 fwmask = mask << 5;
+ u32 hwmask = 0;
+ u32 timeout = 200;
+ u32 i;
+
+ if (swmask == IXGBE_GSSR_EEP_SM)
+ hwmask = IXGBE_GSSR_FLASH_SM;
+
+ for (i = 0; i < timeout; i++) {
+ /*
+ * SW NVM semaphore bit is used for access to all
+ * SW_FW_SYNC bits (not just NVM)
+ */
+ if (ixgbe_get_swfw_sync_semaphore(hw))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ if (!(swfw_sync & (fwmask | swmask | hwmask))) {
+ swfw_sync |= swmask;
+ IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+ ixgbe_release_swfw_sync_semaphore(hw);
+ break;
+ } else {
+ /*
+ * Firmware currently using resource (fwmask),
+ * hardware currently using resource (hwmask),
+ * or other software thread currently using
+ * resource (swmask)
+ */
+ ixgbe_release_swfw_sync_semaphore(hw);
+ msleep(5);
+ }
+ }
+
+ /*
+ * If the resource is not released by the FW/HW the SW can assume that
+ * the FW/HW malfunctions. In that case the SW should sets the
+ * SW bit(s) of the requested resource(s) while ignoring the
+ * corresponding FW/HW bits in the SW_FW_SYNC register.
+ */
+ if (i >= timeout) {
+ swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ if (swfw_sync & (fwmask | hwmask)) {
+ if (ixgbe_get_swfw_sync_semaphore(hw))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ swfw_sync |= swmask;
+ IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+ ixgbe_release_swfw_sync_semaphore(hw);
+ }
+ }
+
+ msleep(5);
+ return 0;
+}
+
+/**
+ * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to release
+ *
+ * Releases the SWFW semaphore throught the SW_FW_SYNC register
+ * for the specified function (CSR, PHY0, PHY1, EVM, Flash)
+ **/
+static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+ u32 swmask = mask;
+
+ ixgbe_get_swfw_sync_semaphore(hw);
+
+ swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ swfw_sync &= ~swmask;
+ IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
+
+ ixgbe_release_swfw_sync_semaphore(hw);
+ msleep(5);
+}
+
+/**
+ * ixgbe_get_nvm_semaphore - Get hardware semaphore
+ * @hw: pointer to hardware structure
+ *
+ * Sets the hardware semaphores so SW/FW can gain control of shared resources
+ **/
+static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_ERR_EEPROM;
+ u32 timeout = 2000;
+ u32 i;
+ u32 swsm;
+
+ /* Get SMBI software semaphore between device drivers first */
+ for (i = 0; i < timeout; i++) {
+ /*
+ * If the SMBI bit is 0 when we read it, then the bit will be
+ * set and we have the semaphore
+ */
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ if (!(swsm & IXGBE_SWSM_SMBI)) {
+ status = 0;
+ break;
+ }
+ udelay(50);
+ }
+
+ /* Now get the semaphore between SW/FW through the REGSMP bit */
+ if (status) {
+ for (i = 0; i < timeout; i++) {
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ if (!(swsm & IXGBE_SWFW_REGSMP))
+ break;
+
+ udelay(50);
+ }
+ } else {
+ hw_dbg(hw, "Software semaphore SMBI between device drivers "
+ "not granted.\n");
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_release_nvm_semaphore - Release hardware semaphore
+ * @hw: pointer to hardware structure
+ *
+ * This function clears hardware semaphore bits.
+ **/
+static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
+{
+ u32 swsm;
+
+ /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
+
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ swsm &= ~IXGBE_SWSM_SMBI;
+ IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ swsm &= ~IXGBE_SWFW_REGSMP;
+ IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm);
+
+ IXGBE_WRITE_FLUSH(hw);
+}
+
+static struct ixgbe_mac_operations mac_ops_X540 = {
+ .init_hw = &ixgbe_init_hw_generic,
+ .reset_hw = &ixgbe_reset_hw_X540,
+ .start_hw = &ixgbe_start_hw_generic,
+ .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
+ .get_media_type = &ixgbe_get_media_type_X540,
+ .get_supported_physical_layer =
+ &ixgbe_get_supported_physical_layer_X540,
+ .enable_rx_dma = &ixgbe_enable_rx_dma_generic,
+ .get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
+ .get_device_caps = NULL,
+ .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
+ .stop_adapter = &ixgbe_stop_adapter_generic,
+ .get_bus_info = &ixgbe_get_bus_info_generic,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
+ .read_analog_reg8 = NULL,
+ .write_analog_reg8 = NULL,
+ .setup_link = &ixgbe_setup_mac_link_X540,
+ .check_link = &ixgbe_check_mac_link_generic,
+ .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic,
+ .led_on = &ixgbe_led_on_generic,
+ .led_off = &ixgbe_led_off_generic,
+ .blink_led_start = &ixgbe_blink_led_start_generic,
+ .blink_led_stop = &ixgbe_blink_led_stop_generic,
+ .set_rar = &ixgbe_set_rar_generic,
+ .clear_rar = &ixgbe_clear_rar_generic,
+ .set_vmdq = &ixgbe_set_vmdq_generic,
+ .clear_vmdq = &ixgbe_clear_vmdq_generic,
+ .init_rx_addrs = &ixgbe_init_rx_addrs_generic,
+ .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic,
+ .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic,
+ .enable_mc = &ixgbe_enable_mc_generic,
+ .disable_mc = &ixgbe_disable_mc_generic,
+ .clear_vfta = &ixgbe_clear_vfta_generic,
+ .set_vfta = &ixgbe_set_vfta_generic,
+ .fc_enable = &ixgbe_fc_enable_generic,
+ .init_uta_tables = &ixgbe_init_uta_tables_generic,
+ .setup_sfp = NULL,
+ .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing,
+ .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
+ .init_params = &ixgbe_init_eeprom_params_X540,
+ .read = &ixgbe_read_eerd_X540,
+ .write = &ixgbe_write_eewr_X540,
+ .calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .update_checksum = &ixgbe_update_eeprom_checksum_X540,
+};
+
+static struct ixgbe_phy_operations phy_ops_X540 = {
+ .identify = &ixgbe_identify_phy_generic,
+ .identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .init = NULL,
+ .reset = &ixgbe_reset_phy_generic,
+ .read_reg = &ixgbe_read_phy_reg_generic,
+ .write_reg = &ixgbe_write_phy_reg_generic,
+ .setup_link = &ixgbe_setup_phy_link_generic,
+ .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
+ .read_i2c_byte = &ixgbe_read_i2c_byte_generic,
+ .write_i2c_byte = &ixgbe_write_i2c_byte_generic,
+ .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
+ .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
+ .check_overtemp = &ixgbe_tn_check_overtemp,
+};
+
+struct ixgbe_info ixgbe_X540_info = {
+ .mac = ixgbe_mac_X540,
+ .get_invariants = &ixgbe_get_invariants_X540,
+ .mac_ops = &mac_ops_X540,
+ .eeprom_ops = &eeprom_ops_X540,
+ .phy_ops = &phy_ops_X540,
+ .mbx_ops = &mbx_ops_generic,
+};
diff --git a/drivers/net/ixgbevf/Makefile b/drivers/net/ixgbevf/Makefile
index dd4e0d27e8cc..1f35d229e71a 100644
--- a/drivers/net/ixgbevf/Makefile
+++ b/drivers/net/ixgbevf/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 82599 Virtual Function driver
-# Copyright(c) 1999 - 2009 Intel Corporation.
+# Copyright(c) 1999 - 2010 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgbevf/defines.h b/drivers/net/ixgbevf/defines.h
index ca2c81f49a05..de643eb2ada6 100644
--- a/drivers/net/ixgbevf/defines.h
+++ b/drivers/net/ixgbevf/defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -30,6 +30,7 @@
/* Device IDs */
#define IXGBE_DEV_ID_82599_VF 0x10ED
+#define IXGBE_DEV_ID_X540_VF 0x1515
#define IXGBE_VF_IRQ_CLEAR_MASK 7
#define IXGBE_VF_MAX_TX_QUEUES 1
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 4cc817acfb62..fa29b3c8c464 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -544,7 +544,7 @@ struct ixgbevf_reg_test {
#define TABLE64_TEST_HI 6
/* default VF register test */
-static struct ixgbevf_reg_test reg_test_vf[] = {
+static const struct ixgbevf_reg_test reg_test_vf[] = {
{ IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
{ IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
@@ -557,19 +557,23 @@ static struct ixgbevf_reg_test reg_test_vf[] = {
{ 0, 0, 0, 0 }
};
+static const u32 register_test_patterns[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
+};
+
#define REG_PATTERN_TEST(R, M, W) \
{ \
u32 pat, val, before; \
- const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
- for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \
+ for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \
before = readl(adapter->hw.hw_addr + R); \
- writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \
+ writel((register_test_patterns[pat] & W), \
+ (adapter->hw.hw_addr + R)); \
val = readl(adapter->hw.hw_addr + R); \
- if (val != (_test[pat] & W & M)) { \
+ if (val != (register_test_patterns[pat] & W & M)) { \
hw_dbg(&adapter->hw, \
"pattern test reg %04X failed: got " \
"0x%08X expected 0x%08X\n", \
- R, val, (_test[pat] & W & M)); \
+ R, val, (register_test_patterns[pat] & W & M)); \
*data = R; \
writel(before, adapter->hw.hw_addr + R); \
return 1; \
@@ -596,7 +600,7 @@ static struct ixgbevf_reg_test reg_test_vf[] = {
static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data)
{
- struct ixgbevf_reg_test *test;
+ const struct ixgbevf_reg_test *test;
u32 i;
test = reg_test_vf;
diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h
index da4033c6efa2..a63efcb2cf1b 100644
--- a/drivers/net/ixgbevf/ixgbevf.h
+++ b/drivers/net/ixgbevf/ixgbevf.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -275,9 +275,11 @@ enum ixbgevf_state_t {
enum ixgbevf_boards {
board_82599_vf,
+ board_X540_vf,
};
-extern struct ixgbevf_info ixgbevf_vf_info;
+extern struct ixgbevf_info ixgbevf_82599_vf_info;
+extern struct ixgbevf_info ixgbevf_X540_vf_info;
extern struct ixgbe_mac_operations ixgbevf_mbx_ops;
/* needed by ethtool.c */
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index dc03c9652389..464e6c9d3fc2 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -51,12 +51,14 @@ char ixgbevf_driver_name[] = "ixgbevf";
static const char ixgbevf_driver_string[] =
"Intel(R) 82599 Virtual Function";
-#define DRV_VERSION "1.0.0-k0"
+#define DRV_VERSION "1.0.19-k0"
const char ixgbevf_driver_version[] = DRV_VERSION;
-static char ixgbevf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+static char ixgbevf_copyright[] =
+ "Copyright (c) 2009 - 2010 Intel Corporation.";
static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
- [board_82599_vf] = &ixgbevf_vf_info,
+ [board_82599_vf] = &ixgbevf_82599_vf_info,
+ [board_X540_vf] = &ixgbevf_X540_vf_info,
};
/* ixgbevf_pci_tbl - PCI Device ID Table
@@ -70,6 +72,8 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
static struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF),
board_82599_vf},
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF),
+ board_X540_vf},
/* required last entry */
{0, }
@@ -2488,10 +2492,9 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter,
int size;
size = sizeof(struct ixgbevf_tx_buffer) * tx_ring->count;
- tx_ring->tx_buffer_info = vmalloc(size);
+ tx_ring->tx_buffer_info = vzalloc(size);
if (!tx_ring->tx_buffer_info)
goto err;
- memset(tx_ring->tx_buffer_info, 0, size);
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
@@ -2555,14 +2558,13 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,
int size;
size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;
- rx_ring->rx_buffer_info = vmalloc(size);
+ rx_ring->rx_buffer_info = vzalloc(size);
if (!rx_ring->rx_buffer_info) {
hw_dbg(&adapter->hw,
"Unable to vmalloc buffer memory for "
"the receive descriptor ring\n");
goto alloc_failed;
}
- memset(rx_ring->rx_buffer_info, 0, size);
/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
@@ -3424,10 +3426,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
if (hw->mac.ops.get_bus_info)
hw->mac.ops.get_bus_info(hw);
-
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
@@ -3436,6 +3434,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
adapter->netdev_registered = true;
+ netif_carrier_off(netdev);
+
ixgbevf_init_last_counter_stats(adapter);
/* print the MAC address */
@@ -3487,10 +3487,9 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
del_timer_sync(&adapter->watchdog_timer);
+ cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->watchdog_task);
- flush_scheduled_work();
-
if (adapter->netdev_registered) {
unregister_netdev(netdev);
adapter->netdev_registered = false;
diff --git a/drivers/net/ixgbevf/mbx.c b/drivers/net/ixgbevf/mbx.c
index 84ac486f4a65..7a8833125770 100644
--- a/drivers/net/ixgbevf/mbx.c
+++ b/drivers/net/ixgbevf/mbx.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h
index 8c063bebee7f..b2b5bf5daa3d 100644
--- a/drivers/net/ixgbevf/mbx.h
+++ b/drivers/net/ixgbevf/mbx.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgbevf/regs.h b/drivers/net/ixgbevf/regs.h
index 12f75960aec1..fb80ca1bcc93 100644
--- a/drivers/net/ixgbevf/regs.h
+++ b/drivers/net/ixgbevf/regs.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c
index bfe42c1fcfaf..eecd3bf6833f 100644
--- a/drivers/net/ixgbevf/vf.c
+++ b/drivers/net/ixgbevf/vf.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -381,8 +381,12 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.set_vfta = ixgbevf_set_vfta_vf,
};
-struct ixgbevf_info ixgbevf_vf_info = {
+struct ixgbevf_info ixgbevf_82599_vf_info = {
.mac = ixgbe_mac_82599_vf,
.mac_ops = &ixgbevf_mac_ops,
};
+struct ixgbevf_info ixgbevf_X540_vf_info = {
+ .mac = ixgbe_mac_X540_vf,
+ .mac_ops = &ixgbevf_mac_ops,
+};
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 61f9dc831424..23eb114c149f 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 82599 Virtual Function driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -73,6 +73,7 @@ struct ixgbe_mac_operations {
enum ixgbe_mac_type {
ixgbe_mac_unknown = 0,
ixgbe_mac_82599_vf,
+ ixgbe_mac_X540_vf,
ixgbe_num_macs
};
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index c57d9a43ceca..e97ebef3cf47 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -135,7 +135,7 @@ jme_reset_phy_processor(struct jme_adapter *jme)
static void
jme_setup_wakeup_frame(struct jme_adapter *jme,
- u32 *mask, u32 crc, int fnr)
+ const u32 *mask, u32 crc, int fnr)
{
int i;
@@ -163,7 +163,7 @@ jme_setup_wakeup_frame(struct jme_adapter *jme,
static inline void
jme_reset_mac_processor(struct jme_adapter *jme)
{
- u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0};
+ static const u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0};
u32 crc = 0xCDCDCDCD;
u32 gpreg0;
int i;
@@ -2076,12 +2076,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
}
if (new_mtu > 1900) {
- netdev->features &= ~(NETIF_F_HW_CSUM |
- NETIF_F_TSO |
- NETIF_F_TSO6);
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6);
} else {
if (test_bit(JME_FLAG_TXCSUM, &jme->flags))
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
if (test_bit(JME_FLAG_TSO, &jme->flags))
netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
}
@@ -2514,10 +2513,12 @@ jme_set_tx_csum(struct net_device *netdev, u32 on)
if (on) {
set_bit(JME_FLAG_TXCSUM, &jme->flags);
if (netdev->mtu <= 1900)
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |=
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
} else {
clear_bit(JME_FLAG_TXCSUM, &jme->flags);
- netdev->features &= ~NETIF_F_HW_CSUM;
+ netdev->features &=
+ ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
}
return 0;
@@ -2797,7 +2798,8 @@ jme_init_one(struct pci_dev *pdev,
netdev->netdev_ops = &jme_netdev_ops;
netdev->ethtool_ops = &jme_ethtool_ops;
netdev->watchdog_timeo = TX_TIMEOUT;
- netdev->features = NETIF_F_HW_CSUM |
+ netdev->features = NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM |
NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index 51919fcd50c2..0fa4a9887ba2 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -1545,6 +1545,37 @@ static int ks8851_read_selftest(struct ks8851_net *ks)
/* driver bus management functions */
+#ifdef CONFIG_PM
+static int ks8851_suspend(struct spi_device *spi, pm_message_t state)
+{
+ struct ks8851_net *ks = dev_get_drvdata(&spi->dev);
+ struct net_device *dev = ks->netdev;
+
+ if (netif_running(dev)) {
+ netif_device_detach(dev);
+ ks8851_net_stop(dev);
+ }
+
+ return 0;
+}
+
+static int ks8851_resume(struct spi_device *spi)
+{
+ struct ks8851_net *ks = dev_get_drvdata(&spi->dev);
+ struct net_device *dev = ks->netdev;
+
+ if (netif_running(dev)) {
+ ks8851_net_open(dev);
+ netif_device_attach(dev);
+ }
+
+ return 0;
+}
+#else
+#define ks8851_suspend NULL
+#define ks8851_resume NULL
+#endif
+
static int __devinit ks8851_probe(struct spi_device *spi)
{
struct net_device *ndev;
@@ -1679,6 +1710,8 @@ static struct spi_driver ks8851_driver = {
},
.probe = ks8851_probe,
.remove = __devexit_p(ks8851_remove),
+ .suspend = ks8851_suspend,
+ .resume = ks8851_resume,
};
static int __init ks8851_init(void)
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 37504a398906..540a8dcbcc46 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -3570,7 +3570,7 @@ static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set)
* This routine is used to program Wake-on-LAN pattern.
*/
static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
- u8 *mask, uint frame_size, u8 *pattern)
+ const u8 *mask, uint frame_size, const u8 *pattern)
{
int bits;
int from;
@@ -3626,9 +3626,9 @@ static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
*
* This routine is used to add ARP pattern for waking up the host.
*/
-static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr)
+static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr)
{
- u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 };
+ static const u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 };
u8 pattern[42] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -3651,8 +3651,8 @@ static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr)
*/
static void hw_add_wol_bcast(struct ksz_hw *hw)
{
- u8 mask[] = { 0x3F };
- u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ static const u8 mask[] = { 0x3F };
+ static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern);
}
@@ -3669,7 +3669,7 @@ static void hw_add_wol_bcast(struct ksz_hw *hw)
*/
static void hw_add_wol_mcast(struct ksz_hw *hw)
{
- u8 mask[] = { 0x3F };
+ static const u8 mask[] = { 0x3F };
u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 };
memcpy(&pattern[3], &hw->override_addr[3], 3);
@@ -3687,7 +3687,7 @@ static void hw_add_wol_mcast(struct ksz_hw *hw)
*/
static void hw_add_wol_ucast(struct ksz_hw *hw)
{
- u8 mask[] = { 0x3F };
+ static const u8 mask[] = { 0x3F };
hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr);
}
@@ -3700,7 +3700,7 @@ static void hw_add_wol_ucast(struct ksz_hw *hw)
*
* This routine is used to enable Wake-on-LAN depending on driver settings.
*/
-static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, u8 *net_addr)
+static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr)
{
hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC));
hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST));
@@ -6208,7 +6208,7 @@ static int netdev_set_wol(struct net_device *dev,
struct dev_info *hw_priv = priv->adapter;
/* Need to find a way to retrieve the device IP address. */
- u8 net_addr[] = { 192, 168, 1, 1 };
+ static const u8 net_addr[] = { 192, 168, 1, 1 };
if (wol->wolopts & ~hw_priv->wol_support)
return -EINVAL;
@@ -6953,7 +6953,7 @@ static void read_other_addr(struct ksz_hw *hw)
#define PCI_VENDOR_ID_MICREL_KS 0x16c6
#endif
-static int __init pcidev_init(struct pci_dev *pdev,
+static int __devinit pcidev_init(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct net_device *dev;
@@ -7241,7 +7241,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
struct ksz_hw *hw = &hw_priv->hw;
/* Need to find a way to retrieve the device IP address. */
- u8 net_addr[] = { 192, 168, 1, 1 };
+ static const u8 net_addr[] = { 192, 168, 1, 1 };
for (i = 0; i < hw->dev_count; i++) {
if (info->netdev[i]) {
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index f06296bfe293..02336edce748 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -207,7 +207,7 @@ tx_full and tbusy flags.
#define LANCE_BUS_IF 0x16
#define LANCE_TOTAL_SIZE 0x18
-#define TX_TIMEOUT 20
+#define TX_TIMEOUT (HZ/5)
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index c27f4291b350..9e042894479b 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -161,7 +161,7 @@ enum commands {
#define RX_SUSPEND 0x0030
#define RX_ABORT 0x0040
-#define TX_TIMEOUT 5
+#define TX_TIMEOUT (HZ/20)
struct i596_reg {
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index e7030ceb178b..da74db4a03d4 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -203,7 +203,7 @@ static void __NS8390_init(struct net_device *dev, int startp);
static int __ei_open(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (dev->watchdog_timeo <= 0)
dev->watchdog_timeo = TX_TIMEOUT;
@@ -231,7 +231,7 @@ static int __ei_open(struct net_device *dev)
*/
static int __ei_close(struct net_device *dev)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/*
@@ -256,7 +256,7 @@ static int __ei_close(struct net_device *dev)
static void __ei_tx_timeout(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
unsigned long flags;
@@ -303,7 +303,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int send_length = skb->len, output_page;
unsigned long flags;
char buf[ETH_ZLEN];
@@ -592,7 +592,7 @@ static void ei_tx_err(struct net_device *dev)
static void ei_tx_intr(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int status = ei_inb(e8390_base + EN0_TSR);
ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
@@ -675,7 +675,7 @@ static void ei_tx_intr(struct net_device *dev)
static void ei_receive(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned char rxing_page, this_frame, next_frame;
unsigned short current_offset;
int rx_pkt_count = 0;
@@ -879,7 +879,7 @@ static void ei_rx_overrun(struct net_device *dev)
static struct net_device_stats *__ei_get_stats(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/* If the card is stopped, just return the present stats. */
@@ -927,7 +927,7 @@ static void do_set_multicast_list(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
int i;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
{
@@ -981,7 +981,7 @@ static void do_set_multicast_list(struct net_device *dev)
static void __ei_set_multicast_list(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
spin_lock_irqsave(&ei_local->page_lock, flags);
do_set_multicast_list(dev);
@@ -998,7 +998,7 @@ static void __ei_set_multicast_list(struct net_device *dev)
static void ethdev_setup(struct net_device *dev)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (ei_debug > 1)
printk(version);
@@ -1036,7 +1036,7 @@ static struct net_device *____alloc_ei_netdev(int size)
static void __NS8390_init(struct net_device *dev, int startp)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int i;
int endcfg = ei_local->word16
? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0))
@@ -1099,7 +1099,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev);
ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index 9f8e7027b0b3..183765cb7f25 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -692,7 +692,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
cur_p->app0 = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- unsigned int csum_start_off = skb_transport_offset(skb);
+ unsigned int csum_start_off = skb_checksum_start_offset(skb);
unsigned int csum_index_off = csum_start_off + skb->csum_offset;
cur_p->app0 |= 1; /* TX Checksum Enabled */
@@ -952,7 +952,7 @@ static const struct attribute_group temac_attr_group = {
.attrs = temac_device_attrs,
};
-static int __init
+static int __devinit
temac_of_probe(struct platform_device *op, const struct of_device_id *match)
{
struct device_node *np;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 0fc9dc7f20db..6ed577b065df 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -38,6 +38,7 @@ struct macvlan_port {
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
struct list_head vlans;
struct rcu_head rcu;
+ bool passthru;
};
#define macvlan_port_get_rcu(dev) \
@@ -169,6 +170,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
macvlan_broadcast(skb, port, NULL,
MACVLAN_MODE_PRIVATE |
MACVLAN_MODE_VEPA |
+ MACVLAN_MODE_PASSTHRU|
MACVLAN_MODE_BRIDGE);
else if (src->mode == MACVLAN_MODE_VEPA)
/* flood to everyone except source */
@@ -185,7 +187,10 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
return skb;
}
- vlan = macvlan_hash_lookup(port, eth->h_dest);
+ if (port->passthru)
+ vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
+ else
+ vlan = macvlan_hash_lookup(port, eth->h_dest);
if (vlan == NULL)
return skb;
@@ -243,18 +248,22 @@ xmit_world:
netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- int i = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
unsigned int len = skb->len;
int ret;
+ const struct macvlan_dev *vlan = netdev_priv(dev);
ret = macvlan_queue_xmit(skb, dev);
if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
- txq->tx_packets++;
- txq->tx_bytes += len;
- } else
- txq->tx_dropped++;
+ struct macvlan_pcpu_stats *pcpu_stats;
+ pcpu_stats = this_cpu_ptr(vlan->pcpu_stats);
+ u64_stats_update_begin(&pcpu_stats->syncp);
+ pcpu_stats->tx_packets++;
+ pcpu_stats->tx_bytes += len;
+ u64_stats_update_end(&pcpu_stats->syncp);
+ } else {
+ this_cpu_inc(vlan->pcpu_stats->tx_dropped);
+ }
return ret;
}
EXPORT_SYMBOL_GPL(macvlan_start_xmit);
@@ -284,6 +293,11 @@ static int macvlan_open(struct net_device *dev)
struct net_device *lowerdev = vlan->lowerdev;
int err;
+ if (vlan->port->passthru) {
+ dev_set_promiscuity(lowerdev, 1);
+ goto hash_add;
+ }
+
err = -EBUSY;
if (macvlan_addr_busy(vlan->port, dev->dev_addr))
goto out;
@@ -296,6 +310,8 @@ static int macvlan_open(struct net_device *dev)
if (err < 0)
goto del_unicast;
}
+
+hash_add:
macvlan_hash_add(vlan);
return 0;
@@ -310,12 +326,18 @@ static int macvlan_stop(struct net_device *dev)
struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
+ if (vlan->port->passthru) {
+ dev_set_promiscuity(lowerdev, -1);
+ goto hash_del;
+ }
+
dev_mc_unsync(lowerdev, dev);
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);
dev_uc_del(lowerdev, dev->dev_addr);
+hash_del:
macvlan_hash_del(vlan);
return 0;
}
@@ -414,14 +436,15 @@ static int macvlan_init(struct net_device *dev)
dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
+ dev->features |= NETIF_F_LLTX;
dev->gso_max_size = lowerdev->gso_max_size;
dev->iflink = lowerdev->ifindex;
dev->hard_header_len = lowerdev->hard_header_len;
macvlan_set_lockdep_class(dev);
- vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats);
- if (!vlan->rx_stats)
+ vlan->pcpu_stats = alloc_percpu(struct macvlan_pcpu_stats);
+ if (!vlan->pcpu_stats)
return -ENOMEM;
return 0;
@@ -431,7 +454,7 @@ static void macvlan_uninit(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- free_percpu(vlan->rx_stats);
+ free_percpu(vlan->pcpu_stats);
}
static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
@@ -439,33 +462,38 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
{
struct macvlan_dev *vlan = netdev_priv(dev);
- dev_txq_stats_fold(dev, stats);
-
- if (vlan->rx_stats) {
- struct macvlan_rx_stats *p, accum = {0};
- u64 rx_packets, rx_bytes, rx_multicast;
+ if (vlan->pcpu_stats) {
+ struct macvlan_pcpu_stats *p;
+ u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes;
+ u32 rx_errors = 0, tx_dropped = 0;
unsigned int start;
int i;
for_each_possible_cpu(i) {
- p = per_cpu_ptr(vlan->rx_stats, i);
+ p = per_cpu_ptr(vlan->pcpu_stats, i);
do {
start = u64_stats_fetch_begin_bh(&p->syncp);
rx_packets = p->rx_packets;
rx_bytes = p->rx_bytes;
rx_multicast = p->rx_multicast;
+ tx_packets = p->tx_packets;
+ tx_bytes = p->tx_bytes;
} while (u64_stats_fetch_retry_bh(&p->syncp, start));
- accum.rx_packets += rx_packets;
- accum.rx_bytes += rx_bytes;
- accum.rx_multicast += rx_multicast;
- /* rx_errors is an ulong, updated without syncp protection */
- accum.rx_errors += p->rx_errors;
+
+ stats->rx_packets += rx_packets;
+ stats->rx_bytes += rx_bytes;
+ stats->multicast += rx_multicast;
+ stats->tx_packets += tx_packets;
+ stats->tx_bytes += tx_bytes;
+ /* rx_errors & tx_dropped are u32, updated
+ * without syncp protection.
+ */
+ rx_errors += p->rx_errors;
+ tx_dropped += p->tx_dropped;
}
- stats->rx_packets = accum.rx_packets;
- stats->rx_bytes = accum.rx_bytes;
- stats->rx_errors = accum.rx_errors;
- stats->rx_dropped = accum.rx_errors;
- stats->multicast = accum.rx_multicast;
+ stats->rx_errors = rx_errors;
+ stats->rx_dropped = rx_errors;
+ stats->tx_dropped = tx_dropped;
}
return stats;
}
@@ -549,6 +577,7 @@ static int macvlan_port_create(struct net_device *dev)
if (port == NULL)
return -ENOMEM;
+ port->passthru = false;
port->dev = dev;
INIT_LIST_HEAD(&port->vlans);
for (i = 0; i < MACVLAN_HASH_SIZE; i++)
@@ -593,6 +622,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
case MACVLAN_MODE_PRIVATE:
case MACVLAN_MODE_VEPA:
case MACVLAN_MODE_BRIDGE:
+ case MACVLAN_MODE_PASSTHRU:
break;
default:
return -EINVAL;
@@ -601,25 +631,6 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
return 0;
}
-static int macvlan_get_tx_queues(struct net *net,
- struct nlattr *tb[],
- unsigned int *num_tx_queues,
- unsigned int *real_num_tx_queues)
-{
- struct net_device *real_dev;
-
- if (!tb[IFLA_LINK])
- return -EINVAL;
-
- real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
- if (!real_dev)
- return -ENODEV;
-
- *num_tx_queues = real_dev->num_tx_queues;
- *real_num_tx_queues = real_dev->real_num_tx_queues;
- return 0;
-}
-
int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
int (*receive)(struct sk_buff *skb),
@@ -661,6 +672,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
}
port = macvlan_port_get(lowerdev);
+ /* Only 1 macvlan device can be created in passthru mode */
+ if (port->passthru)
+ return -EINVAL;
+
vlan->lowerdev = lowerdev;
vlan->dev = dev;
vlan->port = port;
@@ -671,6 +686,13 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
if (data && data[IFLA_MACVLAN_MODE])
vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+ if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
+ if (!list_empty(&port->vlans))
+ return -EINVAL;
+ port->passthru = true;
+ memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN);
+ }
+
err = register_netdevice(dev);
if (err < 0)
goto destroy_port;
@@ -743,7 +765,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
{
/* common fields */
ops->priv_size = sizeof(struct macvlan_dev);
- ops->get_tx_queues = macvlan_get_tx_queues;
ops->validate = macvlan_validate;
ops->maxtype = IFLA_MACVLAN_MAX;
ops->policy = macvlan_policy;
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 42567279843e..21845affea13 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -504,8 +504,7 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- vnet_hdr->csum_start = skb->csum_start -
- skb_headroom(skb);
+ vnet_hdr->csum_start = skb_checksum_start_offset(skb);
vnet_hdr->csum_offset = skb->csum_offset;
} /* else everything is zero */
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index b68eee2414c2..7a7e18ba278a 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -289,6 +289,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET);
dev_cap->bf_reg_size = 1 << (field & 0x1f);
MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET);
+ if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) {
+ mlx4_warn(dev, "firmware bug: log2 # of blue flame regs is invalid (%d), forcing 3\n", field & 0x1f);
+ field = 3;
+ }
dev_cap->bf_regs_per_page = 1 << (field & 0x3f);
mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index dd2b6a71c6d7..02076e16542a 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1514,11 +1514,6 @@ static int mv643xx_eth_nway_reset(struct net_device *dev)
return genphy_restart_aneg(mp->phy);
}
-static u32 mv643xx_eth_get_link(struct net_device *dev)
-{
- return !!netif_carrier_ok(dev);
-}
-
static int
mv643xx_eth_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
{
@@ -1658,7 +1653,7 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
.set_settings = mv643xx_eth_set_settings,
.get_drvinfo = mv643xx_eth_get_drvinfo,
.nway_reset = mv643xx_eth_nway_reset,
- .get_link = mv643xx_eth_get_link,
+ .get_link = ethtool_op_get_link,
.get_coalesce = mv643xx_eth_get_coalesce,
.set_coalesce = mv643xx_eth_set_coalesce,
.get_ringparam = mv643xx_eth_get_ringparam,
@@ -2983,7 +2978,7 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
unregister_netdev(mp->dev);
if (mp->phy != NULL)
phy_detach(mp->phy);
- flush_scheduled_work();
+ cancel_work_sync(&mp->tx_timeout_task);
free_netdev(mp->dev);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 8524cc40ec57..ea5cfe2c3a04 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2736,7 +2736,7 @@ again:
odd_flag = 0;
flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST);
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
- cksum_offset = skb_transport_offset(skb);
+ cksum_offset = skb_checksum_start_offset(skb);
pseudo_hdr_offset = cksum_offset + skb->csum_offset;
/* If the headers are excessively large, then we must
* fall back to a software checksum */
@@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev)
return -EIO;
}
- status = pci_restore_state(pdev);
- if (status)
- return status;
+ pci_restore_state(pdev);
status = pci_enable_device(pdev);
if (status) {
@@ -4067,7 +4065,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
if (mgp == NULL)
return;
- flush_scheduled_work();
+ cancel_work_sync(&mgp->watchdog_work);
netdev = mgp->dev;
unregister_netdev(netdev);
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index e0b0ef11f110..30be8c634ebd 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -86,7 +86,7 @@ static u32 reg_offset[16];
static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int i;
unsigned char bus_width;
@@ -218,7 +218,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
int start_page, stop_page;
int reg0, ret;
static unsigned version_printed;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned char bus_width;
if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
@@ -371,7 +371,7 @@ static int ne_close(struct net_device *dev)
static void ne_reset_8390(struct net_device *dev)
{
unsigned long reset_start_time = jiffies;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (ei_debug > 1)
printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
@@ -397,7 +397,7 @@ static void ne_reset_8390(struct net_device *dev)
static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing)
@@ -437,7 +437,7 @@ static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, i
static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
#ifdef NE_SANITY_CHECK
int xfer_count = count;
#endif
@@ -507,7 +507,7 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk
static void ne_block_output(struct net_device *dev, int count,
const unsigned char *buf, const int start_page)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long dma_start;
#ifdef NE_SANITY_CHECK
int retries = 0;
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 8e8a97839cb0..a11380544e6c 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 74
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.74"
+#define _NETXEN_NIC_LINUX_SUBVERSION 75
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.75"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -1132,6 +1132,7 @@ typedef struct {
#define NETXEN_NIC_MSI_ENABLED 0x02
#define NETXEN_NIC_MSIX_ENABLED 0x04
#define NETXEN_NIC_LRO_ENABLED 0x08
+#define NETXEN_NIC_LRO_DISABLED 0x00
#define NETXEN_NIC_BRIDGE_ENABLED 0X10
#define NETXEN_NIC_DIAG_ENABLED 0x20
#define NETXEN_IS_MSI_FAMILY(adapter) \
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index b30de24f4a52..587498e140bb 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -720,7 +720,21 @@ static u32 netxen_nic_get_rx_csum(struct net_device *dev)
static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- adapter->rx_csum = !!data;
+
+ if (data) {
+ adapter->rx_csum = data;
+ return 0;
+ }
+
+ if (dev->features & NETIF_F_LRO) {
+ if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
+ return -EIO;
+
+ dev->features &= ~NETIF_F_LRO;
+ netxen_send_lro_cleanup(adapter);
+ netdev_info(dev, "disabling LRO as rx_csum is off\n");
+ }
+ adapter->rx_csum = data;
return 0;
}
@@ -893,11 +907,19 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
return -EINVAL;
+ if (!adapter->rx_csum) {
+ netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
+ return -EINVAL;
+ }
+
+ if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
+ return 0;
+
if (data & ETH_FLAG_LRO) {
hw_lro = NETXEN_NIC_LRO_ENABLED;
netdev->features |= NETIF_F_LRO;
} else {
- hw_lro = 0;
+ hw_lro = NETXEN_NIC_LRO_DISABLED;
netdev->features &= ~NETIF_F_LRO;
}
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 37d3ebd65be8..5cef718fe35f 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -655,7 +655,7 @@ nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
}
static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
- u8 *addr, struct list_head *del_list)
+ const u8 *addr, struct list_head *del_list)
{
struct list_head *head;
nx_mac_list_t *cur;
@@ -686,7 +686,9 @@ static void netxen_p3_nic_set_multi(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct netdev_hw_addr *ha;
- u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ static const 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;
@@ -807,9 +809,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
u64 word;
int rv = 0;
- if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable)
- return 0;
-
memset(&req, 0, sizeof(nx_nic_req_t));
req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
@@ -825,8 +824,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
"configure hw lro request\n");
}
- adapter->flags ^= NETXEN_NIC_LRO_ENABLED;
-
return rv;
}
@@ -869,9 +866,11 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
u64 word;
int i, rv;
- u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
- 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
- 0x255b0ec26d5a56daULL };
+ static const u64 key[] = {
+ 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL
+ };
memset(&req, 0, sizeof(nx_nic_req_t));
@@ -895,7 +894,7 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
((u64)(enable & 0x1) << 8) |
((0x7ULL) << 48);
req.words[0] = cpu_to_le64(word);
- for (i = 0; i < 5; i++)
+ for (i = 0; i < ARRAY_SIZE(key); i++)
req.words[i+1] = cpu_to_le64(key[i]);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 95fe552aa279..731077d8d962 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -214,13 +214,12 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
tx_ring->num_desc = adapter->num_txd;
tx_ring->txq = netdev_get_tx_queue(netdev, 0);
- cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
+ cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
netdev->name);
goto err_out;
}
- memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx;
@@ -279,8 +278,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
break;
}
- rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
- vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+ rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
if (rds_ring->rx_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate "
"rx buffer ring %d\n",
@@ -288,7 +286,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
/* free whatever was already allocated */
goto err_out;
}
- memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
INIT_LIST_HEAD(&rds_ring->free_list);
/*
* Now go through all of them, set reference handles
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index e1d30d7f2071..33fac32e0d9f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -38,7 +38,7 @@
#include <linux/sysfs.h>
#include <linux/aer.h>
-MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver");
+MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Intelligent Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME);
@@ -762,8 +762,6 @@ netxen_check_options(struct netxen_adapter *adapter)
if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
- adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
-
if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
@@ -990,7 +988,7 @@ __netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_config_intr_coalesce(adapter);
- if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+ if (netdev->features & NETIF_F_LRO)
netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);
netxen_napi_enable(adapter);
@@ -1277,6 +1275,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int i = 0, err;
int pci_func_id = PCI_FUNC(pdev->devfn);
uint8_t revision_id;
+ u32 val;
if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
pr_warning("%s: chip revisions between 0x%x-0x%x "
@@ -1352,8 +1351,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- if (reset_devices) {
- if (adapter->portnum == 0) {
+ if (adapter->portnum == 0) {
+ val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+ if (val != 0xffffffff && val != 0) {
NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0);
adapter->need_fw_reset = 1;
}
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 33618edc61f9..d973fc6c6b88 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -388,9 +388,9 @@ static long memend; /* e.g 0xd4000 */
struct net_device * __init ni52_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- static int ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
+ static const int ports[] = {0x300, 0x280, 0x360, 0x320, 0x340, 0};
+ const int *port;
struct priv *p;
- int *port;
int err = 0;
if (!dev)
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index da228a0dd6cd..c75ae85eb918 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -361,8 +361,8 @@ static int dma;
struct net_device * __init ni65_probe(int unit)
{
struct net_device *dev = alloc_etherdev(0);
- static int ports[] = {0x360,0x300,0x320,0x340, 0};
- int *port;
+ static const int ports[] = { 0x360, 0x300, 0x320, 0x340, 0 };
+ const int *port;
int err = 0;
if (!dev)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 781e368329f9..2541321bad82 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -6589,7 +6589,7 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr,
(ip_proto == IPPROTO_UDP ?
TXHDR_CSUM_UDP : TXHDR_CSUM_SCTP));
- start = skb_transport_offset(skb) -
+ start = skb_checksum_start_offset(skb) -
(pad_bytes + sizeof(struct tx_pkt_hdr));
stuff = start + skb->csum_offset;
@@ -9917,7 +9917,7 @@ static int niu_suspend(struct pci_dev *pdev, pm_message_t state)
if (!netif_running(dev))
return 0;
- flush_scheduled_work();
+ flush_work_sync(&np->reset_task);
niu_netif_stop(np);
del_timer_sync(&np->timer);
diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c
index c8cc32c0edc9..c8c873b31a89 100644
--- a/drivers/net/pch_gbe/pch_gbe_ethtool.c
+++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c
@@ -469,18 +469,6 @@ static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
}
/**
- * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off
- * @netdev: Network interface device structure
- * Returns
- * true(1): Checksum On
- * false(0): Checksum Off
- */
-static u32 pch_gbe_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-/**
* pch_gbe_set_tx_csum - Turn transmit checksums on or off
* @netdev: Network interface device structure
* @data: Checksum on[true] or off[false]
@@ -493,11 +481,7 @@ static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
adapter->tx_csum = data;
- if (data)
- netdev->features |= NETIF_F_HW_CSUM;
- else
- netdev->features &= ~NETIF_F_HW_CSUM;
- return 0;
+ return ethtool_op_set_tx_ipv6_csum(netdev, data);
}
/**
@@ -572,7 +556,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
.set_pauseparam = pch_gbe_set_pauseparam,
.get_rx_csum = pch_gbe_get_rx_csum,
.set_rx_csum = pch_gbe_set_rx_csum,
- .get_tx_csum = pch_gbe_get_tx_csum,
.set_tx_csum = pch_gbe_set_tx_csum,
.get_strings = pch_gbe_get_strings,
.get_ethtool_stats = pch_gbe_get_ethtool_stats,
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 03a1d280105f..d7355306a738 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -1523,12 +1523,11 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
int desNo;
size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count;
- tx_ring->buffer_info = vmalloc(size);
+ tx_ring->buffer_info = vzalloc(size);
if (!tx_ring->buffer_info) {
pr_err("Unable to allocate memory for the buffer infomation\n");
return -ENOMEM;
}
- memset(tx_ring->buffer_info, 0, size);
tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc);
@@ -1573,12 +1572,11 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,
int desNo;
size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count;
- rx_ring->buffer_info = vmalloc(size);
+ rx_ring->buffer_info = vzalloc(size);
if (!rx_ring->buffer_info) {
pr_err("Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
}
- memset(rx_ring->buffer_info, 0, size);
rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc);
rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
&rx_ring->dma, GFP_KERNEL);
@@ -2321,7 +2319,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
netif_napi_add(netdev, &adapter->napi,
pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);
- netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO;
+ netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO;
pch_gbe_set_ethtool_ops(netdev);
pch_gbe_mac_reset_hw(&adapter->hw);
@@ -2360,9 +2358,9 @@ static int pch_gbe_probe(struct pci_dev *pdev,
pch_gbe_check_options(adapter);
if (adapter->tx_csum)
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
else
- netdev->features &= ~NETIF_F_HW_CSUM;
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
/* initialize the wol settings based on the eeprom settings */
adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8a4d19e5de06..1f42f6ac8551 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -690,6 +690,7 @@ static void block_output(struct net_device *dev, int count,
static struct pcmcia_device_id axnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
+ PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
@@ -875,7 +876,7 @@ static void do_set_multicast_list(struct net_device *dev);
static int ax_open(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
/*
* Grab the page lock so we own the register set, then call
@@ -926,7 +927,7 @@ static int ax_close(struct net_device *dev)
static void axnet_tx_timeout(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
unsigned long flags;
@@ -973,7 +974,7 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int length, send_length, output_page;
unsigned long flags;
u8 packet[ETH_ZLEN];
@@ -1270,7 +1271,7 @@ static void ei_tx_err(struct net_device *dev)
static void ei_tx_intr(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int status = inb(e8390_base + EN0_TSR);
/*
@@ -1354,7 +1355,7 @@ static void ei_tx_intr(struct net_device *dev)
static void ei_receive(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned char rxing_page, this_frame, next_frame;
unsigned short current_offset;
int rx_pkt_count = 0;
@@ -1539,7 +1540,7 @@ static void ei_rx_overrun(struct net_device *dev)
static struct net_device_stats *get_stats(struct net_device *dev)
{
long ioaddr = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/* If the card is stopped, just return the present stats. */
@@ -1588,7 +1589,7 @@ static void do_set_multicast_list(struct net_device *dev)
{
long e8390_base = dev->base_addr;
int i;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
memset(ei_local->mcfilter, 0, 8);
@@ -1646,7 +1647,7 @@ static void AX88190_init(struct net_device *dev, int startp)
{
axnet_dev_t *info = PRIV(dev);
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int i;
int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
@@ -1712,7 +1713,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev);
if (inb_p(e8390_base) & E8390_TRANS)
{
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 0a2b0f9cdf33..76683d97d83b 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -1291,7 +1291,7 @@ updateCRC
static void updateCRC(int *CRC, int bit)
{
- int poly[]={
+ static const int poly[]={
1,1,1,0, 1,1,0,1,
1,0,1,1, 1,0,0,0,
1,0,0,0, 0,0,1,1,
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index d05c44692f08..2c158910f7ea 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
- PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index cb3d13e4e074..35fda5ac8120 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -64,7 +64,7 @@ config BCM63XX_PHY
config ICPLUS_PHY
tristate "Drivers for ICPlus PHYs"
---help---
- Currently supports the IP175C PHY.
+ Currently supports the IP175C and IP1001 PHYs.
config REALTEK_PHY
tristate "Drivers for Realtek PHYs"
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c1d2d251fe8b..9a09e24c30bc 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,7 +30,7 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers");
MODULE_AUTHOR("Michael Barkowski");
MODULE_LICENSE("GPL");
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev)
return 0;
}
+static int ip1001_config_init(struct phy_device *phydev)
+{
+ int err, value;
+
+ /* Software Reset PHY */
+ value = phy_read(phydev, MII_BMCR);
+ value |= BMCR_RESET;
+ err = phy_write(phydev, MII_BMCR, value);
+ if (err < 0)
+ return err;
+
+ do {
+ value = phy_read(phydev, MII_BMCR);
+ } while (value & BMCR_RESET);
+
+ /* Additional delay (2ns) used to adjust RX clock phase
+ * at GMII/ RGMII interface */
+ value = phy_read(phydev, 16);
+ value |= 0x3;
+
+ err = phy_write(phydev, 16, value);
+ if (err < 0)
+ return err;
+
+ return err;
+}
+
static int ip175c_read_status(struct phy_device *phydev)
{
if (phydev->addr == 4) /* WAN port */
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = {
.driver = { .owner = THIS_MODULE,},
};
-static int __init ip175c_init(void)
+static struct phy_driver ip1001_driver = {
+ .phy_id = 0x02430d90,
+ .name = "ICPlus IP1001",
+ .phy_id_mask = 0x0ffffff0,
+ .features = PHY_GBIT_FEATURES | SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause,
+ .config_init = &ip1001_config_init,
+ .config_aneg = &genphy_config_aneg,
+ .read_status = &genphy_read_status,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init icplus_init(void)
{
+ int ret = 0;
+
+ ret = phy_driver_register(&ip1001_driver);
+ if (ret < 0)
+ return -ENODEV;
+
return phy_driver_register(&ip175c_driver);
}
-static void __exit ip175c_exit(void)
+static void __exit icplus_exit(void)
{
+ phy_driver_unregister(&ip1001_driver);
phy_driver_unregister(&ip175c_driver);
}
-module_init(ip175c_init);
-module_exit(ip175c_exit);
+module_init(icplus_init);
+module_exit(icplus_exit);
static struct mdio_device_id __maybe_unused icplus_tbl[] = {
{ 0x02430d80, 0x0ffffff0 },
+ { 0x02430d90, 0x0ffffff0 },
{ }
};
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 7670aac0e93f..a8445c72fc13 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -47,11 +47,11 @@ void phy_print_status(struct phy_device *phydev)
pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev),
phydev->link ? "Up" : "Down");
if (phydev->link)
- printk(" - %d/%s", phydev->speed,
+ printk(KERN_CONT " - %d/%s", phydev->speed,
DUPLEX_FULL == phydev->duplex ?
"Full" : "Half");
- printk("\n");
+ printk(KERN_CONT "\n");
}
EXPORT_SYMBOL(phy_print_status);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 39659976a1ac..6456484c0299 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1136,8 +1136,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
a four-byte PPP header on each packet */
*skb_push(skb, 2) = 1;
if (ppp->pass_filter &&
- sk_run_filter(skb, ppp->pass_filter,
- ppp->pass_len) == 0) {
+ sk_run_filter(skb, ppp->pass_filter) == 0) {
if (ppp->debug & 1)
printk(KERN_DEBUG "PPP: outbound frame not passed\n");
kfree_skb(skb);
@@ -1145,8 +1144,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
}
/* if this packet passes the active filter, record the time */
if (!(ppp->active_filter &&
- sk_run_filter(skb, ppp->active_filter,
- ppp->active_len) == 0))
+ sk_run_filter(skb, ppp->active_filter) == 0))
ppp->last_xmit = jiffies;
skb_pull(skb, 2);
#else
@@ -1285,6 +1283,11 @@ ppp_push(struct ppp *ppp)
}
#ifdef CONFIG_PPP_MULTILINK
+static bool mp_protocol_compress __read_mostly = true;
+module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(mp_protocol_compress,
+ "compress protocol id in multilink fragments");
+
/*
* Divide a packet to be transmitted into fragments and
* send them out the individual links.
@@ -1347,10 +1350,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
if (nfree == 0 || nfree < navail / 2)
return 0; /* can't take now, leave it in xmit_pending */
- /* Do protocol field compression (XXX this should be optional) */
+ /* Do protocol field compression */
p = skb->data;
len = skb->len;
- if (*p == 0) {
+ if (*p == 0 && mp_protocol_compress) {
++p;
--len;
}
@@ -1758,8 +1761,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
*skb_push(skb, 2) = 0;
if (ppp->pass_filter &&
- sk_run_filter(skb, ppp->pass_filter,
- ppp->pass_len) == 0) {
+ sk_run_filter(skb, ppp->pass_filter) == 0) {
if (ppp->debug & 1)
printk(KERN_DEBUG "PPP: inbound frame "
"not passed\n");
@@ -1767,8 +1769,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
return;
}
if (!(ppp->active_filter &&
- sk_run_filter(skb, ppp->active_filter,
- ppp->active_len) == 0))
+ sk_run_filter(skb, ppp->active_filter) == 0))
ppp->last_recv = jiffies;
__skb_pull(skb, 2);
} else
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index d72fb0519a2a..78c0e3c9b2b5 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
abort:
kfree_skb(skb);
- return 0;
+ return 1;
}
/************************************************************************
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
index ccbc91326bfa..164cfad6ce79 100644
--- a/drivers/net/pptp.c
+++ b/drivers/net/pptp.c
@@ -277,7 +277,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
iph->tos = 0;
iph->daddr = rt->rt_dst;
iph->saddr = rt->rt_src;
- iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT);
+ iph->ttl = ip4_dst_hoplimit(&rt->dst);
iph->tot_len = htons(skb->len);
skb_dst_drop(skb);
@@ -673,8 +673,7 @@ static int __init pptp_init_module(void)
int err = 0;
pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n");
- callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *),
- GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+ callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *));
if (!callid_sock) {
pr_err("PPTP: cann't allocate memory\n");
return -ENOMEM;
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index 18c0297743f1..1b63c8aef121 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -1450,16 +1450,11 @@ static void pxa168_get_drvinfo(struct net_device *dev,
strncpy(info->bus_info, "N/A", 32);
}
-static u32 pxa168_get_link(struct net_device *dev)
-{
- return !!netif_carrier_ok(dev);
-}
-
static const struct ethtool_ops pxa168_ethtool_ops = {
.get_settings = pxa168_get_settings,
.set_settings = pxa168_set_settings,
.get_drvinfo = pxa168_get_drvinfo,
- .get_link = pxa168_get_link,
+ .get_link = ethtool_op_get_link,
};
static const struct net_device_ops pxa168_eth_netdev_ops = {
@@ -1607,7 +1602,7 @@ static int pxa168_eth_remove(struct platform_device *pdev)
mdiobus_unregister(pep->smi_bus);
mdiobus_free(pep->smi_bus);
unregister_netdev(dev);
- flush_scheduled_work();
+ cancel_work_sync(&pep->tx_timeout_task);
free_netdev(dev);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 7496ed2c34ab..1a3584edd79c 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2467,7 +2467,7 @@ map_error:
static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
struct net_device *ndev)
{
- struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
+ struct ql3_adapter *qdev = netdev_priv(ndev);
struct ql3xxx_port_registers __iomem *port_regs =
qdev->mem_map_registers;
struct ql_tx_buf_cb *tx_cb;
@@ -3390,7 +3390,7 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
static void ql_display_dev_info(struct net_device *ndev)
{
- struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
+ struct ql3_adapter *qdev = netdev_priv(ndev);
struct pci_dev *pdev = qdev->pdev;
netdev_info(ndev,
@@ -3573,7 +3573,7 @@ static int ql3xxx_open(struct net_device *ndev)
static int ql3xxx_set_mac_address(struct net_device *ndev, void *p)
{
- struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
+ struct ql3_adapter *qdev = netdev_priv(ndev);
struct ql3xxx_port_registers __iomem *port_regs =
qdev->mem_map_registers;
struct sockaddr *addr = p;
@@ -3608,7 +3608,7 @@ static int ql3xxx_set_mac_address(struct net_device *ndev, void *p)
static void ql3xxx_tx_timeout(struct net_device *ndev)
{
- struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
+ struct ql3_adapter *qdev = netdev_priv(ndev);
netdev_err(ndev, "Resetting...\n");
/*
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 8ecc170c9b74..9c2a02d204dc 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#ifndef _QLCNIC_H_
@@ -51,8 +34,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 11
-#define QLCNIC_LINUX_VERSIONID "5.0.11"
+#define _QLCNIC_LINUX_SUBVERSION 14
+#define QLCNIC_LINUX_VERSIONID "5.0.14"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -798,7 +781,6 @@ struct qlcnic_nic_intr_coalesce {
#define QLCNIC_H2C_OPCODE_GET_NET_STATS 16
#define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V 17
#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 18
-#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK 19
#define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE 20
#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21
#define QLCNIC_C2C_OPCODE 22
@@ -923,6 +905,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_MACSPOOF 0x200
#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400
#define QLCNIC_PROMISC_DISABLED 0x800
+#define QLCNIC_NEED_FLR 0x1000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
@@ -942,6 +925,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
+#define QLCNIC_LED_TEST 3
#define QLCNIC_FILTER_AGE 80
#define QLCNIC_READD_AGE 20
@@ -1126,8 +1110,7 @@ struct qlcnic_eswitch {
/* Return codes for Error handling */
#define QL_STATUS_INVALID_PARAM -1
-#define MAX_BW 100
-#define MIN_BW 1
+#define MAX_BW 100 /* % of link speed */
#define MAX_VLAN_ID 4095
#define MIN_VLAN_ID 2
#define MAX_TX_QUEUES 1
@@ -1135,7 +1118,7 @@ struct qlcnic_eswitch {
#define DEFAULT_MAC_LEARN 1
#define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan < MAX_VLAN_ID)
-#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW)
+#define IS_VALID_BW(bw) (bw <= MAX_BW)
#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES)
#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES)
@@ -1314,21 +1297,15 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring);
-void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
-int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
/* Functions from qlcnic_main.c */
-int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter);
-void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter);
int qlcnic_reset_context(struct qlcnic_adapter *);
u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
-int qlcnic_check_loopback_buff(unsigned char *data);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
-void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
/* Management functions */
int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
@@ -1377,6 +1354,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = {
"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x103c, 0x3733,
"NC523SFP 10Gb 2-port Server Adapter"},
+ {0x1077, 0x8020, 0x103c, 0x3346,
+ "CN1000Q Dual Port Converged Network Adapter"},
{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
};
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 1cdc05dade6b..27631f23b3fd 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#include "qlcnic.h"
@@ -480,6 +463,11 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter)
{
int err;
+ if (adapter->flags & QLCNIC_NEED_FLR) {
+ pci_reset_function(adapter->pdev);
+ adapter->flags &= ~QLCNIC_NEED_FLR;
+ }
+
err = qlcnic_fw_cmd_create_rx_ctx(adapter);
if (err)
return err;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index ec21d24015c4..1e7af709d395 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#include <linux/types.h>
@@ -101,8 +84,7 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
"Register_Test_on_offline",
"Link_Test_on_offline",
- "Interrupt_Test_offline",
- "Loopback_Test_offline"
+ "Interrupt_Test_offline"
};
#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
@@ -643,104 +625,6 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset)
}
}
-#define QLC_ILB_PKT_SIZE 64
-#define QLC_NUM_ILB_PKT 16
-#define QLC_ILB_MAX_RCV_LOOP 10
-
-static void qlcnic_create_loopback_buff(unsigned char *data)
-{
- unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
- memset(data, 0x4e, QLC_ILB_PKT_SIZE);
- memset(data, 0xff, 12);
- memcpy(data + 12, random_data, sizeof(random_data));
-}
-
-int qlcnic_check_loopback_buff(unsigned char *data)
-{
- unsigned char buff[QLC_ILB_PKT_SIZE];
- qlcnic_create_loopback_buff(buff);
- return memcmp(data, buff, QLC_ILB_PKT_SIZE);
-}
-
-static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
-{
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
- struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
- struct sk_buff *skb;
- int i, loop, cnt = 0;
-
- for (i = 0; i < QLC_NUM_ILB_PKT; i++) {
- skb = dev_alloc_skb(QLC_ILB_PKT_SIZE);
- qlcnic_create_loopback_buff(skb->data);
- skb_put(skb, QLC_ILB_PKT_SIZE);
-
- adapter->diag_cnt = 0;
- qlcnic_xmit_frame(skb, adapter->netdev);
-
- loop = 0;
- do {
- msleep(1);
- qlcnic_process_rcv_ring_diag(sds_ring);
- } while (loop++ < QLC_ILB_MAX_RCV_LOOP &&
- !adapter->diag_cnt);
-
- dev_kfree_skb_any(skb);
-
- if (!adapter->diag_cnt)
- dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
- " not recevied\n", i + 1);
- else
- cnt++;
- }
- if (cnt != i) {
- dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
- return -1;
- }
- return 0;
-}
-
-static int qlcnic_loopback_test(struct net_device *netdev)
-{
- struct qlcnic_adapter *adapter = netdev_priv(netdev);
- int max_sds_rings = adapter->max_sds_rings;
- int ret;
-
- if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
- dev_warn(&adapter->pdev->dev, "Loopback test not supported"
- "for non privilege function\n");
- return 0;
- }
-
- if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
- return -EIO;
-
- if (qlcnic_request_quiscent_mode(adapter)) {
- clear_bit(__QLCNIC_RESETTING, &adapter->state);
- return -EIO;
- }
-
- ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
- if (ret)
- goto clear_it;
-
- ret = qlcnic_set_ilb_mode(adapter);
- if (ret)
- goto done;
-
- ret = qlcnic_do_ilb_test(adapter);
-
- qlcnic_clear_ilb_mode(adapter);
-
-done:
- qlcnic_diag_free_res(netdev, max_sds_rings);
-
-clear_it:
- qlcnic_clear_quiscent_mode(adapter);
- adapter->max_sds_rings = max_sds_rings;
- clear_bit(__QLCNIC_RESETTING, &adapter->state);
- return ret;
-}
-
static int qlcnic_irq_test(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -793,9 +677,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
if (data[2])
eth_test->flags |= ETH_TEST_FL_FAILED;
- data[3] = qlcnic_loopback_test(dev);
- if (data[3])
- eth_test->flags |= ETH_TEST_FL_FAILED;
}
}
@@ -925,9 +806,10 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
dev->features &= ~NETIF_F_LRO;
qlcnic_send_lro_cleanup(adapter);
+ dev_info(&adapter->pdev->dev,
+ "disabling LRO as rx_csum is off\n");
}
adapter->rx_csum = !!data;
- dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n");
return 0;
}
@@ -952,16 +834,27 @@ static int qlcnic_set_tso(struct net_device *dev, u32 data)
static int qlcnic_blink_led(struct net_device *dev, u32 val)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
+ int max_sds_rings = adapter->max_sds_rings;
+ int dev_down = 0;
int ret;
- if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
- return -EIO;
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
+ dev_down = 1;
+ if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+ return -EIO;
+
+ ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
+ if (ret) {
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return ret;
+ }
+ }
ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
if (ret) {
dev_err(&adapter->pdev->dev,
"Failed to set LED blink state.\n");
- return ret;
+ goto done;
}
msleep_interruptible(val * 1000);
@@ -970,10 +863,16 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val)
if (ret) {
dev_err(&adapter->pdev->dev,
"Failed to reset LED blink state.\n");
- return ret;
+ goto done;
}
- return 0;
+done:
+ if (dev_down) {
+ qlcnic_diag_free_res(dev, max_sds_rings);
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ }
+ return ret;
+
}
static void
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 4290b80cde1a..726ef555b6bc 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#ifndef __QLCNIC_HDR_H_
@@ -638,7 +621,7 @@ enum {
#define PCIX_INT_MASK (0x10104)
#define PCIX_OCM_WINDOW (0x10800)
-#define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x20 * (func))
+#define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x4 * (func))
#define PCIX_TARGET_STATUS (0x10118)
#define PCIX_TARGET_STATUS_F1 (0x10160)
@@ -722,7 +705,7 @@ enum {
#define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */
#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */
-#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4)))
+#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) & (1 << (FN * 4)))
#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4)))
#define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4)))
#define QLC_DEV_SET_RST_RDY(VAL, FN) ((VAL) |= (1 << (FN * 4)))
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 7a47a2a7ee27..616940f0a8d0 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#include "qlcnic.h"
@@ -398,7 +381,7 @@ 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)
+static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr)
{
struct list_head *head;
struct qlcnic_mac_list_s *cur;
@@ -432,7 +415,9 @@ void qlcnic_set_multi(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct netdev_hw_addr *ha;
- u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ static const u8 bcast_addr[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
u32 mode = VPORT_MISS_MODE_DROP;
if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
@@ -638,10 +623,11 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
u64 word;
int i, rv;
- const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
- 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
- 0x255b0ec26d5a56daULL };
-
+ static const u64 key[] = {
+ 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL
+ };
memset(&req, 0, sizeof(struct qlcnic_nic_req));
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -1234,56 +1220,3 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
return rv;
}
-
-static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag)
-{
- struct qlcnic_nic_req req;
- int rv;
- u64 word;
-
- memset(&req, 0, sizeof(struct qlcnic_nic_req));
- req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
-
- word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
- ((u64)adapter->portnum << 16);
- req.req_hdr = cpu_to_le64(word);
- req.words[0] = cpu_to_le64(flag);
-
- rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
- if (rv)
- dev_err(&adapter->pdev->dev,
- "%sting loopback mode failed.\n",
- flag ? "Set" : "Reset");
- return rv;
-}
-
-int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter)
-{
- if (qlcnic_set_fw_loopback(adapter, 1))
- return -EIO;
-
- if (qlcnic_nic_set_promisc(adapter,
- VPORT_MISS_MODE_ACCEPT_ALL)) {
- qlcnic_set_fw_loopback(adapter, 0);
- return -EIO;
- }
-
- msleep(1000);
- return 0;
-}
-
-void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
-{
- int mode = VPORT_MISS_MODE_DROP;
- struct net_device *netdev = adapter->netdev;
-
- qlcnic_set_fw_loopback(adapter, 0);
-
- if (netdev->flags & IFF_PROMISC)
- mode = VPORT_MISS_MODE_ACCEPT_ALL;
- else if (netdev->flags & IFF_ALLMULTI)
- mode = VPORT_MISS_MODE_ACCEPT_MULTI;
-
- qlcnic_nic_set_promisc(adapter, mode);
- msleep(1000);
-}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 0d180c6e41fe..9b9c7c39d3ee 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#include <linux/netdevice.h>
@@ -236,12 +219,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
tx_ring->num_desc = adapter->num_txd;
tx_ring->txq = netdev_get_tx_queue(netdev, 0);
- cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
+ cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n");
goto err_out;
}
- memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx;
@@ -275,14 +257,12 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
rds_ring->dma_size + NET_IP_ALIGN;
break;
}
- rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *)
- vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+ rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
if (rds_ring->rx_buf_arr == NULL) {
dev_err(&netdev->dev, "Failed to allocate "
"rx buffer ring %d\n", ring);
goto err_out;
}
- memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
INIT_LIST_HEAD(&rds_ring->free_list);
/*
* Now go through all of them, set reference handles
@@ -1693,99 +1673,6 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
spin_unlock(&rds_ring->lock);
}
-static void dump_skb(struct sk_buff *skb)
-{
- int i;
- unsigned char *data = skb->data;
-
- for (i = 0; i < skb->len; i++) {
- printk("%02x ", data[i]);
- if ((i & 0x0f) == 8)
- printk("\n");
- }
-}
-
-static struct qlcnic_rx_buffer *
-qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
- struct qlcnic_host_sds_ring *sds_ring,
- int ring, u64 sts_data0)
-{
- struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
- struct qlcnic_rx_buffer *buffer;
- struct sk_buff *skb;
- struct qlcnic_host_rds_ring *rds_ring;
- int index, length, cksum, pkt_offset;
-
- if (unlikely(ring >= adapter->max_rds_rings))
- return NULL;
-
- rds_ring = &recv_ctx->rds_rings[ring];
-
- index = qlcnic_get_sts_refhandle(sts_data0);
- if (unlikely(index >= rds_ring->num_desc))
- return NULL;
-
- buffer = &rds_ring->rx_buf_arr[index];
-
- length = qlcnic_get_sts_totallength(sts_data0);
- cksum = qlcnic_get_sts_status(sts_data0);
- pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
-
- skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
- if (!skb)
- return buffer;
-
- if (length > rds_ring->skb_size)
- skb_put(skb, rds_ring->skb_size);
- else
- skb_put(skb, length);
-
- if (pkt_offset)
- skb_pull(skb, pkt_offset);
-
- if (!qlcnic_check_loopback_buff(skb->data))
- adapter->diag_cnt++;
- else
- dump_skb(skb);
-
- dev_kfree_skb_any(skb);
- adapter->stats.rx_pkts++;
- adapter->stats.rxbytes += length;
-
- return buffer;
-}
-
-void
-qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
-{
- struct qlcnic_adapter *adapter = sds_ring->adapter;
- struct status_desc *desc;
- struct qlcnic_rx_buffer *rxbuf;
- u64 sts_data0;
-
- int opcode, ring, desc_cnt;
- u32 consumer = sds_ring->consumer;
-
- desc = &sds_ring->desc_head[consumer];
- sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
-
- if (!(sts_data0 & STATUS_OWNER_HOST))
- return;
-
- desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
- opcode = qlcnic_get_sts_opcode(sts_data0);
-
- ring = qlcnic_get_sts_type(sts_data0);
- rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring,
- ring, sts_data0);
-
- desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
- consumer = get_next_index(consumer, sds_ring->num_desc);
-
- sds_ring->consumer = consumer;
- writel(consumer, sds_ring->crb_sts_consumer);
-}
-
void
qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
u8 alt_mac, u8 *mac)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index a3dcd04be22f..11e3a46c0911 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1,25 +1,8 @@
/*
- * Copyright (C) 2009 - QLogic 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c) 2009-2010 QLogic Corporation
*
+ * See LICENSE.qlcnic for copyright and licensing details.
*/
#include <linux/slab.h>
@@ -1546,6 +1529,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_out_iounmap;
+ adapter->flags |= QLCNIC_NEED_FLR;
+
err = adapter->nic_ops->start_firmware(adapter);
if (err) {
dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n");
@@ -2854,61 +2839,6 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
qlcnic_api_unlock(adapter);
}
-/* Caller should held RESETTING bit.
- * This should be call in sync with qlcnic_request_quiscent_mode.
- */
-void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter)
-{
- qlcnic_clr_drv_state(adapter);
- qlcnic_api_lock(adapter);
- QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
- qlcnic_api_unlock(adapter);
-}
-
-/* Caller should held RESETTING bit.
- */
-int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter)
-{
- u8 timeo = adapter->dev_init_timeo / 2;
- u32 state;
-
- if (qlcnic_api_lock(adapter))
- return -EIO;
-
- state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (state != QLCNIC_DEV_READY)
- return -EIO;
-
- QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT);
- qlcnic_api_unlock(adapter);
- QLCDB(adapter, DRV, "NEED QUISCENT state set\n");
- qlcnic_idc_debug_info(adapter, 0);
-
- qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT);
-
- do {
- msleep(2000);
- state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (state == QLCNIC_DEV_QUISCENT)
- return 0;
- if (!qlcnic_check_drv_state(adapter)) {
- if (qlcnic_api_lock(adapter))
- return -EIO;
- QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
- QLCNIC_DEV_QUISCENT);
- qlcnic_api_unlock(adapter);
- QLCDB(adapter, DRV, "QUISCENT mode set\n");
- return 0;
- }
- } while (--timeo);
-
- dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x"
- " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE),
- QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE));
- qlcnic_clear_quiscent_mode(adapter);
- return -EIO;
-}
-
/*Transit to RESET state from READY state only */
static void
qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
@@ -3587,9 +3517,12 @@ validate_esw_config(struct qlcnic_adapter *adapter,
case QLCNIC_PORT_DEFAULTS:
if (QLC_DEV_GET_DRV(op_mode, pci_func) !=
QLCNIC_NON_PRIV_FUNC) {
- esw_cfg[i].mac_anti_spoof = 0;
- esw_cfg[i].mac_override = 1;
- esw_cfg[i].promisc_mode = 1;
+ if (esw_cfg[i].mac_anti_spoof != 0)
+ return QL_STATUS_INVALID_PARAM;
+ if (esw_cfg[i].mac_override != 1)
+ return QL_STATUS_INVALID_PARAM;
+ if (esw_cfg[i].promisc_mode != 1)
+ return QL_STATUS_INVALID_PARAM;
}
break;
case QLCNIC_ADD_VLAN:
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 22821398fc63..4757c59a07a2 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -16,7 +16,7 @@
*/
#define DRV_NAME "qlge"
#define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION "v1.00.00.25.00.00-01"
+#define DRV_VERSION "v1.00.00.27.00.00-01"
#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */
@@ -2083,6 +2083,7 @@ struct ql_adapter {
u32 mailbox_in;
u32 mailbox_out;
struct mbox_params idc_mbc;
+ struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
@@ -2221,6 +2222,7 @@ int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
int ql_unpause_mpi_risc(struct ql_adapter *qdev);
int ql_pause_mpi_risc(struct ql_adapter *qdev);
int ql_hard_reset_mpi_risc(struct ql_adapter *qdev);
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev);
int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
u32 ram_addr, int word_count);
int ql_core_dump(struct ql_adapter *qdev,
@@ -2236,6 +2238,7 @@ int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
int ql_mb_get_port_cfg(struct ql_adapter *qdev);
int ql_mb_set_port_cfg(struct ql_adapter *qdev);
int ql_wait_fifo_empty(struct ql_adapter *qdev);
+void ql_get_dump(struct ql_adapter *qdev, void *buff);
void ql_gen_reg_dump(struct ql_adapter *qdev,
struct ql_reg_dump *mpi_coredump);
netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev);
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 4747492935ef..fca804f36d61 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -1317,9 +1317,28 @@ void ql_gen_reg_dump(struct ql_adapter *qdev,
status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
if (status)
return;
+}
+
+void ql_get_dump(struct ql_adapter *qdev, void *buff)
+{
+ /*
+ * If the dump has already been taken and is stored
+ * in our internal buffer and if force dump is set then
+ * just start the spool to dump it to the log file
+ * and also, take a snapshot of the general regs to
+ * to the user's buffer or else take complete dump
+ * to the user's buffer if force is not set.
+ */
- if (test_bit(QL_FRC_COREDUMP, &qdev->flags))
+ if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) {
+ if (!ql_core_dump(qdev, buff))
+ ql_soft_reset_mpi_risc(qdev);
+ else
+ netif_err(qdev, drv, qdev->ndev, "coredump failed!\n");
+ } else {
+ ql_gen_reg_dump(qdev, buff);
ql_get_core_dump(qdev);
+ }
}
/* Coredump to messages log file using separate worker thread */
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 4892d64f4e05..8149cc9de4ca 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -375,7 +375,10 @@ static void ql_get_drvinfo(struct net_device *ndev,
strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32);
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
- drvinfo->regdump_len = 0;
+ if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+ drvinfo->regdump_len = sizeof(struct ql_mpi_coredump);
+ else
+ drvinfo->regdump_len = sizeof(struct ql_reg_dump);
drvinfo->eedump_len = 0;
}
@@ -547,7 +550,12 @@ static void ql_self_test(struct net_device *ndev,
static int ql_get_regs_len(struct net_device *ndev)
{
- return sizeof(struct ql_reg_dump);
+ struct ql_adapter *qdev = netdev_priv(ndev);
+
+ if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+ return sizeof(struct ql_mpi_coredump);
+ else
+ return sizeof(struct ql_reg_dump);
}
static void ql_get_regs(struct net_device *ndev,
@@ -555,7 +563,12 @@ static void ql_get_regs(struct net_device *ndev,
{
struct ql_adapter *qdev = netdev_priv(ndev);
- ql_gen_reg_dump(qdev, p);
+ ql_get_dump(qdev, p);
+ qdev->core_is_dumped = 0;
+ if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+ regs->len = sizeof(struct ql_mpi_coredump);
+ else
+ regs->len = sizeof(struct ql_reg_dump);
}
static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 528eaef5308f..49bfa5813068 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3548,12 +3548,13 @@ err_irq:
static int ql_start_rss(struct ql_adapter *qdev)
{
- u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
- 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
- 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
- 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
- 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
- 0xbe, 0xac, 0x01, 0xfa};
+ static const u8 init_hash_seed[] = {
+ 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+ 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
+ 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
+ 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
+ 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+ };
struct ricb *ricb = &qdev->ricb;
int status = 0;
int i;
@@ -3844,7 +3845,7 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
static void ql_display_dev_info(struct net_device *ndev)
{
- struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
+ struct ql_adapter *qdev = netdev_priv(ndev);
netif_info(qdev, probe, qdev->ndev,
"Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
@@ -4264,7 +4265,7 @@ static struct net_device_stats *qlge_get_stats(struct net_device
static void qlge_set_multicast_list(struct net_device *ndev)
{
- struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
+ struct ql_adapter *qdev = netdev_priv(ndev);
struct netdev_hw_addr *ha;
int i, status;
@@ -4354,7 +4355,7 @@ exit:
static int qlge_set_mac_address(struct net_device *ndev, void *p)
{
- struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
+ struct ql_adapter *qdev = netdev_priv(ndev);
struct sockaddr *addr = p;
int status;
@@ -4377,7 +4378,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
static void qlge_tx_timeout(struct net_device *ndev)
{
- struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
+ struct ql_adapter *qdev = netdev_priv(ndev);
ql_queue_asic_error(qdev);
}
@@ -4629,6 +4630,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
init_completion(&qdev->ide_completion);
+ mutex_init(&qdev->mpi_mutex);
if (!cards_found) {
dev_info(&pdev->dev, "%s\n", DRV_STRING);
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 0e7c7c7ee164..ff2bf8a4e247 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -87,7 +87,7 @@ exit:
return status;
}
-static int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
{
int status;
status = ql_write_mpi_reg(qdev, 0x00001010, 1);
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
int status;
unsigned long count;
+ mutex_lock(&qdev->mpi_mutex);
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -603,6 +604,7 @@ done:
end:
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+ mutex_unlock(&qdev->mpi_mutex);
return status;
}
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev)
static int ql_set_port_cfg(struct ql_adapter *qdev)
{
int status;
- rtnl_lock();
status = ql_mb_set_port_cfg(qdev);
- rtnl_unlock();
if (status)
return status;
status = ql_idc_wait(qdev);
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
int status;
- rtnl_lock();
status = ql_mb_get_port_cfg(qdev);
- rtnl_unlock();
if (status) {
netif_err(qdev, drv, qdev->ndev,
"Bug: Failed to get port config data.\n");
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work)
u32 aen;
int timeout;
- rtnl_lock();
aen = mbcp->mbox_out[1] >> 16;
timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work)
}
break;
}
- rtnl_unlock();
}
void ql_mpi_work(struct work_struct *work)
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work)
struct mbox_params *mbcp = &mbc;
int err = 0;
- rtnl_lock();
+ mutex_lock(&qdev->mpi_mutex);
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work)
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
- rtnl_unlock();
+ mutex_unlock(&qdev->mpi_mutex);
ql_enable_completion_interrupt(qdev, 0);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7d33ef4bcb4a..27a7c20f64cd 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
+#include <linux/firmware.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -33,6 +34,9 @@
#define MODULENAME "r8169"
#define PFX MODULENAME ": "
+#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
+#define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw"
+
#ifdef RTL8169_DEBUG
#define assert(expr) \
if (!(expr)) { \
@@ -63,7 +67,6 @@ static const int multicast_filter_limit = 32;
#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
-#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
@@ -118,7 +121,8 @@ enum mac_version {
RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
- RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP
+ RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP
+ RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP
};
#define _R(NAME,MAC,MASK) \
@@ -155,7 +159,8 @@ static const struct {
_R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
_R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
_R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
- _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880) // PCI-E
+ _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E
+ _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E
};
#undef _R
@@ -227,7 +232,14 @@ enum rtl_registers {
IntrMitigate = 0xe2,
RxDescAddrLow = 0xe4,
RxDescAddrHigh = 0xe8,
- EarlyTxThres = 0xec,
+ EarlyTxThres = 0xec, /* 8169. Unit of 32 bytes. */
+
+#define NoEarlyTx 0x3f /* Max value : no early transmit. */
+
+ MaxTxPacketSize = 0xec, /* 8101/8168. Unit of 128 bytes. */
+
+#define TxPacketMax (8064 >> 7)
+
FuncEvent = 0xf0,
FuncEventMask = 0xf4,
FuncPresetState = 0xf8,
@@ -248,7 +260,7 @@ enum rtl8168_8101_registers {
#define CSIAR_BYTE_ENABLE 0x0f
#define CSIAR_BYTE_ENABLE_SHIFT 12
#define CSIAR_ADDR_MASK 0x0fff
-
+ PMCH = 0x6f,
EPHYAR = 0x80,
#define EPHYAR_FLAG 0x80000000
#define EPHYAR_WRITE_CMD 0x80000000
@@ -267,6 +279,33 @@ enum rtl8168_8101_registers {
#define EFUSEAR_DATA_MASK 0xff
};
+enum rtl8168_registers {
+ ERIDR = 0x70,
+ ERIAR = 0x74,
+#define ERIAR_FLAG 0x80000000
+#define ERIAR_WRITE_CMD 0x80000000
+#define ERIAR_READ_CMD 0x00000000
+#define ERIAR_ADDR_BYTE_ALIGN 4
+#define ERIAR_EXGMAC 0
+#define ERIAR_MSIX 1
+#define ERIAR_ASF 2
+#define ERIAR_TYPE_SHIFT 16
+#define ERIAR_BYTEEN 0x0f
+#define ERIAR_BYTEEN_SHIFT 12
+ EPHY_RXER_NUM = 0x7c,
+ OCPDR = 0xb0, /* OCP GPHY access */
+#define OCPDR_WRITE_CMD 0x80000000
+#define OCPDR_READ_CMD 0x00000000
+#define OCPDR_REG_MASK 0x7f
+#define OCPDR_GPHY_REG_SHIFT 16
+#define OCPDR_DATA_MASK 0xffff
+ OCPAR = 0xb4,
+#define OCPAR_FLAG 0x80000000
+#define OCPAR_GPHY_WRITE_CMD 0x8000f060
+#define OCPAR_GPHY_READ_CMD 0x0000f060
+ RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */
+};
+
enum rtl_register_content {
/* InterruptStatusBits */
SYSErr = 0x8000,
@@ -490,11 +529,22 @@ struct rtl8169_private {
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
#endif
+
+ struct mdio_ops {
+ void (*write)(void __iomem *, int, int);
+ int (*read)(void __iomem *, int);
+ } mdio_ops;
+
+ struct pll_power_ops {
+ void (*down)(struct rtl8169_private *);
+ void (*up)(struct rtl8169_private *);
+ } pll_power_ops;
+
int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
- void (*phy_reset_enable)(void __iomem *);
+ void (*phy_reset_enable)(struct rtl8169_private *tp);
void (*hw_start)(struct net_device *);
- unsigned int (*phy_reset_pending)(void __iomem *);
+ unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
unsigned int (*link_ok)(void __iomem *);
int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
int pcie_cap;
@@ -514,6 +564,8 @@ module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
+MODULE_FIRMWARE(FIRMWARE_8168D_1);
+MODULE_FIRMWARE(FIRMWARE_8168D_2);
static int rtl8169_open(struct net_device *dev);
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -535,7 +587,82 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
-static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ int i;
+
+ RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
+ for (i = 0; i < 20; i++) {
+ udelay(100);
+ if (RTL_R32(OCPAR) & OCPAR_FLAG)
+ break;
+ }
+ return RTL_R32(OCPDR);
+}
+
+static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ int i;
+
+ RTL_W32(OCPDR, data);
+ RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
+ for (i = 0; i < 20; i++) {
+ udelay(100);
+ if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0)
+ break;
+ }
+}
+
+static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)
+{
+ int i;
+
+ RTL_W8(ERIDR, cmd);
+ RTL_W32(ERIAR, 0x800010e8);
+ msleep(2);
+ for (i = 0; i < 5; i++) {
+ udelay(100);
+ if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+ break;
+ }
+
+ ocp_write(ioaddr, 0x1, 0x30, 0x00000001);
+}
+
+#define OOB_CMD_RESET 0x00
+#define OOB_CMD_DRIVER_START 0x05
+#define OOB_CMD_DRIVER_STOP 0x06
+
+static void rtl8168_driver_start(struct rtl8169_private *tp)
+{
+ int i;
+
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
+
+ for (i = 0; i < 10; i++) {
+ msleep(10);
+ if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800)
+ break;
+ }
+}
+
+static void rtl8168_driver_stop(struct rtl8169_private *tp)
+{
+ int i;
+
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+
+ for (i = 0; i < 10; i++) {
+ msleep(10);
+ if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0)
+ break;
+ }
+}
+
+
+static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
int i;
@@ -557,7 +684,7 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
udelay(20);
}
-static int mdio_read(void __iomem *ioaddr, int reg_addr)
+static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
{
int i, value = -1;
@@ -583,34 +710,117 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
return value;
}
-static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
+static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
{
- mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
+ int i;
+
+ RTL_W32(OCPDR, data |
+ ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
+ RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
+ RTL_W32(EPHY_RXER_NUM, 0);
+
+ for (i = 0; i < 100; i++) {
+ mdelay(1);
+ if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
+ break;
+ }
}
-static void mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m)
+static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+{
+ r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
+ (value & OCPDR_DATA_MASK));
+}
+
+static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
+{
+ int i;
+
+ r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);
+
+ mdelay(1);
+ RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
+ RTL_W32(EPHY_RXER_NUM, 0);
+
+ for (i = 0; i < 100; i++) {
+ mdelay(1);
+ if (RTL_R32(OCPAR) & OCPAR_FLAG)
+ break;
+ }
+
+ return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
+}
+
+#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
+
+static void r8168dp_2_mdio_start(void __iomem *ioaddr)
+{
+ RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
+}
+
+static void r8168dp_2_mdio_stop(void __iomem *ioaddr)
+{
+ RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
+}
+
+static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+{
+ r8168dp_2_mdio_start(ioaddr);
+
+ r8169_mdio_write(ioaddr, reg_addr, value);
+
+ r8168dp_2_mdio_stop(ioaddr);
+}
+
+static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
+{
+ int value;
+
+ r8168dp_2_mdio_start(ioaddr);
+
+ value = r8169_mdio_read(ioaddr, reg_addr);
+
+ r8168dp_2_mdio_stop(ioaddr);
+
+ return value;
+}
+
+static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
+{
+ tp->mdio_ops.write(tp->mmio_addr, location, val);
+}
+
+static int rtl_readphy(struct rtl8169_private *tp, int location)
+{
+ return tp->mdio_ops.read(tp->mmio_addr, location);
+}
+
+static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
+{
+ rtl_writephy(tp, reg_addr, rtl_readphy(tp, reg_addr) | value);
+}
+
+static void rtl_w1w0_phy(struct rtl8169_private *tp, int reg_addr, int p, int m)
{
int val;
- val = mdio_read(ioaddr, reg_addr);
- mdio_write(ioaddr, reg_addr, (val | p) & ~m);
+ val = rtl_readphy(tp, reg_addr);
+ rtl_writephy(tp, reg_addr, (val | p) & ~m);
}
static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
int val)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- mdio_write(ioaddr, location, val);
+ rtl_writephy(tp, location, val);
}
static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- return mdio_read(ioaddr, location);
+ return rtl_readphy(tp, location);
}
static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
@@ -711,14 +921,16 @@ static void rtl8169_asic_down(void __iomem *ioaddr)
RTL_R16(CPlusCmd);
}
-static unsigned int rtl8169_tbi_reset_pending(void __iomem *ioaddr)
+static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
return RTL_R32(TBICSR) & TBIReset;
}
-static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr)
+static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp)
{
- return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET;
+ return rtl_readphy(tp, MII_BMCR) & BMCR_RESET;
}
static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
@@ -731,39 +943,51 @@ static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr)
return RTL_R8(PHYstatus) & LinkStatus;
}
-static void rtl8169_tbi_reset_enable(void __iomem *ioaddr)
+static void rtl8169_tbi_reset_enable(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
}
-static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
+static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
{
unsigned int val;
- val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
- mdio_write(ioaddr, MII_BMCR, val & 0xffff);
+ val = rtl_readphy(tp, MII_BMCR) | BMCR_RESET;
+ rtl_writephy(tp, MII_BMCR, val & 0xffff);
}
-static void rtl8169_check_link_status(struct net_device *dev,
+static void __rtl8169_check_link_status(struct net_device *dev,
struct rtl8169_private *tp,
- void __iomem *ioaddr)
+ void __iomem *ioaddr,
+ bool pm)
{
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
if (tp->link_ok(ioaddr)) {
/* This is to cancel a scheduled suspend if there's one. */
- pm_request_resume(&tp->pci_dev->dev);
+ if (pm)
+ pm_request_resume(&tp->pci_dev->dev);
netif_carrier_on(dev);
netif_info(tp, ifup, dev, "link up\n");
} else {
netif_carrier_off(dev);
netif_info(tp, ifdown, dev, "link down\n");
- pm_schedule_suspend(&tp->pci_dev->dev, 100);
+ if (pm)
+ pm_schedule_suspend(&tp->pci_dev->dev, 100);
}
spin_unlock_irqrestore(&tp->lock, flags);
}
+static void rtl8169_check_link_status(struct net_device *dev,
+ struct rtl8169_private *tp,
+ void __iomem *ioaddr)
+{
+ __rtl8169_check_link_status(dev, tp, ioaddr, false);
+}
+
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -895,18 +1119,17 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
u8 autoneg, u16 speed, u8 duplex)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
int giga_ctrl, bmcr;
if (autoneg == AUTONEG_ENABLE) {
int auto_nego;
- auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
+ auto_nego = rtl_readphy(tp, MII_ADVERTISE);
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
+ giga_ctrl = rtl_readphy(tp, MII_CTRL1000);
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
/* The 8100e/8101e/8102e do Fast Ethernet only. */
@@ -934,12 +1157,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
* Vendor specific (0x1f) and reserved (0x0e) MII
* registers.
*/
- mdio_write(ioaddr, 0x1f, 0x0000);
- mdio_write(ioaddr, 0x0e, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0e, 0x0000);
}
- mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
- mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
+ rtl_writephy(tp, MII_ADVERTISE, auto_nego);
+ rtl_writephy(tp, MII_CTRL1000, giga_ctrl);
} else {
giga_ctrl = 0;
@@ -953,21 +1176,21 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
if (duplex == DUPLEX_FULL)
bmcr |= BMCR_FULLDPLX;
- mdio_write(ioaddr, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
}
tp->phy_1000_ctrl_reg = giga_ctrl;
- mdio_write(ioaddr, MII_BMCR, bmcr);
+ rtl_writephy(tp, MII_BMCR, bmcr);
if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
(tp->mac_version == RTL_GIGA_MAC_VER_03)) {
if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
- mdio_write(ioaddr, 0x17, 0x2138);
- mdio_write(ioaddr, 0x0e, 0x0260);
+ rtl_writephy(tp, 0x17, 0x2138);
+ rtl_writephy(tp, 0x0e, 0x0260);
} else {
- mdio_write(ioaddr, 0x17, 0x2108);
- mdio_write(ioaddr, 0x0e, 0x0000);
+ rtl_writephy(tp, 0x17, 0x2108);
+ rtl_writephy(tp, 0x0e, 0x0000);
}
}
@@ -1309,9 +1532,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
/* 8168D family. */
{ 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
{ 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
- { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 },
{ 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
+ /* 8168DP family. */
+ { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 },
+ { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 },
+
/* 8168C family. */
{ 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
{ 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 },
@@ -1375,15 +1601,74 @@ struct phy_reg {
u16 val;
};
-static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int len)
+static void rtl_writephy_batch(struct rtl8169_private *tp,
+ const struct phy_reg *regs, int len)
{
while (len-- > 0) {
- mdio_write(ioaddr, regs->reg, regs->val);
+ rtl_writephy(tp, regs->reg, regs->val);
regs++;
}
}
-static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
+#define PHY_READ 0x00000000
+#define PHY_DATA_OR 0x10000000
+#define PHY_DATA_AND 0x20000000
+#define PHY_BJMPN 0x30000000
+#define PHY_READ_EFUSE 0x40000000
+#define PHY_READ_MAC_BYTE 0x50000000
+#define PHY_WRITE_MAC_BYTE 0x60000000
+#define PHY_CLEAR_READCOUNT 0x70000000
+#define PHY_WRITE 0x80000000
+#define PHY_READCOUNT_EQ_SKIP 0x90000000
+#define PHY_COMP_EQ_SKIPN 0xa0000000
+#define PHY_COMP_NEQ_SKIPN 0xb0000000
+#define PHY_WRITE_PREVIOUS 0xc0000000
+#define PHY_SKIPN 0xd0000000
+#define PHY_DELAY_MS 0xe0000000
+#define PHY_WRITE_ERI_WORD 0xf0000000
+
+static void
+rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
+{
+ __le32 *phytable = (__le32 *)fw->data;
+ struct net_device *dev = tp->dev;
+ size_t i;
+
+ if (fw->size % sizeof(*phytable)) {
+ netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
+ return;
+ }
+
+ for (i = 0; i < fw->size / sizeof(*phytable); i++) {
+ u32 action = le32_to_cpu(phytable[i]);
+
+ if (!action)
+ break;
+
+ if ((action & 0xf0000000) != PHY_WRITE) {
+ netif_err(tp, probe, dev,
+ "unknown action 0x%08x\n", action);
+ return;
+ }
+ }
+
+ while (i-- != 0) {
+ u32 action = le32_to_cpu(*phytable);
+ u32 data = action & 0x0000ffff;
+ u32 reg = (action & 0x0fff0000) >> 16;
+
+ switch(action & 0xf0000000) {
+ case PHY_WRITE:
+ rtl_writephy(tp, reg, data);
+ phytable++;
+ break;
+ default:
+ BUG();
+ }
+ }
+}
+
+static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1447,10 +1732,10 @@ static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
{ 0x00, 0x9200 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
+static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 },
@@ -1458,11 +1743,10 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp,
- void __iomem *ioaddr)
+static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp)
{
struct pci_dev *pdev = tp->pci_dev;
u16 vendor_id, device_id;
@@ -1473,13 +1757,12 @@ static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp,
if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000))
return;
- mdio_write(ioaddr, 0x1f, 0x0001);
- mdio_write(ioaddr, 0x10, 0xf01b);
- mdio_write(ioaddr, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0001);
+ rtl_writephy(tp, 0x10, 0xf01b);
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
- void __iomem *ioaddr)
+static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1521,12 +1804,12 @@ static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- rtl8169scd_hw_phy_config_quirk(tp, ioaddr);
+ rtl8169scd_hw_phy_config_quirk(tp);
}
-static void rtl8169sce_hw_phy_config(void __iomem *ioaddr)
+static void rtl8169sce_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1576,23 +1859,23 @@ static void rtl8169sce_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168bb_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x10, 0xf41b },
{ 0x1f, 0x0000 }
};
- mdio_write(ioaddr, 0x1f, 0x0001);
- mdio_patch(ioaddr, 0x16, 1 << 0);
+ rtl_writephy(tp, 0x1f, 0x0001);
+ rtl_patchphy(tp, 0x16, 1 << 0);
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168bef_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1600,10 +1883,10 @@ static void rtl8168bef_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168cp_1_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0000 },
@@ -1613,10 +1896,10 @@ static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168cp_2_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1624,14 +1907,14 @@ static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- mdio_write(ioaddr, 0x1f, 0x0000);
- mdio_patch(ioaddr, 0x14, 1 << 5);
- mdio_patch(ioaddr, 0x0d, 1 << 5);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_patchphy(tp, 0x14, 1 << 5);
+ rtl_patchphy(tp, 0x0d, 1 << 5);
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168c_1_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1653,14 +1936,14 @@ static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr)
{ 0x09, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- mdio_patch(ioaddr, 0x14, 1 << 5);
- mdio_patch(ioaddr, 0x0d, 1 << 5);
- mdio_write(ioaddr, 0x1f, 0x0000);
+ rtl_patchphy(tp, 0x14, 1 << 5);
+ rtl_patchphy(tp, 0x0d, 1 << 5);
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168c_2_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1680,15 +1963,15 @@ static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- mdio_patch(ioaddr, 0x16, 1 << 0);
- mdio_patch(ioaddr, 0x14, 1 << 5);
- mdio_patch(ioaddr, 0x0d, 1 << 5);
- mdio_write(ioaddr, 0x1f, 0x0000);
+ rtl_patchphy(tp, 0x16, 1 << 0);
+ rtl_patchphy(tp, 0x14, 1 << 5);
+ rtl_patchphy(tp, 0x0d, 1 << 5);
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168c_3_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0001 },
@@ -1702,22 +1985,23 @@ static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- mdio_patch(ioaddr, 0x16, 1 << 0);
- mdio_patch(ioaddr, 0x14, 1 << 5);
- mdio_patch(ioaddr, 0x0d, 1 << 5);
- mdio_write(ioaddr, 0x1f, 0x0000);
+ rtl_patchphy(tp, 0x16, 1 << 0);
+ rtl_patchphy(tp, 0x14, 1 << 5);
+ rtl_patchphy(tp, 0x0d, 1 << 5);
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168c_4_hw_phy_config(struct rtl8169_private *tp)
{
- rtl8168c_3_hw_phy_config(ioaddr);
+ rtl8168c_3_hw_phy_config(tp);
}
-static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init_0[] = {
+ /* Channel Estimation */
{ 0x1f, 0x0001 },
{ 0x06, 0x4064 },
{ 0x07, 0x2863 },
@@ -1734,378 +2018,40 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
{ 0x12, 0xf49f },
{ 0x13, 0x070b },
{ 0x1a, 0x05ad },
- { 0x14, 0x94c0 }
- };
- static const struct phy_reg phy_reg_init_1[] = {
+ { 0x14, 0x94c0 },
+
+ /*
+ * Tx Error Issue
+ * enhance line driver power
+ */
{ 0x1f, 0x0002 },
{ 0x06, 0x5561 },
{ 0x1f, 0x0005 },
{ 0x05, 0x8332 },
- { 0x06, 0x5561 }
- };
- static const struct phy_reg phy_reg_init_2[] = {
- { 0x1f, 0x0005 },
- { 0x05, 0xffc2 },
- { 0x1f, 0x0005 },
- { 0x05, 0x8000 },
- { 0x06, 0xf8f9 },
- { 0x06, 0xfaef },
- { 0x06, 0x59ee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x00e0 },
- { 0x06, 0xf87c },
- { 0x06, 0xe1f8 },
- { 0x06, 0x7d59 },
- { 0x06, 0x0fef },
- { 0x06, 0x0139 },
- { 0x06, 0x029e },
- { 0x06, 0x06ef },
- { 0x06, 0x1039 },
- { 0x06, 0x089f },
- { 0x06, 0x2aee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x01e0 },
- { 0x06, 0xf87c },
- { 0x06, 0xe1f8 },
- { 0x06, 0x7d58 },
- { 0x06, 0x409e },
- { 0x06, 0x0f39 },
- { 0x06, 0x46aa },
- { 0x06, 0x0bbf },
- { 0x06, 0x8290 },
- { 0x06, 0xd682 },
- { 0x06, 0x9802 },
- { 0x06, 0x014f },
- { 0x06, 0xae09 },
- { 0x06, 0xbf82 },
- { 0x06, 0x98d6 },
- { 0x06, 0x82a0 },
- { 0x06, 0x0201 },
- { 0x06, 0x4fef },
- { 0x06, 0x95fe },
- { 0x06, 0xfdfc },
- { 0x06, 0x05f8 },
- { 0x06, 0xf9fa },
- { 0x06, 0xeef8 },
- { 0x06, 0xea00 },
- { 0x06, 0xeef8 },
- { 0x06, 0xeb00 },
- { 0x06, 0xe2f8 },
- { 0x06, 0x7ce3 },
- { 0x06, 0xf87d },
- { 0x06, 0xa511 },
- { 0x06, 0x1112 },
- { 0x06, 0xd240 },
- { 0x06, 0xd644 },
- { 0x06, 0x4402 },
- { 0x06, 0x8217 },
- { 0x06, 0xd2a0 },
- { 0x06, 0xd6aa },
- { 0x06, 0xaa02 },
- { 0x06, 0x8217 },
- { 0x06, 0xae0f },
- { 0x06, 0xa544 },
- { 0x06, 0x4402 },
- { 0x06, 0xae4d },
- { 0x06, 0xa5aa },
- { 0x06, 0xaa02 },
- { 0x06, 0xae47 },
- { 0x06, 0xaf82 },
- { 0x06, 0x13ee },
- { 0x06, 0x834e },
- { 0x06, 0x00ee },
- { 0x06, 0x834d },
- { 0x06, 0x0fee },
- { 0x06, 0x834c },
- { 0x06, 0x0fee },
- { 0x06, 0x834f },
- { 0x06, 0x00ee },
- { 0x06, 0x8351 },
- { 0x06, 0x00ee },
- { 0x06, 0x834a },
- { 0x06, 0xffee },
- { 0x06, 0x834b },
- { 0x06, 0xffe0 },
- { 0x06, 0x8330 },
- { 0x06, 0xe183 },
- { 0x06, 0x3158 },
- { 0x06, 0xfee4 },
- { 0x06, 0xf88a },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8be0 },
- { 0x06, 0x8332 },
- { 0x06, 0xe183 },
- { 0x06, 0x3359 },
- { 0x06, 0x0fe2 },
- { 0x06, 0x834d },
- { 0x06, 0x0c24 },
- { 0x06, 0x5af0 },
- { 0x06, 0x1e12 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ce5 },
- { 0x06, 0xf88d },
- { 0x06, 0xaf82 },
- { 0x06, 0x13e0 },
- { 0x06, 0x834f },
- { 0x06, 0x10e4 },
- { 0x06, 0x834f },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x009f },
- { 0x06, 0x0ae0 },
- { 0x06, 0x834f },
- { 0x06, 0xa010 },
- { 0x06, 0xa5ee },
- { 0x06, 0x834e },
- { 0x06, 0x01e0 },
- { 0x06, 0x834e },
- { 0x06, 0x7805 },
- { 0x06, 0x9e9a },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x049e },
- { 0x06, 0x10e0 },
- { 0x06, 0x834e },
- { 0x06, 0x7803 },
- { 0x06, 0x9e0f },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x019e },
- { 0x06, 0x05ae },
- { 0x06, 0x0caf },
- { 0x06, 0x81f8 },
- { 0x06, 0xaf81 },
- { 0x06, 0xa3af },
- { 0x06, 0x81dc },
- { 0x06, 0xaf82 },
- { 0x06, 0x13ee },
- { 0x06, 0x8348 },
- { 0x06, 0x00ee },
- { 0x06, 0x8349 },
- { 0x06, 0x00e0 },
- { 0x06, 0x8351 },
- { 0x06, 0x10e4 },
- { 0x06, 0x8351 },
- { 0x06, 0x5801 },
- { 0x06, 0x9fea },
- { 0x06, 0xd000 },
- { 0x06, 0xd180 },
- { 0x06, 0x1f66 },
- { 0x06, 0xe2f8 },
- { 0x06, 0xeae3 },
- { 0x06, 0xf8eb },
- { 0x06, 0x5af8 },
- { 0x06, 0x1e20 },
- { 0x06, 0xe6f8 },
- { 0x06, 0xeae5 },
- { 0x06, 0xf8eb },
- { 0x06, 0xd302 },
- { 0x06, 0xb3fe },
- { 0x06, 0xe2f8 },
- { 0x06, 0x7cef },
- { 0x06, 0x325b },
- { 0x06, 0x80e3 },
- { 0x06, 0xf87d },
- { 0x06, 0x9e03 },
- { 0x06, 0x7dff },
- { 0x06, 0xff0d },
- { 0x06, 0x581c },
- { 0x06, 0x551a },
- { 0x06, 0x6511 },
- { 0x06, 0xa190 },
- { 0x06, 0xd3e2 },
- { 0x06, 0x8348 },
- { 0x06, 0xe383 },
- { 0x06, 0x491b },
- { 0x06, 0x56ab },
- { 0x06, 0x08ef },
- { 0x06, 0x56e6 },
- { 0x06, 0x8348 },
- { 0x06, 0xe783 },
- { 0x06, 0x4910 },
- { 0x06, 0xd180 },
- { 0x06, 0x1f66 },
- { 0x06, 0xa004 },
- { 0x06, 0xb9e2 },
- { 0x06, 0x8348 },
- { 0x06, 0xe383 },
- { 0x06, 0x49ef },
- { 0x06, 0x65e2 },
- { 0x06, 0x834a },
- { 0x06, 0xe383 },
- { 0x06, 0x4b1b },
- { 0x06, 0x56aa },
- { 0x06, 0x0eef },
- { 0x06, 0x56e6 },
- { 0x06, 0x834a },
- { 0x06, 0xe783 },
- { 0x06, 0x4be2 },
- { 0x06, 0x834d },
- { 0x06, 0xe683 },
- { 0x06, 0x4ce0 },
- { 0x06, 0x834d },
- { 0x06, 0xa000 },
- { 0x06, 0x0caf },
- { 0x06, 0x81dc },
- { 0x06, 0xe083 },
- { 0x06, 0x4d10 },
- { 0x06, 0xe483 },
- { 0x06, 0x4dae },
- { 0x06, 0x0480 },
- { 0x06, 0xe483 },
- { 0x06, 0x4de0 },
- { 0x06, 0x834e },
- { 0x06, 0x7803 },
- { 0x06, 0x9e0b },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x049e },
- { 0x06, 0x04ee },
- { 0x06, 0x834e },
- { 0x06, 0x02e0 },
- { 0x06, 0x8332 },
- { 0x06, 0xe183 },
- { 0x06, 0x3359 },
- { 0x06, 0x0fe2 },
- { 0x06, 0x834d },
- { 0x06, 0x0c24 },
- { 0x06, 0x5af0 },
- { 0x06, 0x1e12 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ce5 },
- { 0x06, 0xf88d },
- { 0x06, 0xe083 },
- { 0x06, 0x30e1 },
- { 0x06, 0x8331 },
- { 0x06, 0x6801 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ae5 },
- { 0x06, 0xf88b },
- { 0x06, 0xae37 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e03 },
- { 0x06, 0xe083 },
- { 0x06, 0x4ce1 },
- { 0x06, 0x834d },
- { 0x06, 0x1b01 },
- { 0x06, 0x9e04 },
- { 0x06, 0xaaa1 },
- { 0x06, 0xaea8 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e04 },
- { 0x06, 0xee83 },
- { 0x06, 0x4f00 },
- { 0x06, 0xaeab },
- { 0x06, 0xe083 },
- { 0x06, 0x4f78 },
- { 0x06, 0x039f },
- { 0x06, 0x14ee },
- { 0x06, 0x834e },
- { 0x06, 0x05d2 },
- { 0x06, 0x40d6 },
- { 0x06, 0x5554 },
- { 0x06, 0x0282 },
- { 0x06, 0x17d2 },
- { 0x06, 0xa0d6 },
- { 0x06, 0xba00 },
- { 0x06, 0x0282 },
- { 0x06, 0x17fe },
- { 0x06, 0xfdfc },
- { 0x06, 0x05f8 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x60e1 },
- { 0x06, 0xf861 },
- { 0x06, 0x6802 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x60e5 },
- { 0x06, 0xf861 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x48e1 },
- { 0x06, 0xf849 },
- { 0x06, 0x580f },
- { 0x06, 0x1e02 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0xd000 },
- { 0x06, 0x0282 },
- { 0x06, 0x5bbf },
- { 0x06, 0x8350 },
- { 0x06, 0xef46 },
- { 0x06, 0xdc19 },
- { 0x06, 0xddd0 },
- { 0x06, 0x0102 },
- { 0x06, 0x825b },
- { 0x06, 0x0282 },
- { 0x06, 0x77e0 },
- { 0x06, 0xf860 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x6158 },
- { 0x06, 0xfde4 },
- { 0x06, 0xf860 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x61fc },
- { 0x06, 0x04f9 },
- { 0x06, 0xfafb },
- { 0x06, 0xc6bf },
- { 0x06, 0xf840 },
- { 0x06, 0xbe83 },
- { 0x06, 0x50a0 },
- { 0x06, 0x0101 },
- { 0x06, 0x071b },
- { 0x06, 0x89cf },
- { 0x06, 0xd208 },
- { 0x06, 0xebdb },
- { 0x06, 0x19b2 },
- { 0x06, 0xfbff },
- { 0x06, 0xfefd },
- { 0x06, 0x04f8 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x48e1 },
- { 0x06, 0xf849 },
- { 0x06, 0x6808 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0x58f7 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0xfc04 },
- { 0x06, 0x4d20 },
- { 0x06, 0x0002 },
- { 0x06, 0x4e22 },
- { 0x06, 0x0002 },
- { 0x06, 0x4ddf },
- { 0x06, 0xff01 },
- { 0x06, 0x4edd },
- { 0x06, 0xff01 },
- { 0x05, 0x83d4 },
- { 0x06, 0x8000 },
- { 0x05, 0x83d8 },
- { 0x06, 0x8051 },
- { 0x02, 0x6010 },
- { 0x03, 0xdc00 },
- { 0x05, 0xfff6 },
- { 0x06, 0x00fc },
- { 0x1f, 0x0000 },
+ { 0x06, 0x5561 },
+
+ /*
+ * Can not link to 1Gbps with bad cable
+ * Decrease SNR threshold form 21.07dB to 19.04dB
+ */
+ { 0x1f, 0x0001 },
+ { 0x17, 0x0cc0 },
{ 0x1f, 0x0000 },
- { 0x0d, 0xf880 },
- { 0x1f, 0x0000 }
+ { 0x0d, 0xf880 }
};
+ void __iomem *ioaddr = tp->mmio_addr;
+ const struct firmware *fw;
- rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
-
- mdio_write(ioaddr, 0x1f, 0x0002);
- mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
- mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
+ rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
- rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+ /*
+ * Rx Error Issue
+ * Fine Tune Switching regulator parameter
+ */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef);
+ rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00);
if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = {
@@ -2118,9 +2064,9 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
};
int val;
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- val = mdio_read(ioaddr, 0x0d);
+ val = rtl_readphy(tp, 0x0d);
if ((val & 0x00ff) != 0x006c) {
static const u32 set[] = {
@@ -2129,11 +2075,11 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
};
int i;
- mdio_write(ioaddr, 0x1f, 0x0002);
+ rtl_writephy(tp, 0x1f, 0x0002);
val &= 0xff00;
for (i = 0; i < ARRAY_SIZE(set); i++)
- mdio_write(ioaddr, 0x0d, val | set[i]);
+ rtl_writephy(tp, 0x0d, val | set[i]);
}
} else {
static const struct phy_reg phy_reg_init[] = {
@@ -2144,23 +2090,36 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
{ 0x06, 0x6662 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
- mdio_write(ioaddr, 0x1f, 0x0002);
- mdio_patch(ioaddr, 0x0d, 0x0300);
- mdio_patch(ioaddr, 0x0f, 0x0010);
-
- mdio_write(ioaddr, 0x1f, 0x0002);
- mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
- mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
+ /* RSET couple improve */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_patchphy(tp, 0x0d, 0x0300);
+ rtl_patchphy(tp, 0x0f, 0x0010);
+
+ /* Fine tune PLL performance */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_w1w0_phy(tp, 0x02, 0x0100, 0x0600);
+ rtl_w1w0_phy(tp, 0x03, 0x0000, 0xe000);
+
+ rtl_writephy(tp, 0x1f, 0x0005);
+ rtl_writephy(tp, 0x05, 0x001b);
+ if (rtl_readphy(tp, 0x06) == 0xbf00 &&
+ request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) {
+ rtl_phy_write_fw(tp, fw);
+ release_firmware(fw);
+ } else {
+ netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
+ }
- rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init_0[] = {
+ /* Channel Estimation */
{ 0x1f, 0x0001 },
{ 0x06, 0x4064 },
{ 0x07, 0x2863 },
@@ -2179,326 +2138,30 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
{ 0x1a, 0x05ad },
{ 0x14, 0x94c0 },
+ /*
+ * Tx Error Issue
+ * enhance line driver power
+ */
{ 0x1f, 0x0002 },
{ 0x06, 0x5561 },
{ 0x1f, 0x0005 },
{ 0x05, 0x8332 },
- { 0x06, 0x5561 }
- };
- static const struct phy_reg phy_reg_init_1[] = {
- { 0x1f, 0x0005 },
- { 0x05, 0xffc2 },
- { 0x1f, 0x0005 },
- { 0x05, 0x8000 },
- { 0x06, 0xf8f9 },
- { 0x06, 0xfaee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x00e2 },
- { 0x06, 0xf87c },
- { 0x06, 0xe3f8 },
- { 0x06, 0x7da5 },
- { 0x06, 0x1111 },
- { 0x06, 0x12d2 },
- { 0x06, 0x40d6 },
- { 0x06, 0x4444 },
- { 0x06, 0x0281 },
- { 0x06, 0xc6d2 },
- { 0x06, 0xa0d6 },
- { 0x06, 0xaaaa },
- { 0x06, 0x0281 },
- { 0x06, 0xc6ae },
- { 0x06, 0x0fa5 },
- { 0x06, 0x4444 },
- { 0x06, 0x02ae },
- { 0x06, 0x4da5 },
- { 0x06, 0xaaaa },
- { 0x06, 0x02ae },
- { 0x06, 0x47af },
- { 0x06, 0x81c2 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e00 },
- { 0x06, 0xee83 },
- { 0x06, 0x4d0f },
- { 0x06, 0xee83 },
- { 0x06, 0x4c0f },
- { 0x06, 0xee83 },
- { 0x06, 0x4f00 },
- { 0x06, 0xee83 },
- { 0x06, 0x5100 },
- { 0x06, 0xee83 },
- { 0x06, 0x4aff },
- { 0x06, 0xee83 },
- { 0x06, 0x4bff },
- { 0x06, 0xe083 },
- { 0x06, 0x30e1 },
- { 0x06, 0x8331 },
- { 0x06, 0x58fe },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ae5 },
- { 0x06, 0xf88b },
- { 0x06, 0xe083 },
- { 0x06, 0x32e1 },
- { 0x06, 0x8333 },
- { 0x06, 0x590f },
- { 0x06, 0xe283 },
- { 0x06, 0x4d0c },
- { 0x06, 0x245a },
- { 0x06, 0xf01e },
- { 0x06, 0x12e4 },
- { 0x06, 0xf88c },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8daf },
- { 0x06, 0x81c2 },
- { 0x06, 0xe083 },
- { 0x06, 0x4f10 },
- { 0x06, 0xe483 },
- { 0x06, 0x4fe0 },
- { 0x06, 0x834e },
- { 0x06, 0x7800 },
- { 0x06, 0x9f0a },
- { 0x06, 0xe083 },
- { 0x06, 0x4fa0 },
- { 0x06, 0x10a5 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e01 },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x059e },
- { 0x06, 0x9ae0 },
- { 0x06, 0x834e },
- { 0x06, 0x7804 },
- { 0x06, 0x9e10 },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x039e },
- { 0x06, 0x0fe0 },
- { 0x06, 0x834e },
- { 0x06, 0x7801 },
- { 0x06, 0x9e05 },
- { 0x06, 0xae0c },
- { 0x06, 0xaf81 },
- { 0x06, 0xa7af },
- { 0x06, 0x8152 },
- { 0x06, 0xaf81 },
- { 0x06, 0x8baf },
- { 0x06, 0x81c2 },
- { 0x06, 0xee83 },
- { 0x06, 0x4800 },
- { 0x06, 0xee83 },
- { 0x06, 0x4900 },
- { 0x06, 0xe083 },
- { 0x06, 0x5110 },
- { 0x06, 0xe483 },
- { 0x06, 0x5158 },
- { 0x06, 0x019f },
- { 0x06, 0xead0 },
- { 0x06, 0x00d1 },
- { 0x06, 0x801f },
- { 0x06, 0x66e2 },
- { 0x06, 0xf8ea },
- { 0x06, 0xe3f8 },
- { 0x06, 0xeb5a },
- { 0x06, 0xf81e },
- { 0x06, 0x20e6 },
- { 0x06, 0xf8ea },
- { 0x06, 0xe5f8 },
- { 0x06, 0xebd3 },
- { 0x06, 0x02b3 },
- { 0x06, 0xfee2 },
- { 0x06, 0xf87c },
- { 0x06, 0xef32 },
- { 0x06, 0x5b80 },
- { 0x06, 0xe3f8 },
- { 0x06, 0x7d9e },
- { 0x06, 0x037d },
- { 0x06, 0xffff },
- { 0x06, 0x0d58 },
- { 0x06, 0x1c55 },
- { 0x06, 0x1a65 },
- { 0x06, 0x11a1 },
- { 0x06, 0x90d3 },
- { 0x06, 0xe283 },
- { 0x06, 0x48e3 },
- { 0x06, 0x8349 },
- { 0x06, 0x1b56 },
- { 0x06, 0xab08 },
- { 0x06, 0xef56 },
- { 0x06, 0xe683 },
- { 0x06, 0x48e7 },
- { 0x06, 0x8349 },
- { 0x06, 0x10d1 },
- { 0x06, 0x801f },
- { 0x06, 0x66a0 },
- { 0x06, 0x04b9 },
- { 0x06, 0xe283 },
- { 0x06, 0x48e3 },
- { 0x06, 0x8349 },
- { 0x06, 0xef65 },
- { 0x06, 0xe283 },
- { 0x06, 0x4ae3 },
- { 0x06, 0x834b },
- { 0x06, 0x1b56 },
- { 0x06, 0xaa0e },
- { 0x06, 0xef56 },
- { 0x06, 0xe683 },
- { 0x06, 0x4ae7 },
- { 0x06, 0x834b },
- { 0x06, 0xe283 },
- { 0x06, 0x4de6 },
- { 0x06, 0x834c },
- { 0x06, 0xe083 },
- { 0x06, 0x4da0 },
- { 0x06, 0x000c },
- { 0x06, 0xaf81 },
- { 0x06, 0x8be0 },
- { 0x06, 0x834d },
- { 0x06, 0x10e4 },
- { 0x06, 0x834d },
- { 0x06, 0xae04 },
- { 0x06, 0x80e4 },
- { 0x06, 0x834d },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x039e },
- { 0x06, 0x0be0 },
- { 0x06, 0x834e },
- { 0x06, 0x7804 },
- { 0x06, 0x9e04 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e02 },
- { 0x06, 0xe083 },
- { 0x06, 0x32e1 },
- { 0x06, 0x8333 },
- { 0x06, 0x590f },
- { 0x06, 0xe283 },
- { 0x06, 0x4d0c },
- { 0x06, 0x245a },
- { 0x06, 0xf01e },
- { 0x06, 0x12e4 },
- { 0x06, 0xf88c },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8de0 },
- { 0x06, 0x8330 },
- { 0x06, 0xe183 },
- { 0x06, 0x3168 },
- { 0x06, 0x01e4 },
- { 0x06, 0xf88a },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8bae },
- { 0x06, 0x37ee },
- { 0x06, 0x834e },
- { 0x06, 0x03e0 },
- { 0x06, 0x834c },
- { 0x06, 0xe183 },
- { 0x06, 0x4d1b },
- { 0x06, 0x019e },
- { 0x06, 0x04aa },
- { 0x06, 0xa1ae },
- { 0x06, 0xa8ee },
- { 0x06, 0x834e },
- { 0x06, 0x04ee },
- { 0x06, 0x834f },
- { 0x06, 0x00ae },
- { 0x06, 0xabe0 },
- { 0x06, 0x834f },
- { 0x06, 0x7803 },
- { 0x06, 0x9f14 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e05 },
- { 0x06, 0xd240 },
- { 0x06, 0xd655 },
- { 0x06, 0x5402 },
- { 0x06, 0x81c6 },
- { 0x06, 0xd2a0 },
- { 0x06, 0xd6ba },
- { 0x06, 0x0002 },
- { 0x06, 0x81c6 },
- { 0x06, 0xfefd },
- { 0x06, 0xfc05 },
- { 0x06, 0xf8e0 },
- { 0x06, 0xf860 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x6168 },
- { 0x06, 0x02e4 },
- { 0x06, 0xf860 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x61e0 },
- { 0x06, 0xf848 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x4958 },
- { 0x06, 0x0f1e },
- { 0x06, 0x02e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x49d0 },
- { 0x06, 0x0002 },
- { 0x06, 0x820a },
- { 0x06, 0xbf83 },
- { 0x06, 0x50ef },
- { 0x06, 0x46dc },
- { 0x06, 0x19dd },
- { 0x06, 0xd001 },
- { 0x06, 0x0282 },
- { 0x06, 0x0a02 },
- { 0x06, 0x8226 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x60e1 },
- { 0x06, 0xf861 },
- { 0x06, 0x58fd },
- { 0x06, 0xe4f8 },
- { 0x06, 0x60e5 },
- { 0x06, 0xf861 },
- { 0x06, 0xfc04 },
- { 0x06, 0xf9fa },
- { 0x06, 0xfbc6 },
- { 0x06, 0xbff8 },
- { 0x06, 0x40be },
- { 0x06, 0x8350 },
- { 0x06, 0xa001 },
- { 0x06, 0x0107 },
- { 0x06, 0x1b89 },
- { 0x06, 0xcfd2 },
- { 0x06, 0x08eb },
- { 0x06, 0xdb19 },
- { 0x06, 0xb2fb },
- { 0x06, 0xfffe },
- { 0x06, 0xfd04 },
- { 0x06, 0xf8e0 },
- { 0x06, 0xf848 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x4968 },
- { 0x06, 0x08e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x4958 },
- { 0x06, 0xf7e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x49fc },
- { 0x06, 0x044d },
- { 0x06, 0x2000 },
- { 0x06, 0x024e },
- { 0x06, 0x2200 },
- { 0x06, 0x024d },
- { 0x06, 0xdfff },
- { 0x06, 0x014e },
- { 0x06, 0xddff },
- { 0x06, 0x0100 },
- { 0x05, 0x83d8 },
- { 0x06, 0x8000 },
- { 0x03, 0xdc00 },
- { 0x05, 0xfff6 },
- { 0x06, 0x00fc },
- { 0x1f, 0x0000 },
+ { 0x06, 0x5561 },
+
+ /*
+ * Can not link to 1Gbps with bad cable
+ * Decrease SNR threshold form 21.07dB to 19.04dB
+ */
+ { 0x1f, 0x0001 },
+ { 0x17, 0x0cc0 },
{ 0x1f, 0x0000 },
- { 0x0d, 0xf880 },
- { 0x1f, 0x0000 }
+ { 0x0d, 0xf880 }
};
+ void __iomem *ioaddr = tp->mmio_addr;
+ const struct firmware *fw;
- rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
+ rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = {
@@ -2512,21 +2175,21 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
};
int val;
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- val = mdio_read(ioaddr, 0x0d);
+ val = rtl_readphy(tp, 0x0d);
if ((val & 0x00ff) != 0x006c) {
- u32 set[] = {
+ static const u32 set[] = {
0x0065, 0x0066, 0x0067, 0x0068,
0x0069, 0x006a, 0x006b, 0x006c
};
int i;
- mdio_write(ioaddr, 0x1f, 0x0002);
+ rtl_writephy(tp, 0x1f, 0x0002);
val &= 0xff00;
for (i = 0; i < ARRAY_SIZE(set); i++)
- mdio_write(ioaddr, 0x0d, val | set[i]);
+ rtl_writephy(tp, 0x0d, val | set[i]);
}
} else {
static const struct phy_reg phy_reg_init[] = {
@@ -2537,23 +2200,32 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
{ 0x06, 0x2642 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
- mdio_write(ioaddr, 0x1f, 0x0002);
- mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
- mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
-
- mdio_write(ioaddr, 0x1f, 0x0001);
- mdio_write(ioaddr, 0x17, 0x0cc0);
-
- mdio_write(ioaddr, 0x1f, 0x0002);
- mdio_patch(ioaddr, 0x0f, 0x0017);
+ /* Fine tune PLL performance */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_w1w0_phy(tp, 0x02, 0x0100, 0x0600);
+ rtl_w1w0_phy(tp, 0x03, 0x0000, 0xe000);
+
+ /* Switching regulator Slew rate */
+ rtl_writephy(tp, 0x1f, 0x0002);
+ rtl_patchphy(tp, 0x0f, 0x0017);
+
+ rtl_writephy(tp, 0x1f, 0x0005);
+ rtl_writephy(tp, 0x05, 0x001b);
+ if (rtl_readphy(tp, 0x06) == 0xb300 &&
+ request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) {
+ rtl_phy_write_fw(tp, fw);
+ release_firmware(fw);
+ } else {
+ netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
+ }
- rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+ rtl_writephy(tp, 0x1f, 0x0000);
}
-static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 },
@@ -2611,10 +2283,26 @@ static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)
+{
+ static const struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0001 },
+ { 0x17, 0x0cc0 },
+
+ { 0x1f, 0x0007 },
+ { 0x1e, 0x002d },
+ { 0x18, 0x0040 },
+ { 0x1f, 0x0000 }
+ };
+
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_patchphy(tp, 0x0d, 1 << 5);
+}
+
+static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0003 },
@@ -2623,18 +2311,17 @@ static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
{ 0x1f, 0x0000 }
};
- mdio_write(ioaddr, 0x1f, 0x0000);
- mdio_patch(ioaddr, 0x11, 1 << 12);
- mdio_patch(ioaddr, 0x19, 1 << 13);
- mdio_patch(ioaddr, 0x10, 1 << 15);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_patchphy(tp, 0x11, 1 << 12);
+ rtl_patchphy(tp, 0x19, 1 << 13);
+ rtl_patchphy(tp, 0x10, 1 << 15);
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
static void rtl_hw_phy_config(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
rtl8169_print_mac_version(tp);
@@ -2643,58 +2330,61 @@ static void rtl_hw_phy_config(struct net_device *dev)
break;
case RTL_GIGA_MAC_VER_02:
case RTL_GIGA_MAC_VER_03:
- rtl8169s_hw_phy_config(ioaddr);
+ rtl8169s_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_04:
- rtl8169sb_hw_phy_config(ioaddr);
+ rtl8169sb_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_05:
- rtl8169scd_hw_phy_config(tp, ioaddr);
+ rtl8169scd_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_06:
- rtl8169sce_hw_phy_config(ioaddr);
+ rtl8169sce_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_07:
case RTL_GIGA_MAC_VER_08:
case RTL_GIGA_MAC_VER_09:
- rtl8102e_hw_phy_config(ioaddr);
+ rtl8102e_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_11:
- rtl8168bb_hw_phy_config(ioaddr);
+ rtl8168bb_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_12:
- rtl8168bef_hw_phy_config(ioaddr);
+ rtl8168bef_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_17:
- rtl8168bef_hw_phy_config(ioaddr);
+ rtl8168bef_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_18:
- rtl8168cp_1_hw_phy_config(ioaddr);
+ rtl8168cp_1_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_19:
- rtl8168c_1_hw_phy_config(ioaddr);
+ rtl8168c_1_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_20:
- rtl8168c_2_hw_phy_config(ioaddr);
+ rtl8168c_2_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_21:
- rtl8168c_3_hw_phy_config(ioaddr);
+ rtl8168c_3_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_22:
- rtl8168c_4_hw_phy_config(ioaddr);
+ rtl8168c_4_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_23:
case RTL_GIGA_MAC_VER_24:
- rtl8168cp_2_hw_phy_config(ioaddr);
+ rtl8168cp_2_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_25:
- rtl8168d_1_hw_phy_config(ioaddr);
+ rtl8168d_1_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_26:
- rtl8168d_2_hw_phy_config(ioaddr);
+ rtl8168d_2_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_27:
- rtl8168d_3_hw_phy_config(ioaddr);
+ rtl8168d_3_hw_phy_config(tp);
+ break;
+ case RTL_GIGA_MAC_VER_28:
+ rtl8168d_4_hw_phy_config(tp);
break;
default:
@@ -2717,7 +2407,7 @@ static void rtl8169_phy_timer(unsigned long __opaque)
spin_lock_irq(&tp->lock);
- if (tp->phy_reset_pending(ioaddr)) {
+ if (tp->phy_reset_pending(tp)) {
/*
* A busy loop could burn quite a few cycles on nowadays CPU.
* Let's delay the execution of the timer for a few ticks.
@@ -2731,7 +2421,7 @@ static void rtl8169_phy_timer(unsigned long __opaque)
netif_warn(tp, link, dev, "PHY reset until link up\n");
- tp->phy_reset_enable(ioaddr);
+ tp->phy_reset_enable(tp);
out_mod_timer:
mod_timer(timer, jiffies + timeout);
@@ -2791,12 +2481,11 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
static void rtl8169_phy_reset(struct net_device *dev,
struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
- tp->phy_reset_enable(ioaddr);
+ tp->phy_reset_enable(tp);
for (i = 0; i < 100; i++) {
- if (!tp->phy_reset_pending(ioaddr))
+ if (!tp->phy_reset_pending(tp))
return;
msleep(1);
}
@@ -2823,7 +2512,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
RTL_W8(0x82, 0x01);
dprintk("Set PHY Reg 0x0bh = 0x00h\n");
- mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
+ rtl_writephy(tp, 0x0b, 0x0000); //w 0x0b 15 0 0
}
rtl8169_phy_reset(dev, tp);
@@ -2893,11 +2582,11 @@ static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *dat
return 0;
case SIOCGMIIREG:
- data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f);
+ data->val_out = rtl_readphy(tp, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG:
- mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in);
+ rtl_writephy(tp, data->reg_num & 0x1f, data->val_in);
return 0;
}
return -EOPNOTSUPP;
@@ -2997,6 +2686,173 @@ static const struct net_device_ops rtl8169_netdev_ops = {
};
+static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
+{
+ struct mdio_ops *ops = &tp->mdio_ops;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ ops->write = r8168dp_1_mdio_write;
+ ops->read = r8168dp_1_mdio_read;
+ break;
+ case RTL_GIGA_MAC_VER_28:
+ ops->write = r8168dp_2_mdio_write;
+ ops->read = r8168dp_2_mdio_read;
+ break;
+ default:
+ ops->write = r8169_mdio_write;
+ ops->read = r8169_mdio_read;
+ break;
+ }
+}
+
+static void r810x_phy_power_down(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+}
+
+static void r810x_phy_power_up(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
+}
+
+static void r810x_pll_power_down(struct rtl8169_private *tp)
+{
+ if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+ return;
+ }
+
+ r810x_phy_power_down(tp);
+}
+
+static void r810x_pll_power_up(struct rtl8169_private *tp)
+{
+ r810x_phy_power_up(tp);
+}
+
+static void r8168_phy_power_up(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0e, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
+}
+
+static void r8168_phy_power_down(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0e, 0x0200);
+ rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+}
+
+static void r8168_pll_power_down(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ return;
+
+ if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_24)) &&
+ (RTL_R16(CPlusCmd) & ASF)) {
+ return;
+ }
+
+ if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+
+ RTL_W32(RxConfig, RTL_R32(RxConfig) |
+ AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
+ return;
+ }
+
+ r8168_phy_power_down(tp);
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
+ break;
+ }
+}
+
+static void r8168_pll_power_up(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ return;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
+ break;
+ }
+
+ r8168_phy_power_up(tp);
+}
+
+static void rtl_pll_power_op(struct rtl8169_private *tp,
+ void (*op)(struct rtl8169_private *))
+{
+ if (op)
+ op(tp);
+}
+
+static void rtl_pll_power_down(struct rtl8169_private *tp)
+{
+ rtl_pll_power_op(tp, tp->pll_power_ops.down);
+}
+
+static void rtl_pll_power_up(struct rtl8169_private *tp)
+{
+ rtl_pll_power_op(tp, tp->pll_power_ops.up);
+}
+
+static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
+{
+ struct pll_power_ops *ops = &tp->pll_power_ops;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_07:
+ case RTL_GIGA_MAC_VER_08:
+ case RTL_GIGA_MAC_VER_09:
+ case RTL_GIGA_MAC_VER_10:
+ case RTL_GIGA_MAC_VER_16:
+ ops->down = r810x_pll_power_down;
+ ops->up = r810x_pll_power_up;
+ break;
+
+ case RTL_GIGA_MAC_VER_11:
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ case RTL_GIGA_MAC_VER_18:
+ case RTL_GIGA_MAC_VER_19:
+ case RTL_GIGA_MAC_VER_20:
+ case RTL_GIGA_MAC_VER_21:
+ case RTL_GIGA_MAC_VER_22:
+ case RTL_GIGA_MAC_VER_23:
+ case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ ops->down = r8168_pll_power_down;
+ ops->up = r8168_pll_power_up;
+ break;
+
+ default:
+ ops->down = NULL;
+ ops->up = NULL;
+ break;
+ }
+}
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -3115,6 +2971,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
+ rtl_init_mdio_ops(tp);
+ rtl_init_pll_power_ops(tp);
+
/* Use appropriate default if unknown */
if (tp->mac_version == RTL_GIGA_MAC_NONE) {
netif_notice(tp, probe, dev,
@@ -3205,6 +3064,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->base_addr, dev->dev_addr,
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+ rtl8168_driver_start(tp);
+ }
+
rtl8169_init_phy(dev, tp);
/*
@@ -3240,7 +3104,12 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- flush_scheduled_work();
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+ rtl8168_driver_stop(tp);
+ }
+
+ cancel_delayed_work_sync(&tp->task);
unregister_netdev(dev);
@@ -3293,6 +3162,8 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+ rtl_pll_power_up(tp);
+
rtl_hw_start(dev);
rtl8169_request_timer(dev);
@@ -3319,11 +3190,19 @@ err_pm_runtime_put:
goto out;
}
-static void rtl8169_hw_reset(void __iomem *ioaddr)
+static void rtl8169_hw_reset(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
/* Disable interrupts */
rtl8169_irq_mask_and_ack(ioaddr);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_28) {
+ while (RTL_R8(TxPoll) & NPQ)
+ udelay(20);
+
+ }
+
/* Reset the chipset */
RTL_W8(ChipCmd, CmdReset);
@@ -3437,7 +3316,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
(tp->mac_version == RTL_GIGA_MAC_VER_04))
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(EarlyTxThres, NoEarlyTx);
rtl_set_rx_max_size(ioaddr, rx_buf_sz);
@@ -3507,12 +3386,22 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
}
}
-static void rtl_csi_access_enable(void __iomem *ioaddr)
+static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits)
{
u32 csi;
csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
- rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
+ rtl_csi_write(ioaddr, 0x070c, csi | bits);
+}
+
+static void rtl_csi_access_enable_1(void __iomem *ioaddr)
+{
+ rtl_csi_access_enable(ioaddr, 0x17000000);
+}
+
+static void rtl_csi_access_enable_2(void __iomem *ioaddr)
+{
+ rtl_csi_access_enable(ioaddr, 0x27000000);
}
struct ephy_info {
@@ -3547,6 +3436,21 @@ static void rtl_disable_clock_request(struct pci_dev *pdev)
}
}
+static void rtl_enable_clock_request(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct rtl8169_private *tp = netdev_priv(dev);
+ int cap = tp->pcie_cap;
+
+ if (cap) {
+ u16 ctl;
+
+ pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
+ ctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
+ pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
+ }
+}
+
#define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
@@ -3572,7 +3476,7 @@ static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev)
{
rtl_hw_start_8168bb(ioaddr, pdev);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0));
}
@@ -3600,7 +3504,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x07, 0, 0x2000 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
@@ -3609,7 +3513,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
@@ -3620,14 +3524,14 @@ static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
/* Magic. */
RTL_W8(DBG_REG, 0x20);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
@@ -3642,7 +3546,7 @@ static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x06, 0x0080, 0x0000 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
@@ -3658,7 +3562,7 @@ static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x03, 0x0400, 0x0220 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
@@ -3672,24 +3576,50 @@ static void rtl_hw_start_8168c_3(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168c_4(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
__rtl_hw_start_8168cp(ioaddr, pdev);
}
static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_disable_clock_request(pdev);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
}
+static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ static const struct ephy_info e_info_8168d_4[] = {
+ { 0x0b, ~0, 0x48 },
+ { 0x19, 0x20, 0x50 },
+ { 0x0c, ~0, 0x20 }
+ };
+ int i;
+
+ rtl_csi_access_enable_1(ioaddr);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+ for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) {
+ const struct ephy_info *e = e_info_8168d_4 + i;
+ u16 w;
+
+ w = rtl_ephy_read(ioaddr, e->offset);
+ rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits);
+ }
+
+ rtl_enable_clock_request(pdev);
+}
+
static void rtl_hw_start_8168(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3698,7 +3628,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W8(Cfg9346, Cfg9346_Unlock);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
rtl_set_rx_max_size(ioaddr, rx_buf_sz);
@@ -3767,6 +3697,10 @@ static void rtl_hw_start_8168(struct net_device *dev)
rtl_hw_start_8168d(ioaddr, pdev);
break;
+ case RTL_GIGA_MAC_VER_28:
+ rtl_hw_start_8168d_4(ioaddr, pdev);
+ break;
+
default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version);
@@ -3808,7 +3742,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
};
u8 cfg1;
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(DBG_REG, FIX_NAK_1);
@@ -3829,7 +3763,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
@@ -3878,7 +3812,7 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_W8(Cfg9346, Cfg9346_Unlock);
- RTL_W8(EarlyTxThres, EarlyTxThld);
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
rtl_set_rx_max_size(ioaddr, rx_buf_sz);
@@ -4179,7 +4113,7 @@ static void rtl8169_tx_timeout(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
- rtl8169_hw_reset(tp->mmio_addr);
+ rtl8169_hw_reset(tp);
/* Let's wait a bit while any (async) irq lands on */
rtl8169_schedule_work(dev, rtl8169_reset_task);
@@ -4337,7 +4271,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
- void __iomem *ioaddr = tp->mmio_addr;
u16 pci_status, pci_cmd;
pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
@@ -4368,13 +4301,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
/* The infamous DAC f*ckup only happens at boot time */
if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
+ void __iomem *ioaddr = tp->mmio_addr;
+
netif_info(tp, intr, dev, "disabling PCI DAC\n");
tp->cp_cmd &= ~PCIDAC;
RTL_W16(CPlusCmd, tp->cp_cmd);
dev->features &= ~NETIF_F_HIGHDMA;
}
- rtl8169_hw_reset(ioaddr);
+ rtl8169_hw_reset(tp);
rtl8169_schedule_work(dev, rtl8169_reinit_task);
}
@@ -4600,7 +4535,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
}
if (status & LinkChg)
- rtl8169_check_link_status(dev, tp, ioaddr);
+ __rtl8169_check_link_status(dev, tp, ioaddr, true);
/* We need to see the lastest version of tp->intr_mask to
* avoid ignoring an MSI interrupt and having to wait for
@@ -4701,6 +4636,8 @@ static void rtl8169_down(struct net_device *dev)
rtl8169_tx_clear(tp);
rtl8169_rx_clear(tp);
+
+ rtl_pll_power_down(tp);
}
static int rtl8169_close(struct net_device *dev)
@@ -4805,9 +4742,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
static void rtl8169_net_suspend(struct net_device *dev)
{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
if (!netif_running(dev))
return;
+ rtl_pll_power_down(tp);
+
netif_device_detach(dev);
netif_stop_queue(dev);
}
@@ -4826,7 +4767,12 @@ static int rtl8169_suspend(struct device *device)
static void __rtl8169_resume(struct net_device *dev)
{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
netif_device_attach(dev);
+
+ rtl_pll_power_up(tp);
+
rtl8169_schedule_work(dev, rtl8169_reset_task);
}
@@ -4890,11 +4836,7 @@ static int rtl8169_runtime_idle(struct device *device)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- if (!tp->TxDescArray)
- return 0;
-
- rtl8169_check_link_status(dev, tp, tp->mmio_addr);
- return -EBUSY;
+ return tp->TxDescArray ? -EBUSY : 0;
}
static const struct dev_pm_ops rtl8169_pm_ops = {
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index ecc25aab896a..39c17cecb8b9 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -88,14 +88,14 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.27"
+#define DRV_VERSION "2.0.26.28"
/* S2io Driver name & version. */
-static char s2io_driver_name[] = "Neterion";
-static char s2io_driver_version[] = DRV_VERSION;
+static const char s2io_driver_name[] = "Neterion";
+static const char s2io_driver_version[] = DRV_VERSION;
-static int rxd_size[2] = {32, 48};
-static int rxd_count[2] = {127, 85};
+static const int rxd_size[2] = {32, 48};
+static const int rxd_count[2] = {127, 85};
static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
{
@@ -3598,10 +3598,12 @@ static int s2io_set_swapper(struct s2io_nic *sp)
val64 = readq(&bar0->pif_rd_swapper_fb);
if (val64 != 0x0123456789ABCDEFULL) {
int i = 0;
- u64 value[] = { 0xC30000C3C30000C3ULL, /* FE=1, SE=1 */
- 0x8100008181000081ULL, /* FE=1, SE=0 */
- 0x4200004242000042ULL, /* FE=0, SE=1 */
- 0}; /* FE=0, SE=0 */
+ static const u64 value[] = {
+ 0xC30000C3C30000C3ULL, /* FE=1, SE=1 */
+ 0x8100008181000081ULL, /* FE=1, SE=0 */
+ 0x4200004242000042ULL, /* FE=0, SE=1 */
+ 0 /* FE=0, SE=0 */
+ };
while (i < 4) {
writeq(value[i], &bar0->swapper_ctrl);
@@ -3627,10 +3629,12 @@ static int s2io_set_swapper(struct s2io_nic *sp)
if (val64 != valt) {
int i = 0;
- u64 value[] = { 0x00C3C30000C3C300ULL, /* FE=1, SE=1 */
- 0x0081810000818100ULL, /* FE=1, SE=0 */
- 0x0042420000424200ULL, /* FE=0, SE=1 */
- 0}; /* FE=0, SE=0 */
+ static const u64 value[] = {
+ 0x00C3C30000C3C300ULL, /* FE=1, SE=1 */
+ 0x0081810000818100ULL, /* FE=1, SE=0 */
+ 0x0042420000424200ULL, /* FE=0, SE=1 */
+ 0 /* FE=0, SE=0 */
+ };
while (i < 4) {
writeq((value[i] | valr), &bar0->swapper_ctrl);
@@ -5568,30 +5572,27 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
struct s2io_nic *sp = netdev_priv(dev);
int i, tx_desc_count = 0, rx_desc_count = 0;
- if (sp->rxd_mode == RXD_MODE_1)
+ if (sp->rxd_mode == RXD_MODE_1) {
ering->rx_max_pending = MAX_RX_DESC_1;
- else if (sp->rxd_mode == RXD_MODE_3B)
+ ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
+ } else {
ering->rx_max_pending = MAX_RX_DESC_2;
+ ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
+ }
+ ering->rx_mini_max_pending = 0;
ering->tx_max_pending = MAX_TX_DESC;
- for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
- tx_desc_count += sp->config.tx_cfg[i].fifo_len;
- DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds);
- ering->tx_pending = tx_desc_count;
- rx_desc_count = 0;
- for (i = 0 ; i < sp->config.rx_ring_num ; i++)
+ for (i = 0; i < sp->config.rx_ring_num; i++)
rx_desc_count += sp->config.rx_cfg[i].num_rxd;
-
ering->rx_pending = rx_desc_count;
-
- ering->rx_mini_max_pending = 0;
- ering->rx_mini_pending = 0;
- if (sp->rxd_mode == RXD_MODE_1)
- ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
- else if (sp->rxd_mode == RXD_MODE_3B)
- ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
ering->rx_jumbo_pending = rx_desc_count;
+ ering->rx_mini_pending = 0;
+
+ for (i = 0; i < sp->config.tx_fifo_num; i++)
+ tx_desc_count += sp->config.tx_cfg[i].fifo_len;
+ ering->tx_pending = tx_desc_count;
+ DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds);
}
/**
@@ -7692,6 +7693,8 @@ static void s2io_init_pci(struct s2io_nic *sp)
static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
u8 *dev_multiq)
{
+ int i;
+
if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) {
DBG_PRINT(ERR_DBG, "Requested number of tx fifos "
"(%d) not supported\n", tx_fifo_num);
@@ -7750,6 +7753,15 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n");
rx_ring_mode = 1;
}
+
+ for (i = 0; i < MAX_RX_RINGS; i++)
+ if (rx_ring_sz[i] > MAX_RX_BLOCKS_PER_RING) {
+ DBG_PRINT(ERR_DBG, "Requested rx ring size not "
+ "supported\nDefaulting to %d\n",
+ MAX_RX_BLOCKS_PER_RING);
+ rx_ring_sz[i] = MAX_RX_BLOCKS_PER_RING;
+ }
+
return SUCCESS;
}
@@ -8321,8 +8333,7 @@ mem_alloc_failed:
static void __devexit s2io_rem_nic(struct pci_dev *pdev)
{
- struct net_device *dev =
- (struct net_device *)pci_get_drvdata(pdev);
+ struct net_device *dev = pci_get_drvdata(pdev);
struct s2io_nic *sp;
if (dev == NULL) {
@@ -8330,9 +8341,11 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
return;
}
- flush_scheduled_work();
-
sp = netdev_priv(dev);
+
+ cancel_work_sync(&sp->rst_timer_task);
+ cancel_work_sync(&sp->set_link_task);
+
unregister_netdev(dev);
free_shared_mem(sp);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 00b8614efe48..7d160306b651 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -355,13 +355,12 @@ struct stat_block {
#define FIFO_OTHER_MAX_NUM 1
-#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
-#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
-#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 128)
+#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 86)
#define MAX_TX_DESC (MAX_AVAILABLE_TXDS)
/* FIFO mappings for all possible number of fifos configured */
-static int fifo_map[][MAX_TX_FIFOS] = {
+static const int fifo_map[][MAX_TX_FIFOS] = {
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 0, 1, 1, 1, 2, 2},
@@ -372,7 +371,7 @@ static int fifo_map[][MAX_TX_FIFOS] = {
{0, 1, 2, 3, 4, 5, 6, 7},
};
-static u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7};
+static const u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7};
/* Maintains Per FIFO related information. */
struct tx_fifo_config {
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 417adf372828..76290a8c3c14 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1449,7 +1449,8 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
dev->irq = pdev->irq;
/* faked with skb_copy_and_csum_dev */
- dev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
+ dev->features = NETIF_F_SG | NETIF_F_HIGHDMA |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
dev->netdev_ops = &sc92031_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 05df20e47976..711449c6e675 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -23,7 +23,6 @@
#include <linux/gfp.h>
#include "net_driver.h"
#include "efx.h"
-#include "mdio_10g.h"
#include "nic.h"
#include "mcdi.h"
@@ -197,7 +196,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
static void efx_remove_channels(struct efx_nic *efx);
static void efx_remove_port(struct efx_nic *efx);
+static void efx_init_napi(struct efx_nic *efx);
static void efx_fini_napi(struct efx_nic *efx);
+static void efx_fini_napi_channel(struct efx_channel *channel);
static void efx_fini_struct(struct efx_nic *efx);
static void efx_start_all(struct efx_nic *efx);
static void efx_stop_all(struct efx_nic *efx);
@@ -335,8 +336,10 @@ void efx_process_channel_now(struct efx_channel *channel)
/* Disable interrupts and wait for ISRs to complete */
efx_nic_disable_interrupts(efx);
- if (efx->legacy_irq)
+ if (efx->legacy_irq) {
synchronize_irq(efx->legacy_irq);
+ efx->legacy_irq_enabled = false;
+ }
if (channel->irq)
synchronize_irq(channel->irq);
@@ -351,6 +354,8 @@ void efx_process_channel_now(struct efx_channel *channel)
efx_channel_processed(channel);
napi_enable(&channel->napi_str);
+ if (efx->legacy_irq)
+ efx->legacy_irq_enabled = true;
efx_nic_enable_interrupts(efx);
}
@@ -426,6 +431,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
*channel = *old_channel;
+ channel->napi_dev = NULL;
memset(&channel->eventq, 0, sizeof(channel->eventq));
rx_queue = &channel->rx_queue;
@@ -455,9 +461,6 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
}
}
- spin_lock_init(&channel->tx_stop_lock);
- atomic_set(&channel->tx_stop_count, 1);
-
rx_queue = &channel->rx_queue;
rx_queue->efx = efx;
setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
@@ -736,9 +739,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
if (rc)
goto rollback;
+ efx_init_napi(efx);
+
/* Destroy old channels */
- for (i = 0; i < efx->n_channels; i++)
+ for (i = 0; i < efx->n_channels; i++) {
+ efx_fini_napi_channel(other_channel[i]);
efx_remove_channel(other_channel[i]);
+ }
out:
/* Free unused channel structures */
for (i = 0; i < efx->n_channels; i++)
@@ -910,6 +917,7 @@ static void efx_mac_work(struct work_struct *data)
static int efx_probe_port(struct efx_nic *efx)
{
+ unsigned char *perm_addr;
int rc;
netif_dbg(efx, probe, efx->net_dev, "create port\n");
@@ -923,11 +931,12 @@ static int efx_probe_port(struct efx_nic *efx)
return rc;
/* Sanity check MAC address */
- if (is_valid_ether_addr(efx->mac_address)) {
- memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN);
+ perm_addr = efx->net_dev->perm_addr;
+ if (is_valid_ether_addr(perm_addr)) {
+ memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN);
} else {
netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n",
- efx->mac_address);
+ perm_addr);
if (!allow_bad_hwaddr) {
rc = -EINVAL;
goto err;
@@ -1394,12 +1403,14 @@ static void efx_start_all(struct efx_nic *efx)
* restart the transmit interface early so the watchdog timer stops */
efx_start_port(efx);
- efx_for_each_channel(channel, efx) {
- if (efx_dev_registered(efx))
- efx_wake_queue(channel);
+ if (efx_dev_registered(efx))
+ netif_tx_wake_all_queues(efx->net_dev);
+
+ efx_for_each_channel(channel, efx)
efx_start_channel(channel);
- }
+ if (efx->legacy_irq)
+ efx->legacy_irq_enabled = true;
efx_nic_enable_interrupts(efx);
/* Switch to event based MCDI completions after enabling interrupts.
@@ -1460,8 +1471,10 @@ static void efx_stop_all(struct efx_nic *efx)
/* Disable interrupts and wait for ISR to complete */
efx_nic_disable_interrupts(efx);
- if (efx->legacy_irq)
+ if (efx->legacy_irq) {
synchronize_irq(efx->legacy_irq);
+ efx->legacy_irq_enabled = false;
+ }
efx_for_each_channel(channel, efx) {
if (channel->irq)
synchronize_irq(channel->irq);
@@ -1482,9 +1495,7 @@ static void efx_stop_all(struct efx_nic *efx)
/* Stop the kernel transmit interface late, so the watchdog
* timer isn't ticking over the flush */
if (efx_dev_registered(efx)) {
- struct efx_channel *channel;
- efx_for_each_channel(channel, efx)
- efx_stop_queue(channel);
+ netif_tx_stop_all_queues(efx->net_dev);
netif_tx_lock_bh(efx->net_dev);
netif_tx_unlock_bh(efx->net_dev);
}
@@ -1593,7 +1604,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
*
**************************************************************************/
-static int efx_init_napi(struct efx_nic *efx)
+static void efx_init_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
@@ -1602,18 +1613,21 @@ static int efx_init_napi(struct efx_nic *efx)
netif_napi_add(channel->napi_dev, &channel->napi_str,
efx_poll, napi_weight);
}
- return 0;
+}
+
+static void efx_fini_napi_channel(struct efx_channel *channel)
+{
+ if (channel->napi_dev)
+ netif_napi_del(&channel->napi_str);
+ channel->napi_dev = NULL;
}
static void efx_fini_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
- efx_for_each_channel(channel, efx) {
- if (channel->napi_dev)
- netif_napi_del(&channel->napi_str);
- channel->napi_dev = NULL;
- }
+ efx_for_each_channel(channel, efx)
+ efx_fini_napi_channel(channel);
}
/**************************************************************************
@@ -1877,6 +1891,7 @@ static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL);
static int efx_register_netdev(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
+ struct efx_channel *channel;
int rc;
net_dev->watchdog_timeo = 5 * HZ;
@@ -1899,6 +1914,14 @@ static int efx_register_netdev(struct efx_nic *efx)
if (rc)
goto fail_locked;
+ efx_for_each_channel(channel, efx) {
+ struct efx_tx_queue *tx_queue;
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ tx_queue->core_txq = netdev_get_tx_queue(
+ efx->net_dev, tx_queue->queue / EFX_TXQ_TYPES);
+ }
+ }
+
/* Always start with carrier off; PHY events will detect the link */
netif_carrier_off(efx->net_dev);
@@ -1962,7 +1985,6 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
efx_stop_all(efx);
mutex_lock(&efx->mac_lock);
- mutex_lock(&efx->spi_lock);
efx_fini_channels(efx);
if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
@@ -2004,7 +2026,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
efx_init_channels(efx);
efx_restore_filters(efx);
- mutex_unlock(&efx->spi_lock);
mutex_unlock(&efx->mac_lock);
efx_start_all(efx);
@@ -2014,7 +2035,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
fail:
efx->port_initialized = false;
- mutex_unlock(&efx->spi_lock);
mutex_unlock(&efx->mac_lock);
return rc;
@@ -2202,8 +2222,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
/* Initialise common structures */
memset(efx, 0, sizeof(*efx));
spin_lock_init(&efx->biu_lock);
- mutex_init(&efx->mdio_lock);
- mutex_init(&efx->spi_lock);
#ifdef CONFIG_SFC_MTD
INIT_LIST_HEAD(&efx->mtd_list);
#endif
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
if (rc)
goto fail1;
- rc = efx_init_napi(efx);
- if (rc)
- goto fail2;
+ efx_init_napi(efx);
rc = efx->type->init(efx);
if (rc) {
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
efx->type->fini(efx);
fail3:
efx_fini_napi(efx);
- fail2:
efx_remove_all(efx);
fail1:
return rc;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 10a1bf40da96..d43a7e5212b1 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,8 +36,6 @@ efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
extern netdev_tx_t
efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
-extern void efx_stop_queue(struct efx_channel *channel);
-extern void efx_wake_queue(struct efx_channel *channel);
/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
@@ -74,9 +72,8 @@ extern int efx_filter_insert_filter(struct efx_nic *efx,
bool replace);
extern int efx_filter_remove_filter(struct efx_nic *efx,
struct efx_filter_spec *spec);
-extern void efx_filter_table_clear(struct efx_nic *efx,
- enum efx_filter_table_id table_id,
- enum efx_filter_priority priority);
+extern void efx_filter_clear_rx(struct efx_nic *efx,
+ enum efx_filter_priority priority);
/* Channels */
extern void efx_process_channel_now(struct efx_channel *channel);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index edb9d16b8b47..0e8bb19ed60d 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -11,14 +11,13 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
+#include <linux/in.h>
#include "net_driver.h"
#include "workarounds.h"
#include "selftest.h"
#include "efx.h"
#include "filter.h"
#include "nic.h"
-#include "spi.h"
-#include "mdio_10g.h"
struct ethtool_string {
char name[ETH_GSTRING_LEN];
@@ -560,12 +559,8 @@ static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data)
if (rc)
return rc;
- if (!(data & ETH_FLAG_NTUPLE)) {
- efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP,
- EFX_FILTER_PRI_MANUAL);
- efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC,
- EFX_FILTER_PRI_MANUAL);
- }
+ if (!(data & ETH_FLAG_NTUPLE))
+ efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
return 0;
}
@@ -584,6 +579,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
goto fail1;
}
+ netif_info(efx, drv, efx->net_dev, "starting %sline testing\n",
+ (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
+
/* We need rx buffers and interrupts. */
already_up = (efx->net_dev->flags & IFF_UP);
if (!already_up) {
@@ -602,9 +600,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
if (!already_up)
dev_close(efx->net_dev);
- netif_dbg(efx, drv, efx->net_dev, "%s %sline self-tests\n",
- rc == 0 ? "passed" : "failed",
- (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
+ netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n",
+ rc == 0 ? "passed" : "failed",
+ (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
fail2:
fail1:
@@ -622,68 +620,6 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
return mdio45_nway_restart(&efx->mdio);
}
-static u32 efx_ethtool_get_link(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- return efx->link_state.up;
-}
-
-static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_spi_device *spi = efx->spi_eeprom;
-
- if (!spi)
- return 0;
- return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) -
- min(spi->size, EFX_EEPROM_BOOTCONFIG_START);
-}
-
-static int efx_ethtool_get_eeprom(struct net_device *net_dev,
- struct ethtool_eeprom *eeprom, u8 *buf)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_spi_device *spi = efx->spi_eeprom;
- size_t len;
- int rc;
-
- rc = mutex_lock_interruptible(&efx->spi_lock);
- if (rc)
- return rc;
- rc = falcon_spi_read(efx, spi,
- eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
- eeprom->len, &len, buf);
- mutex_unlock(&efx->spi_lock);
-
- eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC;
- eeprom->len = len;
- return rc;
-}
-
-static int efx_ethtool_set_eeprom(struct net_device *net_dev,
- struct ethtool_eeprom *eeprom, u8 *buf)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_spi_device *spi = efx->spi_eeprom;
- size_t len;
- int rc;
-
- if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC)
- return -EINVAL;
-
- rc = mutex_lock_interruptible(&efx->spi_lock);
- if (rc)
- return rc;
- rc = falcon_spi_write(efx, spi,
- eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
- eeprom->len, &len, buf);
- mutex_unlock(&efx->spi_lock);
-
- eeprom->len = len;
- return rc;
-}
-
static int efx_ethtool_get_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
@@ -978,6 +914,7 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec;
struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec;
struct efx_filter_spec filter;
+ int rc;
/* Range-check action */
if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR ||
@@ -987,9 +924,16 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
if (~ntuple->fs.data_mask)
return -EINVAL;
+ efx_filter_init_rx(&filter, EFX_FILTER_PRI_MANUAL, 0,
+ (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) ?
+ 0xfff : ntuple->fs.action);
+
switch (ntuple->fs.flow_type) {
case TCP_V4_FLOW:
- case UDP_V4_FLOW:
+ case UDP_V4_FLOW: {
+ u8 proto = (ntuple->fs.flow_type == TCP_V4_FLOW ?
+ IPPROTO_TCP : IPPROTO_UDP);
+
/* Must match all of destination, */
if (ip_mask->ip4dst | ip_mask->pdst)
return -EINVAL;
@@ -1001,7 +945,22 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
/* and nothing else */
if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask)
return -EINVAL;
+
+ if (!ip_mask->ip4src)
+ rc = efx_filter_set_ipv4_full(&filter, proto,
+ ip_entry->ip4dst,
+ ip_entry->pdst,
+ ip_entry->ip4src,
+ ip_entry->psrc);
+ else
+ rc = efx_filter_set_ipv4_local(&filter, proto,
+ ip_entry->ip4dst,
+ ip_entry->pdst);
+ if (rc)
+ return rc;
break;
+ }
+
case ETHER_FLOW:
/* Must match all of destination, */
if (!is_zero_ether_addr(mac_mask->h_dest))
@@ -1014,58 +973,24 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
if (!is_broadcast_ether_addr(mac_mask->h_source) ||
mac_mask->h_proto != htons(0xffff))
return -EINVAL;
+
+ rc = efx_filter_set_eth_local(
+ &filter,
+ (ntuple->fs.vlan_tag_mask == 0xf000) ?
+ ntuple->fs.vlan_tag : EFX_FILTER_VID_UNSPEC,
+ mac_entry->h_dest);
+ if (rc)
+ return rc;
break;
+
default:
return -EINVAL;
}
- filter.priority = EFX_FILTER_PRI_MANUAL;
- filter.flags = 0;
-
- switch (ntuple->fs.flow_type) {
- case TCP_V4_FLOW:
- if (!ip_mask->ip4src)
- efx_filter_set_rx_tcp_full(&filter,
- htonl(ip_entry->ip4src),
- htons(ip_entry->psrc),
- htonl(ip_entry->ip4dst),
- htons(ip_entry->pdst));
- else
- efx_filter_set_rx_tcp_wild(&filter,
- htonl(ip_entry->ip4dst),
- htons(ip_entry->pdst));
- break;
- case UDP_V4_FLOW:
- if (!ip_mask->ip4src)
- efx_filter_set_rx_udp_full(&filter,
- htonl(ip_entry->ip4src),
- htons(ip_entry->psrc),
- htonl(ip_entry->ip4dst),
- htons(ip_entry->pdst));
- else
- efx_filter_set_rx_udp_wild(&filter,
- htonl(ip_entry->ip4dst),
- htons(ip_entry->pdst));
- break;
- case ETHER_FLOW:
- if (ntuple->fs.vlan_tag_mask == 0xf000)
- efx_filter_set_rx_mac_full(&filter,
- ntuple->fs.vlan_tag & 0xfff,
- mac_entry->h_dest);
- else
- efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest);
- break;
- }
-
- if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) {
+ if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR)
return efx_filter_remove_filter(efx, &filter);
- } else {
- if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
- filter.dmaq_id = 0xfff;
- else
- filter.dmaq_id = ntuple->fs.action;
+ else
return efx_filter_insert_filter(efx, &filter, true);
- }
}
static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
@@ -1115,10 +1040,7 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_msglevel = efx_ethtool_get_msglevel,
.set_msglevel = efx_ethtool_set_msglevel,
.nway_reset = efx_ethtool_nway_reset,
- .get_link = efx_ethtool_get_link,
- .get_eeprom_len = efx_ethtool_get_eeprom_len,
- .get_eeprom = efx_ethtool_get_eeprom,
- .set_eeprom = efx_ethtool_set_eeprom,
+ .get_link = ethtool_op_get_link,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
.get_ringparam = efx_ethtool_get_ringparam,
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 267019bb2b15..61ddd2c6e750 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -24,7 +24,6 @@
#include "nic.h"
#include "regs.h"
#include "io.h"
-#include "mdio_10g.h"
#include "phy.h"
#include "workarounds.h"
@@ -255,7 +254,6 @@ int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi,
/* Input validation */
if (len > FALCON_SPI_MAX_LEN)
return -EINVAL;
- BUG_ON(!mutex_is_locked(&efx->spi_lock));
/* Check that previous command is not still running */
rc = falcon_spi_poll(efx);
@@ -719,6 +717,7 @@ static int falcon_mdio_write(struct net_device *net_dev,
int prtad, int devad, u16 addr, u16 value)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ struct falcon_nic_data *nic_data = efx->nic_data;
efx_oword_t reg;
int rc;
@@ -726,7 +725,7 @@ static int falcon_mdio_write(struct net_device *net_dev,
"writing MDIO %d register %d.%d with 0x%04x\n",
prtad, devad, addr, value);
- mutex_lock(&efx->mdio_lock);
+ mutex_lock(&nic_data->mdio_lock);
/* Check MDIO not currently being accessed */
rc = falcon_gmii_wait(efx);
@@ -762,7 +761,7 @@ static int falcon_mdio_write(struct net_device *net_dev,
}
out:
- mutex_unlock(&efx->mdio_lock);
+ mutex_unlock(&nic_data->mdio_lock);
return rc;
}
@@ -771,10 +770,11 @@ static int falcon_mdio_read(struct net_device *net_dev,
int prtad, int devad, u16 addr)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ struct falcon_nic_data *nic_data = efx->nic_data;
efx_oword_t reg;
int rc;
- mutex_lock(&efx->mdio_lock);
+ mutex_lock(&nic_data->mdio_lock);
/* Check MDIO not currently being accessed */
rc = falcon_gmii_wait(efx);
@@ -813,7 +813,7 @@ static int falcon_mdio_read(struct net_device *net_dev,
}
out:
- mutex_unlock(&efx->mdio_lock);
+ mutex_unlock(&nic_data->mdio_lock);
return rc;
}
@@ -841,6 +841,7 @@ static int falcon_probe_port(struct efx_nic *efx)
}
/* Fill out MDIO structure and loopback modes */
+ mutex_init(&nic_data->mdio_lock);
efx->mdio.mdio_read = falcon_mdio_read;
efx->mdio.mdio_write = falcon_mdio_write;
rc = efx->phy_op->probe(efx);
@@ -880,6 +881,41 @@ static void falcon_remove_port(struct efx_nic *efx)
efx_nic_free_buffer(efx, &efx->stats_buffer);
}
+/* Global events are basically PHY events */
+static bool
+falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
+{
+ struct efx_nic *efx = channel->efx;
+ struct falcon_nic_data *nic_data = efx->nic_data;
+
+ if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
+ EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
+ EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR))
+ /* Ignored */
+ return true;
+
+ if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) &&
+ EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
+ nic_data->xmac_poll_required = true;
+ return true;
+ }
+
+ if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
+ EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
+ EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
+ netif_err(efx, rx_err, efx->net_dev,
+ "channel %d seen global RX_RESET event. Resetting.\n",
+ channel->channel);
+
+ atomic_inc(&efx->rx_reset);
+ efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
+ RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
+ return true;
+ }
+
+ return false;
+}
+
/**************************************************************************
*
* Falcon test code
@@ -889,6 +925,7 @@ static void falcon_remove_port(struct efx_nic *efx)
static int
falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
struct falcon_nvconfig *nvconfig;
struct efx_spi_device *spi;
void *region;
@@ -896,8 +933,11 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
__le16 *word, *limit;
u32 csum;
- spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom;
- if (!spi)
+ if (efx_spi_present(&nic_data->spi_flash))
+ spi = &nic_data->spi_flash;
+ else if (efx_spi_present(&nic_data->spi_eeprom))
+ spi = &nic_data->spi_eeprom;
+ else
return -EINVAL;
region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL);
@@ -905,12 +945,13 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
return -ENOMEM;
nvconfig = region + FALCON_NVCONFIG_OFFSET;
- mutex_lock(&efx->spi_lock);
+ mutex_lock(&nic_data->spi_lock);
rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region);
- mutex_unlock(&efx->spi_lock);
+ mutex_unlock(&nic_data->spi_lock);
if (rc) {
netif_err(efx, hw, efx->net_dev, "Failed to read %s\n",
- efx->spi_flash ? "flash" : "EEPROM");
+ efx_spi_present(&nic_data->spi_flash) ?
+ "flash" : "EEPROM");
rc = -EIO;
goto out;
}
@@ -1012,7 +1053,7 @@ static int falcon_b0_test_registers(struct efx_nic *efx)
/* Resets NIC to known state. This routine must be called in process
* context and is allowed to sleep. */
-static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
+static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
{
struct falcon_nic_data *nic_data = efx->nic_data;
efx_oword_t glb_ctl_reg_ker;
@@ -1066,22 +1107,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
/* Restore PCI configuration if needed */
if (method == RESET_TYPE_WORLD) {
- if (efx_nic_is_dual_func(efx)) {
- rc = pci_restore_state(nic_data->pci_dev2);
- if (rc) {
- netif_err(efx, drv, efx->net_dev,
- "failed to restore PCI config for "
- "the secondary function\n");
- goto fail3;
- }
- }
- rc = pci_restore_state(efx->pci_dev);
- if (rc) {
- netif_err(efx, drv, efx->net_dev,
- "failed to restore PCI config for the "
- "primary function\n");
- goto fail4;
- }
+ if (efx_nic_is_dual_func(efx))
+ pci_restore_state(nic_data->pci_dev2);
+ pci_restore_state(efx->pci_dev);
netif_dbg(efx, drv, efx->net_dev,
"successfully restored PCI config\n");
}
@@ -1092,7 +1120,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
rc = -ETIMEDOUT;
netif_err(efx, hw, efx->net_dev,
"timed out waiting for hardware reset\n");
- goto fail5;
+ goto fail3;
}
netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n");
@@ -1100,11 +1128,21 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
/* pci_save_state() and pci_restore_state() MUST be called in pairs */
fail2:
-fail3:
pci_restore_state(efx->pci_dev);
fail1:
-fail4:
-fail5:
+fail3:
+ return rc;
+}
+
+static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
+{
+ struct falcon_nic_data *nic_data = efx->nic_data;
+ int rc;
+
+ mutex_lock(&nic_data->spi_lock);
+ rc = __falcon_reset_hw(efx, method);
+ mutex_unlock(&nic_data->spi_lock);
+
return rc;
}
@@ -1189,16 +1227,11 @@ static int falcon_reset_sram(struct efx_nic *efx)
return -ETIMEDOUT;
}
-static int falcon_spi_device_init(struct efx_nic *efx,
- struct efx_spi_device **spi_device_ret,
+static void falcon_spi_device_init(struct efx_nic *efx,
+ struct efx_spi_device *spi_device,
unsigned int device_id, u32 device_type)
{
- struct efx_spi_device *spi_device;
-
if (device_type != 0) {
- spi_device = kzalloc(sizeof(*spi_device), GFP_KERNEL);
- if (!spi_device)
- return -ENOMEM;
spi_device->device_id = device_id;
spi_device->size =
1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_SIZE);
@@ -1215,27 +1248,15 @@ static int falcon_spi_device_init(struct efx_nic *efx,
1 << SPI_DEV_TYPE_FIELD(device_type,
SPI_DEV_TYPE_BLOCK_SIZE);
} else {
- spi_device = NULL;
+ spi_device->size = 0;
}
-
- kfree(*spi_device_ret);
- *spi_device_ret = spi_device;
- return 0;
-}
-
-static void falcon_remove_spi_devices(struct efx_nic *efx)
-{
- kfree(efx->spi_eeprom);
- efx->spi_eeprom = NULL;
- kfree(efx->spi_flash);
- efx->spi_flash = NULL;
}
/* Extract non-volatile configuration */
static int falcon_probe_nvconfig(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
struct falcon_nvconfig *nvconfig;
- int board_rev;
int rc;
nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL);
@@ -1243,55 +1264,32 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
return -ENOMEM;
rc = falcon_read_nvram(efx, nvconfig);
- if (rc == -EINVAL) {
- netif_err(efx, probe, efx->net_dev,
- "NVRAM is invalid therefore using defaults\n");
- efx->phy_type = PHY_TYPE_NONE;
- efx->mdio.prtad = MDIO_PRTAD_NONE;
- board_rev = 0;
- rc = 0;
- } else if (rc) {
- goto fail1;
- } else {
- struct falcon_nvconfig_board_v2 *v2 = &nvconfig->board_v2;
- struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
-
- efx->phy_type = v2->port0_phy_type;
- efx->mdio.prtad = v2->port0_phy_addr;
- board_rev = le16_to_cpu(v2->board_revision);
-
- if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
- rc = falcon_spi_device_init(
- efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH,
- le32_to_cpu(v3->spi_device_type
- [FFE_AB_SPI_DEVICE_FLASH]));
- if (rc)
- goto fail2;
- rc = falcon_spi_device_init(
- efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM,
- le32_to_cpu(v3->spi_device_type
- [FFE_AB_SPI_DEVICE_EEPROM]));
- if (rc)
- goto fail2;
- }
+ if (rc)
+ goto out;
+
+ efx->phy_type = nvconfig->board_v2.port0_phy_type;
+ efx->mdio.prtad = nvconfig->board_v2.port0_phy_addr;
+
+ if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
+ falcon_spi_device_init(
+ efx, &nic_data->spi_flash, FFE_AB_SPI_DEVICE_FLASH,
+ le32_to_cpu(nvconfig->board_v3
+ .spi_device_type[FFE_AB_SPI_DEVICE_FLASH]));
+ falcon_spi_device_init(
+ efx, &nic_data->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM,
+ le32_to_cpu(nvconfig->board_v3
+ .spi_device_type[FFE_AB_SPI_DEVICE_EEPROM]));
}
/* Read the MAC addresses */
- memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
+ memcpy(efx->net_dev->perm_addr, nvconfig->mac_address[0], ETH_ALEN);
netif_dbg(efx, probe, efx->net_dev, "PHY is %d phy_id %d\n",
efx->phy_type, efx->mdio.prtad);
- rc = falcon_probe_board(efx, board_rev);
- if (rc)
- goto fail2;
-
- kfree(nvconfig);
- return 0;
-
- fail2:
- falcon_remove_spi_devices(efx);
- fail1:
+ rc = falcon_probe_board(efx,
+ le16_to_cpu(nvconfig->board_v2.board_revision));
+out:
kfree(nvconfig);
return rc;
}
@@ -1299,6 +1297,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
/* Probe all SPI devices on the NIC */
static void falcon_probe_spi_devices(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg;
int boot_dev;
@@ -1327,12 +1326,14 @@ static void falcon_probe_spi_devices(struct efx_nic *efx)
efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0);
}
+ mutex_init(&nic_data->spi_lock);
+
if (boot_dev == FFE_AB_SPI_DEVICE_FLASH)
- falcon_spi_device_init(efx, &efx->spi_flash,
+ falcon_spi_device_init(efx, &nic_data->spi_flash,
FFE_AB_SPI_DEVICE_FLASH,
default_flash_type);
if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM)
- falcon_spi_device_init(efx, &efx->spi_eeprom,
+ falcon_spi_device_init(efx, &nic_data->spi_eeprom,
FFE_AB_SPI_DEVICE_EEPROM,
large_eeprom_type);
}
@@ -1397,7 +1398,7 @@ static int falcon_probe_nic(struct efx_nic *efx)
}
/* Now we can reset the NIC */
- rc = falcon_reset_hw(efx, RESET_TYPE_ALL);
+ rc = __falcon_reset_hw(efx, RESET_TYPE_ALL);
if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n");
goto fail3;
@@ -1419,8 +1420,11 @@ static int falcon_probe_nic(struct efx_nic *efx)
/* Read in the non-volatile configuration */
rc = falcon_probe_nvconfig(efx);
- if (rc)
+ if (rc) {
+ if (rc == -EINVAL)
+ netif_err(efx, probe, efx->net_dev, "NVRAM is invalid\n");
goto fail5;
+ }
/* Initialise I2C adapter */
board = falcon_board(efx);
@@ -1452,7 +1456,6 @@ static int falcon_probe_nic(struct efx_nic *efx)
BUG_ON(i2c_del_adapter(&board->i2c_adap));
memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
fail5:
- falcon_remove_spi_devices(efx);
efx_nic_free_buffer(efx, &efx->irq_status);
fail4:
fail3:
@@ -1606,10 +1609,9 @@ static void falcon_remove_nic(struct efx_nic *efx)
BUG_ON(rc);
memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
- falcon_remove_spi_devices(efx);
efx_nic_free_buffer(efx, &efx->irq_status);
- falcon_reset_hw(efx, RESET_TYPE_ALL);
+ __falcon_reset_hw(efx, RESET_TYPE_ALL);
/* Release the second function after the reset */
if (nic_data->pci_dev2) {
@@ -1720,6 +1722,7 @@ struct efx_nic_type falcon_a1_nic_type = {
.reset = falcon_reset_hw,
.probe_port = falcon_probe_port,
.remove_port = falcon_remove_port,
+ .handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
@@ -1760,6 +1763,7 @@ struct efx_nic_type falcon_b0_nic_type = {
.reset = falcon_reset_hw,
.probe_port = falcon_probe_port,
.remove_port = falcon_remove_port,
+ .handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index cfc6a5b5a477..2dd16f0b3ced 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -13,8 +13,6 @@
#include "phy.h"
#include "efx.h"
#include "nic.h"
-#include "regs.h"
-#include "io.h"
#include "workarounds.h"
/* Macros for unpacking the board revision */
@@ -30,17 +28,28 @@
#define FALCON_BOARD_SFN4112F 0x52
/* Board temperature is about 15°C above ambient when air flow is
- * limited. */
+ * limited. The maximum acceptable ambient temperature varies
+ * depending on the PHY specifications but the critical temperature
+ * above which we should shut down to avoid damage is 80°C. */
#define FALCON_BOARD_TEMP_BIAS 15
+#define FALCON_BOARD_TEMP_CRIT (80 + FALCON_BOARD_TEMP_BIAS)
/* SFC4000 datasheet says: 'The maximum permitted junction temperature
* is 125°C; the thermal design of the environment for the SFC4000
* should aim to keep this well below 100°C.' */
+#define FALCON_JUNC_TEMP_MIN 0
#define FALCON_JUNC_TEMP_MAX 90
+#define FALCON_JUNC_TEMP_CRIT 125
/*****************************************************************************
* Support for LM87 sensor chip used on several boards
*/
+#define LM87_REG_TEMP_HW_INT_LOCK 0x13
+#define LM87_REG_TEMP_HW_EXT_LOCK 0x14
+#define LM87_REG_TEMP_HW_INT 0x17
+#define LM87_REG_TEMP_HW_EXT 0x18
+#define LM87_REG_TEMP_EXT1 0x26
+#define LM87_REG_TEMP_INT 0x27
#define LM87_REG_ALARMS1 0x41
#define LM87_REG_ALARMS2 0x42
#define LM87_IN_LIMITS(nr, _min, _max) \
@@ -57,6 +66,27 @@
#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
+static int efx_poke_lm87(struct i2c_client *client, const u8 *reg_values)
+{
+ while (*reg_values) {
+ u8 reg = *reg_values++;
+ u8 value = *reg_values++;
+ int rc = i2c_smbus_write_byte_data(client, reg, value);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+static const u8 falcon_lm87_common_regs[] = {
+ LM87_REG_TEMP_HW_INT_LOCK, FALCON_BOARD_TEMP_CRIT,
+ LM87_REG_TEMP_HW_INT, FALCON_BOARD_TEMP_CRIT,
+ LM87_TEMP_EXT1_LIMITS(FALCON_JUNC_TEMP_MIN, FALCON_JUNC_TEMP_MAX),
+ LM87_REG_TEMP_HW_EXT_LOCK, FALCON_JUNC_TEMP_CRIT,
+ LM87_REG_TEMP_HW_EXT, FALCON_JUNC_TEMP_CRIT,
+ 0
+};
+
static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
const u8 *reg_values)
{
@@ -67,13 +97,16 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
if (!client)
return -EIO;
- while (*reg_values) {
- u8 reg = *reg_values++;
- u8 value = *reg_values++;
- rc = i2c_smbus_write_byte_data(client, reg, value);
- if (rc)
- goto err;
- }
+ /* Read-to-clear alarm/interrupt status */
+ i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
+ i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
+
+ rc = efx_poke_lm87(client, reg_values);
+ if (rc)
+ goto err;
+ rc = efx_poke_lm87(client, falcon_lm87_common_regs);
+ if (rc)
+ goto err;
board->hwmon_client = client;
return 0;
@@ -91,36 +124,56 @@ static void efx_fini_lm87(struct efx_nic *efx)
static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
{
struct i2c_client *client = falcon_board(efx)->hwmon_client;
- s32 alarms1, alarms2;
+ bool temp_crit, elec_fault, is_failure;
+ u16 alarms;
+ s32 reg;
/* If link is up then do not monitor temperature */
if (EFX_WORKAROUND_7884(efx) && efx->link_state.up)
return 0;
- alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
- alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
- if (alarms1 < 0)
- return alarms1;
- if (alarms2 < 0)
- return alarms2;
- alarms1 &= mask;
- alarms2 &= mask >> 8;
- if (alarms1 || alarms2) {
+ reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
+ if (reg < 0)
+ return reg;
+ alarms = reg;
+ reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
+ if (reg < 0)
+ return reg;
+ alarms |= reg << 8;
+ alarms &= mask;
+
+ temp_crit = false;
+ if (alarms & LM87_ALARM_TEMP_INT) {
+ reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_INT);
+ if (reg < 0)
+ return reg;
+ if (reg > FALCON_BOARD_TEMP_CRIT)
+ temp_crit = true;
+ }
+ if (alarms & LM87_ALARM_TEMP_EXT1) {
+ reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_EXT1);
+ if (reg < 0)
+ return reg;
+ if (reg > FALCON_JUNC_TEMP_CRIT)
+ temp_crit = true;
+ }
+ elec_fault = alarms & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1);
+ is_failure = temp_crit || elec_fault;
+
+ if (alarms)
netif_err(efx, hw, efx->net_dev,
- "LM87 detected a hardware failure (status %02x:%02x)"
- "%s%s%s\n",
- alarms1, alarms2,
- (alarms1 & LM87_ALARM_TEMP_INT) ?
+ "LM87 detected a hardware %s (status %02x:%02x)"
+ "%s%s%s%s\n",
+ is_failure ? "failure" : "problem",
+ alarms & 0xff, alarms >> 8,
+ (alarms & LM87_ALARM_TEMP_INT) ?
"; board is overheating" : "",
- (alarms1 & LM87_ALARM_TEMP_EXT1) ?
+ (alarms & LM87_ALARM_TEMP_EXT1) ?
"; controller is overheating" : "",
- (alarms1 & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1)
- || alarms2) ?
- "; electrical fault" : "");
- return -ERANGE;
- }
+ temp_crit ? "; reached critical temperature" : "",
+ elec_fault ? "; electrical fault" : "");
- return 0;
+ return is_failure ? -ERANGE : 0;
}
#else /* !CONFIG_SENSORS_LM87 */
@@ -325,7 +378,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
new_mode = old_mode & ~PHY_MODE_SPECIAL;
else
new_mode = PHY_MODE_SPECIAL;
- if (old_mode == new_mode) {
+ if (!((old_mode ^ new_mode) & PHY_MODE_SPECIAL)) {
err = 0;
} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
err = -EBUSY;
@@ -362,10 +415,11 @@ static void sfe4001_fini(struct efx_nic *efx)
static int sfe4001_check_hw(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
s32 status;
/* If XAUI link is up then do not monitor */
- if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
+ if (EFX_WORKAROUND_7884(efx) && !nic_data->xmac_poll_required)
return 0;
/* Check the powered status of the PHY. Lack of power implies that
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index b31f595ebb5b..b49e84394641 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -16,7 +16,6 @@
#include "io.h"
#include "mac.h"
#include "mdio_10g.h"
-#include "phy.h"
#include "workarounds.h"
/**************************************************************************
@@ -88,6 +87,7 @@ int falcon_reset_xaui(struct efx_nic *efx)
static void falcon_ack_status_intr(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
efx_oword_t reg;
if ((efx_nic_rev(efx) != EFX_REV_FALCON_B0) || LOOPBACK_INTERNAL(efx))
@@ -99,7 +99,7 @@ static void falcon_ack_status_intr(struct efx_nic *efx)
/* We can only use this interrupt to signal the negative edge of
* xaui_align [we have to poll the positive edge]. */
- if (efx->xmac_poll_required)
+ if (nic_data->xmac_poll_required)
return;
efx_reado(efx, &reg, FR_AB_XM_MGT_INT_MSK);
@@ -277,12 +277,14 @@ static bool falcon_xmac_check_fault(struct efx_nic *efx)
static int falcon_reconfigure_xmac(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
+
falcon_reconfigure_xgxs_core(efx);
falcon_reconfigure_xmac_core(efx);
falcon_reconfigure_mac_wrapper(efx);
- efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5);
+ nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5);
falcon_ack_status_intr(efx);
return 0;
@@ -350,11 +352,13 @@ static void falcon_update_stats_xmac(struct efx_nic *efx)
void falcon_poll_xmac(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
+
if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up ||
- !efx->xmac_poll_required)
+ !nic_data->xmac_poll_required)
return;
- efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1);
+ nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1);
falcon_ack_status_intr(efx);
}
diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c
index 52cb6082b910..d4722c41c4ce 100644
--- a/drivers/net/sfc/filter.c
+++ b/drivers/net/sfc/filter.c
@@ -7,6 +7,7 @@
* by the Free Software Foundation, incorporated herein by reference.
*/
+#include <linux/in.h>
#include "efx.h"
#include "filter.h"
#include "io.h"
@@ -26,19 +27,26 @@
*/
#define FILTER_CTL_SRCH_MAX 200
+enum efx_filter_table_id {
+ EFX_FILTER_TABLE_RX_IP = 0,
+ EFX_FILTER_TABLE_RX_MAC,
+ EFX_FILTER_TABLE_COUNT,
+};
+
struct efx_filter_table {
+ enum efx_filter_table_id id;
u32 offset; /* address of table relative to BAR */
unsigned size; /* number of entries */
unsigned step; /* step between entries */
unsigned used; /* number currently used */
unsigned long *used_bitmap;
struct efx_filter_spec *spec;
+ unsigned search_depth[EFX_FILTER_TYPE_COUNT];
};
struct efx_filter_state {
spinlock_t lock;
struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
- unsigned search_depth[EFX_FILTER_TYPE_COUNT];
};
/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
@@ -65,68 +73,203 @@ static u16 efx_filter_increment(u32 key)
}
static enum efx_filter_table_id
-efx_filter_type_table_id(enum efx_filter_type type)
+efx_filter_spec_table_id(const struct efx_filter_spec *spec)
+{
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2));
+ EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC);
+ return spec->type >> 2;
+}
+
+static struct efx_filter_table *
+efx_filter_spec_table(struct efx_filter_state *state,
+ const struct efx_filter_spec *spec)
{
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2));
- return type >> 2;
+ if (spec->type == EFX_FILTER_UNSPEC)
+ return NULL;
+ else
+ return &state->table[efx_filter_spec_table_id(spec)];
}
-static void
-efx_filter_table_reset_search_depth(struct efx_filter_state *state,
- enum efx_filter_table_id table_id)
+static void efx_filter_table_reset_search_depth(struct efx_filter_table *table)
{
- memset(state->search_depth + (table_id << 2), 0,
- sizeof(state->search_depth[0]) << 2);
+ memset(table->search_depth, 0, sizeof(table->search_depth));
}
static void efx_filter_push_rx_limits(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
+ struct efx_filter_table *table;
efx_oword_t filter_ctl;
efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
+ table = &state->table[EFX_FILTER_TABLE_RX_IP];
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_TCP_FULL] +
+ table->search_depth[EFX_FILTER_TCP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_TCP_WILD] +
+ table->search_depth[EFX_FILTER_TCP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_UDP_FULL] +
+ table->search_depth[EFX_FILTER_UDP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_UDP_WILD] +
+ table->search_depth[EFX_FILTER_UDP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
- if (state->table[EFX_FILTER_TABLE_RX_MAC].size) {
+ table = &state->table[EFX_FILTER_TABLE_RX_MAC];
+ if (table->size) {
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_MAC_FULL] +
+ table->search_depth[EFX_FILTER_MAC_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
- state->search_depth[EFX_FILTER_RX_MAC_WILD] +
+ table->search_depth[EFX_FILTER_MAC_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
}
efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
}
+static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec,
+ __be32 host1, __be16 port1,
+ __be32 host2, __be16 port2)
+{
+ spec->data[0] = ntohl(host1) << 16 | ntohs(port1);
+ spec->data[1] = ntohs(port2) << 16 | ntohl(host1) >> 16;
+ spec->data[2] = ntohl(host2);
+}
+
+/**
+ * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port
+ * @spec: Specification to initialise
+ * @proto: Transport layer protocol number
+ * @host: Local host address (network byte order)
+ * @port: Local port (network byte order)
+ */
+int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
+ __be32 host, __be16 port)
+{
+ __be32 host1;
+ __be16 port1;
+
+ EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
+
+ /* This cannot currently be combined with other filtering */
+ if (spec->type != EFX_FILTER_UNSPEC)
+ return -EPROTONOSUPPORT;
+
+ if (port == 0)
+ return -EINVAL;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ spec->type = EFX_FILTER_TCP_WILD;
+ break;
+ case IPPROTO_UDP:
+ spec->type = EFX_FILTER_UDP_WILD;
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ /* Filter is constructed in terms of source and destination,
+ * with the odd wrinkle that the ports are swapped in a UDP
+ * wildcard filter. We need to convert from local and remote
+ * (= zero for wildcard) addresses.
+ */
+ host1 = 0;
+ if (proto != IPPROTO_UDP) {
+ port1 = 0;
+ } else {
+ port1 = port;
+ port = 0;
+ }
+
+ __efx_filter_set_ipv4(spec, host1, port1, host, port);
+ return 0;
+}
+
+/**
+ * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports
+ * @spec: Specification to initialise
+ * @proto: Transport layer protocol number
+ * @host: Local host address (network byte order)
+ * @port: Local port (network byte order)
+ * @rhost: Remote host address (network byte order)
+ * @rport: Remote port (network byte order)
+ */
+int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
+ __be32 host, __be16 port,
+ __be32 rhost, __be16 rport)
+{
+ EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
+
+ /* This cannot currently be combined with other filtering */
+ if (spec->type != EFX_FILTER_UNSPEC)
+ return -EPROTONOSUPPORT;
+
+ if (port == 0 || rport == 0)
+ return -EINVAL;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ spec->type = EFX_FILTER_TCP_FULL;
+ break;
+ case IPPROTO_UDP:
+ spec->type = EFX_FILTER_UDP_FULL;
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ __efx_filter_set_ipv4(spec, rhost, rport, host, port);
+ return 0;
+}
+
+/**
+ * efx_filter_set_eth_local - specify local Ethernet address and optional VID
+ * @spec: Specification to initialise
+ * @vid: VLAN ID to match, or %EFX_FILTER_VID_UNSPEC
+ * @addr: Local Ethernet MAC address
+ */
+int efx_filter_set_eth_local(struct efx_filter_spec *spec,
+ u16 vid, const u8 *addr)
+{
+ EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
+
+ /* This cannot currently be combined with other filtering */
+ if (spec->type != EFX_FILTER_UNSPEC)
+ return -EPROTONOSUPPORT;
+
+ if (vid == EFX_FILTER_VID_UNSPEC) {
+ spec->type = EFX_FILTER_MAC_WILD;
+ spec->data[0] = 0;
+ } else {
+ spec->type = EFX_FILTER_MAC_FULL;
+ spec->data[0] = vid;
+ }
+
+ spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
+ spec->data[2] = addr[0] << 8 | addr[1];
+ return 0;
+}
+
/* Build a filter entry and return its n-tuple key. */
static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
{
u32 data3;
- switch (efx_filter_type_table_id(spec->type)) {
+ switch (efx_filter_spec_table_id(spec)) {
case EFX_FILTER_TABLE_RX_IP: {
- bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL ||
- spec->type == EFX_FILTER_RX_UDP_WILD);
+ bool is_udp = (spec->type == EFX_FILTER_UDP_FULL ||
+ spec->type == EFX_FILTER_UDP_WILD);
EFX_POPULATE_OWORD_7(
*filter,
FRF_BZ_RSS_EN,
@@ -143,7 +286,7 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
}
case EFX_FILTER_TABLE_RX_MAC: {
- bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD;
+ bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
EFX_POPULATE_OWORD_8(
*filter,
FRF_CZ_RMFT_RSS_EN,
@@ -206,6 +349,14 @@ found:
return filter_idx;
}
+/* Construct/deconstruct external filter IDs */
+
+static inline int
+efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
+{
+ return table_id << 16 | index;
+}
+
/**
* efx_filter_insert_filter - add or replace a filter
* @efx: NIC in which to insert the filter
@@ -213,30 +364,28 @@ found:
* @replace: Flag for whether the specified filter may replace a filter
* with an identical match expression and equal or lower priority
*
- * On success, return the filter index within its table.
+ * On success, return the filter ID.
* On failure, return a negative error code.
*/
int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
bool replace)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id =
- efx_filter_type_table_id(spec->type);
- struct efx_filter_table *table = &state->table[table_id];
+ struct efx_filter_table *table = efx_filter_spec_table(state, spec);
struct efx_filter_spec *saved_spec;
efx_oword_t filter;
int filter_idx, depth;
u32 key;
int rc;
- if (table->size == 0)
+ if (!table || table->size == 0)
return -EINVAL;
key = efx_filter_build(&filter, spec);
netif_vdbg(efx, hw, efx->net_dev,
"%s: type %d search_depth=%d", __func__, spec->type,
- state->search_depth[spec->type]);
+ table->search_depth[spec->type]);
spin_lock_bh(&state->lock);
@@ -263,8 +412,8 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
}
*saved_spec = *spec;
- if (state->search_depth[spec->type] < depth) {
- state->search_depth[spec->type] = depth;
+ if (table->search_depth[spec->type] < depth) {
+ table->search_depth[spec->type] = depth;
efx_filter_push_rx_limits(efx);
}
@@ -273,6 +422,7 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
netif_vdbg(efx, hw, efx->net_dev,
"%s: filter type %d index %d rxq %u set",
__func__, spec->type, filter_idx, spec->dmaq_id);
+ rc = efx_filter_make_id(table->id, filter_idx);
out:
spin_unlock_bh(&state->lock);
@@ -306,15 +456,16 @@ static void efx_filter_table_clear_entry(struct efx_nic *efx,
int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id =
- efx_filter_type_table_id(spec->type);
- struct efx_filter_table *table = &state->table[table_id];
+ struct efx_filter_table *table = efx_filter_spec_table(state, spec);
struct efx_filter_spec *saved_spec;
efx_oword_t filter;
int filter_idx, depth;
u32 key;
int rc;
+ if (!table)
+ return -EINVAL;
+
key = efx_filter_build(&filter, spec);
spin_lock_bh(&state->lock);
@@ -332,7 +483,7 @@ int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
efx_filter_table_clear_entry(efx, table, filter_idx);
if (table->used == 0)
- efx_filter_table_reset_search_depth(state, table_id);
+ efx_filter_table_reset_search_depth(table);
rc = 0;
out:
@@ -340,15 +491,9 @@ out:
return rc;
}
-/**
- * efx_filter_table_clear - remove filters from a table by priority
- * @efx: NIC from which to remove the filters
- * @table_id: Table from which to remove the filters
- * @priority: Maximum priority to remove
- */
-void efx_filter_table_clear(struct efx_nic *efx,
- enum efx_filter_table_id table_id,
- enum efx_filter_priority priority)
+static void efx_filter_table_clear(struct efx_nic *efx,
+ enum efx_filter_table_id table_id,
+ enum efx_filter_priority priority)
{
struct efx_filter_state *state = efx->filter_state;
struct efx_filter_table *table = &state->table[table_id];
@@ -360,11 +505,22 @@ void efx_filter_table_clear(struct efx_nic *efx,
if (table->spec[filter_idx].priority <= priority)
efx_filter_table_clear_entry(efx, table, filter_idx);
if (table->used == 0)
- efx_filter_table_reset_search_depth(state, table_id);
+ efx_filter_table_reset_search_depth(table);
spin_unlock_bh(&state->lock);
}
+/**
+ * efx_filter_clear_rx - remove RX filters by priority
+ * @efx: NIC from which to remove the filters
+ * @priority: Maximum priority to remove
+ */
+void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority)
+{
+ efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, priority);
+ efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority);
+}
+
/* Restore filter stater after reset */
void efx_restore_filters(struct efx_nic *efx)
{
@@ -407,6 +563,7 @@ int efx_probe_filters(struct efx_nic *efx)
if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
table = &state->table[EFX_FILTER_TABLE_RX_IP];
+ table->id = EFX_FILTER_TABLE_RX_IP;
table->offset = FR_BZ_RX_FILTER_TBL0;
table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
table->step = FR_BZ_RX_FILTER_TBL0_STEP;
@@ -414,6 +571,7 @@ int efx_probe_filters(struct efx_nic *efx)
if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
table = &state->table[EFX_FILTER_TABLE_RX_MAC];
+ table->id = EFX_FILTER_TABLE_RX_MAC;
table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
@@ -428,10 +586,9 @@ int efx_probe_filters(struct efx_nic *efx)
GFP_KERNEL);
if (!table->used_bitmap)
goto fail;
- table->spec = vmalloc(table->size * sizeof(*table->spec));
+ table->spec = vzalloc(table->size * sizeof(*table->spec));
if (!table->spec)
goto fail;
- memset(table->spec, 0, table->size * sizeof(*table->spec));
}
return 0;
diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h
index a53319ded79c..872f2132a496 100644
--- a/drivers/net/sfc/filter.h
+++ b/drivers/net/sfc/filter.h
@@ -12,31 +12,27 @@
#include <linux/types.h>
-enum efx_filter_table_id {
- EFX_FILTER_TABLE_RX_IP = 0,
- EFX_FILTER_TABLE_RX_MAC,
- EFX_FILTER_TABLE_COUNT,
-};
-
/**
* enum efx_filter_type - type of hardware filter
- * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple
- * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port)
- * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple
- * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port)
- * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID
- * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address
+ * @EFX_FILTER_TCP_FULL: Matching TCP/IPv4 4-tuple
+ * @EFX_FILTER_TCP_WILD: Matching TCP/IPv4 destination (host, port)
+ * @EFX_FILTER_UDP_FULL: Matching UDP/IPv4 4-tuple
+ * @EFX_FILTER_UDP_WILD: Matching UDP/IPv4 destination (host, port)
+ * @EFX_FILTER_MAC_FULL: Matching Ethernet destination MAC address, VID
+ * @EFX_FILTER_MAC_WILD: Matching Ethernet destination MAC address
+ * @EFX_FILTER_UNSPEC: Match type is unspecified
*
- * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types.
+ * Falcon NICs only support the TCP/IPv4 and UDP/IPv4 filter types.
*/
enum efx_filter_type {
- EFX_FILTER_RX_TCP_FULL = 0,
- EFX_FILTER_RX_TCP_WILD,
- EFX_FILTER_RX_UDP_FULL,
- EFX_FILTER_RX_UDP_WILD,
- EFX_FILTER_RX_MAC_FULL = 4,
- EFX_FILTER_RX_MAC_WILD,
- EFX_FILTER_TYPE_COUNT,
+ EFX_FILTER_TCP_FULL = 0,
+ EFX_FILTER_TCP_WILD,
+ EFX_FILTER_UDP_FULL,
+ EFX_FILTER_UDP_WILD,
+ EFX_FILTER_MAC_FULL = 4,
+ EFX_FILTER_MAC_WILD,
+ EFX_FILTER_TYPE_COUNT, /* number of specific types */
+ EFX_FILTER_UNSPEC = 0xf,
};
/**
@@ -63,13 +59,13 @@ enum efx_filter_priority {
* @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override
* any IP filter that matches the same packet. By default, IP
* filters take precedence.
- *
- * Currently, no flags are defined for TX filters.
+ * @EFX_FILTER_FLAG_RX: Filter is for RX
*/
enum efx_filter_flags {
EFX_FILTER_FLAG_RX_RSS = 0x01,
EFX_FILTER_FLAG_RX_SCATTER = 0x02,
EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04,
+ EFX_FILTER_FLAG_RX = 0x08,
};
/**
@@ -91,99 +87,26 @@ struct efx_filter_spec {
u32 data[3];
};
-/**
- * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match
- * @spec: Specification to initialise
- * @shost: Source host address (host byte order)
- * @sport: Source port (host byte order)
- * @dhost: Destination host address (host byte order)
- * @dport: Destination port (host byte order)
- */
-static inline void
-efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec,
- u32 shost, u16 sport, u32 dhost, u16 dport)
-{
- spec->type = EFX_FILTER_RX_TCP_FULL;
- spec->data[0] = sport | shost << 16;
- spec->data[1] = dport << 16 | shost >> 16;
- spec->data[2] = dhost;
-}
-
-/**
- * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match
- * @spec: Specification to initialise
- * @dhost: Destination host address (host byte order)
- * @dport: Destination port (host byte order)
- */
-static inline void
-efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
-{
- spec->type = EFX_FILTER_RX_TCP_WILD;
- spec->data[0] = 0;
- spec->data[1] = dport << 16;
- spec->data[2] = dhost;
-}
-
-/**
- * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match
- * @spec: Specification to initialise
- * @shost: Source host address (host byte order)
- * @sport: Source port (host byte order)
- * @dhost: Destination host address (host byte order)
- * @dport: Destination port (host byte order)
- */
-static inline void
-efx_filter_set_rx_udp_full(struct efx_filter_spec *spec,
- u32 shost, u16 sport, u32 dhost, u16 dport)
-{
- spec->type = EFX_FILTER_RX_UDP_FULL;
- spec->data[0] = sport | shost << 16;
- spec->data[1] = dport << 16 | shost >> 16;
- spec->data[2] = dhost;
-}
-
-/**
- * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match
- * @spec: Specification to initialise
- * @dhost: Destination host address (host byte order)
- * @dport: Destination port (host byte order)
- */
-static inline void
-efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
+static inline void efx_filter_init_rx(struct efx_filter_spec *spec,
+ enum efx_filter_priority priority,
+ enum efx_filter_flags flags,
+ unsigned rxq_id)
{
- spec->type = EFX_FILTER_RX_UDP_WILD;
- spec->data[0] = dport;
- spec->data[1] = 0;
- spec->data[2] = dhost;
+ spec->type = EFX_FILTER_UNSPEC;
+ spec->priority = priority;
+ spec->flags = EFX_FILTER_FLAG_RX | flags;
+ spec->dmaq_id = rxq_id;
}
-/**
- * efx_filter_set_rx_mac_full - specify RX filter with MAC full match
- * @spec: Specification to initialise
- * @vid: VLAN ID
- * @addr: Destination MAC address
- */
-static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec,
- u16 vid, const u8 *addr)
-{
- spec->type = EFX_FILTER_RX_MAC_FULL;
- spec->data[0] = vid;
- spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
- spec->data[2] = addr[0] << 8 | addr[1];
-}
-
-/**
- * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match
- * @spec: Specification to initialise
- * @addr: Destination MAC address
- */
-static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec,
- const u8 *addr)
-{
- spec->type = EFX_FILTER_RX_MAC_WILD;
- spec->data[0] = 0;
- spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
- spec->data[2] = addr[0] << 8 | addr[1];
-}
+extern int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
+ __be32 host, __be16 port);
+extern int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
+ __be32 host, __be16 port,
+ __be32 rhost, __be16 rport);
+extern int efx_filter_set_eth_local(struct efx_filter_spec *spec,
+ u16 vid, const u8 *addr);
+enum {
+ EFX_FILTER_VID_UNSPEC = 0xffff,
+};
#endif /* EFX_FILTER_H */
diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h
index 85a99fe87437..6da4ae20a039 100644
--- a/drivers/net/sfc/io.h
+++ b/drivers/net/sfc/io.h
@@ -22,28 +22,39 @@
*
* Notes on locking strategy:
*
- * Most NIC registers require 16-byte (or 8-byte, for SRAM) atomic writes
- * which necessitates locking.
- * Under normal operation few writes to NIC registers are made and these
- * registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and TX_DESC_UPD_REG) are special
- * cased to allow 4-byte (hence lockless) accesses.
+ * Most CSRs are 128-bit (oword) and therefore cannot be read or
+ * written atomically. Access from the host is buffered by the Bus
+ * Interface Unit (BIU). Whenever the host reads from the lowest
+ * address of such a register, or from the address of a different such
+ * register, the BIU latches the register's value. Subsequent reads
+ * from higher addresses of the same register will read the latched
+ * value. Whenever the host writes part of such a register, the BIU
+ * collects the written value and does not write to the underlying
+ * register until all 4 dwords have been written. A similar buffering
+ * scheme applies to host access to the NIC's 64-bit SRAM.
*
- * It *is* safe to write to these 4-byte registers in the middle of an
- * access to an 8-byte or 16-byte register. We therefore use a
- * spinlock to protect accesses to the larger registers, but no locks
- * for the 4-byte registers.
+ * Access to different CSRs and 64-bit SRAM words must be serialised,
+ * since interleaved access can result in lost writes or lost
+ * information from read-to-clear fields. We use efx_nic::biu_lock
+ * for this. (We could use separate locks for read and write, but
+ * this is not normally a performance bottleneck.)
*
- * A write barrier is needed to ensure that DW3 is written after DW0/1/2
- * due to the way the 16byte registers are "collected" in the BIU.
+ * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are
+ * 128-bit but are special-cased in the BIU to avoid the need for
+ * locking in the host:
*
- * We also lock when carrying out reads, to ensure consistency of the
- * data (made possible since the BIU reads all 128 bits into a cache).
- * Reads are very rare, so this isn't a significant performance
- * impact. (Most data transferred from NIC to host is DMAed directly
- * into host memory).
- *
- * I/O BAR access uses locks for both reads and writes (but is only provided
- * for testing purposes).
+ * - They are write-only.
+ * - The semantics of writing to these registers are such that
+ * replacing the low 96 bits with zero does not affect functionality.
+ * - If the host writes to the last dword address of such a register
+ * (i.e. the high 32 bits) the underlying register will always be
+ * written. If the collector does not hold values for the low 96
+ * bits of the register, they will be written as zero. Writing to
+ * the last qword does not have this effect and must not be done.
+ * - If the host writes to the address of any other part of such a
+ * register while the collector already holds values for some other
+ * register, the write is discarded and the collector maintains its
+ * current state.
*/
#if BITS_PER_LONG == 64
@@ -72,7 +83,7 @@ static inline __le32 _efx_readd(struct efx_nic *efx, unsigned int reg)
return (__force __le32)__raw_readl(efx->membase + reg);
}
-/* Writes to a normal 16-byte Efx register, locking as appropriate. */
+/* Write a normal 128-bit CSR, locking as appropriate. */
static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value,
unsigned int reg)
{
@@ -85,21 +96,18 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value,
spin_lock_irqsave(&efx->biu_lock, flags);
#ifdef EFX_USE_QWORD_IO
_efx_writeq(efx, value->u64[0], reg + 0);
- wmb();
_efx_writeq(efx, value->u64[1], reg + 8);
#else
_efx_writed(efx, value->u32[0], reg + 0);
_efx_writed(efx, value->u32[1], reg + 4);
_efx_writed(efx, value->u32[2], reg + 8);
- wmb();
_efx_writed(efx, value->u32[3], reg + 12);
#endif
mmiowb();
spin_unlock_irqrestore(&efx->biu_lock, flags);
}
-/* Write an 8-byte NIC SRAM entry through the supplied mapping,
- * locking as appropriate. */
+/* Write 64-bit SRAM through the supplied mapping, locking as appropriate. */
static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase,
efx_qword_t *value, unsigned int index)
{
@@ -115,36 +123,25 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase,
__raw_writeq((__force u64)value->u64[0], membase + addr);
#else
__raw_writel((__force u32)value->u32[0], membase + addr);
- wmb();
__raw_writel((__force u32)value->u32[1], membase + addr + 4);
#endif
mmiowb();
spin_unlock_irqrestore(&efx->biu_lock, flags);
}
-/* Write dword to NIC register that allows partial writes
- *
- * Some registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and
- * TX_DESC_UPD_REG) can be written to as a single dword. This allows
- * for lockless writes.
- */
+/* Write a 32-bit CSR or the last dword of a special 128-bit CSR */
static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value,
unsigned int reg)
{
netif_vdbg(efx, hw, efx->net_dev,
- "writing partial register %x with "EFX_DWORD_FMT"\n",
+ "writing register %x with "EFX_DWORD_FMT"\n",
reg, EFX_DWORD_VAL(*value));
/* No lock required */
_efx_writed(efx, value->u32[0], reg);
}
-/* Read from a NIC register
- *
- * This reads an entire 16-byte register in one go, locking as
- * appropriate. It is essential to read the first dword first, as this
- * prompts the NIC to load the current value into the shadow register.
- */
+/* Read a 128-bit CSR, locking as appropriate. */
static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value,
unsigned int reg)
{
@@ -152,7 +149,6 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value,
spin_lock_irqsave(&efx->biu_lock, flags);
value->u32[0] = _efx_readd(efx, reg + 0);
- rmb();
value->u32[1] = _efx_readd(efx, reg + 4);
value->u32[2] = _efx_readd(efx, reg + 8);
value->u32[3] = _efx_readd(efx, reg + 12);
@@ -163,8 +159,7 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value,
EFX_OWORD_VAL(*value));
}
-/* Read an 8-byte SRAM entry through supplied mapping,
- * locking as appropriate. */
+/* Read 64-bit SRAM through the supplied mapping, locking as appropriate. */
static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase,
efx_qword_t *value, unsigned int index)
{
@@ -176,7 +171,6 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase,
value->u64[0] = (__force __le64)__raw_readq(membase + addr);
#else
value->u32[0] = (__force __le32)__raw_readl(membase + addr);
- rmb();
value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4);
#endif
spin_unlock_irqrestore(&efx->biu_lock, flags);
@@ -186,7 +180,7 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase,
addr, EFX_QWORD_VAL(*value));
}
-/* Read dword from register that allows partial writes (sic) */
+/* Read a 32-bit CSR or SRAM */
static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value,
unsigned int reg)
{
@@ -196,28 +190,28 @@ static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value,
reg, EFX_DWORD_VAL(*value));
}
-/* Write to a register forming part of a table */
+/* Write a 128-bit CSR forming part of a table */
static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value,
unsigned int reg, unsigned int index)
{
efx_writeo(efx, value, reg + index * sizeof(efx_oword_t));
}
-/* Read to a register forming part of a table */
+/* Read a 128-bit CSR forming part of a table */
static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
unsigned int reg, unsigned int index)
{
efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
}
-/* Write to a dword register forming part of a table */
+/* Write a 32-bit CSR forming part of a table, or 32-bit SRAM */
static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value,
unsigned int reg, unsigned int index)
{
efx_writed(efx, value, reg + index * sizeof(efx_oword_t));
}
-/* Read from a dword register forming part of a table */
+/* Read a 32-bit CSR forming part of a table, or 32-bit SRAM */
static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value,
unsigned int reg, unsigned int index)
{
@@ -231,29 +225,54 @@ static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value,
#define EFX_PAGED_REG(page, reg) \
((page) * EFX_PAGE_BLOCK_SIZE + (reg))
-/* As for efx_writeo(), but for a page-mapped register. */
-static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
- unsigned int reg, unsigned int page)
+/* Write the whole of RX_DESC_UPD or TX_DESC_UPD */
+static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
+ unsigned int reg, unsigned int page)
{
- efx_writeo(efx, value, EFX_PAGED_REG(page, reg));
-}
+ reg = EFX_PAGED_REG(page, reg);
-/* As for efx_writed(), but for a page-mapped register. */
-static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value,
- unsigned int reg, unsigned int page)
+ netif_vdbg(efx, hw, efx->net_dev,
+ "writing register %x with " EFX_OWORD_FMT "\n", reg,
+ EFX_OWORD_VAL(*value));
+
+#ifdef EFX_USE_QWORD_IO
+ _efx_writeq(efx, value->u64[0], reg + 0);
+#else
+ _efx_writed(efx, value->u32[0], reg + 0);
+ _efx_writed(efx, value->u32[1], reg + 4);
+#endif
+ _efx_writed(efx, value->u32[2], reg + 8);
+ _efx_writed(efx, value->u32[3], reg + 12);
+}
+#define efx_writeo_page(efx, value, reg, page) \
+ _efx_writeo_page(efx, value, \
+ reg + \
+ BUILD_BUG_ON_ZERO((reg) != 0x830 && (reg) != 0xa10), \
+ page)
+
+/* Write a page-mapped 32-bit CSR (EVQ_RPTR or the high bits of
+ * RX_DESC_UPD or TX_DESC_UPD)
+ */
+static inline void _efx_writed_page(struct efx_nic *efx, efx_dword_t *value,
+ unsigned int reg, unsigned int page)
{
efx_writed(efx, value, EFX_PAGED_REG(page, reg));
}
-
-/* Write dword to page-mapped register with an extra lock.
- *
- * As for efx_writed_page(), but for a register that suffers from
- * SFC bug 3181. Take out a lock so the BIU collector cannot be
- * confused. */
-static inline void efx_writed_page_locked(struct efx_nic *efx,
- efx_dword_t *value,
- unsigned int reg,
- unsigned int page)
+#define efx_writed_page(efx, value, reg, page) \
+ _efx_writed_page(efx, value, \
+ reg + \
+ BUILD_BUG_ON_ZERO((reg) != 0x400 && (reg) != 0x83c \
+ && (reg) != 0xa1c), \
+ page)
+
+/* Write TIMER_COMMAND. This is a page-mapped 32-bit CSR, but a bug
+ * in the BIU means that writes to TIMER_COMMAND[0] invalidate the
+ * collector register.
+ */
+static inline void _efx_writed_page_locked(struct efx_nic *efx,
+ efx_dword_t *value,
+ unsigned int reg,
+ unsigned int page)
{
unsigned long flags __attribute__ ((unused));
@@ -265,5 +284,9 @@ static inline void efx_writed_page_locked(struct efx_nic *efx,
efx_writed(efx, value, EFX_PAGED_REG(page, reg));
}
}
+#define efx_writed_page_locked(efx, value, reg, page) \
+ _efx_writed_page_locked(efx, value, \
+ reg + BUILD_BUG_ON_ZERO((reg) != 0x420), \
+ page)
#endif /* EFX_IO_H */
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c
index 12cf910c2ce7..b716e827b291 100644
--- a/drivers/net/sfc/mcdi.c
+++ b/drivers/net/sfc/mcdi.c
@@ -381,7 +381,7 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
-rc);
efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
} else
- netif_err(efx, hw, efx->net_dev,
+ netif_dbg(efx, hw, efx->net_dev,
"MC command 0x%x inlen %d failed rc=%d\n",
cmd, (int)inlen, -rc);
}
@@ -463,6 +463,7 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
if (mcdi->mode == MCDI_MODE_EVENTS) {
mcdi->resprc = rc;
mcdi->resplen = 0;
+ ++mcdi->credits;
}
} else
/* Nobody was waiting for an MCDI request, so trigger a reset */
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index c992742446b1..0e97eed663c6 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -16,7 +16,6 @@
#include "phy.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
-#include "mdio_10g.h"
#include "nic.h"
#include "selftest.h"
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 98d946020429..56b0266b441f 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,7 +15,6 @@
#include "net_driver.h"
#include "mdio_10g.h"
#include "workarounds.h"
-#include "nic.h"
unsigned efx_mdio_id_oui(u32 id)
{
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index 02e54b4f701f..d38627448c22 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -321,14 +321,15 @@ static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
struct efx_mtd *efx_mtd = mtd->priv;
const struct efx_spi_device *spi = efx_mtd->spi;
struct efx_nic *efx = efx_mtd->efx;
+ struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
- rc = mutex_lock_interruptible(&efx->spi_lock);
+ rc = mutex_lock_interruptible(&nic_data->spi_lock);
if (rc)
return rc;
rc = falcon_spi_read(efx, spi, part->offset + start, len,
retlen, buffer);
- mutex_unlock(&efx->spi_lock);
+ mutex_unlock(&nic_data->spi_lock);
return rc;
}
@@ -337,13 +338,14 @@ static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
struct efx_mtd *efx_mtd = mtd->priv;
struct efx_nic *efx = efx_mtd->efx;
+ struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
- rc = mutex_lock_interruptible(&efx->spi_lock);
+ rc = mutex_lock_interruptible(&nic_data->spi_lock);
if (rc)
return rc;
rc = efx_spi_erase(part, part->offset + start, len);
- mutex_unlock(&efx->spi_lock);
+ mutex_unlock(&nic_data->spi_lock);
return rc;
}
@@ -354,14 +356,15 @@ static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
struct efx_mtd *efx_mtd = mtd->priv;
const struct efx_spi_device *spi = efx_mtd->spi;
struct efx_nic *efx = efx_mtd->efx;
+ struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
- rc = mutex_lock_interruptible(&efx->spi_lock);
+ rc = mutex_lock_interruptible(&nic_data->spi_lock);
if (rc)
return rc;
rc = falcon_spi_write(efx, spi, part->offset + start, len,
retlen, buffer);
- mutex_unlock(&efx->spi_lock);
+ mutex_unlock(&nic_data->spi_lock);
return rc;
}
@@ -370,11 +373,12 @@ static int falcon_mtd_sync(struct mtd_info *mtd)
struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
struct efx_mtd *efx_mtd = mtd->priv;
struct efx_nic *efx = efx_mtd->efx;
+ struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
- mutex_lock(&efx->spi_lock);
+ mutex_lock(&nic_data->spi_lock);
rc = efx_spi_slow_wait(part, true);
- mutex_unlock(&efx->spi_lock);
+ mutex_unlock(&nic_data->spi_lock);
return rc;
}
@@ -387,35 +391,67 @@ static struct efx_mtd_ops falcon_mtd_ops = {
static int falcon_mtd_probe(struct efx_nic *efx)
{
- struct efx_spi_device *spi = efx->spi_flash;
+ struct falcon_nic_data *nic_data = efx->nic_data;
+ struct efx_spi_device *spi;
struct efx_mtd *efx_mtd;
- int rc;
+ int rc = -ENODEV;
ASSERT_RTNL();
- if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
- return -ENODEV;
-
- efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
- GFP_KERNEL);
- if (!efx_mtd)
- return -ENOMEM;
-
- efx_mtd->spi = spi;
- efx_mtd->name = "flash";
- efx_mtd->ops = &falcon_mtd_ops;
+ spi = &nic_data->spi_flash;
+ if (efx_spi_present(spi) && spi->size > FALCON_FLASH_BOOTCODE_START) {
+ efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
+ GFP_KERNEL);
+ if (!efx_mtd)
+ return -ENOMEM;
+
+ efx_mtd->spi = spi;
+ efx_mtd->name = "flash";
+ efx_mtd->ops = &falcon_mtd_ops;
+
+ efx_mtd->n_parts = 1;
+ efx_mtd->part[0].mtd.type = MTD_NORFLASH;
+ efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH;
+ efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
+ efx_mtd->part[0].mtd.erasesize = spi->erase_size;
+ efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START;
+ efx_mtd->part[0].type_name = "sfc_flash_bootrom";
+
+ rc = efx_mtd_probe_device(efx, efx_mtd);
+ if (rc) {
+ kfree(efx_mtd);
+ return rc;
+ }
+ }
- efx_mtd->n_parts = 1;
- efx_mtd->part[0].mtd.type = MTD_NORFLASH;
- efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH;
- efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
- efx_mtd->part[0].mtd.erasesize = spi->erase_size;
- efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START;
- efx_mtd->part[0].type_name = "sfc_flash_bootrom";
+ spi = &nic_data->spi_eeprom;
+ if (efx_spi_present(spi) && spi->size > EFX_EEPROM_BOOTCONFIG_START) {
+ efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
+ GFP_KERNEL);
+ if (!efx_mtd)
+ return -ENOMEM;
+
+ efx_mtd->spi = spi;
+ efx_mtd->name = "EEPROM";
+ efx_mtd->ops = &falcon_mtd_ops;
+
+ efx_mtd->n_parts = 1;
+ efx_mtd->part[0].mtd.type = MTD_RAM;
+ efx_mtd->part[0].mtd.flags = MTD_CAP_RAM;
+ efx_mtd->part[0].mtd.size =
+ min(spi->size, EFX_EEPROM_BOOTCONFIG_END) -
+ EFX_EEPROM_BOOTCONFIG_START;
+ efx_mtd->part[0].mtd.erasesize = spi->erase_size;
+ efx_mtd->part[0].offset = EFX_EEPROM_BOOTCONFIG_START;
+ efx_mtd->part[0].type_name = "sfc_bootconfig";
+
+ rc = efx_mtd_probe_device(efx, efx_mtd);
+ if (rc) {
+ kfree(efx_mtd);
+ return rc;
+ }
+ }
- rc = efx_mtd_probe_device(efx, efx_mtd);
- if (rc)
- kfree(efx_mtd);
return rc;
}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 0a7e26d73b52..bdce66ddf93a 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -136,14 +136,19 @@ struct efx_tx_buffer {
* @efx: The associated Efx NIC
* @queue: DMA queue number
* @channel: The associated channel
+ * @core_txq: The networking core TX queue structure
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
* @ptr_mask: The size of the ring minus 1.
* @flushed: Used when handling queue flushing
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
- * @stopped: Stopped count.
- * Set if this TX queue is currently stopping its port.
+ * @old_write_count: The value of @write_count when last checked.
+ * This is here for performance reasons. The xmit path will
+ * only get the up-to-date value of @write_count if this
+ * variable indicates that the queue is empty. This is to
+ * avoid cache-line ping-pong between the xmit path and the
+ * completion path.
* @insert_count: Current insert pointer
* This is the number of buffers that have been added to the
* software ring.
@@ -163,13 +168,17 @@ struct efx_tx_buffer {
* @tso_long_headers: Number of packets with headers too long for standard
* blocks
* @tso_packets: Number of packets via the TSO xmit path
+ * @pushes: Number of times the TX push feature has been used
+ * @empty_read_count: If the completion path has seen the queue as empty
+ * and the transmission path has not yet checked this, the value of
+ * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0.
*/
struct efx_tx_queue {
/* Members which don't change on the fast path */
struct efx_nic *efx ____cacheline_aligned_in_smp;
unsigned queue;
struct efx_channel *channel;
- struct efx_nic *nic;
+ struct netdev_queue *core_txq;
struct efx_tx_buffer *buffer;
struct efx_special_buffer txd;
unsigned int ptr_mask;
@@ -177,7 +186,7 @@ struct efx_tx_queue {
/* Members used mainly on the completion path */
unsigned int read_count ____cacheline_aligned_in_smp;
- int stopped;
+ unsigned int old_write_count;
/* Members used only on the xmit path */
unsigned int insert_count ____cacheline_aligned_in_smp;
@@ -187,6 +196,11 @@ struct efx_tx_queue {
unsigned int tso_bursts;
unsigned int tso_long_headers;
unsigned int tso_packets;
+ unsigned int pushes;
+
+ /* Members shared between paths and sometimes updated */
+ unsigned int empty_read_count ____cacheline_aligned_in_smp;
+#define EFX_EMPTY_COUNT_VALID 0x80000000
};
/**
@@ -305,7 +319,6 @@ enum efx_rx_alloc_method {
* @irq_moderation: IRQ moderation value (in hardware ticks)
* @napi_dev: Net device used with NAPI
* @napi_str: NAPI control structure
- * @reset_work: Scheduled reset work thread
* @work_pending: Is work pending via NAPI?
* @eventq: Event queue buffer
* @eventq_mask: Event queue pointer mask
@@ -326,8 +339,6 @@ enum efx_rx_alloc_method {
* @n_rx_overlength: Count of RX_OVERLENGTH errors
* @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun
* @rx_queue: RX queue for this channel
- * @tx_stop_count: Core TX queue stop count
- * @tx_stop_lock: Core TX queue stop lock
* @tx_queue: TX queues for this channel
*/
struct efx_channel {
@@ -366,10 +377,6 @@ struct efx_channel {
bool rx_pkt_csummed;
struct efx_rx_queue rx_queue;
-
- atomic_t tx_stop_count;
- spinlock_t tx_stop_lock;
-
struct efx_tx_queue tx_queue[2];
};
@@ -621,14 +628,13 @@ struct efx_filter_state;
* @pci_dev: The PCI device
* @type: Controller type attributes
* @legacy_irq: IRQ number
+ * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
* @workqueue: Workqueue for port reconfigures and the HW monitor.
* Work items do not hold and must not acquire RTNL.
* @workqueue_name: Name of workqueue
* @reset_work: Scheduled reset workitem
- * @monitor_work: Hardware monitor workitem
* @membase_phys: Memory BAR value as physical address
* @membase: Memory BAR value
- * @biu_lock: BIU (bus interface unit) lock
* @interrupt_mode: Interrupt mode
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
* @irq_rx_moderation: IRQ moderation time for RX event queues
@@ -647,23 +653,14 @@ struct efx_filter_state;
* @n_tx_channels: Number of channels used for TX
* @rx_buffer_len: RX buffer length
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer
+ * @rx_hash_key: Toeplitz hash key for RSS
* @rx_indir_table: Indirection table for RSS
* @int_error_count: Number of internal errors seen recently
* @int_error_expire: Time at which error count will be expired
* @irq_status: Interrupt status buffer
- * @last_irq_cpu: Last CPU to handle interrupt.
- * This register is written with the SMP processor ID whenever an
- * interrupt is handled. It is used by efx_nic_test_interrupt()
- * to verify that an interrupt has occurred.
* @irq_zero_count: Number of legacy IRQs seen with queue flags == 0
* @fatal_irq_level: IRQ level (bit number) used for serious errors
- * @spi_flash: SPI flash device
- * This field will be %NULL if no flash device is present (or for Siena).
- * @spi_eeprom: SPI EEPROM device
- * This field will be %NULL if no EEPROM device is present (or for Siena).
- * @spi_lock: SPI bus lock
* @mtd_list: List of MTDs attached to the NIC
- * @n_rx_nodesc_drop_cnt: RX no descriptor drop count
* @nic_data: Hardware dependant state
* @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
* @port_inhibited, efx_monitor() and efx_reconfigure_port()
@@ -676,21 +673,14 @@ struct efx_filter_state;
* @port_initialized: Port initialized?
* @net_dev: Operating system network device. Consider holding the rtnl lock
* @rx_checksum_enabled: RX checksumming enabled
- * @mac_stats: MAC statistics. These include all statistics the MACs
- * can provide. Generic code converts these into a standard
- * &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
- * @stats_lock: Statistics update lock. Serialises statistics fetches
* @mac_op: MAC interface
- * @mac_address: Permanent MAC address
* @phy_type: PHY type
- * @mdio_lock: MDIO lock
* @phy_op: PHY interface
* @phy_data: PHY private data (including PHY-specific stats)
* @mdio: PHY MDIO interface
* @mdio_bus: PHY MDIO bus ID (only used by Siena)
* @phy_mode: PHY operating mode. Serialised by @mac_lock.
- * @xmac_poll_required: XMAC link state needs polling
* @link_advertising: Autonegotiation advertising flags
* @link_state: Current state of the link
* @n_link_state_changes: Number of times the link has changed state
@@ -701,21 +691,34 @@ struct efx_filter_state;
* @loopback_mode: Loopback status
* @loopback_modes: Supported loopback mode bitmask
* @loopback_selftest: Offline self-test private state
+ * @monitor_work: Hardware monitor workitem
+ * @biu_lock: BIU (bus interface unit) lock
+ * @last_irq_cpu: Last CPU to handle interrupt.
+ * This register is written with the SMP processor ID whenever an
+ * interrupt is handled. It is used by efx_nic_test_interrupt()
+ * to verify that an interrupt has occurred.
+ * @n_rx_nodesc_drop_cnt: RX no descriptor drop count
+ * @mac_stats: MAC statistics. These include all statistics the MACs
+ * can provide. Generic code converts these into a standard
+ * &struct net_device_stats.
+ * @stats_lock: Statistics update lock. Serialises statistics fetches
*
* This is stored in the private area of the &struct net_device.
*/
struct efx_nic {
+ /* The following fields should be written very rarely */
+
char name[IFNAMSIZ];
struct pci_dev *pci_dev;
const struct efx_nic_type *type;
int legacy_irq;
+ bool legacy_irq_enabled;
struct workqueue_struct *workqueue;
char workqueue_name[16];
struct work_struct reset_work;
- struct delayed_work monitor_work;
resource_size_t membase_phys;
void __iomem *membase;
- spinlock_t biu_lock;
+
enum efx_int_mode interrupt_mode;
bool irq_rx_adaptive;
unsigned int irq_rx_moderation;
@@ -742,19 +745,13 @@ struct efx_nic {
unsigned long int_error_expire;
struct efx_buffer irq_status;
- volatile signed int last_irq_cpu;
unsigned irq_zero_count;
unsigned fatal_irq_level;
- struct efx_spi_device *spi_flash;
- struct efx_spi_device *spi_eeprom;
- struct mutex spi_lock;
#ifdef CONFIG_SFC_MTD
struct list_head mtd_list;
#endif
- unsigned n_rx_nodesc_drop_cnt;
-
void *nic_data;
struct mutex mac_lock;
@@ -766,22 +763,17 @@ struct efx_nic {
struct net_device *net_dev;
bool rx_checksum_enabled;
- struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
- spinlock_t stats_lock;
struct efx_mac_operations *mac_op;
- unsigned char mac_address[ETH_ALEN];
unsigned int phy_type;
- struct mutex mdio_lock;
struct efx_phy_operations *phy_op;
void *phy_data;
struct mdio_if_info mdio;
unsigned int mdio_bus;
enum efx_phy_mode phy_mode;
- bool xmac_poll_required;
u32 link_advertising;
struct efx_link_state link_state;
unsigned int n_link_state_changes;
@@ -797,6 +789,15 @@ struct efx_nic {
void *loopback_selftest;
struct efx_filter_state *filter_state;
+
+ /* The following fields may be written more often */
+
+ struct delayed_work monitor_work ____cacheline_aligned_in_smp;
+ spinlock_t biu_lock;
+ volatile signed int last_irq_cpu;
+ unsigned n_rx_nodesc_drop_cnt;
+ struct efx_mac_stats mac_stats;
+ spinlock_t stats_lock;
};
static inline int efx_dev_registered(struct efx_nic *efx)
@@ -829,6 +830,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* be called while the controller is uninitialised.
* @probe_port: Probe the MAC and PHY
* @remove_port: Free resources allocated by probe_port()
+ * @handle_global_event: Handle a "global" event (may be %NULL)
* @prepare_flush: Prepare the hardware for flushing the DMA queues
* @update_stats: Update statistics not provided by event handling
* @start_stats: Start the regular fetching of statistics
@@ -873,6 +875,7 @@ struct efx_nic_type {
int (*reset)(struct efx_nic *efx, enum reset_type method);
int (*probe_port)(struct efx_nic *efx);
void (*remove_port)(struct efx_nic *efx);
+ bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *);
void (*prepare_flush)(struct efx_nic *efx);
void (*update_stats)(struct efx_nic *efx);
void (*start_stats)(struct efx_nic *efx);
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 41c36b9a4244..da386599ab68 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -362,6 +362,35 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue)
FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue);
}
+/* Write pointer and first descriptor for TX descriptor ring */
+static inline void efx_push_tx_desc(struct efx_tx_queue *tx_queue,
+ const efx_qword_t *txd)
+{
+ unsigned write_ptr;
+ efx_oword_t reg;
+
+ BUILD_BUG_ON(FRF_AZ_TX_DESC_LBN != 0);
+ BUILD_BUG_ON(FR_AA_TX_DESC_UPD_KER != FR_BZ_TX_DESC_UPD_P0);
+
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
+ EFX_POPULATE_OWORD_2(reg, FRF_AZ_TX_DESC_PUSH_CMD, true,
+ FRF_AZ_TX_DESC_WPTR, write_ptr);
+ reg.qword[0] = *txd;
+ efx_writeo_page(tx_queue->efx, &reg,
+ FR_BZ_TX_DESC_UPD_P0, tx_queue->queue);
+}
+
+static inline bool
+efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count)
+{
+ unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count);
+
+ if (empty_read_count == 0)
+ return false;
+
+ tx_queue->empty_read_count = 0;
+ return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
+}
/* For each entry inserted into the software descriptor ring, create a
* descriptor in the hardware TX descriptor ring (in host memory), and
@@ -373,6 +402,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
struct efx_tx_buffer *buffer;
efx_qword_t *txd;
unsigned write_ptr;
+ unsigned old_write_count = tx_queue->write_count;
BUG_ON(tx_queue->write_count == tx_queue->insert_count);
@@ -391,7 +421,15 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
} while (tx_queue->write_count != tx_queue->insert_count);
wmb(); /* Ensure descriptors are written before they are fetched */
- efx_notify_tx_desc(tx_queue);
+
+ if (efx_may_push_tx_desc(tx_queue, old_write_count)) {
+ txd = efx_tx_desc(tx_queue,
+ old_write_count & tx_queue->ptr_mask);
+ efx_push_tx_desc(tx_queue, txd);
+ ++tx_queue->pushes;
+ } else {
+ efx_notify_tx_desc(tx_queue);
+ }
}
/* Allocate hardware resources for a TX queue */
@@ -894,46 +932,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
channel->channel, EFX_QWORD_VAL(*event));
}
-/* Global events are basically PHY events */
-static void
-efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
-{
- struct efx_nic *efx = channel->efx;
- bool handled = false;
-
- if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
- EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
- EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) {
- /* Ignored */
- handled = true;
- }
-
- if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) &&
- EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
- efx->xmac_poll_required = true;
- handled = true;
- }
-
- if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
- EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
- EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
- netif_err(efx, rx_err, efx->net_dev,
- "channel %d seen global RX_RESET event. Resetting.\n",
- channel->channel);
-
- atomic_inc(&efx->rx_reset);
- efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
- RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
- handled = true;
- }
-
- if (!handled)
- netif_err(efx, hw, efx->net_dev,
- "channel %d unknown global event "
- EFX_QWORD_FMT "\n", channel->channel,
- EFX_QWORD_VAL(*event));
-}
-
static void
efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
{
@@ -1050,15 +1048,17 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
case FSE_AZ_EV_CODE_DRV_GEN_EV:
efx_handle_generated_event(channel, &event);
break;
- case FSE_AZ_EV_CODE_GLOBAL_EV:
- efx_handle_global_event(channel, &event);
- break;
case FSE_AZ_EV_CODE_DRIVER_EV:
efx_handle_driver_event(channel, &event);
break;
case FSE_CZ_EV_CODE_MCDI_EV:
efx_mcdi_process_event(channel, &event);
break;
+ case FSE_AZ_EV_CODE_GLOBAL_EV:
+ if (efx->type->handle_global_event &&
+ efx->type->handle_global_event(channel, &event))
+ break;
+ /* else fall through */
default:
netif_err(channel->efx, hw, channel->efx->net_dev,
"channel %d unknown event type %d (data "
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
u32 queues;
int syserr;
+ /* Could this be ours? If interrupts are disabled then the
+ * channel state may not be valid.
+ */
+ if (!efx->legacy_irq_enabled)
+ return result;
+
/* Read the ISR which also ACKs the interrupts */
efx_readd(efx, &reg, FR_BZ_INT_ISR0);
queues = EFX_EXTRACT_DWORD(reg, 0, 31);
@@ -1664,7 +1670,7 @@ void efx_nic_init_common(struct efx_nic *efx)
EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe);
EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1);
EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
- EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0);
+ EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 1);
EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1);
/* Enable SW_EV to inherit in char driver - assume harmless here */
EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1);
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h
index 0438dc98722d..eb0586925b51 100644
--- a/drivers/net/sfc/nic.h
+++ b/drivers/net/sfc/nic.h
@@ -15,6 +15,7 @@
#include "net_driver.h"
#include "efx.h"
#include "mcdi.h"
+#include "spi.h"
/*
* Falcon hardware control
@@ -113,6 +114,11 @@ struct falcon_board {
* @stats_pending: Is there a pending DMA of MAC statistics.
* @stats_timer: A timer for regularly fetching MAC statistics.
* @stats_dma_done: Pointer to the flag which indicates DMA completion.
+ * @spi_flash: SPI flash device
+ * @spi_eeprom: SPI EEPROM device
+ * @spi_lock: SPI bus lock
+ * @mdio_lock: MDIO bus lock
+ * @xmac_poll_required: XMAC link state needs polling
*/
struct falcon_nic_data {
struct pci_dev *pci_dev2;
@@ -121,6 +127,11 @@ struct falcon_nic_data {
bool stats_pending;
struct timer_list stats_timer;
u32 *stats_dma_done;
+ struct efx_spi_device spi_flash;
+ struct efx_spi_device spi_eeprom;
+ struct mutex spi_lock;
+ struct mutex mdio_lock;
+ bool xmac_poll_required;
};
static inline struct falcon_board *falcon_board(struct efx_nic *efx)
@@ -135,7 +146,6 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
* @fw_build: Firmware build number
* @mcdi: Management-Controller-to-Driver Interface
* @wol_filter_id: Wake-on-LAN packet filter id
- * @ipv6_rss_key: Toeplitz hash key for IPv6 RSS
*/
struct siena_nic_data {
u64 fw_version;
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 68813d1d85f3..ea3ae0089315 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -41,6 +41,8 @@
#define PCS_UC_STATUS_LBN 0
#define PCS_UC_STATUS_WIDTH 8
#define PCS_UC_STATUS_FW_SAVE 0x20
+#define PMA_PMD_MODE_REG 0xc301
+#define PMA_PMD_RXIN_SEL_LBN 6
#define PMA_PMD_FTX_CTRL2_REG 0xc309
#define PMA_PMD_FTX_STATIC_LBN 13
#define PMA_PMD_VEND1_REG 0xc001
@@ -282,6 +284,10 @@ static int qt2025c_select_phy_mode(struct efx_nic *efx)
* slow) reload of the firmware image (the microcontroller's code
* memory is not affected by the microcontroller reset). */
efx_mdio_write(efx, 1, 0xc317, 0x00ff);
+ /* PMA/PMD loopback sets RXIN to inverse polarity and the firmware
+ * restart doesn't reset it. We need to do that ourselves. */
+ efx_mdio_set_flag(efx, 1, PMA_PMD_MODE_REG,
+ 1 << PMA_PMD_RXIN_SEL_LBN, false);
efx_mdio_write(efx, 1, 0xc300, 0x0002);
msleep(20);
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 6d0959b5158e..3925fd621177 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -37,7 +37,7 @@
* This driver supports two methods for allocating and using RX buffers:
* each RX buffer may be backed by an skb or by an order-n page.
*
- * When LRO is in use then the second method has a lower overhead,
+ * When GRO is in use then the second method has a lower overhead,
* since we don't have to allocate then free skbs on reassembled frames.
*
* Values:
@@ -50,25 +50,25 @@
*
* - Since pushing and popping descriptors are separated by the rx_queue
* size, so the watermarks should be ~rxd_size.
- * - The performance win by using page-based allocation for LRO is less
- * than the performance hit of using page-based allocation of non-LRO,
+ * - The performance win by using page-based allocation for GRO is less
+ * than the performance hit of using page-based allocation of non-GRO,
* so the watermarks should reflect this.
*
* Per channel we maintain a single variable, updated by each channel:
*
- * rx_alloc_level += (lro_performed ? RX_ALLOC_FACTOR_LRO :
+ * rx_alloc_level += (gro_performed ? RX_ALLOC_FACTOR_GRO :
* RX_ALLOC_FACTOR_SKB)
* Per NAPI poll interval, we constrain rx_alloc_level to 0..MAX (which
* limits the hysteresis), and update the allocation strategy:
*
- * rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_LRO ?
+ * rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_GRO ?
* RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB)
*/
static int rx_alloc_method = RX_ALLOC_METHOD_AUTO;
-#define RX_ALLOC_LEVEL_LRO 0x2000
+#define RX_ALLOC_LEVEL_GRO 0x2000
#define RX_ALLOC_LEVEL_MAX 0x3000
-#define RX_ALLOC_FACTOR_LRO 1
+#define RX_ALLOC_FACTOR_GRO 1
#define RX_ALLOC_FACTOR_SKB (-2)
/* This is the percentage fill level below which new RX descriptors
@@ -441,19 +441,19 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
efx_rx_queue_channel(rx_queue)->n_rx_overlength++;
}
-/* Pass a received packet up through the generic LRO stack
+/* Pass a received packet up through the generic GRO stack
*
* Handles driverlink veto, and passes the fragment up via
- * the appropriate LRO method
+ * the appropriate GRO method
*/
-static void efx_rx_packet_lro(struct efx_channel *channel,
+static void efx_rx_packet_gro(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf,
bool checksummed)
{
struct napi_struct *napi = &channel->napi_str;
gro_result_t gro_result;
- /* Pass the skb/page into the LRO engine */
+ /* Pass the skb/page into the GRO engine */
if (rx_buf->page) {
struct efx_nic *efx = channel->efx;
struct page *page = rx_buf->page;
@@ -499,7 +499,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
if (gro_result == GRO_NORMAL) {
channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
} else if (gro_result != GRO_DROP) {
- channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
+ channel->rx_alloc_level += RX_ALLOC_FACTOR_GRO;
channel->irq_mod_score += 2;
}
}
@@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel,
}
if (likely(checksummed || rx_buf->page)) {
- efx_rx_packet_lro(channel, rx_buf, checksummed);
+ efx_rx_packet_gro(channel, rx_buf, checksummed);
return;
}
@@ -628,7 +628,7 @@ void efx_rx_strategy(struct efx_channel *channel)
{
enum efx_rx_alloc_method method = rx_alloc_method;
- /* Only makes sense to use page based allocation if LRO is enabled */
+ /* Only makes sense to use page based allocation if GRO is enabled */
if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
method = RX_ALLOC_METHOD_SKB;
} else if (method == RX_ALLOC_METHOD_AUTO) {
@@ -639,7 +639,7 @@ void efx_rx_strategy(struct efx_channel *channel)
channel->rx_alloc_level = RX_ALLOC_LEVEL_MAX;
/* Decide on the allocation method */
- method = ((channel->rx_alloc_level > RX_ALLOC_LEVEL_LRO) ?
+ method = ((channel->rx_alloc_level > RX_ALLOC_LEVEL_GRO) ?
RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB);
}
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 45236f58a258..bf8456176443 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -194,13 +194,7 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
static int siena_probe_nvconfig(struct efx_nic *efx)
{
- int rc;
-
- rc = efx_mcdi_get_board_cfg(efx, efx->mac_address, NULL);
- if (rc)
- return rc;
-
- return 0;
+ return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL);
}
static int siena_probe_nic(struct efx_nic *efx)
@@ -562,7 +556,7 @@ static int siena_set_wol(struct efx_nic *efx, u32 type)
if (nic_data->wol_filter_id != -1)
efx_mcdi_wol_filter_remove(efx,
nic_data->wol_filter_id);
- rc = efx_mcdi_wol_filter_set_magic(efx, efx->mac_address,
+ rc = efx_mcdi_wol_filter_set_magic(efx, efx->net_dev->dev_addr,
&nic_data->wol_filter_id);
if (rc)
goto fail;
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h
index 8bf4fce0813a..879b7f6bde3d 100644
--- a/drivers/net/sfc/spi.h
+++ b/drivers/net/sfc/spi.h
@@ -61,6 +61,11 @@ struct efx_spi_device {
unsigned int block_size;
};
+static inline bool efx_spi_present(const struct efx_spi_device *spi)
+{
+ return spi->size != 0;
+}
+
int falcon_spi_cmd(struct efx_nic *efx,
const struct efx_spi_device *spi, unsigned int command,
int address, const void* in, void *out, size_t len);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 1bc6c48c96ee..f102912eba91 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -15,9 +15,7 @@
#include "mdio_10g.h"
#include "nic.h"
#include "phy.h"
-#include "regs.h"
#include "workarounds.h"
-#include "selftest.h"
/* We expect these MMDs to be in the package. */
#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 11726989fe2d..2f5e9da657bf 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -30,50 +30,6 @@
*/
#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u)
-/* We need to be able to nest calls to netif_tx_stop_queue(), partly
- * because of the 2 hardware queues associated with each core queue,
- * but also so that we can inhibit TX for reasons other than a full
- * hardware queue. */
-void efx_stop_queue(struct efx_channel *channel)
-{
- struct efx_nic *efx = channel->efx;
- struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
-
- if (!tx_queue)
- return;
-
- spin_lock_bh(&channel->tx_stop_lock);
- netif_vdbg(efx, tx_queued, efx->net_dev, "stop TX queue\n");
-
- atomic_inc(&channel->tx_stop_count);
- netif_tx_stop_queue(
- netdev_get_tx_queue(efx->net_dev,
- tx_queue->queue / EFX_TXQ_TYPES));
-
- spin_unlock_bh(&channel->tx_stop_lock);
-}
-
-/* Decrement core TX queue stop count and wake it if the count is 0 */
-void efx_wake_queue(struct efx_channel *channel)
-{
- struct efx_nic *efx = channel->efx;
- struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
-
- if (!tx_queue)
- return;
-
- local_bh_disable();
- if (atomic_dec_and_lock(&channel->tx_stop_count,
- &channel->tx_stop_lock)) {
- netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n");
- netif_tx_wake_queue(
- netdev_get_tx_queue(efx->net_dev,
- tx_queue->queue / EFX_TXQ_TYPES));
- spin_unlock(&channel->tx_stop_lock);
- }
- local_bh_enable();
-}
-
static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
struct efx_tx_buffer *buffer)
{
@@ -234,21 +190,22 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
* checked. Update the xmit path's
* copy of read_count.
*/
- ++tx_queue->stopped;
+ netif_tx_stop_queue(tx_queue->core_txq);
/* This memory barrier protects the
- * change of stopped from the access
+ * change of queue state from the access
* of read_count. */
smp_mb();
tx_queue->old_read_count =
- *(volatile unsigned *)
- &tx_queue->read_count;
+ ACCESS_ONCE(tx_queue->read_count);
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
q_space = efx->txq_entries - 1 - fill_level;
- if (unlikely(q_space-- <= 0))
- goto stop;
+ if (unlikely(q_space-- <= 0)) {
+ rc = NETDEV_TX_BUSY;
+ goto unwind;
+ }
smp_mb();
- --tx_queue->stopped;
+ netif_tx_start_queue(tx_queue->core_txq);
}
insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
@@ -308,13 +265,6 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
/* Mark the packet as transmitted, and free the SKB ourselves */
dev_kfree_skb_any(skb);
- goto unwind;
-
- stop:
- rc = NETDEV_TX_BUSY;
-
- if (tx_queue->stopped == 1)
- efx_stop_queue(tx_queue->channel);
unwind:
/* Work backwards until we hit the original insert pointer value */
@@ -407,22 +357,25 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
efx_dequeue_buffers(tx_queue, index);
/* See if we need to restart the netif queue. This barrier
- * separates the update of read_count from the test of
- * stopped. */
+ * separates the update of read_count from the test of the
+ * queue state. */
smp_mb();
- if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
+ if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) &&
+ likely(efx->port_enabled)) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
+ netif_tx_wake_queue(tx_queue->core_txq);
+ }
+ }
- /* Do this under netif_tx_lock(), to avoid racing
- * with efx_xmit(). */
- netif_tx_lock(efx->net_dev);
- if (tx_queue->stopped) {
- tx_queue->stopped = 0;
- efx_wake_queue(tx_queue->channel);
- }
- netif_tx_unlock(efx->net_dev);
+ /* Check whether the hardware queue is now empty */
+ if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) {
+ tx_queue->old_write_count = ACCESS_ONCE(tx_queue->write_count);
+ if (tx_queue->read_count == tx_queue->old_write_count) {
+ smp_mb();
+ tx_queue->empty_read_count =
+ tx_queue->read_count | EFX_EMPTY_COUNT_VALID;
}
}
}
@@ -470,9 +423,10 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
tx_queue->insert_count = 0;
tx_queue->write_count = 0;
+ tx_queue->old_write_count = 0;
tx_queue->read_count = 0;
tx_queue->old_read_count = 0;
- BUG_ON(tx_queue->stopped);
+ tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID;
/* Set up TX descriptor ring */
efx_nic_init_tx(tx_queue);
@@ -508,12 +462,6 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue)
/* Free up TSO header cache */
efx_fini_tso(tx_queue);
-
- /* Release queue's stop on port, if any */
- if (tx_queue->stopped) {
- tx_queue->stopped = 0;
- efx_wake_queue(tx_queue->channel);
- }
}
void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
@@ -755,12 +703,12 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
* since the xmit path last checked. Update
* the xmit path's copy of read_count.
*/
- ++tx_queue->stopped;
+ netif_tx_stop_queue(tx_queue->core_txq);
/* This memory barrier protects the change of
- * stopped from the access of read_count. */
+ * queue state from the access of read_count. */
smp_mb();
tx_queue->old_read_count =
- *(volatile unsigned *)&tx_queue->read_count;
+ ACCESS_ONCE(tx_queue->read_count);
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
q_space = efx->txq_entries - 1 - fill_level;
@@ -769,7 +717,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
return 1;
}
smp_mb();
- --tx_queue->stopped;
+ netif_tx_start_queue(tx_queue->core_txq);
}
insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
@@ -1109,8 +1057,10 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
while (1) {
rc = tso_fill_packet_with_fragment(tx_queue, skb, &state);
- if (unlikely(rc))
- goto stop;
+ if (unlikely(rc)) {
+ rc2 = NETDEV_TX_BUSY;
+ goto unwind;
+ }
/* Move onto the next fragment? */
if (state.in_len == 0) {
@@ -1139,14 +1089,6 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
netif_err(efx, tx_err, efx->net_dev,
"Out of memory for TSO headers, or PCI mapping error\n");
dev_kfree_skb_any(skb);
- goto unwind;
-
- stop:
- rc2 = NETDEV_TX_BUSY;
-
- /* Stop the queue if it wasn't stopped before. */
- if (tx_queue->stopped == 1)
- efx_stop_queue(tx_queue->channel);
unwind:
/* Free the DMA mapping we were in the process of writing out */
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 50259dfec583..819c1750e2ab 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -45,9 +45,9 @@ static void sh_eth_set_duplex(struct net_device *ndev)
u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
else /* Half */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
@@ -57,10 +57,10 @@ static void sh_eth_set_rate(struct net_device *ndev)
switch (mdp->speed) {
case 10: /* 10BASE */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
break;
case 100:/* 100BASE */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
break;
default:
break;
@@ -96,9 +96,9 @@ static void sh_eth_set_duplex(struct net_device *ndev)
u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
else /* Half */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
@@ -108,10 +108,10 @@ static void sh_eth_set_rate(struct net_device *ndev)
switch (mdp->speed) {
case 10: /* 10BASE */
- ctrl_outl(0, ioaddr + RTRATE);
+ writel(0, ioaddr + RTRATE);
break;
case 100:/* 100BASE */
- ctrl_outl(1, ioaddr + RTRATE);
+ writel(1, ioaddr + RTRATE);
break;
default:
break;
@@ -143,7 +143,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
static void sh_eth_chip_reset(struct net_device *ndev)
{
/* reset device */
- ctrl_outl(ARSTR_ARSTR, ARSTR);
+ writel(ARSTR_ARSTR, ARSTR);
mdelay(1);
}
@@ -152,10 +152,10 @@ static void sh_eth_reset(struct net_device *ndev)
u32 ioaddr = ndev->base_addr;
int cnt = 100;
- ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
- ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ writel(EDSR_ENALL, ioaddr + EDSR);
+ writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
while (cnt > 0) {
- if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
+ if (!(readl(ioaddr + EDMR) & 0x3))
break;
mdelay(1);
cnt--;
@@ -164,14 +164,14 @@ static void sh_eth_reset(struct net_device *ndev)
printk(KERN_ERR "Device reset fail\n");
/* Table Init */
- ctrl_outl(0x0, ioaddr + TDLAR);
- ctrl_outl(0x0, ioaddr + TDFAR);
- ctrl_outl(0x0, ioaddr + TDFXR);
- ctrl_outl(0x0, ioaddr + TDFFR);
- ctrl_outl(0x0, ioaddr + RDLAR);
- ctrl_outl(0x0, ioaddr + RDFAR);
- ctrl_outl(0x0, ioaddr + RDFXR);
- ctrl_outl(0x0, ioaddr + RDFFR);
+ writel(0x0, ioaddr + TDLAR);
+ writel(0x0, ioaddr + TDFAR);
+ writel(0x0, ioaddr + TDFXR);
+ writel(0x0, ioaddr + TDFFR);
+ writel(0x0, ioaddr + RDLAR);
+ writel(0x0, ioaddr + RDFAR);
+ writel(0x0, ioaddr + RDFXR);
+ writel(0x0, ioaddr + RDFFR);
}
static void sh_eth_set_duplex(struct net_device *ndev)
@@ -180,9 +180,9 @@ static void sh_eth_set_duplex(struct net_device *ndev)
u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
else /* Half */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
@@ -192,13 +192,13 @@ static void sh_eth_set_rate(struct net_device *ndev)
switch (mdp->speed) {
case 10: /* 10BASE */
- ctrl_outl(GECMR_10, ioaddr + GECMR);
+ writel(GECMR_10, ioaddr + GECMR);
break;
case 100:/* 100BASE */
- ctrl_outl(GECMR_100, ioaddr + GECMR);
+ writel(GECMR_100, ioaddr + GECMR);
break;
case 1000: /* 1000BASE */
- ctrl_outl(GECMR_1000, ioaddr + GECMR);
+ writel(GECMR_1000, ioaddr + GECMR);
break;
default:
break;
@@ -283,9 +283,9 @@ static void sh_eth_reset(struct net_device *ndev)
{
u32 ioaddr = ndev->base_addr;
- ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
mdelay(3);
- ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+ writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
}
#endif
@@ -336,10 +336,10 @@ static void update_mac_address(struct net_device *ndev)
{
u32 ioaddr = ndev->base_addr;
- ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
+ writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
(ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]),
ioaddr + MAHR);
- ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
+ writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
ioaddr + MALR);
}
@@ -358,12 +358,12 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)
if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
memcpy(ndev->dev_addr, mac, 6);
} else {
- ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
- ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
- ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
- ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
- ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
- ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+ ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24);
+ ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF;
+ ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF;
+ ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF);
+ ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF;
+ ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF);
}
}
@@ -379,19 +379,19 @@ struct bb_info {
/* PHY bit set */
static void bb_set(u32 addr, u32 msk)
{
- ctrl_outl(ctrl_inl(addr) | msk, addr);
+ writel(readl(addr) | msk, addr);
}
/* PHY bit clear */
static void bb_clr(u32 addr, u32 msk)
{
- ctrl_outl((ctrl_inl(addr) & ~msk), addr);
+ writel((readl(addr) & ~msk), addr);
}
/* PHY bit read */
static int bb_read(u32 addr, u32 msk)
{
- return (ctrl_inl(addr) & msk) != 0;
+ return (readl(addr) & msk) != 0;
}
/* Data I/O pin control */
@@ -506,9 +506,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
/* Rx descriptor address set */
if (i == 0) {
- ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR);
+ writel(mdp->rx_desc_dma, ioaddr + RDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR);
+ writel(mdp->rx_desc_dma, ioaddr + RDFAR);
#endif
}
}
@@ -528,9 +528,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
txdesc->buffer_length = 0;
if (i == 0) {
/* Tx descriptor address set */
- ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR);
+ writel(mdp->tx_desc_dma, ioaddr + TDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR);
+ writel(mdp->tx_desc_dma, ioaddr + TDFAR);
#endif
}
}
@@ -623,71 +623,71 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Descriptor format */
sh_eth_ring_format(ndev);
if (mdp->cd->rpadir)
- ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR);
+ writel(mdp->cd->rpadir_value, ioaddr + RPADIR);
/* all sh_eth int mask */
- ctrl_outl(0, ioaddr + EESIPR);
+ writel(0, ioaddr + EESIPR);
#if defined(__LITTLE_ENDIAN__)
if (mdp->cd->hw_swap)
- ctrl_outl(EDMR_EL, ioaddr + EDMR);
+ writel(EDMR_EL, ioaddr + EDMR);
else
#endif
- ctrl_outl(0, ioaddr + EDMR);
+ writel(0, ioaddr + EDMR);
/* FIFO size set */
- ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR);
- ctrl_outl(0, ioaddr + TFTR);
+ writel(mdp->cd->fdr_value, ioaddr + FDR);
+ writel(0, ioaddr + TFTR);
/* Frame recv control */
- ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR);
+ writel(mdp->cd->rmcr_value, ioaddr + RMCR);
rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
- ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
+ writel(rx_int_var | tx_int_var, ioaddr + TRSCER);
if (mdp->cd->bculr)
- ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */
+ writel(0x800, ioaddr + BCULR); /* Burst sycle set */
- ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR);
+ writel(mdp->cd->fcftr_value, ioaddr + FCFTR);
if (!mdp->cd->no_trimd)
- ctrl_outl(0, ioaddr + TRIMD);
+ writel(0, ioaddr + TRIMD);
/* Recv frame limit set register */
- ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
+ writel(RFLR_VALUE, ioaddr + RFLR);
- ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
- ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR);
+ writel(readl(ioaddr + EESR), ioaddr + EESR);
+ writel(mdp->cd->eesipr_value, ioaddr + EESIPR);
/* PAUSE Prohibition */
- val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) |
+ val = (readl(ioaddr + ECMR) & ECMR_DM) |
ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
- ctrl_outl(val, ioaddr + ECMR);
+ writel(val, ioaddr + ECMR);
if (mdp->cd->set_rate)
mdp->cd->set_rate(ndev);
/* E-MAC Status Register clear */
- ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR);
+ writel(mdp->cd->ecsr_value, ioaddr + ECSR);
/* E-MAC Interrupt Enable register */
- ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
+ writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
/* Set MAC address */
update_mac_address(ndev);
/* mask reset */
if (mdp->cd->apr)
- ctrl_outl(APR_AP, ioaddr + APR);
+ writel(APR_AP, ioaddr + APR);
if (mdp->cd->mpr)
- ctrl_outl(MPR_MP, ioaddr + MPR);
+ writel(MPR_MP, ioaddr + MPR);
if (mdp->cd->tpauser)
- ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
+ writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
/* Setting the Rx mode will start the Rx process. */
- ctrl_outl(EDRRR_R, ioaddr + EDRRR);
+ writel(EDRRR_R, ioaddr + EDRRR);
netif_start_queue(ndev);
@@ -811,8 +811,8 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R))
- ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
+ if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R))
+ writel(EDRRR_R, ndev->base_addr + EDRRR);
return 0;
}
@@ -827,8 +827,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
u32 mask;
if (intr_status & EESR_ECI) {
- felic_stat = ctrl_inl(ioaddr + ECSR);
- ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */
+ felic_stat = readl(ioaddr + ECSR);
+ writel(felic_stat, ioaddr + ECSR); /* clear int */
if (felic_stat & ECSR_ICD)
mdp->stats.tx_carrier_errors++;
if (felic_stat & ECSR_LCHNG) {
@@ -839,25 +839,25 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
else
link_stat = PHY_ST_LINK;
} else {
- link_stat = (ctrl_inl(ioaddr + PSR));
+ link_stat = (readl(ioaddr + PSR));
if (mdp->ether_link_active_low)
link_stat = ~link_stat;
}
if (!(link_stat & PHY_ST_LINK)) {
/* Link Down : disable tx and rx */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) &
+ writel(readl(ioaddr + ECMR) &
~(ECMR_RE | ECMR_TE), ioaddr + ECMR);
} else {
/* Link Up */
- ctrl_outl(ctrl_inl(ioaddr + EESIPR) &
+ writel(readl(ioaddr + EESIPR) &
~DMAC_M_ECI, ioaddr + EESIPR);
/*clear int */
- ctrl_outl(ctrl_inl(ioaddr + ECSR),
+ writel(readl(ioaddr + ECSR),
ioaddr + ECSR);
- ctrl_outl(ctrl_inl(ioaddr + EESIPR) |
+ writel(readl(ioaddr + EESIPR) |
DMAC_M_ECI, ioaddr + EESIPR);
/* enable tx and rx */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) |
+ writel(readl(ioaddr + ECMR) |
(ECMR_RE | ECMR_TE), ioaddr + ECMR);
}
}
@@ -888,8 +888,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
/* Receive Descriptor Empty int */
mdp->stats.rx_over_errors++;
- if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R)
- ctrl_outl(EDRRR_R, ioaddr + EDRRR);
+ if (readl(ioaddr + EDRRR) ^ EDRRR_R)
+ writel(EDRRR_R, ioaddr + EDRRR);
dev_err(&ndev->dev, "Receive Descriptor Empty\n");
}
if (intr_status & EESR_RFE) {
@@ -903,7 +903,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
mask &= ~EESR_ADE;
if (intr_status & mask) {
/* Tx error */
- u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
+ u32 edtrr = readl(ndev->base_addr + EDTRR);
/* dmesg */
dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
intr_status, mdp->cur_tx);
@@ -915,7 +915,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
/* SH7712 BUG */
if (edtrr ^ EDTRR_TRNS) {
/* tx dma start */
- ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
}
/* wakeup */
netif_wake_queue(ndev);
@@ -934,12 +934,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
spin_lock(&mdp->lock);
/* Get interrpt stat */
- intr_status = ctrl_inl(ioaddr + EESR);
+ intr_status = readl(ioaddr + EESR);
/* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
cd->tx_check | cd->eesr_err_check)) {
- ctrl_outl(intr_status, ioaddr + EESR);
+ writel(intr_status, ioaddr + EESR);
ret = IRQ_HANDLED;
} else
goto other_irq;
@@ -1000,7 +1000,7 @@ static void sh_eth_adjust_link(struct net_device *ndev)
mdp->cd->set_rate(ndev);
}
if (mdp->link == PHY_DOWN) {
- ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
+ writel((readl(ioaddr + ECMR) & ~ECMR_TXF)
| ECMR_DM, ioaddr + ECMR);
new_state = 1;
mdp->link = phydev->link;
@@ -1125,7 +1125,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* worning message out. */
printk(KERN_WARNING "%s: transmit timed out, status %8.8x,"
- " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR));
+ " resetting...\n", ndev->name, (int)readl(ioaddr + EESR));
/* tx_errors count up */
mdp->stats.tx_errors++;
@@ -1196,8 +1196,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
mdp->cur_tx++;
- if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
- ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
+ writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
return NETDEV_TX_OK;
}
@@ -1212,11 +1212,11 @@ static int sh_eth_close(struct net_device *ndev)
netif_stop_queue(ndev);
/* Disable interrupts by clearing the interrupt mask. */
- ctrl_outl(0x0000, ioaddr + EESIPR);
+ writel(0x0000, ioaddr + EESIPR);
/* Stop the chip's Tx and Rx processes. */
- ctrl_outl(0, ioaddr + EDTRR);
- ctrl_outl(0, ioaddr + EDRRR);
+ writel(0, ioaddr + EDTRR);
+ writel(0, ioaddr + EDRRR);
/* PHY Disconnect */
if (mdp->phydev) {
@@ -1251,20 +1251,20 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
pm_runtime_get_sync(&mdp->pdev->dev);
- mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
- ctrl_outl(0, ioaddr + TROCR); /* (write clear) */
- mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
- ctrl_outl(0, ioaddr + CDCR); /* (write clear) */
- mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR);
- ctrl_outl(0, ioaddr + LCCR); /* (write clear) */
+ mdp->stats.tx_dropped += readl(ioaddr + TROCR);
+ writel(0, ioaddr + TROCR); /* (write clear) */
+ mdp->stats.collisions += readl(ioaddr + CDCR);
+ writel(0, ioaddr + CDCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR);
+ writel(0, ioaddr + LCCR); /* (write clear) */
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */
- ctrl_outl(0, ioaddr + CERCR); /* (write clear) */
- mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */
- ctrl_outl(0, ioaddr + CEECR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */
+ writel(0, ioaddr + CERCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */
+ writel(0, ioaddr + CEECR); /* (write clear) */
#else
- mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
- ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR);
+ writel(0, ioaddr + CNDCR); /* (write clear) */
#endif
pm_runtime_put_sync(&mdp->pdev->dev);
@@ -1295,11 +1295,11 @@ static void sh_eth_set_multicast_list(struct net_device *ndev)
if (ndev->flags & IFF_PROMISC) {
/* Set promiscuous. */
- ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
+ writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
ioaddr + ECMR);
} else {
/* Normal, unicast/broadcast-only mode. */
- ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
+ writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
ioaddr + ECMR);
}
}
@@ -1307,30 +1307,30 @@ static void sh_eth_set_multicast_list(struct net_device *ndev)
/* SuperH's TSU register init function */
static void sh_eth_tsu_init(u32 ioaddr)
{
- ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */
- ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */
- ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */
- ctrl_outl(0xc, ioaddr + TSU_BSYSL0);
- ctrl_outl(0xc, ioaddr + TSU_BSYSL1);
- ctrl_outl(0, ioaddr + TSU_PRISL0);
- ctrl_outl(0, ioaddr + TSU_PRISL1);
- ctrl_outl(0, ioaddr + TSU_FWSL0);
- ctrl_outl(0, ioaddr + TSU_FWSL1);
- ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
+ writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */
+ writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */
+ writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */
+ writel(0xc, ioaddr + TSU_BSYSL0);
+ writel(0xc, ioaddr + TSU_BSYSL1);
+ writel(0, ioaddr + TSU_PRISL0);
+ writel(0, ioaddr + TSU_PRISL1);
+ writel(0, ioaddr + TSU_FWSL0);
+ writel(0, ioaddr + TSU_FWSL1);
+ writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */
- ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */
+ writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */
+ writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */
#else
- ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */
- ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */
+ writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */
+ writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */
#endif
- ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */
- ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */
- ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */
- ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */
- ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */
- ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
- ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
+ writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */
+ writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */
+ writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */
+ writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */
+ writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */
+ writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
+ writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
}
#endif /* SH_ETH_HAS_TSU */
@@ -1552,7 +1552,6 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
sh_mdio_release(ndev);
unregister_netdev(ndev);
- flush_scheduled_work();
pm_runtime_disable(&pdev->dev);
free_netdev(ndev);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 8b47763958f2..efa64221eede 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index a5d6a6bd0c1a..3406ed870917 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1915,9 +1915,10 @@ err_release_board:
static void __devexit sis190_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct sis190_private *tp = netdev_priv(dev);
sis190_mii_remove(dev);
- flush_scheduled_work();
+ cancel_work_sync(&tp->phy_task);
unregister_netdev(dev);
sis190_release_board(pdev);
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 0a66fed52e8e..16c62659cdd9 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -412,7 +412,7 @@ static int skfp_driver_init(struct net_device *dev)
bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
bp->SharedMemSize,
&bp->SharedMemDMA);
- if (!bp->SharedMemSize) {
+ if (!bp->SharedMemAddr) {
printk("could not allocate mem for ");
printk("hardware module: %ld byte\n",
bp->SharedMemSize);
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index 2d9941c045bc..1e1bd0c201c8 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1263,7 +1263,7 @@ void smt_set_timestamp(struct s_smc *smc, u_char *p)
static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy)
{
int i ;
- u_char *map ;
+ const u_char *map ;
u_short in ;
u_short out ;
@@ -1271,7 +1271,7 @@ static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy)
* MIB para 101b (fddiSMTConnectionPolicy) coding
* is different from 0005 coding
*/
- static u_char ansi_weirdness[16] = {
+ static const u_char ansi_weirdness[16] = {
0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15
} ;
SMTSETPARA(policy,SMT_P_POLICY) ;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 220e0398f1d5..42daf98ba736 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1191,7 +1191,7 @@ static void genesis_init(struct skge_hw *hw)
static void genesis_reset(struct skge_hw *hw, int port)
{
- const u8 zero[8] = { 0 };
+ static const u8 zero[8] = { 0 };
u32 reg;
skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
@@ -1557,7 +1557,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
int i;
u32 r;
- const u8 zero[6] = { 0 };
+ static const u8 zero[6] = { 0 };
for (i = 0; i < 10; i++) {
skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
@@ -2764,7 +2764,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
td->dma_hi = map >> 32;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- const int offset = skb_transport_offset(skb);
+ const int offset = skb_checksum_start_offset(skb);
/* This seems backwards, but it is what the sk98lin
* does. Looks like hardware is wrong?
@@ -4012,8 +4012,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
if (!hw)
return;
- flush_scheduled_work();
-
dev1 = hw->dev[1];
if (dev1)
unregister_netdev(dev1);
@@ -4044,53 +4042,40 @@ static void __devexit skge_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+static int skge_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct skge_hw *hw = pci_get_drvdata(pdev);
- int i, err, wol = 0;
+ int i;
if (!hw)
return 0;
- err = pci_save_state(pdev);
- if (err)
- return err;
-
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
struct skge_port *skge = netdev_priv(dev);
if (netif_running(dev))
skge_down(dev);
+
if (skge->wol)
skge_wol_init(skge);
-
- wol |= skge->wol;
}
skge_write32(hw, B0_IMSK, 0);
- pci_prepare_to_sleep(pdev);
-
return 0;
}
-static int skge_resume(struct pci_dev *pdev)
+static int skge_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err;
if (!hw)
return 0;
- err = pci_back_from_sleep(pdev);
- if (err)
- goto out;
-
- err = pci_restore_state(pdev);
- if (err)
- goto out;
-
err = skge_reset(hw);
if (err)
goto out;
@@ -4111,12 +4096,19 @@ static int skge_resume(struct pci_dev *pdev)
out:
return err;
}
+
+static SIMPLE_DEV_PM_OPS(skge_pm_ops, skge_suspend, skge_resume);
+#define SKGE_PM_OPS (&skge_pm_ops)
+
+#else
+
+#define SKGE_PM_OPS NULL
#endif
static void skge_shutdown(struct pci_dev *pdev)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
- int i, wol = 0;
+ int i;
if (!hw)
return;
@@ -4127,15 +4119,10 @@ static void skge_shutdown(struct pci_dev *pdev)
if (skge->wol)
skge_wol_init(skge);
- wol |= skge->wol;
}
- if (pci_enable_wake(pdev, PCI_D3cold, wol))
- pci_enable_wake(pdev, PCI_D3hot, wol);
-
- pci_disable_device(pdev);
+ pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
pci_set_power_state(pdev, PCI_D3hot);
-
}
static struct pci_driver skge_driver = {
@@ -4143,11 +4130,8 @@ static struct pci_driver skge_driver = {
.id_table = skge_id_table,
.probe = skge_probe,
.remove = __devexit_p(skge_remove),
-#ifdef CONFIG_PM
- .suspend = skge_suspend,
- .resume = skge_resume,
-#endif
.shutdown = skge_shutdown,
+ .driver.pm = SKGE_PM_OPS,
};
static struct dmi_system_id skge_32bit_dma_boards[] = {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d6577084ce70..39996bf3b247 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1917,8 +1917,10 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
netif_printk(sky2, tx_done, KERN_DEBUG, dev,
"tx done %u\n", idx);
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
+ u64_stats_update_begin(&sky2->tx_stats.syncp);
+ ++sky2->tx_stats.packets;
+ sky2->tx_stats.bytes += skb->len;
+ u64_stats_update_end(&sky2->tx_stats.syncp);
re->skb = NULL;
dev_kfree_skb_any(skb);
@@ -2460,7 +2462,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
/* if length reported by DMA does not match PHY, packet was truncated */
if (length != count)
- goto len_error;
+ goto error;
okay:
if (length < copybreak)
@@ -2475,34 +2477,13 @@ resubmit:
return skb;
-len_error:
- /* Truncation of overlength packets
- causes PHY length to not match MAC length */
- ++dev->stats.rx_length_errors;
- if (net_ratelimit())
- netif_info(sky2, rx_err, dev,
- "rx length error: status %#x length %d\n",
- status, length);
- goto resubmit;
-
error:
++dev->stats.rx_errors;
- if (status & GMR_FS_RX_FF_OV) {
- dev->stats.rx_over_errors++;
- goto resubmit;
- }
if (net_ratelimit())
netif_info(sky2, rx_err, dev,
"rx error, status 0x%x length %d\n", status, length);
- if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
- dev->stats.rx_length_errors++;
- if (status & GMR_FS_FRAGMENT)
- dev->stats.rx_frame_errors++;
- if (status & GMR_FS_CRC_ERR)
- dev->stats.rx_crc_errors++;
-
goto resubmit;
}
@@ -2543,14 +2524,19 @@ static inline void sky2_skb_rx(const struct sky2_port *sky2,
static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
unsigned packets, unsigned bytes)
{
- if (packets) {
- struct net_device *dev = hw->dev[port];
+ struct net_device *dev = hw->dev[port];
+ struct sky2_port *sky2 = netdev_priv(dev);
- dev->stats.rx_packets += packets;
- dev->stats.rx_bytes += bytes;
- dev->last_rx = jiffies;
- sky2_rx_update(netdev_priv(dev), rxqaddr[port]);
- }
+ if (packets == 0)
+ return;
+
+ u64_stats_update_begin(&sky2->rx_stats.syncp);
+ sky2->rx_stats.packets += packets;
+ sky2->rx_stats.bytes += bytes;
+ u64_stats_update_end(&sky2->rx_stats.syncp);
+
+ dev->last_rx = jiffies;
+ sky2_rx_update(netdev_priv(dev), rxqaddr[port]);
}
static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
@@ -3398,12 +3384,24 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
+ bool enable_wakeup = false;
+ int i;
if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
!device_can_wakeup(&hw->pdev->dev))
return -EOPNOTSUPP;
sky2->wol = wol->wolopts;
+
+ for (i = 0; i < hw->ports; i++) {
+ struct net_device *dev = hw->dev[i];
+ struct sky2_port *sky2 = netdev_priv(dev);
+
+ if (sky2->wol)
+ enable_wakeup = true;
+ }
+ device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
+
return 0;
}
@@ -3614,13 +3612,11 @@ static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
unsigned port = sky2->port;
int i;
- data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
- | (u64) gma_read32(hw, port, GM_TXO_OK_LO);
- data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
- | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
+ data[0] = get_stats64(hw, port, GM_TXO_OK_LO);
+ data[1] = get_stats64(hw, port, GM_RXO_OK_LO);
for (i = 2; i < count; i++)
- data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset);
+ data[i] = get_stats32(hw, port, sky2_stats[i].offset);
}
static void sky2_set_msglevel(struct net_device *netdev, u32 value)
@@ -3738,6 +3734,51 @@ static void sky2_set_multicast(struct net_device *dev)
gma_write16(hw, port, GM_RX_CTRL, reg);
}
+static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct sky2_port *sky2 = netdev_priv(dev);
+ struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
+ unsigned int start;
+ u64 _bytes, _packets;
+
+ do {
+ start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp);
+ _bytes = sky2->rx_stats.bytes;
+ _packets = sky2->rx_stats.packets;
+ } while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start));
+
+ stats->rx_packets = _packets;
+ stats->rx_bytes = _bytes;
+
+ do {
+ start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp);
+ _bytes = sky2->tx_stats.bytes;
+ _packets = sky2->tx_stats.packets;
+ } while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start));
+
+ stats->tx_packets = _packets;
+ stats->tx_bytes = _bytes;
+
+ stats->multicast = get_stats32(hw, port, GM_RXF_MC_OK)
+ + get_stats32(hw, port, GM_RXF_BC_OK);
+
+ stats->collisions = get_stats32(hw, port, GM_TXF_COL);
+
+ stats->rx_length_errors = get_stats32(hw, port, GM_RXF_LNG_ERR);
+ stats->rx_crc_errors = get_stats32(hw, port, GM_RXF_FCS_ERR);
+ stats->rx_frame_errors = get_stats32(hw, port, GM_RXF_SHT)
+ + get_stats32(hw, port, GM_RXE_FRAG);
+ stats->rx_over_errors = get_stats32(hw, port, GM_RXE_FIFO_OV);
+
+ stats->rx_dropped = dev->stats.rx_dropped;
+ stats->rx_fifo_errors = dev->stats.rx_fifo_errors;
+ stats->tx_fifo_errors = dev->stats.tx_fifo_errors;
+
+ return stats;
+}
+
/* Can have one global because blinking is controlled by
* ethtool and that is always under RTNL mutex
*/
@@ -4512,6 +4553,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
.ndo_set_multicast_list = sky2_set_multicast,
.ndo_change_mtu = sky2_change_mtu,
.ndo_tx_timeout = sky2_tx_timeout,
+ .ndo_get_stats64 = sky2_get_stats,
#ifdef SKY2_VLAN_TAG_USED
.ndo_vlan_rx_register = sky2_vlan_rx_register,
#endif
@@ -4529,6 +4571,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
.ndo_set_multicast_list = sky2_set_multicast,
.ndo_change_mtu = sky2_change_mtu,
.ndo_tx_timeout = sky2_tx_timeout,
+ .ndo_get_stats64 = sky2_get_stats,
#ifdef SKY2_VLAN_TAG_USED
.ndo_vlan_rx_register = sky2_vlan_rx_register,
#endif
@@ -4920,10 +4963,11 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+static int sky2_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct sky2_hw *hw = pci_get_drvdata(pdev);
- int i, wol = 0;
+ int i;
if (!hw)
return 0;
@@ -4940,41 +4984,24 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
if (sky2->wol)
sky2_wol_init(sky2);
-
- wol |= sky2->wol;
}
- device_set_wakeup_enable(&pdev->dev, wol != 0);
-
sky2_power_aux(hw);
rtnl_unlock();
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
return 0;
}
#ifdef CONFIG_PM
-static int sky2_resume(struct pci_dev *pdev)
+static int sky2_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct sky2_hw *hw = pci_get_drvdata(pdev);
int err;
if (!hw)
return 0;
- err = pci_set_power_state(pdev, PCI_D0);
- if (err)
- goto out;
-
- err = pci_restore_state(pdev);
- if (err)
- goto out;
-
- pci_enable_wake(pdev, PCI_D0, 0);
-
/* Re-enable all clocks */
err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
if (err) {
@@ -4994,11 +5021,20 @@ out:
pci_disable_device(pdev);
return err;
}
+
+static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
+#define SKY2_PM_OPS (&sky2_pm_ops)
+
+#else
+
+#define SKY2_PM_OPS NULL
#endif
static void sky2_shutdown(struct pci_dev *pdev)
{
- sky2_suspend(pdev, PMSG_SUSPEND);
+ sky2_suspend(&pdev->dev);
+ pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
+ pci_set_power_state(pdev, PCI_D3hot);
}
static struct pci_driver sky2_driver = {
@@ -5006,11 +5042,8 @@ static struct pci_driver sky2_driver = {
.id_table = sky2_id_table,
.probe = sky2_probe,
.remove = __devexit_p(sky2_remove),
-#ifdef CONFIG_PM
- .suspend = sky2_suspend,
- .resume = sky2_resume,
-#endif
.shutdown = sky2_shutdown,
+ .driver.pm = SKY2_PM_OPS,
};
static int __init sky2_init_module(void)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 61891a6cacc2..80bdc404f1ea 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2200,6 +2200,12 @@ enum flow_control {
FC_BOTH = 3,
};
+struct sky2_stats {
+ struct u64_stats_sync syncp;
+ u64 packets;
+ u64 bytes;
+};
+
struct sky2_port {
struct sky2_hw *hw;
struct net_device *netdev;
@@ -2209,6 +2215,8 @@ struct sky2_port {
struct tx_ring_info *tx_ring;
struct sky2_tx_le *tx_le;
+ struct sky2_stats tx_stats;
+
u16 tx_ring_size;
u16 tx_cons; /* next le to check */
u16 tx_prod; /* next le to use */
@@ -2221,6 +2229,7 @@ struct sky2_port {
struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp;
struct sky2_rx_le *rx_le;
+ struct sky2_stats rx_stats;
u16 rx_next; /* next re to check */
u16 rx_put; /* next le index to use */
@@ -2346,6 +2355,39 @@ static inline u32 gma_read32(struct sky2_hw *hw, unsigned port, unsigned reg)
| (u32) sky2_read16(hw, base+4) << 16;
}
+static inline u64 gma_read64(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+ unsigned base = SK_GMAC_REG(port, reg);
+
+ return (u64) sky2_read16(hw, base)
+ | (u64) sky2_read16(hw, base+4) << 16
+ | (u64) sky2_read16(hw, base+8) << 32
+ | (u64) sky2_read16(hw, base+12) << 48;
+}
+
+/* There is no way to atomically read32 bit values from PHY, so retry */
+static inline u32 get_stats32(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+ u32 val;
+
+ do {
+ val = gma_read32(hw, port, reg);
+ } while (gma_read32(hw, port, reg) != val);
+
+ return val;
+}
+
+static inline u64 get_stats64(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+ u64 val;
+
+ do {
+ val = gma_read64(hw, port, reg);
+ } while (gma_read64(hw, port, reg) != val);
+
+ return val;
+}
+
static inline void gma_write16(const struct sky2_hw *hw, unsigned port, int r, u16 v)
{
sky2_write16(hw, SK_GMAC_REG(port,r), v);
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index d2dd8e6113ab..235a3c6c9f91 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -277,8 +277,12 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
{
- int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000};
- short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff};
+ static const int addr_tbl[4] = {
+ 0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000
+ };
+ static const short num_pages_tbl[4] = {
+ 0x20, 0x40, 0x80, 0xff
+ };
dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ;
num_pages = num_pages_tbl[(addr >> 4) & 3];
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 4adf12422787..a4f2bd52e546 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, };
* This SUCKS.
* We need a much better method to determine if dma_addr_t is 64-bit.
*/
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
#define netdrv_addr_t __le64
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index 79bdc2e13224..5f06c4706abe 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -20,7 +20,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
-#define DRV_MODULE_VERSION "Apr_2010"
+#define DRV_MODULE_VERSION "Nov_2010"
#include <linux/platform_device.h>
#include <linux/stmmac.h>
@@ -37,7 +37,6 @@ struct stmmac_priv {
unsigned int cur_tx;
unsigned int dirty_tx;
unsigned int dma_tx_size;
- int tx_coe;
int tx_coalesce;
struct dma_desc *dma_rx ;
@@ -48,7 +47,6 @@ struct stmmac_priv {
struct sk_buff_head rx_recycle;
struct net_device *dev;
- int is_gmac;
dma_addr_t dma_rx_phy;
unsigned int dma_rx_size;
unsigned int dma_buf_sz;
@@ -60,14 +58,11 @@ struct stmmac_priv {
struct napi_struct napi;
phy_interface_t phy_interface;
- int pbl;
- int bus_id;
int phy_addr;
int phy_mask;
int (*phy_reset) (void *priv);
- void (*fix_mac_speed) (void *priv, unsigned int speed);
- void (*bus_setup)(void __iomem *ioaddr);
- void *bsp_priv;
+ int rx_coe;
+ int no_csum_insertion;
int phy_irq;
struct phy_device *phydev;
@@ -77,47 +72,20 @@ struct stmmac_priv {
unsigned int flow_ctrl;
unsigned int pause;
struct mii_bus *mii;
- int mii_clk_csr;
u32 msg_enable;
spinlock_t lock;
int wolopts;
int wolenabled;
- int shutdown;
#ifdef CONFIG_STMMAC_TIMER
struct stmmac_timer *tm;
#endif
#ifdef STMMAC_VLAN_TAG_USED
struct vlan_group *vlgrp;
#endif
- int enh_desc;
- int rx_coe;
- int bugged_jumbo;
- int no_csum_insertion;
+ struct plat_stmmacenet_data *plat;
};
-#ifdef CONFIG_STM_DRIVERS
-#include <linux/stm/pad.h>
-static inline int stmmac_claim_resource(struct platform_device *pdev)
-{
- int ret = 0;
- struct plat_stmmacenet_data *plat_dat = pdev->dev.platform_data;
-
- /* Pad routing setup */
- if (IS_ERR(devm_stm_pad_claim(&pdev->dev, plat_dat->pad_config,
- dev_name(&pdev->dev)))) {
- printk(KERN_ERR "%s: Failed to request pads!\n", __func__);
- ret = -ENODEV;
- }
- return ret;
-}
-#else
-static inline int stmmac_claim_resource(struct platform_device *pdev)
-{
- return 0;
-}
-#endif
-
extern int stmmac_mdio_unregister(struct net_device *ndev);
extern int stmmac_mdio_register(struct net_device *ndev);
extern void stmmac_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index 6d65482e789a..fd719edc7f7c 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -94,7 +94,7 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
{
struct stmmac_priv *priv = netdev_priv(dev);
- if (!priv->is_gmac)
+ if (!priv->plat->has_gmac)
strcpy(info->driver, MAC100_ETHTOOL_NAME);
else
strcpy(info->driver, GMAC_ETHTOOL_NAME);
@@ -176,7 +176,7 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
memset(reg_space, 0x0, REG_SPACE_SIZE);
- if (!priv->is_gmac) {
+ if (!priv->plat->has_gmac) {
/* MAC registers */
for (i = 0; i < 12; i++)
reg_space[i] = readl(priv->ioaddr + (i * 4));
@@ -197,16 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
}
}
-static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
-{
- if (data)
- netdev->features |= NETIF_F_HW_CSUM;
- else
- netdev->features &= ~NETIF_F_HW_CSUM;
-
- return 0;
-}
-
static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
@@ -370,7 +360,7 @@ static struct ethtool_ops stmmac_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_rx_csum = stmmac_ethtool_get_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = stmmac_ethtool_set_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_pauseparam = stmmac_get_pauseparam,
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 06bc6034ce81..34a0af3837f9 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -186,6 +186,18 @@ static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
}
+/* On some ST platforms, some HW system configuraton registers have to be
+ * set according to the link speed negotiated.
+ */
+static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
+{
+ struct phy_device *phydev = priv->phydev;
+
+ if (likely(priv->plat->fix_mac_speed))
+ priv->plat->fix_mac_speed(priv->plat->bsp_priv,
+ phydev->speed);
+}
+
/**
* stmmac_adjust_link
* @dev: net device structure
@@ -228,15 +240,13 @@ static void stmmac_adjust_link(struct net_device *dev)
new_state = 1;
switch (phydev->speed) {
case 1000:
- if (likely(priv->is_gmac))
+ if (likely(priv->plat->has_gmac))
ctrl &= ~priv->hw->link.port;
- if (likely(priv->fix_mac_speed))
- priv->fix_mac_speed(priv->bsp_priv,
- phydev->speed);
+ stmmac_hw_fix_mac_speed(priv);
break;
case 100:
case 10:
- if (priv->is_gmac) {
+ if (priv->plat->has_gmac) {
ctrl |= priv->hw->link.port;
if (phydev->speed == SPEED_100) {
ctrl |= priv->hw->link.speed;
@@ -246,9 +256,7 @@ static void stmmac_adjust_link(struct net_device *dev)
} else {
ctrl &= ~priv->hw->link.port;
}
- if (likely(priv->fix_mac_speed))
- priv->fix_mac_speed(priv->bsp_priv,
- phydev->speed);
+ stmmac_hw_fix_mac_speed(priv);
break;
default:
if (netif_msg_link(priv))
@@ -305,7 +313,7 @@ static int stmmac_init_phy(struct net_device *dev)
return 0;
}
- snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
priv->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
@@ -552,7 +560,7 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
*/
static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
{
- if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) {
+ if (likely((priv->plat->tx_coe) && (!priv->no_csum_insertion))) {
/* In case of GMAC, SF mode has to be enabled
* to perform the TX COE. This depends on:
* 1) TX COE if actually supported
@@ -814,7 +822,7 @@ static int stmmac_open(struct net_device *dev)
init_dma_desc_rings(dev);
/* DMA initialization and SW reset */
- if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl,
+ if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
priv->dma_tx_phy,
priv->dma_rx_phy) < 0)) {
@@ -825,19 +833,17 @@ static int stmmac_open(struct net_device *dev)
/* Copy the MAC addr into the HW */
priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
/* If required, perform hw setup of the bus. */
- if (priv->bus_setup)
- priv->bus_setup(priv->ioaddr);
+ if (priv->plat->bus_setup)
+ priv->plat->bus_setup(priv->ioaddr);
/* Initialize the MAC Core */
priv->hw->mac->core_init(priv->ioaddr);
priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
if (priv->rx_coe)
pr_info("stmmac: Rx Checksum Offload Engine supported\n");
- if (priv->tx_coe)
+ if (priv->plat->tx_coe)
pr_info("\tTX Checksum insertion supported\n");
- priv->shutdown = 0;
-
/* Initialise the MMC (if present) to disable all interrupts. */
writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
@@ -943,7 +949,7 @@ static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
skb, skb->len);
segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
- if (unlikely(IS_ERR(segs)))
+ if (IS_ERR(segs))
goto sw_tso_end;
do {
@@ -1042,7 +1048,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
return stmmac_sw_tso(priv, skb);
if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
- if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion)))
+ if (unlikely((!priv->plat->tx_coe) ||
+ (priv->no_csum_insertion)))
skb_checksum_help(skb);
else
csum_insertion = 1;
@@ -1146,7 +1153,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
DMA_FROM_DEVICE);
(p + entry)->des2 = priv->rx_skbuff_dma[entry];
- if (unlikely(priv->is_gmac)) {
+ if (unlikely(priv->plat->has_gmac)) {
if (bfsize >= BUF_SIZE_8KiB)
(p + entry)->des3 =
(p + entry)->des2 + BUF_SIZE_8KiB;
@@ -1356,7 +1363,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
return -EBUSY;
}
- if (priv->is_gmac)
+ if (priv->plat->has_gmac)
max_mtu = JUMBO_LEN;
else
max_mtu = ETH_DATA_LEN;
@@ -1370,7 +1377,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
* needs to have the Tx COE disabled for oversized frames
* (due to limited buffer sizes). In this case we disable
* the TX csum insertionin the TDES and not use SF. */
- if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
+ if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
priv->no_csum_insertion = 1;
else
priv->no_csum_insertion = 0;
@@ -1390,7 +1397,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
- if (priv->is_gmac)
+ if (priv->plat->has_gmac)
/* To handle GMAC own interrupts */
priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
@@ -1487,7 +1494,8 @@ static int stmmac_probe(struct net_device *dev)
dev->netdev_ops = &stmmac_netdev_ops;
stmmac_set_ethtool_ops(dev);
- dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA);
+ dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
@@ -1509,6 +1517,8 @@ static int stmmac_probe(struct net_device *dev)
pr_warning("\tno valid MAC address;"
"please, use ifconfig or nwhwconfig!\n");
+ spin_lock_init(&priv->lock);
+
ret = register_netdev(dev);
if (ret) {
pr_err("%s: ERROR %i registering the device\n",
@@ -1518,9 +1528,7 @@ static int stmmac_probe(struct net_device *dev)
DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
- (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
-
- spin_lock_init(&priv->lock);
+ (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
return ret;
}
@@ -1536,7 +1544,7 @@ static int stmmac_mac_device_setup(struct net_device *dev)
struct mac_device_info *device;
- if (priv->is_gmac)
+ if (priv->plat->has_gmac)
device = dwmac1000_setup(priv->ioaddr);
else
device = dwmac100_setup(priv->ioaddr);
@@ -1544,7 +1552,7 @@ static int stmmac_mac_device_setup(struct net_device *dev)
if (!device)
return -ENOMEM;
- if (priv->enh_desc) {
+ if (priv->plat->enh_desc) {
device->desc = &enh_desc_ops;
pr_info("\tEnhanced descriptor structure\n");
} else
@@ -1598,7 +1606,7 @@ static int stmmac_associate_phy(struct device *dev, void *data)
plat_dat->bus_id);
/* Check that this phy is for the MAC being initialised */
- if (priv->bus_id != plat_dat->bus_id)
+ if (priv->plat->bus_id != plat_dat->bus_id)
return 0;
/* OK, this PHY is connected to the MAC.
@@ -1634,15 +1642,13 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *addr = NULL;
struct net_device *ndev = NULL;
- struct stmmac_priv *priv;
+ struct stmmac_priv *priv = NULL;
struct plat_stmmacenet_data *plat_dat;
pr_info("STMMAC driver:\n\tplatform registration... ");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto out;
- }
+ if (!res)
+ return -ENODEV;
pr_info("\tdone!\n");
if (!request_mem_region(res->start, resource_size(res),
@@ -1650,22 +1656,21 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
pr_err("%s: ERROR: memory allocation failed"
"cannot get the I/O addr 0x%x\n",
__func__, (unsigned int)res->start);
- ret = -EBUSY;
- goto out;
+ return -EBUSY;
}
addr = ioremap(res->start, resource_size(res));
if (!addr) {
pr_err("%s: ERROR: memory mapping failed\n", __func__);
ret = -ENOMEM;
- goto out;
+ goto out_release_region;
}
ndev = alloc_etherdev(sizeof(struct stmmac_priv));
if (!ndev) {
pr_err("%s: ERROR: allocating the device\n", __func__);
ret = -ENOMEM;
- goto out;
+ goto out_unmap;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -1675,21 +1680,17 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
if (ndev->irq == -ENXIO) {
pr_err("%s: ERROR: MAC IRQ configuration "
"information not found\n", __func__);
- ret = -ENODEV;
- goto out;
+ ret = -ENXIO;
+ goto out_free_ndev;
}
priv = netdev_priv(ndev);
priv->device = &(pdev->dev);
priv->dev = ndev;
plat_dat = pdev->dev.platform_data;
- priv->bus_id = plat_dat->bus_id;
- priv->pbl = plat_dat->pbl; /* TLI */
- priv->mii_clk_csr = plat_dat->clk_csr;
- priv->tx_coe = plat_dat->tx_coe;
- priv->bugged_jumbo = plat_dat->bugged_jumbo;
- priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
- priv->enh_desc = plat_dat->enh_desc;
+
+ priv->plat = plat_dat;
+
priv->ioaddr = addr;
/* PMT module is not integrated in all the MAC devices. */
@@ -1703,20 +1704,22 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
/* Set the I/O base addr */
ndev->base_addr = (unsigned long)addr;
- /* Verify embedded resource for the platform */
- ret = stmmac_claim_resource(pdev);
- if (ret < 0)
- goto out;
+ /* Custom initialisation */
+ if (priv->plat->init) {
+ ret = priv->plat->init(pdev);
+ if (unlikely(ret))
+ goto out_free_ndev;
+ }
/* MAC HW revice detection */
ret = stmmac_mac_device_setup(ndev);
if (ret < 0)
- goto out;
+ goto out_plat_exit;
/* Network Device Registration */
ret = stmmac_probe(ndev);
if (ret < 0)
- goto out;
+ goto out_plat_exit;
/* associate a PHY - it is provided by another platform bus */
if (!driver_for_each_device
@@ -1724,31 +1727,33 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
stmmac_associate_phy)) {
pr_err("No PHY device is associated with this MAC!\n");
ret = -ENODEV;
- goto out;
+ goto out_unregister;
}
- priv->fix_mac_speed = plat_dat->fix_mac_speed;
- priv->bus_setup = plat_dat->bus_setup;
- priv->bsp_priv = plat_dat->bsp_priv;
-
pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
"\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
pdev->id, ndev->irq, addr);
/* MDIO bus Registration */
- pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
+ pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
ret = stmmac_mdio_register(ndev);
if (ret < 0)
- goto out;
+ goto out_unregister;
pr_debug("registered!\n");
+ return 0;
-out:
- if (ret < 0) {
- platform_set_drvdata(pdev, NULL);
- release_mem_region(res->start, resource_size(res));
- if (addr != NULL)
- iounmap(addr);
- }
+out_unregister:
+ unregister_netdev(ndev);
+out_plat_exit:
+ if (priv->plat->exit)
+ priv->plat->exit(pdev);
+out_free_ndev:
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+out_unmap:
+ iounmap(addr);
+out_release_region:
+ release_mem_region(res->start, resource_size(res));
return ret;
}
@@ -1777,6 +1782,9 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
stmmac_mdio_unregister(ndev);
+ if (priv->plat->exit)
+ priv->plat->exit(pdev);
+
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
@@ -1790,69 +1798,54 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
+static int stmmac_suspend(struct device *dev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct stmmac_priv *priv = netdev_priv(dev);
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
int dis_ic = 0;
- if (!dev || !netif_running(dev))
+ if (!ndev || !netif_running(ndev))
return 0;
spin_lock(&priv->lock);
- if (state.event == PM_EVENT_SUSPEND) {
- netif_device_detach(dev);
- netif_stop_queue(dev);
- if (priv->phydev)
- phy_stop(priv->phydev);
+ netif_device_detach(ndev);
+ netif_stop_queue(ndev);
+ if (priv->phydev)
+ phy_stop(priv->phydev);
#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_stop();
- if (likely(priv->tm->enable))
- dis_ic = 1;
+ priv->tm->timer_stop();
+ if (likely(priv->tm->enable))
+ dis_ic = 1;
#endif
- napi_disable(&priv->napi);
-
- /* Stop TX/RX DMA */
- priv->hw->dma->stop_tx(priv->ioaddr);
- priv->hw->dma->stop_rx(priv->ioaddr);
- /* Clear the Rx/Tx descriptors */
- priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
- dis_ic);
- priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
-
- /* Enable Power down mode by programming the PMT regs */
- if (device_can_wakeup(priv->device))
- priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
- else
- stmmac_disable_mac(priv->ioaddr);
- } else {
- priv->shutdown = 1;
- /* Although this can appear slightly redundant it actually
- * makes fast the standby operation and guarantees the driver
- * working if hibernation is on media. */
- stmmac_release(dev);
- }
+ napi_disable(&priv->napi);
+
+ /* Stop TX/RX DMA */
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
+ /* Clear the Rx/Tx descriptors */
+ priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
+ dis_ic);
+ priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+
+ /* Enable Power down mode by programming the PMT regs */
+ if (device_may_wakeup(priv->device))
+ priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
+ else
+ stmmac_disable_mac(priv->ioaddr);
spin_unlock(&priv->lock);
return 0;
}
-static int stmmac_resume(struct platform_device *pdev)
+static int stmmac_resume(struct device *dev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct stmmac_priv *priv = netdev_priv(dev);
-
- if (!netif_running(dev))
- return 0;
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
- if (priv->shutdown) {
- /* Re-open the interface and re-init the MAC/DMA
- and the rings (i.e. on hibernation stage) */
- stmmac_open(dev);
+ if (!netif_running(ndev))
return 0;
- }
spin_lock(&priv->lock);
@@ -1861,10 +1854,10 @@ static int stmmac_resume(struct platform_device *pdev)
* is received. Anyway, it's better to manually clear
* this bit because it can generate problems while resuming
* from another devices (e.g. serial console). */
- if (device_can_wakeup(priv->device))
+ if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, 0);
- netif_device_attach(dev);
+ netif_device_attach(ndev);
/* Enable the MAC and DMA */
stmmac_enable_mac(priv->ioaddr);
@@ -1872,31 +1865,59 @@ static int stmmac_resume(struct platform_device *pdev)
priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_start(tmrate);
+ if (likely(priv->tm->enable))
+ priv->tm->timer_start(tmrate);
#endif
napi_enable(&priv->napi);
if (priv->phydev)
phy_start(priv->phydev);
- netif_start_queue(dev);
+ netif_start_queue(ndev);
spin_unlock(&priv->lock);
return 0;
}
-#endif
-static struct platform_driver stmmac_driver = {
- .driver = {
- .name = STMMAC_RESOURCE_NAME,
- },
- .probe = stmmac_dvr_probe,
- .remove = stmmac_dvr_remove,
-#ifdef CONFIG_PM
+static int stmmac_freeze(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ return stmmac_release(ndev);
+}
+
+static int stmmac_restore(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ return stmmac_open(ndev);
+}
+
+static const struct dev_pm_ops stmmac_pm_ops = {
.suspend = stmmac_suspend,
.resume = stmmac_resume,
-#endif
+ .freeze = stmmac_freeze,
+ .thaw = stmmac_restore,
+ .restore = stmmac_restore,
+};
+#else
+static const struct dev_pm_ops stmmac_pm_ops;
+#endif /* CONFIG_PM */
+static struct platform_driver stmmac_driver = {
+ .probe = stmmac_dvr_probe,
+ .remove = stmmac_dvr_remove,
+ .driver = {
+ .name = STMMAC_RESOURCE_NAME,
+ .owner = THIS_MODULE,
+ .pm = &stmmac_pm_ops,
+ },
};
/**
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
index d7441616357d..234b4068a1fc 100644
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -53,7 +53,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0)));
- regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2);
+ regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
writel(regValue, priv->ioaddr + mii_address);
@@ -85,7 +85,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE;
- value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2);
+ value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
/* Wait until any existing MII operation is complete */
@@ -114,7 +114,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
if (priv->phy_reset) {
pr_debug("stmmac_mdio_reset: calling phy_reset\n");
- priv->phy_reset(priv->bsp_priv);
+ priv->phy_reset(priv->plat->bsp_priv);
}
/* This is a workaround for problems with the STE101P PHY.
@@ -157,7 +157,7 @@ int stmmac_mdio_register(struct net_device *ndev)
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+ snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
new_bus->priv = ndev;
new_bus->irq = irqlist;
new_bus->phy_mask = priv->phy_mask;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 3ed2a67bd6d3..4793df843c24 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -294,6 +294,9 @@ enum alta_offsets {
/* Aliased and bogus values! */
RxStatus = 0x0c,
};
+
+#define ASIC_HI_WORD(x) ((x) + 2)
+
enum ASICCtrl_HiWord_bit {
GlobalReset = 0x0001,
RxReset = 0x0002,
@@ -431,6 +434,7 @@ static void netdev_error(struct net_device *dev, int intr_status);
static void netdev_error(struct net_device *dev, int intr_status);
static void set_rx_mode(struct net_device *dev);
static int __set_mac_addr(struct net_device *dev);
+static int sundance_set_mac_addr(struct net_device *dev, void *data);
static struct net_device_stats *get_stats(struct net_device *dev);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int netdev_close(struct net_device *dev);
@@ -464,7 +468,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_do_ioctl = netdev_ioctl,
.ndo_tx_timeout = tx_timeout,
.ndo_change_mtu = change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = sundance_set_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -1016,7 +1020,7 @@ static void init_ring(struct net_device *dev)
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2);
np->rx_skbuff[i] = skb;
if (skb == NULL)
break;
@@ -1407,7 +1411,7 @@ static void refill_rx (struct net_device *dev)
struct sk_buff *skb;
entry = np->dirty_rx % RX_RING_SIZE;
if (np->rx_skbuff[entry] == NULL) {
- skb = dev_alloc_skb(np->rx_buf_sz);
+ skb = dev_alloc_skb(np->rx_buf_sz + 2);
np->rx_skbuff[entry] = skb;
if (skb == NULL)
break; /* Better luck next round. */
@@ -1592,6 +1596,19 @@ static int __set_mac_addr(struct net_device *dev)
return 0;
}
+/* Invoked with rtnl_lock held */
+static int sundance_set_mac_addr(struct net_device *dev, void *data)
+{
+ const struct sockaddr *addr = data;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ __set_mac_addr(dev);
+
+ return 0;
+}
+
static const struct {
const char name[ETH_GSTRING_LEN];
} sundance_stats[] = {
@@ -1772,10 +1789,10 @@ static int netdev_close(struct net_device *dev)
}
iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset,
- ioaddr +ASICCtrl + 2);
+ ioaddr + ASIC_HI_WORD(ASICCtrl));
for (i = 2000; i > 0; i--) {
- if ((ioread16(ioaddr + ASICCtrl +2) & ResetBusy) == 0)
+ if ((ioread16(ioaddr + ASIC_HI_WORD(ASICCtrl)) & ResetBusy) == 0)
break;
mdelay(1);
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 4ceb3cf6a9a9..1c5408f83937 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -1004,7 +1004,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
ctrl = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- const u64 csum_start_off = skb_transport_offset(skb);
+ const u64 csum_start_off = skb_checksum_start_offset(skb);
const u64 csum_stuff_off = csum_start_off + skb->csum_offset;
ctrl = (TXDCTRL_CENAB |
@@ -2380,10 +2380,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
*/
mutex_unlock(&gp->pm_mutex);
- /* Wait for a pending reset task to complete */
- while (gp->reset_task_pending)
- yield();
- flush_scheduled_work();
+ /* Wait for the pending reset task to complete */
+ flush_work_sync(&gp->reset_task);
/* Shut the PHY down eventually and setup WOL */
gem_stop_phy(gp, gp->asleep_wol);
@@ -2928,10 +2926,8 @@ static void gem_remove_one(struct pci_dev *pdev)
/* We shouldn't need any locking here */
gem_get_cell(gp);
- /* Wait for a pending reset task to complete */
- while (gp->reset_task_pending)
- yield();
- flush_scheduled_work();
+ /* Cancel reset task */
+ cancel_work_sync(&gp->reset_task);
/* Shut the PHY down */
gem_stop_phy(gp, 0);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 5e28c414421a..55bbb9c15d96 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2266,7 +2266,7 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
tx_flags = TXFLAG_OWN;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- const u32 csum_start_off = skb_transport_offset(skb);
+ const u32 csum_start_off = skb_checksum_start_offset(skb);
const u32 csum_stuff_off = csum_start_off + skb->csum_offset;
tx_flags = (TXFLAG_OWN | TXFLAG_CSENABLE |
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 2cf84e5968b2..767e1e2b210d 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1295,17 +1295,9 @@ static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvin
strcpy(info->version, "2.02");
}
-static u32 sparc_lance_get_link(struct net_device *dev)
-{
- /* We really do not keep track of this, but this
- * is better than not reporting anything at all.
- */
- return 1;
-}
-
static const struct ethtool_ops sparc_lance_ethtool_ops = {
.get_drvinfo = sparc_lance_get_drvinfo,
- .get_link = sparc_lance_get_link,
+ .get_link = ethtool_op_get_link,
};
static const struct net_device_ops sparc_lance_ops = {
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8b3dc1eb4015..296000bf5a25 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -324,7 +324,7 @@ static int bdx_fw_load(struct bdx_priv *priv)
ENTER;
master = READ_REG(priv, regINIT_SEMAPHORE);
if (!READ_REG(priv, regINIT_STATUS) && master) {
- rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev);
+ rc = request_firmware(&fw, "tehuti/bdx.bin", &priv->pdev->dev);
if (rc)
goto out;
bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
@@ -2510,4 +2510,4 @@ module_exit(bdx_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(BDX_DRV_DESC);
-MODULE_FIRMWARE("tehuti/firmware.bin");
+MODULE_FIRMWARE("tehuti/bdx.bin");
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 30ccbb6d097a..7841a8f69998 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -32,6 +32,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
+#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/brcmphy.h>
@@ -69,10 +70,10 @@
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
-#define TG3_MIN_NUM 115
+#define TG3_MIN_NUM 116
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE "October 14, 2010"
+#define DRV_MODULE_RELDATE "December 3, 2010"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -1769,9 +1770,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
if (tp->link_config.autoneg == AUTONEG_ENABLE &&
current_link_up == 1 &&
- (tp->link_config.active_speed == SPEED_1000 ||
- (tp->link_config.active_speed == SPEED_100 &&
- tp->link_config.active_duplex == DUPLEX_FULL))) {
+ tp->link_config.active_duplex == DUPLEX_FULL &&
+ (tp->link_config.active_speed == SPEED_100 ||
+ tp->link_config.active_speed == SPEED_1000)) {
u32 eeectl;
if (tp->link_config.active_speed == SPEED_1000)
@@ -1781,7 +1782,8 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
tw32(TG3_CPMU_EEE_CTRL, eeectl);
- tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val);
+ tg3_phy_cl45_read(tp, MDIO_MMD_AN,
+ TG3_CL45_D7_EEERES_STAT, &val);
if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
@@ -2549,39 +2551,35 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
tw32(MAC_TX_BACKOFF_SEED, addr_high);
}
-static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
+static void tg3_enable_register_access(struct tg3 *tp)
{
- u32 misc_host_ctrl;
- bool device_should_wake, do_low_power;
-
- /* Make sure register accesses (indirect or otherwise)
- * will function correctly.
+ /*
+ * Make sure register accesses (indirect or otherwise) will function
+ * correctly.
*/
pci_write_config_dword(tp->pdev,
- TG3PCI_MISC_HOST_CTRL,
- tp->misc_host_ctrl);
+ TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+}
- switch (state) {
- case PCI_D0:
- pci_enable_wake(tp->pdev, state, false);
- pci_set_power_state(tp->pdev, PCI_D0);
+static int tg3_power_up(struct tg3 *tp)
+{
+ tg3_enable_register_access(tp);
- /* Switch out of Vaux if it is a NIC */
- if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
- tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
+ pci_set_power_state(tp->pdev, PCI_D0);
- return 0;
+ /* Switch out of Vaux if it is a NIC */
+ if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
- case PCI_D1:
- case PCI_D2:
- case PCI_D3hot:
- break;
+ return 0;
+}
- default:
- netdev_err(tp->dev, "Invalid power state (D%d) requested\n",
- state);
- return -EINVAL;
- }
+static int tg3_power_down_prepare(struct tg3 *tp)
+{
+ u32 misc_host_ctrl;
+ bool device_should_wake, do_low_power;
+
+ tg3_enable_register_access(tp);
/* Restore the CLKREQ setting. */
if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
@@ -2600,8 +2598,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tw32(TG3PCI_MISC_HOST_CTRL,
misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
- device_should_wake = pci_pme_capable(tp->pdev, state) &&
- device_may_wakeup(&tp->pdev->dev) &&
+ device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
@@ -2728,12 +2725,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
- if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
- mac_mode |= tp->mac_mode &
- (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
- if (mac_mode & MAC_MODE_APE_TX_EN)
- mac_mode |= MAC_MODE_TDE_ENABLE;
- }
+ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ mac_mode |= MAC_MODE_APE_TX_EN |
+ MAC_MODE_APE_RX_EN |
+ MAC_MODE_TDE_ENABLE;
tw32_f(MAC_MODE, mac_mode);
udelay(100);
@@ -2823,13 +2818,15 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
- if (device_should_wake)
- pci_enable_wake(tp->pdev, state, true);
+ return 0;
+}
- /* Finally, set the new power state. */
- pci_set_power_state(tp->pdev, state);
+static void tg3_power_down(struct tg3 *tp)
+{
+ tg3_power_down_prepare(tp);
- return 0;
+ pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+ pci_set_power_state(tp->pdev, PCI_D3hot);
}
static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
@@ -2969,7 +2966,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
}
if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
- u32 val = 0;
+ u32 val;
tw32(TG3_CPMU_EEE_MODE,
tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
@@ -2986,19 +2983,18 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2,
val | MII_TG3_DSP_CH34TP2_HIBW01);
+ val = 0;
if (tp->link_config.autoneg == AUTONEG_ENABLE) {
/* Advertise 100-BaseTX EEE ability */
if (tp->link_config.advertising &
- (ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full))
- val |= TG3_CL45_D7_EEEADV_CAP_100TX;
+ ADVERTISED_100baseT_Full)
+ val |= MDIO_AN_EEE_ADV_100TX;
/* Advertise 1000-BaseT EEE ability */
if (tp->link_config.advertising &
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full))
- val |= TG3_CL45_D7_EEEADV_CAP_1000T;
+ ADVERTISED_1000baseT_Full)
+ val |= MDIO_AN_EEE_ADV_1000T;
}
- tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, val);
+ tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
/* Turn off SM_DSP clock. */
val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
@@ -5763,7 +5759,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
- !mss && skb->len > ETH_DATA_LEN)
+ !mss && skb->len > VLAN_ETH_FRAME_LEN)
base_flags |= TXD_FLAG_JMB_PKT;
tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -5997,7 +5993,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
#endif
if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
- !mss && skb->len > ETH_DATA_LEN)
+ !mss && skb->len > VLAN_ETH_FRAME_LEN)
base_flags |= TXD_FLAG_JMB_PKT;
len = skb_headlen(skb);
@@ -6339,13 +6335,13 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
kfree(tpr->rx_jmb_buffers);
tpr->rx_jmb_buffers = NULL;
if (tpr->rx_std) {
- pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp),
- tpr->rx_std, tpr->rx_std_mapping);
+ dma_free_coherent(&tp->pdev->dev, TG3_RX_STD_RING_BYTES(tp),
+ tpr->rx_std, tpr->rx_std_mapping);
tpr->rx_std = NULL;
}
if (tpr->rx_jmb) {
- pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp),
- tpr->rx_jmb, tpr->rx_jmb_mapping);
+ dma_free_coherent(&tp->pdev->dev, TG3_RX_JMB_RING_BYTES(tp),
+ tpr->rx_jmb, tpr->rx_jmb_mapping);
tpr->rx_jmb = NULL;
}
}
@@ -6358,8 +6354,10 @@ static int tg3_rx_prodring_init(struct tg3 *tp,
if (!tpr->rx_std_buffers)
return -ENOMEM;
- tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp),
- &tpr->rx_std_mapping);
+ tpr->rx_std = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_RX_STD_RING_BYTES(tp),
+ &tpr->rx_std_mapping,
+ GFP_KERNEL);
if (!tpr->rx_std)
goto err_out;
@@ -6370,9 +6368,10 @@ static int tg3_rx_prodring_init(struct tg3 *tp,
if (!tpr->rx_jmb_buffers)
goto err_out;
- tpr->rx_jmb = pci_alloc_consistent(tp->pdev,
- TG3_RX_JMB_RING_BYTES(tp),
- &tpr->rx_jmb_mapping);
+ tpr->rx_jmb = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_RX_JMB_RING_BYTES(tp),
+ &tpr->rx_jmb_mapping,
+ GFP_KERNEL);
if (!tpr->rx_jmb)
goto err_out;
}
@@ -6491,7 +6490,7 @@ static void tg3_free_consistent(struct tg3 *tp)
struct tg3_napi *tnapi = &tp->napi[i];
if (tnapi->tx_ring) {
- pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
+ dma_free_coherent(&tp->pdev->dev, TG3_TX_RING_BYTES,
tnapi->tx_ring, tnapi->tx_desc_mapping);
tnapi->tx_ring = NULL;
}
@@ -6500,25 +6499,26 @@ static void tg3_free_consistent(struct tg3 *tp)
tnapi->tx_buffers = NULL;
if (tnapi->rx_rcb) {
- pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
- tnapi->rx_rcb,
- tnapi->rx_rcb_mapping);
+ dma_free_coherent(&tp->pdev->dev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ tnapi->rx_rcb,
+ tnapi->rx_rcb_mapping);
tnapi->rx_rcb = NULL;
}
tg3_rx_prodring_fini(tp, &tnapi->prodring);
if (tnapi->hw_status) {
- pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
- tnapi->hw_status,
- tnapi->status_mapping);
+ dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE,
+ tnapi->hw_status,
+ tnapi->status_mapping);
tnapi->hw_status = NULL;
}
}
if (tp->hw_stats) {
- pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
- tp->hw_stats, tp->stats_mapping);
+ dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
+ tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
}
@@ -6531,9 +6531,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
{
int i;
- tp->hw_stats = pci_alloc_consistent(tp->pdev,
- sizeof(struct tg3_hw_stats),
- &tp->stats_mapping);
+ tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev,
+ sizeof(struct tg3_hw_stats),
+ &tp->stats_mapping,
+ GFP_KERNEL);
if (!tp->hw_stats)
goto err_out;
@@ -6543,9 +6544,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
struct tg3_napi *tnapi = &tp->napi[i];
struct tg3_hw_status *sblk;
- tnapi->hw_status = pci_alloc_consistent(tp->pdev,
- TG3_HW_STATUS_SIZE,
- &tnapi->status_mapping);
+ tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_HW_STATUS_SIZE,
+ &tnapi->status_mapping,
+ GFP_KERNEL);
if (!tnapi->hw_status)
goto err_out;
@@ -6566,9 +6568,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!tnapi->tx_buffers)
goto err_out;
- tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
- TG3_TX_RING_BYTES,
- &tnapi->tx_desc_mapping);
+ tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_TX_RING_BYTES,
+ &tnapi->tx_desc_mapping,
+ GFP_KERNEL);
if (!tnapi->tx_ring)
goto err_out;
}
@@ -6601,9 +6604,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS))
continue;
- tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
- TG3_RX_RCB_RING_BYTES(tp),
- &tnapi->rx_rcb_mapping);
+ tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ &tnapi->rx_rcb_mapping,
+ GFP_KERNEL);
if (!tnapi->rx_rcb)
goto err_out;
@@ -6987,7 +6991,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
- pcie_set_readrq(tp->pdev, 4096);
+ pcie_set_readrq(tp->pdev, tp->pcie_readrq);
else {
pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
tp->pci_cacheline_sz);
@@ -7181,7 +7185,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tp->pcie_cap + PCI_EXP_DEVCTL,
val16);
- pcie_set_readrq(tp->pdev, 4096);
+ pcie_set_readrq(tp->pdev, tp->pcie_readrq);
/* Clear error status */
pci_write_config_word(tp->pdev,
@@ -7222,19 +7226,21 @@ static int tg3_chip_reset(struct tg3 *tp)
tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
}
+ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ tp->mac_mode = MAC_MODE_APE_TX_EN |
+ MAC_MODE_APE_RX_EN |
+ MAC_MODE_TDE_ENABLE;
+
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
- tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
- tw32_f(MAC_MODE, tp->mac_mode);
+ tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+ val = tp->mac_mode;
} else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
- tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
- tw32_f(MAC_MODE, tp->mac_mode);
- } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
- tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
- if (tp->mac_mode & MAC_MODE_APE_TX_EN)
- tp->mac_mode |= MAC_MODE_TDE_ENABLE;
- tw32_f(MAC_MODE, tp->mac_mode);
+ tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+ val = tp->mac_mode;
} else
- tw32_f(MAC_MODE, 0);
+ val = 0;
+
+ tw32_f(MAC_MODE, val);
udelay(40);
tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
@@ -7801,6 +7807,37 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
tg3_abort_hw(tp, 1);
+ /* Enable MAC control of LPI */
+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
+ tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
+ TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+ TG3_CPMU_EEE_LNKIDL_UART_IDL);
+
+ tw32_f(TG3_CPMU_EEE_CTRL,
+ TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
+
+ val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
+ TG3_CPMU_EEEMD_LPI_IN_TX |
+ TG3_CPMU_EEEMD_LPI_IN_RX |
+ TG3_CPMU_EEEMD_EEE_ENABLE;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+ val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
+
+ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+ val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
+
+ tw32_f(TG3_CPMU_EEE_MODE, val);
+
+ tw32_f(TG3_CPMU_EEE_DBTMR1,
+ TG3_CPMU_DBTMR1_PCIEXIT_2047US |
+ TG3_CPMU_DBTMR1_LNKIDLE_2047US);
+
+ tw32_f(TG3_CPMU_EEE_DBTMR2,
+ TG3_CPMU_DBTMR1_APE_TX_2047US |
+ TG3_CPMU_DBTMR2_TXIDXEQ_2047US);
+ }
+
if (reset_phy)
tg3_phy_reset(tp);
@@ -7860,18 +7897,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(GRC_MODE, grc_mode);
}
- if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
- u32 grc_mode = tr32(GRC_MODE);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+ if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
+ u32 grc_mode = tr32(GRC_MODE);
- /* Access the lower 1K of PL PCIE block registers. */
- val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
- tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
+ /* Access the lower 1K of PL PCIE block registers. */
+ val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
+ tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
- val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5);
- tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5,
- val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ);
+ val = tr32(TG3_PCIE_TLDLPL_PORT +
+ TG3_PCIE_PL_LO_PHYCTL5);
+ tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5,
+ val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ);
- tw32(GRC_MODE, grc_mode);
+ tw32(GRC_MODE, grc_mode);
+ }
val = tr32(TG3_CPMU_LSPD_10MB_CLK);
val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
@@ -7879,22 +7919,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(TG3_CPMU_LSPD_10MB_CLK, val);
}
- /* Enable MAC control of LPI */
- if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
- tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
- TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
- TG3_CPMU_EEE_LNKIDL_UART_IDL);
-
- tw32_f(TG3_CPMU_EEE_CTRL,
- TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
-
- tw32_f(TG3_CPMU_EEE_MODE,
- TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
- TG3_CPMU_EEEMD_LPI_IN_TX |
- TG3_CPMU_EEEMD_LPI_IN_RX |
- TG3_CPMU_EEEMD_EEE_ENABLE);
- }
-
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision. But do not set this on PCI Express
@@ -8162,8 +8186,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -8203,6 +8226,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
val = tr32(TG3_RDMA_RSRVCTRL_REG);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ val &= ~TG3_RDMA_RSRVCTRL_TXMRGN_MASK;
+ val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B;
+ }
tw32(TG3_RDMA_RSRVCTRL_REG,
val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
@@ -8280,7 +8307,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
- tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+ tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = 0;
tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
@@ -9031,8 +9058,14 @@ static bool tg3_enable_msix(struct tg3 *tp)
pci_disable_msix(tp->pdev);
return false;
}
- if (tp->irq_cnt > 1)
+
+ if (tp->irq_cnt > 1) {
tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+ netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1);
+ }
+ }
return true;
}
@@ -9101,7 +9134,7 @@ static int tg3_open(struct net_device *dev)
netif_carrier_off(tp->dev);
- err = tg3_set_power_state(tp, PCI_D0);
+ err = tg3_power_up(tp);
if (err)
return err;
@@ -9266,7 +9299,7 @@ static int tg3_close(struct net_device *dev)
tg3_free_consistent(tp);
- tg3_set_power_state(tp, PCI_D3hot);
+ tg3_power_down(tp);
netif_carrier_off(tp->dev);
@@ -11068,7 +11101,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
struct tg3 *tp = netdev_priv(dev);
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
- tg3_set_power_state(tp, PCI_D0);
+ tg3_power_up(tp);
memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
@@ -11136,7 +11169,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_phy_start(tp);
}
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
- tg3_set_power_state(tp, PCI_D3hot);
+ tg3_power_down(tp);
}
@@ -12411,8 +12444,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
if (cfg2 & (1 << 18))
tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS;
- if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
- GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) &&
+ if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) ||
+ ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) &&
(cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
tp->phy_flags |= TG3_PHYFLG_ENABLE_APD;
@@ -12548,9 +12582,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
}
}
- if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))
+ if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
+ ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)))
tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
@@ -12658,7 +12694,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
cnt = pci_read_vpd(tp->pdev, pos,
TG3_NVM_VPD_LEN - pos,
&vpd_data[pos]);
- if (cnt == -ETIMEDOUT || -EINTR)
+ if (cnt == -ETIMEDOUT || cnt == -EINTR)
cnt = 0;
else if (cnt < 0)
goto out_not_found;
@@ -13047,17 +13083,15 @@ static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
return 512;
}
+DEFINE_PCI_DEVICE_TABLE(write_reorder_chipsets) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) },
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) },
+ { },
+};
+
static int __devinit tg3_get_invariants(struct tg3 *tp)
{
- static struct pci_device_id write_reorder_chipsets[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_FE_GATE_700C) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_8131_BRIDGE) },
- { PCI_DEVICE(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8385_0) },
- { },
- };
u32 misc_ctrl_reg;
u32 pci_state_reg, grc_misc_cfg;
u32 val;
@@ -13359,7 +13393,45 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
- pcie_set_readrq(tp->pdev, 4096);
+ tp->pcie_readrq = 4096;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ u16 word;
+
+ pci_read_config_word(tp->pdev,
+ tp->pcie_cap + PCI_EXP_LNKSTA,
+ &word);
+ switch (word & PCI_EXP_LNKSTA_CLS) {
+ case PCI_EXP_LNKSTA_CLS_2_5GB:
+ word &= PCI_EXP_LNKSTA_NLW;
+ word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
+ switch (word) {
+ case 2:
+ tp->pcie_readrq = 2048;
+ break;
+ case 4:
+ tp->pcie_readrq = 1024;
+ break;
+ }
+ break;
+
+ case PCI_EXP_LNKSTA_CLS_5_0GB:
+ word &= PCI_EXP_LNKSTA_NLW;
+ word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
+ switch (word) {
+ case 1:
+ tp->pcie_readrq = 2048;
+ break;
+ case 2:
+ tp->pcie_readrq = 1024;
+ break;
+ case 4:
+ tp->pcie_readrq = 512;
+ break;
+ }
+ }
+ }
+
+ pcie_set_readrq(tp->pdev, tp->pcie_readrq);
pci_read_config_word(tp->pdev,
tp->pcie_cap + PCI_EXP_LNKCTL,
@@ -13546,7 +13618,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
(tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
- /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
+ /* Set up tp->grc_local_ctrl before calling tg_power_up().
* GPIO1 driven high will bring 5700's external PHY out of reset.
* It is also used as eeprom write protect on LOMs.
*/
@@ -13577,7 +13649,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
/* Force the chip into D0. */
- err = tg3_set_power_state(tp, PCI_D0);
+ err = tg3_power_up(tp);
if (err) {
dev_err(&tp->pdev->dev, "Transition to D0 failed\n");
return err;
@@ -13722,8 +13794,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* Preserve the APE MAC_MODE bits */
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
- tp->mac_mode = tr32(MAC_MODE) |
- MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+ tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = TG3_DEF_MAC_MODE;
@@ -14153,13 +14224,19 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm
#define TEST_BUFFER_SIZE 0x2000
+DEFINE_PCI_DEVICE_TABLE(dma_wait_state_chipsets) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
+ { },
+};
+
static int __devinit tg3_test_dma(struct tg3 *tp)
{
dma_addr_t buf_dma;
u32 *buf, saved_dma_rwctrl;
int ret = 0;
- buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
+ buf = dma_alloc_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE,
+ &buf_dma, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
goto out_nofree;
@@ -14321,11 +14398,6 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
}
if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
DMA_RWCTRL_WRITE_BNDRY_16) {
- static struct pci_device_id dma_wait_state_chipsets[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_APPLE,
- PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
- { },
- };
/* DMA test passed without adjusting DMA boundary,
* now look for chipsets that are known to expose the
@@ -14343,7 +14415,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
}
out:
- pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma);
+ dma_free_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, buf, buf_dma);
out_nofree:
return ret;
}
@@ -14957,7 +15029,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
if (tp->fw)
release_firmware(tp->fw);
- flush_scheduled_work();
+ cancel_work_sync(&tp->reset_task);
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
tg3_phy_fini(tp);
@@ -14980,23 +15052,18 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
}
}
-static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int tg3_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
- pci_power_t target_state;
int err;
- /* PCI register 4 needs to be saved whether netif_running() or not.
- * MSI address and data need to be saved if using MSI and
- * netif_running().
- */
- pci_save_state(pdev);
-
if (!netif_running(dev))
return 0;
- flush_scheduled_work();
+ flush_work_sync(&tp->reset_task);
tg3_phy_stop(tp);
tg3_netif_stop(tp);
@@ -15013,9 +15080,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
- target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot;
-
- err = tg3_set_power_state(tp, target_state);
+ err = tg3_power_down_prepare(tp);
if (err) {
int err2;
@@ -15042,21 +15107,16 @@ out:
return err;
}
-static int tg3_resume(struct pci_dev *pdev)
+static int tg3_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
int err;
- pci_restore_state(tp->pdev);
-
if (!netif_running(dev))
return 0;
- err = tg3_set_power_state(tp, PCI_D0);
- if (err)
- return err;
-
netif_device_attach(dev);
tg3_full_lock(tp, 0);
@@ -15080,13 +15140,21 @@ out:
return err;
}
+static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
+#define TG3_PM_OPS (&tg3_pm_ops)
+
+#else
+
+#define TG3_PM_OPS NULL
+
+#endif /* CONFIG_PM_SLEEP */
+
static struct pci_driver tg3_driver = {
.name = DRV_MODULE_NAME,
.id_table = tg3_pci_tbl,
.probe = tg3_init_one,
.remove = __devexit_p(tg3_remove_one),
- .suspend = tg3_suspend,
- .resume = tg3_resume
+ .driver.pm = TG3_PM_OPS,
};
static int __init tg3_init(void)
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 4a1974804b9f..d62c8d937c82 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1094,13 +1094,19 @@
/* 0x3664 --> 0x36b0 unused */
#define TG3_CPMU_EEE_MODE 0x000036b0
-#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008
-#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080
-#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100
-#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200
-#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000
-/* 0x36b4 --> 0x36b8 unused */
-
+#define TG3_CPMU_EEEMD_APE_TX_DET_EN 0x00000004
+#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008
+#define TG3_CPMU_EEEMD_SND_IDX_DET_EN 0x00000040
+#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080
+#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100
+#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200
+#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000
+#define TG3_CPMU_EEE_DBTMR1 0x000036b4
+#define TG3_CPMU_DBTMR1_PCIEXIT_2047US 0x07ff0000
+#define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000070ff
+#define TG3_CPMU_EEE_DBTMR2 0x000036b8
+#define TG3_CPMU_DBTMR1_APE_TX_2047US 0x07ff0000
+#define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000070ff
#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc
#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000
#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004
@@ -1327,6 +1333,8 @@
#define TG3_RDMA_RSRVCTRL_REG 0x00004900
#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
+#define TG3_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000
+#define TG3_RDMA_RSRVCTRL_TXMRGN_MASK 0xffe00000
/* 0x4904 --> 0x4910 unused */
#define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910
@@ -2170,9 +2178,6 @@
#define MII_TG3_TEST1_CRC_EN 0x8000
/* Clause 45 expansion registers */
-#define TG3_CL45_D7_EEEADV_CAP 0x003c
-#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002
-#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004
#define TG3_CL45_D7_EEERES_STAT 0x803e
#define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002
#define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004
@@ -2562,10 +2567,6 @@ struct ring_info {
DEFINE_DMA_UNMAP_ADDR(mapping);
};
-struct tg3_config_info {
- u32 flags;
-};
-
struct tg3_link_config {
/* Describes what we're trying to get. */
u32 advertising;
@@ -2713,17 +2714,17 @@ struct tg3_napi {
u32 last_irq_tag;
u32 int_mbox;
u32 coal_now;
- u32 tx_prod;
- u32 tx_cons;
- u32 tx_pending;
- u32 prodmbox;
- u32 consmbox;
+ u32 consmbox ____cacheline_aligned;
u32 rx_rcb_ptr;
u16 *rx_rcb_prod_idx;
struct tg3_rx_prodring_set prodring;
-
struct tg3_rx_buffer_desc *rx_rcb;
+
+ u32 tx_prod ____cacheline_aligned;
+ u32 tx_cons;
+ u32 tx_pending;
+ u32 prodmbox;
struct tg3_tx_buffer_desc *tx_ring;
struct ring_info *tx_buffers;
@@ -2946,6 +2947,7 @@ struct tg3 {
int pcix_cap;
int pcie_cap;
};
+ int pcie_readrq;
struct mii_bus *mdio_bus;
int mdio_irq[PHY_MAX_ADDR];
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 91e6c78271a3..4786497de03e 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -657,8 +657,9 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
#ifndef PCMCIA
/* finish figuring the shared RAM address */
if (cardpresent == TR_ISA) {
- static __u32 ram_bndry_mask[] =
- { 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 };
+ static const __u32 ram_bndry_mask[] = {
+ 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000
+ };
__u32 new_base, rrr_32, chk_base, rbm;
rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03;
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index c78a50586c1d..b13c6b040be3 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -964,7 +964,7 @@ static void de_set_media (struct de_private *de)
dw32(MacMode, macmode);
}
-static void de_next_media (struct de_private *de, u32 *media,
+static void de_next_media (struct de_private *de, const u32 *media,
unsigned int n_media)
{
unsigned int i;
@@ -1008,10 +1008,10 @@ static void de21040_media_timer (unsigned long data)
return;
if (de->media_type == DE_MEDIA_AUI) {
- u32 next_state = DE_MEDIA_TP;
+ static const u32 next_state = DE_MEDIA_TP;
de_next_media(de, &next_state, 1);
} else {
- u32 next_state = DE_MEDIA_AUI;
+ static const u32 next_state = DE_MEDIA_AUI;
de_next_media(de, &next_state, 1);
}
@@ -1136,13 +1136,19 @@ static void de21041_media_timer (unsigned long data)
* simply resets the PHY and reloads the current media settings.
*/
if (de->media_type == DE_MEDIA_AUI) {
- u32 next_states[] = { DE_MEDIA_BNC, DE_MEDIA_TP_AUTO };
+ static const u32 next_states[] = {
+ DE_MEDIA_BNC, DE_MEDIA_TP_AUTO
+ };
de_next_media(de, next_states, ARRAY_SIZE(next_states));
} else if (de->media_type == DE_MEDIA_BNC) {
- u32 next_states[] = { DE_MEDIA_TP_AUTO, DE_MEDIA_AUI };
+ static const u32 next_states[] = {
+ DE_MEDIA_TP_AUTO, DE_MEDIA_AUI
+ };
de_next_media(de, next_states, ARRAY_SIZE(next_states));
} else {
- u32 next_states[] = { DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO };
+ static const u32 next_states[] = {
+ DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO
+ };
de_next_media(de, next_states, ARRAY_SIZE(next_states));
}
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index a9f7d5d1a269..7064e035757a 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
DMFE_DBUG(0, "dmfe_start_xmit", 0);
- /* Resource flag check */
- netif_stop_queue(dev);
-
/* Too large packet check */
if (skb->len > MAX_PACKET_SIZE) {
pr_err("big packet = %d\n", (u16)skb->len);
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+ /* Resource flag check */
+ netif_stop_queue(dev);
+
spin_lock_irqsave(&db->lock, flags);
/* No Tx resource check, it never happen nromally */
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 2c39f2591216..5c01e260f1ba 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1302,17 +1302,18 @@ static const struct net_device_ops tulip_netdev_ops = {
#endif
};
+DEFINE_PCI_DEVICE_TABLE(early_486_chipsets) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
+ { },
+};
+
static int __devinit tulip_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct tulip_private *tp;
/* See note below on the multiport cards. */
static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
- static struct pci_device_id early_486_chipsets[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
- { },
- };
static int last_irq;
static int multiport_cnt; /* For four-port boards w/one EEPROM */
int i, irq;
@@ -1682,7 +1683,9 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
tp->full_duplex_lock = 1;
if (tulip_media_cap[tp->default_port] & MediaIsMII) {
- u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
+ static const u16 media2advert[] = {
+ 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200
+ };
tp->mii_advertise = media2advert[tp->default_port - 9];
tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
}
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 55f3a3e667a9..7599c457abd1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -757,7 +757,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- gso.csum_start = skb->csum_start - skb_headroom(skb);
+ gso.csum_start = skb_checksum_start_offset(skb);
gso.csum_offset = skb->csum_offset;
} /* else everything is zero */
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 5b83c3f35f47..a3c46f6a15e7 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
}
strcpy(info->driver, KBUILD_MODNAME);
- strcpy(info->version, UTS_RELEASE);
strcpy(info->bus_info, pci_name(pci_dev));
}
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 52ffabe6db0e..6f600cced6e1 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -196,6 +196,25 @@ config USB_NET_CDC_EEM
IEEE 802 "local assignment" bit is set in the address, a "usbX"
name is used instead.
+config USB_NET_CDC_NCM
+ tristate "CDC NCM support"
+ depends on USB_USBNET
+ default y
+ help
+ This driver provides support for CDC NCM (Network Control Model
+ Device USB Class Specification). The CDC NCM specification is
+ available from <http://www.usb.org/>.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module.
+
+ This driver should work with at least the following devices:
+ * ST-Ericsson M700 LTE FDD/TDD Mobile Broadband Modem (ref. design)
+ * ST-Ericsson M5730 HSPA+ Mobile Broadband Modem (reference design)
+ * ST-Ericsson M570 HSPA+ Mobile Broadband Modem (reference design)
+ * ST-Ericsson M343 HSPA Mobile Broadband Modem (reference design)
+ * Ericsson F5521gw Mobile Broadband Module
+
config USB_NET_DM9601
tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
depends on USB_USBNET
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index a19b0259ae16..cac170301187 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -26,4 +26,5 @@ obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
+obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index aea4645be7f6..6140b56cce53 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1508,6 +1508,10 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x0b95, 0x1780),
.driver_info = (unsigned long) &ax88178_info,
}, {
+ // Logitec LAN-GTJ/U2A
+ USB_DEVICE (0x0789, 0x0160),
+ .driver_info = (unsigned long) &ax88178_info,
+}, {
// Linksys USB200M Rev 2
USB_DEVICE (0x13b1, 0x0018),
.driver_info = (unsigned long) &ax88772_info,
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index b3fe0de40469..9a60e415d76b 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -99,9 +99,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
*/
buf = dev->udev->actconfig->extra;
len = dev->udev->actconfig->extralen;
- if (len)
- dev_dbg(&intf->dev,
- "CDC descriptors on config\n");
+ dev_dbg(&intf->dev, "CDC descriptors on config\n");
}
/* Maybe CDC descriptors are after the endpoint? This bug has
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
new file mode 100644
index 000000000000..593c104ab199
--- /dev/null
+++ b/drivers/net/usb/cdc_ncm.c
@@ -0,0 +1,1213 @@
+/*
+ * cdc_ncm.c
+ *
+ * Copyright (C) ST-Ericsson 2010
+ * Contact: Alexey Orishko <alexey.orishko@stericsson.com>
+ * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
+ *
+ * USB Host Driver for Network Control Model (NCM)
+ * http://www.usb.org/developers/devclass_docs/NCM10.zip
+ *
+ * The NCM encoding, decoding and initialization logic
+ * derives from FreeBSD 8.x. if_cdce.c and if_cdcereg.h
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose this file to be licensed under the terms
+ * of the GNU General Public License (GPL) Version 2 or the 2-clause
+ * BSD license listed below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/version.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+#include <linux/usb/usbnet.h>
+#include <linux/usb/cdc.h>
+
+#define DRIVER_VERSION "30-Nov-2010"
+
+/* CDC NCM subclass 3.2.1 */
+#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
+
+/* Maximum NTB length */
+#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */
+#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */
+
+/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
+#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
+
+#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
+
+/* Default value for MaxDatagramSize */
+#define CDC_NCM_MAX_DATAGRAM_SIZE 2048 /* bytes */
+
+/*
+ * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting
+ * the last NULL entry. Any additional datagrams in NTB would be discarded.
+ */
+#define CDC_NCM_DPT_DATAGRAMS_MAX 32
+
+/* Restart the timer, if amount of datagrams is less than given value */
+#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3
+
+/* The following macro defines the minimum header space */
+#define CDC_NCM_MIN_HDR_SIZE \
+ (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
+ (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16))
+
+struct connection_speed_change {
+ __le32 USBitRate; /* holds 3GPP downlink value, bits per second */
+ __le32 DSBitRate; /* holds 3GPP uplink value, bits per second */
+} __attribute__ ((packed));
+
+struct cdc_ncm_data {
+ struct usb_cdc_ncm_nth16 nth16;
+ struct usb_cdc_ncm_ndp16 ndp16;
+ struct usb_cdc_ncm_dpe16 dpe16[CDC_NCM_DPT_DATAGRAMS_MAX + 1];
+};
+
+struct cdc_ncm_ctx {
+ struct cdc_ncm_data rx_ncm;
+ struct cdc_ncm_data tx_ncm;
+ struct usb_cdc_ncm_ntb_parameters ncm_parm;
+ struct timer_list tx_timer;
+
+ const struct usb_cdc_ncm_desc *func_desc;
+ const struct usb_cdc_header_desc *header_desc;
+ const struct usb_cdc_union_desc *union_desc;
+ const struct usb_cdc_ether_desc *ether_desc;
+
+ struct net_device *netdev;
+ struct usb_device *udev;
+ struct usb_host_endpoint *in_ep;
+ struct usb_host_endpoint *out_ep;
+ struct usb_host_endpoint *status_ep;
+ struct usb_interface *intf;
+ struct usb_interface *control;
+ struct usb_interface *data;
+
+ struct sk_buff *tx_curr_skb;
+ struct sk_buff *tx_rem_skb;
+
+ spinlock_t mtx;
+
+ u32 tx_timer_pending;
+ u32 tx_curr_offset;
+ u32 tx_curr_last_offset;
+ u32 tx_curr_frame_num;
+ u32 rx_speed;
+ u32 tx_speed;
+ u32 rx_max;
+ u32 tx_max;
+ u32 max_datagram_size;
+ u16 tx_max_datagrams;
+ u16 tx_remainder;
+ u16 tx_modulus;
+ u16 tx_ndp_modulus;
+ u16 tx_seq;
+ u16 connected;
+ u8 data_claimed;
+ u8 control_claimed;
+};
+
+static void cdc_ncm_tx_timeout(unsigned long arg);
+static const struct driver_info cdc_ncm_info;
+static struct usb_driver cdc_ncm_driver;
+static struct ethtool_ops cdc_ncm_ethtool_ops;
+
+static const struct usb_device_id cdc_devs[] = {
+ { USB_INTERFACE_INFO(USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&cdc_ncm_info,
+ },
+ {
+ },
+};
+
+MODULE_DEVICE_TABLE(usb, cdc_devs);
+
+static void
+cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ strncpy(info->driver, dev->driver_name, sizeof(info->driver));
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+ strncpy(info->fw_version, dev->driver_info->description,
+ sizeof(info->fw_version));
+ usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
+}
+
+static int
+cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req,
+ void *data, u16 flags, u16 *actlen, u16 timeout)
+{
+ int err;
+
+ err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ?
+ usb_rcvctrlpipe(ctx->udev, 0) :
+ usb_sndctrlpipe(ctx->udev, 0),
+ req->bNotificationType, req->bmRequestType,
+ req->wValue,
+ req->wIndex, data,
+ req->wLength, timeout);
+
+ if (err < 0) {
+ if (actlen)
+ *actlen = 0;
+ return err;
+ }
+
+ if (actlen)
+ *actlen = err;
+
+ return 0;
+}
+
+static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
+{
+ struct usb_cdc_notification req;
+ u32 val;
+ __le16 max_datagram_size;
+ u8 flags;
+ u8 iface_no;
+ int err;
+
+ iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
+
+ req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE;
+ req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS;
+ req.wValue = 0;
+ req.wIndex = cpu_to_le16(iface_no);
+ req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm));
+
+ err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000);
+ if (err) {
+ pr_debug("failed GET_NTB_PARAMETERS\n");
+ return 1;
+ }
+
+ /* read correct set of parameters according to device mode */
+ ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize);
+ ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize);
+ ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder);
+ ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor);
+ ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment);
+
+ if (ctx->func_desc != NULL)
+ flags = ctx->func_desc->bmNetworkCapabilities;
+ else
+ flags = 0;
+
+ pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u "
+ "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u "
+ "wNdpOutAlignment=%u flags=0x%x\n",
+ ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
+ ctx->tx_ndp_modulus, flags);
+
+ /* max count of tx datagrams without terminating NULL entry */
+ ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;
+
+ /* verify maximum size of received NTB in bytes */
+ if ((ctx->rx_max <
+ (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
+ (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX)) {
+ pr_debug("Using default maximum receive length=%d\n",
+ CDC_NCM_NTB_MAX_SIZE_RX);
+ ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX;
+ }
+
+ /* verify maximum size of transmitted NTB in bytes */
+ if ((ctx->tx_max <
+ (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
+ (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) {
+ pr_debug("Using default maximum transmit length=%d\n",
+ CDC_NCM_NTB_MAX_SIZE_TX);
+ ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX;
+ }
+
+ /*
+ * verify that the structure alignment is:
+ * - power of two
+ * - not greater than the maximum transmit length
+ * - not less than four bytes
+ */
+ val = ctx->tx_ndp_modulus;
+
+ if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) ||
+ (val != ((-val) & val)) || (val >= ctx->tx_max)) {
+ pr_debug("Using default alignment: 4 bytes\n");
+ ctx->tx_ndp_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE;
+ }
+
+ /*
+ * verify that the payload alignment is:
+ * - power of two
+ * - not greater than the maximum transmit length
+ * - not less than four bytes
+ */
+ val = ctx->tx_modulus;
+
+ if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) ||
+ (val != ((-val) & val)) || (val >= ctx->tx_max)) {
+ pr_debug("Using default transmit modulus: 4 bytes\n");
+ ctx->tx_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE;
+ }
+
+ /* verify the payload remainder */
+ if (ctx->tx_remainder >= ctx->tx_modulus) {
+ pr_debug("Using default transmit remainder: 0 bytes\n");
+ ctx->tx_remainder = 0;
+ }
+
+ /* adjust TX-remainder according to NCM specification. */
+ ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) &
+ (ctx->tx_modulus - 1));
+
+ /* additional configuration */
+
+ /* set CRC Mode */
+ req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE;
+ req.bNotificationType = USB_CDC_SET_CRC_MODE;
+ req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED);
+ req.wIndex = cpu_to_le16(iface_no);
+ req.wLength = 0;
+
+ err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
+ if (err)
+ pr_debug("Setting CRC mode off failed\n");
+
+ /* set NTB format */
+ req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE;
+ req.bNotificationType = USB_CDC_SET_NTB_FORMAT;
+ req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT);
+ req.wIndex = cpu_to_le16(iface_no);
+ req.wLength = 0;
+
+ err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
+ if (err)
+ pr_debug("Setting NTB format to 16-bit failed\n");
+
+ /* set Max Datagram Size (MTU) */
+ req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE;
+ req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE;
+ req.wValue = 0;
+ req.wIndex = cpu_to_le16(iface_no);
+ req.wLength = cpu_to_le16(2);
+
+ err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, 1000);
+ if (err) {
+ pr_debug(" GET_MAX_DATAGRAM_SIZE failed, using size=%u\n",
+ CDC_NCM_MIN_DATAGRAM_SIZE);
+ /* use default */
+ ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
+ } else {
+ ctx->max_datagram_size = le16_to_cpu(max_datagram_size);
+
+ if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
+ ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
+ else if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
+ ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
+ }
+
+ if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
+ ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
+
+ return 0;
+}
+
+static void
+cdc_ncm_find_endpoints(struct cdc_ncm_ctx *ctx, struct usb_interface *intf)
+{
+ struct usb_host_endpoint *e;
+ u8 ep;
+
+ for (ep = 0; ep < intf->cur_altsetting->desc.bNumEndpoints; ep++) {
+
+ e = intf->cur_altsetting->endpoint + ep;
+ switch (e->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_INT:
+ if (usb_endpoint_dir_in(&e->desc)) {
+ if (ctx->status_ep == NULL)
+ ctx->status_ep = e;
+ }
+ break;
+
+ case USB_ENDPOINT_XFER_BULK:
+ if (usb_endpoint_dir_in(&e->desc)) {
+ if (ctx->in_ep == NULL)
+ ctx->in_ep = e;
+ } else {
+ if (ctx->out_ep == NULL)
+ ctx->out_ep = e;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ del_timer_sync(&ctx->tx_timer);
+
+ if (ctx->data_claimed) {
+ usb_set_intfdata(ctx->data, NULL);
+ usb_driver_release_interface(driver_of(ctx->intf), ctx->data);
+ }
+
+ if (ctx->control_claimed) {
+ usb_set_intfdata(ctx->control, NULL);
+ usb_driver_release_interface(driver_of(ctx->intf),
+ ctx->control);
+ }
+
+ if (ctx->tx_rem_skb != NULL) {
+ dev_kfree_skb_any(ctx->tx_rem_skb);
+ ctx->tx_rem_skb = NULL;
+ }
+
+ if (ctx->tx_curr_skb != NULL) {
+ dev_kfree_skb_any(ctx->tx_curr_skb);
+ ctx->tx_curr_skb = NULL;
+ }
+
+ kfree(ctx);
+}
+
+static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct cdc_ncm_ctx *ctx;
+ struct usb_driver *driver;
+ u8 *buf;
+ int len;
+ int temp;
+ u8 iface_no;
+
+ ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+ if (ctx == NULL)
+ goto error;
+
+ memset(ctx, 0, sizeof(*ctx));
+
+ init_timer(&ctx->tx_timer);
+ spin_lock_init(&ctx->mtx);
+ ctx->netdev = dev->net;
+
+ /* store ctx pointer in device data field */
+ dev->data[0] = (unsigned long)ctx;
+
+ /* get some pointers */
+ driver = driver_of(intf);
+ buf = intf->cur_altsetting->extra;
+ len = intf->cur_altsetting->extralen;
+
+ ctx->udev = dev->udev;
+ ctx->intf = intf;
+
+ /* parse through descriptors associated with control interface */
+ while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) {
+
+ if (buf[1] != USB_DT_CS_INTERFACE)
+ goto advance;
+
+ switch (buf[2]) {
+ case USB_CDC_UNION_TYPE:
+ if (buf[0] < sizeof(*(ctx->union_desc)))
+ break;
+
+ ctx->union_desc =
+ (const struct usb_cdc_union_desc *)buf;
+
+ ctx->control = usb_ifnum_to_if(dev->udev,
+ ctx->union_desc->bMasterInterface0);
+ ctx->data = usb_ifnum_to_if(dev->udev,
+ ctx->union_desc->bSlaveInterface0);
+ break;
+
+ case USB_CDC_ETHERNET_TYPE:
+ if (buf[0] < sizeof(*(ctx->ether_desc)))
+ break;
+
+ ctx->ether_desc =
+ (const struct usb_cdc_ether_desc *)buf;
+
+ dev->hard_mtu =
+ le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
+
+ if (dev->hard_mtu <
+ (CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN))
+ dev->hard_mtu =
+ CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN;
+
+ else if (dev->hard_mtu >
+ (CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN))
+ dev->hard_mtu =
+ CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN;
+ break;
+
+ case USB_CDC_NCM_TYPE:
+ if (buf[0] < sizeof(*(ctx->func_desc)))
+ break;
+
+ ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf;
+ break;
+
+ default:
+ break;
+ }
+advance:
+ /* advance to next descriptor */
+ temp = buf[0];
+ buf += temp;
+ len -= temp;
+ }
+
+ /* check if we got everything */
+ if ((ctx->control == NULL) || (ctx->data == NULL) ||
+ (ctx->ether_desc == NULL))
+ goto error;
+
+ /* claim interfaces, if any */
+ if (ctx->data != intf) {
+ temp = usb_driver_claim_interface(driver, ctx->data, dev);
+ if (temp)
+ goto error;
+ ctx->data_claimed = 1;
+ }
+
+ if (ctx->control != intf) {
+ temp = usb_driver_claim_interface(driver, ctx->control, dev);
+ if (temp)
+ goto error;
+ ctx->control_claimed = 1;
+ }
+
+ iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
+
+ /* reset data interface */
+ temp = usb_set_interface(dev->udev, iface_no, 0);
+ if (temp)
+ goto error;
+
+ /* initialize data interface */
+ if (cdc_ncm_setup(ctx))
+ goto error;
+
+ /* configure data interface */
+ temp = usb_set_interface(dev->udev, iface_no, 1);
+ if (temp)
+ goto error;
+
+ cdc_ncm_find_endpoints(ctx, ctx->data);
+ cdc_ncm_find_endpoints(ctx, ctx->control);
+
+ if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) ||
+ (ctx->status_ep == NULL))
+ goto error;
+
+ dev->net->ethtool_ops = &cdc_ncm_ethtool_ops;
+
+ usb_set_intfdata(ctx->data, dev);
+ usb_set_intfdata(ctx->control, dev);
+ usb_set_intfdata(ctx->intf, dev);
+
+ temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress);
+ if (temp)
+ goto error;
+
+ dev_info(&dev->udev->dev, "MAC-Address: "
+ "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
+ dev->net->dev_addr[0], dev->net->dev_addr[1],
+ dev->net->dev_addr[2], dev->net->dev_addr[3],
+ dev->net->dev_addr[4], dev->net->dev_addr[5]);
+
+ dev->in = usb_rcvbulkpipe(dev->udev,
+ ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ dev->out = usb_sndbulkpipe(dev->udev,
+ ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ dev->status = ctx->status_ep;
+ dev->rx_urb_size = ctx->rx_max;
+
+ /*
+ * We should get an event when network connection is "connected" or
+ * "disconnected". Set network connection in "disconnected" state
+ * (carrier is OFF) during attach, so the IP network stack does not
+ * start IPv6 negotiation and more.
+ */
+ netif_carrier_off(dev->net);
+ ctx->tx_speed = ctx->rx_speed = 0;
+ return 0;
+
+error:
+ cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
+ dev->data[0] = 0;
+ dev_info(&dev->udev->dev, "Descriptor failure\n");
+ return -ENODEV;
+}
+
+static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct usb_driver *driver;
+
+ if (ctx == NULL)
+ return; /* no setup */
+
+ driver = driver_of(intf);
+
+ usb_set_intfdata(ctx->data, NULL);
+ usb_set_intfdata(ctx->control, NULL);
+ usb_set_intfdata(ctx->intf, NULL);
+
+ /* release interfaces, if any */
+ if (ctx->data_claimed) {
+ usb_driver_release_interface(driver, ctx->data);
+ ctx->data_claimed = 0;
+ }
+
+ if (ctx->control_claimed) {
+ usb_driver_release_interface(driver, ctx->control);
+ ctx->control_claimed = 0;
+ }
+
+ cdc_ncm_free(ctx);
+}
+
+static void cdc_ncm_zero_fill(u8 *ptr, u32 first, u32 end, u32 max)
+{
+ if (first >= max)
+ return;
+ if (first >= end)
+ return;
+ if (end > max)
+ end = max;
+ memset(ptr + first, 0, end - first);
+}
+
+static struct sk_buff *
+cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
+{
+ struct sk_buff *skb_out;
+ u32 rem;
+ u32 offset;
+ u32 last_offset;
+ u16 n = 0;
+ u8 timeout = 0;
+
+ /* if there is a remaining skb, it gets priority */
+ if (skb != NULL)
+ swap(skb, ctx->tx_rem_skb);
+ else
+ timeout = 1;
+
+ /*
+ * +----------------+
+ * | skb_out |
+ * +----------------+
+ * ^ offset
+ * ^ last_offset
+ */
+
+ /* check if we are resuming an OUT skb */
+ if (ctx->tx_curr_skb != NULL) {
+ /* pop variables */
+ skb_out = ctx->tx_curr_skb;
+ offset = ctx->tx_curr_offset;
+ last_offset = ctx->tx_curr_last_offset;
+ n = ctx->tx_curr_frame_num;
+
+ } else {
+ /* reset variables */
+ skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC);
+ if (skb_out == NULL) {
+ if (skb != NULL) {
+ dev_kfree_skb_any(skb);
+ ctx->netdev->stats.tx_dropped++;
+ }
+ goto exit_no_skb;
+ }
+
+ /* make room for NTH and NDP */
+ offset = ALIGN(sizeof(struct usb_cdc_ncm_nth16),
+ ctx->tx_ndp_modulus) +
+ sizeof(struct usb_cdc_ncm_ndp16) +
+ (ctx->tx_max_datagrams + 1) *
+ sizeof(struct usb_cdc_ncm_dpe16);
+
+ /* store last valid offset before alignment */
+ last_offset = offset;
+ /* align first Datagram offset correctly */
+ offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder;
+ /* zero buffer till the first IP datagram */
+ cdc_ncm_zero_fill(skb_out->data, 0, offset, offset);
+ n = 0;
+ ctx->tx_curr_frame_num = 0;
+ }
+
+ for (; n < ctx->tx_max_datagrams; n++) {
+ /* check if end of transmit buffer is reached */
+ if (offset >= ctx->tx_max)
+ break;
+
+ /* compute maximum buffer size */
+ rem = ctx->tx_max - offset;
+
+ if (skb == NULL) {
+ skb = ctx->tx_rem_skb;
+ ctx->tx_rem_skb = NULL;
+
+ /* check for end of skb */
+ if (skb == NULL)
+ break;
+ }
+
+ if (skb->len > rem) {
+ if (n == 0) {
+ /* won't fit, MTU problem? */
+ dev_kfree_skb_any(skb);
+ skb = NULL;
+ ctx->netdev->stats.tx_dropped++;
+ } else {
+ /* no room for skb - store for later */
+ if (ctx->tx_rem_skb != NULL) {
+ dev_kfree_skb_any(ctx->tx_rem_skb);
+ ctx->netdev->stats.tx_dropped++;
+ }
+ ctx->tx_rem_skb = skb;
+ skb = NULL;
+
+ /* loop one more time */
+ timeout = 1;
+ }
+ break;
+ }
+
+ memcpy(((u8 *)skb_out->data) + offset, skb->data, skb->len);
+
+ ctx->tx_ncm.dpe16[n].wDatagramLength = cpu_to_le16(skb->len);
+ ctx->tx_ncm.dpe16[n].wDatagramIndex = cpu_to_le16(offset);
+
+ /* update offset */
+ offset += skb->len;
+
+ /* store last valid offset before alignment */
+ last_offset = offset;
+
+ /* align offset correctly */
+ offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder;
+
+ /* zero padding */
+ cdc_ncm_zero_fill(skb_out->data, last_offset, offset,
+ ctx->tx_max);
+ dev_kfree_skb_any(skb);
+ skb = NULL;
+ }
+
+ /* free up any dangling skb */
+ if (skb != NULL) {
+ dev_kfree_skb_any(skb);
+ skb = NULL;
+ ctx->netdev->stats.tx_dropped++;
+ }
+
+ ctx->tx_curr_frame_num = n;
+
+ if (n == 0) {
+ /* wait for more frames */
+ /* push variables */
+ ctx->tx_curr_skb = skb_out;
+ ctx->tx_curr_offset = offset;
+ ctx->tx_curr_last_offset = last_offset;
+ goto exit_no_skb;
+
+ } else if ((n < ctx->tx_max_datagrams) && (timeout == 0)) {
+ /* wait for more frames */
+ /* push variables */
+ ctx->tx_curr_skb = skb_out;
+ ctx->tx_curr_offset = offset;
+ ctx->tx_curr_last_offset = last_offset;
+ /* set the pending count */
+ if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT)
+ ctx->tx_timer_pending = 2;
+ goto exit_no_skb;
+
+ } else {
+ /* frame goes out */
+ /* variables will be reset at next call */
+ }
+
+ /* check for overflow */
+ if (last_offset > ctx->tx_max)
+ last_offset = ctx->tx_max;
+
+ /* revert offset */
+ offset = last_offset;
+
+ /*
+ * If collected data size is less or equal CDC_NCM_MIN_TX_PKT bytes,
+ * we send buffers as it is. If we get more data, it would be more
+ * efficient for USB HS mobile device with DMA engine to receive a full
+ * size NTB, than canceling DMA transfer and receiving a short packet.
+ */
+ if (offset > CDC_NCM_MIN_TX_PKT)
+ offset = ctx->tx_max;
+
+ /* final zero padding */
+ cdc_ncm_zero_fill(skb_out->data, last_offset, offset, ctx->tx_max);
+
+ /* store last offset */
+ last_offset = offset;
+
+ if ((last_offset < ctx->tx_max) && ((last_offset %
+ le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) {
+ /* force short packet */
+ *(((u8 *)skb_out->data) + last_offset) = 0;
+ last_offset++;
+ }
+
+ /* zero the rest of the DPEs plus the last NULL entry */
+ for (; n <= CDC_NCM_DPT_DATAGRAMS_MAX; n++) {
+ ctx->tx_ncm.dpe16[n].wDatagramLength = 0;
+ ctx->tx_ncm.dpe16[n].wDatagramIndex = 0;
+ }
+
+ /* fill out 16-bit NTB header */
+ ctx->tx_ncm.nth16.dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN);
+ ctx->tx_ncm.nth16.wHeaderLength =
+ cpu_to_le16(sizeof(ctx->tx_ncm.nth16));
+ ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq);
+ ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset);
+ ctx->tx_ncm.nth16.wFpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16),
+ ctx->tx_ndp_modulus);
+
+ memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16));
+ ctx->tx_seq++;
+
+ /* fill out 16-bit NDP table */
+ ctx->tx_ncm.ndp16.dwSignature =
+ cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN);
+ rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) *
+ sizeof(struct usb_cdc_ncm_dpe16));
+ ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem);
+ ctx->tx_ncm.ndp16.wNextFpIndex = 0; /* reserved */
+
+ memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex,
+ &(ctx->tx_ncm.ndp16),
+ sizeof(ctx->tx_ncm.ndp16));
+
+ memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex +
+ sizeof(ctx->tx_ncm.ndp16),
+ &(ctx->tx_ncm.dpe16),
+ (ctx->tx_curr_frame_num + 1) *
+ sizeof(struct usb_cdc_ncm_dpe16));
+
+ /* set frame length */
+ skb_put(skb_out, last_offset);
+
+ /* return skb */
+ ctx->tx_curr_skb = NULL;
+ return skb_out;
+
+exit_no_skb:
+ return NULL;
+}
+
+static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx)
+{
+ /* start timer, if not already started */
+ if (timer_pending(&ctx->tx_timer) == 0) {
+ ctx->tx_timer.function = &cdc_ncm_tx_timeout;
+ ctx->tx_timer.data = (unsigned long)ctx;
+ ctx->tx_timer.expires = jiffies + ((HZ + 999) / 1000);
+ add_timer(&ctx->tx_timer);
+ }
+}
+
+static void cdc_ncm_tx_timeout(unsigned long arg)
+{
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)arg;
+ u8 restart;
+
+ spin_lock(&ctx->mtx);
+ if (ctx->tx_timer_pending != 0) {
+ ctx->tx_timer_pending--;
+ restart = 1;
+ } else
+ restart = 0;
+
+ spin_unlock(&ctx->mtx);
+
+ if (restart)
+ cdc_ncm_tx_timeout_start(ctx);
+ else if (ctx->netdev != NULL)
+ usbnet_start_xmit(NULL, ctx->netdev);
+}
+
+static struct sk_buff *
+cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+ struct sk_buff *skb_out;
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ u8 need_timer = 0;
+
+ /*
+ * The Ethernet API we are using does not support transmitting
+ * multiple Ethernet frames in a single call. This driver will
+ * accumulate multiple Ethernet frames and send out a larger
+ * USB frame when the USB buffer is full or when a single jiffies
+ * timeout happens.
+ */
+ if (ctx == NULL)
+ goto error;
+
+ spin_lock(&ctx->mtx);
+ skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
+ if (ctx->tx_curr_skb != NULL)
+ need_timer = 1;
+ spin_unlock(&ctx->mtx);
+
+ /* Start timer, if there is a remaining skb */
+ if (need_timer)
+ cdc_ncm_tx_timeout_start(ctx);
+
+ if (skb_out)
+ dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
+ return skb_out;
+
+error:
+ if (skb != NULL)
+ dev_kfree_skb_any(skb);
+
+ return NULL;
+}
+
+static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
+{
+ struct sk_buff *skb;
+ struct cdc_ncm_ctx *ctx;
+ int sumlen;
+ int actlen;
+ int temp;
+ int nframes;
+ int x;
+ int offset;
+
+ ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ if (ctx == NULL)
+ goto error;
+
+ actlen = skb_in->len;
+ sumlen = CDC_NCM_NTB_MAX_SIZE_RX;
+
+ if (actlen < (sizeof(ctx->rx_ncm.nth16) + sizeof(ctx->rx_ncm.ndp16))) {
+ pr_debug("frame too short\n");
+ goto error;
+ }
+
+ memcpy(&(ctx->rx_ncm.nth16), ((u8 *)skb_in->data),
+ sizeof(ctx->rx_ncm.nth16));
+
+ if (le32_to_cpu(ctx->rx_ncm.nth16.dwSignature) !=
+ USB_CDC_NCM_NTH16_SIGN) {
+ pr_debug("invalid NTH16 signature <%u>\n",
+ le32_to_cpu(ctx->rx_ncm.nth16.dwSignature));
+ goto error;
+ }
+
+ temp = le16_to_cpu(ctx->rx_ncm.nth16.wBlockLength);
+ if (temp > sumlen) {
+ pr_debug("unsupported NTB block length %u/%u\n", temp, sumlen);
+ goto error;
+ }
+
+ temp = le16_to_cpu(ctx->rx_ncm.nth16.wFpIndex);
+ if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) {
+ pr_debug("invalid DPT16 index\n");
+ goto error;
+ }
+
+ memcpy(&(ctx->rx_ncm.ndp16), ((u8 *)skb_in->data) + temp,
+ sizeof(ctx->rx_ncm.ndp16));
+
+ if (le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature) !=
+ USB_CDC_NCM_NDP16_NOCRC_SIGN) {
+ pr_debug("invalid DPT16 signature <%u>\n",
+ le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature));
+ goto error;
+ }
+
+ if (le16_to_cpu(ctx->rx_ncm.ndp16.wLength) <
+ USB_CDC_NCM_NDP16_LENGTH_MIN) {
+ pr_debug("invalid DPT16 length <%u>\n",
+ le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature));
+ goto error;
+ }
+
+ nframes = ((le16_to_cpu(ctx->rx_ncm.ndp16.wLength) -
+ sizeof(struct usb_cdc_ncm_ndp16)) /
+ sizeof(struct usb_cdc_ncm_dpe16));
+ nframes--; /* we process NDP entries except for the last one */
+
+ pr_debug("nframes = %u\n", nframes);
+
+ temp += sizeof(ctx->rx_ncm.ndp16);
+
+ if ((temp + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > actlen) {
+ pr_debug("Invalid nframes = %d\n", nframes);
+ goto error;
+ }
+
+ if (nframes > CDC_NCM_DPT_DATAGRAMS_MAX) {
+ pr_debug("Truncating number of frames from %u to %u\n",
+ nframes, CDC_NCM_DPT_DATAGRAMS_MAX);
+ nframes = CDC_NCM_DPT_DATAGRAMS_MAX;
+ }
+
+ memcpy(&(ctx->rx_ncm.dpe16), ((u8 *)skb_in->data) + temp,
+ nframes * (sizeof(struct usb_cdc_ncm_dpe16)));
+
+ for (x = 0; x < nframes; x++) {
+ offset = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramIndex);
+ temp = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramLength);
+
+ /*
+ * CDC NCM ch. 3.7
+ * All entries after first NULL entry are to be ignored
+ */
+ if ((offset == 0) || (temp == 0)) {
+ if (!x)
+ goto error; /* empty NTB */
+ break;
+ }
+
+ /* sanity checking */
+ if (((offset + temp) > actlen) ||
+ (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) {
+ pr_debug("invalid frame detected (ignored)"
+ "offset[%u]=%u, length=%u, skb=%p\n",
+ x, offset, temp, skb);
+ if (!x)
+ goto error;
+ break;
+
+ } else {
+ skb = skb_clone(skb_in, GFP_ATOMIC);
+ skb->len = temp;
+ skb->data = ((u8 *)skb_in->data) + offset;
+ skb_set_tail_pointer(skb, temp);
+ usbnet_skb_return(dev, skb);
+ }
+ }
+ return 1;
+error:
+ return 0;
+}
+
+static void
+cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx,
+ struct connection_speed_change *data)
+{
+ uint32_t rx_speed = le32_to_cpu(data->USBitRate);
+ uint32_t tx_speed = le32_to_cpu(data->DSBitRate);
+
+ /*
+ * Currently the USB-NET API does not support reporting the actual
+ * device speed. Do print it instead.
+ */
+ if ((tx_speed != ctx->tx_speed) || (rx_speed != ctx->rx_speed)) {
+ ctx->tx_speed = tx_speed;
+ ctx->rx_speed = rx_speed;
+
+ if ((tx_speed > 1000000) && (rx_speed > 1000000)) {
+ printk(KERN_INFO KBUILD_MODNAME
+ ": %s: %u mbit/s downlink "
+ "%u mbit/s uplink\n",
+ ctx->netdev->name,
+ (unsigned int)(rx_speed / 1000000U),
+ (unsigned int)(tx_speed / 1000000U));
+ } else {
+ printk(KERN_INFO KBUILD_MODNAME
+ ": %s: %u kbit/s downlink "
+ "%u kbit/s uplink\n",
+ ctx->netdev->name,
+ (unsigned int)(rx_speed / 1000U),
+ (unsigned int)(tx_speed / 1000U));
+ }
+ }
+}
+
+static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
+{
+ struct cdc_ncm_ctx *ctx;
+ struct usb_cdc_notification *event;
+
+ ctx = (struct cdc_ncm_ctx *)dev->data[0];
+
+ if (urb->actual_length < sizeof(*event))
+ return;
+
+ /* test for split data in 8-byte chunks */
+ if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
+ cdc_ncm_speed_change(ctx,
+ (struct connection_speed_change *)urb->transfer_buffer);
+ return;
+ }
+
+ event = urb->transfer_buffer;
+
+ switch (event->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ /*
+ * According to the CDC NCM specification ch.7.1
+ * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
+ * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE.
+ */
+ ctx->connected = event->wValue;
+
+ printk(KERN_INFO KBUILD_MODNAME ": %s: network connection:"
+ " %sconnected\n",
+ ctx->netdev->name, ctx->connected ? "" : "dis");
+
+ if (ctx->connected)
+ netif_carrier_on(dev->net);
+ else {
+ netif_carrier_off(dev->net);
+ ctx->tx_speed = ctx->rx_speed = 0;
+ }
+ break;
+
+ case USB_CDC_NOTIFY_SPEED_CHANGE:
+ if (urb->actual_length <
+ (sizeof(*event) + sizeof(struct connection_speed_change)))
+ set_bit(EVENT_STS_SPLIT, &dev->flags);
+ else
+ cdc_ncm_speed_change(ctx,
+ (struct connection_speed_change *) &event[1]);
+ break;
+
+ default:
+ dev_err(&dev->udev->dev, "NCM: unexpected "
+ "notification 0x%02x!\n", event->bNotificationType);
+ break;
+ }
+}
+
+static int cdc_ncm_check_connect(struct usbnet *dev)
+{
+ struct cdc_ncm_ctx *ctx;
+
+ ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ if (ctx == NULL)
+ return 1; /* disconnected */
+
+ return !ctx->connected;
+}
+
+static int
+cdc_ncm_probe(struct usb_interface *udev, const struct usb_device_id *prod)
+{
+ return usbnet_probe(udev, prod);
+}
+
+static void cdc_ncm_disconnect(struct usb_interface *intf)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+
+ if (dev == NULL)
+ return; /* already disconnected */
+
+ usbnet_disconnect(intf);
+}
+
+static int cdc_ncm_manage_power(struct usbnet *dev, int status)
+{
+ dev->intf->needs_remote_wakeup = status;
+ return 0;
+}
+
+static const struct driver_info cdc_ncm_info = {
+ .description = "CDC NCM",
+ .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET,
+ .bind = cdc_ncm_bind,
+ .unbind = cdc_ncm_unbind,
+ .check_connect = cdc_ncm_check_connect,
+ .manage_power = cdc_ncm_manage_power,
+ .status = cdc_ncm_status,
+ .rx_fixup = cdc_ncm_rx_fixup,
+ .tx_fixup = cdc_ncm_tx_fixup,
+};
+
+static struct usb_driver cdc_ncm_driver = {
+ .name = "cdc_ncm",
+ .id_table = cdc_devs,
+ .probe = cdc_ncm_probe,
+ .disconnect = cdc_ncm_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .supports_autosuspend = 1,
+};
+
+static struct ethtool_ops cdc_ncm_ethtool_ops = {
+ .get_drvinfo = cdc_ncm_get_drvinfo,
+ .get_link = usbnet_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,
+};
+
+static int __init cdc_ncm_init(void)
+{
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION "\n");
+ return usb_register(&cdc_ncm_driver);
+}
+
+module_init(cdc_ncm_init);
+
+static void __exit cdc_ncm_exit(void)
+{
+ usb_deregister(&cdc_ncm_driver);
+}
+
+module_exit(cdc_ncm_exit);
+
+MODULE_AUTHOR("Hans Petter Selasky");
+MODULE_DESCRIPTION("USB CDC NCM host driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 62e9e8dc8190..bed8fcedff49 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
/* Packet is complete. Inject into stack. */
/* We have IP packet here */
odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
- /* don't check it */
- odev->skb_rx_buf->ip_summed =
- CHECKSUM_UNNECESSARY;
-
skb_reset_mac_header(odev->skb_rx_buf);
/* Ship it off to the kernel */
@@ -1001,6 +997,18 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
}
}
+static void fix_crc_bug(struct urb *urb, __le16 max_packet_size)
+{
+ static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+ u32 rest = urb->actual_length % le16_to_cpu(max_packet_size);
+
+ if (((rest == 5) || (rest == 6)) &&
+ !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4,
+ crc_check, 4)) {
+ urb->actual_length -= 4;
+ }
+}
+
/* Moving data from usb to kernel (in interrupt state) */
static void read_bulk_callback(struct urb *urb)
{
@@ -1029,17 +1037,8 @@ static void read_bulk_callback(struct urb *urb)
return;
}
- if (odev->parent->port_spec & HSO_INFO_CRC_BUG) {
- u32 rest;
- u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
- rest = urb->actual_length %
- le16_to_cpu(odev->in_endp->wMaxPacketSize);
- if (((rest == 5) || (rest == 6)) &&
- !memcmp(((u8 *) urb->transfer_buffer) +
- urb->actual_length - 4, crc_check, 4)) {
- urb->actual_length -= 4;
- }
- }
+ if (odev->parent->port_spec & HSO_INFO_CRC_BUG)
+ fix_crc_bug(urb, odev->in_endp->wMaxPacketSize);
/* do we even have a packet? */
if (urb->actual_length) {
@@ -1231,18 +1230,8 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
return;
if (status == 0) {
- if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
- u32 rest;
- u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
- rest =
- urb->actual_length %
- le16_to_cpu(serial->in_endp->wMaxPacketSize);
- if (((rest == 5) || (rest == 6)) &&
- !memcmp(((u8 *) urb->transfer_buffer) +
- urb->actual_length - 4, crc_check, 4)) {
- urb->actual_length -= 4;
- }
- }
+ if (serial->parent->port_spec & HSO_INFO_CRC_BUG)
+ fix_crc_bug(urb, serial->in_endp->wMaxPacketSize);
/* Valid data, handle RX data */
spin_lock(&serial->serial_lock);
serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
@@ -1745,7 +1734,6 @@ static int hso_serial_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct hso_serial *serial = get_serial_by_tty(tty);
- void __user *uarg = (void __user *)arg;
int ret = 0;
D4("IOCTL cmd: %d, arg: %ld", cmd, arg);
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index b2bcf99e6f08..7d42f9a2c068 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -363,7 +363,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
/* Paranoid */
if (skb->len > IPHETH_BUF_SIZE) {
- WARN(1, "%s: skb too large: %d bytes", __func__, skb->len);
+ WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
dev->net->stats.tx_dropped++;
dev_kfree_skb_irq(skb);
return NETDEV_TX_OK;
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index a6281e3987b5..2b791392e788 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -1,5 +1,5 @@
/*
- * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices
+ * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices
*
* based on usbnet.c, asix.c and the vendor provided mcs7830 driver
*
@@ -11,6 +11,9 @@
*
* Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!).
*
+ * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"),
+ * per active notification by manufacturer
+ *
* TODO:
* - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?)
* - implement ethtool_ops get_pauseparam/set_pauseparam
@@ -60,6 +63,7 @@
#define MCS7830_MAX_MCAST 64
#define MCS7830_VENDOR_ID 0x9710
+#define MCS7832_PRODUCT_ID 0x7832
#define MCS7830_PRODUCT_ID 0x7830
#define MCS7730_PRODUCT_ID 0x7730
@@ -351,7 +355,7 @@ static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode)
if (!ret)
ret = mcs7830_write_phy(dev, MII_BMCR,
BMCR_ANENABLE | BMCR_ANRESTART );
- return ret < 0 ? : 0;
+ return ret;
}
@@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static const struct driver_info moschip_info = {
- .description = "MOSCHIP 7830/7730 usb-NET adapter",
+ .description = "MOSCHIP 7830/7832/7730 usb-NET adapter",
.bind = mcs7830_bind,
.rx_fixup = mcs7830_rx_fixup,
.flags = FLAG_ETHER,
@@ -645,6 +649,10 @@ static const struct driver_info sitecom_info = {
static const struct usb_device_id products[] = {
{
+ USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID),
+ .driver_info = (unsigned long) &moschip_info,
+ },
+ {
USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
.driver_info = (unsigned long) &moschip_info,
},
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 6710f09346d6..ef3667690b12 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -359,7 +359,7 @@ fail:
static int mdio_read(struct net_device *dev, int phy_id, int loc)
{
- pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev);
+ pegasus_t *pegasus = netdev_priv(dev);
u16 res;
read_mii_word(pegasus, phy_id, loc, &res);
@@ -397,7 +397,7 @@ fail:
static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
{
- pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev);
+ pegasus_t *pegasus = netdev_priv(dev);
write_mii_word(pegasus, phy_id, loc, val);
}
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index d1ac15c95faf..ed1b43210584 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -802,10 +802,9 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
dev_dbg(&dev->udev->dev, "%s", __func__);
- /* Kill the timer then flush the work queue */
+ /* kill the timer and work */
del_timer_sync(&priv->sync_timer);
-
- flush_scheduled_work();
+ cancel_work_sync(&priv->sierra_net_kevent);
/* tell modem we are going away */
status = sierra_net_send_cmd(dev, priv->shdwn_msg,
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 65cb1abfbe57..bc86f4b6ecc2 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1163,9 +1163,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
{
- int len = skb->data - skb->head;
- u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len);
- u16 low_16 = (u16)(skb->csum_start - len);
+ u16 low_16 = (u16)skb_checksum_start_offset(skb);
+ u16 high_16 = low_16 + skb->csum_offset;
return (high_16 << 16) | low_16;
}
@@ -1193,7 +1192,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
if (skb->len <= 45) {
/* workaround - hardware tx checksum does not work
* properly with extremely small packets */
- long csstart = skb->csum_start - skb_headroom(skb);
+ long csstart = skb_checksum_start_offset(skb);
__wsum calc = csum_partial(skb->data + csstart,
skb->len - csstart, 0);
*((__sum16 *)(skb->data + csstart
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index c04d49e31f81..ed9a41643ff4 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -391,14 +391,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
goto error;
// else network stack removes extra byte if we forced a short packet
- if (skb->len)
- usbnet_skb_return (dev, skb);
- else {
- netif_dbg(dev, rx_err, dev->net, "drop\n");
-error:
- dev->net->stats.rx_errors++;
- skb_queue_tail (&dev->done, skb);
+ if (skb->len) {
+ /* all data was already cloned from skb inside the driver */
+ if (dev->driver_info->flags & FLAG_MULTI_PACKET)
+ dev_kfree_skb_any(skb);
+ else
+ usbnet_skb_return(dev, skb);
+ return;
}
+
+ netif_dbg(dev, rx_err, dev->net, "drop\n");
+error:
+ dev->net->stats.rx_errors++;
+ skb_queue_tail(&dev->done, skb);
}
/*-------------------------------------------------------------------------*/
@@ -971,7 +976,8 @@ static void tx_complete (struct urb *urb)
struct usbnet *dev = entry->dev;
if (urb->status == 0) {
- dev->net->stats.tx_packets++;
+ if (!(dev->driver_info->flags & FLAG_MULTI_PACKET))
+ dev->net->stats.tx_packets++;
dev->net->stats.tx_bytes += entry->length;
} else {
dev->net->stats.tx_errors++;
@@ -1044,8 +1050,13 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
if (info->tx_fixup) {
skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
if (!skb) {
- netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
- goto drop;
+ if (netif_msg_tx_err(dev)) {
+ netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
+ goto drop;
+ } else {
+ /* cdc_ncm collected packet; waits for more */
+ goto not_drop;
+ }
}
}
length = skb->len;
@@ -1067,13 +1078,18 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
/* don't assume the hardware handles USB_ZERO_PACKET
* NOTE: strictly conforming cdc-ether devices should expect
* the ZLP here, but ignore the one-byte packet.
+ * NOTE2: CDC NCM specification is different from CDC ECM when
+ * handling ZLP/short packets, so cdc_ncm driver will make short
+ * packet itself if needed.
*/
if (length % dev->maxpacket == 0) {
if (!(info->flags & FLAG_SEND_ZLP)) {
- urb->transfer_buffer_length++;
- if (skb_tailroom(skb)) {
- skb->data[skb->len] = 0;
- __skb_put(skb, 1);
+ if (!(info->flags & FLAG_MULTI_PACKET)) {
+ urb->transfer_buffer_length++;
+ if (skb_tailroom(skb)) {
+ skb->data[skb->len] = 0;
+ __skb_put(skb, 1);
+ }
}
} else
urb->transfer_flags |= URB_ZERO_PACKET;
@@ -1122,6 +1138,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval);
drop:
dev->net->stats.tx_dropped++;
+not_drop:
if (skb)
dev_kfree_skb_any (skb);
usb_free_urb (urb);
@@ -1231,8 +1248,7 @@ void usbnet_disconnect (struct usb_interface *intf)
net = dev->net;
unregister_netdev (net);
- /* we don't hold rtnl here ... */
- flush_scheduled_work ();
+ cancel_work_sync(&dev->kevent);
if (dev->driver_info->unbind)
dev->driver_info->unbind (dev, intf);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 0bbc0c323135..cc83fa71c3ff 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -166,7 +166,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(rcv->flags & IFF_UP))
goto tx_drop;
- if (dev->features & NETIF_F_NO_CSUM)
+ /* don't change ip_summed == CHECKSUM_PARTIAL, as that
+ will cause bad checksum on forwarded packets */
+ if (skb->ip_summed == CHECKSUM_NONE)
skb->ip_summed = rcv_priv->ip_summed;
length = skb->len + ETH_HLEN;
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 4930f9dbc493..5e7f069eab53 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -30,8 +30,8 @@
*/
#define DRV_NAME "via-rhine"
-#define DRV_VERSION "1.4.3"
-#define DRV_RELDATE "2007-03-06"
+#define DRV_VERSION "1.5.0"
+#define DRV_RELDATE "2010-10-09"
/* A few user-configurable values.
@@ -100,6 +100,7 @@ static const int multicast_filter_limit = 32;
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
+#include <linux/if_vlan.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
@@ -133,6 +134,9 @@ MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
+#define MCAM_SIZE 32
+#define VCAM_SIZE 32
+
/*
Theory of Operation
@@ -279,15 +283,16 @@ MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
/* Offsets to the device registers. */
enum register_offsets {
StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
- ChipCmd1=0x09,
+ ChipCmd1=0x09, TQWake=0x0A,
IntrStatus=0x0C, IntrEnable=0x0E,
MulticastFilter0=0x10, MulticastFilter1=0x14,
RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
- MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
+ MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, PCIBusConfig1=0x6F,
MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
StickyHW=0x83, IntrStatus2=0x84,
+ CamMask=0x88, CamCon=0x92, CamAddr=0x93,
WOLcrSet=0xA0, PwcfgSet=0xA1, WOLcgSet=0xA3, WOLcrClr=0xA4,
WOLcrClr1=0xA6, WOLcgClr=0xA7,
PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
@@ -299,6 +304,40 @@ enum backoff_bits {
BackCaptureEffect=0x04, BackRandom=0x08
};
+/* Bits in the TxConfig (TCR) register */
+enum tcr_bits {
+ TCR_PQEN=0x01,
+ TCR_LB0=0x02, /* loopback[0] */
+ TCR_LB1=0x04, /* loopback[1] */
+ TCR_OFSET=0x08,
+ TCR_RTGOPT=0x10,
+ TCR_RTFT0=0x20,
+ TCR_RTFT1=0x40,
+ TCR_RTSF=0x80,
+};
+
+/* Bits in the CamCon (CAMC) register */
+enum camcon_bits {
+ CAMC_CAMEN=0x01,
+ CAMC_VCAMSL=0x02,
+ CAMC_CAMWR=0x04,
+ CAMC_CAMRD=0x08,
+};
+
+/* Bits in the PCIBusConfig1 (BCR1) register */
+enum bcr1_bits {
+ BCR1_POT0=0x01,
+ BCR1_POT1=0x02,
+ BCR1_POT2=0x04,
+ BCR1_CTFT0=0x08,
+ BCR1_CTFT1=0x10,
+ BCR1_CTSF=0x20,
+ BCR1_TXQNOBK=0x40, /* for VT6105 */
+ BCR1_VIDFR=0x80, /* for VT6105 */
+ BCR1_MED0=0x40, /* for VT6102 */
+ BCR1_MED1=0x80, /* for VT6102 */
+};
+
#ifdef USE_MMIO
/* Registers we check that mmio and reg are the same. */
static const int mmio_verify_registers[] = {
@@ -356,6 +395,11 @@ enum desc_status_bits {
DescOwn=0x80000000
};
+/* Bits in *_desc.*_length */
+enum desc_length_bits {
+ DescTag=0x00010000
+};
+
/* Bits in ChipCmd. */
enum chip_cmd_bits {
CmdInit=0x01, CmdStart=0x02, CmdStop=0x04, CmdRxOn=0x08,
@@ -365,6 +409,9 @@ enum chip_cmd_bits {
};
struct rhine_private {
+ /* Bit mask for configured VLAN ids */
+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+
/* Descriptor rings */
struct rx_desc *rx_ring;
struct tx_desc *tx_ring;
@@ -405,6 +452,23 @@ struct rhine_private {
void __iomem *base;
};
+#define BYTE_REG_BITS_ON(x, p) do { iowrite8((ioread8((p))|(x)), (p)); } while (0)
+#define WORD_REG_BITS_ON(x, p) do { iowrite16((ioread16((p))|(x)), (p)); } while (0)
+#define DWORD_REG_BITS_ON(x, p) do { iowrite32((ioread32((p))|(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_IS_ON(x, p) (ioread8((p)) & (x))
+#define WORD_REG_BITS_IS_ON(x, p) (ioread16((p)) & (x))
+#define DWORD_REG_BITS_IS_ON(x, p) (ioread32((p)) & (x))
+
+#define BYTE_REG_BITS_OFF(x, p) do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0)
+#define WORD_REG_BITS_OFF(x, p) do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0)
+#define DWORD_REG_BITS_OFF(x, p) do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_SET(x, m, p) do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0)
+#define WORD_REG_BITS_SET(x, m, p) do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0)
+#define DWORD_REG_BITS_SET(x, m, p) do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0)
+
+
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
@@ -422,6 +486,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static const struct ethtool_ops netdev_ethtool_ops;
static int rhine_close(struct net_device *dev);
static void rhine_shutdown (struct pci_dev *pdev);
+static void rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
+static void rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
+static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr);
+static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr);
+static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask);
+static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask);
+static void rhine_init_cam_filter(struct net_device *dev);
+static void rhine_update_vcam(struct net_device *dev);
#define RHINE_WAIT_FOR(condition) do { \
int i=1024; \
@@ -629,6 +701,8 @@ static const struct net_device_ops rhine_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = netdev_ioctl,
.ndo_tx_timeout = rhine_tx_timeout,
+ .ndo_vlan_rx_add_vid = rhine_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = rhine_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = rhine_poll,
#endif
@@ -795,6 +869,10 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+ if (pdev->revision >= VT6105M)
+ dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
+
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
@@ -1040,6 +1118,167 @@ static void rhine_set_carrier(struct mii_if_info *mii)
netif_carrier_ok(mii->dev));
}
+/**
+ * rhine_set_cam - set CAM multicast filters
+ * @ioaddr: register block of this Rhine
+ * @idx: multicast CAM index [0..MCAM_SIZE-1]
+ * @addr: multicast address (6 bytes)
+ *
+ * Load addresses into multicast filters.
+ */
+static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr)
+{
+ int i;
+
+ iowrite8(CAMC_CAMEN, ioaddr + CamCon);
+ wmb();
+
+ /* Paranoid -- idx out of range should never happen */
+ idx &= (MCAM_SIZE - 1);
+
+ iowrite8((u8) idx, ioaddr + CamAddr);
+
+ for (i = 0; i < 6; i++, addr++)
+ iowrite8(*addr, ioaddr + MulticastFilter0 + i);
+ udelay(10);
+ wmb();
+
+ iowrite8(CAMC_CAMWR | CAMC_CAMEN, ioaddr + CamCon);
+ udelay(10);
+
+ iowrite8(0, ioaddr + CamCon);
+}
+
+/**
+ * rhine_set_vlan_cam - set CAM VLAN filters
+ * @ioaddr: register block of this Rhine
+ * @idx: VLAN CAM index [0..VCAM_SIZE-1]
+ * @addr: VLAN ID (2 bytes)
+ *
+ * Load addresses into VLAN filters.
+ */
+static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr)
+{
+ iowrite8(CAMC_CAMEN | CAMC_VCAMSL, ioaddr + CamCon);
+ wmb();
+
+ /* Paranoid -- idx out of range should never happen */
+ idx &= (VCAM_SIZE - 1);
+
+ iowrite8((u8) idx, ioaddr + CamAddr);
+
+ iowrite16(*((u16 *) addr), ioaddr + MulticastFilter0 + 6);
+ udelay(10);
+ wmb();
+
+ iowrite8(CAMC_CAMWR | CAMC_CAMEN, ioaddr + CamCon);
+ udelay(10);
+
+ iowrite8(0, ioaddr + CamCon);
+}
+
+/**
+ * rhine_set_cam_mask - set multicast CAM mask
+ * @ioaddr: register block of this Rhine
+ * @mask: multicast CAM mask
+ *
+ * Mask sets multicast filters active/inactive.
+ */
+static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask)
+{
+ iowrite8(CAMC_CAMEN, ioaddr + CamCon);
+ wmb();
+
+ /* write mask */
+ iowrite32(mask, ioaddr + CamMask);
+
+ /* disable CAMEN */
+ iowrite8(0, ioaddr + CamCon);
+}
+
+/**
+ * rhine_set_vlan_cam_mask - set VLAN CAM mask
+ * @ioaddr: register block of this Rhine
+ * @mask: VLAN CAM mask
+ *
+ * Mask sets VLAN filters active/inactive.
+ */
+static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask)
+{
+ iowrite8(CAMC_CAMEN | CAMC_VCAMSL, ioaddr + CamCon);
+ wmb();
+
+ /* write mask */
+ iowrite32(mask, ioaddr + CamMask);
+
+ /* disable CAMEN */
+ iowrite8(0, ioaddr + CamCon);
+}
+
+/**
+ * rhine_init_cam_filter - initialize CAM filters
+ * @dev: network device
+ *
+ * Initialize (disable) hardware VLAN and multicast support on this
+ * Rhine.
+ */
+static void rhine_init_cam_filter(struct net_device *dev)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+ void __iomem *ioaddr = rp->base;
+
+ /* Disable all CAMs */
+ rhine_set_vlan_cam_mask(ioaddr, 0);
+ rhine_set_cam_mask(ioaddr, 0);
+
+ /* disable hardware VLAN support */
+ BYTE_REG_BITS_ON(TCR_PQEN, ioaddr + TxConfig);
+ BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1);
+}
+
+/**
+ * rhine_update_vcam - update VLAN CAM filters
+ * @rp: rhine_private data of this Rhine
+ *
+ * Update VLAN CAM filters to match configuration change.
+ */
+static void rhine_update_vcam(struct net_device *dev)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+ void __iomem *ioaddr = rp->base;
+ u16 vid;
+ u32 vCAMmask = 0; /* 32 vCAMs (6105M and better) */
+ unsigned int i = 0;
+
+ for_each_set_bit(vid, rp->active_vlans, VLAN_N_VID) {
+ rhine_set_vlan_cam(ioaddr, i, (u8 *)&vid);
+ vCAMmask |= 1 << i;
+ if (++i >= VCAM_SIZE)
+ break;
+ }
+ rhine_set_vlan_cam_mask(ioaddr, vCAMmask);
+}
+
+static void rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+
+ spin_lock_irq(&rp->lock);
+ set_bit(vid, rp->active_vlans);
+ rhine_update_vcam(dev);
+ spin_unlock_irq(&rp->lock);
+}
+
+static void rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+
+ spin_lock_irq(&rp->lock);
+ clear_bit(vid, rp->active_vlans);
+ rhine_update_vcam(dev);
+ spin_unlock_irq(&rp->lock);
+}
+
static void init_registers(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
@@ -1061,6 +1300,9 @@ static void init_registers(struct net_device *dev)
rhine_set_rx_mode(dev);
+ if (rp->pdev->revision >= VT6105M)
+ rhine_init_cam_filter(dev);
+
napi_enable(&rp->napi);
/* Enable interrupts by setting the interrupt mask. */
@@ -1276,16 +1518,28 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
rp->tx_ring[entry].desc_length =
cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+ if (unlikely(vlan_tx_tag_present(skb))) {
+ rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16);
+ /* request tagging */
+ rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000);
+ }
+ else
+ rp->tx_ring[entry].tx_status = 0;
+
/* lock eth irq */
spin_lock_irqsave(&rp->lock, flags);
wmb();
- rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
+ rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn);
wmb();
rp->cur_tx++;
/* Non-x86 Todo: explicitly flush cache lines here. */
+ if (vlan_tx_tag_present(skb))
+ /* Tx queues are bits 7-0 (first Tx queue: bit 7) */
+ BYTE_REG_BITS_ON(1 << 7, ioaddr + TQWake);
+
/* Wake the potentially-idle transmit channel */
iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand,
ioaddr + ChipCmd1);
@@ -1437,6 +1691,21 @@ static void rhine_tx(struct net_device *dev)
spin_unlock(&rp->lock);
}
+/**
+ * rhine_get_vlan_tci - extract TCI from Rx data buffer
+ * @skb: pointer to sk_buff
+ * @data_size: used data area of the buffer including CRC
+ *
+ * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q
+ * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte
+ * aligned following the CRC.
+ */
+static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
+{
+ u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
+ return ntohs(*(u16 *)trailer);
+}
+
/* Process up to limit frames from receive ring */
static int rhine_rx(struct net_device *dev, int limit)
{
@@ -1454,6 +1723,7 @@ static int rhine_rx(struct net_device *dev, int limit)
for (count = 0; count < limit; ++count) {
struct rx_desc *desc = rp->rx_head_desc;
u32 desc_status = le32_to_cpu(desc->rx_status);
+ u32 desc_length = le32_to_cpu(desc->desc_length);
int data_size = desc_status >> 16;
if (desc_status & DescOwn)
@@ -1498,6 +1768,7 @@ static int rhine_rx(struct net_device *dev, int limit)
struct sk_buff *skb = NULL;
/* Length should omit the CRC */
int pkt_len = data_size - 4;
+ u16 vlan_tci = 0;
/* Check if the packet is long enough to accept without
copying to a minimally-sized skbuff. */
@@ -1532,7 +1803,14 @@ static int rhine_rx(struct net_device *dev, int limit)
rp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
}
+
+ if (unlikely(desc_length & DescTag))
+ vlan_tci = rhine_get_vlan_tci(skb, data_size);
+
skb->protocol = eth_type_trans(skb, dev);
+
+ if (unlikely(desc_length & DescTag))
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
netif_receive_skb(skb);
dev->stats.rx_bytes += pkt_len;
dev->stats.rx_packets++;
@@ -1596,6 +1874,11 @@ static void rhine_restart_tx(struct net_device *dev) {
iowrite8(ioread8(ioaddr + ChipCmd) | CmdTxOn,
ioaddr + ChipCmd);
+
+ if (rp->tx_ring[entry].desc_length & cpu_to_le32(0x020000))
+ /* Tx queues are bits 7-0 (first Tx queue: bit 7) */
+ BYTE_REG_BITS_ON(1 << 7, ioaddr + TQWake);
+
iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand,
ioaddr + ChipCmd1);
IOSYNC;
@@ -1631,7 +1914,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
}
if (intr_status & IntrTxUnderrun) {
if (rp->tx_thresh < 0xE0)
- iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig);
+ BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
if (debug > 1)
printk(KERN_INFO "%s: Transmitter underrun, Tx "
"threshold now %2.2x.\n",
@@ -1646,7 +1929,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
(intr_status & (IntrTxAborted |
IntrTxUnderrun | IntrTxDescRace)) == 0) {
if (rp->tx_thresh < 0xE0) {
- iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig);
+ BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
}
if (debug > 1)
printk(KERN_INFO "%s: Unspecified error. Tx "
@@ -1688,7 +1971,8 @@ static void rhine_set_rx_mode(struct net_device *dev)
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
u32 mc_filter[2]; /* Multicast hash filter */
- u8 rx_mode; /* Note: 0x02=accept runt, 0x01=accept errs */
+ u8 rx_mode = 0x0C; /* Note: 0x02=accept runt, 0x01=accept errs */
+ struct netdev_hw_addr *ha;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
rx_mode = 0x1C;
@@ -1699,10 +1983,18 @@ static void rhine_set_rx_mode(struct net_device *dev)
/* Too many to match, or accept all multicasts. */
iowrite32(0xffffffff, ioaddr + MulticastFilter0);
iowrite32(0xffffffff, ioaddr + MulticastFilter1);
- rx_mode = 0x0C;
+ } else if (rp->pdev->revision >= VT6105M) {
+ int i = 0;
+ u32 mCAMmask = 0; /* 32 mCAMs (6105M and better) */
+ netdev_for_each_mc_addr(ha, dev) {
+ if (i == MCAM_SIZE)
+ break;
+ rhine_set_cam(ioaddr, i, ha->addr);
+ mCAMmask |= 1 << i;
+ i++;
+ }
+ rhine_set_cam_mask(ioaddr, mCAMmask);
} else {
- struct netdev_hw_addr *ha;
-
memset(mc_filter, 0, sizeof(mc_filter));
netdev_for_each_mc_addr(ha, dev) {
int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
@@ -1711,9 +2003,15 @@ static void rhine_set_rx_mode(struct net_device *dev)
}
iowrite32(mc_filter[0], ioaddr + MulticastFilter0);
iowrite32(mc_filter[1], ioaddr + MulticastFilter1);
- rx_mode = 0x0C;
}
- iowrite8(rp->rx_thresh | rx_mode, ioaddr + RxConfig);
+ /* enable/disable VLAN receive filtering */
+ if (rp->pdev->revision >= VT6105M) {
+ if (dev->flags & IFF_PROMISC)
+ BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1);
+ else
+ BYTE_REG_BITS_ON(BCR1_VIDFR, ioaddr + PCIBusConfig1);
+ }
+ BYTE_REG_BITS_ON(rx_mode, ioaddr + RxConfig);
}
static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -1966,7 +2264,7 @@ static int rhine_resume(struct pci_dev *pdev)
if (!netif_running(dev))
return 0;
- if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
+ if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
ret = pci_set_power_state(pdev, PCI_D0);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b6d402806ae6..90a23e410d1b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -519,7 +519,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
if (skb->ip_summed == CHECKSUM_PARTIAL) {
hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- hdr->hdr.csum_start = skb->csum_start - skb_headroom(skb);
+ hdr->hdr.csum_start = skb_checksum_start_offset(skb);
hdr->hdr.csum_offset = skb->csum_offset;
} else {
hdr->hdr.flags = 0;
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 21314e06e6d7..d143e8b72b5b 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -44,6 +44,9 @@ MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table);
static atomic_t devices_found;
+#define VMXNET3_MAX_DEVICES 10
+static int enable_mq = 1;
+static int irq_share_mode;
/*
* Enable/Disable the given intr
@@ -99,7 +102,7 @@ vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events)
static bool
vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
{
- return netif_queue_stopped(adapter->netdev);
+ return tq->stopped;
}
@@ -107,7 +110,7 @@ static void
vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
{
tq->stopped = false;
- netif_start_queue(adapter->netdev);
+ netif_start_subqueue(adapter->netdev, tq - adapter->tx_queue);
}
@@ -115,7 +118,7 @@ static void
vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
{
tq->stopped = false;
- netif_wake_queue(adapter->netdev);
+ netif_wake_subqueue(adapter->netdev, (tq - adapter->tx_queue));
}
@@ -124,7 +127,7 @@ vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
{
tq->stopped = true;
tq->num_stop++;
- netif_stop_queue(adapter->netdev);
+ netif_stop_subqueue(adapter->netdev, (tq - adapter->tx_queue));
}
@@ -135,6 +138,7 @@ static void
vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
{
u32 ret;
+ int i;
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
@@ -145,22 +149,28 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
if (!netif_carrier_ok(adapter->netdev))
netif_carrier_on(adapter->netdev);
- if (affectTxQueue)
- vmxnet3_tq_start(&adapter->tx_queue, adapter);
+ if (affectTxQueue) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_start(&adapter->tx_queue[i],
+ adapter);
+ }
} else {
printk(KERN_INFO "%s: NIC Link is Down\n",
adapter->netdev->name);
if (netif_carrier_ok(adapter->netdev))
netif_carrier_off(adapter->netdev);
- if (affectTxQueue)
- vmxnet3_tq_stop(&adapter->tx_queue, adapter);
+ if (affectTxQueue) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_stop(&adapter->tx_queue[i], adapter);
+ }
}
}
static void
vmxnet3_process_events(struct vmxnet3_adapter *adapter)
{
+ int i;
u32 events = le32_to_cpu(adapter->shared->ecr);
if (!events)
return;
@@ -176,16 +186,18 @@ vmxnet3_process_events(struct vmxnet3_adapter *adapter)
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
VMXNET3_CMD_GET_QUEUE_STATUS);
- if (adapter->tqd_start->status.stopped) {
- printk(KERN_ERR "%s: tq error 0x%x\n",
- adapter->netdev->name,
- le32_to_cpu(adapter->tqd_start->status.error));
- }
- if (adapter->rqd_start->status.stopped) {
- printk(KERN_ERR "%s: rq error 0x%x\n",
- adapter->netdev->name,
- adapter->rqd_start->status.error);
- }
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ if (adapter->tqd_start[i].status.stopped)
+ dev_err(&adapter->netdev->dev,
+ "%s: tq[%d] error 0x%x\n",
+ adapter->netdev->name, i, le32_to_cpu(
+ adapter->tqd_start[i].status.error));
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ if (adapter->rqd_start[i].status.stopped)
+ dev_err(&adapter->netdev->dev,
+ "%s: rq[%d] error 0x%x\n",
+ adapter->netdev->name, i,
+ adapter->rqd_start[i].status.error);
schedule_work(&adapter->work);
}
@@ -410,7 +422,7 @@ vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq,
}
-void
+static void
vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
struct vmxnet3_adapter *adapter)
{
@@ -437,6 +449,17 @@ vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
}
+/* Destroy all tx queues */
+void
+vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_destroy(&adapter->tx_queue[i], adapter);
+}
+
+
static void
vmxnet3_tq_init(struct vmxnet3_tx_queue *tq,
struct vmxnet3_adapter *adapter)
@@ -518,6 +541,14 @@ err:
return -ENOMEM;
}
+static void
+vmxnet3_tq_cleanup_all(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_cleanup(&adapter->tx_queue[i], adapter);
+}
/*
* starting from ring->next2fill, allocate rx buffers for the given ring
@@ -732,6 +763,17 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
}
+/* Init all tx queues */
+static void
+vmxnet3_tq_init_all(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_init(&adapter->tx_queue[i], adapter);
+}
+
+
/*
* parse and copy relevant protocol headers:
* For a tso pkt, relevant headers are L2/3/4 including options
@@ -756,7 +798,7 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
{
struct Vmxnet3_TxDataDesc *tdd;
- if (ctx->mss) {
+ if (ctx->mss) { /* TSO */
ctx->eth_ip_hdr_size = skb_transport_offset(skb);
ctx->l4_hdr_size = ((struct tcphdr *)
skb_transport_header(skb))->doff * 4;
@@ -765,7 +807,7 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
unsigned int pull_size;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- ctx->eth_ip_hdr_size = skb_transport_offset(skb);
+ ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb);
if (ctx->ipv4) {
struct iphdr *iph = (struct iphdr *)
@@ -903,6 +945,21 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
}
}
+ spin_lock_irqsave(&tq->tx_lock, flags);
+
+ if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) {
+ tq->stats.tx_ring_full++;
+ dev_dbg(&adapter->netdev->dev,
+ "tx queue stopped on %s, next2comp %u"
+ " next2fill %u\n", adapter->netdev->name,
+ tq->tx_ring.next2comp, tq->tx_ring.next2fill);
+
+ vmxnet3_tq_stop(tq, adapter);
+ spin_unlock_irqrestore(&tq->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+
ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter);
if (ret >= 0) {
BUG_ON(ret <= 0 && ctx.copy_size != 0);
@@ -923,21 +980,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
}
} else {
tq->stats.drop_hdr_inspect_err++;
- goto drop_pkt;
- }
-
- spin_lock_irqsave(&tq->tx_lock, flags);
-
- if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) {
- tq->stats.tx_ring_full++;
- dev_dbg(&adapter->netdev->dev,
- "tx queue stopped on %s, next2comp %u"
- " next2fill %u\n", adapter->netdev->name,
- tq->tx_ring.next2comp, tq->tx_ring.next2fill);
-
- vmxnet3_tq_stop(tq, adapter);
- spin_unlock_irqrestore(&tq->tx_lock, flags);
- return NETDEV_TX_BUSY;
+ goto unlock_drop_pkt;
}
/* fill tx descs related to addr & len */
@@ -1000,7 +1043,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
if (le32_to_cpu(tq->shared->txNumDeferred) >=
le32_to_cpu(tq->shared->txThreshold)) {
tq->shared->txNumDeferred = 0;
- VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
+ VMXNET3_WRITE_BAR0_REG(adapter,
+ VMXNET3_REG_TXPROD + tq->qid * 8,
tq->tx_ring.next2fill);
}
@@ -1008,6 +1052,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
hdr_too_big:
tq->stats.drop_oversized_hdr++;
+unlock_drop_pkt:
+ spin_unlock_irqrestore(&tq->tx_lock, flags);
drop_pkt:
tq->stats.drop_total++;
dev_kfree_skb(skb);
@@ -1020,7 +1066,10 @@ vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- return vmxnet3_tq_xmit(skb, &adapter->tx_queue, adapter, netdev);
+ BUG_ON(skb->queue_mapping > adapter->num_tx_queues);
+ return vmxnet3_tq_xmit(skb,
+ &adapter->tx_queue[skb->queue_mapping],
+ adapter, netdev);
}
@@ -1082,7 +1131,9 @@ static int
vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
struct vmxnet3_adapter *adapter, int quota)
{
- static u32 rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
+ static const u32 rxprod_reg[2] = {
+ VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2
+ };
u32 num_rxd = 0;
struct Vmxnet3_RxCompDesc *rcd;
struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
@@ -1106,9 +1157,9 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
break;
}
num_rxd++;
-
+ BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2);
idx = rcd->rxdIdx;
- ring_idx = rcd->rqID == rq->qid ? 0 : 1;
+ ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1;
vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd,
&rxCmdDesc);
rbi = rq->buf_info[ring_idx] + idx;
@@ -1260,6 +1311,16 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
}
+static void
+vmxnet3_rq_cleanup_all(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ vmxnet3_rq_cleanup(&adapter->rx_queue[i], adapter);
+}
+
+
void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
struct vmxnet3_adapter *adapter)
{
@@ -1351,6 +1412,25 @@ vmxnet3_rq_init(struct vmxnet3_rx_queue *rq,
static int
+vmxnet3_rq_init_all(struct vmxnet3_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = vmxnet3_rq_init(&adapter->rx_queue[i], adapter);
+ if (unlikely(err)) {
+ dev_err(&adapter->netdev->dev, "%s: failed to "
+ "initialize rx queue%i\n",
+ adapter->netdev->name, i);
+ break;
+ }
+ }
+ return err;
+
+}
+
+
+static int
vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
{
int i;
@@ -1398,33 +1478,177 @@ err:
static int
+vmxnet3_rq_create_all(struct vmxnet3_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = vmxnet3_rq_create(&adapter->rx_queue[i], adapter);
+ if (unlikely(err)) {
+ dev_err(&adapter->netdev->dev,
+ "%s: failed to create rx queue%i\n",
+ adapter->netdev->name, i);
+ goto err_out;
+ }
+ }
+ return err;
+err_out:
+ vmxnet3_rq_destroy_all(adapter);
+ return err;
+
+}
+
+/* Multiple queue aware polling function for tx and rx */
+
+static int
vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget)
{
+ int rcd_done = 0, i;
if (unlikely(adapter->shared->ecr))
vmxnet3_process_events(adapter);
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ vmxnet3_tq_tx_complete(&adapter->tx_queue[i], adapter);
- vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter);
- return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ rcd_done += vmxnet3_rq_rx_complete(&adapter->rx_queue[i],
+ adapter, budget);
+ return rcd_done;
}
static int
vmxnet3_poll(struct napi_struct *napi, int budget)
{
- struct vmxnet3_adapter *adapter = container_of(napi,
- struct vmxnet3_adapter, napi);
+ struct vmxnet3_rx_queue *rx_queue = container_of(napi,
+ struct vmxnet3_rx_queue, napi);
+ int rxd_done;
+
+ rxd_done = vmxnet3_do_poll(rx_queue->adapter, budget);
+
+ if (rxd_done < budget) {
+ napi_complete(napi);
+ vmxnet3_enable_all_intrs(rx_queue->adapter);
+ }
+ return rxd_done;
+}
+
+/*
+ * NAPI polling function for MSI-X mode with multiple Rx queues
+ * Returns the # of the NAPI credit consumed (# of rx descriptors processed)
+ */
+
+static int
+vmxnet3_poll_rx_only(struct napi_struct *napi, int budget)
+{
+ struct vmxnet3_rx_queue *rq = container_of(napi,
+ struct vmxnet3_rx_queue, napi);
+ struct vmxnet3_adapter *adapter = rq->adapter;
int rxd_done;
- rxd_done = vmxnet3_do_poll(adapter, budget);
+ /* When sharing interrupt with corresponding tx queue, process
+ * tx completions in that queue as well
+ */
+ if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE) {
+ struct vmxnet3_tx_queue *tq =
+ &adapter->tx_queue[rq - adapter->rx_queue];
+ vmxnet3_tq_tx_complete(tq, adapter);
+ }
+
+ rxd_done = vmxnet3_rq_rx_complete(rq, adapter, budget);
if (rxd_done < budget) {
napi_complete(napi);
- vmxnet3_enable_intr(adapter, 0);
+ vmxnet3_enable_intr(adapter, rq->comp_ring.intr_idx);
}
return rxd_done;
}
+#ifdef CONFIG_PCI_MSI
+
+/*
+ * Handle completion interrupts on tx queues
+ * Returns whether or not the intr is handled
+ */
+
+static irqreturn_t
+vmxnet3_msix_tx(int irq, void *data)
+{
+ struct vmxnet3_tx_queue *tq = data;
+ struct vmxnet3_adapter *adapter = tq->adapter;
+
+ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+ vmxnet3_disable_intr(adapter, tq->comp_ring.intr_idx);
+
+ /* Handle the case where only one irq is allocate for all tx queues */
+ if (adapter->share_intr == VMXNET3_INTR_TXSHARE) {
+ int i;
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct vmxnet3_tx_queue *txq = &adapter->tx_queue[i];
+ vmxnet3_tq_tx_complete(txq, adapter);
+ }
+ } else {
+ vmxnet3_tq_tx_complete(tq, adapter);
+ }
+ vmxnet3_enable_intr(adapter, tq->comp_ring.intr_idx);
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * Handle completion interrupts on rx queues. Returns whether or not the
+ * intr is handled
+ */
+
+static irqreturn_t
+vmxnet3_msix_rx(int irq, void *data)
+{
+ struct vmxnet3_rx_queue *rq = data;
+ struct vmxnet3_adapter *adapter = rq->adapter;
+
+ /* disable intr if needed */
+ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+ vmxnet3_disable_intr(adapter, rq->comp_ring.intr_idx);
+ napi_schedule(&rq->napi);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * vmxnet3_msix_event --
+ *
+ * vmxnet3 msix event intr handler
+ *
+ * Result:
+ * whether or not the intr is handled
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static irqreturn_t
+vmxnet3_msix_event(int irq, void *data)
+{
+ struct net_device *dev = data;
+ struct vmxnet3_adapter *adapter = netdev_priv(dev);
+
+ /* disable intr if needed */
+ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+ vmxnet3_disable_intr(adapter, adapter->intr.event_intr_idx);
+
+ if (adapter->shared->ecr)
+ vmxnet3_process_events(adapter);
+
+ vmxnet3_enable_intr(adapter, adapter->intr.event_intr_idx);
+
+ return IRQ_HANDLED;
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+
/* Interrupt handler for vmxnet3 */
static irqreturn_t
vmxnet3_intr(int irq, void *dev_id)
@@ -1432,7 +1656,7 @@ vmxnet3_intr(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct vmxnet3_adapter *adapter = netdev_priv(dev);
- if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) {
+ if (adapter->intr.type == VMXNET3_IT_INTX) {
u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
if (unlikely(icr == 0))
/* not ours */
@@ -1442,77 +1666,144 @@ vmxnet3_intr(int irq, void *dev_id)
/* disable intr if needed */
if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
- vmxnet3_disable_intr(adapter, 0);
+ vmxnet3_disable_all_intrs(adapter);
- napi_schedule(&adapter->napi);
+ napi_schedule(&adapter->rx_queue[0].napi);
return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-
/* netpoll callback. */
static void
vmxnet3_netpoll(struct net_device *netdev)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- int irq;
-#ifdef CONFIG_PCI_MSI
- if (adapter->intr.type == VMXNET3_IT_MSIX)
- irq = adapter->intr.msix_entries[0].vector;
- else
-#endif
- irq = adapter->pdev->irq;
+ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+ vmxnet3_disable_all_intrs(adapter);
+
+ vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size);
+ vmxnet3_enable_all_intrs(adapter);
- disable_irq(irq);
- vmxnet3_intr(irq, netdev);
- enable_irq(irq);
}
-#endif
+#endif /* CONFIG_NET_POLL_CONTROLLER */
static int
vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
{
- int err;
+ struct vmxnet3_intr *intr = &adapter->intr;
+ int err = 0, i;
+ int vector = 0;
#ifdef CONFIG_PCI_MSI
if (adapter->intr.type == VMXNET3_IT_MSIX) {
- /* we only use 1 MSI-X vector */
- err = request_irq(adapter->intr.msix_entries[0].vector,
- vmxnet3_intr, 0, adapter->netdev->name,
- adapter->netdev);
- } else if (adapter->intr.type == VMXNET3_IT_MSI) {
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) {
+ sprintf(adapter->tx_queue[i].name, "%s-tx-%d",
+ adapter->netdev->name, vector);
+ err = request_irq(
+ intr->msix_entries[vector].vector,
+ vmxnet3_msix_tx, 0,
+ adapter->tx_queue[i].name,
+ &adapter->tx_queue[i]);
+ } else {
+ sprintf(adapter->tx_queue[i].name, "%s-rxtx-%d",
+ adapter->netdev->name, vector);
+ }
+ if (err) {
+ dev_err(&adapter->netdev->dev,
+ "Failed to request irq for MSIX, %s, "
+ "error %d\n",
+ adapter->tx_queue[i].name, err);
+ return err;
+ }
+
+ /* Handle the case where only 1 MSIx was allocated for
+ * all tx queues */
+ if (adapter->share_intr == VMXNET3_INTR_TXSHARE) {
+ for (; i < adapter->num_tx_queues; i++)
+ adapter->tx_queue[i].comp_ring.intr_idx
+ = vector;
+ vector++;
+ break;
+ } else {
+ adapter->tx_queue[i].comp_ring.intr_idx
+ = vector++;
+ }
+ }
+ if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE)
+ vector = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE)
+ sprintf(adapter->rx_queue[i].name, "%s-rx-%d",
+ adapter->netdev->name, vector);
+ else
+ sprintf(adapter->rx_queue[i].name, "%s-rxtx-%d",
+ adapter->netdev->name, vector);
+ err = request_irq(intr->msix_entries[vector].vector,
+ vmxnet3_msix_rx, 0,
+ adapter->rx_queue[i].name,
+ &(adapter->rx_queue[i]));
+ if (err) {
+ printk(KERN_ERR "Failed to request irq for MSIX"
+ ", %s, error %d\n",
+ adapter->rx_queue[i].name, err);
+ return err;
+ }
+
+ adapter->rx_queue[i].comp_ring.intr_idx = vector++;
+ }
+
+ sprintf(intr->event_msi_vector_name, "%s-event-%d",
+ adapter->netdev->name, vector);
+ err = request_irq(intr->msix_entries[vector].vector,
+ vmxnet3_msix_event, 0,
+ intr->event_msi_vector_name, adapter->netdev);
+ intr->event_intr_idx = vector;
+
+ } else if (intr->type == VMXNET3_IT_MSI) {
+ adapter->num_rx_queues = 1;
err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0,
adapter->netdev->name, adapter->netdev);
- } else
+ } else {
#endif
- {
+ adapter->num_rx_queues = 1;
err = request_irq(adapter->pdev->irq, vmxnet3_intr,
IRQF_SHARED, adapter->netdev->name,
adapter->netdev);
+#ifdef CONFIG_PCI_MSI
}
-
- if (err)
+#endif
+ intr->num_intrs = vector + 1;
+ if (err) {
printk(KERN_ERR "Failed to request irq %s (intr type:%d), error"
- ":%d\n", adapter->netdev->name, adapter->intr.type, err);
+ ":%d\n", adapter->netdev->name, intr->type, err);
+ } else {
+ /* Number of rx queues will not change after this */
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
+ rq->qid = i;
+ rq->qid2 = i + adapter->num_rx_queues;
+ }
- if (!err) {
- int i;
- /* init our intr settings */
- for (i = 0; i < adapter->intr.num_intrs; i++)
- adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE;
- /* next setup intr index for all intr sources */
- adapter->tx_queue.comp_ring.intr_idx = 0;
- adapter->rx_queue.comp_ring.intr_idx = 0;
- adapter->intr.event_intr_idx = 0;
+ /* init our intr settings */
+ for (i = 0; i < intr->num_intrs; i++)
+ intr->mod_levels[i] = UPT1_IML_ADAPTIVE;
+ if (adapter->intr.type != VMXNET3_IT_MSIX) {
+ adapter->intr.event_intr_idx = 0;
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_queue[i].comp_ring.intr_idx = 0;
+ adapter->rx_queue[0].comp_ring.intr_idx = 0;
+ }
printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors "
- "allocated\n", adapter->netdev->name, adapter->intr.type,
- adapter->intr.mask_mode, adapter->intr.num_intrs);
+ "allocated\n", adapter->netdev->name, intr->type,
+ intr->mask_mode, intr->num_intrs);
}
return err;
@@ -1522,18 +1813,32 @@ vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
static void
vmxnet3_free_irqs(struct vmxnet3_adapter *adapter)
{
- BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO ||
- adapter->intr.num_intrs <= 0);
+ struct vmxnet3_intr *intr = &adapter->intr;
+ BUG_ON(intr->type == VMXNET3_IT_AUTO || intr->num_intrs <= 0);
- switch (adapter->intr.type) {
+ switch (intr->type) {
#ifdef CONFIG_PCI_MSI
case VMXNET3_IT_MSIX:
{
- int i;
+ int i, vector = 0;
+
+ if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) {
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ free_irq(intr->msix_entries[vector++].vector,
+ &(adapter->tx_queue[i]));
+ if (adapter->share_intr == VMXNET3_INTR_TXSHARE)
+ break;
+ }
+ }
- for (i = 0; i < adapter->intr.num_intrs; i++)
- free_irq(adapter->intr.msix_entries[i].vector,
- adapter->netdev);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ free_irq(intr->msix_entries[vector++].vector,
+ &(adapter->rx_queue[i]));
+ }
+
+ free_irq(intr->msix_entries[vector].vector,
+ adapter->netdev);
+ BUG_ON(vector >= intr->num_intrs);
break;
}
#endif
@@ -1727,6 +2032,15 @@ vmxnet3_set_mc(struct net_device *netdev)
kfree(new_table);
}
+void
+vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ vmxnet3_rq_destroy(&adapter->rx_queue[i], adapter);
+}
+
/*
* Set up driver_shared based on settings in adapter.
@@ -1774,40 +2088,72 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa);
devRead->misc.queueDescLen = cpu_to_le32(
- sizeof(struct Vmxnet3_TxQueueDesc) +
- sizeof(struct Vmxnet3_RxQueueDesc));
+ adapter->num_tx_queues * sizeof(struct Vmxnet3_TxQueueDesc) +
+ adapter->num_rx_queues * sizeof(struct Vmxnet3_RxQueueDesc));
/* tx queue settings */
- BUG_ON(adapter->tx_queue.tx_ring.base == NULL);
-
- devRead->misc.numTxQueues = 1;
- tqc = &adapter->tqd_start->conf;
- tqc->txRingBasePA = cpu_to_le64(adapter->tx_queue.tx_ring.basePA);
- tqc->dataRingBasePA = cpu_to_le64(adapter->tx_queue.data_ring.basePA);
- tqc->compRingBasePA = cpu_to_le64(adapter->tx_queue.comp_ring.basePA);
- tqc->ddPA = cpu_to_le64(virt_to_phys(
- adapter->tx_queue.buf_info));
- tqc->txRingSize = cpu_to_le32(adapter->tx_queue.tx_ring.size);
- tqc->dataRingSize = cpu_to_le32(adapter->tx_queue.data_ring.size);
- tqc->compRingSize = cpu_to_le32(adapter->tx_queue.comp_ring.size);
- tqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_tx_buf_info) *
- tqc->txRingSize);
- tqc->intrIdx = adapter->tx_queue.comp_ring.intr_idx;
+ devRead->misc.numTxQueues = adapter->num_tx_queues;
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i];
+ BUG_ON(adapter->tx_queue[i].tx_ring.base == NULL);
+ tqc = &adapter->tqd_start[i].conf;
+ tqc->txRingBasePA = cpu_to_le64(tq->tx_ring.basePA);
+ tqc->dataRingBasePA = cpu_to_le64(tq->data_ring.basePA);
+ tqc->compRingBasePA = cpu_to_le64(tq->comp_ring.basePA);
+ tqc->ddPA = cpu_to_le64(virt_to_phys(tq->buf_info));
+ tqc->txRingSize = cpu_to_le32(tq->tx_ring.size);
+ tqc->dataRingSize = cpu_to_le32(tq->data_ring.size);
+ tqc->compRingSize = cpu_to_le32(tq->comp_ring.size);
+ tqc->ddLen = cpu_to_le32(
+ sizeof(struct vmxnet3_tx_buf_info) *
+ tqc->txRingSize);
+ tqc->intrIdx = tq->comp_ring.intr_idx;
+ }
/* rx queue settings */
- devRead->misc.numRxQueues = 1;
- rqc = &adapter->rqd_start->conf;
- rqc->rxRingBasePA[0] = cpu_to_le64(adapter->rx_queue.rx_ring[0].basePA);
- rqc->rxRingBasePA[1] = cpu_to_le64(adapter->rx_queue.rx_ring[1].basePA);
- rqc->compRingBasePA = cpu_to_le64(adapter->rx_queue.comp_ring.basePA);
- rqc->ddPA = cpu_to_le64(virt_to_phys(
- adapter->rx_queue.buf_info));
- rqc->rxRingSize[0] = cpu_to_le32(adapter->rx_queue.rx_ring[0].size);
- rqc->rxRingSize[1] = cpu_to_le32(adapter->rx_queue.rx_ring[1].size);
- rqc->compRingSize = cpu_to_le32(adapter->rx_queue.comp_ring.size);
- rqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_rx_buf_info) *
- (rqc->rxRingSize[0] + rqc->rxRingSize[1]));
- rqc->intrIdx = adapter->rx_queue.comp_ring.intr_idx;
+ devRead->misc.numRxQueues = adapter->num_rx_queues;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
+ rqc = &adapter->rqd_start[i].conf;
+ rqc->rxRingBasePA[0] = cpu_to_le64(rq->rx_ring[0].basePA);
+ rqc->rxRingBasePA[1] = cpu_to_le64(rq->rx_ring[1].basePA);
+ rqc->compRingBasePA = cpu_to_le64(rq->comp_ring.basePA);
+ rqc->ddPA = cpu_to_le64(virt_to_phys(
+ rq->buf_info));
+ rqc->rxRingSize[0] = cpu_to_le32(rq->rx_ring[0].size);
+ rqc->rxRingSize[1] = cpu_to_le32(rq->rx_ring[1].size);
+ rqc->compRingSize = cpu_to_le32(rq->comp_ring.size);
+ rqc->ddLen = cpu_to_le32(
+ sizeof(struct vmxnet3_rx_buf_info) *
+ (rqc->rxRingSize[0] +
+ rqc->rxRingSize[1]));
+ rqc->intrIdx = rq->comp_ring.intr_idx;
+ }
+
+#ifdef VMXNET3_RSS
+ memset(adapter->rss_conf, 0, sizeof(*adapter->rss_conf));
+
+ if (adapter->rss) {
+ struct UPT1_RSSConf *rssConf = adapter->rss_conf;
+ devRead->misc.uptFeatures |= UPT1_F_RSS;
+ devRead->misc.numRxQueues = adapter->num_rx_queues;
+ rssConf->hashType = UPT1_RSS_HASH_TYPE_TCP_IPV4 |
+ UPT1_RSS_HASH_TYPE_IPV4 |
+ UPT1_RSS_HASH_TYPE_TCP_IPV6 |
+ UPT1_RSS_HASH_TYPE_IPV6;
+ rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ;
+ rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE;
+ rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE;
+ get_random_bytes(&rssConf->hashKey[0], rssConf->hashKeySize);
+ for (i = 0; i < rssConf->indTableSize; i++)
+ rssConf->indTable[i] = i % adapter->num_rx_queues;
+
+ devRead->rssConfDesc.confVer = 1;
+ devRead->rssConfDesc.confLen = sizeof(*rssConf);
+ devRead->rssConfDesc.confPA = virt_to_phys(rssConf);
+ }
+
+#endif /* VMXNET3_RSS */
/* intr settings */
devRead->intrConf.autoMask = adapter->intr.mask_mode ==
@@ -1829,18 +2175,18 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
int
vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
{
- int err;
+ int err, i;
u32 ret;
- dev_dbg(&adapter->netdev->dev,
- "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes"
- " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size,
- adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size,
- adapter->rx_queue.rx_ring[0].size,
- adapter->rx_queue.rx_ring[1].size);
-
- vmxnet3_tq_init(&adapter->tx_queue, adapter);
- err = vmxnet3_rq_init(&adapter->rx_queue, adapter);
+ dev_dbg(&adapter->netdev->dev, "%s: skb_buf_size %d, rx_buf_per_pkt %d,"
+ " ring sizes %u %u %u\n", adapter->netdev->name,
+ adapter->skb_buf_size, adapter->rx_buf_per_pkt,
+ adapter->tx_queue[0].tx_ring.size,
+ adapter->rx_queue[0].rx_ring[0].size,
+ adapter->rx_queue[0].rx_ring[1].size);
+
+ vmxnet3_tq_init_all(adapter);
+ err = vmxnet3_rq_init_all(adapter);
if (err) {
printk(KERN_ERR "Failed to init rx queue for %s: error %d\n",
adapter->netdev->name, err);
@@ -1870,10 +2216,15 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
err = -EINVAL;
goto activate_err;
}
- VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD,
- adapter->rx_queue.rx_ring[0].next2fill);
- VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2,
- adapter->rx_queue.rx_ring[1].next2fill);
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ VMXNET3_WRITE_BAR0_REG(adapter,
+ VMXNET3_REG_RXPROD + i * VMXNET3_REG_ALIGN,
+ adapter->rx_queue[i].rx_ring[0].next2fill);
+ VMXNET3_WRITE_BAR0_REG(adapter, (VMXNET3_REG_RXPROD2 +
+ (i * VMXNET3_REG_ALIGN)),
+ adapter->rx_queue[i].rx_ring[1].next2fill);
+ }
/* Apply the rx filter settins last. */
vmxnet3_set_mc(adapter->netdev);
@@ -1883,8 +2234,8 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
* tx queue if the link is up.
*/
vmxnet3_check_link(adapter, true);
-
- napi_enable(&adapter->napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_queue[i].napi);
vmxnet3_enable_all_intrs(adapter);
clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
return 0;
@@ -1896,7 +2247,7 @@ activate_err:
irq_err:
rq_err:
/* free up buffers we allocated */
- vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+ vmxnet3_rq_cleanup_all(adapter);
return err;
}
@@ -1911,6 +2262,7 @@ vmxnet3_reset_dev(struct vmxnet3_adapter *adapter)
int
vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
{
+ int i;
if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))
return 0;
@@ -1919,13 +2271,14 @@ vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
VMXNET3_CMD_QUIESCE_DEV);
vmxnet3_disable_all_intrs(adapter);
- napi_disable(&adapter->napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_disable(&adapter->rx_queue[i].napi);
netif_tx_disable(adapter->netdev);
adapter->link_speed = 0;
netif_carrier_off(adapter->netdev);
- vmxnet3_tq_cleanup(&adapter->tx_queue, adapter);
- vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+ vmxnet3_tq_cleanup_all(adapter);
+ vmxnet3_rq_cleanup_all(adapter);
vmxnet3_free_irqs(adapter);
return 0;
}
@@ -2047,7 +2400,9 @@ vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter)
static void
vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
{
- size_t sz;
+ size_t sz, i, ring0_size, ring1_size, comp_size;
+ struct vmxnet3_rx_queue *rq = &adapter->rx_queue[0];
+
if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
VMXNET3_MAX_ETH_HDR_SIZE) {
@@ -2069,11 +2424,19 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
* rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
*/
sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
- adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size +
- sz - 1) / sz * sz;
- adapter->rx_queue.rx_ring[0].size = min_t(u32,
- adapter->rx_queue.rx_ring[0].size,
- VMXNET3_RX_RING_MAX_SIZE / sz * sz);
+ ring0_size = adapter->rx_queue[0].rx_ring[0].size;
+ ring0_size = (ring0_size + sz - 1) / sz * sz;
+ ring0_size = min_t(u32, rq->rx_ring[0].size, VMXNET3_RX_RING_MAX_SIZE /
+ sz * sz);
+ ring1_size = adapter->rx_queue[0].rx_ring[1].size;
+ comp_size = ring0_size + ring1_size;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rq = &adapter->rx_queue[i];
+ rq->rx_ring[0].size = ring0_size;
+ rq->rx_ring[1].size = ring1_size;
+ rq->comp_ring.size = comp_size;
+ }
}
@@ -2081,29 +2444,53 @@ int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
u32 rx_ring_size, u32 rx_ring2_size)
{
- int err;
-
- adapter->tx_queue.tx_ring.size = tx_ring_size;
- adapter->tx_queue.data_ring.size = tx_ring_size;
- adapter->tx_queue.comp_ring.size = tx_ring_size;
- adapter->tx_queue.shared = &adapter->tqd_start->ctrl;
- adapter->tx_queue.stopped = true;
- err = vmxnet3_tq_create(&adapter->tx_queue, adapter);
- if (err)
- return err;
+ int err = 0, i;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i];
+ tq->tx_ring.size = tx_ring_size;
+ tq->data_ring.size = tx_ring_size;
+ tq->comp_ring.size = tx_ring_size;
+ tq->shared = &adapter->tqd_start[i].ctrl;
+ tq->stopped = true;
+ tq->adapter = adapter;
+ tq->qid = i;
+ err = vmxnet3_tq_create(tq, adapter);
+ /*
+ * Too late to change num_tx_queues. We cannot do away with
+ * lesser number of queues than what we asked for
+ */
+ if (err)
+ goto queue_err;
+ }
- adapter->rx_queue.rx_ring[0].size = rx_ring_size;
- adapter->rx_queue.rx_ring[1].size = rx_ring2_size;
+ adapter->rx_queue[0].rx_ring[0].size = rx_ring_size;
+ adapter->rx_queue[0].rx_ring[1].size = rx_ring2_size;
vmxnet3_adjust_rx_ring_size(adapter);
- adapter->rx_queue.comp_ring.size = adapter->rx_queue.rx_ring[0].size +
- adapter->rx_queue.rx_ring[1].size;
- adapter->rx_queue.qid = 0;
- adapter->rx_queue.qid2 = 1;
- adapter->rx_queue.shared = &adapter->rqd_start->ctrl;
- err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
- if (err)
- vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
-
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
+ /* qid and qid2 for rx queues will be assigned later when num
+ * of rx queues is finalized after allocating intrs */
+ rq->shared = &adapter->rqd_start[i].ctrl;
+ rq->adapter = adapter;
+ err = vmxnet3_rq_create(rq, adapter);
+ if (err) {
+ if (i == 0) {
+ printk(KERN_ERR "Could not allocate any rx"
+ "queues. Aborting.\n");
+ goto queue_err;
+ } else {
+ printk(KERN_INFO "Number of rx queues changed "
+ "to : %d.\n", i);
+ adapter->num_rx_queues = i;
+ err = 0;
+ break;
+ }
+ }
+ }
+ return err;
+queue_err:
+ vmxnet3_tq_destroy_all(adapter);
return err;
}
@@ -2111,11 +2498,12 @@ static int
vmxnet3_open(struct net_device *netdev)
{
struct vmxnet3_adapter *adapter;
- int err;
+ int err, i;
adapter = netdev_priv(netdev);
- spin_lock_init(&adapter->tx_queue.tx_lock);
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ spin_lock_init(&adapter->tx_queue[i].tx_lock);
err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE,
VMXNET3_DEF_RX_RING_SIZE,
@@ -2130,8 +2518,8 @@ vmxnet3_open(struct net_device *netdev)
return 0;
activate_err:
- vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
- vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+ vmxnet3_rq_destroy_all(adapter);
+ vmxnet3_tq_destroy_all(adapter);
queue_err:
return err;
}
@@ -2151,8 +2539,8 @@ vmxnet3_close(struct net_device *netdev)
vmxnet3_quiesce_dev(adapter);
- vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
- vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+ vmxnet3_rq_destroy_all(adapter);
+ vmxnet3_tq_destroy_all(adapter);
clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
@@ -2164,6 +2552,8 @@ vmxnet3_close(struct net_device *netdev)
void
vmxnet3_force_close(struct vmxnet3_adapter *adapter)
{
+ int i;
+
/*
* we must clear VMXNET3_STATE_BIT_RESETTING, otherwise
* vmxnet3_close() will deadlock.
@@ -2171,7 +2561,8 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter)
BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state));
/* we need to enable NAPI, otherwise dev_close will deadlock */
- napi_enable(&adapter->napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_queue[i].napi);
dev_close(adapter->netdev);
}
@@ -2202,14 +2593,11 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
vmxnet3_reset_dev(adapter);
/* we need to re-create the rx queue based on the new mtu */
- vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+ vmxnet3_rq_destroy_all(adapter);
vmxnet3_adjust_rx_ring_size(adapter);
- adapter->rx_queue.comp_ring.size =
- adapter->rx_queue.rx_ring[0].size +
- adapter->rx_queue.rx_ring[1].size;
- err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
+ err = vmxnet3_rq_create_all(adapter);
if (err) {
- printk(KERN_ERR "%s: failed to re-create rx queue,"
+ printk(KERN_ERR "%s: failed to re-create rx queues,"
" error %d. Closing it.\n", netdev->name, err);
goto out;
}
@@ -2274,6 +2662,55 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
mac[5] = (tmp >> 8) & 0xff;
}
+#ifdef CONFIG_PCI_MSI
+
+/*
+ * Enable MSIx vectors.
+ * Returns :
+ * 0 on successful enabling of required vectors,
+ * VMXNET3_LINUX_MIN_MSIX_VECT when only minumum number of vectors required
+ * could be enabled.
+ * number of vectors which can be enabled otherwise (this number is smaller
+ * than VMXNET3_LINUX_MIN_MSIX_VECT)
+ */
+
+static int
+vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter,
+ int vectors)
+{
+ int err = 0, vector_threshold;
+ vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT;
+
+ while (vectors >= vector_threshold) {
+ err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
+ vectors);
+ if (!err) {
+ adapter->intr.num_intrs = vectors;
+ return 0;
+ } else if (err < 0) {
+ printk(KERN_ERR "Failed to enable MSI-X for %s, error"
+ " %d\n", adapter->netdev->name, err);
+ vectors = 0;
+ } else if (err < vector_threshold) {
+ break;
+ } else {
+ /* If fails to enable required number of MSI-x vectors
+ * try enabling 3 of them. One each for rx, tx and event
+ */
+ vectors = vector_threshold;
+ printk(KERN_ERR "Failed to enable %d MSI-X for %s, try"
+ " %d instead\n", vectors, adapter->netdev->name,
+ vector_threshold);
+ }
+ }
+
+ printk(KERN_INFO "Number of MSI-X interrupts which can be allocatedi"
+ " are lower than min threshold required.\n");
+ return err;
+}
+
+
+#endif /* CONFIG_PCI_MSI */
static void
vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
@@ -2293,16 +2730,47 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
#ifdef CONFIG_PCI_MSI
if (adapter->intr.type == VMXNET3_IT_MSIX) {
- int err;
-
- adapter->intr.msix_entries[0].entry = 0;
- err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
- VMXNET3_LINUX_MAX_MSIX_VECT);
- if (!err) {
- adapter->intr.num_intrs = 1;
- adapter->intr.type = VMXNET3_IT_MSIX;
+ int vector, err = 0;
+
+ adapter->intr.num_intrs = (adapter->share_intr ==
+ VMXNET3_INTR_TXSHARE) ? 1 :
+ adapter->num_tx_queues;
+ adapter->intr.num_intrs += (adapter->share_intr ==
+ VMXNET3_INTR_BUDDYSHARE) ? 0 :
+ adapter->num_rx_queues;
+ adapter->intr.num_intrs += 1; /* for link event */
+
+ adapter->intr.num_intrs = (adapter->intr.num_intrs >
+ VMXNET3_LINUX_MIN_MSIX_VECT
+ ? adapter->intr.num_intrs :
+ VMXNET3_LINUX_MIN_MSIX_VECT);
+
+ for (vector = 0; vector < adapter->intr.num_intrs; vector++)
+ adapter->intr.msix_entries[vector].entry = vector;
+
+ err = vmxnet3_acquire_msix_vectors(adapter,
+ adapter->intr.num_intrs);
+ /* If we cannot allocate one MSIx vector per queue
+ * then limit the number of rx queues to 1
+ */
+ if (err == VMXNET3_LINUX_MIN_MSIX_VECT) {
+ if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE
+ || adapter->num_rx_queues != 2) {
+ adapter->share_intr = VMXNET3_INTR_TXSHARE;
+ printk(KERN_ERR "Number of rx queues : 1\n");
+ adapter->num_rx_queues = 1;
+ adapter->intr.num_intrs =
+ VMXNET3_LINUX_MIN_MSIX_VECT;
+ }
return;
}
+ if (!err)
+ return;
+
+ /* If we cannot allocate MSIx vectors use only one rx queue */
+ printk(KERN_INFO "Failed to enable MSI-X for %s, error %d."
+ "#rx queues : 1, try MSI\n", adapter->netdev->name, err);
+
adapter->intr.type = VMXNET3_IT_MSI;
}
@@ -2310,12 +2778,15 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
int err;
err = pci_enable_msi(adapter->pdev);
if (!err) {
+ adapter->num_rx_queues = 1;
adapter->intr.num_intrs = 1;
return;
}
}
#endif /* CONFIG_PCI_MSI */
+ adapter->num_rx_queues = 1;
+ printk(KERN_INFO "Using INTx interrupt, #Rx queues: 1.\n");
adapter->intr.type = VMXNET3_IT_INTX;
/* INT-X related setting */
@@ -2343,6 +2814,7 @@ vmxnet3_tx_timeout(struct net_device *netdev)
printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name);
schedule_work(&adapter->work);
+ netif_wake_queue(adapter->netdev);
}
@@ -2399,8 +2871,29 @@ vmxnet3_probe_device(struct pci_dev *pdev,
struct net_device *netdev;
struct vmxnet3_adapter *adapter;
u8 mac[ETH_ALEN];
+ int size;
+ int num_tx_queues;
+ int num_rx_queues;
+
+#ifdef VMXNET3_RSS
+ if (enable_mq)
+ num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
+ (int)num_online_cpus());
+ else
+#endif
+ num_rx_queues = 1;
+
+ if (enable_mq)
+ num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES,
+ (int)num_online_cpus());
+ else
+ num_tx_queues = 1;
+
+ netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter),
+ max(num_tx_queues, num_rx_queues));
+ printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n",
+ num_tx_queues, num_rx_queues);
- netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter));
if (!netdev) {
printk(KERN_ERR "Failed to alloc ethernet device for adapter "
"%s\n", pci_name(pdev));
@@ -2422,9 +2915,12 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_alloc_shared;
}
- adapter->tqd_start = pci_alloc_consistent(adapter->pdev,
- sizeof(struct Vmxnet3_TxQueueDesc) +
- sizeof(struct Vmxnet3_RxQueueDesc),
+ adapter->num_rx_queues = num_rx_queues;
+ adapter->num_tx_queues = num_tx_queues;
+
+ size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
+ size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues;
+ adapter->tqd_start = pci_alloc_consistent(adapter->pdev, size,
&adapter->queue_desc_pa);
if (!adapter->tqd_start) {
@@ -2433,8 +2929,8 @@ vmxnet3_probe_device(struct pci_dev *pdev,
err = -ENOMEM;
goto err_alloc_queue_desc;
}
- adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start
- + 1);
+ adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start +
+ adapter->num_tx_queues);
adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
if (adapter->pm_conf == NULL) {
@@ -2444,6 +2940,17 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_alloc_pm;
}
+#ifdef VMXNET3_RSS
+
+ adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL);
+ if (adapter->rss_conf == NULL) {
+ printk(KERN_ERR "Failed to allocate memory for %s\n",
+ pci_name(pdev));
+ err = -ENOMEM;
+ goto err_alloc_rss;
+ }
+#endif /* VMXNET3_RSS */
+
err = vmxnet3_alloc_pci_resources(adapter, &dma64);
if (err < 0)
goto err_alloc_pci;
@@ -2471,18 +2978,48 @@ vmxnet3_probe_device(struct pci_dev *pdev,
vmxnet3_declare_features(adapter, dma64);
adapter->dev_number = atomic_read(&devices_found);
+
+ adapter->share_intr = irq_share_mode;
+ if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE &&
+ adapter->num_tx_queues != adapter->num_rx_queues)
+ adapter->share_intr = VMXNET3_INTR_DONTSHARE;
+
vmxnet3_alloc_intr_resources(adapter);
+#ifdef VMXNET3_RSS
+ if (adapter->num_rx_queues > 1 &&
+ adapter->intr.type == VMXNET3_IT_MSIX) {
+ adapter->rss = true;
+ printk(KERN_INFO "RSS is enabled.\n");
+ } else {
+ adapter->rss = false;
+ }
+#endif
+
vmxnet3_read_mac_addr(adapter, mac);
memcpy(netdev->dev_addr, mac, netdev->addr_len);
netdev->netdev_ops = &vmxnet3_netdev_ops;
- netdev->watchdog_timeo = 5 * HZ;
vmxnet3_set_ethtool_ops(netdev);
+ netdev->watchdog_timeo = 5 * HZ;
INIT_WORK(&adapter->work, vmxnet3_reset_work);
- netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64);
+ if (adapter->intr.type == VMXNET3_IT_MSIX) {
+ int i;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ netif_napi_add(adapter->netdev,
+ &adapter->rx_queue[i].napi,
+ vmxnet3_poll_rx_only, 64);
+ }
+ } else {
+ netif_napi_add(adapter->netdev, &adapter->rx_queue[0].napi,
+ vmxnet3_poll, 64);
+ }
+
+ netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
+ netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues);
+
SET_NETDEV_DEV(netdev, &pdev->dev);
err = register_netdev(netdev);
@@ -2502,11 +3039,14 @@ err_register:
err_ver:
vmxnet3_free_pci_resources(adapter);
err_alloc_pci:
+#ifdef VMXNET3_RSS
+ kfree(adapter->rss_conf);
+err_alloc_rss:
+#endif
kfree(adapter->pm_conf);
err_alloc_pm:
- pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
- sizeof(struct Vmxnet3_RxQueueDesc),
- adapter->tqd_start, adapter->queue_desc_pa);
+ pci_free_consistent(adapter->pdev, size, adapter->tqd_start,
+ adapter->queue_desc_pa);
err_alloc_queue_desc:
pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
adapter->shared, adapter->shared_pa);
@@ -2522,17 +3062,32 @@ vmxnet3_remove_device(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ int size = 0;
+ int num_rx_queues;
- flush_scheduled_work();
+#ifdef VMXNET3_RSS
+ if (enable_mq)
+ num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
+ (int)num_online_cpus());
+ else
+#endif
+ num_rx_queues = 1;
+
+ cancel_work_sync(&adapter->work);
unregister_netdev(netdev);
vmxnet3_free_intr_resources(adapter);
vmxnet3_free_pci_resources(adapter);
+#ifdef VMXNET3_RSS
+ kfree(adapter->rss_conf);
+#endif
kfree(adapter->pm_conf);
- pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
- sizeof(struct Vmxnet3_RxQueueDesc),
- adapter->tqd_start, adapter->queue_desc_pa);
+
+ size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
+ size += sizeof(struct Vmxnet3_RxQueueDesc) * num_rx_queues;
+ pci_free_consistent(adapter->pdev, size, adapter->tqd_start,
+ adapter->queue_desc_pa);
pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
adapter->shared, adapter->shared_pa);
free_netdev(netdev);
@@ -2563,7 +3118,7 @@ vmxnet3_suspend(struct device *device)
vmxnet3_free_intr_resources(adapter);
netif_device_detach(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
/* Create wake-up filters. */
pmConf = adapter->pm_conf;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index b79070bcc92e..8e17fc8a7fe7 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -151,44 +151,42 @@ vmxnet3_get_stats(struct net_device *netdev)
struct UPT1_TxStats *devTxStats;
struct UPT1_RxStats *devRxStats;
struct net_device_stats *net_stats = &netdev->stats;
+ int i;
adapter = netdev_priv(netdev);
/* Collect the dev stats into the shared area */
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
- /* Assuming that we have a single queue device */
- devTxStats = &adapter->tqd_start->stats;
- devRxStats = &adapter->rqd_start->stats;
-
- /* Get access to the driver stats per queue */
- drvTxStats = &adapter->tx_queue.stats;
- drvRxStats = &adapter->rx_queue.stats;
-
memset(net_stats, 0, sizeof(*net_stats));
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ devTxStats = &adapter->tqd_start[i].stats;
+ drvTxStats = &adapter->tx_queue[i].stats;
+ net_stats->tx_packets += devTxStats->ucastPktsTxOK +
+ devTxStats->mcastPktsTxOK +
+ devTxStats->bcastPktsTxOK;
+ net_stats->tx_bytes += devTxStats->ucastBytesTxOK +
+ devTxStats->mcastBytesTxOK +
+ devTxStats->bcastBytesTxOK;
+ net_stats->tx_errors += devTxStats->pktsTxError;
+ net_stats->tx_dropped += drvTxStats->drop_total;
+ }
- net_stats->rx_packets = devRxStats->ucastPktsRxOK +
- devRxStats->mcastPktsRxOK +
- devRxStats->bcastPktsRxOK;
-
- net_stats->tx_packets = devTxStats->ucastPktsTxOK +
- devTxStats->mcastPktsTxOK +
- devTxStats->bcastPktsTxOK;
-
- net_stats->rx_bytes = devRxStats->ucastBytesRxOK +
- devRxStats->mcastBytesRxOK +
- devRxStats->bcastBytesRxOK;
-
- net_stats->tx_bytes = devTxStats->ucastBytesTxOK +
- devTxStats->mcastBytesTxOK +
- devTxStats->bcastBytesTxOK;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ devRxStats = &adapter->rqd_start[i].stats;
+ drvRxStats = &adapter->rx_queue[i].stats;
+ net_stats->rx_packets += devRxStats->ucastPktsRxOK +
+ devRxStats->mcastPktsRxOK +
+ devRxStats->bcastPktsRxOK;
- net_stats->rx_errors = devRxStats->pktsRxError;
- net_stats->tx_errors = devTxStats->pktsTxError;
- net_stats->rx_dropped = drvRxStats->drop_total;
- net_stats->tx_dropped = drvTxStats->drop_total;
- net_stats->multicast = devRxStats->mcastPktsRxOK;
+ net_stats->rx_bytes += devRxStats->ucastBytesRxOK +
+ devRxStats->mcastBytesRxOK +
+ devRxStats->bcastBytesRxOK;
+ net_stats->rx_errors += devRxStats->pktsRxError;
+ net_stats->rx_dropped += drvRxStats->drop_total;
+ net_stats->multicast += devRxStats->mcastPktsRxOK;
+ }
return net_stats;
}
@@ -307,24 +305,26 @@ vmxnet3_get_ethtool_stats(struct net_device *netdev,
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
u8 *base;
int i;
+ int j = 0;
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
/* this does assume each counter is 64-bit wide */
+/* TODO change this for multiple queues */
- base = (u8 *)&adapter->tqd_start->stats;
+ base = (u8 *)&adapter->tqd_start[j].stats;
for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
*buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);
- base = (u8 *)&adapter->tx_queue.stats;
+ base = (u8 *)&adapter->tx_queue[j].stats;
for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
*buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);
- base = (u8 *)&adapter->rqd_start->stats;
+ base = (u8 *)&adapter->rqd_start[j].stats;
for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
*buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);
- base = (u8 *)&adapter->rx_queue.stats;
+ base = (u8 *)&adapter->rx_queue[j].stats;
for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
*buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);
@@ -339,6 +339,7 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
u32 *buf = p;
+ int i = 0;
memset(p, 0, vmxnet3_get_regs_len(netdev));
@@ -347,28 +348,29 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
/* Update vmxnet3_get_regs_len if we want to dump more registers */
/* make each ring use multiple of 16 bytes */
- buf[0] = adapter->tx_queue.tx_ring.next2fill;
- buf[1] = adapter->tx_queue.tx_ring.next2comp;
- buf[2] = adapter->tx_queue.tx_ring.gen;
+/* TODO change this for multiple queues */
+ buf[0] = adapter->tx_queue[i].tx_ring.next2fill;
+ buf[1] = adapter->tx_queue[i].tx_ring.next2comp;
+ buf[2] = adapter->tx_queue[i].tx_ring.gen;
buf[3] = 0;
- buf[4] = adapter->tx_queue.comp_ring.next2proc;
- buf[5] = adapter->tx_queue.comp_ring.gen;
- buf[6] = adapter->tx_queue.stopped;
+ buf[4] = adapter->tx_queue[i].comp_ring.next2proc;
+ buf[5] = adapter->tx_queue[i].comp_ring.gen;
+ buf[6] = adapter->tx_queue[i].stopped;
buf[7] = 0;
- buf[8] = adapter->rx_queue.rx_ring[0].next2fill;
- buf[9] = adapter->rx_queue.rx_ring[0].next2comp;
- buf[10] = adapter->rx_queue.rx_ring[0].gen;
+ buf[8] = adapter->rx_queue[i].rx_ring[0].next2fill;
+ buf[9] = adapter->rx_queue[i].rx_ring[0].next2comp;
+ buf[10] = adapter->rx_queue[i].rx_ring[0].gen;
buf[11] = 0;
- buf[12] = adapter->rx_queue.rx_ring[1].next2fill;
- buf[13] = adapter->rx_queue.rx_ring[1].next2comp;
- buf[14] = adapter->rx_queue.rx_ring[1].gen;
+ buf[12] = adapter->rx_queue[i].rx_ring[1].next2fill;
+ buf[13] = adapter->rx_queue[i].rx_ring[1].next2comp;
+ buf[14] = adapter->rx_queue[i].rx_ring[1].gen;
buf[15] = 0;
- buf[16] = adapter->rx_queue.comp_ring.next2proc;
- buf[17] = adapter->rx_queue.comp_ring.gen;
+ buf[16] = adapter->rx_queue[i].comp_ring.next2proc;
+ buf[17] = adapter->rx_queue[i].comp_ring.gen;
buf[18] = 0;
buf[19] = 0;
}
@@ -435,8 +437,10 @@ vmxnet3_get_ringparam(struct net_device *netdev,
param->rx_mini_max_pending = 0;
param->rx_jumbo_max_pending = 0;
- param->rx_pending = adapter->rx_queue.rx_ring[0].size;
- param->tx_pending = adapter->tx_queue.tx_ring.size;
+ param->rx_pending = adapter->rx_queue[0].rx_ring[0].size *
+ adapter->num_rx_queues;
+ param->tx_pending = adapter->tx_queue[0].tx_ring.size *
+ adapter->num_tx_queues;
param->rx_mini_pending = 0;
param->rx_jumbo_pending = 0;
}
@@ -480,8 +484,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,
sz) != 0)
return -EINVAL;
- if (new_tx_ring_size == adapter->tx_queue.tx_ring.size &&
- new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) {
+ if (new_tx_ring_size == adapter->tx_queue[0].tx_ring.size &&
+ new_rx_ring_size == adapter->rx_queue[0].rx_ring[0].size) {
return 0;
}
@@ -498,11 +502,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
/* recreate the rx queue and the tx queue based on the
* new sizes */
- vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
- vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+ vmxnet3_tq_destroy_all(adapter);
+ vmxnet3_rq_destroy_all(adapter);
err = vmxnet3_create_queues(adapter, new_tx_ring_size,
new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE);
+
if (err) {
/* failed, most likely because of OOM, try default
* size */
@@ -535,6 +540,66 @@ out:
}
+static int
+vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
+ void *rules)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ switch (info->cmd) {
+ case ETHTOOL_GRXRINGS:
+ info->data = adapter->num_rx_queues;
+ return 0;
+ }
+ return -EOPNOTSUPP;
+}
+
+#ifdef VMXNET3_RSS
+static int
+vmxnet3_get_rss_indir(struct net_device *netdev,
+ struct ethtool_rxfh_indir *p)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct UPT1_RSSConf *rssConf = adapter->rss_conf;
+ unsigned int n = min_t(unsigned int, p->size, rssConf->indTableSize);
+
+ p->size = rssConf->indTableSize;
+ while (n--)
+ p->ring_index[n] = rssConf->indTable[n];
+ return 0;
+
+}
+
+static int
+vmxnet3_set_rss_indir(struct net_device *netdev,
+ const struct ethtool_rxfh_indir *p)
+{
+ unsigned int i;
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct UPT1_RSSConf *rssConf = adapter->rss_conf;
+
+ if (p->size != rssConf->indTableSize)
+ return -EINVAL;
+ for (i = 0; i < rssConf->indTableSize; i++) {
+ /*
+ * Return with error code if any of the queue indices
+ * is out of range
+ */
+ if (p->ring_index[i] < 0 ||
+ p->ring_index[i] >= adapter->num_rx_queues)
+ return -EINVAL;
+ }
+
+ for (i = 0; i < rssConf->indTableSize; i++)
+ rssConf->indTable[i] = p->ring_index[i];
+
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_RSSIDT);
+
+ return 0;
+
+}
+#endif
+
static struct ethtool_ops vmxnet3_ethtool_ops = {
.get_settings = vmxnet3_get_settings,
.get_drvinfo = vmxnet3_get_drvinfo,
@@ -558,6 +623,11 @@ static struct ethtool_ops vmxnet3_ethtool_ops = {
.get_ethtool_stats = vmxnet3_get_ethtool_stats,
.get_ringparam = vmxnet3_get_ringparam,
.set_ringparam = vmxnet3_set_ringparam,
+ .get_rxnfc = vmxnet3_get_rxnfc,
+#ifdef VMXNET3_RSS
+ .get_rxfh_indir = vmxnet3_get_rss_indir,
+ .set_rxfh_indir = vmxnet3_set_rss_indir,
+#endif
};
void vmxnet3_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index edf228843afc..7fadeed37f03 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -68,11 +68,15 @@
/*
* Version numbers
*/
-#define VMXNET3_DRIVER_VERSION_STRING "1.0.14.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING "1.0.16.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM 0x01000E00
+#define VMXNET3_DRIVER_VERSION_NUM 0x01001000
+#if defined(CONFIG_PCI_MSI)
+ /* RSS only makes sense if MSI-X is supported. */
+ #define VMXNET3_RSS
+#endif
/*
* Capabilities
@@ -218,16 +222,19 @@ struct vmxnet3_tx_ctx {
};
struct vmxnet3_tx_queue {
+ char name[IFNAMSIZ+8]; /* To identify interrupt */
+ struct vmxnet3_adapter *adapter;
spinlock_t tx_lock;
struct vmxnet3_cmd_ring tx_ring;
- struct vmxnet3_tx_buf_info *buf_info;
+ struct vmxnet3_tx_buf_info *buf_info;
struct vmxnet3_tx_data_ring data_ring;
struct vmxnet3_comp_ring comp_ring;
- struct Vmxnet3_TxQueueCtrl *shared;
+ struct Vmxnet3_TxQueueCtrl *shared;
struct vmxnet3_tq_driver_stats stats;
bool stopped;
int num_stop; /* # of times the queue is
* stopped */
+ int qid;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
enum vmxnet3_rx_buf_type {
@@ -259,6 +266,9 @@ struct vmxnet3_rq_driver_stats {
};
struct vmxnet3_rx_queue {
+ char name[IFNAMSIZ + 8]; /* To identify interrupt */
+ struct vmxnet3_adapter *adapter;
+ struct napi_struct napi;
struct vmxnet3_cmd_ring rx_ring[2];
struct vmxnet3_comp_ring comp_ring;
struct vmxnet3_rx_ctx rx_ctx;
@@ -271,7 +281,16 @@ struct vmxnet3_rx_queue {
struct vmxnet3_rq_driver_stats stats;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
-#define VMXNET3_LINUX_MAX_MSIX_VECT 1
+#define VMXNET3_DEVICE_MAX_TX_QUEUES 8
+#define VMXNET3_DEVICE_MAX_RX_QUEUES 8 /* Keep this value as a power of 2 */
+
+/* Should be less than UPT1_RSS_MAX_IND_TABLE_SIZE */
+#define VMXNET3_RSS_IND_TABLE_SIZE (VMXNET3_DEVICE_MAX_RX_QUEUES * 4)
+
+#define VMXNET3_LINUX_MAX_MSIX_VECT (VMXNET3_DEVICE_MAX_TX_QUEUES + \
+ VMXNET3_DEVICE_MAX_RX_QUEUES + 1)
+#define VMXNET3_LINUX_MIN_MSIX_VECT 3 /* 1 for each : tx, rx and event */
+
struct vmxnet3_intr {
enum vmxnet3_intr_mask_mode mask_mode;
@@ -279,27 +298,32 @@ struct vmxnet3_intr {
u8 num_intrs; /* # of intr vectors */
u8 event_intr_idx; /* idx of the intr vector for event */
u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
+ char event_msi_vector_name[IFNAMSIZ+11];
#ifdef CONFIG_PCI_MSI
struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
#endif
};
+/* Interrupt sharing schemes, share_intr */
+#define VMXNET3_INTR_BUDDYSHARE 0 /* Corresponding tx,rx queues share irq */
+#define VMXNET3_INTR_TXSHARE 1 /* All tx queues share one irq */
+#define VMXNET3_INTR_DONTSHARE 2 /* each queue has its own irq */
+
+
#define VMXNET3_STATE_BIT_RESETTING 0
#define VMXNET3_STATE_BIT_QUIESCED 1
struct vmxnet3_adapter {
- struct vmxnet3_tx_queue tx_queue;
- struct vmxnet3_rx_queue rx_queue;
- struct napi_struct napi;
- struct vlan_group *vlan_grp;
-
- struct vmxnet3_intr intr;
-
- struct Vmxnet3_DriverShared *shared;
- struct Vmxnet3_PMConf *pm_conf;
- struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */
- struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */
- struct net_device *netdev;
- struct pci_dev *pdev;
+ struct vmxnet3_tx_queue tx_queue[VMXNET3_DEVICE_MAX_TX_QUEUES];
+ struct vmxnet3_rx_queue rx_queue[VMXNET3_DEVICE_MAX_RX_QUEUES];
+ struct vlan_group *vlan_grp;
+ struct vmxnet3_intr intr;
+ struct Vmxnet3_DriverShared *shared;
+ struct Vmxnet3_PMConf *pm_conf;
+ struct Vmxnet3_TxQueueDesc *tqd_start; /* all tx queue desc */
+ struct Vmxnet3_RxQueueDesc *rqd_start; /* all rx queue desc */
+ struct net_device *netdev;
+ struct net_device_stats net_stats;
+ struct pci_dev *pdev;
u8 __iomem *hw_addr0; /* for BAR 0 */
u8 __iomem *hw_addr1; /* for BAR 1 */
@@ -308,6 +332,12 @@ struct vmxnet3_adapter {
bool rxcsum;
bool lro;
bool jumbo_frame;
+#ifdef VMXNET3_RSS
+ struct UPT1_RSSConf *rss_conf;
+ bool rss;
+#endif
+ u32 num_rx_queues;
+ u32 num_tx_queues;
/* rx buffer related */
unsigned skb_buf_size;
@@ -327,6 +357,7 @@ struct vmxnet3_adapter {
unsigned long state; /* VMXNET3_STATE_BIT_xxx */
int dev_number;
+ int share_intr;
};
#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \
@@ -366,12 +397,10 @@ void
vmxnet3_reset_dev(struct vmxnet3_adapter *adapter);
void
-vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
- struct vmxnet3_adapter *adapter);
+vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter);
void
-vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
- struct vmxnet3_adapter *adapter);
+vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 906a3ca3676b..01c05f53e2f9 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -19,109 +19,128 @@
#include "vxge-traffic.h"
#include "vxge-config.h"
-
-static enum vxge_hw_status
-__vxge_hw_fifo_create(
- struct __vxge_hw_vpath_handle *vpath_handle,
- struct vxge_hw_fifo_attr *attr);
-
-static enum vxge_hw_status
-__vxge_hw_fifo_abort(
- struct __vxge_hw_fifo *fifoh);
-
-static enum vxge_hw_status
-__vxge_hw_fifo_reset(
- struct __vxge_hw_fifo *ringh);
-
-static enum vxge_hw_status
-__vxge_hw_fifo_delete(
- struct __vxge_hw_vpath_handle *vpath_handle);
-
-static struct __vxge_hw_blockpool_entry *
-__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *hldev,
- u32 size);
+#include "vxge-main.h"
+
+#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \
+ status = __vxge_hw_vpath_stats_access(vpath, \
+ VXGE_HW_STATS_OP_READ, \
+ offset, \
+ &val64); \
+ if (status != VXGE_HW_OK) \
+ return status; \
+}
static void
-__vxge_hw_blockpool_block_free(struct __vxge_hw_device *hldev,
- struct __vxge_hw_blockpool_entry *entry);
-
-static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh,
- void *block_addr,
- u32 length,
- struct pci_dev *dma_h,
- struct pci_dev *acc_handle);
-
-static enum vxge_hw_status
-__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
- struct __vxge_hw_blockpool *blockpool,
- u32 pool_size,
- u32 pool_max);
+vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg)
+{
+ u64 val64;
-static void
-__vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool);
+ val64 = readq(&vp_reg->rxmac_vcfg0);
+ val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
+ writeq(val64, &vp_reg->rxmac_vcfg0);
+ val64 = readq(&vp_reg->rxmac_vcfg0);
+}
-static void *
-__vxge_hw_blockpool_malloc(struct __vxge_hw_device *hldev,
- u32 size,
- struct vxge_hw_mempool_dma *dma_object);
+/*
+ * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle
+ */
+int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct __vxge_hw_virtualpath *vpath;
+ u64 val64, rxd_count, rxd_spat;
+ int count = 0, total_count = 0;
-static void
-__vxge_hw_blockpool_free(struct __vxge_hw_device *hldev,
- void *memblock,
- u32 size,
- struct vxge_hw_mempool_dma *dma_object);
+ vpath = &hldev->virtual_paths[vp_id];
+ vp_reg = vpath->vp_reg;
+ vxge_hw_vpath_set_zero_rx_frm_len(vp_reg);
-static struct __vxge_hw_channel*
-__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
- enum __vxge_hw_channel_type type, u32 length,
- u32 per_dtr_space, void *userdata);
+ /* Check that the ring controller for this vpath has enough free RxDs
+ * to send frames to the host. This is done by reading the
+ * PRC_RXD_DOORBELL_VPn register and comparing the read value to the
+ * RXD_SPAT value for the vpath.
+ */
+ val64 = readq(&vp_reg->prc_cfg6);
+ rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1;
+ /* Use a factor of 2 when comparing rxd_count against rxd_spat for some
+ * leg room.
+ */
+ rxd_spat *= 2;
-static void
-__vxge_hw_channel_free(
- struct __vxge_hw_channel *channel);
+ do {
+ mdelay(1);
-static enum vxge_hw_status
-__vxge_hw_channel_initialize(
- struct __vxge_hw_channel *channel);
+ rxd_count = readq(&vp_reg->prc_rxd_doorbell);
-static enum vxge_hw_status
-__vxge_hw_channel_reset(
- struct __vxge_hw_channel *channel);
+ /* Check that the ring controller for this vpath does
+ * not have any frame in its pipeline.
+ */
+ val64 = readq(&vp_reg->frm_in_progress_cnt);
+ if ((rxd_count <= rxd_spat) || (val64 > 0))
+ count = 0;
+ else
+ count++;
+ total_count++;
+ } while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) &&
+ (total_count < VXGE_HW_MAX_POLLING_COUNT));
-static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp);
+ if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
+ printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n",
+ __func__);
-static enum vxge_hw_status
-__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config);
+ return total_count;
+}
-static enum vxge_hw_status
-__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config);
+/* vxge_hw_device_wait_receive_idle - This function waits until all frames
+ * stored in the frame buffer for each vpath assigned to the given
+ * function (hldev) have been sent to the host.
+ */
+void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev)
+{
+ int i, total_count = 0;
-static void
-__vxge_hw_device_id_get(struct __vxge_hw_device *hldev);
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+ continue;
-static void
-__vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev);
+ total_count += vxge_hw_vpath_wait_receive_idle(hldev, i);
+ if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
+ break;
+ }
+}
+/*
+ * __vxge_hw_device_register_poll
+ * Will poll certain register for specified amount of time.
+ * Will poll until masked bit is not cleared.
+ */
static enum vxge_hw_status
-__vxge_hw_vpath_card_info_get(
- u32 vp_id,
- struct vxge_hw_vpath_reg __iomem *vpath_reg,
- struct vxge_hw_device_hw_info *hw_info);
+__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
+{
+ u64 val64;
+ u32 i = 0;
+ enum vxge_hw_status ret = VXGE_HW_FAIL;
-static enum vxge_hw_status
-__vxge_hw_device_initialize(struct __vxge_hw_device *hldev);
+ udelay(10);
-static void
-__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev);
+ do {
+ val64 = readq(reg);
+ if (!(val64 & mask))
+ return VXGE_HW_OK;
+ udelay(100);
+ } while (++i <= 9);
-static enum vxge_hw_status
-__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev);
+ i = 0;
+ do {
+ val64 = readq(reg);
+ if (!(val64 & mask))
+ return VXGE_HW_OK;
+ mdelay(1);
+ } while (++i <= max_millis);
-static enum vxge_hw_status
-__vxge_hw_device_register_poll(
- void __iomem *reg,
- u64 mask, u32 max_millis);
+ return ret;
+}
static inline enum vxge_hw_status
__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr,
@@ -129,139 +148,258 @@ __vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr,
{
__vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr);
wmb();
-
__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr);
wmb();
- return __vxge_hw_device_register_poll(addr, mask, max_millis);
+ return __vxge_hw_device_register_poll(addr, mask, max_millis);
}
-static struct vxge_hw_mempool*
-__vxge_hw_mempool_create(struct __vxge_hw_device *devh, u32 memblock_size,
- u32 item_size, u32 private_size, u32 items_initial,
- u32 items_max, struct vxge_hw_mempool_cbs *mp_callback,
- void *userdata);
-static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool);
-
static enum vxge_hw_status
-__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_vpath_stats_hw_info *hw_stats);
+vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action,
+ u32 fw_memo, u32 offset, u64 *data0, u64 *data1,
+ u64 *steer_ctrl)
+{
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ enum vxge_hw_status status;
+ u64 val64;
+ u32 retry = 0, max_retry = 100;
-static enum vxge_hw_status
-vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vpath_handle);
+ vp_reg = vpath->vp_reg;
-static enum vxge_hw_status
-__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg);
+ if (vpath->vp_open) {
+ max_retry = 3;
+ spin_lock(&vpath->lock);
+ }
-static u64
-__vxge_hw_vpath_pci_func_mode_get(u32 vp_id,
- struct vxge_hw_vpath_reg __iomem *vpath_reg);
+ writeq(*data0, &vp_reg->rts_access_steer_data0);
+ writeq(*data1, &vp_reg->rts_access_steer_data1);
+ wmb();
-static u32
-__vxge_hw_vpath_func_id_get(u32 vp_id, struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg);
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ *steer_ctrl;
-static enum vxge_hw_status
-__vxge_hw_vpath_addr_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
- u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN]);
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ /* The __vxge_hw_device_register_poll can udelay for a significant
+ * amount of time, blocking other proccess from the CPU. If it delays
+ * for ~5secs, a NMI error can occur. A way around this is to give up
+ * the processor via msleep, but this is not allowed is under lock.
+ * So, only allow it to sleep for ~4secs if open. Otherwise, delay for
+ * 1sec and sleep for 10ms until the firmware operation has completed
+ * or timed-out.
+ */
+ while ((status != VXGE_HW_OK) && retry++ < max_retry) {
+ if (!vpath->vp_open)
+ msleep(20);
+ status = __vxge_hw_device_register_poll(
+ &vp_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+ }
-static enum vxge_hw_status
-__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath);
+ if (status != VXGE_HW_OK)
+ goto out;
+ val64 = readq(&vp_reg->rts_access_steer_ctrl);
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+ *data0 = readq(&vp_reg->rts_access_steer_data0);
+ *data1 = readq(&vp_reg->rts_access_steer_data1);
+ *steer_ctrl = val64;
+ } else
+ status = VXGE_HW_FAIL;
-static enum vxge_hw_status
-__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id);
+out:
+ if (vpath->vp_open)
+ spin_unlock(&vpath->lock);
+ return status;
+}
-static enum vxge_hw_status
-__vxge_hw_vpath_fw_ver_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
- struct vxge_hw_device_hw_info *hw_info);
+enum vxge_hw_status
+vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major,
+ u32 *minor, u32 *build)
+{
+ u64 data0 = 0, data1 = 0, steer_ctrl = 0;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status;
-static enum vxge_hw_status
-__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id);
+ vpath = &hldev->virtual_paths[hldev->first_vp_id];
-static void
-__vxge_hw_vp_terminate(struct __vxge_hw_device *devh, u32 vp_id);
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_FW_UPGRADE_ACTION,
+ VXGE_HW_FW_UPGRADE_MEMO,
+ VXGE_HW_FW_UPGRADE_OFFSET_READ,
+ &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ return status;
-static enum vxge_hw_status
-__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
- u32 operation, u32 offset, u64 *stat);
+ *major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0);
+ *minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0);
+ *build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0);
-static enum vxge_hw_status
-__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats);
+ return status;
+}
-static enum vxge_hw_status
-__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats);
+enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev)
+{
+ u64 data0 = 0, data1 = 0, steer_ctrl = 0;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status;
+ u32 ret;
-/*
- * __vxge_hw_channel_allocate - Allocate memory for channel
- * This function allocates required memory for the channel and various arrays
- * in the channel
- */
-struct __vxge_hw_channel*
-__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
- enum __vxge_hw_channel_type type,
- u32 length, u32 per_dtr_space, void *userdata)
+ vpath = &hldev->virtual_paths[hldev->first_vp_id];
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_FW_UPGRADE_ACTION,
+ VXGE_HW_FW_UPGRADE_MEMO,
+ VXGE_HW_FW_UPGRADE_OFFSET_COMMIT,
+ &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__);
+ goto exit;
+ }
+
+ ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F;
+ if (ret != 1) {
+ vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d",
+ __func__, ret);
+ status = VXGE_HW_FAIL;
+ }
+
+exit:
+ return status;
+}
+
+enum vxge_hw_status
+vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size)
{
- struct __vxge_hw_channel *channel;
- struct __vxge_hw_device *hldev;
- int size = 0;
- u32 vp_id;
+ u64 data0 = 0, data1 = 0, steer_ctrl = 0;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status;
+ int ret_code, sec_code;
- hldev = vph->vpath->hldev;
- vp_id = vph->vpath->vp_id;
+ vpath = &hldev->virtual_paths[hldev->first_vp_id];
- switch (type) {
- case VXGE_HW_CHANNEL_TYPE_FIFO:
- size = sizeof(struct __vxge_hw_fifo);
- break;
- case VXGE_HW_CHANNEL_TYPE_RING:
- size = sizeof(struct __vxge_hw_ring);
- break;
- default:
- break;
+ /* send upgrade start command */
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_FW_UPGRADE_ACTION,
+ VXGE_HW_FW_UPGRADE_MEMO,
+ VXGE_HW_FW_UPGRADE_OFFSET_START,
+ &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed",
+ __func__);
+ return status;
}
- channel = kzalloc(size, GFP_KERNEL);
- if (channel == NULL)
- goto exit0;
- INIT_LIST_HEAD(&channel->item);
+ /* Transfer fw image to adapter 16 bytes at a time */
+ for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) {
+ steer_ctrl = 0;
- channel->common_reg = hldev->common_reg;
- channel->first_vp_id = hldev->first_vp_id;
- channel->type = type;
- channel->devh = hldev;
- channel->vph = vph;
- channel->userdata = userdata;
- channel->per_dtr_space = per_dtr_space;
- channel->length = length;
- channel->vp_id = vp_id;
+ /* The next 128bits of fwdata to be loaded onto the adapter */
+ data0 = *((u64 *)fwdata);
+ data1 = *((u64 *)fwdata + 1);
- channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
- if (channel->work_arr == NULL)
- goto exit1;
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_FW_UPGRADE_ACTION,
+ VXGE_HW_FW_UPGRADE_MEMO,
+ VXGE_HW_FW_UPGRADE_OFFSET_SEND,
+ &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed",
+ __func__);
+ goto out;
+ }
- channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
- if (channel->free_arr == NULL)
- goto exit1;
- channel->free_ptr = length;
+ ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0);
+ switch (ret_code) {
+ case VXGE_HW_FW_UPGRADE_OK:
+ /* All OK, send next 16 bytes. */
+ break;
+ case VXGE_FW_UPGRADE_BYTES2SKIP:
+ /* skip bytes in the stream */
+ fwdata += (data0 >> 8) & 0xFFFFFFFF;
+ break;
+ case VXGE_HW_FW_UPGRADE_DONE:
+ goto out;
+ case VXGE_HW_FW_UPGRADE_ERR:
+ sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0);
+ switch (sec_code) {
+ case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1:
+ case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7:
+ printk(KERN_ERR
+ "corrupted data from .ncf file\n");
+ break;
+ case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3:
+ case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4:
+ case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5:
+ case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6:
+ case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8:
+ printk(KERN_ERR "invalid .ncf file\n");
+ break;
+ case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW:
+ printk(KERN_ERR "buffer overflow\n");
+ break;
+ case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH:
+ printk(KERN_ERR "failed to flash the image\n");
+ break;
+ case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN:
+ printk(KERN_ERR
+ "generic error. Unknown error type\n");
+ break;
+ default:
+ printk(KERN_ERR "Unknown error of type %d\n",
+ sec_code);
+ break;
+ }
+ status = VXGE_HW_FAIL;
+ goto out;
+ default:
+ printk(KERN_ERR "Unknown FW error: %d\n", ret_code);
+ status = VXGE_HW_FAIL;
+ goto out;
+ }
+ /* point to next 16 bytes */
+ fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE;
+ }
+out:
+ return status;
+}
- channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
- if (channel->reserve_arr == NULL)
- goto exit1;
- channel->reserve_ptr = length;
- channel->reserve_top = 0;
+enum vxge_hw_status
+vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev,
+ struct eprom_image *img)
+{
+ u64 data0 = 0, data1 = 0, steer_ctrl = 0;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status;
+ int i;
- channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
- if (channel->orig_arr == NULL)
- goto exit1;
+ vpath = &hldev->virtual_paths[hldev->first_vp_id];
- return channel;
-exit1:
- __vxge_hw_channel_free(channel);
+ for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) {
+ data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i);
+ data1 = steer_ctrl = 0;
-exit0:
- return NULL;
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ VXGE_HW_FW_API_GET_EPROM_REV,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ break;
+
+ img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0);
+ img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0);
+ img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0);
+ img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0);
+ }
+
+ return status;
}
/*
@@ -269,7 +407,7 @@ exit0:
* This function deallocates memory from the channel and various arrays
* in the channel
*/
-void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
+static void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
{
kfree(channel->work_arr);
kfree(channel->free_arr);
@@ -283,7 +421,7 @@ void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
* This function initializes a channel by properly setting the
* various references
*/
-enum vxge_hw_status
+static enum vxge_hw_status
__vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
{
u32 i;
@@ -318,7 +456,7 @@ __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
* __vxge_hw_channel_reset - Resets a channel
* This function resets a channel by properly setting the various references
*/
-enum vxge_hw_status
+static enum vxge_hw_status
__vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
{
u32 i;
@@ -345,8 +483,7 @@ __vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
* Initialize certain PCI/PCI-X configuration registers
* with recommended values. Save config space for future hw resets.
*/
-void
-__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
+static void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
{
u16 cmd = 0;
@@ -358,39 +495,7 @@ __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
pci_save_state(hldev->pdev);
}
-/*
- * __vxge_hw_device_register_poll
- * Will poll certain register for specified amount of time.
- * Will poll until masked bit is not cleared.
- */
-static enum vxge_hw_status
-__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
-{
- u64 val64;
- u32 i = 0;
- enum vxge_hw_status ret = VXGE_HW_FAIL;
-
- udelay(10);
-
- do {
- val64 = readq(reg);
- if (!(val64 & mask))
- return VXGE_HW_OK;
- udelay(100);
- } while (++i <= 9);
-
- i = 0;
- do {
- val64 = readq(reg);
- if (!(val64 & mask))
- return VXGE_HW_OK;
- mdelay(1);
- } while (++i <= max_millis);
-
- return ret;
-}
-
- /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
+/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
* in progress
* This routine checks the vpath reset in progress register is turned zero
*/
@@ -405,6 +510,60 @@ __vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
}
/*
+ * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
+ * Set the swapper bits appropriately for the lagacy section.
+ */
+static enum vxge_hw_status
+__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = readq(&legacy_reg->toc_swapper_fb);
+
+ wmb();
+
+ switch (val64) {
+ case VXGE_HW_SWAPPER_INITIAL_VALUE:
+ return status;
+
+ case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_rd_swap_en);
+ writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_rd_flip_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_wr_swap_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_wr_flip_en);
+ break;
+
+ case VXGE_HW_SWAPPER_BYTE_SWAPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_rd_swap_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_wr_swap_en);
+ break;
+
+ case VXGE_HW_SWAPPER_BIT_FLIPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_rd_flip_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_wr_flip_en);
+ break;
+ }
+
+ wmb();
+
+ val64 = readq(&legacy_reg->toc_swapper_fb);
+
+ if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
+ status = VXGE_HW_ERR_SWAPPER_CTRL;
+
+ return status;
+}
+
+/*
* __vxge_hw_device_toc_get
* This routine sets the swapper and reads the toc pointer and returns the
* memory mapped address of the toc
@@ -435,7 +594,7 @@ exit:
* register location pointers in the device object. It waits until the ric is
* completed initializing registers.
*/
-enum vxge_hw_status
+static enum vxge_hw_status
__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
{
u64 val64;
@@ -496,26 +655,6 @@ exit:
}
/*
- * __vxge_hw_device_id_get
- * This routine returns sets the device id and revision numbers into the device
- * structure
- */
-void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev)
-{
- u64 val64;
-
- val64 = readq(&hldev->common_reg->titan_asic_id);
- hldev->device_id =
- (u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64);
-
- hldev->major_revision =
- (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64);
-
- hldev->minor_revision =
- (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64);
-}
-
-/*
* __vxge_hw_device_access_rights_get: Get Access Rights of the driver
* This routine returns the Access Rights of the driver
*/
@@ -568,10 +707,25 @@ __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id)
}
/*
+ * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
+ * Returns the function number of the vpath.
+ */
+static u32
+__vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
+{
+ u64 val64;
+
+ val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
+
+ return
+ (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
+}
+
+/*
* __vxge_hw_device_host_info_get
* This routine returns the host type assignments
*/
-void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
+static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
{
u64 val64;
u32 i;
@@ -584,16 +738,18 @@ void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
if (!(hldev->vpath_assignments & vxge_mBIT(i)))
continue;
hldev->func_id =
- __vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]);
+ __vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]);
hldev->access_rights = __vxge_hw_device_access_rights_get(
hldev->host_type, hldev->func_id);
+ hldev->virtual_paths[i].vp_open = VXGE_HW_VP_NOT_OPEN;
+ hldev->virtual_paths[i].vp_reg = hldev->vpath_reg[i];
+
hldev->first_vp_id = i;
break;
}
@@ -634,7 +790,8 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
* __vxge_hw_device_initialize
* Initialize Titan-V hardware.
*/
-enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
+static enum vxge_hw_status
+__vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
{
enum vxge_hw_status status = VXGE_HW_OK;
@@ -650,6 +807,196 @@ exit:
return status;
}
+/*
+ * __vxge_hw_vpath_fw_ver_get - Get the fw version
+ * Returns FW Version
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_fw_ver_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
+ struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
+ struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
+ struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
+ u64 data0, data1 = 0, steer_ctrl = 0;
+ enum vxge_hw_status status;
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ fw_date->day =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(data0);
+ fw_date->month =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(data0);
+ fw_date->year =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(data0);
+
+ snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
+ fw_date->month, fw_date->day, fw_date->year);
+
+ fw_version->major =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0);
+ fw_version->minor =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0);
+ fw_version->build =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0);
+
+ snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+ fw_version->major, fw_version->minor, fw_version->build);
+
+ flash_date->day =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data1);
+ flash_date->month =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data1);
+ flash_date->year =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data1);
+
+ snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
+ flash_date->month, flash_date->day, flash_date->year);
+
+ flash_version->major =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data1);
+ flash_version->minor =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data1);
+ flash_version->build =
+ (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data1);
+
+ snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+ flash_version->major, flash_version->minor,
+ flash_version->build);
+
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_card_info_get - Get the serial numbers,
+ * part number and product description.
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ enum vxge_hw_status status;
+ u64 data0, data1 = 0, steer_ctrl = 0;
+ u8 *serial_number = hw_info->serial_number;
+ u8 *part_number = hw_info->part_number;
+ u8 *product_desc = hw_info->product_desc;
+ u32 i, j = 0;
+
+ data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER;
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ ((u64 *)serial_number)[0] = be64_to_cpu(data0);
+ ((u64 *)serial_number)[1] = be64_to_cpu(data1);
+
+ data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER;
+ data1 = steer_ctrl = 0;
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ ((u64 *)part_number)[0] = be64_to_cpu(data0);
+ ((u64 *)part_number)[1] = be64_to_cpu(data1);
+
+ for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
+ i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
+ data0 = i;
+ data1 = steer_ctrl = 0;
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ ((u64 *)product_desc)[j++] = be64_to_cpu(data0);
+ ((u64 *)product_desc)[j++] = be64_to_cpu(data1);
+ }
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
+ * Returns pci function mode
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ u64 data0, data1 = 0, steer_ctrl = 0;
+ enum vxge_hw_status status;
+
+ data0 = 0;
+
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_FW_API_GET_FUNC_MODE,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ hw_info->function_mode = VXGE_HW_GET_FUNC_MODE_VAL(data0);
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
+ * from MAC address table.
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath,
+ u8 *macaddr, u8 *macaddr_mask)
+{
+ u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
+ data0 = 0, data1 = 0, steer_ctrl = 0;
+ enum vxge_hw_status status;
+ int i;
+
+ do {
+ status = vxge_hw_vpath_fw_api(vpath, action,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+ 0, &data0, &data1, &steer_ctrl);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data0);
+ data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
+ data1);
+
+ for (i = ETH_ALEN; i > 0; i--) {
+ macaddr[i - 1] = (u8) (data0 & 0xFF);
+ data0 >>= 8;
+
+ macaddr_mask[i - 1] = (u8) (data1 & 0xFF);
+ data1 >>= 8;
+ }
+
+ action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY;
+ data0 = 0, data1 = 0, steer_ctrl = 0;
+
+ } while (!is_valid_ether_addr(macaddr));
+exit:
+ return status;
+}
+
/**
* vxge_hw_device_hw_info_get - Get the hw information
* Returns the vpath mask that has the bits set for each vpath allocated
@@ -665,9 +1012,9 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
struct vxge_hw_toc_reg __iomem *toc;
struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
struct vxge_hw_common_reg __iomem *common_reg;
- struct vxge_hw_vpath_reg __iomem *vpath_reg;
struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
enum vxge_hw_status status;
+ struct __vxge_hw_virtualpath vpath;
memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
@@ -693,7 +1040,6 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
(u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
continue;
@@ -702,7 +1048,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *)
(bar0 + val64);
- hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg);
+ hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg);
if (__vxge_hw_device_access_rights_get(hw_info->host_type,
hw_info->func_id) &
VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
@@ -718,16 +1064,19 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
val64 = readq(&toc->toc_vpath_pointer[i]);
- vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+ vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
+ (bar0 + val64);
+ vpath.vp_open = 0;
- hw_info->function_mode =
- __vxge_hw_vpath_pci_func_mode_get(i, vpath_reg);
+ status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info);
+ if (status != VXGE_HW_OK)
+ goto exit;
- status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info);
+ status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info);
if (status != VXGE_HW_OK)
goto exit;
- status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info);
+ status = __vxge_hw_vpath_card_info_get(&vpath, hw_info);
if (status != VXGE_HW_OK)
goto exit;
@@ -735,14 +1084,15 @@ vxge_hw_device_hw_info_get(void __iomem *bar0,
}
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
continue;
val64 = readq(&toc->toc_vpath_pointer[i]);
- vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+ vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
+ (bar0 + val64);
+ vpath.vp_open = 0;
- status = __vxge_hw_vpath_addr_get(i, vpath_reg,
+ status = __vxge_hw_vpath_addr_get(&vpath,
hw_info->mac_addrs[i],
hw_info->mac_addr_masks[i]);
if (status != VXGE_HW_OK)
@@ -753,6 +1103,218 @@ exit:
}
/*
+ * __vxge_hw_blockpool_destroy - Deallocates the block pool
+ */
+static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
+{
+ struct __vxge_hw_device *hldev;
+ struct list_head *p, *n;
+ u16 ret;
+
+ if (blockpool == NULL) {
+ ret = 1;
+ goto exit;
+ }
+
+ hldev = blockpool->hldev;
+
+ list_for_each_safe(p, n, &blockpool->free_block_list) {
+ pci_unmap_single(hldev->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ PCI_DMA_BIDIRECTIONAL);
+
+ vxge_os_dma_free(hldev->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->memblock,
+ &((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
+
+ list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
+ kfree(p);
+ blockpool->pool_size--;
+ }
+
+ list_for_each_safe(p, n, &blockpool->free_entry_list) {
+ list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
+ kfree((void *)p);
+ }
+ ret = 0;
+exit:
+ return;
+}
+
+/*
+ * __vxge_hw_blockpool_create - Create block pool
+ */
+static enum vxge_hw_status
+__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
+ struct __vxge_hw_blockpool *blockpool,
+ u32 pool_size,
+ u32 pool_max)
+{
+ u32 i;
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ void *memblock;
+ dma_addr_t dma_addr;
+ struct pci_dev *dma_handle;
+ struct pci_dev *acc_handle;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (blockpool == NULL) {
+ status = VXGE_HW_FAIL;
+ goto blockpool_create_exit;
+ }
+
+ blockpool->hldev = hldev;
+ blockpool->block_size = VXGE_HW_BLOCK_SIZE;
+ blockpool->pool_size = 0;
+ blockpool->pool_max = pool_max;
+ blockpool->req_out = 0;
+
+ INIT_LIST_HEAD(&blockpool->free_block_list);
+ INIT_LIST_HEAD(&blockpool->free_entry_list);
+
+ for (i = 0; i < pool_size + pool_max; i++) {
+ entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+ GFP_KERNEL);
+ if (entry == NULL) {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+ list_add(&entry->item, &blockpool->free_entry_list);
+ }
+
+ for (i = 0; i < pool_size; i++) {
+ memblock = vxge_os_dma_malloc(
+ hldev->pdev,
+ VXGE_HW_BLOCK_SIZE,
+ &dma_handle,
+ &acc_handle);
+ if (memblock == NULL) {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+
+ dma_addr = pci_map_single(hldev->pdev, memblock,
+ VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(hldev->pdev,
+ dma_addr))) {
+ vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry == NULL)
+ entry =
+ kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+ GFP_KERNEL);
+ if (entry != NULL) {
+ list_del(&entry->item);
+ entry->length = VXGE_HW_BLOCK_SIZE;
+ entry->memblock = memblock;
+ entry->dma_addr = dma_addr;
+ entry->acc_handle = acc_handle;
+ entry->dma_handle = dma_handle;
+ list_add(&entry->item,
+ &blockpool->free_block_list);
+ blockpool->pool_size++;
+ } else {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+ }
+
+blockpool_create_exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_device_fifo_config_check - Check fifo configuration.
+ * Check the fifo configuration
+ */
+static enum vxge_hw_status
+__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
+{
+ if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
+ (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
+ return VXGE_HW_BADCFG_FIFO_BLOCKS;
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_vpath_config_check - Check vpath configuration.
+ * Check the vpath configuration
+ */
+static enum vxge_hw_status
+__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
+{
+ enum vxge_hw_status status;
+
+ if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
+ (vp_config->min_bandwidth > VXGE_HW_VPATH_BANDWIDTH_MAX))
+ return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
+
+ status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
+ ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
+ (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
+ return VXGE_HW_BADCFG_VPATH_MTU;
+
+ if ((vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
+ (vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
+ (vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
+ return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_config_check - Check device configuration.
+ * Check the device configuration
+ */
+static enum vxge_hw_status
+__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
+{
+ u32 i;
+ enum vxge_hw_status status;
+
+ if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
+ return VXGE_HW_BADCFG_INTR_MODE;
+
+ if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
+ (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
+ return VXGE_HW_BADCFG_RTS_MAC_EN;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ status = __vxge_hw_device_vpath_config_check(
+ &new_config->vp_config[i]);
+ if (status != VXGE_HW_OK)
+ return status;
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
* vxge_hw_device_initialize - Initialize Titan device.
* Initialize Titan device. Note that all the arguments of this public API
* are 'IN', including @hldev. Driver cooperates with
@@ -776,14 +1338,12 @@ vxge_hw_device_initialize(
if (status != VXGE_HW_OK)
goto exit;
- hldev = (struct __vxge_hw_device *)
- vmalloc(sizeof(struct __vxge_hw_device));
+ hldev = vzalloc(sizeof(struct __vxge_hw_device));
if (hldev == NULL) {
status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto exit;
}
- memset(hldev, 0, sizeof(struct __vxge_hw_device));
hldev->magic = VXGE_HW_DEVICE_MAGIC;
vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL);
@@ -806,7 +1366,6 @@ vxge_hw_device_initialize(
vfree(hldev);
goto exit;
}
- __vxge_hw_device_id_get(hldev);
__vxge_hw_device_host_info_get(hldev);
@@ -814,7 +1373,6 @@ vxge_hw_device_initialize(
nblocks++;
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
if (!(hldev->vpath_assignments & vxge_mBIT(i)))
continue;
@@ -839,7 +1397,6 @@ vxge_hw_device_initialize(
}
status = __vxge_hw_device_initialize(hldev);
-
if (status != VXGE_HW_OK) {
vxge_hw_device_terminate(hldev);
goto exit;
@@ -865,6 +1422,242 @@ vxge_hw_device_terminate(struct __vxge_hw_device *hldev)
}
/*
+ * __vxge_hw_vpath_stats_access - Get the statistics from the given location
+ * and offset and perform an operation
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
+ u32 operation, u32 offset, u64 *stat)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto vpath_stats_access_exit;
+ }
+
+ vp_reg = vpath->vp_reg;
+
+ val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->xmac_stats_access_cmd,
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
+ vpath->hldev->config.device_poll_millis);
+ if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
+ *stat = readq(&vp_reg->xmac_stats_access_data);
+ else
+ *stat = 0;
+
+vpath_stats_access_exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
+{
+ u64 *val64;
+ int i;
+ u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = (u64 *)vpath_tx_stats;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
+ status = __vxge_hw_vpath_stats_access(vpath,
+ VXGE_HW_STATS_OP_READ,
+ offset, val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ offset++;
+ val64++;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
+{
+ u64 *val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ int i;
+ u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
+ val64 = (u64 *) vpath_rx_stats;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
+ status = __vxge_hw_vpath_stats_access(vpath,
+ VXGE_HW_STATS_OP_READ,
+ offset >> 3, val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ offset += 8;
+ val64++;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_vpath_stats_hw_info *hw_stats)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+ vp_reg = vpath->vp_reg;
+
+ val64 = readq(&vp_reg->vpath_debug_stats0);
+ hw_stats->ini_num_mwr_sent =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats1);
+ hw_stats->ini_num_mrd_sent =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats2);
+ hw_stats->ini_num_cpl_rcvd =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats3);
+ hw_stats->ini_num_mwr_byte_sent =
+ VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats4);
+ hw_stats->ini_num_cpl_byte_rcvd =
+ VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats5);
+ hw_stats->wrcrdtarb_xoff =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats6);
+ hw_stats->rdcrdtarb_xoff =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count0 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count1 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count23);
+ hw_stats->vpath_genstats_count2 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count3 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count4);
+ hw_stats->vpath_genstats_count4 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count5);
+ hw_stats->vpath_genstats_count5 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
+ val64);
+
+ status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ VXGE_HW_VPATH_STATS_PIO_READ(
+ VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
+
+ hw_stats->prog_event_vnum0 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
+
+ hw_stats->prog_event_vnum1 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
+
+ VXGE_HW_VPATH_STATS_PIO_READ(
+ VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
+
+ hw_stats->prog_event_vnum2 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
+
+ hw_stats->prog_event_vnum3 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
+
+ val64 = readq(&vp_reg->rx_multi_cast_stats);
+ hw_stats->rx_multi_cast_frame_discard =
+ (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
+
+ val64 = readq(&vp_reg->rx_frm_transferred);
+ hw_stats->rx_frm_transferred =
+ (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
+
+ val64 = readq(&vp_reg->rxd_returned);
+ hw_stats->rxd_returned =
+ (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
+
+ val64 = readq(&vp_reg->dbg_stats_rx_mpa);
+ hw_stats->rx_mpa_len_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
+ hw_stats->rx_mpa_mrk_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
+ hw_stats->rx_mpa_crc_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
+
+ val64 = readq(&vp_reg->dbg_stats_rx_fau);
+ hw_stats->rx_permitted_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
+ hw_stats->rx_vp_reset_discarded_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
+ hw_stats->rx_wol_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
+
+ val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
+ hw_stats->tx_vp_reset_discarded_frms =
+ (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
+ val64);
+exit:
+ return status;
+}
+
+/*
* vxge_hw_device_stats_get - Get the device hw statistics.
* Returns the vpath h/w stats for the device.
*/
@@ -876,7 +1669,6 @@ vxge_hw_device_stats_get(struct __vxge_hw_device *hldev,
enum vxge_hw_status status = VXGE_HW_OK;
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
if (!(hldev->vpaths_deployed & vxge_mBIT(i)) ||
(hldev->virtual_paths[i].vp_open ==
VXGE_HW_VP_NOT_OPEN))
@@ -1031,7 +1823,6 @@ vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev,
status = vxge_hw_device_xmac_aggr_stats_get(hldev,
0, &xmac_stats->aggr_stats[0]);
-
if (status != VXGE_HW_OK)
goto exit;
@@ -1165,7 +1956,6 @@ exit:
* It can be used to set or reset Pause frame generation or reception
* support of the NIC.
*/
-
enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
u32 port, u32 tx, u32 rx)
{
@@ -1407,190 +2197,359 @@ exit:
}
/*
- * __vxge_hw_ring_create - Create a Ring
- * This function creates Ring and initializes it.
- *
+ * __vxge_hw_channel_allocate - Allocate memory for channel
+ * This function allocates required memory for the channel and various arrays
+ * in the channel
*/
-static enum vxge_hw_status
-__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
- struct vxge_hw_ring_attr *attr)
+static struct __vxge_hw_channel *
+__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
+ enum __vxge_hw_channel_type type,
+ u32 length, u32 per_dtr_space,
+ void *userdata)
{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct __vxge_hw_ring *ring;
- u32 ring_length;
- struct vxge_hw_ring_config *config;
+ struct __vxge_hw_channel *channel;
struct __vxge_hw_device *hldev;
+ int size = 0;
u32 vp_id;
- struct vxge_hw_mempool_cbs ring_mp_callback;
- if ((vp == NULL) || (attr == NULL)) {
+ hldev = vph->vpath->hldev;
+ vp_id = vph->vpath->vp_id;
+
+ switch (type) {
+ case VXGE_HW_CHANNEL_TYPE_FIFO:
+ size = sizeof(struct __vxge_hw_fifo);
+ break;
+ case VXGE_HW_CHANNEL_TYPE_RING:
+ size = sizeof(struct __vxge_hw_ring);
+ break;
+ default:
+ break;
+ }
+
+ channel = kzalloc(size, GFP_KERNEL);
+ if (channel == NULL)
+ goto exit0;
+ INIT_LIST_HEAD(&channel->item);
+
+ channel->common_reg = hldev->common_reg;
+ channel->first_vp_id = hldev->first_vp_id;
+ channel->type = type;
+ channel->devh = hldev;
+ channel->vph = vph;
+ channel->userdata = userdata;
+ channel->per_dtr_space = per_dtr_space;
+ channel->length = length;
+ channel->vp_id = vp_id;
+
+ channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->work_arr == NULL)
+ goto exit1;
+
+ channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->free_arr == NULL)
+ goto exit1;
+ channel->free_ptr = length;
+
+ channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->reserve_arr == NULL)
+ goto exit1;
+ channel->reserve_ptr = length;
+ channel->reserve_top = 0;
+
+ channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->orig_arr == NULL)
+ goto exit1;
+
+ return channel;
+exit1:
+ __vxge_hw_channel_free(channel);
+
+exit0:
+ return NULL;
+}
+
+/*
+ * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
+ * Adds a block to block pool
+ */
+static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh,
+ void *block_addr,
+ u32 length,
+ struct pci_dev *dma_h,
+ struct pci_dev *acc_handle)
+{
+ struct __vxge_hw_blockpool *blockpool;
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ dma_addr_t dma_addr;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u32 req_out;
+
+ blockpool = &devh->block_pool;
+
+ if (block_addr == NULL) {
+ blockpool->req_out--;
status = VXGE_HW_FAIL;
goto exit;
}
- hldev = vp->vpath->hldev;
- vp_id = vp->vpath->vp_id;
+ dma_addr = pci_map_single(devh->pdev, block_addr, length,
+ PCI_DMA_BIDIRECTIONAL);
- config = &hldev->config.vp_config[vp_id].ring;
+ if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
+ vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
+ blockpool->req_out--;
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
- ring_length = config->ring_blocks *
- vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
- ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
- VXGE_HW_CHANNEL_TYPE_RING,
- ring_length,
- attr->per_rxd_space,
- attr->userdata);
+ if (entry == NULL)
+ entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
+ else
+ list_del(&entry->item);
- if (ring == NULL) {
+ if (entry != NULL) {
+ entry->length = length;
+ entry->memblock = block_addr;
+ entry->dma_addr = dma_addr;
+ entry->acc_handle = acc_handle;
+ entry->dma_handle = dma_h;
+ list_add(&entry->item, &blockpool->free_block_list);
+ blockpool->pool_size++;
+ status = VXGE_HW_OK;
+ } else
status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto exit;
- }
- vp->vpath->ringh = ring;
- ring->vp_id = vp_id;
- ring->vp_reg = vp->vpath->vp_reg;
- ring->common_reg = hldev->common_reg;
- ring->stats = &vp->vpath->sw_stats->ring_stats;
- ring->config = config;
- ring->callback = attr->callback;
- ring->rxd_init = attr->rxd_init;
- ring->rxd_term = attr->rxd_term;
- ring->buffer_mode = config->buffer_mode;
- ring->rxds_limit = config->rxds_limit;
+ blockpool->req_out--;
- ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
- ring->rxd_priv_size =
- sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
- ring->per_rxd_space = attr->per_rxd_space;
+ req_out = blockpool->req_out;
+exit:
+ return;
+}
- ring->rxd_priv_size =
- ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
- VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
+static inline void
+vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh, unsigned long size)
+{
+ gfp_t flags;
+ void *vaddr;
- /* how many RxDs can fit into one block. Depends on configured
- * buffer_mode. */
- ring->rxds_per_block =
- vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+ if (in_interrupt())
+ flags = GFP_ATOMIC | GFP_DMA;
+ else
+ flags = GFP_KERNEL | GFP_DMA;
- /* calculate actual RxD block private size */
- ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
- ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc;
- ring->mempool = __vxge_hw_mempool_create(hldev,
- VXGE_HW_BLOCK_SIZE,
- VXGE_HW_BLOCK_SIZE,
- ring->rxdblock_priv_size,
- ring->config->ring_blocks,
- ring->config->ring_blocks,
- &ring_mp_callback,
- ring);
+ vaddr = kmalloc((size), flags);
- if (ring->mempool == NULL) {
- __vxge_hw_ring_delete(vp);
- return VXGE_HW_ERR_OUT_OF_MEMORY;
- }
+ vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev);
+}
- status = __vxge_hw_channel_initialize(&ring->channel);
- if (status != VXGE_HW_OK) {
- __vxge_hw_ring_delete(vp);
- goto exit;
+/*
+ * __vxge_hw_blockpool_blocks_add - Request additional blocks
+ */
+static
+void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
+{
+ u32 nreq = 0, i;
+
+ if ((blockpool->pool_size + blockpool->req_out) <
+ VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
+ nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
+ blockpool->req_out += nreq;
}
- /* Note:
- * Specifying rxd_init callback means two things:
- * 1) rxds need to be initialized by driver at channel-open time;
- * 2) rxds need to be posted at channel-open time
- * (that's what the initial_replenish() below does)
- * Currently we don't have a case when the 1) is done without the 2).
- */
- if (ring->rxd_init) {
- status = vxge_hw_ring_replenish(ring);
- if (status != VXGE_HW_OK) {
- __vxge_hw_ring_delete(vp);
+ for (i = 0; i < nreq; i++)
+ vxge_os_dma_malloc_async(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ blockpool->hldev, VXGE_HW_BLOCK_SIZE);
+}
+
+/*
+ * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
+ * Allocates a block of memory of given size, either from block pool
+ * or by calling vxge_os_dma_malloc()
+ */
+static void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
+ struct vxge_hw_mempool_dma *dma_object)
+{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
+ void *memblock = NULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ blockpool = &devh->block_pool;
+
+ if (size != blockpool->block_size) {
+
+ memblock = vxge_os_dma_malloc(devh->pdev, size,
+ &dma_object->handle,
+ &dma_object->acc_handle);
+
+ if (memblock == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto exit;
}
- }
- /* initial replenish will increment the counter in its post() routine,
- * we have to reset it */
- ring->stats->common_stats.usage_cnt = 0;
+ dma_object->addr = pci_map_single(devh->pdev, memblock, size,
+ PCI_DMA_BIDIRECTIONAL);
+
+ if (unlikely(pci_dma_mapping_error(devh->pdev,
+ dma_object->addr))) {
+ vxge_os_dma_free(devh->pdev, memblock,
+ &dma_object->acc_handle);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ } else {
+
+ if (!list_empty(&blockpool->free_block_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_block_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry != NULL) {
+ list_del(&entry->item);
+ dma_object->addr = entry->dma_addr;
+ dma_object->handle = entry->dma_handle;
+ dma_object->acc_handle = entry->acc_handle;
+ memblock = entry->memblock;
+
+ list_add(&entry->item,
+ &blockpool->free_entry_list);
+ blockpool->pool_size--;
+ }
+
+ if (memblock != NULL)
+ __vxge_hw_blockpool_blocks_add(blockpool);
+ }
exit:
- return status;
+ return memblock;
}
/*
- * __vxge_hw_ring_abort - Returns the RxD
- * This function terminates the RxDs of ring
+ * __vxge_hw_blockpool_blocks_remove - Free additional blocks
*/
-static enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
+static void
+__vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
{
- void *rxdh;
- struct __vxge_hw_channel *channel;
-
- channel = &ring->channel;
+ struct list_head *p, *n;
- for (;;) {
- vxge_hw_channel_dtr_try_complete(channel, &rxdh);
+ list_for_each_safe(p, n, &blockpool->free_block_list) {
- if (rxdh == NULL)
+ if (blockpool->pool_size < blockpool->pool_max)
break;
- vxge_hw_channel_dtr_complete(channel);
+ pci_unmap_single(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ PCI_DMA_BIDIRECTIONAL);
- if (ring->rxd_term)
- ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
- channel->userdata);
+ vxge_os_dma_free(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->memblock,
+ &((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
- vxge_hw_channel_dtr_free(channel, rxdh);
- }
+ list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
- return VXGE_HW_OK;
+ list_add(p, &blockpool->free_entry_list);
+
+ blockpool->pool_size--;
+
+ }
}
/*
- * __vxge_hw_ring_reset - Resets the ring
- * This function resets the ring during vpath reset operation
+ * __vxge_hw_blockpool_free - Frees the memory allcoated with
+ * __vxge_hw_blockpool_malloc
*/
-static enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
+static void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
+ void *memblock, u32 size,
+ struct vxge_hw_mempool_dma *dma_object)
{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
enum vxge_hw_status status = VXGE_HW_OK;
- struct __vxge_hw_channel *channel;
- channel = &ring->channel;
+ blockpool = &devh->block_pool;
- __vxge_hw_ring_abort(ring);
+ if (size != blockpool->block_size) {
+ pci_unmap_single(devh->pdev, dma_object->addr, size,
+ PCI_DMA_BIDIRECTIONAL);
+ vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
+ } else {
- status = __vxge_hw_channel_reset(channel);
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
- if (status != VXGE_HW_OK)
- goto exit;
+ if (entry == NULL)
+ entry = vmalloc(sizeof(
+ struct __vxge_hw_blockpool_entry));
+ else
+ list_del(&entry->item);
- if (ring->rxd_init) {
- status = vxge_hw_ring_replenish(ring);
- if (status != VXGE_HW_OK)
- goto exit;
+ if (entry != NULL) {
+ entry->length = size;
+ entry->memblock = memblock;
+ entry->dma_addr = dma_object->addr;
+ entry->acc_handle = dma_object->acc_handle;
+ entry->dma_handle = dma_object->handle;
+ list_add(&entry->item,
+ &blockpool->free_block_list);
+ blockpool->pool_size++;
+ status = VXGE_HW_OK;
+ } else
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+
+ if (status == VXGE_HW_OK)
+ __vxge_hw_blockpool_blocks_remove(blockpool);
}
-exit:
- return status;
}
/*
- * __vxge_hw_ring_delete - Removes the ring
- * This function freeup the memory pool and removes the ring
+ * vxge_hw_mempool_destroy
*/
-static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
+static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
{
- struct __vxge_hw_ring *ring = vp->vpath->ringh;
+ u32 i, j;
+ struct __vxge_hw_device *devh = mempool->devh;
- __vxge_hw_ring_abort(ring);
+ for (i = 0; i < mempool->memblocks_allocated; i++) {
+ struct vxge_hw_mempool_dma *dma_object;
- if (ring->mempool)
- __vxge_hw_mempool_destroy(ring->mempool);
+ vxge_assert(mempool->memblocks_arr[i]);
+ vxge_assert(mempool->memblocks_dma_arr + i);
- vp->vpath->ringh = NULL;
- __vxge_hw_channel_free(&ring->channel);
+ dma_object = mempool->memblocks_dma_arr + i;
- return VXGE_HW_OK;
+ for (j = 0; j < mempool->items_per_memblock; j++) {
+ u32 index = i * mempool->items_per_memblock + j;
+
+ /* to skip last partially filled(if any) memblock */
+ if (index >= mempool->items_current)
+ break;
+ }
+
+ vfree(mempool->memblocks_priv_arr[i]);
+
+ __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
+ mempool->memblock_size, dma_object);
+ }
+
+ vfree(mempool->items_arr);
+ vfree(mempool->memblocks_dma_arr);
+ vfree(mempool->memblocks_priv_arr);
+ vfree(mempool->memblocks_arr);
+ vfree(mempool);
}
/*
@@ -1627,15 +2586,12 @@ __vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate,
* allocate new memblock and its private part at once.
* This helps to minimize memory usage a lot. */
mempool->memblocks_priv_arr[i] =
- vmalloc(mempool->items_priv_size * n_items);
+ vzalloc(mempool->items_priv_size * n_items);
if (mempool->memblocks_priv_arr[i] == NULL) {
status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto exit;
}
- memset(mempool->memblocks_priv_arr[i], 0,
- mempool->items_priv_size * n_items);
-
/* allocate DMA-capable memblock */
mempool->memblocks_arr[i] =
__vxge_hw_blockpool_malloc(mempool->devh,
@@ -1686,16 +2642,15 @@ exit:
* with size enough to hold %items_initial number of items. Memory is
* DMA-able but client must map/unmap before interoperating with the device.
*/
-static struct vxge_hw_mempool*
-__vxge_hw_mempool_create(
- struct __vxge_hw_device *devh,
- u32 memblock_size,
- u32 item_size,
- u32 items_priv_size,
- u32 items_initial,
- u32 items_max,
- struct vxge_hw_mempool_cbs *mp_callback,
- void *userdata)
+static struct vxge_hw_mempool *
+__vxge_hw_mempool_create(struct __vxge_hw_device *devh,
+ u32 memblock_size,
+ u32 item_size,
+ u32 items_priv_size,
+ u32 items_initial,
+ u32 items_max,
+ struct vxge_hw_mempool_cbs *mp_callback,
+ void *userdata)
{
enum vxge_hw_status status = VXGE_HW_OK;
u32 memblocks_to_allocate;
@@ -1707,13 +2662,11 @@ __vxge_hw_mempool_create(
goto exit;
}
- mempool = (struct vxge_hw_mempool *)
- vmalloc(sizeof(struct vxge_hw_mempool));
+ mempool = vzalloc(sizeof(struct vxge_hw_mempool));
if (mempool == NULL) {
status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto exit;
}
- memset(mempool, 0, sizeof(struct vxge_hw_mempool));
mempool->devh = devh;
mempool->memblock_size = memblock_size;
@@ -1733,53 +2686,43 @@ __vxge_hw_mempool_create(
/* allocate array of memblocks */
mempool->memblocks_arr =
- (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+ vzalloc(sizeof(void *) * mempool->memblocks_max);
if (mempool->memblocks_arr == NULL) {
__vxge_hw_mempool_destroy(mempool);
status = VXGE_HW_ERR_OUT_OF_MEMORY;
mempool = NULL;
goto exit;
}
- memset(mempool->memblocks_arr, 0,
- sizeof(void *) * mempool->memblocks_max);
/* allocate array of private parts of items per memblocks */
mempool->memblocks_priv_arr =
- (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+ vzalloc(sizeof(void *) * mempool->memblocks_max);
if (mempool->memblocks_priv_arr == NULL) {
__vxge_hw_mempool_destroy(mempool);
status = VXGE_HW_ERR_OUT_OF_MEMORY;
mempool = NULL;
goto exit;
}
- memset(mempool->memblocks_priv_arr, 0,
- sizeof(void *) * mempool->memblocks_max);
/* allocate array of memblocks DMA objects */
- mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *)
- vmalloc(sizeof(struct vxge_hw_mempool_dma) *
+ mempool->memblocks_dma_arr =
+ vzalloc(sizeof(struct vxge_hw_mempool_dma) *
mempool->memblocks_max);
-
if (mempool->memblocks_dma_arr == NULL) {
__vxge_hw_mempool_destroy(mempool);
status = VXGE_HW_ERR_OUT_OF_MEMORY;
mempool = NULL;
goto exit;
}
- memset(mempool->memblocks_dma_arr, 0,
- sizeof(struct vxge_hw_mempool_dma) *
- mempool->memblocks_max);
/* allocate hash array of items */
- mempool->items_arr =
- (void **) vmalloc(sizeof(void *) * mempool->items_max);
+ mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max);
if (mempool->items_arr == NULL) {
__vxge_hw_mempool_destroy(mempool);
status = VXGE_HW_ERR_OUT_OF_MEMORY;
mempool = NULL;
goto exit;
}
- memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max);
/* calculate initial number of memblocks */
memblocks_to_allocate = (mempool->items_initial +
@@ -1801,122 +2744,188 @@ exit:
}
/*
- * vxge_hw_mempool_destroy
+ * __vxge_hw_ring_abort - Returns the RxD
+ * This function terminates the RxDs of ring
*/
-static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
+static enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
{
- u32 i, j;
- struct __vxge_hw_device *devh = mempool->devh;
-
- for (i = 0; i < mempool->memblocks_allocated; i++) {
- struct vxge_hw_mempool_dma *dma_object;
+ void *rxdh;
+ struct __vxge_hw_channel *channel;
- vxge_assert(mempool->memblocks_arr[i]);
- vxge_assert(mempool->memblocks_dma_arr + i);
+ channel = &ring->channel;
- dma_object = mempool->memblocks_dma_arr + i;
+ for (;;) {
+ vxge_hw_channel_dtr_try_complete(channel, &rxdh);
- for (j = 0; j < mempool->items_per_memblock; j++) {
- u32 index = i * mempool->items_per_memblock + j;
+ if (rxdh == NULL)
+ break;
- /* to skip last partially filled(if any) memblock */
- if (index >= mempool->items_current)
- break;
- }
+ vxge_hw_channel_dtr_complete(channel);
- vfree(mempool->memblocks_priv_arr[i]);
+ if (ring->rxd_term)
+ ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
+ channel->userdata);
- __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
- mempool->memblock_size, dma_object);
+ vxge_hw_channel_dtr_free(channel, rxdh);
}
- vfree(mempool->items_arr);
+ return VXGE_HW_OK;
+}
- vfree(mempool->memblocks_dma_arr);
+/*
+ * __vxge_hw_ring_reset - Resets the ring
+ * This function resets the ring during vpath reset operation
+ */
+static enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_channel *channel;
- vfree(mempool->memblocks_priv_arr);
+ channel = &ring->channel;
- vfree(mempool->memblocks_arr);
+ __vxge_hw_ring_abort(ring);
- vfree(mempool);
+ status = __vxge_hw_channel_reset(channel);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ if (ring->rxd_init) {
+ status = vxge_hw_ring_replenish(ring);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+exit:
+ return status;
}
/*
- * __vxge_hw_device_fifo_config_check - Check fifo configuration.
- * Check the fifo configuration
+ * __vxge_hw_ring_delete - Removes the ring
+ * This function freeup the memory pool and removes the ring
*/
-enum vxge_hw_status
-__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
+static enum vxge_hw_status
+__vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
{
- if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
- (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
- return VXGE_HW_BADCFG_FIFO_BLOCKS;
+ struct __vxge_hw_ring *ring = vp->vpath->ringh;
+
+ __vxge_hw_ring_abort(ring);
+
+ if (ring->mempool)
+ __vxge_hw_mempool_destroy(ring->mempool);
+
+ vp->vpath->ringh = NULL;
+ __vxge_hw_channel_free(&ring->channel);
return VXGE_HW_OK;
}
/*
- * __vxge_hw_device_vpath_config_check - Check vpath configuration.
- * Check the vpath configuration
+ * __vxge_hw_ring_create - Create a Ring
+ * This function creates Ring and initializes it.
*/
static enum vxge_hw_status
-__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
+__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
+ struct vxge_hw_ring_attr *attr)
{
- enum vxge_hw_status status;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_ring *ring;
+ u32 ring_length;
+ struct vxge_hw_ring_config *config;
+ struct __vxge_hw_device *hldev;
+ u32 vp_id;
+ struct vxge_hw_mempool_cbs ring_mp_callback;
- if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
- (vp_config->min_bandwidth >
- VXGE_HW_VPATH_BANDWIDTH_MAX))
- return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
+ if ((vp == NULL) || (attr == NULL)) {
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
- status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
- if (status != VXGE_HW_OK)
- return status;
+ hldev = vp->vpath->hldev;
+ vp_id = vp->vpath->vp_id;
- if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
- ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
- (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
- return VXGE_HW_BADCFG_VPATH_MTU;
+ config = &hldev->config.vp_config[vp_id].ring;
- if ((vp_config->rpa_strip_vlan_tag !=
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
- (vp_config->rpa_strip_vlan_tag !=
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
- (vp_config->rpa_strip_vlan_tag !=
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
- return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
+ ring_length = config->ring_blocks *
+ vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
- return VXGE_HW_OK;
-}
+ ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
+ VXGE_HW_CHANNEL_TYPE_RING,
+ ring_length,
+ attr->per_rxd_space,
+ attr->userdata);
+ if (ring == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
-/*
- * __vxge_hw_device_config_check - Check device configuration.
- * Check the device configuration
- */
-enum vxge_hw_status
-__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
-{
- u32 i;
- enum vxge_hw_status status;
+ vp->vpath->ringh = ring;
+ ring->vp_id = vp_id;
+ ring->vp_reg = vp->vpath->vp_reg;
+ ring->common_reg = hldev->common_reg;
+ ring->stats = &vp->vpath->sw_stats->ring_stats;
+ ring->config = config;
+ ring->callback = attr->callback;
+ ring->rxd_init = attr->rxd_init;
+ ring->rxd_term = attr->rxd_term;
+ ring->buffer_mode = config->buffer_mode;
+ ring->rxds_limit = config->rxds_limit;
- if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
- (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
- (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
- (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
- return VXGE_HW_BADCFG_INTR_MODE;
+ ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
+ ring->rxd_priv_size =
+ sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
+ ring->per_rxd_space = attr->per_rxd_space;
- if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
- (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
- return VXGE_HW_BADCFG_RTS_MAC_EN;
+ ring->rxd_priv_size =
+ ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
+ VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
- for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
- status = __vxge_hw_device_vpath_config_check(
- &new_config->vp_config[i]);
- if (status != VXGE_HW_OK)
- return status;
+ /* how many RxDs can fit into one block. Depends on configured
+ * buffer_mode. */
+ ring->rxds_per_block =
+ vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+
+ /* calculate actual RxD block private size */
+ ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
+ ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc;
+ ring->mempool = __vxge_hw_mempool_create(hldev,
+ VXGE_HW_BLOCK_SIZE,
+ VXGE_HW_BLOCK_SIZE,
+ ring->rxdblock_priv_size,
+ ring->config->ring_blocks,
+ ring->config->ring_blocks,
+ &ring_mp_callback,
+ ring);
+ if (ring->mempool == NULL) {
+ __vxge_hw_ring_delete(vp);
+ return VXGE_HW_ERR_OUT_OF_MEMORY;
}
- return VXGE_HW_OK;
+ status = __vxge_hw_channel_initialize(&ring->channel);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_ring_delete(vp);
+ goto exit;
+ }
+
+ /* Note:
+ * Specifying rxd_init callback means two things:
+ * 1) rxds need to be initialized by driver at channel-open time;
+ * 2) rxds need to be posted at channel-open time
+ * (that's what the initial_replenish() below does)
+ * Currently we don't have a case when the 1) is done without the 2).
+ */
+ if (ring->rxd_init) {
+ status = vxge_hw_ring_replenish(ring);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_ring_delete(vp);
+ goto exit;
+ }
+ }
+
+ /* initial replenish will increment the counter in its post() routine,
+ * we have to reset it */
+ ring->stats->common_stats.usage_cnt = 0;
+exit:
+ return status;
}
/*
@@ -1938,7 +2947,6 @@ vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
device_config->rts_mac_en = VXGE_HW_RTS_MAC_DEFAULT;
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
device_config->vp_config[i].vp_id = i;
device_config->vp_config[i].min_bandwidth =
@@ -2078,61 +3086,6 @@ vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
}
/*
- * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
- * Set the swapper bits appropriately for the lagacy section.
- */
-static enum vxge_hw_status
-__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
-{
- u64 val64;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- val64 = readq(&legacy_reg->toc_swapper_fb);
-
- wmb();
-
- switch (val64) {
-
- case VXGE_HW_SWAPPER_INITIAL_VALUE:
- return status;
-
- case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
- writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
- &legacy_reg->pifm_rd_swap_en);
- writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
- &legacy_reg->pifm_rd_flip_en);
- writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
- &legacy_reg->pifm_wr_swap_en);
- writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
- &legacy_reg->pifm_wr_flip_en);
- break;
-
- case VXGE_HW_SWAPPER_BYTE_SWAPPED:
- writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
- &legacy_reg->pifm_rd_swap_en);
- writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
- &legacy_reg->pifm_wr_swap_en);
- break;
-
- case VXGE_HW_SWAPPER_BIT_FLIPPED:
- writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
- &legacy_reg->pifm_rd_flip_en);
- writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
- &legacy_reg->pifm_wr_flip_en);
- break;
- }
-
- wmb();
-
- val64 = readq(&legacy_reg->toc_swapper_fb);
-
- if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
- status = VXGE_HW_ERR_SWAPPER_CTRL;
-
- return status;
-}
-
-/*
* __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
* Set the swapper bits appropriately for the vpath.
*/
@@ -2156,9 +3109,8 @@ __vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
* Set the swapper bits appropriately for the vpath.
*/
static enum vxge_hw_status
-__vxge_hw_kdfc_swapper_set(
- struct vxge_hw_legacy_reg __iomem *legacy_reg,
- struct vxge_hw_vpath_reg __iomem *vpath_reg)
+__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg)
{
u64 val64;
@@ -2408,6 +3360,69 @@ exit:
}
/*
+ * __vxge_hw_fifo_abort - Returns the TxD
+ * This function terminates the TxDs of fifo
+ */
+static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
+{
+ void *txdlh;
+
+ for (;;) {
+ vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
+
+ if (txdlh == NULL)
+ break;
+
+ vxge_hw_channel_dtr_complete(&fifo->channel);
+
+ if (fifo->txdl_term) {
+ fifo->txdl_term(txdlh,
+ VXGE_HW_TXDL_STATE_POSTED,
+ fifo->channel.userdata);
+ }
+
+ vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_fifo_reset - Resets the fifo
+ * This function resets the fifo during vpath reset operation
+ */
+static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ __vxge_hw_fifo_abort(fifo);
+ status = __vxge_hw_channel_reset(&fifo->channel);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_fifo_delete - Removes the FIFO
+ * This function freeup the memory pool and removes the FIFO
+ */
+static enum vxge_hw_status
+__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
+
+ __vxge_hw_fifo_abort(fifo);
+
+ if (fifo->mempool)
+ __vxge_hw_mempool_destroy(fifo->mempool);
+
+ vp->vpath->fifoh = NULL;
+
+ __vxge_hw_channel_free(&fifo->channel);
+
+ return VXGE_HW_OK;
+}
+
+/*
* __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD
* list callback
* This function is callback passed to __vxge_hw_mempool_create to create memory
@@ -2453,7 +3468,7 @@ __vxge_hw_fifo_mempool_item_alloc(
* __vxge_hw_fifo_create - Create a FIFO
* This function creates FIFO and initializes it.
*/
-enum vxge_hw_status
+static enum vxge_hw_status
__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp,
struct vxge_hw_fifo_attr *attr)
{
@@ -2572,68 +3587,6 @@ exit:
}
/*
- * __vxge_hw_fifo_abort - Returns the TxD
- * This function terminates the TxDs of fifo
- */
-static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
-{
- void *txdlh;
-
- for (;;) {
- vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
-
- if (txdlh == NULL)
- break;
-
- vxge_hw_channel_dtr_complete(&fifo->channel);
-
- if (fifo->txdl_term) {
- fifo->txdl_term(txdlh,
- VXGE_HW_TXDL_STATE_POSTED,
- fifo->channel.userdata);
- }
-
- vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
- }
-
- return VXGE_HW_OK;
-}
-
-/*
- * __vxge_hw_fifo_reset - Resets the fifo
- * This function resets the fifo during vpath reset operation
- */
-static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
-
- __vxge_hw_fifo_abort(fifo);
- status = __vxge_hw_channel_reset(&fifo->channel);
-
- return status;
-}
-
-/*
- * __vxge_hw_fifo_delete - Removes the FIFO
- * This function freeup the memory pool and removes the FIFO
- */
-enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
-{
- struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
-
- __vxge_hw_fifo_abort(fifo);
-
- if (fifo->mempool)
- __vxge_hw_mempool_destroy(fifo->mempool);
-
- vp->vpath->fifoh = NULL;
-
- __vxge_hw_channel_free(&fifo->channel);
-
- return VXGE_HW_OK;
-}
-
-/*
* __vxge_hw_vpath_pci_read - Read the content of given address
* in pci config space.
* Read from the vpath pci config space.
@@ -2675,297 +3628,6 @@ exit:
return status;
}
-/*
- * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
- * Returns the function number of the vpath.
- */
-static u32
-__vxge_hw_vpath_func_id_get(u32 vp_id,
- struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
-{
- u64 val64;
-
- val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
-
- return
- (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
-}
-
-/*
- * __vxge_hw_read_rts_ds - Program RTS steering critieria
- */
-static inline void
-__vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg,
- u64 dta_struct_sel)
-{
- writeq(0, &vpath_reg->rts_access_steer_ctrl);
- wmb();
- writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0);
- writeq(0, &vpath_reg->rts_access_steer_data1);
- wmb();
-}
-
-
-/*
- * __vxge_hw_vpath_card_info_get - Get the serial numbers,
- * part number and product description.
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_card_info_get(
- u32 vp_id,
- struct vxge_hw_vpath_reg __iomem *vpath_reg,
- struct vxge_hw_device_hw_info *hw_info)
-{
- u32 i, j;
- u64 val64;
- u64 data1 = 0ULL;
- u64 data2 = 0ULL;
- enum vxge_hw_status status = VXGE_HW_OK;
- u8 *serial_number = hw_info->serial_number;
- u8 *part_number = hw_info->part_number;
- u8 *product_desc = hw_info->product_desc;
-
- __vxge_hw_read_rts_ds(vpath_reg,
- VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER);
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- return status;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- ((u64 *)serial_number)[0] = be64_to_cpu(data1);
-
- data2 = readq(&vpath_reg->rts_access_steer_data1);
- ((u64 *)serial_number)[1] = be64_to_cpu(data2);
- status = VXGE_HW_OK;
- } else
- *serial_number = 0;
-
- __vxge_hw_read_rts_ds(vpath_reg,
- VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER);
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- return status;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
-
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- ((u64 *)part_number)[0] = be64_to_cpu(data1);
-
- data2 = readq(&vpath_reg->rts_access_steer_data1);
- ((u64 *)part_number)[1] = be64_to_cpu(data2);
-
- status = VXGE_HW_OK;
-
- } else
- *part_number = 0;
-
- j = 0;
-
- for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
- i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
-
- __vxge_hw_read_rts_ds(vpath_reg, i);
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- return status;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
-
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- ((u64 *)product_desc)[j++] = be64_to_cpu(data1);
-
- data2 = readq(&vpath_reg->rts_access_steer_data1);
- ((u64 *)product_desc)[j++] = be64_to_cpu(data2);
-
- status = VXGE_HW_OK;
- } else
- *product_desc = 0;
- }
-
- return status;
-}
-
-/*
- * __vxge_hw_vpath_fw_ver_get - Get the fw version
- * Returns FW Version
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_fw_ver_get(
- u32 vp_id,
- struct vxge_hw_vpath_reg __iomem *vpath_reg,
- struct vxge_hw_device_hw_info *hw_info)
-{
- u64 val64;
- u64 data1 = 0ULL;
- u64 data2 = 0ULL;
- struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
- struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
- struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
- struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- goto exit;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
-
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- data2 = readq(&vpath_reg->rts_access_steer_data1);
-
- fw_date->day =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(
- data1);
- fw_date->month =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(
- data1);
- fw_date->year =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(
- data1);
-
- snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
- fw_date->month, fw_date->day, fw_date->year);
-
- fw_version->major =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1);
- fw_version->minor =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1);
- fw_version->build =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1);
-
- snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
- fw_version->major, fw_version->minor, fw_version->build);
-
- flash_date->day =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2);
- flash_date->month =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2);
- flash_date->year =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2);
-
- snprintf(flash_date->date, VXGE_HW_FW_STRLEN,
- "%2.2d/%2.2d/%4.4d",
- flash_date->month, flash_date->day, flash_date->year);
-
- flash_version->major =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2);
- flash_version->minor =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2);
- flash_version->build =
- (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2);
-
- snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
- flash_version->major, flash_version->minor,
- flash_version->build);
-
- status = VXGE_HW_OK;
-
- } else
- status = VXGE_HW_FAIL;
-exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
- * Returns pci function mode
- */
-static u64
-__vxge_hw_vpath_pci_func_mode_get(
- u32 vp_id,
- struct vxge_hw_vpath_reg __iomem *vpath_reg)
-{
- u64 val64;
- u64 data1 = 0ULL;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- __vxge_hw_read_rts_ds(vpath_reg,
- VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE);
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- goto exit;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- status = VXGE_HW_OK;
- } else {
- data1 = 0;
- status = VXGE_HW_FAIL;
- }
-exit:
- return data1;
-}
-
/**
* vxge_hw_device_flick_link_led - Flick (blink) link LED.
* @hldev: HW device.
@@ -2974,37 +3636,24 @@ exit:
* Flicker the link LED.
*/
enum vxge_hw_status
-vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev,
- u64 on_off)
+vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off)
{
- u64 val64;
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct __vxge_hw_virtualpath *vpath;
+ u64 data0, data1 = 0, steer_ctrl = 0;
+ enum vxge_hw_status status;
if (hldev == NULL) {
status = VXGE_HW_ERR_INVALID_DEVICE;
goto exit;
}
- vp_reg = hldev->vpath_reg[hldev->first_vp_id];
+ vpath = &hldev->virtual_paths[hldev->first_vp_id];
- writeq(0, &vp_reg->rts_access_steer_ctrl);
- wmb();
- writeq(on_off, &vp_reg->rts_access_steer_data0);
- writeq(0, &vp_reg->rts_access_steer_data1);
- wmb();
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vp_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+ data0 = on_off;
+ status = vxge_hw_vpath_fw_api(vpath,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
+ 0, &data0, &data1, &steer_ctrl);
exit:
return status;
}
@@ -3013,63 +3662,38 @@ exit:
* __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables
*/
enum vxge_hw_status
-__vxge_hw_vpath_rts_table_get(
- struct __vxge_hw_vpath_handle *vp,
- u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2)
+__vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp,
+ u32 action, u32 rts_table, u32 offset,
+ u64 *data0, u64 *data1)
{
- u64 val64;
- struct __vxge_hw_virtualpath *vpath;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
-
- enum vxge_hw_status status = VXGE_HW_OK;
+ enum vxge_hw_status status;
+ u64 steer_ctrl = 0;
if (vp == NULL) {
status = VXGE_HW_ERR_INVALID_HANDLE;
goto exit;
}
- vpath = vp->vpath;
- vp_reg = vpath->vp_reg;
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
-
if ((rts_table ==
- VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
(rts_table ==
- VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
(rts_table ==
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
(rts_table ==
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
- val64 = val64 | VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
+ steer_ctrl = VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
}
- status = __vxge_hw_pio_mem_write64(val64,
- &vp_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- vpath->hldev->config.device_poll_millis);
-
+ status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset,
+ data0, data1, &steer_ctrl);
if (status != VXGE_HW_OK)
goto exit;
- val64 = readq(&vp_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
-
- *data1 = readq(&vp_reg->rts_access_steer_data0);
-
- if ((rts_table ==
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
- (rts_table ==
- VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
- *data2 = readq(&vp_reg->rts_access_steer_data1);
- }
- status = VXGE_HW_OK;
- } else
- status = VXGE_HW_FAIL;
+ if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
+ (rts_table !=
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT))
+ *data1 = 0;
exit:
return status;
}
@@ -3078,107 +3702,27 @@ exit:
* __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables
*/
enum vxge_hw_status
-__vxge_hw_vpath_rts_table_set(
- struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table,
- u32 offset, u64 data1, u64 data2)
+__vxge_hw_vpath_rts_table_set(struct __vxge_hw_vpath_handle *vp, u32 action,
+ u32 rts_table, u32 offset, u64 steer_data0,
+ u64 steer_data1)
{
- u64 val64;
- struct __vxge_hw_virtualpath *vpath;
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
+ u64 data0, data1 = 0, steer_ctrl = 0;
+ enum vxge_hw_status status;
if (vp == NULL) {
status = VXGE_HW_ERR_INVALID_HANDLE;
goto exit;
}
- vpath = vp->vpath;
- vp_reg = vpath->vp_reg;
-
- writeq(data1, &vp_reg->rts_access_steer_data0);
- wmb();
+ data0 = steer_data0;
if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
(rts_table ==
- VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
- writeq(data2, &vp_reg->rts_access_steer_data1);
- wmb();
- }
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vp_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- vpath->hldev->config.device_poll_millis);
-
- if (status != VXGE_HW_OK)
- goto exit;
-
- val64 = readq(&vp_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS)
- status = VXGE_HW_OK;
- else
- status = VXGE_HW_FAIL;
-exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
- * from MAC address table.
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_addr_get(
- u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
- u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN])
-{
- u32 i;
- u64 val64;
- u64 data1 = 0ULL;
- u64 data2 = 0ULL;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
- VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
- VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vpath_reg->rts_access_steer_ctrl,
- VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
- VXGE_HW_DEF_DEVICE_POLL_MILLIS);
-
- if (status != VXGE_HW_OK)
- goto exit;
-
- val64 = readq(&vpath_reg->rts_access_steer_ctrl);
-
- if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT))
+ data1 = steer_data1;
- data1 = readq(&vpath_reg->rts_access_steer_data0);
- data2 = readq(&vpath_reg->rts_access_steer_data1);
-
- data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
- data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
- data2);
-
- for (i = ETH_ALEN; i > 0; i--) {
- macaddr[i-1] = (u8)(data1 & 0xFF);
- data1 >>= 8;
-
- macaddr_mask[i-1] = (u8)(data2 & 0xFF);
- data2 >>= 8;
- }
- status = VXGE_HW_OK;
- } else
- status = VXGE_HW_FAIL;
+ status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset,
+ &data0, &data1, &steer_ctrl);
exit:
return status;
}
@@ -3204,6 +3748,8 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
0, &data0, &data1);
+ if (status != VXGE_HW_OK)
+ goto exit;
data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
@@ -3771,10 +4317,10 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
vp_reg = vpath->vp_reg;
config = vpath->vp_config;
- writeq((u64)0, &vp_reg->tim_dest_addr);
- writeq((u64)0, &vp_reg->tim_vpath_map);
- writeq((u64)0, &vp_reg->tim_bitmap);
- writeq((u64)0, &vp_reg->tim_remap);
+ writeq(0, &vp_reg->tim_dest_addr);
+ writeq(0, &vp_reg->tim_vpath_map);
+ writeq(0, &vp_reg->tim_bitmap);
+ writeq(0, &vp_reg->tim_remap);
if (config->ring.enable == VXGE_HW_RING_ENABLE)
writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
@@ -3876,8 +4422,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
- val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
- config->tti.util_sel);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id);
}
if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
@@ -3981,8 +4526,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
- val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
- config->rti.util_sel);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id);
}
if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
@@ -4003,11 +4547,15 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+ val64 = VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(150);
+ val64 |= VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(0);
+ val64 |= VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(3);
+ writeq(val64, &vp_reg->tim_wrkld_clc);
+
return status;
}
-void
-vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id)
+void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id)
{
struct __vxge_hw_virtualpath *vpath;
struct vxge_hw_vpath_reg __iomem *vp_reg;
@@ -4018,17 +4566,15 @@ vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id)
vp_reg = vpath->vp_reg;
config = vpath->vp_config;
- if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+ if (config->fifo.enable == VXGE_HW_FIFO_ENABLE &&
+ config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) {
+ config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE;
val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
-
- if (config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) {
- config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE;
- val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
- writeq(val64,
- &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
- }
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+ writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
}
}
+
/*
* __vxge_hw_vpath_initialize
* This routine is the final phase of init which initializes the
@@ -4052,22 +4598,18 @@ __vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
vp_reg = vpath->vp_reg;
status = __vxge_hw_vpath_swapper_set(vpath->vp_reg);
-
if (status != VXGE_HW_OK)
goto exit;
status = __vxge_hw_vpath_mac_configure(hldev, vp_id);
-
if (status != VXGE_HW_OK)
goto exit;
status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
-
if (status != VXGE_HW_OK)
goto exit;
status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
-
if (status != VXGE_HW_OK)
goto exit;
@@ -4075,7 +4617,6 @@ __vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
/* Get MRRS value from device control */
status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
-
if (status == VXGE_HW_OK) {
val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
val64 &=
@@ -4099,6 +4640,28 @@ exit:
}
/*
+ * __vxge_hw_vp_terminate - Terminate Virtual Path structure
+ * This routine closes all channels it opened and freeup memory
+ */
+static void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = &hldev->virtual_paths[vp_id];
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
+ goto exit;
+
+ VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
+ vpath->hldev->tim_int_mask1, vpath->vp_id);
+ hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
+
+ memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+exit:
+ return;
+}
+
+/*
* __vxge_hw_vp_initialize - Initialize Virtual Path structure
* This routine is the initial phase of init which resets the vpath and
* initializes the software support structures.
@@ -4117,6 +4680,7 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
vpath = &hldev->virtual_paths[vp_id];
+ spin_lock_init(&hldev->virtual_paths[vp_id].lock);
vpath->vp_id = vp_id;
vpath->vp_open = VXGE_HW_VP_OPEN;
vpath->hldev = hldev;
@@ -4127,14 +4691,12 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
__vxge_hw_vpath_reset(hldev, vp_id);
status = __vxge_hw_vpath_reset_check(vpath);
-
if (status != VXGE_HW_OK) {
memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
goto exit;
}
status = __vxge_hw_vpath_mgmt_read(hldev, vpath);
-
if (status != VXGE_HW_OK) {
memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
goto exit;
@@ -4148,7 +4710,6 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
hldev->tim_int_mask1, vp_id);
status = __vxge_hw_vpath_initialize(hldev, vp_id);
-
if (status != VXGE_HW_OK)
__vxge_hw_vp_terminate(hldev, vp_id);
exit:
@@ -4156,29 +4717,6 @@ exit:
}
/*
- * __vxge_hw_vp_terminate - Terminate Virtual Path structure
- * This routine closes all channels it opened and freeup memory
- */
-static void
-__vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
-{
- struct __vxge_hw_virtualpath *vpath;
-
- vpath = &hldev->virtual_paths[vp_id];
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
- goto exit;
-
- VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
- vpath->hldev->tim_int_mask1, vpath->vp_id);
- hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
-
- memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
-exit:
- return;
-}
-
-/*
* vxge_hw_vpath_mtu_set - Set MTU.
* Set new MTU value. Example, to use jumbo frames:
* vxge_hw_vpath_mtu_set(my_device, 9600);
@@ -4215,6 +4753,64 @@ exit:
}
/*
+ * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
+ * Enable the DMA vpath statistics. The function is to be called to re-enable
+ * the adapter to update stats into the host memory
+ */
+static enum vxge_hw_status
+vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = vp->vpath;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ memcpy(vpath->hw_stats_sav, vpath->hw_stats,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
+ * This function allocates a block from block pool or from the system
+ */
+static struct __vxge_hw_blockpool_entry *
+__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
+{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
+
+ blockpool = &devh->block_pool;
+
+ if (size == blockpool->block_size) {
+
+ if (!list_empty(&blockpool->free_block_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_block_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry != NULL) {
+ list_del(&entry->item);
+ blockpool->pool_size--;
+ }
+ }
+
+ if (entry != NULL)
+ __vxge_hw_blockpool_blocks_add(blockpool);
+
+ return entry;
+}
+
+/*
* vxge_hw_vpath_open - Open a virtual path on a given adapter
* This function is used to open access to virtual path of an
* adapter for offload, GRO operations. This function returns
@@ -4238,19 +4834,15 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev,
status = __vxge_hw_vp_initialize(hldev, attr->vp_id,
&hldev->config.vp_config[attr->vp_id]);
-
if (status != VXGE_HW_OK)
goto vpath_open_exit1;
- vp = (struct __vxge_hw_vpath_handle *)
- vmalloc(sizeof(struct __vxge_hw_vpath_handle));
+ vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle));
if (vp == NULL) {
status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto vpath_open_exit2;
}
- memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle));
-
vp->vpath = vpath;
if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
@@ -4273,7 +4865,6 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev,
vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev,
VXGE_HW_BLOCK_SIZE);
-
if (vpath->stats_block == NULL) {
status = VXGE_HW_ERR_OUT_OF_MEMORY;
goto vpath_open_exit8;
@@ -4332,19 +4923,20 @@ vpath_open_exit1:
* This function is used to close access to virtual path opened
* earlier.
*/
-void
-vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
+void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
{
- struct __vxge_hw_virtualpath *vpath = NULL;
+ struct __vxge_hw_virtualpath *vpath = vp->vpath;
+ struct __vxge_hw_ring *ring = vpath->ringh;
+ struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev);
u64 new_count, val64, val164;
- struct __vxge_hw_ring *ring;
- vpath = vp->vpath;
- ring = vpath->ringh;
+ if (vdev->titan1) {
+ new_count = readq(&vpath->vp_reg->rxdmem_size);
+ new_count &= 0x1fff;
+ } else
+ new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8;
- new_count = readq(&vpath->vp_reg->rxdmem_size);
- new_count &= 0x1fff;
- val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count));
+ val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count);
writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164),
&vpath->vp_reg->prc_rxd_doorbell);
@@ -4367,6 +4959,29 @@ vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
}
/*
+ * __vxge_hw_blockpool_block_free - Frees a block from block pool
+ * @devh: Hal device
+ * @entry: Entry of block to be freed
+ *
+ * This function frees a block from block pool
+ */
+static void
+__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
+ struct __vxge_hw_blockpool_entry *entry)
+{
+ struct __vxge_hw_blockpool *blockpool;
+
+ blockpool = &devh->block_pool;
+
+ if (entry->length == blockpool->block_size) {
+ list_add(&entry->item, &blockpool->free_block_list);
+ blockpool->pool_size++;
+ }
+
+ __vxge_hw_blockpool_blocks_remove(blockpool);
+}
+
+/*
* vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
* This function is used to close access to virtual path opened
* earlier.
@@ -4414,7 +5029,9 @@ enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
__vxge_hw_vp_terminate(devh, vp_id);
+ spin_lock(&vpath->lock);
vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
+ spin_unlock(&vpath->lock);
vpath_close_exit:
return status;
@@ -4515,730 +5132,3 @@ vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp)
__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
&hldev->common_reg->cmn_rsthdlr_cfg1);
}
-
-/*
- * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
- * Enable the DMA vpath statistics. The function is to be called to re-enable
- * the adapter to update stats into the host memory
- */
-static enum vxge_hw_status
-vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct __vxge_hw_virtualpath *vpath;
-
- vpath = vp->vpath;
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
- status = VXGE_HW_ERR_VPATH_NOT_OPEN;
- goto exit;
- }
-
- memcpy(vpath->hw_stats_sav, vpath->hw_stats,
- sizeof(struct vxge_hw_vpath_stats_hw_info));
-
- status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
-exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_stats_access - Get the statistics from the given location
- * and offset and perform an operation
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
- u32 operation, u32 offset, u64 *stat)
-{
- u64 val64;
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
- status = VXGE_HW_ERR_VPATH_NOT_OPEN;
- goto vpath_stats_access_exit;
- }
-
- vp_reg = vpath->vp_reg;
-
- val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
- VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
- VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
-
- status = __vxge_hw_pio_mem_write64(val64,
- &vp_reg->xmac_stats_access_cmd,
- VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
- vpath->hldev->config.device_poll_millis);
-
- if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
- *stat = readq(&vp_reg->xmac_stats_access_data);
- else
- *stat = 0;
-
-vpath_stats_access_exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_xmac_tx_stats_get(
- struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
-{
- u64 *val64;
- int i;
- u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- val64 = (u64 *) vpath_tx_stats;
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
- status = VXGE_HW_ERR_VPATH_NOT_OPEN;
- goto exit;
- }
-
- for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
- status = __vxge_hw_vpath_stats_access(vpath,
- VXGE_HW_STATS_OP_READ,
- offset, val64);
- if (status != VXGE_HW_OK)
- goto exit;
- offset++;
- val64++;
- }
-exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
-{
- u64 *val64;
- enum vxge_hw_status status = VXGE_HW_OK;
- int i;
- u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
- val64 = (u64 *) vpath_rx_stats;
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
- status = VXGE_HW_ERR_VPATH_NOT_OPEN;
- goto exit;
- }
- for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
- status = __vxge_hw_vpath_stats_access(vpath,
- VXGE_HW_STATS_OP_READ,
- offset >> 3, val64);
- if (status != VXGE_HW_OK)
- goto exit;
-
- offset += 8;
- val64++;
- }
-exit:
- return status;
-}
-
-/*
- * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath,
- struct vxge_hw_vpath_stats_hw_info *hw_stats)
-{
- u64 val64;
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
-
- if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
- status = VXGE_HW_ERR_VPATH_NOT_OPEN;
- goto exit;
- }
- vp_reg = vpath->vp_reg;
-
- val64 = readq(&vp_reg->vpath_debug_stats0);
- hw_stats->ini_num_mwr_sent =
- (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats1);
- hw_stats->ini_num_mrd_sent =
- (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats2);
- hw_stats->ini_num_cpl_rcvd =
- (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats3);
- hw_stats->ini_num_mwr_byte_sent =
- VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats4);
- hw_stats->ini_num_cpl_byte_rcvd =
- VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats5);
- hw_stats->wrcrdtarb_xoff =
- (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
-
- val64 = readq(&vp_reg->vpath_debug_stats6);
- hw_stats->rdcrdtarb_xoff =
- (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count01);
- hw_stats->vpath_genstats_count0 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
- val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count01);
- hw_stats->vpath_genstats_count1 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
- val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count23);
- hw_stats->vpath_genstats_count2 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
- val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count01);
- hw_stats->vpath_genstats_count3 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
- val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count4);
- hw_stats->vpath_genstats_count4 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
- val64);
-
- val64 = readq(&vp_reg->vpath_genstats_count5);
- hw_stats->vpath_genstats_count5 =
- (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
- val64);
-
- status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
- if (status != VXGE_HW_OK)
- goto exit;
-
- status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
- if (status != VXGE_HW_OK)
- goto exit;
-
- VXGE_HW_VPATH_STATS_PIO_READ(
- VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
-
- hw_stats->prog_event_vnum0 =
- (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
-
- hw_stats->prog_event_vnum1 =
- (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
-
- VXGE_HW_VPATH_STATS_PIO_READ(
- VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
-
- hw_stats->prog_event_vnum2 =
- (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
-
- hw_stats->prog_event_vnum3 =
- (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
-
- val64 = readq(&vp_reg->rx_multi_cast_stats);
- hw_stats->rx_multi_cast_frame_discard =
- (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
-
- val64 = readq(&vp_reg->rx_frm_transferred);
- hw_stats->rx_frm_transferred =
- (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
-
- val64 = readq(&vp_reg->rxd_returned);
- hw_stats->rxd_returned =
- (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
-
- val64 = readq(&vp_reg->dbg_stats_rx_mpa);
- hw_stats->rx_mpa_len_fail_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
- hw_stats->rx_mpa_mrk_fail_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
- hw_stats->rx_mpa_crc_fail_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
-
- val64 = readq(&vp_reg->dbg_stats_rx_fau);
- hw_stats->rx_permitted_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
- hw_stats->rx_vp_reset_discarded_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
- hw_stats->rx_wol_frms =
- (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
-
- val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
- hw_stats->tx_vp_reset_discarded_frms =
- (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
- val64);
-exit:
- return status;
-}
-
-
-static void vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh,
- unsigned long size)
-{
- gfp_t flags;
- void *vaddr;
-
- if (in_interrupt())
- flags = GFP_ATOMIC | GFP_DMA;
- else
- flags = GFP_KERNEL | GFP_DMA;
-
- vaddr = kmalloc((size), flags);
-
- vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev);
-}
-
-static void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr,
- struct pci_dev **p_dma_acch)
-{
- unsigned long misaligned = *(unsigned long *)p_dma_acch;
- u8 *tmp = (u8 *)vaddr;
- tmp -= misaligned;
- kfree((void *)tmp);
-}
-
-/*
- * __vxge_hw_blockpool_create - Create block pool
- */
-
-enum vxge_hw_status
-__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
- struct __vxge_hw_blockpool *blockpool,
- u32 pool_size,
- u32 pool_max)
-{
- u32 i;
- struct __vxge_hw_blockpool_entry *entry = NULL;
- void *memblock;
- dma_addr_t dma_addr;
- struct pci_dev *dma_handle;
- struct pci_dev *acc_handle;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- if (blockpool == NULL) {
- status = VXGE_HW_FAIL;
- goto blockpool_create_exit;
- }
-
- blockpool->hldev = hldev;
- blockpool->block_size = VXGE_HW_BLOCK_SIZE;
- blockpool->pool_size = 0;
- blockpool->pool_max = pool_max;
- blockpool->req_out = 0;
-
- INIT_LIST_HEAD(&blockpool->free_block_list);
- INIT_LIST_HEAD(&blockpool->free_entry_list);
-
- for (i = 0; i < pool_size + pool_max; i++) {
- entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
- GFP_KERNEL);
- if (entry == NULL) {
- __vxge_hw_blockpool_destroy(blockpool);
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto blockpool_create_exit;
- }
- list_add(&entry->item, &blockpool->free_entry_list);
- }
-
- for (i = 0; i < pool_size; i++) {
-
- memblock = vxge_os_dma_malloc(
- hldev->pdev,
- VXGE_HW_BLOCK_SIZE,
- &dma_handle,
- &acc_handle);
-
- if (memblock == NULL) {
- __vxge_hw_blockpool_destroy(blockpool);
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto blockpool_create_exit;
- }
-
- dma_addr = pci_map_single(hldev->pdev, memblock,
- VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
-
- if (unlikely(pci_dma_mapping_error(hldev->pdev,
- dma_addr))) {
-
- vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
- __vxge_hw_blockpool_destroy(blockpool);
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto blockpool_create_exit;
- }
-
- if (!list_empty(&blockpool->free_entry_list))
- entry = (struct __vxge_hw_blockpool_entry *)
- list_first_entry(&blockpool->free_entry_list,
- struct __vxge_hw_blockpool_entry,
- item);
-
- if (entry == NULL)
- entry =
- kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
- GFP_KERNEL);
- if (entry != NULL) {
- list_del(&entry->item);
- entry->length = VXGE_HW_BLOCK_SIZE;
- entry->memblock = memblock;
- entry->dma_addr = dma_addr;
- entry->acc_handle = acc_handle;
- entry->dma_handle = dma_handle;
- list_add(&entry->item,
- &blockpool->free_block_list);
- blockpool->pool_size++;
- } else {
- __vxge_hw_blockpool_destroy(blockpool);
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto blockpool_create_exit;
- }
- }
-
-blockpool_create_exit:
- return status;
-}
-
-/*
- * __vxge_hw_blockpool_destroy - Deallocates the block pool
- */
-
-void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
-{
-
- struct __vxge_hw_device *hldev;
- struct list_head *p, *n;
- u16 ret;
-
- if (blockpool == NULL) {
- ret = 1;
- goto exit;
- }
-
- hldev = blockpool->hldev;
-
- list_for_each_safe(p, n, &blockpool->free_block_list) {
-
- pci_unmap_single(hldev->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
- ((struct __vxge_hw_blockpool_entry *)p)->length,
- PCI_DMA_BIDIRECTIONAL);
-
- vxge_os_dma_free(hldev->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->memblock,
- &((struct __vxge_hw_blockpool_entry *) p)->acc_handle);
-
- list_del(
- &((struct __vxge_hw_blockpool_entry *)p)->item);
- kfree(p);
- blockpool->pool_size--;
- }
-
- list_for_each_safe(p, n, &blockpool->free_entry_list) {
- list_del(
- &((struct __vxge_hw_blockpool_entry *)p)->item);
- kfree((void *)p);
- }
- ret = 0;
-exit:
- return;
-}
-
-/*
- * __vxge_hw_blockpool_blocks_add - Request additional blocks
- */
-static
-void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
-{
- u32 nreq = 0, i;
-
- if ((blockpool->pool_size + blockpool->req_out) <
- VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
- nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
- blockpool->req_out += nreq;
- }
-
- for (i = 0; i < nreq; i++)
- vxge_os_dma_malloc_async(
- ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
- blockpool->hldev, VXGE_HW_BLOCK_SIZE);
-}
-
-/*
- * __vxge_hw_blockpool_blocks_remove - Free additional blocks
- */
-static
-void __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
-{
- struct list_head *p, *n;
-
- list_for_each_safe(p, n, &blockpool->free_block_list) {
-
- if (blockpool->pool_size < blockpool->pool_max)
- break;
-
- pci_unmap_single(
- ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
- ((struct __vxge_hw_blockpool_entry *)p)->length,
- PCI_DMA_BIDIRECTIONAL);
-
- vxge_os_dma_free(
- ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->memblock,
- &((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
-
- list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
-
- list_add(p, &blockpool->free_entry_list);
-
- blockpool->pool_size--;
-
- }
-}
-
-/*
- * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
- * Adds a block to block pool
- */
-static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh,
- void *block_addr,
- u32 length,
- struct pci_dev *dma_h,
- struct pci_dev *acc_handle)
-{
- struct __vxge_hw_blockpool *blockpool;
- struct __vxge_hw_blockpool_entry *entry = NULL;
- dma_addr_t dma_addr;
- enum vxge_hw_status status = VXGE_HW_OK;
- u32 req_out;
-
- blockpool = &devh->block_pool;
-
- if (block_addr == NULL) {
- blockpool->req_out--;
- status = VXGE_HW_FAIL;
- goto exit;
- }
-
- dma_addr = pci_map_single(devh->pdev, block_addr, length,
- PCI_DMA_BIDIRECTIONAL);
-
- if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
-
- vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
- blockpool->req_out--;
- status = VXGE_HW_FAIL;
- goto exit;
- }
-
-
- if (!list_empty(&blockpool->free_entry_list))
- entry = (struct __vxge_hw_blockpool_entry *)
- list_first_entry(&blockpool->free_entry_list,
- struct __vxge_hw_blockpool_entry,
- item);
-
- if (entry == NULL)
- entry = (struct __vxge_hw_blockpool_entry *)
- vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
- else
- list_del(&entry->item);
-
- if (entry != NULL) {
- entry->length = length;
- entry->memblock = block_addr;
- entry->dma_addr = dma_addr;
- entry->acc_handle = acc_handle;
- entry->dma_handle = dma_h;
- list_add(&entry->item, &blockpool->free_block_list);
- blockpool->pool_size++;
- status = VXGE_HW_OK;
- } else
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
-
- blockpool->req_out--;
-
- req_out = blockpool->req_out;
-exit:
- return;
-}
-
-/*
- * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
- * Allocates a block of memory of given size, either from block pool
- * or by calling vxge_os_dma_malloc()
- */
-void *
-__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
- struct vxge_hw_mempool_dma *dma_object)
-{
- struct __vxge_hw_blockpool_entry *entry = NULL;
- struct __vxge_hw_blockpool *blockpool;
- void *memblock = NULL;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- blockpool = &devh->block_pool;
-
- if (size != blockpool->block_size) {
-
- memblock = vxge_os_dma_malloc(devh->pdev, size,
- &dma_object->handle,
- &dma_object->acc_handle);
-
- if (memblock == NULL) {
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto exit;
- }
-
- dma_object->addr = pci_map_single(devh->pdev, memblock, size,
- PCI_DMA_BIDIRECTIONAL);
-
- if (unlikely(pci_dma_mapping_error(devh->pdev,
- dma_object->addr))) {
- vxge_os_dma_free(devh->pdev, memblock,
- &dma_object->acc_handle);
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
- goto exit;
- }
-
- } else {
-
- if (!list_empty(&blockpool->free_block_list))
- entry = (struct __vxge_hw_blockpool_entry *)
- list_first_entry(&blockpool->free_block_list,
- struct __vxge_hw_blockpool_entry,
- item);
-
- if (entry != NULL) {
- list_del(&entry->item);
- dma_object->addr = entry->dma_addr;
- dma_object->handle = entry->dma_handle;
- dma_object->acc_handle = entry->acc_handle;
- memblock = entry->memblock;
-
- list_add(&entry->item,
- &blockpool->free_entry_list);
- blockpool->pool_size--;
- }
-
- if (memblock != NULL)
- __vxge_hw_blockpool_blocks_add(blockpool);
- }
-exit:
- return memblock;
-}
-
-/*
- * __vxge_hw_blockpool_free - Frees the memory allcoated with
- __vxge_hw_blockpool_malloc
- */
-void
-__vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
- void *memblock, u32 size,
- struct vxge_hw_mempool_dma *dma_object)
-{
- struct __vxge_hw_blockpool_entry *entry = NULL;
- struct __vxge_hw_blockpool *blockpool;
- enum vxge_hw_status status = VXGE_HW_OK;
-
- blockpool = &devh->block_pool;
-
- if (size != blockpool->block_size) {
- pci_unmap_single(devh->pdev, dma_object->addr, size,
- PCI_DMA_BIDIRECTIONAL);
- vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
- } else {
-
- if (!list_empty(&blockpool->free_entry_list))
- entry = (struct __vxge_hw_blockpool_entry *)
- list_first_entry(&blockpool->free_entry_list,
- struct __vxge_hw_blockpool_entry,
- item);
-
- if (entry == NULL)
- entry = (struct __vxge_hw_blockpool_entry *)
- vmalloc(sizeof(
- struct __vxge_hw_blockpool_entry));
- else
- list_del(&entry->item);
-
- if (entry != NULL) {
- entry->length = size;
- entry->memblock = memblock;
- entry->dma_addr = dma_object->addr;
- entry->acc_handle = dma_object->acc_handle;
- entry->dma_handle = dma_object->handle;
- list_add(&entry->item,
- &blockpool->free_block_list);
- blockpool->pool_size++;
- status = VXGE_HW_OK;
- } else
- status = VXGE_HW_ERR_OUT_OF_MEMORY;
-
- if (status == VXGE_HW_OK)
- __vxge_hw_blockpool_blocks_remove(blockpool);
- }
-}
-
-/*
- * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
- * This function allocates a block from block pool or from the system
- */
-struct __vxge_hw_blockpool_entry *
-__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
-{
- struct __vxge_hw_blockpool_entry *entry = NULL;
- struct __vxge_hw_blockpool *blockpool;
-
- blockpool = &devh->block_pool;
-
- if (size == blockpool->block_size) {
-
- if (!list_empty(&blockpool->free_block_list))
- entry = (struct __vxge_hw_blockpool_entry *)
- list_first_entry(&blockpool->free_block_list,
- struct __vxge_hw_blockpool_entry,
- item);
-
- if (entry != NULL) {
- list_del(&entry->item);
- blockpool->pool_size--;
- }
- }
-
- if (entry != NULL)
- __vxge_hw_blockpool_blocks_add(blockpool);
-
- return entry;
-}
-
-/*
- * __vxge_hw_blockpool_block_free - Frees a block from block pool
- * @devh: Hal device
- * @entry: Entry of block to be freed
- *
- * This function frees a block from block pool
- */
-void
-__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
- struct __vxge_hw_blockpool_entry *entry)
-{
- struct __vxge_hw_blockpool *blockpool;
-
- blockpool = &devh->block_pool;
-
- if (entry->length == blockpool->block_size) {
- list_add(&entry->item, &blockpool->free_block_list);
- blockpool->pool_size++;
- }
-
- __vxge_hw_blockpool_blocks_remove(blockpool);
-}
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 5c00861b6c2c..e249e288d160 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -20,13 +20,6 @@
#define VXGE_CACHE_LINE_SIZE 128
#endif
-#define vxge_os_vaprintf(level, mask, fmt, ...) { \
- char buff[255]; \
- snprintf(buff, 255, fmt, __VA_ARGS__); \
- printk(buff); \
- printk("\n"); \
-}
-
#ifndef VXGE_ALIGN
#define VXGE_ALIGN(adrs, size) \
(((size) - (((u64)adrs) & ((size)-1))) & ((size)-1))
@@ -36,8 +29,16 @@
#define VXGE_HW_MAX_MTU 9600
#define VXGE_HW_DEFAULT_MTU 1500
-#ifdef VXGE_DEBUG_ASSERT
+#define VXGE_HW_MAX_ROM_IMAGES 8
+struct eprom_image {
+ u8 is_valid:1;
+ u8 index;
+ u8 type;
+ u16 version;
+};
+
+#ifdef VXGE_DEBUG_ASSERT
/**
* vxge_assert
* @test: C-condition to check
@@ -48,16 +49,13 @@
* compilation
* time.
*/
-#define vxge_assert(test) { \
- if (!(test)) \
- vxge_os_bug("bad cond: "#test" at %s:%d\n", \
- __FILE__, __LINE__); }
+#define vxge_assert(test) BUG_ON(!(test))
#else
#define vxge_assert(test)
#endif /* end of VXGE_DEBUG_ASSERT */
/**
- * enum enum vxge_debug_level
+ * enum vxge_debug_level
* @VXGE_NONE: debug disabled
* @VXGE_ERR: all errors going to be logged out
* @VXGE_TRACE: all errors plus all kind of verbose tracing print outs
@@ -159,6 +157,47 @@ enum vxge_hw_device_link_state {
};
/**
+ * enum enum vxge_hw_fw_upgrade_code - FW upgrade return codes.
+ * @VXGE_HW_FW_UPGRADE_OK: All OK send next 16 bytes
+ * @VXGE_HW_FW_UPGRADE_DONE: upload completed
+ * @VXGE_HW_FW_UPGRADE_ERR: upload error
+ * @VXGE_FW_UPGRADE_BYTES2SKIP: skip bytes in the stream
+ *
+ */
+enum vxge_hw_fw_upgrade_code {
+ VXGE_HW_FW_UPGRADE_OK = 0,
+ VXGE_HW_FW_UPGRADE_DONE = 1,
+ VXGE_HW_FW_UPGRADE_ERR = 2,
+ VXGE_FW_UPGRADE_BYTES2SKIP = 3
+};
+
+/**
+ * enum enum vxge_hw_fw_upgrade_err_code - FW upgrade error codes.
+ * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: corrupt data
+ * @VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: buffer overflow
+ * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: invalid .ncf file
+ * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: invalid .ncf file
+ * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: invalid .ncf file
+ * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: invalid .ncf file
+ * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: corrupt data
+ * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: invalid .ncf file
+ * @VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: generic error unknown type
+ * @VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: failed to flash image check failed
+ */
+enum vxge_hw_fw_upgrade_err_code {
+ VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1 = 1,
+ VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW = 2,
+ VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3 = 3,
+ VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4 = 4,
+ VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5 = 5,
+ VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6 = 6,
+ VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7 = 7,
+ VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8 = 8,
+ VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN = 9,
+ VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH = 10
+};
+
+/**
* struct vxge_hw_device_date - Date Format
* @day: Day
* @month: Month
@@ -275,9 +314,9 @@ struct vxge_hw_ring_config {
#define VXGE_HW_RING_DEFAULT 1
u32 ring_blocks;
-#define VXGE_HW_MIN_RING_BLOCKS 1
-#define VXGE_HW_MAX_RING_BLOCKS 128
-#define VXGE_HW_DEF_RING_BLOCKS 2
+#define VXGE_HW_MIN_RING_BLOCKS 1
+#define VXGE_HW_MAX_RING_BLOCKS 128
+#define VXGE_HW_DEF_RING_BLOCKS 2
u32 buffer_mode;
#define VXGE_HW_RING_RXD_BUFFER_MODE_1 1
@@ -465,7 +504,6 @@ struct vxge_hw_device_config {
* See also: vxge_hw_driver_initialize().
*/
struct vxge_hw_uld_cbs {
-
void (*link_up)(struct __vxge_hw_device *devh);
void (*link_down)(struct __vxge_hw_device *devh);
void (*crit_err)(struct __vxge_hw_device *devh,
@@ -652,6 +690,7 @@ struct __vxge_hw_virtualpath {
struct vxge_hw_vpath_stats_hw_info *hw_stats;
struct vxge_hw_vpath_stats_hw_info *hw_stats_sav;
struct vxge_hw_vpath_stats_sw_info *sw_stats;
+ spinlock_t lock;
};
/*
@@ -661,7 +700,7 @@ struct __vxge_hw_virtualpath {
*
* This structure is used to store the callback information.
*/
-struct __vxge_hw_vpath_handle{
+struct __vxge_hw_vpath_handle {
struct list_head item;
struct __vxge_hw_virtualpath *vpath;
};
@@ -674,9 +713,6 @@ struct __vxge_hw_vpath_handle{
/**
* struct __vxge_hw_device - Hal device object
* @magic: Magic Number
- * @device_id: PCI Device Id of the adapter
- * @major_revision: PCI Device major revision
- * @minor_revision: PCI Device minor revision
* @bar0: BAR0 virtual address.
* @pdev: Physical device handle
* @config: Confguration passed by the LL driver at initialization
@@ -688,9 +724,6 @@ struct __vxge_hw_device {
u32 magic;
#define VXGE_HW_DEVICE_MAGIC 0x12345678
#define VXGE_HW_DEVICE_DEAD 0xDEADDEAD
- u16 device_id;
- u8 major_revision;
- u8 minor_revision;
void __iomem *bar0;
struct pci_dev *pdev;
struct net_device *ndev;
@@ -731,6 +764,7 @@ struct __vxge_hw_device {
u32 debug_level;
u32 level_err;
u32 level_trace;
+ u16 eprom_versions[VXGE_HW_MAX_ROM_IMAGES];
};
#define VXGE_HW_INFO_LEN 64
@@ -781,8 +815,8 @@ struct vxge_hw_device_hw_info {
u8 serial_number[VXGE_HW_INFO_LEN];
u8 part_number[VXGE_HW_INFO_LEN];
u8 product_desc[VXGE_HW_INFO_LEN];
- u8 (mac_addrs)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
- u8 (mac_addr_masks)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+ u8 mac_addrs[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+ u8 mac_addr_masks[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
};
/**
@@ -829,20 +863,10 @@ struct vxge_hw_device_attr {
loc, \
offset, \
&val64); \
- \
if (status != VXGE_HW_OK) \
return status; \
}
-#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \
- status = __vxge_hw_vpath_stats_access(vpath, \
- VXGE_HW_STATS_OP_READ, \
- offset, \
- &val64); \
- if (status != VXGE_HW_OK) \
- return status; \
-}
-
/*
* struct __vxge_hw_ring - Ring channel.
* @channel: Channel "base" of this ring, the common part of all HW
@@ -1114,7 +1138,7 @@ struct __vxge_hw_non_offload_db_wrapper {
* lookup to determine the transmit port.
* 01: Send on physical Port1.
* 10: Send on physical Port0.
- * 11: Send on both ports.
+ * 11: Send on both ports.
* Bits 18 to 21 - Reserved
* Bits 22 to 23 - Gather_Code. This field is set by the host and
* is used to describe how individual buffers comprise a frame.
@@ -1413,12 +1437,12 @@ enum vxge_hw_rth_algoritms {
* See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
*/
struct vxge_hw_rth_hash_types {
- u8 hash_type_tcpipv4_en;
- u8 hash_type_ipv4_en;
- u8 hash_type_tcpipv6_en;
- u8 hash_type_ipv6_en;
- u8 hash_type_tcpipv6ex_en;
- u8 hash_type_ipv6ex_en;
+ u8 hash_type_tcpipv4_en:1,
+ hash_type_ipv4_en:1,
+ hash_type_tcpipv6_en:1,
+ hash_type_ipv6_en:1,
+ hash_type_tcpipv6ex_en:1,
+ hash_type_ipv6ex_en:1;
};
void vxge_hw_device_debug_set(
@@ -1893,6 +1917,15 @@ out:
return vaddr;
}
+static inline void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr,
+ struct pci_dev **p_dma_acch)
+{
+ unsigned long misaligned = *(unsigned long *)p_dma_acch;
+ u8 *tmp = (u8 *)vaddr;
+ tmp -= misaligned;
+ kfree((void *)tmp);
+}
+
/*
* __vxge_hw_mempool_item_priv - will return pointer on per item private space
*/
@@ -1962,7 +1995,6 @@ enum vxge_hw_status vxge_hw_vpath_mtu_set(
void
vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp);
-
#ifndef readq
static inline u64 readq(void __iomem *addr)
{
@@ -2000,7 +2032,7 @@ enum vxge_hw_status
vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask);
/**
- * vxge_debug
+ * vxge_debug_ll
* @level: level of debug verbosity.
* @mask: mask for the debug
* @buf: Circular buffer for tracing
@@ -2012,26 +2044,13 @@ vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask);
* may be compiled out if DEBUG macro was never defined.
* See also: enum vxge_debug_level{}.
*/
-
-#define vxge_trace_aux(level, mask, fmt, ...) \
-{\
- vxge_os_vaprintf(level, mask, fmt, __VA_ARGS__);\
-}
-
-#define vxge_debug(module, level, mask, fmt, ...) { \
-if ((level >= VXGE_TRACE && ((module & VXGE_DEBUG_TRACE_MASK) == module)) || \
- (level >= VXGE_ERR && ((module & VXGE_DEBUG_ERR_MASK) == module))) {\
- if ((mask & VXGE_DEBUG_MASK) == mask)\
- vxge_trace_aux(level, mask, fmt, __VA_ARGS__); \
-} \
-}
-
#if (VXGE_COMPONENT_LL & VXGE_DEBUG_MODULE_MASK)
-#define vxge_debug_ll(level, mask, fmt, ...) \
-{\
- vxge_debug(VXGE_COMPONENT_LL, level, mask, fmt, __VA_ARGS__);\
-}
-
+#define vxge_debug_ll(level, mask, fmt, ...) do { \
+ if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \
+ (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\
+ if ((mask & VXGE_DEBUG_MASK) == mask) \
+ printk(fmt "\n", __VA_ARGS__); \
+} while (0)
#else
#define vxge_debug_ll(level, mask, fmt, ...)
#endif
@@ -2051,4 +2070,26 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
enum vxge_hw_status
__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id);
+
+#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5
+#define VXGE_HW_MAX_POLLING_COUNT 100
+
+void
+vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major,
+ u32 *minor, u32 *build);
+
+enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *filebuf,
+ int size);
+
+enum vxge_hw_status
+vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev,
+ struct eprom_image *eprom_image_data);
+
+int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id);
#endif
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index b67746eef923..1dd3a21b3a43 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -11,7 +11,7 @@
* Virtualized Server Adapter.
* Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
-#include<linux/ethtool.h>
+#include <linux/ethtool.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
@@ -29,7 +29,6 @@
* Return value:
* 0 on success.
*/
-
static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
{
/* We currently only support 10Gb/FULL */
@@ -79,10 +78,9 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
* Returns driver specefic information like name, version etc.. to ethtool.
*/
static void vxge_ethtool_gdrvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+ struct ethtool_drvinfo *info)
{
- struct vxgedev *vdev;
- vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME));
strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN);
@@ -104,15 +102,14 @@ static void vxge_ethtool_gdrvinfo(struct net_device *dev,
* buffer area.
*/
static void vxge_ethtool_gregs(struct net_device *dev,
- struct ethtool_regs *regs, void *space)
+ struct ethtool_regs *regs, void *space)
{
int index, offset;
enum vxge_hw_status status;
u64 reg;
- u64 *reg_space = (u64 *) space;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ u64 *reg_space = (u64 *)space;
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
regs->version = vdev->pdev->subsystem_device;
@@ -147,9 +144,8 @@ static void vxge_ethtool_gregs(struct net_device *dev,
*/
static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
@@ -168,11 +164,10 @@ static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
* void
*/
static void vxge_ethtool_getpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
+ struct ethtool_pauseparam *ep)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause);
}
@@ -188,11 +183,10 @@ static void vxge_ethtool_getpause_data(struct net_device *dev,
* int, returns 0 on Success
*/
static int vxge_ethtool_setpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
+ struct ethtool_pauseparam *ep)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause);
@@ -209,9 +203,8 @@ static void vxge_get_ethtool_stats(struct net_device *dev,
enum vxge_hw_status status;
enum vxge_hw_status swstatus;
struct vxge_vpath *vpath = NULL;
-
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
- struct __vxge_hw_device *hldev = vdev->devh;
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
struct vxge_hw_xmac_stats *xmac_stats;
struct vxge_hw_device_stats_sw_info *sw_stats;
struct vxge_hw_device_stats_hw_info *hw_stats;
@@ -574,12 +567,12 @@ static void vxge_get_ethtool_stats(struct net_device *dev,
kfree(hw_stats);
}
-static void vxge_ethtool_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
+static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset,
+ u8 *data)
{
int stat_size = 0;
int i, j;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
switch (stringset) {
case ETH_SS_STATS:
vxge_add_string("VPATH STATISTICS%s\t\t\t",
@@ -1066,21 +1059,21 @@ static void vxge_ethtool_get_strings(struct net_device *dev,
static int vxge_ethtool_get_regs_len(struct net_device *dev)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
}
static u32 vxge_get_rx_csum(struct net_device *dev)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
return vdev->rx_csum;
}
static int vxge_set_rx_csum(struct net_device *dev, u32 data)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
if (data)
vdev->rx_csum = 1;
@@ -1102,7 +1095,7 @@ static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
{
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
switch (sset) {
case ETH_SS_STATS:
@@ -1119,6 +1112,59 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
}
}
+static int vxge_set_flags(struct net_device *dev, u32 data)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+ enum vxge_hw_status status;
+
+ if (data & ~ETH_FLAG_RXHASH)
+ return -EOPNOTSUPP;
+
+ if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
+ return 0;
+
+ if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
+ return -EINVAL;
+
+ vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);
+
+ /* Enabling RTH requires some of the logic in vxge_device_register and a
+ * vpath reset. Due to these restrictions, only allow modification
+ * while the interface is down.
+ */
+ status = vxge_reset_all_vpaths(vdev);
+ if (status != VXGE_HW_OK) {
+ vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
+ return -EFAULT;
+ }
+
+ if (vdev->devh->config.rth_en)
+ dev->features |= NETIF_F_RXHASH;
+ else
+ dev->features &= ~NETIF_F_RXHASH;
+
+ return 0;
+}
+
+static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+
+ if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) {
+ printk(KERN_INFO "Single Function Mode is required to flash the"
+ " firmware\n");
+ return -EINVAL;
+ }
+
+ if (netif_running(dev)) {
+ printk(KERN_INFO "Interface %s must be down to flash the "
+ "firmware\n", dev->name);
+ return -EBUSY;
+ }
+
+ return vxge_fw_upgrade(vdev, parms->data, 1);
+}
+
static const struct ethtool_ops vxge_ethtool_ops = {
.get_settings = vxge_ethtool_gset,
.set_settings = vxge_ethtool_sset,
@@ -1131,7 +1177,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.get_rx_csum = vxge_get_rx_csum,
.set_rx_csum = vxge_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
@@ -1140,6 +1186,8 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.phys_id = vxge_ethtool_idnic,
.get_sset_count = vxge_ethtool_get_sset_count,
.get_ethtool_stats = vxge_get_ethtool_stats,
+ .set_flags = vxge_set_flags,
+ .flash_device = vxge_fw_flash,
};
void vxge_initialize_ethtool_ops(struct net_device *ndev)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 813829f3d024..1ac9b568f1b0 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -50,6 +50,8 @@
#include <net/ip.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/firmware.h>
+#include <linux/net_tstamp.h>
#include "vxge-main.h"
#include "vxge-reg.h"
@@ -82,16 +84,6 @@ module_param_array(bw_percentage, uint, NULL, 0);
static struct vxge_drv_config *driver_config;
-static enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
- struct macInfo *mac);
-static enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev,
- struct macInfo *mac);
-static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac);
-static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac);
-static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath);
-static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath);
-static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
-
static inline int is_vxge_card_up(struct vxgedev *vdev)
{
return test_bit(__VXGE_STATE_CARD_UP, &vdev->state);
@@ -148,11 +140,10 @@ static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev)
* This function is called during interrupt context to notify link up state
* change.
*/
-static void
-vxge_callback_link_up(struct __vxge_hw_device *hldev)
+static void vxge_callback_link_up(struct __vxge_hw_device *hldev)
{
struct net_device *dev = hldev->ndev;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
vdev->ndev->name, __func__, __LINE__);
@@ -172,11 +163,10 @@ vxge_callback_link_up(struct __vxge_hw_device *hldev)
* This function is called during interrupt context to notify link down state
* change.
*/
-static void
-vxge_callback_link_down(struct __vxge_hw_device *hldev)
+static void vxge_callback_link_down(struct __vxge_hw_device *hldev)
{
struct net_device *dev = hldev->ndev;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
@@ -195,7 +185,7 @@ vxge_callback_link_down(struct __vxge_hw_device *hldev)
*
* Allocate SKB.
*/
-static struct sk_buff*
+static struct sk_buff *
vxge_rx_alloc(void *dtrh, struct vxge_ring *ring, const int skb_size)
{
struct net_device *dev;
@@ -369,7 +359,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
u8 t_code, void *userdata)
{
struct vxge_ring *ring = (struct vxge_ring *)userdata;
- struct net_device *dev = ring->ndev;
+ struct net_device *dev = ring->ndev;
unsigned int dma_sizes;
void *first_dtr = NULL;
int dtr_cnt = 0;
@@ -413,7 +403,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
prefetch((char *)skb + L1_CACHE_BYTES);
if (unlikely(t_code)) {
-
if (vxge_hw_ring_handle_tcode(ringh, dtr, t_code) !=
VXGE_HW_OK) {
@@ -436,9 +425,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
}
if (pkt_length > VXGE_LL_RX_COPY_THRESHOLD) {
-
if (vxge_rx_alloc(dtr, ring, data_size) != NULL) {
-
if (!vxge_rx_map(dtr, ring)) {
skb_put(skb, pkt_length);
@@ -513,6 +500,23 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
else
skb_checksum_none_assert(skb);
+
+ if (ring->rx_hwts) {
+ struct skb_shared_hwtstamps *skb_hwts;
+ u32 ns = *(u32 *)(skb->head + pkt_length);
+
+ skb_hwts = skb_hwtstamps(skb);
+ skb_hwts->hwtstamp = ns_to_ktime(ns);
+ skb_hwts->syststamp.tv64 = 0;
+ }
+
+ /* rth_hash_type and rth_it_hit are non-zero regardless of
+ * whether rss is enabled. Only the rth_value is zero/non-zero
+ * if rss is disabled/enabled, so key off of that.
+ */
+ if (ext_info.rth_value)
+ skb->rxhash = ext_info.rth_value;
+
vxge_rx_complete(ring, skb, ext_info.vlan,
pkt_length, &ext_info);
@@ -660,6 +664,65 @@ static enum vxge_hw_status vxge_search_mac_addr_in_list(
return FALSE;
}
+static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+ struct vxge_mac_addrs *new_mac_entry;
+ u8 *mac_address = NULL;
+
+ if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT)
+ return TRUE;
+
+ new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC);
+ if (!new_mac_entry) {
+ vxge_debug_mem(VXGE_ERR,
+ "%s: memory allocation failed",
+ VXGE_DRIVER_NAME);
+ return FALSE;
+ }
+
+ list_add(&new_mac_entry->item, &vpath->mac_addr_list);
+
+ /* Copy the new mac address to the list */
+ mac_address = (u8 *)&new_mac_entry->macaddr;
+ memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+ new_mac_entry->state = mac->state;
+ vpath->mac_addr_cnt++;
+
+ /* Is this a multicast address */
+ if (0x01 & mac->macaddr[0])
+ vpath->mcast_addr_cnt++;
+
+ return TRUE;
+}
+
+/* Add a mac address to DA table */
+static enum vxge_hw_status
+vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+ enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode;
+
+ if (0x01 & mac->macaddr[0]) /* multicast address */
+ duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE;
+ else
+ duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE;
+
+ vpath = &vdev->vpaths[mac->vpath_no];
+ status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr,
+ mac->macmask, duplicate_mode);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config add entry failed for vpath:%d",
+ vpath->device_id);
+ } else
+ if (FALSE == vxge_mac_list_add(vpath, mac))
+ status = -EPERM;
+
+ return status;
+}
+
static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
{
struct macInfo mac_info;
@@ -670,7 +733,7 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
struct vxge_vpath *vpath = NULL;
struct __vxge_hw_device *hldev;
- hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+ hldev = pci_get_drvdata(vdev->pdev);
mac_address = (u8 *)&mac_addr;
memcpy(mac_address, mac_header, ETH_ALEN);
@@ -769,7 +832,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
if (unlikely(!is_vxge_card_up(vdev))) {
vxge_debug_tx(VXGE_ERR,
@@ -1005,6 +1068,50 @@ vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata)
"%s:%d Exiting...", __func__, __LINE__);
}
+static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+ struct list_head *entry, *next;
+ u64 del_mac = 0;
+ u8 *mac_address = (u8 *) (&del_mac);
+
+ /* Copy the mac address to delete from the list */
+ memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) {
+ list_del(entry);
+ kfree((struct vxge_mac_addrs *)entry);
+ vpath->mac_addr_cnt--;
+
+ /* Is this a multicast address */
+ if (0x01 & mac->macaddr[0])
+ vpath->mcast_addr_cnt--;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* delete a mac address from DA table */
+static enum vxge_hw_status
+vxge_del_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+
+ vpath = &vdev->vpaths[mac->vpath_no];
+ status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr,
+ mac->macmask);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config delete entry failed for vpath:%d",
+ vpath->device_id);
+ } else
+ vxge_mac_list_del(vpath, mac);
+ return status;
+}
+
/**
* vxge_set_multicast
* @dev: pointer to the device structure
@@ -1034,7 +1141,7 @@ static void vxge_set_multicast(struct net_device *dev)
vxge_debug_entryexit(VXGE_TRACE,
"%s:%d", __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
hldev = (struct __vxge_hw_device *)vdev->devh;
if (unlikely(!is_vxge_card_up(vdev)))
@@ -1094,7 +1201,7 @@ static void vxge_set_multicast(struct net_device *dev)
/* Delete previous MC's */
for (i = 0; i < mcast_cnt; i++) {
list_for_each_safe(entry, next, list_head) {
- mac_entry = (struct vxge_mac_addrs *) entry;
+ mac_entry = (struct vxge_mac_addrs *)entry;
/* Copy the mac address to delete */
mac_address = (u8 *)&mac_entry->macaddr;
memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
@@ -1137,7 +1244,7 @@ _set_all_mcast:
/* Delete previous MC's */
for (i = 0; i < mcast_cnt; i++) {
list_for_each_safe(entry, next, list_head) {
- mac_entry = (struct vxge_mac_addrs *) entry;
+ mac_entry = (struct vxge_mac_addrs *)entry;
/* Copy the mac address to delete */
mac_address = (u8 *)&mac_entry->macaddr;
memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
@@ -1184,14 +1291,14 @@ static int vxge_set_mac_addr(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
struct vxgedev *vdev;
- struct __vxge_hw_device *hldev;
+ struct __vxge_hw_device *hldev;
enum vxge_hw_status status = VXGE_HW_OK;
struct macInfo mac_info_new, mac_info_old;
int vpath_idx = 0;
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
hldev = vdev->devh;
if (!is_valid_ether_addr(addr->sa_data))
@@ -1292,8 +1399,13 @@ static void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id)
static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id)
{
struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
+ struct __vxge_hw_device *hldev;
int msix_id;
+ hldev = pci_get_drvdata(vdev->pdev);
+
+ vxge_hw_vpath_wait_receive_idle(hldev, vpath->device_id);
+
vxge_hw_vpath_intr_disable(vpath->handle);
if (vdev->config.intr_type == INTA)
@@ -1310,6 +1422,95 @@ static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id)
}
}
+/* list all mac addresses from DA table */
+static enum vxge_hw_status
+vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ unsigned char macmask[ETH_ALEN];
+ unsigned char macaddr[ETH_ALEN];
+
+ status = vxge_hw_vpath_mac_addr_get(vpath->handle,
+ macaddr, macmask);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config list entry failed for vpath:%d",
+ vpath->device_id);
+ return status;
+ }
+
+ while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) {
+ status = vxge_hw_vpath_mac_addr_get_next(vpath->handle,
+ macaddr, macmask);
+ if (status != VXGE_HW_OK)
+ break;
+ }
+
+ return status;
+}
+
+/* Store all mac addresses from the list to the DA table */
+static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct macInfo mac_info;
+ u8 *mac_address = NULL;
+ struct list_head *entry, *next;
+
+ memset(&mac_info, 0, sizeof(struct macInfo));
+
+ if (vpath->is_open) {
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ mac_address =
+ (u8 *)&
+ ((struct vxge_mac_addrs *)entry)->macaddr;
+ memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+ ((struct vxge_mac_addrs *)entry)->state =
+ VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+ /* does this mac address already exist in da table? */
+ status = vxge_search_mac_addr_in_da_table(vpath,
+ &mac_info);
+ if (status != VXGE_HW_OK) {
+ /* Add this mac address to the DA table */
+ status = vxge_hw_vpath_mac_addr_add(
+ vpath->handle, mac_info.macaddr,
+ mac_info.macmask,
+ VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA add entry failed for vpath:%d",
+ vpath->device_id);
+ ((struct vxge_mac_addrs *)entry)->state
+ = VXGE_LL_MAC_ADDR_IN_LIST;
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+/* Store all vlan ids from the list to the vid table */
+static enum vxge_hw_status
+vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxgedev *vdev = vpath->vdev;
+ u16 vid;
+
+ if (vdev->vlgrp && vpath->is_open) {
+
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
+ if (!vlan_group_get_device(vdev->vlgrp, vid))
+ continue;
+ /* Add these vlan to the vid table */
+ status = vxge_hw_vpath_vid_add(vpath->handle, vid);
+ }
+ }
+
+ return status;
+}
+
/*
* vxge_reset_vpath
* @vdev: pointer to vdev
@@ -1405,12 +1606,16 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
}
if (event == VXGE_LL_FULL_RESET) {
+ netif_carrier_off(vdev->ndev);
+
/* wait for all the vpath reset to complete */
for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
while (test_bit(vp_id, &vdev->vp_reset))
msleep(50);
}
+ netif_carrier_on(vdev->ndev);
+
/* if execution mode is set to debug, don't reset the adapter */
if (unlikely(vdev->exec_mode)) {
vxge_debug_init(VXGE_ERR,
@@ -1423,6 +1628,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
}
if (event == VXGE_LL_FULL_RESET) {
+ vxge_hw_device_wait_receive_idle(vdev->devh);
vxge_hw_device_intr_disable(vdev->devh);
switch (vdev->cric_err_event) {
@@ -1563,9 +1769,14 @@ out:
*
* driver may reset the chip on events of serr, eccerr, etc
*/
-static int vxge_reset(struct vxgedev *vdev)
+static void vxge_reset(struct work_struct *work)
{
- return do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
+ struct vxgedev *vdev = container_of(work, struct vxgedev, reset_task);
+
+ if (!netif_running(vdev->ndev))
+ return;
+
+ do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
}
/**
@@ -1608,8 +1819,7 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget)
int budget_org = budget;
struct vxge_ring *ring;
- struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
- pci_get_drvdata(vdev->pdev);
+ struct __vxge_hw_device *hldev = pci_get_drvdata(vdev->pdev);
for (i = 0; i < vdev->no_of_vpath; i++) {
ring = &vdev->vpaths[i].ring;
@@ -1645,11 +1855,11 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget)
*/
static void vxge_netpoll(struct net_device *dev)
{
- struct __vxge_hw_device *hldev;
+ struct __vxge_hw_device *hldev;
struct vxgedev *vdev;
- vdev = (struct vxgedev *)netdev_priv(dev);
- hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
+ vdev = netdev_priv(dev);
+ hldev = pci_get_drvdata(vdev->pdev);
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
@@ -1689,15 +1899,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
mtable[index] = index % vdev->no_of_vpath;
}
- /* Fill RTH hash types */
- hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4;
- hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4;
- hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6;
- hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6;
- hash_types.hash_type_tcpipv6ex_en =
- vdev->config.rth_hash_type_tcpipv6ex;
- hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex;
-
/* set indirection table, bucket-to-vpath mapping */
status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
vdev->no_of_vpath,
@@ -1710,19 +1911,27 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
return status;
}
+ /* Fill RTH hash types */
+ hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4;
+ hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4;
+ hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6;
+ hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6;
+ hash_types.hash_type_tcpipv6ex_en =
+ vdev->config.rth_hash_type_tcpipv6ex;
+ hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex;
+
/*
- * Because the itable_set() method uses the active_table field
- * for the target virtual path the RTH config should be updated
- * for all VPATHs. The h/w only uses the lowest numbered VPATH
- * when steering frames.
- */
+ * Because the itable_set() method uses the active_table field
+ * for the target virtual path the RTH config should be updated
+ * for all VPATHs. The h/w only uses the lowest numbered VPATH
+ * when steering frames.
+ */
for (index = 0; index < vdev->no_of_vpath; index++) {
status = vxge_hw_vpath_rts_rth_set(
vdev->vpaths[index].handle,
vdev->config.rth_algorithm,
&hash_types,
vdev->config.rth_bkt_sz);
-
if (status != VXGE_HW_OK) {
vxge_debug_init(VXGE_ERR,
"RTH configuration failed for vpath:%d",
@@ -1734,201 +1943,8 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
return status;
}
-static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac)
-{
- struct vxge_mac_addrs *new_mac_entry;
- u8 *mac_address = NULL;
-
- if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT)
- return TRUE;
-
- new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC);
- if (!new_mac_entry) {
- vxge_debug_mem(VXGE_ERR,
- "%s: memory allocation failed",
- VXGE_DRIVER_NAME);
- return FALSE;
- }
-
- list_add(&new_mac_entry->item, &vpath->mac_addr_list);
-
- /* Copy the new mac address to the list */
- mac_address = (u8 *)&new_mac_entry->macaddr;
- memcpy(mac_address, mac->macaddr, ETH_ALEN);
-
- new_mac_entry->state = mac->state;
- vpath->mac_addr_cnt++;
-
- /* Is this a multicast address */
- if (0x01 & mac->macaddr[0])
- vpath->mcast_addr_cnt++;
-
- return TRUE;
-}
-
-/* Add a mac address to DA table */
-static enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
- struct macInfo *mac)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_vpath *vpath;
- enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode;
-
- if (0x01 & mac->macaddr[0]) /* multicast address */
- duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE;
- else
- duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE;
-
- vpath = &vdev->vpaths[mac->vpath_no];
- status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr,
- mac->macmask, duplicate_mode);
- if (status != VXGE_HW_OK) {
- vxge_debug_init(VXGE_ERR,
- "DA config add entry failed for vpath:%d",
- vpath->device_id);
- } else
- if (FALSE == vxge_mac_list_add(vpath, mac))
- status = -EPERM;
-
- return status;
-}
-
-static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac)
-{
- struct list_head *entry, *next;
- u64 del_mac = 0;
- u8 *mac_address = (u8 *) (&del_mac);
-
- /* Copy the mac address to delete from the list */
- memcpy(mac_address, mac->macaddr, ETH_ALEN);
-
- list_for_each_safe(entry, next, &vpath->mac_addr_list) {
- if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) {
- list_del(entry);
- kfree((struct vxge_mac_addrs *)entry);
- vpath->mac_addr_cnt--;
-
- /* Is this a multicast address */
- if (0x01 & mac->macaddr[0])
- vpath->mcast_addr_cnt--;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-/* delete a mac address from DA table */
-static enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev,
- struct macInfo *mac)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxge_vpath *vpath;
-
- vpath = &vdev->vpaths[mac->vpath_no];
- status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr,
- mac->macmask);
- if (status != VXGE_HW_OK) {
- vxge_debug_init(VXGE_ERR,
- "DA config delete entry failed for vpath:%d",
- vpath->device_id);
- } else
- vxge_mac_list_del(vpath, mac);
- return status;
-}
-
-/* list all mac addresses from DA table */
-enum vxge_hw_status
-static vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath,
- struct macInfo *mac)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- unsigned char macmask[ETH_ALEN];
- unsigned char macaddr[ETH_ALEN];
-
- status = vxge_hw_vpath_mac_addr_get(vpath->handle,
- macaddr, macmask);
- if (status != VXGE_HW_OK) {
- vxge_debug_init(VXGE_ERR,
- "DA config list entry failed for vpath:%d",
- vpath->device_id);
- return status;
- }
-
- while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) {
-
- status = vxge_hw_vpath_mac_addr_get_next(vpath->handle,
- macaddr, macmask);
- if (status != VXGE_HW_OK)
- break;
- }
-
- return status;
-}
-
-/* Store all vlan ids from the list to the vid table */
-static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct vxgedev *vdev = vpath->vdev;
- u16 vid;
-
- if (vdev->vlgrp && vpath->is_open) {
-
- for (vid = 0; vid < VLAN_N_VID; vid++) {
- if (!vlan_group_get_device(vdev->vlgrp, vid))
- continue;
- /* Add these vlan to the vid table */
- status = vxge_hw_vpath_vid_add(vpath->handle, vid);
- }
- }
-
- return status;
-}
-
-/* Store all mac addresses from the list to the DA table */
-static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath)
-{
- enum vxge_hw_status status = VXGE_HW_OK;
- struct macInfo mac_info;
- u8 *mac_address = NULL;
- struct list_head *entry, *next;
-
- memset(&mac_info, 0, sizeof(struct macInfo));
-
- if (vpath->is_open) {
-
- list_for_each_safe(entry, next, &vpath->mac_addr_list) {
- mac_address =
- (u8 *)&
- ((struct vxge_mac_addrs *)entry)->macaddr;
- memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
- ((struct vxge_mac_addrs *)entry)->state =
- VXGE_LL_MAC_ADDR_IN_DA_TABLE;
- /* does this mac address already exist in da table? */
- status = vxge_search_mac_addr_in_da_table(vpath,
- &mac_info);
- if (status != VXGE_HW_OK) {
- /* Add this mac address to the DA table */
- status = vxge_hw_vpath_mac_addr_add(
- vpath->handle, mac_info.macaddr,
- mac_info.macmask,
- VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE);
- if (status != VXGE_HW_OK) {
- vxge_debug_init(VXGE_ERR,
- "DA add entry failed for vpath:%d",
- vpath->device_id);
- ((struct vxge_mac_addrs *)entry)->state
- = VXGE_LL_MAC_ADDR_IN_LIST;
- }
- }
- }
- }
-
- return status;
-}
-
/* reset vpaths */
-static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
{
enum vxge_hw_status status = VXGE_HW_OK;
struct vxge_vpath *vpath;
@@ -1988,8 +2004,23 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
for (i = 0; i < vdev->no_of_vpath; i++) {
vpath = &vdev->vpaths[i];
-
vxge_assert(vpath->is_configured);
+
+ if (!vdev->titan1) {
+ struct vxge_hw_vp_config *vcfg;
+ vcfg = &vdev->devh->config.vp_config[vpath->device_id];
+
+ vcfg->rti.urange_a = RTI_T1A_RX_URANGE_A;
+ vcfg->rti.urange_b = RTI_T1A_RX_URANGE_B;
+ vcfg->rti.urange_c = RTI_T1A_RX_URANGE_C;
+ vcfg->tti.uec_a = TTI_T1A_TX_UFC_A;
+ vcfg->tti.uec_b = TTI_T1A_TX_UFC_B;
+ vcfg->tti.uec_c = TTI_T1A_TX_UFC_C(vdev->mtu);
+ vcfg->tti.uec_d = TTI_T1A_TX_UFC_D(vdev->mtu);
+ vcfg->tti.ltimer_val = VXGE_T1A_TTI_LTIMER_VAL;
+ vcfg->tti.rtimer_val = VXGE_T1A_TTI_RTIMER_VAL;
+ }
+
attr.vp_id = vpath->device_id;
attr.fifo_attr.callback = vxge_xmit_compl;
attr.fifo_attr.txdl_term = vxge_tx_term;
@@ -2004,6 +2035,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vpath->ring.ndev = vdev->ndev;
vpath->ring.pdev = vdev->pdev;
+
status = vxge_hw_vpath_open(vdev->devh, &attr, &vpath->handle);
if (status == VXGE_HW_OK) {
vpath->fifo.handle =
@@ -2024,6 +2056,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.fifo_indicate_max_pkts;
vpath->ring.rx_vector_no = 0;
vpath->ring.rx_csum = vdev->rx_csum;
+ vpath->ring.rx_hwts = vdev->rx_hwts;
vpath->is_open = 1;
vdev->vp_handles[i] = vpath->handle;
vpath->ring.gro_enable = vdev->config.gro_enable;
@@ -2031,11 +2064,10 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->stats.vpaths_open++;
} else {
vdev->stats.vpath_open_fail++;
- vxge_debug_init(VXGE_ERR,
- "%s: vpath: %d failed to open "
- "with status: %d",
- vdev->ndev->name, vpath->device_id,
- status);
+ vxge_debug_init(VXGE_ERR, "%s: vpath: %d failed to "
+ "open with status: %d",
+ vdev->ndev->name, vpath->device_id,
+ status);
vxge_close_vpaths(vdev, 0);
return -EPERM;
}
@@ -2043,6 +2075,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vp_id = vpath->handle->vpath->vp_id;
vdev->vpaths_deployed |= vxge_mBIT(vp_id);
}
+
return VXGE_HW_OK;
}
@@ -2062,21 +2095,20 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id)
struct __vxge_hw_device *hldev;
u64 reason;
enum vxge_hw_status status;
- struct vxgedev *vdev = (struct vxgedev *) dev_id;;
+ struct vxgedev *vdev = (struct vxgedev *)dev_id;
vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__);
dev = vdev->ndev;
- hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
+ hldev = pci_get_drvdata(vdev->pdev);
if (pci_channel_offline(vdev->pdev))
return IRQ_NONE;
if (unlikely(!is_vxge_card_up(vdev)))
- return IRQ_NONE;
+ return IRQ_HANDLED;
- status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode,
- &reason);
+ status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, &reason);
if (status == VXGE_HW_OK) {
vxge_hw_device_mask_all(hldev);
@@ -2301,8 +2333,8 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev)
static void vxge_rem_isr(struct vxgedev *vdev)
{
- struct __vxge_hw_device *hldev;
- hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+ struct __vxge_hw_device *hldev;
+ hldev = pci_get_drvdata(vdev->pdev);
#ifdef CONFIG_PCI_MSI
if (vdev->config.intr_type == MSI_X) {
@@ -2529,8 +2561,7 @@ static void vxge_poll_vp_lockup(unsigned long data)
* Return value: '0' on success and an appropriate (-)ve integer as
* defined in errno.h file on failure.
*/
-static int
-vxge_open(struct net_device *dev)
+static int vxge_open(struct net_device *dev)
{
enum vxge_hw_status status;
struct vxgedev *vdev;
@@ -2539,11 +2570,12 @@ vxge_open(struct net_device *dev)
int ret = 0;
int i;
u64 val64, function_mode;
+
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d", dev->name, __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
- hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+ vdev = netdev_priv(dev);
+ hldev = pci_get_drvdata(vdev->pdev);
function_mode = vdev->config.device_hw_info.function_mode;
/* make sure you have link off by default every time Nic is
@@ -2598,6 +2630,8 @@ vxge_open(struct net_device *dev)
goto out2;
}
}
+ printk(KERN_INFO "%s: Receive Hashing Offload %s\n", dev->name,
+ hldev->config.rth_en ? "enabled" : "disabled");
for (i = 0; i < vdev->no_of_vpath; i++) {
vpath = &vdev->vpaths[i];
@@ -2683,9 +2717,10 @@ vxge_open(struct net_device *dev)
vxge_os_timer(vdev->vp_reset_timer,
vxge_poll_vp_reset, vdev, (HZ/2));
- if (vdev->vp_lockup_timer.function == NULL)
- vxge_os_timer(vdev->vp_lockup_timer,
- vxge_poll_vp_lockup, vdev, (HZ/2));
+ /* There is no need to check for RxD leak and RxD lookup on Titan1A */
+ if (vdev->titan1 && vdev->vp_lockup_timer.function == NULL)
+ vxge_os_timer(vdev->vp_lockup_timer, vxge_poll_vp_lockup, vdev,
+ HZ / 2);
set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
@@ -2767,8 +2802,8 @@ static int do_vxge_close(struct net_device *dev, int do_io)
vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
dev->name, __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
- hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+ vdev = netdev_priv(dev);
+ hldev = pci_get_drvdata(vdev->pdev);
if (unlikely(!is_vxge_card_up(vdev)))
return 0;
@@ -2778,7 +2813,6 @@ static int do_vxge_close(struct net_device *dev, int do_io)
while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
msleep(50);
- clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
if (do_io) {
/* Put the vpath back in normal mode */
vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id);
@@ -2789,7 +2823,6 @@ static int do_vxge_close(struct net_device *dev, int do_io)
struct vxge_hw_mrpcim_reg,
rts_mgr_cbasin_cfg),
&val64);
-
if (status == VXGE_HW_OK) {
val64 &= ~vpath_vector;
status = vxge_hw_mgmt_reg_write(vdev->devh,
@@ -2818,10 +2851,17 @@ static int do_vxge_close(struct net_device *dev, int do_io)
smp_wmb();
}
- del_timer_sync(&vdev->vp_lockup_timer);
+
+ if (vdev->titan1)
+ del_timer_sync(&vdev->vp_lockup_timer);
del_timer_sync(&vdev->vp_reset_timer);
+ if (do_io)
+ vxge_hw_device_wait_receive_idle(hldev);
+
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+
/* Disable napi */
if (vdev->config.intr_type != MSI_X)
napi_disable(&vdev->napi);
@@ -2838,8 +2878,6 @@ static int do_vxge_close(struct net_device *dev, int do_io)
if (do_io)
vxge_hw_device_intr_disable(vdev->devh);
- mdelay(1000);
-
vxge_rem_isr(vdev);
vxge_napi_del_all(vdev);
@@ -2868,8 +2906,7 @@ static int do_vxge_close(struct net_device *dev, int do_io)
* Return value: '0' on success and an appropriate (-)ve integer as
* defined in errno.h file on failure.
*/
-static int
-vxge_close(struct net_device *dev)
+static int vxge_close(struct net_device *dev)
{
do_vxge_close(dev, 1);
return 0;
@@ -2943,9 +2980,7 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors;
net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast;
- net_stats->rx_dropped +=
- vdev->vpaths[k].ring.stats.rx_dropped;
-
+ net_stats->rx_dropped += vdev->vpaths[k].ring.stats.rx_dropped;
net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms;
net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes;
net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors;
@@ -2954,6 +2989,101 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
return net_stats;
}
+static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev,
+ int enable)
+{
+ enum vxge_hw_status status;
+ u64 val64;
+
+ /* Timestamp is passed to the driver via the FCS, therefore we
+ * must disable the FCS stripping by the adapter. Since this is
+ * required for the driver to load (due to a hardware bug),
+ * there is no need to do anything special here.
+ */
+ if (enable)
+ val64 = VXGE_HW_XMAC_TIMESTAMP_EN |
+ VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) |
+ VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0);
+ else
+ val64 = 0;
+
+ status = vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ offsetof(struct vxge_hw_mrpcim_reg,
+ xmac_timestamp),
+ val64);
+ vxge_hw_device_flush_io(vdev->devh);
+ return status;
+}
+
+static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
+{
+ struct hwtstamp_config config;
+ enum vxge_hw_status status;
+ int i;
+
+ if (copy_from_user(&config, data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ /* Transmit HW Timestamp not supported */
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ break;
+ case HWTSTAMP_TX_ON:
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ status = vxge_timestamp_config(vdev, 0);
+ if (status != VXGE_HW_OK)
+ return -EFAULT;
+
+ vdev->rx_hwts = 0;
+ config.rx_filter = HWTSTAMP_FILTER_NONE;
+ break;
+
+ case HWTSTAMP_FILTER_ALL:
+ case HWTSTAMP_FILTER_SOME:
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ status = vxge_timestamp_config(vdev, 1);
+ if (status != VXGE_HW_OK)
+ return -EFAULT;
+
+ vdev->rx_hwts = 1;
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ break;
+
+ default:
+ return -ERANGE;
+ }
+
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vdev->vpaths[i].ring.rx_hwts = vdev->rx_hwts;
+
+ if (copy_to_user(data, &config, sizeof(config)))
+ return -EFAULT;
+
+ return 0;
+}
+
/**
* vxge_ioctl
* @dev: Device pointer.
@@ -2966,7 +3096,20 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
*/
static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- return -EOPNOTSUPP;
+ struct vxgedev *vdev = netdev_priv(dev);
+ int ret;
+
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ ret = vxge_hwtstamp_ioctl(vdev, rq->ifr_data);
+ if (ret)
+ return ret;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
}
/**
@@ -2977,18 +3120,17 @@ static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* This function is triggered if the Tx Queue is stopped
* for a pre-defined amount of time when the Interface is still up.
*/
-static void
-vxge_tx_watchdog(struct net_device *dev)
+static void vxge_tx_watchdog(struct net_device *dev)
{
struct vxgedev *vdev;
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
vdev->cric_err_event = VXGE_HW_EVENT_RESET_START;
- vxge_reset(vdev);
+ schedule_work(&vdev->reset_task);
vxge_debug_entryexit(VXGE_TRACE,
"%s:%d Exiting...", __func__, __LINE__);
}
@@ -3012,7 +3154,7 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
vpath = &vdev->vpaths[0];
if ((NULL == grp) && (vpath->is_open)) {
@@ -3061,7 +3203,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
struct vxge_vpath *vpath;
int vp_id;
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
/* Add these vlan to the vid table */
for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
@@ -3088,7 +3230,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
- vdev = (struct vxgedev *)netdev_priv(dev);
+ vdev = netdev_priv(dev);
vlan_group_set_device(vdev->vlgrp, vid, NULL);
@@ -3110,21 +3252,31 @@ static const struct net_device_ops vxge_netdev_ops = {
.ndo_start_xmit = vxge_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = vxge_set_multicast,
-
.ndo_do_ioctl = vxge_ioctl,
-
.ndo_set_mac_address = vxge_set_mac_addr,
.ndo_change_mtu = vxge_change_mtu,
.ndo_vlan_rx_register = vxge_vlan_rx_register,
.ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid,
.ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid,
-
.ndo_tx_timeout = vxge_tx_watchdog,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = vxge_netpoll,
#endif
};
+static int __devinit vxge_device_revision(struct vxgedev *vdev)
+{
+ int ret;
+ u8 revision;
+
+ ret = pci_read_config_byte(vdev->pdev, PCI_REVISION_ID, &revision);
+ if (ret)
+ return -EIO;
+
+ vdev->titan1 = (revision == VXGE_HW_TITAN1_PCI_REVISION);
+ return 0;
+}
+
static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
struct vxge_config *config,
int high_dma, int no_of_vpath,
@@ -3163,6 +3315,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
vdev->pdev = hldev->pdev;
memcpy(&vdev->config, config, sizeof(struct vxge_config));
vdev->rx_csum = 1; /* Enable Rx CSUM by default. */
+ vdev->rx_hwts = 0;
+
+ ret = vxge_device_revision(vdev);
+ if (ret < 0)
+ goto _out1;
SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
@@ -3175,9 +3332,15 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
ndev->netdev_ops = &vxge_netdev_ops;
ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT;
+ INIT_WORK(&vdev->reset_task, vxge_reset);
vxge_initialize_ethtool_ops(ndev);
+ if (vdev->config.rth_steering != NO_STEERING) {
+ ndev->features |= NETIF_F_RXHASH;
+ hldev->config.rth_en = VXGE_HW_RTH_ENABLE;
+ }
+
/* Allocate memory for vpath */
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
no_of_vpath, GFP_KERNEL);
@@ -3191,7 +3354,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
ndev->features |= NETIF_F_SG;
- ndev->features |= NETIF_F_HW_CSUM;
+ ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
"%s : checksuming enabled", __func__);
@@ -3227,6 +3390,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
"%s: Ethernet device registered",
ndev->name);
+ hldev->ndev = ndev;
*vdev_out = vdev;
/* Resetting the Device stats */
@@ -3261,36 +3425,29 @@ _out0:
*
* This function will unregister and free network device
*/
-static void
-vxge_device_unregister(struct __vxge_hw_device *hldev)
+static void vxge_device_unregister(struct __vxge_hw_device *hldev)
{
struct vxgedev *vdev;
struct net_device *dev;
char buf[IFNAMSIZ];
-#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
- (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
- u32 level_trace;
-#endif
dev = hldev->ndev;
vdev = netdev_priv(dev);
-#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
- (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
- level_trace = vdev->level_trace;
-#endif
- vxge_debug_entryexit(level_trace,
- "%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
- memcpy(buf, vdev->ndev->name, IFNAMSIZ);
+ vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d", vdev->ndev->name,
+ __func__, __LINE__);
+
+ strncpy(buf, dev->name, IFNAMSIZ);
+
+ flush_work_sync(&vdev->reset_task);
/* in 2.6 will call stop() if device is up */
unregister_netdev(dev);
- flush_scheduled_work();
-
- vxge_debug_init(level_trace, "%s: ethernet device unregistered", buf);
- vxge_debug_entryexit(level_trace,
- "%s: %s:%d Exiting...", buf, __func__, __LINE__);
+ vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered",
+ buf);
+ vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf,
+ __func__, __LINE__);
}
/*
@@ -3304,7 +3461,7 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev,
enum vxge_hw_event type, u64 vp_id)
{
struct net_device *dev = hldev->ndev;
- struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxgedev *vdev = netdev_priv(dev);
struct vxge_vpath *vpath = NULL;
int vpath_idx;
@@ -3527,9 +3684,9 @@ static int __devinit vxge_config_vpaths(
device_config->vp_config[i].tti.timer_ac_en =
VXGE_HW_TIM_TIMER_AC_ENABLE;
- /* For msi-x with napi (each vector
- has a handler of its own) -
- Set CI to OFF for all vpaths */
+ /* For msi-x with napi (each vector has a handler of its own) -
+ * Set CI to OFF for all vpaths
+ */
device_config->vp_config[i].tti.timer_ci_en =
VXGE_HW_TIM_TIMER_CI_DISABLE;
@@ -3559,10 +3716,13 @@ static int __devinit vxge_config_vpaths(
device_config->vp_config[i].ring.ring_blocks =
VXGE_HW_DEF_RING_BLOCKS;
+
device_config->vp_config[i].ring.buffer_mode =
VXGE_HW_RING_RXD_BUFFER_MODE_1;
+
device_config->vp_config[i].ring.rxds_limit =
VXGE_HW_DEF_RING_RXDS_LIMIT;
+
device_config->vp_config[i].ring.scatter_mode =
VXGE_HW_RING_SCATTER_MODE_A;
@@ -3642,6 +3802,7 @@ static void __devinit vxge_device_config_init(
device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX;
break;
}
+
/* Timer period between device poll */
device_config->device_poll_millis = VXGE_TIMER_DELAY;
@@ -3653,16 +3814,10 @@ static void __devinit vxge_device_config_init(
vxge_debug_ll_config(VXGE_TRACE, "%s : Device Config Params ",
__func__);
- vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_initial : %d",
- device_config->dma_blockpool_initial);
- vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_max : %d",
- device_config->dma_blockpool_max);
vxge_debug_ll_config(VXGE_TRACE, "intr_mode : %d",
device_config->intr_mode);
vxge_debug_ll_config(VXGE_TRACE, "device_poll_millis : %d",
device_config->device_poll_millis);
- vxge_debug_ll_config(VXGE_TRACE, "rts_mac_en : %d",
- device_config->rts_mac_en);
vxge_debug_ll_config(VXGE_TRACE, "rth_en : %d",
device_config->rth_en);
vxge_debug_ll_config(VXGE_TRACE, "rth_it_type : %d",
@@ -3751,9 +3906,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
vxge_debug_init(VXGE_TRACE,
"%s: MAC Address learning enabled", vdev->ndev->name);
- vxge_debug_init(VXGE_TRACE,
- "%s: Rx doorbell mode enabled", vdev->ndev->name);
-
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
if (!vxge_bVALn(vpath_mask, i, 1))
continue;
@@ -3766,14 +3918,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
((struct __vxge_hw_device *)(vdev->devh))->
config.vp_config[i].rpa_strip_vlan_tag
? "Enabled" : "Disabled");
- vxge_debug_init(VXGE_TRACE,
- "%s: Ring blocks : %d", vdev->ndev->name,
- ((struct __vxge_hw_device *)(vdev->devh))->
- config.vp_config[i].ring.ring_blocks);
- vxge_debug_init(VXGE_TRACE,
- "%s: Fifo blocks : %d", vdev->ndev->name,
- ((struct __vxge_hw_device *)(vdev->devh))->
- config.vp_config[i].fifo.fifo_blocks);
vxge_debug_ll_config(VXGE_TRACE,
"%s: Max frags : %d", vdev->ndev->name,
((struct __vxge_hw_device *)(vdev->devh))->
@@ -3813,8 +3957,7 @@ static int vxge_pm_resume(struct pci_dev *pdev)
static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- struct __vxge_hw_device *hldev =
- (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct __vxge_hw_device *hldev = pci_get_drvdata(pdev);
struct net_device *netdev = hldev->ndev;
netif_device_detach(netdev);
@@ -3843,8 +3986,7 @@ static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev,
*/
static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
{
- struct __vxge_hw_device *hldev =
- (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct __vxge_hw_device *hldev = pci_get_drvdata(pdev);
struct net_device *netdev = hldev->ndev;
struct vxgedev *vdev = netdev_priv(netdev);
@@ -3855,7 +3997,7 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
}
pci_set_master(pdev);
- vxge_reset(vdev);
+ do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
return PCI_ERS_RESULT_RECOVERED;
}
@@ -3869,8 +4011,7 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
*/
static void vxge_io_resume(struct pci_dev *pdev)
{
- struct __vxge_hw_device *hldev =
- (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct __vxge_hw_device *hldev = pci_get_drvdata(pdev);
struct net_device *netdev = hldev->ndev;
if (netif_running(netdev)) {
@@ -3914,6 +4055,156 @@ static inline u32 vxge_get_num_vfs(u64 function_mode)
return num_functions;
}
+int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override)
+{
+ struct __vxge_hw_device *hldev = vdev->devh;
+ u32 maj, min, bld, cmaj, cmin, cbld;
+ enum vxge_hw_status status;
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, fw_name, &vdev->pdev->dev);
+ if (ret) {
+ vxge_debug_init(VXGE_ERR, "%s: Firmware file '%s' not found",
+ VXGE_DRIVER_NAME, fw_name);
+ goto out;
+ }
+
+ /* Load the new firmware onto the adapter */
+ status = vxge_update_fw_image(hldev, fw->data, fw->size);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: FW image download to adapter failed '%s'.",
+ VXGE_DRIVER_NAME, fw_name);
+ ret = -EIO;
+ goto out;
+ }
+
+ /* Read the version of the new firmware */
+ status = vxge_hw_upgrade_read_version(hldev, &maj, &min, &bld);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Upgrade read version failed '%s'.",
+ VXGE_DRIVER_NAME, fw_name);
+ ret = -EIO;
+ goto out;
+ }
+
+ cmaj = vdev->config.device_hw_info.fw_version.major;
+ cmin = vdev->config.device_hw_info.fw_version.minor;
+ cbld = vdev->config.device_hw_info.fw_version.build;
+ /* It's possible the version in /lib/firmware is not the latest version.
+ * If so, we could get into a loop of trying to upgrade to the latest
+ * and flashing the older version.
+ */
+ if (VXGE_FW_VER(maj, min, bld) == VXGE_FW_VER(cmaj, cmin, cbld) &&
+ !override) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ printk(KERN_NOTICE "Upgrade to firmware version %d.%d.%d commencing\n",
+ maj, min, bld);
+
+ /* Flash the adapter with the new firmware */
+ status = vxge_hw_flash_fw(hldev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: Upgrade commit failed '%s'.",
+ VXGE_DRIVER_NAME, fw_name);
+ ret = -EIO;
+ goto out;
+ }
+
+ printk(KERN_NOTICE "Upgrade of firmware successful! Adapter must be "
+ "hard reset before using, thus requiring a system reboot or a "
+ "hotplug event.\n");
+
+out:
+ return ret;
+}
+
+static int vxge_probe_fw_update(struct vxgedev *vdev)
+{
+ u32 maj, min, bld;
+ int ret, gpxe = 0;
+ char *fw_name;
+
+ maj = vdev->config.device_hw_info.fw_version.major;
+ min = vdev->config.device_hw_info.fw_version.minor;
+ bld = vdev->config.device_hw_info.fw_version.build;
+
+ if (VXGE_FW_VER(maj, min, bld) == VXGE_CERT_FW_VER)
+ return 0;
+
+ /* Ignore the build number when determining if the current firmware is
+ * "too new" to load the driver
+ */
+ if (VXGE_FW_VER(maj, min, 0) > VXGE_CERT_FW_VER) {
+ vxge_debug_init(VXGE_ERR, "%s: Firmware newer than last known "
+ "version, unable to load driver\n",
+ VXGE_DRIVER_NAME);
+ return -EINVAL;
+ }
+
+ /* Firmware 1.4.4 and older cannot be upgraded, and is too ancient to
+ * work with this driver.
+ */
+ if (VXGE_FW_VER(maj, min, bld) <= VXGE_FW_DEAD_VER) {
+ vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d cannot be "
+ "upgraded\n", VXGE_DRIVER_NAME, maj, min, bld);
+ return -EINVAL;
+ }
+
+ /* If file not specified, determine gPXE or not */
+ if (VXGE_FW_VER(maj, min, bld) >= VXGE_EPROM_FW_VER) {
+ int i;
+ for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++)
+ if (vdev->devh->eprom_versions[i]) {
+ gpxe = 1;
+ break;
+ }
+ }
+ if (gpxe)
+ fw_name = "vxge/X3fw-pxe.ncf";
+ else
+ fw_name = "vxge/X3fw.ncf";
+
+ ret = vxge_fw_upgrade(vdev, fw_name, 0);
+ /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on
+ * probe, so ignore them
+ */
+ if (ret != -EINVAL && ret != -ENOENT)
+ return -EIO;
+ else
+ ret = 0;
+
+ if (VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, VXGE_CERT_FW_VER_MINOR, 0) >
+ VXGE_FW_VER(maj, min, 0)) {
+ vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d is too old to"
+ " be used with this driver.\n"
+ "Please get the latest version from "
+ "ftp://ftp.s2io.com/pub/X3100-Drivers/FIRMWARE",
+ VXGE_DRIVER_NAME, maj, min, bld);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int __devinit is_sriov_initialized(struct pci_dev *pdev)
+{
+ int pos;
+ u16 ctrl;
+
+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+ if (pos) {
+ pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &ctrl);
+ if (ctrl & PCI_SRIOV_CTRL_VFE)
+ return 1;
+ }
+ return 0;
+}
+
/**
* vxge_probe
* @pdev : structure containing the PCI related information of the device.
@@ -3928,7 +4219,7 @@ static inline u32 vxge_get_num_vfs(u64 function_mode)
static int __devinit
vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
{
- struct __vxge_hw_device *hldev;
+ struct __vxge_hw_device *hldev;
enum vxge_hw_status status;
int ret;
int high_dma = 0;
@@ -3951,9 +4242,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
attr.pdev = pdev;
/* In SRIOV-17 mode, functions of the same adapter
- * can be deployed on different buses */
- if ((!pdev->is_virtfn) && ((bus != pdev->bus->number) ||
- (device != PCI_SLOT(pdev->devfn))))
+ * can be deployed on different buses
+ */
+ if (((bus != pdev->bus->number) || (device != PCI_SLOT(pdev->devfn))) &&
+ !pdev->is_virtfn)
new_device = 1;
bus = pdev->bus->number;
@@ -3971,6 +4263,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
driver_config->config_dev_cnt = 0;
driver_config->total_dev_cnt = 0;
}
+
/* Now making the CPU based no of vpath calculation
* applicable for individual functions as well.
*/
@@ -3993,11 +4286,11 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit0;
}
- ll_config = kzalloc(sizeof(*ll_config), GFP_KERNEL);
+ ll_config = kzalloc(sizeof(struct vxge_config), GFP_KERNEL);
if (!ll_config) {
ret = -ENOMEM;
vxge_debug_init(VXGE_ERR,
- "ll_config : malloc failed %s %d",
+ "device_config : malloc failed %s %d",
__FILE__, __LINE__);
goto _exit0;
}
@@ -4041,7 +4334,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit1;
}
- if (pci_request_regions(pdev, VXGE_DRIVER_NAME)) {
+ if (pci_request_region(pdev, 0, VXGE_DRIVER_NAME)) {
vxge_debug_init(VXGE_ERR,
"%s : request regions failed", __func__);
ret = -ENODEV;
@@ -4072,16 +4365,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit3;
}
- if (ll_config->device_hw_info.fw_version.major !=
- VXGE_DRIVER_FW_VERSION_MAJOR) {
- vxge_debug_init(VXGE_ERR,
- "%s: Incorrect firmware version."
- "Please upgrade the firmware to version 1.x.x",
- VXGE_DRIVER_NAME);
- ret = -EINVAL;
- goto _exit3;
- }
-
vpath_mask = ll_config->device_hw_info.vpath_mask;
if (vpath_mask == 0) {
vxge_debug_ll_config(VXGE_TRACE,
@@ -4110,14 +4393,13 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
num_vfs = vxge_get_num_vfs(function_mode) - 1;
/* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */
- if (is_sriov(function_mode) && (max_config_dev > 1) &&
- (ll_config->intr_type != INTA) &&
- (is_privileged == VXGE_HW_OK)) {
- ret = pci_enable_sriov(pdev, ((max_config_dev - 1) < num_vfs)
- ? (max_config_dev - 1) : num_vfs);
+ if (is_sriov(function_mode) && !is_sriov_initialized(pdev) &&
+ (ll_config->intr_type != INTA)) {
+ ret = pci_enable_sriov(pdev, num_vfs);
if (ret)
vxge_debug_ll_config(VXGE_ERR,
"Failed in enabling SRIOV mode: %d\n", ret);
+ /* No need to fail out, as an error here is non-fatal */
}
/*
@@ -4145,11 +4427,37 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit3;
}
+ if (VXGE_FW_VER(ll_config->device_hw_info.fw_version.major,
+ ll_config->device_hw_info.fw_version.minor,
+ ll_config->device_hw_info.fw_version.build) >=
+ VXGE_EPROM_FW_VER) {
+ struct eprom_image img[VXGE_HW_MAX_ROM_IMAGES];
+
+ status = vxge_hw_vpath_eprom_img_ver_get(hldev, img);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: Reading of EPROM failed",
+ VXGE_DRIVER_NAME);
+ /* This is a non-fatal error, continue */
+ }
+
+ for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) {
+ hldev->eprom_versions[i] = img[i].version;
+ if (!img[i].is_valid)
+ break;
+ vxge_debug_init(VXGE_TRACE, "%s: EPROM %d, version "
+ "%d.%d.%d.%d\n", VXGE_DRIVER_NAME, i,
+ VXGE_EPROM_IMG_MAJOR(img[i].version),
+ VXGE_EPROM_IMG_MINOR(img[i].version),
+ VXGE_EPROM_IMG_FIX(img[i].version),
+ VXGE_EPROM_IMG_BUILD(img[i].version));
+ }
+ }
+
/* if FCS stripping is not disabled in MAC fail driver load */
- if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) {
- vxge_debug_init(VXGE_ERR,
- "%s: FCS stripping is not disabled in MAC"
- " failing driver load", VXGE_DRIVER_NAME);
+ status = vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR, "%s: FCS stripping is enabled in MAC"
+ " failing driver load", VXGE_DRIVER_NAME);
ret = -EINVAL;
goto _exit4;
}
@@ -4163,28 +4471,32 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
ll_config->addr_learn_en = addr_learn_en;
ll_config->rth_algorithm = RTH_ALG_JENKINS;
- ll_config->rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4;
- ll_config->rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE;
- ll_config->rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
- ll_config->rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
- ll_config->rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
- ll_config->rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config->rth_hash_type_tcpipv4 = 1;
+ ll_config->rth_hash_type_ipv4 = 0;
+ ll_config->rth_hash_type_tcpipv6 = 0;
+ ll_config->rth_hash_type_ipv6 = 0;
+ ll_config->rth_hash_type_tcpipv6ex = 0;
+ ll_config->rth_hash_type_ipv6ex = 0;
ll_config->rth_bkt_sz = RTH_BUCKET_SIZE;
ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
- if (vxge_device_register(hldev, ll_config, high_dma, no_of_vpath,
- &vdev)) {
+ ret = vxge_device_register(hldev, ll_config, high_dma, no_of_vpath,
+ &vdev);
+ if (ret) {
ret = -EINVAL;
goto _exit4;
}
+ ret = vxge_probe_fw_update(vdev);
+ if (ret)
+ goto _exit5;
+
vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL);
VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
vxge_hw_device_trace_level_get(hldev));
/* set private HW device info */
- hldev->ndev = vdev->ndev;
vdev->mtu = VXGE_HW_DEFAULT_MTU;
vdev->bar0 = attr.bar0;
vdev->max_vpath_supported = max_vpath_supported;
@@ -4278,15 +4590,13 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Copy the station mac address to the list */
for (i = 0; i < vdev->no_of_vpath; i++) {
- entry = (struct vxge_mac_addrs *)
- kzalloc(sizeof(struct vxge_mac_addrs),
- GFP_KERNEL);
+ entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_KERNEL);
if (NULL == entry) {
vxge_debug_init(VXGE_ERR,
"%s: mac_addr_list : memory allocation failed",
vdev->ndev->name);
ret = -EPERM;
- goto _exit5;
+ goto _exit6;
}
macaddr = (u8 *)&entry->macaddr;
memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN);
@@ -4326,10 +4636,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
kfree(ll_config);
return 0;
-_exit5:
+_exit6:
for (i = 0; i < vdev->no_of_vpath; i++)
vxge_free_mac_add_list(&vdev->vpaths[i]);
-
+_exit5:
vxge_device_unregister(hldev);
_exit4:
pci_disable_sriov(pdev);
@@ -4337,7 +4647,7 @@ _exit4:
_exit3:
iounmap(attr.bar0);
_exit2:
- pci_release_regions(pdev);
+ pci_release_region(pdev, 0);
_exit1:
pci_disable_device(pdev);
_exit0:
@@ -4354,34 +4664,25 @@ _exit0:
* Description: This function is called by the Pci subsystem to release a
* PCI device and free up all resource held up by the device.
*/
-static void __devexit
-vxge_remove(struct pci_dev *pdev)
+static void __devexit vxge_remove(struct pci_dev *pdev)
{
- struct __vxge_hw_device *hldev;
+ struct __vxge_hw_device *hldev;
struct vxgedev *vdev = NULL;
struct net_device *dev;
int i = 0;
-#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
- (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
- u32 level_trace;
-#endif
- hldev = (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ hldev = pci_get_drvdata(pdev);
if (hldev == NULL)
return;
+
dev = hldev->ndev;
vdev = netdev_priv(dev);
-#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
- (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
- level_trace = vdev->level_trace;
-#endif
- vxge_debug_entryexit(level_trace,
- "%s:%d", __func__, __LINE__);
+ vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__);
- vxge_debug_init(level_trace,
- "%s : removing PCI device...", __func__);
+ vxge_debug_init(vdev->level_trace, "%s : removing PCI device...",
+ __func__);
vxge_device_unregister(hldev);
for (i = 0; i < vdev->no_of_vpath; i++) {
@@ -4394,21 +4695,19 @@ vxge_remove(struct pci_dev *pdev)
iounmap(vdev->bar0);
- pci_disable_sriov(pdev);
-
/* we are safe to free it now */
free_netdev(dev);
- vxge_debug_init(level_trace,
- "%s:%d Device unregistered", __func__, __LINE__);
+ vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered",
+ __func__, __LINE__);
vxge_hw_device_terminate(hldev);
pci_disable_device(pdev);
- pci_release_regions(pdev);
+ pci_release_region(pdev, 0);
pci_set_drvdata(pdev, NULL);
- vxge_debug_entryexit(level_trace,
- "%s:%d Exiting...", __func__, __LINE__);
+ vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__,
+ __LINE__);
}
static struct pci_error_handlers vxge_err_handler = {
@@ -4444,6 +4743,10 @@ vxge_starter(void)
return -ENOMEM;
ret = pci_register_driver(&vxge_driver);
+ if (ret) {
+ kfree(driver_config);
+ goto err;
+ }
if (driver_config->config_dev_cnt &&
(driver_config->config_dev_cnt != driver_config->total_dev_cnt))
@@ -4451,10 +4754,7 @@ vxge_starter(void)
"%s: Configured %d of %d devices",
VXGE_DRIVER_NAME, driver_config->config_dev_cnt,
driver_config->total_dev_cnt);
-
- if (ret)
- kfree(driver_config);
-
+err:
return ret;
}
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index de64536cb7d0..5746fedc356f 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -29,6 +29,9 @@
#define PCI_DEVICE_ID_TITAN_WIN 0x5733
#define PCI_DEVICE_ID_TITAN_UNI 0x5833
+#define VXGE_HW_TITAN1_PCI_REVISION 1
+#define VXGE_HW_TITAN1A_PCI_REVISION 2
+
#define VXGE_USE_DEFAULT 0xffffffff
#define VXGE_HW_VPATH_MSIX_ACTIVE 4
#define VXGE_ALARM_MSIX_ID 2
@@ -53,11 +56,13 @@
#define VXGE_TTI_BTIMER_VAL 250000
-#define VXGE_TTI_LTIMER_VAL 1000
-#define VXGE_TTI_RTIMER_VAL 0
-#define VXGE_RTI_BTIMER_VAL 250
-#define VXGE_RTI_LTIMER_VAL 100
-#define VXGE_RTI_RTIMER_VAL 0
+#define VXGE_TTI_LTIMER_VAL 1000
+#define VXGE_T1A_TTI_LTIMER_VAL 80
+#define VXGE_TTI_RTIMER_VAL 0
+#define VXGE_T1A_TTI_RTIMER_VAL 400
+#define VXGE_RTI_BTIMER_VAL 250
+#define VXGE_RTI_LTIMER_VAL 100
+#define VXGE_RTI_RTIMER_VAL 0
#define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH
#define VXGE_ISR_POLLING_CNT 8
#define VXGE_MAX_CONFIG_DEV 0xFF
@@ -76,14 +81,32 @@
#define TTI_TX_UFC_B 40
#define TTI_TX_UFC_C 60
#define TTI_TX_UFC_D 100
+#define TTI_T1A_TX_UFC_A 30
+#define TTI_T1A_TX_UFC_B 80
+/* Slope - (max_mtu - min_mtu)/(max_mtu_ufc - min_mtu_ufc) */
+/* Slope - 93 */
+/* 60 - 9k Mtu, 140 - 1.5k mtu */
+#define TTI_T1A_TX_UFC_C(mtu) (60 + ((VXGE_HW_MAX_MTU - mtu) / 93))
+
+/* Slope - 37 */
+/* 100 - 9k Mtu, 300 - 1.5k mtu */
+#define TTI_T1A_TX_UFC_D(mtu) (100 + ((VXGE_HW_MAX_MTU - mtu) / 37))
+
+
+#define RTI_RX_URANGE_A 5
+#define RTI_RX_URANGE_B 15
+#define RTI_RX_URANGE_C 40
+#define RTI_T1A_RX_URANGE_A 1
+#define RTI_T1A_RX_URANGE_B 20
+#define RTI_T1A_RX_URANGE_C 50
+#define RTI_RX_UFC_A 1
+#define RTI_RX_UFC_B 5
+#define RTI_RX_UFC_C 10
+#define RTI_RX_UFC_D 15
+#define RTI_T1A_RX_UFC_B 20
+#define RTI_T1A_RX_UFC_C 50
+#define RTI_T1A_RX_UFC_D 60
-#define RTI_RX_URANGE_A 5
-#define RTI_RX_URANGE_B 15
-#define RTI_RX_URANGE_C 40
-#define RTI_RX_UFC_A 1
-#define RTI_RX_UFC_B 5
-#define RTI_RX_UFC_C 10
-#define RTI_RX_UFC_D 15
/* Milli secs timer period */
#define VXGE_TIMER_DELAY 10000
@@ -145,15 +168,15 @@ struct vxge_config {
int addr_learn_en;
- int rth_steering;
- int rth_algorithm;
- int rth_hash_type_tcpipv4;
- int rth_hash_type_ipv4;
- int rth_hash_type_tcpipv6;
- int rth_hash_type_ipv6;
- int rth_hash_type_tcpipv6ex;
- int rth_hash_type_ipv6ex;
- int rth_bkt_sz;
+ u32 rth_steering:2,
+ rth_algorithm:2,
+ rth_hash_type_tcpipv4:1,
+ rth_hash_type_ipv4:1,
+ rth_hash_type_tcpipv6:1,
+ rth_hash_type_ipv6:1,
+ rth_hash_type_tcpipv6ex:1,
+ rth_hash_type_ipv6ex:1,
+ rth_bkt_sz:8;
int rth_jhash_golden_ratio;
int tx_steering_type;
int fifo_indicate_max_pkts;
@@ -248,8 +271,9 @@ struct vxge_ring {
*/
int driver_id;
- /* copy of the flag indicating whether rx_csum is to be used */
- u32 rx_csum;
+ /* copy of the flag indicating whether rx_csum is to be used */
+ u32 rx_csum:1,
+ rx_hwts:1;
int pkts_processed;
int budget;
@@ -281,8 +305,8 @@ struct vxge_vpath {
int is_configured;
int is_open;
struct vxgedev *vdev;
- u8 (macaddr)[ETH_ALEN];
- u8 (macmask)[ETH_ALEN];
+ u8 macaddr[ETH_ALEN];
+ u8 macmask[ETH_ALEN];
#define VXGE_MAX_LEARN_MAC_ADDR_CNT 2048
/* mac addresses currently programmed into NIC */
@@ -327,7 +351,9 @@ struct vxgedev {
u16 all_multi_flg;
/* A flag indicating whether rx_csum is to be used or not. */
- u32 rx_csum;
+ u32 rx_csum:1,
+ rx_hwts:1,
+ titan1:1;
struct vxge_msix_entry *vxge_entries;
struct msix_entry *entries;
@@ -369,6 +395,7 @@ struct vxgedev {
u32 level_err;
u32 level_trace;
char fw_version[VXGE_HW_FW_STRLEN];
+ struct work_struct reset_task;
};
struct vxge_rx_priv {
@@ -387,8 +414,6 @@ struct vxge_tx_priv {
static int p = val; \
module_param(p, int, 0)
-#define vxge_os_bug(fmt...) { printk(fmt); BUG(); }
-
#define vxge_os_timer(timer, handle, arg, exp) do { \
init_timer(&timer); \
timer.function = handle; \
@@ -396,7 +421,10 @@ struct vxge_tx_priv {
mod_timer(&timer, (jiffies + exp)); \
} while (0);
-extern void vxge_initialize_ethtool_ops(struct net_device *ndev);
+void vxge_initialize_ethtool_ops(struct net_device *ndev);
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
+int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override);
+
/**
* #define VXGE_DEBUG_INIT: debug for initialization functions
* #define VXGE_DEBUG_TX : debug transmit related functions
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
index 3dd5c9615ef9..3e658b175947 100644
--- a/drivers/net/vxge/vxge-reg.h
+++ b/drivers/net/vxge/vxge-reg.h
@@ -49,6 +49,33 @@
#define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17
#define VXGE_HW_TITAN_VPATH_REG_SPACES 17
+#define VXGE_HW_FW_API_GET_EPROM_REV 31
+
+#define VXGE_EPROM_IMG_MAJOR(val) (u32) vxge_bVALn(val, 48, 4)
+#define VXGE_EPROM_IMG_MINOR(val) (u32) vxge_bVALn(val, 52, 4)
+#define VXGE_EPROM_IMG_FIX(val) (u32) vxge_bVALn(val, 56, 4)
+#define VXGE_EPROM_IMG_BUILD(val) (u32) vxge_bVALn(val, 60, 4)
+
+#define VXGE_HW_GET_EPROM_IMAGE_INDEX(val) vxge_bVALn(val, 16, 8)
+#define VXGE_HW_GET_EPROM_IMAGE_VALID(val) vxge_bVALn(val, 31, 1)
+#define VXGE_HW_GET_EPROM_IMAGE_TYPE(val) vxge_bVALn(val, 40, 8)
+#define VXGE_HW_GET_EPROM_IMAGE_REV(val) vxge_bVALn(val, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(val) vxge_vBIT(val, 16, 8)
+
+#define VXGE_HW_FW_API_GET_FUNC_MODE 29
+#define VXGE_HW_GET_FUNC_MODE_VAL(val) (val & 0xFF)
+
+#define VXGE_HW_FW_UPGRADE_MEMO 13
+#define VXGE_HW_FW_UPGRADE_ACTION 16
+#define VXGE_HW_FW_UPGRADE_OFFSET_START 2
+#define VXGE_HW_FW_UPGRADE_OFFSET_SEND 3
+#define VXGE_HW_FW_UPGRADE_OFFSET_COMMIT 4
+#define VXGE_HW_FW_UPGRADE_OFFSET_READ 5
+
+#define VXGE_HW_FW_UPGRADE_BLK_SIZE 16
+#define VXGE_HW_UPGRADE_GET_RET_ERR_CODE(val) (val & 0xff)
+#define VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(val) ((val >> 8) & 0xff)
+
#define VXGE_HW_ASIC_MODE_RESERVED 0
#define VXGE_HW_ASIC_MODE_NO_IOV 1
#define VXGE_HW_ASIC_MODE_SR_IOV 2
@@ -165,13 +192,13 @@
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5
-#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6
+#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11
-#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12
+#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12
#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13
#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
@@ -437,6 +464,7 @@
#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \
vxge_bVALn(bits, 48, 16)
#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(bits) vxge_bVALn(bits, 0, 8)
#define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\
vxge_bVALn(bits, 0, 18)
@@ -3998,6 +4026,7 @@ struct vxge_hw_vpath_reg {
#define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9)
#define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9)
#define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9)
+#define VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val) vxge_bVALn(val, 36, 9)
/*0x00a78*/ u64 prc_cfg7;
#define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2)
#define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11)
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index 4bdb611a6842..4c10d6c4075f 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -17,13 +17,6 @@
#include "vxge-config.h"
#include "vxge-main.h"
-static enum vxge_hw_status
-__vxge_hw_device_handle_error(struct __vxge_hw_device *hldev,
- u32 vp_id, enum vxge_hw_event type);
-static enum vxge_hw_status
-__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath,
- u32 skip_alarms);
-
/*
* vxge_hw_vpath_intr_enable - Enable vpath interrupts.
* @vp: Virtual Path handle.
@@ -419,6 +412,384 @@ void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev)
}
/**
+ * __vxge_hw_device_handle_error - Handle error
+ * @hldev: HW device
+ * @vp_id: Vpath Id
+ * @type: Error type. Please see enum vxge_hw_event{}
+ *
+ * Handle error.
+ */
+static enum vxge_hw_status
+__vxge_hw_device_handle_error(struct __vxge_hw_device *hldev, u32 vp_id,
+ enum vxge_hw_event type)
+{
+ switch (type) {
+ case VXGE_HW_EVENT_UNKNOWN:
+ break;
+ case VXGE_HW_EVENT_RESET_START:
+ case VXGE_HW_EVENT_RESET_COMPLETE:
+ case VXGE_HW_EVENT_LINK_DOWN:
+ case VXGE_HW_EVENT_LINK_UP:
+ goto out;
+ case VXGE_HW_EVENT_ALARM_CLEARED:
+ goto out;
+ case VXGE_HW_EVENT_ECCERR:
+ case VXGE_HW_EVENT_MRPCIM_ECCERR:
+ goto out;
+ case VXGE_HW_EVENT_FIFO_ERR:
+ case VXGE_HW_EVENT_VPATH_ERR:
+ case VXGE_HW_EVENT_CRITICAL_ERR:
+ case VXGE_HW_EVENT_SERR:
+ break;
+ case VXGE_HW_EVENT_SRPCIM_SERR:
+ case VXGE_HW_EVENT_MRPCIM_SERR:
+ goto out;
+ case VXGE_HW_EVENT_SLOT_FREEZE:
+ break;
+ default:
+ vxge_assert(0);
+ goto out;
+ }
+
+ /* notify driver */
+ if (hldev->uld_callbacks.crit_err)
+ hldev->uld_callbacks.crit_err(
+ (struct __vxge_hw_device *)hldev,
+ type, vp_id);
+out:
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_handle_link_down_ind
+ * @hldev: HW device handle.
+ *
+ * Link down indication handler. The function is invoked by HW when
+ * Titan indicates that the link is down.
+ */
+static enum vxge_hw_status
+__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev)
+{
+ /*
+ * If the previous link state is not down, return.
+ */
+ if (hldev->link_state == VXGE_HW_LINK_DOWN)
+ goto exit;
+
+ hldev->link_state = VXGE_HW_LINK_DOWN;
+
+ /* notify driver */
+ if (hldev->uld_callbacks.link_down)
+ hldev->uld_callbacks.link_down(hldev);
+exit:
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_handle_link_up_ind
+ * @hldev: HW device handle.
+ *
+ * Link up indication handler. The function is invoked by HW when
+ * Titan indicates that the link is up for programmable amount of time.
+ */
+static enum vxge_hw_status
+__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev)
+{
+ /*
+ * If the previous link state is not down, return.
+ */
+ if (hldev->link_state == VXGE_HW_LINK_UP)
+ goto exit;
+
+ hldev->link_state = VXGE_HW_LINK_UP;
+
+ /* notify driver */
+ if (hldev->uld_callbacks.link_up)
+ hldev->uld_callbacks.link_up(hldev);
+exit:
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_vpath_alarm_process - Process Alarms.
+ * @vpath: Virtual Path.
+ * @skip_alarms: Do not clear the alarms
+ *
+ * Process vpath alarms.
+ *
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath,
+ u32 skip_alarms)
+{
+ u64 val64;
+ u64 alarm_status;
+ u64 pic_status;
+ struct __vxge_hw_device *hldev = NULL;
+ enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN;
+ u64 mask64;
+ struct vxge_hw_vpath_stats_sw_info *sw_stats;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath == NULL) {
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+ alarm_event);
+ goto out2;
+ }
+
+ hldev = vpath->hldev;
+ vp_reg = vpath->vp_reg;
+ alarm_status = readq(&vp_reg->vpath_general_int_status);
+
+ if (alarm_status == VXGE_HW_ALL_FOXES) {
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE,
+ alarm_event);
+ goto out;
+ }
+
+ sw_stats = vpath->sw_stats;
+
+ if (alarm_status & ~(
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) {
+ sw_stats->error_stats.unknown_alarms++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+ alarm_event);
+ goto out;
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) {
+
+ val64 = readq(&vp_reg->xgmac_vp_int_status);
+
+ if (val64 &
+ VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) {
+
+ val64 = readq(&vp_reg->asic_ntwk_vp_err_reg);
+
+ if (((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) ||
+ ((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
+ ))) {
+ sw_stats->error_stats.network_sustained_fault++;
+
+ writeq(
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT,
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+ __vxge_hw_device_handle_link_down_ind(hldev);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_LINK_DOWN, alarm_event);
+ }
+
+ if (((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) ||
+ ((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
+ ))) {
+
+ sw_stats->error_stats.network_sustained_ok++;
+
+ writeq(
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK,
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+ __vxge_hw_device_handle_link_up_ind(hldev);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_LINK_UP, alarm_event);
+ }
+
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->asic_ntwk_vp_err_reg);
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED, alarm_event);
+
+ if (skip_alarms)
+ return VXGE_HW_OK;
+ }
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) {
+
+ pic_status = readq(&vp_reg->vpath_ppif_int_status);
+
+ if (pic_status &
+ VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) {
+
+ val64 = readq(&vp_reg->general_errors_reg);
+ mask64 = readq(&vp_reg->general_errors_mask);
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) &
+ ~mask64) {
+ sw_stats->error_stats.ini_serr_det++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_SERR, alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) &
+ ~mask64) {
+ sw_stats->error_stats.dblgen_fifo0_overflow++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR, alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) &
+ ~mask64)
+ sw_stats->error_stats.statsb_pif_chain_error++;
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) &
+ ~mask64)
+ sw_stats->error_stats.statsb_drop_timeout++;
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) &
+ ~mask64)
+ sw_stats->error_stats.target_illegal_access++;
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->general_errors_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+
+ if (pic_status &
+ VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) {
+
+ val64 = readq(&vp_reg->kdfcctl_errors_reg);
+ mask64 = readq(&vp_reg->kdfcctl_errors_mask);
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_overwrite++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_poison++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_dma_error++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->kdfcctl_errors_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) {
+
+ val64 = readq(&vp_reg->wrdma_alarm_status);
+
+ if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) {
+
+ val64 = readq(&vp_reg->prc_alarm_reg);
+ mask64 = readq(&vp_reg->prc_alarm_mask);
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)&
+ ~mask64)
+ sw_stats->error_stats.prc_ring_bumps++;
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) &
+ ~mask64) {
+ sw_stats->error_stats.prc_rxdcm_sc_err++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT)
+ & ~mask64) {
+ sw_stats->error_stats.prc_rxdcm_sc_abort++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR)
+ & ~mask64) {
+ sw_stats->error_stats.prc_quanta_size_err++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->prc_alarm_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+ }
+out:
+ hldev->stats.sw_dev_err_stats.vpath_alarms++;
+out2:
+ if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
+ (alarm_event == VXGE_HW_EVENT_UNKNOWN))
+ return VXGE_HW_OK;
+
+ __vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event);
+
+ if (alarm_event == VXGE_HW_EVENT_SERR)
+ return VXGE_HW_ERR_CRITICAL;
+
+ return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ?
+ VXGE_HW_ERR_SLOT_FREEZE :
+ (alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO :
+ VXGE_HW_ERR_VPATH;
+}
+
+/**
* vxge_hw_device_begin_irq - Begin IRQ processing.
* @hldev: HW device handle.
* @skip_alarms: Do not clear the alarms
@@ -513,108 +884,6 @@ exit:
return ret;
}
-/*
- * __vxge_hw_device_handle_link_up_ind
- * @hldev: HW device handle.
- *
- * Link up indication handler. The function is invoked by HW when
- * Titan indicates that the link is up for programmable amount of time.
- */
-static enum vxge_hw_status
-__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev)
-{
- /*
- * If the previous link state is not down, return.
- */
- if (hldev->link_state == VXGE_HW_LINK_UP)
- goto exit;
-
- hldev->link_state = VXGE_HW_LINK_UP;
-
- /* notify driver */
- if (hldev->uld_callbacks.link_up)
- hldev->uld_callbacks.link_up(hldev);
-exit:
- return VXGE_HW_OK;
-}
-
-/*
- * __vxge_hw_device_handle_link_down_ind
- * @hldev: HW device handle.
- *
- * Link down indication handler. The function is invoked by HW when
- * Titan indicates that the link is down.
- */
-static enum vxge_hw_status
-__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev)
-{
- /*
- * If the previous link state is not down, return.
- */
- if (hldev->link_state == VXGE_HW_LINK_DOWN)
- goto exit;
-
- hldev->link_state = VXGE_HW_LINK_DOWN;
-
- /* notify driver */
- if (hldev->uld_callbacks.link_down)
- hldev->uld_callbacks.link_down(hldev);
-exit:
- return VXGE_HW_OK;
-}
-
-/**
- * __vxge_hw_device_handle_error - Handle error
- * @hldev: HW device
- * @vp_id: Vpath Id
- * @type: Error type. Please see enum vxge_hw_event{}
- *
- * Handle error.
- */
-static enum vxge_hw_status
-__vxge_hw_device_handle_error(
- struct __vxge_hw_device *hldev,
- u32 vp_id,
- enum vxge_hw_event type)
-{
- switch (type) {
- case VXGE_HW_EVENT_UNKNOWN:
- break;
- case VXGE_HW_EVENT_RESET_START:
- case VXGE_HW_EVENT_RESET_COMPLETE:
- case VXGE_HW_EVENT_LINK_DOWN:
- case VXGE_HW_EVENT_LINK_UP:
- goto out;
- case VXGE_HW_EVENT_ALARM_CLEARED:
- goto out;
- case VXGE_HW_EVENT_ECCERR:
- case VXGE_HW_EVENT_MRPCIM_ECCERR:
- goto out;
- case VXGE_HW_EVENT_FIFO_ERR:
- case VXGE_HW_EVENT_VPATH_ERR:
- case VXGE_HW_EVENT_CRITICAL_ERR:
- case VXGE_HW_EVENT_SERR:
- break;
- case VXGE_HW_EVENT_SRPCIM_SERR:
- case VXGE_HW_EVENT_MRPCIM_SERR:
- goto out;
- case VXGE_HW_EVENT_SLOT_FREEZE:
- break;
- default:
- vxge_assert(0);
- goto out;
- }
-
- /* notify driver */
- if (hldev->uld_callbacks.crit_err)
- hldev->uld_callbacks.crit_err(
- (struct __vxge_hw_device *)hldev,
- type, vp_id);
-out:
-
- return VXGE_HW_OK;
-}
-
/**
* vxge_hw_device_clear_tx_rx - Acknowledge (that is, clear) the
* condition that has caused the Tx and RX interrupt.
@@ -699,8 +968,8 @@ _alloc_after_swap:
* Posts a dtr to work array.
*
*/
-static void vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel,
- void *dtrh)
+static void
+vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh)
{
vxge_assert(channel->work_arr[channel->post_index] == NULL);
@@ -911,10 +1180,6 @@ void vxge_hw_ring_rxd_post(struct __vxge_hw_ring *ring, void *rxdh)
*/
void vxge_hw_ring_rxd_post_post_wmb(struct __vxge_hw_ring *ring, void *rxdh)
{
- struct __vxge_hw_channel *channel;
-
- channel = &ring->channel;
-
wmb();
vxge_hw_ring_rxd_post_post(ring, rxdh);
}
@@ -975,7 +1240,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_next_completed(
*t_code = (u8)VXGE_HW_RING_RXD_T_CODE_GET(control_0);
/* check whether it is not the end */
- if (!own || ((*t_code == VXGE_HW_RING_T_CODE_FRM_DROP) && own)) {
+ if (!own || *t_code == VXGE_HW_RING_T_CODE_FRM_DROP) {
vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control !=
0);
@@ -1868,284 +2133,6 @@ exit:
}
/*
- * __vxge_hw_vpath_alarm_process - Process Alarms.
- * @vpath: Virtual Path.
- * @skip_alarms: Do not clear the alarms
- *
- * Process vpath alarms.
- *
- */
-static enum vxge_hw_status
-__vxge_hw_vpath_alarm_process(struct __vxge_hw_virtualpath *vpath,
- u32 skip_alarms)
-{
- u64 val64;
- u64 alarm_status;
- u64 pic_status;
- struct __vxge_hw_device *hldev = NULL;
- enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN;
- u64 mask64;
- struct vxge_hw_vpath_stats_sw_info *sw_stats;
- struct vxge_hw_vpath_reg __iomem *vp_reg;
-
- if (vpath == NULL) {
- alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
- alarm_event);
- goto out2;
- }
-
- hldev = vpath->hldev;
- vp_reg = vpath->vp_reg;
- alarm_status = readq(&vp_reg->vpath_general_int_status);
-
- if (alarm_status == VXGE_HW_ALL_FOXES) {
- alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE,
- alarm_event);
- goto out;
- }
-
- sw_stats = vpath->sw_stats;
-
- if (alarm_status & ~(
- VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT |
- VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT |
- VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT |
- VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) {
- sw_stats->error_stats.unknown_alarms++;
-
- alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
- alarm_event);
- goto out;
- }
-
- if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) {
-
- val64 = readq(&vp_reg->xgmac_vp_int_status);
-
- if (val64 &
- VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) {
-
- val64 = readq(&vp_reg->asic_ntwk_vp_err_reg);
-
- if (((val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) &&
- (!(val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) ||
- ((val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) &&
- (!(val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
- ))) {
- sw_stats->error_stats.network_sustained_fault++;
-
- writeq(
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT,
- &vp_reg->asic_ntwk_vp_err_mask);
-
- __vxge_hw_device_handle_link_down_ind(hldev);
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_LINK_DOWN, alarm_event);
- }
-
- if (((val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) &&
- (!(val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) ||
- ((val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) &&
- (!(val64 &
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
- ))) {
-
- sw_stats->error_stats.network_sustained_ok++;
-
- writeq(
- VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK,
- &vp_reg->asic_ntwk_vp_err_mask);
-
- __vxge_hw_device_handle_link_up_ind(hldev);
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_LINK_UP, alarm_event);
- }
-
- writeq(VXGE_HW_INTR_MASK_ALL,
- &vp_reg->asic_ntwk_vp_err_reg);
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_ALARM_CLEARED, alarm_event);
-
- if (skip_alarms)
- return VXGE_HW_OK;
- }
- }
-
- if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) {
-
- pic_status = readq(&vp_reg->vpath_ppif_int_status);
-
- if (pic_status &
- VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) {
-
- val64 = readq(&vp_reg->general_errors_reg);
- mask64 = readq(&vp_reg->general_errors_mask);
-
- if ((val64 &
- VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) &
- ~mask64) {
- sw_stats->error_stats.ini_serr_det++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_SERR, alarm_event);
- }
-
- if ((val64 &
- VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) &
- ~mask64) {
- sw_stats->error_stats.dblgen_fifo0_overflow++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_FIFO_ERR, alarm_event);
- }
-
- if ((val64 &
- VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) &
- ~mask64)
- sw_stats->error_stats.statsb_pif_chain_error++;
-
- if ((val64 &
- VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) &
- ~mask64)
- sw_stats->error_stats.statsb_drop_timeout++;
-
- if ((val64 &
- VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) &
- ~mask64)
- sw_stats->error_stats.target_illegal_access++;
-
- if (!skip_alarms) {
- writeq(VXGE_HW_INTR_MASK_ALL,
- &vp_reg->general_errors_reg);
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_ALARM_CLEARED,
- alarm_event);
- }
- }
-
- if (pic_status &
- VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) {
-
- val64 = readq(&vp_reg->kdfcctl_errors_reg);
- mask64 = readq(&vp_reg->kdfcctl_errors_mask);
-
- if ((val64 &
- VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) &
- ~mask64) {
- sw_stats->error_stats.kdfcctl_fifo0_overwrite++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_FIFO_ERR,
- alarm_event);
- }
-
- if ((val64 &
- VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) &
- ~mask64) {
- sw_stats->error_stats.kdfcctl_fifo0_poison++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_FIFO_ERR,
- alarm_event);
- }
-
- if ((val64 &
- VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) &
- ~mask64) {
- sw_stats->error_stats.kdfcctl_fifo0_dma_error++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_FIFO_ERR,
- alarm_event);
- }
-
- if (!skip_alarms) {
- writeq(VXGE_HW_INTR_MASK_ALL,
- &vp_reg->kdfcctl_errors_reg);
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_ALARM_CLEARED,
- alarm_event);
- }
- }
-
- }
-
- if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) {
-
- val64 = readq(&vp_reg->wrdma_alarm_status);
-
- if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) {
-
- val64 = readq(&vp_reg->prc_alarm_reg);
- mask64 = readq(&vp_reg->prc_alarm_mask);
-
- if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)&
- ~mask64)
- sw_stats->error_stats.prc_ring_bumps++;
-
- if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) &
- ~mask64) {
- sw_stats->error_stats.prc_rxdcm_sc_err++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_VPATH_ERR,
- alarm_event);
- }
-
- if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT)
- & ~mask64) {
- sw_stats->error_stats.prc_rxdcm_sc_abort++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_VPATH_ERR,
- alarm_event);
- }
-
- if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR)
- & ~mask64) {
- sw_stats->error_stats.prc_quanta_size_err++;
-
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_VPATH_ERR,
- alarm_event);
- }
-
- if (!skip_alarms) {
- writeq(VXGE_HW_INTR_MASK_ALL,
- &vp_reg->prc_alarm_reg);
- alarm_event = VXGE_HW_SET_LEVEL(
- VXGE_HW_EVENT_ALARM_CLEARED,
- alarm_event);
- }
- }
- }
-out:
- hldev->stats.sw_dev_err_stats.vpath_alarms++;
-out2:
- if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
- (alarm_event == VXGE_HW_EVENT_UNKNOWN))
- return VXGE_HW_OK;
-
- __vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event);
-
- if (alarm_event == VXGE_HW_EVENT_SERR)
- return VXGE_HW_ERR_CRITICAL;
-
- return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ?
- VXGE_HW_ERR_SLOT_FREEZE :
- (alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO :
- VXGE_HW_ERR_VPATH;
-}
-
-/*
* vxge_hw_vpath_alarm_process - Process Alarms.
* @vpath: Virtual Path.
* @skip_alarms: Do not clear the alarms
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
index 9890d4d596d0..8c3103fb6442 100644
--- a/drivers/net/vxge/vxge-traffic.h
+++ b/drivers/net/vxge/vxge-traffic.h
@@ -1904,34 +1904,6 @@ enum vxge_hw_ring_tcode {
VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF
};
-/**
- * enum enum vxge_hw_ring_hash_type - RTH hash types
- * @VXGE_HW_RING_HASH_TYPE_NONE: No Hash
- * @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4
- * @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4
- * @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4
- * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6
- * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6
- * @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6
- * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension
- * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension
- * @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension
- *
- * RTH hash types
- */
-enum vxge_hw_ring_hash_type {
- VXGE_HW_RING_HASH_TYPE_NONE = 0x0,
- VXGE_HW_RING_HASH_TYPE_TCP_IPV4 = 0x1,
- VXGE_HW_RING_HASH_TYPE_UDP_IPV4 = 0x2,
- VXGE_HW_RING_HASH_TYPE_IPV4 = 0x3,
- VXGE_HW_RING_HASH_TYPE_TCP_IPV6 = 0x4,
- VXGE_HW_RING_HASH_TYPE_UDP_IPV6 = 0x5,
- VXGE_HW_RING_HASH_TYPE_IPV6 = 0x6,
- VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX = 0x7,
- VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX = 0x8,
- VXGE_HW_RING_HASH_TYPE_IPV6_EX = 0x9
-};
-
enum vxge_hw_status vxge_hw_ring_rxd_reserve(
struct __vxge_hw_ring *ring_handle,
void **rxdh);
@@ -2109,10 +2081,6 @@ struct __vxge_hw_ring_rxd_priv {
#endif
};
-/* ========================= FIFO PRIVATE API ============================= */
-
-struct vxge_hw_fifo_attr;
-
struct vxge_hw_mempool_cbs {
void (*item_func_alloc)(
struct vxge_hw_mempool *mempoolh,
@@ -2186,27 +2154,27 @@ enum vxge_hw_vpath_mac_addr_add_mode {
enum vxge_hw_status
vxge_hw_vpath_mac_addr_add(
struct __vxge_hw_vpath_handle *vpath_handle,
- u8 (macaddr)[ETH_ALEN],
- u8 (macaddr_mask)[ETH_ALEN],
+ u8 *macaddr,
+ u8 *macaddr_mask,
enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode);
enum vxge_hw_status
vxge_hw_vpath_mac_addr_get(
struct __vxge_hw_vpath_handle *vpath_handle,
- u8 (macaddr)[ETH_ALEN],
- u8 (macaddr_mask)[ETH_ALEN]);
+ u8 *macaddr,
+ u8 *macaddr_mask);
enum vxge_hw_status
vxge_hw_vpath_mac_addr_get_next(
struct __vxge_hw_vpath_handle *vpath_handle,
- u8 (macaddr)[ETH_ALEN],
- u8 (macaddr_mask)[ETH_ALEN]);
+ u8 *macaddr,
+ u8 *macaddr_mask);
enum vxge_hw_status
vxge_hw_vpath_mac_addr_delete(
struct __vxge_hw_vpath_handle *vpath_handle,
- u8 (macaddr)[ETH_ALEN],
- u8 (macaddr_mask)[ETH_ALEN]);
+ u8 *macaddr,
+ u8 *macaddr_mask);
enum vxge_hw_status
vxge_hw_vpath_vid_add(
@@ -2313,6 +2281,7 @@ vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh);
int
vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel);
+
void
vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id);
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 53fefe137368..ad2f99b9bcf3 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -15,8 +15,35 @@
#define VXGE_VERSION_H
#define VXGE_VERSION_MAJOR "2"
-#define VXGE_VERSION_MINOR "0"
-#define VXGE_VERSION_FIX "9"
-#define VXGE_VERSION_BUILD "20840"
+#define VXGE_VERSION_MINOR "5"
+#define VXGE_VERSION_FIX "1"
+#define VXGE_VERSION_BUILD "22082"
#define VXGE_VERSION_FOR "k"
+
+#define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld))
+
+#define VXGE_DEAD_FW_VER_MAJOR 1
+#define VXGE_DEAD_FW_VER_MINOR 4
+#define VXGE_DEAD_FW_VER_BUILD 4
+
+#define VXGE_FW_DEAD_VER VXGE_FW_VER(VXGE_DEAD_FW_VER_MAJOR, \
+ VXGE_DEAD_FW_VER_MINOR, \
+ VXGE_DEAD_FW_VER_BUILD)
+
+#define VXGE_EPROM_FW_VER_MAJOR 1
+#define VXGE_EPROM_FW_VER_MINOR 6
+#define VXGE_EPROM_FW_VER_BUILD 1
+
+#define VXGE_EPROM_FW_VER VXGE_FW_VER(VXGE_EPROM_FW_VER_MAJOR, \
+ VXGE_EPROM_FW_VER_MINOR, \
+ VXGE_EPROM_FW_VER_BUILD)
+
+#define VXGE_CERT_FW_VER_MAJOR 1
+#define VXGE_CERT_FW_VER_MINOR 8
+#define VXGE_CERT_FW_VER_BUILD 1
+
+#define VXGE_CERT_FW_VER VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, \
+ VXGE_CERT_FW_VER_MINOR, \
+ VXGE_CERT_FW_VER_BUILD)
+
#endif
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index d45b08d1dbc9..34cff6ce6d27 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -1358,7 +1358,7 @@ static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return ret;
}
-static int dscc4_match(struct thingie *p, int value)
+static int dscc4_match(const struct thingie *p, int value)
{
int i;
@@ -1403,7 +1403,7 @@ done:
static int dscc4_encoding_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{
- struct thingie encoding[] = {
+ static const struct thingie encoding[] = {
{ ENCODING_NRZ, 0x00000000 },
{ ENCODING_NRZI, 0x00200000 },
{ ENCODING_FM_MARK, 0x00400000 },
@@ -1442,7 +1442,7 @@ static int dscc4_loopback_setting(struct dscc4_dev_priv *dpriv,
static int dscc4_crc_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{
- struct thingie crc[] = {
+ static const struct thingie crc[] = {
{ PARITY_CRC16_PR0_CCITT, 0x00000010 },
{ PARITY_CRC16_PR1_CCITT, 0x00000000 },
{ PARITY_CRC32_PR0_CCITT, 0x00000011 },
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index ea476cbd38b5..e305274f83fb 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port)
struct net_device *dev = port->netdev;
card_t* card = port->card;
u8 stat;
+ unsigned count = 0;
spin_lock(&port->lock);
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port)
dev->stats.tx_bytes += readw(&desc->len);
}
writeb(0, &desc->stat); /* Free descriptor */
+ count++;
port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
}
- netif_wake_queue(dev);
+ if (count)
+ netif_wake_queue(dev);
spin_unlock(&port->lock);
}
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index cf05504d9511..24297b274cd4 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -577,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
if (err)
return err;
/* Done. We have linked the TTY line to a channel. */
- return sl->dev->base_addr;
+ return 0;
}
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index f1549fff0edc..8831a3393ecf 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -275,7 +275,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr+WD_NIC_OFFSET;
if (dev->irq < 2) {
- int irqmap[] = {9,3,5,7,10,11,15,4};
+ static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4};
int reg1 = inb(ioaddr+1);
int reg4 = inb(ioaddr+4);
if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index cdedab46ba21..f0603327aafa 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -92,54 +92,6 @@ MODULE_PARM_DESC(barkers,
"signal; values are appended to a list--setting one value "
"as zero cleans the existing list and starts a new one.");
-static
-struct i2400m_work *__i2400m_work_setup(
- struct i2400m *i2400m, void (*fn)(struct work_struct *),
- gfp_t gfp_flags, const void *pl, size_t pl_size)
-{
- struct i2400m_work *iw;
-
- iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags);
- if (iw == NULL)
- return NULL;
- iw->i2400m = i2400m_get(i2400m);
- iw->pl_size = pl_size;
- memcpy(iw->pl, pl, pl_size);
- INIT_WORK(&iw->ws, fn);
- return iw;
-}
-
-
-/*
- * Schedule i2400m's specific work on the system's queue.
- *
- * Used for a few cases where we really need it; otherwise, identical
- * to i2400m_queue_work().
- *
- * Returns < 0 errno code on error, 1 if ok.
- *
- * If it returns zero, something really bad happened, as it means the
- * works struct was already queued, but we have just allocated it, so
- * it should not happen.
- */
-static int i2400m_schedule_work(struct i2400m *i2400m,
- void (*fn)(struct work_struct *), gfp_t gfp_flags,
- const void *pl, size_t pl_size)
-{
- int result;
- struct i2400m_work *iw;
-
- result = -ENOMEM;
- iw = __i2400m_work_setup(i2400m, fn, gfp_flags, pl, pl_size);
- if (iw != NULL) {
- result = schedule_work(&iw->ws);
- if (WARN_ON(result == 0))
- result = -ENXIO;
- }
- return result;
-}
-
-
/*
* WiMAX stack operation: relay a message from user space
*
@@ -648,17 +600,11 @@ EXPORT_SYMBOL_GPL(i2400m_post_reset);
static
void __i2400m_dev_reset_handle(struct work_struct *ws)
{
- int result;
- struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
- const char *reason;
- struct i2400m *i2400m = iw->i2400m;
+ struct i2400m *i2400m = container_of(ws, struct i2400m, reset_ws);
+ const char *reason = i2400m->reset_reason;
struct device *dev = i2400m_dev(i2400m);
struct i2400m_reset_ctx *ctx = i2400m->reset_ctx;
-
- if (WARN_ON(iw->pl_size != sizeof(reason)))
- reason = "SW BUG: reason n/a";
- else
- memcpy(&reason, iw->pl, sizeof(reason));
+ int result;
d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason);
@@ -733,8 +679,6 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
}
}
out:
- i2400m_put(i2400m);
- kfree(iw);
d_fnend(3, dev, "(ws %p i2400m %p reason %s) = void\n",
ws, i2400m, reason);
}
@@ -754,8 +698,8 @@ out:
*/
int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason)
{
- return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
- GFP_ATOMIC, &reason, sizeof(reason));
+ i2400m->reset_reason = reason;
+ return schedule_work(&i2400m->reset_ws);
}
EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
@@ -768,14 +712,9 @@ EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
static
void __i2400m_error_recovery(struct work_struct *ws)
{
- struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
- struct i2400m *i2400m = iw->i2400m;
+ struct i2400m *i2400m = container_of(ws, struct i2400m, recovery_ws);
i2400m_reset(i2400m, I2400M_RT_BUS);
-
- i2400m_put(i2400m);
- kfree(iw);
- return;
}
/*
@@ -805,18 +744,10 @@ void __i2400m_error_recovery(struct work_struct *ws)
*/
void i2400m_error_recovery(struct i2400m *i2400m)
{
- struct device *dev = i2400m_dev(i2400m);
-
- if (atomic_add_return(1, &i2400m->error_recovery) == 1) {
- if (i2400m_schedule_work(i2400m, __i2400m_error_recovery,
- GFP_ATOMIC, NULL, 0) < 0) {
- dev_err(dev, "run out of memory for "
- "scheduling an error recovery ?\n");
- atomic_dec(&i2400m->error_recovery);
- }
- } else
+ if (atomic_add_return(1, &i2400m->error_recovery) == 1)
+ schedule_work(&i2400m->recovery_ws);
+ else
atomic_dec(&i2400m->error_recovery);
- return;
}
EXPORT_SYMBOL_GPL(i2400m_error_recovery);
@@ -886,6 +817,10 @@ void i2400m_init(struct i2400m *i2400m)
mutex_init(&i2400m->init_mutex);
/* wake_tx_ws is initialized in i2400m_tx_setup() */
+
+ INIT_WORK(&i2400m->reset_ws, __i2400m_dev_reset_handle);
+ INIT_WORK(&i2400m->recovery_ws, __i2400m_error_recovery);
+
atomic_set(&i2400m->bus_reset_retries, 0);
i2400m->alive = 0;
@@ -1040,6 +975,9 @@ void i2400m_release(struct i2400m *i2400m)
i2400m_dev_stop(i2400m);
+ cancel_work_sync(&i2400m->reset_ws);
+ cancel_work_sync(&i2400m->recovery_ws);
+
i2400m_debugfs_rm(i2400m);
sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
&i2400m_dev_attr_group);
@@ -1083,8 +1021,6 @@ module_init(i2400m_driver_init);
static
void __exit i2400m_driver_exit(void)
{
- /* for scheds i2400m_dev_reset_handle() */
- flush_scheduled_work();
i2400m_barker_db_exit();
}
module_exit(i2400m_driver_exit);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 59ac7705e76e..17ecaa41a807 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -632,6 +632,11 @@ struct i2400m {
struct work_struct wake_tx_ws;
struct sk_buff *wake_tx_skb;
+ struct work_struct reset_ws;
+ const char *reset_reason;
+
+ struct work_struct recovery_ws;
+
struct dentry *debugfs_dentry;
const char *fw_name; /* name of the current firmware image */
unsigned long fw_version; /* version of the firmware interface */
@@ -896,20 +901,6 @@ struct device *i2400m_dev(struct i2400m *i2400m)
return i2400m->wimax_dev.net_dev->dev.parent;
}
-/*
- * Helper for scheduling simple work functions
- *
- * This struct can get any kind of payload attached (normally in the
- * form of a struct where you pack the stuff you want to pass to the
- * _work function).
- */
-struct i2400m_work {
- struct work_struct ws;
- struct i2400m *i2400m;
- size_t pl_size;
- u8 pl[0];
-};
-
extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *,
char *, size_t);
extern int i2400m_msg_size_check(struct i2400m *,
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 9bfc26e1bc6b..be428cae28d8 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -590,7 +590,6 @@ module_init(i2400ms_driver_init);
static
void __exit i2400ms_driver_exit(void)
{
- flush_scheduled_work(); /* for the stuff we schedule */
sdio_unregister_driver(&i2400m_sdio_driver);
}
module_exit(i2400ms_driver_exit);
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index d3365ac85dde..10e3ab352175 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -780,7 +780,6 @@ module_init(i2400mu_driver_init);
static
void __exit i2400mu_driver_exit(void)
{
- flush_scheduled_work(); /* for the stuff we schedule from sysfs.c */
usb_deregister(&i2400mu_driver);
}
module_exit(i2400mu_driver_exit);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4de4410cd38e..b4338f389394 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/rtlwifi/Kconfig"
source "drivers/net/wireless/wl1251/Kconfig"
source "drivers/net/wireless/wl12xx/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 06f8ca26c5c1..9760561a27a5 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
obj-$(CONFIG_ZD1211RW) += zd1211rw/
obj-$(CONFIG_RTL8180) += rtl818x/
obj-$(CONFIG_RTL8187) += rtl818x/
+obj-$(CONFIG_RTL8192CE) += rtlwifi/
# 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a36e7870b03e..57a79b0475f6 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4652,24 +4652,18 @@ static ssize_t proc_write( struct file *file,
size_t len,
loff_t *offset )
{
- loff_t pos = *offset;
+ ssize_t ret;
struct proc_data *priv = file->private_data;
if (!priv->wbuffer)
return -EINVAL;
- if (pos < 0)
- return -EINVAL;
- if (pos >= priv->maxwritelen)
- return 0;
- if (len > priv->maxwritelen - pos)
- len = priv->maxwritelen - pos;
- if (copy_from_user(priv->wbuffer + pos, buffer, len))
- return -EFAULT;
- if ( pos + len > priv->writelen )
- priv->writelen = len + file->f_pos;
- *offset = pos + len;
- return len;
+ ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
+ buffer, len);
+ if (ret > 0)
+ priv->writelen = max_t(int, priv->writelen, *offset);
+
+ return ret;
}
static int proc_status_open(struct inode *inode, struct file *file)
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
index 4604de09a8b2..6452c5055a63 100644
--- a/drivers/net/wireless/ath/ar9170/cmd.c
+++ b/drivers/net/wireless/ath/ar9170/cmd.c
@@ -54,7 +54,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
{
- __le32 buf[2] = {
+ const __le32 buf[2] = {
cpu_to_le32(reg),
cpu_to_le32(val),
};
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 5dbb5361fd51..d3be6f9816b5 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -161,8 +161,7 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = (struct ar9170_usb *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
if (unlikely(!aru)) {
dev_kfree_skb_irq(skb);
@@ -219,8 +218,7 @@ free:
static void ar9170_usb_rx_completed(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = (struct ar9170_usb *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int err;
if (!aru)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 501050c0296f..e43210c8585c 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -126,6 +126,7 @@ struct ath_bus_ops {
void (*read_cachesize)(struct ath_common *common, int *csz);
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
void (*bt_coex_prep)(struct ath_common *common);
+ void (*extn_synch_en)(struct ath_common *common);
};
struct ath_common {
@@ -162,6 +163,8 @@ struct ath_common {
struct ath_regulatory regulatory;
const struct ath_ops *ops;
const struct ath_bus_ops *bus_ops;
+
+ bool btcoex_enabled;
};
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
@@ -178,4 +181,112 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
void ath_hw_cycle_counters_update(struct ath_common *common);
int32_t ath_hw_get_listen_time(struct ath_common *common);
+extern __attribute__ ((format (printf, 3, 4))) int
+ath_printk(const char *level, struct ath_common *common, const char *fmt, ...);
+
+#define ath_emerg(common, fmt, ...) \
+ ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
+#define ath_alert(common, fmt, ...) \
+ ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
+#define ath_crit(common, fmt, ...) \
+ ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
+#define ath_err(common, fmt, ...) \
+ ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
+#define ath_warn(common, fmt, ...) \
+ ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
+#define ath_notice(common, fmt, ...) \
+ ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
+#define ath_info(common, fmt, ...) \
+ ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
+
+/**
+ * enum ath_debug_level - atheros wireless debug level
+ *
+ * @ATH_DBG_RESET: reset processing
+ * @ATH_DBG_QUEUE: hardware queue management
+ * @ATH_DBG_EEPROM: eeprom processing
+ * @ATH_DBG_CALIBRATE: periodic calibration
+ * @ATH_DBG_INTERRUPT: interrupt processing
+ * @ATH_DBG_REGULATORY: regulatory processing
+ * @ATH_DBG_ANI: adaptive noise immunitive processing
+ * @ATH_DBG_XMIT: basic xmit operation
+ * @ATH_DBG_BEACON: beacon handling
+ * @ATH_DBG_CONFIG: configuration of the hardware
+ * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
+ * @ATH_DBG_PS: power save processing
+ * @ATH_DBG_HWTIMER: hardware timer handling
+ * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
+ * @ATH_DBG_ANY: enable all debugging
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. Each driver has its own method for enabling debugging and
+ * modifying debug level states -- but this is typically done through a
+ * module parameter 'debug' along with a respective 'debug' debugfs file
+ * entry.
+ */
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
+ ATH_DBG_PS = 0x00000800,
+ ATH_DBG_HWTIMER = 0x00001000,
+ ATH_DBG_BTCOEX = 0x00002000,
+ ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH_DEBUG
+
+#define ath_dbg(common, dbg_mask, fmt, ...) \
+({ \
+ int rtn; \
+ if ((common)->debug_mask & dbg_mask) \
+ rtn = ath_printk(KERN_DEBUG, common, fmt, \
+ ##__VA_ARGS__); \
+ else \
+ rtn = 0; \
+ \
+ rtn; \
+})
+#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
+#define ATH_DBG_WARN_ON_ONCE(foo) WARN_ON_ONCE(foo)
+
+#else
+
+static inline __attribute__ ((format (printf, 3, 4))) int
+ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
+ const char *fmt, ...)
+{
+ return 0;
+}
+#define ATH_DBG_WARN(foo, arg...) do {} while (0)
+#define ATH_DBG_WARN_ON_ONCE(foo) ({ \
+ int __ret_warn_once = !!(foo); \
+ unlikely(__ret_warn_once); \
+})
+
+#endif /* CONFIG_ATH_DEBUG */
+
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ return "UNKNOWN";
+}
+#endif
+
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index eb83b7b4d0e3..e0793319389d 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,9 +1,12 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
- depends on PCI && MAC80211
+ depends on (PCI || ATHEROS_AR231X) && MAC80211
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
+ select AVERAGE
+ select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
+ select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
@@ -37,3 +40,16 @@ config ATH5K_DEBUG
modprobe ath5k debug=0x00000400
+config ATH5K_AHB
+ bool "Atheros 5xxx AHB bus support"
+ depends on (ATHEROS_AR231X && !PCI)
+ ---help---
+ This adds support for WiSoC type chipsets of the 5xxx Atheros
+ family.
+
+config ATH5K_PCI
+ bool "Atheros 5xxx PCI bus support"
+ depends on (!ATHEROS_AR231X && PCI)
+ ---help---
+ This adds support for PCI type chipsets of the 5xxx Atheros
+ family.
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 2242a140e4fe..f60b3899afc4 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -14,5 +14,8 @@ ath5k-y += led.o
ath5k-y += rfkill.o
ath5k-y += ani.o
ath5k-y += sysfs.o
+ath5k-y += mac80211-ops.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
+ath5k-$(CONFIG_ATH5K_AHB) += ahb.o
+ath5k-$(CONFIG_ATH5K_PCI) += pci.o
obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
new file mode 100644
index 000000000000..707cde149248
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <ar231x_platform.h>
+#include "ath5k.h"
+#include "debug.h"
+#include "base.h"
+#include "reg.h"
+#include "debug.h"
+
+/* return bus cachesize in 4B word units */
+static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
+{
+ *csz = L1_CACHE_BYTES >> 2;
+}
+
+bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
+{
+ struct ath5k_softc *sc = common->priv;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ u16 *eeprom, *eeprom_end;
+
+
+
+ bcfg = pdev->dev.platform_data;
+ eeprom = (u16 *) bcfg->radio;
+ eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
+
+ eeprom += off;
+ if (eeprom > eeprom_end)
+ return -EINVAL;
+
+ *data = *eeprom;
+ return 0;
+}
+
+int ath5k_hw_read_srev(struct ath5k_hw *ah)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ ah->ah_mac_srev = bcfg->devid;
+ return 0;
+}
+
+static const struct ath_bus_ops ath_ahb_bus_ops = {
+ .ath_bus_type = ATH_AHB,
+ .read_cachesize = ath5k_ahb_read_cachesize,
+ .eeprom_read = ath5k_ahb_eeprom_read,
+};
+
+/*Initialization*/
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ struct ath5k_softc *sc;
+ struct ieee80211_hw *hw;
+ struct resource *res;
+ void __iomem *mem;
+ int irq;
+ int ret = 0;
+ u32 reg;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ mem = ioremap_nocache(res->start, res->end - res->start + 1);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ irq = res->start;
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ sc = hw->priv;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->iobase = mem;
+ sc->irq = irq;
+ sc->devid = bcfg->devid;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Enable WMAC AHB arbitration */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+
+ /* Enable global WMAC swapping */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
+ reg |= AR5K_AR2315_BYTESWAP_WMAC;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
+ } else {
+ /* Enable WMAC DMA access (assuming 5312 or 231x*/
+ /* TODO: check other platforms */
+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(sc->dev)->id == 0)
+ reg |= AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg |= AR5K_AR5312_ENABLE_WLAN1;
+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+ }
+
+ ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+ ret = -ENODEV;
+ goto err_free_hw;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ return 0;
+
+ err_free_hw:
+ ieee80211_free_hw(hw);
+ platform_set_drvdata(pdev, NULL);
+ err_out:
+ return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+ struct ath5k_softc *sc;
+ u32 reg;
+
+ if (!hw)
+ return 0;
+
+ sc = hw->priv;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Disable WMAC AHB arbitration */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ } else {
+ /*Stop DMA access */
+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(sc->dev)->id == 0)
+ reg &= ~AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg &= ~AR5K_AR5312_ENABLE_WLAN1;
+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+ }
+
+ ath5k_deinit_softc(sc);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+ .probe = ath_ahb_probe,
+ .remove = ath_ahb_remove,
+ .driver = {
+ .name = "ar231x-wmac",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init
+ath5k_ahb_init(void)
+{
+ return platform_driver_register(&ath_ahb_driver);
+}
+
+static void __exit
+ath5k_ahb_exit(void)
+{
+ platform_driver_unregister(&ath_ahb_driver);
+}
+
+module_init(ath5k_ahb_init);
+module_exit(ath5k_ahb_exit);
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index f1419198a479..f915f404302d 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -58,20 +58,20 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
{
/* TODO:
* ANI documents suggest the following five levels to use, but the HAL
- * and ath9k use only use the last two levels, making this
+ * and ath9k use only the last two levels, making this
* essentially an on/off option. There *may* be a reason for this (???),
* so i stick with the HAL version for now...
*/
#if 0
- const s8 hi[] = { -18, -18, -16, -14, -12 };
- const s8 lo[] = { -52, -56, -60, -64, -70 };
- const s8 sz[] = { -34, -41, -48, -55, -62 };
- const s8 fr[] = { -70, -72, -75, -78, -80 };
+ static const s8 lo[] = { -52, -56, -60, -64, -70 };
+ static const s8 hi[] = { -18, -18, -16, -14, -12 };
+ static const s8 sz[] = { -34, -41, -48, -55, -62 };
+ static const s8 fr[] = { -70, -72, -75, -78, -80 };
#else
- const s8 sz[] = { -55, -62 };
- const s8 lo[] = { -64, -70 };
- const s8 hi[] = { -14, -12 };
- const s8 fr[] = { -78, -80 };
+ static const s8 lo[] = { -64, -70 };
+ static const s8 hi[] = { -14, -12 };
+ static const s8 sz[] = { -55, -62 };
+ static const s8 fr[] = { -78, -80 };
#endif
if (level < 0 || level >= ARRAY_SIZE(sz)) {
ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
@@ -102,7 +102,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
{
- const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+ static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
if (level < 0 || level >= ARRAY_SIZE(val) ||
level > ah->ah_sc->ani_state.max_spur_level) {
@@ -127,7 +127,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
{
- const int val[] = { 0, 4, 8 };
+ static const int val[] = { 0, 4, 8 };
if (level < 0 || level >= ARRAY_SIZE(val)) {
ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
@@ -151,12 +151,12 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
{
- const int m1l[] = { 127, 50 };
- const int m2l[] = { 127, 40 };
- const int m1[] = { 127, 0x4d };
- const int m2[] = { 127, 0x40 };
- const int m2cnt[] = { 31, 16 };
- const int m2lcnt[] = { 63, 48 };
+ static const int m1l[] = { 127, 50 };
+ static const int m2l[] = { 127, 40 };
+ static const int m1[] = { 127, 0x4d };
+ static const int m2[] = { 127, 0x40 };
+ static const int m2cnt[] = { 31, 16 };
+ static const int m2lcnt[] = { 63, 48 };
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
@@ -192,7 +192,7 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
void
ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
{
- const int val[] = { 8, 6 };
+ static const int val[] = { 8, 6 };
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
ah->ah_sc->ani_state.cck_weak_sig = on;
@@ -216,7 +216,7 @@ static void
ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
bool ofdm_trigger)
{
- int rssi = ah->ah_beacon_rssi_avg.avg;
+ int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
ofdm_trigger ? "ODFM" : "CCK");
@@ -301,7 +301,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
static void
ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
- int rssi = ah->ah_beacon_rssi_avg.avg;
+ int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 308b79e1ff08..407e39c2b10b 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/types.h>
+#include <linux/average.h>
#include <net/mac80211.h>
/* RX/TX descriptor hw structs
@@ -153,19 +154,6 @@
udelay(1); \
} while (0)
-/* Register dumps are done per operation mode */
-#define AR5K_INI_RFGAIN_5GHZ 0
-#define AR5K_INI_RFGAIN_2GHZ 1
-
-/* TODO: Clean this up */
-#define AR5K_INI_VAL_11A 0
-#define AR5K_INI_VAL_11A_TURBO 1
-#define AR5K_INI_VAL_11B 2
-#define AR5K_INI_VAL_11G 3
-#define AR5K_INI_VAL_11G_TURBO 4
-#define AR5K_INI_VAL_XR 0
-#define AR5K_INI_VAL_MAX 5
-
/*
* Some tuneable values (these should be changeable by the user)
* TODO: Make use of them and add more options OR use debug/configfs
@@ -221,42 +209,66 @@
/* Initial values */
#define AR5K_INIT_CYCRSSI_THR1 2
-#define AR5K_INIT_TX_LATENCY 502
-#define AR5K_INIT_USEC 39
-#define AR5K_INIT_USEC_TURBO 79
-#define AR5K_INIT_USEC_32 31
-#define AR5K_INIT_SLOT_TIME 396
-#define AR5K_INIT_SLOT_TIME_TURBO 480
-#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
-#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
-#define AR5K_INIT_PROG_IFS 920
-#define AR5K_INIT_PROG_IFS_TURBO 960
-#define AR5K_INIT_EIFS 3440
-#define AR5K_INIT_EIFS_TURBO 6880
-#define AR5K_INIT_SIFS 560
-#define AR5K_INIT_SIFS_TURBO 480
+
+/* Tx retry limits */
#define AR5K_INIT_SH_RETRY 10
#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
+/* For station mode */
#define AR5K_INIT_SSH_RETRY 32
#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
#define AR5K_INIT_TX_RETRY 10
-#define AR5K_INIT_TRANSMIT_LATENCY ( \
- (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
- (AR5K_INIT_USEC) \
-)
-#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
- (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
- (AR5K_INIT_USEC_TURBO) \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL ( \
- (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
- (AR5K_INIT_PROG_IFS) \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
- (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
- (AR5K_INIT_PROG_IFS_TURBO) \
-)
+
+/* Slot time */
+#define AR5K_INIT_SLOT_TIME_TURBO 6
+#define AR5K_INIT_SLOT_TIME_DEFAULT 9
+#define AR5K_INIT_SLOT_TIME_HALF_RATE 13
+#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21
+#define AR5K_INIT_SLOT_TIME_B 20
+#define AR5K_SLOT_TIME_MAX 0xffff
+
+/* SIFS */
+#define AR5K_INIT_SIFS_TURBO 6
+/* XXX: 8 from initvals 10 from standard */
+#define AR5K_INIT_SIFS_DEFAULT_BG 8
+#define AR5K_INIT_SIFS_DEFAULT_A 16
+#define AR5K_INIT_SIFS_HALF_RATE 32
+#define AR5K_INIT_SIFS_QUARTER_RATE 64
+
+/* Used to calculate tx time for non 5/10/40MHz
+ * operation */
+/* It's preamble time + signal time (16 + 4) */
+#define AR5K_INIT_OFDM_PREAMPLE_TIME 20
+/* Preamble time for 40MHz (turbo) operation (min ?) */
+#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14
+#define AR5K_INIT_OFDM_SYMBOL_TIME 4
+#define AR5K_INIT_OFDM_PLCP_BITS 22
+
+/* Rx latency for 5 and 10MHz operation (max ?) */
+#define AR5K_INIT_RX_LAT_MAX 63
+/* Tx latencies from initvals (5212 only but no problem
+ * because we only tweak them on 5212) */
+#define AR5K_INIT_TX_LAT_A 54
+#define AR5K_INIT_TX_LAT_BG 384
+/* Tx latency for 40MHz (turbo) operation (min ?) */
+#define AR5K_INIT_TX_LAT_MIN 32
+/* Default Tx/Rx latencies (same for 5211)*/
+#define AR5K_INIT_TX_LATENCY_5210 54
+#define AR5K_INIT_RX_LATENCY_5210 29
+
+/* Tx frame to Tx data start delay */
+#define AR5K_INIT_TXF2TXD_START_DEFAULT 14
+#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12
+#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13
+
+/* We need to increase PHY switch and agc settling time
+ * on turbo mode */
+#define AR5K_SWITCH_SETTLING 5760
+#define AR5K_SWITCH_SETTLING_TURBO 7168
+
+#define AR5K_AGC_SETTLING 28
+/* 38 on 5210 but shouldn't matter */
+#define AR5K_AGC_SETTLING_TURBO 37
/* GENERIC CHIPSET DEFINITIONS */
@@ -303,12 +315,19 @@ struct ath5k_srev_name {
#define AR5K_SREV_AR5311B 0x30 /* Spirit */
#define AR5K_SREV_AR5211 0x40 /* Oahu */
#define AR5K_SREV_AR5212 0x50 /* Venice */
+#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */
#define AR5K_SREV_AR5212_V4 0x54 /* ??? */
#define AR5K_SREV_AR5213 0x55 /* ??? */
+#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */
+#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */
#define AR5K_SREV_AR5213A 0x59 /* Hainan */
#define AR5K_SREV_AR2413 0x78 /* Griffin lite */
#define AR5K_SREV_AR2414 0x70 /* Griffin */
+#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */
+#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */
#define AR5K_SREV_AR5424 0x90 /* Condor */
+#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */
+#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */
#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
#define AR5K_SREV_AR5414 0xa0 /* Eagle */
#define AR5K_SREV_AR2415 0xb0 /* Talon */
@@ -404,12 +423,10 @@ struct ath5k_srev_name {
enum ath5k_driver_mode {
AR5K_MODE_11A = 0,
- AR5K_MODE_11A_TURBO = 1,
- AR5K_MODE_11B = 2,
- AR5K_MODE_11G = 3,
- AR5K_MODE_11G_TURBO = 4,
+ AR5K_MODE_11B = 1,
+ AR5K_MODE_11G = 2,
AR5K_MODE_XR = 0,
- AR5K_MODE_MAX = 5
+ AR5K_MODE_MAX = 3
};
enum ath5k_ant_mode {
@@ -423,6 +440,12 @@ enum ath5k_ant_mode {
AR5K_ANTMODE_MAX,
};
+enum ath5k_bw_mode {
+ AR5K_BWMODE_DEFAULT = 0, /* 20MHz, default operation */
+ AR5K_BWMODE_5MHZ = 1, /* Quarter rate */
+ AR5K_BWMODE_10MHZ = 2, /* Half rate */
+ AR5K_BWMODE_40MHZ = 3 /* Turbo */
+};
/****************\
TX DEFINITIONS
@@ -655,7 +678,6 @@ struct ath5k_gain {
/* channel_flags */
#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
-#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
#define CHANNEL_CCK 0x0020 /* CCK channel */
#define CHANNEL_OFDM 0x0040 /* OFDM channel */
#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
@@ -667,16 +689,10 @@ struct ath5k_gain {
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_108A CHANNEL_T
-#define CHANNEL_108G CHANNEL_TG
#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
-#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
- CHANNEL_TURBO)
+#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ)
-#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO)
#define CHANNEL_MODES CHANNEL_ALL
/*
@@ -1025,7 +1041,6 @@ struct ath5k_hw {
enum ath5k_int ah_imr;
struct ieee80211_channel *ah_current_channel;
- bool ah_turbo;
bool ah_calibration;
bool ah_single_chip;
@@ -1034,6 +1049,7 @@ struct ath5k_hw {
u32 ah_phy;
u32 ah_mac_srev;
u16 ah_mac_version;
+ u16 ah_mac_revision;
u16 ah_phy_revision;
u16 ah_radio_5ghz_revision;
u16 ah_radio_2ghz_revision;
@@ -1043,6 +1059,8 @@ struct ath5k_hw {
u32 ah_limit_tx_retries;
u8 ah_coverage_class;
+ bool ah_ack_bitrate_high;
+ u8 ah_bwmode;
/* Antenna Control */
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1085,12 +1103,14 @@ struct ath5k_hw {
/* Values in 0.25dB units */
s16 txp_min_pwr;
s16 txp_max_pwr;
+ s16 txp_cur_pwr;
/* Values in 0.5dB units */
s16 txp_offset;
s16 txp_ofdm;
s16 txp_cck_ofdm_gainf_delta;
/* Value in dB units */
s16 txp_cck_ofdm_pwr_delta;
+ bool txp_setup;
} ah_txpower;
struct {
@@ -1102,7 +1122,7 @@ struct ath5k_hw {
struct ath5k_nfcal_hist ah_nfcal_hist;
/* average beacon RSSI in our BSS (used by ANI) */
- struct ath5k_avg_val ah_beacon_rssi_avg;
+ struct ewma ah_beacon_rssi_avg;
/* noise floor from last periodic calibration */
s32 ah_noise_floor;
@@ -1131,36 +1151,50 @@ struct ath5k_hw {
/*
* Prototypes
*/
+extern const struct ieee80211_ops ath5k_hw_ops;
-/* Attach/Detach Functions */
-int ath5k_hw_attach(struct ath5k_softc *sc);
-void ath5k_hw_detach(struct ath5k_hw *ah);
+/* Initialization and detach functions */
+int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
+void ath5k_deinit_softc(struct ath5k_softc *sc);
+int ath5k_hw_init(struct ath5k_softc *sc);
+void ath5k_hw_deinit(struct ath5k_hw *ah);
int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
+/*Chip id helper functions */
+const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
+int ath5k_hw_read_srev(struct ath5k_hw *ah);
+
/* LED functions */
int ath5k_init_leds(struct ath5k_softc *sc);
void ath5k_led_enable(struct ath5k_softc *sc);
void ath5k_led_off(struct ath5k_softc *sc);
void ath5k_unregister_leds(struct ath5k_softc *sc);
+
/* Reset Functions */
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
int ath5k_hw_on_hold(struct ath5k_hw *ah);
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
- struct ieee80211_channel *channel, bool change_channel);
+ struct ieee80211_channel *channel, bool fast, bool skip_pcu);
int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
bool is_set);
/* Power management functions */
+
+/* Clock rate related functions */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
+
+
/* DMA Related Functions */
void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
+int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue);
u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
u32 phys_addr);
@@ -1170,38 +1204,43 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
+/* Init/Stop functions */
+void ath5k_hw_dma_init(struct ath5k_hw *ah);
+int ath5k_hw_dma_stop(struct ath5k_hw *ah);
/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
void ath5k_eeprom_detach(struct ath5k_hw *ah);
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+
/* Protocol Control Unit Functions */
+/* Helpers */
+int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
+ int len, struct ieee80211_rate *rate);
+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
-/* BSSID Functions */
+/* RX filter control*/
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
void ath5k_hw_set_bssid(struct ath5k_hw *ah);
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
-/* Receive start/stop functions */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
-/* RX Filter functions */
void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
+/* Receive (DRU) start/stop functions */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
/* Beacon control functions */
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
-/* ACK bit rate */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
-/* Clock rate related functions */
-unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
-unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
-void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
+/* Init function */
+void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+ u8 mode);
/* Queue Control Unit, DFS Control Unit Functions */
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
@@ -1214,7 +1253,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
+int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time);
+/* Init function */
+int ath5k_hw_init_queues(struct ath5k_hw *ah);
/* Hardware Descriptor Functions */
int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
@@ -1224,6 +1265,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
+
/* GPIO Functions */
void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
@@ -1233,11 +1275,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 interrupt_level);
-/* rfkill Functions */
+
+/* RFkill Functions */
void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
-/* Misc functions */
+
+/* Misc functions TODO: Cleanup */
int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
int ath5k_hw_get_capability(struct ath5k_hw *ah,
enum ath5k_capability_type cap_type, u32 capability,
@@ -1245,19 +1289,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
+
/* Initial register settings functions */
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
-/* Initialize RF */
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
- struct ieee80211_channel *channel,
- unsigned int mode);
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+
+/* PHY functions */
+/* Misc PHY functions */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Gain_F optimization */
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
/* PHY calibration */
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
@@ -1266,18 +1311,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
/* Spur mitigation */
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
struct ieee80211_channel *channel);
-void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
- struct ieee80211_channel *channel);
-/* Misc PHY functions */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Antenna control */
void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
/* TX power setup */
-int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower);
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
+/* Init function */
+int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ u8 mode, bool fast);
/*
* Functions used internaly
@@ -1293,6 +1334,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
return &(ath5k_hw_common(ah)->regulatory);
}
+#ifdef CONFIG_ATHEROS_AR231X
+#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
+
+static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
+{
+ /* On AR2315 and AR2317 the PCI clock domain registers
+ * are outside of the WMAC register space */
+ if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
+ (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
+ return AR5K_AR2315_PCI_BASE + reg;
+
+ return ah->ah_iobase + reg;
+}
+
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+ return __raw_readl(ath5k_ahb_reg(ah, reg));
+}
+
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+ __raw_writel(val, ath5k_ahb_reg(ah, reg));
+}
+
+#else
+
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
return ioread32(ah->ah_iobase + reg);
@@ -1303,6 +1370,24 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
iowrite32(val, ah->ah_iobase + reg);
}
+#endif
+
+static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
+{
+ return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
+}
+
+static inline void ath5k_read_cachesize(struct ath_common *common, int *csz)
+{
+ common->bus_ops->read_cachesize(common, csz);
+}
+
+static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return common->bus_ops->eeprom_read(common, off, data);
+}
+
static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
{
u32 retval = 0, bit, i;
@@ -1315,27 +1400,4 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
return retval;
}
-#define AVG_SAMPLES 8
-#define AVG_FACTOR 1000
-
-/**
- * ath5k_moving_average - Exponentially weighted moving average
- * @avg: average structure
- * @val: current value
- *
- * This implementation make use of a struct ath5k_avg_val to prevent rounding
- * errors.
- */
-static inline struct ath5k_avg_val
-ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
-{
- struct ath5k_avg_val new;
- new.avg_weight = avg.avg_weight ?
- (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
- (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
- (val * (AVG_FACTOR));
- new.avg = new.avg_weight / (AVG_FACTOR);
- return new;
-}
-
#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index fbe8aca975d8..cdac5cff0177 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
}
/**
- * ath5k_hw_attach - Check if hw is supported and init the needed structs
+ * ath5k_hw_init - Check if hw is supported and init the needed structs
*
- * @sc: The &struct ath5k_softc we got from the driver's attach function
+ * @sc: The &struct ath5k_softc we got from the driver's init_softc function
*
* Check if the device is supported, perform a POST and initialize the needed
* structs. Returns -ENOMEM if we don't have memory for the needed structs,
* -ENODEV if the device is not supported or prints an error msg if something
* else went wrong.
*/
-int ath5k_hw_attach(struct ath5k_softc *sc)
+int ath5k_hw_init(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
@@ -115,7 +115,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
* HW information
*/
ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
- ah->ah_turbo = false;
+ ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
@@ -128,7 +128,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/*
* Find the mac version
*/
- srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+ ath5k_hw_read_srev(ah);
+ srev = ah->ah_mac_srev;
if (srev < AR5K_SREV_AR5311)
ah->ah_version = AR5K_AR5210;
else if (srev < AR5K_SREV_AR5212)
@@ -136,6 +137,10 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
else
ah->ah_version = AR5K_AR5212;
+ /* Get the MAC revision */
+ ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+ ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
+
/* Fill the ath5k_hw struct with the needed functions */
ret = ath5k_hw_init_desc_functions(ah);
if (ret)
@@ -146,9 +151,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
if (ret)
goto err;
- /* Get MAC, PHY and RADIO revisions */
- ah->ah_mac_srev = srev;
- ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+ /* Get PHY and RADIO revisions */
ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
0xffffffff;
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -273,7 +276,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/*
* Write PCI-E power save settings
*/
- if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
+ if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) {
ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
@@ -305,8 +308,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/* Get misc capabilities */
ret = ath5k_hw_set_capabilities(ah);
if (ret) {
- ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
- sc->pdev->device);
+ ATH5K_ERR(sc, "unable to get device capabilities\n");
goto err;
}
@@ -346,11 +348,11 @@ err:
}
/**
- * ath5k_hw_detach - Free the ath5k_hw struct
+ * ath5k_hw_deinit - Free the ath5k_hw struct
*
* @ah: The &struct ath5k_hw
*/
-void ath5k_hw_detach(struct ath5k_hw *ah)
+void ath5k_hw_deinit(struct ath5k_hw *ah)
{
__set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8251946842e6..fce9a987789c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -47,8 +47,6 @@
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/cache.h>
-#include <linux/pci.h>
-#include <linux/pci-aspm.h>
#include <linux/ethtool.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
@@ -62,9 +60,8 @@
#include "reg.h"
#include "debug.h"
#include "ani.h"
-#include "../debug.h"
-static int modparam_nohwcrypt;
+int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -78,39 +75,24 @@ MODULE_AUTHOR("Nick Kossifidis");
MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
-
-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-static int ath5k_beacon_update(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-
-/* Known PCI ids */
-static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
- { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
- { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
- { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
- { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
- { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
- { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
- { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
- { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
- { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
- { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
- { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
- { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
+
+static int ath5k_init(struct ieee80211_hw *hw);
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+ bool skip_pcu);
+int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
/* Known SREVs */
static const struct ath5k_srev_name srev_names[] = {
+#ifdef CONFIG_ATHEROS_AR231X
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },
+ { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },
+#else
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -129,6 +111,7 @@ static const struct ath5k_srev_name srev_names[] = {
{ "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },
{ "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },
{ "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },
+#endif
{ "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },
{ "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
{ "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
@@ -142,10 +125,12 @@ static const struct ath5k_srev_name srev_names[] = {
{ "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B },
{ "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 },
{ "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },
- { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
- { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
{ "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },
{ "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
+#ifdef CONFIG_ATHEROS_AR231X
+ { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
+ { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
+#endif
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
@@ -191,38 +176,6 @@ static const struct ieee80211_rate ath5k_rates[] = {
/* XR missing */
};
-static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
- struct ath5k_buf *bf)
-{
- BUG_ON(!bf);
- if (!bf->skb)
- return;
- pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_any(bf->skb);
- bf->skb = NULL;
- bf->skbaddr = 0;
- bf->desc->ds_data = 0;
-}
-
-static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
- struct ath5k_buf *bf)
-{
- struct ath5k_hw *ah = sc->ah;
- struct ath_common *common = ath5k_hw_common(ah);
-
- BUG_ON(!bf);
- if (!bf->skb)
- return;
- pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb_any(bf->skb);
- bf->skb = NULL;
- bf->skbaddr = 0;
- bf->desc->ds_data = 0;
-}
-
-
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
{
u64 tsf = ath5k_hw_get_tsf64(ah);
@@ -233,7 +186,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
-static const char *
+const char *
ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
{
const char *name = "xxxxx";
@@ -327,14 +280,12 @@ ath5k_copy_channels(struct ath5k_hw *ah,
switch (mode) {
case AR5K_MODE_11A:
- case AR5K_MODE_11A_TURBO:
/* 1..220, but 2GHz frequencies are filtered by check_channel */
size = 220 ;
chfreq = CHANNEL_5GHZ;
break;
case AR5K_MODE_11B:
case AR5K_MODE_11G:
- case AR5K_MODE_11G_TURBO:
size = 26;
chfreq = CHANNEL_2GHZ;
break;
@@ -363,11 +314,6 @@ ath5k_copy_channels(struct ath5k_hw *ah,
case AR5K_MODE_11G:
channels[count].hw_value = chfreq | CHANNEL_OFDM;
break;
- case AR5K_MODE_11A_TURBO:
- case AR5K_MODE_11G_TURBO:
- channels[count].hw_value = chfreq |
- CHANNEL_OFDM | CHANNEL_TURBO;
- break;
case AR5K_MODE_11B:
channels[count].hw_value = CHANNEL_B;
}
@@ -483,7 +429,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
*
* Called with sc->lock.
*/
-static int
+int
ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
{
ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
@@ -496,7 +442,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- return ath5k_reset(sc, chan);
+ return ath5k_reset(sc, chan, true);
}
static void
@@ -549,7 +495,7 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
/* Calculate combined mode - when APs are active, operate in AP mode.
* Otherwise use the mode of the new interface. This can currently
* only deal with combinations of APs and STAs. Only one ad-hoc
- * interfaces is allowed above.
+ * interfaces is allowed.
*/
if (avf->opmode == NL80211_IFTYPE_AP)
iter_data->opmode = NL80211_IFTYPE_AP;
@@ -558,16 +504,9 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
iter_data->opmode = avf->opmode;
}
-static void ath_do_set_opmode(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
- ath5k_hw_set_opmode(ah, sc->opmode);
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
- sc->opmode, ath_opmode_to_string(sc->opmode));
-}
-
-void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
- struct ieee80211_vif *vif)
+void
+ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+ struct ieee80211_vif *vif)
{
struct ath_common *common = ath5k_hw_common(sc->ah);
struct ath_vif_iter_data iter_data;
@@ -595,7 +534,9 @@ void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
/* Nothing active, default to station mode */
sc->opmode = NL80211_IFTYPE_STATION;
- ath_do_set_opmode(sc);
+ ath5k_hw_set_opmode(sc->ah, sc->opmode);
+ ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+ sc->opmode, ath_opmode_to_string(sc->opmode));
if (iter_data.need_set_hw_addr && iter_data.found_active)
ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
@@ -604,7 +545,7 @@ void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
}
-static void
+void
ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
{
struct ath5k_hw *ah = sc->ah;
@@ -659,10 +600,11 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
return NULL;
}
- *skb_addr = pci_map_single(sc->pdev,
+ *skb_addr = dma_map_single(sc->dev,
skb->data, common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+ DMA_FROM_DEVICE);
+
+ if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) {
ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
dev_kfree_skb(skb);
return NULL;
@@ -758,8 +700,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
/* XXX endianness */
- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
rate = ieee80211_get_tx_rate(sc->hw, info);
if (!rate) {
@@ -839,7 +781,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
return 0;
err_unmap:
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
return ret;
}
@@ -848,7 +790,7 @@ err_unmap:
\*******************/
static int
-ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
+ath5k_desc_alloc(struct ath5k_softc *sc)
{
struct ath5k_desc *ds;
struct ath5k_buf *bf;
@@ -859,7 +801,9 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
/* allocate descriptors */
sc->desc_len = sizeof(struct ath5k_desc) *
(ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
- sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
+
+ sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len,
+ &sc->desc_daddr, GFP_KERNEL);
if (sc->desc == NULL) {
ATH5K_ERR(sc, "can't allocate descriptors\n");
ret = -ENOMEM;
@@ -905,14 +849,45 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
return 0;
err_free:
- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
err:
sc->desc = NULL;
return ret;
}
+void
+ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+ BUG_ON(!bf);
+ if (!bf->skb)
+ return;
+ dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(bf->skb);
+ bf->skb = NULL;
+ bf->skbaddr = 0;
+ bf->desc->ds_data = 0;
+}
+
+void
+ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+ struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
+
+ BUG_ON(!bf);
+ if (!bf->skb)
+ return;
+ dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize,
+ DMA_FROM_DEVICE);
+ dev_kfree_skb_any(bf->skb);
+ bf->skb = NULL;
+ bf->skbaddr = 0;
+ bf->desc->ds_data = 0;
+}
+
static void
-ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
+ath5k_desc_free(struct ath5k_softc *sc)
{
struct ath5k_buf *bf;
@@ -924,7 +899,7 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
ath5k_txbuf_free_skb(sc, bf);
/* Free memory associated with all descriptors */
- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
sc->desc = NULL;
sc->desc_daddr = 0;
@@ -1069,62 +1044,44 @@ err:
return ret;
}
+/**
+ * ath5k_drain_tx_buffs - Empty tx buffers
+ *
+ * @sc The &struct ath5k_softc
+ *
+ * Empty tx buffers from all queues in preparation
+ * of a reset or during shutdown.
+ *
+ * NB: this assumes output has been stopped and
+ * we do not need to block ath5k_tx_tasklet
+ */
static void
-ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+ath5k_drain_tx_buffs(struct ath5k_softc *sc)
{
+ struct ath5k_txq *txq;
struct ath5k_buf *bf, *bf0;
+ int i;
- /*
- * NB: this assumes output has been stopped and
- * we do not need to block ath5k_tx_tasklet
- */
- spin_lock_bh(&txq->lock);
- list_for_each_entry_safe(bf, bf0, &txq->q, list) {
- ath5k_debug_printtxbuf(sc, bf);
-
- ath5k_txbuf_free_skb(sc, bf);
+ for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
+ if (sc->txqs[i].setup) {
+ txq = &sc->txqs[i];
+ spin_lock_bh(&txq->lock);
+ list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+ ath5k_debug_printtxbuf(sc, bf);
- spin_lock_bh(&sc->txbuflock);
- list_move_tail(&bf->list, &sc->txbuf);
- sc->txbuf_len++;
- txq->txq_len--;
- spin_unlock_bh(&sc->txbuflock);
- }
- txq->link = NULL;
- txq->txq_poll_mark = false;
- spin_unlock_bh(&txq->lock);
-}
+ ath5k_txbuf_free_skb(sc, bf);
-/*
- * Drain the transmit queues and reclaim resources.
- */
-static void
-ath5k_txq_cleanup(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
- unsigned int i;
-
- /* XXX return value */
- if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
- /* don't touch the hardware if marked invalid */
- ath5k_hw_stop_tx_dma(ah, sc->bhalq);
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
- ath5k_hw_get_txdp(ah, sc->bhalq));
- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
- if (sc->txqs[i].setup) {
- ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
- "link %p\n",
- sc->txqs[i].qnum,
- ath5k_hw_get_txdp(ah,
- sc->txqs[i].qnum),
- sc->txqs[i].link);
+ spin_lock_bh(&sc->txbuflock);
+ list_move_tail(&bf->list, &sc->txbuf);
+ sc->txbuf_len++;
+ txq->txq_len--;
+ spin_unlock_bh(&sc->txbuflock);
}
+ txq->link = NULL;
+ txq->txq_poll_mark = false;
+ spin_unlock_bh(&txq->lock);
+ }
}
-
- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
- if (sc->txqs[i].setup)
- ath5k_txq_drainq(sc, &sc->txqs[i]);
}
static void
@@ -1184,16 +1141,19 @@ err:
}
/*
- * Disable the receive h/w in preparation for a reset.
+ * Disable the receive logic on PCU (DRU)
+ * In preparation for a shutdown.
+ *
+ * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop
+ * does.
*/
static void
ath5k_rx_stop(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
- ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
- ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
+ ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
ath5k_debug_printrxbuffs(sc, ah);
}
@@ -1307,8 +1267,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
return;
- ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
- rssi);
+ ewma_add(&ah->ah_beacon_rssi_avg, rssi);
/* in IBSS mode we should keep RSSI statistics per neighbour */
/* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
@@ -1551,9 +1510,9 @@ ath5k_tasklet_rx(unsigned long data)
if (!next_skb)
goto next;
- pci_unmap_single(sc->pdev, bf->skbaddr,
+ dma_unmap_single(sc->dev, bf->skbaddr,
common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb, rs.rs_datalen);
@@ -1574,8 +1533,9 @@ unlock:
* TX Handling *
\*************/
-static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq)
+int
+ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath5k_txq *txq)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_buf *bf;
@@ -1716,8 +1676,9 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
skb = bf->skb;
bf->skb = NULL;
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
- PCI_DMA_TODEVICE);
+
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
+ DMA_TO_DEVICE);
ath5k_tx_frame_completed(sc, skb, &ts);
}
@@ -1771,12 +1732,13 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
u32 flags;
const int padsize = 0;
- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
"skbaddr %llx\n", skb, skb->data, skb->len,
(unsigned long long)bf->skbaddr);
- if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
+
+ if (dma_mapping_error(sc->dev, bf->skbaddr)) {
ATH5K_ERR(sc, "beacon DMA mapping failed\n");
return -EIO;
}
@@ -1828,7 +1790,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
return 0;
err_unmap:
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
return ret;
}
@@ -1839,7 +1801,7 @@ err_unmap:
*
* Called with the beacon lock.
*/
-static int
+int
ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
int ret;
@@ -1917,7 +1879,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
sc->bmisscount = 0;
}
- if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+ if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+ sc->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
@@ -1944,13 +1907,14 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
- if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
+ if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) {
ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
/* NB: hw still stops DMA, so proceed */
}
- /* refresh the beacon for AP mode */
- if (sc->opmode == NL80211_IFTYPE_AP)
+ /* refresh the beacon for AP or MESH mode */
+ if (sc->opmode == NL80211_IFTYPE_AP ||
+ sc->opmode == NL80211_IFTYPE_MESH_POINT)
ath5k_beacon_update(sc->hw, vif);
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
@@ -1983,7 +1947,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* when we otherwise know we have to update the timers, but we keep it in this
* function to have it all together in one place.
*/
-static void
+void
ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
{
struct ath5k_hw *ah = sc->ah;
@@ -2085,7 +2049,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
* In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect TSF updates only.
*/
-static void
+void
ath5k_beacon_config(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
@@ -2113,7 +2077,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
} else
ath5k_beacon_update_timers(sc, -1);
} else {
- ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
+ ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq);
}
ath5k_hw_set_imr(ah, sc->imask);
@@ -2175,7 +2139,7 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
* AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
}
-static irqreturn_t
+irqreturn_t
ath5k_intr(int irq, void *dev_id)
{
struct ath5k_softc *sc = dev_id;
@@ -2184,7 +2148,8 @@ ath5k_intr(int irq, void *dev_id)
unsigned int counter = 1000;
if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
- !ath5k_hw_is_intr_pending(ah)))
+ ((ath5k_get_bus_type(ah) != ATH_AHB) &&
+ !ath5k_hw_is_intr_pending(ah))))
return IRQ_NONE;
do {
@@ -2250,6 +2215,10 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->rf_kill.toggleq);
}
+
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ break;
+
} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
if (unlikely(!counter))
@@ -2349,7 +2318,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
if (needreset) {
ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
"TX queues stuck, resetting\n");
- ath5k_reset(sc, sc->curchan);
+ ath5k_reset(sc, NULL, true);
}
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
@@ -2361,6 +2330,163 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
* Initialization routines *
\*************************/
+int
+ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ struct ath_common *common;
+ int ret;
+ int csz;
+
+ /* Initialize driver private data */
+ SET_IEEE80211_DEV(hw, sc->dev);
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT);
+
+ /* both antennas can be configured as RX or TX */
+ hw->wiphy->available_antennas_tx = 0x3;
+ hw->wiphy->available_antennas_rx = 0x3;
+
+ hw->extra_tx_headroom = 2;
+ hw->channel_change_time = 5000;
+
+ /*
+ * Mark the device as detached to avoid processing
+ * interrupts until setup is complete.
+ */
+ __set_bit(ATH_STAT_INVALID, sc->status);
+
+ sc->opmode = NL80211_IFTYPE_STATION;
+ sc->bintval = 1000;
+ mutex_init(&sc->lock);
+ spin_lock_init(&sc->rxbuflock);
+ spin_lock_init(&sc->txbuflock);
+ spin_lock_init(&sc->block);
+
+
+ /* Setup interrupt handler */
+ ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+ if (ret) {
+ ATH5K_ERR(sc, "request_irq failed\n");
+ goto err;
+ }
+
+ /* If we passed the test, malloc an ath5k_hw struct */
+ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+ if (!sc->ah) {
+ ret = -ENOMEM;
+ ATH5K_ERR(sc, "out of memory\n");
+ goto err_irq;
+ }
+
+ sc->ah->ah_sc = sc;
+ sc->ah->ah_iobase = sc->iobase;
+ common = ath5k_hw_common(sc->ah);
+ common->ops = &ath5k_common_ops;
+ common->bus_ops = bus_ops;
+ common->ah = sc->ah;
+ common->hw = hw;
+ common->priv = sc;
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ ath5k_read_cachesize(common, &csz);
+ common->cachelsz = csz << 2; /* convert to bytes */
+
+ spin_lock_init(&common->cc_lock);
+
+ /* Initialize device */
+ ret = ath5k_hw_init(sc);
+ if (ret)
+ goto err_free_ah;
+
+ /* set up multi-rate retry capabilities */
+ if (sc->ah->ah_version == AR5K_AR5212) {
+ hw->max_rates = 4;
+ hw->max_rate_tries = 11;
+ }
+
+ hw->vif_data_size = sizeof(struct ath5k_vif);
+
+ /* Finish private driver data initialization */
+ ret = ath5k_init(hw);
+ if (ret)
+ goto err_ah;
+
+ ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
+ sc->ah->ah_mac_srev,
+ sc->ah->ah_phy_revision);
+
+ if (!sc->ah->ah_single_chip) {
+ /* Single chip radio (!RF5111) */
+ if (sc->ah->ah_radio_5ghz_revision &&
+ !sc->ah->ah_radio_2ghz_revision) {
+ /* No 5GHz support -> report 2GHz radio */
+ if (!test_bit(AR5K_MODE_11A,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* No 2GHz support (5110 and some
+ * 5Ghz only cards) -> report 5Ghz radio */
+ } else if (!test_bit(AR5K_MODE_11B,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* Multiband radio */
+ } else {
+ ATH5K_INFO(sc, "RF%s multiband radio found"
+ " (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ }
+ }
+ /* Multi chip radio (RF5111 - RF2111) ->
+ * report both 2GHz/5GHz radios */
+ else if (sc->ah->ah_radio_5ghz_revision &&
+ sc->ah->ah_radio_2ghz_revision){
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_2ghz_revision),
+ sc->ah->ah_radio_2ghz_revision);
+ }
+ }
+
+ ath5k_debug_init_device(sc);
+
+ /* ready to process interrupts */
+ __clear_bit(ATH_STAT_INVALID, sc->status);
+
+ return 0;
+err_ah:
+ ath5k_hw_deinit(sc->ah);
+err_free_ah:
+ kfree(sc->ah);
+err_irq:
+ free_irq(sc->irq, sc);
+err:
+ return ret;
+}
+
static int
ath5k_stop_locked(struct ath5k_softc *sc)
{
@@ -2389,19 +2515,18 @@ ath5k_stop_locked(struct ath5k_softc *sc)
if (!test_bit(ATH_STAT_INVALID, sc->status)) {
ath5k_led_off(sc);
ath5k_hw_set_imr(ah, 0);
- synchronize_irq(sc->pdev->irq);
- }
- ath5k_txq_cleanup(sc);
- if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+ synchronize_irq(sc->irq);
ath5k_rx_stop(sc);
+ ath5k_hw_dma_stop(ah);
+ ath5k_drain_tx_buffs(sc);
ath5k_hw_phy_disable(ah);
}
return 0;
}
-static int
-ath5k_init(struct ath5k_softc *sc)
+int
+ath5k_init_hw(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
@@ -2430,7 +2555,7 @@ ath5k_init(struct ath5k_softc *sc)
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
- ret = ath5k_reset(sc, NULL);
+ ret = ath5k_reset(sc, NULL, false);
if (ret)
goto done;
@@ -2443,7 +2568,9 @@ ath5k_init(struct ath5k_softc *sc)
for (i = 0; i < common->keymax; i++)
ath_hw_keyreset(common, (u16) i);
- ath5k_hw_set_ack_bitrate_high(ah, true);
+ /* Use higher rates for acks instead of base
+ * rate */
+ ah->ah_ack_bitrate_high = true;
for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
sc->bslot[i] = NULL;
@@ -2474,7 +2601,7 @@ static void stop_tasklets(struct ath5k_softc *sc)
* if another thread does a system call and the thread doing the
* stop is preempted).
*/
-static int
+int
ath5k_stop_hw(struct ath5k_softc *sc)
{
int ret;
@@ -2527,25 +2654,35 @@ ath5k_stop_hw(struct ath5k_softc *sc)
* This should be called with sc->lock.
*/
static int
-ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+ bool skip_pcu)
{
struct ath5k_hw *ah = sc->ah;
- int ret;
+ struct ath_common *common = ath5k_hw_common(ah);
+ int ret, ani_mode;
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
ath5k_hw_set_imr(ah, 0);
- synchronize_irq(sc->pdev->irq);
+ synchronize_irq(sc->irq);
stop_tasklets(sc);
- if (chan) {
- ath5k_txq_cleanup(sc);
- ath5k_rx_stop(sc);
+ /* Save ani mode and disable ANI durring
+ * reset. If we don't we might get false
+ * PHY error interrupts. */
+ ani_mode = ah->ah_sc->ani_state.ani_mode;
+ ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
+ /* We are going to empty hw queues
+ * so we should also free any remaining
+ * tx buffers */
+ ath5k_drain_tx_buffs(sc);
+ if (chan) {
sc->curchan = chan;
sc->curband = &sc->sbands[chan->band];
}
- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
+ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
+ skip_pcu);
if (ret) {
ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
goto err;
@@ -2557,11 +2694,20 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
goto err;
}
- ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
+ ath5k_ani_init(ah, ani_mode);
ah->ah_cal_next_full = jiffies;
ah->ah_cal_next_ani = jiffies;
ah->ah_cal_next_nf = jiffies;
+ ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
+
+ /* clear survey data and cycle counters */
+ memset(&sc->survey, 0, sizeof(sc->survey));
+ spin_lock_bh(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
+ memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+ memset(&common->cc_ani, 0, sizeof(common->cc_ani));
+ spin_unlock_bh(&common->cc_lock);
/*
* Change channels and update the h/w rate map if we're switching;
@@ -2590,13 +2736,14 @@ static void ath5k_reset_work(struct work_struct *work)
reset_work);
mutex_lock(&sc->lock);
- ath5k_reset(sc, sc->curchan);
+ ath5k_reset(sc, NULL, true);
mutex_unlock(&sc->lock);
}
static int
-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ath5k_init(struct ieee80211_hw *hw)
{
+
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
@@ -2604,7 +2751,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
u8 mac[ETH_ALEN] = {};
int ret;
- ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
/*
* Check if the MAC has multi-rate retry support.
@@ -2641,7 +2787,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
/*
* Allocate tx+rx descriptors and populate the lists.
*/
- ret = ath5k_desc_alloc(sc, pdev);
+ ret = ath5k_desc_alloc(sc);
if (ret) {
ATH5K_ERR(sc, "can't allocate descriptors\n");
goto err;
@@ -2666,33 +2812,46 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
goto err_bhal;
}
- /* This order matches mac80211's queue priority, so we can
- * directly use the mac80211 queue number without any mapping */
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
+ /* 5211 and 5212 usually support 10 queues but we better rely on the
+ * capability information */
+ if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) {
+ /* This order matches mac80211's queue priority, so we can
+ * directly use the mac80211 queue number without any mapping */
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ hw->queues = 4;
+ } else {
+ /* older hardware (5210) can only support one data queue */
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ hw->queues = 1;
}
- hw->queues = 4;
tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
@@ -2705,8 +2864,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
- ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
- sc->pdev->device);
+ ATH5K_ERR(sc, "unable to read address from EEPROM\n");
goto err_queues;
}
@@ -2741,15 +2899,15 @@ err_queues:
err_bhal:
ath5k_hw_release_tx_queue(ah, sc->bhalq);
err_desc:
- ath5k_desc_free(sc, pdev);
+ ath5k_desc_free(sc);
err:
return ret;
}
-static void
-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+void
+ath5k_deinit_softc(struct ath5k_softc *sc)
{
- struct ath5k_softc *sc = hw->priv;
+ struct ieee80211_hw *hw = sc->hw;
/*
* NB: the order of these is important:
@@ -2764,8 +2922,9 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* XXX: ??? detach ath5k_hw ???
* Other than that, it's straightforward...
*/
+ ath5k_debug_finish_device(sc);
ieee80211_unregister_hw(hw);
- ath5k_desc_free(sc, pdev);
+ ath5k_desc_free(sc);
ath5k_txq_release(sc);
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
ath5k_unregister_leds(sc);
@@ -2776,231 +2935,12 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* returns because we'll get called back to reclaim node
* state and potentially want to use them.
*/
+ ath5k_hw_deinit(sc->ah);
+ free_irq(sc->irq, sc);
}
-/********************\
-* Mac80211 functions *
-\********************/
-
-static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct ath5k_softc *sc = hw->priv;
- u16 qnum = skb_get_queue_mapping(skb);
-
- if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
-}
-
-static int ath5k_start(struct ieee80211_hw *hw)
-{
- return ath5k_init(hw->priv);
-}
-
-static void ath5k_stop(struct ieee80211_hw *hw)
-{
- ath5k_stop_hw(hw->priv);
-}
-
-static int ath5k_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct ath5k_softc *sc = hw->priv;
- int ret;
- struct ath5k_vif *avf = (void *)vif->drv_priv;
-
- mutex_lock(&sc->lock);
-
- if ((vif->type == NL80211_IFTYPE_AP ||
- vif->type == NL80211_IFTYPE_ADHOC)
- && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
- ret = -ELNRNG;
- goto end;
- }
-
- /* Don't allow other interfaces if one ad-hoc is configured.
- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
- * for the IBSS, but this breaks with additional AP or STA interfaces
- * at the moment. */
- if (sc->num_adhoc_vifs ||
- (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
- ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
- ret = -ELNRNG;
- goto end;
- }
-
- switch (vif->type) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_MESH_POINT:
- avf->opmode = vif->type;
- break;
- default:
- ret = -EOPNOTSUPP;
- goto end;
- }
-
- sc->nvifs++;
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
-
- /* Assign the vap/adhoc to a beacon xmit slot. */
- if ((avf->opmode == NL80211_IFTYPE_AP) ||
- (avf->opmode == NL80211_IFTYPE_ADHOC)) {
- int slot;
-
- WARN_ON(list_empty(&sc->bcbuf));
- avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
- list);
- list_del(&avf->bbuf->list);
-
- avf->bslot = 0;
- for (slot = 0; slot < ATH_BCBUF; slot++) {
- if (!sc->bslot[slot]) {
- avf->bslot = slot;
- break;
- }
- }
- BUG_ON(sc->bslot[avf->bslot] != NULL);
- sc->bslot[avf->bslot] = vif;
- if (avf->opmode == NL80211_IFTYPE_AP)
- sc->num_ap_vifs++;
- else
- sc->num_adhoc_vifs++;
- }
-
- /* Any MAC address is fine, all others are included through the
- * filter.
- */
- memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
- ath5k_hw_set_lladdr(sc->ah, vif->addr);
-
- memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
-
- ath5k_mode_setup(sc, vif);
-
- ret = 0;
-end:
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static void
-ath5k_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_vif *avf = (void *)vif->drv_priv;
- unsigned int i;
-
- mutex_lock(&sc->lock);
- sc->nvifs--;
-
- if (avf->bbuf) {
- ath5k_txbuf_free_skb(sc, avf->bbuf);
- list_add_tail(&avf->bbuf->list, &sc->bcbuf);
- for (i = 0; i < ATH_BCBUF; i++) {
- if (sc->bslot[i] == vif) {
- sc->bslot[i] = NULL;
- break;
- }
- }
- avf->bbuf = NULL;
- }
- if (avf->opmode == NL80211_IFTYPE_AP)
- sc->num_ap_vifs--;
- else if (avf->opmode == NL80211_IFTYPE_ADHOC)
- sc->num_adhoc_vifs--;
-
- ath5k_update_bssid_mask_and_opmode(sc, NULL);
- mutex_unlock(&sc->lock);
-}
-
-/*
- * TODO: Phy disable/diversity etc
- */
-static int
-ath5k_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- struct ieee80211_conf *conf = &hw->conf;
- int ret = 0;
-
- mutex_lock(&sc->lock);
-
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- ret = ath5k_chan_set(sc, conf->channel);
- if (ret < 0)
- goto unlock;
- }
-
- if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
- (sc->power_level != conf->power_level)) {
- sc->power_level = conf->power_level;
-
- /* Half dB steps */
- ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
- }
-
- /* TODO:
- * 1) Move this on config_interface and handle each case
- * separately eg. when we have only one STA vif, use
- * AR5K_ANTMODE_SINGLE_AP
- *
- * 2) Allow the user to change antenna mode eg. when only
- * one antenna is present
- *
- * 3) Allow the user to set default/tx antenna when possible
- *
- * 4) Default mode should handle 90% of the cases, together
- * with fixed a/b and single AP modes we should be able to
- * handle 99%. Sectored modes are extreme cases and i still
- * haven't found a usage for them. If we decide to support them,
- * then we must allow the user to set how many tx antennas we
- * have available
- */
- ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
-
-unlock:
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
- struct netdev_hw_addr_list *mc_list)
-{
- u32 mfilt[2], val;
- u8 pos;
- struct netdev_hw_addr *ha;
-
- mfilt[0] = 0;
- mfilt[1] = 1;
-
- netdev_hw_addr_list_for_each(ha, mc_list) {
- /* calculate XOR of eight 6-bit values */
- val = get_unaligned_le32(ha->addr + 0);
- pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
- val = get_unaligned_le32(ha->addr + 3);
- pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
- pos &= 0x3f;
- mfilt[pos / 32] |= (1 << (pos % 32));
- /* XXX: we might be able to just do this instead,
- * but not sure, needs testing, if we do use this we'd
- * neet to inform below to not reset the mcast */
- /* ath5k_hw_set_mcast_filterindex(ah,
- * ha->addr[5]); */
- }
-
- return ((u64)(mfilt[1]) << 32) | mfilt[0];
-}
-
-static bool ath_any_vif_assoc(struct ath5k_softc *sc)
+bool
+ath_any_vif_assoc(struct ath5k_softc *sc)
{
struct ath_vif_iter_data iter_data;
iter_data.hw_macaddr = NULL;
@@ -3013,242 +2953,7 @@ static bool ath_any_vif_assoc(struct ath5k_softc *sc)
return iter_data.any_assoc;
}
-#define SUPPORTED_FIF_FLAGS \
- FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
- FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
- FIF_BCN_PRBRESP_PROMISC
-/*
- * o always accept unicast, broadcast, and multicast traffic
- * o multicast traffic for all BSSIDs will be enabled if mac80211
- * says it should be
- * o maintain current state of phy ofdm or phy cck error reception.
- * If the hardware detects any of these type of errors then
- * ath5k_hw_get_rx_filter() will pass to us the respective
- * hardware filters to be able to receive these type of frames.
- * o probe request frames are accepted only when operating in
- * hostap, adhoc, or monitor modes
- * o enable promiscuous mode according to the interface state
- * o accept beacons:
- * - when operating in adhoc mode so the 802.11 layer creates
- * node table entries for peers,
- * - when operating in station mode for collecting rssi data when
- * the station is otherwise quiet, or
- * - when scanning
- */
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *new_flags,
- u64 multicast)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- u32 mfilt[2], rfilt;
-
- mutex_lock(&sc->lock);
-
- mfilt[0] = multicast;
- mfilt[1] = multicast >> 32;
-
- /* Only deal with supported flags */
- changed_flags &= SUPPORTED_FIF_FLAGS;
- *new_flags &= SUPPORTED_FIF_FLAGS;
-
- /* If HW detects any phy or radar errors, leave those filters on.
- * Also, always enable Unicast, Broadcasts and Multicast
- * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
- rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
- (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
- AR5K_RX_FILTER_MCAST);
-
- if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
- if (*new_flags & FIF_PROMISC_IN_BSS) {
- __set_bit(ATH_STAT_PROMISC, sc->status);
- } else {
- __clear_bit(ATH_STAT_PROMISC, sc->status);
- }
- }
-
- if (test_bit(ATH_STAT_PROMISC, sc->status))
- rfilt |= AR5K_RX_FILTER_PROM;
-
- /* Note, AR5K_RX_FILTER_MCAST is already enabled */
- if (*new_flags & FIF_ALLMULTI) {
- mfilt[0] = ~0;
- mfilt[1] = ~0;
- }
-
- /* This is the best we can do */
- if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
- rfilt |= AR5K_RX_FILTER_PHYERR;
-
- /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
- * and probes for any BSSID */
- if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
- rfilt |= AR5K_RX_FILTER_BEACON;
-
- /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
- * set we should only pass on control frames for this
- * station. This needs testing. I believe right now this
- * enables *all* control frames, which is OK.. but
- * but we should see if we can improve on granularity */
- if (*new_flags & FIF_CONTROL)
- rfilt |= AR5K_RX_FILTER_CONTROL;
-
- /* Additional settings per mode -- this is per ath5k */
-
- /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
-
- switch (sc->opmode) {
- case NL80211_IFTYPE_MESH_POINT:
- rfilt |= AR5K_RX_FILTER_CONTROL |
- AR5K_RX_FILTER_BEACON |
- AR5K_RX_FILTER_PROBEREQ |
- AR5K_RX_FILTER_PROM;
- break;
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_ADHOC:
- rfilt |= AR5K_RX_FILTER_PROBEREQ |
- AR5K_RX_FILTER_BEACON;
- break;
- case NL80211_IFTYPE_STATION:
- if (sc->assoc)
- rfilt |= AR5K_RX_FILTER_BEACON;
- default:
- break;
- }
-
- /* Set filters */
- ath5k_hw_set_rx_filter(ah, rfilt);
-
- /* Set multicast bits */
- ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
- /* Set the cached hw filter flags, this will later actually
- * be set in HW */
- sc->filter_flags = rfilt;
-
- mutex_unlock(&sc->lock);
-}
-
-static int
-ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- struct ath_common *common = ath5k_hw_common(ah);
- int ret = 0;
-
- if (modparam_nohwcrypt)
- return -EOPNOTSUPP;
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- case WLAN_CIPHER_SUITE_TKIP:
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)
- break;
- return -EOPNOTSUPP;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
-
- mutex_lock(&sc->lock);
-
- switch (cmd) {
- case SET_KEY:
- ret = ath_key_config(common, vif, sta, key);
- if (ret >= 0) {
- key->hw_key_idx = ret;
- /* push IV and Michael MIC generation to stack */
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
- ret = 0;
- }
- break;
- case DISABLE_KEY:
- ath_key_delete(common, key);
- break;
- default:
- ret = -EINVAL;
- }
-
- mmiowb();
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static int
-ath5k_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
-{
- struct ath5k_softc *sc = hw->priv;
-
- /* Force update */
- ath5k_hw_update_mib_counters(sc->ah);
-
- stats->dot11ACKFailureCount = sc->stats.ack_fail;
- stats->dot11RTSFailureCount = sc->stats.rts_fail;
- stats->dot11RTSSuccessCount = sc->stats.rts_ok;
- stats->dot11FCSErrorCount = sc->stats.fcs_error;
-
- return 0;
-}
-
-static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
- struct survey_info *survey)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
-
- if (idx != 0)
- return -ENOENT;
-
- survey->channel = conf->channel;
- survey->filled = SURVEY_INFO_NOISE_DBM;
- survey->noise = sc->ah->ah_noise_floor;
-
- return 0;
-}
-
-static u64
-ath5k_get_tsf(struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
-
- return ath5k_hw_get_tsf64(sc->ah);
-}
-
-static void
-ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
-{
- struct ath5k_softc *sc = hw->priv;
-
- ath5k_hw_set_tsf64(sc->ah, tsf);
-}
-
-static void
-ath5k_reset_tsf(struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
-
- /*
- * in IBSS mode we need to update the beacon timers too.
- * this will also reset the TSF if we call it with 0
- */
- if (sc->opmode == NL80211_IFTYPE_ADHOC)
- ath5k_beacon_update_timers(sc, 0);
- else
- ath5k_hw_reset_tsf(sc->ah);
-}
-
-static void
+void
set_beacon_filter(struct ieee80211_hw *hw, bool enable)
{
struct ath5k_softc *sc = hw->priv;
@@ -3262,494 +2967,3 @@ set_beacon_filter(struct ieee80211_hw *hw, bool enable)
ath5k_hw_set_rx_filter(ah, rfilt);
sc->filter_flags = rfilt;
}
-
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct ath5k_vif *avf = (void *)vif->drv_priv;
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- struct ath_common *common = ath5k_hw_common(ah);
- unsigned long flags;
-
- mutex_lock(&sc->lock);
-
- if (changes & BSS_CHANGED_BSSID) {
- /* Cache for later use during resets */
- memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
- common->curaid = 0;
- ath5k_hw_set_bssid(ah);
- mmiowb();
- }
-
- if (changes & BSS_CHANGED_BEACON_INT)
- sc->bintval = bss_conf->beacon_int;
-
- if (changes & BSS_CHANGED_ASSOC) {
- avf->assoc = bss_conf->assoc;
- if (bss_conf->assoc)
- sc->assoc = bss_conf->assoc;
- else
- sc->assoc = ath_any_vif_assoc(sc);
-
- if (sc->opmode == NL80211_IFTYPE_STATION)
- set_beacon_filter(hw, sc->assoc);
- ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
- AR5K_LED_ASSOC : AR5K_LED_INIT);
- if (bss_conf->assoc) {
- ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
- "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, common->curbssid);
- common->curaid = bss_conf->aid;
- ath5k_hw_set_bssid(ah);
- /* Once ANI is available you would start it here */
- }
- }
-
- if (changes & BSS_CHANGED_BEACON) {
- spin_lock_irqsave(&sc->block, flags);
- ath5k_beacon_update(hw, vif);
- spin_unlock_irqrestore(&sc->block, flags);
- }
-
- if (changes & BSS_CHANGED_BEACON_ENABLED)
- sc->enable_beacon = bss_conf->enable_beacon;
-
- if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
- BSS_CHANGED_BEACON_INT))
- ath5k_beacon_config(sc);
-
- mutex_unlock(&sc->lock);
-}
-
-static void ath5k_sw_scan_start(struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
- if (!sc->assoc)
- ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
-}
-
-static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
- ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
- AR5K_LED_ASSOC : AR5K_LED_INIT);
-}
-
-/**
- * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
- *
- * @hw: struct ieee80211_hw pointer
- * @coverage_class: IEEE 802.11 coverage class number
- *
- * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
- * coverage class. The values are persistent, they are restored after device
- * reset.
- */
-static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
-{
- struct ath5k_softc *sc = hw->priv;
-
- mutex_lock(&sc->lock);
- ath5k_hw_set_coverage_class(sc->ah, coverage_class);
- mutex_unlock(&sc->lock);
-}
-
-static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- struct ath5k_txq_info qi;
- int ret = 0;
-
- if (queue >= ah->ah_capabilities.cap_queues.q_tx_num)
- return 0;
-
- mutex_lock(&sc->lock);
-
- ath5k_hw_get_tx_queueprops(ah, queue, &qi);
-
- qi.tqi_aifs = params->aifs;
- qi.tqi_cw_min = params->cw_min;
- qi.tqi_cw_max = params->cw_max;
- qi.tqi_burst_time = params->txop;
-
- ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
- "Configure tx [queue %d], "
- "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
- queue, params->aifs, params->cw_min,
- params->cw_max, params->txop);
-
- if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) {
- ATH5K_ERR(sc,
- "Unable to update hardware queue %u!\n", queue);
- ret = -EIO;
- } else
- ath5k_hw_reset_tx_queue(ah, queue);
-
- mutex_unlock(&sc->lock);
-
- return ret;
-}
-
-static const struct ieee80211_ops ath5k_hw_ops = {
- .tx = ath5k_tx,
- .start = ath5k_start,
- .stop = ath5k_stop,
- .add_interface = ath5k_add_interface,
- .remove_interface = ath5k_remove_interface,
- .config = ath5k_config,
- .prepare_multicast = ath5k_prepare_multicast,
- .configure_filter = ath5k_configure_filter,
- .set_key = ath5k_set_key,
- .get_stats = ath5k_get_stats,
- .get_survey = ath5k_get_survey,
- .conf_tx = ath5k_conf_tx,
- .get_tsf = ath5k_get_tsf,
- .set_tsf = ath5k_set_tsf,
- .reset_tsf = ath5k_reset_tsf,
- .bss_info_changed = ath5k_bss_info_changed,
- .sw_scan_start = ath5k_sw_scan_start,
- .sw_scan_complete = ath5k_sw_scan_complete,
- .set_coverage_class = ath5k_set_coverage_class,
-};
-
-/********************\
-* PCI Initialization *
-\********************/
-
-static int __devinit
-ath5k_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- void __iomem *mem;
- struct ath5k_softc *sc;
- struct ath_common *common;
- struct ieee80211_hw *hw;
- int ret;
- u8 csz;
-
- /*
- * L0s needs to be disabled on all ath5k cards.
- *
- * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
- * by default in the future in 2.6.36) this will also mean both L1 and
- * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
- * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
- * though but cannot currently undue the effect of a blacklist, for
- * details you can read pcie_aspm_sanity_check() and see how it adjusts
- * the device link capability.
- *
- * It may be possible in the future to implement some PCI API to allow
- * drivers to override blacklists for pre 1.1 PCIe but for now it is
- * best to accept that both L0s and L1 will be disabled completely for
- * distributions shipping with CONFIG_PCIEASPM rather than having this
- * issue present. Motivation for adding this new API will be to help
- * with power consumption for some of these devices.
- */
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
-
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev, "can't enable device\n");
- goto err;
- }
-
- /* XXX 32-bit addressing only */
- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(&pdev->dev, "32-bit DMA not available\n");
- goto err_dis;
- }
-
- /*
- * Cache line size is used to size and align various
- * structures used to communicate with the hardware.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
- if (csz == 0) {
- /*
- * Linux 2.4.18 (at least) writes the cache line size
- * register as a 16-bit wide register which is wrong.
- * We must have this setup properly for rx buffer
- * DMA to work so force a reasonable value here if it
- * comes up zero.
- */
- csz = L1_CACHE_BYTES >> 2;
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
- }
- /*
- * The default setting of latency timer yields poor results,
- * set it to the value used by other systems. It may be worth
- * tweaking this setting more.
- */
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /*
- * Disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state.
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ret = pci_request_region(pdev, 0, "ath5k");
- if (ret) {
- dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
- goto err_dis;
- }
-
- mem = pci_iomap(pdev, 0, 0);
- if (!mem) {
- dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
- ret = -EIO;
- goto err_reg;
- }
-
- /*
- * Allocate hw (mac80211 main struct)
- * and hw->priv (driver private data)
- */
- hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
- if (hw == NULL) {
- dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
- ret = -ENOMEM;
- goto err_map;
- }
-
- dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
-
- /* Initialize driver private data */
- SET_IEEE80211_DEV(hw, &pdev->dev);
- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
-
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT);
-
- hw->extra_tx_headroom = 2;
- hw->channel_change_time = 5000;
- sc = hw->priv;
- sc->hw = hw;
- sc->pdev = pdev;
-
- /*
- * Mark the device as detached to avoid processing
- * interrupts until setup is complete.
- */
- __set_bit(ATH_STAT_INVALID, sc->status);
-
- sc->iobase = mem; /* So we can unmap it on detach */
- sc->opmode = NL80211_IFTYPE_STATION;
- sc->bintval = 1000;
- mutex_init(&sc->lock);
- spin_lock_init(&sc->rxbuflock);
- spin_lock_init(&sc->txbuflock);
- spin_lock_init(&sc->block);
-
- /* Set private data */
- pci_set_drvdata(pdev, sc);
-
- /* Setup interrupt handler */
- ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
- if (ret) {
- ATH5K_ERR(sc, "request_irq failed\n");
- goto err_free;
- }
-
- /* If we passed the test, malloc an ath5k_hw struct */
- sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
- if (!sc->ah) {
- ret = -ENOMEM;
- ATH5K_ERR(sc, "out of memory\n");
- goto err_irq;
- }
-
- sc->ah->ah_sc = sc;
- sc->ah->ah_iobase = sc->iobase;
- common = ath5k_hw_common(sc->ah);
- common->ops = &ath5k_common_ops;
- common->ah = sc->ah;
- common->hw = hw;
- common->cachelsz = csz << 2; /* convert to bytes */
- spin_lock_init(&common->cc_lock);
-
- /* Initialize device */
- ret = ath5k_hw_attach(sc);
- if (ret) {
- goto err_free_ah;
- }
-
- /* set up multi-rate retry capabilities */
- if (sc->ah->ah_version == AR5K_AR5212) {
- hw->max_rates = 4;
- hw->max_rate_tries = 11;
- }
-
- hw->vif_data_size = sizeof(struct ath5k_vif);
-
- /* Finish private driver data initialization */
- ret = ath5k_attach(pdev, hw);
- if (ret)
- goto err_ah;
-
- ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
- sc->ah->ah_mac_srev,
- sc->ah->ah_phy_revision);
-
- if (!sc->ah->ah_single_chip) {
- /* Single chip radio (!RF5111) */
- if (sc->ah->ah_radio_5ghz_revision &&
- !sc->ah->ah_radio_2ghz_revision) {
- /* No 5GHz support -> report 2GHz radio */
- if (!test_bit(AR5K_MODE_11A,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* No 2GHz support (5110 and some
- * 5Ghz only cards) -> report 5Ghz radio */
- } else if (!test_bit(AR5K_MODE_11B,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* Multiband radio */
- } else {
- ATH5K_INFO(sc, "RF%s multiband radio found"
- " (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- }
- }
- /* Multi chip radio (RF5111 - RF2111) ->
- * report both 2GHz/5GHz radios */
- else if (sc->ah->ah_radio_5ghz_revision &&
- sc->ah->ah_radio_2ghz_revision){
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_2ghz_revision),
- sc->ah->ah_radio_2ghz_revision);
- }
- }
-
- ath5k_debug_init_device(sc);
-
- /* ready to process interrupts */
- __clear_bit(ATH_STAT_INVALID, sc->status);
-
- return 0;
-err_ah:
- ath5k_hw_detach(sc->ah);
-err_free_ah:
- kfree(sc->ah);
-err_irq:
- free_irq(pdev->irq, sc);
-err_free:
- ieee80211_free_hw(hw);
-err_map:
- pci_iounmap(pdev, mem);
-err_reg:
- pci_release_region(pdev, 0);
-err_dis:
- pci_disable_device(pdev);
-err:
- return ret;
-}
-
-static void __devexit
-ath5k_pci_remove(struct pci_dev *pdev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- ath5k_debug_finish_device(sc);
- ath5k_detach(pdev, sc->hw);
- ath5k_hw_detach(sc->ah);
- kfree(sc->ah);
- free_irq(pdev->irq, sc);
- pci_iounmap(pdev, sc->iobase);
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- ieee80211_free_hw(sc->hw);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int ath5k_pci_suspend(struct device *dev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
-
- ath5k_led_off(sc);
- return 0;
-}
-
-static int ath5k_pci_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ath5k_led_enable(sc);
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
-#define ATH5K_PM_OPS (&ath5k_pm_ops)
-#else
-#define ATH5K_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
-
-static struct pci_driver ath5k_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = ath5k_pci_id_table,
- .probe = ath5k_pci_probe,
- .remove = __devexit_p(ath5k_pci_remove),
- .driver.pm = ATH5K_PM_OPS,
-};
-
-/*
- * Module init/exit functions
- */
-static int __init
-init_ath5k_pci(void)
-{
- int ret;
-
- ret = pci_register_driver(&ath5k_pci_driver);
- if (ret) {
- printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
- return ret;
- }
-
- return 0;
-}
-
-static void __exit
-exit_ath5k_pci(void)
-{
- pci_unregister_driver(&ath5k_pci_driver);
-}
-
-module_init(init_ath5k_pci);
-module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 9a79773cdc2a..6d511476e4d2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -169,7 +169,10 @@ struct ath5k_vif {
/* Software Carrier, keeps track of the driver state
* associated with an instance of a device */
struct ath5k_softc {
- struct pci_dev *pdev; /* for dma mapping */
+ struct pci_dev *pdev;
+ struct device *dev; /* for dma mapping */
+ int irq;
+ u16 devid;
void __iomem *iobase; /* address of the device */
struct mutex lock; /* dev-level lock */
struct ieee80211_hw *hw; /* IEEE 802.11 common */
@@ -255,6 +258,8 @@ struct ath5k_softc {
struct tasklet_struct ani_tasklet; /* ANI calibration */
struct delayed_work tx_complete_work;
+
+ struct survey_info survey; /* collected survey info */
};
#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index beae519aa735..31cad80e9b01 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -49,7 +49,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Set supported modes */
__set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
- __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
} else {
/*
* XXX The tranceiver supports frequencies from 4920 to 6100GHz
@@ -74,11 +73,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Set supported modes */
__set_bit(AR5K_MODE_11A,
ah->ah_capabilities.cap_mode);
- __set_bit(AR5K_MODE_11A_TURBO,
- ah->ah_capabilities.cap_mode);
- if (ah->ah_version == AR5K_AR5212)
- __set_bit(AR5K_MODE_11G_TURBO,
- ah->ah_capabilities.cap_mode);
}
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index acda56ee521b..d2f84d76bb07 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -60,7 +60,6 @@
#include "base.h"
#include "debug.h"
-#include "../debug.h"
static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0);
@@ -312,6 +311,7 @@ static const struct {
{ ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
+ { ATH5K_DEBUG_DMA, "dma", "dma start/stop" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
{ ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" },
@@ -554,63 +554,63 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
len += snprintf(buf+len, sizeof(buf)-len,
"RX\n---------------------\n");
- len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n",
st->rxerr_crc,
st->rx_all_count > 0 ?
st->rxerr_crc*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n",
st->rxerr_phy,
st->rx_all_count > 0 ?
st->rxerr_phy*100/st->rx_all_count : 0);
for (i = 0; i < 32; i++) {
if (st->rxerr_phy_code[i])
len += snprintf(buf+len, sizeof(buf)-len,
- " phy_err[%d]\t%d\n",
+ " phy_err[%u]\t%u\n",
i, st->rxerr_phy_code[i]);
}
- len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
st->rxerr_fifo,
st->rx_all_count > 0 ?
st->rxerr_fifo*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n",
st->rxerr_decrypt,
st->rx_all_count > 0 ?
st->rxerr_decrypt*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n",
st->rxerr_mic,
st->rx_all_count > 0 ?
st->rxerr_mic*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n",
st->rxerr_proc,
st->rx_all_count > 0 ?
st->rxerr_proc*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n",
st->rxerr_jumbo,
st->rx_all_count > 0 ?
st->rxerr_jumbo*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n",
st->rx_all_count);
- len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n",
st->rx_bytes_count);
len += snprintf(buf+len, sizeof(buf)-len,
"\nTX\n---------------------\n");
- len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n",
st->txerr_retry,
st->tx_all_count > 0 ?
st->txerr_retry*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
st->txerr_fifo,
st->tx_all_count > 0 ?
st->txerr_fifo*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n",
st->txerr_filt,
st->tx_all_count > 0 ?
st->txerr_filt*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n",
st->tx_all_count);
- len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n",
st->tx_bytes_count);
if (len > sizeof(buf))
@@ -719,7 +719,7 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
st->mib_intr);
len += snprintf(buf+len, sizeof(buf)-len,
"beacon RSSI average:\t%d\n",
- sc->ah->ah_beacon_rssi_avg.avg);
+ (int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
#define CC_PRINT(_struct, _field) \
_struct._field, \
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 236edbd2507d..3e34428d5126 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -95,6 +95,7 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_RX: print received skb content
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPBANDS: dump bands
+ * @ATH5K_DEBUG_DMA: debug dma start/stop
* @ATH5K_DEBUG_TRACE: trace function calls
* @ATH5K_DEBUG_DESC: descriptor setup
* @ATH5K_DEBUG_ANY: show at any debug level
@@ -118,6 +119,7 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_RX = 0x00000100,
ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400,
+ ATH5K_DEBUG_DMA = 0x00000800,
ATH5K_DEBUG_ANI = 0x00002000,
ATH5K_DEBUG_DESC = 0x00004000,
ATH5K_DEBUG_ANY = 0xffffffff
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 43244382f213..16b44ff7dd3e 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -26,9 +26,10 @@
#include "debug.h"
#include "base.h"
-/*
- * TX Descriptors
- */
+
+/************************\
+* TX Control descriptors *
+\************************/
/*
* Initialize the 2-word tx control descriptor on 5210/5211
@@ -335,6 +336,11 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
return 0;
}
+
+/***********************\
+* TX Status descriptors *
+\***********************/
+
/*
* Proccess the tx status descriptor on 5210/5211
*/
@@ -476,9 +482,10 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
return 0;
}
-/*
- * RX Descriptors
- */
+
+/****************\
+* RX Descriptors *
+\****************/
/*
* Initialize an rx control descriptor
@@ -666,6 +673,11 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
return 0;
}
+
+/********\
+* Attach *
+\********/
+
/*
* Init function pointers inside ath5k_hw struct
*/
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index b2adb2a281c2..2509d0bf037d 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -26,7 +26,7 @@
struct ath5k_hw_rx_ctl {
u32 rx_control_0; /* RX control word 0 */
u32 rx_control_1; /* RX control word 1 */
-} __packed;
+} __packed __aligned(4);
/* RX control word 1 fields/flags */
#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */
@@ -39,7 +39,7 @@ struct ath5k_hw_rx_ctl {
struct ath5k_hw_rx_status {
u32 rx_status_0; /* RX status word 0 */
u32 rx_status_1; /* RX status word 1 */
-} __packed;
+} __packed __aligned(4);
/* 5210/5211 */
/* RX status word 0 fields/flags */
@@ -129,7 +129,7 @@ enum ath5k_phy_error_code {
struct ath5k_hw_2w_tx_ctl {
u32 tx_control_0; /* TX control word 0 */
u32 tx_control_1; /* TX control word 1 */
-} __packed;
+} __packed __aligned(4);
/* TX control word 0 fields/flags */
#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -185,7 +185,7 @@ struct ath5k_hw_4w_tx_ctl {
u32 tx_control_1; /* TX control word 1 */
u32 tx_control_2; /* TX control word 2 */
u32 tx_control_3; /* TX control word 3 */
-} __packed;
+} __packed __aligned(4);
/* TX control word 0 fields/flags */
#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -244,7 +244,7 @@ struct ath5k_hw_4w_tx_ctl {
struct ath5k_hw_tx_status {
u32 tx_status_0; /* TX status word 0 */
u32 tx_status_1; /* TX status word 1 */
-} __packed;
+} __packed __aligned(4);
/* TX status word 0 fields/flags */
#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */
@@ -282,7 +282,7 @@ struct ath5k_hw_tx_status {
struct ath5k_hw_5210_tx_desc {
struct ath5k_hw_2w_tx_ctl tx_ctl;
struct ath5k_hw_tx_status tx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* 5212 hardware TX descriptor
@@ -290,7 +290,7 @@ struct ath5k_hw_5210_tx_desc {
struct ath5k_hw_5212_tx_desc {
struct ath5k_hw_4w_tx_ctl tx_ctl;
struct ath5k_hw_tx_status tx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* Common hardware RX descriptor
@@ -298,7 +298,7 @@ struct ath5k_hw_5212_tx_desc {
struct ath5k_hw_all_rx_desc {
struct ath5k_hw_rx_ctl rx_ctl;
struct ath5k_hw_rx_status rx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* Atheros hardware DMA descriptor
@@ -313,7 +313,7 @@ struct ath5k_desc {
struct ath5k_hw_5212_tx_desc ds_tx5212;
struct ath5k_hw_all_rx_desc ds_rx;
} ud;
-} __packed;
+} __packed __aligned(4);
#define AR5K_RXDESC_INTREQ 0x0020
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 923c9ca5c4f0..0064be7ce5c9 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -37,6 +37,7 @@
#include "debug.h"
#include "base.h"
+
/*********\
* Receive *
\*********/
@@ -57,7 +58,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
*
* @ah: The &struct ath5k_hw
*/
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
+static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
{
unsigned int i;
@@ -69,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
for (i = 1000; i > 0 &&
(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
i--)
- udelay(10);
+ udelay(100);
+
+ if (!i)
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "failed to stop RX DMA !\n");
return i ? 0 : -EBUSY;
}
@@ -90,11 +95,18 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
* @ah: The &struct ath5k_hw
* @phys_addr: RX descriptor address
*
- * XXX: Should we check if rx is enabled before setting rxdp ?
+ * Returns -EIO if rx is active
*/
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
+int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
{
+ if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "tried to set RXDP while rx was active !\n");
+ return -EIO;
+ }
+
ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
+ return 0;
}
@@ -125,7 +137,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
/* Return if queue is declared inactive */
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return -EIO;
+ return -EINVAL;
if (ah->ah_version == AR5K_AR5210) {
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -173,10 +185,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
*
* Stop DMA transmit on a specific hw queue and drain queue so we don't
* have any pending frames. Returns -EBUSY if we still have pending frames,
- * -EINVAL if queue number is out of range.
+ * -EINVAL if queue number is out of range or inactive.
*
*/
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
{
unsigned int i = 40;
u32 tx_queue, pending;
@@ -185,7 +197,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
/* Return if queue is declared inactive */
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return -EIO;
+ return -EINVAL;
if (ah->ah_version == AR5K_AR5210) {
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -211,12 +223,31 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
ath5k_hw_reg_read(ah, AR5K_CR);
} else {
+
+ /*
+ * Enable DCU early termination to quickly
+ * flush any pending frames from QCU
+ */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
/*
* Schedule TX disable and wait until queue is empty
*/
AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
- /*Check for pending frames*/
+ /* Wait for queue to stop */
+ for (i = 1000; i > 0 &&
+ (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);
+ i--)
+ udelay(100);
+
+ if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "queue %i didn't stop !\n", queue);
+
+ /* Check for pending frames */
+ i = 1000;
do {
pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) &
@@ -247,12 +278,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
/* Wait a while and disable mechanism */
- udelay(200);
+ udelay(400);
AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
AR5K_QUIET_CTL1_QT_EN);
/* Re-check for pending frames */
- i = 40;
+ i = 100;
do {
pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) &
@@ -262,12 +293,27 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
+
+ if (pending)
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "quiet mechanism didn't work q:%i !\n",
+ queue);
}
+ /*
+ * Disable DCU early termination
+ */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
/* Clear register */
ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
- if (pending)
+ if (pending) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "tx dma didn't stop (q:%i, frm:%i) !\n",
+ queue, pending);
return -EBUSY;
+ }
}
/* TODO: Check for success on 5210 else return error */
@@ -275,6 +321,26 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
}
/**
+ * ath5k_hw_stop_beacon_queue - Stop beacon queue
+ *
+ * @ah The &struct ath5k_hw
+ * @queue The queue number
+ *
+ * Returns -EIO if queue didn't stop
+ */
+int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ int ret;
+ ret = ath5k_hw_stop_tx_dma(ah, queue);
+ if (ret) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "beacon queue didn't stop !\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+/**
* ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
*
* @ah: The &struct ath5k_hw
@@ -427,6 +493,7 @@ done:
return ret;
}
+
/*******************\
* Interrupt masking *
\*******************/
@@ -688,3 +755,92 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
return old_mask;
}
+
+/********************\
+ Init/Stop functions
+\********************/
+
+/**
+ * ath5k_hw_dma_init - Initialize DMA unit
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Set DMA size and pre-enable interrupts
+ * (driver handles tx/rx buffer setup and
+ * dma start/stop)
+ *
+ * XXX: Save/restore RXDP/TXDP registers ?
+ */
+void ath5k_hw_dma_init(struct ath5k_hw *ah)
+{
+ /*
+ * Set Rx/Tx DMA Configuration
+ *
+ * Set standard DMA size (128). Note that
+ * a DMA size of 512 causes rx overruns and tx errors
+ * on pci-e cards (tested on 5424 but since rx overruns
+ * also occur on 5416/5418 with madwifi we set 128
+ * for all PCI-E cards to be safe).
+ *
+ * XXX: need to check 5210 for this
+ * TODO: Check out tx triger level, it's always 64 on dumps but I
+ * guess we can tweak it and see how it goes ;-)
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+ }
+
+ /* Pre-enable interrupts on 5211/5212*/
+ if (ah->ah_version != AR5K_AR5210)
+ ath5k_hw_set_imr(ah, ah->ah_imr);
+
+}
+
+/**
+ * ath5k_hw_dma_stop - stop DMA unit
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stop tx/rx DMA and interrupts. Returns
+ * -EBUSY if tx or rx dma failed to stop.
+ *
+ * XXX: Sometimes DMA unit hangs and we have
+ * stuck frames on tx queues, only a reset
+ * can fix that.
+ */
+int ath5k_hw_dma_stop(struct ath5k_hw *ah)
+{
+ int i, qmax, err;
+ err = 0;
+
+ /* Disable interrupts */
+ ath5k_hw_set_imr(ah, 0);
+
+ /* Stop rx dma */
+ err = ath5k_hw_stop_rx_dma(ah);
+ if (err)
+ return err;
+
+ /* Clear any pending interrupts
+ * and disable tx dma */
+ if (ah->ah_version != AR5K_AR5210) {
+ ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
+ qmax = AR5K_NUM_TX_QUEUES;
+ } else {
+ /* PISR/SISR Not available on 5210 */
+ ath5k_hw_reg_read(ah, AR5K_ISR);
+ qmax = AR5K_NUM_TX_QUEUES_NOQCU;
+ }
+
+ for (i = 0; i < qmax; i++) {
+ err = ath5k_hw_stop_tx_dma(ah, i);
+ /* -EINVAL -> queue inactive */
+ if (err != -EINVAL)
+ return err;
+ }
+
+ return err;
+}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 39722dd73e43..80e625608bac 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -28,45 +28,16 @@
#include "debug.h"
#include "base.h"
-/*
- * Read from eeprom
- */
-static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
-{
- u32 status, timeout;
-
- /*
- * Initialize EEPROM access
- */
- if (ah->ah_version == AR5K_AR5210) {
- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
- (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
- } else {
- ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
- AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
- AR5K_EEPROM_CMD_READ);
- }
-
- for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
- status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
- if (status & AR5K_EEPROM_STAT_RDDONE) {
- if (status & AR5K_EEPROM_STAT_RDERR)
- return -EIO;
- *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
- 0xffff);
- return 0;
- }
- udelay(15);
- }
- return -ETIMEDOUT;
-}
+/******************\
+* Helper functions *
+\******************/
/*
* Translate binary channel representation in EEPROM to frequency
*/
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
- unsigned int mode)
+ unsigned int mode)
{
u16 val;
@@ -89,6 +60,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
return val;
}
+
+/*********\
+* Parsers *
+\*********/
+
/*
* Initialize eeprom & capabilities structs
*/
@@ -198,7 +174,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
*
* XXX: Serdes values seem to be fixed so
* no need to read them here, we write them
- * during ath5k_hw_attach */
+ * during ath5k_hw_init */
AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
true : false;
@@ -647,6 +623,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
return 0;
}
+
/*
* Read power calibration for RF5111 chips
*
@@ -1514,6 +1491,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
return 0;
}
+
/*
* Read per channel calibration info from EEPROM
*
@@ -1607,15 +1585,6 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
return 0;
}
-void
-ath5k_eeprom_detach(struct ath5k_hw *ah)
-{
- u8 mode;
-
- for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
- ath5k_eeprom_free_pcal_info(ah, mode);
-}
-
/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1757,6 +1726,44 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
}
/*
+ * Read the MAC address from eeprom
+ */
+int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+ u8 mac_d[ETH_ALEN] = {};
+ u32 total, offset;
+ u16 data;
+ int octet, ret;
+
+ ret = ath5k_hw_nvram_read(ah, 0x20, &data);
+ if (ret)
+ return ret;
+
+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+ ret = ath5k_hw_nvram_read(ah, offset, &data);
+ if (ret)
+ return ret;
+
+ total += data;
+ mac_d[octet + 1] = data & 0xff;
+ mac_d[octet] = data >> 8;
+ octet += 2;
+ }
+
+ if (!total || total == 3 * 0xffff)
+ return -EINVAL;
+
+ memcpy(mac, mac_d, ETH_ALEN);
+
+ return 0;
+}
+
+
+/***********************\
+* Init/Detach functions *
+\***********************/
+
+/*
* Initialize eeprom data structure
*/
int
@@ -1787,35 +1794,27 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
return 0;
}
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
{
- u8 mac_d[ETH_ALEN] = {};
- u32 total, offset;
- u16 data;
- int octet, ret;
-
- ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
- if (ret)
- return ret;
+ u8 mode;
- for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
- ret = ath5k_hw_eeprom_read(ah, offset, &data);
- if (ret)
- return ret;
+ for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+ ath5k_eeprom_free_pcal_info(ah, mode);
+}
- total += data;
- mac_d[octet + 1] = data & 0xff;
- mac_d[octet] = data >> 8;
- octet += 2;
+int
+ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
+{
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_XR:
+ return AR5K_EEPROM_MODE_11A;
+ case CHANNEL_G:
+ return AR5K_EEPROM_MODE_11G;
+ case CHANNEL_B:
+ return AR5K_EEPROM_MODE_11B;
+ default:
+ return -1;
}
-
- if (!total || total == 3 * 0xffff)
- return -EINVAL;
-
- memcpy(mac, mac_d, ETH_ALEN);
-
- return 0;
}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index c4a6d5f26af4..7c09e150dbdc 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -241,7 +241,7 @@ enum ath5k_eeprom_freq_bands{
#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
#define AR5K_EEPROM_READ(_o, _v) do { \
- ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
+ ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \
if (ret) \
return ret; \
} while (0)
@@ -517,3 +517,5 @@ struct ath5k_eeprom_info {
u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
};
+int
+ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 8fa439308828..e49340d18df4 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -44,7 +44,7 @@ struct ath5k_ini {
struct ath5k_ini_mode {
u16 mode_register;
- u32 mode_value[5];
+ u32 mode_value[3];
};
/* Initial register settings for AR5210 */
@@ -391,76 +391,74 @@ static const struct ath5k_ini ar5211_ini[] = {
*/
static const struct ath5k_ini_mode ar5211_ini_mode[] = {
{ AR5K_TXCFG,
- /* a aTurbo b g (OFDM) */
- { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x0000001d, 0x00000015 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
+ { 0x00000168, 0x000001b8, 0x00000168 } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
+ { 0x00000230, 0x000000b0, 0x00000230 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
+ { 0x00000d98, 0x00001f48, 0x00000d98 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
+ { 0x0000a0e0, 0x00005880, 0x0000a0e0 } },
{ AR5K_TIME_OUT,
- { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
+ { 0x04000400, 0x20003000, 0x04000400 } },
{ AR5K_USEC_5211,
- { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
+ { 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
- { AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(17),
- { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
- { AR5K_PHY(18),
- { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
- { AR5K_PHY(20),
- { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+ { 0x02020200, 0x02010200, 0x02020200 } },
+ { AR5K_PHY_RF_CTL2,
+ { 0x00000e0e, 0x00000707, 0x00000e0e } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x05010000, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372169c, 0x137216a8, 0x1372169c } },
+ { AR5K_PHY_GAIN,
+ { 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
+ { 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
{ AR5K_PHY_AGCCTL,
- { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
+ { 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
+ { 0x00002710, 0x0000157c, 0x00002710 } },
{ AR5K_PHY(70),
- { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
+ { 0x00000190, 0x00000084, 0x00000190 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+ { 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
{ AR5K_PHY_PCDAC_TXPOWER_BASE,
- { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
+ { 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
{ AR5K_RF_BUFFER_CONTROL_4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
+ { 0x00000010, 0x00000010, 0x00000010 } },
};
/* Initial register settings for AR5212 */
@@ -677,89 +675,87 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ /* A/XR B G */
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+ { 0x00000230, 0x000000b0, 0x00000160 } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+ { 0x00000168, 0x000001b8, 0x0000018c } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+ { 0x00000e60, 0x00001f1c, 0x00003e38 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+ { 0x0000a0e0, 0x00005880, 0x0000b0e0 } },
{ AR5K_TIME_OUT,
- { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+ { 0x03e803e8, 0x04200420, 0x08400840 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+ { 0x02020200, 0x02010200, 0x02020200 } },
{ AR5K_PHY_RF_CTL2,
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000707, 0x00000e0e } },
{ AR5K_PHY_SETTLING,
- { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+ { 0x1372161c, 0x13721722, 0x137216a2 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
+ { 0x00009d10, 0x00009d18, 0x00009d18 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
- { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+ { 0x409a4190, 0x409a4190, 0x409a4190 } },
{ AR5K_PHY(70),
- { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+ { 0x000001b8, 0x00000084, 0x00000108 } },
{ AR5K_PHY_OFDM_SELFCORR,
- { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+ { 0x10058a05, 0x10058a05, 0x10058a05 } },
{ 0xa230,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000108 } },
};
/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* A/XR B G */
+ { 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+ { 0x128d8fa7, 0x04e00f95, 0x12e00fab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05010100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+ { 0x0018da5a, 0x0018ca69, 0x0018ca69 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+ { 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+ { 0x050cb081, 0x050cb081, 0x050cb080 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+ { 0x00002710, 0x0000157c, 0x00002af8 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+ { 0xf7b81020, 0xf7b80d20, 0xf7b81020 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+ { 0x642c416a, 0x6440416a, 0x6440416a } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1873800a, 0x1883800a } },
};
static const struct ath5k_ini rf5111_ini_common_end[] = {
@@ -782,38 +778,38 @@ static const struct ath5k_ini rf5111_ini_common_end[] = {
/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* A/XR B G */
+ { 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+ { 0x0018da6d, 0x0018ca75, 0x0018ca75 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+ { 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+ { 0xf7b81020, 0xf7b80d10, 0xf7b81010 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+ { 0x00000000, 0x00000008, 0x00000008 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+ { 0x642c0140, 0x6442c160, 0x6442c160 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1873800a, 0x1883800a } },
};
static const struct ath5k_ini rf5112_ini_common_end[] = {
@@ -833,66 +829,66 @@ static const struct ath5k_ini rf5112_ini_common_end[] = {
/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+ { 0x0018fa61, 0x001a1a63, 0x001a1a63 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { 0x3139605e, 0x3139605e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+ { 0x002ec1e0, 0x002ac120, 0x002ac120 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
{ 0xa300,
- { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+ { 0x18010000, 0x18010000, 0x18010000 } },
{ 0xa304,
- { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+ { 0x30032602, 0x30032602, 0x30032602 } },
{ 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+ { 0x48073e06, 0x48073e06, 0x48073e06 } },
{ 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+ { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
{ 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+ { 0x641a600f, 0x641a600f, 0x641a600f } },
{ 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+ { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
{ 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+ { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
{ 0xa31c,
- { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+ { 0x90cf865b, 0x8ecf865b, 0x8ecf865b } },
{ 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+ { 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } },
{ 0xa324,
- { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+ { 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } },
{ 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+ { 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } },
{ 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+ { 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } },
{ 0xa330,
- { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+ { 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } },
{ 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+ { 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
};
static const struct ath5k_ini rf5413_ini_common_end[] = {
@@ -972,38 +968,38 @@ static const struct ath5k_ini rf5413_ini_common_end[] = {
/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020000, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+ { 0x00000e00, 0x00000e00, 0x00000e00 } },
{ AR5K_PHY_PA_CTL,
- { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+ { 0x00000002, 0x0000000a, 0x0000000a } },
{ AR5K_PHY_GAIN,
- { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+ { 0x0018da6d, 0x001a6a64, 0x001a6a64 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
+ { 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+ { 0x3137665e, 0x3137665e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+ { 0x002c0140, 0x0042c140, 0x0042c140 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
};
static const struct ath5k_ini rf2413_ini_common_end[] = {
@@ -1094,52 +1090,50 @@ static const struct ath5k_ini rf2413_ini_common_end[] = {
/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000003, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_SETTLING,
- { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+ { 0x1372161c, 0x13721722, 0x13721422 } },
{ AR5K_PHY_GAIN,
- { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+ { 0x0018fa61, 0x00199a65, 0x00199a65 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { 0x3139605e, 0x3139605e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+ { 0x00000140, 0x0052c140, 0x0052c140 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
{ 0xa324,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa328,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa32c,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa330,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa334,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
};
static const struct ath5k_ini rf2425_ini_common_end[] = {
@@ -1368,15 +1362,15 @@ static const struct ath5k_ini rf5112_ini_bbgain[] = {
* Write initial register dump
*/
static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
- const struct ath5k_ini *ini_regs, bool change_channel)
+ const struct ath5k_ini *ini_regs, bool skip_pcu)
{
unsigned int i;
/* Write initial registers */
for (i = 0; i < size; i++) {
- /* On channel change there is
- * no need to mess with PCU */
- if (change_channel &&
+ /* Skip PCU registers if
+ * requested */
+ if (skip_pcu &&
ini_regs[i].ini_register >= AR5K_PCU_MIN &&
ini_regs[i].ini_register <= AR5K_PCU_MAX)
continue;
@@ -1409,7 +1403,7 @@ static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
}
-int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
+int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
{
/*
* Write initial register settings
@@ -1427,7 +1421,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
* Write initial settings common for all modes
*/
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
- ar5212_ini_common_start, change_channel);
+ ar5212_ini_common_start, skip_pcu);
/* Second set of mode-specific settings */
switch (ah->ah_radio) {
@@ -1439,12 +1433,12 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_common_end),
- rf5111_ini_common_end, change_channel);
+ rf5111_ini_common_end, skip_pcu);
/* Baseband gain table */
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_bbgain),
- rf5111_ini_bbgain, change_channel);
+ rf5111_ini_bbgain, skip_pcu);
break;
case AR5K_RF5112:
@@ -1455,11 +1449,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_common_end),
- rf5112_ini_common_end, change_channel);
+ rf5112_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF5413:
@@ -1470,11 +1464,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5413_ini_common_end),
- rf5413_ini_common_end, change_channel);
+ rf5413_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF2316:
@@ -1486,7 +1480,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf2413_ini_common_end),
- rf2413_ini_common_end, change_channel);
+ rf2413_ini_common_end, skip_pcu);
/* Override settings from rf2413_ini_common_end */
if (ah->ah_radio == AR5K_RF2316) {
@@ -1498,9 +1492,32 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF2317:
+
+ ath5k_hw_ini_mode_registers(ah,
+ ARRAY_SIZE(rf2413_ini_mode_end),
+ rf2413_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf2425_ini_common_end),
+ rf2425_ini_common_end, skip_pcu);
+
+ /* Override settings from rf2413_ini_mode_end */
+ ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN);
+
+ /* Override settings from rf2413_ini_common_end */
+ ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5,
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa);
+ ath5k_hw_reg_write(ah, 0x800000a8, 0x8140);
+ ath5k_hw_reg_write(ah, 0x000000ff, 0x9958);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_bbgain),
+ rf5112_ini_bbgain, skip_pcu);
+ break;
case AR5K_RF2425:
ath5k_hw_ini_mode_registers(ah,
@@ -1509,11 +1526,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf2425_ini_common_end),
- rf2425_ini_common_end, change_channel);
+ rf2425_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
default:
return -EINVAL;
@@ -1538,17 +1555,17 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
* Write initial settings common for all modes
*/
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
- ar5211_ini, change_channel);
+ ar5211_ini, skip_pcu);
/* AR5211 only comes with 5111 */
/* Baseband gain table */
ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
- rf5111_ini_bbgain, change_channel);
+ rf5111_ini_bbgain, skip_pcu);
/* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
} else if (ah->ah_version == AR5K_AR5210) {
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
- ar5210_ini, change_channel);
+ ar5210_ini, skip_pcu);
}
return 0;
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 67aa52e9bf94..576edf2965dc 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -133,7 +133,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = ath5k_led_brightness_set;
- err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+ err = led_classdev_register(sc->dev, &led->led_dev);
if (err) {
ATH5K_WARN(sc, "could not register LED %s\n", name);
led->sc = NULL;
@@ -161,11 +161,20 @@ int ath5k_init_leds(struct ath5k_softc *sc)
{
int ret = 0;
struct ieee80211_hw *hw = sc->hw;
+#ifndef CONFIG_ATHEROS_AR231X
struct pci_dev *pdev = sc->pdev;
+#endif
char name[ATH5K_LED_MAX_NAME_LEN + 1];
const struct pci_device_id *match;
+ if (!sc->pdev)
+ return 0;
+
+#ifdef CONFIG_ATHEROS_AR231X
+ match = NULL;
+#else
match = pci_match_id(&ath5k_led_devices[0], pdev);
+#endif
if (match) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = ATH_PIN(match->driver_data);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
new file mode 100644
index 000000000000..de257a3430be
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -0,0 +1,774 @@
+/*-
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
+ *
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#include <asm/unaligned.h>
+
+#include "base.h"
+#include "reg.h"
+
+extern int modparam_nohwcrypt;
+
+/* functions used from base.c */
+void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
+bool ath_any_vif_assoc(struct ath5k_softc *sc);
+int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath5k_txq *txq);
+int ath5k_init_hw(struct ath5k_softc *sc);
+int ath5k_stop_hw(struct ath5k_softc *sc);
+void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+ struct ieee80211_vif *vif);
+int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
+void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void ath5k_beacon_config(struct ath5k_softc *sc);
+void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
+void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
+
+/********************\
+* Mac80211 functions *
+\********************/
+
+static int
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath5k_softc *sc = hw->priv;
+ u16 qnum = skb_get_queue_mapping(skb);
+
+ if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
+ return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
+}
+
+
+static int
+ath5k_start(struct ieee80211_hw *hw)
+{
+ return ath5k_init_hw(hw->priv);
+}
+
+
+static void
+ath5k_stop(struct ieee80211_hw *hw)
+{
+ ath5k_stop_hw(hw->priv);
+}
+
+
+static int
+ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct ath5k_softc *sc = hw->priv;
+ int ret;
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+
+ mutex_lock(&sc->lock);
+
+ if ((vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC)
+ && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
+ ret = -ELNRNG;
+ goto end;
+ }
+
+ /* Don't allow other interfaces if one ad-hoc is configured.
+ * TODO: Fix the problems with ad-hoc and multiple other interfaces.
+ * We would need to operate the HW in ad-hoc mode to allow TSF updates
+ * for the IBSS, but this breaks with additional AP or STA interfaces
+ * at the moment. */
+ if (sc->num_adhoc_vifs ||
+ (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+ ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
+ ret = -ELNRNG;
+ goto end;
+ }
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ avf->opmode = vif->type;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto end;
+ }
+
+ sc->nvifs++;
+ ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
+
+ /* Assign the vap/adhoc to a beacon xmit slot. */
+ if ((avf->opmode == NL80211_IFTYPE_AP) ||
+ (avf->opmode == NL80211_IFTYPE_ADHOC) ||
+ (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
+ int slot;
+
+ WARN_ON(list_empty(&sc->bcbuf));
+ avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
+ list);
+ list_del(&avf->bbuf->list);
+
+ avf->bslot = 0;
+ for (slot = 0; slot < ATH_BCBUF; slot++) {
+ if (!sc->bslot[slot]) {
+ avf->bslot = slot;
+ break;
+ }
+ }
+ BUG_ON(sc->bslot[avf->bslot] != NULL);
+ sc->bslot[avf->bslot] = vif;
+ if (avf->opmode == NL80211_IFTYPE_AP)
+ sc->num_ap_vifs++;
+ else if (avf->opmode == NL80211_IFTYPE_ADHOC)
+ sc->num_adhoc_vifs++;
+ }
+
+ /* Any MAC address is fine, all others are included through the
+ * filter.
+ */
+ memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
+ ath5k_hw_set_lladdr(sc->ah, vif->addr);
+
+ memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
+
+ ath5k_mode_setup(sc, vif);
+
+ ret = 0;
+end:
+ mutex_unlock(&sc->lock);
+ return ret;
+}
+
+
+static void
+ath5k_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+ unsigned int i;
+
+ mutex_lock(&sc->lock);
+ sc->nvifs--;
+
+ if (avf->bbuf) {
+ ath5k_txbuf_free_skb(sc, avf->bbuf);
+ list_add_tail(&avf->bbuf->list, &sc->bcbuf);
+ for (i = 0; i < ATH_BCBUF; i++) {
+ if (sc->bslot[i] == vif) {
+ sc->bslot[i] = NULL;
+ break;
+ }
+ }
+ avf->bbuf = NULL;
+ }
+ if (avf->opmode == NL80211_IFTYPE_AP)
+ sc->num_ap_vifs--;
+ else if (avf->opmode == NL80211_IFTYPE_ADHOC)
+ sc->num_adhoc_vifs--;
+
+ ath5k_update_bssid_mask_and_opmode(sc, NULL);
+ mutex_unlock(&sc->lock);
+}
+
+
+/*
+ * TODO: Phy disable/diversity etc
+ */
+static int
+ath5k_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ieee80211_conf *conf = &hw->conf;
+ int ret = 0;
+
+ mutex_lock(&sc->lock);
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ ret = ath5k_chan_set(sc, conf->channel);
+ if (ret < 0)
+ goto unlock;
+ }
+
+ if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
+ (sc->power_level != conf->power_level)) {
+ sc->power_level = conf->power_level;
+
+ /* Half dB steps */
+ ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
+ }
+
+ /* TODO:
+ * 1) Move this on config_interface and handle each case
+ * separately eg. when we have only one STA vif, use
+ * AR5K_ANTMODE_SINGLE_AP
+ *
+ * 2) Allow the user to change antenna mode eg. when only
+ * one antenna is present
+ *
+ * 3) Allow the user to set default/tx antenna when possible
+ *
+ * 4) Default mode should handle 90% of the cases, together
+ * with fixed a/b and single AP modes we should be able to
+ * handle 99%. Sectored modes are extreme cases and i still
+ * haven't found a usage for them. If we decide to support them,
+ * then we must allow the user to set how many tx antennas we
+ * have available
+ */
+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
+
+unlock:
+ mutex_unlock(&sc->lock);
+ return ret;
+}
+
+
+static void
+ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf, u32 changes)
+{
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
+ unsigned long flags;
+
+ mutex_lock(&sc->lock);
+
+ if (changes & BSS_CHANGED_BSSID) {
+ /* Cache for later use during resets */
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ common->curaid = 0;
+ ath5k_hw_set_bssid(ah);
+ mmiowb();
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT)
+ sc->bintval = bss_conf->beacon_int;
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ avf->assoc = bss_conf->assoc;
+ if (bss_conf->assoc)
+ sc->assoc = bss_conf->assoc;
+ else
+ sc->assoc = ath_any_vif_assoc(sc);
+
+ if (sc->opmode == NL80211_IFTYPE_STATION)
+ set_beacon_filter(hw, sc->assoc);
+ ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+ AR5K_LED_ASSOC : AR5K_LED_INIT);
+ if (bss_conf->assoc) {
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+ "Bss Info ASSOC %d, bssid: %pM\n",
+ bss_conf->aid, common->curbssid);
+ common->curaid = bss_conf->aid;
+ ath5k_hw_set_bssid(ah);
+ /* Once ANI is available you would start it here */
+ }
+ }
+
+ if (changes & BSS_CHANGED_BEACON) {
+ spin_lock_irqsave(&sc->block, flags);
+ ath5k_beacon_update(hw, vif);
+ spin_unlock_irqrestore(&sc->block, flags);
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED)
+ sc->enable_beacon = bss_conf->enable_beacon;
+
+ if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
+ BSS_CHANGED_BEACON_INT))
+ ath5k_beacon_config(sc);
+
+ mutex_unlock(&sc->lock);
+}
+
+
+static u64
+ath5k_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ u32 mfilt[2], val;
+ u8 pos;
+ struct netdev_hw_addr *ha;
+
+ mfilt[0] = 0;
+ mfilt[1] = 1;
+
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ /* calculate XOR of eight 6-bit values */
+ val = get_unaligned_le32(ha->addr + 0);
+ pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ val = get_unaligned_le32(ha->addr + 3);
+ pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ pos &= 0x3f;
+ mfilt[pos / 32] |= (1 << (pos % 32));
+ /* XXX: we might be able to just do this instead,
+ * but not sure, needs testing, if we do use this we'd
+ * neet to inform below to not reset the mcast */
+ /* ath5k_hw_set_mcast_filterindex(ah,
+ * ha->addr[5]); */
+ }
+
+ return ((u64)(mfilt[1]) << 32) | mfilt[0];
+}
+
+
+/*
+ * o always accept unicast, broadcast, and multicast traffic
+ * o multicast traffic for all BSSIDs will be enabled if mac80211
+ * says it should be
+ * o maintain current state of phy ofdm or phy cck error reception.
+ * If the hardware detects any of these type of errors then
+ * ath5k_hw_get_rx_filter() will pass to us the respective
+ * hardware filters to be able to receive these type of frames.
+ * o probe request frames are accepted only when operating in
+ * hostap, adhoc, or monitor modes
+ * o enable promiscuous mode according to the interface state
+ * o accept beacons:
+ * - when operating in adhoc mode so the 802.11 layer creates
+ * node table entries for peers,
+ * - when operating in station mode for collecting rssi data when
+ * the station is otherwise quiet, or
+ * - when scanning
+ */
+static void
+ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
+ unsigned int *new_flags, u64 multicast)
+{
+#define SUPPORTED_FIF_FLAGS \
+ (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
+ FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
+ FIF_BCN_PRBRESP_PROMISC)
+
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ u32 mfilt[2], rfilt;
+
+ mutex_lock(&sc->lock);
+
+ mfilt[0] = multicast;
+ mfilt[1] = multicast >> 32;
+
+ /* Only deal with supported flags */
+ changed_flags &= SUPPORTED_FIF_FLAGS;
+ *new_flags &= SUPPORTED_FIF_FLAGS;
+
+ /* If HW detects any phy or radar errors, leave those filters on.
+ * Also, always enable Unicast, Broadcasts and Multicast
+ * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
+ rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
+ (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
+ AR5K_RX_FILTER_MCAST);
+
+ if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
+ if (*new_flags & FIF_PROMISC_IN_BSS)
+ __set_bit(ATH_STAT_PROMISC, sc->status);
+ else
+ __clear_bit(ATH_STAT_PROMISC, sc->status);
+ }
+
+ if (test_bit(ATH_STAT_PROMISC, sc->status))
+ rfilt |= AR5K_RX_FILTER_PROM;
+
+ /* Note, AR5K_RX_FILTER_MCAST is already enabled */
+ if (*new_flags & FIF_ALLMULTI) {
+ mfilt[0] = ~0;
+ mfilt[1] = ~0;
+ }
+
+ /* This is the best we can do */
+ if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
+ rfilt |= AR5K_RX_FILTER_PHYERR;
+
+ /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
+ * and probes for any BSSID */
+ if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
+ rfilt |= AR5K_RX_FILTER_BEACON;
+
+ /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
+ * set we should only pass on control frames for this
+ * station. This needs testing. I believe right now this
+ * enables *all* control frames, which is OK.. but
+ * but we should see if we can improve on granularity */
+ if (*new_flags & FIF_CONTROL)
+ rfilt |= AR5K_RX_FILTER_CONTROL;
+
+ /* Additional settings per mode -- this is per ath5k */
+
+ /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
+
+ switch (sc->opmode) {
+ case NL80211_IFTYPE_MESH_POINT:
+ rfilt |= AR5K_RX_FILTER_CONTROL |
+ AR5K_RX_FILTER_BEACON |
+ AR5K_RX_FILTER_PROBEREQ |
+ AR5K_RX_FILTER_PROM;
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_ADHOC:
+ rfilt |= AR5K_RX_FILTER_PROBEREQ |
+ AR5K_RX_FILTER_BEACON;
+ break;
+ case NL80211_IFTYPE_STATION:
+ if (sc->assoc)
+ rfilt |= AR5K_RX_FILTER_BEACON;
+ default:
+ break;
+ }
+
+ /* Set filters */
+ ath5k_hw_set_rx_filter(ah, rfilt);
+
+ /* Set multicast bits */
+ ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
+ /* Set the cached hw filter flags, this will later actually
+ * be set in HW */
+ sc->filter_flags = rfilt;
+
+ mutex_unlock(&sc->lock);
+}
+
+
+static int
+ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
+ int ret = 0;
+
+ if (modparam_nohwcrypt)
+ return -EOPNOTSUPP;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)
+ break;
+ return -EOPNOTSUPP;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ mutex_lock(&sc->lock);
+
+ switch (cmd) {
+ case SET_KEY:
+ ret = ath_key_config(common, vif, sta, key);
+ if (ret >= 0) {
+ key->hw_key_idx = ret;
+ /* push IV and Michael MIC generation to stack */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
+ ret = 0;
+ }
+ break;
+ case DISABLE_KEY:
+ ath_key_delete(common, key);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ mmiowb();
+ mutex_unlock(&sc->lock);
+ return ret;
+}
+
+
+static void
+ath5k_sw_scan_start(struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+ if (!sc->assoc)
+ ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
+}
+
+
+static void
+ath5k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+ ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+ AR5K_LED_ASSOC : AR5K_LED_INIT);
+}
+
+
+static int
+ath5k_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ /* Force update */
+ ath5k_hw_update_mib_counters(sc->ah);
+
+ stats->dot11ACKFailureCount = sc->stats.ack_fail;
+ stats->dot11RTSFailureCount = sc->stats.rts_fail;
+ stats->dot11RTSSuccessCount = sc->stats.rts_ok;
+ stats->dot11FCSErrorCount = sc->stats.fcs_error;
+
+ return 0;
+}
+
+
+static int
+ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath5k_txq_info qi;
+ int ret = 0;
+
+ if (queue >= ah->ah_capabilities.cap_queues.q_tx_num)
+ return 0;
+
+ mutex_lock(&sc->lock);
+
+ ath5k_hw_get_tx_queueprops(ah, queue, &qi);
+
+ qi.tqi_aifs = params->aifs;
+ qi.tqi_cw_min = params->cw_min;
+ qi.tqi_cw_max = params->cw_max;
+ qi.tqi_burst_time = params->txop;
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+ "Configure tx [queue %d], "
+ "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
+
+ if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) {
+ ATH5K_ERR(sc,
+ "Unable to update hardware queue %u!\n", queue);
+ ret = -EIO;
+ } else
+ ath5k_hw_reset_tx_queue(ah, queue);
+
+ mutex_unlock(&sc->lock);
+
+ return ret;
+}
+
+
+static u64
+ath5k_get_tsf(struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ return ath5k_hw_get_tsf64(sc->ah);
+}
+
+
+static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+
+static void
+ath5k_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ /*
+ * in IBSS mode we need to update the beacon timers too.
+ * this will also reset the TSF if we call it with 0
+ */
+ if (sc->opmode == NL80211_IFTYPE_ADHOC)
+ ath5k_beacon_update_timers(sc, 0);
+ else
+ ath5k_hw_reset_tsf(sc->ah);
+}
+
+
+static int
+ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct ath_common *common = ath5k_hw_common(sc->ah);
+ struct ath_cycle_counters *cc = &common->cc_survey;
+ unsigned int div = common->clockrate * 1000;
+
+ if (idx != 0)
+ return -ENOENT;
+
+ spin_lock_bh(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
+ if (cc->cycles > 0) {
+ sc->survey.channel_time += cc->cycles / div;
+ sc->survey.channel_time_busy += cc->rx_busy / div;
+ sc->survey.channel_time_rx += cc->rx_frame / div;
+ sc->survey.channel_time_tx += cc->tx_frame / div;
+ }
+ memset(cc, 0, sizeof(*cc));
+ spin_unlock_bh(&common->cc_lock);
+
+ memcpy(survey, &sc->survey, sizeof(*survey));
+
+ survey->channel = conf->channel;
+ survey->noise = sc->ah->ah_noise_floor;
+ survey->filled = SURVEY_INFO_NOISE_DBM |
+ SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_RX |
+ SURVEY_INFO_CHANNEL_TIME_TX;
+
+ return 0;
+}
+
+
+/**
+ * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
+ *
+ * @hw: struct ieee80211_hw pointer
+ * @coverage_class: IEEE 802.11 coverage class number
+ *
+ * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
+ * coverage class. The values are persistent, they are restored after device
+ * reset.
+ */
+static void
+ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ mutex_lock(&sc->lock);
+ ath5k_hw_set_coverage_class(sc->ah, coverage_class);
+ mutex_unlock(&sc->lock);
+}
+
+
+static int
+ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ if (tx_ant == 1 && rx_ant == 1)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
+ else if (tx_ant == 2 && rx_ant == 2)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
+ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
+ else
+ return -EINVAL;
+ return 0;
+}
+
+
+static int
+ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ switch (sc->ah->ah_ant_mode) {
+ case AR5K_ANTMODE_FIXED_A:
+ *tx_ant = 1; *rx_ant = 1; break;
+ case AR5K_ANTMODE_FIXED_B:
+ *tx_ant = 2; *rx_ant = 2; break;
+ case AR5K_ANTMODE_DEFAULT:
+ *tx_ant = 3; *rx_ant = 3; break;
+ }
+ return 0;
+}
+
+
+const struct ieee80211_ops ath5k_hw_ops = {
+ .tx = ath5k_tx,
+ .start = ath5k_start,
+ .stop = ath5k_stop,
+ .add_interface = ath5k_add_interface,
+ /* .change_interface = not implemented */
+ .remove_interface = ath5k_remove_interface,
+ .config = ath5k_config,
+ .bss_info_changed = ath5k_bss_info_changed,
+ .prepare_multicast = ath5k_prepare_multicast,
+ .configure_filter = ath5k_configure_filter,
+ /* .set_tim = not implemented */
+ .set_key = ath5k_set_key,
+ /* .update_tkip_key = not implemented */
+ /* .hw_scan = not implemented */
+ .sw_scan_start = ath5k_sw_scan_start,
+ .sw_scan_complete = ath5k_sw_scan_complete,
+ .get_stats = ath5k_get_stats,
+ /* .get_tkip_seq = not implemented */
+ /* .set_frag_threshold = not implemented */
+ /* .set_rts_threshold = not implemented */
+ /* .sta_add = not implemented */
+ /* .sta_remove = not implemented */
+ /* .sta_notify = not implemented */
+ .conf_tx = ath5k_conf_tx,
+ .get_tsf = ath5k_get_tsf,
+ .set_tsf = ath5k_set_tsf,
+ .reset_tsf = ath5k_reset_tsf,
+ /* .tx_last_beacon = not implemented */
+ /* .ampdu_action = not needed */
+ .get_survey = ath5k_get_survey,
+ .set_coverage_class = ath5k_set_coverage_class,
+ /* .rfkill_poll = not implemented */
+ /* .flush = not implemented */
+ /* .channel_switch = not implemented */
+ /* .napi_poll = not implemented */
+ .set_antenna = ath5k_set_antenna,
+ .get_antenna = ath5k_get_antenna,
+};
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
new file mode 100644
index 000000000000..7f8c5b0e9d2a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/pci.h>
+#include <linux/pci-aspm.h>
+#include "../ath.h"
+#include "ath5k.h"
+#include "debug.h"
+#include "base.h"
+#include "reg.h"
+
+/* Known PCI ids */
+static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
+ { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
+ { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
+ { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
+ { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
+ { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
+ { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
+ { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
+ { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
+ { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
+ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
+ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
+ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
+
+/* return bus cachesize in 4B word units */
+static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
+{
+ struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;
+ u8 u8tmp;
+
+ pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
+ *csz = (int)u8tmp;
+
+ /*
+ * This check was put in to avoid "unplesant" consequences if
+ * the bootrom has not fully initialized all PCI devices.
+ * Sometimes the cache line size register is not set
+ */
+
+ if (*csz == 0)
+ *csz = L1_CACHE_BYTES >> 2; /* Use the default size */
+}
+
+/*
+ * Read from eeprom
+ */
+bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
+{
+ struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
+ u32 status, timeout;
+
+ /*
+ * Initialize EEPROM access
+ */
+ if (ah->ah_version == AR5K_AR5210) {
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
+ (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
+ } else {
+ ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+ AR5K_EEPROM_CMD_READ);
+ }
+
+ for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
+ status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
+ if (status & AR5K_EEPROM_STAT_RDDONE) {
+ if (status & AR5K_EEPROM_STAT_RDERR)
+ return -EIO;
+ *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
+ 0xffff);
+ return 0;
+ }
+ udelay(15);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int ath5k_hw_read_srev(struct ath5k_hw *ah)
+{
+ ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+ return 0;
+}
+
+/* Common ath_bus_opts structure */
+static const struct ath_bus_ops ath_pci_bus_ops = {
+ .ath_bus_type = ATH_PCI,
+ .read_cachesize = ath5k_pci_read_cachesize,
+ .eeprom_read = ath5k_pci_eeprom_read,
+};
+
+/********************\
+* PCI Initialization *
+\********************/
+
+static int __devinit
+ath5k_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ void __iomem *mem;
+ struct ath5k_softc *sc;
+ struct ieee80211_hw *hw;
+ int ret;
+ u8 csz;
+
+ /*
+ * L0s needs to be disabled on all ath5k cards.
+ *
+ * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
+ * by default in the future in 2.6.36) this will also mean both L1 and
+ * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
+ * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
+ * though but cannot currently undue the effect of a blacklist, for
+ * details you can read pcie_aspm_sanity_check() and see how it adjusts
+ * the device link capability.
+ *
+ * It may be possible in the future to implement some PCI API to allow
+ * drivers to override blacklists for pre 1.1 PCIe but for now it is
+ * best to accept that both L0s and L1 will be disabled completely for
+ * distributions shipping with CONFIG_PCIEASPM rather than having this
+ * issue present. Motivation for adding this new API will be to help
+ * with power consumption for some of these devices.
+ */
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "can't enable device\n");
+ goto err;
+ }
+
+ /* XXX 32-bit addressing only */
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "32-bit DMA not available\n");
+ goto err_dis;
+ }
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+ if (csz == 0) {
+ /*
+ * Linux 2.4.18 (at least) writes the cache line size
+ * register as a 16-bit wide register which is wrong.
+ * We must have this setup properly for rx buffer
+ * DMA to work so force a reasonable value here if it
+ * comes up zero.
+ */
+ csz = L1_CACHE_BYTES >> 2;
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+ }
+ /*
+ * The default setting of latency timer yields poor results,
+ * set it to the value used by other systems. It may be worth
+ * tweaking this setting more.
+ */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /*
+ * Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state.
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ret = pci_request_region(pdev, 0, "ath5k");
+ if (ret) {
+ dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+ goto err_dis;
+ }
+
+ mem = pci_iomap(pdev, 0, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+ ret = -EIO;
+ goto err_reg;
+ }
+
+ /*
+ * Allocate hw (mac80211 main struct)
+ * and hw->priv (driver private data)
+ */
+ hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_map;
+ }
+
+ dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
+
+ sc = hw->priv;
+ sc->hw = hw;
+ sc->pdev = pdev;
+ sc->dev = &pdev->dev;
+ sc->irq = pdev->irq;
+ sc->devid = id->device;
+ sc->iobase = mem; /* So we can unmap it on detach */
+
+ /* Initialize */
+ ret = ath5k_init_softc(sc, &ath_pci_bus_ops);
+ if (ret)
+ goto err_free;
+
+ /* Set private data */
+ pci_set_drvdata(pdev, hw);
+
+ return 0;
+err_free:
+ ieee80211_free_hw(hw);
+err_map:
+ pci_iounmap(pdev, mem);
+err_reg:
+ pci_release_region(pdev, 0);
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return ret;
+}
+
+static void __devexit
+ath5k_pci_remove(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath5k_softc *sc = hw->priv;
+
+ ath5k_deinit_softc(sc);
+ pci_iounmap(pdev, sc->iobase);
+ pci_release_region(pdev, 0);
+ pci_disable_device(pdev);
+ ieee80211_free_hw(hw);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ath5k_pci_suspend(struct device *dev)
+{
+ struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
+
+ ath5k_led_off(sc);
+ return 0;
+}
+
+static int ath5k_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ath5k_softc *sc = pci_get_drvdata(pdev);
+
+ /*
+ * Suspend/Resume resets the PCI configuration space, so we have to
+ * re-disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ath5k_led_enable(sc);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
+#define ATH5K_PM_OPS (&ath5k_pm_ops)
+#else
+#define ATH5K_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static struct pci_driver ath5k_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = ath5k_pci_id_table,
+ .probe = ath5k_pci_probe,
+ .remove = __devexit_p(ath5k_pci_remove),
+ .driver.pm = ATH5K_PM_OPS,
+};
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+ int ret;
+
+ ret = pci_register_driver(&ath5k_pci_driver);
+ if (ret) {
+ printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit
+exit_ath5k_pci(void)
+{
+ pci_unregister_driver(&ath5k_pci_driver);
+}
+
+module_init(init_ath5k_pci);
+module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 074b4c644399..e5f2b96a4c63 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -31,87 +31,163 @@
#include "debug.h"
#include "base.h"
+/*
+ * AR5212+ can use higher rates for ack transmition
+ * based on current tx rate instead of the base rate.
+ * It does this to better utilize channel usage.
+ * This is a mapping between G rates (that cover both
+ * CCK and OFDM) and ack rates that we use when setting
+ * rate -> duration table. This mapping is hw-based so
+ * don't change anything.
+ *
+ * To enable this functionality we must set
+ * ah->ah_ack_bitrate_high to true else base rate is
+ * used (1Mb for CCK, 6Mb for OFDM).
+ */
+static const unsigned int ack_rates_high[] =
+/* Tx -> ACK */
+/* 1Mb -> 1Mb */ { 0,
+/* 2MB -> 2Mb */ 1,
+/* 5.5Mb -> 2Mb */ 1,
+/* 11Mb -> 2Mb */ 1,
+/* 6Mb -> 6Mb */ 4,
+/* 9Mb -> 6Mb */ 4,
+/* 12Mb -> 12Mb */ 6,
+/* 18Mb -> 12Mb */ 6,
+/* 24Mb -> 24Mb */ 8,
+/* 36Mb -> 24Mb */ 8,
+/* 48Mb -> 24Mb */ 8,
+/* 54Mb -> 24Mb */ 8 };
+
/*******************\
-* Generic functions *
+* Helper functions *
\*******************/
/**
- * ath5k_hw_set_opmode - Set PCU operating mode
+ * ath5k_hw_get_frame_duration - Get tx time of a frame
*
* @ah: The &struct ath5k_hw
- * @op_mode: &enum nl80211_iftype operating mode
+ * @len: Frame's length in bytes
+ * @rate: The @struct ieee80211_rate
*
- * Initialize PCU for the various operating modes (AP/STA etc)
+ * Calculate tx duration of a frame given it's rate and length
+ * It extends ieee80211_generic_frame_duration for non standard
+ * bwmodes.
*/
-int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
+int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
+ int len, struct ieee80211_rate *rate)
{
- struct ath_common *common = ath5k_hw_common(ah);
- u32 pcu_reg, beacon_reg, low_id, high_id;
+ struct ath5k_softc *sc = ah->ah_sc;
+ int sifs, preamble, plcp_bits, sym_time;
+ int bitrate, bits, symbols, symbol_bits;
+ int dur;
+
+ /* Fallback */
+ if (!ah->ah_bwmode) {
+ dur = ieee80211_generic_frame_duration(sc->hw,
+ NULL, len, rate);
+ return dur;
+ }
- ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
+ bitrate = rate->bitrate;
+ preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
+ plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
+ sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
- /* Preserve rest settings */
- pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
- pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
- | AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ sifs = AR5K_INIT_SIFS_TURBO;
+ preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ sifs = AR5K_INIT_SIFS_HALF_RATE;
+ preamble *= 2;
+ sym_time *= 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;
+ preamble *= 4;
+ sym_time *= 4;
+ break;
+ default:
+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;
+ break;
+ }
- beacon_reg = 0;
+ bits = plcp_bits + (len << 3);
+ /* Bit rate is in 100Kbits */
+ symbol_bits = bitrate * sym_time;
+ symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
- switch (op_mode) {
- case NL80211_IFTYPE_ADHOC:
- pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
- beacon_reg |= AR5K_BCR_ADHOC;
- if (ah->ah_version == AR5K_AR5210)
- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
- else
- AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
- break;
+ dur = sifs + preamble + (sym_time * symbols);
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_MESH_POINT:
- pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
- beacon_reg |= AR5K_BCR_AP;
- if (ah->ah_version == AR5K_AR5210)
- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
- else
- AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
- break;
+ return dur;
+}
- case NL80211_IFTYPE_STATION:
- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- AR5K_STA_ID1_PWR_SV : 0);
- case NL80211_IFTYPE_MONITOR:
- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- AR5K_STA_ID1_NO_PSPOLL : 0);
- break;
+/**
+ * ath5k_hw_get_default_slottime - Get the default slot time for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
+{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ unsigned int slot_time;
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_TURBO;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
+ break;
+ case AR5K_BWMODE_DEFAULT:
+ slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
default:
- return -EINVAL;
+ if (channel->hw_value & CHANNEL_CCK)
+ slot_time = AR5K_INIT_SLOT_TIME_B;
+ break;
}
- /*
- * Set PCU registers
- */
- low_id = get_unaligned_le32(common->macaddr);
- high_id = get_unaligned_le16(common->macaddr + 4);
- ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
- ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+ return slot_time;
+}
- /*
- * Set Beacon Control Register on 5210
- */
- if (ah->ah_version == AR5K_AR5210)
- ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+/**
+ * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
+{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ unsigned int sifs;
- return 0;
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ sifs = AR5K_INIT_SIFS_TURBO;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ sifs = AR5K_INIT_SIFS_HALF_RATE;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;
+ break;
+ case AR5K_BWMODE_DEFAULT:
+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;
+ default:
+ if (channel->hw_value & CHANNEL_5GHZ)
+ sifs = AR5K_INIT_SIFS_DEFAULT_A;
+ break;
+ }
+
+ return sifs;
}
/**
- * ath5k_hw_update - Update MIB counters (mac layer statistics)
+ * ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)
*
* @ah: The &struct ath5k_hw
*
@@ -133,36 +209,88 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
}
+
+/******************\
+* ACK/CTS Timeouts *
+\******************/
+
/**
- * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
*
- * @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmission rate
- * for ACKs or not
+ * @ah: the &struct ath5k_hw
+ * @mode: one of enum ath5k_driver_mode
+ *
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preamble
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates.
*
- * If high flag is set, we tell hw to use a set of control rates based on
- * the current transmission rate (check out control_rates array inside reset.c).
- * If not hw just uses the lowest rate available for the current modulation
- * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
*/
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
{
- if (ah->ah_version != AR5K_AR5212)
- return;
- else {
- u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
- if (high)
- AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct ieee80211_rate *rate;
+ unsigned int i;
+ /* 802.11g covers both OFDM and CCK */
+ u8 band = IEEE80211_BAND_2GHZ;
+
+ /* Write rate duration table */
+ for (i = 0; i < sc->sbands[band].n_bitrates; i++) {
+ u32 reg;
+ u16 tx_time;
+
+ if (ah->ah_ack_bitrate_high)
+ rate = &sc->sbands[band].bitrates[ack_rates_high[i]];
+ /* CCK -> 1Mb */
+ else if (i < 4)
+ rate = &sc->sbands[band].bitrates[0];
+ /* OFDM -> 6Mb */
else
- AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+ rate = &sc->sbands[band].bitrates[4];
+
+ /* Set ACK timeout */
+ reg = AR5K_RATE_DUR(rate->hw_value);
+
+ /* An ACK frame consists of 10 bytes. If you add the FCS,
+ * which ieee80211_generic_frame_duration() adds,
+ * its 14 bytes. Note we use the control rate and not the
+ * actual rate for this rate. See mac80211 tx.c
+ * ieee80211_duration() for a brief description of
+ * what rate we should choose to TX ACKs. */
+ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+
+ tx_time = le16_to_cpu(tx_time);
+
+ ath5k_hw_reg_write(ah, tx_time, reg);
+
+ if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
+ continue;
+
+ /*
+ * We're not distinguishing short preamble here,
+ * This is true, all we'll get is a longer value here
+ * which is not necessarilly bad. We could use
+ * export ieee80211_frame_duration() but that needs to be
+ * fixed first to be properly used by mac802111 drivers:
+ *
+ * - remove erp stuff and let the routine figure ofdm
+ * erp rates
+ * - remove passing argument ieee80211_local as
+ * drivers don't have access to it
+ * - move drivers using ieee80211_generic_frame_duration()
+ * to this
+ */
+ ath5k_hw_reg_write(ah, tx_time,
+ reg + (AR5K_SET_SHORT_PREAMBLE << 2));
}
}
-
-/******************\
-* ACK/CTS Timeouts *
-\******************/
-
/**
* ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
*
@@ -199,88 +327,10 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
return 0;
}
-/**
- * ath5k_hw_htoclock - Translate usec to hw clock units
- *
- * @ah: The &struct ath5k_hw
- * @usec: value in microseconds
- */
-unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
-{
- struct ath_common *common = ath5k_hw_common(ah);
- return usec * common->clockrate;
-}
-
-/**
- * ath5k_hw_clocktoh - Translate hw clock units to usec
- * @clock: value in hw clock units
- */
-unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
-{
- struct ath_common *common = ath5k_hw_common(ah);
- return clock / common->clockrate;
-}
-
-/**
- * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
- *
- * @ah: The &struct ath5k_hw
- */
-void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
- struct ath_common *common = ath5k_hw_common(ah);
- int clock;
-
- if (channel->hw_value & CHANNEL_5GHZ)
- clock = 40; /* 802.11a */
- else if (channel->hw_value & CHANNEL_CCK)
- clock = 22; /* 802.11b */
- else
- clock = 44; /* 802.11g */
-
- /* Clock rate in turbo modes is twice the normal rate */
- if (channel->hw_value & CHANNEL_TURBO)
- clock *= 2;
-
- common->clockrate = clock;
-}
-
-/**
- * ath5k_hw_get_default_slottime - Get the default slot time for current mode
- *
- * @ah: The &struct ath5k_hw
- */
-static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
-
- if (channel->hw_value & CHANNEL_TURBO)
- return 6; /* both turbo modes */
-
- if (channel->hw_value & CHANNEL_CCK)
- return 20; /* 802.11b */
-
- return 9; /* 802.11 a/g */
-}
-
-/**
- * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
- *
- * @ah: The &struct ath5k_hw
- */
-static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
-
- if (channel->hw_value & CHANNEL_TURBO)
- return 8; /* both turbo modes */
- if (channel->hw_value & CHANNEL_5GHZ)
- return 16; /* 802.11a */
-
- return 10; /* 802.11 b/g */
-}
+/*******************\
+* RX filter Control *
+\*******************/
/**
* ath5k_hw_set_lladdr - Set station id
@@ -362,39 +412,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
ath_hw_setbssidmask(common);
}
-/************\
-* RX Control *
-\************/
-
-/**
- * ath5k_hw_start_rx_pcu - Start RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Starts RX engine on PCU so that hw can process RXed frames
- * (ACK etc).
- *
- * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
- */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
-{
- AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/**
- * at5k_hw_stop_rx_pcu - Stop RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Stops RX engine on PCU
- *
- * TODO: Detach ANI here
- */
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
-{
- AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
/*
* Set multicast filter
*/
@@ -746,7 +763,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
* @ah: The &struct ath5k_hw
* @coverage_class: IEEE 802.11 coverage class number
*
- * Sets slot time, ACK timeout and CTS timeout for given coverage class.
+ * Sets IFS intervals and ACK/CTS timeouts for given coverage class.
*/
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
{
@@ -755,9 +772,175 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
int cts_timeout = ack_timeout;
- ath5k_hw_set_slot_time(ah, slot_time);
+ ath5k_hw_set_ifs_intervals(ah, slot_time);
ath5k_hw_set_ack_timeout(ah, ack_timeout);
ath5k_hw_set_cts_timeout(ah, cts_timeout);
ah->ah_coverage_class = coverage_class;
}
+
+/***************************\
+* Init/Start/Stop functions *
+\***************************/
+
+/**
+ * ath5k_hw_start_rx_pcu - Start RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Starts RX engine on PCU so that hw can process RXed frames
+ * (ACK etc).
+ *
+ * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
+ */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
+{
+ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * at5k_hw_stop_rx_pcu - Stop RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stops RX engine on PCU
+ */
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
+{
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * ath5k_hw_set_opmode - Set PCU operating mode
+ *
+ * @ah: The &struct ath5k_hw
+ * @op_mode: &enum nl80211_iftype operating mode
+ *
+ * Configure PCU for the various operating modes (AP/STA etc)
+ */
+int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ u32 pcu_reg, beacon_reg, low_id, high_id;
+
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
+
+ /* Preserve rest settings */
+ pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+ pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
+ | AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+
+ beacon_reg = 0;
+
+ switch (op_mode) {
+ case NL80211_IFTYPE_ADHOC:
+ pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
+ beacon_reg |= AR5K_BCR_ADHOC;
+ if (ah->ah_version == AR5K_AR5210)
+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+ break;
+
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
+ beacon_reg |= AR5K_BCR_AP;
+ if (ah->ah_version == AR5K_AR5210)
+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+ else
+ AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+ break;
+
+ case NL80211_IFTYPE_STATION:
+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ AR5K_STA_ID1_PWR_SV : 0);
+ case NL80211_IFTYPE_MONITOR:
+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ AR5K_STA_ID1_NO_PSPOLL : 0);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Set PCU registers
+ */
+ low_id = get_unaligned_le32(common->macaddr);
+ high_id = get_unaligned_le16(common->macaddr + 4);
+ ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+ ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+ /*
+ * Set Beacon Control Register on 5210
+ */
+ if (ah->ah_version == AR5K_AR5210)
+ ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+
+ return 0;
+}
+
+void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+ u8 mode)
+{
+ /* Set bssid and bssid mask */
+ ath5k_hw_set_bssid(ah);
+
+ /* Set PCU config */
+ ath5k_hw_set_opmode(ah, op_mode);
+
+ /* Write rate duration table only on AR5212 and if
+ * virtual interface has already been brought up
+ * XXX: rethink this after new mode changes to
+ * mac80211 are integrated */
+ if (ah->ah_version == AR5K_AR5212 &&
+ ah->ah_sc->nvifs)
+ ath5k_hw_write_rate_duration(ah);
+
+ /* Set RSSI/BRSSI thresholds
+ *
+ * Note: If we decide to set this value
+ * dynamicaly, have in mind that when AR5K_RSSI_THR
+ * register is read it might return 0x40 if we haven't
+ * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * So doing a save/restore procedure here isn't the right
+ * choice. Instead store it on ath5k_hw */
+ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES <<
+ AR5K_RSSI_THR_BMISS_S),
+ AR5K_RSSI_THR);
+
+ /* MIC QoS support */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+ ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+ ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
+ }
+
+ /* QoS NOACK Policy */
+ if (ah->ah_version == AR5K_AR5212) {
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+ AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
+ AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+ AR5K_QOS_NOACK);
+ }
+
+ /* Restore slot time and ACK timeouts */
+ if (ah->ah_coverage_class > 0)
+ ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
+
+ /* Set ACK bitrate mode (see ack_rates_high) */
+ if (ah->ah_version == AR5K_AR5212) {
+ u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
+ if (ah->ah_ack_bitrate_high)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+ }
+ return;
+}
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 219367884e64..78c26fdccad1 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -29,6 +29,95 @@
#include "rfbuffer.h"
#include "rfgain.h"
+
+/******************\
+* Helper functions *
+\******************/
+
+/*
+ * Get the PHY Chip revision
+ */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+{
+ unsigned int i;
+ u32 srev;
+ u16 ret;
+
+ /*
+ * Set the radio chip access register
+ */
+ switch (chan) {
+ case CHANNEL_2GHZ:
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
+ break;
+ case CHANNEL_5GHZ:
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ break;
+ default:
+ return 0;
+ }
+
+ mdelay(2);
+
+ /* ...wait until PHY is ready and read the selected radio revision */
+ ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
+
+ for (i = 0; i < 8; i++)
+ ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
+
+ if (ah->ah_version == AR5K_AR5210) {
+ srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
+ ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
+ } else {
+ srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
+ ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
+ ((srev & 0x0f) << 4), 8);
+ }
+
+ /* Reset to the 5GHz mode */
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+
+ return ret;
+}
+
+/*
+ * Check if a channel is supported
+ */
+bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+{
+ /* Check if the channel is in our supported range */
+ if (flags & CHANNEL_2GHZ) {
+ if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
+ (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
+ return true;
+ } else if (flags & CHANNEL_5GHZ)
+ if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
+ (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
+ return true;
+
+ return false;
+}
+
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
/*
* Used to modify RF Banks before writing them to AR5K_RF_BUFFER
*/
@@ -110,6 +199,90 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
return data;
}
+/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
+ *
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ /* Get exponent and mantissa and set it */
+ u32 coef_scaled, coef_exp, coef_man,
+ ds_coef_exp, ds_coef_man, clock;
+
+ BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+ !(channel->hw_value & CHANNEL_OFDM));
+
+ /* Get coefficient
+ * ALGO: coef = (5 * clock / carrier_freq) / 2
+ * we scale coef by shifting clock value by 24 for
+ * better precision since we use integers */
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ clock = 40 * 2;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ clock = 40 / 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ clock = 40 / 4;
+ break;
+ default:
+ clock = 40;
+ break;
+ }
+ coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+ /* Get exponent
+ * ALGO: coef_exp = 14 - highest set bit position */
+ coef_exp = ilog2(coef_scaled);
+
+ /* Doesn't make sense if it's zero*/
+ if (!coef_scaled || !coef_exp)
+ return -EINVAL;
+
+ /* Note: we've shifted coef_scaled by 24 */
+ coef_exp = 14 - (coef_exp - 24);
+
+
+ /* Get mantissa (significant digits)
+ * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
+ coef_man = coef_scaled +
+ (1 << (24 - coef_exp - 1));
+
+ /* Calculate delta slope coefficient exponent
+ * and mantissa (remove scaling) and set them on hw */
+ ds_coef_man = coef_man >> (24 - coef_exp);
+ ds_coef_exp = coef_exp - 16;
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+ return 0;
+}
+
+int ath5k_hw_phy_disable(struct ath5k_hw *ah)
+{
+ /*Just a try M.F.*/
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+
+ return 0;
+}
+
+
/**********************\
* RF Gain optimization *
\**********************/
@@ -436,10 +609,10 @@ done:
/* Write initial RF gain table to set the RF sensitivity
* this one works on all RF chips and has nothing to do
* with gain_F calibration */
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
{
const struct ath5k_ini_rfgain *ath5k_rfg;
- unsigned int i, size;
+ unsigned int i, size, index;
switch (ah->ah_radio) {
case AR5K_RF5111:
@@ -471,17 +644,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
return -EINVAL;
}
- switch (freq) {
- case AR5K_INI_RFGAIN_2GHZ:
- case AR5K_INI_RFGAIN_5GHZ:
- break;
- default:
- return -EINVAL;
- }
+ index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0;
for (i = 0; i < size; i++) {
AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+ ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
(u32)ath5k_rfg[i].rfg_register);
}
@@ -494,12 +661,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
* RF Registers setup *
\********************/
-
/*
* Setup RF registers by writing RF buffer on hw
*/
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- unsigned int mode)
+static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel, unsigned int mode)
{
const struct ath5k_rf_reg *rf_regs;
const struct ath5k_ini_rfbuffer *ini_rfb;
@@ -652,6 +818,11 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
g_step = &go->go_step[ah->ah_gain.g_step_idx];
+ /* Set turbo mode (N/A on RF5413) */
+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
+ (ah->ah_radio != AR5K_RF5413))
+ ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
+
/* Bank Modifications (chip-specific) */
if (ah->ah_radio == AR5K_RF5111) {
@@ -691,7 +862,23 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
AR5K_RF_PLO_SEL, true);
- /* TODO: Half/quarter channel support */
+ /* Tweak power detectors for half/quarter rate support */
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
+ u8 wait_i;
+
+ ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
+ AR5K_RF_WAIT_S, true);
+
+ wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
+ 0x1f : 0x10;
+
+ ath5k_hw_rfb_op(ah, rf_regs, wait_i,
+ AR5K_RF_WAIT_I, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 3,
+ AR5K_RF_MAX_TIME, true);
+
+ }
}
if (ah->ah_radio == AR5K_RF5112) {
@@ -789,8 +976,20 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
AR5K_RF_GAIN_I, true);
- /* TODO: Half/quarter channel support */
+ /* Tweak power detector for half/quarter rates */
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
+ u8 pd_delay;
+ pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
+ 0xf : 0x8;
+
+ ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
+ AR5K_RF_PD_PERIOD_A, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 0xf,
+ AR5K_RF_PD_DELAY_A, true);
+
+ }
}
if (ah->ah_radio == AR5K_RF5413 &&
@@ -822,24 +1021,6 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
\**************************/
/*
- * Check if a channel is supported
- */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
-{
- /* Check if the channel is in our supported range */
- if (flags & CHANNEL_2GHZ) {
- if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
- (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
- return true;
- } else if (flags & CHANNEL_5GHZ)
- if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
- (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
- return true;
-
- return false;
-}
-
-/*
* Convertion needed for RF5110
*/
static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
@@ -1045,7 +1226,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
/*
* Set a channel on the radio chip
*/
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
+static int ath5k_hw_channel(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
{
int ret;
/*
@@ -1092,8 +1274,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
}
ah->ah_current_channel = channel;
- ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
- ath5k_hw_set_clockrate(ah);
return 0;
}
@@ -1102,18 +1282,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
PHY calibration
\*****************/
-static int sign_extend(int val, const int nbits)
-{
- int order = BIT(nbits-1);
- return (val ^ order) - order;
-}
-
static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
{
s32 val;
val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
- return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9);
+ return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
}
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
@@ -1181,22 +1355,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
return;
}
- switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_T:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- case CHANNEL_TG:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- default:
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- }
-
+ ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
/* completed NF calibration, test threshold */
nf = ath5k_hw_read_measured_noise_floor(ah);
@@ -1425,31 +1584,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
return ret;
}
+
/***************************\
* Spur mitigation functions *
\***************************/
-bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
-{
- u8 refclk_freq;
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- refclk_freq = 40;
- else
- refclk_freq = 32;
-
- if ((channel->center_freq % refclk_freq != 0) &&
- ((channel->center_freq % refclk_freq < 10) ||
- (channel->center_freq % refclk_freq > 22)))
- return true;
- else
- return false;
-}
-
-void
+static void
ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
{
@@ -1478,7 +1618,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
/* XXX: Half/Quarter channels ?*/
- if (channel->hw_value & CHANNEL_TURBO)
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
spur_detection_window *= 2;
for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
@@ -1507,32 +1647,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
* Calculate deltas:
* spur_freq_sigma_delta -> spur_offset / sample_freq << 21
* spur_delta_phase -> spur_offset / chip_freq << 11
- * Note: Both values have 100KHz resolution
+ * Note: Both values have 100Hz resolution
*/
- /* XXX: Half/Quarter rate channels ? */
- switch (channel->hw_value) {
- case CHANNEL_A:
- /* Both sample_freq and chip_freq are 40MHz */
- spur_delta_phase = (spur_offset << 17) / 25;
- spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
- break;
- case CHANNEL_G:
- /* sample_freq -> 40MHz chip_freq -> 44MHz
- * (for b compatibility) */
- spur_freq_sigma_delta = (spur_offset << 8) / 55;
- spur_delta_phase = (spur_offset << 17) / 25;
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
- break;
- case CHANNEL_T:
- case CHANNEL_TG:
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
/* Both sample_freq and chip_freq are 80MHz */
spur_delta_phase = (spur_offset << 16) / 25;
spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
break;
+ case AR5K_BWMODE_10MHZ:
+ /* Both sample_freq and chip_freq are 20MHz (?) */
+ spur_delta_phase = (spur_offset << 18) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
+ case AR5K_BWMODE_5MHZ:
+ /* Both sample_freq and chip_freq are 10MHz (?) */
+ spur_delta_phase = (spur_offset << 19) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
default:
- return;
+ if (channel->hw_value == CHANNEL_A) {
+ /* Both sample_freq and chip_freq are 40MHz */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta =
+ (spur_delta_phase >> 10);
+ symbol_width =
+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ } else {
+ /* sample_freq -> 40MHz chip_freq -> 44MHz
+ * (for b compatibility) */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta =
+ (spur_offset << 8) / 55;
+ symbol_width =
+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ }
+ break;
}
/* Calculate pilot and magnitude masks */
@@ -1672,63 +1823,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
}
}
-/********************\
- Misc PHY functions
-\********************/
-
-int ath5k_hw_phy_disable(struct ath5k_hw *ah)
-{
- /*Just a try M.F.*/
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-
- return 0;
-}
-
-/*
- * Get the PHY Chip revision
- */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
-{
- unsigned int i;
- u32 srev;
- u16 ret;
-
- /*
- * Set the radio chip access register
- */
- switch (chan) {
- case CHANNEL_2GHZ:
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
- break;
- case CHANNEL_5GHZ:
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
- break;
- default:
- return 0;
- }
-
- mdelay(2);
-
- /* ...wait until PHY is ready and read the selected radio revision */
- ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
-
- for (i = 0; i < 8; i++)
- ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
-
- if (ah->ah_version == AR5K_AR5210) {
- srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
- ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
- } else {
- srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
- ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
- ((srev & 0x0f) << 4), 8);
- }
-
- /* Reset to the 5GHz mode */
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-
- return ret;
-}
/*****************\
* Antenna control *
@@ -1822,7 +1916,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
struct ieee80211_channel *channel = ah->ah_current_channel;
bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
bool use_def_for_sg;
- u8 def_ant, tx_ant, ee_mode;
+ int ee_mode;
+ u8 def_ant, tx_ant;
u32 sta_id1 = 0;
/* if channel is not initialized yet we can't set the antennas
@@ -1834,20 +1929,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
def_ant = ah->ah_def_ant;
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_T:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- case CHANNEL_TG:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- default:
+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
+ if (ee_mode < 0) {
ATH5K_ERR(ah->ah_sc,
"invalid channel: %d\n", channel->center_freq);
return;
@@ -2275,20 +2358,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- ctl_mode |= AR5K_CTL_11A;
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ ctl_mode |= AR5K_CTL_TURBO;
+ else
+ ctl_mode |= AR5K_CTL_11A;
break;
case CHANNEL_G:
- ctl_mode |= AR5K_CTL_11G;
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ ctl_mode |= AR5K_CTL_TURBOG;
+ else
+ ctl_mode |= AR5K_CTL_11G;
break;
case CHANNEL_B:
ctl_mode |= AR5K_CTL_11B;
break;
- case CHANNEL_T:
- ctl_mode |= AR5K_CTL_TURBO;
- break;
- case CHANNEL_TG:
- ctl_mode |= AR5K_CTL_TURBOG;
- break;
case CHANNEL_XR:
/* Fall through */
default:
@@ -2482,7 +2565,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
/* Write PCDAC values on hw */
static void
-ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+ath5k_write_pcdac_table(struct ath5k_hw *ah)
{
u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
int i;
@@ -2631,10 +2714,12 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
/* Write PDADC values on hw */
static void
-ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
- u8 pdcurves, u8 *pdg_to_idx)
+ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+ u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
+ u8 pdcurves = ee->ee_pd_gains[ee_mode];
u32 reg;
u8 i;
@@ -2844,8 +2929,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
(s16) pcinfo_R->freq,
pcinfo_L->max_pwr, pcinfo_R->max_pwr);
- /* We are ready to go, fill PCDAC/PDADC
- * table and write settings on hardware */
+ /* Fill PCDAC/PDADC table */
switch (type) {
case AR5K_PWRTABLE_LINEAR_PCDAC:
/* For RF5112 we can have one or two curves
@@ -2858,9 +2942,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
* match max power value with max
* table index */
ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
-
- /* Write settings on hw */
- ath5k_setup_pcdac_table(ah);
break;
case AR5K_PWRTABLE_PWR_TO_PCDAC:
/* We are done for RF5111 since it has only
@@ -2870,9 +2951,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
/* No rate powertable adjustment for RF5111 */
ah->ah_txpower.txp_min_idx = 0;
ah->ah_txpower.txp_offset = 0;
-
- /* Write settings on hw */
- ath5k_setup_pcdac_table(ah);
break;
case AR5K_PWRTABLE_PWR_TO_PDADC:
/* Set PDADC boundaries and fill
@@ -2880,9 +2958,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
ee->ee_pd_gains[ee_mode]);
- /* Write settings on hw */
- ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
-
/* Set txp.offset, note that table_min
* can be negative */
ah->ah_txpower.txp_offset = table_min[0];
@@ -2891,9 +2966,20 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
return -EINVAL;
}
+ ah->ah_txpower.txp_setup = true;
+
return 0;
}
+/* Write power table for current channel to hw */
+static void
+ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
+{
+ if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
+ ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
+ else
+ ath5k_write_pcdac_table(ah);
+}
/*
* Per-rate tx power setting
@@ -2982,7 +3068,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
/* Min/max in 0.25dB units */
ah->ah_txpower.txp_min_pwr = 2 * rates[7];
- ah->ah_txpower.txp_max_pwr = 2 * rates[0];
+ ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
ah->ah_txpower.txp_ofdm = rates[7];
}
@@ -2990,11 +3076,13 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
/*
* Set transmission power
*/
-int
+static int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower)
+ u8 txpower)
{
struct ath5k_rate_pcal_info rate_info;
+ struct ieee80211_channel *curr_channel = ah->ah_current_channel;
+ int ee_mode;
u8 type;
int ret;
@@ -3003,14 +3091,18 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* Reset TX power values */
- memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
- ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
- ah->ah_txpower.txp_min_pwr = 0;
- ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
+ if (ee_mode < 0) {
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
/* Initialize TX power table */
switch (ah->ah_radio) {
+ case AR5K_RF5110:
+ /* TODO */
+ return 0;
case AR5K_RF5111:
type = AR5K_PWRTABLE_PWR_TO_PCDAC;
break;
@@ -3028,10 +3120,26 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* FIXME: Only on channel/mode change */
- ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
- if (ret)
- return ret;
+ /*
+ * If we don't change channel/mode skip tx powertable calculation
+ * and use the cached one.
+ */
+ if (!ah->ah_txpower.txp_setup ||
+ (channel->hw_value != curr_channel->hw_value) ||
+ (channel->center_freq != curr_channel->center_freq)) {
+ /* Reset TX power values */
+ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+ ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+
+ /* Calculate the powertable */
+ ret = ath5k_setup_channel_powertable(ah, channel,
+ ee_mode, type);
+ if (ret)
+ return ret;
+ }
+
+ /* Write table on hw */
+ ath5k_write_channel_powertable(ah, ee_mode, type);
/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);
@@ -3086,31 +3194,219 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
{
- /*Just a try M.F.*/
- struct ieee80211_channel *channel = ah->ah_current_channel;
- u8 ee_mode;
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
+ "changing txpower to %d\n", txpower);
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_T:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- case CHANNEL_TG:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- default:
- ATH5K_ERR(ah->ah_sc,
- "invalid channel: %d\n", channel->center_freq);
+ return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
+}
+
+/*************\
+ Init function
+\*************/
+
+int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ u8 mode, bool fast)
+{
+ struct ieee80211_channel *curr_channel;
+ int ret, i;
+ u32 phy_tst1;
+ ret = 0;
+
+ /*
+ * Sanity check for fast flag
+ * Don't try fast channel change when changing modulation
+ * mode/band. We check for chip compatibility on
+ * ath5k_hw_reset.
+ */
+ curr_channel = ah->ah_current_channel;
+ if (fast && (channel->hw_value != curr_channel->hw_value))
return -EINVAL;
+
+ /*
+ * On fast channel change we only set the synth parameters
+ * while PHY is running, enable calibration and skip the rest.
+ */
+ if (fast) {
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
+ AR5K_PHY_RFBUS_REQ_REQUEST);
+ for (i = 0; i < 100; i++) {
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
+ break;
+ udelay(5);
+ }
+ /* Failed */
+ if (i >= 100)
+ return -EIO;
}
- ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
- "changing txpower to %d\n", txpower);
+ /*
+ * Set TX power
+ *
+ * Note: We need to do that before we set
+ * RF buffer settings on 5211/5212+ so that we
+ * properly set curve indices.
+ */
+ ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ?
+ ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
+ if (ret)
+ return ret;
+
+ /*
+ * For 5210 we do all initialization using
+ * initvals, so we don't have to modify
+ * any settings (5210 also only supports
+ * a/aturbo modes)
+ */
+ if ((ah->ah_version != AR5K_AR5210) && !fast) {
+
+ /*
+ * Write initial RF gain settings
+ * This should work for both 5111/5112
+ */
+ ret = ath5k_hw_rfgain_init(ah, channel->band);
+ if (ret)
+ return ret;
+
+ mdelay(1);
+
+ /*
+ * Write RF buffer
+ */
+ ret = ath5k_hw_rfregs_init(ah, channel, mode);
+ if (ret)
+ return ret;
+
+ /* Write OFDM timings on 5212*/
+ if (ah->ah_version == AR5K_AR5212 &&
+ channel->hw_value & CHANNEL_OFDM) {
+
+ ret = ath5k_hw_write_ofdm_timings(ah, channel);
+ if (ret)
+ return ret;
+
+ /* Spur info is available only from EEPROM versions
+ * greater than 5.3, but the EEPROM routines will use
+ * static values for older versions */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
+ ath5k_hw_set_spur_mitigation_filter(ah,
+ channel);
+ }
+
+ /*Enable/disable 802.11b mode on 5111
+ (enable 2111 frequency converter + CCK)*/
+ if (ah->ah_radio == AR5K_RF5111) {
+ if (mode == AR5K_MODE_11B)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_B_MODE);
+ else
+ AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_B_MODE);
+ }
+
+ } else if (ah->ah_version == AR5K_AR5210) {
+ mdelay(1);
+ /* Disable phy and wait */
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+ mdelay(1);
+ }
+
+ /* Set channel on PHY */
+ ret = ath5k_hw_channel(ah, channel);
+ if (ret)
+ return ret;
+
+ /*
+ * Enable the PHY and wait until completion
+ * This includes BaseBand and Synthesizer
+ * activation.
+ */
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+
+ /*
+ * On 5211+ read activation -> rx delay
+ * and use it.
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ u32 delay;
+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+ AR5K_PHY_RX_DELAY_M;
+ delay = (channel->hw_value & CHANNEL_CCK) ?
+ ((delay << 2) / 22) : (delay / 10);
+ if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
+ delay = delay << 1;
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
+ delay = delay << 2;
+ /* XXX: /2 on turbo ? Let's be safe
+ * for now */
+ udelay(100 + delay);
+ } else {
+ mdelay(1);
+ }
+
+ if (fast)
+ /*
+ * Release RF Bus grant
+ */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
+ AR5K_PHY_RFBUS_REQ_REQUEST);
+ else {
+ /*
+ * Perform ADC test to see if baseband is ready
+ * Set tx hold and check adc test register
+ */
+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+ ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+ for (i = 0; i <= 20; i++) {
+ if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+ break;
+ udelay(200);
+ }
+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
+ }
+
+ /*
+ * Start automatic gain control calibration
+ *
+ * During AGC calibration RX path is re-routed to
+ * a power detector so we don't receive anything.
+ *
+ * This method is used to calibrate some static offsets
+ * used together with on-the fly I/Q calibration (the
+ * one performed via ath5k_hw_phy_calibrate), which doesn't
+ * interrupt rx path.
+ *
+ * While rx path is re-routed to the power detector we also
+ * start a noise floor calibration to measure the
+ * card's noise floor (the noise we measure when we are not
+ * transmitting or receiving anything).
+ *
+ * If we are in a noisy environment, AGC calibration may time
+ * out and/or noise floor calibration might timeout.
+ */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
+
+ /* At the same time start I/Q calibration for QAM constellation
+ * -no need for CCK- */
+ ah->ah_calibration = false;
+ if (!(mode == AR5K_MODE_11B)) {
+ ah->ah_calibration = true;
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_RUN);
+ }
+
+ /* Wait for gain calibration to finish (we check for I/Q calibration
+ * during ath5k_phy_calibrate) */
+ if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_CAL, 0, false)) {
+ ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
+ channel->center_freq);
+ }
+
+ /* Restore antenna mode */
+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
- return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
+ return ret;
}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 84c717ded1c5..2c9c9e793d4e 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -25,14 +25,52 @@ Queue Control Unit, DFS Control Unit Functions
#include "debug.h"
#include "base.h"
+
+/******************\
+* Helper functions *
+\******************/
+
/*
- * Get properties for a transmit queue
+ * Get number of pending frames
+ * for a specific queue [5211+]
*/
-int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
- struct ath5k_txq_info *queue_info)
+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{
- memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
- return 0;
+ u32 pending;
+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+ /* Return if queue is declared inactive */
+ if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+ return false;
+
+ /* XXX: How about AR5K_CFG_TXCNT ? */
+ if (ah->ah_version == AR5K_AR5210)
+ return false;
+
+ pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
+ pending &= AR5K_QCU_STS_FRMPENDCNT;
+
+ /* It's possible to have no frames pending even if TXE
+ * is set. To indicate that q has not stopped return
+ * true */
+ if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ return true;
+
+ return pending;
+}
+
+/*
+ * Set a transmit queue inactive
+ */
+void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
+ return;
+
+ /* This queue will be skipped in further operations */
+ ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
+ /*For SIMR setup*/
+ AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
}
/*
@@ -50,6 +88,16 @@ static u16 ath5k_cw_validate(u16 cw_req)
}
/*
+ * Get properties for a transmit queue
+ */
+int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
+ struct ath5k_txq_info *queue_info)
+{
+ memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
+ return 0;
+}
+
+/*
* Set properties for a transmit queue
*/
int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
@@ -104,8 +152,8 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
/*
* Get queue by type
*/
- /*5210 only has 2 queues*/
- if (ah->ah_version == AR5K_AR5210) {
+ /* 5210 only has 2 queues */
+ if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
switch (queue_type) {
case AR5K_TX_QUEUE_DATA:
queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
@@ -172,113 +220,18 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
return queue;
}
-/*
- * Get number of pending frames
- * for a specific queue [5211+]
- */
-u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
-{
- u32 pending;
- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
- /* Return if queue is declared inactive */
- if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return false;
-
- /* XXX: How about AR5K_CFG_TXCNT ? */
- if (ah->ah_version == AR5K_AR5210)
- return false;
-
- pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
- pending &= AR5K_QCU_STS_FRMPENDCNT;
-
- /* It's possible to have no frames pending even if TXE
- * is set. To indicate that q has not stopped return
- * true */
- if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
- return true;
-
- return pending;
-}
-
-/*
- * Set a transmit queue inactive
- */
-void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
- if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
- return;
- /* This queue will be skipped in further operations */
- ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
- /*For SIMR setup*/
- AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
-}
+/*******************************\
+* Single QCU/DCU initialization *
+\*******************************/
/*
- * Set DFS properties for a transmit queue on DCU
+ * Set tx retry limits on DCU
*/
-int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
+ unsigned int queue)
{
u32 retry_lg, retry_sh;
- struct ath5k_txq_info *tq = &ah->ah_txq[queue];
-
- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
- tq = &ah->ah_txq[queue];
-
- if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return 0;
-
- if (ah->ah_version == AR5K_AR5210) {
- /* Only handle data queues, others will be ignored */
- if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
- return 0;
-
- /* Set Slot time */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
- AR5K_SLOT_TIME);
- /* Set ACK_CTS timeout */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
- AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
- /* Set Transmit Latency */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_TRANSMIT_LATENCY_TURBO :
- AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
-
- /* Set IFS0 */
- if (ah->ah_turbo) {
- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
- tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) <<
- AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
- AR5K_IFS0);
- } else {
- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
- tq->tqi_aifs * AR5K_INIT_SLOT_TIME) <<
- AR5K_IFS0_DIFS_S) |
- AR5K_INIT_SIFS, AR5K_IFS0);
- }
-
- /* Set IFS1 */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
- AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
- /* Set AR5K_PHY_SETTLING */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
- | 0x38 :
- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
- | 0x1C,
- AR5K_PHY_SETTLING);
- /* Set Frame Control Register */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
- AR5K_PHY_TURBO_SHORT | 0x2020) :
- (AR5K_PHY_FRAME_CTL_INI | 0x1020),
- AR5K_PHY_FRAME_CTL_5210);
- }
/*
* Calculate and set retry limits
@@ -293,8 +246,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
retry_sh = AR5K_INIT_SH_RETRY;
}
- /*No QCU/DCU [5210]*/
+ /* Single data queue on AR5210 */
if (ah->ah_version == AR5K_AR5210) {
+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];
+
+ if (queue > 0)
+ return;
+
ath5k_hw_reg_write(ah,
(tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
| AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
@@ -304,8 +262,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
| AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
| AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
AR5K_NODCU_RETRY_LMT);
+ /* DCU on AR5211+ */
} else {
- /*QCU/DCU [5211+]*/
ath5k_hw_reg_write(ah,
AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
AR5K_DCU_RETRY_LMT_SLG_RETRY) |
@@ -314,219 +272,393 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
+ }
+ return;
+}
- /*===Rest is also for QCU/DCU only [5211+]===*/
+/**
+ * ath5k_hw_reset_tx_queue - Initialize a single hw queue
+ *
+ * @ah The &struct ath5k_hw
+ * @queue The hw queue number
+ *
+ * Set DFS properties for the given transmit queue on DCU
+ * and configures all queue-specific parameters.
+ */
+int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];
- /*
- * Set contention window (cw_min/cw_max)
- * and arbitrated interframe space (aifs)...
- */
- ath5k_hw_reg_write(ah,
- AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
- AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
- AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
- AR5K_QUEUE_DFS_LOCAL_IFS(queue));
-
- /*
- * Set misc registers
- */
- /* Enable DCU early termination for this queue */
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_DCU_EARLY);
+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+ tq = &ah->ah_txq[queue];
+
+ /* Skip if queue inactive or if we are on AR5210
+ * that doesn't have QCU/DCU */
+ if ((ah->ah_version == AR5K_AR5210) ||
+ (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
+ return 0;
+
+ /*
+ * Set contention window (cw_min/cw_max)
+ * and arbitrated interframe space (aifs)...
+ */
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
+ AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
+ AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
+ AR5K_QUEUE_DFS_LOCAL_IFS(queue));
+
+ /*
+ * Set tx retry limits for this queue
+ */
+ ath5k_hw_set_tx_retry_limits(ah, queue);
+
+
+ /*
+ * Set misc registers
+ */
+
+ /* Enable DCU to wait for next fragment from QCU */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_FRAG_WAIT);
- /* Enable DCU to wait for next fragment from QCU */
+ /* On Maui and Spirit use the global seqnum on DCU */
+ if (ah->ah_mac_version < AR5K_SREV_AR5211)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- AR5K_DCU_MISC_FRAG_WAIT);
-
- /* On Maui and Spirit use the global seqnum on DCU */
- if (ah->ah_mac_version < AR5K_SREV_AR5211)
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- AR5K_DCU_MISC_SEQNUM_CTL);
-
- if (tq->tqi_cbr_period) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
- AR5K_QCU_CBRCFG_INTVAL) |
- AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
- AR5K_QCU_CBRCFG_ORN_THRES),
- AR5K_QUEUE_CBRCFG(queue));
+ AR5K_DCU_MISC_SEQNUM_CTL);
+
+ /* Constant bit rate period */
+ if (tq->tqi_cbr_period) {
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
+ AR5K_QCU_CBRCFG_INTVAL) |
+ AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
+ AR5K_QCU_CBRCFG_ORN_THRES),
+ AR5K_QUEUE_CBRCFG(queue));
+
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_FRSHED_CBR);
+
+ if (tq->tqi_cbr_overflow_limit)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_CBR);
- if (tq->tqi_cbr_overflow_limit)
- AR5K_REG_ENABLE_BITS(ah,
- AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_CBR_THRES_ENABLE);
- }
+ }
- if (tq->tqi_ready_time &&
- (tq->tqi_type != AR5K_TX_QUEUE_CAB))
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
- AR5K_QCU_RDYTIMECFG_INTVAL) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
-
- if (tq->tqi_burst_time) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
- AR5K_DCU_CHAN_TIME_DUR) |
- AR5K_DCU_CHAN_TIME_ENABLE,
- AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
-
- if (tq->tqi_flags
- & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
- AR5K_REG_ENABLE_BITS(ah,
- AR5K_QUEUE_MISC(queue),
+ /* Ready time interval */
+ if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
+ AR5K_QCU_RDYTIMECFG_INTVAL) |
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
+
+ if (tq->tqi_burst_time) {
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
+ AR5K_DCU_CHAN_TIME_DUR) |
+ AR5K_DCU_CHAN_TIME_ENABLE,
+ AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_RDY_VEOL_POLICY);
- }
+ }
- if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
- AR5K_QUEUE_DFS_MISC(queue));
+ /* Enable/disable Post frame backoff */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
+ AR5K_QUEUE_DFS_MISC(queue));
- if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
- AR5K_QUEUE_DFS_MISC(queue));
+ /* Enable/disable fragmentation burst backoff */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
+ AR5K_QUEUE_DFS_MISC(queue));
- /*
- * Set registers by queue type
- */
- switch (tq->tqi_type) {
- case AR5K_TX_QUEUE_BEACON:
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ /*
+ * Set registers by queue type
+ */
+ switch (tq->tqi_type) {
+ case AR5K_TX_QUEUE_BEACON:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_FRSHED_DBA_GT |
AR5K_QCU_MISC_CBREXP_BCN_DIS |
AR5K_QCU_MISC_BCN_ENABLE);
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
AR5K_DCU_MISC_ARBLOCK_IGNORE |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
- break;
+ break;
- case AR5K_TX_QUEUE_CAB:
- /* XXX: use BCN_SENT_GT, if we can figure out how */
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_DBA_GT |
- AR5K_QCU_MISC_CBREXP_DIS |
- AR5K_QCU_MISC_CBREXP_BCN_DIS);
+ case AR5K_TX_QUEUE_CAB:
+ /* XXX: use BCN_SENT_GT, if we can figure out how */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_QCU_MISC_CBREXP_DIS |
+ AR5K_QCU_MISC_CBREXP_BCN_DIS);
- ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
- (AR5K_TUNE_SW_BEACON_RESP -
- AR5K_TUNE_DMA_BEACON_RESP) -
+ ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
+ (AR5K_TUNE_SW_BEACON_RESP -
+ AR5K_TUNE_DMA_BEACON_RESP) -
AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
- AR5K_DCU_MISC_ARBLOCK_CTL_S));
- break;
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+ AR5K_DCU_MISC_ARBLOCK_CTL_S));
+ break;
- case AR5K_TX_QUEUE_UAPSD:
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_CBREXP_DIS);
- break;
+ case AR5K_TX_QUEUE_UAPSD:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_CBREXP_DIS);
+ break;
- case AR5K_TX_QUEUE_DATA:
- default:
+ case AR5K_TX_QUEUE_DATA:
+ default:
break;
- }
-
- /* TODO: Handle frame compression */
-
- /*
- * Enable interrupts for this tx queue
- * in the secondary interrupt mask registers
- */
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
-
- /* Update secondary interrupt mask registers */
-
- /* Filter out inactive queues */
- ah->ah_txq_imr_txok &= ah->ah_txq_status;
- ah->ah_txq_imr_txerr &= ah->ah_txq_status;
- ah->ah_txq_imr_txurn &= ah->ah_txq_status;
- ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
- ah->ah_txq_imr_txeol &= ah->ah_txq_status;
- ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
- ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
- ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
- ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
-
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
- AR5K_SIMR0_QCU_TXOK) |
- AR5K_REG_SM(ah->ah_txq_imr_txdesc,
- AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
- AR5K_SIMR1_QCU_TXERR) |
- AR5K_REG_SM(ah->ah_txq_imr_txeol,
- AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
- /* Update simr2 but don't overwrite rest simr2 settings */
- AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
- AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
- AR5K_REG_SM(ah->ah_txq_imr_txurn,
- AR5K_SIMR2_QCU_TXURN));
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
- AR5K_SIMR3_QCBRORN) |
- AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
- AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
- AR5K_SIMR4_QTRIG), AR5K_SIMR4);
- /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
- AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
- /* No queue has TXNOFRM enabled, disable the interrupt
- * by setting AR5K_TXNOFRM to zero */
- if (ah->ah_txq_imr_nofrm == 0)
- ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
-
- /* Set QCU mask for this DCU to save power */
- AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
}
+ /* TODO: Handle frame compression */
+
+ /*
+ * Enable interrupts for this tx queue
+ * in the secondary interrupt mask registers
+ */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
+
+ /* Update secondary interrupt mask registers */
+
+ /* Filter out inactive queues */
+ ah->ah_txq_imr_txok &= ah->ah_txq_status;
+ ah->ah_txq_imr_txerr &= ah->ah_txq_status;
+ ah->ah_txq_imr_txurn &= ah->ah_txq_status;
+ ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
+ ah->ah_txq_imr_txeol &= ah->ah_txq_status;
+ ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
+ ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
+ ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
+ ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
+ AR5K_SIMR0_QCU_TXOK) |
+ AR5K_REG_SM(ah->ah_txq_imr_txdesc,
+ AR5K_SIMR0_QCU_TXDESC),
+ AR5K_SIMR0);
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
+ AR5K_SIMR1_QCU_TXERR) |
+ AR5K_REG_SM(ah->ah_txq_imr_txeol,
+ AR5K_SIMR1_QCU_TXEOL),
+ AR5K_SIMR1);
+
+ /* Update SIMR2 but don't overwrite rest simr2 settings */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
+ AR5K_REG_SM(ah->ah_txq_imr_txurn,
+ AR5K_SIMR2_QCU_TXURN));
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
+ AR5K_SIMR3_QCBRORN) |
+ AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
+ AR5K_SIMR3_QCBRURN),
+ AR5K_SIMR3);
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
+ AR5K_SIMR4_QTRIG), AR5K_SIMR4);
+
+ /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
+ AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
+
+ /* No queue has TXNOFRM enabled, disable the interrupt
+ * by setting AR5K_TXNOFRM to zero */
+ if (ah->ah_txq_imr_nofrm == 0)
+ ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+ /* Set QCU mask for this DCU to save power */
+ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
+
return 0;
}
-/*
- * Set slot time on DCU
+
+/**************************\
+* Global QCU/DCU functions *
+\**************************/
+
+/**
+ * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU
+ *
+ * @ah The &struct ath5k_hw
+ * @slot_time Slot time in us
+ *
+ * Sets the global IFS intervals on DCU (also works on AR5210) for
+ * the given slot time and the current bwmode.
*/
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
+int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct ieee80211_rate *rate;
+ u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
return -EINVAL;
- if (ah->ah_version == AR5K_AR5210)
- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
+ sifs = ath5k_hw_get_default_sifs(ah);
+ sifs_clock = ath5k_hw_htoclock(ah, sifs);
+
+ /* EIFS
+ * Txtime of ack at lowest rate + SIFS + DIFS
+ * (DIFS = SIFS + 2 * Slot time)
+ *
+ * Note: HAL has some predefined values for EIFS
+ * Turbo: (37 + 2 * 6)
+ * Default: (74 + 2 * 9)
+ * Half: (149 + 2 * 13)
+ * Quarter: (298 + 2 * 21)
+ *
+ * (74 + 2 * 6) for AR5210 default and turbo !
+ *
+ * According to the formula we have
+ * ack_tx_time = 25 for turbo and
+ * ack_tx_time = 42.5 * clock multiplier
+ * for default/half/quarter.
+ *
+ * This can't be right, 42 is what we would get
+ * from ath5k_hw_get_frame_dur_for_bwmode or
+ * ieee80211_generic_frame_duration for zero frame
+ * length and without SIFS !
+ *
+ * Also we have different lowest rate for 802.11a
+ */
+ if (channel->hw_value & CHANNEL_5GHZ)
+ rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
else
- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
+ rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
+
+ ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+
+ /* ack_tx_time includes an SIFS already */
+ eifs = ack_tx_time + sifs + 2 * slot_time;
+ eifs_clock = ath5k_hw_htoclock(ah, eifs);
+
+ /* Set IFS settings on AR5210 */
+ if (ah->ah_version == AR5K_AR5210) {
+ u32 pifs, pifs_clock, difs, difs_clock;
+
+ /* Set slot time */
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
+
+ /* Set EIFS */
+ eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
+
+ /* PIFS = Slot time + SIFS */
+ pifs = slot_time + sifs;
+ pifs_clock = ath5k_hw_htoclock(ah, pifs);
+ pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
+
+ /* DIFS = SIFS + 2 * Slot time */
+ difs = sifs + 2 * slot_time;
+ difs_clock = ath5k_hw_htoclock(ah, difs);
+
+ /* Set SIFS/DIFS */
+ ath5k_hw_reg_write(ah, (difs_clock <<
+ AR5K_IFS0_DIFS_S) | sifs_clock,
+ AR5K_IFS0);
+
+ /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
+ ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
+ (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
+ AR5K_IFS1);
+
+ return 0;
+ }
+
+ /* Set IFS slot time */
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
+
+ /* Set EIFS interval */
+ ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
+
+ /* Set SIFS interval in usecs */
+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
+ sifs);
+
+ /* Set SIFS interval in clock cycles */
+ ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
return 0;
}
+
+int ath5k_hw_init_queues(struct ath5k_hw *ah)
+{
+ int i, ret;
+
+ /* TODO: HW Compression support for data queues */
+ /* TODO: Burst prefetch for data queues */
+
+ /*
+ * Reset queues and start beacon timers at the end of the reset routine
+ * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+ * Note: If we want we can assign multiple qcus on one dcu.
+ */
+ if (ah->ah_version != AR5K_AR5210)
+ for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
+ ret = ath5k_hw_reset_tx_queue(ah, i);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc,
+ "failed to reset TX queue #%d\n", i);
+ return ret;
+ }
+ }
+ else
+ /* No QCU/DCU on AR5210, just set tx
+ * retry limits. We set IFS parameters
+ * on ath5k_hw_set_ifs_intervals */
+ ath5k_hw_set_tx_retry_limits(ah, 0);
+
+ /* Set the turbo flag when operating on 40MHz */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
+
+ /* If we didn't set IFS timings through
+ * ath5k_hw_set_coverage_class make sure
+ * we set them here */
+ if (!ah->ah_coverage_class) {
+ unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
+ ath5k_hw_set_ifs_intervals(ah, slot_time);
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index ca79ecd832fd..7ad05d401ab5 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -787,6 +787,7 @@
#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
+#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
@@ -1311,7 +1312,7 @@
#define AR5K_IFS1_EIFS 0x03fff000
#define AR5K_IFS1_EIFS_S 12
#define AR5K_IFS1_CS_EN 0x04000000
-
+#define AR5K_IFS1_CS_EN_S 26
/*
* CFP duration register
@@ -2058,6 +2059,7 @@
#define AR5K_PHY_SCAL 0x9878
#define AR5K_PHY_SCAL_32MHZ 0x0000000e
+#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008
#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
@@ -2244,6 +2246,8 @@
#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
/*---[5111+]---*/
+#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */
+#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0
#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */
#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */
@@ -2558,3 +2562,28 @@
*/
#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
+
+/*
+ * Platform registers for WiSoC
+ */
+#define AR5K_AR5312_RESET 0xbc003020
+#define AR5K_AR5312_RESET_BB0_COLD 0x00000004
+#define AR5K_AR5312_RESET_BB1_COLD 0x00000200
+#define AR5K_AR5312_RESET_WMAC0 0x00002000
+#define AR5K_AR5312_RESET_BB0_WARM 0x00004000
+#define AR5K_AR5312_RESET_WMAC1 0x00020000
+#define AR5K_AR5312_RESET_BB1_WARM 0x00040000
+
+#define AR5K_AR5312_ENABLE 0xbc003080
+#define AR5K_AR5312_ENABLE_WLAN0 0x00000001
+#define AR5K_AR5312_ENABLE_WLAN1 0x00000008
+
+#define AR5K_AR2315_RESET 0xb1000004
+#define AR5K_AR2315_RESET_WMAC 0x00000001
+#define AR5K_AR2315_RESET_BB_WARM 0x00000002
+
+#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008
+#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002
+
+#define AR5K_AR2315_BYTESWAP 0xb100000c
+#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 5b179d01f97d..84206898f77d 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -27,11 +27,17 @@
#include <linux/pci.h> /* To determine if a card is pci-e */
#include <linux/log2.h>
+#include <linux/platform_device.h>
#include "ath5k.h"
#include "reg.h"
#include "base.h"
#include "debug.h"
+
+/******************\
+* Helper functions *
+\******************/
+
/*
* Check if a register write has been completed
*/
@@ -53,146 +59,267 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
return (i <= 0) ? -EAGAIN : 0;
}
+
+/*************************\
+* Clock related functions *
+\*************************/
+
/**
- * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ * ath5k_hw_htoclock - Translate usec to hw clock units
*
- * @ah: the &struct ath5k_hw
- * @channel: the currently set channel upon reset
- *
- * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
- * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
+ * @ah: The &struct ath5k_hw
+ * @usec: value in microseconds
+ */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return usec * common->clockrate;
+}
+
+/**
+ * ath5k_hw_clocktoh - Translate hw clock units to usec
+ * @clock: value in hw clock units
+ */
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return clock / common->clockrate;
+}
+
+/**
+ * ath5k_hw_init_core_clock - Initialize core clock
*
- * Since delta slope is floating point we split it on its exponent and
- * mantissa and provide these values on hw.
+ * @ah The &struct ath5k_hw
*
- * For more infos i think this patent is related
- * http://www.freepatentsonline.com/7184495.html
+ * Initialize core clock parameters (usec, usec32, latencies etc).
*/
-static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
+static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
{
- /* Get exponent and mantissa and set it */
- u32 coef_scaled, coef_exp, coef_man,
- ds_coef_exp, ds_coef_man, clock;
-
- BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
- !(channel->hw_value & CHANNEL_OFDM));
-
- /* Get coefficient
- * ALGO: coef = (5 * clock / carrier_freq) / 2
- * we scale coef by shifting clock value by 24 for
- * better precision since we use integers */
- /* TODO: Half/quarter rate */
- clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
-
- /* Get exponent
- * ALGO: coef_exp = 14 - highest set bit position */
- coef_exp = ilog2(coef_scaled);
-
- /* Doesn't make sense if it's zero*/
- if (!coef_scaled || !coef_exp)
- return -EINVAL;
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ struct ath_common *common = ath5k_hw_common(ah);
+ u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;
+
+ /*
+ * Set core clock frequency
+ */
+ if (channel->hw_value & CHANNEL_5GHZ)
+ clock = 40; /* 802.11a */
+ else if (channel->hw_value & CHANNEL_CCK)
+ clock = 22; /* 802.11b */
+ else
+ clock = 44; /* 802.11g */
+
+ /* Use clock multiplier for non-default
+ * bwmode */
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ clock *= 2;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ clock /= 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ clock /= 4;
+ break;
+ default:
+ break;
+ }
- /* Note: we've shifted coef_scaled by 24 */
- coef_exp = 14 - (coef_exp - 24);
+ common->clockrate = clock;
+ /*
+ * Set USEC parameters
+ */
+ /* Set USEC counter on PCU*/
+ usec = clock - 1;
+ usec = AR5K_REG_SM(usec, AR5K_USEC_1);
- /* Get mantissa (significant digits)
- * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
- coef_man = coef_scaled +
- (1 << (24 - coef_exp - 1));
+ /* Set usec duration on DCU */
+ if (ah->ah_version != AR5K_AR5210)
+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_USEC_DUR,
+ clock);
- /* Calculate delta slope coefficient exponent
- * and mantissa (remove scaling) and set them on hw */
- ds_coef_man = coef_man >> (24 - coef_exp);
- ds_coef_exp = coef_exp - 16;
+ /* Set 32MHz USEC counter */
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_radio == AR5K_RF2317))
+ /* Remain on 40MHz clock ? */
+ sclock = 40 - 1;
+ else
+ sclock = 32 - 1;
+ sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+ /*
+ * Set tx/rx latencies
+ */
+ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+ txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
- return 0;
-}
+ /*
+ * 5210 initvals don't include usec settings
+ * so we need to use magic values here for
+ * tx/rx latencies
+ */
+ if (ah->ah_version == AR5K_AR5210) {
+ /* same for turbo */
+ txlat = AR5K_INIT_TX_LATENCY_5210;
+ rxlat = AR5K_INIT_RX_LATENCY_5210;
+ }
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ /* 5311 has different tx/rx latency masks
+ * from 5211, since we deal 5311 the same
+ * as 5211 when setting initvals, shift
+ * values here to their proper locations
+ *
+ * Note: Initvals indicate tx/rx/ latencies
+ * are the same for turbo mode */
+ txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);
+ rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);
+ } else
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_10MHZ:
+ txlat = AR5K_REG_SM(txlat * 2,
+ AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ txlat = AR5K_REG_SM(txlat * 4,
+ AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;
+ break;
+ case AR5K_BWMODE_40MHZ:
+ txlat = AR5K_INIT_TX_LAT_MIN;
+ rxlat = AR5K_REG_SM(rxlat / 2,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
+ break;
+ default:
+ break;
+ }
-/*
- * index into rates for control rates, we can set it up like this because
- * this is only used for AR5212 and we know it supports G mode
- */
-static const unsigned int control_rates[] =
- { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
+ usec_reg = (usec | sclock | txlat | rxlat);
+ ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);
-/**
- * ath5k_hw_write_rate_duration - fill rate code to duration table
- *
- * @ah: the &struct ath5k_hw
- * @mode: one of enum ath5k_driver_mode
- *
- * Write the rate code to duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
- * the hardware, based on current mode, for each rate. The rates which are
- * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
- * different rate code so we write their value twice (one for long preample
- * and one for short).
+ /* On 5112 set tx frane to tx data start delay */
+ if (ah->ah_radio == AR5K_RF5112) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,
+ AR5K_PHY_RF_CTL2_TXF2TXD_START,
+ txf2txs);
+ }
+}
+
+/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
*
- * Note: Band doesn't matter here, if we set the values for OFDM it works
- * on both a and g modes. So all we have to do is set values for all g rates
- * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
- * quarter rate mode, we need to use another set of bitrates (that's why we
- * need the mode parameter) but we don't handle these proprietary modes yet.
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ * 123 - 127) require delay on access.
*/
-static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
- unsigned int mode)
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
{
- struct ath5k_softc *sc = ah->ah_sc;
- struct ieee80211_rate *rate;
- unsigned int i;
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 scal, spending;
+
+ /* Only set 32KHz settings if we have an external
+ * 32KHz crystal present */
+ if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+ AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+ enable) {
- /* Write rate duration table */
- for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
- u32 reg;
- u16 tx_time;
+ /* 1 usec/cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
- rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
+ /* Set baseband sleep control registers
+ * and sleep control rate */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
- /* Set ACK timeout */
- reg = AR5K_RATE_DUR(rate->hw_value);
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+ } else {
+ ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+ }
- /* An ACK frame consists of 10 bytes. If you add the FCS,
- * which ieee80211_generic_frame_duration() adds,
- * its 14 bytes. Note we use the control rate and not the
- * actual rate for this rate. See mac80211 tx.c
- * ieee80211_duration() for a brief description of
- * what rate we should choose to TX ACKs. */
- tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
- NULL, 10, rate));
+ /* Enable sleep clock operation */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
- ath5k_hw_reg_write(ah, tx_time, reg);
+ } else {
- if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
- continue;
+ /* Disable sleep clock operation and
+ * restore default parameters */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
- /*
- * We're not distinguishing short preamble here,
- * This is true, all we'll get is a longer value here
- * which is not necessarilly bad. We could use
- * export ieee80211_frame_duration() but that needs to be
- * fixed first to be properly used by mac802111 drivers:
- *
- * - remove erp stuff and let the routine figure ofdm
- * erp rates
- * - remove passing argument ieee80211_local as
- * drivers don't have access to it
- * - move drivers using ieee80211_generic_frame_duration()
- * to this
- */
- ath5k_hw_reg_write(ah, tx_time,
- reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+ /* Set DAC/ADC delays */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ee->ee_is_hb63)
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
}
}
+
+/*********************\
+* Reset/Sleep control *
+\*********************/
+
/*
* Reset chipset
*/
@@ -236,6 +363,64 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
}
/*
+ * Reset AHB chipset
+ * AR5K_RESET_CTL_PCU flag resets WMAC
+ * AR5K_RESET_CTL_BASEBAND flag resets WBB
+ */
+static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
+{
+ u32 mask = flags ? flags : ~0U;
+ volatile u32 *reg;
+ u32 regval;
+ u32 val = 0;
+
+ /* ah->ah_mac_srev is not available at this point yet */
+ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
+ reg = (u32 *) AR5K_AR2315_RESET;
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR2315_RESET_WMAC;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR2315_RESET_BB_WARM;
+ } else {
+ reg = (u32 *) AR5K_AR5312_RESET;
+ if (to_platform_device(ah->ah_sc->dev)->id == 0) {
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR5312_RESET_WMAC0;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB0_COLD |
+ AR5K_AR5312_RESET_BB0_WARM;
+ } else {
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR5312_RESET_WMAC1;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB1_COLD |
+ AR5K_AR5312_RESET_BB1_WARM;
+ }
+ }
+
+ /* Put BB/MAC into reset */
+ regval = __raw_readl(reg);
+ __raw_writel(regval | val, reg);
+ regval = __raw_readl(reg);
+ udelay(100);
+
+ /* Bring BB/MAC out of reset */
+ __raw_writel(regval & ~val, reg);
+ regval = __raw_readl(reg);
+
+ /*
+ * Reset configuration register (for hw byte-swap). Note that this
+ * is only set for big endian. We do the necessary magic in
+ * AR5K_INIT_CFG.
+ */
+ if ((flags & AR5K_RESET_CTL_PCU) == 0)
+ ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
+
+ return 0;
+}
+
+
+/*
* Sleep control
*/
static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
@@ -334,6 +519,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
u32 bus_flags;
int ret;
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ return 0;
+
/* Make sure device is awake */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
@@ -349,7 +537,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -378,7 +566,6 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
/*
* Bring up MAC + PHY Chips and program PLL
- * TODO: Half/Quarter rate support
*/
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
{
@@ -390,11 +577,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode = 0;
clock = 0;
- /* Wakeup the device */
- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
- return ret;
+ if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {
+ /* Wakeup the device */
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+ return ret;
+ }
}
/*
@@ -405,7 +594,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -413,8 +602,12 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
mdelay(2);
} else {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_BASEBAND | bus_flags);
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND);
+ else
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
}
if (ret) {
@@ -429,9 +622,15 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return ret;
}
- /* ...clear reset control register and pull device out of
- * warm reset */
- if (ath5k_hw_nic_reset(ah, 0)) {
+ /* ...reset configuration regiter on Wisoc ...
+ * ...clear reset control register and pull device out of
+ * warm reset on others */
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ ret = ath5k_hw_wisoc_reset(ah, 0);
+ else
+ ret = ath5k_hw_nic_reset(ah, 0);
+
+ if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
return -EIO;
}
@@ -466,7 +665,8 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
* CCK headers) operation. We need to test
* this, 5211 might support ofdm-only g after
* all, there are also initial register values
- * in the code for g mode (see initvals.c). */
+ * in the code for g mode (see initvals.c).
+ */
if (ah->ah_version == AR5K_AR5211)
mode |= AR5K_PHY_MODE_MOD_OFDM;
else
@@ -479,6 +679,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
} else if (flags & CHANNEL_5GHZ) {
mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+ /* Different PLL setting for 5413 */
if (ah->ah_radio == AR5K_RF5413)
clock = AR5K_PHY_PLL_40MHZ_5413;
else
@@ -496,12 +697,29 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return -EINVAL;
}
- if (flags & CHANNEL_TURBO)
- turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
+ /*XXX: Can bwmode be used with dynamic mode ?
+ * (I don't think it supports 44MHz) */
+ /* On 2425 initvals TURBO_SHORT is not pressent */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
+ turbo = AR5K_PHY_TURBO_MODE |
+ (ah->ah_radio == AR5K_RF2425) ? 0 :
+ AR5K_PHY_TURBO_SHORT;
+ } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
+ if (ah->ah_radio == AR5K_RF5413) {
+ mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
+ AR5K_PHY_MODE_HALF_RATE :
+ AR5K_PHY_MODE_QUARTER_RATE;
+ } else if (ah->ah_version == AR5K_AR5212) {
+ clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
+ AR5K_PHY_PLL_HALF_RATE :
+ AR5K_PHY_PLL_QUARTER_RATE;
+ }
+ }
+
} else { /* Reset the device */
/* ...enable Atheros turbo mode if requested */
- if (flags & CHANNEL_TURBO)
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
AR5K_PHY_TURBO);
}
@@ -522,107 +740,10 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return 0;
}
-/*
- * If there is an external 32KHz crystal available, use it
- * as ref. clock instead of 32/40MHz clock and baseband clocks
- * to save power during sleep or restore normal 32/40MHz
- * operation.
- *
- * XXX: When operating on 32KHz certain PHY registers (27 - 31,
- * 123 - 127) require delay on access.
- */
-static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
-{
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 scal, spending, usec32;
- /* Only set 32KHz settings if we have an external
- * 32KHz crystal present */
- if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
- AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
- enable) {
-
- /* 1 usec/cycle */
- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
- /* Set up tsf increment on each cycle */
- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
-
- /* Set baseband sleep control registers
- * and sleep control rate */
- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- spending = 0x14;
- else
- spending = 0x18;
- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
- ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
- } else {
- ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
- }
-
- /* Enable sleep clock operation */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_EN);
-
- } else {
-
- /* Disable sleep clock operation and
- * restore default parameters */
- AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_EN);
-
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
-
- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
- ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
-
- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
- scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ee->ee_is_hb63)
- scal = AR5K_PHY_SCAL_32MHZ_HB63;
- else
- scal = AR5K_PHY_SCAL_32MHZ;
- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-
- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- spending = 0x14;
- else
- spending = 0x18;
- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413))
- usec32 = 39;
- else
- usec32 = 31;
- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
-
- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
- }
-}
+/**************************************\
+* Post-initvals register modifications *
+\**************************************/
/* TODO: Half/Quarter rate */
static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
@@ -663,22 +784,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
AR5K_TXCFG_DCU_DBL_BUF_DIS);
- /* Set DAC/ADC delays */
- if (ah->ah_version == AR5K_AR5212) {
- u32 scal;
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
- scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ee->ee_is_hb63)
- scal = AR5K_PHY_SCAL_32MHZ_HB63;
- else
- scal = AR5K_PHY_SCAL_32MHZ;
- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
- }
-
/* Set fast ADC */
if ((ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ (ah->ah_radio == AR5K_RF2317) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
u32 fast_adc = true;
if (channel->center_freq == 2462 ||
@@ -706,33 +815,68 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
}
if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
- u32 usec_reg;
- /* 5311 has different tx/rx latency masks
- * from 5211, since we deal 5311 the same
- * as 5211 when setting initvals, shift
- * values here to their proper locations */
- usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
- ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
- AR5K_USEC_32 |
- AR5K_USEC_TX_LATENCY_5211 |
- AR5K_REG_SM(29,
- AR5K_USEC_RX_LATENCY_5210)),
- AR5K_USEC_5211);
/* Clear QCU/DCU clock gating register */
ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
/* Set DAC/ADC delays */
- ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,
+ AR5K_PHY_SCAL);
/* Enable PCU FIFO corruption ECO */
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_ECO_ENABLE);
}
+
+ if (ah->ah_bwmode) {
+ /* Increase PHY switch and AGC settling time
+ * on turbo mode (ath5k_hw_commit_eeprom_settings
+ * will override settling time if available) */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_AGC,
+ AR5K_AGC_SETTLING_TURBO);
+
+ /* XXX: Initvals indicate we only increase
+ * switch time on AR5212, 5211 and 5210
+ * only change agc time (bug?) */
+ if (ah->ah_version == AR5K_AR5212)
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ AR5K_SWITCH_SETTLING_TURBO);
+
+ if (ah->ah_version == AR5K_AR5210) {
+ /* Set Frame Control Register */
+ ath5k_hw_reg_write(ah,
+ (AR5K_PHY_FRAME_CTL_INI |
+ AR5K_PHY_TURBO_MODE |
+ AR5K_PHY_TURBO_SHORT | 0x2020),
+ AR5K_PHY_FRAME_CTL_5210);
+ }
+ /* On 5413 PHY force window length for half/quarter rate*/
+ } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&
+ (ah->ah_mac_srev <= AR5K_SREV_AR5414)) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,
+ AR5K_PHY_FRAME_CTL_WIN_LEN,
+ 3);
+ }
+ } else if (ah->ah_version == AR5K_AR5210) {
+ /* Set Frame Control Register for normal operation */
+ ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),
+ AR5K_PHY_FRAME_CTL_5210);
+ }
}
static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, u8 ee_mode)
+ struct ieee80211_channel *channel)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
s16 cck_ofdm_pwr_delta;
+ u8 ee_mode;
+
+ /* TODO: Add support for AR5210 EEPROM */
+ if (ah->ah_version == AR5K_AR5210)
+ return;
+
+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
/* Adjust power delta for channel 14 */
if (channel->center_freq == 2484)
@@ -772,7 +916,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
AR5K_PHY_NFTHRES);
- if ((channel->hw_value & CHANNEL_TURBO) &&
+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
(ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
/* Switch settling time (Turbo) */
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
@@ -870,143 +1014,172 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
}
-/*
- * Main reset function
- */
+
+/*********************\
+* Main reset function *
+\*********************/
+
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
- struct ieee80211_channel *channel, bool change_channel)
+ struct ieee80211_channel *channel, bool fast, bool skip_pcu)
{
- struct ath_common *common = ath5k_hw_common(ah);
- u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;
- u32 phy_tst1;
- u8 mode, freq, ee_mode;
+ u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
+ u8 mode;
int i, ret;
- ee_mode = 0;
- staid1_flags = 0;
tsf_up = 0;
tsf_lo = 0;
- freq = 0;
mode = 0;
/*
- * Save some registers before a reset
+ * Sanity check for fast flag
+ * Fast channel change only available
+ * on AR2413/AR5413.
*/
- /*DCU/Antenna selection not available on 5210*/
- if (ah->ah_version != AR5K_AR5210) {
+ if (fast && (ah->ah_radio != AR5K_RF2413) &&
+ (ah->ah_radio != AR5K_RF5413))
+ fast = 0;
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- mode = AR5K_MODE_11A;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- mode = AR5K_MODE_11G;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- mode = AR5K_MODE_11B;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- case CHANNEL_T:
- mode = AR5K_MODE_11A_TURBO;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_TG:
- if (ah->ah_version == AR5K_AR5211) {
- ATH5K_ERR(ah->ah_sc,
- "TurboG mode not available on 5211");
- return -EINVAL;
- }
- mode = AR5K_MODE_11G_TURBO;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_XR:
- if (ah->ah_version == AR5K_AR5211) {
- ATH5K_ERR(ah->ah_sc,
- "XR mode not available on 5211");
- return -EINVAL;
- }
- mode = AR5K_MODE_XR;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- default:
+ /* Disable sleep clock operation
+ * to avoid register access delay on certain
+ * PHY registers */
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_set_sleep_clock(ah, false);
+
+ /*
+ * Stop PCU
+ */
+ ath5k_hw_stop_rx_pcu(ah);
+
+ /*
+ * Stop DMA
+ *
+ * Note: If DMA didn't stop continue
+ * since only a reset will fix it.
+ */
+ ret = ath5k_hw_dma_stop(ah);
+
+ /* RF Bus grant won't work if we have pending
+ * frames */
+ if (ret && fast) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+ "DMA didn't stop, falling back to normal reset\n");
+ fast = 0;
+ /* Non fatal, just continue with
+ * normal reset */
+ ret = 0;
+ }
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ mode = AR5K_MODE_11A;
+ break;
+ case CHANNEL_G:
+
+ if (ah->ah_version <= AR5K_AR5211) {
ATH5K_ERR(ah->ah_sc,
- "invalid channel: %d\n", channel->center_freq);
+ "G mode not available on 5210/5211");
return -EINVAL;
}
- if (change_channel) {
- /*
- * Save frame sequence count
- * For revs. after Oahu, only save
- * seq num for DCU 0 (Global seq num)
- */
- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-
- for (i = 0; i < 10; i++)
- s_seq[i] = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DCU_SEQNUM(i));
+ mode = AR5K_MODE_11G;
+ break;
+ case CHANNEL_B:
- } else {
- s_seq[0] = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DCU_SEQNUM(0));
- }
+ if (ah->ah_version < AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "B mode not available on 5210");
+ return -EINVAL;
+ }
- /* TSF accelerates on AR5211 during reset
- * As a workaround save it here and restore
- * it later so that it's back in time after
- * reset. This way it'll get re-synced on the
- * next beacon without breaking ad-hoc.
- *
- * On AR5212 TSF is almost preserved across a
- * reset so it stays back in time anyway and
- * we don't have to save/restore it.
- *
- * XXX: Since this breaks power saving we have
- * to disable power saving until we receive the
- * next beacon, so we can resync beacon timers */
- if (ah->ah_version == AR5K_AR5211) {
- tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
- tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
- }
+ mode = AR5K_MODE_11B;
+ break;
+ case CHANNEL_XR:
+ if (ah->ah_version == AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "XR mode not available on 5211");
+ return -EINVAL;
}
+ mode = AR5K_MODE_XR;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
- if (ah->ah_version == AR5K_AR5212) {
- /* Restore normal 32/40MHz clock operation
- * to avoid register access delay on certain
- * PHY registers */
- ath5k_hw_set_sleep_clock(ah, false);
+ /*
+ * If driver requested fast channel change and DMA has stopped
+ * go on. If it fails continue with a normal reset.
+ */
+ if (fast) {
+ ret = ath5k_hw_phy_init(ah, channel, mode, true);
+ if (ret) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+ "fast chan change failed, falling back to normal reset\n");
+ /* Non fatal, can happen eg.
+ * on mode change */
+ ret = 0;
+ } else
+ return 0;
+ }
- /* Since we are going to write rf buffer
- * check if we have any pending gain_F
- * optimization settings */
- if (change_channel && ah->ah_rf_banks != NULL)
- ath5k_hw_gainf_calibrate(ah);
+ /*
+ * Save some registers before a reset
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ /*
+ * Save frame sequence count
+ * For revs. after Oahu, only save
+ * seq num for DCU 0 (Global seq num)
+ */
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+ for (i = 0; i < 10; i++)
+ s_seq[i] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(i));
+
+ } else {
+ s_seq[0] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+ /* TSF accelerates on AR5211 during reset
+ * As a workaround save it here and restore
+ * it later so that it's back in time after
+ * reset. This way it'll get re-synced on the
+ * next beacon without breaking ad-hoc.
+ *
+ * On AR5212 TSF is almost preserved across a
+ * reset so it stays back in time anyway and
+ * we don't have to save/restore it.
+ *
+ * XXX: Since this breaks power saving we have
+ * to disable power saving until we receive the
+ * next beacon, so we can resync beacon timers */
+ if (ah->ah_version == AR5K_AR5211) {
+ tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
}
}
+
/*GPIOs*/
s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
AR5K_PCICFG_LEDSTATE;
s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
- /* AR5K_STA_ID1 flags, only preserve antenna
- * settings and ack/cts rate mode */
- staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
- (AR5K_STA_ID1_DEFAULT_ANTENNA |
- AR5K_STA_ID1_DESC_ANTENNA |
- AR5K_STA_ID1_RTS_DEF_ANTENNA |
- AR5K_STA_ID1_ACKCTS_6MB |
- AR5K_STA_ID1_BASE_RATE_11B |
- AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+ /*
+ * Since we are going to write rf buffer
+ * check if we have any pending gain_F
+ * optimization settings
+ */
+ if (ah->ah_version == AR5K_AR5212 &&
+ (ah->ah_radio <= AR5K_RF5112)) {
+ if (!fast && ah->ah_rf_banks != NULL)
+ ath5k_hw_gainf_calibrate(ah);
+ }
/* Wakeup the device */
ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
@@ -1021,121 +1194,42 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_PHY(0));
/* Write initial settings */
- ret = ath5k_hw_write_initvals(ah, mode, change_channel);
+ ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);
if (ret)
return ret;
+ /* Initialize core clock settings */
+ ath5k_hw_init_core_clock(ah);
+
/*
- * 5211/5212 Specific
+ * Tweak initval settings for revised
+ * chipsets and add some more config
+ * bits
*/
- if (ah->ah_version != AR5K_AR5210) {
-
- /*
- * Write initial RF gain settings
- * This should work for both 5111/5112
- */
- ret = ath5k_hw_rfgain_init(ah, freq);
- if (ret)
- return ret;
-
- mdelay(1);
-
- /*
- * Tweak initval settings for revised
- * chipsets and add some more config
- * bits
- */
- ath5k_hw_tweak_initval_settings(ah, channel);
-
- /*
- * Set TX power
- */
- ret = ath5k_hw_txpower(ah, channel, ee_mode,
- ah->ah_txpower.txp_max_pwr / 2);
- if (ret)
- return ret;
+ ath5k_hw_tweak_initval_settings(ah, channel);
- /* Write rate duration table only on AR5212 and if
- * virtual interface has already been brought up
- * XXX: rethink this after new mode changes to
- * mac80211 are integrated */
- if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_sc->nvifs)
- ath5k_hw_write_rate_duration(ah, mode);
+ /* Commit values from EEPROM */
+ ath5k_hw_commit_eeprom_settings(ah, channel);
- /*
- * Write RF buffer
- */
- ret = ath5k_hw_rfregs_init(ah, channel, mode);
- if (ret)
- return ret;
-
-
- /* Write OFDM timings on 5212*/
- if (ah->ah_version == AR5K_AR5212 &&
- channel->hw_value & CHANNEL_OFDM) {
-
- ret = ath5k_hw_write_ofdm_timings(ah, channel);
- if (ret)
- return ret;
-
- /* Spur info is available only from EEPROM versions
- * greater than 5.3, but the EEPROM routines will use
- * static values for older versions */
- if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
- ath5k_hw_set_spur_mitigation_filter(ah,
- channel);
- }
-
- /*Enable/disable 802.11b mode on 5111
- (enable 2111 frequency converter + CCK)*/
- if (ah->ah_radio == AR5K_RF5111) {
- if (mode == AR5K_MODE_11B)
- AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_B_MODE);
- else
- AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_B_MODE);
- }
-
- /* Commit values from EEPROM */
- ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
-
- } else {
- /*
- * For 5210 we do all initialization using
- * initvals, so we don't have to modify
- * any settings (5210 also only supports
- * a/aturbo modes)
- */
- mdelay(1);
- /* Disable phy and wait */
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
- mdelay(1);
- }
/*
* Restore saved values
*/
- /*DCU/Antenna selection not available on 5210*/
+ /* Seqnum, TSF */
if (ah->ah_version != AR5K_AR5210) {
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ for (i = 0; i < 10; i++)
+ ath5k_hw_reg_write(ah, s_seq[i],
+ AR5K_QUEUE_DCU_SEQNUM(i));
+ } else {
+ ath5k_hw_reg_write(ah, s_seq[0],
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
- if (change_channel) {
- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
- for (i = 0; i < 10; i++)
- ath5k_hw_reg_write(ah, s_seq[i],
- AR5K_QUEUE_DCU_SEQNUM(i));
- } else {
- ath5k_hw_reg_write(ah, s_seq[0],
- AR5K_QUEUE_DCU_SEQNUM(0));
- }
-
-
- if (ah->ah_version == AR5K_AR5211) {
- ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
- ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
- }
+ if (ah->ah_version == AR5K_AR5211) {
+ ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+ ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
}
}
@@ -1146,203 +1240,34 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
- /* Restore sta_id flags and preserve our mac address*/
- ath5k_hw_reg_write(ah,
- get_unaligned_le32(common->macaddr),
- AR5K_STA_ID0);
- ath5k_hw_reg_write(ah,
- staid1_flags | get_unaligned_le16(common->macaddr + 4),
- AR5K_STA_ID1);
-
-
/*
- * Configure PCU
+ * Initialize PCU
*/
-
- /* Restore bssid and bssid mask */
- ath5k_hw_set_bssid(ah);
-
- /* Set PCU config */
- ath5k_hw_set_opmode(ah, op_mode);
-
- /* Clear any pending interrupts
- * PISR/SISR Not available on 5210 */
- if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
-
- /* Set RSSI/BRSSI thresholds
- *
- * Note: If we decide to set this value
- * dynamically, keep in mind that when AR5K_RSSI_THR
- * register is read, it might return 0x40 if we haven't
- * written anything to it. Also, BMISS RSSI threshold is zeroed.
- * So doing a save/restore procedure here isn't the right
- * choice. Instead, store it in ath5k_hw */
- ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
- AR5K_TUNE_BMISS_THRES <<
- AR5K_RSSI_THR_BMISS_S),
- AR5K_RSSI_THR);
-
- /* MIC QoS support */
- if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
- ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
- ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
- }
-
- /* QoS NOACK Policy */
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah,
- AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
- AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
- AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
- AR5K_QOS_NOACK);
- }
-
+ ath5k_hw_pcu_init(ah, op_mode, mode);
/*
- * Configure PHY
+ * Initialize PHY
*/
-
- /* Set channel on PHY */
- ret = ath5k_hw_channel(ah, channel);
- if (ret)
+ ret = ath5k_hw_phy_init(ah, channel, mode, false);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc,
+ "failed to initialize PHY (%i) !\n", ret);
return ret;
-
- /*
- * Enable the PHY and wait until completion
- * This includes BaseBand and Synthesizer
- * activation.
- */
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-
- /*
- * On 5211+ read activation -> rx delay
- * and use it.
- *
- * TODO: Half/quarter rate support
- */
- if (ah->ah_version != AR5K_AR5210) {
- u32 delay;
- delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
- AR5K_PHY_RX_DELAY_M;
- delay = (channel->hw_value & CHANNEL_CCK) ?
- ((delay << 2) / 22) : (delay / 10);
-
- udelay(100 + (2 * delay));
- } else {
- mdelay(1);
}
/*
- * Perform ADC test to see if baseband is ready
- * Set TX hold and check ADC test register
- */
- phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
- ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
- for (i = 0; i <= 20; i++) {
- if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
- break;
- udelay(200);
- }
- ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
-
- /*
- * Start automatic gain control calibration
- *
- * During AGC calibration RX path is re-routed to
- * a power detector so we don't receive anything.
- *
- * This method is used to calibrate some static offsets
- * used together with on-the fly I/Q calibration (the
- * one performed via ath5k_hw_phy_calibrate), which doesn't
- * interrupt rx path.
- *
- * While rx path is re-routed to the power detector we also
- * start a noise floor calibration to measure the
- * card's noise floor (the noise we measure when we are not
- * transmitting or receiving anything).
- *
- * If we are in a noisy environment, AGC calibration may time
- * out and/or noise floor calibration might timeout.
- */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
- AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
-
- /* At the same time start I/Q calibration for QAM constellation
- * -no need for CCK- */
- ah->ah_calibration = false;
- if (!(mode == AR5K_MODE_11B)) {
- ah->ah_calibration = true;
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_RUN);
- }
-
- /* Wait for gain calibration to finish (we check for I/Q calibration
- * during ath5k_phy_calibrate) */
- if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
- AR5K_PHY_AGCCTL_CAL, 0, false)) {
- ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
- channel->center_freq);
- }
-
- /* Restore antenna mode */
- ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
-
- /* Restore slot time and ACK timeouts */
- if (ah->ah_coverage_class > 0)
- ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
-
- /*
* Configure QCUs/DCUs
*/
+ ret = ath5k_hw_init_queues(ah);
+ if (ret)
+ return ret;
- /* TODO: HW Compression support for data queues */
- /* TODO: Burst prefetch for data queues */
-
- /*
- * Reset queues and start beacon timers at the end of the reset routine
- * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
- * Note: If we want we can assign multiple qcus on one dcu.
- */
- for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
- ret = ath5k_hw_reset_tx_queue(ah, i);
- if (ret) {
- ATH5K_ERR(ah->ah_sc,
- "failed to reset TX queue #%d\n", i);
- return ret;
- }
- }
-
-
- /*
- * Configure DMA/Interrupts
- */
/*
- * Set Rx/Tx DMA Configuration
- *
- * Set standard DMA size (128). Note that
- * a DMA size of 512 causes rx overruns and tx errors
- * on pci-e cards (tested on 5424 but since rx overruns
- * also occur on 5416/5418 with madwifi we set 128
- * for all PCI-E cards to be safe).
- *
- * XXX: need to check 5210 for this
- * TODO: Check out tx triger level, it's always 64 on dumps but I
- * guess we can tweak it and see how it goes ;-)
+ * Initialize DMA/Interrupts
*/
- if (ah->ah_version != AR5K_AR5210) {
- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
- AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
- }
+ ath5k_hw_dma_init(ah);
- /* Pre-enable interrupts on 5211/5212*/
- if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_set_imr(ah, ah->ah_imr);
/* Enable 32KHz clock function for AR5212+ chips
* Set clocks to 32KHz operation and use an
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index 3ac4cff4239d..16b67e84906d 100644
--- a/drivers/net/wireless/ath/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
@@ -51,7 +51,7 @@
struct ath5k_ini_rfbuffer {
u8 rfb_bank; /* RF Bank number */
u16 rfb_ctrl_register; /* RF Buffer control register */
- u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
+ u32 rfb_mode_data[3]; /* RF Buffer data for each mode */
};
/*
@@ -79,8 +79,10 @@ struct ath5k_rf_reg {
* life easier by using an index for each register
* instead of a full rfb_field */
enum ath5k_rf_regs_idx {
+ /* BANK 2 */
+ AR5K_RF_TURBO = 0,
/* BANK 6 */
- AR5K_RF_OB_2GHZ = 0,
+ AR5K_RF_OB_2GHZ,
AR5K_RF_OB_5GHZ,
AR5K_RF_DB_2GHZ,
AR5K_RF_DB_5GHZ,
@@ -134,6 +136,9 @@ enum ath5k_rf_regs_idx {
* RF5111 (Sombrero) *
\*******************/
+/* BANK 2 len pos col */
+#define AR5K_RF5111_RF_TURBO { 1, 3, 0 }
+
/* BANK 6 len pos col */
#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
@@ -158,6 +163,7 @@ enum ath5k_rf_regs_idx {
#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
static const struct ath5k_rf_reg rf_regs_5111[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5111_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
@@ -177,97 +183,52 @@ static const struct ath5k_rf_reg rf_regs_5111[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5111[] = {
- { 0, 0x989c,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
- { 0, 0x989c,
- { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
- { 0, 0x98d4,
- { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
- { 1, 0x98d4,
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
- { 3, 0x98d8,
- { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
- { 6, 0x989c,
- { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
- { 6, 0x989c,
- { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
- { 6, 0x989c,
- { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
- { 6, 0x989c,
- { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
- { 6, 0x98d4,
- { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
- { 7, 0x989c,
- { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
- { 7, 0x989c,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 7, 0x989c,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 7, 0x989c,
- { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
- { 7, 0x989c,
- { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
- { 7, 0x989c,
- { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
- { 7, 0x989c,
- { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x000000c0, 0x00000080 } },
+ { 0, 0x989c, { 0x000400f9, 0x000400ff, 0x000400fd } },
+ { 0, 0x98d4, { 0x00000000, 0x00000004, 0x00000004 } },
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d4, { 0x00000010, 0x00000010, 0x00000010 } },
+ { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x0a000000, 0x00000000 } },
+ { 6, 0x989c, { 0x003800c0, 0x023800c0, 0x003800c0 } },
+ { 6, 0x989c, { 0x00020006, 0x00000006, 0x00020006 } },
+ { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089 } },
+ { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0 } },
+ { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007 } },
+ { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a } },
+ { 7, 0x989c, { 0x00000040, 0x00000040, 0x00000040 } },
+ { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010 } },
+ { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008 } },
+ { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f } },
+ { 7, 0x989c, { 0x000000f1, 0x00000061, 0x000000f1 } },
+ { 7, 0x989c, { 0x0000904f, 0x0000904c, 0x0000904f } },
+ { 7, 0x989c, { 0x0000125a, 0x0000129a, 0x0000125a } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000f, 0x0000000e } },
};
@@ -276,6 +237,9 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
* RF5112/RF2112 (Derby) *
\***********************/
+/* BANK 2 (Common) len pos col */
+#define AR5K_RF5112X_RF_TURBO { 1, 1, 2 }
+
/* BANK 7 (Common) len pos col */
#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
@@ -307,6 +271,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
static const struct ath5k_rf_reg rf_regs_5112[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
@@ -335,115 +300,61 @@ static const struct ath5k_rf_reg rf_regs_5112[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5112[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
- { 6, 0x989c,
- { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
- { 6, 0x989c,
- { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
- { 6, 0x989c,
- { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
- { 6, 0x989c,
- { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
- { 6, 0x989c,
- { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
- { 6, 0x989c,
- { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
- { 6, 0x989c,
- { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
- { 6, 0x989c,
- { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
- { 6, 0x989c,
- { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
- { 6, 0x989c,
- { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
- { 6, 0x989c,
- { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
- { 6, 0x989c,
- { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
- { 6, 0x98d0,
- { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
- { 7, 0x989c,
- { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
+ { 3, 0x98dc, { 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+ { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000 } },
+ { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000 } },
+ { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000 } },
+ { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000 } },
+ { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000 } },
+ { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000 } },
+ { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000 } },
+ { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000 } },
+ { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000 } },
+ { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000 } },
+ { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000 } },
+ { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000 } },
+ { 6, 0x989c, { 0x000000b0, 0x000000a8, 0x000000a8 } },
+ { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e } },
+ { 6, 0x989c, { 0x006c4a41, 0x006c4af1, 0x006c4a61 } },
+ { 6, 0x989c, { 0x0050892a, 0x0050892b, 0x0050892b } },
+ { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400 } },
+ { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200 } },
+ { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c } },
+ { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c, { 0x0000000a, 0x00000012, 0x00000012 } },
+ { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1 } },
+ { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022 } },
+ { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092 } },
+ { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
};
/* RFX112A (Derby 2) */
@@ -477,6 +388,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112[] = {
#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
static const struct ath5k_rf_reg rf_regs_5112a[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
@@ -515,119 +427,63 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, 0x989c,
- { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, 0x989c,
- { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, 0x989c,
- { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
- { 6, 0x989c,
- { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
- { 6, 0x989c,
- { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, 0x989c,
- { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
- { 6, 0x989c,
- { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, 0x989c,
- { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
- { 6, 0x989c,
- { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
- { 6, 0x989c,
- { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
- { 6, 0x989c,
- { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
- { 6, 0x989c,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, 0x989c,
- { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
- { 6, 0x989c,
- { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, 0x989c,
- { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
- { 6, 0x989c,
- { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, 0x98d8,
- { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, 0x989c,
- { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000 } },
+ { 6, 0x989c, { 0x00600000, 0x006e0000, 0x006e0000 } },
+ { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000 } },
+ { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000 } },
+ { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000 } },
+ { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000 } },
+ { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000 } },
+ { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000 } },
+ { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000 } },
+ { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000 } },
+ { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000 } },
+ { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000 } },
+ { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080 } },
+ { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019 } },
+ { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2 } },
+ { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084 } },
+ { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4 } },
+ { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220 } },
+ { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800 } },
+ { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230 } },
+ { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9 } },
+ { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2 } },
+ { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052 } },
+ { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
};
@@ -636,11 +492,15 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
* RF2413 (Griffin) *
\******************/
+/* BANK 2 len pos col */
+#define AR5K_RF2413_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
static const struct ath5k_rf_reg rf_regs_2413[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2413_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
};
@@ -649,73 +509,40 @@ static const struct ath5k_rf_reg rf_regs_2413[] = {
* XXX: a/aTurbo ???
*/
static const struct ath5k_ini_rfbuffer rfb_2413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
- { 6, 0x989c,
- { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
- { 6, 0x989c,
- { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
- { 6, 0x989c,
- { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
- { 6, 0x989c,
- { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
- { 6, 0x989c,
- { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
- { 6, 0x989c,
- { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
- { 6, 0x989c,
- { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
- { 6, 0x989c,
- { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
- { 6, 0x989c,
- { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
- { 6, 0x989c,
- { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
- { 6, 0x989c,
- { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
- { 6, 0x989c,
- { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
- { 6, 0x98d8,
- { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000 } },
+ { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000 } },
+ { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000 } },
+ { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000 } },
+ { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000 } },
+ { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000 } },
+ { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000 } },
+ { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000 } },
+ { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018 } },
+ { 6, 0x989c, { 0x00280000, 0x00280060, 0x00280060 } },
+ { 6, 0x989c, { 0x005000c0, 0x005000c3, 0x005000c3 } },
+ { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f } },
+ { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000 } },
+ { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -724,88 +551,57 @@ static const struct ath5k_ini_rfbuffer rfb_2413[] = {
* RF2315/RF2316 (Cobra SoC) *
\***************************/
+/* BANK 2 len pos col */
+#define AR5K_RF2316_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
static const struct ath5k_rf_reg rf_regs_2316[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2316_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
};
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_2316[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
- { 6, 0x989c,
- { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
- { 6, 0x989c,
- { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
- { 6, 0x989c,
- { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
- { 6, 0x989c,
- { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
- { 6, 0x989c,
- { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
- { 6, 0x989c,
- { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
- { 6, 0x989c,
- { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
- { 6, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 6, 0x989c,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 6, 0x989c,
- { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
- { 6, 0x989c,
- { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
- { 6, 0x98c0,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000 } },
+ { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000 } },
+ { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000 } },
+ { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000 } },
+ { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000 } },
+ { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+ { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000 } },
+ { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000 } },
+ { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060 } },
+ { 6, 0x989c, { 0x00a00000, 0x00a00080, 0x00a00080 } },
+ { 6, 0x989c, { 0x00400000, 0x0040000d, 0x0040000d } },
+ { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400 } },
+ { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00 } },
+ { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8 } },
+ { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -835,93 +631,50 @@ static const struct ath5k_rf_reg rf_regs_5413[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 3, 0x98dc,
- { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
- { 6, 0x989c,
- { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
- { 6, 0x989c,
- { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
- { 6, 0x989c,
- { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
- { 6, 0x989c,
- { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
- { 6, 0x989c,
- { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
- { 6, 0x989c,
- { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
- { 6, 0x989c,
- { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
- { 6, 0x989c,
- { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
- { 6, 0x989c,
- { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
- { 6, 0x989c,
- { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
- { 6, 0x989c,
- { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
- { 6, 0x989c,
- { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
- { 6, 0x989c,
- { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
- { 6, 0x989c,
- { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
- { 6, 0x98c8,
- { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008 } },
+ { 3, 0x98dc, { 0x00a000c0, 0x00e000c0, 0x00e000c0 } },
+ { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000 } },
+ { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000 } },
+ { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000 } },
+ { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000 } },
+ { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000 } },
+ { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+ { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000 } },
+ { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000 } },
+ { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000 } },
+ { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000 } },
+ { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080 } },
+ { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034 } },
+ { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0 } },
+ { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f } },
+ { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040 } },
+ { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0 } },
+ { 6, 0x989c, { 0x00002c00, 0x00003600, 0x00003600 } },
+ { 6, 0x98c8, { 0x00000403, 0x00040403, 0x00040403 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -931,92 +684,59 @@ static const struct ath5k_ini_rfbuffer rfb_5413[] = {
* AR2317 (Spider SoC) *
\***************************/
+/* BANK 2 len pos col */
+#define AR5K_RF2425_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
static const struct ath5k_rf_reg rf_regs_2425[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2425_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
};
/* Default mode specific settings
- * XXX: a/aTurbo ?
*/
static const struct ath5k_ini_rfbuffer rfb_2425[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
/*
@@ -1024,158 +744,85 @@ static const struct ath5k_ini_rfbuffer rfb_2425[] = {
* bank modification and get rid of this
*/
static const struct ath5k_ini_rfbuffer rfb_2317[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
/*
* TODO: Handle the few differences with swan during
* bank modification and get rid of this
- * XXX: a/aTurbo ?
*/
static const struct ath5k_ini_rfbuffer rfb_2417[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x80e70000, 0x80e70000 } },
+ { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0207001a, 0x0207001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
index 90757de7bf59..929c68cdf8ab 100644
--- a/drivers/net/wireless/ath/ath5k/sysfs.c
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -95,7 +95,7 @@ static struct attribute_group ath5k_attribute_group_ani = {
int
ath5k_sysfs_register(struct ath5k_softc *sc)
{
- struct device *dev = &sc->pdev->dev;
+ struct device *dev = sc->dev;
int err;
err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
@@ -110,7 +110,7 @@ ath5k_sysfs_register(struct ath5k_softc *sc)
void
ath5k_sysfs_unregister(struct ath5k_softc *sc)
{
- struct device *dev = &sc->pdev->dev;
+ struct device *dev = sc->dev;
sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
}
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 1a984b02e9e5..25a6e4417cdb 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -35,10 +35,9 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_print(common, ATH_DBG_FATAL,
- "%s: flash read failed, offset %08x "
- "is out of range\n",
- __func__, off);
+ ath_err(common,
+ "%s: flash read failed, offset %08x is out of range\n",
+ __func__, off);
return false;
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 63ccb39cdcd4..2e31c775351f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -135,8 +135,8 @@ static void ath9k_ani_restart(struct ath_hw *ah)
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
}
- ath_print(common, ATH_DBG_ANI,
- "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
ENABLE_REGWRITE_BUFFER(ah);
@@ -267,11 +267,11 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
aniState->noiseFloor = BEACON_RSSI(ah);
- ath_print(common, ATH_DBG_ANI,
- "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
- aniState->ofdmNoiseImmunityLevel,
- immunityLevel, aniState->noiseFloor,
- aniState->rssiThrLow, aniState->rssiThrHigh);
+ ath_dbg(common, ATH_DBG_ANI,
+ "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+ aniState->ofdmNoiseImmunityLevel,
+ immunityLevel, aniState->noiseFloor,
+ aniState->rssiThrLow, aniState->rssiThrHigh);
aniState->ofdmNoiseImmunityLevel = immunityLevel;
@@ -334,11 +334,11 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
const struct ani_cck_level_entry *entry_cck;
aniState->noiseFloor = BEACON_RSSI(ah);
- ath_print(common, ATH_DBG_ANI,
- "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
- aniState->cckNoiseImmunityLevel, immunityLevel,
- aniState->noiseFloor, aniState->rssiThrLow,
- aniState->rssiThrHigh);
+ ath_dbg(common, ATH_DBG_ANI,
+ "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+ aniState->cckNoiseImmunityLevel, immunityLevel,
+ aniState->noiseFloor, aniState->rssiThrLow,
+ aniState->rssiThrHigh);
if ((ah->opmode == NL80211_IFTYPE_STATION ||
ah->opmode == NL80211_IFTYPE_ADHOC) &&
@@ -358,7 +358,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
entry_cck->fir_step_level);
/* Skip MRC CCK for pre AR9003 families */
- if (!AR_SREV_9300_20_OR_LATER(ah))
+ if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
return;
if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
@@ -478,8 +478,8 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
if (ah->opmode != NL80211_IFTYPE_STATION
&& ah->opmode != NL80211_IFTYPE_ADHOC) {
- ath_print(common, ATH_DBG_ANI,
- "Reset ANI state opmode %u\n", ah->opmode);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Reset ANI state opmode %u\n", ah->opmode);
ah->stats.ast_ani_reset++;
if (ah->opmode == NL80211_IFTYPE_AP) {
@@ -584,16 +584,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
ATH9K_ANI_OFDM_DEF_LEVEL ||
aniState->cckNoiseImmunityLevel !=
ATH9K_ANI_CCK_DEF_LEVEL) {
- ath_print(common, ATH_DBG_ANI,
- "Restore defaults: opmode %u "
- "chan %d Mhz/0x%x is_scanning=%d "
- "ofdm:%d cck:%d\n",
- ah->opmode,
- chan->channel,
- chan->channelFlags,
- is_scanning,
- aniState->ofdmNoiseImmunityLevel,
- aniState->cckNoiseImmunityLevel);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags,
+ is_scanning,
+ aniState->ofdmNoiseImmunityLevel,
+ aniState->cckNoiseImmunityLevel);
ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
@@ -602,16 +600,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
/*
* restore historical levels for this channel
*/
- ath_print(common, ATH_DBG_ANI,
- "Restore history: opmode %u "
- "chan %d Mhz/0x%x is_scanning=%d "
- "ofdm:%d cck:%d\n",
- ah->opmode,
- chan->channel,
- chan->channelFlags,
- is_scanning,
- aniState->ofdmNoiseImmunityLevel,
- aniState->cckNoiseImmunityLevel);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags,
+ is_scanning,
+ aniState->ofdmNoiseImmunityLevel,
+ aniState->cckNoiseImmunityLevel);
ath9k_hw_set_ofdm_nil(ah,
aniState->ofdmNoiseImmunityLevel);
@@ -666,19 +662,17 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
if (phyCnt1 < ofdm_base) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt1 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt1, ofdm_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "phyCnt1 0x%x, resetting counter value to 0x%x\n",
+ phyCnt1, ofdm_base);
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
AR_PHY_ERR_OFDM_TIMING);
}
if (phyCnt2 < cck_base) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt2 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt2, cck_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "phyCnt2 0x%x, resetting counter value to 0x%x\n",
+ phyCnt2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
AR_PHY_ERR_CCK_TIMING);
@@ -719,13 +713,12 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
aniState->listenTime;
- ath_print(common, ATH_DBG_ANI,
- "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
- "errs=%d/s ofdm_turn=%d\n",
- aniState->listenTime,
- aniState->ofdmNoiseImmunityLevel,
- ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
- cckPhyErrRate, aniState->ofdmsTurn);
+ ath_dbg(common, ATH_DBG_ANI,
+ "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
+ aniState->listenTime,
+ aniState->ofdmNoiseImmunityLevel,
+ ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
+ cckPhyErrRate, aniState->ofdmsTurn);
if (aniState->listenTime > 5 * ah->aniperiod) {
if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
@@ -755,7 +748,7 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n");
+ ath_dbg(common, ATH_DBG_ANI, "Enable MIB counters\n");
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -777,7 +770,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n");
+ ath_dbg(common, ATH_DBG_ANI, "Disable MIB counters\n");
REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -834,10 +827,10 @@ void ath9k_hw_ani_setup(struct ath_hw *ah)
{
int i;
- const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
- const int coarseHigh[] = { -14, -14, -14, -14, -12 };
- const int coarseLow[] = { -64, -64, -64, -64, -70 };
- const int firpwr[] = { -78, -78, -78, -78, -80 };
+ static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+ static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+ static const int coarseLow[] = { -64, -64, -64, -64, -70 };
+ static const int firpwr[] = { -78, -78, -78, -78, -80 };
for (i = 0; i < 5; i++) {
ah->totalSizeDesired[i] = totalSizeDesired[i];
@@ -852,7 +845,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
int i;
- ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
+ ath_dbg(common, ATH_DBG_ANI, "Initialize ANI\n");
if (use_new_ani(ah)) {
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index ea9f4497f58c..ffcf44a4058b 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -130,9 +130,8 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
/* pre-reverse this field */
tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
- ath_print(common, ATH_DBG_CONFIG,
- "Force rf_pwd_icsyndiv to %1d on %4d\n",
- new_bias, synth_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n",
+ new_bias, synth_freq);
/* swizzle rf_pwd_icsyndiv */
ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
@@ -173,8 +172,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid channel %u MHz\n", freq);
+ ath_err(common, "Invalid channel %u MHz\n", freq);
return -EINVAL;
}
@@ -206,8 +204,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid channel %u MHz\n", freq);
+ ath_err(common, "Invalid channel %u MHz\n", freq);
return -EINVAL;
}
@@ -244,13 +241,15 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
int upper, lower, cur_vit_mask;
int tmp, new;
int i;
- int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
- AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+ static int pilot_mask_reg[4] = {
+ AR_PHY_TIMING7, AR_PHY_TIMING8,
+ AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
};
- int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
- AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+ static int chan_mask_reg[4] = {
+ AR_PHY_TIMING9, AR_PHY_TIMING10,
+ AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
};
- int inc[4] = { 0, 100, 0, 0 };
+ static int inc[4] = { 0, 100, 0, 0 };
int8_t mask_m[123];
int8_t mask_p[123];
@@ -446,8 +445,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
#define ATH_ALLOC_BANK(bank, size) do { \
bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
if (!bank) { \
- ath_print(common, ATH_DBG_FATAL, \
- "Cannot allocate RF banks\n"); \
+ ath_err(common, "Cannot allocate RF banks\n"); \
return -ENOMEM; \
} \
} while (0);
@@ -873,12 +871,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
/* Write analog registers */
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "ar5416SetRfRegs failed\n");
+ ath_err(ath9k_hw_common(ah), "ar5416SetRfRegs failed\n");
return -EIO;
}
@@ -964,18 +961,6 @@ static void ar5008_hw_rfbus_done(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
}
-static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
-{
- REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
- AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-
- REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
- AR_GPIO_INPUT_MUX2_RFSILENT);
-
- ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
- REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-
static void ar5008_restore_chainmask(struct ath_hw *ah)
{
int rx_chainmask = ah->rxchainmask;
@@ -1056,10 +1041,9 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(ah->totalSizeDesired));
return false;
}
@@ -1084,12 +1068,12 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
- const int m1ThreshLow[] = { 127, 50 };
- const int m2ThreshLow[] = { 127, 40 };
- const int m1Thresh[] = { 127, 0x4d };
- const int m2Thresh[] = { 127, 0x40 };
- const int m2CountThr[] = { 31, 16 };
- const int m2CountThrLow[] = { 63, 48 };
+ static const int m1ThreshLow[] = { 127, 50 };
+ static const int m2ThreshLow[] = { 127, 40 };
+ static const int m1Thresh[] = { 127, 0x4d };
+ static const int m2Thresh[] = { 127, 0x40 };
+ static const int m2CountThr[] = { 31, 16 };
+ static const int m2CountThrLow[] = { 63, 48 };
u32 on = param ? 1 : 0;
REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
@@ -1141,7 +1125,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
- const int weakSigThrCck[] = { 8, 6 };
+ static const int weakSigThrCck[] = { 8, 6 };
u32 high = param ? 1 : 0;
REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
@@ -1157,14 +1141,13 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_FIRSTEP_LEVEL:{
- const int firstep[] = { 0, 4, 8 };
+ static const int firstep[] = { 0, 4, 8 };
u32 level = param;
if (level >= ARRAY_SIZE(firstep)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
@@ -1178,14 +1161,13 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
- const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+ static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_TIMING5,
@@ -1201,25 +1183,22 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
- ath_print(common, ATH_DBG_ANI,
- "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
- "ofdmWeakSigDetectOff=%d\n",
- aniState->noiseImmunityLevel,
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff);
- ath_print(common, ATH_DBG_ANI,
- "cckWeakSigThreshold=%d, "
- "firstepLevel=%d, listenTime=%d\n",
- aniState->cckWeakSigThreshold,
- aniState->firstepLevel,
- aniState->listenTime);
- ath_print(common, ATH_DBG_ANI,
+ ath_dbg(common, ATH_DBG_ANI, "ANI parameters:\n");
+ ath_dbg(common, ATH_DBG_ANI,
+ "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n",
+ aniState->noiseImmunityLevel,
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff);
+ ath_dbg(common, ATH_DBG_ANI,
+ "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n",
+ aniState->cckWeakSigThreshold,
+ aniState->firstepLevel,
+ aniState->listenTime);
+ ath_dbg(common, ATH_DBG_ANI,
"ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
@@ -1304,12 +1283,12 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
if (!on != aniState->ofdmWeakSigDetectOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: ofdm weak signal: %s=>%s\n",
- chan->channel,
- !aniState->ofdmWeakSigDetectOff ?
- "on" : "off",
- on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: ofdm weak signal: %s=>%s\n",
+ chan->channel,
+ !aniState->ofdmWeakSigDetectOff ?
+ "on" : "off",
+ on ? "on" : "off");
if (on)
ah->stats.ast_ani_ofdmon++;
else
@@ -1322,11 +1301,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(firstep_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_FIRSTEP_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep_table));
return false;
}
@@ -1361,24 +1338,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
if (level != aniState->firstepLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value,
- aniState->iniDef.firstep);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep_low[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value2,
- aniState->iniDef.firstepLow);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value,
+ aniState->iniDef.firstep);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value2,
+ aniState->iniDef.firstepLow);
if (level > aniState->firstepLevel)
ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
@@ -1391,11 +1366,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1_table));
return false;
}
/*
@@ -1429,24 +1402,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
if (level != aniState->spurImmunityLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value,
- aniState->iniDef.cycpwrThr1);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1Ext[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value2,
- aniState->iniDef.cycpwrThr1Ext);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value,
+ aniState->iniDef.cycpwrThr1);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value2,
+ aniState->iniDef.cycpwrThr1Ext);
if (level > aniState->spurImmunityLevel)
ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
@@ -1465,22 +1436,19 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI,
- "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d "
- "ofdmErrs=%d cckErrs=%d\n",
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
- aniState->firstepLevel,
- !aniState->mrcCCKOff ? "on" : "off",
- aniState->listenTime,
- aniState->ofdmPhyErrCount,
- aniState->cckPhyErrCount);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+ aniState->firstepLevel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ aniState->listenTime,
+ aniState->ofdmPhyErrCount,
+ aniState->cckPhyErrCount);
return true;
}
@@ -1490,25 +1458,25 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
- nfarray[2] = sign_extend(nf, 9);
+ nfarray[2] = sign_extend32(nf, 8);
if (!IS_CHAN_HT40(ah->curchan))
return;
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
- nfarray[5] = sign_extend(nf, 9);
+ nfarray[5] = sign_extend32(nf, 8);
}
/*
@@ -1526,13 +1494,12 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
iniDef = &aniState->iniDef;
- ath_print(common, ATH_DBG_ANI,
- "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
- ah->hw_version.macVersion,
- ah->hw_version.macRev,
- ah->opmode,
- chan->channel,
- chan->channelFlags);
+ ath_dbg(common, ATH_DBG_ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+ ah->hw_version.macVersion,
+ ah->hw_version.macRev,
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1579,10 +1546,55 @@ static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
}
+static void ar5008_hw_set_radar_params(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf)
+{
+ u32 radar_0 = 0, radar_1 = 0;
+
+ if (!conf) {
+ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+ return;
+ }
+
+ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+ if (conf->ext_channel)
+ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+ else
+ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
+{
+ struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+ conf->fir_power = -33;
+ conf->radar_rssi = 20;
+ conf->pulse_height = 10;
+ conf->pulse_rssi = 24;
+ conf->pulse_inband = 15;
+ conf->pulse_maxlen = 255;
+ conf->pulse_inband_step = 12;
+ conf->radar_inband = 8;
+}
+
void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
- const u32 ar5416_cca_regs[6] = {
+ static const u32 ar5416_cca_regs[6] = {
AR_PHY_CCA,
AR_PHY_CH1_CCA,
AR_PHY_CH2_CCA,
@@ -1605,10 +1617,10 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
priv_ops->rfbus_req = ar5008_hw_rfbus_req;
priv_ops->rfbus_done = ar5008_hw_rfbus_done;
- priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
priv_ops->restore_chainmask = ar5008_restore_chainmask;
priv_ops->set_diversity = ar5008_set_diversity;
priv_ops->do_getnf = ar5008_hw_do_getnf;
+ priv_ops->set_radar_params = ar5008_hw_set_radar_params;
if (modparam_force_new_ani) {
priv_ops->ani_control = ar5008_hw_ani_control_new;
@@ -1624,5 +1636,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
ar5008_hw_set_nf_limits(ah);
+ ar5008_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 15f62cd0cc38..01880aa13e36 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -39,18 +39,18 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
switch (currCal->calData->calType) {
case IQ_MISMATCH_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting IQ Mismatch Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting IQ Mismatch Calibration\n");
break;
case ADC_GAIN_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting ADC Gain Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting ADC Gain Calibration\n");
break;
case ADC_DC_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting ADC DC Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting ADC DC Calibration\n");
break;
}
@@ -107,11 +107,11 @@ static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
@@ -129,14 +129,13 @@ static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
ah->totalAdcQEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
- "oddq=0x%08x; evenq=0x%08x;\n",
- ah->cal_samples, i,
- ah->totalAdcIOddPhase[i],
- ah->totalAdcIEvenPhase[i],
- ah->totalAdcQOddPhase[i],
- ah->totalAdcQEvenPhase[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
+ ah->cal_samples, i,
+ ah->totalAdcIOddPhase[i],
+ ah->totalAdcIEvenPhase[i],
+ ah->totalAdcQOddPhase[i],
+ ah->totalAdcQEvenPhase[i]);
}
}
@@ -154,14 +153,13 @@ static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
ah->totalAdcDcOffsetQEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
- "oddq=0x%08x; evenq=0x%08x;\n",
- ah->cal_samples, i,
- ah->totalAdcDcOffsetIOddPhase[i],
- ah->totalAdcDcOffsetIEvenPhase[i],
- ah->totalAdcDcOffsetQOddPhase[i],
- ah->totalAdcDcOffsetQEvenPhase[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
+ ah->cal_samples, i,
+ ah->totalAdcDcOffsetIOddPhase[i],
+ ah->totalAdcDcOffsetIEvenPhase[i],
+ ah->totalAdcDcOffsetQOddPhase[i],
+ ah->totalAdcDcOffsetQEvenPhase[i]);
}
}
@@ -178,13 +176,13 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
powerMeasQ = ah->totalPowerMeasQ[i];
iqCorrMeas = ah->totalIqCorrMeas[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting IQ Cal and Correction for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting IQ Cal and Correction for Chain %d\n",
+ i);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ah->totalIqCorrMeas[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -193,12 +191,12 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iqCorrNeg = 1;
}
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
- ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
- iqCorrNeg);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+ iqCorrNeg);
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
qCoffDenom = powerMeasQ / 64;
@@ -207,14 +205,14 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
(qCoffDenom != 0)) {
iCoff = iqCorrMeas / iCoffDenom;
qCoff = powerMeasI / qCoffDenom - 64;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d iCoff = 0x%08x\n", i, iCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d qCoff = 0x%08x\n", i, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d qCoff = 0x%08x\n", i, qCoff);
iCoff = iCoff & 0x3f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
if (iqCorrNeg == 0x0)
iCoff = 0x40 - iCoff;
@@ -223,9 +221,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
else if (qCoff <= -16)
qCoff = -16;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
- i, iCoff, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
+ i, iCoff, qCoff);
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
@@ -233,9 +231,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction done for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction done for Chain %d\n",
+ i);
}
}
@@ -255,21 +253,21 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
qOddMeasOffset = ah->totalAdcQOddPhase[i];
qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting ADC Gain Cal for Chain %d\n", i);
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
- iOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_i = 0x%08x\n", i,
- iEvenMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
- qOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_q = 0x%08x\n", i,
- qEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting ADC Gain Cal for Chain %d\n", i);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+ iOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+ iEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+ qOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+ qEvenMeasOffset);
if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
iGainMismatch =
@@ -279,20 +277,20 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
((qOddMeasOffset * 32) /
qEvenMeasOffset) & 0x3f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d gain_mismatch_i = 0x%08x\n", i,
- iGainMismatch);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d gain_mismatch_q = 0x%08x\n", i,
- qGainMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d gain_mismatch_i = 0x%08x\n", i,
+ iGainMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d gain_mismatch_q = 0x%08x\n", i,
+ qGainMismatch);
val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
val &= 0xfffff000;
val |= (qGainMismatch) | (iGainMismatch << 6);
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
- ath_print(common, ATH_DBG_CALIBRATE,
- "ADC Gain Cal done for Chain %d\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "ADC Gain Cal done for Chain %d\n", i);
}
}
@@ -317,41 +315,41 @@ static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting ADC DC Offset Cal for Chain %d\n", i);
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_i = %d\n", i,
- iOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_i = %d\n", i,
- iEvenMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_q = %d\n", i,
- qOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_q = %d\n", i,
- qEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_i = %d\n", i,
+ iOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_i = %d\n", i,
+ iEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_q = %d\n", i,
+ qOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_q = %d\n", i,
+ qEvenMeasOffset);
iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
numSamples) & 0x1ff;
qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
numSamples) & 0x1ff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
- iDcMismatch);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
- qDcMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+ iDcMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+ qDcMismatch);
val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
val &= 0xc0000fff;
val |= (qDcMismatch << 12) | (iDcMismatch << 21);
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
- ath_print(common, ATH_DBG_CALIBRATE,
- "ADC DC Offset Cal done for Chain %d\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "ADC DC Offset Cal done for Chain %d\n", i);
}
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
@@ -540,7 +538,7 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
{ 0x7838, 0 },
};
- ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
/* PA CAL is not needed for high power solution */
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
@@ -721,9 +719,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE, "offset "
- "calibration failed to complete in "
- "1ms; noisy ??\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
@@ -736,8 +733,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
- "failed to complete in 1ms; noisy ??\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
@@ -829,9 +826,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "offset calibration failed to "
- "complete in 1ms; noisy environment?\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
@@ -866,19 +862,19 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling ADC Gain Calibration.\n");
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling ADC DC Calibration.\n");
}
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
ah->cal_list_curr = ah->cal_list;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 48261b7252d0..fdb5a835fdcf 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -26,24 +26,6 @@ MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002");
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
-static bool ar9002_hw_macversion_supported(u32 macversion)
-{
- switch (macversion) {
- case AR_SREV_VERSION_5416_PCI:
- case AR_SREV_VERSION_5416_PCIE:
- case AR_SREV_VERSION_9160:
- case AR_SREV_VERSION_9100:
- case AR_SREV_VERSION_9280:
- case AR_SREV_VERSION_9285:
- case AR_SREV_VERSION_9287:
- case AR_SREV_VERSION_9271:
- return true;
- default:
- break;
- }
- return false;
-}
-
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
{
if (AR_SREV_9271(ah)) {
@@ -494,9 +476,9 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
case AR_RAD2122_SREV_MAJOR:
break;
default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Radio Chip Rev 0x%02X not supported\n",
- val & AR_RADIO_SREV_MAJOR);
+ ath_err(ath9k_hw_common(ah),
+ "Radio Chip Rev 0x%02X not supported\n",
+ val & AR_RADIO_SREV_MAJOR);
return -EOPNOTSUPP;
}
@@ -565,7 +547,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
- priv_ops->macversion_supported = ar9002_hw_macversion_supported;
ops->config_pci_powersave = ar9002_hw_configpcipowersave;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 50dda394f8be..399ab3bb299b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -90,13 +90,10 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ah->config.rx_intr_mitigation) {
- if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
- *masked |= ATH9K_INT_RX;
- }
-
- if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+ if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
+ AR_ISR_RXOK | AR_ISR_RXERR))
*masked |= ATH9K_INT_RX;
+
if (isr &
(AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
AR_ISR_TXEOL)) {
@@ -114,16 +111,8 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
}
if (isr & AR_ISR_RXORN) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "receive FIFO overrun interrupt\n");
- }
-
- if (!AR_SREV_9100(ah)) {
- if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
- u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
- if (isr5 & AR_ISR_S5_TIM_TIMER)
- *masked |= ATH9K_INT_TIM_TIMER;
- }
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "receive FIFO overrun interrupt\n");
}
*masked |= mask2;
@@ -136,17 +125,18 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
u32 s5_s;
s5_s = REG_READ(ah, AR_ISR_S5_S);
- if (isr & AR_ISR_GENTMR) {
- ah->intr_gen_timer_trigger =
+ ah->intr_gen_timer_trigger =
MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
- ah->intr_gen_timer_thresh =
- MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+ ah->intr_gen_timer_thresh =
+ MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
- if (ah->intr_gen_timer_trigger)
- *masked |= ATH9K_INT_GENTIMER;
+ if (ah->intr_gen_timer_trigger)
+ *masked |= ATH9K_INT_GENTIMER;
- }
+ if ((s5_s & AR_ISR_S5_TIM_TIMER) &&
+ !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+ *masked |= ATH9K_INT_TIM_TIMER;
}
if (sync_cause) {
@@ -157,25 +147,25 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
if (fatal_int) {
if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
- ath_print(common, ATH_DBG_ANY,
- "received PCI FATAL interrupt\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "received PCI FATAL interrupt\n");
}
if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
- ath_print(common, ATH_DBG_ANY,
- "received PCI PERR interrupt\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "received PCI PERR interrupt\n");
}
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
REG_WRITE(ah, AR_RC, 0);
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
}
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
@@ -218,77 +208,70 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
struct ath_tx_status *ts)
{
struct ar5416_desc *ads = AR5416DESC(ds);
+ u32 status;
- if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+ status = ACCESS_ONCE(ads->ds_txstatus9);
+ if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
- ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
ts->ts_tstamp = ads->AR_SendTimestamp;
ts->ts_status = 0;
ts->ts_flags = 0;
- if (ads->ds_txstatus1 & AR_FrmXmitOK)
+ if (status & AR_TxOpExceeded)
+ ts->ts_status |= ATH9K_TXERR_XTXOP;
+ ts->tid = MS(status, AR_TxTid);
+ ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+ ts->ts_seqnum = MS(status, AR_SeqNum);
+
+ status = ACCESS_ONCE(ads->ds_txstatus0);
+ ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+ ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+ ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+ if (status & AR_TxBaStatus) {
+ ts->ts_flags |= ATH9K_TX_BA;
+ ts->ba_low = ads->AR_BaBitmapLow;
+ ts->ba_high = ads->AR_BaBitmapHigh;
+ }
+
+ status = ACCESS_ONCE(ads->ds_txstatus1);
+ if (status & AR_FrmXmitOK)
ts->ts_status |= ATH9K_TX_ACKED;
- if (ads->ds_txstatus1 & AR_ExcessiveRetries)
- ts->ts_status |= ATH9K_TXERR_XRETRY;
- if (ads->ds_txstatus1 & AR_Filtered)
- ts->ts_status |= ATH9K_TXERR_FILT;
- if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
- ts->ts_status |= ATH9K_TXERR_FIFO;
- ath9k_hw_updatetxtriglevel(ah, true);
+ else {
+ if (status & AR_ExcessiveRetries)
+ ts->ts_status |= ATH9K_TXERR_XRETRY;
+ if (status & AR_Filtered)
+ ts->ts_status |= ATH9K_TXERR_FILT;
+ if (status & AR_FIFOUnderrun) {
+ ts->ts_status |= ATH9K_TXERR_FIFO;
+ ath9k_hw_updatetxtriglevel(ah, true);
+ }
}
- if (ads->ds_txstatus9 & AR_TxOpExceeded)
- ts->ts_status |= ATH9K_TXERR_XTXOP;
- if (ads->ds_txstatus1 & AR_TxTimerExpired)
+ if (status & AR_TxTimerExpired)
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
- if (ads->ds_txstatus1 & AR_DescCfgErr)
+ if (status & AR_DescCfgErr)
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
- if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+ if (status & AR_TxDataUnderrun) {
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+ if (status & AR_TxDelimUnderrun) {
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->ds_txstatus0 & AR_TxBaStatus) {
- ts->ts_flags |= ATH9K_TX_BA;
- ts->ba_low = ads->AR_BaBitmapLow;
- ts->ba_high = ads->AR_BaBitmapHigh;
- }
+ ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+ ts->ts_longretry = MS(status, AR_DataFailCnt);
+ ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
- switch (ts->ts_rateindex) {
- case 0:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
- break;
- case 1:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
- break;
- case 2:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
- break;
- case 3:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
- break;
- }
+ status = ACCESS_ONCE(ads->ds_txstatus5);
+ ts->ts_rssi = MS(status, AR_TxRSSICombined);
+ ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+ ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+ ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
- ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
- ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
- ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
- ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
- ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
- ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
- ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
ts->evm0 = ads->AR_TxEVM0;
ts->evm1 = ads->AR_TxEVM1;
ts->evm2 = ads->AR_TxEVM2;
- ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
- ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
- ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
- ts->tid = MS(ads->ds_txstatus9, AR_TxTid);
- ts->ts_antenna = 0;
return 0;
}
@@ -300,7 +283,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
{
struct ar5416_desc *ads = AR5416DESC(ds);
- txPower += ah->txpower_indexoffset;
if (txPower > 63)
txPower = 63;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index c00cdc67b55b..7d68d61e406b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -175,13 +175,15 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
int upper, lower, cur_vit_mask;
int tmp, newVal;
int i;
- int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
- AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+ static const int pilot_mask_reg[4] = {
+ AR_PHY_TIMING7, AR_PHY_TIMING8,
+ AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
};
- int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
- AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+ static const int chan_mask_reg[4] = {
+ AR_PHY_TIMING9, AR_PHY_TIMING10,
+ AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
};
- int inc[4] = { 0, 100, 0, 0 };
+ static const int inc[4] = { 0, 100, 0, 0 };
struct chan_centers centers;
int8_t mask_m[123];
@@ -201,13 +203,14 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+ if (AR_NO_SPUR == cur_bb_spur)
+ break;
+
if (is2GHz)
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
else
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
- if (AR_NO_SPUR == cur_bb_spur)
- break;
cur_bb_spur = cur_bb_spur - freq;
if (IS_CHAN_HT40(chan)) {
@@ -473,21 +476,21 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
if (IS_CHAN_HT40(ah->curchan))
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
return;
nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
if (IS_CHAN_HT40(ah->curchan))
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
}
static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index a14a5e43cf56..81f9cf294dec 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -34,9 +34,9 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+ {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -56,21 +56,21 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
- {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
- {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
- {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
- {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
- {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
- {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
- {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
- {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
- {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
- {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
+ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -88,44 +88,44 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
- {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
- {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
- {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
- {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
- {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
- {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
- {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
- {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
- {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
- {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
- {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
- {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
- {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
- {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
- {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
- {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
- {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+ {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
- {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
- {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+ {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
@@ -638,6 +638,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
{0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+ {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
{0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
{0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
@@ -680,7 +681,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
{0x0000981c, 0x00020028},
{0x00009834, 0x6400a290},
{0x00009838, 0x0108ecff},
- {0x0000983c, 0x14750600},
+ {0x0000983c, 0x0d000600},
{0x00009880, 0x201fff00},
{0x00009884, 0x00001042},
{0x000098a4, 0x00200400},
@@ -722,7 +723,6 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
{0x0000a220, 0x00000000},
{0x0000a224, 0x00000000},
{0x0000a228, 0x10002310},
- {0x0000a22c, 0x01036a27},
{0x0000a23c, 0x00000000},
{0x0000a244, 0x0c000000},
{0x0000a2a0, 0x00000001},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 9e6edffe0bd1..4a4cd88429c0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,6 +18,16 @@
#include "hw-ops.h"
#include "ar9003_phy.h"
+#define MPASS 3
+#define MAX_MEASUREMENT 8
+#define MAX_DIFFERENCE 10
+
+struct coeff {
+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+ int iqc_coeff[2];
+};
+
enum ar9003_cal_types {
IQ_MISMATCH_CAL = BIT(0),
TEMP_COMP_CAL = BIT(1),
@@ -40,8 +50,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
currCal->calData->calCountMax);
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting IQ Mismatch Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting IQ Mismatch Calibration\n");
/* Kick-off cal */
REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
@@ -52,8 +62,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
AR_PHY_65NM_CH0_THERM_START, 1);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting Temperature Compensation Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting Temperature Compensation Calibration\n");
break;
}
}
@@ -181,11 +191,11 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
@@ -196,7 +206,7 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
u32 qCoffDenom, iCoffDenom;
int32_t qCoff, iCoff;
int iqCorrNeg, i;
- const u_int32_t offset_array[3] = {
+ static const u_int32_t offset_array[3] = {
AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_B1,
AR_PHY_RX_IQCAL_CORR_B2,
@@ -207,13 +217,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
powerMeasQ = ah->totalPowerMeasQ[i];
iqCorrMeas = ah->totalIqCorrMeas[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting IQ Cal and Correction for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting IQ Cal and Correction for Chain %d\n",
+ i);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ah->totalIqCorrMeas[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -222,12 +232,12 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iqCorrNeg = 1;
}
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
- ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
- iqCorrNeg);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+ iqCorrNeg);
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
qCoffDenom = powerMeasQ / 64;
@@ -235,10 +245,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
iCoff = iqCorrMeas / iCoffDenom;
qCoff = powerMeasI / qCoffDenom - 64;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d iCoff = 0x%08x\n", i, iCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d qCoff = 0x%08x\n", i, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d qCoff = 0x%08x\n", i, qCoff);
/* Force bounds on iCoff */
if (iCoff >= 63)
@@ -259,14 +269,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iCoff = iCoff & 0x7f;
qCoff = qCoff & 0x7f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
- i, iCoff, qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) "
- "before update = 0x%x\n",
- offset_array[i],
- REG_READ(ah, offset_array[i]));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
+ i, iCoff, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) before update = 0x%x\n",
+ offset_array[i],
+ REG_READ(ah, offset_array[i]));
REG_RMW_FIELD(ah, offset_array[i],
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
@@ -274,33 +283,29 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
REG_RMW_FIELD(ah, offset_array[i],
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) QI COFF "
- "(bitfields 0x%08x) after update = 0x%x\n",
- offset_array[i],
- AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
- REG_READ(ah, offset_array[i]));
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) QQ COFF "
- "(bitfields 0x%08x) after update = 0x%x\n",
- offset_array[i],
- AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
- REG_READ(ah, offset_array[i]));
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction done for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
+ offset_array[i],
+ AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+ REG_READ(ah, offset_array[i]));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
+ offset_array[i],
+ AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+ REG_READ(ah, offset_array[i]));
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction done for Chain %d\n", i);
}
}
REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction (offset 0x%04x) enabled "
- "(bit position 0x%08x). New Value 0x%08x\n",
- (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
- AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
- REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
+ (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
+ AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
+ REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
}
static const struct ath9k_percal_data iq_cal_single_sample = {
@@ -340,7 +345,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
f2 = (f1 * f1 + f3 * f3) / result_shift;
if (!f2) {
- ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
return false;
}
@@ -461,11 +466,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
(i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0:\na0_d0=%d\n"
- "a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
- i2_p_q2_a0_d0, i2_p_q2_a0_d1,
- i2_p_q2_a1_d0, i2_p_q2_a1_d1);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0:\n"
+ "a0_d0=%d\n"
+ "a0_d1=%d\n"
+ "a2_d0=%d\n"
+ "a1_d1=%d\n",
+ i2_p_q2_a0_d0, i2_p_q2_a0_d1,
+ i2_p_q2_a1_d0, i2_p_q2_a1_d1);
return false;
}
@@ -498,9 +506,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
if ((mag1 == 0) || (mag2 == 0)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag1=%d, mag2=%d\n",
- mag1, mag2);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag1=%d, mag2=%d\n",
+ mag1, mag2);
return false;
}
@@ -517,8 +525,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag_a0_d0, phs_a0_d0,
mag_a1_d0,
phs_a1_d0, solved_eq)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Call to ar9003_hw_solve_iq_cal() failed.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Call to ar9003_hw_solve_iq_cal() failed.\n");
return false;
}
@@ -527,14 +535,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag_rx = solved_eq[2];
phs_rx = solved_eq[3];
- ath_print(common, ATH_DBG_CALIBRATE,
- "chain %d: mag mismatch=%d phase mismatch=%d\n",
- chain_idx, mag_tx/res_scale, phs_tx/res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "chain %d: mag mismatch=%d phase mismatch=%d\n",
+ chain_idx, mag_tx/res_scale, phs_tx/res_scale);
if (res_scale == mag_tx) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag_tx=%d, res_scale=%d\n",
- mag_tx, res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag_tx=%d, res_scale=%d\n",
+ mag_tx, res_scale);
return false;
}
@@ -545,9 +553,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
q_q_coff = (mag_corr_tx * 128 / res_scale);
q_i_coff = (phs_corr_tx * 256 / res_scale);
- ath_print(common, ATH_DBG_CALIBRATE,
- "tx chain %d: mag corr=%d phase corr=%d\n",
- chain_idx, q_q_coff, q_i_coff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "tx chain %d: mag corr=%d phase corr=%d\n",
+ chain_idx, q_q_coff, q_i_coff);
if (q_i_coff < -63)
q_i_coff = -63;
@@ -560,14 +568,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "tx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[0]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "tx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[0]);
if (-mag_rx == res_scale) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag_rx=%d, res_scale=%d\n",
- mag_rx, res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag_rx=%d, res_scale=%d\n",
+ mag_rx, res_scale);
return false;
}
@@ -578,9 +586,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
q_q_coff = (mag_corr_rx * 128 / res_scale);
q_i_coff = (phs_corr_rx * 256 / res_scale);
- ath_print(common, ATH_DBG_CALIBRATE,
- "rx chain %d: mag corr=%d phase corr=%d\n",
- chain_idx, q_q_coff, q_i_coff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "rx chain %d: mag corr=%d phase corr=%d\n",
+ chain_idx, q_q_coff, q_i_coff);
if (q_i_coff < -63)
q_i_coff = -63;
@@ -593,140 +601,367 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "rx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[1]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "rx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[1]);
+
+ return true;
+}
+
+static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
+{
+ int diff[MPASS];
+
+ diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
+ diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
+ diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
+
+ if (diff[0] > MAX_DIFFERENCE &&
+ diff[1] > MAX_DIFFERENCE &&
+ diff[2] > MAX_DIFFERENCE)
+ return false;
+
+ if (diff[0] <= diff[1] && diff[0] <= diff[2])
+ *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
+ else if (diff[1] <= diff[2])
+ *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
+ else
+ *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
return true;
}
+static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+ u8 num_chains,
+ struct coeff *coeff)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ int i, im, nmeasurement;
+ int magnitude, phase;
+ u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
+
+ memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
+ for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
+ tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
+ if (!AR_SREV_9485(ah)) {
+ tx_corr_coeff[i * 2][1] =
+ tx_corr_coeff[(i * 2) + 1][1] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
+
+ tx_corr_coeff[i * 2][2] =
+ tx_corr_coeff[(i * 2) + 1][2] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
+ }
+ }
+
+ /* Load the average of 2 passes */
+ for (i = 0; i < num_chains; i++) {
+ if (AR_SREV_9485(ah))
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_CALIBRATED_GAINS_0);
+ else
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
+
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (im = 0; im < nmeasurement; im++) {
+ /*
+ * Determine which 2 passes are closest and compute avg
+ * magnitude
+ */
+ if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
+ &magnitude))
+ goto disable_txiqcal;
+
+ /*
+ * Determine which 2 passes are closest and compute avg
+ * phase
+ */
+ if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
+ &phase))
+ goto disable_txiqcal;
+
+ coeff->iqc_coeff[0] = (magnitude & 0x7f) |
+ ((phase & 0x7f) << 7);
+
+ if ((im % 2) == 0)
+ REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+ AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
+ coeff->iqc_coeff[0]);
+ else
+ REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+ AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
+ coeff->iqc_coeff[0]);
+ }
+ }
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+ AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
+ REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+ AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
+
+ return;
+
+disable_txiqcal:
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+ AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
+ REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+ AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
+}
+
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+ static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
- const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
- };
- const u32 rx_corr[AR9300_MAX_CHAINS] = {
- AR_PHY_RX_IQCAL_CORR_B0,
- AR_PHY_RX_IQCAL_CORR_B1,
- AR_PHY_RX_IQCAL_CORR_B2,
- };
- const u_int32_t chan_info_tab[] = {
+ static const u32 chan_info_tab[] = {
AR_PHY_CHAN_INFO_TAB_0,
AR_PHY_CHAN_INFO_TAB_1,
AR_PHY_CHAN_INFO_TAB_2,
};
+ struct coeff coeff;
s32 iq_res[6];
- s32 iqc_coeff[2];
- s32 i, j;
- u32 num_chains = 0;
+ s32 i, j, ip, im, nmeasurement;
+ u8 nchains = get_streams(common->tx_chainmask);
+
+ for (ip = 0; ip < MPASS; ip++) {
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+ AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+ DELPT);
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL,
+ AR_PHY_TX_IQCAL_START_DO_CAL);
+
+ if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal not complete.\n");
+ goto TX_IQ_CAL_FAILED;
+ }
- for (i = 0; i < AR9300_MAX_CHAINS; i++) {
- if (ah->txchainmask & (1 << i))
- num_chains++;
- }
+ nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (i = 0; i < nchains; i++) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
+ for (im = 0; im < nmeasurement; im++) {
+ if (REG_READ(ah, txiqcal_status[i]) &
+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal failed for chain %d.\n", i);
+ goto TX_IQ_CAL_FAILED;
+ }
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
- DELPT);
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- AR_PHY_TX_IQCAL_START_DO_CAL);
+ for (j = 0; j < 3; j++) {
+ u8 idx = 2 * j,
+ offset = 4 * (3 * im + j);
- if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- 0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal not complete.\n");
- goto TX_IQ_CAL_FAILED;
- }
+ REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 0);
- for (i = 0; i < num_chains; i++) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Doing Tx IQ Cal for chain %d.\n", i);
+ /* 32 bits */
+ iq_res[idx] = REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
- if (REG_READ(ah, txiqcal_status[i]) &
- AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal failed for chain %d.\n", i);
- goto TX_IQ_CAL_FAILED;
- }
+ REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 1);
- for (j = 0; j < 3; j++) {
- u_int8_t idx = 2 * j,
- offset = 4 * j;
+ /* 16 bits */
+ iq_res[idx+1] = 0xffff & REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
-
- /* 32 bits */
- iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx+1, iq_res[idx+1]);
+ }
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+ coeff.iqc_coeff)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of IQ correction.\n");
+ goto TX_IQ_CAL_FAILED;
+ }
+ coeff.mag_coeff[i][im][ip] =
+ coeff.iqc_coeff[0] & 0x7f;
+ coeff.phs_coeff[i][im][ip] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
- /* 16 bits */
- iq_res[idx+1] = 0xffff & REG_READ(ah,
- chan_info_tab[i] +
- offset);
+ if (coeff.mag_coeff[i][im][ip] > 63)
+ coeff.mag_coeff[i][im][ip] -= 128;
+ if (coeff.phs_coeff[i][im][ip] > 63)
+ coeff.phs_coeff[i][im][ip] -= 128;
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
- idx, iq_res[idx], idx+1, iq_res[idx+1]);
- }
-
- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Failed in calculation of IQ correction.\n");
- goto TX_IQ_CAL_FAILED;
+ }
}
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
- iqc_coeff[0], iqc_coeff[1]);
-
- REG_RMW_FIELD(ah, tx_corr_coeff[i],
- AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
- iqc_coeff[0]);
- REG_RMW_FIELD(ah, rx_corr[i],
- AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
- iqc_coeff[1] >> 7);
- REG_RMW_FIELD(ah, rx_corr[i],
- AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
- iqc_coeff[1]);
}
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
- AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
- REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
- AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
+ ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
return;
TX_IQ_CAL_FAILED:
- ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+}
+
+static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
+{
+ u8 tx_gain_forced;
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
+ AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
+ tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+ AR_PHY_TXGAIN_FORCE);
+ if (tx_gain_forced)
+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+ AR_PHY_TXGAIN_FORCE, 0);
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
+ AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
}
+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_TX_IQCAL_STATUS_B1,
+ AR_PHY_TX_IQCAL_STATUS_B2,
+ };
+ const u_int32_t chan_info_tab[] = {
+ AR_PHY_CHAN_INFO_TAB_0,
+ AR_PHY_CHAN_INFO_TAB_1,
+ AR_PHY_CHAN_INFO_TAB_2,
+ };
+ struct coeff coeff;
+ s32 iq_res[6];
+ u8 num_chains = 0;
+ int i, ip, im, j;
+ int nmeasurement;
+
+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+ if (ah->txchainmask & (1 << i))
+ num_chains++;
+ }
+
+ for (ip = 0; ip < MPASS; ip++) {
+ for (i = 0; i < num_chains; i++) {
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_CALIBRATED_GAINS_0);
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (im = 0; im < nmeasurement; im++) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
+
+ if (REG_READ(ah, txiqcal_status[i]) &
+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal failed for chain %d.\n", i);
+ goto tx_iqcal_fail;
+ }
+
+ for (j = 0; j < 3; j++) {
+ u32 idx = 2 * j, offset = 4 * (3 * im + j);
+
+ REG_RMW_FIELD(ah,
+ AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 0);
+
+ /* 32 bits */
+ iq_res[idx] = REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
+
+ REG_RMW_FIELD(ah,
+ AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 1);
+
+ /* 16 bits */
+ iq_res[idx + 1] = 0xffff & REG_READ(ah,
+ chan_info_tab[i] + offset);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x"
+ "IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx + 1,
+ iq_res[idx + 1]);
+ }
+
+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+ coeff.iqc_coeff)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of IQ correction.\n");
+ goto tx_iqcal_fail;
+ }
+
+ coeff.mag_coeff[i][im][ip] =
+ coeff.iqc_coeff[0] & 0x7f;
+ coeff.phs_coeff[i][im][ip] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
+ if (coeff.mag_coeff[i][im][ip] > 63)
+ coeff.mag_coeff[i][im][ip] -= 128;
+ if (coeff.phs_coeff[i][im][ip] > 63)
+ coeff.phs_coeff[i][im][ip] -= 128;
+ }
+ }
+ }
+ ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
+
+ return;
+
+tx_iqcal_fail:
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+ return;
+}
static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
+ int val;
- /*
- * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
- * running AGC/TxIQ cals
- */
- ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+ val = REG_READ(ah, AR_ENT_OTP);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
+
+ if (AR_SREV_9485(ah))
+ ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
+ else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+ ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
+ else
+ /*
+ * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
+ * mode before running AGC/TxIQ cals
+ */
+ ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
/* Do Tx IQ Calibration */
- ar9003_hw_tx_iq_cal(ah);
+ if (AR_SREV_9485(ah))
+ ar9003_hw_tx_iq_cal_run(ah);
+ else
+ ar9003_hw_tx_iq_cal(ah);
+
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
udelay(5);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
@@ -739,12 +974,14 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
/* Poll for offset calibration complete */
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "offset calibration failed to "
- "complete in 1ms; noisy environment?\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
+ if (AR_SREV_9485(ah))
+ ar9003_hw_tx_iq_cal_post_proc(ah);
+
/* Revert chainmasks to their original values before NF cal */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
@@ -757,15 +994,15 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
if (ah->supp_cals & IQ_MISMATCH_CAL) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
}
if (ah->supp_cals & TEMP_COMP_CAL) {
INIT_CAL(&ah->tempCompCalData);
INSERT_CAL(ah, &ah->tempCompCalData);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling Temperature Compensation Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling Temperature Compensation Calibration.\n");
}
/* Initialize current pointer to first element in list */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c4182359bee4..4819747fa4c3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -22,12 +22,14 @@
#define COMP_CKSUM_LEN 2
#define AR_CH0_TOP (0x00016288)
-#define AR_CH0_TOP_XPABIASLVL (0x3)
+#define AR_CH0_TOP_XPABIASLVL (0x300)
#define AR_CH0_TOP_XPABIASLVL_S (8)
#define AR_CH0_THERM (0x00016290)
-#define AR_CH0_THERM_SPARE (0x3f)
-#define AR_CH0_THERM_SPARE_S (0)
+#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
+#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
+#define AR_CH0_THERM_XPASHORT2GND 0x4
+#define AR_CH0_THERM_XPASHORT2GND_S 2
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
#define AR_SWITCH_TABLE_COM_ALL_S (0)
@@ -55,6 +57,14 @@
#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
+#define EEPROM_DATA_LEN_9485 1088
+
+static int ar9003_hw_power_interpolate(int32_t x,
+ int32_t *px, int32_t *py, u_int16_t np);
+
+
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
@@ -65,7 +75,7 @@ static const struct ar9300_eeprom ar9300_default = {
.regDmn = { LE16(0), LE16(0x1f) },
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
- .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+ .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
.eepMisc = 0,
},
.rfSilent = 0,
@@ -144,13 +154,16 @@ static const struct ar9300_eeprom ar9300_default = {
.txEndToRxOn = 0x2,
.txFrameToXpaOn = 0xe,
.thresh62 = 28,
- .papdRateMaskHt20 = LE32(0x80c080),
- .papdRateMaskHt40 = LE32(0x80c080),
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
.futureModal = {
- 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,
},
},
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
.calFreqPier2G = {
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
@@ -285,25 +298,25 @@ static const struct ar9300_eeprom ar9300_default = {
/* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
/* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
/* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
- /* Data[11].ctlEdges[3].bChannel */
- FREQ2FBIN(2462, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
}
},
.ctlPowerData_2G = {
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
- { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
- { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
},
.modalHeader5G = {
/* 4 idle,t1,t2,b (4 bits per setting) */
@@ -343,13 +356,20 @@ static const struct ar9300_eeprom ar9300_default = {
.txEndToRxOn = 0x2,
.txFrameToXpaOn = 0xe,
.thresh62 = 28,
- .papdRateMaskHt20 = LE32(0xf0e0e0),
- .papdRateMaskHt40 = LE32(0xf0e0e0),
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
.futureModal = {
- 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,
},
},
+ .base_ext2 = {
+ .tempSlopeLow = 0,
+ .tempSlopeHigh = 0,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
.calFreqPier5G = {
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
@@ -568,64 +588,2396 @@ static const struct ar9300_eeprom ar9300_default = {
.ctlPowerData_5G = {
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+static const struct ar9300_eeprom ar9300_x113 = {
+ .eepromVersion = 2,
+ .templateVersion = 6,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"x113-023-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x21,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {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} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x11111),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 68,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 72,
+ .tempSlopeHigh = 105,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {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, 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, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5190, 0),
+ FREQ2FBIN(5230, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5410, 0),
+ FREQ2FBIN(5510, 0),
+ FREQ2FBIN(5670, 0),
+ FREQ2FBIN(5755, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
+ { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
+ { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+
+static const struct ar9300_eeprom ar9300_h112 = {
+ .eepromVersion = 2,
+ .templateVersion = 3,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"h112-241-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x10,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x80c080),
+ .papdRateMaskHt40 = LE32(0x80c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {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} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2484, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 45,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 40,
+ .tempSlopeHigh = 50,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calPierData5G = {
+ {
+ {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, 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, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+
+static const struct ar9300_eeprom ar9300_x112 = {
+ .eepromVersion = 2,
+ .templateVersion = 5,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"x112-041-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastclock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x0,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x22222),
+
+ /*
+ * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+ /*
+ * xatten1DB[AR9300_max_chains]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0x1b, 0x1b, 0x1b},
+
+ /*
+ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x15, 0x15, 0x15},
+ .tempSlope = 50,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPrey_eeprom_modal_sPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {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} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11s */
+ { {38, 38, 38, 38} },
+ { {38, 38, 38, 38} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {38, 38, 36, 34} },
+ { {38, 38, 36, 34} },
+ { {38, 38, 34, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+ { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
+ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+ },
+ .calTargetPower2GHT40 = {
+ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+ { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
+ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x22222),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x0), LE16(0x0), LE16(0x0),
+ },
+ /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0x13, 0x19, 0x17},
+
+ /*
+ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x19, 0x19, 0x19},
+ .tempSlope = 70,
+ .voltSlope = 15,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshch check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 72,
+ .tempSlopeHigh = 105,
+ .xatten1DBLow = {0x10, 0x14, 0x10},
+ .xatten1MarginLow = {0x19, 0x19 , 0x19},
+ .xatten1DBHigh = {0x1d, 0x20, 0x24},
+ .xatten1MarginHigh = {0x10, 0x10, 0x10}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {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, 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, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {32, 32, 28, 26} },
+ { {32, 32, 28, 26} },
+ { {32, 32, 28, 26} },
+ { {32, 32, 26, 24} },
+ { {32, 32, 26, 24} },
+ { {32, 32, 24, 22} },
+ { {30, 30, 24, 22} },
+ { {30, 30, 24, 22} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
+ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
+ { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
+ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
+ { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctledges[6].bchannel */ 0xFF,
+ /* Data[3].ctledges[7].bchannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctledges[4].bchannel */ 0xFF,
+ /* Data[4].ctledges[5].bchannel */ 0xFF,
+ /* Data[4].ctledges[6].bchannel */ 0xFF,
+ /* Data[4].ctledges[7].bchannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctledges[6].bchannel */ 0xFF,
+ /* Data[5].ctledges[7].bchannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+static const struct ar9300_eeprom ar9300_h116 = {
+ .eepromVersion = 2,
+ .templateVersion = 4,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"h116-041-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x10,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0x1f, 0x1f, 0x1f},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x12, 0x12, 0x12},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80C080),
+ .papdRateMaskHt40 = LE32(0x0080C080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {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} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0x19, 0x19, 0x19},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x14, 0x14, 0x14},
+ .tempSlope = 70,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 35,
+ .tempSlopeHigh = 50,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {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, 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, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 0}, {60, 1}, {60, 0}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
}
},
{
{
- {60, 0}, {60, 1}, {60, 1}, {60, 0},
- {60, 1}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
- {60, 0}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
}
},
{
{
- {60, 1}, {60, 1}, {60, 0}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 0}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 0}, {60, 1},
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
}
},
}
};
+
+static const struct ar9300_eeprom *ar9300_eep_templates[] = {
+ &ar9300_default,
+ &ar9300_x112,
+ &ar9300_h116,
+ &ar9300_h112,
+ &ar9300_x113,
+};
+
+static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
+{
+#define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
+ int it;
+
+ for (it = 0; it < N_LOOP; it++)
+ if (ar9300_eep_templates[it]->templateVersion == id)
+ return ar9300_eep_templates[it];
+ return NULL;
+#undef N_LOOP
+}
+
+
static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
{
- if (fbin == AR9300_BCHAN_UNUSED)
+ if (fbin == AR5416_BCHAN_UNUSED)
return fbin;
return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
@@ -636,6 +2988,16 @@ static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
return 0;
}
+static int interpolate(int x, int xa, int xb, int ya, int yb)
+{
+ int bf, factor, plus;
+
+ bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
+ factor = bf / 2;
+ plus = bf % 2;
+ return ya + factor + plus;
+}
+
static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
enum eeprom_param param)
{
@@ -673,6 +3035,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
return le32_to_cpu(pBase->swreg);
case EEP_PAPRD:
return !!(pBase->featureEnable & BIT(5));
+ case EEP_CHAIN_MASK_REDUCE:
+ return (pBase->miscConfiguration >> 0x3) & 0x1;
+ case EEP_ANT_DIV_CTL1:
+ return le32_to_cpu(eep->base_ext1.ant_div_control);
default:
return 0;
}
@@ -711,8 +3077,8 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
int i;
if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
- ath_print(common, ATH_DBG_EEPROM,
- "eeprom address not in range\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "eeprom address not in range\n");
return false;
}
@@ -743,11 +3109,41 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
return true;
error:
- ath_print(common, ATH_DBG_EEPROM,
- "unable to read eeprom region at offset %d\n", address);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "unable to read eeprom region at offset %d\n", address);
return false;
}
+static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
+{
+ REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
+
+ if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
+ AR9300_OTP_STATUS_VALID, 1000))
+ return false;
+
+ *data = REG_READ(ah, AR9300_OTP_READ_DATA);
+ return true;
+}
+
+static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
+ int count)
+{
+ u32 data;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ int offset = 8 * ((address - i) % 4);
+ if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
+ return false;
+
+ buffer[i] = (data >> offset) & 0xff;
+ }
+
+ return true;
+}
+
+
static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
int *length, int *major, int *minor)
{
@@ -798,17 +3194,15 @@ static bool ar9300_uncompress_block(struct ath_hw *ah,
length &= 0xff;
if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "Restore at %d: spot=%d "
- "offset=%d length=%d\n",
- it, spot, offset, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Restore at %d: spot=%d offset=%d length=%d\n",
+ it, spot, offset, length);
memcpy(&mptr[spot], &block[it+2], length);
spot += length;
} else if (length > 0) {
- ath_print(common, ATH_DBG_EEPROM,
- "Bad restore at %d: spot=%d "
- "offset=%d length=%d\n",
- it, spot, offset, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Bad restore at %d: spot=%d offset=%d length=%d\n",
+ it, spot, offset, length);
return false;
}
}
@@ -824,45 +3218,80 @@ static int ar9300_compress_decision(struct ath_hw *ah,
{
struct ath_common *common = ath9k_hw_common(ah);
u8 *dptr;
+ const struct ar9300_eeprom *eep = NULL;
switch (code) {
case _CompressNone:
if (length != mdata_size) {
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM structure size mismatch"
- "memory=%d eeprom=%d\n", mdata_size, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM structure size mismatch memory=%d eeprom=%d\n",
+ mdata_size, length);
return -1;
}
memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
- ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
- " uncompressed, length %d\n", it, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "restored eeprom %d: uncompressed, length %d\n",
+ it, length);
break;
case _CompressBlock:
if (reference == 0) {
dptr = mptr;
} else {
- if (reference != 2) {
- ath_print(common, ATH_DBG_EEPROM,
- "cant find reference eeprom"
- "struct %d\n", reference);
+ eep = ar9003_eeprom_struct_find_by_id(reference);
+ if (eep == NULL) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "cant find reference eeprom struct %d\n",
+ reference);
return -1;
}
- memcpy(mptr, &ar9300_default, mdata_size);
+ memcpy(mptr, eep, mdata_size);
}
- ath_print(common, ATH_DBG_EEPROM,
- "restore eeprom %d: block, reference %d,"
- " length %d\n", it, reference, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "restore eeprom %d: block, reference %d, length %d\n",
+ it, reference, length);
ar9300_uncompress_block(ah, mptr, mdata_size,
(u8 *) (word + COMP_HDR_LEN), length);
break;
default:
- ath_print(common, ATH_DBG_EEPROM, "unknown compression"
- " code %d\n", code);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "unknown compression code %d\n", code);
return -1;
}
return 0;
}
+typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
+ int count);
+
+static bool ar9300_check_header(void *data)
+{
+ u32 *word = data;
+ return !(*word == 0 || *word == ~0);
+}
+
+static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
+ int base_addr)
+{
+ u8 header[4];
+
+ if (!read(ah, base_addr, header, 4))
+ return false;
+
+ return ar9300_check_header(header);
+}
+
+static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
+ int mdata_size)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ u16 *data = (u16 *) mptr;
+ int i;
+
+ for (i = 0; i < mdata_size / 2; i++, data++)
+ ath9k_hw_nvram_read(common, i, data);
+
+ return 0;
+}
/*
* Read the configuration data from the eeprom.
* The data can be put in any specified memory buffer.
@@ -883,6 +3312,10 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
int it;
u16 checksum, mchecksum;
struct ath_common *common = ath9k_hw_common(ah);
+ eeprom_read_op read;
+
+ if (ath9k_hw_use_flash(ah))
+ return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
word = kzalloc(2048, GFP_KERNEL);
if (!word)
@@ -890,43 +3323,73 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
memcpy(mptr, &ar9300_default, mdata_size);
+ read = ar9300_read_eeprom;
+ if (AR_SREV_9485(ah))
+ cptr = AR9300_BASE_ADDR_4K;
+ else
+ cptr = AR9300_BASE_ADDR;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying EEPROM accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ cptr = AR9300_BASE_ADDR_512;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying EEPROM accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ read = ar9300_read_otp;
cptr = AR9300_BASE_ADDR;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying OTP accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ cptr = AR9300_BASE_ADDR_512;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying OTP accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ goto fail;
+
+found:
+ ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n");
+
for (it = 0; it < MSTATE; it++) {
- if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
+ if (!read(ah, cptr, word, COMP_HDR_LEN))
goto fail;
- if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
- word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
- && word[2] == 0xff && word[3] == 0xff))
+ if (!ar9300_check_header(word))
break;
ar9300_comp_hdr_unpack(word, &code, &reference,
&length, &major, &minor);
- ath_print(common, ATH_DBG_EEPROM,
- "Found block at %x: code=%d ref=%d"
- "length=%d major=%d minor=%d\n", cptr, code,
- reference, length, major, minor);
- if (length >= 1024) {
- ath_print(common, ATH_DBG_EEPROM,
- "Skipping bad header\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
+ cptr, code, reference, length, major, minor);
+ if ((!AR_SREV_9485(ah) && length >= 1024) ||
+ (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Skipping bad header\n");
cptr -= COMP_HDR_LEN;
continue;
}
osize = length;
- ar9300_read_eeprom(ah, cptr, word,
- COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+ read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
mchecksum = word[COMP_HDR_LEN + osize] |
(word[COMP_HDR_LEN + osize + 1] << 8);
- ath_print(common, ATH_DBG_EEPROM,
- "checksum %x %x\n", checksum, mchecksum);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "checksum %x %x\n", checksum, mchecksum);
if (checksum == mchecksum) {
ar9300_compress_decision(ah, it, code, reference, mptr,
word, length, mdata_size);
} else {
- ath_print(common, ATH_DBG_EEPROM,
- "skipping block with bad checksum\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "skipping block with bad checksum\n");
}
cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
}
@@ -967,18 +3430,6 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
return 0;
}
-static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
- enum ath9k_hal_freq_band freq_band)
-{
- return 1;
-}
-
-static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- return -EINVAL;
-}
-
static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
{
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
@@ -992,9 +3443,15 @@ static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
{
int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
- REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
- REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
- ((bias >> 2) & 0x3));
+
+ if (AR_SREV_9485(ah))
+ REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
+ else {
+ REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
+ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
+ bias >> 2);
+ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
+ }
}
static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
@@ -1049,11 +3506,25 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
- value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
+ if (!AR_SREV_9485(ah)) {
+ value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
+ REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
+ value);
+
+ value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
+ REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
+ value);
+ }
- value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
+ if (AR_SREV_9485(ah)) {
+ value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL,
+ value);
+ REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE,
+ value >> 6);
+ REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE,
+ value >> 7);
+ }
}
static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -1097,28 +3568,177 @@ static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
}
+static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
+ struct ath9k_channel *chan)
+{
+ int f[3], t[3];
+ u16 value;
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (chain >= 0 && chain < 3) {
+ if (IS_CHAN_2GHZ(chan))
+ return eep->modalHeader2G.xatten1DB[chain];
+ else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
+ t[0] = eep->base_ext2.xatten1DBLow[chain];
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.xatten1DB[chain];
+ f[1] = 5500;
+ t[2] = eep->base_ext2.xatten1DBHigh[chain];
+ f[2] = 5785;
+ value = ar9003_hw_power_interpolate((s32) chan->channel,
+ f, t, 3);
+ return value;
+ } else
+ return eep->modalHeader5G.xatten1DB[chain];
+ }
+
+ return 0;
+}
+
+
+static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
+ struct ath9k_channel *chan)
+{
+ int f[3], t[3];
+ u16 value;
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (chain >= 0 && chain < 3) {
+ if (IS_CHAN_2GHZ(chan))
+ return eep->modalHeader2G.xatten1Margin[chain];
+ else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
+ t[0] = eep->base_ext2.xatten1MarginLow[chain];
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.xatten1Margin[chain];
+ f[1] = 5500;
+ t[2] = eep->base_ext2.xatten1MarginHigh[chain];
+ f[2] = 5785;
+ value = ar9003_hw_power_interpolate((s32) chan->channel,
+ f, t, 3);
+ return value;
+ } else
+ return eep->modalHeader5G.xatten1Margin[chain];
+ }
+
+ return 0;
+}
+
+static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ int i;
+ u16 value;
+ unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
+ AR_PHY_EXT_ATTEN_CTL_1,
+ AR_PHY_EXT_ATTEN_CTL_2,
+ };
+
+ /* Test value. if 0 then attenuation is unused. Don't load anything. */
+ for (i = 0; i < 3; i++) {
+ value = ar9003_hw_atten_chain_get(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+ value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+ }
+}
+
+static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
+{
+ int timeout = 100;
+
+ while (pmu_set != REG_READ(ah, pmu_reg)) {
+ if (timeout-- == 0)
+ return false;
+ REG_WRITE(ah, pmu_reg, pmu_set);
+ udelay(10);
+ }
+
+ return true;
+}
+
static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
{
int internal_regulator =
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
if (internal_regulator) {
- /* Internal regulator is ON. Write swreg register. */
- int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
- REG_WRITE(ah, AR_RTC_REG_CONTROL1,
- REG_READ(ah, AR_RTC_REG_CONTROL1) &
- (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
- REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
- /* Set REG_CONTROL1.SWREG_PROGRAM */
- REG_WRITE(ah, AR_RTC_REG_CONTROL1,
- REG_READ(ah,
- AR_RTC_REG_CONTROL1) |
- AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ if (AR_SREV_9485(ah)) {
+ int reg_pmu_set;
+
+ reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) |
+ (7 << 14) | (6 << 17) | (1 << 20) |
+ (3 << 24) | (1 << 28);
+
+ REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
+ | (4 << 26);
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
+ | (1 << 21);
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+ } else {
+ /* Internal regulator is ON. Write swreg register. */
+ int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+ REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+ REG_READ(ah, AR_RTC_REG_CONTROL1) &
+ (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
+ REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
+ /* Set REG_CONTROL1.SWREG_PROGRAM */
+ REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+ REG_READ(ah,
+ AR_RTC_REG_CONTROL1) |
+ AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ }
} else {
- REG_WRITE(ah, AR_RTC_SLEEP_CLK,
- (REG_READ(ah,
- AR_RTC_SLEEP_CLK) |
- AR_RTC_FORCE_SWREG_PRD));
+ if (AR_SREV_9485(ah)) {
+ REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
+ while (REG_READ_FIELD(ah, AR_PHY_PMU2,
+ AR_PHY_PMU2_PGM))
+ udelay(10);
+
+ REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
+ while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
+ AR_PHY_PMU1_PWD))
+ udelay(10);
+ REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
+ while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
+ AR_PHY_PMU2_PGM))
+ udelay(10);
+ } else
+ REG_WRITE(ah, AR_RTC_SLEEP_CLK,
+ (REG_READ(ah,
+ AR_RTC_SLEEP_CLK) |
+ AR_RTC_FORCE_SWREG_PRD));
+ }
+
+}
+
+static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
+
+ if (eep->baseEepHeader.featureEnable & 0x40) {
+ tuning_caps_param &= 0x7f;
+ REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
+ tuning_caps_param);
+ REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
+ tuning_caps_param);
}
}
@@ -1128,7 +3748,10 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah);
+ ar9003_hw_atten_apply(ah, chan);
ar9003_hw_internal_regulator_apply(ah);
+ if (AR_SREV_9485(ah))
+ ar9003_hw_apply_tuning_caps(ah);
}
static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
@@ -1189,7 +3812,7 @@ static int ar9003_hw_power_interpolate(int32_t x,
if (hx == lx)
y = ly;
else /* interpolate */
- y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
+ y = interpolate(x, lx, hx, ly, hy);
} else /* only low is good, use it */
y = ly;
} else if (hhave) /* only high is good, use it */
@@ -1558,22 +4181,9 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
is2GHz) + ht40PowerIncForPdadc;
- while (i < ar9300RateSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
- i++;
+ for (i = 0; i < ar9300RateSize; i++) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
}
}
@@ -1592,18 +4202,17 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
if (ichain >= AR9300_MAX_CHAINS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid chain index, must be less than %d\n",
- AR9300_MAX_CHAINS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid chain index, must be less than %d\n",
+ AR9300_MAX_CHAINS);
return -1;
}
if (mode) { /* 5GHz */
if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid 5GHz cal pier index, must "
- "be less than %d\n",
- AR9300_NUM_5G_CAL_PIERS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid 5GHz cal pier index, must be less than %d\n",
+ AR9300_NUM_5G_CAL_PIERS);
return -1;
}
pCalPier = &(eep->calFreqPier5G[ipier]);
@@ -1611,9 +4220,9 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
is2GHz = 0;
} else {
if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid 2GHz cal pier index, must "
- "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid 2GHz cal pier index, must be less than %d\n",
+ AR9300_NUM_2G_CAL_PIERS);
return -1;
}
@@ -1637,27 +4246,32 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
{
int tempSlope = 0;
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ int f[3], t[3];
REG_RMW(ah, AR_PHY_TPC_11_B0,
(correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
AR_PHY_TPC_OLPC_GAIN_DELTA);
- REG_RMW(ah, AR_PHY_TPC_11_B1,
- (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
- AR_PHY_TPC_OLPC_GAIN_DELTA);
- REG_RMW(ah, AR_PHY_TPC_11_B2,
- (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
- AR_PHY_TPC_OLPC_GAIN_DELTA);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW(ah, AR_PHY_TPC_11_B1,
+ (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+ AR_PHY_TPC_OLPC_GAIN_DELTA);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW(ah, AR_PHY_TPC_11_B2,
+ (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+ AR_PHY_TPC_OLPC_GAIN_DELTA);
/* enable open loop power control on chip */
REG_RMW(ah, AR_PHY_TPC_6_B0,
(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
AR_PHY_TPC_6_ERROR_EST_MODE);
- REG_RMW(ah, AR_PHY_TPC_6_B1,
- (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
- AR_PHY_TPC_6_ERROR_EST_MODE);
- REG_RMW(ah, AR_PHY_TPC_6_B2,
- (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
- AR_PHY_TPC_6_ERROR_EST_MODE);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW(ah, AR_PHY_TPC_6_B1,
+ (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+ AR_PHY_TPC_6_ERROR_EST_MODE);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW(ah, AR_PHY_TPC_6_B2,
+ (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+ AR_PHY_TPC_6_ERROR_EST_MODE);
/*
* enable temperature compensation
@@ -1665,7 +4279,16 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
*/
if (frequency < 4000)
tempSlope = eep->modalHeader2G.tempSlope;
- else
+ else if (eep->base_ext2.tempSlopeLow != 0) {
+ t[0] = eep->base_ext2.tempSlopeLow;
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.tempSlope;
+ f[1] = 5500;
+ t[2] = eep->base_ext2.tempSlopeHigh;
+ f[2] = 5785;
+ tempSlope = ar9003_hw_power_interpolate((s32) frequency,
+ f, t, 3);
+ } else
tempSlope = eep->modalHeader5G.tempSlope;
REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
@@ -1753,11 +4376,11 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
/* interpolate */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
- ath_print(common, ATH_DBG_EEPROM,
- "ch=%d f=%d low=%d %d h=%d %d\n",
- ichain, frequency, lfrequency[ichain],
- lcorrection[ichain], hfrequency[ichain],
- hcorrection[ichain]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "ch=%d f=%d low=%d %d h=%d %d\n",
+ ichain, frequency, lfrequency[ichain],
+ lcorrection[ichain], hfrequency[ichain],
+ hcorrection[ichain]);
/* they're the same, so just pick one */
if (hfrequency[ichain] == lfrequency[ichain]) {
correction[ichain] = lcorrection[ichain];
@@ -1769,25 +4392,23 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
/* so is the high frequency, interpolate */
if (hfrequency[ichain] - frequency < 1000) {
- correction[ichain] = lcorrection[ichain] +
- (((frequency - lfrequency[ichain]) *
- (hcorrection[ichain] -
- lcorrection[ichain])) /
- (hfrequency[ichain] - lfrequency[ichain]));
-
- temperature[ichain] = ltemperature[ichain] +
- (((frequency - lfrequency[ichain]) *
- (htemperature[ichain] -
- ltemperature[ichain])) /
- (hfrequency[ichain] - lfrequency[ichain]));
-
- voltage[ichain] =
- lvoltage[ichain] +
- (((frequency -
- lfrequency[ichain]) * (hvoltage[ichain] -
- lvoltage[ichain]))
- / (hfrequency[ichain] -
- lfrequency[ichain]));
+ correction[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ lcorrection[ichain],
+ hcorrection[ichain]);
+
+ temperature[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ ltemperature[ichain],
+ htemperature[ichain]);
+
+ voltage[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ lvoltage[ichain],
+ hvoltage[ichain]);
}
/* only low is good, use it */
else {
@@ -1811,9 +4432,9 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
ar9003_hw_power_control_override(ah, frequency, correction, voltage,
temperature);
- ath_print(common, ATH_DBG_EEPROM,
- "for frequency=%d, calibration correction = %d %d %d\n",
- frequency, correction[0], correction[1], correction[2]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "for frequency=%d, calibration correction = %d %d %d\n",
+ frequency, correction[0], correction[1], correction[2]);
return 0;
}
@@ -1827,9 +4448,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
if (is2GHz)
- return ctl_2g[idx].ctlEdges[edge].tPower;
+ return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
else
- return ctl_5g[idx].ctlEdges[edge].tPower;
+ return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
}
static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
@@ -1847,15 +4468,15 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
if (is2GHz) {
if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
- ctl_2g[idx].ctlEdges[edge - 1].flag)
- return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+ CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+ return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
} else {
if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
- ctl_5g[idx].ctlEdges[edge - 1].flag)
- return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+ CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+ return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
}
- return AR9300_MAX_RATE_POWER;
+ return MAX_RATE_POWER;
}
/*
@@ -1864,7 +4485,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
u16 freq, int idx, bool is2GHz)
{
- u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
u8 *ctl_freqbin = is2GHz ?
&eep->ctl_freqbin_2G[idx][0] :
&eep->ctl_freqbin_5G[idx][0];
@@ -1874,7 +4495,7 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
/* Get the edge power */
for (edge = 0;
- (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
+ (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
edge++) {
/*
* If there's an exact channel match or an inband flag set
@@ -1912,21 +4533,23 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah);
struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
- u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] = {
- 0, 3, 6, 9, AR9300_MAX_RATE_POWER
+ 0, 3, 6, 9, MAX_RATE_POWER
};
int i;
int16_t twiceLargestAntenna;
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] = {
+ static const u16 ctlModesFor11a[] = {
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
};
- u16 ctlModesFor11g[] = {
+ static const u16 ctlModesFor11g[] = {
CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
CTL_11G_EXT, CTL_2GHT40
};
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
u8 *ctlIndex;
u8 ctlNum;
@@ -2016,11 +4639,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
else
freq = centers.ctl_center;
- ath_print(common, ATH_DBG_REGULATORY,
- "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
- "EXT_ADDITIVE %d\n",
- ctlMode, numCtlModes, isHt40CtlMode,
- (pCtlMode[ctlMode] & EXT_ADDITIVE));
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
/* walk through each CTL index stored in EEPROM */
if (is2ghz) {
@@ -2032,12 +4654,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
}
for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
- ath_print(common, ATH_DBG_REGULATORY,
- "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
- "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
- "chan %dn",
- i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
- chan->channel);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
+ i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
+ chan->channel);
/*
* compare test group from regulatory
@@ -2076,11 +4696,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
- ath_print(common, ATH_DBG_REGULATORY,
- "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
- "sP %d minCtlPwr %d\n",
- ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
- scaledPower, minCtlPower);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
/* Apply ctl mode to correct target power set */
switch (pCtlMode[ctlMode]) {
@@ -2127,40 +4746,101 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
} /* end ctl mode checking */
}
+static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
+{
+ u8 mod_idx = mcs_idx % 8;
+
+ if (mod_idx <= 3)
+ return mod_idx ? (base_pwridx + 1) : base_pwridx;
+ else
+ return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
+}
+
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
+ struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah);
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ struct ar9300_modal_eep_header *modal_hdr;
u8 targetPowerValT2[ar9300RateSize];
- unsigned int i = 0;
+ u8 target_power_val_t2_eep[ar9300RateSize];
+ unsigned int i = 0, paprd_scale_factor = 0;
+ u8 pwr_idx, min_pwridx = 0;
ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
+
+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ if (IS_CHAN_2GHZ(chan))
+ modal_hdr = &eep->modalHeader2G;
+ else
+ modal_hdr = &eep->modalHeader5G;
+
+ ah->paprd_ratemask =
+ le32_to_cpu(modal_hdr->papdRateMaskHt20) &
+ AR9300_PAPRD_RATE_MASK;
+
+ ah->paprd_ratemask_ht40 =
+ le32_to_cpu(modal_hdr->papdRateMaskHt40) &
+ AR9300_PAPRD_RATE_MASK;
+
+ paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
+ min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
+ ALL_TARGET_HT20_0_8_16;
+
+ if (!ah->paprd_table_write_done) {
+ memcpy(target_power_val_t2_eep, targetPowerValT2,
+ sizeof(targetPowerValT2));
+ for (i = 0; i < 24; i++) {
+ pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
+ if (ah->paprd_ratemask & (1 << i)) {
+ if (targetPowerValT2[pwr_idx] &&
+ targetPowerValT2[pwr_idx] ==
+ target_power_val_t2_eep[pwr_idx])
+ targetPowerValT2[pwr_idx] -=
+ paprd_scale_factor;
+ }
+ }
+ }
+ memcpy(target_power_val_t2_eep, targetPowerValT2,
+ sizeof(targetPowerValT2));
+ }
+
ar9003_hw_set_power_per_rate_table(ah, chan,
targetPowerValT2, cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
powerLimit);
- while (i < ar9300RateSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
- i++;
+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ for (i = 0; i < ar9300RateSize; i++) {
+ if ((ah->paprd_ratemask & (1 << i)) &&
+ (abs(targetPowerValT2[i] -
+ target_power_val_t2_eep[i]) >
+ paprd_scale_factor)) {
+ ah->paprd_ratemask &= ~(1 << i);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "paprd disabled for mcs %d\n", i);
+ }
+ }
}
- /* Write target power array to registers */
- ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+ regulatory->max_power_level = 0;
+ for (i = 0; i < ar9300RateSize; i++) {
+ if (targetPowerValT2[i] > regulatory->max_power_level)
+ regulatory->max_power_level = targetPowerValT2[i];
+ }
+
+ if (test)
+ return;
+
+ for (i = 0; i < ar9300RateSize; i++) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+ }
/*
* This is the TX power we send back to driver core,
@@ -2180,8 +4860,24 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
i = ALL_TARGET_HT20_0_8_16; /* ht20 */
ah->txpower_limit = targetPowerValT2[i];
+ regulatory->max_power_level = targetPowerValT2[i];
+ /* Write target power array to registers */
+ ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
ar9003_hw_calibration_apply(ah, chan->channel);
+
+ if (IS_CHAN_2GHZ(chan)) {
+ if (IS_CHAN_HT40(chan))
+ i = ALL_TARGET_HT40_0_8_16;
+ else
+ i = ALL_TARGET_HT20_0_8_16;
+ } else {
+ if (IS_CHAN_HT40(chan))
+ i = ALL_TARGET_HT40_7;
+ else
+ i = ALL_TARGET_HT20_7;
+ }
+ ah->paprd_target_power = targetPowerValT2[i];
}
static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
@@ -2204,14 +4900,43 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
}
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (is_2ghz)
+ return eep->modalHeader2G.spurChans;
+ else
+ return eep->modalHeader5G.spurChans;
+}
+
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (IS_CHAN_2GHZ(chan))
+ return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
+ AR9300_PAPRD_SCALE_1);
+ else {
+ if (chan->channel >= 5700)
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
+ AR9300_PAPRD_SCALE_1);
+ else if (chan->channel >= 5400)
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_2);
+ else
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_1);
+ }
+}
+
const struct eeprom_ops eep_ar9300_ops = {
.check_eeprom = ath9k_hw_ar9300_check_eeprom,
.get_eeprom = ath9k_hw_ar9300_get_eeprom,
.fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
.get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
.get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
- .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
- .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
.set_board_values = ath9k_hw_ar9300_set_board_values,
.set_addac = ath9k_hw_ar9300_set_addac,
.set_txpower = ath9k_hw_ar9300_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 3c533bb983c7..afb0b5ee1865 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -20,47 +20,22 @@
/* #define AR9300_NUM_CTLS 21 */
#define AR9300_NUM_CTLS_5G 9
#define AR9300_NUM_CTLS_2G 12
-#define AR9300_CTL_MODE_M 0xF
#define AR9300_NUM_BAND_EDGES_5G 8
#define AR9300_NUM_BAND_EDGES_2G 4
-#define AR9300_NUM_PD_GAINS 4
-#define AR9300_PD_GAINS_IN_MASK 4
-#define AR9300_PD_GAIN_ICEPTS 5
-#define AR9300_EEPROM_MODAL_SPURS 5
-#define AR9300_MAX_RATE_POWER 63
-#define AR9300_NUM_PDADC_VALUES 128
-#define AR9300_NUM_RATES 16
-#define AR9300_BCHAN_UNUSED 0xFF
-#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
-#define AR9300_OPFLAGS_11A 0x01
-#define AR9300_OPFLAGS_11G 0x02
-#define AR9300_OPFLAGS_5G_HT40 0x04
-#define AR9300_OPFLAGS_2G_HT40 0x08
-#define AR9300_OPFLAGS_5G_HT20 0x10
-#define AR9300_OPFLAGS_2G_HT20 0x20
#define AR9300_EEPMISC_BIG_ENDIAN 0x01
#define AR9300_EEPMISC_WOW 0x02
#define AR9300_CUSTOMER_DATA_SIZE 20
-#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
#define AR9300_MAX_CHAINS 3
#define AR9300_ANT_16S 25
#define AR9300_FUTURE_MODAL_SZ 6
-#define AR9300_NUM_ANT_CHAIN_FIELDS 7
-#define AR9300_NUM_ANT_COMMON_FIELDS 4
-#define AR9300_SIZE_ANT_CHAIN_FIELD 3
-#define AR9300_SIZE_ANT_COMMON_FIELD 4
-#define AR9300_ANT_CHAIN_MASK 0x7
-#define AR9300_ANT_COMMON_MASK 0xf
-#define AR9300_CHAIN_0_IDX 0
-#define AR9300_CHAIN_1_IDX 1
-#define AR9300_CHAIN_2_IDX 2
-
-#define AR928X_NUM_ANT_CHAIN_FIELDS 6
-#define AR928X_SIZE_ANT_CHAIN_FIELD 2
-#define AR928X_ANT_CHAIN_MASK 0x3
+#define AR9300_PAPRD_RATE_MASK 0x01ffffff
+#define AR9300_PAPRD_SCALE_1 0x0e000000
+#define AR9300_PAPRD_SCALE_1_S 25
+#define AR9300_PAPRD_SCALE_2 0x70000000
+#define AR9300_PAPRD_SCALE_2_S 28
/* Delta from which to start power to pdadc table */
/* This offset is used in both open loop and closed loop power control
@@ -71,14 +46,20 @@
*/
#define AR9300_PWR_TABLE_OFFSET 0
-/* enable flags for voltage and temp compensation */
-#define ENABLE_TEMP_COMPENSATION 0x01
-#define ENABLE_VOLT_COMPENSATION 0x02
/* byte addressable */
#define AR9300_EEPROM_SIZE (16*1024)
-#define FIXED_CCA_THRESHOLD 15
+#define AR9300_BASE_ADDR_4K 0xfff
#define AR9300_BASE_ADDR 0x3ff
+#define AR9300_BASE_ADDR_512 0x1ff
+
+#define AR9300_OTP_BASE 0x14000
+#define AR9300_OTP_STATUS 0x15f18
+#define AR9300_OTP_STATUS_TYPE 0x7
+#define AR9300_OTP_STATUS_VALID 0x4
+#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+#define AR9300_OTP_STATUS_SM_BUSY 0x1
+#define AR9300_OTP_READ_DATA 0x15f1c
enum targetPowerHTRates {
HT_TARGET_RATE_0_8_16,
@@ -216,7 +197,7 @@ struct ar9300_modal_eep_header {
int8_t tempSlope;
int8_t voltSlope;
/* spur channels in usual fbin coding format */
- u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
+ u8 spurChans[AR_EEPROM_MODAL_SPURS];
/* 3 Check if the register is per chain */
int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
u8 ob[AR9300_MAX_CHAINS];
@@ -236,7 +217,7 @@ struct ar9300_modal_eep_header {
u8 thresh62;
__le32 papdRateMaskHt20;
__le32 papdRateMaskHt40;
- u8 futureModal[24];
+ u8 futureModal[10];
} __packed;
struct ar9300_cal_data_per_freq_op_loop {
@@ -261,17 +242,26 @@ struct cal_tgt_pow_ht {
u8 tPow2x[14];
} __packed;
-struct cal_ctl_edge_pwr {
- u8 tPower:6,
- flag:2;
-} __packed;
-
struct cal_ctl_data_2g {
- struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+ u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
} __packed;
struct cal_ctl_data_5g {
- struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+ u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct ar9300_BaseExtension_1 {
+ u8 ant_div_control;
+ u8 future[13];
+} __packed;
+
+struct ar9300_BaseExtension_2 {
+ int8_t tempSlopeLow;
+ int8_t tempSlopeHigh;
+ u8 xatten1DBLow[AR9300_MAX_CHAINS];
+ u8 xatten1MarginLow[AR9300_MAX_CHAINS];
+ u8 xatten1DBHigh[AR9300_MAX_CHAINS];
+ u8 xatten1MarginHigh[AR9300_MAX_CHAINS];
} __packed;
struct ar9300_eeprom {
@@ -283,6 +273,7 @@ struct ar9300_eeprom {
struct ar9300_base_eep_hdr baseEepHeader;
struct ar9300_modal_eep_header modalHeader2G;
+ struct ar9300_BaseExtension_1 base_ext1;
u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
struct ar9300_cal_data_per_freq_op_loop
calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
@@ -302,6 +293,7 @@ struct ar9300_eeprom {
u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
struct ar9300_modal_eep_header modalHeader5G;
+ struct ar9300_BaseExtension_2 base_ext2;
u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
struct ar9300_cal_data_per_freq_op_loop
calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
@@ -322,4 +314,8 @@ struct ar9300_eeprom {
s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
+
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+ struct ath9k_channel *chan);
#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index c2a057156bfa..6137634e46ca 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -17,20 +17,10 @@
#include "hw.h"
#include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h"
+#include "ar9485_initvals.h"
/* General hardware code for the AR9003 hadware family */
-static bool ar9003_hw_macversion_supported(u32 macversion)
-{
- switch (macversion) {
- case AR_SREV_VERSION_9300:
- return true;
- default:
- break;
- }
- return false;
-}
-
/*
* The AR9003 family uses a new INI format (pre, core, post
* arrays per subsystem). This provides support for the
@@ -38,72 +28,134 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
- /* mac */
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
- ar9300_2p2_mac_core,
- ARRAY_SIZE(ar9300_2p2_mac_core), 2);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
- ar9300_2p2_mac_postamble,
- ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
-
- /* bb */
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- ar9300_2p2_baseband_core,
- ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- ar9300_2p2_baseband_postamble,
- ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
-
- /* radio */
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
- ar9300_2p2_radio_core,
- ARRAY_SIZE(ar9300_2p2_radio_core), 2);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
- ar9300_2p2_radio_postamble,
- ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
-
- /* soc */
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
- ar9300_2p2_soc_preamble,
- ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
- ar9300_2p2_soc_postamble,
- ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
-
- /* rx/tx gain */
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
- 5);
-
- /* Load PCIE SERDES settings from INI */
-
- /* Awake Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdes,
- ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
- ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
- 2);
-
- /* Sleep Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9300PciePhy_clkreq_enable_L1_2p2,
- ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
- 2);
-
- /* Fast clock modal settings */
- INIT_INI_ARRAY(&ah->iniModesAdditional,
- ar9300Modes_fast_clock_2p2,
- ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
- 3);
+ if (AR_SREV_9485(ah)) {
+ /* mac */
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+ ar9485_1_0_mac_core,
+ ARRAY_SIZE(ar9485_1_0_mac_core), 2);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+ ar9485_1_0_mac_postamble,
+ ARRAY_SIZE(ar9485_1_0_mac_postamble), 5);
+
+ /* bb */
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0,
+ ARRAY_SIZE(ar9485_1_0), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ ar9485_1_0_baseband_core,
+ ARRAY_SIZE(ar9485_1_0_baseband_core), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ ar9485_1_0_baseband_postamble,
+ ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5);
+
+ /* radio */
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+ ar9485_1_0_radio_core,
+ ARRAY_SIZE(ar9485_1_0_radio_core), 2);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+ ar9485_1_0_radio_postamble,
+ ARRAY_SIZE(ar9485_1_0_radio_postamble), 2);
+
+ /* soc */
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+ ar9485_1_0_soc_preamble,
+ ARRAY_SIZE(ar9485_1_0_soc_preamble), 2);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+
+ /* rx/tx gain */
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_lowest_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+
+ /* Load PCIE SERDES settings from INI */
+
+ /* Awake Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
+ ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
+ ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+ 2);
+
+ /* Sleep Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+ ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1,
+ ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1),
+ 2);
+ } else {
+ /* mac */
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+ ar9300_2p2_mac_core,
+ ARRAY_SIZE(ar9300_2p2_mac_core), 2);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+ ar9300_2p2_mac_postamble,
+ ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
+
+ /* bb */
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ ar9300_2p2_baseband_core,
+ ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ ar9300_2p2_baseband_postamble,
+ ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
+
+ /* radio */
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+ ar9300_2p2_radio_core,
+ ARRAY_SIZE(ar9300_2p2_radio_core), 2);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+ ar9300_2p2_radio_postamble,
+ ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
+
+ /* soc */
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+ ar9300_2p2_soc_preamble,
+ ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+ ar9300_2p2_soc_postamble,
+ ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
+
+ /* rx/tx gain */
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+ 5);
+
+ /* Load PCIE SERDES settings from INI */
+
+ /* Awake Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
+ ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+ ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
+ 2);
+
+ /* Sleep Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+ ar9300PciePhy_clkreq_enable_L1_2p2,
+ ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
+ 2);
+
+ /* Fast clock modal settings */
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
+ ar9300Modes_fast_clock_2p2,
+ ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
+ 3);
+ }
}
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -111,22 +163,52 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_lowest_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 1:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_high_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_high_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_high_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 2:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_low_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_low_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_low_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+ 5);
+ break;
+ case 3:
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_high_power_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_high_power_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
+ 5);
break;
}
}
@@ -136,16 +218,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
- 2);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_rx_gain_1_0),
+ 2);
+ else
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+ 2);
break;
case 1:
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_wo_xlna_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
- 2);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_wo_xlna_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
+ 2);
+ else
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_wo_xlna_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+ 2);
break;
}
}
@@ -216,7 +310,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
- priv_ops->macversion_supported = ar9003_hw_macversion_supported;
ops->config_pci_powersave = ar9003_hw_configpcipowersave;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 3b424ca1ba84..4ceddbbdfcee 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -182,8 +182,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
}
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
@@ -237,73 +237,76 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
struct ath_tx_status *ts)
{
struct ar9003_txs *ads;
+ u32 status;
ads = &ah->ts_ring[ah->ts_tail];
- if ((ads->status8 & AR_TxDone) == 0)
+ status = ACCESS_ONCE(ads->status8);
+ if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
(MS(ads->ds_info, AR_TxRxDesc) != 1)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "Tx Descriptor error %x\n", ads->ds_info);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "Tx Descriptor error %x\n", ads->ds_info);
memset(ads, 0, sizeof(*ads));
return -EIO;
}
+ if (status & AR_TxOpExceeded)
+ ts->ts_status |= ATH9K_TXERR_XTXOP;
+ ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+ ts->ts_seqnum = MS(status, AR_SeqNum);
+ ts->tid = MS(status, AR_TxTid);
+
ts->qid = MS(ads->ds_info, AR_TxQcuNum);
ts->desc_id = MS(ads->status1, AR_TxDescId);
- ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
ts->ts_tstamp = ads->status4;
ts->ts_status = 0;
ts->ts_flags = 0;
- if (ads->status3 & AR_ExcessiveRetries)
+ status = ACCESS_ONCE(ads->status2);
+ ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+ ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+ ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+ if (status & AR_TxBaStatus) {
+ ts->ts_flags |= ATH9K_TX_BA;
+ ts->ba_low = ads->status5;
+ ts->ba_high = ads->status6;
+ }
+
+ status = ACCESS_ONCE(ads->status3);
+ if (status & AR_ExcessiveRetries)
ts->ts_status |= ATH9K_TXERR_XRETRY;
- if (ads->status3 & AR_Filtered)
+ if (status & AR_Filtered)
ts->ts_status |= ATH9K_TXERR_FILT;
- if (ads->status3 & AR_FIFOUnderrun) {
+ if (status & AR_FIFOUnderrun) {
ts->ts_status |= ATH9K_TXERR_FIFO;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status8 & AR_TxOpExceeded)
- ts->ts_status |= ATH9K_TXERR_XTXOP;
- if (ads->status3 & AR_TxTimerExpired)
+ if (status & AR_TxTimerExpired)
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
- if (ads->status3 & AR_DescCfgErr)
+ if (status & AR_DescCfgErr)
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
- if (ads->status3 & AR_TxDataUnderrun) {
+ if (status & AR_TxDataUnderrun) {
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status3 & AR_TxDelimUnderrun) {
+ if (status & AR_TxDelimUnderrun) {
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status2 & AR_TxBaStatus) {
- ts->ts_flags |= ATH9K_TX_BA;
- ts->ba_low = ads->status5;
- ts->ba_high = ads->status6;
- }
+ ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+ ts->ts_longretry = MS(status, AR_DataFailCnt);
+ ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
-
- ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
- ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
- ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
- ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
- ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
- ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
- ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
- ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
- ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
- ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
- ts->ts_antenna = 0;
-
- ts->tid = MS(ads->status8, AR_TxTid);
+ status = ACCESS_ONCE(ads->status7);
+ ts->ts_rssi = MS(status, AR_TxRSSICombined);
+ ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+ ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+ ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
memset(ads, 0, sizeof(*ads));
@@ -319,7 +322,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
if (txpower > ah->txpower_limit)
txpower = ah->txpower_limit;
- txpower += ah->txpower_indexoffset;
if (txpower > 63)
txpower = 63;
@@ -407,12 +409,36 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
u32 aggrLen)
{
+#define FIRST_DESC_NDELIMS 60
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
- ads->ctl17 &= ~AR_AggrLen;
- ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ if (ah->ent_mode & AR_ENT_OTP_MPSD) {
+ u32 ctl17, ndelim;
+ /*
+ * Add delimiter when using RTS/CTS with aggregation
+ * and non enterprise AR9003 card
+ */
+ ctl17 = ads->ctl17;
+ ndelim = MS(ctl17, AR_PadDelim);
+
+ if (ndelim < FIRST_DESC_NDELIMS) {
+ aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
+ ndelim = FIRST_DESC_NDELIMS;
+ }
+
+ ctl17 &= ~AR_AggrLen;
+ ctl17 |= SM(aggrLen, AR_AggrLen);
+
+ ctl17 &= ~AR_PadDelim;
+ ctl17 |= SM(ndelim, AR_PadDelim);
+
+ ads->ctl17 = ctl17;
+ } else {
+ ads->ctl17 &= ~AR_AggrLen;
+ ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ }
}
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
@@ -587,9 +613,9 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
* possibly be reviewing the last subframe. AR_CRCErr
* is the CRC of the actual data.
*/
- if (rxsp->status11 & AR_CRCErr) {
+ if (rxsp->status11 & AR_CRCErr)
rxs->rs_status |= ATH9K_RXERR_CRC;
- } else if (rxsp->status11 & AR_PHYErr) {
+ if (rxsp->status11 & AR_PHYErr) {
phyerr = MS(rxsp->status11, AR_PHYErrCode);
/*
* If we reach a point here where AR_PostDelimCRCErr is
@@ -612,11 +638,12 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_phyerr = phyerr;
}
- } else if (rxsp->status11 & AR_DecryptCRCErr) {
+ }
+ if (rxsp->status11 & AR_DecryptCRCErr)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
- } else if (rxsp->status11 & AR_MichaelErr) {
+ if (rxsp->status11 & AR_MichaelErr)
rxs->rs_status |= ATH9K_RXERR_MIC;
- } else if (rxsp->status11 & AR_KeyMiss)
+ if (rxsp->status11 & AR_KeyMiss)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
}
@@ -631,10 +658,10 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
memset((void *) ah->ts_ring, 0,
ah->ts_size * sizeof(struct ar9003_txs));
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
- ah->ts_paddr_start, ah->ts_paddr_end,
- ah->ts_ring, ah->ts_size);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
+ ah->ts_paddr_start, ah->ts_paddr_end,
+ ah->ts_ring, ah->ts_size);
REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 9f2cea70a840..45cc7e80436c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -65,7 +65,7 @@ struct ar9003_rxs {
u32 status9;
u32 status10;
u32 status11;
-} __packed;
+} __packed __aligned(4);
/* Transmit Control Descriptor */
struct ar9003_txc {
@@ -93,7 +93,7 @@ struct ar9003_txc {
u32 ctl21; /* DMA control 21 */
u32 ctl22; /* DMA control 22 */
u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
-} __packed;
+} __packed __aligned(4);
struct ar9003_txs {
u32 ds_info;
@@ -105,7 +105,7 @@ struct ar9003_txs {
u32 status6;
u32 status7;
u32 status8;
-} __packed;
+} __packed __aligned(4);
void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 716db414c258..356d2fd78822 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,45 +19,124 @@
void ar9003_paprd_enable(struct ath_hw *ah, bool val)
{
+ struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+ struct ath9k_channel *chan = ah->curchan;
+
+ if (val) {
+ ah->paprd_table_write_done = true;
+
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(regulatory, chan),
+ chan->chan->max_antenna_gain * 2,
+ chan->chan->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) regulatory->power_limit), false);
+ }
+
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
- AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
- AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
}
EXPORT_SYMBOL(ar9003_paprd_enable);
-static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
+static int ar9003_get_training_power_2g(struct ath_hw *ah)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
+ unsigned int power, scale, delta;
+
+ scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
+ power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
+
+ delta = abs((int) ah->paprd_target_power - (int) power);
+ if (delta > scale)
+ return -1;
+
+ if (delta < 4)
+ power -= 4 - delta;
+
+ return power;
+}
+
+static int ar9003_get_training_power_5g(struct ath_hw *ah)
{
+ struct ath_common *common = ath9k_hw_common(ah);
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
- struct ar9300_modal_eep_header *hdr;
- const u32 ctrl0[3] = {
+ struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
+ struct ath9k_channel *chan = ah->curchan;
+ unsigned int power, scale, delta;
+
+ if (chan->channel >= 5700)
+ scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
+ AR9300_PAPRD_SCALE_1);
+ else if (chan->channel >= 5400)
+ scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_2);
+ else
+ scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_1);
+
+ if (IS_CHAN_HT40(chan))
+ power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
+ AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
+ else
+ power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
+ AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
+
+ power += scale;
+ delta = abs((int) ah->paprd_target_power - (int) power);
+ if (delta > scale)
+ return -1;
+
+ power += 2 * get_streams(common->tx_chainmask);
+ return power;
+}
+
+static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ static const u32 ctrl0[3] = {
AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_B1,
AR_PHY_PAPRD_CTRL0_B2
};
- const u32 ctrl1[3] = {
+ static const u32 ctrl1[3] = {
AR_PHY_PAPRD_CTRL1_B0,
AR_PHY_PAPRD_CTRL1_B1,
AR_PHY_PAPRD_CTRL1_B2
};
- u32 am_mask, ht40_mask;
+ int training_power;
int i;
- if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
- hdr = &eep->modalHeader5G;
+ if (IS_CHAN_2GHZ(ah->curchan))
+ training_power = ar9003_get_training_power_2g(ah);
else
- hdr = &eep->modalHeader2G;
-
- am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
- ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
+ training_power = ar9003_get_training_power_5g(ah);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
-
- for (i = 0; i < 3; i++) {
+ if (training_power < 0) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "PAPRD target power delta out of range");
+ return -ERANGE;
+ }
+ ah->paprd_training_power = training_power;
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Training power: %d, Target power: %d\n",
+ ah->paprd_training_power, ah->paprd_target_power);
+
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
+ ah->paprd_ratemask);
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
+ ah->paprd_ratemask);
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
+ ah->paprd_ratemask_ht40);
+
+ for (i = 0; i < ah->caps.max_txchains; i++) {
REG_RMW_FIELD(ah, ctrl0[i],
AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
REG_RMW_FIELD(ah, ctrl1[i],
@@ -102,8 +181,14 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
- AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
+ if (AR_SREV_9485(ah))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
+ -3);
+ else
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
+ -6);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
-15);
@@ -132,6 +217,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
+ return 0;
}
static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
@@ -586,15 +672,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
{
u32 *paprd_table_val = caldata->pa_table[chain];
u32 small_signal_gain = caldata->small_signal_gain[chain];
- u32 training_power;
+ u32 training_power = ah->paprd_training_power;
u32 reg = 0;
int i;
- training_power =
- REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
- AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
- training_power -= 4;
-
if (chain == 0)
reg = AR_PHY_PAPRD_MEM_TAB_B0;
else if (chain == 1)
@@ -620,26 +701,22 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
training_power);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
- AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
- training_power);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
+ training_power);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
- AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
- training_power);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
+ training_power);
}
EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
{
-
unsigned int i, desired_gain, gain_index;
- unsigned int train_power;
-
- train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
- AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
-
- train_power = train_power - 4;
+ unsigned int train_power = ah->paprd_training_power;
desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
@@ -705,7 +782,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
int ar9003_paprd_init_table(struct ath_hw *ah)
{
- ar9003_paprd_setup_single_table(ah);
+ int ret;
+
+ ret = ar9003_paprd_setup_single_table(ah);
+ if (ret < 0)
+ return ret;
+
ar9003_paprd_get_gain_table(ah);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 669b777729b3..8d60f4f09acc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -75,7 +75,10 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
freq = centers.synth_center;
if (freq < 4800) { /* 2 GHz, fractional mode */
- channelSel = CHANSEL_2G(freq);
+ if (AR_SREV_9485(ah))
+ channelSel = CHANSEL_2G_9485(freq);
+ else
+ channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */
bMode = 1;
} else {
@@ -128,24 +131,53 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
+ static const u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
int cur_bb_spur, negative = 0, cck_spur_freq;
int i;
+ int range, max_spur_cnts, synth_freq;
+ u8 *spur_fbin_ptr = NULL;
/*
* Need to verify range +/- 10 MHz in control channel, otherwise spur
* is out-of-band and can be ignored.
*/
- for (i = 0; i < 4; i++) {
+ if (AR_SREV_9485(ah)) {
+ spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
+ IS_CHAN_2GHZ(chan));
+ if (spur_fbin_ptr[0] == 0) /* No spur */
+ return;
+ max_spur_cnts = 5;
+ if (IS_CHAN_HT40(chan)) {
+ range = 19;
+ if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+ AR_PHY_GC_DYN2040_PRI_CH) == 0)
+ synth_freq = chan->channel + 10;
+ else
+ synth_freq = chan->channel - 10;
+ } else {
+ range = 10;
+ synth_freq = chan->channel;
+ }
+ } else {
+ range = 10;
+ max_spur_cnts = 4;
+ synth_freq = chan->channel;
+ }
+
+ for (i = 0; i < max_spur_cnts; i++) {
negative = 0;
- cur_bb_spur = spur_freq[i] - chan->channel;
+ if (AR_SREV_9485(ah))
+ cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
+ IS_CHAN_2GHZ(chan)) - synth_freq;
+ else
+ cur_bb_spur = spur_freq[i] - synth_freq;
if (cur_bb_spur < 0) {
negative = 1;
cur_bb_spur = -cur_bb_spur;
}
- if (cur_bb_spur < 10) {
+ if (cur_bb_spur < range) {
cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
if (negative == 1)
@@ -487,7 +519,11 @@ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
break;
}
- REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+ if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
+ REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
+ else
+ REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+
if (tx == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
@@ -542,10 +578,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
u32 reg = INI_RA(iniArr, i, 0);
u32 val = INI_RA(iniArr, i, column);
- if (reg >= 0x16000 && reg < 0x17000)
- ath9k_hw_analog_shift_regwrite(ah, reg, val);
- else
- REG_WRITE(ah, reg, val);
+ REG_WRITE(ah, reg, val);
DO_DELAY(regWrites);
}
@@ -614,7 +647,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
return 0;
}
@@ -712,28 +745,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
}
-/*
- * Set the interrupt and GPIO values so the ISR can disable RF
- * on a switch signal. Assumes GPIO port and interrupt polarity
- * are set prior to call.
- */
-static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
-{
- /* Connect rfsilent_bb_l to baseband */
- REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
- AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
- /* Set input mux for rfsilent_bb_l to GPIO #0 */
- REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
- AR_GPIO_INPUT_MUX2_RFSILENT);
-
- /*
- * Configure the desired GPIO port for input and
- * enable baseband rf silence.
- */
- ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
- REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-
static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
{
u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
@@ -820,12 +831,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
if (!on != aniState->ofdmWeakSigDetectOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: ofdm weak signal: %s=>%s\n",
- chan->channel,
- !aniState->ofdmWeakSigDetectOff ?
- "on" : "off",
- on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: ofdm weak signal: %s=>%s\n",
+ chan->channel,
+ !aniState->ofdmWeakSigDetectOff ?
+ "on" : "off",
+ on ? "on" : "off");
if (on)
ah->stats.ast_ani_ofdmon++;
else
@@ -838,11 +849,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(firstep_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_FIRSTEP_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep_table));
return false;
}
@@ -877,24 +886,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
if (level != aniState->firstepLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value,
- aniState->iniDef.firstep);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep_low[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value2,
- aniState->iniDef.firstepLow);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value,
+ aniState->iniDef.firstep);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value2,
+ aniState->iniDef.firstepLow);
if (level > aniState->firstepLevel)
ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
@@ -907,11 +914,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1_table));
return false;
}
/*
@@ -945,24 +950,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_EXT_CYCPWR_THR1, value2);
if (level != aniState->spurImmunityLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value,
- aniState->iniDef.cycpwrThr1);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1Ext[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value2,
- aniState->iniDef.cycpwrThr1Ext);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value,
+ aniState->iniDef.cycpwrThr1);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value2,
+ aniState->iniDef.cycpwrThr1Ext);
if (level > aniState->spurImmunityLevel)
ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
@@ -982,11 +985,11 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
AR_PHY_MRC_CCK_MUX_REG, is_on);
if (!is_on != aniState->mrcCCKOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: MRC CCK: %s=>%s\n",
- chan->channel,
- !aniState->mrcCCKOff ? "on" : "off",
- is_on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: MRC CCK: %s=>%s\n",
+ chan->channel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ is_on ? "on" : "off");
if (is_on)
ah->stats.ast_ani_ccklow++;
else
@@ -998,22 +1001,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI,
- "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d "
- "ofdmErrs=%d cckErrs=%d\n",
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
- aniState->firstepLevel,
- !aniState->mrcCCKOff ? "on" : "off",
- aniState->listenTime,
- aniState->ofdmPhyErrCount,
- aniState->cckPhyErrCount);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+ aniState->firstepLevel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ aniState->listenTime,
+ aniState->ofdmPhyErrCount,
+ aniState->cckPhyErrCount);
return true;
}
@@ -1023,25 +1023,25 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
- nfarray[2] = sign_extend(nf, 9);
+ nfarray[2] = sign_extend32(nf, 8);
if (!IS_CHAN_HT40(ah->curchan))
return;
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
- nfarray[5] = sign_extend(nf, 9);
+ nfarray[5] = sign_extend32(nf, 8);
}
static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
@@ -1070,13 +1070,13 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState = &ah->curchan->ani;
iniDef = &aniState->iniDef;
- ath_print(common, ATH_DBG_ANI,
- "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
- ah->hw_version.macVersion,
- ah->hw_version.macRev,
- ah->opmode,
- chan->channel,
- chan->channelFlags);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+ ah->hw_version.macVersion,
+ ah->hw_version.macRev,
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1113,10 +1113,55 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
}
+static void ar9003_hw_set_radar_params(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf)
+{
+ u32 radar_0 = 0, radar_1 = 0;
+
+ if (!conf) {
+ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+ return;
+ }
+
+ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+ if (conf->ext_channel)
+ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+ else
+ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
+{
+ struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+ conf->fir_power = -28;
+ conf->radar_rssi = 0;
+ conf->pulse_height = 10;
+ conf->pulse_rssi = 24;
+ conf->pulse_inband = 8;
+ conf->pulse_maxlen = 255;
+ conf->pulse_inband_step = 12;
+ conf->radar_inband = 8;
+}
+
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
- const u32 ar9300_cca_regs[6] = {
+ static const u32 ar9300_cca_regs[6] = {
AR_PHY_CCA_0,
AR_PHY_CCA_1,
AR_PHY_CCA_2,
@@ -1136,13 +1181,14 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
priv_ops->rfbus_req = ar9003_hw_rfbus_req;
priv_ops->rfbus_done = ar9003_hw_rfbus_done;
- priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
priv_ops->set_diversity = ar9003_hw_set_diversity;
priv_ops->ani_control = ar9003_hw_ani_control;
priv_ops->do_getnf = ar9003_hw_do_getnf;
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
+ priv_ops->set_radar_params = ar9003_hw_set_radar_params;
ar9003_hw_set_nf_limits(ah);
+ ar9003_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
}
@@ -1165,7 +1211,7 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
AR_PHY_WATCHDOG_IDLE_ENABLE));
- ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
+ ath_dbg(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
return;
}
@@ -1201,9 +1247,9 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
AR_PHY_WATCHDOG_IDLE_MASK |
(AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2)));
- ath_print(common, ATH_DBG_RESET,
- "Enabled BB Watchdog timeout (%u ms)\n",
- idle_tmo_ms);
+ ath_dbg(common, ATH_DBG_RESET,
+ "Enabled BB Watchdog timeout (%u ms)\n",
+ idle_tmo_ms);
}
void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
@@ -1231,37 +1277,35 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
return;
status = ah->bb_watchdog_last_status;
- ath_print(common, ATH_DBG_RESET,
- "\n==== BB update: BB status=0x%08x ====\n", status);
- ath_print(common, ATH_DBG_RESET,
- "** BB state: wd=%u det=%u rdar=%u rOFDM=%d "
- "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
- MS(status, AR_PHY_WATCHDOG_INFO),
- MS(status, AR_PHY_WATCHDOG_DET_HANG),
- MS(status, AR_PHY_WATCHDOG_RADAR_SM),
- MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
- MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
- MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
- MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
- MS(status, AR_PHY_WATCHDOG_AGC_SM),
- MS(status,AR_PHY_WATCHDOG_SRCH_SM));
-
- ath_print(common, ATH_DBG_RESET,
- "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
- REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
- REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
- ath_print(common, ATH_DBG_RESET,
- "** BB mode: BB_gen_controls=0x%08x **\n",
- REG_READ(ah, AR_PHY_GEN_CTRL));
+ ath_dbg(common, ATH_DBG_RESET,
+ "\n==== BB update: BB status=0x%08x ====\n", status);
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB state: wd=%u det=%u rdar=%u rOFDM=%d rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
+ MS(status, AR_PHY_WATCHDOG_INFO),
+ MS(status, AR_PHY_WATCHDOG_DET_HANG),
+ MS(status, AR_PHY_WATCHDOG_RADAR_SM),
+ MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
+ MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
+ MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
+ MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
+ MS(status, AR_PHY_WATCHDOG_AGC_SM),
+ MS(status, AR_PHY_WATCHDOG_SRCH_SM));
+
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
+ REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
+ REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB mode: BB_gen_controls=0x%08x **\n",
+ REG_READ(ah, AR_PHY_GEN_CTRL));
#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
if (common->cc_survey.cycles)
- ath_print(common, ATH_DBG_RESET,
- "** BB busy times: rx_clear=%d%%, "
- "rx_frame=%d%%, tx_frame=%d%% **\n",
- PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB busy times: rx_clear=%d%%, rx_frame=%d%%, tx_frame=%d%% **\n",
+ PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
- ath_print(common, ATH_DBG_RESET,
- "==== BB update: done ====\n\n");
+ ath_dbg(common, ATH_DBG_RESET,
+ "==== BB update: done ====\n\n");
}
EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 3394dfe52b42..59bab6bd8a74 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -260,7 +260,13 @@
#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c)
#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
+
#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
+#define AR_ANT_DIV_CTRL_ALL 0x7e000000
+#define AR_ANT_DIV_CTRL_ALL_S 25
+#define AR_ANT_DIV_ENABLE 0x1000000
+#define AR_ANT_DIV_ENABLE_S 24
+
#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
@@ -271,7 +277,11 @@
#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
#define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180)
#define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184)
+
#define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0)
+#define AR_FAST_DIV_ENABLE 0x2000
+#define AR_FAST_DIV_ENABLE_S 13
+
#define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4)
#define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8)
@@ -536,10 +546,18 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
+#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
+#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
+#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
+#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
+#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
+
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x3d0 : 0x450) + ((_i) << 2))
#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
@@ -568,7 +586,7 @@
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
-#define AR_PHY_65NM_CH0_THERM 0x16290
+#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@@ -584,6 +602,24 @@
#define AR_PHY_65NM_CH2_RXTX1 0x16900
#define AR_PHY_65NM_CH2_RXTX2 0x16904
+#define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c)
+#define AR_CH0_TOP2_XPABIASLVL 0xf000
+#define AR_CH0_TOP2_XPABIASLVL_S 12
+
+#define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294)
+#define AR_CH0_XTAL_CAPINDAC 0x7f000000
+#define AR_CH0_XTAL_CAPINDAC_S 24
+#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
+#define AR_CH0_XTAL_CAPOUTDAC_S 17
+
+#define AR_PHY_PMU1 0x16c40
+#define AR_PHY_PMU1_PWD 0x1
+#define AR_PHY_PMU1_PWD_S 0
+
+#define AR_PHY_PMU2 0x16c44
+#define AR_PHY_PMU2_PGM 0x00200000
+#define AR_PHY_PMU2_PGM_S 21
+
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19
#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000
@@ -683,6 +719,7 @@
#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
#define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001
#define AR_PHY_TXGAIN_FORCE 0x00000001
+#define AR_PHY_TXGAIN_FORCE_S 0
#define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00
#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10
#define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000
@@ -725,8 +762,13 @@
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
+#define AR_PHY_CALIBRATED_GAINS_0 0x3e
+#define AR_PHY_CALIBRATED_GAINS_0_S 1
+
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE 0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE_S 0
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x0fffc000
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 14
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
@@ -785,7 +827,7 @@
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240)
#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2))
/*
* Channel 2 Register Map
@@ -838,7 +880,7 @@
#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
#define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240)
#define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2))
#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001
@@ -945,7 +987,9 @@
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17
-#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490)
+#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x580 : 0x490))
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e
@@ -961,11 +1005,15 @@
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12
-#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494)
+#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x584 : 0x494))
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0
-#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498)
+#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x588 : 0x498))
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0
@@ -981,7 +1029,9 @@
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29
-#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c)
+#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x58c : 0x49c))
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000
@@ -1040,6 +1090,14 @@
#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
+#define AR_PHY_POWERTX_RATE6 (AR_SM_BASE + 0x1d4)
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5 0x3F00
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S 8
+
+#define AR_PHY_POWERTX_RATE8 (AR_SM_BASE + 0x1dc)
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8
+
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
new file mode 100644
index 000000000000..70de3d89a7b5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9485_H
+#define INITVALS_9485_H
+
+static const u32 ar9485Common_1_0[][2] = {
+ /* Addr allmodes */
+ {0x00007010, 0x00000022},
+ {0x00007020, 0x00000000},
+ {0x00007034, 0x00000002},
+ {0x00007038, 0x000004c2},
+};
+
+static const u32 ar9485_1_0_mac_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+ {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+ {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+ {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+ {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+ {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+ {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+ {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10212e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x01800082},
+ {0x0000a014, 0x01820181},
+ {0x0000a018, 0x01840183},
+ {0x0000a01c, 0x01880185},
+ {0x0000a020, 0x018a0189},
+ {0x0000a024, 0x02850284},
+ {0x0000a028, 0x02890288},
+ {0x0000a02c, 0x03850384},
+ {0x0000a030, 0x03890388},
+ {0x0000a034, 0x038b038a},
+ {0x0000a038, 0x038d038c},
+ {0x0000a03c, 0x03910390},
+ {0x0000a040, 0x03930392},
+ {0x0000a044, 0x03950394},
+ {0x0000a048, 0x00000396},
+ {0x0000a04c, 0x00000000},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x28282828},
+ {0x0000a084, 0x28282828},
+ {0x0000a088, 0x28282828},
+ {0x0000a08c, 0x28282828},
+ {0x0000a090, 0x28282828},
+ {0x0000a094, 0x21212128},
+ {0x0000a098, 0x171c1c1c},
+ {0x0000a09c, 0x02020212},
+ {0x0000a0a0, 0x00000202},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x111f1100},
+ {0x0000a0c8, 0x111d111e},
+ {0x0000a0cc, 0x111b111c},
+ {0x0000a0d0, 0x22032204},
+ {0x0000a0d4, 0x22012202},
+ {0x0000a0d8, 0x221f2200},
+ {0x0000a0dc, 0x221d221e},
+ {0x0000a0e0, 0x33013302},
+ {0x0000a0e4, 0x331f3300},
+ {0x0000a0e8, 0x4402331e},
+ {0x0000a0ec, 0x44004401},
+ {0x0000a0f0, 0x441e441f},
+ {0x0000a0f4, 0x55015502},
+ {0x0000a0f8, 0x551f5500},
+ {0x0000a0fc, 0x6602551e},
+ {0x0000a100, 0x66006601},
+ {0x0000a104, 0x661e661f},
+ {0x0000a108, 0x7703661d},
+ {0x0000a10c, 0x77017702},
+ {0x0000a110, 0x00007700},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x111f1100},
+ {0x0000a148, 0x111d111e},
+ {0x0000a14c, 0x111b111c},
+ {0x0000a150, 0x22032204},
+ {0x0000a154, 0x22012202},
+ {0x0000a158, 0x221f2200},
+ {0x0000a15c, 0x221d221e},
+ {0x0000a160, 0x33013302},
+ {0x0000a164, 0x331f3300},
+ {0x0000a168, 0x4402331e},
+ {0x0000a16c, 0x44004401},
+ {0x0000a170, 0x441e441f},
+ {0x0000a174, 0x55015502},
+ {0x0000a178, 0x551f5500},
+ {0x0000a17c, 0x6602551e},
+ {0x0000a180, 0x66006601},
+ {0x0000a184, 0x661e661f},
+ {0x0000a188, 0x7703661d},
+ {0x0000a18c, 0x77017702},
+ {0x0000a190, 0x00007700},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000296},
+};
+
+static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a580, 0x00000000},
+ {0x0000a584, 0x00000000},
+ {0x0000a588, 0x00000000},
+ {0x0000a58c, 0x00000000},
+ {0x0000a590, 0x00000000},
+ {0x0000a594, 0x00000000},
+ {0x0000a598, 0x00000000},
+ {0x0000a59c, 0x00000000},
+ {0x0000a5a0, 0x00000000},
+ {0x0000a5a4, 0x00000000},
+ {0x0000a5a8, 0x00000000},
+ {0x0000a5ac, 0x00000000},
+ {0x0000a5b0, 0x00000000},
+ {0x0000a5b4, 0x00000000},
+ {0x0000a5b8, 0x00000000},
+ {0x0000a5bc, 0x00000000},
+};
+
+static const u32 ar9485_1_0_radio_core[][2] = {
+ /* Addr allmodes */
+ {0x00016000, 0x36db6db6},
+ {0x00016004, 0x6db6db40},
+ {0x00016008, 0x73800000},
+ {0x0001600c, 0x00000000},
+ {0x00016040, 0x7f80fff8},
+ {0x00016048, 0x6c92426e},
+ {0x0001604c, 0x000f0278},
+ {0x00016050, 0x6db6db6c},
+ {0x00016054, 0x6db60000},
+ {0x00016080, 0x00080000},
+ {0x00016084, 0x0e48048c},
+ {0x00016088, 0x14214514},
+ {0x0001608c, 0x119f081e},
+ {0x00016090, 0x24926490},
+ {0x00016098, 0xd28b3330},
+ {0x000160a0, 0xc2108ffe},
+ {0x000160a4, 0x812fc370},
+ {0x000160a8, 0x423c8000},
+ {0x000160b4, 0x92480040},
+ {0x000160c0, 0x006db6db},
+ {0x000160c4, 0x0186db60},
+ {0x000160c8, 0x6db6db6c},
+ {0x000160cc, 0x6de6fbe0},
+ {0x000160d0, 0xf7dfcf3c},
+ {0x00016100, 0x04cb0001},
+ {0x00016104, 0xfff80015},
+ {0x00016108, 0x00080010},
+ {0x00016144, 0x01884080},
+ {0x00016148, 0x00008040},
+ {0x00016180, 0x08453333},
+ {0x00016184, 0x18e82f01},
+ {0x00016188, 0x00000000},
+ {0x0001618c, 0x00000000},
+ {0x00016240, 0x08400000},
+ {0x00016244, 0x1bf90f00},
+ {0x00016248, 0x00000000},
+ {0x0001624c, 0x00000000},
+ {0x00016280, 0x01000015},
+ {0x00016284, 0x00d30000},
+ {0x00016288, 0x00318000},
+ {0x0001628c, 0x50000000},
+ {0x00016290, 0x4b96210f},
+ {0x00016380, 0x00000000},
+ {0x00016384, 0x00000000},
+ {0x00016388, 0x00800700},
+ {0x0001638c, 0x00800700},
+ {0x00016390, 0x00800700},
+ {0x00016394, 0x00000000},
+ {0x00016398, 0x00000000},
+ {0x0001639c, 0x00000000},
+ {0x000163a0, 0x00000001},
+ {0x000163a4, 0x00000001},
+ {0x000163a8, 0x00000000},
+ {0x000163ac, 0x00000000},
+ {0x000163b0, 0x00000000},
+ {0x000163b4, 0x00000000},
+ {0x000163b8, 0x00000000},
+ {0x000163bc, 0x00000000},
+ {0x000163c0, 0x000000a0},
+ {0x000163c4, 0x000c0000},
+ {0x000163c8, 0x14021402},
+ {0x000163cc, 0x00001402},
+ {0x000163d0, 0x00000000},
+ {0x000163d4, 0x00000000},
+ {0x00016c40, 0x1319c178},
+ {0x00016c44, 0x10000000},
+};
+
+static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0_baseband_core[][2] = {
+ /* Addr allmodes */
+ {0x00009800, 0xafe68e30},
+ {0x00009804, 0xfd14e000},
+ {0x00009808, 0x9c0a8f6b},
+ {0x0000980c, 0x04800000},
+ {0x00009814, 0x9280c00a},
+ {0x00009818, 0x00000000},
+ {0x0000981c, 0x00020028},
+ {0x00009834, 0x5f3ca3de},
+ {0x00009838, 0x0108ecff},
+ {0x0000983c, 0x14750600},
+ {0x00009880, 0x201fff00},
+ {0x00009884, 0x00001042},
+ {0x000098a4, 0x00200400},
+ {0x000098b0, 0x52440bbe},
+ {0x000098bc, 0x00000002},
+ {0x000098d0, 0x004b6a8e},
+ {0x000098d4, 0x00000820},
+ {0x000098dc, 0x00000000},
+ {0x000098f0, 0x00000000},
+ {0x000098f4, 0x00000000},
+ {0x00009c04, 0x00000000},
+ {0x00009c08, 0x03200000},
+ {0x00009c0c, 0x00000000},
+ {0x00009c10, 0x00000000},
+ {0x00009c14, 0x00046384},
+ {0x00009c18, 0x05b6b440},
+ {0x00009c1c, 0x00b6b440},
+ {0x00009d00, 0xc080a333},
+ {0x00009d04, 0x40206c10},
+ {0x00009d08, 0x009c4060},
+ {0x00009d0c, 0x1883800a},
+ {0x00009d10, 0x01834061},
+ {0x00009d14, 0x00c00400},
+ {0x00009d18, 0x00000000},
+ {0x00009d1c, 0x00000000},
+ {0x00009e08, 0x0038233c},
+ {0x00009e24, 0x990bb515},
+ {0x00009e28, 0x0a6f0000},
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+ {0x00009e40, 0x0d261820},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009fc0, 0x80be4788},
+ {0x00009fc4, 0x0001efb5},
+ {0x00009fcc, 0x40000014},
+ {0x0000a20c, 0x00000000},
+ {0x0000a210, 0x00000000},
+ {0x0000a220, 0x00000000},
+ {0x0000a224, 0x00000000},
+ {0x0000a228, 0x10002310},
+ {0x0000a23c, 0x00000000},
+ {0x0000a244, 0x0c000000},
+ {0x0000a2a0, 0x00000001},
+ {0x0000a2c0, 0x00000001},
+ {0x0000a2c8, 0x00000000},
+ {0x0000a2cc, 0x18c43433},
+ {0x0000a2d4, 0x00000000},
+ {0x0000a2dc, 0x00000000},
+ {0x0000a2e0, 0x00000000},
+ {0x0000a2e4, 0x00000000},
+ {0x0000a2e8, 0x00000000},
+ {0x0000a2ec, 0x00000000},
+ {0x0000a2f0, 0x00000000},
+ {0x0000a2f4, 0x00000000},
+ {0x0000a2f8, 0x00000000},
+ {0x0000a344, 0x00000000},
+ {0x0000a34c, 0x00000000},
+ {0x0000a350, 0x0000a000},
+ {0x0000a364, 0x00000000},
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+ {0x0000a398, 0x001f0e0f},
+ {0x0000a39c, 0x0075393f},
+ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x00000000},
+ {0x0000a3a8, 0xaaaaaaaa},
+ {0x0000a3ac, 0x3c466478},
+ {0x0000a3c0, 0x20202020},
+ {0x0000a3c4, 0x22222220},
+ {0x0000a3c8, 0x20200020},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3d8, 0x20202020},
+ {0x0000a3dc, 0x20202020},
+ {0x0000a3e0, 0x20202020},
+ {0x0000a3e4, 0x20202020},
+ {0x0000a3e8, 0x20202020},
+ {0x0000a3ec, 0x20202020},
+ {0x0000a3f0, 0x00000000},
+ {0x0000a3f4, 0x00000006},
+ {0x0000a3f8, 0x0cdbd380},
+ {0x0000a3fc, 0x000f0f01},
+ {0x0000a400, 0x8fa91f01},
+ {0x0000a404, 0x00000000},
+ {0x0000a408, 0x0e79e5c6},
+ {0x0000a40c, 0x00820820},
+ {0x0000a414, 0x1ce739ce},
+ {0x0000a418, 0x2d0011ce},
+ {0x0000a41c, 0x1ce739ce},
+ {0x0000a420, 0x000001ce},
+ {0x0000a424, 0x1ce739ce},
+ {0x0000a428, 0x000001ce},
+ {0x0000a42c, 0x1ce739ce},
+ {0x0000a430, 0x1ce739ce},
+ {0x0000a434, 0x00000000},
+ {0x0000a438, 0x00001801},
+ {0x0000a43c, 0x00000000},
+ {0x0000a440, 0x00000000},
+ {0x0000a444, 0x00000000},
+ {0x0000a448, 0x04000000},
+ {0x0000a44c, 0x00000001},
+ {0x0000a450, 0x00010000},
+ {0x0000a458, 0x00000000},
+ {0x0000a5c4, 0x3fad9d74},
+ {0x0000a5c8, 0x0048060a},
+ {0x0000a5cc, 0x00000637},
+ {0x0000a760, 0x03020100},
+ {0x0000a764, 0x09080504},
+ {0x0000a768, 0x0d0c0b0a},
+ {0x0000a76c, 0x13121110},
+ {0x0000a770, 0x31301514},
+ {0x0000a774, 0x35343332},
+ {0x0000a778, 0x00000036},
+ {0x0000a780, 0x00000838},
+ {0x0000a7c0, 0x00000000},
+ {0x0000a7c4, 0xfffffffc},
+ {0x0000a7c8, 0x00000000},
+ {0x0000a7cc, 0x00000000},
+ {0x0000a7d0, 0x00000000},
+ {0x0000a7d4, 0x00000004},
+ {0x0000a7dc, 0x00000001},
+};
+
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485Common_rx_gain_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x01800082},
+ {0x0000a014, 0x01820181},
+ {0x0000a018, 0x01840183},
+ {0x0000a01c, 0x01880185},
+ {0x0000a020, 0x018a0189},
+ {0x0000a024, 0x02850284},
+ {0x0000a028, 0x02890288},
+ {0x0000a02c, 0x03850384},
+ {0x0000a030, 0x03890388},
+ {0x0000a034, 0x038b038a},
+ {0x0000a038, 0x038d038c},
+ {0x0000a03c, 0x03910390},
+ {0x0000a040, 0x03930392},
+ {0x0000a044, 0x03950394},
+ {0x0000a048, 0x00000396},
+ {0x0000a04c, 0x00000000},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x28282828},
+ {0x0000a084, 0x28282828},
+ {0x0000a088, 0x28282828},
+ {0x0000a08c, 0x28282828},
+ {0x0000a090, 0x28282828},
+ {0x0000a094, 0x21212128},
+ {0x0000a098, 0x171c1c1c},
+ {0x0000a09c, 0x02020212},
+ {0x0000a0a0, 0x00000202},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x111f1100},
+ {0x0000a0c8, 0x111d111e},
+ {0x0000a0cc, 0x111b111c},
+ {0x0000a0d0, 0x22032204},
+ {0x0000a0d4, 0x22012202},
+ {0x0000a0d8, 0x221f2200},
+ {0x0000a0dc, 0x221d221e},
+ {0x0000a0e0, 0x33013302},
+ {0x0000a0e4, 0x331f3300},
+ {0x0000a0e8, 0x4402331e},
+ {0x0000a0ec, 0x44004401},
+ {0x0000a0f0, 0x441e441f},
+ {0x0000a0f4, 0x55015502},
+ {0x0000a0f8, 0x551f5500},
+ {0x0000a0fc, 0x6602551e},
+ {0x0000a100, 0x66006601},
+ {0x0000a104, 0x661e661f},
+ {0x0000a108, 0x7703661d},
+ {0x0000a10c, 0x77017702},
+ {0x0000a110, 0x00007700},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x111f1100},
+ {0x0000a148, 0x111d111e},
+ {0x0000a14c, 0x111b111c},
+ {0x0000a150, 0x22032204},
+ {0x0000a154, 0x22012202},
+ {0x0000a158, 0x221f2200},
+ {0x0000a15c, 0x221d221e},
+ {0x0000a160, 0x33013302},
+ {0x0000a164, 0x331f3300},
+ {0x0000a168, 0x4402331e},
+ {0x0000a16c, 0x44004401},
+ {0x0000a170, 0x441e441f},
+ {0x0000a174, 0x55015502},
+ {0x0000a178, 0x551f5500},
+ {0x0000a17c, 0x6602551e},
+ {0x0000a180, 0x66006601},
+ {0x0000a184, 0x661e661f},
+ {0x0000a188, 0x7703661d},
+ {0x0000a18c, 0x77017702},
+ {0x0000a190, 0x00007700},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000296},
+};
+
+static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10252e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10253e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_soc_preamble[][2] = {
+ /* Addr allmodes */
+ {0x000040a4, 0x00a0c9c9},
+ {0x00007048, 0x00000004},
+};
+
+static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = {
+ /* Addr 5G_HT20 5G_HT40 */
+ {0x00009e00, 0x03721821, 0x03721821},
+ {0x0000a230, 0x0000400b, 0x00004016},
+ {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9485_1_0_baseband_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+ {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
+ {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+ {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+ {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
+ {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+ {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+ {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+ {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
+ {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+ {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+ {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+ {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+ {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
+ {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+ {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+ {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+ {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
+ {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+ {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
+ {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
+ {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+ {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+ {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+ {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+ {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+ {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
+ {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+ {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+ {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
+ {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+ {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+ {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+ {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+ {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10213e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_radio_postamble[][2] = {
+ /* Addr allmodes */
+ {0x0001609c, 0x0b283f31},
+ {0x000160ac, 0x24611800},
+ {0x000160b0, 0x03284f3e},
+ {0x0001610c, 0x00170000},
+ {0x00016140, 0x10804008},
+};
+
+static const u32 ar9485_1_0_mac_core[][2] = {
+ /* Addr allmodes */
+ {0x00000008, 0x00000000},
+ {0x00000030, 0x00020085},
+ {0x00000034, 0x00000005},
+ {0x00000040, 0x00000000},
+ {0x00000044, 0x00000000},
+ {0x00000048, 0x00000008},
+ {0x0000004c, 0x00000010},
+ {0x00000050, 0x00000000},
+ {0x00001040, 0x002ffc0f},
+ {0x00001044, 0x002ffc0f},
+ {0x00001048, 0x002ffc0f},
+ {0x0000104c, 0x002ffc0f},
+ {0x00001050, 0x002ffc0f},
+ {0x00001054, 0x002ffc0f},
+ {0x00001058, 0x002ffc0f},
+ {0x0000105c, 0x002ffc0f},
+ {0x00001060, 0x002ffc0f},
+ {0x00001064, 0x002ffc0f},
+ {0x000010f0, 0x00000100},
+ {0x00001270, 0x00000000},
+ {0x000012b0, 0x00000000},
+ {0x000012f0, 0x00000000},
+ {0x0000143c, 0x00000000},
+ {0x0000147c, 0x00000000},
+ {0x00008000, 0x00000000},
+ {0x00008004, 0x00000000},
+ {0x00008008, 0x00000000},
+ {0x0000800c, 0x00000000},
+ {0x00008018, 0x00000000},
+ {0x00008020, 0x00000000},
+ {0x00008038, 0x00000000},
+ {0x0000803c, 0x00000000},
+ {0x00008040, 0x00000000},
+ {0x00008044, 0x00000000},
+ {0x00008048, 0x00000000},
+ {0x0000804c, 0xffffffff},
+ {0x00008054, 0x00000000},
+ {0x00008058, 0x00000000},
+ {0x0000805c, 0x000fc78f},
+ {0x00008060, 0x0000000f},
+ {0x00008064, 0x00000000},
+ {0x00008070, 0x00000310},
+ {0x00008074, 0x00000020},
+ {0x00008078, 0x00000000},
+ {0x0000809c, 0x0000000f},
+ {0x000080a0, 0x00000000},
+ {0x000080a4, 0x02ff0000},
+ {0x000080a8, 0x0e070605},
+ {0x000080ac, 0x0000000d},
+ {0x000080b0, 0x00000000},
+ {0x000080b4, 0x00000000},
+ {0x000080b8, 0x00000000},
+ {0x000080bc, 0x00000000},
+ {0x000080c0, 0x2a800000},
+ {0x000080c4, 0x06900168},
+ {0x000080c8, 0x13881c20},
+ {0x000080cc, 0x01f40000},
+ {0x000080d0, 0x00252500},
+ {0x000080d4, 0x00a00000},
+ {0x000080d8, 0x00400000},
+ {0x000080dc, 0x00000000},
+ {0x000080e0, 0xffffffff},
+ {0x000080e4, 0x0000ffff},
+ {0x000080e8, 0x3f3f3f3f},
+ {0x000080ec, 0x00000000},
+ {0x000080f0, 0x00000000},
+ {0x000080f4, 0x00000000},
+ {0x000080fc, 0x00020000},
+ {0x00008100, 0x00000000},
+ {0x00008108, 0x00000052},
+ {0x0000810c, 0x00000000},
+ {0x00008110, 0x00000000},
+ {0x00008114, 0x000007ff},
+ {0x00008118, 0x000000aa},
+ {0x0000811c, 0x00003210},
+ {0x00008124, 0x00000000},
+ {0x00008128, 0x00000000},
+ {0x0000812c, 0x00000000},
+ {0x00008130, 0x00000000},
+ {0x00008134, 0x00000000},
+ {0x00008138, 0x00000000},
+ {0x0000813c, 0x0000ffff},
+ {0x00008144, 0xffffffff},
+ {0x00008168, 0x00000000},
+ {0x0000816c, 0x00000000},
+ {0x00008170, 0x18486200},
+ {0x00008174, 0x33332210},
+ {0x00008178, 0x00000000},
+ {0x0000817c, 0x00020000},
+ {0x000081c0, 0x00000000},
+ {0x000081c4, 0x33332210},
+ {0x000081c8, 0x00000000},
+ {0x000081cc, 0x00000000},
+ {0x000081d4, 0x00000000},
+ {0x000081ec, 0x00000000},
+ {0x000081f0, 0x00000000},
+ {0x000081f4, 0x00000000},
+ {0x000081f8, 0x00000000},
+ {0x000081fc, 0x00000000},
+ {0x00008240, 0x00100000},
+ {0x00008244, 0x0010f400},
+ {0x00008248, 0x00000800},
+ {0x0000824c, 0x0001e800},
+ {0x00008250, 0x00000000},
+ {0x00008254, 0x00000000},
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x40000000},
+ {0x00008260, 0x00080922},
+ {0x00008264, 0x9ca00010},
+ {0x00008268, 0xffffffff},
+ {0x0000826c, 0x0000ffff},
+ {0x00008270, 0x00000000},
+ {0x00008274, 0x40000000},
+ {0x00008278, 0x003e4180},
+ {0x0000827c, 0x00000004},
+ {0x00008284, 0x0000002c},
+ {0x00008288, 0x0000002c},
+ {0x0000828c, 0x000000ff},
+ {0x00008294, 0x00000000},
+ {0x00008298, 0x00000000},
+ {0x0000829c, 0x00000000},
+ {0x00008300, 0x00000140},
+ {0x00008314, 0x00000000},
+ {0x0000831c, 0x0000010d},
+ {0x00008328, 0x00000000},
+ {0x0000832c, 0x00000007},
+ {0x00008330, 0x00000302},
+ {0x00008334, 0x00000700},
+ {0x00008338, 0x00ff0000},
+ {0x0000833c, 0x02400000},
+ {0x00008340, 0x000107ff},
+ {0x00008344, 0xa248105b},
+ {0x00008348, 0x008f0000},
+ {0x0000835c, 0x00000000},
+ {0x00008360, 0xffffffff},
+ {0x00008364, 0xffffffff},
+ {0x00008368, 0x00000000},
+ {0x00008370, 0x00000000},
+ {0x00008374, 0x000000ff},
+ {0x00008378, 0x00000000},
+ {0x0000837c, 0x00000000},
+ {0x00008380, 0xffffffff},
+ {0x00008384, 0xffffffff},
+ {0x00008390, 0xffffffff},
+ {0x00008394, 0xffffffff},
+ {0x00008398, 0x00000000},
+ {0x0000839c, 0x00000000},
+ {0x000083a0, 0x00000000},
+ {0x000083a4, 0x0000fa14},
+ {0x000083a8, 0x000f0c00},
+ {0x000083ac, 0x33332210},
+ {0x000083b0, 0x33332210},
+ {0x000083b4, 0x33332210},
+ {0x000083b8, 0x33332210},
+ {0x000083bc, 0x00000000},
+ {0x000083c0, 0x00000000},
+ {0x000083c4, 0x00000000},
+ {0x000083c8, 0x00000000},
+ {0x000083cc, 0x00000200},
+ {0x000083d0, 0x000301ff},
+};
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 170d44a35ccb..fcc087ce3bc3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/leds.h>
#include <linux/completion.h>
+#include <linux/pm_qos_params.h>
#include "debug.h"
#include "common.h"
@@ -56,6 +57,8 @@ struct ath_node;
#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ATH9K_PM_QOS_DEFAULT_VALUE 55
+
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
@@ -86,33 +89,19 @@ struct ath_config {
/**
* enum buffer_type - Buffer type flags
*
- * @BUF_HT: Send this buffer using HT capabilities
* @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
* @BUF_AGGR: Indicates whether the buffer can be aggregated
* (used in aggregation scheduling)
- * @BUF_RETRY: Indicates whether the buffer is retried
* @BUF_XRETRY: To denote excessive retries of the buffer
*/
enum buffer_type {
- BUF_HT = BIT(1),
BUF_AMPDU = BIT(2),
BUF_AGGR = BIT(3),
- BUF_RETRY = BIT(4),
BUF_XRETRY = BIT(5),
};
-#define bf_nframes bf_state.bfs_nframes
-#define bf_al bf_state.bfs_al
-#define bf_frmlen bf_state.bfs_frmlen
-#define bf_retries bf_state.bfs_retries
-#define bf_seqno bf_state.bfs_seqno
-#define bf_tidno bf_state.bfs_tidno
-#define bf_keyix bf_state.bfs_keyix
-#define bf_keytype bf_state.bfs_keytype
-#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
#define ATH_TXSTATUS_RING_SIZE 64
@@ -177,8 +166,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
/* returns delimiter padding required given the packet length */
#define ATH_AGGR_GET_NDELIM(_len) \
- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+ (((_len) >= ATH_AGGR_MINPLEN) ? 0 : \
+ DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ))
#define BAW_WITHIN(_start, _bawsz, _seqno) \
((((_seqno) - (_start)) & 4095) < (_bawsz))
@@ -195,12 +184,12 @@ enum ATH_AGGR_STATUS {
#define ATH_TXFIFO_DEPTH 8
struct ath_txq {
- int axq_class;
u32 axq_qnum;
u32 *axq_link;
struct list_head axq_q;
spinlock_t axq_lock;
u32 axq_depth;
+ u32 axq_ampdu_depth;
bool stopped;
bool axq_tx_inprogress;
struct list_head axq_acq;
@@ -208,27 +197,28 @@ struct ath_txq {
struct list_head txq_fifo_pending;
u8 txq_headidx;
u8 txq_tailidx;
+ int pending_frames;
};
struct ath_atx_ac {
+ struct ath_txq *txq;
int sched;
- int qnum;
struct list_head list;
struct list_head tid_q;
};
+struct ath_frame_info {
+ int framelen;
+ u32 keyix;
+ enum ath9k_key_type keytype;
+ u8 retries;
+ u16 seqno;
+};
+
struct ath_buf_state {
- int bfs_nframes;
- u16 bfs_al;
- u16 bfs_frmlen;
- int bfs_seqno;
- int bfs_tidno;
- int bfs_retries;
u8 bf_type;
u8 bfs_paprd;
- unsigned long bfs_paprd_timestamp;
- u32 bfs_keyix;
- enum ath9k_key_type bfs_keytype;
+ enum ath9k_internal_frame_type bfs_ftype;
};
struct ath_buf {
@@ -241,7 +231,6 @@ struct ath_buf {
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
bool bf_stale;
- bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
struct ath_wiphy *aphy;
@@ -270,7 +259,6 @@ struct ath_node {
struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu;
u8 mpdudensity;
- int last_rssi;
};
#define AGGR_CLEANUP BIT(1)
@@ -279,6 +267,7 @@ struct ath_node {
struct ath_tx_control {
struct ath_txq *txq;
+ struct ath_node *an;
int if_id;
enum ath9k_internal_frame_type frame_type;
u8 paprd;
@@ -291,12 +280,11 @@ struct ath_tx_control {
struct ath_tx {
u16 seq_no;
u32 txqsetup;
- int hwq_map[WME_NUM_AC];
spinlock_t txbuflock;
struct list_head txbuf;
struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
struct ath_descdma txdma;
- int pending_frames[WME_NUM_AC];
+ struct ath_txq *txq_map[WME_NUM_AC];
};
struct ath_rx_edma {
@@ -310,7 +298,6 @@ struct ath_rx {
u8 rxotherant;
u32 *rxlink;
unsigned int rxfilter;
- spinlock_t pcu_lock;
spinlock_t rxbuflock;
struct list_head rxbuf;
struct ath_descdma rxdma;
@@ -327,8 +314,7 @@ void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
void ath_draintxq(struct ath_softc *sc,
struct ath_txq *txq, bool retry_tx);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -342,7 +328,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl);
void ath_tx_tasklet(struct ath_softc *sc);
void ath_tx_edma_tasklet(struct ath_softc *sc);
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
@@ -563,6 +548,7 @@ struct ath_ant_comb {
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
#define SC_OP_BT_SCAN BIT(13)
#define SC_OP_ANI_RUN BIT(14)
+#define SC_OP_ENABLE_APM BIT(15)
/* Powersave flags */
#define PS_WAIT_FOR_BEACON BIT(0)
@@ -600,13 +586,14 @@ struct ath_softc {
struct ath_hw *sc_ah;
void __iomem *mem;
int irq;
- spinlock_t sc_resetlock;
spinlock_t sc_serial_rw;
spinlock_t sc_pm_lock;
+ spinlock_t sc_pcu_lock;
struct mutex mutex;
struct work_struct paprd_work;
struct work_struct hw_check_work;
struct completion paprd_complete;
+ bool paprd_pending;
u32 intrstatus;
u32 sc_flags; /* SC_OP_* */
@@ -646,6 +633,8 @@ struct ath_softc {
struct ath_descdma txsdma;
struct ath_ant_comb ant_comb;
+
+ struct pm_qos_request_list pm_qos_req;
};
struct ath_wiphy {
@@ -662,11 +651,11 @@ struct ath_wiphy {
bool idle;
int chan_idx;
int chan_is_ht;
+ int last_rssi;
};
void ath9k_tasklet(unsigned long data);
int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
int ath_cabq_update(struct ath_softc *);
static inline void ath_read_cachesize(struct ath_common *common, int *csz)
@@ -675,18 +664,19 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
}
extern struct ieee80211_ops ath9k_ops;
-extern struct pm_qos_request_list ath9k_pm_qos_req;
extern int modparam_nohwcrypt;
extern int led_blink;
+extern int ath9k_pm_qos_value;
+extern bool is_ath9k_unloaded;
irqreturn_t ath_isr(int irq, void *dev);
+void ath9k_init_crypto(struct ath_softc *sc);
int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops);
void ath9k_deinit_device(struct ath_softc *sc);
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
struct ath9k_channel *ichan);
-void ath_update_chainmask(struct ath_softc *sc, int is_ht);
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
struct ath9k_channel *hchan);
@@ -713,10 +703,12 @@ static inline void ath_ahb_exit(void) {};
void ath9k_ps_wakeup(struct ath_softc *sc);
void ath9k_ps_restore(struct ath_softc *sc);
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
+
void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int ath9k_wiphy_add(struct ath_softc *sc);
int ath9k_wiphy_del(struct ath_wiphy *aphy);
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype);
int ath9k_wiphy_pause(struct ath_wiphy *aphy);
int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
int ath9k_wiphy_select(struct ath_wiphy *aphy);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 19891e7d49ae..385ba03134ba 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -28,7 +28,7 @@ int ath_beaconq_config(struct ath_softc *sc)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi, qi_be;
- int qnum;
+ struct ath_txq *txq;
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -38,16 +38,16 @@ int ath_beaconq_config(struct ath_softc *sc)
qi.tqi_cwmax = 0;
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
- qnum = sc->tx.hwq_map[WME_AC_BE];
- ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+ txq = sc->tx.txq_map[WME_AC_BE];
+ ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
qi.tqi_aifs = qi_be.tqi_aifs;
qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
qi.tqi_cwmax = qi_be.tqi_cwmax;
}
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to update h/w beacon queue parameters\n");
+ ath_err(common,
+ "Unable to update h/w beacon queue parameters\n");
return 0;
} else {
ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
@@ -103,12 +103,32 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
- series[0].ChSel = common->tx_chainmask;
+ series[0].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[0].Rate);
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
series, 4, 0);
}
+static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_tx_control txctl;
+
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = sc->beacon.cabq;
+
+ ath_dbg(common, ATH_DBG_XMIT,
+ "transmitting CABQ packet, skb: %p\n", skb);
+
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
+ ath_dbg(common, ATH_DBG_XMIT, "CABQ TX failed\n");
+ dev_kfree_skb_any(skb);
+ }
+}
+
static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
@@ -169,8 +189,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error on beaconing\n");
+ ath_err(common, "dma_mapping_error on beaconing\n");
return NULL;
}
@@ -190,8 +209,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
if (skb && cabq_depth) {
if (sc->nvifs > 1) {
- ath_print(common, ATH_DBG_BEACON,
- "Flushing previous cabq traffic\n");
+ ath_dbg(common, ATH_DBG_BEACON,
+ "Flushing previous cabq traffic\n");
ath_draintxq(sc, cabq, false);
}
}
@@ -263,7 +282,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
/* NB: the beacon data buffer must be 32-bit aligned. */
skb = ieee80211_beacon_get(sc->hw, vif);
if (skb == NULL) {
- ath_print(common, ATH_DBG_BEACON, "cannot get skb\n");
+ ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n");
return -ENOMEM;
}
@@ -287,10 +306,9 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
- ath_print(common, ATH_DBG_BEACON,
- "stagger beacons, bslot %d intval "
- "%u tsfadjust %llu\n",
- avp->av_bslot, intval, (unsigned long long)tsfadjust);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
+ avp->av_bslot, intval, (unsigned long long)tsfadjust);
((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
avp->tsf_adjust;
@@ -304,8 +322,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error on beacon alloc\n");
+ ath_err(common, "dma_mapping_error on beacon alloc\n");
return -ENOMEM;
}
@@ -362,13 +379,13 @@ void ath_beacon_tasklet(unsigned long data)
sc->beacon.bmisscnt++;
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BSTUCK,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "missed %u consecutive beacons\n",
+ sc->beacon.bmisscnt);
ath9k_hw_bstuck_nfcal(ah);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BSTUCK,
- "beacon is officially stuck\n");
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, true);
}
@@ -377,9 +394,9 @@ void ath_beacon_tasklet(unsigned long data)
}
if (sc->beacon.bmisscnt != 0) {
- ath_print(common, ATH_DBG_BSTUCK,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "resume beacon xmit after %u misses\n",
+ sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
}
@@ -405,9 +422,9 @@ void ath_beacon_tasklet(unsigned long data)
vif = sc->beacon.bslot[slot];
aphy = sc->beacon.bslot_aphy[slot];
- ath_print(common, ATH_DBG_BEACON,
- "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
- slot, tsf, tsftu, intval, vif);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+ slot, tsf, tsftu, intval, vif);
bfaddr = 0;
if (vif) {
@@ -449,8 +466,8 @@ void ath_beacon_tasklet(unsigned long data)
* are still pending on the queue.
*/
if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
- ath_print(common, ATH_DBG_FATAL,
- "beacon queue %u did not stop?\n", sc->beacon.beaconq);
+ ath_err(common, "beacon queue %u did not stop?\n",
+ sc->beacon.beaconq);
}
/* NB: cabq traffic should already be queued and primed */
@@ -503,7 +520,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
/* Set the computed AP beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -536,8 +553,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
/* No need to configure beacon if we are not associated */
if (!common->curaid) {
- ath_print(common, ATH_DBG_BEACON,
- "STA is not yet associated..skipping beacon config\n");
+ ath_dbg(common, ATH_DBG_BEACON,
+ "STA is not yet associated..skipping beacon config\n");
return;
}
@@ -549,8 +566,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
* last beacon we received (which may be none).
*/
dtimperiod = conf->dtim_period;
- if (dtimperiod <= 0) /* NB: 0 if not known */
- dtimperiod = 1;
dtimcount = conf->dtim_count;
if (dtimcount >= dtimperiod) /* NB: sanity check */
dtimcount = 0;
@@ -558,8 +573,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
cfpcount = 0;
sleepduration = conf->listen_interval * intval;
- if (sleepduration <= 0)
- sleepduration = intval;
/*
* Pull nexttbtt forward to reflect the current
@@ -630,23 +643,22 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
/* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
- ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
- bs.bs_bmissthreshold, bs.bs_sleepduration,
- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+ ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
/* Set the computed STA beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_hw_set_sta_beacon_timers(ah, &bs);
ah->imask |= ATH9K_INT_BMISS;
ath9k_hw_set_interrupts(ah, ah->imask);
}
static void ath_beacon_config_adhoc(struct ath_softc *sc,
- struct ath_beacon_config *conf,
- struct ieee80211_vif *vif)
+ struct ath_beacon_config *conf)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
@@ -670,9 +682,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
nexttbtt += intval;
} while (nexttbtt < tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "IBSS nexttbtt %u intval %u (%u)\n",
- nexttbtt, intval, conf->beacon_interval);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "IBSS nexttbtt %u intval %u (%u)\n",
+ nexttbtt, intval, conf->beacon_interval);
/*
* In IBSS mode enable the beacon timers but only enable SWBA interrupts
@@ -686,7 +698,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
/* Set the computed ADHOC beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -701,18 +713,17 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
/* Setup the beacon configuration parameters */
if (vif) {
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-
iftype = vif->type;
-
cur_conf->beacon_interval = bss_conf->beacon_int;
cur_conf->dtim_period = bss_conf->dtim_period;
+ } else {
+ iftype = sc->sc_ah->opmode;
+ }
+
cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1;
cur_conf->bmiss_timeout =
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
- } else {
- iftype = sc->sc_ah->opmode;
- }
/*
* It looks like mac80211 may end up using beacon interval of zero in
@@ -723,20 +734,27 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
if (cur_conf->beacon_interval == 0)
cur_conf->beacon_interval = 100;
+ /*
+ * Some times we dont parse dtim period from mac80211, in that case
+ * use a default value
+ */
+ if (cur_conf->dtim_period == 0)
+ cur_conf->dtim_period = 1;
+
switch (iftype) {
case NL80211_IFTYPE_AP:
ath_beacon_config_ap(sc, cur_conf);
break;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
- ath_beacon_config_adhoc(sc, cur_conf, vif);
+ ath_beacon_config_adhoc(sc, cur_conf);
break;
case NL80211_IFTYPE_STATION:
ath_beacon_config_sta(sc, cur_conf);
break;
default:
- ath_print(common, ATH_DBG_CONFIG,
- "Unsupported beaconing mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
return;
}
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 6a92e57fddf0..d33bf204c995 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -35,29 +35,6 @@ struct ath_btcoex_config {
bool bt_hold_rx_clear;
};
-static const u16 ath_subsysid_tbl[] = {
- AR9280_COEX2WIRE_SUBSYSID,
- AT9285_COEX3WIRE_SA_SUBSYSID,
- AT9285_COEX3WIRE_DA_SUBSYSID
-};
-
-/*
- * Checks the subsystem id of the device to see if it
- * supports btcoex
- */
-bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
-{
- int i;
-
- if (!ah->hw_version.subsysid)
- return false;
-
- for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
- if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
- return true;
-
- return false;
-}
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
{
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1ee5a15ccbb1..588dfd464dd1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -49,7 +49,6 @@ struct ath_btcoex_hw {
u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
};
-bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6d509484b5f6..b68a1acbddd0 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -97,12 +97,12 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
if (h[i].privNF > limit->max) {
high_nf_mid = true;
- ath_print(common, ATH_DBG_CALIBRATE,
- "NFmid[%d] (%d) > MAX (%d), %s\n",
- i, h[i].privNF, limit->max,
- (cal->nfcal_interference ?
- "not corrected (due to interference)" :
- "correcting to MAX"));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NFmid[%d] (%d) > MAX (%d), %s\n",
+ i, h[i].privNF, limit->max,
+ (cal->nfcal_interference ?
+ "not corrected (due to interference)" :
+ "correcting to MAX"));
/*
* Normally we limit the average noise floor by the
@@ -180,18 +180,18 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
if (currCal->calState != CAL_DONE) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Calibration state incorrect, %d\n",
- currCal->calState);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Calibration state incorrect, %d\n",
+ currCal->calState);
return true;
}
if (!(ah->supp_cals & currCal->calData->calType))
return true;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Resetting Cal %d state for channel %u\n",
- currCal->calData->calType, conf->channel->center_freq);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Resetting Cal %d state for channel %u\n",
+ currCal->calData->calType, conf->channel->center_freq);
ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
@@ -279,9 +279,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
* noisefloor until the next calibration timer.
*/
if (j == 1000) {
- ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
- "to load: AR_PHY_AGC_CONTROL=0x%x\n",
- REG_READ(ah, AR_PHY_AGC_CONTROL));
+ ath_dbg(common, ATH_DBG_ANY,
+ "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
+ REG_READ(ah, AR_PHY_AGC_CONTROL));
return;
}
@@ -318,19 +318,19 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
if (!nf[i])
continue;
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF calibrated [%s] [chain %d] is %d\n",
- (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF calibrated [%s] [chain %d] is %d\n",
+ (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
if (nf[i] > ATH9K_NF_TOO_HIGH) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF[%d] (%d) > MAX (%d), correcting to MAX",
- i, nf[i], ATH9K_NF_TOO_HIGH);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) > MAX (%d), correcting to MAX\n",
+ i, nf[i], ATH9K_NF_TOO_HIGH);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF[%d] (%d) < MIN (%d), correcting to NOM",
- i, nf[i], limit->min);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) < MIN (%d), correcting to NOM\n",
+ i, nf[i], limit->min);
nf[i] = limit->nominal;
}
}
@@ -347,8 +347,8 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF did not complete in calibration window\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF did not complete in calibration window\n");
return false;
}
@@ -357,10 +357,9 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
nf = nfarray[0];
if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
&& nf > nfThresh) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "noise floor failed detected; "
- "detected %d, threshold %d\n",
- nf, nfThresh);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "noise floor failed detected; detected %d, threshold %d\n",
+ nf, nfThresh);
chan->channelFlags |= CHANNEL_CW_INT;
}
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index f43a2d98421c..df1998d48253 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -107,12 +107,10 @@ static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
/*
* Update internal channel flags.
*/
-void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
- struct ath9k_channel *ichan)
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
{
- struct ieee80211_channel *chan = hw->conf.channel;
- struct ieee80211_conf *conf = &hw->conf;
-
ichan->channel = chan->center_freq;
ichan->chan = chan;
@@ -124,9 +122,8 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
}
- if (conf_is_ht(conf))
- ichan->chanmode = ath9k_get_extchanmode(chan,
- conf->channel_type);
+ if (channel_type != NL80211_CHAN_NO_HT)
+ ichan->chanmode = ath9k_get_extchanmode(chan, channel_type);
}
EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
@@ -142,7 +139,7 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx];
- ath9k_cmn_update_ichannel(hw, channel);
+ ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type);
return channel;
}
@@ -183,8 +180,8 @@ void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
AR_STOMP_NONE_WLAN_WGHT);
break;
default:
- ath_print(common, ATH_DBG_BTCOEX,
- "Invalid Stomptype\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
break;
}
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index fea3b3315391..a126bddebb0a 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -17,7 +17,6 @@
#include <net/mac80211.h>
#include "../ath.h"
-#include "../debug.h"
#include "hw.h"
#include "hw-ops.h"
@@ -31,10 +30,11 @@
#define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-#define WME_AC_BE 0
-#define WME_AC_BK 1
-#define WME_AC_VI 2
-#define WME_AC_VO 3
+/* These must match mac80211 skb queue mapping numbers */
+#define WME_AC_VO 0
+#define WME_AC_VI 1
+#define WME_AC_BE 2
+#define WME_AC_BK 3
#define WME_NUM_AC 4
#define ATH_RSSI_DUMMY_MARKER 0x127
@@ -62,8 +62,9 @@ enum ath_stomp_type {
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
-void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
- struct ath9k_channel *ichan);
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 43e71a944cb1..3586c43077a7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -24,8 +24,6 @@
#define REG_READ_D(_ah, _reg) \
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
-static struct dentry *ath9k_debugfs_root;
-
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
@@ -461,16 +459,16 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
/* Put variable-length stuff down here, and check for overflows. */
for (i = 0; i < sc->num_sec_wiphy; i++) {
- struct ath_wiphy *aphy = sc->sec_wiphy[i];
- if (aphy == NULL)
+ struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i];
+ if (aphy_tmp == NULL)
continue;
- chan = aphy->hw->conf.channel;
+ chan = aphy_tmp->hw->conf.channel;
len += snprintf(buf + len, sizeof(buf) - len,
"secondary: %s (%s chan=%d ht=%d)\n",
- wiphy_name(aphy->hw->wiphy),
- ath_wiphy_state_str(aphy->state),
+ wiphy_name(aphy_tmp->hw->wiphy),
+ ath_wiphy_state_str(aphy_tmp->state),
ieee80211_frequency_to_channel(chan->center_freq),
- aphy->chan_is_ht);
+ aphy_tmp->chan_is_ht);
}
if (len > sizeof(buf))
len = sizeof(buf);
@@ -585,10 +583,10 @@ static const struct file_operations fops_wiphy = {
do { \
len += snprintf(buf + len, size - len, \
"%s%13u%11u%10u%10u\n", str, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \
+ sc->debug.stats.txstats[WME_AC_BE].elem, \
+ sc->debug.stats.txstats[WME_AC_BK].elem, \
+ sc->debug.stats.txstats[WME_AC_VI].elem, \
+ sc->debug.stats.txstats[WME_AC_VO].elem); \
} while(0)
static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -630,33 +628,35 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
return retval;
}
-void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf, struct ath_tx_status *ts)
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts)
{
- TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
- sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
+ int qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
+ TX_STAT_INC(qnum, tx_pkts_all);
+ sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
if (bf_isampdu(bf)) {
if (bf_isxretried(bf))
- TX_STAT_INC(txq->axq_qnum, a_xretries);
+ TX_STAT_INC(qnum, a_xretries);
else
- TX_STAT_INC(txq->axq_qnum, a_completed);
+ TX_STAT_INC(qnum, a_completed);
} else {
- TX_STAT_INC(txq->axq_qnum, completed);
+ TX_STAT_INC(qnum, completed);
}
if (ts->ts_status & ATH9K_TXERR_FIFO)
- TX_STAT_INC(txq->axq_qnum, fifo_underrun);
+ TX_STAT_INC(qnum, fifo_underrun);
if (ts->ts_status & ATH9K_TXERR_XTXOP)
- TX_STAT_INC(txq->axq_qnum, xtxop);
+ TX_STAT_INC(qnum, xtxop);
if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
- TX_STAT_INC(txq->axq_qnum, timer_exp);
+ TX_STAT_INC(qnum, timer_exp);
if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
- TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
+ TX_STAT_INC(qnum, desc_cfg_err);
if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
- TX_STAT_INC(txq->axq_qnum, data_underrun);
+ TX_STAT_INC(qnum, data_underrun);
if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
- TX_STAT_INC(txq->axq_qnum, delim_underrun);
+ TX_STAT_INC(qnum, delim_underrun);
}
static const struct file_operations fops_xmit = {
@@ -876,11 +876,8 @@ int ath9k_init_debug(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath_softc *sc = (struct ath_softc *) common->priv;
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- ath9k_debugfs_root);
+ sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
+ sc->hw->wiphy->debugfsdir);
if (!sc->debug.debugfs_phy)
return -ENOMEM;
@@ -933,29 +930,7 @@ int ath9k_init_debug(struct ath_hw *ah)
sc->debug.regidx = 0;
return 0;
err:
- ath9k_exit_debug(ah);
- return -ENOMEM;
-}
-
-void ath9k_exit_debug(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
-
debugfs_remove_recursive(sc->debug.debugfs_phy);
-}
-
-int ath9k_debug_create_root(void)
-{
- ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- return 0;
-}
-
-void ath9k_debug_remove_root(void)
-{
- debugfs_remove(ath9k_debugfs_root);
- ath9k_debugfs_root = NULL;
+ sc->debug.debugfs_phy = NULL;
+ return -ENOMEM;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index bb0823242ba0..1e5078bd0344 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -164,13 +164,10 @@ struct ath9k_debug {
};
int ath9k_init_debug(struct ath_hw *ah);
-void ath9k_exit_debug(struct ath_hw *ah);
-int ath9k_debug_create_root(void);
-void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf, struct ath_tx_status *ts);
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
#else
@@ -180,26 +177,12 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
return 0;
}
-static inline void ath9k_exit_debug(struct ath_hw *ah)
-{
-}
-
-static inline int ath9k_debug_create_root(void)
-{
- return 0;
-}
-
-static inline void ath9k_debug_remove_root(void)
-{
-}
-
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
enum ath9k_int status)
{
}
static inline void ath_debug_stat_tx(struct ath_softc *sc,
- struct ath_txq *txq,
struct ath_buf *bf,
struct ath_tx_status *ts)
{
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 1266333f586d..d05163159572 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -234,22 +234,22 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
bool is2GHz, int num_band_edges)
{
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
int i;
for (i = 0; (i < num_band_edges) &&
(pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
- twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+ twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
break;
} else if ((i > 0) &&
(freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
is2GHz))) {
if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
is2GHz) < freq &&
- pRdEdgesPower[i - 1].flag) {
+ CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
twiceMaxEdgePower =
- pRdEdgesPower[i - 1].tPower;
+ CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
}
break;
}
@@ -273,12 +273,225 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
break;
default:
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid chainmask configuration\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
break;
}
}
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ void *pRawDataSet,
+ u8 *bChans, u16 availPiers,
+ u16 tPdGainOverlap,
+ u16 *pPdGainBoundaries, u8 *pPDADCValues,
+ u16 numXpdGains)
+{
+ int i, j, k;
+ int16_t ss;
+ u16 idxL = 0, idxR = 0, numPiers;
+ static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+ u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+ u8 minPwrT4[AR5416_NUM_PD_GAINS];
+ u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+ int16_t vpdStep;
+ int16_t tmpVal;
+ u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+ bool match;
+ int16_t minDelta = 0;
+ struct chan_centers centers;
+ int pdgain_boundary_default;
+ struct cal_data_per_freq *data_def = pRawDataSet;
+ struct cal_data_per_freq_4k *data_4k = pRawDataSet;
+ struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
+ bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
+ int intercepts;
+
+ if (AR_SREV_9287(ah))
+ intercepts = AR9287_PD_GAIN_ICEPTS;
+ else
+ intercepts = AR5416_PD_GAIN_ICEPTS;
+
+ memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
+
+ match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan)),
+ bChans, numPiers, &idxL, &idxR);
+
+ if (match) {
+ if (AR_SREV_9287(ah)) {
+ /* FIXME: array overrun? */
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ data_9287[idxL].pwrPdg[i],
+ data_9287[idxL].vpdPdg[i],
+ intercepts,
+ vpdTableI[i]);
+ }
+ } else if (eeprom_4k) {
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ data_4k[idxL].pwrPdg[i],
+ data_4k[idxL].vpdPdg[i],
+ intercepts,
+ vpdTableI[i]);
+ }
+ } else {
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ data_def[idxL].pwrPdg[i],
+ data_def[idxL].vpdPdg[i],
+ intercepts,
+ vpdTableI[i]);
+ }
+ }
+ } else {
+ for (i = 0; i < numXpdGains; i++) {
+ if (AR_SREV_9287(ah)) {
+ pVpdL = data_9287[idxL].vpdPdg[i];
+ pPwrL = data_9287[idxL].pwrPdg[i];
+ pVpdR = data_9287[idxR].vpdPdg[i];
+ pPwrR = data_9287[idxR].pwrPdg[i];
+ } else if (eeprom_4k) {
+ pVpdL = data_4k[idxL].vpdPdg[i];
+ pPwrL = data_4k[idxL].pwrPdg[i];
+ pVpdR = data_4k[idxR].vpdPdg[i];
+ pPwrR = data_4k[idxR].pwrPdg[i];
+ } else {
+ pVpdL = data_def[idxL].vpdPdg[i];
+ pPwrL = data_def[idxL].pwrPdg[i];
+ pVpdR = data_def[idxR].vpdPdg[i];
+ pPwrR = data_def[idxR].pwrPdg[i];
+ }
+
+ minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+ maxPwrT4[i] =
+ min(pPwrL[intercepts - 1],
+ pPwrR[intercepts - 1]);
+
+
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrL, pVpdL,
+ intercepts,
+ vpdTableL[i]);
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrR, pVpdR,
+ intercepts,
+ vpdTableR[i]);
+
+ for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+ vpdTableI[i][j] =
+ (u8)(ath9k_hw_interpolate((u16)
+ FREQ2FBIN(centers.
+ synth_center,
+ IS_CHAN_2GHZ
+ (chan)),
+ bChans[idxL], bChans[idxR],
+ vpdTableL[i][j], vpdTableR[i][j]));
+ }
+ }
+ }
+
+ k = 0;
+
+ for (i = 0; i < numXpdGains; i++) {
+ if (i == (numXpdGains - 1))
+ pPdGainBoundaries[i] =
+ (u16)(maxPwrT4[i] / 2);
+ else
+ pPdGainBoundaries[i] =
+ (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+ pPdGainBoundaries[i] =
+ min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+ if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+ minDelta = pPdGainBoundaries[0] - 23;
+ pPdGainBoundaries[0] = 23;
+ } else {
+ minDelta = 0;
+ }
+
+ if (i == 0) {
+ if (AR_SREV_9280_20_OR_LATER(ah))
+ ss = (int16_t)(0 - (minPwrT4[i] / 2));
+ else
+ ss = 0;
+ } else {
+ ss = (int16_t)((pPdGainBoundaries[i - 1] -
+ (minPwrT4[i] / 2)) -
+ tPdGainOverlap + 1 + minDelta);
+ }
+ vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+ pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+ ss++;
+ }
+
+ sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+ tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+ (minPwrT4[i] / 2));
+ maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+ tgtIndex : sizeCurrVpdTable;
+
+ while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ pPDADCValues[k++] = vpdTableI[i][ss++];
+ }
+
+ vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+ vpdTableI[i][sizeCurrVpdTable - 2]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ if (tgtIndex >= maxIndex) {
+ while ((ss <= tgtIndex) &&
+ (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+ (ss - maxIndex + 1) * vpdStep));
+ pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+ 255 : tmpVal);
+ ss++;
+ }
+ }
+ }
+
+ if (eeprom_4k)
+ pdgain_boundary_default = 58;
+ else
+ pdgain_boundary_default = pPdGainBoundaries[i - 1];
+
+ while (i < AR5416_PD_GAINS_IN_MASK) {
+ pPdGainBoundaries[i] = pdgain_boundary_default;
+ i++;
+ }
+
+ while (k < AR5416_NUM_PDADC_VALUES) {
+ pPDADCValues[k] = pPDADCValues[k - 1];
+ k++;
+ }
+}
+
int ath9k_hw_eeprom_init(struct ath_hw *ah)
{
int status;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index dacb45e1b906..58e2ddc927a9 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -17,12 +17,12 @@
#ifndef EEPROM_H
#define EEPROM_H
+#define AR_EEPROM_MODAL_SPURS 5
+
#include "../ath.h"
#include <net/cfg80211.h>
#include "ar9003_eeprom.h"
-#define AH_USE_EEPROM 0x1
-
#ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
#else
@@ -149,8 +149,6 @@
#define AR5416_NUM_PD_GAINS 4
#define AR5416_PD_GAINS_IN_MASK 4
#define AR5416_PD_GAIN_ICEPTS 5
-#define AR5416_EEPROM_MODAL_SPURS 5
-#define AR5416_MAX_RATE_POWER 63
#define AR5416_NUM_PDADC_VALUES 128
#define AR5416_BCHAN_UNUSED 0xFF
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
@@ -175,8 +173,6 @@
#define AR5416_EEP4K_NUM_CTLS 12
#define AR5416_EEP4K_NUM_BAND_EDGES 4
#define AR5416_EEP4K_NUM_PD_GAINS 2
-#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
-#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
#define AR5416_EEP4K_MAX_CHAINS 1
#define AR9280_TX_GAIN_TABLE_SIZE 22
@@ -198,41 +194,30 @@
#define AR9287_NUM_2G_40_TARGET_POWERS 3
#define AR9287_NUM_CTLS 12
#define AR9287_NUM_BAND_EDGES 4
-#define AR9287_NUM_PD_GAINS 4
-#define AR9287_PD_GAINS_IN_MASK 4
#define AR9287_PD_GAIN_ICEPTS 1
-#define AR9287_EEPROM_MODAL_SPURS 5
-#define AR9287_MAX_RATE_POWER 63
-#define AR9287_NUM_PDADC_VALUES 128
-#define AR9287_NUM_RATES 16
-#define AR9287_BCHAN_UNUSED 0xFF
-#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64
-#define AR9287_OPFLAGS_11A 0x01
-#define AR9287_OPFLAGS_11G 0x02
-#define AR9287_OPFLAGS_2G_HT40 0x08
-#define AR9287_OPFLAGS_2G_HT20 0x20
-#define AR9287_OPFLAGS_5G_HT40 0x04
-#define AR9287_OPFLAGS_5G_HT20 0x10
#define AR9287_EEPMISC_BIG_ENDIAN 0x01
#define AR9287_EEPMISC_WOW 0x02
#define AR9287_MAX_CHAINS 2
#define AR9287_ANT_16S 32
-#define AR9287_custdatasize 20
-
-#define AR9287_NUM_ANT_CHAIN_FIELDS 6
-#define AR9287_NUM_ANT_COMMON_FIELDS 4
-#define AR9287_SIZE_ANT_CHAIN_FIELD 2
-#define AR9287_SIZE_ANT_COMMON_FIELD 4
-#define AR9287_ANT_CHAIN_MASK 0x3
-#define AR9287_ANT_COMMON_MASK 0xf
-#define AR9287_CHAIN_0_IDX 0
-#define AR9287_CHAIN_1_IDX 1
+
#define AR9287_DATA_SZ 32
#define AR9287_PWR_TABLE_OFFSET_DB -5
#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE BIT(0)
+#define LNA_CTL_ISEL_LO BIT(1)
+#define LNA_CTL_ISEL_HI BIT(2)
+#define LNA_CTL_BUF_IN BIT(3)
+#define LNA_CTL_FEM_BAND BIT(4)
+#define LNA_CTL_LOCAL_BIAS BIT(5)
+#define LNA_CTL_FORCE_XPA BIT(6)
+#define LNA_CTL_USE_ANT1 BIT(7)
+
enum eeprom_param {
EEP_NFTHRESH_5,
EEP_NFTHRESH_2,
@@ -268,6 +253,7 @@ enum eeprom_param {
EEP_PAPRD,
EEP_MODAL_VER,
EEP_ANT_DIV_CTL1,
+ EEP_CHAIN_MASK_REDUCE
};
enum ar5416_rates {
@@ -378,15 +364,12 @@ struct modal_eep_header {
u8 xatten2Margin[AR5416_MAX_CHAINS];
u8 ob_ch1;
u8 db_ch1;
- u8 useAnt1:1,
- force_xpaon:1,
- local_bias:1,
- femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+ u8 lna_ctl;
u8 miscBits;
u16 xpaBiasLvlFreq[3];
u8 futureModal[6];
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+ struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
} __packed;
struct calDataPerFreqOpLoop {
@@ -454,7 +437,7 @@ struct modal_eep_4k_header {
u8 db2_4:4, reserved:4;
#endif
u8 futureModal[4];
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+ struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
} __packed;
struct base_eep_ar9287_header {
@@ -512,7 +495,7 @@ struct modal_eep_ar9287_header {
u8 ob_qam;
u8 ob_pal_off;
u8 futureModal[30];
- struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
+ struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
} __packed;
struct cal_data_per_freq {
@@ -521,8 +504,8 @@ struct cal_data_per_freq {
} __packed;
struct cal_data_per_freq_4k {
- u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+ u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
} __packed;
struct cal_target_power_leg {
@@ -535,18 +518,10 @@ struct cal_target_power_ht {
u8 tPow2x[8];
} __packed;
-
-#ifdef __BIG_ENDIAN_BITFIELD
struct cal_ctl_edges {
u8 bChannel;
- u8 flag:2, tPower:6;
+ u8 ctl;
} __packed;
-#else
-struct cal_ctl_edges {
- u8 bChannel;
- u8 tPower:6, flag:2;
-} __packed;
-#endif
struct cal_data_op_loop_ar9287 {
u8 pwrPdg[2][5];
@@ -556,8 +531,8 @@ struct cal_data_op_loop_ar9287 {
} __packed;
struct cal_data_per_freq_ar9287 {
- u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+ u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
} __packed;
union cal_data_per_freq_ar9287_u {
@@ -672,15 +647,12 @@ struct eeprom_ops {
bool (*fill_eeprom)(struct ath_hw *hw);
int (*get_eeprom_ver)(struct ath_hw *hw);
int (*get_eeprom_rev)(struct ath_hw *hw);
- u8 (*get_num_ant_config)(struct ath_hw *hw,
- enum ath9k_hal_freq_band band);
- u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
- struct ath9k_channel *chan);
void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
u16 cfgCtl, u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower, u8 powerLimit);
+ u8 twiceMaxRegulatoryPower, u8 powerLimit,
+ bool test);
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
};
@@ -713,6 +685,14 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
int ath9k_hw_eeprom_init(struct ath_hw *ah);
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ void *pRawDataSet,
+ u8 *bChans, u16 availPiers,
+ u16 tPdGainOverlap,
+ u16 *pPdGainBoundaries, u8 *pPDADCValues,
+ u16 numXpdGains);
+
#define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 1))
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 4fa4d8e28c64..fbdff7e47952 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -37,14 +37,14 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
eep_start_loc = 64;
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -69,13 +69,12 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
if (!ath9k_hw_use_flash(ah)) {
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) {
- ath_print(common, ATH_DBG_FATAL,
- "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -90,16 +89,15 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.map4k.baseEepHeader.length);
@@ -120,8 +118,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
u32 integer;
u16 word;
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing\n");
word = swab16(eep->baseEepHeader.length);
eep->baseEepHeader.length = word;
@@ -155,7 +153,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
eep->modalHeader.antCtrlChain[i] = integer;
}
- for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(eep->modalHeader.spurChans[i].spurChan);
eep->modalHeader.spurChans[i].spurChan = word;
}
@@ -163,9 +161,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ah->eep_ops->get_eeprom_ver(ah));
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -230,173 +227,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
}
}
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
- struct ath9k_channel *chan,
- struct cal_data_per_freq_4k *pRawDataSet,
- u8 *bChans, u16 availPiers,
- u16 tPdGainOverlap,
- u16 *pPdGainBoundaries, u8 *pPDADCValues,
- u16 numXpdGains)
-{
-#define TMP_VAL_VPD_TABLE \
- ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
- int i, j, k;
- int16_t ss;
- u16 idxL = 0, idxR = 0, numPiers;
- static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
- u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
- u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
- u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
- int16_t vpdStep;
- int16_t tmpVal;
- u16 sizeCurrVpdTable, maxIndex, tgtIndex;
- bool match;
- int16_t minDelta = 0;
- struct chan_centers centers;
-#define PD_GAIN_BOUNDARY_DEFAULT 58;
-
- memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
- break;
- }
-
- match = ath9k_hw_get_lower_upper_index(
- (u8)FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan)), bChans, numPiers,
- &idxL, &idxR);
-
- if (match) {
- for (i = 0; i < numXpdGains; i++) {
- minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
- maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pRawDataSet[idxL].pwrPdg[i],
- pRawDataSet[idxL].vpdPdg[i],
- AR5416_EEP4K_PD_GAIN_ICEPTS,
- vpdTableI[i]);
- }
- } else {
- for (i = 0; i < numXpdGains; i++) {
- pVpdL = pRawDataSet[idxL].vpdPdg[i];
- pPwrL = pRawDataSet[idxL].pwrPdg[i];
- pVpdR = pRawDataSet[idxR].vpdPdg[i];
- pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
- minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
- maxPwrT4[i] =
- min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
- pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
-
-
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrL, pVpdL,
- AR5416_EEP4K_PD_GAIN_ICEPTS,
- vpdTableL[i]);
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrR, pVpdR,
- AR5416_EEP4K_PD_GAIN_ICEPTS,
- vpdTableR[i]);
-
- for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] =
- (u8)(ath9k_hw_interpolate((u16)
- FREQ2FBIN(centers.
- synth_center,
- IS_CHAN_2GHZ
- (chan)),
- bChans[idxL], bChans[idxR],
- vpdTableL[i][j], vpdTableR[i][j]));
- }
- }
- }
-
- k = 0;
-
- for (i = 0; i < numXpdGains; i++) {
- if (i == (numXpdGains - 1))
- pPdGainBoundaries[i] =
- (u16)(maxPwrT4[i] / 2);
- else
- pPdGainBoundaries[i] =
- (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
- pPdGainBoundaries[i] =
- min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
- if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
- minDelta = pPdGainBoundaries[0] - 23;
- pPdGainBoundaries[0] = 23;
- } else {
- minDelta = 0;
- }
-
- if (i == 0) {
- if (AR_SREV_9280_20_OR_LATER(ah))
- ss = (int16_t)(0 - (minPwrT4[i] / 2));
- else
- ss = 0;
- } else {
- ss = (int16_t)((pPdGainBoundaries[i - 1] -
- (minPwrT4[i] / 2)) -
- tPdGainOverlap + 1 + minDelta);
- }
- vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
- pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
- ss++;
- }
-
- sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
- tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
- (minPwrT4[i] / 2));
- maxIndex = (tgtIndex < sizeCurrVpdTable) ?
- tgtIndex : sizeCurrVpdTable;
-
- while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
- pPDADCValues[k++] = vpdTableI[i][ss++];
-
- vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- if (tgtIndex >= maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
- pPDADCValues[k++] = (u8)((tmpVal > 255) ?
- 255 : tmpVal);
- ss++;
- }
- }
- }
-
- while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
- i++;
- }
-
- while (k < AR5416_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k - 1];
- k++;
- }
-
- return;
-#undef TMP_VAL_VPD_TABLE
-}
-
static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
@@ -407,7 +237,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
u8 *pCalBChans = NULL;
u16 pdGainOverlap_t2;
static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
u16 numPiers, i, j;
u16 numXpdGain, xpdMask;
u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
@@ -429,12 +259,12 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
numXpdGain = 0;
- for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
break;
xpdGainValues[numXpdGain] =
- (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
+ (u16)(AR5416_PD_GAINS_IN_MASK - i);
numXpdGain++;
}
}
@@ -458,7 +288,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
if (pEepData->baseEepHeader.txMask & (1 << i)) {
pRawDataset = pEepData->calPierData2G[i];
- ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
+ ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
pRawDataset, pCalBChans,
numPiers, pdGainOverlap_t2,
gainBoundaries,
@@ -488,21 +318,20 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC: Chain %d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC: Chain %d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3, pdadcValues[4 * j + 3]);
regOffset += 4;
}
@@ -532,14 +361,16 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
int i;
int16_t twiceLargestAntenna;
u16 twiceMinEdgePower;
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
struct cal_ctl_data_4k *rep;
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+ { 0, 3, 6, 9, MAX_RATE_POWER };
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
0, { 0, 0, 0, 0}
};
@@ -550,10 +381,10 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
0, {0, 0, 0, 0}
};
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -615,7 +446,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
ah->eep_ops->get_eeprom_rev(ah) <= 2)
- twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ twiceMaxEdgePower = MAX_RATE_POWER;
for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
pEepData->ctlIndex[i]; i++) {
@@ -726,7 +557,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -751,15 +582,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR5416_MAX_RATE_POWER)
- ratesArray[i] = AR5416_MAX_RATE_POWER;
+ if (ratesArray[i] > MAX_RATE_POWER)
+ ratesArray[i] = MAX_RATE_POWER;
+
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
}
+ if (test)
+ return;
/* Update regulatory */
-
i = rate6mb;
if (IS_CHAN_HT40(chan))
i = rateHt40_0;
@@ -934,8 +770,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
pModal = &eep->modalHeader;
txRxAttenLocal = 23;
- REG_WRITE(ah, AR_PHY_SWITCH_COM,
- ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
/* Single chain for 4K EEPROM*/
ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
@@ -1151,21 +986,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
}
}
-static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
-
- return pModal->antCtrlCommon;
-}
-
-static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
- enum ath9k_hal_freq_band freq_band)
-{
- return 1;
-}
-
static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
{
#define EEP_MAP4K_SPURCHAN \
@@ -1174,17 +994,17 @@ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_MAP4K_SPURCHAN;
@@ -1202,8 +1022,6 @@ const struct eeprom_ops eep_4k_ops = {
.fill_eeprom = ath9k_hw_4k_fill_eeprom,
.get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
.get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
- .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
- .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
.set_board_values = ath9k_hw_4k_set_board_values,
.set_addac = ath9k_hw_4k_set_addac,
.set_txpower = ath9k_hw_4k_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 195406db3bd8..9b6bc8a953bc 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -37,21 +37,21 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
int addr, eep_start_loc;
eep_data = (u16 *)eep;
- if (AR9287_HTC_DEVID(ah))
+ if (common->bus_ops->ath_bus_type == ATH_USB)
eep_start_loc = AR9287_HTC_EEP_START_LOC;
else
eep_start_loc = AR9287_EEP_START_LOC;
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < NUM_EEP_WORDS; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
eep_data)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -72,13 +72,12 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
if (!ath9k_hw_use_flash(ah)) {
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) {
- ath_print(common, ATH_DBG_FATAL,
- "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -93,16 +92,15 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "Endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.map9287.baseEepHeader.length);
@@ -152,7 +150,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
eep->modalHeader.antCtrlChain[i] = integer;
}
- for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(eep->modalHeader.spurChans[i].spurChan);
eep->modalHeader.spurChans[i].spurChan = word;
}
@@ -160,9 +158,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
|| ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ah->eep_ops->get_eeprom_ver(ah));
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -223,163 +220,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
}
}
-static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
- struct ath9k_channel *chan,
- struct cal_data_per_freq_ar9287 *pRawDataSet,
- u8 *bChans, u16 availPiers,
- u16 tPdGainOverlap,
- u16 *pPdGainBoundaries,
- u8 *pPDADCValues,
- u16 numXpdGains)
-{
-#define TMP_VAL_VPD_TABLE \
- ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
-
- int i, j, k;
- int16_t ss;
- u16 idxL = 0, idxR = 0, numPiers;
- u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
- u8 minPwrT4[AR9287_NUM_PD_GAINS];
- u8 maxPwrT4[AR9287_NUM_PD_GAINS];
- int16_t vpdStep;
- int16_t tmpVal;
- u16 sizeCurrVpdTable, maxIndex, tgtIndex;
- bool match;
- int16_t minDelta = 0;
- struct chan_centers centers;
- static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
- memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
- break;
- }
-
- match = ath9k_hw_get_lower_upper_index(
- (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
- bChans, numPiers, &idxL, &idxR);
-
- if (match) {
- for (i = 0; i < numXpdGains; i++) {
- minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
- maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pRawDataSet[idxL].pwrPdg[i],
- pRawDataSet[idxL].vpdPdg[i],
- AR9287_PD_GAIN_ICEPTS,
- vpdTableI[i]);
- }
- } else {
- for (i = 0; i < numXpdGains; i++) {
- pVpdL = pRawDataSet[idxL].vpdPdg[i];
- pPwrL = pRawDataSet[idxL].pwrPdg[i];
- pVpdR = pRawDataSet[idxR].vpdPdg[i];
- pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
- minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
- maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
- pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
-
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrL, pVpdL,
- AR9287_PD_GAIN_ICEPTS,
- vpdTableL[i]);
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrR, pVpdR,
- AR9287_PD_GAIN_ICEPTS,
- vpdTableR[i]);
-
- for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] = (u8)(ath9k_hw_interpolate(
- (u16)FREQ2FBIN(centers. synth_center,
- IS_CHAN_2GHZ(chan)),
- bChans[idxL], bChans[idxR],
- vpdTableL[i][j], vpdTableR[i][j]));
- }
- }
- }
-
- k = 0;
-
- for (i = 0; i < numXpdGains; i++) {
- if (i == (numXpdGains - 1))
- pPdGainBoundaries[i] =
- (u16)(maxPwrT4[i] / 2);
- else
- pPdGainBoundaries[i] =
- (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
-
- pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
- pPdGainBoundaries[i]);
-
-
- minDelta = 0;
-
- if (i == 0) {
- if (AR_SREV_9280_20_OR_LATER(ah))
- ss = (int16_t)(0 - (minPwrT4[i] / 2));
- else
- ss = 0;
- } else {
- ss = (int16_t)((pPdGainBoundaries[i-1] -
- (minPwrT4[i] / 2)) -
- tPdGainOverlap + 1 + minDelta);
- }
-
- vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
- pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
- ss++;
- }
-
- sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
- tgtIndex = (u8)(pPdGainBoundaries[i] +
- tPdGainOverlap - (minPwrT4[i] / 2));
- maxIndex = (tgtIndex < sizeCurrVpdTable) ?
- tgtIndex : sizeCurrVpdTable;
-
- while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
- pPDADCValues[k++] = vpdTableI[i][ss++];
-
- vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- if (tgtIndex > maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR9287_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
- pPDADCValues[k++] =
- (u8)((tmpVal > 255) ? 255 : tmpVal);
- ss++;
- }
- }
- }
-
- while (i < AR9287_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
- i++;
- }
-
- while (k < AR9287_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k-1];
- k++;
- }
-
-#undef TMP_VAL_VPD_TABLE
-}
-
static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
struct ath9k_channel *chan,
struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
@@ -392,7 +232,7 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
ath9k_hw_get_channel_centers(ah, chan, &centers);
for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
+ if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
break;
}
@@ -458,11 +298,11 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
u8 *pCalBChans = NULL;
u16 pdGainOverlap_t2;
- u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
+ u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
u16 numPiers = 0, i, j;
u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
+ u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
u32 reg32, regOffset, regChainOffset, regval;
int16_t modalIdx, diff = 0;
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
@@ -490,12 +330,12 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
numXpdGain = 0;
/* Calculate the value of xpdgains from the xpdGain Mask */
- for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR9287_NUM_PD_GAINS)
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
break;
xpdGainValues[numXpdGain] =
- (u16)(AR9287_PD_GAINS_IN_MASK-i);
+ (u16)(AR5416_PD_GAINS_IN_MASK-i);
numXpdGain++;
}
}
@@ -528,7 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
(struct cal_data_per_freq_ar9287 *)
pEepData->calPierData2G[i];
- ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan,
+ ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
pRawDataset,
pCalBChans, numPiers,
pdGainOverlap_t2,
@@ -564,13 +404,13 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
(int32_t)AR9287_PWR_TABLE_OFFSET_DB);
diff *= 2;
- for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++)
+ for (j = 0; j < ((u16)AR5416_NUM_PDADC_VALUES-diff); j++)
pdadcValues[j] = pdadcValues[j+diff];
- for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
- j < AR9287_NUM_PDADC_VALUES; j++)
+ for (j = (u16)(AR5416_NUM_PDADC_VALUES-diff);
+ j < AR5416_NUM_PDADC_VALUES; j++)
pdadcValues[j] =
- pdadcValues[AR9287_NUM_PDADC_VALUES-diff];
+ pdadcValues[AR5416_NUM_PDADC_VALUES-diff];
}
if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
@@ -613,9 +453,9 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+ { 0, 3, 6, 9, MAX_RATE_POWER };
int i;
int16_t twiceLargestAntenna;
struct cal_ctl_data_ar9287 *rep;
@@ -626,13 +466,13 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
struct cal_target_power_ht targetPowerHt20,
targetPowerHt40 = {0, {0, 0, 0, 0} };
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11g[] = {CTL_11B,
- CTL_11G,
- CTL_2GHT20,
- CTL_11B_EXT,
- CTL_11G_EXT,
- CTL_2GHT40};
- u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ u16 numCtlModes = 0;
+ const u16 *pCtlMode = NULL;
+ u16 ctlMode, freq;
struct chan_centers centers;
int tx_chainmask;
u16 twiceMinEdgePower;
@@ -853,7 +693,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
@@ -877,12 +717,26 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR9287_MAX_RATE_POWER)
- ratesArray[i] = AR9287_MAX_RATE_POWER;
+ if (ratesArray[i] > MAX_RATE_POWER)
+ ratesArray[i] = MAX_RATE_POWER;
+
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
}
+ if (test)
+ return;
+
+ if (IS_CHAN_2GHZ(chan))
+ i = rate1l;
+ else
+ i = rate6mb;
+
+ regulatory->max_power_level = ratesArray[i];
+
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
@@ -971,17 +825,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
-
- if (IS_CHAN_2GHZ(chan))
- i = rate1l;
- else
- i = rate6mb;
-
- if (AR_SREV_9280_20_OR_LATER(ah))
- regulatory->max_power_level =
- ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
- else
- regulatory->max_power_level = ratesArray[i];
}
static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
@@ -1023,8 +866,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
}
- REG_WRITE(ah, AR_PHY_SWITCH_COM,
- ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
for (i = 0; i < AR9287_MAX_CHAINS; i++) {
regChainOffset = i * 0x1000;
@@ -1125,21 +967,6 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
pModal->xpaBiasLvl);
}
-static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah,
- enum ath9k_hal_freq_band freq_band)
-{
- return 1;
-}
-
-static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- struct ar9287_eeprom *eep = &ah->eeprom.map9287;
- struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
-
- return pModal->antCtrlCommon;
-}
-
static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
u16 i, bool is2GHz)
{
@@ -1149,17 +976,17 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_MAP9287_SPURCHAN;
@@ -1177,8 +1004,6 @@ const struct eeprom_ops eep_ar9287_ops = {
.fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
.get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
.get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
- .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config,
- .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg,
.set_board_values = ath9k_hw_ar9287_set_board_values,
.set_addac = ath9k_hw_ar9287_set_addac,
.set_txpower = ath9k_hw_ar9287_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 76b4d65472dd..088f141f2006 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -96,8 +96,8 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
eep_data)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to read eeprom region\n");
+ ath_err(ath9k_hw_common(ah),
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -117,13 +117,13 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
int i, addr, size;
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
- ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -139,16 +139,15 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "Endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.def.baseEepHeader.length);
@@ -169,8 +168,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
u32 integer, j;
u16 word;
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing.\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing.\n");
word = swab16(eep->baseEepHeader.length);
eep->baseEepHeader.length = word;
@@ -207,7 +206,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
pModal->antCtrlChain[i] = integer;
}
- for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(pModal->spurChans[i].spurChan);
pModal->spurChans[i].spurChan = word;
}
@@ -216,8 +215,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -376,8 +374,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
- REG_WRITE(ah, AR_PHY_SWITCH_COM,
- ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_9280(ah)) {
@@ -451,9 +448,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
AR_AN_TOP2_LOCALBIAS,
AR_AN_TOP2_LOCALBIAS_S,
- pModal->local_bias);
+ !!(pModal->lna_ctl &
+ LNA_CTL_LOCAL_BIAS));
REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
- pModal->force_xpaon);
+ !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
}
REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
@@ -589,168 +587,6 @@ static void ath9k_hw_def_set_addac(struct ath_hw *ah,
#undef XPA_LVL_FREQ
}
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
- struct ath9k_channel *chan,
- struct cal_data_per_freq *pRawDataSet,
- u8 *bChans, u16 availPiers,
- u16 tPdGainOverlap,
- u16 *pPdGainBoundaries, u8 *pPDADCValues,
- u16 numXpdGains)
-{
- int i, j, k;
- int16_t ss;
- u16 idxL = 0, idxR = 0, numPiers;
- static u8 vpdTableL[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableR[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableI[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
- u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
- u8 minPwrT4[AR5416_NUM_PD_GAINS];
- u8 maxPwrT4[AR5416_NUM_PD_GAINS];
- int16_t vpdStep;
- int16_t tmpVal;
- u16 sizeCurrVpdTable, maxIndex, tgtIndex;
- bool match;
- int16_t minDelta = 0;
- struct chan_centers centers;
-
- memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
- break;
- }
-
- match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan)),
- bChans, numPiers, &idxL, &idxR);
-
- if (match) {
- for (i = 0; i < numXpdGains; i++) {
- minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
- maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pRawDataSet[idxL].pwrPdg[i],
- pRawDataSet[idxL].vpdPdg[i],
- AR5416_PD_GAIN_ICEPTS,
- vpdTableI[i]);
- }
- } else {
- for (i = 0; i < numXpdGains; i++) {
- pVpdL = pRawDataSet[idxL].vpdPdg[i];
- pPwrL = pRawDataSet[idxL].pwrPdg[i];
- pVpdR = pRawDataSet[idxR].vpdPdg[i];
- pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
- minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
- maxPwrT4[i] =
- min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
- pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrL, pVpdL,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableL[i]);
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrR, pVpdR,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableR[i]);
-
- for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] =
- (u8)(ath9k_hw_interpolate((u16)
- FREQ2FBIN(centers.
- synth_center,
- IS_CHAN_2GHZ
- (chan)),
- bChans[idxL], bChans[idxR],
- vpdTableL[i][j], vpdTableR[i][j]));
- }
- }
- }
-
- k = 0;
-
- for (i = 0; i < numXpdGains; i++) {
- if (i == (numXpdGains - 1))
- pPdGainBoundaries[i] =
- (u16)(maxPwrT4[i] / 2);
- else
- pPdGainBoundaries[i] =
- (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
- pPdGainBoundaries[i] =
- min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
- if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
- minDelta = pPdGainBoundaries[0] - 23;
- pPdGainBoundaries[0] = 23;
- } else {
- minDelta = 0;
- }
-
- if (i == 0) {
- if (AR_SREV_9280_20_OR_LATER(ah))
- ss = (int16_t)(0 - (minPwrT4[i] / 2));
- else
- ss = 0;
- } else {
- ss = (int16_t)((pPdGainBoundaries[i - 1] -
- (minPwrT4[i] / 2)) -
- tPdGainOverlap + 1 + minDelta);
- }
- vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
- pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
- ss++;
- }
-
- sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
- tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
- (minPwrT4[i] / 2));
- maxIndex = (tgtIndex < sizeCurrVpdTable) ?
- tgtIndex : sizeCurrVpdTable;
-
- while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- pPDADCValues[k++] = vpdTableI[i][ss++];
- }
-
- vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- if (tgtIndex >= maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
- (ss - maxIndex + 1) * vpdStep));
- pPDADCValues[k++] = (u8)((tmpVal > 255) ?
- 255 : tmpVal);
- ss++;
- }
- }
- }
-
- while (i < AR5416_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
- i++;
- }
-
- while (k < AR5416_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k - 1];
- k++;
- }
-}
-
static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
u16 *gb,
u16 numXpdGain,
@@ -783,7 +619,7 @@ static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
/* Because of a hardware limitation, ensure the gain boundary
* is not larger than (63 - overlap)
*/
- gb_limit = (u16)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2);
+ gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
for (k = 0; k < numXpdGain; k++)
gb[k] = (u16)min(gb_limit, gb[k]);
@@ -917,7 +753,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
ath9k_olc_get_pdadcs(ah, pcdacIdx,
txPower/2, pdadcValues);
} else {
- ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+ ath9k_hw_get_gain_boundaries_pdadcs(ah,
chan, pRawDataset,
pCalBChans, numPiers,
pdGainOverlap_t2,
@@ -965,20 +801,19 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC: Chain %d | PDADC %3d "
- "Value %3d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | PDADC %3d "
- "Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC: Chain %d | PDADC %3d "
+ "Value %3d | PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | PDADC %3d "
+ "Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3, pdadcValues[4 * j + 3]);
regOffset += 4;
}
@@ -1003,9 +838,9 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ u16 twiceMaxEdgePower = MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+ { 0, 3, 6, 9, MAX_RATE_POWER };
int i;
int16_t twiceLargestAntenna;
@@ -1021,13 +856,16 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
0, {0, 0, 0, 0}
};
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] =
- { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ static const u16 ctlModesFor11a[] = {
+ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+ };
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
int tx_chainmask;
u16 twiceMinEdgePower;
@@ -1062,15 +900,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
case 1:
break;
case 2:
- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ else
+ scaledPower = 0;
break;
case 3:
- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ else
+ scaledPower = 0;
break;
}
- scaledPower = max((u16)0, scaledPower);
-
if (IS_CHAN_2GHZ(chan)) {
numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
SUB_NUM_CTL_MODES_AT_2G_40;
@@ -1143,7 +985,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
ah->eep_ops->get_eeprom_rev(ah) <= 2)
- twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ twiceMaxEdgePower = MAX_RATE_POWER;
for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
if ((((cfgCtl & ~CTL_MODE_M) |
@@ -1258,7 +1100,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -1285,12 +1127,44 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR5416_MAX_RATE_POWER)
- ratesArray[i] = AR5416_MAX_RATE_POWER;
+ if (ratesArray[i] > MAX_RATE_POWER)
+ ratesArray[i] = MAX_RATE_POWER;
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
}
+ if (!test) {
+ i = rate6mb;
+
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
+
+ regulatory->max_power_level = ratesArray[i];
+ }
+
+ switch(ar5416_get_ntxchains(ah->txchainmask)) {
+ case 1:
+ break;
+ case 2:
+ regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+ break;
+ case 3:
+ regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+ break;
+ default:
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
+ break;
+ }
+
+ if (test)
+ return;
+
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++) {
int8_t pwr_table_offset;
@@ -1387,62 +1261,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
- i = rate6mb;
-
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
-
- if (AR_SREV_9280_20_OR_LATER(ah))
- regulatory->max_power_level =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2;
- else
- regulatory->max_power_level = ratesArray[i];
-
- switch(ar5416_get_ntxchains(ah->txchainmask)) {
- case 1:
- break;
- case 2:
- regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
- break;
- case 3:
- regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
- break;
- default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
- "Invalid chainmask configuration\n");
- break;
- }
-}
-
-static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
- enum ath9k_hal_freq_band freq_band)
-{
- struct ar5416_eeprom_def *eep = &ah->eeprom.def;
- struct modal_eep_header *pModal =
- &(eep->modalHeader[freq_band]);
- struct base_eep_header *pBase = &eep->baseEepHeader;
- u8 num_ant_config;
-
- num_ant_config = 1;
-
- if (pBase->version >= 0x0E0D)
- if (pModal->useAnt1)
- num_ant_config += 1;
-
- return num_ant_config;
-}
-
-static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- struct ar5416_eeprom_def *eep = &ah->eeprom.def;
- struct modal_eep_header *pModal =
- &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
- return pModal->antCtrlCommon;
}
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
@@ -1453,17 +1271,17 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_DEF_SPURCHAN;
@@ -1481,8 +1299,6 @@ const struct eeprom_ops eep_def_ops = {
.fill_eeprom = ath9k_hw_def_fill_eeprom,
.get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
.get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
- .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
- .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
.set_board_values = ath9k_hw_def_set_board_values,
.set_addac = ath9k_hw_def_set_addac,
.set_txpower = ath9k_hw_def_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 4a9a68bba324..133764069246 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -103,8 +103,8 @@ static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
if (ret)
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Failed to register led:%s", led->name);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Failed to register led:%s", led->name);
else
led->registered = 1;
return ret;
@@ -236,13 +236,13 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
/* Detect if colocated bt started scanning */
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
- "BT scan detected");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+ "BT scan detected\n");
sc->sc_flags |= (SC_OP_BT_SCAN |
SC_OP_BT_PRIORITY_DETECTED);
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
- "BT priority traffic detected");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected\n");
sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
}
@@ -259,7 +259,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ah->imask |= ATH9K_INT_GENTIMER;
ath9k_hw_set_interrupts(ah, ah->imask);
}
@@ -273,7 +273,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
/* if no timer is enabled, turn off interrupt mask */
if (timer_table->timer_mask.val == 0) {
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ah->imask &= ~ATH9K_INT_GENTIMER;
ath9k_hw_set_interrupts(ah, ah->imask);
}
@@ -310,10 +310,8 @@ static void ath_btcoex_period_timer(unsigned long data)
timer_period = is_btscan ? btcoex->btscan_no_stomp :
btcoex->btcoex_no_stomp;
- ath9k_gen_timer_start(ah,
- btcoex->no_stomp_timer,
- (ath9k_hw_gettsf32(ah) +
- timer_period), timer_period * 10);
+ ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
+ timer_period * 10);
btcoex->hw_timer_enabled = true;
}
@@ -333,8 +331,8 @@ static void ath_btcoex_no_stomp_timer(void *arg)
struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
- ath_print(common, ATH_DBG_BTCOEX,
- "no stomp timer running\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "no stomp timer running\n");
spin_lock_bh(&btcoex->btcoex_lock);
@@ -380,8 +378,8 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_hw *ah = sc->sc_ah;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Starting btcoex timers");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Starting btcoex timers\n");
/* make sure duty cycle timer is also stopped when resuming */
if (btcoex->hw_timer_enabled)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index dfb6560dab92..5ab3084eb9cb 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -28,10 +28,7 @@ MODULE_FIRMWARE(FIRMWARE_AR9271);
static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
{ USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
- { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */
- { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */
{ USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
- { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */
{ USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
@@ -40,9 +37,21 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
- { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
- { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */
+ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
+
+ { USB_DEVICE(0x0cf3, 0x7015),
+ .driver_info = AR9287_USB }, /* Atheros */
+ { USB_DEVICE(0x1668, 0x1200),
+ .driver_info = AR9287_USB }, /* Verizon */
+
+ { USB_DEVICE(0x0cf3, 0x7010),
+ .driver_info = AR9280_USB }, /* Atheros */
+ { USB_DEVICE(0x0846, 0x9018),
+ .driver_info = AR9280_USB }, /* Netgear WNDA3200 */
+ { USB_DEVICE(0x083A, 0xA704),
+ .driver_info = AR9280_USB }, /* SMC Networks */
+
{ },
};
@@ -144,16 +153,36 @@ static void hif_usb_tx_cb(struct urb *urb)
case -ENODEV:
case -ESHUTDOWN:
/*
- * The URB has been killed, free the SKBs
- * and return.
+ * The URB has been killed, free the SKBs.
*/
ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
- return;
+
+ /*
+ * If the URBs are being flushed, no need to add this
+ * URB to the free list.
+ */
+ spin_lock(&hif_dev->tx.tx_lock);
+ if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
+ spin_unlock(&hif_dev->tx.tx_lock);
+ return;
+ }
+ spin_unlock(&hif_dev->tx.tx_lock);
+
+ /*
+ * In the stop() case, this URB has to be added to
+ * the free list.
+ */
+ goto add_free;
default:
break;
}
- /* Check if TX has been stopped */
+ /*
+ * Check if TX has been stopped, this is needed because
+ * this CB could have been invoked just after the TX lock
+ * was released in hif_stop() and kill_urb() hasn't been
+ * called yet.
+ */
spin_lock(&hif_dev->tx.tx_lock);
if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
spin_unlock(&hif_dev->tx.tx_lock);
@@ -305,6 +334,7 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id)
static void hif_usb_stop(void *hif_handle, u8 pipe_id)
{
struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
+ struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
unsigned long flags;
spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
@@ -312,6 +342,12 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
hif_dev->tx.tx_skb_cnt = 0;
hif_dev->tx.flags |= HIF_USB_TX_STOP;
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+
+ /* The pending URBs have to be canceled. */
+ list_for_each_entry_safe(tx_buf, tx_buf_tmp,
+ &hif_dev->tx.tx_pending, list) {
+ usb_kill_urb(tx_buf->urb);
+ }
}
static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
@@ -353,9 +389,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
struct sk_buff *skb)
{
struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
- int index = 0, i = 0, chk_idx, len = skb->len;
- int rx_remain_len = 0, rx_pkt_len = 0;
- u16 pkt_len, pkt_tag, pool_index = 0;
+ int index = 0, i = 0, len = skb->len;
+ int rx_remain_len, rx_pkt_len;
+ u16 pool_index = 0;
u8 *ptr;
spin_lock(&hif_dev->rx_lock);
@@ -389,64 +425,64 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
spin_unlock(&hif_dev->rx_lock);
while (index < len) {
+ u16 pkt_len;
+ u16 pkt_tag;
+ u16 pad_len;
+ int chk_idx;
+
ptr = (u8 *) skb->data;
pkt_len = ptr[index] + (ptr[index+1] << 8);
pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
- if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
- u16 pad_len;
-
- pad_len = 4 - (pkt_len & 0x3);
- if (pad_len == 4)
- pad_len = 0;
-
- chk_idx = index;
- index = index + 4 + pkt_len + pad_len;
-
- if (index > MAX_RX_BUF_SIZE) {
- spin_lock(&hif_dev->rx_lock);
- hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
- hif_dev->rx_transfer_len =
- MAX_RX_BUF_SIZE - chk_idx - 4;
- hif_dev->rx_pad_len = pad_len;
-
- nskb = __dev_alloc_skb(pkt_len + 32,
- GFP_ATOMIC);
- if (!nskb) {
- dev_err(&hif_dev->udev->dev,
- "ath9k_htc: RX memory allocation"
- " error\n");
- spin_unlock(&hif_dev->rx_lock);
- goto err;
- }
- skb_reserve(nskb, 32);
- RX_STAT_INC(skb_allocated);
-
- memcpy(nskb->data, &(skb->data[chk_idx+4]),
- hif_dev->rx_transfer_len);
-
- /* Record the buffer pointer */
- hif_dev->remain_skb = nskb;
+ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
+ RX_STAT_INC(skb_dropped);
+ return;
+ }
+
+ pad_len = 4 - (pkt_len & 0x3);
+ if (pad_len == 4)
+ pad_len = 0;
+
+ chk_idx = index;
+ index = index + 4 + pkt_len + pad_len;
+
+ if (index > MAX_RX_BUF_SIZE) {
+ spin_lock(&hif_dev->rx_lock);
+ hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
+ hif_dev->rx_transfer_len =
+ MAX_RX_BUF_SIZE - chk_idx - 4;
+ hif_dev->rx_pad_len = pad_len;
+
+ nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
+ if (!nskb) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: RX memory allocation error\n");
spin_unlock(&hif_dev->rx_lock);
- } else {
- nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
- if (!nskb) {
- dev_err(&hif_dev->udev->dev,
- "ath9k_htc: RX memory allocation"
- " error\n");
- goto err;
- }
- skb_reserve(nskb, 32);
- RX_STAT_INC(skb_allocated);
-
- memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
- skb_put(nskb, pkt_len);
- skb_pool[pool_index++] = nskb;
+ goto err;
}
+ skb_reserve(nskb, 32);
+ RX_STAT_INC(skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]),
+ hif_dev->rx_transfer_len);
+
+ /* Record the buffer pointer */
+ hif_dev->remain_skb = nskb;
+ spin_unlock(&hif_dev->rx_lock);
} else {
- RX_STAT_INC(skb_dropped);
- return;
+ nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
+ if (!nskb) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: RX memory allocation error\n");
+ goto err;
+ }
+ skb_reserve(nskb, 32);
+ RX_STAT_INC(skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
+ skb_put(nskb, pkt_len);
+ skb_pool[pool_index++] = nskb;
}
}
@@ -461,7 +497,7 @@ err:
static void ath9k_hif_usb_rx_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct hif_device_usb *hif_dev = (struct hif_device_usb *)
+ struct hif_device_usb *hif_dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int ret;
@@ -508,7 +544,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
struct sk_buff *nskb;
- struct hif_device_usb *hif_dev = (struct hif_device_usb *)
+ struct hif_device_usb *hif_dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int ret;
@@ -578,6 +614,7 @@ free:
static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
{
struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
+ unsigned long flags;
list_for_each_entry_safe(tx_buf, tx_buf_tmp,
&hif_dev->tx.tx_buf, list) {
@@ -588,6 +625,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
kfree(tx_buf);
}
+ spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+ hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
+ spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+
list_for_each_entry_safe(tx_buf, tx_buf_tmp,
&hif_dev->tx.tx_pending, list) {
usb_kill_urb(tx_buf->urb);
@@ -776,7 +817,8 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}
-static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
+ u32 drv_info)
{
int transfer, err;
const void *data = hif_dev->firmware->data;
@@ -807,18 +849,10 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
}
kfree(buf);
- switch (hif_dev->device_id) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(drv_info))
firm_offset = AR7010_FIRMWARE_TEXT;
- break;
- default:
+ else
firm_offset = AR9271_FIRMWARE_TEXT;
- break;
- }
/*
* Issue FW download complete command to firmware.
@@ -836,7 +870,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
return 0;
}
-static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
{
int ret, idx;
struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
@@ -852,7 +886,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
}
/* Download firmware */
- ret = ath9k_hif_usb_download_fw(hif_dev);
+ ret = ath9k_hif_usb_download_fw(hif_dev, drv_info);
if (ret) {
dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s download failed\n",
@@ -884,9 +918,9 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
return 0;
-err_fw_download:
- ath9k_hif_usb_dealloc_urbs(hif_dev);
err_urb:
+ ath9k_hif_usb_dealloc_urbs(hif_dev);
+err_fw_download:
release_firmware(hif_dev->firmware);
err_fw_req:
hif_dev->firmware = NULL;
@@ -931,23 +965,15 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
/* Find out which firmware to load */
- switch(hif_dev->device_id) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(id->driver_info))
if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
hif_dev->fw_name = FIRMWARE_AR7010_1_1;
else
hif_dev->fw_name = FIRMWARE_AR7010;
- break;
- default:
+ else
hif_dev->fw_name = FIRMWARE_AR9271;
- break;
- }
- ret = ath9k_hif_usb_dev_init(hif_dev);
+ ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info);
if (ret) {
ret = -EINVAL;
goto err_hif_init_usb;
@@ -955,7 +981,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
&hif_dev->udev->dev, hif_dev->device_id,
- hif_dev->udev->product);
+ hif_dev->udev->product, id->driver_info);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
@@ -998,18 +1024,17 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
{
struct usb_device *udev = interface_to_usbdev(interface);
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
+ bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false;
if (hif_dev) {
- ath9k_htc_hw_deinit(hif_dev->htc_handle,
- (udev->state == USB_STATE_NOTATTACHED) ? true : false);
+ ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
ath9k_htc_hw_free(hif_dev->htc_handle);
ath9k_hif_usb_dev_deinit(hif_dev);
usb_set_intfdata(interface, NULL);
}
- if (hif_dev->flags & HIF_USB_START)
+ if (!unplugged && (hif_dev->flags & HIF_USB_START))
ath9k_hif_usb_reboot(udev);
kfree(hif_dev);
@@ -1021,8 +1046,14 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
static int ath9k_hif_usb_suspend(struct usb_interface *interface,
pm_message_t message)
{
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
+
+ /*
+ * The device has to be set to FULLSLEEP mode in case no
+ * interface is up.
+ */
+ if (!(hif_dev->flags & HIF_USB_START))
+ ath9k_htc_suspend(hif_dev->htc_handle);
ath9k_hif_usb_dealloc_urbs(hif_dev);
@@ -1031,8 +1062,8 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
static int ath9k_hif_usb_resume(struct usb_interface *interface)
{
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
+ struct htc_target *htc_handle = hif_dev->htc_handle;
int ret;
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
@@ -1040,7 +1071,8 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
return ret;
if (hif_dev->firmware) {
- ret = ath9k_hif_usb_download_fw(hif_dev);
+ ret = ath9k_hif_usb_download_fw(hif_dev,
+ htc_handle->drv_priv->ah->hw_version.usbdev);
if (ret)
goto fail_resume;
} else {
@@ -1050,7 +1082,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
mdelay(100);
- ret = ath9k_htc_resume(hif_dev->htc_handle);
+ ret = ath9k_htc_resume(htc_handle);
if (ret)
goto fail_resume;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 2daf97b11c08..7b9d863d4035 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -17,6 +17,8 @@
#ifndef HTC_USB_H
#define HTC_USB_H
+#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
+
#define AR9271_FIRMWARE 0x501000
#define AR9271_FIRMWARE_TEXT 0x903000
#define AR7010_FIRMWARE_TEXT 0x906000
@@ -62,6 +64,7 @@ struct tx_buf {
};
#define HIF_USB_TX_STOP BIT(0)
+#define HIF_USB_TX_FLUSH BIT(1)
struct hif_usb_tx {
u8 flags;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 75ecf6a30d25..a099b3e87ed3 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -331,17 +331,15 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#define OP_INVALID BIT(0)
#define OP_SCANNING BIT(1)
-#define OP_FULL_RESET BIT(2)
-#define OP_LED_ASSOCIATED BIT(3)
-#define OP_LED_ON BIT(4)
-#define OP_PREAMBLE_SHORT BIT(5)
-#define OP_PROTECT_ENABLE BIT(6)
-#define OP_ASSOCIATED BIT(7)
-#define OP_ENABLE_BEACON BIT(8)
-#define OP_LED_DEINIT BIT(9)
-#define OP_UNPLUGGED BIT(10)
-#define OP_BT_PRIORITY_DETECTED BIT(11)
-#define OP_BT_SCAN BIT(12)
+#define OP_LED_ASSOCIATED BIT(2)
+#define OP_LED_ON BIT(3)
+#define OP_PREAMBLE_SHORT BIT(4)
+#define OP_PROTECT_ENABLE BIT(5)
+#define OP_ASSOCIATED BIT(6)
+#define OP_ENABLE_BEACON BIT(7)
+#define OP_LED_DEINIT BIT(8)
+#define OP_BT_PRIORITY_DETECTED BIT(9)
+#define OP_BT_SCAN BIT(10)
struct ath9k_htc_priv {
struct device *dev;
@@ -368,7 +366,7 @@ struct ath9k_htc_priv {
u16 seq_no;
u32 bmiss_cnt;
- struct ath9k_hw_cal_data caldata[38];
+ struct ath9k_hw_cal_data caldata[ATH9K_NUM_CHANNELS];
spinlock_t beacon_lock;
@@ -378,7 +376,7 @@ struct ath9k_htc_priv {
struct ieee80211_vif *vif;
struct htc_beacon_config cur_beacon_conf;
unsigned int rxfilter;
- struct tasklet_struct wmi_tasklet;
+ struct tasklet_struct swba_tasklet;
struct tasklet_struct rx_tasklet;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath9k_htc_rx rx;
@@ -386,6 +384,7 @@ struct ath9k_htc_priv {
struct sk_buff_head tx_queue;
struct delayed_work ath9k_ani_work;
struct work_struct ps_work;
+ struct work_struct fatal_work;
struct mutex htc_pm_lock;
unsigned long ps_usecount;
@@ -420,6 +419,8 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
common->bus_ops->read_cachesize(common, csz);
}
+void ath9k_htc_reset(struct ath9k_htc_priv *priv);
+
void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif);
@@ -435,6 +436,7 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
void ath9k_htc_station_work(struct work_struct *work);
void ath9k_htc_aggr_work(struct work_struct *work);
void ath9k_ani_work(struct work_struct *work);;
+void ath_start_ani(struct ath9k_htc_priv *priv);
int ath9k_tx_init(struct ath9k_htc_priv *priv);
void ath9k_tx_tasklet(unsigned long data);
@@ -455,15 +457,23 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
void ath9k_ps_work(struct work_struct *work);
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+ enum ath9k_power_mode mode);
+void ath_update_txpow(struct ath9k_htc_priv *priv);
void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
+void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
+void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
+void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
+void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid, char *product);
+ u16 devid, char *product, u32 drv_info);
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
#ifdef CONFIG_PM
+void ath9k_htc_suspend(struct htc_target *htc_handle);
int ath9k_htc_resume(struct htc_target *htc_handle);
#endif
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 1b72aa482ac7..87cc65a78a3f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -123,11 +123,11 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
/* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
- ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
- bs.bs_bmissthreshold, bs.bs_sleepduration,
- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+ ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
/* Set the computed STA beacon timers */
@@ -154,9 +154,9 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA;
- ath_print(common, ATH_DBG_BEACON,
- "IBSS Beacon config, intval: %d, imask: 0x%x\n",
- bss_conf->beacon_interval, imask);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "IBSS Beacon config, intval: %d, imask: 0x%x\n",
+ bss_conf->beacon_interval, imask);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
@@ -246,8 +246,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
qi.tqi_cwmax = qi_be.tqi_cwmax;
if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to update beacon queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(ah),
+ "Unable to update beacon queue %u!\n", qnum);
} else {
ath9k_hw_resettxqueue(ah, priv->beaconq);
}
@@ -278,8 +278,8 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
ath9k_htc_beacon_config_adhoc(priv, cur_conf);
break;
default:
- ath_print(common, ATH_DBG_CONFIG,
- "Unsupported beaconing mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
return;
}
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 50eec9a3b88c..fe70f67aa088 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
#include "htc.h"
/******************/
@@ -20,13 +36,13 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv)
priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
/* Detect if colocated bt started scanning */
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "BT scan detected");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT scan detected\n");
priv->op_flags |= (OP_BT_SCAN |
OP_BT_PRIORITY_DETECTED);
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "BT priority traffic detected");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected\n");
priv->op_flags |= OP_BT_PRIORITY_DETECTED;
}
@@ -83,8 +99,8 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = priv->op_flags & OP_BT_SCAN;
- ath_print(common, ATH_DBG_BTCOEX,
- "time slice work for bt and wlan\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "time slice work for bt and wlan\n");
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
@@ -114,8 +130,7 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
struct ath_btcoex *btcoex = &priv->btcoex;
struct ath_hw *ah = priv->ah;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Starting btcoex work");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "Starting btcoex work\n");
btcoex->bt_priority_cnt = 0;
btcoex->bt_priority_time = jiffies;
@@ -132,3 +147,314 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
cancel_delayed_work_sync(&priv->coex_period_work);
cancel_delayed_work_sync(&priv->duty_cycle_work);
}
+
+/*******/
+/* LED */
+/*******/
+
+static void ath9k_led_blink_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ ath9k_led_blink_work.work);
+
+ if (!(priv->op_flags & OP_LED_ASSOCIATED))
+ return;
+
+ if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
+ (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
+ else
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
+ (priv->op_flags & OP_LED_ON) ? 1 : 0);
+
+ ieee80211_queue_delayed_work(priv->hw,
+ &priv->ath9k_led_blink_work,
+ (priv->op_flags & OP_LED_ON) ?
+ msecs_to_jiffies(priv->led_off_duration) :
+ msecs_to_jiffies(priv->led_on_duration));
+
+ priv->led_on_duration = priv->led_on_cnt ?
+ max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
+ ATH_LED_ON_DURATION_IDLE;
+ priv->led_off_duration = priv->led_off_cnt ?
+ max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
+ ATH_LED_OFF_DURATION_IDLE;
+ priv->led_on_cnt = priv->led_off_cnt = 0;
+
+ if (priv->op_flags & OP_LED_ON)
+ priv->op_flags &= ~OP_LED_ON;
+ else
+ priv->op_flags |= OP_LED_ON;
+}
+
+static void ath9k_led_brightness_work(struct work_struct *work)
+{
+ struct ath_led *led = container_of(work, struct ath_led,
+ brightness_work.work);
+ struct ath9k_htc_priv *priv = led->priv;
+
+ switch (led->brightness) {
+ case LED_OFF:
+ if (led->led_type == ATH_LED_ASSOC ||
+ led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
+ (led->led_type == ATH_LED_RADIO));
+ priv->op_flags &= ~OP_LED_ASSOCIATED;
+ if (led->led_type == ATH_LED_RADIO)
+ priv->op_flags &= ~OP_LED_ON;
+ } else {
+ priv->led_off_cnt++;
+ }
+ break;
+ case LED_FULL:
+ if (led->led_type == ATH_LED_ASSOC) {
+ priv->op_flags |= OP_LED_ASSOCIATED;
+ ieee80211_queue_delayed_work(priv->hw,
+ &priv->ath9k_led_blink_work, 0);
+ } else if (led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
+ priv->op_flags |= OP_LED_ON;
+ } else {
+ priv->led_on_cnt++;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath9k_led_brightness(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
+ struct ath9k_htc_priv *priv = led->priv;
+
+ led->brightness = brightness;
+ if (!(priv->op_flags & OP_LED_DEINIT))
+ ieee80211_queue_delayed_work(priv->hw,
+ &led->brightness_work, 0);
+}
+
+void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
+{
+ cancel_delayed_work_sync(&priv->radio_led.brightness_work);
+ cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
+ cancel_delayed_work_sync(&priv->tx_led.brightness_work);
+ cancel_delayed_work_sync(&priv->rx_led.brightness_work);
+}
+
+static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
+ char *trigger)
+{
+ int ret;
+
+ led->priv = priv;
+ led->led_cdev.name = led->name;
+ led->led_cdev.default_trigger = trigger;
+ led->led_cdev.brightness_set = ath9k_led_brightness;
+
+ ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
+ if (ret)
+ ath_err(ath9k_hw_common(priv->ah),
+ "Failed to register led:%s", led->name);
+ else
+ led->registered = 1;
+
+ INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
+
+ return ret;
+}
+
+static void ath9k_unregister_led(struct ath_led *led)
+{
+ if (led->registered) {
+ led_classdev_unregister(&led->led_cdev);
+ led->registered = 0;
+ }
+}
+
+void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
+{
+ priv->op_flags |= OP_LED_DEINIT;
+ ath9k_unregister_led(&priv->assoc_led);
+ priv->op_flags &= ~OP_LED_ASSOCIATED;
+ ath9k_unregister_led(&priv->tx_led);
+ ath9k_unregister_led(&priv->rx_led);
+ ath9k_unregister_led(&priv->radio_led);
+}
+
+void ath9k_init_leds(struct ath9k_htc_priv *priv)
+{
+ char *trigger;
+ int ret;
+
+ if (AR_SREV_9287(priv->ah))
+ priv->ah->led_pin = ATH_LED_PIN_9287;
+ else if (AR_SREV_9271(priv->ah))
+ priv->ah->led_pin = ATH_LED_PIN_9271;
+ else if (AR_DEVID_7010(priv->ah))
+ priv->ah->led_pin = ATH_LED_PIN_7010;
+ else
+ priv->ah->led_pin = ATH_LED_PIN_DEF;
+
+ /* Configure gpio 1 for output */
+ ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ /* LED off, active low */
+ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
+
+ INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
+
+ trigger = ieee80211_get_radio_led_name(priv->hw);
+ snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
+ "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
+ ret = ath9k_register_led(priv, &priv->radio_led, trigger);
+ priv->radio_led.led_type = ATH_LED_RADIO;
+ if (ret)
+ goto fail;
+
+ trigger = ieee80211_get_assoc_led_name(priv->hw);
+ snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
+ "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
+ ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
+ priv->assoc_led.led_type = ATH_LED_ASSOC;
+ if (ret)
+ goto fail;
+
+ trigger = ieee80211_get_tx_led_name(priv->hw);
+ snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
+ "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
+ ret = ath9k_register_led(priv, &priv->tx_led, trigger);
+ priv->tx_led.led_type = ATH_LED_TX;
+ if (ret)
+ goto fail;
+
+ trigger = ieee80211_get_rx_led_name(priv->hw);
+ snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
+ "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
+ ret = ath9k_register_led(priv, &priv->rx_led, trigger);
+ priv->rx_led.led_type = ATH_LED_RX;
+ if (ret)
+ goto fail;
+
+ priv->op_flags &= ~OP_LED_DEINIT;
+
+ return;
+
+fail:
+ cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+ ath9k_deinit_leds(priv);
+}
+
+/*******************/
+/* Rfkill */
+/*******************/
+
+static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
+{
+ return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
+ priv->ah->rfkill_polarity;
+}
+
+void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
+{
+ struct ath9k_htc_priv *priv = hw->priv;
+ bool blocked = !!ath_is_rfkill_set(priv);
+
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+}
+
+void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
+{
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ wiphy_rfkill_start_polling(priv->hw->wiphy);
+}
+
+void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
+{
+ struct ath9k_htc_priv *priv = hw->priv;
+ struct ath_hw *ah = priv->ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ int ret;
+ u8 cmd_rsp;
+
+ if (!ah->curchan)
+ ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
+
+ /* Reset the HW */
+ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+ if (ret) {
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, ah->curchan->channel);
+ }
+
+ ath_update_txpow(priv);
+
+ /* Start RX */
+ WMI_CMD(WMI_START_RECV_CMDID);
+ ath9k_host_rx_init(priv);
+
+ /* Start TX */
+ htc_start(priv->htc);
+ spin_lock_bh(&priv->tx_lock);
+ priv->tx_queues_stop = false;
+ spin_unlock_bh(&priv->tx_lock);
+ ieee80211_wake_queues(hw);
+
+ WMI_CMD(WMI_ENABLE_INTR_CMDID);
+
+ /* Enable LED */
+ ath9k_hw_cfg_output(ah, ah->led_pin,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
+}
+
+void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
+{
+ struct ath9k_htc_priv *priv = hw->priv;
+ struct ath_hw *ah = priv->ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ int ret;
+ u8 cmd_rsp;
+
+ ath9k_htc_ps_wakeup(priv);
+
+ /* Disable LED */
+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+
+ WMI_CMD(WMI_DISABLE_INTR_CMDID);
+
+ /* Stop TX */
+ ieee80211_stop_queues(hw);
+ htc_stop(priv->htc);
+ WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
+ skb_queue_purge(&priv->tx_queue);
+
+ /* Stop RX */
+ WMI_CMD(WMI_STOP_RECV_CMDID);
+
+ /*
+ * The MIB counters have to be disabled here,
+ * since the target doesn't do it.
+ */
+ ath9k_hw_disable_mib_counters(ah);
+
+ if (!ah->curchan)
+ ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
+
+ /* Reset the HW */
+ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+ if (ret) {
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, ah->curchan->channel);
+ }
+
+ /* Disable the PHY */
+ ath9k_hw_phy_disable(ah);
+
+ ath9k_htc_ps_restore(priv);
+ ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
+}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 7c8a38d04561..38433f9bfe59 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -142,7 +142,7 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
{
ath9k_htc_exit_debug(priv->ah);
ath9k_hw_deinit(priv->ah);
- tasklet_kill(&priv->wmi_tasklet);
+ tasklet_kill(&priv->swba_tasklet);
tasklet_kill(&priv->rx_tasklet);
tasklet_kill(&priv->tx_tasklet);
kfree(priv->ah);
@@ -181,7 +181,8 @@ static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
return htc_connect_service(priv->htc, &req, ep_id);
}
-static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
+static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
+ u32 drv_info)
{
int ret;
@@ -245,17 +246,10 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
* the HIF layer, shouldn't matter much.
*/
- switch(devid) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(drv_info))
priv->htc->credits = 45;
- break;
- default:
+ else
priv->htc->credits = 33;
- }
ret = htc_init(priv->htc);
if (ret)
@@ -294,9 +288,9 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
(u8 *) &val, sizeof(val),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER READ FAILED: (0x%04x, %d)\n",
- reg_offset, r);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER READ FAILED: (0x%04x, %d)\n",
+ reg_offset, r);
return -EIO;
}
@@ -308,7 +302,7 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
struct ath_hw *ah = (struct ath_hw *) hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
- __be32 buf[2] = {
+ const __be32 buf[2] = {
cpu_to_be32(reg_offset),
cpu_to_be32(val),
};
@@ -319,9 +313,9 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
(u8 *) &val, sizeof(val),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED:(0x%04x, %d)\n",
- reg_offset, r);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED:(0x%04x, %d)\n",
+ reg_offset, r);
}
}
@@ -351,9 +345,9 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
(u8 *) &rsp_status, sizeof(rsp_status),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED, multi len: %d\n",
- priv->wmi->multi_write_idx);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED, multi len: %d\n",
+ priv->wmi->multi_write_idx);
}
priv->wmi->multi_write_idx = 0;
}
@@ -401,9 +395,9 @@ static void ath9k_regwrite_flush(void *hw_priv)
(u8 *) &rsp_status, sizeof(rsp_status),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED, multi len: %d\n",
- priv->wmi->multi_write_idx);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED, multi len: %d\n",
+ priv->wmi->multi_write_idx);
}
priv->wmi->multi_write_idx = 0;
}
@@ -475,9 +469,9 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv,
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2);
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2);
- ath_print(common, ATH_DBG_CONFIG,
- "TX streams %d, RX streams: %d\n",
- tx_streams, rx_streams);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "TX streams %d, RX streams: %d\n",
+ tx_streams, rx_streams);
if (tx_streams != rx_streams) {
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
@@ -501,37 +495,31 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv)
priv->beaconq = ath9k_hw_beaconq_setup(priv->ah);
if (priv->beaconq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup BEACON xmit queue\n");
+ ath_err(common, "Unable to setup BEACON xmit queue\n");
goto err;
}
priv->cabq = ath9k_htc_cabq_setup(priv);
if (priv->cabq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup CAB xmit queue\n");
+ ath_err(common, "Unable to setup CAB xmit queue\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BE traffic\n");
+ ath_err(common, "Unable to setup xmit queue for BE traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BK traffic\n");
+ ath_err(common, "Unable to setup xmit queue for BK traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VI traffic\n");
+ ath_err(common, "Unable to setup xmit queue for VI traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VO traffic\n");
+ ath_err(common, "Unable to setup xmit queue for VO traffic\n");
goto err;
}
@@ -549,9 +537,9 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
/* Get the hardware key cache size. */
common->keymax = priv->ah->caps.keycache_size;
if (common->keymax > ATH_KEYMAX) {
- ath_print(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
+ ath_dbg(common, ATH_DBG_ANY,
+ "Warning, using only %u entries in %u key cache\n",
+ ATH_KEYMAX, common->keymax);
common->keymax = ATH_KEYMAX;
}
@@ -627,7 +615,8 @@ static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
}
static int ath9k_init_priv(struct ath9k_htc_priv *priv,
- u16 devid, char *product)
+ u16 devid, char *product,
+ u32 drv_info)
{
struct ath_hw *ah = NULL;
struct ath_common *common;
@@ -641,6 +630,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ah->hw_version.devid = devid;
ah->hw_version.subsysid = 0; /* FIXME */
+ ah->hw_version.usbdev = drv_info;
+ ah->ah_flags |= AH_USE_EEPROM;
priv->ah = ah;
common = ath9k_hw_common(ah);
@@ -656,13 +647,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
spin_lock_init(&priv->tx_lock);
mutex_init(&priv->mutex);
mutex_init(&priv->htc_pm_lock);
- tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
+ tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet,
(unsigned long)priv);
tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
(unsigned long)priv);
- tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
+ tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
+ (unsigned long)priv);
INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
INIT_WORK(&priv->ps_work, ath9k_ps_work);
+ INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
/*
* Cache line size is used to size and align various
@@ -673,16 +666,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ret = ath9k_hw_init(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize hardware; "
- "initialization status: %d\n", ret);
+ ath_err(common,
+ "Unable to initialize hardware; initialization status: %d\n",
+ ret);
goto err_hw;
}
ret = ath9k_htc_init_debug(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to create debugfs files\n");
+ ath_err(common, "Unable to create debugfs files\n");
goto err_debug;
}
@@ -762,7 +754,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
}
static int ath9k_init_device(struct ath9k_htc_priv *priv,
- u16 devid, char *product)
+ u16 devid, char *product, u32 drv_info)
{
struct ieee80211_hw *hw = priv->hw;
struct ath_common *common;
@@ -771,7 +763,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
struct ath_regulatory *reg;
/* Bring up device */
- error = ath9k_init_priv(priv, devid, product);
+ error = ath9k_init_priv(priv, devid, product, drv_info);
if (error != 0)
goto err_init;
@@ -829,7 +821,7 @@ err_init:
}
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid, char *product)
+ u16 devid, char *product, u32 drv_info)
{
struct ieee80211_hw *hw;
struct ath9k_htc_priv *priv;
@@ -856,14 +848,11 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
goto err_free;
}
- ret = ath9k_init_htc_services(priv, devid);
+ ret = ath9k_init_htc_services(priv, devid, drv_info);
if (ret)
goto err_init;
- /* The device may have been unplugged earlier. */
- priv->op_flags &= ~OP_UNPLUGGED;
-
- ret = ath9k_init_device(priv, devid, product);
+ ret = ath9k_init_device(priv, devid, product, drv_info);
if (ret)
goto err_init;
@@ -882,7 +871,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
/* Check if the device has been yanked out. */
if (hotunplug)
- htc_handle->drv_priv->op_flags |= OP_UNPLUGGED;
+ htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
ath9k_deinit_device(htc_handle->drv_priv);
ath9k_deinit_wmi(htc_handle->drv_priv);
@@ -891,16 +880,23 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
}
#ifdef CONFIG_PM
+
+void ath9k_htc_suspend(struct htc_target *htc_handle)
+{
+ ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
+}
+
int ath9k_htc_resume(struct htc_target *htc_handle)
{
+ struct ath9k_htc_priv *priv = htc_handle->drv_priv;
int ret;
- ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
+ ret = ath9k_htc_wait_for_target(priv);
if (ret)
return ret;
- ret = ath9k_init_htc_services(htc_handle->drv_priv,
- htc_handle->drv_priv->ah->hw_version.devid);
+ ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid,
+ priv->ah->hw_version.usbdev);
return ret;
}
#endif
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9a3be8da755d..845b4c938d16 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -24,12 +24,12 @@ static struct dentry *ath9k_debugfs_root;
/* Utilities */
/*************/
-static void ath_update_txpow(struct ath9k_htc_priv *priv)
+void ath_update_txpow(struct ath9k_htc_priv *priv)
{
struct ath_hw *ah = priv->ah;
if (priv->curtxpow != priv->txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
+ ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
/* read back in case value is clamped */
priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
}
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
return mode;
}
-static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
- enum ath9k_power_mode mode)
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+ enum ath9k_power_mode mode)
{
bool ret;
@@ -116,6 +116,60 @@ void ath9k_ps_work(struct work_struct *work)
ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
}
+void ath9k_htc_reset(struct ath9k_htc_priv *priv)
+{
+ struct ath_hw *ah = priv->ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_channel *channel = priv->hw->conf.channel;
+ struct ath9k_hw_cal_data *caldata;
+ enum htc_phymode mode;
+ __be16 htc_mode;
+ u8 cmd_rsp;
+ int ret;
+
+ mutex_lock(&priv->mutex);
+ ath9k_htc_ps_wakeup(priv);
+
+ if (priv->op_flags & OP_ASSOCIATED)
+ cancel_delayed_work_sync(&priv->ath9k_ani_work);
+
+ ieee80211_stop_queues(priv->hw);
+ htc_stop(priv->htc);
+ WMI_CMD(WMI_DISABLE_INTR_CMDID);
+ WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
+ WMI_CMD(WMI_STOP_RECV_CMDID);
+
+ caldata = &priv->caldata[channel->hw_value];
+ ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
+ if (ret) {
+ ath_err(common,
+ "Unable to reset device (%u Mhz) reset status %d\n",
+ channel->center_freq, ret);
+ }
+
+ ath_update_txpow(priv);
+
+ WMI_CMD(WMI_START_RECV_CMDID);
+ ath9k_host_rx_init(priv);
+
+ mode = ath9k_htc_get_curmode(priv, ah->curchan);
+ htc_mode = cpu_to_be16(mode);
+ WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
+
+ WMI_CMD(WMI_ENABLE_INTR_CMDID);
+ htc_start(priv->htc);
+
+ if (priv->op_flags & OP_ASSOCIATED) {
+ ath9k_htc_beacon_config(priv, priv->vif);
+ ath_start_ani(priv);
+ }
+
+ ieee80211_wake_queues(priv->hw);
+
+ ath9k_htc_ps_restore(priv);
+ mutex_unlock(&priv->mutex);
+}
+
static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ieee80211_hw *hw,
struct ath9k_channel *hchan)
@@ -123,7 +177,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
- bool fastcc = true;
+ bool fastcc;
struct ieee80211_channel *channel = hw->conf.channel;
struct ath9k_hw_cal_data *caldata;
enum htc_phymode mode;
@@ -134,8 +188,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
if (priv->op_flags & OP_INVALID)
return -EIO;
- if (priv->op_flags & OP_FULL_RESET)
- fastcc = false;
+ fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
ath9k_htc_ps_wakeup(priv);
htc_stop(priv->htc);
@@ -143,18 +196,18 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
WMI_CMD(WMI_STOP_RECV_CMDID);
- ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
- priv->ah->curchan->channel,
- channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
- fastcc);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
+ priv->ah->curchan->channel,
+ channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
+ fastcc);
caldata = &priv->caldata[channel->hw_value];
ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u Mhz) "
- "reset status %d\n", channel->center_freq, ret);
+ ath_err(common,
+ "Unable to reset channel (%u Mhz) reset status %d\n",
+ channel->center_freq, ret);
goto err;
}
@@ -177,23 +230,43 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
goto err;
htc_start(priv->htc);
-
- priv->op_flags &= ~OP_FULL_RESET;
err:
ath9k_htc_ps_restore(priv);
return ret;
}
+static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_target_vif hvif;
+ int ret = 0;
+ u8 cmd_rsp;
+
+ memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
+ memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
+ hvif.index = 0; /* Should do for now */
+ WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+ priv->nvifs--;
+}
+
static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_target_vif hvif;
+ struct ath9k_htc_target_sta tsta;
int ret = 0;
u8 cmd_rsp;
if (priv->nvifs > 0)
return -ENOBUFS;
+ if (priv->nstations >= ATH9K_HTC_MAX_STA)
+ return -ENOBUFS;
+
+ /*
+ * Add an interface.
+ */
+
memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
@@ -206,23 +279,57 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
return ret;
priv->nvifs++;
+
+ /*
+ * Associate a station with the interface for packet injection.
+ */
+
+ memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
+
+ memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
+
+ tsta.is_vif_sta = 1;
+ tsta.sta_index = priv->nstations;
+ tsta.vif_index = hvif.index;
+ tsta.maxampdu = 0xffff;
+
+ WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
+ if (ret) {
+ ath_err(common, "Unable to add station entry for monitor mode\n");
+ goto err_vif;
+ }
+
+ priv->nstations++;
+
return 0;
+
+err_vif:
+ /*
+ * Remove the interface from the target.
+ */
+ __ath9k_htc_remove_monitor_interface(priv);
+ return ret;
}
static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
- struct ath9k_htc_target_vif hvif;
int ret = 0;
- u8 cmd_rsp;
+ u8 cmd_rsp, sta_idx;
- memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
- memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
- hvif.index = 0; /* Should do for now */
- WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
- priv->nvifs--;
+ __ath9k_htc_remove_monitor_interface(priv);
- return ret;
+ sta_idx = 0; /* Only single interface, for now */
+
+ WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
+ if (ret) {
+ ath_err(common, "Unable to remove station entry for monitor mode\n");
+ return ret;
+ }
+
+ priv->nstations--;
+
+ return 0;
}
static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
@@ -263,15 +370,16 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
if (ret) {
if (sta)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to add station entry for: %pM\n", sta->addr);
+ ath_err(common,
+ "Unable to add station entry for: %pM\n",
+ sta->addr);
return ret;
}
if (sta)
- ath_print(common, ATH_DBG_CONFIG,
- "Added a station entry for: %pM (idx: %d)\n",
- sta->addr, tsta.sta_index);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Added a station entry for: %pM (idx: %d)\n",
+ sta->addr, tsta.sta_index);
priv->nstations++;
return 0;
@@ -296,16 +404,16 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
if (ret) {
if (sta)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to remove station entry for: %pM\n",
- sta->addr);
+ ath_err(common,
+ "Unable to remove station entry for: %pM\n",
+ sta->addr);
return ret;
}
if (sta)
- ath_print(common, ATH_DBG_CONFIG,
- "Removed a station entry for: %pM (idx: %d)\n",
- sta->addr, sta_idx);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Removed a station entry for: %pM (idx: %d)\n",
+ sta->addr, sta_idx);
priv->nstations--;
return 0;
@@ -390,8 +498,8 @@ static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize Rate information on target\n");
+ ath_err(common,
+ "Unable to initialize Rate information on target\n");
}
return ret;
@@ -408,9 +516,9 @@ static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
ath9k_htc_setup_rate(priv, sta, &trate);
ret = ath9k_htc_send_rate_cmd(priv, &trate);
if (!ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Updated target sta: %pM, rate caps: 0x%X\n",
- sta->addr, be32_to_cpu(trate.capflags));
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Updated target sta: %pM, rate caps: 0x%X\n",
+ sta->addr, be32_to_cpu(trate.capflags));
}
static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
@@ -435,9 +543,9 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
ret = ath9k_htc_send_rate_cmd(priv, &trate);
if (!ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Updated target sta: %pM, rate caps: 0x%X\n",
- bss_conf->bssid, be32_to_cpu(trate.capflags));
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Updated target sta: %pM, rate caps: 0x%X\n",
+ bss_conf->bssid, be32_to_cpu(trate.capflags));
}
static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
@@ -464,14 +572,14 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
if (ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Unable to %s TX aggregation for (%pM, %d)\n",
- (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unable to %s TX aggregation for (%pM, %d)\n",
+ (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
else
- ath_print(common, ATH_DBG_CONFIG,
- "%s TX aggregation for (%pM, %d)\n",
- (aggr.aggr_enable) ? "Starting" : "Stopping",
- sta->addr, tid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "%s TX aggregation for (%pM, %d)\n",
+ (aggr.aggr_enable) ? "Starting" : "Stopping",
+ sta->addr, tid);
spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
@@ -689,7 +797,7 @@ void ath9k_htc_debug_remove_root(void)
/* ANI */
/*******/
-static void ath_start_ani(struct ath9k_htc_priv *priv)
+void ath_start_ani(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -724,7 +832,7 @@ void ath9k_ani_work(struct work_struct *work)
/* Long calibration runs independently of short calibration. */
if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
longcal = true;
- ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
}
@@ -733,8 +841,8 @@ void ath9k_ani_work(struct work_struct *work)
if ((timestamp - common->ani.shortcal_timer) >=
short_cal_interval) {
shortcal = true;
- ath_print(common, ATH_DBG_ANI,
- "shortcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI,
+ "shortcal @%lu\n", jiffies);
common->ani.shortcal_timer = timestamp;
common->ani.resetcal_timer = timestamp;
}
@@ -788,317 +896,6 @@ set_timer:
msecs_to_jiffies(cal_interval));
}
-/*******/
-/* LED */
-/*******/
-
-static void ath9k_led_blink_work(struct work_struct *work)
-{
- struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
- ath9k_led_blink_work.work);
-
- if (!(priv->op_flags & OP_LED_ASSOCIATED))
- return;
-
- if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
- (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
- else
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
- (priv->op_flags & OP_LED_ON) ? 1 : 0);
-
- ieee80211_queue_delayed_work(priv->hw,
- &priv->ath9k_led_blink_work,
- (priv->op_flags & OP_LED_ON) ?
- msecs_to_jiffies(priv->led_off_duration) :
- msecs_to_jiffies(priv->led_on_duration));
-
- priv->led_on_duration = priv->led_on_cnt ?
- max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
- ATH_LED_ON_DURATION_IDLE;
- priv->led_off_duration = priv->led_off_cnt ?
- max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
- ATH_LED_OFF_DURATION_IDLE;
- priv->led_on_cnt = priv->led_off_cnt = 0;
-
- if (priv->op_flags & OP_LED_ON)
- priv->op_flags &= ~OP_LED_ON;
- else
- priv->op_flags |= OP_LED_ON;
-}
-
-static void ath9k_led_brightness_work(struct work_struct *work)
-{
- struct ath_led *led = container_of(work, struct ath_led,
- brightness_work.work);
- struct ath9k_htc_priv *priv = led->priv;
-
- switch (led->brightness) {
- case LED_OFF:
- if (led->led_type == ATH_LED_ASSOC ||
- led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
- (led->led_type == ATH_LED_RADIO));
- priv->op_flags &= ~OP_LED_ASSOCIATED;
- if (led->led_type == ATH_LED_RADIO)
- priv->op_flags &= ~OP_LED_ON;
- } else {
- priv->led_off_cnt++;
- }
- break;
- case LED_FULL:
- if (led->led_type == ATH_LED_ASSOC) {
- priv->op_flags |= OP_LED_ASSOCIATED;
- ieee80211_queue_delayed_work(priv->hw,
- &priv->ath9k_led_blink_work, 0);
- } else if (led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
- priv->op_flags |= OP_LED_ON;
- } else {
- priv->led_on_cnt++;
- }
- break;
- default:
- break;
- }
-}
-
-static void ath9k_led_brightness(struct led_classdev *led_cdev,
- enum led_brightness brightness)
-{
- struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
- struct ath9k_htc_priv *priv = led->priv;
-
- led->brightness = brightness;
- if (!(priv->op_flags & OP_LED_DEINIT))
- ieee80211_queue_delayed_work(priv->hw,
- &led->brightness_work, 0);
-}
-
-static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
-{
- cancel_delayed_work_sync(&priv->radio_led.brightness_work);
- cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
- cancel_delayed_work_sync(&priv->tx_led.brightness_work);
- cancel_delayed_work_sync(&priv->rx_led.brightness_work);
-}
-
-static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
- char *trigger)
-{
- int ret;
-
- led->priv = priv;
- led->led_cdev.name = led->name;
- led->led_cdev.default_trigger = trigger;
- led->led_cdev.brightness_set = ath9k_led_brightness;
-
- ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
- if (ret)
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
- "Failed to register led:%s", led->name);
- else
- led->registered = 1;
-
- INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
-
- return ret;
-}
-
-static void ath9k_unregister_led(struct ath_led *led)
-{
- if (led->registered) {
- led_classdev_unregister(&led->led_cdev);
- led->registered = 0;
- }
-}
-
-void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
-{
- priv->op_flags |= OP_LED_DEINIT;
- ath9k_unregister_led(&priv->assoc_led);
- priv->op_flags &= ~OP_LED_ASSOCIATED;
- ath9k_unregister_led(&priv->tx_led);
- ath9k_unregister_led(&priv->rx_led);
- ath9k_unregister_led(&priv->radio_led);
-}
-
-void ath9k_init_leds(struct ath9k_htc_priv *priv)
-{
- char *trigger;
- int ret;
-
- if (AR_SREV_9287(priv->ah))
- priv->ah->led_pin = ATH_LED_PIN_9287;
- else if (AR_SREV_9271(priv->ah))
- priv->ah->led_pin = ATH_LED_PIN_9271;
- else if (AR_DEVID_7010(priv->ah))
- priv->ah->led_pin = ATH_LED_PIN_7010;
- else
- priv->ah->led_pin = ATH_LED_PIN_DEF;
-
- /* Configure gpio 1 for output */
- ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- /* LED off, active low */
- ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
-
- INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
-
- trigger = ieee80211_get_radio_led_name(priv->hw);
- snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
- "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->radio_led, trigger);
- priv->radio_led.led_type = ATH_LED_RADIO;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_assoc_led_name(priv->hw);
- snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
- "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
- priv->assoc_led.led_type = ATH_LED_ASSOC;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_tx_led_name(priv->hw);
- snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
- "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->tx_led, trigger);
- priv->tx_led.led_type = ATH_LED_TX;
- if (ret)
- goto fail;
-
- trigger = ieee80211_get_rx_led_name(priv->hw);
- snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
- "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
- ret = ath9k_register_led(priv, &priv->rx_led, trigger);
- priv->rx_led.led_type = ATH_LED_RX;
- if (ret)
- goto fail;
-
- priv->op_flags &= ~OP_LED_DEINIT;
-
- return;
-
-fail:
- cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
- ath9k_deinit_leds(priv);
-}
-
-/*******************/
-/* Rfkill */
-/*******************/
-
-static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
-{
- return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
- priv->ah->rfkill_polarity;
-}
-
-static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
-{
- struct ath9k_htc_priv *priv = hw->priv;
- bool blocked = !!ath_is_rfkill_set(priv);
-
- wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
-}
-
-void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
-{
- if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- wiphy_rfkill_start_polling(priv->hw->wiphy);
-}
-
-static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
-{
- struct ath9k_htc_priv *priv = hw->priv;
- struct ath_hw *ah = priv->ah;
- struct ath_common *common = ath9k_hw_common(ah);
- int ret;
- u8 cmd_rsp;
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
-
- /* Reset the HW */
- ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, ah->curchan->channel);
- }
-
- ath_update_txpow(priv);
-
- /* Start RX */
- WMI_CMD(WMI_START_RECV_CMDID);
- ath9k_host_rx_init(priv);
-
- /* Start TX */
- htc_start(priv->htc);
- spin_lock_bh(&priv->tx_lock);
- priv->tx_queues_stop = false;
- spin_unlock_bh(&priv->tx_lock);
- ieee80211_wake_queues(hw);
-
- WMI_CMD(WMI_ENABLE_INTR_CMDID);
-
- /* Enable LED */
- ath9k_hw_cfg_output(ah, ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-}
-
-static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
-{
- struct ath9k_htc_priv *priv = hw->priv;
- struct ath_hw *ah = priv->ah;
- struct ath_common *common = ath9k_hw_common(ah);
- int ret;
- u8 cmd_rsp;
-
- ath9k_htc_ps_wakeup(priv);
-
- /* Disable LED */
- ath9k_hw_set_gpio(ah, ah->led_pin, 1);
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
-
- WMI_CMD(WMI_DISABLE_INTR_CMDID);
-
- /* Stop TX */
- ieee80211_stop_queues(hw);
- htc_stop(priv->htc);
- WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
- skb_queue_purge(&priv->tx_queue);
-
- /* Stop RX */
- WMI_CMD(WMI_STOP_RECV_CMDID);
-
- /*
- * The MIB counters have to be disabled here,
- * since the target doesn't do it.
- */
- ath9k_hw_disable_mib_counters(ah);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
-
- /* Reset the HW */
- ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, ah->curchan->channel);
- }
-
- /* Disable the PHY */
- ath9k_hw_phy_disable(ah);
-
- ath9k_htc_ps_restore(priv);
- ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
-}
-
/**********************/
/* mac80211 Callbacks */
/**********************/
@@ -1124,15 +921,15 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
ret = ath9k_htc_tx_start(priv, skb);
if (ret != 0) {
if (ret == -ENOMEM) {
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Stopping TX queues\n");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Stopping TX queues\n");
ieee80211_stop_queues(hw);
spin_lock_bh(&priv->tx_lock);
priv->tx_queues_stop = true;
spin_unlock_bh(&priv->tx_lock);
} else {
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Tx failed");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Tx failed\n");
}
goto fail_tx;
}
@@ -1158,9 +955,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
- ath_print(common, ATH_DBG_CONFIG,
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Starting driver with initial channel: %d MHz\n",
+ curchan->center_freq);
/* Ensure that HW is awake before flushing RX */
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
@@ -1169,15 +966,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
/* setup initial channel */
init_channel = ath9k_cmn_get_curchannel(hw, ah);
- /* Reset SERDES registers */
- ath9k_hw_configpcipowersave(ah, 0, 0);
-
ath9k_hw_htc_resetinit(ah);
ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, curchan->center_freq);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, curchan->center_freq);
mutex_unlock(&priv->mutex);
return ret;
}
@@ -1220,19 +1014,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
int ret = 0;
u8 cmd_rsp;
+ /* Cancel all the running timers/work .. */
+ cancel_work_sync(&priv->fatal_work);
+ cancel_work_sync(&priv->ps_work);
+ cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+ ath9k_led_stop_brightness(priv);
+
mutex_lock(&priv->mutex);
if (priv->op_flags & OP_INVALID) {
- ath_print(common, ATH_DBG_ANY, "Device not present\n");
+ ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
mutex_unlock(&priv->mutex);
return;
}
- /* Cancel all the running timers/work .. */
- cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
- ath9k_led_stop_brightness(priv);
-
ath9k_htc_ps_wakeup(priv);
htc_stop(priv->htc);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -1243,11 +1038,10 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Remove monitor interface here */
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
if (ath9k_htc_remove_monitor_interface(priv))
- ath_print(common, ATH_DBG_FATAL,
- "Unable to remove monitor interface\n");
+ ath_err(common, "Unable to remove monitor interface\n");
else
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor interface removed\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor interface removed\n");
}
if (ah->btcoex_hw.enabled) {
@@ -1258,13 +1052,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
ath9k_hw_phy_disable(ah);
ath9k_hw_disable(ah);
- ath9k_hw_configpcipowersave(ah, 1, 1);
ath9k_htc_ps_restore(priv);
ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
priv->op_flags |= OP_INVALID;
- ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
mutex_unlock(&priv->mutex);
}
@@ -1298,14 +1091,14 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
hvif.opmode = cpu_to_be32(HTC_M_IBSS);
break;
default:
- ath_print(common, ATH_DBG_FATAL,
+ ath_err(common,
"Interface type %d not yet supported\n", vif->type);
ret = -EOPNOTSUPP;
goto out;
}
- ath_print(common, ATH_DBG_CONFIG,
- "Attach a VIF of type: %d\n", vif->type);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Attach a VIF of type: %d\n", vif->type);
priv->ah->opmode = vif->type;
@@ -1328,8 +1121,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
ret = ath9k_htc_update_cap_target(priv);
if (ret)
- ath_print(common, ATH_DBG_CONFIG, "Failed to update"
- " capability in target \n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Failed to update capability in target\n");
priv->vif = vif;
out:
@@ -1349,7 +1142,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
int ret = 0;
u8 cmd_rsp;
- ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv);
@@ -1386,8 +1179,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
mutex_unlock(&priv->htc_pm_lock);
if (enable_radio) {
- ath_print(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "not-idle: enabling radio\n");
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
ath9k_htc_radio_enable(hw);
}
@@ -1397,19 +1190,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
- ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
- ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
+ ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
+ hw->conf.channel,
+ hw->conf.channel_type);
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to set channel\n");
+ ath_err(common, "Unable to set channel\n");
mutex_unlock(&priv->mutex);
return -EINVAL;
}
}
+
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (conf->flags & IEEE80211_CONF_PS) {
ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
@@ -1421,14 +1216,18 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
}
}
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ priv->txpowlimit = 2 * conf->power_level;
+ ath_update_txpow(priv);
+ }
+
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
if (conf->flags & IEEE80211_CONF_MONITOR) {
if (ath9k_htc_add_monitor_interface(priv))
- ath_print(common, ATH_DBG_FATAL,
- "Failed to set monitor mode\n");
+ ath_err(common, "Failed to set monitor mode\n");
else
- ath_print(common, ATH_DBG_CONFIG,
- "HW opmode set to Monitor mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "HW opmode set to Monitor mode\n");
}
}
@@ -1440,8 +1239,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
}
mutex_unlock(&priv->htc_pm_lock);
- ath_print(common, ATH_DBG_CONFIG,
- "idle: disabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "idle: disabling radio\n");
ath9k_htc_radio_disable(hw);
}
@@ -1478,8 +1277,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
rfilt = ath9k_htc_calcrxfilter(priv);
ath9k_hw_setrxfilter(priv->ah, rfilt);
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
- "Set HW RX filter: 0x%x\n", rfilt);
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
+ "Set HW RX filter: 0x%x\n", rfilt);
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
@@ -1542,15 +1341,14 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
qnum = get_hw_qnum(queue, priv->hwq_map);
- ath_print(common, ATH_DBG_CONFIG,
- "Configure tx [queue/hwq] [%d/%d], "
- "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
- queue, qnum, params->aifs, params->cw_min,
- params->cw_max, params->txop);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, qnum, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
ret = ath_htc_txq_update(priv, qnum, &qi);
if (ret) {
- ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
+ ath_err(common, "TXQ Update failed\n");
goto out;
}
@@ -1578,7 +1376,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
return -ENOSPC;
mutex_lock(&priv->mutex);
- ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
ath9k_htc_ps_wakeup(priv);
switch (cmd) {
@@ -1624,7 +1422,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
common->curaid = bss_conf->assoc ?
bss_conf->aid : 0;
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
bss_conf->assoc);
if (bss_conf->assoc) {
@@ -1641,9 +1439,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
ath9k_hw_write_associd(ah);
- ath_print(common, ATH_DBG_CONFIG,
- "BSSID: %pM aid: 0x%x\n",
- common->curbssid, common->curaid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "BSSID: %pM aid: 0x%x\n",
+ common->curbssid, common->curaid);
}
if ((changed & BSS_CHANGED_BEACON_INT) ||
@@ -1661,8 +1459,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
- bss_conf->use_short_preamble);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
priv->op_flags |= OP_PREAMBLE_SHORT;
else
@@ -1670,8 +1468,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
- bss_conf->use_cts_prot);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+ bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot &&
hw->conf.channel->band != IEEE80211_BAND_5GHZ)
priv->op_flags |= OP_PROTECT_ENABLE;
@@ -1762,8 +1560,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
spin_unlock_bh(&priv->tx_lock);
break;
default:
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
- "Unknown AMPDU action\n");
+ ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
}
return ret;
@@ -1792,7 +1589,6 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
spin_lock_bh(&priv->beacon_lock);
priv->op_flags &= ~OP_SCANNING;
spin_unlock_bh(&priv->beacon_lock);
- priv->op_flags |= OP_FULL_RESET;
if (priv->op_flags & OP_ASSOCIATED) {
ath9k_htc_beacon_config(priv, priv->vif);
ath_start_ani(priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 29d80ca78393..33f36029fa4f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -20,8 +20,15 @@
/* TX */
/******/
+static const int subtype_txq_to_hwq[] = {
+ [WME_AC_BE] = ATH_TXQ_AC_BE,
+ [WME_AC_BK] = ATH_TXQ_AC_BK,
+ [WME_AC_VI] = ATH_TXQ_AC_VI,
+ [WME_AC_VO] = ATH_TXQ_AC_VO,
+};
+
#define ATH9K_HTC_INIT_TXQ(subtype) do { \
- qi.tqi_subtype = subtype; \
+ qi.tqi_subtype = subtype_txq_to_hwq[subtype]; \
qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \
qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \
qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \
@@ -62,8 +69,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
qi.tqi_readyTime = qinfo->tqi_readyTime;
if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to update hardware queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(ah),
+ "Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
ath9k_hw_resettxqueue(ah, qnum);
@@ -244,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data)
ista = (struct ath9k_htc_sta *)sta->drv_priv;
if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
- ieee80211_start_tx_ba_session(sta, tid);
+ ieee80211_start_tx_ba_session(sta, tid, 0);
spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = AGGR_PROGRESS;
spin_unlock_bh(&priv->tx_lock);
@@ -263,8 +270,8 @@ void ath9k_tx_tasklet(unsigned long data)
if (priv->tx_queues_stop) {
priv->tx_queues_stop = false;
spin_unlock_bh(&priv->tx_lock);
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Waking up TX queues\n");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Waking up TX queues\n");
ieee80211_wake_queues(priv->hw);
return;
}
@@ -289,8 +296,7 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
(ep_id == priv->data_vo_ep)) {
skb_pull(skb, sizeof(struct tx_frame_hdr));
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Unsupported TX EPID: %d\n", ep_id);
+ ath_err(common, "Unsupported TX EPID: %d\n", ep_id);
dev_kfree_skb_any(skb);
return;
}
@@ -330,9 +336,8 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)
return false;
if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
- ath_print(common, ATH_DBG_FATAL,
- "qnum %u out of range, max %u!\n",
- qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
+ ath_err(common, "qnum %u out of range, max %zu!\n",
+ qnum, ARRAY_SIZE(priv->hwq_map));
ath9k_hw_releasetxqueue(ah, qnum);
return false;
}
@@ -483,8 +488,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
__le16 fc;
if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
- ath_print(common, ATH_DBG_FATAL,
- "Corrupted RX frame, dropping\n");
+ ath_err(common, "Corrupted RX frame, dropping\n");
goto rx_next;
}
@@ -492,10 +496,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
if (be16_to_cpu(rxstatus->rs_datalen) -
(skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Corrupted RX data len, dropping "
- "(dlen: %d, skblen: %d)\n",
- rxstatus->rs_datalen, skb->len);
+ ath_err(common,
+ "Corrupted RX data len, dropping (dlen: %d, skblen: %d)\n",
+ rxstatus->rs_datalen, skb->len);
goto rx_next;
}
@@ -678,8 +681,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
spin_unlock(&priv->rx.rxbuflock);
if (rxbuf == NULL) {
- ath_print(common, ATH_DBG_ANY,
- "No free RX buffer\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "No free RX buffer\n");
goto err;
}
@@ -721,8 +724,7 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv)
for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
if (rxbuf == NULL) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to allocate RX buffers\n");
+ ath_err(common, "Unable to allocate RX buffers\n");
goto err;
}
list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 861ec9269309..c41ab8c30161 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -462,9 +462,10 @@ void ath9k_htc_hw_free(struct htc_target *htc)
}
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid, char *product)
+ struct device *dev, u16 devid,
+ char *product, u32 drv_info)
{
- if (ath9k_htc_probe_device(target, dev, devid, product)) {
+ if (ath9k_htc_probe_device(target, dev, devid, product, drv_info)) {
printk(KERN_ERR "Failed to initialize the device\n");
return -ENODEV;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index 07b6509d5896..ecd018798c47 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -77,20 +77,6 @@ struct htc_config_pipe_msg {
u8 credits;
} __packed;
-struct htc_packet {
- void *pktcontext;
- u8 *buf;
- u8 *buf_payload;
- u32 buflen;
- u32 payload_len;
-
- int endpoint;
- int status;
-
- void *context;
- u32 reserved;
-};
-
struct htc_ep_callbacks {
void *priv;
void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
@@ -123,11 +109,6 @@ struct htc_endpoint {
#define HTC_CONTROL_BUFFER_SIZE \
(HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
-struct htc_control_buf {
- struct htc_packet htc_pkt;
- u8 buf[HTC_CONTROL_BUFFER_SIZE];
-};
-
#define HTC_OP_START_WAIT BIT(0)
#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
@@ -239,7 +220,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct device *dev);
void ath9k_htc_hw_free(struct htc_target *htc);
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid, char *product);
+ struct device *dev, u16 devid, char *product,
+ u32 drv_info);
void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 0a4ad348b699..c8f254fe0f0b 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -223,11 +223,6 @@ static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
return ath9k_hw_private_ops(ah)->rfbus_done(ah);
}
-static inline void ath9k_enable_rfkill(struct ath_hw *ah)
-{
- return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
-}
-
static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
{
if (!ath9k_hw_private_ops(ah)->restore_chainmask)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6ebc68bca91f..fde978665e07 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -54,13 +54,6 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
ath9k_hw_private_ops(ah)->init_mode_regs(ah);
}
-static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
-{
- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-
- return priv_ops->macversion_supported(ah->hw_version.macVersion);
-}
-
static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
struct ath9k_channel *chan)
{
@@ -129,9 +122,9 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
udelay(AH_TIME_QUANTUM);
}
- ath_print(ath9k_hw_common(ah), ATH_DBG_ANY,
- "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
- timeout, reg, REG_READ(ah, reg), mask, val);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_ANY,
+ "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+ timeout, reg, REG_READ(ah, reg), mask, val);
return false;
}
@@ -211,8 +204,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
}
break;
default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unknown phy %u (rate ix %u)\n", phy, rateix);
+ ath_err(ath9k_hw_common(ah),
+ "Unknown phy %u (rate ix %u)\n", phy, rateix);
txTime = 0;
break;
}
@@ -284,11 +277,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
static void ath9k_hw_disablepcie(struct ath_hw *ah)
{
- if (AR_SREV_9100(ah))
+ if (!AR_SREV_5416(ah))
return;
- ENABLE_REGWRITE_BUFFER(ah);
-
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
@@ -300,8 +291,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
- REGWRITE_BUFFER_FLUSH(ah);
}
/* This should work for all families including legacy */
@@ -310,10 +299,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
u32 regAddr[2] = { AR_STA_ID0 };
u32 regHold[2];
- u32 patternData[4] = { 0x55555555,
- 0xaaaaaaaa,
- 0x66666666,
- 0x99999999 };
+ static const u32 patternData[4] = {
+ 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999
+ };
int i, j, loop_max;
if (!AR_SREV_9300_20_OR_LATER(ah)) {
@@ -332,11 +320,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (rdData != wrData) {
- ath_print(common, ATH_DBG_FATAL,
- "address test failed "
- "addr: 0x%08x - wr:0x%08x != "
- "rd:0x%08x\n",
- addr, wrData, rdData);
+ ath_err(common,
+ "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ addr, wrData, rdData);
return false;
}
}
@@ -345,11 +331,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (wrData != rdData) {
- ath_print(common, ATH_DBG_FATAL,
- "address test failed "
- "addr: 0x%08x - wr:0x%08x != "
- "rd:0x%08x\n",
- addr, wrData, rdData);
+ ath_err(common,
+ "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ addr, wrData, rdData);
return false;
}
}
@@ -419,17 +403,12 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->hw_version.magic = AR5416_MAGIC;
ah->hw_version.subvendorid = 0;
- ah->ah_flags = 0;
- if (!AR_SREV_9100(ah))
- ah->ah_flags = AH_USE_EEPROM;
-
ah->atim_window = 0;
ah->sta_id1_defaults =
AR_STA_ID1_CRPT_MIC_ENABLE |
AR_STA_ID1_MCAST_KSRCH;
- ah->beacon_interval = 100;
ah->enable_32kHz_clock = DONT_USE_32KHZ;
- ah->slottime = (u32) -1;
+ ah->slottime = 20;
ah->globaltxtimeout = (u32) -1;
ah->power_mode = ATH9K_PM_UNDEFINED;
}
@@ -440,7 +419,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
u32 sum;
int i;
u16 eeval;
- u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
+ static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
sum = 0;
for (i = 0; i < 3; i++) {
@@ -474,16 +453,15 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
if (ecode != 0)
return ecode;
- ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG,
- "Eeprom VER: %d, REV: %d\n",
- ah->eep_ops->get_eeprom_ver(ah),
- ah->eep_ops->get_eeprom_rev(ah));
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CONFIG,
+ "Eeprom VER: %d, REV: %d\n",
+ ah->eep_ops->get_eeprom_ver(ah),
+ ah->eep_ops->get_eeprom_rev(ah));
ecode = ath9k_hw_rf_alloc_ext_banks(ah);
if (ecode) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed allocating banks for "
- "external radio\n");
+ ath_err(ath9k_hw_common(ah),
+ "Failed allocating banks for external radio\n");
ath9k_hw_rf_free_ext_banks(ah);
return ecode;
}
@@ -514,8 +492,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- ath_print(common, ATH_DBG_FATAL,
- "Couldn't reset chip\n");
+ ath_err(common, "Couldn't reset chip\n");
return -EIO;
}
@@ -525,7 +502,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ath9k_hw_attach_ops(ah);
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+ ath_err(common, "Couldn't wakeup chip\n");
return -EIO;
}
@@ -541,7 +518,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
}
}
- ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
+ ath_dbg(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
ah->config.serialize_regmode);
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
@@ -549,11 +526,22 @@ static int __ath9k_hw_init(struct ath_hw *ah)
else
ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
- if (!ath9k_hw_macversion_supported(ah)) {
- ath_print(common, ATH_DBG_FATAL,
- "Mac Chip Rev 0x%02x.%x is not supported by "
- "this driver\n", ah->hw_version.macVersion,
- ah->hw_version.macRev);
+ switch (ah->hw_version.macVersion) {
+ case AR_SREV_VERSION_5416_PCI:
+ case AR_SREV_VERSION_5416_PCIE:
+ case AR_SREV_VERSION_9160:
+ case AR_SREV_VERSION_9100:
+ case AR_SREV_VERSION_9280:
+ case AR_SREV_VERSION_9285:
+ case AR_SREV_VERSION_9287:
+ case AR_SREV_VERSION_9271:
+ case AR_SREV_VERSION_9300:
+ case AR_SREV_VERSION_9485:
+ break;
+ default:
+ ath_err(common,
+ "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
+ ah->hw_version.macVersion, ah->hw_version.macRev);
return -EOPNOTSUPP;
}
@@ -599,8 +587,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
r = ath9k_hw_init_macaddr(ah);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to initialize MAC address\n");
+ ath_err(common, "Failed to initialize MAC address\n");
return r;
}
@@ -634,21 +621,21 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR9287_DEVID_PCIE:
case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE:
+ case AR9300_DEVID_AR9485_PCIE:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
break;
- ath_print(common, ATH_DBG_FATAL,
- "Hardware device ID 0x%04x not supported\n",
- ah->hw_version.devid);
+ ath_err(common, "Hardware device ID 0x%04x not supported\n",
+ ah->hw_version.devid);
return -EOPNOTSUPP;
}
ret = __ath9k_hw_init(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize hardware; "
- "initialization status: %d\n", ret);
+ ath_err(common,
+ "Unable to initialize hardware; initialization status: %d\n",
+ ret);
return ret;
}
@@ -680,7 +667,12 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- u32 pll = ath9k_hw_compute_pll_control(ah, chan);
+ u32 pll;
+
+ if (AR_SREV_9485(ah))
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
+
+ pll = ath9k_hw_compute_pll_control(ah, chan);
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
@@ -772,8 +764,8 @@ static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
{
if (tu > 0xFFFF) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "bad global tx timeout %u\n", tu);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "bad global tx timeout %u\n", tu);
ah->globaltxtimeout = (u32) -1;
return false;
} else {
@@ -790,8 +782,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
int slottime;
int sifstime;
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
- ah->misc_mode);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+ ah->misc_mode);
if (ah->misc_mode != 0)
REG_WRITE(ah, AR_PCU_MISC,
@@ -816,7 +808,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
acktimeout += 64 - sifstime - ah->slottime;
- ath9k_hw_setslottime(ah, slottime);
+ ath9k_hw_setslottime(ah, ah->slottime);
ath9k_hw_set_ack_timeout(ah, acktimeout);
ath9k_hw_set_cts_timeout(ah, acktimeout);
if (ah->globaltxtimeout != (u32) -1)
@@ -1034,8 +1026,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, 0);
if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "RTC stuck in MAC reset\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "RTC stuck in MAC reset\n");
return false;
}
@@ -1081,8 +1073,8 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
AR_RTC_STATUS_M,
AR_RTC_STATUS_ON,
AH_WAIT_TIMEOUT)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "RTC not waking up\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "RTC not waking up\n");
return false;
}
@@ -1142,16 +1134,14 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
if (ath9k_hw_numtxpending(ah, qnum)) {
- ath_print(common, ATH_DBG_QUEUE,
- "Transmit frames pending on "
- "queue %d\n", qnum);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Transmit frames pending on queue %d\n", qnum);
return false;
}
}
if (!ath9k_hw_rfbus_req(ah)) {
- ath_print(common, ATH_DBG_FATAL,
- "Could not kill baseband RX\n");
+ ath_err(common, "Could not kill baseband RX\n");
return false;
}
@@ -1159,8 +1149,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
r = ath9k_hw_rf_set_freq(ah, chan);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to set channel\n");
+ ath_err(common, "Failed to set channel\n");
return false;
}
ath9k_hw_set_clockrate(ah);
@@ -1170,7 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
ath9k_hw_rfbus_done(ah);
@@ -1227,7 +1216,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ah->chip_fullsleep) {
ath9k_hw_abortpcurecv(ah);
if (!ath9k_hw_stopdmarecv(ah)) {
- ath_print(common, ATH_DBG_XMIT,
+ ath_dbg(common, ATH_DBG_XMIT,
"Failed to stop receive dma\n");
bChannelChange = false;
}
@@ -1283,6 +1272,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_mark_phy_inactive(ah);
+ ah->paprd_table_write_done = false;
+
/* Only required on the first reset */
if (AR_SREV_9271(ah) && ah->htc_reset_init) {
REG_WRITE(ah,
@@ -1292,7 +1283,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
}
if (!ath9k_hw_chip_reset(ah, chan)) {
- ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n");
+ ath_err(common, "Chip reset failed\n");
return -EINVAL;
}
@@ -1394,7 +1385,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_qos(ah);
if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- ath9k_enable_rfkill(ah);
+ ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
ath9k_hw_init_global_settings(ah);
@@ -1439,13 +1430,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
u32 mask;
mask = REG_READ(ah, AR_CFG);
if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
- ath_print(common, ATH_DBG_RESET,
+ ath_dbg(common, ATH_DBG_RESET,
"CFG Byte Swap Set 0x%x\n", mask);
} else {
mask =
INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
REG_WRITE(ah, AR_CFG, mask);
- ath_print(common, ATH_DBG_RESET,
+ ath_dbg(common, ATH_DBG_RESET,
"Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
}
} else {
@@ -1573,9 +1564,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
AR_RTC_FORCE_WAKE_EN);
}
if (i == 0) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed to wakeup in %uus\n",
- POWER_UP_TIME / 20);
+ ath_err(ath9k_hw_common(ah),
+ "Failed to wakeup in %uus\n",
+ POWER_UP_TIME / 20);
return false;
}
}
@@ -1599,8 +1590,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
if (ah->power_mode == mode)
return status;
- ath_print(common, ATH_DBG_RESET, "%s -> %s\n",
- modes[ah->power_mode], modes[mode]);
+ ath_dbg(common, ATH_DBG_RESET, "%s -> %s\n",
+ modes[ah->power_mode], modes[mode]);
switch (mode) {
case ATH9K_PM_AWAKE:
@@ -1614,12 +1605,20 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
ath9k_set_power_network_sleep(ah, setChip);
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Unknown power mode %u\n", mode);
+ ath_err(common, "Unknown power mode %u\n", mode);
return false;
}
ah->power_mode = mode;
+ /*
+ * XXX: If this warning never comes up after a while then
+ * simply keep the ATH_DBG_WARN_ON_ONCE() but make
+ * ath9k_hw_setpower() return type void.
+ */
+
+ if (!(ah->ah_flags & AH_UNPLUGGED))
+ ATH_DBG_WARN_ON_ONCE(!status);
+
return status;
}
EXPORT_SYMBOL(ath9k_hw_setpower);
@@ -1632,17 +1631,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
{
int flags = 0;
- ah->beacon_interval = beacon_period;
-
ENABLE_REGWRITE_BUFFER(ah);
switch (ah->opmode) {
- case NL80211_IFTYPE_STATION:
- REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
- REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
- REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
- flags |= AR_TBTT_TIMER_EN;
- break;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
REG_SET_BIT(ah, AR_TXCFG,
@@ -1666,17 +1657,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
break;
default:
- if (ah->is_monitoring) {
- REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
- TU_TO_USEC(next_beacon));
- REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
- REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
- flags |= AR_TBTT_TIMER_EN;
- break;
- }
- ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
- "%s: unsupported opmode: %d\n",
- __func__, ah->opmode);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON,
+ "%s: unsupported opmode: %d\n",
+ __func__, ah->opmode);
return;
break;
}
@@ -1732,10 +1715,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
else
nextTbtt = bs->bs_nexttbtt;
- ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
- ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
- ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
- ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
+ ath_dbg(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
+ ath_dbg(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
+ ath_dbg(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
+ ath_dbg(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
ENABLE_REGWRITE_BUFFER(ah);
@@ -1781,7 +1764,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval;
- u8 ant_div_ctl1;
+ u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
regulatory->current_rd = eeval;
@@ -1800,14 +1783,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
regulatory->current_rd += 5;
else if (regulatory->current_rd == 0x41)
regulatory->current_rd = 0x43;
- ath_print(common, ATH_DBG_REGULATORY,
- "regdomain mapped to 0x%x\n", regulatory->current_rd);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "regdomain mapped to 0x%x\n", regulatory->current_rd);
}
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "no band has been marked as supported in EEPROM.\n");
+ ath_err(common,
+ "no band has been marked as supported in EEPROM\n");
return -EINVAL;
}
@@ -1833,6 +1816,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+ /* enable key search for every frame in an aggregate */
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
+
pCap->low_2ghz_chan = 2312;
pCap->high_2ghz_chan = 2732;
@@ -1921,13 +1908,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
AR_SREV_5416(ah))
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
- pCap->num_antcfg_5ghz =
- ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
- pCap->num_antcfg_2ghz =
- ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
-
- if (AR_SREV_9280_20_OR_LATER(ah) &&
- ath9k_hw_btcoex_supported(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
@@ -1942,8 +1923,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
if (AR_SREV_9300_20_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC |
- ATH9K_HW_CAP_FASTCLOCK;
+ pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
+ if (!AR_SREV_9485(ah))
+ pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
+
pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
pCap->rx_status_len = sizeof(struct ar9003_rxs);
@@ -1963,6 +1946,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if (AR_SREV_9300_20_OR_LATER(ah))
pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
+
if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
@@ -1973,6 +1959,29 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
}
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
+ pCap->hw_caps |= ATH9K_HW_CAP_APM;
+ }
+
+
+
+ if (AR_SREV_9485_10(ah)) {
+ pCap->pcie_lcr_extsync_en = true;
+ pCap->pcie_lcr_offset = 0x80;
+ }
+
+ tx_chainmask = pCap->tx_chainmask;
+ rx_chainmask = pCap->rx_chainmask;
+ while (tx_chainmask || rx_chainmask) {
+ if (tx_chainmask & BIT(0))
+ pCap->max_txchains++;
+ if (rx_chainmask & BIT(0))
+ pCap->max_rxchains++;
+
+ tx_chainmask >>= 1;
+ rx_chainmask >>= 1;
+ }
return 0;
}
@@ -2044,7 +2053,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
val = REG_READ(ah, AR7010_GPIO_IN);
return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
} else if (AR_SREV_9300_20_OR_LATER(ah))
- return MS_REG_READ(AR9300, gpio) != 0;
+ return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+ AR_GPIO_BIT(gpio)) != 0;
else if (AR_SREV_9271(ah))
return MS_REG_READ(AR9271, gpio) != 0;
else if (AR_SREV_9287_11_OR_LATER(ah))
@@ -2176,7 +2186,7 @@ bool ath9k_hw_disable(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable);
-void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath9k_channel *chan = ah->curchan;
@@ -2189,7 +2199,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), test);
}
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
@@ -2249,8 +2259,8 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah)
{
if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
AH_TSF_WRITE_TIMEOUT))
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
}
@@ -2323,11 +2333,10 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
return timer_table->gen_timer_index[b];
}
-u32 ath9k_hw_gettsf32(struct ath_hw *ah)
+static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
{
return REG_READ(ah, AR_TSF_L32);
}
-EXPORT_SYMBOL(ath9k_hw_gettsf32);
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
void (*trigger)(void *),
@@ -2341,9 +2350,9 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
if (timer == NULL) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed to allocate memory"
- "for hw timer[%d]\n", timer_index);
+ ath_err(ath9k_hw_common(ah),
+ "Failed to allocate memory for hw timer[%d]\n",
+ timer_index);
return NULL;
}
@@ -2372,9 +2381,9 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
tsf = ath9k_hw_gettsf32(ah);
- ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
- "curent tsf %x period %x"
- "timer_next %x\n", tsf, timer_period, timer_next);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
+ "current tsf %x period %x timer_next %x\n",
+ tsf, timer_period, timer_next);
/*
* Pull timer_next forward if the current TSF already passed it
@@ -2454,8 +2463,8 @@ void ath_gen_timer_isr(struct ath_hw *ah)
index = rightmost_index(timer_table, &thresh_mask);
timer = timer_table->timers[index];
BUG_ON(!timer);
- ath_print(common, ATH_DBG_HWTIMER,
- "TSF overflow for Gen timer %d\n", index);
+ ath_dbg(common, ATH_DBG_HWTIMER,
+ "TSF overflow for Gen timer %d\n", index);
timer->overflow(timer->arg);
}
@@ -2463,8 +2472,8 @@ void ath_gen_timer_isr(struct ath_hw *ah)
index = rightmost_index(timer_table, &trigger_mask);
timer = timer_table->timers[index];
BUG_ON(!timer);
- ath_print(common, ATH_DBG_HWTIMER,
- "Gen timer[%d] trigger\n", index);
+ ath_dbg(common, ATH_DBG_HWTIMER,
+ "Gen timer[%d] trigger\n", index);
timer->trigger(timer->arg);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d47d1b4b6002..5a3dfec45e96 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -30,7 +30,6 @@
#include "btcoex.h"
#include "../regd.h"
-#include "../debug.h"
#define ATHEROS_VENDOR_ID 0x168c
@@ -44,6 +43,7 @@
#define AR9287_DEVID_PCI 0x002d
#define AR9287_DEVID_PCIE 0x002e
#define AR9300_DEVID_PCIE 0x0030
+#define AR9300_DEVID_AR9485_PCIE 0x0032
#define AR5416_AR9100_DEVID 0x000b
@@ -157,6 +157,13 @@
#define PAPRD_GAIN_TABLE_ENTRIES 32
#define PAPRD_TABLE_SZ 24
+enum ath_hw_txq_subtype {
+ ATH_TXQ_AC_BE = 0,
+ ATH_TXQ_AC_BK = 1,
+ ATH_TXQ_AC_VI = 2,
+ ATH_TXQ_AC_VO = 3,
+};
+
enum ath_ini_subsys {
ATH_INI_PRE = 0,
ATH_INI_CORE,
@@ -180,6 +187,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
ATH9K_HW_CAP_2GHZ = BIT(13),
ATH9K_HW_CAP_5GHZ = BIT(14),
+ ATH9K_HW_CAP_APM = BIT(15),
};
struct ath9k_hw_capabilities {
@@ -191,16 +199,18 @@ struct ath9k_hw_capabilities {
u16 rts_aggr_limit;
u8 tx_chainmask;
u8 rx_chainmask;
+ u8 max_txchains;
+ u8 max_rxchains;
u16 tx_triglevel_max;
u16 reg_cap;
u8 num_gpio_pins;
- u8 num_antcfg_2ghz;
- u8 num_antcfg_5ghz;
u8 rx_hp_qdepth;
u8 rx_lp_qdepth;
u8 rx_status_len;
u8 tx_desc_len;
u8 txs_len;
+ u16 pcie_lcr_offset;
+ bool pcie_lcr_extsync_en;
};
struct ath9k_ops_config {
@@ -226,7 +236,6 @@ struct ath9k_ops_config {
#define SPUR_DISABLE 0
#define SPUR_ENABLE_IOCTL 1
#define SPUR_ENABLE_EEPROM 2
-#define AR_EEPROM_MODAL_SPURS 5
#define AR_SPUR_5413_1 1640
#define AR_SPUR_5413_2 1200
#define AR_NO_SPUR 0x8000
@@ -434,6 +443,7 @@ struct ath9k_hw_version {
u16 analog5GhzRev;
u16 analog2GhzRev;
u16 subsysid;
+ enum ath_usb_dev usbdev;
};
/* Generic TSF timer definitions */
@@ -478,6 +488,40 @@ struct ath_hw_antcomb_conf {
};
/**
+ * struct ath_hw_radar_conf - radar detection initialization parameters
+ *
+ * @pulse_inband: threshold for checking the ratio of in-band power
+ * to total power for short radar pulses (half dB steps)
+ * @pulse_inband_step: threshold for checking an in-band power to total
+ * power ratio increase for short radar pulses (half dB steps)
+ * @pulse_height: threshold for detecting the beginning of a short
+ * radar pulse (dB step)
+ * @pulse_rssi: threshold for detecting if a short radar pulse is
+ * gone (dB step)
+ * @pulse_maxlen: maximum pulse length (0.8 us steps)
+ *
+ * @radar_rssi: RSSI threshold for starting long radar detection (dB steps)
+ * @radar_inband: threshold for checking the ratio of in-band power
+ * to total power for long radar pulses (half dB steps)
+ * @fir_power: threshold for detecting the end of a long radar pulse (dB)
+ *
+ * @ext_channel: enable extension channel radar detection
+ */
+struct ath_hw_radar_conf {
+ unsigned int pulse_inband;
+ unsigned int pulse_inband_step;
+ unsigned int pulse_height;
+ unsigned int pulse_rssi;
+ unsigned int pulse_maxlen;
+
+ unsigned int radar_rssi;
+ unsigned int radar_inband;
+ int fir_power;
+
+ bool ext_channel;
+};
+
+/**
* struct ath_hw_private_ops - callbacks used internally by hardware code
*
* This structure contains private callbacks designed to only be used internally
@@ -488,7 +532,6 @@ struct ath_hw_antcomb_conf {
*
* @init_mode_regs: Initializes mode registers
* @init_mode_gain_regs: Initialize TX/RX gain registers
- * @macversion_supported: If this specific mac revision is supported
*
* @rf_set_freq: change frequency
* @spur_mitigate_freq: spur mitigation
@@ -510,7 +553,6 @@ struct ath_hw_private_ops {
void (*init_mode_regs)(struct ath_hw *ah);
void (*init_mode_gain_regs)(struct ath_hw *ah);
- bool (*macversion_supported)(u32 macversion);
void (*setup_calibration)(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
@@ -534,7 +576,6 @@ struct ath_hw_private_ops {
void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
bool (*rfbus_req)(struct ath_hw *ah);
void (*rfbus_done)(struct ath_hw *ah);
- void (*enable_rfkill)(struct ath_hw *ah);
void (*restore_chainmask)(struct ath_hw *ah);
void (*set_diversity)(struct ath_hw *ah, bool value);
u32 (*compute_pll_control)(struct ath_hw *ah,
@@ -542,6 +583,8 @@ struct ath_hw_private_ops {
bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
int param);
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
+ void (*set_radar_params)(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf);
/* ANI */
void (*ani_cache_ini_regs)(struct ath_hw *ah);
@@ -603,6 +646,10 @@ struct ath_nf_limits {
s16 nominal;
};
+/* ah_flags */
+#define AH_USE_EEPROM 0x1
+#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
+
struct ath_hw {
struct ieee80211_hw *hw;
struct ath_common common;
@@ -718,9 +765,7 @@ struct ath_hw {
u32 *bank6Temp;
u8 txpower_limit;
- int16_t txpower_indexoffset;
int coverage_class;
- u32 beacon_interval;
u32 slottime;
u32 globaltxtimeout;
@@ -740,6 +785,8 @@ struct ath_hw {
u8 txchainmask;
u8 rxchainmask;
+ struct ath_hw_radar_conf radar_conf;
+
u32 originalGain[22];
int initPDADC;
int PDADCdelta;
@@ -789,6 +836,11 @@ struct ath_hw {
u32 bb_watchdog_last_status;
u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
+ unsigned int paprd_target_power;
+ unsigned int paprd_training_power;
+ unsigned int paprd_ratemask;
+ unsigned int paprd_ratemask_ht40;
+ bool paprd_table_write_done;
u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
/*
@@ -797,6 +849,9 @@ struct ath_hw {
* this register when in sleep states.
*/
u32 WARegVal;
+
+ /* Enterprise mode cap */
+ u32 ent_mode;
};
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -819,10 +874,9 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
return &ah->ops;
}
-static inline int sign_extend(int val, const int nbits)
+static inline u8 get_streams(int mask)
{
- int order = BIT(nbits-1);
- return (val ^ order) - order;
+ return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
}
/* Initialization, Detach, Reset */
@@ -861,7 +915,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
bool ath9k_hw_phy_disable(struct ath_hw *ah);
bool ath9k_hw_disable(struct ath_hw *ah);
-void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test);
void ath9k_hw_setopmode(struct ath_hw *ah);
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
void ath9k_hw_setbssidmask(struct ath_hw *ah);
@@ -893,7 +947,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_isr(struct ath_hw *hw);
-u32 ath9k_hw_gettsf32(struct ath_hw *ah);
void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 92bc5c5f4876..b6643b5bf050 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -15,7 +15,6 @@
*/
#include <linux/slab.h>
-#include <linux/pm_qos_params.h>
#include "ath9k.h"
@@ -38,9 +37,19 @@ int led_blink;
module_param_named(blink, led_blink, int, 0444);
MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+static int ath9k_btcoex_enable;
+module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
+MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
+
+int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
+module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
+
+bool is_ath9k_unloaded;
/* We use the hw_value as an index into our private channel structure */
#define CHAN2G(_freq, _idx) { \
+ .band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 20, \
@@ -180,8 +189,6 @@ static const struct ath_ops ath9k_common_ops = {
.write = ath9k_iowrite32,
};
-struct pm_qos_request_list ath9k_pm_qos_req;
-
/**************************/
/* Initialization */
/**************************/
@@ -209,7 +216,9 @@ static void setup_ht_cap(struct ath_softc *sc,
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
- if (AR_SREV_9300_20_OR_LATER(ah))
+ if (AR_SREV_9485(ah))
+ max_streams = 1;
+ else if (AR_SREV_9300_20_OR_LATER(ah))
max_streams = 3;
else
max_streams = 2;
@@ -225,9 +234,9 @@ static void setup_ht_cap(struct ath_softc *sc,
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
- ath_print(common, ATH_DBG_CONFIG,
- "TX streams %d, RX streams: %d\n",
- tx_streams, rx_streams);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "TX streams %d, RX streams: %d\n",
+ tx_streams, rx_streams);
if (tx_streams != rx_streams) {
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
@@ -270,8 +279,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
struct ath_buf *bf;
int i, bsize, error, desc_len;
- ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
- name, nbuf, ndesc);
+ ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+ name, nbuf, ndesc);
INIT_LIST_HEAD(head);
@@ -282,8 +291,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* ath_desc must be a multiple of DWORDs */
if ((desc_len % 4) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "ath_desc not DWORD aligned\n");
+ ath_err(common, "ath_desc not DWORD aligned\n");
BUG_ON((desc_len % 4) != 0);
error = -ENOMEM;
goto fail;
@@ -317,9 +325,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
goto fail;
}
ds = (u8 *) dd->dd_desc;
- ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
- name, ds, (u32) dd->dd_desc_len,
- ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+ ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+ name, ds, (u32) dd->dd_desc_len,
+ ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
@@ -365,7 +373,7 @@ fail:
#undef DS2PHYS
}
-static void ath9k_init_crypto(struct ath_softc *sc)
+void ath9k_init_crypto(struct ath_softc *sc)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int i = 0;
@@ -373,9 +381,9 @@ static void ath9k_init_crypto(struct ath_softc *sc)
/* Get the hardware key cache size. */
common->keymax = sc->sc_ah->caps.keycache_size;
if (common->keymax > ATH_KEYMAX) {
- ath_print(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
+ ath_dbg(common, ATH_DBG_ANY,
+ "Warning, using only %u entries in %u key cache\n",
+ ATH_KEYMAX, common->keymax);
common->keymax = ATH_KEYMAX;
}
@@ -398,7 +406,8 @@ static void ath9k_init_crypto(struct ath_softc *sc)
static int ath9k_init_btcoex(struct ath_softc *sc)
{
- int r, qnum;
+ struct ath_txq *txq;
+ int r;
switch (sc->sc_ah->btcoex_hw.scheme) {
case ATH_BTCOEX_CFG_NONE:
@@ -411,8 +420,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
r = ath_init_btcoex_timer(sc);
if (r)
return -1;
- qnum = sc->tx.hwq_map[WME_AC_BE];
- ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
+ txq = sc->tx.txq_map[WME_AC_BE];
+ ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
break;
default:
@@ -425,59 +434,18 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
static int ath9k_init_queues(struct ath_softc *sc)
{
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int i = 0;
- for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
- sc->tx.hwq_map[i] = -1;
-
sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
- if (sc->beacon.beaconq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup a beacon xmit queue\n");
- goto err;
- }
-
sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
- if (sc->beacon.cabq == NULL) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup CAB xmit queue\n");
- goto err;
- }
sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
- if (!ath_tx_setup(sc, WME_AC_BK)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BK traffic\n");
- goto err;
- }
-
- if (!ath_tx_setup(sc, WME_AC_BE)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BE traffic\n");
- goto err;
- }
- if (!ath_tx_setup(sc, WME_AC_VI)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VI traffic\n");
- goto err;
- }
- if (!ath_tx_setup(sc, WME_AC_VO)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VO traffic\n");
- goto err;
- }
+ for (i = 0; i < WME_NUM_AC; i++)
+ sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
return 0;
-
-err:
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
- if (ATH_TXQ_SETUP(sc, i))
- ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
- return -EIO;
}
static int ath9k_init_channels_rates(struct ath_softc *sc)
@@ -573,6 +541,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;
+ if (!sc->dev->platform_data)
+ ah->ah_flags |= AH_USE_EEPROM;
+
common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;
common->bus_ops = bus_ops;
@@ -580,10 +551,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
common->hw = sc->hw;
common->priv = sc;
common->debug_mask = ath9k_debug;
+ common->btcoex_enabled = ath9k_btcoex_enable == 1;
spin_lock_init(&common->cc_lock);
spin_lock_init(&sc->wiphy_lock);
- spin_lock_init(&sc->sc_resetlock);
spin_lock_init(&sc->sc_serial_rw);
spin_lock_init(&sc->sc_pm_lock);
mutex_init(&sc->mutex);
@@ -603,13 +574,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (ret)
goto err_hw;
- ret = ath9k_init_debug(ah);
- if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to create debugfs files\n");
- goto err_debug;
- }
-
ret = ath9k_init_queues(sc);
if (ret)
goto err_queues;
@@ -632,8 +596,6 @@ err_btcoex:
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
err_queues:
- ath9k_exit_debug(ah);
-err_debug:
ath9k_hw_deinit(ah);
err_hw:
tasklet_kill(&sc->intr_tq);
@@ -645,6 +607,37 @@ err_hw:
return ret;
}
+static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+ int i;
+
+ sband = &sc->sbands[band];
+ for (i = 0; i < sband->n_channels; i++) {
+ chan = &sband->channels[i];
+ ah->curchan = &ah->channels[chan->hw_value];
+ ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
+ ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
+ chan->max_power = reg->max_power_level / 2;
+ }
+}
+
+static void ath9k_init_txpower_limits(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_channel *curchan = ah->curchan;
+
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
+ ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+ ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
+
+ ah->curchan = curchan;
+}
+
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -664,6 +657,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_STATION) |
@@ -706,6 +701,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops)
{
struct ieee80211_hw *hw = sc->hw;
+ struct ath_wiphy *aphy = hw->priv;
struct ath_common *common;
struct ath_hw *ah;
int error = 0;
@@ -738,11 +734,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
if (error != 0)
goto error_rx;
+ ath9k_init_txpower_limits(sc);
+
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
goto error_register;
+ error = ath9k_init_debug(ah);
+ if (error) {
+ ath_err(common, "Unable to create debugfs files\n");
+ goto error_world;
+ }
+
/* Handle world regulatory */
if (!ath_is_world_regd(reg)) {
error = regulatory_hint(hw->wiphy, reg->alpha2);
@@ -755,11 +759,12 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc);
ath_start_rfkill_poll(sc);
- pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+ pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
return 0;
@@ -800,7 +805,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
- ath9k_exit_debug(sc->sc_ah);
ath9k_hw_deinit(sc->sc_ah);
tasklet_kill(&sc->intr_tq);
@@ -830,7 +834,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
}
ieee80211_unregister_hw(hw);
- pm_qos_remove_request(&ath9k_pm_qos_req);
+ pm_qos_remove_request(&sc->pm_qos_req);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
ath9k_deinit_softc(sc);
@@ -867,20 +871,12 @@ static int __init ath9k_init(void)
goto err_out;
}
- error = ath9k_debug_create_root();
- if (error) {
- printk(KERN_ERR
- "ath9k: Unable to create debugfs root: %d\n",
- error);
- goto err_rate_unregister;
- }
-
error = ath_pci_init();
if (error < 0) {
printk(KERN_ERR
"ath9k: No PCI devices found, driver not installed.\n");
error = -ENODEV;
- goto err_remove_root;
+ goto err_rate_unregister;
}
error = ath_ahb_init();
@@ -894,8 +890,6 @@ static int __init ath9k_init(void)
err_pci_exit:
ath_pci_exit();
- err_remove_root:
- ath9k_debug_remove_root();
err_rate_unregister:
ath_rate_control_unregister();
err_out:
@@ -905,9 +899,9 @@ module_init(ath9k_init);
static void __exit ath9k_exit(void)
{
+ is_ath9k_unloaded = true;
ath_ahb_exit();
ath_pci_exit();
- ath9k_debug_remove_root();
ath_rate_control_unregister();
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
}
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 8c13479b17cd..180170d3ce25 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -20,11 +20,11 @@
static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
struct ath9k_tx_queue_info *qi)
{
- ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
- "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
- ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
- ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
- ah->txurn_interrupt_mask);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
+ "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+ ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+ ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+ ah->txurn_interrupt_mask);
ENABLE_REGWRITE_BUFFER(ah);
@@ -56,8 +56,8 @@ EXPORT_SYMBOL(ath9k_hw_puttxbuf);
void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
- ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
- "Enable TXE on queue: %u\n", q);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE,
+ "Enable TXE on queue: %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q);
}
EXPORT_SYMBOL(ath9k_hw_txstart);
@@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
{
u32 txcfg, curLevel, newLevel;
- enum ath9k_int omask;
if (ah->tx_trig_level >= ah->config.max_txtrig_level)
return false;
- omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
+ ath9k_hw_disable_interrupts(ah);
txcfg = REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG);
@@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
REG_WRITE(ah, AR_TXCFG,
(txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
- ath9k_hw_set_interrupts(ah, omask);
+ ath9k_hw_enable_interrupts(ah);
ah->tx_trig_level = newLevel;
@@ -155,15 +154,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Stopping TX DMA, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Stopping TX DMA, inactive queue: %u\n", q);
return false;
}
@@ -176,9 +175,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
}
if (ath9k_hw_numtxpending(ah, q)) {
- ath_print(common, ATH_DBG_QUEUE,
- "%s: Num of pending TX Frames %d on Q %d\n",
- __func__, ath9k_hw_numtxpending(ah, q), q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "%s: Num of pending TX Frames %d on Q %d\n",
+ __func__, ath9k_hw_numtxpending(ah, q), q);
for (j = 0; j < 2; j++) {
tsfLow = REG_READ(ah, AR_TSF_L32);
@@ -192,9 +191,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
break;
- ath_print(common, ATH_DBG_QUEUE,
- "TSF has moved while trying to set "
- "quiet time TSF: 0x%08x\n", tsfLow);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "TSF has moved while trying to set quiet time TSF: 0x%08x\n",
+ tsfLow);
}
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
@@ -205,9 +204,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to stop TX DMA in 100 "
- "msec after killing last frame\n");
+ ath_err(common,
+ "Failed to stop TX DMA in 100 msec after killing last frame\n");
break;
}
udelay(ATH9K_TIME_QUANTUM);
@@ -240,19 +238,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Set TXQ properties, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Set TXQ properties, inactive queue: %u\n", q);
return false;
}
- ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
qi->tqi_ver = qinfo->tqi_ver;
qi->tqi_subtype = qinfo->tqi_subtype;
@@ -311,15 +309,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Get TXQ properties, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Get TXQ properties, inactive queue: %u\n", q);
return false;
}
@@ -369,23 +367,20 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
- ath_print(common, ATH_DBG_FATAL,
- "No available TX queue\n");
+ ath_err(common, "No available TX queue\n");
return -1;
}
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Invalid TX queue type: %u\n", type);
+ ath_err(common, "Invalid TX queue type: %u\n", type);
return -1;
}
- ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
qi = &ah->txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_FATAL,
- "TX queue: %u already active\n", q);
+ ath_err(common, "TX queue: %u already active\n", q);
return -1;
}
memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -417,18 +412,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Release TXQ, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Release TXQ, inactive queue: %u\n", q);
return false;
}
- ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
ah->txok_interrupt_mask &= ~(1 << q);
@@ -451,19 +446,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
u32 cwMin, chanCwMin, value;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Reset TXQ, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Reset TXQ, inactive queue: %u\n", q);
return true;
}
- ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan))
@@ -697,16 +692,16 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
if (ads.ds_rxstatus8 & AR_CRCErr)
rs->rs_status |= ATH9K_RXERR_CRC;
- else if (ads.ds_rxstatus8 & AR_PHYErr) {
+ if (ads.ds_rxstatus8 & AR_PHYErr) {
rs->rs_status |= ATH9K_RXERR_PHY;
phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
rs->rs_phyerr = phyerr;
- } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+ }
+ if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
- rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+ if (ads.ds_rxstatus8 & AR_MichaelErr)
rs->rs_status |= ATH9K_RXERR_MIC;
- else if (ads.ds_rxstatus8 & AR_KeyMiss)
+ if (ads.ds_rxstatus8 & AR_KeyMiss)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
}
@@ -736,9 +731,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
AR_DIAG_RX_ABORT));
reg = REG_READ(ah, AR_OBS_BUS_1);
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "RX failed to go idle in 10 ms RXSM=0x%x\n",
- reg);
+ ath_err(ath9k_hw_common(ah),
+ "RX failed to go idle in 10 ms RXSM=0x%x\n",
+ reg);
return false;
}
@@ -767,14 +762,6 @@ void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning)
}
EXPORT_SYMBOL(ath9k_hw_startpcureceive);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah)
-{
- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-
- ath9k_hw_disable_mib_counters(ah);
-}
-EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
-
void ath9k_hw_abortpcurecv(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
@@ -800,12 +787,11 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
}
if (i == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "DMA failed to stop in %d ms "
- "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
- AH_RX_STOP_DMA_TIMEOUT / 1000,
- REG_READ(ah, AR_CR),
- REG_READ(ah, AR_DIAG_SW));
+ ath_err(common,
+ "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+ AH_RX_STOP_DMA_TIMEOUT / 1000,
+ REG_READ(ah, AR_CR),
+ REG_READ(ah, AR_DIAG_SW));
return false;
} else {
return true;
@@ -849,28 +835,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_intrpend);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
- enum ath9k_int ints)
+void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
+ REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+ (void) REG_READ(ah, AR_IER);
+ if (!AR_SREV_9100(ah)) {
+ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+ (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+ (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+ }
+}
+EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
+ return;
+
+ ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
+ REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+ if (!AR_SREV_9100(ah)) {
+ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+ AR_INTR_MAC_IRQ);
+ REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+ AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_MASK,
+ AR_INTR_SYNC_DEFAULT);
+ }
+ ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+}
+EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
{
enum ath9k_int omask = ah->imask;
u32 mask, mask2;
struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+ if (!(ints & ATH9K_INT_GLOBAL))
+ ath9k_hw_enable_interrupts(ah);
- if (omask & ATH9K_INT_GLOBAL) {
- ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
- REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
- (void) REG_READ(ah, AR_IER);
- if (!AR_SREV_9100(ah)) {
- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
- (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
-
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
- (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
- }
- }
+ ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
/* TODO: global int Ref count */
mask = ints & ATH9K_INT_COMMON;
@@ -931,7 +948,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
mask2 |= AR_IMR_S2_CST;
}
- ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+ ath_dbg(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
REG_WRITE(ah, AR_IMR, mask);
ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
@@ -946,24 +963,8 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
}
- if (ints & ATH9K_INT_GLOBAL) {
- ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
- REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
- if (!AR_SREV_9100(ah)) {
- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
- AR_INTR_MAC_IRQ);
- REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
-
-
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
- AR_INTR_SYNC_DEFAULT);
- REG_WRITE(ah, AR_INTR_SYNC_MASK,
- AR_INTR_SYNC_DEFAULT);
- }
- ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
- REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
- }
+ ath9k_hw_enable_interrupts(ah);
- return omask;
+ return;
}
EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7c1a34d64f6d..7512f97e8f49 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -104,13 +104,11 @@ struct ath_tx_status {
u32 ts_tstamp;
u16 ts_seqnum;
u8 ts_status;
- u8 ts_ratecode;
u8 ts_rateindex;
int8_t ts_rssi;
u8 ts_shortretry;
u8 ts_longretry;
u8 ts_virtcol;
- u8 ts_antenna;
u8 ts_flags;
int8_t ts_rssi_ctl0;
int8_t ts_rssi_ctl1;
@@ -121,7 +119,6 @@ struct ath_tx_status {
u8 qid;
u16 desc_id;
u8 tid;
- u8 pad[2];
u32 ba_low;
u32 ba_high;
u32 evm0;
@@ -240,7 +237,7 @@ struct ath_desc {
u32 ds_ctl1;
u32 ds_hw[20];
void *ds_vdata;
-} __packed;
+} __packed __aligned(4);
#define ATH9K_TXDESC_CLRDMASK 0x0001
#define ATH9K_TXDESC_NOACK 0x0002
@@ -310,7 +307,7 @@ struct ar5416_desc {
u32 status8;
} rx;
} u;
-} __packed;
+} __packed __aligned(4);
#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
@@ -669,6 +666,7 @@ enum ath9k_key_type {
struct ath_hw;
struct ath9k_channel;
+enum ath9k_int;
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
@@ -693,15 +691,15 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah);
void ath9k_hw_abortpcurecv(struct ath_hw *ah);
bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
int ath9k_hw_beaconq_setup(struct ath_hw *ah);
/* Interrupt Handling */
bool ath9k_hw_intrpend(struct ath_hw *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
- enum ath9k_int ints);
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+void ath9k_hw_disable_interrupts(struct ath_hw *ah);
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 25d3ef4c338e..a818e4fd56f5 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -15,7 +15,6 @@
*/
#include <linux/nl80211.h>
-#include <linux/pm_qos_params.h>
#include "ath9k.h"
#include "btcoex.h"
@@ -24,7 +23,7 @@ static void ath_update_txpow(struct ath_softc *sc)
struct ath_hw *ah = sc->sc_ah;
if (sc->curtxpow != sc->config.txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
+ ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
/* read back in case value is clamped */
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
}
@@ -235,6 +234,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
/*
* This is only performed if the channel settings have
* actually changed.
@@ -244,12 +245,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- ath9k_hw_set_interrupts(ah, 0);
- ath_drain_all_txq(sc, false);
-
- spin_lock_bh(&sc->rx.pcu_lock);
+ ath9k_hw_disable_interrupts(ah);
+ stopped = ath_drain_all_txq(sc, false);
- stopped = ath_stoprecv(sc);
+ if (!ath_stoprecv(sc))
+ stopped = false;
/* XXX: do not flush receive queue here. We don't want
* to flush data frames already in queue because of
@@ -261,46 +261,39 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
caldata = &aphy->caldata;
- ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
- sc->sc_ah->curchan->channel,
- channel->center_freq, conf_is_ht40(conf),
- fastcc);
-
- spin_lock_bh(&sc->sc_resetlock);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
+ sc->sc_ah->curchan->channel,
+ channel->center_freq, conf_is_ht40(conf),
+ fastcc);
r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
- spin_unlock_bh(&sc->sc_resetlock);
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common,
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
goto ps_restore;
}
- spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
+ ath_err(common, "Unable to restart recv logic\n");
r = -EIO;
- spin_unlock_bh(&sc->rx.pcu_lock);
goto ps_restore;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
-
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
- ath_beacon_config(sc, NULL);
+ if (sc->sc_flags & SC_OP_BEACONS)
+ ath_beacon_config(sc, NULL);
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
ath_start_ani(common);
}
ps_restore:
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
return r;
}
@@ -328,6 +321,42 @@ static void ath_paprd_activate(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
+static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_control txctl;
+ int time_left;
+
+ memset(&txctl, 0, sizeof(txctl));
+ txctl.txq = sc->tx.txq_map[WME_AC_BE];
+
+ memset(tx_info, 0, sizeof(*tx_info));
+ tx_info->band = hw->conf.channel->band;
+ tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
+ tx_info->control.rates[0].idx = 0;
+ tx_info->control.rates[0].count = 1;
+ tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
+ tx_info->control.rates[1].idx = -1;
+
+ init_completion(&sc->paprd_complete);
+ sc->paprd_pending = true;
+ txctl.paprd = BIT(chain);
+ if (ath_tx_start(hw, skb, &txctl) != 0)
+ return false;
+
+ time_left = wait_for_completion_timeout(&sc->paprd_complete,
+ msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
+ sc->paprd_pending = false;
+
+ if (!time_left)
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
+ "Timeout waiting for paprd training on TX chain %d\n",
+ chain);
+
+ return !!time_left;
+}
+
void ath_paprd_calibrate(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
@@ -335,28 +364,23 @@ void ath_paprd_calibrate(struct work_struct *work)
struct ath_hw *ah = sc->sc_ah;
struct ieee80211_hdr *hdr;
struct sk_buff *skb = NULL;
- struct ieee80211_tx_info *tx_info;
- int band = hw->conf.channel->band;
- struct ieee80211_supported_band *sband = &sc->sbands[band];
- struct ath_tx_control txctl;
struct ath9k_hw_cal_data *caldata = ah->caldata;
struct ath_common *common = ath9k_hw_common(ah);
- int qnum, ftype;
+ int ftype;
int chain_ok = 0;
int chain;
int len = 1800;
- int time_left;
- int i;
if (!caldata)
return;
+ if (ar9003_paprd_init_table(ah) < 0)
+ return;
+
skb = alloc_skb(len, GFP_KERNEL);
if (!skb)
return;
- tx_info = IEEE80211_SKB_CB(skb);
-
skb_put(skb, len);
memset(skb->data, 0, len);
hdr = (struct ieee80211_hdr *)skb->data;
@@ -367,40 +391,25 @@ void ath_paprd_calibrate(struct work_struct *work)
memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
- memset(&txctl, 0, sizeof(txctl));
- qnum = sc->tx.hwq_map[WME_AC_BE];
- txctl.txq = &sc->tx.txq[qnum];
-
ath9k_ps_wakeup(sc);
- ar9003_paprd_init_table(ah);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
if (!(common->tx_chainmask & BIT(chain)))
continue;
chain_ok = 0;
- memset(tx_info, 0, sizeof(*tx_info));
- tx_info->band = band;
- for (i = 0; i < 4; i++) {
- tx_info->control.rates[i].idx = sband->n_bitrates - 1;
- tx_info->control.rates[i].count = 6;
- }
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Sending PAPRD frame for thermal measurement "
+ "on chain %d\n", chain);
+ if (!ath_paprd_send_frame(sc, skb, chain))
+ goto fail_paprd;
- init_completion(&sc->paprd_complete);
ar9003_paprd_setup_gain_table(ah, chain);
- txctl.paprd = BIT(chain);
- if (ath_tx_start(hw, skb, &txctl) != 0)
- break;
- time_left = wait_for_completion_timeout(&sc->paprd_complete,
- msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
- if (!time_left) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "Timeout waiting for paprd training on "
- "TX chain %d\n",
- chain);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Sending PAPRD training frame on chain %d\n", chain);
+ if (!ath_paprd_send_frame(sc, skb, chain))
goto fail_paprd;
- }
if (!ar9003_paprd_is_done(ah))
break;
@@ -457,7 +466,7 @@ void ath_ani_calibrate(unsigned long data)
/* Long calibration runs independently of short calibration. */
if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
longcal = true;
- ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
}
@@ -465,8 +474,8 @@ void ath_ani_calibrate(unsigned long data)
if (!common->ani.caldone) {
if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
shortcal = true;
- ath_print(common, ATH_DBG_ANI,
- "shortcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI,
+ "shortcal @%lu\n", jiffies);
common->ani.shortcal_timer = timestamp;
common->ani.resetcal_timer = timestamp;
}
@@ -525,49 +534,25 @@ set_timer:
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
if (!ah->caldata->paprd_done)
ieee80211_queue_work(sc->hw, &sc->paprd_work);
- else
+ else if (!ah->paprd_table_write_done)
ath_paprd_activate(sc);
}
}
-/*
- * Update tx/rx chainmask. For legacy association,
- * hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration, for bt coexistence, use
- * the chainmask configuration even in legacy mode.
- */
-void ath_update_chainmask(struct ath_softc *sc, int is_ht)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
-
- if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
- (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
- common->tx_chainmask = ah->caps.tx_chainmask;
- common->rx_chainmask = ah->caps.rx_chainmask;
- } else {
- common->tx_chainmask = 1;
- common->rx_chainmask = 1;
- }
-
- ath_print(common, ATH_DBG_CONFIG,
- "tx chmask: %d, rx chmask: %d\n",
- common->tx_chainmask,
- common->rx_chainmask);
-}
-
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
struct ath_node *an;
-
+ struct ath_hw *ah = sc->sc_ah;
an = (struct ath_node *)sta->drv_priv;
+ if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
+ sc->sc_flags |= SC_OP_ENABLE_APM;
+
if (sc->sc_flags & SC_OP_TXAGGR) {
ath_tx_node_init(sc, an);
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
- an->last_rssi = ATH_RSSI_DUMMY_MARKER;
}
}
@@ -615,6 +600,8 @@ void ath9k_tasklet(unsigned long data)
return;
}
+ spin_lock(&sc->sc_pcu_lock);
+
if (!ath9k_hw_check_alive(ah))
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
@@ -625,15 +612,12 @@ void ath9k_tasklet(unsigned long data)
rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
if (status & rxmask) {
- spin_lock_bh(&sc->rx.pcu_lock);
-
/* Check for high priority Rx first */
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
(status & ATH9K_INT_RXHP))
ath_rx_tasklet(sc, 0, true);
ath_rx_tasklet(sc, 0, false);
- spin_unlock_bh(&sc->rx.pcu_lock);
}
if (status & ATH9K_INT_TX) {
@@ -648,8 +632,8 @@ void ath9k_tasklet(unsigned long data)
* TSF sync does not look correct; remain awake to sync with
* the next Beacon.
*/
- ath_print(common, ATH_DBG_PS,
- "TSFOOR - Sync with next Beacon\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "TSFOOR - Sync with next Beacon\n");
sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
}
@@ -658,7 +642,9 @@ void ath9k_tasklet(unsigned long data)
ath_gen_timer_isr(sc->sc_ah);
/* re-enable hardware interrupt */
- ath9k_hw_set_interrupts(ah, ah->imask);
+ ath9k_hw_enable_interrupts(ah);
+
+ spin_unlock(&sc->sc_pcu_lock);
ath9k_ps_restore(sc);
}
@@ -757,7 +743,7 @@ irqreturn_t ath_isr(int irq, void *dev)
* interrupt; otherwise it will continue to
* fire.
*/
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
/*
* Let the hal handle the event. We assume
* it will clear whatever condition caused
@@ -766,11 +752,13 @@ irqreturn_t ath_isr(int irq, void *dev)
spin_lock(&common->cc_lock);
ath9k_hw_proc_mib_event(ah);
spin_unlock(&common->cc_lock);
- ath9k_hw_set_interrupts(ah, ah->imask);
+ ath9k_hw_enable_interrupts(ah);
}
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
if (status & ATH9K_INT_TIM_TIMER) {
+ if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
+ goto chip_reset;
/* Clear RxAbort bit so that we can
* receive frames */
ath9k_setpower(sc, ATH9K_PM_AWAKE);
@@ -783,8 +771,8 @@ chip_reset:
ath_debug_stat_interrupt(sc, status);
if (sched) {
- /* turn off every interrupt except SWBA */
- ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
+ /* turn off every interrupt */
+ ath9k_hw_disable_interrupts(ah);
tasklet_schedule(&sc->intr_tq);
}
@@ -836,16 +824,18 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
}
static void ath9k_bss_assoc_info(struct ath_softc *sc,
+ struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf)
{
+ struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
if (bss_conf->assoc) {
- ath_print(common, ATH_DBG_CONFIG,
- "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, common->curbssid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Bss Info ASSOC %d, bssid: %pM\n",
+ bss_conf->aid, common->curbssid);
/* New association, store aid */
common->curaid = bss_conf->aid;
@@ -862,12 +852,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
ath_beacon_config(sc, vif);
/* Reset rssi stats */
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common);
} else {
- ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
common->curaid = 0;
/* Stop ANI */
sc->sc_flags &= ~SC_OP_ANI_RUN;
@@ -883,31 +874,25 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
int r;
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ath9k_hw_configpcipowersave(ah, 0, 0);
if (!ah->curchan)
ah->curchan = ath_get_curchannel(sc, sc->hw);
- spin_lock_bh(&sc->rx.pcu_lock);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
+ ath_err(common,
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
}
- spin_unlock_bh(&sc->sc_resetlock);
ath_update_txpow(sc);
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
- spin_unlock_bh(&sc->rx.pcu_lock);
- return;
+ ath_err(common, "Unable to restart recv logic\n");
+ goto out;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
-
if (sc->sc_flags & SC_OP_BEACONS)
ath_beacon_config(sc, NULL); /* restart beacons */
@@ -920,6 +905,9 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
ath9k_hw_set_gpio(ah, ah->led_pin, 0);
ieee80211_wake_queues(hw);
+out:
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
}
@@ -930,6 +918,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
int r;
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ieee80211_stop_queues(hw);
/*
@@ -942,34 +932,30 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
}
/* Disable interrupts */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath_drain_all_txq(sc, false); /* clear pending tx frames */
- spin_lock_bh(&sc->rx.pcu_lock);
-
ath_stoprecv(sc); /* turn off frame recv */
ath_flushrecv(sc); /* flush recv queue */
if (!ah->curchan)
ah->curchan = ath_get_curchannel(sc, hw);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
}
- spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
- spin_unlock_bh(&sc->rx.pcu_lock);
-
ath9k_hw_configpcipowersave(ah, 1, 1);
+
+ spin_unlock_bh(&sc->sc_pcu_lock);
ath9k_ps_restore(sc);
+
ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
}
@@ -983,28 +969,23 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
/* Stop ANI */
del_timer_sync(&common->ani.timer);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ieee80211_stop_queues(hw);
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath_drain_all_txq(sc, retry_tx);
- spin_lock_bh(&sc->rx.pcu_lock);
-
ath_stoprecv(sc);
ath_flushrecv(sc);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
if (r)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d\n", r);
- spin_unlock_bh(&sc->sc_resetlock);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d\n", r);
if (ath_startrecv(sc) != 0)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
-
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common, "Unable to start recv logic\n");
/*
* We may be doing a reset in response to a request
@@ -1030,6 +1011,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
}
ieee80211_wake_queues(hw);
+ spin_unlock_bh(&sc->sc_pcu_lock);
/* Start ANI */
ath_start_ani(common);
@@ -1037,56 +1019,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
return r;
}
-static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
-{
- int qnum;
-
- switch (queue) {
- case 0:
- qnum = sc->tx.hwq_map[WME_AC_VO];
- break;
- case 1:
- qnum = sc->tx.hwq_map[WME_AC_VI];
- break;
- case 2:
- qnum = sc->tx.hwq_map[WME_AC_BE];
- break;
- case 3:
- qnum = sc->tx.hwq_map[WME_AC_BK];
- break;
- default:
- qnum = sc->tx.hwq_map[WME_AC_BE];
- break;
- }
-
- return qnum;
-}
-
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
-{
- int qnum;
-
- switch (queue) {
- case WME_AC_VO:
- qnum = 0;
- break;
- case WME_AC_VI:
- qnum = 1;
- break;
- case WME_AC_BE:
- qnum = 2;
- break;
- case WME_AC_BK:
- qnum = 3;
- break;
- default:
- qnum = -1;
- break;
- }
-
- return qnum;
-}
-
/* XXX: Remove me once we don't depend on ath9k_channel for all
* this redundant data */
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
@@ -1125,9 +1057,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath9k_channel *init_channel;
int r;
- ath_print(common, ATH_DBG_CONFIG,
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Starting driver with initial channel: %d MHz\n",
+ curchan->center_freq);
mutex_lock(&sc->mutex);
@@ -1168,19 +1100,15 @@ static int ath9k_start(struct ieee80211_hw *hw)
* be followed by initialization of the appropriate bits
* and then setup of the interrupt mask.
*/
- spin_lock_bh(&sc->rx.pcu_lock);
- spin_lock_bh(&sc->sc_resetlock);
+ spin_lock_bh(&sc->sc_pcu_lock);
r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", r,
- curchan->center_freq);
- spin_unlock_bh(&sc->sc_resetlock);
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ r, curchan->center_freq);
+ spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
- spin_unlock_bh(&sc->sc_resetlock);
/*
* This is needed only to setup initial state
@@ -1196,13 +1124,12 @@ static int ath9k_start(struct ieee80211_hw *hw)
* here except setup the interrupt mask.
*/
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
+ ath_err(common, "Unable to start recv logic\n");
r = -EIO;
- spin_unlock_bh(&sc->rx.pcu_lock);
+ spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
+ spin_unlock_bh(&sc->sc_pcu_lock);
/* Setup our intr mask. */
ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
@@ -1244,7 +1171,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath9k_btcoex_timer_resume(sc);
}
- pm_qos_update_request(&ath9k_pm_qos_req, 55);
+ /* User has the option to provide pm-qos value as a module
+ * parameter rather than using the default value of
+ * 'ATH9K_PM_QOS_DEFAULT_VALUE'.
+ */
+ pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
+
+ if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
+ common->bus_ops->extn_synch_en(common);
mutex_unlock:
mutex_unlock(&sc->mutex);
@@ -1255,19 +1189,16 @@ mutex_unlock:
static int ath9k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_tx_control txctl;
- int padpos, padsize;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- int qnum;
if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
- ath_print(common, ATH_DBG_XMIT,
- "ath9k: %s: TX in unexpected wiphy state "
- "%d\n", wiphy_name(hw->wiphy), aphy->state);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "ath9k: %s: TX in unexpected wiphy state %d\n",
+ wiphy_name(hw->wiphy), aphy->state);
goto exit;
}
@@ -1279,8 +1210,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (ieee80211_is_data(hdr->frame_control) &&
!ieee80211_is_nullfunc(hdr->frame_control) &&
!ieee80211_has_pm(hdr->frame_control)) {
- ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
- "while in PS mode\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Add PM=1 for a TX frame while in PS mode\n");
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
}
}
@@ -1295,12 +1226,12 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
ath9k_hw_setrxabort(sc->sc_ah, 0);
if (ieee80211_is_pspoll(hdr->frame_control)) {
- ath_print(common, ATH_DBG_PS,
- "Sending PS-Poll to pick a buffered frame\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Sending PS-Poll to pick a buffered frame\n");
sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
} else {
- ath_print(common, ATH_DBG_PS,
- "Wake up to complete TX\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Wake up to complete TX\n");
sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
}
/*
@@ -1312,36 +1243,12 @@ static int ath9k_tx(struct ieee80211_hw *hw,
}
memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
- /*
- * As a temporary workaround, assign seq# here; this will likely need
- * to be cleaned up to work better with Beacon transmission and virtual
- * BSSes.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->tx.seq_no += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
- }
-
- /* Add the padding after the header if this is not already done */
- padpos = ath9k_cmn_padpos(hdr->frame_control);
- padsize = padpos & 3;
- if (padsize && skb->len>padpos) {
- if (skb_headroom(skb) < padsize)
- return -1;
- skb_push(skb, padsize);
- memmove(skb->data, skb->data + padsize, padpos);
- }
-
- qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
- txctl.txq = &sc->tx.txq[qnum];
-
- ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
+ ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
if (ath_tx_start(hw, skb, &txctl) != 0) {
- ath_print(common, ATH_DBG_XMIT, "TX failed\n");
+ ath_dbg(common, ATH_DBG_XMIT, "TX failed\n");
goto exit;
}
@@ -1381,7 +1288,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
}
if (sc->sc_flags & SC_OP_INVALID) {
- ath_print(common, ATH_DBG_ANY, "Device not present\n");
+ ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
mutex_unlock(&sc->mutex);
return;
}
@@ -1400,34 +1307,38 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_btcoex_timer_pause(sc);
}
+ spin_lock_bh(&sc->sc_pcu_lock);
+
/* make sure h/w will not generate any interrupt
* before setting the invalid flag. */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
- spin_lock_bh(&sc->rx.pcu_lock);
if (!(sc->sc_flags & SC_OP_INVALID)) {
ath_drain_all_txq(sc, false);
ath_stoprecv(sc);
ath9k_hw_phy_disable(ah);
} else
sc->rx.rxlink = NULL;
- spin_unlock_bh(&sc->rx.pcu_lock);
/* disable HAL and put h/w to sleep */
ath9k_hw_disable(ah);
ath9k_hw_configpcipowersave(ah, 1, 1);
+
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
- /* Finally, put the chip in FULL SLEEP mode */
- ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
+ sc->ps_idle = true;
+ ath9k_set_wiphy_idle(aphy, true);
+ ath_radio_disable(sc, hw);
sc->sc_flags |= SC_OP_INVALID;
- pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+ pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
mutex_unlock(&sc->mutex);
- ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
}
static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1460,14 +1371,14 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ic_opmode = vif->type;
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Interface type %d not yet supported\n", vif->type);
+ ath_err(common, "Interface type %d not yet supported\n",
+ vif->type);
ret = -EOPNOTSUPP;
goto out;
}
- ath_print(common, ATH_DBG_CONFIG,
- "Attach a VIF of type: %d\n", ic_opmode);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Attach a VIF of type: %d\n", ic_opmode);
/* Set the VIF opmode */
avp->av_opmode = ic_opmode;
@@ -1513,16 +1424,83 @@ out:
return ret;
}
+static void ath9k_reclaim_beacon(struct ath_softc *sc,
+ struct ieee80211_vif *vif)
+{
+ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ /* Disable SWBA interrupt */
+ sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+ tasklet_kill(&sc->bcon_tasklet);
+ ath9k_ps_restore(sc);
+
+ ath_beacon_return(sc, avp);
+ sc->sc_flags &= ~SC_OP_BEACONS;
+
+ if (sc->nbcnvifs > 0) {
+ /* Re-enable beaconing */
+ sc->sc_ah->imask |= ATH9K_INT_SWBA;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+ ath9k_ps_restore(sc);
+ }
+}
+
+static int ath9k_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype new_type,
+ bool p2p)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ int ret = 0;
+
+ ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
+ mutex_lock(&sc->mutex);
+
+ switch (new_type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_ADHOC:
+ if (sc->nbcnvifs >= ATH_BCBUF) {
+ ath_err(common, "No beacon slot available\n");
+ ret = -ENOBUFS;
+ goto out;
+ }
+ break;
+ case NL80211_IFTYPE_STATION:
+ /* Stop ANI */
+ sc->sc_flags &= ~SC_OP_ANI_RUN;
+ del_timer_sync(&common->ani.timer);
+ if ((vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_ADHOC))
+ ath9k_reclaim_beacon(sc, vif);
+ break;
+ default:
+ ath_err(common, "Interface type %d not yet supported\n",
+ vif->type);
+ ret = -ENOTSUPP;
+ goto out;
+ }
+ vif->type = new_type;
+ vif->p2p = p2p;
+
+out:
+ mutex_unlock(&sc->mutex);
+ return ret;
+}
+
static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_vif *avp = (void *)vif->drv_priv;
- int i;
- ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
mutex_lock(&sc->mutex);
@@ -1533,23 +1511,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
/* Reclaim beacon resources */
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
- (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
- ath9k_ps_wakeup(sc);
- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
- ath9k_ps_restore(sc);
- }
-
- ath_beacon_return(sc, avp);
- sc->sc_flags &= ~SC_OP_BEACONS;
-
- for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
- if (sc->beacon.bslot[i] == vif) {
- printk(KERN_DEBUG "%s: vif had allocated beacon "
- "slot\n", __func__);
- sc->beacon.bslot[i] = NULL;
- sc->beacon.bslot_aphy[i] = NULL;
- }
- }
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))
+ ath9k_reclaim_beacon(sc, vif);
sc->nvifs--;
@@ -1629,8 +1592,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (enable_radio) {
sc->ps_idle = false;
ath_radio_enable(sc, hw);
- ath_print(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "not-idle: enabling radio\n");
}
}
@@ -1652,12 +1615,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
if (conf->flags & IEEE80211_CONF_MONITOR) {
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor mode is enabled\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor mode is enabled\n");
sc->sc_ah->is_monitoring = true;
} else {
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor mode is disabled\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor mode is disabled\n");
sc->sc_ah->is_monitoring = false;
}
}
@@ -1689,14 +1652,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
goto skip_chan_change;
}
- ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
/* XXX: remove me eventualy */
ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
- ath_update_chainmask(sc, conf_is_ht(conf));
-
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
ath_update_survey_stats(sc);
@@ -1723,8 +1684,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to set channel\n");
+ ath_err(common, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
@@ -1749,7 +1709,7 @@ skip_chan_change:
spin_unlock_bh(&sc->wiphy_lock);
if (disable_radio) {
- ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
sc->ps_idle = true;
ath_radio_disable(sc, hw);
}
@@ -1788,8 +1748,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
ath9k_ps_restore(sc);
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Set HW RX filter: 0x%x\n", rfilt);
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Set HW RX filter: 0x%x\n", rfilt);
}
static int ath9k_sta_add(struct ieee80211_hw *hw,
@@ -1822,12 +1782,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_txq *txq;
struct ath9k_tx_queue_info qi;
- int ret = 0, qnum;
+ int ret = 0;
if (queue >= WME_NUM_AC)
return 0;
+ txq = sc->tx.txq_map[queue];
+
mutex_lock(&sc->mutex);
memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -1836,20 +1799,18 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
qi.tqi_burstTime = params->txop;
- qnum = ath_get_hal_qnum(queue, sc);
- ath_print(common, ATH_DBG_CONFIG,
- "Configure tx [queue/halq] [%d/%d], "
- "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
- queue, qnum, params->aifs, params->cw_min,
- params->cw_max, params->txop);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, txq->axq_qnum, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
- ret = ath_txq_update(sc, qnum, &qi);
+ ret = ath_txq_update(sc, txq->axq_qnum, &qi);
if (ret)
- ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
+ ath_err(common, "TXQ Update failed\n");
if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
- if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
+ if (queue == WME_AC_BE && !ret)
ath_beaconq_config(sc);
mutex_unlock(&sc->mutex);
@@ -1873,7 +1834,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
- ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
@@ -1928,13 +1889,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
/* Set aggregation protection mode parameters */
sc->config.ath_aggr_prot = 0;
- /* Only legacy IBSS for now */
- if (vif->type == NL80211_IFTYPE_ADHOC)
- ath_update_chainmask(sc, 0);
-
- ath_print(common, ATH_DBG_CONFIG,
- "BSSID: %pM aid: 0x%x\n",
- common->curbssid, common->curaid);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
+ common->curbssid, common->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -1990,8 +1946,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
- bss_conf->use_short_preamble);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
else
@@ -1999,8 +1955,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
- bss_conf->use_cts_prot);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+ bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot &&
hw->conf.channel->band != IEEE80211_BAND_5GHZ)
sc->sc_flags |= SC_OP_PROTECT_ENABLE;
@@ -2009,9 +1965,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ASSOC) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
bss_conf->assoc);
- ath9k_bss_assoc_info(sc, vif, bss_conf);
+ ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
}
mutex_unlock(&sc->mutex);
@@ -2024,7 +1980,9 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
struct ath_softc *sc = aphy->sc;
mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ ath9k_ps_restore(sc);
mutex_unlock(&sc->mutex);
return tsf;
@@ -2036,7 +1994,9 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
struct ath_softc *sc = aphy->sc;
mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
ath9k_hw_settsf64(sc->sc_ah, tsf);
+ ath9k_ps_restore(sc);
mutex_unlock(&sc->mutex);
}
@@ -2074,6 +2034,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_RX_STOP:
break;
case IEEE80211_AMPDU_TX_START:
+ if (!(sc->sc_flags & SC_OP_TXAGGR))
+ return -EOPNOTSUPP;
+
ath9k_ps_wakeup(sc);
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
if (!ret)
@@ -2092,8 +2055,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
ath9k_ps_restore(sc);
break;
default:
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unknown AMPDU action\n");
+ ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
}
local_bh_enable();
@@ -2193,6 +2155,7 @@ struct ieee80211_ops ath9k_ops = {
.start = ath9k_start,
.stop = ath9k_stop,
.add_interface = ath9k_add_interface,
+ .change_interface = ath9k_change_interface,
.remove_interface = ath9k_remove_interface,
.config = ath9k_config,
.configure_filter = ath9k_configure_filter,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b5b651413e77..78ef1f13386f 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -16,6 +16,7 @@
#include <linux/nl80211.h>
#include <linux/pci.h>
+#include <linux/ath9k_platform.h>
#include "ath9k.h"
static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
@@ -29,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
+ { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
{ 0 }
};
@@ -53,21 +55,35 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_hw *ah = (struct ath_hw *) common->ah;
-
- common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
- AH_WAIT_TIMEOUT)) {
- return false;
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
+
+ if (pdata) {
+ if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+ ath_err(common,
+ "%s: eeprom read failed, offset %08x is out of range\n",
+ __func__, off);
+ }
+
+ *data = pdata->eeprom_data[off];
+ } else {
+ struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+ common->ops->read(ah, AR5416_EEPROM_OFFSET +
+ (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
+ }
+
+ *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
}
- *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
-
return true;
}
@@ -80,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
struct pci_dev *pdev = to_pci_dev(sc->dev);
u8 aspm;
- if (!pdev->is_pcie)
+ if (!pci_is_pcie(pdev))
return;
pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
@@ -88,11 +104,23 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
}
+static void ath_pci_extn_synch_enable(struct ath_common *common)
+{
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct pci_dev *pdev = to_pci_dev(sc->dev);
+ u8 lnkctl;
+
+ pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl);
+ lnkctl |= PCI_EXP_LNKCTL_ES;
+ pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
+}
+
static const struct ath_bus_ops ath_pci_bus_ops = {
.ath_bus_type = ATH_PCI,
.read_cachesize = ath_pci_read_cachesize,
.eeprom_read = ath_pci_eeprom_read,
.bt_coex_prep = ath_pci_bt_coex_prep,
+ .extn_synch_en = ath_pci_extn_synch_enable,
};
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -236,6 +264,8 @@ static void ath_pci_remove(struct pci_dev *pdev)
struct ath_softc *sc = aphy->sc;
void __iomem *mem = sc->mem;
+ if (!is_ath9k_unloaded)
+ sc->sc_ah->ah_flags |= AH_UNPLUGGED;
ath9k_deinit_device(sc);
free_irq(sc->irq, sc);
ieee80211_free_hw(sc->hw);
@@ -247,34 +277,25 @@ static void ath_pci_remove(struct pci_dev *pdev)
#ifdef CONFIG_PM
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ath_pci_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
return 0;
}
-static int ath_pci_resume(struct pci_dev *pdev)
+static int ath_pci_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
u32 val;
- int err;
-
- pci_restore_state(pdev);
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
/*
* Suspend/Resume resets the PCI configuration space, so we have to
@@ -290,10 +311,38 @@ static int ath_pci_resume(struct pci_dev *pdev)
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
+ /*
+ * Reset key cache to sane defaults (all entries cleared) instead of
+ * semi-random values after suspend/resume.
+ */
+ ath9k_ps_wakeup(sc);
+ ath9k_init_crypto(sc);
+ ath9k_ps_restore(sc);
+
+ sc->ps_idle = true;
+ ath9k_set_wiphy_idle(aphy, true);
+ ath_radio_disable(sc, hw);
+
return 0;
}
-#endif /* CONFIG_PM */
+static const struct dev_pm_ops ath9k_pm_ops = {
+ .suspend = ath_pci_suspend,
+ .resume = ath_pci_resume,
+ .freeze = ath_pci_suspend,
+ .thaw = ath_pci_resume,
+ .poweroff = ath_pci_suspend,
+ .restore = ath_pci_resume,
+};
+
+#define ATH9K_PM_OPS (&ath9k_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define ATH9K_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
@@ -302,10 +351,7 @@ static struct pci_driver ath_pci_driver = {
.id_table = ath_pci_id_table,
.probe = ath_pci_probe,
.remove = ath_pci_remove,
-#ifdef CONFIG_PM
- .suspend = ath_pci_suspend,
- .resume = ath_pci_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = ATH9K_PM_OPS,
};
int ath_pci_init(void)
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 17969af842f6..5e3d7496986e 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -19,6 +19,7 @@
#define CHANSEL_DIV 15
#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
+#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV)
#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
#define AR_PHY_BASE 0x9800
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 89978d71617f..e45147820eae 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -381,25 +381,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate);
-static inline int8_t median(int8_t a, int8_t b, int8_t c)
-{
- if (a >= b) {
- if (b >= c)
- return b;
- else if (a > c)
- return c;
- else
- return a;
- } else {
- if (a >= c)
- return a;
- else if (b >= c)
- return c;
- else
- return b;
- }
-}
-
static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv)
{
@@ -419,7 +400,7 @@ static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
}
}
-static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
+static void ath_rc_init_valid_rate_idx(struct ath_rate_priv *ath_rc_priv)
{
u8 i;
@@ -427,7 +408,7 @@ static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
ath_rc_priv->valid_rate_index[i] = 0;
}
-static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
+static inline void ath_rc_set_valid_rate_idx(struct ath_rate_priv *ath_rc_priv,
u8 index, int valid_tx_rate)
{
BUG_ON(index > ath_rc_priv->rate_table_size);
@@ -508,7 +489,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
- ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
+ ath_rc_set_valid_rate_idx(ath_rc_priv, i, 1);
hi = i;
}
}
@@ -551,7 +532,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
ath_rc_priv->valid_phy_rateidx[phy]
[valid_rate_count] = j;
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
- ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+ ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
hi = A_MAX(hi, j);
}
}
@@ -587,7 +568,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
ath_rc_priv->valid_phy_rateidx[phy]
[ath_rc_priv->valid_phy_ratecnt[phy]] = j;
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
- ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+ ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
hi = A_MAX(hi, j);
}
}
@@ -883,7 +864,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
bool state_change = false;
int count, n_bad_frames;
u8 last_per;
- static u32 nretry_to_per_lookup[10] = {
+ static const u32 nretry_to_per_lookup[10] = {
100 * 0 / 1,
100 * 1 / 4,
100 * 1 / 2,
@@ -1106,13 +1087,13 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate)
{
int rix = 0, i = 0;
- int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
+ static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
if (!(rate->flags & IEEE80211_TX_RC_MCS))
return rate->idx;
while (rate->idx > mcs_rix_off[i] &&
- i < sizeof(mcs_rix_off)/sizeof(int)) {
+ i < ARRAY_SIZE(mcs_rix_off)) {
rix++; i++;
}
@@ -1203,7 +1184,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
return &ar5416_11na_ratetable;
return &ar5416_11a_ratetable;
default:
- ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n");
return NULL;
}
}
@@ -1229,7 +1210,7 @@ static void ath_rc_init(struct ath_softc *sc,
}
/* Determine the valid rates */
- ath_rc_init_valid_txmask(ath_rc_priv);
+ ath_rc_init_valid_rate_idx(ath_rc_priv);
for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
for (j = 0; j < MAX_TX_RATE_PHY; j++)
@@ -1278,9 +1259,9 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
ath_rc_priv->rate_table = rate_table;
- ath_print(common, ATH_DBG_CONFIG,
- "RC Initialized with capabilities: 0x%x\n",
- ath_rc_priv->ht_cap);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "RC Initialized with capabilities: 0x%x\n",
+ ath_rc_priv->ht_cap);
}
static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1340,7 +1321,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ath_rate_priv *ath_rc_priv = priv_sta;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr;
- int final_ts_idx = 0, tx_status = 0, is_underrun = 0;
+ int final_ts_idx = 0, tx_status = 0;
int long_retry = 0;
__le16 fc;
int i;
@@ -1373,32 +1354,17 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
tx_info->status.ampdu_len = 1;
}
- /*
- * If an underrun error is seen assume it as an excessive retry only
- * if max frame trigger level has been reached (2 KB for singel stream,
- * and 4 KB for dual stream). Adjust the long retry as if the frame was
- * tried hw->max_rate_tries times to affect how ratectrl updates PER for
- * the failed rate. In case of congestion on the bus penalizing these
- * type of underruns should help hardware actually transmit new frames
- * successfully by eventually preferring slower rates. This itself
- * should also alleviate congestion on the bus.
- */
- if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
- (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
- tx_status = 1;
- is_underrun = 1;
- }
-
- if (tx_info->pad[0] & ATH_TX_INFO_XRETRY)
+ if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
tx_status = 1;
ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
- (is_underrun) ? sc->hw->max_rate_tries : long_retry);
+ long_retry);
/* Check if aggregation has to be enabled for this tid */
if (conf_is_ht(&sc->hw->conf) &&
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- if (ieee80211_is_data_qos(fc)) {
+ if (ieee80211_is_data_qos(fc) &&
+ skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
u8 *qc, tid;
struct ath_node *an;
@@ -1407,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
an = (struct ath_node *)sta->drv_priv;
if(ath_tx_aggr_check(sc, an, tid))
- ieee80211_start_tx_ba_session(sta, tid);
+ ieee80211_start_tx_ba_session(sta, tid, 0);
}
}
@@ -1444,12 +1410,12 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
ath_rc_priv->neg_ht_rates.rs_nrates = j;
}
- is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
if (is_cw40)
- is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
- is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+ is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
/* Choose rate table first */
@@ -1468,10 +1434,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
struct ath_rate_priv *ath_rc_priv = priv_sta;
const struct ath_rate_table *rate_table = NULL;
bool oper_cw40 = false, oper_sgi;
- bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
- true : false;
- bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
- true : false;
+ bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
+ bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG);
/* FIXME: Handle AP mode later when we support CWM */
@@ -1499,9 +1463,9 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
oper_cw40, oper_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Operating HT Bandwidth changed to: %d\n",
- sc->hw->conf.channel_type);
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Operating HT Bandwidth changed to: %d\n",
+ sc->hw->conf.channel_type);
}
}
}
@@ -1612,13 +1576,11 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
if (!rate_priv) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to allocate private rc structure\n");
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to allocate private rc structure\n");
return NULL;
}
- rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
-
return rate_priv;
}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 2f46a2266ba1..5d984b8acdb1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -195,7 +195,6 @@ struct ath_rc_stats {
* @rate_max_phy: phy index for the max rate
* @per: PER for every valid rate in %
* @probe_interval: interval for ratectrl to probe for other rates
- * @prev_data_rix: rate idx of last data frame
* @ht_cap: HT capabilities
* @neg_rates: Negotatied rates
* @neg_ht_rates: Negotiated HT rates
@@ -214,22 +213,14 @@ struct ath_rate_priv {
u32 probe_time;
u32 per_down_time;
u32 probe_interval;
- u32 prev_data_rix;
- u32 tx_triglevel_max;
struct ath_rateset neg_rates;
struct ath_rateset neg_ht_rates;
- struct ath_rate_softc *asc;
const struct ath_rate_table *rate_table;
struct dentry *debugfs_rcstats;
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
-#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
-#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1)
-#define ATH_TX_INFO_XRETRY (1 << 3)
-#define ATH_TX_INFO_UNDERRUN (1 << 4)
-
enum ath9k_internal_frame_type {
ATH9K_IFT_NOT_INTERNAL,
ATH9K_IFT_PAUSE,
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 1a62e351ec77..b2497b8601e5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -165,7 +165,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
u32 nbuf = 0;
if (list_empty(&sc->rx.rxbuf)) {
- ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
+ ath_dbg(common, ATH_DBG_QUEUE, "No free rx buf available\n");
return;
}
@@ -269,7 +269,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
+ ath_err(common,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto rx_init_fail;
@@ -317,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
struct ath_buf *bf;
int error = 0;
- spin_lock_init(&sc->rx.pcu_lock);
+ spin_lock_init(&sc->sc_pcu_lock);
sc->sc_flags &= ~SC_OP_RXFLUSH;
spin_lock_init(&sc->rx.rxbuflock);
@@ -327,17 +327,17 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
min(common->cachelsz, (u16)64));
- ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- common->cachelsz, common->rx_bufsize);
+ ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+ common->cachelsz, common->rx_bufsize);
/* Initialize rx descriptors */
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
"rx", nbufs, 1, 0);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "failed to allocate rx descriptors: %d\n",
- error);
+ ath_err(common,
+ "failed to allocate rx descriptors: %d\n",
+ error);
goto err;
}
@@ -358,8 +358,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error() on RX init\n");
+ ath_err(common,
+ "dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto err;
}
@@ -528,6 +528,13 @@ bool ath_stoprecv(struct ath_softc *sc)
sc->rx.rxlink = NULL;
spin_unlock_bh(&sc->rx.rxbuflock);
+ if (!(ah->ah_flags & AH_UNPLUGGED) &&
+ unlikely(!stopped)) {
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Could not stop RX, we could be "
+ "confusing the DMA engine when we start RX up\n");
+ ATH_DBG_WARN_ON_ONCE(!stopped);
+ }
return stopped;
}
@@ -588,9 +595,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (sc->ps_flags & PS_BEACON_SYNC) {
sc->ps_flags &= ~PS_BEACON_SYNC;
- ath_print(common, ATH_DBG_PS,
- "Reconfigure Beacon timers based on "
- "timestamp from the AP\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Reconfigure Beacon timers based on timestamp from the AP\n");
ath_beacon_config(sc, NULL);
}
@@ -602,8 +608,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
* a backup trigger for returning into NETWORK SLEEP state,
* so we are waiting for it as well.
*/
- ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
- "buffered broadcast/multicast frame(s)\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Received DTIM beacon indicating buffered broadcast/multicast frame(s)\n");
sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON;
return;
}
@@ -615,8 +621,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
* been delivered.
*/
sc->ps_flags &= ~PS_WAIT_FOR_CAB;
- ath_print(common, ATH_DBG_PS,
- "PS wait for CAB frames timed out\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "PS wait for CAB frames timed out\n");
}
}
@@ -641,15 +647,14 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
* point.
*/
sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON);
- ath_print(common, ATH_DBG_PS,
- "All PS CAB frames received, back to sleep\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "All PS CAB frames received, back to sleep\n");
} else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
!is_multicast_ether_addr(hdr->addr1) &&
!ieee80211_has_morefrags(hdr->frame_control)) {
sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
- ath_print(common, ATH_DBG_PS,
- "Going back to sleep after having received "
- "PS-Poll data (0x%lx)\n",
+ ath_dbg(common, ATH_DBG_PS,
+ "Going back to sleep after having received PS-Poll data (0x%lx)\n",
sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA |
@@ -658,8 +663,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
}
static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
- struct ath_softc *sc, struct sk_buff *skb,
- struct ieee80211_rx_status *rxs)
+ struct ath_softc *sc, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
@@ -838,6 +842,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
struct ath_rx_status *rx_stats,
bool *decrypt_error)
{
+#define is_mc_or_valid_tkip_keyix ((is_mc || \
+ (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
+ test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
+
struct ath_hw *ah = common->ah;
__le16 fc;
u8 rx_status_len = ah->caps.rx_status_len;
@@ -879,15 +887,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
*decrypt_error = true;
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+ bool is_mc;
/*
* The MIC error bit is only valid if the frame
* is not a control frame or fragment, and it was
* decrypted using a valid TKIP key.
*/
+ is_mc = !!is_multicast_ether_addr(hdr->addr1);
+
if (!ieee80211_is_ctl(fc) &&
!ieee80211_has_morefrags(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
- test_bit(rx_stats->rs_keyix, common->tkip_keymap))
+ is_mc_or_valid_tkip_keyix)
rxs->flag |= RX_FLAG_MMIC_ERROR;
else
rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
@@ -951,8 +962,9 @@ static int ath9k_process_rate(struct ath_common *common,
* No valid hardware bitrate found -- we should not get here
* because hardware has already validated this frame as OK.
*/
- ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
- "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
+ rx_stats->rs_rate);
return -EINVAL;
}
@@ -962,36 +974,23 @@ static void ath9k_process_rssi(struct ath_common *common,
struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats)
{
+ struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = common->ah;
- struct ieee80211_sta *sta;
- struct ath_node *an;
- int last_rssi = ATH_RSSI_DUMMY_MARKER;
+ int last_rssi;
__le16 fc;
+ if (ah->opmode != NL80211_IFTYPE_STATION)
+ return;
+
fc = hdr->frame_control;
+ if (!ieee80211_is_beacon(fc) ||
+ compare_ether_addr(hdr->addr3, common->curbssid))
+ return;
- rcu_read_lock();
- /*
- * XXX: use ieee80211_find_sta! This requires quite a bit of work
- * under the current ath9k virtual wiphy implementation as we have
- * no way of tying a vif to wiphy. Typically vifs are attached to
- * at least one sdata of a wiphy on mac80211 but with ath9k virtual
- * wiphy you'd have to iterate over every wiphy and each sdata.
- */
- if (is_multicast_ether_addr(hdr->addr1))
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
- else
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
-
- if (sta) {
- an = (struct ath_node *) sta->drv_priv;
- if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
- !rx_stats->rs_moreaggr)
- ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
- last_rssi = an->last_rssi;
- }
- rcu_read_unlock();
+ if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
+ ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
+ last_rssi = aphy->last_rssi;
if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
ATH_RSSI_EP_MULTIPLIER);
@@ -999,8 +998,7 @@ static void ath9k_process_rssi(struct ath_common *common,
rx_stats->rs_rssi = 0;
/* Update Beacon RSSI, this is used by ANI. */
- if (ieee80211_is_beacon(fc))
- ah->stats.avgbrssi = rx_stats->rs_rssi;
+ ah->stats.avgbrssi = rx_stats->rs_rssi;
}
/*
@@ -1630,7 +1628,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
/*
- * The hw can techncically differ from common->hw when using ath9k
+ * The hw can technically differ from common->hw when using ath9k
* virtual wiphy so to account for that we iterate over the active
* wiphys and find the appropriate wiphy and therefore hw.
*/
@@ -1737,9 +1735,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error() on RX\n");
- ath_rx_send_to_mac80211(hw, sc, skb, rxs);
+ ath_err(common, "dma_mapping_error() on RX\n");
+ ath_rx_send_to_mac80211(hw, sc, skb);
break;
}
@@ -1755,17 +1752,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
}
spin_lock_irqsave(&sc->sc_pm_lock, flags);
- if (unlikely(ath9k_check_auto_sleep(sc) ||
- (sc->ps_flags & (PS_WAIT_FOR_BEACON |
+
+ if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA))))
+ PS_WAIT_FOR_PSPOLL_DATA)) ||
+ unlikely(ath9k_check_auto_sleep(sc)))
ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
ath_ant_comb_scan(sc, &rs);
- ath_rx_send_to_mac80211(hw, sc, skb, rxs);
+ ath_rx_send_to_mac80211(hw, sc, skb);
requeue:
if (edma) {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index dddf579aacf1..4df5659c6c16 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -787,6 +787,8 @@
#define AR_SREV_REVISION_9271_11 1
#define AR_SREV_VERSION_9300 0x1c0
#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
+#define AR_SREV_VERSION_9485 0x240
+#define AR_SREV_REVISION_9485_10 0
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -859,20 +861,24 @@
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
+#define AR_SREV_9485(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
+#define AR_SREV_9485_10(_ah) \
+ (AR_SREV_9485(_ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
+
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
-#define AR_DEVID_7010(_ah) \
- (((_ah)->hw_version.devid == 0x7010) || \
- ((_ah)->hw_version.devid == 0x7015) || \
- ((_ah)->hw_version.devid == 0x9018) || \
- ((_ah)->hw_version.devid == 0xA704) || \
- ((_ah)->hw_version.devid == 0x1200))
+enum ath_usb_dev {
+ AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
+ AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
+};
-#define AR9287_HTC_DEVID(_ah) \
- (((_ah)->hw_version.devid == 0x7015) || \
- ((_ah)->hw_version.devid == 0x1200))
+#define AR_DEVID_7010(_ah) \
+ (((_ah)->hw_version.usbdev == AR9280_USB) || \
+ ((_ah)->hw_version.usbdev == AR9287_USB))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -984,11 +990,13 @@ enum {
#define AR9287_GPIO_IN_VAL_S 11
#define AR9271_GPIO_IN_VAL 0xFFFF0000
#define AR9271_GPIO_IN_VAL_S 16
-#define AR9300_GPIO_IN_VAL 0x0001FFFF
-#define AR9300_GPIO_IN_VAL_S 0
#define AR7010_GPIO_IN_VAL 0x0000FFFF
#define AR7010_GPIO_IN_VAL_S 0
+#define AR_GPIO_IN 0x404c
+#define AR9300_GPIO_IN_VAL 0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S 0
+
#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
#define AR_GPIO_OE_OUT_DRV 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0
@@ -1072,6 +1080,9 @@ enum {
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
#define AR_INTR_PRIO_SYNC_MASK 0x40cc
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_ENT_OTP 0x40d8
+#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
+#define AR_ENT_OTP_MPSD 0x00800000
#define AR_RTC_9300_PLL_DIV 0x000003ff
#define AR_RTC_9300_PLL_DIV_S 0
@@ -1109,6 +1120,8 @@ enum {
#define AR_RTC_PLL_CONTROL \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
+#define AR_RTC_PLL_CONTROL2 0x703c
+
#define AR_RTC_PLL_DIV 0x0000001f
#define AR_RTC_PLL_DIV_S 0
#define AR_RTC_PLL_DIV2 0x00000020
@@ -1572,6 +1585,7 @@ enum {
#define AR_PCU_TBTT_PROTECT 0x00200000
#define AR_PCU_CLEAR_VMF 0x01000000
#define AR_PCU_CLEAR_BA_VALID 0x04000000
+#define AR_PCU_ALWAYS_PERFORM_KEYSEARCH 0x10000000
#define AR_PCU_BT_ANT_PREVENT_RX 0x00100000
#define AR_PCU_BT_ANT_PREVENT_RX_S 20
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index ec7cf5ee56bc..2dc7095e56d1 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
aphy->sc = sc;
aphy->hw = hw;
sc->sec_wiphy[i] = aphy;
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
spin_unlock_bh(&sc->wiphy_lock);
memcpy(addr, common->macaddr, ETH_ALEN);
@@ -186,7 +187,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
info->control.rates[1].idx = -1;
memset(&txctl, 0, sizeof(struct ath_tx_control));
- txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]];
+ txctl.txq = sc->tx.txq_map[WME_AC_VO];
txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
@@ -287,7 +288,6 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
/* sync hw configuration for hw code */
common->hw = aphy->hw;
- ath_update_chainmask(sc, sc->chan_is_ht);
if (ath_set_channel(sc, aphy->hw,
&sc->sc_ah->channels[sc->chan_idx]) < 0) {
printk(KERN_DEBUG "ath9k: Failed to set channel for new "
@@ -304,13 +304,12 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
* ath9k version of ieee80211_tx_status() for TX frames that are generated
* internally in the driver.
*/
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype)
{
struct ath_wiphy *aphy = hw->priv;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) &&
- aphy->state == ATH_WIPHY_PAUSING) {
+ if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) {
if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) {
printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
"frame\n", wiphy_name(hw->wiphy));
@@ -656,10 +655,9 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
struct ath_softc *sc = aphy->sc;
aphy->idle = idle;
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Marking %s as %s\n",
- wiphy_name(aphy->hw->wiphy),
- idle ? "idle" : "not-idle");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Marking %s as %sidle\n",
+ wiphy_name(aphy->hw->wiphy), idle ? "" : "not-");
}
/* Only bother starting a queue on an active virtual wiphy */
bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 93a8bda09c25..dc862f5e1162 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -120,17 +120,27 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
kfree(priv->wmi);
}
-void ath9k_wmi_tasklet(unsigned long data)
+void ath9k_swba_tasklet(unsigned long data)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ath_common *common = ath9k_hw_common(priv->ah);
- ath_print(common, ATH_DBG_WMI, "SWBA Event received\n");
+ ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n");
ath9k_htc_swba(priv, priv->wmi->beacon_pending);
}
+void ath9k_fatal_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ fatal_work);
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+
+ ath_dbg(common, ATH_DBG_FATAL, "FATAL Event received, resetting device\n");
+ ath9k_htc_reset(priv);
+}
+
static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
{
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
@@ -163,7 +173,11 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
switch (cmd_id) {
case WMI_SWBA_EVENTID:
wmi->beacon_pending = *(u8 *)wmi_event;
- tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
+ tasklet_schedule(&wmi->drv_priv->swba_tasklet);
+ break;
+ case WMI_FATAL_EVENTID:
+ ieee80211_queue_work(wmi->drv_priv->hw,
+ &wmi->drv_priv->fatal_work);
break;
case WMI_TXRATE_EVENTID:
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
@@ -250,7 +264,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
int time_left, ret = 0;
unsigned long flags;
- if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
+ if (ah->ah_flags & AH_UNPLUGGED)
return 0;
skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
@@ -286,9 +300,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
if (!time_left) {
- ath_print(common, ATH_DBG_WMI,
- "Timeout waiting for WMI command: %s\n",
- wmi_cmd_to_name(cmd_id));
+ ath_dbg(common, ATH_DBG_WMI,
+ "Timeout waiting for WMI command: %s\n",
+ wmi_cmd_to_name(cmd_id));
mutex_unlock(&wmi->op_mutex);
return -ETIMEDOUT;
}
@@ -298,8 +312,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
return 0;
out:
- ath_print(common, ATH_DBG_WMI,
- "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
+ ath_dbg(common, ATH_DBG_WMI,
+ "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
mutex_unlock(&wmi->op_mutex);
kfree_skb(skb);
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index ac61074af8ac..42084277522d 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -117,7 +117,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
u8 *cmd_buf, u32 cmd_len,
u8 *rsp_buf, u32 rsp_len,
u32 timeout);
-void ath9k_wmi_tasklet(unsigned long data);
+void ath9k_swba_tasklet(unsigned long data);
+void ath9k_fatal_work(struct work_struct *work);
#define WMI_CMD(_wmi_cmd) \
do { \
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f2ade2402ce2..332d1feb5c18 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -48,19 +48,17 @@ static u16 bits_per_symbol[][2] = {
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head);
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head);
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
struct ath_tx_status *ts, int txok, int sendbar);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
struct list_head *head);
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_status *ts, int txok);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
- int nbad, int txok, bool update_rc);
+ int nframes, int nbad, int txok, bool update_rc);
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
int seqno);
@@ -124,7 +122,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_txq *txq = tid->ac->txq;
WARN_ON(!tid->paused);
@@ -140,12 +138,21 @@ unlock:
spin_unlock_bh(&txq->axq_lock);
}
+static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ BUILD_BUG_ON(sizeof(struct ath_frame_info) >
+ sizeof(tx_info->rate_driver_data));
+ return (struct ath_frame_info *) &tx_info->rate_driver_data[0];
+}
+
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_txq *txq = tid->ac->txq;
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
+ struct ath_frame_info *fi;
INIT_LIST_HEAD(&bf_head);
@@ -156,12 +163,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
list_move_tail(&bf->list, &bf_head);
- if (bf_isretried(bf)) {
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ spin_unlock_bh(&txq->axq_lock);
+ fi = get_frame_info(bf->bf_mpdu);
+ if (fi->retries) {
+ ath_tx_update_baw(sc, tid, fi->seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
} else {
- ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+ ath_tx_send_normal(sc, txq, tid, &bf_head);
}
+ spin_lock_bh(&txq->axq_lock);
}
spin_unlock_bh(&txq->axq_lock);
@@ -184,14 +194,11 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
}
static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
- struct ath_buf *bf)
+ u16 seqno)
{
int index, cindex;
- if (bf_isretried(bf))
- return;
-
- index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+ index = ATH_BA_INDEX(tid->seq_start, seqno);
cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
__set_bit(cindex, tid->tx_buf);
@@ -215,6 +222,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
+ struct ath_frame_info *fi;
memset(&ts, 0, sizeof(ts));
INIT_LIST_HEAD(&bf_head);
@@ -226,8 +234,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
list_move_tail(&bf->list, &bf_head);
- if (bf_isretried(bf))
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ fi = get_frame_info(bf->bf_mpdu);
+ if (fi->retries)
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock(&txq->axq_lock);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
@@ -239,16 +248,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
}
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf)
+ struct sk_buff *skb)
{
- struct sk_buff *skb;
+ struct ath_frame_info *fi = get_frame_info(skb);
struct ieee80211_hdr *hdr;
- bf->bf_state.bf_type |= BUF_RETRY;
- bf->bf_retries++;
TX_STAT_INC(txq->axq_qnum, a_retries);
+ if (fi->retries++ > 0)
+ return;
- skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
}
@@ -298,9 +306,41 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
return tbf;
}
+static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts, int txok,
+ int *nframes, int *nbad)
+{
+ struct ath_frame_info *fi;
+ u16 seq_st = 0;
+ u32 ba[WME_BA_BMP_SIZE >> 5];
+ int ba_index;
+ int isaggr = 0;
+
+ *nbad = 0;
+ *nframes = 0;
+
+ isaggr = bf_isaggr(bf);
+ if (isaggr) {
+ seq_st = ts->ts_seqnum;
+ memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+ }
+
+ while (bf) {
+ fi = get_frame_info(bf->bf_mpdu);
+ ba_index = ATH_BA_INDEX(seq_st, fi->seqno);
+
+ (*nframes)++;
+ if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+ (*nbad)++;
+
+ bf = bf->bf_next;
+ }
+}
+
+
static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct list_head *bf_q,
- struct ath_tx_status *ts, int txok)
+ struct ath_tx_status *ts, int txok, bool retry)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
@@ -316,7 +356,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
struct ieee80211_tx_rate rates[4];
+ struct ath_frame_info *fi;
int nframes;
+ u8 tidno;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -325,7 +367,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
hw = bf->aphy->hw;
memcpy(rates, tx_info->control.rates, sizeof(rates));
- nframes = bf->bf_nframes;
rcu_read_lock();
@@ -342,7 +383,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!bf->bf_stale || bf_next != NULL)
list_move_tail(&bf->list, &bf_head);
- ath_tx_rc_status(bf, ts, 1, 0, false);
+ ath_tx_rc_status(bf, ts, 1, 1, 0, false);
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
0, 0);
@@ -352,14 +393,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
an = (struct ath_node *)sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+ tid = ATH_AN_2_TID(an, tidno);
/*
* The hardware occasionally sends a tx status for the wrong TID.
* In this case, the BA status cannot be considered valid and all
* subframes need to be retransmitted
*/
- if (bf->bf_tidno != ts->tid)
+ if (tidno != ts->tid)
txok = false;
isaggr = bf_isaggr(bf);
@@ -385,15 +427,16 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_pending);
INIT_LIST_HEAD(&bf_head);
- nbad = ath_tx_num_badfrms(sc, bf, ts, txok);
+ ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
while (bf) {
txfail = txpending = 0;
bf_next = bf->bf_next;
skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
+ fi = get_frame_info(skb);
- if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
+ if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) {
/* transmit completion, subframe is
* acked by block ack */
acked_cnt++;
@@ -401,10 +444,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* transmit completion */
acked_cnt++;
} else {
- if (!(tid->state & AGGR_CLEANUP) &&
- !bf_last->bf_tx_aborted) {
- if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
- ath_tx_set_retry(sc, txq, bf);
+ if (!(tid->state & AGGR_CLEANUP) && retry) {
+ if (fi->retries < ATH_MAX_SW_RETRIES) {
+ ath_tx_set_retry(sc, txq, bf->bf_mpdu);
txpending = 1;
} else {
bf->bf_state.bf_type |= BUF_XRETRY;
@@ -442,16 +484,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
* block-ack window
*/
spin_lock_bh(&txq->axq_lock);
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock_bh(&txq->axq_lock);
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
memcpy(tx_info->control.rates, rates, sizeof(rates));
- bf->bf_nframes = nframes;
- ath_tx_rc_status(bf, ts, nbad, txok, true);
+ ath_tx_rc_status(bf, ts, nframes, nbad, txok, true);
rc_update = false;
} else {
- ath_tx_rc_status(bf, ts, nbad, txok, false);
+ ath_tx_rc_status(bf, ts, nframes, nbad, txok, false);
}
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
@@ -470,14 +511,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
*/
if (!tbf) {
spin_lock_bh(&txq->axq_lock);
- ath_tx_update_baw(sc, tid,
- bf->bf_seqno);
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock_bh(&txq->axq_lock);
bf->bf_state.bf_type |=
BUF_XRETRY;
- ath_tx_rc_status(bf, ts, nbad,
- 0, false);
+ ath_tx_rc_status(bf, ts, nframes,
+ nbad, 0, false);
ath_tx_complete_buf(sc, bf, txq,
&bf_head,
ts, 0, 0);
@@ -611,6 +651,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
u16 minlen;
u8 flags, rix;
int width, streams, half_gi, ndelim, mindelim;
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
/* Select standard number of delimiters based on frame length alone */
ndelim = ATH_AGGR_GET_NDELIM(frmlen);
@@ -621,7 +662,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
* TODO - this could be improved to be dependent on the rate.
* The hardware can keep up at lower rates, but not higher rates
*/
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
+ if (fi->keyix != ATH9K_TXKEYIX_INVALID)
ndelim += ATH_AGGR_ENCRYPTDELIM;
/*
@@ -665,7 +706,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct list_head *bf_q)
+ struct list_head *bf_q,
+ int *aggr_len)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
struct ath_buf *bf, *bf_first, *bf_prev = NULL;
@@ -674,14 +716,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
al_delta, h_baw = tid->baw_size / 2;
enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
struct ieee80211_tx_info *tx_info;
+ struct ath_frame_info *fi;
bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
do {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ fi = get_frame_info(bf->bf_mpdu);
/* do not step over block-ack window */
- if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
+ if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
status = ATH_AGGR_BAW_CLOSED;
break;
}
@@ -692,7 +736,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
}
/* do not exceed aggregation limit */
- al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
+ al_delta = ATH_AGGR_DELIM_SZ + fi->framelen;
if (nframes &&
(aggr_limit < (al + bpad + al_delta + prev_al))) {
@@ -719,14 +763,15 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
* Get the delimiters needed to meet the MPDU
* density for this node.
*/
- ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
+ ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen);
bpad = PADBYTES(al_delta) + (ndelim << 2);
bf->bf_next = NULL;
ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
/* link buffers of this frame to the aggregate */
- ath_tx_addto_baw(sc, tid, bf);
+ if (!fi->retries)
+ ath_tx_addto_baw(sc, tid, fi->seqno);
ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
list_move_tail(&bf->list, bf_q);
if (bf_prev) {
@@ -738,8 +783,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
} while (!list_empty(&tid->buf_q));
- bf_first->bf_al = al;
- bf_first->bf_nframes = nframes;
+ *aggr_len = al;
return status;
#undef PADBYTES
@@ -750,7 +794,9 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
{
struct ath_buf *bf;
enum ATH_AGGR_STATUS status;
+ struct ath_frame_info *fi;
struct list_head bf_q;
+ int aggr_len;
do {
if (list_empty(&tid->buf_q))
@@ -758,7 +804,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_q);
- status = ath_tx_form_aggr(sc, txq, tid, &bf_q);
+ status = ath_tx_form_aggr(sc, txq, tid, &bf_q, &aggr_len);
/*
* no frames picked up to be aggregated;
@@ -771,18 +817,20 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
/* if only one frame, send as non-aggregate */
- if (bf->bf_nframes == 1) {
+ if (bf == bf->bf_lastbf) {
+ fi = get_frame_info(bf->bf_mpdu);
+
bf->bf_state.bf_type &= ~BUF_AGGR;
ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
- ath_buf_set_rate(sc, bf);
+ ath_buf_set_rate(sc, bf, fi->framelen);
ath_tx_txqaddbuf(sc, txq, &bf_q);
continue;
}
/* setup first desc of aggregate */
bf->bf_state.bf_type |= BUF_AGGR;
- ath_buf_set_rate(sc, bf);
- ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
+ ath_buf_set_rate(sc, bf, aggr_len);
+ ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len);
/* anchor last desc of aggregate */
ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
@@ -790,7 +838,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_txqaddbuf(sc, txq, &bf_q);
TX_STAT_INC(txq->axq_qnum, a_aggr);
- } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
+ } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
status != ATH_AGGR_BAW_CLOSED);
}
@@ -817,7 +865,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+ struct ath_txq *txq = txtid->ac->txq;
if (txtid->state & AGGR_CLEANUP)
return;
@@ -888,10 +936,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi;
+ static const int subtype_txq_to_hwq[] = {
+ [WME_AC_BE] = ATH_TXQ_AC_BE,
+ [WME_AC_BK] = ATH_TXQ_AC_BK,
+ [WME_AC_VI] = ATH_TXQ_AC_VI,
+ [WME_AC_VO] = ATH_TXQ_AC_VO,
+ };
int qnum, i;
memset(&qi, 0, sizeof(qi));
- qi.tqi_subtype = subtype;
+ qi.tqi_subtype = subtype_txq_to_hwq[subtype];
qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
@@ -931,22 +985,21 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
return NULL;
}
if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
- ath_print(common, ATH_DBG_FATAL,
- "qnum %u out of range, max %u!\n",
- qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
+ ath_err(common, "qnum %u out of range, max %zu!\n",
+ qnum, ARRAY_SIZE(sc->tx.txq));
ath9k_hw_releasetxqueue(ah, qnum);
return NULL;
}
if (!ATH_TXQ_SETUP(sc, qnum)) {
struct ath_txq *txq = &sc->tx.txq[qnum];
- txq->axq_class = subtype;
txq->axq_qnum = qnum;
txq->axq_link = NULL;
INIT_LIST_HEAD(&txq->axq_q);
INIT_LIST_HEAD(&txq->axq_acq);
spin_lock_init(&txq->axq_lock);
txq->axq_depth = 0;
+ txq->axq_ampdu_depth = 0;
txq->axq_tx_inprogress = false;
sc->tx.txqsetup |= 1<<qnum;
@@ -985,8 +1038,8 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
qi.tqi_readyTime = qinfo->tqi_readyTime;
if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to update hardware queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
ath9k_hw_resettxqueue(ah, qnum);
@@ -1016,6 +1069,12 @@ int ath_cabq_update(struct ath_softc *sc)
return 0;
}
+static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
+ return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
+}
+
/*
* Drain a given TX queue (could be Beacon or Data)
*
@@ -1062,8 +1121,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
}
lastbf = bf->bf_lastbf;
- if (!retry_tx)
- lastbf->bf_tx_aborted = true;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
list_cut_position(&bf_head,
@@ -1076,11 +1133,13 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
}
txq->axq_depth--;
-
+ if (bf_is_ampdu_not_probing(bf))
+ txq->axq_ampdu_depth--;
spin_unlock_bh(&txq->axq_lock);
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
+ retry_tx);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
}
@@ -1101,7 +1160,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
if (bf_isampdu(bf))
ath_tx_complete_aggr(sc, txq, bf, &bf_head,
- &ts, 0);
+ &ts, 0, retry_tx);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head,
&ts, 0, 0);
@@ -1120,7 +1179,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
}
}
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1128,7 +1187,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
int i, npend = 0;
if (sc->sc_flags & SC_OP_INVALID)
- return;
+ return true;
/* Stop beacon queue */
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -1142,25 +1201,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
}
}
- if (npend) {
- int r;
-
- ath_print(common, ATH_DBG_FATAL,
- "Failed to stop TX DMA. Resetting hardware!\n");
-
- spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
- if (r)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d\n",
- r);
- spin_unlock_bh(&sc->sc_resetlock);
- }
+ if (npend)
+ ath_err(common, "Failed to stop TX DMA!\n");
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i))
ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
}
+
+ return !npend;
}
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
@@ -1212,24 +1261,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
}
}
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
- struct ath_txq *txq;
-
- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->tx.hwq_map));
- return 0;
- }
- txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
- if (txq != NULL) {
- sc->tx.hwq_map[haltype] = txq->axq_qnum;
- return 1;
- } else
- return 0;
-}
-
/***********/
/* TX, DMA */
/***********/
@@ -1255,8 +1286,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(head, struct ath_buf, list);
- ath_print(common, ATH_DBG_QUEUE,
- "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
@@ -1264,47 +1295,45 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
return;
}
if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
- ath_print(common, ATH_DBG_XMIT,
- "Initializing tx fifo %d which "
- "is non-empty\n",
- txq->txq_headidx);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Initializing tx fifo %d which is non-empty\n",
+ txq->txq_headidx);
INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- ath_print(common, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
} else {
list_splice_tail_init(head, &txq->axq_q);
if (txq->axq_link == NULL) {
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- ath_print(common, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr),
- bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr),
+ bf->bf_desc);
} else {
*txq->axq_link = bf->bf_daddr;
- ath_print(common, ATH_DBG_XMIT,
- "link[%u] (%p)=%llx (%p)\n",
- txq->axq_qnum, txq->axq_link,
- ito64(bf->bf_daddr), bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "link[%u] (%p)=%llx (%p)\n",
+ txq->axq_qnum, txq->axq_link,
+ ito64(bf->bf_daddr), bf->bf_desc);
}
ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
&txq->axq_link);
ath9k_hw_txstart(ah, txq->axq_qnum);
}
txq->axq_depth++;
+ if (bf_is_ampdu_not_probing(bf))
+ txq->axq_ampdu_depth++;
}
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
- struct list_head *bf_head,
- struct ath_tx_control *txctl)
+ struct ath_buf *bf, struct ath_tx_control *txctl)
{
- struct ath_buf *bf;
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
+ struct list_head bf_head;
- bf = list_first_entry(bf_head, struct ath_buf, list);
bf->bf_state.bf_type |= BUF_AMPDU;
TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
@@ -1316,56 +1345,47 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
* - h/w queue depth exceeds low water mark
*/
if (!list_empty(&tid->buf_q) || tid->paused ||
- !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
- txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+ !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
+ txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
/*
* Add this frame to software queue for scheduling later
* for aggregation.
*/
- list_move_tail(&bf->list, &tid->buf_q);
+ list_add_tail(&bf->list, &tid->buf_q);
ath_tx_queue_tid(txctl->txq, tid);
return;
}
+ INIT_LIST_HEAD(&bf_head);
+ list_add(&bf->list, &bf_head);
+
/* Add sub-frame to BAW */
- ath_tx_addto_baw(sc, tid, bf);
+ if (!fi->retries)
+ ath_tx_addto_baw(sc, tid, fi->seqno);
/* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
bf->bf_lastbf = bf;
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+ ath_buf_set_rate(sc, bf, fi->framelen);
+ ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
}
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head)
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head)
{
+ struct ath_frame_info *fi;
struct ath_buf *bf;
bf = list_first_entry(bf_head, struct ath_buf, list);
bf->bf_state.bf_type &= ~BUF_AMPDU;
/* update starting sequence number for subsequent ADDBA request */
- INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf;
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txq, bf_head);
- TX_STAT_INC(txq->axq_qnum, queued);
-}
-
-static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *bf_head)
-{
- struct ath_buf *bf;
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
+ if (tid)
+ INCR(tid->seq_start, IEEE80211_SEQ_MAX);
bf->bf_lastbf = bf;
- bf->bf_nframes = 1;
- ath_buf_set_rate(sc, bf);
+ fi = get_frame_info(bf->bf_mpdu);
+ ath_buf_set_rate(sc, bf, fi->framelen);
ath_tx_txqaddbuf(sc, txq, bf_head);
TX_STAT_INC(txq->axq_qnum, queued);
}
@@ -1393,40 +1413,52 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
- struct ath_buf *bf)
+static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
+ int framelen)
{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = tx_info->control.sta;
+ struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
struct ieee80211_hdr *hdr;
+ struct ath_frame_info *fi = get_frame_info(skb);
struct ath_node *an;
struct ath_atx_tid *tid;
- __le16 fc;
- u8 *qc;
+ enum ath9k_key_type keytype;
+ u16 seqno = 0;
+ u8 tidno;
- if (!tx_info->control.sta)
- return;
+ keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
+ if (sta && ieee80211_is_data_qos(hdr->frame_control) &&
+ conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
+
+ an = (struct ath_node *) sta->drv_priv;
+ tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
- if (ieee80211_is_data_qos(fc)) {
- qc = ieee80211_get_qos_ctl(hdr);
- bf->bf_tidno = qc[0] & 0xf;
+ /*
+ * Override seqno set by upper layer with the one
+ * in tx aggregation state.
+ */
+ tid = ATH_AN_2_TID(an, tidno);
+ seqno = tid->seq_next;
+ hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+ INCR(tid->seq_next, IEEE80211_SEQ_MAX);
}
- /*
- * For HT capable stations, we save tidno for later use.
- * We also override seqno set by upper layer with the one
- * in tx aggregation state.
- */
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
- hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
- bf->bf_seqno = tid->seq_next;
- INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+ memset(fi, 0, sizeof(*fi));
+ if (hw_key)
+ fi->keyix = hw_key->hw_key_idx;
+ else
+ fi->keyix = ATH9K_TXKEYIX_INVALID;
+ fi->keytype = keytype;
+ fi->framelen = framelen;
+ fi->seqno = seqno;
}
-static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
+static int setup_tx_flags(struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int flags = 0;
@@ -1437,7 +1469,7 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= ATH9K_TXDESC_NOACK;
- if (use_ldpc)
+ if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
flags |= ATH9K_TXDESC_LDPC;
return flags;
@@ -1449,13 +1481,11 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
* width - 0 for 20 MHz, 1 for 40 MHz
* half_gi - to use 4us v/s 3.6 us for symbol time
*/
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
int width, int half_gi, bool shortPreamble)
{
u32 nbits, nsymbits, duration, nsymbols;
- int streams, pktlen;
-
- pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+ int streams;
/* find number of symbols: PLCP + data */
streams = HT_RC_2_STREAMS(rix);
@@ -1474,7 +1504,19 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
return duration;
}
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_channel *curchan = ah->curchan;
+ if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
+ (curchan->channelFlags & CHANNEL_5GHZ) &&
+ (chainmask == 0x7) && (rate < 0x90))
+ return 0x3;
+ else
+ return chainmask;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_11n_rate_series series[4];
@@ -1514,7 +1556,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
rix = rates[i].idx;
series[i].Tries = rates[i].count;
- series[i].ChSel = common->tx_chainmask;
if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
@@ -1537,14 +1578,16 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
if (rates[i].flags & IEEE80211_TX_RC_MCS) {
/* MCS rates */
series[i].Rate = rix | 0x80;
- series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+ series[i].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[i].Rate);
+ series[i].PktDuration = ath_pkt_duration(sc, rix, len,
is_40, is_sgi, is_sp);
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
series[i].RateFlags |= ATH9K_RATESERIES_STBC;
continue;
}
- /* legcay rates */
+ /* legacy rates */
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
!(rate->flags & IEEE80211_RATE_ERP_G))
phy = WLAN_RC_PHY_CCK;
@@ -1560,12 +1603,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
is_sp = false;
}
+ if (bf->bf_state.bfs_paprd)
+ series[i].ChSel = common->tx_chainmask;
+ else
+ series[i].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[i].Rate);
+
series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
- phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
+ phy, rate->bitrate * 100, len, rix, is_sp);
}
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
- if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+ if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
flags &= ~ATH9K_TXDESC_RTSENA;
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
@@ -1582,67 +1631,29 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
-static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
- struct sk_buff *skb,
- struct ath_tx_control *txctl)
+static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
+ struct ath_txq *txq,
+ struct sk_buff *skb)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- int hdrlen;
- __le16 fc;
- int padpos, padsize;
- bool use_ldpc = false;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_frame_info *fi = get_frame_info(skb);
+ struct ath_buf *bf;
+ struct ath_desc *ds;
+ int frm_type;
- tx_info->pad[0] = 0;
- switch (txctl->frame_type) {
- case ATH9K_IFT_NOT_INTERNAL:
- break;
- case ATH9K_IFT_PAUSE:
- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE;
- /* fall through */
- case ATH9K_IFT_UNPAUSE:
- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL;
- break;
+ bf = ath_tx_get_buffer(sc);
+ if (!bf) {
+ ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n");
+ return NULL;
}
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- fc = hdr->frame_control;
ATH_TXBUF_RESET(bf);
bf->aphy = aphy;
- bf->bf_frmlen = skb->len + FCS_LEN;
- /* Remove the padding size from bf_frmlen, if any */
- padpos = ath9k_cmn_padpos(hdr->frame_control);
- padsize = padpos & 3;
- if (padsize && skb->len>padpos+padsize) {
- bf->bf_frmlen -= padsize;
- }
-
- if (!txctl->paprd && conf_is_ht(&hw->conf)) {
- bf->bf_state.bf_type |= BUF_HT;
- if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
- use_ldpc = true;
- }
-
- bf->bf_state.bfs_paprd = txctl->paprd;
- if (txctl->paprd)
- bf->bf_state.bfs_paprd_timestamp = jiffies;
- bf->bf_flags = setup_tx_flags(skb, use_ldpc);
-
- bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
- bf->bf_frmlen += tx_info->control.hw_key->icv_len;
- bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
- } else {
- bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
- }
-
- if (ieee80211_is_data_qos(fc) && bf_isht(bf) &&
- (sc->sc_flags & SC_OP_TXAGGR))
- assign_aggr_tid_seqno(skb, bf);
-
+ bf->bf_flags = setup_tx_flags(skb);
bf->bf_mpdu = skb;
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
@@ -1650,42 +1661,19 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "dma_mapping_error() on TX\n");
- return -ENOMEM;
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "dma_mapping_error() on TX\n");
+ ath_tx_return_buffer(sc, bf);
+ return NULL;
}
- bf->bf_tx_aborted = false;
-
- return 0;
-}
-
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_control *txctl)
-{
- struct sk_buff *skb = bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ath_node *an = NULL;
- struct list_head bf_head;
- struct ath_desc *ds;
- struct ath_atx_tid *tid;
- struct ath_hw *ah = sc->sc_ah;
- int frm_type;
- __le16 fc;
-
frm_type = get_hw_packet_type(skb);
- fc = hdr->frame_control;
-
- INIT_LIST_HEAD(&bf_head);
- list_add_tail(&bf->list, &bf_head);
ds = bf->bf_desc;
ath9k_hw_set_desc_link(ah, ds, 0);
- ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
- bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
+ ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER,
+ fi->keyix, fi->keytype, bf->bf_flags);
ath9k_hw_filltxdesc(ah, ds,
skb->len, /* segment length */
@@ -1693,42 +1681,53 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
true, /* last segment */
ds, /* first descriptor */
bf->bf_buf_addr,
- txctl->txq->axq_qnum);
+ txq->axq_qnum);
+
- if (bf->bf_state.bfs_paprd)
- ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd);
+ return bf;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_control *txctl)
+{
+ struct sk_buff *skb = bf->bf_mpdu;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct list_head bf_head;
+ struct ath_atx_tid *tid = NULL;
+ u8 tidno;
spin_lock_bh(&txctl->txq->axq_lock);
- if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
- tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ if (ieee80211_is_data_qos(hdr->frame_control) && txctl->an) {
+ tidno = ieee80211_get_qos_ctl(hdr)[0] &
+ IEEE80211_QOS_CTL_TID_MASK;
+ tid = ATH_AN_2_TID(txctl->an, tidno);
- if (!ieee80211_is_data_qos(fc)) {
- ath_tx_send_normal(sc, txctl->txq, &bf_head);
- goto tx_done;
- }
+ WARN_ON(tid->ac->txq != txctl->txq);
+ }
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- /*
- * Try aggregation if it's a unicast data frame
- * and the destination is HT capable.
- */
- ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
- } else {
- /*
- * Send this frame as regular when ADDBA
- * exchange is neither complete nor pending.
- */
- ath_tx_send_ht_normal(sc, txctl->txq,
- tid, &bf_head);
- }
+ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
+ /*
+ * Try aggregation if it's a unicast data frame
+ * and the destination is HT capable.
+ */
+ ath_tx_send_ampdu(sc, tid, bf, txctl);
} else {
- ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ INIT_LIST_HEAD(&bf_head);
+ list_add_tail(&bf->list, &bf_head);
+
+ bf->bf_state.bfs_ftype = txctl->frame_type;
+ bf->bf_state.bfs_paprd = txctl->paprd;
+
+ if (bf->bf_state.bfs_paprd)
+ ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
+ bf->bf_state.bfs_paprd);
+
+ ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
}
-tx_done:
spin_unlock_bh(&txctl->txq->axq_lock);
}
@@ -1736,66 +1735,23 @@ tx_done:
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl)
{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = info->control.sta;
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_txq *txq = txctl->txq;
struct ath_buf *bf;
- int q, r;
-
- bf = ath_tx_get_buffer(sc);
- if (!bf) {
- ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n");
- return -1;
- }
-
- r = ath_tx_setup_buffer(hw, bf, skb, txctl);
- if (unlikely(r)) {
- ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
- /* upon ath_tx_processq() this TX queue will be resumed, we
- * guarantee this will happen by knowing beforehand that
- * we will at least have to run TX completionon one buffer
- * on the queue */
- spin_lock_bh(&txq->axq_lock);
- if (!txq->stopped && txq->axq_depth > 1) {
- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
-
- ath_tx_return_buffer(sc, bf);
-
- return r;
- }
-
- q = skb_get_queue_mapping(skb);
- if (q >= 4)
- q = 0;
-
- spin_lock_bh(&txq->axq_lock);
- if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
-
- ath_tx_start_dma(sc, bf, txctl);
-
- return 0;
-}
-
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
int padpos, padsize;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_tx_control txctl;
+ int frmlen = skb->len + FCS_LEN;
+ int q;
+
+ /* NOTE: sta can be NULL according to net/mac80211.h */
+ if (sta)
+ txctl->an = (struct ath_node *)sta->drv_priv;
- memset(&txctl, 0, sizeof(struct ath_tx_control));
+ if (info->control.hw_key)
+ frmlen += info->control.hw_key->icv_len;
/*
* As a temporary workaround, assign seq# here; this will likely need
@@ -1812,30 +1768,37 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
/* Add the padding after the header if this is not already done */
padpos = ath9k_cmn_padpos(hdr->frame_control);
padsize = padpos & 3;
- if (padsize && skb->len>padpos) {
- if (skb_headroom(skb) < padsize) {
- ath_print(common, ATH_DBG_XMIT,
- "TX CABQ padding failed\n");
- dev_kfree_skb_any(skb);
- return;
- }
+ if (padsize && skb->len > padpos) {
+ if (skb_headroom(skb) < padsize)
+ return -ENOMEM;
+
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
}
- txctl.txq = sc->beacon.cabq;
+ setup_frame_info(hw, skb, frmlen);
- ath_print(common, ATH_DBG_XMIT,
- "transmitting CABQ packet, skb: %p\n", skb);
+ /*
+ * At this point, the vif, hw_key and sta pointers in the tx control
+ * info are no longer valid (overwritten by the ath_frame_info data.
+ */
+
+ bf = ath_tx_setup_buffer(hw, txctl->txq, skb);
+ if (unlikely(!bf))
+ return -ENOMEM;
- if (ath_tx_start(hw, skb, &txctl) != 0) {
- ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n");
- goto exit;
+ q = skb_get_queue_mapping(skb);
+ spin_lock_bh(&txq->axq_lock);
+ if (txq == sc->tx.txq_map[q] &&
+ ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
+ ath_mac80211_stop_queue(sc, q);
+ txq->stopped = 1;
}
+ spin_unlock_bh(&txq->axq_lock);
- return;
-exit:
- dev_kfree_skb_any(skb);
+ ath_tx_start_dma(sc, bf, txctl);
+
+ return 0;
}
/*****************/
@@ -1843,7 +1806,8 @@ exit:
/*****************/
static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_wiphy *aphy, int tx_flags)
+ struct ath_wiphy *aphy, int tx_flags, int ftype,
+ struct ath_txq *txq)
{
struct ieee80211_hw *hw = sc->hw;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1851,7 +1815,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
int q, padpos, padsize;
- ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+ ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
if (aphy)
hw = aphy->hw;
@@ -1877,24 +1841,24 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
- ath_print(common, ATH_DBG_PS,
- "Going back to sleep after having "
- "received TX status (0x%lx)\n",
+ ath_dbg(common, ATH_DBG_PS,
+ "Going back to sleep after having received TX status (0x%lx)\n",
sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA |
PS_WAIT_FOR_TX_ACK));
}
- if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
- ath9k_tx_status(hw, skb);
+ if (unlikely(ftype))
+ ath9k_tx_status(hw, skb, ftype);
else {
q = skb_get_queue_mapping(skb);
- if (q >= 4)
- q = 0;
-
- if (--sc->tx.pending_frames[q] < 0)
- sc->tx.pending_frames[q] = 0;
+ if (txq == sc->tx.txq_map[q]) {
+ spin_lock_bh(&txq->axq_lock);
+ if (WARN_ON(--txq->pending_frames < 0))
+ txq->pending_frames = 0;
+ spin_unlock_bh(&txq->axq_lock);
+ }
ieee80211_tx_status(hw, skb);
}
@@ -1922,15 +1886,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
bf->bf_buf_addr = 0;
if (bf->bf_state.bfs_paprd) {
- if (time_after(jiffies,
- bf->bf_state.bfs_paprd_timestamp +
- msecs_to_jiffies(ATH_PAPRD_TIMEOUT)))
+ if (!sc->paprd_pending)
dev_kfree_skb_any(skb);
else
complete(&sc->paprd_complete);
} else {
- ath_debug_stat_tx(sc, txq, bf, ts);
- ath_tx_complete(sc, skb, bf->aphy, tx_flags);
+ ath_debug_stat_tx(sc, bf, ts);
+ ath_tx_complete(sc, skb, bf->aphy, tx_flags,
+ bf->bf_state.bfs_ftype, txq);
}
/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
* accidentally reference it later.
@@ -1945,42 +1908,15 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
}
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_status *ts, int txok)
-{
- u16 seq_st = 0;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int ba_index;
- int nbad = 0;
- int isaggr = 0;
-
- if (bf->bf_lastbf->bf_tx_aborted)
- return 0;
-
- isaggr = bf_isaggr(bf);
- if (isaggr) {
- seq_st = ts->ts_seqnum;
- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
- }
-
- while (bf) {
- ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
- if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
- nbad++;
-
- bf = bf->bf_next;
- }
-
- return nbad;
-}
-
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
- int nbad, int txok, bool update_rc)
+ int nframes, int nbad, int txok, bool update_rc)
{
struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hw *hw = bf->aphy->hw;
+ struct ath_softc *sc = bf->aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
u8 i, tx_rateindex;
if (txok)
@@ -1994,22 +1930,32 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
- BUG_ON(nbad > bf->bf_nframes);
+ BUG_ON(nbad > nframes);
- tx_info->status.ampdu_len = bf->bf_nframes;
- tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
+ tx_info->status.ampdu_len = nframes;
+ tx_info->status.ampdu_ack_len = nframes - nbad;
}
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
- if (ieee80211_is_data(hdr->frame_control)) {
- if (ts->ts_flags &
- (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
- tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
- if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
- (ts->ts_status & ATH9K_TXERR_FIFO))
- tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
- }
+ /*
+ * If an underrun error is seen assume it as an excessive
+ * retry only if max frame trigger level has been reached
+ * (2 KB for single stream, and 4 KB for dual stream).
+ * Adjust the long retry as if the frame was tried
+ * hw->max_rate_tries times to affect how rate control updates
+ * PER for the failed rate.
+ * In case of congestion on the bus penalizing this type of
+ * underruns should help hardware actually transmit new frames
+ * successfully by eventually preferring slower rates.
+ * This itself should also alleviate congestion on the bus.
+ */
+ if (ieee80211_is_data(hdr->frame_control) &&
+ (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
+ ATH9K_TX_DELIM_UNDERRUN)) &&
+ ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max)
+ tx_info->status.rates[tx_rateindex].count =
+ hw->max_rate_tries;
}
for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
@@ -2020,16 +1966,13 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
}
-static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
{
- int qnum;
-
- qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
- if (qnum == -1)
- return;
+ struct ath_txq *txq;
+ txq = sc->tx.txq_map[qnum];
spin_lock_bh(&txq->axq_lock);
- if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
+ if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
if (ath_mac80211_start_queue(sc, qnum))
txq->stopped = 0;
}
@@ -2046,10 +1989,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
struct ath_tx_status ts;
int txok;
int status;
+ int qnum;
- ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
- txq->axq_link);
+ ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+ txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+ txq->axq_link);
for (;;) {
spin_lock_bh(&txq->axq_lock);
@@ -2106,6 +2050,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
txq->axq_tx_inprogress = false;
if (bf_held)
list_del(&bf_held->list);
+
+ if (bf_is_ampdu_not_probing(bf))
+ txq->axq_ampdu_depth--;
spin_unlock_bh(&txq->axq_lock);
if (bf_held)
@@ -2118,15 +2065,19 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
*/
if (ts.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
+ ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true);
}
+ qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok,
+ true);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
- ath_wake_mac80211_queue(sc, txq);
+ if (txq == sc->tx.txq_map[qnum])
+ ath_wake_mac80211_queue(sc, qnum);
spin_lock_bh(&txq->axq_lock);
if (sc->sc_flags & SC_OP_TXAGGR)
@@ -2160,8 +2111,8 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
}
if (needreset) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
- "tx hung, resetting the chip\n");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
+ "tx hung, resetting the chip\n");
ath9k_ps_wakeup(sc);
ath_reset(sc, true);
ath9k_ps_restore(sc);
@@ -2196,14 +2147,15 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
struct list_head bf_head;
int status;
int txok;
+ int qnum;
for (;;) {
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
if (status == -EINPROGRESS)
break;
if (status == -EIO) {
- ath_print(common, ATH_DBG_XMIT,
- "Error processing tx status\n");
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Error processing tx status\n");
break;
}
@@ -2229,6 +2181,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
txq->axq_depth--;
txq->axq_tx_inprogress = false;
+ if (bf_is_ampdu_not_probing(bf))
+ txq->axq_ampdu_depth--;
spin_unlock_bh(&txq->axq_lock);
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
@@ -2236,16 +2190,20 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
if (!bf_isampdu(bf)) {
if (txs.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
+ ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true);
}
+ qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
+ txok, true);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head,
&txs, txok, 0);
- ath_wake_mac80211_queue(sc, txq);
+ if (txq == sc->tx.txq_map[qnum])
+ ath_wake_mac80211_queue(sc, qnum);
spin_lock_bh(&txq->axq_lock);
if (!list_empty(&txq->txq_fifo_pending)) {
@@ -2310,16 +2268,16 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
"tx", nbufs, 1, 1);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to allocate tx descriptors: %d\n", error);
+ ath_err(common,
+ "Failed to allocate tx descriptors: %d\n", error);
goto err;
}
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
"beacon", ATH_BCBUF, 1, 1);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to allocate beacon descriptors: %d\n", error);
+ ath_err(common,
+ "Failed to allocate beacon descriptors: %d\n", error);
goto err;
}
@@ -2377,7 +2335,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
for (acno = 0, ac = &an->ac[acno];
acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false;
- ac->qnum = sc->tx.hwq_map[acno];
+ ac->txq = sc->tx.txq_map[acno];
INIT_LIST_HEAD(&ac->tid_q);
}
}
@@ -2387,17 +2345,13 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_ac *ac;
struct ath_atx_tid *tid;
struct ath_txq *txq;
- int i, tidno;
+ int tidno;
for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno++, tid++) {
- i = tid->ac->qnum;
-
- if (!ATH_TXQ_SETUP(sc, i))
- continue;
- txq = &sc->tx.txq[i];
ac = tid->ac;
+ txq = ac->txq;
spin_lock_bh(&txq->axq_lock);
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cf0c9ef47aa..d07ff7f2fd92 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -48,7 +48,7 @@
#include <linux/usb.h>
#ifdef CONFIG_CARL9170_LEDS
#include <linux/leds.h>
-#endif /* CONFIG_CARL170_LEDS */
+#endif /* CONFIG_CARL9170_LEDS */
#ifdef CONFIG_CARL9170_WPC
#include <linux/input.h>
#endif /* CONFIG_CARL9170_WPC */
@@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
CARL9170_RR_WATCHDOG,
CARL9170_RR_STUCK_TX,
- CARL9170_RR_SLOW_SYSTEM,
+ CARL9170_RR_UNRESPONSIVE_DEVICE,
CARL9170_RR_COMMAND_TIMEOUT,
CARL9170_RR_TOO_MANY_PHY_ERRORS,
CARL9170_RR_LOST_RSP,
@@ -287,6 +287,7 @@ struct ar9170 {
/* reset / stuck frames/queue detection */
struct work_struct restart_work;
+ struct work_struct ping_work;
unsigned int restart_counter;
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
index c21f3364bfec..cdfc94c371b4 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.c
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -41,7 +41,7 @@
int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
{
- __le32 buf[2] = {
+ const __le32 buf[2] = {
cpu_to_le32(reg),
cpu_to_le32(val),
};
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index ae6c006bbc56..546b4e4ec5ea 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
if (SUPP(CARL9170FW_WLANTX_CAB)) {
ar->hw->wiphy->interface_modes |=
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO);
}
}
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d552166db505..3680dfc70f46 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -97,13 +97,13 @@ struct carl9170_set_key_cmd {
__le16 type;
u8 macAddr[6];
u32 key[4];
-} __packed;
+} __packed __aligned(4);
#define CARL9170_SET_KEY_CMD_SIZE 28
struct carl9170_disable_key_cmd {
__le16 user;
__le16 padding;
-} __packed;
+} __packed __aligned(4);
#define CARL9170_DISABLE_KEY_CMD_SIZE 4
struct carl9170_u32_list {
@@ -206,7 +206,7 @@ struct carl9170_cmd {
struct carl9170_rx_filter_cmd rx_filter;
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
} __packed;
-} __packed;
+} __packed __aligned(4);
#define CARL9170_TX_STATUS_QUEUE 3
#define CARL9170_TX_STATUS_QUEUE_S 0
@@ -216,6 +216,7 @@ struct carl9170_cmd {
#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
#define CARL9170_TX_STATUS_SUCCESS 0x80
+#ifdef __CARL9170FW__
/*
* NOTE:
* Both structs [carl9170_tx_status and _carl9170_tx_status]
@@ -232,6 +233,8 @@ struct carl9170_tx_status {
u8 tries:3;
u8 success:1;
} __packed;
+#endif /* __CARL9170FW__ */
+
struct _carl9170_tx_status {
/*
* This version should be immune to all alignment bugs.
@@ -272,13 +275,15 @@ struct carl9170_rsp {
struct carl9170_rf_init_result rf_init_res;
struct carl9170_u32_list rreg_res;
struct carl9170_u32_list echo;
+#ifdef __CARL9170FW__
struct carl9170_tx_status tx_status[0];
+#endif /* __CARL9170FW__ */
struct _carl9170_tx_status _tx_status[0];
struct carl9170_gpio gpio;
struct carl9170_tsf_rsp tsf;
struct carl9170_psm psm;
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
} __packed;
-} __packed;
+} __packed __aligned(4);
#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 2f471b3f05af..e85df6edfed3 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -712,7 +712,8 @@ struct ar9170_stream {
__le16 tag;
u8 payload[0];
-};
+} __packed __aligned(4);
+#define AR9170_STREAM_LEN 4
#define AR9170_MAX_ACKTABLE_ENTRIES 8
#define AR9170_MAX_VIRTUAL_MAC 7
@@ -736,4 +737,8 @@ struct ar9170_stream {
#define MOD_VAL(reg, value, newvalue) \
(((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+
+#define GET_VAL(reg, value) \
+ (((value) & reg) >> reg##_S)
+
#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 2305bc27151c..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar)
carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
/* Aggregation MAX number and timeout */
- carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
- carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
AR9170_MAC_FTF_DEFAULTS);
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct carl9170_vif_info *cvif;
+ struct ieee80211_tx_info *txinfo;
__le32 *data, *old = NULL;
u32 word, off, addr, len;
int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
if (!skb) {
err = -ENOMEM;
- goto out_unlock;
+ goto err_free;
+ }
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
+ err = -EINVAL;
+ goto err_free;
}
spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
wiphy_err(ar->hw->wiphy, "beacon does not "
"fit into device memory!\n");
}
-
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EINVAL;
- goto out_unlock;
+ goto err_unlock;
}
if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
AR9170_MAC_BCN_LENGTH_MAX, len);
}
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EMSGSIZE;
- goto out_unlock;
+ goto err_unlock;
}
- carl9170_async_regwrite_begin(ar);
+ i = txinfo->control.rates[0].idx;
+ if (txinfo->band != IEEE80211_BAND_2GHZ)
+ i += 4;
- /* XXX: use skb->cb info */
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
- } else {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << 16) + 0x001b);
- }
+ word = __carl9170_ratetable[i].hw_value & 0xf;
+ if (i < 4)
+ word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
+ else
+ word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
+
+ carl9170_async_regwrite_begin(ar);
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
/*
@@ -557,7 +561,7 @@ found:
cvif->beacon = skb;
spin_unlock_bh(&ar->beacon_lock);
if (err)
- goto out_unlock;
+ goto err_free;
if (submit) {
err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
addr, skb->len + FCS_LEN);
if (err)
- goto out_unlock;
+ goto err_free;
}
out_unlock:
rcu_read_unlock();
+ return 0;
+
+err_unlock:
+ spin_unlock_bh(&ar->beacon_lock);
+
+err_free:
+ rcu_read_unlock();
+ dev_kfree_skb_any(skb);
return err;
}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index a314c2c2bfbe..870df8c42622 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
cancel_delayed_work_sync(&ar->led_work);
#endif /* CONFIG_CARL9170_LEDS */
cancel_work_sync(&ar->ps_work);
+ cancel_work_sync(&ar->ping_work);
cancel_work_sync(&ar->ampdu_work);
}
@@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
*/
}
+static void carl9170_ping_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
+ int err;
+
+ if (!IS_STARTED(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_echo_test(ar, 0xdeadbeef);
+ if (err)
+ carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
+ mutex_unlock(&ar->mutex);
+}
+
static int carl9170_init_interface(struct ar9170 *ar,
struct ieee80211_vif *vif)
{
@@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
skb_queue_head_init(&ar->tx_pending[i]);
}
INIT_WORK(&ar->ps_work, carl9170_ps_work);
+ INIT_WORK(&ar->ping_work, carl9170_ping_work);
INIT_WORK(&ar->restart_work, carl9170_restart_work);
INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
@@ -1631,7 +1648,8 @@ void *carl9170_alloc(size_t priv_size)
* supports these modes. The code which will add the
* additional interface_modes is in fw.c.
*/
- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
@@ -1828,7 +1846,7 @@ int carl9170_register(struct ar9170 *ar)
err = carl9170_led_register(ar);
if (err)
goto err_unreg;
-#endif /* CONFIG_CAR9L170_LEDS */
+#endif /* CONFIG_CARL9170_LEDS */
#ifdef CONFIG_CARL9170_WPC
err = carl9170_register_wps_button(ar);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 89deca37a988..b6b0de600506 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1029,8 +1029,6 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
if (err)
return err;
- msleep(20);
-
return 0;
}
@@ -1554,15 +1552,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
return carl9170_regwrite_result();
}
-/* TODO: replace this with sign_extend32(noise, 8) */
-static int carl9170_calc_noise_dbm(u32 raw_noise)
-{
- if (raw_noise & 0x100)
- return ~0x1ff | raw_noise;
- else
- return raw_noise;
-}
-
int carl9170_get_noisefloor(struct ar9170 *ar)
{
static const u32 phy_regs[] = {
@@ -1578,11 +1567,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
return err;
for (i = 0; i < 2; i++) {
- ar->noise[i] = carl9170_calc_noise_dbm(
- (phy_res[i] >> 19) & 0x1ff);
+ ar->noise[i] = sign_extend32(GET_VAL(
+ AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
- ar->noise[i + 2] = carl9170_calc_noise_dbm(
- (phy_res[i + 2] >> 23) & 0x1ff);
+ ar->noise[i + 2] = sign_extend32(GET_VAL(
+ AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
}
return 0;
@@ -1669,12 +1658,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
return err;
cmd = CARL9170_CMD_RF_INIT;
-
- msleep(100);
-
- err = carl9170_echo_test(ar, 0xaabbccdd);
- if (err)
- return err;
} else {
cmd = CARL9170_CMD_FREQUENCY;
}
@@ -1685,6 +1668,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
0x200);
+ if (err)
+ return err;
err = carl9170_init_rf_bank4_pwr(ar,
channel->band == IEEE80211_BAND_5GHZ,
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 02c34eb4ebde..024fb42bc787 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -139,8 +139,8 @@
#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
-#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CCA_MINCCA_PWR_S 19
+#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CCA_MIN_PWR_S 19
#define AR9170_PHY_CCA_THRESH62 0x0007f000
#define AR9170_PHY_CCA_THRESH62_S 12
@@ -338,8 +338,8 @@
#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
#define AR9170_PHY_EXT_CCA_THRESH62_S 16
-#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23
#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
@@ -546,19 +546,19 @@
#define AR9170_PHY_FORCE_XPA_CFG_S 0
#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
-#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CH1_MINCCA_PWR_S 19
+#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19
#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
-#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CH2_MINCCA_PWR_S 19
+#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19
#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
-#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23
#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
-#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23
#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index b575c865142d..6cc58e052d10 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -242,9 +242,11 @@ static void carl9170_tx_release(struct kref *ref)
ar->tx_ampdu_schedule = true;
if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
- txinfo->status.ampdu_len = txinfo->pad[0];
- txinfo->status.ampdu_ack_len = txinfo->pad[1];
- txinfo->pad[0] = txinfo->pad[1] = 0;
+ struct _carl9170_tx_superframe *super;
+
+ super = (void *)skb->data;
+ txinfo->status.ampdu_len = super->s.rix;
+ txinfo->status.ampdu_ack_len = super->s.cnt;
} else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
/*
* drop redundant tx_status reports:
@@ -337,7 +339,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
u8 tid;
if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
- txinfo->flags & IEEE80211_TX_CTL_INJECTED)
+ txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
+ (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
return;
tx_info = IEEE80211_SKB_CB(skb);
@@ -389,8 +392,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
sta_info->stats[tid].ampdu_ack_len++;
if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
- txinfo->pad[0] = sta_info->stats[tid].ampdu_len;
- txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len;
+ super->s.rix = sta_info->stats[tid].ampdu_len;
+ super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
sta_info->stats[tid].clear = true;
}
@@ -524,6 +527,59 @@ next:
}
}
+static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
+{
+ struct carl9170_sta_tid *iter;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ struct _carl9170_tx_superframe *super;
+ struct ieee80211_sta *sta;
+ struct ieee80211_vif *vif;
+ struct ieee80211_hdr *hdr;
+ unsigned int vif_id;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
+ if (iter->state < CARL9170_TID_STATE_IDLE)
+ continue;
+
+ spin_lock_bh(&iter->lock);
+ skb = skb_peek(&iter->queue);
+ if (!skb)
+ goto unlock;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *)txinfo->rate_driver_data;
+ if (time_is_after_jiffies(arinfo->timeout +
+ msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
+ goto unlock;
+
+ super = (void *) skb->data;
+ hdr = (void *) super->frame_data;
+
+ vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+ if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+ goto unlock;
+
+ vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+ if (WARN_ON(!vif))
+ goto unlock;
+
+ sta = ieee80211_find_sta(vif, hdr->addr1);
+ if (WARN_ON(!sta))
+ goto unlock;
+
+ ieee80211_stop_tx_ba_session(sta, iter->tid);
+unlock:
+ spin_unlock_bh(&iter->lock);
+
+ }
+ rcu_read_unlock();
+}
+
void carl9170_tx_janitor(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
@@ -534,6 +590,7 @@ void carl9170_tx_janitor(struct work_struct *work)
ar->tx_janitor_last_run = jiffies;
carl9170_check_queue_stop_timeout(ar);
+ carl9170_tx_ampdu_timeout(ar);
if (!atomic_read(&ar->tx_total_queued))
return;
@@ -810,7 +867,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
AR9170_TX_MAC_BACKOFF);
- mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+ mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
AR9170_TX_MAC_QOS);
no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
@@ -842,10 +899,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
if (unlikely(!sta || !cvif))
goto err_out;
- factor = min_t(unsigned int, 1u,
- info->control.sta->ht_cap.ampdu_factor);
-
- density = info->control.sta->ht_cap.ampdu_density;
+ factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor);
+ density = sta->ht_cap.ampdu_density;
if (density) {
/*
@@ -1206,6 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar)
static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
struct ieee80211_sta *sta, struct sk_buff *skb)
{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
struct carl9170_sta_info *sta_info;
struct carl9170_sta_tid *agg;
struct sk_buff *iter;
@@ -1274,6 +1330,7 @@ err_unlock:
err_unlock_rcu:
rcu_read_unlock();
+ super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
carl9170_tx_status(ar, skb, false);
ar->tx_dropped++;
return false;
@@ -1302,9 +1359,6 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
- if (WARN_ON_ONCE(!sta))
- goto err_free;
-
run = carl9170_tx_ampdu_queue(ar, sta, skb);
if (run)
carl9170_tx_ampdu(ar);
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 7504ed14c725..537732e5964f 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -160,8 +160,7 @@ err_acc:
static void carl9170_usb_tx_data_complete(struct urb *urb)
{
- struct ar9170 *ar = (struct ar9170 *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
if (WARN_ON_ONCE(!ar)) {
dev_kfree_skb_irq(urb->context);
@@ -433,7 +432,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
* device.
*/
- carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+ ieee80211_queue_work(ar->hw, &ar->ping_work);
}
} else {
/*
@@ -835,7 +834,7 @@ static int carl9170_usb_load_firmware(struct ar9170 *ar)
if (err)
goto err_out;
- /* firmware restarts cmd counter */
+ /* now, start the command response counter */
ar->cmd_seq = -1;
return 0;
@@ -852,7 +851,12 @@ int carl9170_usb_restart(struct ar9170 *ar)
if (ar->intf->condition != USB_INTERFACE_BOUND)
return 0;
- /* Disable command response sequence counter. */
+ /*
+ * Disable the command response sequence counter check.
+ * We already know that the device/firmware is in a bad state.
+ * So, no extra points are awarded to anyone who reminds the
+ * driver about that.
+ */
ar->cmd_seq = -2;
err = carl9170_reboot(ar);
@@ -904,6 +908,15 @@ static int carl9170_usb_init_device(struct ar9170 *ar)
{
int err;
+ /*
+ * The carl9170 firmware let's the driver know when it's
+ * ready for action. But we have to be prepared to gracefully
+ * handle all spurious [flushed] messages after each (re-)boot.
+ * Thus the command response counter remains disabled until it
+ * can be safely synchronized.
+ */
+ ar->cmd_seq = -2;
+
err = carl9170_usb_send_rx_irq_urb(ar);
if (err)
goto err_out;
@@ -912,14 +925,21 @@ static int carl9170_usb_init_device(struct ar9170 *ar)
if (err)
goto err_unrx;
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
mutex_lock(&ar->mutex);
err = carl9170_usb_load_firmware(ar);
mutex_unlock(&ar->mutex);
if (err)
- goto err_unrx;
+ goto err_stop;
return 0;
+err_stop:
+ carl9170_usb_stop(ar);
+
err_unrx:
carl9170_usb_cancel_urbs(ar);
@@ -965,10 +985,6 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar)
if (err)
goto err_freefw;
- err = carl9170_usb_open(ar);
- if (err)
- goto err_unrx;
-
err = carl9170_register(ar);
carl9170_usb_stop(ar);
@@ -1044,7 +1060,6 @@ static int carl9170_usb_probe(struct usb_interface *intf,
atomic_set(&ar->rx_work_urbs, 0);
atomic_set(&ar->rx_anch_urbs, 0);
atomic_set(&ar->rx_pool_urbs, 0);
- ar->cmd_seq = -2;
usb_get_dev(ar->udev);
@@ -1091,10 +1106,6 @@ static int carl9170_usb_suspend(struct usb_interface *intf,
carl9170_usb_cancel_urbs(ar);
- /*
- * firmware automatically reboots for usb suspend.
- */
-
return 0;
}
@@ -1107,12 +1118,20 @@ static int carl9170_usb_resume(struct usb_interface *intf)
return -ENODEV;
usb_unpoison_anchored_urbs(&ar->rx_anch);
+ carl9170_set_state(ar, CARL9170_STOPPED);
- err = carl9170_usb_init_device(ar);
- if (err)
- goto err_unrx;
+ /*
+ * The USB documentation demands that [for suspend] all traffic
+ * to and from the device has to stop. This would be fine, but
+ * there's a catch: the device[usb phy] does not come back.
+ *
+ * Upon resume the firmware will "kill" itself and the
+ * boot-code sorts out the magic voodoo.
+ * Not very nice, but there's not much what could go wrong.
+ */
+ msleep(1100);
- err = carl9170_usb_open(ar);
+ err = carl9170_usb_init_device(ar);
if (err)
goto err_unrx;
@@ -1134,6 +1153,7 @@ static struct usb_driver carl9170_driver = {
#ifdef CONFIG_PM
.suspend = carl9170_usb_suspend,
.resume = carl9170_usb_resume,
+ .reset_resume = carl9170_usb_resume,
#endif /* CONFIG_PM */
};
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index ff53f078a0b5..ee0f84f2a2f6 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
#ifndef __CARL9170_SHARED_VERSION_H
#define __CARL9170_SHARED_VERSION_H
#define CARL9170FW_VERSION_YEAR 10
-#define CARL9170FW_VERSION_MONTH 9
-#define CARL9170FW_VERSION_DAY 28
-#define CARL9170FW_VERSION_GIT "1.8.8.3"
+#define CARL9170FW_VERSION_MONTH 10
+#define CARL9170FW_VERSION_DAY 29
+#define CARL9170FW_VERSION_GIT "1.9.0"
#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index dacfb234f491..5367b1086e09 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -15,21 +15,6 @@
*/
#include "ath.h"
-#include "debug.h"
-
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
- va_list args;
-
- if (likely(!(common->debug_mask & dbg_mask)))
- return;
-
- va_start(args, fmt);
- printk(KERN_DEBUG "ath: ");
- vprintk(fmt, args);
- va_end(args);
-}
-EXPORT_SYMBOL(ath_print);
const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
deleted file mode 100644
index 64e4af2c2887..000000000000
--- a/drivers/net/wireless/ath/debug.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef ATH_DEBUG_H
-#define ATH_DEBUG_H
-
-#include "ath.h"
-
-/**
- * enum ath_debug_level - atheros wireless debug level
- *
- * @ATH_DBG_RESET: reset processing
- * @ATH_DBG_QUEUE: hardware queue management
- * @ATH_DBG_EEPROM: eeprom processing
- * @ATH_DBG_CALIBRATE: periodic calibration
- * @ATH_DBG_INTERRUPT: interrupt processing
- * @ATH_DBG_REGULATORY: regulatory processing
- * @ATH_DBG_ANI: adaptive noise immunitive processing
- * @ATH_DBG_XMIT: basic xmit operation
- * @ATH_DBG_BEACON: beacon handling
- * @ATH_DBG_CONFIG: configuration of the hardware
- * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
- * @ATH_DBG_PS: power save processing
- * @ATH_DBG_HWTIMER: hardware timer handling
- * @ATH_DBG_BTCOEX: bluetooth coexistance
- * @ATH_DBG_BSTUCK: stuck beacons
- * @ATH_DBG_ANY: enable all debugging
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. Each driver has its own method for enabling debugging and
- * modifying debug level states -- but this is typically done through a
- * module parameter 'debug' along with a respective 'debug' debugfs file
- * entry.
- */
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_QUEUE = 0x00000002,
- ATH_DBG_EEPROM = 0x00000004,
- ATH_DBG_CALIBRATE = 0x00000008,
- ATH_DBG_INTERRUPT = 0x00000010,
- ATH_DBG_REGULATORY = 0x00000020,
- ATH_DBG_ANI = 0x00000040,
- ATH_DBG_XMIT = 0x00000080,
- ATH_DBG_BEACON = 0x00000100,
- ATH_DBG_CONFIG = 0x00000200,
- ATH_DBG_FATAL = 0x00000400,
- ATH_DBG_PS = 0x00000800,
- ATH_DBG_HWTIMER = 0x00001000,
- ATH_DBG_BTCOEX = 0x00002000,
- ATH_DBG_WMI = 0x00004000,
- ATH_DBG_BSTUCK = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH_DEBUG
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-#else
-static inline void __attribute__ ((format (printf, 3, 4)))
-ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
-}
-#endif /* CONFIG_ATH_DEBUG */
-
-/** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CONFIG_ATH_DEBUG
-const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
- return "UNKNOWN";
-}
-#endif
-
-#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index bd21a4d82085..5d465e5fcf24 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -20,7 +20,6 @@
#include "ath.h"
#include "reg.h"
-#include "debug.h"
#define REG_READ (common->ops->read)
#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
@@ -37,8 +36,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
void *ah = common->ah;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -60,6 +58,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+ if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
}
@@ -67,15 +67,15 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
}
EXPORT_SYMBOL(ath_hw_keyreset);
-bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
+static bool ath_hw_keysetmac(struct ath_common *common,
+ u16 entry, const u8 *mac)
{
u32 macHi, macLo;
u32 unicast_flag = AR_KEYTABLE_VALID;
void *ah = common->ah;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -107,17 +107,16 @@ bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
return true;
}
-bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
- const struct ath_keyval *k,
- const u8 *mac)
+static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
+ const struct ath_keyval *k,
+ const u8 *mac)
{
void *ah = common->ah;
u32 key0, key1, key2, key3, key4;
u32 keyType;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keycache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -127,8 +126,8 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
break;
case ATH_CIPHER_AES_CCM:
if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
- ath_print(common, ATH_DBG_ANY,
- "AES-CCM not supported by this mac rev\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "AES-CCM not supported by this mac rev\n");
return false;
}
keyType = AR_KEYTABLE_TYPE_CCM;
@@ -136,15 +135,15 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
case ATH_CIPHER_TKIP:
keyType = AR_KEYTABLE_TYPE_TKIP;
if (entry + 64 >= common->keymax) {
- ath_print(common, ATH_DBG_ANY,
- "entry %u inappropriate for TKIP\n", entry);
+ ath_dbg(common, ATH_DBG_ANY,
+ "entry %u inappropriate for TKIP\n", entry);
return false;
}
break;
case ATH_CIPHER_WEP:
if (k->kv_len < WLAN_KEY_LEN_WEP40) {
- ath_print(common, ATH_DBG_ANY,
- "WEP key length %u too small\n", k->kv_len);
+ ath_dbg(common, ATH_DBG_ANY,
+ "WEP key length %u too small\n", k->kv_len);
return false;
}
if (k->kv_len <= WLAN_KEY_LEN_WEP40)
@@ -158,8 +157,7 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
keyType = AR_KEYTABLE_TYPE_CLR;
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "cipher %u not supported\n", k->kv_type);
+ ath_err(common, "cipher %u not supported\n", k->kv_type);
return false;
}
@@ -340,8 +338,7 @@ static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
/* TX MIC entry failed. No need to proceed further */
- ath_print(common, ATH_DBG_FATAL,
- "Setting TX MIC Key Failed\n");
+ ath_err(common, "Setting TX MIC Key Failed\n");
return 0;
}
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 487193f1de1a..c325202fdc5f 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -56,3 +56,23 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
return skb;
}
EXPORT_SYMBOL(ath_rxbuf_alloc);
+
+int ath_printk(const char *level, struct ath_common *common,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int rtn;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ rtn = printk("%sath: %pV", level, &vaf);
+
+ va_end(args);
+
+ return rtn;
+}
+EXPORT_SYMBOL(ath_printk);
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 3f4244f56ce5..2b14775e6bc6 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -342,6 +342,14 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
/* We always apply this */
ath_reg_apply_radar_flags(wiphy);
+ /*
+ * This would happen when we have sent a custom regulatory request
+ * a world regulatory domain and the scheduler hasn't yet processed
+ * any pending requests in the queue.
+ */
+ if (!request)
+ return 0;
+
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_CORE:
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index c8f7090b27d3..46e382ed46aa 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1161,7 +1161,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id)
struct atmel_private *priv = netdev_priv(dev);
u8 isr;
int i = -1;
- static u8 irq_order[] = {
+ static const u8 irq_order[] = {
ISR_OUT_OF_RANGE,
ISR_RxCOMPLETE,
ISR_TxCOMPLETE,
@@ -3771,7 +3771,9 @@ static int probe_atmel_card(struct net_device *dev)
if (rc) {
if (dev->dev_addr[0] == 0xFF) {
- u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
+ static const u8 default_mac[] = {
+ 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
+ };
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 0a00d42642cd..47033f6a1c2b 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -86,15 +86,16 @@ config B43_PIO
select SSB_BLOCKIO
default y
-config B43_NPHY
- bool "Pre IEEE 802.11n support (BROKEN)"
- depends on B43 && EXPERIMENTAL && BROKEN
+config B43_PHY_N
+ bool "Support for 802.11n (N-PHY) devices (EXPERIMENTAL)"
+ depends on B43 && EXPERIMENTAL
---help---
- Support for the IEEE 802.11n draft.
+ Support for the N-PHY.
- THIS IS BROKEN AND DOES NOT WORK YET.
+ This enables support for devices with N-PHY revision up to 2.
- SAY N.
+ Say N if you expect high stability and performance. Saying Y will not
+ affect other devices support and may provide support for basic needs.
config B43_PHY_LP
bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 69d4af09a6cb..cef334a8c669 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,12 +1,12 @@
b43-y += main.o
b43-y += tables.o
-b43-$(CONFIG_B43_NPHY) += tables_nphy.o
-b43-$(CONFIG_B43_NPHY) += radio_2055.o
-b43-$(CONFIG_B43_NPHY) += radio_2056.o
+b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
+b43-$(CONFIG_B43_PHY_N) += radio_2055.o
+b43-$(CONFIG_B43_PHY_N) += radio_2056.o
b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
-b43-$(CONFIG_B43_NPHY) += phy_n.o
+b43-$(CONFIG_B43_PHY_N) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
b43-y += sysfs.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 72821c456b02..bd4cb75b6ca3 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -153,6 +153,19 @@
#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna
* with bluetooth */
+/* SPROM boardflags2_lo values */
+#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */
+#define B43_BFL2_APLL_WAR 0x0002 /* alternative A-band PLL settings implemented */
+#define B43_BFL2_TXPWRCTRL_EN 0x0004 /* permits enabling TX Power Control */
+#define B43_BFL2_2X4_DIV 0x0008 /* 2x4 diversity switch */
+#define B43_BFL2_5G_PWRGAIN 0x0010 /* supports 5G band power gain */
+#define B43_BFL2_PCIEWAR_OVR 0x0020 /* overrides ASPM and Clkreq settings */
+#define B43_BFL2_CAESERS_BRD 0x0040 /* is Caesers board (unused) */
+#define B43_BFL2_BTC3WIRE 0x0080 /* used 3-wire bluetooth coexist */
+#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */
+#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */
+#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */
+
/* GPIO register offset, in both ChipCommon and PCI core. */
#define B43_GPIO_CONTROL 0x6c
@@ -403,10 +416,10 @@ enum {
/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
#define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
-#define B43_TMSLOW_PHYCLKSPEED 0x00C00000 /* PHY clock speed mask (N-PHY only) */
-#define B43_TMSLOW_PHYCLKSPEED_40MHZ 0x00000000 /* 40 MHz PHY */
-#define B43_TMSLOW_PHYCLKSPEED_80MHZ 0x00400000 /* 80 MHz PHY */
-#define B43_TMSLOW_PHYCLKSPEED_160MHZ 0x00800000 /* 160 MHz PHY */
+#define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */
+#define B43_TMSLOW_PHY_BANDWIDTH_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */
+#define B43_TMSLOW_PHY_BANDWIDTH_20MHZ 0x00400000 /* 20 MHz bandwidth, 80 MHz PHY */
+#define B43_TMSLOW_PHY_BANDWIDTH_40MHZ 0x00800000 /* 40 MHz bandwidth, 160 MHz PHY */
#define B43_TMSLOW_PLLREFSEL 0x00200000 /* PLL Frequency Reference Select (rev >= 5) */
#define B43_TMSLOW_MACPHYCLKEN 0x00100000 /* MAC PHY Clock Control Enable (rev >= 5) */
#define B43_TMSLOW_PHYRESET 0x00080000 /* PHY Reset */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 10d0aaf754c5..3d5566e7af0a 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -415,11 +415,6 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring)
{
- gfp_t flags = GFP_KERNEL;
-
- if (ring->type == B43_DMA_64BIT)
- flags |= GFP_DMA;
-
dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
}
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a1186525c70d..22bc9f17f634 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -322,59 +322,83 @@ static int b43_ratelimit(struct b43_wl *wl)
void b43info(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_INFO)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_INFO "b43-%s: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_INFO "b43-%s: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43err(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_ERR "b43-%s ERROR: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_ERR "b43-%s ERROR: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_WARN)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_WARNING "b43-%s warning: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_WARNING "b43-%s warning: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
return;
+
va_start(args, fmt);
- printk(KERN_DEBUG "b43-%s debug: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_DEBUG "b43-%s debug: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
@@ -1126,6 +1150,8 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
flags |= B43_TMSLOW_PHYCLKEN;
flags |= B43_TMSLOW_PHYRESET;
+ if (dev->phy.type == B43_PHYTYPE_N)
+ flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
ssb_device_enable(dev->dev, flags);
msleep(2); /* Wait for the PLL to turn on. */
@@ -2095,8 +2121,10 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
filename = "ucode13";
else if (rev == 14)
filename = "ucode14";
- else if (rev >= 15)
+ else if (rev == 15)
filename = "ucode15";
+ else if ((rev >= 16) && (rev <= 20))
+ filename = "ucode16_mimo";
else
goto err_no_ucode;
err = b43_do_request_fw(ctx, filename, &fw->ucode);
@@ -2139,7 +2167,9 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
goto err_no_initvals;
break;
case B43_PHYTYPE_N:
- if ((rev >= 11) && (rev <= 12))
+ if (rev >= 16)
+ filename = "n0initvals16";
+ else if ((rev >= 11) && (rev <= 12))
filename = "n0initvals11";
else
goto err_no_initvals;
@@ -2183,7 +2213,9 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
goto err_no_initvals;
break;
case B43_PHYTYPE_N:
- if ((rev >= 11) && (rev <= 12))
+ if (rev >= 16)
+ filename = "n0bsinitvals16";
+ else if ((rev >= 11) && (rev <= 12))
filename = "n0bsinitvals11";
else
goto err_no_initvals;
@@ -4022,9 +4054,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
if (phy_rev > 9)
unsupported = 1;
break;
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
case B43_PHYTYPE_N:
- if (phy_rev > 4)
+ if (phy_rev > 9)
unsupported = 1;
break;
#endif
@@ -5067,7 +5099,7 @@ static void b43_print_driverinfo(void)
#ifdef CONFIG_B43_PCMCIA
feat_pcmcia = "M";
#endif
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
feat_nphy = "N";
#endif
#ifdef CONFIG_B43_LEDS
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 7b2ea6781457..b5c5ce94d3fd 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -50,7 +50,7 @@ int b43_phy_allocate(struct b43_wldev *dev)
phy->ops = &b43_phyops_g;
break;
case B43_PHYTYPE_N:
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
phy->ops = &b43_phyops_n;
#endif
break;
@@ -231,6 +231,7 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
{
assert_mac_suspended(dev);
+ dev->phy.writes_counter = 0;
return dev->phy.ops->phy_read(dev, reg);
}
@@ -238,6 +239,10 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
{
assert_mac_suspended(dev);
dev->phy.ops->phy_write(dev, reg, value);
+ if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
+ b43_read16(dev, B43_MMIO_PHY_VER);
+ dev->phy.writes_counter = 0;
+ }
}
void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
@@ -424,12 +429,21 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
}
+
+bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
+{
+ return (channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS);
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
struct b43_c32 b43_cordic(int theta)
{
- u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
- 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
- 229, 115, 57, 29, };
+ static const u32 arctg[] = {
+ 2949120, 1740967, 919879, 466945, 234379, 117304,
+ 58666, 29335, 14668, 7334, 3667, 1833,
+ 917, 458, 229, 115, 57, 29,
+ };
u8 i;
s32 tmp;
s8 signx = 1;
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 0e6194228845..2401bee8b081 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -39,6 +39,9 @@ struct b43_c32 { s32 i, q; };
#define B43_PHYVER_TYPE_SHIFT 8
#define B43_PHYVER_VERSION 0x00FF
+/* PHY writes need to be flushed if we reach limit */
+#define B43_MAX_WRITES_IN_ROW 24
+
/**
* enum b43_interference_mitigation - Interference Mitigation mode
*
@@ -232,6 +235,9 @@ struct b43_phy {
/* PHY revision number. */
u8 rev;
+ /* Count writes since last read */
+ u8 writes_counter;
+
/* Radio versioning */
u16 radio_manuf; /* Radio manufacturer */
u16 radio_ver; /* Radio version */
@@ -430,6 +436,8 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
*/
void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
+bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
+
struct b43_c32 b43_cordic(int theta);
#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e0f2d122e124..ab81ed8b19d7 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -67,6 +67,18 @@ enum b43_nphy_rf_sequence {
B43_RFSEQ_UPDATE_GAINU,
};
+enum b43_nphy_rssi_type {
+ B43_NPHY_RSSI_X = 0,
+ B43_NPHY_RSSI_Y,
+ B43_NPHY_RSSI_Z,
+ B43_NPHY_RSSI_PWRDET,
+ B43_NPHY_RSSI_TSSI_I,
+ B43_NPHY_RSSI_TSSI_Q,
+ B43_NPHY_RSSI_TBD,
+};
+
+static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev,
+ bool enable);
static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
u8 *events, u8 *delays, u8 length);
static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
@@ -76,13 +88,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
u16 value, u8 core);
-static inline bool b43_channel_type_is_40mhz(
- enum nl80211_channel_type channel_type)
-{
- return (channel_type == NL80211_CHAN_HT40MINUS ||
- channel_type == NL80211_CHAN_HT40PLUS);
-}
-
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
{//TODO
}
@@ -134,6 +139,99 @@ static void b43_chantab_radio_upload(struct b43_wldev *dev,
b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
}
+static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
+ const struct b43_nphy_channeltab_entry_rev3 *e)
+{
+ b43_radio_write(dev, B2056_SYN_PLL_VCOCAL1, e->radio_syn_pll_vcocal1);
+ b43_radio_write(dev, B2056_SYN_PLL_VCOCAL2, e->radio_syn_pll_vcocal2);
+ b43_radio_write(dev, B2056_SYN_PLL_REFDIV, e->radio_syn_pll_refdiv);
+ b43_radio_write(dev, B2056_SYN_PLL_MMD2, e->radio_syn_pll_mmd2);
+ b43_radio_write(dev, B2056_SYN_PLL_MMD1, e->radio_syn_pll_mmd1);
+ b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1,
+ e->radio_syn_pll_loopfilter1);
+ b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2,
+ e->radio_syn_pll_loopfilter2);
+ b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER3,
+ e->radio_syn_pll_loopfilter3);
+ b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4,
+ e->radio_syn_pll_loopfilter4);
+ b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER5,
+ e->radio_syn_pll_loopfilter5);
+ b43_radio_write(dev, B2056_SYN_RESERVED_ADDR27,
+ e->radio_syn_reserved_addr27);
+ b43_radio_write(dev, B2056_SYN_RESERVED_ADDR28,
+ e->radio_syn_reserved_addr28);
+ b43_radio_write(dev, B2056_SYN_RESERVED_ADDR29,
+ e->radio_syn_reserved_addr29);
+ b43_radio_write(dev, B2056_SYN_LOGEN_VCOBUF1,
+ e->radio_syn_logen_vcobuf1);
+ b43_radio_write(dev, B2056_SYN_LOGEN_MIXER2, e->radio_syn_logen_mixer2);
+ b43_radio_write(dev, B2056_SYN_LOGEN_BUF3, e->radio_syn_logen_buf3);
+ b43_radio_write(dev, B2056_SYN_LOGEN_BUF4, e->radio_syn_logen_buf4);
+
+ b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA_TUNE,
+ e->radio_rx0_lnaa_tune);
+ b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG_TUNE,
+ e->radio_rx0_lnag_tune);
+
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAA_BOOST_TUNE,
+ e->radio_tx0_intpaa_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAG_BOOST_TUNE,
+ e->radio_tx0_intpag_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE,
+ e->radio_tx0_pada_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE,
+ e->radio_tx0_padg_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE,
+ e->radio_tx0_pgaa_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE,
+ e->radio_tx0_pgag_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE,
+ e->radio_tx0_mixa_boost_tune);
+ b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE,
+ e->radio_tx0_mixg_boost_tune);
+
+ b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA_TUNE,
+ e->radio_rx1_lnaa_tune);
+ b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG_TUNE,
+ e->radio_rx1_lnag_tune);
+
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAA_BOOST_TUNE,
+ e->radio_tx1_intpaa_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAG_BOOST_TUNE,
+ e->radio_tx1_intpag_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE,
+ e->radio_tx1_pada_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE,
+ e->radio_tx1_padg_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE,
+ e->radio_tx1_pgaa_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE,
+ e->radio_tx1_pgag_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE,
+ e->radio_tx1_mixa_boost_tune);
+ b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE,
+ e->radio_tx1_mixg_boost_tune);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */
+static void b43_radio_2056_setup(struct b43_wldev *dev,
+ const struct b43_nphy_channeltab_entry_rev3 *e)
+{
+ B43_WARN_ON(dev->phy.rev < 3);
+
+ b43_chantab_radio_2056_upload(dev, e);
+ /* TODO */
+ udelay(50);
+ /* VCO calibration */
+ b43_radio_write(dev, B2056_SYN_PLL_VCOCAL12, 0x00);
+ b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
+ b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x18);
+ b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
+ b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x39);
+ udelay(300);
+}
+
static void b43_chantab_phy_upload(struct b43_wldev *dev,
const struct b43_phy_n_sfo_cfg *e)
{
@@ -145,9 +243,154 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev,
b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
+static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_n *nphy = dev->phy.n;
+ u8 i;
+ u16 tmp;
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 1);
+
+ nphy->txpwrctrl = enable;
+ if (!enable) {
+ if (dev->phy.rev >= 3)
+ ; /* TODO */
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
+ for (i = 0; i < 84; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40);
+ for (i = 0; i < 84; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
+
+ tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
+ if (dev->phy.rev >= 3)
+ tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN;
+ b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp);
+
+ if (dev->phy.rev >= 3) {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
+ } else {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
+ }
+
+ if (dev->phy.rev == 2)
+ b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+ ~B43_NPHY_BPHY_CTL3_SCALE, 0x53);
+ else if (dev->phy.rev < 2)
+ b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+ ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
+
+ if (dev->phy.rev < 2 && 0)
+ ; /* TODO */
+ } else {
+ b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n");
+ }
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 0);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
{
- //TODO
+ struct b43_phy_n *nphy = dev->phy.n;
+ struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+
+ u8 txpi[2], bbmult, i;
+ u16 tmp, radio_gain, dac_gain;
+ u16 freq = dev->phy.channel_freq;
+ u32 txgain;
+ /* u32 gaintbl; rev3+ */
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 1);
+
+ if (dev->phy.rev >= 3) {
+ txpi[0] = 40;
+ txpi[1] = 40;
+ } else if (sprom->revision < 4) {
+ txpi[0] = 72;
+ txpi[1] = 72;
+ } else {
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ txpi[0] = sprom->txpid2g[0];
+ txpi[1] = sprom->txpid2g[1];
+ } else if (freq >= 4900 && freq < 5100) {
+ txpi[0] = sprom->txpid5gl[0];
+ txpi[1] = sprom->txpid5gl[1];
+ } else if (freq >= 5100 && freq < 5500) {
+ txpi[0] = sprom->txpid5g[0];
+ txpi[1] = sprom->txpid5g[1];
+ } else if (freq >= 5500) {
+ txpi[0] = sprom->txpid5gh[0];
+ txpi[1] = sprom->txpid5gh[1];
+ } else {
+ txpi[0] = 91;
+ txpi[1] = 91;
+ }
+ }
+
+ /*
+ for (i = 0; i < 2; i++) {
+ nphy->txpwrindex[i].index_internal = txpi[i];
+ nphy->txpwrindex[i].index_internal_save = txpi[i];
+ }
+ */
+
+ for (i = 0; i < 2; i++) {
+ if (dev->phy.rev >= 3) {
+ /* FIXME: support 5GHz */
+ txgain = b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
+ radio_gain = (txgain >> 16) & 0x1FFFF;
+ } else {
+ txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
+ radio_gain = (txgain >> 16) & 0x1FFF;
+ }
+
+ dac_gain = (txgain >> 8) & 0x3F;
+ bbmult = txgain & 0xFF;
+
+ if (dev->phy.rev >= 3) {
+ if (i == 0)
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
+ else
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
+ } else {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
+ }
+
+ if (i == 0)
+ b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain);
+ else
+ b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i);
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
+ tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+
+ if (i == 0)
+ tmp = (tmp & 0x00FF) | (bbmult << 8);
+ else
+ tmp = (tmp & 0xFF00) | bbmult;
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp);
+
+ if (0)
+ ; /* TODO */
+ }
+
+ b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 0);
}
@@ -191,7 +434,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
binfo->type != 0x46D ||
binfo->rev < 0x41);
else
- workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0);
+ workaround =
+ !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
if (workaround) {
@@ -240,23 +484,55 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
static void b43_radio_init2055(struct b43_wldev *dev)
{
b43_radio_init2055_pre(dev);
- if (b43_status(dev) < B43_STAT_INITIALIZED)
- b2055_upload_inittab(dev, 0, 1);
- else
- b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0);
+ if (b43_status(dev) < B43_STAT_INITIALIZED) {
+ /* Follow wl, not specs. Do not force uploading all regs */
+ b2055_upload_inittab(dev, 0, 0);
+ } else {
+ bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ;
+ b2055_upload_inittab(dev, ghz5, 0);
+ }
b43_radio_init2055_post(dev);
}
+static void b43_radio_init2056_pre(struct b43_wldev *dev)
+{
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_CHIP0PU);
+ /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ B43_NPHY_RFCTL_CMD_OEPORFORCE);
+ b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
+ b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+ B43_NPHY_RFCTL_CMD_CHIP0PU);
+}
+
+static void b43_radio_init2056_post(struct b43_wldev *dev)
+{
+ b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB);
+ b43_radio_set(dev, B2056_SYN_COM_PU, 0x2);
+ b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2);
+ msleep(1);
+ b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
+ b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
+ b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
+ /*
+ if (nphy->init_por)
+ Call Radio 2056 Recalibrate
+ */
+}
+
/*
* Initialize a Broadcom 2056 N-radio
* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
*/
static void b43_radio_init2056(struct b43_wldev *dev)
{
- /* TODO */
+ b43_radio_init2056_pre(dev);
+ b2056_upload_inittabs(dev, 0, 0);
+ b43_radio_init2056_post(dev);
}
-
/*
* Upload the N-PHY tables.
* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables
@@ -453,6 +729,8 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
}
}
+#if 0
+/* Ready but not used anywhere */
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
{
@@ -534,6 +812,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
}
+#endif
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
@@ -569,7 +848,6 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
ii = est.i1_pwr;
qq = est.q1_pwr;
} else {
- B43_WARN_ON(1);
continue;
}
@@ -651,7 +929,8 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
-static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st)
+static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
+ const u16 *clip_st)
{
b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
@@ -727,7 +1006,7 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
struct b43_phy_n *nphy = phy->n;
if (enable) {
- u16 clip[] = { 0xFFFF, 0xFFFF };
+ static const u16 clip[] = { 0xFFFF, 0xFFFF };
if (nphy->deaf_count++ == 0) {
nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
b43_nphy_classifier(dev, 0x7, 0);
@@ -839,7 +1118,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
u16 data[4];
s16 gain[2];
u16 minmax[2];
- u16 lna_gain[4] = { -2, 10, 19, 25 };
+ static const u16 lna_gain[4] = { -2, 10, 19, 25 };
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 1);
@@ -871,7 +1150,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
data[2] = lna_gain[2] + gain[i];
data[3] = lna_gain[3] + gain[i];
}
- b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data);
+ b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data);
minmax[i] = 23 + gain[i];
}
@@ -891,6 +1170,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
struct b43_phy_n *nphy = dev->phy.n;
u8 i, j;
u8 code;
+ u16 tmp;
/* TODO: for PHY >= 3
s8 *lna1_gain, *lna2_gain;
@@ -913,15 +1193,15 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
B43_NPHY_C2_CGAINI_CL2DETECT);
/* Set narrowband clip threshold */
- b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
- b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
+ b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
+ b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
if (!dev->phy.is_40mhz) {
/* Set dwell lengths */
- b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
- b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
- b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
- b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
+ b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
+ b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
+ b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
+ b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
}
/* Set wideband clip 2 threshold */
@@ -943,7 +1223,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
}
- b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
+ b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
if (nphy->gain_boost) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
@@ -964,10 +1244,10 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x7C));
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x7C));
+ /* specs say about 2 loops, but wl does 4 */
+ for (i = 0; i < 4; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+ (code << 8 | 0x7C));
b43_nphy_adjust_lna_gain_table(dev);
@@ -985,19 +1265,21 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x74));
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x74));
+ /* specs say about 2 loops, but wl does 4 */
+ for (i = 0; i < 4; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+ (code << 8 | 0x74));
}
if (dev->phy.rev == 2) {
for (i = 0; i < 4; i++) {
b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
(0x0400 * i) + 0x0020);
- for (j = 0; j < 21; j++)
+ for (j = 0; j < 21; j++) {
+ tmp = j * (i < 2 ? 3 : 1);
b43_phy_write(dev,
- B43_NPHY_TABLE_DATALO, 3 * j);
+ B43_NPHY_TABLE_DATALO, tmp);
+ }
}
b43_nphy_set_rf_sequence(dev, 5,
@@ -1026,7 +1308,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
- if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
b43_nphy_classifier(dev, 1, 0);
else
b43_nphy_classifier(dev, 1, 1);
@@ -1049,29 +1331,18 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
}
- /* TODO: convert to b43_ntab_write? */
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
if (dev->phy.rev < 2) {
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
- b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
}
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -1565,19 +1836,20 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
}
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
static void b43_nphy_bphy_init(struct b43_wldev *dev)
{
unsigned int i;
u16 val;
val = 0x1E1F;
- for (i = 0; i < 14; i++) {
+ for (i = 0; i < 16; i++) {
b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
val -= 0x202;
}
val = 0x3E3F;
for (i = 0; i < 16; i++) {
- b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val);
+ b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
val -= 0x202;
}
b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
@@ -1585,7 +1857,8 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
- s8 offset, u8 core, u8 rail, u8 type)
+ s8 offset, u8 core, u8 rail,
+ enum b43_nphy_rssi_type type)
{
u16 tmp;
bool core1or5 = (core == 1) || (core == 5);
@@ -1594,53 +1867,59 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
offset = clamp_val(offset, -32, 31);
tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
- if (core1or5 && (rail == 0) && (type == 2))
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
- if (core1or5 && (rail == 1) && (type == 2))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
- if (core2or5 && (rail == 0) && (type == 2))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
- if (core2or5 && (rail == 1) && (type == 2))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
- if (core1or5 && (rail == 0) && (type == 0))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
- if (core1or5 && (rail == 1) && (type == 0))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
- if (core2or5 && (rail == 0) && (type == 0))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
- if (core2or5 && (rail == 1) && (type == 0))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
- if (core1or5 && (rail == 0) && (type == 1))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
- if (core1or5 && (rail == 1) && (type == 1))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
- if (core2or5 && (rail == 0) && (type == 1))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
- if (core2or5 && (rail == 1) && (type == 1))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
- if (core1or5 && (rail == 0) && (type == 6))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
- if (core1or5 && (rail == 1) && (type == 6))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
- if (core2or5 && (rail == 0) && (type == 6))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
- if (core2or5 && (rail == 1) && (type == 6))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
- if (core1or5 && (rail == 0) && (type == 3))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
- if (core1or5 && (rail == 1) && (type == 3))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
- if (core2or5 && (rail == 0) && (type == 3))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
- if (core2or5 && (rail == 1) && (type == 3))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
- if (core1or5 && (type == 4))
+
+ if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
- if (core2or5 && (type == 4))
+ if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
- if (core1or5 && (type == 5))
+
+ if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
- if (core2or5 && (type == 5))
+ if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
}
@@ -1668,27 +1947,39 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
(type + 1) << 4);
}
- /* TODO use some definitions */
if (code == 0) {
- b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
+ b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000);
if (type < 3) {
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~(B43_NPHY_RFCTL_CMD_RXEN |
+ B43_NPHY_RFCTL_CMD_CORESEL));
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
+ ~(0x1 << 12 |
+ 0x1 << 5 |
+ 0x1 << 1 |
+ 0x1));
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_START);
udelay(20);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
}
} else {
- b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
- 0x3000);
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000);
if (type < 3) {
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
- 0xFEC7, 0x0180);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
- 0xEFDC, (code << 1 | 0x1021));
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
+ ~(B43_NPHY_RFCTL_CMD_RXEN |
+ B43_NPHY_RFCTL_CMD_CORESEL),
+ (B43_NPHY_RFCTL_CMD_RXEN |
+ code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT));
+ b43_phy_set(dev, B43_NPHY_RFCTL_OVER,
+ (0x1 << 12 |
+ 0x1 << 5 |
+ 0x1 << 1 |
+ 0x1));
+ b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+ B43_NPHY_RFCTL_CMD_START);
udelay(20);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
}
}
}
@@ -1837,6 +2128,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+ } else if (dev->phy.rev == 2) {
+ save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+ save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+ save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+ save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
+ save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
+ save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
+ save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
}
b43_nphy_rssi_select(dev, 5, type);
@@ -1880,6 +2179,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
+ } else if (dev->phy.rev == 2) {
+ b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
}
return out;
@@ -1894,7 +2201,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
u16 class, override;
u8 regs_save_radio[2];
u16 regs_save_phy[2];
+
s8 offset[4];
+ u8 core;
+ u8 rail;
u16 clip_state[2];
u16 clip_off[2] = { 0xFFFF, 0xFFFF };
@@ -1995,16 +2305,15 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
if (results_min[i] == 248)
offset[i] = code - 32;
- if (i % 2 == 0)
- b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
- type);
- else
- b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
- type);
+ core = (i / 2) ? 2 : 1;
+ rail = (i % 2) ? 1 : 0;
+
+ b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
+ type);
}
b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
- b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
+ b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
switch (state[2]) {
case 1:
@@ -2042,6 +2351,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
b43_nphy_classifier(dev, 7, class);
b43_nphy_write_clip_detection(dev, clip_state);
+ /* Specs don't say about reset here, but it makes wl and b43 dumps
+ identical, it really seems wl performs this */
+ b43_nphy_reset_cca(dev);
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
@@ -2059,9 +2371,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev)
if (dev->phy.rev >= 3) {
b43_nphy_rev3_rssi_cal(dev);
} else {
- b43_nphy_rev2_rssi_cal(dev, 2);
- b43_nphy_rev2_rssi_cal(dev, 0);
- b43_nphy_rev2_rssi_cal(dev, 1);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
}
}
@@ -2295,7 +2607,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
int i, j;
/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
- u16 offset[] = { 0x186, 0x195, 0x2C5 };
+ static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
for (i = 0; i < 3; i++)
for (j = 0; j < 15; j++)
@@ -2327,7 +2639,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
struct nphy_txgains target;
const u32 *table = NULL;
- if (nphy->txpwrctrl == 0) {
+ if (!nphy->txpwrctrl) {
int i;
if (nphy->hang_avoid)
@@ -2884,7 +3196,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
u8 rfctl[2];
u8 afectl_core;
u16 tmp[6];
- u16 cur_hpf1, cur_hpf2, cur_lna;
+ u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna;
u32 real, imag;
enum ieee80211_band band;
@@ -3077,9 +3389,9 @@ static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
{
u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
if (on)
- tmslow |= SSB_TMSLOW_PHYCLK;
+ tmslow |= B43_TMSLOW_MACPHYCLKEN;
else
- tmslow &= ~SSB_TMSLOW_PHYCLK;
+ tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
}
@@ -3088,7 +3400,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = phy->n;
- u16 buf[16];
+ /* u16 buf[16]; it's rev3+ */
nphy->phyrxchain = mask;
@@ -3232,10 +3544,12 @@ int b43_phy_initn(struct b43_wldev *dev)
b43_nphy_classifier(dev, 0, 0);
b43_nphy_read_clip_detection(dev, clip);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ b43_nphy_bphy_init(dev);
+
tx_pwr_state = nphy->txpwrctrl;
- /* TODO N PHY TX power control with argument 0
- (turning off power control) */
- /* TODO Fix the TX Power Settings */
+ b43_nphy_tx_power_ctrl(dev, false);
+ b43_nphy_tx_power_fix(dev);
/* TODO N PHY TX Power Control Idle TSSI */
/* TODO N PHY TX Power Control Setup */
@@ -3292,21 +3606,18 @@ int b43_phy_initn(struct b43_wldev *dev)
/* TODO N PHY Pre Calibrate TX Gain */
target = b43_nphy_get_tx_gains(dev);
}
- }
+ if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false))
+ if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
+ b43_nphy_save_cal(dev);
+ } else if (nphy->mphase_cal_phase_id == 0)
+ ;/* N PHY Periodic Calibration with arg 3 */
+ } else {
+ b43_nphy_restore_cal(dev);
}
}
- if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
- if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
- b43_nphy_save_cal(dev);
- else if (nphy->mphase_cal_phase_id == 0)
- ;/* N PHY Periodic Calibration with argument 3 */
- } else {
- b43_nphy_restore_cal(dev);
- }
-
b43_nphy_tx_pwr_ctrl_coef_setup(dev);
- /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
+ b43_nphy_tx_power_ctrl(dev, tx_pwr_state);
b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
if (phy->rev >= 3 && phy->rev <= 6)
@@ -3315,7 +3626,6 @@ int b43_phy_initn(struct b43_wldev *dev)
if (phy->rev >= 3)
b43_nphy_spur_workaround(dev);
- b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
return 0;
}
@@ -3357,7 +3667,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
}
- if (nphy->txpwrctrl)
+ if (!nphy->txpwrctrl)
b43_nphy_tx_power_fix(dev);
if (dev->phy.rev < 3)
@@ -3381,7 +3691,6 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
enum nl80211_channel_type channel_type)
{
struct b43_phy *phy = &dev->phy;
- struct b43_phy_n *nphy = dev->phy.n;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
@@ -3391,7 +3700,6 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
if (dev->phy.rev >= 3) {
tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
channel->center_freq);
- tabent_r3 = NULL;
if (!tabent_r3)
return -ESRCH;
} else {
@@ -3420,7 +3728,7 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
if (dev->phy.rev >= 3) {
tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
- /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
+ b43_radio_2056_setup(dev, tabent_r3);
b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
} else {
tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
@@ -3451,7 +3759,11 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
memset(nphy, 0, sizeof(*nphy));
- //TODO init struct b43_phy_n
+ nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
+ nphy->gain_boost = true; /* this way we follow wl, assume it is true */
+ nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
+ nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
+ nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
}
static void b43_nphy_op_free(struct b43_wldev *dev)
@@ -3500,6 +3812,15 @@ static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
+static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
+ u16 set)
+{
+ check_phyreg(dev, reg);
+ b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16(dev, B43_MMIO_PHY_DATA,
+ (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
+}
+
static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
{
/* Register 1 is a 32-bit register. */
@@ -3524,8 +3845,6 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
- struct b43_phy_n *nphy = dev->phy.n;
-
if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
b43err(dev->wl, "MAC not suspended\n");
@@ -3596,6 +3915,7 @@ const struct b43_phy_operations b43_phyops_n = {
.init = b43_nphy_op_init,
.phy_read = b43_nphy_op_read,
.phy_write = b43_nphy_op_write,
+ .phy_maskset = b43_nphy_op_maskset,
.radio_read = b43_nphy_op_radio_read,
.radio_write = b43_nphy_op_radio_write,
.software_rfkill = b43_nphy_op_software_rfkill,
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index c144e59a708b..001e841f118c 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -782,7 +782,7 @@ struct b43_phy_n {
u16 mphase_txcal_numcmds;
u16 mphase_txcal_bestcoeffs[11];
- u8 txpwrctrl;
+ bool txpwrctrl;
u16 txcal_bbmult;
u16 txiqlocal_bestc[11];
bool txiqlocal_coeffsvalid;
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
index 1b5316586cbf..44c6dea66882 100644
--- a/drivers/net/wireless/b43/radio_2055.c
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -244,7 +244,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
[0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCE] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
[0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -256,7 +256,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
[0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDA] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
[0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -304,178 +304,178 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
{ .channel = 184,
.freq = 4920, /* MHz */
.unk2 = 3280,
- RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEC, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+ PHYREGS(0x07B4, 0x07B0, 0x07AC, 0x0214, 0x0215, 0x0216),
},
{ .channel = 186,
.freq = 4930, /* MHz */
.unk2 = 3287,
- RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xED, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+ PHYREGS(0x07B8, 0x07B4, 0x07B0, 0x0213, 0x0214, 0x0215),
},
{ .channel = 188,
.freq = 4940, /* MHz */
.unk2 = 3293,
- RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEE, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+ PHYREGS(0x07BC, 0x07B8, 0x07B4, 0x0212, 0x0213, 0x0214),
},
{ .channel = 190,
.freq = 4950, /* MHz */
.unk2 = 3300,
- RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEF, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+ PHYREGS(0x07C0, 0x07BC, 0x07B8, 0x0211, 0x0212, 0x0213),
},
{ .channel = 192,
.freq = 4960, /* MHz */
.unk2 = 3307,
- RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF0, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+ PHYREGS(0x07C4, 0x07C0, 0x07BC, 0x020F, 0x0211, 0x0212),
},
{ .channel = 194,
.freq = 4970, /* MHz */
.unk2 = 3313,
- RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF1, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+ PHYREGS(0x07C8, 0x07C4, 0x07C0, 0x020E, 0x020F, 0x0211),
},
{ .channel = 196,
.freq = 4980, /* MHz */
.unk2 = 3320,
- RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF2, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+ PHYREGS(0x07CC, 0x07C8, 0x07C4, 0x020D, 0x020E, 0x020F),
},
{ .channel = 198,
.freq = 4990, /* MHz */
.unk2 = 3327,
- RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF3, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+ PHYREGS(0x07D0, 0x07CC, 0x07C8, 0x020C, 0x020D, 0x020E),
},
{ .channel = 200,
.freq = 5000, /* MHz */
.unk2 = 3333,
- RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF4, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+ PHYREGS(0x07D4, 0x07D0, 0x07CC, 0x020B, 0x020C, 0x020D),
},
{ .channel = 202,
.freq = 5010, /* MHz */
.unk2 = 3340,
- RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF5, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+ PHYREGS(0x07D8, 0x07D4, 0x07D0, 0x020A, 0x020B, 0x020C),
},
{ .channel = 204,
.freq = 5020, /* MHz */
.unk2 = 3347,
- RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF6, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+ PHYREGS(0x07DC, 0x07D8, 0x07D4, 0x0209, 0x020A, 0x020B),
},
{ .channel = 206,
.freq = 5030, /* MHz */
.unk2 = 3353,
- RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF7, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+ PHYREGS(0x07E0, 0x07DC, 0x07D8, 0x0208, 0x0209, 0x020A),
},
{ .channel = 208,
.freq = 5040, /* MHz */
.unk2 = 3360,
- RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF8, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+ PHYREGS(0x07E4, 0x07E0, 0x07DC, 0x0207, 0x0208, 0x0209),
},
{ .channel = 210,
.freq = 5050, /* MHz */
.unk2 = 3367,
- RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF9, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+ PHYREGS(0x07E8, 0x07E4, 0x07E0, 0x0206, 0x0207, 0x0208),
},
{ .channel = 212,
.freq = 5060, /* MHz */
.unk2 = 3373,
- RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFA, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+ PHYREGS(0x07EC, 0x07E8, 0x07E4, 0x0205, 0x0206, 0x0207),
},
{ .channel = 214,
.freq = 5070, /* MHz */
.unk2 = 3380,
- RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFB, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+ PHYREGS(0x07F0, 0x07EC, 0x07E8, 0x0204, 0x0205, 0x0206),
},
{ .channel = 216,
.freq = 5080, /* MHz */
.unk2 = 3387,
- RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFC, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+ PHYREGS(0x07F4, 0x07F0, 0x07EC, 0x0203, 0x0204, 0x0205),
},
{ .channel = 218,
.freq = 5090, /* MHz */
.unk2 = 3393,
- RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFD, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+ PHYREGS(0x07F8, 0x07F4, 0x07F0, 0x0202, 0x0203, 0x0204),
},
{ .channel = 220,
.freq = 5100, /* MHz */
.unk2 = 3400,
- RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFE, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+ PHYREGS(0x07FC, 0x07F8, 0x07F4, 0x0201, 0x0202, 0x0203),
},
{ .channel = 222,
.freq = 5110, /* MHz */
.unk2 = 3407,
- RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFF, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+ PHYREGS(0x0800, 0x07FC, 0x07F8, 0x0200, 0x0201, 0x0202),
},
{ .channel = 224,
.freq = 5120, /* MHz */
.unk2 = 3413,
- RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x00, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+ PHYREGS(0x0804, 0x0800, 0x07FC, 0x01FF, 0x0200, 0x0201),
},
{ .channel = 226,
.freq = 5130, /* MHz */
.unk2 = 3420,
- RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x01, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01FE, 0x01FF, 0x0200),
},
{ .channel = 228,
.freq = 5140, /* MHz */
@@ -483,815 +483,815 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
- PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+ PHYREGS(0x080C, 0x0808, 0x0804, 0x01FD, 0x01FE, 0x01FF),
},
{ .channel = 32,
.freq = 5160, /* MHz */
.unk2 = 3440,
- RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x04, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+ PHYREGS(0x0814, 0x0810, 0x080C, 0x01FB, 0x01FC, 0x01FD),
},
{ .channel = 34,
.freq = 5170, /* MHz */
.unk2 = 3447,
- RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x05, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01FA, 0x01FB, 0x01FC),
},
{ .channel = 36,
.freq = 5180, /* MHz */
.unk2 = 3453,
- RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x06, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+ PHYREGS(0x081C, 0x0818, 0x0814, 0x01F9, 0x01FA, 0x01FB),
},
{ .channel = 38,
.freq = 5190, /* MHz */
.unk2 = 3460,
- RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x07, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+ PHYREGS(0x0820, 0x081C, 0x0818, 0x01F8, 0x01F9, 0x01FA),
},
{ .channel = 40,
.freq = 5200, /* MHz */
.unk2 = 3467,
- RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x08, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+ PHYREGS(0x0824, 0x0820, 0x081C, 0x01F7, 0x01F8, 0x01F9),
},
{ .channel = 42,
.freq = 5210, /* MHz */
.unk2 = 3473,
- RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x09, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01F6, 0x01F7, 0x01F8),
},
{ .channel = 44,
.freq = 5220, /* MHz */
.unk2 = 3480,
- RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0A, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+ PHYREGS(0x082C, 0x0828, 0x0824, 0x01F5, 0x01F6, 0x01F7),
},
{ .channel = 46,
.freq = 5230, /* MHz */
.unk2 = 3487,
- RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0B, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+ PHYREGS(0x0830, 0x082C, 0x0828, 0x01F4, 0x01F5, 0x01F6),
},
{ .channel = 48,
.freq = 5240, /* MHz */
.unk2 = 3493,
- RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0C, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+ PHYREGS(0x0834, 0x0830, 0x082C, 0x01F3, 0x01F4, 0x01F5),
},
{ .channel = 50,
.freq = 5250, /* MHz */
.unk2 = 3500,
- RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0D, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01F2, 0x01F3, 0x01F4),
},
{ .channel = 52,
.freq = 5260, /* MHz */
.unk2 = 3507,
- RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0E, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+ PHYREGS(0x083C, 0x0838, 0x0834, 0x01F1, 0x01F2, 0x01F3),
},
{ .channel = 54,
.freq = 5270, /* MHz */
.unk2 = 3513,
- RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0F, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+ PHYREGS(0x0840, 0x083C, 0x0838, 0x01F0, 0x01F1, 0x01F2),
},
{ .channel = 56,
.freq = 5280, /* MHz */
.unk2 = 3520,
- RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x10, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+ PHYREGS(0x0844, 0x0840, 0x083C, 0x01F0, 0x01F0, 0x01F1),
},
{ .channel = 58,
.freq = 5290, /* MHz */
.unk2 = 3527,
- RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x11, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01EF, 0x01F0, 0x01F0),
},
{ .channel = 60,
.freq = 5300, /* MHz */
.unk2 = 3533,
- RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x12, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+ PHYREGS(0x084C, 0x0848, 0x0844, 0x01EE, 0x01EF, 0x01F0),
},
{ .channel = 62,
.freq = 5310, /* MHz */
.unk2 = 3540,
- RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x13, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+ PHYREGS(0x0850, 0x084C, 0x0848, 0x01ED, 0x01EE, 0x01EF),
},
{ .channel = 64,
.freq = 5320, /* MHz */
.unk2 = 3547,
- RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x14, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+ PHYREGS(0x0854, 0x0850, 0x084C, 0x01EC, 0x01ED, 0x01EE),
},
{ .channel = 66,
.freq = 5330, /* MHz */
.unk2 = 3553,
- RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x15, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01EB, 0x01EC, 0x01ED),
},
{ .channel = 68,
.freq = 5340, /* MHz */
.unk2 = 3560,
- RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x16, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+ PHYREGS(0x085C, 0x0858, 0x0854, 0x01EA, 0x01EB, 0x01EC),
},
{ .channel = 70,
.freq = 5350, /* MHz */
.unk2 = 3567,
- RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x17, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+ PHYREGS(0x0860, 0x085C, 0x0858, 0x01E9, 0x01EA, 0x01EB),
},
{ .channel = 72,
.freq = 5360, /* MHz */
.unk2 = 3573,
- RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x18, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+ PHYREGS(0x0864, 0x0860, 0x085C, 0x01E8, 0x01E9, 0x01EA),
},
{ .channel = 74,
.freq = 5370, /* MHz */
.unk2 = 3580,
- RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x19, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01E7, 0x01E8, 0x01E9),
},
{ .channel = 76,
.freq = 5380, /* MHz */
.unk2 = 3587,
- RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1A, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+ PHYREGS(0x086C, 0x0868, 0x0864, 0x01E6, 0x01E7, 0x01E8),
},
{ .channel = 78,
.freq = 5390, /* MHz */
.unk2 = 3593,
- RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1B, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+ PHYREGS(0x0870, 0x086C, 0x0868, 0x01E5, 0x01E6, 0x01E7),
},
{ .channel = 80,
.freq = 5400, /* MHz */
.unk2 = 3600,
- RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1C, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+ PHYREGS(0x0874, 0x0870, 0x086C, 0x01E5, 0x01E5, 0x01E6),
},
{ .channel = 82,
.freq = 5410, /* MHz */
.unk2 = 3607,
- RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1D, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01E4, 0x01E5, 0x01E5),
},
{ .channel = 84,
.freq = 5420, /* MHz */
.unk2 = 3613,
- RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1E, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+ PHYREGS(0x087C, 0x0878, 0x0874, 0x01E3, 0x01E4, 0x01E5),
},
{ .channel = 86,
.freq = 5430, /* MHz */
.unk2 = 3620,
- RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1F, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+ PHYREGS(0x0880, 0x087C, 0x0878, 0x01E2, 0x01E3, 0x01E4),
},
{ .channel = 88,
.freq = 5440, /* MHz */
.unk2 = 3627,
- RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x20, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+ PHYREGS(0x0884, 0x0880, 0x087C, 0x01E1, 0x01E2, 0x01E3),
},
{ .channel = 90,
.freq = 5450, /* MHz */
.unk2 = 3633,
- RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x21, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01E0, 0x01E1, 0x01E2),
},
{ .channel = 92,
.freq = 5460, /* MHz */
.unk2 = 3640,
- RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x22, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+ PHYREGS(0x088C, 0x0888, 0x0884, 0x01DF, 0x01E0, 0x01E1),
},
{ .channel = 94,
.freq = 5470, /* MHz */
.unk2 = 3647,
- RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x23, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+ PHYREGS(0x0890, 0x088C, 0x0888, 0x01DE, 0x01DF, 0x01E0),
},
{ .channel = 96,
.freq = 5480, /* MHz */
.unk2 = 3653,
- RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x24, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+ PHYREGS(0x0894, 0x0890, 0x088C, 0x01DD, 0x01DE, 0x01DF),
},
{ .channel = 98,
.freq = 5490, /* MHz */
.unk2 = 3660,
- RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x25, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01DD, 0x01DD, 0x01DE),
},
{ .channel = 100,
.freq = 5500, /* MHz */
.unk2 = 3667,
- RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x26, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+ PHYREGS(0x089C, 0x0898, 0x0894, 0x01DC, 0x01DD, 0x01DD),
},
{ .channel = 102,
.freq = 5510, /* MHz */
.unk2 = 3673,
- RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x27, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+ PHYREGS(0x08A0, 0x089C, 0x0898, 0x01DB, 0x01DC, 0x01DD),
},
{ .channel = 104,
.freq = 5520, /* MHz */
.unk2 = 3680,
- RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x28, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+ PHYREGS(0x08A4, 0x08A0, 0x089C, 0x01DA, 0x01DB, 0x01DC),
},
{ .channel = 106,
.freq = 5530, /* MHz */
.unk2 = 3687,
- RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x29, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+ PHYREGS(0x08A8, 0x08A4, 0x08A0, 0x01D9, 0x01DA, 0x01DB),
},
{ .channel = 108,
.freq = 5540, /* MHz */
.unk2 = 3693,
- RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2A, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+ PHYREGS(0x08AC, 0x08A8, 0x08A4, 0x01D8, 0x01D9, 0x01DA),
},
{ .channel = 110,
.freq = 5550, /* MHz */
.unk2 = 3700,
- RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2B, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+ PHYREGS(0x08B0, 0x08AC, 0x08A8, 0x01D7, 0x01D8, 0x01D9),
},
{ .channel = 112,
.freq = 5560, /* MHz */
.unk2 = 3707,
- RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2C, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+ PHYREGS(0x08B4, 0x08B0, 0x08AC, 0x01D7, 0x01D7, 0x01D8),
},
{ .channel = 114,
.freq = 5570, /* MHz */
.unk2 = 3713,
- RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2D, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+ PHYREGS(0x08B8, 0x08B4, 0x08B0, 0x01D6, 0x01D7, 0x01D7),
},
{ .channel = 116,
.freq = 5580, /* MHz */
.unk2 = 3720,
- RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2E, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+ PHYREGS(0x08BC, 0x08B8, 0x08B4, 0x01D5, 0x01D6, 0x01D7),
},
{ .channel = 118,
.freq = 5590, /* MHz */
.unk2 = 3727,
- RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2F, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+ PHYREGS(0x08C0, 0x08BC, 0x08B8, 0x01D4, 0x01D5, 0x01D6),
},
{ .channel = 120,
.freq = 5600, /* MHz */
.unk2 = 3733,
- RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x30, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+ PHYREGS(0x08C4, 0x08C0, 0x08BC, 0x01D3, 0x01D4, 0x01D5),
},
{ .channel = 122,
.freq = 5610, /* MHz */
.unk2 = 3740,
- RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x31, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+ PHYREGS(0x08C8, 0x08C4, 0x08C0, 0x01D2, 0x01D3, 0x01D4),
},
{ .channel = 124,
.freq = 5620, /* MHz */
.unk2 = 3747,
- RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x32, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+ PHYREGS(0x08CC, 0x08C8, 0x08C4, 0x01D2, 0x01D2, 0x01D3),
},
{ .channel = 126,
.freq = 5630, /* MHz */
.unk2 = 3753,
- RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x33, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+ PHYREGS(0x08D0, 0x08CC, 0x08C8, 0x01D1, 0x01D2, 0x01D2),
},
{ .channel = 128,
.freq = 5640, /* MHz */
.unk2 = 3760,
- RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x34, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+ PHYREGS(0x08D4, 0x08D0, 0x08CC, 0x01D0, 0x01D1, 0x01D2),
},
{ .channel = 130,
.freq = 5650, /* MHz */
.unk2 = 3767,
- RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x35, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+ PHYREGS(0x08D8, 0x08D4, 0x08D0, 0x01CF, 0x01D0, 0x01D1),
},
{ .channel = 132,
.freq = 5660, /* MHz */
.unk2 = 3773,
- RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x36, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+ PHYREGS(0x08DC, 0x08D8, 0x08D4, 0x01CE, 0x01CF, 0x01D0),
},
{ .channel = 134,
.freq = 5670, /* MHz */
.unk2 = 3780,
- RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x37, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+ PHYREGS(0x08E0, 0x08DC, 0x08D8, 0x01CE, 0x01CE, 0x01CF),
},
{ .channel = 136,
.freq = 5680, /* MHz */
.unk2 = 3787,
- RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x38, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+ PHYREGS(0x08E4, 0x08E0, 0x08DC, 0x01CD, 0x01CE, 0x01CE),
},
{ .channel = 138,
.freq = 5690, /* MHz */
.unk2 = 3793,
- RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x39, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+ PHYREGS(0x08E8, 0x08E4, 0x08E0, 0x01CC, 0x01CD, 0x01CE),
},
{ .channel = 140,
.freq = 5700, /* MHz */
.unk2 = 3800,
- RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3A, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+ PHYREGS(0x08EC, 0x08E8, 0x08E4, 0x01CB, 0x01CC, 0x01CD),
},
{ .channel = 142,
.freq = 5710, /* MHz */
.unk2 = 3807,
- RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3B, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+ PHYREGS(0x08F0, 0x08EC, 0x08E8, 0x01CA, 0x01CB, 0x01CC),
},
{ .channel = 144,
.freq = 5720, /* MHz */
.unk2 = 3813,
- RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3C, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+ PHYREGS(0x08F4, 0x08F0, 0x08EC, 0x01C9, 0x01CA, 0x01CB),
},
{ .channel = 145,
.freq = 5725, /* MHz */
.unk2 = 3817,
- RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+ RADIOREGS(0x72, 0x79, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+ PHYREGS(0x08F6, 0x08F2, 0x08EE, 0x01C9, 0x01CA, 0x01CB),
},
{ .channel = 146,
.freq = 5730, /* MHz */
.unk2 = 3820,
- RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3D, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+ PHYREGS(0x08F8, 0x08F4, 0x08F0, 0x01C9, 0x01C9, 0x01CA),
},
{ .channel = 147,
.freq = 5735, /* MHz */
.unk2 = 3823,
- RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7B, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+ PHYREGS(0x08FA, 0x08F6, 0x08F2, 0x01C8, 0x01C9, 0x01CA),
},
{ .channel = 148,
.freq = 5740, /* MHz */
.unk2 = 3827,
- RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3E, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+ PHYREGS(0x08FC, 0x08F8, 0x08F4, 0x01C8, 0x01C9, 0x01C9),
},
{ .channel = 149,
.freq = 5745, /* MHz */
.unk2 = 3830,
- RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7D, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+ PHYREGS(0x08FE, 0x08FA, 0x08F6, 0x01C8, 0x01C8, 0x01C9),
},
{ .channel = 150,
.freq = 5750, /* MHz */
.unk2 = 3833,
- RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3F, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+ PHYREGS(0x0900, 0x08FC, 0x08F8, 0x01C7, 0x01C8, 0x01C9),
},
{ .channel = 151,
.freq = 5755, /* MHz */
.unk2 = 3837,
- RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7F, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+ PHYREGS(0x0902, 0x08FE, 0x08FA, 0x01C7, 0x01C8, 0x01C8),
},
{ .channel = 152,
.freq = 5760, /* MHz */
.unk2 = 3840,
- RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x40, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+ PHYREGS(0x0904, 0x0900, 0x08FC, 0x01C6, 0x01C7, 0x01C8),
},
{ .channel = 153,
.freq = 5765, /* MHz */
.unk2 = 3843,
- RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x81, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+ PHYREGS(0x0906, 0x0902, 0x08FE, 0x01C6, 0x01C7, 0x01C8),
},
{ .channel = 154,
.freq = 5770, /* MHz */
.unk2 = 3847,
- RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x41, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01C6, 0x01C6, 0x01C7),
},
{ .channel = 155,
.freq = 5775, /* MHz */
.unk2 = 3850,
- RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x83, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+ PHYREGS(0x090A, 0x0906, 0x0902, 0x01C5, 0x01C6, 0x01C7),
},
{ .channel = 156,
.freq = 5780, /* MHz */
.unk2 = 3853,
- RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x42, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+ PHYREGS(0x090C, 0x0908, 0x0904, 0x01C5, 0x01C6, 0x01C6),
},
{ .channel = 157,
.freq = 5785, /* MHz */
.unk2 = 3857,
- RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x85, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+ PHYREGS(0x090E, 0x090A, 0x0906, 0x01C4, 0x01C5, 0x01C6),
},
{ .channel = 158,
.freq = 5790, /* MHz */
.unk2 = 3860,
- RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x43, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+ PHYREGS(0x0910, 0x090C, 0x0908, 0x01C4, 0x01C5, 0x01C6),
},
{ .channel = 159,
.freq = 5795, /* MHz */
.unk2 = 3863,
- RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x87, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+ PHYREGS(0x0912, 0x090E, 0x090A, 0x01C4, 0x01C4, 0x01C5),
},
{ .channel = 160,
.freq = 5800, /* MHz */
.unk2 = 3867,
- RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x44, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+ PHYREGS(0x0914, 0x0910, 0x090C, 0x01C3, 0x01C4, 0x01C5),
},
{ .channel = 161,
.freq = 5805, /* MHz */
.unk2 = 3870,
- RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x89, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+ PHYREGS(0x0916, 0x0912, 0x090E, 0x01C3, 0x01C4, 0x01C4),
},
{ .channel = 162,
.freq = 5810, /* MHz */
.unk2 = 3873,
- RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x45, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01C2, 0x01C3, 0x01C4),
},
{ .channel = 163,
.freq = 5815, /* MHz */
.unk2 = 3877,
- RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x8B, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+ PHYREGS(0x091A, 0x0916, 0x0912, 0x01C2, 0x01C3, 0x01C4),
},
{ .channel = 164,
.freq = 5820, /* MHz */
.unk2 = 3880,
- RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x46, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+ PHYREGS(0x091C, 0x0918, 0x0914, 0x01C2, 0x01C2, 0x01C3),
},
{ .channel = 165,
.freq = 5825, /* MHz */
.unk2 = 3883,
- RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x8D, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+ PHYREGS(0x091E, 0x091A, 0x0916, 0x01C1, 0x01C2, 0x01C3),
},
{ .channel = 166,
.freq = 5830, /* MHz */
.unk2 = 3887,
- RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x47, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+ PHYREGS(0x0920, 0x091C, 0x0918, 0x01C1, 0x01C2, 0x01C2),
},
{ .channel = 168,
.freq = 5840, /* MHz */
.unk2 = 3893,
- RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x48, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+ PHYREGS(0x0924, 0x0920, 0x091C, 0x01C0, 0x01C1, 0x01C2),
},
{ .channel = 170,
.freq = 5850, /* MHz */
.unk2 = 3900,
- RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x49, 0x02, 0x01, 0xE0, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01BF, 0x01C0, 0x01C1),
},
{ .channel = 172,
.freq = 5860, /* MHz */
.unk2 = 3907,
- RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4A, 0x02, 0x01, 0xDE, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+ PHYREGS(0x092C, 0x0928, 0x0924, 0x01BF, 0x01BF, 0x01C0),
},
{ .channel = 174,
.freq = 5870, /* MHz */
.unk2 = 3913,
- RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4B, 0x02, 0x00, 0xDB, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+ PHYREGS(0x0930, 0x092C, 0x0928, 0x01BE, 0x01BF, 0x01BF),
},
{ .channel = 176,
.freq = 5880, /* MHz */
.unk2 = 3920,
- RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4C, 0x02, 0x00, 0xD8, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+ PHYREGS(0x0934, 0x0930, 0x092C, 0x01BD, 0x01BE, 0x01BF),
},
{ .channel = 178,
.freq = 5890, /* MHz */
.unk2 = 3927,
- RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4D, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01BC, 0x01BD, 0x01BE),
},
{ .channel = 180,
.freq = 5900, /* MHz */
.unk2 = 3933,
- RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4E, 0x02, 0x00, 0xD3, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+ PHYREGS(0x093C, 0x0938, 0x0934, 0x01BC, 0x01BC, 0x01BD),
},
{ .channel = 182,
.freq = 5910, /* MHz */
.unk2 = 3940,
- RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4F, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+ PHYREGS(0x0940, 0x093C, 0x0938, 0x01BB, 0x01BC, 0x01BC),
},
{ .channel = 1,
.freq = 2412, /* MHz */
.unk2 = 3216,
- RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x6C, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
- PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+ PHYREGS(0x03C9, 0x03C5, 0x03C1, 0x043A, 0x043F, 0x0443),
},
{ .channel = 2,
.freq = 2417, /* MHz */
.unk2 = 3223,
- RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x71, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
- PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+ PHYREGS(0x03CB, 0x03C7, 0x03C3, 0x0438, 0x043D, 0x0441),
},
{ .channel = 3,
.freq = 2422, /* MHz */
.unk2 = 3229,
- RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x76, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+ PHYREGS(0x03CD, 0x03C9, 0x03C5, 0x0436, 0x043A, 0x043F),
},
{ .channel = 4,
.freq = 2427, /* MHz */
.unk2 = 3236,
- RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x7B, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+ PHYREGS(0x03CF, 0x03CB, 0x03C7, 0x0434, 0x0438, 0x043D),
},
{ .channel = 5,
.freq = 2432, /* MHz */
.unk2 = 3243,
- RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x80, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
- PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+ PHYREGS(0x03D1, 0x03CD, 0x03C9, 0x0431, 0x0436, 0x043A),
},
{ .channel = 6,
.freq = 2437, /* MHz */
.unk2 = 3249,
- RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x85, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
- PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+ PHYREGS(0x03D3, 0x03CF, 0x03CB, 0x042F, 0x0434, 0x0438),
},
{ .channel = 7,
.freq = 2442, /* MHz */
.unk2 = 3256,
- RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x8A, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
- PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+ PHYREGS(0x03D5, 0x03D1, 0x03CD, 0x042D, 0x0431, 0x0436),
},
{ .channel = 8,
.freq = 2447, /* MHz */
.unk2 = 3263,
- RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x8F, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
- PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+ PHYREGS(0x03D7, 0x03D3, 0x03CF, 0x042B, 0x042F, 0x0434),
},
{ .channel = 9,
.freq = 2452, /* MHz */
.unk2 = 3269,
- RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x94, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
- PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+ PHYREGS(0x03D9, 0x03D5, 0x03D1, 0x0429, 0x042D, 0x0431),
},
{ .channel = 10,
.freq = 2457, /* MHz */
.unk2 = 3276,
- RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x99, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
- PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+ PHYREGS(0x03DB, 0x03D7, 0x03D3, 0x0427, 0x042B, 0x042F),
},
{ .channel = 11,
.freq = 2462, /* MHz */
.unk2 = 3283,
- RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x9E, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
- PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+ PHYREGS(0x03DD, 0x03D9, 0x03D5, 0x0424, 0x0429, 0x042D),
},
{ .channel = 12,
.freq = 2467, /* MHz */
.unk2 = 3289,
- RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xA3, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
- PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+ PHYREGS(0x03DF, 0x03DB, 0x03D7, 0x0422, 0x0427, 0x042B),
},
{ .channel = 13,
.freq = 2472, /* MHz */
.unk2 = 3296,
- RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xA8, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
- PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+ PHYREGS(0x03E1, 0x03DD, 0x03D9, 0x0420, 0x0424, 0x0429),
},
{ .channel = 14,
.freq = 2484, /* MHz */
.unk2 = 3312,
- RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xB4, 0x09, 0x0F, 0xFF, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
- PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+ PHYREGS(0x03E6, 0x03E2, 0x03DE, 0x041B, 0x041F, 0x0424),
},
};
@@ -1299,7 +1299,7 @@ void b2055_upload_inittab(struct b43_wldev *dev,
bool ghz5, bool ignore_uploadflag)
{
const struct b2055_inittab_entry *e;
- unsigned int i;
+ unsigned int i, writes = 0;
u16 value;
for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
@@ -1312,6 +1312,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
else
value = e->ghz2;
b43_radio_write16(dev, i, value);
+ if (++writes % 4 == 0)
+ b43_read32(dev, B43_MMIO_MACCTL); /* flush */
}
}
}
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
index d8563192ce56..8890df067029 100644
--- a/drivers/net/wireless/b43/radio_2056.c
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -24,17 +24,9073 @@
#include "radio_2056.h"
#include "phy_common.h"
+struct b2056_inittab_entry {
+ /* Value to write if we use the 5GHz band. */
+ u16 ghz5;
+ /* Value to write if we use the 2.4GHz band. */
+ u16 ghz2;
+ /* Flags */
+ u8 flags;
+};
+#define B2056_INITTAB_ENTRY_OK 0x01
+#define B2056_INITTAB_UPLOAD 0x02
+#define UPLOAD .flags = B2056_INITTAB_ENTRY_OK | B2056_INITTAB_UPLOAD
+#define NOUPLOAD .flags = B2056_INITTAB_ENTRY_OK
+
+struct b2056_inittabs_pts {
+ const struct b2056_inittab_entry *syn;
+ unsigned int syn_length;
+ const struct b2056_inittab_entry *tx;
+ unsigned int tx_length;
+ const struct b2056_inittab_entry *rx;
+ unsigned int rx_length;
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev3_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev3_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev3_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0099, .ghz2 = 0x0099, NOUPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0044, .ghz2 = 0x0044, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0099, .ghz2 = 0x0099, NOUPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x0057, .ghz2 = 0x0057, NOUPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x0057, .ghz2 = 0x0057, NOUPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev4_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev4_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev4_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0044, .ghz2 = 0x0044, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x002f, .ghz2 = 0x002f, UPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev5_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev5_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x002d, .ghz2 = 0x002d, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, },
+ [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, },
+ [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, },
+ [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0073, .ghz2 = 0x0073, UPLOAD, },
+ [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, },
+ [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev5_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev6_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev6_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev7_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev7_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, },
+ [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0071, .ghz2 = 0x0071, UPLOAD, },
+ [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0072, .ghz2 = 0x0072, UPLOAD, },
+ [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0073, .ghz2 = 0x0073, UPLOAD, },
+ [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0074, .ghz2 = 0x0074, UPLOAD, },
+ [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev7_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev8_syn[] = {
+ [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_PU] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_GPIO_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_MASTER] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_TOPBIAS_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_AFEREG] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSEIDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_TEMPPROCSENSERCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LPO] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_VDDCAL_STATUS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCAL_CODE_OUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL1] = { .ghz5 = 0x001f, .ghz2 = 0x001f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL2] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL3] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_RCCAL_CTRL11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_ZCAL_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST1] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST2] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_MAST3] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2056_SYN_PLL_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL1] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL3] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
+ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
+ [B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO1] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
+ [B2056_SYN_PLL_MONITOR1] = { .ghz5 = 0x00b4, .ghz2 = 0x00b4, NOUPLOAD, },
+ [B2056_SYN_PLL_MONITOR2] = { .ghz5 = 0x00d2, .ghz2 = 0x00d2, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL4] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL6] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL7] = { .ghz5 = 0x003e, .ghz2 = 0x003e, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_SYN_PLL_VCOCAL13] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_SYN_PLL_VREG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_PLL_STATUS3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU2] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PU8] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BIAS_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RCCR1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF1] = { .ghz5 = 0x0060, .ghz2 = 0x0060, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER2] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF1] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
+ [B2056_SYN_LOGEN_BUF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF4] = { .ghz5 = 0x00cc, .ghz2 = 0x00cc, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV1] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV2] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_DIV3] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLOUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACLCAL3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_CALEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_PEAKDET1] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_DIFF_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_ACL_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_VCOBUF2_OVRVAL]= { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_SYN_LOGEN_MIXER3_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF5_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_BUF6_OVRVAL] = { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CBUFTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSRX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX1_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX2_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX3_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CMOSTX4_OVRVAL]= { .ghz5 = 0x0066, .ghz2 = 0x0066, NOUPLOAD, },
+ [B2056_SYN_LOGEN_ACL_WAITCNT] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_SYN_LOGEN_CORE_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_RX_CMOS_CALVALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev8_tx[] = {
+ [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_GAIN_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_FINE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_I] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_LOFT_COARSE_Q] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER1] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_TX_COM_MASTER2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_RXIQCAL_TXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_IQCAL_VCM_HG] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_IQCAL_IDAC] = { .ghz5 = 0x0037, .ghz2 = 0x0037, NOUPLOAD, },
+ [B2056_TX_TSSI_VCM] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_TX_AMP_DET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TX_SSI_MUX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSIA] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSIG] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TSSI_MISC3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PA_SPARE1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, },
+ [B2056_TX_INTPAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
+ [B2056_TX_INTPAA_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAA_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAA_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_BOOST_TUNE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_STAT] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_TX_INTPAG_IAUX_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_STAT] = { .ghz5 = 0x001e, .ghz2 = 0x001e, NOUPLOAD, },
+ [B2056_TX_INTPAG_IMAIN_DYN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_INTPAG_CASCBIAS] = { .ghz5 = 0x006e, .ghz2 = 0x006e, NOUPLOAD, },
+ [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_TX_INTPAG_PA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PADA_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADA_BOOST_TUNE] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PADG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PADG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PADG_CASCBIAS] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_TX_PADG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PADG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
+ [B2056_TX_PGAA_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_TX_PGAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAA_BOOST_TUNE] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAA_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_MASTER] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_PGAG_IDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_TX_PGAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_PGAG_BOOST_TUNE] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
+ [B2056_TX_PGAG_MISC] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_TX_MIXA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXA_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_MIXG] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_MIXG_BOOST_TUNE] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_TX_BB_GM_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_GM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_TX_TXLPF_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_RCCAL_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_BW] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_TX_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_0] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_1] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_2] = { .ghz5 = 0x000e, .ghz2 = 0x000e, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_4] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_5] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_IDAC_6] = { .ghz5 = 0x001b, .ghz2 = 0x001b, NOUPLOAD, },
+ [B2056_TX_TXLPF_OPAMP_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_TX_TXLPF_MISC] = { .ghz5 = 0x005b, .ghz2 = 0x005b, NOUPLOAD, },
+ [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, },
+ [B2056_TX_TXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_TXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_INTPA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PAD_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_PGA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_GM_TXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC0] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC1] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC2] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC3] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC4] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC5] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC6] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+};
+
+static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = {
+ [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_CTRL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_OVR] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RESET] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RCAL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_TXLPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_COM_RC_RXHPF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR17] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR18] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR19] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR20] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR21] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR22] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR23] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR24] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR25] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR26] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR27] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR28] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR29] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR30] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RESERVED_ADDR31] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXIQCAL_RXMUX] = { .ghz5 = 0x0003, .ghz2 = 0x0003, NOUPLOAD, },
+ [B2056_RX_RSSI_PU] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_SEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RSSI_GAIN] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_RSSI_NB_IDAC] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2I_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2056_RX_RSSI_WB2Q_IDAC_2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, NOUPLOAD, },
+ [B2056_RX_RSSI_POLE] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_RSSI_WB1_IDAC] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_RSSI_MISC] = { .ghz5 = 0x0090, .ghz2 = 0x0090, NOUPLOAD, },
+ [B2056_RX_LNAA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAA_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAA_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_A_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
+ [B2056_RX_LNA1A_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_LNAG_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_LNAG_TUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2056_RX_LNAG_GAIN] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
+ [B2056_RX_LNA_G_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
+ [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
+ [B2056_RX_LNA1G_MISC] = { .ghz5 = 0x0020, .ghz2 = 0x0020, NOUPLOAD, },
+ [B2056_RX_MIXA_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXA_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
+ [B2056_RX_MIXA_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXA_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2056_RX_MIXA_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXA_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXA_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
+ [B2056_RX_MIXG_CTRLPTAT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_LOB_BIAS] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2056_RX_MIXG_CORE_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_MIXG_CMFB_IDAC] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MAIN] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2056_RX_MIXG_BIAS_MISC] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
+ [B2056_RX_MIXG_MAST_BIAS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_MASTER] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
+ [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
+ [B2056_RX_TIA_GAIN] = { .ghz5 = 0x0044, .ghz2 = 0x0044, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TIA_SPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_BB_LPF_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_AACI_MASTER] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2056_RX_RXLPF_IDAC] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_LOWQ] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_OPAMPBIAS_HIGHQ]= { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_RXLPF_BIAS_DCCANCEL] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2056_RX_RXLPF_INVCM_BODY] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2056_RX_RXLPF_CC_OP] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2056_RX_RXLPF_GAIN] = { .ghz5 = 0x0023, .ghz2 = 0x0023, NOUPLOAD, },
+ [B2056_RX_RXLPF_Q_BW] = { .ghz5 = 0x0041, .ghz2 = 0x0041, NOUPLOAD, },
+ [B2056_RX_RXLPF_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_HPC] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXHPF_OFF7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_RCCAL_LPC] = { .ghz5 = 0x000c, .ghz2 = 0x000c, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXLPF_OFF_4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_UNUSED] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_VGA_MASTER] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
+ [B2056_RX_VGA_GAIN] = { .ghz5 = 0x000a, .ghz2 = 0x000a, NOUPLOAD, },
+ [B2056_RX_VGA_HP_CORNER_BW] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2056_RX_VGABUF_BIAS] = { .ghz5 = 0x0022, .ghz2 = 0x0022, NOUPLOAD, },
+ [B2056_RX_VGABUF_GAIN_BW] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_A] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_TXFBMIX_G] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+ [B2056_RX_RXSPARE4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE6] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE10] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE11] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_RXSPARE16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_LNAG_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_MIXTIA_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_VGA_BUF_GAIN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_Q] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_BUF_BW] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_VGA_HPC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_RXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+#define INITTABSPTS(prefix) \
+ .syn = prefix##_syn, \
+ .syn_length = ARRAY_SIZE(prefix##_syn), \
+ .tx = prefix##_tx, \
+ .tx_length = ARRAY_SIZE(prefix##_tx), \
+ .rx = prefix##_rx, \
+ .rx_length = ARRAY_SIZE(prefix##_rx)
+
+struct b2056_inittabs_pts b2056_inittabs[] = {
+ [3] = { INITTABSPTS(b2056_inittab_rev3) },
+ [4] = { INITTABSPTS(b2056_inittab_rev4) },
+ [5] = { INITTABSPTS(b2056_inittab_rev5) },
+ [6] = { INITTABSPTS(b2056_inittab_rev6) },
+ [7] = { INITTABSPTS(b2056_inittab_rev7) },
+ [8] = { INITTABSPTS(b2056_inittab_rev8) },
+ [9] = { INITTABSPTS(b2056_inittab_rev7) },
+};
+
+#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
+ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
+ r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \
+ r30, r31, r32, r33, r34, r35, r36) \
+ .radio_syn_pll_vcocal1 = r00, \
+ .radio_syn_pll_vcocal2 = r01, \
+ .radio_syn_pll_refdiv = r02, \
+ .radio_syn_pll_mmd2 = r03, \
+ .radio_syn_pll_mmd1 = r04, \
+ .radio_syn_pll_loopfilter1 = r05, \
+ .radio_syn_pll_loopfilter2 = r06, \
+ .radio_syn_pll_loopfilter3 = r07, \
+ .radio_syn_pll_loopfilter4 = r08, \
+ .radio_syn_pll_loopfilter5 = r09, \
+ .radio_syn_reserved_addr27 = r10, \
+ .radio_syn_reserved_addr28 = r11, \
+ .radio_syn_reserved_addr29 = r12, \
+ .radio_syn_logen_vcobuf1 = r13, \
+ .radio_syn_logen_mixer2 = r14, \
+ .radio_syn_logen_buf3 = r15, \
+ .radio_syn_logen_buf4 = r16, \
+ .radio_rx0_lnaa_tune = r17, \
+ .radio_rx0_lnag_tune = r18, \
+ .radio_tx0_intpaa_boost_tune = r19, \
+ .radio_tx0_intpag_boost_tune = r20, \
+ .radio_tx0_pada_boost_tune = r21, \
+ .radio_tx0_padg_boost_tune = r22, \
+ .radio_tx0_pgaa_boost_tune = r23, \
+ .radio_tx0_pgag_boost_tune = r24, \
+ .radio_tx0_mixa_boost_tune = r25, \
+ .radio_tx0_mixg_boost_tune = r26, \
+ .radio_rx1_lnaa_tune = r27, \
+ .radio_rx1_lnag_tune = r28, \
+ .radio_tx1_intpaa_boost_tune = r29, \
+ .radio_tx1_intpag_boost_tune = r30, \
+ .radio_tx1_pada_boost_tune = r31, \
+ .radio_tx1_padg_boost_tune = r32, \
+ .radio_tx1_pgaa_boost_tune = r33, \
+ .radio_tx1_pgag_boost_tune = r34, \
+ .radio_tx1_mixa_boost_tune = r35, \
+ .radio_tx1_mixg_boost_tune = r36
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5) \
+ .phy_regs.phy_bw1a = r0, \
+ .phy_regs.phy_bw2 = r1, \
+ .phy_regs.phy_bw3 = r2, \
+ .phy_regs.phy_bw4 = r3, \
+ .phy_regs.phy_bw5 = r4, \
+ .phy_regs.phy_bw6 = r5
+
+/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfc, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5b, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x5a, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x75, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x75, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x75, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7b, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x7a, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x79, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x79, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x85, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x85, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x85, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
};
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5,
+ bool ignore_uploadflag, u16 routing,
+ const struct b2056_inittab_entry *e,
+ unsigned int length)
+{
+ unsigned int i;
+ u16 value;
+
+ for (i = 0; i < length; i++, e++) {
+ if (!(e->flags & B2056_INITTAB_ENTRY_OK))
+ continue;
+ if ((e->flags & B2056_INITTAB_UPLOAD) || ignore_uploadflag) {
+ if (ghz5)
+ value = e->ghz5;
+ else
+ value = e->ghz2;
+ b43_radio_write(dev, routing | i, value);
+ }
+ }
+}
+
+void b2056_upload_inittabs(struct b43_wldev *dev,
+ bool ghz5, bool ignore_uploadflag)
+{
+ struct b2056_inittabs_pts *pts;
+
+ if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
+ B43_WARN_ON(1);
+ return;
+ }
+ pts = &b2056_inittabs[dev->phy.rev];
+
+ b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
+ B2056_SYN, pts->syn, pts->syn_length);
+ b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
+ B2056_TX0, pts->tx, pts->tx_length);
+ b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
+ B2056_TX1, pts->tx, pts->tx_length);
+ b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
+ B2056_RX0, pts->rx, pts->rx_length);
+ b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
+ B2056_RX1, pts->rx, pts->rx_length);
+}
+
const struct b43_nphy_channeltab_entry_rev3 *
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
{
const struct b43_nphy_channeltab_entry_rev3 *e;
- unsigned int i;
+ unsigned int length, i;
+
+ switch (dev->phy.rev) {
+ case 3:
+ e = b43_nphy_channeltab_rev3;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev3);
+ break;
+ case 4:
+ e = b43_nphy_channeltab_rev4;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev4);
+ break;
+ case 5:
+ e = b43_nphy_channeltab_rev5;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev5);
+ break;
+ case 6:
+ e = b43_nphy_channeltab_rev6;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev6);
+ break;
+ case 7:
+ case 9:
+ e = b43_nphy_channeltab_rev7_9;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev7_9);
+ break;
+ case 8:
+ e = b43_nphy_channeltab_rev8;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev8);
+ break;
+ default:
+ B43_WARN_ON(1);
+ return NULL;
+ }
- for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
- e = &(b43_nphy_channeltab_rev3[i]);
+ for (i = 0; i < length; i++, e++) {
if (e->freq == freq)
return e;
}
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
index fda6dafecb8c..d601f6e7e313 100644
--- a/drivers/net/wireless/b43/radio_2056.h
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -4,6 +4,9 @@
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
+ Some parts of the code in this file are derived from the brcm80211
+ driver Copyright (c) 2010 Broadcom 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
@@ -28,15 +31,1090 @@
#include "tables_nphy.h"
+#define B2056_SYN (0x0 << 12)
+#define B2056_TX0 (0x2 << 12)
+#define B2056_TX1 (0x3 << 12)
+#define B2056_RX0 (0x6 << 12)
+#define B2056_RX1 (0x7 << 12)
+#define B2056_ALLTX (0xE << 12)
+#define B2056_ALLRX (0xF << 12)
+
+#define B2056_SYN_RESERVED_ADDR0 0x00
+#define B2056_SYN_IDCODE 0x01
+#define B2056_SYN_RESERVED_ADDR2 0x02
+#define B2056_SYN_RESERVED_ADDR3 0x03
+#define B2056_SYN_RESERVED_ADDR4 0x04
+#define B2056_SYN_RESERVED_ADDR5 0x05
+#define B2056_SYN_RESERVED_ADDR6 0x06
+#define B2056_SYN_RESERVED_ADDR7 0x07
+#define B2056_SYN_COM_CTRL 0x08
+#define B2056_SYN_COM_PU 0x09
+#define B2056_SYN_COM_OVR 0x0A
+#define B2056_SYN_COM_RESET 0x0B
+#define B2056_SYN_COM_RCAL 0x0C
+#define B2056_SYN_COM_RC_RXLPF 0x0D
+#define B2056_SYN_COM_RC_TXLPF 0x0E
+#define B2056_SYN_COM_RC_RXHPF 0x0F
+#define B2056_SYN_RESERVED_ADDR16 0x10
+#define B2056_SYN_RESERVED_ADDR17 0x11
+#define B2056_SYN_RESERVED_ADDR18 0x12
+#define B2056_SYN_RESERVED_ADDR19 0x13
+#define B2056_SYN_RESERVED_ADDR20 0x14
+#define B2056_SYN_RESERVED_ADDR21 0x15
+#define B2056_SYN_RESERVED_ADDR22 0x16
+#define B2056_SYN_RESERVED_ADDR23 0x17
+#define B2056_SYN_RESERVED_ADDR24 0x18
+#define B2056_SYN_RESERVED_ADDR25 0x19
+#define B2056_SYN_RESERVED_ADDR26 0x1A
+#define B2056_SYN_RESERVED_ADDR27 0x1B
+#define B2056_SYN_RESERVED_ADDR28 0x1C
+#define B2056_SYN_RESERVED_ADDR29 0x1D
+#define B2056_SYN_RESERVED_ADDR30 0x1E
+#define B2056_SYN_RESERVED_ADDR31 0x1F
+#define B2056_SYN_GPIO_MASTER1 0x20
+#define B2056_SYN_GPIO_MASTER2 0x21
+#define B2056_SYN_TOPBIAS_MASTER 0x22
+#define B2056_SYN_TOPBIAS_RCAL 0x23
+#define B2056_SYN_AFEREG 0x24
+#define B2056_SYN_TEMPPROCSENSE 0x25
+#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
+#define B2056_SYN_TEMPPROCSENSERCAL 0x27
+#define B2056_SYN_LPO 0x28
+#define B2056_SYN_VDDCAL_MASTER 0x29
+#define B2056_SYN_VDDCAL_IDAC 0x2A
+#define B2056_SYN_VDDCAL_STATUS 0x2B
+#define B2056_SYN_RCAL_MASTER 0x2C
+#define B2056_SYN_RCAL_CODE_OUT 0x2D
+#define B2056_SYN_RCCAL_CTRL0 0x2E
+#define B2056_SYN_RCCAL_CTRL1 0x2F
+#define B2056_SYN_RCCAL_CTRL2 0x30
+#define B2056_SYN_RCCAL_CTRL3 0x31
+#define B2056_SYN_RCCAL_CTRL4 0x32
+#define B2056_SYN_RCCAL_CTRL5 0x33
+#define B2056_SYN_RCCAL_CTRL6 0x34
+#define B2056_SYN_RCCAL_CTRL7 0x35
+#define B2056_SYN_RCCAL_CTRL8 0x36
+#define B2056_SYN_RCCAL_CTRL9 0x37
+#define B2056_SYN_RCCAL_CTRL10 0x38
+#define B2056_SYN_RCCAL_CTRL11 0x39
+#define B2056_SYN_ZCAL_SPARE1 0x3A
+#define B2056_SYN_ZCAL_SPARE2 0x3B
+#define B2056_SYN_PLL_MAST1 0x3C
+#define B2056_SYN_PLL_MAST2 0x3D
+#define B2056_SYN_PLL_MAST3 0x3E
+#define B2056_SYN_PLL_BIAS_RESET 0x3F
+#define B2056_SYN_PLL_XTAL0 0x40
+#define B2056_SYN_PLL_XTAL1 0x41
+#define B2056_SYN_PLL_XTAL3 0x42
+#define B2056_SYN_PLL_XTAL4 0x43
+#define B2056_SYN_PLL_XTAL5 0x44
+#define B2056_SYN_PLL_XTAL6 0x45
+#define B2056_SYN_PLL_REFDIV 0x46
+#define B2056_SYN_PLL_PFD 0x47
+#define B2056_SYN_PLL_CP1 0x48
+#define B2056_SYN_PLL_CP2 0x49
+#define B2056_SYN_PLL_CP3 0x4A
+#define B2056_SYN_PLL_LOOPFILTER1 0x4B
+#define B2056_SYN_PLL_LOOPFILTER2 0x4C
+#define B2056_SYN_PLL_LOOPFILTER3 0x4D
+#define B2056_SYN_PLL_LOOPFILTER4 0x4E
+#define B2056_SYN_PLL_LOOPFILTER5 0x4F
+#define B2056_SYN_PLL_MMD1 0x50
+#define B2056_SYN_PLL_MMD2 0x51
+#define B2056_SYN_PLL_VCO1 0x52
+#define B2056_SYN_PLL_VCO2 0x53
+#define B2056_SYN_PLL_MONITOR1 0x54
+#define B2056_SYN_PLL_MONITOR2 0x55
+#define B2056_SYN_PLL_VCOCAL1 0x56
+#define B2056_SYN_PLL_VCOCAL2 0x57
+#define B2056_SYN_PLL_VCOCAL4 0x58
+#define B2056_SYN_PLL_VCOCAL5 0x59
+#define B2056_SYN_PLL_VCOCAL6 0x5A
+#define B2056_SYN_PLL_VCOCAL7 0x5B
+#define B2056_SYN_PLL_VCOCAL8 0x5C
+#define B2056_SYN_PLL_VCOCAL9 0x5D
+#define B2056_SYN_PLL_VCOCAL10 0x5E
+#define B2056_SYN_PLL_VCOCAL11 0x5F
+#define B2056_SYN_PLL_VCOCAL12 0x60
+#define B2056_SYN_PLL_VCOCAL13 0x61
+#define B2056_SYN_PLL_VREG 0x62
+#define B2056_SYN_PLL_STATUS1 0x63
+#define B2056_SYN_PLL_STATUS2 0x64
+#define B2056_SYN_PLL_STATUS3 0x65
+#define B2056_SYN_LOGEN_PU0 0x66
+#define B2056_SYN_LOGEN_PU1 0x67
+#define B2056_SYN_LOGEN_PU2 0x68
+#define B2056_SYN_LOGEN_PU3 0x69
+#define B2056_SYN_LOGEN_PU5 0x6A
+#define B2056_SYN_LOGEN_PU6 0x6B
+#define B2056_SYN_LOGEN_PU7 0x6C
+#define B2056_SYN_LOGEN_PU8 0x6D
+#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
+#define B2056_SYN_LOGEN_RCCR1 0x6F
+#define B2056_SYN_LOGEN_VCOBUF1 0x70
+#define B2056_SYN_LOGEN_MIXER1 0x71
+#define B2056_SYN_LOGEN_MIXER2 0x72
+#define B2056_SYN_LOGEN_BUF1 0x73
+#define B2056_SYN_LOGENBUF2 0x74
+#define B2056_SYN_LOGEN_BUF3 0x75
+#define B2056_SYN_LOGEN_BUF4 0x76
+#define B2056_SYN_LOGEN_DIV1 0x77
+#define B2056_SYN_LOGEN_DIV2 0x78
+#define B2056_SYN_LOGEN_DIV3 0x79
+#define B2056_SYN_LOGEN_ACL1 0x7A
+#define B2056_SYN_LOGEN_ACL2 0x7B
+#define B2056_SYN_LOGEN_ACL3 0x7C
+#define B2056_SYN_LOGEN_ACL4 0x7D
+#define B2056_SYN_LOGEN_ACL5 0x7E
+#define B2056_SYN_LOGEN_ACL6 0x7F
+#define B2056_SYN_LOGEN_ACLOUT 0x80
+#define B2056_SYN_LOGEN_ACLCAL1 0x81
+#define B2056_SYN_LOGEN_ACLCAL2 0x82
+#define B2056_SYN_LOGEN_ACLCAL3 0x83
+#define B2056_SYN_CALEN 0x84
+#define B2056_SYN_LOGEN_PEAKDET1 0x85
+#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
+#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
+#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
+#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
+#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
+#define B2056_SYN_LOGEN_VCOBUF2 0x8B
+#define B2056_SYN_LOGEN_MIXER3 0x8C
+#define B2056_SYN_LOGEN_BUF5 0x8D
+#define B2056_SYN_LOGEN_BUF6 0x8E
+#define B2056_SYN_LOGEN_CBUFRX1 0x8F
+#define B2056_SYN_LOGEN_CBUFRX2 0x90
+#define B2056_SYN_LOGEN_CBUFRX3 0x91
+#define B2056_SYN_LOGEN_CBUFRX4 0x92
+#define B2056_SYN_LOGEN_CBUFTX1 0x93
+#define B2056_SYN_LOGEN_CBUFTX2 0x94
+#define B2056_SYN_LOGEN_CBUFTX3 0x95
+#define B2056_SYN_LOGEN_CBUFTX4 0x96
+#define B2056_SYN_LOGEN_CMOSRX1 0x97
+#define B2056_SYN_LOGEN_CMOSRX2 0x98
+#define B2056_SYN_LOGEN_CMOSRX3 0x99
+#define B2056_SYN_LOGEN_CMOSRX4 0x9A
+#define B2056_SYN_LOGEN_CMOSTX1 0x9B
+#define B2056_SYN_LOGEN_CMOSTX2 0x9C
+#define B2056_SYN_LOGEN_CMOSTX3 0x9D
+#define B2056_SYN_LOGEN_CMOSTX4 0x9E
+#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
+#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
+#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
+#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
+#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
+#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
+#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
+#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
+#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
+#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
+#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
+#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
+#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
+#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
+#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
+#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
+#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
+#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
+#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
+#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
+#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
+#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
+#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
+#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
+
+#define B2056_TX_RESERVED_ADDR0 0x00
+#define B2056_TX_IDCODE 0x01
+#define B2056_TX_RESERVED_ADDR2 0x02
+#define B2056_TX_RESERVED_ADDR3 0x03
+#define B2056_TX_RESERVED_ADDR4 0x04
+#define B2056_TX_RESERVED_ADDR5 0x05
+#define B2056_TX_RESERVED_ADDR6 0x06
+#define B2056_TX_RESERVED_ADDR7 0x07
+#define B2056_TX_COM_CTRL 0x08
+#define B2056_TX_COM_PU 0x09
+#define B2056_TX_COM_OVR 0x0A
+#define B2056_TX_COM_RESET 0x0B
+#define B2056_TX_COM_RCAL 0x0C
+#define B2056_TX_COM_RC_RXLPF 0x0D
+#define B2056_TX_COM_RC_TXLPF 0x0E
+#define B2056_TX_COM_RC_RXHPF 0x0F
+#define B2056_TX_RESERVED_ADDR16 0x10
+#define B2056_TX_RESERVED_ADDR17 0x11
+#define B2056_TX_RESERVED_ADDR18 0x12
+#define B2056_TX_RESERVED_ADDR19 0x13
+#define B2056_TX_RESERVED_ADDR20 0x14
+#define B2056_TX_RESERVED_ADDR21 0x15
+#define B2056_TX_RESERVED_ADDR22 0x16
+#define B2056_TX_RESERVED_ADDR23 0x17
+#define B2056_TX_RESERVED_ADDR24 0x18
+#define B2056_TX_RESERVED_ADDR25 0x19
+#define B2056_TX_RESERVED_ADDR26 0x1A
+#define B2056_TX_RESERVED_ADDR27 0x1B
+#define B2056_TX_RESERVED_ADDR28 0x1C
+#define B2056_TX_RESERVED_ADDR29 0x1D
+#define B2056_TX_RESERVED_ADDR30 0x1E
+#define B2056_TX_RESERVED_ADDR31 0x1F
+#define B2056_TX_IQCAL_GAIN_BW 0x20
+#define B2056_TX_LOFT_FINE_I 0x21
+#define B2056_TX_LOFT_FINE_Q 0x22
+#define B2056_TX_LOFT_COARSE_I 0x23
+#define B2056_TX_LOFT_COARSE_Q 0x24
+#define B2056_TX_TX_COM_MASTER1 0x25
+#define B2056_TX_TX_COM_MASTER2 0x26
+#define B2056_TX_RXIQCAL_TXMUX 0x27
+#define B2056_TX_TX_SSI_MASTER 0x28
+#define B2056_TX_IQCAL_VCM_HG 0x29
+#define B2056_TX_IQCAL_IDAC 0x2A
+#define B2056_TX_TSSI_VCM 0x2B
+#define B2056_TX_TX_AMP_DET 0x2C
+#define B2056_TX_TX_SSI_MUX 0x2D
+#define B2056_TX_TSSIA 0x2E
+#define B2056_TX_TSSIG 0x2F
+#define B2056_TX_TSSI_MISC1 0x30
+#define B2056_TX_TSSI_MISC2 0x31
+#define B2056_TX_TSSI_MISC3 0x32
+#define B2056_TX_PA_SPARE1 0x33
+#define B2056_TX_PA_SPARE2 0x34
+#define B2056_TX_INTPAA_MASTER 0x35
+#define B2056_TX_INTPAA_GAIN 0x36
+#define B2056_TX_INTPAA_BOOST_TUNE 0x37
+#define B2056_TX_INTPAA_IAUX_STAT 0x38
+#define B2056_TX_INTPAA_IAUX_DYN 0x39
+#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
+#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
+#define B2056_TX_INTPAA_CASCBIAS 0x3C
+#define B2056_TX_INTPAA_PASLOPE 0x3D
+#define B2056_TX_INTPAA_PA_MISC 0x3E
+#define B2056_TX_INTPAG_MASTER 0x3F
+#define B2056_TX_INTPAG_GAIN 0x40
+#define B2056_TX_INTPAG_BOOST_TUNE 0x41
+#define B2056_TX_INTPAG_IAUX_STAT 0x42
+#define B2056_TX_INTPAG_IAUX_DYN 0x43
+#define B2056_TX_INTPAG_IMAIN_STAT 0x44
+#define B2056_TX_INTPAG_IMAIN_DYN 0x45
+#define B2056_TX_INTPAG_CASCBIAS 0x46
+#define B2056_TX_INTPAG_PASLOPE 0x47
+#define B2056_TX_INTPAG_PA_MISC 0x48
+#define B2056_TX_PADA_MASTER 0x49
+#define B2056_TX_PADA_IDAC 0x4A
+#define B2056_TX_PADA_CASCBIAS 0x4B
+#define B2056_TX_PADA_GAIN 0x4C
+#define B2056_TX_PADA_BOOST_TUNE 0x4D
+#define B2056_TX_PADA_SLOPE 0x4E
+#define B2056_TX_PADG_MASTER 0x4F
+#define B2056_TX_PADG_IDAC 0x50
+#define B2056_TX_PADG_CASCBIAS 0x51
+#define B2056_TX_PADG_GAIN 0x52
+#define B2056_TX_PADG_BOOST_TUNE 0x53
+#define B2056_TX_PADG_SLOPE 0x54
+#define B2056_TX_PGAA_MASTER 0x55
+#define B2056_TX_PGAA_IDAC 0x56
+#define B2056_TX_PGAA_GAIN 0x57
+#define B2056_TX_PGAA_BOOST_TUNE 0x58
+#define B2056_TX_PGAA_SLOPE 0x59
+#define B2056_TX_PGAA_MISC 0x5A
+#define B2056_TX_PGAG_MASTER 0x5B
+#define B2056_TX_PGAG_IDAC 0x5C
+#define B2056_TX_PGAG_GAIN 0x5D
+#define B2056_TX_PGAG_BOOST_TUNE 0x5E
+#define B2056_TX_PGAG_SLOPE 0x5F
+#define B2056_TX_PGAG_MISC 0x60
+#define B2056_TX_MIXA_MASTER 0x61
+#define B2056_TX_MIXA_BOOST_TUNE 0x62
+#define B2056_TX_MIXG 0x63
+#define B2056_TX_MIXG_BOOST_TUNE 0x64
+#define B2056_TX_BB_GM_MASTER 0x65
+#define B2056_TX_GMBB_GM 0x66
+#define B2056_TX_GMBB_IDAC 0x67
+#define B2056_TX_TXLPF_MASTER 0x68
+#define B2056_TX_TXLPF_RCCAL 0x69
+#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
+#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
+#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
+#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
+#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
+#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
+#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
+#define B2056_TX_TXLPF_BW 0x71
+#define B2056_TX_TXLPF_GAIN 0x72
+#define B2056_TX_TXLPF_IDAC 0x73
+#define B2056_TX_TXLPF_IDAC_0 0x74
+#define B2056_TX_TXLPF_IDAC_1 0x75
+#define B2056_TX_TXLPF_IDAC_2 0x76
+#define B2056_TX_TXLPF_IDAC_3 0x77
+#define B2056_TX_TXLPF_IDAC_4 0x78
+#define B2056_TX_TXLPF_IDAC_5 0x79
+#define B2056_TX_TXLPF_IDAC_6 0x7A
+#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
+#define B2056_TX_TXLPF_MISC 0x7C
+#define B2056_TX_TXSPARE1 0x7D
+#define B2056_TX_TXSPARE2 0x7E
+#define B2056_TX_TXSPARE3 0x7F
+#define B2056_TX_TXSPARE4 0x80
+#define B2056_TX_TXSPARE5 0x81
+#define B2056_TX_TXSPARE6 0x82
+#define B2056_TX_TXSPARE7 0x83
+#define B2056_TX_TXSPARE8 0x84
+#define B2056_TX_TXSPARE9 0x85
+#define B2056_TX_TXSPARE10 0x86
+#define B2056_TX_TXSPARE11 0x87
+#define B2056_TX_TXSPARE12 0x88
+#define B2056_TX_TXSPARE13 0x89
+#define B2056_TX_TXSPARE14 0x8A
+#define B2056_TX_TXSPARE15 0x8B
+#define B2056_TX_TXSPARE16 0x8C
+#define B2056_TX_STATUS_INTPA_GAIN 0x8D
+#define B2056_TX_STATUS_PAD_GAIN 0x8E
+#define B2056_TX_STATUS_PGA_GAIN 0x8F
+#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
+#define B2056_TX_STATUS_TXLPF_BW 0x91
+#define B2056_TX_STATUS_TXLPF_RC 0x92
+#define B2056_TX_GMBB_IDAC0 0x93
+#define B2056_TX_GMBB_IDAC1 0x94
+#define B2056_TX_GMBB_IDAC2 0x95
+#define B2056_TX_GMBB_IDAC3 0x96
+#define B2056_TX_GMBB_IDAC4 0x97
+#define B2056_TX_GMBB_IDAC5 0x98
+#define B2056_TX_GMBB_IDAC6 0x99
+#define B2056_TX_GMBB_IDAC7 0x9A
+
+#define B2056_RX_RESERVED_ADDR0 0x00
+#define B2056_RX_IDCODE 0x01
+#define B2056_RX_RESERVED_ADDR2 0x02
+#define B2056_RX_RESERVED_ADDR3 0x03
+#define B2056_RX_RESERVED_ADDR4 0x04
+#define B2056_RX_RESERVED_ADDR5 0x05
+#define B2056_RX_RESERVED_ADDR6 0x06
+#define B2056_RX_RESERVED_ADDR7 0x07
+#define B2056_RX_COM_CTRL 0x08
+#define B2056_RX_COM_PU 0x09
+#define B2056_RX_COM_OVR 0x0A
+#define B2056_RX_COM_RESET 0x0B
+#define B2056_RX_COM_RCAL 0x0C
+#define B2056_RX_COM_RC_RXLPF 0x0D
+#define B2056_RX_COM_RC_TXLPF 0x0E
+#define B2056_RX_COM_RC_RXHPF 0x0F
+#define B2056_RX_RESERVED_ADDR16 0x10
+#define B2056_RX_RESERVED_ADDR17 0x11
+#define B2056_RX_RESERVED_ADDR18 0x12
+#define B2056_RX_RESERVED_ADDR19 0x13
+#define B2056_RX_RESERVED_ADDR20 0x14
+#define B2056_RX_RESERVED_ADDR21 0x15
+#define B2056_RX_RESERVED_ADDR22 0x16
+#define B2056_RX_RESERVED_ADDR23 0x17
+#define B2056_RX_RESERVED_ADDR24 0x18
+#define B2056_RX_RESERVED_ADDR25 0x19
+#define B2056_RX_RESERVED_ADDR26 0x1A
+#define B2056_RX_RESERVED_ADDR27 0x1B
+#define B2056_RX_RESERVED_ADDR28 0x1C
+#define B2056_RX_RESERVED_ADDR29 0x1D
+#define B2056_RX_RESERVED_ADDR30 0x1E
+#define B2056_RX_RESERVED_ADDR31 0x1F
+#define B2056_RX_RXIQCAL_RXMUX 0x20
+#define B2056_RX_RSSI_PU 0x21
+#define B2056_RX_RSSI_SEL 0x22
+#define B2056_RX_RSSI_GAIN 0x23
+#define B2056_RX_RSSI_NB_IDAC 0x24
+#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
+#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
+#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
+#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
+#define B2056_RX_RSSI_POLE 0x29
+#define B2056_RX_RSSI_WB1_IDAC 0x2A
+#define B2056_RX_RSSI_MISC 0x2B
+#define B2056_RX_LNAA_MASTER 0x2C
+#define B2056_RX_LNAA_TUNE 0x2D
+#define B2056_RX_LNAA_GAIN 0x2E
+#define B2056_RX_LNA_A_SLOPE 0x2F
+#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
+#define B2056_RX_LNAA2_IDAC 0x31
+#define B2056_RX_LNA1A_MISC 0x32
+#define B2056_RX_LNAG_MASTER 0x33
+#define B2056_RX_LNAG_TUNE 0x34
+#define B2056_RX_LNAG_GAIN 0x35
+#define B2056_RX_LNA_G_SLOPE 0x36
+#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
+#define B2056_RX_LNAG2_IDAC 0x38
+#define B2056_RX_LNA1G_MISC 0x39
+#define B2056_RX_MIXA_MASTER 0x3A
+#define B2056_RX_MIXA_VCM 0x3B
+#define B2056_RX_MIXA_CTRLPTAT 0x3C
+#define B2056_RX_MIXA_LOB_BIAS 0x3D
+#define B2056_RX_MIXA_CORE_IDAC 0x3E
+#define B2056_RX_MIXA_CMFB_IDAC 0x3F
+#define B2056_RX_MIXA_BIAS_AUX 0x40
+#define B2056_RX_MIXA_BIAS_MAIN 0x41
+#define B2056_RX_MIXA_BIAS_MISC 0x42
+#define B2056_RX_MIXA_MAST_BIAS 0x43
+#define B2056_RX_MIXG_MASTER 0x44
+#define B2056_RX_MIXG_VCM 0x45
+#define B2056_RX_MIXG_CTRLPTAT 0x46
+#define B2056_RX_MIXG_LOB_BIAS 0x47
+#define B2056_RX_MIXG_CORE_IDAC 0x48
+#define B2056_RX_MIXG_CMFB_IDAC 0x49
+#define B2056_RX_MIXG_BIAS_AUX 0x4A
+#define B2056_RX_MIXG_BIAS_MAIN 0x4B
+#define B2056_RX_MIXG_BIAS_MISC 0x4C
+#define B2056_RX_MIXG_MAST_BIAS 0x4D
+#define B2056_RX_TIA_MASTER 0x4E
+#define B2056_RX_TIA_IOPAMP 0x4F
+#define B2056_RX_TIA_QOPAMP 0x50
+#define B2056_RX_TIA_IMISC 0x51
+#define B2056_RX_TIA_QMISC 0x52
+#define B2056_RX_TIA_GAIN 0x53
+#define B2056_RX_TIA_SPARE1 0x54
+#define B2056_RX_TIA_SPARE2 0x55
+#define B2056_RX_BB_LPF_MASTER 0x56
+#define B2056_RX_AACI_MASTER 0x57
+#define B2056_RX_RXLPF_IDAC 0x58
+#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
+#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
+#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
+#define B2056_RX_RXLPF_OUTVCM 0x5C
+#define B2056_RX_RXLPF_INVCM_BODY 0x5D
+#define B2056_RX_RXLPF_CC_OP 0x5E
+#define B2056_RX_RXLPF_GAIN 0x5F
+#define B2056_RX_RXLPF_Q_BW 0x60
+#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
+#define B2056_RX_RXLPF_RCCAL_HPC 0x62
+#define B2056_RX_RXHPF_OFF0 0x63
+#define B2056_RX_RXHPF_OFF1 0x64
+#define B2056_RX_RXHPF_OFF2 0x65
+#define B2056_RX_RXHPF_OFF3 0x66
+#define B2056_RX_RXHPF_OFF4 0x67
+#define B2056_RX_RXHPF_OFF5 0x68
+#define B2056_RX_RXHPF_OFF6 0x69
+#define B2056_RX_RXHPF_OFF7 0x6A
+#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
+#define B2056_RX_RXLPF_OFF_0 0x6C
+#define B2056_RX_RXLPF_OFF_1 0x6D
+#define B2056_RX_RXLPF_OFF_2 0x6E
+#define B2056_RX_RXLPF_OFF_3 0x6F
+#define B2056_RX_RXLPF_OFF_4 0x70
+#define B2056_RX_UNUSED 0x71
+#define B2056_RX_VGA_MASTER 0x72
+#define B2056_RX_VGA_BIAS 0x73
+#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
+#define B2056_RX_VGA_GAIN 0x75
+#define B2056_RX_VGA_HP_CORNER_BW 0x76
+#define B2056_RX_VGABUF_BIAS 0x77
+#define B2056_RX_VGABUF_GAIN_BW 0x78
+#define B2056_RX_TXFBMIX_A 0x79
+#define B2056_RX_TXFBMIX_G 0x7A
+#define B2056_RX_RXSPARE1 0x7B
+#define B2056_RX_RXSPARE2 0x7C
+#define B2056_RX_RXSPARE3 0x7D
+#define B2056_RX_RXSPARE4 0x7E
+#define B2056_RX_RXSPARE5 0x7F
+#define B2056_RX_RXSPARE6 0x80
+#define B2056_RX_RXSPARE7 0x81
+#define B2056_RX_RXSPARE8 0x82
+#define B2056_RX_RXSPARE9 0x83
+#define B2056_RX_RXSPARE10 0x84
+#define B2056_RX_RXSPARE11 0x85
+#define B2056_RX_RXSPARE12 0x86
+#define B2056_RX_RXSPARE13 0x87
+#define B2056_RX_RXSPARE14 0x88
+#define B2056_RX_RXSPARE15 0x89
+#define B2056_RX_RXSPARE16 0x8A
+#define B2056_RX_STATUS_LNAA_GAIN 0x8B
+#define B2056_RX_STATUS_LNAG_GAIN 0x8C
+#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
+#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
+#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
+#define B2056_RX_STATUS_RXLPF_Q 0x90
+#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
+#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
+#define B2056_RX_STATUS_RXLPF_RC 0x93
+#define B2056_RX_STATUS_HPC_RC 0x94
+
+#define B2056_LNA1_A_PU 0x01
+#define B2056_LNA2_A_PU 0x02
+#define B2056_LNA1_G_PU 0x01
+#define B2056_LNA2_G_PU 0x02
+#define B2056_MIXA_PU_I 0x01
+#define B2056_MIXA_PU_Q 0x02
+#define B2056_MIXA_PU_GM 0x10
+#define B2056_MIXG_PU_I 0x01
+#define B2056_MIXG_PU_Q 0x02
+#define B2056_MIXG_PU_GM 0x10
+#define B2056_TIA_PU 0x01
+#define B2056_BB_LPF_PU 0x20
+#define B2056_W1_PU 0x02
+#define B2056_W2_PU 0x04
+#define B2056_NB_PU 0x08
+#define B2056_RSSI_W1_SEL 0x02
+#define B2056_RSSI_W2_SEL 0x04
+#define B2056_RSSI_NB_SEL 0x08
+#define B2056_VCM_MASK 0x1C
+#define B2056_RSSI_VCM_SHIFT 0x02
+
+#define B2056_SYN (0x0 << 12)
+#define B2056_TX0 (0x2 << 12)
+#define B2056_TX1 (0x3 << 12)
+#define B2056_RX0 (0x6 << 12)
+#define B2056_RX1 (0x7 << 12)
+#define B2056_ALLTX (0xE << 12)
+#define B2056_ALLRX (0xF << 12)
+
+#define B2056_SYN_RESERVED_ADDR0 0x00
+#define B2056_SYN_IDCODE 0x01
+#define B2056_SYN_RESERVED_ADDR2 0x02
+#define B2056_SYN_RESERVED_ADDR3 0x03
+#define B2056_SYN_RESERVED_ADDR4 0x04
+#define B2056_SYN_RESERVED_ADDR5 0x05
+#define B2056_SYN_RESERVED_ADDR6 0x06
+#define B2056_SYN_RESERVED_ADDR7 0x07
+#define B2056_SYN_COM_CTRL 0x08
+#define B2056_SYN_COM_PU 0x09
+#define B2056_SYN_COM_OVR 0x0A
+#define B2056_SYN_COM_RESET 0x0B
+#define B2056_SYN_COM_RCAL 0x0C
+#define B2056_SYN_COM_RC_RXLPF 0x0D
+#define B2056_SYN_COM_RC_TXLPF 0x0E
+#define B2056_SYN_COM_RC_RXHPF 0x0F
+#define B2056_SYN_RESERVED_ADDR16 0x10
+#define B2056_SYN_RESERVED_ADDR17 0x11
+#define B2056_SYN_RESERVED_ADDR18 0x12
+#define B2056_SYN_RESERVED_ADDR19 0x13
+#define B2056_SYN_RESERVED_ADDR20 0x14
+#define B2056_SYN_RESERVED_ADDR21 0x15
+#define B2056_SYN_RESERVED_ADDR22 0x16
+#define B2056_SYN_RESERVED_ADDR23 0x17
+#define B2056_SYN_RESERVED_ADDR24 0x18
+#define B2056_SYN_RESERVED_ADDR25 0x19
+#define B2056_SYN_RESERVED_ADDR26 0x1A
+#define B2056_SYN_RESERVED_ADDR27 0x1B
+#define B2056_SYN_RESERVED_ADDR28 0x1C
+#define B2056_SYN_RESERVED_ADDR29 0x1D
+#define B2056_SYN_RESERVED_ADDR30 0x1E
+#define B2056_SYN_RESERVED_ADDR31 0x1F
+#define B2056_SYN_GPIO_MASTER1 0x20
+#define B2056_SYN_GPIO_MASTER2 0x21
+#define B2056_SYN_TOPBIAS_MASTER 0x22
+#define B2056_SYN_TOPBIAS_RCAL 0x23
+#define B2056_SYN_AFEREG 0x24
+#define B2056_SYN_TEMPPROCSENSE 0x25
+#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
+#define B2056_SYN_TEMPPROCSENSERCAL 0x27
+#define B2056_SYN_LPO 0x28
+#define B2056_SYN_VDDCAL_MASTER 0x29
+#define B2056_SYN_VDDCAL_IDAC 0x2A
+#define B2056_SYN_VDDCAL_STATUS 0x2B
+#define B2056_SYN_RCAL_MASTER 0x2C
+#define B2056_SYN_RCAL_CODE_OUT 0x2D
+#define B2056_SYN_RCCAL_CTRL0 0x2E
+#define B2056_SYN_RCCAL_CTRL1 0x2F
+#define B2056_SYN_RCCAL_CTRL2 0x30
+#define B2056_SYN_RCCAL_CTRL3 0x31
+#define B2056_SYN_RCCAL_CTRL4 0x32
+#define B2056_SYN_RCCAL_CTRL5 0x33
+#define B2056_SYN_RCCAL_CTRL6 0x34
+#define B2056_SYN_RCCAL_CTRL7 0x35
+#define B2056_SYN_RCCAL_CTRL8 0x36
+#define B2056_SYN_RCCAL_CTRL9 0x37
+#define B2056_SYN_RCCAL_CTRL10 0x38
+#define B2056_SYN_RCCAL_CTRL11 0x39
+#define B2056_SYN_ZCAL_SPARE1 0x3A
+#define B2056_SYN_ZCAL_SPARE2 0x3B
+#define B2056_SYN_PLL_MAST1 0x3C
+#define B2056_SYN_PLL_MAST2 0x3D
+#define B2056_SYN_PLL_MAST3 0x3E
+#define B2056_SYN_PLL_BIAS_RESET 0x3F
+#define B2056_SYN_PLL_XTAL0 0x40
+#define B2056_SYN_PLL_XTAL1 0x41
+#define B2056_SYN_PLL_XTAL3 0x42
+#define B2056_SYN_PLL_XTAL4 0x43
+#define B2056_SYN_PLL_XTAL5 0x44
+#define B2056_SYN_PLL_XTAL6 0x45
+#define B2056_SYN_PLL_REFDIV 0x46
+#define B2056_SYN_PLL_PFD 0x47
+#define B2056_SYN_PLL_CP1 0x48
+#define B2056_SYN_PLL_CP2 0x49
+#define B2056_SYN_PLL_CP3 0x4A
+#define B2056_SYN_PLL_LOOPFILTER1 0x4B
+#define B2056_SYN_PLL_LOOPFILTER2 0x4C
+#define B2056_SYN_PLL_LOOPFILTER3 0x4D
+#define B2056_SYN_PLL_LOOPFILTER4 0x4E
+#define B2056_SYN_PLL_LOOPFILTER5 0x4F
+#define B2056_SYN_PLL_MMD1 0x50
+#define B2056_SYN_PLL_MMD2 0x51
+#define B2056_SYN_PLL_VCO1 0x52
+#define B2056_SYN_PLL_VCO2 0x53
+#define B2056_SYN_PLL_MONITOR1 0x54
+#define B2056_SYN_PLL_MONITOR2 0x55
+#define B2056_SYN_PLL_VCOCAL1 0x56
+#define B2056_SYN_PLL_VCOCAL2 0x57
+#define B2056_SYN_PLL_VCOCAL4 0x58
+#define B2056_SYN_PLL_VCOCAL5 0x59
+#define B2056_SYN_PLL_VCOCAL6 0x5A
+#define B2056_SYN_PLL_VCOCAL7 0x5B
+#define B2056_SYN_PLL_VCOCAL8 0x5C
+#define B2056_SYN_PLL_VCOCAL9 0x5D
+#define B2056_SYN_PLL_VCOCAL10 0x5E
+#define B2056_SYN_PLL_VCOCAL11 0x5F
+#define B2056_SYN_PLL_VCOCAL12 0x60
+#define B2056_SYN_PLL_VCOCAL13 0x61
+#define B2056_SYN_PLL_VREG 0x62
+#define B2056_SYN_PLL_STATUS1 0x63
+#define B2056_SYN_PLL_STATUS2 0x64
+#define B2056_SYN_PLL_STATUS3 0x65
+#define B2056_SYN_LOGEN_PU0 0x66
+#define B2056_SYN_LOGEN_PU1 0x67
+#define B2056_SYN_LOGEN_PU2 0x68
+#define B2056_SYN_LOGEN_PU3 0x69
+#define B2056_SYN_LOGEN_PU5 0x6A
+#define B2056_SYN_LOGEN_PU6 0x6B
+#define B2056_SYN_LOGEN_PU7 0x6C
+#define B2056_SYN_LOGEN_PU8 0x6D
+#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
+#define B2056_SYN_LOGEN_RCCR1 0x6F
+#define B2056_SYN_LOGEN_VCOBUF1 0x70
+#define B2056_SYN_LOGEN_MIXER1 0x71
+#define B2056_SYN_LOGEN_MIXER2 0x72
+#define B2056_SYN_LOGEN_BUF1 0x73
+#define B2056_SYN_LOGENBUF2 0x74
+#define B2056_SYN_LOGEN_BUF3 0x75
+#define B2056_SYN_LOGEN_BUF4 0x76
+#define B2056_SYN_LOGEN_DIV1 0x77
+#define B2056_SYN_LOGEN_DIV2 0x78
+#define B2056_SYN_LOGEN_DIV3 0x79
+#define B2056_SYN_LOGEN_ACL1 0x7A
+#define B2056_SYN_LOGEN_ACL2 0x7B
+#define B2056_SYN_LOGEN_ACL3 0x7C
+#define B2056_SYN_LOGEN_ACL4 0x7D
+#define B2056_SYN_LOGEN_ACL5 0x7E
+#define B2056_SYN_LOGEN_ACL6 0x7F
+#define B2056_SYN_LOGEN_ACLOUT 0x80
+#define B2056_SYN_LOGEN_ACLCAL1 0x81
+#define B2056_SYN_LOGEN_ACLCAL2 0x82
+#define B2056_SYN_LOGEN_ACLCAL3 0x83
+#define B2056_SYN_CALEN 0x84
+#define B2056_SYN_LOGEN_PEAKDET1 0x85
+#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
+#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
+#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
+#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
+#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
+#define B2056_SYN_LOGEN_VCOBUF2 0x8B
+#define B2056_SYN_LOGEN_MIXER3 0x8C
+#define B2056_SYN_LOGEN_BUF5 0x8D
+#define B2056_SYN_LOGEN_BUF6 0x8E
+#define B2056_SYN_LOGEN_CBUFRX1 0x8F
+#define B2056_SYN_LOGEN_CBUFRX2 0x90
+#define B2056_SYN_LOGEN_CBUFRX3 0x91
+#define B2056_SYN_LOGEN_CBUFRX4 0x92
+#define B2056_SYN_LOGEN_CBUFTX1 0x93
+#define B2056_SYN_LOGEN_CBUFTX2 0x94
+#define B2056_SYN_LOGEN_CBUFTX3 0x95
+#define B2056_SYN_LOGEN_CBUFTX4 0x96
+#define B2056_SYN_LOGEN_CMOSRX1 0x97
+#define B2056_SYN_LOGEN_CMOSRX2 0x98
+#define B2056_SYN_LOGEN_CMOSRX3 0x99
+#define B2056_SYN_LOGEN_CMOSRX4 0x9A
+#define B2056_SYN_LOGEN_CMOSTX1 0x9B
+#define B2056_SYN_LOGEN_CMOSTX2 0x9C
+#define B2056_SYN_LOGEN_CMOSTX3 0x9D
+#define B2056_SYN_LOGEN_CMOSTX4 0x9E
+#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
+#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
+#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
+#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
+#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
+#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
+#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
+#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
+#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
+#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
+#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
+#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
+#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
+#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
+#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
+#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
+#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
+#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
+#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
+#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
+#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
+#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
+#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
+#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
+
+#define B2056_TX_RESERVED_ADDR0 0x00
+#define B2056_TX_IDCODE 0x01
+#define B2056_TX_RESERVED_ADDR2 0x02
+#define B2056_TX_RESERVED_ADDR3 0x03
+#define B2056_TX_RESERVED_ADDR4 0x04
+#define B2056_TX_RESERVED_ADDR5 0x05
+#define B2056_TX_RESERVED_ADDR6 0x06
+#define B2056_TX_RESERVED_ADDR7 0x07
+#define B2056_TX_COM_CTRL 0x08
+#define B2056_TX_COM_PU 0x09
+#define B2056_TX_COM_OVR 0x0A
+#define B2056_TX_COM_RESET 0x0B
+#define B2056_TX_COM_RCAL 0x0C
+#define B2056_TX_COM_RC_RXLPF 0x0D
+#define B2056_TX_COM_RC_TXLPF 0x0E
+#define B2056_TX_COM_RC_RXHPF 0x0F
+#define B2056_TX_RESERVED_ADDR16 0x10
+#define B2056_TX_RESERVED_ADDR17 0x11
+#define B2056_TX_RESERVED_ADDR18 0x12
+#define B2056_TX_RESERVED_ADDR19 0x13
+#define B2056_TX_RESERVED_ADDR20 0x14
+#define B2056_TX_RESERVED_ADDR21 0x15
+#define B2056_TX_RESERVED_ADDR22 0x16
+#define B2056_TX_RESERVED_ADDR23 0x17
+#define B2056_TX_RESERVED_ADDR24 0x18
+#define B2056_TX_RESERVED_ADDR25 0x19
+#define B2056_TX_RESERVED_ADDR26 0x1A
+#define B2056_TX_RESERVED_ADDR27 0x1B
+#define B2056_TX_RESERVED_ADDR28 0x1C
+#define B2056_TX_RESERVED_ADDR29 0x1D
+#define B2056_TX_RESERVED_ADDR30 0x1E
+#define B2056_TX_RESERVED_ADDR31 0x1F
+#define B2056_TX_IQCAL_GAIN_BW 0x20
+#define B2056_TX_LOFT_FINE_I 0x21
+#define B2056_TX_LOFT_FINE_Q 0x22
+#define B2056_TX_LOFT_COARSE_I 0x23
+#define B2056_TX_LOFT_COARSE_Q 0x24
+#define B2056_TX_TX_COM_MASTER1 0x25
+#define B2056_TX_TX_COM_MASTER2 0x26
+#define B2056_TX_RXIQCAL_TXMUX 0x27
+#define B2056_TX_TX_SSI_MASTER 0x28
+#define B2056_TX_IQCAL_VCM_HG 0x29
+#define B2056_TX_IQCAL_IDAC 0x2A
+#define B2056_TX_TSSI_VCM 0x2B
+#define B2056_TX_TX_AMP_DET 0x2C
+#define B2056_TX_TX_SSI_MUX 0x2D
+#define B2056_TX_TSSIA 0x2E
+#define B2056_TX_TSSIG 0x2F
+#define B2056_TX_TSSI_MISC1 0x30
+#define B2056_TX_TSSI_MISC2 0x31
+#define B2056_TX_TSSI_MISC3 0x32
+#define B2056_TX_PA_SPARE1 0x33
+#define B2056_TX_PA_SPARE2 0x34
+#define B2056_TX_INTPAA_MASTER 0x35
+#define B2056_TX_INTPAA_GAIN 0x36
+#define B2056_TX_INTPAA_BOOST_TUNE 0x37
+#define B2056_TX_INTPAA_IAUX_STAT 0x38
+#define B2056_TX_INTPAA_IAUX_DYN 0x39
+#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
+#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
+#define B2056_TX_INTPAA_CASCBIAS 0x3C
+#define B2056_TX_INTPAA_PASLOPE 0x3D
+#define B2056_TX_INTPAA_PA_MISC 0x3E
+#define B2056_TX_INTPAG_MASTER 0x3F
+#define B2056_TX_INTPAG_GAIN 0x40
+#define B2056_TX_INTPAG_BOOST_TUNE 0x41
+#define B2056_TX_INTPAG_IAUX_STAT 0x42
+#define B2056_TX_INTPAG_IAUX_DYN 0x43
+#define B2056_TX_INTPAG_IMAIN_STAT 0x44
+#define B2056_TX_INTPAG_IMAIN_DYN 0x45
+#define B2056_TX_INTPAG_CASCBIAS 0x46
+#define B2056_TX_INTPAG_PASLOPE 0x47
+#define B2056_TX_INTPAG_PA_MISC 0x48
+#define B2056_TX_PADA_MASTER 0x49
+#define B2056_TX_PADA_IDAC 0x4A
+#define B2056_TX_PADA_CASCBIAS 0x4B
+#define B2056_TX_PADA_GAIN 0x4C
+#define B2056_TX_PADA_BOOST_TUNE 0x4D
+#define B2056_TX_PADA_SLOPE 0x4E
+#define B2056_TX_PADG_MASTER 0x4F
+#define B2056_TX_PADG_IDAC 0x50
+#define B2056_TX_PADG_CASCBIAS 0x51
+#define B2056_TX_PADG_GAIN 0x52
+#define B2056_TX_PADG_BOOST_TUNE 0x53
+#define B2056_TX_PADG_SLOPE 0x54
+#define B2056_TX_PGAA_MASTER 0x55
+#define B2056_TX_PGAA_IDAC 0x56
+#define B2056_TX_PGAA_GAIN 0x57
+#define B2056_TX_PGAA_BOOST_TUNE 0x58
+#define B2056_TX_PGAA_SLOPE 0x59
+#define B2056_TX_PGAA_MISC 0x5A
+#define B2056_TX_PGAG_MASTER 0x5B
+#define B2056_TX_PGAG_IDAC 0x5C
+#define B2056_TX_PGAG_GAIN 0x5D
+#define B2056_TX_PGAG_BOOST_TUNE 0x5E
+#define B2056_TX_PGAG_SLOPE 0x5F
+#define B2056_TX_PGAG_MISC 0x60
+#define B2056_TX_MIXA_MASTER 0x61
+#define B2056_TX_MIXA_BOOST_TUNE 0x62
+#define B2056_TX_MIXG 0x63
+#define B2056_TX_MIXG_BOOST_TUNE 0x64
+#define B2056_TX_BB_GM_MASTER 0x65
+#define B2056_TX_GMBB_GM 0x66
+#define B2056_TX_GMBB_IDAC 0x67
+#define B2056_TX_TXLPF_MASTER 0x68
+#define B2056_TX_TXLPF_RCCAL 0x69
+#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
+#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
+#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
+#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
+#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
+#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
+#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
+#define B2056_TX_TXLPF_BW 0x71
+#define B2056_TX_TXLPF_GAIN 0x72
+#define B2056_TX_TXLPF_IDAC 0x73
+#define B2056_TX_TXLPF_IDAC_0 0x74
+#define B2056_TX_TXLPF_IDAC_1 0x75
+#define B2056_TX_TXLPF_IDAC_2 0x76
+#define B2056_TX_TXLPF_IDAC_3 0x77
+#define B2056_TX_TXLPF_IDAC_4 0x78
+#define B2056_TX_TXLPF_IDAC_5 0x79
+#define B2056_TX_TXLPF_IDAC_6 0x7A
+#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
+#define B2056_TX_TXLPF_MISC 0x7C
+#define B2056_TX_TXSPARE1 0x7D
+#define B2056_TX_TXSPARE2 0x7E
+#define B2056_TX_TXSPARE3 0x7F
+#define B2056_TX_TXSPARE4 0x80
+#define B2056_TX_TXSPARE5 0x81
+#define B2056_TX_TXSPARE6 0x82
+#define B2056_TX_TXSPARE7 0x83
+#define B2056_TX_TXSPARE8 0x84
+#define B2056_TX_TXSPARE9 0x85
+#define B2056_TX_TXSPARE10 0x86
+#define B2056_TX_TXSPARE11 0x87
+#define B2056_TX_TXSPARE12 0x88
+#define B2056_TX_TXSPARE13 0x89
+#define B2056_TX_TXSPARE14 0x8A
+#define B2056_TX_TXSPARE15 0x8B
+#define B2056_TX_TXSPARE16 0x8C
+#define B2056_TX_STATUS_INTPA_GAIN 0x8D
+#define B2056_TX_STATUS_PAD_GAIN 0x8E
+#define B2056_TX_STATUS_PGA_GAIN 0x8F
+#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
+#define B2056_TX_STATUS_TXLPF_BW 0x91
+#define B2056_TX_STATUS_TXLPF_RC 0x92
+#define B2056_TX_GMBB_IDAC0 0x93
+#define B2056_TX_GMBB_IDAC1 0x94
+#define B2056_TX_GMBB_IDAC2 0x95
+#define B2056_TX_GMBB_IDAC3 0x96
+#define B2056_TX_GMBB_IDAC4 0x97
+#define B2056_TX_GMBB_IDAC5 0x98
+#define B2056_TX_GMBB_IDAC6 0x99
+#define B2056_TX_GMBB_IDAC7 0x9A
+
+#define B2056_RX_RESERVED_ADDR0 0x00
+#define B2056_RX_IDCODE 0x01
+#define B2056_RX_RESERVED_ADDR2 0x02
+#define B2056_RX_RESERVED_ADDR3 0x03
+#define B2056_RX_RESERVED_ADDR4 0x04
+#define B2056_RX_RESERVED_ADDR5 0x05
+#define B2056_RX_RESERVED_ADDR6 0x06
+#define B2056_RX_RESERVED_ADDR7 0x07
+#define B2056_RX_COM_CTRL 0x08
+#define B2056_RX_COM_PU 0x09
+#define B2056_RX_COM_OVR 0x0A
+#define B2056_RX_COM_RESET 0x0B
+#define B2056_RX_COM_RCAL 0x0C
+#define B2056_RX_COM_RC_RXLPF 0x0D
+#define B2056_RX_COM_RC_TXLPF 0x0E
+#define B2056_RX_COM_RC_RXHPF 0x0F
+#define B2056_RX_RESERVED_ADDR16 0x10
+#define B2056_RX_RESERVED_ADDR17 0x11
+#define B2056_RX_RESERVED_ADDR18 0x12
+#define B2056_RX_RESERVED_ADDR19 0x13
+#define B2056_RX_RESERVED_ADDR20 0x14
+#define B2056_RX_RESERVED_ADDR21 0x15
+#define B2056_RX_RESERVED_ADDR22 0x16
+#define B2056_RX_RESERVED_ADDR23 0x17
+#define B2056_RX_RESERVED_ADDR24 0x18
+#define B2056_RX_RESERVED_ADDR25 0x19
+#define B2056_RX_RESERVED_ADDR26 0x1A
+#define B2056_RX_RESERVED_ADDR27 0x1B
+#define B2056_RX_RESERVED_ADDR28 0x1C
+#define B2056_RX_RESERVED_ADDR29 0x1D
+#define B2056_RX_RESERVED_ADDR30 0x1E
+#define B2056_RX_RESERVED_ADDR31 0x1F
+#define B2056_RX_RXIQCAL_RXMUX 0x20
+#define B2056_RX_RSSI_PU 0x21
+#define B2056_RX_RSSI_SEL 0x22
+#define B2056_RX_RSSI_GAIN 0x23
+#define B2056_RX_RSSI_NB_IDAC 0x24
+#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
+#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
+#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
+#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
+#define B2056_RX_RSSI_POLE 0x29
+#define B2056_RX_RSSI_WB1_IDAC 0x2A
+#define B2056_RX_RSSI_MISC 0x2B
+#define B2056_RX_LNAA_MASTER 0x2C
+#define B2056_RX_LNAA_TUNE 0x2D
+#define B2056_RX_LNAA_GAIN 0x2E
+#define B2056_RX_LNA_A_SLOPE 0x2F
+#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
+#define B2056_RX_LNAA2_IDAC 0x31
+#define B2056_RX_LNA1A_MISC 0x32
+#define B2056_RX_LNAG_MASTER 0x33
+#define B2056_RX_LNAG_TUNE 0x34
+#define B2056_RX_LNAG_GAIN 0x35
+#define B2056_RX_LNA_G_SLOPE 0x36
+#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
+#define B2056_RX_LNAG2_IDAC 0x38
+#define B2056_RX_LNA1G_MISC 0x39
+#define B2056_RX_MIXA_MASTER 0x3A
+#define B2056_RX_MIXA_VCM 0x3B
+#define B2056_RX_MIXA_CTRLPTAT 0x3C
+#define B2056_RX_MIXA_LOB_BIAS 0x3D
+#define B2056_RX_MIXA_CORE_IDAC 0x3E
+#define B2056_RX_MIXA_CMFB_IDAC 0x3F
+#define B2056_RX_MIXA_BIAS_AUX 0x40
+#define B2056_RX_MIXA_BIAS_MAIN 0x41
+#define B2056_RX_MIXA_BIAS_MISC 0x42
+#define B2056_RX_MIXA_MAST_BIAS 0x43
+#define B2056_RX_MIXG_MASTER 0x44
+#define B2056_RX_MIXG_VCM 0x45
+#define B2056_RX_MIXG_CTRLPTAT 0x46
+#define B2056_RX_MIXG_LOB_BIAS 0x47
+#define B2056_RX_MIXG_CORE_IDAC 0x48
+#define B2056_RX_MIXG_CMFB_IDAC 0x49
+#define B2056_RX_MIXG_BIAS_AUX 0x4A
+#define B2056_RX_MIXG_BIAS_MAIN 0x4B
+#define B2056_RX_MIXG_BIAS_MISC 0x4C
+#define B2056_RX_MIXG_MAST_BIAS 0x4D
+#define B2056_RX_TIA_MASTER 0x4E
+#define B2056_RX_TIA_IOPAMP 0x4F
+#define B2056_RX_TIA_QOPAMP 0x50
+#define B2056_RX_TIA_IMISC 0x51
+#define B2056_RX_TIA_QMISC 0x52
+#define B2056_RX_TIA_GAIN 0x53
+#define B2056_RX_TIA_SPARE1 0x54
+#define B2056_RX_TIA_SPARE2 0x55
+#define B2056_RX_BB_LPF_MASTER 0x56
+#define B2056_RX_AACI_MASTER 0x57
+#define B2056_RX_RXLPF_IDAC 0x58
+#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
+#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
+#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
+#define B2056_RX_RXLPF_OUTVCM 0x5C
+#define B2056_RX_RXLPF_INVCM_BODY 0x5D
+#define B2056_RX_RXLPF_CC_OP 0x5E
+#define B2056_RX_RXLPF_GAIN 0x5F
+#define B2056_RX_RXLPF_Q_BW 0x60
+#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
+#define B2056_RX_RXLPF_RCCAL_HPC 0x62
+#define B2056_RX_RXHPF_OFF0 0x63
+#define B2056_RX_RXHPF_OFF1 0x64
+#define B2056_RX_RXHPF_OFF2 0x65
+#define B2056_RX_RXHPF_OFF3 0x66
+#define B2056_RX_RXHPF_OFF4 0x67
+#define B2056_RX_RXHPF_OFF5 0x68
+#define B2056_RX_RXHPF_OFF6 0x69
+#define B2056_RX_RXHPF_OFF7 0x6A
+#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
+#define B2056_RX_RXLPF_OFF_0 0x6C
+#define B2056_RX_RXLPF_OFF_1 0x6D
+#define B2056_RX_RXLPF_OFF_2 0x6E
+#define B2056_RX_RXLPF_OFF_3 0x6F
+#define B2056_RX_RXLPF_OFF_4 0x70
+#define B2056_RX_UNUSED 0x71
+#define B2056_RX_VGA_MASTER 0x72
+#define B2056_RX_VGA_BIAS 0x73
+#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
+#define B2056_RX_VGA_GAIN 0x75
+#define B2056_RX_VGA_HP_CORNER_BW 0x76
+#define B2056_RX_VGABUF_BIAS 0x77
+#define B2056_RX_VGABUF_GAIN_BW 0x78
+#define B2056_RX_TXFBMIX_A 0x79
+#define B2056_RX_TXFBMIX_G 0x7A
+#define B2056_RX_RXSPARE1 0x7B
+#define B2056_RX_RXSPARE2 0x7C
+#define B2056_RX_RXSPARE3 0x7D
+#define B2056_RX_RXSPARE4 0x7E
+#define B2056_RX_RXSPARE5 0x7F
+#define B2056_RX_RXSPARE6 0x80
+#define B2056_RX_RXSPARE7 0x81
+#define B2056_RX_RXSPARE8 0x82
+#define B2056_RX_RXSPARE9 0x83
+#define B2056_RX_RXSPARE10 0x84
+#define B2056_RX_RXSPARE11 0x85
+#define B2056_RX_RXSPARE12 0x86
+#define B2056_RX_RXSPARE13 0x87
+#define B2056_RX_RXSPARE14 0x88
+#define B2056_RX_RXSPARE15 0x89
+#define B2056_RX_RXSPARE16 0x8A
+#define B2056_RX_STATUS_LNAA_GAIN 0x8B
+#define B2056_RX_STATUS_LNAG_GAIN 0x8C
+#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
+#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
+#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
+#define B2056_RX_STATUS_RXLPF_Q 0x90
+#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
+#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
+#define B2056_RX_STATUS_RXLPF_RC 0x93
+#define B2056_RX_STATUS_HPC_RC 0x94
+
+#define B2056_LNA1_A_PU 0x01
+#define B2056_LNA2_A_PU 0x02
+#define B2056_LNA1_G_PU 0x01
+#define B2056_LNA2_G_PU 0x02
+#define B2056_MIXA_PU_I 0x01
+#define B2056_MIXA_PU_Q 0x02
+#define B2056_MIXA_PU_GM 0x10
+#define B2056_MIXG_PU_I 0x01
+#define B2056_MIXG_PU_Q 0x02
+#define B2056_MIXG_PU_GM 0x10
+#define B2056_TIA_PU 0x01
+#define B2056_BB_LPF_PU 0x20
+#define B2056_W1_PU 0x02
+#define B2056_W2_PU 0x04
+#define B2056_NB_PU 0x08
+#define B2056_RSSI_W1_SEL 0x02
+#define B2056_RSSI_W2_SEL 0x04
+#define B2056_RSSI_NB_SEL 0x08
+#define B2056_VCM_MASK 0x1C
+#define B2056_RSSI_VCM_SHIFT 0x02
+
struct b43_nphy_channeltab_entry_rev3 {
- /* The channel number */
- u8 channel;
/* The channel frequency in MHz */
u16 freq;
/* Radio register values on channelswitch */
- /* TODO */
+ u8 radio_syn_pll_vcocal1;
+ u8 radio_syn_pll_vcocal2;
+ u8 radio_syn_pll_refdiv;
+ u8 radio_syn_pll_mmd2;
+ u8 radio_syn_pll_mmd1;
+ u8 radio_syn_pll_loopfilter1;
+ u8 radio_syn_pll_loopfilter2;
+ u8 radio_syn_pll_loopfilter3;
+ u8 radio_syn_pll_loopfilter4;
+ u8 radio_syn_pll_loopfilter5;
+ u8 radio_syn_reserved_addr27;
+ u8 radio_syn_reserved_addr28;
+ u8 radio_syn_reserved_addr29;
+ u8 radio_syn_logen_vcobuf1;
+ u8 radio_syn_logen_mixer2;
+ u8 radio_syn_logen_buf3;
+ u8 radio_syn_logen_buf4;
+ u8 radio_rx0_lnaa_tune;
+ u8 radio_rx0_lnag_tune;
+ u8 radio_tx0_intpaa_boost_tune;
+ u8 radio_tx0_intpag_boost_tune;
+ u8 radio_tx0_pada_boost_tune;
+ u8 radio_tx0_padg_boost_tune;
+ u8 radio_tx0_pgaa_boost_tune;
+ u8 radio_tx0_pgag_boost_tune;
+ u8 radio_tx0_mixa_boost_tune;
+ u8 radio_tx0_mixg_boost_tune;
+ u8 radio_rx1_lnaa_tune;
+ u8 radio_rx1_lnag_tune;
+ u8 radio_tx1_intpaa_boost_tune;
+ u8 radio_tx1_intpag_boost_tune;
+ u8 radio_tx1_pada_boost_tune;
+ u8 radio_tx1_padg_boost_tune;
+ u8 radio_tx1_pgaa_boost_tune;
+ u8 radio_tx1_pgag_boost_tune;
+ u8 radio_tx1_mixa_boost_tune;
+ u8 radio_tx1_mixg_boost_tune;
/* PHY register values on channelswitch */
struct b43_phy_n_sfo_cfg phy_regs;
};
+void b2056_upload_inittabs(struct b43_wldev *dev,
+ bool ghz5, bool ignore_uploadflag);
+
#endif /* B43_RADIO_2056_H_ */
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 78016ae21c50..86bc0a0f735c 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -28,23 +28,8 @@
/* Returns TRUE, if the radio is enabled in hardware. */
bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
{
- if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) {
- if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
- & B43_MMIO_RADIO_HWENABLED_HI_MASK))
- return 1;
- } else {
- /* To prevent CPU fault on PPC, do not read a register
- * unless the interface is started; however, on resume
- * for hibernation, this routine is entered early. When
- * that happens, unconditionally return TRUE.
- */
- if (b43_status(dev) < B43_STAT_STARTED)
- return 1;
- if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
- & B43_MMIO_RADIO_HWENABLED_LO_MASK)
- return 1;
- }
- return 0;
+ return !(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
+ & B43_MMIO_RADIO_HWENABLED_HI_MASK);
}
/* The poll callback for the hardware button. */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index d60db078eae2..dc8ef09a8552 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -28,41 +28,41 @@
#include "phy_n.h"
static const u8 b43_ntab_adjustpower0[] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
- 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
- 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
- 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const u8 b43_ntab_adjustpower1[] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
- 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
- 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
- 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const u16 b43_ntab_bdi[] = {
@@ -130,8 +130,8 @@ static const u32 b43_ntab_framestruct[] = {
0x09804506, 0x00100030, 0x09804507, 0x00100030,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x08004A0C, 0x00100008, 0x01000A0D, 0x00100028,
- 0x0980450E, 0x00100038, 0x0980450F, 0x00100038,
+ 0x08004A0C, 0x00100004, 0x01000A0D, 0x00100024,
+ 0x0980450E, 0x00100034, 0x0980450F, 0x00100034,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000A04, 0x00100000, 0x11008A05, 0x00100020,
@@ -202,13 +202,13 @@ static const u32 b43_ntab_framestruct[] = {
0x53028A06, 0x01900060, 0x53028A07, 0x01900060,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x4002140C, 0x000F4810, 0x6203140D, 0x00100050,
- 0x53028A0E, 0x01900070, 0x53028A0F, 0x01900070,
+ 0x4002140C, 0x000F4808, 0x6203140D, 0x00100048,
+ 0x53028A0E, 0x01900068, 0x53028A0F, 0x01900068,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
- 0x1980C50E, 0x00100038, 0x2181050E, 0x00100038,
- 0x2181050E, 0x00100038, 0x0180050C, 0x00100038,
+ 0x00000A0C, 0x00100004, 0x11008A0D, 0x00100024,
+ 0x1980C50E, 0x00100034, 0x2181050E, 0x00100034,
+ 0x2181050E, 0x00100034, 0x0180050C, 0x00100038,
0x1180850D, 0x00100038, 0x1181850D, 0x00100038,
0x2981450F, 0x01100038, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -238,9 +238,9 @@ static const u32 b43_ntab_framestruct[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x4002140C, 0x00100010, 0x0200140D, 0x00100050,
- 0x0B004A0E, 0x01900070, 0x13008A0E, 0x01900070,
- 0x13008A0E, 0x01900070, 0x43020A0C, 0x00100070,
+ 0x4002140C, 0x00100008, 0x0200140D, 0x00100048,
+ 0x0B004A0E, 0x01900068, 0x13008A0E, 0x01900068,
+ 0x13008A0E, 0x01900068, 0x43020A0C, 0x00100070,
0x1B00CA0D, 0x00100070, 0x1B014A0D, 0x00100070,
0x23010A0F, 0x01500070, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -337,73 +337,73 @@ static const u32 b43_ntab_framestruct[] = {
};
static const u32 b43_ntab_gainctl0[] = {
- 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
- 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
- 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
- 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
- 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
- 0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
- 0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
- 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
- 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
- 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
- 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
- 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
- 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
- 0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
- 0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
- 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
- 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
- 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
- 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
- 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
- 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
- 0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
- 0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
- 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
- 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
- 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
- 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
- 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
- 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
- 0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
- 0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
- 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+ 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E,
+ 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42,
+ 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B,
+ 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34,
+ 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E,
+ 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38,
+ 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32,
+ 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44,
+ 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D,
+ 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36,
+ 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40,
+ 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39,
+ 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33,
+ 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D,
+ 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E,
+ 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38,
+ 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42,
+ 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B,
+ 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34,
+ 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44,
+ 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D,
+ 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36,
+ 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30,
+ 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B,
+ 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26,
+ 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22,
+ 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E,
+ 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B,
+ 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00,
};
static const u32 b43_ntab_gainctl1[] = {
- 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
- 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
- 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
- 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
- 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
- 0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
- 0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
- 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
- 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
- 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
- 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
- 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
- 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
- 0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
- 0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
- 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
- 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
- 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
- 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
- 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
- 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
- 0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
- 0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
- 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
- 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
- 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
- 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
- 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
- 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
- 0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
- 0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
- 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+ 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E,
+ 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42,
+ 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B,
+ 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34,
+ 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E,
+ 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38,
+ 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32,
+ 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44,
+ 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D,
+ 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36,
+ 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40,
+ 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39,
+ 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33,
+ 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D,
+ 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E,
+ 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38,
+ 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42,
+ 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B,
+ 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34,
+ 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44,
+ 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D,
+ 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36,
+ 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30,
+ 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B,
+ 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26,
+ 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22,
+ 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E,
+ 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B,
+ 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00,
};
static const u32 b43_ntab_intlevel[] = {
@@ -1811,9 +1811,7 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
}
#define ntab_upload(dev, offset, data) do { \
- unsigned int i; \
- for (i = 0; i < (offset##_SIZE); i++) \
- b43_ntab_write(dev, (offset) + i, (data)[i]); \
+ b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \
} while (0)
void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
@@ -1825,24 +1823,24 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
- ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
- ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
-
- /* Volatile tables */
ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
+
+ /* Volatile tables */
+ ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
+ ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
+ ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
+ ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
- ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
- ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 67f18ecdb3bf..1f11e1670bf0 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -181,52 +181,75 @@ static int b43legacy_ratelimit(struct b43legacy_wl *wl)
void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_INFO "b43legacy-%s: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_INFO "b43legacy-%s: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_ERR "b43legacy-%s ERROR: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_ERR "b43legacy-%s ERROR: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_WARNING "b43legacy-%s warning: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_WARNING "b43legacy-%s warning: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
#if B43legacy_DEBUG
void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_DEBUG "b43legacy-%s debug: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_DEBUG "b43legacy-%s debug: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
#endif /* DEBUG */
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index d579df72b783..b90f223fb31c 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -29,7 +29,7 @@
/* Returns TRUE, if the radio is enabled in hardware. */
bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
{
- if (dev->phy.rev >= 3) {
+ if (dev->dev->id.revision >= 3) {
if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
& B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
return 1;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index dbb986946e1a..18d63f57777d 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -858,7 +858,10 @@ void hostap_free_data(struct ap_data *ap)
return;
}
+ flush_work_sync(&ap->add_sta_proc_queue);
+
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
+ flush_work_sync(&ap->wds_oper_queue);
if (ap->crypt)
ap->crypt->deinit(ap->crypt_priv);
ap->crypt = ap->crypt_priv = NULL;
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index b7cb165d612b..a8bddd81b4d1 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3317,7 +3317,13 @@ static void prism2_free_local_data(struct net_device *dev)
unregister_netdev(local->dev);
- flush_scheduled_work();
+ flush_work_sync(&local->reset_queue);
+ flush_work_sync(&local->set_multicast_list_queue);
+ flush_work_sync(&local->set_tim_queue);
+#ifndef PRISM2_NO_STATION_MODES
+ flush_work_sync(&local->info_queue);
+#endif
+ flush_work_sync(&local->comms_qual_update);
lib80211_crypt_info_free(&local->crypt_info);
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 25a2722c8a98..1d9aed645723 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -891,7 +891,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
- netif_stop_queue(dev);
}
static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b82364258dc5..ed424574160e 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -106,6 +106,9 @@ config IWL5000
Intel WiFi Link 1000BGN
Intel Wireless WiFi 5150AGN
Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
+ Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B)
+ Intel WIreless WiFi Link 6050BGN Gen 2 Adapter
+ Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 63edbe2e557f..93380f97835f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,20 +2,27 @@ obj-$(CONFIG_IWLWIFI) += iwlcore.o
iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
iwlcore-objs += iwl-scan.o iwl-led.o
+iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o
+iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+# If 3945 is selected only, iwl-legacy.o will be added
+# to iwlcore-m above, but it needs to be built in.
+iwlcore-objs += $(iwlcore-m)
+
CFLAGS_iwl-devtrace.o := -I$(src)
# AGN
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
-iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
+iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
+iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index db540910b110..ba78bc8a259f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -147,7 +147,11 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
- priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+ if (priv->cfg->rx_with_siso_diversity)
+ priv->hw_params.rx_chains_num = 1;
+ else
+ priv->hw_params.rx_chains_num =
+ num_of_ant(priv->cfg->valid_rx_ant);
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
@@ -211,14 +215,16 @@ static struct iwl_lib_ops iwl1000_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -226,7 +232,6 @@ static struct iwl_lib_ops iwl1000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -243,6 +248,7 @@ static const struct iwl_ops iwl1000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl1000_base_params = {
@@ -259,7 +265,7 @@ static struct iwl_base_params iwl1000_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -270,66 +276,49 @@ static struct iwl_ht_params iwl1000_ht_params = {
.use_rts_for_aggregation = true, /* use rts/cts protection */
};
+#define IWL_DEVICE_1000 \
+ .fw_name_pre = IWL1000_FW_PRE, \
+ .ucode_api_max = IWL1000_UCODE_API_MAX, \
+ .ucode_api_min = IWL1000_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
+ .ops = &iwl1000_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl1000_base_params, \
+ .led_mode = IWL_LED_BLINK
+
struct iwl_cfg iwl1000_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
- .fw_name_pre = IWL1000_FW_PRE,
- .ucode_api_max = IWL1000_UCODE_API_MAX,
- .ucode_api_min = IWL1000_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
- .ops = &iwl1000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl1000_base_params,
+ IWL_DEVICE_1000,
.ht_params = &iwl1000_ht_params,
};
struct iwl_cfg iwl1000_bg_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
- .fw_name_pre = IWL1000_FW_PRE,
- .ucode_api_max = IWL1000_UCODE_API_MAX,
- .ucode_api_min = IWL1000_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
- .ops = &iwl1000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl1000_base_params,
+ IWL_DEVICE_1000,
};
+#define IWL_DEVICE_100 \
+ .fw_name_pre = IWL100_FW_PRE, \
+ .ucode_api_max = IWL100_UCODE_API_MAX, \
+ .ucode_api_min = IWL100_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
+ .ops = &iwl1000_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl1000_base_params, \
+ .led_mode = IWL_LED_RF_STATE, \
+ .rx_with_siso_diversity = true
+
struct iwl_cfg iwl100_bgn_cfg = {
- .name = "Intel(R) 100 Series 1x1 BGN",
- .fw_name_pre = IWL100_FW_PRE,
- .ucode_api_max = IWL100_UCODE_API_MAX,
- .ucode_api_min = IWL100_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
- .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
- .ops = &iwl1000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl1000_base_params,
+ .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
+ IWL_DEVICE_100,
.ht_params = &iwl1000_ht_params,
};
struct iwl_cfg iwl100_bg_cfg = {
- .name = "Intel(R) 100 Series 1x1 BG",
- .fw_name_pre = IWL100_FW_PRE,
- .ucode_api_max = IWL100_UCODE_API_MAX,
- .ucode_api_min = IWL100_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
- .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
- .ops = &iwl1000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl1000_base_params,
+ .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
+ IWL_DEVICE_100,
};
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 176e52577673..a9b852be4509 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -51,6 +51,7 @@
#include "iwl-led.h"
#include "iwl-3945-led.h"
#include "iwl-3945-debugfs.h"
+#include "iwl-legacy.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -115,7 +116,7 @@ void iwl3945_disable_events(struct iwl_priv *priv)
u32 base; /* SRAM address of event log header */
u32 disable_ptr; /* SRAM address of event-disable bitmap array */
u32 array_size; /* # of u32 entries in array */
- u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
+ static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
0x00000000, /* 31 - 0 Event id numbers */
0x00000000, /* 63 - 32 */
0x00000000, /* 95 - 64 */
@@ -296,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL39_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
/**
@@ -324,6 +325,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
ieee80211_tx_info_clear_status(info);
@@ -1451,6 +1453,10 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
};
u16 chan;
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
+ return -EAGAIN;
+
chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
@@ -1779,6 +1785,9 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
int rc = 0;
bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EINVAL;
+
if (!iwl_is_alive(priv))
return -1;
@@ -2722,11 +2731,9 @@ static struct iwl_lib_ops iwl3945_lib = {
},
.send_tx_power = iwl3945_send_tx_power,
.is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
- .post_associate = iwl3945_post_associate,
- .isr = iwl_isr_legacy,
- .config_ap = iwl3945_config_ap,
- .manage_ibss_station = iwl3945_manage_ibss_station,
- .recover_from_tx_stall = iwl_bg_monitor_recover,
+ .isr_ops = {
+ .isr = iwl_isr_legacy,
+ },
.check_plcp_health = iwl3945_good_plcp_health,
.debugfs_ops = {
@@ -2736,10 +2743,16 @@ static struct iwl_lib_ops iwl3945_lib = {
},
};
+static const struct iwl_legacy_ops iwl3945_legacy_ops = {
+ .post_associate = iwl3945_post_associate,
+ .config_ap = iwl3945_config_ap,
+ .manage_ibss_station = iwl3945_manage_ibss_station,
+};
+
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
.get_hcmd_size = iwl3945_get_hcmd_size,
.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
- .tx_cmd_protection = iwlcore_tx_cmd_protection,
+ .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
.request_scan = iwl3945_request_scan,
.post_scan = iwl3945_post_scan,
};
@@ -2749,6 +2762,8 @@ static const struct iwl_ops iwl3945_ops = {
.hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
.led = &iwl3945_led_ops,
+ .legacy = &iwl3945_legacy_ops,
+ .ieee80211_ops = &iwl3945_hw_ops,
};
static struct iwl_base_params iwl3945_base_params = {
@@ -2761,7 +2776,7 @@ static struct iwl_base_params iwl3945_base_params = {
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
@@ -2776,6 +2791,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params,
+ .led_mode = IWL_LED_BLINK,
};
static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2788,6 +2804,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params,
+ .led_mode = IWL_LED_BLINK,
};
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 09391f0ee61f..3eef1eb74a78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -264,10 +264,8 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
-extern void iwl3945_post_associate(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
-extern void iwl3945_config_ap(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
+extern void iwl3945_post_associate(struct iwl_priv *priv);
+extern void iwl3945_config_ap(struct iwl_priv *priv);
extern int iwl3945_commit_rxon(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -282,6 +280,8 @@ extern int iwl3945_commit_rxon(struct iwl_priv *priv,
*/
extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
+extern struct ieee80211_ops iwl3945_hw_ops;
+
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b207e3e9299f..3f1e5f1bf847 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -48,6 +48,7 @@
#include "iwl-agn-led.h"
#include "iwl-agn.h"
#include "iwl-agn-debugfs.h"
+#include "iwl-legacy.h"
static int iwl4965_send_tx_power(struct iwl_priv *priv);
static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -1377,13 +1378,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
u8 ctrl_chan_high = 0;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- /* If this gets hit a lot, switch it to a BUG() and catch
- * the stack trace to find out who is calling this during
- * a scan. */
- IWL_WARN(priv, "TX Power requested while scanning!\n");
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
return -EAGAIN;
- }
band = priv->band == IEEE80211_BAND_2GHZ;
@@ -1447,6 +1444,142 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
return ret;
}
+static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
+ int ret;
+ bool new_assoc =
+ !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+
+ if (!iwl_is_alive(priv))
+ return -EBUSY;
+
+ if (!ctx->is_active)
+ return 0;
+
+ /* always get timestamp with Rx frame */
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+
+ ret = iwl_check_rxon_cmd(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * receive commit_rxon request
+ * abort any previous channel switch if still in process
+ */
+ if (priv->switch_rxon.switch_in_progress &&
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
+ IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+ le16_to_cpu(priv->switch_rxon.channel));
+ iwl_chswitch_done(priv, false);
+ }
+
+ /* If we don't need to send a full RXON, we can use
+ * iwl_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration. */
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_print_rx_config_cmd(priv, ctx);
+ return 0;
+ }
+
+ /* If we are currently associated and the new config requires
+ * an RXON_ASSOC and the new config wants the associated mask enabled,
+ * we must clear the associated from the active configuration
+ * before we apply the new config */
+ if (iwl_is_associated_ctx(ctx) && new_assoc) {
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
+ active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd),
+ active_rxon);
+
+ /* If the mask clearing failed then we set
+ * active_rxon back to what it was previously */
+ if (ret) {
+ active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
+ IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
+ return ret;
+ }
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
+ "* with%s RXON_FILTER_ASSOC_MSK\n"
+ "* channel = %d\n"
+ "* bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
+
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+
+ /* Apply the new configuration
+ * RXON unassoc clears the station table in uCode so restoration of
+ * stations is needed after it (the RXON command) completes
+ */
+ if (!new_assoc) {
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+ if (new_assoc) {
+ priv->start_calib = 0;
+ /* Apply the new configuration
+ * RXON assoc doesn't clear the station table in uCode,
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ }
+ iwl_print_rx_config_cmd(priv, ctx);
+
+ iwl_init_sensitivity(priv);
+
+ /* If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames */
+ ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
@@ -1554,22 +1687,6 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
}
/**
- * sign_extend - Sign extend a value using specified bit as sign-bit
- *
- * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1
- * and bit0..2 is 001b which when sign extended to 1111111111111001b is -7.
- *
- * @param oper value to sign extend
- * @param index 0 based bit index (0<=index<32) to sign bit
- */
-static s32 sign_extend(u32 oper, int index)
-{
- u8 shift = 31 - index;
-
- return (s32)(oper << shift) >> shift;
-}
-
-/**
* iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
* @statistics: Provides the temperature reading from the uCode
*
@@ -1606,9 +1723,9 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
* "initialize" ALIVE response.
*/
if (!test_bit(STATUS_TEMPERATURE, &priv->status))
- vt = sign_extend(R4, 23);
+ vt = sign_extend32(R4, 23);
else
- vt = sign_extend(le32_to_cpu(priv->_agn.statistics.
+ vt = sign_extend32(le32_to_cpu(priv->_agn.statistics.
general.common.temperature), 23);
IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
@@ -2081,6 +2198,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
memset(&info->status, 0, sizeof(info->status));
@@ -2121,12 +2239,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
- (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
- if (agg->state == IWL_AGG_OFF)
- iwl_wake_queue(priv, txq_id);
- else
- iwl_wake_queue(priv, txq->swq_id);
- }
+ (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
+ iwl_wake_queue(priv, txq);
}
} else {
info->status.rates[0].count = tx_resp->failure_frame + 1;
@@ -2150,7 +2264,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
@@ -2216,7 +2330,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
- .commit_rxon = iwlagn_commit_rxon,
+ .commit_rxon = iwl4965_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.send_bt_config = iwl_send_bt_config,
};
@@ -2233,12 +2347,155 @@ static void iwl4965_post_scan(struct iwl_priv *priv)
iwlcore_commit_rxon(priv, ctx);
}
+static void iwl4965_post_associate(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
+ struct ieee80211_conf *conf = NULL;
+ int ret = 0;
+
+ if (!vif || !priv->is_open)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_AP) {
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
+ return;
+ }
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ iwl_scan_cancel_timeout(priv, 200);
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret)
+ IWL_WARN(priv, "RXON timing - "
+ "Attempting to continue.\n");
+
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
+ vif->bss_conf.aid, vif->bss_conf.beacon_int);
+
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (vif->bss_conf.use_short_slot)
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ }
+
+ iwlcore_commit_rxon(priv, ctx);
+
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
+ vif->bss_conf.aid, ctx->active.bssid_addr);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ iwlagn_send_beacon_cmd(priv);
+ break;
+ default:
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
+ __func__, vif->type);
+ break;
+ }
+
+ /* the chain noise calibration will enabled PM upon completion
+ * If chain noise has already been run, then we need to enable
+ * power management here */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_update_mode(priv, false);
+
+ /* Enable Rx differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+}
+
+static void iwl4965_config_ap(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
+ int ret = 0;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* The following should be done only at AP bring up */
+ if (!iwl_is_associated_ctx(ctx)) {
+
+ /* RXON - unassoc (to set timing command) */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ /* RXON Timing */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret)
+ IWL_WARN(priv, "RXON timing failed - "
+ "Attempting to continue.\n");
+
+ /* AP has all antennas */
+ priv->chain_noise_data.active_chains =
+ priv->hw_params.valid_rx_ant;
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ ctx->staging.assoc_id = 0;
+
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |=
+ RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &=
+ ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (vif->bss_conf.use_short_slot)
+ ctx->staging.flags |=
+ RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &=
+ ~RXON_FLG_SHORT_SLOT_MSK;
+ }
+ /* need to send beacon cmd before committing assoc RXON! */
+ iwlagn_send_beacon_cmd(priv);
+ /* restore RXON assoc */
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+ }
+ iwlagn_send_beacon_cmd(priv);
+
+ /* FIXME - we need to add code here to detect a totally new
+ * configuration, reset the AP, unassoc, rxon timing, assoc,
+ * clear sta table, add BCAST sta... */
+}
+
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
.chain_noise_reset = iwl4965_chain_noise_reset,
.gain_computation = iwl4965_gain_computation,
- .tx_cmd_protection = iwlcore_tx_cmd_protection,
+ .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
.calc_rssi = iwl4965_calc_rssi,
.request_scan = iwlagn_request_scan,
.post_scan = iwl4965_post_scan,
@@ -2285,14 +2542,12 @@ static struct iwl_lib_ops iwl4965_lib = {
},
.send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
- .post_associate = iwl_post_associate,
- .config_ap = iwl_config_ap,
- .isr = iwl_isr_legacy,
+ .isr_ops = {
+ .isr = iwl_isr_legacy,
+ },
.temp_ops = {
.temperature = iwl4965_temperature_calib,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -2300,15 +2555,46 @@ static struct iwl_lib_ops iwl4965_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
};
+static const struct iwl_legacy_ops iwl4965_legacy_ops = {
+ .post_associate = iwl4965_post_associate,
+ .config_ap = iwl4965_config_ap,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
+};
+
+struct ieee80211_ops iwl4965_hw_ops = {
+ .tx = iwlagn_mac_tx,
+ .start = iwlagn_mac_start,
+ .stop = iwlagn_mac_stop,
+ .add_interface = iwl_mac_add_interface,
+ .remove_interface = iwl_mac_remove_interface,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwl_legacy_mac_config,
+ .configure_filter = iwlagn_configure_filter,
+ .set_key = iwlagn_mac_set_key,
+ .update_tkip_key = iwlagn_mac_update_tkip_key,
+ .conf_tx = iwl_mac_conf_tx,
+ .reset_tsf = iwl_legacy_mac_reset_tsf,
+ .bss_info_changed = iwl_legacy_mac_bss_info_changed,
+ .ampdu_action = iwlagn_mac_ampdu_action,
+ .hw_scan = iwl_mac_hw_scan,
+ .sta_add = iwlagn_mac_sta_add,
+ .sta_remove = iwl_mac_sta_remove,
+ .channel_switch = iwlagn_mac_channel_switch,
+ .flush = iwlagn_mac_flush,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
+};
+
static const struct iwl_ops iwl4965_ops = {
.lib = &iwl4965_lib,
.hcmd = &iwl4965_hcmd,
.utils = &iwl4965_hcmd_utils,
.led = &iwlagn_led_ops,
+ .legacy = &iwl4965_legacy_ops,
+ .ieee80211_ops = &iwl4965_hw_ops,
};
static struct iwl_base_params iwl4965_base_params = {
@@ -2323,13 +2609,14 @@ static struct iwl_base_params iwl4965_base_params = {
.led_compensation = 61,
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.temperature_kelvin = true,
.max_event_log_size = 512,
.tx_power_by_driver = true,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .no_agg_framecnt_info = true,
};
struct iwl_cfg iwl4965_agn_cfg = {
@@ -2337,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = {
.fw_name_pre = IWL4965_FW_PRE,
.ucode_api_max = IWL4965_UCODE_API_MAX,
.ucode_api_min = IWL4965_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
@@ -2345,6 +2631,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.ops = &iwl4965_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl4965_base_params,
+ .led_mode = IWL_LED_BLINK,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index fd9fbc93ea1b..79ab0a6b1386 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -385,14 +385,16 @@ static struct iwl_lib_ops iwl5000_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -400,7 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -453,14 +454,16 @@ static struct iwl_lib_ops iwl5150_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwl5150_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -468,7 +471,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -485,6 +487,7 @@ static const struct iwl_ops iwl5000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl5150_ops = {
@@ -492,6 +495,7 @@ static const struct iwl_ops iwl5150_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl5000_base_params = {
@@ -505,7 +509,7 @@ static struct iwl_base_params iwl5000_base_params = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -516,66 +520,43 @@ static struct iwl_ht_params iwl5000_ht_params = {
.use_rts_for_aggregation = true, /* use rts/cts protection */
};
+#define IWL_DEVICE_5000 \
+ .fw_name_pre = IWL5000_FW_PRE, \
+ .ucode_api_max = IWL5000_UCODE_API_MAX, \
+ .ucode_api_min = IWL5000_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
+ .ops = &iwl5000_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl5000_base_params, \
+ .led_mode = IWL_LED_BLINK
+
struct iwl_cfg iwl5300_agn_cfg = {
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
- .fw_name_pre = IWL5000_FW_PRE,
- .ucode_api_max = IWL5000_UCODE_API_MAX,
- .ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
- .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
+ IWL_DEVICE_5000,
.ht_params = &iwl5000_ht_params,
};
struct iwl_cfg iwl5100_bgn_cfg = {
.name = "Intel(R) WiFi Link 5100 BGN",
- .fw_name_pre = IWL5000_FW_PRE,
- .ucode_api_max = IWL5000_UCODE_API_MAX,
- .ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
+ IWL_DEVICE_5000,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
.ht_params = &iwl5000_ht_params,
};
struct iwl_cfg iwl5100_abg_cfg = {
.name = "Intel(R) WiFi Link 5100 ABG",
- .fw_name_pre = IWL5000_FW_PRE,
- .ucode_api_max = IWL5000_UCODE_API_MAX,
- .ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
+ IWL_DEVICE_5000,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
};
struct iwl_cfg iwl5100_agn_cfg = {
.name = "Intel(R) WiFi Link 5100 AGN",
- .fw_name_pre = IWL5000_FW_PRE,
- .ucode_api_max = IWL5000_UCODE_API_MAX,
- .ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
+ IWL_DEVICE_5000,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
.ht_params = &iwl5000_ht_params,
};
@@ -584,48 +565,39 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
+ .led_mode = IWL_LED_BLINK,
+ .internal_wimax_coex = true,
};
+#define IWL_DEVICE_5150 \
+ .fw_name_pre = IWL5150_FW_PRE, \
+ .ucode_api_max = IWL5150_UCODE_API_MAX, \
+ .ucode_api_min = IWL5150_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
+ .ops = &iwl5150_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl5000_base_params, \
+ .need_dc_calib = true, \
+ .led_mode = IWL_LED_BLINK, \
+ .internal_wimax_coex = true
+
struct iwl_cfg iwl5150_agn_cfg = {
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
- .fw_name_pre = IWL5150_FW_PRE,
- .ucode_api_max = IWL5150_UCODE_API_MAX,
- .ucode_api_min = IWL5150_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .ops = &iwl5150_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
+ IWL_DEVICE_5150,
.ht_params = &iwl5000_ht_params,
- .need_dc_calib = true,
+
};
struct iwl_cfg iwl5150_abg_cfg = {
.name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
- .fw_name_pre = IWL5150_FW_PRE,
- .ucode_api_max = IWL5150_UCODE_API_MAX,
- .ucode_api_min = IWL5150_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .ops = &iwl5150_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl5000_base_params,
- .need_dc_calib = true,
+ IWL_DEVICE_5150,
};
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 11e6532fc573..af505bcd7ae0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -53,13 +53,11 @@
#define IWL6000_UCODE_API_MAX 4
#define IWL6050_UCODE_API_MAX 5
#define IWL6000G2_UCODE_API_MAX 5
-#define IWL130_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL6000_UCODE_API_MIN 4
#define IWL6050_UCODE_API_MIN 4
#define IWL6000G2_UCODE_API_MIN 4
-#define IWL130_UCODE_API_MIN 5
#define IWL6000_FW_PRE "iwlwifi-6000-"
#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -77,10 +75,6 @@
#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
-#define IWL130_FW_PRE "iwlwifi-130-"
-#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
-#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
-
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
/* want Celsius */
@@ -188,7 +182,11 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
- priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+ if (priv->cfg->rx_with_siso_diversity)
+ priv->hw_params.rx_chains_num = 1;
+ else
+ priv->hw_params.rx_chains_num =
+ num_of_ant(priv->cfg->valid_rx_ant);
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
@@ -328,14 +326,16 @@ static struct iwl_lib_ops iwl6000_lib = {
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -343,7 +343,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -399,14 +398,16 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -414,7 +415,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -439,6 +439,7 @@ static const struct iwl_ops iwl6000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050_ops = {
@@ -447,6 +448,7 @@ static const struct iwl_ops iwl6050_ops = {
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
.nic = &iwl6050_nic_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050g2_ops = {
@@ -455,6 +457,7 @@ static const struct iwl_ops iwl6050g2_ops = {
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
.nic = &iwl6050g2_nic_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6000g2b_ops = {
@@ -462,6 +465,7 @@ static const struct iwl_ops iwl6000g2b_ops = {
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl6000_base_params = {
@@ -480,11 +484,12 @@ static struct iwl_base_params iwl6000_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
static struct iwl_base_params iwl6050_base_params = {
@@ -503,13 +508,14 @@ static struct iwl_base_params iwl6050_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
-static struct iwl_base_params iwl6000_coex_base_params = {
+static struct iwl_base_params iwl6000_g2_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE,
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -518,18 +524,19 @@ static struct iwl_base_params iwl6000_coex_base_params = {
.use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
- .led_compensation = 51,
+ .led_compensation = 57,
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
static struct iwl_ht_params iwl6000_ht_params = {
@@ -541,262 +548,164 @@ static struct iwl_bt_params iwl6000_bt_params = {
.bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
+ .agg_time_limit = BT_AGG_THRESHOLD_DEF,
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
+ .bt_sco_disable = true,
+};
+
+#define IWL_DEVICE_6005 \
+ .fw_name_pre = IWL6000G2A_FW_PRE, \
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
+ .ops = &iwl6000_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl6000_g2_base_params, \
+ .need_dc_calib = true, \
+ .need_temp_offset_calib = true, \
+ .led_mode = IWL_LED_RF_STATE
+
+struct iwl_cfg iwl6005_2agn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
+ IWL_DEVICE_6005,
+ .ht_params = &iwl6000_ht_params,
};
-struct iwl_cfg iwl6000g2a_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
+struct iwl_cfg iwl6005_2abg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
+ IWL_DEVICE_6005,
+};
+
+struct iwl_cfg iwl6005_2bg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
+ IWL_DEVICE_6005,
+};
+
+#define IWL_DEVICE_6030 \
+ .fw_name_pre = IWL6000G2B_FW_PRE, \
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
+ .ops = &iwl6000g2b_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl6000_g2_base_params, \
+ .bt_params = &iwl6000_bt_params, \
+ .need_dc_calib = true, \
+ .need_temp_offset_calib = true, \
+ .led_mode = IWL_LED_RF_STATE, \
+ .adv_pm = true \
+
+struct iwl_cfg iwl6030_2agn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
+ IWL_DEVICE_6030,
.ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
-};
-
-struct iwl_cfg iwl6000g2a_2abg_cfg = {
- .name = "6000 Series 2x2 ABG Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
-};
-
-struct iwl_cfg iwl6000g2a_2bg_cfg = {
- .name = "6000 Series 2x2 BG Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
-};
-
-struct iwl_cfg iwl6000g2b_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
+};
+
+struct iwl_cfg iwl6030_2abg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
+ IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl6030_2bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
+ IWL_DEVICE_6030,
.ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl6000g2b_2abg_cfg = {
- .name = "6000 Series 2x2 ABG Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl6000g2b_2bgn_cfg = {
- .name = "6000 Series 2x2 BGN Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
+};
+
+struct iwl_cfg iwl6030_2bg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
+ IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl1030_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
+ IWL_DEVICE_6030,
.ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl6000g2b_2bg_cfg = {
- .name = "6000 Series 2x2 BG Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl6000g2b_bgn_cfg = {
- .name = "6000 Series 1x2 BGN Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
+};
+
+struct iwl_cfg iwl1030_bg_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
+ IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl130_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
+ IWL_DEVICE_6030,
.ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl6000g2b_bg_cfg = {
- .name = "6000 Series 1x2 BG Gen2b",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
- .need_dc_calib = true,
- .need_temp_offset_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .rx_with_siso_diversity = true,
+};
+
+struct iwl_cfg iwl130_bg_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
+ IWL_DEVICE_6030,
+ .rx_with_siso_diversity = true,
};
/*
* "i": Internal configuration, use internal Power Amplifier
*/
+#define IWL_DEVICE_6000i \
+ .fw_name_pre = IWL6000_FW_PRE, \
+ .ucode_api_max = IWL6000_UCODE_API_MAX, \
+ .ucode_api_min = IWL6000_UCODE_API_MIN, \
+ .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
+ .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
+ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
+ .ops = &iwl6000_ops, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl6000_base_params, \
+ .pa_type = IWL_PA_INTERNAL, \
+ .led_mode = IWL_LED_BLINK
+
struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
+ IWL_DEVICE_6000i,
.ht_params = &iwl6000_ht_params,
- .pa_type = IWL_PA_INTERNAL,
};
struct iwl_cfg iwl6000i_2abg_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
- .pa_type = IWL_PA_INTERNAL,
+ IWL_DEVICE_6000i,
};
struct iwl_cfg iwl6000i_2bg_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_base_params,
- .pa_type = IWL_PA_INTERNAL,
-};
+ IWL_DEVICE_6000i,
+};
+
+#define IWL_DEVICE_6050 \
+ .fw_name_pre = IWL6050_FW_PRE, \
+ .ucode_api_max = IWL6050_UCODE_API_MAX, \
+ .ucode_api_min = IWL6050_UCODE_API_MIN, \
+ .ops = &iwl6050_ops, \
+ .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
+ .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
+ .mod_params = &iwlagn_mod_params, \
+ .base_params = &iwl6050_base_params, \
+ .need_dc_calib = true, \
+ .led_mode = IWL_LED_BLINK, \
+ .internal_wimax_coex = true
struct iwl_cfg iwl6050_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
- .fw_name_pre = IWL6050_FW_PRE,
- .ucode_api_max = IWL6050_UCODE_API_MAX,
- .ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .ops = &iwl6050_ops,
- .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6050_base_params,
+ IWL_DEVICE_6050,
.ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
};
-struct iwl_cfg iwl6050g2_bgn_cfg = {
- .name = "6050 Series 1x2 BGN Gen2",
+struct iwl_cfg iwl6050_2abg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
+ IWL_DEVICE_6050,
+};
+
+struct iwl_cfg iwl6150_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
.fw_name_pre = IWL6050_FW_PRE,
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
.ops = &iwl6050g2_ops,
@@ -804,22 +713,8 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
-};
-
-struct iwl_cfg iwl6050_2abg_cfg = {
- .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
- .fw_name_pre = IWL6050_FW_PRE,
- .ucode_api_max = IWL6050_UCODE_API_MAX,
- .ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
- .ops = &iwl6050_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6050_base_params,
- .need_dc_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .internal_wimax_coex = true,
};
struct iwl_cfg iwl6000_3agn_cfg = {
@@ -827,9 +722,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -837,49 +729,10 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
-};
-
-struct iwl_cfg iwl130_bgn_cfg = {
- .name = "Intel(R) 130 Series 1x1 BGN",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL130_UCODE_API_MAX,
- .ucode_api_min = IWL130_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
- .ht_params = &iwl6000_ht_params,
- .need_dc_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
-};
-
-struct iwl_cfg iwl130_bg_cfg = {
- .name = "Intel(R) 130 Series 1x2 BG",
- .fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL130_UCODE_API_MAX,
- .ucode_api_min = IWL130_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .ops = &iwl6000g2b_ops,
- .mod_params = &iwlagn_mod_params,
- .base_params = &iwl6000_coex_base_params,
- .bt_params = &iwl6000_bt_params,
- .need_dc_calib = true,
- /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
- .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .led_mode = IWL_LED_BLINK,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index e2019e756936..d16bb5ede014 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -732,8 +732,122 @@ static inline u8 find_first_chain(u8 mask)
return CHAIN_C;
}
+/**
+ * Run disconnected antenna algorithm to find out which antennas are
+ * disconnected.
+ */
+static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
+ struct iwl_chain_noise_data *data)
+{
+ u32 active_chains = 0;
+ u32 max_average_sig;
+ u16 max_average_sig_antenna_i;
+ u8 num_tx_chains;
+ u8 first_chain;
+ u16 i = 0;
+
+ average_sig[0] = data->chain_signal_a /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[1] = data->chain_signal_b /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[2] = data->chain_signal_c /
+ priv->cfg->base_params->chain_noise_num_beacons;
+
+ if (average_sig[0] >= average_sig[1]) {
+ max_average_sig = average_sig[0];
+ max_average_sig_antenna_i = 0;
+ active_chains = (1 << max_average_sig_antenna_i);
+ } else {
+ max_average_sig = average_sig[1];
+ max_average_sig_antenna_i = 1;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ if (average_sig[2] >= max_average_sig) {
+ max_average_sig = average_sig[2];
+ max_average_sig_antenna_i = 2;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
+ average_sig[0], average_sig[1], average_sig[2]);
+ IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
+ max_average_sig, max_average_sig_antenna_i);
+
+ /* Compare signal strengths for all 3 receivers. */
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ if (i != max_average_sig_antenna_i) {
+ s32 rssi_delta = (max_average_sig - average_sig[i]);
+
+ /* If signal is very weak, compared with
+ * strongest, mark it as disconnected. */
+ if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
+ data->disconn_array[i] = 1;
+ else
+ active_chains |= (1 << i);
+ IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
+ "disconn_array[i] = %d\n",
+ i, rssi_delta, data->disconn_array[i]);
+ }
+ }
+
+ /*
+ * 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
+ * priv->hw_setting.valid_tx_ant */
+ u8 ant_msk = (1 << i);
+ if (!(priv->hw_params.valid_tx_ant & ant_msk))
+ continue;
+
+ num_tx_chains++;
+ if (data->disconn_array[i] == 0)
+ /* there is a Tx antenna connected */
+ break;
+ if (num_tx_chains == priv->hw_params.tx_chains_num &&
+ data->disconn_array[i]) {
+ /*
+ * If all chains are disconnected
+ * connect the first valid tx chain
+ */
+ first_chain =
+ find_first_chain(priv->cfg->valid_tx_ant);
+ data->disconn_array[first_chain] = 0;
+ active_chains |= BIT(first_chain);
+ IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \
+ W/A - declare %d as connected\n",
+ first_chain);
+ break;
+ }
+ }
+
+ if (active_chains != priv->hw_params.valid_rx_ant &&
+ active_chains != priv->chain_noise_data.active_chains)
+ IWL_DEBUG_CALIB(priv,
+ "Detected that not all antennas are connected! "
+ "Connected: %#x, valid: %#x.\n",
+ active_chains, priv->hw_params.valid_rx_ant);
+
+ /* Save for use within RXON, TX, SCAN commands, etc. */
+ data->active_chains = active_chains;
+ IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
+ active_chains);
+}
+
+
/*
- * Accumulate 20 beacons of signal and noise statistics for each of
+ * Accumulate 16 beacons of signal and noise statistics for each of
* 3 receivers/antennas/rx-chains, then figure out:
* 1) Which antennas are connected.
* 2) Differential rx gain settings to balance the 3 receivers.
@@ -750,8 +864,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
u32 chain_sig_c;
u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
- u32 max_average_sig;
- u16 max_average_sig_antenna_i;
u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE;
u16 min_average_noise_antenna_i = INITIALIZATION_VALUE;
u16 i = 0;
@@ -759,11 +871,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
u16 stat_chnum = INITIALIZATION_VALUE;
u8 rxon_band24;
u8 stat_band24;
- u32 active_chains = 0;
- u8 num_tx_chains;
unsigned long flags;
struct statistics_rx_non_phy *rx_info;
- u8 first_chain;
+
/*
* MULTI-FIXME:
* When we support multiple interfaces on different channels,
@@ -869,108 +979,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
return;
/* Analyze signal for disconnected antenna */
- average_sig[0] = data->chain_signal_a /
- priv->cfg->base_params->chain_noise_num_beacons;
- average_sig[1] = data->chain_signal_b /
- priv->cfg->base_params->chain_noise_num_beacons;
- average_sig[2] = data->chain_signal_c /
- priv->cfg->base_params->chain_noise_num_beacons;
-
- if (average_sig[0] >= average_sig[1]) {
- max_average_sig = average_sig[0];
- max_average_sig_antenna_i = 0;
- active_chains = (1 << max_average_sig_antenna_i);
- } else {
- max_average_sig = average_sig[1];
- max_average_sig_antenna_i = 1;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- if (average_sig[2] >= max_average_sig) {
- max_average_sig = average_sig[2];
- max_average_sig_antenna_i = 2;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
- average_sig[0], average_sig[1], average_sig[2]);
- IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
- max_average_sig, max_average_sig_antenna_i);
-
- /* Compare signal strengths for all 3 receivers. */
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- if (i != max_average_sig_antenna_i) {
- s32 rssi_delta = (max_average_sig - average_sig[i]);
-
- /* If signal is very weak, compared with
- * strongest, mark it as disconnected. */
- if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
- data->disconn_array[i] = 1;
- else
- active_chains |= (1 << i);
- IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
- "disconn_array[i] = %d\n",
- i, rssi_delta, data->disconn_array[i]);
- }
- }
-
- /*
- * 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.
- */
if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- priv->bt_full_concurrent) {
- /* operated as 1x1 in full concurrency mode */
- active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /* Disable disconnected antenna algorithm for advanced
+ bt coex, assuming valid antennas are connected */
+ data->active_chains = priv->hw_params.valid_rx_ant;
+ for (i = 0; i < NUM_RX_CHAINS; i++)
+ if (!(data->active_chains & (1<<i)))
+ data->disconn_array[i] = 1;
} else
- 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
- * priv->hw_setting.valid_tx_ant */
- u8 ant_msk = (1 << i);
- if (!(priv->hw_params.valid_tx_ant & ant_msk))
- continue;
-
- num_tx_chains++;
- if (data->disconn_array[i] == 0)
- /* there is a Tx antenna connected */
- break;
- if (num_tx_chains == priv->hw_params.tx_chains_num &&
- data->disconn_array[i]) {
- /*
- * If all chains are disconnected
- * connect the first valid tx chain
- */
- first_chain =
- find_first_chain(priv->cfg->valid_tx_ant);
- data->disconn_array[first_chain] = 0;
- active_chains |= BIT(first_chain);
- IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - declare %d as connected\n",
- first_chain);
- break;
- }
- }
-
- if (active_chains != priv->hw_params.valid_rx_ant &&
- active_chains != priv->chain_noise_data.active_chains)
- IWL_DEBUG_CALIB(priv,
- "Detected that not all antennas are connected! "
- "Connected: %#x, valid: %#x.\n",
- active_chains, priv->hw_params.valid_rx_ant);
-
- /* Save for use within RXON, TX, SCAN commands, etc. */
- priv->chain_noise_data.active_chains = active_chains;
- IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
- active_chains);
+ iwl_find_disconn_antenna(priv, average_sig, data);
/* Analyze noise for rx balance */
average_noise[0] = data->chain_noise_a /
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index a358d4334a1a..a6dbd8983dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -856,6 +856,9 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
if (!iwl_is_alive(priv))
return -EAGAIN;
+ if (!priv->bt_enable_flag)
+ return -EINVAL;
+
/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index a650baba0809..97906dd442e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -75,109 +75,6 @@
#include "iwl-agn.h"
#include "iwl-io.h"
-/************************** EEPROM BANDS ****************************
- *
- * The iwl_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel. We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware. This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel. There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/**
- * struct iwl_txpwr_section: eeprom section information
- * @offset: indirect address into eeprom image
- * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
- * @band: band type for the section
- * @is_common - true: common section, false: channel section
- * @is_cck - true: cck section, false: not cck section
- * @is_ht_40 - true: all channel in the section are HT40 channel,
- * false: legacy or HT 20 MHz
- * ignore if it is common section
- * @iwl_eeprom_section_channel: channel array in the section,
- * ignore if common section
- */
-struct iwl_txpwr_section {
- u32 offset;
- u8 count;
- enum ieee80211_band band;
- bool is_common;
- bool is_cck;
- bool is_ht40;
- u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
-};
-
-/**
- * section 1 - 3 are regulatory tx power apply to all channels based on
- * modulation: CCK, OFDM
- * Band: 2.4GHz, 5.2GHz
- * section 4 - 10 are regulatory tx power apply to specified channels
- * For example:
- * 1L - Channel 1 Legacy
- * 1HT - Channel 1 HT
- * (1,+1) - Channel 1 HT40 "_above_"
- *
- * Section 1: all CCK channels
- * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
- * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
- * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
- * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
- * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
- * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
- * Section 8: 2.4 GHz channel: 13L, 13HT
- * Section 9: 2.4 GHz channel: 140L, 140HT
- * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
- *
- */
-static const struct iwl_txpwr_section enhinfo[] = {
- { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
- { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
- { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
- { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
- false, false, false,
- {1, 1, 2, 2, 10, 10, 11, 11 } },
- { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
- false, false, true,
- { 1, 2, 6, 7, 9 } },
- { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
- false, false, false,
- { 36, 64, 100, 36, 64, 100 } },
- { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
- false, false, true,
- { 36, 60, 100 } },
- { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
- false, false, false,
- { 13, 13 } },
- { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
- false, false, false,
- { 140, 140 } },
- { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
- false, false, true,
- { 132, 44 } },
-};
-
/******************************************************************************
*
* EEPROM related functions
@@ -248,6 +145,47 @@ err:
}
+int iwl_eeprom_check_sku(struct iwl_priv *priv)
+{
+ u16 eeprom_sku;
+ u16 radio_cfg;
+
+ eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
+
+ priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
+ EEPROM_SKU_CAP_BAND_POS);
+ if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
+ priv->cfg->sku |= IWL_SKU_N;
+
+ if (!priv->cfg->sku) {
+ IWL_ERR(priv, "Invalid device sku\n");
+ return -EINVAL;
+ }
+
+ IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku);
+
+ if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) {
+ /* not using .cfg overwrite */
+ radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
+ priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+ priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+ if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
+ IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
+ priv->cfg->valid_tx_ant,
+ priv->cfg->valid_rx_ant);
+ return -EINVAL;
+ }
+ IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n",
+ priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant);
+ }
+ /*
+ * for some special cases,
+ * EEPROM did not reflect the correct antenna setting
+ * so overwrite the valid tx/rx antenna from .cfg
+ */
+ return 0;
+}
+
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{
const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
@@ -265,15 +203,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
{
s8 max_txpower_avg = 0; /* (dBm) */
- IWL_DEBUG_INFO(priv, "%d - "
- "chain_a: %d dB chain_b: %d dB "
- "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
- element,
- enhanced_txpower[element].chain_a_max >> 1,
- enhanced_txpower[element].chain_b_max >> 1,
- enhanced_txpower[element].chain_c_max >> 1,
- enhanced_txpower[element].mimo2_max >> 1,
- enhanced_txpower[element].mimo3_max >> 1);
/* Take the highest tx power from any valid chains */
if ((priv->cfg->valid_tx_ant & ANT_A) &&
(enhanced_txpower[element].chain_a_max > max_txpower_avg))
@@ -303,152 +232,106 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
}
-/**
- * iwl_update_common_txpower: update channel tx power
- * update tx power per band based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_common_txpower(struct iwl_priv *priv,
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
- int section, int element, s8 *max_txpower_in_half_dbm)
+static void
+iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
+ struct iwl_eeprom_enhanced_txpwr *txp,
+ s8 max_txpower_avg)
{
- struct iwl_channel_info *ch_info;
- int ch;
- bool is_ht40 = false;
- s8 max_txpower_avg; /* (dBm) */
-
- /* it is common section, contain all type (Legacy, HT and HT40)
- * based on the element in the section to determine
- * is it HT 40 or not
- */
- if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
- is_ht40 = true;
- max_txpower_avg =
- iwl_get_max_txpower_avg(priv, enhanced_txpower,
- element, max_txpower_in_half_dbm);
-
- ch_info = priv->channel_info;
-
- for (ch = 0; ch < priv->channel_count; ch++) {
- /* find matching band and update tx power if needed */
- if ((ch_info->band == enhinfo[section].band) &&
- (ch_info->max_power_avg < max_txpower_avg) &&
- (!is_ht40)) {
- /* Update regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- max_txpower_avg;
+ int ch_idx;
+ bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ;
+ enum ieee80211_band band;
+
+ band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ?
+ IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
+
+ for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) {
+ struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx];
+
+ /* update matching channel or from common data only */
+ if (txp->channel != 0 && ch_info->channel != txp->channel)
+ continue;
+
+ /* update matching band only */
+ if (band != ch_info->band)
+ continue;
+
+ if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) {
+ ch_info->max_power_avg = max_txpower_avg;
+ ch_info->curr_txpow = max_txpower_avg;
ch_info->scan_power = max_txpower_avg;
}
- if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
- (ch_info->ht40_max_power_avg < max_txpower_avg)) {
- /* Update regulatory-based run-time data */
+
+ if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg)
ch_info->ht40_max_power_avg = max_txpower_avg;
- }
- ch_info++;
}
- return max_txpower_avg;
}
-/**
- * iwl_update_channel_txpower: update channel tx power
- * update channel tx power based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
- int section, int element, s8 *max_txpower_in_half_dbm)
-{
- struct iwl_channel_info *ch_info;
- int ch;
- u8 channel;
- s8 max_txpower_avg; /* (dBm) */
-
- channel = enhinfo[section].iwl_eeprom_section_channel[element];
- max_txpower_avg =
- iwl_get_max_txpower_avg(priv, enhanced_txpower,
- element, max_txpower_in_half_dbm);
-
- ch_info = priv->channel_info;
- for (ch = 0; ch < priv->channel_count; ch++) {
- /* find matching channel and update tx power if needed */
- if (ch_info->channel == channel) {
- if ((ch_info->max_power_avg < max_txpower_avg) &&
- (!enhinfo[section].is_ht40)) {
- /* Update regulatory-based run-time data */
- ch_info->max_power_avg = max_txpower_avg;
- ch_info->curr_txpow = max_txpower_avg;
- ch_info->scan_power = max_txpower_avg;
- }
- if ((enhinfo[section].is_ht40) &&
- (ch_info->ht40_max_power_avg < max_txpower_avg)) {
- /* Update regulatory-based run-time data */
- ch_info->ht40_max_power_avg = max_txpower_avg;
- }
- break;
- }
- ch_info++;
- }
- return max_txpower_avg;
-}
+#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT)
+#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
+#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)
+
+#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
+ ? # x " " : "")
-/**
- * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
- */
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
{
- int eeprom_section_count = 0;
- int section, element;
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
- u32 offset;
- s8 max_txpower_avg; /* (dBm) */
- s8 max_txpower_in_half_dbm; /* (half-dBm) */
-
- /* Loop through all the sections
- * adjust bands and channel's max tx power
- * Set the tx_power_user_lmt to the highest power
- * supported by any channels and chains
- */
- for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
- eeprom_section_count = enhinfo[section].count;
- offset = enhinfo[section].offset;
- enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
- iwl_eeprom_query_addr(priv, offset);
+ struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
+ int idx, entries;
+ __le16 *txp_len;
+ s8 max_txp_avg, max_txp_avg_halfdbm;
+
+ BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
+
+ /* the length is in 16-bit words, but we want entries */
+ txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
+ entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
+
+ txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
+
+ for (idx = 0; idx < entries; idx++) {
+ txp = &txp_array[idx];
+ /* skip invalid entries */
+ if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
+ continue;
+
+ IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n",
+ (txp->channel && (txp->flags &
+ IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ?
+ "Common " : (txp->channel) ?
+ "Channel" : "Common",
+ (txp->channel),
+ TXP_CHECK_AND_PRINT(VALID),
+ TXP_CHECK_AND_PRINT(BAND_52G),
+ TXP_CHECK_AND_PRINT(OFDM),
+ TXP_CHECK_AND_PRINT(40MHZ),
+ TXP_CHECK_AND_PRINT(HT_AP),
+ TXP_CHECK_AND_PRINT(RES1),
+ TXP_CHECK_AND_PRINT(RES2),
+ TXP_CHECK_AND_PRINT(COMMON_TYPE),
+ txp->flags);
+ IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x "
+ "chain_B: 0X%02x chain_C: 0X%02x\n",
+ txp->chain_a_max, txp->chain_b_max,
+ txp->chain_c_max);
+ IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x "
+ "MIMO3: 0x%02x High 20_on_40: 0x%02x "
+ "Low 20_on_40: 0x%02x\n",
+ txp->mimo2_max, txp->mimo3_max,
+ ((txp->delta_20_in_40 & 0xf0) >> 4),
+ (txp->delta_20_in_40 & 0x0f));
+
+ max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
+ &max_txp_avg_halfdbm);
/*
- * check for valid entry -
- * different version of EEPROM might contain different set
- * of enhanced tx power table
- * always check for valid entry before process
- * the information
+ * Update the user limit values values to the highest
+ * power supported by any channel
*/
- if (!enhanced_txpower->common || enhanced_txpower->reserved)
- continue;
+ if (max_txp_avg > priv->tx_power_user_lmt)
+ priv->tx_power_user_lmt = max_txp_avg;
+ if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm)
+ priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm;
- for (element = 0; element < eeprom_section_count; element++) {
- if (enhinfo[section].is_common)
- max_txpower_avg =
- iwl_update_common_txpower(priv,
- enhanced_txpower, section,
- element,
- &max_txpower_in_half_dbm);
- else
- max_txpower_avg =
- iwl_update_channel_txpower(priv,
- enhanced_txpower, section,
- element,
- &max_txpower_in_half_dbm);
-
- /* Update the tx_power_user_lmt to the highest power
- * supported by any channel */
- if (max_txpower_avg > priv->tx_power_user_lmt)
- priv->tx_power_user_lmt = max_txpower_avg;
-
- /*
- * Update the tx_power_lmt_in_half_dbm to
- * the highest power supported by any channel
- */
- if (max_txpower_in_half_dbm >
- priv->tx_power_lmt_in_half_dbm)
- priv->tx_power_lmt_in_half_dbm =
- max_txpower_in_half_dbm;
- }
+ iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index ffb2f4111ad0..366340f3fb0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (ctx_bss->vif && ctx_pan->vif) {
int bcnint = ctx_pan->vif->bss_conf.beacon_int;
+ int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
/* should be set, but seems unused?? */
cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
@@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (test_bit(STATUS_SCAN_HW, &priv->status) ||
(!ctx_bss->vif->bss_conf.idle &&
!ctx_bss->vif->bss_conf.assoc)) {
- slot0 = bcnint * 3 - 20;
+ slot0 = dtim * bcnint * 3 - 20;
slot1 = 20;
} else if (!ctx_pan->vif->bss_conf.idle &&
- !ctx_pan->vif->bss_conf.assoc) {
+ !ctx_pan->vif->bss_conf.assoc) {
slot1 = bcnint * 3 - 20;
slot0 = 20;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index b555edd53354..3dee87e8f55d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -405,6 +405,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
memset(&info->status, 0, sizeof(info->status));
@@ -445,22 +446,17 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
- (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
- if (agg->state == IWL_AGG_OFF)
- iwl_wake_queue(priv, txq_id);
- else
- iwl_wake_queue(priv, txq->swq_id);
- }
+ (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
+ iwl_wake_queue(priv, txq);
}
} else {
- BUG_ON(txq_id != txq->swq_id);
iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
@@ -496,6 +492,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
u8 tx_ant_cfg_cmd;
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
+ return -EAGAIN;
+
/* half dBm need to multiply */
tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
@@ -522,9 +522,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
else
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
- return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
- sizeof(tx_power_cmd), &tx_power_cmd,
- NULL);
+ return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd),
+ &tx_power_cmd);
}
void iwlagn_temperature(struct iwl_priv *priv)
@@ -569,6 +568,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
case INDIRECT_REGULATORY:
offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
break;
+ case INDIRECT_TXP_LIMIT:
+ offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
+ break;
+ case INDIRECT_TXP_LIMIT_SIZE:
+ offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
+ break;
case INDIRECT_CALIBRATION:
offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
break;
@@ -750,6 +755,12 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
} else
iwlagn_txq_ctx_reset(priv);
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* enable shadow regs in HW */
+ iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
+ 0x800FFFFF);
+ }
+
set_bit(STATUS_INIT, &priv->status);
return 0;
@@ -1481,15 +1492,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (priv->cfg->scan_rx_antennas[band])
rx_ant = priv->cfg->scan_rx_antennas[band];
- if (priv->cfg->scan_tx_antennas[band])
- scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
-
- if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- priv->bt_full_concurrent) {
- /* operated as 1x1 in full concurrency mode */
- scan_tx_antennas = first_antenna(
- priv->cfg->scan_tx_antennas[band]);
+ if (band == IEEE80211_BAND_2GHZ &&
+ priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /* transmit 2.4 GHz probes only on first antenna */
+ scan_tx_antennas = first_antenna(scan_tx_antennas);
}
priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
@@ -1584,22 +1591,6 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
return ret;
}
-void iwlagn_post_scan(struct iwl_priv *priv)
-{
- struct iwl_rxon_context *ctx;
-
- /*
- * Since setting the RXON may have been deferred while
- * performing the scan, fire one off if needed
- */
- for_each_context(priv, ctx)
- if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
- iwlagn_commit_rxon(priv, ctx);
-
- if (priv->cfg->ops->hcmd->set_pan_params)
- priv->cfg->ops->hcmd->set_pan_params(priv);
-}
-
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
@@ -1790,7 +1781,7 @@ static const __le32 iwlagn_def_3w_lookup[12] = {
cpu_to_le32(0xc0004000),
cpu_to_le32(0x00004000),
cpu_to_le32(0xf0005000),
- cpu_to_le32(0xf0004000),
+ cpu_to_le32(0xf0005000),
};
static const __le32 iwlagn_concurrent_lookup[12] = {
@@ -1826,6 +1817,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
bt_cmd.prio_boost = 0;
bt_cmd.kill_ack_mask = priv->kill_ack_mask;
bt_cmd.kill_cts_mask = priv->kill_cts_mask;
+
bt_cmd.valid = priv->bt_valid;
bt_cmd.tx_prio_boost = 0;
bt_cmd.rx_prio_boost = 0;
@@ -1841,10 +1833,15 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
} else {
bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_sco_disable)
+ bt_cmd.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
+
if (priv->bt_ch_announce)
bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
}
+ priv->bt_enable_flag = bt_cmd.flags;
if (priv->bt_full_concurrent)
memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
sizeof(iwlagn_concurrent_lookup));
@@ -1884,12 +1881,20 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
struct iwl_rxon_context *ctx;
int smps_request = -1;
+ /*
+ * Note: bt_traffic_load can be overridden by scan complete and
+ * coex profile notifications. Ignore that since only bad consequence
+ * can be not matching debug print with actual state.
+ */
IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
priv->bt_traffic_load);
switch (priv->bt_traffic_load) {
case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
- smps_request = IEEE80211_SMPS_AUTOMATIC;
+ if (priv->bt_status)
+ smps_request = IEEE80211_SMPS_DYNAMIC;
+ else
+ smps_request = IEEE80211_SMPS_AUTOMATIC;
break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
smps_request = IEEE80211_SMPS_DYNAMIC;
@@ -1906,6 +1911,16 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
mutex_lock(&priv->mutex);
+ /*
+ * We can not send command to firmware while scanning. When the scan
+ * complete we will schedule this work again. We do check with mutex
+ * locked to prevent new scan request to arrive. We do not check
+ * STATUS_SCANNING to avoid race when queue_work two times from
+ * different notifications, but quit and not perform any work at all.
+ */
+ if (test_bit(STATUS_SCAN_HW, &priv->status))
+ goto out;
+
if (priv->cfg->ops->lib->update_chain_flags)
priv->cfg->ops->lib->update_chain_flags(priv);
@@ -1915,7 +1930,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
ieee80211_request_smps(ctx->vif, smps_request);
}
}
-
+out:
mutex_unlock(&priv->mutex);
}
@@ -1986,24 +2001,29 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv,
BT_UART_MSG_FRAME7CONNECTABLE_POS);
}
-static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
- struct iwl_bt_uart_msg *uart_msg)
+static void iwlagn_set_kill_msk(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
{
- u8 kill_ack_msk;
- __le32 bt_kill_ack_msg[2] = {
- cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
-
- kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
- BT_UART_MSG_FRAME3SNIFF_MSK |
- BT_UART_MSG_FRAME3SCOESCO_MSK) &
- uart_msg->frame3) == 0) ? 1 : 0;
- if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
+ u8 kill_msk;
+ static const __le32 bt_kill_ack_msg[2] = {
+ IWLAGN_BT_KILL_ACK_MASK_DEFAULT,
+ IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
+ static const __le32 bt_kill_cts_msg[2] = {
+ IWLAGN_BT_KILL_CTS_MASK_DEFAULT,
+ IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
+
+ kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3)
+ ? 1 : 0;
+ if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] ||
+ priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) {
priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
- priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
+ priv->kill_ack_mask = bt_kill_ack_msg[kill_msk];
+ priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK;
+ priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
+
/* schedule to send runtime bt_config */
queue_work(priv->workqueue, &priv->bt_runtime_config);
}
-
}
void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
@@ -2014,7 +2034,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
- u8 last_traffic_load;
IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
@@ -2023,11 +2042,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
coex->bt_ci_compliance);
iwlagn_print_uartmsg(priv, uart_msg);
- last_traffic_load = priv->notif_bt_traffic_load;
- priv->notif_bt_traffic_load = coex->bt_traffic_load;
+ priv->last_bt_traffic_load = priv->bt_traffic_load;
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
if (priv->bt_status != coex->bt_status ||
- last_traffic_load != coex->bt_traffic_load) {
+ priv->last_bt_traffic_load != coex->bt_traffic_load) {
if (coex->bt_status) {
/* BT on */
if (!priv->bt_ch_announce)
@@ -2056,7 +2074,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
}
}
- iwlagn_set_kill_ack_msk(priv, uart_msg);
+ iwlagn_set_kill_msk(priv, uart_msg);
/* FIXME: based on notification, adjust the prio_boost */
@@ -2276,7 +2294,7 @@ static const char *get_csr_string(int cmd)
void iwl_dump_csr(struct iwl_priv *priv)
{
int i;
- u32 csr_tbl[] = {
+ static const u32 csr_tbl[] = {
CSR_HW_IF_CONFIG_REG,
CSR_INT_COALESCING,
CSR_INT,
@@ -2335,7 +2353,7 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
int pos = 0;
size_t bufsz = 0;
#endif
- u32 fh_tbl[] = {
+ static const u32 fh_tbl[] = {
FH_RSCSR_CHNL0_STTS_WPTR_REG,
FH_RSCSR_CHNL0_RBDCB_BASE_REG,
FH_RSCSR_CHNL0_WPTR,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 065553629de5..75fcd30a7c13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
if (load > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
- ret = ieee80211_start_tx_ba_session(sta, tid);
+ ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
if (ret == -EAGAIN) {
/*
* driver and mac80211 is out of sync
@@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_lq_sta *lq_sta)
{
struct iwl_scale_tbl_info *tbl;
- bool full_concurrent;
+ bool full_concurrent = priv->bt_full_concurrent;
unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
- if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
- full_concurrent = true;
- else
- full_concurrent = false;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->bt_full_concurrent != full_concurrent) {
+ if (priv->bt_ant_couple_ok) {
+ /*
+ * Is there a need to switch between
+ * full concurrency and 3-wire?
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
+ full_concurrent = true;
+ else
+ full_concurrent = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
+ (priv->bt_full_concurrent != full_concurrent)) {
priv->bt_full_concurrent = full_concurrent;
/* Update uCode's rate table. */
@@ -1040,8 +1046,7 @@ done:
if (sta && sta->supp_rates[sband->band])
rs_rate_scale_perform(priv, skb, sta, lq_sta);
- /* Is there a need to switch between full concurrency and 3-wire? */
- if (priv->bt_ant_couple_ok)
+ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
rs_bt_update_lq(priv, ctx, lq_sta);
}
@@ -2868,6 +2873,10 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_agg = 0;
+#ifdef CONFIG_MAC80211_DEBUGFS
+ lq_sta->dbg_fixed_rate = 0;
+#endif
+
rs_initialize_lq(priv, conf, sta, lq_sta);
}
@@ -3010,10 +3019,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
*/
if (priv && priv->cfg->bt_params &&
priv->cfg->bt_params->agg_time_limit &&
- priv->cfg->bt_params->agg_time_limit >=
- LINK_QUAL_AGG_TIME_LIMIT_MIN &&
- priv->cfg->bt_params->agg_time_limit <=
- LINK_QUAL_AGG_TIME_LIMIT_MAX)
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
new file mode 100644
index 000000000000..6d140bd53291
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -0,0 +1,642 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include "iwl-dev.h"
+#include "iwl-agn.h"
+#include "iwl-sta.h"
+#include "iwl-core.h"
+#include "iwl-agn-calib.h"
+
+static int iwlagn_disable_bss(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct iwl_rxon_cmd *send)
+{
+ __le32 old_filter = send->filter_flags;
+ int ret;
+
+ send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+
+ send->filter_flags = old_filter;
+
+ if (ret)
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret);
+
+ return ret;
+}
+
+static int iwlagn_disable_pan(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct iwl_rxon_cmd *send)
+{
+ __le32 old_filter = send->filter_flags;
+ u8 old_dev_type = send->dev_type;
+ int ret;
+
+ send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ send->dev_type = RXON_DEV_TYPE_P2P;
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+
+ send->filter_flags = old_filter;
+ send->dev_type = old_dev_type;
+
+ if (ret)
+ IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
+
+ /* FIXME: WAIT FOR PAN DISABLE */
+ msleep(300);
+
+ return ret;
+}
+
+static void iwlagn_update_qos(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
+
+ ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
+ sizeof(struct iwl_qosparam_cmd),
+ &ctx->qos_data.def_qos_parm);
+ if (ret)
+ IWL_ERR(priv, "Failed to update QoS\n");
+}
+
+static int iwlagn_update_beacon(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ lockdep_assert_held(&priv->mutex);
+
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
+ if (!priv->beacon_skb)
+ return -ENOMEM;
+ return iwlagn_send_beacon_cmd(priv);
+}
+
+/**
+ * iwlagn_commit_rxon - commit staging_rxon to hardware
+ *
+ * The RXON command in staging_rxon is committed to the hardware and
+ * the active_rxon structure is updated with the new data. This
+ * function correctly transitions out of the RXON_ASSOC_MSK state if
+ * a HW tune is required based on the RXON structure changes.
+ */
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+ bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EINVAL;
+
+ if (!iwl_is_alive(priv))
+ return -EBUSY;
+
+ /* This function hardcodes a bunch of dual-mode assumptions */
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+ if (!ctx->is_active)
+ return 0;
+
+ /* always get timestamp with Rx frame */
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+
+ if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
+ !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ ret = iwl_check_rxon_cmd(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * receive commit_rxon request
+ * abort any previous channel switch if still in process
+ */
+ if (priv->switch_rxon.switch_in_progress &&
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
+ IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+ le16_to_cpu(priv->switch_rxon.channel));
+ iwl_chswitch_done(priv, false);
+ }
+
+ /*
+ * If we don't need to send a full RXON, we can use
+ * iwl_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration.
+ */
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+ iwl_print_rx_config_cmd(priv, ctx);
+ return 0;
+ }
+
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
+
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+
+ IWL_DEBUG_INFO(priv,
+ "Going to commit RXON\n"
+ " * with%s RXON_FILTER_ASSOC_MSK\n"
+ " * channel = %d\n"
+ " * bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
+
+ /*
+ * Always clear associated first, but with the correct config.
+ * This is required as for example station addition for the
+ * AP station must be done after the BSSID is set to correctly
+ * set up filters in the device.
+ */
+ if ((old_assoc && new_assoc) || !new_assoc) {
+ if (ctx->ctxid == IWL_RXON_CTX_BSS)
+ ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+ else
+ ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ if (ret)
+ return ret;
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ /*
+ * Un-assoc RXON clears the station table and WEP
+ * keys, so we have to restore those afterwards.
+ */
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+
+ /* RXON timing must be before associated RXON */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+ return ret;
+ }
+
+ if (new_assoc) {
+ /* QoS info may be cleared by previous un-assoc RXON */
+ iwlagn_update_qos(priv, ctx);
+
+ /*
+ * We'll run into this code path when beaconing is
+ * enabled, but then we also need to send the beacon
+ * to the device.
+ */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+ ret = iwlagn_update_beacon(priv, ctx->vif);
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending required beacon (%d)!\n",
+ ret);
+ return ret;
+ }
+ }
+
+ priv->start_calib = 0;
+ /*
+ * Apply the new configuration.
+ *
+ * Associated RXON doesn't clear the station table in uCode,
+ * so we don't need to restore stations etc. after this.
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ iwl_reprogram_ap_sta(priv, ctx);
+
+ /* IBSS beacon needs to be sent after setting assoc */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+ if (iwlagn_update_beacon(priv, ctx->vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ }
+
+ iwl_print_rx_config_cmd(priv, ctx);
+
+ iwl_init_sensitivity(priv);
+
+ /*
+ * If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames.
+ *
+ * FIXME: which RXON requires a tune? Can we optimise this out in
+ * some cases?
+ */
+ ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
+ const struct iwl_channel_info *ch_info;
+ int ret = 0;
+ bool ht_changed[NUM_IWL_RXON_CTX] = {};
+
+ IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
+
+ mutex_lock(&priv->mutex);
+
+ if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ goto out;
+ }
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ /* mac80211 uses static for non-HT which is what we want */
+ priv->current_ht_config.smps = conf->smps_mode;
+
+ /*
+ * Recalculate chain counts.
+ *
+ * If monitor mode is enabled then mac80211 will
+ * set up the SM PS mode to OFF if an HT channel is
+ * configured.
+ */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ unsigned long flags;
+
+ ch_info = iwl_get_channel_info(priv, channel->band,
+ channel->hw_value);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ if (ctx->ht.enabled != conf_is_ht(conf)) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ ht_changed[ctx->ctxid] = true;
+ }
+
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
+
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if (le16_to_cpu(ctx->staging.channel) !=
+ channel->hw_value)
+ ctx->staging.flags = 0;
+
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_update_bcast_stations(priv);
+
+ /*
+ * The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists.
+ */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_PS |
+ IEEE80211_CONF_CHANGE_IDLE)) {
+ ret = iwl_power_update_mode(priv, false);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ for_each_context(priv, ctx) {
+ if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ continue;
+ iwlagn_commit_rxon(priv, ctx);
+ if (ht_changed[ctx->ctxid])
+ iwlagn_update_qos(priv, ctx);
+ }
+ out:
+ mutex_unlock(&priv->mutex);
+ return ret;
+}
+
+static void iwlagn_check_needed_chains(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct ieee80211_vif *vif = ctx->vif;
+ struct iwl_rxon_context *tmp;
+ struct ieee80211_sta *sta;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ bool need_multiple;
+
+ lockdep_assert_held(&priv->mutex);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (sta) {
+ struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+ int maxstreams;
+
+ maxstreams = (ht_cap->mcs.tx_params &
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+ maxstreams += 1;
+
+ need_multiple = true;
+
+ if ((ht_cap->mcs.rx_mask[1] == 0) &&
+ (ht_cap->mcs.rx_mask[2] == 0))
+ need_multiple = false;
+ if (maxstreams <= 1)
+ need_multiple = false;
+ } else {
+ /*
+ * If at all, this can only happen through a race
+ * when the AP disconnects us while we're still
+ * setting up the connection, in that case mac80211
+ * will soon tell us about that.
+ */
+ need_multiple = false;
+ }
+ rcu_read_unlock();
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ /* currently */
+ need_multiple = false;
+ break;
+ default:
+ /* only AP really */
+ need_multiple = true;
+ break;
+ }
+
+ ctx->ht_need_multiple_chains = need_multiple;
+
+ if (!need_multiple) {
+ /* check all contexts */
+ for_each_context(priv, tmp) {
+ if (!tmp->vif)
+ continue;
+ if (tmp->ht_need_multiple_chains) {
+ need_multiple = true;
+ break;
+ }
+ }
+ }
+
+ ht_conf->single_chain_sufficient = !need_multiple;
+}
+
+void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ int ret;
+ bool force = false;
+
+ mutex_lock(&priv->mutex);
+
+ if (unlikely(!iwl_is_ready(priv))) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ if (unlikely(!ctx->vif)) {
+ IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT)
+ force = true;
+
+ if (changes & BSS_CHANGED_QOS) {
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwlagn_update_qos(priv, ctx);
+ }
+
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ iwl_led_associate(priv);
+ priv->timestamp = bss_conf->timestamp;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ } else {
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl_led_disassociate(priv);
+ }
+ }
+
+ if (ctx->ht.enabled) {
+ ctx->ht.protection = bss_conf->ht_operation_mode &
+ IEEE80211_HT_OP_MODE_PROTECTION;
+ ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &
+ IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+ iwlagn_check_needed_chains(priv, ctx, bss_conf);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+
+ if (bss_conf->use_cts_prot)
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+
+ memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
+
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ if (vif->bss_conf.enable_beacon) {
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ priv->beacon_ctx = ctx;
+ } else {
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ priv->beacon_ctx = NULL;
+ }
+ }
+
+ if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlagn_commit_rxon(priv, ctx);
+
+ if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) {
+ /*
+ * The chain noise calibration will enable PM upon
+ * completion. If calibration has already been run
+ * then we need to enable power management here.
+ */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_update_mode(priv, false);
+
+ /* Enable RX differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+ }
+
+ if (changes & BSS_CHANGED_IBSS) {
+ ret = iwlagn_manage_ibss_station(priv, vif,
+ bss_conf->ibss_joined);
+ if (ret)
+ IWL_ERR(priv, "failed to %s IBSS station %pM\n",
+ bss_conf->ibss_joined ? "add" : "remove",
+ bss_conf->bssid);
+ }
+
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC &&
+ priv->beacon_ctx) {
+ if (iwlagn_update_beacon(priv, vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ }
+
+ mutex_unlock(&priv->mutex);
+}
+
+void iwlagn_post_scan(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+
+ /*
+ * Since setting the RXON may have been deferred while
+ * performing the scan, fire one off if needed
+ */
+ for_each_context(priv, ctx)
+ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlagn_commit_rxon(priv, ctx);
+
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35a30d2e0734..35f085ac336b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -684,7 +684,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
}
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
{
unsigned long flags;
@@ -714,3 +714,33 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
+
+void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ int sta_id;
+
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ WARN_ON(!sta_priv->client);
+ sta_priv->asleep = true;
+ if (atomic_read(&sta_priv->pending_frames) > 0)
+ ieee80211_sta_block_awake(hw, sta, true);
+ break;
+ case STA_NOTIFY_AWAKE:
+ WARN_ON(!sta_priv->client);
+ if (!sta_priv->asleep)
+ break;
+ sta_priv->asleep = false;
+ sta_id = iwl_sta_id(sta);
+ if (sta_id != IWL_INVALID_STATION)
+ iwl_sta_modify_ps_wake(priv, sta_id);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 2b078a995729..24a11b8f73bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -67,8 +67,14 @@
*/
static const u8 tid_to_ac[] = {
- /* this matches the mac80211 numbers */
- 2, 3, 3, 2, 1, 1, 0, 0
+ IEEE80211_AC_BE,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BE,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VO,
+ IEEE80211_AC_VO
};
static inline int get_ac_from_tid(u16 tid)
@@ -518,11 +524,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_cmd_meta *out_meta;
struct iwl_tx_cmd *tx_cmd;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- int swq_id, txq_id;
+ int txq_id;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
dma_addr_t scratch_phys;
- u16 len, len_org, firstlen, secondlen;
+ u16 len, firstlen, secondlen;
u16 seq_number = 0;
__le16 fc;
u8 hdr_len;
@@ -531,6 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u8 tid = 0;
u8 *qc = NULL;
unsigned long flags;
+ bool is_agg = false;
if (info->control.vif)
ctx = iwl_rxon_ctx_from_vif(info->control.vif);
@@ -567,8 +574,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta)
sta_priv = (void *)sta->drv_priv;
- if (sta_priv && sta_priv->asleep) {
- WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
+ if (sta_priv && sta_priv->asleep &&
+ (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
@@ -616,11 +623,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+ is_agg = true;
}
}
txq = &priv->txq[txq_id];
- swq_id = txq->swq_id;
q = &txq->q;
if (unlikely(iwl_queue_space(q) < q->high_mark)) {
@@ -687,30 +694,23 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
*/
len = sizeof(struct iwl_tx_cmd) +
sizeof(struct iwl_cmd_header) + hdr_len;
-
- len_org = len;
- firstlen = len = (len + 3) & ~3;
-
- if (len_org != len)
- len_org = 1;
- else
- len_org = 0;
+ firstlen = (len + 3) & ~3;
/* Tell NIC about any 2-byte padding after MAC header */
- if (len_org)
+ if (firstlen != len)
tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev,
- &out_cmd->hdr, len,
+ &out_cmd->hdr, firstlen,
PCI_DMA_BIDIRECTIONAL);
dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
- dma_unmap_len_set(out_meta, len, len);
+ dma_unmap_len_set(out_meta, len, firstlen);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- txcmd_phys, len, 1, 0);
+ txcmd_phys, firstlen, 1, 0);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
@@ -721,23 +721,21 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
- secondlen = len = skb->len - hdr_len;
- if (len) {
+ secondlen = skb->len - hdr_len;
+ if (secondlen > 0) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
- len, PCI_DMA_TODEVICE);
+ secondlen, PCI_DMA_TODEVICE);
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- phys_addr, len,
+ phys_addr, secondlen,
0, 0);
}
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
offsetof(struct iwl_tx_cmd, scratch);
- len = sizeof(struct iwl_tx_cmd) +
- sizeof(struct iwl_cmd_header) + hdr_len;
/* take back ownership of DMA buffer to enable update */
pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
- len, PCI_DMA_BIDIRECTIONAL);
+ firstlen, PCI_DMA_BIDIRECTIONAL);
tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
@@ -753,7 +751,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
- len, PCI_DMA_BIDIRECTIONAL);
+ firstlen, PCI_DMA_BIDIRECTIONAL);
trace_iwlwifi_dev_tx(priv,
&((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
@@ -773,8 +771,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
* whether or not we should update the write pointer.
*/
- /* avoid atomic ops if it isn't an associated client */
- if (sta_priv && sta_priv->client)
+ /*
+ * Avoid atomic ops if it isn't an associated client.
+ * Also, if this is a packet for aggregation, don't
+ * increase the counter because the ucode will stop
+ * aggregation queues when their respective station
+ * goes to sleep.
+ */
+ if (sta_priv && sta_priv->client && !is_agg)
atomic_inc(&sta_priv->pending_frames);
if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
@@ -784,7 +788,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
} else {
- iwl_stop_queue(priv, txq->swq_id);
+ iwl_stop_queue(priv, txq);
}
}
@@ -1013,7 +1017,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id;
- priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id);
+ iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags);
ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
@@ -1153,14 +1157,15 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
return 0;
}
-static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
+static void iwlagn_non_agg_tx_status(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ const u8 *addr1)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
struct ieee80211_sta *sta;
struct iwl_station_priv *sta_priv;
rcu_read_lock();
- sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
+ sta = ieee80211_find_sta(ctx->vif, addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
@@ -1169,6 +1174,15 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
ieee80211_sta_block_awake(priv->hw, sta, false);
}
rcu_read_unlock();
+}
+
+static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info,
+ bool is_agg)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
+
+ if (!is_agg)
+ iwlagn_non_agg_tx_status(priv, tx_info->ctx, hdr->addr1);
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
}
@@ -1193,7 +1207,8 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr];
- iwlagn_tx_status(priv, tx_info);
+ iwlagn_tx_status(priv, tx_info,
+ txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
hdr = (struct ieee80211_hdr *)tx_info->skb->data;
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
@@ -1222,7 +1237,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
int i, sh, ack;
u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
- u64 bitmap, sent_bitmap;
int successes = 0;
struct ieee80211_tx_info *info;
@@ -1241,40 +1255,68 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
if (sh < 0) /* tbw something is wrong with indices */
sh += 0x100;
- /* don't use 64-bit values for now */
- bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
if (agg->frame_count > (64 - sh)) {
IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1;
}
+ if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ /*
+ * sent and ack information provided by uCode
+ * use it instead of figure out ourself
+ */
+ if (ba_resp->txed_2_done > ba_resp->txed) {
+ IWL_DEBUG_TX_REPLY(priv,
+ "bogus sent(%d) and ack(%d) count\n",
+ ba_resp->txed, ba_resp->txed_2_done);
+ /*
+ * set txed_2_done = txed,
+ * so it won't impact rate scale
+ */
+ ba_resp->txed = ba_resp->txed_2_done;
+ }
+ IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
+ ba_resp->txed, ba_resp->txed_2_done);
+ } else {
+ u64 bitmap, sent_bitmap;
+
+ /* don't use 64-bit values for now */
+ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+
+ /* check for success or failure according to the
+ * transmitted bitmap and block-ack bitmap */
+ sent_bitmap = bitmap & agg->bitmap;
+
+ /* For each frame attempted in aggregation,
+ * update driver's record of tx frame's status. */
+ i = 0;
+ while (sent_bitmap) {
+ ack = sent_bitmap & 1ULL;
+ successes += ack;
+ IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
+ ack ? "ACK" : "NACK", i,
+ (agg->start_idx + i) & 0xff,
+ agg->start_idx + i);
+ sent_bitmap >>= 1;
+ ++i;
+ }
- /* check for success or failure according to the
- * transmitted bitmap and block-ack bitmap */
- sent_bitmap = bitmap & agg->bitmap;
-
- /* For each frame attempted in aggregation,
- * update driver's record of tx frame's status. */
- i = 0;
- while (sent_bitmap) {
- ack = sent_bitmap & 1ULL;
- successes += ack;
- IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
- ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
- agg->start_idx + i);
- sent_bitmap >>= 1;
- ++i;
+ IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
+ (unsigned long long)bitmap);
}
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
- info->status.ampdu_ack_len = successes;
- info->status.ampdu_len = agg->frame_count;
- iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
+ if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ info->status.ampdu_ack_len = ba_resp->txed_2_done;
+ info->status.ampdu_len = ba_resp->txed;
- IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
+ } else {
+ info->status.ampdu_ack_len = successes;
+ info->status.ampdu_len = agg->frame_count;
+ }
+ iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
return 0;
}
@@ -1385,7 +1427,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
priv->mac80211_registered &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
- iwl_wake_queue(priv, txq->swq_id);
+ iwl_wake_queue(priv, txq);
iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 703621107dac..24dabcd2a36c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -40,30 +40,36 @@
#include "iwl-agn.h"
#include "iwl-agn-calib.h"
-static const s8 iwlagn_default_queue_to_tx_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
- IWLAGN_CMD_FIFO_NUM,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
+#define IWL_AC_UNSET -1
+
+struct queue_to_fifo_ac {
+ s8 fifo, ac;
+};
+
+static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
+ { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+ { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
};
-static const s8 iwlagn_ipan_queue_to_tx_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
- IWL_TX_FIFO_BK_IPAN,
- IWL_TX_FIFO_BE_IPAN,
- IWL_TX_FIFO_VI_IPAN,
- IWL_TX_FIFO_VO_IPAN,
- IWL_TX_FIFO_BE_IPAN,
- IWLAGN_CMD_FIFO_NUM,
+static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
+ { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+ { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
+ { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_BE_IPAN, 2, },
+ { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
};
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
@@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
int iwlagn_alive_notify(struct iwl_priv *priv)
{
- const s8 *queues;
+ const struct queue_to_fifo_ac *queue_to_fifo;
u32 a;
unsigned long flags;
int i, chan;
@@ -492,9 +498,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* map queues to FIFOs */
if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
- queues = iwlagn_ipan_queue_to_tx_fifo;
+ queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
else
- queues = iwlagn_default_queue_to_tx_fifo;
+ queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
@@ -510,18 +516,25 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
for (i = 0; i < 10; i++) {
- int ac = queues[i];
+ int fifo = queue_to_fifo[i].fifo;
+ int ac = queue_to_fifo[i].ac;
iwl_txq_ctx_activate(priv, i);
- if (ac == IWL_TX_FIFO_UNUSED)
+ if (fifo == IWL_TX_FIFO_UNUSED)
continue;
- iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
+ if (ac != IWL_AC_UNSET)
+ iwl_set_swq_id(&priv->txq[i], ac, i);
+ iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0);
}
spin_unlock_irqrestore(&priv->lock, flags);
+ /* Enable L1-Active */
+ iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
iwlagn_send_wimax_coex(priv);
iwlagn_set_Xtal_calib(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c2636a7ab9ee..f13a83a7e62b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -90,170 +90,6 @@ MODULE_ALIAS("iwl4965");
static int iwlagn_ant_coupling;
static bool iwlagn_bt_ch_announce = 1;
-/**
- * iwlagn_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data. This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
- /* cast away the const for active_rxon in this function */
- struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
- int ret;
- bool new_assoc =
- !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
- bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
-
- if (!iwl_is_alive(priv))
- return -EBUSY;
-
- if (!ctx->is_active)
- return 0;
-
- /* always get timestamp with Rx frame */
- ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
-
- ret = iwl_check_rxon_cmd(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
- return -EINVAL;
- }
-
- /*
- * receive commit_rxon request
- * abort any previous channel switch if still in process
- */
- if (priv->switch_rxon.switch_in_progress &&
- (priv->switch_rxon.channel != ctx->staging.channel)) {
- IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
- le16_to_cpu(priv->switch_rxon.channel));
- iwl_chswitch_done(priv, false);
- }
-
- /* If we don't need to send a full RXON, we can use
- * iwl_rxon_assoc_cmd which is used to reconfigure filter
- * and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv, ctx)) {
- ret = iwl_send_rxon_assoc(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
- return ret;
- }
-
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- iwl_print_rx_config_cmd(priv, ctx);
- return 0;
- }
-
- /* If we are currently associated and the new config requires
- * an RXON_ASSOC and the new config wants the associated mask enabled,
- * we must clear the associated from the active configuration
- * before we apply the new config */
- if (iwl_is_associated_ctx(ctx) && new_assoc) {
- IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
- active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd),
- active_rxon);
-
- /* If the mask clearing failed then we set
- * active_rxon back to what it was previously */
- if (ret) {
- active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
- return ret;
- }
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
-
- IWL_DEBUG_INFO(priv, "Sending RXON\n"
- "* with%s RXON_FILTER_ASSOC_MSK\n"
- "* channel = %d\n"
- "* bssid = %pM\n",
- (new_assoc ? "" : "out"),
- le16_to_cpu(ctx->staging.channel),
- ctx->staging.bssid_addr);
-
- iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
-
- if (!old_assoc) {
- /*
- * First of all, before setting associated, we need to
- * send RXON timing so the device knows about the DTIM
- * period and other timing values
- */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Error setting RXON timing!\n");
- return ret;
- }
- }
-
- if (priv->cfg->ops->hcmd->set_pan_params) {
- ret = priv->cfg->ops->hcmd->set_pan_params(priv);
- if (ret)
- return ret;
- }
-
- /* Apply the new configuration
- * RXON unassoc clears the station table in uCode so restoration of
- * stations is needed after it (the RXON command) completes
- */
- if (!new_assoc) {
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
- if (new_assoc) {
- priv->start_calib = 0;
- /* Apply the new configuration
- * RXON assoc doesn't clear the station table in uCode,
- */
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- }
- iwl_print_rx_config_cmd(priv, ctx);
-
- iwl_init_sensitivity(priv);
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
- if (ret) {
- IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
void iwl_update_chain_flags(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx;
@@ -261,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_rxon_chain) {
for_each_context(priv, ctx) {
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- iwlcore_commit_rxon(priv, ctx);
+ if (ctx->active.rx_chain != ctx->staging.rx_chain)
+ iwlcore_commit_rxon(priv, ctx);
}
}
}
@@ -411,7 +248,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
return sizeof(*tx_beacon_cmd) + frame_size;
}
-static int iwl_send_beacon_cmd(struct iwl_priv *priv)
+
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl_frame *frame;
unsigned int frame_size;
@@ -661,7 +499,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
priv->beacon_skb = beacon;
- iwl_send_beacon_cmd(priv);
+ iwlagn_send_beacon_cmd(priv);
out:
mutex_unlock(&priv->mutex);
}
@@ -2664,7 +2502,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
- /* enable/disable bt channel announcement */
+ /* enable/disable bt channel inhibition */
priv->bt_ch_announce = iwlagn_bt_ch_announce;
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -2816,13 +2654,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- /* Enable timer to monitor the driver queues */
- mod_timer(&priv->monitor_recover,
- jiffies +
- msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+ /* Enable watchdog to monitor the driver tx queues */
+ iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
return;
@@ -2879,6 +2712,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv);
+ set_bit(STATUS_READY, &priv->status);
+
/* Configure the adapter for unassociated operation */
iwlcore_commit_rxon(priv, ctx);
@@ -2888,7 +2723,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_leds_init(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
iwl_power_update_mode(priv, true);
@@ -2916,8 +2750,7 @@ static void __iwl_down(struct iwl_priv *priv)
/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
* to prevent rearm timer */
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+ del_timer_sync(&priv->watchdog);
iwl_clear_ucode_stations(priv, NULL);
iwl_dealloc_bcast_stations(priv);
@@ -2978,7 +2811,8 @@ static void __iwl_down(struct iwl_priv *priv)
STATUS_EXIT_PENDING;
/* device going down, Stop using ICT table */
- iwl_disable_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.disable)
+ priv->cfg->ops->lib->isr_ops.disable(priv);
iwlagn_txq_ctx_stop(priv);
iwlagn_rxq_stop(priv);
@@ -3201,7 +3035,8 @@ static void iwl_bg_alive_start(struct work_struct *data)
return;
/* enable dram interrupt */
- iwl_reset_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.reset)
+ priv->cfg->ops->lib->isr_ops.reset(priv);
mutex_lock(&priv->mutex);
iwl_alive_start(priv);
@@ -3309,92 +3144,6 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-
-void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx;
- struct ieee80211_conf *conf = NULL;
- int ret = 0;
-
- if (!vif || !priv->is_open)
- return;
-
- ctx = iwl_rxon_ctx_from_vif(vif);
-
- if (vif->type == NL80211_IFTYPE_AP) {
- IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
- return;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- iwl_scan_cancel_timeout(priv, 200);
-
- conf = ieee80211_get_hw_conf(priv->hw);
-
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
-
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret)
- IWL_WARN(priv, "RXON timing - "
- "Attempting to continue.\n");
-
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
-
- IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- vif->bss_conf.aid, vif->bss_conf.beacon_int);
-
- if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
-
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- }
-
- iwlcore_commit_rxon(priv, ctx);
-
- IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, ctx->active.bssid_addr);
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- break;
- case NL80211_IFTYPE_ADHOC:
- iwl_send_beacon_cmd(priv);
- break;
- default:
- IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, vif->type);
- break;
- }
-
- /* the chain noise calibration will enabled PM upon completion
- * If chain noise has already been run, then we need to enable
- * power management here */
- if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
- iwl_power_update_mode(priv, false);
-
- /* Enable Rx differential gain and sensitivity calibrations */
- iwl_chain_noise_reset(priv);
- priv->start_calib = 1;
-
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -3420,7 +3169,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_NEED_DTIM_PERIOD |
- IEEE80211_HW_SPECTRUM_MGMT;
+ IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
if (!priv->cfg->base_params->broken_powersave)
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
@@ -3474,7 +3224,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
}
-static int iwl_mac_start(struct ieee80211_hw *hw)
+int iwlagn_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
@@ -3515,7 +3265,7 @@ out:
return 0;
}
-static void iwl_mac_stop(struct ieee80211_hw *hw)
+void iwlagn_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
@@ -3530,14 +3280,15 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
flush_workqueue(priv->workqueue);
- /* enable interrupts again in order to receive rfkill changes */
+ /* User space software may expect getting rfkill changes
+ * even if interface is down */
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl_enable_interrupts(priv);
+ iwl_enable_rfkill_int(priv);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
@@ -3553,73 +3304,12 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- int ret = 0;
-
- lockdep_assert_held(&priv->mutex);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* The following should be done only at AP bring up */
- if (!iwl_is_associated_ctx(ctx)) {
-
- /* RXON - unassoc (to set timing command) */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
-
- /* RXON Timing */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret)
- IWL_WARN(priv, "RXON timing failed - "
- "Attempting to continue.\n");
-
- /* AP has all antennas */
- priv->chain_noise_data.active_chains =
- priv->hw_params.valid_rx_ant;
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- ctx->staging.assoc_id = 0;
-
- if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |=
- RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &=
- ~RXON_FLG_SHORT_PREAMBLE_MSK;
-
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |=
- RXON_FLG_SHORT_SLOT_MSK;
- else
- ctx->staging.flags &=
- ~RXON_FLG_SHORT_SLOT_MSK;
- }
- /* need to send beacon cmd before committing assoc RXON! */
- iwl_send_beacon_cmd(priv);
- /* restore RXON assoc */
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
- }
- iwl_send_beacon_cmd(priv);
-
- /* FIXME - we need to add code here to detect a totally new
- * configuration, reset the AP, unassoc, rxon timing, assoc,
- * clear sta table, add BCAST sta... */
-}
-
-static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key)
+void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key)
{
-
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3631,10 +3321,9 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3701,10 +3390,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
int ret = -EINVAL;
@@ -3785,39 +3474,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum sta_notify_cmd cmd,
- struct ieee80211_sta *sta)
-{
- struct iwl_priv *priv = hw->priv;
- struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- int sta_id;
-
- switch (cmd) {
- case STA_NOTIFY_SLEEP:
- WARN_ON(!sta_priv->client);
- sta_priv->asleep = true;
- if (atomic_read(&sta_priv->pending_frames) > 0)
- ieee80211_sta_block_awake(hw, sta, true);
- break;
- case STA_NOTIFY_AWAKE:
- WARN_ON(!sta_priv->client);
- if (!sta_priv->asleep)
- break;
- sta_priv->asleep = false;
- sta_id = iwl_sta_id(sta);
- if (sta_id != IWL_INVALID_STATION)
- iwl_sta_modify_ps_wake(priv, sta_id);
- break;
- default:
- break;
- }
-}
-
-static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3858,8 +3517,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return 0;
}
-static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch)
+void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch)
{
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
@@ -3956,10 +3615,10 @@ out_exit:
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
@@ -3976,7 +3635,8 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
changed_flags, *total_flags);
CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
- CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
+ /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
+ CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
#undef CHK
@@ -3986,7 +3646,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
for_each_context(priv, ctx) {
ctx->staging.filter_flags &= ~filter_nand;
ctx->staging.filter_flags |= filter_or;
- iwlcore_commit_rxon(priv, ctx);
+
+ /*
+ * Not committing directly because hardware can perform a scan,
+ * but we'll eventually commit the filter flags change anyway.
+ */
}
mutex_unlock(&priv->mutex);
@@ -4001,7 +3665,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
-static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
+void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
{
struct iwl_priv *priv = hw->priv;
@@ -4074,12 +3738,9 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->ucode_trace.data = (unsigned long)priv;
priv->ucode_trace.function = iwl_bg_ucode_trace;
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- init_timer(&priv->monitor_recover);
- priv->monitor_recover.data = (unsigned long)priv;
- priv->monitor_recover.function =
- priv->cfg->ops->lib->recover_from_tx_stall;
- }
+ init_timer(&priv->watchdog);
+ priv->watchdog.data = (unsigned long)priv;
+ priv->watchdog.function = iwl_bg_watchdog;
if (!priv->cfg->base_params->use_isr_legacy)
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
@@ -4172,13 +3833,13 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
priv->bt_duration = BT_DURATION_LIMIT_DEF;
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
- priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF;
}
/* Set the tx_power_user_lmt to the lowest power level
* this value will get overwritten by channel max power avg
* from eeprom */
priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
+ priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
ret = iwl_init_channel_map(priv);
if (ret) {
@@ -4209,28 +3870,30 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
kfree(priv->scan_cmd);
}
-static struct ieee80211_ops iwl_hw_ops = {
- .tx = iwl_mac_tx,
- .start = iwl_mac_start,
- .stop = iwl_mac_stop,
+#ifdef CONFIG_IWL5000
+struct ieee80211_ops iwlagn_hw_ops = {
+ .tx = iwlagn_mac_tx,
+ .start = iwlagn_mac_start,
+ .stop = iwlagn_mac_stop,
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
- .config = iwl_mac_config,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwlagn_mac_config,
.configure_filter = iwlagn_configure_filter,
- .set_key = iwl_mac_set_key,
- .update_tkip_key = iwl_mac_update_tkip_key,
+ .set_key = iwlagn_mac_set_key,
+ .update_tkip_key = iwlagn_mac_update_tkip_key,
.conf_tx = iwl_mac_conf_tx,
- .reset_tsf = iwl_mac_reset_tsf,
- .bss_info_changed = iwl_bss_info_changed,
- .ampdu_action = iwl_mac_ampdu_action,
+ .bss_info_changed = iwlagn_bss_info_changed,
+ .ampdu_action = iwlagn_mac_ampdu_action,
.hw_scan = iwl_mac_hw_scan,
- .sta_notify = iwl_mac_sta_notify,
+ .sta_notify = iwlagn_mac_sta_notify,
.sta_add = iwlagn_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
- .channel_switch = iwl_mac_channel_switch,
- .flush = iwl_mac_flush,
+ .channel_switch = iwlagn_mac_channel_switch,
+ .flush = iwlagn_mac_flush,
.tx_last_beacon = iwl_mac_tx_last_beacon,
};
+#endif
static void iwl_hw_detect(struct iwl_priv *priv)
{
@@ -4298,10 +3961,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (cfg->mod_params->disable_hw_scan) {
dev_printk(KERN_DEBUG, &(pdev->dev),
"sw scan support is deprecated\n");
- iwl_hw_ops.hw_scan = NULL;
+#ifdef CONFIG_IWL5000
+ iwlagn_hw_ops.hw_scan = NULL;
+#endif
+#ifdef CONFIG_IWL4965
+ iwl4965_hw_ops.hw_scan = NULL;
+#endif
}
- hw = iwl_alloc_all(cfg, &iwl_hw_ops);
+ hw = iwl_alloc_all(cfg);
if (!hw) {
err = -ENOMEM;
goto out;
@@ -4333,6 +4001,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
BIT(NL80211_IFTYPE_ADHOC);
priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
BIT(NL80211_IFTYPE_STATION);
+ priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
@@ -4368,8 +4037,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
true : false;
- /* enable/disable bt channel announcement */
+ /* enable/disable bt channel inhibition */
priv->bt_ch_announce = iwlagn_bt_ch_announce;
+ IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
+ (priv->bt_ch_announce) ? "On" : "Off");
if (iwl_alloc_traffic_mem(priv))
IWL_ERR(priv, "Not enough memory to generate traffic log\n");
@@ -4461,6 +4132,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto out_free_eeprom;
+ err = iwl_eeprom_check_sku(priv);
+ if (err)
+ goto out_free_eeprom;
+
/* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
@@ -4500,8 +4175,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_msi(priv->pci_dev);
- iwl_alloc_isr_ict(priv);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ if (priv->cfg->ops->lib->isr_ops.alloc)
+ priv->cfg->ops->lib->isr_ops.alloc(priv);
+
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4515,14 +4192,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 8. Enable interrupts and read RFKILL state
*********************************************/
- /* enable interrupts if needed: hw bug w/a */
+ /* enable rfkill interrupt: hw bug w/a */
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
}
- iwl_enable_interrupts(priv);
+ iwl_enable_rfkill_int(priv);
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
@@ -4548,7 +4225,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
free_irq(priv->pci_dev->irq, priv);
- iwl_free_isr_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.free)
+ priv->cfg->ops->lib->isr_ops.free(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
@@ -4643,7 +4321,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_uninit_drv(priv);
- iwl_free_isr_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.free)
+ priv->cfg->ops->lib->isr_ops.free(priv);
dev_kfree_skb(priv->beacon_skb);
@@ -4734,51 +4413,32 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
-/* 6x00 Series Gen2a */
- {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)},
-
-/* 6x00 Series Gen2b */
- {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)},
+/* 6x05 Series */
+ {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
+
+/* 6x30 Series */
+ {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)},
/* 6x50 WiFi/WiMax Series */
{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
@@ -4788,13 +4448,13 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
{IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
-/* 6x50 WiFi/WiMax Series Gen2 */
- {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6050g2_bgn_cfg)},
+/* 6150 WiFi/WiMax Series */
+ {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)},
/* 1000 Series WiFi */
{IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
@@ -4812,10 +4472,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
/* 100 Series WiFi */
{IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
{IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)},
{IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)},
/* 130 Series WiFi */
{IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
@@ -4836,10 +4497,7 @@ static struct pci_driver iwl_driver = {
.id_table = iwl_hw_card_ids,
.probe = iwl_pci_probe,
.remove = __devexit_p(iwl_pci_remove),
-#ifdef CONFIG_PM
- .suspend = iwl_pci_suspend,
- .resume = iwl_pci_resume,
-#endif
+ .driver.pm = IWL_PM_OPS,
};
static int __init iwl_init(void)
@@ -4925,6 +4583,6 @@ module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO);
MODULE_PARM_DESC(antenna_coupling,
"specify antenna coupling in dB (defualt: 0 dB)");
-module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO);
-MODULE_PARM_DESC(bt_ch_announce,
- "Enable BT channel announcement mode (default: enable)");
+module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO);
+MODULE_PARM_DESC(bt_ch_inhibition,
+ "Disable BT channel inhibition (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index f525d55f2c0f..da303585f801 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -74,22 +74,22 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
-extern struct iwl_cfg iwl6000g2a_2agn_cfg;
-extern struct iwl_cfg iwl6000g2a_2abg_cfg;
-extern struct iwl_cfg iwl6000g2a_2bg_cfg;
-extern struct iwl_cfg iwl6000g2b_bgn_cfg;
-extern struct iwl_cfg iwl6000g2b_bg_cfg;
-extern struct iwl_cfg iwl6000g2b_2agn_cfg;
-extern struct iwl_cfg iwl6000g2b_2abg_cfg;
-extern struct iwl_cfg iwl6000g2b_2bgn_cfg;
-extern struct iwl_cfg iwl6000g2b_2bg_cfg;
+extern struct iwl_cfg iwl6005_2agn_cfg;
+extern struct iwl_cfg iwl6005_2abg_cfg;
+extern struct iwl_cfg iwl6005_2bg_cfg;
+extern struct iwl_cfg iwl1030_bgn_cfg;
+extern struct iwl_cfg iwl1030_bg_cfg;
+extern struct iwl_cfg iwl6030_2agn_cfg;
+extern struct iwl_cfg iwl6030_2abg_cfg;
+extern struct iwl_cfg iwl6030_2bgn_cfg;
+extern struct iwl_cfg iwl6030_2bg_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_2abg_cfg;
-extern struct iwl_cfg iwl6050g2_bgn_cfg;
+extern struct iwl_cfg iwl6150_bgn_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
extern struct iwl_cfg iwl1000_bg_cfg;
extern struct iwl_cfg iwl100_bgn_cfg;
@@ -102,6 +102,9 @@ extern struct iwl_hcmd_ops iwlagn_hcmd;
extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
+extern struct ieee80211_ops iwlagn_hw_ops;
+extern struct ieee80211_ops iwl4965_hw_ops;
+
int iwl_reset_ict(struct iwl_priv *priv);
void iwl_disable_ict(struct iwl_priv *priv);
int iwl_alloc_isr_ict(struct iwl_priv *priv);
@@ -132,6 +135,11 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
/* RXON */
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
/* uCode */
int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -249,6 +257,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
/* bt coex */
void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -292,9 +301,12 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
int tid, u16 ssn);
int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
int tid);
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
int iwl_update_bcast_stations(struct iwl_priv *priv);
+void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta);
/* rate */
static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -318,4 +330,31 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+/* mac80211 handlers (for 4965) */
+int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int iwlagn_mac_start(struct ieee80211_hw *hw);
+void iwlagn_mac_stop(struct ieee80211_hw *hw);
+void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast);
+int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key);
+void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key);
+int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch);
+void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
+
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 424801abc80e..f893d4a6aa87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp {
__le64 bitmap;
__le16 scd_flow;
__le16 scd_ssn;
+ /* following only for 5000 series and up */
+ u8 txed; /* number of frames sent */
+ u8 txed_2_done; /* number of frames acked */
} __packed;
/*
@@ -2407,9 +2410,9 @@ struct iwl_link_quality_cmd {
#define BT_FRAG_THRESHOLD_MAX 0
#define BT_FRAG_THRESHOLD_MIN 0
-#define BT_AGG_THRESHOLD_DEF 0
-#define BT_AGG_THRESHOLD_MAX 0
-#define BT_AGG_THRESHOLD_MIN 0
+#define BT_AGG_THRESHOLD_DEF 1200
+#define BT_AGG_THRESHOLD_MAX 8000
+#define BT_AGG_THRESHOLD_MIN 400
/*
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
@@ -2436,8 +2439,9 @@ struct iwl_bt_cmd {
#define IWLAGN_BT_FLAG_COEX_MODE_3W 2
#define IWLAGN_BT_FLAG_COEX_MODE_4W 3
-#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
-#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7)
+#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
+/* Disable Sync PSPoll on SCO/eSCO */
+#define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7)
#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF
#define IWLAGN_BT_PRIO_BOOST_MIN 0x00
@@ -2447,8 +2451,9 @@ struct iwl_bt_cmd {
#define IWLAGN_BT3_T7_DEFAULT 1
-#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff)
-#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff)
+#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000)
+#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000)
+#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff)
#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
@@ -2664,9 +2669,16 @@ struct iwl_spectrum_notification {
#define IWL_POWER_VEC_SIZE 5
#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1))
#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4))
+#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5))
+#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6))
+#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7))
+#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8))
+#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9))
struct iwl3945_powertable_cmd {
__le16 flags;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 25fb3912342c..efbde1f1a8bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -77,15 +77,15 @@ EXPORT_SYMBOL(iwl_bcast_addr);
/* This function both allocates and initializes hw and priv. */
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
- struct ieee80211_ops *hw_ops)
+struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
{
struct iwl_priv *priv;
-
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
- struct ieee80211_hw *hw =
- ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
+ struct ieee80211_hw *hw;
+
+ hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
+ cfg->ops->ieee80211_ops);
if (hw == NULL) {
pr_err("%s: Can not allocate network device\n",
cfg->name);
@@ -100,35 +100,6 @@ out:
}
EXPORT_SYMBOL(iwl_alloc_all);
-/*
- * QoS support
-*/
-static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!ctx->is_active)
- return;
-
- ctx->qos_data.def_qos_parm.qos_flags = 0;
-
- if (ctx->qos_data.qos_active)
- ctx->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- if (ctx->ht.enabled)
- ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
- IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- ctx->qos_data.qos_active,
- ctx->qos_data.def_qos_parm.qos_flags);
-
- iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
- sizeof(struct iwl_qosparam_cmd),
- &ctx->qos_data.def_qos_parm, NULL);
-}
-
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -317,40 +288,6 @@ void iwlcore_free_geos(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwlcore_free_geos);
-/*
- * iwlcore_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
- * function.
- */
-void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
- struct ieee80211_tx_info *info,
- __le16 fc, __le32 *tx_flags)
-{
- if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
- *tx_flags |= TX_CMD_FLG_RTS_MSK;
- *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
- *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
-
- if (!ieee80211_is_mgmt(fc))
- return;
-
- switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
- case cpu_to_le16(IEEE80211_STYPE_AUTH):
- case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
- case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
- case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
- *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- *tx_flags |= TX_CMD_FLG_CTS_MSK;
- break;
- }
- } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
- *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- *tx_flags |= TX_CMD_FLG_CTS_MSK;
- *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
- }
-}
-EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
-
-
static bool iwl_is_channel_extension(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel, u8 extension_chan_offset)
@@ -1020,6 +957,22 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
+ if (priv->cfg->internal_wimax_coex &&
+ (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
+ APMS_CLK_VAL_MRB_FUNC_MODE) ||
+ (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
+ APMG_PS_CTRL_VAL_RESET_REQ))) {
+ wake_up_interruptible(&priv->wait_command_queue);
+ /*
+ *Keep the restart process from trying to send host
+ * commands by clearing the INIT status bit
+ */
+ clear_bit(STATUS_READY, &priv->status);
+ IWL_ERR(priv, "RF is used by WiMAX\n");
+ return;
+ }
+
IWL_ERR(priv, "Loaded firmware version: %s\n",
priv->hw->wiphy->fw_version);
@@ -1206,8 +1159,16 @@ EXPORT_SYMBOL(iwl_apm_init);
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
- int ret = 0;
- s8 prev_tx_power = priv->tx_power_user_lmt;
+ int ret;
+ s8 prev_tx_power;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (priv->tx_power_user_lmt == tx_power && !force)
+ return 0;
+
+ if (!priv->cfg->ops->lib->send_tx_power)
+ return -EOPNOTSUPP;
if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
IWL_WARN(priv,
@@ -1224,93 +1185,29 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
return -EINVAL;
}
- if (priv->tx_power_user_lmt != tx_power)
- force = true;
+ if (!iwl_is_ready_rf(priv))
+ return -EIO;
- /* if nic is not up don't send command */
- if (iwl_is_ready_rf(priv)) {
- priv->tx_power_user_lmt = tx_power;
- if (force && priv->cfg->ops->lib->send_tx_power)
- ret = priv->cfg->ops->lib->send_tx_power(priv);
- else if (!priv->cfg->ops->lib->send_tx_power)
- ret = -EOPNOTSUPP;
- /*
- * if fail to set tx_power, restore the orig. tx power
- */
- if (ret)
- priv->tx_power_user_lmt = prev_tx_power;
+ /* scan complete use tx_power_next, need to be updated */
+ priv->tx_power_next = tx_power;
+ if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
+ IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n");
+ return 0;
}
- /*
- * Even this is an async host command, the command
- * will always report success from uCode
- * So once driver can placing the command into the queue
- * successfully, driver can use priv->tx_power_user_lmt
- * to reflect the current tx power
- */
- return ret;
-}
-EXPORT_SYMBOL(iwl_set_tx_power);
+ prev_tx_power = priv->tx_power_user_lmt;
+ priv->tx_power_user_lmt = tx_power;
-irqreturn_t iwl_isr_legacy(int irq, void *data)
-{
- struct iwl_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- unsigned long flags;
- if (!priv)
- return IRQ_NONE;
-
- spin_lock_irqsave(&priv->lock, flags);
+ ret = priv->cfg->ops->lib->send_tx_power(priv);
- /* Disable (but don't clear!) interrupts here to avoid
- * back-to-back ISRs and sporadic interrupts from our NIC.
- * If we have something to service, the tasklet will re-enable ints.
- * If we *don't* have something, we'll re-enable before leaving here. */
- inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* Discover which interrupts are active/pending */
- inta = iwl_read32(priv, CSR_INT);
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
+ /* if fail to set tx_power, restore the orig. tx power */
+ if (ret) {
+ priv->tx_power_user_lmt = prev_tx_power;
+ priv->tx_power_next = prev_tx_power;
}
-
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared. It might have already raised
- * an interrupt */
- IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
- }
-
- IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-
- unplugged:
- spin_unlock_irqrestore(&priv->lock, flags);
- return IRQ_HANDLED;
-
- none:
- /* re-enable interrupts here since we don't have anything to service. */
- /* only Re-enable if diabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- return IRQ_NONE;
+ return ret;
}
-EXPORT_SYMBOL(iwl_isr_legacy);
+EXPORT_SYMBOL(iwl_set_tx_power);
void iwl_send_bt_config(struct iwl_priv *priv)
{
@@ -1326,6 +1223,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
else
bt_cmd.flags = BT_COEX_ENABLE;
+ priv->bt_enable_flag = bt_cmd.flags;
IWL_DEBUG_INFO(priv, "BT coex %s\n",
(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
@@ -1452,318 +1350,51 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
-static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
+static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- struct ieee80211_sta *sta;
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-
- IWL_DEBUG_MAC80211(priv, "enter:\n");
-
- if (!ctx->ht.enabled)
- return;
-
- ctx->ht.protection =
- bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- ctx->ht.non_gf_sta_present =
- !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
- ht_conf->single_chain_sufficient = false;
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, bss_conf->bssid);
- if (sta) {
- struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
- int maxstreams;
-
- maxstreams = (ht_cap->mcs.tx_params &
- IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
- >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
- maxstreams += 1;
-
- if ((ht_cap->mcs.rx_mask[1] == 0) &&
- (ht_cap->mcs.rx_mask[2] == 0))
- ht_conf->single_chain_sufficient = true;
- if (maxstreams <= 1)
- ht_conf->single_chain_sufficient = true;
- } else {
- /*
- * If at all, this can only happen through a race
- * when the AP disconnects us while we're still
- * setting up the connection, in that case mac80211
- * will soon tell us about that.
- */
- ht_conf->single_chain_sufficient = true;
- }
- rcu_read_unlock();
- break;
- case NL80211_IFTYPE_ADHOC:
- ht_conf->single_chain_sufficient = true;
- break;
- default:
- break;
- }
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
+ iwl_connection_init_rx_config(priv, ctx);
-static inline void iwl_set_no_assoc(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- iwl_led_disassociate(priv);
- /*
- * inform the ucode that there is no longer an
- * association and that no more packets should be
- * sent
- */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = 0;
- iwlcore_commit_rxon(priv, ctx);
+ return iwlcore_commit_rxon(priv, ctx);
}
-static void iwlcore_beacon_update(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static int iwl_setup_interface(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
- struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
-
- if (!skb)
- return;
-
- IWL_DEBUG_ASSOC(priv, "enter\n");
+ struct ieee80211_vif *vif = ctx->vif;
+ int err;
lockdep_assert_held(&priv->mutex);
- if (!priv->beacon_ctx) {
- IWL_ERR(priv, "update beacon but no beacon context!\n");
- dev_kfree_skb(skb);
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->beacon_skb)
- dev_kfree_skb(priv->beacon_skb);
-
- priv->beacon_skb = skb;
-
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_ASSOC(priv, "leave\n");
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return;
- }
-
- priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
-}
-
-void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- int ret;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (!iwl_is_alive(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- if (changes & BSS_CHANGED_QOS) {
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- ctx->qos_data.qos_active = bss_conf->qos;
- iwl_update_qos(priv, ctx);
- spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- if (changes & BSS_CHANGED_BEACON_ENABLED) {
- /*
- * the add_interface code must make sure we only ever
- * have a single interface that could be beaconing at
- * any time.
- */
- if (vif->bss_conf.enable_beacon)
- priv->beacon_ctx = ctx;
- else
- priv->beacon_ctx = NULL;
- }
-
- if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
- dev_kfree_skb(priv->beacon_skb);
- priv->beacon_skb = ieee80211_beacon_get(hw, vif);
- }
-
- if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
- iwl_send_rxon_timing(priv, ctx);
-
- if (changes & BSS_CHANGED_BSSID) {
- IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
-
- /*
- * If there is currently a HW scan going on in the
- * background then we need to cancel it else the RXON
- * below/in post_associate will fail.
- */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* mac80211 only sets assoc when in STATION mode */
- if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
- memcpy(ctx->staging.bssid_addr,
- bss_conf->bssid, ETH_ALEN);
-
- /* currently needed in a few places */
- memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
- } else {
- ctx->staging.filter_flags &=
- ~RXON_FILTER_ASSOC_MSK;
- }
-
- }
-
/*
- * This needs to be after setting the BSSID in case
- * mac80211 decides to do both changes at once because
- * it will invoke post_associate.
+ * This variable will be correct only when there's just
+ * a single context, but all code using it is for hardware
+ * that supports only one context.
*/
- if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
- iwlcore_beacon_update(hw, vif);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- if (bss_conf->use_cts_prot)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
- else
- ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
- }
-
- if (changes & BSS_CHANGED_BASIC_RATES) {
- /* XXX use this information
- *
- * To do that, remove code from iwl_set_rate() and put something
- * like this here:
- *
- if (A-band)
- ctx->staging.ofdm_basic_rates =
- bss_conf->basic_rates;
- else
- ctx->staging.ofdm_basic_rates =
- bss_conf->basic_rates >> 4;
- ctx->staging.cck_basic_rates =
- bss_conf->basic_rates & 0xF;
- */
- }
-
- if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, vif);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- if (bss_conf->assoc) {
- priv->timestamp = bss_conf->timestamp;
-
- iwl_led_associate(priv);
-
- if (!iwl_is_rfkill(priv))
- priv->cfg->ops->lib->post_associate(priv, vif);
- } else
- iwl_set_no_assoc(priv, vif);
- }
-
- if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
- IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
- changes);
- ret = iwl_send_rxon_assoc(priv, ctx);
- if (!ret) {
- /* Sync active_rxon with latest change. */
- memcpy((void *)&ctx->active,
- &ctx->staging,
- sizeof(struct iwl_rxon_cmd));
- }
- }
+ priv->iw_mode = vif->type;
- if (changes & BSS_CHANGED_BEACON_ENABLED) {
- if (vif->bss_conf.enable_beacon) {
- memcpy(ctx->staging.bssid_addr,
- bss_conf->bssid, ETH_ALEN);
- memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
- iwl_led_associate(priv);
- iwlcore_config_ap(priv, vif);
- } else
- iwl_set_no_assoc(priv, vif);
- }
+ ctx->is_active = true;
- if (changes & BSS_CHANGED_IBSS) {
- ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
- bss_conf->ibss_joined);
- if (ret)
- IWL_ERR(priv, "failed to %s IBSS station %pM\n",
- bss_conf->ibss_joined ? "add" : "remove",
- bss_conf->bssid);
+ err = iwl_set_mode(priv, ctx);
+ if (err) {
+ if (!ctx->always_active)
+ ctx->is_active = false;
+ return err;
}
- if (changes & BSS_CHANGED_IDLE &&
- priv->cfg->ops->hcmd->set_pan_params) {
- if (priv->cfg->ops->hcmd->set_pan_params(priv))
- IWL_ERR(priv, "failed to update PAN params\n");
+ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist &&
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ /*
+ * pretend to have high BT traffic as long as we
+ * are operating in IBSS mode, as this will cause
+ * the rate scaling etc. to behave as intended.
+ */
+ priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
}
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-EXPORT_SYMBOL(iwl_bss_info_changed);
-
-static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-
- iwl_connection_init_rx_config(priv, ctx);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- return iwlcore_commit_rxon(priv, ctx);
+ return 0;
}
int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
@@ -1771,7 +1402,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *tmp, *ctx = NULL;
- int err = 0;
+ int err;
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
vif->type, vif->addr);
@@ -1813,36 +1444,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
vif_priv->ctx = ctx;
ctx->vif = vif;
- /*
- * This variable will be correct only when there's just
- * a single context, but all code using it is for hardware
- * that supports only one context.
- */
- priv->iw_mode = vif->type;
-
- ctx->is_active = true;
- err = iwl_set_mode(priv, vif);
- if (err) {
- if (!ctx->always_active)
- ctx->is_active = false;
- goto out_err;
- }
-
- if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- vif->type == NL80211_IFTYPE_ADHOC) {
- /*
- * pretend to have high BT traffic as long as we
- * are operating in IBSS mode, as this will cause
- * the rate scaling etc. to behave as intended.
- */
- priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
- }
-
- goto out;
+ err = iwl_setup_interface(priv, ctx);
+ if (!err)
+ goto out;
- out_err:
ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION;
out:
@@ -1853,27 +1459,24 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
}
EXPORT_SYMBOL(iwl_mac_add_interface);
-void iwl_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void iwl_teardown_interface(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ bool mode_change)
{
- struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- WARN_ON(ctx->vif != vif);
- ctx->vif = NULL;
+ lockdep_assert_held(&priv->mutex);
if (priv->scan_vif == vif) {
iwl_scan_cancel_timeout(priv, 200);
iwl_force_scan_end(priv);
}
- iwl_set_mode(priv, vif);
- if (!ctx->always_active)
- ctx->is_active = false;
+ if (!mode_change) {
+ iwl_set_mode(priv, ctx);
+ if (!ctx->always_active)
+ ctx->is_active = false;
+ }
/*
* When removing the IBSS interface, overwrite the
@@ -1883,211 +1486,31 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
* both values are the same and zero.
*/
if (vif->type == NL80211_IFTYPE_ADHOC)
- priv->bt_traffic_load = priv->notif_bt_traffic_load;
-
- memset(priv->bssid, 0, ETH_ALEN);
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-EXPORT_SYMBOL(iwl_mac_remove_interface);
-
-/**
- * iwl_mac_config - mac80211 config callback
- */
-int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = conf->channel;
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- struct iwl_rxon_context *ctx;
- unsigned long flags = 0;
- int ret = 0;
- u16 ch;
- int scan_active = 0;
-
- mutex_lock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- channel->hw_value, changed);
-
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- }
-
- if (changed & (IEEE80211_CONF_CHANGE_SMPS |
- IEEE80211_CONF_CHANGE_CHANNEL)) {
- /* mac80211 uses static for non-HT which is what we want */
- priv->current_ht_config.smps = conf->smps_mode;
-
- /*
- * Recalculate chain counts.
- *
- * If monitor mode is enabled then mac80211 will
- * set up the SM PS mode to OFF if an HT channel is
- * configured.
- */
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- for_each_context(priv, ctx)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- }
-
- /* during scanning mac80211 will delay channel setting until
- * scan finish with changed = 0
- */
- if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
- if (scan_active)
- goto set_ch_out;
-
- ch = channel->hw_value;
- ch_info = iwl_get_channel_info(priv, channel->band, ch);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for_each_context(priv, ctx) {
- /* Configure HT40 channels */
- ctx->ht.enabled = conf_is_ht(conf);
- if (ctx->ht.enabled) {
- if (conf_is_ht40_minus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ctx->ht.is_40mhz = true;
- } else if (conf_is_ht40_plus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ctx->ht.is_40mhz = true;
- } else {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ctx->ht.is_40mhz = false;
- }
- } else
- ctx->ht.is_40mhz = false;
-
- /*
- * Default to no protection. Protection mode will
- * later be set from BSS config in iwl_ht_conf
- */
- ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
-
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(ctx->staging.channel) != ch))
- ctx->staging.flags = 0;
-
- iwl_set_rxon_channel(priv, channel, ctx);
- iwl_set_rxon_ht(priv, ht_conf);
-
- iwl_set_flags_for_band(priv, ctx, channel->band,
- ctx->vif);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->cfg->ops->lib->update_bcast_stations)
- ret = priv->cfg->ops->lib->update_bcast_stations(priv);
-
- set_ch_out:
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
- }
-
- if (changed & (IEEE80211_CONF_CHANGE_PS |
- IEEE80211_CONF_CHANGE_IDLE)) {
- ret = iwl_power_update_mode(priv, false);
- if (ret)
- IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
- }
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- goto out;
- }
-
- if (scan_active)
- goto out;
-
- for_each_context(priv, ctx) {
- if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
- iwlcore_commit_rxon(priv, ctx);
- else
- IWL_DEBUG_INFO(priv,
- "Not re-sending same RXON configuration.\n");
- }
-
-out:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
- return ret;
+ priv->bt_traffic_load = priv->last_bt_traffic_load;
}
-EXPORT_SYMBOL(iwl_mac_config);
-void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- /* IBSS can only be the IWL_RXON_CTX_BSS context */
- struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n");
- spin_lock_irqsave(&priv->lock, flags);
- memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
- spin_unlock_irqrestore(&priv->lock, flags);
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* new association get rid of ibss beacon skb */
- if (priv->beacon_skb)
- dev_kfree_skb(priv->beacon_skb);
-
- priv->beacon_skb = NULL;
-
- priv->timestamp = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_scan_cancel_timeout(priv, 100);
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
+ mutex_lock(&priv->mutex);
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
+ WARN_ON(ctx->vif != vif);
+ ctx->vif = NULL;
- iwl_set_rate(priv);
+ iwl_teardown_interface(priv, vif, false);
+ memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
+
}
-EXPORT_SYMBOL(iwl_mac_reset_tsf);
+EXPORT_SYMBOL(iwl_mac_remove_interface);
int iwl_alloc_txq_mem(struct iwl_priv *priv)
{
@@ -2431,77 +1854,115 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
return 0;
}
-/**
- * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
- *
- * During normal condition (no queue is stuck), the timer is continually set to
- * execute every monitor_recover_period milliseconds after the last timer
- * expired. When the queue read_ptr is at the same place, the timer is
- * shorten to 100mSecs. This is
- * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
- * 2) to detect the stuck queues quicker before the station and AP can
- * disassociate each other.
- *
- * This function monitors all the tx queues and recover from it if any
- * of the queues are stuck.
- * 1. It first check the cmd queue for stuck conditions. If it is stuck,
- * it will recover by resetting the firmware and return.
- * 2. Then, it checks for station association. If it associates it will check
- * other queues. If any queue is stuck, it will recover by resetting
- * the firmware.
- * Note: It the number of times the queue read_ptr to be at the same place to
- * be MAX_REPEAT+1 in order to consider to be stuck.
- */
+int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype, bool newp2p)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ struct iwl_rxon_context *tmp;
+ u32 interface_modes;
+ int err;
+
+ newtype = ieee80211_iftype_p2p(newtype, newp2p);
+
+ mutex_lock(&priv->mutex);
+
+ interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
+
+ if (!(interface_modes & BIT(newtype))) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if (ctx->exclusive_interface_modes & BIT(newtype)) {
+ for_each_context(priv, tmp) {
+ if (ctx == tmp)
+ continue;
+
+ if (!tmp->vif)
+ continue;
+
+ /*
+ * The current mode switch would be exclusive, but
+ * another context is active ... refuse the switch.
+ */
+ err = -EBUSY;
+ goto out;
+ }
+ }
+
+ /* success */
+ iwl_teardown_interface(priv, vif, true);
+ vif->type = newtype;
+ err = iwl_setup_interface(priv, ctx);
+ WARN_ON(err);
+ /*
+ * We've switched internally, but submitting to the
+ * device may have failed for some reason. Mask this
+ * error, because otherwise mac80211 will not switch
+ * (and set the interface type back) and we'll be
+ * out of sync with it.
+ */
+ err = 0;
+
+ out:
+ mutex_unlock(&priv->mutex);
+ return err;
+}
+EXPORT_SYMBOL(iwl_mac_change_interface);
+
/*
- * The maximum number of times the read pointer of the tx queue at the
- * same place without considering to be stuck.
+ * On every watchdog tick we check (latest) time stamp. If it does not
+ * change during timeout period and queue is not empty we reset firmware.
*/
-#define MAX_REPEAT (2)
static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
{
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
+ struct iwl_tx_queue *txq = &priv->txq[cnt];
+ struct iwl_queue *q = &txq->q;
+ unsigned long timeout;
+ int ret;
- txq = &priv->txq[cnt];
- q = &txq->q;
- /* queue is empty, skip */
- if (q->read_ptr == q->write_ptr)
+ if (q->read_ptr == q->write_ptr) {
+ txq->time_stamp = jiffies;
return 0;
+ }
- if (q->read_ptr == q->last_read_ptr) {
- /* a queue has not been read from last time */
- if (q->repeat_same_read_ptr > MAX_REPEAT) {
- IWL_ERR(priv,
- "queue %d stuck %d time. Fw reload.\n",
- q->id, q->repeat_same_read_ptr);
- q->repeat_same_read_ptr = 0;
- iwl_force_reset(priv, IWL_FW_RESET, false);
- } else {
- q->repeat_same_read_ptr++;
- IWL_DEBUG_RADIO(priv,
- "queue %d, not read %d time\n",
- q->id,
- q->repeat_same_read_ptr);
- mod_timer(&priv->monitor_recover,
- jiffies + msecs_to_jiffies(
- IWL_ONE_HUNDRED_MSECS));
- return 1;
- }
- } else {
- q->last_read_ptr = q->read_ptr;
- q->repeat_same_read_ptr = 0;
+ timeout = txq->time_stamp +
+ msecs_to_jiffies(priv->cfg->base_params->wd_timeout);
+
+ if (time_after(jiffies, timeout)) {
+ IWL_ERR(priv, "Queue %d stuck for %u ms.\n",
+ q->id, priv->cfg->base_params->wd_timeout);
+ ret = iwl_force_reset(priv, IWL_FW_RESET, false);
+ return (ret == -EAGAIN) ? 0 : 1;
}
+
return 0;
}
-void iwl_bg_monitor_recover(unsigned long data)
+/*
+ * Making watchdog tick be a quarter of timeout assure we will
+ * discover the queue hung between timeout and 1.25*timeout
+ */
+#define IWL_WD_TICK(timeout) ((timeout) / 4)
+
+/*
+ * Watchdog timer callback, we check each tx queue for stuck, if if hung
+ * we reset the firmware. If everything is fine just rearm the timer.
+ */
+void iwl_bg_watchdog(unsigned long data)
{
struct iwl_priv *priv = (struct iwl_priv *)data;
int cnt;
+ unsigned long timeout;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ timeout = priv->cfg->base_params->wd_timeout;
+ if (timeout == 0)
+ return;
+
/* monitor and check for stuck cmd queue */
if (iwl_check_stuck_queue(priv, priv->cmd_queue))
return;
@@ -2516,17 +1977,23 @@ void iwl_bg_monitor_recover(unsigned long data)
return;
}
}
- if (priv->cfg->base_params->monitor_recover_period) {
- /*
- * Reschedule the timer to occur in
- * priv->cfg->base_params->monitor_recover_period
- */
- mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+
+ mod_timer(&priv->watchdog, jiffies +
+ msecs_to_jiffies(IWL_WD_TICK(timeout)));
}
-EXPORT_SYMBOL(iwl_bg_monitor_recover);
+EXPORT_SYMBOL(iwl_bg_watchdog);
+
+void iwl_setup_watchdog(struct iwl_priv *priv)
+{
+ unsigned int timeout = priv->cfg->base_params->wd_timeout;
+ if (timeout)
+ mod_timer(&priv->watchdog,
+ jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout)));
+ else
+ del_timer(&priv->watchdog);
+}
+EXPORT_SYMBOL(iwl_setup_watchdog);
/*
* extended beacon time format
@@ -2584,8 +2051,9 @@ EXPORT_SYMBOL(iwl_add_beacon_time);
#ifdef CONFIG_PM
-int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+int iwl_pci_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct iwl_priv *priv = pci_get_drvdata(pdev);
/*
@@ -2597,18 +2065,14 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
*/
iwl_apm_stop(priv);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
return 0;
}
EXPORT_SYMBOL(iwl_pci_suspend);
-int iwl_pci_resume(struct pci_dev *pdev)
+int iwl_pci_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
bool hw_rfkill = false;
/*
@@ -2617,11 +2081,6 @@ int iwl_pci_resume(struct pci_dev *pdev)
*/
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
iwl_enable_interrupts(priv);
if (!(iwl_read32(priv, CSR_GP_CNTRL) &
@@ -2639,4 +2098,14 @@ int iwl_pci_resume(struct pci_dev *pdev)
}
EXPORT_SYMBOL(iwl_pci_resume);
+const struct dev_pm_ops iwl_pm_ops = {
+ .suspend = iwl_pci_suspend,
+ .resume = iwl_pci_resume,
+ .freeze = iwl_pci_suspend,
+ .thaw = iwl_pci_resume,
+ .poweroff = iwl_pci_suspend,
+ .restore = iwl_pci_resume,
+};
+EXPORT_SYMBOL(iwl_pm_ops);
+
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64527def059f..a3474376fdbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -120,6 +120,14 @@ struct iwl_apm_ops {
void (*config)(struct iwl_priv *priv);
};
+struct iwl_isr_ops {
+ irqreturn_t (*isr) (int irq, void *data);
+ void (*free)(struct iwl_priv *priv);
+ int (*alloc)(struct iwl_priv *priv);
+ int (*reset)(struct iwl_priv *priv);
+ void (*disable)(struct iwl_priv *priv);
+};
+
struct iwl_debugfs_ops {
ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
@@ -193,22 +201,15 @@ struct iwl_lib_ops {
/* power */
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- void (*post_associate)(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
- void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
- irqreturn_t (*isr) (int irq, void *data);
+
+ /* isr */
+ struct iwl_isr_ops isr_ops;
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
/* temperature */
struct iwl_temp_ops temp_ops;
- /* station management */
- int (*manage_ibss_station)(struct iwl_priv *priv,
- struct ieee80211_vif *vif, bool add);
- int (*update_bcast_stations)(struct iwl_priv *priv);
- /* recover from tx queue stall */
- void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
bool (*check_plcp_health)(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
@@ -235,12 +236,23 @@ struct iwl_nic_ops {
void (*additional_nic_config)(struct iwl_priv *priv);
};
+struct iwl_legacy_ops {
+ void (*post_associate)(struct iwl_priv *priv);
+ void (*config_ap)(struct iwl_priv *priv);
+ /* station management */
+ int (*update_bcast_stations)(struct iwl_priv *priv);
+ int (*manage_ibss_station)(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add);
+};
+
struct iwl_ops {
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
const struct iwl_led_ops *led;
const struct iwl_nic_ops *nic;
+ const struct iwl_legacy_ops *legacy;
+ const struct ieee80211_ops *ieee80211_ops;
};
struct iwl_mod_params {
@@ -266,7 +278,7 @@ struct iwl_mod_params {
* @plcp_delta_threshold: plcp error rate threshold used to trigger
* radio tuning when there is a high receiving plcp error rate
* @chain_noise_scale: default chain noise scale used for gain computation
- * @monitor_recover_period: default timer used to check stuck queues
+ * @wd_timeout: TX queues watchdog timeout
* @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
* @tx_power_by_driver: tx power calibration performed by driver
@@ -276,7 +288,10 @@ struct iwl_mod_params {
* sensitivity calibration operation
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
-*/
+ * @shadow_reg_enable: HW shadhow register bit
+ * @no_agg_framecnt_info: uCode do not provide aggregation frame count
+ * information
+ */
struct iwl_base_params {
int eeprom_size;
int num_of_queues; /* def: HW dependent */
@@ -298,14 +313,15 @@ struct iwl_base_params {
const bool support_wimax_coexist;
u8 plcp_delta_threshold;
s32 chain_noise_scale;
- /* timer period for monitor the driver queues */
- u32 monitor_recover_period;
+ unsigned int wd_timeout;
bool temperature_kelvin;
u32 max_event_log_size;
const bool tx_power_by_driver;
const bool ucode_tracing;
const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver;
+ const bool shadow_reg_enable;
+ const bool no_agg_framecnt_info;
};
/*
* @advanced_bt_coexist: support advanced bt coexist
@@ -315,6 +331,7 @@ struct iwl_base_params {
* @agg_time_limit: maximum number of uSec in aggregation
* @ampdu_factor: Maximum A-MPDU length factor
* @ampdu_density: Minimum A-MPDU spacing
+ * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
*/
struct iwl_bt_params {
bool advanced_bt_coexist;
@@ -324,6 +341,7 @@ struct iwl_bt_params {
u16 agg_time_limit;
u8 ampdu_factor;
u8 ampdu_density;
+ bool bt_sco_disable;
};
/*
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
@@ -344,6 +362,10 @@ struct iwl_ht_params {
* @need_dc_calib: need to perform init dc calibration
* @need_temp_offset_calib: need to perform temperature offset calibration
* @scan_antennas: available antenna for scan operation
+ * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
+ * @adv_pm: advance power management
+ * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
+ * @internal_wimax_coex: internal wifi/wimax combo device
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -389,15 +411,17 @@ struct iwl_cfg {
const bool need_dc_calib; /* if used set to true */
const bool need_temp_offset_calib; /* if used set to true */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
- u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
+ enum iwl_led_mode led_mode;
+ const bool adv_pm;
+ const bool rx_with_siso_diversity;
+ const bool internal_wimax_coex;
};
/***************************
* L i b *
***************************/
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
- struct ieee80211_ops *hw_ops);
+struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -425,23 +449,16 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
void iwl_irq_handle_error(struct iwl_priv *priv);
-void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
-void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes);
int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
-int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
-void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
-void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
+int iwl_mac_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype, bool newp2p);
int iwl_alloc_txq_mem(struct iwl_priv *priv);
void iwl_free_txq_mem(struct iwl_priv *priv);
-void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
- struct ieee80211_tx_info *info,
- __le16 fc, __le32 *tx_flags);
+
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -529,6 +546,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
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);
+void iwl_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
* TX power
****************************************************/
@@ -598,7 +616,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
/*****************************************************
* PCI *
*****************************************************/
-irqreturn_t iwl_isr_legacy(int irq, void *data);
static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
{
@@ -609,15 +626,23 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
return pci_lnk_ctl;
}
-void iwl_bg_monitor_recover(unsigned long data);
+void iwl_bg_watchdog(unsigned long data);
u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
u32 addon, u32 beacon_interval);
#ifdef CONFIG_PM
-int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
-int iwl_pci_resume(struct pci_dev *pdev);
-#endif /* CONFIG_PM */
+int iwl_pci_suspend(struct device *device);
+int iwl_pci_resume(struct device *device);
+extern const struct dev_pm_ops iwl_pm_ops;
+
+#define IWL_PM_OPS (&iwl_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define IWL_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
/*****************************************************
* Error Handling Debugging
@@ -724,11 +749,6 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
{
return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
}
-static inline void iwlcore_config_ap(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
-{
- priv->cfg->ops->lib->config_ap(priv, vif);
-}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
struct iwl_priv *priv, enum ieee80211_band band)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 2aa15ab13892..b80bf7dff55b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -132,6 +132,8 @@
#define CSR_LED_REG (CSR_BASE+0x094)
#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0)
+#define CSR_MAC_SHADOW_REG_CTRL (CSR_BASE+0x0A8) /* 6000 and up */
+
/* GIO Chicken Bits (PCI Express bus link power management) */
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 0b961a353ff6..ebdea3be3ef9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -120,6 +120,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
/* 0x000000F0 - 0x00000010 */
#define IWL_DL_MACDUMP (1 << 4)
#define IWL_DL_HCMD_DUMP (1 << 5)
+#define IWL_DL_EEPROM (1 << 6)
#define IWL_DL_RADIO (1 << 7)
/* 0x00000F00 - 0x00000100 */
#define IWL_DL_POWER (1 << 8)
@@ -164,6 +165,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
+#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a)
#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8fdd4efdb1d3..6fe80b5e7a15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
" swq_id=%#.2x (ac %d/hwq %d)\n",
cnt, q->read_ptr, q->write_ptr,
!!test_bit(cnt, priv->queue_stopped),
- txq->swq_id,
- txq->swq_id & 0x80 ? txq->swq_id & 3 :
- txq->swq_id,
- txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
- 0x1f : txq->swq_id);
+ txq->swq_id, txq->swq_id & 3,
+ (txq->swq_id >> 2) & 0x1f);
if (cnt >= 4)
continue;
/* for the ACs, display the stop count too */
@@ -1537,32 +1534,26 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
user_buf, count, ppos);
}
-static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
+static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
char buf[8];
int buf_size;
- int period;
+ int timeout;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
- if (sscanf(buf, "%d", &period) != 1)
+ if (sscanf(buf, "%d", &timeout) != 1)
return -EINVAL;
- if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
- priv->cfg->base_params->monitor_recover_period =
- IWL_DEF_MONITORING_PERIOD;
- else
- priv->cfg->base_params->monitor_recover_period = period;
+ if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
+ timeout = IWL_DEF_WD_TIMEOUT;
- if (priv->cfg->base_params->monitor_recover_period)
- mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- else
- del_timer_sync(&priv->monitor_recover);
+ priv->cfg->base_params->wd_timeout = timeout;
+ iwl_setup_watchdog(priv);
return count;
}
@@ -1576,11 +1567,18 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
const size_t bufsz = sizeof(buf);
ssize_t ret;
+ if (!priv->bt_enable_flag) {
+ pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ return ret;
+ }
+ pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
+ priv->bt_enable_flag);
pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
priv->bt_full_concurrent ? "full concurrency" : "3-wire");
pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
"last traffic notif: %d\n",
- priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load);
+ priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
"sco_active: %d, kill_ack_mask: %x, "
"kill_cts_mask: %x\n",
@@ -1689,7 +1687,7 @@ DEBUGFS_READ_FILE_OPS(rxon_flags);
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
-DEBUGFS_WRITE_FILE_OPS(monitor_period);
+DEBUGFS_WRITE_FILE_OPS(wd_timeout);
DEBUGFS_READ_FILE_OPS(bt_traffic);
DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
DEBUGFS_READ_FILE_OPS(reply_tx_error);
@@ -1766,7 +1764,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
- DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
+ DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
if (priv->cfg->base_params->sensitivity_calib_by_driver)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 70e07fa48405..8dda67850af4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -129,9 +129,6 @@ struct iwl_queue {
int write_ptr; /* 1-st empty entry (index) host_w*/
int read_ptr; /* last used entry (index) host_r*/
/* use for monitoring and recovering the stuck queue */
- int last_read_ptr; /* storing the last read_ptr */
- /* number of time read_ptr and last_read_ptr are the same */
- u8 repeat_same_read_ptr;
dma_addr_t dma_addr; /* physical addr for BD's */
int n_window; /* safe queue window */
u32 id;
@@ -155,6 +152,7 @@ struct iwl_tx_info {
* @meta: array of meta data for each command/tx buffer
* @dma_addr_cmd: physical address of cmd/tx buffer array
* @txb: array of per-TFD driver data
+ * @time_stamp: time (in jiffies) of last read_ptr change
* @need_update: indicates need to update read/write index
* @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
*
@@ -170,6 +168,7 @@ struct iwl_tx_queue {
struct iwl_device_cmd **cmd;
struct iwl_cmd_meta *meta;
struct iwl_tx_info *txb;
+ unsigned long time_stamp;
u8 need_update;
u8 sched_retry;
u8 active;
@@ -1104,11 +1103,10 @@ struct iwl_event_log {
#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
-/* timer constants use to monitor and recover stuck tx queues in mSecs */
-#define IWL_DEF_MONITORING_PERIOD (1000)
-#define IWL_LONG_MONITORING_PERIOD (5000)
-#define IWL_ONE_HUNDRED_MSECS (100)
-#define IWL_MAX_MONITORING_PERIOD (60000)
+/* TX queue watchdog timeouts in mSecs */
+#define IWL_DEF_WD_TIMEOUT (2000)
+#define IWL_LONG_WD_TIMEOUT (10000)
+#define IWL_MAX_WD_TIMEOUT (120000)
/* BT Antenna Coupling Threshold (dB) */
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
@@ -1162,6 +1160,8 @@ struct iwl_rxon_context {
*/
bool always_active, is_active;
+ bool ht_need_multiple_chains;
+
enum iwl_rxon_context_id ctxid;
u32 interface_modes, exclusive_interface_modes;
@@ -1468,8 +1468,9 @@ struct iwl_priv {
};
/* bt coex */
+ u8 bt_enable_flag;
u8 bt_status;
- u8 bt_traffic_load, notif_bt_traffic_load;
+ u8 bt_traffic_load, last_bt_traffic_load;
bool bt_ch_announce;
bool bt_sco_active;
bool bt_full_concurrent;
@@ -1480,7 +1481,6 @@ struct iwl_priv {
u16 bt_on_thresh;
u16 bt_duration;
u16 dynamic_frag_thresh;
- u16 dynamic_agg_thresh;
u8 bt_ci_compliance;
struct work_struct bt_traffic_change_work;
@@ -1517,6 +1517,7 @@ struct iwl_priv {
s8 tx_power_user_lmt;
s8 tx_power_device_lmt;
s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */
+ s8 tx_power_next;
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1542,7 +1543,7 @@ struct iwl_priv {
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
struct timer_list ucode_trace;
- struct timer_list monitor_recover;
+ struct timer_list watchdog;
bool hw_ready;
struct iwl_event_log event_log;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 87cd10ff285d..358cfd7e5af1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -147,7 +147,7 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
int ret = 0;
- IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp);
+ IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
switch (gp) {
case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
@@ -354,7 +354,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
*/
valid_addr = next_link_addr;
next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
- IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
+ IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n",
usedblocks, next_link_addr);
if (iwl_read_otp_word(priv, next_link_addr, &link_value))
return -EINVAL;
@@ -374,7 +374,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
} while (usedblocks <= priv->cfg->base_params->max_ll_items);
/* OTP has no valid blocks */
- IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
+ IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n");
return -EINVAL;
}
@@ -414,7 +414,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
return -ENOENT;
/* allocate eeprom */
sz = priv->cfg->base_params->eeprom_size;
- IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz);
+ IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
priv->eeprom = kzalloc(sz, GFP_KERNEL);
if (!priv->eeprom) {
ret = -ENOMEM;
@@ -492,7 +492,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
}
}
- IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
+ IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
? "OTP" : "EEPROM",
iwl_eeprom_query16(priv, EEPROM_VERSION));
@@ -594,7 +594,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;
- IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -634,11 +634,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
struct iwl_channel_info *ch_info;
if (priv->channel_count) {
- IWL_DEBUG_INFO(priv, "Channel map already initialized.\n");
+ IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n");
return 0;
}
- IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n");
+ IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n");
priv->channel_count =
ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -647,7 +647,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ARRAY_SIZE(iwl_eeprom_band_4) +
ARRAY_SIZE(iwl_eeprom_band_5);
- IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count);
+ IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
+ priv->channel_count);
priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
priv->channel_count, GFP_KERNEL);
@@ -686,7 +687,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
IEEE80211_CHAN_NO_HT40;
if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
+ IWL_DEBUG_EEPROM(priv,
+ "Ch. %d Flags %x [%sGHz] - "
"No traffic\n",
ch_info->channel,
ch_info->flags,
@@ -702,7 +704,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] "
+ "%s%s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index d9b590625ae4..9e6f31355eee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -110,9 +110,18 @@ enum {
};
/* SKU Capabilities */
+/* 3945 only */
#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
+/* 5000 and up */
+#define EEPROM_SKU_CAP_BAND_POS (4)
+#define EEPROM_SKU_CAP_BAND_SELECTION \
+ (3 << EEPROM_SKU_CAP_BAND_POS)
+#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6)
+#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7)
+#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8)
+
/* *regulatory* channel data format in eeprom, one for each channel.
* There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */
struct iwl_eeprom_channel {
@@ -120,6 +129,17 @@ struct iwl_eeprom_channel {
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __packed;
+enum iwl_eeprom_enhanced_txpwr_flags {
+ IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0),
+ IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1),
+ IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2),
+ IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3),
+ IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4),
+ IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5),
+ IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6),
+ IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7),
+};
+
/**
* iwl_eeprom_enhanced_txpwr structure
* This structure presents the enhanced regulatory tx power limit layout
@@ -127,21 +147,23 @@ struct iwl_eeprom_channel {
* Enhanced regulatory tx power portion of eeprom image can be broken down
* into individual structures; each one is 8 bytes in size and contain the
* following information
- * @common: (desc + channel) not used by driver, should _NOT_ be "zero"
+ * @flags: entry flags
+ * @channel: channel number
* @chain_a_max_pwr: chain a max power in 1/2 dBm
* @chain_b_max_pwr: chain b max power in 1/2 dBm
* @chain_c_max_pwr: chain c max power in 1/2 dBm
- * @reserved: not used, should be "zero"
+ * @delta_20_in_40: 20-in-40 deltas (hi/lo)
* @mimo2_max_pwr: mimo2 max power in 1/2 dBm
* @mimo3_max_pwr: mimo3 max power in 1/2 dBm
*
*/
struct iwl_eeprom_enhanced_txpwr {
- __le16 common;
+ u8 flags;
+ u8 channel;
s8 chain_a_max;
s8 chain_b_max;
s8 chain_c_max;
- s8 reserved;
+ u8 delta_20_in_40;
s8 mimo2_max;
s8 mimo3_max;
} __packed;
@@ -186,6 +208,8 @@ struct iwl_eeprom_enhanced_txpwr {
#define EEPROM_LINK_CALIBRATION (2*0x67)
#define EEPROM_LINK_PROCESS_ADJST (2*0x68)
#define EEPROM_LINK_OTHERS (2*0x69)
+#define EEPROM_LINK_TXP_LIMIT (2*0x6a)
+#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b)
/* agn regulatory - indirect access */
#define EEPROM_REG_BAND_1_CHANNELS ((0x08)\
@@ -207,59 +231,6 @@ struct iwl_eeprom_enhanced_txpwr {
#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)
-#define EEPROM_TXPOWER_COMMON_HT40_INDEX (2)
-
-/**
- * Partition the enhanced tx power portion of eeprom image into
- * 10 sections based on band, modulation, frequency and channel
- *
- * Section 1: all CCK channels
- * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40 ) channels
- * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
- * Section 4: 2.4 GHz 20MHz channels: 1, 2, 10, 11. Both Legacy and HT
- * Section 5: 2.4 GHz 40MHz channels: 1, 2, 6, 7, 9, (_above_)
- * Section 6: 5.2 GHz 20MHz channels: 36, 64, 100, both Legacy and HT
- * Section 7: 5.2 GHz 40MHz channels: 36, 60, 100 (_above_)
- * Section 8: 2.4 GHz channel 13, Both Legacy and HT
- * Section 9: 2.4 GHz channel 140, Both Legacy and HT
- * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
- */
-/* 2.4 GHz band: CCK */
-#define EEPROM_LB_CCK_20_COMMON ((0xA8)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
-/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_LB_OFDM_COMMON ((0xB0)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
-/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_HB_OFDM_COMMON ((0xC8)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
-/* 2.4GHz band channels:
- * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
-#define EEPROM_LB_OFDM_20_BAND ((0xE0)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
-/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
-#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
-/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
-#define EEPROM_HB_OFDM_20_BAND ((0x148)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
-/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
-/* 2.4 GHz band, channnel 13: Legacy, HT */
-#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
-/* 5.2 GHz band, channnel 140: Legacy, HT */
-#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
-/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
- | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
-
-
/* 5050 Specific */
#define EEPROM_5050_TX_POWER_VERSION (4)
#define EEPROM_5050_EEPROM_VERSION (0x21E)
@@ -389,6 +360,8 @@ struct iwl_eeprom_calib_info {
#define INDIRECT_CALIBRATION 0x00040000
#define INDIRECT_PROCESS_ADJST 0x00050000
#define INDIRECT_OTHERS 0x00060000
+#define INDIRECT_TXP_LIMIT 0x00070000
+#define INDIRECT_TXP_LIMIT_SIZE 0x00080000
#define INDIRECT_ADDRESS 0x00100000
/* General */
@@ -397,11 +370,10 @@ struct iwl_eeprom_calib_info {
#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
#define EEPROM_VERSION (2*0x44) /* 2 bytes */
-#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */
+#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */
#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
-#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */
#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */
/* The following masks are to be applied on EEPROM_RADIO_CONFIG */
@@ -504,6 +476,7 @@ struct iwl_eeprom_ops {
int iwl_eeprom_init(struct iwl_priv *priv);
void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv);
+int iwl_eeprom_check_sku(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 1aaef70deaec..8821f088ba7f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -44,15 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
return &hw->conf;
}
-static inline unsigned long elapsed_jiffies(unsigned long start,
- unsigned long end)
-{
- if (end >= start)
- return end - start;
-
- return end + (MAX_JIFFY_OFFSET - start) + 1;
-}
-
/**
* iwl_queue_inc_wrap - increment queue index, wrap back to beginning
* @index -- current index
@@ -104,42 +95,36 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
* | | | | | | | |
* | | | | | | +-+-------- AC queue (0-3)
* | | | | | |
- * | +-+-+-+-+------------ HW A-MPDU queue
+ * | +-+-+-+-+------------ HW queue ID
* |
- * +---------------------- indicates agg queue
+ * +---------------------- unused
*/
-static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
+static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq)
{
BUG_ON(ac > 3); /* only have 2 bits */
- BUG_ON(hwq > 31); /* only have 5 bits */
+ BUG_ON(hwq > 31); /* only use 5 bits */
- return 0x80 | (hwq << 2) | ac;
+ txq->swq_id = (hwq << 2) | ac;
}
-static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
+static inline void iwl_wake_queue(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
- u8 ac = queue;
- u8 hwq = queue;
-
- if (queue & 0x80) {
- ac = queue & 3;
- hwq = (queue >> 2) & 0x1f;
- }
+ u8 queue = txq->swq_id;
+ u8 ac = queue & 3;
+ u8 hwq = (queue >> 2) & 0x1f;
if (test_and_clear_bit(hwq, priv->queue_stopped))
if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(priv->hw, ac);
}
-static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
+static inline void iwl_stop_queue(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
- u8 ac = queue;
- u8 hwq = queue;
-
- if (queue & 0x80) {
- ac = queue & 3;
- hwq = (queue >> 2) & 0x1f;
- }
+ u8 queue = txq->swq_id;
+ u8 ac = queue & 3;
+ u8 hwq = (queue >> 2) & 0x1f;
if (!test_and_set_bit(hwq, priv->queue_stopped))
if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
@@ -163,6 +148,12 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv)
IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
}
+static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
+{
+ IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
+ iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+}
+
static inline void iwl_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 86c2b6fed0c6..46ccdf406e8e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -45,9 +45,8 @@
/* default: IWL_LED_BLINK(0) using blinking index table */
static int led_mode;
module_param(led_mode, int, S_IRUGO);
-MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
- "(default 0)");
-
+MODULE_PARM_DESC(led_mode, "0=system default, "
+ "1=On(RF On)/Off(RF Off), 2=blinking");
static const struct {
u16 tpt; /* Mb/s */
@@ -128,12 +127,13 @@ EXPORT_SYMBOL(iwl_led_start);
int iwl_led_associate(struct iwl_priv *priv)
{
IWL_DEBUG_LED(priv, "Associated\n");
- if (led_mode == IWL_LED_BLINK)
+ if (priv->cfg->led_mode == IWL_LED_BLINK)
priv->allow_blinking = 1;
priv->last_blink_time = jiffies;
return 0;
}
+EXPORT_SYMBOL(iwl_led_associate);
int iwl_led_disassociate(struct iwl_priv *priv)
{
@@ -141,6 +141,7 @@ int iwl_led_disassociate(struct iwl_priv *priv)
return 0;
}
+EXPORT_SYMBOL(iwl_led_disassociate);
/*
* calculate blink rate according to last second Tx/Rx activities
@@ -221,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv)
priv->last_blink_rate = 0;
priv->last_blink_time = 0;
priv->allow_blinking = 0;
+ if (led_mode != IWL_LED_DEFAULT &&
+ led_mode != priv->cfg->led_mode)
+ priv->cfg->led_mode = led_mode;
}
EXPORT_SYMBOL(iwl_leds_init);
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 49a70baa3fb6..9079b33486ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -47,14 +47,16 @@ enum led_type {
/*
* LED mode
- * IWL_LED_BLINK: adjust led blink rate based on blink table
+ * IWL_LED_DEFAULT: use system default
* IWL_LED_RF_STATE: turn LED on/off based on RF state
* LED ON = RF ON
* LED OFF = RF OFF
+ * IWL_LED_BLINK: adjust led blink rate based on blink table
*/
enum iwl_led_mode {
- IWL_LED_BLINK,
+ IWL_LED_DEFAULT,
IWL_LED_RF_STATE,
+ IWL_LED_BLINK,
};
void iwl_leds_init(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
new file mode 100644
index 000000000000..a08b4e56e6b1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -0,0 +1,662 @@
+/******************************************************************************
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-helpers.h"
+#include "iwl-legacy.h"
+
+static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
+
+ iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
+ sizeof(struct iwl_qosparam_cmd),
+ &ctx->qos_data.def_qos_parm, NULL);
+}
+
+/**
+ * iwl_legacy_mac_config - mac80211 config callback
+ */
+int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct iwl_rxon_context *ctx;
+ unsigned long flags = 0;
+ int ret = 0;
+ u16 ch;
+ int scan_active = 0;
+ bool ht_changed[NUM_IWL_RXON_CTX] = {};
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+ channel->hw_value, changed);
+
+ if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+ test_bit(STATUS_SCANNING, &priv->status))) {
+ scan_active = 1;
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ /* mac80211 uses static for non-HT which is what we want */
+ priv->current_ht_config.smps = conf->smps_mode;
+
+ /*
+ * Recalculate chain counts.
+ *
+ * If monitor mode is enabled then mac80211 will
+ * set up the SM PS mode to OFF if an HT channel is
+ * configured.
+ */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ /* during scanning mac80211 will delay channel setting until
+ * scan finish with changed = 0
+ */
+ if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ if (scan_active)
+ goto set_ch_out;
+
+ ch = channel->hw_value;
+ ch_info = iwl_get_channel_info(priv, channel->band, ch);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ if (ctx->ht.enabled != conf_is_ht(conf)) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ ht_changed[ctx->ctxid] = true;
+ }
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
+
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
+
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, ht_conf);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (priv->cfg->ops->legacy->update_bcast_stations)
+ ret = priv->cfg->ops->legacy->update_bcast_stations(priv);
+
+ set_ch_out:
+ /* The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_PS |
+ IEEE80211_CONF_CHANGE_IDLE)) {
+ ret = iwl_power_update_mode(priv, false);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (scan_active)
+ goto out;
+
+ for_each_context(priv, ctx) {
+ if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
+ iwlcore_commit_rxon(priv, ctx);
+ else
+ IWL_DEBUG_INFO(priv,
+ "Not re-sending same RXON configuration.\n");
+ if (ht_changed[ctx->ctxid])
+ iwl_update_qos(priv, ctx);
+ }
+
+out:
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ mutex_unlock(&priv->mutex);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_legacy_mac_config);
+
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ /* IBSS can only be the IWL_RXON_CTX_BSS context */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return;
+
+ mutex_lock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* new association get rid of ibss beacon skb */
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
+
+ priv->beacon_skb = NULL;
+
+ priv->timestamp = 0;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_scan_cancel_timeout(priv, 100);
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* we are restarting association process
+ * clear RXON_FILTER_ASSOC_MSK bit
+ */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ iwl_set_rate(priv);
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf);
+
+static void iwl_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct ieee80211_sta *sta;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ IWL_DEBUG_ASSOC(priv, "enter:\n");
+
+ if (!ctx->ht.enabled)
+ return;
+
+ ctx->ht.protection =
+ bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+ ctx->ht.non_gf_sta_present =
+ !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+ ht_conf->single_chain_sufficient = false;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (sta) {
+ struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+ int maxstreams;
+
+ maxstreams = (ht_cap->mcs.tx_params &
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+ maxstreams += 1;
+
+ if ((ht_cap->mcs.rx_mask[1] == 0) &&
+ (ht_cap->mcs.rx_mask[2] == 0))
+ ht_conf->single_chain_sufficient = true;
+ if (maxstreams <= 1)
+ ht_conf->single_chain_sufficient = true;
+ } else {
+ /*
+ * If at all, this can only happen through a race
+ * when the AP disconnects us while we're still
+ * setting up the connection, in that case mac80211
+ * will soon tell us about that.
+ */
+ ht_conf->single_chain_sufficient = true;
+ }
+ rcu_read_unlock();
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ht_conf->single_chain_sufficient = true;
+ break;
+ default:
+ break;
+ }
+
+ IWL_DEBUG_ASSOC(priv, "leave\n");
+}
+
+static inline void iwl_set_no_assoc(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ iwl_led_disassociate(priv);
+ /*
+ * inform the ucode that there is no longer an
+ * association and that no more packets should be
+ * sent
+ */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ctx->staging.assoc_id = 0;
+ iwlcore_commit_rxon(priv, ctx);
+}
+
+static void iwlcore_beacon_update(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ __le64 timestamp;
+ struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
+
+ if (!skb)
+ return;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "update beacon but no beacon context!\n");
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
+
+ priv->beacon_skb = skb;
+
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return;
+ }
+
+ priv->cfg->ops->legacy->post_associate(priv);
+}
+
+void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ int ret;
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return;
+
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
+
+ if (!iwl_is_alive(priv))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ if (changes & BSS_CHANGED_QOS) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwl_update_qos(priv, ctx);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ /*
+ * the add_interface code must make sure we only ever
+ * have a single interface that could be beaconing at
+ * any time.
+ */
+ if (vif->bss_conf.enable_beacon)
+ priv->beacon_ctx = ctx;
+ else
+ priv->beacon_ctx = NULL;
+ }
+
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = ieee80211_beacon_get(hw, vif);
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
+ iwl_send_rxon_timing(priv, ctx);
+
+ if (changes & BSS_CHANGED_BSSID) {
+ IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
+
+ /*
+ * If there is currently a HW scan going on in the
+ * background then we need to cancel it else the RXON
+ * below/in post_associate will fail.
+ */
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* mac80211 only sets assoc when in STATION mode */
+ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
+ memcpy(ctx->staging.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+
+ /* currently needed in a few places */
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+ } else {
+ ctx->staging.filter_flags &=
+ ~RXON_FILTER_ASSOC_MSK;
+ }
+
+ }
+
+ /*
+ * This needs to be after setting the BSSID in case
+ * mac80211 decides to do both changes at once because
+ * it will invoke post_associate.
+ */
+ if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
+ iwlcore_beacon_update(hw, vif);
+
+ if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
+ if (bss_conf->use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ if (bss_conf->use_cts_prot)
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+ }
+
+ if (changes & BSS_CHANGED_BASIC_RATES) {
+ /* XXX use this information
+ *
+ * To do that, remove code from iwl_set_rate() and put something
+ * like this here:
+ *
+ if (A-band)
+ ctx->staging.ofdm_basic_rates =
+ bss_conf->basic_rates;
+ else
+ ctx->staging.ofdm_basic_rates =
+ bss_conf->basic_rates >> 4;
+ ctx->staging.cck_basic_rates =
+ bss_conf->basic_rates & 0xF;
+ */
+ }
+
+ if (changes & BSS_CHANGED_HT) {
+ iwl_ht_conf(priv, vif);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
+ if (bss_conf->assoc) {
+ priv->timestamp = bss_conf->timestamp;
+
+ iwl_led_associate(priv);
+
+ if (!iwl_is_rfkill(priv))
+ priv->cfg->ops->legacy->post_associate(priv);
+ } else
+ iwl_set_no_assoc(priv, vif);
+ }
+
+ if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
+ IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
+ changes);
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (!ret) {
+ /* Sync active_rxon with latest change. */
+ memcpy((void *)&ctx->active,
+ &ctx->staging,
+ sizeof(struct iwl_rxon_cmd));
+ }
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ if (vif->bss_conf.enable_beacon) {
+ memcpy(ctx->staging.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+ iwl_led_associate(priv);
+ priv->cfg->ops->legacy->config_ap(priv);
+ } else
+ iwl_set_no_assoc(priv, vif);
+ }
+
+ if (changes & BSS_CHANGED_IBSS) {
+ ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif,
+ bss_conf->ibss_joined);
+ if (ret)
+ IWL_ERR(priv, "failed to %s IBSS station %pM\n",
+ bss_conf->ibss_joined ? "add" : "remove",
+ bss_conf->bssid);
+ }
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed);
+
+irqreturn_t iwl_isr_legacy(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+ u32 inta_fh;
+ unsigned long flags;
+ if (!priv)
+ return IRQ_NONE;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Disable (but don't clear!) interrupts here to avoid
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here. */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+ /* Discover which interrupts are active/pending */
+ inta = iwl_read32(priv, CSR_INT);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!inta && !inta_fh) {
+ IWL_DEBUG_ISR(priv,
+ "Ignore interrupt, inta == 0, inta_fh == 0\n");
+ goto none;
+ }
+
+ if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+ /* Hardware disappeared. It might have already raised
+ * an interrupt */
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ goto unplugged;
+ }
+
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta, inta_mask, inta_fh);
+
+ inta &= ~CSR_INT_BIT_SCD;
+
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
+
+unplugged:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return IRQ_HANDLED;
+
+none:
+ /* re-enable interrupts here since we don't have anything to service. */
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl_enable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr_legacy);
+
+/*
+ * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
+ * function.
+ */
+void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ __le16 fc, __le32 *tx_flags)
+{
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ *tx_flags |= TX_CMD_FLG_RTS_MSK;
+ *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
+ *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+
+ if (!ieee80211_is_mgmt(fc))
+ return;
+
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+ *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ *tx_flags |= TX_CMD_FLG_CTS_MSK;
+ break;
+ }
+ } else if (info->control.rates[0].flags &
+ IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ *tx_flags |= TX_CMD_FLG_CTS_MSK;
+ *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+ }
+}
+EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h
new file mode 100644
index 000000000000..9f7b2f935964
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED 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.
+ *****************************************************************************/
+
+#ifndef __iwl_legacy_h__
+#define __iwl_legacy_h__
+
+/* mac80211 handlers */
+int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw);
+void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
+void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ __le16 fc, __le32 *tx_flags);
+
+irqreturn_t iwl_isr_legacy(int irq, void *data);
+
+#endif /* __iwl_legacy_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 49d7788937a9..1eec18d909d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -75,6 +75,10 @@ struct iwl_power_vec_entry {
#define NOSLP cpu_to_le16(0), 0, 0
#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define ASLP (IWL_POWER_POWER_SAVE_ENA_MSK | \
+ IWL_POWER_POWER_MANAGEMENT_ENA_MSK | \
+ IWL_POWER_ADVANCE_PM_ENA_MSK)
+#define ASLP_TOUT(T) cpu_to_le32(T)
#define TU_TO_USEC 1024
#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
@@ -114,6 +118,52 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
};
+/* advance power management */
+/* DTIM 0 - 2 */
+static const struct iwl_power_vec_entry apm_range_0[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2}
+};
+
+
+/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
+/* DTIM 3 - 10 */
+static const struct iwl_power_vec_entry apm_range_1[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), 0}, 2}
+};
+
+/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
+/* DTIM 11 - */
+static const struct iwl_power_vec_entry apm_range_2[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2}
+};
+
static void iwl_static_sleep_cmd(struct iwl_priv *priv,
struct iwl_powertable_cmd *cmd,
enum iwl_power_level lvl, int period)
@@ -124,11 +174,19 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
u8 skip;
u32 slp_itrvl;
- table = range_2;
- if (period <= IWL_DTIM_RANGE_1_MAX)
- table = range_1;
- if (period <= IWL_DTIM_RANGE_0_MAX)
- table = range_0;
+ if (priv->cfg->adv_pm) {
+ table = apm_range_2;
+ if (period <= IWL_DTIM_RANGE_1_MAX)
+ table = apm_range_1;
+ if (period <= IWL_DTIM_RANGE_0_MAX)
+ table = apm_range_0;
+ } else {
+ table = range_2;
+ if (period <= IWL_DTIM_RANGE_1_MAX)
+ table = range_1;
+ if (period <= IWL_DTIM_RANGE_0_MAX)
+ table = range_0;
+ }
BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
@@ -163,6 +221,20 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
else
cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ if (priv->cfg->base_params->shadow_reg_enable)
+ cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ if (!priv->cfg->bt_params->bt_sco_disable)
+ cmd->flags |= IWL_POWER_BT_SCO_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
+ }
+
+
slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]);
if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL)
cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] =
@@ -236,6 +308,19 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
if (priv->power_data.pci_pm)
cmd->flags |= IWL_POWER_PCI_PM_MSK;
+ if (priv->cfg->base_params->shadow_reg_enable)
+ cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ if (!priv->cfg->bt_params->bt_sco_disable)
+ cmd->flags |= IWL_POWER_BT_SCO_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
+ }
+
cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
@@ -263,70 +348,95 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
sizeof(struct iwl_powertable_cmd), cmd);
}
-/* priv->mutex must be held */
-int iwl_power_update_mode(struct iwl_priv *priv, bool force)
+static void iwl_power_build_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd)
{
- int ret = 0;
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
- bool update_chains;
- struct iwl_powertable_cmd cmd;
int dtimper;
- /* Don't update the RX chain when chain noise calibration is running */
- update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
- priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
-
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
if (priv->cfg->base_params->broken_powersave)
- iwl_power_sleep_cam_cmd(priv, &cmd);
+ iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->cfg->base_params->supports_idle &&
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
- iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
+ iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
priv->cfg->ops->lib->tt_ops.tt_power_mode &&
priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
/* in thermal throttling low power state */
- iwl_static_sleep_cmd(priv, &cmd,
+ iwl_static_sleep_cmd(priv, cmd,
priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
} else if (!enabled)
- iwl_power_sleep_cam_cmd(priv, &cmd);
+ iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
- iwl_static_sleep_cmd(priv, &cmd,
+ iwl_static_sleep_cmd(priv, cmd,
priv->power_data.debug_sleep_level_override,
dtimper);
else if (no_sleep_autoadjust)
- iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper);
+ iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper);
else
- iwl_power_fill_sleep_cmd(priv, &cmd,
+ iwl_power_fill_sleep_cmd(priv, cmd,
priv->hw->conf.dynamic_ps_timeout,
priv->hw->conf.max_sleep_period);
+}
+
+int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
+ bool force)
+{
+ int ret;
+ bool update_chains;
+
+ lockdep_assert_held(&priv->mutex);
+
+ /* Don't update the RX chain when chain noise calibration is running */
+ update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
+ priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
+
+ if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force)
+ return 0;
+
+ if (!iwl_is_ready_rf(priv))
+ return -EIO;
- if (iwl_is_ready_rf(priv) &&
- (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) {
- if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
- set_bit(STATUS_POWER_PMI, &priv->status);
-
- ret = iwl_set_power(priv, &cmd);
- if (!ret) {
- if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
- clear_bit(STATUS_POWER_PMI, &priv->status);
-
- if (priv->cfg->ops->lib->update_chain_flags &&
- update_chains)
- priv->cfg->ops->lib->update_chain_flags(priv);
- else if (priv->cfg->ops->lib->update_chain_flags)
- IWL_DEBUG_POWER(priv,
+ /* scan complete use sleep_power_next, need to be updated */
+ memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd));
+ if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
+ IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n");
+ return 0;
+ }
+
+ if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
+ set_bit(STATUS_POWER_PMI, &priv->status);
+
+ ret = iwl_set_power(priv, cmd);
+ if (!ret) {
+ if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
+ clear_bit(STATUS_POWER_PMI, &priv->status);
+
+ if (priv->cfg->ops->lib->update_chain_flags && update_chains)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+ else if (priv->cfg->ops->lib->update_chain_flags)
+ IWL_DEBUG_POWER(priv,
"Cannot update the power, chain noise "
"calibration running: %d\n",
priv->chain_noise_data.state);
- memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd));
- } else
- IWL_ERR(priv, "set power fail, ret = %d", ret);
- }
+
+ memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd));
+ } else
+ IWL_ERR(priv, "set power fail, ret = %d", ret);
return ret;
}
+EXPORT_SYMBOL(iwl_power_set_mode);
+
+int iwl_power_update_mode(struct iwl_priv *priv, bool force)
+{
+ struct iwl_powertable_cmd cmd;
+
+ iwl_power_build_cmd(priv, &cmd);
+ return iwl_power_set_mode(priv, &cmd, force);
+}
EXPORT_SYMBOL(iwl_power_update_mode);
/* initialize to default */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index df81565a7cc4..fe012032c28c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -41,10 +41,13 @@ enum iwl_power_level {
struct iwl_power_mgr {
struct iwl_powertable_cmd sleep_cmd;
+ struct iwl_powertable_cmd sleep_cmd_next;
int debug_sleep_level_override;
bool pci_pm;
};
+int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
+ bool force);
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
void iwl_power_initialize(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 5469655646ae..86f5123bccda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -83,10 +83,10 @@
#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058)
#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C)
+#define APMS_CLK_VAL_MRB_FUNC_MODE (0x00000001)
#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
-
#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000)
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index f436270ca39a..87a6fd84d4d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -134,28 +134,37 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
if (q->need_update == 0)
goto exit_unlock;
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* shadow register enabled */
+ /* Device expects a multiple of 8 */
+ q->write_actual = (q->write & ~0x7);
+ iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual);
+ } else {
+ /* If power-saving is in use, make sure device is awake */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n",
- reg);
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO(priv,
+ "Rx queue requesting wakeup,"
+ " GP1 = 0x%x\n", reg);
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ goto exit_unlock;
+ }
- q->write_actual = (q->write & ~0x7);
- iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg,
+ q->write_actual);
- /* Else device is assumed to be awake */
- } else {
- /* Device expects a multiple of 8 */
- q->write_actual = (q->write & ~0x7);
- iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
+ /* Else device is assumed to be awake */
+ } else {
+ /* Device expects a multiple of 8 */
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg,
+ q->write_actual);
+ }
}
-
q->need_update = 0;
exit_unlock:
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 67da31295781..12d9363d0afe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -252,8 +252,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_start, jiffies)));
+ jiffies_to_msecs(jiffies - priv->scan_start));
queue_work(priv->workqueue, &priv->scan_completed);
@@ -603,13 +602,16 @@ out_settings:
if (!iwl_is_ready_rf(priv))
goto out;
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ /*
+ * We do not commit power settings while scan is pending,
+ * do it now if the settings changed.
+ */
+ iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
+ iwl_set_tx_power(priv, priv->tx_power_next, false);
priv->cfg->ops->utils->post_scan(priv);
- out:
+out:
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7c7f7dcb1b1e..4776323b1eba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
}
static int iwl_send_remove_station(struct iwl_priv *priv,
- const u8 *addr, int sta_id)
+ const u8 *addr, int sta_id,
+ bool temporary)
{
struct iwl_rx_packet *pkt;
int ret;
@@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
if (!ret) {
switch (pkt->u.rem_sta.status) {
case REM_STA_SUCCESS_MSK:
- spin_lock_irqsave(&priv->sta_lock, flags_spin);
- iwl_sta_ucode_deactivate(priv, sta_id);
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ if (!temporary) {
+ spin_lock_irqsave(&priv->sta_lock, flags_spin);
+ iwl_sta_ucode_deactivate(priv, sta_id);
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ }
IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
break;
default:
@@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
spin_unlock_irqrestore(&priv->sta_lock, flags);
- return iwl_send_remove_station(priv, addr, sta_id);
+ return iwl_send_remove_station(priv, addr, sta_id, false);
out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags);
return -EINVAL;
@@ -624,6 +627,49 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
}
EXPORT_SYMBOL(iwl_restore_stations);
+void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ unsigned long flags;
+ int sta_id = ctx->ap_sta_id;
+ int ret;
+ struct iwl_addsta_cmd sta_cmd;
+ struct iwl_link_quality_cmd lq;
+ bool active;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return;
+ }
+
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
+ sta_cmd.mode = 0;
+ memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
+
+ active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
+ priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ if (active) {
+ ret = iwl_send_remove_station(
+ priv, priv->stations[sta_id].sta.sta.addr,
+ sta_id, true);
+ if (ret)
+ IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
+ priv->stations[sta_id].sta.sta.addr, ret);
+ }
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+ if (ret)
+ IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
+ priv->stations[sta_id].sta.sta.addr, ret);
+ iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
+}
+EXPORT_SYMBOL(iwl_reprogram_ap_sta);
+
int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
@@ -736,6 +782,14 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
return -EINVAL;
+
+ spin_lock_irqsave(&priv->sta_lock, flags_spin);
+ if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+
iwl_dump_lq_cmd(priv, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 06475872eee4..206f1e1a0caf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init);
+void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
/**
* iwl_clear_driver_stations - clear knowledge of all stations from driver
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7261ee49f282..073b6ce6141c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -49,30 +49,39 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
if (txq->need_update == 0)
return;
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
- txq_id, reg);
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return;
- }
-
- iwl_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* shadow register enabled */
iwl_write32(priv, HBUS_TARG_WRPTR,
txq->q.write_ptr | (txq_id << 8));
+ } else {
+ /* if we're trying to save power */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ /* wake up nic if it's powered down ...
+ * uCode will wake up, and interrupt us again, so next
+ * time we'll skip this part. */
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO(priv,
+ "Tx queue %d requesting wakeup,"
+ " GP1 = 0x%x\n", txq_id, reg);
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ return;
+ }
+
+ iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+ /*
+ * else not in power-save mode,
+ * uCode will never sleep when we're
+ * trying to tx (during RFKILL, we're not trying to tx).
+ */
+ } else
+ iwl_write32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+ }
txq->need_update = 0;
}
EXPORT_SYMBOL(iwl_txq_update_write_ptr);
@@ -254,8 +263,6 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
q->high_mark = 2;
q->write_ptr = q->read_ptr = 0;
- q->last_read_ptr = 0;
- q->repeat_same_read_ptr = 0;
return 0;
}
@@ -350,13 +357,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
txq->need_update = 0;
/*
- * Aggregation TX queues will get their ID when aggregation begins;
- * they overwrite the setting done here. The command FIFO doesn't
- * need an swq_id so don't set one to catch errors, all others can
- * be set up to the identity mapping.
+ * For the default queues 0-3, set up the swq_id
+ * already -- all others need to get one later
+ * (if they need one at all).
*/
- if (txq_id != priv->cmd_queue)
- txq->swq_id = txq_id;
+ if (txq_id < 4)
+ iwl_set_swq_id(txq, txq_id, txq_id);
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
* iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 7edf8c2fb8c7..371abbf60eac 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -61,6 +61,7 @@
#include "iwl-helpers.h"
#include "iwl-dev.h"
#include "iwl-spectrum.h"
+#include "iwl-legacy.h"
/*
* module name, copyright, version, etc.
@@ -474,7 +475,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
int txq_id = skb_get_queue_mapping(skb);
- u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
+ u16 len, idx, hdr_len;
u8 id;
u8 unicast;
u8 sta_id;
@@ -611,15 +612,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
*/
len = sizeof(struct iwl3945_tx_cmd) +
sizeof(struct iwl_cmd_header) + hdr_len;
-
- len_org = len;
len = (len + 3) & ~3;
- if (len_org != len)
- len_org = 1;
- else
- len_org = 0;
-
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
@@ -661,7 +655,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->lock, flags);
}
- iwl_stop_queue(priv, skb_get_queue_mapping(skb));
+ iwl_stop_queue(priv, txq);
}
return 0;
@@ -2515,13 +2509,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- /* Enable timer to monitor the driver queues */
- mod_timer(&priv->monitor_recover,
- jiffies +
- msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+ /* Enable watchdog to monitor the driver tx queues */
+ iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
return;
@@ -2578,8 +2567,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
* to prevent rearm timer */
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+ del_timer_sync(&priv->watchdog);
/* Station information will now be cleared in device */
iwl_clear_ucode_stations(priv, NULL);
@@ -3057,22 +3045,22 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (!vif || !priv->is_open)
+ if (!ctx->vif || !priv->is_open)
return;
- if (vif->type == NL80211_IFTYPE_AP) {
+ if (ctx->vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, ctx->active.bssid_addr);
+ ctx->vif->bss_conf.aid, ctx->active.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -3091,18 +3079,18 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- vif->bss_conf.aid, vif->bss_conf.beacon_int);
+ ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int);
- if (vif->bss_conf.use_short_preamble)
+ if (ctx->vif->bss_conf.use_short_preamble)
ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
+ if (ctx->vif->bss_conf.use_short_slot)
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
@@ -3110,7 +3098,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
iwl3945_commit_rxon(priv, ctx);
- switch (vif->type) {
+ switch (ctx->vif->type) {
case NL80211_IFTYPE_STATION:
iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
break;
@@ -3119,7 +3107,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
break;
default:
IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, vif->type);
+ __func__, ctx->vif->type);
break;
}
}
@@ -3234,9 +3222,10 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
+void iwl3945_config_ap(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
int rc = 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -3407,9 +3396,9 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
ctx->staging.filter_flags |= filter_or;
/*
- * Committing directly here breaks for some reason,
- * but we'll eventually commit the filter flags
- * change anyway.
+ * Not committing directly because hardware can perform a scan,
+ * but even if hw is ready, committing here breaks for some reason,
+ * we'll eventually commit the filter flags change anyway.
*/
mutex_unlock(&priv->mutex);
@@ -3780,12 +3769,9 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
iwl3945_hw_setup_deferred_work(priv);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- init_timer(&priv->monitor_recover);
- priv->monitor_recover.data = (unsigned long)priv;
- priv->monitor_recover.function =
- priv->cfg->ops->lib->recover_from_tx_stall;
- }
+ init_timer(&priv->watchdog);
+ priv->watchdog.data = (unsigned long)priv;
+ priv->watchdog.function = iwl_bg_watchdog;
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
iwl3945_irq_tasklet, (unsigned long)priv);
@@ -3824,18 +3810,19 @@ static struct attribute_group iwl3945_attribute_group = {
.attrs = iwl3945_sysfs_entries,
};
-static struct ieee80211_ops iwl3945_hw_ops = {
+struct ieee80211_ops iwl3945_hw_ops = {
.tx = iwl3945_mac_tx,
.start = iwl3945_mac_start,
.stop = iwl3945_mac_stop,
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
- .config = iwl_mac_config,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwl_legacy_mac_config,
.configure_filter = iwl3945_configure_filter,
.set_key = iwl3945_mac_set_key,
.conf_tx = iwl_mac_conf_tx,
- .reset_tsf = iwl_mac_reset_tsf,
- .bss_info_changed = iwl_bss_info_changed,
+ .reset_tsf = iwl_legacy_mac_reset_tsf,
+ .bss_info_changed = iwl_legacy_mac_bss_info_changed,
.hw_scan = iwl_mac_hw_scan,
.sta_add = iwl3945_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
@@ -3865,7 +3852,15 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->iw_mode = NL80211_IFTYPE_STATION;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
+ /* initialize force reset */
+ priv->force_reset[IWL_RF_RESET].reset_duration =
+ IWL_DELAY_NEXT_FORCE_RF_RESET;
+ priv->force_reset[IWL_FW_RESET].reset_duration =
+ IWL_DELAY_NEXT_FORCE_FW_RELOAD;
+
+
priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+ priv->tx_power_next = IWL_DEFAULT_TX_POWER;
if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
@@ -3965,7 +3960,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
- hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+ hw = iwl_alloc_all(cfg);
if (hw == NULL) {
pr_err("Can not allocate network device\n");
err = -ENOMEM;
@@ -4117,7 +4112,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_enable_msi(priv->pci_dev);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4275,10 +4270,7 @@ static struct pci_driver iwl3945_driver = {
.id_table = iwl3945_hw_card_ids,
.probe = iwl3945_pci_probe,
.remove = __devexit_p(iwl3945_pci_remove),
-#ifdef CONFIG_PM
- .suspend = iwl_pci_suspend,
- .resume = iwl_pci_resume,
-#endif
+ .driver.pm = IWL_PM_OPS,
};
static int __init iwl3945_init(void)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index c6c0eff9b5ed..5a4982271e96 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *ndev,
- u8 key_index)
+ u8 key_index, bool unicast,
+ bool multicast)
{
struct iwm_priv *iwm = ndev_to_iwm(ndev);
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 330c7d9cf101..50dee6a0a5ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -908,7 +908,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
return ret;
}
- iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX;
+ iwm->scan_id = (iwm->scan_id + 1) % IWM_SCAN_ID_MAX;
return 0;
}
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 373930afc26b..698a1f7694ed 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -9,8 +9,6 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <asm/unaligned.h>
@@ -619,7 +617,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
print_ssid(ssid_buf, ssid, ssid_len),
LBS_SCAN_RSSI_TO_MBM(rssi)/100);
- if (channel ||
+ if (channel &&
!(channel->flags & IEEE80211_CHAN_DISABLED))
cfg80211_inform_bss(wiphy, channel,
bssid, le64_to_cpu(*(__le64 *)tsfdesc),
@@ -1424,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
static int lbs_cfg_set_default_key(struct wiphy *wiphy,
struct net_device *netdev,
- u8 key_index)
+ u8 key_index, bool unicast,
+ bool multicast)
{
struct lbs_private *priv = wiphy_priv(wiphy);
@@ -2062,7 +2061,7 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
};
/* Section 5.17.2 */
- static struct region_code_mapping regmap[] = {
+ static const struct region_code_mapping regmap[] = {
{"US ", 0x10}, /* US FCC */
{"CA ", 0x20}, /* Canada */
{"EU ", 0x30}, /* ETSI */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 70745928f3f8..78c4da150a74 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
struct cmd_ds_host_sleep cmd_config;
int ret;
+ /*
+ * Certain firmware versions do not support EHS_REMOVE_WAKEUP command
+ * and the card will return a failure. Since we need to be
+ * able to reset the mask, in those cases we set a 0 mask instead.
+ */
+ if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
+ criteria = 0;
+
cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
cmd_config.criteria = cpu_to_le32(criteria);
cmd_config.gpio = priv->wol_gpio;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index cb14c38caf3a..18dd9a02c459 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -138,6 +138,7 @@ struct lbs_private {
uint32_t wol_criteria;
uint8_t wol_gpio;
uint8_t wol_gap;
+ bool ehs_remove_supported;
/* Transmitting */
int tx_pending_len; /* -1 while building packet */
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index e5685dc317a8..b4de0ca10feb 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_deb_sdio("call remove card\n");
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- card->priv->surpriseremoved = 1;
flush_workqueue(card->workqueue);
destroy_workqueue(card->workqueue);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 79bcb4e5d2ca..00600239a053 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -784,7 +784,7 @@ static int lbs_spi_thread(void *data)
up(&card->spi_thread_terminated);
do_exit(0);
}
- } while (err == EINTR);
+ } while (err == -EINTR);
/* Read the host interrupt status register to see what we
* can do. */
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
lbs_stop_card(priv);
lbs_remove_card(priv); /* will call free_netdev */
- priv->surpriseremoved = 1;
free_irq(spi->irq, card);
if_spi_terminate_spi_thread(card);
if (card->pdata->teardown)
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index efaf85032208..6524c70363d9 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -345,6 +345,13 @@ static int if_usb_probe(struct usb_interface *intf,
if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
+ /*
+ * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
+ */
+ priv->wol_criteria = EHS_REMOVE_WAKEUP;
+ if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
+ priv->ehs_remove_supported = false;
+
return 0;
err_start_card:
@@ -1090,12 +1097,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (priv->psstate != PS_STATE_FULL_POWER)
return -1;
- if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- lbs_pr_info("Suspend attempt without "
- "configuring wake params!\n");
- return -ENOSYS;
- }
-
ret = lbs_suspend(priv);
if (ret)
goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 46b88b118c99..6836a6dd9853 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -851,9 +851,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->work_thread = create_singlethread_workqueue("lbs_worker");
INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
- priv->wol_criteria = 0xffffffff;
+ priv->wol_criteria = EHS_REMOVE_WAKEUP;
priv->wol_gpio = 0xff;
priv->wol_gap = 20;
+ priv->ehs_remove_supported = true;
goto done;
@@ -915,8 +916,6 @@ void lbs_remove_card(struct lbs_private *priv)
lbs_free_adapter(priv);
lbs_cfg_free(priv);
-
- priv->dev = NULL;
free_netdev(dev);
lbs_deb_leave(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index a4d0bca9ef2c..a2b1df21d286 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -55,7 +55,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
struct rxpd *p_rx_pd;
int hdrchop;
struct ethhdr *p_ethhdr;
- const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+ static const u8 rfc1042_eth_hdr[] = {
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
+ };
lbs_deb_enter(LBS_DEB_RX);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7eaaa3bab547..454f045ddff3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -309,6 +309,8 @@ struct mac80211_hwsim_data {
*/
u64 group;
struct dentry *debugfs_group;
+
+ int power_level;
};
@@ -497,7 +499,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
rx_status.band = data->channel->band;
rx_status.rate_idx = info->control.rates[0].idx;
/* TODO: simulate real signal strength (and optional packet loss) */
- rx_status.signal = -50;
+ rx_status.signal = data->power_level - 50;
if (data->ps != PS_DISABLED)
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -698,6 +700,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
data->channel = conf->channel;
+ data->power_level = conf->power_level;
if (!data->started || !data->beacon_int)
del_timer(&data->beacon_timer);
else
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index f152a25be59f..9ecf8407cb1b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -29,6 +29,12 @@
#define MWL8K_NAME KBUILD_MODNAME
#define MWL8K_VERSION "0.12"
+/* Module parameters */
+static unsigned ap_mode_default;
+module_param(ap_mode_default, bool, 0);
+MODULE_PARM_DESC(ap_mode_default,
+ "Set to 1 to make ap mode the default instead of sta mode");
+
/* Register definitions */
#define MWL8K_HIU_GEN_PTR 0x00000c10
#define MWL8K_MODE_STA 0x0000005a
@@ -92,8 +98,10 @@ struct rxd_ops {
struct mwl8k_device_info {
char *part_name;
char *helper_image;
- char *fw_image;
+ char *fw_image_sta;
+ char *fw_image_ap;
struct rxd_ops *ap_rxd_ops;
+ u32 fw_api_ap;
};
struct mwl8k_rx_queue {
@@ -136,8 +144,8 @@ struct mwl8k_priv {
void __iomem *regs;
/* firmware */
- struct firmware *fw_helper;
- struct firmware *fw_ucode;
+ const struct firmware *fw_helper;
+ const struct firmware *fw_ucode;
/* hardware/firmware parameters */
bool ap_fw;
@@ -210,6 +218,18 @@ struct mwl8k_priv {
/* Most recently reported noise in dBm */
s8 noise;
+
+ /*
+ * preserve the queue configurations so they can be restored if/when
+ * the firmware image is swapped.
+ */
+ struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES];
+
+ /* async firmware loading state */
+ unsigned fw_state;
+ char *fw_pref;
+ char *fw_alt;
+ struct completion firmware_loading_complete;
};
/* Per interface specific private data */
@@ -285,8 +305,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
};
/* Set or get info from Firmware */
-#define MWL8K_CMD_SET 0x0001
#define MWL8K_CMD_GET 0x0000
+#define MWL8K_CMD_SET 0x0001
+#define MWL8K_CMD_SET_LIST 0x0002
/* Firmware command codes */
#define MWL8K_CMD_CODE_DNLD 0x0001
@@ -296,6 +317,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
#define MWL8K_CMD_GET_STAT 0x0014
#define MWL8K_CMD_RADIO_CONTROL 0x001c
#define MWL8K_CMD_RF_TX_POWER 0x001e
+#define MWL8K_CMD_TX_POWER 0x001f
#define MWL8K_CMD_RF_ANTENNA 0x0020
#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
#define MWL8K_CMD_SET_PRE_SCAN 0x0107
@@ -333,6 +355,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
MWL8K_CMDNAME(GET_STAT);
MWL8K_CMDNAME(RADIO_CONTROL);
MWL8K_CMDNAME(RF_TX_POWER);
+ MWL8K_CMDNAME(TX_POWER);
MWL8K_CMDNAME(RF_ANTENNA);
MWL8K_CMDNAME(SET_BEACON);
MWL8K_CMDNAME(SET_PRE_SCAN);
@@ -372,7 +395,7 @@ static void mwl8k_hw_reset(struct mwl8k_priv *priv)
}
/* Release fw image */
-static void mwl8k_release_fw(struct firmware **fw)
+static void mwl8k_release_fw(const struct firmware **fw)
{
if (*fw == NULL)
return;
@@ -386,37 +409,68 @@ static void mwl8k_release_firmware(struct mwl8k_priv *priv)
mwl8k_release_fw(&priv->fw_helper);
}
+/* states for asynchronous f/w loading */
+static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
+enum {
+ FW_STATE_INIT = 0,
+ FW_STATE_LOADING_PREF,
+ FW_STATE_LOADING_ALT,
+ FW_STATE_ERROR,
+};
+
/* Request fw image */
static int mwl8k_request_fw(struct mwl8k_priv *priv,
- const char *fname, struct firmware **fw)
+ const char *fname, const struct firmware **fw,
+ bool nowait)
{
/* release current image */
if (*fw != NULL)
mwl8k_release_fw(fw);
- return request_firmware((const struct firmware **)fw,
- fname, &priv->pdev->dev);
+ if (nowait)
+ return request_firmware_nowait(THIS_MODULE, 1, fname,
+ &priv->pdev->dev, GFP_KERNEL,
+ priv, mwl8k_fw_state_machine);
+ else
+ return request_firmware(fw, fname, &priv->pdev->dev);
}
-static int mwl8k_request_firmware(struct mwl8k_priv *priv)
+static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
+ bool nowait)
{
struct mwl8k_device_info *di = priv->device_info;
int rc;
if (di->helper_image != NULL) {
- rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper);
- if (rc) {
- printk(KERN_ERR "%s: Error requesting helper "
- "firmware file %s\n", pci_name(priv->pdev),
- di->helper_image);
+ if (nowait)
+ rc = mwl8k_request_fw(priv, di->helper_image,
+ &priv->fw_helper, true);
+ else
+ rc = mwl8k_request_fw(priv, di->helper_image,
+ &priv->fw_helper, false);
+ if (rc)
+ printk(KERN_ERR "%s: Error requesting helper fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+
+ if (rc || nowait)
return rc;
- }
}
- rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode);
+ if (nowait) {
+ /*
+ * if we get here, no helper image is needed. Skip the
+ * FW_STATE_INIT state.
+ */
+ priv->fw_state = FW_STATE_LOADING_PREF;
+ rc = mwl8k_request_fw(priv, fw_image,
+ &priv->fw_ucode,
+ true);
+ } else
+ rc = mwl8k_request_fw(priv, fw_image,
+ &priv->fw_ucode, false);
if (rc) {
printk(KERN_ERR "%s: Error requesting firmware file %s\n",
- pci_name(priv->pdev), di->fw_image);
+ pci_name(priv->pdev), fw_image);
mwl8k_release_fw(&priv->fw_helper);
return rc;
}
@@ -577,12 +631,12 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
static int mwl8k_load_firmware(struct ieee80211_hw *hw)
{
struct mwl8k_priv *priv = hw->priv;
- struct firmware *fw = priv->fw_ucode;
+ const struct firmware *fw = priv->fw_ucode;
int rc;
int loops;
if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
- struct firmware *helper = priv->fw_helper;
+ const struct firmware *helper = priv->fw_helper;
if (helper == NULL) {
printk(KERN_ERR "%s: helper image needed but none "
@@ -1811,6 +1865,7 @@ struct mwl8k_cmd_get_hw_spec_ap {
__le32 wcbbase1;
__le32 wcbbase2;
__le32 wcbbase3;
+ __le32 fw_api_version;
} __packed;
static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
@@ -1818,6 +1873,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_cmd_get_hw_spec_ap *cmd;
int rc;
+ u32 api_version;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL)
@@ -1834,6 +1890,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
if (!rc) {
int off;
+ api_version = le32_to_cpu(cmd->fw_api_version);
+ if (priv->device_info->fw_api_ap != api_version) {
+ printk(KERN_ERR "%s: Unsupported fw API version for %s."
+ " Expected %d got %d.\n", MWL8K_NAME,
+ priv->device_info->part_name,
+ priv->device_info->fw_api_ap,
+ api_version);
+ rc = -EINVAL;
+ goto done;
+ }
SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
priv->fw_rev = le32_to_cpu(cmd->fw_rev);
@@ -1861,6 +1927,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
iowrite32(priv->txq[3].txd_dma, priv->sram + off);
}
+done:
kfree(cmd);
return rc;
}
@@ -2084,7 +2151,7 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
/*
* CMD_RF_TX_POWER.
*/
-#define MWL8K_TX_POWER_LEVEL_TOTAL 8
+#define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8
struct mwl8k_cmd_rf_tx_power {
struct mwl8k_cmd_pkt header;
@@ -2092,7 +2159,7 @@ struct mwl8k_cmd_rf_tx_power {
__le16 support_level;
__le16 current_level;
__le16 reserved;
- __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+ __le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL];
} __packed;
static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
@@ -2116,6 +2183,65 @@ static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
}
/*
+ * CMD_TX_POWER.
+ */
+#define MWL8K_TX_POWER_LEVEL_TOTAL 12
+
+struct mwl8k_cmd_tx_power {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 band;
+ __le16 channel;
+ __le16 bw;
+ __le16 sub_ch;
+ __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+} __attribute__((packed));
+
+static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
+ struct ieee80211_conf *conf,
+ unsigned short pwr)
+{
+ struct ieee80211_channel *channel = conf->channel;
+ struct mwl8k_cmd_tx_power *cmd;
+ int rc;
+ int i;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST);
+
+ if (channel->band == IEEE80211_BAND_2GHZ)
+ cmd->band = cpu_to_le16(0x1);
+ else if (channel->band == IEEE80211_BAND_5GHZ)
+ cmd->band = cpu_to_le16(0x4);
+
+ cmd->channel = channel->hw_value;
+
+ if (conf->channel_type == NL80211_CHAN_NO_HT ||
+ conf->channel_type == NL80211_CHAN_HT20) {
+ cmd->bw = cpu_to_le16(0x2);
+ } else {
+ cmd->bw = cpu_to_le16(0x4);
+ if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+ cmd->sub_ch = cpu_to_le16(0x3);
+ else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+ cmd->sub_ch = cpu_to_le16(0x1);
+ }
+
+ for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++)
+ cmd->power_level_list[i] = cpu_to_le16(pwr);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
* CMD_RF_ANTENNA.
*/
struct mwl8k_cmd_rf_antenna {
@@ -3283,13 +3409,16 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
}
+static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image);
+
static int mwl8k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_vif *mwl8k_vif;
u32 macids_supported;
- int macid;
+ int macid, rc;
+ struct mwl8k_device_info *di;
/*
* Reject interface creation if sniffer mode is active, as
@@ -3302,12 +3431,28 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
return -EINVAL;
}
-
+ di = priv->device_info;
switch (vif->type) {
case NL80211_IFTYPE_AP:
+ if (!priv->ap_fw && di->fw_image_ap) {
+ /* we must load the ap fw to meet this request */
+ if (!list_empty(&priv->vif_list))
+ return -EBUSY;
+ rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
+ if (rc)
+ return rc;
+ }
macids_supported = priv->ap_macids_supported;
break;
case NL80211_IFTYPE_STATION:
+ if (priv->ap_fw && di->fw_image_sta) {
+ /* we must load the sta fw to meet this request */
+ if (!list_empty(&priv->vif_list))
+ return -EBUSY;
+ rc = mwl8k_reload_firmware(hw, di->fw_image_sta);
+ if (rc)
+ return rc;
+ }
macids_supported = priv->sta_macids_supported;
break;
default:
@@ -3377,15 +3522,19 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
if (conf->power_level > 18)
conf->power_level = 18;
- rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
- if (rc)
- goto out;
if (priv->ap_fw) {
+ rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
+ if (rc)
+ goto out;
+
rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
if (!rc)
rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
} else {
+ rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
+ if (rc)
+ goto out;
rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
}
@@ -3739,6 +3888,9 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
rc = mwl8k_fw_lock(hw);
if (!rc) {
+ BUG_ON(queue > MWL8K_TX_QUEUES - 1);
+ memcpy(&priv->wmm_params[queue], params, sizeof(*params));
+
if (!priv->wmm_enabled)
rc = mwl8k_cmd_set_wmm_mode(hw, 1);
@@ -3838,21 +3990,27 @@ enum {
MWL8366,
};
+#define MWL8K_8366_AP_FW_API 1
+#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
+#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
+
static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
[MWL8363] = {
.part_name = "88w8363",
.helper_image = "mwl8k/helper_8363.fw",
- .fw_image = "mwl8k/fmimage_8363.fw",
+ .fw_image_sta = "mwl8k/fmimage_8363.fw",
},
[MWL8687] = {
.part_name = "88w8687",
.helper_image = "mwl8k/helper_8687.fw",
- .fw_image = "mwl8k/fmimage_8687.fw",
+ .fw_image_sta = "mwl8k/fmimage_8687.fw",
},
[MWL8366] = {
.part_name = "88w8366",
.helper_image = "mwl8k/helper_8366.fw",
- .fw_image = "mwl8k/fmimage_8366.fw",
+ .fw_image_sta = "mwl8k/fmimage_8366.fw",
+ .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
+ .fw_api_ap = MWL8K_8366_AP_FW_API,
.ap_rxd_ops = &rxd_8366_ap_ops,
},
};
@@ -3863,6 +4021,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
MODULE_FIRMWARE("mwl8k/helper_8366.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
+MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
@@ -3876,94 +4035,133 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
};
MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
-static int __devinit mwl8k_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int mwl8k_request_alt_fw(struct mwl8k_priv *priv)
{
- static int printed_version = 0;
- struct ieee80211_hw *hw;
- struct mwl8k_priv *priv;
int rc;
- int i;
-
- if (!printed_version) {
- printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
- printed_version = 1;
- }
-
-
- rc = pci_enable_device(pdev);
+ printk(KERN_ERR "%s: Error requesting preferred fw %s.\n"
+ "Trying alternative firmware %s\n", pci_name(priv->pdev),
+ priv->fw_pref, priv->fw_alt);
+ rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true);
if (rc) {
- printk(KERN_ERR "%s: Cannot enable new PCI device\n",
- MWL8K_NAME);
+ printk(KERN_ERR "%s: Error requesting alt fw %s\n",
+ pci_name(priv->pdev), priv->fw_alt);
return rc;
}
+ return 0;
+}
- rc = pci_request_regions(pdev, MWL8K_NAME);
- if (rc) {
- printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
- MWL8K_NAME);
- goto err_disable_device;
- }
-
- pci_set_master(pdev);
-
-
- hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
- if (hw == NULL) {
- printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
- rc = -ENOMEM;
- goto err_free_reg;
- }
+static int mwl8k_firmware_load_success(struct mwl8k_priv *priv);
+static void mwl8k_fw_state_machine(const struct firmware *fw, void *context)
+{
+ struct mwl8k_priv *priv = context;
+ struct mwl8k_device_info *di = priv->device_info;
+ int rc;
- SET_IEEE80211_DEV(hw, &pdev->dev);
- pci_set_drvdata(pdev, hw);
+ switch (priv->fw_state) {
+ case FW_STATE_INIT:
+ if (!fw) {
+ printk(KERN_ERR "%s: Error requesting helper fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+ goto fail;
+ }
+ priv->fw_helper = fw;
+ rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode,
+ true);
+ if (rc && priv->fw_alt) {
+ rc = mwl8k_request_alt_fw(priv);
+ if (rc)
+ goto fail;
+ priv->fw_state = FW_STATE_LOADING_ALT;
+ } else if (rc)
+ goto fail;
+ else
+ priv->fw_state = FW_STATE_LOADING_PREF;
+ break;
- priv = hw->priv;
- priv->hw = hw;
- priv->pdev = pdev;
- priv->device_info = &mwl8k_info_tbl[id->driver_data];
+ case FW_STATE_LOADING_PREF:
+ if (!fw) {
+ if (priv->fw_alt) {
+ rc = mwl8k_request_alt_fw(priv);
+ if (rc)
+ goto fail;
+ priv->fw_state = FW_STATE_LOADING_ALT;
+ } else
+ goto fail;
+ } else {
+ priv->fw_ucode = fw;
+ rc = mwl8k_firmware_load_success(priv);
+ if (rc)
+ goto fail;
+ else
+ complete(&priv->firmware_loading_complete);
+ }
+ break;
+ case FW_STATE_LOADING_ALT:
+ if (!fw) {
+ printk(KERN_ERR "%s: Error requesting alt fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+ goto fail;
+ }
+ priv->fw_ucode = fw;
+ rc = mwl8k_firmware_load_success(priv);
+ if (rc)
+ goto fail;
+ else
+ complete(&priv->firmware_loading_complete);
+ break;
- priv->sram = pci_iomap(pdev, 0, 0x10000);
- if (priv->sram == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
- goto err_iounmap;
+ default:
+ printk(KERN_ERR "%s: Unexpected firmware loading state: %d\n",
+ MWL8K_NAME, priv->fw_state);
+ BUG_ON(1);
}
- /*
- * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
- * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
- */
- priv->regs = pci_iomap(pdev, 1, 0x10000);
- if (priv->regs == NULL) {
- priv->regs = pci_iomap(pdev, 2, 0x10000);
- if (priv->regs == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device registers\n");
- goto err_iounmap;
- }
- }
+ return;
+fail:
+ priv->fw_state = FW_STATE_ERROR;
+ complete(&priv->firmware_loading_complete);
+ device_release_driver(&priv->pdev->dev);
+ mwl8k_release_firmware(priv);
+}
+
+static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
+ bool nowait)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
/* Reset firmware and hardware */
mwl8k_hw_reset(priv);
/* Ask userland hotplug daemon for the device firmware */
- rc = mwl8k_request_firmware(priv);
+ rc = mwl8k_request_firmware(priv, fw_image, nowait);
if (rc) {
wiphy_err(hw->wiphy, "Firmware files not found\n");
- goto err_stop_firmware;
+ return rc;
}
+ if (nowait)
+ return rc;
+
/* Load firmware into hardware */
rc = mwl8k_load_firmware(hw);
- if (rc) {
+ if (rc)
wiphy_err(hw->wiphy, "Cannot start firmware\n");
- goto err_stop_firmware;
- }
/* Reclaim memory once firmware is successfully loaded */
mwl8k_release_firmware(priv);
+ return rc;
+}
+
+/* initialize hw after successfully loading a firmware image */
+static int mwl8k_probe_hw(struct ieee80211_hw *hw)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+ int i;
if (priv->ap_fw) {
priv->rxd_ops = priv->device_info->ap_rxd_ops;
@@ -3980,58 +4178,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
priv->wmm_enabled = false;
priv->pending_tx_pkts = 0;
-
- /*
- * Extra headroom is the size of the required DMA header
- * minus the size of the smallest 802.11 frame (CTS frame).
- */
- hw->extra_tx_headroom =
- sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
-
- hw->channel_change_time = 10;
-
- hw->queues = MWL8K_TX_QUEUES;
-
- /* Set rssi values to dBm */
- hw->flags |= IEEE80211_HW_SIGNAL_DBM;
- hw->vif_data_size = sizeof(struct mwl8k_vif);
- hw->sta_data_size = sizeof(struct mwl8k_sta);
-
- priv->macids_used = 0;
- INIT_LIST_HEAD(&priv->vif_list);
-
- /* Set default radio state and preamble */
- priv->radio_on = 0;
- priv->radio_short_preamble = 0;
-
- /* Finalize join worker */
- INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
-
- /* TX reclaim and RX tasklets. */
- tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
- tasklet_disable(&priv->poll_tx_task);
- tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
- tasklet_disable(&priv->poll_rx_task);
-
- /* Power management cookie */
- priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
- if (priv->cookie == NULL)
- goto err_stop_firmware;
-
rc = mwl8k_rxq_init(hw, 0);
if (rc)
- goto err_free_cookie;
+ goto err_stop_firmware;
rxq_refill(hw, 0, INT_MAX);
- mutex_init(&priv->fw_mutex);
- priv->fw_mutex_owner = NULL;
- priv->fw_mutex_depth = 0;
- priv->hostcmd_wait = NULL;
-
- spin_lock_init(&priv->tx_lock);
-
- priv->tx_wait = NULL;
-
for (i = 0; i < MWL8K_TX_QUEUES; i++) {
rc = mwl8k_txq_init(hw, i);
if (rc)
@@ -4071,13 +4222,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
goto err_free_irq;
}
- hw->wiphy->interface_modes = 0;
- if (priv->ap_macids_supported)
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
- if (priv->sta_macids_supported)
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
-
-
/* Turn radio off */
rc = mwl8k_cmd_radio_disable(hw);
if (rc) {
@@ -4096,12 +4240,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
free_irq(priv->pdev->irq, hw);
- rc = ieee80211_register_hw(hw);
- if (rc) {
- wiphy_err(hw->wiphy, "Cannot register device\n");
- goto err_free_queues;
- }
-
wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
priv->device_info->part_name,
priv->hw_rev, hw->wiphy->perm_addr,
@@ -4120,14 +4258,238 @@ err_free_queues:
mwl8k_txq_deinit(hw, i);
mwl8k_rxq_deinit(hw, 0);
+err_stop_firmware:
+ mwl8k_hw_reset(priv);
+
+ return rc;
+}
+
+/*
+ * invoke mwl8k_reload_firmware to change the firmware image after the device
+ * has already been registered
+ */
+static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
+{
+ int i, rc = 0;
+ struct mwl8k_priv *priv = hw->priv;
+
+ mwl8k_stop(hw);
+ mwl8k_rxq_deinit(hw, 0);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+
+ rc = mwl8k_init_firmware(hw, fw_image, false);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_probe_hw(hw);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_start(hw);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_config(hw, ~0);
+ if (rc)
+ goto fail;
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
+ if (rc)
+ goto fail;
+ }
+
+ return rc;
+
+fail:
+ printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n");
+ return rc;
+}
+
+static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ int i, rc;
+
+ rc = mwl8k_load_firmware(hw);
+ mwl8k_release_firmware(priv);
+ if (rc) {
+ wiphy_err(hw->wiphy, "Cannot start firmware\n");
+ return rc;
+ }
+
+ /*
+ * Extra headroom is the size of the required DMA header
+ * minus the size of the smallest 802.11 frame (CTS frame).
+ */
+ hw->extra_tx_headroom =
+ sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+
+ hw->channel_change_time = 10;
+
+ hw->queues = MWL8K_TX_QUEUES;
+
+ /* Set rssi values to dBm */
+ hw->flags |= IEEE80211_HW_SIGNAL_DBM;
+ hw->vif_data_size = sizeof(struct mwl8k_vif);
+ hw->sta_data_size = sizeof(struct mwl8k_sta);
+
+ priv->macids_used = 0;
+ INIT_LIST_HEAD(&priv->vif_list);
+
+ /* Set default radio state and preamble */
+ priv->radio_on = 0;
+ priv->radio_short_preamble = 0;
+
+ /* Finalize join worker */
+ INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+
+ /* TX reclaim and RX tasklets. */
+ tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
+ tasklet_disable(&priv->poll_tx_task);
+ tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
+ tasklet_disable(&priv->poll_rx_task);
+
+ /* Power management cookie */
+ priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
+ if (priv->cookie == NULL)
+ return -ENOMEM;
+
+ mutex_init(&priv->fw_mutex);
+ priv->fw_mutex_owner = NULL;
+ priv->fw_mutex_depth = 0;
+ priv->hostcmd_wait = NULL;
+
+ spin_lock_init(&priv->tx_lock);
+
+ priv->tx_wait = NULL;
+
+ rc = mwl8k_probe_hw(hw);
+ if (rc)
+ goto err_free_cookie;
+
+ hw->wiphy->interface_modes = 0;
+ if (priv->ap_macids_supported || priv->device_info->fw_image_ap)
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
+ if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
+
+ rc = ieee80211_register_hw(hw);
+ if (rc) {
+ wiphy_err(hw->wiphy, "Cannot register device\n");
+ goto err_unprobe_hw;
+ }
+
+ return 0;
+
+err_unprobe_hw:
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+ mwl8k_rxq_deinit(hw, 0);
+
err_free_cookie:
if (priv->cookie != NULL)
pci_free_consistent(priv->pdev, 4,
priv->cookie, priv->cookie_dma);
+ return rc;
+}
+static int __devinit mwl8k_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ static int printed_version;
+ struct ieee80211_hw *hw;
+ struct mwl8k_priv *priv;
+ struct mwl8k_device_info *di;
+ int rc;
+
+ if (!printed_version) {
+ printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
+ printed_version = 1;
+ }
+
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot enable new PCI device\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ rc = pci_request_regions(pdev, MWL8K_NAME);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
+ MWL8K_NAME);
+ goto err_disable_device;
+ }
+
+ pci_set_master(pdev);
+
+
+ hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
+ rc = -ENOMEM;
+ goto err_free_reg;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->pdev = pdev;
+ priv->device_info = &mwl8k_info_tbl[id->driver_data];
+
+
+ priv->sram = pci_iomap(pdev, 0, 0x10000);
+ if (priv->sram == NULL) {
+ wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
+ goto err_iounmap;
+ }
+
+ /*
+ * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
+ * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
+ */
+ priv->regs = pci_iomap(pdev, 1, 0x10000);
+ if (priv->regs == NULL) {
+ priv->regs = pci_iomap(pdev, 2, 0x10000);
+ if (priv->regs == NULL) {
+ wiphy_err(hw->wiphy, "Cannot map device registers\n");
+ goto err_iounmap;
+ }
+ }
+
+ /*
+ * Choose the initial fw image depending on user input. If a second
+ * image is available, make it the alternative image that will be
+ * loaded if the first one fails.
+ */
+ init_completion(&priv->firmware_loading_complete);
+ di = priv->device_info;
+ if (ap_mode_default && di->fw_image_ap) {
+ priv->fw_pref = di->fw_image_ap;
+ priv->fw_alt = di->fw_image_sta;
+ } else if (!ap_mode_default && di->fw_image_sta) {
+ priv->fw_pref = di->fw_image_sta;
+ priv->fw_alt = di->fw_image_ap;
+ } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) {
+ printk(KERN_WARNING "AP fw is unavailable. Using STA fw.");
+ priv->fw_pref = di->fw_image_sta;
+ } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) {
+ printk(KERN_WARNING "STA fw is unavailable. Using AP fw.");
+ priv->fw_pref = di->fw_image_ap;
+ }
+ rc = mwl8k_init_firmware(hw, priv->fw_pref, true);
+ if (rc)
+ goto err_stop_firmware;
+ return rc;
+
err_stop_firmware:
mwl8k_hw_reset(priv);
- mwl8k_release_firmware(priv);
err_iounmap:
if (priv->regs != NULL)
@@ -4163,6 +4525,13 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
return;
priv = hw->priv;
+ wait_for_completion(&priv->firmware_loading_complete);
+
+ if (priv->fw_state == FW_STATE_ERROR) {
+ mwl8k_hw_reset(priv);
+ goto unmap;
+ }
+
ieee80211_stop_queues(hw);
ieee80211_unregister_hw(hw);
@@ -4185,6 +4554,7 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
+unmap:
pci_iounmap(pdev, priv->regs);
pci_iounmap(pdev, priv->sram);
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index e8e2d0f4763d..f3d396e7544b 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
orinoco_add_hostscan_results(priv, buf, len);
kfree(buf);
- } else if (priv->scan_request) {
+ } else {
/* Either abort or complete the scan */
- cfg80211_scan_done(priv->scan_request, (len < 0));
- priv->scan_request = NULL;
+ orinoco_scan_done(priv, (len < 0));
}
spin_lock_irqsave(&priv->scan_lock, flags);
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv)
hermes_write_regn(hw, EVACK, 0xffff);
}
+ orinoco_scan_done(priv, true);
+
/* firmware will have to reassociate */
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work)
orinoco_unlock(priv, &flags);
/* Scanning support: Notify scan cancellation */
- if (priv->scan_request) {
- cfg80211_scan_done(priv->scan_request, 1);
- priv->scan_request = NULL;
- }
+ orinoco_scan_done(priv, true);
if (priv->hard_reset) {
err = (*priv->hard_reset)(priv);
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv)
struct net_device *dev = priv->ndev;
int err = 0;
+ /* If we've called commit, we are reconfiguring or bringing the
+ * interface up. Maintaining countermeasures across this would
+ * be confusing, so note that we've disabled them. The port will
+ * be enabled later in orinoco_commit or __orinoco_up. */
+ priv->tkip_cm_active = 0;
+
err = orinoco_hw_program_rids(priv);
/* FIXME: what about netif_tx_lock */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 71b3d68b9403..32954c4b243a 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link)
goto failed;
}
- ret = pcmcia_request_irq(link, orinoco_interrupt);
- if (ret)
- goto failed;
-
- /* We initialize the hermes structure before completing PCMCIA
- * configuration just in case the interrupt handler gets
- * called. */
mem = ioport_map(link->resource[0]->start,
resource_size(link->resource[0]));
if (!mem)
goto failed;
+ /* We initialize the hermes structure before completing PCMCIA
+ * configuration just in case the interrupt handler gets
+ * called. */
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
+ if (ret)
+ goto failed;
+
ret = pcmcia_enable_device(link);
if (ret)
goto failed;
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 4300d9db7d8c..86cb54c842e7 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
priv->scan_request = NULL;
}
}
+
+void orinoco_scan_done(struct orinoco_private *priv, bool abort)
+{
+ if (priv->scan_request) {
+ cfg80211_scan_done(priv->scan_request, abort);
+ priv->scan_request = NULL;
+ }
+}
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
index 2dc4e046dbdb..27281fb0a6dc 100644
--- a/drivers/net/wireless/orinoco/scan.h
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
void orinoco_add_hostscan_results(struct orinoco_private *dev,
unsigned char *buf,
size_t len);
+void orinoco_scan_done(struct orinoco_private *priv, bool abort);
#endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index fb859a5ad2eb..db34c282e59b 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link)
goto failed;
}
- ret = pcmcia_request_irq(link, orinoco_interrupt);
- if (ret)
- goto failed;
-
- /* We initialize the hermes structure before completing PCMCIA
- * configuration just in case the interrupt handler gets
- * called. */
mem = ioport_map(link->resource[0]->start,
resource_size(link->resource[0]));
if (!mem)
goto failed;
+ /* We initialize the hermes structure before completing PCMCIA
+ * configuration just in case the interrupt handler gets
+ * called. */
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
hw->eeprom_pda = true;
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
+ if (ret)
+ goto failed;
+
ret = pcmcia_enable_device(link);
if (ret)
goto failed;
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 93505f93bf97..e793679e2e19 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -893,6 +893,14 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
*/
break;
+ case IW_AUTH_MFP:
+ /* Management Frame Protection not supported.
+ * Only fail if set to required.
+ */
+ if (param->value == IW_AUTH_MFP_REQUIRED)
+ ret = -EINVAL;
+ break;
+
case IW_AUTH_KEY_MGMT:
/* wl_lkm implies value 2 == PSK for Hermes I
* which ties in with WEXT
@@ -911,10 +919,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
*/
if (param->value) {
priv->tkip_cm_active = 1;
- ret = hermes_enable_port(hw, 0);
+ ret = hermes_disable_port(hw, 0);
} else {
priv->tkip_cm_active = 0;
- ret = hermes_disable_port(hw, 0);
+ ret = hermes_enable_port(hw, 0);
}
break;
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index d5bc21e5a02c..21713a7638c4 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -43,6 +43,7 @@ MODULE_FIRMWARE("isl3887usb");
static struct usb_device_id p54u_table[] __devinitdata = {
/* Version 1 devices (pci chip + net2280) */
+ {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
{USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
{USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
@@ -56,9 +57,13 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
+ {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */
{USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
+ {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */
+ {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */
{USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
+ {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */
{USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
{USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
{USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
@@ -94,6 +99,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
{USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
+ {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */
{USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
{USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
{USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
@@ -183,7 +189,7 @@ static void p54u_rx_cb(struct urb *urb)
static void p54u_tx_cb(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ieee80211_hw *dev = (struct ieee80211_hw *)
+ struct ieee80211_hw *dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
p54_free_skb(dev, skb);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 97007d9e2c1f..0764d1a30d13 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1776,11 +1776,8 @@ static void ray_update_multi_list(struct net_device *dev, int all)
/* Copy the kernel's list of MC addresses to card */
netdev_for_each_mc_addr(ha, dev) {
memcpy_toio(p, ha->addr, ETH_ALEN);
- dev_dbg(&link->dev,
- "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
- ha->addr[0], ha->addr[1],
- ha->addr[2], ha->addr[3],
- ha->addr[4], ha->addr[5]);
+ dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
+ ha->addr);
p += ETH_ALEN;
i++;
}
@@ -2015,11 +2012,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
memcpy_fromio(&local->bss_id,
prcs->var.rejoin_net_complete.
bssid, ADDRLEN);
- dev_dbg(&link->dev,
- "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
- local->bss_id[0], local->bss_id[1],
- local->bss_id[2], local->bss_id[3],
- local->bss_id[4], local->bss_id[5]);
+ dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
+ local->bss_id);
if (!sniffer)
authenticate(local);
}
@@ -2286,8 +2280,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
struct ethhdr *peth;
UCHAR srcaddr[ADDRLEN];
UCHAR destaddr[ADDRLEN];
- static UCHAR org_bridge[3] = { 0, 0, 0xf8 };
- static UCHAR org_1042[3] = { 0, 0, 0 };
+ static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
+ static const UCHAR org_1042[3] = { 0, 0, 0 };
memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 71b5971da597..848cc2cce247 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -129,6 +129,7 @@ MODULE_PARM_DESC(workaround_interval,
#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
+#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216)
#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
@@ -156,6 +157,12 @@ MODULE_PARM_DESC(workaround_interval,
#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
+/* Known device types */
+#define RNDIS_UNKNOWN 0
+#define RNDIS_BCM4320A 1
+#define RNDIS_BCM4320B 2
+
+
/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
* slightly modified for datatype endianess, etc
*/
@@ -233,6 +240,12 @@ enum ndis_80211_addwep_bits {
NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
};
+enum ndis_80211_power_mode {
+ NDIS_80211_POWER_MODE_CAM,
+ NDIS_80211_POWER_MODE_MAX_PSP,
+ NDIS_80211_POWER_MODE_FAST_PSP,
+};
+
struct ndis_80211_auth_request {
__le32 length;
u8 bssid[6];
@@ -472,12 +485,16 @@ struct rndis_wlan_private {
struct mutex command_lock;
unsigned long work_pending;
int last_qual;
+ s32 cqm_rssi_thold;
+ u32 cqm_rssi_hyst;
+ int last_cqm_event_rssi;
struct ieee80211_supported_band band;
struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
u32 cipher_suites[ARRAY_SIZE(rndis_cipher_suites)];
+ int device_type;
int caps;
int multicast_size;
@@ -493,10 +510,10 @@ struct rndis_wlan_private {
/* hardware state */
bool radio_on;
+ int power_mode;
int infra_mode;
bool connected;
u8 bssid[ETH_ALEN];
- struct ndis_80211_ssid essid;
__le32 current_command_oid;
/* encryption stuff */
@@ -547,7 +564,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr);
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index);
+ u8 key_index, bool unicast, bool multicast);
static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
u8 *mac, struct station_info *sinfo);
@@ -563,7 +580,14 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
-static struct cfg80211_ops rndis_config_ops = {
+static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, int timeout);
+
+static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev,
+ s32 rssi_thold, u32 rssi_hyst);
+
+static const struct cfg80211_ops rndis_config_ops = {
.change_virtual_intf = rndis_change_virtual_intf,
.scan = rndis_scan,
.set_wiphy_params = rndis_set_wiphy_params,
@@ -582,6 +606,8 @@ static struct cfg80211_ops rndis_config_ops = {
.set_pmksa = rndis_set_pmksa,
.del_pmksa = rndis_del_pmksa,
.flush_pmksa = rndis_flush_pmksa,
+ .set_power_mgmt = rndis_set_power_mgmt,
+ .set_cqm_rssi_config = rndis_set_cqm_rssi_config,
};
static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -680,6 +706,7 @@ static const char *oid_to_string(__le32 oid)
OID_STR(OID_802_11_ADD_KEY);
OID_STR(OID_802_11_REMOVE_KEY);
OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
+ OID_STR(OID_802_11_CAPABILITY);
OID_STR(OID_802_11_PMKID);
OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
@@ -690,6 +717,7 @@ static const char *oid_to_string(__le32 oid)
OID_STR(OID_802_11_RTS_THRESHOLD);
OID_STR(OID_802_11_SUPPORTED_RATES);
OID_STR(OID_802_11_CONFIGURATION);
+ OID_STR(OID_802_11_POWER_MODE);
OID_STR(OID_802_11_BSSID_LIST);
#undef OID_STR
}
@@ -810,7 +838,8 @@ exit_unlock:
return ret;
}
-static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
+static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data,
+ int len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
union {
@@ -994,7 +1023,18 @@ static int level_to_qual(int level)
*/
static int set_infra_mode(struct usbnet *usbdev, int mode);
static void restore_keys(struct usbnet *usbdev);
-static int rndis_check_bssid_list(struct usbnet *usbdev);
+static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid,
+ bool *matched);
+
+static int rndis_start_bssid_list_scan(struct usbnet *usbdev)
+{
+ __le32 tmp;
+
+ /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */
+ tmp = cpu_to_le32(1);
+ return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
+}
static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
@@ -1007,7 +1047,6 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
return ret;
}
if (ret == 0) {
- memcpy(&priv->essid, ssid, sizeof(priv->essid));
priv->radio_on = true;
netdev_dbg(usbdev->net, "%s(): radio_on = true\n", __func__);
}
@@ -1015,7 +1054,7 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
return ret;
}
-static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
+static int set_bssid(struct usbnet *usbdev, const u8 *bssid)
{
int ret;
@@ -1031,7 +1070,9 @@ static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
static int clear_bssid(struct usbnet *usbdev)
{
- u8 broadcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const u8 broadcast_mac[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
return set_bssid(usbdev, broadcast_mac);
}
@@ -1904,14 +1945,14 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
struct usbnet *usbdev = netdev_priv(dev);
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret;
- __le32 tmp;
+ int delay = SCAN_DELAY_JIFFIES;
netdev_dbg(usbdev->net, "cfg80211.scan\n");
/* Get current bssid list from device before new scan, as new scan
* clears internal bssid list.
*/
- rndis_check_bssid_list(usbdev);
+ rndis_check_bssid_list(usbdev, NULL, NULL);
if (!request)
return -EINVAL;
@@ -1921,13 +1962,13 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
priv->scan_request = request;
- tmp = cpu_to_le32(1);
- ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
- sizeof(tmp));
+ ret = rndis_start_bssid_list_scan(usbdev);
if (ret == 0) {
+ if (priv->device_type == RNDIS_BCM4320A)
+ delay = HZ;
+
/* Wait before retrieving scan results from device */
- queue_delayed_work(priv->workqueue, &priv->scan_work,
- SCAN_DELAY_JIFFIES);
+ queue_delayed_work(priv->workqueue, &priv->scan_work, delay);
}
return ret;
@@ -1946,8 +1987,8 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
int ie_len, bssid_len;
u8 *ie;
- netdev_dbg(usbdev->net, " found bssid: '%.32s' [%pM]\n",
- bssid->ssid.essid, bssid->mac);
+ netdev_dbg(usbdev->net, " found bssid: '%.32s' [%pM], len: %d\n",
+ bssid->ssid.essid, bssid->mac, le32_to_cpu(bssid->length));
/* parse bssid structure */
bssid_len = le32_to_cpu(bssid->length);
@@ -1981,49 +2022,98 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
GFP_KERNEL);
}
-static int rndis_check_bssid_list(struct usbnet *usbdev)
+static struct ndis_80211_bssid_ex *next_bssid_list_item(
+ struct ndis_80211_bssid_ex *bssid,
+ int *bssid_len, void *buf, int len)
+{
+ void *buf_end, *bssid_end;
+
+ buf_end = (char *)buf + len;
+ bssid_end = (char *)bssid + *bssid_len;
+
+ if ((int)(buf_end - bssid_end) < sizeof(bssid->length)) {
+ *bssid_len = 0;
+ return NULL;
+ } else {
+ bssid = (void *)((char *)bssid + *bssid_len);
+ *bssid_len = le32_to_cpu(bssid->length);
+ return bssid;
+ }
+}
+
+static bool check_bssid_list_item(struct ndis_80211_bssid_ex *bssid,
+ int bssid_len, void *buf, int len)
+{
+ void *buf_end, *bssid_end;
+
+ if (!bssid || bssid_len <= 0 || bssid_len > len)
+ return false;
+
+ buf_end = (char *)buf + len;
+ bssid_end = (char *)bssid + bssid_len;
+
+ return (int)(buf_end - bssid_end) >= 0 && (int)(bssid_end - buf) >= 0;
+}
+
+static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid,
+ bool *matched)
{
void *buf = NULL;
struct ndis_80211_bssid_list_ex *bssid_list;
struct ndis_80211_bssid_ex *bssid;
- int ret = -EINVAL, len, count, bssid_len;
- bool resized = false;
+ int ret = -EINVAL, len, count, bssid_len, real_count, new_len;
- netdev_dbg(usbdev->net, "check_bssid_list\n");
+ netdev_dbg(usbdev->net, "%s()\n", __func__);
len = CONTROL_BUFFER_SIZE;
resize_buf:
- buf = kmalloc(len, GFP_KERNEL);
+ buf = kzalloc(len, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
goto out;
}
- ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
- if (ret != 0)
+ /* BSSID-list might have got bigger last time we checked, keep
+ * resizing until it won't get any bigger.
+ */
+ new_len = len;
+ ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &new_len);
+ if (ret != 0 || new_len < sizeof(struct ndis_80211_bssid_list_ex))
goto out;
- if (!resized && len > CONTROL_BUFFER_SIZE) {
- resized = true;
+ if (new_len > len) {
+ len = new_len;
kfree(buf);
goto resize_buf;
}
+ len = new_len;
+
bssid_list = buf;
- bssid = bssid_list->bssid;
- bssid_len = le32_to_cpu(bssid->length);
count = le32_to_cpu(bssid_list->num_items);
- netdev_dbg(usbdev->net, "check_bssid_list: %d BSSIDs found (buflen: %d)\n",
- count, len);
+ real_count = 0;
+ netdev_dbg(usbdev->net, "%s(): buflen: %d\n", __func__, len);
+
+ bssid_len = 0;
+ bssid = next_bssid_list_item(bssid_list->bssid, &bssid_len, buf, len);
- while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
- rndis_bss_info_update(usbdev, bssid);
+ /* Device returns incorrect 'num_items'. Workaround by ignoring the
+ * received 'num_items' and walking through full bssid buffer instead.
+ */
+ while (check_bssid_list_item(bssid, bssid_len, buf, len)) {
+ if (rndis_bss_info_update(usbdev, bssid) && match_bssid &&
+ matched) {
+ if (compare_ether_addr(bssid->mac, match_bssid))
+ *matched = true;
+ }
- bssid = (void *)bssid + bssid_len;
- bssid_len = le32_to_cpu(bssid->length);
- count--;
+ real_count++;
+ bssid = next_bssid_list_item(bssid, &bssid_len, buf, len);
}
+ netdev_dbg(usbdev->net, "%s(): num_items from device: %d, really found:"
+ " %d\n", __func__, count, real_count);
+
out:
kfree(buf);
return ret;
@@ -2041,7 +2131,7 @@ static void rndis_get_scan_results(struct work_struct *work)
if (!priv->scan_request)
return;
- ret = rndis_check_bssid_list(usbdev);
+ ret = rndis_check_bssid_list(usbdev, NULL, NULL);
cfg80211_scan_done(priv->scan_request, ret < 0);
@@ -2355,7 +2445,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
}
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index)
+ u8 key_index, bool unicast, bool multicast)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
@@ -2365,6 +2455,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
priv->encr_tx_key_index = key_index;
+ if (is_wpa_key(priv, key_index))
+ return 0;
+
key = priv->encr_keys[key_index];
return add_wep_key(usbdev, key.material, key.len, key_index);
@@ -2495,6 +2588,136 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
}
+static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, int timeout)
+{
+ struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+ struct usbnet *usbdev = priv->usbdev;
+ int power_mode;
+ __le32 mode;
+ int ret;
+
+ netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__,
+ enabled ? "enabled" : "disabled",
+ timeout);
+
+ if (enabled)
+ power_mode = NDIS_80211_POWER_MODE_FAST_PSP;
+ else
+ power_mode = NDIS_80211_POWER_MODE_CAM;
+
+ if (power_mode == priv->power_mode)
+ return 0;
+
+ priv->power_mode = power_mode;
+
+ mode = cpu_to_le32(power_mode);
+ ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode));
+
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev,
+ s32 rssi_thold, u32 rssi_hyst)
+{
+ struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+
+ priv->cqm_rssi_thold = rssi_thold;
+ priv->cqm_rssi_hyst = rssi_hyst;
+ priv->last_cqm_event_rssi = 0;
+
+ return 0;
+}
+
+static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
+ struct ndis_80211_assoc_info *info)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ struct ieee80211_channel *channel;
+ struct ndis_80211_conf config;
+ struct ndis_80211_ssid ssid;
+ s32 signal;
+ u64 timestamp;
+ u16 capability;
+ u16 beacon_interval;
+ __le32 rssi;
+ u8 ie_buf[34];
+ int len, ret, ie_len;
+
+ /* Get signal quality, in case of error use rssi=0 and ignore error. */
+ len = sizeof(rssi);
+ rssi = 0;
+ ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+ signal = level_to_qual(le32_to_cpu(rssi));
+
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, "
+ "rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi),
+ level_to_qual(le32_to_cpu(rssi)));
+
+ /* Get AP capabilities */
+ if (info) {
+ capability = le16_to_cpu(info->resp_ie.capa);
+ } else {
+ /* Set atleast ESS/IBSS capability */
+ capability = (priv->infra_mode == NDIS_80211_INFRA_INFRA) ?
+ WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS;
+ }
+
+ /* Get channel and beacon interval */
+ len = sizeof(config);
+ ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n",
+ __func__, ret);
+ if (ret >= 0) {
+ beacon_interval = le16_to_cpu(config.beacon_period);
+ channel = ieee80211_get_channel(priv->wdev.wiphy,
+ KHZ_TO_MHZ(le32_to_cpu(config.ds_config)));
+ if (!channel) {
+ netdev_warn(usbdev->net, "%s(): could not get channel."
+ "\n", __func__);
+ return;
+ }
+ } else {
+ netdev_warn(usbdev->net, "%s(): could not get configuration.\n",
+ __func__);
+ return;
+ }
+
+ /* Get SSID, in case of error, use zero length SSID and ignore error. */
+ len = sizeof(ssid);
+ memset(&ssid, 0, sizeof(ssid));
+ ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len);
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: "
+ "'%.32s'\n", __func__, ret,
+ le32_to_cpu(ssid.length), ssid.essid);
+
+ if (le32_to_cpu(ssid.length) > 32)
+ ssid.length = cpu_to_le32(32);
+
+ ie_buf[0] = WLAN_EID_SSID;
+ ie_buf[1] = le32_to_cpu(ssid.length);
+ memcpy(&ie_buf[2], ssid.essid, le32_to_cpu(ssid.length));
+
+ ie_len = le32_to_cpu(ssid.length) + 2;
+
+ /* no tsf */
+ timestamp = 0;
+
+ netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, "
+ "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), "
+ "signal:%d\n", __func__, (channel ? channel->center_freq : -1),
+ bssid, (u32)timestamp, capability, beacon_interval, ie_len,
+ ssid.essid, signal);
+
+ cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
+ timestamp, capability, beacon_interval, ie_buf, ie_len,
+ signal, GFP_KERNEL);
+}
+
/*
* workers, indication handlers, device poller
*/
@@ -2507,6 +2730,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
u8 *req_ie, *resp_ie;
int ret, offset;
bool roamed = false;
+ bool match_bss;
if (priv->infra_mode == NDIS_80211_INFRA_INFRA && priv->connected) {
/* received media connect indication while connected, either
@@ -2558,6 +2782,13 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
resp_ie_len =
CONTROL_BUFFER_SIZE - offset;
}
+ } else {
+ /* Since rndis_wlan_craft_connected_bss() might use info
+ * later and expects info to contain valid data if
+ * non-null, free info and set NULL here.
+ */
+ kfree(info);
+ info = NULL;
}
} else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
return;
@@ -2569,13 +2800,26 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
netdev_dbg(usbdev->net, "link up work: [%pM]%s\n",
bssid, roamed ? " roamed" : "");
- /* Internal bss list in device always contains at least the currently
+ /* Internal bss list in device should contain at least the currently
* connected bss and we can get it to cfg80211 with
* rndis_check_bssid_list().
- * NOTE: This is true for Broadcom chip, but not mentioned in RNDIS
- * spec.
+ *
+ * NDIS spec says: "If the device is associated, but the associated
+ * BSSID is not in its BSSID scan list, then the driver must add an
+ * entry for the BSSID at the end of the data that it returns in
+ * response to query of OID_802_11_BSSID_LIST."
+ *
+ * NOTE: Seems to be true for BCM4320b variant, but not BCM4320a.
*/
- rndis_check_bssid_list(usbdev);
+ match_bss = false;
+ rndis_check_bssid_list(usbdev, bssid, &match_bss);
+
+ if (!is_zero_ether_addr(bssid) && !match_bss) {
+ /* Couldn't get bss from device, we need to manually craft bss
+ * for cfg80211.
+ */
+ rndis_wlan_craft_connected_bss(usbdev, bssid, info);
+ }
if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
if (!roamed)
@@ -2918,6 +3162,32 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
return retval;
}
+static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ enum nl80211_cqm_rssi_threshold_event event;
+ int thold, hyst, last_event;
+
+ if (priv->cqm_rssi_thold >= 0 || rssi >= 0)
+ return;
+ if (priv->infra_mode != NDIS_80211_INFRA_INFRA)
+ return;
+
+ last_event = priv->last_cqm_event_rssi;
+ thold = priv->cqm_rssi_thold;
+ hyst = priv->cqm_rssi_hyst;
+
+ if (rssi < thold && (last_event == 0 || rssi < last_event - hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
+ else if (rssi > thold && (last_event == 0 || rssi > last_event + hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+ else
+ return;
+
+ priv->last_cqm_event_rssi = rssi;
+ cfg80211_cqm_rssi_notify(usbdev->net, event, GFP_KERNEL);
+}
+
#define DEVICE_POLLER_JIFFIES (HZ)
static void rndis_device_poller(struct work_struct *work)
{
@@ -2934,13 +3204,28 @@ static void rndis_device_poller(struct work_struct *work)
* also polls device with rndis_command() and catches for media link
* indications.
*/
- if (!is_associated(usbdev))
+ if (!is_associated(usbdev)) {
+ /* Workaround bad scanning in BCM4320a devices with active
+ * background scanning when not associated.
+ */
+ if (priv->device_type == RNDIS_BCM4320A && priv->radio_on &&
+ !priv->scan_request) {
+ /* Get previous scan results */
+ rndis_check_bssid_list(usbdev, NULL, NULL);
+
+ /* Initiate new scan */
+ rndis_start_bssid_list_scan(usbdev);
+ }
+
goto end;
+ }
len = sizeof(rssi);
ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
- if (ret == 0)
+ if (ret == 0) {
priv->last_qual = level_to_qual(le32_to_cpu(rssi));
+ rndis_do_cqm(usbdev, le32_to_cpu(rssi));
+ }
netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n",
ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
@@ -2992,10 +3277,12 @@ end:
/*
* driver/device initialization
*/
-static void rndis_copy_module_params(struct usbnet *usbdev)
+static void rndis_copy_module_params(struct usbnet *usbdev, int device_type)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ priv->device_type = device_type;
+
priv->param_country[0] = modparam_country[0];
priv->param_country[1] = modparam_country[1];
priv->param_country[2] = 0;
@@ -3038,12 +3325,25 @@ static void rndis_copy_module_params(struct usbnet *usbdev)
priv->param_workaround_interval = modparam_workaround_interval;
}
+static int unknown_early_init(struct usbnet *usbdev)
+{
+ /* copy module parameters for unknown so that iwconfig reports txpower
+ * and workaround parameter is copied to private structure correctly.
+ */
+ rndis_copy_module_params(usbdev, RNDIS_UNKNOWN);
+
+ /* This is unknown device, so do not try set configuration parameters.
+ */
+
+ return 0;
+}
+
static int bcm4320a_early_init(struct usbnet *usbdev)
{
/* copy module parameters for bcm4320a so that iwconfig reports txpower
* and workaround parameter is copied to private structure correctly.
*/
- rndis_copy_module_params(usbdev);
+ rndis_copy_module_params(usbdev, RNDIS_BCM4320A);
/* bcm4320a doesn't handle configuration parameters well. Try
* set any and you get partially zeroed mac and broken device.
@@ -3057,7 +3357,7 @@ static int bcm4320b_early_init(struct usbnet *usbdev)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
char buf[8];
- rndis_copy_module_params(usbdev);
+ rndis_copy_module_params(usbdev, RNDIS_BCM4320B);
/* Early initialization settings, setting these won't have effect
* if called after generic_rndis_bind().
@@ -3187,13 +3487,15 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
set_default_iw_params(usbdev);
+ priv->power_mode = -1;
+
/* set default rts/frag */
rndis_set_wiphy_params(wiphy,
WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
- /* turn radio on */
- priv->radio_on = true;
- disassociate(usbdev, true);
+ /* turn radio off on init */
+ priv->radio_on = false;
+ disassociate(usbdev, false);
netif_carrier_off(usbdev->net);
return 0;
@@ -3320,7 +3622,7 @@ static const struct driver_info rndis_wlan_info = {
.tx_fixup = rndis_tx_fixup,
.reset = rndis_wlan_reset,
.stop = rndis_wlan_stop,
- .early_init = bcm4320a_early_init,
+ .early_init = unknown_early_init,
.indication = rndis_wlan_indication,
};
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 4396d4b9bfb9..6f383cd684b0 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -53,51 +53,41 @@ config RT61PCI
When compiled as a module, this driver will be called rt61pci.
-config RT2800PCI_PCI
- boolean
- depends on PCI
- default y
-
-config RT2800PCI_SOC
- boolean
- depends on RALINK_RT288X || RALINK_RT305X
- default y
-
config RT2800PCI
- tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)"
- depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL
+ tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
+ depends on PCI || RALINK_RT288X || RALINK_RT305X
select RT2800_LIB
- select RT2X00_LIB_PCI if RT2800PCI_PCI
- select RT2X00_LIB_SOC if RT2800PCI_SOC
+ select RT2X00_LIB_PCI if PCI
+ select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
select RT2X00_LIB_HT
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
select EEPROM_93CX6
---help---
- This adds support for rt2800/rt3000/rt3500 wireless chipset family.
- Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052
-
- This driver is non-functional at the moment and is intended for
- developers.
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052,
+ RT3090, RT3091 & RT3092
When compiled as a module, this driver will be called "rt2800pci.ko".
if RT2800PCI
-config RT2800PCI_RT30XX
- bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"
- default y
+config RT2800PCI_RT33XX
+ bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default n
---help---
- This adds support for rt30xx wireless chipset family to the
+ This adds support for rt33xx wireless chipset family to the
rt2800pci driver.
- Supported chips: RT3090, RT3091 & RT3092
+ Supported chips: RT3390
Support for these devices is non-functional at the moment and is
intended for testers and developers.
config RT2800PCI_RT35XX
- bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices"
+ bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
default n
---help---
This adds support for rt35xx wireless chipset family to the
@@ -134,8 +124,8 @@ config RT73USB
When compiled as a module, this driver will be called rt73usb.
config RT2800USB
- tristate "Ralink rt2800 (USB) support (EXPERIMENTAL)"
- depends on USB && EXPERIMENTAL
+ tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support"
+ depends on USB
select RT2800_LIB
select RT2X00_LIB_USB
select RT2X00_LIB_HT
@@ -143,30 +133,28 @@ config RT2800USB
select RT2X00_LIB_CRYPTO
select CRC_CCITT
---help---
- This adds experimental support for rt2800 wireless chipset family.
- Supported chips: RT2770, RT2870 & RT3070.
-
- Known issues:
- - support for RT2870 chips doesn't work with 802.11n APs yet
- - support for RT3070 chips is non-functional at the moment
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072
When compiled as a module, this driver will be called "rt2800usb.ko".
if RT2800USB
-config RT2800USB_RT30XX
- bool "rt2800usb - Include support for rt30xx (USB) devices"
- default y
+config RT2800USB_RT33XX
+ bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default n
---help---
- This adds support for rt30xx wireless chipset family to the
+ This adds support for rt33xx wireless chipset family to the
rt2800usb driver.
- Supported chips: RT3070, RT3071 & RT3072
+ Supported chips: RT3370
Support for these devices is non-functional at the moment and is
intended for testers and developers.
config RT2800USB_RT35XX
- bool "rt2800usb - Include support for rt35xx (USB) devices"
+ bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
default n
---help---
This adds support for rt35xx wireless chipset family to the
@@ -180,9 +168,9 @@ config RT2800USB_UNKNOWN
bool "rt2800usb - Include support for unknown (USB) devices"
default n
---help---
- This adds support for rt2800 family devices that are known to
- have a rt2800 family chipset, but for which the exact chipset
- is unknown.
+ This adds support for rt2800usb devices that are known to
+ have a rt28xx family compatible chipset, but for which the exact
+ chipset is unknown.
Support status for these devices is unknown, and enabling these
devices may or may not work.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 4f420a9ec5dc..54ca49ad3472 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -633,6 +633,88 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
}
/*
+ * Queue handlers.
+ */
+static void rt2400pci_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+ rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2400pci_kick_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_AC_VI:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_ATIM:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2400pci_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_ATIM:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+ rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Initialization functions.
*/
static bool rt2400pci_get_entry_state(struct queue_entry *entry)
@@ -878,18 +960,6 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
- rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-}
-
static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
@@ -988,12 +1058,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_RADIO_OFF:
rt2400pci_disable_radio(rt2x00dev);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt2400pci_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -1125,32 +1189,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2400pci_kick_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-}
-
-static void rt2400pci_kill_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- if (queue->qid == QID_BEACON) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
- } else {
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
- }
-}
-
/*
* RX control handlers
*/
@@ -1284,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
* 4 - Priority ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
- rt2400pci_txdone(rt2x00dev, QID_AC_BE);
+ rt2400pci_txdone(rt2x00dev, QID_AC_VO);
/*
* 5 - Tx ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
- rt2400pci_txdone(rt2x00dev, QID_AC_BK);
+ rt2400pci_txdone(rt2x00dev, QID_AC_VI);
/* Enable interrupts again. */
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
@@ -1612,6 +1650,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.get_tsf = rt2400pci_get_tsf,
.tx_last_beacon = rt2400pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
@@ -1627,10 +1666,11 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.link_stats = rt2400pci_link_stats,
.reset_tuner = rt2400pci_reset_tuner,
.link_tuner = rt2400pci_link_tuner,
+ .start_queue = rt2400pci_start_queue,
+ .kick_queue = rt2400pci_kick_queue,
+ .stop_queue = rt2400pci_stop_queue,
.write_tx_desc = rt2400pci_write_tx_desc,
.write_beacon = rt2400pci_write_beacon,
- .kick_tx_queue = rt2400pci_kick_tx_queue,
- .kill_tx_queue = rt2400pci_kill_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone,
.config_filter = rt2400pci_config_filter,
.config_intf = rt2400pci_config_intf,
@@ -1640,28 +1680,28 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2400pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 24,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 24,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index c048b18f4133..d3a4a68cc439 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -809,8 +809,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 8 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 8 * sizeof(__le32) )
+#define TXD_DESC_SIZE (8 * sizeof(__le32))
+#define RXD_DESC_SIZE (8 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
@@ -948,6 +948,6 @@
((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER)
#define TXPOWER_TO_DEV(__txpower) \
- MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)
+ (MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER))
#endif /* RT2400PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 97feb7aef809..a9ff26a27724 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -723,6 +723,88 @@ dynamic_cca_tune:
}
/*
+ * Queue handlers.
+ */
+static void rt2500pci_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+ rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2500pci_kick_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_AC_VI:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_ATIM:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2500pci_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_ATIM:
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ break;
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
+ rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Initialization functions.
*/
static bool rt2500pci_get_entry_state(struct queue_entry *entry)
@@ -1033,18 +1115,6 @@ static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
- rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-}
-
static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
@@ -1143,12 +1213,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_RADIO_OFF:
rt2500pci_disable_radio(rt2x00dev);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt2500pci_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -1193,9 +1257,9 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -1279,32 +1343,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2500pci_kick_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-}
-
-static void rt2500pci_kill_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- if (queue->qid == QID_BEACON) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
- } else {
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
- }
-}
-
/*
* RX control handlers
*/
@@ -1417,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
* 4 - Priority ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
- rt2500pci_txdone(rt2x00dev, QID_AC_BE);
+ rt2500pci_txdone(rt2x00dev, QID_AC_VO);
/*
* 5 - Tx ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
- rt2500pci_txdone(rt2x00dev, QID_AC_BK);
+ rt2500pci_txdone(rt2x00dev, QID_AC_VI);
/* Enable interrupts again. */
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
@@ -1909,6 +1947,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.get_tsf = rt2500pci_get_tsf,
.tx_last_beacon = rt2500pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
@@ -1924,10 +1963,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.link_stats = rt2500pci_link_stats,
.reset_tuner = rt2500pci_reset_tuner,
.link_tuner = rt2500pci_link_tuner,
+ .start_queue = rt2500pci_start_queue,
+ .kick_queue = rt2500pci_kick_queue,
+ .stop_queue = rt2500pci_stop_queue,
.write_tx_desc = rt2500pci_write_tx_desc,
.write_beacon = rt2500pci_write_beacon,
- .kick_tx_queue = rt2500pci_kick_tx_queue,
- .kill_tx_queue = rt2500pci_kill_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone,
.config_filter = rt2500pci_config_filter,
.config_intf = rt2500pci_config_intf,
@@ -1937,28 +1977,28 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2500pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index d708031361ac..2aad7ba8a100 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1088,8 +1088,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 11 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 11 * sizeof(__le32) )
+#define TXD_DESC_SIZE (11 * sizeof(__le32))
+#define RXD_DESC_SIZE (11 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 93e44c7f3a74..6b3b1de46792 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -39,7 +39,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -739,6 +739,55 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
}
/*
+ * Queue handlers.
+ */
+static void rt2500usb_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u16 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
+ break;
+ case QID_BEACON:
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
+ rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2500usb_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u16 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX, 1);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
+ break;
+ case QID_BEACON:
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Initialization functions.
*/
static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
@@ -931,18 +980,6 @@ static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u16 reg;
-
- rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
- rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
-}
-
static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
/*
@@ -1018,12 +1055,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_RADIO_OFF:
rt2500usb_disable_radio(rt2x00dev);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt2500usb_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -1081,9 +1112,9 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
- rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_AIFS, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
@@ -1206,14 +1237,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
-static void rt2500usb_kill_tx_queue(struct data_queue *queue)
-{
- if (queue->qid == QID_BEACON)
- rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
-
- rt2x00usb_kill_tx_queue(queue);
-}
-
/*
* RX control handlers
*/
@@ -1801,6 +1824,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1813,11 +1837,13 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.link_stats = rt2500usb_link_stats,
.reset_tuner = rt2500usb_reset_tuner,
.watchdog = rt2x00usb_watchdog,
+ .start_queue = rt2500usb_start_queue,
+ .kick_queue = rt2x00usb_kick_queue,
+ .stop_queue = rt2500usb_stop_queue,
+ .flush_queue = rt2x00usb_flush_queue,
.write_tx_desc = rt2500usb_write_tx_desc,
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
- .kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2500usb_kill_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_shared_key = rt2500usb_config_key,
.config_pairwise_key = rt2500usb_config_key,
@@ -1829,28 +1855,28 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
};
static const struct data_queue_desc rt2500usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb_bcn),
};
static const struct data_queue_desc rt2500usb_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index eb8b6cab9925..4c55e8525cad 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -46,7 +46,11 @@
* RF2020 2.4G B/G
* RF3021 2.4G 1T2R
* RF3022 2.4G 2T2R
- * RF3052 2.4G 2T2R
+ * RF3052 2.4G/5G 2T2R
+ * RF2853 2.4G/5G 3T3R
+ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
+ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
+ * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
*/
#define RF2820 0x0001
#define RF2850 0x0002
@@ -57,7 +61,10 @@
#define RF3021 0x0007
#define RF3022 0x0008
#define RF3052 0x0009
+#define RF2853 0x000a
#define RF3320 0x000b
+#define RF3322 0x000c
+#define RF3853 0x000d
/*
* Chipset revisions.
@@ -206,10 +213,10 @@
/*
* WMM_AIFSN_CFG: Aifsn for each EDCA AC
- * AIFSN0: AC_BE
- * AIFSN1: AC_BK
- * AIFSN2: AC_VI
- * AIFSN3: AC_VO
+ * AIFSN0: AC_VO
+ * AIFSN1: AC_VI
+ * AIFSN2: AC_BE
+ * AIFSN3: AC_BK
*/
#define WMM_AIFSN_CFG 0x0214
#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f)
@@ -219,10 +226,10 @@
/*
* WMM_CWMIN_CSR: CWmin for each EDCA AC
- * CWMIN0: AC_BE
- * CWMIN1: AC_BK
- * CWMIN2: AC_VI
- * CWMIN3: AC_VO
+ * CWMIN0: AC_VO
+ * CWMIN1: AC_VI
+ * CWMIN2: AC_BE
+ * CWMIN3: AC_BK
*/
#define WMM_CWMIN_CFG 0x0218
#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f)
@@ -232,10 +239,10 @@
/*
* WMM_CWMAX_CSR: CWmax for each EDCA AC
- * CWMAX0: AC_BE
- * CWMAX1: AC_BK
- * CWMAX2: AC_VI
- * CWMAX3: AC_VO
+ * CWMAX0: AC_VO
+ * CWMAX1: AC_VI
+ * CWMAX2: AC_BE
+ * CWMAX3: AC_BK
*/
#define WMM_CWMAX_CFG 0x021c
#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f)
@@ -244,18 +251,18 @@
#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000)
/*
- * AC_TXOP0: AC_BK/AC_BE TXOP register
- * AC0TXOP: AC_BK in unit of 32us
- * AC1TXOP: AC_BE in unit of 32us
+ * AC_TXOP0: AC_VO/AC_VI TXOP register
+ * AC0TXOP: AC_VO in unit of 32us
+ * AC1TXOP: AC_VI in unit of 32us
*/
#define WMM_TXOP0_CFG 0x0220
#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff)
#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000)
/*
- * AC_TXOP1: AC_VO/AC_VI TXOP register
- * AC2TXOP: AC_VI in unit of 32us
- * AC3TXOP: AC_VO in unit of 32us
+ * AC_TXOP1: AC_BE/AC_BK TXOP register
+ * AC2TXOP: AC_BE in unit of 32us
+ * AC3TXOP: AC_BK in unit of 32us
*/
#define WMM_TXOP1_CFG 0x0224
#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff)
@@ -281,7 +288,7 @@
#define MCU_CMD_CFG 0x022c
/*
- * AC_BK register offsets
+ * AC_VO register offsets
*/
#define TX_BASE_PTR0 0x0230
#define TX_MAX_CNT0 0x0234
@@ -289,7 +296,7 @@
#define TX_DTX_IDX0 0x023c
/*
- * AC_BE register offsets
+ * AC_VI register offsets
*/
#define TX_BASE_PTR1 0x0240
#define TX_MAX_CNT1 0x0244
@@ -297,7 +304,7 @@
#define TX_DTX_IDX1 0x024c
/*
- * AC_VI register offsets
+ * AC_BE register offsets
*/
#define TX_BASE_PTR2 0x0250
#define TX_MAX_CNT2 0x0254
@@ -305,7 +312,7 @@
#define TX_DTX_IDX2 0x025c
/*
- * AC_VO register offsets
+ * AC_BK register offsets
*/
#define TX_BASE_PTR3 0x0260
#define TX_MAX_CNT3 0x0264
@@ -412,10 +419,22 @@
#define BCN_OFFSET1_BCN7 FIELD32(0xff000000)
/*
- * PBF registers
- * Most are for debug. Driver doesn't touch PBF register.
+ * TXRXQ_PCNT: PBF register
+ * PCNT_TX0Q: Page count for TX hardware queue 0
+ * PCNT_TX1Q: Page count for TX hardware queue 1
+ * PCNT_TX2Q: Page count for TX hardware queue 2
+ * PCNT_RX0Q: Page count for RX hardware queue
*/
#define TXRXQ_PCNT 0x0438
+#define TXRXQ_PCNT_TX0Q FIELD32(0x000000ff)
+#define TXRXQ_PCNT_TX1Q FIELD32(0x0000ff00)
+#define TXRXQ_PCNT_TX2Q FIELD32(0x00ff0000)
+#define TXRXQ_PCNT_RX0Q FIELD32(0xff000000)
+
+/*
+ * PBF register
+ * Debug. Driver doesn't touch PBF register.
+ */
#define PBF_DBG 0x043c
/*
@@ -686,8 +705,18 @@
/*
* CH_TIME_CFG: count as channel busy
+ * EIFS_BUSY: Count EIFS as channel busy
+ * NAV_BUSY: Count NAS as channel busy
+ * RX_BUSY: Count RX as channel busy
+ * TX_BUSY: Count TX as channel busy
+ * TMR_EN: Enable channel statistics timer
*/
#define CH_TIME_CFG 0x110c
+#define CH_TIME_CFG_EIFS_BUSY FIELD32(0x00000010)
+#define CH_TIME_CFG_NAV_BUSY FIELD32(0x00000008)
+#define CH_TIME_CFG_RX_BUSY FIELD32(0x00000004)
+#define CH_TIME_CFG_TX_BUSY FIELD32(0x00000002)
+#define CH_TIME_CFG_TMR_EN FIELD32(0x00000001)
/*
* PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
@@ -960,8 +989,31 @@
/*
* TXOP_CTRL_CFG:
+ * TIMEOUT_TRUN_EN: Enable/Disable TXOP timeout truncation
+ * AC_TRUN_EN: Enable/Disable truncation for AC change
+ * TXRATEGRP_TRUN_EN: Enable/Disable truncation for TX rate group change
+ * USER_MODE_TRUN_EN: Enable/Disable truncation for user TXOP mode
+ * MIMO_PS_TRUN_EN: Enable/Disable truncation for MIMO PS RTS/CTS
+ * RESERVED_TRUN_EN: Reserved
+ * LSIG_TXOP_EN: Enable/Disable L-SIG TXOP protection
+ * EXT_CCA_EN: Enable/Disable extension channel CCA reference (Defer 40Mhz
+ * transmissions if extension CCA is clear).
+ * EXT_CCA_DLY: Extension CCA signal delay time (unit: us)
+ * EXT_CWMIN: CwMin for extension channel backoff
+ * 0: Disabled
+ *
*/
#define TXOP_CTRL_CFG 0x1340
+#define TXOP_CTRL_CFG_TIMEOUT_TRUN_EN FIELD32(0x00000001)
+#define TXOP_CTRL_CFG_AC_TRUN_EN FIELD32(0x00000002)
+#define TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN FIELD32(0x00000004)
+#define TXOP_CTRL_CFG_USER_MODE_TRUN_EN FIELD32(0x00000008)
+#define TXOP_CTRL_CFG_MIMO_PS_TRUN_EN FIELD32(0x00000010)
+#define TXOP_CTRL_CFG_RESERVED_TRUN_EN FIELD32(0x00000020)
+#define TXOP_CTRL_CFG_LSIG_TXOP_EN FIELD32(0x00000040)
+#define TXOP_CTRL_CFG_EXT_CCA_EN FIELD32(0x00000080)
+#define TXOP_CTRL_CFG_EXT_CCA_DLY FIELD32(0x0000ff00)
+#define TXOP_CTRL_CFG_EXT_CWMIN FIELD32(0x000f0000)
/*
* TX_RTS_CFG:
@@ -1485,17 +1537,17 @@
#define SHARED_KEY_MODE_BASE 0x7000
#define MAC_WCID_ENTRY(__idx) \
- ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+ (MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)))
#define PAIRWISE_KEY_ENTRY(__idx) \
- ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+ (PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
#define MAC_IVEIV_ENTRY(__idx) \
- ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) )
+ (MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)))
#define MAC_WCID_ATTR_ENTRY(__idx) \
- ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+ (MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)))
#define SHARED_KEY_ENTRY(__idx) \
- ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+ (SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
#define SHARED_KEY_MODE_ENTRY(__idx) \
- ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+ (SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)))
struct mac_wcid_entry {
u8 mac[6];
@@ -1635,9 +1687,9 @@ struct mac_iveiv_entry {
#define HW_BEACON_BASE7 0x5bc0
#define HW_BEACON_OFFSET(__index) \
- ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
- (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
- (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+ (((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \
+ (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
/*
* BBP registers.
@@ -1805,32 +1857,51 @@ struct mac_iveiv_entry {
#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
/*
- * EEPROM ANTENNA config
+ * EEPROM NIC Configuration 0
* RXPATH: 1: 1R, 2: 2R, 3: 3R
- * TXPATH: 1: 1T, 2: 2T
- */
-#define EEPROM_ANTENNA 0x001a
-#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f)
-#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0)
-#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00)
-
-/*
- * EEPROM NIC config
- * CARDBUS_ACCEL: 0 - enable, 1 - disable
- */
-#define EEPROM_NIC 0x001b
-#define EEPROM_NIC_HW_RADIO FIELD16(0x0001)
-#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002)
-#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004)
-#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008)
-#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010)
-#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020)
-#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040)
-#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
-#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
-#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
-#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800)
-#define EEPROM_NIC_DAC_TEST FIELD16(0x8000)
+ * TXPATH: 1: 1T, 2: 2T, 3: 3T
+ * RF_TYPE: RFIC type
+ */
+#define EEPROM_NIC_CONF0 0x001a
+#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
+#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
+#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC Configuration 1
+ * HW_RADIO: 0: disable, 1: enable
+ * EXTERNAL_TX_ALC: 0: disable, 1: enable
+ * EXTERNAL_LNA_2G: 0: disable, 1: enable
+ * EXTERNAL_LNA_5G: 0: disable, 1: enable
+ * CARDBUS_ACCEL: 0: enable, 1: disable
+ * BW40M_SB_2G: 0: disable, 1: enable
+ * BW40M_SB_5G: 0: disable, 1: enable
+ * WPS_PBC: 0: disable, 1: enable
+ * BW40M_2G: 0: enable, 1: disable
+ * BW40M_5G: 0: enable, 1: disable
+ * BROADBAND_EXT_LNA: 0: disable, 1: enable
+ * ANT_DIVERSITY: 00: Disable, 01: Diversity,
+ * 10: Main antenna, 11: Aux antenna
+ * INTERNAL_TX_ALC: 0: disable, 1: enable
+ * BT_COEXIST: 0: disable, 1: enable
+ * DAC_TEST: 0: disable, 1: enable
+ */
+#define EEPROM_NIC_CONF1 0x001b
+#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
+#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
+#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
+#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008)
+#define EEPROM_NIC_CONF1_CARDBUS_ACCEL FIELD16(0x0010)
+#define EEPROM_NIC_CONF1_BW40M_SB_2G FIELD16(0x0020)
+#define EEPROM_NIC_CONF1_BW40M_SB_5G FIELD16(0x0040)
+#define EEPROM_NIC_CONF1_WPS_PBC FIELD16(0x0080)
+#define EEPROM_NIC_CONF1_BW40M_2G FIELD16(0x0100)
+#define EEPROM_NIC_CONF1_BW40M_5G FIELD16(0x0200)
+#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400)
+#define EEPROM_NIC_CONF1_ANT_DIVERSITY FIELD16(0x1800)
+#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000)
+#define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000)
+#define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000)
/*
* EEPROM frequency
@@ -1852,9 +1923,9 @@ struct mac_iveiv_entry {
* POLARITY_GPIO_4: Polarity GPIO4 setting.
* LED_MODE: Led mode.
*/
-#define EEPROM_LED1 0x001e
-#define EEPROM_LED2 0x001f
-#define EEPROM_LED3 0x0020
+#define EEPROM_LED_AG_CONF 0x001e
+#define EEPROM_LED_ACT_CONF 0x001f
+#define EEPROM_LED_POLARITY 0x0020
#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
@@ -1866,6 +1937,17 @@ struct mac_iveiv_entry {
#define EEPROM_LED_LED_MODE FIELD16(0x1f00)
/*
+ * EEPROM NIC Configuration 2
+ * RX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
+ * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
+ * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
+ */
+#define EEPROM_NIC_CONF2 0x0021
+#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
+#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
+#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
+
+/*
* EEPROM LNA
*/
#define EEPROM_LNA 0x0022
@@ -1915,7 +1997,7 @@ struct mac_iveiv_entry {
/*
* EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
- * This is delta in 40MHZ.
+ * This is delta in 40MHZ.
* VALUE: Tx Power dalta value (MAX=4)
* TYPE: 1: Plus the delta value, 0: minus the delta value
* TXPOWER: Enable:
@@ -1971,9 +2053,9 @@ struct mac_iveiv_entry {
#define MCU_CURRENT 0x36
#define MCU_LED 0x50
#define MCU_LED_STRENGTH 0x51
-#define MCU_LED_1 0x52
-#define MCU_LED_2 0x53
-#define MCU_LED_3 0x54
+#define MCU_LED_AG_CONF 0x52
+#define MCU_LED_ACT_CONF 0x53
+#define MCU_LED_LED_POLARITY 0x54
#define MCU_RADAR 0x60
#define MCU_BOOT_SIGNAL 0x72
#define MCU_BBP_SIGNAL 0x80
@@ -1987,8 +2069,8 @@ struct mac_iveiv_entry {
/*
* DMA descriptor defines.
*/
-#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) )
-#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXWI_DESC_SIZE (4 * sizeof(__le32))
+#define RXWI_DESC_SIZE (4 * sizeof(__le32))
/*
* TX WI structure
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 5f00e00789d8..54917a281398 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
unsigned int i;
u32 reg;
+ /*
+ * Some devices are really slow to respond here. Wait a whole second
+ * before timing out.
+ */
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
!rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
return 0;
- msleep(1);
+ msleep(10);
}
ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
@@ -483,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
txdesc->key_idx : 0xff);
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
txdesc->length);
- rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid);
rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
rt2x00_desc_write(txwi, 1, word);
@@ -727,7 +731,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
* that the TX_STA_FIFO stack has a size of 16. We stick to our
* tx ring size for now.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
break;
@@ -768,6 +772,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
unsigned int beacon_base;
+ unsigned int padding_len;
u32 reg;
/*
@@ -802,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Write entire beacon with TXWI to register.
+ * Write entire beacon with TXWI and padding to register.
*/
+ padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+ skb_pad(entry->skb, padding_len);
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2800_register_multiwrite(rt2x00dev, beacon_base,
- entry->skb->data, entry->skb->len);
+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+ entry->skb->len + padding_len);
/*
* Enable beaconing again.
@@ -824,7 +831,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
}
EXPORT_SYMBOL_GPL(rt2800_write_beacon);
-static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
+static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
unsigned int beacon_base)
{
int i;
@@ -1144,6 +1151,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, const unsigned int flags)
{
u32 reg;
+ bool update_bssid = false;
if (flags & CONFIG_UPDATE_TYPE) {
/*
@@ -1173,6 +1181,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
if (flags & CONFIG_UPDATE_MAC) {
+ if (flags & CONFIG_UPDATE_TYPE &&
+ conf->sync == TSF_SYNC_AP_NONE) {
+ /*
+ * The BSSID register has to be set to our own mac
+ * address in AP mode.
+ */
+ memcpy(conf->bssid, conf->mac, sizeof(conf->mac));
+ update_bssid = true;
+ }
+
if (!is_zero_ether_addr((const u8 *)conf->mac)) {
reg = le32_to_cpu(conf->mac[1]);
rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
@@ -1183,7 +1201,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
conf->mac, sizeof(conf->mac));
}
- if (flags & CONFIG_UPDATE_BSSID) {
+ if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) {
if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
reg = le32_to_cpu(conf->bssid[1]);
rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
@@ -1529,7 +1547,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
rt2x00_rf(rt2x00dev, RF3022) ||
- rt2x00_rf(rt2x00dev, RF3052))
+ rt2x00_rf(rt2x00dev, RF3052) ||
+ rt2x00_rf(rt2x00dev, RF3320))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
else
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1609,6 +1628,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
}
msleep(1);
+
+ /*
+ * Clear channel statistic counters
+ */
+ rt2800_register_read(rt2x00dev, CH_IDLE_STA, &reg);
+ rt2800_register_read(rt2x00dev, CH_BUSY_STA, &reg);
+ rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
}
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
@@ -1914,8 +1940,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x0000002c);
else
@@ -2097,7 +2123,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
}
- rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+ /*
+ * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
+ * although it is reserved.
+ */
+ rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, &reg);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
+ rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
+
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
@@ -2134,7 +2176,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
SHARED_KEY_MODE_ENTRY(i), 0);
for (i = 0; i < 256; i++) {
- u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+ static const u32 wcid[2] = { 0xffffffff, 0x00ffffff };
rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
wcid, sizeof(wcid));
@@ -2227,6 +2269,17 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
+ /*
+ * Set up channel statistics timer
+ */
+ rt2800_register_read(rt2x00dev, CH_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, CH_TIME_CFG_EIFS_BUSY, 1);
+ rt2x00_set_field32(&reg, CH_TIME_CFG_NAV_BUSY, 1);
+ rt2x00_set_field32(&reg, CH_TIME_CFG_RX_BUSY, 1);
+ rt2x00_set_field32(&reg, CH_TIME_CFG_TX_BUSY, 1);
+ rt2x00_set_field32(&reg, CH_TIME_CFG_TMR_EN, 1);
+ rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg);
+
return 0;
}
@@ -2344,10 +2397,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_bbp_read(rt2x00dev, 138, &value);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
value |= 0x20;
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
value &= ~0x02;
rt2800_bbp_write(rt2x00dev, 138, value);
@@ -2559,8 +2612,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
else
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
@@ -2633,10 +2686,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_bbp_read(rt2x00dev, 138, &bbp);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
rt2800_bbp_write(rt2x00dev, 138, bbp);
@@ -2735,16 +2788,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize LED control
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
word & 0xff, (word >> 8) & 0xff);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
word & 0xff, (word >> 8) & 0xff);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
word & 0xff, (word >> 8) & 0xff);
return 0;
@@ -2838,38 +2891,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
EEPROM(rt2x00dev, "MAC: %pM\n", mac);
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
if (word == 0xffff) {
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2872)) {
/*
* There is a max of 2 RX streams for RT28x0 series
*/
- if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
if (word == 0xffff) {
- rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
}
@@ -2884,9 +2940,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
LED_MODE_TXRX_ACTIVITY);
rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word);
}
@@ -2950,12 +3006,12 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Read EEPROM word for configuration.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
/*
* Identify RF chipset.
*/
- value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+ value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
@@ -2981,7 +3037,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
!rt2x00_rf(rt2x00dev, RF2020) &&
!rt2x00_rf(rt2x00dev, RF3021) &&
!rt2x00_rf(rt2x00dev, RF3022) &&
- !rt2x00_rf(rt2x00dev, RF3052)) {
+ !rt2x00_rf(rt2x00dev, RF3052) &&
+ !rt2x00_rf(rt2x00dev, RF3320)) {
ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
return -ENODEV;
}
@@ -2990,9 +3047,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Identify default antenna configuration.
*/
rt2x00dev->default_ant.tx =
- rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
rt2x00dev->default_ant.rx =
- rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
/*
* Read frequency offset and RF programming sequence.
@@ -3003,17 +3060,17 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Read external LNA informations.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
/*
* Detect if this device has an hardware controlled radio.
*/
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
/*
@@ -3225,7 +3282,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->max_report_rates = 7;
rt2x00dev->hw->max_rate_tries = 1;
- rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
/*
* Initialize hw_mode information.
@@ -3245,7 +3302,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
} else if (rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF2020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022)) {
+ rt2x00_rf(rt2x00dev, RF3022) ||
+ rt2x00_rf(rt2x00dev, RF3320)) {
spec->num_channels = 14;
spec->channels = rf_vals_3x;
} else if (rt2x00_rf(rt2x00dev, RF3052)) {
@@ -3268,11 +3326,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40;
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2)
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2)
spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC;
spec->ht.cap |=
- rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) <<
+ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) <<
IEEE80211_HT_CAP_RX_STBC_SHIFT;
spec->ht.ampdu_factor = 3;
@@ -3280,10 +3338,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->ht.mcs.tx_params =
IEEE80211_HT_MCS_TX_DEFINED |
IEEE80211_HT_MCS_TX_RX_DIFF |
- ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+ ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) <<
IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
- switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+ switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) {
case 3:
spec->ht.mcs.rx_mask[2] = 0xff;
case 2:
@@ -3502,6 +3560,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
EXPORT_SYMBOL_GPL(rt2800_ampdu_action);
+int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
+ struct survey_info *survey)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ u32 idle, busy, busy_ext;
+
+ if (idx != 0)
+ return -ENOENT;
+
+ survey->channel = conf->channel;
+
+ rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
+ rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
+ rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext);
+
+ if (idle || busy) {
+ survey->filled = SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_EXT_BUSY;
+
+ survey->channel_time = (idle + busy) / 1000;
+ survey->channel_time_busy = busy / 1000;
+ survey->channel_time_ext_busy = busy_ext / 1000;
+ }
+
+ return 0;
+
+}
+EXPORT_SYMBOL_GPL(rt2800_get_survey);
+
MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT2800 library");
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 81cbc92e7857..e3c995a9dec4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -199,5 +199,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw);
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
+ struct survey_info *survey);
#endif /* RT2800LIB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b26739535986..aa97971a38af 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -84,20 +84,22 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
- u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
+ void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+
+ iounmap(base_addr);
}
#else
static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
}
-#endif /* CONFIG_RT2800PCI_SOC */
+#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
struct rt2x00_dev *rt2x00dev = eeprom->data;
@@ -181,7 +183,78 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
{
}
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
+
+/*
+ * Queue handlers.
+ */
+static void rt2800pci_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ break;
+ case QID_BEACON:
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ break;
+ default:
+ break;
+ };
+}
+
+static void rt2800pci_kick_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ struct queue_entry *entry;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
+ break;
+ case QID_MGMT:
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2800pci_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ break;
+ case QID_BEACON:
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ break;
+ default:
+ break;
+ }
+}
/*
* Firmware functions
@@ -321,18 +394,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
- (state == STATE_RADIO_RX_ON) ||
- (state == STATE_RADIO_RX_ON_LINK));
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-}
-
static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
@@ -442,7 +503,7 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
* if the device is booting and wasn't asleep it will return
* failure when attempting to wakeup.
*/
- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
if (state == STATE_AWAKE) {
rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0);
@@ -476,12 +537,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2800pci_disable_radio(rt2x00dev);
rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt2800pci_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -567,41 +622,6 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
}
/*
- * TX data initialization
- */
-static void rt2800pci_kick_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
- unsigned int qidx;
-
- if (queue->qid == QID_MGMT)
- qidx = 5;
- else
- qidx = queue->qid;
-
- rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx);
-}
-
-static void rt2800pci_kill_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- if (queue->qid == QID_BEACON) {
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
- return;
- }
-
- rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO));
- rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
-}
-
-/*
* RX control handlers
*/
static void rt2800pci_fill_rxdone(struct queue_entry *entry,
@@ -668,14 +688,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
u32 status;
u8 qid;
- while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
- /* Now remove the tx status from the FIFO */
- if (kfifo_out(&rt2x00dev->txstatus_fifo, &status,
- sizeof(status)) != sizeof(status)) {
- WARN_ON(1);
- break;
- }
-
+ while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
if (qid >= QID_RX) {
/*
@@ -683,7 +696,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
* this tx status.
*/
WARNING(rt2x00dev, "Got TX status report with "
- "unexpected pid %u, dropping", qid);
+ "unexpected pid %u, dropping\n", qid);
break;
}
@@ -694,7 +707,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
* processing here and drop the tx status
*/
WARNING(rt2x00dev, "Got TX status for an unavailable "
- "queue %u, dropping", qid);
+ "queue %u, dropping\n", qid);
break;
}
@@ -704,7 +717,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
* and drop the tx status.
*/
WARNING(rt2x00dev, "Got TX status for an empty "
- "queue %u, dropping", qid);
+ "queue %u, dropping\n", qid);
break;
}
@@ -777,20 +790,13 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
* Since we have only one producer and one consumer we don't
* need to lock the kfifo.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
break;
- if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
- WARNING(rt2x00dev, "TX status FIFO overrun,"
- " drop tx status report.\n");
- break;
- }
-
- if (kfifo_in(&rt2x00dev->txstatus_fifo, &status,
- sizeof(status)) != sizeof(status)) {
+ if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) {
WARNING(rt2x00dev, "TX status FIFO overrun,"
"drop tx status report.\n");
break;
@@ -912,6 +918,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
if (!modparam_nohwcrypt)
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
@@ -943,6 +950,8 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
.get_tsf = rt2800_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.ampdu_action = rt2800_ampdu_action,
+ .flush = rt2x00mac_flush,
+ .get_survey = rt2800_get_survey,
};
static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -975,11 +984,12 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.link_stats = rt2800_link_stats,
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
+ .start_queue = rt2800pci_start_queue,
+ .kick_queue = rt2800pci_kick_queue,
+ .stop_queue = rt2800pci_stop_queue,
.write_tx_desc = rt2800pci_write_tx_desc,
.write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
- .kick_tx_queue = rt2800pci_kick_tx_queue,
- .kill_tx_queue = rt2800pci_kill_tx_queue,
.fill_rxdone = rt2800pci_fill_rxdone,
.config_shared_key = rt2800_config_shared_key,
.config_pairwise_key = rt2800_config_pairwise_key,
@@ -991,21 +1001,21 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2800pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 128,
.data_size = AGGREGATION_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2800pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 64,
.data_size = AGGREGATION_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2800pci_queue_bcn = {
- .entry_num = 8 * BEACON_ENTRIES,
+ .entry_num = 8,
.data_size = 0, /* No DMA required for beacons */
.desc_size = TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
@@ -1033,12 +1043,15 @@ static const struct rt2x00_ops rt2800pci_ops = {
/*
* RT2800pci module information.
*/
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1046,12 +1059,10 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
-#ifdef CONFIG_RT2800PCI_RT30XX
- { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#ifdef CONFIG_RT2800PCI_RT33XX
+ { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
#endif
#ifdef CONFIG_RT2800PCI_RT35XX
{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1062,19 +1073,19 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
#endif
{ 0, }
};
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
MODULE_AUTHOR(DRV_PROJECT);
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver.");
MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards");
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
MODULE_FIRMWARE(FIRMWARE_RT2860);
MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
MODULE_LICENSE("GPL");
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
static int rt2800soc_probe(struct platform_device *pdev)
{
return rt2x00soc_probe(pdev, &rt2800pci_ops);
@@ -1091,9 +1102,9 @@ static struct platform_driver rt2800soc_driver = {
.suspend = rt2x00soc_suspend,
.resume = rt2x00soc_resume,
};
-#endif /* CONFIG_RT2800PCI_SOC */
+#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static struct pci_driver rt2800pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2800pci_device_table,
@@ -1102,21 +1113,21 @@ static struct pci_driver rt2800pci_driver = {
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
};
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
static int __init rt2800pci_init(void)
{
int ret = 0;
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
ret = platform_driver_register(&rt2800soc_driver);
if (ret)
return ret;
#endif
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
ret = pci_register_driver(&rt2800pci_driver);
if (ret) {
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
return ret;
@@ -1128,10 +1139,10 @@ static int __init rt2800pci_init(void)
static void __exit rt2800pci_exit(void)
{
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
pci_unregister_driver(&rt2800pci_driver);
#endif
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
}
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index 5a8dda9b5b5a..70e050d904c8 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -38,10 +38,10 @@
* Queue register offset macros
*/
#define TX_QUEUE_REG_OFFSET 0x10
-#define TX_BASE_PTR(__x) TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_MAX_CNT(__x) TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_CTX_IDX(__x) TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
+#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
/*
* 8051 firmware image.
@@ -52,8 +52,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 4 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXD_DESC_SIZE (4 * sizeof(__le32))
+#define RXD_DESC_SIZE (4 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3dff56ec195a..b97a4a54ff4c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -45,11 +45,60 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
/*
+ * Queue handlers.
+ */
+static void rt2800usb_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ break;
+ case QID_BEACON:
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt2800usb_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+ break;
+ case QID_BEACON:
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Firmware functions
*/
static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -107,18 +156,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Device state switch handlers.
*/
-static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
- (state == STATE_RADIO_RX_ON) ||
- (state == STATE_RADIO_RX_ON_LINK));
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-}
-
static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
@@ -165,7 +202,8 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
* this limit so reduce the number to prevent errors.
*/
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
- ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
+ ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE)
+ / 1024) - 3);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
@@ -183,9 +221,9 @@ static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
if (state == STATE_AWAKE)
- rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2);
else
- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
return 0;
}
@@ -214,12 +252,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2800usb_disable_radio(rt2x00dev);
rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt2800usb_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -245,6 +277,49 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
}
/*
+ * Watchdog handlers
+ */
+static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
+ WARNING(rt2x00dev, "TX HW queue 0 timed out,"
+ " invoke forced kick\n");
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
+
+ for (i = 0; i < 10; i++) {
+ udelay(10);
+ if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q))
+ break;
+ }
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ }
+
+ rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
+ WARNING(rt2x00dev, "TX HW queue 1 timed out,"
+ " invoke forced kick\n");
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
+
+ for (i = 0; i < 10; i++) {
+ udelay(10);
+ if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q))
+ break;
+ }
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ }
+
+ rt2x00usb_watchdog(rt2x00dev);
+}
+
+/*
* TX descriptor initialization
*/
static __le32 *rt2800usb_get_txwi(struct queue_entry *entry)
@@ -266,8 +341,14 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
* Initialize TXINFO descriptor
*/
rt2x00_desc_read(txi, 0, &word);
+
+ /*
+ * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is
+ * TXWI + 802.11 header + L2 pad + payload + pad,
+ * so need to decrease size of TXINFO and USB end pad.
+ */
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
- entry->skb->len - TXINFO_DESC_SIZE);
+ entry->skb->len - TXINFO_DESC_SIZE - 4);
rt2x00_set_field32(&word, TXINFO_W0_WIV,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -285,22 +366,37 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
}
-/*
- * TX data initialization
- */
-static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+static void rt2800usb_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
{
- int length;
+ unsigned int len;
+ int err;
+
+ rt2800_write_tx_data(entry, txdesc);
/*
- * The length _must_ include 4 bytes padding,
- * it should always be multiple of 4,
- * but it must _not_ be a multiple of the USB packet size.
+ * pad(1~3 bytes) is added after each 802.11 payload.
+ * USB end pad(4 bytes) is added at each USB bulk out packet end.
+ * TX frame format is :
+ * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad |
+ * |<------------- tx_pkt_len ------------->|
*/
- length = roundup(entry->skb->len + 4, 4);
- length += (4 * !(length % entry->queue->usb_maxpacket));
+ len = roundup(entry->skb->len, 4) + 4;
+ err = skb_padto(entry->skb, len);
+ if (unlikely(err)) {
+ WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n");
+ return;
+ }
- return length;
+ entry->skb->len = len;
+}
+
+/*
+ * TX data initialization
+ */
+static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+{
+ return entry->skb->len;
}
/*
@@ -335,14 +431,6 @@ static void rt2800usb_work_txdone(struct work_struct *work)
}
}
-static void rt2800usb_kill_tx_queue(struct data_queue *queue)
-{
- if (queue->qid == QID_BEACON)
- rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
-
- rt2x00usb_kill_tx_queue(queue);
-}
-
/*
* RX control handlers
*/
@@ -507,6 +595,8 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
.get_tsf = rt2800_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.ampdu_action = rt2800_ampdu_action,
+ .flush = rt2x00mac_flush,
+ .get_survey = rt2800_get_survey,
};
static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -535,13 +625,15 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_stats = rt2800_link_stats,
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
- .watchdog = rt2x00usb_watchdog,
+ .watchdog = rt2800usb_watchdog,
+ .start_queue = rt2800usb_start_queue,
+ .kick_queue = rt2x00usb_kick_queue,
+ .stop_queue = rt2800usb_stop_queue,
+ .flush_queue = rt2x00usb_flush_queue,
.write_tx_desc = rt2800usb_write_tx_desc,
- .write_tx_data = rt2800_write_tx_data,
+ .write_tx_data = rt2800usb_write_tx_data,
.write_beacon = rt2800_write_beacon,
.get_tx_data_len = rt2800usb_get_tx_data_len,
- .kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2800usb_kill_tx_queue,
.fill_rxdone = rt2800usb_fill_rxdone,
.config_shared_key = rt2800_config_shared_key,
.config_pairwise_key = rt2800_config_pairwise_key,
@@ -553,21 +645,21 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
};
static const struct data_queue_desc rt2800usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 128,
.data_size = AGGREGATION_SIZE,
.desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2800usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 64,
.data_size = AGGREGATION_SIZE,
.desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2800usb_queue_bcn = {
- .entry_num = 8 * BEACON_ENTRIES,
+ .entry_num = 8,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
@@ -599,11 +691,19 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Abocom */
{ USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AirTies */
+ { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Allwin */
{ USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Amit */
{ USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Askey */
@@ -612,8 +712,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
/* AzureWave */
{ USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Belkin */
{ USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -624,6 +729,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -632,17 +738,36 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
/* D-Link */
{ USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Draytek */
+ { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Edimax */
+ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Encore */
+ { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
/* EnGenius */
{ USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Gigabyte */
{ USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Hawking */
{ USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -651,6 +776,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* I-O DATA */
+ { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Linksys */
{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -658,17 +787,44 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Motorola */
{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
/* MSI */
+ { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Para */
+ { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Pegatron */
+ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Philips */
{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Planex */
+ { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Quanta */
+ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Ralink */
+ { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Samsung */
{ USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Siemens */
@@ -681,13 +837,22 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
/* SMC */
{ USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sparklan */
{ USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -701,101 +866,16 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zyxel */
{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
-#ifdef CONFIG_RT2800USB_RT30XX
- /* Abocom */
- { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* AirTies */
- { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Allwin */
- { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* ASUS */
- { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* AzureWave */
- { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Corega */
- { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* D-Link */
- { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Draytek */
- { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Edimax */
- { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Encore */
- { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* EnGenius */
- { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Gigabyte */
- { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* I-O DATA */
- { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Logitec */
- { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* MSI */
- { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Para */
- { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Pegatron */
- { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Planex */
- { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Quanta */
- { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+#ifdef CONFIG_RT2800USB_RT33XX
/* Ralink */
- { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* SMC */
- { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Zinwell */
- { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif
#ifdef CONFIG_RT2800USB_RT35XX
/* Allwin */
@@ -809,12 +889,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* I-O DATA */
{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Ralink */
- { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sitecom */
{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 0722badccf86..671ea3592610 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -40,8 +40,8 @@
/*
* DMA descriptor defines.
*/
-#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
-#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
+#define TXINFO_DESC_SIZE (1 * sizeof(__le32))
+#define RXINFO_DESC_SIZE (1 * sizeof(__le32))
/*
* TX Info structure
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 94fe589acfaa..84aaf393da43 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -66,7 +66,7 @@
#ifdef CONFIG_RT2X00_DEBUG
#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
- DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args);
+ DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args)
#else
#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
do { } while (0)
@@ -347,6 +347,10 @@ struct link {
struct delayed_work watchdog_work;
};
+enum rt2x00_delayed_flags {
+ DELAYED_UPDATE_BEACON,
+};
+
/*
* Interface structure
* Per interface configuration details, this structure
@@ -354,22 +358,6 @@ struct link {
*/
struct rt2x00_intf {
/*
- * All fields within the rt2x00_intf structure
- * must be protected with a spinlock.
- */
- spinlock_t lock;
-
- /*
- * MAC of the device.
- */
- u8 mac[ETH_ALEN];
-
- /*
- * BBSID of the AP to associate with.
- */
- u8 bssid[ETH_ALEN];
-
- /*
* beacon->skb must be protected with the mutex.
*/
struct mutex beacon_skb_mutex;
@@ -384,8 +372,7 @@ struct rt2x00_intf {
/*
* Actions that needed rescheduling.
*/
- unsigned int delayed_flags;
-#define DELAYED_UPDATE_BEACON 0x00000001
+ unsigned long delayed_flags;
/*
* Software sequence counter, this is only required
@@ -567,7 +554,15 @@ struct rt2x00lib_ops {
struct link_qual *qual);
void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
struct link_qual *qual, const u32 count);
+
+ /*
+ * Data queue handlers.
+ */
void (*watchdog) (struct rt2x00_dev *rt2x00dev);
+ void (*start_queue) (struct data_queue *queue);
+ void (*kick_queue) (struct data_queue *queue);
+ void (*stop_queue) (struct data_queue *queue);
+ void (*flush_queue) (struct data_queue *queue);
/*
* TX control handlers
@@ -579,8 +574,6 @@ struct rt2x00lib_ops {
void (*write_beacon) (struct queue_entry *entry,
struct txentry_desc *txdesc);
int (*get_tx_data_len) (struct queue_entry *entry);
- void (*kick_tx_queue) (struct data_queue *queue);
- void (*kill_tx_queue) (struct data_queue *queue);
/*
* RX control handlers
@@ -664,6 +657,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_COPY_IV,
DRIVER_REQUIRE_L2PAD,
DRIVER_REQUIRE_TXSTATUS_FIFO,
+ DRIVER_REQUIRE_TASKLET_CONTEXT,
/*
* Driver features
@@ -901,7 +895,7 @@ struct rt2x00_dev {
/*
* FIFO for storing tx status reports between isr and tasklet.
*/
- struct kfifo txstatus_fifo;
+ DECLARE_KFIFO_PTR(txstatus_fifo, u32);
/*
* Tasklet for processing tx status reports (rt2800pci).
@@ -915,7 +909,7 @@ struct rt2x00_dev {
* in those cases REGISTER_BUSY_COUNT attempts should be
* taken with a REGISTER_BUSY_DELAY interval.
*/
-#define REGISTER_BUSY_COUNT 5
+#define REGISTER_BUSY_COUNT 100
#define REGISTER_BUSY_DELAY 100
/*
@@ -1067,6 +1061,78 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
enum queue_index index);
+/**
+ * rt2x00queue_pause_queue - Pause a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will pause the data queue locally, preventing
+ * new frames to be added to the queue (while the hardware is
+ * still allowed to run).
+ */
+void rt2x00queue_pause_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_unpause_queue - unpause a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will unpause the data queue locally, allowing
+ * new frames to be added to the queue again.
+ */
+void rt2x00queue_unpause_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_start_queue - Start a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will start handling all pending frames in the queue.
+ */
+void rt2x00queue_start_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_stop_queue - Halt a data queue
+ * @queue: Pointer to &struct data_queue.
+ *
+ * This function will stop all pending frames in the queue.
+ */
+void rt2x00queue_stop_queue(struct data_queue *queue);
+
+/**
+ * rt2x00queue_flush_queue - Flush a data queue
+ * @queue: Pointer to &struct data_queue.
+ * @drop: True to drop all pending frames.
+ *
+ * This function will flush the queue. After this call
+ * the queue is guarenteed to be empty.
+ */
+void rt2x00queue_flush_queue(struct data_queue *queue, bool drop);
+
+/**
+ * rt2x00queue_start_queues - Start all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to start them
+ */
+void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00queue_stop_queues - Halt all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to stop
+ * any pending frames.
+ */
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00queue_flush_queues - Flush all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @drop: True to drop all pending frames.
+ *
+ * This function will loop through all available queues to flush
+ * any pending frames.
+ */
+void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
+
/*
* Debugfs handlers.
*/
@@ -1092,6 +1158,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_dmastart(struct queue_entry *entry);
void rt2x00lib_dmadone(struct queue_entry *entry);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
@@ -1133,6 +1200,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
+void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
/*
* Driver allocation handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 54ffb5aeb34e..e7f67d5eda52 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -62,13 +62,13 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
* This will prevent the device being confused when it wants
* to ACK frames or consideres itself associated.
*/
- memset(&conf.mac, 0, sizeof(conf.mac));
+ memset(conf.mac, 0, sizeof(conf.mac));
if (mac)
- memcpy(&conf.mac, mac, ETH_ALEN);
+ memcpy(conf.mac, mac, ETH_ALEN);
- memset(&conf.bssid, 0, sizeof(conf.bssid));
+ memset(conf.bssid, 0, sizeof(conf.bssid));
if (bssid)
- memcpy(&conf.bssid, bssid, ETH_ALEN);
+ memcpy(conf.bssid, bssid, ETH_ALEN);
flags |= CONFIG_UPDATE_TYPE;
if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
@@ -133,7 +133,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
*/
if (!(ant->flags & ANTENNA_RX_DIVERSITY))
config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
- else if(config.rx == ANTENNA_SW_DIVERSITY)
+ else if (config.rx == ANTENNA_SW_DIVERSITY)
config.rx = active->rx;
if (!(ant->flags & ANTENNA_TX_DIVERSITY))
@@ -146,7 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* else the changes will be ignored by the device.
*/
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
+ rt2x00queue_stop_queue(rt2x00dev->rx);
/*
* Write new antenna setup to device and reset the link tuner.
@@ -160,7 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
memcpy(active, &config, sizeof(config));
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
+ rt2x00queue_start_queue(rt2x00dev->rx);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index fcdb6b0dc40f..c92db3264741 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -162,11 +162,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
struct timeval timestamp;
u32 data_len;
- do_gettimeofday(&timestamp);
-
- if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
+ if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
return;
+ do_gettimeofday(&timestamp);
+
if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
return;
@@ -339,18 +339,19 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
return -ENOMEM;
temp = data +
- sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
+ sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
queue_for_each(intf->rt2x00dev, queue) {
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
- temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
+ temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
+ queue->qid, (unsigned int)queue->flags,
queue->count, queue->limit, queue->length,
queue->index[Q_INDEX],
queue->index[Q_INDEX_DMA_DONE],
queue->index[Q_INDEX_DONE]);
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
size = strlen(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5ba79b935f09..9597a03242cc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -66,20 +66,16 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
/*
- * Enable RX.
+ * Enable queues.
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ rt2x00queue_start_queues(rt2x00dev);
+ rt2x00link_start_tuner(rt2x00dev);
/*
* Start watchdog monitoring.
*/
rt2x00link_start_watchdog(rt2x00dev);
- /*
- * Start the TX queues.
- */
- ieee80211_wake_queues(rt2x00dev->hw);
-
return 0;
}
@@ -89,20 +85,16 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Stop the TX queues in mac80211.
- */
- ieee80211_stop_queues(rt2x00dev->hw);
- rt2x00queue_stop_queues(rt2x00dev);
-
- /*
* Stop watchdog monitoring.
*/
rt2x00link_stop_watchdog(rt2x00dev);
/*
- * Disable RX.
+ * Stop all queues
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2x00link_stop_tuner(rt2x00dev);
+ rt2x00queue_stop_queues(rt2x00dev);
+ rt2x00queue_flush_queues(rt2x00dev, true);
/*
* Disable radio.
@@ -113,41 +105,11 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00leds_led_radio(rt2x00dev, false);
}
-void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
-{
- /*
- * When we are disabling the RX, we should also stop the link tuner.
- */
- if (state == STATE_RADIO_RX_OFF)
- rt2x00link_stop_tuner(rt2x00dev);
-
- rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
-
- /*
- * When we are enabling the RX, we should also start the link tuner.
- */
- if (state == STATE_RADIO_RX_ON)
- rt2x00link_start_tuner(rt2x00dev);
-}
-
static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
struct rt2x00_dev *rt2x00dev = data;
struct rt2x00_intf *intf = vif_to_intf(vif);
- int delayed_flags;
-
- /*
- * Copy all data we need during this action under the protection
- * of a spinlock. Otherwise race conditions might occur which results
- * into an invalid configuration.
- */
- spin_lock(&intf->lock);
-
- delayed_flags = intf->delayed_flags;
- intf->delayed_flags = 0;
-
- spin_unlock(&intf->lock);
/*
* It is possible the radio was disabled while the work had been
@@ -158,7 +120,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
return;
- if (delayed_flags & DELAYED_UPDATE_BEACON)
+ if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
rt2x00queue_update_beacon(rt2x00dev, vif, true);
}
@@ -251,8 +213,16 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
+void rt2x00lib_dmastart(struct queue_entry *entry)
+{
+ set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
+
void rt2x00lib_dmadone(struct queue_entry *entry)
{
+ set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
}
@@ -264,11 +234,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+ unsigned int header_length, i;
u8 rate_idx, rate_flags, retry_rates;
u8 skbdesc_flags = skbdesc->flags;
- unsigned int i;
bool success;
/*
@@ -287,6 +255,11 @@ void rt2x00lib_txdone(struct queue_entry *entry,
skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
/*
+ * Determine the length of 802.11 header.
+ */
+ header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+
+ /*
* Remove L2 padding which was added during
*/
if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
@@ -390,9 +363,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* through a mac80211 library call (RTS/CTS) then we should not
* send the status report back.
*/
- if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
- ieee80211_tx_status(rt2x00dev->hw, entry->skb);
- else
+ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
+ if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ else
+ ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
+ } else
dev_kfree_skb_any(entry->skb);
/*
@@ -411,7 +387,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* is reenabled when the txdone handler has finished.
*/
if (!rt2x00queue_threshold(entry->queue))
- ieee80211_wake_queue(rt2x00dev->hw, qid);
+ rt2x00queue_unpause_queue(entry->queue);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
@@ -483,6 +459,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
unsigned int header_length;
int rate_idx;
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
+ !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ goto submit_entry;
+
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
goto submit_entry;
@@ -567,9 +547,11 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
entry->skb = skb;
submit_entry:
- rt2x00dev->ops->lib->clear_entry(entry);
- rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ entry->flags = 0;
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ rt2x00dev->ops->lib->clear_entry(entry);
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
@@ -678,7 +660,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry,
{
entry->flags = 0;
entry->bitrate = rate->bitrate;
- entry->hw_value =index;
+ entry->hw_value = index;
entry->hw_value_short = index;
if (rate->flags & DEV_RATE_SHORT_PREAMBLE)
@@ -818,8 +800,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* Allocate tx status FIFO for driver use.
*/
- if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) &&
- rt2x00dev->ops->lib->txstatus_tasklet) {
+ if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) {
/*
* Allocate txstatus fifo and tasklet, we use a size of 512
* for the kfifo which is big enough to store 512/4=128 tx
@@ -833,9 +814,10 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
return status;
/* tasklet for processing the tx status reports. */
- tasklet_init(&rt2x00dev->txstatus_tasklet,
- rt2x00dev->ops->lib->txstatus_tasklet,
- (unsigned long)rt2x00dev);
+ if (rt2x00dev->ops->lib->txstatus_tasklet)
+ tasklet_init(&rt2x00dev->txstatus_tasklet,
+ rt2x00dev->ops->lib->txstatus_tasklet,
+ (unsigned long)rt2x00dev);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index c637bcaec5f8..b7ad46ecaa1d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -40,8 +40,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
if (tx_info->control.sta)
txdesc->mpdu_density =
tx_info->control.sta->ht_cap.ampdu_density;
- else
- txdesc->mpdu_density = 0;
txdesc->ba_size = 7; /* FIXME: What value is needed? */
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 619da23b7b56..a105c500627b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -57,7 +57,7 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
}
#define RATE_MCS(__mode, __mcs) \
- ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
+ ((((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff))
static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
{
@@ -69,7 +69,6 @@ static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
*/
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
-void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
/*
* Initialization handlers.
@@ -179,15 +178,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
/**
- * rt2x00queue_stop_queues - Halt all data queues
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- *
- * This function will loop through all available queues to stop
- * any pending outgoing frames.
- */
-void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
-
-/**
* rt2x00queue_init_queues - Initialize all data queues
* @rt2x00dev: Pointer to &struct rt2x00_dev.
*
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index b971d8798ebf..bfda60eaf4ef 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -67,7 +67,7 @@
(__avg).avg_weight ? \
((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \
((__val) * (AVG_FACTOR))) / \
- (AVG_SAMPLES) ) : \
+ (AVG_SAMPLES)) : \
((__val) * (AVG_FACTOR)); \
__new.avg = __new.avg_weight / (AVG_FACTOR); \
__new; \
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c3c206a97d54..658542d2efe1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -104,7 +104,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct rt2x00_dev *rt2x00dev = hw->priv;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
enum data_queue_qid qid = skb_get_queue_mapping(skb);
- struct data_queue *queue;
+ struct data_queue *queue = NULL;
/*
* Mac80211 might be calling this function while we are trying
@@ -153,7 +153,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
goto exit_fail;
if (rt2x00queue_threshold(queue))
- ieee80211_stop_queue(rt2x00dev->hw, qid);
+ rt2x00queue_pause_queue(queue);
return NETDEV_TX_OK;
@@ -268,7 +268,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
else
rt2x00dev->intf_sta_count++;
- spin_lock_init(&intf->lock);
spin_lock_init(&intf->seqlock);
mutex_init(&intf->beacon_skb_mutex);
intf->beacon = entry;
@@ -282,15 +281,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
* STA interfaces at this time, since this can cause
* invalid behavior in the device.
*/
- memcpy(&intf->mac, vif->addr, ETH_ALEN);
- if (vif->type == NL80211_IFTYPE_AP) {
- memcpy(&intf->bssid, vif->addr, ETH_ALEN);
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
- intf->mac, intf->bssid);
- } else {
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
- intf->mac, NULL);
- }
+ rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
+ vif->addr, NULL);
/*
* Some filters depend on the current working mode. We can force
@@ -358,7 +350,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
* if for any reason the link tuner must be reset, this will be
* handled by rt2x00lib_config().
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
+ rt2x00queue_stop_queue(rt2x00dev->rx);
/*
* When we've just turned on the radio, we want to reprogram
@@ -376,7 +368,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
/* Turn RX back on */
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
+ rt2x00queue_start_queue(rt2x00dev->rx);
return 0;
}
@@ -451,9 +443,7 @@ static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
vif->type != NL80211_IFTYPE_WDS)
return;
- spin_lock(&intf->lock);
- intf->delayed_flags |= DELAYED_UPDATE_BEACON;
- spin_unlock(&intf->lock);
+ set_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags);
}
int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
@@ -478,17 +468,17 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
{
if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
- memcpy(&crypto->key,
+ memcpy(crypto->key,
&key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
sizeof(crypto->key));
if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
- memcpy(&crypto->tx_mic,
+ memcpy(crypto->tx_mic,
&key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
sizeof(crypto->tx_mic));
if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
- memcpy(&crypto->rx_mic,
+ memcpy(crypto->rx_mic,
&key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
sizeof(crypto->rx_mic));
}
@@ -498,7 +488,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(vif);
int (*set_key) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key);
@@ -522,7 +511,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (rt2x00dev->intf_sta_count)
crypto.bssidx = 0;
else
- crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1);
+ crypto.bssidx = vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1);
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
@@ -540,7 +529,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (crypto.cipher == CIPHER_TKIP)
memcpy_tkip(&crypto, &key->key[0], key->keylen);
else
- memcpy(&crypto.key, &key->key[0], key->keylen);
+ memcpy(crypto.key, &key->key[0], key->keylen);
/*
* Each BSS has a maximum of 4 shared keys.
* Shared key index values:
@@ -620,22 +609,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return;
- spin_lock(&intf->lock);
-
/*
- * conf->bssid can be NULL if coming from the internal
- * beacon update routine.
- */
- if (changes & BSS_CHANGED_BSSID)
- memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
-
- spin_unlock(&intf->lock);
-
- /*
- * Call rt2x00_config_intf() outside of the spinlock context since
- * the call will sleep for USB drivers. By using the ieee80211_if_conf
- * values as arguments we make keep access to rt2x00_intf thread safe
- * even without the lock.
+ * Update the BSSID.
*/
if (changes & BSS_CHANGED_BSSID)
rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
@@ -719,3 +694,13 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
wiphy_rfkill_set_hw_state(hw->wiphy, !active);
}
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
+
+void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct data_queue *queue;
+
+ tx_queue_for_each(rt2x00dev, queue)
+ rt2x00queue_flush_queue(queue, drop);
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_flush);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 2449d785cf8d..ace0b668c04e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -82,6 +82,13 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
skbdesc->desc_len = entry->queue->desc_size;
/*
+ * DMA is already done, notify rt2x00lib that
+ * it finished successfully.
+ */
+ rt2x00lib_dmastart(entry);
+ rt2x00lib_dmadone(entry);
+
+ /*
* Send the frame to rt2x00lib for further processing.
*/
rt2x00lib_rxdone(entry);
@@ -105,7 +112,7 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
*/
addr = dma_alloc_coherent(rt2x00dev->dev,
queue->limit * queue->desc_size,
- &dma, GFP_KERNEL | GFP_DMA);
+ &dma, GFP_KERNEL);
if (!addr)
return -ENOMEM;
@@ -279,7 +286,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
rt2x00dev->irq = pci_dev->irq;
rt2x00dev->name = pci_name(pci_dev);
- if (pci_dev->is_pcie)
+ if (pci_is_pcie(pci_dev))
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
else
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
@@ -356,12 +363,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
struct rt2x00_dev *rt2x00dev = hw->priv;
if (pci_set_power_state(pci_dev, PCI_D0) ||
- pci_enable_device(pci_dev) ||
- pci_restore_state(pci_dev)) {
+ pci_enable_device(pci_dev)) {
ERROR(rt2x00dev, "Failed to resume device.\n");
return -EIO;
}
+ pci_restore_state(pci_dev);
return rt2x00lib_resume(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00pci_resume);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index b854d62ff99b..746ce8fe8cf4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -64,7 +64,7 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const void *value,
const u32 length)
{
- memcpy_toio(rt2x00dev->csr.base + offset, value, length);
+ __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
}
/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e360d287defb..ca82b3a91697 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -199,7 +199,12 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
{
- unsigned int l2pad = L2PAD_SIZE(header_length);
+ /*
+ * L2 padding is only present if the skb contains more than just the
+ * IEEE 802.11 header.
+ */
+ unsigned int l2pad = (skb->len > header_length) ?
+ L2PAD_SIZE(header_length) : 0;
if (!l2pad)
return;
@@ -311,14 +316,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
memset(txdesc, 0, sizeof(*txdesc));
/*
- * Initialize information from queue
- */
- txdesc->qid = entry->queue->qid;
- txdesc->cw_min = entry->queue->cw_min;
- txdesc->cw_max = entry->queue->cw_max;
- txdesc->aifs = entry->queue->aifs;
-
- /*
* Header and frame information.
*/
txdesc->length = entry->skb->len;
@@ -460,12 +457,9 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
-static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
+static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
struct txentry_desc *txdesc)
{
- struct data_queue *queue = entry->queue;
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-
/*
* Check if we need to kick the queue, there are however a few rules
* 1) Don't kick unless this is the last in frame in a burst.
@@ -477,7 +471,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
*/
if (rt2x00queue_threshold(queue) ||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
- rt2x00dev->ops->lib->kick_tx_queue(queue);
+ queue->rt2x00dev->ops->lib->kick_queue(queue);
}
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -567,7 +561,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
rt2x00queue_index_inc(queue, Q_INDEX);
rt2x00queue_write_tx_descriptor(entry, &txdesc);
- rt2x00queue_kick_tx_queue(entry, &txdesc);
+ rt2x00queue_kick_tx_queue(queue, &txdesc);
return 0;
}
@@ -591,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
rt2x00queue_free_skb(intf->beacon);
if (!enable_beacon) {
- rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
+ rt2x00queue_stop_queue(intf->beacon->queue);
mutex_unlock(&intf->beacon_skb_mutex);
return 0;
}
@@ -649,10 +643,10 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
* it should not be kicked during this run, since it
* is part of another TX operation.
*/
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
index_start = queue->index[start];
index_end = queue->index[end];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
/*
* Start from the TX done pointer, this guarentees that we will
@@ -706,11 +700,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
return NULL;
}
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
entry = &queue->entries[queue->index[index]];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
return entry;
}
@@ -726,7 +720,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
return;
}
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
queue->index[index]++;
if (queue->index[index] >= queue->limit)
@@ -741,15 +735,219 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
queue->count++;
}
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
+void rt2x00queue_pause_queue(struct data_queue *queue)
+{
+ if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+ !test_bit(QUEUE_STARTED, &queue->flags) ||
+ test_and_set_bit(QUEUE_PAUSED, &queue->flags))
+ return;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ /*
+ * For TX queues, we have to disable the queue
+ * inside mac80211.
+ */
+ ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
+
+void rt2x00queue_unpause_queue(struct data_queue *queue)
+{
+ if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+ !test_bit(QUEUE_STARTED, &queue->flags) ||
+ !test_and_clear_bit(QUEUE_PAUSED, &queue->flags))
+ return;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ /*
+ * For TX queues, we have to enable the queue
+ * inside mac80211.
+ */
+ ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
+ break;
+ case QID_RX:
+ /*
+ * For RX we need to kick the queue now in order to
+ * receive frames.
+ */
+ queue->rt2x00dev->ops->lib->kick_queue(queue);
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_unpause_queue);
+
+void rt2x00queue_start_queue(struct data_queue *queue)
+{
+ mutex_lock(&queue->status_lock);
+
+ if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+ test_and_set_bit(QUEUE_STARTED, &queue->flags)) {
+ mutex_unlock(&queue->status_lock);
+ return;
+ }
+
+ set_bit(QUEUE_PAUSED, &queue->flags);
+
+ queue->rt2x00dev->ops->lib->start_queue(queue);
+
+ rt2x00queue_unpause_queue(queue);
+
+ mutex_unlock(&queue->status_lock);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_start_queue);
+
+void rt2x00queue_stop_queue(struct data_queue *queue)
+{
+ mutex_lock(&queue->status_lock);
+
+ if (!test_and_clear_bit(QUEUE_STARTED, &queue->flags)) {
+ mutex_unlock(&queue->status_lock);
+ return;
+ }
+
+ rt2x00queue_pause_queue(queue);
+
+ queue->rt2x00dev->ops->lib->stop_queue(queue);
+
+ mutex_unlock(&queue->status_lock);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
+
+void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
+{
+ unsigned int i;
+ bool started;
+ bool tx_queue =
+ (queue->qid == QID_AC_VO) ||
+ (queue->qid == QID_AC_VI) ||
+ (queue->qid == QID_AC_BE) ||
+ (queue->qid == QID_AC_BK);
+
+ mutex_lock(&queue->status_lock);
+
+ /*
+ * If the queue has been started, we must stop it temporarily
+ * to prevent any new frames to be queued on the device. If
+ * we are not dropping the pending frames, the queue must
+ * only be stopped in the software and not the hardware,
+ * otherwise the queue will never become empty on its own.
+ */
+ started = test_bit(QUEUE_STARTED, &queue->flags);
+ if (started) {
+ /*
+ * Pause the queue
+ */
+ rt2x00queue_pause_queue(queue);
+
+ /*
+ * If we are not supposed to drop any pending
+ * frames, this means we must force a start (=kick)
+ * to the queue to make sure the hardware will
+ * start transmitting.
+ */
+ if (!drop && tx_queue)
+ queue->rt2x00dev->ops->lib->kick_queue(queue);
+ }
+
+ /*
+ * Check if driver supports flushing, we can only guarentee
+ * full support for flushing if the driver is able
+ * to cancel all pending frames (drop = true).
+ */
+ if (drop && queue->rt2x00dev->ops->lib->flush_queue)
+ queue->rt2x00dev->ops->lib->flush_queue(queue);
+
+ /*
+ * When we don't want to drop any frames, or when
+ * the driver doesn't fully flush the queue correcly,
+ * we must wait for the queue to become empty.
+ */
+ for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
+ msleep(10);
+
+ /*
+ * The queue flush has failed...
+ */
+ if (unlikely(!rt2x00queue_empty(queue)))
+ WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid);
+
+ /*
+ * Restore the queue to the previous status
+ */
+ if (started)
+ rt2x00queue_unpause_queue(queue);
+
+ mutex_unlock(&queue->status_lock);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
+
+void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ /*
+ * rt2x00queue_start_queue will call ieee80211_wake_queue
+ * for each queue after is has been properly initialized.
+ */
+ tx_queue_for_each(rt2x00dev, queue)
+ rt2x00queue_start_queue(queue);
+
+ rt2x00queue_start_queue(rt2x00dev->rx);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_start_queues);
+
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ /*
+ * rt2x00queue_stop_queue will call ieee80211_stop_queue
+ * as well, but we are completely shutting doing everything
+ * now, so it is much safer to stop all TX queues at once,
+ * and use rt2x00queue_stop_queue for cleaning up.
+ */
+ ieee80211_stop_queues(rt2x00dev->hw);
+
+ tx_queue_for_each(rt2x00dev, queue)
+ rt2x00queue_stop_queue(queue);
+
+ rt2x00queue_stop_queue(rt2x00dev->rx);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues);
+
+void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop)
+{
+ struct data_queue *queue;
+
+ tx_queue_for_each(rt2x00dev, queue)
+ rt2x00queue_flush_queue(queue, drop);
+
+ rt2x00queue_flush_queue(rt2x00dev->rx, drop);
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues);
+
static void rt2x00queue_reset(struct data_queue *queue)
{
unsigned long irqflags;
unsigned int i;
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
queue->count = 0;
queue->length = 0;
@@ -759,15 +957,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
queue->last_action[i] = jiffies;
}
- spin_unlock_irqrestore(&queue->lock, irqflags);
-}
-
-void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
-
- txall_queue_for_each(rt2x00dev, queue)
- rt2x00dev->ops->lib->kill_tx_queue(queue);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -778,11 +968,8 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
queue_for_each(rt2x00dev, queue) {
rt2x00queue_reset(queue);
- for (i = 0; i < queue->limit; i++) {
+ for (i = 0; i < queue->limit; i++)
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
- if (queue->qid == QID_RX)
- rt2x00queue_index_inc(queue, Q_INDEX);
- }
}
}
@@ -809,8 +996,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
return -ENOMEM;
#define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \
- ( ((char *)(__base)) + ((__limit) * (__esize)) + \
- ((__index) * (__psize)) )
+ (((char *)(__base)) + ((__limit) * (__esize)) + \
+ ((__index) * (__psize)))
for (i = 0; i < queue->limit; i++) {
entries[i].flags = 0;
@@ -911,7 +1098,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue, enum data_queue_qid qid)
{
- spin_lock_init(&queue->lock);
+ mutex_init(&queue->status_lock);
+ spin_lock_init(&queue->index_lock);
queue->rt2x00dev = rt2x00dev;
queue->qid = qid;
@@ -953,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
/*
* Initialize queue parameters.
* RX: qid = QID_RX
- * TX: qid = QID_AC_BE + index
+ * TX: qid = QID_AC_VO + index
* TX: cw_min: 2^5 = 32.
* TX: cw_max: 2^10 = 1024.
* BCN: qid = QID_BEACON
@@ -961,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
*/
rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
- qid = QID_AC_BE;
+ qid = QID_AC_VO;
tx_queue_for_each(rt2x00dev, queue)
rt2x00queue_init(rt2x00dev, queue, qid++);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index d81d85f34866..fab8e2687f29 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -43,28 +43,12 @@
#define AGGREGATION_SIZE 3840
/**
- * DOC: Number of entries per queue
- *
- * Under normal load without fragmentation, 12 entries are sufficient
- * without the queue being filled up to the maximum. When using fragmentation
- * and the queue threshold code, we need to add some additional margins to
- * make sure the queue will never (or only under extreme load) fill up
- * completely.
- * Since we don't use preallocated DMA, having a large number of queue entries
- * will have minimal impact on the memory requirements for the queue.
- */
-#define RX_ENTRIES 24
-#define TX_ENTRIES 24
-#define BEACON_ENTRIES 1
-#define ATIM_ENTRIES 8
-
-/**
* enum data_queue_qid: Queue identification
*
+ * @QID_AC_VO: AC VO queue
+ * @QID_AC_VI: AC VI queue
* @QID_AC_BE: AC BE queue
* @QID_AC_BK: AC BK queue
- * @QID_AC_VI: AC VI queue
- * @QID_AC_VO: AC VO queue
* @QID_HCCA: HCCA queue
* @QID_MGMT: MGMT queue (prio queue)
* @QID_RX: RX queue
@@ -73,10 +57,10 @@
* @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
*/
enum data_queue_qid {
- QID_AC_BE = 0,
- QID_AC_BK = 1,
- QID_AC_VI = 2,
- QID_AC_VO = 3,
+ QID_AC_VO = 0,
+ QID_AC_VI = 1,
+ QID_AC_BE = 2,
+ QID_AC_BK = 3,
QID_HCCA = 4,
QID_MGMT = 13,
QID_RX = 14,
@@ -296,7 +280,6 @@ enum txentry_desc_flags {
* Summary of information for the frame descriptor before sending a TX frame.
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
- * @qid: Queue identification (See &enum data_queue_qid).
* @length: Length of the entire frame.
* @header_length: Length of 802.11 header.
* @length_high: PLCP length high word.
@@ -309,11 +292,8 @@ enum txentry_desc_flags {
* @rate_mode: Rate mode (See @enum rate_modulation).
* @mpdu_density: MDPU density.
* @retry_limit: Max number of retries.
- * @aifs: AIFS value.
* @ifs: IFS value.
* @txop: IFS value for 11n capable chips.
- * @cw_min: cwmin value.
- * @cw_max: cwmax value.
* @cipher: Cipher type used for encryption.
* @key_idx: Key index used for encryption.
* @iv_offset: Position where IV should be inserted by hardware.
@@ -322,8 +302,6 @@ enum txentry_desc_flags {
struct txentry_desc {
unsigned long flags;
- enum data_queue_qid qid;
-
u16 length;
u16 header_length;
@@ -339,11 +317,8 @@ struct txentry_desc {
u16 mpdu_density;
short retry_limit;
- short aifs;
short ifs;
short txop;
- short cw_min;
- short cw_max;
enum cipher cipher;
u16 key_idx;
@@ -365,12 +340,16 @@ struct txentry_desc {
* @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
* while transfering the data to the hardware. No TX status report will
* be expected from the hardware.
+ * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
+ * returned. It is now waiting for the status reporting before the
+ * entry can be reused again.
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
ENTRY_OWNER_DEVICE_DATA,
ENTRY_DATA_PENDING,
- ENTRY_DATA_IO_FAILED
+ ENTRY_DATA_IO_FAILED,
+ ENTRY_DATA_STATUS_PENDING,
};
/**
@@ -417,13 +396,33 @@ enum queue_index {
};
/**
+ * enum data_queue_flags: Status flags for data queues
+ *
+ * @QUEUE_STARTED: The queue has been started. Fox RX queues this means the
+ * device might be DMA'ing skbuffers. TX queues will accept skbuffers to
+ * be transmitted and beacon queues will start beaconing the configured
+ * beacons.
+ * @QUEUE_PAUSED: The queue has been started but is currently paused.
+ * When this bit is set, the queue has been stopped in mac80211,
+ * preventing new frames to be enqueued. However, a few frames
+ * might still appear shortly after the pausing...
+ */
+enum data_queue_flags {
+ QUEUE_STARTED,
+ QUEUE_PAUSED,
+};
+
+/**
* struct data_queue: Data queue
*
* @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to.
* @entries: Base address of the &struct queue_entry which are
* part of this queue.
* @qid: The queue identification, see &enum data_queue_qid.
- * @lock: Spinlock to protect index handling. Whenever @index, @index_done or
+ * @flags: Entry flags, see &enum queue_entry_flags.
+ * @status_lock: The mutex for protecting the start/stop/flush
+ * handling on this queue.
+ * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
* @index_crypt needs to be changed this lock should be grabbed to prevent
* index corruption due to concurrency.
* @count: Number of frames handled in the queue.
@@ -446,8 +445,11 @@ struct data_queue {
struct queue_entry *entries;
enum data_queue_qid qid;
+ unsigned long flags;
+
+ struct mutex status_lock;
+ spinlock_t index_lock;
- spinlock_t lock;
unsigned int count;
unsigned short limit;
unsigned short threshold;
@@ -618,10 +620,10 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
}
/**
- * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts
+ * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports
* @queue: Queue to check.
*/
-static inline int rt2x00queue_timeout(struct data_queue *queue)
+static inline int rt2x00queue_status_timeout(struct data_queue *queue)
{
return time_after(queue->last_action[Q_INDEX_DMA_DONE],
queue->last_action[Q_INDEX_DONE] + (HZ / 10));
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index cef94621cef7..e8259ae48ced 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -83,10 +83,6 @@ enum dev_state {
*/
STATE_RADIO_ON,
STATE_RADIO_OFF,
- STATE_RADIO_RX_ON,
- STATE_RADIO_RX_OFF,
- STATE_RADIO_RX_ON_LINK,
- STATE_RADIO_RX_OFF_LINK,
STATE_RADIO_IRQ_ON,
STATE_RADIO_IRQ_OFF,
STATE_RADIO_IRQ_ON_ISR,
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c
index fc98063de71d..2aa5c38022f3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
@@ -40,6 +40,8 @@ static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)
kfree(rt2x00dev->eeprom);
rt2x00dev->eeprom = NULL;
+
+ iounmap(rt2x00dev->csr.base);
}
static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
@@ -51,9 +53,9 @@ static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
if (!res)
return -ENODEV;
- rt2x00dev->csr.base = (void __iomem *)KSEG1ADDR(res->start);
+ rt2x00dev->csr.base = ioremap(res->start, resource_size(res));
if (!rt2x00dev->csr.base)
- goto exit;
+ return -ENOMEM;
rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
if (!rt2x00dev->eeprom)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index b3317df7a7d4..1a9937d5aff6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work)
while (!rt2x00queue_empty(queue)) {
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+ !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
break;
rt2x00usb_work_txdone_entry(entry);
@@ -226,9 +227,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
* Schedule the delayed work for reading the TX status
* from the device.
*/
- if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
}
static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -237,8 +236,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
u32 length;
+ int status;
- if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+ if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
+ test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
return;
/*
@@ -253,121 +254,15 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
entry->skb->data, length,
rt2x00usb_interrupt_txdone, entry);
- if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+ if (status == -ENODEV)
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
}
}
-void rt2x00usb_kick_tx_queue(struct data_queue *queue)
-{
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
- rt2x00usb_kick_tx_entry);
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
-
-static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
-{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
-
- if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
- return;
-
- usb_kill_urb(entry_priv->urb);
-
- /*
- * Kill guardian urb (if required by driver).
- */
- if ((entry->queue->qid == QID_BEACON) &&
- (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
- usb_kill_urb(bcn_priv->guardian_urb);
-}
-
-void rt2x00usb_kill_tx_queue(struct data_queue *queue)
-{
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
- rt2x00usb_kill_tx_entry);
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
-
-static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- unsigned short threshold = queue->threshold;
-
- WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
- " invoke forced forced reset", queue->qid);
-
- /*
- * Temporarily disable the TX queue, this will force mac80211
- * to use the other queues until this queue has been restored.
- *
- * Set the queue threshold to the queue limit. This prevents the
- * queue from being enabled during the txdone handler.
- */
- queue->threshold = queue->limit;
- ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
-
- /*
- * Kill all entries in the queue, afterwards we need to
- * wait a bit for all URBs to be cancelled.
- */
- rt2x00usb_kill_tx_queue(queue);
-
- /*
- * In case that a driver has overriden the txdone_work
- * function, we invoke the TX done through there.
- */
- rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
-
- /*
- * Security measure: if the driver did override the
- * txdone_work function, and the hardware did arrive
- * in a state which causes it to malfunction, it is
- * possible that the driver couldn't handle the txdone
- * event correctly. So after giving the driver the
- * chance to cleanup, we now force a cleanup of any
- * leftovers.
- */
- if (!rt2x00queue_empty(queue)) {
- WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
- " status handling failed, invoke hard reset", queue->qid);
- rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
- }
-
- /*
- * The queue has been reset, and mac80211 is allowed to use the
- * queue again.
- */
- queue->threshold = threshold;
- ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
-}
-
-static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
-{
- WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
- " invoke forced tx handler", queue->qid);
-
- ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
-}
-
-void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
-
- tx_queue_for_each(rt2x00dev, queue) {
- if (!rt2x00queue_empty(queue)) {
- if (rt2x00queue_dma_timeout(queue))
- rt2x00usb_watchdog_tx_dma(queue);
- if (rt2x00queue_timeout(queue))
- rt2x00usb_watchdog_tx_status(queue);
- }
- }
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
-
/*
* RX data handlers.
*/
@@ -382,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
while (!rt2x00queue_empty(rt2x00dev->rx)) {
entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+ !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
break;
/*
@@ -424,11 +320,157 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* Schedule the delayed work for reading the RX status
* from the device.
*/
- if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
}
+static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+ int status;
+
+ if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+ test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+ return;
+
+ rt2x00lib_dmastart(entry);
+
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+ usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
+ entry->skb->data, entry->skb->len,
+ rt2x00usb_interrupt_rxdone, entry);
+
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+ if (status == -ENODEV)
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+ rt2x00lib_dmadone(entry);
+ }
+}
+
+void rt2x00usb_kick_queue(struct data_queue *queue)
+{
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ if (!rt2x00queue_empty(queue))
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kick_tx_entry);
+ break;
+ case QID_RX:
+ if (!rt2x00queue_full(queue))
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kick_rx_entry);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
+
+static void rt2x00usb_flush_entry(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+ struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
+
+ if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ return;
+
+ usb_kill_urb(entry_priv->urb);
+
+ /*
+ * Kill guardian urb (if required by driver).
+ */
+ if ((entry->queue->qid == QID_BEACON) &&
+ (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
+ usb_kill_urb(bcn_priv->guardian_urb);
+}
+
+void rt2x00usb_flush_queue(struct data_queue *queue)
+{
+ struct work_struct *completion;
+ unsigned int i;
+
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_flush_entry);
+
+ /*
+ * Obtain the queue completion handler
+ */
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ completion = &queue->rt2x00dev->txdone_work;
+ break;
+ case QID_RX:
+ completion = &queue->rt2x00dev->rxdone_work;
+ break;
+ default:
+ return;
+ }
+
+ for (i = 0; i < 20; i++) {
+ /*
+ * Check if the driver is already done, otherwise we
+ * have to sleep a little while to give the driver/hw
+ * the oppurtunity to complete interrupt process itself.
+ */
+ if (rt2x00queue_empty(queue))
+ break;
+
+ /*
+ * Schedule the completion handler manually, when this
+ * worker function runs, it should cleanup the queue.
+ */
+ ieee80211_queue_work(queue->rt2x00dev->hw, completion);
+
+ /*
+ * Wait for a little while to give the driver
+ * the oppurtunity to recover itself.
+ */
+ msleep(10);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);
+
+static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
+{
+ WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
+ " invoke forced forced reset\n", queue->qid);
+
+ rt2x00queue_flush_queue(queue, true);
+}
+
+static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
+{
+ WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
+ " invoke forced tx handler\n", queue->qid);
+
+ ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
+}
+
+void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ tx_queue_for_each(rt2x00dev, queue) {
+ if (!rt2x00queue_empty(queue)) {
+ if (rt2x00queue_dma_timeout(queue))
+ rt2x00usb_watchdog_tx_dma(queue);
+ if (rt2x00queue_status_timeout(queue))
+ rt2x00usb_watchdog_tx_status(queue);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
+
/*
* Radio handlers
*/
@@ -436,12 +478,6 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
REGISTER_TIMEOUT);
-
- /*
- * The USB version of kill_tx_queue also works
- * on the RX queue.
- */
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
@@ -450,25 +486,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
*/
void rt2x00usb_clear_entry(struct queue_entry *entry)
{
- struct usb_device *usb_dev =
- to_usb_device_intf(entry->queue->rt2x00dev->dev);
- struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- int pipe;
-
entry->flags = 0;
- if (entry->queue->qid == QID_RX) {
- pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
- usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
- entry->skb->data, entry->skb->len,
- rt2x00usb_interrupt_rxdone, entry);
-
- set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
- set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
- rt2x00lib_dmadone(entry);
- }
- }
+ if (entry->queue->qid == QID_RX)
+ rt2x00usb_kick_rx_entry(entry);
}
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index c2d997f67b3e..6aaf51fc7ad8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -378,22 +378,22 @@ struct queue_entry_priv_usb_bcn {
};
/**
- * rt2x00usb_kick_tx_queue - Kick data queue
+ * rt2x00usb_kick_queue - Kick data queue
* @queue: Data queue to kick
*
* This will walk through all entries of the queue and push all pending
* frames to the hardware as a single burst.
*/
-void rt2x00usb_kick_tx_queue(struct data_queue *queue);
+void rt2x00usb_kick_queue(struct data_queue *queue);
/**
- * rt2x00usb_kill_tx_queue - Kill data queue
- * @queue: Data queue to kill
+ * rt2x00usb_flush_queue - Flush data queue
+ * @queue: Data queue to stop
*
* This will walk through all entries of the queue and kill all
- * previously kicked frames before they can be send.
+ * URB's which were send to the device.
*/
-void rt2x00usb_kill_tx_queue(struct data_queue *queue);
+void rt2x00usb_flush_queue(struct data_queue *queue);
/**
* rt2x00usb_watchdog - Watchdog for USB communication
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index af548c87f108..8de44dd401e0 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1140,6 +1140,106 @@ dynamic_cca_tune:
}
/*
+ * Queue handlers.
+ */
+static void rt61pci_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt61pci_kick_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_VI:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_BE:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_BK:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt61pci_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_VI:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_BE:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_AC_BK:
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ break;
+ case QID_RX:
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Firmware functions
*/
static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -1616,18 +1716,6 @@ static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
-}
-
static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
@@ -1744,12 +1832,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_RADIO_OFF:
rt61pci_disable_radio(rt2x00dev);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt61pci_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -1789,10 +1871,10 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
* Start writing the descriptor words.
*/
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
- rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -1820,7 +1902,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
- if (txdesc->qid != QID_BEACON) {
+ if (entry->queue->qid != QID_BEACON) {
rt2x00_desc_read(txd, 6, &word);
rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
skbdesc->skb_dma);
@@ -1866,8 +1948,8 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
* Register descriptor details in skb frame descriptor.
*/
skbdesc->desc = txd;
- skbdesc->desc_len =
- (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
+ skbdesc->desc_len = (entry->queue->qid == QID_BEACON) ? TXINFO_SIZE :
+ TXD_DESC_SIZE;
}
/*
@@ -1879,6 +1961,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
unsigned int beacon_base;
+ unsigned int padding_len;
u32 reg;
/*
@@ -1900,13 +1983,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Write entire beacon with descriptor to register.
+ * Write entire beacon with descriptor and padding to register.
*/
+ padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+ skb_pad(entry->skb, padding_len);
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
entry_priv->desc, TXINFO_SIZE);
rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
- entry->skb->data, entry->skb->len);
+ entry->skb->data,
+ entry->skb->len + padding_len);
/*
* Enable beaconing again.
@@ -1928,37 +2014,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
entry->skb = NULL;
}
-static void rt61pci_kick_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));
- rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
-}
-
-static void rt61pci_kill_tx_queue(struct data_queue *queue)
-{
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- u32 reg;
-
- if (queue->qid == QID_BEACON) {
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
- return;
- }
-
- rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));
- rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
-}
-
/*
* RX control handlers
*/
@@ -2078,7 +2133,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
* that the TX_STA_FIFO stack has a size of 16. We stick to our
* tx ring size for now.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
break;
@@ -2824,6 +2879,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.conf_tx = rt61pci_conf_tx,
.get_tsf = rt61pci_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -2842,10 +2898,11 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.link_stats = rt61pci_link_stats,
.reset_tuner = rt61pci_reset_tuner,
.link_tuner = rt61pci_link_tuner,
+ .start_queue = rt61pci_start_queue,
+ .kick_queue = rt61pci_kick_queue,
+ .stop_queue = rt61pci_stop_queue,
.write_tx_desc = rt61pci_write_tx_desc,
.write_beacon = rt61pci_write_beacon,
- .kick_tx_queue = rt61pci_kick_tx_queue,
- .kill_tx_queue = rt61pci_kill_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone,
.config_shared_key = rt61pci_config_shared_key,
.config_pairwise_key = rt61pci_config_pairwise_key,
@@ -2857,21 +2914,21 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
};
static const struct data_queue_desc rt61pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_bcn = {
- .entry_num = 4 * BEACON_ENTRIES,
+ .entry_num = 4,
.data_size = 0, /* No DMA required for beacons */
.desc_size = TXINFO_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index e2e728ab0b2e..e3cd6db76b0e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -412,7 +412,7 @@ struct hw_pairwise_ta_entry {
* DROP_VERSION_ERROR: Drop version error frame.
* DROP_MULTICAST: Drop multicast frames.
* DROP_BORADCAST: Drop broadcast frames.
- * ROP_ACK_CTS: Drop received ACK and CTS.
+ * DROP_ACK_CTS: Drop received ACK and CTS.
*/
#define TXRX_CSR0 0x3040
#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
@@ -784,25 +784,25 @@ struct hw_pairwise_ta_entry {
*/
/*
- * AC0_BASE_CSR: AC_BK base address.
+ * AC0_BASE_CSR: AC_VO base address.
*/
#define AC0_BASE_CSR 0x3400
#define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
/*
- * AC1_BASE_CSR: AC_BE base address.
+ * AC1_BASE_CSR: AC_VI base address.
*/
#define AC1_BASE_CSR 0x3404
#define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
/*
- * AC2_BASE_CSR: AC_VI base address.
+ * AC2_BASE_CSR: AC_BE base address.
*/
#define AC2_BASE_CSR 0x3408
#define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
/*
- * AC3_BASE_CSR: AC_VO base address.
+ * AC3_BASE_CSR: AC_BK base address.
*/
#define AC3_BASE_CSR 0x340c
#define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
@@ -814,7 +814,7 @@ struct hw_pairwise_ta_entry {
#define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
/*
- * TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO.
+ * TX_RING_CSR0: TX Ring size for AC_VO, AC_VI, AC_BE, AC_BK.
*/
#define TX_RING_CSR0 0x3418
#define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff)
@@ -833,10 +833,10 @@ struct hw_pairwise_ta_entry {
/*
* AIFSN_CSR: AIFSN for each EDCA AC.
- * AIFSN0: For AC_BK.
- * AIFSN1: For AC_BE.
- * AIFSN2: For AC_VI.
- * AIFSN3: For AC_VO.
+ * AIFSN0: For AC_VO.
+ * AIFSN1: For AC_VI.
+ * AIFSN2: For AC_BE.
+ * AIFSN3: For AC_BK.
*/
#define AIFSN_CSR 0x3420
#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
@@ -846,10 +846,10 @@ struct hw_pairwise_ta_entry {
/*
* CWMIN_CSR: CWmin for each EDCA AC.
- * CWMIN0: For AC_BK.
- * CWMIN1: For AC_BE.
- * CWMIN2: For AC_VI.
- * CWMIN3: For AC_VO.
+ * CWMIN0: For AC_VO.
+ * CWMIN1: For AC_VI.
+ * CWMIN2: For AC_BE.
+ * CWMIN3: For AC_BK.
*/
#define CWMIN_CSR 0x3424
#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
@@ -859,10 +859,10 @@ struct hw_pairwise_ta_entry {
/*
* CWMAX_CSR: CWmax for each EDCA AC.
- * CWMAX0: For AC_BK.
- * CWMAX1: For AC_BE.
- * CWMAX2: For AC_VI.
- * CWMAX3: For AC_VO.
+ * CWMAX0: For AC_VO.
+ * CWMAX1: For AC_VI.
+ * CWMAX2: For AC_BE.
+ * CWMAX3: For AC_BK.
*/
#define CWMAX_CSR 0x3428
#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
@@ -883,14 +883,14 @@ struct hw_pairwise_ta_entry {
/*
* TX_CNTL_CSR: KICK/Abort TX.
- * KICK_TX_AC0: For AC_BK.
- * KICK_TX_AC1: For AC_BE.
- * KICK_TX_AC2: For AC_VI.
- * KICK_TX_AC3: For AC_VO.
- * ABORT_TX_AC0: For AC_BK.
- * ABORT_TX_AC1: For AC_BE.
- * ABORT_TX_AC2: For AC_VI.
- * ABORT_TX_AC3: For AC_VO.
+ * KICK_TX_AC0: For AC_VO.
+ * KICK_TX_AC1: For AC_VI.
+ * KICK_TX_AC2: For AC_BE.
+ * KICK_TX_AC3: For AC_BK.
+ * ABORT_TX_AC0: For AC_VO.
+ * ABORT_TX_AC1: For AC_VI.
+ * ABORT_TX_AC2: For AC_BE.
+ * ABORT_TX_AC3: For AC_BK.
*/
#define TX_CNTL_CSR 0x3430
#define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001)
@@ -1010,18 +1010,18 @@ struct hw_pairwise_ta_entry {
#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
/*
- * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
- * AC0_TX_OP: For AC_BK, in unit of 32us.
- * AC1_TX_OP: For AC_BE, in unit of 32us.
+ * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
+ * AC0_TX_OP: For AC_VO, in unit of 32us.
+ * AC1_TX_OP: For AC_VI, in unit of 32us.
*/
#define AC_TXOP_CSR0 0x3474
#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
/*
- * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
- * AC2_TX_OP: For AC_VI, in unit of 32us.
- * AC3_TX_OP: For AC_VO, in unit of 32us.
+ * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
+ * AC2_TX_OP: For AC_BE, in unit of 32us.
+ * AC3_TX_OP: For AC_BK, in unit of 32us.
*/
#define AC_TXOP_CSR1 0x3478
#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 9be8089317e4..0b4e8590cbb7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -40,7 +40,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -1031,6 +1031,55 @@ dynamic_cca_tune:
}
/*
+ * Queue handlers.
+ */
+static void rt73usb_start_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+static void rt73usb_stop_queue(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ u32 reg;
+
+ switch (queue->qid) {
+ case QID_RX:
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+ break;
+ case QID_BEACON:
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Firmware functions
*/
static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -1324,18 +1373,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
/*
* Device state switch handlers.
*/
-static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- u32 reg;
-
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-}
-
static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
/*
@@ -1402,12 +1439,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_RADIO_OFF:
rt73usb_disable_radio(rt2x00dev);
break;
- case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
- case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
- rt73usb_toggle_rx(rt2x00dev, state);
- break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_ON_ISR:
case STATE_RADIO_IRQ_OFF:
@@ -1472,10 +1503,10 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
- rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -1515,6 +1546,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
unsigned int beacon_base;
+ unsigned int padding_len;
u32 reg;
/*
@@ -1542,11 +1574,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Write entire beacon with descriptor to register.
+ * Write entire beacon with descriptor and padding to register.
*/
+ padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+ skb_pad(entry->skb, padding_len);
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2x00usb_register_multiwrite(rt2x00dev, beacon_base,
- entry->skb->data, entry->skb->len);
+ rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+ entry->skb->len + padding_len);
/*
* Enable beaconing again.
@@ -1582,14 +1616,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
-static void rt73usb_kill_tx_queue(struct data_queue *queue)
-{
- if (queue->qid == QID_BEACON)
- rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
-
- rt2x00usb_kill_tx_queue(queue);
-}
-
/*
* RX control handlers
*/
@@ -2264,6 +2290,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.conf_tx = rt73usb_conf_tx,
.get_tsf = rt73usb_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2280,11 +2307,13 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.reset_tuner = rt73usb_reset_tuner,
.link_tuner = rt73usb_link_tuner,
.watchdog = rt2x00usb_watchdog,
+ .start_queue = rt73usb_start_queue,
+ .kick_queue = rt2x00usb_kick_queue,
+ .stop_queue = rt73usb_stop_queue,
+ .flush_queue = rt2x00usb_flush_queue,
.write_tx_desc = rt73usb_write_tx_desc,
.write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
- .kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt73usb_kill_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
@@ -2296,21 +2325,21 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
};
static const struct data_queue_desc rt73usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_bcn = {
- .entry_num = 4 * BEACON_ENTRIES,
+ .entry_num = 4,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 44d5b2bebd39..9f6b470414d3 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -322,7 +322,7 @@ struct hw_pairwise_ta_entry {
* DROP_VERSION_ERROR: Drop version error frame.
* DROP_MULTICAST: Drop multicast frames.
* DROP_BORADCAST: Drop broadcast frames.
- * ROP_ACK_CTS: Drop received ACK and CTS.
+ * DROP_ACK_CTS: Drop received ACK and CTS.
*/
#define TXRX_CSR0 0x3040
#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
@@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry {
/*
* AIFSN_CSR: AIFSN for each EDCA AC.
- * AIFSN0: For AC_BK.
- * AIFSN1: For AC_BE.
- * AIFSN2: For AC_VI.
- * AIFSN3: For AC_VO.
+ * AIFSN0: For AC_VO.
+ * AIFSN1: For AC_VI.
+ * AIFSN2: For AC_BE.
+ * AIFSN3: For AC_BK.
*/
#define AIFSN_CSR 0x0400
#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
@@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry {
/*
* CWMIN_CSR: CWmin for each EDCA AC.
- * CWMIN0: For AC_BK.
- * CWMIN1: For AC_BE.
- * CWMIN2: For AC_VI.
- * CWMIN3: For AC_VO.
+ * CWMIN0: For AC_VO.
+ * CWMIN1: For AC_VI.
+ * CWMIN2: For AC_BE.
+ * CWMIN3: For AC_BK.
*/
#define CWMIN_CSR 0x0404
#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
@@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry {
/*
* CWMAX_CSR: CWmax for each EDCA AC.
- * CWMAX0: For AC_BK.
- * CWMAX1: For AC_BE.
- * CWMAX2: For AC_VI.
- * CWMAX3: For AC_VO.
+ * CWMAX0: For AC_VO.
+ * CWMAX1: For AC_VI.
+ * CWMAX2: For AC_BE.
+ * CWMAX3: For AC_BK.
*/
#define CWMAX_CSR 0x0408
#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
@@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry {
#define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000)
/*
- * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
- * AC0_TX_OP: For AC_BK, in unit of 32us.
- * AC1_TX_OP: For AC_BE, in unit of 32us.
+ * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
+ * AC0_TX_OP: For AC_VO, in unit of 32us.
+ * AC1_TX_OP: For AC_VI, in unit of 32us.
*/
#define AC_TXOP_CSR0 0x040c
#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
/*
- * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
- * AC2_TX_OP: For AC_VI, in unit of 32us.
- * AC3_TX_OP: For AC_VO, in unit of 32us.
+ * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
+ * AC2_TX_OP: For AC_BE, in unit of 32us.
+ * AC3_TX_OP: For AC_BK, in unit of 32us.
*/
#define AC_TXOP_CSR1 0x0410
#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
index 93cbfbedb46d..997569076923 100644
--- a/drivers/net/wireless/rtl818x/Makefile
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -1,7 +1,2 @@
-rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o
-
-obj-$(CONFIG_RTL8180) += rtl8180.o
-obj-$(CONFIG_RTL8187) += rtl8187.o
-
-
+obj-$(CONFIG_RTL8180) += rtl8180/
+obj-$(CONFIG_RTL8187) += rtl8187/
diff --git a/drivers/net/wireless/rtl818x/rtl8180/Makefile b/drivers/net/wireless/rtl818x/rtl8180/Makefile
new file mode 100644
index 000000000000..cb4fb8596f0b
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180/Makefile
@@ -0,0 +1,5 @@
+rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o
+
+obj-$(CONFIG_RTL8180) += rtl8180.o
+
+ccflags-y += -Idrivers/net/wireless/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 707c688da618..5851cbc1e957 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -24,10 +24,10 @@
#include <net/mac80211.h>
#include "rtl8180.h"
-#include "rtl8180_rtl8225.h"
-#include "rtl8180_sa2400.h"
-#include "rtl8180_max2820.h"
-#include "rtl8180_grf5101.h"
+#include "rtl8225.h"
+#include "sa2400.h"
+#include "max2820.h"
+#include "grf5101.h"
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
index 5cab9dfa8c07..5ee7589dd546 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
@@ -25,7 +25,7 @@
#include <net/mac80211.h>
#include "rtl8180.h"
-#include "rtl8180_grf5101.h"
+#include "grf5101.h"
static const int grf5101_encode[] = {
0x0, 0x8, 0x4, 0xC,
diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.h b/drivers/net/wireless/rtl818x/rtl8180/grf5101.h
index 76647111bcff..76647111bcff 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
index 16c4655181c0..667b3363d437 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_max2820.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
@@ -24,7 +24,7 @@
#include <net/mac80211.h>
#include "rtl8180.h"
-#include "rtl8180_max2820.h"
+#include "max2820.h"
static const u32 max2820_chan[] = {
12, /* CH 1 */
diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.h b/drivers/net/wireless/rtl818x/rtl8180/max2820.h
index 61cf6d1e7d57..61cf6d1e7d57 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_max2820.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
index 30523314da43..30523314da43 100644
--- a/drivers/net/wireless/rtl818x/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
index 69e4d4745dae..7c4574ba9d75 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
@@ -21,7 +21,7 @@
#include <net/mac80211.h>
#include "rtl8180.h"
-#include "rtl8180_rtl8225.h"
+#include "rtl8225.h"
static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
{
diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h
index 310013a2d726..310013a2d726 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
index d064fcc5ec08..44771a6286af 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
@@ -25,7 +25,7 @@
#include <net/mac80211.h>
#include "rtl8180.h"
-#include "rtl8180_sa2400.h"
+#include "sa2400.h"
static const u32 sa2400_chan[] = {
0x00096c, /* ch1 */
diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.h b/drivers/net/wireless/rtl818x/rtl8180/sa2400.h
index a4aaa0d413f1..a4aaa0d413f1 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187/Makefile b/drivers/net/wireless/rtl818x/rtl8187/Makefile
new file mode 100644
index 000000000000..7b6299268ecf
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/Makefile
@@ -0,0 +1,5 @@
+rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o
+
+obj-$(CONFIG_RTL8187) += rtl8187.o
+
+ccflags-y += -Idrivers/net/wireless/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 38fa8244cc96..6b82cac37ee3 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -29,11 +29,11 @@
#include <net/mac80211.h>
#include "rtl8187.h"
-#include "rtl8187_rtl8225.h"
+#include "rtl8225.h"
#ifdef CONFIG_RTL8187_LEDS
-#include "rtl8187_leds.h"
+#include "leds.h"
#endif
-#include "rtl8187_rfkill.h"
+#include "rfkill.h"
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -553,6 +553,46 @@ static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
return ret;
}
+static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
+{
+ u32 anaparam, anaparam2;
+ u8 anaparam3, reg;
+
+ if (!priv->is_rtl8187b) {
+ if (rfon) {
+ anaparam = RTL8187_RTL8225_ANAPARAM_ON;
+ anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON;
+ } else {
+ anaparam = RTL8187_RTL8225_ANAPARAM_OFF;
+ anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF;
+ }
+ } else {
+ if (rfon) {
+ anaparam = RTL8187B_RTL8225_ANAPARAM_ON;
+ anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON;
+ anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON;
+ } else {
+ anaparam = RTL8187B_RTL8225_ANAPARAM_OFF;
+ anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF;
+ anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF;
+ }
+ }
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
+ if (priv->is_rtl8187b)
+ rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
+ reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+}
+
static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
@@ -603,19 +643,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
int res;
/* reset */
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
- RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
- ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
+ rtl8187_set_anaparam(priv, true);
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
@@ -629,17 +657,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
if (res)
return res;
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ rtl8187_set_anaparam(priv, true);
/* setup card */
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
@@ -712,10 +730,9 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
{0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
- {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
- {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
- {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
- {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
+ {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1},
+ {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1},
+ {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
{0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
{0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
@@ -723,14 +740,13 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
{0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
{0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
- {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
- {0x73, 0x9A, 2},
+ {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2},
- {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
- {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
- {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
- {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
- {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
+ {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0},
+ {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0},
+ {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0},
+ {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0},
+ {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
{0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
{0x8F, 0x00, 0}
@@ -742,48 +758,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
int res, i;
u8 reg;
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
-
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187B_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187B_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
- RTL8187B_RTL8225_ANAPARAM3_ON);
+ rtl8187_set_anaparam(priv, true);
+ /* Reset PLL sequence on 8187B. Realtek note: reduces power
+ * consumption about 30 mA */
rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
-
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
-
res = rtl8187_cmd_reset(dev);
if (res)
return res;
- rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
+ rtl8187_set_anaparam(priv, true);
+
+ /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as
+ * RESP_RATE on 8187L in Realtek sources: each bit should be each
+ * one of the 12 rates, all are enabled */
+ rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF);
+
reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
- reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
- reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
- RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
- rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+ /* Auto Rate Fallback Register (ARFR): 1M-54M setting */
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1);
- rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
- rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
@@ -811,16 +813,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
+ /* RFSW_CTRL register */
rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
-
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
@@ -929,6 +924,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
priv->rx_conf = reg;
rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+ reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+ reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
+ reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+ reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
+ rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
rtl818x_iowrite32(priv, &priv->map->TX_CONF,
RTL818X_TX_CONF_HW_SEQNUM |
RTL818X_TX_CONF_DISREQQSIZE |
@@ -1002,6 +1003,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
priv->rf->stop(dev);
+ rtl8187_set_anaparam(priv, false);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c
index 4637337d5ce6..2e0de2f5f0f9 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c
@@ -20,7 +20,7 @@
#include <linux/eeprom_93cx6.h>
#include "rtl8187.h"
-#include "rtl8187_leds.h"
+#include "leds.h"
static void led_turn_on(struct work_struct *work)
{
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187/leds.h
index d743c96d4a20..d743c96d4a20 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.h
+++ b/drivers/net/wireless/rtl818x/rtl8187/leds.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c
index 03555e1e0cab..34116719974a 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c
@@ -18,7 +18,7 @@
#include <net/mac80211.h>
#include "rtl8187.h"
-#include "rtl8187_rfkill.h"
+#include "rfkill.h"
static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
{
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h
index e12575e96d11..e12575e96d11 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h
+++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
index 98878160a65a..0d7b1423f77b 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
@@ -16,7 +16,7 @@
#define RTL8187_H
#include "rtl818x.h"
-#include "rtl8187_leds.h"
+#include "leds.h"
#define RTL8187_EEPROM_TXPWR_BASE 0x05
#define RTL8187_EEPROM_MAC_ADDR 0x07
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
index 97eebdcf7eb9..908903f721f5 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
@@ -21,7 +21,7 @@
#include <net/mac80211.h>
#include "rtl8187.h"
-#include "rtl8187_rtl8225.h"
+#include "rtl8225.h"
static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
{
@@ -898,29 +898,7 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
static void rtl8225_rf_stop(struct ieee80211_hw *dev)
{
- u8 reg;
- struct rtl8187_priv *priv = dev->priv;
-
rtl8225_write(dev, 0x4, 0x1f);
-
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- if (!priv->is_rtl8187b) {
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_OFF);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_OFF);
- } else {
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187B_RTL8225_ANAPARAM2_OFF);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187B_RTL8225_ANAPARAM_OFF);
- rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
- RTL8187B_RTL8225_ANAPARAM3_OFF);
- }
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
}
static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h
index 20c5b6ead0f6..20c5b6ead0f6 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
new file mode 100644
index 000000000000..7f6573f7f470
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -0,0 +1,15 @@
+config RTL8192CE
+ tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
+ depends on MAC80211 && EXPERIMENTAL
+ select FW_LOADER
+ select RTLWIFI
+ ---help---
+ This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
+ wireless network adapters.
+
+ If you choose to build it as a module, it will be called rtl8192ce
+
+config RTLWIFI
+ tristate
+ depends on RTL8192CE
+ default m
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
new file mode 100644
index 000000000000..2a7a4384f8ee
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_RTLWIFI) += rtlwifi.o
+rtlwifi-objs := \
+ base.o \
+ cam.o \
+ core.o \
+ debug.o \
+ efuse.o \
+ pci.o \
+ ps.o \
+ rc.o \
+ regd.o
+
+obj-$(CONFIG_RTL8192CE) += rtl8192ce/
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
new file mode 100644
index 000000000000..cf0b73e51fc2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -0,0 +1,956 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/ip.h>
+#include "wifi.h"
+#include "rc.h"
+#include "base.h"
+#include "efuse.h"
+#include "cam.h"
+#include "ps.h"
+#include "regd.h"
+
+/*
+ *NOTICE!!!: This file will be very big, we hsould
+ *keep it clear under follwing roles:
+ *
+ *This file include follwing part, so, if you add new
+ *functions into this file, please check which part it
+ *should includes. or check if you should add new part
+ *for this file:
+ *
+ *1) mac80211 init functions
+ *2) tx information functions
+ *3) functions called by core.c
+ *4) wq & timer callback functions
+ *5) frame process functions
+ *6) sysfs functions
+ *7) ...
+ */
+
+/*********************************************************
+ *
+ * mac80211 init functions
+ *
+ *********************************************************/
+static struct ieee80211_channel rtl_channeltable[] = {
+ {.center_freq = 2412, .hw_value = 1,},
+ {.center_freq = 2417, .hw_value = 2,},
+ {.center_freq = 2422, .hw_value = 3,},
+ {.center_freq = 2427, .hw_value = 4,},
+ {.center_freq = 2432, .hw_value = 5,},
+ {.center_freq = 2437, .hw_value = 6,},
+ {.center_freq = 2442, .hw_value = 7,},
+ {.center_freq = 2447, .hw_value = 8,},
+ {.center_freq = 2452, .hw_value = 9,},
+ {.center_freq = 2457, .hw_value = 10,},
+ {.center_freq = 2462, .hw_value = 11,},
+ {.center_freq = 2467, .hw_value = 12,},
+ {.center_freq = 2472, .hw_value = 13,},
+ {.center_freq = 2484, .hw_value = 14,},
+};
+
+static struct ieee80211_rate rtl_ratetable[] = {
+ {.bitrate = 10, .hw_value = 0x00,},
+ {.bitrate = 20, .hw_value = 0x01,},
+ {.bitrate = 55, .hw_value = 0x02,},
+ {.bitrate = 110, .hw_value = 0x03,},
+ {.bitrate = 60, .hw_value = 0x04,},
+ {.bitrate = 90, .hw_value = 0x05,},
+ {.bitrate = 120, .hw_value = 0x06,},
+ {.bitrate = 180, .hw_value = 0x07,},
+ {.bitrate = 240, .hw_value = 0x08,},
+ {.bitrate = 360, .hw_value = 0x09,},
+ {.bitrate = 480, .hw_value = 0x0a,},
+ {.bitrate = 540, .hw_value = 0x0b,},
+};
+
+static const struct ieee80211_supported_band rtl_band_2ghz = {
+ .band = IEEE80211_BAND_2GHZ,
+
+ .channels = rtl_channeltable,
+ .n_channels = ARRAY_SIZE(rtl_channeltable),
+
+ .bitrates = rtl_ratetable,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable),
+
+ .ht_cap = {0},
+};
+
+static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
+ struct ieee80211_sta_ht_cap *ht_cap)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ ht_cap->ht_supported = true;
+ ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
+
+ /*
+ *Maximum length of AMPDU that the STA can receive.
+ *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+
+ /*Minimum MPDU start spacing , */
+ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+
+ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ /*
+ *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ *base on ant_num
+ *rx_mask: RX mask
+ *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
+ *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
+ *if rx_ant >=3 rx_mask[2]=0xff;
+ *if BW_40 rx_mask[4]=0x01;
+ *highest supported RX rate
+ */
+ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0xFF;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
+ } else if (get_rf_type(rtlphy) == RF_1T1R) {
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0x00;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
+ }
+}
+
+static void _rtl_init_mac80211(struct ieee80211_hw *hw)
+{
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct ieee80211_supported_band *sband;
+
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /*
+ * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R)
+ */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+
+ /* <5> set hw caps */
+ hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
+ /*IEEE80211_HW_SUPPORTS_PS | */
+ /*IEEE80211_HW_PS_NULLFUNC_STACK | */
+ /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+
+ hw->wiphy->rts_threshold = 2347;
+
+ hw->queues = AC_MAX;
+ hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
+
+ /* TODO: Correct this value for our hw */
+ /* TODO: define these hard code value */
+ hw->channel_change_time = 100;
+ hw->max_listen_interval = 5;
+ hw->max_rate_tries = 4;
+ /* hw->max_rates = 1; */
+
+ /* <6> mac address */
+ if (is_valid_ether_addr(rtlefuse->dev_addr)) {
+ SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
+ } else {
+ u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
+ get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
+ SET_IEEE80211_PERM_ADDR(hw, rtlmac);
+ }
+
+}
+
+static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* <1> timer */
+ init_timer(&rtlpriv->works.watchdog_timer);
+ setup_timer(&rtlpriv->works.watchdog_timer,
+ rtl_watch_dog_timer_callback, (unsigned long)hw);
+
+ /* <2> work queue */
+ rtlpriv->works.hw = hw;
+ rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
+ INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
+ (void *)rtl_watchdog_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
+ (void *)rtl_ips_nic_off_wq_callback);
+
+}
+
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ del_timer_sync(&rtlpriv->works.watchdog_timer);
+
+ cancel_delayed_work(&rtlpriv->works.watchdog_wq);
+ cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+}
+
+void rtl_init_rfkill(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ bool radio_state;
+ bool blocked;
+ u8 valid = 0;
+
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+ /*set init state to that of switch */
+ rtlpriv->rfkill.rfkill_state = radio_state;
+ printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
+ rtlpriv->rfkill.rfkill_state ? "on" : "off");
+
+ if (valid) {
+ rtlpriv->rfkill.rfkill_state = radio_state;
+
+ blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+ }
+
+ wiphy_rfkill_start_polling(hw->wiphy);
+}
+
+void rtl_deinit_rfkill(struct ieee80211_hw *hw)
+{
+ wiphy_rfkill_stop_polling(hw->wiphy);
+}
+
+int rtl_init_core(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+
+ /* <1> init mac80211 */
+ _rtl_init_mac80211(hw);
+ rtlmac->hw = hw;
+
+ /* <2> rate control register */
+ if (rtl_rate_control_register()) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("rtl: Unable to register rtl_rc,"
+ "use default RC !!\n"));
+ } else {
+ hw->rate_control_algorithm = "rtl_rc";
+ }
+
+ /*
+ * <3> init CRDA must come after init
+ * mac80211 hw in _rtl_init_mac80211.
+ */
+ if (rtl_regd_init(hw, rtl_reg_notifier)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
+ return 1;
+ } else {
+ /* CRDA regd hint must after init CRDA */
+ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("regulatory_hint fail\n"));
+ }
+ }
+
+ /* <4> locks */
+ mutex_init(&rtlpriv->locks.conf_mutex);
+ spin_lock_init(&rtlpriv->locks.ips_lock);
+ spin_lock_init(&rtlpriv->locks.irq_th_lock);
+ spin_lock_init(&rtlpriv->locks.h2c_lock);
+ spin_lock_init(&rtlpriv->locks.rf_ps_lock);
+ spin_lock_init(&rtlpriv->locks.rf_lock);
+ spin_lock_init(&rtlpriv->locks.lps_lock);
+
+ rtlmac->link_state = MAC80211_NOLINK;
+
+ /* <5> init deferred work */
+ _rtl_init_deferred_work(hw);
+
+ return 0;
+}
+
+void rtl_deinit_core(struct ieee80211_hw *hw)
+{
+ /*RC*/
+ rtl_rate_control_unregister();
+}
+
+void rtl_init_rx_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
+ (u8 *) (&mac->rx_mgt_filter));
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
+ (u8 *) (&mac->rx_ctrl_filter));
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
+ (u8 *) (&mac->rx_data_filter));
+}
+
+/*********************************************************
+ *
+ * tx information functions
+ *
+ *********************************************************/
+static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ tcb_desc->use_shortpreamble = false;
+
+ /* 1M can only use Long Preamble. 11B spec */
+ if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
+ return;
+ else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ tcb_desc->use_shortpreamble = true;
+
+ return;
+}
+
+static void _rtl_query_shortgi(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 rate_flag = info->control.rates[0].flags;
+
+ tcb_desc->use_shortgi = false;
+
+ if (!mac->ht_enable)
+ return;
+
+ if (!mac->sgi_40 && !mac->sgi_20)
+ return;
+
+ if ((mac->bw_40 == true) && mac->sgi_40)
+ tcb_desc->use_shortgi = true;
+ else if ((mac->bw_40 == false) && mac->sgi_20)
+ tcb_desc->use_shortgi = true;
+
+ if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
+ tcb_desc->use_shortgi = false;
+
+}
+
+static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ /* Common Settings */
+ tcb_desc->b_rts_stbc = false;
+ tcb_desc->b_cts_enable = false;
+ tcb_desc->rts_sc = 0;
+ tcb_desc->b_rts_bw = false;
+ tcb_desc->b_rts_use_shortpreamble = false;
+ tcb_desc->b_rts_use_shortgi = false;
+
+ if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ /* Use CTS-to-SELF in protection mode. */
+ tcb_desc->b_rts_enable = true;
+ tcb_desc->b_cts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
+ /* Use RTS-CTS in protection mode. */
+ tcb_desc->b_rts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ }
+
+}
+
+static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ tcb_desc->ratr_index = 0;
+ else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
+ tcb_desc->use_driver_rate = 1;
+ } else {
+ /* TODO */
+ }
+ }
+ }
+
+ if (rtlpriv->dm.b_useramask) {
+ /* TODO we will differentiate adhoc and station futrue */
+ tcb_desc->mac_id = 0;
+
+ if ((mac->mode == WIRELESS_MODE_N_24G) ||
+ (mac->mode == WIRELESS_MODE_N_5G)) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
+ } else if (mac->mode & WIRELESS_MODE_G) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
+ } else if (mac->mode & WIRELESS_MODE_B) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+ }
+ }
+
+}
+
+static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ tcb_desc->b_packet_bw = false;
+
+ if (!mac->bw_40 || !mac->ht_enable)
+ return;
+
+ if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
+ return;
+
+ /*use legency rate, shall use 20MHz */
+ if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
+ return;
+
+ tcb_desc->b_packet_bw = true;
+}
+
+static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u8 hw_rate;
+
+ if (get_rf_type(rtlphy) == RF_2T2R)
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
+ else
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
+
+ return hw_rate;
+}
+
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ struct ieee80211_rate *txrate;
+ u16 fc = le16_to_cpu(hdr->frame_control);
+
+ memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (ieee80211_is_data(fc)) {
+ txrate = ieee80211_get_tx_rate(hw, info);
+ tcb_desc->hw_rate = txrate->hw_value;
+
+ /*
+ *we set data rate RTL_RC_CCK_RATE1M
+ *in rtl_rc.c if skb is special data or
+ *mgt which need low data rate.
+ */
+
+ /*
+ *So tcb_desc->hw_rate is just used for
+ *special data and mgt frames
+ */
+ if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index = 7;
+
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ tcb_desc->disable_ratefallback = 1;
+ } else {
+ /*
+ *because hw will nerver use hw_rate
+ *when tcb_desc->use_driver_rate = false
+ *so we never set highest N rate here,
+ *and N rate will all be controled by FW
+ *when tcb_desc->use_driver_rate = false
+ */
+ if (rtlmac->ht_enable) {
+ tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
+ } else {
+ if (rtlmac->mode == WIRELESS_MODE_B) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
+ } else {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ }
+ }
+ }
+
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
+ tcb_desc->b_multicast = 1;
+ else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ tcb_desc->b_broadcast = 1;
+
+ _rtl_txrate_selectmode(hw, tcb_desc);
+ _rtl_query_bandwidth_mode(hw, tcb_desc);
+ _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
+ _rtl_query_shortgi(hw, tcb_desc, info);
+ _rtl_query_protection_mode(hw, tcb_desc, info);
+ } else {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index = 7;
+ tcb_desc->disable_ratefallback = 1;
+ tcb_desc->mac_id = 0;
+
+ tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ }
+}
+EXPORT_SYMBOL(rtl_get_tcb_desc);
+
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ u16 fc = le16_to_cpu(hdr->frame_control);
+
+ if (ieee80211_is_auth(fc)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+ rtl_ips_nic_on(hw);
+
+ mac->link_state = MAC80211_LINKING;
+ }
+
+ return true;
+}
+
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
+ u8 category;
+
+ if (!ieee80211_is_action(fc))
+ return true;
+
+ category = *act;
+ act++;
+ switch (category) {
+ case ACT_CAT_BA:
+ switch (*act) {
+ case ACT_ADDBAREQ:
+ if (mac->act_scanning)
+ return false;
+
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("%s ACT_ADDBAREQ From :" MAC_FMT "\n",
+ is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
+ break;
+ case ACT_ADDBARSP:
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("%s ACT_ADDBARSP From :" MAC_FMT "\n",
+ is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
+ break;
+ case ACT_DELBA:
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("ACT_ADDBADEL From :" MAC_FMT "\n",
+ MAC_ARG(hdr->addr2)));
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/*should call before software enc*/
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ u16 ether_type;
+ u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+ const struct iphdr *ip;
+
+ if (!ieee80211_is_data(fc))
+ goto end;
+
+ if (ieee80211_is_nullfunc(fc))
+ return true;
+
+ ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
+ SNAP_SIZE + PROTOC_TYPE_SIZE);
+ ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
+ ether_type = ntohs(ether_type);
+
+ if (ETH_P_IP == ether_type) {
+ if (IPPROTO_UDP == ip->protocol) {
+ struct udphdr *udp = (struct udphdr *)((u8 *) ip +
+ (ip->ihl << 2));
+ 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
+ */
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
+ DBG_DMESG, ("dhcp %s !!\n",
+ (is_tx) ? "Tx" : "Rx"));
+
+ if (is_tx) {
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies =
+ jiffies;
+ }
+
+ return true;
+ }
+ }
+ } else if (ETH_P_ARP == ether_type) {
+ if (is_tx) {
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
+ return true;
+ } else if (ETH_P_PAE == ether_type) {
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
+
+ if (is_tx) {
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
+ return true;
+ } else if (0x86DD == ether_type) {
+ return true;
+ }
+
+end:
+ return false;
+}
+
+/*********************************************************
+ *
+ * functions called by core.c
+ *
+ *********************************************************/
+int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", ra, tid));
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Start AGG when state is not RTL_AGG_OFF !\n"));
+ return -ENXIO;
+ }
+
+ tid_data = &mac->tids[tid];
+ *ssn = SEQ_TO_SN(tid_data->seq_number);
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+ ("HW queue is empty tid:%d\n", tid));
+ tid_data->agg.agg_state = RTL_AGG_ON;
+
+ ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+
+ return 0;
+}
+
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
+{
+ int ssn = -1;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_tid_data *tid_data;
+
+ if (!ra) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+ return -EINVAL;
+ }
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Stopping AGG while state not ON or starting\n"));
+
+ tid_data = &mac->tids[tid];
+ ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
+
+ mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
+
+ ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+
+ return 0;
+}
+
+/*********************************************************
+ *
+ * wq & timer callback functions
+ *
+ *********************************************************/
+void rtl_watchdog_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ watchdog_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ bool b_busytraffic = false;
+ bool b_higher_busytraffic = false;
+ bool b_higher_busyrxtraffic = false;
+ bool b_higher_busytxtraffic = false;
+
+ u8 idx = 0;
+ u32 rx_cnt_inp4eriod = 0;
+ u32 tx_cnt_inp4eriod = 0;
+ u32 aver_rx_cnt_inperiod = 0;
+ u32 aver_tx_cnt_inperiod = 0;
+
+ bool benter_ps = false;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ /* <1> Determine if action frame is allowed */
+ if (mac->link_state > MAC80211_NOLINK) {
+ if (mac->cnt_after_linked < 20)
+ mac->cnt_after_linked++;
+ } else {
+ mac->cnt_after_linked = 0;
+ }
+
+ /* <2> DM */
+ rtlpriv->cfg->ops->dm_watchdog(hw);
+
+ /*
+ *<3> to check if traffic busy, if
+ * busytraffic we don't change channel
+ */
+ if (mac->link_state >= MAC80211_LINKED) {
+
+ /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
+ for (idx = 0; idx <= 2; idx++) {
+ rtlpriv->link_info.num_rx_in4period[idx] =
+ rtlpriv->link_info.num_rx_in4period[idx + 1];
+ rtlpriv->link_info.num_tx_in4period[idx] =
+ rtlpriv->link_info.num_tx_in4period[idx + 1];
+ }
+ rtlpriv->link_info.num_rx_in4period[3] =
+ rtlpriv->link_info.num_rx_inperiod;
+ rtlpriv->link_info.num_tx_in4period[3] =
+ rtlpriv->link_info.num_tx_inperiod;
+ for (idx = 0; idx <= 3; idx++) {
+ rx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_rx_in4period[idx];
+ tx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_tx_in4period[idx];
+ }
+ aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
+ aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
+
+ /* (2) check traffic busy */
+ if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
+ b_busytraffic = true;
+
+ /* Higher Tx/Rx data. */
+ if (aver_rx_cnt_inperiod > 4000 ||
+ aver_tx_cnt_inperiod > 4000) {
+ b_higher_busytraffic = true;
+
+ /* Extremely high Rx data. */
+ if (aver_rx_cnt_inperiod > 5000)
+ b_higher_busyrxtraffic = true;
+ else
+ b_higher_busytxtraffic = false;
+ }
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2))
+ benter_ps = false;
+ else
+ benter_ps = true;
+
+ /* LeisurePS only work in infra mode. */
+ if (benter_ps)
+ rtl_lps_enter(hw);
+ else
+ rtl_lps_leave(hw);
+ }
+
+ rtlpriv->link_info.num_rx_inperiod = 0;
+ rtlpriv->link_info.num_tx_inperiod = 0;
+
+ rtlpriv->link_info.b_busytraffic = b_busytraffic;
+ rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
+ rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
+
+}
+
+void rtl_watch_dog_timer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.watchdog_wq, 0);
+
+ mod_timer(&rtlpriv->works.watchdog_timer,
+ jiffies + MSECS(RTL_WATCH_DOG_TIME));
+}
+
+/*********************************************************
+ *
+ * sysfs functions
+ *
+ *********************************************************/
+static ssize_t rtl_show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(d);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
+}
+
+static ssize_t rtl_store_debug_level(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(d);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long val;
+ int ret;
+
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret) {
+ printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
+ } else {
+ rtlpriv->dbg.global_debuglevel = val;
+ printk(KERN_DEBUG "debuglevel:%x\n",
+ rtlpriv->dbg.global_debuglevel);
+ }
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ rtl_show_debug_level, rtl_store_debug_level);
+
+static struct attribute *rtl_sysfs_entries[] = {
+
+ &dev_attr_debug_level.attr,
+
+ NULL
+};
+
+/*
+ * "name" is folder name witch will be
+ * put in device directory like :
+ * sys/devices/pci0000:00/0000:00:1c.4/
+ * 0000:06:00.0/rtl_sysfs
+ */
+struct attribute_group rtl_attribute_group = {
+ .name = "rtlsysfs",
+ .attrs = rtl_sysfs_entries,
+};
+
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
+
+static int __init rtl_core_module_init(void)
+{
+ return 0;
+}
+
+static void __exit rtl_core_module_exit(void)
+{
+}
+
+module_init(rtl_core_module_init);
+module_exit(rtl_core_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
new file mode 100644
index 000000000000..3de5a14745f1
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#ifndef __RTL_BASE_H__
+#define __RTL_BASE_H__
+
+#define RTL_DUMMY_OFFSET 0
+#define RTL_DUMMY_UNIT 8
+#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
+#define RTL_TX_DESC_SIZE 32
+#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
+
+#define HT_AMSDU_SIZE_4K 3839
+#define HT_AMSDU_SIZE_8K 7935
+
+#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
+#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
+
+#define RTL_RATE_COUNT_LEGACY 12
+#define RTL_CHANNEL_COUNT 14
+
+#define FRAME_OFFSET_FRAME_CONTROL 0
+#define FRAME_OFFSET_DURATION 2
+#define FRAME_OFFSET_ADDRESS1 4
+#define FRAME_OFFSET_ADDRESS2 10
+#define FRAME_OFFSET_ADDRESS3 16
+#define FRAME_OFFSET_SEQUENCE 22
+#define FRAME_OFFSET_ADDRESS4 24
+
+#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
+ WRITEEF2BYTE(_hdr, _val)
+#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
+ WRITEEF1BYTE(_hdr, _val)
+#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
+#define SET_80211_HDR_TO_DS(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
+
+#define SET_80211_PS_POLL_AID(_hdr, _val) \
+ WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
+#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
+ CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
+#define SET_80211_PS_POLL_TA(_hdr, _val) \
+ CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
+
+#define SET_80211_HDR_DURATION(_hdr, _val) \
+ WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
+#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
+#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
+#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
+ CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
+#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
+ WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
+
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
+ WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
+#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
+#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
+ READEF2BYTE(((u8 *)(__phdr)) + 34)
+#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
+#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
+ (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
+
+int rtl_init_core(struct ieee80211_hw *hw);
+void rtl_deinit_core(struct ieee80211_hw *hw);
+void rtl_init_rx_config(struct ieee80211_hw *hw);
+void rtl_init_rfkill(struct ieee80211_hw *hw);
+void rtl_deinit_rfkill(struct ieee80211_hw *hw);
+
+void rtl_watch_dog_timer_callback(unsigned long data);
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
+
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
+
+void rtl_watch_dog_timer_callback(unsigned long data);
+int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
+ u16 tid, u16 *ssn);
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
+void rtl_watchdog_wq_callback(void *data);
+
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
+
+extern struct attribute_group rtl_attribute_group;
+#endif
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
new file mode 100644
index 000000000000..52c9c1367cac
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -0,0 +1,291 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "cam.h"
+
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->sec.use_defaultkey = false;
+ rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
+ rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
+ memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
+ memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
+ rtlpriv->sec.pairwise_key = NULL;
+}
+
+static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
+ u8 *mac_addr, u8 *key_cont_128, u16 us_config)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 target_command;
+ u32 target_content = 0;
+ u8 entry_i;
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
+ key_cont_128[0], key_cont_128[1],
+ key_cont_128[2], key_cont_128[3],
+ key_cont_128[4], key_cont_128[5]));
+
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
+ target_command = target_command | BIT(31) | BIT(16);
+
+ if (entry_i == 0) {
+ target_content = (u32) (*(mac_addr + 0)) << 16 |
+ (u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): "
+ "WRITE %x: %x\n",
+ rtlpriv->cfg->maps[WCAMI], target_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("The Key ID is %d\n", entry_no));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): "
+ "WRITE %x: %x\n",
+ rtlpriv->cfg->maps[RWCAM], target_command));
+
+ } else if (entry_i == 1) {
+
+ target_content = (u32) (*(mac_addr + 5)) << 24 |
+ (u32) (*(mac_addr + 4)) << 16 |
+ (u32) (*(mac_addr + 3)) << 8 |
+ (u32) (*(mac_addr + 2));
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): WRITE A4: %x\n",
+ target_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): WRITE A0: %x\n",
+ target_command));
+
+ } else {
+
+ target_content =
+ (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
+ 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
+ << 16 |
+ (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
+ | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+ target_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_command);
+ udelay(100);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): WRITE A4: %x\n",
+ target_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_program_entry(): WRITE A0: %x\n",
+ target_command));
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("after set key, usconfig:%x\n", us_config));
+}
+
+u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+ u32 ul_default_key, u8 *key_content)
+{
+ u32 us_config;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
+ "ulUseDK=%x MacAddr" MAC_FMT "\n",
+ ul_entry_idx, ul_key_id, ul_enc_alg,
+ ul_default_key, MAC_ARG(mac_addr)));
+
+ if (ul_key_id == TOTAL_CAM_ENTRY) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("<=== ulKeyId exceed!\n"));
+ return 0;
+ }
+
+ if (ul_default_key == 1) {
+ us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
+ } else {
+ us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
+ }
+
+ rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
+ (u8 *) key_content, us_config);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
+
+ return 1;
+
+}
+EXPORT_SYMBOL(rtl_cam_add_one_entry);
+
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
+ u8 *mac_addr, u32 ul_key_id)
+{
+ u32 ul_command;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
+
+ ul_command = ul_key_id * CAM_CONTENT_COUNT;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
+
+ return 0;
+
+}
+EXPORT_SYMBOL(rtl_cam_delete_one_entry);
+
+void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
+{
+ u32 ul_command;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ ul_command = BIT(31) | BIT(30);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+}
+EXPORT_SYMBOL(rtl_cam_reset_all_entry);
+
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 ul_command;
+ u32 ul_content;
+ u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+ break;
+ case WEP104_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+ break;
+ case TKIP_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+ break;
+ case AESCCMP_ENCRYPTION:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ break;
+ default:
+ ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ }
+
+ ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
+
+ ul_content |= BIT(15);
+ ul_command = CAM_CONTENT_COUNT * uc_index;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
+}
+EXPORT_SYMBOL(rtl_cam_mark_invalid);
+
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ u32 ul_command;
+ u32 ul_content;
+ u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ u8 entry_i;
+
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+ break;
+ case WEP104_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+ break;
+ case TKIP_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+ break;
+ case AESCCMP_ENCRYPTION:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ break;
+ default:
+ ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+ }
+
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+
+ if (entry_i == 0) {
+ ul_content =
+ (uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
+ ul_content |= BIT(15);
+
+ } else {
+ ul_content = 0;
+ }
+
+ ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
+ ul_command = ul_command | BIT(31) | BIT(16);
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("rtl_cam_empty_entry(): WRITE A4: %x\n",
+ ul_content));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("rtl_cam_empty_entry(): WRITE A0: %x\n",
+ ul_command));
+ }
+
+}
+EXPORT_SYMBOL(rtl_cam_empty_entry);
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
new file mode 100644
index 000000000000..dd82f057d53d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_CAM_H_
+#define __RTL_CAM_H_
+
+#define TOTAL_CAM_ENTRY 32
+#define CAM_CONTENT_COUNT 8
+
+#define CFG_DEFAULT_KEY BIT(5)
+#define CFG_VALID BIT(15)
+
+#define PAIRWISE_KEYIDX 0
+#define CAM_PAIRWISE_KEY_POSITION 4
+
+#define CAM_CONFIG_USEDK 1
+#define CAM_CONFIG_NO_USEDK 0
+
+extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
+extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+ u32 ul_default_key, u8 *key_content);
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+ u32 ul_key_id);
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
new file mode 100644
index 000000000000..d6a924a05654
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -0,0 +1,1029 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "core.h"
+#include "cam.h"
+#include "base.h"
+#include "ps.h"
+
+/*mutex for start & stop is must here. */
+static int rtl_op_start(struct ieee80211_hw *hw)
+{
+ int err = 0;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (!is_hal_stop(rtlhal))
+ return 0;
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ return 0;
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ err = rtlpriv->intf_ops->adapter_start(hw);
+ if (err)
+ goto out;
+ rtl_watch_dog_timer_callback((unsigned long)hw);
+out:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ return err;
+}
+
+static void rtl_op_stop(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ if (unlikely(ppsc->rfpwr_state == ERFOFF)) {
+ rtl_ips_nic_on(hw);
+ mdelay(1);
+ }
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ mac->link_state = MAC80211_NOLINK;
+ memset(mac->bssid, 0, 6);
+
+ /*reset sec info */
+ rtl_cam_reset_sec_info(hw);
+
+ rtl_deinit_deferred_work(hw);
+ rtlpriv->intf_ops->adapter_stop(hw);
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+ goto err_free;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ goto err_free;
+
+
+ rtlpriv->intf_ops->adapter_tx(hw, skb);
+
+ return NETDEV_TX_OK;
+
+err_free:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static int rtl_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ int err = 0;
+
+ if (mac->vif) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
+ return -EOPNOTSUPP;
+ }
+
+ rtl_ips_nic_on(hw);
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (mac->beacon_enabled == 1) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("NL80211_IFTYPE_STATION\n"));
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS]);
+ }
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("NL80211_IFTYPE_ADHOC\n"));
+
+ mac->link_state = MAC80211_LINKED;
+ rtlpriv->cfg->ops->set_bcn_reg(hw);
+ break;
+ case NL80211_IFTYPE_AP:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("NL80211_IFTYPE_AP\n"));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("operation mode %d is not support!\n", vif->type));
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ mac->vif = vif;
+ mac->opmode = vif->type;
+ rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+ memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+
+out:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ return err;
+}
+
+static void rtl_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ /* Free beacon resources */
+ if ((mac->opmode == NL80211_IFTYPE_AP) ||
+ (mac->opmode == NL80211_IFTYPE_ADHOC) ||
+ (mac->opmode == NL80211_IFTYPE_MESH_POINT)) {
+ if (mac->beacon_enabled == 1) {
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS]);
+ }
+ }
+
+ /*
+ *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
+ *NO LINK for our hardware.
+ */
+ mac->vif = NULL;
+ mac->link_state = MAC80211_NOLINK;
+ memset(mac->bssid, 0, 6);
+ mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
+ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+
+static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct ieee80211_conf *conf = &hw->conf;
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
+ }
+
+ /*For IPS */
+ if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+ if (hw->conf.flags & IEEE80211_CONF_IDLE)
+ rtl_ips_nic_off(hw);
+ else
+ rtl_ips_nic_on(hw);
+ } else {
+ /*
+ *although rfoff may not cause by ips, but we will
+ *check the reason in set_rf_power_state function
+ */
+ if (unlikely(ppsc->rfpwr_state == ERFOFF))
+ rtl_ips_nic_on(hw);
+ }
+
+ /*For LPS */
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS)
+ rtl_lps_enter(hw);
+ else
+ rtl_lps_leave(hw);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
+ hw->conf.long_frame_max_tx_count));
+ mac->retry_long = hw->conf.long_frame_max_tx_count;
+ mac->retry_short = hw->conf.long_frame_max_tx_count;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ (u8 *) (&hw->conf.
+ long_frame_max_tx_count));
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ struct ieee80211_channel *channel = hw->conf.channel;
+ u8 wide_chan = (u8) channel->hw_value;
+
+ /*
+ *because we should back channel to
+ *current_network.chan in in scanning,
+ *So if set_chan == current_network.chan
+ *we should set it.
+ *because mac80211 tell us wrong bw40
+ *info for cisco1253 bw20, so we modify
+ *it here based on UPPER & LOWER
+ */
+ switch (hw->conf.channel_type) {
+ case NL80211_CHAN_HT20:
+ case NL80211_CHAN_NO_HT:
+ /* SC */
+ mac->cur_40_prime_sc =
+ PRIME_CHNL_OFFSET_DONT_CARE;
+ rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
+ mac->bw_40 = false;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ /* SC */
+ mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ mac->bw_40 = true;
+
+ /*wide channel */
+ wide_chan -= 2;
+
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ /* SC */
+ mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
+ rtlphy->current_chan_bw =
+ HT_CHANNEL_WIDTH_20_40;
+ mac->bw_40 = true;
+
+ /*wide channel */
+ wide_chan += 2;
+
+ break;
+ default:
+ mac->bw_40 = false;
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not processed\n"));
+ break;
+ }
+
+ if (wide_chan <= 0)
+ wide_chan = 1;
+ rtlphy->current_channel = wide_chan;
+
+ rtlpriv->cfg->ops->set_channel_access(hw);
+ rtlpriv->cfg->ops->switch_channel(hw);
+ rtlpriv->cfg->ops->set_bw_mode(hw,
+ hw->conf.channel_type);
+ }
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+
+ return 0;
+}
+
+static void rtl_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *new_flags, u64 multicast)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ *new_flags &= RTL_SUPPORTED_FILTERS;
+ if (!changed_flags)
+ return;
+
+ /*TODO: we disable broadcase now, so enable here */
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*new_flags & FIF_ALLMULTI) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
+ rtlpriv->cfg->maps[MAC_RCR_AB];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Enable receive multicast frame.\n"));
+ } else {
+ mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
+ rtlpriv->cfg->maps[MAC_RCR_AB]);
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Disable receive multicast frame.\n"));
+ }
+ }
+
+ if (changed_flags & FIF_FCSFAIL) {
+ if (*new_flags & FIF_FCSFAIL) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Enable receive FCS error frame.\n"));
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Disable receive FCS error frame.\n"));
+ }
+ }
+
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ /*
+ *TODO: BIT(5) is probe response BIT(8) is beacon
+ *TODO: Use define for BIT(5) and BIT(8)
+ */
+ if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
+ mac->rx_mgt_filter |= (BIT(5) | BIT(8));
+ else
+ mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
+ }
+
+ if (changed_flags & FIF_CONTROL) {
+ if (*new_flags & FIF_CONTROL) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
+ mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Enable receive control frame.\n"));
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
+ mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Disable receive control frame.\n"));
+ }
+ }
+
+ if (changed_flags & FIF_OTHER_BSS) {
+ if (*new_flags & FIF_OTHER_BSS) {
+ mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Enable receive other BSS's frame.\n"));
+ } else {
+ mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("Disable receive other BSS's frame.\n"));
+ }
+ }
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
+ (u8 *) (&mac->rx_mgt_filter));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
+ (u8 *) (&mac->rx_ctrl_filter));
+}
+
+static int _rtl_get_hal_qnum(u16 queue)
+{
+ int qnum;
+
+ switch (queue) {
+ case 0:
+ qnum = AC3_VO;
+ break;
+ case 1:
+ qnum = AC2_VI;
+ break;
+ case 2:
+ qnum = AC0_BE;
+ break;
+ case 3:
+ qnum = AC1_BK;
+ break;
+ default:
+ qnum = AC0_BE;
+ break;
+ }
+ return qnum;
+}
+
+/*
+ *for mac80211 VO=0, VI=1, BE=2, BK=3
+ *for rtl819x BE=0, BK=1, VI=2, VO=3
+ */
+static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *param)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ int aci;
+
+ if (queue >= AC_MAX) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("queue number %d is incorrect!\n", queue));
+ return -EINVAL;
+ }
+
+ aci = _rtl_get_hal_qnum(queue);
+ mac->ac[aci].aifs = param->aifs;
+ mac->ac[aci].cw_min = param->cw_min;
+ mac->ac[aci].cw_max = param->cw_max;
+ mac->ac[aci].tx_op = param->txop;
+ memcpy(&mac->edca_param[aci], param, sizeof(*param));
+ rtlpriv->cfg->ops->set_qos(hw, aci);
+ return 0;
+}
+
+static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf, u32 changed)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+
+ if ((changed & BSS_CHANGED_BEACON) ||
+ (changed & BSS_CHANGED_BEACON_ENABLED &&
+ bss_conf->enable_beacon)) {
+
+ if (mac->beacon_enabled == 0) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("BSS_CHANGED_BEACON_ENABLED\n"));
+
+ /*start hw beacon interrupt. */
+ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
+ mac->beacon_enabled = 1;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS],
+ 0);
+ }
+ } else {
+ if (mac->beacon_enabled == 1) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("ADHOC DISABLE BEACON\n"));
+
+ mac->beacon_enabled = 0;
+ rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+ rtlpriv->cfg->maps
+ [RTL_IBSS_INT_MASKS]);
+ }
+ }
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
+ ("BSS_CHANGED_BEACON_INT\n"));
+ mac->beacon_interval = bss_conf->beacon_int;
+ rtlpriv->cfg->ops->set_bcn_intv(hw);
+ }
+ }
+
+ /*TODO: reference to enum ieee80211_bss_change */
+ if (changed & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ mac->link_state = MAC80211_LINKED;
+ mac->cnt_after_linked = 0;
+ mac->assoc_id = bss_conf->aid;
+ memcpy(mac->bssid, bss_conf->bssid, 6);
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("BSS_CHANGED_ASSOC\n"));
+ } else {
+ if (mac->link_state == MAC80211_LINKED)
+ rtl_lps_leave(hw);
+
+ mac->link_state = MAC80211_NOLINK;
+ memset(mac->bssid, 0, 6);
+
+ /* reset sec info */
+ rtl_cam_reset_sec_info(hw);
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ ("BSS_CHANGED_UN_ASSOC\n"));
+ }
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("BSS_CHANGED_ERP_CTS_PROT\n"));
+ mac->use_cts_protect = bss_conf->use_cts_prot;
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
+ bss_conf->use_short_preamble));
+
+ mac->short_preamble = bss_conf->use_short_preamble;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
+ (u8 *) (&mac->short_preamble));
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("BSS_CHANGED_ERP_SLOT\n"));
+
+ if (bss_conf->use_short_slot)
+ mac->slot_time = RTL_SLOT_TIME_9;
+ else
+ mac->slot_time = RTL_SLOT_TIME_20;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+ (u8 *) (&mac->slot_time));
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ struct ieee80211_sta *sta = NULL;
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("BSS_CHANGED_HT\n"));
+
+ sta = ieee80211_find_sta(mac->vif, mac->bssid);
+
+ if (sta) {
+ if (sta->ht_cap.ampdu_density >
+ mac->current_ampdu_density)
+ mac->current_ampdu_density =
+ sta->ht_cap.ampdu_density;
+ if (sta->ht_cap.ampdu_factor <
+ mac->current_ampdu_factor)
+ mac->current_ampdu_factor =
+ sta->ht_cap.ampdu_factor;
+ }
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
+ (u8 *) (&mac->max_mss_density));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
+ &mac->current_ampdu_factor);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
+ &mac->current_ampdu_density);
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+ struct ieee80211_sta *sta = NULL;
+ u32 basic_rates;
+ u8 i;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
+ (u8 *) bss_conf->bssid);
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+ (MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
+
+ memcpy(mac->bssid, bss_conf->bssid, 6);
+ if (is_valid_ether_addr(bss_conf->bssid)) {
+ switch (vif->type) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ break;
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_AP:
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+ } else
+ rtlpriv->cfg->ops->set_network_type(hw,
+ NL80211_IFTYPE_UNSPECIFIED);
+
+ memset(mac->mcs, 0, 16);
+ mac->ht_enable = false;
+ mac->sgi_40 = false;
+ mac->sgi_20 = false;
+
+ if (!bss_conf->use_short_slot)
+ mac->mode = WIRELESS_MODE_B;
+ else
+ mac->mode = WIRELESS_MODE_G;
+
+ sta = ieee80211_find_sta(mac->vif, mac->bssid);
+
+ if (sta) {
+ if (sta->ht_cap.ht_supported) {
+ mac->mode = WIRELESS_MODE_N_24G;
+ mac->ht_enable = true;
+ }
+
+ if (mac->ht_enable) {
+ u16 ht_cap = sta->ht_cap.cap;
+ memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16);
+
+ for (i = 0; i < 16; i++)
+ RT_TRACE(rtlpriv, COMP_MAC80211,
+ DBG_LOUD, ("%x ",
+ mac->mcs[i]));
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
+ ("\n"));
+
+ if (ht_cap & IEEE80211_HT_CAP_SGI_40)
+ mac->sgi_40 = true;
+
+ if (ht_cap & IEEE80211_HT_CAP_SGI_20)
+ mac->sgi_20 = true;
+
+ /*
+ * for cisco 1252 bw20 it's wrong
+ * if (ht_cap &
+ * IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+ * mac->bw_40 = true;
+ * }
+ */
+ }
+ }
+
+ /*mac80211 just give us CCK rates any time
+ *So we add G rate in basic rates when
+ not in B mode*/
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ if (mac->mode == WIRELESS_MODE_B)
+ basic_rates = bss_conf->basic_rates | 0x00f;
+ else
+ basic_rates = bss_conf->basic_rates | 0xff0;
+
+ if (!vif)
+ goto out;
+
+ mac->basic_rates = basic_rates;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *) (&basic_rates));
+
+ if (rtlpriv->dm.b_useramask)
+ rtlpriv->cfg->ops->update_rate_mask(hw, 0);
+ else
+ rtlpriv->cfg->ops->update_rate_table(hw);
+
+ }
+ }
+
+ /*
+ * For FW LPS:
+ * To tell firmware we have connected
+ * to an AP. For 92SE/CE power save v2.
+ */
+ if (changed & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ if (ppsc->b_fwctrl_lps) {
+ u8 mstatus = RT_MEDIA_CONNECT;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *) (&mstatus));
+ ppsc->report_linked = true;
+ }
+ } else {
+ if (ppsc->b_fwctrl_lps) {
+ u8 mstatus = RT_MEDIA_DISCONNECT;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)(&mstatus));
+ ppsc->report_linked = false;
+ }
+ }
+ }
+
+out:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u64 tsf;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
+ return tsf;
+}
+
+static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;;
+
+ mac->tsf = tsf;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
+}
+
+static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp = 0;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
+}
+
+static void rtl_op_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ break;
+ case STA_NOTIFY_AWAKE:
+ break;
+ default:
+ break;
+ }
+}
+
+static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 * ssn)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ switch (action) {
+ case IEEE80211_AMPDU_TX_START:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
+ return rtl_tx_agg_start(hw, sta->addr, tid, ssn);
+ break;
+ case IEEE80211_AMPDU_TX_STOP:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
+ return rtl_tx_agg_stop(hw, sta->addr, tid);
+ break;
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+ break;
+ case IEEE80211_AMPDU_RX_START:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
+ break;
+ case IEEE80211_AMPDU_RX_STOP:
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
+ ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("IEEE80211_AMPDU_ERR!!!!:\n"));
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ mac->act_scanning = true;
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+
+ if (mac->link_state == MAC80211_LINKED) {
+ rtl_lps_leave(hw);
+ mac->link_state = MAC80211_LINKED_SCANNING;
+ } else
+ rtl_ips_nic_on(hw);
+
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
+}
+
+static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
+ mac->act_scanning = false;
+ if (mac->link_state == MAC80211_LINKED_SCANNING) {
+ mac->link_state = MAC80211_LINKED;
+
+ /* fix fwlps issue */
+ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+
+ if (rtlpriv->dm.b_useramask)
+ rtlpriv->cfg->ops->update_rate_mask(hw, 0);
+ else
+ rtlpriv->cfg->ops->update_rate_table(hw);
+
+ }
+
+}
+
+static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 key_type = NO_ENCRYPTION;
+ u8 key_idx;
+ bool group_key = false;
+ bool wep_only = false;
+ int err = 0;
+ u8 mac_addr[ETH_ALEN];
+ u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ u8 zero_addr[ETH_ALEN] = { 0 };
+
+ if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("not open hw encryption\n"));
+ return -ENOSPC; /*User disabled HW-crypto */
+ }
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
+ cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+ sta ? sta->addr : bcast_addr));
+ rtlpriv->sec.being_setkey = true;
+ rtl_ips_nic_on(hw);
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+ /* <1> get encryption alg */
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key_type = WEP40_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
+ rtlpriv->sec.use_defaultkey = true;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("alg:WEP104\n"));
+ key_type = WEP104_ENCRYPTION;
+ rtlpriv->sec.use_defaultkey = true;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key_type = TKIP_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ rtlpriv->sec.use_defaultkey = true;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key_type = AESCCMP_ENCRYPTION;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ rtlpriv->sec.use_defaultkey = true;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("alg_err:%x!!!!:\n", key->cipher));
+ goto out_unlock;
+ }
+ /* <2> get key_idx */
+ key_idx = (u8) (key->keyidx);
+ if (key_idx > 3)
+ goto out_unlock;
+ /* <3> if pairwise key enable_hw_sec */
+ group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
+ if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
+ rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
+ if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
+ (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION))
+ wep_only = true;
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ rtlpriv->cfg->ops->enable_hw_sec(hw);
+ }
+ /* <4> set key based on cmd */
+ switch (cmd) {
+ case SET_KEY:
+ if (wep_only) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set WEP(group/pairwise) key\n"));
+ /* Pairwise key with an assigned MAC address. */
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ rtlpriv->sec.group_enc_algorithm = key_type;
+ /*set local buf about wep key. */
+ memcpy(rtlpriv->sec.key_buf[key_idx],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = key->keylen;
+ memcpy(mac_addr, zero_addr, ETH_ALEN);
+ } else if (group_key) { /* group key */
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set group key\n"));
+ /* group key */
+ rtlpriv->sec.group_enc_algorithm = key_type;
+ /*set local buf about group key. */
+ memcpy(rtlpriv->sec.key_buf[key_idx],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = key->keylen;
+ memcpy(mac_addr, bcast_addr, ETH_ALEN);
+ } else { /* pairwise key */
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set pairwise key\n"));
+ if (!sta) {
+ RT_ASSERT(false, ("pairwise key withnot"
+ "mac_addr\n"));
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ /* Pairwise key with an assigned MAC address. */
+ rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ /*set local buf about pairwise key. */
+ memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
+ key->key, key->keylen);
+ rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
+ rtlpriv->sec.pairwise_key =
+ rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
+ memcpy(mac_addr, sta->addr, ETH_ALEN);
+ }
+ rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
+ group_key, key_type, wep_only,
+ false);
+ /* <5> tell mac80211 do something: */
+ /*must use sw generate IV, or can not work !!!!. */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ key->hw_key_idx = key_idx;
+ if (key_type == TKIP_ENCRYPTION)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ break;
+ case DISABLE_KEY:
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("disable key delete one entry\n"));
+ /*set local buf about wep key. */
+ memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
+ rtlpriv->sec.key_len[key_idx] = 0;
+ memcpy(mac_addr, zero_addr, ETH_ALEN);
+ /*
+ *mac80211 will delete entrys one by one,
+ *so don't use rtl_cam_reset_all_entry
+ *or clear all entry here.
+ */
+ rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("cmd_err:%x!!!!:\n", cmd));
+ }
+out_unlock:
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+ rtlpriv->sec.being_setkey = false;
+ return err;
+}
+
+static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ bool radio_state;
+ bool blocked;
+ u8 valid = 0;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ return;
+
+ mutex_lock(&rtlpriv->locks.conf_mutex);
+
+ /*if Radio On return true here */
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+ if (valid) {
+ if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
+ rtlpriv->rfkill.rfkill_state = radio_state;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ (KERN_INFO "wireless radio switch turned %s\n",
+ radio_state ? "on" : "off"));
+
+ blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+ }
+ }
+
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+const struct ieee80211_ops rtl_ops = {
+ .start = rtl_op_start,
+ .stop = rtl_op_stop,
+ .tx = rtl_op_tx,
+ .add_interface = rtl_op_add_interface,
+ .remove_interface = rtl_op_remove_interface,
+ .config = rtl_op_config,
+ .configure_filter = rtl_op_configure_filter,
+ .set_key = rtl_op_set_key,
+ .conf_tx = rtl_op_conf_tx,
+ .bss_info_changed = rtl_op_bss_info_changed,
+ .get_tsf = rtl_op_get_tsf,
+ .set_tsf = rtl_op_set_tsf,
+ .reset_tsf = rtl_op_reset_tsf,
+ .sta_notify = rtl_op_sta_notify,
+ .ampdu_action = rtl_op_ampdu_action,
+ .sw_scan_start = rtl_op_sw_scan_start,
+ .sw_scan_complete = rtl_op_sw_scan_complete,
+ .rfkill_poll = rtl_op_rfkill_poll,
+};
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
new file mode 100644
index 000000000000..0ef31c3c6196
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#ifndef __RTL_CORE_H__
+#define __RTL_CORE_H__
+
+#define RTL_SUPPORTED_FILTERS \
+ (FIF_PROMISC_IN_BSS | \
+ FIF_ALLMULTI | FIF_CONTROL | \
+ FIF_OTHER_BSS | \
+ FIF_FCSFAIL | \
+ FIF_BCN_PRBRESP_PROMISC)
+
+#define RTL_SUPPORTED_CTRL_FILTER 0xFF
+
+extern const struct ieee80211_ops rtl_ops;
+#endif
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
new file mode 100644
index 000000000000..5fa73852cb66
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#include "wifi.h"
+
+void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 i;
+
+ rtlpriv->dbg.global_debuglevel = DBG_EMERG;
+
+ rtlpriv->dbg.global_debugcomponents =
+ COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
+ COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
+ COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
+ COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
+ COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
+ COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN;
+
+ for (i = 0; i < DBGP_TYPE_MAX; i++)
+ rtlpriv->dbg.dbgp_type[i] = 0;
+
+ /*Init Debug flag enable condition */
+}
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
new file mode 100644
index 000000000000..08bdec2ceda4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -0,0 +1,212 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *****************************************************************************/
+
+#ifndef __RTL_DEBUG_H__
+#define __RTL_DEBUG_H__
+
+/*--------------------------------------------------------------
+ Debug level
+--------------------------------------------------------------*/
+/*
+ *Fatal bug.
+ *For example, Tx/Rx/IO locked up,
+ *memory access violation,
+ *resource allocation failed,
+ *unexpected HW behavior, HW BUG
+ *and so on.
+ */
+#define DBG_EMERG 0
+
+/*
+ *Abnormal, rare, or unexpeted cases.
+ *For example, Packet/IO Ctl canceled,
+ *device suprisely unremoved and so on.
+ */
+#define DBG_WARNING 2
+
+/*
+ *Normal case driver developer should
+ *open, we can see link status like
+ *assoc/AddBA/DHCP/adapter start and
+ *so on basic and useful infromations.
+ */
+#define DBG_DMESG 3
+
+/*
+ *Normal case with useful information
+ *about current SW or HW state.
+ *For example, Tx/Rx descriptor to fill,
+ *Tx/Rx descriptor completed status,
+ *SW protocol state change, dynamic
+ *mechanism state change and so on.
+ */
+#define DBG_LOUD 4
+
+/*
+ *Normal case with detail execution
+ *flow or information.
+ */
+#define DBG_TRACE 5
+
+/*--------------------------------------------------------------
+ Define the rt_trace components
+--------------------------------------------------------------*/
+#define COMP_ERR BIT(0)
+#define COMP_FW BIT(1)
+#define COMP_INIT BIT(2) /*For init/deinit */
+#define COMP_RECV BIT(3) /*For Rx. */
+#define COMP_SEND BIT(4) /*For Tx. */
+#define COMP_MLME BIT(5) /*For MLME. */
+#define COMP_SCAN BIT(6) /*For Scan. */
+#define COMP_INTR BIT(7) /*For interrupt Related. */
+#define COMP_LED BIT(8) /*For LED. */
+#define COMP_SEC BIT(9) /*For sec. */
+#define COMP_BEACON BIT(10) /*For beacon. */
+#define COMP_RATE BIT(11) /*For rate. */
+#define COMP_RXDESC BIT(12) /*For rx desc. */
+#define COMP_DIG BIT(13) /*For DIG */
+#define COMP_TXAGC BIT(14) /*For Tx power */
+#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
+#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
+#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
+#define COMP_BB_POWERSAVING BIT(18)
+#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
+#define COMP_RF BIT(20) /*For RF. */
+#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
+#define COMP_RATR BIT(22)
+#define COMP_CMD BIT(23)
+#define COMP_EFUSE BIT(24)
+#define COMP_QOS BIT(25)
+#define COMP_MAC80211 BIT(26)
+#define COMP_REGD BIT(27)
+#define COMP_CHAN BIT(28)
+
+/*--------------------------------------------------------------
+ Define the rt_print components
+--------------------------------------------------------------*/
+/* Define EEPROM and EFUSE check module bit*/
+#define EEPROM_W BIT(0)
+#define EFUSE_PG BIT(1)
+#define EFUSE_READ_ALL BIT(2)
+
+/* Define init check for module bit*/
+#define INIT_EEPROM BIT(0)
+#define INIT_TxPower BIT(1)
+#define INIT_IQK BIT(2)
+#define INIT_RF BIT(3)
+
+/* Define PHY-BB/RF/MAC check module bit */
+#define PHY_BBR BIT(0)
+#define PHY_BBW BIT(1)
+#define PHY_RFR BIT(2)
+#define PHY_RFW BIT(3)
+#define PHY_MACR BIT(4)
+#define PHY_MACW BIT(5)
+#define PHY_ALLR BIT(6)
+#define PHY_ALLW BIT(7)
+#define PHY_TXPWR BIT(8)
+#define PHY_PWRDIFF BIT(9)
+
+enum dbgp_flag_e {
+ FQOS = 0,
+ FTX = 1,
+ FRX = 2,
+ FSEC = 3,
+ FMGNT = 4,
+ FMLME = 5,
+ FRESOURCE = 6,
+ FBEACON = 7,
+ FISR = 8,
+ FPHY = 9,
+ FMP = 10,
+ FEEPROM = 11,
+ FPWR = 12,
+ FDM = 13,
+ FDBGCtrl = 14,
+ FC2H = 15,
+ FBT = 16,
+ FINIT = 17,
+ FIOCTL = 18,
+ DBGP_TYPE_MAX
+};
+
+#define RT_ASSERT(_exp, fmt) \
+ do { \
+ if (!(_exp)) { \
+ printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
+ __func__); \
+ printk fmt; \
+ } \
+ } while (0);
+
+#define RT_TRACE(rtlpriv, comp, level, fmt)\
+ do { \
+ if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
+ ((level) <= rtlpriv->dbg.global_debuglevel))) {\
+ printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
+ __func__, in_interrupt(), in_atomic()); \
+ printk fmt; \
+ } \
+ } while (0);
+
+#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \
+ do { \
+ if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
+ printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
+ printk printstr; \
+ } \
+ } while (0);
+
+#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
+ _hexdatalen) \
+ do {\
+ if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
+ (_level <= rtlpriv->dbg.global_debuglevel))) { \
+ int __i; \
+ u8* ptr = (u8 *)_hexdata; \
+ printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
+ printk("In process \"%s\" (pid %i):", current->comm,\
+ current->pid); \
+ printk(_titlestring); \
+ for (__i = 0; __i < (int)_hexdatalen; __i++) { \
+ printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
+ == 0) ? " " : " ");\
+ if (((__i + 1) % 16) == 0) \
+ printk("\n"); \
+ } \
+ printk(KERN_DEBUG "\n"); \
+ } \
+ } while (0);
+
+#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]
+
+void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
new file mode 100644
index 000000000000..b8433f3a9bc2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -0,0 +1,1189 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "efuse.h"
+
+static const u8 MAX_PGPKT_SIZE = 9;
+static const u8 PGPKT_DATA_SIZE = 8;
+static const int EFUSE_MAX_SIZE = 512;
+
+static const u8 EFUSE_OOB_PROTECT_BYTES = 15;
+
+static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
+ {0, 0, 0, 2},
+ {0, 1, 0, 2},
+ {0, 2, 0, 2},
+ {1, 0, 0, 1},
+ {1, 0, 1, 1},
+ {1, 1, 0, 1},
+ {1, 1, 1, 3},
+ {1, 3, 0, 17},
+ {3, 3, 1, 48},
+ {10, 0, 0, 6},
+ {10, 3, 0, 1},
+ {10, 3, 1, 1},
+ {11, 0, 0, 28}
+};
+
+static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset,
+ u8 *pbuf);
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
+ u8 *value);
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
+ u16 *value);
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
+ u32 *value);
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
+ u8 value);
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
+ u16 value);
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
+ u32 value);
+static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr,
+ u8 *data);
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
+ u8 data);
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
+ u8 *data);
+static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
+ u8 word_en, u8 *data);
+static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
+ u8 *targetdata);
+static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
+ u16 efuse_addr, u8 word_en, u8 *data);
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
+ u8 pwrstate);
+static u16 efuse_get_current_size(struct ieee80211_hw *hw);
+static u8 efuse_calculate_word_cnts(u8 word_en);
+
+void efuse_initialize(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bytetemp;
+ u8 temp;
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
+ temp = bytetemp | 0x20;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
+ temp = bytetemp & 0xFE;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
+ temp = bytetemp | 0x80;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
+
+ rtl_write_byte(rtlpriv, 0x2F8, 0x3);
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+
+}
+
+u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 data;
+ u8 bytetemp;
+ u8 temp;
+ u32 k = 0;
+
+ if (address < EFUSE_REAL_CONTENT_LEN) {
+ temp = address & 0xFF;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ temp);
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+ temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ temp = bytetemp & 0x7F;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+ temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ while (!(bytetemp & 0x80)) {
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->
+ maps[EFUSE_CTRL] + 3);
+ k++;
+ if (k == 1000) {
+ k = 0;
+ break;
+ }
+ }
+ data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ return data;
+ } else
+ return 0xFF;
+
+}
+EXPORT_SYMBOL(efuse_read_1byte);
+
+void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bytetemp;
+ u8 temp;
+ u32 k = 0;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("Addr=%x Data =%x\n", address, value));
+
+ if (address < EFUSE_REAL_CONTENT_LEN) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
+
+ temp = address & 0xFF;
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ temp);
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+
+ temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ temp = bytetemp | 0x80;
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
+
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+
+ while (bytetemp & 0x80) {
+ bytetemp = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->
+ maps[EFUSE_CTRL] + 3);
+ k++;
+ if (k == 100) {
+ k = 0;
+ break;
+ }
+ }
+ }
+
+}
+
+static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 value32;
+ u8 readbyte;
+ u16 retry;
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ (_offset & 0xff));
+ readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
+
+ readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+ (readbyte & 0x7f));
+
+ retry = 0;
+ value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
+ value32 = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL]);
+ retry++;
+ }
+
+ udelay(50);
+ value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+
+ *pbuf = (u8) (value32 & 0xff);
+}
+
+void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 efuse_tbl[EFUSE_MAP_LEN];
+ u8 rtemp8[1];
+ u16 efuse_addr = 0;
+ u8 offset, wren;
+ u16 i;
+ u16 j;
+ u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
+ u16 efuse_utilized = 0;
+ u8 efuse_usage;
+
+ if ((_offset + _size_byte) > EFUSE_MAP_LEN) {
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("read_efuse(): Invalid offset(%#x) with read "
+ "bytes(%#x)!!\n", _offset, _size_byte));
+ return;
+ }
+
+ for (i = 0; i < EFUSE_MAX_SECTION; i++)
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+ efuse_word[i][j] = 0xFFFF;
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ if (*rtemp8 != 0xFF) {
+ efuse_utilized++;
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ ("Addr=%d\n", efuse_addr));
+ efuse_addr++;
+ }
+
+ while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) {
+ offset = ((*rtemp8 >> 4) & 0x0f);
+
+ if (offset < EFUSE_MAX_SECTION) {
+ wren = (*rtemp8 & 0x0f);
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ ("offset-%d Worden=%x\n", offset, wren));
+
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ if (!(wren & 0x01)) {
+ RTPRINT(rtlpriv, FEEPROM,
+ EFUSE_READ_ALL, ("Addr=%d\n",
+ efuse_addr));
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ efuse_addr++;
+ efuse_utilized++;
+ efuse_word[offset][i] = (*rtemp8 & 0xff);
+
+ if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ break;
+
+ RTPRINT(rtlpriv, FEEPROM,
+ EFUSE_READ_ALL, ("Addr=%d\n",
+ efuse_addr));
+
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ efuse_addr++;
+ efuse_utilized++;
+ efuse_word[offset][i] |=
+ (((u16)*rtemp8 << 8) & 0xff00);
+
+ if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ break;
+ }
+
+ wren >>= 1;
+ }
+ }
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+ ("Addr=%d\n", efuse_addr));
+ read_efuse_byte(hw, efuse_addr, rtemp8);
+ if (*rtemp8 != 0xFF && (efuse_addr < 512)) {
+ efuse_utilized++;
+ efuse_addr++;
+ }
+ }
+
+ for (i = 0; i < EFUSE_MAX_SECTION; i++) {
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+ efuse_tbl[(i * 8) + (j * 2)] =
+ (efuse_word[i][j] & 0xff);
+ efuse_tbl[(i * 8) + ((j * 2) + 1)] =
+ ((efuse_word[i][j] >> 8) & 0xff);
+ }
+ }
+
+ for (i = 0; i < _size_byte; i++)
+ pbuf[i] = efuse_tbl[_offset + i];
+
+ rtlefuse->efuse_usedbytes = efuse_utilized;
+ efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN);
+ rtlefuse->efuse_usedpercentage = efuse_usage;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
+ (u8 *)&efuse_utilized);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
+ (u8 *)&efuse_usage);
+}
+
+bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 section_idx, i, Base;
+ u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
+ bool bwordchanged, bresult = true;
+
+ for (section_idx = 0; section_idx < 16; section_idx++) {
+ Base = section_idx * 8;
+ bwordchanged = false;
+
+ for (i = 0; i < 8; i = i + 2) {
+ if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) ||
+ (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
+ 1])) {
+ words_need++;
+ bwordchanged = true;
+ }
+ }
+
+ if (bwordchanged == true)
+ hdr_num++;
+ }
+
+ totalbytes = hdr_num + words_need * 2;
+ efuse_used = rtlefuse->efuse_usedbytes;
+
+ if ((totalbytes + efuse_used) >=
+ (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))
+ bresult = false;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("efuse_shadow_update_chk(): totalbytes(%#x), "
+ "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
+ totalbytes, hdr_num, words_need, efuse_used));
+
+ return bresult;
+}
+
+void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 *value)
+{
+ if (type == 1)
+ efuse_shadow_read_1byte(hw, offset, (u8 *) value);
+ else if (type == 2)
+ efuse_shadow_read_2byte(hw, offset, (u16 *) value);
+ else if (type == 4)
+ efuse_shadow_read_4byte(hw, offset, (u32 *) value);
+
+}
+
+void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
+ u32 value)
+{
+ if (type == 1)
+ efuse_shadow_write_1byte(hw, offset, (u8) value);
+ else if (type == 2)
+ efuse_shadow_write_2byte(hw, offset, (u16) value);
+ else if (type == 4)
+ efuse_shadow_write_4byte(hw, offset, (u32) value);
+
+}
+
+bool efuse_shadow_update(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u16 i, offset, base;
+ u8 word_en = 0x0F;
+ u8 first_pg = false;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n"));
+
+ if (!efuse_shadow_update_chk(hw)) {
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+ memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("<---efuse out of capacity!!\n"));
+ return false;
+ }
+ efuse_power_switch(hw, true, true);
+
+ for (offset = 0; offset < 16; offset++) {
+
+ word_en = 0x0F;
+ base = offset * 8;
+
+ for (i = 0; i < 8; i++) {
+ if (first_pg == true) {
+
+ word_en &= ~(BIT(i / 2));
+
+ rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+ } else {
+
+ if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
+ word_en &= ~(BIT(i / 2));
+
+ rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+ }
+ }
+ }
+
+ if (word_en != 0x0F) {
+ u8 tmpdata[8];
+ memcpy((void *)tmpdata,
+ (void *)(&rtlefuse->
+ efuse_map[EFUSE_MODIFY_MAP][base]), 8);
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("U-efuse\n"), tmpdata, 8);
+
+ if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
+ tmpdata)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("PG section(%#x) fail!!\n", offset));
+ break;
+ }
+ }
+
+ }
+
+ efuse_power_switch(hw, true, false);
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+
+ memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n"));
+ return true;
+}
+
+void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ if (rtlefuse->autoload_failflag == true) {
+ memset((void *)(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), 128,
+ 0xFF);
+ } else
+ efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+
+ memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+ (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+}
+EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
+
+void efuse_force_write_vendor_Id(struct ieee80211_hw *hw)
+{
+ u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ efuse_power_switch(hw, true, true);
+
+ efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
+
+ efuse_power_switch(hw, true, false);
+
+}
+
+void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
+{
+}
+
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
+ u16 offset, u8 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+}
+
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
+ u16 offset, u16 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+
+}
+
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
+ u16 offset, u32 *value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
+ *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
+}
+
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
+ u16 offset, u8 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
+}
+
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
+ u16 offset, u16 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
+
+}
+
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
+ u16 offset, u32 value)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
+ (u8) (value & 0x000000FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
+ (u8) ((value >> 8) & 0x0000FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
+ (u8) ((value >> 16) & 0x00FF);
+ rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
+ (u8) ((value >> 24) & 0xFF);
+
+}
+
+static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmpidx = 0;
+ int bresult;
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ (u8) (addr & 0xff));
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ ((u8) ((addr >> 8) & 0x03)) |
+ (rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
+ 0xFC));
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+
+ while (!(0x80 & rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
+ && (tmpidx < 100)) {
+ tmpidx++;
+ }
+
+ if (tmpidx < 100) {
+ *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+ bresult = true;
+ } else {
+ *data = 0xff;
+ bresult = false;
+ }
+ return bresult;
+}
+
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmpidx = 0;
+ bool bresult;
+
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("Addr = %x Data=%x\n", addr, data));
+
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+ (rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] +
+ 2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
+
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
+
+ while ((0x80 & rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
+ && (tmpidx < 100)) {
+ tmpidx++;
+ }
+
+ if (tmpidx < 100)
+ bresult = true;
+ else
+ bresult = false;
+
+ return bresult;
+}
+
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
+{
+ efuse_power_switch(hw, false, true);
+ read_efuse(hw, 0, 128, efuse);
+ efuse_power_switch(hw, false, false);
+}
+
+static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+ u8 efuse_data, u8 offset, u8 *tmpdata,
+ u8 *readstate)
+{
+ bool bdataempty = true;
+ u8 hoffset;
+ u8 tmpidx;
+ u8 hworden;
+ u8 word_cnts;
+
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = efuse_calculate_word_cnts(hworden);
+
+ if (hoffset == offset) {
+ for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
+ if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
+ &efuse_data)) {
+ tmpdata[tmpidx] = efuse_data;
+ if (efuse_data != 0xff)
+ bdataempty = true;
+ }
+ }
+
+ if (bdataempty == true)
+ *readstate = PG_STATE_DATA;
+ else {
+ *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+ *readstate = PG_STATE_HEADER;
+ }
+
+ } else {
+ *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+ *readstate = PG_STATE_HEADER;
+ }
+}
+
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
+{
+ u8 readstate = PG_STATE_HEADER;
+
+ bool bcontinual = true;
+
+ u8 efuse_data, word_cnts = 0;
+ u16 efuse_addr = 0;
+ u8 hworden;
+ u8 tmpdata[8];
+
+ if (data == NULL)
+ return false;
+ if (offset > 15)
+ return false;
+
+ memset((void *)data, PGPKT_DATA_SIZE * sizeof(u8), 0xff);
+ memset((void *)tmpdata, PGPKT_DATA_SIZE * sizeof(u8), 0xff);
+
+ while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
+ if (readstate & PG_STATE_HEADER) {
+ if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+ && (efuse_data != 0xFF))
+ efuse_read_data_case1(hw, &efuse_addr,
+ efuse_data,
+ offset, tmpdata,
+ &readstate);
+ else
+ bcontinual = false;
+ } else if (readstate & PG_STATE_DATA) {
+ efuse_word_enable_data_read(hworden, tmpdata, data);
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ readstate = PG_STATE_HEADER;
+ }
+
+ }
+
+ if ((data[0] == 0xff) && (data[1] == 0xff) &&
+ (data[2] == 0xff) && (data[3] == 0xff) &&
+ (data[4] == 0xff) && (data[5] == 0xff) &&
+ (data[6] == 0xff) && (data[7] == 0xff))
+ return false;
+ else
+ return true;
+
+}
+
+static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+ u8 efuse_data, u8 offset, int *bcontinual,
+ u8 *write_state, struct pgpkt_struct target_pkt,
+ int *repeat_times, int *bresult, u8 word_en)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct tmp_pkt;
+ int bdataempty = true;
+ u8 originaldata[8 * sizeof(u8)];
+ u8 badworden = 0x0F;
+ u8 match_word_en, tmp_word_en;
+ u8 tmpindex;
+ u8 tmp_header = efuse_data;
+ u8 tmp_word_cnts;
+
+ tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+ tmp_pkt.word_en = tmp_header & 0x0F;
+ tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+ if (tmp_pkt.offset != target_pkt.offset) {
+ efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
+ *write_state = PG_STATE_HEADER;
+ } else {
+ for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
+ u16 address = *efuse_addr + 1 + tmpindex;
+ if (efuse_one_byte_read(hw, address,
+ &efuse_data) && (efuse_data != 0xFF))
+ bdataempty = false;
+ }
+
+ if (bdataempty == false) {
+ efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
+ *write_state = PG_STATE_HEADER;
+ } else {
+ match_word_en = 0x0F;
+ if (!((target_pkt.word_en & BIT(0)) |
+ (tmp_pkt.word_en & BIT(0))))
+ match_word_en &= (~BIT(0));
+
+ if (!((target_pkt.word_en & BIT(1)) |
+ (tmp_pkt.word_en & BIT(1))))
+ match_word_en &= (~BIT(1));
+
+ if (!((target_pkt.word_en & BIT(2)) |
+ (tmp_pkt.word_en & BIT(2))))
+ match_word_en &= (~BIT(2));
+
+ if (!((target_pkt.word_en & BIT(3)) |
+ (tmp_pkt.word_en & BIT(3))))
+ match_word_en &= (~BIT(3));
+
+ if ((match_word_en & 0x0F) != 0x0F) {
+ badworden = efuse_word_enable_data_write(
+ hw, *efuse_addr + 1,
+ tmp_pkt.word_en,
+ target_pkt.data);
+
+ if (0x0F != (badworden & 0x0F)) {
+ u8 reorg_offset = offset;
+ u8 reorg_worden = badworden;
+ efuse_pg_packet_write(hw, reorg_offset,
+ reorg_worden,
+ originaldata);
+ }
+
+ tmp_word_en = 0x0F;
+ if ((target_pkt.word_en & BIT(0)) ^
+ (match_word_en & BIT(0)))
+ tmp_word_en &= (~BIT(0));
+
+ if ((target_pkt.word_en & BIT(1)) ^
+ (match_word_en & BIT(1)))
+ tmp_word_en &= (~BIT(1));
+
+ if ((target_pkt.word_en & BIT(2)) ^
+ (match_word_en & BIT(2)))
+ tmp_word_en &= (~BIT(2));
+
+ if ((target_pkt.word_en & BIT(3)) ^
+ (match_word_en & BIT(3)))
+ tmp_word_en &= (~BIT(3));
+
+ if ((tmp_word_en & 0x0F) != 0x0F) {
+ *efuse_addr = efuse_get_current_size(hw);
+ target_pkt.offset = offset;
+ target_pkt.word_en = tmp_word_en;
+ } else
+ *bcontinual = false;
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *bcontinual = false;
+ *bresult = false;
+ }
+ } else {
+ *efuse_addr += (2 * tmp_word_cnts) + 1;
+ target_pkt.offset = offset;
+ target_pkt.word_en = word_en;
+ *write_state = PG_STATE_HEADER;
+ }
+ }
+ }
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
+}
+
+static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
+ int *bcontinual, u8 *write_state,
+ struct pgpkt_struct target_pkt,
+ int *repeat_times, int *bresult)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct tmp_pkt;
+ u8 pg_header;
+ u8 tmp_header;
+ u8 originaldata[8 * sizeof(u8)];
+ u8 tmp_word_cnts;
+ u8 badworden = 0x0F;
+
+ pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
+ efuse_one_byte_write(hw, *efuse_addr, pg_header);
+ efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
+
+ if (tmp_header == pg_header)
+ *write_state = PG_STATE_DATA;
+ else if (tmp_header == 0xFF) {
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *bcontinual = false;
+ *bresult = false;
+ }
+ } else {
+ tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+ tmp_pkt.word_en = tmp_header & 0x0F;
+
+ tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+ memset((void *)originaldata, 8 * sizeof(u8), 0xff);
+
+ if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
+ badworden = efuse_word_enable_data_write(hw,
+ *efuse_addr + 1, tmp_pkt.word_en,
+ originaldata);
+
+ if (0x0F != (badworden & 0x0F)) {
+ u8 reorg_offset = tmp_pkt.offset;
+ u8 reorg_worden = badworden;
+ efuse_pg_packet_write(hw, reorg_offset,
+ reorg_worden,
+ originaldata);
+ *efuse_addr = efuse_get_current_size(hw);
+ } else
+ *efuse_addr = *efuse_addr + (tmp_word_cnts * 2)
+ + 1;
+ } else
+ *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+
+ *write_state = PG_STATE_HEADER;
+ *repeat_times += 1;
+ if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ *bcontinual = false;
+ *bresult = false;
+ }
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ ("efuse PG_STATE_HEADER-2\n"));
+ }
+}
+
+static int efuse_pg_packet_write(struct ieee80211_hw *hw,
+ u8 offset, u8 word_en, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct pgpkt_struct target_pkt;
+ u8 write_state = PG_STATE_HEADER;
+ int bcontinual = true, bdataempty = true, bresult = true;
+ u16 efuse_addr = 0;
+ u8 efuse_data;
+ u8 target_word_cnts = 0;
+ u8 badworden = 0x0F;
+ static int repeat_times;
+
+ if (efuse_get_current_size(hw) >=
+ (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ ("efuse_pg_packet_write error\n"));
+ return false;
+ }
+
+ target_pkt.offset = offset;
+ target_pkt.word_en = word_en;
+
+ memset((void *)target_pkt.data, 8 * sizeof(u8), 0xFF);
+
+ efuse_word_enable_data_read(word_en, data, target_pkt.data);
+ target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
+
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
+
+ while (bcontinual && (efuse_addr <
+ (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
+
+ if (write_state == PG_STATE_HEADER) {
+ bdataempty = true;
+ badworden = 0x0F;
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ ("efuse PG_STATE_HEADER\n"));
+
+ if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
+ (efuse_data != 0xFF))
+ efuse_write_data_case1(hw, &efuse_addr,
+ efuse_data, offset,
+ &bcontinual,
+ &write_state, target_pkt,
+ &repeat_times, &bresult,
+ word_en);
+ else
+ efuse_write_data_case2(hw, &efuse_addr,
+ &bcontinual,
+ &write_state,
+ target_pkt,
+ &repeat_times,
+ &bresult);
+
+ } else if (write_state == PG_STATE_DATA) {
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ ("efuse PG_STATE_DATA\n"));
+ badworden = 0x0f;
+ badworden =
+ efuse_word_enable_data_write(hw, efuse_addr + 1,
+ target_pkt.word_en,
+ target_pkt.data);
+
+ if ((badworden & 0x0F) == 0x0F) {
+ bcontinual = false;
+ } else {
+ efuse_addr =
+ efuse_addr + (2 * target_word_cnts) + 1;
+
+ target_pkt.offset = offset;
+ target_pkt.word_en = badworden;
+ target_word_cnts =
+ efuse_calculate_word_cnts(target_pkt.
+ word_en);
+ write_state = PG_STATE_HEADER;
+ repeat_times++;
+ if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+ bcontinual = false;
+ bresult = false;
+ }
+ RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+ ("efuse PG_STATE_HEADER-3\n"));
+ }
+ }
+ }
+
+ if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
+ }
+
+ return true;
+}
+
+static void efuse_word_enable_data_read(u8 word_en,
+ u8 *sourdata, u8 *targetdata)
+{
+ if (!(word_en & BIT(0))) {
+ targetdata[0] = sourdata[0];
+ targetdata[1] = sourdata[1];
+ }
+
+ if (!(word_en & BIT(1))) {
+ targetdata[2] = sourdata[2];
+ targetdata[3] = sourdata[3];
+ }
+
+ if (!(word_en & BIT(2))) {
+ targetdata[4] = sourdata[4];
+ targetdata[5] = sourdata[5];
+ }
+
+ if (!(word_en & BIT(3))) {
+ targetdata[6] = sourdata[6];
+ targetdata[7] = sourdata[7];
+ }
+}
+
+static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
+ u16 efuse_addr, u8 word_en, u8 *data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 tmpaddr;
+ u16 start_addr = efuse_addr;
+ u8 badworden = 0x0F;
+ u8 tmpdata[8];
+
+ memset((void *)tmpdata, PGPKT_DATA_SIZE, 0xff);
+ RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
+ ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
+
+ if (!(word_en & BIT(0))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[0]);
+ efuse_one_byte_write(hw, start_addr++, data[1]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
+ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
+ badworden &= (~BIT(0));
+ }
+
+ if (!(word_en & BIT(1))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[2]);
+ efuse_one_byte_write(hw, start_addr++, data[3]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
+ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
+ badworden &= (~BIT(1));
+ }
+
+ if (!(word_en & BIT(2))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[4]);
+ efuse_one_byte_write(hw, start_addr++, data[5]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
+ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
+ badworden &= (~BIT(2));
+ }
+
+ if (!(word_en & BIT(3))) {
+ tmpaddr = start_addr;
+ efuse_one_byte_write(hw, start_addr++, data[6]);
+ efuse_one_byte_write(hw, start_addr++, data[7]);
+
+ efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
+ efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
+ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
+ badworden &= (~BIT(3));
+ }
+
+ return badworden;
+}
+
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tempval;
+ u16 tmpV16;
+
+ if (pwrstate == true) {
+ tmpV16 = rtl_read_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_ISO_CTRL]);
+ if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
+ tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_ISO_CTRL],
+ tmpV16);
+ }
+
+ tmpV16 = rtl_read_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_FUNC_EN]);
+ if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
+ tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
+ }
+
+ tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
+ if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
+ (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
+ tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
+ rtlpriv->cfg->maps[EFUSE_ANA8M]);
+ rtl_write_word(rtlpriv,
+ rtlpriv->cfg->maps[SYS_CLK], tmpV16);
+ }
+ }
+
+ if (pwrstate == true) {
+ if (bwrite == true) {
+ tempval = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] +
+ 3);
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+ (tempval | 0x80));
+ }
+
+ } else {
+ if (bwrite == true) {
+ tempval = rtl_read_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] +
+ 3);
+ rtl_write_byte(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+ (tempval & 0x7F));
+ }
+
+ }
+
+}
+
+static u16 efuse_get_current_size(struct ieee80211_hw *hw)
+{
+ int bcontinual = true;
+ u16 efuse_addr = 0;
+ u8 hoffset, hworden;
+ u8 efuse_data, word_cnts;
+
+ while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+ && (efuse_addr < EFUSE_MAX_SIZE)) {
+ if (efuse_data != 0xFF) {
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = efuse_calculate_word_cnts(hworden);
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ } else {
+ bcontinual = false;
+ }
+ }
+
+ return efuse_addr;
+}
+
+static u8 efuse_calculate_word_cnts(u8 word_en)
+{
+ u8 word_cnts = 0;
+ if (!(word_en & BIT(0)))
+ word_cnts++;
+ if (!(word_en & BIT(1)))
+ word_cnts++;
+ if (!(word_en & BIT(2)))
+ word_cnts++;
+ if (!(word_en & BIT(3)))
+ word_cnts++;
+ return word_cnts;
+}
+
+void efuse_reset_loader(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 tmp_u2b;
+
+ tmp_u2b = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN]);
+ rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN],
+ (tmp_u2b & ~(BIT(12))));
+ udelay(10000);
+ rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN],
+ (tmp_u2b | BIT(12)));
+ udelay(10000);
+}
+
+bool efuse_program_map(struct ieee80211_hw *hw, char *p_filename, u8 tabletype)
+{
+ return true;
+}
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
new file mode 100644
index 000000000000..2d39a4df181b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_EFUSE_H_
+#define __RTL_EFUSE_H_
+
+#define EFUSE_REAL_CONTENT_LEN 512
+#define EFUSE_MAP_LEN 128
+#define EFUSE_MAX_SECTION 16
+#define EFUSE_MAX_WORD_UNIT 4
+
+#define EFUSE_INIT_MAP 0
+#define EFUSE_MODIFY_MAP 1
+
+#define PG_STATE_HEADER 0x01
+#define PG_STATE_WORD_0 0x02
+#define PG_STATE_WORD_1 0x04
+#define PG_STATE_WORD_2 0x08
+#define PG_STATE_WORD_3 0x10
+#define PG_STATE_DATA 0x20
+
+#define PG_SWBYTE_H 0x01
+#define PG_SWBYTE_L 0x02
+
+#define _POWERON_DELAY_
+#define _PRE_EXECUTE_READ_CMD_
+
+#define EFUSE_REPEAT_THRESHOLD_ 3
+
+struct efuse_map {
+ u8 offset;
+ u8 word_start;
+ u8 byte_start;
+ u8 byte_cnts;
+};
+
+struct pgpkt_struct {
+ u8 offset;
+ u8 word_en;
+ u8 data[8];
+};
+
+enum efuse_data_item {
+ EFUSE_CHIP_ID = 0,
+ EFUSE_LDO_SETTING,
+ EFUSE_CLK_SETTING,
+ EFUSE_SDIO_SETTING,
+ EFUSE_CCCR,
+ EFUSE_SDIO_MODE,
+ EFUSE_OCR,
+ EFUSE_F0CIS,
+ EFUSE_F1CIS,
+ EFUSE_MAC_ADDR,
+ EFUSE_EEPROM_VER,
+ EFUSE_CHAN_PLAN,
+ EFUSE_TXPW_TAB
+};
+
+enum {
+ VOLTAGE_V25 = 0x03,
+ LDOE25_SHIFT = 28,
+};
+
+struct efuse_priv {
+ u8 id[2];
+ u8 ldo_setting[2];
+ u8 clk_setting[2];
+ u8 cccr;
+ u8 sdio_mode;
+ u8 ocr[3];
+ u8 cis0[17];
+ u8 cis1[48];
+ u8 mac_addr[6];
+ u8 eeprom_verno;
+ u8 channel_plan;
+ u8 tx_power_b[14];
+ u8 tx_power_g[14];
+};
+
+extern void efuse_initialize(struct ieee80211_hw *hw);
+extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
+extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
+extern void read_efuse(struct ieee80211_hw *hw, u16 _offset,
+ u16 _size_byte, u8 *pbuf);
+extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 *value);
+extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
+ u16 offset, u32 value);
+extern bool efuse_shadow_update(struct ieee80211_hw *hw);
+extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
+extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
+extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
+extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
+extern bool efuse_program_map(struct ieee80211_hw *hw,
+ char *p_filename, u8 tabletype);
+extern void efuse_reset_loader(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
new file mode 100644
index 000000000000..0fa36aa6701a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -0,0 +1,1945 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "core.h"
+#include "wifi.h"
+#include "pci.h"
+#include "base.h"
+#include "ps.h"
+
+static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
+ INTEL_VENDOR_ID,
+ ATI_VENDOR_ID,
+ AMD_VENDOR_ID,
+ SIS_VENDOR_ID
+};
+
+/* Update PCI dependent default settings*/
+static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+
+ ppsc->reg_rfps_level = 0;
+ ppsc->b_support_aspm = 0;
+
+ /*Update PCI ASPM setting */
+ ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
+ switch (rtlpci->const_pci_aspm) {
+ case 0:
+ /*No ASPM */
+ break;
+
+ case 1:
+ /*ASPM dynamically enabled/disable. */
+ ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM;
+ break;
+
+ case 2:
+ /*ASPM with Clock Req dynamically enabled/disable. */
+ ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ break;
+
+ case 3:
+ /*
+ * Always enable ASPM and Clock Req
+ * from initialization to halt.
+ * */
+ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM);
+ ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ break;
+
+ case 4:
+ /*
+ * Always enable ASPM without Clock Req
+ * from initialization to halt.
+ * */
+ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM |
+ RT_RF_OFF_LEVL_CLK_REQ);
+ ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM;
+ break;
+ }
+
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+
+ /*Update Radio OFF setting */
+ switch (rtlpci->const_hwsw_rfoff_d3) {
+ case 1:
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+ break;
+
+ case 2:
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+ break;
+
+ case 3:
+ ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3;
+ break;
+ }
+
+ /*Set HW definition to determine if it supports ASPM. */
+ switch (rtlpci->const_support_pciaspm) {
+ case 0:{
+ /*Not support ASPM. */
+ bool b_support_aspm = false;
+ ppsc->b_support_aspm = b_support_aspm;
+ break;
+ }
+ case 1:{
+ /*Support ASPM. */
+ bool b_support_aspm = true;
+ bool b_support_backdoor = true;
+ ppsc->b_support_aspm = b_support_aspm;
+
+ /*if(priv->oem_id == RT_CID_TOSHIBA &&
+ !priv->ndis_adapter.amd_l1_patch)
+ b_support_backdoor = false; */
+
+ ppsc->b_support_backdoor = b_support_backdoor;
+
+ break;
+ }
+ case 2:
+ /*ASPM value set by chipset. */
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
+ bool b_support_aspm = true;
+ ppsc->b_support_aspm = b_support_aspm;
+ }
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+}
+
+static bool _rtl_pci_platform_switch_device_pci_aspm(
+ struct ieee80211_hw *hw,
+ u8 value)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ bool bresult = false;
+
+ value |= 0x40;
+
+ pci_write_config_byte(rtlpci->pdev, 0x80, value);
+
+ return bresult;
+}
+
+/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
+static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 buffer;
+ bool bresult = false;
+
+ buffer = value;
+
+ pci_write_config_byte(rtlpci->pdev, 0x81, value);
+ bresult = true;
+
+ return bresult;
+}
+
+/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
+static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+ u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ /*Retrieve original configuration settings. */
+ u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
+ u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
+ pcibridge_linkctrlreg;
+ u16 aspmlevel = 0;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("PCI(Bridge) UNKNOWN.\n"));
+
+ return;
+ }
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+ _rtl_pci_switch_clk_req(hw, 0x0);
+ }
+
+ if (1) {
+ /*for promising device will in L0 state after an I/O. */
+ u8 tmp_u1b;
+ pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
+ }
+
+ /*Set corresponding value. */
+ aspmlevel |= BIT(0) | BIT(1);
+ linkctrl_reg &= ~aspmlevel;
+ pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
+
+ _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
+ udelay(50);
+
+ /*4 Disable Pci Bridge ASPM */
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + (num4bytes << 2));
+ rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
+
+ udelay(50);
+
+}
+
+/*
+ *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
+ *power saving We should follow the sequence to enable
+ *RTL8192SE first then enable Pci Bridge ASPM
+ *or the system will show bluescreen.
+ */
+static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_busnum = pcipriv->ndis_adapter.pcibridge_busnum;
+ u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum;
+ u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum;
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+ u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ u16 aspmlevel;
+ u8 u_pcibridge_aspmsetting;
+ u8 u_device_aspmsetting;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("PCI(Bridge) UNKNOWN.\n"));
+ return;
+ }
+
+ /*4 Enable Pci Bridge ASPM */
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + (num4bytes << 2));
+
+ u_pcibridge_aspmsetting =
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg |
+ rtlpci->const_hostpci_aspm_setting;
+
+ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
+ u_pcibridge_aspmsetting &= ~BIT(0);
+
+ rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("PlatformEnableASPM():PciBridge busnumber[%x], "
+ "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
+ pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
+ (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+ u_pcibridge_aspmsetting));
+
+ udelay(50);
+
+ /*Get ASPM level (with/without Clock Req) */
+ aspmlevel = rtlpci->const_devicepci_aspm_setting;
+ u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
+
+ /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/
+ /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */
+
+ u_device_aspmsetting |= aspmlevel;
+
+ _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+ _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
+ RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+ }
+ udelay(200);
+}
+
+static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+
+ bool status = false;
+ u8 offset_e0;
+ unsigned offset_e4;
+
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + 0xE0);
+ rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0);
+
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + 0xE0);
+ rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0);
+
+ if (offset_e0 == 0xA0) {
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + 0xE4);
+ rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4);
+ if (offset_e4 & BIT(23))
+ status = true;
+ }
+
+ return status;
+}
+
+static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
+ u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+ u8 linkctrl_reg;
+ u8 num4bBytes;
+
+ num4bBytes = (capabilityoffset + 0x10) / 4;
+
+ /*Read Link Control Register */
+ rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+ pcicfg_addrport + (num4bBytes << 2));
+ rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
+
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
+}
+
+static void rtl_pci_parse_configuration(struct pci_dev *pdev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+
+ u8 tmp;
+ int pos;
+ u8 linkctrl_reg;
+
+ /*Link Control Register */
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
+ pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Link Control Register =%x\n",
+ pcipriv->ndis_adapter.linkctrl_reg));
+
+ pci_read_config_byte(pdev, 0x98, &tmp);
+ tmp |= BIT(4);
+ pci_write_config_byte(pdev, 0x98, tmp);
+
+ tmp = 0x17;
+ pci_write_config_byte(pdev, 0x70f, tmp);
+}
+
+static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
+{
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ _rtl_pci_update_default_setting(hw);
+
+ if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) {
+ /*Always enable ASPM & Clock Req. */
+ rtl_pci_enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM);
+ }
+
+}
+
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ /*close ASPM for AMD defaultly */
+ rtlpci->const_amdpci_aspm = 0;
+
+ /*
+ * ASPM PS mode.
+ * 0 - Disable ASPM,
+ * 1 - Enable ASPM without Clock Req,
+ * 2 - Enable ASPM with Clock Req,
+ * 3 - Alwyas Enable ASPM with Clock Req,
+ * 4 - Always Enable ASPM without Clock Req.
+ * set defult to RTL8192CE:3 RTL8192E:2
+ * */
+ rtlpci->const_pci_aspm = 3;
+
+ /*Setting for PCI-E device */
+ rtlpci->const_devicepci_aspm_setting = 0x03;
+
+ /*Setting for PCI-E bridge */
+ rtlpci->const_hostpci_aspm_setting = 0x02;
+
+ /*
+ * In Hw/Sw Radio Off situation.
+ * 0 - Default,
+ * 1 - From ASPM setting without low Mac Pwr,
+ * 2 - From ASPM setting with low Mac Pwr,
+ * 3 - Bus D3
+ * set default to RTL8192CE:0 RTL8192SE:2
+ */
+ rtlpci->const_hwsw_rfoff_d3 = 0;
+
+ /*
+ * This setting works for those device with
+ * backdoor ASPM setting such as EPHY setting.
+ * 0 - Not support ASPM,
+ * 1 - Support ASPM,
+ * 2 - According to chipset.
+ */
+ rtlpci->const_support_pciaspm = 1;
+
+ _rtl_pci_initialize_adapter_common(hw);
+}
+
+static void _rtl_pci_io_handler_init(struct device *dev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->io.dev = dev;
+
+ rtlpriv->io.write8_async = pci_write8_async;
+ rtlpriv->io.write16_async = pci_write16_async;
+ rtlpriv->io.write32_async = pci_write32_async;
+
+ rtlpriv->io.read8_sync = pci_read8_sync;
+ rtlpriv->io.read16_sync = pci_read16_sync;
+ rtlpriv->io.read32_sync = pci_read32_sync;
+
+}
+
+static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw)
+{
+}
+
+static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+
+ u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
+ HW_DESC_OWN);
+
+ /*
+ *beacon packet will only use the first
+ *descriptor defautly,and the own may not
+ *be cleared by the hardware
+ */
+ if (own)
+ return;
+ ring->idx = (ring->idx + 1) % ring->entries;
+
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(rtlpci->pdev,
+ le32_to_cpu(rtlpriv->cfg->ops->
+ get_desc((u8 *) entry, true,
+ HW_DESC_TXBUFF_ADDR)),
+ skb->len, PCI_DMA_TODEVICE);
+
+ RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
+ ("new ring->idx:%d, "
+ "free: skb_queue_len:%d, free: seq:%x\n",
+ ring->idx,
+ skb_queue_len(&ring->queue),
+ *(u16 *) (skb->data + 22)));
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ /*info->status.rates[0].count = 1; */
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ if ((ring->entries - skb_queue_len(&ring->queue))
+ == 2) {
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ ("more desc left, wake"
+ "skb_queue@%d,ring->idx = %d,"
+ "skb_queue_len = 0x%d\n",
+ prio, ring->idx,
+ skb_queue_len(&ring->queue)));
+
+ ieee80211_wake_queue(hw,
+ skb_get_queue_mapping
+ (skb));
+ }
+
+ skb = NULL;
+ }
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2)) {
+ rtl_lps_leave(hw);
+ }
+}
+
+static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int rx_queue_idx = RTL_PCI_RX_MPDU_QUEUE;
+
+ struct ieee80211_rx_status rx_status = { 0 };
+ unsigned int count = rtlpci->rxringcount;
+ u8 own;
+ u8 tmp_one;
+ u32 bufferaddress;
+ bool unicast = false;
+
+ struct rtl_stats stats = {
+ .signal = 0,
+ .noise = -98,
+ .rate = 0,
+ };
+
+ /*RX NORMAL PKT */
+ while (count--) {
+ /*rx descriptor */
+ struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
+ rtlpci->rx_ring[rx_queue_idx].idx];
+ /*rx pkt */
+ struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
+ rtlpci->rx_ring[rx_queue_idx].idx];
+
+ own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
+ false, HW_DESC_OWN);
+
+ if (own) {
+ /*wait data to be filled by hardware */
+ return;
+ } else {
+ struct ieee80211_hdr *hdr;
+ u16 fc;
+ struct sk_buff *new_skb = NULL;
+
+ rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
+ &rx_status,
+ (u8 *) pdesc, skb);
+
+ pci_unmap_single(rtlpci->pdev,
+ *((dma_addr_t *) skb->cb),
+ rtlpci->rxbuffersize,
+ PCI_DMA_FROMDEVICE);
+
+ skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
+ false,
+ HW_DESC_RXPKT_LEN));
+ skb_reserve(skb,
+ stats.rx_drvinfo_size + stats.rx_bufshift);
+
+ /*
+ *NOTICE This can not be use for mac80211,
+ *this is done in mac80211 code,
+ *if you done here sec DHCP will fail
+ *skb_trim(skb, skb->len - 4);
+ */
+
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ fc = le16_to_cpu(hdr->frame_control);
+
+ if (!stats.b_crc) {
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
+ sizeof(rx_status));
+
+ if (is_broadcast_ether_addr(hdr->addr1))
+ ;/*TODO*/
+ else {
+ if (is_multicast_ether_addr(hdr->addr1))
+ ;/*TODO*/
+ else {
+ unicast = true;
+ rtlpriv->stats.rxbytesunicast +=
+ skb->len;
+ }
+ }
+
+ rtl_is_special_data(hw, skb, false);
+
+ if (ieee80211_is_data(fc)) {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_RX);
+
+ if (unicast)
+ rtlpriv->link_info.
+ num_rx_inperiod++;
+ }
+
+ if (unlikely(!rtl_action_proc(hw, skb,
+ false))) {
+ dev_kfree_skb_any(skb);
+ } else {
+ struct sk_buff *uskb = NULL;
+ u8 *pdata;
+ uskb = dev_alloc_skb(skb->len + 128);
+ memcpy(IEEE80211_SKB_RXCB(uskb),
+ &rx_status,
+ sizeof(rx_status));
+ pdata = (u8 *)skb_put(uskb, skb->len);
+ memcpy(pdata, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+
+ ieee80211_rx_irqsafe(hw, uskb);
+ }
+ } else {
+ dev_kfree_skb_any(skb);
+ }
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2)) {
+ rtl_lps_leave(hw);
+ }
+
+ new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
+ if (unlikely(!new_skb)) {
+ RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
+ DBG_DMESG,
+ ("can't alloc skb for rx\n"));
+ goto done;
+ }
+ skb = new_skb;
+ /*skb->dev = dev; */
+
+ rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
+ rx_ring
+ [rx_queue_idx].
+ idx] = skb;
+ *((dma_addr_t *) skb->cb) =
+ pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
+ rtlpci->rxbuffersize,
+ PCI_DMA_FROMDEVICE);
+
+ }
+done:
+ bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb));
+ tmp_one = 1;
+ rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
+ HW_DESC_RXBUFF_ADDR,
+ (u8 *)&bufferaddress);
+ rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
+ (u8 *)&tmp_one);
+ rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
+ HW_DESC_RXPKT_LEN,
+ (u8 *)&rtlpci->rxbuffersize);
+
+ if (rtlpci->rx_ring[rx_queue_idx].idx ==
+ rtlpci->rxringcount - 1)
+ rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
+ HW_DESC_RXERO,
+ (u8 *)&tmp_one);
+
+ rtlpci->rx_ring[rx_queue_idx].idx =
+ (rtlpci->rx_ring[rx_queue_idx].idx + 1) %
+ rtlpci->rxringcount;
+ }
+
+}
+
+void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int prio;
+
+ for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) {
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u8 own;
+
+ /*
+ *beacon packet will only use the first
+ *descriptor defautly, and the own may not
+ *be cleared by the hardware, and
+ *beacon will free in prepare beacon
+ */
+ if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE ||
+ prio == HCCA_QUEUE)
+ break;
+
+ own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry,
+ true,
+ HW_DESC_OWN);
+
+ if (own)
+ break;
+
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(rtlpci->pdev,
+ le32_to_cpu(rtlpriv->cfg->ops->
+ get_desc((u8 *) entry,
+ true,
+ HW_DESC_TXBUFF_ADDR)),
+ skb->len, PCI_DMA_TODEVICE);
+
+ ring->idx = (ring->idx + 1) % ring->entries;
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ /*info->status.rates[0].count = 1; */
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ if ((ring->entries - skb_queue_len(&ring->queue))
+ == 2 && prio != BEACON_QUEUE) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("more desc left, wake "
+ "skb_queue@%d,ring->idx = %d,"
+ "skb_queue_len = 0x%d\n",
+ prio, ring->idx,
+ skb_queue_len(&ring->queue)));
+
+ ieee80211_wake_queue(hw,
+ skb_get_queue_mapping
+ (skb));
+ }
+
+ skb = NULL;
+ }
+ }
+}
+
+static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
+{
+ struct ieee80211_hw *hw = dev_id;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ unsigned long flags;
+ u32 inta = 0;
+ u32 intb = 0;
+
+ if (rtlpci->irq_enabled == 0)
+ return IRQ_HANDLED;
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ /*read ISR: 4/8bytes */
+ rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb);
+
+ /*Shared IRQ or HW disappared */
+ if (!inta || inta == 0xffff)
+ goto done;
+
+ /*<1> beacon related */
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("beacon ok interrupt!\n"));
+ }
+
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("beacon err interrupt!\n"));
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("beacon interrupt!\n"));
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("prepare beacon for interrupt!\n"));
+ tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
+ }
+
+ /*<3> Tx related */
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n"));
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("Manage ok interrupt!\n"));
+ _rtl_pci_tx_isr(hw, MGNT_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("HIGH_QUEUE ok interrupt!\n"));
+ _rtl_pci_tx_isr(hw, HIGH_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("BK Tx OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, BK_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("BE TX OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, BE_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("VI TX OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, VI_QUEUE);
+ }
+
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("Vo TX OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, VO_QUEUE);
+ }
+
+ /*<2> Rx related */
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ }
+
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("rx descriptor unavailable!\n"));
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ }
+
+ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ return IRQ_HANDLED;
+
+done:
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ return IRQ_HANDLED;
+}
+
+static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
+{
+ _rtl_pci_rx_interrupt(hw);
+}
+
+static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+ struct ieee80211_hdr *hdr = NULL;
+ struct ieee80211_tx_info *info = NULL;
+ struct sk_buff *pskb = NULL;
+ struct rtl_tx_desc *pdesc = NULL;
+ unsigned int queue_index;
+ u8 temp_one = 1;
+
+ ring = &rtlpci->tx_ring[BEACON_QUEUE];
+ pskb = __skb_dequeue(&ring->queue);
+ if (pskb)
+ kfree_skb(pskb);
+
+ /*NB: the beacon data buffer must be 32-bit aligned. */
+ pskb = ieee80211_beacon_get(hw, mac->vif);
+ if (pskb == NULL)
+ return;
+ hdr = (struct ieee80211_hdr *)(pskb->data);
+ info = IEEE80211_SKB_CB(pskb);
+
+ queue_index = BEACON_QUEUE;
+
+ pdesc = &ring->desc[0];
+ rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
+ info, pskb, queue_index);
+
+ __skb_queue_tail(&ring->queue, pskb);
+
+ rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN,
+ (u8 *)&temp_one);
+
+ return;
+}
+
+static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 i;
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ rtlpci->txringcount[i] = RT_TXDESC_NUM;
+
+ /*
+ *we just alloc 2 desc for beacon queue,
+ *because we just need first desc in hw beacon.
+ */
+ rtlpci->txringcount[BEACON_QUEUE] = 2;
+
+ /*
+ *BE queue need more descriptor for performance
+ *consideration or, No more tx desc will happen,
+ *and may cause mac80211 mem leakage.
+ */
+ rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE;
+
+ rtlpci->rxbuffersize = 9100; /*2048/1024; */
+ rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT; /*64; */
+}
+
+static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
+ struct pci_dev *pdev)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ rtlpci->up_first_time = true;
+ rtlpci->being_init_adapter = false;
+
+ rtlhal->hw = hw;
+ rtlpci->pdev = pdev;
+
+ ppsc->b_inactiveps = false;
+ ppsc->b_leisure_ps = true;
+ ppsc->b_fwctrl_lps = true;
+ ppsc->b_reg_fwctrl_lps = 3;
+ ppsc->reg_max_lps_awakeintvl = 5;
+
+ if (ppsc->b_reg_fwctrl_lps == 1)
+ ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
+ else if (ppsc->b_reg_fwctrl_lps == 2)
+ ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
+ else if (ppsc->b_reg_fwctrl_lps == 3)
+ ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
+
+ /*Tx/Rx related var */
+ _rtl_pci_init_trx_var(hw);
+
+ /*IBSS*/ mac->beacon_interval = 100;
+
+ /*AMPDU*/ mac->min_space_cfg = 0;
+ mac->max_mss_density = 0;
+ /*set sane AMPDU defaults */
+ mac->current_ampdu_density = 7;
+ mac->current_ampdu_factor = 3;
+
+ /*QOS*/ rtlpci->acm_method = eAcmWay2_SW;
+
+ /*task */
+ tasklet_init(&rtlpriv->works.irq_tasklet,
+ (void (*)(unsigned long))_rtl_pci_irq_tasklet,
+ (unsigned long)hw);
+ tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
+ (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
+ (unsigned long)hw);
+}
+
+static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
+ unsigned int prio, unsigned int entries)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_desc *ring;
+ dma_addr_t dma;
+ u32 nextdescaddress;
+ int i;
+
+ ring = pci_alloc_consistent(rtlpci->pdev,
+ sizeof(*ring) * entries, &dma);
+
+ if (!ring || (unsigned long)ring & 0xFF) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Cannot allocate TX ring (prio = %d)\n", prio));
+ return -ENOMEM;
+ }
+
+ memset(ring, 0, sizeof(*ring) * entries);
+ rtlpci->tx_ring[prio].desc = ring;
+ rtlpci->tx_ring[prio].dma = dma;
+ rtlpci->tx_ring[prio].idx = 0;
+ rtlpci->tx_ring[prio].entries = entries;
+ skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("queue:%d, ring_addr:%p\n", prio, ring));
+
+ for (i = 0; i < entries; i++) {
+ nextdescaddress = cpu_to_le32((u32) dma +
+ ((i + 1) % entries) *
+ sizeof(*ring));
+
+ rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
+ true, HW_DESC_TX_NEXTDESC_ADDR,
+ (u8 *)&nextdescaddress);
+ }
+
+ return 0;
+}
+
+static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_rx_desc *entry = NULL;
+ int i, rx_queue_idx;
+ u8 tmp_one = 1;
+
+ /*
+ *rx_queue_idx 0:RX_MPDU_QUEUE
+ *rx_queue_idx 1:RX_CMD_QUEUE
+ */
+ for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
+ rx_queue_idx++) {
+ rtlpci->rx_ring[rx_queue_idx].desc =
+ pci_alloc_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rx_queue_idx].
+ desc) * rtlpci->rxringcount,
+ &rtlpci->rx_ring[rx_queue_idx].dma);
+
+ if (!rtlpci->rx_ring[rx_queue_idx].desc ||
+ (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Cannot allocate RX ring\n"));
+ return -ENOMEM;
+ }
+
+ memset(rtlpci->rx_ring[rx_queue_idx].desc, 0,
+ sizeof(*rtlpci->rx_ring[rx_queue_idx].desc) *
+ rtlpci->rxringcount);
+
+ rtlpci->rx_ring[rx_queue_idx].idx = 0;
+
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ struct sk_buff *skb =
+ dev_alloc_skb(rtlpci->rxbuffersize);
+ u32 bufferaddress;
+ entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
+ if (!skb)
+ return 0;
+
+ /*skb->dev = dev; */
+
+ rtlpci->rx_ring[rx_queue_idx].rx_buf[i] = skb;
+
+ /*
+ *just set skb->cb to mapping addr
+ *for pci_unmap_single use
+ */
+ *((dma_addr_t *) skb->cb) =
+ pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
+ rtlpci->rxbuffersize,
+ PCI_DMA_FROMDEVICE);
+
+ bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
+ rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
+ HW_DESC_RXBUFF_ADDR,
+ (u8 *)&bufferaddress);
+ rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
+ HW_DESC_RXPKT_LEN,
+ (u8 *)&rtlpci->
+ rxbuffersize);
+ rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
+ HW_DESC_RXOWN,
+ (u8 *)&tmp_one);
+ }
+
+ rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
+ HW_DESC_RXERO, (u8 *)&tmp_one);
+ }
+ return 0;
+}
+
+static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
+ unsigned int prio)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+ pci_unmap_single(rtlpci->pdev,
+ le32_to_cpu(rtlpriv->cfg->
+ ops->get_desc((u8 *) entry, true,
+ HW_DESC_TXBUFF_ADDR)),
+ skb->len, PCI_DMA_TODEVICE);
+ kfree_skb(skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*ring->desc) * ring->entries,
+ ring->desc, ring->dma);
+ ring->desc = NULL;
+}
+
+static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
+{
+ int i, rx_queue_idx;
+
+ /*rx_queue_idx 0:RX_MPDU_QUEUE */
+ /*rx_queue_idx 1:RX_CMD_QUEUE */
+ for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
+ rx_queue_idx++) {
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ struct sk_buff *skb =
+ rtlpci->rx_ring[rx_queue_idx].rx_buf[i];
+ if (!skb)
+ continue;
+
+ pci_unmap_single(rtlpci->pdev,
+ *((dma_addr_t *) skb->cb),
+ rtlpci->rxbuffersize,
+ PCI_DMA_FROMDEVICE);
+ kfree_skb(skb);
+ }
+
+ pci_free_consistent(rtlpci->pdev,
+ sizeof(*rtlpci->rx_ring[rx_queue_idx].
+ desc) * rtlpci->rxringcount,
+ rtlpci->rx_ring[rx_queue_idx].desc,
+ rtlpci->rx_ring[rx_queue_idx].dma);
+ rtlpci->rx_ring[rx_queue_idx].desc = NULL;
+ }
+}
+
+static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int ret;
+ int i;
+
+ ret = _rtl_pci_init_rx_ring(hw);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+ ret = _rtl_pci_init_tx_ring(hw, i,
+ rtlpci->txringcount[i]);
+ if (ret)
+ goto err_free_rings;
+ }
+
+ return 0;
+
+err_free_rings:
+ _rtl_pci_free_rx_ring(rtlpci);
+
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ if (rtlpci->tx_ring[i].desc)
+ _rtl_pci_free_tx_ring(hw, i);
+
+ return 1;
+}
+
+static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u32 i;
+
+ /*free rx rings */
+ _rtl_pci_free_rx_ring(rtlpci);
+
+ /*free tx rings */
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+ _rtl_pci_free_tx_ring(hw, i);
+
+ return 0;
+}
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ int i, rx_queue_idx;
+ unsigned long flags;
+ u8 tmp_one = 1;
+
+ /*rx_queue_idx 0:RX_MPDU_QUEUE */
+ /*rx_queue_idx 1:RX_CMD_QUEUE */
+ for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
+ rx_queue_idx++) {
+ /*
+ *force the rx_ring[RX_MPDU_QUEUE/
+ *RX_CMD_QUEUE].idx to the first one
+ */
+ if (rtlpci->rx_ring[rx_queue_idx].desc) {
+ struct rtl_rx_desc *entry = NULL;
+
+ for (i = 0; i < rtlpci->rxringcount; i++) {
+ entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
+ rtlpriv->cfg->ops->set_desc((u8 *) entry,
+ false,
+ HW_DESC_RXOWN,
+ (u8 *)&tmp_one);
+ }
+ rtlpci->rx_ring[rx_queue_idx].idx = 0;
+ }
+ }
+
+ /*
+ *after reset, release previous pending packet,
+ *and force the tx idx to the first one
+ */
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+ if (rtlpci->tx_ring[i].desc) {
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry =
+ &ring->desc[ring->idx];
+ struct sk_buff *skb =
+ __skb_dequeue(&ring->queue);
+
+ pci_unmap_single(rtlpci->pdev,
+ le32_to_cpu(rtlpriv->cfg->ops->
+ get_desc((u8 *)
+ entry,
+ true,
+ HW_DESC_TXBUFF_ADDR)),
+ skb->len, PCI_DMA_TODEVICE);
+ kfree_skb(skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+ ring->idx = 0;
+ }
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ return 0;
+}
+
+unsigned int _rtl_mac_to_hwqueue(u16 fc,
+ unsigned int mac80211_queue_index)
+{
+ unsigned int hw_queue_index;
+
+ if (unlikely(ieee80211_is_beacon(fc))) {
+ hw_queue_index = BEACON_QUEUE;
+ goto out;
+ }
+
+ if (ieee80211_is_mgmt(fc)) {
+ hw_queue_index = MGNT_QUEUE;
+ goto out;
+ }
+
+ switch (mac80211_queue_index) {
+ case 0:
+ hw_queue_index = VO_QUEUE;
+ break;
+ case 1:
+ hw_queue_index = VI_QUEUE;
+ break;
+ case 2:
+ hw_queue_index = BE_QUEUE;;
+ break;
+ case 3:
+ hw_queue_index = BK_QUEUE;
+ break;
+ default:
+ hw_queue_index = BE_QUEUE;
+ RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
+ mac80211_queue_index));
+ break;
+ }
+
+out:
+ return hw_queue_index;
+}
+
+int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ u8 idx;
+ unsigned int queue_index, hw_queue;
+ unsigned long flags;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ u8 *pda_addr = hdr->addr1;
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ /*ssn */
+ u8 *qc = NULL;
+ u8 tid = 0;
+ u16 seq_number = 0;
+ u8 own;
+ u8 temp_one = 1;
+
+ if (ieee80211_is_mgmt(fc))
+ rtl_tx_mgmt_proc(hw, skb);
+ rtl_action_proc(hw, skb, true);
+
+ queue_index = skb_get_queue_mapping(skb);
+ hw_queue = _rtl_mac_to_hwqueue(fc, queue_index);
+
+ if (is_multicast_ether_addr(pda_addr))
+ rtlpriv->stats.txbytesmulticast += skb->len;
+ else if (is_broadcast_ether_addr(pda_addr))
+ rtlpriv->stats.txbytesbroadcast += skb->len;
+ else
+ rtlpriv->stats.txbytesunicast += skb->len;
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ ring = &rtlpci->tx_ring[hw_queue];
+ if (hw_queue != BEACON_QUEUE)
+ idx = (ring->idx + skb_queue_len(&ring->queue)) %
+ ring->entries;
+ else
+ idx = 0;
+
+ pdesc = &ring->desc[idx];
+ own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
+ true, HW_DESC_OWN);
+
+ if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("No more TX desc@%d, ring->idx = %d,"
+ "idx = %d, skb_queue_len = 0x%d\n",
+ hw_queue, ring->idx, idx,
+ skb_queue_len(&ring->queue)));
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ return skb->len;
+ }
+
+ /*
+ *if(ieee80211_is_nullfunc(fc)) {
+ * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+ * return 1;
+ *}
+ */
+
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+
+ seq_number = mac->tids[tid].seq_number;
+ seq_number &= IEEE80211_SCTL_SEQ;
+ /*
+ *hdr->seq_ctrl = hdr->seq_ctrl &
+ *cpu_to_le16(IEEE80211_SCTL_FRAG);
+ *hdr->seq_ctrl |= cpu_to_le16(seq_number);
+ */
+
+ seq_number += 1;
+ }
+
+ if (ieee80211_is_data(fc))
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
+
+ rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
+ info, skb, hw_queue);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true,
+ HW_DESC_OWN, (u8 *)&temp_one);
+
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ if (qc)
+ mac->tids[tid].seq_number = seq_number;
+ }
+
+ if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
+ hw_queue != BEACON_QUEUE) {
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ ("less desc left, stop skb_queue@%d, "
+ "ring->idx = %d,"
+ "idx = %d, skb_queue_len = 0x%d\n",
+ hw_queue, ring->idx, idx,
+ skb_queue_len(&ring->queue)));
+
+ ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
+
+ return 0;
+}
+
+void rtl_pci_deinit(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ _rtl_pci_deinit_trx_ring(hw);
+
+ synchronize_irq(rtlpci->pdev->irq);
+ tasklet_kill(&rtlpriv->works.irq_tasklet);
+
+ flush_workqueue(rtlpriv->works.rtl_wq);
+ destroy_workqueue(rtlpriv->works.rtl_wq);
+
+}
+
+int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int err;
+
+ _rtl_pci_init_struct(hw, pdev);
+
+ err = _rtl_pci_init_trx_ring(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("tx ring initialization failed"));
+ return err;
+ }
+
+ return 1;
+}
+
+int rtl_pci_start(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ int err;
+
+ rtl_pci_reset_trx_ring(hw);
+
+ rtlpci->driver_is_goingto_unload = false;
+ err = rtlpriv->cfg->ops->hw_init(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("Failed to config hardware!\n"));
+ return err;
+ }
+
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n"));
+
+ rtl_init_rx_config(hw);
+
+ /*should after adapter start and interrupt enable. */
+ set_hal_start(rtlhal);
+
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+ rtlpci->up_first_time = false;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+ return 0;
+}
+
+void rtl_pci_stop(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ unsigned long flags;
+ u8 RFInProgressTimeOut = 0;
+
+ /*
+ *should before disable interrrupt&adapter
+ *and will do it immediately.
+ */
+ set_hal_stop(rtlhal);
+
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ while (ppsc->rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+ if (RFInProgressTimeOut > 100) {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ break;
+ }
+ mdelay(1);
+ RFInProgressTimeOut++;
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ }
+ ppsc->rfchange_inprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+
+ rtlpci->driver_is_goingto_unload = true;
+ rtlpriv->cfg->ops->hw_disable(hw);
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
+
+ rtl_pci_enable_aspm(hw);
+}
+
+static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct pci_dev *bridge_pdev = pdev->bus->self;
+ u16 venderid;
+ u16 deviceid;
+ u8 revisionid;
+ u16 irqline;
+ u8 tmp;
+
+ venderid = pdev->vendor;
+ deviceid = pdev->device;
+ pci_read_config_byte(pdev, 0x8, &revisionid);
+ pci_read_config_word(pdev, 0x3C, &irqline);
+
+ if (deviceid == RTL_PCI_8192_DID ||
+ deviceid == RTL_PCI_0044_DID ||
+ deviceid == RTL_PCI_0047_DID ||
+ deviceid == RTL_PCI_8192SE_DID ||
+ deviceid == RTL_PCI_8174_DID ||
+ deviceid == RTL_PCI_8173_DID ||
+ deviceid == RTL_PCI_8172_DID ||
+ deviceid == RTL_PCI_8171_DID) {
+ switch (revisionid) {
+ case RTL_PCI_REVISION_ID_8192PCIE:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("8192 PCI-E is found - "
+ "vid/did=%x/%x\n", venderid, deviceid));
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
+ break;
+ case RTL_PCI_REVISION_ID_8192SE:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("8192SE is found - "
+ "vid/did=%x/%x\n", venderid, deviceid));
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Err: Unknown device - "
+ "vid/did=%x/%x\n", venderid, deviceid));
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+ break;
+
+ }
+ } else if (deviceid == RTL_PCI_8192CET_DID ||
+ deviceid == RTL_PCI_8192CE_DID ||
+ deviceid == RTL_PCI_8191CE_DID ||
+ deviceid == RTL_PCI_8188CE_DID) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("8192C PCI-E is found - "
+ "vid/did=%x/%x\n", venderid, deviceid));
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Err: Unknown device -"
+ " vid/did=%x/%x\n", venderid, deviceid));
+
+ rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
+ }
+
+ /*find bus info */
+ pcipriv->ndis_adapter.busnumber = pdev->bus->number;
+ pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
+ pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
+
+ /*find bridge info */
+ pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
+ for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
+ if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
+ pcipriv->ndis_adapter.pcibridge_vendor = tmp;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("Pci Bridge Vendor is found index: %d\n",
+ tmp));
+ break;
+ }
+ }
+
+ if (pcipriv->ndis_adapter.pcibridge_vendor !=
+ PCI_BRIDGE_VENDOR_UNKNOWN) {
+ pcipriv->ndis_adapter.pcibridge_busnum =
+ bridge_pdev->bus->number;
+ pcipriv->ndis_adapter.pcibridge_devnum =
+ PCI_SLOT(bridge_pdev->devfn);
+ pcipriv->ndis_adapter.pcibridge_funcnum =
+ PCI_FUNC(bridge_pdev->devfn);
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+ pci_pcie_cap(bridge_pdev);
+ pcipriv->ndis_adapter.pcicfg_addrport =
+ (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
+ (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
+ (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
+ pcipriv->ndis_adapter.num4bytes =
+ (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
+
+ rtl_pci_get_linkcontrol_field(hw);
+
+ if (pcipriv->ndis_adapter.pcibridge_vendor ==
+ PCI_BRIDGE_VENDOR_AMD) {
+ pcipriv->ndis_adapter.amd_l1_patch =
+ rtl_pci_get_amd_l1_patch(hw);
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("pcidev busnumber:devnumber:funcnumber:"
+ "vendor:link_ctl %d:%d:%d:%x:%x\n",
+ pcipriv->ndis_adapter.busnumber,
+ pcipriv->ndis_adapter.devnumber,
+ pcipriv->ndis_adapter.funcnumber,
+ pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
+ "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+ pcipriv->ndis_adapter.pcibridge_busnum,
+ pcipriv->ndis_adapter.pcibridge_devnum,
+ pcipriv->ndis_adapter.pcibridge_funcnum,
+ pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+ pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+ pcipriv->ndis_adapter.amd_l1_patch));
+
+ rtl_pci_parse_configuration(pdev, hw);
+
+ return true;
+}
+
+int __devinit rtl_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct ieee80211_hw *hw = NULL;
+
+ struct rtl_priv *rtlpriv = NULL;
+ struct rtl_pci_priv *pcipriv = NULL;
+ struct rtl_pci *rtlpci;
+ unsigned long pmem_start, pmem_len, pmem_flags;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ RT_ASSERT(false,
+ ("%s : Cannot enable new PCI device\n",
+ pci_name(pdev)));
+ return err;
+ }
+
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ RT_ASSERT(false, ("Unable to obtain 32bit DMA "
+ "for consistent allocations\n"));
+ pci_disable_device(pdev);
+ return -ENOMEM;
+ }
+ }
+
+ pci_set_master(pdev);
+
+ hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) +
+ sizeof(struct rtl_priv), &rtl_ops);
+ if (!hw) {
+ RT_ASSERT(false,
+ ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ rtlpriv = hw->priv;
+ pcipriv = (void *)rtlpriv->priv;
+ pcipriv->dev.pdev = pdev;
+
+ /*
+ *init dbgp flags before all
+ *other functions, because we will
+ *use it in other funtions like
+ *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
+ *you can not use these macro
+ *before this
+ */
+ rtl_dbgp_flag_init(hw);
+
+ /* MEM map */
+ err = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (err) {
+ RT_ASSERT(false, ("Can't obtain PCI resources\n"));
+ return err;
+ }
+
+ pmem_start = pci_resource_start(pdev, 2);
+ pmem_len = pci_resource_len(pdev, 2);
+ pmem_flags = pci_resource_flags(pdev, 2);
+
+ /*shared mem start */
+ rtlpriv->io.pci_mem_start =
+ (unsigned long)pci_iomap(pdev, 2, pmem_len);
+ if (rtlpriv->io.pci_mem_start == 0) {
+ RT_ASSERT(false, ("Can't map PCI mem\n"));
+ goto fail2;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("mem mapped space: start: 0x%08lx len:%08lx "
+ "flags:%08lx, after map:0x%08lx\n",
+ pmem_start, pmem_len, pmem_flags,
+ rtlpriv->io.pci_mem_start));
+
+ /* Disable Clk Request */
+ pci_write_config_byte(pdev, 0x81, 0);
+ /* leave D3 mode */
+ pci_write_config_byte(pdev, 0x44, 0);
+ pci_write_config_byte(pdev, 0x04, 0x06);
+ pci_write_config_byte(pdev, 0x04, 0x07);
+
+ /* init cfg & intf_ops */
+ rtlpriv->rtlhal.interface = INTF_PCI;
+ rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+ rtlpriv->intf_ops = &rtl_pci_ops;
+
+ /* find adapter */
+ _rtl_pci_find_adapter(pdev, hw);
+
+ /* Init IO handler */
+ _rtl_pci_io_handler_init(&pdev->dev, hw);
+
+ /*like read eeprom and so on */
+ rtlpriv->cfg->ops->read_eeprom_info(hw);
+
+ if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't init_sw_vars.\n"));
+ goto fail3;
+ }
+
+ rtlpriv->cfg->ops->init_sw_leds(hw);
+
+ /*aspm */
+ rtl_pci_init_aspm(hw);
+
+ /* Init mac80211 sw */
+ err = rtl_init_core(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't allocate sw for mac80211.\n"));
+ goto fail3;
+ }
+
+ /* Init PCI sw */
+ err = !rtl_pci_init(hw, pdev);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to init PCI.\n"));
+ goto fail3;
+ }
+
+ err = ieee80211_register_hw(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't register mac80211 hw.\n"));
+ goto fail3;
+ } else {
+ rtlpriv->mac80211.mac80211_registered = 1;
+ }
+
+ err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("failed to create sysfs device attributes\n"));
+ goto fail3;
+ }
+
+ /*init rfkill */
+ rtl_init_rfkill(hw);
+
+ rtlpci = rtl_pcidev(pcipriv);
+ err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
+ IRQF_SHARED, KBUILD_MODNAME, hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("%s: failed to register IRQ handler\n",
+ wiphy_name(hw->wiphy)));
+ goto fail3;
+ } else {
+ rtlpci->irq_alloc = 1;
+ }
+
+ set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+ return 0;
+
+fail3:
+ pci_set_drvdata(pdev, NULL);
+ rtl_deinit_core(hw);
+ _rtl_pci_io_handler_release(hw);
+ ieee80211_free_hw(hw);
+
+ if (rtlpriv->io.pci_mem_start != 0)
+ pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+
+fail2:
+ pci_release_regions(pdev);
+
+fail1:
+
+ pci_disable_device(pdev);
+
+ return -ENODEV;
+
+}
+EXPORT_SYMBOL(rtl_pci_probe);
+
+void rtl_pci_disconnect(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+ struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+
+ clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+ sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
+
+ /*ieee80211_unregister_hw will call ops_stop */
+ if (rtlmac->mac80211_registered == 1) {
+ ieee80211_unregister_hw(hw);
+ rtlmac->mac80211_registered = 0;
+ } else {
+ rtl_deinit_deferred_work(hw);
+ rtlpriv->intf_ops->adapter_stop(hw);
+ }
+
+ /*deinit rfkill */
+ rtl_deinit_rfkill(hw);
+
+ rtl_pci_deinit(hw);
+ rtl_deinit_core(hw);
+ rtlpriv->cfg->ops->deinit_sw_leds(hw);
+ _rtl_pci_io_handler_release(hw);
+ rtlpriv->cfg->ops->deinit_sw_vars(hw);
+
+ if (rtlpci->irq_alloc) {
+ free_irq(rtlpci->pdev->irq, hw);
+ rtlpci->irq_alloc = 0;
+ }
+
+ if (rtlpriv->io.pci_mem_start != 0) {
+ pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+ pci_release_regions(pdev);
+ }
+
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+ ieee80211_free_hw(hw);
+}
+EXPORT_SYMBOL(rtl_pci_disconnect);
+
+/***************************************
+kernel pci power state define:
+PCI_D0 ((pci_power_t __force) 0)
+PCI_D1 ((pci_power_t __force) 1)
+PCI_D2 ((pci_power_t __force) 2)
+PCI_D3hot ((pci_power_t __force) 3)
+PCI_D3cold ((pci_power_t __force) 4)
+PCI_UNKNOWN ((pci_power_t __force) 5)
+
+This function is called when system
+goes into suspend state mac80211 will
+call rtl_mac_stop() from the mac80211
+suspend function first, So there is
+no need to call hw_disable here.
+****************************************/
+int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+EXPORT_SYMBOL(rtl_pci_suspend);
+
+int rtl_pci_resume(struct pci_dev *pdev)
+{
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ RT_ASSERT(false, ("ERR: <======\n"));
+ return ret;
+ }
+
+ pci_restore_state(pdev);
+
+ return 0;
+}
+EXPORT_SYMBOL(rtl_pci_resume);
+
+struct rtl_intf_ops rtl_pci_ops = {
+ .adapter_start = rtl_pci_start,
+ .adapter_stop = rtl_pci_stop,
+ .adapter_tx = rtl_pci_tx,
+ .reset_trx_ring = rtl_pci_reset_trx_ring,
+
+ .disable_aspm = rtl_pci_disable_aspm,
+ .enable_aspm = rtl_pci_enable_aspm,
+};
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
new file mode 100644
index 000000000000..d36a66939958
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -0,0 +1,302 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_PCI_H__
+#define __RTL_PCI_H__
+
+#include <linux/pci.h>
+/*
+1: MSDU packet queue,
+2: Rx Command Queue
+*/
+#define RTL_PCI_RX_MPDU_QUEUE 0
+#define RTL_PCI_RX_CMD_QUEUE 1
+#define RTL_PCI_MAX_RX_QUEUE 2
+
+#define RTL_PCI_MAX_RX_COUNT 64
+#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
+
+#define RT_TXDESC_NUM 128
+#define RT_TXDESC_NUM_BE_QUEUE 256
+
+#define BK_QUEUE 0
+#define BE_QUEUE 1
+#define VI_QUEUE 2
+#define VO_QUEUE 3
+#define BEACON_QUEUE 4
+#define TXCMD_QUEUE 5
+#define MGNT_QUEUE 6
+#define HIGH_QUEUE 7
+#define HCCA_QUEUE 8
+
+#define RTL_PCI_DEVICE(vend, dev, cfg) \
+ .vendor = (vend), \
+ .device = (dev), \
+ .subvendor = PCI_ANY_ID, \
+ .subdevice = PCI_ANY_ID,\
+ .driver_data = (kernel_ulong_t)&(cfg)
+
+#define INTEL_VENDOR_ID 0x8086
+#define SIS_VENDOR_ID 0x1039
+#define ATI_VENDOR_ID 0x1002
+#define ATI_DEVICE_ID 0x7914
+#define AMD_VENDOR_ID 0x1022
+
+#define PCI_MAX_BRIDGE_NUMBER 255
+#define PCI_MAX_DEVICES 32
+#define PCI_MAX_FUNCTION 8
+
+#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
+#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
+
+#define PCI_CLASS_BRIDGE_DEV 0x06
+#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
+#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
+#define PCI_CAP_ID_EXP 0x10
+
+#define U1DONTCARE 0xFF
+#define U2DONTCARE 0xFFFF
+#define U4DONTCARE 0xFFFFFFFF
+
+#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
+#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
+#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
+#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
+#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
+#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
+#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
+#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
+#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
+#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
+#define RTL_PCI_700F_DID 0x700F
+#define RTL_PCI_701F_DID 0x701F
+#define RTL_PCI_DLINK_DID 0x3304
+#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
+#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
+#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
+#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
+#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
+#define RTL_PCI_8192DE_DID 0x092D /*8192ce */
+#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
+
+/*8192 support 16 pages of IO registers*/
+#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
+#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
+
+#define RTL_PCI_REVISION_ID_8190PCI 0x00
+#define RTL_PCI_REVISION_ID_8192PCIE 0x01
+#define RTL_PCI_REVISION_ID_8192SE 0x10
+#define RTL_PCI_REVISION_ID_8192CE 0x1
+#define RTL_PCI_REVISION_ID_8192DE 0x0
+
+#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
+
+enum pci_bridge_vendor {
+ PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
+ PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
+ PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
+ PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
+ PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
+ PCI_BRIDGE_VENDOR_MAX,
+};
+
+struct rtl_rx_desc {
+ u32 dword[8];
+} __packed;
+
+struct rtl_tx_desc {
+ u32 dword[16];
+} __packed;
+
+struct rtl_tx_cmd_desc {
+ u32 dword[16];
+} __packed;
+
+struct rtl8192_tx_ring {
+ struct rtl_tx_desc *desc;
+ dma_addr_t dma;
+ unsigned int idx;
+ unsigned int entries;
+ struct sk_buff_head queue;
+};
+
+struct rtl8192_rx_ring {
+ struct rtl_rx_desc *desc;
+ dma_addr_t dma;
+ unsigned int idx;
+ struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
+};
+
+struct rtl_pci {
+ struct pci_dev *pdev;
+
+ bool driver_is_goingto_unload;
+ bool up_first_time;
+ bool being_init_adapter;
+ bool irq_enabled;
+
+ /*Tx */
+ struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
+ int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
+ u32 transmit_config;
+
+ /*Rx */
+ struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
+ int rxringcount;
+ u16 rxbuffersize;
+ u32 receive_config;
+
+ /*irq */
+ u8 irq_alloc;
+ u32 irq_mask[2];
+
+ /*Bcn control register setting */
+ u32 reg_bcn_ctrl_val;
+
+ /*ASPM*/ u8 const_pci_aspm;
+ u8 const_amdpci_aspm;
+ u8 const_hwsw_rfoff_d3;
+ u8 const_support_pciaspm;
+ /*pci-e bridge */
+ u8 const_hostpci_aspm_setting;
+ /*pci-e device */
+ u8 const_devicepci_aspm_setting;
+ /*If it supports ASPM, Offset[560h] = 0x40,
+ otherwise Offset[560h] = 0x00. */
+ bool b_support_aspm;
+ bool b_support_backdoor;
+
+ /*QOS & EDCA */
+ enum acm_method acm_method;
+};
+
+struct mp_adapter {
+ u8 linkctrl_reg;
+
+ u8 busnumber;
+ u8 devnumber;
+ u8 funcnumber;
+
+ u8 pcibridge_busnum;
+ u8 pcibridge_devnum;
+ u8 pcibridge_funcnum;
+
+ u8 pcibridge_vendor;
+ u16 pcibridge_vendorid;
+ u16 pcibridge_deviceid;
+
+ u32 pcicfg_addrport;
+ u8 num4bytes;
+
+ u8 pcibridge_pciehdr_offset;
+ u8 pcibridge_linkctrlreg;
+
+ bool amd_l1_patch;
+};
+
+struct rtl_pci_priv {
+ struct rtl_pci dev;
+ struct mp_adapter ndis_adapter;
+ struct rtl_led_ctl ledctl;
+};
+
+#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
+#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
+
+extern struct rtl_intf_ops rtl_pci_ops;
+
+int __devinit rtl_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id);
+void rtl_pci_disconnect(struct pci_dev *pdev);
+int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
+int rtl_pci_resume(struct pci_dev *pdev);
+
+static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
+{
+ writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write16_async(struct rtl_priv *rtlpriv,
+ u32 addr, u16 val)
+{
+ writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write32_async(struct rtl_priv *rtlpriv,
+ u32 addr, u32 val)
+{
+ writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
+{
+ outl(val, port);
+}
+
+static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
+{
+ outb(val, port);
+}
+
+static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
+{
+ *pval = inb(port);
+}
+
+static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
+{
+ *pval = inw(port);
+}
+
+static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
+{
+ *pval = inl(port);
+}
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
new file mode 100644
index 000000000000..d2326c13449e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -0,0 +1,493 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "base.h"
+#include "ps.h"
+
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool init_status = true;
+
+ /*<1> reset trx ring */
+ if (rtlhal->interface == INTF_PCI)
+ rtlpriv->intf_ops->reset_trx_ring(hw);
+
+ if (is_hal_stop(rtlhal))
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Driver is already down!\n"));
+
+ /*<2> Enable Adapter */
+ rtlpriv->cfg->ops->hw_init(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ /*init_status = false; */
+
+ /*<3> Enable Interrupt */
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+
+ /*<enable timer> */
+ rtl_watch_dog_timer_callback((unsigned long)hw);
+
+ return init_status;
+}
+EXPORT_SYMBOL(rtl_ps_enable_nic);
+
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
+{
+ bool status = true;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /*<1> Stop all timer */
+ rtl_deinit_deferred_work(hw);
+
+ /*<2> Disable Interrupt */
+ rtlpriv->cfg->ops->disable_interrupt(hw);
+
+ /*<3> Disable Adapter */
+ rtlpriv->cfg->ops->hw_disable(hw);
+
+ return status;
+}
+EXPORT_SYMBOL(rtl_ps_disable_nic);
+
+bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate state_toset,
+ u32 changesource, bool protect_or_not)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+ bool b_actionallowed = false;
+ u16 rfwait_cnt = 0;
+ unsigned long flag;
+
+ /*protect_or_not = true; */
+
+ if (protect_or_not)
+ goto no_protect;
+
+ /*
+ *Only one thread can change
+ *the RF state at one time, and others
+ *should wait to be executed.
+ */
+ while (true) {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ if (ppsc->rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
+ flag);
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("RF Change in progress!"
+ "Wait to set..state_toset(%d).\n",
+ state_toset));
+
+ /* Set RF after the previous action is done. */
+ while (ppsc->rfchange_inprogress) {
+ rfwait_cnt++;
+ mdelay(1);
+
+ /*
+ *Wait too long, return false to avoid
+ *to be stuck here.
+ */
+ if (rfwait_cnt > 100)
+ return false;
+ }
+ } else {
+ ppsc->rfchange_inprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
+ flag);
+ break;
+ }
+ }
+
+no_protect:
+ rtstate = ppsc->rfpwr_state;
+
+ switch (state_toset) {
+ case ERFON:
+ ppsc->rfoff_reason &= (~changesource);
+
+ if ((changesource == RF_CHANGE_BY_HW) &&
+ (ppsc->b_hwradiooff == true)) {
+ ppsc->b_hwradiooff = false;
+ }
+
+ if (!ppsc->rfoff_reason) {
+ ppsc->rfoff_reason = 0;
+ b_actionallowed = true;
+ }
+
+ break;
+
+ case ERFOFF:
+
+ if ((changesource == RF_CHANGE_BY_HW)
+ && (ppsc->b_hwradiooff == false)) {
+ ppsc->b_hwradiooff = true;
+ }
+
+ ppsc->rfoff_reason |= changesource;
+ b_actionallowed = true;
+ break;
+
+ case ERFSLEEP:
+ ppsc->rfoff_reason |= changesource;
+ b_actionallowed = true;
+ break;
+
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+ if (b_actionallowed)
+ rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
+
+ if (!protect_or_not) {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ }
+
+ return b_actionallowed;
+}
+EXPORT_SYMBOL(rtl_ps_set_rf_state);
+
+static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ ppsc->b_swrf_processing = true;
+
+ if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
+ if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) &&
+ rtlhal->interface == INTF_PCI) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+ }
+
+ rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
+ RF_CHANGE_BY_IPS, false);
+
+ if (ppsc->inactive_pwrstate == ERFOFF &&
+ rtlhal->interface == INTF_PCI) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+ }
+
+ ppsc->b_swrf_processing = false;
+}
+
+void rtl_ips_nic_off_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+
+ if (mac->opmode != NL80211_IFTYPE_STATION) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("not station return\n"));
+ return;
+ }
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ if (rtlpriv->sec.being_setkey)
+ return;
+
+ if (ppsc->b_inactiveps) {
+ rtstate = ppsc->rfpwr_state;
+
+ /*
+ *Do not enter IPS in the following conditions:
+ *(1) RF is already OFF or Sleep
+ *(2) b_swrf_processing (indicates the IPS is still under going)
+ *(3) Connectted (only disconnected can trigger IPS)
+ *(4) IBSS (send Beacon)
+ *(5) AP mode (send Beacon)
+ *(6) monitor mode (rcv packet)
+ */
+
+ if (rtstate == ERFON &&
+ !ppsc->b_swrf_processing &&
+ (mac->link_state == MAC80211_NOLINK) &&
+ !mac->act_scanning) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ ("IPSEnter(): Turn off RF.\n"));
+
+ ppsc->inactive_pwrstate = ERFOFF;
+ ppsc->b_in_powersavemode = true;
+
+ /*rtl_pci_reset_trx_ring(hw); */
+ _rtl_ps_inactive_ps(hw);
+ }
+ }
+}
+
+void rtl_ips_nic_off(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /*
+ *because when link with ap, mac80211 will ask us
+ *to disable nic quickly after scan before linking,
+ *this will cause link failed, so we delay 100ms here
+ */
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ips_nic_off_wq, MSECS(100));
+}
+
+void rtl_ips_nic_on(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ enum rf_pwrstate rtstate;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
+
+ if (ppsc->b_inactiveps) {
+ rtstate = ppsc->rfpwr_state;
+
+ if (rtstate != ERFON &&
+ !ppsc->b_swrf_processing &&
+ ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
+
+ ppsc->inactive_pwrstate = ERFON;
+ ppsc->b_in_powersavemode = false;
+
+ _rtl_ps_inactive_ps(hw);
+ }
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
+}
+
+/*for FW LPS*/
+
+/*
+ *Determine if we can set Fw into PS mode
+ *in current condition.Return TRUE if it
+ *can enter PS mode.
+ */
+static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u32 ps_timediff;
+
+ ps_timediff = jiffies_to_msecs(jiffies -
+ ppsc->last_delaylps_stamp_jiffies);
+
+ if (ps_timediff < 2000) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Delay enter Fw LPS for DHCP, ARP,"
+ " or EAPOL exchanging state.\n"));
+ return false;
+ }
+
+ if (mac->link_state != MAC80211_LINKED)
+ return false;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return false;
+
+ return true;
+}
+
+/* Change current and default preamble mode.*/
+static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u8 rpwm_val, fw_pwrmode;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return;
+
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ if (ppsc->dot11_psmode == rt_psmode)
+ return;
+
+ /* Update power save mode configured. */
+ ppsc->dot11_psmode = rt_psmode;
+
+ /*
+ *<FW control LPS>
+ *1. Enter PS mode
+ * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
+ * cmd to set Fw into PS mode.
+ *2. Leave PS mode
+ * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
+ * mode and set RPWM to turn RF on.
+ */
+
+ if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
+ ppsc->report_linked) {
+ bool b_fw_current_inps;
+ if (ppsc->dot11_psmode == EACTIVE) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("FW LPS leave ps_mode:%x\n",
+ FW_PS_ACTIVE_MODE));
+
+ rpwm_val = 0x0C; /* RF on */
+ fw_pwrmode = FW_PS_ACTIVE_MODE;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+ (u8 *) (&rpwm_val));
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_PWRMODE,
+ (u8 *) (&fw_pwrmode));
+ b_fw_current_inps = false;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_FW_PSMODE_STATUS,
+ (u8 *) (&b_fw_current_inps));
+
+ } else {
+ if (rtl_get_fwlps_doze(hw)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("FW LPS enter ps_mode:%x\n",
+ ppsc->fwctrl_psmode));
+
+ rpwm_val = 0x02; /* RF off */
+ b_fw_current_inps = true;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_FW_PSMODE_STATUS,
+ (u8 *) (&b_fw_current_inps));
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_H2C_FW_PWRMODE,
+ (u8 *) (&ppsc->fwctrl_psmode));
+
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_SET_RPWM,
+ (u8 *) (&rpwm_val));
+ } else {
+ /* Reset the power save related parameters. */
+ ppsc->dot11_psmode = EACTIVE;
+ }
+ }
+ }
+}
+
+/*Enter the leisure power save mode.*/
+void rtl_lps_enter(struct ieee80211_hw *hw)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long flag;
+
+ if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
+ return;
+
+ if (rtlpriv->sec.being_setkey)
+ return;
+
+ if (rtlpriv->link_info.b_busytraffic)
+ return;
+
+ /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+ if (mac->cnt_after_linked < 5)
+ return;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ return;
+
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+
+ if (ppsc->b_leisure_ps) {
+ /* Idle for a while if we connect to AP a while ago. */
+ if (mac->cnt_after_linked >= 2) {
+ if (ppsc->dot11_psmode == EACTIVE) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Enter 802.11 power save mode...\n"));
+
+ rtl_lps_set_psmode(hw, EAUTOPS);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+/*Leave the leisure power save mode.*/
+void rtl_lps_leave(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ unsigned long flag;
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+
+ if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
+ if (ppsc->dot11_psmode != EACTIVE) {
+
+ /*FIX ME */
+ rtlpriv->cfg->ops->enable_interrupt(hw);
+
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
+ rtlhal->interface == INTF_PCI) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
+ }
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Busy Traffic,Leave 802.11 power save..\n"));
+
+ rtl_lps_set_psmode(hw, EACTIVE);
+ }
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
new file mode 100644
index 000000000000..ae56da801a23
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __REALTEK_RTL_PCI_PS_H__
+#define __REALTEK_RTL_PCI_PS_H__
+
+bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate state_toset, u32 changesource,
+ bool protect_or_not);
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
+void rtl_ips_nic_off(struct ieee80211_hw *hw);
+void rtl_ips_nic_on(struct ieee80211_hw *hw);
+void rtl_ips_nic_off_wq_callback(void *data);
+void rtl_lps_enter(struct ieee80211_hw *hw);
+void rtl_lps_leave(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
new file mode 100644
index 000000000000..91634107434a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -0,0 +1,329 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "base.h"
+#include "rc.h"
+
+/*
+ *Finds the highest rate index we can use
+ *if skb is special data like DHCP/EAPOL, we set should
+ *it to lowest rate CCK_1M, otherwise we set rate to
+ *CCK11M or OFDM_54M based on wireless mode.
+ */
+static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
+ struct sk_buff *skb, bool not_data)
+{
+ struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+
+ /*
+ *mgt use 1M, although we have check it
+ *before this function use rate_control_send_low,
+ *we still check it here
+ */
+ if (not_data)
+ return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+
+ /*
+ *this rate is no use for true rate, firmware
+ *will control rate at all it just used for
+ *1.show in iwconfig in B/G mode
+ *2.in rtl_get_tcb_desc when we check rate is
+ * 1M we will not use FW rate but user rate.
+ */
+ if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
+ return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ } else {
+ if (rtlmac->mode == WIRELESS_MODE_B)
+ return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
+ else
+ return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ }
+}
+
+static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
+ struct ieee80211_tx_rate *rate,
+ struct ieee80211_tx_rate_control *txrc,
+ u8 tries, u8 rix, int rtsctsenable,
+ bool not_data)
+{
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+ rate->count = tries;
+ rate->idx = (rix > 0x2) ? rix : 0x2;
+
+ if (!not_data) {
+ if (txrc->short_preamble)
+ rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+ if (mac->bw_40)
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ if (mac->sgi_20 || mac->sgi_40)
+ rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+ if (mac->ht_enable)
+ rate->flags |= IEEE80211_TX_RC_MCS;
+ }
+}
+
+static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
+ void *priv_sta, struct ieee80211_tx_rate_control *txrc)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct sk_buff *skb = txrc->skb;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ __le16 fc = hdr->frame_control;
+ u8 try_per_rate, i, rix;
+ bool not_data = !ieee80211_is_data(fc);
+
+ if (rate_control_send_low(sta, priv_sta, txrc))
+ return;
+
+ rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);
+
+ try_per_rate = 1;
+ _rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
+ try_per_rate, rix, 1, not_data);
+
+ if (!not_data) {
+ for (i = 1; i < 4; i++)
+ _rtl_rc_rate_set_series(rtlpriv, &rates[i],
+ txrc, i, (rix - i), 1,
+ not_data);
+ }
+}
+
+static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
+{
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+ if (mac->act_scanning)
+ return false;
+
+ if (mac->cnt_after_linked < 3)
+ return false;
+
+ if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
+ return true;
+
+ return false;
+}
+
+/*mac80211 Rate Control callbacks*/
+static void rtl_tx_status(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (!priv_sta || !ieee80211_is_data(fc))
+ return;
+
+ if (rtl_is_special_data(mac->hw, skb, true))
+ return;
+
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr))
+ || is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ return;
+
+ /* Check if aggregation has to be enabled for this tid */
+ if (conf_is_ht(&mac->hw->conf) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc, tid;
+
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+
+ if (_rtl_tx_aggr_check(rtlpriv, tid))
+ ieee80211_start_tx_ba_session(sta, tid, 5000);
+ }
+ }
+}
+
+static void rtl_rate_init(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ u8 is_ht = conf_is_ht(&mac->hw->conf);
+
+ if ((mac->opmode == NL80211_IFTYPE_STATION) ||
+ (mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
+ (mac->opmode == NL80211_IFTYPE_ADHOC)) {
+
+ switch (sband->band) {
+ case IEEE80211_BAND_2GHZ:
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_G;
+ if (is_ht)
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ case IEEE80211_BAND_5GHZ:
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_A;
+ if (is_ht)
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Invalid band\n"));
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ }
+
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
+ ("Choosing rate table index: %d\n",
+ rtlpriv->rate_priv->cur_ratetab_idx));
+
+ }
+
+}
+
+static void rtl_rate_update(void *ppriv,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ u32 changed,
+ enum nl80211_channel_type oper_chan_type)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ bool oper_cw40 = false, oper_sgi40;
+ bool local_cw40 = mac->bw_40;
+ bool local_sgi40 = mac->sgi_40;
+ u8 is_ht = conf_is_ht(&mac->hw->conf);
+
+ if (changed & IEEE80211_RC_HT_CHANGED) {
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+ rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+ oper_cw40 = true;
+
+ oper_sgi40 = mac->sgi_40;
+
+ if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+ switch (sband->band) {
+ case IEEE80211_BAND_2GHZ:
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_G;
+ if (is_ht)
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ case IEEE80211_BAND_5GHZ:
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_A;
+ if (is_ht)
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Invalid band\n"));
+ rtlpriv->rate_priv->cur_ratetab_idx =
+ RATR_INX_WIRELESS_NGB;
+ break;
+ }
+ }
+ }
+}
+
+static void *rtl_rate_alloc(struct ieee80211_hw *hw,
+ struct dentry *debugfsdir)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ return rtlpriv;
+}
+
+static void rtl_rate_free(void *rtlpriv)
+{
+ return;
+}
+
+static void *rtl_rate_alloc_sta(void *ppriv,
+ struct ieee80211_sta *sta, gfp_t gfp)
+{
+ struct rtl_priv *rtlpriv = ppriv;
+ struct rtl_rate_priv *rate_priv;
+
+ rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
+ if (!rate_priv) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Unable to allocate private rc structure\n"));
+ return NULL;
+ }
+
+ rtlpriv->rate_priv = rate_priv;
+
+ return rate_priv;
+}
+
+static void rtl_rate_free_sta(void *rtlpriv,
+ struct ieee80211_sta *sta, void *priv_sta)
+{
+ struct rtl_rate_priv *rate_priv = priv_sta;
+ kfree(rate_priv);
+}
+
+static struct rate_control_ops rtl_rate_ops = {
+ .module = NULL,
+ .name = "rtl_rc",
+ .alloc = rtl_rate_alloc,
+ .free = rtl_rate_free,
+ .alloc_sta = rtl_rate_alloc_sta,
+ .free_sta = rtl_rate_free_sta,
+ .rate_init = rtl_rate_init,
+ .rate_update = rtl_rate_update,
+ .tx_status = rtl_tx_status,
+ .get_rate = rtl_get_rate,
+};
+
+int rtl_rate_control_register(void)
+{
+ return ieee80211_rate_control_register(&rtl_rate_ops);
+}
+
+void rtl_rate_control_unregister(void)
+{
+ ieee80211_rate_control_unregister(&rtl_rate_ops);
+}
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h
new file mode 100644
index 000000000000..b4667c035f0b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rc.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_RC_H__
+#define __RTL_RC_H__
+
+struct rtl_rate_priv {
+ u8 cur_ratetab_idx;
+ u8 ht_cap;
+};
+
+int rtl_rate_control_register(void);
+void rtl_rate_control_unregister(void);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
new file mode 100644
index 000000000000..3336ca999dfd
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -0,0 +1,400 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "wifi.h"
+#include "regd.h"
+
+static struct country_code_to_enum_rd allCountries[] = {
+ {COUNTRY_CODE_FCC, "US"},
+ {COUNTRY_CODE_IC, "US"},
+ {COUNTRY_CODE_ETSI, "EC"},
+ {COUNTRY_CODE_SPAIN, "EC"},
+ {COUNTRY_CODE_FRANCE, "EC"},
+ {COUNTRY_CODE_MKK, "JP"},
+ {COUNTRY_CODE_MKK1, "JP"},
+ {COUNTRY_CODE_ISRAEL, "EC"},
+ {COUNTRY_CODE_TELEC, "JP"},
+ {COUNTRY_CODE_MIC, "JP"},
+ {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
+ {COUNTRY_CODE_WORLD_WIDE_13, "EC"},
+ {COUNTRY_CODE_TELEC_NETGEAR, "EC"},
+};
+
+/*
+ *Only these channels all allow active
+ *scan on all world regulatory domains
+ */
+#define RTL819x_2GHZ_CH01_11 \
+ REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/*
+ *We enable active scan on these a case
+ *by case basis by regulatory domain
+ */
+#define RTL819x_2GHZ_CH12_13 \
+ REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN)
+
+#define RTL819x_2GHZ_CH14 \
+ REG_RULE(2484-10, 2484+10, 40, 0, 20, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_OFDM)
+
+static const struct ieee80211_regdomain rtl_regdom_11 = {
+ .n_reg_rules = 1,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_global = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ RTL819x_2GHZ_CH14,
+ }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_world = {
+ .n_reg_rules = 2,
+ .alpha2 = "99",
+ .reg_rules = {
+ RTL819x_2GHZ_CH01_11,
+ RTL819x_2GHZ_CH12_13,
+ }
+};
+
+static bool _rtl_is_radar_freq(u16 center_freq)
+{
+ return (center_freq >= 5260 && center_freq <= 5700);
+}
+
+static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
+{
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ const struct ieee80211_reg_rule *reg_rule;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+ u32 bandwidth = 0;
+ int r;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+ if (!wiphy->bands[band])
+ continue;
+
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (_rtl_is_radar_freq(ch->center_freq) ||
+ (ch->flags & IEEE80211_CHAN_RADAR))
+ continue;
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ r = freq_reg_info(wiphy, ch->center_freq,
+ bandwidth, &reg_rule);
+ if (r)
+ continue;
+
+ /*
+ *If 11d had a rule for this channel ensure
+ *we enable adhoc/beaconing if it allows us to
+ *use it. Note that we would have disabled it
+ *by applying our static world regdomain by
+ *default during init, prior to calling our
+ *regulatory_hint().
+ */
+
+ if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
+ ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
+ if (!(reg_rule->
+ flags & NL80211_RRF_PASSIVE_SCAN))
+ ch->flags &=
+ ~IEEE80211_CHAN_PASSIVE_SCAN;
+ } else {
+ if (ch->beacon_found)
+ ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN);
+ }
+ }
+ }
+}
+
+/* Allows active scan scan on Ch 12 and 13 */
+static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator
+ initiator)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+ u32 bandwidth = 0;
+ int r;
+
+ sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+ /*
+ *If no country IE has been received always enable active scan
+ *on these channels. This is only done for specific regulatory SKUs
+ */
+ if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ ch = &sband->channels[11]; /* CH 12 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ ch = &sband->channels[12]; /* CH 13 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ return;
+ }
+
+ /*
+ *If a country IE has been recieved check its rule for this
+ *channel first before enabling active scan. The passive scan
+ *would have been enforced by the initial processing of our
+ *custom regulatory domain.
+ */
+
+ ch = &sband->channels[11]; /* CH 12 */
+ r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+
+ ch = &sband->channels[12]; /* CH 13 */
+ r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+}
+
+/*
+ *Always apply Radar/DFS rules on
+ *freq range 5260 MHz - 5700 MHz
+ */
+static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
+ if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+ return;
+
+ sband = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (!_rtl_is_radar_freq(ch->center_freq))
+ continue;
+
+ /*
+ *We always enable radar detection/DFS on this
+ *frequency range. Additionally we also apply on
+ *this frequency range:
+ *- If STA mode does not yet have DFS supports disable
+ * active scanning
+ *- If adhoc mode does not support DFS yet then disable
+ * adhoc in the frequency.
+ *- If AP mode does not yet support radar detection/DFS
+ *do not allow AP mode
+ */
+ if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+ ch->flags |= IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+}
+
+static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator,
+ struct rtl_regulatory *reg)
+{
+ _rtl_reg_apply_beaconing_flags(wiphy, initiator);
+ _rtl_reg_apply_active_scan_flags(wiphy, initiator);
+ return;
+}
+
+static void _rtl_dump_channel_map(struct wiphy *wiphy)
+{
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ if (!wiphy->bands[band])
+ continue;
+ sband = wiphy->bands[band];
+ for (i = 0; i < sband->n_channels; i++)
+ ch = &sband->channels[i];
+ }
+}
+
+static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct rtl_regulatory *reg)
+{
+ /* We always apply this */
+ _rtl_reg_apply_radar_flags(wiphy);
+
+ switch (request->initiator) {
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ case NL80211_REGDOM_SET_BY_CORE:
+ case NL80211_REGDOM_SET_BY_USER:
+ break;
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
+ break;
+ }
+
+ _rtl_dump_channel_map(wiphy);
+
+ return 0;
+}
+
+static const struct ieee80211_regdomain *_rtl_regdomain_select(
+ struct rtl_regulatory *reg)
+{
+ switch (reg->country_code) {
+ case COUNTRY_CODE_FCC:
+ case COUNTRY_CODE_IC:
+ return &rtl_regdom_11;
+ case COUNTRY_CODE_ETSI:
+ case COUNTRY_CODE_SPAIN:
+ case COUNTRY_CODE_FRANCE:
+ case COUNTRY_CODE_ISRAEL:
+ case COUNTRY_CODE_TELEC_NETGEAR:
+ return &rtl_regdom_world;
+ case COUNTRY_CODE_MKK:
+ case COUNTRY_CODE_MKK1:
+ case COUNTRY_CODE_TELEC:
+ case COUNTRY_CODE_MIC:
+ return &rtl_regdom_global;
+ case COUNTRY_CODE_GLOBAL_DOMAIN:
+ return &rtl_regdom_global;
+ case COUNTRY_CODE_WORLD_WIDE_13:
+ return &rtl_regdom_world;
+ default:
+ return &rtl_regdom_world;
+ }
+}
+
+static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier) (struct wiphy *wiphy,
+ struct regulatory_request *
+ request))
+{
+ const struct ieee80211_regdomain *regd;
+
+ wiphy->reg_notifier = reg_notifier;
+ wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+ wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
+ wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
+ regd = _rtl_regdomain_select(reg);
+ wiphy_apply_custom_regulatory(wiphy, regd);
+ _rtl_reg_apply_radar_flags(wiphy);
+ _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+ return 0;
+}
+
+static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (allCountries[i].countrycode == countrycode)
+ return &allCountries[i];
+ }
+ return NULL;
+}
+
+int rtl_regd_init(struct ieee80211_hw *hw,
+ int (*reg_notifier) (struct wiphy *wiphy,
+ struct regulatory_request *request))
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct wiphy *wiphy = hw->wiphy;
+ struct country_code_to_enum_rd *country = NULL;
+
+ if (wiphy == NULL || &rtlpriv->regd == NULL)
+ return -EINVAL;
+
+ /* force the channel plan to world wide 13 */
+ rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
+ (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
+ rtlpriv->regd.country_code));
+
+ if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
+ (KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
+ "world wide 13 should be used\n"));
+
+ rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+ }
+
+ country = _rtl_regd_find_country(rtlpriv->regd.country_code);
+
+ if (country) {
+ rtlpriv->regd.alpha2[0] = country->isoName[0];
+ rtlpriv->regd.alpha2[1] = country->isoName[1];
+ } else {
+ rtlpriv->regd.alpha2[0] = '0';
+ rtlpriv->regd.alpha2[1] = '0';
+ }
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
+ (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
+ rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
+
+ _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
+
+ return 0;
+}
+
+int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n"));
+
+ return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
+}
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h
new file mode 100644
index 000000000000..4cdbc4ae76d4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/regd.h
@@ -0,0 +1,61 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_REGD_H__
+#define __RTL_REGD_H__
+
+struct country_code_to_enum_rd {
+ u16 countrycode;
+ const char *isoName;
+};
+
+enum country_code_type_t {
+ COUNTRY_CODE_FCC = 0,
+ COUNTRY_CODE_IC = 1,
+ COUNTRY_CODE_ETSI = 2,
+ COUNTRY_CODE_SPAIN = 3,
+ COUNTRY_CODE_FRANCE = 4,
+ COUNTRY_CODE_MKK = 5,
+ COUNTRY_CODE_MKK1 = 6,
+ COUNTRY_CODE_ISRAEL = 7,
+ COUNTRY_CODE_TELEC = 8,
+ COUNTRY_CODE_MIC = 9,
+ COUNTRY_CODE_GLOBAL_DOMAIN = 10,
+ COUNTRY_CODE_WORLD_WIDE_13 = 11,
+ COUNTRY_CODE_TELEC_NETGEAR = 12,
+
+ /*add new channel plan above this line */
+ COUNTRY_CODE_MAX
+};
+
+int rtl_regd_init(struct ieee80211_hw *hw,
+ int (*reg_notifier) (struct wiphy *wiphy,
+ struct regulatory_request *request));
+int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
new file mode 100644
index 000000000000..0f0be7c763b8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
@@ -0,0 +1,12 @@
+rtl8192ce-objs := \
+ dm.o \
+ fw.o \
+ hw.o \
+ led.o \
+ phy.o \
+ rf.o \
+ sw.o \
+ table.o \
+ trx.o
+
+obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
new file mode 100644
index 000000000000..83cd64895292
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -0,0 +1,257 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C_DEF_H__
+#define __RTL92C_DEF_H__
+
+#define HAL_RETRY_LIMIT_INFRA 48
+#define HAL_RETRY_LIMIT_AP_ADHOC 7
+
+#define PHY_RSSI_SLID_WIN_MAX 100
+#define PHY_LINKQUALITY_SLID_WIN_MAX 20
+#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
+
+#define RESET_DELAY_8185 20
+
+#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
+#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
+
+#define NUM_OF_FIRMWARE_QUEUE 10
+#define NUM_OF_PAGES_IN_FW 0x100
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
+
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
+
+#define MAX_LINES_HWCONFIG_TXT 1000
+#define MAX_BYTES_LINE_HWCONFIG_TXT 256
+
+#define SW_THREE_WIRE 0
+#define HW_THREE_WIRE 2
+
+#define BT_DEMO_BOARD 0
+#define BT_QA_BOARD 1
+#define BT_FPGA 2
+
+#define RX_SMOOTH_FACTOR 20
+
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
+#define HAL_PRIME_CHNL_OFFSET_LOWER 1
+#define HAL_PRIME_CHNL_OFFSET_UPPER 2
+
+#define MAX_H2C_QUEUE_NUM 10
+
+#define RX_MPDU_QUEUE 0
+#define RX_CMD_QUEUE 1
+#define RX_MAX_QUEUE 2
+#define AC2QUEUEID(_AC) (_AC)
+
+#define C2H_RX_CMD_HDR_LEN 8
+#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
+ LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
+#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
+ LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
+#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
+ LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
+#define GET_C2H_CMD_CONTINUE(__prxhdr) \
+ LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
+#define GET_C2H_CMD_CONTENT(__prxhdr) \
+ ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
+
+#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
+#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
+#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
+#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
+#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
+#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
+#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
+#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
+#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
+ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
+
+#define CHIP_VER_B BIT(4)
+#define CHIP_92C_BITMASK BIT(0)
+#define CHIP_92C_1T2R 0x03
+#define CHIP_92C 0x01
+#define CHIP_88C 0x00
+
+enum version_8192c {
+ VERSION_A_CHIP_92C = 0x01,
+ VERSION_A_CHIP_88C = 0x00,
+ VERSION_B_CHIP_92C = 0x11,
+ VERSION_B_CHIP_88C = 0x10,
+ VERSION_UNKNOWN = 0x88,
+};
+
+#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false)
+#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false)
+
+enum rtl819x_loopback_e {
+ RTL819X_NO_LOOPBACK = 0,
+ RTL819X_MAC_LOOPBACK = 1,
+ RTL819X_DMA_LOOPBACK = 2,
+ RTL819X_CCK_LOOPBACK = 3,
+};
+
+enum rf_optype {
+ RF_OP_BY_SW_3WIRE = 0,
+ RF_OP_BY_FW,
+ RF_OP_MAX
+};
+
+enum rf_power_state {
+ RF_ON,
+ RF_OFF,
+ RF_SLEEP,
+ RF_SHUT_DOWN,
+};
+
+enum power_save_mode {
+ POWER_SAVE_MODE_ACTIVE,
+ POWER_SAVE_MODE_SAVE,
+};
+
+enum power_polocy_config {
+ POWERCFG_MAX_POWER_SAVINGS,
+ POWERCFG_GLOBAL_POWER_SAVINGS,
+ POWERCFG_LOCAL_POWER_SAVINGS,
+ POWERCFG_LENOVO,
+};
+
+enum interface_select_pci {
+ INTF_SEL1_MINICARD = 0,
+ INTF_SEL0_PCIE = 1,
+ INTF_SEL2_RSV = 2,
+ INTF_SEL3_RSV = 3,
+};
+
+enum hal_fw_c2h_cmd_id {
+ HAL_FW_C2H_CMD_Read_MACREG = 0,
+ HAL_FW_C2H_CMD_Read_BBREG = 1,
+ HAL_FW_C2H_CMD_Read_RFREG = 2,
+ HAL_FW_C2H_CMD_Read_EEPROM = 3,
+ HAL_FW_C2H_CMD_Read_EFUSE = 4,
+ HAL_FW_C2H_CMD_Read_CAM = 5,
+ HAL_FW_C2H_CMD_Get_BasicRate = 6,
+ HAL_FW_C2H_CMD_Get_DataRate = 7,
+ HAL_FW_C2H_CMD_Survey = 8,
+ HAL_FW_C2H_CMD_SurveyDone = 9,
+ HAL_FW_C2H_CMD_JoinBss = 10,
+ HAL_FW_C2H_CMD_AddSTA = 11,
+ HAL_FW_C2H_CMD_DelSTA = 12,
+ HAL_FW_C2H_CMD_AtimDone = 13,
+ HAL_FW_C2H_CMD_TX_Report = 14,
+ HAL_FW_C2H_CMD_CCX_Report = 15,
+ HAL_FW_C2H_CMD_DTM_Report = 16,
+ HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
+ HAL_FW_C2H_CMD_C2HLBK = 18,
+ HAL_FW_C2H_CMD_C2HDBG = 19,
+ HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
+ HAL_FW_C2H_CMD_MAX
+};
+
+enum rtl_desc_qsel {
+ QSLT_BK = 0x2,
+ QSLT_BE = 0x0,
+ QSLT_VI = 0x5,
+ QSLT_VO = 0x7,
+ QSLT_BEACON = 0x10,
+ QSLT_HIGH = 0x11,
+ QSLT_MGNT = 0x12,
+ QSLT_CMD = 0x13,
+};
+
+enum rtl_desc92c_rate {
+ DESC92C_RATE1M = 0x00,
+ DESC92C_RATE2M = 0x01,
+ DESC92C_RATE5_5M = 0x02,
+ DESC92C_RATE11M = 0x03,
+
+ DESC92C_RATE6M = 0x04,
+ DESC92C_RATE9M = 0x05,
+ DESC92C_RATE12M = 0x06,
+ DESC92C_RATE18M = 0x07,
+ DESC92C_RATE24M = 0x08,
+ DESC92C_RATE36M = 0x09,
+ DESC92C_RATE48M = 0x0a,
+ DESC92C_RATE54M = 0x0b,
+
+ DESC92C_RATEMCS0 = 0x0c,
+ DESC92C_RATEMCS1 = 0x0d,
+ DESC92C_RATEMCS2 = 0x0e,
+ DESC92C_RATEMCS3 = 0x0f,
+ DESC92C_RATEMCS4 = 0x10,
+ DESC92C_RATEMCS5 = 0x11,
+ DESC92C_RATEMCS6 = 0x12,
+ DESC92C_RATEMCS7 = 0x13,
+ DESC92C_RATEMCS8 = 0x14,
+ DESC92C_RATEMCS9 = 0x15,
+ DESC92C_RATEMCS10 = 0x16,
+ DESC92C_RATEMCS11 = 0x17,
+ DESC92C_RATEMCS12 = 0x18,
+ DESC92C_RATEMCS13 = 0x19,
+ DESC92C_RATEMCS14 = 0x1a,
+ DESC92C_RATEMCS15 = 0x1b,
+ DESC92C_RATEMCS15_SG = 0x1c,
+ DESC92C_RATEMCS32 = 0x20,
+};
+
+struct phy_sts_cck_8192s_t {
+ u8 adc_pwdb_X[4];
+ u8 sq_rpt;
+ u8 cck_agc_rpt;
+};
+
+struct h2c_cmd_8192c {
+ u8 element_id;
+ u32 cmd_len;
+ u8 *p_cmdbuffer;
+};
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
new file mode 100644
index 000000000000..62e7c64e087b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
@@ -0,0 +1,1473 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+
+struct dig_t dm_digtable;
+static struct ps_t dm_pstable;
+
+static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
+ 0x7f8001fe,
+ 0x788001e2,
+ 0x71c001c7,
+ 0x6b8001ae,
+ 0x65400195,
+ 0x5fc0017f,
+ 0x5a400169,
+ 0x55400155,
+ 0x50800142,
+ 0x4c000130,
+ 0x47c0011f,
+ 0x43c0010f,
+ 0x40000100,
+ 0x3c8000f2,
+ 0x390000e4,
+ 0x35c000d7,
+ 0x32c000cb,
+ 0x300000c0,
+ 0x2d4000b5,
+ 0x2ac000ab,
+ 0x288000a2,
+ 0x26000098,
+ 0x24000090,
+ 0x22000088,
+ 0x20000080,
+ 0x1e400079,
+ 0x1c800072,
+ 0x1b00006c,
+ 0x19800066,
+ 0x18000060,
+ 0x16c0005b,
+ 0x15800056,
+ 0x14400051,
+ 0x1300004c,
+ 0x12000048,
+ 0x11000044,
+ 0x10000040,
+};
+
+static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
+ {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}
+};
+
+static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
+ {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}
+};
+
+static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
+{
+ dm_digtable.dig_enable_flag = true;
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ dm_digtable.cur_igvalue = 0x20;
+ dm_digtable.pre_igvalue = 0x0;
+ dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
+ dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
+ dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;
+ dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
+ dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
+ dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+ dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+ dm_digtable.rx_gain_range_max = DM_DIG_MAX;
+ dm_digtable.rx_gain_range_min = DM_DIG_MIN;
+ dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
+ dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
+ dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
+ dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX;
+ dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
+}
+
+static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ long rssi_val_min = 0;
+
+ if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) &&
+ (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) {
+ if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0)
+ rssi_val_min =
+ (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb >
+ rtlpriv->dm.undecorated_smoothed_pwdb) ?
+ rtlpriv->dm.undecorated_smoothed_pwdb :
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ else
+ rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
+ } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ||
+ dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) {
+ rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
+ } else if (dm_digtable.curmultista_connectstate ==
+ DIG_MULTISTA_CONNECT) {
+ rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ }
+
+ return (u8) rssi_val_min;
+}
+
+static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
+{
+ u32 ret_value;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
+ falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
+ falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+ falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
+ falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+ falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
+ falsealm_cnt->cnt_rate_illegal +
+ falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
+
+ rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
+ ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
+ falsealm_cnt->cnt_cck_fail = ret_value;
+
+ ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
+ falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
+ falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
+ falsealm_cnt->cnt_rate_illegal +
+ falsealm_cnt->cnt_crc8_fail +
+ falsealm_cnt->cnt_mcs_fail +
+ falsealm_cnt->cnt_cck_fail);
+
+ rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
+ rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
+ rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
+ rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
+ "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
+ falsealm_cnt->cnt_parity_fail,
+ falsealm_cnt->cnt_rate_illegal,
+ falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
+ falsealm_cnt->cnt_ofdm_fail,
+ falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
+}
+
+static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 value_igi = dm_digtable.cur_igvalue;
+
+ if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
+ value_igi--;
+ else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
+ value_igi += 0;
+ else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
+ value_igi++;
+ else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
+ value_igi += 2;
+ if (value_igi > DM_DIG_FA_UPPER)
+ value_igi = DM_DIG_FA_UPPER;
+ else if (value_igi < DM_DIG_FA_LOWER)
+ value_igi = DM_DIG_FA_LOWER;
+ if (rtlpriv->falsealm_cnt.cnt_all > 10000)
+ value_igi = 0x32;
+
+ dm_digtable.cur_igvalue = value_igi;
+ rtl92c_dm_write_dig(hw);
+}
+
+static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) {
+ if ((dm_digtable.backoff_val - 2) <
+ dm_digtable.backoff_val_range_min)
+ dm_digtable.backoff_val =
+ dm_digtable.backoff_val_range_min;
+ else
+ dm_digtable.backoff_val -= 2;
+ } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) {
+ if ((dm_digtable.backoff_val + 2) >
+ dm_digtable.backoff_val_range_max)
+ dm_digtable.backoff_val =
+ dm_digtable.backoff_val_range_max;
+ else
+ dm_digtable.backoff_val += 2;
+ }
+
+ if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) >
+ dm_digtable.rx_gain_range_max)
+ dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max;
+ else if ((dm_digtable.rssi_val_min + 10 -
+ dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
+ dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min;
+ else
+ dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 -
+ dm_digtable.backoff_val;
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("rssi_val_min = %x backoff_val %x\n",
+ dm_digtable.rssi_val_min, dm_digtable.backoff_val));
+
+ rtl92c_dm_write_dig(hw);
+}
+
+static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
+{
+ static u8 binitialized; /* initialized to false */
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ bool b_multi_sta = false;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ b_multi_sta = true;
+
+ if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate !=
+ DIG_STA_DISCONNECT)) {
+ binitialized = false;
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ return;
+ } else if (binitialized == false) {
+ binitialized = true;
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
+ dm_digtable.cur_igvalue = 0x20;
+ rtl92c_dm_write_dig(hw);
+ }
+
+ if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) {
+ if ((rssi_strength < dm_digtable.rssi_lowthresh) &&
+ (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
+
+ if (dm_digtable.dig_ext_port_stage ==
+ DIG_EXT_PORT_STAGE_2) {
+ dm_digtable.cur_igvalue = 0x20;
+ rtl92c_dm_write_dig(hw);
+ }
+
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
+ } else if (rssi_strength > dm_digtable.rssi_highthresh) {
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
+ rtl92c_dm_ctrl_initgain_by_fa(hw);
+ }
+ } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
+ dm_digtable.cur_igvalue = 0x20;
+ rtl92c_dm_write_dig(hw);
+ }
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("curmultista_connectstate = "
+ "%x dig_ext_port_stage %x\n",
+ dm_digtable.curmultista_connectstate,
+ dm_digtable.dig_ext_port_stage));
+}
+
+static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("presta_connectstate = %x,"
+ " cursta_connectctate = %x\n",
+ dm_digtable.presta_connectstate,
+ dm_digtable.cursta_connectctate));
+
+ if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
+ || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
+ || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
+
+ if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
+ dm_digtable.rssi_val_min =
+ rtl92c_dm_initial_gain_min_pwdb(hw);
+ rtl92c_dm_ctrl_initgain_by_rssi(hw);
+ }
+ } else {
+ dm_digtable.rssi_val_min = 0;
+ dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+ dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
+ dm_digtable.cur_igvalue = 0x20;
+ dm_digtable.pre_igvalue = 0;
+ rtl92c_dm_write_dig(hw);
+ }
+}
+
+static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
+ dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
+
+ if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
+ if (dm_digtable.rssi_val_min <= 25)
+ dm_digtable.cur_cck_pd_state =
+ CCK_PD_STAGE_LowRssi;
+ else
+ dm_digtable.cur_cck_pd_state =
+ CCK_PD_STAGE_HighRssi;
+ } else {
+ if (dm_digtable.rssi_val_min <= 20)
+ dm_digtable.cur_cck_pd_state =
+ CCK_PD_STAGE_LowRssi;
+ else
+ dm_digtable.cur_cck_pd_state =
+ CCK_PD_STAGE_HighRssi;
+ }
+ } else {
+ dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
+ }
+
+ if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) {
+ if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
+ if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
+ dm_digtable.cur_cck_fa_state =
+ CCK_FA_STAGE_High;
+ else
+ dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low;
+
+ if (dm_digtable.pre_cck_fa_state !=
+ dm_digtable.cur_cck_fa_state) {
+ if (dm_digtable.cur_cck_fa_state ==
+ CCK_FA_STAGE_Low)
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
+ 0x83);
+ else
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
+ 0xcd);
+
+ dm_digtable.pre_cck_fa_state =
+ dm_digtable.cur_cck_fa_state;
+ }
+
+ rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
+
+ if (IS_92C_SERIAL(rtlhal->version))
+ rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
+ MASKBYTE2, 0xd7);
+ } else {
+ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
+ rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
+
+ if (IS_92C_SERIAL(rtlhal->version))
+ rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
+ MASKBYTE2, 0xd3);
+ }
+ dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
+ }
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
+ ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
+}
+
+static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ if (mac->act_scanning == true)
+ return;
+
+ if ((mac->link_state > MAC80211_NOLINK) &&
+ (mac->link_state < MAC80211_LINKED))
+ dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT;
+ else if (mac->link_state >= MAC80211_LINKED)
+ dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
+ else
+ dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
+
+ rtl92c_dm_initial_gain_sta(hw);
+ rtl92c_dm_initial_gain_multi_sta(hw);
+ rtl92c_dm_cck_packet_detection_thresh(hw);
+
+ dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate;
+
+}
+
+static void rtl92c_dm_dig(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dm.b_dm_initialgain_enable == false)
+ return;
+ if (dm_digtable.dig_enable_flag == false)
+ return;
+
+ rtl92c_dm_ctrl_initgain_by_twoport(hw);
+
+}
+
+static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.bdynamic_txpower_enable = false;
+
+ rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+}
+
+static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long undecorated_smoothed_pwdb;
+
+ if (!rtlpriv->dm.bdynamic_txpower_enable)
+ return;
+
+ if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+ return;
+ }
+
+ if ((mac->link_state < MAC80211_LINKED) &&
+ (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("Not connected to any\n"));
+
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+
+ rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+ return;
+ }
+
+ if (mac->link_state >= MAC80211_LINKED) {
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Client PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("STA Default Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("AP Ext Port PWDB = 0x%lx\n",
+ undecorated_smoothed_pwdb));
+ }
+
+ if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+ } else if ((undecorated_smoothed_pwdb <
+ (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
+ (undecorated_smoothed_pwdb >=
+ TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
+
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+ } else if (undecorated_smoothed_pwdb <
+ (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
+ rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("TXHIGHPWRLEVEL_NORMAL\n"));
+ }
+
+ if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
+ rtlphy->current_channel));
+ rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+ }
+
+ rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
+void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+ ("cur_igvalue = 0x%x, "
+ "pre_igvalue = 0x%x, backoff_val = %d\n",
+ dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
+ dm_digtable.backoff_val));
+
+ if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
+ rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
+ dm_digtable.cur_igvalue);
+ rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
+ dm_digtable.cur_igvalue);
+
+ dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
+ }
+}
+
+static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
+
+ u8 h2c_parameter[3] = { 0 };
+
+ return;
+
+ if (tmpentry_max_pwdb != 0) {
+ rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb =
+ tmpentry_max_pwdb;
+ } else {
+ rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
+ }
+
+ if (tmpentry_min_pwdb != 0xff) {
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb =
+ tmpentry_min_pwdb;
+ } else {
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
+ }
+
+ h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
+ h2c_parameter[0] = 0;
+
+ rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
+}
+
+void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ rtlpriv->dm.bcurrent_turbo_edca = false;
+ rtlpriv->dm.bis_any_nonbepkts = false;
+ rtlpriv->dm.bis_cur_rdlstate = false;
+}
+
+static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ static u64 last_txok_cnt;
+ static u64 last_rxok_cnt;
+ u64 cur_txok_cnt;
+ u64 cur_rxok_cnt;
+ u32 edca_be_ul = 0x5ea42b;
+ u32 edca_be_dl = 0x5ea42b;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ goto dm_checkedcaturbo_exit;
+
+ if (mac->link_state != MAC80211_LINKED) {
+ rtlpriv->dm.bcurrent_turbo_edca = false;
+ return;
+ }
+
+ if (!mac->ht_enable) { /*FIX MERGE */
+ if (!(edca_be_ul & 0xffff0000))
+ edca_be_ul |= 0x005e0000;
+
+ if (!(edca_be_dl & 0xffff0000))
+ edca_be_dl |= 0x005e0000;
+ }
+
+ if ((!rtlpriv->dm.bis_any_nonbepkts) &&
+ (!rtlpriv->dm.b_disable_framebursting)) {
+ cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
+ cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+ if (cur_rxok_cnt > 4 * cur_txok_cnt) {
+ if (!rtlpriv->dm.bis_cur_rdlstate ||
+ !rtlpriv->dm.bcurrent_turbo_edca) {
+ rtl_write_dword(rtlpriv,
+ REG_EDCA_BE_PARAM,
+ edca_be_dl);
+ rtlpriv->dm.bis_cur_rdlstate = true;
+ }
+ } else {
+ if (rtlpriv->dm.bis_cur_rdlstate ||
+ !rtlpriv->dm.bcurrent_turbo_edca) {
+ rtl_write_dword(rtlpriv,
+ REG_EDCA_BE_PARAM,
+ edca_be_ul);
+ rtlpriv->dm.bis_cur_rdlstate = false;
+ }
+ }
+ rtlpriv->dm.bcurrent_turbo_edca = true;
+ } else {
+ if (rtlpriv->dm.bcurrent_turbo_edca) {
+ u8 tmp = AC0_BE;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_AC_PARAM,
+ (u8 *) (&tmp));
+ rtlpriv->dm.bcurrent_turbo_edca = false;
+ }
+ }
+
+dm_checkedcaturbo_exit:
+ rtlpriv->dm.bis_any_nonbepkts = false;
+ last_txok_cnt = rtlpriv->stats.txbytesunicast;
+ last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
+}
+
+static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
+ *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 thermalvalue, delta, delta_lck, delta_iqk;
+ long ele_a, ele_d, temp_cck, val_x, value32;
+ long val_y, ele_c;
+ u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old;
+ int i;
+ bool is2t = IS_92C_SERIAL(rtlhal->version);
+ u8 txpwr_level[2] = {0, 0};
+ u8 ofdm_min_index = 6, rf;
+
+ rtlpriv->dm.btxpower_trackingInit = true;
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
+
+ thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
+ "eeprom_thermalmeter 0x%x\n",
+ thermalvalue, rtlpriv->dm.thermalvalue,
+ rtlefuse->eeprom_thermalmeter));
+
+ rtl92c_phy_ap_calibrate(hw, (thermalvalue -
+ rtlefuse->eeprom_thermalmeter));
+ if (is2t)
+ rf = 2;
+ else
+ rf = 1;
+
+ if (thermalvalue) {
+ ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
+ MASKDWORD) & MASKOFDM_D;
+
+ for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
+ if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
+ ofdm_index_old[0] = (u8) i;
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Initial pathA ele_d reg0x%x = 0x%lx, "
+ "ofdm_index=0x%x\n",
+ ROFDM0_XATXIQIMBALANCE,
+ ele_d, ofdm_index_old[0]));
+ break;
+ }
+ }
+
+ if (is2t) {
+ ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
+ MASKDWORD) & MASKOFDM_D;
+
+ for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
+ if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
+ ofdm_index_old[1] = (u8) i;
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
+ DBG_LOUD,
+ ("Initial pathB ele_d reg0x%x = "
+ "0x%lx, ofdm_index=0x%x\n",
+ ROFDM0_XBTXIQIMBALANCE, ele_d,
+ ofdm_index_old[1]));
+ break;
+ }
+ }
+ }
+
+ temp_cck =
+ rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
+
+ for (i = 0; i < CCK_TABLE_LENGTH; i++) {
+ if (rtlpriv->dm.b_cck_inch14) {
+ if (memcmp((void *)&temp_cck,
+ (void *)&cckswing_table_ch14[i][2],
+ 4) == 0) {
+ cck_index_old = (u8) i;
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
+ DBG_LOUD,
+ ("Initial reg0x%x = 0x%lx, "
+ "cck_index=0x%x, ch 14 %d\n",
+ RCCK0_TXFILTER2, temp_cck,
+ cck_index_old,
+ rtlpriv->dm.b_cck_inch14));
+ break;
+ }
+ } else {
+ if (memcmp((void *)&temp_cck,
+ (void *)
+ &cckswing_table_ch1ch13[i][2],
+ 4) == 0) {
+ cck_index_old = (u8) i;
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
+ DBG_LOUD,
+ ("Initial reg0x%x = 0x%lx, "
+ "cck_index=0x%x, ch14 %d\n",
+ RCCK0_TXFILTER2, temp_cck,
+ cck_index_old,
+ rtlpriv->dm.b_cck_inch14));
+ break;
+ }
+ }
+ }
+
+ if (!rtlpriv->dm.thermalvalue) {
+ rtlpriv->dm.thermalvalue =
+ rtlefuse->eeprom_thermalmeter;
+ rtlpriv->dm.thermalvalue_lck = thermalvalue;
+ rtlpriv->dm.thermalvalue_iqk = thermalvalue;
+ for (i = 0; i < rf; i++)
+ rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
+ rtlpriv->dm.cck_index = cck_index_old;
+ }
+
+ delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
+ (thermalvalue - rtlpriv->dm.thermalvalue) :
+ (rtlpriv->dm.thermalvalue - thermalvalue);
+
+ delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
+ (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
+ (rtlpriv->dm.thermalvalue_lck - thermalvalue);
+
+ delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
+ (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
+ (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
+ "eeprom_thermalmeter 0x%x delta 0x%x "
+ "delta_lck 0x%x delta_iqk 0x%x\n",
+ thermalvalue, rtlpriv->dm.thermalvalue,
+ rtlefuse->eeprom_thermalmeter, delta, delta_lck,
+ delta_iqk));
+
+ if (delta_lck > 1) {
+ rtlpriv->dm.thermalvalue_lck = thermalvalue;
+ rtl92c_phy_lc_calibrate(hw);
+ }
+
+ if (delta > 0 && rtlpriv->dm.txpower_track_control) {
+ if (thermalvalue > rtlpriv->dm.thermalvalue) {
+ for (i = 0; i < rf; i++)
+ rtlpriv->dm.ofdm_index[i] -= delta;
+ rtlpriv->dm.cck_index -= delta;
+ } else {
+ for (i = 0; i < rf; i++)
+ rtlpriv->dm.ofdm_index[i] += delta;
+ rtlpriv->dm.cck_index += delta;
+ }
+
+ if (is2t) {
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("temp OFDM_A_index=0x%x, "
+ "OFDM_B_index=0x%x,"
+ "cck_index=0x%x\n",
+ rtlpriv->dm.ofdm_index[0],
+ rtlpriv->dm.ofdm_index[1],
+ rtlpriv->dm.cck_index));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("temp OFDM_A_index=0x%x,"
+ "cck_index=0x%x\n",
+ rtlpriv->dm.ofdm_index[0],
+ rtlpriv->dm.cck_index));
+ }
+
+ if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
+ for (i = 0; i < rf; i++)
+ ofdm_index[i] =
+ rtlpriv->dm.ofdm_index[i]
+ + 1;
+ cck_index = rtlpriv->dm.cck_index + 1;
+ } else {
+ for (i = 0; i < rf; i++)
+ ofdm_index[i] =
+ rtlpriv->dm.ofdm_index[i];
+ cck_index = rtlpriv->dm.cck_index;
+ }
+
+ for (i = 0; i < rf; i++) {
+ if (txpwr_level[i] >= 0 &&
+ txpwr_level[i] <= 26) {
+ if (thermalvalue >
+ rtlefuse->eeprom_thermalmeter) {
+ if (delta < 5)
+ ofdm_index[i] -= 1;
+
+ else
+ ofdm_index[i] -= 2;
+ } else if (delta > 5 && thermalvalue <
+ rtlefuse->
+ eeprom_thermalmeter) {
+ ofdm_index[i] += 1;
+ }
+ } else if (txpwr_level[i] >= 27 &&
+ txpwr_level[i] <= 32
+ && thermalvalue >
+ rtlefuse->eeprom_thermalmeter) {
+ if (delta < 5)
+ ofdm_index[i] -= 1;
+
+ else
+ ofdm_index[i] -= 2;
+ } else if (txpwr_level[i] >= 32 &&
+ txpwr_level[i] <= 38 &&
+ thermalvalue >
+ rtlefuse->eeprom_thermalmeter
+ && delta > 5) {
+ ofdm_index[i] -= 1;
+ }
+ }
+
+ if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
+ if (thermalvalue >
+ rtlefuse->eeprom_thermalmeter) {
+ if (delta < 5)
+ cck_index -= 1;
+
+ else
+ cck_index -= 2;
+ } else if (delta > 5 && thermalvalue <
+ rtlefuse->eeprom_thermalmeter) {
+ cck_index += 1;
+ }
+ } else if (txpwr_level[i] >= 27 &&
+ txpwr_level[i] <= 32 &&
+ thermalvalue >
+ rtlefuse->eeprom_thermalmeter) {
+ if (delta < 5)
+ cck_index -= 1;
+
+ else
+ cck_index -= 2;
+ } else if (txpwr_level[i] >= 32 &&
+ txpwr_level[i] <= 38 &&
+ thermalvalue > rtlefuse->eeprom_thermalmeter
+ && delta > 5) {
+ cck_index -= 1;
+ }
+
+ for (i = 0; i < rf; i++) {
+ if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
+ ofdm_index[i] = OFDM_TABLE_SIZE - 1;
+
+ else if (ofdm_index[i] < ofdm_min_index)
+ ofdm_index[i] = ofdm_min_index;
+ }
+
+ if (cck_index > CCK_TABLE_SIZE - 1)
+ cck_index = CCK_TABLE_SIZE - 1;
+ else if (cck_index < 0)
+ cck_index = 0;
+
+ if (is2t) {
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("new OFDM_A_index=0x%x, "
+ "OFDM_B_index=0x%x,"
+ "cck_index=0x%x\n",
+ ofdm_index[0], ofdm_index[1],
+ cck_index));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("new OFDM_A_index=0x%x,"
+ "cck_index=0x%x\n",
+ ofdm_index[0], cck_index));
+ }
+ }
+
+ if (rtlpriv->dm.txpower_track_control && delta != 0) {
+ ele_d =
+ (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
+ val_x = rtlphy->reg_e94;
+ val_y = rtlphy->reg_e9c;
+
+ if (val_x != 0) {
+ if ((val_x & 0x00000200) != 0)
+ val_x = val_x | 0xFFFFFC00;
+ ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
+
+ if ((val_y & 0x00000200) != 0)
+ val_y = val_y | 0xFFFFFC00;
+ ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
+
+ value32 = (ele_d << 22) |
+ ((ele_c & 0x3F) << 16) | ele_a;
+
+ rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
+ MASKDWORD, value32);
+
+ value32 = (ele_c & 0x000003C0) >> 6;
+ rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
+ value32);
+
+ value32 = ((val_x * ele_d) >> 7) & 0x01;
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(31), value32);
+
+ value32 = ((val_y * ele_d) >> 7) & 0x01;
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(29), value32);
+ } else {
+ rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
+ MASKDWORD,
+ ofdmswing_table[ofdm_index[0]]);
+
+ rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
+ 0x00);
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(31) | BIT(29), 0x00);
+ }
+
+ if (!rtlpriv->dm.b_cck_inch14) {
+ rtl_write_byte(rtlpriv, 0xa22,
+ cckswing_table_ch1ch13[cck_index]
+ [0]);
+ rtl_write_byte(rtlpriv, 0xa23,
+ cckswing_table_ch1ch13[cck_index]
+ [1]);
+ rtl_write_byte(rtlpriv, 0xa24,
+ cckswing_table_ch1ch13[cck_index]
+ [2]);
+ rtl_write_byte(rtlpriv, 0xa25,
+ cckswing_table_ch1ch13[cck_index]
+ [3]);
+ rtl_write_byte(rtlpriv, 0xa26,
+ cckswing_table_ch1ch13[cck_index]
+ [4]);
+ rtl_write_byte(rtlpriv, 0xa27,
+ cckswing_table_ch1ch13[cck_index]
+ [5]);
+ rtl_write_byte(rtlpriv, 0xa28,
+ cckswing_table_ch1ch13[cck_index]
+ [6]);
+ rtl_write_byte(rtlpriv, 0xa29,
+ cckswing_table_ch1ch13[cck_index]
+ [7]);
+ } else {
+ rtl_write_byte(rtlpriv, 0xa22,
+ cckswing_table_ch14[cck_index]
+ [0]);
+ rtl_write_byte(rtlpriv, 0xa23,
+ cckswing_table_ch14[cck_index]
+ [1]);
+ rtl_write_byte(rtlpriv, 0xa24,
+ cckswing_table_ch14[cck_index]
+ [2]);
+ rtl_write_byte(rtlpriv, 0xa25,
+ cckswing_table_ch14[cck_index]
+ [3]);
+ rtl_write_byte(rtlpriv, 0xa26,
+ cckswing_table_ch14[cck_index]
+ [4]);
+ rtl_write_byte(rtlpriv, 0xa27,
+ cckswing_table_ch14[cck_index]
+ [5]);
+ rtl_write_byte(rtlpriv, 0xa28,
+ cckswing_table_ch14[cck_index]
+ [6]);
+ rtl_write_byte(rtlpriv, 0xa29,
+ cckswing_table_ch14[cck_index]
+ [7]);
+ }
+
+ if (is2t) {
+ ele_d = (ofdmswing_table[ofdm_index[1]] &
+ 0xFFC00000) >> 22;
+
+ val_x = rtlphy->reg_eb4;
+ val_y = rtlphy->reg_ebc;
+
+ if (val_x != 0) {
+ if ((val_x & 0x00000200) != 0)
+ val_x = val_x | 0xFFFFFC00;
+ ele_a = ((val_x * ele_d) >> 8) &
+ 0x000003FF;
+
+ if ((val_y & 0x00000200) != 0)
+ val_y = val_y | 0xFFFFFC00;
+ ele_c = ((val_y * ele_d) >> 8) &
+ 0x00003FF;
+
+ value32 = (ele_d << 22) |
+ ((ele_c & 0x3F) << 16) | ele_a;
+ rtl_set_bbreg(hw,
+ ROFDM0_XBTXIQIMBALANCE,
+ MASKDWORD, value32);
+
+ value32 = (ele_c & 0x000003C0) >> 6;
+ rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
+ MASKH4BITS, value32);
+
+ value32 = ((val_x * ele_d) >> 7) & 0x01;
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(27), value32);
+
+ value32 = ((val_y * ele_d) >> 7) & 0x01;
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(25), value32);
+ } else {
+ rtl_set_bbreg(hw,
+ ROFDM0_XBTXIQIMBALANCE,
+ MASKDWORD,
+ ofdmswing_table[ofdm_index
+ [1]]);
+ rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
+ MASKH4BITS, 0x00);
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+ BIT(27) | BIT(25), 0x00);
+ }
+
+ }
+ }
+
+ if (delta_iqk > 3) {
+ rtlpriv->dm.thermalvalue_iqk = thermalvalue;
+ rtl92c_phy_iq_calibrate(hw, false);
+ }
+
+ if (rtlpriv->dm.txpower_track_control)
+ rtlpriv->dm.thermalvalue = thermalvalue;
+ }
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+
+}
+
+static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.btxpower_tracking = true;
+ rtlpriv->dm.btxpower_trackingInit = false;
+
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("pMgntInfo->btxpower_tracking = %d\n",
+ rtlpriv->dm.btxpower_tracking));
+}
+
+static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
+{
+ rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
+}
+
+static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
+{
+ rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
+}
+
+static void rtl92c_dm_check_txpower_tracking_thermal_meter(
+ struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ static u8 tm_trigger;
+
+ if (!rtlpriv->dm.btxpower_tracking)
+ return;
+
+ if (!tm_trigger) {
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
+ 0x60);
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Trigger 92S Thermal Meter!!\n"));
+ tm_trigger = 1;
+ return;
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+ ("Schedule TxPowerTracking direct call!!\n"));
+ rtl92c_dm_txpower_tracking_directcall(hw);
+ tm_trigger = 0;
+ }
+}
+
+void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
+{
+ rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
+}
+
+void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rate_adaptive *p_ra = &(rtlpriv->ra);
+
+ p_ra->ratr_state = DM_RATR_STA_INIT;
+ p_ra->pre_ratr_state = DM_RATR_STA_INIT;
+
+ if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
+ rtlpriv->dm.b_useramask = true;
+ else
+ rtlpriv->dm.b_useramask = false;
+
+}
+
+static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rate_adaptive *p_ra = &(rtlpriv->ra);
+ u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
+
+ if (is_hal_stop(rtlhal)) {
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+ ("<---- driver is going to unload\n"));
+ return;
+ }
+
+ if (!rtlpriv->dm.b_useramask) {
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+ ("<---- driver does not control rate adaptive mask\n"));
+ return;
+ }
+
+ if (mac->link_state == MAC80211_LINKED) {
+
+ switch (p_ra->pre_ratr_state) {
+ case DM_RATR_STA_HIGH:
+ high_rssithresh_for_ra = 50;
+ low_rssithresh_for_ra = 20;
+ break;
+ case DM_RATR_STA_MIDDLE:
+ high_rssithresh_for_ra = 55;
+ low_rssithresh_for_ra = 20;
+ break;
+ case DM_RATR_STA_LOW:
+ high_rssithresh_for_ra = 50;
+ low_rssithresh_for_ra = 25;
+ break;
+ default:
+ high_rssithresh_for_ra = 50;
+ low_rssithresh_for_ra = 20;
+ break;
+ }
+
+ if (rtlpriv->dm.undecorated_smoothed_pwdb >
+ (long)high_rssithresh_for_ra)
+ p_ra->ratr_state = DM_RATR_STA_HIGH;
+ else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+ (long)low_rssithresh_for_ra)
+ p_ra->ratr_state = DM_RATR_STA_MIDDLE;
+ else
+ p_ra->ratr_state = DM_RATR_STA_LOW;
+
+ if (p_ra->pre_ratr_state != p_ra->ratr_state) {
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+ ("RSSI = %ld\n",
+ rtlpriv->dm.undecorated_smoothed_pwdb));
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+ ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
+ RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+ ("PreState = %d, CurState = %d\n",
+ p_ra->pre_ratr_state, p_ra->ratr_state));
+
+ rtlpriv->cfg->ops->update_rate_mask(hw,
+ p_ra->ratr_state);
+
+ p_ra->pre_ratr_state = p_ra->ratr_state;
+ }
+ }
+}
+
+static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
+{
+ dm_pstable.pre_ccastate = CCA_MAX;
+ dm_pstable.cur_ccasate = CCA_MAX;
+ dm_pstable.pre_rfstate = RF_MAX;
+ dm_pstable.cur_rfstate = RF_MAX;
+ dm_pstable.rssi_val_min = 0;
+}
+
+static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ if (dm_pstable.rssi_val_min != 0) {
+ if (dm_pstable.pre_ccastate == CCA_2R) {
+ if (dm_pstable.rssi_val_min >= 35)
+ dm_pstable.cur_ccasate = CCA_1R;
+ else
+ dm_pstable.cur_ccasate = CCA_2R;
+ } else {
+ if (dm_pstable.rssi_val_min <= 30)
+ dm_pstable.cur_ccasate = CCA_2R;
+ else
+ dm_pstable.cur_ccasate = CCA_1R;
+ }
+ } else {
+ dm_pstable.cur_ccasate = CCA_MAX;
+ }
+
+ if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) {
+ if (dm_pstable.cur_ccasate == CCA_1R) {
+ if (get_rf_type(rtlphy) == RF_2T2R) {
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE0, 0x13);
+ rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20);
+ } else {
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+ MASKBYTE0, 0x23);
+ rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c);
+ }
+ } else {
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0,
+ 0x33);
+ rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63);
+ }
+ dm_pstable.pre_ccastate = dm_pstable.cur_ccasate;
+ }
+
+ RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n",
+ (dm_pstable.cur_ccasate ==
+ 0) ? "1RCCA" : "2RCCA"));
+}
+
+void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
+{
+ static u8 initialize;
+ static u32 reg_874, reg_c70, reg_85c, reg_a74;
+
+ if (initialize == 0) {
+ reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
+ MASKDWORD) & 0x1CC000) >> 14;
+
+ reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
+ MASKDWORD) & BIT(3)) >> 3;
+
+ reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
+ MASKDWORD) & 0xFF000000) >> 24;
+
+ reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
+
+ initialize = 1;
+ }
+
+ if (!bforce_in_normal) {
+ if (dm_pstable.rssi_val_min != 0) {
+ if (dm_pstable.pre_rfstate == RF_NORMAL) {
+ if (dm_pstable.rssi_val_min >= 30)
+ dm_pstable.cur_rfstate = RF_SAVE;
+ else
+ dm_pstable.cur_rfstate = RF_NORMAL;
+ } else {
+ if (dm_pstable.rssi_val_min <= 25)
+ dm_pstable.cur_rfstate = RF_NORMAL;
+ else
+ dm_pstable.cur_rfstate = RF_SAVE;
+ }
+ } else {
+ dm_pstable.cur_rfstate = RF_MAX;
+ }
+ } else {
+ dm_pstable.cur_rfstate = RF_NORMAL;
+ }
+
+ if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) {
+ if (dm_pstable.cur_rfstate == RF_SAVE) {
+ rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
+ 0x1C0000, 0x2);
+ rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
+ rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
+ 0xFF000000, 0x63);
+ rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
+ 0xC000, 0x2);
+ rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
+ rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
+ rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
+ } else {
+ rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
+ 0x1CC000, reg_874);
+ rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
+ reg_c70);
+ rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
+ reg_85c);
+ rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
+ rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
+ }
+
+ dm_pstable.pre_rfstate = dm_pstable.cur_rfstate;
+ }
+}
+
+static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (((mac->link_state == MAC80211_NOLINK)) &&
+ (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+ dm_pstable.rssi_val_min = 0;
+ RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
+ ("Not connected to any\n"));
+ }
+
+ if (mac->link_state == MAC80211_LINKED) {
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ dm_pstable.rssi_val_min =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+ RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
+ ("AP Client PWDB = 0x%lx\n",
+ dm_pstable.rssi_val_min));
+ } else {
+ dm_pstable.rssi_val_min =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
+ ("STA Default Port PWDB = 0x%lx\n",
+ dm_pstable.rssi_val_min));
+ }
+ } else {
+ dm_pstable.rssi_val_min =
+ rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+ RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
+ ("AP Ext Port PWDB = 0x%lx\n",
+ dm_pstable.rssi_val_min));
+ }
+
+ if (IS_92C_SERIAL(rtlhal->version))
+ rtl92c_dm_1r_cca(hw);
+}
+
+void rtl92c_dm_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+ rtl92c_dm_diginit(hw);
+ rtl92c_dm_init_dynamic_txpower(hw);
+ rtl92c_dm_init_edca_turbo(hw);
+ rtl92c_dm_init_rate_adaptive_mask(hw);
+ rtl92c_dm_initialize_txpower_tracking(hw);
+ rtl92c_dm_init_dynamic_bb_powersaving(hw);
+}
+
+void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool b_fw_current_inpsmode = false;
+ bool b_fw_ps_awake = true;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+ (u8 *) (&b_fw_current_inpsmode));
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
+ (u8 *) (&b_fw_ps_awake));
+
+ if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) &&
+ b_fw_ps_awake)
+ && (!ppsc->rfchange_inprogress)) {
+ rtl92c_dm_pwdb_monitor(hw);
+ rtl92c_dm_dig(hw);
+ rtl92c_dm_false_alarm_counter_statistics(hw);
+ rtl92c_dm_dynamic_bb_powersaving(hw);
+ rtl92c_dm_dynamic_txpower(hw);
+ rtl92c_dm_check_txpower_tracking(hw);
+ rtl92c_dm_refresh_rate_adaptive_mask(hw);
+ rtl92c_dm_check_edca_turbo(hw);
+ }
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
new file mode 100644
index 000000000000..463439e4074c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
@@ -0,0 +1,196 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C_DM_H__
+#define __RTL92C_DM_H__
+
+#define HAL_DM_DIG_DISABLE BIT(0)
+#define HAL_DM_HIPWR_DISABLE BIT(1)
+
+#define OFDM_TABLE_LENGTH 37
+#define CCK_TABLE_LENGTH 33
+
+#define OFDM_TABLE_SIZE 37
+#define CCK_TABLE_SIZE 33
+
+#define BW_AUTO_SWITCH_HIGH_LOW 25
+#define BW_AUTO_SWITCH_LOW_HIGH 30
+
+#define DM_DIG_THRESH_HIGH 40
+#define DM_DIG_THRESH_LOW 35
+
+#define DM_FALSEALARM_THRESH_LOW 400
+#define DM_FALSEALARM_THRESH_HIGH 1000
+
+#define DM_DIG_MAX 0x3e
+#define DM_DIG_MIN 0x1e
+
+#define DM_DIG_FA_UPPER 0x32
+#define DM_DIG_FA_LOWER 0x20
+#define DM_DIG_FA_TH0 0x20
+#define DM_DIG_FA_TH1 0x100
+#define DM_DIG_FA_TH2 0x200
+
+#define DM_DIG_BACKOFF_MAX 12
+#define DM_DIG_BACKOFF_MIN -4
+#define DM_DIG_BACKOFF_DEFAULT 10
+
+#define RXPATHSELECTION_SS_TH_lOW 30
+#define RXPATHSELECTION_DIFF_TH 18
+
+#define DM_RATR_STA_INIT 0
+#define DM_RATR_STA_HIGH 1
+#define DM_RATR_STA_MIDDLE 2
+#define DM_RATR_STA_LOW 3
+
+#define CTS2SELF_THVAL 30
+#define REGC38_TH 20
+
+#define WAIOTTHVal 25
+
+#define TXHIGHPWRLEVEL_NORMAL 0
+#define TXHIGHPWRLEVEL_LEVEL1 1
+#define TXHIGHPWRLEVEL_LEVEL2 2
+#define TXHIGHPWRLEVEL_BT1 3
+#define TXHIGHPWRLEVEL_BT2 4
+
+#define DM_TYPE_BYFW 0
+#define DM_TYPE_BYDRIVER 1
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
+
+struct ps_t {
+ u8 pre_ccastate;
+ u8 cur_ccasate;
+ u8 pre_rfstate;
+ u8 cur_rfstate;
+ long rssi_val_min;
+};
+
+struct dig_t {
+ u8 dig_enable_flag;
+ u8 dig_ext_port_stage;
+ u32 rssi_lowthresh;
+ u32 rssi_highthresh;
+ u32 fa_lowthresh;
+ u32 fa_highthresh;
+ u8 cursta_connectctate;
+ u8 presta_connectstate;
+ u8 curmultista_connectstate;
+ u8 pre_igvalue;
+ u8 cur_igvalue;
+ char backoff_val;
+ char backoff_val_range_max;
+ char backoff_val_range_min;
+ u8 rx_gain_range_max;
+ u8 rx_gain_range_min;
+ u8 rssi_val_min;
+ u8 pre_cck_pd_state;
+ u8 cur_cck_pd_state;
+ u8 pre_cck_fa_state;
+ u8 cur_cck_fa_state;
+ u8 pre_ccastate;
+ u8 cur_ccasate;
+};
+
+struct swat_t {
+ u8 failure_cnt;
+ u8 try_flag;
+ u8 stop_trying;
+ long pre_rssi;
+ long trying_threshold;
+ u8 cur_antenna;
+ u8 pre_antenna;
+};
+
+enum tag_dynamic_init_gain_operation_type_definition {
+ DIG_TYPE_THRESH_HIGH = 0,
+ DIG_TYPE_THRESH_LOW = 1,
+ DIG_TYPE_BACKOFF = 2,
+ DIG_TYPE_RX_GAIN_MIN = 3,
+ DIG_TYPE_RX_GAIN_MAX = 4,
+ DIG_TYPE_ENABLE = 5,
+ DIG_TYPE_DISABLE = 6,
+ DIG_OP_TYPE_MAX
+};
+
+enum tag_cck_packet_detection_threshold_type_definition {
+ CCK_PD_STAGE_LowRssi = 0,
+ CCK_PD_STAGE_HighRssi = 1,
+ CCK_FA_STAGE_Low = 2,
+ CCK_FA_STAGE_High = 3,
+ CCK_PD_STAGE_MAX = 4,
+};
+
+enum dm_1r_cca_e {
+ CCA_1R = 0,
+ CCA_2R = 1,
+ CCA_MAX = 2,
+};
+
+enum dm_rf_e {
+ RF_SAVE = 0,
+ RF_NORMAL = 1,
+ RF_MAX = 2,
+};
+
+enum dm_sw_ant_switch_e {
+ ANS_ANTENNA_B = 1,
+ ANS_ANTENNA_A = 2,
+ ANS_ANTENNA_MAX = 3,
+};
+
+enum dm_dig_ext_port_alg_e {
+ DIG_EXT_PORT_STAGE_0 = 0,
+ DIG_EXT_PORT_STAGE_1 = 1,
+ DIG_EXT_PORT_STAGE_2 = 2,
+ DIG_EXT_PORT_STAGE_3 = 3,
+ DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_dig_connect_e {
+ DIG_STA_DISCONNECT = 0,
+ DIG_STA_CONNECT = 1,
+ DIG_STA_BEFORE_CONNECT = 2,
+ DIG_MULTISTA_DISCONNECT = 3,
+ DIG_MULTISTA_CONNECT = 4,
+ DIG_CONNECT_MAX
+};
+
+extern struct dig_t dm_digtable;
+void rtl92c_dm_init(struct ieee80211_hw *hw);
+void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
+void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
+void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
+void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
+void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
+void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
new file mode 100644
index 000000000000..11dd22b987e7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
@@ -0,0 +1,804 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/firmware.h>
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+#include "table.h"
+
+static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
+ u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+ if (enable)
+ value32 |= MCUFWDL_EN;
+ else
+ value32 &= ~MCUFWDL_EN;
+ rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
+ } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
+ u8 tmp;
+ if (enable) {
+
+ tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
+ tmp | 0x04);
+
+ tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+ rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
+
+ tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
+ rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
+ } else {
+
+ tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+ rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
+
+ rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
+ }
+ }
+}
+
+static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
+ const u8 *buffer, u32 size)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 blockSize = sizeof(u32);
+ u8 *bufferPtr = (u8 *) buffer;
+ u32 *pu4BytePtr = (u32 *) buffer;
+ u32 i, offset, blockCount, remainSize;
+
+ blockCount = size / blockSize;
+ remainSize = size % blockSize;
+
+ for (i = 0; i < blockCount; i++) {
+ offset = i * blockSize;
+ rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
+ *(pu4BytePtr + i));
+ }
+
+ if (remainSize) {
+ offset = blockCount * blockSize;
+ bufferPtr += offset;
+ for (i = 0; i < remainSize; i++) {
+ rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
+ offset + i), *(bufferPtr + i));
+ }
+ }
+}
+
+static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
+ u32 page, const u8 *buffer, u32 size)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 value8;
+ u8 u8page = (u8) (page & 0x07);
+
+ value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+
+ rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+ _rtl92c_fw_block_write(hw, buffer, size);
+}
+
+static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+ u32 fwlen = *pfwlen;
+ u8 remain = (u8) (fwlen % 4);
+
+ remain = (remain == 0) ? 0 : (4 - remain);
+
+ while (remain > 0) {
+ pfwbuf[fwlen] = 0;
+ fwlen++;
+ remain--;
+ }
+
+ *pfwlen = fwlen;
+}
+
+static void _rtl92c_write_fw(struct ieee80211_hw *hw,
+ enum version_8192c version, u8 *buffer, u32 size)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool is_version_b;
+ u8 *bufferPtr = (u8 *) buffer;
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+
+ is_version_b = IS_CHIP_VER_B(version);
+ if (is_version_b) {
+ u32 pageNums, remainSize;
+ u32 page, offset;
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
+ _rtl92c_fill_dummy(bufferPtr, &size);
+
+ pageNums = size / FW_8192C_PAGE_SIZE;
+ remainSize = size % FW_8192C_PAGE_SIZE;
+
+ if (pageNums > 4) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Page numbers should not greater then 4\n"));
+ }
+
+ for (page = 0; page < pageNums; page++) {
+ offset = page * FW_8192C_PAGE_SIZE;
+ _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
+ FW_8192C_PAGE_SIZE);
+ }
+
+ if (remainSize) {
+ offset = pageNums * FW_8192C_PAGE_SIZE;
+ page = pageNums;
+ _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
+ remainSize);
+ }
+ } else {
+ _rtl92c_fw_block_write(hw, buffer, size);
+ }
+}
+
+static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int err = -EIO;
+ u32 counter = 0;
+ u32 value32;
+
+ do {
+ value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+ } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
+ (!(value32 & FWDL_ChkSum_rpt)));
+
+ if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
+ value32));
+ goto exit;
+ }
+
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+
+ value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+ value32 |= MCUFWDL_RDY;
+ value32 &= ~WINTINI_RDY;
+ rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
+
+ counter = 0;
+
+ do {
+ value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+ if (value32 & WINTINI_RDY) {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ ("Polling FW ready success!!"
+ " REG_MCUFWDL:0x%08x .\n",
+ value32));
+ err = 0;
+ goto exit;
+ }
+
+ mdelay(FW_8192C_POLLING_DELAY);
+
+ } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
+
+exit:
+ return err;
+}
+
+int rtl92c_download_fw(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl92c_firmware_header *pfwheader;
+ u8 *pfwdata;
+ u32 fwsize;
+ int err;
+ enum version_8192c version = rtlhal->version;
+
+ const struct firmware *firmware = NULL;
+
+ err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+ rtlpriv->io.dev);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to request firmware!\n"));
+ return 1;
+ }
+
+ if (firmware->size > 0x4000) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Firmware is too big!\n"));
+ release_firmware(firmware);
+ return 1;
+ }
+
+ memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
+ fwsize = firmware->size;
+ release_firmware(firmware);
+
+ pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
+ pfwdata = (u8 *) rtlhal->pfirmware;
+
+ if (IS_FW_HEADER_EXIST(pfwheader)) {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+ ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
+ pfwheader->version, pfwheader->signature,
+ (uint)sizeof(struct rtl92c_firmware_header)));
+
+ pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
+ fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
+ }
+
+ _rtl92c_enable_fw_download(hw, true);
+ _rtl92c_write_fw(hw, version, pfwdata, fwsize);
+ _rtl92c_enable_fw_download(hw, false);
+
+ err = _rtl92c_fw_free_to_go(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Firmware is not ready to run!\n"));
+ } else {
+ RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+ ("Firmware is ready to run!\n"));
+ }
+
+ return 0;
+}
+
+static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 val_hmetfr, val_mcutst_1;
+ bool result = false;
+
+ val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
+ val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
+
+ if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
+ result = true;
+ return result;
+}
+
+static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
+ u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 boxnum;
+ u16 box_reg, box_extreg;
+ u8 u1b_tmp;
+ bool isfw_read = false;
+ u8 buf_index;
+ bool bwrite_sucess = false;
+ u8 wait_h2c_limmit = 100;
+ u8 wait_writeh2c_limmit = 100;
+ u8 boxcontent[4], boxextcontent[2];
+ u32 h2c_waitcounter = 0;
+ unsigned long flag;
+ u8 idx;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+
+ while (true) {
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+ if (rtlhal->b_h2c_setinprogress) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("H2C set in progress! Wait to set.."
+ "element_id(%d).\n", element_id));
+
+ while (rtlhal->b_h2c_setinprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
+ flag);
+ h2c_waitcounter++;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Wait 100 us (%d times)...\n",
+ h2c_waitcounter));
+ udelay(100);
+
+ if (h2c_waitcounter > 1000)
+ return;
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
+ flag);
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+ } else {
+ rtlhal->b_h2c_setinprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+ break;
+ }
+ }
+
+ while (!bwrite_sucess) {
+ wait_writeh2c_limmit--;
+ if (wait_writeh2c_limmit == 0) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Write H2C fail because no trigger "
+ "for FW INT!\n"));
+ break;
+ }
+
+ boxnum = rtlhal->last_hmeboxnum;
+ switch (boxnum) {
+ case 0:
+ box_reg = REG_HMEBOX_0;
+ box_extreg = REG_HMEBOX_EXT_0;
+ break;
+ case 1:
+ box_reg = REG_HMEBOX_1;
+ box_extreg = REG_HMEBOX_EXT_1;
+ break;
+ case 2:
+ box_reg = REG_HMEBOX_2;
+ box_extreg = REG_HMEBOX_EXT_2;
+ break;
+ case 3:
+ box_reg = REG_HMEBOX_3;
+ box_extreg = REG_HMEBOX_EXT_3;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+ isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
+ while (!isfw_read) {
+
+ wait_h2c_limmit--;
+ if (wait_h2c_limmit == 0) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Wating too long for FW read "
+ "clear HMEBox(%d)!\n", boxnum));
+ break;
+ }
+
+ udelay(10);
+
+ isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
+ u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Wating for FW read clear HMEBox(%d)!!! "
+ "0x1BF = %2x\n", boxnum, u1b_tmp));
+ }
+
+ if (!isfw_read) {
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Write H2C register BOX[%d] fail!!!!! "
+ "Fw do not read.\n", boxnum));
+ break;
+ }
+
+ memset(boxcontent, 0, sizeof(boxcontent));
+ memset(boxextcontent, 0, sizeof(boxextcontent));
+ boxcontent[0] = element_id;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("Write element_id box_reg(%4x) = %2x\n",
+ box_reg, element_id));
+
+ switch (cmd_len) {
+ case 1:
+ boxcontent[0] &= ~(BIT(7));
+ memcpy((u8 *) (boxcontent) + 1,
+ p_cmdbuffer + buf_index, 1);
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ case 2:
+ boxcontent[0] &= ~(BIT(7));
+ memcpy((u8 *) (boxcontent) + 1,
+ p_cmdbuffer + buf_index, 2);
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ case 3:
+ boxcontent[0] &= ~(BIT(7));
+ memcpy((u8 *) (boxcontent) + 1,
+ p_cmdbuffer + buf_index, 3);
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ case 4:
+ boxcontent[0] |= (BIT(7));
+ memcpy((u8 *) (boxextcontent),
+ p_cmdbuffer + buf_index, 2);
+ memcpy((u8 *) (boxcontent) + 1,
+ p_cmdbuffer + buf_index + 2, 2);
+
+ for (idx = 0; idx < 2; idx++) {
+ rtl_write_byte(rtlpriv, box_extreg + idx,
+ boxextcontent[idx]);
+ }
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ case 5:
+ boxcontent[0] |= (BIT(7));
+ memcpy((u8 *) (boxextcontent),
+ p_cmdbuffer + buf_index, 2);
+ memcpy((u8 *) (boxcontent) + 1,
+ p_cmdbuffer + buf_index + 2, 3);
+
+ for (idx = 0; idx < 2; idx++) {
+ rtl_write_byte(rtlpriv, box_extreg + idx,
+ boxextcontent[idx]);
+ }
+
+ for (idx = 0; idx < 4; idx++) {
+ rtl_write_byte(rtlpriv, box_reg + idx,
+ boxcontent[idx]);
+ }
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+ bwrite_sucess = true;
+
+ rtlhal->last_hmeboxnum = boxnum + 1;
+ if (rtlhal->last_hmeboxnum == 4)
+ rtlhal->last_hmeboxnum = 0;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+ ("pHalData->last_hmeboxnum = %d\n",
+ rtlhal->last_hmeboxnum));
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+ rtlhal->b_h2c_setinprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+}
+
+void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
+ u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u32 tmp_cmdbuf[2];
+
+ if (rtlhal->bfw_ready == false) {
+ RT_ASSERT(false, ("return H2C cmd because of Fw "
+ "download fail!!!\n"));
+ return;
+ }
+
+ memset(tmp_cmdbuf, 0, 8);
+ memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
+ _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
+
+ return;
+}
+
+void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
+{
+ u8 u1b_tmp;
+ u8 delay = 100;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+
+ while (u1b_tmp & BIT(2)) {
+ delay--;
+ if (delay == 0) {
+ RT_ASSERT(false, ("8051 reset fail.\n"));
+ break;
+ }
+ udelay(50);
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+ }
+}
+
+void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 u1_h2c_set_pwrmode[3] = {0};
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+
+ SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
+ SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
+ SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
+ ppsc->reg_max_lps_awakeintvl);
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+ "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+ u1_h2c_set_pwrmode, 3);
+ rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
+
+}
+
+static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring;
+ struct rtl_tx_desc *pdesc;
+ u8 own;
+ unsigned long flags;
+ struct sk_buff *pskb = NULL;
+
+ ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+ pskb = __skb_dequeue(&ring->queue);
+ if (pskb)
+ kfree_skb(pskb);
+
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+ pdesc = &ring->desc[0];
+ own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
+
+ rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
+
+ __skb_queue_tail(&ring->queue, skb);
+
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+ rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+ return true;
+}
+
+#define BEACON_PG 0 /*->1*/
+#define PSPOLL_PG 2
+#define NULL_PG 3
+#define PROBERSP_PG 4 /*->5*/
+
+#define TOTAL_RESERVED_PKT_LEN 768
+
+static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
+ /* page 0 beacon */
+ 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+ 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
+ 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
+ 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
+ 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
+ 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
+ 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
+ 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 1 beacon */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 2 ps-poll */
+ 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
+ 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 3 null */
+ 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
+ 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+ 0x00, 0x40, 0x10, 0x10, 0x00, 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,
+ 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 4 probe_resp */
+ 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
+ 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+ 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
+ 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
+ 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
+ 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
+ 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
+ 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
+ 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
+ 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
+ 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* page 5 probe_resp */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct sk_buff *skb = NULL;
+
+ u32 totalpacketlen;
+ bool rtstatus;
+ u8 u1RsvdPageLoc[3] = {0};
+ bool b_dlok = false;
+
+ u8 *beacon;
+ u8 *p_pspoll;
+ u8 *nullfunc;
+ u8 *p_probersp;
+ /*---------------------------------------------------------
+ (1) beacon
+ ---------------------------------------------------------*/
+ beacon = &reserved_page_packet[BEACON_PG * 128];
+ SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
+
+ /*-------------------------------------------------------
+ (2) ps-poll
+ --------------------------------------------------------*/
+ p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
+ SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
+ SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
+ SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+
+ SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
+
+ /*--------------------------------------------------------
+ (3) null data
+ ---------------------------------------------------------*/
+ nullfunc = &reserved_page_packet[NULL_PG * 128];
+ SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
+ SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
+
+ /*---------------------------------------------------------
+ (4) probe response
+ ----------------------------------------------------------*/
+ p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
+ SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
+ SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
+ SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+
+ SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
+
+ totalpacketlen = TOTAL_RESERVED_PKT_LEN;
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+ "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+ &reserved_page_packet[0], totalpacketlen);
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+ "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+ u1RsvdPageLoc, 3);
+
+
+ skb = dev_alloc_skb(totalpacketlen);
+ memcpy((u8 *) skb_put(skb, totalpacketlen),
+ &reserved_page_packet, totalpacketlen);
+
+ rtstatus = _rtl92c_cmd_send_packet(hw, skb);
+
+ if (rtstatus)
+ b_dlok = true;
+
+ if (b_dlok) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Set RSVD page location to Fw.\n"));
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+ "H2C_RSVDPAGE:\n",
+ u1RsvdPageLoc, 3);
+ rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
+ sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
+ } else
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+}
+
+void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
+{
+ u8 u1_joinbssrpt_parm[1] = {0};
+
+ SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
+
+ rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h
new file mode 100644
index 000000000000..3db33bd14666
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C__FW__H__
+#define __RTL92C__FW__H__
+
+#define FW_8192C_SIZE 0x3000
+#define FW_8192C_START_ADDRESS 0x1000
+#define FW_8192C_END_ADDRESS 0x3FFF
+#define FW_8192C_PAGE_SIZE 4096
+#define FW_8192C_POLLING_DELAY 5
+#define FW_8192C_POLLING_TIMEOUT_COUNT 100
+
+#define IS_FW_HEADER_EXIST(_pfwhdr) \
+ ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\
+ (_pfwhdr->signature&0xFFF0) == 0x88C0)
+
+struct rtl92c_firmware_header {
+ u16 signature;
+ u8 category;
+ u8 function;
+ u16 version;
+ u8 subversion;
+ u8 rsvd1;
+ u8 month;
+ u8 date;
+ u8 hour;
+ u8 minute;
+ u16 ramcodeSize;
+ u16 rsvd2;
+ u32 svnindex;
+ u32 rsvd3;
+ u32 rsvd4;
+ u32 rsvd5;
+};
+
+enum rtl8192c_h2c_cmd {
+ H2C_AP_OFFLOAD = 0,
+ H2C_SETPWRMODE = 1,
+ H2C_JOINBSSRPT = 2,
+ H2C_RSVDPAGE = 3,
+ H2C_RSSI_REPORT = 5,
+ H2C_RA_MASK = 6,
+ MAX_H2CCMD
+};
+
+#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
+
+#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
+#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
+ SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
+
+int rtl92c_download_fw(struct ieee80211_hw *hw);
+void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
+ u32 cmd_len, u8 *p_cmdbuffer);
+void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
+void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
new file mode 100644
index 000000000000..1c41a0c93506
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -0,0 +1,2162 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
+
+#define LLT_CONFIG 5
+
+static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
+ u8 set_bits, u8 clear_bits)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpci->reg_bcn_ctrl_val |= set_bits;
+ rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
+
+ rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
+}
+
+static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp1byte;
+
+ tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
+ tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+ tmp1byte &= ~(BIT(0));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 tmp1byte;
+
+ tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+ tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+ tmp1byte |= BIT(0);
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+ _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1));
+}
+
+static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+ _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0);
+}
+
+void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ switch (variable) {
+ case HW_VAR_RCR:
+ *((u32 *) (val)) = rtlpci->receive_config;
+ break;
+ case HW_VAR_RF_STATE:
+ *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+ break;
+ case HW_VAR_FWLPS_RF_ON:{
+ enum rf_pwrstate rfState;
+ u32 val_rcr;
+
+ rtlpriv->cfg->ops->get_hw_reg(hw,
+ HW_VAR_RF_STATE,
+ (u8 *) (&rfState));
+ if (rfState == ERFOFF) {
+ *((bool *) (val)) = true;
+ } else {
+ val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
+ val_rcr &= 0x00070000;
+ if (val_rcr)
+ *((bool *) (val)) = false;
+ else
+ *((bool *) (val)) = true;
+ }
+ break;
+ }
+ case HW_VAR_FW_PSMODE_STATUS:
+ *((bool *) (val)) = ppsc->b_fw_current_inpsmode;
+ break;
+ case HW_VAR_CORRECT_TSF:{
+ u64 tsf;
+ u32 *ptsf_low = (u32 *)&tsf;
+ u32 *ptsf_high = ((u32 *)&tsf) + 1;
+
+ *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
+ *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
+
+ *((u64 *) (val)) = tsf;
+
+ break;
+ }
+ case HW_VAR_MGT_FILTER:
+ *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
+ break;
+ case HW_VAR_CTRL_FILTER:
+ *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
+ break;
+ case HW_VAR_DATA_FILTER:
+ *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+}
+
+void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u8 idx;
+
+ switch (variable) {
+ case HW_VAR_ETHER_ADDR:{
+ for (idx = 0; idx < ETH_ALEN; idx++) {
+ rtl_write_byte(rtlpriv, (REG_MACID + idx),
+ val[idx]);
+ }
+ break;
+ }
+ case HW_VAR_BASIC_RATE:{
+ u16 b_rate_cfg = ((u16 *) val)[0];
+ u8 rate_index = 0;
+ b_rate_cfg = b_rate_cfg & 0x15f;
+ b_rate_cfg |= 0x01;
+ rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
+ rtl_write_byte(rtlpriv, REG_RRSR + 1,
+ (b_rate_cfg >> 8)&0xff);
+ while (b_rate_cfg > 0x1) {
+ b_rate_cfg = (b_rate_cfg >> 1);
+ rate_index++;
+ }
+ rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
+ rate_index);
+ break;
+ }
+ case HW_VAR_BSSID:{
+ for (idx = 0; idx < ETH_ALEN; idx++) {
+ rtl_write_byte(rtlpriv, (REG_BSSID + idx),
+ val[idx]);
+ }
+ break;
+ }
+ case HW_VAR_SIFS:{
+ rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
+ rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
+
+ rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
+ rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
+
+ if (!mac->ht_enable)
+ rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+ 0x0e0e);
+ else
+ rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+ *((u16 *) val));
+ break;
+ }
+ case HW_VAR_SLOT_TIME:{
+ u8 e_aci;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("HW_VAR_SLOT_TIME %x\n", val[0]));
+
+ rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
+
+ for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_AC_PARAM,
+ (u8 *) (&e_aci));
+ }
+ break;
+ }
+ case HW_VAR_ACK_PREAMBLE:{
+ u8 reg_tmp;
+ u8 short_preamble = (bool) (*(u8 *) val);
+ reg_tmp = (mac->cur_40_prime_sc) << 5;
+ if (short_preamble)
+ reg_tmp |= 0x80;
+
+ rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
+ break;
+ }
+ case HW_VAR_AMPDU_MIN_SPACE:{
+ u8 min_spacing_to_set;
+ u8 sec_min_space;
+
+ min_spacing_to_set = *((u8 *) val);
+ if (min_spacing_to_set <= 7) {
+ sec_min_space = 0;
+
+ if (min_spacing_to_set < sec_min_space)
+ min_spacing_to_set = sec_min_space;
+
+ mac->min_space_cfg = ((mac->min_space_cfg &
+ 0xf8) |
+ min_spacing_to_set);
+
+ *val = min_spacing_to_set;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+ mac->min_space_cfg));
+
+ rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+ mac->min_space_cfg);
+ }
+ break;
+ }
+ case HW_VAR_SHORTGI_DENSITY:{
+ u8 density_to_set;
+
+ density_to_set = *((u8 *) val);
+ mac->min_space_cfg |= (density_to_set << 3);
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+ mac->min_space_cfg));
+
+ rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+ mac->min_space_cfg);
+
+ break;
+ }
+ case HW_VAR_AMPDU_FACTOR:{
+ u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
+
+ u8 factor_toset;
+ u8 *p_regtoset = NULL;
+ u8 index = 0;
+
+ p_regtoset = regtoset_normal;
+
+ factor_toset = *((u8 *) val);
+ if (factor_toset <= 3) {
+ factor_toset = (1 << (factor_toset + 2));
+ if (factor_toset > 0xf)
+ factor_toset = 0xf;
+
+ for (index = 0; index < 4; index++) {
+ if ((p_regtoset[index] & 0xf0) >
+ (factor_toset << 4))
+ p_regtoset[index] =
+ (p_regtoset[index] & 0x0f) |
+ (factor_toset << 4);
+
+ if ((p_regtoset[index] & 0x0f) >
+ factor_toset)
+ p_regtoset[index] =
+ (p_regtoset[index] & 0xf0) |
+ (factor_toset);
+
+ rtl_write_byte(rtlpriv,
+ (REG_AGGLEN_LMT + index),
+ p_regtoset[index]);
+
+ }
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
+ factor_toset));
+ }
+ break;
+ }
+ case HW_VAR_AC_PARAM:{
+ u8 e_aci = *((u8 *) val);
+ u32 u4b_ac_param = 0;
+
+ u4b_ac_param |= (u32) mac->ac[e_aci].aifs;
+ u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min
+ & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
+ u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max &
+ 0xF) << AC_PARAM_ECW_MAX_OFFSET;
+ u4b_ac_param |= (u32) mac->ac[e_aci].tx_op
+ << AC_PARAM_TXOP_LIMIT_OFFSET;
+
+ RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+ ("queue:%x, ac_param:%x\n", e_aci,
+ u4b_ac_param));
+
+ switch (e_aci) {
+ case AC1_BK:
+ rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
+ u4b_ac_param);
+ break;
+ case AC0_BE:
+ rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
+ u4b_ac_param);
+ break;
+ case AC2_VI:
+ rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM,
+ u4b_ac_param);
+ break;
+ case AC3_VO:
+ rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM,
+ u4b_ac_param);
+ break;
+ default:
+ RT_ASSERT(false,
+ ("SetHwReg8185(): invalid aci: %d !\n",
+ e_aci));
+ break;
+ }
+
+ if (rtlpci->acm_method != eAcmWay2_SW)
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_ACM_CTRL,
+ (u8 *) (&e_aci));
+ break;
+ }
+ case HW_VAR_ACM_CTRL:{
+ u8 e_aci = *((u8 *) val);
+ union aci_aifsn *p_aci_aifsn =
+ (union aci_aifsn *)(&(mac->ac[0].aifs));
+ u8 acm = p_aci_aifsn->f.acm;
+ u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
+
+ acm_ctrl =
+ acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
+
+ if (acm) {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl |= AcmHw_BeqEn;
+ break;
+ case AC2_VI:
+ acm_ctrl |= AcmHw_ViqEn;
+ break;
+ case AC3_VO:
+ acm_ctrl |= AcmHw_VoqEn;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("HW_VAR_ACM_CTRL acm set "
+ "failed: eACI is %d\n", acm));
+ break;
+ }
+ } else {
+ switch (e_aci) {
+ case AC0_BE:
+ acm_ctrl &= (~AcmHw_BeqEn);
+ break;
+ case AC2_VI:
+ acm_ctrl &= (~AcmHw_ViqEn);
+ break;
+ case AC3_VO:
+ acm_ctrl &= (~AcmHw_BeqEn);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ }
+
+ RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
+ ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
+ "Write 0x%X\n", acm_ctrl));
+ rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
+ break;
+ }
+ case HW_VAR_RCR:{
+ rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
+ rtlpci->receive_config = ((u32 *) (val))[0];
+ break;
+ }
+ case HW_VAR_RETRY_LIMIT:{
+ u8 retry_limit = ((u8 *) (val))[0];
+
+ rtl_write_word(rtlpriv, REG_RL,
+ retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+ retry_limit << RETRY_LIMIT_LONG_SHIFT);
+ break;
+ }
+ case HW_VAR_DUAL_TSF_RST:
+ rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
+ break;
+ case HW_VAR_EFUSE_BYTES:
+ rtlefuse->efuse_usedbytes = *((u16 *) val);
+ break;
+ case HW_VAR_EFUSE_USAGE:
+ rtlefuse->efuse_usedpercentage = *((u8 *) val);
+ break;
+ case HW_VAR_IO_CMD:
+ rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val));
+ break;
+ case HW_VAR_WPA_CONFIG:
+ rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
+ break;
+ case HW_VAR_SET_RPWM:{
+ u8 rpwm_val;
+
+ rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
+ udelay(1);
+
+ if (rpwm_val & BIT(7)) {
+ rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
+ (*(u8 *) val));
+ } else {
+ rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
+ ((*(u8 *) val) | BIT(7)));
+ }
+
+ break;
+ }
+ case HW_VAR_H2C_FW_PWRMODE:{
+ u8 psmode = (*(u8 *) val);
+
+ if ((psmode != FW_PS_ACTIVE_MODE) &&
+ (!IS_92C_SERIAL(rtlhal->version))) {
+ rtl92c_dm_rf_saving(hw, true);
+ }
+
+ rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
+ break;
+ }
+ case HW_VAR_FW_PSMODE_STATUS:
+ ppsc->b_fw_current_inpsmode = *((bool *) val);
+ break;
+ case HW_VAR_H2C_FW_JOINBSSRPT:{
+ u8 mstatus = (*(u8 *) val);
+ u8 tmp_regcr, tmp_reg422;
+ bool b_recover = false;
+
+ if (mstatus == RT_MEDIA_CONNECT) {
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID,
+ NULL);
+
+ tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
+ rtl_write_byte(rtlpriv, REG_CR + 1,
+ (tmp_regcr | BIT(0)));
+
+ _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3));
+ _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
+
+ tmp_reg422 =
+ rtl_read_byte(rtlpriv,
+ REG_FWHW_TXQ_CTRL + 2);
+ if (tmp_reg422 & BIT(6))
+ b_recover = true;
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
+ tmp_reg422 & (~BIT(6)));
+
+ rtl92c_set_fw_rsvdpagepkt(hw, 0);
+
+ _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
+ _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
+
+ if (b_recover) {
+ rtl_write_byte(rtlpriv,
+ REG_FWHW_TXQ_CTRL + 2,
+ tmp_reg422);
+ }
+
+ rtl_write_byte(rtlpriv, REG_CR + 1,
+ (tmp_regcr & ~(BIT(0))));
+ }
+ rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
+
+ break;
+ }
+ case HW_VAR_AID:{
+ u16 u2btmp;
+ u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
+ u2btmp &= 0xC000;
+ rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
+ mac->assoc_id));
+
+ break;
+ }
+ case HW_VAR_CORRECT_TSF:{
+ u8 btype_ibss = ((u8 *) (val))[0];
+
+ /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ?
+ 1 : 0;*/
+
+ if (btype_ibss == true)
+ _rtl92ce_stop_tx_beacon(hw);
+
+ _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3));
+
+ rtl_write_dword(rtlpriv, REG_TSFTR,
+ (u32) (mac->tsf & 0xffffffff));
+ rtl_write_dword(rtlpriv, REG_TSFTR + 4,
+ (u32) ((mac->tsf >> 32)&0xffffffff));
+
+ _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
+
+ if (btype_ibss == true)
+ _rtl92ce_resume_tx_beacon(hw);
+
+ break;
+
+ }
+ case HW_VAR_MGT_FILTER:
+ rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val);
+ break;
+ case HW_VAR_CTRL_FILTER:
+ rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val);
+ break;
+ case HW_VAR_DATA_FILTER:
+ rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
+ "not process\n"));
+ break;
+ }
+}
+
+static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool status = true;
+ long count = 0;
+ u32 value = _LLT_INIT_ADDR(address) |
+ _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
+
+ rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
+
+ do {
+ value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
+ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
+ break;
+
+ if (count > POLLING_LLT_THRESHOLD) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to polling write LLT done at "
+ "address %d!\n", address));
+ status = false;
+ break;
+ }
+ } while (++count);
+
+ return status;
+}
+
+static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned short i;
+ u8 txpktbuf_bndy;
+ u8 maxPage;
+ bool status;
+
+#if LLT_CONFIG == 1
+ maxPage = 255;
+ txpktbuf_bndy = 252;
+#elif LLT_CONFIG == 2
+ maxPage = 127;
+ txpktbuf_bndy = 124;
+#elif LLT_CONFIG == 3
+ maxPage = 255;
+ txpktbuf_bndy = 174;
+#elif LLT_CONFIG == 4
+ maxPage = 255;
+ txpktbuf_bndy = 246;
+#elif LLT_CONFIG == 5
+ maxPage = 255;
+ txpktbuf_bndy = 246;
+#endif
+
+#if LLT_CONFIG == 1
+ rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c);
+ rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c);
+#elif LLT_CONFIG == 2
+ rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010);
+#elif LLT_CONFIG == 3
+ rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484);
+#elif LLT_CONFIG == 4
+ rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c);
+#elif LLT_CONFIG == 5
+ rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000);
+
+ rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29);
+#endif
+
+ rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy));
+ rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
+
+ rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
+ rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
+
+ rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
+ rtl_write_byte(rtlpriv, REG_PBP, 0x11);
+ rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
+
+ for (i = 0; i < (txpktbuf_bndy - 1); i++) {
+ status = _rtl92ce_llt_write(hw, i, i + 1);
+ if (true != status)
+ return status;
+ }
+
+ status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
+ if (true != status)
+ return status;
+
+ for (i = txpktbuf_bndy; i < maxPage; i++) {
+ status = _rtl92ce_llt_write(hw, i, (i + 1));
+ if (true != status)
+ return status;
+ }
+
+ status = _rtl92ce_llt_write(hw, maxPage, txpktbuf_bndy);
+ if (true != status)
+ return status;
+
+ return true;
+}
+
+static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+
+ if (rtlpci->up_first_time)
+ return;
+
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+ rtl92ce_sw_led_on(hw, pLed0);
+ else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
+ rtl92ce_sw_led_on(hw, pLed0);
+ else
+ rtl92ce_sw_led_off(hw, pLed0);
+
+}
+
+static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ unsigned char bytetmp;
+ unsigned short wordtmp;
+ u16 retry;
+
+ rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
+ rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F);
+
+ bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);
+ udelay(2);
+
+ rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
+ udelay(2);
+
+ bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
+ udelay(2);
+
+ retry = 0;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
+ rtl_read_dword(rtlpriv, 0xEC),
+ bytetmp));
+
+ while ((bytetmp & BIT(0)) && retry < 1000) {
+ retry++;
+ udelay(50);
+ bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
+ rtl_read_dword(rtlpriv,
+ 0xEC),
+ bytetmp));
+ udelay(50);
+ }
+
+ rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012);
+
+ rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);
+ udelay(2);
+
+ rtl_write_word(rtlpriv, REG_CR, 0x2ff);
+
+ if (_rtl92ce_llt_table_init(hw) == false)
+ return false;;
+
+ rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
+ rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
+
+ rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff);
+
+ wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
+ wordtmp &= 0xf;
+ wordtmp |= 0xF771;
+ rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
+
+ rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
+ rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
+ rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
+
+ rtl_write_byte(rtlpriv, 0x4d0, 0x0);
+
+ rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
+ ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_MGQ_DESA,
+ (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_VOQ_DESA,
+ (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_VIQ_DESA,
+ (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_BEQ_DESA,
+ (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_BKQ_DESA,
+ (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_HQ_DESA,
+ (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
+ DMA_BIT_MASK(32));
+ rtl_write_dword(rtlpriv, REG_RX_DESA,
+ (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
+ DMA_BIT_MASK(32));
+
+ if (IS_92C_SERIAL(rtlhal->version))
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77);
+ else
+ rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22);
+
+ rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
+
+ bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
+ do {
+ retry++;
+ bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
+ } while ((retry < 200) && (bytetmp & BIT(7)));
+
+ _rtl92ce_gen_refresh_led_state(hw);
+
+ rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
+
+ return true;;
+}
+
+static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
+{
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 reg_bw_opmode;
+ u32 reg_ratr, reg_prsr;
+
+ reg_bw_opmode = BW_OPMODE_20MHZ;
+ reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
+ RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+ reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+
+ rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
+
+ rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+
+ rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
+
+ rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
+
+ rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0);
+
+ rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
+
+ rtl_write_word(rtlpriv, REG_RL, 0x0707);
+
+ rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802);
+
+ rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
+
+ rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
+ rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
+ rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
+ rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
+
+ rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
+
+ rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
+
+ rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
+
+ rtlpci->reg_bcn_ctrl_val = 0x1f;
+ rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
+
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+
+ rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+
+ rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
+ rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
+
+ rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+
+ rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+
+ rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
+
+ rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
+
+ rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
+ rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010);
+
+ rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010);
+
+ rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
+
+ rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
+ rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
+
+}
+
+static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ rtl_write_byte(rtlpriv, 0x34b, 0x93);
+ rtl_write_word(rtlpriv, 0x350, 0x870c);
+ rtl_write_byte(rtlpriv, 0x352, 0x1);
+
+ if (ppsc->b_support_backdoor)
+ rtl_write_byte(rtlpriv, 0x349, 0x1b);
+ else
+ rtl_write_byte(rtlpriv, 0x349, 0x03);
+
+ rtl_write_word(rtlpriv, 0x350, 0x2718);
+ rtl_write_byte(rtlpriv, 0x352, 0x1);
+}
+
+void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 sec_reg_value;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+ rtlpriv->sec.pairwise_enc_algorithm,
+ rtlpriv->sec.group_enc_algorithm));
+
+ if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open "
+ "hw encryption\n"));
+ return;
+ }
+
+ sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
+
+ if (rtlpriv->sec.use_defaultkey) {
+ sec_reg_value |= SCR_TxUseDK;
+ sec_reg_value |= SCR_RxUseDK;
+ }
+
+ sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
+
+ rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("The SECR-value %x\n", sec_reg_value));
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+
+}
+
+int rtl92ce_hw_init(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ static bool iqk_initialized; /* initialized to false */
+ bool rtstatus = true;
+ bool is92c;
+ int err;
+ u8 tmp_u1b;
+
+ rtlpci->being_init_adapter = true;
+ rtlpriv->intf_ops->disable_aspm(hw);
+ rtstatus = _rtl92ce_init_mac(hw);
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+ err = 1;
+ return err;
+ }
+
+ err = rtl92c_download_fw(hw);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Failed to download FW. Init HW "
+ "without FW now..\n"));
+ err = 1;
+ rtlhal->bfw_ready = false;
+ return err;
+ } else {
+ rtlhal->bfw_ready = true;
+ }
+
+ rtlhal->last_hmeboxnum = 0;
+ rtl92c_phy_mac_config(hw);
+ rtl92c_phy_bb_config(hw);
+ rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
+ rtl92c_phy_rf_config(hw);
+ rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
+ RF_CHNLBW, RFREG_OFFSET_MASK);
+ rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
+ RF_CHNLBW, RFREG_OFFSET_MASK);
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
+ rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
+ _rtl92ce_hw_configure(hw);
+ rtl_cam_reset_all_entry(hw);
+ rtl92ce_enable_hw_security_config(hw);
+ ppsc->rfpwr_state = ERFON;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+ _rtl92ce_enable_aspm_back_door(hw);
+ rtlpriv->intf_ops->enable_aspm(hw);
+ if (ppsc->rfpwr_state == ERFON) {
+ rtl92c_phy_set_rfpath_switch(hw, 1);
+ if (iqk_initialized)
+ rtl92c_phy_iq_calibrate(hw, true);
+ else {
+ rtl92c_phy_iq_calibrate(hw, false);
+ iqk_initialized = true;
+ }
+
+ rtl92c_dm_check_txpower_tracking(hw);
+ rtl92c_phy_lc_calibrate(hw);
+ }
+
+ is92c = IS_92C_SERIAL(rtlhal->version);
+ tmp_u1b = efuse_read_1byte(hw, 0x1FA);
+ if (!(tmp_u1b & BIT(0))) {
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n"));
+ }
+
+ if (!(tmp_u1b & BIT(1)) && is92c) {
+ rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n"));
+ }
+
+ if (!(tmp_u1b & BIT(4))) {
+ tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
+ tmp_u1b &= 0x0F;
+ rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
+ udelay(10);
+ rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n"));
+ }
+ rtl92c_dm_init(hw);
+ rtlpci->being_init_adapter = false;
+ return err;
+}
+
+static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ enum version_8192c version = VERSION_UNKNOWN;
+ u32 value32;
+
+ value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
+ if (value32 & TRP_VAUX_EN) {
+ version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C :
+ VERSION_A_CHIP_88C;
+ } else {
+ version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C :
+ VERSION_B_CHIP_88C;
+ }
+
+ switch (version) {
+ case VERSION_B_CHIP_92C:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
+ break;
+ case VERSION_B_CHIP_88C:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Chip Version ID: VERSION_B_CHIP_88C.\n"));
+ break;
+ case VERSION_A_CHIP_92C:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Chip Version ID: VERSION_A_CHIP_92C.\n"));
+ break;
+ case VERSION_A_CHIP_88C:
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Chip Version ID: VERSION_A_CHIP_88C.\n"));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Chip Version ID: Unknown. Bug?\n"));
+ break;
+ }
+
+ switch (version & 0x3) {
+ case CHIP_88C:
+ rtlphy->rf_type = RF_1T1R;
+ break;
+ case CHIP_92C:
+ rtlphy->rf_type = RF_2T2R;
+ break;
+ case CHIP_92C_1T2R:
+ rtlphy->rf_type = RF_1T2R;
+ break;
+ default:
+ rtlphy->rf_type = RF_1T1R;
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("ERROR RF_Type is set!!"));
+ break;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
+ "RF_2T2R" : "RF_1T1R"));
+
+ return version;
+}
+
+static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+ enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+ bt_msr &= 0xfc;
+
+ if (type == NL80211_IFTYPE_UNSPECIFIED ||
+ type == NL80211_IFTYPE_STATION) {
+ _rtl92ce_stop_tx_beacon(hw);
+ _rtl92ce_enable_bcn_sub_func(hw);
+ } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
+ _rtl92ce_resume_tx_beacon(hw);
+ _rtl92ce_disable_bcn_sub_func(hw);
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("Set HW_VAR_MEDIA_STATUS: "
+ "No such media status(%x).\n", type));
+ }
+
+ switch (type) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ bt_msr |= MSR_NOLINK;
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to NO LINK!\n"));
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ bt_msr |= MSR_ADHOC;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to Ad Hoc!\n"));
+ break;
+ case NL80211_IFTYPE_STATION:
+ bt_msr |= MSR_INFRA;
+ ledaction = LED_CTL_LINK;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to STA!\n"));
+ break;
+ case NL80211_IFTYPE_AP:
+ bt_msr |= MSR_AP;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Set Network type to AP!\n"));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Network type %d not support!\n", type));
+ return 1;
+ break;
+
+ }
+
+ rtl_write_byte(rtlpriv, (MSR), bt_msr);
+ rtlpriv->cfg->ops->led_control(hw, ledaction);
+ if ((bt_msr & 0xfc) == MSR_AP)
+ rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
+ else
+ rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
+ return 0;
+}
+
+static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
+ u8 filterout_non_associated_bssid = false;
+
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_STATION:
+ filterout_non_associated_bssid = true;
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ case NL80211_IFTYPE_AP:
+ default:
+ break;
+ }
+
+ if (filterout_non_associated_bssid == true) {
+ reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *) (&reg_rcr));
+ _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
+ } else if (filterout_non_associated_bssid == false) {
+ reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+ _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_RCR, (u8 *) (&reg_rcr));
+ }
+}
+
+int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
+{
+ if (_rtl92ce_set_media_status(hw, type))
+ return -EOPNOTSUPP;
+ _rtl92ce_set_check_bssid(hw, type);
+ return 0;
+}
+
+void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ u32 u4b_ac_param;
+
+ rtl92c_dm_init_edca_turbo(hw);
+
+ u4b_ac_param = (u32) mac->ac[aci].aifs;
+ u4b_ac_param |=
+ ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
+ u4b_ac_param |=
+ ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET;
+ u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET;
+ RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG,
+ ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n",
+ aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min,
+ mac->ac[aci].cw_max, mac->ac[aci].tx_op));
+ switch (aci) {
+ case AC1_BK:
+ rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
+ break;
+ case AC0_BE:
+ rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
+ break;
+ case AC2_VI:
+ rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
+ break;
+ case AC3_VO:
+ rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
+ break;
+ default:
+ RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+ break;
+ }
+}
+
+void rtl92ce_enable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
+ rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
+ rtlpci->irq_enabled = true;
+}
+
+void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
+ rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
+ rtlpci->irq_enabled = false;
+}
+
+static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 u1b_tmp;
+
+ rtlpriv->intf_ops->enable_aspm(hw);
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+ rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
+ if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready)
+ rtl92c_firmware_selfreset(hw);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
+ rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);
+ u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL);
+ rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
+ (u1b_tmp << 8));
+ rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
+ rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
+ rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
+ rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+ rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
+ rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
+}
+
+void rtl92ce_card_disable(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ enum nl80211_iftype opmode;
+
+ mac->link_state = MAC80211_NOLINK;
+ opmode = NL80211_IFTYPE_UNSPECIFIED;
+ _rtl92ce_set_media_status(hw, opmode);
+ if (rtlpci->driver_is_goingto_unload ||
+ ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+ rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ _rtl92ce_poweroff_adapter(hw);
+}
+
+void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
+ u32 *p_inta, u32 *p_intb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
+ rtl_write_dword(rtlpriv, ISR, *p_inta);
+
+ /*
+ * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
+ * rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
+ */
+}
+
+void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 bcn_interval, atim_window;
+
+ bcn_interval = mac->beacon_interval;
+ atim_window = 2; /*FIX MERGE */
+ rtl92ce_disable_interrupt(hw);
+ rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
+ rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+ rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
+ rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
+ rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
+ rtl_write_byte(rtlpriv, 0x606, 0x30);
+ rtl92ce_enable_interrupt(hw);
+}
+
+void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 bcn_interval = mac->beacon_interval;
+
+ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+ ("beacon_interval:%d\n", bcn_interval));
+ rtl92ce_disable_interrupt(hw);
+ rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+ rtl92ce_enable_interrupt(hw);
+}
+
+void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+ ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+ if (add_msr)
+ rtlpci->irq_mask[0] |= add_msr;
+ if (rm_msr)
+ rtlpci->irq_mask[0] &= (~rm_msr);
+ rtl92ce_disable_interrupt(hw);
+ rtl92ce_enable_interrupt(hw);
+}
+
+static u8 _rtl92c_get_chnl_group(u8 chnl)
+{
+ u8 group;
+
+ if (chnl < 3)
+ group = 0;
+ else if (chnl < 9)
+ group = 1;
+ else
+ group = 2;
+ return group;
+}
+
+static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
+ bool autoload_fail,
+ u8 *hwinfo)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 rf_path, index, tempval;
+ u16 i;
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 3; i++) {
+ if (!autoload_fail) {
+ rtlefuse->
+ eeprom_chnlarea_txpwr_cck[rf_path][i] =
+ hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i];
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
+ hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 +
+ i];
+ } else {
+ rtlefuse->
+ eeprom_chnlarea_txpwr_cck[rf_path][i] =
+ EEPROM_DEFAULT_TXPOWERLEVEL;
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
+ EEPROM_DEFAULT_TXPOWERLEVEL;
+ }
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (!autoload_fail)
+ tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
+ else
+ tempval = EEPROM_DEFAULT_HT40_2SDIFF;
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] =
+ (tempval & 0xf);
+ rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] =
+ ((tempval & 0xf0) >> 4);
+ }
+
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
+ i,
+ rtlefuse->
+ eeprom_chnlarea_txpwr_cck[rf_path][i]));
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+ rf_path, i,
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
+ for (rf_path = 0; rf_path < 2; rf_path++)
+ for (i = 0; i < 3; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+ ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+ rf_path, i,
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
+ [i]));
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 14; i++) {
+ index = _rtl92c_get_chnl_group((u8) i);
+
+ rtlefuse->txpwrlevel_cck[rf_path][i] =
+ rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index];
+ rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path][index];
+
+ if ((rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index])
+ > 0) {
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_1s[rf_path]
+ [index] -
+ rtlefuse->
+ eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
+ [index];
+ } else {
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
+ }
+ }
+
+ for (i = 0; i < 14; i++) {
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
+ "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
+ rtlefuse->txpwrlevel_cck[rf_path][i],
+ rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (!autoload_fail) {
+ rtlefuse->eeprom_pwrlimit_ht40[i] =
+ hwinfo[EEPROM_TXPWR_GROUP + i];
+ rtlefuse->eeprom_pwrlimit_ht20[i] =
+ hwinfo[EEPROM_TXPWR_GROUP + 3 + i];
+ } else {
+ rtlefuse->eeprom_pwrlimit_ht40[i] = 0;
+ rtlefuse->eeprom_pwrlimit_ht20[i] = 0;
+ }
+ }
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 14; i++) {
+ index = _rtl92c_get_chnl_group((u8) i);
+
+ if (rf_path == RF90_PATH_A) {
+ rtlefuse->pwrgroup_ht20[rf_path][i] =
+ (rtlefuse->eeprom_pwrlimit_ht20[index]
+ & 0xf);
+ rtlefuse->pwrgroup_ht40[rf_path][i] =
+ (rtlefuse->eeprom_pwrlimit_ht40[index]
+ & 0xf);
+ } else if (rf_path == RF90_PATH_B) {
+ rtlefuse->pwrgroup_ht20[rf_path][i] =
+ ((rtlefuse->eeprom_pwrlimit_ht20[index]
+ & 0xf0) >> 4);
+ rtlefuse->pwrgroup_ht40[rf_path][i] =
+ ((rtlefuse->eeprom_pwrlimit_ht40[index]
+ & 0xf0) >> 4);
+ }
+
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+ rf_path, i,
+ rtlefuse->pwrgroup_ht20[rf_path][i]));
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+ rf_path, i,
+ rtlefuse->pwrgroup_ht40[rf_path][i]));
+ }
+ }
+
+ for (i = 0; i < 14; i++) {
+ index = _rtl92c_get_chnl_group((u8) i);
+
+ if (!autoload_fail)
+ tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index];
+ else
+ tempval = EEPROM_DEFAULT_HT20_DIFF;
+
+ rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
+ rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
+ ((tempval >> 4) & 0xF);
+
+ if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3))
+ rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0;
+
+ if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3))
+ rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0;
+
+ index = _rtl92c_get_chnl_group((u8) i);
+
+ if (!autoload_fail)
+ tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index];
+ else
+ tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
+
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF);
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
+ ((tempval >> 4) & 0xF);
+ }
+
+ rtlefuse->legacy_ht_txpowerdiff =
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
+
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+ for (i = 0; i < 14; i++)
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
+ rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+
+ if (!autoload_fail)
+ rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
+ else
+ rtlefuse->eeprom_regulatory = 0;
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+
+ if (!autoload_fail) {
+ rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
+ rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B];
+ } else {
+ rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
+ rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
+ }
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+ rtlefuse->eeprom_tssi[RF90_PATH_A],
+ rtlefuse->eeprom_tssi[RF90_PATH_B]));
+
+ if (!autoload_fail)
+ tempval = hwinfo[EEPROM_THERMAL_METER];
+ else
+ tempval = EEPROM_DEFAULT_THERMALMETER;
+ rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
+
+ if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
+ rtlefuse->b_apk_thermalmeterignore = true;
+
+ rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
+ RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+ ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+}
+
+static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u16 i, usvalue;
+ u8 hwinfo[HWSET_MAX_SIZE];
+ u16 eeprom_id;
+
+ if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+ rtl_efuse_shadow_map_update(hw);
+
+ memcpy((void *)hwinfo,
+ (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ HWSET_MAX_SIZE);
+ } else if (rtlefuse->epromtype == EEPROM_93C46) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("RTL819X Not boot from eeprom, check it !!"));
+ }
+
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
+ hwinfo, HWSET_MAX_SIZE);
+
+ eeprom_id = *((u16 *)&hwinfo[0]);
+ if (eeprom_id != RTL8190_EEPROM_ID) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+ rtlefuse->autoload_failflag = true;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+ rtlefuse->autoload_failflag = false;
+ }
+
+ if (rtlefuse->autoload_failflag == true)
+ return;
+
+ for (i = 0; i < 6; i += 2) {
+ usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
+ *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+
+ _rtl92ce_read_txpower_info_from_hwpg(hw,
+ rtlefuse->autoload_failflag,
+ hwinfo);
+
+ rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
+ rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
+ rtlefuse->b_txpwr_fromeprom = true;
+ rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+
+ if (rtlhal->oem_id == RT_CID_DEFAULT) {
+ switch (rtlefuse->eeprom_oemid) {
+ case EEPROM_CID_DEFAULT:
+ if (rtlefuse->eeprom_did == 0x8176) {
+ if ((rtlefuse->eeprom_svid == 0x103C &&
+ rtlefuse->eeprom_smid == 0x1629))
+ rtlhal->oem_id = RT_CID_819x_HP;
+ else
+ rtlhal->oem_id = RT_CID_DEFAULT;
+ } else {
+ rtlhal->oem_id = RT_CID_DEFAULT;
+ }
+ break;
+ case EEPROM_CID_TOSHIBA:
+ rtlhal->oem_id = RT_CID_TOSHIBA;
+ break;
+ case EEPROM_CID_QMI:
+ rtlhal->oem_id = RT_CID_819x_QMI;
+ break;
+ case EEPROM_CID_WHQL:
+ default:
+ rtlhal->oem_id = RT_CID_DEFAULT;
+ break;
+
+ }
+ }
+
+}
+
+static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ switch (rtlhal->oem_id) {
+ case RT_CID_819x_HP:
+ pcipriv->ledctl.bled_opendrain = true;
+ break;
+ case RT_CID_819x_Lenovo:
+ case RT_CID_DEFAULT:
+ case RT_CID_TOSHIBA:
+ case RT_CID_CCX:
+ case RT_CID_819x_Acer:
+ case RT_CID_WHQL:
+ default:
+ break;
+ }
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+}
+
+void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 tmp_u1b;
+
+ rtlhal->version = _rtl92ce_read_chip_version(hw);
+ if (get_rf_type(rtlphy) == RF_1T1R)
+ rtlpriv->dm.brfpath_rxenable[0] = true;
+ else
+ rtlpriv->dm.brfpath_rxenable[0] =
+ rtlpriv->dm.brfpath_rxenable[1] = true;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
+ rtlhal->version));
+ tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
+ if (tmp_u1b & BIT(4)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+ rtlefuse->epromtype = EEPROM_93C46;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+ rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+ }
+ if (tmp_u1b & BIT(5)) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+ rtlefuse->autoload_failflag = false;
+ _rtl92ce_read_adapter_info(hw);
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+ }
+
+ _rtl92ce_hal_customized_behavior(hw);
+}
+
+void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ u32 ratr_value = (u32) mac->basic_rates;
+ u8 *p_mcsrate = mac->mcs;
+ u8 ratr_index = 0;
+ u8 b_nmode = mac->ht_enable;
+ u8 mimo_ps = 1;
+ u16 shortgi_rate;
+ u32 tmp_ratr_value;
+ u8 b_curtxbw_40mhz = mac->bw_40;
+ u8 b_curshortgi_40mhz = mac->sgi_40;
+ u8 b_curshortgi_20mhz = mac->sgi_20;
+ enum wireless_mode wirelessmode = mac->mode;
+
+ ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12;
+
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ if (ratr_value & 0x0000000c)
+ ratr_value &= 0x0000000d;
+ else
+ ratr_value &= 0x0000000f;
+ break;
+ case WIRELESS_MODE_G:
+ ratr_value &= 0x00000FF5;
+ break;
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G:
+ b_nmode = 1;
+ if (mimo_ps == 0) {
+ ratr_value &= 0x0007F005;
+ } else {
+ u32 ratr_mask;
+
+ if (get_rf_type(rtlphy) == RF_1T2R ||
+ get_rf_type(rtlphy) == RF_1T1R)
+ ratr_mask = 0x000ff005;
+ else
+ ratr_mask = 0x0f0ff005;
+
+ ratr_value &= ratr_mask;
+ }
+ break;
+ default:
+ if (rtlphy->rf_type == RF_1T2R)
+ ratr_value &= 0x000ff0ff;
+ else
+ ratr_value &= 0x0f0ff0ff;
+
+ break;
+ }
+
+ ratr_value &= 0x0FFFFFFF;
+
+ if (b_nmode && ((b_curtxbw_40mhz &&
+ b_curshortgi_40mhz) || (!b_curtxbw_40mhz &&
+ b_curshortgi_20mhz))) {
+
+ ratr_value |= 0x10000000;
+ tmp_ratr_value = (ratr_value >> 12);
+
+ for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+ if ((1 << shortgi_rate) & tmp_ratr_value)
+ break;
+ }
+
+ shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+ (shortgi_rate << 4) | (shortgi_rate);
+ }
+
+ rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+ ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+}
+
+void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u32 ratr_bitmap = (u32) mac->basic_rates;
+ u8 *p_mcsrate = mac->mcs;
+ u8 ratr_index;
+ u8 b_curtxbw_40mhz = mac->bw_40;
+ u8 b_curshortgi_40mhz = mac->sgi_40;
+ u8 b_curshortgi_20mhz = mac->sgi_20;
+ enum wireless_mode wirelessmode = mac->mode;
+ bool b_shortgi = false;
+ u8 rate_mask[5];
+ u8 macid = 0;
+ u8 mimops = 1;
+
+ ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ ratr_index = RATR_INX_WIRELESS_B;
+ if (ratr_bitmap & 0x0000000c)
+ ratr_bitmap &= 0x0000000d;
+ else
+ ratr_bitmap &= 0x0000000f;
+ break;
+ case WIRELESS_MODE_G:
+ ratr_index = RATR_INX_WIRELESS_GB;
+
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x00000f00;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x00000ff0;
+ else
+ ratr_bitmap &= 0x00000ff5;
+ break;
+ case WIRELESS_MODE_A:
+ ratr_index = RATR_INX_WIRELESS_A;
+ ratr_bitmap &= 0x00000ff0;
+ break;
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G:
+ ratr_index = RATR_INX_WIRELESS_NGB;
+
+ if (mimops == 0) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x00070000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0007f000;
+ else
+ ratr_bitmap &= 0x0007f005;
+ } else {
+ if (rtlphy->rf_type == RF_1T2R ||
+ rtlphy->rf_type == RF_1T1R) {
+ if (b_curtxbw_40mhz) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x000f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x000ff000;
+ else
+ ratr_bitmap &= 0x000ff015;
+ } else {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x000f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x000ff000;
+ else
+ ratr_bitmap &= 0x000ff005;
+ }
+ } else {
+ if (b_curtxbw_40mhz) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x0f0f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0f0ff000;
+ else
+ ratr_bitmap &= 0x0f0ff015;
+ } else {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x0f0f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0f0ff000;
+ else
+ ratr_bitmap &= 0x0f0ff005;
+ }
+ }
+ }
+
+ if ((b_curtxbw_40mhz && b_curshortgi_40mhz) ||
+ (!b_curtxbw_40mhz && b_curshortgi_20mhz)) {
+
+ if (macid == 0)
+ b_shortgi = true;
+ else if (macid == 1)
+ b_shortgi = false;
+ }
+ break;
+ default:
+ ratr_index = RATR_INX_WIRELESS_NGB;
+
+ if (rtlphy->rf_type == RF_1T2R)
+ ratr_bitmap &= 0x000ff0ff;
+ else
+ ratr_bitmap &= 0x0f0ff0ff;
+ break;
+ }
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+ ("ratr_bitmap :%x\n", ratr_bitmap));
+ *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
+ (ratr_index << 28));
+ rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80;
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
+ "ratr_val:%x, %x:%x:%x:%x:%x\n",
+ ratr_index, ratr_bitmap,
+ rate_mask[0], rate_mask[1],
+ rate_mask[2], rate_mask[3],
+ rate_mask[4]));
+ rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+}
+
+void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u16 sifs_timer;
+
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+ (u8 *)&mac->slot_time);
+ if (!mac->ht_enable)
+ sifs_timer = 0x0a0a;
+ else
+ sifs_timer = 0x1010;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
+}
+
+bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
+ u8 u1tmp;
+ bool b_actuallyset = false;
+ unsigned long flag;
+
+ if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
+ return false;
+
+ if (ppsc->b_swrf_processing)
+ return false;
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ if (ppsc->rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ return false;
+ } else {
+ ppsc->rfchange_inprogress = true;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ }
+
+ cur_rfstate = ppsc->rfpwr_state;
+
+ if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+
+ rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
+ REG_MAC_PINMUX_CFG)&~(BIT(3)));
+
+ u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
+ e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
+
+ if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("GPIOChangeRF - HW Radio ON, RF ON\n"));
+
+ e_rfpowerstate_toset = ERFON;
+ ppsc->b_hwradiooff = false;
+ b_actuallyset = true;
+ } else if ((ppsc->b_hwradiooff == false)
+ && (e_rfpowerstate_toset == ERFOFF)) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("GPIOChangeRF - HW Radio OFF, RF OFF\n"));
+
+ e_rfpowerstate_toset = ERFOFF;
+ ppsc->b_hwradiooff = true;
+ b_actuallyset = true;
+ }
+
+ if (b_actuallyset) {
+ if (e_rfpowerstate_toset == ERFON) {
+ if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+ if (e_rfpowerstate_toset == ERFOFF) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+ }
+
+ } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ } else {
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ }
+
+ *valid = 1;
+ return !ppsc->b_hwradiooff;
+
+}
+
+void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
+ u8 *p_macaddr, bool is_group, u8 enc_algo,
+ bool is_wepkey, bool clear_all)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 *macaddr = p_macaddr;
+ u32 entry_id = 0;
+ bool is_pairwise = false;
+
+ static u8 cam_const_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}
+ };
+ static u8 cam_const_broad[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ if (clear_all) {
+ u8 idx = 0;
+ u8 cam_offset = 0;
+ u8 clear_number = 5;
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+
+ for (idx = 0; idx < clear_number; idx++) {
+ rtl_cam_mark_invalid(hw, cam_offset + idx);
+ rtl_cam_empty_entry(hw, cam_offset + idx);
+
+ if (idx < 5) {
+ memset(rtlpriv->sec.key_buf[idx], 0,
+ MAX_KEY_LEN);
+ rtlpriv->sec.key_len[idx] = 0;
+ }
+ }
+
+ } else {
+ switch (enc_algo) {
+ case WEP40_ENCRYPTION:
+ enc_algo = CAM_WEP40;
+ break;
+ case WEP104_ENCRYPTION:
+ enc_algo = CAM_WEP104;
+ break;
+ case TKIP_ENCRYPTION:
+ enc_algo = CAM_TKIP;
+ break;
+ case AESCCMP_ENCRYPTION:
+ enc_algo = CAM_AES;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
+ "not process\n"));
+ enc_algo = CAM_TKIP;
+ break;
+ }
+
+ if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+ macaddr = cam_const_addr[key_index];
+ entry_id = key_index;
+ } else {
+ if (is_group) {
+ macaddr = cam_const_broad;
+ entry_id = key_index;
+ } else {
+ key_index = PAIRWISE_KEYIDX;
+ entry_id = CAM_PAIRWISE_KEY_POSITION;
+ is_pairwise = true;
+ }
+ }
+
+ if (rtlpriv->sec.key_len[key_index] == 0) {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("delete one entry\n"));
+ rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("The insert KEY length is %d\n",
+ rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+ ("The insert KEY is %x %x\n",
+ rtlpriv->sec.key_buf[0][0],
+ rtlpriv->sec.key_buf[0][1]));
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("add one entry\n"));
+ if (is_pairwise) {
+ RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
+ "Pairwiase Key content :",
+ rtlpriv->sec.pairwise_key,
+ rtlpriv->sec.
+ key_len[PAIRWISE_KEYIDX]);
+
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set Pairwiase key\n"));
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index,
+ entry_id, enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.
+ key_buf[key_index]);
+ } else {
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set group key\n"));
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ rtl_cam_add_one_entry(hw,
+ rtlefuse->dev_addr,
+ PAIRWISE_KEYIDX,
+ CAM_PAIRWISE_KEY_POSITION,
+ enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf
+ [entry_id]);
+ }
+
+ rtl_cam_add_one_entry(hw, macaddr, key_index,
+ entry_id, enc_algo,
+ CAM_CONFIG_NO_USEDK,
+ rtlpriv->sec.key_buf[entry_id]);
+ }
+
+ }
+ }
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
new file mode 100644
index 000000000000..305c819c8c78
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_HW_H__
+#define __RTL92CE_HW_H__
+
+void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
+void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
+ u32 *p_inta, u32 *p_intb);
+int rtl92ce_hw_init(struct ieee80211_hw *hw);
+void rtl92ce_card_disable(struct ieee80211_hw *hw);
+void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
+void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
+int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr);
+void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw);
+void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
+void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
+void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
+ u8 *p_macaddr, bool is_group, u8 enc_algo,
+ bool is_wepkey, bool clear_all);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
new file mode 100644
index 000000000000..78a0569208ea
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
@@ -0,0 +1,144 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+#include "led.h"
+
+void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ u8 ledcfg;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+ ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+ ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ rtl_write_byte(rtlpriv,
+ REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
+ break;
+ case LED_PIN_LED1:
+ rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ pled->b_ledon = true;
+}
+
+void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ u8 ledcfg;
+
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+ ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+ ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+
+ switch (pled->ledpin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ ledcfg &= 0xf0;
+ if (pcipriv->ledctl.bled_opendrain == true)
+ rtl_write_byte(rtlpriv, REG_LEDCFG2,
+ (ledcfg | BIT(1) | BIT(5) | BIT(6)));
+ else
+ rtl_write_byte(rtlpriv, REG_LEDCFG2,
+ (ledcfg | BIT(3) | BIT(5) | BIT(6)));
+ break;
+ case LED_PIN_LED1:
+ ledcfg &= 0x0f;
+ rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ pled->b_ledon = false;
+}
+
+void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
+{
+}
+
+void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw)
+{
+}
+
+void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction)
+{
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+ switch (ledaction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ rtl92ce_sw_led_on(hw, pLed0);
+ break;
+ case LED_CTL_POWER_OFF:
+ rtl92ce_sw_led_off(hw, pLed0);
+ break;
+ default:
+ break;
+ }
+}
+
+void rtl92ce_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+ if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+ (ledaction == LED_CTL_TX ||
+ ledaction == LED_CTL_RX ||
+ ledaction == LED_CTL_SITE_SURVEY ||
+ ledaction == LED_CTL_LINK ||
+ ledaction == LED_CTL_NO_LINK ||
+ ledaction == LED_CTL_START_TO_LINK ||
+ ledaction == LED_CTL_POWER_ON)) {
+ return;
+ }
+ RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
+ ledaction));
+ _rtl92ce_sw_led_control(hw, ledaction);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
new file mode 100644
index 000000000000..10da3018f4b7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_LED_H__
+#define __RTL92CE_LED_H__
+
+void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
+void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
+void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
+void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
new file mode 100644
index 000000000000..45044117139a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -0,0 +1,2676 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "table.h"
+
+static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset);
+static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data);
+static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset);
+static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data);
+static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
+static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
+static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype);
+static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+ u8 configtype);
+static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
+static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+ u32 cmdtableidx, u32 cmdtablesz,
+ enum swchnlcmd_id cmdid, u32 para1,
+ u32 para2, u32 msdelay);
+static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+ u8 channel, u8 *stage, u8 *step,
+ u32 *delay);
+static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ long power_indbm);
+static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
+ enum radio_path rfpath);
+static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ u8 txpwridx);
+u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 returnvalue, originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+ "bitmask(%#x)\n", regaddr,
+ bitmask));
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
+ returnvalue = (originalvalue & bitmask) >> bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
+ "Addr[0x%x]=0x%x\n", bitmask,
+ regaddr, originalvalue));
+
+ return returnvalue;
+
+}
+
+void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 originalvalue, bitshift;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+ " data(%#x)\n", regaddr, bitmask,
+ data));
+
+ if (bitmask != MASKDWORD) {
+ originalvalue = rtl_read_dword(rtlpriv, regaddr);
+ bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
+ data = ((originalvalue & (~bitmask)) | (data << bitshift));
+ }
+
+ rtl_write_dword(rtlpriv, regaddr, data);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+ " data(%#x)\n", regaddr, bitmask,
+ data));
+
+}
+
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr, u32 bitmask)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 original_value, readback_value, bitshift;
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ unsigned long flags;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+ "rfpath(%#x), bitmask(%#x)\n",
+ regaddr, rfpath, bitmask));
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ if (rtlphy->rf_mode != RF_OP_BY_FW) {
+ original_value = _rtl92c_phy_rf_serial_read(hw,
+ rfpath, regaddr);
+ } else {
+ original_value = _rtl92c_phy_fw_rf_serial_read(hw,
+ rfpath, regaddr);
+ }
+
+ bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
+ readback_value = (original_value & bitmask) >> bitshift;
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ ("regaddr(%#x), rfpath(%#x), "
+ "bitmask(%#x), original_value(%#x)\n",
+ regaddr, rfpath, bitmask, original_value));
+
+ return readback_value;
+}
+
+void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 original_value, bitshift;
+ unsigned long flags;
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+ ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+ regaddr, bitmask, data, rfpath));
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+ if (rtlphy->rf_mode != RF_OP_BY_FW) {
+ if (bitmask != RFREG_OFFSET_MASK) {
+ original_value = _rtl92c_phy_rf_serial_read(hw,
+ rfpath,
+ regaddr);
+ bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
+ data =
+ ((original_value & (~bitmask)) |
+ (data << bitshift));
+ }
+
+ _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
+ } else {
+ if (bitmask != RFREG_OFFSET_MASK) {
+ original_value = _rtl92c_phy_fw_rf_serial_read(hw,
+ rfpath,
+ regaddr);
+ bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
+ data =
+ ((original_value & (~bitmask)) |
+ (data << bitshift));
+ }
+ _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+ "bitmask(%#x), data(%#x), "
+ "rfpath(%#x)\n", regaddr,
+ bitmask, data, rfpath));
+}
+
+static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset)
+{
+ RT_ASSERT(false, ("deprecated!\n"));
+ return 0;
+}
+
+static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data)
+{
+ RT_ASSERT(false, ("deprecated!\n"));
+}
+
+static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+ u32 newoffset;
+ u32 tmplong, tmplong2;
+ u8 rfpi_enable = 0;
+ u32 retvalue;
+
+ offset &= 0x3f;
+ newoffset = offset;
+ if (RT_CANNOT_IO(hw)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
+ return 0xFFFFFFFF;
+ }
+ tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
+ if (rfpath == RF90_PATH_A)
+ tmplong2 = tmplong;
+ else
+ tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
+ tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
+ (newoffset << 23) | BLSSIREADEDGE;
+ rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+ tmplong & (~BLSSIREADEDGE));
+ mdelay(1);
+ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
+ mdelay(1);
+ rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+ tmplong | BLSSIREADEDGE);
+ mdelay(1);
+ if (rfpath == RF90_PATH_A)
+ rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
+ BIT(8));
+ else if (rfpath == RF90_PATH_B)
+ rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
+ BIT(8));
+ if (rfpi_enable)
+ retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
+ BLSSIREADBACKDATA);
+ else
+ retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+ BLSSIREADBACKDATA);
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
+ rfpath, pphyreg->rflssi_readback,
+ retvalue));
+ return retvalue;
+}
+
+static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 offset,
+ u32 data)
+{
+ u32 data_and_addr;
+ u32 newoffset;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+
+ if (RT_CANNOT_IO(hw)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
+ return;
+ }
+ offset &= 0x3f;
+ newoffset = offset;
+ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
+ rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
+ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
+ rfpath, pphyreg->rf3wire_offset,
+ data_and_addr));
+}
+
+static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
+{
+ u32 i;
+
+ for (i = 0; i <= 31; i++) {
+ if (((bitmask >> i) & 0x1) == 1)
+ break;
+ }
+ return i;
+}
+
+static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
+{
+ rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
+ rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
+ rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
+ rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
+ rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
+ rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
+ rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
+ rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
+ rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
+ rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
+}
+
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool is92c = IS_92C_SERIAL(rtlhal->version);
+ bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
+
+ if (is92c)
+ rtl_write_byte(rtlpriv, 0x14, 0x71);
+ return rtstatus;
+}
+
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
+{
+ bool rtstatus = true;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 regval;
+ u32 regvaldw;
+ u8 b_reg_hwparafile = 1;
+
+ _rtl92c_phy_init_bb_rf_register_definition(hw);
+ regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+ rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
+ regval | BIT(13) | BIT(0) | BIT(1));
+ rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
+ rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
+ rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
+ FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
+ FEN_BB_GLB_RSTn | FEN_BBRSTB);
+ rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
+ regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
+ rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
+ if (b_reg_hwparafile == 1)
+ rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
+ return rtstatus;
+}
+
+bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
+{
+ return rtl92c_phy_rf6052_config(hw);
+}
+
+static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ bool rtstatus;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+ rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
+ BASEBAND_CONFIG_PHY_REG);
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+ return false;
+ }
+ if (rtlphy->rf_type == RF_1T2R) {
+ _rtl92c_phy_bb_config_1t(hw);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+ }
+ if (rtlefuse->autoload_failflag == false) {
+ rtlphy->pwrgroup_cnt = 0;
+ rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw,
+ BASEBAND_CONFIG_PHY_REG);
+ }
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+ return false;
+ }
+ rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
+ BASEBAND_CONFIG_AGC_TAB);
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+ return false;
+ }
+ rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER2,
+ 0x200));
+ return true;
+}
+
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 i;
+ u32 arraylength;
+ u32 *ptrarray;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+ arraylength = MAC_2T_ARRAYLENGTH;
+ ptrarray = RTL8192CEMAC_2T_ARRAY;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Img:RTL8192CEMAC_2T_ARRAY\n"));
+ for (i = 0; i < arraylength; i = i + 2)
+ rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
+ return true;
+}
+
+void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw)
+{
+}
+
+static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype)
+{
+ int i;
+ u32 *phy_regarray_table;
+ u32 *agctab_array_table;
+ u16 phy_reg_arraylen, agctab_arraylen;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (IS_92C_SERIAL(rtlhal->version)) {
+ agctab_arraylen = AGCTAB_2TARRAYLENGTH;
+ agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
+ phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
+ phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
+ } else {
+ agctab_arraylen = AGCTAB_1TARRAYLENGTH;
+ agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
+ phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
+ phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
+ }
+ if (configtype == BASEBAND_CONFIG_PHY_REG) {
+ for (i = 0; i < phy_reg_arraylen; i = i + 2) {
+ if (phy_regarray_table[i] == 0xfe)
+ mdelay(50);
+ else if (phy_regarray_table[i] == 0xfd)
+ mdelay(5);
+ else if (phy_regarray_table[i] == 0xfc)
+ mdelay(1);
+ else if (phy_regarray_table[i] == 0xfb)
+ udelay(50);
+ else if (phy_regarray_table[i] == 0xfa)
+ udelay(5);
+ else if (phy_regarray_table[i] == 0xf9)
+ udelay(1);
+ rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
+ phy_regarray_table[i + 1]);
+ udelay(1);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("The phy_regarray_table[0] is %x"
+ " Rtl819XPHY_REGArray[1] is %x\n",
+ phy_regarray_table[i],
+ phy_regarray_table[i + 1]));
+ }
+ rtl92c_phy_config_bb_external_pa(hw);
+ } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+ for (i = 0; i < agctab_arraylen; i = i + 2) {
+ rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
+ agctab_array_table[i + 1]);
+ udelay(1);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("The agctab_array_table[0] is "
+ "%x Rtl819XPHY_REGArray[1] is %x\n",
+ agctab_array_table[i],
+ agctab_array_table[i + 1]));
+ }
+ }
+ return true;
+}
+
+static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask,
+ u32 data)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ if (regaddr == RTXAGC_A_RATE18_06) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][0]));
+ }
+ if (regaddr == RTXAGC_A_RATE54_24) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][1]));
+ }
+ if (regaddr == RTXAGC_A_CCK1_MCS32) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][6]));
+ }
+ if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][7]));
+ }
+ if (regaddr == RTXAGC_A_MCS03_MCS00) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][2]));
+ }
+ if (regaddr == RTXAGC_A_MCS07_MCS04) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][3]));
+ }
+ if (regaddr == RTXAGC_A_MCS11_MCS08) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][4]));
+ }
+ if (regaddr == RTXAGC_A_MCS15_MCS12) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][5]));
+ }
+ if (regaddr == RTXAGC_B_RATE18_06) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
+ data;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][8]));
+ }
+ if (regaddr == RTXAGC_B_RATE54_24) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][9]));
+ }
+
+ if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][14]));
+ }
+
+ if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][15]));
+ }
+
+ if (regaddr == RTXAGC_B_MCS03_MCS00) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][10]));
+ }
+
+ if (regaddr == RTXAGC_B_MCS07_MCS04) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][11]));
+ }
+
+ if (regaddr == RTXAGC_B_MCS11_MCS08) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][12]));
+ }
+
+ if (regaddr == RTXAGC_B_MCS15_MCS12) {
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
+ data;
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
+ rtlphy->pwrgroup_cnt,
+ rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
+ pwrgroup_cnt][13]));
+
+ rtlphy->pwrgroup_cnt++;
+ }
+}
+
+static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+ u8 configtype)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int i;
+ u32 *phy_regarray_table_pg;
+ u16 phy_regarray_pg_len;
+
+ phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
+ phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
+
+ if (configtype == BASEBAND_CONFIG_PHY_REG) {
+ for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
+ if (phy_regarray_table_pg[i] == 0xfe)
+ mdelay(50);
+ else if (phy_regarray_table_pg[i] == 0xfd)
+ mdelay(5);
+ else if (phy_regarray_table_pg[i] == 0xfc)
+ mdelay(1);
+ else if (phy_regarray_table_pg[i] == 0xfb)
+ udelay(50);
+ else if (phy_regarray_table_pg[i] == 0xfa)
+ udelay(5);
+ else if (phy_regarray_table_pg[i] == 0xf9)
+ udelay(1);
+
+ _rtl92c_store_pwrIndex_diffrate_offset(hw,
+ phy_regarray_table_pg[i],
+ phy_regarray_table_pg[i + 1],
+ phy_regarray_table_pg[i + 2]);
+ }
+ } else {
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ ("configtype != BaseBand_Config_PHY_REG\n"));
+ }
+ return true;
+}
+
+static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
+ enum radio_path rfpath)
+{
+ return true;
+}
+
+bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+ enum radio_path rfpath)
+{
+
+ int i;
+ bool rtstatus = true;
+ u32 *radioa_array_table;
+ u32 *radiob_array_table;
+ u16 radioa_arraylen, radiob_arraylen;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (IS_92C_SERIAL(rtlhal->version)) {
+ radioa_arraylen = RADIOA_2TARRAYLENGTH;
+ radioa_array_table = RTL8192CERADIOA_2TARRAY;
+ radiob_arraylen = RADIOB_2TARRAYLENGTH;
+ radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
+ } else {
+ radioa_arraylen = RADIOA_1TARRAYLENGTH;
+ radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
+ radiob_arraylen = RADIOB_1TARRAYLENGTH;
+ radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
+ }
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+ rtstatus = true;
+ switch (rfpath) {
+ case RF90_PATH_A:
+ for (i = 0; i < radioa_arraylen; i = i + 2) {
+ if (radioa_array_table[i] == 0xfe)
+ mdelay(50);
+ else if (radioa_array_table[i] == 0xfd)
+ mdelay(5);
+ else if (radioa_array_table[i] == 0xfc)
+ mdelay(1);
+ else if (radioa_array_table[i] == 0xfb)
+ udelay(50);
+ else if (radioa_array_table[i] == 0xfa)
+ udelay(5);
+ else if (radioa_array_table[i] == 0xf9)
+ udelay(1);
+ else {
+ rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
+ RFREG_OFFSET_MASK,
+ radioa_array_table[i + 1]);
+ udelay(1);
+ }
+ }
+ _rtl92c_phy_config_rf_external_pa(hw, rfpath);
+ break;
+ case RF90_PATH_B:
+ for (i = 0; i < radiob_arraylen; i = i + 2) {
+ if (radiob_array_table[i] == 0xfe) {
+ mdelay(50);
+ } else if (radiob_array_table[i] == 0xfd)
+ mdelay(5);
+ else if (radiob_array_table[i] == 0xfc)
+ mdelay(1);
+ else if (radiob_array_table[i] == 0xfb)
+ udelay(50);
+ else if (radiob_array_table[i] == 0xfa)
+ udelay(5);
+ else if (radiob_array_table[i] == 0xf9)
+ udelay(1);
+ else {
+ rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
+ RFREG_OFFSET_MASK,
+ radiob_array_table[i + 1]);
+ udelay(1);
+ }
+ }
+ break;
+ case RF90_PATH_C:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ case RF90_PATH_D:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ return true;
+}
+
+void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ rtlphy->default_initialgain[0] =
+ (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[1] =
+ (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[2] =
+ (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
+ rtlphy->default_initialgain[3] =
+ (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Default initial gain (c50=0x%x, "
+ "c58=0x%x, c60=0x%x, c68=0x%x\n",
+ rtlphy->default_initialgain[0],
+ rtlphy->default_initialgain[1],
+ rtlphy->default_initialgain[2],
+ rtlphy->default_initialgain[3]));
+
+ rtlphy->framesync = (u8) rtl_get_bbreg(hw,
+ ROFDM0_RXDETECTOR3, MASKBYTE0);
+ rtlphy->framesync_c34 = rtl_get_bbreg(hw,
+ ROFDM0_RXDETECTOR2, MASKDWORD);
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Default framesync (0x%x) = 0x%x\n",
+ ROFDM0_RXDETECTOR3, rtlphy->framesync));
+}
+
+static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+ rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
+ RFPGA0_XA_LSSIPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
+ RFPGA0_XB_LSSIPARAMETER;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
+ rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
+ rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
+ rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
+ RFPGA0_XAB_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
+ RFPGA0_XAB_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
+ RFPGA0_XCD_SWITCHCONTROL;
+ rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
+ RFPGA0_XCD_SWITCHCONTROL;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
+ rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
+ rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
+ ROFDM0_XARXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
+ ROFDM0_XBRXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
+ ROFDM0_XCRXIQIMBANLANCE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
+ ROFDM0_XDRXIQIMBALANCE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
+ rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
+ rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
+ rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
+ ROFDM0_XATXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
+ ROFDM0_XBTXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
+ ROFDM0_XCTXIQIMBALANCE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
+ ROFDM0_XDTXIQIMBALANCE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
+ rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
+ rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
+ rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
+ RFPGA0_XA_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
+ RFPGA0_XB_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
+ RFPGA0_XC_LSSIREADBACK;
+ rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
+ RFPGA0_XD_LSSIREADBACK;
+
+ rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
+ TRANSCEIVEA_HSPI_READBACK;
+ rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
+ TRANSCEIVEB_HSPI_READBACK;
+
+}
+
+void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 txpwr_level;
+ long txpwr_dbm;
+
+ txpwr_level = rtlphy->cur_cck_txpwridx;
+ txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw,
+ WIRELESS_MODE_B, txpwr_level);
+ txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
+ rtlefuse->legacy_ht_txpowerdiff;
+ if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
+ WIRELESS_MODE_G,
+ txpwr_level) > txpwr_dbm)
+ txpwr_dbm =
+ _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
+ txpwr_level);
+ txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
+ if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
+ WIRELESS_MODE_N_24G,
+ txpwr_level) > txpwr_dbm)
+ txpwr_dbm =
+ _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
+ txpwr_level);
+ *powerlevel = txpwr_dbm;
+}
+
+static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
+ u8 *cckpowerlevel, u8 *ofdmpowerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 index = (channel - 1);
+
+ cckpowerlevel[RF90_PATH_A] =
+ rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
+ cckpowerlevel[RF90_PATH_B] =
+ rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
+ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
+ ofdmpowerlevel[RF90_PATH_A] =
+ rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
+ ofdmpowerlevel[RF90_PATH_B] =
+ rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
+ } else if (get_rf_type(rtlphy) == RF_2T2R) {
+ ofdmpowerlevel[RF90_PATH_A] =
+ rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
+ ofdmpowerlevel[RF90_PATH_B] =
+ rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
+ }
+}
+
+static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
+ u8 channel, u8 *cckpowerlevel,
+ u8 *ofdmpowerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
+ rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+}
+
+void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 cckpowerlevel[2], ofdmpowerlevel[2];
+
+ if (rtlefuse->b_txpwr_fromeprom == false)
+ return;
+ _rtl92c_get_txpower_index(hw, channel,
+ &cckpowerlevel[0], &ofdmpowerlevel[0]);
+ _rtl92c_ccxpower_index_check(hw,
+ channel, &cckpowerlevel[0],
+ &ofdmpowerlevel[0]);
+ rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
+ rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
+}
+
+bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 idx;
+ u8 rf_path;
+
+ u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
+ WIRELESS_MODE_B,
+ power_indbm);
+ u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
+ WIRELESS_MODE_N_24G,
+ power_indbm);
+ if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
+ ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
+ else
+ ofdmtxpwridx = 0;
+ RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
+ ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
+ power_indbm, ccktxpwridx, ofdmtxpwridx));
+ for (idx = 0; idx < 14; idx++) {
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
+ rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
+ ofdmtxpwridx;
+ rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
+ ofdmtxpwridx;
+ }
+ }
+ rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+ return true;
+}
+
+void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval)
+{
+}
+
+static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ long power_indbm)
+{
+ u8 txpwridx;
+ long offset;
+
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ offset = -7;
+ break;
+ case WIRELESS_MODE_G:
+ case WIRELESS_MODE_N_24G:
+ offset = -8;
+ break;
+ default:
+ offset = -8;
+ break;
+ }
+
+ if ((power_indbm - offset) > 0)
+ txpwridx = (u8) ((power_indbm - offset) * 2);
+ else
+ txpwridx = 0;
+
+ if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
+ txpwridx = MAX_TXPWR_IDX_NMODE_92S;
+
+ return txpwridx;
+}
+
+static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+ enum wireless_mode wirelessmode,
+ u8 txpwridx)
+{
+ long offset;
+ long pwrout_dbm;
+
+ switch (wirelessmode) {
+ case WIRELESS_MODE_B:
+ offset = -7;
+ break;
+ case WIRELESS_MODE_G:
+ case WIRELESS_MODE_N_24G:
+ offset = -8;
+ break;
+ default:
+ offset = -8;
+ break;
+ }
+ pwrout_dbm = txpwridx / 2 + offset;
+ return pwrout_dbm;
+}
+
+void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ enum io_type iotype;
+
+ if (!is_hal_stop(rtlhal)) {
+ switch (operation) {
+ case SCAN_OPT_BACKUP:
+ iotype = IO_CMD_PAUSE_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+
+ break;
+ case SCAN_OPT_RESTORE:
+ iotype = IO_CMD_RESUME_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Unknown Scan Backup operation.\n"));
+ break;
+ }
+ }
+}
+
+void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 reg_bw_opmode;
+ u8 reg_prsr_rsc;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+ ("Switch to %s bandwidth\n",
+ rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+ "20MHz" : "40MHz"))
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
+ reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
+
+ switch (rtlphy->current_chan_bw) {
+ case HT_CHANNEL_WIDTH_20:
+ reg_bw_opmode |= BW_OPMODE_20MHZ;
+ rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+ break;
+
+ case HT_CHANNEL_WIDTH_20_40:
+ reg_bw_opmode &= ~BW_OPMODE_20MHZ;
+ rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+
+ reg_prsr_rsc =
+ (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
+ rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
+ break;
+
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+ break;
+ }
+
+ switch (rtlphy->current_chan_bw) {
+ case HT_CHANNEL_WIDTH_20:
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
+ rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
+ rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
+ rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
+ rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
+ (mac->cur_40_prime_sc >> 1));
+ rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
+ rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
+ rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
+ (mac->cur_40_prime_sc ==
+ HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+ break;
+ }
+ rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+ rtlphy->set_bwmode_inprogress = false;
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+}
+
+void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u8 tmp_bw = rtlphy->current_chan_bw;
+
+ if (rtlphy->set_bwmode_inprogress)
+ return;
+ rtlphy->set_bwmode_inprogress = true;
+ if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
+ rtl92c_phy_set_bw_mode_callback(hw);
+ else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("FALSE driver sleep or unload\n"));
+ rtlphy->set_bwmode_inprogress = false;
+ rtlphy->current_chan_bw = tmp_bw;
+ }
+}
+
+void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 delay;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+ ("switch to channel%d\n", rtlphy->current_channel));
+ if (is_hal_stop(rtlhal))
+ return;
+ do {
+ if (!rtlphy->sw_chnl_inprogress)
+ break;
+ if (!_rtl92c_phy_sw_chnl_step_by_step
+ (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
+ &rtlphy->sw_chnl_step, &delay)) {
+ if (delay > 0)
+ mdelay(delay);
+ else
+ continue;
+ } else
+ rtlphy->sw_chnl_inprogress = false;
+ break;
+ } while (true);
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+}
+
+u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (rtlphy->sw_chnl_inprogress)
+ return 0;
+ if (rtlphy->set_bwmode_inprogress)
+ return 0;
+ RT_ASSERT((rtlphy->current_channel <= 14),
+ ("WIRELESS_MODE_G but channel>14"));
+ rtlphy->sw_chnl_inprogress = true;
+ rtlphy->sw_chnl_stage = 0;
+ rtlphy->sw_chnl_step = 0;
+ if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
+ rtl92c_phy_sw_chnl_callback(hw);
+ RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
+ ("sw_chnl_inprogress false schdule workitem\n"));
+ rtlphy->sw_chnl_inprogress = false;
+ } else {
+ RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
+ ("sw_chnl_inprogress false driver sleep or"
+ " unload\n"));
+ rtlphy->sw_chnl_inprogress = false;
+ }
+ return 1;
+}
+
+static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+ u8 channel, u8 *stage, u8 *step,
+ u32 *delay)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
+ u32 precommoncmdcnt;
+ struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
+ u32 postcommoncmdcnt;
+ struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
+ u32 rfdependcmdcnt;
+ struct swchnlcmd *currentcmd = NULL;
+ u8 rfpath;
+ u8 num_total_rfpath = rtlphy->num_total_rfpath;
+
+ precommoncmdcnt = 0;
+ _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+ MAX_PRECMD_CNT,
+ CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
+ _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+ MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
+
+ postcommoncmdcnt = 0;
+
+ _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
+ MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
+
+ rfdependcmdcnt = 0;
+
+ RT_ASSERT((channel >= 1 && channel <= 14),
+ ("illegal channel for Zebra: %d\n", channel));
+
+ _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+ MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
+ RF_CHNLBW, channel, 10);
+
+ _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+ MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
+ 0);
+
+ do {
+ switch (*stage) {
+ case 0:
+ currentcmd = &precommoncmd[*step];
+ break;
+ case 1:
+ currentcmd = &rfdependcmd[*step];
+ break;
+ case 2:
+ currentcmd = &postcommoncmd[*step];
+ break;
+ }
+
+ if (currentcmd->cmdid == CMDID_END) {
+ if ((*stage) == 2) {
+ return true;
+ } else {
+ (*stage)++;
+ (*step) = 0;
+ continue;
+ }
+ }
+
+ switch (currentcmd->cmdid) {
+ case CMDID_SET_TXPOWEROWER_LEVEL:
+ rtl92c_phy_set_txpower_level(hw, channel);
+ break;
+ case CMDID_WRITEPORT_ULONG:
+ rtl_write_dword(rtlpriv, currentcmd->para1,
+ currentcmd->para2);
+ break;
+ case CMDID_WRITEPORT_USHORT:
+ rtl_write_word(rtlpriv, currentcmd->para1,
+ (u16) currentcmd->para2);
+ break;
+ case CMDID_WRITEPORT_UCHAR:
+ rtl_write_byte(rtlpriv, currentcmd->para1,
+ (u8) currentcmd->para2);
+ break;
+ case CMDID_RF_WRITEREG:
+ for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
+ rtlphy->rfreg_chnlval[rfpath] =
+ ((rtlphy->rfreg_chnlval[rfpath] &
+ 0xfffffc00) | currentcmd->para2);
+
+ rtl_set_rfreg(hw, (enum radio_path)rfpath,
+ currentcmd->para1,
+ RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[rfpath]);
+ }
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+
+ break;
+ } while (true);
+
+ (*delay) = currentcmd->msdelay;
+ (*step)++;
+ return false;
+}
+
+static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+ u32 cmdtableidx, u32 cmdtablesz,
+ enum swchnlcmd_id cmdid,
+ u32 para1, u32 para2, u32 msdelay)
+{
+ struct swchnlcmd *pcmd;
+
+ if (cmdtable == NULL) {
+ RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+ return false;
+ }
+
+ if (cmdtableidx >= cmdtablesz)
+ return false;
+
+ pcmd = cmdtable + cmdtableidx;
+ pcmd->cmdid = cmdid;
+ pcmd->para1 = para1;
+ pcmd->para2 = para2;
+ pcmd->msdelay = msdelay;
+ return true;
+}
+
+bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
+{
+ return true;
+}
+
+static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
+{
+ u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
+ u8 result = 0x00;
+
+ rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
+ rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
+ rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
+ rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
+ config_pathb ? 0x28160202 : 0x28160502);
+
+ if (config_pathb) {
+ rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
+ rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
+ rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
+ rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
+ }
+
+ rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
+ rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
+ rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
+
+ mdelay(IQK_DELAY_TIME);
+
+ reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
+ reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
+ reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
+ reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
+
+ if (!(reg_eac & BIT(28)) &&
+ (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
+ (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
+ result |= 0x01;
+ else
+ return result;
+
+ if (!(reg_eac & BIT(27)) &&
+ (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
+ (((reg_eac & 0x03FF0000) >> 16) != 0x36))
+ result |= 0x02;
+ return result;
+}
+
+static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
+{
+ u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
+ u8 result = 0x00;
+
+ rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
+ rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
+ mdelay(IQK_DELAY_TIME);
+ reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
+ reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
+ reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
+ reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
+ reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
+ if (!(reg_eac & BIT(31)) &&
+ (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
+ (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
+ result |= 0x01;
+ else
+ return result;
+
+ if (!(reg_eac & BIT(30)) &&
+ (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
+ (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
+ result |= 0x02;
+ return result;
+}
+
+static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
+ bool b_iqk_ok, long result[][8],
+ u8 final_candidate, bool btxonly)
+{
+ u32 oldval_0, x, tx0_a, reg;
+ long y, tx0_c;
+
+ if (final_candidate == 0xFF)
+ return;
+ else if (b_iqk_ok) {
+ oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
+ MASKDWORD) >> 22) & 0x3FF;
+ x = result[final_candidate][0];
+ if ((x & 0x00000200) != 0)
+ x = x | 0xFFFFFC00;
+ tx0_a = (x * oldval_0) >> 8;
+ rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
+ ((x * oldval_0 >> 7) & 0x1));
+ y = result[final_candidate][1];
+ if ((y & 0x00000200) != 0)
+ y = y | 0xFFFFFC00;
+ tx0_c = (y * oldval_0) >> 8;
+ rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
+ ((tx0_c & 0x3C0) >> 6));
+ rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
+ (tx0_c & 0x3F));
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
+ ((y * oldval_0 >> 7) & 0x1));
+ if (btxonly)
+ return;
+ reg = result[final_candidate][2];
+ rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
+ reg = result[final_candidate][3] & 0x3F;
+ rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
+ reg = (result[final_candidate][3] >> 6) & 0xF;
+ rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
+ }
+}
+
+static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
+ bool b_iqk_ok, long result[][8],
+ u8 final_candidate, bool btxonly)
+{
+ u32 oldval_1, x, tx1_a, reg;
+ long y, tx1_c;
+
+ if (final_candidate == 0xFF)
+ return;
+ else if (b_iqk_ok) {
+ oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
+ MASKDWORD) >> 22) & 0x3FF;
+ x = result[final_candidate][4];
+ if ((x & 0x00000200) != 0)
+ x = x | 0xFFFFFC00;
+ tx1_a = (x * oldval_1) >> 8;
+ rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
+ ((x * oldval_1 >> 7) & 0x1));
+ y = result[final_candidate][5];
+ if ((y & 0x00000200) != 0)
+ y = y | 0xFFFFFC00;
+ tx1_c = (y * oldval_1) >> 8;
+ rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
+ ((tx1_c & 0x3C0) >> 6));
+ rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
+ (tx1_c & 0x3F));
+ rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
+ ((y * oldval_1 >> 7) & 0x1));
+ if (btxonly)
+ return;
+ reg = result[final_candidate][6];
+ rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
+ reg = result[final_candidate][7] & 0x3F;
+ rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
+ reg = (result[final_candidate][7] >> 6) & 0xF;
+ rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
+ }
+}
+
+static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
+ u32 *addareg, u32 *addabackup,
+ u32 registernum)
+{
+ u32 i;
+
+ for (i = 0; i < registernum; i++)
+ addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
+}
+
+static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
+ u32 *macreg, u32 *macbackup)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 i;
+
+ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+ macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
+ macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
+}
+
+static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
+ u32 *addareg, u32 *addabackup,
+ u32 regiesternum)
+{
+ u32 i;
+
+ for (i = 0; i < regiesternum; i++)
+ rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
+}
+
+static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
+ u32 *macreg, u32 *macbackup)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 i;
+
+ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+ rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
+ rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
+}
+
+static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
+ u32 *addareg, bool is_patha_on, bool is2t)
+{
+ u32 pathOn;
+ u32 i;
+
+ pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
+ if (false == is2t) {
+ pathOn = 0x0bdb25a0;
+ rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
+ } else {
+ rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
+ }
+
+ for (i = 1; i < IQK_ADDA_REG_NUM; i++)
+ rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
+}
+
+static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
+ u32 *macreg, u32 *macbackup)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 i;
+
+ rtl_write_byte(rtlpriv, macreg[0], 0x3F);
+
+ for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
+ rtl_write_byte(rtlpriv, macreg[i],
+ (u8) (macbackup[i] & (~BIT(3))));
+ rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
+}
+
+static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
+{
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
+ rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
+}
+
+static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
+{
+ u32 mode;
+
+ mode = pi_mode ? 0x01000100 : 0x01000000;
+ rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
+ rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
+}
+
+static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
+ long result[][8], u8 c1, u8 c2)
+{
+ u32 i, j, diff, simularity_bitmap, bound;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ u8 final_candidate[2] = { 0xFF, 0xFF };
+ bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
+
+ if (is2t)
+ bound = 8;
+ else
+ bound = 4;
+
+ simularity_bitmap = 0;
+
+ for (i = 0; i < bound; i++) {
+ diff = (result[c1][i] > result[c2][i]) ?
+ (result[c1][i] - result[c2][i]) :
+ (result[c2][i] - result[c1][i]);
+
+ if (diff > MAX_TOLERANCE) {
+ if ((i == 2 || i == 6) && !simularity_bitmap) {
+ if (result[c1][i] + result[c1][i + 1] == 0)
+ final_candidate[(i / 4)] = c2;
+ else if (result[c2][i] + result[c2][i + 1] == 0)
+ final_candidate[(i / 4)] = c1;
+ else
+ simularity_bitmap = simularity_bitmap |
+ (1 << i);
+ } else
+ simularity_bitmap =
+ simularity_bitmap | (1 << i);
+ }
+ }
+
+ if (simularity_bitmap == 0) {
+ for (i = 0; i < (bound / 4); i++) {
+ if (final_candidate[i] != 0xFF) {
+ for (j = i * 4; j < (i + 1) * 4 - 2; j++)
+ result[3][j] =
+ result[final_candidate[i]][j];
+ bresult = false;
+ }
+ }
+ return bresult;
+ } else if (!(simularity_bitmap & 0x0F)) {
+ for (i = 0; i < 4; i++)
+ result[3][i] = result[c1][i];
+ return false;
+ } else if (!(simularity_bitmap & 0xF0) && is2t) {
+ for (i = 4; i < 8; i++)
+ result[3][i] = result[c1][i];
+ return false;
+ } else {
+ return false;
+ }
+
+}
+
+static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
+ long result[][8], u8 t, bool is2t)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 i;
+ u8 patha_ok, pathb_ok;
+ u32 adda_reg[IQK_ADDA_REG_NUM] = {
+ 0x85c, 0xe6c, 0xe70, 0xe74,
+ 0xe78, 0xe7c, 0xe80, 0xe84,
+ 0xe88, 0xe8c, 0xed0, 0xed4,
+ 0xed8, 0xedc, 0xee0, 0xeec
+ };
+
+ u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
+ 0x522, 0x550, 0x551, 0x040
+ };
+
+ const u32 retrycount = 2;
+
+ u32 bbvalue;
+
+ if (t == 0) {
+ bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
+
+ _rtl92c_phy_save_adda_registers(hw, adda_reg,
+ rtlphy->adda_backup, 16);
+ _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
+ rtlphy->iqk_mac_backup);
+ }
+ _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
+ if (t == 0) {
+ rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER1,
+ BIT(8));
+ }
+ if (!rtlphy->b_rfpi_enable)
+ _rtl92c_phy_pi_mode_switch(hw, true);
+ if (t == 0) {
+ rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
+ rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
+ rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
+ }
+ rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
+ rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
+ rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
+ if (is2t) {
+ rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
+ rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
+ }
+ _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
+ rtlphy->iqk_mac_backup);
+ rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
+ if (is2t)
+ rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
+ rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
+ rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
+ for (i = 0; i < retrycount; i++) {
+ patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
+ if (patha_ok == 0x03) {
+ result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ break;
+ } else if (i == (retrycount - 1) && patha_ok == 0x01)
+ result[t][0] = (rtl_get_bbreg(hw, 0xe94,
+ MASKDWORD) & 0x3FF0000) >>
+ 16;
+ result[t][1] =
+ (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
+
+ }
+
+ if (is2t) {
+ _rtl92c_phy_path_a_standby(hw);
+ _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
+ for (i = 0; i < retrycount; i++) {
+ pathb_ok = _rtl92c_phy_path_b_iqk(hw);
+ if (pathb_ok == 0x03) {
+ result[t][4] = (rtl_get_bbreg(hw,
+ 0xeb4,
+ MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][5] =
+ (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][6] =
+ (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ result[t][7] =
+ (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ break;
+ } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
+ result[t][4] = (rtl_get_bbreg(hw,
+ 0xeb4,
+ MASKDWORD) &
+ 0x3FF0000) >> 16;
+ }
+ result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
+ 0x3FF0000) >> 16;
+ }
+ }
+ rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
+ rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
+ rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
+ rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
+ if (is2t)
+ rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
+ if (t != 0) {
+ if (!rtlphy->b_rfpi_enable)
+ _rtl92c_phy_pi_mode_switch(hw, false);
+ _rtl92c_phy_reload_adda_registers(hw, adda_reg,
+ rtlphy->adda_backup, 16);
+ _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
+ rtlphy->iqk_mac_backup);
+ }
+}
+
+static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
+{
+ u8 tmpreg;
+ u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ tmpreg = rtl_read_byte(rtlpriv, 0xd03);
+
+ if ((tmpreg & 0x70) != 0)
+ rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
+ else
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+
+ if ((tmpreg & 0x70) != 0) {
+ rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
+
+ if (is2t)
+ rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
+ MASK12BITS);
+
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
+ (rf_a_mode & 0x8FFFF) | 0x10000);
+
+ if (is2t)
+ rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
+ (rf_b_mode & 0x8FFFF) | 0x10000);
+ }
+ lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
+
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
+
+ mdelay(100);
+
+ if ((tmpreg & 0x70) != 0) {
+ rtl_write_byte(rtlpriv, 0xd03, tmpreg);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
+
+ if (is2t)
+ rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
+ rf_b_mode);
+ } else {
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+ }
+}
+
+static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
+ char delta, bool is2t)
+{
+ /* This routine is deliberately dummied out for later fixes */
+#if 0
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ u32 reg_d[PATH_NUM];
+ u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound;
+
+ u32 bb_backup[APK_BB_REG_NUM];
+ u32 bb_reg[APK_BB_REG_NUM] = {
+ 0x904, 0xc04, 0x800, 0xc08, 0x874
+ };
+ u32 bb_ap_mode[APK_BB_REG_NUM] = {
+ 0x00000020, 0x00a05430, 0x02040000,
+ 0x000800e4, 0x00204000
+ };
+ u32 bb_normal_ap_mode[APK_BB_REG_NUM] = {
+ 0x00000020, 0x00a05430, 0x02040000,
+ 0x000800e4, 0x22204000
+ };
+
+ u32 afe_backup[APK_AFE_REG_NUM];
+ u32 afe_reg[APK_AFE_REG_NUM] = {
+ 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78,
+ 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
+ 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
+ 0xeec
+ };
+
+ u32 mac_backup[IQK_MAC_REG_NUM];
+ u32 mac_reg[IQK_MAC_REG_NUM] = {
+ 0x522, 0x550, 0x551, 0x040
+ };
+
+ u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
+ {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
+ };
+
+ u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},
+ {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
+ };
+
+ u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
+ {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
+ };
+
+ u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
+ };
+
+ u32 afe_on_off[PATH_NUM] = {
+ 0x04db25a4, 0x0b1b25a4
+ };
+
+ u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
+
+ u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
+
+ u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 };
+
+ u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 };
+
+ const char apk_delta_mapping[APK_BB_REG_NUM][13] = {
+ {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
+ };
+
+ const u32 apk_normal_setting_value_1[13] = {
+ 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
+ 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
+ 0x12680000, 0x00880000, 0x00880000
+ };
+
+ const u32 apk_normal_setting_value_2[16] = {
+ 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
+ 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
+ 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
+ 0x00050006
+ };
+
+ const u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
+
+ long bb_offset, delta_v, delta_offset;
+
+ if (!is2t)
+ pathbound = 1;
+
+ for (index = 0; index < PATH_NUM; index++) {
+ apk_offset[index] = apk_normal_offset[index];
+ apk_value[index] = apk_normal_value[index];
+ afe_on_off[index] = 0x6fdb25a4;
+ }
+
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ for (path = 0; path < pathbound; path++) {
+ apk_rf_init_value[path][index] =
+ apk_normal_rf_init_value[path][index];
+ apk_rf_value_0[path][index] =
+ apk_normal_rf_value_0[path][index];
+ }
+ bb_ap_mode[index] = bb_normal_ap_mode[index];
+
+ apkbound = 6;
+ }
+
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ if (index == 0)
+ continue;
+ bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD);
+ }
+
+ _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup);
+
+ _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16);
+
+ for (path = 0; path < pathbound; path++) {
+ if (path == RF90_PATH_A) {
+ offset = 0xb00;
+ for (index = 0; index < 11; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_1
+ [index]);
+
+ offset += 0x04;
+ }
+
+ rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
+
+ offset = 0xb68;
+ for (; index < 13; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_1
+ [index]);
+
+ offset += 0x04;
+ }
+
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
+
+ offset = 0xb00;
+ for (index = 0; index < 16; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_2
+ [index]);
+
+ offset += 0x04;
+ }
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
+ } else if (path == RF90_PATH_B) {
+ offset = 0xb70;
+ for (index = 0; index < 10; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_1
+ [index]);
+
+ offset += 0x04;
+ }
+ rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000);
+ rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
+
+ offset = 0xb68;
+ index = 11;
+ for (; index < 13; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_1
+ [index]);
+
+ offset += 0x04;
+ }
+
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
+
+ offset = 0xb60;
+ for (index = 0; index < 16; index++) {
+ rtl_set_bbreg(hw, offset, MASKDWORD,
+ apk_normal_setting_value_2
+ [index]);
+
+ offset += 0x04;
+ }
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
+ }
+
+ reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path,
+ 0xd, MASKDWORD);
+
+ for (index = 0; index < APK_AFE_REG_NUM; index++)
+ rtl_set_bbreg(hw, afe_reg[index], MASKDWORD,
+ afe_on_off[path]);
+
+ if (path == RF90_PATH_A) {
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ if (index == 0)
+ continue;
+ rtl_set_bbreg(hw, bb_reg[index], MASKDWORD,
+ bb_ap_mode[index]);
+ }
+ }
+
+ _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup);
+
+ if (path == 0) {
+ rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000);
+ } else {
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD,
+ 0x10000);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
+ 0x1000f);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
+ 0x20103);
+ }
+
+ delta_offset = ((delta + 14) / 2);
+ if (delta_offset < 0)
+ delta_offset = 0;
+ else if (delta_offset > 12)
+ delta_offset = 12;
+
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ if (index != 1)
+ continue;
+
+ tmpreg = apk_rf_init_value[path][index];
+
+ if (!rtlefuse->b_apk_thermalmeterignore) {
+ bb_offset = (tmpreg & 0xF0000) >> 16;
+
+ if (!(tmpreg & BIT(15)))
+ bb_offset = -bb_offset;
+
+ delta_v =
+ apk_delta_mapping[index][delta_offset];
+
+ bb_offset += delta_v;
+
+ if (bb_offset < 0) {
+ tmpreg = tmpreg & (~BIT(15));
+ bb_offset = -bb_offset;
+ } else {
+ tmpreg = tmpreg | BIT(15);
+ }
+
+ tmpreg =
+ (tmpreg & 0xFFF0FFFF) | (bb_offset << 16);
+ }
+
+ rtl_set_rfreg(hw, (enum radio_path)path, 0xc,
+ MASKDWORD, 0x8992e);
+ rtl_set_rfreg(hw, (enum radio_path)path, 0x0,
+ MASKDWORD, apk_rf_value_0[path][index]);
+ rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
+ MASKDWORD, tmpreg);
+
+ i = 0;
+ do {
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000);
+ rtl_set_bbreg(hw, apk_offset[path],
+ MASKDWORD, apk_value[0]);
+ RTPRINT(rtlpriv, FINIT, INIT_IQK,
+ ("PHY_APCalibrate() offset 0x%x "
+ "value 0x%x\n",
+ apk_offset[path],
+ rtl_get_bbreg(hw, apk_offset[path],
+ MASKDWORD)));
+
+ mdelay(3);
+
+ rtl_set_bbreg(hw, apk_offset[path],
+ MASKDWORD, apk_value[1]);
+ RTPRINT(rtlpriv, FINIT, INIT_IQK,
+ ("PHY_APCalibrate() offset 0x%x "
+ "value 0x%x\n",
+ apk_offset[path],
+ rtl_get_bbreg(hw, apk_offset[path],
+ MASKDWORD)));
+
+ mdelay(20);
+
+ rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
+
+ if (path == RF90_PATH_A)
+ tmpreg = rtl_get_bbreg(hw, 0xbd8,
+ 0x03E00000);
+ else
+ tmpreg = rtl_get_bbreg(hw, 0xbd8,
+ 0xF8000000);
+
+ RTPRINT(rtlpriv, FINIT, INIT_IQK,
+ ("PHY_APCalibrate() offset "
+ "0xbd8[25:21] %x\n", tmpreg));
+
+ i++;
+
+ } while (tmpreg > apkbound && i < 4);
+
+ apk_result[path][index] = tmpreg;
+ }
+ }
+
+ _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup);
+
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ if (index == 0)
+ continue;
+ rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]);
+ }
+
+ _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16);
+
+ for (path = 0; path < pathbound; path++) {
+ rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
+ MASKDWORD, reg_d[path]);
+
+ if (path == RF90_PATH_B) {
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
+ 0x1000f);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
+ 0x20101);
+ }
+
+ if (apk_result[path][1] > 6)
+ apk_result[path][1] = 6;
+ }
+
+ for (path = 0; path < pathbound; path++) {
+ rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD,
+ ((apk_result[path][1] << 15) |
+ (apk_result[path][1] << 10) |
+ (apk_result[path][1] << 5) |
+ apk_result[path][1]));
+
+ if (path == RF90_PATH_A)
+ rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
+ ((apk_result[path][1] << 15) |
+ (apk_result[path][1] << 10) |
+ (0x00 << 5) | 0x05));
+ else
+ rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
+ ((apk_result[path][1] << 15) |
+ (apk_result[path][1] << 10) |
+ (0x02 << 5) | 0x05));
+
+ rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD,
+ ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) |
+ 0x08));
+
+ }
+
+ rtlphy->b_apk_done = true;
+#endif
+}
+
+static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
+ bool bmain, bool is2t)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (is_hal_stop(rtlhal)) {
+ rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
+ rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
+ }
+ if (is2t) {
+ if (bmain)
+ rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
+ BIT(5) | BIT(6), 0x1);
+ else
+ rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
+ BIT(5) | BIT(6), 0x2);
+ } else {
+ if (bmain)
+ rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
+ else
+ rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
+
+ }
+}
+
+#undef IQK_ADDA_REG_NUM
+#undef IQK_DELAY_TIME
+
+void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ long result[4][8];
+ u8 i, final_candidate;
+ bool b_patha_ok, b_pathb_ok;
+ long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
+ reg_ecc, reg_tmp = 0;
+ bool is12simular, is13simular, is23simular;
+ bool b_start_conttx = false, b_singletone = false;
+ u32 iqk_bb_reg[10] = {
+ ROFDM0_XARXIQIMBALANCE,
+ ROFDM0_XBRXIQIMBALANCE,
+ ROFDM0_ECCATHRESHOLD,
+ ROFDM0_AGCRSSITABLE,
+ ROFDM0_XATXIQIMBALANCE,
+ ROFDM0_XBTXIQIMBALANCE,
+ ROFDM0_XCTXIQIMBALANCE,
+ ROFDM0_XCTXAFE,
+ ROFDM0_XDTXAFE,
+ ROFDM0_RXIQEXTANTA
+ };
+
+ if (b_recovery) {
+ _rtl92c_phy_reload_adda_registers(hw,
+ iqk_bb_reg,
+ rtlphy->iqk_bb_backup, 10);
+ return;
+ }
+ if (b_start_conttx || b_singletone)
+ return;
+ for (i = 0; i < 8; i++) {
+ result[0][i] = 0;
+ result[1][i] = 0;
+ result[2][i] = 0;
+ result[3][i] = 0;
+ }
+ final_candidate = 0xff;
+ b_patha_ok = false;
+ b_pathb_ok = false;
+ is12simular = false;
+ is23simular = false;
+ is13simular = false;
+ for (i = 0; i < 3; i++) {
+ if (IS_92C_SERIAL(rtlhal->version))
+ _rtl92c_phy_iq_calibrate(hw, result, i, true);
+ else
+ _rtl92c_phy_iq_calibrate(hw, result, i, false);
+ if (i == 1) {
+ is12simular = _rtl92c_phy_simularity_compare(hw,
+ result, 0,
+ 1);
+ if (is12simular) {
+ final_candidate = 0;
+ break;
+ }
+ }
+ if (i == 2) {
+ is13simular = _rtl92c_phy_simularity_compare(hw,
+ result, 0,
+ 2);
+ if (is13simular) {
+ final_candidate = 0;
+ break;
+ }
+ is23simular = _rtl92c_phy_simularity_compare(hw,
+ result, 1,
+ 2);
+ if (is23simular)
+ final_candidate = 1;
+ else {
+ for (i = 0; i < 8; i++)
+ reg_tmp += result[3][i];
+
+ if (reg_tmp != 0)
+ final_candidate = 3;
+ else
+ final_candidate = 0xFF;
+ }
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ reg_e94 = result[i][0];
+ reg_e9c = result[i][1];
+ reg_ea4 = result[i][2];
+ reg_eac = result[i][3];
+ reg_eb4 = result[i][4];
+ reg_ebc = result[i][5];
+ reg_ec4 = result[i][6];
+ reg_ecc = result[i][7];
+ }
+ if (final_candidate != 0xff) {
+ rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
+ rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
+ reg_ea4 = result[final_candidate][2];
+ reg_eac = result[final_candidate][3];
+ rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
+ rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
+ reg_ec4 = result[final_candidate][6];
+ reg_ecc = result[final_candidate][7];
+ b_patha_ok = b_pathb_ok = true;
+ } else {
+ rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
+ rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
+ }
+ if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
+ _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
+ final_candidate,
+ (reg_ea4 == 0));
+ if (IS_92C_SERIAL(rtlhal->version)) {
+ if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
+ _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok,
+ result,
+ final_candidate,
+ (reg_ec4 == 0));
+ }
+ _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
+ rtlphy->iqk_bb_backup, 10);
+}
+
+void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ bool b_start_conttx = false, b_singletone = false;
+
+ if (b_start_conttx || b_singletone)
+ return;
+ if (IS_92C_SERIAL(rtlhal->version))
+ _rtl92c_phy_lc_calibrate(hw, true);
+ else
+ _rtl92c_phy_lc_calibrate(hw, false);
+}
+
+void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (rtlphy->b_apk_done)
+ return;
+ if (IS_92C_SERIAL(rtlhal->version))
+ _rtl92c_phy_ap_calibrate(hw, delta, true);
+ else
+ _rtl92c_phy_ap_calibrate(hw, delta, false);
+}
+
+void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
+{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (IS_92C_SERIAL(rtlhal->version))
+ _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
+ else
+ _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
+}
+
+bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ bool b_postprocessing = false;
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+ iotype, rtlphy->set_io_inprogress));
+ do {
+ switch (iotype) {
+ case IO_CMD_RESUME_DM_BY_SCAN:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ ("[IO CMD] Resume DM after scan.\n"));
+ b_postprocessing = true;
+ break;
+ case IO_CMD_PAUSE_DM_BY_SCAN:
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ ("[IO CMD] Pause DM before scan.\n"));
+ b_postprocessing = true;
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ } while (false);
+ if (b_postprocessing && !rtlphy->set_io_inprogress) {
+ rtlphy->set_io_inprogress = true;
+ rtlphy->current_io_type = iotype;
+ } else {
+ return false;
+ }
+ rtl92c_phy_set_io(hw);
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+ return true;
+}
+
+void rtl92c_phy_set_io(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ ("--->Cmd(%#x), set_io_inprogress(%d)\n",
+ rtlphy->current_io_type, rtlphy->set_io_inprogress));
+ switch (rtlphy->current_io_type) {
+ case IO_CMD_RESUME_DM_BY_SCAN:
+ dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
+ rtl92c_dm_write_dig(hw);
+ rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+ break;
+ case IO_CMD_PAUSE_DM_BY_SCAN:
+ rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
+ dm_digtable.cur_igvalue = 0x17;
+ rtl92c_dm_write_dig(hw);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ break;
+ }
+ rtlphy->set_io_inprogress = false;
+ RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+ ("<---(%#x)\n", rtlphy->current_io_type));
+}
+
+void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+}
+
+static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+ u32 u4b_tmp;
+ u8 delay = 5;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+ u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+ while (u4b_tmp != 0 && delay > 0) {
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
+ rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+ u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+ delay--;
+ }
+ if (delay == 0) {
+ rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+ rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+ ("Switch RF timeout !!!.\n"));
+ return;
+ }
+ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+ rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
+}
+
+static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool bresult = true;
+ u8 i, queue_id;
+ struct rtl8192_tx_ring *ring = NULL;
+
+ ppsc->set_rfpowerstate_inprogress = true;
+ switch (rfpwr_state) {
+ case ERFON:{
+ if ((ppsc->rfpwr_state == ERFOFF) &&
+ RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+ bool rtstatus;
+ u32 InitializeCount = 0;
+ do {
+ InitializeCount++;
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("IPS Set eRf nic enable\n"));
+ rtstatus = rtl_ps_enable_nic(hw);
+ } while ((rtstatus != true)
+ && (InitializeCount < 10));
+ RT_CLEAR_PS_LEVEL(ppsc,
+ RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("Set ERFON sleeped:%d ms\n",
+ jiffies_to_msecs(jiffies -
+ ppsc->
+ last_sleep_jiffies)));
+ ppsc->last_awake_jiffies = jiffies;
+ rtl92ce_phy_set_rf_on(hw);
+ }
+ if (mac->link_state == MAC80211_LINKED) {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_LINK);
+ } else {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_NO_LINK);
+ }
+ break;
+ }
+ case ERFOFF:{
+ for (queue_id = 0, i = 0;
+ queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ if (skb_queue_len(&ring->queue) == 0 ||
+ queue_id == BEACON_QUEUE) {
+ queue_id++;
+ continue;
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("eRf Off/Sleep: %d times "
+ "TcbBusyQueue[%d] "
+ "=%d before doze!\n", (i + 1),
+ queue_id,
+ skb_queue_len(&ring->queue)));
+ udelay(10);
+ i++;
+ }
+ if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("\nERFOFF: %d times "
+ "TcbBusyQueue[%d] = %d !\n",
+ MAX_DOZE_WAITING_TIMES_9x,
+ queue_id,
+ skb_queue_len(&ring->queue)));
+ break;
+ }
+ }
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("IPS Set eRf nic disable\n"));
+ rtl_ps_disable_nic(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_NO_LINK);
+ } else {
+ rtlpriv->cfg->ops->led_control(hw,
+ LED_CTL_POWER_OFF);
+ }
+ }
+ break;
+ }
+ case ERFSLEEP:{
+ if (ppsc->rfpwr_state == ERFOFF)
+ break;
+ for (queue_id = 0, i = 0;
+ queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+ ring = &pcipriv->dev.tx_ring[queue_id];
+ if (skb_queue_len(&ring->queue) == 0) {
+ queue_id++;
+ continue;
+ } else {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("eRf Off/Sleep: %d times "
+ "TcbBusyQueue[%d] =%d before "
+ "doze!\n", (i + 1), queue_id,
+ skb_queue_len(&ring->queue)));
+ udelay(10);
+ i++;
+ }
+ if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+ ("\n ERFSLEEP: %d times "
+ "TcbBusyQueue[%d] = %d !\n",
+ MAX_DOZE_WAITING_TIMES_9x,
+ queue_id,
+ skb_queue_len(&ring->queue)));
+ break;
+ }
+ }
+ RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+ ("Set ERFSLEEP awaked:%d ms\n",
+ jiffies_to_msecs(jiffies -
+ ppsc->last_awake_jiffies)));
+ ppsc->last_sleep_jiffies = jiffies;
+ _rtl92ce_phy_set_rf_sleep(hw);
+ break;
+ }
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("switch case not process\n"));
+ bresult = false;
+ break;
+ }
+ if (bresult)
+ ppsc->rfpwr_state = rfpwr_state;
+ ppsc->set_rfpowerstate_inprogress = false;
+ return bresult;
+}
+
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state)
+{
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool bresult = false;
+
+ if (rfpwr_state == ppsc->rfpwr_state)
+ return bresult;
+ bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
+ return bresult;
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
new file mode 100644
index 000000000000..ca4daee6e9a8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C_PHY_H__
+#define __RTL92C_PHY_H__
+
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#define MAX_DOZE_WAITING_TIMES_9x 64
+
+#define RT_CANNOT_IO(hw) false
+#define HIGHPOWER_RADIOA_ARRAYLEN 22
+
+#define MAX_TOLERANCE 5
+#define IQK_DELAY_TIME 1
+
+#define APK_BB_REG_NUM 5
+#define APK_AFE_REG_NUM 16
+#define APK_CURVE_REG_NUM 4
+#define PATH_NUM 2
+
+#define LOOP_LIMIT 5
+#define MAX_STALL_TIME 50
+#define AntennaDiversityValue 0x80
+#define MAX_TXPWR_IDX_NMODE_92S 63
+#define Reset_Cnt_Limit 3
+
+#define IQK_ADDA_REG_NUM 16
+#define IQK_MAC_REG_NUM 4
+
+#define RF90_PATH_MAX 2
+#define CHANNEL_MAX_NUMBER 14
+#define CHANNEL_GROUP_MAX 3
+
+#define CT_OFFSET_MAC_ADDR 0X16
+
+#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
+#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
+#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66
+#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
+#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
+
+#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
+#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
+
+#define CT_OFFSET_CHANNEL_PLAH 0x75
+#define CT_OFFSET_THERMAL_METER 0x78
+#define CT_OFFSET_RF_OPTION 0x79
+#define CT_OFFSET_VERSION 0x7E
+#define CT_OFFSET_CUSTOMER_ID 0x7F
+
+#define RTL92C_MAX_PATH_NUM 2
+#define CHANNEL_MAX_NUMBER 14
+#define CHANNEL_GROUP_MAX 3
+
+enum swchnlcmd_id {
+ CMDID_END,
+ CMDID_SET_TXPOWEROWER_LEVEL,
+ CMDID_BBREGWRITE10,
+ CMDID_WRITEPORT_ULONG,
+ CMDID_WRITEPORT_USHORT,
+ CMDID_WRITEPORT_UCHAR,
+ CMDID_RF_WRITEREG,
+};
+
+struct swchnlcmd {
+ enum swchnlcmd_id cmdid;
+ u32 para1;
+ u32 para2;
+ u32 msdelay;
+};
+
+enum hw90_block_e {
+ HW90_BLOCK_MAC = 0,
+ HW90_BLOCK_PHY0 = 1,
+ HW90_BLOCK_PHY1 = 2,
+ HW90_BLOCK_RF = 3,
+ HW90_BLOCK_MAXIMUM = 4,
+};
+
+enum baseband_config_type {
+ BASEBAND_CONFIG_PHY_REG = 0,
+ BASEBAND_CONFIG_AGC_TAB = 1,
+};
+
+enum ra_offset_area {
+ RA_OFFSET_LEGACY_OFDM1,
+ RA_OFFSET_LEGACY_OFDM2,
+ RA_OFFSET_HT_OFDM1,
+ RA_OFFSET_HT_OFDM2,
+ RA_OFFSET_HT_OFDM3,
+ RA_OFFSET_HT_OFDM4,
+ RA_OFFSET_HT_CCK,
+};
+
+enum antenna_path {
+ ANTENNA_NONE,
+ ANTENNA_D,
+ ANTENNA_C,
+ ANTENNA_CD,
+ ANTENNA_B,
+ ANTENNA_BD,
+ ANTENNA_BC,
+ ANTENNA_BCD,
+ ANTENNA_A,
+ ANTENNA_AD,
+ ANTENNA_AC,
+ ANTENNA_ACD,
+ ANTENNA_AB,
+ ANTENNA_ABD,
+ ANTENNA_ABC,
+ ANTENNA_ABCD
+};
+
+struct r_antenna_select_ofdm {
+ u32 r_tx_antenna:4;
+ u32 r_ant_l:4;
+ u32 r_ant_non_ht:4;
+ u32 r_ant_ht1:4;
+ u32 r_ant_ht2:4;
+ u32 r_ant_ht_s1:4;
+ u32 r_ant_non_ht_s1:4;
+ u32 ofdm_txsc:2;
+ u32 reserved:2;
+};
+
+struct r_antenna_select_cck {
+ u8 r_cckrx_enable_2:2;
+ u8 r_cckrx_enable:2;
+ u8 r_ccktx_enable:4;
+};
+
+struct efuse_contents {
+ u8 mac_addr[ETH_ALEN];
+ u8 cck_tx_power_idx[6];
+ u8 ht40_1s_tx_power_idx[6];
+ u8 ht40_2s_tx_power_idx_diff[3];
+ u8 ht20_tx_power_idx_diff[3];
+ u8 ofdm_tx_power_idx_diff[3];
+ u8 ht40_max_power_offset[3];
+ u8 ht20_max_power_offset[3];
+ u8 channel_plan;
+ u8 thermal_meter;
+ u8 rf_option[5];
+ u8 version;
+ u8 oem_id;
+ u8 regulatory;
+};
+
+struct tx_power_struct {
+ u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 legacy_ht_txpowerdiff;
+ u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+ u8 pwrgroup_cnt;
+ u32 mcs_original_offset[4][16];
+};
+
+extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask);
+extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask, u32 data);
+extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask);
+extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask, u32 data);
+extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
+extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
+extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
+extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+ enum radio_path rfpath);
+extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
+ long *powerlevel);
+extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+ long power_indbm);
+extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
+ u8 operation);
+extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type);
+extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
+extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
+ u16 beaconinterval);
+void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
+void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
+void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
+bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+ enum radio_path rfpath);
+extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+ u32 rfpath);
+bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
+void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw);
+void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
+bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+void rtl92c_phy_set_io(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
new file mode 100644
index 000000000000..875d51465225
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -0,0 +1,2065 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C_REG_H__
+#define __RTL92C_REG_H__
+
+#define REG_SYS_ISO_CTRL 0x0000
+#define REG_SYS_FUNC_EN 0x0002
+#define REG_APS_FSMCO 0x0004
+#define REG_SYS_CLKR 0x0008
+#define REG_9346CR 0x000A
+#define REG_EE_VPD 0x000C
+#define REG_AFE_MISC 0x0010
+#define REG_SPS0_CTRL 0x0011
+#define REG_SPS_OCP_CFG 0x0018
+#define REG_RSV_CTRL 0x001C
+#define REG_RF_CTRL 0x001F
+#define REG_LDOA15_CTRL 0x0020
+#define REG_LDOV12D_CTRL 0x0021
+#define REG_LDOHCI12_CTRL 0x0022
+#define REG_LPLDO_CTRL 0x0023
+#define REG_AFE_XTAL_CTRL 0x0024
+#define REG_AFE_PLL_CTRL 0x0028
+#define REG_EFUSE_CTRL 0x0030
+#define REG_EFUSE_TEST 0x0034
+#define REG_PWR_DATA 0x0038
+#define REG_CAL_TIMER 0x003C
+#define REG_ACLK_MON 0x003E
+#define REG_GPIO_MUXCFG 0x0040
+#define REG_GPIO_IO_SEL 0x0042
+#define REG_MAC_PINMUX_CFG 0x0043
+#define REG_GPIO_PIN_CTRL 0x0044
+#define REG_GPIO_INTM 0x0048
+#define REG_LEDCFG0 0x004C
+#define REG_LEDCFG1 0x004D
+#define REG_LEDCFG2 0x004E
+#define REG_LEDCFG3 0x004F
+#define REG_FSIMR 0x0050
+#define REG_FSISR 0x0054
+
+#define REG_MCUFWDL 0x0080
+
+#define REG_HMEBOX_EXT_0 0x0088
+#define REG_HMEBOX_EXT_1 0x008A
+#define REG_HMEBOX_EXT_2 0x008C
+#define REG_HMEBOX_EXT_3 0x008E
+
+#define REG_BIST_SCAN 0x00D0
+#define REG_BIST_RPT 0x00D4
+#define REG_BIST_ROM_RPT 0x00D8
+#define REG_USB_SIE_INTF 0x00E0
+#define REG_PCIE_MIO_INTF 0x00E4
+#define REG_PCIE_MIO_INTD 0x00E8
+#define REG_HPON_FSM 0x00EC
+#define REG_SYS_CFG 0x00F0
+
+#define REG_CR 0x0100
+#define REG_PBP 0x0104
+#define REG_TRXDMA_CTRL 0x010C
+#define REG_TRXFF_BNDY 0x0114
+#define REG_TRXFF_STATUS 0x0118
+#define REG_RXFF_PTR 0x011C
+#define REG_HIMR 0x0120
+#define REG_HISR 0x0124
+#define REG_HIMRE 0x0128
+#define REG_HISRE 0x012C
+#define REG_CPWM 0x012F
+#define REG_FWIMR 0x0130
+#define REG_FWISR 0x0134
+#define REG_PKTBUF_DBG_CTRL 0x0140
+#define REG_PKTBUF_DBG_DATA_L 0x0144
+#define REG_PKTBUF_DBG_DATA_H 0x0148
+
+#define REG_TC0_CTRL 0x0150
+#define REG_TC1_CTRL 0x0154
+#define REG_TC2_CTRL 0x0158
+#define REG_TC3_CTRL 0x015C
+#define REG_TC4_CTRL 0x0160
+#define REG_TCUNIT_BASE 0x0164
+#define REG_MBIST_START 0x0174
+#define REG_MBIST_DONE 0x0178
+#define REG_MBIST_FAIL 0x017C
+#define REG_C2HEVT_MSG_NORMAL 0x01A0
+#define REG_C2HEVT_MSG_TEST 0x01B8
+#define REG_C2HEVT_CLEAR 0x01BF
+#define REG_MCUTST_1 0x01c0
+#define REG_FMETHR 0x01C8
+#define REG_HMETFR 0x01CC
+#define REG_HMEBOX_0 0x01D0
+#define REG_HMEBOX_1 0x01D4
+#define REG_HMEBOX_2 0x01D8
+#define REG_HMEBOX_3 0x01DC
+
+#define REG_LLT_INIT 0x01E0
+#define REG_BB_ACCEESS_CTRL 0x01E8
+#define REG_BB_ACCESS_DATA 0x01EC
+
+#define REG_RQPN 0x0200
+#define REG_FIFOPAGE 0x0204
+#define REG_TDECTRL 0x0208
+#define REG_TXDMA_OFFSET_CHK 0x020C
+#define REG_TXDMA_STATUS 0x0210
+#define REG_RQPN_NPQ 0x0214
+
+#define REG_RXDMA_AGG_PG_TH 0x0280
+#define REG_RXPKT_NUM 0x0284
+#define REG_RXDMA_STATUS 0x0288
+
+#define REG_PCIE_CTRL_REG 0x0300
+#define REG_INT_MIG 0x0304
+#define REG_BCNQ_DESA 0x0308
+#define REG_HQ_DESA 0x0310
+#define REG_MGQ_DESA 0x0318
+#define REG_VOQ_DESA 0x0320
+#define REG_VIQ_DESA 0x0328
+#define REG_BEQ_DESA 0x0330
+#define REG_BKQ_DESA 0x0338
+#define REG_RX_DESA 0x0340
+#define REG_DBI 0x0348
+#define REG_MDIO 0x0354
+#define REG_DBG_SEL 0x0360
+#define REG_PCIE_HRPWM 0x0361
+#define REG_PCIE_HCPWM 0x0363
+#define REG_UART_CTRL 0x0364
+#define REG_UART_TX_DESA 0x0370
+#define REG_UART_RX_DESA 0x0378
+
+#define REG_HDAQ_DESA_NODEF 0x0000
+#define REG_CMDQ_DESA_NODEF 0x0000
+
+#define REG_VOQ_INFORMATION 0x0400
+#define REG_VIQ_INFORMATION 0x0404
+#define REG_BEQ_INFORMATION 0x0408
+#define REG_BKQ_INFORMATION 0x040C
+#define REG_MGQ_INFORMATION 0x0410
+#define REG_HGQ_INFORMATION 0x0414
+#define REG_BCNQ_INFORMATION 0x0418
+
+#define REG_CPU_MGQ_INFORMATION 0x041C
+#define REG_FWHW_TXQ_CTRL 0x0420
+#define REG_HWSEQ_CTRL 0x0423
+#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
+#define REG_TXPKTBUF_MGQ_BDNY 0x0425
+#define REG_MULTI_BCNQ_EN 0x0426
+#define REG_MULTI_BCNQ_OFFSET 0x0427
+#define REG_SPEC_SIFS 0x0428
+#define REG_RL 0x042A
+#define REG_DARFRC 0x0430
+#define REG_RARFRC 0x0438
+#define REG_RRSR 0x0440
+#define REG_ARFR0 0x0444
+#define REG_ARFR1 0x0448
+#define REG_ARFR2 0x044C
+#define REG_ARFR3 0x0450
+#define REG_AGGLEN_LMT 0x0458
+#define REG_AMPDU_MIN_SPACE 0x045C
+#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
+#define REG_FAST_EDCA_CTRL 0x0460
+#define REG_RD_RESP_PKT_TH 0x0463
+#define REG_INIRTS_RATE_SEL 0x0480
+#define REG_INIDATA_RATE_SEL 0x0484
+#define REG_POWER_STATUS 0x04A4
+#define REG_POWER_STAGE1 0x04B4
+#define REG_POWER_STAGE2 0x04B8
+#define REG_PKT_LIFE_TIME 0x04C0
+#define REG_STBC_SETTING 0x04C4
+#define REG_PROT_MODE_CTRL 0x04C8
+#define REG_BAR_MODE_CTRL 0x04CC
+#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
+#define REG_NQOS_SEQ 0x04DC
+#define REG_QOS_SEQ 0x04DE
+#define REG_NEED_CPU_HANDLE 0x04E0
+#define REG_PKT_LOSE_RPT 0x04E1
+#define REG_PTCL_ERR_STATUS 0x04E2
+#define REG_DUMMY 0x04FC
+
+#define REG_EDCA_VO_PARAM 0x0500
+#define REG_EDCA_VI_PARAM 0x0504
+#define REG_EDCA_BE_PARAM 0x0508
+#define REG_EDCA_BK_PARAM 0x050C
+#define REG_BCNTCFG 0x0510
+#define REG_PIFS 0x0512
+#define REG_RDG_PIFS 0x0513
+#define REG_SIFS_CTX 0x0514
+#define REG_SIFS_TRX 0x0516
+#define REG_AGGR_BREAK_TIME 0x051A
+#define REG_SLOT 0x051B
+#define REG_TX_PTCL_CTRL 0x0520
+#define REG_TXPAUSE 0x0522
+#define REG_DIS_TXREQ_CLR 0x0523
+#define REG_RD_CTRL 0x0524
+#define REG_TBTT_PROHIBIT 0x0540
+#define REG_RD_NAV_NXT 0x0544
+#define REG_NAV_PROT_LEN 0x0546
+#define REG_BCN_CTRL 0x0550
+#define REG_USTIME_TSF 0x0551
+#define REG_MBID_NUM 0x0552
+#define REG_DUAL_TSF_RST 0x0553
+#define REG_BCN_INTERVAL 0x0554
+#define REG_MBSSID_BCN_SPACE 0x0554
+#define REG_DRVERLYINT 0x0558
+#define REG_BCNDMATIM 0x0559
+#define REG_ATIMWND 0x055A
+#define REG_BCN_MAX_ERR 0x055D
+#define REG_RXTSF_OFFSET_CCK 0x055E
+#define REG_RXTSF_OFFSET_OFDM 0x055F
+#define REG_TSFTR 0x0560
+#define REG_INIT_TSFTR 0x0564
+#define REG_PSTIMER 0x0580
+#define REG_TIMER0 0x0584
+#define REG_TIMER1 0x0588
+#define REG_ACMHWCTRL 0x05C0
+#define REG_ACMRSTCTRL 0x05C1
+#define REG_ACMAVG 0x05C2
+#define REG_VO_ADMTIME 0x05C4
+#define REG_VI_ADMTIME 0x05C6
+#define REG_BE_ADMTIME 0x05C8
+#define REG_EDCA_RANDOM_GEN 0x05CC
+#define REG_SCH_TXCMD 0x05D0
+
+#define REG_APSD_CTRL 0x0600
+#define REG_BWOPMODE 0x0603
+#define REG_TCR 0x0604
+#define REG_RCR 0x0608
+#define REG_RX_PKT_LIMIT 0x060C
+#define REG_RX_DLK_TIME 0x060D
+#define REG_RX_DRVINFO_SZ 0x060F
+
+#define REG_MACID 0x0610
+#define REG_BSSID 0x0618
+#define REG_MAR 0x0620
+#define REG_MBIDCAMCFG 0x0628
+
+#define REG_USTIME_EDCA 0x0638
+#define REG_MAC_SPEC_SIFS 0x063A
+#define REG_RESP_SIFS_CCK 0x063C
+#define REG_RESP_SIFS_OFDM 0x063E
+#define REG_ACKTO 0x0640
+#define REG_CTS2TO 0x0641
+#define REG_EIFS 0x0642
+
+#define REG_NAV_CTRL 0x0650
+#define REG_BACAMCMD 0x0654
+#define REG_BACAMCONTENT 0x0658
+#define REG_LBDLY 0x0660
+#define REG_FWDLY 0x0661
+#define REG_RXERR_RPT 0x0664
+#define REG_WMAC_TRXPTCL_CTL 0x0668
+
+#define REG_CAMCMD 0x0670
+#define REG_CAMWRITE 0x0674
+#define REG_CAMREAD 0x0678
+#define REG_CAMDBG 0x067C
+#define REG_SECCFG 0x0680
+
+#define REG_WOW_CTRL 0x0690
+#define REG_PSSTATUS 0x0691
+#define REG_PS_RX_INFO 0x0692
+#define REG_LPNAV_CTRL 0x0694
+#define REG_WKFMCAM_CMD 0x0698
+#define REG_WKFMCAM_RWD 0x069C
+#define REG_RXFLTMAP0 0x06A0
+#define REG_RXFLTMAP1 0x06A2
+#define REG_RXFLTMAP2 0x06A4
+#define REG_BCN_PSR_RPT 0x06A8
+#define REG_CALB32K_CTRL 0x06AC
+#define REG_PKT_MON_CTRL 0x06B4
+#define REG_BT_COEX_TABLE 0x06C0
+#define REG_WMAC_RESP_TXINFO 0x06D8
+
+#define REG_USB_INFO 0xFE17
+#define REG_USB_SPECIAL_OPTION 0xFE55
+#define REG_USB_DMA_AGG_TO 0xFE5B
+#define REG_USB_AGG_TO 0xFE5C
+#define REG_USB_AGG_TH 0xFE5D
+
+#define REG_TEST_USB_TXQS 0xFE48
+#define REG_TEST_SIE_VID 0xFE60
+#define REG_TEST_SIE_PID 0xFE62
+#define REG_TEST_SIE_OPTIONAL 0xFE64
+#define REG_TEST_SIE_CHIRP_K 0xFE65
+#define REG_TEST_SIE_PHY 0xFE66
+#define REG_TEST_SIE_MAC_ADDR 0xFE70
+#define REG_TEST_SIE_STRING 0xFE80
+
+#define REG_NORMAL_SIE_VID 0xFE60
+#define REG_NORMAL_SIE_PID 0xFE62
+#define REG_NORMAL_SIE_OPTIONAL 0xFE64
+#define REG_NORMAL_SIE_EP 0xFE65
+#define REG_NORMAL_SIE_PHY 0xFE68
+#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
+#define REG_NORMAL_SIE_STRING 0xFE80
+
+#define CR9346 REG_9346CR
+#define MSR (REG_CR + 2)
+#define ISR REG_HISR
+#define TSFR REG_TSFTR
+
+#define MACIDR0 REG_MACID
+#define MACIDR4 (REG_MACID + 4)
+
+#define PBP REG_PBP
+
+#define IDR0 MACIDR0
+#define IDR4 MACIDR4
+
+#define UNUSED_REGISTER 0x1BF
+#define DCAM UNUSED_REGISTER
+#define PSR UNUSED_REGISTER
+#define BBADDR UNUSED_REGISTER
+#define PHYDATAR UNUSED_REGISTER
+
+#define INVALID_BBRF_VALUE 0x12345678
+
+#define MAX_MSS_DENSITY_2T 0x13
+#define MAX_MSS_DENSITY_1T 0x0A
+
+#define CMDEEPROM_EN BIT(5)
+#define CMDEEPROM_SEL BIT(4)
+#define CMD9346CR_9356SEL BIT(4)
+#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL)
+#define AUTOLOAD_EFUSE CMDEEPROM_EN
+
+#define GPIOSEL_GPIO 0
+#define GPIOSEL_ENBT BIT(5)
+
+#define GPIO_IN REG_GPIO_PIN_CTRL
+#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
+#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
+#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
+
+#define MSR_NOLINK 0x00
+#define MSR_ADHOC 0x01
+#define MSR_INFRA 0x02
+#define MSR_AP 0x03
+
+#define RRSR_RSC_OFFSET 21
+#define RRSR_SHORT_OFFSET 23
+#define RRSR_RSC_BW_40M 0x600000
+#define RRSR_RSC_UPSUBCHNL 0x400000
+#define RRSR_RSC_LOWSUBCHNL 0x200000
+#define RRSR_SHORT 0x800000
+#define RRSR_1M BIT(0)
+#define RRSR_2M BIT(1)
+#define RRSR_5_5M BIT(2)
+#define RRSR_11M BIT(3)
+#define RRSR_6M BIT(4)
+#define RRSR_9M BIT(5)
+#define RRSR_12M BIT(6)
+#define RRSR_18M BIT(7)
+#define RRSR_24M BIT(8)
+#define RRSR_36M BIT(9)
+#define RRSR_48M BIT(10)
+#define RRSR_54M BIT(11)
+#define RRSR_MCS0 BIT(12)
+#define RRSR_MCS1 BIT(13)
+#define RRSR_MCS2 BIT(14)
+#define RRSR_MCS3 BIT(15)
+#define RRSR_MCS4 BIT(16)
+#define RRSR_MCS5 BIT(17)
+#define RRSR_MCS6 BIT(18)
+#define RRSR_MCS7 BIT(19)
+#define BRSR_ACKSHORTPMB BIT(23)
+
+#define RATR_1M 0x00000001
+#define RATR_2M 0x00000002
+#define RATR_55M 0x00000004
+#define RATR_11M 0x00000008
+#define RATR_6M 0x00000010
+#define RATR_9M 0x00000020
+#define RATR_12M 0x00000040
+#define RATR_18M 0x00000080
+#define RATR_24M 0x00000100
+#define RATR_36M 0x00000200
+#define RATR_48M 0x00000400
+#define RATR_54M 0x00000800
+#define RATR_MCS0 0x00001000
+#define RATR_MCS1 0x00002000
+#define RATR_MCS2 0x00004000
+#define RATR_MCS3 0x00008000
+#define RATR_MCS4 0x00010000
+#define RATR_MCS5 0x00020000
+#define RATR_MCS6 0x00040000
+#define RATR_MCS7 0x00080000
+#define RATR_MCS8 0x00100000
+#define RATR_MCS9 0x00200000
+#define RATR_MCS10 0x00400000
+#define RATR_MCS11 0x00800000
+#define RATR_MCS12 0x01000000
+#define RATR_MCS13 0x02000000
+#define RATR_MCS14 0x04000000
+#define RATR_MCS15 0x08000000
+
+#define RATE_1M BIT(0)
+#define RATE_2M BIT(1)
+#define RATE_5_5M BIT(2)
+#define RATE_11M BIT(3)
+#define RATE_6M BIT(4)
+#define RATE_9M BIT(5)
+#define RATE_12M BIT(6)
+#define RATE_18M BIT(7)
+#define RATE_24M BIT(8)
+#define RATE_36M BIT(9)
+#define RATE_48M BIT(10)
+#define RATE_54M BIT(11)
+#define RATE_MCS0 BIT(12)
+#define RATE_MCS1 BIT(13)
+#define RATE_MCS2 BIT(14)
+#define RATE_MCS3 BIT(15)
+#define RATE_MCS4 BIT(16)
+#define RATE_MCS5 BIT(17)
+#define RATE_MCS6 BIT(18)
+#define RATE_MCS7 BIT(19)
+#define RATE_MCS8 BIT(20)
+#define RATE_MCS9 BIT(21)
+#define RATE_MCS10 BIT(22)
+#define RATE_MCS11 BIT(23)
+#define RATE_MCS12 BIT(24)
+#define RATE_MCS13 BIT(25)
+#define RATE_MCS14 BIT(26)
+#define RATE_MCS15 BIT(27)
+
+#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
+#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \
+ | RATR_24M | RATR_36M | RATR_48M | RATR_54M)
+#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
+ RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
+ RATR_MCS6 | RATR_MCS7)
+#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
+ RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
+ RATR_MCS14 | RATR_MCS15)
+
+#define BW_OPMODE_20MHZ BIT(2)
+#define BW_OPMODE_5G BIT(1)
+#define BW_OPMODE_11J BIT(0)
+
+#define CAM_VALID BIT(15)
+#define CAM_NOTVALID 0x0000
+#define CAM_USEDK BIT(5)
+
+#define CAM_NONE 0x0
+#define CAM_WEP40 0x01
+#define CAM_TKIP 0x02
+#define CAM_AES 0x04
+#define CAM_WEP104 0x05
+
+#define TOTAL_CAM_ENTRY 32
+#define HALF_CAM_ENTRY 16
+
+#define CAM_WRITE BIT(16)
+#define CAM_READ 0x00000000
+#define CAM_POLLINIG BIT(31)
+
+#define SCR_USEDK 0x01
+#define SCR_TXSEC_ENABLE 0x02
+#define SCR_RXSEC_ENABLE 0x04
+
+#define WOW_PMEN BIT(0)
+#define WOW_WOMEN BIT(1)
+#define WOW_MAGIC BIT(2)
+#define WOW_UWF BIT(3)
+
+#define IMR8190_DISABLED 0x0
+#define IMR_BCNDMAINT6 BIT(31)
+#define IMR_BCNDMAINT5 BIT(30)
+#define IMR_BCNDMAINT4 BIT(29)
+#define IMR_BCNDMAINT3 BIT(28)
+#define IMR_BCNDMAINT2 BIT(27)
+#define IMR_BCNDMAINT1 BIT(26)
+#define IMR_BCNDOK8 BIT(25)
+#define IMR_BCNDOK7 BIT(24)
+#define IMR_BCNDOK6 BIT(23)
+#define IMR_BCNDOK5 BIT(22)
+#define IMR_BCNDOK4 BIT(21)
+#define IMR_BCNDOK3 BIT(20)
+#define IMR_BCNDOK2 BIT(19)
+#define IMR_BCNDOK1 BIT(18)
+#define IMR_TIMEOUT2 BIT(17)
+#define IMR_TIMEOUT1 BIT(16)
+#define IMR_TXFOVW BIT(15)
+#define IMR_PSTIMEOUT BIT(14)
+#define IMR_BCNINT BIT(13)
+#define IMR_RXFOVW BIT(12)
+#define IMR_RDU BIT(11)
+#define IMR_ATIMEND BIT(10)
+#define IMR_BDOK BIT(9)
+#define IMR_HIGHDOK BIT(8)
+#define IMR_TBDOK BIT(7)
+#define IMR_MGNTDOK BIT(6)
+#define IMR_TBDER BIT(5)
+#define IMR_BKDOK BIT(4)
+#define IMR_BEDOK BIT(3)
+#define IMR_VIDOK BIT(2)
+#define IMR_VODOK BIT(1)
+#define IMR_ROK BIT(0)
+
+#define IMR_TXERR BIT(11)
+#define IMR_RXERR BIT(10)
+#define IMR_C2HCMD BIT(9)
+#define IMR_CPWM BIT(8)
+#define IMR_OCPINT BIT(1)
+#define IMR_WLANOFF BIT(0)
+
+#define HWSET_MAX_SIZE 128
+
+#define EEPROM_DEFAULT_TSSI 0x0
+#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
+#define EEPROM_DEFAULT_CRYSTALCAP 0x5
+#define EEPROM_DEFAULT_BOARDTYPE 0x02
+#define EEPROM_DEFAULT_TXPOWER 0x1010
+#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
+
+#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
+#define EEPROM_DEFAULT_THERMALMETER 0x12
+#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
+#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
+#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
+#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
+#define EEPROM_DEFAULT_HT20_DIFF 2
+#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
+#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
+#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
+
+#define RF_OPTION1 0x79
+#define RF_OPTION2 0x7A
+#define RF_OPTION3 0x7B
+#define RF_OPTION4 0x7C
+
+#define EEPROM_DEFAULT_PID 0x1234
+#define EEPROM_DEFAULT_VID 0x5678
+#define EEPROM_DEFAULT_CUSTOMERID 0xAB
+#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
+#define EEPROM_DEFAULT_VERSION 0
+
+#define EEPROM_CHANNEL_PLAN_FCC 0x0
+#define EEPROM_CHANNEL_PLAN_IC 0x1
+#define EEPROM_CHANNEL_PLAN_ETSI 0x2
+#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
+#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
+#define EEPROM_CHANNEL_PLAN_MKK 0x5
+#define EEPROM_CHANNEL_PLAN_MKK1 0x6
+#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
+#define EEPROM_CHANNEL_PLAN_TELEC 0x8
+#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
+#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
+#define EEPROM_CHANNEL_PLAN_NCC 0xB
+#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
+
+#define EEPROM_CID_DEFAULT 0x0
+#define EEPROM_CID_TOSHIBA 0x4
+#define EEPROM_CID_CCX 0x10
+#define EEPROM_CID_QMI 0x0D
+#define EEPROM_CID_WHQL 0xFE
+
+#define RTL8192_EEPROM_ID 0x8129
+
+#define RTL8190_EEPROM_ID 0x8129
+#define EEPROM_HPON 0x02
+#define EEPROM_CLK 0x06
+#define EEPROM_TESTR 0x08
+
+#define EEPROM_VID 0x0A
+#define EEPROM_DID 0x0C
+#define EEPROM_SVID 0x0E
+#define EEPROM_SMID 0x10
+
+#define EEPROM_MAC_ADDR 0x16
+
+#define EEPROM_CCK_TX_PWR_INX 0x5A
+#define EEPROM_HT40_1S_TX_PWR_INX 0x60
+#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66
+#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69
+#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C
+#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F
+#define EEPROM_HT20_MAX_PWR_OFFSET 0x72
+
+#define EEPROM_TSSI_A 0x76
+#define EEPROM_TSSI_B 0x77
+#define EEPROM_THERMAL_METER 0x78
+#define EEPROM_XTAL_K 0x78
+#define EEPROM_RF_OPT1 0x79
+#define EEPROM_RF_OPT2 0x7A
+#define EEPROM_RF_OPT3 0x7B
+#define EEPROM_RF_OPT4 0x7C
+#define EEPROM_CHANNEL_PLAN 0x7D
+#define EEPROM_VERSION 0x7E
+#define EEPROM_CUSTOMER_ID 0x7F
+
+#define EEPROM_PWRDIFF 0x54
+
+#define EEPROM_TXPOWERCCK 0x5A
+#define EEPROM_TXPOWERHT40_1S 0x60
+#define EEPROM_TXPOWERHT40_2SDIFF 0x66
+#define EEPROM_TXPOWERHT20DIFF 0x69
+#define EEPROM_TXPOWER_OFDMDIFF 0x6C
+
+#define EEPROM_TXPWR_GROUP 0x6F
+
+#define EEPROM_TSSI_A 0x76
+#define EEPROM_TSSI_B 0x77
+#define EEPROM_THERMAL_METER 0x78
+
+#define EEPROM_CHANNELPLAN 0x75
+
+#define RF_OPTION1 0x79
+#define RF_OPTION2 0x7A
+#define RF_OPTION3 0x7B
+#define RF_OPTION4 0x7C
+
+#define STOPBECON BIT(6)
+#define STOPHIGHT BIT(5)
+#define STOPMGT BIT(4)
+#define STOPVO BIT(3)
+#define STOPVI BIT(2)
+#define STOPBE BIT(1)
+#define STOPBK BIT(0)
+
+#define RCR_APPFCS BIT(31)
+#define RCR_APP_MIC BIT(30)
+#define RCR_APP_ICV BIT(29)
+#define RCR_APP_PHYST_RXFF BIT(28)
+#define RCR_APP_BA_SSN BIT(27)
+#define RCR_ENMBID BIT(24)
+#define RCR_LSIGEN BIT(23)
+#define RCR_MFBEN BIT(22)
+#define RCR_HTC_LOC_CTRL BIT(14)
+#define RCR_AMF BIT(13)
+#define RCR_ACF BIT(12)
+#define RCR_ADF BIT(11)
+#define RCR_AICV BIT(9)
+#define RCR_ACRC32 BIT(8)
+#define RCR_CBSSID_BCN BIT(7)
+#define RCR_CBSSID_DATA BIT(6)
+#define RCR_CBSSID RCR_CBSSID_DATA
+#define RCR_APWRMGT BIT(5)
+#define RCR_ADD3 BIT(4)
+#define RCR_AB BIT(3)
+#define RCR_AM BIT(2)
+#define RCR_APM BIT(1)
+#define RCR_AAP BIT(0)
+#define RCR_MXDMA_OFFSET 8
+#define RCR_FIFO_OFFSET 13
+
+#define RSV_CTRL 0x001C
+#define RD_CTRL 0x0524
+
+#define REG_USB_INFO 0xFE17
+#define REG_USB_SPECIAL_OPTION 0xFE55
+#define REG_USB_DMA_AGG_TO 0xFE5B
+#define REG_USB_AGG_TO 0xFE5C
+#define REG_USB_AGG_TH 0xFE5D
+
+#define REG_USB_VID 0xFE60
+#define REG_USB_PID 0xFE62
+#define REG_USB_OPTIONAL 0xFE64
+#define REG_USB_CHIRP_K 0xFE65
+#define REG_USB_PHY 0xFE66
+#define REG_USB_MAC_ADDR 0xFE70
+#define REG_USB_HRPWM 0xFE58
+#define REG_USB_HCPWM 0xFE57
+
+#define SW18_FPWM BIT(3)
+
+#define ISO_MD2PP BIT(0)
+#define ISO_UA2USB BIT(1)
+#define ISO_UD2CORE BIT(2)
+#define ISO_PA2PCIE BIT(3)
+#define ISO_PD2CORE BIT(4)
+#define ISO_IP2MAC BIT(5)
+#define ISO_DIOP BIT(6)
+#define ISO_DIOE BIT(7)
+#define ISO_EB2CORE BIT(8)
+#define ISO_DIOR BIT(9)
+
+#define PWC_EV25V BIT(14)
+#define PWC_EV12V BIT(15)
+
+#define FEN_BBRSTB BIT(0)
+#define FEN_BB_GLB_RSTn BIT(1)
+#define FEN_USBA BIT(2)
+#define FEN_UPLL BIT(3)
+#define FEN_USBD BIT(4)
+#define FEN_DIO_PCIE BIT(5)
+#define FEN_PCIEA BIT(6)
+#define FEN_PPLL BIT(7)
+#define FEN_PCIED BIT(8)
+#define FEN_DIOE BIT(9)
+#define FEN_CPUEN BIT(10)
+#define FEN_DCORE BIT(11)
+#define FEN_ELDR BIT(12)
+#define FEN_DIO_RF BIT(13)
+#define FEN_HWPDN BIT(14)
+#define FEN_MREGEN BIT(15)
+
+#define PFM_LDALL BIT(0)
+#define PFM_ALDN BIT(1)
+#define PFM_LDKP BIT(2)
+#define PFM_WOWL BIT(3)
+#define EnPDN BIT(4)
+#define PDN_PL BIT(5)
+#define APFM_ONMAC BIT(8)
+#define APFM_OFF BIT(9)
+#define APFM_RSM BIT(10)
+#define AFSM_HSUS BIT(11)
+#define AFSM_PCIE BIT(12)
+#define APDM_MAC BIT(13)
+#define APDM_HOST BIT(14)
+#define APDM_HPDN BIT(15)
+#define RDY_MACON BIT(16)
+#define SUS_HOST BIT(17)
+#define ROP_ALD BIT(20)
+#define ROP_PWR BIT(21)
+#define ROP_SPS BIT(22)
+#define SOP_MRST BIT(25)
+#define SOP_FUSE BIT(26)
+#define SOP_ABG BIT(27)
+#define SOP_AMB BIT(28)
+#define SOP_RCK BIT(29)
+#define SOP_A8M BIT(30)
+#define XOP_BTCK BIT(31)
+
+#define ANAD16V_EN BIT(0)
+#define ANA8M BIT(1)
+#define MACSLP BIT(4)
+#define LOADER_CLK_EN BIT(5)
+#define _80M_SSC_DIS BIT(7)
+#define _80M_SSC_EN_HO BIT(8)
+#define PHY_SSC_RSTB BIT(9)
+#define SEC_CLK_EN BIT(10)
+#define MAC_CLK_EN BIT(11)
+#define SYS_CLK_EN BIT(12)
+#define RING_CLK_EN BIT(13)
+
+#define BOOT_FROM_EEPROM BIT(4)
+#define EEPROM_EN BIT(5)
+
+#define AFE_BGEN BIT(0)
+#define AFE_MBEN BIT(1)
+#define MAC_ID_EN BIT(7)
+
+#define WLOCK_ALL BIT(0)
+#define WLOCK_00 BIT(1)
+#define WLOCK_04 BIT(2)
+#define WLOCK_08 BIT(3)
+#define WLOCK_40 BIT(4)
+#define R_DIS_PRST_0 BIT(5)
+#define R_DIS_PRST_1 BIT(6)
+#define LOCK_ALL_EN BIT(7)
+
+#define RF_EN BIT(0)
+#define RF_RSTB BIT(1)
+#define RF_SDMRSTB BIT(2)
+
+#define LDA15_EN BIT(0)
+#define LDA15_STBY BIT(1)
+#define LDA15_OBUF BIT(2)
+#define LDA15_REG_VOS BIT(3)
+#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
+
+#define LDV12_EN BIT(0)
+#define LDV12_SDBY BIT(1)
+#define LPLDO_HSM BIT(2)
+#define LPLDO_LSM_DIS BIT(3)
+#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
+
+#define XTAL_EN BIT(0)
+#define XTAL_BSEL BIT(1)
+#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
+#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
+#define XTAL_GATE_USB BIT(8)
+#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
+#define XTAL_GATE_AFE BIT(11)
+#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
+#define XTAL_RF_GATE BIT(14)
+#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
+#define XTAL_GATE_DIG BIT(17)
+#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
+#define XTAL_BT_GATE BIT(20)
+#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
+#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
+
+#define CKDLY_AFE BIT(26)
+#define CKDLY_USB BIT(27)
+#define CKDLY_DIG BIT(28)
+#define CKDLY_BT BIT(29)
+
+#define APLL_EN BIT(0)
+#define APLL_320_EN BIT(1)
+#define APLL_FREF_SEL BIT(2)
+#define APLL_EDGE_SEL BIT(3)
+#define APLL_WDOGB BIT(4)
+#define APLL_LPFEN BIT(5)
+
+#define APLL_REF_CLK_13MHZ 0x1
+#define APLL_REF_CLK_19_2MHZ 0x2
+#define APLL_REF_CLK_20MHZ 0x3
+#define APLL_REF_CLK_25MHZ 0x4
+#define APLL_REF_CLK_26MHZ 0x5
+#define APLL_REF_CLK_38_4MHZ 0x6
+#define APLL_REF_CLK_40MHZ 0x7
+
+#define APLL_320EN BIT(14)
+#define APLL_80EN BIT(15)
+#define APLL_1MEN BIT(24)
+
+#define ALD_EN BIT(18)
+#define EF_PD BIT(19)
+#define EF_FLAG BIT(31)
+
+#define EF_TRPT BIT(7)
+#define LDOE25_EN BIT(31)
+
+#define RSM_EN BIT(0)
+#define Timer_EN BIT(4)
+
+#define TRSW0EN BIT(2)
+#define TRSW1EN BIT(3)
+#define EROM_EN BIT(4)
+#define EnBT BIT(5)
+#define EnUart BIT(8)
+#define Uart_910 BIT(9)
+#define EnPMAC BIT(10)
+#define SIC_SWRST BIT(11)
+#define EnSIC BIT(12)
+#define SIC_23 BIT(13)
+#define EnHDP BIT(14)
+#define SIC_LBK BIT(15)
+
+#define LED0PL BIT(4)
+#define LED1PL BIT(12)
+#define LED0DIS BIT(7)
+
+#define MCUFWDL_EN BIT(0)
+#define MCUFWDL_RDY BIT(1)
+#define FWDL_ChkSum_rpt BIT(2)
+#define MACINI_RDY BIT(3)
+#define BBINI_RDY BIT(4)
+#define RFINI_RDY BIT(5)
+#define WINTINI_RDY BIT(6)
+#define CPRST BIT(23)
+
+#define XCLK_VLD BIT(0)
+#define ACLK_VLD BIT(1)
+#define UCLK_VLD BIT(2)
+#define PCLK_VLD BIT(3)
+#define PCIRSTB BIT(4)
+#define V15_VLD BIT(5)
+#define TRP_B15V_EN BIT(7)
+#define SIC_IDLE BIT(8)
+#define BD_MAC2 BIT(9)
+#define BD_MAC1 BIT(10)
+#define IC_MACPHY_MODE BIT(11)
+#define PAD_HWPD_IDN BIT(22)
+#define TRP_VAUX_EN BIT(23)
+#define TRP_BT_EN BIT(24)
+#define BD_PKG_SEL BIT(25)
+#define BD_HCI_SEL BIT(26)
+#define TYPE_ID BIT(27)
+
+#define CHIP_VER_RTL_MASK 0xF000
+#define CHIP_VER_RTL_SHIFT 12
+
+#define REG_LBMODE (REG_CR + 3)
+
+#define HCI_TXDMA_EN BIT(0)
+#define HCI_RXDMA_EN BIT(1)
+#define TXDMA_EN BIT(2)
+#define RXDMA_EN BIT(3)
+#define PROTOCOL_EN BIT(4)
+#define SCHEDULE_EN BIT(5)
+#define MACTXEN BIT(6)
+#define MACRXEN BIT(7)
+#define ENSWBCN BIT(8)
+#define ENSEC BIT(9)
+
+#define _NETTYPE(x) (((x) & 0x3) << 16)
+#define MASK_NETTYPE 0x30000
+#define NT_NO_LINK 0x0
+#define NT_LINK_AD_HOC 0x1
+#define NT_LINK_AP 0x2
+#define NT_AS_AP 0x3
+
+#define _LBMODE(x) (((x) & 0xF) << 24)
+#define MASK_LBMODE 0xF000000
+#define LOOPBACK_NORMAL 0x0
+#define LOOPBACK_IMMEDIATELY 0xB
+#define LOOPBACK_MAC_DELAY 0x3
+#define LOOPBACK_PHY 0x1
+#define LOOPBACK_DMA 0x7
+
+#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
+#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
+#define _PSRX_MASK 0xF
+#define _PSTX_MASK 0xF0
+#define _PSRX(x) (x)
+#define _PSTX(x) ((x) << 4)
+
+#define PBP_64 0x0
+#define PBP_128 0x1
+#define PBP_256 0x2
+#define PBP_512 0x3
+#define PBP_1024 0x4
+
+#define RXDMA_ARBBW_EN BIT(0)
+#define RXSHFT_EN BIT(1)
+#define RXDMA_AGG_EN BIT(2)
+#define QS_VO_QUEUE BIT(8)
+#define QS_VI_QUEUE BIT(9)
+#define QS_BE_QUEUE BIT(10)
+#define QS_BK_QUEUE BIT(11)
+#define QS_MANAGER_QUEUE BIT(12)
+#define QS_HIGH_QUEUE BIT(13)
+
+#define HQSEL_VOQ BIT(0)
+#define HQSEL_VIQ BIT(1)
+#define HQSEL_BEQ BIT(2)
+#define HQSEL_BKQ BIT(3)
+#define HQSEL_MGTQ BIT(4)
+#define HQSEL_HIQ BIT(5)
+
+#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
+#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
+#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
+#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
+#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
+#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
+
+#define QUEUE_LOW 1
+#define QUEUE_NORMAL 2
+#define QUEUE_HIGH 3
+
+#define _LLT_NO_ACTIVE 0x0
+#define _LLT_WRITE_ACCESS 0x1
+#define _LLT_READ_ACCESS 0x2
+
+#define _LLT_INIT_DATA(x) ((x) & 0xFF)
+#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
+#define _LLT_OP(x) (((x) & 0x3) << 30)
+#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
+
+#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
+#define BB_WRITE_EN BIT(30)
+#define BB_READ_EN BIT(31)
+
+#define _HPQ(x) ((x) & 0xFF)
+#define _LPQ(x) (((x) & 0xFF) << 8)
+#define _PUBQ(x) (((x) & 0xFF) << 16)
+#define _NPQ(x) ((x) & 0xFF)
+
+#define HPQ_PUBLIC_DIS BIT(24)
+#define LPQ_PUBLIC_DIS BIT(25)
+#define LD_RQPN BIT(31)
+
+#define BCN_VALID BIT(16)
+#define BCN_HEAD(x) (((x) & 0xFF) << 8)
+#define BCN_HEAD_MASK 0xFF00
+
+#define BLK_DESC_NUM_SHIFT 4
+#define BLK_DESC_NUM_MASK 0xF
+
+#define DROP_DATA_EN BIT(9)
+
+#define EN_AMPDU_RTY_NEW BIT(7)
+
+#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
+
+#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
+#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
+
+#define RATE_REG_BITMAP_ALL 0xFFFFF
+
+#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
+
+#define _RRSR_RSC(x) (((x) & 0x3) << 21)
+#define RRSR_RSC_RESERVED 0x0
+#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
+#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
+#define RRSR_RSC_DUPLICATE_MODE 0x3
+
+#define USE_SHORT_G1 BIT(20)
+
+#define _AGGLMT_MCS0(x) ((x) & 0xF)
+#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
+#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
+#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
+#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
+#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
+#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
+#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
+
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_LONG_SHIFT 0
+
+#define _DARF_RC1(x) ((x) & 0x1F)
+#define _DARF_RC2(x) (((x) & 0x1F) << 8)
+#define _DARF_RC3(x) (((x) & 0x1F) << 16)
+#define _DARF_RC4(x) (((x) & 0x1F) << 24)
+#define _DARF_RC5(x) ((x) & 0x1F)
+#define _DARF_RC6(x) (((x) & 0x1F) << 8)
+#define _DARF_RC7(x) (((x) & 0x1F) << 16)
+#define _DARF_RC8(x) (((x) & 0x1F) << 24)
+
+#define _RARF_RC1(x) ((x) & 0x1F)
+#define _RARF_RC2(x) (((x) & 0x1F) << 8)
+#define _RARF_RC3(x) (((x) & 0x1F) << 16)
+#define _RARF_RC4(x) (((x) & 0x1F) << 24)
+#define _RARF_RC5(x) ((x) & 0x1F)
+#define _RARF_RC6(x) (((x) & 0x1F) << 8)
+#define _RARF_RC7(x) (((x) & 0x1F) << 16)
+#define _RARF_RC8(x) (((x) & 0x1F) << 24)
+
+#define AC_PARAM_TXOP_LIMIT_OFFSET 16
+#define AC_PARAM_ECW_MAX_OFFSET 12
+#define AC_PARAM_ECW_MIN_OFFSET 8
+#define AC_PARAM_AIFS_OFFSET 0
+
+#define _AIFS(x) (x)
+#define _ECW_MAX_MIN(x) ((x) << 8)
+#define _TXOP_LIMIT(x) ((x) << 16)
+
+#define _BCNIFS(x) ((x) & 0xFF)
+#define _BCNECW(x) ((((x) & 0xF)) << 8)
+
+#define _LRL(x) ((x) & 0x3F)
+#define _SRL(x) (((x) & 0x3F) << 8)
+
+#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
+#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
+
+#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
+#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
+
+#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
+
+#define DIS_EDCA_CNT_DWN BIT(11)
+
+#define EN_MBSSID BIT(1)
+#define EN_TXBCN_RPT BIT(2)
+#define EN_BCN_FUNCTION BIT(3)
+
+#define TSFTR_RST BIT(0)
+#define TSFTR1_RST BIT(1)
+
+#define STOP_BCNQ BIT(6)
+
+#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
+#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
+
+#define AcmHw_HwEn BIT(0)
+#define AcmHw_BeqEn BIT(1)
+#define AcmHw_ViqEn BIT(2)
+#define AcmHw_VoqEn BIT(3)
+#define AcmHw_BeqStatus BIT(4)
+#define AcmHw_ViqStatus BIT(5)
+#define AcmHw_VoqStatus BIT(6)
+
+#define APSDOFF BIT(6)
+#define APSDOFF_STATUS BIT(7)
+
+#define BW_20MHZ BIT(2)
+
+#define RATE_BITMAP_ALL 0xFFFFF
+
+#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
+
+#define TSFRST BIT(0)
+#define DIS_GCLK BIT(1)
+#define PAD_SEL BIT(2)
+#define PWR_ST BIT(6)
+#define PWRBIT_OW_EN BIT(7)
+#define ACRC BIT(8)
+#define CFENDFORM BIT(9)
+#define ICV BIT(10)
+
+#define AAP BIT(0)
+#define APM BIT(1)
+#define AM BIT(2)
+#define AB BIT(3)
+#define ADD3 BIT(4)
+#define APWRMGT BIT(5)
+#define CBSSID BIT(6)
+#define CBSSID_DATA BIT(6)
+#define CBSSID_BCN BIT(7)
+#define ACRC32 BIT(8)
+#define AICV BIT(9)
+#define ADF BIT(11)
+#define ACF BIT(12)
+#define AMF BIT(13)
+#define HTC_LOC_CTRL BIT(14)
+#define UC_DATA_EN BIT(16)
+#define BM_DATA_EN BIT(17)
+#define MFBEN BIT(22)
+#define LSIGEN BIT(23)
+#define EnMBID BIT(24)
+#define APP_BASSN BIT(27)
+#define APP_PHYSTS BIT(28)
+#define APP_ICV BIT(29)
+#define APP_MIC BIT(30)
+#define APP_FCS BIT(31)
+
+#define _MIN_SPACE(x) ((x) & 0x7)
+#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
+
+#define RXERR_TYPE_OFDM_PPDU 0
+#define RXERR_TYPE_OFDM_FALSE_ALARM 1
+#define RXERR_TYPE_OFDM_MPDU_OK 2
+#define RXERR_TYPE_OFDM_MPDU_FAIL 3
+#define RXERR_TYPE_CCK_PPDU 4
+#define RXERR_TYPE_CCK_FALSE_ALARM 5
+#define RXERR_TYPE_CCK_MPDU_OK 6
+#define RXERR_TYPE_CCK_MPDU_FAIL 7
+#define RXERR_TYPE_HT_PPDU 8
+#define RXERR_TYPE_HT_FALSE_ALARM 9
+#define RXERR_TYPE_HT_MPDU_TOTAL 10
+#define RXERR_TYPE_HT_MPDU_OK 11
+#define RXERR_TYPE_HT_MPDU_FAIL 12
+#define RXERR_TYPE_RX_FULL_DROP 15
+
+#define RXERR_COUNTER_MASK 0xFFFFF
+#define RXERR_RPT_RST BIT(27)
+#define _RXERR_RPT_SEL(type) ((type) << 28)
+
+#define SCR_TxUseDK BIT(0)
+#define SCR_RxUseDK BIT(1)
+#define SCR_TxEncEnable BIT(2)
+#define SCR_RxDecEnable BIT(3)
+#define SCR_SKByA2 BIT(4)
+#define SCR_NoSKMC BIT(5)
+#define SCR_TXBCUSEDK BIT(6)
+#define SCR_RXBCUSEDK BIT(7)
+
+#define USB_IS_HIGH_SPEED 0
+#define USB_IS_FULL_SPEED 1
+#define USB_SPEED_MASK BIT(5)
+
+#define USB_NORMAL_SIE_EP_MASK 0xF
+#define USB_NORMAL_SIE_EP_SHIFT 4
+
+#define USB_TEST_EP_MASK 0x30
+#define USB_TEST_EP_SHIFT 4
+
+#define USB_AGG_EN BIT(3)
+
+#define MAC_ADDR_LEN 6
+#define LAST_ENTRY_OF_TX_PKT_BUFFER 255
+
+#define POLLING_LLT_THRESHOLD 20
+#define POLLING_READY_TIMEOUT_COUNT 1000
+
+#define MAX_MSS_DENSITY_2T 0x13
+#define MAX_MSS_DENSITY_1T 0x0A
+
+#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
+#define EPROM_CMD_CONFIG 0x3
+#define EPROM_CMD_LOAD 1
+
+#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
+
+#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
+
+#define RPMAC_RESET 0x100
+#define RPMAC_TXSTART 0x104
+#define RPMAC_TXLEGACYSIG 0x108
+#define RPMAC_TXHTSIG1 0x10c
+#define RPMAC_TXHTSIG2 0x110
+#define RPMAC_PHYDEBUG 0x114
+#define RPMAC_TXPACKETNUM 0x118
+#define RPMAC_TXIDLE 0x11c
+#define RPMAC_TXMACHEADER0 0x120
+#define RPMAC_TXMACHEADER1 0x124
+#define RPMAC_TXMACHEADER2 0x128
+#define RPMAC_TXMACHEADER3 0x12c
+#define RPMAC_TXMACHEADER4 0x130
+#define RPMAC_TXMACHEADER5 0x134
+#define RPMAC_TXDADATYPE 0x138
+#define RPMAC_TXRANDOMSEED 0x13c
+#define RPMAC_CCKPLCPPREAMBLE 0x140
+#define RPMAC_CCKPLCPHEADER 0x144
+#define RPMAC_CCKCRC16 0x148
+#define RPMAC_OFDMRXCRC32OK 0x170
+#define RPMAC_OFDMRXCRC32Er 0x174
+#define RPMAC_OFDMRXPARITYER 0x178
+#define RPMAC_OFDMRXCRC8ER 0x17c
+#define RPMAC_CCKCRXRC16ER 0x180
+#define RPMAC_CCKCRXRC32ER 0x184
+#define RPMAC_CCKCRXRC32OK 0x188
+#define RPMAC_TXSTATUS 0x18c
+
+#define RFPGA0_RFMOD 0x800
+
+#define RFPGA0_TXINFO 0x804
+#define RFPGA0_PSDFUNCTION 0x808
+
+#define RFPGA0_TXGAINSTAGE 0x80c
+
+#define RFPGA0_RFTIMING1 0x810
+#define RFPGA0_RFTIMING2 0x814
+
+#define RFPGA0_XA_HSSIPARAMETER1 0x820
+#define RFPGA0_XA_HSSIPARAMETER2 0x824
+#define RFPGA0_XB_HSSIPARAMETER1 0x828
+#define RFPGA0_XB_HSSIPARAMETER2 0x82c
+
+#define RFPGA0_XA_LSSIPARAMETER 0x840
+#define RFPGA0_XB_LSSIPARAMETER 0x844
+
+#define RFPGA0_RFWAKEUPPARAMETER 0x850
+#define RFPGA0_RFSLEEPUPPARAMETER 0x854
+
+#define RFPGA0_XAB_SWITCHCONTROL 0x858
+#define RFPGA0_XCD_SWITCHCONTROL 0x85c
+
+#define RFPGA0_XA_RFINTERFACEOE 0x860
+#define RFPGA0_XB_RFINTERFACEOE 0x864
+
+#define RFPGA0_XAB_RFINTERFACESW 0x870
+#define RFPGA0_XCD_RFINTERFACESW 0x874
+
+#define rFPGA0_XAB_RFPARAMETER 0x878
+#define rFPGA0_XCD_RFPARAMETER 0x87c
+
+#define RFPGA0_ANALOGPARAMETER1 0x880
+#define RFPGA0_ANALOGPARAMETER2 0x884
+#define RFPGA0_ANALOGPARAMETER3 0x888
+#define RFPGA0_ANALOGPARAMETER4 0x88c
+
+#define RFPGA0_XA_LSSIREADBACK 0x8a0
+#define RFPGA0_XB_LSSIREADBACK 0x8a4
+#define RFPGA0_XC_LSSIREADBACK 0x8a8
+#define RFPGA0_XD_LSSIREADBACK 0x8ac
+
+#define RFPGA0_PSDREPORT 0x8b4
+#define TRANSCEIVEA_HSPI_READBACK 0x8b8
+#define TRANSCEIVEB_HSPI_READBACK 0x8bc
+#define RFPGA0_XAB_RFINTERFACERB 0x8e0
+#define RFPGA0_XCD_RFINTERFACERB 0x8e4
+
+#define RFPGA1_RFMOD 0x900
+
+#define RFPGA1_TXBLOCK 0x904
+#define RFPGA1_DEBUGSELECT 0x908
+#define RFPGA1_TXINFO 0x90c
+
+#define RCCK0_SYSTEM 0xa00
+
+#define RCCK0_AFESETTING 0xa04
+#define RCCK0_CCA 0xa08
+
+#define RCCK0_RXAGC1 0xa0c
+#define RCCK0_RXAGC2 0xa10
+
+#define RCCK0_RXHP 0xa14
+
+#define RCCK0_DSPPARAMETER1 0xa18
+#define RCCK0_DSPPARAMETER2 0xa1c
+
+#define RCCK0_TXFILTER1 0xa20
+#define RCCK0_TXFILTER2 0xa24
+#define RCCK0_DEBUGPORT 0xa28
+#define RCCK0_FALSEALARMREPORT 0xa2c
+#define RCCK0_TRSSIREPORT 0xa50
+#define RCCK0_RXREPORT 0xa54
+#define RCCK0_FACOUNTERLOWER 0xa5c
+#define RCCK0_FACOUNTERUPPER 0xa58
+
+#define ROFDM0_LSTF 0xc00
+
+#define ROFDM0_TRXPATHENABLE 0xc04
+#define ROFDM0_TRMUXPAR 0xc08
+#define ROFDM0_TRSWISOLATION 0xc0c
+
+#define ROFDM0_XARXAFE 0xc10
+#define ROFDM0_XARXIQIMBALANCE 0xc14
+#define ROFDM0_XBRXAFE 0xc18
+#define ROFDM0_XBRXIQIMBALANCE 0xc1c
+#define ROFDM0_XCRXAFE 0xc20
+#define ROFDM0_XCRXIQIMBANLANCE 0xc24
+#define ROFDM0_XDRXAFE 0xc28
+#define ROFDM0_XDRXIQIMBALANCE 0xc2c
+
+#define ROFDM0_RXDETECTOR1 0xc30
+#define ROFDM0_RXDETECTOR2 0xc34
+#define ROFDM0_RXDETECTOR3 0xc38
+#define ROFDM0_RXDETECTOR4 0xc3c
+
+#define ROFDM0_RXDSP 0xc40
+#define ROFDM0_CFOANDDAGC 0xc44
+#define ROFDM0_CCADROPTHRESHOLD 0xc48
+#define ROFDM0_ECCATHRESHOLD 0xc4c
+
+#define ROFDM0_XAAGCCORE1 0xc50
+#define ROFDM0_XAAGCCORE2 0xc54
+#define ROFDM0_XBAGCCORE1 0xc58
+#define ROFDM0_XBAGCCORE2 0xc5c
+#define ROFDM0_XCAGCCORE1 0xc60
+#define ROFDM0_XCAGCCORE2 0xc64
+#define ROFDM0_XDAGCCORE1 0xc68
+#define ROFDM0_XDAGCCORE2 0xc6c
+
+#define ROFDM0_AGCPARAMETER1 0xc70
+#define ROFDM0_AGCPARAMETER2 0xc74
+#define ROFDM0_AGCRSSITABLE 0xc78
+#define ROFDM0_HTSTFAGC 0xc7c
+
+#define ROFDM0_XATXIQIMBALANCE 0xc80
+#define ROFDM0_XATXAFE 0xc84
+#define ROFDM0_XBTXIQIMBALANCE 0xc88
+#define ROFDM0_XBTXAFE 0xc8c
+#define ROFDM0_XCTXIQIMBALANCE 0xc90
+#define ROFDM0_XCTXAFE 0xc94
+#define ROFDM0_XDTXIQIMBALANCE 0xc98
+#define ROFDM0_XDTXAFE 0xc9c
+
+#define ROFDM0_RXIQEXTANTA 0xca0
+
+#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
+
+#define ROFDM1_LSTF 0xd00
+#define ROFDM1_TRXPATHENABLE 0xd04
+
+#define ROFDM1_CF0 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
+#define ROFDM_PHYCOUNTER2 0xda4
+#define ROFDM_PHYCOUNTER3 0xda8
+
+#define ROFDM_SHORTCFOAB 0xdac
+#define ROFDM_SHORTCFOCD 0xdb0
+#define ROFDM_LONGCFOAB 0xdb4
+#define ROFDM_LONGCFOCD 0xdb8
+#define ROFDM_TAILCF0AB 0xdbc
+#define ROFDM_TAILCF0CD 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
+
+#define RTXAGC_A_RATE18_06 0xe00
+#define RTXAGC_A_RATE54_24 0xe04
+#define RTXAGC_A_CCK1_MCS32 0xe08
+#define RTXAGC_A_MCS03_MCS00 0xe10
+#define RTXAGC_A_MCS07_MCS04 0xe14
+#define RTXAGC_A_MCS11_MCS08 0xe18
+#define RTXAGC_A_MCS15_MCS12 0xe1c
+
+#define RTXAGC_B_RATE18_06 0x830
+#define RTXAGC_B_RATE54_24 0x834
+#define RTXAGC_B_CCK1_55_MCS32 0x838
+#define RTXAGC_B_MCS03_MCS00 0x83c
+#define RTXAGC_B_MCS07_MCS04 0x848
+#define RTXAGC_B_MCS11_MCS08 0x84c
+#define RTXAGC_B_MCS15_MCS12 0x868
+#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
+
+#define RZEBRA1_HSSIENABLE 0x0
+#define RZEBRA1_TRXENABLE1 0x1
+#define RZEBRA1_TRXENABLE2 0x2
+#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_RXHPFCORNER 0xc
+
+#define RGLOBALCTRL 0
+#define RRTL8256_TXLPF 19
+#define RRTL8256_RXLPF 11
+#define RRTL8258_TXLPF 0x11
+#define RRTL8258_RXLPF 0x13
+#define RRTL8258_RSSILPF 0xa
+
+#define RF_AC 0x00
+
+#define RF_IQADJ_G1 0x01
+#define RF_IQADJ_G2 0x02
+#define RF_POW_TRSW 0x05
+
+#define RF_GAIN_RX 0x06
+#define RF_GAIN_TX 0x07
+
+#define RF_TXM_IDAC 0x08
+#define RF_BS_IQGEN 0x0F
+
+#define RF_MODE1 0x10
+#define RF_MODE2 0x11
+
+#define RF_RX_AGC_HP 0x12
+#define RF_TX_AGC 0x13
+#define RF_BIAS 0x14
+#define RF_IPA 0x15
+#define RF_POW_ABILITY 0x17
+#define RF_MODE_AG 0x18
+#define RRFCHANNEL 0x18
+#define RF_CHNLBW 0x18
+#define RF_TOP 0x19
+
+#define RF_RX_G1 0x1A
+#define RF_RX_G2 0x1B
+
+#define RF_RX_BB2 0x1C
+#define RF_RX_BB1 0x1D
+
+#define RF_RCK1 0x1E
+#define RF_RCK2 0x1F
+
+#define RF_TX_G1 0x20
+#define RF_TX_G2 0x21
+#define RF_TX_G3 0x22
+
+#define RF_TX_BB1 0x23
+#define RF_T_METER 0x24
+
+#define RF_SYN_G1 0x25
+#define RF_SYN_G2 0x26
+#define RF_SYN_G3 0x27
+#define RF_SYN_G4 0x28
+#define RF_SYN_G5 0x29
+#define RF_SYN_G6 0x2A
+#define RF_SYN_G7 0x2B
+#define RF_SYN_G8 0x2C
+
+#define RF_RCK_OS 0x30
+#define RF_TXPA_G1 0x31
+#define RF_TXPA_G2 0x32
+#define RF_TXPA_G3 0x33
+
+#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_LT F 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 BCCKTXLENGHT 0xffff0000
+#define BCCKTXCRC16 0xffff
+#define BCCKTXSTATUS 0x1
+#define BOFDMTXSTATUS 0x2
+#define IS_BB_REG_OFFSET_92S(_Offset) \
+ ((_Offset >= 0x800) && (_Offset <= 0xfff))
+
+#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
+#define BTREND 0x0f000000
+#define BRFEND 0x000f0000
+#define BCCAMASK 0x000000f0
+#define BR2RCCAMASK 0x00000f00
+#define BHSSI_R2TDELAY 0xf8000000
+#define BHSSI_T2RDELAY 0xf80000
+#define BCONTXHSSI 0x400
+#define BIGFROMCCK 0x200
+#define BAGCADDRESS 0x3f
+#define BRXHPTX 0x7000
+#define BRXHP2RX 0x38000
+#define BRXHPCCKINI 0xc0000
+#define BAGCTXCODE 0xc00000
+#define BAGCRXCODE 0x300000
+
+#define B3WIREDATALENGTH 0x800
+#define B3WIREADDREAALENGTH 0x400
+
+#define B3WIRERFPOWERDOWN 0x1
+#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
+
+#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 0x7f800000
+#define BLSSIREADEDGE 0x80000000
+
+#define BLSSIREADBACKDATA 0xfffff
+
+#define BLSSIREADOKFLAG 0x1000
+#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 BXTALCAP01 0xc0000000
+#define BXTALCAP23 0x3
+#define BXTALCAP92X 0x0f000000
+#define BXTALCAP 0x0f000000
+
+#define BINTDIFCLKENABLE 0x400
+#define BEXTSIGCLKENABLE 0x800
+#define BBANDGAP_MBIAS_POWERUP 0x10000
+#define BAD11SH_GAIN 0xc0000
+#define BAD11NPUT_RANGE 0x700000
+#define BAD110P_CURRENT 0x3800000
+#define BLPATH_LOOPBACK 0x4000000
+#define BQPATH_LOOPBACK 0x8000000
+#define BAFE_LOOPBACK 0x10000000
+#define BDA10_SWING 0x7e0
+#define BDA10_REVERSE 0x800
+#define BDA_CLK_SOURCE 0x1000
+#define BDA7INPUT_RANGE 0x6000
+#define BDA7_GAIN 0x38000
+#define BDA7OUTPUT_CM_MODE 0x40000
+#define BDA7INPUT_CM_MODE 0x380000
+#define BDA7CURRENT 0xc00000
+#define BREGULATOR_ADJUST 0x7000000
+#define BAD11POWERUP_ATTX 0x1
+#define BDA10PS_ATTX 0x10
+#define BAD11POWERUP_ATRX 0x100
+#define BDA10PS_ATRX 0x1000
+#define BCCKRX_AGC_FORMAT 0x200
+#define BPSDFFT_SAMPLE_POINT 0xc000
+#define BPSD_AVERAGE_NUM 0x3000
+#define BIQPATH_CONTROL 0xc00
+#define BPSD_FREQ 0x3ff
+#define BPSD_ANTENNA_PATH 0x30
+#define BPSD_IQ_SWITCH 0x40
+#define BPSD_RX_TRIGGER 0x400000
+#define BPSD_TX_TRIGGER 0x80000000
+#define BPSD_SINE_TONE_SCALE 0x7f000000
+#define BPSD_REPORT 0xffff
+
+#define BOFDM_TXSC 0x30000000
+#define BCCK_TXON 0x1
+#define BOFDM_TXON 0x2
+#define BDEBUG_PAGE 0xfff
+#define BDEBUG_ITEM 0xff
+#define BANTL 0x10
+#define BANT_NONHT 0x100
+#define BANT_HT1 0x1000
+#define BANT_HT2 0x10000
+#define BANT_HT1S1 0x100000
+#define BANT_NONHTS1 0x1000000
+
+#define BCCK_BBMODE 0x3
+#define BCCK_TXPOWERSAVING 0x80
+#define BCCK_RXPOWERSAVING 0x40
+
+#define BCCK_SIDEBAND 0x10
+
+#define BCCK_SCRAMBLE 0x8
+#define BCCK_ANTDIVERSITY 0x8000
+#define BCCK_CARRIER_RECOVERY 0x4000
+#define BCCK_TXRATE 0x3000
+#define BCCK_DCCANCEL 0x0800
+#define BCCK_ISICANCEL 0x0400
+#define BCCK_MATCH_FILTER 0x0200
+#define BCCK_EQUALIZER 0x0100
+#define BCCK_PREAMBLE_DETECT 0x800000
+#define BCCK_FAST_FALSECCA 0x400000
+#define BCCK_CH_ESTSTART 0x300000
+#define BCCK_CCA_COUNT 0x080000
+#define BCCK_CS_LIM 0x070000
+#define BCCK_BIST_MODE 0x80000000
+#define BCCK_CCAMASK 0x40000000
+#define BCCK_TX_DAC_PHASE 0x4
+#define BCCK_RX_ADC_PHASE 0x20000000
+#define BCCKR_CP_MODE 0x0100
+#define BCCK_TXDC_OFFSET 0xf0
+#define BCCK_RXDC_OFFSET 0xf
+#define BCCK_CCA_MODE 0xc000
+#define BCCK_FALSECS_LIM 0x3f00
+#define BCCK_CS_RATIO 0xc00000
+#define BCCK_CORGBIT_SEL 0x300000
+#define BCCK_PD_LIM 0x0f0000
+#define BCCK_NEWCCA 0x80000000
+#define BCCK_RXHP_OF_IG 0x8000
+#define BCCK_RXIG 0x7f00
+#define BCCK_LNA_POLARITY 0x800000
+#define BCCK_RX1ST_BAIN 0x7f0000
+#define BCCK_RF_EXTEND 0x20000000
+#define BCCK_RXAGC_SATLEVEL 0x1f000000
+#define BCCK_RXAGC_SATCOUNT 0xe0
+#define bCCKRxRFSettle 0x1f
+#define BCCK_FIXED_RXAGC 0x8000
+#define BCCK_ANTENNA_POLARITY 0x2000
+#define BCCK_TXFILTER_TYPE 0x0c00
+#define BCCK_RXAGC_REPORTTYPE 0x0300
+#define BCCK_RXDAGC_EN 0x80000000
+#define BCCK_RXDAGC_PERIOD 0x20000000
+#define BCCK_RXDAGC_SATLEVEL 0x1f000000
+#define BCCK_TIMING_RECOVERY 0x800000
+#define BCCK_TXC0 0x3f0000
+#define BCCK_TXC1 0x3f000000
+#define BCCK_TXC2 0x3f
+#define BCCK_TXC3 0x3f00
+#define BCCK_TXC4 0x3f0000
+#define BCCK_TXC5 0x3f000000
+#define BCCK_TXC6 0x3f
+#define BCCK_TXC7 0x3f00
+#define BCCK_DEBUGPORT 0xff0000
+#define BCCK_DAC_DEBUG 0x0f000000
+#define BCCK_FALSEALARM_ENABLE 0x8000
+#define BCCK_FALSEALARM_READ 0x4000
+#define BCCK_TRSSI 0x7f
+#define BCCK_RXAGC_REPORT 0xfe
+#define BCCK_RXREPORT_ANTSEL 0x80000000
+#define BCCK_RXREPORT_MFOFF 0x40000000
+#define BCCK_RXREPORT_SQLOSS 0x20000000
+#define BCCK_RXREPORT_PKTLOSS 0x10000000
+#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
+#define BCCK_RXREPORT_RATEERROR 0x04000000
+#define BCCK_RXREPORT_RXRATE 0x03000000
+#define BCCK_RXFA_COUNTER_LOWER 0xff
+#define BCCK_RXFA_COUNTER_UPPER 0xff000000
+#define BCCK_RXHPAGC_START 0xe000
+#define BCCK_RXHPAGC_FINAL 0x1c00
+#define BCCK_RXFALSEALARM_ENABLE 0x8000
+#define BCCK_FACOUNTER_FREEZE 0x4000
+#define BCCK_TXPATH_SEL 0x10000000
+#define BCCK_DEFAULT_RXPATH 0xc000000
+#define BCCK_OPTION_RXPATH 0x3000000
+
+#define BNUM_OFSTF 0x3
+#define BSHIFT_L 0xc0
+#define BGI_TH 0xc
+#define BRXPATH_A 0x1
+#define BRXPATH_B 0x2
+#define BRXPATH_C 0x4
+#define BRXPATH_D 0x8
+#define BTXPATH_A 0x1
+#define BTXPATH_B 0x2
+#define BTXPATH_C 0x4
+#define BTXPATH_D 0x8
+#define BTRSSI_FREQ 0x200
+#define BADC_BACKOFF 0x3000
+#define BDFIR_BACKOFF 0xc000
+#define BTRSSI_LATCH_PHASE 0x10000
+#define BRX_LDC_OFFSET 0xff
+#define BRX_QDC_OFFSET 0xff00
+#define BRX_DFIR_MODE 0x1800000
+#define BRX_DCNF_TYPE 0xe000000
+#define BRXIQIMB_A 0x3ff
+#define BRXIQIMB_B 0xfc00
+#define BRXIQIMB_C 0x3f0000
+#define BRXIQIMB_D 0xffc00000
+#define BDC_DC_NOTCH 0x60000
+#define BRXNB_NOTCH 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 BRADIO_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 BCFOLOOPBACK 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 BTXIQDCOFFSET 0xff00
+#define BTXDFIRMODE 0x10000
+#define BTXPESUDO_NOISEON 0x4000000
+#define BTXPESUDO_NOISE_A 0xff
+#define BTXPESUDO_NOISE_B 0xff00
+#define BTXPESUDO_NOISE_C 0xff0000
+#define BTXPESUDO_NOISE_D 0xff000000
+#define BCCA_DROPOPTION 0x20000
+#define BCCA_DROPTHRES 0xfff00000
+#define BEDCCA_H 0xf
+#define BEDCCA_L 0xf0
+#define BLAMBDA_ED 0x300
+#define BRX_INITIALGAIN 0x7f
+#define BRX_ANTDIV_EN 0x80
+#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
+#define BRX_HIGHPOWER_FLOW 0x8000
+#define BRX_AGC_FREEZE_THRES 0xc0000
+#define BRX_FREEZESTEP_AGC1 0x300000
+#define BRX_FREEZESTEP_AGC2 0xc00000
+#define BRX_FREEZESTEP_AGC3 0x3000000
+#define BRX_FREEZESTEP_AGC0 0xc000000
+#define BRXRSSI_CMP_EN 0x10000000
+#define BRXQUICK_AGCEN 0x20000000
+#define BRXAGC_FREEZE_THRES_MODE 0x40000000
+#define BRX_OVERFLOW_CHECKTYPE 0x80000000
+#define BRX_AGCSHIFT 0x7f
+#define BTRSW_TRI_ONLY 0x80
+#define BPOWER_THRES 0x300
+#define BRXAGC_EN 0x1
+#define BRXAGC_TOGETHER_EN 0x2
+#define BRXAGC_MIN 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
+#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 BRXPROCESS_TIME_DAGC 0x300000
+#define BRXSETTLE_HSSI 0x400000
+#define BRXPROCESS_TIME_BBPPW 0x800000
+#define BRXANTENNA_POWER_SHIFT 0x3000000
+#define BRSSI_TABLE_SELECT 0xc000000
+#define BRXHP_FINAL 0x7000000
+#define BRXHPSETTLE_BBP 0x7
+#define BRXHTSETTLE_HSSI 0x8
+#define BRXHTSETTLE_RXHP 0x70
+#define BRXHTSETTLE_BBPPW 0x80
+#define BRXHTSETTLE_IDLE 0x300
+#define BRXHTSETTLE_RESERVED 0x1c00
+#define BRXHT_RXHP_EN 0x8000
+#define BRXAGC_FREEZE_THRES 0x30000
+#define BRXAGC_TOGETHEREN 0x40000
+#define BRXHTAGC_MIN 0x80000
+#define BRXHTAGC_EN 0x100000
+#define BRXHTDAGC_EN 0x200000
+#define BRXHT_RXHP_BBP 0x1c00000
+#define BRXHT_RXHP_FINAL 0xe0000000
+#define BRXPW_RADIO_TH 0x3
+#define BRXPW_RADIO_EN 0x4
+#define BRXMF_HOLD 0x3800
+#define BRXPD_DELAY_TH1 0x38
+#define BRXPD_DELAY_TH2 0x1c0
+#define BRXPD_DC_COUNT_MAX 0x600
+#define BRXPD_DELAY_TH 0x8000
+#define BRXPROCESS_DELAY 0xf0000
+#define BRXSEARCHRANGE_GI2_EARLY 0x700000
+#define BRXFRAME_FUARD_COUNTER_L 0x3800000
+#define BRXSGI_GUARD_L 0xc000000
+#define BRXSGI_SEARCH_L 0x30000000
+#define BRXSGI_TH 0xc0000000
+#define BDFSCNT0 0xff
+#define BDFSCNT1 0xff00
+#define BDFSFLAG 0xf0000
+#define BMF_WEIGHT_SUM 0x300000
+#define BMINIDX_TH 0x7f000000
+#define BDAFORMAT 0x40000
+#define BTXCH_EMU_ENABLE 0x01000000
+#define BTRSW_ISOLATION_A 0x7f
+#define BTRSW_ISOLATION_B 0x7f00
+#define BTRSW_ISOLATION_C 0x7f0000
+#define BTRSW_ISOLATION_D 0x7f000000
+#define BEXT_LNA_GAIN 0x7c00
+
+#define BSTBC_EN 0x4
+#define BANTENNA_MAPPING 0x10
+#define BNSS 0x20
+#define BCFO_ANTSUM_ID 0x200
+#define BPHY_COUNTER_RESET 0x8000000
+#define BCFO_REPORT_GET 0x4000000
+#define BOFDM_CONTINUE_TX 0x10000000
+#define BOFDM_SINGLE_CARRIER 0x20000000
+#define BOFDM_SINGLE_TONE 0x40000000
+#define BHT_DETECT 0x100
+#define BCFOEN 0x10000
+#define BCFOVALUE 0xfff00000
+#define BSIGTONE_RE 0x3f
+#define BSIGTONE_IM 0x7f00
+#define BCOUNTER_CCA 0xffff
+#define BCOUNTER_PARITYFAIL 0xffff0000
+#define BCOUNTER_RATEILLEGAL 0xffff
+#define BCOUNTER_CRC8FAIL 0xffff0000
+#define BCOUNTER_MCSNOSUPPORT 0xffff
+#define BCOUNTER_FASTSYNC 0xffff
+#define BSHORTCFO 0xfff
+#define BSHORTCFOT_LENGTH 12
+#define BSHORTCFOF_LENGTH 11
+#define BLONGCFO 0x7ff
+#define BLONGCFOT_LENGTH 11
+#define BLONGCFOF_LENGTH 11
+#define BTAILCFO 0x1fff
+#define BTAILCFOT_LENGTH 13
+#define BTAILCFOF_LENGTH 12
+#define BNOISE_EN_PWDB 0xffff
+#define BCC_POWER_DB 0xffff0000
+#define BMOISE_PWDB 0xffff
+#define BPOWERMEAST_LENGTH 10
+#define BPOWERMEASF_LENGTH 3
+#define BRX_HT_BW 0x1
+#define BRXSC 0x6
+#define BRX_HT 0x8
+#define BNB_INTF_DET_ON 0x1
+#define BINTF_WIN_LEN_CFG 0x30
+#define BNB_INTF_TH_CFG 0x1c0
+#define BRFGAIN 0x3f
+#define BTABLESEL 0x40
+#define BTRSW 0x80
+#define BRXSNR_A 0xff
+#define BRXSNR_B 0xff00
+#define BRXSNR_C 0xff0000
+#define BRXSNR_D 0xff000000
+#define BSNR_EVMT_LENGTH 8
+#define BSNR_EVMF_LENGTH 1
+#define BCSI1ST 0xff
+#define BCSI2ND 0xff00
+#define BRXEVM1ST 0xff0000
+#define BRXEVM2ND 0xff000000
+#define BSIGEVM 0xff
+#define BPWDB 0xff00
+#define BSGIEN 0x10000
+
+#define BSFACTOR_QMA1 0xf
+#define BSFACTOR_QMA2 0xf0
+#define BSFACTOR_QMA3 0xf00
+#define BSFACTOR_QMA4 0xf000
+#define BSFACTOR_QMA5 0xf0000
+#define BSFACTOR_QMA6 0xf0000
+#define BSFACTOR_QMA7 0xf00000
+#define BSFACTOR_QMA8 0xf000000
+#define BSFACTOR_QMA9 0xf0000000
+#define BCSI_SCHEME 0x100000
+
+#define BNOISE_LVL_TOP_SET 0x3
+#define BCHSMOOTH 0x4
+#define BCHSMOOTH_CFG1 0x38
+#define BCHSMOOTH_CFG2 0x1c0
+#define BCHSMOOTH_CFG3 0xe00
+#define BCHSMOOTH_CFG4 0x7000
+#define BMRCMODE 0x800000
+#define BTHEVMCFG 0x7000000
+
+#define BLOOP_FIT_TYPE 0x1
+#define BUPD_CFO 0x40
+#define BUPD_CFO_OFFDATA 0x80
+#define BADV_UPD_CFO 0x100
+#define BADV_TIME_CTRL 0x800
+#define BUPD_CLKO 0x1000
+#define BFC 0x6000
+#define BTRACKING_MODE 0x8000
+#define BPHCMP_ENABLE 0x10000
+#define BUPD_CLKO_LTF 0x20000
+#define BCOM_CH_CFO 0x40000
+#define BCSI_ESTI_MODE 0x80000
+#define BADV_UPD_EQZ 0x100000
+#define BUCHCFG 0x7000000
+#define BUPDEQZ 0x8000000
+
+#define BRX_PESUDO_NOISE_ON 0x20000000
+#define BRX_PESUDO_NOISE_A 0xff
+#define BRX_PESUDO_NOISE_B 0xff00
+#define BRX_PESUDO_NOISE_C 0xff0000
+#define BRX_PESUDO_NOISE_D 0xff000000
+#define BRX_PESUDO_NOISESTATE_A 0xffff
+#define BRX_PESUDO_NOISESTATE_B 0xffff0000
+#define BRX_PESUDO_NOISESTATE_C 0xffff
+#define BRX_PESUDO_NOISESTATE_D 0xffff0000
+
+#define BZEBRA1_HSSIENABLE 0x8
+#define BZEBRA1_TRXCONTROL 0xc00
+#define BZEBRA1_TRXGAINSETTING 0x07f
+#define BZEBRA1_RXCOUNTER 0xc00
+#define BZEBRA1_TXCHANGEPUMP 0x38
+#define BZEBRA1_RXCHANGEPUMP 0x7
+#define BZEBRA1_CHANNEL_NUM 0xf80
+#define BZEBRA1_TXLPFBW 0x400
+#define BZEBRA1_RXLPFBW 0x600
+
+#define BRTL8256REG_MODE_CTRL1 0x100
+#define BRTL8256REG_MODE_CTRL0 0x40
+#define BRTL8256REG_TXLPFBW 0x18
+#define BRTL8256REG_RXLPFBW 0x600
+
+#define BRTL8258_TXLPFBW 0xc
+#define BRTL8258_RXLPFBW 0xc00
+#define BRTL8258_RSSILPFBW 0xc0
+
+#define BBYTE0 0x1
+#define BBYTE1 0x2
+#define BBYTE2 0x4
+#define BBYTE3 0x8
+#define BWORD0 0x3
+#define BWORD1 0xc
+#define BWORD 0xf
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#define MASK4BITS 0x0f
+#define MASK20BITS 0xfffff
+#define RFREG_OFFSET_MASK 0xfffff
+
+#define BENABLE 0x1
+#define BDISABLE 0x0
+
+#define LEFT_ANTENNA 0x0
+#define RIGHT_ANTENNA 0x1
+
+#define TCHECK_TXSTATUS 500
+#define TUPDATE_RXCOUNTER 100
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
new file mode 100644
index 000000000000..ffd8e04c4028
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -0,0 +1,523 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+
+static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
+
+void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ switch (bandwidth) {
+ case HT_CHANNEL_WIDTH_20:
+ rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+ 0xfffff3ff) | 0x0400);
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[0]);
+ break;
+ case HT_CHANNEL_WIDTH_20_40:
+ rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+ 0xfffff3ff));
+ rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+ rtlphy->rfreg_chnlval[0]);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("unknown bandwidth: %#X\n", bandwidth));
+ break;
+ }
+}
+
+void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u32 tx_agc[2] = {0, 0}, tmpval;
+ bool turbo_scanoff = false;
+ u8 idx1, idx2;
+ u8 *ptr;
+
+ if (rtlefuse->eeprom_regulatory != 0)
+ turbo_scanoff = true;
+
+ if (mac->act_scanning == true) {
+ tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
+ tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
+
+ if (turbo_scanoff) {
+ for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+ tx_agc[idx1] = ppowerlevel[idx1] |
+ (ppowerlevel[idx1] << 8) |
+ (ppowerlevel[idx1] << 16) |
+ (ppowerlevel[idx1] << 24);
+ }
+ }
+ } else {
+ for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+ tx_agc[idx1] = ppowerlevel[idx1] |
+ (ppowerlevel[idx1] << 8) |
+ (ppowerlevel[idx1] << 16) |
+ (ppowerlevel[idx1] << 24);
+ }
+
+ if (rtlefuse->eeprom_regulatory == 0) {
+ tmpval =
+ (rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
+ (rtlphy->mcs_txpwrlevel_origoffset[0][7] <<
+ 8);
+ tx_agc[RF90_PATH_A] += tmpval;
+
+ tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
+ (rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
+ 24);
+ tx_agc[RF90_PATH_B] += tmpval;
+ }
+ }
+
+ for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+ ptr = (u8 *) (&(tx_agc[idx1]));
+ for (idx2 = 0; idx2 < 4; idx2++) {
+ if (*ptr > RF6052_MAX_TX_PWR)
+ *ptr = RF6052_MAX_TX_PWR;
+ ptr++;
+ }
+ }
+
+ tmpval = tx_agc[RF90_PATH_A] & 0xff;
+ rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
+ RTXAGC_A_CCK1_MCS32));
+
+ tmpval = tx_agc[RF90_PATH_A] >> 8;
+
+ if (mac->mode == WIRELESS_MODE_B)
+ tmpval = tmpval & 0xff00ffff;
+
+ rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
+ RTXAGC_B_CCK11_A_CCK2_11));
+
+ tmpval = tx_agc[RF90_PATH_B] >> 24;
+ rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
+ RTXAGC_B_CCK11_A_CCK2_11));
+
+ tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
+ rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
+ RTXAGC_B_CCK1_55_MCS32));
+}
+
+static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel,
+ u32 *ofdmbase, u32 *mcsbase)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u32 powerBase0, powerBase1;
+ u8 legacy_pwrdiff, ht20_pwrdiff;
+ u8 i, powerlevel[2];
+
+ for (i = 0; i < 2; i++) {
+ powerlevel[i] = ppowerlevel[i];
+ legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
+ powerBase0 = powerlevel[i] + legacy_pwrdiff;
+
+ powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
+ (powerBase0 << 8) | powerBase0;
+ *(ofdmbase + i) = powerBase0;
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ (" [OFDM power base index rf(%c) = 0x%x]\n",
+ ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
+ ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
+ powerlevel[i] += ht20_pwrdiff;
+ }
+ powerBase1 = powerlevel[i];
+ powerBase1 = (powerBase1 << 24) |
+ (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
+
+ *(mcsbase + i) = powerBase1;
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ (" [MCS power base index rf(%c) = 0x%x]\n",
+ ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+ }
+}
+
+static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
+ u8 channel, u8 index,
+ u32 *powerBase0,
+ u32 *powerBase1,
+ u32 *p_outwriteval)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ u8 i, chnlgroup, pwr_diff_limit[4];
+ u32 writeVal, customer_limit, rf;
+
+ for (rf = 0; rf < 2; rf++) {
+ switch (rtlefuse->eeprom_regulatory) {
+ case 0:
+ chnlgroup = 0;
+
+ writeVal =
+ rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index +
+ (rf ? 8 : 0)]
+ + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("RTK better performance, "
+ "writeVal(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ break;
+ case 1:
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ writeVal = ((index < 2) ? powerBase0[rf] :
+ powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Realtek regulatory, 40MHz, "
+ "writeVal(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ } else {
+ if (rtlphy->pwrgroup_cnt == 1)
+ chnlgroup = 0;
+ if (rtlphy->pwrgroup_cnt >= 3) {
+ if (channel <= 3)
+ chnlgroup = 0;
+ else if (channel >= 4 && channel <= 9)
+ chnlgroup = 1;
+ else if (channel > 9)
+ chnlgroup = 2;
+ if (rtlphy->pwrgroup_cnt == 4)
+ chnlgroup++;
+ }
+
+ writeVal =
+ rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
+ [index + (rf ? 8 : 0)] + ((index < 2) ?
+ powerBase0[rf] :
+ powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Realtek regulatory, 20MHz, "
+ "writeVal(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ }
+ break;
+ case 2:
+ writeVal =
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Better regulatory, "
+ "writeVal(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ break;
+ case 3:
+ chnlgroup = 0;
+
+ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("customer's limit, 40MHz "
+ "rf(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'),
+ rtlefuse->pwrgroup_ht40[rf][channel -
+ 1]));
+ } else {
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("customer's limit, 20MHz "
+ "rf(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'),
+ rtlefuse->pwrgroup_ht20[rf][channel -
+ 1]));
+ }
+ for (i = 0; i < 4; i++) {
+ pwr_diff_limit[i] =
+ (u8) ((rtlphy->mcs_txpwrlevel_origoffset
+ [chnlgroup][index +
+ (rf ? 8 : 0)] & (0x7f << (i * 8))) >>
+ (i * 8));
+
+ if (rtlphy->current_chan_bw ==
+ HT_CHANNEL_WIDTH_20_40) {
+ if (pwr_diff_limit[i] >
+ rtlefuse->
+ pwrgroup_ht40[rf][channel - 1])
+ pwr_diff_limit[i] =
+ rtlefuse->pwrgroup_ht40[rf]
+ [channel - 1];
+ } else {
+ if (pwr_diff_limit[i] >
+ rtlefuse->
+ pwrgroup_ht20[rf][channel - 1])
+ pwr_diff_limit[i] =
+ rtlefuse->pwrgroup_ht20[rf]
+ [channel - 1];
+ }
+ }
+
+ customer_limit = (pwr_diff_limit[3] << 24) |
+ (pwr_diff_limit[2] << 16) |
+ (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Customer's limit rf(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), customer_limit));
+
+ writeVal = customer_limit +
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Customer, writeVal rf(%c)= 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ break;
+ default:
+ chnlgroup = 0;
+ writeVal =
+ rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
+ [index + (rf ? 8 : 0)]
+ + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("RTK better performance, writeVal "
+ "rf(%c) = 0x%x\n",
+ ((rf == 0) ? 'A' : 'B'), writeVal));
+ break;
+ }
+
+ if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
+ writeVal = writeVal - 0x06060606;
+ else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+ TXHIGHPWRLEVEL_BT2)
+ writeVal = writeVal - 0x0c0c0c0c;
+ *(p_outwriteval + rf) = writeVal;
+ }
+}
+
+static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
+ u8 index, u32 *pValue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ u16 regoffset_a[6] = {
+ RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
+ RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
+ RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
+ };
+ u16 regoffset_b[6] = {
+ RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
+ RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
+ RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
+ };
+ u8 i, rf, pwr_val[4];
+ u32 writeVal;
+ u16 regoffset;
+
+ for (rf = 0; rf < 2; rf++) {
+ writeVal = pValue[rf];
+ for (i = 0; i < 4; i++) {
+ pwr_val[i] = (u8) ((writeVal & (0x7f <<
+ (i * 8))) >> (i * 8));
+
+ if (pwr_val[i] > RF6052_MAX_TX_PWR)
+ pwr_val[i] = RF6052_MAX_TX_PWR;
+ }
+ writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
+ (pwr_val[1] << 8) | pwr_val[0];
+
+ if (rf == 0)
+ regoffset = regoffset_a[index];
+ else
+ regoffset = regoffset_b[index];
+ rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
+
+ RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+ ("Set 0x%x = %08x\n", regoffset, writeVal));
+
+ if (((get_rf_type(rtlphy) == RF_2T2R) &&
+ (regoffset == RTXAGC_A_MCS15_MCS12 ||
+ regoffset == RTXAGC_B_MCS15_MCS12)) ||
+ ((get_rf_type(rtlphy) != RF_2T2R) &&
+ (regoffset == RTXAGC_A_MCS07_MCS04 ||
+ regoffset == RTXAGC_B_MCS07_MCS04))) {
+
+ writeVal = pwr_val[3];
+ if (regoffset == RTXAGC_A_MCS15_MCS12 ||
+ regoffset == RTXAGC_A_MCS07_MCS04)
+ regoffset = 0xc90;
+ if (regoffset == RTXAGC_B_MCS15_MCS12 ||
+ regoffset == RTXAGC_B_MCS07_MCS04)
+ regoffset = 0xc98;
+
+ for (i = 0; i < 3; i++) {
+ writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
+ rtl_write_byte(rtlpriv, (u32) (regoffset + i),
+ (u8) writeVal);
+ }
+ }
+ }
+}
+
+void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel)
+{
+ u32 writeVal[2], powerBase0[2], powerBase1[2];
+ u8 index;
+
+ rtl92c_phy_get_power_base(hw, ppowerlevel,
+ channel, &powerBase0[0], &powerBase1[0]);
+
+ for (index = 0; index < 6; index++) {
+ _rtl92c_get_txpower_writeval_by_regulatory(hw,
+ channel, index,
+ &powerBase0[0],
+ &powerBase1[0],
+ &writeVal[0]);
+
+ _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]);
+ }
+}
+
+bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ if (rtlphy->rf_type == RF_1T1R)
+ rtlphy->num_total_rfpath = 1;
+ else
+ rtlphy->num_total_rfpath = 2;
+
+ return _rtl92c_phy_rf6052_config_parafile(hw);
+}
+
+static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u32 u4_regvalue;
+ u8 rfpath;
+ bool rtstatus;
+ struct bb_reg_def *pphyreg;
+
+ for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+
+ pphyreg = &rtlphy->phyreg_def[rfpath];
+
+ switch (rfpath) {
+ case RF90_PATH_A:
+ case RF90_PATH_C:
+ u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
+ BRFSI_RFENV);
+ break;
+ case RF90_PATH_B:
+ case RF90_PATH_D:
+ u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
+ BRFSI_RFENV << 16);
+ break;
+ }
+
+ rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
+ udelay(1);
+
+ rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
+ udelay(1);
+
+ rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
+ B3WIREADDREAALENGTH, 0x0);
+ udelay(1);
+
+ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
+ udelay(1);
+
+ switch (rfpath) {
+ case RF90_PATH_A:
+ rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+ (enum radio_path) rfpath);
+ break;
+ case RF90_PATH_B:
+ rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+ (enum radio_path) rfpath);
+ break;
+ case RF90_PATH_C:
+ break;
+ case RF90_PATH_D:
+ break;
+ }
+
+ switch (rfpath) {
+ case RF90_PATH_A:
+ case RF90_PATH_C:
+ rtl_set_bbreg(hw, pphyreg->rfintfs,
+ BRFSI_RFENV, u4_regvalue);
+ break;
+ case RF90_PATH_B:
+ case RF90_PATH_D:
+ rtl_set_bbreg(hw, pphyreg->rfintfs,
+ BRFSI_RFENV << 16, u4_regvalue);
+ break;
+ }
+
+ if (rtstatus != true) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+ ("Radio[%d] Fail!!", rfpath));
+ return false;
+ }
+
+ }
+
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+ return rtstatus;
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
new file mode 100644
index 000000000000..d3014f99bb7b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92C_RF_H__
+#define __RTL92C_RF_H__
+
+#define RF6052_MAX_TX_PWR 0x3F
+#define RF6052_MAX_REG 0x3F
+#define RF6052_MAX_PATH 2
+
+extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+ u8 bandwidth);
+extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel);
+extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel);
+extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
new file mode 100644
index 000000000000..b366e8862929
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -0,0 +1,282 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/vmalloc.h>
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
+
+int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+ rtlpriv->dm.b_dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_flag = 0;
+ rtlpriv->dm.b_disable_framebursting = 0;;
+ rtlpriv->dm.thermalvalue = 0;
+ rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
+
+ rtlpci->receive_config = (RCR_APPFCS |
+ RCR_AMF |
+ RCR_ADF |
+ RCR_APP_MIC |
+ RCR_APP_ICV |
+ RCR_AICV |
+ RCR_ACRC32 |
+ RCR_AB |
+ RCR_AM |
+ RCR_APM |
+ RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0);
+
+ rtlpci->irq_mask[0] =
+ (u32) (IMR_ROK |
+ IMR_VODOK |
+ IMR_VIDOK |
+ IMR_BEDOK |
+ IMR_BKDOK |
+ IMR_MGNTDOK |
+ IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0);
+
+ rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
+
+ rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
+ if (!rtlpriv->rtlhal.pfirmware) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't alloc buffer for fw.\n"));
+ return 1;
+ }
+
+ return 0;
+}
+
+void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->rtlhal.pfirmware) {
+ vfree(rtlpriv->rtlhal.pfirmware);
+ rtlpriv->rtlhal.pfirmware = NULL;
+ }
+}
+
+static struct rtl_hal_ops rtl8192ce_hal_ops = {
+ .init_sw_vars = rtl92c_init_sw_vars,
+ .deinit_sw_vars = rtl92c_deinit_sw_vars,
+ .read_eeprom_info = rtl92ce_read_eeprom_info,
+ .interrupt_recognized = rtl92ce_interrupt_recognized,
+ .hw_init = rtl92ce_hw_init,
+ .hw_disable = rtl92ce_card_disable,
+ .enable_interrupt = rtl92ce_enable_interrupt,
+ .disable_interrupt = rtl92ce_disable_interrupt,
+ .set_network_type = rtl92ce_set_network_type,
+ .set_qos = rtl92ce_set_qos,
+ .set_bcn_reg = rtl92ce_set_beacon_related_registers,
+ .set_bcn_intv = rtl92ce_set_beacon_interval,
+ .update_interrupt_mask = rtl92ce_update_interrupt_mask,
+ .get_hw_reg = rtl92ce_get_hw_reg,
+ .set_hw_reg = rtl92ce_set_hw_reg,
+ .update_rate_table = rtl92ce_update_hal_rate_table,
+ .update_rate_mask = rtl92ce_update_hal_rate_mask,
+ .fill_tx_desc = rtl92ce_tx_fill_desc,
+ .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
+ .query_rx_desc = rtl92ce_rx_query_desc,
+ .set_channel_access = rtl92ce_update_channel_access_setting,
+ .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking,
+ .set_bw_mode = rtl92c_phy_set_bw_mode,
+ .switch_channel = rtl92c_phy_sw_chnl,
+ .dm_watchdog = rtl92c_dm_watchdog,
+ .scan_operation_backup = rtl92c_phy_scan_operation_backup,
+ .set_rf_power_state = rtl92c_phy_set_rf_power_state,
+ .led_control = rtl92ce_led_control,
+ .set_desc = rtl92ce_set_desc,
+ .get_desc = rtl92ce_get_desc,
+ .tx_polling = rtl92ce_tx_polling,
+ .enable_hw_sec = rtl92ce_enable_hw_security_config,
+ .set_key = rtl92ce_set_key,
+ .init_sw_leds = rtl92ce_init_sw_leds,
+ .deinit_sw_leds = rtl92ce_deinit_sw_leds,
+ .get_bbreg = rtl92c_phy_query_bb_reg,
+ .set_bbreg = rtl92c_phy_set_bb_reg,
+ .get_rfreg = rtl92c_phy_query_rf_reg,
+ .set_rfreg = rtl92c_phy_set_rf_reg,
+};
+
+static struct rtl_mod_params rtl92ce_mod_params = {
+ .sw_crypto = 0,
+};
+
+static struct rtl_hal_cfg rtl92ce_hal_cfg = {
+ .name = "rtl92c_pci",
+ .fw_name = "rtlwifi/rtl8192cfw.bin",
+ .ops = &rtl8192ce_hal_ops,
+ .mod_params = &rtl92ce_mod_params,
+
+ .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
+ .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
+ .maps[SYS_CLK] = REG_SYS_CLKR,
+ .maps[MAC_RCR_AM] = AM,
+ .maps[MAC_RCR_AB] = AB,
+ .maps[MAC_RCR_ACRC32] = ACRC32,
+ .maps[MAC_RCR_ACF] = ACF,
+ .maps[MAC_RCR_AAP] = AAP,
+
+ .maps[EFUSE_TEST] = REG_EFUSE_TEST,
+ .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
+ .maps[EFUSE_CLK] = 0,
+ .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
+ .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
+ .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
+ .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
+ .maps[EFUSE_ANA8M] = EFUSE_ANA8M,
+ .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+
+ .maps[RWCAM] = REG_CAMCMD,
+ .maps[WCAMI] = REG_CAMWRITE,
+ .maps[RCAMO] = REG_CAMREAD,
+ .maps[CAMDBG] = REG_CAMDBG,
+ .maps[SECR] = REG_SECCFG,
+ .maps[SEC_CAM_NONE] = CAM_NONE,
+ .maps[SEC_CAM_WEP40] = CAM_WEP40,
+ .maps[SEC_CAM_TKIP] = CAM_TKIP,
+ .maps[SEC_CAM_AES] = CAM_AES,
+ .maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+ .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+ .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+ .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+ .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+ .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+ .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+ .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
+ .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+ .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+ .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+ .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+ .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+ .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+ .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+ .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
+ .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
+
+ .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+ .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+ .maps[RTL_IMR_BcnInt] = IMR_BCNINT,
+ .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+ .maps[RTL_IMR_RDU] = IMR_RDU,
+ .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+ .maps[RTL_IMR_BDOK] = IMR_BDOK,
+ .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+ .maps[RTL_IMR_TBDER] = IMR_TBDER,
+ .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+ .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+ .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+ .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+ .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+ .maps[RTL_IMR_VODOK] = IMR_VODOK,
+ .maps[RTL_IMR_ROK] = IMR_ROK,
+ .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
+
+ .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
+ .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
+ .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
+ .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
+ .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
+ .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
+ .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
+ .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
+ .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
+ .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
+ .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
+ .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
+
+ .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
+ .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
+};
+
+static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
+ {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)},
+ {},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids);
+
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
+MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
+
+module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
+MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+
+static struct pci_driver rtl92ce_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rtl92ce_pci_ids,
+ .probe = rtl_pci_probe,
+ .remove = rtl_pci_disconnect,
+
+#ifdef CONFIG_PM
+ .suspend = rtl_pci_suspend,
+ .resume = rtl_pci_resume,
+#endif
+
+};
+
+static int __init rtl92ce_module_init(void)
+{
+ int ret;
+
+ ret = pci_register_driver(&rtl92ce_driver);
+ if (ret)
+ RT_ASSERT(false, (": No device found\n"));
+
+ return ret;
+}
+
+static void __exit rtl92ce_module_exit(void)
+{
+ pci_unregister_driver(&rtl92ce_driver);
+}
+
+module_init(rtl92ce_module_init);
+module_exit(rtl92ce_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
new file mode 100644
index 000000000000..de1198c38d4e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_SW_H__
+#define __RTL92CE_SW_H__
+
+int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
+void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
+void rtl92c_init_var_map(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
new file mode 100644
index 000000000000..ba938b91aa6f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
@@ -0,0 +1,1224 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Created on 2010/ 5/18, 1:41
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "table.h"
+
+
+u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = {
+ 0x024, 0x0011800f,
+ 0x028, 0x00ffdb83,
+ 0x800, 0x80040002,
+ 0x804, 0x00000003,
+ 0x808, 0x0000fc00,
+ 0x80c, 0x0000000a,
+ 0x810, 0x10005388,
+ 0x814, 0x020c3d10,
+ 0x818, 0x02200385,
+ 0x81c, 0x00000000,
+ 0x820, 0x01000100,
+ 0x824, 0x00390004,
+ 0x828, 0x01000100,
+ 0x82c, 0x00390004,
+ 0x830, 0x27272727,
+ 0x834, 0x27272727,
+ 0x838, 0x27272727,
+ 0x83c, 0x27272727,
+ 0x840, 0x00010000,
+ 0x844, 0x00010000,
+ 0x848, 0x27272727,
+ 0x84c, 0x27272727,
+ 0x850, 0x00000000,
+ 0x854, 0x00000000,
+ 0x858, 0x569a569a,
+ 0x85c, 0x0c1b25a4,
+ 0x860, 0x66e60230,
+ 0x864, 0x061f0130,
+ 0x868, 0x27272727,
+ 0x86c, 0x2b2b2b27,
+ 0x870, 0x07000700,
+ 0x874, 0x22184000,
+ 0x878, 0x08080808,
+ 0x87c, 0x00000000,
+ 0x880, 0xc0083070,
+ 0x884, 0x000004d5,
+ 0x888, 0x00000000,
+ 0x88c, 0xcc0000c0,
+ 0x890, 0x00000800,
+ 0x894, 0xfffffffe,
+ 0x898, 0x40302010,
+ 0x89c, 0x00706050,
+ 0x900, 0x00000000,
+ 0x904, 0x00000023,
+ 0x908, 0x00000000,
+ 0x90c, 0x81121313,
+ 0xa00, 0x00d047c8,
+ 0xa04, 0x80ff000c,
+ 0xa08, 0x8c838300,
+ 0xa0c, 0x2e68120f,
+ 0xa10, 0x9500bb78,
+ 0xa14, 0x11144028,
+ 0xa18, 0x00881117,
+ 0xa1c, 0x89140f00,
+ 0xa20, 0x1a1b0000,
+ 0xa24, 0x090e1317,
+ 0xa28, 0x00000204,
+ 0xa2c, 0x00d30000,
+ 0xa70, 0x101fbf00,
+ 0xa74, 0x00000007,
+ 0xc00, 0x48071d40,
+ 0xc04, 0x03a05633,
+ 0xc08, 0x000000e4,
+ 0xc0c, 0x6c6c6c6c,
+ 0xc10, 0x08800000,
+ 0xc14, 0x40000100,
+ 0xc18, 0x08800000,
+ 0xc1c, 0x40000100,
+ 0xc20, 0x00000000,
+ 0xc24, 0x00000000,
+ 0xc28, 0x00000000,
+ 0xc2c, 0x00000000,
+ 0xc30, 0x69e9ac44,
+ 0xc34, 0x469652cf,
+ 0xc38, 0x49795994,
+ 0xc3c, 0x0a97971c,
+ 0xc40, 0x1f7c403f,
+ 0xc44, 0x000100b7,
+ 0xc48, 0xec020107,
+ 0xc4c, 0x007f037f,
+ 0xc50, 0x69543420,
+ 0xc54, 0x43bc0094,
+ 0xc58, 0x69543420,
+ 0xc5c, 0x433c0094,
+ 0xc60, 0x00000000,
+ 0xc64, 0x5116848b,
+ 0xc68, 0x47c00bff,
+ 0xc6c, 0x00000036,
+ 0xc70, 0x2c7f000d,
+ 0xc74, 0x018610db,
+ 0xc78, 0x0000001f,
+ 0xc7c, 0x00b91612,
+ 0xc80, 0x40000100,
+ 0xc84, 0x20f60000,
+ 0xc88, 0x40000100,
+ 0xc8c, 0x20200000,
+ 0xc90, 0x00121820,
+ 0xc94, 0x00000000,
+ 0xc98, 0x00121820,
+ 0xc9c, 0x00007f7f,
+ 0xca0, 0x00000000,
+ 0xca4, 0x00000080,
+ 0xca8, 0x00000000,
+ 0xcac, 0x00000000,
+ 0xcb0, 0x00000000,
+ 0xcb4, 0x00000000,
+ 0xcb8, 0x00000000,
+ 0xcbc, 0x28000000,
+ 0xcc0, 0x00000000,
+ 0xcc4, 0x00000000,
+ 0xcc8, 0x00000000,
+ 0xccc, 0x00000000,
+ 0xcd0, 0x00000000,
+ 0xcd4, 0x00000000,
+ 0xcd8, 0x64b22427,
+ 0xcdc, 0x00766932,
+ 0xce0, 0x00222222,
+ 0xce4, 0x00000000,
+ 0xce8, 0x37644302,
+ 0xcec, 0x2f97d40c,
+ 0xd00, 0x00080740,
+ 0xd04, 0x00020403,
+ 0xd08, 0x0000907f,
+ 0xd0c, 0x20010201,
+ 0xd10, 0xa0633333,
+ 0xd14, 0x3333bc43,
+ 0xd18, 0x7a8f5b6b,
+ 0xd2c, 0xcc979975,
+ 0xd30, 0x00000000,
+ 0xd34, 0x80608000,
+ 0xd38, 0x00000000,
+ 0xd3c, 0x00027293,
+ 0xd40, 0x00000000,
+ 0xd44, 0x00000000,
+ 0xd48, 0x00000000,
+ 0xd4c, 0x00000000,
+ 0xd50, 0x6437140a,
+ 0xd54, 0x00000000,
+ 0xd58, 0x00000000,
+ 0xd5c, 0x30032064,
+ 0xd60, 0x4653de68,
+ 0xd64, 0x04518a3c,
+ 0xd68, 0x00002101,
+ 0xd6c, 0x2a201c16,
+ 0xd70, 0x1812362e,
+ 0xd74, 0x322c2220,
+ 0xd78, 0x000e3c24,
+ 0xe00, 0x2a2a2a2a,
+ 0xe04, 0x2a2a2a2a,
+ 0xe08, 0x03902a2a,
+ 0xe10, 0x2a2a2a2a,
+ 0xe14, 0x2a2a2a2a,
+ 0xe18, 0x2a2a2a2a,
+ 0xe1c, 0x2a2a2a2a,
+ 0xe28, 0x00000000,
+ 0xe30, 0x1000dc1f,
+ 0xe34, 0x10008c1f,
+ 0xe38, 0x02140102,
+ 0xe3c, 0x681604c2,
+ 0xe40, 0x01007c00,
+ 0xe44, 0x01004800,
+ 0xe48, 0xfb000000,
+ 0xe4c, 0x000028d1,
+ 0xe50, 0x1000dc1f,
+ 0xe54, 0x10008c1f,
+ 0xe58, 0x02140102,
+ 0xe5c, 0x28160d05,
+ 0xe60, 0x00000010,
+ 0xe68, 0x001b25a4,
+ 0xe6c, 0x63db25a4,
+ 0xe70, 0x63db25a4,
+ 0xe74, 0x0c1b25a4,
+ 0xe78, 0x0c1b25a4,
+ 0xe7c, 0x0c1b25a4,
+ 0xe80, 0x0c1b25a4,
+ 0xe84, 0x63db25a4,
+ 0xe88, 0x0c1b25a4,
+ 0xe8c, 0x63db25a4,
+ 0xed0, 0x63db25a4,
+ 0xed4, 0x63db25a4,
+ 0xed8, 0x63db25a4,
+ 0xedc, 0x001b25a4,
+ 0xee0, 0x001b25a4,
+ 0xeec, 0x6fdb25a4,
+ 0xf14, 0x00000003,
+ 0xf4c, 0x00000000,
+ 0xf00, 0x00000300,
+};
+
+u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = {
+ 0x024, 0x0011800f,
+ 0x028, 0x00ffdb83,
+ 0x800, 0x80040000,
+ 0x804, 0x00000001,
+ 0x808, 0x0000fc00,
+ 0x80c, 0x0000000a,
+ 0x810, 0x10005388,
+ 0x814, 0x020c3d10,
+ 0x818, 0x02200385,
+ 0x81c, 0x00000000,
+ 0x820, 0x01000100,
+ 0x824, 0x00390004,
+ 0x828, 0x00000000,
+ 0x82c, 0x00000000,
+ 0x830, 0x00000000,
+ 0x834, 0x00000000,
+ 0x838, 0x00000000,
+ 0x83c, 0x00000000,
+ 0x840, 0x00010000,
+ 0x844, 0x00000000,
+ 0x848, 0x00000000,
+ 0x84c, 0x00000000,
+ 0x850, 0x00000000,
+ 0x854, 0x00000000,
+ 0x858, 0x569a569a,
+ 0x85c, 0x001b25a4,
+ 0x860, 0x66e60230,
+ 0x864, 0x061f0130,
+ 0x868, 0x00000000,
+ 0x86c, 0x32323200,
+ 0x870, 0x07000700,
+ 0x874, 0x22004000,
+ 0x878, 0x00000808,
+ 0x87c, 0x00000000,
+ 0x880, 0xc0083070,
+ 0x884, 0x000004d5,
+ 0x888, 0x00000000,
+ 0x88c, 0xccc000c0,
+ 0x890, 0x00000800,
+ 0x894, 0xfffffffe,
+ 0x898, 0x40302010,
+ 0x89c, 0x00706050,
+ 0x900, 0x00000000,
+ 0x904, 0x00000023,
+ 0x908, 0x00000000,
+ 0x90c, 0x81121111,
+ 0xa00, 0x00d047c8,
+ 0xa04, 0x80ff000c,
+ 0xa08, 0x8c838300,
+ 0xa0c, 0x2e68120f,
+ 0xa10, 0x9500bb78,
+ 0xa14, 0x11144028,
+ 0xa18, 0x00881117,
+ 0xa1c, 0x89140f00,
+ 0xa20, 0x1a1b0000,
+ 0xa24, 0x090e1317,
+ 0xa28, 0x00000204,
+ 0xa2c, 0x00d30000,
+ 0xa70, 0x101fbf00,
+ 0xa74, 0x00000007,
+ 0xc00, 0x48071d40,
+ 0xc04, 0x03a05611,
+ 0xc08, 0x000000e4,
+ 0xc0c, 0x6c6c6c6c,
+ 0xc10, 0x08800000,
+ 0xc14, 0x40000100,
+ 0xc18, 0x08800000,
+ 0xc1c, 0x40000100,
+ 0xc20, 0x00000000,
+ 0xc24, 0x00000000,
+ 0xc28, 0x00000000,
+ 0xc2c, 0x00000000,
+ 0xc30, 0x69e9ac44,
+ 0xc34, 0x469652cf,
+ 0xc38, 0x49795994,
+ 0xc3c, 0x0a97971c,
+ 0xc40, 0x1f7c403f,
+ 0xc44, 0x000100b7,
+ 0xc48, 0xec020107,
+ 0xc4c, 0x007f037f,
+ 0xc50, 0x69543420,
+ 0xc54, 0x43bc0094,
+ 0xc58, 0x69543420,
+ 0xc5c, 0x433c0094,
+ 0xc60, 0x00000000,
+ 0xc64, 0x5116848b,
+ 0xc68, 0x47c00bff,
+ 0xc6c, 0x00000036,
+ 0xc70, 0x2c7f000d,
+ 0xc74, 0x018610db,
+ 0xc78, 0x0000001f,
+ 0xc7c, 0x00b91612,
+ 0xc80, 0x40000100,
+ 0xc84, 0x20f60000,
+ 0xc88, 0x40000100,
+ 0xc8c, 0x20200000,
+ 0xc90, 0x00121820,
+ 0xc94, 0x00000000,
+ 0xc98, 0x00121820,
+ 0xc9c, 0x00007f7f,
+ 0xca0, 0x00000000,
+ 0xca4, 0x00000080,
+ 0xca8, 0x00000000,
+ 0xcac, 0x00000000,
+ 0xcb0, 0x00000000,
+ 0xcb4, 0x00000000,
+ 0xcb8, 0x00000000,
+ 0xcbc, 0x28000000,
+ 0xcc0, 0x00000000,
+ 0xcc4, 0x00000000,
+ 0xcc8, 0x00000000,
+ 0xccc, 0x00000000,
+ 0xcd0, 0x00000000,
+ 0xcd4, 0x00000000,
+ 0xcd8, 0x64b22427,
+ 0xcdc, 0x00766932,
+ 0xce0, 0x00222222,
+ 0xce4, 0x00000000,
+ 0xce8, 0x37644302,
+ 0xcec, 0x2f97d40c,
+ 0xd00, 0x00080740,
+ 0xd04, 0x00020401,
+ 0xd08, 0x0000907f,
+ 0xd0c, 0x20010201,
+ 0xd10, 0xa0633333,
+ 0xd14, 0x3333bc43,
+ 0xd18, 0x7a8f5b6b,
+ 0xd2c, 0xcc979975,
+ 0xd30, 0x00000000,
+ 0xd34, 0x80608000,
+ 0xd38, 0x00000000,
+ 0xd3c, 0x00027293,
+ 0xd40, 0x00000000,
+ 0xd44, 0x00000000,
+ 0xd48, 0x00000000,
+ 0xd4c, 0x00000000,
+ 0xd50, 0x6437140a,
+ 0xd54, 0x00000000,
+ 0xd58, 0x00000000,
+ 0xd5c, 0x30032064,
+ 0xd60, 0x4653de68,
+ 0xd64, 0x04518a3c,
+ 0xd68, 0x00002101,
+ 0xd6c, 0x2a201c16,
+ 0xd70, 0x1812362e,
+ 0xd74, 0x322c2220,
+ 0xd78, 0x000e3c24,
+ 0xe00, 0x2a2a2a2a,
+ 0xe04, 0x2a2a2a2a,
+ 0xe08, 0x03902a2a,
+ 0xe10, 0x2a2a2a2a,
+ 0xe14, 0x2a2a2a2a,
+ 0xe18, 0x2a2a2a2a,
+ 0xe1c, 0x2a2a2a2a,
+ 0xe28, 0x00000000,
+ 0xe30, 0x1000dc1f,
+ 0xe34, 0x10008c1f,
+ 0xe38, 0x02140102,
+ 0xe3c, 0x681604c2,
+ 0xe40, 0x01007c00,
+ 0xe44, 0x01004800,
+ 0xe48, 0xfb000000,
+ 0xe4c, 0x000028d1,
+ 0xe50, 0x1000dc1f,
+ 0xe54, 0x10008c1f,
+ 0xe58, 0x02140102,
+ 0xe5c, 0x28160d05,
+ 0xe60, 0x00000010,
+ 0xe68, 0x001b25a4,
+ 0xe6c, 0x631b25a0,
+ 0xe70, 0x631b25a0,
+ 0xe74, 0x081b25a0,
+ 0xe78, 0x081b25a0,
+ 0xe7c, 0x081b25a0,
+ 0xe80, 0x081b25a0,
+ 0xe84, 0x631b25a0,
+ 0xe88, 0x081b25a0,
+ 0xe8c, 0x631b25a0,
+ 0xed0, 0x631b25a0,
+ 0xed4, 0x631b25a0,
+ 0xed8, 0x631b25a0,
+ 0xedc, 0x001b25a0,
+ 0xee0, 0x001b25a0,
+ 0xeec, 0x6b1b25a0,
+ 0xf14, 0x00000003,
+ 0xf4c, 0x00000000,
+ 0xf00, 0x00000300,
+};
+
+u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = {
+ 0xe00, 0xffffffff, 0x0a0c0c0c,
+ 0xe04, 0xffffffff, 0x02040608,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0x86c, 0xffffff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x0a0c0d0e,
+ 0xe14, 0xffffffff, 0x02040608,
+ 0xe18, 0xffffffff, 0x0a0c0d0e,
+ 0xe1c, 0xffffffff, 0x02040608,
+ 0x830, 0xffffffff, 0x0a0c0c0c,
+ 0x834, 0xffffffff, 0x02040608,
+ 0x838, 0xffffff00, 0x00000000,
+ 0x86c, 0x000000ff, 0x00000000,
+ 0x83c, 0xffffffff, 0x0a0c0d0e,
+ 0x848, 0xffffffff, 0x02040608,
+ 0x84c, 0xffffffff, 0x0a0c0d0e,
+ 0x868, 0xffffffff, 0x02040608,
+ 0xe00, 0xffffffff, 0x00000000,
+ 0xe04, 0xffffffff, 0x00000000,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0x86c, 0xffffff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x00000000,
+ 0xe14, 0xffffffff, 0x00000000,
+ 0xe18, 0xffffffff, 0x00000000,
+ 0xe1c, 0xffffffff, 0x00000000,
+ 0x830, 0xffffffff, 0x00000000,
+ 0x834, 0xffffffff, 0x00000000,
+ 0x838, 0xffffff00, 0x00000000,
+ 0x86c, 0x000000ff, 0x00000000,
+ 0x83c, 0xffffffff, 0x00000000,
+ 0x848, 0xffffffff, 0x00000000,
+ 0x84c, 0xffffffff, 0x00000000,
+ 0x868, 0xffffffff, 0x00000000,
+ 0xe00, 0xffffffff, 0x04040404,
+ 0xe04, 0xffffffff, 0x00020204,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0x86c, 0xffffff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x06060606,
+ 0xe14, 0xffffffff, 0x00020406,
+ 0xe18, 0xffffffff, 0x06060606,
+ 0xe1c, 0xffffffff, 0x00020406,
+ 0x830, 0xffffffff, 0x04040404,
+ 0x834, 0xffffffff, 0x00020204,
+ 0x838, 0xffffff00, 0x00000000,
+ 0x86c, 0x000000ff, 0x00000000,
+ 0x83c, 0xffffffff, 0x06060606,
+ 0x848, 0xffffffff, 0x00020406,
+ 0x84c, 0xffffffff, 0x06060606,
+ 0x868, 0xffffffff, 0x00020406,
+ 0xe00, 0xffffffff, 0x00000000,
+ 0xe04, 0xffffffff, 0x00000000,
+ 0xe08, 0x0000ff00, 0x00000000,
+ 0x86c, 0xffffff00, 0x00000000,
+ 0xe10, 0xffffffff, 0x00000000,
+ 0xe14, 0xffffffff, 0x00000000,
+ 0xe18, 0xffffffff, 0x00000000,
+ 0xe1c, 0xffffffff, 0x00000000,
+ 0x830, 0xffffffff, 0x00000000,
+ 0x834, 0xffffffff, 0x00000000,
+ 0x838, 0xffffff00, 0x00000000,
+ 0x86c, 0x000000ff, 0x00000000,
+ 0x83c, 0xffffffff, 0x00000000,
+ 0x848, 0xffffffff, 0x00000000,
+ 0x84c, 0xffffffff, 0x00000000,
+ 0x868, 0xffffffff, 0x00000000,
+};
+
+u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00031284,
+ 0x002, 0x00098000,
+ 0x003, 0x00018c63,
+ 0x004, 0x000210e7,
+ 0x009, 0x0002044f,
+ 0x00a, 0x0001adb0,
+ 0x00b, 0x00054867,
+ 0x00c, 0x0008992e,
+ 0x00d, 0x0000e52c,
+ 0x00e, 0x00039ce7,
+ 0x00f, 0x00000451,
+ 0x019, 0x00000000,
+ 0x01a, 0x00010255,
+ 0x01b, 0x00060a00,
+ 0x01c, 0x000fc378,
+ 0x01d, 0x000a1250,
+ 0x01e, 0x0004445f,
+ 0x01f, 0x00080001,
+ 0x020, 0x0000b614,
+ 0x021, 0x0006c000,
+ 0x022, 0x00000000,
+ 0x023, 0x00001558,
+ 0x024, 0x00000060,
+ 0x025, 0x00000483,
+ 0x026, 0x0004f000,
+ 0x027, 0x000ec7d9,
+ 0x028, 0x000977c0,
+ 0x029, 0x00004783,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00021334,
+ 0x02a, 0x00000000,
+ 0x02b, 0x00000054,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000c,
+ 0x02a, 0x00000002,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000003,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000004,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000005,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00073333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000006,
+ 0x02b, 0x00000709,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000007,
+ 0x02b, 0x00000709,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000008,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0004b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000009,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000a,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000b,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000c,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000d,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00073333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000e,
+ 0x02b, 0x0000050b,
+ 0x02b, 0x00066666,
+ 0x02c, 0x0000001a,
+ 0x02a, 0x000e0000,
+ 0x010, 0x0004000f,
+ 0x011, 0x000e31fc,
+ 0x010, 0x0006000f,
+ 0x011, 0x000ff9f8,
+ 0x010, 0x0002000f,
+ 0x011, 0x000203f9,
+ 0x010, 0x0003000f,
+ 0x011, 0x000ff500,
+ 0x010, 0x00000000,
+ 0x011, 0x00000000,
+ 0x010, 0x0008000f,
+ 0x011, 0x0003f100,
+ 0x010, 0x0009000f,
+ 0x011, 0x00023100,
+ 0x012, 0x00032000,
+ 0x012, 0x00071000,
+ 0x012, 0x000b0000,
+ 0x012, 0x000fc000,
+ 0x013, 0x000287af,
+ 0x013, 0x000244b7,
+ 0x013, 0x000204ab,
+ 0x013, 0x0001c49f,
+ 0x013, 0x00018493,
+ 0x013, 0x00014297,
+ 0x013, 0x00010295,
+ 0x013, 0x0000c298,
+ 0x013, 0x0000819c,
+ 0x013, 0x000040a8,
+ 0x013, 0x0000001c,
+ 0x014, 0x0001944c,
+ 0x014, 0x00059444,
+ 0x014, 0x0009944c,
+ 0x014, 0x000d9444,
+ 0x015, 0x0000f424,
+ 0x015, 0x0004f424,
+ 0x015, 0x0008f424,
+ 0x015, 0x000cf424,
+ 0x016, 0x000e0330,
+ 0x016, 0x000a0330,
+ 0x016, 0x00060330,
+ 0x016, 0x00020330,
+ 0x000, 0x00010159,
+ 0x018, 0x0000f401,
+ 0x0fe, 0x00000000,
+ 0x0fe, 0x00000000,
+ 0x01f, 0x00080003,
+ 0x0fe, 0x00000000,
+ 0x0fe, 0x00000000,
+ 0x01e, 0x00044457,
+ 0x01f, 0x00080000,
+ 0x000, 0x00030159,
+};
+
+u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00031284,
+ 0x002, 0x00098000,
+ 0x003, 0x00018c63,
+ 0x004, 0x000210e7,
+ 0x009, 0x0002044f,
+ 0x00a, 0x0001adb0,
+ 0x00b, 0x00054867,
+ 0x00c, 0x0008992e,
+ 0x00d, 0x0000e52c,
+ 0x00e, 0x00039ce7,
+ 0x00f, 0x00000451,
+ 0x012, 0x00032000,
+ 0x012, 0x00071000,
+ 0x012, 0x000b0000,
+ 0x012, 0x000fc000,
+ 0x013, 0x000287af,
+ 0x013, 0x000244b7,
+ 0x013, 0x000204ab,
+ 0x013, 0x0001c49f,
+ 0x013, 0x00018493,
+ 0x013, 0x00014297,
+ 0x013, 0x00010295,
+ 0x013, 0x0000c298,
+ 0x013, 0x0000819c,
+ 0x013, 0x000040a8,
+ 0x013, 0x0000001c,
+ 0x014, 0x0001944c,
+ 0x014, 0x00059444,
+ 0x014, 0x0009944c,
+ 0x014, 0x000d9444,
+ 0x015, 0x0000f424,
+ 0x015, 0x0004f424,
+ 0x015, 0x0008f424,
+ 0x015, 0x000cf424,
+ 0x016, 0x000e0330,
+ 0x016, 0x000a0330,
+ 0x016, 0x00060330,
+ 0x016, 0x00020330,
+};
+
+u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = {
+ 0x000, 0x00030159,
+ 0x001, 0x00031284,
+ 0x002, 0x00098000,
+ 0x003, 0x00018c63,
+ 0x004, 0x000210e7,
+ 0x009, 0x0002044f,
+ 0x00a, 0x0001adb0,
+ 0x00b, 0x00054867,
+ 0x00c, 0x0008992e,
+ 0x00d, 0x0000e52c,
+ 0x00e, 0x00039ce7,
+ 0x00f, 0x00000451,
+ 0x019, 0x00000000,
+ 0x01a, 0x00010255,
+ 0x01b, 0x00060a00,
+ 0x01c, 0x000fc378,
+ 0x01d, 0x000a1250,
+ 0x01e, 0x0004445f,
+ 0x01f, 0x00080001,
+ 0x020, 0x0000b614,
+ 0x021, 0x0006c000,
+ 0x022, 0x00000000,
+ 0x023, 0x00001558,
+ 0x024, 0x00000060,
+ 0x025, 0x00000483,
+ 0x026, 0x0004f000,
+ 0x027, 0x000ec7d9,
+ 0x028, 0x000977c0,
+ 0x029, 0x00004783,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00021334,
+ 0x02a, 0x00000000,
+ 0x02b, 0x00000054,
+ 0x02a, 0x00000001,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000c,
+ 0x02a, 0x00000002,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000003,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000004,
+ 0x02b, 0x00000808,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000005,
+ 0x02b, 0x00000808,
+ 0x02b, 0x00073333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000006,
+ 0x02b, 0x00000709,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000007,
+ 0x02b, 0x00000709,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000008,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0004b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x00000009,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00053333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000a,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0005b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000b,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00063333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000c,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x0006b333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000d,
+ 0x02b, 0x0000060a,
+ 0x02b, 0x00073333,
+ 0x02c, 0x0000000d,
+ 0x02a, 0x0000000e,
+ 0x02b, 0x0000050b,
+ 0x02b, 0x00066666,
+ 0x02c, 0x0000001a,
+ 0x02a, 0x000e0000,
+ 0x010, 0x0004000f,
+ 0x011, 0x000e31fc,
+ 0x010, 0x0006000f,
+ 0x011, 0x000ff9f8,
+ 0x010, 0x0002000f,
+ 0x011, 0x000203f9,
+ 0x010, 0x0003000f,
+ 0x011, 0x000ff500,
+ 0x010, 0x00000000,
+ 0x011, 0x00000000,
+ 0x010, 0x0008000f,
+ 0x011, 0x0003f100,
+ 0x010, 0x0009000f,
+ 0x011, 0x00023100,
+ 0x012, 0x00032000,
+ 0x012, 0x00071000,
+ 0x012, 0x000b0000,
+ 0x012, 0x000fc000,
+ 0x013, 0x000287af,
+ 0x013, 0x000244b7,
+ 0x013, 0x000204ab,
+ 0x013, 0x0001c49f,
+ 0x013, 0x00018493,
+ 0x013, 0x00014297,
+ 0x013, 0x00010295,
+ 0x013, 0x0000c298,
+ 0x013, 0x0000819c,
+ 0x013, 0x000040a8,
+ 0x013, 0x0000001c,
+ 0x014, 0x0001944c,
+ 0x014, 0x00059444,
+ 0x014, 0x0009944c,
+ 0x014, 0x000d9444,
+ 0x015, 0x0000f424,
+ 0x015, 0x0004f424,
+ 0x015, 0x0008f424,
+ 0x015, 0x000cf424,
+ 0x016, 0x000e0330,
+ 0x016, 0x000a0330,
+ 0x016, 0x00060330,
+ 0x016, 0x00020330,
+ 0x000, 0x00010159,
+ 0x018, 0x0000f401,
+ 0x0fe, 0x00000000,
+ 0x0fe, 0x00000000,
+ 0x01f, 0x00080003,
+ 0x0fe, 0x00000000,
+ 0x0fe, 0x00000000,
+ 0x01e, 0x00044457,
+ 0x01f, 0x00080000,
+ 0x000, 0x00030159,
+};
+
+u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = {
+ 0x0,
+};
+
+u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = {
+ 0x420, 0x00000080,
+ 0x423, 0x00000000,
+ 0x430, 0x00000000,
+ 0x431, 0x00000000,
+ 0x432, 0x00000000,
+ 0x433, 0x00000001,
+ 0x434, 0x00000004,
+ 0x435, 0x00000005,
+ 0x436, 0x00000006,
+ 0x437, 0x00000007,
+ 0x438, 0x00000000,
+ 0x439, 0x00000000,
+ 0x43a, 0x00000000,
+ 0x43b, 0x00000001,
+ 0x43c, 0x00000004,
+ 0x43d, 0x00000005,
+ 0x43e, 0x00000006,
+ 0x43f, 0x00000007,
+ 0x440, 0x0000005d,
+ 0x441, 0x00000001,
+ 0x442, 0x00000000,
+ 0x444, 0x00000015,
+ 0x445, 0x000000f0,
+ 0x446, 0x0000000f,
+ 0x447, 0x00000000,
+ 0x458, 0x00000041,
+ 0x459, 0x000000a8,
+ 0x45a, 0x00000072,
+ 0x45b, 0x000000b9,
+ 0x460, 0x00000088,
+ 0x461, 0x00000088,
+ 0x462, 0x00000006,
+ 0x463, 0x00000003,
+ 0x4c8, 0x00000004,
+ 0x4c9, 0x00000008,
+ 0x4cc, 0x00000002,
+ 0x4cd, 0x00000028,
+ 0x4ce, 0x00000001,
+ 0x500, 0x00000026,
+ 0x501, 0x000000a2,
+ 0x502, 0x0000002f,
+ 0x503, 0x00000000,
+ 0x504, 0x00000028,
+ 0x505, 0x000000a3,
+ 0x506, 0x0000005e,
+ 0x507, 0x00000000,
+ 0x508, 0x0000002b,
+ 0x509, 0x000000a4,
+ 0x50a, 0x0000005e,
+ 0x50b, 0x00000000,
+ 0x50c, 0x0000004f,
+ 0x50d, 0x000000a4,
+ 0x50e, 0x00000000,
+ 0x50f, 0x00000000,
+ 0x512, 0x0000001c,
+ 0x514, 0x0000000a,
+ 0x515, 0x00000010,
+ 0x516, 0x0000000a,
+ 0x517, 0x00000010,
+ 0x51a, 0x00000016,
+ 0x524, 0x0000000f,
+ 0x525, 0x0000004f,
+ 0x546, 0x00000020,
+ 0x547, 0x00000000,
+ 0x559, 0x00000002,
+ 0x55a, 0x00000002,
+ 0x55d, 0x000000ff,
+ 0x605, 0x00000030,
+ 0x608, 0x0000000e,
+ 0x609, 0x0000002a,
+ 0x652, 0x00000020,
+ 0x63c, 0x0000000a,
+ 0x63d, 0x0000000a,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70a, 0x00000065,
+ 0x70b, 0x00000087,
+};
+
+u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = {
+ 0xc78, 0x7b000001,
+ 0xc78, 0x7b010001,
+ 0xc78, 0x7b020001,
+ 0xc78, 0x7b030001,
+ 0xc78, 0x7b040001,
+ 0xc78, 0x7b050001,
+ 0xc78, 0x7a060001,
+ 0xc78, 0x79070001,
+ 0xc78, 0x78080001,
+ 0xc78, 0x77090001,
+ 0xc78, 0x760a0001,
+ 0xc78, 0x750b0001,
+ 0xc78, 0x740c0001,
+ 0xc78, 0x730d0001,
+ 0xc78, 0x720e0001,
+ 0xc78, 0x710f0001,
+ 0xc78, 0x70100001,
+ 0xc78, 0x6f110001,
+ 0xc78, 0x6e120001,
+ 0xc78, 0x6d130001,
+ 0xc78, 0x6c140001,
+ 0xc78, 0x6b150001,
+ 0xc78, 0x6a160001,
+ 0xc78, 0x69170001,
+ 0xc78, 0x68180001,
+ 0xc78, 0x67190001,
+ 0xc78, 0x661a0001,
+ 0xc78, 0x651b0001,
+ 0xc78, 0x641c0001,
+ 0xc78, 0x631d0001,
+ 0xc78, 0x621e0001,
+ 0xc78, 0x611f0001,
+ 0xc78, 0x60200001,
+ 0xc78, 0x49210001,
+ 0xc78, 0x48220001,
+ 0xc78, 0x47230001,
+ 0xc78, 0x46240001,
+ 0xc78, 0x45250001,
+ 0xc78, 0x44260001,
+ 0xc78, 0x43270001,
+ 0xc78, 0x42280001,
+ 0xc78, 0x41290001,
+ 0xc78, 0x402a0001,
+ 0xc78, 0x262b0001,
+ 0xc78, 0x252c0001,
+ 0xc78, 0x242d0001,
+ 0xc78, 0x232e0001,
+ 0xc78, 0x222f0001,
+ 0xc78, 0x21300001,
+ 0xc78, 0x20310001,
+ 0xc78, 0x06320001,
+ 0xc78, 0x05330001,
+ 0xc78, 0x04340001,
+ 0xc78, 0x03350001,
+ 0xc78, 0x02360001,
+ 0xc78, 0x01370001,
+ 0xc78, 0x00380001,
+ 0xc78, 0x00390001,
+ 0xc78, 0x003a0001,
+ 0xc78, 0x003b0001,
+ 0xc78, 0x003c0001,
+ 0xc78, 0x003d0001,
+ 0xc78, 0x003e0001,
+ 0xc78, 0x003f0001,
+ 0xc78, 0x7b400001,
+ 0xc78, 0x7b410001,
+ 0xc78, 0x7b420001,
+ 0xc78, 0x7b430001,
+ 0xc78, 0x7b440001,
+ 0xc78, 0x7b450001,
+ 0xc78, 0x7a460001,
+ 0xc78, 0x79470001,
+ 0xc78, 0x78480001,
+ 0xc78, 0x77490001,
+ 0xc78, 0x764a0001,
+ 0xc78, 0x754b0001,
+ 0xc78, 0x744c0001,
+ 0xc78, 0x734d0001,
+ 0xc78, 0x724e0001,
+ 0xc78, 0x714f0001,
+ 0xc78, 0x70500001,
+ 0xc78, 0x6f510001,
+ 0xc78, 0x6e520001,
+ 0xc78, 0x6d530001,
+ 0xc78, 0x6c540001,
+ 0xc78, 0x6b550001,
+ 0xc78, 0x6a560001,
+ 0xc78, 0x69570001,
+ 0xc78, 0x68580001,
+ 0xc78, 0x67590001,
+ 0xc78, 0x665a0001,
+ 0xc78, 0x655b0001,
+ 0xc78, 0x645c0001,
+ 0xc78, 0x635d0001,
+ 0xc78, 0x625e0001,
+ 0xc78, 0x615f0001,
+ 0xc78, 0x60600001,
+ 0xc78, 0x49610001,
+ 0xc78, 0x48620001,
+ 0xc78, 0x47630001,
+ 0xc78, 0x46640001,
+ 0xc78, 0x45650001,
+ 0xc78, 0x44660001,
+ 0xc78, 0x43670001,
+ 0xc78, 0x42680001,
+ 0xc78, 0x41690001,
+ 0xc78, 0x406a0001,
+ 0xc78, 0x266b0001,
+ 0xc78, 0x256c0001,
+ 0xc78, 0x246d0001,
+ 0xc78, 0x236e0001,
+ 0xc78, 0x226f0001,
+ 0xc78, 0x21700001,
+ 0xc78, 0x20710001,
+ 0xc78, 0x06720001,
+ 0xc78, 0x05730001,
+ 0xc78, 0x04740001,
+ 0xc78, 0x03750001,
+ 0xc78, 0x02760001,
+ 0xc78, 0x01770001,
+ 0xc78, 0x00780001,
+ 0xc78, 0x00790001,
+ 0xc78, 0x007a0001,
+ 0xc78, 0x007b0001,
+ 0xc78, 0x007c0001,
+ 0xc78, 0x007d0001,
+ 0xc78, 0x007e0001,
+ 0xc78, 0x007f0001,
+ 0xc78, 0x3800001e,
+ 0xc78, 0x3801001e,
+ 0xc78, 0x3802001e,
+ 0xc78, 0x3803001e,
+ 0xc78, 0x3804001e,
+ 0xc78, 0x3805001e,
+ 0xc78, 0x3806001e,
+ 0xc78, 0x3807001e,
+ 0xc78, 0x3808001e,
+ 0xc78, 0x3c09001e,
+ 0xc78, 0x3e0a001e,
+ 0xc78, 0x400b001e,
+ 0xc78, 0x440c001e,
+ 0xc78, 0x480d001e,
+ 0xc78, 0x4c0e001e,
+ 0xc78, 0x500f001e,
+ 0xc78, 0x5210001e,
+ 0xc78, 0x5611001e,
+ 0xc78, 0x5a12001e,
+ 0xc78, 0x5e13001e,
+ 0xc78, 0x6014001e,
+ 0xc78, 0x6015001e,
+ 0xc78, 0x6016001e,
+ 0xc78, 0x6217001e,
+ 0xc78, 0x6218001e,
+ 0xc78, 0x6219001e,
+ 0xc78, 0x621a001e,
+ 0xc78, 0x621b001e,
+ 0xc78, 0x621c001e,
+ 0xc78, 0x621d001e,
+ 0xc78, 0x621e001e,
+ 0xc78, 0x621f001e,
+};
+
+u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = {
+ 0xc78, 0x7b000001,
+ 0xc78, 0x7b010001,
+ 0xc78, 0x7b020001,
+ 0xc78, 0x7b030001,
+ 0xc78, 0x7b040001,
+ 0xc78, 0x7b050001,
+ 0xc78, 0x7a060001,
+ 0xc78, 0x79070001,
+ 0xc78, 0x78080001,
+ 0xc78, 0x77090001,
+ 0xc78, 0x760a0001,
+ 0xc78, 0x750b0001,
+ 0xc78, 0x740c0001,
+ 0xc78, 0x730d0001,
+ 0xc78, 0x720e0001,
+ 0xc78, 0x710f0001,
+ 0xc78, 0x70100001,
+ 0xc78, 0x6f110001,
+ 0xc78, 0x6e120001,
+ 0xc78, 0x6d130001,
+ 0xc78, 0x6c140001,
+ 0xc78, 0x6b150001,
+ 0xc78, 0x6a160001,
+ 0xc78, 0x69170001,
+ 0xc78, 0x68180001,
+ 0xc78, 0x67190001,
+ 0xc78, 0x661a0001,
+ 0xc78, 0x651b0001,
+ 0xc78, 0x641c0001,
+ 0xc78, 0x631d0001,
+ 0xc78, 0x621e0001,
+ 0xc78, 0x611f0001,
+ 0xc78, 0x60200001,
+ 0xc78, 0x49210001,
+ 0xc78, 0x48220001,
+ 0xc78, 0x47230001,
+ 0xc78, 0x46240001,
+ 0xc78, 0x45250001,
+ 0xc78, 0x44260001,
+ 0xc78, 0x43270001,
+ 0xc78, 0x42280001,
+ 0xc78, 0x41290001,
+ 0xc78, 0x402a0001,
+ 0xc78, 0x262b0001,
+ 0xc78, 0x252c0001,
+ 0xc78, 0x242d0001,
+ 0xc78, 0x232e0001,
+ 0xc78, 0x222f0001,
+ 0xc78, 0x21300001,
+ 0xc78, 0x20310001,
+ 0xc78, 0x06320001,
+ 0xc78, 0x05330001,
+ 0xc78, 0x04340001,
+ 0xc78, 0x03350001,
+ 0xc78, 0x02360001,
+ 0xc78, 0x01370001,
+ 0xc78, 0x00380001,
+ 0xc78, 0x00390001,
+ 0xc78, 0x003a0001,
+ 0xc78, 0x003b0001,
+ 0xc78, 0x003c0001,
+ 0xc78, 0x003d0001,
+ 0xc78, 0x003e0001,
+ 0xc78, 0x003f0001,
+ 0xc78, 0x7b400001,
+ 0xc78, 0x7b410001,
+ 0xc78, 0x7b420001,
+ 0xc78, 0x7b430001,
+ 0xc78, 0x7b440001,
+ 0xc78, 0x7b450001,
+ 0xc78, 0x7a460001,
+ 0xc78, 0x79470001,
+ 0xc78, 0x78480001,
+ 0xc78, 0x77490001,
+ 0xc78, 0x764a0001,
+ 0xc78, 0x754b0001,
+ 0xc78, 0x744c0001,
+ 0xc78, 0x734d0001,
+ 0xc78, 0x724e0001,
+ 0xc78, 0x714f0001,
+ 0xc78, 0x70500001,
+ 0xc78, 0x6f510001,
+ 0xc78, 0x6e520001,
+ 0xc78, 0x6d530001,
+ 0xc78, 0x6c540001,
+ 0xc78, 0x6b550001,
+ 0xc78, 0x6a560001,
+ 0xc78, 0x69570001,
+ 0xc78, 0x68580001,
+ 0xc78, 0x67590001,
+ 0xc78, 0x665a0001,
+ 0xc78, 0x655b0001,
+ 0xc78, 0x645c0001,
+ 0xc78, 0x635d0001,
+ 0xc78, 0x625e0001,
+ 0xc78, 0x615f0001,
+ 0xc78, 0x60600001,
+ 0xc78, 0x49610001,
+ 0xc78, 0x48620001,
+ 0xc78, 0x47630001,
+ 0xc78, 0x46640001,
+ 0xc78, 0x45650001,
+ 0xc78, 0x44660001,
+ 0xc78, 0x43670001,
+ 0xc78, 0x42680001,
+ 0xc78, 0x41690001,
+ 0xc78, 0x406a0001,
+ 0xc78, 0x266b0001,
+ 0xc78, 0x256c0001,
+ 0xc78, 0x246d0001,
+ 0xc78, 0x236e0001,
+ 0xc78, 0x226f0001,
+ 0xc78, 0x21700001,
+ 0xc78, 0x20710001,
+ 0xc78, 0x06720001,
+ 0xc78, 0x05730001,
+ 0xc78, 0x04740001,
+ 0xc78, 0x03750001,
+ 0xc78, 0x02760001,
+ 0xc78, 0x01770001,
+ 0xc78, 0x00780001,
+ 0xc78, 0x00790001,
+ 0xc78, 0x007a0001,
+ 0xc78, 0x007b0001,
+ 0xc78, 0x007c0001,
+ 0xc78, 0x007d0001,
+ 0xc78, 0x007e0001,
+ 0xc78, 0x007f0001,
+ 0xc78, 0x3800001e,
+ 0xc78, 0x3801001e,
+ 0xc78, 0x3802001e,
+ 0xc78, 0x3803001e,
+ 0xc78, 0x3804001e,
+ 0xc78, 0x3805001e,
+ 0xc78, 0x3806001e,
+ 0xc78, 0x3807001e,
+ 0xc78, 0x3808001e,
+ 0xc78, 0x3c09001e,
+ 0xc78, 0x3e0a001e,
+ 0xc78, 0x400b001e,
+ 0xc78, 0x440c001e,
+ 0xc78, 0x480d001e,
+ 0xc78, 0x4c0e001e,
+ 0xc78, 0x500f001e,
+ 0xc78, 0x5210001e,
+ 0xc78, 0x5611001e,
+ 0xc78, 0x5a12001e,
+ 0xc78, 0x5e13001e,
+ 0xc78, 0x6014001e,
+ 0xc78, 0x6015001e,
+ 0xc78, 0x6016001e,
+ 0xc78, 0x6217001e,
+ 0xc78, 0x6218001e,
+ 0xc78, 0x6219001e,
+ 0xc78, 0x621a001e,
+ 0xc78, 0x621b001e,
+ 0xc78, 0x621c001e,
+ 0xc78, 0x621d001e,
+ 0xc78, 0x621e001e,
+ 0xc78, 0x621f001e,
+};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
new file mode 100644
index 000000000000..3a6e8b6aeee0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Created on 2010/ 5/18, 1:41
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_TABLE__H_
+#define __RTL92CE_TABLE__H_
+
+#include <linux/types.h>
+
+#define PHY_REG_2TARRAY_LENGTH 374
+extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH];
+#define PHY_REG_1TARRAY_LENGTH 374
+extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH];
+#define PHY_REG_ARRAY_PGLENGTH 192
+extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH];
+#define RADIOA_2TARRAYLENGTH 282
+extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH];
+#define RADIOB_2TARRAYLENGTH 78
+extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH];
+#define RADIOA_1TARRAYLENGTH 282
+extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH];
+#define RADIOB_1TARRAYLENGTH 1
+extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH];
+#define MAC_2T_ARRAYLENGTH 162
+extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH];
+#define AGCTAB_2TARRAYLENGTH 320
+extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH];
+#define AGCTAB_1TARRAYLENGTH 320
+extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH];
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
new file mode 100644
index 000000000000..bf5852f2d634
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -0,0 +1,1031 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "led.h"
+
+static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
+ unsigned int
+ skb_queue)
+{
+ enum rtl_desc_qsel qsel;
+
+ if (unlikely(ieee80211_is_beacon(fc))) {
+ qsel = QSLT_BEACON;
+ return qsel;
+ }
+
+ if (ieee80211_is_mgmt(fc)) {
+ qsel = QSLT_MGNT;
+ return qsel;
+ }
+
+ switch (skb_queue) {
+ case VO_QUEUE:
+ qsel = QSLT_VO;
+ break;
+ case VI_QUEUE:
+ qsel = QSLT_VI;
+ break;
+ case BE_QUEUE:
+ qsel = QSLT_BE;
+ break;
+ case BK_QUEUE:
+ qsel = QSLT_BK;
+ break;
+ default:
+ qsel = QSLT_BE;
+ RT_ASSERT(false, ("BE queue, skb_queue:%d,"
+ " set qsel = 0x%X\n", skb_queue, QSLT_BE));
+ break;
+ }
+ return qsel;
+}
+
+static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
+{
+ int rate_idx;
+
+ if (first_ampdu) {
+ if (false == isht) {
+ switch (desc_rate) {
+ case DESC92C_RATE1M:
+ rate_idx = 0;
+ break;
+ case DESC92C_RATE2M:
+ rate_idx = 1;
+ break;
+ case DESC92C_RATE5_5M:
+ rate_idx = 2;
+ break;
+ case DESC92C_RATE11M:
+ rate_idx = 3;
+ break;
+ case DESC92C_RATE6M:
+ rate_idx = 4;
+ break;
+ case DESC92C_RATE9M:
+ rate_idx = 5;
+ break;
+ case DESC92C_RATE12M:
+ rate_idx = 6;
+ break;
+ case DESC92C_RATE18M:
+ rate_idx = 7;
+ break;
+ case DESC92C_RATE24M:
+ rate_idx = 8;
+ break;
+ case DESC92C_RATE36M:
+ rate_idx = 9;
+ break;
+ case DESC92C_RATE48M:
+ rate_idx = 10;
+ break;
+ case DESC92C_RATE54M:
+ rate_idx = 11;
+ break;
+ default:
+ rate_idx = 0;
+ break;
+ }
+ } else {
+ rate_idx = 11;
+ }
+
+ return rate_idx;
+ }
+
+ switch (desc_rate) {
+ case DESC92C_RATE1M:
+ rate_idx = 0;
+ break;
+ case DESC92C_RATE2M:
+ rate_idx = 1;
+ break;
+ case DESC92C_RATE5_5M:
+ rate_idx = 2;
+ break;
+ case DESC92C_RATE11M:
+ rate_idx = 3;
+ break;
+ case DESC92C_RATE6M:
+ rate_idx = 4;
+ break;
+ case DESC92C_RATE9M:
+ rate_idx = 5;
+ break;
+ case DESC92C_RATE12M:
+ rate_idx = 6;
+ break;
+ case DESC92C_RATE18M:
+ rate_idx = 7;
+ break;
+ case DESC92C_RATE24M:
+ rate_idx = 8;
+ break;
+ case DESC92C_RATE36M:
+ rate_idx = 9;
+ break;
+ case DESC92C_RATE48M:
+ rate_idx = 10;
+ break;
+ case DESC92C_RATE54M:
+ rate_idx = 11;
+ break;
+ default:
+ rate_idx = 11;
+ break;
+ }
+ return rate_idx;
+}
+
+static u8 _rtl92c_query_rxpwrpercentage(char antpower)
+{
+ if ((antpower <= -100) || (antpower >= 20))
+ return 0;
+ else if (antpower >= 0)
+ return 100;
+ else
+ return 100 + antpower;
+}
+
+static u8 _rtl92c_evm_db_to_percentage(char value)
+{
+ char ret_val;
+ ret_val = value;
+
+ if (ret_val >= 0)
+ ret_val = 0;
+
+ if (ret_val <= -33)
+ ret_val = -33;
+
+ ret_val = 0 - ret_val;
+ ret_val *= 3;
+
+ if (ret_val == 99)
+ ret_val = 100;
+
+ return ret_val;
+}
+
+static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
+ u8 signal_strength_index)
+{
+ long signal_power;
+
+ signal_power = (long)((signal_strength_index + 1) >> 1);
+ signal_power -= 95;
+ return signal_power;
+}
+
+static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
+ long currsig)
+{
+ long retsig;
+
+ if (currsig >= 61 && currsig <= 100)
+ retsig = 90 + ((currsig - 60) / 4);
+ else if (currsig >= 41 && currsig <= 60)
+ retsig = 78 + ((currsig - 40) / 2);
+ else if (currsig >= 31 && currsig <= 40)
+ retsig = 66 + (currsig - 30);
+ else if (currsig >= 21 && currsig <= 30)
+ retsig = 54 + (currsig - 20);
+ else if (currsig >= 5 && currsig <= 20)
+ retsig = 42 + (((currsig - 5) * 2) / 3);
+ else if (currsig == 4)
+ retsig = 36;
+ else if (currsig == 3)
+ retsig = 27;
+ else if (currsig == 2)
+ retsig = 18;
+ else if (currsig == 1)
+ retsig = 9;
+ else
+ retsig = currsig;
+
+ return retsig;
+}
+
+static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats,
+ struct rx_desc_92c *pdesc,
+ struct rx_fwinfo_92c *p_drvinfo,
+ bool bpacket_match_bssid,
+ bool bpacket_toself,
+ bool b_packet_beacon)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct phy_sts_cck_8192s_t *cck_buf;
+ s8 rx_pwr_all, rx_pwr[4];
+ u8 rf_rx_num, evm, pwdb_all;
+ u8 i, max_spatial_stream;
+ u32 rssi, total_rssi;
+ bool is_cck_rate;
+
+ is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
+ pstats->b_packet_matchbssid = bpacket_match_bssid;
+ pstats->b_packet_toself = bpacket_toself;
+ pstats->b_is_cck = is_cck_rate;
+ pstats->b_packet_beacon = b_packet_beacon;
+ pstats->b_is_cck = is_cck_rate;
+ pstats->rx_mimo_signalquality[0] = -1;
+ pstats->rx_mimo_signalquality[1] = -1;
+
+ if (is_cck_rate) {
+ u8 report, cck_highpwr;
+ cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
+
+ cck_highpwr = (u8) rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER2,
+ BIT(9));
+ if (!cck_highpwr) {
+ u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+ report = cck_buf->cck_agc_rpt & 0xc0;
+ report = report >> 6;
+ switch (report) {
+ case 0x3:
+ rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x2:
+ rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x1:
+ rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x0:
+ rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
+ break;
+ }
+ } else {
+ u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+ report = p_drvinfo->cfosho[0] & 0x60;
+ report = report >> 5;
+ switch (report) {
+ case 0x3:
+ rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x2:
+ rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x1:
+ rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ case 0x0:
+ rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
+ break;
+ }
+ }
+
+ pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
+ pstats->rx_pwdb_all = pwdb_all;
+ pstats->recvsignalpower = rx_pwr_all;
+
+ if (bpacket_match_bssid) {
+ u8 sq;
+ if (pstats->rx_pwdb_all > 40)
+ sq = 100;
+ else {
+ sq = cck_buf->sq_rpt;
+ if (sq > 64)
+ sq = 0;
+ else if (sq < 20)
+ sq = 100;
+ else
+ sq = ((64 - sq) * 100) / 44;
+ }
+
+ pstats->signalquality = sq;
+ pstats->rx_mimo_signalquality[0] = sq;
+ pstats->rx_mimo_signalquality[1] = -1;
+ }
+ } else {
+ rtlpriv->dm.brfpath_rxenable[0] =
+ rtlpriv->dm.brfpath_rxenable[1] = true;
+ for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
+ if (rtlpriv->dm.brfpath_rxenable[i])
+ rf_rx_num++;
+
+ rx_pwr[i] =
+ ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
+ rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
+ total_rssi += rssi;
+ rtlpriv->stats.rx_snr_db[i] =
+ (long)(p_drvinfo->rxsnr[i] / 2);
+
+ if (bpacket_match_bssid)
+ pstats->rx_mimo_signalstrength[i] = (u8) rssi;
+ }
+
+ rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
+ pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
+ pstats->rx_pwdb_all = pwdb_all;
+ pstats->rxpower = rx_pwr_all;
+ pstats->recvsignalpower = rx_pwr_all;
+
+ if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
+ pdesc->rxmcs <= DESC92C_RATEMCS15)
+ max_spatial_stream = 2;
+ else
+ max_spatial_stream = 1;
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
+
+ if (bpacket_match_bssid) {
+ if (i == 0)
+ pstats->signalquality =
+ (u8) (evm & 0xff);
+ pstats->rx_mimo_signalquality[i] =
+ (u8) (evm & 0xff);
+ }
+ }
+ }
+
+ if (is_cck_rate)
+ pstats->signalstrength =
+ (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
+ else if (rf_rx_num != 0)
+ pstats->signalstrength =
+ (u8) (_rtl92ce_signal_scale_mapping
+ (hw, total_rssi /= rf_rx_num));
+}
+
+static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u8 rfpath;
+ u32 last_rssi, tmpval;
+
+ if (pstats->b_packet_toself || pstats->b_packet_beacon) {
+ rtlpriv->stats.rssi_calculate_cnt++;
+
+ if (rtlpriv->stats.ui_rssi.total_num++ >=
+ PHY_RSSI_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_rssi.total_num =
+ PHY_RSSI_SLID_WIN_MAX;
+ last_rssi =
+ rtlpriv->stats.ui_rssi.elements[rtlpriv->
+ stats.ui_rssi.index];
+ rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+ }
+
+ rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
+ rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
+ index++] =
+ pstats->signalstrength;
+
+ if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+ rtlpriv->stats.ui_rssi.index = 0;
+
+ tmpval = rtlpriv->stats.ui_rssi.total_val /
+ rtlpriv->stats.ui_rssi.total_num;
+ rtlpriv->stats.signal_strength =
+ _rtl92ce_translate_todbm(hw, (u8) tmpval);
+ pstats->rssi = rtlpriv->stats.signal_strength;
+ }
+
+ if (!pstats->b_is_cck && pstats->b_packet_toself) {
+ for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+ rfpath++) {
+
+ if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
+ continue;
+
+ if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ pstats->rx_mimo_signalstrength[rfpath];
+
+ }
+
+ if (pstats->rx_mimo_signalstrength[rfpath] >
+ rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.
+ rx_rssi_percentage[rfpath] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ rtlpriv->stats.rx_rssi_percentage[rfpath] +
+ 1;
+ } else {
+ rtlpriv->stats.rx_rssi_percentage[rfpath] =
+ ((rtlpriv->stats.
+ rx_rssi_percentage[rfpath] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_mimo_signalstrength[rfpath])) /
+ (RX_SMOOTH_FACTOR);
+ }
+
+ }
+ }
+}
+
+static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int weighting;
+
+ if (rtlpriv->stats.recv_signal_power == 0)
+ rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
+
+ if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
+ weighting = 5;
+
+ else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
+ weighting = (-5);
+
+ rtlpriv->stats.recv_signal_power =
+ (rtlpriv->stats.recv_signal_power * 5 +
+ pstats->recvsignalpower + weighting) / 6;
+}
+
+static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ long undecorated_smoothed_pwdb;
+
+ if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+ return;
+ } else {
+ undecorated_smoothed_pwdb =
+ rtlpriv->dm.undecorated_smoothed_pwdb;
+ }
+
+ if (pstats->b_packet_toself || pstats->b_packet_beacon) {
+ if (undecorated_smoothed_pwdb < 0)
+ undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
+
+ if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
+ undecorated_smoothed_pwdb =
+ (((undecorated_smoothed_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+
+ undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
+ + 1;
+ } else {
+ undecorated_smoothed_pwdb =
+ (((undecorated_smoothed_pwdb) *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+ }
+
+ rtlpriv->dm.undecorated_smoothed_pwdb =
+ undecorated_smoothed_pwdb;
+ _rtl92ce_update_rxsignalstatistics(hw, pstats);
+ }
+}
+
+static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
+ struct rtl_stats *pstats)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 last_evm, n_spatialstream, tmpval;
+
+ if (pstats->signalquality != 0) {
+ if (pstats->b_packet_toself || pstats->b_packet_beacon) {
+
+ if (rtlpriv->stats.ui_link_quality.total_num++ >=
+ PHY_LINKQUALITY_SLID_WIN_MAX) {
+ rtlpriv->stats.ui_link_quality.total_num =
+ PHY_LINKQUALITY_SLID_WIN_MAX;
+ last_evm =
+ rtlpriv->stats.
+ ui_link_quality.elements[rtlpriv->
+ stats.ui_link_quality.
+ index];
+ rtlpriv->stats.ui_link_quality.total_val -=
+ last_evm;
+ }
+
+ rtlpriv->stats.ui_link_quality.total_val +=
+ pstats->signalquality;
+ rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
+ ui_link_quality.
+ index++] =
+ pstats->signalquality;
+
+ if (rtlpriv->stats.ui_link_quality.index >=
+ PHY_LINKQUALITY_SLID_WIN_MAX)
+ rtlpriv->stats.ui_link_quality.index = 0;
+
+ tmpval = rtlpriv->stats.ui_link_quality.total_val /
+ rtlpriv->stats.ui_link_quality.total_num;
+ rtlpriv->stats.signal_quality = tmpval;
+
+ rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+
+ for (n_spatialstream = 0; n_spatialstream < 2;
+ n_spatialstream++) {
+ if (pstats->
+ rx_mimo_signalquality[n_spatialstream] !=
+ -1) {
+ if (rtlpriv->stats.
+ rx_evm_percentage[n_spatialstream]
+ == 0) {
+ rtlpriv->stats.
+ rx_evm_percentage
+ [n_spatialstream] =
+ pstats->rx_mimo_signalquality
+ [n_spatialstream];
+ }
+
+ rtlpriv->stats.
+ rx_evm_percentage[n_spatialstream] =
+ ((rtlpriv->
+ stats.rx_evm_percentage
+ [n_spatialstream] *
+ (RX_SMOOTH_FACTOR - 1)) +
+ (pstats->
+ rx_mimo_signalquality
+ [n_spatialstream] * 1)) /
+ (RX_SMOOTH_FACTOR);
+ }
+ }
+ }
+ } else {
+ ;
+ }
+}
+
+static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
+ u8 *buffer,
+ struct rtl_stats *pcurrent_stats)
+{
+
+ if (!pcurrent_stats->b_packet_matchbssid &&
+ !pcurrent_stats->b_packet_beacon)
+ return;
+
+ _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
+ _rtl92ce_process_pwdb(hw, pcurrent_stats);
+ _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
+}
+
+static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ struct rtl_stats *pstats,
+ struct rx_desc_92c *pdesc,
+ struct rx_fwinfo_92c *p_drvinfo)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+ struct ieee80211_hdr *hdr;
+ u8 *tmp_buf;
+ u8 *praddr;
+ u8 *psaddr;
+ u16 fc, type;
+ bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
+
+ tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
+
+ hdr = (struct ieee80211_hdr *)tmp_buf;
+ fc = le16_to_cpu(hdr->frame_control);
+ type = WLAN_FC_GET_TYPE(fc);
+ praddr = hdr->addr1;
+ psaddr = hdr->addr2;
+
+ b_packet_matchbssid =
+ ((IEEE80211_FTYPE_CTL != type) &&
+ (!compare_ether_addr(mac->bssid,
+ (fc & IEEE80211_FCTL_TODS) ?
+ hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
+ hdr->addr2 : hdr->addr3)) &&
+ (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
+
+ b_packet_toself = b_packet_matchbssid &&
+ (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+
+ if (ieee80211_is_beacon(fc))
+ b_packet_beacon = true;
+
+ _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
+ b_packet_matchbssid, b_packet_toself,
+ b_packet_beacon);
+
+ _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
+}
+
+bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
+ struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status,
+ u8 *p_desc, struct sk_buff *skb)
+{
+ struct rx_fwinfo_92c *p_drvinfo;
+ struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
+
+ u32 phystatus = GET_RX_DESC_PHYST(pdesc);
+ stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
+ stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
+ RX_DRV_INFO_SIZE_UNIT;
+ stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
+ stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
+ stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
+ stats->b_hwerror = (stats->b_crc | stats->b_icv);
+ stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
+ stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
+ stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
+ stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
+ stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
+ && (GET_RX_DESC_FAGGR(pdesc) == 1));
+ stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
+ stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
+
+ rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->band = hw->conf.channel->band;
+
+ if (GET_RX_DESC_CRC32(pdesc))
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (!GET_RX_DESC_SWDEC(pdesc))
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+
+ if (GET_RX_DESC_BW(pdesc))
+ rx_status->flag |= RX_FLAG_40MHZ;
+
+ if (GET_RX_DESC_RXHT(pdesc))
+ rx_status->flag |= RX_FLAG_HT;
+
+ rx_status->flag |= RX_FLAG_TSFT;
+
+ if (stats->decrypted)
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+
+ rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
+ GET_RX_DESC_RXHT(pdesc),
+ (u8)
+ GET_RX_DESC_RXMCS(pdesc),
+ (bool)
+ GET_RX_DESC_PAGGR(pdesc));
+
+ rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
+ if (phystatus == true) {
+ p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
+ stats->rx_bufshift);
+
+ _rtl92ce_translate_rx_signal_stuff(hw,
+ skb, stats, pdesc,
+ p_drvinfo);
+ }
+
+ /*rx_status->qual = stats->signal; */
+ rx_status->signal = stats->rssi + 10;
+ /*rx_status->noise = -stats->noise; */
+
+ return true;
+}
+
+void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+ struct ieee80211_tx_info *info, struct sk_buff *skb,
+ unsigned int queue_index)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ bool b_defaultadapter = true;
+
+ struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
+
+ u8 *pdesc = (u8 *) pdesc_tx;
+ struct rtl_tcb_desc tcb_desc;
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+ u16 seq_number;
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ enum rtl_desc_qsel fw_qsel =
+ _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
+ queue_index);
+
+ bool b_firstseg = ((hdr->seq_ctrl &
+ cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
+
+ bool b_lastseg = ((hdr->frame_control &
+ cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
+
+ dma_addr_t mapping = pci_map_single(rtlpci->pdev,
+ skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+
+ seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+
+ rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+
+ CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
+
+ if (b_firstseg) {
+ SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+
+ SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
+
+ if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+ SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
+
+ if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
+ info->flags & IEEE80211_TX_CTL_AMPDU) {
+ SET_TX_DESC_AGG_BREAK(pdesc, 1);
+ SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
+ }
+ SET_TX_DESC_SEQ(pdesc, seq_number);
+
+ SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
+ !tcb_desc.
+ b_cts_enable) ? 1 : 0));
+ SET_TX_DESC_HW_RTS_ENABLE(pdesc,
+ ((tcb_desc.b_rts_enable
+ || tcb_desc.b_cts_enable) ? 1 : 0));
+ SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
+ SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
+
+ SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
+ SET_TX_DESC_RTS_BW(pdesc, 0);
+ SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
+ SET_TX_DESC_RTS_SHORT(pdesc,
+ ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
+ (tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
+ : (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
+
+ if (mac->bw_40) {
+ if (tcb_desc.b_packet_bw) {
+ SET_TX_DESC_DATA_BW(pdesc, 1);
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
+ } else {
+ SET_TX_DESC_DATA_BW(pdesc, 0);
+
+ if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+ mac->cur_40_prime_sc);
+ }
+ }
+ } else {
+ SET_TX_DESC_DATA_BW(pdesc, 0);
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+ }
+
+ SET_TX_DESC_LINIP(pdesc, 0);
+ SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
+
+ if (sta) {
+ u8 ampdu_density = sta->ht_cap.ampdu_density;
+ SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
+ }
+
+ if (info->control.hw_key) {
+ struct ieee80211_key_conf *keyconf =
+ info->control.hw_key;
+
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+ break;
+ default:
+ SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+ break;
+
+ }
+ }
+
+ SET_TX_DESC_PKT_ID(pdesc, 0);
+ SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
+
+ SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
+ SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
+ SET_TX_DESC_DISABLE_FB(pdesc, 0);
+ SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
+
+ if (ieee80211_is_data_qos(fc)) {
+ if (mac->rdg_en) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ ("Enable RDG function.\n"));
+ SET_TX_DESC_RDG_ENABLE(pdesc, 1);
+ SET_TX_DESC_HTC(pdesc, 1);
+ }
+ }
+ }
+
+ SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
+ SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
+
+ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
+
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+ if (rtlpriv->dm.b_useramask) {
+ SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
+ } else {
+ SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
+ }
+
+ if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
+ ppsc->b_fwctrl_lps) {
+ SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+ SET_TX_DESC_PKT_ID(pdesc, 8);
+
+ if (!b_defaultadapter)
+ SET_TX_DESC_QOS(pdesc, 1);
+ }
+
+ SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
+
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
+ is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
+ SET_TX_DESC_BMC(pdesc, 1);
+ }
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+}
+
+void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
+ u8 *pdesc, bool b_firstseg,
+ bool b_lastseg, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 fw_queue = QSLT_BEACON;
+
+ dma_addr_t mapping = pci_map_single(rtlpci->pdev,
+ skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ u16 fc = le16_to_cpu(hdr->frame_control);
+
+ CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
+
+ if (b_firstseg)
+ SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+
+ SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
+
+ SET_TX_DESC_SEQ(pdesc, 0);
+
+ SET_TX_DESC_LINIP(pdesc, 0);
+
+ SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
+
+ SET_TX_DESC_FIRST_SEG(pdesc, 1);
+ SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+ SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
+
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+ SET_TX_DESC_RATE_ID(pdesc, 7);
+ SET_TX_DESC_MACID(pdesc, 0);
+
+ SET_TX_DESC_OWN(pdesc, 1);
+
+ SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
+
+ SET_TX_DESC_FIRST_SEG(pdesc, 1);
+ SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+ SET_TX_DESC_OFFSET(pdesc, 0x20);
+
+ SET_TX_DESC_USE_RATE(pdesc, 1);
+
+ if (!ieee80211_is_data_qos(fc)) {
+ SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+ SET_TX_DESC_PKT_ID(pdesc, 8);
+ }
+
+ RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+ "H2C Tx Cmd Content\n",
+ pdesc, TX_DESC_SIZE);
+}
+
+void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+{
+ if (istx == true) {
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ SET_TX_DESC_OWN(pdesc, 1);
+ break;
+ case HW_DESC_TX_NEXTDESC_ADDR:
+ SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR txdesc :%d"
+ " not process\n", desc_name));
+ break;
+ }
+ } else {
+ switch (desc_name) {
+ case HW_DESC_RXOWN:
+ SET_RX_DESC_OWN(pdesc, 1);
+ break;
+ case HW_DESC_RXBUFF_ADDR:
+ SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
+ break;
+ case HW_DESC_RXPKT_LEN:
+ SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
+ break;
+ case HW_DESC_RXERO:
+ SET_RX_DESC_EOR(pdesc, 1);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR rxdesc :%d "
+ "not process\n", desc_name));
+ break;
+ }
+ }
+}
+
+u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
+{
+ u32 ret = 0;
+
+ if (istx == true) {
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ ret = GET_TX_DESC_OWN(p_desc);
+ break;
+ case HW_DESC_TXBUFF_ADDR:
+ ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR txdesc :%d "
+ "not process\n", desc_name));
+ break;
+ }
+ } else {
+ struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
+ switch (desc_name) {
+ case HW_DESC_OWN:
+ ret = GET_RX_DESC_OWN(pdesc);
+ break;
+ case HW_DESC_RXPKT_LEN:
+ ret = GET_RX_DESC_PKT_LEN(pdesc);
+ break;
+ default:
+ RT_ASSERT(false, ("ERR rxdesc :%d "
+ "not process\n", desc_name));
+ break;
+ }
+ }
+ return ret;
+}
+
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ if (hw_queue == BEACON_QUEUE) {
+ rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
+ } else {
+ rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
+ BIT(0) << (hw_queue));
+ }
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
new file mode 100644
index 000000000000..53d0e0a5af5c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -0,0 +1,714 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_TRX_H__
+#define __RTL92CE_TRX_H__
+
+#define TX_DESC_SIZE 64
+#define TX_DESC_AGGR_SUBFRAME_SIZE 32
+
+#define RX_DESC_SIZE 32
+#define RX_DRV_INFO_SIZE_UNIT 8
+
+#define TX_DESC_NEXT_DESC_OFFSET 40
+#define USB_HWDESC_HEADER_LEN 32
+#define CRCLENGTH 4
+
+#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
+#define SET_TX_DESC_OFFSET(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
+#define SET_TX_DESC_BMC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
+#define SET_TX_DESC_HTC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
+#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
+#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
+#define SET_TX_DESC_LINIP(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
+#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
+#define SET_TX_DESC_GF(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
+#define SET_TX_DESC_OWN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
+
+#define GET_TX_DESC_PKT_SIZE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 0, 16)
+#define GET_TX_DESC_OFFSET(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 16, 8)
+#define GET_TX_DESC_BMC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 24, 1)
+#define GET_TX_DESC_HTC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 25, 1)
+#define GET_TX_DESC_LAST_SEG(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 26, 1)
+#define GET_TX_DESC_FIRST_SEG(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 27, 1)
+#define GET_TX_DESC_LINIP(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 28, 1)
+#define GET_TX_DESC_NO_ACM(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 29, 1)
+#define GET_TX_DESC_GF(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 30, 1)
+#define GET_TX_DESC_OWN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 31, 1)
+
+#define SET_TX_DESC_MACID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
+#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
+#define SET_TX_DESC_BK(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
+#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
+#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
+#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
+#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
+#define SET_TX_DESC_PIFS(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
+#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
+#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
+#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
+#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
+#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
+
+#define GET_TX_DESC_MACID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
+#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
+#define GET_TX_DESC_AGG_BREAK(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
+#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
+#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
+#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
+#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
+#define GET_TX_DESC_PIFS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
+#define GET_TX_DESC_RATE_ID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
+#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
+#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
+#define GET_TX_DESC_SEC_TYPE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
+#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
+
+#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
+#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
+#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
+#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
+#define SET_TX_DESC_RAW(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
+#define SET_TX_DESC_CCX(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
+#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
+#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
+#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
+#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
+#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
+#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
+
+#define GET_TX_DESC_RTS_RC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
+#define GET_TX_DESC_DATA_RC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
+#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
+#define GET_TX_DESC_MORE_FRAG(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
+#define GET_TX_DESC_RAW(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
+#define GET_TX_DESC_CCX(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
+#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
+#define GET_TX_DESC_ANTSEL_A(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
+#define GET_TX_DESC_ANTSEL_B(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
+#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
+#define GET_TX_DESC_TX_ANTL(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
+#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
+
+#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
+#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
+#define SET_TX_DESC_SEQ(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
+#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
+
+#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
+#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
+#define GET_TX_DESC_SEQ(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
+#define GET_TX_DESC_PKT_ID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
+
+#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
+#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
+#define SET_TX_DESC_QOS(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
+#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
+#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
+#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
+#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
+#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
+#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
+#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
+#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
+#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
+#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
+#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
+#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
+#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
+#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
+#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
+#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
+#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
+#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
+
+#define GET_TX_DESC_RTS_RATE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
+#define GET_TX_DESC_AP_DCFE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
+#define GET_TX_DESC_QOS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
+#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
+#define GET_TX_DESC_USE_RATE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
+#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
+#define GET_TX_DESC_DISABLE_FB(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
+#define GET_TX_DESC_CTS2SELF(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
+#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
+#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
+#define GET_TX_DESC_PORT_ID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
+#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
+#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
+#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
+#define GET_TX_DESC_TX_STBC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
+#define GET_TX_DESC_DATA_SHORT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
+#define GET_TX_DESC_DATA_BW(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
+#define GET_TX_DESC_RTS_SHORT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
+#define GET_TX_DESC_RTS_BW(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
+#define GET_TX_DESC_RTS_SC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
+#define GET_TX_DESC_RTS_STBC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
+
+#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
+#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
+#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
+#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
+#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
+#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
+#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
+#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
+
+#define GET_TX_DESC_TX_RATE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
+#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
+#define GET_TX_DESC_CCX_TAG(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
+#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
+#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
+#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
+#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
+#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
+
+#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
+#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
+#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
+#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
+#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
+#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
+#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
+#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
+
+#define GET_TX_DESC_TXAGC_A(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
+#define GET_TX_DESC_TXAGC_B(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
+#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
+#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
+#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
+#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
+#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
+#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
+
+#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
+#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
+#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
+#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
+#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
+
+#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
+#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
+#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
+#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
+#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
+
+#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
+#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
+
+#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
+#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
+
+#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
+#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
+
+#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
+#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
+
+#define GET_RX_DESC_PKT_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 0, 14)
+#define GET_RX_DESC_CRC32(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 14, 1)
+#define GET_RX_DESC_ICV(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 15, 1)
+#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 16, 4)
+#define GET_RX_DESC_SECURITY(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 20, 3)
+#define GET_RX_DESC_QOS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 23, 1)
+#define GET_RX_DESC_SHIFT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 24, 2)
+#define GET_RX_DESC_PHYST(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 26, 1)
+#define GET_RX_DESC_SWDEC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 27, 1)
+#define GET_RX_DESC_LS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 28, 1)
+#define GET_RX_DESC_FS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 29, 1)
+#define GET_RX_DESC_EOR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 30, 1)
+#define GET_RX_DESC_OWN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc, 31, 1)
+
+#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
+#define SET_RX_DESC_EOR(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
+#define SET_RX_DESC_OWN(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
+
+#define GET_RX_DESC_MACID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
+#define GET_RX_DESC_TID(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
+#define GET_RX_DESC_HWRSVD(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
+#define GET_RX_DESC_PAGGR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
+#define GET_RX_DESC_FAGGR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
+#define GET_RX_DESC_A1_FIT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
+#define GET_RX_DESC_A2_FIT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
+#define GET_RX_DESC_PAM(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
+#define GET_RX_DESC_PWR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
+#define GET_RX_DESC_MD(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
+#define GET_RX_DESC_MF(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
+#define GET_RX_DESC_TYPE(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
+#define GET_RX_DESC_MC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
+#define GET_RX_DESC_BC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
+#define GET_RX_DESC_SEQ(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
+#define GET_RX_DESC_FRAG(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
+#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
+#define GET_RX_DESC_NEXT_IND(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
+#define GET_RX_DESC_RSVD(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
+
+#define GET_RX_DESC_RXMCS(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
+#define GET_RX_DESC_RXHT(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
+#define GET_RX_DESC_SPLCP(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
+#define GET_RX_DESC_BW(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
+#define GET_RX_DESC_HTC(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
+#define GET_RX_DESC_HWPC_ERR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
+#define GET_RX_DESC_HWPC_IND(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
+#define GET_RX_DESC_IV0(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
+
+#define GET_RX_DESC_IV1(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
+#define GET_RX_DESC_TSFL(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
+
+#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
+#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
+ LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
+
+#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
+#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
+
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
+do { \
+ if (_size > TX_DESC_NEXT_DESC_OFFSET) \
+ memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
+ else \
+ memset((void *)__pdesc, 0, _size); \
+} while (0);
+
+#define RX_HAL_IS_CCK_RATE(_pdesc)\
+ (_pdesc->rxmcs == DESC92C_RATE1M || \
+ _pdesc->rxmcs == DESC92C_RATE2M || \
+ _pdesc->rxmcs == DESC92C_RATE5_5M || \
+ _pdesc->rxmcs == DESC92C_RATE11M)
+
+struct rx_fwinfo_92c {
+ u8 gain_trsw[4];
+ u8 pwdb_all;
+ u8 cfosho[4];
+ u8 cfotail[4];
+ char rxevm[2];
+ char rxsnr[4];
+ u8 pdsnr[2];
+ u8 csi_current[2];
+ u8 csi_target[2];
+ u8 sigevm;
+ u8 max_ex_pwr;
+ u8 ex_intf_flag:1;
+ u8 sgi_en:1;
+ u8 rxsc:2;
+ u8 reserve:4;
+} __packed;
+
+struct tx_desc_92c {
+ u32 pktsize:16;
+ u32 offset:8;
+ u32 bmc:1;
+ u32 htc:1;
+ u32 lastseg:1;
+ u32 firstseg:1;
+ u32 linip:1;
+ u32 noacm:1;
+ u32 gf:1;
+ u32 own:1;
+
+ u32 macid:5;
+ u32 agg_en:1;
+ u32 bk:1;
+ u32 rdg_en:1;
+ u32 queuesel:5;
+ u32 rd_nav_ext:1;
+ u32 lsig_txop_en:1;
+ u32 pifs:1;
+ u32 rateid:4;
+ u32 nav_usehdr:1;
+ u32 en_descid:1;
+ u32 sectype:2;
+ u32 pktoffset:8;
+
+ u32 rts_rc:6;
+ u32 data_rc:6;
+ u32 rsvd0:2;
+ u32 bar_retryht:2;
+ u32 rsvd1:1;
+ u32 morefrag:1;
+ u32 raw:1;
+ u32 ccx:1;
+ u32 ampdudensity:3;
+ u32 rsvd2:1;
+ u32 ant_sela:1;
+ u32 ant_selb:1;
+ u32 txant_cck:2;
+ u32 txant_l:2;
+ u32 txant_ht:2;
+
+ u32 nextheadpage:8;
+ u32 tailpage:8;
+ u32 seq:12;
+ u32 pktid:4;
+
+ u32 rtsrate:5;
+ u32 apdcfe:1;
+ u32 qos:1;
+ u32 hwseq_enable:1;
+ u32 userrate:1;
+ u32 dis_rtsfb:1;
+ u32 dis_datafb:1;
+ u32 cts2self:1;
+ u32 rts_en:1;
+ u32 hwrts_en:1;
+ u32 portid:1;
+ u32 rsvd3:3;
+ u32 waitdcts:1;
+ u32 cts2ap_en:1;
+ u32 txsc:2;
+ u32 stbc:2;
+ u32 txshort:1;
+ u32 txbw:1;
+ u32 rtsshort:1;
+ u32 rtsbw:1;
+ u32 rtssc:2;
+ u32 rtsstbc:2;
+
+ u32 txrate:6;
+ u32 shortgi:1;
+ u32 ccxt:1;
+ u32 txrate_fb_lmt:5;
+ u32 rtsrate_fb_lmt:4;
+ u32 retrylmt_en:1;
+ u32 txretrylmt:6;
+ u32 usb_txaggnum:8;
+
+ u32 txagca:5;
+ u32 txagcb:5;
+ u32 usemaxlen:1;
+ u32 maxaggnum:5;
+ u32 mcsg1maxlen:4;
+ u32 mcsg2maxlen:4;
+ u32 mcsg3maxlen:4;
+ u32 mcs7sgimaxlen:4;
+
+ u32 txbuffersize:16;
+ u32 mcsg4maxlen:4;
+ u32 mcsg5maxlen:4;
+ u32 mcsg6maxlen:4;
+ u32 mcsg15sgimaxlen:4;
+
+ u32 txbuffaddr;
+ u32 txbufferaddr64;
+ u32 nextdescaddress;
+ u32 nextdescaddress64;
+
+ u32 reserve_pass_pcie_mm_limit[4];
+} __packed;
+
+struct rx_desc_92c {
+ u32 length:14;
+ u32 crc32:1;
+ u32 icverror:1;
+ u32 drv_infosize:4;
+ u32 security:3;
+ u32 qos:1;
+ u32 shift:2;
+ u32 phystatus:1;
+ u32 swdec:1;
+ u32 lastseg:1;
+ u32 firstseg:1;
+ u32 eor:1;
+ u32 own:1;
+
+ u32 macid:5;
+ u32 tid:4;
+ u32 hwrsvd:5;
+ u32 paggr:1;
+ u32 faggr:1;
+ u32 a1_fit:4;
+ u32 a2_fit:4;
+ u32 pam:1;
+ u32 pwr:1;
+ u32 moredata:1;
+ u32 morefrag:1;
+ u32 type:2;
+ u32 mc:1;
+ u32 bc:1;
+
+ u32 seq:12;
+ u32 frag:4;
+ u32 nextpktlen:14;
+ u32 nextind:1;
+ u32 rsvd:1;
+
+ u32 rxmcs:6;
+ u32 rxht:1;
+ u32 amsdu:1;
+ u32 splcp:1;
+ u32 bandwidth:1;
+ u32 htc:1;
+ u32 tcpchk_rpt:1;
+ u32 ipcchk_rpt:1;
+ u32 tcpchk_valid:1;
+ u32 hwpcerr:1;
+ u32 hwpcind:1;
+ u32 iv0:16;
+
+ u32 iv1;
+
+ u32 tsfl;
+
+ u32 bufferaddress;
+ u32 bufferaddress64;
+
+} __packed;
+
+void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr,
+ u8 *pdesc, struct ieee80211_tx_info *info,
+ struct sk_buff *skb, unsigned int qsel);
+bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
+ struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status,
+ u8 *pdesc, struct sk_buff *skb);
+void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
+void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+ bool b_firstseg, bool b_lastseg,
+ struct sk_buff *skb);
+#endif
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
new file mode 100644
index 000000000000..d44d79613d2d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -0,0 +1,1532 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 Realtek Corporation.
+ *
+ * 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, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_WIFI_H__
+#define __RTL_WIFI_H__
+
+#include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "debug.h"
+
+#define RF_CHANGE_BY_INIT 0
+#define RF_CHANGE_BY_IPS BIT(28)
+#define RF_CHANGE_BY_PS BIT(29)
+#define RF_CHANGE_BY_HW BIT(30)
+#define RF_CHANGE_BY_SW BIT(31)
+
+#define IQK_ADDA_REG_NUM 16
+#define IQK_MAC_REG_NUM 4
+
+#define MAX_KEY_LEN 61
+#define KEY_BUF_SIZE 5
+
+/* QoS related. */
+/*aci: 0x00 Best Effort*/
+/*aci: 0x01 Background*/
+/*aci: 0x10 Video*/
+/*aci: 0x11 Voice*/
+/*Max: define total number.*/
+#define AC0_BE 0
+#define AC1_BK 1
+#define AC2_VI 2
+#define AC3_VO 3
+#define AC_MAX 4
+#define QOS_QUEUE_NUM 4
+#define RTL_MAC80211_NUM_QUEUE 5
+
+#define QBSS_LOAD_SIZE 5
+#define MAX_WMMELE_LENGTH 64
+
+/*slot time for 11g. */
+#define RTL_SLOT_TIME_9 9
+#define RTL_SLOT_TIME_20 20
+
+/*related with tcp/ip. */
+/*if_ehther.h*/
+#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */
+#define ETH_P_IP 0x0800 /*Internet Protocol packet */
+#define ETH_P_ARP 0x0806 /*Address Resolution packet */
+#define SNAP_SIZE 6
+#define PROTOC_TYPE_SIZE 2
+
+/*related with 802.11 frame*/
+#define MAC80211_3ADDR_LEN 24
+#define MAC80211_4ADDR_LEN 30
+
+enum intf_type {
+ INTF_PCI = 0,
+ INTF_USB = 1,
+};
+
+enum radio_path {
+ RF90_PATH_A = 0,
+ RF90_PATH_B = 1,
+ RF90_PATH_C = 2,
+ RF90_PATH_D = 3,
+};
+
+enum rt_eeprom_type {
+ EEPROM_93C46,
+ EEPROM_93C56,
+ EEPROM_BOOT_EFUSE,
+};
+
+enum rtl_status {
+ RTL_STATUS_INTERFACE_START = 0,
+};
+
+enum hardware_type {
+ HARDWARE_TYPE_RTL8192E,
+ HARDWARE_TYPE_RTL8192U,
+ HARDWARE_TYPE_RTL8192SE,
+ HARDWARE_TYPE_RTL8192SU,
+ HARDWARE_TYPE_RTL8192CE,
+ HARDWARE_TYPE_RTL8192CU,
+ HARDWARE_TYPE_RTL8192DE,
+ HARDWARE_TYPE_RTL8192DU,
+
+ /*keep it last*/
+ HARDWARE_TYPE_NUM
+};
+
+enum scan_operation_backup_opt {
+ SCAN_OPT_BACKUP = 0,
+ SCAN_OPT_RESTORE,
+ SCAN_OPT_MAX
+};
+
+/*RF state.*/
+enum rf_pwrstate {
+ ERFON,
+ ERFSLEEP,
+ ERFOFF
+};
+
+struct bb_reg_def {
+ u32 rfintfs;
+ u32 rfintfi;
+ u32 rfintfo;
+ u32 rfintfe;
+ u32 rf3wire_offset;
+ u32 rflssi_select;
+ u32 rftxgain_stage;
+ u32 rfhssi_para1;
+ u32 rfhssi_para2;
+ u32 rfswitch_control;
+ u32 rfagc_control1;
+ u32 rfagc_control2;
+ u32 rfrxiq_imbalance;
+ u32 rfrx_afe;
+ u32 rftxiq_imbalance;
+ u32 rftx_afe;
+ u32 rflssi_readback;
+ u32 rflssi_readbackpi;
+};
+
+enum io_type {
+ IO_CMD_PAUSE_DM_BY_SCAN = 0,
+ IO_CMD_RESUME_DM_BY_SCAN = 1,
+};
+
+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,
+ HW_VAR_WPA_CONFIG,
+ HW_VAR_AMPDU_MIN_SPACE,
+ HW_VAR_SHORTGI_DENSITY,
+ HW_VAR_AMPDU_FACTOR,
+ HW_VAR_MCS_RATE_AVAILABLE,
+ HW_VAR_AC_PARAM,
+ HW_VAR_ACM_CTRL,
+ HW_VAR_DIS_Req_Qsize,
+ HW_VAR_CCX_CHNL_LOAD,
+ HW_VAR_CCX_NOISE_HISTOGRAM,
+ HW_VAR_CCX_CLM_NHM,
+ HW_VAR_TxOPLimit,
+ HW_VAR_TURBO_MODE,
+ HW_VAR_RF_STATE,
+ HW_VAR_RF_OFF_BY_HW,
+ HW_VAR_BUS_SPEED,
+ HW_VAR_SET_DEV_POWER,
+
+ HW_VAR_RCR,
+ HW_VAR_RATR_0,
+ HW_VAR_RRSR,
+ HW_VAR_CPU_RST,
+ HW_VAR_CECHK_BSSID,
+ HW_VAR_LBK_MODE,
+ HW_VAR_AES_11N_FIX,
+ HW_VAR_USB_RX_AGGR,
+ HW_VAR_USER_CONTROL_TURBO_MODE,
+ HW_VAR_RETRY_LIMIT,
+ HW_VAR_INIT_TX_RATE,
+ HW_VAR_TX_RATE_REG,
+ HW_VAR_EFUSE_USAGE,
+ HW_VAR_EFUSE_BYTES,
+ HW_VAR_AUTOLOAD_STATUS,
+ HW_VAR_RF_2R_DISABLE,
+ HW_VAR_SET_RPWM,
+ HW_VAR_H2C_FW_PWRMODE,
+ HW_VAR_H2C_FW_JOINBSSRPT,
+ HW_VAR_FW_PSMODE_STATUS,
+ HW_VAR_1X1_RECV_COMBINE,
+ HW_VAR_STOP_SEND_BEACON,
+ HW_VAR_TSF_TIMER,
+ HW_VAR_IO_CMD,
+
+ HW_VAR_RF_RECOVERY,
+ HW_VAR_H2C_FW_UPDATE_GTK,
+ HW_VAR_WF_MASK,
+ HW_VAR_WF_CRC,
+ HW_VAR_WF_IS_MAC_ADDR,
+ HW_VAR_H2C_FW_OFFLOAD,
+ HW_VAR_RESET_WFCRC,
+
+ HW_VAR_HANDLE_FW_C2H,
+ HW_VAR_DL_FW_RSVD_PAGE,
+ HW_VAR_AID,
+ HW_VAR_HW_SEQ_ENABLE,
+ HW_VAR_CORRECT_TSF,
+ HW_VAR_BCN_VALID,
+ HW_VAR_FWLPS_RF_ON,
+ HW_VAR_DUAL_TSF_RST,
+ HW_VAR_SWITCH_EPHY_WoWLAN,
+ HW_VAR_INT_MIGRATION,
+ HW_VAR_INT_AC,
+ HW_VAR_RF_TIMING,
+
+ HW_VAR_MRC,
+
+ HW_VAR_MGT_FILTER,
+ HW_VAR_CTRL_FILTER,
+ HW_VAR_DATA_FILTER,
+};
+
+enum _RT_MEDIA_STATUS {
+ RT_MEDIA_DISCONNECT = 0,
+ RT_MEDIA_CONNECT = 1
+};
+
+enum rt_oem_id {
+ RT_CID_DEFAULT = 0,
+ RT_CID_8187_ALPHA0 = 1,
+ RT_CID_8187_SERCOMM_PS = 2,
+ RT_CID_8187_HW_LED = 3,
+ RT_CID_8187_NETGEAR = 4,
+ RT_CID_WHQL = 5,
+ RT_CID_819x_CAMEO = 6,
+ RT_CID_819x_RUNTOP = 7,
+ RT_CID_819x_Senao = 8,
+ RT_CID_TOSHIBA = 9,
+ RT_CID_819x_Netcore = 10,
+ RT_CID_Nettronix = 11,
+ RT_CID_DLINK = 12,
+ RT_CID_PRONET = 13,
+ RT_CID_COREGA = 14,
+ RT_CID_819x_ALPHA = 15,
+ RT_CID_819x_Sitecom = 16,
+ RT_CID_CCX = 17,
+ RT_CID_819x_Lenovo = 18,
+ RT_CID_819x_QMI = 19,
+ RT_CID_819x_Edimax_Belkin = 20,
+ RT_CID_819x_Sercomm_Belkin = 21,
+ RT_CID_819x_CAMEO1 = 22,
+ RT_CID_819x_MSI = 23,
+ RT_CID_819x_Acer = 24,
+ RT_CID_819x_HP = 27,
+ RT_CID_819x_CLEVO = 28,
+ RT_CID_819x_Arcadyan_Belkin = 29,
+ RT_CID_819x_SAMSUNG = 30,
+ RT_CID_819x_WNC_COREGA = 31,
+ RT_CID_819x_Foxcoon = 32,
+ RT_CID_819x_DELL = 33,
+};
+
+enum hw_descs {
+ HW_DESC_OWN,
+ HW_DESC_RXOWN,
+ HW_DESC_TX_NEXTDESC_ADDR,
+ HW_DESC_TXBUFF_ADDR,
+ HW_DESC_RXBUFF_ADDR,
+ HW_DESC_RXPKT_LEN,
+ HW_DESC_RXERO,
+};
+
+enum prime_sc {
+ PRIME_CHNL_OFFSET_DONT_CARE = 0,
+ PRIME_CHNL_OFFSET_LOWER = 1,
+ PRIME_CHNL_OFFSET_UPPER = 2,
+};
+
+enum rf_type {
+ RF_1T1R = 0,
+ RF_1T2R = 1,
+ RF_2T2R = 2,
+};
+
+enum ht_channel_width {
+ HT_CHANNEL_WIDTH_20 = 0,
+ HT_CHANNEL_WIDTH_20_40 = 1,
+};
+
+/* Ref: 802.11i sepc D10.0 7.3.2.25.1
+Cipher Suites Encryption Algorithms */
+enum rt_enc_alg {
+ NO_ENCRYPTION = 0,
+ WEP40_ENCRYPTION = 1,
+ TKIP_ENCRYPTION = 2,
+ RSERVED_ENCRYPTION = 3,
+ AESCCMP_ENCRYPTION = 4,
+ WEP104_ENCRYPTION = 5,
+};
+
+enum rtl_hal_state {
+ _HAL_STATE_STOP = 0,
+ _HAL_STATE_START = 1,
+};
+
+enum rtl_var_map {
+ /*reg map */
+ SYS_ISO_CTRL = 0,
+ SYS_FUNC_EN,
+ SYS_CLK,
+ MAC_RCR_AM,
+ MAC_RCR_AB,
+ MAC_RCR_ACRC32,
+ MAC_RCR_ACF,
+ MAC_RCR_AAP,
+
+ /*efuse map */
+ EFUSE_TEST,
+ EFUSE_CTRL,
+ EFUSE_CLK,
+ EFUSE_CLK_CTRL,
+ EFUSE_PWC_EV12V,
+ EFUSE_FEN_ELDR,
+ EFUSE_LOADER_CLK_EN,
+ EFUSE_ANA8M,
+ EFUSE_HWSET_MAX_SIZE,
+
+ /*CAM map */
+ RWCAM,
+ WCAMI,
+ RCAMO,
+ CAMDBG,
+ SECR,
+ SEC_CAM_NONE,
+ SEC_CAM_WEP40,
+ SEC_CAM_TKIP,
+ SEC_CAM_AES,
+ SEC_CAM_WEP104,
+
+ /*IMR map */
+ RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */
+ RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */
+ RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */
+ RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */
+ RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */
+ RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */
+ RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrup 8 */
+ RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrup 7 */
+ RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrup 6 */
+ RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrup 5 */
+ RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrup 4 */
+ RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrup 3 */
+ RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrup 2 */
+ RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrup 1 */
+ RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */
+ RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */
+ RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */
+ RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */
+ RTL_IMR_BcnInt, /*Beacon DMA Interrupt 0 */
+ RTL_IMR_RXFOVW, /*Receive FIFO Overflow */
+ RTL_IMR_RDU, /*Receive Descriptor Unavailable */
+ RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */
+ RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */
+ RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */
+ RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */
+ RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */
+ RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */
+ RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */
+ RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */
+ RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */
+ RTL_IMR_VODOK, /*AC_VO DMA Interrupt */
+ RTL_IMR_ROK, /*Receive DMA OK Interrupt */
+ RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt|RTL_IMR_TBDOK|RTL_IMR_TBDER)*/
+
+ /*CCK Rates, TxHT = 0 */
+ RTL_RC_CCK_RATE1M,
+ RTL_RC_CCK_RATE2M,
+ RTL_RC_CCK_RATE5_5M,
+ RTL_RC_CCK_RATE11M,
+
+ /*OFDM Rates, TxHT = 0 */
+ RTL_RC_OFDM_RATE6M,
+ RTL_RC_OFDM_RATE9M,
+ RTL_RC_OFDM_RATE12M,
+ RTL_RC_OFDM_RATE18M,
+ RTL_RC_OFDM_RATE24M,
+ RTL_RC_OFDM_RATE36M,
+ RTL_RC_OFDM_RATE48M,
+ RTL_RC_OFDM_RATE54M,
+
+ RTL_RC_HT_RATEMCS7,
+ RTL_RC_HT_RATEMCS15,
+
+ /*keep it last */
+ RTL_VAR_MAP_MAX,
+};
+
+/*Firmware PS mode for control LPS.*/
+enum _fw_ps_mode {
+ FW_PS_ACTIVE_MODE = 0,
+ FW_PS_MIN_MODE = 1,
+ FW_PS_MAX_MODE = 2,
+ FW_PS_DTIM_MODE = 3,
+ FW_PS_VOIP_MODE = 4,
+ FW_PS_UAPSD_WMM_MODE = 5,
+ FW_PS_UAPSD_MODE = 6,
+ FW_PS_IBSS_MODE = 7,
+ FW_PS_WWLAN_MODE = 8,
+ FW_PS_PM_Radio_Off = 9,
+ FW_PS_PM_Card_Disable = 10,
+};
+
+enum rt_psmode {
+ EACTIVE, /*Active/Continuous access. */
+ EMAXPS, /*Max power save mode. */
+ EFASTPS, /*Fast power save mode. */
+ EAUTOPS, /*Auto power save mode. */
+};
+
+/*LED related.*/
+enum led_ctl_mode {
+ LED_CTL_POWER_ON = 1,
+ LED_CTL_LINK = 2,
+ LED_CTL_NO_LINK = 3,
+ LED_CTL_TX = 4,
+ LED_CTL_RX = 5,
+ LED_CTL_SITE_SURVEY = 6,
+ LED_CTL_POWER_OFF = 7,
+ LED_CTL_START_TO_LINK = 8,
+ LED_CTL_START_WPS = 9,
+ LED_CTL_STOP_WPS = 10,
+};
+
+enum rtl_led_pin {
+ LED_PIN_GPIO0,
+ LED_PIN_LED0,
+ LED_PIN_LED1,
+ LED_PIN_LED2
+};
+
+/*QoS related.*/
+/*acm implementation method.*/
+enum acm_method {
+ eAcmWay0_SwAndHw = 0,
+ eAcmWay1_HW = 1,
+ eAcmWay2_SW = 2,
+};
+
+/*aci/aifsn Field.
+Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/
+union aci_aifsn {
+ u8 char_data;
+
+ struct {
+ u8 aifsn:4;
+ u8 acm:1;
+ u8 aci:2;
+ u8 reserved:1;
+ } f; /* Field */
+};
+
+/*mlme related.*/
+enum wireless_mode {
+ WIRELESS_MODE_UNKNOWN = 0x00,
+ WIRELESS_MODE_A = 0x01,
+ WIRELESS_MODE_B = 0x02,
+ WIRELESS_MODE_G = 0x04,
+ WIRELESS_MODE_AUTO = 0x08,
+ WIRELESS_MODE_N_24G = 0x10,
+ WIRELESS_MODE_N_5G = 0x20
+};
+
+enum ratr_table_mode {
+ RATR_INX_WIRELESS_NGB = 0,
+ RATR_INX_WIRELESS_NG = 1,
+ RATR_INX_WIRELESS_NB = 2,
+ RATR_INX_WIRELESS_N = 3,
+ RATR_INX_WIRELESS_GB = 4,
+ RATR_INX_WIRELESS_G = 5,
+ RATR_INX_WIRELESS_B = 6,
+ RATR_INX_WIRELESS_MC = 7,
+ RATR_INX_WIRELESS_A = 8,
+};
+
+enum rtl_link_state {
+ MAC80211_NOLINK = 0,
+ MAC80211_LINKING = 1,
+ MAC80211_LINKED = 2,
+ MAC80211_LINKED_SCANNING = 3,
+};
+
+enum act_category {
+ ACT_CAT_QOS = 1,
+ ACT_CAT_DLS = 2,
+ ACT_CAT_BA = 3,
+ ACT_CAT_HT = 7,
+ ACT_CAT_WMM = 17,
+};
+
+enum ba_action {
+ ACT_ADDBAREQ = 0,
+ ACT_ADDBARSP = 1,
+ ACT_DELBA = 2,
+};
+
+struct octet_string {
+ u8 *octet;
+ u16 length;
+};
+
+struct rtl_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __packed;
+
+struct rtl_info_element {
+ u8 id;
+ u8 len;
+ u8 data[0];
+} __packed;
+
+struct rtl_probe_rsp {
+ struct rtl_hdr_3addr header;
+ u32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ /*SSID, supported rates, FH params, DS params,
+ CF params, IBSS params, TIM (if beacon), RSN */
+ struct rtl_info_element info_element[0];
+} __packed;
+
+/*LED related.*/
+/*ledpin Identify how to implement this SW led.*/
+struct rtl_led {
+ void *hw;
+ enum rtl_led_pin ledpin;
+ bool b_ledon;
+};
+
+struct rtl_led_ctl {
+ bool bled_opendrain;
+ struct rtl_led sw_led0;
+ struct rtl_led sw_led1;
+};
+
+struct rtl_qos_parameters {
+ __le16 cw_min;
+ __le16 cw_max;
+ u8 aifs;
+ u8 flag;
+ __le16 tx_op;
+} __packed;
+
+struct rt_smooth_data {
+ u32 elements[100]; /*array to store values */
+ u32 index; /*index to current array to store */
+ u32 total_num; /*num of valid elements */
+ u32 total_val; /*sum of valid elements */
+};
+
+struct false_alarm_statistics {
+ u32 cnt_parity_fail;
+ u32 cnt_rate_illegal;
+ u32 cnt_crc8_fail;
+ u32 cnt_mcs_fail;
+ u32 cnt_ofdm_fail;
+ u32 cnt_cck_fail;
+ u32 cnt_all;
+};
+
+struct init_gain {
+ u8 xaagccore1;
+ u8 xbagccore1;
+ u8 xcagccore1;
+ u8 xdagccore1;
+ u8 cca;
+
+};
+
+struct wireless_stats {
+ unsigned long txbytesunicast;
+ unsigned long txbytesmulticast;
+ unsigned long txbytesbroadcast;
+ unsigned long rxbytesunicast;
+
+ long rx_snr_db[4];
+ /*Correct smoothed ss in Dbm, only used
+ in driver to report real power now. */
+ long recv_signal_power;
+ long signal_quality;
+ long last_sigstrength_inpercent;
+
+ u32 rssi_calculate_cnt;
+
+ /*Transformed, in dbm. Beautified signal
+ strength for UI, not correct. */
+ long signal_strength;
+
+ u8 rx_rssi_percentage[4];
+ u8 rx_evm_percentage[2];
+
+ struct rt_smooth_data ui_rssi;
+ struct rt_smooth_data ui_link_quality;
+};
+
+struct rate_adaptive {
+ u8 rate_adaptive_disabled;
+ u8 ratr_state;
+ u16 reserve;
+
+ u32 high_rssi_thresh_for_ra;
+ u32 high2low_rssi_thresh_for_ra;
+ u8 low2high_rssi_thresh_for_ra40m;
+ u32 low_rssi_thresh_for_ra40M;
+ u8 low2high_rssi_thresh_for_ra20m;
+ u32 low_rssi_thresh_for_ra20M;
+ u32 upper_rssi_threshold_ratr;
+ u32 middleupper_rssi_threshold_ratr;
+ u32 middle_rssi_threshold_ratr;
+ u32 middlelow_rssi_threshold_ratr;
+ u32 low_rssi_threshold_ratr;
+ u32 ultralow_rssi_threshold_ratr;
+ u32 low_rssi_threshold_ratr_40m;
+ u32 low_rssi_threshold_ratr_20m;
+ u8 ping_rssi_enable;
+ u32 ping_rssi_ratr;
+ u32 ping_rssi_thresh_for_ra;
+ u32 last_ratr;
+ u8 pre_ratr_state;
+};
+
+struct regd_pair_mapping {
+ u16 reg_dmnenum;
+ u16 reg_5ghz_ctl;
+ u16 reg_2ghz_ctl;
+};
+
+struct rtl_regulatory {
+ char alpha2[2];
+ u16 country_code;
+ u16 max_power_level;
+ u32 tp_scale;
+ u16 current_rd;
+ u16 current_rd_ext;
+ int16_t power_limit;
+ struct regd_pair_mapping *regpair;
+};
+
+struct rtl_rfkill {
+ bool rfkill_state; /*0 is off, 1 is on */
+};
+
+struct rtl_phy {
+ struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */
+ struct init_gain initgain_backup;
+ enum io_type current_io_type;
+
+ u8 rf_mode;
+ u8 rf_type;
+ u8 current_chan_bw;
+ u8 set_bwmode_inprogress;
+ u8 sw_chnl_inprogress;
+ u8 sw_chnl_stage;
+ u8 sw_chnl_step;
+ u8 current_channel;
+ u8 h2c_box_num;
+ u8 set_io_inprogress;
+
+ /*record for power tracking*/
+ s32 reg_e94;
+ s32 reg_e9c;
+ s32 reg_ea4;
+ s32 reg_eac;
+ s32 reg_eb4;
+ s32 reg_ebc;
+ s32 reg_ec4;
+ s32 reg_ecc;
+ u8 rfpienable;
+ u8 reserve_0;
+ u16 reserve_1;
+ u32 reg_c04, reg_c08, reg_874;
+ u32 adda_backup[16];
+ u32 iqk_mac_backup[IQK_MAC_REG_NUM];
+ u32 iqk_bb_backup[10];
+
+ bool b_rfpi_enable;
+
+ u8 pwrgroup_cnt;
+ u8 bcck_high_power;
+ /* 3 groups of pwr diff by rates*/
+ u32 mcs_txpwrlevel_origoffset[4][16];
+ u8 default_initialgain[4];
+
+ /*the current Tx power level*/
+ u8 cur_cck_txpwridx;
+ u8 cur_ofdm24g_txpwridx;
+
+ u32 rfreg_chnlval[2];
+ bool b_apk_done;
+
+ /*fsync*/
+ u8 framesync;
+ u32 framesync_c34;
+
+ u8 num_total_rfpath;
+};
+
+#define MAX_TID_COUNT 9
+#define RTL_AGG_OFF 0
+#define RTL_AGG_ON 1
+#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2
+#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3
+
+struct rtl_ht_agg {
+ u16 txq_id;
+ u16 wait_for_ba;
+ u16 start_idx;
+ u64 bitmap;
+ u32 rate_n_flags;
+ u8 agg_state;
+};
+
+struct rtl_tid_data {
+ u16 seq_number;
+ struct rtl_ht_agg agg;
+};
+
+struct rtl_priv;
+struct rtl_io {
+ struct device *dev;
+
+ /*PCI MEM map */
+ unsigned long pci_mem_end; /*shared mem end */
+ unsigned long pci_mem_start; /*shared mem start */
+
+ /*PCI IO map */
+ unsigned long pci_base_addr; /*device I/O address */
+
+ void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val);
+ void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val);
+ void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val);
+
+ u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr);
+ u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr);
+ u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);
+
+};
+
+struct rtl_mac {
+ u8 mac_addr[ETH_ALEN];
+ u8 mac80211_registered;
+ u8 beacon_enabled;
+
+ u32 tx_ss_num;
+ u32 rx_ss_num;
+
+ struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
+ struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
+ enum nl80211_iftype opmode;
+
+ /*Probe Beacon management */
+ struct rtl_tid_data tids[MAX_TID_COUNT];
+ enum rtl_link_state link_state;
+
+ int n_channels;
+ int n_bitrates;
+
+ /*filters */
+ u32 rx_conf;
+ u16 rx_mgt_filter;
+ u16 rx_ctrl_filter;
+ u16 rx_data_filter;
+
+ bool act_scanning;
+ u8 cnt_after_linked;
+
+ /*RDG*/ bool rdg_en;
+
+ /*AP*/ u8 bssid[6];
+ u8 mcs[16]; /*16 bytes mcs for HT rates.*/
+ u32 basic_rates; /*b/g rates*/
+ u8 ht_enable;
+ u8 sgi_40;
+ u8 sgi_20;
+ u8 bw_40;
+ u8 mode; /*wireless mode*/
+ u8 slot_time;
+ u8 short_preamble;
+ u8 use_cts_protect;
+ u8 cur_40_prime_sc;
+ u8 cur_40_prime_sc_bk;
+ u64 tsf;
+ u8 retry_short;
+ u8 retry_long;
+ u16 assoc_id;
+
+ /*IBSS*/ int beacon_interval;
+
+ /*AMPDU*/ u8 min_space_cfg; /*For Min spacing configurations */
+ u8 max_mss_density;
+ u8 current_ampdu_factor;
+ u8 current_ampdu_density;
+
+ /*QOS & EDCA */
+ struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
+ struct rtl_qos_parameters ac[AC_MAX];
+};
+
+struct rtl_hal {
+ struct ieee80211_hw *hw;
+
+ enum intf_type interface;
+ u16 hw_type; /*92c or 92d or 92s and so on */
+ u8 oem_id;
+ u8 version; /*version of chip */
+ u8 state; /*stop 0, start 1 */
+
+ /*firmware */
+ u8 *pfirmware;
+ bool b_h2c_setinprogress;
+ u8 last_hmeboxnum;
+ bool bfw_ready;
+ /*Reserve page start offset except beacon in TxQ. */
+ u8 fw_rsvdpage_startoffset;
+};
+
+struct rtl_security {
+ /*default 0 */
+ bool use_sw_sec;
+
+ bool being_setkey;
+ bool use_defaultkey;
+ /*Encryption Algorithm for Unicast Packet */
+ enum rt_enc_alg pairwise_enc_algorithm;
+ /*Encryption Algorithm for Brocast/Multicast */
+ enum rt_enc_alg group_enc_algorithm;
+
+ /*local Key buffer, indx 0 is for
+ pairwise key 1-4 is for agoup key. */
+ u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
+ u8 key_len[KEY_BUF_SIZE];
+
+ /*The pointer of Pairwise Key,
+ it always points to KeyBuf[4] */
+ u8 *pairwise_key;
+};
+
+struct rtl_dm {
+ /*PHY status for DM */
+ long entry_min_undecoratedsmoothed_pwdb;
+ long undecorated_smoothed_pwdb; /*out dm */
+ long entry_max_undecoratedsmoothed_pwdb;
+ bool b_dm_initialgain_enable;
+ bool bdynamic_txpower_enable;
+ bool bcurrent_turbo_edca;
+ bool bis_any_nonbepkts; /*out dm */
+ bool bis_cur_rdlstate;
+ bool btxpower_trackingInit;
+ bool b_disable_framebursting;
+ bool b_cck_inch14;
+ bool btxpower_tracking;
+ bool b_useramask;
+ bool brfpath_rxenable[4];
+
+ u8 thermalvalue_iqk;
+ u8 thermalvalue_lck;
+ u8 thermalvalue;
+ u8 last_dtp_lvl;
+ u8 dynamic_txhighpower_lvl; /*Tx high power level */
+ u8 dm_flag; /*Indicate if each dynamic mechanism's status. */
+ u8 dm_type;
+ u8 txpower_track_control;
+
+ char ofdm_index[2];
+ char cck_index;
+};
+
+#define EFUSE_MAX_LOGICAL_SIZE 128
+
+struct rtl_efuse {
+ bool bautoLoad_ok;
+ bool bootfromefuse;
+ u16 max_physical_size;
+ u8 contents[EFUSE_MAX_LOGICAL_SIZE];
+
+ u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE];
+ u16 efuse_usedbytes;
+ u8 efuse_usedpercentage;
+
+ u8 autoload_failflag;
+
+ short epromtype;
+ u16 eeprom_vid;
+ u16 eeprom_did;
+ u16 eeprom_svid;
+ u16 eeprom_smid;
+ u8 eeprom_oemid;
+ u16 eeprom_channelplan;
+ u8 eeprom_version;
+
+ u8 dev_addr[6];
+
+ bool b_txpwr_fromeprom;
+ u8 eeprom_tssi[2];
+ u8 eeprom_pwrlimit_ht20[3];
+ u8 eeprom_pwrlimit_ht40[3];
+ u8 eeprom_chnlarea_txpwr_cck[2][3];
+ u8 eeprom_chnlarea_txpwr_ht40_1s[2][3];
+ u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][3];
+ u8 txpwrlevel_cck[2][14];
+ u8 txpwrlevel_ht40_1s[2][14]; /*For HT 40MHZ pwr */
+ u8 txpwrlevel_ht40_2s[2][14]; /*For HT 40MHZ pwr */
+
+ /*For power group */
+ u8 pwrgroup_ht20[2][14];
+ u8 pwrgroup_ht40[2][14];
+
+ char txpwr_ht20diff[2][14]; /*HT 20<->40 Pwr diff */
+ u8 txpwr_legacyhtdiff[2][14]; /*For HT<->legacy pwr diff */
+
+ u8 eeprom_regulatory;
+ u8 eeprom_thermalmeter;
+ /*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */
+ u8 thermalmeter[2];
+
+ u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */
+ bool b_apk_thermalmeterignore;
+};
+
+struct rtl_ps_ctl {
+ bool set_rfpowerstate_inprogress;
+ bool b_in_powersavemode;
+ bool rfchange_inprogress;
+ bool b_swrf_processing;
+ bool b_hwradiooff;
+
+ u32 last_sleep_jiffies;
+ u32 last_awake_jiffies;
+ u32 last_delaylps_stamp_jiffies;
+
+ /*
+ * just for PCIE ASPM
+ * If it supports ASPM, Offset[560h] = 0x40,
+ * otherwise Offset[560h] = 0x00.
+ * */
+ bool b_support_aspm;
+ bool b_support_backdoor;
+
+ /*for LPS */
+ enum rt_psmode dot11_psmode; /*Power save mode configured. */
+ bool b_leisure_ps;
+ bool b_fwctrl_lps;
+ u8 fwctrl_psmode;
+ /*For Fw control LPS mode */
+ u8 b_reg_fwctrl_lps;
+ /*Record Fw PS mode status. */
+ bool b_fw_current_inpsmode;
+ u8 reg_max_lps_awakeintvl;
+ bool report_linked;
+
+ /*for IPS */
+ bool b_inactiveps;
+
+ u32 rfoff_reason;
+
+ /*RF OFF Level */
+ u32 cur_ps_level;
+ u32 reg_rfps_level;
+
+ /*just for PCIE ASPM */
+ u8 const_amdpci_aspm;
+
+ enum rf_pwrstate inactive_pwrstate;
+ enum rf_pwrstate rfpwr_state; /*cur power state */
+};
+
+struct rtl_stats {
+ u32 mac_time[2];
+ s8 rssi;
+ u8 signal;
+ u8 noise;
+ u16 rate; /*in 100 kbps */
+ u8 received_channel;
+ u8 control;
+ u8 mask;
+ u8 freq;
+ u16 len;
+ u64 tsf;
+ u32 beacon_time;
+ u8 nic_type;
+ u16 length;
+ u8 signalquality; /*in 0-100 index. */
+ /*
+ * Real power in dBm for this packet,
+ * no beautification and aggregation.
+ * */
+ s32 recvsignalpower;
+ s8 rxpower; /*in dBm Translate from PWdB */
+ u8 signalstrength; /*in 0-100 index. */
+ u16 b_hwerror:1;
+ u16 b_crc:1;
+ u16 b_icv:1;
+ u16 b_shortpreamble:1;
+ u16 antenna:1;
+ u16 decrypted:1;
+ u16 wakeup:1;
+ u32 timestamp_low;
+ u32 timestamp_high;
+
+ u8 rx_drvinfo_size;
+ u8 rx_bufshift;
+ bool b_isampdu;
+ bool rx_is40Mhzpacket;
+ u32 rx_pwdb_all;
+ u8 rx_mimo_signalstrength[4]; /*in 0~100 index */
+ s8 rx_mimo_signalquality[2];
+ bool b_packet_matchbssid;
+ bool b_is_cck;
+ bool b_packet_toself;
+ bool b_packet_beacon; /*for rssi */
+ char cck_adc_pwdb[4]; /*for rx path selection */
+};
+
+struct rt_link_detect {
+ u32 num_tx_in4period[4];
+ u32 num_rx_in4period[4];
+
+ u32 num_tx_inperiod;
+ u32 num_rx_inperiod;
+
+ bool b_busytraffic;
+ bool b_higher_busytraffic;
+ bool b_higher_busyrxtraffic;
+};
+
+struct rtl_tcb_desc {
+ u8 b_packet_bw:1;
+ u8 b_multicast:1;
+ u8 b_broadcast:1;
+
+ u8 b_rts_stbc:1;
+ u8 b_rts_enable:1;
+ u8 b_cts_enable:1;
+ u8 b_rts_use_shortpreamble:1;
+ u8 b_rts_use_shortgi:1;
+ u8 rts_sc:1;
+ u8 b_rts_bw:1;
+ u8 rts_rate;
+
+ u8 use_shortgi:1;
+ u8 use_shortpreamble:1;
+ u8 use_driver_rate:1;
+ u8 disable_ratefallback:1;
+
+ u8 ratr_index;
+ u8 mac_id;
+ u8 hw_rate;
+};
+
+struct rtl_hal_ops {
+ int (*init_sw_vars) (struct ieee80211_hw *hw);
+ void (*deinit_sw_vars) (struct ieee80211_hw *hw);
+ void (*read_eeprom_info) (struct ieee80211_hw *hw);
+ void (*interrupt_recognized) (struct ieee80211_hw *hw,
+ u32 *p_inta, u32 *p_intb);
+ int (*hw_init) (struct ieee80211_hw *hw);
+ void (*hw_disable) (struct ieee80211_hw *hw);
+ void (*enable_interrupt) (struct ieee80211_hw *hw);
+ void (*disable_interrupt) (struct ieee80211_hw *hw);
+ int (*set_network_type) (struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
+ void (*set_bw_mode) (struct ieee80211_hw *hw,
+ enum nl80211_channel_type ch_type);
+ u8(*switch_channel) (struct ieee80211_hw *hw);
+ void (*set_qos) (struct ieee80211_hw *hw, int aci);
+ void (*set_bcn_reg) (struct ieee80211_hw *hw);
+ void (*set_bcn_intv) (struct ieee80211_hw *hw);
+ void (*update_interrupt_mask) (struct ieee80211_hw *hw,
+ u32 add_msr, u32 rm_msr);
+ void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
+ void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
+ void (*update_rate_table) (struct ieee80211_hw *hw);
+ void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);
+ void (*fill_tx_desc) (struct ieee80211_hw *hw,
+ struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+ struct ieee80211_tx_info *info,
+ struct sk_buff *skb, unsigned int queue_index);
+ void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
+ bool b_firstseg, bool b_lastseg,
+ struct sk_buff *skb);
+ bool(*query_rx_desc) (struct ieee80211_hw *hw,
+ struct rtl_stats *stats,
+ struct ieee80211_rx_status *rx_status,
+ u8 *pdesc, struct sk_buff *skb);
+ void (*set_channel_access) (struct ieee80211_hw *hw);
+ bool(*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid);
+ void (*dm_watchdog) (struct ieee80211_hw *hw);
+ void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation);
+ bool(*set_rf_power_state) (struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
+ void (*led_control) (struct ieee80211_hw *hw,
+ enum led_ctl_mode ledaction);
+ void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+ u32(*get_desc) (u8 *pdesc, bool istx, u8 desc_name);
+ void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue);
+ void (*enable_hw_sec) (struct ieee80211_hw *hw);
+ void (*set_key) (struct ieee80211_hw *hw, u32 key_index,
+ u8 *p_macaddr, bool is_group, u8 enc_algo,
+ bool is_wepkey, bool clear_all);
+ void (*init_sw_leds) (struct ieee80211_hw *hw);
+ void (*deinit_sw_leds) (struct ieee80211_hw *hw);
+ u32(*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
+ void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+ u32 data);
+ u32(*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask);
+ void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
+ u32 regaddr, u32 bitmask, u32 data);
+};
+
+struct rtl_intf_ops {
+ /*com */
+ int (*adapter_start) (struct ieee80211_hw *hw);
+ void (*adapter_stop) (struct ieee80211_hw *hw);
+
+ int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb);
+ int (*reset_trx_ring) (struct ieee80211_hw *hw);
+
+ /*pci */
+ void (*disable_aspm) (struct ieee80211_hw *hw);
+ void (*enable_aspm) (struct ieee80211_hw *hw);
+
+ /*usb */
+};
+
+struct rtl_mod_params {
+ /* default: 0 = using hardware encryption */
+ int sw_crypto;
+};
+
+struct rtl_hal_cfg {
+ char *name;
+ char *fw_name;
+ struct rtl_hal_ops *ops;
+ struct rtl_mod_params *mod_params;
+
+ /*this map used for some registers or vars
+ defined int HAL but used in MAIN */
+ u32 maps[RTL_VAR_MAP_MAX];
+
+};
+
+struct rtl_locks {
+ /* mutex */
+ struct mutex conf_mutex;
+
+ /*spin lock */
+ spinlock_t ips_lock;
+ spinlock_t irq_th_lock;
+ spinlock_t h2c_lock;
+ spinlock_t rf_ps_lock;
+ spinlock_t rf_lock;
+ spinlock_t lps_lock;
+};
+
+struct rtl_works {
+ struct ieee80211_hw *hw;
+
+ /*timer */
+ struct timer_list watchdog_timer;
+
+ /*task */
+ struct tasklet_struct irq_tasklet;
+ struct tasklet_struct irq_prepare_bcn_tasklet;
+
+ /*work queue */
+ struct workqueue_struct *rtl_wq;
+ struct delayed_work watchdog_wq;
+ struct delayed_work ips_nic_off_wq;
+};
+
+struct rtl_debug {
+ u32 dbgp_type[DBGP_TYPE_MAX];
+ u32 global_debuglevel;
+ u64 global_debugcomponents;
+};
+
+struct rtl_priv {
+ struct rtl_locks locks;
+ struct rtl_works works;
+ struct rtl_mac mac80211;
+ struct rtl_hal rtlhal;
+ struct rtl_regulatory regd;
+ struct rtl_rfkill rfkill;
+ struct rtl_io io;
+ struct rtl_phy phy;
+ struct rtl_dm dm;
+ struct rtl_security sec;
+ struct rtl_efuse efuse;
+
+ struct rtl_ps_ctl psc;
+ struct rate_adaptive ra;
+ struct wireless_stats stats;
+ struct rt_link_detect link_info;
+ struct false_alarm_statistics falsealm_cnt;
+
+ struct rtl_rate_priv *rate_priv;
+
+ struct rtl_debug dbg;
+
+ /*
+ *hal_cfg : for diff cards
+ *intf_ops : for diff interrface usb/pcie
+ */
+ struct rtl_hal_cfg *cfg;
+ struct rtl_intf_ops *intf_ops;
+
+ /*this var will be set by set_bit,
+ and was used to indicate status of
+ interface or hardware */
+ unsigned long status;
+
+ /*This must be the last item so
+ that it points to the data allocated
+ beyond this structure like:
+ rtl_pci_priv or rtl_usb_priv */
+ u8 priv[0];
+};
+
+#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv))
+#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211))
+#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal))
+#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse))
+#define rtl_psc(rtlpriv) (&((rtlpriv)->psc))
+
+/****************************************
+ mem access macro define start
+ Call endian free function when
+ 1. Read/write packet content.
+ 2. Before write integer to IO.
+ 3. After read integer from IO.
+****************************************/
+/* Convert little data endian to host */
+#define EF1BYTE(_val) \
+ ((u8)(_val))
+#define EF2BYTE(_val) \
+ (le16_to_cpu(_val))
+#define EF4BYTE(_val) \
+ (le32_to_cpu(_val))
+
+/* Read data from memory */
+#define READEF1BYTE(_ptr) \
+ EF1BYTE(*((u8 *)(_ptr)))
+#define READEF2BYTE(_ptr) \
+ EF2BYTE(*((u16 *)(_ptr)))
+#define READEF4BYTE(_ptr) \
+ EF4BYTE(*((u32 *)(_ptr)))
+
+/* Write data to memory */
+#define WRITEEF1BYTE(_ptr, _val) \
+ (*((u8 *)(_ptr))) = EF1BYTE(_val)
+#define WRITEEF2BYTE(_ptr, _val) \
+ (*((u16 *)(_ptr))) = EF2BYTE(_val)
+#define WRITEEF4BYTE(_ptr, _val) \
+ (*((u32 *)(_ptr))) = EF4BYTE(_val)
+
+/*Example:
+BIT_LEN_MASK_32(0) => 0x00000000
+BIT_LEN_MASK_32(1) => 0x00000001
+BIT_LEN_MASK_32(2) => 0x00000003
+BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/
+#define BIT_LEN_MASK_32(__bitlen) \
+ (0xFFFFFFFF >> (32 - (__bitlen)))
+#define BIT_LEN_MASK_16(__bitlen) \
+ (0xFFFF >> (16 - (__bitlen)))
+#define BIT_LEN_MASK_8(__bitlen) \
+ (0xFF >> (8 - (__bitlen)))
+
+/*Example:
+BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
+BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/
+#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_32(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_16(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \
+ (BIT_LEN_MASK_8(__bitlen) << (__bitoffset))
+
+/*Description:
+Return 4-byte value in host byte ordering from
+4-byte pointer in little-endian system.*/
+#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \
+ (EF4BYTE(*((u32 *)(__pstart))))
+#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \
+ (EF2BYTE(*((u16 *)(__pstart))))
+#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
+ (EF1BYTE(*((u8 *)(__pstart))))
+
+/*Description:
+Translate subfield (continuous bits in little-endian) of 4-byte
+value to host byte ordering.*/
+#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_32(__bitlen) \
+ )
+#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_16(__bitlen) \
+ )
+#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
+ BIT_LEN_MASK_8(__bitlen) \
+ )
+
+/*Description:
+Mask subfield (continuous bits in little-endian) of 4-byte value
+and return the result in 4-byte value in host byte ordering.*/
+#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \
+ )
+#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \
+ )
+#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+ ( \
+ LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \
+ (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \
+ )
+
+/*Description:
+Set subfield of little-endian 4-byte value to specified value. */
+#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ *((u32 *)(__pstart)) = EF4BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
+ );
+#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ *((u16 *)(__pstart)) = EF2BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
+ );
+#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
+ *((u8 *)(__pstart)) = EF1BYTE \
+ ( \
+ LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \
+ ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
+ );
+
+/****************************************
+ mem access macro define end
+****************************************/
+
+#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
+#define RTL_WATCH_DOG_TIME 2000
+#define MSECS(t) msecs_to_jiffies(t)
+#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 SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
+#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
+
+#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */
+#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */
+#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */
+/*NIC halt, re-initialize hw parameters*/
+#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
+#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */
+#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */
+/*Always enable ASPM and Clock Req in initialization.*/
+#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6)
+/*When LPS is on, disable 2R if no packet is received or transmittd.*/
+#define RT_RF_LPS_DISALBE_2R BIT(30)
+#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */
+#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \
+ ((ppsc->cur_ps_level & _ps_flg) ? true : false)
+#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \
+ (ppsc->cur_ps_level &= (~(_ps_flg)))
+#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \
+ (ppsc->cur_ps_level |= _ps_flg)
+
+#define container_of_dwork_rtl(x, y, z) \
+ container_of(container_of(x, struct delayed_work, work), y, z)
+
+#define FILL_OCTET_STRING(_os, _octet, _len) \
+ (_os).octet = (u8 *)(_octet); \
+ (_os).length = (_len);
+
+#define CP_MACADDR(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])
+
+static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read8_sync(rtlpriv, addr);
+}
+
+static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read16_sync(rtlpriv, addr);
+}
+
+static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)
+{
+ return rtlpriv->io.read32_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
+{
+ rtlpriv->io.write8_async(rtlpriv, addr, val8);
+}
+
+static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
+{
+ rtlpriv->io.write16_async(rtlpriv, addr, val16);
+}
+
+static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
+ u32 addr, u32 val32)
+{
+ rtlpriv->io.write32_async(rtlpriv, addr, val32);
+}
+
+static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
+ u32 regaddr, u32 bitmask)
+{
+ return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_bbreg(hw,
+ regaddr,
+ bitmask);
+}
+
+static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr,
+ u32 bitmask, u32 data)
+{
+ ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_bbreg(hw,
+ regaddr, bitmask,
+ data);
+
+}
+
+static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask)
+{
+ return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_rfreg(hw,
+ rfpath,
+ regaddr,
+ bitmask);
+}
+
+static inline void rtl_set_rfreg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr,
+ u32 bitmask, u32 data)
+{
+ ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_rfreg(hw,
+ rfpath, regaddr,
+ bitmask, data);
+}
+
+static inline bool is_hal_stop(struct rtl_hal *rtlhal)
+{
+ return (_HAL_STATE_STOP == rtlhal->state);
+}
+
+static inline void set_hal_start(struct rtl_hal *rtlhal)
+{
+ rtlhal->state = _HAL_STATE_START;
+}
+
+static inline void set_hal_stop(struct rtl_hal *rtlhal)
+{
+ rtlhal->state = _HAL_STATE_STOP;
+}
+
+static inline u8 get_rf_type(struct rtl_phy *rtlphy)
+{
+ return rtlphy->rf_type;
+}
+
+#endif
diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/wl1251/boot.c
index 61572dfa1f60..d729daf8e841 100644
--- a/drivers/net/wireless/wl1251/boot.c
+++ b/drivers/net/wireless/wl1251/boot.c
@@ -19,7 +19,6 @@
*
*/
-#include <linux/gpio.h>
#include <linux/slab.h>
#include "reg.h"
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 7a8762553cdc..012e1a4016fe 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -52,14 +52,14 @@ void wl1251_disable_interrupts(struct wl1251 *wl)
wl->if_ops->disable_irq(wl);
}
-static void wl1251_power_off(struct wl1251 *wl)
+static int wl1251_power_off(struct wl1251 *wl)
{
- wl->set_power(false);
+ return wl->if_ops->power(wl, false);
}
-static void wl1251_power_on(struct wl1251 *wl)
+static int wl1251_power_on(struct wl1251 *wl)
{
- wl->set_power(true);
+ return wl->if_ops->power(wl, true);
}
static int wl1251_fetch_firmware(struct wl1251 *wl)
@@ -152,9 +152,12 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
static int wl1251_chip_wakeup(struct wl1251 *wl)
{
- int ret = 0;
+ int ret;
+
+ ret = wl1251_power_on(wl);
+ if (ret < 0)
+ return ret;
- wl1251_power_on(wl);
msleep(WL1251_POWER_ON_SLEEP);
wl->if_ops->reset(wl);
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 74ba9ced5393..d550b5e68d3c 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <linux/wl12xx.h>
#include <linux/irq.h>
+#include <linux/pm_runtime.h>
#include "wl1251.h"
@@ -42,8 +43,6 @@ struct wl1251_sdio {
u32 elp_val;
};
-static struct wl12xx_platform_data *wl12xx_board_data;
-
static struct sdio_func *wl_to_func(struct wl1251 *wl)
{
struct wl1251_sdio *wl_sdio = wl->if_priv;
@@ -171,8 +170,42 @@ static void wl1251_disable_line_irq(struct wl1251 *wl)
return disable_irq(wl->irq);
}
-static void wl1251_sdio_set_power(bool enable)
+static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
{
+ struct sdio_func *func = wl_to_func(wl);
+ int ret;
+
+ if (enable) {
+ /*
+ * Power is controlled by runtime PM, but we still call board
+ * callback in case it wants to do any additional setup,
+ * for example enabling clock buffer for the module.
+ */
+ if (wl->set_power)
+ wl->set_power(true);
+
+ ret = pm_runtime_get_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
+ } else {
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ ret = pm_runtime_put_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ if (wl->set_power)
+ wl->set_power(false);
+ }
+
+out:
+ return ret;
}
static struct wl1251_if_operations wl1251_sdio_ops = {
@@ -181,30 +214,7 @@ static struct wl1251_if_operations wl1251_sdio_ops = {
.write_elp = wl1251_sdio_write_elp,
.read_elp = wl1251_sdio_read_elp,
.reset = wl1251_sdio_reset,
-};
-
-static int wl1251_platform_probe(struct platform_device *pdev)
-{
- if (pdev->id != -1) {
- wl1251_error("can only handle single device");
- return -ENODEV;
- }
-
- wl12xx_board_data = pdev->dev.platform_data;
- return 0;
-}
-
-/*
- * Dummy platform_driver for passing platform_data to this driver,
- * until we have a way to pass this through SDIO subsystem or
- * some other way.
- */
-static struct platform_driver wl1251_platform_driver = {
- .driver = {
- .name = "wl1251_data",
- .owner = THIS_MODULE,
- },
- .probe = wl1251_platform_probe,
+ .power = wl1251_sdio_set_power,
};
static int wl1251_sdio_probe(struct sdio_func *func,
@@ -214,6 +224,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
struct wl1251 *wl;
struct ieee80211_hw *hw;
struct wl1251_sdio *wl_sdio;
+ const struct wl12xx_platform_data *wl12xx_board_data;
hw = wl1251_alloc_hw();
if (IS_ERR(hw))
@@ -239,9 +250,9 @@ static int wl1251_sdio_probe(struct sdio_func *func,
wl_sdio->func = func;
wl->if_priv = wl_sdio;
wl->if_ops = &wl1251_sdio_ops;
- wl->set_power = wl1251_sdio_set_power;
- if (wl12xx_board_data != NULL) {
+ wl12xx_board_data = wl12xx_get_platform_data();
+ if (!IS_ERR(wl12xx_board_data)) {
wl->set_power = wl12xx_board_data->set_power;
wl->irq = wl12xx_board_data->irq;
wl->use_eeprom = wl12xx_board_data->use_eeprom;
@@ -273,6 +284,10 @@ static int wl1251_sdio_probe(struct sdio_func *func,
goto out_free_irq;
sdio_set_drvdata(func, wl);
+
+ /* Tell PM core that we don't need the card to be powered now */
+ pm_runtime_put_noidle(&func->dev);
+
return ret;
out_free_irq:
@@ -294,6 +309,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
struct wl1251 *wl = sdio_get_drvdata(func);
struct wl1251_sdio *wl_sdio = wl->if_priv;
+ /* Undo decrement done above in wl1251_probe */
+ pm_runtime_get_noresume(&func->dev);
+
if (wl->irq)
free_irq(wl->irq, wl);
kfree(wl_sdio);
@@ -305,23 +323,37 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
sdio_release_host(func);
}
+static int wl1251_suspend(struct device *dev)
+{
+ /*
+ * Tell MMC/SDIO core it's OK to power down the card
+ * (if it isn't already), but not to remove it completely.
+ */
+ return 0;
+}
+
+static int wl1251_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops wl1251_sdio_pm_ops = {
+ .suspend = wl1251_suspend,
+ .resume = wl1251_resume,
+};
+
static struct sdio_driver wl1251_sdio_driver = {
.name = "wl1251_sdio",
.id_table = wl1251_devices,
.probe = wl1251_sdio_probe,
.remove = __devexit_p(wl1251_sdio_remove),
+ .drv.pm = &wl1251_sdio_pm_ops,
};
static int __init wl1251_sdio_init(void)
{
int err;
- err = platform_driver_register(&wl1251_platform_driver);
- if (err) {
- wl1251_error("failed to register platform driver: %d", err);
- return err;
- }
-
err = sdio_register_driver(&wl1251_sdio_driver);
if (err)
wl1251_error("failed to register sdio driver: %d", err);
@@ -331,7 +363,6 @@ static int __init wl1251_sdio_init(void)
static void __exit wl1251_sdio_exit(void)
{
sdio_unregister_driver(&wl1251_sdio_driver);
- platform_driver_unregister(&wl1251_platform_driver);
wl1251_notice("unloaded");
}
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
index 88fa8e69d0d1..ac872b38960f 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -215,12 +215,21 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
return disable_irq(wl->irq);
}
+static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
+{
+ if (wl->set_power)
+ wl->set_power(enable);
+
+ return 0;
+}
+
static const struct wl1251_if_operations wl1251_spi_ops = {
.read = wl1251_spi_read,
.write = wl1251_spi_write,
.reset = wl1251_spi_reset_wake,
.enable_irq = wl1251_spi_enable_irq,
.disable_irq = wl1251_spi_disable_irq,
+ .power = wl1251_spi_set_power,
};
static int __devinit wl1251_spi_probe(struct spi_device *spi)
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index e113d4c1fb35..13fbeeccf609 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -256,6 +256,7 @@ struct wl1251_if_operations {
void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
+ int (*power)(struct wl1251 *wl, bool enable);
void (*reset)(struct wl1251 *wl);
void (*enable_irq)(struct wl1251 *wl);
void (*disable_irq)(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index b447559f1db5..0e65bce457d6 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -1,46 +1,68 @@
-menuconfig WL12XX
+menuconfig WL12XX_MENU
tristate "TI wl12xx driver support"
depends on MAC80211 && EXPERIMENTAL
---help---
- This will enable TI wl12xx driver support. The drivers make
- use of the mac80211 stack.
+ This will enable TI wl12xx driver support for the following chips:
+ wl1271 and wl1273.
+ The drivers make use of the mac80211 stack.
-config WL1271
- tristate "TI wl1271 support"
- depends on WL12XX && GENERIC_HARDIRQS
+config WL12XX
+ tristate "TI wl12xx support"
+ depends on WL12XX_MENU && GENERIC_HARDIRQS
depends on INET
select FW_LOADER
select CRC7
---help---
- This module adds support for wireless adapters based on the
- TI wl1271 chipset.
+ This module adds support for wireless adapters based on TI wl1271 and
+ TI wl1273 chipsets. This module does *not* include support for wl1251.
+ For wl1251 support, use the separate homonymous driver instead.
- If you choose to build a module, it'll be called wl1271. Say N if
+ If you choose to build a module, it will be called wl12xx. Say N if
unsure.
-config WL1271_SPI
- tristate "TI wl1271 SPI support"
- depends on WL1271 && SPI_MASTER
+config WL12XX_HT
+ bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)"
+ depends on WL12XX && EXPERIMENTAL
+ default n
+ ---help---
+ This will enable 802.11 HT support in the wl12xx module.
+
+ That configuration is temporary due to the code incomplete and
+ still in testing process.
+
+config WL12XX_SPI
+ tristate "TI wl12xx SPI support"
+ depends on WL12XX && SPI_MASTER
---help---
This module adds support for the SPI interface of adapters using
- TI wl1271 chipset. Select this if your platform is using
+ TI wl12xx chipsets. Select this if your platform is using
the SPI bus.
- If you choose to build a module, it'll be called wl1251_spi.
+ If you choose to build a module, it'll be called wl12xx_spi.
Say N if unsure.
-config WL1271_SDIO
- tristate "TI wl1271 SDIO support"
- depends on WL1271 && MMC
+config WL12XX_SDIO
+ tristate "TI wl12xx SDIO support"
+ depends on WL12XX && MMC
---help---
This module adds support for the SDIO interface of adapters using
- TI wl1271 chipset. Select this if your platform is using
+ TI wl12xx chipsets. Select this if your platform is using
the SDIO bus.
- If you choose to build a module, it'll be called
- wl1271_sdio. Say N if unsure.
+ If you choose to build a module, it'll be called wl12xx_sdio.
+ Say N if unsure.
+
+config WL12XX_SDIO_TEST
+ tristate "TI wl12xx SDIO testing support"
+ depends on WL12XX && MMC
+ default n
+ ---help---
+ This module adds support for the SDIO bus testing with the
+ TI wl12xx chipsets. You probably don't want this unless you are
+ testing a new hardware platform. Select this if you want to test the
+ SDIO bus which is connected to the wl12xx chip.
config WL12XX_PLATFORM_DATA
bool
- depends on WL1271_SDIO != n
+ depends on WL12XX_SDIO != n || WL1251_SDIO != n
default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 3a807444b2af..521c0414e52e 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,16 @@
-wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
- wl1271_event.o wl1271_tx.o wl1271_rx.o \
- wl1271_ps.o wl1271_acx.o wl1271_boot.o \
- wl1271_init.o wl1271_debugfs.o wl1271_scan.o
-
-wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
-obj-$(CONFIG_WL1271) += wl1271.o
-obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
-obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
+wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
+ boot.o init.o debugfs.o scan.o
+
+wl12xx_spi-objs = spi.o
+wl12xx_sdio-objs = sdio.o
+wl12xx_sdio_test-objs = sdio_test.o
+
+wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
+obj-$(CONFIG_WL12XX) += wl12xx.o
+obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
+obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
+
+obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/acx.c
index 618993405262..cc4068d2b4a8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -21,7 +21,7 @@
*
*/
-#include "wl1271_acx.h"
+#include "acx.h"
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -29,10 +29,10 @@
#include <linux/spi/spi.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
+#include "reg.h"
+#include "ps.h"
int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
{
@@ -862,7 +862,7 @@ out:
return ret;
}
-int wl1271_acx_frag_threshold(struct wl1271 *wl)
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
{
struct acx_frag_threshold *acx;
int ret = 0;
@@ -876,7 +876,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl)
goto out;
}
- acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold);
+ acx->frag_threshold = cpu_to_le16(frag_threshold);
ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -1041,7 +1041,7 @@ out:
return ret;
}
-int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
+int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
{
struct wl1271_acx_arp_filter *acx;
int ret;
@@ -1057,7 +1057,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
acx->version = ACX_IPV4_VERSION;
acx->enable = enable;
- if (enable == true)
+ if (enable)
memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
@@ -1226,6 +1226,89 @@ out:
return ret;
}
+int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ bool allow_ht_operation)
+{
+ struct wl1271_acx_ht_capabilities *acx;
+ u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx ht capabilities setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Allow HT Operation ? */
+ if (allow_ht_operation) {
+ acx->ht_capabilites =
+ WL1271_ACX_FW_CAP_HT_OPERATION;
+ if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
+ if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
+ if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
+
+ /* get data from A-MPDU parameters field */
+ acx->ampdu_max_length = ht_cap->ampdu_factor;
+ acx->ampdu_min_spacing = ht_cap->ampdu_density;
+
+ memcpy(acx->mac_address, mac_address, ETH_ALEN);
+ } else { /* HT operations are not allowed */
+ acx->ht_capabilites = 0;
+ }
+
+ ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx ht capabilities setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_set_ht_information(struct wl1271 *wl,
+ u16 ht_operation_mode)
+{
+ struct wl1271_acx_ht_information *acx;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx ht information setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->ht_protection =
+ (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
+ acx->rifs_mode = 0;
+ acx->gf_protection = 0;
+ acx->ht_tx_burst_limit = 0;
+ acx->dual_cts_protection = 0;
+
+ ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
+
+ if (ret < 0) {
+ wl1271_warning("acx ht information setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
{
struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/acx.h
index ebb341d36e8c..9cbc3f40c8dd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -22,11 +22,11 @@
*
*/
-#ifndef __WL1271_ACX_H__
-#define __WL1271_ACX_H__
+#ifndef __ACX_H__
+#define __ACX_H__
-#include "wl1271.h"
-#include "wl1271_cmd.h"
+#include "wl12xx.h"
+#include "cmd.h"
/*************************************************************************
@@ -61,7 +61,8 @@
WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
-#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \
+#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
+ WL1271_ACX_INTR_EVENT_A | \
WL1271_ACX_INTR_EVENT_B | \
WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
@@ -867,10 +868,15 @@ struct wl1271_acx_bet_enable {
#define ACX_IPV4_VERSION 4
#define ACX_IPV6_VERSION 6
#define ACX_IPV4_ADDR_SIZE 4
+
+/* bitmap of enabled arp_filter features */
+#define ACX_ARP_FILTER_ARP_FILTERING BIT(0)
+#define ACX_ARP_FILTER_AUTO_ARP BIT(1)
+
struct wl1271_acx_arp_filter {
struct acx_header header;
u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
- u8 enable; /* 1 to enable ARP filtering, 0 to disable */
+ u8 enable; /* bitmap of enabled ARP filtering features */
u8 padding[2];
u8 address[16]; /* The configured device IP address - all ARP
requests directed to this IP address will pass
@@ -964,6 +970,87 @@ struct wl1271_acx_rssi_snr_avg_weights {
u8 snr_data;
};
+/*
+ * ACX_PEER_HT_CAP
+ * Configure HT capabilities - declare the capabilities of the peer
+ * we are connected to.
+ */
+struct wl1271_acx_ht_capabilities {
+ struct acx_header header;
+
+ /*
+ * bit 0 - Allow HT Operation
+ * bit 1 - Allow Greenfield format in TX
+ * bit 2 - Allow Short GI in TX
+ * bit 3 - Allow L-SIG TXOP Protection in TX
+ * bit 4 - Allow HT Control fields in TX.
+ * Note, driver will still leave space for HT control in packets
+ * regardless of the value of this field. FW will be responsible
+ * to drop the HT field from any frame when this Bit set to 0.
+ * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
+ * Exact policy setting for this feature is TBD.
+ * Note, this bit can only be set to 1 if bit 3 is set to 1.
+ */
+ __le32 ht_capabilites;
+
+ /*
+ * Indicates to which peer these capabilities apply.
+ * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance
+ * for all peers.
+ * Only valid for IBSS/DLS operation.
+ */
+ u8 mac_address[ETH_ALEN];
+
+ /*
+ * This the maximum A-MPDU length supported by the AP. The FW may not
+ * exceed this length when sending A-MPDUs
+ */
+ u8 ampdu_max_length;
+
+ /* This is the minimal spacing required when sending A-MPDUs to the AP*/
+ u8 ampdu_min_spacing;
+} __packed;
+
+/* HT Capabilites Fw Bit Mask Mapping */
+#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0)
+#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1)
+#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2)
+#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3)
+#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4)
+#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5)
+
+
+/*
+ * ACX_HT_BSS_OPERATION
+ * Configure HT capabilities - AP rules for behavior in the BSS.
+ */
+struct wl1271_acx_ht_information {
+ struct acx_header header;
+
+ /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
+ u8 rifs_mode;
+
+ /* Values: 0 - 3 like in spec */
+ u8 ht_protection;
+
+ /* Values: 0 - GF protection not required, 1 - GF protection required */
+ u8 gf_protection;
+
+ /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/
+ u8 ht_tx_burst_limit;
+
+ /*
+ * Values: 0 - Dual CTS protection not required,
+ * 1 - Dual CTS Protection required
+ * Note: When this value is set to 1 FW will protect all TXOP with RTS
+ * frame and will not use CTS-to-self regardless of the value of the
+ * ACX_CTS_PROTECTION information element
+ */
+ u8 dual_cts_protection;
+
+ u8 padding[3];
+} __packed;
+
struct wl1271_acx_fw_tsf_information {
struct acx_header header;
@@ -1079,20 +1166,25 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u8 tsid, u8 ps_scheme, u8 ack_policy,
u32 apsd_conf0, u32 apsd_conf1);
-int wl1271_acx_frag_threshold(struct wl1271 *wl);
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
int wl1271_acx_tx_config_options(struct wl1271 *wl);
int wl1271_acx_mem_cfg(struct wl1271 *wl);
int wl1271_acx_init_mem_config(struct wl1271 *wl);
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
int wl1271_acx_smart_reflex(struct wl1271 *wl);
int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
-int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address);
+int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address);
int wl1271_acx_pm_config(struct wl1271 *wl);
int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
s16 thold, u8 hyst);
int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
+int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ bool allow_ht_operation);
+int wl1271_acx_set_ht_information(struct wl1271 *wl,
+ u16 ht_operation_mode);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/boot.c
index b91021242098..4df04f84d7f1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -21,14 +21,13 @@
*
*/
-#include <linux/gpio.h>
#include <linux/slab.h>
-#include "wl1271_acx.h"
-#include "wl1271_reg.h"
-#include "wl1271_boot.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
+#include "acx.h"
+#include "reg.h"
+#include "boot.h"
+#include "io.h"
+#include "event.h"
static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
[PART_DOWN] = {
@@ -467,24 +466,24 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
wl->hw_pg_ver = (s8)fuse;
}
-int wl1271_boot(struct wl1271 *wl)
+/* uploads NVS and firmware */
+int wl1271_load_firmware(struct wl1271 *wl)
{
int ret = 0;
u32 tmp, clk, pause;
- int ref_clock = wl->ref_clock;
wl1271_boot_hw_version(wl);
- if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
+ if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
- else if (ref_clock == 1 || ref_clock == 3)
+ else if (wl->ref_clock == 1 || wl->ref_clock == 3)
/* ref clk: 26/52 */
clk = 0x5;
else
return -EINVAL;
- if (ref_clock != 0) {
+ if (wl->ref_clock != 0) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -529,8 +528,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
- /* 2 */
- clk |= (ref_clock << 1) << 4;
+ clk |= (wl->ref_clock << 1) << 4;
wl1271_write32(wl, DRPW_SCRATCH_START, clk);
wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -574,6 +572,20 @@ int wl1271_boot(struct wl1271 *wl)
if (ret < 0)
goto out;
+out:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wl1271_load_firmware);
+
+int wl1271_boot(struct wl1271 *wl)
+{
+ int ret;
+
+ /* upload NVS and firmware */
+ ret = wl1271_load_firmware(wl);
+ if (ret)
+ return ret;
+
/* 10.5 start firmware */
ret = wl1271_boot_run_firmware(wl);
if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/boot.h
index f73b0b15a280..d67dcffa31eb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -24,9 +24,10 @@
#ifndef __BOOT_H__
#define __BOOT_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_boot(struct wl1271 *wl);
+int wl1271_load_firmware(struct wl1271 *wl);
#define WL1271_NO_SUBBANDS 8
#define WL1271_NO_POWER_LEVELS 4
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 5d3e8485ea4e..0106628aa5a2 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -29,13 +29,13 @@
#include <linux/ieee80211.h>
#include <linux/slab.h>
-#include "wl1271.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "reg.h"
+#include "io.h"
+#include "acx.h"
#include "wl12xx_80211.h"
-#include "wl1271_cmd.h"
-#include "wl1271_event.h"
+#include "cmd.h"
+#include "event.h"
#define WL1271_CMD_FAST_POLL_COUNT 50
@@ -611,6 +611,75 @@ out:
return ret;
}
+struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
+ struct sk_buff *skb)
+{
+ int ret;
+
+ if (!skb)
+ skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
+ if (!skb)
+ goto out;
+
+ wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
+
+ if (wl->band == IEEE80211_BAND_2GHZ)
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate);
+ else
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ skb->data, skb->len, 0,
+ wl->conf.tx.basic_rate_5);
+
+ if (ret < 0)
+ wl1271_error("Unable to set ap probe request template.");
+
+out:
+ return skb;
+}
+
+int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr)
+{
+ int ret;
+ struct wl12xx_arp_rsp_template tmpl;
+ struct ieee80211_hdr_3addr *hdr;
+ struct arphdr *arp_hdr;
+
+ memset(&tmpl, 0, sizeof(tmpl));
+
+ /* mac80211 header */
+ hdr = &tmpl.hdr;
+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_DATA |
+ IEEE80211_FCTL_TODS);
+ memcpy(hdr->addr1, wl->vif->bss_conf.bssid, ETH_ALEN);
+ memcpy(hdr->addr2, wl->vif->addr, ETH_ALEN);
+ memset(hdr->addr3, 0xff, ETH_ALEN);
+
+ /* llc layer */
+ memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header));
+ tmpl.llc_type = htons(ETH_P_ARP);
+
+ /* arp header */
+ arp_hdr = &tmpl.arp_hdr;
+ arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
+ arp_hdr->ar_pro = htons(ETH_P_IP);
+ arp_hdr->ar_hln = ETH_ALEN;
+ arp_hdr->ar_pln = 4;
+ arp_hdr->ar_op = htons(ARPOP_REPLY);
+
+ /* arp payload */
+ memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN);
+ tmpl.sender_ip = ip_addr;
+
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
+ &tmpl, sizeof(tmpl), 0,
+ wl->basic_rate);
+
+ return ret;
+}
+
int wl1271_build_qos_null_data(struct wl1271 *wl)
{
struct ieee80211_qos_hdr template;
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index a0caf4fc37b1..2a1d9db7ceb8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -22,10 +22,10 @@
*
*/
-#ifndef __WL1271_CMD_H__
-#define __WL1271_CMD_H__
+#ifndef __CMD_H__
+#define __CMD_H__
-#include "wl1271.h"
+#include "wl12xx.h"
struct acx_header;
@@ -49,6 +49,9 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
int wl1271_cmd_build_probe_req(struct wl1271 *wl,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len, u8 band);
+struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
+ struct sk_buff *skb);
+int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr);
int wl1271_build_qos_null_data(struct wl1271 *wl);
int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
@@ -122,6 +125,7 @@ enum cmd_templ {
CMD_TEMPL_CTS, /*
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
+ CMD_TEMPL_ARP_RSP,
CMD_TEMPL_MAX = 0xff
};
@@ -327,9 +331,6 @@ enum wl1271_channel_tune_bands {
#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
-#define TEST_CMD_P2G_CAL 0x02
-#define TEST_CMD_CHANNEL_TUNE 0x0d
-#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
@@ -375,51 +376,6 @@ struct wl1271_ext_radio_parms_cmd {
u8 padding[3];
} __packed;
-struct wl1271_cmd_cal_channel_tune {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- u8 band;
- u8 channel;
-
- __le16 radio_status;
-} __packed;
-
-struct wl1271_cmd_cal_update_ref_point {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- __le32 ref_power;
- __le32 ref_detector;
- u8 sub_band;
- u8 padding[3];
-} __packed;
-
-#define MAX_TLV_LENGTH 400
-#define MAX_NVS_VERSION_LENGTH 12
-
-#define WL1271_CAL_P2G_BAND_B_G BIT(0)
-
-struct wl1271_cmd_cal_p2g {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- __le16 len;
- u8 buf[MAX_TLV_LENGTH];
- u8 type;
- u8 padding;
-
- __le16 radio_status;
- u8 nvs_version[MAX_NVS_VERSION_LENGTH];
-
- u8 sub_band_mask;
- u8 padding2;
-} __packed;
-
-
/*
* There are three types of disconnections:
*
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/conf.h
index 5f78a6cb1433..a16b3616e430 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_CONF_H__
-#define __WL1271_CONF_H__
+#ifndef __CONF_H__
+#define __CONF_H__
enum {
CONF_HW_BIT_RATE_1MBPS = BIT(0),
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
new file mode 100644
index 000000000000..ec6077760157
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -0,0 +1,480 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "debugfs.h"
+
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+#include "ps.h"
+#include "io.h"
+
+/* ms */
+#define WL1271_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+#define DEBUGFS_FORMAT_BUFFER_SIZE 100
+static int wl1271_format_buffer(char __user *userbuf, size_t count,
+ loff_t *ppos, char *fmt, ...)
+{
+ va_list args;
+ char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
+ int res;
+
+ va_start(args, fmt);
+ res = vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
+static ssize_t name## _read(struct file *file, char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl1271 *wl = file->private_data; \
+ return wl1271_format_buffer(userbuf, count, ppos, \
+ fmt "\n", ##value); \
+} \
+ \
+static const struct file_operations name## _ops = { \
+ .read = name## _read, \
+ .open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
+};
+
+#define DEBUGFS_ADD(name, parent) \
+ entry = debugfs_create_file(#name, 0400, parent, \
+ wl, &name## _ops); \
+ if (!entry || IS_ERR(entry)) \
+ goto err; \
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
+static ssize_t sub## _ ##name## _read(struct file *file, \
+ char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl1271 *wl = file->private_data; \
+ \
+ wl1271_debugfs_update_stats(wl); \
+ \
+ return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \
+ wl->stats.fw_stats->sub.name); \
+} \
+ \
+static const struct file_operations sub## _ ##name## _ops = { \
+ .read = sub## _ ##name## _read, \
+ .open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name) \
+ DEBUGFS_ADD(sub## _ ##name, stats)
+
+static void wl1271_debugfs_update_stats(struct wl1271 *wl)
+{
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ if (wl->state == WL1271_STATE_ON &&
+ time_after(jiffies, wl->stats.fw_stats_update +
+ msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
+ wl1271_acx_statistics(wl, wl->stats.fw_stats);
+ wl->stats.fw_stats_update = jiffies;
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl1271_open_file_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, "%u",
+ wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ u32 queue_len;
+ char buf[20];
+ int res;
+
+ queue_len = wl->tx_queue_count;
+
+ res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+ .read = tx_queue_len_read,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
+static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+
+ int res;
+ char buf[10];
+
+ res = scnprintf(buf, sizeof(buf), "%d\n", state);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t gpio_power_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ char buf[10];
+ size_t len;
+ unsigned long value;
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ buf[len] = '\0';
+
+ ret = strict_strtoul(buf, 0, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value in gpio_power");
+ goto out;
+ }
+
+ if (value)
+ wl1271_power_on(wl);
+ else
+ wl1271_power_off(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+static const struct file_operations gpio_power_ops = {
+ .read = gpio_power_read,
+ .write = gpio_power_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
+static int wl1271_debugfs_add_files(struct wl1271 *wl)
+{
+ int ret = 0;
+ struct dentry *entry, *stats;
+
+ stats = debugfs_create_dir("fw-statistics", wl->rootdir);
+ if (!stats || IS_ERR(stats)) {
+ entry = stats;
+ goto err;
+ }
+
+ DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+ DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+ DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+ DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+ DEBUGFS_FWSTATS_ADD(rx, dropped);
+ DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+ DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+ DEBUGFS_FWSTATS_ADD(rx, path_reset);
+ DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+ DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+ DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+ DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+ DEBUGFS_FWSTATS_ADD(isr, fiqs);
+ DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+ DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+ DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+ DEBUGFS_FWSTATS_ADD(isr, irqs);
+ DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+ DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+ DEBUGFS_FWSTATS_ADD(isr, commands);
+ DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+ DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+ DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+ DEBUGFS_FWSTATS_ADD(isr, wakeups);
+ DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+ DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+ DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+ /* skipping wep.reserved */
+ DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+ DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(wep, packets);
+ DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+ DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+ DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+ DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+ /* skipping cont_miss_bcns_spread for now */
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+ DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+ DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+ DEBUGFS_FWSTATS_ADD(event, heart_beat);
+ DEBUGFS_FWSTATS_ADD(event, calibration);
+ DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+ DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+ DEBUGFS_FWSTATS_ADD(event, rx_pool);
+ DEBUGFS_FWSTATS_ADD(event, oom_late);
+ DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+ DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+ DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+ DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+ DEBUGFS_ADD(tx_queue_len, wl->rootdir);
+ DEBUGFS_ADD(retry_count, wl->rootdir);
+ DEBUGFS_ADD(excessive_retries, wl->rootdir);
+
+ DEBUGFS_ADD(gpio_power, wl->rootdir);
+
+ entry = debugfs_create_x32("debug_level", 0600, wl->rootdir,
+ &wl12xx_debug_level);
+ if (!entry || IS_ERR(entry))
+ goto err;
+
+ return 0;
+
+err:
+ if (IS_ERR(entry))
+ ret = PTR_ERR(entry);
+ else
+ ret = -ENOMEM;
+
+ return ret;
+}
+
+void wl1271_debugfs_reset(struct wl1271 *wl)
+{
+ if (!wl->rootdir)
+ return;
+
+ memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+ wl->stats.retry_count = 0;
+ wl->stats.excessive_retries = 0;
+}
+
+int wl1271_debugfs_init(struct wl1271 *wl)
+{
+ int ret;
+
+ wl->rootdir = debugfs_create_dir(KBUILD_MODNAME,
+ wl->hw->wiphy->debugfsdir);
+
+ if (IS_ERR(wl->rootdir)) {
+ ret = PTR_ERR(wl->rootdir);
+ wl->rootdir = NULL;
+ goto err;
+ }
+
+ wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+ GFP_KERNEL);
+
+ if (!wl->stats.fw_stats) {
+ ret = -ENOMEM;
+ goto err_fw;
+ }
+
+ wl->stats.fw_stats_update = jiffies;
+
+ ret = wl1271_debugfs_add_files(wl);
+
+ if (ret < 0)
+ goto err_file;
+
+ return 0;
+
+err_file:
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+err_fw:
+ debugfs_remove_recursive(wl->rootdir);
+ wl->rootdir = NULL;
+
+err:
+ return ret;
+}
+
+void wl1271_debugfs_exit(struct wl1271 *wl)
+{
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+ debugfs_remove_recursive(wl->rootdir);
+ wl->rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
index 00a45b2669ad..254c5b292cf6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.h
+++ b/drivers/net/wireless/wl12xx/debugfs.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef WL1271_DEBUGFS_H
-#define WL1271_DEBUGFS_H
+#ifndef __DEBUGFS_H__
+#define __DEBUGFS_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_debugfs_init(struct wl1271 *wl);
void wl1271_debugfs_exit(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/event.c
index 7b3f50382963..f9146f5242fb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -21,12 +21,12 @@
*
*/
-#include "wl1271.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
-#include "wl1271_ps.h"
-#include "wl1271_scan.h"
+#include "wl12xx.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "ps.h"
+#include "scan.h"
#include "wl12xx_80211.h"
void wl1271_pspoll_work(struct work_struct *work)
@@ -134,8 +134,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* go to extremely low power mode */
wl1271_ps_elp_sleep(wl);
- if (ret < 0)
- break;
break;
case EVENT_EXIT_POWER_SAVE_FAIL:
wl1271_debug(DEBUG_PSM, "PSM exit failed");
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/event.h
index e4751667cf5e..6cce0143adb5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_EVENT_H__
-#define __WL1271_EVENT_H__
+#ifndef __EVENT_H__
+#define __EVENT_H__
/*
* Mbox events
diff --git a/drivers/net/wireless/wl12xx/wl1271_ini.h b/drivers/net/wireless/wl12xx/ini.h
index 2313047d4015..c330a2583dfd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ini.h
+++ b/drivers/net/wireless/wl12xx/ini.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_INI_H__
-#define __WL1271_INI_H__
+#ifndef __INI_H__
+#define __INI_H__
#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/init.c
index 8044bba70ee7..785a5304bfc4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -25,11 +25,11 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include "wl1271_init.h"
+#include "init.h"
#include "wl12xx_80211.h"
-#include "wl1271_acx.h"
-#include "wl1271_cmd.h"
-#include "wl1271_reg.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
static int wl1271_init_hwenc_config(struct wl1271 *wl)
{
@@ -53,18 +53,16 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
int wl1271_init_templates_config(struct wl1271 *wl)
{
int ret, i;
- size_t size;
/* send empty templates for fw memory reservation */
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
- sizeof(struct wl12xx_probe_req_template),
+ WL1271_CMD_TEMPL_MAX_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;
- size = sizeof(struct wl12xx_probe_req_template);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
- NULL, size, 0,
+ NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;
@@ -102,6 +100,13 @@ int wl1271_init_templates_config(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
+ sizeof
+ (struct wl12xx_arp_rsp_template),
+ 0, WL1271_RATE_AUTOMATIC);
+ if (ret < 0)
+ return ret;
+
for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
WL1271_CMD_TEMPL_MAX_SIZE, i,
@@ -290,7 +295,7 @@ int wl1271_hw_init(struct wl1271 *wl)
goto out_free_memmap;
/* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl);
+ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
if (ret < 0)
goto out_free_memmap;
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/init.h
index bc26f8c53b91..7762421f8602 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.h
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef __WL1271_INIT_H__
-#define __WL1271_INIT_H__
+#ifndef __INIT_H__
+#define __INIT_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_hw_init_power_auth(struct wl1271 *wl);
int wl1271_init_templates_config(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/io.c
index c8759acef131..d557f73e7c19 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.c
+++ b/drivers/net/wireless/wl12xx/io.c
@@ -26,9 +26,9 @@
#include <linux/crc7.h>
#include <linux/spi/spi.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
#define OCP_CMD_LOOP 32
@@ -113,6 +113,7 @@ int wl1271_set_partition(struct wl1271 *wl,
return 0;
}
+EXPORT_SYMBOL_GPL(wl1271_set_partition);
void wl1271_io_reset(struct wl1271 *wl)
{
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/io.h
index c1f92e65ded0..844b32b170bb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/io.h
@@ -22,10 +22,10 @@
*
*/
-#ifndef __WL1271_IO_H__
-#define __WL1271_IO_H__
+#ifndef __IO_H__
+#define __IO_H__
-#include "wl1271_reg.h"
+#include "reg.h"
#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/main.c
index 48a4b9961ae6..062247ef3ad2 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -31,20 +31,20 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
-#include "wl1271_tx.h"
-#include "wl1271_rx.h"
-#include "wl1271_ps.h"
-#include "wl1271_init.h"
-#include "wl1271_debugfs.h"
-#include "wl1271_cmd.h"
-#include "wl1271_boot.h"
-#include "wl1271_testmode.h"
-#include "wl1271_scan.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+#include "cmd.h"
+#include "boot.h"
+#include "testmode.h"
+#include "scan.h"
#define WL1271_BOOT_RETRIES 3
@@ -335,6 +335,28 @@ out:
return NOTIFY_OK;
}
+static int wl1271_reg_notify(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_supported_band *band;
+ struct ieee80211_channel *ch;
+ int i;
+
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ for (i = 0; i < band->n_channels; i++) {
+ ch = &band->channels[i];
+ if (ch->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ if (ch->flags & IEEE80211_CHAN_RADAR)
+ ch->flags |= IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
+
+ }
+
+ return 0;
+}
+
static void wl1271_conf_init(struct wl1271 *wl)
{
@@ -404,7 +426,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
goto out_free_memmap;
/* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl);
+ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
if (ret < 0)
goto out_free_memmap;
@@ -481,9 +503,9 @@ static void wl1271_fw_status(struct wl1271 *wl,
total += cnt;
}
- /* if more blocks are available now, schedule some tx work */
- if (total && !skb_queue_empty(&wl->tx_queue))
- ieee80211_queue_work(wl->hw, &wl->tx_work);
+ /* if more blocks are available now, tx work can be scheduled */
+ if (total)
+ clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
/* update the host-chipset time offset */
getnstimeofday(&ts);
@@ -529,6 +551,15 @@ static void wl1271_irq_work(struct work_struct *work)
intr &= WL1271_INTR_MASK;
+ if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
+ wl1271_error("watchdog interrupt received! "
+ "starting recovery.");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+
+ /* restarting the chip. ignore any other interrupt. */
+ goto out;
+ }
+
if (intr & WL1271_ACX_INTR_DATA) {
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
@@ -537,6 +568,16 @@ static void wl1271_irq_work(struct work_struct *work)
(wl->tx_results_count & 0xff))
wl1271_tx_complete(wl);
+ /* Check if any tx blocks were freed */
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
+ wl->tx_queue_count) {
+ /*
+ * In order to avoid starvation of the TX path,
+ * call the work function directly.
+ */
+ wl1271_tx_work_locked(wl);
+ }
+
wl1271_rx(wl, wl->fw_status);
}
@@ -850,30 +891,54 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = txinfo->control.sta;
unsigned long flags;
+ int q;
- /* peek into the rates configured in the STA entry */
+ /*
+ * peek into the rates configured in the STA entry.
+ * The rates set after connection stage, The first block only BG sets:
+ * the compare is for bit 0-16 of sta_rate_set. The second block add
+ * HT rates in case of HT supported.
+ */
spin_lock_irqsave(&wl->wl_lock, flags);
- if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
+ if (sta &&
+ (sta->supp_rates[conf->channel->band] !=
+ (wl->sta_rate_set & HW_BG_RATES_MASK))) {
wl->sta_rate_set = sta->supp_rates[conf->channel->band];
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
}
+
+#ifdef CONFIG_WL12XX_HT
+ if (sta &&
+ sta->ht_cap.ht_supported &&
+ ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
+ sta->ht_cap.mcs.rx_mask[0])) {
+ /* Clean MCS bits before setting them */
+ wl->sta_rate_set &= HW_BG_RATES_MASK;
+ wl->sta_rate_set |=
+ (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
+ set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
+ }
+#endif
+ wl->tx_queue_count++;
spin_unlock_irqrestore(&wl->wl_lock, flags);
/* queue the packet */
- skb_queue_tail(&wl->tx_queue, skb);
+ q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
+ skb_queue_tail(&wl->tx_queue[q], skb);
/*
* The chip specific setup must run before the first TX packet -
* before that, the tx_work will not be initialized!
*/
- ieee80211_queue_work(wl->hw, &wl->tx_work);
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
/*
* The workqueue is slow to process the tx_queue and we need stop
* the queue here, otherwise the queue will get too long.
*/
- if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
+ if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
spin_lock_irqsave(&wl->wl_lock, flags);
@@ -919,18 +984,19 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
struct wiphy *wiphy = hw->wiphy;
int retries = WL1271_BOOT_RETRIES;
int ret = 0;
+ bool booted = false;
wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
vif->type, vif->addr);
mutex_lock(&wl->mutex);
if (wl->vif) {
+ wl1271_debug(DEBUG_MAC80211,
+ "multiple vifs are not supported yet");
ret = -EBUSY;
goto out;
}
- wl->vif = vif;
-
switch (vif->type) {
case NL80211_IFTYPE_STATION:
wl->bss_type = BSS_TYPE_STA_BSS;
@@ -968,15 +1034,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
if (ret < 0)
goto irq_disable;
- wl->state = WL1271_STATE_ON;
- wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
-
- /* update hw/fw version info in wiphy struct */
- wiphy->hw_version = wl->chip.id;
- strncpy(wiphy->fw_version, wl->chip.fw_ver,
- sizeof(wiphy->fw_version));
-
- goto out;
+ booted = true;
+ break;
irq_disable:
wl1271_disable_interrupts(wl);
@@ -994,8 +1053,31 @@ power_off:
wl1271_power_off(wl);
}
- wl1271_error("firmware boot failed despite %d retries",
- WL1271_BOOT_RETRIES);
+ if (!booted) {
+ wl1271_error("firmware boot failed despite %d retries",
+ WL1271_BOOT_RETRIES);
+ goto out;
+ }
+
+ wl->vif = vif;
+ wl->state = WL1271_STATE_ON;
+ wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+
+ /* update hw/fw version info in wiphy struct */
+ wiphy->hw_version = wl->chip.id;
+ strncpy(wiphy->fw_version, wl->chip.fw_ver,
+ sizeof(wiphy->fw_version));
+
+ /*
+ * Now we know if 11a is supported (info from the NVS), so disable
+ * 11a channels if not supported
+ */
+ if (!wl->enable_11a)
+ wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels = 0;
+
+ wl1271_debug(DEBUG_MAC80211, "11a is %ssupported",
+ wl->enable_11a ? "" : "not ");
+
out:
mutex_unlock(&wl->mutex);
@@ -1025,6 +1107,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
+ wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, true);
}
@@ -1088,10 +1171,16 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
struct wl1271 *wl = hw->priv;
mutex_lock(&wl->mutex);
- WARN_ON(wl->vif != vif);
- __wl1271_op_remove_interface(wl);
- mutex_unlock(&wl->mutex);
+ /*
+ * wl->vif can be null here if someone shuts down the interface
+ * just when hardware recovery has been started.
+ */
+ if (wl->vif) {
+ WARN_ON(wl->vif != vif);
+ __wl1271_op_remove_interface(wl);
+ }
+ mutex_unlock(&wl->mutex);
cancel_work_sync(&wl->recovery_work);
}
@@ -1312,8 +1401,10 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&wl->mutex);
- if (unlikely(wl->state == WL1271_STATE_OFF))
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
goto out;
+ }
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
@@ -1536,6 +1627,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out_unlock;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out_unlock;
@@ -1645,6 +1741,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&wl->mutex);
+ if (wl->state == WL1271_STATE_OFF) {
+ /*
+ * We cannot return -EBUSY here because cfg80211 will expect
+ * a call to ieee80211_scan_completed if we do - in this case
+ * there won't be any call.
+ */
+ ret = -EAGAIN;
+ goto out;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -1659,6 +1765,34 @@ out:
return ret;
}
+static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct wl1271 *wl = hw->priv;
+ int ret = 0;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ ret = wl1271_acx_frag_threshold(wl, (u16)value);
+ if (ret < 0)
+ wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
struct wl1271 *wl = hw->priv;
@@ -1666,8 +1800,10 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
mutex_lock(&wl->mutex);
- if (unlikely(wl->state == WL1271_STATE_OFF))
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
goto out;
+ }
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
@@ -1685,21 +1821,21 @@ out:
return ret;
}
-static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon)
+static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
+ int offset)
{
- u8 *ptr = beacon->data +
- offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ u8 *ptr = skb->data + offset;
/* find the location of the ssid in the beacon */
- while (ptr < beacon->data + beacon->len) {
+ while (ptr < skb->data + skb->len) {
if (ptr[0] == WLAN_EID_SSID) {
wl->ssid_len = ptr[1];
memcpy(wl->ssid, ptr+2, wl->ssid_len);
return;
}
- ptr += ptr[1];
+ ptr += (ptr[1] + 2);
}
- wl1271_error("ad-hoc beacon template has no SSID!\n");
+ wl1271_error("No SSID in IEs!\n");
}
static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -1709,6 +1845,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
{
enum wl1271_cmd_ps_mode mode;
struct wl1271 *wl = hw->priv;
+ struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid);
bool do_join = false;
bool set_assoc = false;
int ret;
@@ -1717,6 +1854,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -1738,8 +1878,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (beacon) {
struct ieee80211_hdr *hdr;
+ int ieoffset = offsetof(struct ieee80211_mgmt,
+ u.beacon.variable);
+
+ wl1271_ssid_set(wl, beacon, ieoffset);
- wl1271_ssid_set(wl, beacon);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
beacon->data,
beacon->len, 0,
@@ -1819,6 +1962,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
if (bss_conf->assoc) {
u32 rates;
+ int ieoffset;
wl->aid = bss_conf->aid;
set_assoc = true;
@@ -1847,13 +1991,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
goto out_sleep;
/*
- * The SSID is intentionally set to NULL here - the
- * firmware will set the probe request with a
- * broadcast SSID regardless of what we set in the
- * template.
+ * Get a template for hardware connection maintenance
*/
- ret = wl1271_cmd_build_probe_req(wl, NULL, 0,
- NULL, 0, wl->band);
+ dev_kfree_skb(wl->probereq);
+ wl->probereq = wl1271_cmd_build_ap_probe_req(wl, NULL);
+ ieoffset = offsetof(struct ieee80211_mgmt,
+ u.probe_req.variable);
+ wl1271_ssid_set(wl, wl->probereq, ieoffset);
/* enable the connection monitoring feature */
ret = wl1271_acx_conn_monit_params(wl, true);
@@ -1876,6 +2020,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
wl->aid = 0;
+ /* free probe-request template */
+ dev_kfree_skb(wl->probereq);
+ wl->probereq = NULL;
+
/* re-enable dynamic ps - just in case */
ieee80211_enable_dyn_ps(wl->vif);
@@ -1891,9 +2039,12 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
/* Disable the keep-alive feature */
ret = wl1271_acx_keep_alive_mode(wl, false);
-
if (ret < 0)
goto out_sleep;
+
+ /* restore the bssid filter and go to dummy bssid */
+ wl1271_unjoin(wl);
+ wl1271_dummy_join(wl);
}
}
@@ -1927,14 +2078,61 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
+ /*
+ * Takes care of: New association with HT enable,
+ * HT information change in beacon.
+ */
+ if (sta &&
+ (changed & BSS_CHANGED_HT) &&
+ (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap true failed %d", ret);
+ goto out_sleep;
+ }
+ ret = wl1271_acx_set_ht_information(wl,
+ bss_conf->ht_operation_mode);
+ if (ret < 0) {
+ wl1271_warning("Set ht information failed %d", ret);
+ goto out_sleep;
+ }
+ }
+ /*
+ * Takes care of: New association without HT,
+ * Disassociation.
+ */
+ else if (sta && (changed & BSS_CHANGED_ASSOC)) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap false failed %d", ret);
+ goto out_sleep;
+ }
+ }
+
if (changed & BSS_CHANGED_ARP_FILTER) {
__be32 addr = bss_conf->arp_addr_list[0];
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
- if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled)
- ret = wl1271_acx_arp_ip_filter(wl, true, addr);
- else
- ret = wl1271_acx_arp_ip_filter(wl, false, addr);
+ if (bss_conf->arp_addr_cnt == 1 &&
+ bss_conf->arp_filter_enabled) {
+ /*
+ * The template should have been configured only upon
+ * association. however, it seems that the correct ip
+ * isn't being set (when sending), so we have to
+ * reconfigure the template upon every ip change.
+ */
+ ret = wl1271_cmd_build_arp_rsp(wl, addr);
+ if (ret < 0) {
+ wl1271_warning("build arp rsp failed: %d", ret);
+ goto out_sleep;
+ }
+
+ ret = wl1271_acx_arp_ip_filter(wl,
+ (ACX_ARP_FILTER_ARP_FILTERING |
+ ACX_ARP_FILTER_AUTO_ARP),
+ addr);
+ } else
+ ret = wl1271_acx_arp_ip_filter(wl, 0, addr);
if (ret < 0)
goto out_sleep;
@@ -1966,6 +2164,11 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -2009,6 +2212,9 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -2030,14 +2236,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
{
struct wl1271 *wl = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
-
+
if (idx != 0)
return -ENOENT;
-
+
survey->channel = conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = wl->noise;
-
+
return 0;
}
@@ -2084,37 +2290,34 @@ static struct ieee80211_rate wl1271_rates[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/*
- * Can't be const, mac80211 writes to this. The order of the channels here
- * is designed to improve scanning.
- */
+/* can't be const, mac80211 writes to this */
static struct ieee80211_channel wl1271_channels[] = {
{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
- { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
- { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
- { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
- { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
- { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
- { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
- { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
- { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
- { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
{ .hw_value = 2, .center_freq = 2417, .max_power = 25 },
+ { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
+ { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
+ { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
{ .hw_value = 6, .center_freq = 2437, .max_power = 25 },
+ { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
+ { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
+ { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
{ .hw_value = 10, .center_freq = 2457, .max_power = 25 },
+ { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
+ { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
+ { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
};
/* mapping to indexes for wl1271_rates */
static const u8 wl1271_rate_to_idx_2ghz[] = {
/* MCS rates are used only with 11n */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+ 7, /* CONF_HW_RXTX_RATE_MCS7 */
+ 6, /* CONF_HW_RXTX_RATE_MCS6 */
+ 5, /* CONF_HW_RXTX_RATE_MCS5 */
+ 4, /* CONF_HW_RXTX_RATE_MCS4 */
+ 3, /* CONF_HW_RXTX_RATE_MCS3 */
+ 2, /* CONF_HW_RXTX_RATE_MCS2 */
+ 1, /* CONF_HW_RXTX_RATE_MCS1 */
+ 0, /* CONF_HW_RXTX_RATE_MCS0 */
11, /* CONF_HW_RXTX_RATE_54 */
10, /* CONF_HW_RXTX_RATE_48 */
@@ -2134,12 +2337,34 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
0 /* CONF_HW_RXTX_RATE_1 */
};
+/* 11n STA capabilities */
+#define HW_RX_HIGHEST_RATE 72
+
+#ifdef CONFIG_WL12XX_HT
+#define WL12XX_HT_CAP { \
+ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
+ .ht_supported = true, \
+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
+ .mcs = { \
+ .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
+ .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
+ }, \
+}
+#else
+#define WL12XX_HT_CAP { \
+ .ht_supported = false, \
+}
+#endif
+
/* can't be const, mac80211 writes to this */
static struct ieee80211_supported_band wl1271_band_2ghz = {
.channels = wl1271_channels,
.n_channels = ARRAY_SIZE(wl1271_channels),
.bitrates = wl1271_rates,
.n_bitrates = ARRAY_SIZE(wl1271_rates),
+ .ht_cap = WL12XX_HT_CAP,
};
/* 5 GHz data rates for WL1273 */
@@ -2170,66 +2395,55 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/*
- * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this.
- * The order of the channels here is designed to improve scanning.
- */
+/* 5 GHz band channels for WL1273 */
static struct ieee80211_channel wl1271_channels_5ghz[] = {
- { .hw_value = 183, .center_freq = 4915},
- { .hw_value = 188, .center_freq = 4940},
+ { .hw_value = 7, .center_freq = 5035},
{ .hw_value = 8, .center_freq = 5040},
- { .hw_value = 34, .center_freq = 5170},
- { .hw_value = 44, .center_freq = 5220},
- { .hw_value = 60, .center_freq = 5300},
- { .hw_value = 112, .center_freq = 5560},
- { .hw_value = 132, .center_freq = 5660},
- { .hw_value = 157, .center_freq = 5785},
- { .hw_value = 184, .center_freq = 4920},
- { .hw_value = 189, .center_freq = 4945},
{ .hw_value = 9, .center_freq = 5045},
- { .hw_value = 36, .center_freq = 5180},
- { .hw_value = 46, .center_freq = 5230},
- { .hw_value = 64, .center_freq = 5320},
- { .hw_value = 116, .center_freq = 5580},
- { .hw_value = 136, .center_freq = 5680},
- { .hw_value = 192, .center_freq = 4960},
{ .hw_value = 11, .center_freq = 5055},
- { .hw_value = 38, .center_freq = 5190},
- { .hw_value = 48, .center_freq = 5240},
- { .hw_value = 100, .center_freq = 5500},
- { .hw_value = 120, .center_freq = 5600},
- { .hw_value = 140, .center_freq = 5700},
- { .hw_value = 185, .center_freq = 4925},
- { .hw_value = 196, .center_freq = 4980},
{ .hw_value = 12, .center_freq = 5060},
- { .hw_value = 40, .center_freq = 5200},
- { .hw_value = 52, .center_freq = 5260},
- { .hw_value = 104, .center_freq = 5520},
- { .hw_value = 124, .center_freq = 5620},
- { .hw_value = 149, .center_freq = 5745},
- { .hw_value = 161, .center_freq = 5805},
- { .hw_value = 187, .center_freq = 4935},
- { .hw_value = 7, .center_freq = 5035},
{ .hw_value = 16, .center_freq = 5080},
+ { .hw_value = 34, .center_freq = 5170},
+ { .hw_value = 36, .center_freq = 5180},
+ { .hw_value = 38, .center_freq = 5190},
+ { .hw_value = 40, .center_freq = 5200},
{ .hw_value = 42, .center_freq = 5210},
+ { .hw_value = 44, .center_freq = 5220},
+ { .hw_value = 46, .center_freq = 5230},
+ { .hw_value = 48, .center_freq = 5240},
+ { .hw_value = 52, .center_freq = 5260},
{ .hw_value = 56, .center_freq = 5280},
+ { .hw_value = 60, .center_freq = 5300},
+ { .hw_value = 64, .center_freq = 5320},
+ { .hw_value = 100, .center_freq = 5500},
+ { .hw_value = 104, .center_freq = 5520},
{ .hw_value = 108, .center_freq = 5540},
+ { .hw_value = 112, .center_freq = 5560},
+ { .hw_value = 116, .center_freq = 5580},
+ { .hw_value = 120, .center_freq = 5600},
+ { .hw_value = 124, .center_freq = 5620},
{ .hw_value = 128, .center_freq = 5640},
+ { .hw_value = 132, .center_freq = 5660},
+ { .hw_value = 136, .center_freq = 5680},
+ { .hw_value = 140, .center_freq = 5700},
+ { .hw_value = 149, .center_freq = 5745},
{ .hw_value = 153, .center_freq = 5765},
+ { .hw_value = 157, .center_freq = 5785},
+ { .hw_value = 161, .center_freq = 5805},
{ .hw_value = 165, .center_freq = 5825},
};
/* mapping to indexes for wl1271_rates_5ghz */
static const u8 wl1271_rate_to_idx_5ghz[] = {
/* MCS rates are used only with 11n */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+ 7, /* CONF_HW_RXTX_RATE_MCS7 */
+ 6, /* CONF_HW_RXTX_RATE_MCS6 */
+ 5, /* CONF_HW_RXTX_RATE_MCS5 */
+ 4, /* CONF_HW_RXTX_RATE_MCS4 */
+ 3, /* CONF_HW_RXTX_RATE_MCS3 */
+ 2, /* CONF_HW_RXTX_RATE_MCS2 */
+ 1, /* CONF_HW_RXTX_RATE_MCS1 */
+ 0, /* CONF_HW_RXTX_RATE_MCS0 */
7, /* CONF_HW_RXTX_RATE_54 */
6, /* CONF_HW_RXTX_RATE_48 */
@@ -2254,6 +2468,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
.n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
.bitrates = wl1271_rates_5ghz,
.n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
+ .ht_cap = WL12XX_HT_CAP,
};
static const u8 *wl1271_band_rate_to_idx[] = {
@@ -2273,6 +2488,7 @@ static const struct ieee80211_ops wl1271_ops = {
.set_key = wl1271_op_set_key,
.hw_scan = wl1271_op_hw_scan,
.bss_info_changed = wl1271_op_bss_info_changed,
+ .set_frag_threshold = wl1271_op_set_frag_threshold,
.set_rts_threshold = wl1271_op_set_rts_threshold,
.conf_tx = wl1271_op_conf_tx,
.get_tsf = wl1271_op_get_tsf,
@@ -2281,18 +2497,18 @@ static const struct ieee80211_ops wl1271_ops = {
};
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate)
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band)
{
u8 idx;
- BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
+ BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
wl1271_error("Illegal RX rate from HW: %d", rate);
return 0;
}
- idx = wl1271_band_rate_to_idx[wl->band][rate];
+ idx = wl1271_band_rate_to_idx[band][rate];
if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
wl1271_error("Unsupported RX rate from HW: %d", rate);
return 0;
@@ -2401,6 +2617,8 @@ int wl1271_register_hw(struct wl1271 *wl)
wl->mac80211_registered = true;
+ wl1271_debugfs_init(wl);
+
register_netdevice_notifier(&wl1271_dev_notifier);
wl1271_notice("loaded");
@@ -2451,12 +2669,21 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
wl->hw->wiphy->max_scan_ssids = 1;
+ /*
+ * Maximum length of elements in scanning probe request templates
+ * should be the maximum length possible for a template, without
+ * the IEEE80211 header of the template
+ */
+ wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
+ sizeof(struct ieee80211_header);
wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
wl->hw->queues = 4;
wl->hw->max_rates = 1;
+ wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
+
SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
return 0;
@@ -2495,7 +2722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->hw = hw;
wl->plat_dev = plat_dev;
- skb_queue_head_init(&wl->tx_queue);
+ for (i = 0; i < NUM_TX_QUEUES; i++)
+ skb_queue_head_init(&wl->tx_queue[i]);
INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
@@ -2521,6 +2749,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->sg_enabled = true;
wl->hw_pg_ver = -1;
+ memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
wl->tx_frames[i] = NULL;
@@ -2532,8 +2761,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
/* Apply default driver configuration. */
wl1271_conf_init(wl);
- wl1271_debugfs_init(wl);
-
order = get_order(WL1271_AGGR_BUFFER_SIZE);
wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
if (!wl->aggr_buf) {
@@ -2610,6 +2837,11 @@ int wl1271_free_hw(struct wl1271 *wl)
}
EXPORT_SYMBOL_GPL(wl1271_free_hw);
+u32 wl12xx_debug_level;
+EXPORT_SYMBOL_GPL(wl12xx_debug_level);
+module_param_named(debug_level, wl12xx_debug_level, uint, DEBUG_NONE);
+MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/ps.c
index e3c332e2f97c..60a3738eadb0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -21,9 +21,9 @@
*
*/
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
-#include "wl1271_io.h"
+#include "reg.h"
+#include "ps.h"
+#include "io.h"
#define WL1271_WAKEUP_TIMEOUT 500
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/ps.h
index 6ba7b032736f..8415060f08e5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -21,11 +21,11 @@
*
*/
-#ifndef __WL1271_PS_H__
-#define __WL1271_PS_H__
+#ifndef __PS_H__
+#define __PS_H__
-#include "wl1271.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "acx.h"
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
u32 rates, bool send);
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/reg.h
index 990960771528..990960771528 100644
--- a/drivers/net/wireless/wl12xx/wl1271_reg.h
+++ b/drivers/net/wireless/wl12xx/reg.h
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/rx.c
index bea133b6e489..682304c30b81 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -23,11 +23,11 @@
#include <linux/gfp.h>
-#include "wl1271.h"
-#include "wl1271_acx.h"
-#include "wl1271_reg.h"
-#include "wl1271_rx.h"
-#include "wl1271_io.h"
+#include "wl12xx.h"
+#include "acx.h"
+#include "reg.h"
+#include "rx.h"
+#include "io.h"
static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
u32 drv_rx_counter)
@@ -48,10 +48,24 @@ static void wl1271_rx_status(struct wl1271 *wl,
struct ieee80211_rx_status *status,
u8 beacon)
{
+ enum ieee80211_band desc_band;
+
memset(status, 0, sizeof(struct ieee80211_rx_status));
status->band = wl->band;
- status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
+
+ if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
+ desc_band = IEEE80211_BAND_2GHZ;
+ else
+ desc_band = IEEE80211_BAND_5GHZ;
+
+ status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
+
+#ifdef CONFIG_WL12XX_HT
+ /* 11n support */
+ if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
+ status->flag |= RX_FLAG_HT;
+#endif
status->signal = desc->rssi;
@@ -170,10 +184,14 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
while (pkt_offset < buf_size) {
pkt_length = wl1271_rx_get_buf_size(status,
drv_rx_counter);
- if (wl1271_rx_handle_data(wl,
- wl->aggr_buf + pkt_offset,
- pkt_length) < 0)
- break;
+ /*
+ * the handle data call can only fail in memory-outage
+ * conditions, in that case the received frame will just
+ * be dropped.
+ */
+ wl1271_rx_handle_data(wl,
+ wl->aggr_buf + pkt_offset,
+ pkt_length);
wl->rx_counter++;
drv_rx_counter++;
drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/rx.h
index 13a232333b13..3abb26fe0364 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_RX_H__
-#define __WL1271_RX_H__
+#ifndef __RX_H__
+#define __RX_H__
#include <linux/bitops.h>
@@ -116,6 +116,6 @@ struct wl1271_rx_descriptor {
} __packed;
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/scan.c
index 909bb47995b6..6f897b9d90ca 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -23,10 +23,10 @@
#include <linux/ieee80211.h>
-#include "wl1271.h"
-#include "wl1271_cmd.h"
-#include "wl1271_scan.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "cmd.h"
+#include "scan.h"
+#include "acx.h"
void wl1271_scan_complete_work(struct work_struct *work)
{
@@ -48,14 +48,19 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
- mutex_unlock(&wl->mutex);
-
+ wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, false);
+ /* restore hardware connection monitoring template */
+ if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+ wl1271_cmd_build_ap_probe_req(wl, wl->probereq);
+
if (wl->scan.failed) {
wl1271_info("Scan completed due to error.");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
}
+ mutex_unlock(&wl->mutex);
+
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/scan.h
index 6d57127b5e6b..421a750add5a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef __WL1271_SCAN_H__
-#define __WL1271_SCAN_H__
+#ifndef __SCAN_H__
+#define __SCAN_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
struct cfg80211_scan_request *req);
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index 784ef3432641..93cbb8d5aba9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -32,9 +32,9 @@
#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c
new file mode 100644
index 000000000000..9fcbd3dd8490
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/sdio_test.c
@@ -0,0 +1,520 @@
+/*
+ * SDIO testing driver for wl12xx
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Roger Quadros <roger.quadros@nokia.com>
+ *
+ * wl12xx read/write routines taken from the main module
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/vmalloc.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/card.h>
+#include <linux/gpio.h>
+#include <linux/wl12xx.h>
+#include <linux/kthread.h>
+#include <linux/firmware.h>
+#include <linux/pm_runtime.h>
+
+#include "wl12xx.h"
+#include "io.h"
+#include "boot.h"
+
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI 0x0097
+#endif
+
+#ifndef SDIO_DEVICE_ID_TI_WL1271
+#define SDIO_DEVICE_ID_TI_WL1271 0x4076
+#endif
+
+static bool rx, tx;
+
+module_param(rx, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(rx, "Perform rx test. Default (0). "
+ "This test continuously reads data from the SDIO device.\n");
+
+module_param(tx, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tx, "Perform tx test. Default (0). "
+ "This test continuously writes data to the SDIO device.\n");
+
+struct wl1271_test {
+ struct wl1271 wl;
+ struct task_struct *test_task;
+};
+
+static const struct sdio_device_id wl1271_devices[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
+ {}
+};
+
+static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
+{
+ return wl->if_priv;
+}
+
+static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
+{
+ return &(wl_to_func(wl)->dev);
+}
+
+static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
+ size_t len, bool fixed)
+{
+ int ret = 0;
+ struct sdio_func *func = wl_to_func(wl);
+
+ if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
+ ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
+ wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
+ addr, ((u8 *)buf)[0]);
+ } else {
+ if (fixed)
+ ret = sdio_readsb(func, buf, addr, len);
+ else
+ ret = sdio_memcpy_fromio(func, buf, addr, len);
+
+ wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
+ addr, len);
+ wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
+ }
+
+ if (ret)
+ wl1271_error("sdio read failed (%d)", ret);
+}
+
+static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
+ size_t len, bool fixed)
+{
+ int ret = 0;
+ struct sdio_func *func = wl_to_func(wl);
+
+ if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
+ sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
+ wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
+ addr, ((u8 *)buf)[0]);
+ } else {
+ wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
+ addr, len);
+ wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
+
+ if (fixed)
+ ret = sdio_writesb(func, addr, buf, len);
+ else
+ ret = sdio_memcpy_toio(func, addr, buf, len);
+ }
+ if (ret)
+ wl1271_error("sdio write failed (%d)", ret);
+
+}
+
+static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+{
+ struct sdio_func *func = wl_to_func(wl);
+ int ret;
+
+ /* Let the SDIO stack handle wlan_enable control, so we
+ * keep host claimed while wlan is in use to keep wl1271
+ * alive.
+ */
+ if (enable) {
+ /* Power up the card */
+ ret = pm_runtime_get_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
+ } else {
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ /* Power down the card */
+ ret = pm_runtime_put_sync(&func->dev);
+ }
+
+out:
+ return ret;
+}
+
+static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
+{
+}
+
+static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
+{
+}
+
+
+static struct wl1271_if_operations sdio_ops = {
+ .read = wl1271_sdio_raw_read,
+ .write = wl1271_sdio_raw_write,
+ .power = wl1271_sdio_set_power,
+ .dev = wl1271_sdio_wl_to_dev,
+ .enable_irq = wl1271_sdio_enable_interrupts,
+ .disable_irq = wl1271_sdio_disable_interrupts,
+};
+
+static void wl1271_fw_wakeup(struct wl1271 *wl)
+{
+ u32 elp_reg;
+
+ elp_reg = ELPCTRL_WAKE_UP;
+ wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+}
+
+static int wl1271_fetch_firmware(struct wl1271 *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
+
+ if (ret < 0) {
+ wl1271_error("could not get firmware: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ wl1271_error("firmware size is not multiple of 32 bits: %zu",
+ fw->size);
+ ret = -EILSEQ;
+ goto out;
+ }
+
+ wl->fw_len = fw->size;
+ wl->fw = vmalloc(wl->fw_len);
+
+ if (!wl->fw) {
+ wl1271_error("could not allocate memory for the firmware");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(wl->fw, fw->data, wl->fw_len);
+
+ ret = 0;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int wl1271_fetch_nvs(struct wl1271 *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
+
+ if (ret < 0) {
+ wl1271_error("could not get nvs file: %d", ret);
+ return ret;
+ }
+
+ wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+
+ if (!wl->nvs) {
+ wl1271_error("could not allocate memory for the nvs file");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ wl->nvs_len = fw->size;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int wl1271_chip_wakeup(struct wl1271 *wl)
+{
+ struct wl1271_partition_set partition;
+ int ret;
+
+ msleep(WL1271_PRE_POWER_ON_SLEEP);
+ ret = wl1271_power_on(wl);
+ if (ret)
+ return ret;
+
+ msleep(WL1271_POWER_ON_SLEEP);
+
+ /* We don't need a real memory partition here, because we only want
+ * to use the registers at this point. */
+ memset(&partition, 0, sizeof(partition));
+ partition.reg.start = REGISTERS_BASE;
+ partition.reg.size = REGISTERS_DOWN_SIZE;
+ wl1271_set_partition(wl, &partition);
+
+ /* ELP module wake up */
+ wl1271_fw_wakeup(wl);
+
+ /* whal_FwCtrl_BootSm() */
+
+ /* 0. read chip id from CHIP_ID */
+ wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
+
+ /* 1. check if chip id is valid */
+
+ switch (wl->chip.id) {
+ case CHIP_ID_1271_PG10:
+ wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
+ wl->chip.id);
+ break;
+ case CHIP_ID_1271_PG20:
+ wl1271_notice("chip id 0x%x (1271 PG20)",
+ wl->chip.id);
+ break;
+ default:
+ wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+static struct wl1271_partition_set part_down = {
+ .mem = {
+ .start = 0x00000000,
+ .size = 0x000177c0
+ },
+ .reg = {
+ .start = REGISTERS_BASE,
+ .size = 0x00008800
+ },
+ .mem2 = {
+ .start = 0x00000000,
+ .size = 0x00000000
+ },
+ .mem3 = {
+ .start = 0x00000000,
+ .size = 0x00000000
+ },
+};
+
+static int tester(void *data)
+{
+ struct wl1271 *wl = data;
+ struct sdio_func *func = wl_to_func(wl);
+ struct device *pdev = &func->dev;
+ int ret = 0;
+ bool rx_started = 0;
+ bool tx_started = 0;
+ uint8_t *tx_buf, *rx_buf;
+ int test_size = PAGE_SIZE;
+ u32 addr = 0;
+ struct wl1271_partition_set partition;
+
+ /* We assume chip is powered up and firmware fetched */
+
+ memcpy(&partition, &part_down, sizeof(partition));
+ partition.mem.start = addr;
+ wl1271_set_partition(wl, &partition);
+
+ tx_buf = kmalloc(test_size, GFP_KERNEL);
+ rx_buf = kmalloc(test_size, GFP_KERNEL);
+ if (!tx_buf || !rx_buf) {
+ dev_err(pdev,
+ "Could not allocate memory. Test will not run.\n");
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ memset(tx_buf, 0x5a, test_size);
+
+ /* write something in data area so we can read it back */
+ wl1271_write(wl, addr, tx_buf, test_size, false);
+
+ while (!kthread_should_stop()) {
+ if (rx && !rx_started) {
+ dev_info(pdev, "starting rx test\n");
+ rx_started = 1;
+ } else if (!rx && rx_started) {
+ dev_info(pdev, "stopping rx test\n");
+ rx_started = 0;
+ }
+
+ if (tx && !tx_started) {
+ dev_info(pdev, "starting tx test\n");
+ tx_started = 1;
+ } else if (!tx && tx_started) {
+ dev_info(pdev, "stopping tx test\n");
+ tx_started = 0;
+ }
+
+ if (rx_started)
+ wl1271_read(wl, addr, rx_buf, test_size, false);
+
+ if (tx_started)
+ wl1271_write(wl, addr, tx_buf, test_size, false);
+
+ if (!rx_started && !tx_started)
+ msleep(100);
+ }
+
+free:
+ kfree(tx_buf);
+ kfree(rx_buf);
+ return ret;
+}
+
+static int __devinit wl1271_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ const struct wl12xx_platform_data *wlan_data;
+ struct wl1271 *wl;
+ struct wl1271_test *wl_test;
+ int ret = 0;
+
+ /* wl1271 has 2 sdio functions we handle just the wlan part */
+ if (func->num != 0x02)
+ return -ENODEV;
+
+ wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL);
+ if (!wl_test) {
+ dev_err(&func->dev, "Could not allocate memory\n");
+ return -ENOMEM;
+ }
+
+ wl = &wl_test->wl;
+
+ wl->if_priv = func;
+ wl->if_ops = &sdio_ops;
+
+ /* Grab access to FN0 for ELP reg. */
+ func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
+ wlan_data = wl12xx_get_platform_data();
+ if (IS_ERR(wlan_data)) {
+ ret = PTR_ERR(wlan_data);
+ dev_err(&func->dev, "missing wlan platform data: %d\n", ret);
+ goto out_free;
+ }
+
+ wl->irq = wlan_data->irq;
+ wl->ref_clock = wlan_data->board_ref_clock;
+
+ sdio_set_drvdata(func, wl_test);
+
+
+ /* power up the device */
+ ret = wl1271_chip_wakeup(wl);
+ if (ret) {
+ dev_err(&func->dev, "could not wake up chip\n");
+ goto out_free;
+ }
+
+ if (wl->fw == NULL) {
+ ret = wl1271_fetch_firmware(wl);
+ if (ret < 0) {
+ dev_err(&func->dev, "firmware fetch error\n");
+ goto out_off;
+ }
+ }
+
+ /* fetch NVS */
+ if (wl->nvs == NULL) {
+ ret = wl1271_fetch_nvs(wl);
+ if (ret < 0) {
+ dev_err(&func->dev, "NVS fetch error\n");
+ goto out_off;
+ }
+ }
+
+ ret = wl1271_load_firmware(wl);
+ if (ret < 0) {
+ dev_err(&func->dev, "firmware load error: %d\n", ret);
+ goto out_free;
+ }
+
+ dev_info(&func->dev, "initialized\n");
+
+ /* I/O testing will be done in the tester thread */
+
+ wl_test->test_task = kthread_run(tester, wl, "sdio_tester");
+ if (IS_ERR(wl_test->test_task)) {
+ dev_err(&func->dev, "unable to create kernel thread\n");
+ ret = PTR_ERR(wl_test->test_task);
+ goto out_free;
+ }
+
+ return 0;
+
+out_off:
+ /* power off the chip */
+ wl1271_power_off(wl);
+
+out_free:
+ kfree(wl_test);
+ return ret;
+}
+
+static void __devexit wl1271_remove(struct sdio_func *func)
+{
+ struct wl1271_test *wl_test = sdio_get_drvdata(func);
+
+ /* stop the I/O test thread */
+ kthread_stop(wl_test->test_task);
+
+ /* power off the chip */
+ wl1271_power_off(&wl_test->wl);
+
+ vfree(wl_test->wl.fw);
+ wl_test->wl.fw = NULL;
+ kfree(wl_test->wl.nvs);
+ wl_test->wl.nvs = NULL;
+
+ kfree(wl_test);
+}
+
+static struct sdio_driver wl1271_sdio_driver = {
+ .name = "wl12xx_sdio_test",
+ .id_table = wl1271_devices,
+ .probe = wl1271_probe,
+ .remove = __devexit_p(wl1271_remove),
+};
+
+static int __init wl1271_init(void)
+{
+ int ret;
+
+ ret = sdio_register_driver(&wl1271_sdio_driver);
+ if (ret < 0)
+ pr_err("failed to register sdio driver: %d\n", ret);
+
+ return ret;
+}
+module_init(wl1271_init);
+
+static void __exit wl1271_exit(void)
+{
+ sdio_unregister_driver(&wl1271_sdio_driver);
+}
+module_exit(wl1271_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Roger Quadros <roger.quadros@nokia.com>");
+
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/spi.c
index ef801680773f..46714910f98c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -28,11 +28,11 @@
#include <linux/wl12xx.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
-#include "wl1271_reg.h"
+#include "reg.h"
#define WSPI_CMD_READ 0x40000000
#define WSPI_CMD_WRITE 0x00000000
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index a3aa84386c88..e64403b6896d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -20,13 +20,13 @@
* 02110-1301 USA
*
*/
-#include "wl1271_testmode.h"
+#include "testmode.h"
#include <linux/slab.h>
#include <net/genetlink.h>
-#include "wl1271.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "acx.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
@@ -37,6 +37,7 @@ enum wl1271_tm_commands {
WL1271_TM_CMD_CONFIGURE,
WL1271_TM_CMD_NVS_PUSH,
WL1271_TM_CMD_SET_PLT_MODE,
+ WL1271_TM_CMD_RECOVER,
__WL1271_TM_CMD_AFTER_LAST
};
@@ -248,6 +249,15 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
return ret;
}
+static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
+{
+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover");
+
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+
+ return 0;
+}
+
int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
{
struct wl1271 *wl = hw->priv;
@@ -272,6 +282,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
return wl1271_tm_cmd_nvs_push(wl, tb);
case WL1271_TM_CMD_SET_PLT_MODE:
return wl1271_tm_cmd_set_plt_mode(wl, tb);
+ case WL1271_TM_CMD_RECOVER:
+ return wl1271_tm_cmd_recover(wl, tb);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.h b/drivers/net/wireless/wl12xx/testmode.h
index c196d28f9d9d..8071654259ea 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.h
+++ b/drivers/net/wireless/wl12xx/testmode.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_TESTMODE_H__
-#define __WL1271_TESTMODE_H__
+#ifndef __TESTMODE_H__
+#define __TESTMODE_H__
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/tx.c
index e3dc13c4d01a..b44c75cd8c1e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -24,23 +24,32 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include "wl1271.h"
-#include "wl1271_io.h"
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
-#include "wl1271_tx.h"
+#include "wl12xx.h"
+#include "io.h"
+#include "reg.h"
+#include "ps.h"
+#include "tx.h"
-static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
+static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
{
- int i;
- for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
- if (wl->tx_frames[i] == NULL) {
- wl->tx_frames[i] = skb;
- wl->tx_frames_cnt++;
- return i;
- }
+ int id;
+
+ id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS);
+ if (id >= ACX_TX_DESCRIPTORS)
+ return -EBUSY;
- return -EBUSY;
+ __set_bit(id, wl->tx_frames_map);
+ wl->tx_frames[id] = skb;
+ wl->tx_frames_cnt++;
+ return id;
+}
+
+static void wl1271_free_tx_id(struct wl1271 *wl, int id)
+{
+ if (__test_and_clear_bit(id, wl->tx_frames_map)) {
+ wl->tx_frames[id] = NULL;
+ wl->tx_frames_cnt--;
+ }
}
static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
@@ -52,10 +61,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
int id, ret = -EBUSY;
if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
- return -EBUSY;
+ return -EAGAIN;
/* allocate free identifier for the packet */
- id = wl1271_tx_id(wl, skb);
+ id = wl1271_alloc_tx_id(wl, skb);
if (id < 0)
return id;
@@ -79,8 +88,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
"tx_allocate: size: %d, blocks: %d, id: %d",
total_len, total_blocks, id);
} else {
- wl->tx_frames[id] = NULL;
- wl->tx_frames_cnt--;
+ wl1271_free_tx_id(wl, id);
}
return ret;
@@ -117,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
/* queue (we use same identifiers for tid's and ac's */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
desc->tid = ac;
-
desc->aid = TX_HW_DEFAULT_AID;
desc->reserved = 0;
@@ -201,42 +208,105 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
rate_set >>= 1;
}
+#ifdef CONFIG_WL12XX_HT
+ /* MCS rates indication are on bits 16 - 23 */
+ rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
+
+ for (bit = 0; bit < 8; bit++) {
+ if (rate_set & 0x1)
+ enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
+ rate_set >>= 1;
+ }
+#endif
+
return enabled_rates;
}
-void wl1271_tx_work(struct work_struct *work)
+static void handle_tx_low_watermark(struct wl1271 *wl)
+{
+ unsigned long flags;
+
+ if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
+ wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) {
+ /* firmware buffer has space, restart queues */
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_wake_queues(wl->hw);
+ clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+}
+
+static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
+{
+ struct sk_buff *skb = NULL;
+ unsigned long flags;
+
+ skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]);
+ if (skb)
+ goto out;
+ skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]);
+ if (skb)
+ goto out;
+ skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]);
+ if (skb)
+ goto out;
+ skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]);
+
+out:
+ if (skb) {
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ wl->tx_queue_count--;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+
+ return skb;
+}
+
+static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
+{
+ unsigned long flags;
+ int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
+
+ skb_queue_head(&wl->tx_queue[q], skb);
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ wl->tx_queue_count++;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+}
+
+void wl1271_tx_work_locked(struct wl1271 *wl)
{
- struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
struct sk_buff *skb;
bool woken_up = false;
u32 sta_rates = 0;
- u32 buf_offset;
+ u32 buf_offset = 0;
+ bool sent_packets = false;
int ret;
/* check if the rates supported by the AP have changed */
if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
&wl->flags))) {
unsigned long flags;
+
spin_lock_irqsave(&wl->wl_lock, flags);
sta_rates = wl->sta_rate_set;
spin_unlock_irqrestore(&wl->wl_lock, flags);
}
- mutex_lock(&wl->mutex);
-
if (unlikely(wl->state == WL1271_STATE_OFF))
goto out;
/* if rates have changed, re-configure the rate policy */
if (unlikely(sta_rates)) {
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+ woken_up = true;
+
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
wl1271_acx_rate_policies(wl);
}
- /* Prepare the transfer buffer, by aggregating all
- * available packets */
- buf_offset = 0;
- while ((skb = skb_dequeue(&wl->tx_queue))) {
+ while ((skb = wl1271_skb_dequeue(wl))) {
if (!woken_up) {
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
@@ -245,13 +315,25 @@ void wl1271_tx_work(struct work_struct *work)
}
ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
- if (ret == -EBUSY) {
+ if (ret == -EAGAIN) {
+ /*
+ * Aggregation buffer is full.
+ * Flush buffer and try again.
+ */
+ wl1271_skb_queue_head(wl, skb);
+ wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_offset, true);
+ sent_packets = true;
+ buf_offset = 0;
+ continue;
+ } else if (ret == -EBUSY) {
/*
- * Either the firmware buffer is full, or the
- * aggregation buffer is.
+ * Firmware buffer is full.
* Queue back last skb, and stop aggregating.
*/
- skb_queue_head(&wl->tx_queue, skb);
+ wl1271_skb_queue_head(wl, skb);
+ /* No work left, avoid scheduling redundant tx work */
+ set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
goto out_ack;
} else if (ret < 0) {
dev_kfree_skb(skb);
@@ -265,14 +347,25 @@ out_ack:
if (buf_offset) {
wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
buf_offset, true);
+ sent_packets = true;
+ }
+ if (sent_packets) {
/* interrupt the firmware with the new packets */
wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+ handle_tx_low_watermark(wl);
}
out:
if (woken_up)
wl1271_ps_elp_sleep(wl);
+}
+void wl1271_tx_work(struct work_struct *work)
+{
+ struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
+
+ mutex_lock(&wl->mutex);
+ wl1271_tx_work_locked(wl);
mutex_unlock(&wl->mutex);
}
@@ -298,7 +391,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
if (result->status == TX_SUCCESS) {
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
info->flags |= IEEE80211_TX_STAT_ACK;
- rate = wl1271_rate_to_idx(wl, result->rate_class_index);
+ rate = wl1271_rate_to_idx(result->rate_class_index, wl->band);
retries = result->ack_failures;
} else if (result->status == TX_RETRY_EXCEEDED) {
wl->stats.excessive_retries++;
@@ -335,8 +428,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
/* return the packet to the stack */
ieee80211_tx_status(wl->hw, skb);
- wl->tx_frames[result->id] = NULL;
- wl->tx_frames_cnt--;
+ wl1271_free_tx_id(wl, result->id);
}
/* Called upon reception of a TX complete interrupt */
@@ -375,19 +467,6 @@ void wl1271_tx_complete(struct wl1271 *wl)
wl->tx_results_count++;
}
-
- if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
- skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
- unsigned long flags;
-
- /* firmware buffer has space, restart queues */
- wl1271_debug(DEBUG_TX, "tx_complete: waking queues");
- spin_lock_irqsave(&wl->wl_lock, flags);
- ieee80211_wake_queues(wl->hw);
- clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- ieee80211_queue_work(wl->hw, &wl->tx_work);
- }
}
/* caller must hold wl->mutex */
@@ -397,19 +476,27 @@ void wl1271_tx_reset(struct wl1271 *wl)
struct sk_buff *skb;
/* TX failure */
- while ((skb = skb_dequeue(&wl->tx_queue))) {
- wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
- ieee80211_tx_status(wl->hw, skb);
+ for (i = 0; i < NUM_TX_QUEUES; i++) {
+ while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
+ wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
+ ieee80211_tx_status(wl->hw, skb);
+ }
}
+ wl->tx_queue_count = 0;
+
+ /*
+ * Make sure the driver is at a consistent state, in case this
+ * function is called from a context other than interface removal.
+ */
+ handle_tx_low_watermark(wl);
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
if (wl->tx_frames[i] != NULL) {
skb = wl->tx_frames[i];
- wl->tx_frames[i] = NULL;
+ wl1271_free_tx_id(wl, i);
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
ieee80211_tx_status(wl->hw, skb);
}
- wl->tx_frames_cnt = 0;
}
#define WL1271_TX_FLUSH_TIMEOUT 500000
@@ -424,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
mutex_lock(&wl->mutex);
wl1271_debug(DEBUG_TX, "flushing tx buffer: %d",
wl->tx_frames_cnt);
- if ((wl->tx_frames_cnt == 0) &&
- skb_queue_empty(&wl->tx_queue)) {
+ if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) {
mutex_unlock(&wl->mutex);
return;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/tx.h
index d12a129ad11c..903e5dc69b7a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_TX_H__
-#define __WL1271_TX_H__
+#ifndef __TX_H__
+#define __TX_H__
#define TX_HW_BLOCK_SPARE 2
#define TX_HW_BLOCK_SIZE 252
@@ -140,10 +140,11 @@ static inline int wl1271_tx_get_queue(int queue)
}
void wl1271_tx_work(struct work_struct *work);
+void wl1271_tx_work_locked(struct wl1271 *wl);
void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl);
void wl1271_tx_flush(struct wl1271 *wl);
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
deleted file mode 100644
index 66c2b90ddfd4..000000000000
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_debugfs.h"
-
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-
-#include "wl1271.h"
-#include "wl1271_acx.h"
-#include "wl1271_ps.h"
-#include "wl1271_io.h"
-
-/* ms */
-#define WL1271_DEBUGFS_STATS_LIFETIME 1000
-
-/* debugfs macros idea from mac80211 */
-
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
-static ssize_t name## _read(struct file *file, char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1271 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
- \
- res = scnprintf(buf, buflen, fmt "\n", ##value); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-} \
- \
-static const struct file_operations name## _ops = { \
- .read = name## _read, \
- .open = wl1271_open_file_generic, \
- .llseek = generic_file_llseek, \
-};
-
-#define DEBUGFS_ADD(name, parent) \
- wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
- wl, &name## _ops); \
- if (IS_ERR(wl->debugfs.name)) { \
- ret = PTR_ERR(wl->debugfs.name); \
- wl->debugfs.name = NULL; \
- goto out; \
- }
-
-#define DEBUGFS_DEL(name) \
- do { \
- debugfs_remove(wl->debugfs.name); \
- wl->debugfs.name = NULL; \
- } while (0)
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
-static ssize_t sub## _ ##name## _read(struct file *file, \
- char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1271 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
- \
- wl1271_debugfs_update_stats(wl); \
- \
- res = scnprintf(buf, buflen, fmt "\n", \
- wl->stats.fw_stats->sub.name); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-} \
- \
-static const struct file_operations sub## _ ##name## _ops = { \
- .read = sub## _ ##name## _read, \
- .open = wl1271_open_file_generic, \
- .llseek = generic_file_llseek, \
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name) \
- DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
-
-#define DEBUGFS_FWSTATS_DEL(sub, name) \
- DEBUGFS_DEL(sub## _ ##name)
-
-static void wl1271_debugfs_update_stats(struct wl1271 *wl)
-{
- int ret;
-
- mutex_lock(&wl->mutex);
-
- ret = wl1271_ps_elp_wakeup(wl, false);
- if (ret < 0)
- goto out;
-
- if (wl->state == WL1271_STATE_ON &&
- time_after(jiffies, wl->stats.fw_stats_update +
- msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
- wl1271_acx_statistics(wl, wl->stats.fw_stats);
- wl->stats.fw_stats_update = jiffies;
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1271_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
- 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
- wl->stats.excessive_retries);
-
-static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- u32 queue_len;
- char buf[20];
- int res;
-
- queue_len = skb_queue_len(&wl->tx_queue);
-
- res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static const struct file_operations tx_queue_len_ops = {
- .read = tx_queue_len_read,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
-
- int res;
- char buf[10];
-
- res = scnprintf(buf, sizeof(buf), "%d\n", state);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, res);
-}
-
-static ssize_t gpio_power_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- char buf[10];
- size_t len;
- unsigned long value;
- int ret;
-
- mutex_lock(&wl->mutex);
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len)) {
- ret = -EFAULT;
- goto out;
- }
- buf[len] = '\0';
-
- ret = strict_strtoul(buf, 0, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in gpio_power");
- goto out;
- }
-
- if (value)
- wl1271_power_on(wl);
- else
- wl1271_power_off(wl);
-
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations gpio_power_ops = {
- .read = gpio_power_read,
- .write = gpio_power_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static void wl1271_debugfs_delete_files(struct wl1271 *wl)
-{
- DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
-
- DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
- DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
- DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
- DEBUGFS_FWSTATS_DEL(rx, dropped);
- DEBUGFS_FWSTATS_DEL(rx, fcs_err);
- DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
- DEBUGFS_FWSTATS_DEL(rx, path_reset);
- DEBUGFS_FWSTATS_DEL(rx, reset_counter);
-
- DEBUGFS_FWSTATS_DEL(dma, rx_requested);
- DEBUGFS_FWSTATS_DEL(dma, rx_errors);
- DEBUGFS_FWSTATS_DEL(dma, tx_requested);
- DEBUGFS_FWSTATS_DEL(dma, tx_errors);
-
- DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
- DEBUGFS_FWSTATS_DEL(isr, fiqs);
- DEBUGFS_FWSTATS_DEL(isr, rx_headers);
- DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
- DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
- DEBUGFS_FWSTATS_DEL(isr, irqs);
- DEBUGFS_FWSTATS_DEL(isr, tx_procs);
- DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
- DEBUGFS_FWSTATS_DEL(isr, dma0_done);
- DEBUGFS_FWSTATS_DEL(isr, dma1_done);
- DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
- DEBUGFS_FWSTATS_DEL(isr, commands);
- DEBUGFS_FWSTATS_DEL(isr, rx_procs);
- DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
- DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
- DEBUGFS_FWSTATS_DEL(isr, pci_pm);
- DEBUGFS_FWSTATS_DEL(isr, wakeups);
- DEBUGFS_FWSTATS_DEL(isr, low_rssi);
-
- DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
- DEBUGFS_FWSTATS_DEL(wep, default_key_count);
- /* skipping wep.reserved */
- DEBUGFS_FWSTATS_DEL(wep, key_not_found);
- DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
- DEBUGFS_FWSTATS_DEL(wep, packets);
- DEBUGFS_FWSTATS_DEL(wep, interrupt);
-
- DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
- DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
- DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
- DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
- DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
- DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
- DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
- DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
- DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
- DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
- DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
- DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
- /* skipping cont_miss_bcns_spread for now */
- DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
-
- DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
- DEBUGFS_FWSTATS_DEL(mic, calc_failure);
-
- DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
- DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
- DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
-
- DEBUGFS_FWSTATS_DEL(event, heart_beat);
- DEBUGFS_FWSTATS_DEL(event, calibration);
- DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
- DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
- DEBUGFS_FWSTATS_DEL(event, rx_pool);
- DEBUGFS_FWSTATS_DEL(event, oom_late);
- DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
- DEBUGFS_FWSTATS_DEL(event, tx_stuck);
-
- DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
- DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
- DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
- DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
- DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
- DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
- DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
-
- DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
- DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
-
- DEBUGFS_DEL(tx_queue_len);
- DEBUGFS_DEL(retry_count);
- DEBUGFS_DEL(excessive_retries);
-
- DEBUGFS_DEL(gpio_power);
-}
-
-static int wl1271_debugfs_add_files(struct wl1271 *wl)
-{
- int ret = 0;
-
- DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
- DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
- DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
- DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
- DEBUGFS_FWSTATS_ADD(rx, dropped);
- DEBUGFS_FWSTATS_ADD(rx, fcs_err);
- DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
- DEBUGFS_FWSTATS_ADD(rx, path_reset);
- DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
- DEBUGFS_FWSTATS_ADD(dma, rx_requested);
- DEBUGFS_FWSTATS_ADD(dma, rx_errors);
- DEBUGFS_FWSTATS_ADD(dma, tx_requested);
- DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
- DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
- DEBUGFS_FWSTATS_ADD(isr, fiqs);
- DEBUGFS_FWSTATS_ADD(isr, rx_headers);
- DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
- DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
- DEBUGFS_FWSTATS_ADD(isr, irqs);
- DEBUGFS_FWSTATS_ADD(isr, tx_procs);
- DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
- DEBUGFS_FWSTATS_ADD(isr, dma0_done);
- DEBUGFS_FWSTATS_ADD(isr, dma1_done);
- DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
- DEBUGFS_FWSTATS_ADD(isr, commands);
- DEBUGFS_FWSTATS_ADD(isr, rx_procs);
- DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
- DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
- DEBUGFS_FWSTATS_ADD(isr, pci_pm);
- DEBUGFS_FWSTATS_ADD(isr, wakeups);
- DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
- DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
- DEBUGFS_FWSTATS_ADD(wep, default_key_count);
- /* skipping wep.reserved */
- DEBUGFS_FWSTATS_ADD(wep, key_not_found);
- DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(wep, packets);
- DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
- DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
- DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
- DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
- DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
- DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
- DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
- DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
- /* skipping cont_miss_bcns_spread for now */
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
- DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
- DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
- DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
- DEBUGFS_FWSTATS_ADD(event, heart_beat);
- DEBUGFS_FWSTATS_ADD(event, calibration);
- DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
- DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
- DEBUGFS_FWSTATS_ADD(event, rx_pool);
- DEBUGFS_FWSTATS_ADD(event, oom_late);
- DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
- DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
- DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
- DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
- DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
- DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
-
- DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
- DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
- DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
-
- DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir);
-
-out:
- if (ret < 0)
- wl1271_debugfs_delete_files(wl);
-
- return ret;
-}
-
-void wl1271_debugfs_reset(struct wl1271 *wl)
-{
- memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
- wl->stats.retry_count = 0;
- wl->stats.excessive_retries = 0;
-}
-
-int wl1271_debugfs_init(struct wl1271 *wl)
-{
- int ret;
-
- wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
-
- if (IS_ERR(wl->debugfs.rootdir)) {
- ret = PTR_ERR(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
- goto err;
- }
-
- wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
- wl->debugfs.rootdir);
-
- if (IS_ERR(wl->debugfs.fw_statistics)) {
- ret = PTR_ERR(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
- goto err_root;
- }
-
- wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
- GFP_KERNEL);
-
- if (!wl->stats.fw_stats) {
- ret = -ENOMEM;
- goto err_fw;
- }
-
- wl->stats.fw_stats_update = jiffies;
-
- ret = wl1271_debugfs_add_files(wl);
-
- if (ret < 0)
- goto err_file;
-
- return 0;
-
-err_file:
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-
-err_fw:
- debugfs_remove(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
-
-err_root:
- debugfs_remove(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
-
-err:
- return ret;
-}
-
-void wl1271_debugfs_exit(struct wl1271 *wl)
-{
- wl1271_debugfs_delete_files(wl);
-
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-
- debugfs_remove(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
-
- debugfs_remove(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
-
-}
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 8a4cd763e5a2..ce3d31f98c55 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_H__
-#define __WL1271_H__
+#ifndef __WL12XX_H__
+#define __WL12XX_H__
#include <linux/mutex.h>
#include <linux/completion.h>
@@ -32,8 +32,8 @@
#include <linux/bitops.h>
#include <net/mac80211.h>
-#include "wl1271_conf.h"
-#include "wl1271_ini.h"
+#include "conf.h"
+#include "ini.h"
#define DRIVER_NAME "wl1271"
#define DRIVER_PREFIX DRIVER_NAME ": "
@@ -60,31 +60,32 @@ enum {
DEBUG_ALL = ~0,
};
-#define DEBUG_LEVEL (DEBUG_NONE)
+extern u32 wl12xx_debug_level;
#define DEBUG_DUMP_LIMIT 1024
#define wl1271_error(fmt, arg...) \
- printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+ pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
#define wl1271_warning(fmt, arg...) \
- printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+ pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
#define wl1271_notice(fmt, arg...) \
- printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+ pr_info(DRIVER_PREFIX fmt "\n", ##arg)
#define wl1271_info(fmt, arg...) \
- printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+ pr_info(DRIVER_PREFIX fmt "\n", ##arg)
#define wl1271_debug(level, fmt, arg...) \
do { \
- if (level & DEBUG_LEVEL) \
- printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+ if (level & wl12xx_debug_level) \
+ pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
} while (0)
+/* TODO: use pr_debug_hex_dump when it will be available */
#define wl1271_dump(level, prefix, buf, len) \
do { \
- if (level & DEBUG_LEVEL) \
+ if (level & wl12xx_debug_level) \
print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
DUMP_PREFIX_OFFSET, 16, 1, \
buf, \
@@ -94,7 +95,7 @@ enum {
#define wl1271_dump_ascii(level, prefix, buf, len) \
do { \
- if (level & DEBUG_LEVEL) \
+ if (level & wl12xx_debug_level) \
print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
DUMP_PREFIX_OFFSET, 16, 1, \
buf, \
@@ -174,108 +175,6 @@ struct wl1271_stats {
unsigned int excessive_retries;
};
-struct wl1271_debugfs {
- struct dentry *rootdir;
- struct dentry *fw_statistics;
-
- struct dentry *tx_internal_desc_overflow;
-
- struct dentry *rx_out_of_mem;
- struct dentry *rx_hdr_overflow;
- struct dentry *rx_hw_stuck;
- struct dentry *rx_dropped;
- struct dentry *rx_fcs_err;
- struct dentry *rx_xfr_hint_trig;
- struct dentry *rx_path_reset;
- struct dentry *rx_reset_counter;
-
- struct dentry *dma_rx_requested;
- struct dentry *dma_rx_errors;
- struct dentry *dma_tx_requested;
- struct dentry *dma_tx_errors;
-
- struct dentry *isr_cmd_cmplt;
- struct dentry *isr_fiqs;
- struct dentry *isr_rx_headers;
- struct dentry *isr_rx_mem_overflow;
- struct dentry *isr_rx_rdys;
- struct dentry *isr_irqs;
- struct dentry *isr_tx_procs;
- struct dentry *isr_decrypt_done;
- struct dentry *isr_dma0_done;
- struct dentry *isr_dma1_done;
- struct dentry *isr_tx_exch_complete;
- struct dentry *isr_commands;
- struct dentry *isr_rx_procs;
- struct dentry *isr_hw_pm_mode_changes;
- struct dentry *isr_host_acknowledges;
- struct dentry *isr_pci_pm;
- struct dentry *isr_wakeups;
- struct dentry *isr_low_rssi;
-
- struct dentry *wep_addr_key_count;
- struct dentry *wep_default_key_count;
- /* skipping wep.reserved */
- struct dentry *wep_key_not_found;
- struct dentry *wep_decrypt_fail;
- struct dentry *wep_packets;
- struct dentry *wep_interrupt;
-
- struct dentry *pwr_ps_enter;
- struct dentry *pwr_elp_enter;
- struct dentry *pwr_missing_bcns;
- struct dentry *pwr_wake_on_host;
- struct dentry *pwr_wake_on_timer_exp;
- struct dentry *pwr_tx_with_ps;
- struct dentry *pwr_tx_without_ps;
- struct dentry *pwr_rcvd_beacons;
- struct dentry *pwr_power_save_off;
- struct dentry *pwr_enable_ps;
- struct dentry *pwr_disable_ps;
- struct dentry *pwr_fix_tsf_ps;
- /* skipping cont_miss_bcns_spread for now */
- struct dentry *pwr_rcvd_awake_beacons;
-
- struct dentry *mic_rx_pkts;
- struct dentry *mic_calc_failure;
-
- struct dentry *aes_encrypt_fail;
- struct dentry *aes_decrypt_fail;
- struct dentry *aes_encrypt_packets;
- struct dentry *aes_decrypt_packets;
- struct dentry *aes_encrypt_interrupt;
- struct dentry *aes_decrypt_interrupt;
-
- struct dentry *event_heart_beat;
- struct dentry *event_calibration;
- struct dentry *event_rx_mismatch;
- struct dentry *event_rx_mem_empty;
- struct dentry *event_rx_pool;
- struct dentry *event_oom_late;
- struct dentry *event_phy_transmit_error;
- struct dentry *event_tx_stuck;
-
- struct dentry *ps_pspoll_timeouts;
- struct dentry *ps_upsd_timeouts;
- struct dentry *ps_upsd_max_sptime;
- struct dentry *ps_upsd_max_apturn;
- struct dentry *ps_pspoll_max_apturn;
- struct dentry *ps_pspoll_utilization;
- struct dentry *ps_upsd_utilization;
-
- struct dentry *rxpipe_rx_prep_beacon_drop;
- struct dentry *rxpipe_descr_host_int_trig_rx_data;
- struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
- struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
- struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
-
- struct dentry *tx_queue_len;
-
- struct dentry *retry_count;
- struct dentry *excessive_retries;
- struct dentry *gpio_power;
-};
-
#define NUM_TX_QUEUES 4
#define NUM_RX_PKT_DESC 8
@@ -351,6 +250,7 @@ struct wl1271 {
#define WL1271_FLAG_IDLE_REQUESTED (11)
#define WL1271_FLAG_PSPOLL_FAILURE (12)
#define WL1271_FLAG_STA_STATE_SENT (13)
+#define WL1271_FLAG_FW_TX_BUSY (14)
unsigned long flags;
struct wl1271_partition_set part;
@@ -392,11 +292,13 @@ struct wl1271 {
int session_counter;
/* Frames scheduled for transmission, not handled yet */
- struct sk_buff_head tx_queue;
+ struct sk_buff_head tx_queue[NUM_TX_QUEUES];
+ int tx_queue_count;
struct work_struct tx_work;
/* Pending TX frames */
+ unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
int tx_frames_cnt;
@@ -429,10 +331,18 @@ struct wl1271 {
struct wl1271_scan scan;
struct delayed_work scan_complete_work;
+ /* probe-req template for the current AP */
+ struct sk_buff *probereq;
+
/* Our association ID */
u16 aid;
- /* currently configured rate set */
+ /*
+ * currently configured rate set:
+ * bits 0-15 - 802.11abg rates
+ * bits 16-23 - 802.11n MCS index mask
+ * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
+ */
u32 sta_rate_set;
u32 basic_rate_set;
u32 basic_rate;
@@ -468,7 +378,7 @@ struct wl1271 {
int last_rssi_event;
struct wl1271_stats stats;
- struct wl1271_debugfs debugfs;
+ struct dentry *rootdir;
__le32 buffer_32;
u32 buffer_cmd;
@@ -509,4 +419,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
+/* Macros to handle wl1271.sta_rate_set */
+#define HW_BG_RATES_MASK 0xffff
+#define HW_HT_RATES_OFFSET 16
+
#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
index 184628027213..be21032f4dc1 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h
@@ -2,6 +2,7 @@
#define __WL12XX_80211_H__
#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/if_arp.h>
/* RATES */
#define IEEE80211_CCK_RATE_1MB 0x02
@@ -133,11 +134,17 @@ struct wl12xx_qos_null_data_template {
__le16 qos_ctl;
} __packed;
-struct wl12xx_probe_req_template {
- struct ieee80211_header header;
- struct wl12xx_ie_ssid ssid;
- struct wl12xx_ie_rates rates;
- struct wl12xx_ie_rates ext_rates;
+struct wl12xx_arp_rsp_template {
+ struct ieee80211_hdr_3addr hdr;
+
+ u8 llc_hdr[sizeof(rfc1042_header)];
+ u16 llc_type;
+
+ struct arphdr arp_hdr;
+ u8 sender_hw[ETH_ALEN];
+ u32 sender_ip;
+ u8 target_hw[ETH_ALEN];
+ u32 target_ip;
} __packed;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 390d77f762c4..415eec401e2e 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -30,6 +30,7 @@ static struct usb_device_id zd1201_table[] = {
{USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
{USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */
{USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */
+ {USB_DEVICE(0x1044, 0x8004)}, /* Gigabyte GN-WLBZ101 */
{USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
{}
};
@@ -1829,7 +1830,7 @@ err_zd:
static void zd1201_disconnect(struct usb_interface *interface)
{
- struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface);
+ struct zd1201 *zd = usb_get_intfdata(interface);
struct hlist_node *node, *node2;
struct zd1201_frag *frag;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 87a95bcfee57..6a9b66051cf7 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -117,6 +117,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
/* Allocate a single memory block for values and addresses. */
count16 = 2*count;
+ /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */
a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
GFP_KERNEL);
if (!a16) {
@@ -1448,7 +1449,7 @@ int zd_rfwritev_locked(struct zd_chip *chip,
*/
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
{
- struct zd_ioreq16 ioreqs[] = {
+ const struct zd_ioreq16 ioreqs[] = {
{ CR244, (value >> 16) & 0xff },
{ CR243, (value >> 8) & 0xff },
{ CR242, value & 0xff },
@@ -1475,7 +1476,7 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash)
{
- struct zd_ioreq32 ioreqs[] = {
+ const struct zd_ioreq32 ioreqs[] = {
{ CR_GROUP_HASH_P1, hash->low },
{ CR_GROUP_HASH_P2, hash->high },
};
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 818e1480ca93..06041cb1c422 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -55,6 +55,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
+ { USB_DEVICE(0x14ea, 0xab10), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
@@ -92,6 +93,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x2019, 0xed01), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 458bb57914a3..cdbeec9f83ea 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -66,8 +66,8 @@ struct netfront_cb {
#define GRANT_INVALID_REF 0
-#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
struct netfront_info {
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 14f0955eca68..de6c3086d232 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -515,7 +515,7 @@ static void xemaclite_update_address(struct net_local *drvdata,
*/
static int xemaclite_set_mac_address(struct net_device *dev, void *address)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
struct sockaddr *addr = address;
if (netif_running(dev))
@@ -534,7 +534,7 @@ static int xemaclite_set_mac_address(struct net_device *dev, void *address)
*/
static void xemaclite_tx_timeout(struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
unsigned long flags;
dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n",
@@ -578,7 +578,7 @@ static void xemaclite_tx_timeout(struct net_device *dev)
*/
static void xemaclite_tx_handler(struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
dev->stats.tx_packets++;
if (lp->deferred_skb) {
@@ -605,7 +605,7 @@ static void xemaclite_tx_handler(struct net_device *dev)
*/
static void xemaclite_rx_handler(struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
struct sk_buff *skb;
unsigned int align;
u32 len;
@@ -661,7 +661,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
{
bool tx_complete = 0;
struct net_device *dev = dev_id;
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
void __iomem *base_addr = lp->base_addr;
u32 tx_status;
@@ -918,7 +918,7 @@ void xemaclite_adjust_link(struct net_device *ndev)
*/
static int xemaclite_open(struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
int retval;
/* Just to be safe, stop the device first */
@@ -987,7 +987,7 @@ static int xemaclite_open(struct net_device *dev)
*/
static int xemaclite_close(struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
netif_stop_queue(dev);
xemaclite_disable_interrupts(lp);
@@ -1001,21 +1001,6 @@ static int xemaclite_close(struct net_device *dev)
}
/**
- * xemaclite_get_stats - Get the stats for the net_device
- * @dev: Pointer to the network device
- *
- * This function returns the address of the 'net_device_stats' structure for the
- * given network device. This structure holds usage statistics for the network
- * device.
- *
- * Return: Pointer to the net_device_stats structure.
- */
-static struct net_device_stats *xemaclite_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
-/**
* xemaclite_send - Transmit a frame
* @orig_skb: Pointer to the socket buffer to be transmitted
* @dev: Pointer to the network device
@@ -1031,7 +1016,7 @@ static struct net_device_stats *xemaclite_get_stats(struct net_device *dev)
*/
static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
{
- struct net_local *lp = (struct net_local *) netdev_priv(dev);
+ struct net_local *lp = netdev_priv(dev);
struct sk_buff *new_skb;
unsigned int len;
unsigned long flags;
@@ -1068,7 +1053,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
static void xemaclite_remove_ndev(struct net_device *ndev)
{
if (ndev) {
- struct net_local *lp = (struct net_local *) netdev_priv(ndev);
+ struct net_local *lp = netdev_priv(ndev);
if (lp->base_addr)
iounmap((void __iomem __force *) (lp->base_addr));
@@ -1245,7 +1230,7 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev)
struct device *dev = &of_dev->dev;
struct net_device *ndev = dev_get_drvdata(dev);
- struct net_local *lp = (struct net_local *) netdev_priv(ndev);
+ struct net_local *lp = netdev_priv(ndev);
/* Un-register the mii_bus, if configured */
if (lp->has_mdio) {
@@ -1285,7 +1270,6 @@ static struct net_device_ops xemaclite_netdev_ops = {
.ndo_start_xmit = xemaclite_send,
.ndo_set_mac_address = xemaclite_set_mac_address,
.ndo_tx_timeout = xemaclite_tx_timeout,
- .ndo_get_stats = xemaclite_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = xemaclite_poll_controller,
#endif
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index cd1b3dcd61db..ec47e22fa186 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -744,7 +744,7 @@ static int yellowfin_init_ring(struct net_device *dev)
}
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
yp->rx_skbuff[i] = skb;
if (skb == NULL)
break;
@@ -1157,7 +1157,7 @@ static int yellowfin_rx(struct net_device *dev)
for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) {
entry = yp->dirty_rx % RX_RING_SIZE;
if (yp->rx_skbuff[entry] == NULL) {
- struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
+ struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
if (skb == NULL)
break; /* Better luck next round. */
yp->rx_skbuff[entry] = skb;
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index c3a329204511..ae07b3dfbcc1 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -124,7 +124,7 @@ MODULE_LICENSE("GPL");
#define TX_BUF_SIZE 8192
#define DMA_BUF_SIZE (RX_BUF_SIZE + 16) /* 8k + 16 bytes for trailers */
-#define TX_TIMEOUT 10
+#define TX_TIMEOUT (HZ/10)
struct znet_private {
int rx_dma, tx_dma;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 3a1c7e70b192..b4559c58c095 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -12,13 +12,13 @@
(ns) > 0)
static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
- u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+ const __be32 *addrp, u64 size, unsigned int flags,
struct resource *r);
/* Debug utility */
#ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
{
printk(KERN_DEBUG "%s", s);
while (na--)
@@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na)
printk("\n");
}
#else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
#endif
/* Callbacks for bus specific translators */
@@ -36,10 +36,10 @@ struct of_bus {
int (*match)(struct device_node *parent);
void (*count_cells)(struct device_node *child,
int *addrc, int *sizec);
- u64 (*map)(u32 *addr, const u32 *range,
+ u64 (*map)(u32 *addr, const __be32 *range,
int na, int ns, int pna);
int (*translate)(u32 *addr, u64 offset, int na);
- unsigned int (*get_flags)(const u32 *addr);
+ unsigned int (*get_flags)(const __be32 *addr);
};
/*
@@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev,
*sizec = of_n_size_cells(dev);
}
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
+static u64 of_bus_default_map(u32 *addr, const __be32 *range,
int na, int ns, int pna)
{
u64 cp, s, da;
@@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
return 0;
}
-static unsigned int of_bus_default_get_flags(const u32 *addr)
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
{
return IORESOURCE_MEM;
}
@@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np,
*sizec = 2;
}
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+static unsigned int of_bus_pci_get_flags(const __be32 *addr)
{
unsigned int flags = 0;
- u32 w = addr[0];
+ u32 w = be32_to_cpup(addr);
switch((w >> 24) & 0x03) {
case 0x01:
@@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
return flags;
}
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns,
+ int pna)
{
u64 cp, s, da;
unsigned int af, rf;
@@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
return of_bus_default_translate(addr + 1, offset, na - 1);
}
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
unsigned int *flags)
{
const __be32 *prop;
@@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address);
int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r)
{
- const u32 *addrp;
+ const __be32 *addrp;
u64 size;
unsigned int flags;
@@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child,
*sizec = 1;
}
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns,
+ int pna)
{
u64 cp, s, da;
/* Check address type match */
- if ((addr[0] ^ range[0]) & 0x00000001)
+ if ((addr[0] ^ range[0]) & cpu_to_be32(1))
return OF_BAD_ADDR;
/* Read address values, skipping high cell */
@@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
return of_bus_default_translate(addr + 1, offset, na - 1);
}
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
+static unsigned int of_bus_isa_get_flags(const __be32 *addr)
{
unsigned int flags = 0;
- u32 w = addr[0];
+ u32 w = be32_to_cpup(addr);
if (w & 1)
flags |= IORESOURCE_IO;
@@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
struct of_bus *pbus, u32 *addr,
int na, int ns, int pna, const char *rprop)
{
- const u32 *ranges;
+ const __be32 *ranges;
unsigned int rlen;
int rone;
u64 offset = OF_BAD_ADDR;
@@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
* that can be mapped to a cpu physical address). This is not really specified
* that way, but this is traditionally the way IBM at least do things
*/
-u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr,
const char *rprop)
{
struct device_node *parent = NULL;
@@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
return result;
}
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
{
return __of_translate_address(dev, in_addr, "ranges");
}
EXPORT_SYMBOL(of_translate_address);
-u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
{
return __of_translate_address(dev, in_addr, "dma-ranges");
}
EXPORT_SYMBOL(of_translate_dma_address);
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
unsigned int *flags)
{
- const u32 *prop;
+ const __be32 *prop;
unsigned int psize;
struct device_node *parent;
struct of_bus *bus;
@@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
}
EXPORT_SYMBOL(of_get_address);
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
- u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+ const __be32 *addrp, u64 size, unsigned int flags,
struct resource *r)
{
u64 taddr;
@@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
int of_address_to_resource(struct device_node *dev, int index,
struct resource *r)
{
- const u32 *addrp;
+ const __be32 *addrp;
u64 size;
unsigned int flags;
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index c85d3c7421fc..f37fbeb66a44 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -61,7 +61,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
- request_module("%s", info.type);
+ request_module("%s%s", I2C_MODULE_PREFIX, info.type);
result = i2c_new_device(adap, &info);
if (result == NULL) {
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index d9f51485beee..9383063d2b16 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -349,7 +349,6 @@ static struct irq_chip dino_interrupt_type = {
.name = "GSC-PCI",
.unmask = dino_unmask_irq,
.mask = dino_mask_irq,
- .ack = no_ack_irq,
};
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 1211974f55aa..e860038b0b84 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -186,7 +186,6 @@ static struct irq_chip eisa_interrupt_type = {
.name = "EISA",
.unmask = eisa_unmask_irq,
.mask = eisa_mask_irq,
- .ack = no_ack_irq,
};
static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
@@ -340,7 +339,7 @@ static int __init eisa_probe(struct parisc_device *dev)
setup_irq(2, &irq2_action);
for (i = 0; i < 16; i++) {
set_irq_chip_and_handler(i, &eisa_interrupt_type,
- handle_level_irq);
+ handle_simple_irq);
}
EISA_bus = 1;
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index e605298e3aee..772b1939ac21 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -143,7 +143,6 @@ static struct irq_chip gsc_asic_interrupt_type = {
.name = "GSC-ASIC",
.unmask = gsc_asic_unmask_irq,
.mask = gsc_asic_mask_irq,
- .ack = no_ack_irq,
};
int gsc_assign_irq(struct irq_chip *type, void *data)
@@ -153,7 +152,7 @@ int gsc_assign_irq(struct irq_chip *type, void *data)
if (irq > GSC_IRQ_MAX)
return NO_IRQ;
- set_irq_chip_and_handler(irq, type, handle_level_irq);
+ set_irq_chip_and_handler(irq, type, handle_simple_irq);
set_irq_chip_data(irq, data);
return irq++;
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index a3120a09c43d..0327894bf235 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -669,6 +669,13 @@ printk("\n");
DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
vi->eoi_addr, vi->eoi_data);
iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
+
+static void iosapic_eoi_irq(unsigned int irq)
+{
+ struct vector_info *vi = get_irq_chip_data(irq);
+
+ iosapic_eoi(vi->eoi_addr, vi->eoi_data);
cpu_eoi_irq(irq);
}
@@ -705,6 +712,7 @@ static struct irq_chip iosapic_interrupt_type = {
.unmask = iosapic_unmask_irq,
.mask = iosapic_mask_irq,
.ack = cpu_ack_irq,
+ .eoi = iosapic_eoi_irq,
#ifdef CONFIG_SMP
.set_affinity = iosapic_set_affinity_irq,
#endif
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 2350e8a86eef..f2f501e5b6a0 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -64,6 +64,7 @@ static unsigned int led_diskio __read_mostly = 1;
static unsigned int led_lanrxtx __read_mostly = 1;
static char lcd_text[32] __read_mostly;
static char lcd_text_default[32] __read_mostly;
+static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
static struct workqueue_struct *led_wq;
@@ -115,7 +116,7 @@ lcd_info __attribute__((aligned(8))) __read_mostly =
.lcd_width = 16,
.lcd_cmd_reg_addr = KITTYHAWK_LCD_CMD,
.lcd_data_reg_addr = KITTYHAWK_LCD_DATA,
- .min_cmd_delay = 40,
+ .min_cmd_delay = 80,
.reset_cmd1 = 0x80,
.reset_cmd2 = 0xc0,
};
@@ -135,6 +136,9 @@ static int start_task(void)
/* Display the default text now */
if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
+ /* KittyHawk has no LED support on its LCD */
+ if (lcd_no_led_support) return 0;
+
/* Create the work queue and queue the LED task */
led_wq = create_singlethread_workqueue("led_wq");
queue_delayed_work(led_wq, &led_task, 0);
@@ -248,9 +252,13 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
- &led_proc_fops, (void *)LED_NOLCD); /* LED */
- if (!ent) return -1;
+
+ if (!lcd_no_led_support)
+ {
+ ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+ &led_proc_fops, (void *)LED_NOLCD); /* LED */
+ if (!ent) return -1;
+ }
if (led_type == LED_HASLCD)
{
@@ -692,6 +700,7 @@ int __init led_init(void)
case 0x58B: /* KittyHawk DC2 100 (K200) */
printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
"LED detection skipped.\n", __FILE__, CPU_HVERSION);
+ lcd_no_led_support = 1;
goto found; /* use the preinitialized values of lcd_info */
}
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 0846dafdfff1..28241532c0fd 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -323,7 +323,6 @@ static struct irq_chip superio_interrupt_type = {
.name = SUPERIO,
.unmask = superio_unmask_irq,
.mask = superio_mask_irq,
- .ack = no_ack_irq,
};
#ifdef DEBUG_SUPERIO_INIT
@@ -354,7 +353,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
#endif
for (i = 0; i < 16; i++) {
- set_irq_chip_and_handler(i, &superio_interrupt_type, handle_level_irq);
+ set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq);
}
/*
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 003170ea2e39..69546e9213dd 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
}
}
-static bool pci_bus_resource_better(struct resource *res1, bool pos1,
- struct resource *res2, bool pos2)
-{
- /* If exactly one is positive decode, always prefer that one */
- if (pos1 != pos2)
- return pos1 ? true : false;
-
- /* Prefer the one that contains the highest address */
- if (res1->end != res2->end)
- return (res1->end > res2->end) ? true : false;
-
- /* Otherwise, prefer the one with highest "center of gravity" */
- if (res1->start != res2->start)
- return (res1->start > res2->start) ? true : false;
-
- /* Otherwise, choose one arbitrarily (but consistently) */
- return (res1 > res2) ? true : false;
-}
-
-static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res)
-{
- struct pci_bus_resource *bus_res;
-
- /*
- * This relies on the fact that pci_bus.resource[] refers to P2P or
- * CardBus bridge base/limit registers, which are always positively
- * decoded. The pci_bus.resources list contains host bridge or
- * subtractively decoded resources.
- */
- list_for_each_entry(bus_res, &bus->resources, list) {
- if (bus_res->res == res)
- return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ?
- false : true;
- }
- return true;
-}
-
-/*
- * Find the next-best bus resource after the cursor "res". If the cursor is
- * NULL, return the best resource. "Best" means that we prefer positive
- * decode regions over subtractive decode, then those at higher addresses.
- */
-static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
- unsigned int type,
- struct resource *res)
-{
- bool res_pos, r_pos, prev_pos = false;
- struct resource *r, *prev = NULL;
- int i;
-
- res_pos = pci_bus_resource_positive(bus, res);
- pci_bus_for_each_resource(bus, r, i) {
- if (!r)
- continue;
-
- if ((r->flags & IORESOURCE_TYPE_BITS) != type)
- continue;
-
- r_pos = pci_bus_resource_positive(bus, r);
- if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) {
- if (!prev || pci_bus_resource_better(r, r_pos,
- prev, prev_pos)) {
- prev = r;
- prev_pos = r_pos;
- }
- }
- }
-
- return prev;
-}
-
/**
* pci_bus_alloc_resource - allocate a resource from a parent bus
* @bus: PCI bus
@@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
resource_size_t),
void *alignf_data)
{
- int ret = -ENOMEM;
+ int i, ret = -ENOMEM;
struct resource *r;
resource_size_t max = -1;
- unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
@@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
if (!(res->flags & IORESOURCE_MEM_64))
max = PCIBIOS_MAX_MEM_32;
- /* Look for space at highest addresses first */
- r = pci_bus_find_resource_prev(bus, type, NULL);
- for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) {
+ pci_bus_for_each_resource(bus, r, i) {
+ if (!r)
+ continue;
+
/* type_mask must match */
if ((res->flags ^ r->flags) & type_mask)
continue;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0157708d474d..09933eb9126b 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void)
(unsigned long long)drhd->reg_base_addr, ret);
return -1;
}
+
+ /*
+ * Clear any previous faults.
+ */
+ dmar_fault(iommu->irq, iommu);
}
return 0;
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 2574700db461..5f7226223a62 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -115,7 +115,8 @@ static struct pcie_port_service_driver __initdata dummy_driver = {
static int __init select_detection_mode(void)
{
struct dummy_slot *slot, *tmp;
- pcie_port_service_register(&dummy_driver);
+ if (pcie_port_service_register(&dummy_driver))
+ return PCIEHP_DETECT_ACPI;
pcie_port_service_unregister(&dummy_driver);
list_for_each_entry_safe(slot, tmp, &dummy_slots, list) {
list_del(&slot->list);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7c24dcef2989..44b0aeee83e5 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -168,8 +168,9 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
u32 mask_bits = desc->masked;
unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_VECTOR_CTRL;
- mask_bits &= ~1;
- mask_bits |= flag;
+ mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
+ if (flag)
+ mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
writel(mask_bits, desc->mask_base + offset);
return mask_bits;
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index feff3bee6fe5..65c42f80f23e 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -6,12 +6,6 @@
#ifndef MSI_H
#define MSI_H
-#define PCI_MSIX_ENTRY_SIZE 16
-#define PCI_MSIX_ENTRY_LOWER_ADDR 0
-#define PCI_MSIX_ENTRY_UPPER_ADDR 4
-#define PCI_MSIX_ENTRY_DATA 8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
-
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 24e19c594e57..d7ea699b8ddc 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -399,6 +399,7 @@ static int __init acpi_pci_init(void)
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
+ pcie_clear_aspm();
pcie_no_aspm();
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 8a6f797de8e5..88246dd46452 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
}
/**
- * __pci_device_probe()
+ * __pci_device_probe - check if a driver wants to claim a specific PCI device
* @drv: driver to call to check if it wants the PCI device
* @pci_dev: PCI device being probed
*
@@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
return error;
}
- return pci_restore_state(pci_dev);
+ pci_restore_state(pci_dev);
+ return 0;
}
static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index f7b68ca6cc98..775e933c2225 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -47,6 +47,10 @@ static int __init pci_stub_init(void)
if (rc)
return rc;
+ /* no ids passed actually */
+ if (ids[0] == '\0')
+ return 0;
+
/* add ids specified in the module parameter */
p = ids;
while ((id = strsep(&p, ","))) {
@@ -54,6 +58,9 @@ static int __init pci_stub_init(void)
subdevice = PCI_ANY_ID, class=0, class_mask=0;
int fields;
+ if (!strlen(id))
+ continue;
+
fields = sscanf(id, "%x:%x:%x:%x:%x:%x",
&vendor, &device, &subvendor, &subdevice,
&class, &class_mask);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 710c8a29be0d..6762dcae90ab 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev)
* pci_restore_state - Restore the saved state of a PCI device
* @dev: - PCI device that we're dealing with
*/
-int
-pci_restore_state(struct pci_dev *dev)
+void pci_restore_state(struct pci_dev *dev)
{
int i;
u32 val;
if (!dev->state_saved)
- return 0;
+ return;
/* PCI Express register must be restored first */
pci_restore_pcie_state(dev);
@@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev)
pci_restore_iov_state(dev);
dev->state_saved = false;
-
- return 0;
}
static int do_pci_enable_device(struct pci_dev *dev, int bars)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 71222814c1ec..3188cd96b338 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -68,7 +68,7 @@ struct pcie_link_state {
struct aspm_latency acceptable[8];
};
-static int aspm_disabled, aspm_force;
+static int aspm_disabled, aspm_force, aspm_clear_state;
static DEFINE_MUTEX(aspm_lock);
static LIST_HEAD(link_list);
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
{
/* Don't enable Clock PM if the link is not Clock PM capable */
if (!link->clkpm_capable && enable)
- return;
+ enable = 0;
/* Need nothing if the specified equals to current state */
if (link->clkpm_enabled == enable)
return;
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
struct pci_dev *child;
int pos;
u32 reg32;
+
+ if (aspm_clear_state)
+ return -EINVAL;
+
/*
* Some functions in a slot might not all be PCIe functions,
* very strange. Disable ASPM for the whole slot
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
struct pcie_link_state *link;
int blacklist = !!pcie_aspm_sanity_check(pdev);
- if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
+ if (!pci_is_pcie(pdev) || pdev->link_state)
return;
if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
return;
+ if (aspm_disabled && !aspm_clear_state)
+ return;
+
/* VIA has a strange chipset, root port is under a bridge */
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
pdev->bus->self)
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link, *root, *parent_link;
- if (aspm_disabled || !pci_is_pcie(pdev) ||
+ if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
!parent || !parent->link_state)
return;
if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str)
__setup("pcie_aspm=", pcie_aspm_disable);
+void pcie_clear_aspm(void)
+{
+ if (!aspm_force)
+ aspm_clear_state = 1;
+}
+
void pcie_no_aspm(void)
{
if (!aspm_force)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 2f3c90407227..073f0308c6b2 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -26,9 +26,6 @@
#include "../pci.h"
#include "portdrv.h"
-#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
-#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
-
/*
* If this switch is set, MSI will not be used for PCIe PME signaling. This
* causes the PCIe port driver to use INTx interrupts only, but it turns out
@@ -74,22 +71,6 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
}
/**
- * pcie_pme_clear_status - Clear root port PME interrupt status.
- * @dev: PCIe root port or event collector.
- */
-static void pcie_pme_clear_status(struct pci_dev *dev)
-{
- int rtsta_pos;
- u32 rtsta;
-
- rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
-
- pci_read_config_dword(dev, rtsta_pos, &rtsta);
- rtsta |= PCI_EXP_RTSTA_PME;
- pci_write_config_dword(dev, rtsta_pos, rtsta);
-}
-
-/**
* pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
* @bus: PCI bus to scan.
*
@@ -253,7 +234,7 @@ static void pcie_pme_work_fn(struct work_struct *work)
* Clear PME status of the port. If there are other
* pending PMEs, the status will be set again.
*/
- pcie_pme_clear_status(port);
+ pcie_clear_root_pme_status(port);
spin_unlock_irq(&data->lock);
pcie_pme_handle_request(port, rtsta & 0xffff);
@@ -378,7 +359,7 @@ static int pcie_pme_probe(struct pcie_device *srv)
port = srv->port;
pcie_pme_interrupt_enable(port, false);
- pcie_pme_clear_status(port);
+ pcie_clear_root_pme_status(port);
ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv);
if (ret) {
@@ -402,7 +383,7 @@ static int pcie_pme_suspend(struct pcie_device *srv)
spin_lock_irq(&data->lock);
pcie_pme_interrupt_enable(port, false);
- pcie_pme_clear_status(port);
+ pcie_clear_root_pme_status(port);
data->noirq = true;
spin_unlock_irq(&data->lock);
@@ -422,7 +403,7 @@ static int pcie_pme_resume(struct pcie_device *srv)
spin_lock_irq(&data->lock);
data->noirq = false;
- pcie_pme_clear_status(port);
+ pcie_clear_root_pme_status(port);
pcie_pme_interrupt_enable(port, true);
spin_unlock_irq(&data->lock);
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 7b5aba0a3291..8fcc03598b29 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -35,6 +35,8 @@ extern void pcie_port_bus_unregister(void);
struct pci_dev;
+extern void pcie_clear_root_pme_status(struct pci_dev *dev);
+
#ifdef CONFIG_PCIE_PME
extern bool pcie_pme_msi_disabled;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index a9c222d79ebc..5130d0d22390 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev)
int cap_mask;
int err;
+ if (pcie_ports_disabled)
+ return 0;
+
err = pcie_port_platform_notify(dev, &cap_mask);
- if (pcie_ports_auto) {
- if (err) {
- pcie_no_aspm();
- return 0;
- }
- } else {
+ if (!pcie_ports_auto) {
cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
| PCIE_PORT_SERVICE_VC;
if (pci_aer_available())
cap_mask |= PCIE_PORT_SERVICE_AER;
+ } else if (err) {
+ return 0;
}
pos = pci_pcie_cap(dev);
@@ -349,15 +349,18 @@ int pcie_port_device_register(struct pci_dev *dev)
int status, capabilities, i, nr_service;
int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
- /* Get and check PCI Express port services */
- capabilities = get_port_device_capability(dev);
- if (!capabilities)
- return -ENODEV;
-
/* Enable PCI Express port device */
status = pci_enable_device(dev);
if (status)
return status;
+
+ /* Get and check PCI Express port services */
+ capabilities = get_port_device_capability(dev);
+ if (!capabilities) {
+ pcie_no_aspm();
+ return 0;
+ }
+
pci_set_master(dev);
/*
* Initialize service irqs. Don't use service devices that
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index f9033e190fb6..e0610bda1dea 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -57,6 +57,22 @@ __setup("pcie_ports=", pcie_port_setup);
/* global data */
+/**
+ * pcie_clear_root_pme_status - Clear root port PME interrupt status.
+ * @dev: PCIe root port or event collector.
+ */
+void pcie_clear_root_pme_status(struct pci_dev *dev)
+{
+ int rtsta_pos;
+ u32 rtsta;
+
+ rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
+
+ pci_read_config_dword(dev, rtsta_pos, &rtsta);
+ rtsta |= PCI_EXP_RTSTA_PME;
+ pci_write_config_dword(dev, rtsta_pos, rtsta);
+}
+
static int pcie_portdrv_restore_config(struct pci_dev *dev)
{
int retval;
@@ -69,6 +85,20 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
}
#ifdef CONFIG_PM
+static int pcie_port_resume_noirq(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ /*
+ * Some BIOSes forget to clear Root PME Status bits after system wakeup
+ * which breaks ACPI-based runtime wakeup on PCI Express, so clear those
+ * bits now just in case (shouldn't hurt).
+ */
+ if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ pcie_clear_root_pme_status(pdev);
+ return 0;
+}
+
static const struct dev_pm_ops pcie_portdrv_pm_ops = {
.suspend = pcie_port_device_suspend,
.resume = pcie_port_device_resume,
@@ -76,6 +106,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
.thaw = pcie_port_device_resume,
.poweroff = pcie_port_device_suspend,
.restore = pcie_port_device_resume,
+ .resume_noirq = pcie_port_resume_noirq,
};
#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
@@ -327,10 +358,8 @@ static int __init pcie_portdrv_init(void)
{
int retval;
- if (pcie_ports_disabled) {
- pcie_no_aspm();
- return -EACCES;
- }
+ if (pcie_ports_disabled)
+ return pci_register_driver(&pcie_portdriver);
dmi_check_system(pcie_portdrv_dmi_table);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6f9350cabbd5..53a786fd0d40 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
{
u32 cfg;
+ if (!pci_find_capability(dev, PCI_CAP_ID_HT))
+ return;
+
pci_read_config_dword(dev, 0x74, &cfg);
if (cfg & ((1 << 2) | (1 << 15))) {
@@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
#endif /*CONFIG_MMC_RICOH_MMC*/
+#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
+#define VTUNCERRMSK_REG 0x1ac
+#define VTD_MSK_SPEC_ERRORS (1 << 31)
+/*
+ * This is a quirk for masking vt-d spec defined errors to platform error
+ * handling logic. With out this, platforms using Intel 7500, 5500 chipsets
+ * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based
+ * on the RAS config settings of the platform) when a vt-d fault happens.
+ * The resulting SMI caused the system to hang.
+ *
+ * VT-d spec related errors are already handled by the VT-d OS code, so no
+ * need to report the same error through other channels.
+ */
+static void vtd_mask_spec_errors(struct pci_dev *dev)
+{
+ u32 word;
+
+ pci_read_config_dword(dev, VTUNCERRMSK_REG, &word);
+ pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
+#endif
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index c80a7a6e7698..de886f3dfd39 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -215,7 +215,8 @@ config PCMCIA_PXA2XX
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|| ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
- || MACH_VPAC270 || MACH_BALLOON3)
+ || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
+ || MACH_COLIBRI320)
select PCMCIA_SOC_COMMON
help
Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 8d9386a22eb3..29935ea921df 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -50,8 +50,9 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
-sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
+sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
+sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
@@ -70,6 +71,8 @@ pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o
pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o
+pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o
+pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y)
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c
index dbbdd0063202..453c54c97612 100644
--- a/drivers/pcmcia/pxa2xx_balloon3.c
+++ b/drivers/pcmcia/pxa2xx_balloon3.c
@@ -39,12 +39,10 @@ static struct pcmcia_irqs irqs[] = {
static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
uint16_t ver;
- int ret;
- static void __iomem *fpga_ver;
ver = __raw_readw(BALLOON3_FPGA_VER);
- if (ver > 0x0201)
- pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. "
+ if (ver < 0x4f08)
+ pr_warn("The FPGA code, version 0x%04x, is too old. "
"PCMCIA/CF support might be broken in this version!",
ver);
@@ -97,8 +95,9 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
- __raw_writew((state->flags & SS_RESET) ? BALLOON3_CF_RESET : 0,
- BALLOON3_CF_CONTROL_REG);
+ __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG |
+ ((state->flags & SS_RESET) ?
+ BALLOON3_FPGA_SETnCLR : 0));
return 0;
}
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index ae07b4db8a6e..3755e7c8c715 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <mach/hardware.h>
+#include <mach/smemc.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -116,37 +117,49 @@ static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz,
static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock )
{
- MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+ uint32_t val;
+
+ val = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+ __raw_writel(val, MCMEM(sock));
+
return 0;
}
static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock )
{
- MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+ uint32_t val;
+
+ val = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+ __raw_writel(val, MCIO(sock));
+
return 0;
}
static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
{
- MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock)
+ uint32_t val;
+
+ val = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
+ __raw_writel(val, MCATT(sock));
+
return 0;
}
@@ -166,8 +179,8 @@ static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int cl
static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
- unsigned int clk = get_memclk_frequency_10khz();
- return pxa2xx_pcmcia_set_mcxx(skt, clk);
+ unsigned long clk = clk_get_rate(skt->clk);
+ return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000);
}
#ifdef CONFIG_CPU_FREQ
@@ -205,19 +218,18 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
static void pxa2xx_configure_sockets(struct device *dev)
{
struct pcmcia_low_level *ops = dev->platform_data;
-
/*
* We have at least one socket, so set MECR:CIT
* (Card Is There)
*/
- MECR |= MECR_CIT;
+ uint32_t mecr = MECR_CIT;
/* Set MECR:NOS (Number Of Sockets) */
if ((ops->first + ops->nr) > 1 ||
machine_is_viper() || machine_is_arcom_zeus())
- MECR |= MECR_NOS;
- else
- MECR &= ~MECR_NOS;
+ mecr |= MECR_NOS;
+
+ __raw_writel(mecr, MECR);
}
static const char *skt_names[] = {
@@ -270,24 +282,41 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
struct pcmcia_low_level *ops;
struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
+ struct clk *clk;
ops = (struct pcmcia_low_level *)dev->dev.platform_data;
- if (!ops)
+ if (!ops) {
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ if (cpu_is_pxa320() && ops->nr > 1) {
+ dev_err(&dev->dev, "pxa320 supports only one pcmcia slot");
+ ret = -EINVAL;
+ goto err0;
+ }
+
+ clk = clk_get(&dev->dev, NULL);
+ if (!clk)
return -ENODEV;
pxa2xx_drv_pcmcia_ops(ops);
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
- if (!sinfo)
+ if (!sinfo) {
+ clk_put(clk);
return -ENOMEM;
+ }
sinfo->nskt = ops->nr;
+ sinfo->clk = clk;
/* Initialize processor specific parameters */
for (i = 0; i < ops->nr; i++) {
skt = &sinfo->skt[i];
skt->nr = ops->first + i;
+ skt->clk = clk;
skt->ops = ops;
skt->socket.owner = ops->owner;
skt->socket.dev.parent = &dev->dev;
@@ -295,18 +324,26 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
ret = pxa2xx_drv_pcmcia_add_one(skt);
if (ret)
- break;
+ goto err1;
}
if (ret) {
while (--i >= 0)
soc_pcmcia_remove_one(&sinfo->skt[i]);
kfree(sinfo);
+ clk_put(clk);
} else {
pxa2xx_configure_sockets(&dev->dev);
dev_set_drvdata(&dev->dev, sinfo);
}
+ return 0;
+
+err1:
+ while (--i >= 0)
+ soc_pcmcia_remove_one(&sinfo->skt[i]);
+ kfree(sinfo);
+err0:
return ret;
}
@@ -320,6 +357,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
for (i = 0; i < sinfo->nskt; i++)
soc_pcmcia_remove_one(&sinfo->skt[i]);
+ clk_put(sinfo->clk);
kfree(sinfo);
return 0;
}
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
new file mode 100644
index 000000000000..c3f72192af66
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -0,0 +1,229 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_colibri.c
+ *
+ * Driver for Toradex Colibri PXA270 CF socket
+ *
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include "soc_common.h"
+
+#define COLIBRI270_RESET_GPIO 53
+#define COLIBRI270_PPEN_GPIO 107
+#define COLIBRI270_BVD1_GPIO 83
+#define COLIBRI270_BVD2_GPIO 82
+#define COLIBRI270_DETECT_GPIO 84
+#define COLIBRI270_READY_GPIO 1
+
+#define COLIBRI320_RESET_GPIO 77
+#define COLIBRI320_PPEN_GPIO 57
+#define COLIBRI320_BVD1_GPIO 53
+#define COLIBRI320_BVD2_GPIO 79
+#define COLIBRI320_DETECT_GPIO 81
+#define COLIBRI320_READY_GPIO 29
+
+static struct {
+ int reset_gpio;
+ int ppen_gpio;
+ int bvd1_gpio;
+ int bvd2_gpio;
+ int detect_gpio;
+ int ready_gpio;
+} colibri_pcmcia_gpio;
+
+static struct pcmcia_irqs colibri_irqs[] = {
+ {
+ .sock = 0,
+ .str = "PCMCIA CD"
+ },
+};
+
+static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ int ret;
+
+ ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio);
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio);
+ if (ret)
+ goto err3;
+
+ ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1");
+ if (ret)
+ goto err3;
+ ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio);
+ if (ret)
+ goto err4;
+
+ ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2");
+ if (ret)
+ goto err4;
+ ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio);
+ if (ret)
+ goto err5;
+
+ ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN");
+ if (ret)
+ goto err5;
+ ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0);
+ if (ret)
+ goto err6;
+
+ ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET");
+ if (ret)
+ goto err6;
+ ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1);
+ if (ret)
+ goto err7;
+
+ colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio);
+ skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio);
+
+ return soc_pcmcia_request_irqs(skt, colibri_irqs,
+ ARRAY_SIZE(colibri_irqs));
+
+err7:
+ gpio_free(colibri_pcmcia_gpio.detect_gpio);
+err6:
+ gpio_free(colibri_pcmcia_gpio.ready_gpio);
+err5:
+ gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
+err4:
+ gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
+err3:
+ gpio_free(colibri_pcmcia_gpio.reset_gpio);
+err2:
+ gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+err1:
+ return ret;
+}
+
+static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ gpio_free(colibri_pcmcia_gpio.detect_gpio);
+ gpio_free(colibri_pcmcia_gpio.ready_gpio);
+ gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
+ gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
+ gpio_free(colibri_pcmcia_gpio.reset_gpio);
+ gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+}
+
+static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+
+ state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio);
+ state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio);
+ state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio);
+ state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio);
+ state->wrprot = 0;
+ state->vs_3v = 1;
+ state->vs_Xv = 0;
+}
+
+static int
+colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ gpio_set_value(colibri_pcmcia_gpio.ppen_gpio,
+ !(state->Vcc == 33 && state->Vpp < 50));
+ gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET);
+ return 0;
+}
+
+static void colibri_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void colibri_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level colibri_pcmcia_ops = {
+ .owner = THIS_MODULE,
+
+ .first = 0,
+ .nr = 1,
+
+ .hw_init = colibri_pcmcia_hw_init,
+ .hw_shutdown = colibri_pcmcia_hw_shutdown,
+
+ .socket_state = colibri_pcmcia_socket_state,
+ .configure_socket = colibri_pcmcia_configure_socket,
+
+ .socket_init = colibri_pcmcia_socket_init,
+ .socket_suspend = colibri_pcmcia_socket_suspend,
+};
+
+static struct platform_device *colibri_pcmcia_device;
+
+static int __init colibri_pcmcia_init(void)
+{
+ int ret;
+
+ colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+ if (!colibri_pcmcia_device)
+ return -ENOMEM;
+
+ /* Colibri PXA270 */
+ if (machine_is_colibri()) {
+ colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO;
+ colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO;
+ colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO;
+ colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO;
+ colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO;
+ colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO;
+ /* Colibri PXA320 */
+ } else if (machine_is_colibri320()) {
+ colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO;
+ colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO;
+ colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO;
+ colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO;
+ colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO;
+ colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO;
+ }
+
+ ret = platform_device_add_data(colibri_pcmcia_device,
+ &colibri_pcmcia_ops, sizeof(colibri_pcmcia_ops));
+
+ if (!ret)
+ ret = platform_device_add(colibri_pcmcia_device);
+
+ if (ret)
+ platform_device_put(colibri_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit colibri_pcmcia_exit(void)
+{
+ platform_device_unregister(colibri_pcmcia_device);
+}
+
+module_init(colibri_pcmcia_init);
+module_exit(colibri_pcmcia_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270/PXA320");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 6b228590b3fd..fb9740d3e9a7 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -53,6 +53,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
pcmcia_h3600_init,
#endif
+#ifdef CONFIG_SA1100_NANOENGINE
+ pcmcia_nanoengine_init,
+#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_init,
#endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index 794f96a35bba..adb08dbc723f 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -13,6 +13,7 @@ extern int pcmcia_freebird_init(struct device *);
extern int pcmcia_gcplus_init(struct device *);
extern int pcmcia_graphicsmaster_init(struct device *);
extern int pcmcia_h3600_init(struct device *);
+extern int pcmcia_nanoengine_init(struct device *);
extern int pcmcia_pangolin_init(struct device *);
extern int pcmcia_pfs168_init(struct device *);
extern int pcmcia_shannon_init(struct device *);
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
new file mode 100644
index 000000000000..3d2652e2f5ae
--- /dev/null
+++ b/drivers/pcmcia/sa1100_nanoengine.c
@@ -0,0 +1,219 @@
+/*
+ * drivers/pcmcia/sa1100_nanoengine.c
+ *
+ * PCMCIA implementation routines for BSI nanoEngine.
+ *
+ * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine
+ * board you should carefully read this:
+ * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * Based on original work for kernel 2.4 by
+ * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+
+#include "sa1100_generic.h"
+
+static struct pcmcia_irqs irqs_skt0[] = {
+ /* socket, IRQ, name */
+ { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
+};
+
+static struct pcmcia_irqs irqs_skt1[] = {
+ /* socket, IRQ, name */
+ { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
+};
+
+struct nanoengine_pins {
+ unsigned input_pins;
+ unsigned output_pins;
+ unsigned clear_outputs;
+ unsigned transition_pins;
+ unsigned pci_irq;
+ struct pcmcia_irqs *pcmcia_irqs;
+ unsigned pcmcia_irqs_size;
+};
+
+static struct nanoengine_pins nano_skts[] = {
+ {
+ .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0,
+ .output_pins = GPIO_PC_RESET0,
+ .clear_outputs = GPIO_PC_RESET0,
+ .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0,
+ .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0,
+ .pcmcia_irqs = irqs_skt0,
+ .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0)
+ }, {
+ .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1,
+ .output_pins = GPIO_PC_RESET1,
+ .clear_outputs = GPIO_PC_RESET1,
+ .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1,
+ .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1,
+ .pcmcia_irqs = irqs_skt1,
+ .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1)
+ }
+};
+
+unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
+
+static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return -ENXIO;
+
+ GPDR &= ~nano_skts[i].input_pins;
+ GPDR |= nano_skts[i].output_pins;
+ GPCR = nano_skts[i].clear_outputs;
+ set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
+ skt->socket.pci_irq = nano_skts[i].pci_irq;
+
+ return soc_pcmcia_request_irqs(skt,
+ nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+/*
+ * Release all resources.
+ */
+static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return;
+
+ soc_pcmcia_free_irqs(skt,
+ nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+static int nanoengine_pcmcia_configure_socket(
+ struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+ unsigned reset;
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return -ENXIO;
+
+ switch (i) {
+ case 0:
+ reset = GPIO_PC_RESET0;
+ break;
+ case 1:
+ reset = GPIO_PC_RESET1;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ if (state->flags & SS_RESET)
+ GPSR = reset;
+ else
+ GPCR = reset;
+
+ return 0;
+}
+
+static void nanoengine_pcmcia_socket_state(
+ struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
+{
+ unsigned long levels = GPLR;
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return;
+
+ memset(state, 0, sizeof(struct pcmcia_state));
+ switch (i) {
+ case 0:
+ state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
+ state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
+ break;
+ case 1:
+ state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
+ state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
+ break;
+ default:
+ return;
+ }
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->wrprot = 0; /* Not available */
+ state->vs_3v = 1; /* Can only apply 3.3V */
+ state->vs_Xv = 0;
+}
+
+/*
+ * Enable card status IRQs on (re-)initialisation. This can
+ * be called at initialisation, power management event, or
+ * pcmcia event.
+ */
+static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return;
+
+ soc_pcmcia_enable_irqs(skt,
+ nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+/*
+ * Disable card status IRQs on suspend.
+ */
+static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+ unsigned i = skt->nr;
+
+ if (i >= num_nano_pcmcia_sockets)
+ return;
+
+ soc_pcmcia_disable_irqs(skt,
+ nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+static struct pcmcia_low_level nanoengine_pcmcia_ops = {
+ .owner = THIS_MODULE,
+
+ .hw_init = nanoengine_pcmcia_hw_init,
+ .hw_shutdown = nanoengine_pcmcia_hw_shutdown,
+
+ .configure_socket = nanoengine_pcmcia_configure_socket,
+ .socket_state = nanoengine_pcmcia_socket_state,
+ .socket_init = nanoengine_pcmcia_socket_init,
+ .socket_suspend = nanoengine_pcmcia_socket_suspend,
+};
+
+int pcmcia_nanoengine_init(struct device *dev)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_nanoengine())
+ ret = sa11xx_drv_pcmcia_probe(
+ dev, &nanoengine_pcmcia_ops, 0, 2);
+
+ return ret;
+}
+
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 3753fd0722e7..5a9a392eacdf 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -31,20 +31,20 @@
======================================================================*/
-#include <linux/module.h>
-#include <linux/moduleparam.h>
+#include <linux/cpufreq.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
-#include <linux/timer.h>
#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/mutex.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/spinlock.h>
-#include <linux/cpufreq.h>
+#include <linux/timer.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/system.h>
#include "soc_common.h"
@@ -70,10 +70,12 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
va_end(args);
}
}
+EXPORT_SYMBOL(soc_pcmcia_debug);
#endif
-#define to_soc_pcmcia_socket(x) container_of(x, struct soc_pcmcia_socket, socket)
+#define to_soc_pcmcia_socket(x) \
+ container_of(x, struct soc_pcmcia_socket, socket)
static unsigned short
calc_speed(unsigned short *spds, int num, unsigned short dflt)
@@ -90,11 +92,15 @@ calc_speed(unsigned short *spds, int num, unsigned short dflt)
return speed;
}
-void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing)
+void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
+ struct soc_pcmcia_timing *timing)
{
- timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
- timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
- timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
+ timing->io =
+ calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
+ timing->mem =
+ calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
+ timing->attr =
+ calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
}
EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
@@ -136,8 +142,8 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
*
* Convert PCMCIA socket state to our socket configure structure.
*/
-static int
-soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state)
+static int soc_common_pcmcia_config_skt(
+ struct soc_pcmcia_socket *skt, socket_state_t *state)
{
int ret;
@@ -149,7 +155,8 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
*/
if (skt->irq_state != 1 && state->io_irq) {
skt->irq_state = 1;
- set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
+ set_irq_type(skt->socket.pci_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else if (skt->irq_state == 1 && state->io_irq == 0) {
skt->irq_state = 0;
set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
@@ -303,24 +310,24 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
* of power configuration, reset, &c. We also record the value of
* `state' in order to regurgitate it to the PCMCIA core later.
*/
-static int
-soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+static int soc_common_pcmcia_set_socket(
+ struct pcmcia_socket *sock, socket_state_t *state)
{
struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
- debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n",
- (state->csc_mask==0)?"<NONE> ":"",
- (state->csc_mask&SS_DETECT)?"DETECT ":"",
- (state->csc_mask&SS_READY)?"READY ":"",
- (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
- (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
- (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
- (state->flags==0)?"<NONE> ":"",
- (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
- (state->flags&SS_IOCARD)?"IOCARD ":"",
- (state->flags&SS_RESET)?"RESET ":"",
- (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
- (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+ debug(skt, 2, "mask: %s%s%s%s%s%s flags: %s%s%s%s%s%s Vcc %d Vpp %d irq %d\n",
+ (state->csc_mask == 0) ? "<NONE> " : "",
+ (state->csc_mask & SS_DETECT) ? "DETECT " : "",
+ (state->csc_mask & SS_READY) ? "READY " : "",
+ (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
+ (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
+ (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
+ (state->flags == 0) ? "<NONE> " : "",
+ (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
+ (state->flags & SS_IOCARD) ? "IOCARD " : "",
+ (state->flags & SS_RESET) ? "RESET " : "",
+ (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
+ (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
state->Vcc, state->Vpp, state->io_irq);
return soc_common_pcmcia_config_skt(skt, state);
@@ -335,8 +342,8 @@ soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
*
* Returns: 0 on success, -1 on error
*/
-static int
-soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
+static int soc_common_pcmcia_set_io_map(
+ struct pcmcia_socket *sock, struct pccard_io_map *map)
{
struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
unsigned short speed = map->speed;
@@ -345,14 +352,14 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
map->map, map->speed, (unsigned long long)map->start,
(unsigned long long)map->stop);
debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
- (map->flags==0)?"<NONE>":"",
- (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
- (map->flags&MAP_16BIT)?"16BIT ":"",
- (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
- (map->flags&MAP_0WS)?"0WS ":"",
- (map->flags&MAP_WRPROT)?"WRPROT ":"",
- (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
- (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
+ (map->flags == 0) ? "<NONE>" : "",
+ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
+ (map->flags & MAP_16BIT) ? "16BIT " : "",
+ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
+ (map->flags & MAP_0WS) ? "0WS " : "",
+ (map->flags & MAP_WRPROT) ? "WRPROT " : "",
+ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
+ (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
if (map->map >= MAX_IO_WIN) {
printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
@@ -389,8 +396,8 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
*
* Returns: 0 on success, -ERRNO on error
*/
-static int
-soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
+static int soc_common_pcmcia_set_mem_map(
+ struct pcmcia_socket *sock, struct pccard_mem_map *map)
{
struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
struct resource *res;
@@ -399,14 +406,14 @@ soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
debug(skt, 2, "map %u speed %u card_start %08x\n",
map->map, map->speed, map->card_start);
debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
- (map->flags==0)?"<NONE>":"",
- (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
- (map->flags&MAP_16BIT)?"16BIT ":"",
- (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
- (map->flags&MAP_0WS)?"0WS ":"",
- (map->flags&MAP_WRPROT)?"WRPROT ":"",
- (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
- (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
+ (map->flags == 0) ? "<NONE>" : "",
+ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
+ (map->flags & MAP_16BIT) ? "16BIT " : "",
+ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
+ (map->flags & MAP_0WS) ? "0WS " : "",
+ (map->flags & MAP_WRPROT) ? "WRPROT " : "",
+ (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
+ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
if (map->map >= MAX_WIN)
return -EINVAL;
@@ -461,8 +468,8 @@ static struct bittbl conf_bits[] = {
{ SS_OUTPUT_ENA, "SS_OUTPUT_ENA" },
};
-static void
-dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz)
+static void dump_bits(char **p, const char *prefix,
+ unsigned int val, struct bittbl *bits, int sz)
{
char *b = *p;
int i;
@@ -480,13 +487,14 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
*
* Returns: the number of characters added to the buffer
*/
-static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_status(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
struct soc_pcmcia_socket *skt =
container_of(dev, struct soc_pcmcia_socket, socket.dev);
char *p = buf;
- p+=sprintf(p, "slot : %d\n", skt->nr);
+ p += sprintf(p, "slot : %d\n", skt->nr);
dump_bits(&p, "status", skt->status,
status_bits, ARRAY_SIZE(status_bits));
@@ -495,12 +503,12 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch
dump_bits(&p, "cs_flags", skt->cs_state.flags,
conf_bits, ARRAY_SIZE(conf_bits));
- p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
- p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
- p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq,
+ p += sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
+ p += sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
+ p += sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq,
skt->socket.pci_irq);
if (skt->ops->show_timing)
- p+=skt->ops->show_timing(skt, p);
+ p += skt->ops->show_timing(skt, p);
return p-buf;
}
@@ -593,7 +601,7 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
mutex_lock(&soc_pcmcia_sockets_lock);
list_for_each_entry(skt, &soc_pcmcia_sockets, node)
- if ( skt->ops->frequency_change )
+ if (skt->ops->frequency_change)
ret += skt->ops->frequency_change(skt, val, freqs);
mutex_unlock(&soc_pcmcia_sockets_lock);
@@ -619,7 +627,8 @@ fs_initcall(soc_pcmcia_cpufreq_register);
static void soc_pcmcia_cpufreq_unregister(void)
{
- cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+ cpufreq_unregister_notifier(&soc_pcmcia_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
}
module_exit(soc_pcmcia_cpufreq_unregister);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index bbcd5385a221..9daa73615c8b 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -10,6 +10,7 @@
#define _ASM_ARCH_PCMCIA
/* include the world */
+#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
@@ -29,6 +30,7 @@ struct soc_pcmcia_socket {
* Info from low level handler
*/
unsigned int nr;
+ struct clk *clk;
/*
* Core PCMCIA state
@@ -56,6 +58,7 @@ struct soc_pcmcia_socket {
struct skt_dev_info {
int nskt;
+ struct clk *clk;
struct soc_pcmcia_socket skt[0];
};
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 60a5a5c6b50a..d235f44fd7a3 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -81,6 +81,8 @@ MODULE_PARM_DESC(wapf, "WAPF value");
static int wlan_status = 1;
static int bluetooth_status = 1;
+static int wimax_status = -1;
+static int wwan_status = -1;
module_param(wlan_status, int, 0444);
MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
@@ -92,6 +94,16 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
"(0 = disabled, 1 = enabled, -1 = don't do anything). "
"default is 1");
+module_param(wimax_status, int, 0444);
+MODULE_PARM_DESC(wimax_status, "Set the wireless status on boot "
+ "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+ "default is 1");
+
+module_param(wwan_status, int, 0444);
+MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
+ "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+ "default is 1");
+
/*
* Some events we use, same for all Asus
*/
@@ -114,6 +126,8 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
*/
#define WL_RSTS 0x01 /* internal Wifi */
#define BT_RSTS 0x02 /* internal Bluetooth */
+#define WM_RSTS 0x08 /* internal wimax */
+#define WW_RSTS 0x20 /* internal wwan */
/* LED */
#define METHOD_MLED "MLED"
@@ -132,6 +146,11 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
*/
#define METHOD_WLAN "WLED"
#define METHOD_BLUETOOTH "BLED"
+
+/* WWAN and WIMAX */
+#define METHOD_WWAN "GSMC"
+#define METHOD_WIMAX "WMXC"
+
#define METHOD_WL_STATUS "RSTS"
/* Brightness */
@@ -883,6 +902,64 @@ static ssize_t store_bluetooth(struct device *dev,
}
/*
+ * Wimax
+ */
+static int asus_wimax_set(struct asus_laptop *asus, int status)
+{
+ if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) {
+ pr_warning("Error setting wimax status to %d", status);
+ return -EIO;
+ }
+ return 0;
+}
+
+static ssize_t show_wimax(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_laptop *asus = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS));
+}
+
+static ssize_t store_wimax(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct asus_laptop *asus = dev_get_drvdata(dev);
+
+ return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX);
+}
+
+/*
+ * Wwan
+ */
+static int asus_wwan_set(struct asus_laptop *asus, int status)
+{
+ if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) {
+ pr_warning("Error setting wwan status to %d", status);
+ return -EIO;
+ }
+ return 0;
+}
+
+static ssize_t show_wwan(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_laptop *asus = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS));
+}
+
+static ssize_t store_wwan(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct asus_laptop *asus = dev_get_drvdata(dev);
+
+ return sysfs_acpi_set(asus, buf, count, METHOD_WWAN);
+}
+
+/*
* Display
*/
static void asus_set_display(struct asus_laptop *asus, int value)
@@ -1202,6 +1279,8 @@ static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL);
static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan);
static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
show_bluetooth, store_bluetooth);
+static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
+static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
@@ -1212,6 +1291,8 @@ static struct attribute *asus_attributes[] = {
&dev_attr_infos.attr,
&dev_attr_wlan.attr,
&dev_attr_bluetooth.attr,
+ &dev_attr_wimax.attr,
+ &dev_attr_wwan.attr,
&dev_attr_display.attr,
&dev_attr_ledd.attr,
&dev_attr_ls_level.attr,
@@ -1239,6 +1320,13 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
} else if (attr == &dev_attr_display.attr) {
supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL);
+ } else if (attr == &dev_attr_wimax.attr) {
+ supported =
+ !acpi_check_handle(asus->handle, METHOD_WIMAX, NULL);
+
+ } else if (attr == &dev_attr_wwan.attr) {
+ supported = !acpi_check_handle(asus->handle, METHOD_WWAN, NULL);
+
} else if (attr == &dev_attr_ledd.attr) {
supported = !acpi_check_handle(handle, METHOD_LEDD, NULL);
@@ -1397,7 +1485,8 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
/*
* The HWRS method return informations about the hardware.
- * 0x80 bit is for WLAN, 0x100 for Bluetooth.
+ * 0x80 bit is for WLAN, 0x100 for Bluetooth,
+ * 0x40 for WWAN, 0x10 for WIMAX.
* The significance of others is yet to be found.
*/
status =
@@ -1440,6 +1529,12 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
if (wlan_status >= 0)
asus_wlan_set(asus, !!wlan_status);
+ if (wimax_status >= 0)
+ asus_wimax_set(asus, !!wimax_status);
+
+ if (wwan_status >= 0)
+ asus_wwan_set(asus, !!wwan_status);
+
/* Keyboard Backlight is on by default */
if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL))
asus_kled_set(asus, 1);
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 462ceab93f87..0d50fbbe2478 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -298,8 +298,8 @@ static void eeepc_wmi_notify(u32 value, void *context)
kfree(obj);
}
-static int store_cpufv(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int value;
struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index f44cd2620ff9..cf6c47250c56 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -689,7 +689,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
if (error)
goto err_free_input_dev;
- result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+ result = acpi_bus_update_power(fujitsu->acpi_handle, &state);
if (result) {
printk(KERN_ERR "Error reading power state\n");
goto err_unregister_input_dev;
@@ -857,7 +857,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
if (error)
goto err_free_input_dev;
- result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state);
+ result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state);
if (result) {
printk(KERN_ERR "Error reading power state\n");
goto err_unregister_input_dev;
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 1dac659b5e0c..9e05af9c41cb 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -172,6 +172,8 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
bios_return = *((struct bios_return *)obj->buffer.pointer);
memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
+
+ kfree(obj);
return 0;
}
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c
index 3c2c6b91ecb3..94a114aa8e28 100644
--- a/drivers/platform/x86/ibm_rtl.c
+++ b/drivers/platform/x86/ibm_rtl.c
@@ -28,6 +28,7 @@
#include <linux/io.h>
#include <linux/sysdev.h>
#include <linux/dmi.h>
+#include <linux/efi.h>
#include <linux/mutex.h>
#include <asm/bios_ebda.h>
@@ -220,32 +221,13 @@ static void rtl_teardown_sysfs(void) {
sysdev_class_unregister(&class_rtl);
}
-static int dmi_check_cb(const struct dmi_system_id *id)
-{
- RTL_DEBUG("found IBM server '%s'\n", id->ident);
- return 0;
-}
-
-#define ibm_dmi_entry(NAME, TYPE) \
-{ \
- .ident = NAME, \
- .matches = { \
- DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \
- DMI_MATCH(DMI_PRODUCT_NAME, TYPE), \
- }, \
- .callback = dmi_check_cb \
-}
static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = {
- ibm_dmi_entry("BladeCenter LS21", "7971"),
- ibm_dmi_entry("BladeCenter LS22", "7901"),
- ibm_dmi_entry("BladeCenter HS21 XM", "7995"),
- ibm_dmi_entry("BladeCenter HS22", "7870"),
- ibm_dmi_entry("BladeCenter HS22V", "7871"),
- ibm_dmi_entry("System x3550 M2", "7946"),
- ibm_dmi_entry("System x3650 M2", "7947"),
- ibm_dmi_entry("System x3550 M3", "7944"),
- ibm_dmi_entry("System x3650 M3", "7945"),
+ { \
+ .matches = { \
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \
+ }, \
+ },
{ }
};
@@ -257,7 +239,7 @@ static int __init ibm_rtl_init(void) {
if (force)
pr_warning("ibm-rtl: module loaded by force\n");
/* first ensure that we are running on IBM HW */
- else if (!dmi_check_system(ibm_rtl_dmi_table))
+ else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
return -ENODEV;
/* Get the address for the Extended BIOS Data Area */
@@ -302,7 +284,7 @@ static int __init ibm_rtl_init(void) {
RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
rtl_cmd_width, rtl_cmd_type);
addr = ioread32(&rtl_table->cmd_port_address);
- RTL_DEBUG("addr = %#llx\n", addr);
+ RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
plen = rtl_cmd_width/sizeof(char);
rtl_cmd_addr = rtl_port_map(addr, plen);
RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr);
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index c44a5e8b8b82..f0b3ad13c273 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -75,6 +75,7 @@
#include <drm/i915_drm.h>
#include <asm/msr.h>
#include <asm/processor.h>
+#include "intel_ips.h"
#define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
@@ -245,6 +246,7 @@
#define thm_writel(off, val) writel((val), ips->regmap + (off))
static const int IPS_ADJUST_PERIOD = 5000; /* ms */
+static bool late_i915_load = false;
/* For initial average collection */
static const int IPS_SAMPLE_PERIOD = 200; /* ms */
@@ -339,6 +341,9 @@ struct ips_driver {
u64 orig_turbo_ratios;
};
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips);
+
/**
* ips_cpu_busy - is CPU busy?
* @ips: IPS driver struct
@@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips)
*/
static bool ips_gpu_busy(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return false;
return ips->gpu_busy();
@@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips)
*/
static void ips_gpu_raise(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return;
if (!ips->gpu_raise())
@@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips)
*/
static void ips_gpu_lower(struct ips_driver *ips)
{
- if (!ips->gpu_turbo_enabled)
+ if (!ips_gpu_turbo_enabled(ips))
return;
if (!ips->gpu_lower())
@@ -1454,6 +1459,31 @@ out_err:
return false;
}
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips)
+{
+ if (!ips->gpu_busy && late_i915_load) {
+ if (ips_get_i915_syms(ips)) {
+ dev_info(&ips->dev->dev,
+ "i915 driver attached, reenabling gpu turbo\n");
+ ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS);
+ }
+ }
+
+ return ips->gpu_turbo_enabled;
+}
+
+void
+ips_link_to_i915_driver()
+{
+ /* We can't cleanly get at the various ips_driver structs from
+ * this caller (the i915 driver), so just set a flag saying
+ * that it's time to try getting the symbols again.
+ */
+ late_i915_load = true;
+}
+EXPORT_SYMBOL_GPL(ips_link_to_i915_driver);
+
static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), },
diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h
new file mode 100644
index 000000000000..73299beff5b3
--- /dev/null
+++ b/drivers/platform/x86/intel_ips.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+void ips_link_to_i915_driver(void);
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
index 42a5469a2459..35278ad7e628 100644
--- a/drivers/platform/x86/msi-wmi.c
+++ b/drivers/platform/x86/msi-wmi.c
@@ -43,16 +43,18 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
#define dprintk(msg...) pr_debug(DRV_PFX msg)
-#define KEYCODE_BASE 0xD0
-#define MSI_WMI_BRIGHTNESSUP KEYCODE_BASE
-#define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1)
-#define MSI_WMI_VOLUMEUP (KEYCODE_BASE + 2)
-#define MSI_WMI_VOLUMEDOWN (KEYCODE_BASE + 3)
+#define SCANCODE_BASE 0xD0
+#define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE
+#define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1)
+#define MSI_WMI_VOLUMEUP (SCANCODE_BASE + 2)
+#define MSI_WMI_VOLUMEDOWN (SCANCODE_BASE + 3)
+#define MSI_WMI_MUTE (SCANCODE_BASE + 4)
static struct key_entry msi_wmi_keymap[] = {
{ KE_KEY, MSI_WMI_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} },
{ KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} },
{ KE_KEY, MSI_WMI_VOLUMEUP, {KEY_VOLUMEUP} },
{ KE_KEY, MSI_WMI_VOLUMEDOWN, {KEY_VOLUMEDOWN} },
+ { KE_KEY, MSI_WMI_MUTE, {KEY_MUTE} },
{ KE_END, 0}
};
static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1];
@@ -169,7 +171,7 @@ static void msi_wmi_notify(u32 value, void *context)
ktime_t diff;
cur = ktime_get_real();
diff = ktime_sub(cur, last_pressed[key->code -
- KEYCODE_BASE]);
+ SCANCODE_BASE]);
/* Ignore event if the same event happened in a 50 ms
timeframe -> Key press may result in 10-20 GPEs */
if (ktime_to_us(diff) < 1000 * 50) {
@@ -178,7 +180,7 @@ static void msi_wmi_notify(u32 value, void *context)
key->code, ktime_to_us(diff));
return;
}
- last_pressed[key->code - KEYCODE_BASE] = cur;
+ last_pressed[key->code - SCANCODE_BASE] = cur;
if (key->type == KE_KEY &&
/* Brightness is served via acpi video driver */
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 2d61186ad5a2..e8c21994b36d 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -8497,7 +8497,6 @@ static void ibm_exit(struct ibm_struct *ibm)
ibm->acpi->type,
dispatch_acpi_notify);
ibm->flags.acpi_notify_installed = 0;
- ibm->flags.acpi_notify_installed = 0;
}
if (ibm->flags.proc_created) {
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 06f304f46e02..4276da7291b8 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -135,6 +135,7 @@ static const struct key_entry toshiba_acpi_keymap[] __initconst = {
{ KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
{ KE_KEY, 0x142, { KEY_WLAN } },
{ KE_KEY, 0x143, { KEY_PROG1 } },
+ { KE_KEY, 0x17f, { KEY_FN } },
{ KE_KEY, 0xb05, { KEY_PROG2 } },
{ KE_KEY, 0xb06, { KEY_WWW } },
{ KE_KEY, 0xb07, { KEY_MAIL } },
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 104b77c87ef5..aecd9a9b549f 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -755,7 +755,7 @@ static bool guid_already_parsed(const char *guid_string)
struct wmi_block *wblock;
list_for_each_entry(wblock, &wmi_block_list, list)
- if (strncmp(wblock->gblock.guid, guid_string, 16) == 0)
+ if (memcmp(wblock->gblock.guid, guid_string, 16) == 0)
return true;
return false;
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile
index 8de3775ec242..bfba893cb321 100644
--- a/drivers/pnp/Makefile
+++ b/drivers/pnp/Makefile
@@ -2,11 +2,13 @@
# Makefile for the Linux Plug-and-Play Support.
#
-obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o
+obj-y := pnp.o
+
+pnp-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o
obj-$(CONFIG_PNPACPI) += pnpacpi/
obj-$(CONFIG_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/
# pnp_system_init goes after pnpacpi/pnpbios init
-obj-y += system.o
+pnp-y += system.o
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 0f34d962fd3c..cb6ce42f8e77 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -220,10 +220,5 @@ subsys_initcall(pnp_init);
int pnp_debug;
#if defined(CONFIG_PNP_DEBUG_MESSAGES)
-static int __init pnp_debug_setup(char *__unused)
-{
- pnp_debug = 1;
- return 1;
-}
-__setup("pnp.debug", pnp_debug_setup);
+module_param_named(debug, pnp_debug, int, 0644);
#endif
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
index cac18bbfb817..6e607aa33aa3 100644
--- a/drivers/pnp/isapnp/Makefile
+++ b/drivers/pnp/isapnp/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the kernel ISAPNP driver.
#
+obj-y += pnp.o
+pnp-y := core.o compat.o
-isapnp-proc-$(CONFIG_PROC_FS) = proc.o
-
-obj-y := core.o compat.o $(isapnp-proc-y)
+pnp-$(CONFIG_PROC_FS) += proc.o
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile
index 905326fcca85..40c93da18252 100644
--- a/drivers/pnp/pnpacpi/Makefile
+++ b/drivers/pnp/pnpacpi/Makefile
@@ -1,5 +1,6 @@
#
# Makefile for the kernel PNPACPI driver.
#
+obj-y += pnp.o
-obj-y := core.o rsparser.o
+pnp-y := core.o rsparser.o
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2d73dfcecdbb..57313f4658bc 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = {
};
EXPORT_SYMBOL(pnpacpi_protocol);
-static char *pnpacpi_get_id(struct acpi_device *device)
+static char *__init pnpacpi_get_id(struct acpi_device *device)
{
struct acpi_hardware_id *id;
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
index 3cd3ed760605..240b0ffb83ca 100644
--- a/drivers/pnp/pnpbios/Makefile
+++ b/drivers/pnp/pnpbios/Makefile
@@ -1,7 +1,8 @@
#
# Makefile for the kernel PNPBIOS driver.
#
+obj-y := pnp.o
-pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
+pnp-y := core.o bioscalls.o rsparser.o
-obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
+pnp-$(CONFIG_PNPBIOS_PROC_FS) += proc.o
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 60d83d983a36..32165295cb1b 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -185,4 +185,14 @@ config CHARGER_TWL4030
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
+config CHARGER_GPIO
+ tristate "GPIO charger"
+ depends on GPIOLIB
+ help
+ Say Y to include support for chargers which report their online status
+ through a GPIO pin.
+
+ This driver can be build as a module. If so, the module will be
+ called gpio-charger.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index c75772eb157c..545459f9f356 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
+obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c
index 039f41ae217d..548d263b1ad0 100644
--- a/drivers/power/collie_battery.c
+++ b/drivers/power/collie_battery.c
@@ -295,7 +295,7 @@ static struct {
static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state)
{
/* flush all pending status updates */
- flush_scheduled_work();
+ flush_work_sync(&bat_work);
return 0;
}
@@ -362,7 +362,7 @@ err_psy_reg_bu:
err_psy_reg_main:
/* see comment in collie_bat_remove */
- flush_scheduled_work();
+ cancel_work_sync(&bat_work);
i--;
err_gpio:
@@ -382,12 +382,11 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
power_supply_unregister(&collie_bat_main.psy);
/*
- * now flush all pending work.
- * we won't get any more schedules, since all
- * sources (isr and external_power_changed)
- * are unregistered now.
+ * Now cancel the bat_work. We won't get any more schedules,
+ * since all sources (isr and external_power_changed) are
+ * unregistered now.
*/
- flush_scheduled_work();
+ cancel_work_sync(&bat_work);
for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
gpio_free(gpios[i].gpio);
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index b3c01c16a164..11e1ac508e57 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -212,7 +212,7 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
if (di->rem_capacity > 100)
di->rem_capacity = 100;
- if (di->current_uA >= 100L)
+ if (di->current_uA < -100L)
di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L)
/ (di->current_uA / 100L);
else
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
new file mode 100644
index 000000000000..25b88ac1d44c
--- /dev/null
+++ b/drivers/power/gpio-charger.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * Driver for chargers which report their online status through a GPIO pin
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+
+#include <linux/power/gpio-charger.h>
+
+struct gpio_charger {
+ const struct gpio_charger_platform_data *pdata;
+ unsigned int irq;
+
+ struct power_supply charger;
+};
+
+static irqreturn_t gpio_charger_irq(int irq, void *devid)
+{
+ struct power_supply *charger = devid;
+
+ power_supply_changed(charger);
+
+ return IRQ_HANDLED;
+}
+
+static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
+{
+ return container_of(psy, struct gpio_charger, charger);
+}
+
+static int gpio_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp, union power_supply_propval *val)
+{
+ struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);
+ const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = gpio_get_value(pdata->gpio);
+ val->intval ^= pdata->gpio_active_low;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property gpio_charger_properties[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static int __devinit gpio_charger_probe(struct platform_device *pdev)
+{
+ const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
+ struct gpio_charger *gpio_charger;
+ struct power_supply *charger;
+ int ret;
+ int irq;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data\n");
+ return -EINVAL;
+ }
+
+ if (!gpio_is_valid(pdata->gpio)) {
+ dev_err(&pdev->dev, "Invalid gpio pin\n");
+ return -EINVAL;
+ }
+
+ gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL);
+ if (!gpio_charger) {
+ dev_err(&pdev->dev, "Failed to alloc driver structure\n");
+ return -ENOMEM;
+ }
+
+ charger = &gpio_charger->charger;
+
+ charger->name = pdata->name ? pdata->name : "gpio-charger";
+ charger->type = pdata->type;
+ charger->properties = gpio_charger_properties;
+ charger->num_properties = ARRAY_SIZE(gpio_charger_properties);
+ charger->get_property = gpio_charger_get_property;
+ charger->supplied_to = pdata->supplied_to;
+ charger->num_supplicants = pdata->num_supplicants;
+
+ ret = gpio_request(pdata->gpio, dev_name(&pdev->dev));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret);
+ goto err_free;
+ }
+ ret = gpio_direction_input(pdata->gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret);
+ goto err_gpio_free;
+ }
+
+ gpio_charger->pdata = pdata;
+
+ ret = power_supply_register(&pdev->dev, charger);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register power supply: %d\n",
+ ret);
+ goto err_gpio_free;
+ }
+
+ irq = gpio_to_irq(pdata->gpio);
+ if (irq > 0) {
+ ret = request_any_context_irq(irq, gpio_charger_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ dev_name(&pdev->dev), charger);
+ if (ret)
+ dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret);
+ else
+ gpio_charger->irq = irq;
+ }
+
+ platform_set_drvdata(pdev, gpio_charger);
+
+ return 0;
+
+err_gpio_free:
+ gpio_free(pdata->gpio);
+err_free:
+ kfree(gpio_charger);
+ return ret;
+}
+
+static int __devexit gpio_charger_remove(struct platform_device *pdev)
+{
+ struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
+
+ if (gpio_charger->irq)
+ free_irq(gpio_charger->irq, &gpio_charger->charger);
+
+ power_supply_unregister(&gpio_charger->charger);
+
+ gpio_free(gpio_charger->pdata->gpio);
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(gpio_charger);
+
+ return 0;
+}
+
+static struct platform_driver gpio_charger_driver = {
+ .probe = gpio_charger_probe,
+ .remove = __devexit_p(gpio_charger_remove),
+ .driver = {
+ .name = "gpio-charger",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init gpio_charger_init(void)
+{
+ return platform_driver_register(&gpio_charger_driver);
+}
+module_init(gpio_charger_init);
+
+static void __exit gpio_charger_exit(void)
+{
+ platform_driver_unregister(&gpio_charger_driver);
+}
+module_exit(gpio_charger_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio-charger");
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c
index 2a10cd361181..236147c3a5c6 100644
--- a/drivers/power/intel_mid_battery.c
+++ b/drivers/power/intel_mid_battery.c
@@ -767,7 +767,7 @@ static int __devexit platform_pmic_battery_remove(struct platform_device *pdev)
power_supply_unregister(&pbi->usb);
power_supply_unregister(&pbi->batt);
- flush_scheduled_work();
+ cancel_work_sync(&pbi->handler);
kfree(pbi);
return 0;
}
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 72512185f3e2..2ad9b14a5ce3 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -59,11 +59,61 @@ struct isp1704_charger {
struct notifier_block nb;
struct work_struct work;
- char model[7];
+ /* properties */
+ char model[8];
unsigned present:1;
+ unsigned online:1;
+ unsigned current_max;
+
+ /* temp storage variables */
+ unsigned long event;
+ unsigned max_power;
};
/*
+ * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB
+ * chargers).
+ *
+ * REVISIT: The method is defined in Battery Charging Specification and is
+ * applicable to any ULPI transceiver. Nothing isp170x specific here.
+ */
+static inline int isp1704_charger_type(struct isp1704_charger *isp)
+{
+ u8 reg;
+ u8 func_ctrl;
+ u8 otg_ctrl;
+ int type = POWER_SUPPLY_TYPE_USB_DCP;
+
+ func_ctrl = otg_io_read(isp->otg, ULPI_FUNC_CTRL);
+ otg_ctrl = otg_io_read(isp->otg, ULPI_OTG_CTRL);
+
+ /* disable pulldowns */
+ reg = ULPI_OTG_CTRL_DM_PULLDOWN | ULPI_OTG_CTRL_DP_PULLDOWN;
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), reg);
+
+ /* full speed */
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_XCVRSEL_MASK);
+ otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_FULL_SPEED);
+
+ /* Enable strong pull-up on DP (1.5K) and reset */
+ reg = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET;
+ otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), reg);
+ usleep_range(1000, 2000);
+
+ reg = otg_io_read(isp->otg, ULPI_DEBUG);
+ if ((reg & 3) != 3)
+ type = POWER_SUPPLY_TYPE_USB_CDP;
+
+ /* recover original state */
+ otg_io_write(isp->otg, ULPI_FUNC_CTRL, func_ctrl);
+ otg_io_write(isp->otg, ULPI_OTG_CTRL, otg_ctrl);
+
+ return type;
+}
+
+/*
* ISP1704 detects PS/2 adapters as charger. To make sure the detected charger
* is actually a dedicated charger, the following steps need to be taken.
*/
@@ -127,16 +177,19 @@ static inline int isp1704_charger_verify(struct isp1704_charger *isp)
static inline int isp1704_charger_detect(struct isp1704_charger *isp)
{
unsigned long timeout;
- u8 r;
+ u8 pwr_ctrl;
int ret = 0;
+ pwr_ctrl = otg_io_read(isp->otg, ISP1704_PWR_CTRL);
+
/* set SW control bit in PWR_CTRL register */
otg_io_write(isp->otg, ISP1704_PWR_CTRL,
ISP1704_PWR_CTRL_SWCTRL);
/* enable manual charger detection */
- r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN);
- otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r);
+ otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL),
+ ISP1704_PWR_CTRL_SWCTRL
+ | ISP1704_PWR_CTRL_DPVSRC_EN);
usleep_range(1000, 2000);
timeout = jiffies + msecs_to_jiffies(300);
@@ -147,7 +200,10 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp)
ret = isp1704_charger_verify(isp);
break;
}
- } while (!time_after(jiffies, timeout));
+ } while (!time_after(jiffies, timeout) && isp->online);
+
+ /* recover original state */
+ otg_io_write(isp->otg, ISP1704_PWR_CTRL, pwr_ctrl);
return ret;
}
@@ -155,52 +211,92 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp)
static void isp1704_charger_work(struct work_struct *data)
{
int detect;
+ unsigned long event;
+ unsigned power;
struct isp1704_charger *isp =
container_of(data, struct isp1704_charger, work);
+ static DEFINE_MUTEX(lock);
- /*
- * FIXME Only supporting dedicated chargers even though isp1704 can
- * detect HUB and HOST chargers. If the device has already been
- * enumerated, the detection will break the connection.
- */
- if (isp->otg->state != OTG_STATE_B_IDLE)
- return;
+ event = isp->event;
+ power = isp->max_power;
- /* disable data pullups */
- if (isp->otg->gadget)
- usb_gadget_disconnect(isp->otg->gadget);
+ mutex_lock(&lock);
+
+ switch (event) {
+ case USB_EVENT_VBUS:
+ isp->online = true;
+
+ /* detect charger */
+ detect = isp1704_charger_detect(isp);
+
+ if (detect) {
+ isp->present = detect;
+ isp->psy.type = isp1704_charger_type(isp);
+ }
- /* detect charger */
- detect = isp1704_charger_detect(isp);
- if (detect) {
- isp->present = detect;
- power_supply_changed(&isp->psy);
+ switch (isp->psy.type) {
+ case POWER_SUPPLY_TYPE_USB_DCP:
+ isp->current_max = 1800;
+ break;
+ case POWER_SUPPLY_TYPE_USB_CDP:
+ /*
+ * Only 500mA here or high speed chirp
+ * handshaking may break
+ */
+ isp->current_max = 500;
+ /* FALLTHROUGH */
+ case POWER_SUPPLY_TYPE_USB:
+ default:
+ /* enable data pullups */
+ if (isp->otg->gadget)
+ usb_gadget_connect(isp->otg->gadget);
+ }
+ break;
+ case USB_EVENT_NONE:
+ isp->online = false;
+ isp->current_max = 0;
+ isp->present = 0;
+ isp->current_max = 0;
+ isp->psy.type = POWER_SUPPLY_TYPE_USB;
+
+ /*
+ * Disable data pullups. We need to prevent the controller from
+ * enumerating.
+ *
+ * FIXME: This is here to allow charger detection with Host/HUB
+ * chargers. The pullups may be enabled elsewhere, so this can
+ * not be the final solution.
+ */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+ break;
+ case USB_EVENT_ENUMERATED:
+ if (isp->present)
+ isp->current_max = 1800;
+ else
+ isp->current_max = power;
+ break;
+ default:
+ goto out;
}
- /* enable data pullups */
- if (isp->otg->gadget)
- usb_gadget_connect(isp->otg->gadget);
+ power_supply_changed(&isp->psy);
+out:
+ mutex_unlock(&lock);
}
static int isp1704_notifier_call(struct notifier_block *nb,
- unsigned long event, void *unused)
+ unsigned long event, void *power)
{
struct isp1704_charger *isp =
container_of(nb, struct isp1704_charger, nb);
- switch (event) {
- case USB_EVENT_VBUS:
- schedule_work(&isp->work);
- break;
- case USB_EVENT_NONE:
- if (isp->present) {
- isp->present = 0;
- power_supply_changed(&isp->psy);
- }
- break;
- default:
- return NOTIFY_DONE;
- }
+ isp->event = event;
+
+ if (power)
+ isp->max_power = *((unsigned *)power);
+
+ schedule_work(&isp->work);
return NOTIFY_OK;
}
@@ -216,6 +312,12 @@ static int isp1704_charger_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_PRESENT:
val->intval = isp->present;
break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = isp->online;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = isp->current_max;
+ break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = isp->model;
break;
@@ -230,6 +332,8 @@ static int isp1704_charger_get_property(struct power_supply *psy,
static enum power_supply_property power_props[] = {
POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
};
@@ -287,13 +391,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
if (!isp->otg)
goto fail0;
+ isp->dev = &pdev->dev;
+ platform_set_drvdata(pdev, isp);
+
ret = isp1704_test_ulpi(isp);
if (ret < 0)
goto fail1;
- isp->dev = &pdev->dev;
- platform_set_drvdata(pdev, isp);
-
isp->psy.name = "isp1704";
isp->psy.type = POWER_SUPPLY_TYPE_USB;
isp->psy.properties = power_props;
@@ -318,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
dev_info(isp->dev, "registered with product id %s\n", isp->model);
+ /*
+ * Taking over the D+ pullup.
+ *
+ * FIXME: The device will be disconnected if it was already
+ * enumerated. The charger driver should be always loaded before any
+ * gadget is loaded.
+ */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+
+ /* Detect charger if VBUS is valid (the cable was already plugged). */
+ ret = otg_io_read(isp->otg, ULPI_USB_INT_STS);
+ if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) {
+ isp->event = USB_EVENT_VBUS;
+ schedule_work(&isp->work);
+ }
+
return 0;
fail2:
power_supply_unregister(&isp->psy);
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index a8108a73593e..02414db6a94c 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <linux/gpio.h>
@@ -47,6 +48,8 @@ struct jz_battery {
struct power_supply battery;
struct delayed_work work;
+
+ struct mutex lock;
};
static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy)
@@ -68,6 +71,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery)
unsigned long val;
long voltage;
+ mutex_lock(&battery->lock);
+
INIT_COMPLETION(battery->read_completion);
enable_irq(battery->irq);
@@ -91,6 +96,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery)
battery->cell->disable(battery->pdev);
disable_irq(battery->irq);
+ mutex_unlock(&battery->lock);
+
return voltage;
}
@@ -240,6 +247,11 @@ static int __devinit jz_battery_probe(struct platform_device *pdev)
struct jz_battery *jz_battery;
struct power_supply *battery;
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform_data supplied\n");
+ return -ENXIO;
+ }
+
jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL);
if (!jz_battery) {
dev_err(&pdev->dev, "Failed to allocate driver structure\n");
@@ -291,6 +303,7 @@ static int __devinit jz_battery_probe(struct platform_device *pdev)
jz_battery->pdev = pdev;
init_completion(&jz_battery->read_completion);
+ mutex_init(&jz_battery->lock);
INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work);
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 91606bb55318..970f7335d3a7 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -190,10 +190,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
goto success;
create_triggers_failed:
- device_unregister(psy->dev);
+ device_del(dev);
kobject_set_name_failed:
device_add_failed:
- kfree(dev);
+ put_device(dev);
success:
return rc;
}
@@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(power_supply_register);
void power_supply_unregister(struct power_supply *psy)
{
- flush_scheduled_work();
+ cancel_work_sync(&psy->changed_work);
power_supply_remove_triggers(psy);
device_unregister(psy->dev);
}
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c
index fe16b482e912..7bc5bfe55ce9 100644
--- a/drivers/power/s3c_adc_battery.c
+++ b/drivers/power/s3c_adc_battery.c
@@ -112,6 +112,13 @@ static int calc_full_volt(int volt_val, int cur_val, int impedance)
return volt_val + cur_val * impedance / 1000;
}
+static int charge_finished(struct s3c_adc_bat *bat)
+{
+ return bat->pdata->gpio_inverted ?
+ !gpio_get_value(bat->pdata->gpio_charge_finished) :
+ gpio_get_value(bat->pdata->gpio_charge_finished);
+}
+
static int s3c_adc_bat_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -140,7 +147,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy,
if (bat->cable_plugged &&
((bat->pdata->gpio_charge_finished < 0) ||
- !gpio_get_value(bat->pdata->gpio_charge_finished))) {
+ !charge_finished(bat))) {
lut = bat->pdata->lut_acin;
lut_size = bat->pdata->lut_acin_cnt;
}
@@ -236,8 +243,7 @@ static void s3c_adc_bat_work(struct work_struct *work)
}
} else {
if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) {
- is_charged = gpio_get_value(
- main_bat.pdata->gpio_charge_finished);
+ is_charged = charge_finished(&main_bat);
if (is_charged) {
if (bat->pdata->disable_charger)
bat->pdata->disable_charger();
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
index ee04936b2db5..53f0d3524fcd 100644
--- a/drivers/power/tosa_battery.c
+++ b/drivers/power/tosa_battery.c
@@ -332,7 +332,7 @@ static struct {
static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state)
{
/* flush all pending status updates */
- flush_scheduled_work();
+ flush_work_sync(&bat_work);
return 0;
}
@@ -422,7 +422,7 @@ err_psy_reg_jacket:
err_psy_reg_main:
/* see comment in tosa_bat_remove */
- flush_scheduled_work();
+ cancel_work_sync(&bat_work);
i--;
err_gpio:
@@ -445,12 +445,11 @@ static int __devexit tosa_bat_remove(struct platform_device *dev)
power_supply_unregister(&tosa_bat_main.psy);
/*
- * now flush all pending work.
- * we won't get any more schedules, since all
- * sources (isr and external_power_changed)
- * are unregistered now.
+ * Now cancel the bat_work. We won't get any more schedules,
+ * since all sources (isr and external_power_changed) are
+ * unregistered now.
*/
- flush_scheduled_work();
+ cancel_work_sync(&bat_work);
for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
gpio_free(gpios[i].gpio);
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index 5071d85ec12d..156559e56fa5 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -147,7 +147,7 @@ static irqreturn_t wm97xx_chrg_irq(int irq, void *data)
#ifdef CONFIG_PM
static int wm97xx_bat_suspend(struct device *dev)
{
- flush_scheduled_work();
+ flush_work_sync(&bat_work);
return 0;
}
@@ -273,7 +273,7 @@ static int __devexit wm97xx_bat_remove(struct platform_device *dev)
free_irq(gpio_to_irq(pdata->charge_gpio), dev);
gpio_free(pdata->charge_gpio);
}
- flush_scheduled_work();
+ cancel_work_sync(&bat_work);
power_supply_unregister(&bat_ps);
kfree(prop);
return 0;
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c
index 85064a9f649e..e5ed52d71937 100644
--- a/drivers/power/z2_battery.c
+++ b/drivers/power/z2_battery.c
@@ -254,7 +254,7 @@ static int __devexit z2_batt_remove(struct i2c_client *client)
struct z2_charger *charger = i2c_get_clientdata(client);
struct z2_battery_info *info = charger->info;
- flush_scheduled_work();
+ cancel_work_sync(&charger->bat_work);
power_supply_unregister(&charger->batt_ps);
kfree(charger->batt_ps.properties);
@@ -271,7 +271,9 @@ static int __devexit z2_batt_remove(struct i2c_client *client)
#ifdef CONFIG_PM
static int z2_batt_suspend(struct i2c_client *client, pm_message_t state)
{
- flush_scheduled_work();
+ struct z2_charger *charger = i2c_get_clientdata(client);
+
+ flush_work_sync(&charger->bat_work);
return 0;
}
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index ccea15c11c19..50cb1e1b4a12 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_PS3_VUART) += ps3-vuart.o
obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o
-ps3av_mod-objs += ps3av.o ps3av_cmd.o
+ps3av_mod-y := ps3av.o ps3av_cmd.o
obj-$(CONFIG_PPC_PS3) += sys-manager-core.o
obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o
obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f1d10c974cd4..ba521f0f0fac 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -911,7 +911,7 @@ out:
}
/**
- * set_consumer_device_supply: Bind a regulator to a symbolic supply
+ * set_consumer_device_supply - Bind a regulator to a symbolic supply
* @rdev: regulator source
* @consumer_dev: device the supply applies to
* @consumer_dev_name: dev_name() string for device supply applies to
@@ -1052,7 +1052,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
printk(KERN_WARNING
"%s: could not add device link %s err %d\n",
__func__, dev->kobj.name, err);
- device_remove_file(dev, &regulator->dev_attr);
goto link_name_err;
}
}
@@ -1268,13 +1267,17 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
int ret, delay;
- /* do we need to enable the supply regulator first */
- if (rdev->supply) {
- ret = _regulator_enable(rdev->supply);
- if (ret < 0) {
- printk(KERN_ERR "%s: failed to enable %s: %d\n",
- __func__, rdev_get_name(rdev), ret);
- return ret;
+ if (rdev->use_count == 0) {
+ /* do we need to enable the supply regulator first */
+ if (rdev->supply) {
+ mutex_lock(&rdev->supply->mutex);
+ ret = _regulator_enable(rdev->supply);
+ mutex_unlock(&rdev->supply->mutex);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to enable %s: %d\n",
+ __func__, rdev_get_name(rdev), ret);
+ return ret;
+ }
}
}
@@ -1313,10 +1316,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
- if (delay >= 1000)
+ if (delay >= 1000) {
mdelay(delay / 1000);
- else if (delay)
+ udelay(delay % 1000);
+ } else if (delay) {
udelay(delay);
+ }
} else if (ret < 0) {
printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
@@ -1359,6 +1364,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
struct regulator_dev **supply_rdev_ptr)
{
int ret = 0;
+ *supply_rdev_ptr = NULL;
if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n",
@@ -2346,6 +2352,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (init_data->supply_regulator && init_data->supply_regulator_dev) {
dev_err(dev,
"Supply regulator specified by both name and dev\n");
+ ret = -EINVAL;
goto scrub;
}
@@ -2364,6 +2371,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (!found) {
dev_err(dev, "Failed to find supply %s\n",
init_data->supply_regulator);
+ ret = -ENODEV;
goto scrub;
}
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 4597d508a229..ecd99f59dba8 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -465,8 +465,8 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
.get_voltage = mc13783_fixed_regulator_get_voltage,
};
-int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
- u32 val)
+static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
+ u32 val)
{
struct mc13783 *mc13783 = priv->mc13783;
int ret;
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index 51237fbb1bbb..6d20b0454a1d 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = {
};
#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
-{ \
+ ereg0, ebit0, ereg1, ebit1) \
.desc = { \
.name = "REG-" #_id, \
.ops = &tps6586x_regulator_##_ops, \
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = {
.enable_bit[0] = (ebit0), \
.enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
.enable_bit[1] = (ebit1), \
- .voltages = tps6586x_##vdata##_voltages, \
-}
+ .voltages = tps6586x_##vdata##_voltages,
+
+#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
+ .go_reg = TPS6586X_##goreg, \
+ .go_bit = (gobit),
#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
+{ \
TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, 0, 0)
+ ereg0, ebit0, ereg1, ebit1) \
+}
#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
+{ \
TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit)
+ ereg0, ebit0, ereg1, ebit1) \
+ TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
+}
static struct tps6586x_regulator tps6586x_regulator[] = {
TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
- TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6),
+ TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
- TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7),
+ TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
- TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1),
+ TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
uint8_t val1, val2;
int ret;
+ if (ri->enable_reg[0] == ri->enable_reg[1] &&
+ ri->enable_bit[0] == ri->enable_bit[1])
+ return 0;
+
ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
if (ret)
return ret;
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
if (ret)
return ret;
- if (!(val2 & ri->enable_bit[1]))
+ if (!(val2 & (1 << ri->enable_bit[1])))
return 0;
/*
* The regulator is on, but it's enabled with the bit we don't
* want to use, so we switch the enable bits
*/
- if (!(val1 & ri->enable_bit[0])) {
+ if (!(val1 & (1 << ri->enable_bit[0]))) {
ret = tps6586x_set_bits(parent, ri->enable_reg[0],
1 << ri->enable_bit[0]);
if (ret)
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 7e5892efc437..a57262a4fa6c 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -219,12 +219,12 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
return -EACCES;
status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
- message >> 8, 0x15 /* PB_WORD_MSB */ );
- if (status >= 0)
+ message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB);
+ if (status < 0)
return status;
return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
- message, 0x16 /* PB_WORD_LSB */ );
+ message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
}
/*----------------------------------------------------------------------*/
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 03713bc66e4a..21fefef02a43 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -131,10 +131,19 @@ static struct regulator_ops wm8994_ldo1_ops = {
static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
unsigned int selector)
{
+ struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+
if (selector > WM8994_LDO2_MAX_SELECTOR)
return -EINVAL;
- return (selector * 100000) + 900000;
+ switch (ldo->wm8994->type) {
+ case WM8994:
+ return (selector * 100000) + 900000;
+ case WM8958:
+ return (selector * 100000) + 1000000;
+ default:
+ return -EINVAL;
+ }
}
static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev)
@@ -157,7 +166,17 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int selector, v;
- selector = (min_uV - 900000) / 100000;
+ switch (ldo->wm8994->type) {
+ case WM8994:
+ selector = (min_uV - 900000) / 100000;
+ break;
+ case WM8958:
+ selector = (min_uV - 1000000) / 100000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
v = wm8994_ldo2_list_voltage(rdev, selector);
if (v < 0 || v > max_uV)
return -EINVAL;
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5856167a0c90..7e6ce626b7f1 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -687,7 +687,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
#if defined(CONFIG_ATARI)
address_space = 64;
#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \
- || defined(__sparc__) || defined(__mips__)
+ || defined(__sparc__) || defined(__mips__) \
+ || defined(__powerpc__)
address_space = 128;
#else
#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 90cf0a6ff23e..dd14e202c2c8 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -207,7 +207,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct rs5c372 *rs5c = i2c_get_clientdata(client);
- unsigned char buf[8];
+ unsigned char buf[7];
int addr;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index e4a44b641702..88ea52b8647a 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -39,10 +39,10 @@
#include <mach/regs-ost.h>
#endif
-#define RTC_DEF_DIVIDER 32768 - 1
+#define RTC_DEF_DIVIDER (32768 - 1)
#define RTC_DEF_TRIM 0
-static unsigned long rtc_freq = 1024;
+static const unsigned long RTC_FREQ = 1024;
static unsigned long timer_freq;
static struct rtc_time rtc_alarm;
static DEFINE_SPINLOCK(sa1100_rtc_lock);
@@ -61,7 +61,8 @@ static inline int rtc_periodic_alarm(struct rtc_time *tm)
* Calculate the next alarm time given the requested alarm time mask
* and the current time.
*/
-static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
+static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
+ struct rtc_time *alrm)
{
unsigned long next_time;
unsigned long now_time;
@@ -116,7 +117,23 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
rtsr = RTSR;
/* clear interrupt sources */
RTSR = 0;
- RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
+ /* Fix for a nasty initialization problem the in SA11xx RTSR register.
+ * See also the comments in sa1100_rtc_probe(). */
+ if (rtsr & (RTSR_ALE | RTSR_HZE)) {
+ /* This is the original code, before there was the if test
+ * above. This code does not clear interrupts that were not
+ * enabled. */
+ RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
+ } else {
+ /* For some reason, it is possible to enter this routine
+ * without interruptions enabled, it has been tested with
+ * several units (Bug in SA11xx chip?).
+ *
+ * This situation leads to an infinite "loop" of interrupt
+ * routine calling and as a result the processor seems to
+ * lock on its first call to open(). */
+ RTSR = RTSR_AL | RTSR_HZ;
+ }
/* clear alarm interrupt if it has occurred */
if (rtsr & RTSR_AL)
@@ -139,8 +156,58 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int sa1100_irq_set_freq(struct device *dev, int freq)
+{
+ if (freq < 1 || freq > timer_freq) {
+ return -EINVAL;
+ } else {
+ struct rtc_device *rtc = (struct rtc_device *)dev;
+
+ rtc->irq_freq = freq;
+
+ return 0;
+ }
+}
+
static int rtc_timer1_count;
+static int sa1100_irq_set_state(struct device *dev, int enabled)
+{
+ spin_lock_irq(&sa1100_rtc_lock);
+ if (enabled) {
+ struct rtc_device *rtc = (struct rtc_device *)dev;
+
+ OSMR1 = timer_freq / rtc->irq_freq + OSCR;
+ OIER |= OIER_E1;
+ rtc_timer1_count = 1;
+ } else {
+ OIER &= ~OIER_E1;
+ }
+ spin_unlock_irq(&sa1100_rtc_lock);
+
+ return 0;
+}
+
+static inline int sa1100_timer1_retrigger(struct rtc_device *rtc)
+{
+ unsigned long diff;
+ unsigned long period = timer_freq / rtc->irq_freq;
+
+ spin_lock_irq(&sa1100_rtc_lock);
+
+ do {
+ OSMR1 += period;
+ diff = OSMR1 - OSCR;
+ /* If OSCR > OSMR1, diff is a very large number (unsigned
+ * math). This means we have a lost interrupt. */
+ } while (diff > period);
+ OIER |= OIER_E1;
+
+ spin_unlock_irq(&sa1100_rtc_lock);
+
+ return 0;
+}
+
static irqreturn_t timer1_interrupt(int irq, void *dev_id)
{
struct platform_device *pdev = to_platform_device(dev_id);
@@ -158,7 +225,11 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
if (rtc_timer1_count == 1)
- rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2)));
+ rtc_timer1_count =
+ (rtc->irq_freq * ((1 << 30) / (timer_freq >> 2)));
+
+ /* retrigger. */
+ sa1100_timer1_retrigger(rtc);
return IRQ_HANDLED;
}
@@ -166,8 +237,10 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
static int sa1100_rtc_read_callback(struct device *dev, int data)
{
if (data & RTC_PF) {
+ struct rtc_device *rtc = (struct rtc_device *)dev;
+
/* interpolate missed periods and set match for the next */
- unsigned long period = timer_freq / rtc_freq;
+ unsigned long period = timer_freq / rtc->irq_freq;
unsigned long oscr = OSCR;
unsigned long osmr1 = OSMR1;
unsigned long missed = (oscr - osmr1)/period;
@@ -178,7 +251,7 @@ static int sa1100_rtc_read_callback(struct device *dev, int data)
* Here we compare (match - OSCR) 8 instead of 0 --
* see comment in pxa_timer_interrupt() for explanation.
*/
- while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
+ while ((signed long)((osmr1 = OSMR1) - OSCR) <= 8) {
data += 0x100;
OSSR = OSSR_M1; /* clear match on timer 1 */
OSMR1 = osmr1 + period;
@@ -190,25 +263,29 @@ static int sa1100_rtc_read_callback(struct device *dev, int data)
static int sa1100_rtc_open(struct device *dev)
{
int ret;
+ struct rtc_device *rtc = (struct rtc_device *)dev;
ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
- "rtc 1Hz", dev);
+ "rtc 1Hz", dev);
if (ret) {
dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
goto fail_ui;
}
ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
- "rtc Alrm", dev);
+ "rtc Alrm", dev);
if (ret) {
dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
goto fail_ai;
}
ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED,
- "rtc timer", dev);
+ "rtc timer", dev);
if (ret) {
dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1);
goto fail_pi;
}
+ rtc->max_user_freq = RTC_FREQ;
+ sa1100_irq_set_freq(dev, RTC_FREQ);
+
return 0;
fail_pi:
@@ -236,7 +313,7 @@ static void sa1100_rtc_release(struct device *dev)
static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
- switch(cmd) {
+ switch (cmd) {
case RTC_AIE_OFF:
spin_lock_irq(&sa1100_rtc_lock);
RTSR &= ~RTSR_ALE;
@@ -257,25 +334,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
RTSR |= RTSR_HZE;
spin_unlock_irq(&sa1100_rtc_lock);
return 0;
- case RTC_PIE_OFF:
- spin_lock_irq(&sa1100_rtc_lock);
- OIER &= ~OIER_E1;
- spin_unlock_irq(&sa1100_rtc_lock);
- return 0;
- case RTC_PIE_ON:
- spin_lock_irq(&sa1100_rtc_lock);
- OSMR1 = timer_freq / rtc_freq + OSCR;
- OIER |= OIER_E1;
- rtc_timer1_count = 1;
- spin_unlock_irq(&sa1100_rtc_lock);
- return 0;
- case RTC_IRQP_READ:
- return put_user(rtc_freq, (unsigned long *)arg);
- case RTC_IRQP_SET:
- if (arg < 1 || arg > timer_freq)
- return -EINVAL;
- rtc_freq = arg;
- return 0;
}
return -ENOIOCTLCMD;
}
@@ -327,12 +385,15 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
{
+ struct rtc_device *rtc = (struct rtc_device *)dev;
+
seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR);
seq_printf(seq, "update_IRQ\t: %s\n",
(RTSR & RTSR_HZE) ? "yes" : "no");
seq_printf(seq, "periodic_IRQ\t: %s\n",
(OIER & OIER_E1) ? "yes" : "no");
- seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq);
+ seq_printf(seq, "periodic_freq\t: %d\n", rtc->irq_freq);
+ seq_printf(seq, "RTSR\t\t: 0x%08x\n", (u32)RTSR);
return 0;
}
@@ -347,6 +408,8 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
.read_alarm = sa1100_rtc_read_alarm,
.set_alarm = sa1100_rtc_set_alarm,
.proc = sa1100_rtc_proc,
+ .irq_set_freq = sa1100_irq_set_freq,
+ .irq_set_state = sa1100_irq_set_state,
};
static int sa1100_rtc_probe(struct platform_device *pdev)
@@ -364,7 +427,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
*/
if (RTTR == 0) {
RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
- dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n");
+ dev_warn(&pdev->dev, "warning: "
+ "initializing default clock divider/trim value\n");
/* The current RTC value probably doesn't make sense either */
RCNR = 0;
}
@@ -372,13 +436,42 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
- THIS_MODULE);
+ THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
platform_set_drvdata(pdev, rtc);
+ /* Set the irq_freq */
+ /*TODO: Find out who is messing with this value after we initialize
+ * it here.*/
+ rtc->irq_freq = RTC_FREQ;
+
+ /* Fix for a nasty initialization problem the in SA11xx RTSR register.
+ * See also the comments in sa1100_rtc_interrupt().
+ *
+ * Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an
+ * interrupt pending, even though interrupts were never enabled.
+ * In this case, this bit it must be reset before enabling
+ * interruptions to avoid a nonexistent interrupt to occur.
+ *
+ * In principle, the same problem would apply to bit 0, although it has
+ * never been observed to happen.
+ *
+ * This issue is addressed both here and in sa1100_rtc_interrupt().
+ * If the issue is not addressed here, in the times when the processor
+ * wakes up with the bit set there will be one spurious interrupt.
+ *
+ * The issue is also dealt with in sa1100_rtc_interrupt() to be on the
+ * safe side, once the condition that lead to this strange
+ * initialization is unknown and could in principle happen during
+ * normal processing.
+ *
+ * Notice that clearing bit 1 and 0 is accomplished by writting ONES to
+ * the corresponding bits in RTSR. */
+ RTSR = RTSR_AL | RTSR_HZ;
+
return 0;
}
@@ -386,7 +479,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
{
struct rtc_device *rtc = platform_get_drvdata(pdev);
- if (rtc)
+ if (rtc)
rtc_device_unregister(rtc);
return 0;
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index 07883197f474..8e477bb1f3f6 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -2,7 +2,8 @@ comment "S/390 block device drivers"
depends on S390 && BLOCK
config BLK_DEV_XPRAM
- tristate "XPRAM disk support"
+ def_tristate m
+ prompt "XPRAM disk support"
depends on S390 && BLOCK
help
Select this option if you want to use your expanded storage on S/390
@@ -12,13 +13,15 @@ config BLK_DEV_XPRAM
xpram. If unsure, say "N".
config DCSSBLK
- tristate "DCSSBLK support"
+ def_tristate m
+ prompt "DCSSBLK support"
depends on S390 && BLOCK
help
Support for dcss block device
config DASD
- tristate "Support for DASD devices"
+ def_tristate y
+ prompt "Support for DASD devices"
depends on CCW && BLOCK
select IOSCHED_DEADLINE
help
@@ -27,28 +30,32 @@ config DASD
natively on a single image or an LPAR.
config DASD_PROFILE
- bool "Profiling support for dasd devices"
+ def_bool y
+ prompt "Profiling support for dasd devices"
depends on DASD
help
Enable this option if you want to see profiling information
in /proc/dasd/statistics.
config DASD_ECKD
- tristate "Support for ECKD Disks"
+ def_tristate y
+ prompt "Support for ECKD Disks"
depends on DASD
help
ECKD devices are the most commonly used devices. You should enable
this option unless you are very sure to have no ECKD device.
config DASD_FBA
- tristate "Support for FBA Disks"
+ def_tristate y
+ prompt "Support for FBA Disks"
depends on DASD
help
Select this option to be able to access FBA devices. It is safe to
say "Y".
config DASD_DIAG
- tristate "Support for DIAG access to Disks"
+ def_tristate y
+ prompt "Support for DIAG access to Disks"
depends on DASD
help
Select this option if you want to use Diagnose250 command to access
@@ -56,7 +63,8 @@ config DASD_DIAG
say "N".
config DASD_EER
- bool "Extended error reporting (EER)"
+ def_bool y
+ prompt "Extended error reporting (EER)"
depends on DASD
help
This driver provides a character device interface to the
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index fb613d70c2cb..794bfd962266 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -11,6 +11,7 @@
#define KMSG_COMPONENT "dasd"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -368,6 +369,11 @@ dasd_state_ready_to_online(struct dasd_device * device)
device->state = DASD_STATE_ONLINE;
if (device->block) {
dasd_schedule_block_bh(device->block);
+ if ((device->features & DASD_FEATURE_USERAW)) {
+ disk = device->block->gdp;
+ kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
+ return 0;
+ }
disk = device->block->bdev->bd_disk;
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
while ((part = disk_part_iter_next(&piter)))
@@ -393,7 +399,7 @@ static int dasd_state_online_to_ready(struct dasd_device *device)
return rc;
}
device->state = DASD_STATE_READY;
- if (device->block) {
+ if (device->block && !(device->features & DASD_FEATURE_USERAW)) {
disk = device->block->bdev->bd_disk;
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
while ((part = disk_part_iter_next(&piter)))
@@ -744,10 +750,6 @@ struct dasd_ccw_req *dasd_smalloc_request(int magic, int cplength,
char *data;
int size;
- /* Sanity checks */
- BUG_ON(datasize > PAGE_SIZE ||
- (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
-
size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
if (cplength > 0)
size += cplength * sizeof(struct ccw1);
@@ -853,7 +855,6 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
rc = ccw_device_clear(device->cdev, (long) cqr);
switch (rc) {
case 0: /* termination successful */
- cqr->retries--;
cqr->status = DASD_CQR_CLEAR_PENDING;
cqr->stopclk = get_clock();
cqr->starttime = 0;
@@ -905,6 +906,16 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
return rc;
}
device = (struct dasd_device *) cqr->startdev;
+ if (((cqr->block &&
+ test_bit(DASD_FLAG_LOCK_STOLEN, &cqr->block->base->flags)) ||
+ test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) &&
+ !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
+ DBF_DEV_EVENT(DBF_DEBUG, device, "start_IO: return request %p "
+ "because of stolen lock", cqr);
+ cqr->status = DASD_CQR_ERROR;
+ cqr->intrc = -EPERM;
+ return -EPERM;
+ }
if (cqr->retries < 0) {
/* internal error 14 - start_IO run out of retries */
sprintf(errorstring, "14 %p", cqr);
@@ -916,6 +927,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->startclk = get_clock();
cqr->starttime = jiffies;
cqr->retries--;
+ if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
+ cqr->lpm &= device->path_data.opm;
+ if (!cqr->lpm)
+ cqr->lpm = device->path_data.opm;
+ }
if (cqr->cpmode == 1) {
rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
(long) cqr, cqr->lpm);
@@ -928,35 +944,53 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->status = DASD_CQR_IN_IO;
break;
case -EBUSY:
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"start_IO: device busy, retry later");
break;
case -ETIMEDOUT:
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"start_IO: request timeout, retry later");
break;
case -EACCES:
- /* -EACCES indicates that the request used only a
- * subset of the available pathes and all these
- * pathes are gone.
- * Do a retry with all available pathes.
+ /* -EACCES indicates that the request used only a subset of the
+ * available paths and all these paths are gone. If the lpm of
+ * this request was only a subset of the opm (e.g. the ppm) then
+ * we just do a retry with all available paths.
+ * If we already use the full opm, something is amiss, and we
+ * need a full path verification.
*/
- cqr->lpm = LPM_ANYPATH;
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
- "start_IO: selected pathes gone,"
- " retry on all pathes");
+ if (test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
+ DBF_DEV_EVENT(DBF_WARNING, device,
+ "start_IO: selected paths gone (%x)",
+ cqr->lpm);
+ } else if (cqr->lpm != device->path_data.opm) {
+ cqr->lpm = device->path_data.opm;
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: selected paths gone,"
+ " retry on all paths");
+ } else {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "start_IO: all paths in opm gone,"
+ " do path verification");
+ dasd_generic_last_path_gone(device);
+ device->path_data.opm = 0;
+ device->path_data.ppm = 0;
+ device->path_data.npm = 0;
+ device->path_data.tbvpm =
+ ccw_device_get_path_mask(device->cdev);
+ }
break;
case -ENODEV:
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"start_IO: -ENODEV device gone, retry");
break;
case -EIO:
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"start_IO: -EIO device gone, retry");
break;
case -EINVAL:
/* most likely caused in power management context */
- DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"start_IO: -EINVAL device currently "
"not accessible");
break;
@@ -1076,6 +1110,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
unsigned long long now;
int expires;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_DAS]++;
if (IS_ERR(irb)) {
switch (PTR_ERR(irb)) {
case -EIO:
@@ -1094,16 +1129,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
}
now = get_clock();
-
- /* check for unsolicited interrupts */
cqr = (struct dasd_ccw_req *) intparm;
- if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
- (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
- ((scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND) ||
- (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND |
- SCSW_STCTL_ALERT_STATUS))))) {
- if (cqr && cqr->status == DASD_CQR_IN_IO)
- cqr->status = DASD_CQR_QUEUED;
+ /* check for conditions that should be handled immediately */
+ if (!cqr ||
+ !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+ scsw_cstat(&irb->scsw) == 0)) {
if (cqr)
memcpy(&cqr->irb, irb, sizeof(*irb));
device = dasd_device_from_cdev_locked(cdev);
@@ -1114,17 +1144,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
dasd_put_device(device);
return;
}
- device->discipline->dump_sense_dbf(device, irb,
- "unsolicited");
- if ((device->features & DASD_FEATURE_ERPLOG))
- device->discipline->dump_sense(device, cqr,
- irb);
- dasd_device_clear_timer(device);
- device->discipline->handle_unsolicited_interrupt(device,
- irb);
+ device->discipline->dump_sense_dbf(device, irb, "int");
+ if (device->features & DASD_FEATURE_ERPLOG)
+ device->discipline->dump_sense(device, cqr, irb);
+ device->discipline->check_for_device_change(device, cqr, irb);
dasd_put_device(device);
- return;
}
+ if (!cqr)
+ return;
device = (struct dasd_device *) cqr->startdev;
if (!device ||
@@ -1164,25 +1191,19 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
struct dasd_ccw_req, devlist);
}
} else { /* error */
- memcpy(&cqr->irb, irb, sizeof(struct irb));
- /* log sense for every failed I/O to s390 debugfeature */
- dasd_log_sense_dbf(cqr, irb);
- if (device->features & DASD_FEATURE_ERPLOG) {
- dasd_log_sense(cqr, irb);
- }
-
/*
* If we don't want complex ERP for this request, then just
* reset this and retry it in the fastpath
*/
if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
cqr->retries > 0) {
- if (cqr->lpm == LPM_ANYPATH)
+ if (cqr->lpm == device->path_data.opm)
DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP in fastpath "
"(%i retries left)",
cqr->retries);
- cqr->lpm = LPM_ANYPATH;
+ if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
+ cqr->lpm = device->path_data.opm;
cqr->status = DASD_CQR_QUEUED;
next = cqr;
} else
@@ -1210,13 +1231,13 @@ enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb)
goto out;
if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
device->state != device->target ||
- !device->discipline->handle_unsolicited_interrupt){
+ !device->discipline->check_for_device_change){
dasd_put_device(device);
goto out;
}
-
- dasd_device_clear_timer(device);
- device->discipline->handle_unsolicited_interrupt(device, irb);
+ if (device->discipline->dump_sense_dbf)
+ device->discipline->dump_sense_dbf(device, irb, "uc");
+ device->discipline->check_for_device_change(device, NULL, irb);
dasd_put_device(device);
out:
return UC_TODO_RETRY;
@@ -1366,8 +1387,14 @@ static void __dasd_device_start_head(struct dasd_device *device)
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist);
if (cqr->status != DASD_CQR_QUEUED)
return;
- /* when device is stopped, return request to previous layer */
- if (device->stopped) {
+ /* when device is stopped, return request to previous layer
+ * exception: only the disconnect or unresumed bits are set and the
+ * cqr is a path verification request
+ */
+ if (device->stopped &&
+ !(!(device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM))
+ && test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))) {
+ cqr->intrc = -EAGAIN;
cqr->status = DASD_CQR_CLEARED;
dasd_schedule_device_bh(device);
return;
@@ -1383,6 +1410,23 @@ static void __dasd_device_start_head(struct dasd_device *device)
dasd_device_set_timer(device, 50);
}
+static void __dasd_device_check_path_events(struct dasd_device *device)
+{
+ int rc;
+
+ if (device->path_data.tbvpm) {
+ if (device->stopped & ~(DASD_STOPPED_DC_WAIT |
+ DASD_UNRESUMED_PM))
+ return;
+ rc = device->discipline->verify_path(
+ device, device->path_data.tbvpm);
+ if (rc)
+ dasd_device_set_timer(device, 50);
+ else
+ device->path_data.tbvpm = 0;
+ }
+};
+
/*
* Go through all request on the dasd_device request queue,
* terminate them on the cdev if necessary, and return them to the
@@ -1457,6 +1501,7 @@ static void dasd_device_tasklet(struct dasd_device *device)
__dasd_device_check_expire(device);
/* find final requests on ccw queue */
__dasd_device_process_ccw_queue(device, &final_queue);
+ __dasd_device_check_path_events(device);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
/* Now call the callback function of requests with final status */
__dasd_device_process_final_queue(device, &final_queue);
@@ -1613,7 +1658,12 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
continue;
if (cqr->status != DASD_CQR_FILLED) /* could be failed */
continue;
-
+ if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) &&
+ !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
+ cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -EPERM;
+ continue;
+ }
/* Non-temporary stop condition will trigger fail fast */
if (device->stopped & ~DASD_STOPPED_PENDING &&
test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
@@ -1621,7 +1671,6 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
cqr->status = DASD_CQR_FAILED;
continue;
}
-
/* Don't try to start requests if device is stopped */
if (interruptible) {
rc = wait_event_interruptible(
@@ -1706,13 +1755,18 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
int rc;
device = cqr->startdev;
+ if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) &&
+ !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
+ cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -EPERM;
+ return -EIO;
+ }
spin_lock_irq(get_ccwdev_lock(device->cdev));
rc = _dasd_term_running_cqr(device);
if (rc) {
spin_unlock_irq(get_ccwdev_lock(device->cdev));
return rc;
}
-
cqr->callback = dasd_wakeup_cb;
cqr->callback_data = DASD_SLEEPON_START_TAG;
cqr->status = DASD_CQR_QUEUED;
@@ -2016,6 +2070,13 @@ static void __dasd_block_start_head(struct dasd_block *block)
list_for_each_entry(cqr, &block->ccw_queue, blocklist) {
if (cqr->status != DASD_CQR_FILLED)
continue;
+ if (test_bit(DASD_FLAG_LOCK_STOLEN, &block->base->flags) &&
+ !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
+ cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -EPERM;
+ dasd_schedule_block_bh(block);
+ continue;
+ }
/* Non-temporary stop condition will trigger fail fast */
if (block->base->stopped & ~DASD_STOPPED_PENDING &&
test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
@@ -2201,8 +2262,20 @@ static void dasd_setup_queue(struct dasd_block *block)
{
int max;
- blk_queue_logical_block_size(block->request_queue, block->bp_block);
- max = block->base->discipline->max_blocks << block->s2b_shift;
+ if (block->base->features & DASD_FEATURE_USERAW) {
+ /*
+ * the max_blocks value for raw_track access is 256
+ * it is higher than the native ECKD value because we
+ * only need one ccw per track
+ * so the max_hw_sectors are
+ * 2048 x 512B = 1024kB = 16 tracks
+ */
+ max = 2048;
+ } else {
+ max = block->base->discipline->max_blocks << block->s2b_shift;
+ }
+ blk_queue_logical_block_size(block->request_queue,
+ block->bp_block);
blk_queue_max_hw_sectors(block->request_queue, max);
blk_queue_max_segments(block->request_queue, -1L);
/* with page sized segments we can translate each segement into
@@ -2588,10 +2661,53 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
return 0;
}
+int dasd_generic_last_path_gone(struct dasd_device *device)
+{
+ struct dasd_ccw_req *cqr;
+
+ dev_warn(&device->cdev->dev, "No operational channel path is left "
+ "for the device\n");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "last path gone");
+ /* First of all call extended error reporting. */
+ dasd_eer_write(device, NULL, DASD_EER_NOPATH);
+
+ if (device->state < DASD_STATE_BASIC)
+ return 0;
+ /* Device is active. We want to keep it. */
+ list_for_each_entry(cqr, &device->ccw_queue, devlist)
+ if ((cqr->status == DASD_CQR_IN_IO) ||
+ (cqr->status == DASD_CQR_CLEAR_PENDING)) {
+ cqr->status = DASD_CQR_QUEUED;
+ cqr->retries++;
+ }
+ dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
+ dasd_device_clear_timer(device);
+ dasd_schedule_device_bh(device);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(dasd_generic_last_path_gone);
+
+int dasd_generic_path_operational(struct dasd_device *device)
+{
+ dev_info(&device->cdev->dev, "A channel path to the device has become "
+ "operational\n");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "path operational");
+ dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
+ if (device->stopped & DASD_UNRESUMED_PM) {
+ dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
+ dasd_restore_device(device);
+ return 1;
+ }
+ dasd_schedule_device_bh(device);
+ if (device->block)
+ dasd_schedule_block_bh(device->block);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(dasd_generic_path_operational);
+
int dasd_generic_notify(struct ccw_device *cdev, int event)
{
struct dasd_device *device;
- struct dasd_ccw_req *cqr;
int ret;
device = dasd_device_from_cdev_locked(cdev);
@@ -2602,41 +2718,64 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
case CIO_GONE:
case CIO_BOXED:
case CIO_NO_PATH:
- /* First of all call extended error reporting. */
- dasd_eer_write(device, NULL, DASD_EER_NOPATH);
-
- if (device->state < DASD_STATE_BASIC)
- break;
- /* Device is active. We want to keep it. */
- list_for_each_entry(cqr, &device->ccw_queue, devlist)
- if (cqr->status == DASD_CQR_IN_IO) {
- cqr->status = DASD_CQR_QUEUED;
- cqr->retries++;
- }
- dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
- dasd_device_clear_timer(device);
- dasd_schedule_device_bh(device);
- ret = 1;
+ device->path_data.opm = 0;
+ device->path_data.ppm = 0;
+ device->path_data.npm = 0;
+ ret = dasd_generic_last_path_gone(device);
break;
case CIO_OPER:
- /* FIXME: add a sanity check. */
- dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
- if (device->stopped & DASD_UNRESUMED_PM) {
- dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
- dasd_restore_device(device);
- ret = 1;
- break;
- }
- dasd_schedule_device_bh(device);
- if (device->block)
- dasd_schedule_block_bh(device->block);
ret = 1;
+ if (device->path_data.opm)
+ ret = dasd_generic_path_operational(device);
break;
}
dasd_put_device(device);
return ret;
}
+void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
+{
+ int chp;
+ __u8 oldopm, eventlpm;
+ struct dasd_device *device;
+
+ device = dasd_device_from_cdev_locked(cdev);
+ if (IS_ERR(device))
+ return;
+ for (chp = 0; chp < 8; chp++) {
+ eventlpm = 0x80 >> chp;
+ if (path_event[chp] & PE_PATH_GONE) {
+ oldopm = device->path_data.opm;
+ device->path_data.opm &= ~eventlpm;
+ device->path_data.ppm &= ~eventlpm;
+ device->path_data.npm &= ~eventlpm;
+ if (oldopm && !device->path_data.opm)
+ dasd_generic_last_path_gone(device);
+ }
+ if (path_event[chp] & PE_PATH_AVAILABLE) {
+ device->path_data.opm &= ~eventlpm;
+ device->path_data.ppm &= ~eventlpm;
+ device->path_data.npm &= ~eventlpm;
+ device->path_data.tbvpm |= eventlpm;
+ dasd_schedule_device_bh(device);
+ }
+ }
+ dasd_put_device(device);
+}
+EXPORT_SYMBOL_GPL(dasd_generic_path_event);
+
+int dasd_generic_verify_path(struct dasd_device *device, __u8 lpm)
+{
+ if (!device->path_data.opm && lpm) {
+ device->path_data.opm = lpm;
+ dasd_generic_path_operational(device);
+ } else
+ device->path_data.opm |= lpm;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dasd_generic_verify_path);
+
+
int dasd_generic_pm_freeze(struct ccw_device *cdev)
{
struct dasd_ccw_req *cqr, *n;
@@ -2646,6 +2785,10 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev)
if (IS_ERR(device))
return PTR_ERR(device);
+
+ if (device->discipline->freeze)
+ rc = device->discipline->freeze(device);
+
/* disallow new I/O */
dasd_device_set_stop_bits(device, DASD_STOPPED_PM);
/* clear active requests */
@@ -2682,9 +2825,6 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev)
list_splice_tail(&freeze_queue, &device->ccw_queue);
spin_unlock_irq(get_ccwdev_lock(cdev));
- if (device->discipline->freeze)
- rc = device->discipline->freeze(device);
-
dasd_put_device(device);
return rc;
}
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 968c76cf7127..1654a24817be 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -152,9 +152,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
opm = ccw_device_get_path_mask(device->cdev);
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
- //FIXME: start with get_opm ?
if (erp->lpm == 0)
- erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum);
+ erp->lpm = device->path_data.opm &
+ ~(erp->irb.esw.esw0.sublog.lpum);
else
erp->lpm &= ~(erp->irb.esw.esw0.sublog.lpum);
@@ -270,10 +270,11 @@ static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
{
erp->function = dasd_3990_erp_action_1;
dasd_3990_erp_alternate_path(erp);
- if (erp->status == DASD_CQR_FAILED) {
+ if (erp->status == DASD_CQR_FAILED &&
+ !test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
erp->status = DASD_CQR_FILLED;
erp->retries = 10;
- erp->lpm = LPM_ANYPATH;
+ erp->lpm = erp->startdev->path_data.opm;
erp->function = dasd_3990_erp_action_1_sec;
}
return erp;
@@ -1907,15 +1908,14 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense)
static void
dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
{
-
if (sense[25] & DASD_SENSE_BIT_3) {
dasd_3990_erp_alternate_path(erp);
- if (erp->status == DASD_CQR_FAILED) {
+ if (erp->status == DASD_CQR_FAILED &&
+ !test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
/* reset the lpm and the status to be able to
* try further actions. */
-
- erp->lpm = 0;
+ erp->lpm = erp->startdev->path_data.opm;
erp->status = DASD_CQR_NEED_ERP;
}
}
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 8d41f3ed38d7..cb6a67bc89ff 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -208,6 +208,8 @@ dasd_feature_list(char *str, char **endp)
features |= DASD_FEATURE_READONLY;
else if (len == 4 && !strncmp(str, "diag", 4))
features |= DASD_FEATURE_USEDIAG;
+ else if (len == 3 && !strncmp(str, "raw", 3))
+ features |= DASD_FEATURE_USERAW;
else if (len == 6 && !strncmp(str, "erplog", 6))
features |= DASD_FEATURE_ERPLOG;
else if (len == 8 && !strncmp(str, "failfast", 8))
@@ -639,6 +641,7 @@ dasd_put_device_wake(struct dasd_device *device)
{
wake_up(&dasd_delete_wq);
}
+EXPORT_SYMBOL_GPL(dasd_put_device_wake);
/*
* Return dasd_device structure associated with cdev.
@@ -856,7 +859,7 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
spin_lock(&dasd_devmap_lock);
/* Changing diag discipline flag is only allowed in offline state. */
rc = count;
- if (!devmap->device) {
+ if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
if (val)
devmap->features |= DASD_FEATURE_USEDIAG;
else
@@ -869,6 +872,56 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
+/*
+ * use_raw controls whether the driver should give access to raw eckd data or
+ * operate in standard mode
+ */
+static ssize_t
+dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct dasd_devmap *devmap;
+ int use_raw;
+
+ devmap = dasd_find_busid(dev_name(dev));
+ if (!IS_ERR(devmap))
+ use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
+ else
+ use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
+ return sprintf(buf, use_raw ? "1\n" : "0\n");
+}
+
+static ssize_t
+dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct dasd_devmap *devmap;
+ ssize_t rc;
+ unsigned long val;
+
+ devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
+ if (IS_ERR(devmap))
+ return PTR_ERR(devmap);
+
+ if ((strict_strtoul(buf, 10, &val) != 0) || val > 1)
+ return -EINVAL;
+
+ spin_lock(&dasd_devmap_lock);
+ /* Changing diag discipline flag is only allowed in offline state. */
+ rc = count;
+ if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
+ if (val)
+ devmap->features |= DASD_FEATURE_USERAW;
+ else
+ devmap->features &= ~DASD_FEATURE_USERAW;
+ } else
+ rc = -EPERM;
+ spin_unlock(&dasd_devmap_lock);
+ return rc;
+}
+
+static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
+ dasd_use_raw_store);
+
static ssize_t
dasd_discipline_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1126,6 +1179,103 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
+static ssize_t dasd_reservation_policy_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct dasd_devmap *devmap;
+ int rc = 0;
+
+ devmap = dasd_find_busid(dev_name(dev));
+ if (IS_ERR(devmap)) {
+ rc = snprintf(buf, PAGE_SIZE, "ignore\n");
+ } else {
+ spin_lock(&dasd_devmap_lock);
+ if (devmap->features & DASD_FEATURE_FAILONSLCK)
+ rc = snprintf(buf, PAGE_SIZE, "fail\n");
+ else
+ rc = snprintf(buf, PAGE_SIZE, "ignore\n");
+ spin_unlock(&dasd_devmap_lock);
+ }
+ return rc;
+}
+
+static ssize_t dasd_reservation_policy_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct dasd_devmap *devmap;
+ int rc;
+
+ devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
+ if (IS_ERR(devmap))
+ return PTR_ERR(devmap);
+ rc = 0;
+ spin_lock(&dasd_devmap_lock);
+ if (sysfs_streq("ignore", buf))
+ devmap->features &= ~DASD_FEATURE_FAILONSLCK;
+ else if (sysfs_streq("fail", buf))
+ devmap->features |= DASD_FEATURE_FAILONSLCK;
+ else
+ rc = -EINVAL;
+ if (devmap->device)
+ devmap->device->features = devmap->features;
+ spin_unlock(&dasd_devmap_lock);
+ if (rc)
+ return rc;
+ else
+ return count;
+}
+
+static DEVICE_ATTR(reservation_policy, 0644,
+ dasd_reservation_policy_show, dasd_reservation_policy_store);
+
+static ssize_t dasd_reservation_state_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct dasd_device *device;
+ int rc = 0;
+
+ device = dasd_device_from_cdev(to_ccwdev(dev));
+ if (IS_ERR(device))
+ return snprintf(buf, PAGE_SIZE, "none\n");
+
+ if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
+ rc = snprintf(buf, PAGE_SIZE, "reserved\n");
+ else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
+ rc = snprintf(buf, PAGE_SIZE, "lost\n");
+ else
+ rc = snprintf(buf, PAGE_SIZE, "none\n");
+ dasd_put_device(device);
+ return rc;
+}
+
+static ssize_t dasd_reservation_state_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct dasd_device *device;
+ int rc = 0;
+
+ device = dasd_device_from_cdev(to_ccwdev(dev));
+ if (IS_ERR(device))
+ return -ENODEV;
+ if (sysfs_streq("reset", buf))
+ clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
+ else
+ rc = -EINVAL;
+ dasd_put_device(device);
+
+ if (rc)
+ return rc;
+ else
+ return count;
+}
+
+static DEVICE_ATTR(last_known_reservation_state, 0644,
+ dasd_reservation_state_show, dasd_reservation_state_store);
+
static struct attribute * dasd_attrs[] = {
&dev_attr_readonly.attr,
&dev_attr_discipline.attr,
@@ -1134,10 +1284,13 @@ static struct attribute * dasd_attrs[] = {
&dev_attr_vendor.attr,
&dev_attr_uid.attr,
&dev_attr_use_diag.attr,
+ &dev_attr_raw_track_access.attr,
&dev_attr_eer_enabled.attr,
&dev_attr_erplog.attr,
&dev_attr_failfast.attr,
&dev_attr_expires.attr,
+ &dev_attr_reservation_policy.attr,
+ &dev_attr_last_known_reservation_state.attr,
NULL,
};
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 266b34b55403..29143eda9dd9 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -10,6 +10,7 @@
#define KMSG_COMPONENT "dasd"
+#include <linux/kernel_stat.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -238,6 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
addr_t ip;
int rc;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++;
switch (ext_int_code >> 24) {
case DASD_DIAG_CODE_31BIT:
ip = (addr_t) param32;
@@ -617,6 +619,7 @@ static struct dasd_discipline dasd_diag_discipline = {
.ebcname = "DIAG",
.max_blocks = DIAG_MAX_BLOCKS,
.check_device = dasd_diag_check_device,
+ .verify_path = dasd_generic_verify_path,
.fill_geometry = dasd_diag_fill_geometry,
.start_IO = dasd_start_diag,
.term_IO = dasd_diag_term_IO,
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index bf61274af3bb..318672d05563 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -54,6 +54,15 @@
#define ECKD_F7(i) (i->factor7)
#define ECKD_F8(i) (i->factor8)
+/*
+ * raw track access always map to 64k in memory
+ * so it maps to 16 blocks of 4k per track
+ */
+#define DASD_RAW_BLOCK_PER_TRACK 16
+#define DASD_RAW_BLOCKSIZE 4096
+/* 64k are 128 x 512 byte sectors */
+#define DASD_RAW_SECTORS_PER_TRACK 128
+
MODULE_LICENSE("GPL");
static struct dasd_discipline dasd_eckd_discipline;
@@ -90,6 +99,18 @@ static struct {
} *dasd_reserve_req;
static DEFINE_MUTEX(dasd_reserve_mutex);
+/* definitions for the path verification worker */
+struct path_verification_work_data {
+ struct work_struct worker;
+ struct dasd_device *device;
+ struct dasd_ccw_req cqr;
+ struct ccw1 ccw;
+ __u8 rcd_buffer[DASD_ECKD_RCD_DATA_SIZE];
+ int isglobal;
+ __u8 tbvpm;
+};
+static struct path_verification_work_data *path_verification_worker;
+static DEFINE_MUTEX(dasd_path_verification_mutex);
/* initial attempt at a probe function. this can be simplified once
* the other detection code is gone */
@@ -373,6 +394,23 @@ static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
data->length = reclen;
data->operation.operation = 0x03;
break;
+ case DASD_ECKD_CCW_WRITE_FULL_TRACK:
+ data->operation.orientation = 0x0;
+ data->operation.operation = 0x3F;
+ data->extended_operation = 0x11;
+ data->length = 0;
+ data->extended_parameter_length = 0x02;
+ if (data->count > 8) {
+ data->extended_parameter[0] = 0xFF;
+ data->extended_parameter[1] = 0xFF;
+ data->extended_parameter[1] <<= (16 - count);
+ } else {
+ data->extended_parameter[0] = 0xFF;
+ data->extended_parameter[0] <<= (8 - count);
+ data->extended_parameter[1] = 0x00;
+ }
+ data->sector = 0xFF;
+ break;
case DASD_ECKD_CCW_WRITE_TRACK_DATA:
data->auxiliary.length_valid = 0x1;
data->length = reclen; /* not tlf, as one might think */
@@ -396,6 +434,12 @@ static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
case DASD_ECKD_CCW_READ_COUNT:
data->operation.operation = 0x06;
break;
+ case DASD_ECKD_CCW_READ_TRACK:
+ data->operation.orientation = 0x1;
+ data->operation.operation = 0x0C;
+ data->extended_parameter_length = 0;
+ data->sector = 0xFF;
+ break;
case DASD_ECKD_CCW_READ_TRACK_DATA:
data->auxiliary.length_valid = 0x1;
data->length = tlf;
@@ -439,10 +483,16 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
ccw->cmd_code = DASD_ECKD_CCW_PFX;
ccw->flags = 0;
- ccw->count = sizeof(*pfxdata);
- ccw->cda = (__u32) __pa(pfxdata);
+ if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK) {
+ ccw->count = sizeof(*pfxdata) + 2;
+ ccw->cda = (__u32) __pa(pfxdata);
+ memset(pfxdata, 0, sizeof(*pfxdata) + 2);
+ } else {
+ ccw->count = sizeof(*pfxdata);
+ ccw->cda = (__u32) __pa(pfxdata);
+ memset(pfxdata, 0, sizeof(*pfxdata));
+ }
- memset(pfxdata, 0, sizeof(*pfxdata));
/* prefix data */
if (format > 1) {
DBF_DEV_EVENT(DBF_ERR, basedev,
@@ -476,6 +526,7 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
dedata->mask.perm = 0x1;
dedata->attributes.operation = basepriv->attrib.operation;
break;
+ case DASD_ECKD_CCW_READ_TRACK:
case DASD_ECKD_CCW_READ_TRACK_DATA:
dedata->mask.perm = 0x1;
dedata->attributes.operation = basepriv->attrib.operation;
@@ -502,6 +553,11 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
+ case DASD_ECKD_CCW_WRITE_FULL_TRACK:
+ dedata->mask.perm = 0x03;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = 0;
+ break;
case DASD_ECKD_CCW_WRITE_TRACK_DATA:
dedata->mask.perm = 0x02;
dedata->attributes.operation = basepriv->attrib.operation;
@@ -755,26 +811,27 @@ static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
return -EINVAL;
}
-static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
- void *rcd_buffer,
- struct ciw *ciw, __u8 lpm)
+static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
+ struct dasd_ccw_req *cqr,
+ __u8 *rcd_buffer,
+ __u8 lpm)
{
- struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
-
- cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* RCD */, ciw->count,
- device);
-
- if (IS_ERR(cqr)) {
- DBF_DEV_EVENT(DBF_WARNING, device, "%s",
- "Could not allocate RCD request");
- return cqr;
- }
+ /*
+ * buffer has to start with EBCDIC "V1.0" to show
+ * support for virtual device SNEQ
+ */
+ rcd_buffer[0] = 0xE5;
+ rcd_buffer[1] = 0xF1;
+ rcd_buffer[2] = 0x4B;
+ rcd_buffer[3] = 0xF0;
ccw = cqr->cpaddr;
- ccw->cmd_code = ciw->cmd;
+ ccw->cmd_code = DASD_ECKD_CCW_RCD;
+ ccw->flags = 0;
ccw->cda = (__u32)(addr_t)rcd_buffer;
- ccw->count = ciw->count;
+ ccw->count = DASD_ECKD_RCD_DATA_SIZE;
+ cqr->magic = DASD_ECKD_MAGIC;
cqr->startdev = device;
cqr->memdev = device;
@@ -784,7 +841,30 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
cqr->retries = 256;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
- return cqr;
+ set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
+}
+
+static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
+ struct dasd_ccw_req *cqr,
+ __u8 *rcd_buffer,
+ __u8 lpm)
+{
+ struct ciw *ciw;
+ int rc;
+ /*
+ * sanity check: scan for RCD command in extended SenseID data
+ * some devices do not support RCD
+ */
+ ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
+ if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD)
+ return -EOPNOTSUPP;
+
+ dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buffer, lpm);
+ clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+ set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
+ cqr->retries = 5;
+ rc = dasd_sleep_on_immediatly(cqr);
+ return rc;
}
static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
@@ -797,32 +877,29 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
struct dasd_ccw_req *cqr;
/*
- * scan for RCD command in extended SenseID data
+ * sanity check: scan for RCD command in extended SenseID data
+ * some devices do not support RCD
*/
ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
- if (!ciw || ciw->cmd == 0) {
+ if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD) {
ret = -EOPNOTSUPP;
goto out_error;
}
- rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
+ rcd_buf = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL | GFP_DMA);
if (!rcd_buf) {
ret = -ENOMEM;
goto out_error;
}
-
- /*
- * buffer has to start with EBCDIC "V1.0" to show
- * support for virtual device SNEQ
- */
- rcd_buf[0] = 0xE5;
- rcd_buf[1] = 0xF1;
- rcd_buf[2] = 0x4B;
- rcd_buf[3] = 0xF0;
- cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm);
+ cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* RCD */,
+ 0, /* use rcd_buf as data ara */
+ device);
if (IS_ERR(cqr)) {
- ret = PTR_ERR(cqr);
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Could not allocate RCD request");
+ ret = -ENOMEM;
goto out_error;
}
+ dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
ret = dasd_sleep_on(cqr);
/*
* on success we update the user input parms
@@ -831,7 +908,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
if (ret)
goto out_error;
- *rcd_buffer_size = ciw->count;
+ *rcd_buffer_size = DASD_ECKD_RCD_DATA_SIZE;
*rcd_buffer = rcd_buf;
return 0;
out_error:
@@ -901,18 +978,18 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
void *conf_data;
int conf_len, conf_data_saved;
int rc;
- __u8 lpm;
+ __u8 lpm, opm;
struct dasd_eckd_private *private;
- struct dasd_eckd_path *path_data;
+ struct dasd_path *path_data;
private = (struct dasd_eckd_private *) device->private;
- path_data = (struct dasd_eckd_path *) &private->path_data;
- path_data->opm = ccw_device_get_path_mask(device->cdev);
+ path_data = &device->path_data;
+ opm = ccw_device_get_path_mask(device->cdev);
lpm = 0x80;
conf_data_saved = 0;
/* get configuration data per operational path */
for (lpm = 0x80; lpm; lpm>>= 1) {
- if (lpm & path_data->opm){
+ if (lpm & opm) {
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
&conf_len, lpm);
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
@@ -925,6 +1002,8 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
"No configuration data "
"retrieved");
+ /* no further analysis possible */
+ path_data->opm |= lpm;
continue; /* no error */
}
/* save first valid configuration data */
@@ -948,6 +1027,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
path_data->ppm |= lpm;
break;
}
+ path_data->opm |= lpm;
if (conf_data != private->conf_data)
kfree(conf_data);
}
@@ -955,6 +1035,140 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
return 0;
}
+static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
+{
+ struct dasd_eckd_private *private;
+ int mdc;
+ u32 fcx_max_data;
+
+ private = (struct dasd_eckd_private *) device->private;
+ if (private->fcx_max_data) {
+ mdc = ccw_device_get_mdc(device->cdev, lpm);
+ if ((mdc < 0)) {
+ dev_warn(&device->cdev->dev,
+ "Detecting the maximum data size for zHPF "
+ "requests failed (rc=%d) for a new path %x\n",
+ mdc, lpm);
+ return mdc;
+ }
+ fcx_max_data = mdc * FCX_MAX_DATA_FACTOR;
+ if (fcx_max_data < private->fcx_max_data) {
+ dev_warn(&device->cdev->dev,
+ "The maximum data size for zHPF requests %u "
+ "on a new path %x is below the active maximum "
+ "%u\n", fcx_max_data, lpm,
+ private->fcx_max_data);
+ return -EACCES;
+ }
+ }
+ return 0;
+}
+
+static void do_path_verification_work(struct work_struct *work)
+{
+ struct path_verification_work_data *data;
+ struct dasd_device *device;
+ __u8 lpm, opm, npm, ppm, epm;
+ unsigned long flags;
+ int rc;
+
+ data = container_of(work, struct path_verification_work_data, worker);
+ device = data->device;
+
+ opm = 0;
+ npm = 0;
+ ppm = 0;
+ epm = 0;
+ for (lpm = 0x80; lpm; lpm >>= 1) {
+ if (lpm & data->tbvpm) {
+ memset(data->rcd_buffer, 0, sizeof(data->rcd_buffer));
+ memset(&data->cqr, 0, sizeof(data->cqr));
+ data->cqr.cpaddr = &data->ccw;
+ rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
+ data->rcd_buffer,
+ lpm);
+ if (!rc) {
+ switch (dasd_eckd_path_access(data->rcd_buffer,
+ DASD_ECKD_RCD_DATA_SIZE)) {
+ case 0x02:
+ npm |= lpm;
+ break;
+ case 0x03:
+ ppm |= lpm;
+ break;
+ }
+ opm |= lpm;
+ } else if (rc == -EOPNOTSUPP) {
+ DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+ "path verification: No configuration "
+ "data retrieved");
+ opm |= lpm;
+ } else if (rc == -EAGAIN) {
+ DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+ "path verification: device is stopped,"
+ " try again later");
+ epm |= lpm;
+ } else {
+ dev_warn(&device->cdev->dev,
+ "Reading device feature codes failed "
+ "(rc=%d) for new path %x\n", rc, lpm);
+ continue;
+ }
+ if (verify_fcx_max_data(device, lpm)) {
+ opm &= ~lpm;
+ npm &= ~lpm;
+ ppm &= ~lpm;
+ }
+ }
+ }
+ /*
+ * There is a small chance that a path is lost again between
+ * above path verification and the following modification of
+ * the device opm mask. We could avoid that race here by using
+ * yet another path mask, but we rather deal with this unlikely
+ * situation in dasd_start_IO.
+ */
+ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+ if (!device->path_data.opm && opm) {
+ device->path_data.opm = opm;
+ dasd_generic_path_operational(device);
+ } else
+ device->path_data.opm |= opm;
+ device->path_data.npm |= npm;
+ device->path_data.ppm |= ppm;
+ device->path_data.tbvpm |= epm;
+ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+
+ dasd_put_device(device);
+ if (data->isglobal)
+ mutex_unlock(&dasd_path_verification_mutex);
+ else
+ kfree(data);
+}
+
+static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm)
+{
+ struct path_verification_work_data *data;
+
+ data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);
+ if (!data) {
+ if (mutex_trylock(&dasd_path_verification_mutex)) {
+ data = path_verification_worker;
+ data->isglobal = 1;
+ } else
+ return -ENOMEM;
+ } else {
+ memset(data, 0, sizeof(*data));
+ data->isglobal = 0;
+ }
+ INIT_WORK(&data->worker, do_path_verification_work);
+ dasd_get_device(device);
+ data->device = device;
+ data->tbvpm = lpm;
+ schedule_work(&data->worker);
+ return 0;
+}
+
static int dasd_eckd_read_features(struct dasd_device *device)
{
struct dasd_psf_prssd_data *prssdp;
@@ -1105,6 +1319,37 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
"returned rc=%d", private->uid.ssid, rc);
}
+static u32 get_fcx_max_data(struct dasd_device *device)
+{
+#if defined(CONFIG_64BIT)
+ int tpm, mdc;
+ int fcx_in_css, fcx_in_gneq, fcx_in_features;
+ struct dasd_eckd_private *private;
+
+ if (dasd_nofcx)
+ return 0;
+ /* is transport mode supported? */
+ private = (struct dasd_eckd_private *) device->private;
+ fcx_in_css = css_general_characteristics.fcx;
+ fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+ fcx_in_features = private->features.feature[40] & 0x80;
+ tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+ if (!tpm)
+ return 0;
+
+ mdc = ccw_device_get_mdc(device->cdev, 0);
+ if (mdc < 0) {
+ dev_warn(&device->cdev->dev, "Detecting the maximum supported"
+ " data size for zHPF requests failed\n");
+ return 0;
+ } else
+ return mdc * FCX_MAX_DATA_FACTOR;
+#else
+ return 0;
+#endif
+}
+
/*
* Check device characteristics.
* If the device is accessible using ECKD discipline, the device is enabled.
@@ -1223,6 +1468,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
else
private->real_cyl = private->rdc_data.no_cyl;
+ private->fcx_max_data = get_fcx_max_data(device);
+
readonly = dasd_device_is_ro(device);
if (readonly)
set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
@@ -1404,6 +1651,13 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
dasd_sfree_request(init_cqr, device);
}
+ if (device->features & DASD_FEATURE_USERAW) {
+ block->bp_block = DASD_RAW_BLOCKSIZE;
+ blk_per_trk = DASD_RAW_BLOCK_PER_TRACK;
+ block->s2b_shift = 3;
+ goto raw;
+ }
+
if (status == INIT_CQR_UNFORMATTED) {
dev_warn(&device->cdev->dev, "The DASD is not formatted\n");
return -EMEDIUMTYPE;
@@ -1441,6 +1695,7 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
dev_warn(&device->cdev->dev,
"Track 0 has no records following the VTOC\n");
}
+
if (count_area != NULL && count_area->kl == 0) {
/* we found notthing violating our disk layout */
if (dasd_check_blocksize(count_area->dl) == 0)
@@ -1456,6 +1711,8 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
block->s2b_shift++;
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
+
+raw:
block->blocks = (private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk);
@@ -1716,6 +1973,7 @@ static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
if (cqr->block && (cqr->startdev != cqr->block->base)) {
dasd_eckd_reset_ccw_to_base_io(cqr);
cqr->startdev = cqr->block->base;
+ cqr->lpm = cqr->block->base->path_data.opm;
}
};
@@ -1744,9 +2002,9 @@ dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)
return dasd_default_erp_postaction;
}
-
-static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
- struct irb *irb)
+static void dasd_eckd_check_for_device_change(struct dasd_device *device,
+ struct dasd_ccw_req *cqr,
+ struct irb *irb)
{
char mask;
char *sense = NULL;
@@ -1770,40 +2028,41 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
/* schedule worker to reload device */
dasd_reload_device(device);
}
-
dasd_generic_handle_state_change(device);
return;
}
- /* summary unit check */
sense = dasd_get_sense(irb);
- if (sense && (sense[7] == 0x0D) &&
+ if (!sense)
+ return;
+
+ /* summary unit check */
+ if ((sense[7] == 0x0D) &&
(scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {
dasd_alias_handle_summary_unit_check(device, irb);
return;
}
/* service information message SIM */
- if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+ if (!cqr && !(sense[27] & DASD_SENSE_BIT_0) &&
((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
dasd_3990_erp_handle_sim(device, sense);
- dasd_schedule_device_bh(device);
return;
}
- if ((scsw_cc(&irb->scsw) == 1) && !sense &&
- (scsw_fctl(&irb->scsw) == SCSW_FCTL_START_FUNC) &&
- (scsw_actl(&irb->scsw) == SCSW_ACTL_START_PEND) &&
- (scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND)) {
- /* fake irb do nothing, they are handled elsewhere */
- dasd_schedule_device_bh(device);
- return;
+ /* loss of device reservation is handled via base devices only
+ * as alias devices may be used with several bases
+ */
+ if (device->block && (sense[7] == 0x3F) &&
+ (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
+ test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) {
+ if (device->features & DASD_FEATURE_FAILONSLCK)
+ set_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
+ clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
+ dev_err(&device->cdev->dev,
+ "The device reservation was lost\n");
}
-
- dasd_schedule_device_bh(device);
- return;
-};
-
+}
static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
struct dasd_device *startdev,
@@ -1984,7 +2243,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
cqr->memdev = startdev;
cqr->block = block;
cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
- cqr->lpm = private->path_data.ppm;
+ cqr->lpm = startdev->path_data.ppm;
cqr->retries = 256;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@@ -2161,7 +2420,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
cqr->memdev = startdev;
cqr->block = block;
cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
- cqr->lpm = private->path_data.ppm;
+ cqr->lpm = startdev->path_data.ppm;
cqr->retries = 256;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@@ -2326,6 +2585,12 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
struct tidaw *last_tidaw = NULL;
int itcw_op;
size_t itcw_size;
+ u8 tidaw_flags;
+ unsigned int seg_len, part_len, len_to_track_end;
+ unsigned char new_track;
+ sector_t recid, trkid;
+ unsigned int offs;
+ unsigned int count, count_to_trk_end;
basedev = block->base;
private = (struct dasd_eckd_private *) basedev->private;
@@ -2341,12 +2606,16 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
/* trackbased I/O needs address all memory via TIDAWs,
* not just for 64 bit addresses. This allows us to map
* each segment directly to one tidaw.
+ * In the case of write requests, additional tidaws may
+ * be needed when a segment crosses a track boundary.
*/
trkcount = last_trk - first_trk + 1;
ctidaw = 0;
rq_for_each_segment(bv, req, iter) {
++ctidaw;
}
+ if (rq_data_dir(req) == WRITE)
+ ctidaw += (last_trk - first_trk);
/* Allocate the ccw request. */
itcw_size = itcw_calc_size(0, ctidaw, 0);
@@ -2354,15 +2623,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
if (IS_ERR(cqr))
return cqr;
- cqr->cpmode = 1;
- cqr->startdev = startdev;
- cqr->memdev = startdev;
- cqr->block = block;
- cqr->expires = 100*HZ;
- cqr->buildclk = get_clock();
- cqr->status = DASD_CQR_FILLED;
- cqr->retries = 10;
-
/* transfer length factor: how many bytes to read from the last track */
if (first_trk == last_trk)
tlf = last_offs - first_offs + 1;
@@ -2371,8 +2631,11 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
tlf *= blksize;
itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+ if (IS_ERR(itcw)) {
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EINVAL);
+ }
cqr->cpaddr = itcw_get_tcw(itcw);
-
if (prepare_itcw(itcw, first_trk, last_trk,
cmd, basedev, startdev,
first_offs + 1,
@@ -2385,31 +2648,69 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
dasd_sfree_request(cqr, startdev);
return ERR_PTR(-EAGAIN);
}
-
/*
* A tidaw can address 4k of memory, but must not cross page boundaries
* We can let the block layer handle this by setting
* blk_queue_segment_boundary to page boundaries and
* blk_max_segment_size to page size when setting up the request queue.
+ * For write requests, a TIDAW must not cross track boundaries, because
+ * we have to set the CBC flag on the last tidaw for each track.
*/
- rq_for_each_segment(bv, req, iter) {
- dst = page_address(bv->bv_page) + bv->bv_offset;
- last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
- if (IS_ERR(last_tidaw))
- return (struct dasd_ccw_req *)last_tidaw;
+ if (rq_data_dir(req) == WRITE) {
+ new_track = 1;
+ recid = first_rec;
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ seg_len = bv->bv_len;
+ while (seg_len) {
+ if (new_track) {
+ trkid = recid;
+ offs = sector_div(trkid, blk_per_trk);
+ count_to_trk_end = blk_per_trk - offs;
+ count = min((last_rec - recid + 1),
+ (sector_t)count_to_trk_end);
+ len_to_track_end = count * blksize;
+ recid += count;
+ new_track = 0;
+ }
+ part_len = min(seg_len, len_to_track_end);
+ seg_len -= part_len;
+ len_to_track_end -= part_len;
+ /* We need to end the tidaw at track end */
+ if (!len_to_track_end) {
+ new_track = 1;
+ tidaw_flags = TIDAW_FLAGS_INSERT_CBC;
+ } else
+ tidaw_flags = 0;
+ last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
+ dst, part_len);
+ if (IS_ERR(last_tidaw))
+ return ERR_PTR(-EINVAL);
+ dst += part_len;
+ }
+ }
+ } else {
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ last_tidaw = itcw_add_tidaw(itcw, 0x00,
+ dst, bv->bv_len);
+ if (IS_ERR(last_tidaw))
+ return ERR_PTR(-EINVAL);
+ }
}
-
- last_tidaw->flags |= 0x80;
+ last_tidaw->flags |= TIDAW_FLAGS_LAST;
+ last_tidaw->flags &= ~TIDAW_FLAGS_INSERT_CBC;
itcw_finalize(itcw);
if (blk_noretry_request(req) ||
block->base->features & DASD_FEATURE_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->cpmode = 1;
cqr->startdev = startdev;
cqr->memdev = startdev;
cqr->block = block;
cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
- cqr->lpm = private->path_data.ppm;
+ cqr->lpm = startdev->path_data.ppm;
cqr->retries = 256;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@@ -2420,11 +2721,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
struct dasd_block *block,
struct request *req)
{
- int tpm, cmdrtd, cmdwtd;
+ int cmdrtd, cmdwtd;
int use_prefix;
-#if defined(CONFIG_64BIT)
- int fcx_in_css, fcx_in_gneq, fcx_in_features;
-#endif
+ int fcx_multitrack;
struct dasd_eckd_private *private;
struct dasd_device *basedev;
sector_t first_rec, last_rec;
@@ -2432,6 +2731,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
unsigned int first_offs, last_offs;
unsigned int blk_per_trk, blksize;
int cdlspecial;
+ unsigned int data_size;
struct dasd_ccw_req *cqr;
basedev = block->base;
@@ -2450,15 +2750,11 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
last_offs = sector_div(last_trk, blk_per_trk);
cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
- /* is transport mode supported? */
-#if defined(CONFIG_64BIT)
- fcx_in_css = css_general_characteristics.fcx;
- fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
- fcx_in_features = private->features.feature[40] & 0x80;
- tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
-#else
- tpm = 0;
-#endif
+ fcx_multitrack = private->features.feature[40] & 0x20;
+ data_size = blk_rq_bytes(req);
+ /* tpm write request add CBC data on each track boundary */
+ if (rq_data_dir(req) == WRITE)
+ data_size += (last_trk - first_trk) * 4;
/* is read track data and write track data in command mode supported? */
cmdrtd = private->features.feature[9] & 0x20;
@@ -2468,13 +2764,15 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
cqr = NULL;
if (cdlspecial || dasd_page_cache) {
/* do nothing, just fall through to the cmd mode single case */
- } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+ } else if ((data_size <= private->fcx_max_data)
+ && (fcx_multitrack || (first_trk == last_trk))) {
cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
first_rec, last_rec,
first_trk, last_trk,
first_offs, last_offs,
blk_per_trk, blksize);
- if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
+ (PTR_ERR(cqr) != -ENOMEM))
cqr = NULL;
} else if (use_prefix &&
(((rq_data_dir(req) == READ) && cmdrtd) ||
@@ -2484,7 +2782,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
first_trk, last_trk,
first_offs, last_offs,
blk_per_trk, blksize);
- if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
+ (PTR_ERR(cqr) != -ENOMEM))
cqr = NULL;
}
if (!cqr)
@@ -2496,6 +2795,135 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
return cqr;
}
+static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ struct dasd_eckd_private *private;
+ unsigned long *idaws;
+ struct dasd_device *basedev;
+ struct dasd_ccw_req *cqr;
+ struct ccw1 *ccw;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst;
+ unsigned char cmd;
+ unsigned int trkcount;
+ unsigned int seg_len, len_to_track_end;
+ unsigned int first_offs;
+ unsigned int cidaw, cplength, datasize;
+ sector_t first_trk, last_trk;
+ unsigned int pfx_datasize;
+
+ /*
+ * raw track access needs to be mutiple of 64k and on 64k boundary
+ */
+ if ((blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK) != 0) {
+ cqr = ERR_PTR(-EINVAL);
+ goto out;
+ }
+ if (((blk_rq_pos(req) + blk_rq_sectors(req)) %
+ DASD_RAW_SECTORS_PER_TRACK) != 0) {
+ cqr = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
+ first_trk = blk_rq_pos(req) / DASD_RAW_SECTORS_PER_TRACK;
+ last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
+ DASD_RAW_SECTORS_PER_TRACK;
+ trkcount = last_trk - first_trk + 1;
+ first_offs = 0;
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+
+ if (rq_data_dir(req) == READ)
+ cmd = DASD_ECKD_CCW_READ_TRACK;
+ else if (rq_data_dir(req) == WRITE)
+ cmd = DASD_ECKD_CCW_WRITE_FULL_TRACK;
+ else {
+ cqr = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
+ /*
+ * Raw track based I/O needs IDAWs for each page,
+ * and not just for 64 bit addresses.
+ */
+ cidaw = trkcount * DASD_RAW_BLOCK_PER_TRACK;
+
+ /* 1x prefix + one read/write ccw per track */
+ cplength = 1 + trkcount;
+
+ /*
+ * struct PFX_eckd_data has up to 2 byte as extended parameter
+ * this is needed for write full track and has to be mentioned
+ * seperately
+ * add 8 instead of 2 to keep 8 byte boundary
+ */
+ pfx_datasize = sizeof(struct PFX_eckd_data) + 8;
+
+ datasize = pfx_datasize + cidaw * sizeof(unsigned long long);
+
+ /* Allocate the ccw request. */
+ cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength,
+ datasize, startdev);
+ if (IS_ERR(cqr))
+ goto out;
+ ccw = cqr->cpaddr;
+
+ if (prefix_LRE(ccw++, cqr->data, first_trk, last_trk, cmd,
+ basedev, startdev, 1 /* format */, first_offs + 1,
+ trkcount, 0, 0) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ cqr = ERR_PTR(-EAGAIN);
+ goto out;
+ }
+
+ idaws = (unsigned long *)(cqr->data + pfx_datasize);
+
+ len_to_track_end = 0;
+
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ seg_len = bv->bv_len;
+ if (!len_to_track_end) {
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw->cmd_code = cmd;
+ /* maximum 3390 track size */
+ ccw->count = 57326;
+ /* 64k map to one track */
+ len_to_track_end = 65536;
+ ccw->cda = (__u32)(addr_t)idaws;
+ ccw->flags |= CCW_FLAG_IDA;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw++;
+ }
+ len_to_track_end -= seg_len;
+ idaws = idal_create_words(idaws, dst, seg_len);
+ }
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = startdev->default_expires * HZ;
+ cqr->lpm = startdev->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+out:
+ return cqr;
+}
+
+
static int
dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{
@@ -2600,7 +3028,10 @@ static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,
spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags);
private->count++;
- cqr = dasd_eckd_build_cp(startdev, block, req);
+ if ((base->features & DASD_FEATURE_USERAW))
+ cqr = dasd_raw_build_cp(startdev, block, req);
+ else
+ cqr = dasd_eckd_build_cp(startdev, block, req);
if (IS_ERR(cqr))
private->count--;
spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags);
@@ -2688,6 +3119,8 @@ dasd_eckd_release(struct dasd_device *device)
cqr->status = DASD_CQR_FILLED;
rc = dasd_sleep_on_immediatly(cqr);
+ if (!rc)
+ clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
if (useglobal)
mutex_unlock(&dasd_reserve_mutex);
@@ -2741,6 +3174,8 @@ dasd_eckd_reserve(struct dasd_device *device)
cqr->status = DASD_CQR_FILLED;
rc = dasd_sleep_on_immediatly(cqr);
+ if (!rc)
+ set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
if (useglobal)
mutex_unlock(&dasd_reserve_mutex);
@@ -2793,6 +3228,8 @@ dasd_eckd_steal_lock(struct dasd_device *device)
cqr->status = DASD_CQR_FILLED;
rc = dasd_sleep_on_immediatly(cqr);
+ if (!rc)
+ set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
if (useglobal)
mutex_unlock(&dasd_reserve_mutex);
@@ -2845,6 +3282,7 @@ static int dasd_eckd_snid(struct dasd_device *device,
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
cqr->retries = 5;
cqr->expires = 10 * HZ;
cqr->buildclk = get_clock();
@@ -3279,10 +3717,8 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
{
char *page;
int len, sl, sct, residual;
-
struct tsb *tsb;
- u8 *sense;
-
+ u8 *sense, *rcq;
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
@@ -3348,12 +3784,15 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
case 2: /* ts_ddpc */
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
- len += sprintf(page + len, KERN_ERR PRINTK_HEADER
- " tsb->tsa.ddpc.rcq: ");
- for (sl = 0; sl < 16; sl++) {
+ for (sl = 0; sl < 2; sl++) {
+ len += sprintf(page + len,
+ KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rcq %2d-%2d: ",
+ (8 * sl), ((8 * sl) + 7));
+ rcq = tsb->tsa.ddpc.rcq;
for (sct = 0; sct < 8; sct++) {
len += sprintf(page + len, " %02x",
- tsb->tsa.ddpc.rcq[sl]);
+ rcq[8 * sl + sct]);
}
len += sprintf(page + len, "\n");
}
@@ -3550,6 +3989,7 @@ static struct ccw_driver dasd_eckd_driver = {
.set_offline = dasd_generic_set_offline,
.set_online = dasd_eckd_set_online,
.notify = dasd_generic_notify,
+ .path_event = dasd_generic_path_event,
.freeze = dasd_generic_pm_freeze,
.thaw = dasd_generic_restore_device,
.restore = dasd_generic_restore_device,
@@ -3573,10 +4013,11 @@ static struct dasd_discipline dasd_eckd_discipline = {
.owner = THIS_MODULE,
.name = "ECKD",
.ebcname = "ECKD",
- .max_blocks = 240,
+ .max_blocks = 190,
.check_device = dasd_eckd_check_characteristics,
.uncheck_device = dasd_eckd_uncheck_device,
.do_analysis = dasd_eckd_do_analysis,
+ .verify_path = dasd_eckd_verify_path,
.ready_to_online = dasd_eckd_ready_to_online,
.online_to_ready = dasd_eckd_online_to_ready,
.fill_geometry = dasd_eckd_fill_geometry,
@@ -3586,7 +4027,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.format_device = dasd_eckd_format_device,
.erp_action = dasd_eckd_erp_action,
.erp_postaction = dasd_eckd_erp_postaction,
- .handle_unsolicited_interrupt = dasd_eckd_handle_unsolicited_interrupt,
+ .check_for_device_change = dasd_eckd_check_for_device_change,
.build_cp = dasd_eckd_build_alias_cp,
.free_cp = dasd_eckd_free_alias_cp,
.dump_sense = dasd_eckd_dump_sense,
@@ -3609,11 +4050,19 @@ dasd_eckd_init(void)
GFP_KERNEL | GFP_DMA);
if (!dasd_reserve_req)
return -ENOMEM;
+ path_verification_worker = kmalloc(sizeof(*path_verification_worker),
+ GFP_KERNEL | GFP_DMA);
+ if (!path_verification_worker) {
+ kfree(dasd_reserve_req);
+ return -ENOMEM;
+ }
ret = ccw_driver_register(&dasd_eckd_driver);
if (!ret)
wait_for_device_probe();
- else
+ else {
+ kfree(path_verification_worker);
kfree(dasd_reserve_req);
+ }
return ret;
}
@@ -3621,6 +4070,7 @@ static void __exit
dasd_eckd_cleanup(void)
{
ccw_driver_unregister(&dasd_eckd_driver);
+ kfree(path_verification_worker);
kfree(dasd_reserve_req);
}
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 12097c24f2f5..4a688a873a77 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -37,14 +37,17 @@
#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
#define DASD_ECKD_CCW_READ_KD_MT 0x8e
#define DASD_ECKD_CCW_RELEASE 0x94
+#define DASD_ECKD_CCW_WRITE_FULL_TRACK 0x95
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
#define DASD_ECKD_CCW_RESERVE 0xB4
+#define DASD_ECKD_CCW_READ_TRACK 0xDE
#define DASD_ECKD_CCW_PFX 0xE7
#define DASD_ECKD_CCW_PFX_READ 0xEA
#define DASD_ECKD_CCW_RSCK 0xF9
+#define DASD_ECKD_CCW_RCD 0xFA
/*
* Perform Subsystem Function / Sub-Orders
@@ -57,6 +60,11 @@
*/
#define LV_COMPAT_CYL 0xFFFE
+
+#define FCX_MAX_DATA_FACTOR 65536
+#define DASD_ECKD_RCD_DATA_SIZE 256
+
+
/*****************************************************************************
* SECTION: Type Definitions
****************************************************************************/
@@ -331,12 +339,6 @@ struct dasd_gneq {
__u8 reserved2[22];
} __attribute__ ((packed));
-struct dasd_eckd_path {
- __u8 opm;
- __u8 ppm;
- __u8 npm;
-};
-
struct dasd_rssd_features {
char feature[256];
} __attribute__((packed));
@@ -442,7 +444,6 @@ struct dasd_eckd_private {
struct vd_sneq *vdsneq;
struct dasd_gneq *gneq;
- struct dasd_eckd_path path_data;
struct eckd_count count_area[5];
int init_cqr_status;
int uses_cdl;
@@ -455,6 +456,8 @@ struct dasd_eckd_private {
struct alias_pav_group *pavgroup;
struct alias_lcu *lcu;
int count;
+
+ u32 fcx_max_data;
};
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 83b4615a3b62..77f778b7b070 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -473,6 +473,7 @@ int dasd_eer_enable(struct dasd_device *device)
cqr->retries = 255;
cqr->expires = 10 * HZ;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+ set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_SNSS;
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 7656384a811d..0eafe2e421e7 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -96,7 +96,8 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP called (%i retries left)",
cqr->retries);
- cqr->lpm = LPM_ANYPATH;
+ if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
+ cqr->lpm = device->path_data.opm;
cqr->status = DASD_CQR_FILLED;
} else {
pr_err("%s: default ERP has run out of retries and failed\n",
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index bec5486e0e6d..be89b3a893da 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -73,6 +73,7 @@ static struct ccw_driver dasd_fba_driver = {
.set_offline = dasd_generic_set_offline,
.set_online = dasd_fba_set_online,
.notify = dasd_generic_notify,
+ .path_event = dasd_generic_path_event,
.freeze = dasd_generic_pm_freeze,
.thaw = dasd_generic_restore_device,
.restore = dasd_generic_restore_device,
@@ -164,6 +165,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
}
device->default_expires = DASD_EXPIRES;
+ device->path_data.opm = LPM_ANYPATH;
readonly = dasd_device_is_ro(device);
if (readonly)
@@ -231,24 +233,16 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr)
return NULL;
}
-static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
- struct irb *irb)
+static void dasd_fba_check_for_device_change(struct dasd_device *device,
+ struct dasd_ccw_req *cqr,
+ struct irb *irb)
{
char mask;
/* first of all check for state change pending interrupt */
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
- if ((irb->scsw.cmd.dstat & mask) == mask) {
+ if ((irb->scsw.cmd.dstat & mask) == mask)
dasd_generic_handle_state_change(device);
- return;
- }
-
- /* check for unsolicited interrupts */
- DBF_DEV_EVENT(DBF_WARNING, device, "%s",
- "unsolicited interrupt received");
- device->discipline->dump_sense_dbf(device, irb, "unsolicited");
- dasd_schedule_device_bh(device);
- return;
};
static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
@@ -596,13 +590,14 @@ static struct dasd_discipline dasd_fba_discipline = {
.max_blocks = 96,
.check_device = dasd_fba_check_characteristics,
.do_analysis = dasd_fba_do_analysis,
+ .verify_path = dasd_generic_verify_path,
.fill_geometry = dasd_fba_fill_geometry,
.start_IO = dasd_start_IO,
.term_IO = dasd_term_IO,
.handle_terminated_request = dasd_fba_handle_terminated_request,
.erp_action = dasd_fba_erp_action,
.erp_postaction = dasd_fba_erp_postaction,
- .handle_unsolicited_interrupt = dasd_fba_handle_unsolicited_interrupt,
+ .check_for_device_change = dasd_fba_check_for_device_change,
.build_cp = dasd_fba_build_cp,
.free_cp = dasd_fba_free_cp,
.dump_sense = dasd_fba_dump_sense,
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 30a1ca3d08b7..5505bc07e1e7 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block)
struct block_device *bdev;
bdev = bdget_disk(block->gdp, 0);
- if (!bdev || blkdev_get(bdev, FMODE_READ) < 0)
+ if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0)
return -ENODEV;
/*
* See fs/partition/check.c:register_disk,rescan_partitions
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 500678d7116c..df9f6999411d 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -231,6 +231,11 @@ struct dasd_ccw_req {
/* per dasd_ccw_req flags */
#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */
#define DASD_CQR_FLAGS_FAILFAST 1 /* FAILFAST */
+#define DASD_CQR_VERIFY_PATH 2 /* path verification request */
+#define DASD_CQR_ALLOW_SLOCK 3 /* Try this request even when lock was
+ * stolen. Should not be combined with
+ * DASD_CQR_FLAGS_USE_ERP
+ */
/* Signature for error recovery functions. */
typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
@@ -287,6 +292,14 @@ struct dasd_discipline {
int (*do_analysis) (struct dasd_block *);
/*
+ * This function is called, when new paths become available.
+ * Disciplins may use this callback to do necessary setup work,
+ * e.g. verify that new path is compatible with the current
+ * configuration.
+ */
+ int (*verify_path)(struct dasd_device *, __u8);
+
+ /*
* Last things to do when a device is set online, and first things
* when it is set offline.
*/
@@ -325,9 +338,9 @@ struct dasd_discipline {
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
struct irb *);
void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);
-
- void (*handle_unsolicited_interrupt) (struct dasd_device *,
- struct irb *);
+ void (*check_for_device_change) (struct dasd_device *,
+ struct dasd_ccw_req *,
+ struct irb *);
/* i/o control functions. */
int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
@@ -362,6 +375,13 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer;
#define DASD_EER_STATECHANGE 3
#define DASD_EER_PPRCSUSPEND 4
+struct dasd_path {
+ __u8 opm;
+ __u8 tbvpm;
+ __u8 ppm;
+ __u8 npm;
+};
+
struct dasd_device {
/* Block device stuff. */
struct dasd_block *block;
@@ -377,6 +397,7 @@ struct dasd_device {
struct dasd_discipline *discipline;
struct dasd_discipline *base_discipline;
char *private;
+ struct dasd_path path_data;
/* Device state and target state. */
int state, target;
@@ -456,6 +477,9 @@ struct dasd_block {
* confuse this with the user specified
* read-only feature.
*/
+#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */
+#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */
+
void dasd_put_device_wake(struct dasd_device *);
@@ -620,10 +644,15 @@ void dasd_generic_remove (struct ccw_device *cdev);
int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
int dasd_generic_set_offline (struct ccw_device *cdev);
int dasd_generic_notify(struct ccw_device *, int);
+int dasd_generic_last_path_gone(struct dasd_device *);
+int dasd_generic_path_operational(struct dasd_device *);
+
void dasd_generic_handle_state_change(struct dasd_device *);
int dasd_generic_pm_freeze(struct ccw_device *);
int dasd_generic_restore_device(struct ccw_device *);
enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *);
+void dasd_generic_path_event(struct ccw_device *, int *);
+int dasd_generic_verify_path(struct dasd_device *, __u8);
int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
char *dasd_get_sense(struct irb *);
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index 40834f18754c..dcee3c5c8954 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -2,76 +2,85 @@ comment "S/390 character device drivers"
depends on S390
config TN3270
- tristate "Support for locally attached 3270 terminals"
+ def_tristate y
+ prompt "Support for locally attached 3270 terminals"
depends on CCW
help
Include support for IBM 3270 terminals.
config TN3270_TTY
- tristate "Support for tty input/output on 3270 terminals"
+ def_tristate y
+ prompt "Support for tty input/output on 3270 terminals"
depends on TN3270
help
Include support for using an IBM 3270 terminal as a Linux tty.
config TN3270_FS
- tristate "Support for fullscreen applications on 3270 terminals"
+ def_tristate m
+ prompt "Support for fullscreen applications on 3270 terminals"
depends on TN3270
help
Include support for fullscreen applications on an IBM 3270 terminal.
config TN3270_CONSOLE
- bool "Support for console on 3270 terminal"
+ def_bool y
+ prompt "Support for console on 3270 terminal"
depends on TN3270=y && TN3270_TTY=y
help
Include support for using an IBM 3270 terminal as a Linux system
console. Available only if 3270 support is compiled in statically.
config TN3215
- bool "Support for 3215 line mode terminal"
+ def_bool y
+ prompt "Support for 3215 line mode terminal"
depends on CCW
help
Include support for IBM 3215 line-mode terminals.
config TN3215_CONSOLE
- bool "Support for console on 3215 line mode terminal"
+ def_bool y
+ prompt "Support for console on 3215 line mode terminal"
depends on TN3215
help
Include support for using an IBM 3215 line-mode terminal as a
Linux system console.
config CCW_CONSOLE
- bool
- depends on TN3215_CONSOLE || TN3270_CONSOLE
- default y
+ def_bool y if TN3215_CONSOLE || TN3270_CONSOLE
config SCLP_TTY
- bool "Support for SCLP line mode terminal"
+ def_bool y
+ prompt "Support for SCLP line mode terminal"
depends on S390
help
Include support for IBM SCLP line-mode terminals.
config SCLP_CONSOLE
- bool "Support for console on SCLP line mode terminal"
+ def_bool y
+ prompt "Support for console on SCLP line mode terminal"
depends on SCLP_TTY
help
Include support for using an IBM HWC line-mode terminal as the Linux
system console.
config SCLP_VT220_TTY
- bool "Support for SCLP VT220-compatible terminal"
+ def_bool y
+ prompt "Support for SCLP VT220-compatible terminal"
depends on S390
help
Include support for an IBM SCLP VT220-compatible terminal.
config SCLP_VT220_CONSOLE
- bool "Support for console on SCLP VT220-compatible terminal"
+ def_bool y
+ prompt "Support for console on SCLP VT220-compatible terminal"
depends on SCLP_VT220_TTY
help
Include support for using an IBM SCLP VT220-compatible terminal as a
Linux system console.
config SCLP_CPI
- tristate "Control-Program Identification"
+ def_tristate m
+ prompt "Control-Program Identification"
depends on S390
help
This option enables the hardware console interface for system
@@ -83,7 +92,8 @@ config SCLP_CPI
need this feature and intend to run your kernel in LPAR.
config SCLP_ASYNC
- tristate "Support for Call Home via Asynchronous SCLP Records"
+ def_tristate m
+ prompt "Support for Call Home via Asynchronous SCLP Records"
depends on S390
help
This option enables the call home function, which is able to inform
@@ -93,7 +103,8 @@ config SCLP_ASYNC
need this feature and intend to run your kernel in LPAR.
config S390_TAPE
- tristate "S/390 tape device support"
+ def_tristate m
+ prompt "S/390 tape device support"
depends on CCW
help
Select this option if you want to access channel-attached tape
@@ -109,7 +120,8 @@ comment "S/390 tape interface support"
depends on S390_TAPE
config S390_TAPE_BLOCK
- bool "Support for tape block devices"
+ def_bool y
+ prompt "Support for tape block devices"
depends on S390_TAPE && BLOCK
help
Select this option if you want to access your channel-attached tape
@@ -123,7 +135,8 @@ comment "S/390 tape hardware support"
depends on S390_TAPE
config S390_TAPE_34XX
- tristate "Support for 3480/3490 tape hardware"
+ def_tristate m
+ prompt "Support for 3480/3490 tape hardware"
depends on S390_TAPE
help
Select this option if you want to access IBM 3480/3490 magnetic
@@ -131,7 +144,8 @@ config S390_TAPE_34XX
It is safe to say "Y" here.
config S390_TAPE_3590
- tristate "Support for 3590 tape hardware"
+ def_tristate m
+ prompt "Support for 3590 tape hardware"
depends on S390_TAPE
help
Select this option if you want to access IBM 3590 magnetic
@@ -139,7 +153,8 @@ config S390_TAPE_3590
It is safe to say "Y" here.
config VMLOGRDR
- tristate "Support for the z/VM recording system services (VM only)"
+ def_tristate m
+ prompt "Support for the z/VM recording system services (VM only)"
depends on IUCV
help
Select this option if you want to be able to receive records collected
@@ -148,29 +163,31 @@ config VMLOGRDR
This driver depends on the IUCV support driver.
config VMCP
- bool "Support for the z/VM CP interface"
+ def_bool y
+ prompt "Support for the z/VM CP interface"
depends on S390
help
Select this option if you want to be able to interact with the control
program on z/VM
config MONREADER
- tristate "API for reading z/VM monitor service records"
+ def_tristate m
+ prompt "API for reading z/VM monitor service records"
depends on IUCV
help
Character device driver for reading z/VM monitor service records
config MONWRITER
- tristate "API for writing z/VM monitor service records"
+ def_tristate m
+ prompt "API for writing z/VM monitor service records"
depends on S390
- default "m"
help
Character device driver for writing z/VM monitor service records
config S390_VMUR
- tristate "z/VM unit record device driver"
+ def_tristate m
+ prompt "z/VM unit record device driver"
depends on S390
- default "m"
help
Character device driver for z/VM reader, puncher and printer.
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 59ec073724bf..3fb4335d491d 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -9,6 +9,7 @@
* Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu>
*/
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
@@ -361,6 +362,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
int cstat, dstat;
int count;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_C15]++;
raw = dev_get_drvdata(&cdev->dev);
req = (struct raw3215_req *) intparm;
cstat = irb->scsw.cmd.cstat;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 2a4c566456e7..96ba2fd1c8ad 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -7,6 +7,7 @@
* Copyright IBM Corp. 2003, 2009
*/
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -329,6 +330,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
struct raw3270_request *rq;
int rc;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_C70]++;
rp = dev_get_drvdata(&cdev->dev);
if (!rp)
return;
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 35cc4686b99b..b76c61f82485 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -7,6 +7,7 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/spinlock.h>
@@ -18,16 +19,14 @@
#include <linux/suspend.h>
#include <linux/completion.h>
#include <linux/platform_device.h>
-#include <asm/types.h>
#include <asm/s390_ext.h>
+#include <asm/types.h>
+#include <asm/irq.h>
#include "sclp.h"
#define SCLP_HEADER "sclp: "
-/* Structure for register_early_external_interrupt. */
-static ext_int_info_t ext_int_info_hwc;
-
/* Lock to protect internal data consistency. */
static DEFINE_SPINLOCK(sclp_lock);
@@ -402,6 +401,7 @@ static void sclp_interrupt_handler(unsigned int ext_int_code,
u32 finished_sccb;
u32 evbuf_pending;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
spin_lock(&sclp_lock);
finished_sccb = param32 & 0xfffffff8;
evbuf_pending = param32 & 0x3;
@@ -824,6 +824,7 @@ static void sclp_check_handler(unsigned int ext_int_code,
{
u32 finished_sccb;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
finished_sccb = param32 & 0xfffffff8;
/* Is this the interrupt we are waiting for? */
if (finished_sccb == 0)
@@ -866,8 +867,7 @@ sclp_check_interface(void)
spin_lock_irqsave(&sclp_lock, flags);
/* Prepare init mask command */
- rc = register_early_external_interrupt(0x2401, sclp_check_handler,
- &ext_int_info_hwc);
+ rc = register_external_interrupt(0x2401, sclp_check_handler);
if (rc) {
spin_unlock_irqrestore(&sclp_lock, flags);
return rc;
@@ -900,8 +900,7 @@ sclp_check_interface(void)
} else
rc = -EBUSY;
}
- unregister_early_external_interrupt(0x2401, sclp_check_handler,
- &ext_int_info_hwc);
+ unregister_external_interrupt(0x2401, sclp_check_handler);
spin_unlock_irqrestore(&sclp_lock, flags);
return rc;
}
@@ -1064,8 +1063,7 @@ sclp_init(void)
if (rc)
goto fail_init_state_uninitialized;
/* Register interrupt handler */
- rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler,
- &ext_int_info_hwc);
+ rc = register_external_interrupt(0x2401, sclp_interrupt_handler);
if (rc)
goto fail_unregister_reboot_notifier;
sclp_init_state = sclp_init_state_initialized;
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index b497afe061cc..16e232a99fb7 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -33,6 +33,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
int cpu;
struct sys_device *sysdev;
+ s390_adjust_jiffies();
pr_warning("cpu capability changed.\n");
get_online_cpus();
for_each_online_cpu(cpu) {
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index b3a3e8e8656e..7978a0adeaf3 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -14,6 +14,7 @@
#define KMSG_COMPONENT "tape"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/init.h> // for kernel parameters
#include <linux/kmod.h> // for requesting modules
@@ -1114,6 +1115,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
struct tape_request *request;
int rc;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_TAP]++;
device = dev_get_drvdata(&cdev->dev);
if (device == NULL) {
return;
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index f7e4ae6bf15a..caef1757341d 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -11,6 +11,7 @@
#define KMSG_COMPONENT "vmur"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/cdev.h>
#include <linux/slab.h>
@@ -302,6 +303,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
{
struct urdev *urd;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_VMR]++;
TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
irb->scsw.cmd.count);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 97b25d68e3e7..2864581d8ecb 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -67,6 +67,27 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
}
/*
+ * Remove references from ccw devices to ccw group device and from
+ * ccw group device to ccw devices.
+ */
+static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev)
+{
+ struct ccw_device *cdev;
+ int i;
+
+ for (i = 0; i < gdev->count; i++) {
+ cdev = gdev->cdev[i];
+ if (!cdev)
+ continue;
+ spin_lock_irq(cdev->ccwlock);
+ dev_set_drvdata(&cdev->dev, NULL);
+ spin_unlock_irq(cdev->ccwlock);
+ gdev->cdev[i] = NULL;
+ put_device(&cdev->dev);
+ }
+}
+
+/*
* Provide an 'ungroup' attribute so the user can remove group devices no
* longer needed or accidentially created. Saves memory :)
*/
@@ -78,6 +99,7 @@ static void ccwgroup_ungroup_callback(struct device *dev)
if (device_is_registered(&gdev->dev)) {
__ccwgroup_remove_symlinks(gdev);
device_unregister(dev);
+ __ccwgroup_remove_cdev_refs(gdev);
}
mutex_unlock(&gdev->reg_mutex);
}
@@ -116,21 +138,7 @@ static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store);
static void
ccwgroup_release (struct device *dev)
{
- struct ccwgroup_device *gdev;
- int i;
-
- gdev = to_ccwgroupdev(dev);
-
- for (i = 0; i < gdev->count; i++) {
- if (gdev->cdev[i]) {
- spin_lock_irq(gdev->cdev[i]->ccwlock);
- if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
- dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
- spin_unlock_irq(gdev->cdev[i]->ccwlock);
- put_device(&gdev->cdev[i]->dev);
- }
- }
- kfree(gdev);
+ kfree(to_ccwgroupdev(dev));
}
static int
@@ -639,6 +647,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
mutex_lock(&gdev->reg_mutex);
__ccwgroup_remove_symlinks(gdev);
device_unregister(dev);
+ __ccwgroup_remove_cdev_refs(gdev);
mutex_unlock(&gdev->reg_mutex);
put_device(dev);
}
@@ -660,25 +669,6 @@ int ccwgroup_probe_ccwdev(struct ccw_device *cdev)
return 0;
}
-static struct ccwgroup_device *
-__ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
-{
- struct ccwgroup_device *gdev;
-
- gdev = dev_get_drvdata(&cdev->dev);
- if (gdev) {
- if (get_device(&gdev->dev)) {
- mutex_lock(&gdev->reg_mutex);
- if (device_is_registered(&gdev->dev))
- return gdev;
- mutex_unlock(&gdev->reg_mutex);
- put_device(&gdev->dev);
- }
- return NULL;
- }
- return NULL;
-}
-
/**
* ccwgroup_remove_ccwdev() - remove function for slave devices
* @cdev: ccw device to be removed
@@ -694,13 +684,25 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
/* Ignore offlining errors, device is gone anyway. */
ccw_device_set_offline(cdev);
/* If one of its devices is gone, the whole group is done for. */
- gdev = __ccwgroup_get_gdev_by_cdev(cdev);
- if (gdev) {
+ spin_lock_irq(cdev->ccwlock);
+ gdev = dev_get_drvdata(&cdev->dev);
+ if (!gdev) {
+ spin_unlock_irq(cdev->ccwlock);
+ return;
+ }
+ /* Get ccwgroup device reference for local processing. */
+ get_device(&gdev->dev);
+ spin_unlock_irq(cdev->ccwlock);
+ /* Unregister group device. */
+ mutex_lock(&gdev->reg_mutex);
+ if (device_is_registered(&gdev->dev)) {
__ccwgroup_remove_symlinks(gdev);
device_unregister(&gdev->dev);
- mutex_unlock(&gdev->reg_mutex);
- put_device(&gdev->dev);
+ __ccwgroup_remove_cdev_refs(gdev);
}
+ mutex_unlock(&gdev->reg_mutex);
+ /* Release ccwgroup device reference for local processing. */
+ put_device(&gdev->dev);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 1aaddea673e0..0689fcf23a11 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -695,6 +695,25 @@ out:
return ret;
}
+int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
+ struct channel_path_desc_fmt1 *desc)
+{
+ struct chsc_response_struct *chsc_resp;
+ struct chsc_scpd *scpd_area;
+ int ret;
+
+ spin_lock_irq(&chsc_page_lock);
+ scpd_area = chsc_page;
+ ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area);
+ if (ret)
+ goto out;
+ chsc_resp = (void *)&scpd_area->response;
+ memcpy(desc, &chsc_resp->data, sizeof(*desc));
+out:
+ spin_unlock_irq(&chsc_page_lock);
+ return ret;
+}
+
static void
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
struct cmg_chars *chars)
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index 6693f5e3176f..3f15b2aaeaea 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -35,6 +35,22 @@ struct channel_path_desc {
u8 chpp;
} __attribute__ ((packed));
+struct channel_path_desc_fmt1 {
+ u8 flags;
+ u8 lsn;
+ u8 desc;
+ u8 chpid;
+ u32:24;
+ u8 chpp;
+ u32 unused[3];
+ u16 mdc;
+ u16:13;
+ u8 r:1;
+ u8 s:1;
+ u8 f:1;
+ u32 zeros[2];
+} __attribute__ ((packed));
+
struct channel_path;
struct css_chsc_char {
@@ -92,6 +108,8 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
int c, int m, void *page);
int chsc_determine_base_channel_path_desc(struct chp_id chpid,
struct channel_path_desc *desc);
+int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
+ struct channel_path_desc_fmt1 *desc);
void chsc_chp_online(struct chp_id chpid);
void chsc_chp_offline(struct chp_id chpid);
int chsc_get_channel_measurement_chars(struct channel_path *chp);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index a5050e217150..24d8e97355b9 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -618,6 +618,7 @@ EXPORT_SYMBOL_GPL(css_schedule_reprobe);
static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
{
struct subchannel_id mchk_schid;
+ struct subchannel *sch;
if (overflow) {
css_schedule_eval_all();
@@ -635,8 +636,15 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
init_subchannel_id(&mchk_schid);
mchk_schid.sch_no = crw0->rsid;
if (crw1)
- mchk_schid.ssid = (crw1->rsid >> 8) & 3;
+ mchk_schid.ssid = (crw1->rsid >> 4) & 3;
+ if (crw0->erc == CRW_ERC_PMOD) {
+ sch = get_subchannel_by_schid(mchk_schid);
+ if (sch) {
+ css_update_ssd_info(sch);
+ put_device(&sch->dev);
+ }
+ }
/*
* Since we are always presented with IPI in the CRW, we have to
* use stsch() to find out if the subchannel in question has come
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 6da84543dfe9..651976b54af8 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -687,6 +687,46 @@ int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw,
EXPORT_SYMBOL(ccw_device_tm_start_timeout);
/**
+ * ccw_device_get_mdc - accumulate max data count
+ * @cdev: ccw device for which the max data count is accumulated
+ * @mask: mask of paths to use
+ *
+ * Return the number of 64K-bytes blocks all paths at least support
+ * for a transport command. Return values <= 0 indicate failures.
+ */
+int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
+{
+ struct subchannel *sch = to_subchannel(cdev->dev.parent);
+ struct channel_path_desc_fmt1 desc;
+ struct chp_id chpid;
+ int mdc = 0, ret, i;
+
+ /* Adjust requested path mask to excluded varied off paths. */
+ if (mask)
+ mask &= sch->lpm;
+ else
+ mask = sch->lpm;
+
+ chp_id_init(&chpid);
+ for (i = 0; i < 8; i++) {
+ if (!(mask & (0x80 >> i)))
+ continue;
+ chpid.id = sch->schib.pmcw.chpid[i];
+ ret = chsc_determine_fmt1_channel_path_desc(chpid, &desc);
+ if (ret)
+ return ret;
+ if (!desc.f)
+ return 0;
+ if (!desc.r)
+ mdc = 1;
+ mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc;
+ }
+
+ return mdc;
+}
+EXPORT_SYMBOL(ccw_device_get_mdc);
+
+/**
* ccw_device_tm_intrg - perform interrogate function
* @cdev: ccw device on which to perform the interrogate function
*
diff --git a/drivers/s390/cio/itcw.c b/drivers/s390/cio/itcw.c
index a0ae29564774..358ee16d10a2 100644
--- a/drivers/s390/cio/itcw.c
+++ b/drivers/s390/cio/itcw.c
@@ -93,6 +93,7 @@ EXPORT_SYMBOL(itcw_get_tcw);
size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws)
{
size_t len;
+ int cross_count;
/* Main data. */
len = sizeof(struct itcw);
@@ -105,12 +106,27 @@ size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws)
/* TSB */ sizeof(struct tsb) +
/* TIDAL */ intrg_max_tidaws * sizeof(struct tidaw);
}
+
/* Maximum required alignment padding. */
len += /* Initial TCW */ 63 + /* Interrogate TCCB */ 7;
- /* Maximum padding for structures that may not cross 4k boundary. */
- if ((max_tidaws > 0) || (intrg_max_tidaws > 0))
- len += max(max_tidaws, intrg_max_tidaws) *
- sizeof(struct tidaw) - 1;
+
+ /* TIDAW lists may not cross a 4k boundary. To cross a
+ * boundary we need to add a TTIC TIDAW. We need to reserve
+ * one additional TIDAW for a TTIC that we may need to add due
+ * to the placement of the data chunk in memory, and a further
+ * TIDAW for each page boundary that the TIDAW list may cross
+ * due to it's own size.
+ */
+ if (max_tidaws) {
+ cross_count = 1 + ((max_tidaws * sizeof(struct tidaw) - 1)
+ >> PAGE_SHIFT);
+ len += cross_count * sizeof(struct tidaw);
+ }
+ if (intrg_max_tidaws) {
+ cross_count = 1 + ((intrg_max_tidaws * sizeof(struct tidaw) - 1)
+ >> PAGE_SHIFT);
+ len += cross_count * sizeof(struct tidaw);
+ }
return len;
}
EXPORT_SYMBOL(itcw_calc_size);
@@ -165,6 +181,7 @@ struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg,
void *chunk;
addr_t start;
addr_t end;
+ int cross_count;
/* Check for 2G limit. */
start = (addr_t) buffer;
@@ -177,8 +194,17 @@ struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg,
if (IS_ERR(chunk))
return chunk;
itcw = chunk;
- itcw->max_tidaws = max_tidaws;
- itcw->intrg_max_tidaws = intrg_max_tidaws;
+ /* allow for TTIC tidaws that may be needed to cross a page boundary */
+ cross_count = 0;
+ if (max_tidaws)
+ cross_count = 1 + ((max_tidaws * sizeof(struct tidaw) - 1)
+ >> PAGE_SHIFT);
+ itcw->max_tidaws = max_tidaws + cross_count;
+ cross_count = 0;
+ if (intrg_max_tidaws)
+ cross_count = 1 + ((intrg_max_tidaws * sizeof(struct tidaw) - 1)
+ >> PAGE_SHIFT);
+ itcw->intrg_max_tidaws = intrg_max_tidaws + cross_count;
/* Main TCW. */
chunk = fit_chunk(&start, end, sizeof(struct tcw), 64, 0);
if (IS_ERR(chunk))
@@ -198,7 +224,7 @@ struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg,
/* Data TIDAL. */
if (max_tidaws > 0) {
chunk = fit_chunk(&start, end, sizeof(struct tidaw) *
- max_tidaws, 16, 1);
+ itcw->max_tidaws, 16, 0);
if (IS_ERR(chunk))
return chunk;
tcw_set_data(itcw->tcw, chunk, 1);
@@ -206,7 +232,7 @@ struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg,
/* Interrogate data TIDAL. */
if (intrg && (intrg_max_tidaws > 0)) {
chunk = fit_chunk(&start, end, sizeof(struct tidaw) *
- intrg_max_tidaws, 16, 1);
+ itcw->intrg_max_tidaws, 16, 0);
if (IS_ERR(chunk))
return chunk;
tcw_set_data(itcw->intrg_tcw, chunk, 1);
@@ -283,13 +309,29 @@ EXPORT_SYMBOL(itcw_add_dcw);
* the new tidaw on success or -%ENOSPC if the new tidaw would exceed the
* available space.
*
- * Note: the tidaw-list is assumed to be contiguous with no ttics. The
- * last-tidaw flag for the last tidaw in the list will be set by itcw_finalize.
+ * Note: TTIC tidaws are automatically added when needed, so explicitly calling
+ * this interface with the TTIC flag is not supported. The last-tidaw flag
+ * for the last tidaw in the list will be set by itcw_finalize.
*/
struct tidaw *itcw_add_tidaw(struct itcw *itcw, u8 flags, void *addr, u32 count)
{
+ struct tidaw *following;
+
if (itcw->num_tidaws >= itcw->max_tidaws)
return ERR_PTR(-ENOSPC);
+ /*
+ * Is the tidaw, which follows the one we are about to fill, on the next
+ * page? Then we have to insert a TTIC tidaw first, that points to the
+ * tidaw on the new page.
+ */
+ following = ((struct tidaw *) tcw_get_data(itcw->tcw))
+ + itcw->num_tidaws + 1;
+ if (itcw->num_tidaws && !((unsigned long) following & ~PAGE_MASK)) {
+ tcw_add_tidaw(itcw->tcw, itcw->num_tidaws++,
+ TIDAW_FLAGS_TTIC, following, 0);
+ if (itcw->num_tidaws >= itcw->max_tidaws)
+ return ERR_PTR(-ENOSPC);
+ }
return tcw_add_tidaw(itcw->tcw, itcw->num_tidaws++, flags, addr, count);
}
EXPORT_SYMBOL(itcw_add_tidaw);
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 0f4ef8769a3d..7bc643f3f5ab 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -91,6 +91,12 @@ enum qdio_irq_states {
#define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */
#define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */
+/* SIGA flags */
+#define QDIO_SIGA_WRITE 0x00
+#define QDIO_SIGA_READ 0x01
+#define QDIO_SIGA_SYNC 0x02
+#define QDIO_SIGA_QEBSM_FLAG 0x80
+
#ifdef CONFIG_64BIT
static inline int do_sqbs(u64 token, unsigned char state, int queue,
int *start, int *count)
@@ -142,10 +148,9 @@ struct siga_flag {
u8 input:1;
u8 output:1;
u8 sync:1;
- u8 no_sync_ti:1;
- u8 no_sync_out_ti:1;
- u8 no_sync_out_pci:1;
- u8:2;
+ u8 sync_after_ai:1;
+ u8 sync_out_after_pci:1;
+ u8:3;
} __attribute__ ((packed));
struct chsc_ssqd_area {
@@ -202,6 +207,7 @@ struct qdio_dev_perf_stat {
unsigned int inbound_queue_full;
unsigned int outbound_call;
unsigned int outbound_handler;
+ unsigned int outbound_queue_full;
unsigned int fast_requeue;
unsigned int target_full;
unsigned int eqbs;
@@ -245,10 +251,10 @@ struct qdio_input_q {
struct qdio_output_q {
/* PCIs are enabled for the queue */
int pci_out_enabled;
- /* IQDIO: output multiple buffers (enhanced SIGA) */
- int use_enh_siga;
/* timer to check for more outbound work */
struct timer_list timer;
+ /* used SBALs before tasklet schedule */
+ int scan_threshold;
};
/*
@@ -383,12 +389,13 @@ static inline int multicast_outbound(struct qdio_q *q)
(q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)
#define is_qebsm(q) (q->irq_ptr->sch_token != 0)
-#define need_siga_sync_thinint(q) (!q->irq_ptr->siga_flag.no_sync_ti)
-#define need_siga_sync_out_thinint(q) (!q->irq_ptr->siga_flag.no_sync_out_ti)
#define need_siga_in(q) (q->irq_ptr->siga_flag.input)
#define need_siga_out(q) (q->irq_ptr->siga_flag.output)
-#define need_siga_sync(q) (q->irq_ptr->siga_flag.sync)
-#define siga_syncs_out_pci(q) (q->irq_ptr->siga_flag.no_sync_out_pci)
+#define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync))
+#define need_siga_sync_after_ai(q) \
+ (unlikely(q->irq_ptr->siga_flag.sync_after_ai))
+#define need_siga_sync_out_after_pci(q) \
+ (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci))
#define for_each_input_queue(irq_ptr, q, i) \
for (i = 0, q = irq_ptr->input_qs[0]; \
@@ -423,9 +430,9 @@ struct indicator_t {
extern struct indicator_t *q_indicators;
-static inline int shared_ind(struct qdio_irq *irq_ptr)
+static inline int shared_ind(u32 *dsci)
{
- return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+ return dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
}
/* prototypes for thin interrupt */
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 28868e7471a5..f8b03a636e49 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -151,6 +151,7 @@ static char *qperf_names[] = {
"Inbound queue full",
"Outbound calls",
"Outbound handler",
+ "Outbound queue full",
"Outbound fast_requeue",
"Outbound target_full",
"QEBSM eqbs",
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 5fcfa7f9e9ef..e9fff2b9bce2 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -14,6 +14,7 @@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/gfp.h>
+#include <linux/kernel_stat.h>
#include <asm/atomic.h>
#include <asm/debug.h>
#include <asm/qdio.h>
@@ -29,11 +30,12 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\
MODULE_DESCRIPTION("QDIO base support");
MODULE_LICENSE("GPL");
-static inline int do_siga_sync(struct subchannel_id schid,
- unsigned int out_mask, unsigned int in_mask)
+static inline int do_siga_sync(unsigned long schid,
+ unsigned int out_mask, unsigned int in_mask,
+ unsigned int fc)
{
- register unsigned long __fc asm ("0") = 2;
- register struct subchannel_id __schid asm ("1") = schid;
+ register unsigned long __fc asm ("0") = fc;
+ register unsigned long __schid asm ("1") = schid;
register unsigned long out asm ("2") = out_mask;
register unsigned long in asm ("3") = in_mask;
int cc;
@@ -47,10 +49,11 @@ static inline int do_siga_sync(struct subchannel_id schid,
return cc;
}
-static inline int do_siga_input(struct subchannel_id schid, unsigned int mask)
+static inline int do_siga_input(unsigned long schid, unsigned int mask,
+ unsigned int fc)
{
- register unsigned long __fc asm ("0") = 1;
- register struct subchannel_id __schid asm ("1") = schid;
+ register unsigned long __fc asm ("0") = fc;
+ register unsigned long __schid asm ("1") = schid;
register unsigned long __mask asm ("2") = mask;
int cc;
@@ -279,16 +282,20 @@ void qdio_init_buf_states(struct qdio_irq *irq_ptr)
static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
unsigned int input)
{
+ unsigned long schid = *((u32 *) &q->irq_ptr->schid);
+ unsigned int fc = QDIO_SIGA_SYNC;
int cc;
- if (!need_siga_sync(q))
- return 0;
-
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr);
qperf_inc(q, siga_sync);
- cc = do_siga_sync(q->irq_ptr->schid, output, input);
- if (cc)
+ if (is_qebsm(q)) {
+ schid = q->irq_ptr->sch_token;
+ fc |= QDIO_SIGA_QEBSM_FLAG;
+ }
+
+ cc = do_siga_sync(schid, output, input, fc);
+ if (unlikely(cc))
DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc);
return cc;
}
@@ -301,38 +308,22 @@ static inline int qdio_siga_sync_q(struct qdio_q *q)
return qdio_siga_sync(q, q->mask, 0);
}
-static inline int qdio_siga_sync_out(struct qdio_q *q)
-{
- return qdio_siga_sync(q, ~0U, 0);
-}
-
-static inline int qdio_siga_sync_all(struct qdio_q *q)
-{
- return qdio_siga_sync(q, ~0U, ~0U);
-}
-
static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit)
{
- unsigned long schid;
- unsigned int fc = 0;
+ unsigned long schid = *((u32 *) &q->irq_ptr->schid);
+ unsigned int fc = QDIO_SIGA_WRITE;
u64 start_time = 0;
int cc;
- if (q->u.out.use_enh_siga)
- fc = 3;
-
if (is_qebsm(q)) {
schid = q->irq_ptr->sch_token;
- fc |= 0x80;
+ fc |= QDIO_SIGA_QEBSM_FLAG;
}
- else
- schid = *((u32 *)&q->irq_ptr->schid);
-
again:
cc = do_siga_output(schid, q->mask, busy_bit, fc);
/* hipersocket busy condition */
- if (*busy_bit) {
+ if (unlikely(*busy_bit)) {
WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2);
if (!start_time) {
@@ -347,32 +338,41 @@ again:
static inline int qdio_siga_input(struct qdio_q *q)
{
+ unsigned long schid = *((u32 *) &q->irq_ptr->schid);
+ unsigned int fc = QDIO_SIGA_READ;
int cc;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr);
qperf_inc(q, siga_read);
- cc = do_siga_input(q->irq_ptr->schid, q->mask);
- if (cc)
+ if (is_qebsm(q)) {
+ schid = q->irq_ptr->sch_token;
+ fc |= QDIO_SIGA_QEBSM_FLAG;
+ }
+
+ cc = do_siga_input(schid, q->mask, fc);
+ if (unlikely(cc))
DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc);
return cc;
}
-static inline void qdio_sync_after_thinint(struct qdio_q *q)
+#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
+#define qdio_siga_sync_all(q) qdio_siga_sync(q, ~0U, ~0U)
+
+static inline void qdio_sync_queues(struct qdio_q *q)
{
- if (pci_out_supported(q)) {
- if (need_siga_sync_thinint(q))
- qdio_siga_sync_all(q);
- else if (need_siga_sync_out_thinint(q))
- qdio_siga_sync_out(q);
- } else
+ /* PCI capable outbound queues will also be scanned so sync them too */
+ if (pci_out_supported(q))
+ qdio_siga_sync_all(q);
+ else
qdio_siga_sync_q(q);
}
int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
unsigned char *state)
{
- qdio_siga_sync_q(q);
+ if (need_siga_sync(q))
+ qdio_siga_sync_q(q);
return get_buf_states(q, bufnr, state, 1, 0);
}
@@ -549,7 +549,8 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
if (!atomic_read(&q->nr_buf_used))
return 1;
- qdio_siga_sync_q(q);
+ if (need_siga_sync(q))
+ qdio_siga_sync_q(q);
get_buf_state(q, q->first_to_check, &state, 0);
if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
@@ -644,9 +645,12 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
int count, stop;
unsigned char state;
- if (((queue_type(q) != QDIO_IQDIO_QFMT) && !pci_out_supported(q)) ||
- (queue_type(q) == QDIO_IQDIO_QFMT && multicast_outbound(q)))
- qdio_siga_sync_q(q);
+ if (need_siga_sync(q))
+ if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
+ !pci_out_supported(q)) ||
+ (queue_type(q) == QDIO_IQDIO_QFMT &&
+ multicast_outbound(q)))
+ qdio_siga_sync_q(q);
/*
* Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -818,7 +822,8 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
static void __tiqdio_inbound_processing(struct qdio_q *q)
{
qperf_inc(q, tasklet_inbound);
- qdio_sync_after_thinint(q);
+ if (need_siga_sync(q) && need_siga_sync_after_ai(q))
+ qdio_sync_queues(q);
/*
* The interrupt could be caused by a PCI request. Check the
@@ -898,16 +903,14 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
tasklet_schedule(&q->tasklet);
}
- if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
+ if (!pci_out_supported(q))
return;
for_each_output_queue(irq_ptr, q, i) {
if (qdio_outbound_q_done(q))
continue;
-
- if (!siga_syncs_out_pci(q))
+ if (need_siga_sync(q) && need_siga_sync_out_after_pci(q))
qdio_siga_sync_q(q);
-
tasklet_schedule(&q->tasklet);
}
}
@@ -970,6 +973,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
+ kstat_cpu(smp_processor_id()).irqs[IOINT_QDI]++;
if (irq_ptr->perf_stat_enabled)
irq_ptr->perf_stat.qdio_int++;
@@ -1273,7 +1277,6 @@ int qdio_establish(struct qdio_initialize *init_data)
}
qdio_setup_ssqd_info(irq_ptr);
- DBF_EVENT("qDmmwc:%2x", irq_ptr->ssqd_desc.mmwc);
DBF_EVENT("qib ac:%4x", irq_ptr->qib.ac);
/* qebsm is now setup if available, initialize buffer states */
@@ -1445,52 +1448,38 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
used = atomic_add_return(count, &q->nr_buf_used);
BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q);
+ if (used == QDIO_MAX_BUFFERS_PER_Q)
+ qperf_inc(q, outbound_queue_full);
+
if (callflags & QDIO_FLAG_PCI_OUT) {
q->u.out.pci_out_enabled = 1;
qperf_inc(q, pci_request_int);
- }
- else
+ } else
q->u.out.pci_out_enabled = 0;
if (queue_type(q) == QDIO_IQDIO_QFMT) {
- if (multicast_outbound(q))
+ /* One SIGA-W per buffer required for unicast HiperSockets. */
+ WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
+
+ rc = qdio_kick_outbound_q(q);
+ } else if (need_siga_sync(q)) {
+ rc = qdio_siga_sync_q(q);
+ } else {
+ /* try to fast requeue buffers */
+ get_buf_state(q, prev_buf(bufnr), &state, 0);
+ if (state != SLSB_CU_OUTPUT_PRIMED)
rc = qdio_kick_outbound_q(q);
else
- if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
- (count > 1) &&
- (count <= q->irq_ptr->ssqd_desc.mmwc)) {
- /* exploit enhanced SIGA */
- q->u.out.use_enh_siga = 1;
- rc = qdio_kick_outbound_q(q);
- } else {
- /*
- * One siga-w per buffer required for unicast
- * HiperSockets.
- */
- q->u.out.use_enh_siga = 0;
- while (count--) {
- rc = qdio_kick_outbound_q(q);
- if (rc)
- goto out;
- }
- }
- goto out;
- }
-
- if (need_siga_sync(q)) {
- qdio_siga_sync_q(q);
- goto out;
+ qperf_inc(q, fast_requeue);
}
- /* try to fast requeue buffers */
- get_buf_state(q, prev_buf(bufnr), &state, 0);
- if (state != SLSB_CU_OUTPUT_PRIMED)
- rc = qdio_kick_outbound_q(q);
+ /* in case of SIGA errors we must process the error immediately */
+ if (used >= q->u.out.scan_threshold || rc)
+ tasklet_schedule(&q->tasklet);
else
- qperf_inc(q, fast_requeue);
-
-out:
- tasklet_schedule(&q->tasklet);
+ /* free the SBALs in case of no further traffic */
+ if (!timer_pending(&q->u.out.timer))
+ mod_timer(&q->u.out.timer, jiffies + HZ);
return rc;
}
@@ -1550,7 +1539,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
WARN_ON(queue_irqs_enabled(q));
- if (!shared_ind(q->irq_ptr))
+ if (!shared_ind(q->irq_ptr->dsci))
xchg(q->irq_ptr->dsci, 0);
qdio_stop_polling(q);
@@ -1560,7 +1549,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
* We need to check again to not lose initiative after
* resetting the ACK state.
*/
- if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci)
+ if (!shared_ind(q->irq_ptr->dsci) && *q->irq_ptr->dsci)
goto rescan;
if (!qdio_inbound_q_done(q))
goto rescan;
@@ -1600,12 +1589,14 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
q = irq_ptr->input_qs[nr];
WARN_ON(queue_irqs_enabled(q));
- qdio_sync_after_thinint(q);
-
/*
- * The interrupt could be caused by a PCI request. Check the
- * PCI capable outbound queues.
+ * Cannot rely on automatic sync after interrupt since queues may
+ * also be examined without interrupt.
*/
+ if (need_siga_sync(q))
+ qdio_sync_queues(q);
+
+ /* check the PCI capable outbound queues. */
qdio_check_outbound_after_thinint(q);
if (!qdio_inbound_q_moved(q))
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index a13cf7ec64b2..89107d0938c4 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -178,6 +178,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
q->is_input_q = 0;
+ q->u.out.scan_threshold = qdio_init->scan_threshold;
setup_storage_lists(q, irq_ptr, output_sbal_array, i);
output_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
@@ -196,14 +197,10 @@ static void process_ac_flags(struct qdio_irq *irq_ptr, unsigned char qdioac)
irq_ptr->siga_flag.output = 1;
if (qdioac & AC1_SIGA_SYNC_NEEDED)
irq_ptr->siga_flag.sync = 1;
- if (qdioac & AC1_AUTOMATIC_SYNC_ON_THININT)
- irq_ptr->siga_flag.no_sync_ti = 1;
- if (qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI)
- irq_ptr->siga_flag.no_sync_out_pci = 1;
-
- if (irq_ptr->siga_flag.no_sync_out_pci &&
- irq_ptr->siga_flag.no_sync_ti)
- irq_ptr->siga_flag.no_sync_out_ti = 1;
+ if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_THININT))
+ irq_ptr->siga_flag.sync_after_ai = 1;
+ if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI))
+ irq_ptr->siga_flag.sync_out_after_pci = 1;
}
static void check_and_setup_qebsm(struct qdio_irq *irq_ptr,
@@ -451,7 +448,7 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
char s[80];
snprintf(s, 80, "qdio: %s %s on SC %x using "
- "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s%s\n",
+ "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s\n",
dev_name(&cdev->dev),
(irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" :
((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"),
@@ -463,9 +460,8 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
(irq_ptr->siga_flag.input) ? "R" : " ",
(irq_ptr->siga_flag.output) ? "W" : " ",
(irq_ptr->siga_flag.sync) ? "S" : " ",
- (!irq_ptr->siga_flag.no_sync_ti) ? "A" : " ",
- (!irq_ptr->siga_flag.no_sync_out_ti) ? "O" : " ",
- (!irq_ptr->siga_flag.no_sync_out_pci) ? "P" : " ");
+ (irq_ptr->siga_flag.sync_after_ai) ? "A" : " ",
+ (irq_ptr->siga_flag.sync_out_after_pci) ? "P" : " ");
printk(KERN_INFO "%s", s);
}
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 5d9c66627b6e..5c4e741d8221 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -8,6 +8,7 @@
*/
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/kernel_stat.h>
#include <asm/atomic.h>
#include <asm/debug.h>
#include <asm/qdio.h>
@@ -35,22 +36,8 @@ static u8 *tiqdio_alsi;
struct indicator_t *q_indicators;
-static int css_qdio_omit_svs;
-
static u64 last_ai_time;
-static inline unsigned long do_clear_global_summary(void)
-{
- register unsigned long __fn asm("1") = 3;
- register unsigned long __tmp asm("2");
- register unsigned long __time asm("3");
-
- asm volatile(
- " .insn rre,0xb2650000,2,0"
- : "+d" (__fn), "=d" (__tmp), "=d" (__time));
- return __time;
-}
-
/* returns addr for the device state change indicator */
static u32 *get_indicator(void)
{
@@ -83,10 +70,6 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
struct qdio_q *q;
int i;
- /* No TDD facility? If we must use SIGA-s we can also omit SVS. */
- if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
- css_qdio_omit_svs = 1;
-
mutex_lock(&tiq_list_lock);
for_each_input_queue(irq_ptr, q, i)
list_add_rcu(&q->entry, &tiq_list);
@@ -112,9 +95,9 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
}
}
-static inline int shared_ind_used(void)
+static inline u32 shared_ind_set(void)
{
- return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count);
+ return q_indicators[TIQDIO_SHARED_IND].ind;
}
/**
@@ -124,20 +107,11 @@ static inline int shared_ind_used(void)
*/
static void tiqdio_thinint_handler(void *alsi, void *data)
{
+ u32 si_used = shared_ind_set();
struct qdio_q *q;
last_ai_time = S390_lowcore.int_clock;
-
- /*
- * SVS only when needed: issue SVS to benefit from iqdio interrupt
- * avoidance (SVS clears adapter interrupt suppression overwrite).
- */
- if (!css_qdio_omit_svs)
- do_clear_global_summary();
-
- /* reset local summary indicator */
- if (shared_ind_used())
- xchg(tiqdio_alsi, 0);
+ kstat_cpu(smp_processor_id()).irqs[IOINT_QAI]++;
/* protect tiq_list entries, only changed in activate or shutdown */
rcu_read_lock();
@@ -146,7 +120,10 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
list_for_each_entry_rcu(q, &tiq_list, entry) {
/* only process queues from changed sets */
- if (!*q->irq_ptr->dsci)
+ if (unlikely(shared_ind(q->irq_ptr->dsci))) {
+ if (!si_used)
+ continue;
+ } else if (!*q->irq_ptr->dsci)
continue;
if (q->u.in.queue_start_poll) {
@@ -162,7 +139,7 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
q->irq_ptr->int_parm);
} else {
/* only clear it if the indicator is non-shared */
- if (!shared_ind(q->irq_ptr))
+ if (!shared_ind(q->irq_ptr->dsci))
xchg(q->irq_ptr->dsci, 0);
/*
* Call inbound processing but not directly
@@ -178,13 +155,8 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
* If the shared indicator was used clear it now after all queues
* were processed.
*/
- if (shared_ind_used()) {
+ if (si_used && shared_ind_set())
xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0);
-
- /* prevent racing */
- if (*tiqdio_alsi)
- xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1 << 7);
- }
}
static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
@@ -269,12 +241,6 @@ int qdio_establish_thinint(struct qdio_irq *irq_ptr)
{
if (!is_thinint_irq(irq_ptr))
return 0;
-
- /* Check for aif time delay disablement. If installed,
- * omit SVS even under LPAR
- */
- if (css_general_characteristics.aif_tdd)
- css_qdio_omit_svs = 1;
return set_subchannel_ind(irq_ptr, 0);
}
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 8fd8c62455e9..67302b944ab3 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -27,6 +27,7 @@
#define KMSG_COMPONENT "ap"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -154,7 +155,7 @@ static inline int ap_instructions_available(void)
*/
static int ap_interrupts_available(void)
{
- return test_facility(1) && test_facility(2);
+ return test_facility(2) && test_facility(65);
}
/**
@@ -221,6 +222,69 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
}
#endif
+static inline struct ap_queue_status __ap_4096_commands_available(ap_qid_t qid,
+ int *support)
+{
+ register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
+ register struct ap_queue_status reg1 asm ("1");
+ register unsigned long reg2 asm ("2") = 0UL;
+
+ asm volatile(
+ ".long 0xb2af0000\n"
+ "0: la %1,0\n"
+ "1:\n"
+ EX_TABLE(0b, 1b)
+ : "+d" (reg0), "=d" (reg1), "=d" (reg2)
+ :
+ : "cc");
+
+ if (reg2 & 0x6000000000000000ULL)
+ *support = 1;
+ else
+ *support = 0;
+
+ return reg1;
+}
+
+/**
+ * ap_4096_commands_availablen(): Check for availability of 4096 bit RSA
+ * support.
+ * @qid: The AP queue number
+ *
+ * Returns 1 if 4096 bit RSA keys are support fo the AP, returns 0 if not.
+ */
+int ap_4096_commands_available(ap_qid_t qid)
+{
+ struct ap_queue_status status;
+ int i, support = 0;
+ status = __ap_4096_commands_available(qid, &support);
+
+ for (i = 0; i < AP_MAX_RESET; i++) {
+ switch (status.response_code) {
+ case AP_RESPONSE_NORMAL:
+ return support;
+ case AP_RESPONSE_RESET_IN_PROGRESS:
+ case AP_RESPONSE_BUSY:
+ break;
+ case AP_RESPONSE_Q_NOT_AVAIL:
+ case AP_RESPONSE_DECONFIGURED:
+ case AP_RESPONSE_CHECKSTOPPED:
+ case AP_RESPONSE_INVALID_ADDRESS:
+ return 0;
+ case AP_RESPONSE_OTHERWISE_CHANGED:
+ break;
+ default:
+ break;
+ }
+ if (i < AP_MAX_RESET - 1) {
+ udelay(5);
+ status = __ap_4096_commands_available(qid, &support);
+ }
+ }
+ return support;
+}
+EXPORT_SYMBOL(ap_4096_commands_available);
+
/**
* ap_queue_enable_interruption(): Enable interruption on an AP.
* @qid: The AP queue number
@@ -1042,6 +1106,7 @@ out:
static void ap_interrupt_handler(void *unused1, void *unused2)
{
+ kstat_cpu(smp_processor_id()).irqs[IOINT_APB]++;
tasklet_schedule(&ap_tasklet);
}
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 4785d07cd447..08b9738285b4 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -196,4 +196,6 @@ void ap_flush_queue(struct ap_device *ap_dev);
int ap_module_init(void);
void ap_module_exit(void);
+int ap_4096_commands_available(ap_qid_t qid);
+
#endif /* _AP_BUS_H_ */
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 7fca9c10ffcf..8e65447f76b7 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -396,8 +396,15 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
if (copied == 0) {
unsigned int len;
spin_unlock_bh(&zcrypt_device_lock);
- /* len is max 256 / 2 - 120 = 8 */
- len = crt->inputdatalength / 2 - 120;
+ /* len is max 256 / 2 - 120 = 8
+ * For bigger device just assume len of leading
+ * 0s is 8 as stated in the requirements for
+ * ica_rsa_modexpo_crt struct in zcrypt.h.
+ */
+ if (crt->inputdatalength <= 256)
+ len = crt->inputdatalength / 2 - 120;
+ else
+ len = 8;
if (len > sizeof(z1))
return -EFAULT;
z1 = z2 = z3 = 0;
@@ -405,6 +412,7 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
copy_from_user(&z2, crt->bp_key, len) ||
copy_from_user(&z3, crt->u_mult_inv, len))
return -EFAULT;
+ z1 = z2 = z3 = 0;
copied = 1;
/*
* We have to restart device lookup -
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 8e7ffbf2466c..88ebd114735b 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -109,6 +109,7 @@ struct zcrypt_device {
int request_count; /* # current requests. */
struct ap_message reply; /* Per-device reply structure. */
+ int max_exp_bit_length;
};
struct zcrypt_device *zcrypt_device_alloc(size_t);
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 9c409efa1ecf..2176d00b395e 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -41,7 +41,7 @@
#define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */
#define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */
#define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE
-#define CEX3A_MAX_MOD_SIZE CEX2A_MAX_MOD_SIZE
+#define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */
#define CEX2A_SPEED_RATING 970
#define CEX3A_SPEED_RATING 900 /* Fixme: Needs finetuning */
@@ -49,8 +49,10 @@
#define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
#define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
-#define CEX3A_MAX_MESSAGE_SIZE CEX2A_MAX_MESSAGE_SIZE
-#define CEX3A_MAX_RESPONSE_SIZE CEX2A_MAX_RESPONSE_SIZE
+#define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus
+ * (max outputdatalength) +
+ * type80_hdr*/
+#define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg)
#define CEX2A_CLEANUP_TIME (15*HZ)
#define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME
@@ -110,7 +112,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev,
mod = meb1->modulus + sizeof(meb1->modulus) - mod_len;
exp = meb1->exponent + sizeof(meb1->exponent) - mod_len;
inp = meb1->message + sizeof(meb1->message) - mod_len;
- } else {
+ } else if (mod_len <= 256) {
struct type50_meb2_msg *meb2 = ap_msg->message;
memset(meb2, 0, sizeof(*meb2));
ap_msg->length = sizeof(*meb2);
@@ -120,6 +122,17 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev,
mod = meb2->modulus + sizeof(meb2->modulus) - mod_len;
exp = meb2->exponent + sizeof(meb2->exponent) - mod_len;
inp = meb2->message + sizeof(meb2->message) - mod_len;
+ } else {
+ /* mod_len > 256 = 4096 bit RSA Key */
+ struct type50_meb3_msg *meb3 = ap_msg->message;
+ memset(meb3, 0, sizeof(*meb3));
+ ap_msg->length = sizeof(*meb3);
+ meb3->header.msg_type_code = TYPE50_TYPE_CODE;
+ meb3->header.msg_len = sizeof(*meb3);
+ meb3->keyblock_type = TYPE50_MEB3_FMT;
+ mod = meb3->modulus + sizeof(meb3->modulus) - mod_len;
+ exp = meb3->exponent + sizeof(meb3->exponent) - mod_len;
+ inp = meb3->message + sizeof(meb3->message) - mod_len;
}
if (copy_from_user(mod, mex->n_modulus, mod_len) ||
@@ -142,7 +155,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
struct ap_message *ap_msg,
struct ica_rsa_modexpo_crt *crt)
{
- int mod_len, short_len, long_len, long_offset;
+ int mod_len, short_len, long_len, long_offset, limit;
unsigned char *p, *q, *dp, *dq, *u, *inp;
mod_len = crt->inputdatalength;
@@ -152,14 +165,20 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
/*
* CEX2A cannot handle p, dp, or U > 128 bytes.
* If we have one of these, we need to do extra checking.
+ * For CEX3A the limit is 256 bytes.
*/
- if (long_len > 128) {
+ if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)
+ limit = 256;
+ else
+ limit = 128;
+
+ if (long_len > limit) {
/*
* zcrypt_rsa_crt already checked for the leading
* zeroes of np_prime, bp_key and u_mult_inc.
*/
- long_offset = long_len - 128;
- long_len = 128;
+ long_offset = long_len - limit;
+ long_len = limit;
} else
long_offset = 0;
@@ -180,7 +199,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
dq = crb1->dq + sizeof(crb1->dq) - short_len;
u = crb1->u + sizeof(crb1->u) - long_len;
inp = crb1->message + sizeof(crb1->message) - mod_len;
- } else {
+ } else if (long_len <= 128) {
struct type50_crb2_msg *crb2 = ap_msg->message;
memset(crb2, 0, sizeof(*crb2));
ap_msg->length = sizeof(*crb2);
@@ -193,6 +212,20 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
dq = crb2->dq + sizeof(crb2->dq) - short_len;
u = crb2->u + sizeof(crb2->u) - long_len;
inp = crb2->message + sizeof(crb2->message) - mod_len;
+ } else {
+ /* long_len >= 256 */
+ struct type50_crb3_msg *crb3 = ap_msg->message;
+ memset(crb3, 0, sizeof(*crb3));
+ ap_msg->length = sizeof(*crb3);
+ crb3->header.msg_type_code = TYPE50_TYPE_CODE;
+ crb3->header.msg_len = sizeof(*crb3);
+ crb3->keyblock_type = TYPE50_CRB3_FMT;
+ p = crb3->p + sizeof(crb3->p) - long_len;
+ q = crb3->q + sizeof(crb3->q) - short_len;
+ dp = crb3->dp + sizeof(crb3->dp) - long_len;
+ dq = crb3->dq + sizeof(crb3->dq) - short_len;
+ u = crb3->u + sizeof(crb3->u) - long_len;
+ inp = crb3->message + sizeof(crb3->message) - mod_len;
}
if (copy_from_user(p, crt->np_prime + long_offset, long_len) ||
@@ -203,7 +236,6 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
copy_from_user(inp, crt->inputdata, mod_len))
return -EFAULT;
-
return 0;
}
@@ -230,7 +262,10 @@ static int convert_type80(struct zcrypt_device *zdev,
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
- BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE);
+ if (zdev->user_space_type == ZCRYPT_CEX2A)
+ BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE);
+ else
+ BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE);
data = reply->message + t80h->len - outputdatalength;
if (copy_to_user(outputdata, data, outputdatalength))
return -EFAULT;
@@ -282,7 +317,10 @@ static void zcrypt_cex2a_receive(struct ap_device *ap_dev,
}
t80h = reply->message;
if (t80h->type == TYPE80_RSP_CODE) {
- length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len);
+ if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A)
+ length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len);
+ else
+ length = min(CEX3A_MAX_RESPONSE_SIZE, (int) t80h->len);
memcpy(msg->message, reply->message, length);
} else
memcpy(msg->message, reply->message, sizeof error_reply);
@@ -307,7 +345,10 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
int rc;
ap_init_message(&ap_msg);
- ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ if (zdev->user_space_type == ZCRYPT_CEX2A)
+ ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ else
+ ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -345,7 +386,10 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
int rc;
ap_init_message(&ap_msg);
- ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ if (zdev->user_space_type == ZCRYPT_CEX2A)
+ ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ else
+ ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -397,6 +441,7 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
zdev->short_crt = 1;
zdev->speed_rating = CEX2A_SPEED_RATING;
+ zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
break;
case AP_DEVICE_TYPE_CEX3A:
zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE);
@@ -404,8 +449,13 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
return -ENOMEM;
zdev->user_space_type = ZCRYPT_CEX3A;
zdev->type_string = "CEX3A";
- zdev->min_mod_size = CEX3A_MIN_MOD_SIZE;
- zdev->max_mod_size = CEX3A_MAX_MOD_SIZE;
+ zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
+ zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
+ if (ap_4096_commands_available(ap_dev->qid)) {
+ zdev->max_mod_size = CEX3A_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
+ }
zdev->short_crt = 1;
zdev->speed_rating = CEX3A_SPEED_RATING;
break;
diff --git a/drivers/s390/crypto/zcrypt_cex2a.h b/drivers/s390/crypto/zcrypt_cex2a.h
index 8f69d1dacab8..0350665810cf 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.h
+++ b/drivers/s390/crypto/zcrypt_cex2a.h
@@ -51,8 +51,10 @@ struct type50_hdr {
#define TYPE50_MEB1_FMT 0x0001
#define TYPE50_MEB2_FMT 0x0002
+#define TYPE50_MEB3_FMT 0x0003
#define TYPE50_CRB1_FMT 0x0011
#define TYPE50_CRB2_FMT 0x0012
+#define TYPE50_CRB3_FMT 0x0013
/* Mod-Exp, with a small modulus */
struct type50_meb1_msg {
@@ -74,6 +76,16 @@ struct type50_meb2_msg {
unsigned char message[256];
} __attribute__((packed));
+/* Mod-Exp, with a larger modulus */
+struct type50_meb3_msg {
+ struct type50_hdr header;
+ unsigned short keyblock_type; /* 0x0003 */
+ unsigned char reserved[6];
+ unsigned char exponent[512];
+ unsigned char modulus[512];
+ unsigned char message[512];
+} __attribute__((packed));
+
/* CRT, with a small modulus */
struct type50_crb1_msg {
struct type50_hdr header;
@@ -100,6 +112,19 @@ struct type50_crb2_msg {
unsigned char message[256];
} __attribute__((packed));
+/* CRT, with a larger modulus */
+struct type50_crb3_msg {
+ struct type50_hdr header;
+ unsigned short keyblock_type; /* 0x0013 */
+ unsigned char reserved[6];
+ unsigned char p[256];
+ unsigned char q[256];
+ unsigned char dp[256];
+ unsigned char dq[256];
+ unsigned char u[256];
+ unsigned char message[512];
+} __attribute__((packed));
+
/**
* The type 80 response family is associated with a CEX2A card.
*
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 09e934b295a0..1afb69c75fea 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -373,6 +373,7 @@ static int zcrypt_pcica_probe(struct ap_device *ap_dev)
zdev->min_mod_size = PCICA_MIN_MOD_SIZE;
zdev->max_mod_size = PCICA_MAX_MOD_SIZE;
zdev->speed_rating = PCICA_SPEED_RATING;
+ zdev->max_exp_bit_length = PCICA_MAX_MOD_SIZE;
ap_dev->reply = &zdev->reply;
ap_dev->private = zdev;
rc = zcrypt_device_register(zdev);
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index 9dec5c77cff4..aa4c050a5694 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -579,6 +579,7 @@ static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
zdev->speed_rating = PCICC_SPEED_RATING;
+ zdev->max_exp_bit_length = PCICC_MAX_MOD_SIZE;
ap_dev->reply = &zdev->reply;
ap_dev->private = zdev;
rc = zcrypt_device_register(zdev);
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 510fab4577d4..4f85eb725f4f 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -45,12 +45,12 @@
#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
-#define CEX3C_MAX_MOD_SIZE PCIXCC_MAX_MOD_SIZE
+#define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
#define PCIXCC_MCL2_SPEED_RATING 7870
#define PCIXCC_MCL3_SPEED_RATING 7870
#define CEX2C_SPEED_RATING 7000
-#define CEX3C_SPEED_RATING 6500 /* FIXME: needs finetuning */
+#define CEX3C_SPEED_RATING 6500
#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
@@ -567,6 +567,15 @@ static int convert_response_ica(struct zcrypt_device *zdev,
case TYPE88_RSP_CODE:
return convert_error(zdev, reply);
case TYPE86_RSP_CODE:
+ if (msg->cprbx.ccp_rtcode &&
+ (msg->cprbx.ccp_rscode == 0x14f) &&
+ (outputdatalength > 256)) {
+ if (zdev->max_exp_bit_length <= 17) {
+ zdev->max_exp_bit_length = 17;
+ return -EAGAIN;
+ } else
+ return -EINVAL;
+ }
if (msg->hdr.reply_code)
return convert_error(zdev, reply);
if (msg->cprbx.cprb_ver_id == 0x02)
@@ -1052,11 +1061,13 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
} else {
zdev->type_string = "PCIXCC_MCL3";
zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
}
break;
case AP_DEVICE_TYPE_CEX2C:
@@ -1065,6 +1076,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX2C_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
break;
case AP_DEVICE_TYPE_CEX3C:
zdev->user_space_type = ZCRYPT_CEX3C;
@@ -1072,6 +1084,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX3C_SPEED_RATING;
zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
break;
default:
goto out_free;
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 375aeeaf9ea5..414427d64a8f 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -10,6 +10,7 @@
* Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
*/
+#include <linux/kernel_stat.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/err.h>
@@ -25,6 +26,7 @@
#include <asm/kvm_virtio.h>
#include <asm/setup.h>
#include <asm/s390_ext.h>
+#include <asm/irq.h>
#define VIRTIO_SUBCODE_64 0x0D00
@@ -379,6 +381,7 @@ static void kvm_extint_handler(unsigned int ext_int_code,
u16 subcode;
u32 param;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++;
subcode = ext_int_code >> 16;
if ((subcode & 0xff00) != VIRTIO_SUBCODE_64)
return;
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 456b18743397..fa80ba1f0344 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -2,7 +2,8 @@ menu "S/390 network device drivers"
depends on NETDEVICES && S390
config LCS
- tristate "Lan Channel Station Interface"
+ def_tristate m
+ prompt "Lan Channel Station Interface"
depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI)
help
Select this option if you want to use LCS networking on IBM System z.
@@ -12,7 +13,8 @@ config LCS
If you do not know what it is, it's safe to choose Y.
config CTCM
- tristate "CTC and MPC SNA device support"
+ def_tristate m
+ prompt "CTC and MPC SNA device support"
depends on CCW && NETDEVICES
help
Select this option if you want to use channel-to-channel
@@ -26,7 +28,8 @@ config CTCM
If you do not need any channel-to-channel connection, choose N.
config NETIUCV
- tristate "IUCV network device support (VM only)"
+ def_tristate m
+ prompt "IUCV network device support (VM only)"
depends on IUCV && NETDEVICES
help
Select this option if you want to use inter-user communication
@@ -37,14 +40,16 @@ config NETIUCV
The module name is netiucv. If unsure, choose Y.
config SMSGIUCV
- tristate "IUCV special message support (VM only)"
+ def_tristate m
+ prompt "IUCV special message support (VM only)"
depends on IUCV
help
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)"
+ def_tristate m
+ prompt "Deliver IUCV special messages as uevents (VM only)"
depends on SMSGIUCV
help
Select this option to deliver CP special messages (SMSGs) as
@@ -54,7 +59,8 @@ config SMSGIUCV_EVENT
To compile as a module, choose M. The module name is "smsgiucv_app".
config CLAW
- tristate "CLAW device support"
+ def_tristate m
+ prompt "CLAW device support"
depends on CCW && NETDEVICES
help
This driver supports channel attached CLAW devices.
@@ -64,7 +70,8 @@ config CLAW
To compile into the kernel, choose Y.
config QETH
- tristate "Gigabit Ethernet device support"
+ def_tristate y
+ prompt "Gigabit Ethernet device support"
depends on CCW && NETDEVICES && IP_MULTICAST && QDIO
help
This driver supports the IBM System z OSA Express adapters
@@ -78,25 +85,25 @@ config QETH
The module name is qeth.
config QETH_L2
- tristate "qeth layer 2 device support"
- depends on QETH
- help
- Select this option to be able to run qeth devices in layer 2 mode.
- To compile as a module, choose M. The module name is qeth_l2.
- If unsure, choose y.
+ def_tristate y
+ prompt "qeth layer 2 device support"
+ depends on QETH
+ help
+ Select this option to be able to run qeth devices in layer 2 mode.
+ To compile as a module, choose M. The module name is qeth_l2.
+ If unsure, choose y.
config QETH_L3
- tristate "qeth layer 3 device support"
- depends on QETH
- help
- Select this option to be able to run qeth devices in layer 3 mode.
- To compile as a module choose M. The module name is qeth_l3.
- If unsure, choose Y.
+ def_tristate y
+ prompt "qeth layer 3 device support"
+ depends on QETH
+ help
+ Select this option to be able to run qeth devices in layer 3 mode.
+ To compile as a module choose M. The module name is qeth_l3.
+ If unsure, choose Y.
config QETH_IPV6
- bool
- depends on (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y')
- default y
+ def_bool y if (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y')
config CCWGROUP
tristate
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 8e4153d740f3..ce3a5c13ce0b 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -63,6 +63,7 @@
#define KMSG_COMPONENT "claw"
+#include <linux/kernel_stat.h>
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include <asm/debug.h>
@@ -640,6 +641,7 @@ claw_irq_handler(struct ccw_device *cdev,
struct claw_env *p_env;
struct chbk *p_ch_r=NULL;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_CLW]++;
CLAW_DBF_TEXT(4, trace, "clawirq");
/* Bypass all 'unsolicited interrupts' */
privptr = dev_get_drvdata(&cdev->dev);
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 2c7d2d9be4d0..4c2845985927 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -24,6 +24,7 @@
#define KMSG_COMPONENT "ctcm"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -1204,6 +1205,7 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
int cstat;
int dstat;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_CTC]++;
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
"Enter %s(%s)", CTCM_FUNTAIL, dev_name(&cdev->dev));
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 0f19d540b655..09e7a053c844 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -26,6 +26,7 @@
#define KMSG_COMPONENT "lcs"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/if.h>
#include <linux/netdevice.h>
@@ -1188,7 +1189,8 @@ lcs_remove_mc_addresses(struct lcs_card *card, struct in_device *in4_dev)
spin_lock_irqsave(&card->ipm_lock, flags);
list_for_each(l, &card->ipm_list) {
ipm = list_entry(l, struct lcs_ipm_list, list);
- for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) {
+ for (im4 = rcu_dereference(in4_dev->mc_list);
+ im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) {
lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev);
if ( (ipm->ipm.ip_addr == im4->multiaddr) &&
(memcmp(buf, &ipm->ipm.mac_addr,
@@ -1233,7 +1235,8 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev)
unsigned long flags;
LCS_DBF_TEXT(4, trace, "setmclst");
- for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
+ for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL;
+ im4 = rcu_dereference(im4->next_rcu)) {
lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev);
ipm = lcs_check_addr_entry(card, im4, buf);
if (ipm != NULL)
@@ -1269,10 +1272,10 @@ lcs_register_mc_addresses(void *data)
in4_dev = in_dev_get(card->dev);
if (in4_dev == NULL)
goto out;
- read_lock(&in4_dev->mc_list_lock);
+ rcu_read_lock();
lcs_remove_mc_addresses(card,in4_dev);
lcs_set_mc_addresses(card, in4_dev);
- read_unlock(&in4_dev->mc_list_lock);
+ rcu_read_unlock();
in_dev_put(in4_dev);
netif_carrier_off(card->dev);
@@ -1396,6 +1399,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
int rc, index;
int cstat, dstat;
+ kstat_cpu(smp_processor_id()).irqs[IOINT_LCS]++;
if (lcs_check_irb_error(cdev, irb))
return;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e6b2df0e73f5..29f848bfc12f 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2840,6 +2840,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
queue->card->perf_stats.outbound_do_qdio_time +=
qeth_get_micros() -
queue->card->perf_stats.outbound_do_qdio_start_time;
+ atomic_add(count, &queue->used_buffers);
if (rc) {
queue->card->stats.tx_errors += count;
/* ignore temporary SIGA errors without busy condition */
@@ -2853,7 +2854,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
qeth_schedule_recovery(queue->card);
return;
}
- atomic_add(count, &queue->used_buffers);
if (queue->card->options.performance_stats)
queue->card->perf_stats.bufs_sent += count;
}
@@ -3831,6 +3831,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.int_parm = (unsigned long) card;
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
+ init_data.scan_threshold =
+ (card->info.type == QETH_CARD_TYPE_IQD) ? 8 : 32;
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index e37dd8c4bf4e..07d588867b57 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -333,7 +333,7 @@ struct qeth_arp_query_data {
__u16 request_bits;
__u16 reply_bits;
__u32 no_entries;
- char data;
+ char data; /* only for replies */
} __attribute__((packed));
/* used as parameter for arp_query reply */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 42fa783a70c8..b5e967cf7e2d 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -372,7 +372,7 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev,
i = simple_strtoul(buf, &tmp, 16);
if ((i == 0) || (i == 1)) {
if (i == card->options.performance_stats)
- goto out;;
+ goto out;
card->options.performance_stats = i;
if (i == 0)
memset(&card->perf_stats, 0,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 847e8797073c..7a7a1b664781 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -849,8 +849,6 @@ static int qeth_l2_open(struct net_device *dev)
card->state = CARD_STATE_UP;
netif_start_queue(dev);
- if (!card->lan_online && netif_carrier_ok(dev))
- netif_carrier_off(dev);
if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
napi_enable(&card->napi);
napi_schedule(&card->napi);
@@ -1013,13 +1011,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
card->lan_online = 0;
- goto out;
+ goto contin;
}
rc = -ENODEV;
goto out_remove;
} else
card->lan_online = 1;
+contin:
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX))
/* configure isolation level */
@@ -1038,7 +1037,10 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
goto out_remove;
}
card->state = CARD_STATE_SOFTSETUP;
- netif_carrier_on(card->dev);
+ if (card->lan_online)
+ netif_carrier_on(card->dev);
+ else
+ netif_carrier_off(card->dev);
qeth_set_allowed_threads(card, 0xffffffff, 0);
if (recover_flag == CARD_STATE_RECOVER) {
@@ -1055,7 +1057,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
}
/* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
-out:
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 74d1401a5d5e..e227e465bfc4 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -30,6 +30,7 @@
#include "qeth_l3.h"
+
static int qeth_l3_set_offline(struct ccwgroup_device *);
static int qeth_l3_recover(void *);
static int qeth_l3_stop(struct net_device *);
@@ -455,8 +456,11 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
QETH_CARD_TEXT(card, 2, "sdiplist");
QETH_CARD_HEX(card, 2, &card, sizeof(void *));
- if (card->options.sniffer)
+ if ((card->state != CARD_STATE_UP &&
+ card->state != CARD_STATE_SOFTSETUP) || card->options.sniffer) {
return;
+ }
+
spin_lock_irqsave(&card->ip_lock, flags);
tbd_list = card->ip_tbd_list;
card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
@@ -1796,7 +1800,8 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev)
char buf[MAX_ADDR_LEN];
QETH_CARD_TEXT(card, 4, "addmc");
- for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
+ for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL;
+ im4 = rcu_dereference(im4->next_rcu)) {
qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev);
ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
if (!ipm)
@@ -1828,9 +1833,9 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card)
in_dev = in_dev_get(netdev);
if (!in_dev)
continue;
- read_lock(&in_dev->mc_list_lock);
+ rcu_read_lock();
qeth_l3_add_mc(card, in_dev);
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
in_dev_put(in_dev);
}
}
@@ -1843,10 +1848,10 @@ static void qeth_l3_add_multicast_ipv4(struct qeth_card *card)
in4_dev = in_dev_get(card->dev);
if (in4_dev == NULL)
return;
- read_lock(&in4_dev->mc_list_lock);
+ rcu_read_lock();
qeth_l3_add_mc(card, in4_dev);
qeth_l3_add_vlan_mc(card);
- read_unlock(&in4_dev->mc_list_lock);
+ rcu_read_unlock();
in_dev_put(in4_dev);
}
@@ -2454,22 +2459,46 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries)
return rc;
}
-static void qeth_l3_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
- struct qeth_arp_query_data *qdata, int entry_size,
- int uentry_size)
+static __u32 get_arp_entry_size(struct qeth_card *card,
+ struct qeth_arp_query_data *qdata,
+ struct qeth_arp_entrytype *type, __u8 strip_entries)
{
- char *entry_ptr;
- char *uentry_ptr;
- int i;
+ __u32 rc;
+ __u8 is_hsi;
- entry_ptr = (char *)&qdata->data;
- uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset);
- for (i = 0; i < qdata->no_entries; ++i) {
- /* strip off 32 bytes "media specific information" */
- memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32);
- entry_ptr += entry_size;
- uentry_ptr += uentry_size;
+ is_hsi = qdata->reply_bits == 5;
+ if (type->ip == QETHARP_IP_ADDR_V4) {
+ QETH_CARD_TEXT(card, 4, "arpev4");
+ if (strip_entries) {
+ rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5_short) :
+ sizeof(struct qeth_arp_qi_entry7_short);
+ } else {
+ rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5) :
+ sizeof(struct qeth_arp_qi_entry7);
+ }
+ } else if (type->ip == QETHARP_IP_ADDR_V6) {
+ QETH_CARD_TEXT(card, 4, "arpev6");
+ if (strip_entries) {
+ rc = is_hsi ?
+ sizeof(struct qeth_arp_qi_entry5_short_ipv6) :
+ sizeof(struct qeth_arp_qi_entry7_short_ipv6);
+ } else {
+ rc = is_hsi ?
+ sizeof(struct qeth_arp_qi_entry5_ipv6) :
+ sizeof(struct qeth_arp_qi_entry7_ipv6);
+ }
+ } else {
+ QETH_CARD_TEXT(card, 4, "arpinv");
+ rc = 0;
}
+
+ return rc;
+}
+
+static int arpentry_matches_prot(struct qeth_arp_entrytype *type, __u16 prot)
+{
+ return (type->ip == QETHARP_IP_ADDR_V4 && prot == QETH_PROT_IPV4) ||
+ (type->ip == QETHARP_IP_ADDR_V6 && prot == QETH_PROT_IPV6);
}
static int qeth_l3_arp_query_cb(struct qeth_card *card,
@@ -2478,72 +2507,77 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card,
struct qeth_ipa_cmd *cmd;
struct qeth_arp_query_data *qdata;
struct qeth_arp_query_info *qinfo;
- int entry_size;
- int uentry_size;
int i;
+ int e;
+ int entrybytes_done;
+ int stripped_bytes;
+ __u8 do_strip_entries;
- QETH_CARD_TEXT(card, 4, "arpquecb");
+ QETH_CARD_TEXT(card, 3, "arpquecb");
qinfo = (struct qeth_arp_query_info *) reply->param;
cmd = (struct qeth_ipa_cmd *) data;
+ QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.prot_version);
if (cmd->hdr.return_code) {
- QETH_CARD_TEXT_(card, 4, "qaer1%i", cmd->hdr.return_code);
+ QETH_CARD_TEXT(card, 4, "arpcberr");
+ QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code);
return 0;
}
if (cmd->data.setassparms.hdr.return_code) {
cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
- QETH_CARD_TEXT_(card, 4, "qaer2%i", cmd->hdr.return_code);
+ QETH_CARD_TEXT(card, 4, "setaperr");
+ QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code);
return 0;
}
qdata = &cmd->data.setassparms.data.query_arp;
- switch (qdata->reply_bits) {
- case 5:
- uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5);
- if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
- uentry_size = sizeof(struct qeth_arp_qi_entry5_short);
- break;
- case 7:
- /* fall through to default */
- default:
- /* tr is the same as eth -> entry7 */
- uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7);
- if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
- uentry_size = sizeof(struct qeth_arp_qi_entry7_short);
- break;
- }
- /* check if there is enough room in userspace */
- if ((qinfo->udata_len - qinfo->udata_offset) <
- qdata->no_entries * uentry_size){
- QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM);
- cmd->hdr.return_code = -ENOMEM;
- goto out_error;
- }
- QETH_CARD_TEXT_(card, 4, "anore%i",
- cmd->data.setassparms.hdr.number_of_replies);
- QETH_CARD_TEXT_(card, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no);
QETH_CARD_TEXT_(card, 4, "anoen%i", qdata->no_entries);
- if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) {
- /* strip off "media specific information" */
- qeth_l3_copy_arp_entries_stripped(qinfo, qdata, entry_size,
- uentry_size);
- } else
- /*copy entries to user buffer*/
- memcpy(qinfo->udata + qinfo->udata_offset,
- (char *)&qdata->data, qdata->no_entries*uentry_size);
+ do_strip_entries = (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) > 0;
+ stripped_bytes = do_strip_entries ? QETH_QARP_MEDIASPECIFIC_BYTES : 0;
+ entrybytes_done = 0;
+ for (e = 0; e < qdata->no_entries; ++e) {
+ char *cur_entry;
+ __u32 esize;
+ struct qeth_arp_entrytype *etype;
+
+ cur_entry = &qdata->data + entrybytes_done;
+ etype = &((struct qeth_arp_qi_entry5 *) cur_entry)->type;
+ if (!arpentry_matches_prot(etype, cmd->hdr.prot_version)) {
+ QETH_CARD_TEXT(card, 4, "pmis");
+ QETH_CARD_TEXT_(card, 4, "%i", etype->ip);
+ break;
+ }
+ esize = get_arp_entry_size(card, qdata, etype,
+ do_strip_entries);
+ QETH_CARD_TEXT_(card, 5, "esz%i", esize);
+ if (!esize)
+ break;
+
+ if ((qinfo->udata_len - qinfo->udata_offset) < esize) {
+ QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM);
+ cmd->hdr.return_code = -ENOMEM;
+ goto out_error;
+ }
- qinfo->no_entries += qdata->no_entries;
- qinfo->udata_offset += (qdata->no_entries*uentry_size);
+ memcpy(qinfo->udata + qinfo->udata_offset,
+ &qdata->data + entrybytes_done + stripped_bytes,
+ esize);
+ entrybytes_done += esize + stripped_bytes;
+ qinfo->udata_offset += esize;
+ ++qinfo->no_entries;
+ }
/* check if all replies received ... */
if (cmd->data.setassparms.hdr.seq_no <
cmd->data.setassparms.hdr.number_of_replies)
return 1;
+ QETH_CARD_TEXT_(card, 4, "nove%i", qinfo->no_entries);
memcpy(qinfo->udata, &qinfo->no_entries, 4);
/* keep STRIP_ENTRIES flag so the user program can distinguish
* stripped entries from normal ones */
if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES;
memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET, &qdata->reply_bits, 2);
+ QETH_CARD_TEXT_(card, 4, "rc%i", 0);
return 0;
out_error:
i = 0;
@@ -2566,45 +2600,86 @@ static int qeth_l3_send_ipa_arp_cmd(struct qeth_card *card,
reply_cb, reply_param);
}
-static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
+static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
+ enum qeth_prot_versions prot,
+ struct qeth_arp_query_info *qinfo)
{
struct qeth_cmd_buffer *iob;
- struct qeth_arp_query_info qinfo = {0, };
+ struct qeth_ipa_cmd *cmd;
int tmp;
int rc;
+ QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot);
+
+ iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
+ IPA_CMD_ASS_ARP_QUERY_INFO,
+ sizeof(struct qeth_arp_query_data) - sizeof(char),
+ prot);
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ cmd->data.setassparms.data.query_arp.request_bits = 0x000F;
+ cmd->data.setassparms.data.query_arp.reply_bits = 0;
+ cmd->data.setassparms.data.query_arp.no_entries = 0;
+ rc = qeth_l3_send_ipa_arp_cmd(card, iob,
+ QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
+ qeth_l3_arp_query_cb, (void *)qinfo);
+ if (rc) {
+ tmp = rc;
+ QETH_DBF_MESSAGE(2,
+ "Error while querying ARP cache on %s: %s "
+ "(0x%x/%d)\n", QETH_CARD_IFNAME(card),
+ qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
+ }
+
+ return rc;
+}
+
+static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
+{
+ struct qeth_arp_query_info qinfo = {0, };
+ int rc;
+
QETH_CARD_TEXT(card, 3, "arpquery");
if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
IPA_ARP_PROCESSING)) {
- return -EOPNOTSUPP;
+ QETH_CARD_TEXT(card, 3, "arpqnsup");
+ rc = -EOPNOTSUPP;
+ goto out;
}
/* get size of userspace buffer and mask_bits -> 6 bytes */
- if (copy_from_user(&qinfo, udata, 6))
- return -EFAULT;
+ if (copy_from_user(&qinfo, udata, 6)) {
+ rc = -EFAULT;
+ goto out;
+ }
qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
- if (!qinfo.udata)
- return -ENOMEM;
+ if (!qinfo.udata) {
+ rc = -ENOMEM;
+ goto out;
+ }
qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
- iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
- IPA_CMD_ASS_ARP_QUERY_INFO,
- sizeof(int), QETH_PROT_IPV4);
-
- rc = qeth_l3_send_ipa_arp_cmd(card, iob,
- QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
- qeth_l3_arp_query_cb, (void *)&qinfo);
+ rc = qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV4, &qinfo);
if (rc) {
- tmp = rc;
- QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s "
- "(0x%x/%d)\n", QETH_CARD_IFNAME(card),
- qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
if (copy_to_user(udata, qinfo.udata, 4))
rc = -EFAULT;
+ goto free_and_out;
} else {
- if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
+#ifdef CONFIG_QETH_IPV6
+ if (qinfo.mask_bits & QETH_QARP_WITH_IPV6) {
+ /* fails in case of GuestLAN QDIO mode */
+ qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV6,
+ &qinfo);
+ }
+#endif
+ if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) {
+ QETH_CARD_TEXT(card, 4, "qactf");
rc = -EFAULT;
+ goto free_and_out;
+ }
+ QETH_CARD_TEXT_(card, 4, "qacts");
}
+free_and_out:
kfree(qinfo.udata);
+out:
return rc;
}
@@ -2938,6 +3013,7 @@ static void qeth_tso_fill_header(struct qeth_card *card,
/*fix header to TSO values ...*/
hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
+ hdr->hdr.hdr.l3.length = skb->len - sizeof(struct qeth_hdr_tso);
/*set values which are fix for the first approach ...*/
hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
hdr->ext.imb_hdr_no = 1;
@@ -3039,7 +3115,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb_pull(new_skb, ETH_HLEN);
}
- if (ipv == 6 && card->vlangrp &&
+ if (ipv != 4 && 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);
@@ -3176,8 +3252,6 @@ static int qeth_l3_open(struct net_device *dev)
card->state = CARD_STATE_UP;
netif_start_queue(dev);
- if (!card->lan_online && netif_carrier_ok(dev))
- netif_carrier_off(dev);
if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
napi_enable(&card->napi);
napi_schedule(&card->napi);
@@ -3449,13 +3523,14 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
card->lan_online = 0;
- goto out;
+ goto contin;
}
rc = -ENODEV;
goto out_remove;
} else
card->lan_online = 1;
+contin:
rc = qeth_l3_setadapter_parms(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
@@ -3480,10 +3555,13 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
goto out_remove;
}
card->state = CARD_STATE_SOFTSETUP;
- netif_carrier_on(card->dev);
qeth_set_allowed_threads(card, 0xffffffff, 0);
qeth_l3_set_ip_addr_list(card);
+ if (card->lan_online)
+ netif_carrier_on(card->dev);
+ else
+ netif_carrier_off(card->dev);
if (recover_flag == CARD_STATE_RECOVER) {
if (recovery_mode)
qeth_l3_open(card->dev);
@@ -3496,7 +3574,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
}
/* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
-out:
mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 044fb22718d2..51c666fb67a4 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -45,8 +45,8 @@ static char *init_device;
module_param_named(device, init_device, charp, 0400);
MODULE_PARM_DESC(device, "specify initial device");
-static struct kmem_cache *zfcp_cache_hw_align(const char *name,
- unsigned long size)
+static struct kmem_cache * __init zfcp_cache_hw_align(const char *name,
+ unsigned long size)
{
return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
}
@@ -311,8 +311,7 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter)
if (zfcp_fsf_status_read(adapter->qdio)) {
if (atomic_read(&adapter->stat_miss) >=
adapter->stat_read_buf_num) {
- zfcp_erp_adapter_reopen(adapter, 0, "axsref1",
- NULL);
+ zfcp_erp_adapter_reopen(adapter, 0, "axsref1");
return 1;
}
break;
@@ -459,7 +458,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
zfcp_erp_thread_kill(adapter);
- zfcp_dbf_adapter_unregister(adapter->dbf);
+ zfcp_dbf_adapter_unregister(adapter);
zfcp_qdio_destroy(adapter->qdio);
zfcp_ccw_adapter_put(adapter); /* final put to release */
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 0833c2b51e39..4f7852dd30c7 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -48,7 +48,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- "ccresu2", NULL);
+ "ccresu2");
zfcp_erp_wait(adapter);
flush_work(&adapter->scan_work);
@@ -182,7 +182,7 @@ static int zfcp_ccw_set_offline(struct ccw_device *cdev)
if (!adapter)
return 0;
- zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
zfcp_erp_wait(adapter);
zfcp_ccw_adapter_put(adapter);
@@ -207,24 +207,24 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
switch (event) {
case CIO_GONE:
dev_warn(&cdev->dev, "The FCP device has been detached\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
break;
case CIO_NO_PATH:
dev_warn(&cdev->dev,
"The CHPID for the FCP device is offline\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
break;
case CIO_OPER:
dev_info(&cdev->dev, "The FCP device is operational again\n");
zfcp_erp_set_adapter_status(adapter,
ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- "ccnoti4", NULL);
+ "ccnoti4");
break;
case CIO_BOXED:
dev_warn(&cdev->dev, "The FCP device did not respond within "
"the specified time\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
break;
}
@@ -243,7 +243,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
if (!adapter)
return;
- zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter);
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index d692e229ecba..46342fee394d 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -288,7 +288,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
(status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "cfaac_1", NULL);
+ "cfaac_1");
}
read_unlock_irqrestore(&adapter->port_list_lock, flags);
@@ -299,7 +299,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
(status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
zfcp_erp_lun_reopen(sdev,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "cfaac_2", NULL);
+ "cfaac_2");
}
}
@@ -426,7 +426,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
- zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
+ zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6");
return -EACCES;
}
@@ -437,7 +437,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
- zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
+ zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8");
return -EACCES;
}
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 2cdd6b28ff7f..96d1462e0bf5 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -3,7 +3,7 @@
*
* Debug traces for zfcp.
*
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
*/
#define KMSG_COMPONENT "zfcp"
@@ -22,980 +22,392 @@ module_param(dbfsize, uint, 0400);
MODULE_PARM_DESC(dbfsize,
"number of pages for each debug feature area (default 4)");
-static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
- int level, char *from, int from_len)
+static inline unsigned int zfcp_dbf_plen(unsigned int offset)
{
- int offset;
- struct zfcp_dbf_dump *dump = to;
- int room = to_len - sizeof(*dump);
-
- for (offset = 0; offset < from_len; offset += dump->size) {
- memset(to, 0, to_len);
- strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
- dump->total_size = from_len;
- dump->offset = offset;
- dump->size = min(from_len - offset, room);
- memcpy(dump->data, from + offset, dump->size);
- debug_event(dbf, level, dump, dump->size + sizeof(*dump));
- }
+ return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC;
}
-static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
+static inline
+void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area,
+ u64 req_id)
{
- int i;
-
- *p += sprintf(*p, "%-24s", label);
- for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
- *p += sprintf(*p, "%c", tag[i]);
- *p += sprintf(*p, "\n");
-}
+ struct zfcp_dbf_pay *pl = &dbf->pay_buf;
+ u16 offset = 0, rec_length;
-static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
-{
- *buf += sprintf(*buf, "%-24s%s\n", s1, s2);
-}
+ spin_lock(&dbf->pay_lock);
+ memset(pl, 0, sizeof(*pl));
+ pl->fsf_req_id = req_id;
+ memcpy(pl->area, area, ZFCP_DBF_TAG_LEN);
-static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
-{
- va_list arg;
+ while (offset < length) {
+ rec_length = min((u16) ZFCP_DBF_PAY_MAX_REC,
+ (u16) (length - offset));
+ memcpy(pl->data, data + offset, rec_length);
+ debug_event(dbf->pay, 1, pl, zfcp_dbf_plen(rec_length));
- *buf += sprintf(*buf, "%-24s", s);
- va_start(arg, format);
- *buf += vsprintf(*buf, format, arg);
- va_end(arg);
- *buf += sprintf(*buf, "\n");
-}
-
-static void zfcp_dbf_outd(char **p, const char *label, char *buffer,
- int buflen, int offset, int total_size)
-{
- if (!offset)
- *p += sprintf(*p, "%-24s ", label);
- while (buflen--) {
- if (offset > 0) {
- if ((offset % 32) == 0)
- *p += sprintf(*p, "\n%-24c ", ' ');
- else if ((offset % 4) == 0)
- *p += sprintf(*p, " ");
- }
- *p += sprintf(*p, "%02x", *buffer++);
- if (++offset == total_size) {
- *p += sprintf(*p, "\n");
- break;
- }
+ offset += rec_length;
+ pl->counter++;
}
- if (!total_size)
- *p += sprintf(*p, "\n");
-}
-static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
- int area, debug_entry_t *entry, char *out_buf)
-{
- struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
- struct timespec t;
- char *p = out_buf;
-
- if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
- stck_to_timespec(entry->id.stck, &t);
- zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu",
- t.tv_sec, t.tv_nsec);
- zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
- } else {
- zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
- dump->total_size);
- if ((dump->offset + dump->size) == dump->total_size)
- p += sprintf(p, "\n");
- }
- return p - out_buf;
+ spin_unlock(&dbf->pay_lock);
}
-void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
- struct zfcp_fsf_req *fsf_req,
- struct zfcp_dbf *dbf)
+/**
+ * zfcp_dbf_hba_fsf_res - trace event for fsf responses
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request for which a response was received
+ */
+void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
{
- struct fsf_qtcb *qtcb = fsf_req->qtcb;
- union fsf_prot_status_qual *prot_status_qual =
- &qtcb->prefix.prot_status_qual;
- union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
- struct scsi_cmnd *scsi_cmnd;
- struct zfcp_port *port;
- struct zfcp_unit *unit;
- struct zfcp_send_els *send_els;
- struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
- struct zfcp_dbf_hba_record_response *response = &rec->u.response;
+ struct zfcp_dbf *dbf = req->adapter->dbf;
+ struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix;
+ struct fsf_qtcb_header *q_head = &req->qtcb->header;
+ struct zfcp_dbf_hba *rec = &dbf->hba_buf;
unsigned long flags;
spin_lock_irqsave(&dbf->hba_lock, flags);
memset(rec, 0, sizeof(*rec));
- strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
- strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
-
- response->fsf_command = fsf_req->fsf_command;
- response->fsf_reqid = fsf_req->req_id;
- response->fsf_seqno = fsf_req->seq_no;
- response->fsf_issued = fsf_req->issued;
- response->fsf_prot_status = qtcb->prefix.prot_status;
- response->fsf_status = qtcb->header.fsf_status;
- memcpy(response->fsf_prot_status_qual,
- prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
- memcpy(response->fsf_status_qual,
- fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
- response->fsf_req_status = fsf_req->status;
- response->sbal_first = fsf_req->qdio_req.sbal_first;
- response->sbal_last = fsf_req->qdio_req.sbal_last;
- response->sbal_response = fsf_req->qdio_req.sbal_response;
- response->pool = fsf_req->pool != NULL;
- response->erp_action = (unsigned long)fsf_req->erp_action;
-
- switch (fsf_req->fsf_command) {
- case FSF_QTCB_FCP_CMND:
- if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
- break;
- scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
- if (scsi_cmnd) {
- response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
- response->u.fcp.data_dir =
- qtcb->bottom.io.data_direction;
- }
- break;
-
- case FSF_QTCB_OPEN_PORT_WITH_DID:
- case FSF_QTCB_CLOSE_PORT:
- case FSF_QTCB_CLOSE_PHYSICAL_PORT:
- port = (struct zfcp_port *)fsf_req->data;
- response->u.port.wwpn = port->wwpn;
- response->u.port.d_id = port->d_id;
- response->u.port.port_handle = qtcb->header.port_handle;
- break;
-
- case FSF_QTCB_OPEN_LUN:
- case FSF_QTCB_CLOSE_LUN:
- unit = (struct zfcp_unit *)fsf_req->data;
- port = unit->port;
- response->u.unit.wwpn = port->wwpn;
- response->u.unit.fcp_lun = unit->fcp_lun;
- response->u.unit.port_handle = qtcb->header.port_handle;
- response->u.unit.lun_handle = qtcb->header.lun_handle;
- break;
-
- case FSF_QTCB_SEND_ELS:
- send_els = (struct zfcp_send_els *)fsf_req->data;
- response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id);
- break;
-
- case FSF_QTCB_ABORT_FCP_CMND:
- case FSF_QTCB_SEND_GENERIC:
- case FSF_QTCB_EXCHANGE_CONFIG_DATA:
- case FSF_QTCB_EXCHANGE_PORT_DATA:
- case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
- case FSF_QTCB_UPLOAD_CONTROL_FILE:
- break;
- }
-
- debug_event(dbf->hba, level, rec, sizeof(*rec));
- /* have fcp channel microcode fixed to use as little as possible */
- if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
- /* adjust length skipping trailing zeros */
- char *buf = (char *)qtcb + qtcb->header.log_start;
- int len = qtcb->header.log_length;
- for (; len && !buf[len - 1]; len--);
- zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf,
- len);
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->id = ZFCP_DBF_HBA_RES;
+ rec->fsf_req_id = req->req_id;
+ rec->fsf_req_status = req->status;
+ rec->fsf_cmd = req->fsf_command;
+ rec->fsf_seq_no = req->seq_no;
+ rec->u.res.req_issued = req->issued;
+ rec->u.res.prot_status = q_pref->prot_status;
+ rec->u.res.fsf_status = q_head->fsf_status;
+
+ memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual,
+ FSF_PROT_STATUS_QUAL_SIZE);
+ memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
+ FSF_STATUS_QUALIFIER_SIZE);
+
+ if (req->fsf_command != FSF_QTCB_FCP_CMND) {
+ rec->pl_len = q_head->log_length;
+ zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
+ rec->pl_len, "fsf_res", req->req_id);
}
- spin_unlock_irqrestore(&dbf->hba_lock, flags);
-}
-
-void _zfcp_dbf_hba_fsf_unsol(const char *tag, int level, struct zfcp_dbf *dbf,
- struct fsf_status_read_buffer *status_buffer)
-{
- struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
- unsigned long flags;
-
- spin_lock_irqsave(&dbf->hba_lock, flags);
- memset(rec, 0, sizeof(*rec));
- strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
- strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
-
- rec->u.status.failed = atomic_read(&dbf->adapter->stat_miss);
- if (status_buffer != NULL) {
- rec->u.status.status_type = status_buffer->status_type;
- rec->u.status.status_subtype = status_buffer->status_subtype;
- memcpy(&rec->u.status.queue_designator,
- &status_buffer->queue_designator,
- sizeof(struct fsf_queue_designator));
-
- switch (status_buffer->status_type) {
- case FSF_STATUS_READ_SENSE_DATA_AVAIL:
- rec->u.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
- break;
-
- case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
- rec->u.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
- break;
-
- case FSF_STATUS_READ_LINK_DOWN:
- switch (status_buffer->status_subtype) {
- case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
- case FSF_STATUS_READ_SUB_FDISC_FAILED:
- rec->u.status.payload_size =
- sizeof(struct fsf_link_down_info);
- }
- break;
-
- case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
- rec->u.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
- break;
- }
- memcpy(&rec->u.status.payload,
- &status_buffer->payload, rec->u.status.payload_size);
- }
-
- debug_event(dbf->hba, level, rec, sizeof(*rec));
+ debug_event(dbf->hba, 1, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->hba_lock, flags);
}
/**
- * zfcp_dbf_hba_qdio - trace event for QDIO related failure
- * @qdio: qdio structure affected by this QDIO related event
- * @qdio_error: as passed by qdio module
- * @sbal_index: first buffer with error condition, as passed by qdio module
- * @sbal_count: number of buffers affected, as passed by qdio module
+ * zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request providing the unsolicited status
*/
-void zfcp_dbf_hba_qdio(struct zfcp_dbf *dbf, unsigned int qdio_error,
- int sbal_index, int sbal_count)
+void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req)
{
- struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
+ struct zfcp_dbf *dbf = req->adapter->dbf;
+ struct fsf_status_read_buffer *srb = req->data;
+ struct zfcp_dbf_hba *rec = &dbf->hba_buf;
unsigned long flags;
spin_lock_irqsave(&dbf->hba_lock, flags);
- memset(r, 0, sizeof(*r));
- strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE);
- r->u.qdio.qdio_error = qdio_error;
- r->u.qdio.sbal_index = sbal_index;
- r->u.qdio.sbal_count = sbal_count;
- debug_event(dbf->hba, 0, r, sizeof(*r));
+ memset(rec, 0, sizeof(*rec));
+
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->id = ZFCP_DBF_HBA_USS;
+ rec->fsf_req_id = req->req_id;
+ rec->fsf_req_status = req->status;
+ rec->fsf_cmd = req->fsf_command;
+
+ if (!srb)
+ goto log;
+
+ rec->u.uss.status_type = srb->status_type;
+ rec->u.uss.status_subtype = srb->status_subtype;
+ rec->u.uss.d_id = ntoh24(srb->d_id);
+ rec->u.uss.lun = srb->fcp_lun;
+ memcpy(&rec->u.uss.queue_designator, &srb->queue_designator,
+ sizeof(rec->u.uss.queue_designator));
+
+ /* status read buffer payload length */
+ rec->pl_len = (!srb->length) ? 0 : srb->length -
+ offsetof(struct fsf_status_read_buffer, payload);
+
+ if (rec->pl_len)
+ zfcp_dbf_pl_write(dbf, srb->payload.data, rec->pl_len,
+ "fsf_uss", req->req_id);
+log:
+ debug_event(dbf->hba, 2, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->hba_lock, flags);
}
/**
- * zfcp_dbf_hba_berr - trace event for bit error threshold
- * @dbf: dbf structure affected by this QDIO related event
- * @req: fsf request
+ * zfcp_dbf_hba_bit_err - trace event for bit error conditions
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request which caused the bit_error condition
*/
-void zfcp_dbf_hba_berr(struct zfcp_dbf *dbf, struct zfcp_fsf_req *req)
+void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req)
{
- struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
+ struct zfcp_dbf *dbf = req->adapter->dbf;
+ struct zfcp_dbf_hba *rec = &dbf->hba_buf;
struct fsf_status_read_buffer *sr_buf = req->data;
- struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
unsigned long flags;
spin_lock_irqsave(&dbf->hba_lock, flags);
- memset(r, 0, sizeof(*r));
- strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
- memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
- debug_event(dbf->hba, 0, r, sizeof(*r));
- spin_unlock_irqrestore(&dbf->hba_lock, flags);
-}
-static void zfcp_dbf_hba_view_response(char **p,
- struct zfcp_dbf_hba_record_response *r)
-{
- struct timespec t;
-
- zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command);
- zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
- zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno);
- stck_to_timespec(r->fsf_issued, &t);
- zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
- zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status);
- zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status);
- zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual,
- FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE);
- zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual,
- FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE);
- zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status);
- zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first);
- zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last);
- zfcp_dbf_out(p, "sbal_response", "0x%02x", r->sbal_response);
- zfcp_dbf_out(p, "pool", "0x%02x", r->pool);
-
- switch (r->fsf_command) {
- case FSF_QTCB_FCP_CMND:
- if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
- break;
- zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir);
- zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
- *p += sprintf(*p, "\n");
- break;
-
- case FSF_QTCB_OPEN_PORT_WITH_DID:
- case FSF_QTCB_CLOSE_PORT:
- case FSF_QTCB_CLOSE_PHYSICAL_PORT:
- zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn);
- zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id);
- zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle);
- break;
-
- case FSF_QTCB_OPEN_LUN:
- case FSF_QTCB_CLOSE_LUN:
- zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn);
- zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun);
- zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle);
- zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle);
- break;
-
- case FSF_QTCB_SEND_ELS:
- zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
- break;
-
- case FSF_QTCB_ABORT_FCP_CMND:
- case FSF_QTCB_SEND_GENERIC:
- case FSF_QTCB_EXCHANGE_CONFIG_DATA:
- case FSF_QTCB_EXCHANGE_PORT_DATA:
- case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
- case FSF_QTCB_UPLOAD_CONTROL_FILE:
- break;
- }
-}
-
-static void zfcp_dbf_hba_view_status(char **p,
- struct zfcp_dbf_hba_record_status *r)
-{
- zfcp_dbf_out(p, "failed", "0x%02x", r->failed);
- zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type);
- zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype);
- zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator,
- sizeof(struct fsf_queue_designator), 0,
- sizeof(struct fsf_queue_designator));
- zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0,
- r->payload_size);
-}
-
-static void zfcp_dbf_hba_view_qdio(char **p, struct zfcp_dbf_hba_record_qdio *r)
-{
- zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error);
- zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index);
- zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
-}
+ memset(rec, 0, sizeof(*rec));
-static void zfcp_dbf_hba_view_berr(char **p, struct fsf_bit_error_payload *r)
-{
- zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
- zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
- zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count);
- zfcp_dbf_out(p, "prim_seq_err", "%d",
- r->primitive_sequence_error_count);
- zfcp_dbf_out(p, "inval_trans_word_err", "%d",
- r->invalid_transmission_word_error_count);
- zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count);
- zfcp_dbf_out(p, "prim_seq_event_to", "%d",
- r->primitive_sequence_event_timeout_count);
- zfcp_dbf_out(p, "elast_buf_overrun_err", "%d",
- r->elastic_buffer_overrun_error_count);
- zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d",
- r->advertised_receive_b2b_credit);
- zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d",
- r->current_receive_b2b_credit);
- zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d",
- r->advertised_transmit_b2b_credit);
- zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d",
- r->current_transmit_b2b_credit);
-}
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->id = ZFCP_DBF_HBA_BIT;
+ rec->fsf_req_id = req->req_id;
+ rec->fsf_req_status = req->status;
+ rec->fsf_cmd = req->fsf_command;
+ memcpy(&rec->u.be, &sr_buf->payload.bit_error,
+ sizeof(struct fsf_bit_error_payload));
-static int zfcp_dbf_hba_view_format(debug_info_t *id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_dbf_hba_record *r = (struct zfcp_dbf_hba_record *)in_buf;
- char *p = out_buf;
-
- if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- zfcp_dbf_tag(&p, "tag", r->tag);
- if (isalpha(r->tag2[0]))
- zfcp_dbf_tag(&p, "tag2", r->tag2);
-
- if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
- zfcp_dbf_hba_view_response(&p, &r->u.response);
- else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
- zfcp_dbf_hba_view_status(&p, &r->u.status);
- else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
- zfcp_dbf_hba_view_qdio(&p, &r->u.qdio);
- else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
- zfcp_dbf_hba_view_berr(&p, &r->u.berr);
-
- if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
- p += sprintf(p, "\n");
- return p - out_buf;
+ debug_event(dbf->hba, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->hba_lock, flags);
}
-static struct debug_view zfcp_dbf_hba_view = {
- .name = "structured",
- .header_proc = zfcp_dbf_view_header,
- .format_proc = zfcp_dbf_hba_view_format,
-};
-
-static const char *zfcp_dbf_rec_tags[] = {
- [ZFCP_REC_DBF_ID_THREAD] = "thread",
- [ZFCP_REC_DBF_ID_TARGET] = "target",
- [ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
- [ZFCP_REC_DBF_ID_ACTION] = "action",
-};
-
-static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view,
- char *buf, const char *_rec)
+static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
+ struct zfcp_adapter *adapter,
+ struct zfcp_port *port,
+ struct scsi_device *sdev)
{
- struct zfcp_dbf_rec_record *r = (struct zfcp_dbf_rec_record *)_rec;
- char *p = buf;
- char hint[ZFCP_DBF_ID_SIZE + 1];
-
- memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE);
- hint[ZFCP_DBF_ID_SIZE] = 0;
- zfcp_dbf_outs(&p, "tag", zfcp_dbf_rec_tags[r->id]);
- zfcp_dbf_outs(&p, "hint", hint);
- switch (r->id) {
- case ZFCP_REC_DBF_ID_THREAD:
- zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
- zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready);
- zfcp_dbf_out(&p, "running", "%d", r->u.thread.running);
- break;
- case ZFCP_REC_DBF_ID_TARGET:
- zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref);
- zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status);
- zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count);
- zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id);
- zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn);
- zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun);
- break;
- case ZFCP_REC_DBF_ID_TRIGGER:
- zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref);
- zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action);
- zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want);
- zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need);
- zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn);
- zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
- zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
- zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
- zfcp_dbf_out(&p, "lun_status", "0x%08x", r->u.trigger.ls);
- break;
- case ZFCP_REC_DBF_ID_ACTION:
- zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
- zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req);
- zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status);
- zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step);
- break;
+ rec->adapter_status = atomic_read(&adapter->status);
+ if (port) {
+ rec->port_status = atomic_read(&port->status);
+ rec->wwpn = port->wwpn;
+ rec->d_id = port->d_id;
+ }
+ if (sdev) {
+ rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status);
+ rec->lun = zfcp_scsi_dev_lun(sdev);
}
- p += sprintf(p, "\n");
- return p - buf;
}
-static struct debug_view zfcp_dbf_rec_view = {
- .name = "structured",
- .header_proc = zfcp_dbf_view_header,
- .format_proc = zfcp_dbf_rec_view_format,
-};
-
/**
- * zfcp_dbf_rec_thread - trace event related to recovery thread operation
- * @id2: identifier for event
- * @dbf: reference to dbf structure
- * This function assumes that the caller is holding erp_lock.
+ * zfcp_dbf_rec_trig - trace event related to triggered recovery
+ * @tag: identifier for event
+ * @adapter: adapter on which the erp_action should run
+ * @port: remote port involved in the erp_action
+ * @sdev: scsi device involved in the erp_action
+ * @want: wanted erp_action
+ * @need: required erp_action
+ *
+ * The adapter->erp_lock has to be held.
*/
-void zfcp_dbf_rec_thread(char *id2, struct zfcp_dbf *dbf)
+void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
+ struct zfcp_port *port, struct scsi_device *sdev,
+ u8 want, u8 need)
{
- struct zfcp_adapter *adapter = dbf->adapter;
- struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
- unsigned long flags = 0;
+ struct zfcp_dbf *dbf = adapter->dbf;
+ struct zfcp_dbf_rec *rec = &dbf->rec_buf;
struct list_head *entry;
- unsigned ready = 0, running = 0, total;
-
- list_for_each(entry, &adapter->erp_ready_head)
- ready++;
- list_for_each(entry, &adapter->erp_running_head)
- running++;
- total = adapter->erp_total_count;
-
- spin_lock_irqsave(&dbf->rec_lock, flags);
- memset(r, 0, sizeof(*r));
- r->id = ZFCP_REC_DBF_ID_THREAD;
- memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
- r->u.thread.total = total;
- r->u.thread.ready = ready;
- r->u.thread.running = running;
- debug_event(dbf->rec, 6, r, sizeof(*r));
- spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
-
-/**
- * zfcp_dbf_rec_thread - trace event related to recovery thread operation
- * @id2: identifier for event
- * @adapter: adapter
- * This function assumes that the caller does not hold erp_lock.
- */
-void zfcp_dbf_rec_thread_lock(char *id2, struct zfcp_dbf *dbf)
-{
- struct zfcp_adapter *adapter = dbf->adapter;
- unsigned long flags;
-
- read_lock_irqsave(&adapter->erp_lock, flags);
- zfcp_dbf_rec_thread(id2, dbf);
- read_unlock_irqrestore(&adapter->erp_lock, flags);
-}
-
-static void zfcp_dbf_rec_target(char *id2, void *ref, struct zfcp_dbf *dbf,
- atomic_t *status, atomic_t *erp_count, u64 wwpn,
- u32 d_id, u64 fcp_lun)
-{
- struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
unsigned long flags;
spin_lock_irqsave(&dbf->rec_lock, flags);
- memset(r, 0, sizeof(*r));
- r->id = ZFCP_REC_DBF_ID_TARGET;
- memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
- r->u.target.ref = (unsigned long)ref;
- r->u.target.status = atomic_read(status);
- r->u.target.wwpn = wwpn;
- r->u.target.d_id = d_id;
- r->u.target.fcp_lun = fcp_lun;
- r->u.target.erp_count = atomic_read(erp_count);
- debug_event(dbf->rec, 3, r, sizeof(*r));
- spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
-
-/**
- * zfcp_dbf_rec_adapter - trace event for adapter state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @dbf: reference to dbf structure
- */
-void zfcp_dbf_rec_adapter(char *id, void *ref, struct zfcp_dbf *dbf)
-{
- struct zfcp_adapter *adapter = dbf->adapter;
-
- zfcp_dbf_rec_target(id, ref, dbf, &adapter->status,
- &adapter->erp_counter, 0, 0,
- ZFCP_DBF_INVALID_LUN);
-}
-
-/**
- * zfcp_dbf_rec_port - trace event for port state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @port: port
- */
-void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port)
-{
- struct zfcp_dbf *dbf = port->adapter->dbf;
+ memset(rec, 0, sizeof(*rec));
- zfcp_dbf_rec_target(id, ref, dbf, &port->status,
- &port->erp_counter, port->wwpn, port->d_id,
- ZFCP_DBF_INVALID_LUN);
-}
+ rec->id = ZFCP_DBF_REC_TRIG;
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ zfcp_dbf_set_common(rec, adapter, port, sdev);
-/**
- * zfcp_dbf_rec_lun - trace event for LUN state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @sdev: SCSI device
- */
-void zfcp_dbf_rec_lun(char *id, void *ref, struct scsi_device *sdev)
-{
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
- struct zfcp_port *port = zfcp_sdev->port;
- struct zfcp_dbf *dbf = port->adapter->dbf;
+ list_for_each(entry, &adapter->erp_ready_head)
+ rec->u.trig.ready++;
- zfcp_dbf_rec_target(id, ref, dbf, &zfcp_sdev->status,
- &zfcp_sdev->erp_counter, port->wwpn, port->d_id,
- zfcp_scsi_dev_lun(sdev));
-}
+ list_for_each(entry, &adapter->erp_running_head)
+ rec->u.trig.running++;
-/**
- * zfcp_dbf_rec_trigger - trace event for triggered error recovery
- * @id2: identifier for error recovery trigger
- * @ref: additional reference (e.g. request)
- * @want: originally requested error recovery action
- * @need: error recovery action actually initiated
- * @action: address of error recovery action struct
- * @adapter: adapter
- * @port: port
- * @sdev: SCSI device
- */
-void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
- struct zfcp_adapter *adapter, struct zfcp_port *port,
- struct scsi_device *sdev)
-{
- struct zfcp_dbf *dbf = adapter->dbf;
- struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
- unsigned long flags;
+ rec->u.trig.want = want;
+ rec->u.trig.need = need;
- spin_lock_irqsave(&dbf->rec_lock, flags);
- memset(r, 0, sizeof(*r));
- r->id = ZFCP_REC_DBF_ID_TRIGGER;
- memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
- r->u.trigger.ref = (unsigned long)ref;
- r->u.trigger.want = want;
- r->u.trigger.need = need;
- r->u.trigger.action = (unsigned long)action;
- r->u.trigger.as = atomic_read(&adapter->status);
- if (port) {
- r->u.trigger.ps = atomic_read(&port->status);
- r->u.trigger.wwpn = port->wwpn;
- }
- if (sdev)
- r->u.trigger.ls = atomic_read(&sdev_to_zfcp(sdev)->status);
- r->u.trigger.fcp_lun = sdev ? zfcp_scsi_dev_lun(sdev) :
- ZFCP_DBF_INVALID_LUN;
- debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
+ debug_event(dbf->rec, 1, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->rec_lock, flags);
}
+
/**
- * zfcp_dbf_rec_action - trace event showing progress of recovery action
- * @id2: identifier
- * @erp_action: error recovery action struct pointer
+ * zfcp_dbf_rec_run - trace event related to running recovery
+ * @tag: identifier for event
+ * @erp: erp_action running
*/
-void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action)
+void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
{
- struct zfcp_dbf *dbf = erp_action->adapter->dbf;
- struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
+ struct zfcp_dbf *dbf = erp->adapter->dbf;
+ struct zfcp_dbf_rec *rec = &dbf->rec_buf;
unsigned long flags;
spin_lock_irqsave(&dbf->rec_lock, flags);
- memset(r, 0, sizeof(*r));
- r->id = ZFCP_REC_DBF_ID_ACTION;
- memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
- r->u.action.action = (unsigned long)erp_action;
- r->u.action.status = erp_action->status;
- r->u.action.step = erp_action->step;
- r->u.action.fsf_req = erp_action->fsf_req_id;
- debug_event(dbf->rec, 5, r, sizeof(*r));
- spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
+ memset(rec, 0, sizeof(*rec));
-/**
- * zfcp_dbf_san_ct_request - trace event for issued CT request
- * @fsf_req: request containing issued CT data
- * @d_id: destination id where ct request is sent to
- */
-void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id)
-{
- struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct zfcp_dbf *dbf = adapter->dbf;
- struct fc_ct_hdr *hdr = sg_virt(ct->req);
- struct zfcp_dbf_san_record *r = &dbf->san_buf;
- struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
- int level = 3;
- unsigned long flags;
+ rec->id = ZFCP_DBF_REC_RUN;
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ zfcp_dbf_set_common(rec, erp->adapter, erp->port, erp->sdev);
- spin_lock_irqsave(&dbf->san_lock, flags);
- memset(r, 0, sizeof(*r));
- strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
- r->fsf_reqid = fsf_req->req_id;
- r->fsf_seqno = fsf_req->seq_no;
- oct->d_id = d_id;
- oct->cmd_req_code = hdr->ct_cmd;
- oct->revision = hdr->ct_rev;
- oct->gs_type = hdr->ct_fs_type;
- oct->gs_subtype = hdr->ct_fs_subtype;
- oct->options = hdr->ct_options;
- oct->max_res_size = hdr->ct_mr_size;
- oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr),
- ZFCP_DBF_SAN_MAX_PAYLOAD);
- debug_event(dbf->san, level, r, sizeof(*r));
- zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
- (void *)hdr + sizeof(struct fc_ct_hdr), oct->len);
- spin_unlock_irqrestore(&dbf->san_lock, flags);
-}
+ rec->u.run.fsf_req_id = erp->fsf_req_id;
+ rec->u.run.rec_status = erp->status;
+ rec->u.run.rec_step = erp->step;
+ rec->u.run.rec_action = erp->action;
-/**
- * zfcp_dbf_san_ct_response - trace event for completion of CT request
- * @fsf_req: request containing CT response
- */
-void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct fc_ct_hdr *hdr = sg_virt(ct->resp);
- struct zfcp_dbf *dbf = adapter->dbf;
- struct zfcp_dbf_san_record *r = &dbf->san_buf;
- struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
- int level = 3;
- unsigned long flags;
+ if (erp->sdev)
+ rec->u.run.rec_count =
+ atomic_read(&sdev_to_zfcp(erp->sdev)->erp_counter);
+ else if (erp->port)
+ rec->u.run.rec_count = atomic_read(&erp->port->erp_counter);
+ else
+ rec->u.run.rec_count = atomic_read(&erp->adapter->erp_counter);
- spin_lock_irqsave(&dbf->san_lock, flags);
- memset(r, 0, sizeof(*r));
- strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
- r->fsf_reqid = fsf_req->req_id;
- r->fsf_seqno = fsf_req->seq_no;
- rct->cmd_rsp_code = hdr->ct_cmd;
- rct->revision = hdr->ct_rev;
- rct->reason_code = hdr->ct_reason;
- rct->expl = hdr->ct_explan;
- rct->vendor_unique = hdr->ct_vendor;
- rct->max_res_size = hdr->ct_mr_size;
- rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr),
- ZFCP_DBF_SAN_MAX_PAYLOAD);
- debug_event(dbf->san, level, r, sizeof(*r));
- zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
- (void *)hdr + sizeof(struct fc_ct_hdr), rct->len);
- spin_unlock_irqrestore(&dbf->san_lock, flags);
+ debug_event(dbf->rec, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->rec_lock, flags);
}
-static void zfcp_dbf_san_els(const char *tag, int level,
- struct zfcp_fsf_req *fsf_req, u32 d_id,
- void *buffer, int buflen)
+static inline
+void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+ u64 req_id, u32 d_id)
{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct zfcp_dbf *dbf = adapter->dbf;
- struct zfcp_dbf_san_record *rec = &dbf->san_buf;
+ struct zfcp_dbf_san *rec = &dbf->san_buf;
+ u16 rec_len;
unsigned long flags;
spin_lock_irqsave(&dbf->san_lock, flags);
memset(rec, 0, sizeof(*rec));
- strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
- rec->fsf_reqid = fsf_req->req_id;
- rec->fsf_seqno = fsf_req->seq_no;
- rec->u.els.d_id = d_id;
- debug_event(dbf->san, level, rec, sizeof(*rec));
- zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
- buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
+
+ rec->id = id;
+ rec->fsf_req_id = req_id;
+ rec->d_id = d_id;
+ rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD);
+ memcpy(rec->payload, data, rec_len);
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+
+ debug_event(dbf->san, 1, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->san_lock, flags);
}
/**
- * zfcp_dbf_san_els_request - trace event for issued ELS
- * @fsf_req: request containing issued ELS
+ * zfcp_dbf_san_req - trace event for issued SAN request
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
+ * d_id: destination ID
*/
-void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
{
- struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
- u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
+ struct zfcp_dbf *dbf = fsf->adapter->dbf;
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
- zfcp_dbf_san_els("oels", 2, fsf_req, d_id,
- sg_virt(els->req), els->req->length);
+ length = (u16)(ct_els->req->length + FC_CT_HDR_LEN);
+ zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
+ fsf->req_id, d_id);
}
/**
- * zfcp_dbf_san_els_response - trace event for completed ELS
- * @fsf_req: request containing ELS response
+ * zfcp_dbf_san_res - trace event for received SAN request
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
*/
-void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
{
- struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
- u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
+ struct zfcp_dbf *dbf = fsf->adapter->dbf;
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
- zfcp_dbf_san_els("rels", 2, fsf_req, d_id,
- sg_virt(els->resp), els->resp->length);
+ length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
+ zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+ fsf->req_id, 0);
}
/**
- * zfcp_dbf_san_incoming_els - trace event for incomig ELS
- * @fsf_req: request containing unsolicited status buffer with incoming ELS
+ * zfcp_dbf_san_in_els - trace event for incoming ELS
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
*/
-void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
{
- struct fsf_status_read_buffer *buf =
- (struct fsf_status_read_buffer *)fsf_req->data;
- int length = (int)buf->length -
- (int)((void *)&buf->payload - (void *)buf);
+ struct zfcp_dbf *dbf = fsf->adapter->dbf;
+ struct fsf_status_read_buffer *srb =
+ (struct fsf_status_read_buffer *) fsf->data;
+ u16 length;
- zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id),
- (void *)buf->payload.data, length);
-}
-
-static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_dbf_san_record *r = (struct zfcp_dbf_san_record *)in_buf;
- char *p = out_buf;
-
- if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- zfcp_dbf_tag(&p, "tag", r->tag);
- zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
- zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-
- if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
- struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
- zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id);
- zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
- zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
- zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
- zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
- zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
- zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
- } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
- struct zfcp_dbf_san_record_ct_response *ct = &r->u.ct_resp;
- zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
- zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
- zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
- zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
- zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
- zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
- } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
- strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
- strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
- struct zfcp_dbf_san_record_els *els = &r->u.els;
- zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id);
- }
- return p - out_buf;
+ length = (u16)(srb->length -
+ offsetof(struct fsf_status_read_buffer, payload));
+ zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length,
+ fsf->req_id, ntoh24(srb->d_id));
}
-static struct debug_view zfcp_dbf_san_view = {
- .name = "structured",
- .header_proc = zfcp_dbf_view_header,
- .format_proc = zfcp_dbf_san_view_format,
-};
-
-void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
- struct zfcp_dbf *dbf, struct scsi_cmnd *scsi_cmnd,
- struct zfcp_fsf_req *fsf_req, unsigned long old_req_id)
+/**
+ * zfcp_dbf_scsi - trace event for scsi commands
+ * @tag: identifier for event
+ * @sc: pointer to struct scsi_cmnd
+ * @fsf: pointer to struct zfcp_fsf_req
+ */
+void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
{
- struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
- struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
- unsigned long flags;
+ struct zfcp_adapter *adapter =
+ (struct zfcp_adapter *) sc->device->host->hostdata[0];
+ struct zfcp_dbf *dbf = adapter->dbf;
+ struct zfcp_dbf_scsi *rec = &dbf->scsi_buf;
struct fcp_resp_with_ext *fcp_rsp;
- struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
- char *fcp_sns_info = NULL;
- int offset = 0, buflen = 0;
+ struct fcp_resp_rsp_info *fcp_rsp_info;
+ unsigned long flags;
spin_lock_irqsave(&dbf->scsi_lock, flags);
- do {
- memset(rec, 0, sizeof(*rec));
- if (offset == 0) {
- strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
- strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
- if (scsi_cmnd != NULL) {
- if (scsi_cmnd->device) {
- rec->scsi_id = scsi_cmnd->device->id;
- rec->scsi_lun = scsi_cmnd->device->lun;
- }
- rec->scsi_result = scsi_cmnd->result;
- rec->scsi_cmnd = (unsigned long)scsi_cmnd;
- memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
- min((int)scsi_cmnd->cmd_len,
- ZFCP_DBF_SCSI_OPCODE));
- rec->scsi_retries = scsi_cmnd->retries;
- rec->scsi_allowed = scsi_cmnd->allowed;
- }
- if (fsf_req != NULL) {
- fcp_rsp = (struct fcp_resp_with_ext *)
- &(fsf_req->qtcb->bottom.io.fcp_rsp);
- fcp_rsp_info = (struct fcp_resp_rsp_info *)
- &fcp_rsp[1];
- fcp_sns_info = (char *) &fcp_rsp[1];
- if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
- fcp_sns_info += fcp_rsp->ext.fr_sns_len;
-
- rec->rsp_validity = fcp_rsp->resp.fr_flags;
- rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
- rec->rsp_resid = fcp_rsp->ext.fr_resid;
- if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
- rec->rsp_code = fcp_rsp_info->rsp_code;
- if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
- buflen = min(fcp_rsp->ext.fr_sns_len,
- (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
- rec->sns_info_len = buflen;
- memcpy(rec->sns_info, fcp_sns_info,
- min(buflen,
- ZFCP_DBF_SCSI_FCP_SNS_INFO));
- offset += min(buflen,
- ZFCP_DBF_SCSI_FCP_SNS_INFO);
- }
-
- rec->fsf_reqid = fsf_req->req_id;
- rec->fsf_seqno = fsf_req->seq_no;
- rec->fsf_issued = fsf_req->issued;
- }
- rec->old_fsf_reqid = old_req_id;
- } else {
- strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
- dump->total_size = buflen;
- dump->offset = offset;
- dump->size = min(buflen - offset,
- (int)sizeof(struct
- zfcp_dbf_scsi_record) -
- (int)sizeof(struct zfcp_dbf_dump));
- memcpy(dump->data, fcp_sns_info + offset, dump->size);
- offset += dump->size;
- }
- debug_event(dbf->scsi, level, rec, sizeof(*rec));
- } while (offset < buflen);
- spin_unlock_irqrestore(&dbf->scsi_lock, flags);
-}
+ memset(rec, 0, sizeof(*rec));
-static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_dbf_scsi_record *r = (struct zfcp_dbf_scsi_record *)in_buf;
- struct timespec t;
- char *p = out_buf;
-
- if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- zfcp_dbf_tag(&p, "tag", r->tag);
- zfcp_dbf_tag(&p, "tag2", r->tag2);
- zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id);
- zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun);
- zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result);
- zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd);
- zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE,
- 0, ZFCP_DBF_SCSI_OPCODE);
- zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries);
- zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed);
- if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0)
- zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid);
- zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
- zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
- stck_to_timespec(r->fsf_issued, &t);
- zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
-
- if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
- zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity);
- zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x",
- r->rsp_scsi_status);
- zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid);
- zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code);
- zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len);
- zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info,
- min((int)r->sns_info_len,
- ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
- r->sns_info_len);
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->id = ZFCP_DBF_SCSI_CMND;
+ rec->scsi_result = sc->result;
+ rec->scsi_retries = sc->retries;
+ rec->scsi_allowed = sc->allowed;
+ rec->scsi_id = sc->device->id;
+ rec->scsi_lun = sc->device->lun;
+ rec->host_scribble = (unsigned long)sc->host_scribble;
+
+ memcpy(rec->scsi_opcode, sc->cmnd,
+ min((int)sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
+
+ if (fsf) {
+ rec->fsf_req_id = fsf->req_id;
+ fcp_rsp = (struct fcp_resp_with_ext *)
+ &(fsf->qtcb->bottom.io.fcp_rsp);
+ memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
+ if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
+ fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+ rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
+ }
+ if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
+ rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
+ (u16)ZFCP_DBF_PAY_MAX_REC);
+ zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
+ "fcp_sns", fsf->req_id);
+ }
}
- p += sprintf(p, "\n");
- return p - out_buf;
-}
-static struct debug_view zfcp_dbf_scsi_view = {
- .name = "structured",
- .header_proc = zfcp_dbf_view_header,
- .format_proc = zfcp_dbf_scsi_view_format,
-};
+ debug_event(dbf->scsi, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->scsi_lock, flags);
+}
-static debug_info_t *zfcp_dbf_reg(const char *name, int level,
- struct debug_view *view, int size)
+static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size)
{
struct debug_info *d;
- d = debug_register(name, dbfsize, level, size);
+ d = debug_register(name, size, 1, rec_size);
if (!d)
return NULL;
debug_register_view(d, &debug_hex_ascii_view);
- debug_register_view(d, view);
- debug_set_level(d, level);
+ debug_set_level(d, 3);
return d;
}
+static void zfcp_dbf_unregister(struct zfcp_dbf *dbf)
+{
+ if (!dbf)
+ return;
+
+ debug_unregister(dbf->scsi);
+ debug_unregister(dbf->san);
+ debug_unregister(dbf->hba);
+ debug_unregister(dbf->pay);
+ debug_unregister(dbf->rec);
+ kfree(dbf);
+}
+
/**
* zfcp_adapter_debug_register - registers debug feature for an adapter
* @adapter: pointer to adapter for which debug features should be registered
@@ -1003,69 +415,66 @@ static debug_info_t *zfcp_dbf_reg(const char *name, int level,
*/
int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
{
- char dbf_name[DEBUG_MAX_NAME_LEN];
+ char name[DEBUG_MAX_NAME_LEN];
struct zfcp_dbf *dbf;
dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL);
if (!dbf)
return -ENOMEM;
- dbf->adapter = adapter;
-
+ spin_lock_init(&dbf->pay_lock);
spin_lock_init(&dbf->hba_lock);
spin_lock_init(&dbf->san_lock);
spin_lock_init(&dbf->scsi_lock);
spin_lock_init(&dbf->rec_lock);
/* debug feature area which records recovery activity */
- sprintf(dbf_name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
- dbf->rec = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_rec_view,
- sizeof(struct zfcp_dbf_rec_record));
+ sprintf(name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
+ dbf->rec = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_rec));
if (!dbf->rec)
goto err_out;
/* debug feature area which records HBA (FSF and QDIO) conditions */
- sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
- dbf->hba = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_hba_view,
- sizeof(struct zfcp_dbf_hba_record));
+ sprintf(name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
+ dbf->hba = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_hba));
if (!dbf->hba)
goto err_out;
+ /* debug feature area which records payload info */
+ sprintf(name, "zfcp_%s_pay", dev_name(&adapter->ccw_device->dev));
+ dbf->pay = zfcp_dbf_reg(name, dbfsize * 2, sizeof(struct zfcp_dbf_pay));
+ if (!dbf->pay)
+ goto err_out;
+
/* debug feature area which records SAN command failures and recovery */
- sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
- dbf->san = zfcp_dbf_reg(dbf_name, 6, &zfcp_dbf_san_view,
- sizeof(struct zfcp_dbf_san_record));
+ sprintf(name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
+ dbf->san = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_san));
if (!dbf->san)
goto err_out;
/* debug feature area which records SCSI command failures and recovery */
- sprintf(dbf_name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
- dbf->scsi = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_scsi_view,
- sizeof(struct zfcp_dbf_scsi_record));
+ sprintf(name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
+ dbf->scsi = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_scsi));
if (!dbf->scsi)
goto err_out;
adapter->dbf = dbf;
- return 0;
+ return 0;
err_out:
- zfcp_dbf_adapter_unregister(dbf);
+ zfcp_dbf_unregister(dbf);
return -ENOMEM;
}
/**
* zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
- * @dbf: pointer to dbf for which debug features should be unregistered
+ * @adapter: pointer to adapter for which debug features should be unregistered
*/
-void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
+void zfcp_dbf_adapter_unregister(struct zfcp_adapter *adapter)
{
- if (!dbf)
- return;
- debug_unregister(dbf->scsi);
- debug_unregister(dbf->san);
- debug_unregister(dbf->hba);
- debug_unregister(dbf->rec);
- dbf->adapter->dbf = NULL;
- kfree(dbf);
+ struct zfcp_dbf *dbf = adapter->dbf;
+
+ adapter->dbf = NULL;
+ zfcp_dbf_unregister(dbf);
}
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 04081b1b62b4..714f087eb7a9 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -1,22 +1,8 @@
/*
- * This file is part of the zfcp device driver for
- * FCP adapters for IBM System z9 and zSeries.
+ * zfcp device driver
+ * debug feature declarations
*
- * Copyright IBM Corp. 2008, 2009
- *
- * This program is free software; you can redistribute 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Copyright IBM Corp. 2008, 2010
*/
#ifndef ZFCP_DBF_H
@@ -27,322 +13,350 @@
#include "zfcp_fsf.h"
#include "zfcp_def.h"
-#define ZFCP_DBF_TAG_SIZE 4
-#define ZFCP_DBF_ID_SIZE 7
+#define ZFCP_DBF_TAG_LEN 7
#define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull
-struct zfcp_dbf_dump {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u32 total_size; /* size of total dump data */
- u32 offset; /* how much data has being already dumped */
- u32 size; /* how much data comes with this record */
- u8 data[]; /* dump data */
-} __attribute__ ((packed));
-
-struct zfcp_dbf_rec_record_thread {
- u32 total;
+/**
+ * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
+ * @ready: number of ready recovery actions
+ * @running: number of running recovery actions
+ * @want: wanted recovery action
+ * @need: needed recovery action
+ */
+struct zfcp_dbf_rec_trigger {
u32 ready;
u32 running;
-};
-
-struct zfcp_dbf_rec_record_target {
- u64 ref;
- u32 status;
- u32 d_id;
- u64 wwpn;
- u64 fcp_lun;
- u32 erp_count;
-};
-
-struct zfcp_dbf_rec_record_trigger {
u8 want;
u8 need;
- u32 as;
- u32 ps;
- u32 ls;
- u64 ref;
- u64 action;
- u64 wwpn;
- u64 fcp_lun;
-};
+} __packed;
-struct zfcp_dbf_rec_record_action {
- u32 status;
- u32 step;
- u64 action;
- u64 fsf_req;
+/**
+ * struct zfcp_dbf_rec_running - trace record for running recovery
+ * @fsf_req_id: request id for fsf requests
+ * @rec_status: status of the fsf request
+ * @rec_step: current step of the recovery action
+ * rec_count: recovery counter
+ */
+struct zfcp_dbf_rec_running {
+ u64 fsf_req_id;
+ u32 rec_status;
+ u16 rec_step;
+ u8 rec_action;
+ u8 rec_count;
+} __packed;
+
+/**
+ * enum zfcp_dbf_rec_id - recovery trace record id
+ * @ZFCP_DBF_REC_TRIG: triggered recovery identifier
+ * @ZFCP_DBF_REC_RUN: running recovery identifier
+ */
+enum zfcp_dbf_rec_id {
+ ZFCP_DBF_REC_TRIG = 1,
+ ZFCP_DBF_REC_RUN = 2,
};
-struct zfcp_dbf_rec_record {
+/**
+ * struct zfcp_dbf_rec - trace record for error recovery actions
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @lun: logical unit number
+ * @wwpn: word wide port number
+ * @d_id: destination ID
+ * @adapter_status: current status of the adapter
+ * @port_status: current status of the port
+ * @lun_status: current status of the lun
+ * @u.trig: structure zfcp_dbf_rec_trigger
+ * @u.run: structure zfcp_dbf_rec_running
+ */
+struct zfcp_dbf_rec {
u8 id;
- char id2[7];
+ char tag[ZFCP_DBF_TAG_LEN];
+ u64 lun;
+ u64 wwpn;
+ u32 d_id;
+ u32 adapter_status;
+ u32 port_status;
+ u32 lun_status;
union {
- struct zfcp_dbf_rec_record_action action;
- struct zfcp_dbf_rec_record_thread thread;
- struct zfcp_dbf_rec_record_target target;
- struct zfcp_dbf_rec_record_trigger trigger;
+ struct zfcp_dbf_rec_trigger trig;
+ struct zfcp_dbf_rec_running run;
} u;
-};
+} __packed;
-enum {
- ZFCP_REC_DBF_ID_ACTION,
- ZFCP_REC_DBF_ID_THREAD,
- ZFCP_REC_DBF_ID_TARGET,
- ZFCP_REC_DBF_ID_TRIGGER,
+/**
+ * enum zfcp_dbf_san_id - SAN trace record identifier
+ * @ZFCP_DBF_SAN_REQ: request trace record id
+ * @ZFCP_DBF_SAN_RES: response trace record id
+ * @ZFCP_DBF_SAN_ELS: extended link service record id
+ */
+enum zfcp_dbf_san_id {
+ ZFCP_DBF_SAN_REQ = 1,
+ ZFCP_DBF_SAN_RES = 2,
+ ZFCP_DBF_SAN_ELS = 3,
};
-struct zfcp_dbf_hba_record_response {
- u32 fsf_command;
- u64 fsf_reqid;
- u32 fsf_seqno;
- u64 fsf_issued;
- u32 fsf_prot_status;
+/** struct zfcp_dbf_san - trace record for SAN requests and responses
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @fsf_req_id: request id for fsf requests
+ * @payload: unformatted information related to request/response
+ * @d_id: destination id
+ */
+struct zfcp_dbf_san {
+ u8 id;
+ char tag[ZFCP_DBF_TAG_LEN];
+ u64 fsf_req_id;
+ u32 d_id;
+#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
+ char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
+} __packed;
+
+/**
+ * struct zfcp_dbf_hba_res - trace record for hba responses
+ * @req_issued: timestamp when request was issued
+ * @prot_status: protocol status
+ * @prot_status_qual: protocol status qualifier
+ * @fsf_status: fsf status
+ * @fsf_status_qual: fsf status qualifier
+ */
+struct zfcp_dbf_hba_res {
+ u64 req_issued;
+ u32 prot_status;
+ u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
u32 fsf_status;
- u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
- u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
- u32 fsf_req_status;
- u8 sbal_first;
- u8 sbal_last;
- u8 sbal_response;
- u8 pool;
- u64 erp_action;
- union {
- struct {
- u64 cmnd;
- u32 data_dir;
- } fcp;
- struct {
- u64 wwpn;
- u32 d_id;
- u32 port_handle;
- } port;
- struct {
- u64 wwpn;
- u64 fcp_lun;
- u32 port_handle;
- u32 lun_handle;
- } unit;
- struct {
- u32 d_id;
- } els;
- } u;
-} __attribute__ ((packed));
+ u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+} __packed;
-struct zfcp_dbf_hba_record_status {
- u8 failed;
+/**
+ * struct zfcp_dbf_hba_uss - trace record for unsolicited status
+ * @status_type: type of unsolicited status
+ * @status_subtype: subtype of unsolicited status
+ * @d_id: destination ID
+ * @lun: logical unit number
+ * @queue_designator: queue designator
+ */
+struct zfcp_dbf_hba_uss {
u32 status_type;
u32 status_subtype;
- struct fsf_queue_designator
- queue_designator;
- u32 payload_size;
-#define ZFCP_DBF_UNSOL_PAYLOAD 80
-#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32
-#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56
-#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)
- u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_dbf_hba_record_qdio {
- u32 qdio_error;
- u8 sbal_index;
- u8 sbal_count;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_hba_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u8 tag2[ZFCP_DBF_TAG_SIZE];
- union {
- struct zfcp_dbf_hba_record_response response;
- struct zfcp_dbf_hba_record_status status;
- struct zfcp_dbf_hba_record_qdio qdio;
- struct fsf_bit_error_payload berr;
- } u;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_ct_request {
- u16 cmd_req_code;
- u8 revision;
- u8 gs_type;
- u8 gs_subtype;
- u8 options;
- u16 max_res_size;
- u32 len;
- u32 d_id;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_ct_response {
- u16 cmd_rsp_code;
- u8 revision;
- u8 reason_code;
- u8 expl;
- u8 vendor_unique;
- u16 max_res_size;
- u32 len;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_els {
u32 d_id;
-} __attribute__ ((packed));
+ u64 lun;
+ u64 queue_designator;
+} __packed;
-struct zfcp_dbf_san_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u64 fsf_reqid;
- u32 fsf_seqno;
+/**
+ * enum zfcp_dbf_hba_id - HBA trace record identifier
+ * @ZFCP_DBF_HBA_RES: response trace record
+ * @ZFCP_DBF_HBA_USS: unsolicited status trace record
+ * @ZFCP_DBF_HBA_BIT: bit error trace record
+ */
+enum zfcp_dbf_hba_id {
+ ZFCP_DBF_HBA_RES = 1,
+ ZFCP_DBF_HBA_USS = 2,
+ ZFCP_DBF_HBA_BIT = 3,
+};
+
+/**
+ * struct zfcp_dbf_hba - common trace record for HBA records
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @fsf_req_id: request id for fsf requests
+ * @fsf_req_status: status of fsf request
+ * @fsf_cmd: fsf command
+ * @fsf_seq_no: fsf sequence number
+ * @pl_len: length of payload stored as zfcp_dbf_pay
+ * @u: record type specific data
+ */
+struct zfcp_dbf_hba {
+ u8 id;
+ char tag[ZFCP_DBF_TAG_LEN];
+ u64 fsf_req_id;
+ u32 fsf_req_status;
+ u32 fsf_cmd;
+ u32 fsf_seq_no;
+ u16 pl_len;
union {
- struct zfcp_dbf_san_record_ct_request ct_req;
- struct zfcp_dbf_san_record_ct_response ct_resp;
- struct zfcp_dbf_san_record_els els;
+ struct zfcp_dbf_hba_res res;
+ struct zfcp_dbf_hba_uss uss;
+ struct fsf_bit_error_payload be;
} u;
-} __attribute__ ((packed));
+} __packed;
-#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
+/**
+ * enum zfcp_dbf_scsi_id - scsi trace record identifier
+ * @ZFCP_DBF_SCSI_CMND: scsi command trace record
+ */
+enum zfcp_dbf_scsi_id {
+ ZFCP_DBF_SCSI_CMND = 1,
+};
-struct zfcp_dbf_scsi_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u8 tag2[ZFCP_DBF_TAG_SIZE];
+/**
+ * struct zfcp_dbf_scsi - common trace record for SCSI records
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @scsi_id: scsi device id
+ * @scsi_lun: scsi device logical unit number
+ * @scsi_result: scsi result
+ * @scsi_retries: current retry number of scsi request
+ * @scsi_allowed: allowed retries
+ * @fcp_rsp_info: FCP response info
+ * @scsi_opcode: scsi opcode
+ * @fsf_req_id: request id of fsf request
+ * @host_scribble: LLD specific data attached to SCSI request
+ * @pl_len: length of paload stored as zfcp_dbf_pay
+ * @fsf_rsp: response for fsf request
+ */
+struct zfcp_dbf_scsi {
+ u8 id;
+ char tag[ZFCP_DBF_TAG_LEN];
u32 scsi_id;
u32 scsi_lun;
u32 scsi_result;
- u64 scsi_cmnd;
-#define ZFCP_DBF_SCSI_OPCODE 16
- u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
u8 scsi_retries;
u8 scsi_allowed;
- u64 fsf_reqid;
- u32 fsf_seqno;
- u64 fsf_issued;
- u64 old_fsf_reqid;
- u8 rsp_validity;
- u8 rsp_scsi_status;
- u32 rsp_resid;
- u8 rsp_code;
-#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16
-#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
- u32 sns_info_len;
- u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
-} __attribute__ ((packed));
+ u8 fcp_rsp_info;
+#define ZFCP_DBF_SCSI_OPCODE 16
+ u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
+ u64 fsf_req_id;
+ u64 host_scribble;
+ u16 pl_len;
+ struct fcp_resp_with_ext fcp_rsp;
+} __packed;
+/**
+ * struct zfcp_dbf_pay - trace record for unformatted payload information
+ * @area: area this record is originated from
+ * @counter: ascending record number
+ * @fsf_req_id: request id of fsf request
+ * @data: unformatted data
+ */
+struct zfcp_dbf_pay {
+ u8 counter;
+ char area[ZFCP_DBF_TAG_LEN];
+ u64 fsf_req_id;
+#define ZFCP_DBF_PAY_MAX_REC 0x100
+ char data[ZFCP_DBF_PAY_MAX_REC];
+} __packed;
+
+/**
+ * struct zfcp_dbf - main dbf trace structure
+ * @pay: reference to payload trace area
+ * @rec: reference to recovery trace area
+ * @hba: reference to hba trace area
+ * @san: reference to san trace area
+ * @scsi: reference to scsi trace area
+ * @pay_lock: lock protecting payload trace buffer
+ * @rec_lock: lock protecting recovery trace buffer
+ * @hba_lock: lock protecting hba trace buffer
+ * @san_lock: lock protecting san trace buffer
+ * @scsi_lock: lock protecting scsi trace buffer
+ * @pay_buf: pre-allocated buffer for payload
+ * @rec_buf: pre-allocated buffer for recovery
+ * @hba_buf: pre-allocated buffer for hba
+ * @san_buf: pre-allocated buffer for san
+ * @scsi_buf: pre-allocated buffer for scsi
+ */
struct zfcp_dbf {
+ debug_info_t *pay;
debug_info_t *rec;
debug_info_t *hba;
debug_info_t *san;
debug_info_t *scsi;
+ spinlock_t pay_lock;
spinlock_t rec_lock;
spinlock_t hba_lock;
spinlock_t san_lock;
spinlock_t scsi_lock;
- struct zfcp_dbf_rec_record rec_buf;
- struct zfcp_dbf_hba_record hba_buf;
- struct zfcp_dbf_san_record san_buf;
- struct zfcp_dbf_scsi_record scsi_buf;
- struct zfcp_adapter *adapter;
+ struct zfcp_dbf_pay pay_buf;
+ struct zfcp_dbf_rec rec_buf;
+ struct zfcp_dbf_hba hba_buf;
+ struct zfcp_dbf_san san_buf;
+ struct zfcp_dbf_scsi scsi_buf;
};
static inline
-void zfcp_dbf_hba_fsf_resp(const char *tag2, int level,
- struct zfcp_fsf_req *req, struct zfcp_dbf *dbf)
+void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
{
- if (level <= dbf->hba->level)
- _zfcp_dbf_hba_fsf_response(tag2, level, req, dbf);
+ if (level <= req->adapter->dbf->hba->level)
+ zfcp_dbf_hba_fsf_res(tag, req);
}
/**
* zfcp_dbf_hba_fsf_response - trace event for request completion
- * @fsf_req: request that has been completed
+ * @req: request that has been completed
*/
-static inline void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
+static inline
+void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
{
- struct zfcp_dbf *dbf = req->adapter->dbf;
struct fsf_qtcb *qtcb = req->qtcb;
if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
(qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
- zfcp_dbf_hba_fsf_resp("perr", 1, req, dbf);
+ zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
} else if (qtcb->header.fsf_status != FSF_GOOD) {
- zfcp_dbf_hba_fsf_resp("ferr", 1, req, dbf);
+ zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req);
} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
(req->fsf_command == FSF_QTCB_OPEN_LUN)) {
- zfcp_dbf_hba_fsf_resp("open", 4, req, dbf);
+ zfcp_dbf_hba_fsf_resp("fs_open", 4, req);
} else if (qtcb->header.log_length) {
- zfcp_dbf_hba_fsf_resp("qtcb", 5, req, dbf);
+ zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req);
} else {
- zfcp_dbf_hba_fsf_resp("norm", 6, req, dbf);
+ zfcp_dbf_hba_fsf_resp("fs_norm", 6, req);
}
- }
-
-/**
- * zfcp_dbf_hba_fsf_unsol - trace event for an unsolicited status buffer
- * @tag: tag indicating which kind of unsolicited status has been received
- * @dbf: reference to dbf structure
- * @status_buffer: buffer containing payload of unsolicited status
- */
-static inline
-void zfcp_dbf_hba_fsf_unsol(const char *tag, struct zfcp_dbf *dbf,
- struct fsf_status_read_buffer *buf)
-{
- int level = 2;
-
- if (level <= dbf->hba->level)
- _zfcp_dbf_hba_fsf_unsol(tag, level, dbf, buf);
}
static inline
-void zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
- struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
- struct zfcp_fsf_req *req, unsigned long old_id)
+void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
+ struct zfcp_fsf_req *req)
{
- if (level <= dbf->scsi->level)
- _zfcp_dbf_scsi(tag, tag2, level, dbf, scmd, req, old_id);
+ struct zfcp_adapter *adapter = (struct zfcp_adapter *)
+ scmd->device->host->hostdata[0];
+
+ if (level <= adapter->dbf->scsi->level)
+ zfcp_dbf_scsi(tag, scmd, req);
}
/**
* zfcp_dbf_scsi_result - trace event for SCSI command completion
- * @dbf: adapter dbf trace
* @scmd: SCSI command pointer
* @req: FSF request used to issue SCSI command
*/
static inline
-void zfcp_dbf_scsi_result(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
- struct zfcp_fsf_req *req)
+void zfcp_dbf_scsi_result(struct scsi_cmnd *scmd, struct zfcp_fsf_req *req)
{
if (scmd->result != 0)
- zfcp_dbf_scsi("rslt", "erro", 3, dbf, scmd, req, 0);
+ _zfcp_dbf_scsi("rsl_err", 3, scmd, req);
else if (scmd->retries > 0)
- zfcp_dbf_scsi("rslt", "retr", 4, dbf, scmd, req, 0);
+ _zfcp_dbf_scsi("rsl_ret", 4, scmd, req);
else
- zfcp_dbf_scsi("rslt", "norm", 6, dbf, scmd, req, 0);
+ _zfcp_dbf_scsi("rsl_nor", 6, scmd, req);
}
/**
* zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
- * @dbf: adapter dbf trace
* @scmd: SCSI command pointer
*/
static inline
-void zfcp_dbf_scsi_fail_send(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd)
+void zfcp_dbf_scsi_fail_send(struct scsi_cmnd *scmd)
{
- zfcp_dbf_scsi("rslt", "fail", 4, dbf, scmd, NULL, 0);
+ _zfcp_dbf_scsi("rsl_fai", 4, scmd, NULL);
}
/**
* zfcp_dbf_scsi_abort - trace event for SCSI command abort
* @tag: tag indicating success or failure of abort operation
- * @adapter: adapter thas has been used to issue SCSI command to be aborted
* @scmd: SCSI command to be aborted
- * @new_req: request containing abort (might be NULL)
- * @old_id: identifier of request containg SCSI command to be aborted
+ * @fsf_req: request containing abort (might be NULL)
*/
static inline
-void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
- struct scsi_cmnd *scmd, struct zfcp_fsf_req *new_req,
- unsigned long old_id)
+void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd,
+ struct zfcp_fsf_req *fsf_req)
{
- zfcp_dbf_scsi("abrt", tag, 1, dbf, scmd, new_req, old_id);
+ _zfcp_dbf_scsi(tag, 1, scmd, fsf_req);
}
/**
@@ -352,12 +366,17 @@ void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
* @flag: indicates type of reset (Target Reset, Logical Unit Reset)
*/
static inline
-void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag)
+void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
{
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
+ char tmp_tag[ZFCP_DBF_TAG_LEN];
+
+ if (flag == FCP_TMF_TGT_RESET)
+ memcpy(tmp_tag, "tr_", 3);
+ else
+ memcpy(tmp_tag, "lr_", 3);
- zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
- zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0);
+ memcpy(&tmp_tag[3], tag, 4);
+ _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
}
#endif /* ZFCP_DBF_H */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index d37c7331f244..e003e306f870 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -76,9 +76,9 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
struct zfcp_adapter *adapter = act->adapter;
list_move(&act->list, &act->adapter->erp_ready_head);
- zfcp_dbf_rec_action("erardy1", act);
+ zfcp_dbf_rec_run("erardy1", act);
wake_up(&adapter->erp_ready_wq);
- zfcp_dbf_rec_thread("erardy2", adapter->dbf);
+ zfcp_dbf_rec_run("erardy2", act);
}
static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) ||
a_status & ZFCP_STATUS_COMMON_ERP_FAILED)
return 0;
+ if (p_status & ZFCP_STATUS_COMMON_NOESC)
+ return need;
if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED))
need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
/* fall through */
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
&zfcp_sdev->status);
erp_action = &zfcp_sdev->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+ erp_action->port = port;
+ erp_action->sdev = sdev;
if (!(atomic_read(&zfcp_sdev->status) &
ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
zfcp_erp_action_dismiss_port(port);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
erp_action = &port->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+ erp_action->port = port;
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
break;
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
zfcp_erp_action_dismiss_adapter(adapter);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
erp_action = &adapter->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
return NULL;
}
- memset(erp_action, 0, sizeof(struct zfcp_erp_action));
erp_action->adapter = adapter;
- erp_action->port = port;
- erp_action->sdev = sdev;
erp_action->action = need;
erp_action->status = act_status;
@@ -231,10 +236,10 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
struct zfcp_port *port,
struct scsi_device *sdev,
- char *id, void *ref, u32 act_status)
+ char *id, u32 act_status)
{
int retval = 1, need;
- struct zfcp_erp_action *act = NULL;
+ struct zfcp_erp_action *act;
if (!adapter->erp_thread)
return -EIO;
@@ -250,15 +255,14 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
++adapter->erp_total_count;
list_add_tail(&act->list, &adapter->erp_ready_head);
wake_up(&adapter->erp_ready_wq);
- zfcp_dbf_rec_thread("eracte1", adapter->dbf);
retval = 0;
out:
- zfcp_dbf_rec_trigger(id, ref, want, need, act, adapter, port, sdev);
+ zfcp_dbf_rec_trig(id, adapter, port, sdev, want, need);
return retval;
}
static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
- int clear_mask, char *id, void *ref)
+ int clear_mask, char *id)
{
zfcp_erp_adapter_block(adapter, clear_mask);
zfcp_scsi_schedule_rports_block(adapter);
@@ -270,7 +274,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
return -EIO;
}
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
- adapter, NULL, NULL, id, ref, 0);
+ adapter, NULL, NULL, id, 0);
}
/**
@@ -278,10 +282,8 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
* @adapter: Adapter to reopen.
* @clear: Status flags to clear.
* @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
*/
-void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
- char *id, void *ref)
+void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id)
{
unsigned long flags;
@@ -294,7 +296,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
ZFCP_STATUS_COMMON_ERP_FAILED);
else
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
- NULL, NULL, id, ref, 0);
+ NULL, NULL, id, 0);
write_unlock_irqrestore(&adapter->erp_lock, flags);
}
@@ -303,13 +305,12 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
* @adapter: Adapter to shut down.
* @clear: Status flags to clear.
* @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
*/
void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
- char *id, void *ref)
+ char *id)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
- zfcp_erp_adapter_reopen(adapter, clear | flags, id, ref);
+ zfcp_erp_adapter_reopen(adapter, clear | flags, id);
}
/**
@@ -317,13 +318,11 @@ void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
* @port: Port to shut down.
* @clear: Status flags to clear.
* @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
*/
-void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
- void *ref)
+void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
- zfcp_erp_port_reopen(port, clear | flags, id, ref);
+ zfcp_erp_port_reopen(port, clear | flags, id);
}
static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
@@ -332,8 +331,8 @@ static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
ZFCP_STATUS_COMMON_UNBLOCKED | clear);
}
-static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
- int clear, char *id, void *ref)
+static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear,
+ char *id)
{
zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port);
@@ -342,28 +341,26 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
return;
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
- port->adapter, port, NULL, id, ref, 0);
+ port->adapter, port, NULL, id, 0);
}
/**
* zfcp_erp_port_forced_reopen - Forced close of port and open again
* @port: Port to force close and to reopen.
+ * @clear: Status flags to clear.
* @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
*/
-void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
- void *ref)
+void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id)
{
unsigned long flags;
struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags);
- _zfcp_erp_port_forced_reopen(port, clear, id, ref);
+ _zfcp_erp_port_forced_reopen(port, clear, id);
write_unlock_irqrestore(&adapter->erp_lock, flags);
}
-static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
- void *ref)
+static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
{
zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port);
@@ -375,24 +372,25 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
}
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
- port->adapter, port, NULL, id, ref, 0);
+ port->adapter, port, NULL, id, 0);
}
/**
* zfcp_erp_port_reopen - trigger remote port recovery
* @port: port to recover
* @clear_mask: flags in port status to be cleared
+ * @id: Id for debug trace event.
*
* Returns 0 if recovery has been triggered, < 0 if not.
*/
-int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
+int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
{
int retval;
unsigned long flags;
struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags);
- retval = _zfcp_erp_port_reopen(port, clear, id, ref);
+ retval = _zfcp_erp_port_reopen(port, clear, id);
write_unlock_irqrestore(&adapter->erp_lock, flags);
return retval;
@@ -405,7 +403,7 @@ static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask)
}
static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
- void *ref, u32 act_status)
+ u32 act_status)
{
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -416,17 +414,18 @@ static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
return;
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter,
- zfcp_sdev->port, sdev, id, ref, act_status);
+ zfcp_sdev->port, sdev, id, act_status);
}
/**
* zfcp_erp_lun_reopen - initiate reopen of a LUN
* @sdev: SCSI device / LUN to be reopened
* @clear_mask: specifies flags in LUN status to be cleared
+ * @id: Id for debug trace event.
+ *
* Return: 0 on success, < 0 on error
*/
-void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
- void *ref)
+void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id)
{
unsigned long flags;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@@ -434,7 +433,7 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags);
- _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0);
+ _zfcp_erp_lun_reopen(sdev, clear, id, 0);
write_unlock_irqrestore(&adapter->erp_lock, flags);
}
@@ -443,13 +442,11 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
* @sdev: SCSI device / LUN to shut down.
* @clear: Status flags to clear.
* @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
*/
-void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id,
- void *ref)
+void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
- zfcp_erp_lun_reopen(sdev, clear | flags, id, ref);
+ zfcp_erp_lun_reopen(sdev, clear | flags, id);
}
/**
@@ -471,7 +468,7 @@ void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id)
int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
write_lock_irqsave(&adapter->erp_lock, flags);
- _zfcp_erp_lun_reopen(sdev, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF);
+ _zfcp_erp_lun_reopen(sdev, clear, id, ZFCP_STATUS_ERP_NO_REF);
write_unlock_irqrestore(&adapter->erp_lock, flags);
zfcp_erp_wait(adapter);
@@ -485,14 +482,14 @@ static int status_change_set(unsigned long mask, atomic_t *status)
static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
{
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
- zfcp_dbf_rec_adapter("eraubl1", NULL, adapter->dbf);
+ zfcp_dbf_rec_run("eraubl1", &adapter->erp_action);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
}
static void zfcp_erp_port_unblock(struct zfcp_port *port)
{
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
- zfcp_dbf_rec_port("erpubl1", NULL, port);
+ zfcp_dbf_rec_run("erpubl1", &port->erp_action);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
}
@@ -501,14 +498,14 @@ static void zfcp_erp_lun_unblock(struct scsi_device *sdev)
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status))
- zfcp_dbf_rec_lun("erlubl1", NULL, sdev);
+ zfcp_dbf_rec_run("erlubl1", &sdev_to_zfcp(sdev)->erp_action);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status);
}
static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
{
list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
- zfcp_dbf_rec_action("erator1", erp_action);
+ zfcp_dbf_rec_run("erator1", erp_action);
}
static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
@@ -525,11 +522,11 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
ZFCP_STATUS_ERP_TIMEDOUT)) {
req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_dbf_rec_action("erscf_1", act);
+ zfcp_dbf_rec_run("erscf_1", act);
req->erp_action = NULL;
}
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
- zfcp_dbf_rec_action("erscf_2", act);
+ zfcp_dbf_rec_run("erscf_2", act);
if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
act->fsf_req_id = 0;
} else
@@ -580,40 +577,40 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
}
static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
- int clear, char *id, void *ref)
+ int clear, char *id)
{
struct zfcp_port *port;
read_lock(&adapter->port_list_lock);
list_for_each_entry(port, &adapter->port_list, list)
- _zfcp_erp_port_reopen(port, clear, id, ref);
+ _zfcp_erp_port_reopen(port, clear, id);
read_unlock(&adapter->port_list_lock);
}
static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear,
- char *id, void *ref)
+ char *id)
{
struct scsi_device *sdev;
shost_for_each_device(sdev, port->adapter->scsi_host)
if (sdev_to_zfcp(sdev)->port == port)
- _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0);
+ _zfcp_erp_lun_reopen(sdev, clear, id, 0);
}
static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
{
switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
- _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1", NULL);
+ _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1");
break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
- _zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2", NULL);
+ _zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2");
break;
case ZFCP_ERP_ACTION_REOPEN_PORT:
- _zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);
+ _zfcp_erp_port_reopen(act->port, 0, "ersff_3");
break;
case ZFCP_ERP_ACTION_REOPEN_LUN:
- _zfcp_erp_lun_reopen(act->sdev, 0, "ersff_4", NULL, 0);
+ _zfcp_erp_lun_reopen(act->sdev, 0, "ersff_4", 0);
break;
}
}
@@ -622,13 +619,13 @@ static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act)
{
switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
- _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1", NULL);
+ _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1");
break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
- _zfcp_erp_port_reopen(act->port, 0, "ersfs_2", NULL);
+ _zfcp_erp_port_reopen(act->port, 0, "ersfs_2");
break;
case ZFCP_ERP_ACTION_REOPEN_PORT:
- _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3", NULL);
+ _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3");
break;
}
}
@@ -647,17 +644,6 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
read_unlock_irqrestore(&adapter->erp_lock, flags);
}
-static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
-{
- struct zfcp_qdio *qdio = act->adapter->qdio;
-
- if (zfcp_qdio_open(qdio))
- return ZFCP_ERP_FAILED;
- init_waitqueue_head(&qdio->req_q_wq);
- atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &act->adapter->status);
- return ZFCP_ERP_SUCCEEDED;
-}
-
static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
{
struct zfcp_port *port;
@@ -665,7 +651,7 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
adapter->peer_d_id);
if (IS_ERR(port)) /* error or port already attached */
return;
- _zfcp_erp_port_reopen(port, 0, "ereptp1", NULL);
+ _zfcp_erp_port_reopen(port, 0, "ereptp1");
}
static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
@@ -688,10 +674,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_FAILED;
}
- zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
wait_event(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head));
- zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
break;
@@ -730,10 +714,10 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
if (ret)
return ZFCP_ERP_FAILED;
- zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
+ zfcp_dbf_rec_run("erasox1", act);
wait_event(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head));
- zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
+ zfcp_dbf_rec_run("erasox2", act);
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
return ZFCP_ERP_FAILED;
@@ -783,7 +767,7 @@ static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
{
struct zfcp_adapter *adapter = act->adapter;
- if (zfcp_erp_adapter_strategy_open_qdio(act)) {
+ if (zfcp_qdio_open(adapter->qdio)) {
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
&adapter->status);
@@ -1161,7 +1145,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
_zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "ersscg1", NULL);
+ "ersscg1");
return ZFCP_ERP_EXIT;
}
break;
@@ -1171,7 +1155,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
_zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "ersscg2", NULL);
+ "ersscg2");
return ZFCP_ERP_EXIT;
}
break;
@@ -1181,7 +1165,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&zfcp_sdev->status, erp_status)) {
_zfcp_erp_lun_reopen(sdev,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "ersscg3", NULL, 0);
+ "ersscg3", 0);
return ZFCP_ERP_EXIT;
}
break;
@@ -1201,7 +1185,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
}
list_del(&erp_action->list);
- zfcp_dbf_rec_action("eractd1", erp_action);
+ zfcp_dbf_rec_run("eractd1", erp_action);
switch (erp_action->action) {
case ZFCP_ERP_ACTION_REOPEN_LUN:
@@ -1308,7 +1292,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
}
if (adapter->erp_total_count == adapter->erp_low_mem_count)
- _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1", NULL);
+ _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1");
else {
zfcp_erp_strategy_memwait(erp_action);
retval = ZFCP_ERP_CONTINUES;
@@ -1352,11 +1336,9 @@ static int zfcp_erp_thread(void *data)
unsigned long flags;
for (;;) {
- zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
wait_event_interruptible(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head) ||
kthread_should_stop());
- zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
if (kthread_should_stop())
break;
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index bf8f3e514839..6e325284fbe7 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -45,47 +45,33 @@ extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *);
/* zfcp_dbf.c */
extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
-extern void zfcp_dbf_adapter_unregister(struct zfcp_dbf *);
-extern void zfcp_dbf_rec_thread(char *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *);
-extern void zfcp_dbf_rec_lun(char *, void *, struct scsi_device *);
-extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *,
- struct zfcp_adapter *, struct zfcp_port *,
- struct scsi_device *);
-extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *);
-extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *,
- struct zfcp_dbf *);
-extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *,
- struct fsf_status_read_buffer *);
-extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
+extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
+extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+ struct zfcp_port *, struct scsi_device *, u8, u8);
+extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
+extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *, u32);
-extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *);
-extern void _zfcp_dbf_scsi(const char *, const char *, int, struct zfcp_dbf *,
- struct scsi_cmnd *, struct zfcp_fsf_req *,
- unsigned long);
+extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
+extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *);
/* zfcp_erp.c */
extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
-extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
-extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
- void *);
+extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *);
+extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
-extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
-extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
-extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
- void *);
+extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *);
+extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *);
+extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *);
extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
-extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *);
-extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *);
+extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *);
+extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *);
extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *);
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
@@ -149,6 +135,8 @@ extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *,
extern int zfcp_qdio_open(struct zfcp_qdio *);
extern void zfcp_qdio_close(struct zfcp_qdio *);
extern void zfcp_qdio_siosl(struct zfcp_adapter *);
+extern struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *,
+ struct qdio_buffer *);
/* zfcp_scsi.c */
extern struct zfcp_data zfcp_data;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 86fd905df48b..30cf91a787a3 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -174,7 +174,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
if (!port->d_id)
zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED,
- "fcrscn1", NULL);
+ "fcrscn1");
}
read_unlock_irqrestore(&adapter->port_list_lock, flags);
}
@@ -215,7 +215,7 @@ static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
read_lock_irqsave(&adapter->port_list_lock, flags);
list_for_each_entry(port, &adapter->port_list, list)
if (port->wwpn == wwpn) {
- zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
+ zfcp_erp_port_forced_reopen(port, 0, "fciwwp1");
break;
}
read_unlock_irqrestore(&adapter->port_list_lock, flags);
@@ -251,7 +251,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
(struct fsf_status_read_buffer *) fsf_req->data;
unsigned int els_type = status_buffer->payload.data[0];
- zfcp_dbf_san_incoming_els(fsf_req);
+ zfcp_dbf_san_in_els("fciels1", fsf_req);
if (els_type == ELS_PLOGI)
zfcp_fc_incoming_plogi(fsf_req);
else if (els_type == ELS_LOGO)
@@ -360,7 +360,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
ret = zfcp_fc_ns_gid_pn(port);
if (ret) {
/* could not issue gid_pn for some reason */
- zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL);
+ zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1");
goto out;
}
@@ -369,7 +369,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
goto out;
}
- zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
+ zfcp_erp_port_reopen(port, 0, "fcgpn_3");
out:
put_device(&port->dev);
}
@@ -426,7 +426,7 @@ static void zfcp_fc_adisc_handler(void *data)
if (adisc->els.status) {
/* request rejected or timed out */
zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fcadh_1", NULL);
+ "fcadh_1");
goto out;
}
@@ -436,7 +436,7 @@ static void zfcp_fc_adisc_handler(void *data)
if ((port->wwpn != adisc_resp->adisc_wwpn) ||
!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fcadh_2", NULL);
+ "fcadh_2");
goto out;
}
@@ -507,7 +507,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
/* send of ADISC was not possible */
atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
- zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
+ zfcp_erp_port_forced_reopen(port, 0, "fcltwk1");
out:
put_device(&port->dev);
@@ -659,7 +659,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
port = zfcp_port_enqueue(adapter, acc->fp_wwpn,
ZFCP_STATUS_COMMON_NOESC, d_id);
if (!IS_ERR(port))
- zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
+ zfcp_erp_port_reopen(port, 0, "fcegpf1");
else if (PTR_ERR(port) != -EEXIST)
ret = PTR_ERR(port);
}
@@ -671,7 +671,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
write_unlock_irqrestore(&adapter->port_list_lock, flags);
list_for_each_entry_safe(port, tmp, &remove_lh, list) {
- zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
+ zfcp_erp_port_shutdown(port, 0, "fcegpf2");
zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
}
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index be0317457147..60ff9d172c79 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -23,7 +23,7 @@ static void zfcp_fsf_request_timeout_handler(unsigned long data)
struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fsrth_1", NULL);
+ "fsrth_1");
}
static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req,
@@ -65,7 +65,7 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
{
dev_err(&req->adapter->ccw_device->dev, "FCP device not "
"operational because of an unsupported FC class\n");
- zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1", req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -98,7 +98,7 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
read_lock_irqsave(&adapter->port_list_lock, flags);
list_for_each_entry(port, &adapter->port_list, list)
if (port->d_id == d_id) {
- zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
+ zfcp_erp_port_reopen(port, 0, "fssrpc1");
break;
}
read_unlock_irqrestore(&adapter->port_list_lock, flags);
@@ -211,13 +211,13 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
struct fsf_status_read_buffer *sr_buf = req->data;
if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
- zfcp_dbf_hba_fsf_unsol("dism", adapter->dbf, sr_buf);
+ zfcp_dbf_hba_fsf_uss("fssrh_1", req);
mempool_free(sr_buf, adapter->pool.status_read_data);
zfcp_fsf_req_free(req);
return;
}
- zfcp_dbf_hba_fsf_unsol("read", adapter->dbf, sr_buf);
+ zfcp_dbf_hba_fsf_uss("fssrh_2", req);
switch (sr_buf->status_type) {
case FSF_STATUS_READ_PORT_CLOSED:
@@ -232,7 +232,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
dev_warn(&adapter->ccw_device->dev,
"The error threshold for checksum statistics "
"has been exceeded\n");
- zfcp_dbf_hba_berr(adapter->dbf, req);
+ zfcp_dbf_hba_bit_err("fssrh_3", req);
break;
case FSF_STATUS_READ_LINK_DOWN:
zfcp_fsf_status_read_link_down(req);
@@ -247,7 +247,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED,
- "fssrh_2", req);
+ "fssrh_2");
zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKUP, 0);
break;
@@ -287,7 +287,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
"The FCP adapter reported a problem "
"that cannot be recovered\n");
zfcp_qdio_siosl(req->adapter);
- zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1");
break;
}
/* all non-return stats set FSFREQ_ERROR*/
@@ -304,7 +304,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
dev_err(&req->adapter->ccw_device->dev,
"The FCP adapter does not recognize the command 0x%x\n",
req->qtcb->header.fsf_command);
- zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1", req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -335,17 +335,17 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
"QTCB version 0x%x not supported by FCP adapter "
"(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
psq->word[0], psq->word[1]);
- zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1");
break;
case FSF_PROT_ERROR_STATE:
case FSF_PROT_SEQ_NUMB_ERROR:
- zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fspse_2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_UNSUPP_QTCB_TYPE:
dev_err(&adapter->ccw_device->dev,
"The QTCB type is not supported by the FCP adapter\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3");
break;
case FSF_PROT_HOST_CONNECTION_INITIALIZING:
atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
@@ -355,12 +355,12 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"0x%Lx is an ambiguous request identifier\n",
(unsigned long long)qtcb->bottom.support.req_handle);
- zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4");
break;
case FSF_PROT_LINK_DOWN:
zfcp_fsf_link_down_info_eval(req, &psq->link_down_info);
/* go through reopen to flush pending requests */
- zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fspse_6");
break;
case FSF_PROT_REEST_QUEUE:
/* All ports should be marked as ready to run again */
@@ -369,14 +369,14 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED,
- "fspse_8", req);
+ "fspse_8");
break;
default:
dev_err(&adapter->ccw_device->dev,
"0x%x is not a valid transfer protocol status\n",
qtcb->prefix.prot_status);
zfcp_qdio_siosl(adapter);
- zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9");
}
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -482,7 +482,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"Unknown or unsupported arbitrated loop "
"fibre channel topology detected\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1");
return -EIO;
}
@@ -518,7 +518,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
"FCP adapter maximum QTCB size (%d bytes) "
"is too small\n",
bottom->max_qtcb_size);
- zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1");
return;
}
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
@@ -536,7 +536,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
&qtcb->header.fsf_status_qual.link_down_info);
break;
default:
- zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3");
return;
}
@@ -552,14 +552,14 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"The FCP adapter only supports newer "
"control block versions\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4");
return;
}
if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
dev_err(&adapter->ccw_device->dev,
"The FCP adapter only supports older "
"control block versions\n");
- zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5", req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5");
}
}
@@ -700,7 +700,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
del_timer(&req->timer);
/* lookup request again, list might have changed */
zfcp_reqlist_find_rm(adapter->req_list, req_id);
- zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1", req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1");
return -EIO;
}
@@ -754,10 +754,11 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio)
goto out;
failed_req_send:
+ req->data = NULL;
mempool_free(sr_buf, adapter->pool.status_read_data);
failed_buf:
+ zfcp_dbf_hba_fsf_uss("fssr__1", req);
zfcp_fsf_req_free(req);
- zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL);
out:
spin_unlock_irq(&qdio->req_q_lock);
return retval;
@@ -776,14 +777,13 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
case FSF_PORT_HANDLE_NOT_VALID:
if (fsq->word[0] == fsq->word[1]) {
zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0,
- "fsafch1", req);
+ "fsafch1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
break;
case FSF_LUN_HANDLE_NOT_VALID:
if (fsq->word[0] == fsq->word[1]) {
- zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2",
- req);
+ zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
break;
@@ -794,14 +794,13 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
zfcp_erp_set_port_status(zfcp_sdev->port,
ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_port_reopen(zfcp_sdev->port,
- ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3",
- req);
+ ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_LUN_BOXED:
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fsafch4", req);
+ "fsafch4");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -851,7 +850,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
- req->data = zfcp_sdev;
+ req->data = sdev;
req->handler = zfcp_fsf_abort_fcp_command_handler;
req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -882,7 +881,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_dbf_san_ct_response(req);
+ zfcp_dbf_san_res("fsscth1", req);
ct->status = 0;
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -902,7 +901,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fsscth1");
/* fall through */
case FSF_GENERIC_COMMAND_REJECTED:
case FSF_PAYLOAD_SIZE_MISMATCH:
@@ -1025,7 +1024,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
req->qtcb->header.port_handle = wka_port->handle;
req->data = ct;
- zfcp_dbf_san_ct_request(req, wka_port->d_id);
+ zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
ret = zfcp_fsf_req_send(req);
if (ret)
@@ -1053,7 +1052,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_dbf_san_els_response(req);
+ zfcp_dbf_san_res("fsselh1", req);
send_els->status = 0;
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1127,7 +1126,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
req->handler = zfcp_fsf_send_els_handler;
req->data = els;
- zfcp_dbf_san_els_request(req);
+ zfcp_dbf_san_req("fssels1", req, d_id);
ret = zfcp_fsf_req_send(req);
if (ret)
@@ -1448,7 +1447,7 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1", req);
+ zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -1580,7 +1579,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
- zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
+ zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1");
}
wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
@@ -1638,7 +1637,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1", req);
+ zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ACCESS_DENIED:
@@ -1654,7 +1653,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
&sdev_to_zfcp(sdev)->status);
zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fscpph2", req);
+ "fscpph2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -1743,7 +1742,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1", req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1");
/* fall through */
case FSF_LUN_ALREADY_OPEN:
break;
@@ -1755,8 +1754,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
zfcp_erp_set_port_status(zfcp_sdev->port,
ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_port_reopen(zfcp_sdev->port,
- ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2",
- req);
+ ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_LUN_SHARING_VIOLATION:
@@ -1852,20 +1850,18 @@ static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1",
- req);
+ zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_LUN_HANDLE_NOT_VALID:
- zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2", req);
+ zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_BOXED:
zfcp_erp_set_port_status(zfcp_sdev->port,
ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_port_reopen(zfcp_sdev->port,
- ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3",
- req);
+ ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -2002,13 +1998,12 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_HANDLE_MISMATCH:
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1",
- req);
+ zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_FCPLUN_NOT_VALID:
case FSF_LUN_HANDLE_NOT_VALID:
- zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2", req);
+ zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -2026,7 +2021,7 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
(unsigned long long)zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
- "fssfch3", req);
+ "fssfch3");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_CMND_LENGTH_NOT_VALID:
@@ -2037,21 +2032,20 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
(unsigned long long)zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
- "fssfch4", req);
+ "fssfch4");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_BOXED:
zfcp_erp_set_port_status(zfcp_sdev->port,
ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_port_reopen(zfcp_sdev->port,
- ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5",
- req);
+ ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_LUN_BOXED:
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
- "fssfch6", req);
+ "fssfch6");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -2069,8 +2063,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
struct fcp_resp_with_ext *fcp_rsp;
unsigned long flags;
- zfcp_fsf_fcp_handler_common(req);
-
read_lock_irqsave(&req->adapter->abort_lock, flags);
scpnt = req->data;
@@ -2079,6 +2071,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
return;
}
+ zfcp_fsf_fcp_handler_common(req);
+
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
goto skip_fsfstatus;
@@ -2104,7 +2098,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
skip_fsfstatus:
zfcp_fsf_req_trace(req, scpnt);
- zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
+ zfcp_dbf_scsi_result(scpnt, req);
scpnt->host_scribble = NULL;
(scpnt->scsi_done) (scpnt);
@@ -2170,12 +2164,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
struct zfcp_qdio *qdio = adapter->qdio;
struct fsf_qtcb_bottom_io *io;
+ unsigned long flags;
if (unlikely(!(atomic_read(&zfcp_sdev->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
return -EBUSY;
- spin_lock(&qdio->req_q_lock);
+ spin_lock_irqsave(&qdio->req_q_lock, flags);
if (atomic_read(&qdio->req_q_free) <= 0) {
atomic_inc(&qdio->req_q_full);
goto out;
@@ -2239,7 +2234,7 @@ failed_scsi_cmnd:
zfcp_fsf_req_free(req);
scsi_cmnd->host_scribble = NULL;
out:
- spin_unlock(&qdio->req_q_lock);
+ spin_unlock_irqrestore(&qdio->req_q_lock, flags);
return retval;
}
@@ -2419,3 +2414,12 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
break;
}
}
+
+struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *qdio,
+ struct qdio_buffer *sbal)
+{
+ struct qdio_buffer_element *sbale = &sbal->element[0];
+ u64 req_id = (unsigned long) sbale->addr;
+
+ return zfcp_reqlist_find(qdio->adapter->req_list, req_id);
+}
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index a0554beb4179..8da5ed644c2b 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -41,7 +41,7 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
- ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL);
+ ZFCP_STATUS_COMMON_ERP_FAILED, id);
}
static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
@@ -74,7 +74,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
if (unlikely(qdio_err)) {
- zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
return;
}
@@ -97,7 +96,6 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
int sbal_idx, sbal_no;
if (unlikely(qdio_err)) {
- zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
return;
}
@@ -116,7 +114,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
* put SBALs back to response queue
*/
if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
- zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL);
+ zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
}
static struct qdio_buffer_element *
@@ -236,7 +234,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
if (!ret) {
atomic_inc(&qdio->req_q_full);
/* assume hanging outbound queue, try queue recovery */
- zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL);
+ zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1");
}
spin_lock_irq(&qdio->req_q_lock);
@@ -292,6 +290,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
id->int_parm = (unsigned long) qdio;
id->input_sbal_addr_array = (void **) (qdio->res_q);
id->output_sbal_addr_array = (void **) (qdio->req_q);
+ id->scan_threshold =
+ QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2;
}
/**
@@ -309,6 +309,7 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
return -ENOMEM;
zfcp_qdio_setup_init_data(&init_data, qdio);
+ init_waitqueue_head(&qdio->req_q_wq);
return qdio_allocate(&init_data);
}
@@ -393,6 +394,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
/* set index of first avalable SBALS / number of available SBALS */
qdio->req_q_idx = 0;
atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
return 0;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 6bd2dbc4c316..ddb5800823a9 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -30,6 +30,10 @@ module_param_named(dif, enable_dif, bool, 0600);
MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
#endif
+static bool allow_lun_scan = 1;
+module_param(allow_lun_scan, bool, 0600);
+MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs");
+
static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
int reason)
{
@@ -68,31 +72,26 @@ static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
{
- struct zfcp_adapter *adapter =
- (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
-
set_host_byte(scpnt, result);
- zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
+ zfcp_dbf_scsi_fail_send(scpnt);
scpnt->scsi_done(scpnt);
}
-static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
- void (*done) (struct scsi_cmnd *))
+static
+int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
{
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
- struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
int status, scsi_result, ret;
/* reset the status for this request */
scpnt->result = 0;
scpnt->host_scribble = NULL;
- scpnt->scsi_done = done;
scsi_result = fc_remote_port_chkready(rport);
if (unlikely(scsi_result)) {
scpnt->result = scsi_result;
- zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
+ zfcp_dbf_scsi_fail_send(scpnt);
scpnt->scsi_done(scpnt);
return 0;
}
@@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
return ret;
}
-static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
-
static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
@@ -137,6 +134,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_port *port;
struct zfcp_unit *unit;
+ int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE;
port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
if (!port)
@@ -146,7 +144,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
if (unit)
put_device(&unit->dev);
- if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
+ if (!unit && !(allow_lun_scan && npiv)) {
put_device(&port->dev);
return -ENXIO;
}
@@ -161,7 +159,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
spin_lock_init(&zfcp_sdev->latencies.lock);
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
- zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL);
+ zfcp_erp_lun_reopen(sdev, 0, "scsla_1");
zfcp_erp_wait(port->adapter);
return 0;
@@ -185,8 +183,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
old_req = zfcp_reqlist_find(adapter->req_list, old_reqid);
if (!old_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags);
- zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL,
- old_reqid);
+ zfcp_dbf_scsi_abort("abrt_or", scpnt, NULL);
return FAILED; /* completion could be in progress */
}
old_req->data = NULL;
@@ -201,29 +198,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
- if (ret)
+ if (ret) {
+ zfcp_dbf_scsi_abort("abrt_bl", scpnt, NULL);
return ret;
+ }
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
- zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
- old_reqid);
+ zfcp_dbf_scsi_abort("abrt_ru", scpnt, NULL);
return SUCCESS;
}
}
- if (!abrt_req)
+ if (!abrt_req) {
+ zfcp_dbf_scsi_abort("abrt_ar", scpnt, NULL);
return FAILED;
+ }
wait_for_completion(&abrt_req->completion);
if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
- dbf_tag = "okay";
+ dbf_tag = "abrt_ok";
else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED)
- dbf_tag = "lte2";
+ dbf_tag = "abrt_nn";
else {
- dbf_tag = "fail";
+ dbf_tag = "abrt_fa";
retval = FAILED;
}
- zfcp_dbf_scsi_abort(dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid);
+ zfcp_dbf_scsi_abort(dbf_tag, scpnt, abrt_req);
zfcp_fsf_req_free(abrt_req);
return retval;
}
@@ -283,7 +283,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
int ret;
- zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
+ zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
if (ret)
@@ -521,7 +521,7 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
if (port) {
- zfcp_erp_port_forced_reopen(port, 0, "sctrpi1", NULL);
+ zfcp_erp_port_forced_reopen(port, 0, "sctrpi1");
put_device(&port->dev);
}
}
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 2f2c54f4718f..cdc4ff78a7ba 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -105,8 +105,7 @@ static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
return -EINVAL;
zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
- zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2",
- NULL);
+ zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2");
zfcp_erp_wait(port->adapter);
return count;
@@ -148,7 +147,7 @@ static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
if (sdev) {
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
- "syufai2", NULL);
+ "syufai2");
zfcp_erp_wait(unit->port->adapter);
} else
zfcp_unit_scsi_scan(unit);
@@ -198,7 +197,7 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- "syafai2", NULL);
+ "syafai2");
zfcp_erp_wait(adapter);
out:
zfcp_ccw_adapter_put(adapter);
@@ -256,7 +255,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
put_device(&port->dev);
- zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
+ zfcp_erp_port_shutdown(port, 0, "syprs_1");
zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
out:
zfcp_ccw_adapter_put(adapter);
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 17e3df4f016f..1cadcd6b7da6 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1171,9 +1171,8 @@ static int arcmsr_build_ccb(struct AdapterControlBlock *acb,
arcmsr_cdb->msgPages = arccdbsize/0x100 + (arccdbsize % 0x100 ? 1 : 0);
if ( arccdbsize > 256)
arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
- if (pcmd->cmnd[0]|WRITE_6 || pcmd->cmnd[0]|WRITE_10 || pcmd->cmnd[0]|WRITE_12 ){
+ if (pcmd->sc_data_direction == DMA_TO_DEVICE)
arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
- }
ccb->arc_cdb_size = arccdbsize;
return SUCCESS;
}
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 75a85aa9e882..79cefbe31367 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -3785,7 +3785,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
dma_addr_t paddr;
io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool,
- GFP_KERNEL, &paddr);
+ GFP_ATOMIC, &paddr);
if (!io_task->cmd_bhs)
return -ENOMEM;
io_task->bhs_pa.u.a64.address = paddr;
@@ -3914,7 +3914,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
io_task->psgl_handle = NULL;
}
} else {
- if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN)
+ if (task->hdr &&
+ ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN))
return;
if (io_task->psgl_handle) {
spin_lock(&phba->mgmt_sgl_lock);
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index d2eefd3e3bd5..4ce6f4942327 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -3,6 +3,4 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_im.o bfad_attr.o bfad_debugfs.o
bfa-y += bfa_ioc.o bfa_ioc_cb.o bfa_ioc_ct.o bfa_hw_cb.o bfa_hw_ct.o
bfa-y += bfa_fcs.o bfa_fcs_lport.o bfa_fcs_rport.o bfa_fcs_fcpim.o bfa_fcbuild.o
-bfa-y += bfa_port.o bfa_fcpim.o bfa_core.o bfa_drv.o bfa_svc.o
-
-ccflags-y := -DBFA_PERF_BUILD
+bfa-y += bfa_port.o bfa_fcpim.o bfa_core.o bfa_svc.o
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
index ff2bd07161f7..7be6b5a8114b 100644
--- a/drivers/scsi/bfa/bfa.h
+++ b/drivers/scsi/bfa/bfa.h
@@ -17,7 +17,7 @@
#ifndef __BFA_H__
#define __BFA_H__
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#include "bfa_cs.h"
#include "bfa_plog.h"
#include "bfa_defs_svc.h"
@@ -33,7 +33,6 @@ typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
* Interrupt message handlers
*/
void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
-void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
/*
* Request and response queue related defines
@@ -121,8 +120,8 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
\
struct list_head *waitq = bfa_reqq(__bfa, __reqq); \
\
- bfa_assert(((__reqq) < BFI_IOC_MAX_CQS)); \
- bfa_assert((__wqe)->qresume && (__wqe)->cbarg); \
+ WARN_ON(((__reqq) >= BFI_IOC_MAX_CQS)); \
+ WARN_ON(!((__wqe)->qresume && (__wqe)->cbarg)); \
\
list_add_tail(&(__wqe)->qe, waitq); \
} while (0)
@@ -297,7 +296,6 @@ void bfa_iocfc_attach(struct bfa_s *bfa, void *bfad,
struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo,
struct bfa_pcidev_s *pcidev);
-void bfa_iocfc_detach(struct bfa_s *bfa);
void bfa_iocfc_init(struct bfa_s *bfa);
void bfa_iocfc_start(struct bfa_s *bfa);
void bfa_iocfc_stop(struct bfa_s *bfa);
@@ -333,12 +331,9 @@ void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs,
u32 *maxvec);
void bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start,
u32 *end);
-void bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi);
void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns);
wwn_t bfa_iocfc_get_pwwn(struct bfa_s *bfa);
wwn_t bfa_iocfc_get_nwwn(struct bfa_s *bfa);
-void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa,
- struct bfa_boot_pbc_s *pbcfg);
int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
struct bfi_pbc_vport_s *pbc_vport);
@@ -386,19 +381,11 @@ void bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg,
void bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo,
struct bfa_pcidev_s *pcidev);
-void bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod);
-void bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog);
void bfa_detach(struct bfa_s *bfa);
-void bfa_init(struct bfa_s *bfa);
-void bfa_start(struct bfa_s *bfa);
-void bfa_stop(struct bfa_s *bfa);
-void bfa_attach_fcs(struct bfa_s *bfa);
void bfa_cb_init(void *bfad, bfa_status_t status);
void bfa_cb_updateq(void *bfad, bfa_status_t status);
bfa_boolean_t bfa_intx(struct bfa_s *bfa);
-void bfa_intx_disable(struct bfa_s *bfa);
-void bfa_intx_enable(struct bfa_s *bfa);
void bfa_isr_enable(struct bfa_s *bfa);
void bfa_isr_disable(struct bfa_s *bfa);
@@ -408,31 +395,14 @@ void bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q);
typedef void (*bfa_cb_ioc_t) (void *cbarg, enum bfa_status status);
void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr);
-void bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr);
-void bfa_adapter_get_attr(struct bfa_s *bfa,
- struct bfa_adapter_attr_s *ad_attr);
-u64 bfa_adapter_get_id(struct bfa_s *bfa);
bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
struct bfa_iocfc_intr_attr_s *attr);
void bfa_iocfc_enable(struct bfa_s *bfa);
void bfa_iocfc_disable(struct bfa_s *bfa);
-void bfa_chip_reset(struct bfa_s *bfa);
-void bfa_timer_tick(struct bfa_s *bfa);
#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
-/*
- * BFA debug API functions
- */
-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);
-bfa_status_t bfa_debug_fwcore(struct bfa_s *bfa, void *buf,
- u32 *offset, int *buflen);
-void bfa_debug_fwsave_clear(struct bfa_s *bfa);
-bfa_status_t bfa_fw_stats_get(struct bfa_s *bfa, void *data);
-bfa_status_t bfa_fw_stats_clear(struct bfa_s *bfa);
-
#endif /* __BFA_H__ */
diff --git a/drivers/scsi/bfa/bfa_cb_ioim.h b/drivers/scsi/bfa/bfa_cb_ioim.h
deleted file mode 100644
index 6f021015f1f6..000000000000
--- a/drivers/scsi/bfa/bfa_cb_ioim.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2005-2010 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_HCB_IOIM_H__
-#define __BFA_HCB_IOIM_H__
-
-#include "bfa_os_inc.h"
-/*
- * task attribute values in FCP-2 FCP_CMND IU
- */
-#define SIMPLE_Q 0
-#define HEAD_OF_Q 1
-#define ORDERED_Q 2
-#define ACA_Q 4
-#define UNTAGGED 5
-
-static inline lun_t
-bfad_int_to_lun(u32 luno)
-{
- union {
- u16 scsi_lun[4];
- lun_t bfa_lun;
- } lun;
-
- lun.bfa_lun = 0;
- lun.scsi_lun[0] = cpu_to_be16(luno);
-
- return lun.bfa_lun;
-}
-
-/*
- * Get LUN for the I/O request
- */
-#define bfa_cb_ioim_get_lun(__dio) \
- bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
-
-/*
- * Get CDB for the I/O request
- */
-static inline u8 *
-bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
- return (u8 *) cmnd->cmnd;
-}
-
-/*
- * Get I/O direction (read/write) for the I/O request
- */
-static inline enum fcp_iodir
-bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
- enum dma_data_direction dmadir;
-
- dmadir = cmnd->sc_data_direction;
- if (dmadir == DMA_TO_DEVICE)
- return FCP_IODIR_WRITE;
- else if (dmadir == DMA_FROM_DEVICE)
- return FCP_IODIR_READ;
- else
- return FCP_IODIR_NONE;
-}
-
-/*
- * Get IO size in bytes for the I/O request
- */
-static inline u32
-bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
- return scsi_bufflen(cmnd);
-}
-
-/*
- * Get timeout for the I/O request
- */
-static inline u8
-bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
- /*
- * TBD: need a timeout for scsi passthru
- */
- if (cmnd->device->host == NULL)
- return 4;
-
- return 0;
-}
-
-/*
- * Get Command Reference Number for the I/O request. 0 if none.
- */
-static inline u8
-bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
-{
- return 0;
-}
-
-/*
- * Get SAM-3 priority for the I/O request. 0 is default.
- */
-static inline u8
-bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
-{
- return 0;
-}
-
-/*
- * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
- */
-static inline u8
-bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
- u8 task_attr = UNTAGGED;
-
- if (cmnd->device->tagged_supported) {
- switch (cmnd->tag) {
- case HEAD_OF_QUEUE_TAG:
- task_attr = HEAD_OF_Q;
- break;
- case ORDERED_QUEUE_TAG:
- task_attr = ORDERED_Q;
- break;
- default:
- task_attr = SIMPLE_Q;
- break;
- }
- }
-
- return task_attr;
-}
-
-/*
- * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
- */
-static inline u8
-bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
-{
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
- return cmnd->cmd_len;
-}
-
-/*
- * Assign queue to be used for the I/O request. This value depends on whether
- * the driver wants to use the queues via any specific algorithm. Currently,
- * this is not supported.
- */
-#define bfa_cb_ioim_get_reqq(__dio) BFA_FALSE
-
-#endif /* __BFA_HCB_IOIM_H__ */
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 2345f48dc57f..1cd5c8b0618d 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -15,13 +15,100 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_modules.h"
#include "bfi_ctreg.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(HAL, CORE);
/*
+ * BFA module list terminated by NULL
+ */
+static struct bfa_module_s *hal_mods[] = {
+ &hal_mod_sgpg,
+ &hal_mod_fcport,
+ &hal_mod_fcxp,
+ &hal_mod_lps,
+ &hal_mod_uf,
+ &hal_mod_rport,
+ &hal_mod_fcpim,
+ NULL
+};
+
+/*
+ * Message handlers for various modules.
+ */
+static bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
+ bfa_isr_unhandled, /* NONE */
+ bfa_isr_unhandled, /* BFI_MC_IOC */
+ bfa_isr_unhandled, /* BFI_MC_DIAG */
+ bfa_isr_unhandled, /* BFI_MC_FLASH */
+ bfa_isr_unhandled, /* BFI_MC_CEE */
+ bfa_fcport_isr, /* BFI_MC_FCPORT */
+ bfa_isr_unhandled, /* BFI_MC_IOCFC */
+ bfa_isr_unhandled, /* BFI_MC_LL */
+ bfa_uf_isr, /* BFI_MC_UF */
+ bfa_fcxp_isr, /* BFI_MC_FCXP */
+ bfa_lps_isr, /* BFI_MC_LPS */
+ bfa_rport_isr, /* BFI_MC_RPORT */
+ bfa_itnim_isr, /* BFI_MC_ITNIM */
+ bfa_isr_unhandled, /* BFI_MC_IOIM_READ */
+ bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */
+ bfa_isr_unhandled, /* BFI_MC_IOIM_IO */
+ bfa_ioim_isr, /* BFI_MC_IOIM */
+ bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
+ bfa_tskim_isr, /* BFI_MC_TSKIM */
+ bfa_isr_unhandled, /* BFI_MC_SBOOT */
+ bfa_isr_unhandled, /* BFI_MC_IPFC */
+ bfa_isr_unhandled, /* BFI_MC_PORT */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+ bfa_isr_unhandled, /* --------- */
+};
+/*
+ * Message handlers for mailbox command classes
+ */
+static bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = {
+ NULL,
+ NULL, /* BFI_MC_IOC */
+ NULL, /* BFI_MC_DIAG */
+ NULL, /* BFI_MC_FLASH */
+ NULL, /* BFI_MC_CEE */
+ NULL, /* BFI_MC_PORT */
+ bfa_iocfc_isr, /* BFI_MC_IOCFC */
+ NULL,
+};
+
+
+
+static void
+bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi)
+{
+ struct bfa_port_s *port = &bfa->modules.port;
+ u32 dm_len;
+ u8 *dm_kva;
+ u64 dm_pa;
+
+ dm_len = bfa_port_meminfo();
+ dm_kva = bfa_meminfo_dma_virt(mi);
+ dm_pa = bfa_meminfo_dma_phys(mi);
+
+ memset(port, 0, sizeof(struct bfa_port_s));
+ bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
+ bfa_port_mem_claim(port, dm_kva, dm_pa);
+
+ bfa_meminfo_dma_virt(mi) = dm_kva + dm_len;
+ bfa_meminfo_dma_phys(mi) = dm_pa + dm_len;
+}
+
+/*
* BFA IOC FC related definitions
*/
@@ -67,18 +154,6 @@ static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
* BFA Interrupt handling functions
*/
static void
-bfa_msix_errint(struct bfa_s *bfa, u32 intr)
-{
- bfa_ioc_error_isr(&bfa->ioc);
-}
-
-static void
-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;
@@ -104,9 +179,6 @@ bfa_msix_all(struct bfa_s *bfa, int vec)
bfa_intx(bfa);
}
-/*
- * hal_intr_api
- */
bfa_boolean_t
bfa_intx(struct bfa_s *bfa)
{
@@ -151,18 +223,6 @@ bfa_intx(struct bfa_s *bfa)
}
void
-bfa_intx_enable(struct bfa_s *bfa)
-{
- writel(bfa->iocfc.intr_mask, bfa->iocfc.bfa_regs.intr_mask);
-}
-
-void
-bfa_intx_disable(struct bfa_s *bfa)
-{
- writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
-}
-
-void
bfa_isr_enable(struct bfa_s *bfa)
{
u32 intr_unmask;
@@ -225,7 +285,7 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
bfa_trc(bfa, m->mhdr.msg_class);
bfa_trc(bfa, m->mhdr.msg_id);
bfa_trc(bfa, m->mhdr.mtag.i2htok);
- bfa_assert(0);
+ WARN_ON(1);
bfa_trc_stop(bfa->trcmod);
}
@@ -236,8 +296,6 @@ bfa_msix_rspq(struct bfa_s *bfa, int qid)
u32 pi, ci;
struct list_head *waitq;
- bfa_trc_fp(bfa, qid);
-
qid &= (BFI_IOC_MAX_CQS - 1);
bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
@@ -245,16 +303,10 @@ bfa_msix_rspq(struct bfa_s *bfa, int 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, qid, ci);
- bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
-
bfa_isrs[m->mhdr.msg_class] (bfa, m);
-
CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);
}
}
@@ -282,7 +334,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
intr = readl(bfa->iocfc.bfa_regs.intr_status);
if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
- bfa_msix_lpu(bfa);
+ bfa_ioc_mbox_isr(&bfa->ioc);
intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
@@ -313,22 +365,16 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
}
writel(intr, bfa->iocfc.bfa_regs.intr_status);
- bfa_msix_errint(bfa, intr);
+ bfa_ioc_error_isr(&bfa->ioc);
}
}
-void
-bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func)
-{
- bfa_isrs[mc] = isr_func;
-}
-
/*
* BFA IOC FC related functions
*/
/*
- * hal_ioc_pvt BFA IOC private functions
+ * BFA IOC private functions
*/
static void
@@ -379,7 +425,7 @@ bfa_iocfc_send_cfg(void *bfa_arg)
struct bfa_iocfc_cfg_s *cfg = &iocfc->cfg;
int i;
- bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS);
+ WARN_ON(cfg->fwcfg.num_cqs > BFI_IOC_MAX_CQS);
bfa_trc(bfa, cfg->fwcfg.num_cqs);
bfa_iocfc_reset_queues(bfa);
@@ -488,8 +534,8 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
* First allocate dma memory for IOC.
*/
bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa);
- dm_kva += bfa_ioc_meminfo();
- dm_pa += bfa_ioc_meminfo();
+ dm_kva += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
+ dm_pa += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
/*
* Claim DMA-able memory for the request/response queues and for shadow
@@ -552,7 +598,7 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
bfa_meminfo_dma_virt(meminfo) = dm_kva;
bfa_meminfo_dma_phys(meminfo) = dm_pa;
- dbgsz = bfa_ioc_debug_trcsz(bfa_auto_recover);
+ dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
if (dbgsz > 0) {
bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo));
bfa_meminfo_kva(meminfo) += dbgsz;
@@ -699,7 +745,7 @@ bfa_iocfc_disable_cbfn(void *bfa_arg)
bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
bfa);
else {
- bfa_assert(bfa->iocfc.action == BFA_IOCFC_ACT_DISABLE);
+ WARN_ON(bfa->iocfc.action != BFA_IOCFC_ACT_DISABLE);
bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
bfa);
}
@@ -735,9 +781,6 @@ bfa_iocfc_reset_cbfn(void *bfa_arg)
bfa_isr_enable(bfa);
}
-/*
- * hal_ioc_public
- */
/*
* Query IOC memory requirement information.
@@ -747,11 +790,11 @@ bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
u32 *dm_len)
{
/* dma memory for IOC */
- *dm_len += bfa_ioc_meminfo();
+ *dm_len += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
bfa_iocfc_fw_cfg_sz(cfg, dm_len);
bfa_iocfc_cqs_sz(cfg, dm_len);
- *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover);
+ *km_len += (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
}
/*
@@ -783,7 +826,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
bfa_iocfc_mem_claim(bfa, cfg, meminfo);
- bfa_timer_init(&bfa->timer_mod);
+ INIT_LIST_HEAD(&bfa->timer_mod.timer_q);
INIT_LIST_HEAD(&bfa->comp_q);
for (i = 0; i < BFI_IOC_MAX_CQS; i++)
@@ -794,15 +837,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
* Query IOC memory requirement information.
*/
void
-bfa_iocfc_detach(struct bfa_s *bfa)
-{
- bfa_ioc_detach(&bfa->ioc);
-}
-
-/*
- * Query IOC memory requirement information.
- */
-void
bfa_iocfc_init(struct bfa_s *bfa)
{
bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
@@ -852,23 +886,11 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
}
void
-bfa_adapter_get_attr(struct bfa_s *bfa, struct bfa_adapter_attr_s *ad_attr)
-{
- bfa_ioc_get_adapter_attr(&bfa->ioc, ad_attr);
-}
-
-u64
-bfa_adapter_get_id(struct bfa_s *bfa)
-{
- return bfa_ioc_get_adid(&bfa->ioc);
-}
-
-void
bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
{
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
@@ -976,18 +998,6 @@ bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)
memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));
}
-void
-bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg)
-{
- struct bfa_iocfc_s *iocfc = &bfa->iocfc;
- struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
-
- pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled;
- pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns;
- pbcfg->speed = cfgrsp->pbc_cfg.port_speed;
- memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
-}
-
int
bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
{
@@ -998,9 +1008,6 @@ bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
return cfgrsp->pbc_cfg.nvports;
}
-/*
- * hal_api
- */
/*
* Use this function query the memory requirement of the BFA library.
@@ -1036,7 +1043,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
int i;
u32 km_len = 0, dm_len = 0;
- bfa_assert((cfg != NULL) && (meminfo != NULL));
+ WARN_ON((cfg == NULL) || (meminfo == NULL));
memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
@@ -1090,7 +1097,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa->fcs = BFA_FALSE;
- bfa_assert((cfg != NULL) && (meminfo != NULL));
+ WARN_ON((cfg == NULL) || (meminfo == NULL));
/*
* initialize all memory pointers for iterative allocation
@@ -1129,79 +1136,7 @@ bfa_detach(struct bfa_s *bfa)
for (i = 0; hal_mods[i]; i++)
hal_mods[i]->detach(bfa);
-
- bfa_iocfc_detach(bfa);
-}
-
-
-void
-bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
-{
- bfa->trcmod = trcmod;
-}
-
-void
-bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
-{
- bfa->plog = plog;
-}
-
-/*
- * Initialize IOC.
- *
- * This function will return immediately, when the IOC initialization is
- * completed, the bfa_cb_init() will be called.
- *
- * @param[in] bfa instance
- *
- * @return void
- *
- * Special Considerations:
- *
- * @note
- * When this function returns, the driver should register the interrupt service
- * routine(s) and enable the device interrupts. If this is not done,
- * bfa_cb_init() will never get called
- */
-void
-bfa_init(struct bfa_s *bfa)
-{
- bfa_iocfc_init(bfa);
-}
-
-/*
- * Use this function initiate the IOC configuration setup. This function
- * will return immediately.
- *
- * @param[in] bfa instance
- *
- * @return None
- */
-void
-bfa_start(struct bfa_s *bfa)
-{
- bfa_iocfc_start(bfa);
-}
-
-/*
- * Use this function quiese the IOC. This function will return immediately,
- * when the IOC is actually stopped, the bfad->comp will be set.
- *
- * @param[in]bfa - pointer to bfa_t.
- *
- * @return None
- *
- * Special Considerations:
- * bfad->comp can be set before or after bfa_stop() returns.
- *
- * @note
- * In case of any failure, we could handle it automatically by doing a
- * reset and then succeed the bfa_stop() call.
- */
-void
-bfa_stop(struct bfa_s *bfa)
-{
- bfa_iocfc_stop(bfa);
+ bfa_ioc_detach(&bfa->ioc);
}
void
@@ -1237,20 +1172,6 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
}
}
-void
-bfa_attach_fcs(struct bfa_s *bfa)
-{
- bfa->fcs = BFA_TRUE;
-}
-
-/*
- * Periodic timer heart beat from driver
- */
-void
-bfa_timer_tick(struct bfa_s *bfa)
-{
- bfa_timer_beat(&bfa->timer_mod);
-}
/*
* Return the list of PCI vendor/device id lists supported by this
@@ -1321,89 +1242,3 @@ bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
cfg->drvcfg.min_cfg = BFA_TRUE;
}
-
-void
-bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
-{
- bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
-}
-
-/*
- * Retrieve firmware trace information on IOC failure.
- */
-bfa_status_t
-bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
-{
- return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, 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
- * @param[out] trcdata Firmware trace buffer
- * @param[in,out] trclen Firmware trace buffer len
- *
- * @retval BFA_STATUS_OK Firmware trace is fetched.
- * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress.
- */
-bfa_status_t
-bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
-{
- return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
-}
-
-/*
- * Dump firmware memory.
- *
- * @param[in] bfa BFA instance
- * @param[out] buf buffer for dump
- * @param[in,out] offset smem offset to start read
- * @param[in,out] buflen length of buffer
- *
- * @retval BFA_STATUS_OK Firmware memory is dumped.
- * @retval BFA_STATUS_INPROGRESS Firmware memory dump is in progress.
- */
-bfa_status_t
-bfa_debug_fwcore(struct bfa_s *bfa, void *buf, u32 *offset, int *buflen)
-{
- return bfa_ioc_debug_fwcore(&bfa->ioc, buf, offset, buflen);
-}
-/*
- * 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);
-}
-
-/*
- * Fetch firmware statistics data.
- *
- * @param[in] bfa BFA instance
- * @param[out] data Firmware stats buffer
- *
- * @retval BFA_STATUS_OK Firmware trace is fetched.
- */
-bfa_status_t
-bfa_fw_stats_get(struct bfa_s *bfa, void *data)
-{
- return bfa_ioc_fw_stats_get(&bfa->ioc, data);
-}
-
-bfa_status_t
-bfa_fw_stats_clear(struct bfa_s *bfa)
-{
- return bfa_ioc_fw_stats_clear(&bfa->ioc);
-}
diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h
index 99f242b9aa31..12bfeed268eb 100644
--- a/drivers/scsi/bfa/bfa_cs.h
+++ b/drivers/scsi/bfa/bfa_cs.h
@@ -22,7 +22,7 @@
#ifndef __BFA_CS_H__
#define __BFA_CS_H__
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
/*
* BFA TRC
@@ -32,12 +32,20 @@
#define BFA_TRC_MAX (4 * 1024)
#endif
+#define BFA_TRC_TS(_trcm) \
+ ({ \
+ struct timeval tv; \
+ \
+ do_gettimeofday(&tv); \
+ (tv.tv_sec*1000000+tv.tv_usec); \
+ })
+
#ifndef BFA_TRC_TS
#define BFA_TRC_TS(_trcm) ((_trcm)->ticks++)
#endif
struct bfa_trc_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u16 fileno;
u16 line;
#else
@@ -99,13 +107,6 @@ bfa_trc_stop(struct bfa_trc_mod_s *trcm)
trcm->stopped = 1;
}
-#ifdef FWTRC
-extern void dc_flush(void *data);
-#else
-#define dc_flush(data)
-#endif
-
-
static inline void
__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data)
{
@@ -119,12 +120,10 @@ __bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data)
trc->line = (u16) line;
trc->data.u64 = data;
trc->timestamp = BFA_TRC_TS(trcm);
- dc_flush(trc);
trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
if (trcm->tail == trcm->head)
trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
- dc_flush(trcm);
}
@@ -141,42 +140,18 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
trc->line = (u16) line;
trc->data.u32.u32 = data;
trc->timestamp = BFA_TRC_TS(trcm);
- dc_flush(trc);
trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
if (trcm->tail == trcm->head)
trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
- dc_flush(trcm);
}
-#ifndef BFA_PERF_BUILD
-#define bfa_trc_fp(_trcp, _data) bfa_trc(_trcp, _data)
-#else
-#define bfa_trc_fp(_trcp, _data)
-#endif
-
-/*
- * @ BFA LOG interfaces
- */
-#define bfa_assert(__cond) do { \
- if (!(__cond)) { \
- printk(KERN_ERR "assert(%s) failed at %s:%d\\n", \
- #__cond, __FILE__, __LINE__); \
- } \
-} while (0)
-
#define bfa_sm_fault(__mod, __event) do { \
bfa_trc(__mod, (((u32)0xDEAD << 16) | __event)); \
printk(KERN_ERR "Assertion failure: %s:%d: %d", \
__FILE__, __LINE__, (__event)); \
} while (0)
-#ifndef BFA_PERF_BUILD
-#define bfa_assert_fp(__cond) bfa_assert(__cond)
-#else
-#define bfa_assert_fp(__cond)
-#endif
-
/* BFA queue definitions */
#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))
#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)
@@ -199,7 +174,6 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
(struct list_head *) (_q); \
bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe));\
- BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
} else { \
*((struct list_head **) (_qe)) = (struct list_head *) NULL;\
} \
@@ -214,7 +188,6 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \
(struct list_head *) (_q); \
bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe);\
- BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
} else { \
*((struct list_head **) (_qe)) = (struct list_head *) NULL;\
} \
@@ -236,16 +209,6 @@ bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
return 0;
}
-/*
- * #ifdef BFA_DEBUG (Using bfa_assert to check for debug_build is not
- * consistent across modules)
- */
-#ifndef BFA_PERF_BUILD
-#define BFA_Q_DBG_INIT(_qe) bfa_q_qe_init(_qe)
-#else
-#define BFA_Q_DBG_INIT(_qe)
-#endif
-
#define bfa_q_is_on_q(_q, _qe) \
bfa_q_is_on_q_func(_q, (struct list_head *)(_qe))
@@ -361,4 +324,43 @@ bfa_wc_wait(struct bfa_wc_s *wc)
bfa_wc_down(wc);
}
+static inline void
+wwn2str(char *wwn_str, u64 wwn)
+{
+ union {
+ u64 wwn;
+ u8 byte[8];
+ } w;
+
+ w.wwn = wwn;
+ sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
+ w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
+ w.byte[6], w.byte[7]);
+}
+
+static inline void
+fcid2str(char *fcid_str, u32 fcid)
+{
+ union {
+ u32 fcid;
+ u8 byte[4];
+ } f;
+
+ f.fcid = fcid;
+ sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
+}
+
+#define bfa_swap_3b(_x) \
+ ((((_x) & 0xff) << 16) | \
+ ((_x) & 0x00ff00) | \
+ (((_x) & 0xff0000) >> 16))
+
+#ifndef __BIG_ENDIAN
+#define bfa_hton3b(_x) bfa_swap_3b(_x)
+#else
+#define bfa_hton3b(_x) (_x)
+#endif
+
+#define bfa_ntoh3b(_x) bfa_hton3b(_x)
+
#endif /* __BFA_CS_H__ */
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index 4b5b9e35abb9..d85f93aea465 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -19,7 +19,7 @@
#define __BFA_DEFS_H__
#include "bfa_fc.h"
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#define BFA_MFG_SERIALNUM_SIZE 11
#define STRSZ(_n) (((_n) + 4) & ~3)
@@ -446,8 +446,8 @@ enum bfa_boot_bootopt {
* Boot lun information.
*/
struct bfa_boot_bootlun_s {
- wwn_t pwwn; /* port wwn of target */
- lun_t lun; /* 64-bit lun */
+ wwn_t pwwn; /* port wwn of target */
+ struct scsi_lun lun; /* 64-bit lun */
};
#pragma pack()
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index e24e9f7ca81f..648c84176722 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -34,8 +34,8 @@
struct bfa_iocfc_intr_attr_s {
u8 coalesce; /* enable/disable coalescing */
u8 rsvd[3];
- u16 latency; /* latency in microseconds */
- u16 delay; /* delay in microseconds */
+ __be16 latency; /* latency in microseconds */
+ __be16 delay; /* delay in microseconds */
};
/*
@@ -743,7 +743,7 @@ struct bfa_port_cfg_s {
u8 qos_enabled; /* qos enabled or not */
u8 cfg_hardalpa; /* is hard alpa configured */
u8 hardalpa; /* configured hard alpa */
- u16 maxfrsize; /* maximum frame size */
+ __be16 maxfrsize; /* maximum frame size */
u8 rx_bbcredit; /* receive buffer credits */
u8 tx_bbcredit; /* transmit buffer credits */
u8 ratelimit; /* ratelimit enabled or not */
@@ -843,7 +843,7 @@ struct bfa_fcport_fcf_s {
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 */
+ __be16 vlan; /* FCoE vlan tag/priority */
u32 fka_adv_per; /* FIP ka advert. period */
mac_t mac; /* FCF mac */
};
diff --git a/drivers/scsi/bfa/bfa_drv.c b/drivers/scsi/bfa/bfa_drv.c
deleted file mode 100644
index 0222d7c88a9a..000000000000
--- a/drivers/scsi/bfa/bfa_drv.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2005-2010 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_modules.h"
-
-/*
- * BFA module list terminated by NULL
- */
-struct bfa_module_s *hal_mods[] = {
- &hal_mod_sgpg,
- &hal_mod_fcport,
- &hal_mod_fcxp,
- &hal_mod_lps,
- &hal_mod_uf,
- &hal_mod_rport,
- &hal_mod_fcpim,
- NULL
-};
-
-/*
- * Message handlers for various modules.
- */
-bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
- bfa_isr_unhandled, /* NONE */
- bfa_isr_unhandled, /* BFI_MC_IOC */
- bfa_isr_unhandled, /* BFI_MC_DIAG */
- bfa_isr_unhandled, /* BFI_MC_FLASH */
- bfa_isr_unhandled, /* BFI_MC_CEE */
- bfa_fcport_isr, /* BFI_MC_FCPORT */
- bfa_isr_unhandled, /* BFI_MC_IOCFC */
- bfa_isr_unhandled, /* BFI_MC_LL */
- bfa_uf_isr, /* BFI_MC_UF */
- bfa_fcxp_isr, /* BFI_MC_FCXP */
- bfa_lps_isr, /* BFI_MC_LPS */
- bfa_rport_isr, /* BFI_MC_RPORT */
- bfa_itnim_isr, /* BFI_MC_ITNIM */
- bfa_isr_unhandled, /* BFI_MC_IOIM_READ */
- bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */
- bfa_isr_unhandled, /* BFI_MC_IOIM_IO */
- bfa_ioim_isr, /* BFI_MC_IOIM */
- bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
- bfa_tskim_isr, /* BFI_MC_TSKIM */
- bfa_isr_unhandled, /* BFI_MC_SBOOT */
- bfa_isr_unhandled, /* BFI_MC_IPFC */
- bfa_isr_unhandled, /* BFI_MC_PORT */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
- bfa_isr_unhandled, /* --------- */
-};
-
-
-/*
- * Message handlers for mailbox command classes
- */
-bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = {
- NULL,
- NULL, /* BFI_MC_IOC */
- NULL, /* BFI_MC_DIAG */
- NULL, /* BFI_MC_FLASH */
- NULL, /* BFI_MC_CEE */
- NULL, /* BFI_MC_PORT */
- bfa_iocfc_isr, /* BFI_MC_IOCFC */
- NULL,
-};
-
-
-
-void
-bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi)
-{
- struct bfa_port_s *port = &bfa->modules.port;
- u32 dm_len;
- u8 *dm_kva;
- u64 dm_pa;
-
- dm_len = bfa_port_meminfo();
- dm_kva = bfa_meminfo_dma_virt(mi);
- dm_pa = bfa_meminfo_dma_phys(mi);
-
- memset(port, 0, sizeof(struct bfa_port_s));
- bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
- bfa_port_mem_claim(port, dm_kva, dm_pa);
-
- bfa_meminfo_dma_virt(mi) = dm_kva + dm_len;
- bfa_meminfo_dma_phys(mi) = dm_pa + dm_len;
-}
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h
index e929d25b09e3..8e764fae8dc9 100644
--- a/drivers/scsi/bfa/bfa_fc.h
+++ b/drivers/scsi/bfa/bfa_fc.h
@@ -18,14 +18,12 @@
#ifndef __BFA_FC_H__
#define __BFA_FC_H__
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
typedef u64 wwn_t;
-typedef u64 lun_t;
#define WWN_NULL (0)
#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
-#define FC_ALPA_MAX 128
#pragma pack(1)
@@ -40,7 +38,6 @@ struct mac_s { u8 mac[MAC_ADDRLEN]; };
struct scsi_cdb_s {
u8 scsi_cdb[SCSI_MAX_CDBLEN];
};
-#define scsi_cdb_t struct scsi_cdb_s
/* ------------------------------------------------------------
* SCSI status byte values
@@ -63,7 +60,7 @@ struct scsi_cdb_s {
* Fibre Channel Header Structure (FCHS) definition
*/
struct fchs_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 routing:4; /* routing bits */
u32 cat_info:4; /* category info */
#else
@@ -75,34 +72,19 @@ struct fchs_s {
u32 cs_ctl:8; /* class specific control */
u32 s_id:24; /* source identifier */
- u32 type:8; /* data structure type */
+ u32 type:8; /* data structure type */
u32 f_ctl:24; /* initial frame control */
- u8 seq_id; /* sequence identifier */
- u8 df_ctl; /* data field control */
+ u8 seq_id; /* sequence identifier */
+ u8 df_ctl; /* data field control */
u16 seq_cnt; /* sequence count */
- u16 ox_id; /* originator exchange ID */
- u16 rx_id; /* responder exchange ID */
+ __be16 ox_id; /* originator exchange ID */
+ u16 rx_id; /* responder exchange ID */
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
- */
-struct fcbbehs_s {
- u16 ver_rsvd;
- u32 rsvd[2];
- u32 rsvd__sof;
-};
-
-#define FC_SEQ_ID_MAX 256
-
/*
* routing bit definitions
*/
@@ -149,22 +131,6 @@ enum {
};
/*
- * information category for Link Control
- */
-enum {
- FC_CAT_ACK_1 = 0x00,
- FC_CAT_ACK_0_N = 0x01,
- FC_CAT_P_RJT = 0x02,
- FC_CAT_F_RJT = 0x03,
- FC_CAT_P_BSY = 0x04,
- FC_CAT_F_BSY_DATA = 0x05,
- FC_CAT_F_BSY_LINK_CTL = 0x06,
- FC_CAT_F_LCR = 0x07,
- FC_CAT_NTY = 0x08,
- FC_CAT_END = 0x09,
-};
-
-/*
* Type Field Definitions. FC-PH Section 18.5 pg. 165
*/
enum {
@@ -182,10 +148,6 @@ enum {
FC_TYPE_MAX = 256, /* 256 FC-4 types */
};
-struct fc_fc4types_s {
- u8 bits[FC_TYPE_MAX / 8];
-};
-
/*
* Frame Control Definitions. FC-PH Table-45. pg. 168
*/
@@ -288,7 +250,6 @@ enum {
FC_ELS_AUTH = 0x90, /* Authentication. Ref FC-SP */
FC_ELS_RFCN = 0x97, /* Request Fabric Change Notification. Ref
*FC-SP */
-
};
/*
@@ -314,12 +275,12 @@ enum {
* FC-PH-x. Figure-76. pg. 308.
*/
struct fc_plogi_csp_s {
- u8 verhi; /* FC-PH high version */
- u8 verlo; /* FC-PH low version */
- u16 bbcred; /* BB_Credit */
+ u8 verhi; /* FC-PH high version */
+ u8 verlo; /* FC-PH low version */
+ __be16 bbcred; /* BB_Credit */
-#ifdef __BIGENDIAN
- u8 ciro:1, /* continuously increasing RO */
+#ifdef __BIG_ENDIAN
+ u8 ciro:1, /* continuously increasing RO */
rro:1, /* random relative offset */
npiv_supp:1, /* NPIV supported */
port_type:1, /* N_Port/F_port */
@@ -328,7 +289,7 @@ struct fc_plogi_csp_s {
vvl_info:1, /* VVL Info included */
reserved1:1;
- u8 hg_supp:1,
+ u8 hg_supp:1,
query_dbc:1,
security:1,
sync_cap:1,
@@ -337,7 +298,7 @@ struct fc_plogi_csp_s {
cisc:1, /* continuously increasing seq count */
payload:1;
#else
- u8 reserved2:2,
+ u8 reserved2:2,
resolution:1, /* ms/ns ED_TOV resolution */
altbbcred:1, /* alternate BB_Credit */
port_type:1, /* N_Port/F_port */
@@ -345,7 +306,7 @@ struct fc_plogi_csp_s {
rro:1, /* random relative offset */
ciro:1; /* continuously increasing RO */
- u8 payload:1,
+ u8 payload:1,
cisc:1, /* continuously increasing seq count */
dh_dup_supp:1,
r_t_tov:1,
@@ -354,13 +315,10 @@ struct fc_plogi_csp_s {
query_dbc:1,
hg_supp:1;
#endif
-
- u16 rxsz; /* recieve data_field size */
-
- u16 conseq;
- u16 ro_bitmap;
-
- u32 e_d_tov;
+ __be16 rxsz; /* recieve data_field size */
+ __be16 conseq;
+ __be16 ro_bitmap;
+ __be32 e_d_tov;
};
/*
@@ -368,12 +326,11 @@ struct fc_plogi_csp_s {
* FC-PH-x. Figure 78. pg. 318.
*/
struct fc_plogi_clp_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 class_valid:1;
u32 intermix:1; /* class intermix supported if set =1.
- * valid only for class1. Reserved for
- * class2 & class3
- */
+ * valid only for class1. Reserved for
+ * class2 & class3 */
u32 reserved1:2;
u32 sequential:1;
u32 reserved2:3;
@@ -382,12 +339,10 @@ struct fc_plogi_clp_s {
u32 sequential:1;
u32 reserved1:2;
u32 intermix:1; /* class intermix supported if set =1.
- * valid only for class1. Reserved for
- * class2 & class3
- */
+ * valid only for class1. Reserved for
+ * class2 & class3 */
u32 class_valid:1;
#endif
-
u32 reserved3:24;
u32 reserved4:16;
@@ -395,7 +350,7 @@ struct fc_plogi_clp_s {
u32 reserved5:8;
u32 conseq:8;
- u32 e2e_credit:16; /* end to end credit */
+ u32 e2e_credit:16; /* end to end credit */
u32 reserved7:8;
u32 ospx:8;
@@ -409,24 +364,24 @@ struct fc_plogi_clp_s {
* PLOGI els command and reply payload
*/
struct fc_logi_s {
- struct fc_els_cmd_s els_cmd; /* ELS command code */
- struct fc_plogi_csp_s csp; /* common service params */
- wwn_t port_name;
- wwn_t node_name;
- struct fc_plogi_clp_s class1; /* class 1 service parameters */
- struct fc_plogi_clp_s class2; /* class 2 service parameters */
- struct fc_plogi_clp_s class3; /* class 3 service parameters */
- struct fc_plogi_clp_s class4; /* class 4 service parameters */
- u8 vvl[16]; /* vendor version level */
+ struct fc_els_cmd_s els_cmd; /* ELS command code */
+ struct fc_plogi_csp_s csp; /* common service params */
+ wwn_t port_name;
+ wwn_t node_name;
+ struct fc_plogi_clp_s class1; /* class 1 service parameters */
+ struct fc_plogi_clp_s class2; /* class 2 service parameters */
+ struct fc_plogi_clp_s class3; /* class 3 service parameters */
+ struct fc_plogi_clp_s class4; /* class 4 service parameters */
+ u8 vvl[16]; /* vendor version level */
};
/*
* LOGO els command payload
*/
struct fc_logo_s {
- struct fc_els_cmd_s els_cmd; /* ELS command code */
- u32 res1:8;
- u32 nport_id:24; /* N_Port identifier of source */
+ struct fc_els_cmd_s els_cmd; /* ELS command code */
+ u32 res1:8;
+ u32 nport_id:24; /* N_Port identifier of source */
wwn_t orig_port_name; /* Port name of the LOGO originator */
};
@@ -435,12 +390,12 @@ struct fc_logo_s {
*/
struct fc_adisc_s {
struct fc_els_cmd_s els_cmd; /* ELS command code */
- u32 res1:8;
- u32 orig_HA:24; /* originator hard address */
- wwn_t orig_port_name; /* originator port name */
- wwn_t orig_node_name; /* originator node name */
- u32 res2:8;
- u32 nport_id:24; /* originator NPortID */
+ u32 res1:8;
+ u32 orig_HA:24; /* originator hard address */
+ wwn_t orig_port_name; /* originator port name */
+ wwn_t orig_node_name; /* originator node name */
+ u32 res2:8;
+ u32 nport_id:24; /* originator NPortID */
};
/*
@@ -466,7 +421,7 @@ struct fc_exch_status_blk_s {
struct fc_res_s {
struct fc_els_cmd_s els_cmd; /* ELS command code */
u32 res1:8;
- u32 nport_id:24; /* N_Port identifier of source */
+ u32 nport_id:24; /* N_Port identifier of source */
u32 oxid:16;
u32 rxid:16;
u8 assoc_hdr[32];
@@ -512,8 +467,8 @@ struct fc_rec_acc_s {
u32 orig_id:24; /* N_Port id of exchange originator */
u32 res2:8;
u32 resp_id:24; /* N_Port id of exchange responder */
- u32 count; /* data transfer count */
- u32 e_stat; /* exchange status */
+ u32 count; /* data transfer count */
+ u32 e_stat; /* exchange status */
};
/*
@@ -533,7 +488,7 @@ struct fc_rsi_s {
*/
struct fc_prli_params_s {
u32 reserved:16;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 reserved1:5;
u32 rec_support:1;
u32 task_retry_id:1;
@@ -575,7 +530,7 @@ enum {
struct fc_prli_params_page_s {
u32 type:8;
u32 codext:8;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 origprocasv:1;
u32 rsppav:1;
u32 imagepair:1;
@@ -611,18 +566,14 @@ struct fc_prli_s {
struct fc_prlo_params_page_s {
u32 type:8;
u32 type_ext:8;
-#ifdef __BIGENDIAN
- u32 opa_valid:1; /* originator process associator
- * valid
- */
+#ifdef __BIG_ENDIAN
+ u32 opa_valid:1; /* originator process associator valid */
u32 rpa_valid:1; /* responder process associator valid */
u32 res1:14;
#else
u32 res1:14;
u32 rpa_valid:1; /* responder process associator valid */
- u32 opa_valid:1; /* originator process associator
- * valid
- */
+ u32 opa_valid:1; /* originator process associator valid */
#endif
u32 orig_process_assc;
u32 resp_process_assc;
@@ -647,18 +598,14 @@ struct fc_prlo_acc_params_page_s {
u32 type:8;
u32 type_ext:8;
-#ifdef __BIGENDIAN
- u32 opa_valid:1; /* originator process associator
- * valid
- */
+#ifdef __BIG_ENDIAN
+ u32 opa_valid:1; /* originator process associator valid */
u32 rpa_valid:1; /* responder process associator valid */
u32 res1:14;
#else
u32 res1:14;
u32 rpa_valid:1; /* responder process associator valid */
- u32 opa_valid:1; /* originator process associator
- * valid
- */
+ u32 opa_valid:1; /* originator process associator valid */
#endif
u32 orig_process_assc;
u32 resp_process_assc;
@@ -715,9 +662,9 @@ enum {
* LS_RJT els reply payload
*/
struct fc_ls_rjt_s {
- struct fc_els_cmd_s els_cmd; /* ELS command code */
+ struct fc_els_cmd_s els_cmd; /* ELS command code */
u32 res1:8;
- u32 reason_code:8; /* Reason code for reject */
+ u32 reason_code:8; /* Reason code for reject */
u32 reason_code_expl:8; /* Reason code explanation */
u32 vendor_unique:8; /* Vendor specific */
};
@@ -779,12 +726,12 @@ struct fc_rrq_s {
*/
struct fc_ba_acc_s {
u32 seq_id_valid:8; /* set to 0x00 for Abort Exchange */
- u32 seq_id:8; /* invalid for Abort Exchange */
+ u32 seq_id:8; /* invalid for Abort Exchange */
u32 res2:16;
- u32 ox_id:16; /* OX_ID from ABTS frame */
- u32 rx_id:16; /* RX_ID from ABTS frame */
+ u32 ox_id:16; /* OX_ID from ABTS frame */
+ u32 rx_id:16; /* RX_ID from ABTS frame */
u32 low_seq_cnt:16; /* set to 0x0000 for Abort Exchange */
- u32 high_seq_cnt:16;/* set to 0xFFFF for Abort Exchange */
+ u32 high_seq_cnt:16; /* set to 0xFFFF for Abort Exchange */
};
/*
@@ -794,17 +741,17 @@ struct fc_ba_rjt_s {
u32 res1:8; /* Reserved */
u32 reason_code:8; /* reason code for reject */
u32 reason_expl:8; /* reason code explanation */
- u32 vendor_unique:8;/* vendor unique reason code,set to 0 */
+ u32 vendor_unique:8; /* vendor unique reason code,set to 0 */
};
/*
* TPRLO logout parameter page
*/
struct fc_tprlo_params_page_s {
-u32 type:8;
-u32 type_ext:8;
+ u32 type:8;
+ u32 type_ext:8;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 opa_valid:1;
u32 rpa_valid:1;
u32 tpo_nport_valid:1;
@@ -864,16 +811,16 @@ enum fc_rscn_format {
};
struct fc_rscn_event_s {
- u32 format:2;
- u32 qualifier:4;
- u32 resvd:2;
- u32 portid:24;
+ u32 format:2;
+ u32 qualifier:4;
+ u32 resvd:2;
+ u32 portid:24;
};
struct fc_rscn_pl_s {
- u8 command;
- u8 pagelen;
- u16 payldlen;
+ u8 command;
+ u8 pagelen;
+ __be16 payldlen;
struct fc_rscn_event_s event[1];
};
@@ -887,7 +834,6 @@ struct fc_echo_s {
/*
* RNID els command
*/
-
#define RNID_NODEID_DATA_FORMAT_COMMON 0x00
#define RNID_NODEID_DATA_FORMAT_FCP3 0x08
#define RNID_NODEID_DATA_FORMAT_DISCOVERY 0xDF
@@ -920,15 +866,15 @@ struct fc_rnid_cmd_s {
*/
struct fc_rnid_common_id_data_s {
- wwn_t port_name;
+ wwn_t port_name;
wwn_t node_name;
};
struct fc_rnid_general_topology_data_s {
u32 vendor_unique[4];
- u32 asso_type;
+ __be32 asso_type;
u32 phy_port_num;
- u32 num_attached_nodes;
+ __be32 num_attached_nodes;
u32 node_mgmt:8;
u32 ip_version:8;
u32 udp_tcp_port_num:16;
@@ -980,59 +926,17 @@ enum fc_rpsc_op_speed {
RPSC_OP_SPEED_8G = 0x0800,
RPSC_OP_SPEED_16G = 0x0400,
- RPSC_OP_SPEED_NOT_EST = 0x0001, /*! speed not established */
+ RPSC_OP_SPEED_NOT_EST = 0x0001, /* speed not established */
};
struct fc_rpsc_speed_info_s {
- u16 port_speed_cap; /*! see enum fc_rpsc_speed_cap */
- u16 port_op_speed; /*! see enum fc_rpsc_op_speed */
-};
-
-enum link_e2e_beacon_subcmd {
- LINK_E2E_BEACON_ON = 1,
- LINK_E2E_BEACON_OFF = 2
-};
-
-enum beacon_type {
- BEACON_TYPE_NORMAL = 1, /*! Normal Beaconing. Green */
- BEACON_TYPE_WARN = 2, /*! Warning Beaconing. Yellow/Amber */
- BEACON_TYPE_CRITICAL = 3 /*! Critical Beaconing. Red */
-};
-
-struct link_e2e_beacon_param_s {
- u8 beacon_type; /* Beacon Type. See enum beacon_type */
- u8 beacon_frequency;
- /* Beacon frequency. Number of blinks
- * per 10 seconds
- */
- u16 beacon_duration;/* Beacon duration (in Seconds). The
- * command operation should be
- * terminated at the end of this
- * timeout value.
- *
- * Ignored if diag_sub_cmd is
- * LINK_E2E_BEACON_OFF.
- *
- * If 0, beaconing will continue till a
- * BEACON OFF request is received
- */
-};
-
-/*
- * Link E2E beacon request/good response format.
- * For LS_RJTs use struct fc_ls_rjt_s
- */
-struct link_e2e_beacon_req_s {
- u32 ls_code; /*! FC_ELS_E2E_LBEACON in requests *
- *or FC_ELS_ACC in good replies */
- u32 ls_sub_cmd; /*! See enum link_e2e_beacon_subcmd */
- struct link_e2e_beacon_param_s beacon_parm;
+ __be16 port_speed_cap; /* see enum fc_rpsc_speed_cap */
+ __be16 port_op_speed; /* see enum fc_rpsc_op_speed */
};
/*
* If RPSC request is sent to the Domain Controller, the request is for
- * all the ports within that domain (TODO - I don't think FOS implements
- * this...).
+ * all the ports within that domain.
*/
struct fc_rpsc_cmd_s {
struct fc_els_cmd_s els_cmd;
@@ -1056,9 +960,9 @@ struct fc_rpsc_acc_s {
struct fc_rpsc2_cmd_s {
struct fc_els_cmd_s els_cmd;
- u32 token;
+ __be32 token;
u16 resvd;
- u16 num_pids; /* Number of pids in the request */
+ __be16 num_pids; /* Number of pids in the request */
struct {
u32 rsvd1:8;
u32 pid:24; /* port identifier */
@@ -1072,16 +976,17 @@ enum fc_rpsc2_port_type {
RPSC2_PORT_TYPE_NPIV_PORT = 0x5f,
RPSC2_PORT_TYPE_NPORT_TRUNK = 0x6f,
};
+
/*
* RPSC2 portInfo entry structure
*/
struct fc_rpsc2_port_info_s {
- u32 pid; /* PID */
- u16 resvd1;
- u16 index; /* port number / index */
- u8 resvd2;
- u8 type; /* port type N/NL/... */
- u16 speed; /* port Operating Speed */
+ __be32 pid; /* PID */
+ u16 resvd1;
+ __be16 index; /* port number / index */
+ u8 resvd2;
+ u8 type; /* port type N/NL/... */
+ __be16 speed; /* port Operating Speed */
};
/*
@@ -1090,8 +995,8 @@ struct fc_rpsc2_port_info_s {
struct fc_rpsc2_acc_s {
u8 els_cmd;
u8 resvd;
- u16 num_pids; /* Number of pids in the request */
- struct fc_rpsc2_port_info_s port_info[1]; /* port information */
+ __be16 num_pids; /* Number of pids in the request */
+ struct fc_rpsc2_port_info_s port_info[1]; /* port information */
};
/*
@@ -1110,18 +1015,14 @@ struct fc_symname_s {
u8 symname[FC_SYMNAME_MAX];
};
-struct fc_alpabm_s {
- u8 alpa_bm[FC_ALPA_MAX / 8];
-};
-
/*
* protocol default timeout values
*/
-#define FC_ED_TOV 2
-#define FC_REC_TOV (FC_ED_TOV + 1)
-#define FC_RA_TOV 10
-#define FC_ELS_TOV (2 * FC_RA_TOV)
-#define FC_FCCT_TOV (3 * FC_RA_TOV)
+#define FC_ED_TOV 2
+#define FC_REC_TOV (FC_ED_TOV + 1)
+#define FC_RA_TOV 10
+#define FC_ELS_TOV (2 * FC_RA_TOV)
+#define FC_FCCT_TOV (3 * FC_RA_TOV)
/*
* virtual fabric related defines
@@ -1157,50 +1058,34 @@ enum {
};
/*
- * SRR FC-4 LS payload
- */
-struct fc_srr_s {
- u32 ls_cmd;
- u32 ox_id:16; /* ox-id */
- u32 rx_id:16; /* rx-id */
- u32 ro; /* relative offset */
- u32 r_ctl:8; /* R_CTL for I.U. */
- u32 res:24;
-};
-
-
-/*
* FCP_CMND definitions
*/
#define FCP_CMND_CDB_LEN 16
#define FCP_CMND_LUN_LEN 8
struct fcp_cmnd_s {
- lun_t lun; /* 64-bit LU number */
- u8 crn; /* command reference number */
-#ifdef __BIGENDIAN
- u8 resvd:1,
+ struct scsi_lun lun; /* 64-bit LU number */
+ u8 crn; /* command reference number */
+#ifdef __BIG_ENDIAN
+ u8 resvd:1,
priority:4, /* FCP-3: SAM-3 priority */
taskattr:3; /* scsi task attribute */
#else
- u8 taskattr:3, /* scsi task attribute */
+ u8 taskattr:3, /* scsi task attribute */
priority:4, /* FCP-3: SAM-3 priority */
resvd:1;
#endif
- u8 tm_flags; /* task management flags */
-#ifdef __BIGENDIAN
- u8 addl_cdb_len:6, /* additional CDB length words */
+ u8 tm_flags; /* task management flags */
+#ifdef __BIG_ENDIAN
+ u8 addl_cdb_len:6, /* additional CDB length words */
iodir:2; /* read/write FCP_DATA IUs */
#else
- u8 iodir:2, /* read/write FCP_DATA IUs */
+ u8 iodir:2, /* read/write FCP_DATA IUs */
addl_cdb_len:6; /* additional CDB length */
#endif
- scsi_cdb_t cdb;
+ struct scsi_cdb_s cdb;
- /*
- * !!! additional cdb bytes follows here!!!
- */
- u32 fcp_dl; /* bytes to be transferred */
+ __be32 fcp_dl; /* bytes to be transferred */
};
#define fcp_cmnd_cdb_len(_cmnd) ((_cmnd)->addl_cdb_len * 4 + FCP_CMND_CDB_LEN)
@@ -1210,21 +1095,10 @@ struct fcp_cmnd_s {
* struct fcp_cmnd_s .iodir field values
*/
enum fcp_iodir {
- FCP_IODIR_NONE = 0,
+ FCP_IODIR_NONE = 0,
FCP_IODIR_WRITE = 1,
- FCP_IODIR_READ = 2,
- FCP_IODIR_RW = 3,
-};
-
-/*
- * Task attribute field
- */
-enum {
- FCP_TASK_ATTR_SIMPLE = 0,
- FCP_TASK_ATTR_HOQ = 1,
- FCP_TASK_ATTR_ORDERED = 2,
- FCP_TASK_ATTR_ACA = 4,
- FCP_TASK_ATTR_UNTAGGED = 5, /* obsolete in FCP-3 */
+ FCP_IODIR_READ = 2,
+ FCP_IODIR_RW = 3,
};
/*
@@ -1239,58 +1113,40 @@ enum fcp_tm_cmnd {
};
/*
- * FCP_XFER_RDY IU defines
- */
-struct fcp_xfer_rdy_s {
- u32 data_ro;
- u32 burst_len;
- u32 reserved;
-};
-
-/*
* FCP_RSP residue flags
*/
enum fcp_residue {
- FCP_NO_RESIDUE = 0, /* no residue */
- FCP_RESID_OVER = 1, /* more data left that was not sent */
- FCP_RESID_UNDER = 2, /* less data than requested */
-};
-
-enum {
- FCP_RSPINFO_GOOD = 0,
- FCP_RSPINFO_DATALEN_MISMATCH = 1,
- FCP_RSPINFO_CMND_INVALID = 2,
- FCP_RSPINFO_ROLEN_MISMATCH = 3,
- FCP_RSPINFO_TM_NOT_SUPP = 4,
- FCP_RSPINFO_TM_FAILED = 5,
+ FCP_NO_RESIDUE = 0, /* no residue */
+ FCP_RESID_OVER = 1, /* more data left that was not sent */
+ FCP_RESID_UNDER = 2, /* less data than requested */
};
struct fcp_rspinfo_s {
u32 res0:24;
- u32 rsp_code:8; /* response code (as above) */
+ u32 rsp_code:8; /* response code (as above) */
u32 res1;
};
struct fcp_resp_s {
- u32 reserved[2]; /* 2 words reserved */
+ u32 reserved[2]; /* 2 words reserved */
u16 reserved2;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u8 reserved3:3;
u8 fcp_conf_req:1; /* FCP_CONF is requested */
u8 resid_flags:2; /* underflow/overflow */
- u8 sns_len_valid:1;/* sense len is valid */
- u8 rsp_len_valid:1;/* response len is valid */
+ u8 sns_len_valid:1; /* sense len is valid */
+ u8 rsp_len_valid:1; /* response len is valid */
#else
- u8 rsp_len_valid:1;/* response len is valid */
- u8 sns_len_valid:1;/* sense len is valid */
+ u8 rsp_len_valid:1; /* response len is valid */
+ u8 sns_len_valid:1; /* sense len is valid */
u8 resid_flags:2; /* underflow/overflow */
u8 fcp_conf_req:1; /* FCP_CONF is requested */
u8 reserved3:3;
#endif
- u8 scsi_status; /* one byte SCSI status */
- u32 residue; /* residual data bytes */
- u32 sns_len; /* length od sense info */
- u32 rsp_len; /* length of response info */
+ u8 scsi_status; /* one byte SCSI status */
+ u32 residue; /* residual data bytes */
+ u32 sns_len; /* length od sense info */
+ u32 rsp_len; /* length of response info */
};
#define fcp_snslen(__fcprsp) ((__fcprsp)->sns_len_valid ? \
@@ -1300,12 +1156,6 @@ struct fcp_resp_s {
#define fcp_rspinfo(__fcprsp) ((struct fcp_rspinfo_s *)((__fcprsp) + 1))
#define fcp_snsinfo(__fcprsp) (((u8 *)fcp_rspinfo(__fcprsp)) + \
fcp_rsplen(__fcprsp))
-
-struct fcp_cmnd_fr_s {
- struct fchs_s fchs;
- struct fcp_cmnd_s fcp;
-};
-
/*
* CT
*/
@@ -1379,7 +1229,7 @@ enum {
CT_RSN_LOGICAL_BUSY = 0x05,
CT_RSN_PROTO_ERR = 0x07,
CT_RSN_UNABLE_TO_PERF = 0x09,
- CT_RSN_NOT_SUPP = 0x0B,
+ CT_RSN_NOT_SUPP = 0x0B,
CT_RSN_SERVER_NOT_AVBL = 0x0D,
CT_RSN_SESSION_COULD_NOT_BE_ESTBD = 0x0E,
CT_RSN_VENDOR_SPECIFIC = 0xFF,
@@ -1419,10 +1269,10 @@ enum {
* defintions for the explanation code for all servers
*/
enum {
- CT_EXP_AUTH_EXCEPTION = 0xF1,
- CT_EXP_DB_FULL = 0xF2,
- CT_EXP_DB_EMPTY = 0xF3,
- CT_EXP_PROCESSING_REQ = 0xF4,
+ CT_EXP_AUTH_EXCEPTION = 0xF1,
+ CT_EXP_DB_FULL = 0xF2,
+ CT_EXP_DB_EMPTY = 0xF3,
+ CT_EXP_PROCESSING_REQ = 0xF4,
CT_EXP_UNABLE_TO_VERIFY_CONN = 0xF5,
CT_EXP_DEVICES_NOT_IN_CMN_ZONE = 0xF6
};
@@ -1446,7 +1296,7 @@ enum {
GS_RFF_ID = 0x021F, /* Register FC4 Feature */
};
-struct fcgs_id_req_s{
+struct fcgs_id_req_s {
u32 rsvd:8;
u32 dap:24; /* port identifier */
};
@@ -1460,7 +1310,7 @@ struct fcgs_gidpn_req_s {
struct fcgs_gidpn_resp_s {
u32 rsvd:8;
- u32 dap:24; /* port identifier */
+ u32 dap:24; /* port identifier */
};
/*
@@ -1469,22 +1319,21 @@ struct fcgs_gidpn_resp_s {
struct fcgs_rftid_req_s {
u32 rsvd:8;
u32 dap:24; /* port identifier */
- u32 fc4_type[8]; /* fc4 types */
+ __be32 fc4_type[8]; /* fc4 types */
};
/*
* RFF_ID : Register FC4 features.
*/
-
#define FC_GS_FCP_FC4_FEATURE_INITIATOR 0x02
#define FC_GS_FCP_FC4_FEATURE_TARGET 0x01
struct fcgs_rffid_req_s {
- u32 rsvd:8;
- u32 dap:24; /* port identifier */
- u32 rsvd1:16;
- u32 fc4ftr_bits:8; /* fc4 feature bits */
- u32 fc4_type:8; /* corresponding FC4 Type */
+ u32 rsvd:8;
+ u32 dap:24; /* port identifier */
+ u32 rsvd1:16;
+ u32 fc4ftr_bits:8; /* fc4 feature bits */
+ u32 fc4_type:8; /* corresponding FC4 Type */
};
/*
@@ -1495,16 +1344,16 @@ struct fcgs_gidft_req_s {
u8 domain_id; /* domain, 0 - all fabric */
u8 area_id; /* area, 0 - whole domain */
u8 fc4_type; /* FC_TYPE_FCP for SCSI devices */
-}; /* GID_FT Request */
+};
/*
* GID_FT Response
*/
struct fcgs_gidft_resp_s {
- u8 last:1; /* last port identifier flag */
- u8 reserved:7;
- u32 pid:24; /* port identifier */
-}; /* GID_FT Response */
+ u8 last:1; /* last port identifier flag */
+ u8 reserved:7;
+ u32 pid:24; /* port identifier */
+};
/*
* RSPN_ID
@@ -1512,8 +1361,8 @@ struct fcgs_gidft_resp_s {
struct fcgs_rspnid_req_s {
u32 rsvd:8;
u32 dap:24; /* port identifier */
- u8 spn_len; /* symbolic port name length */
- u8 spn[256]; /* symbolic port name */
+ u8 spn_len; /* symbolic port name length */
+ u8 spn[256]; /* symbolic port name */
};
/*
@@ -1522,7 +1371,7 @@ struct fcgs_rspnid_req_s {
struct fcgs_rpnid_req_s {
u32 rsvd:8;
u32 port_id:24;
- wwn_t port_name;
+ wwn_t port_name;
};
/*
@@ -1531,7 +1380,7 @@ struct fcgs_rpnid_req_s {
struct fcgs_rnnid_req_s {
u32 rsvd:8;
u32 port_id:24;
- wwn_t node_name;
+ wwn_t node_name;
};
/*
@@ -1565,8 +1414,8 @@ struct fcgs_ganxt_req_s {
* GA_NXT Response
*/
struct fcgs_ganxt_rsp_s {
- u32 port_type:8; /* Port Type */
- u32 port_id:24; /* Port Identifier */
+ u32 port_type:8; /* Port Type */
+ u32 port_id:24; /* Port Identifier */
wwn_t port_name; /* Port Name */
u8 spn_len; /* Length of Symbolic Port Name */
char spn[255]; /* Symbolic Port Name */
@@ -1575,19 +1424,14 @@ struct fcgs_ganxt_rsp_s {
char snn[255]; /* Symbolic Node Name */
u8 ipa[8]; /* Initial Process Associator */
u8 ip[16]; /* IP Address */
- u32 cos; /* Class of Service */
- u32 fc4types[8]; /* FC-4 TYPEs */
- wwn_t fabric_port_name;
- /* Fabric Port Name */
- u32 rsvd:8; /* Reserved */
- u32 hard_addr:24; /* Hard Address */
+ u32 cos; /* Class of Service */
+ u32 fc4types[8]; /* FC-4 TYPEs */
+ wwn_t fabric_port_name; /* Fabric Port Name */
+ u32 rsvd:8; /* Reserved */
+ u32 hard_addr:24; /* Hard Address */
};
/*
- * Fabric Config Server
- */
-
-/*
* Command codes for Fabric Configuration Server
*/
enum {
@@ -1598,159 +1442,9 @@ enum {
};
/*
- * Source or Destination Port Tags.
- */
-enum {
- GS_FTRACE_TAG_NPORT_ID = 1,
- GS_FTRACE_TAG_NPORT_NAME = 2,
-};
-
-/*
-* Port Value : Could be a Port id or wwn
- */
-union fcgs_port_val_u {
- u32 nport_id;
- wwn_t nport_wwn;
-};
-
-#define GS_FTRACE_MAX_HOP_COUNT 20
-#define GS_FTRACE_REVISION 1
-
-/*
- * Ftrace Related Structures.
- */
-
-/*
- * STR (Switch Trace) Reject Reason Codes. From FC-SW.
- */
-enum {
- GS_FTRACE_STR_CMD_COMPLETED_SUCC = 0,
- GS_FTRACE_STR_CMD_NOT_SUPP_IN_NEXT_SWITCH,
- GS_FTRACE_STR_NO_RESP_FROM_NEXT_SWITCH,
- GS_FTRACE_STR_MAX_HOP_CNT_REACHED,
- GS_FTRACE_STR_SRC_PORT_NOT_FOUND,
- GS_FTRACE_STR_DST_PORT_NOT_FOUND,
- GS_FTRACE_STR_DEVICES_NOT_IN_COMMON_ZONE,
- GS_FTRACE_STR_NO_ROUTE_BW_PORTS,
- GS_FTRACE_STR_NO_ADDL_EXPLN,
- GS_FTRACE_STR_FABRIC_BUSY,
- GS_FTRACE_STR_FABRIC_BUILD_IN_PROGRESS,
- GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_START = 0xf0,
- GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_END = 0xff,
-};
-
-/*
- * Ftrace Request
- */
-struct fcgs_ftrace_req_s {
- u32 revision;
- u16 src_port_tag; /* Source Port tag */
- u16 src_port_len; /* Source Port len */
- union fcgs_port_val_u src_port_val; /* Source Port value */
- u16 dst_port_tag; /* Destination Port tag */
- u16 dst_port_len; /* Destination Port len */
- union fcgs_port_val_u dst_port_val; /* Destination Port value */
- u32 token;
- u8 vendor_id[8]; /* T10 Vendor Identifier */
- u8 vendor_info[8]; /* Vendor specific Info */
- u32 max_hop_cnt; /* Max Hop Count */
-};
-
-/*
- * Path info structure
- */
-struct fcgs_ftrace_path_info_s {
- wwn_t switch_name; /* Switch WWN */
- u32 domain_id;
- wwn_t ingress_port_name; /* Ingress ports wwn */
- u32 ingress_phys_port_num; /* Ingress ports physical port
- * number
- */
- wwn_t egress_port_name; /* Ingress ports wwn */
- u32 egress_phys_port_num; /* Ingress ports physical port
- * number
- */
-};
-
-/*
- * Ftrace Acc Response
- */
-struct fcgs_ftrace_resp_s {
- u32 revision;
- u32 token;
- u8 vendor_id[8]; /* T10 Vendor Identifier */
- u8 vendor_info[8]; /* Vendor specific Info */
- u32 str_rej_reason_code; /* STR Reject Reason Code */
- u32 num_path_info_entries; /* No. of path info entries */
- /*
- * path info entry/entries.
- */
- struct fcgs_ftrace_path_info_s path_info[1];
-
-};
-
-/*
-* Fabric Config Server : FCPing
- */
-
-/*
- * FC Ping Request
- */
-struct fcgs_fcping_req_s {
- u32 revision;
- u16 port_tag;
- u16 port_len; /* Port len */
- union fcgs_port_val_u port_val; /* Port value */
- u32 token;
-};
-
-/*
- * FC Ping Response
- */
-struct fcgs_fcping_resp_s {
- u32 token;
-};
-
-/*
- * Command codes for zone server query.
- */
-enum {
- ZS_GZME = 0x0124, /* Get zone member extended */
-};
-
-/*
- * ZS GZME request
- */
-#define ZS_GZME_ZNAMELEN 32
-struct zs_gzme_req_s {
- u8 znamelen;
- u8 rsvd[3];
- u8 zname[ZS_GZME_ZNAMELEN];
-};
-
-enum zs_mbr_type {
- ZS_MBR_TYPE_PWWN = 1,
- ZS_MBR_TYPE_DOMPORT = 2,
- ZS_MBR_TYPE_PORTID = 3,
- ZS_MBR_TYPE_NWWN = 4,
-};
-
-struct zs_mbr_wwn_s {
- u8 mbr_type;
- u8 rsvd[3];
- wwn_t wwn;
-};
-
-struct zs_query_resp_s {
- u32 nmbrs; /* number of zone members */
- struct zs_mbr_wwn_s mbr[1];
-};
-
-/*
* GMAL Command ( Get ( interconnect Element) Management Address List)
* To retrieve the IP Address of a Switch.
*/
-
#define CT_GMAL_RESP_PREFIX_TELNET "telnet://"
#define CT_GMAL_RESP_PREFIX_HTTP "http://"
@@ -1764,7 +1458,7 @@ struct fcgs_req_s {
/* Accept Response to GMAL */
struct fcgs_gmal_resp_s {
- u32 ms_len; /* Num of entries */
+ __be32 ms_len; /* Num of entries */
u8 ms_ma[256];
};
@@ -1775,9 +1469,6 @@ struct fcgs_gmal_entry_s {
};
/*
- * FDMI
- */
-/*
* FDMI Command Codes
*/
#define FDMI_GRHL 0x0100
@@ -1856,8 +1547,8 @@ enum fdmi_port_attribute_type {
* FDMI attribute
*/
struct fdmi_attr_s {
- u16 type;
- u16 len;
+ __be16 type;
+ __be16 len;
u8 value[1];
};
@@ -1865,7 +1556,7 @@ struct fdmi_attr_s {
* HBA Attribute Block
*/
struct fdmi_hba_attr_s {
- u32 attr_count; /* # of attributes */
+ __be32 attr_count; /* # of attributes */
struct fdmi_attr_s hba_attr; /* n attributes */
};
@@ -1873,15 +1564,15 @@ struct fdmi_hba_attr_s {
* Registered Port List
*/
struct fdmi_port_list_s {
- u32 num_ports; /* number Of Port Entries */
- wwn_t port_entry; /* one or more */
+ __be32 num_ports; /* number Of Port Entries */
+ wwn_t port_entry; /* one or more */
};
/*
* Port Attribute Block
*/
struct fdmi_port_attr_s {
- u32 attr_count; /* # of attributes */
+ __be32 attr_count; /* # of attributes */
struct fdmi_attr_s port_attr; /* n attributes */
};
@@ -1889,7 +1580,7 @@ struct fdmi_port_attr_s {
* FDMI Register HBA Attributes
*/
struct fdmi_rhba_s {
- wwn_t hba_id; /* HBA Identifier */
+ wwn_t hba_id; /* HBA Identifier */
struct fdmi_port_list_s port_list; /* Registered Port List */
struct fdmi_hba_attr_s hba_attr_blk; /* HBA attribute block */
};
@@ -1898,8 +1589,8 @@ struct fdmi_rhba_s {
* FDMI Register Port
*/
struct fdmi_rprt_s {
- wwn_t hba_id; /* HBA Identifier */
- wwn_t port_name; /* Port wwn */
+ wwn_t hba_id; /* HBA Identifier */
+ wwn_t port_name; /* Port wwn */
struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
};
@@ -1907,7 +1598,7 @@ struct fdmi_rprt_s {
* FDMI Register Port Attributes
*/
struct fdmi_rpa_s {
- wwn_t port_name; /* port wwn */
+ wwn_t port_name; /* port wwn */
struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
};
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c
index 9c725314b513..b7e253451654 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.c
+++ b/drivers/scsi/bfa/bfa_fcbuild.c
@@ -18,16 +18,16 @@
* fcbuild.c - FC link service frame building and parsing routines
*/
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#include "bfa_fcbuild.h"
/*
* static build functions
*/
static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
- u16 ox_id);
+ __be16 ox_id);
static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
- u16 ox_id);
+ __be16 ox_id);
static struct fchs_s fc_els_req_tmpl;
static struct fchs_s fc_els_rsp_tmpl;
static struct fchs_s fc_bls_req_tmpl;
@@ -48,7 +48,7 @@ fcbuild_init(void)
fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
fc_els_req_tmpl.type = FC_TYPE_ELS;
fc_els_req_tmpl.f_ctl =
- bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
+ bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
FCTL_SI_XFER);
fc_els_req_tmpl.rx_id = FC_RXID_ANY;
@@ -59,7 +59,7 @@ fcbuild_init(void)
fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
fc_els_rsp_tmpl.type = FC_TYPE_ELS;
fc_els_rsp_tmpl.f_ctl =
- bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
+ bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
FCTL_END_SEQ | FCTL_SI_XFER);
fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
@@ -68,7 +68,7 @@ fcbuild_init(void)
*/
fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
fc_bls_req_tmpl.type = FC_TYPE_BLS;
- fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
+ fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
/*
@@ -78,7 +78,7 @@ fcbuild_init(void)
fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
fc_bls_rsp_tmpl.f_ctl =
- bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
+ bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
FCTL_END_SEQ | FCTL_SI_XFER);
fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
@@ -129,7 +129,7 @@ fcbuild_init(void)
fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
fcp_fchs_tmpl.type = FC_TYPE_FCP;
fcp_fchs_tmpl.f_ctl =
- bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
+ bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
fcp_fchs_tmpl.seq_id = 1;
fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
}
@@ -143,7 +143,7 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
fchs->type = FC_TYPE_SERVICES;
fchs->f_ctl =
- bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
+ bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
FCTL_SI_XFER);
fchs->rx_id = FC_RXID_ANY;
fchs->d_id = (d_id);
@@ -157,7 +157,7 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
}
void
-fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
{
memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
fchs->d_id = (d_id);
@@ -166,7 +166,7 @@ fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
}
static void
-fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
{
memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
fchs->d_id = d_id;
@@ -196,7 +196,7 @@ fc_els_rsp_parse(struct fchs_s *fchs, int len)
}
static void
-fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
{
memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
fchs->d_id = d_id;
@@ -206,7 +206,7 @@ fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
static u16
fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
- u16 ox_id, wwn_t port_name, wwn_t node_name,
+ __be16 ox_id, wwn_t port_name, wwn_t node_name,
u16 pdu_size, u8 els_code)
{
struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
@@ -232,8 +232,8 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
u8 set_npiv, u8 set_auth, u16 local_bb_credits)
{
- u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
- u32 *vvl_info;
+ u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
+ __be32 *vvl_info;
memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
@@ -267,7 +267,7 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
u16
fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
- u16 ox_id, wwn_t port_name, wwn_t node_name,
+ __be16 ox_id, wwn_t port_name, wwn_t node_name,
u16 pdu_size, u16 local_bb_credits)
{
u32 d_id = 0;
@@ -289,7 +289,7 @@ u16
fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
{
- u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
+ u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
@@ -392,7 +392,7 @@ fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
u16
fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
- u16 ox_id, enum bfa_lport_role role)
+ __be16 ox_id, enum bfa_lport_role role)
{
struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
@@ -456,9 +456,9 @@ fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
return sizeof(struct fc_logo_s);
}
-static u16
+static u16
fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
- u32 s_id, u16 ox_id, wwn_t port_name,
+ u32 s_id, __be16 ox_id, wwn_t port_name,
wwn_t node_name, u8 els_code)
{
memset(adisc, '\0', sizeof(struct fc_adisc_s));
@@ -480,7 +480,7 @@ fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
u16
fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
- u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name)
+ u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
{
return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
node_name, FC_ELS_ADISC);
@@ -488,7 +488,7 @@ fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
u16
fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
- u32 s_id, u16 ox_id, wwn_t port_name,
+ u32 s_id, __be16 ox_id, wwn_t port_name,
wwn_t node_name)
{
return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
@@ -592,7 +592,7 @@ fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
u16
fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
- u16 ox_id)
+ __be16 ox_id)
{
struct fc_els_cmd_s *acc = pld;
@@ -606,7 +606,7 @@ fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
u16
fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
- u32 s_id, u16 ox_id, u8 reason_code,
+ u32 s_id, __be16 ox_id, u8 reason_code,
u8 reason_code_expl)
{
fc_els_rsp_build(fchs, d_id, s_id, ox_id);
@@ -622,7 +622,7 @@ fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
u16
fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
- u32 s_id, u16 ox_id, u16 rx_id)
+ u32 s_id, __be16 ox_id, u16 rx_id)
{
fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
@@ -638,7 +638,7 @@ fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
u16
fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
- u32 s_id, u16 ox_id)
+ u32 s_id, __be16 ox_id)
{
fc_els_rsp_build(fchs, d_id, s_id, ox_id);
memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
@@ -666,7 +666,7 @@ fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
u16
fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
- u32 d_id, u32 s_id, u16 ox_id, int num_pages)
+ u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
{
int page;
@@ -690,7 +690,7 @@ fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
u16
fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
- u32 s_id, u16 ox_id, int num_pages)
+ u32 s_id, __be16 ox_id, int num_pages)
{
int page;
@@ -728,7 +728,7 @@ fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
u16
fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
- u32 s_id, u16 ox_id, u32 data_format,
+ u32 s_id, __be16 ox_id, u32 data_format,
struct fc_rnid_common_id_data_s *common_id_data,
struct fc_rnid_general_topology_data_s *gen_topo_data)
{
@@ -770,10 +770,10 @@ u16
fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
u32 s_id, u32 *pid_list, u16 npids)
{
- u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id));
+ u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
int i = 0;
- fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0);
+ fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
@@ -788,7 +788,7 @@ fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
u16
fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
- u32 d_id, u32 s_id, u16 ox_id,
+ u32 d_id, u32 s_id, __be16 ox_id,
struct fc_rpsc_speed_info_s *oper_speed)
{
memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
@@ -807,11 +807,6 @@ fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
return sizeof(struct fc_rpsc_acc_s);
}
-/*
- * TBD -
- * . get rid of unnecessary memsets
- */
-
u16
fc_logo_rsp_parse(struct fchs_s *fchs, int len)
{
@@ -995,7 +990,7 @@ fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
}
u16
-fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
+fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
u32 reason_code, u32 reason_expl)
{
struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
@@ -1045,7 +1040,7 @@ fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
@@ -1061,7 +1056,7 @@ fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
@@ -1077,7 +1072,7 @@ fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
@@ -1104,7 +1099,7 @@ u16
fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
u8 set_br_reg, u32 s_id, u16 ox_id)
{
- u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
+ u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
fc_els_req_build(fchs, d_id, s_id, ox_id);
@@ -1121,7 +1116,7 @@ u16
fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
u32 s_id, u16 ox_id)
{
- u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
+ u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
u16 payldlen;
fc_els_req_build(fchs, d_id, s_id, ox_id);
@@ -1143,7 +1138,7 @@ fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
- u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
u8 index;
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
@@ -1167,7 +1162,7 @@ fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
@@ -1187,7 +1182,7 @@ fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
@@ -1209,7 +1204,7 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rspnid_req_s *rspnid =
(struct fcgs_rspnid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
@@ -1229,7 +1224,7 @@ fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
@@ -1249,7 +1244,7 @@ fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
@@ -1267,7 +1262,7 @@ fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
@@ -1286,7 +1281,7 @@ fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rcsid_req_s *rcsid =
(struct fcgs_rcsid_req_s *) (cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
@@ -1304,7 +1299,7 @@ fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
@@ -1321,7 +1316,7 @@ fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
@@ -1341,7 +1336,7 @@ fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
- u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+ u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
@@ -1356,7 +1351,7 @@ void
fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
{
u8 index;
- u32 *ptr = (u32 *) bit_mask;
+ __be32 *ptr = (__be32 *) bit_mask;
u32 type_value;
/*
@@ -1377,7 +1372,7 @@ fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+ u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
@@ -1397,7 +1392,7 @@ fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
{
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
- u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+ u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
fc_gs_fchdr_build(fchs, d_id, s_id, 0);
fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h
index 73abd02e53cc..ece51ec7620b 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.h
+++ b/drivers/scsi/bfa/bfa_fcbuild.h
@@ -21,7 +21,7 @@
#ifndef __FCBUILD_H__
#define __FCBUILD_H__
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#include "bfa_fc.h"
#include "bfa_defs_fcs.h"
@@ -138,7 +138,7 @@ u16 fc_fdisc_build(struct fchs_s *buf, struct fc_logi_s *flogi, u32 s_id,
u16 pdu_size);
u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
- u32 s_id, u16 ox_id,
+ u32 s_id, __be16 ox_id,
wwn_t port_name, wwn_t node_name,
u16 pdu_size,
u16 local_bb_credits);
@@ -186,7 +186,7 @@ u16 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
u16 pdu_size);
u16 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
- u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name,
+ u32 d_id, u32 s_id, __be16 ox_id, wwn_t port_name,
wwn_t node_name);
enum fc_parse_status fc_adisc_parse(struct fchs_s *fchs, void *pld,
@@ -196,20 +196,20 @@ enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len,
wwn_t port_name, wwn_t node_name);
u16 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
- u32 d_id, u32 s_id, u16 ox_id,
+ u32 d_id, u32 s_id, __be16 ox_id,
wwn_t port_name, wwn_t node_name);
u16 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt,
- u32 d_id, u32 s_id, u16 ox_id,
+ u32 d_id, u32 s_id, __be16 ox_id,
u8 reason_code, u8 reason_code_expl);
u16 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
- u32 d_id, u32 s_id, u16 ox_id);
+ u32 d_id, u32 s_id, __be16 ox_id);
u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id,
u32 s_id, u16 ox_id);
enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len);
u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
- u32 s_id, u16 ox_id,
+ u32 s_id, __be16 ox_id,
enum bfa_lport_role role);
u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
@@ -218,7 +218,7 @@ u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
u16 fc_rnid_acc_build(struct fchs_s *fchs,
struct fc_rnid_acc_s *rnid_acc, u32 d_id, u32 s_id,
- u16 ox_id, u32 data_format,
+ __be16 ox_id, u32 data_format,
struct fc_rnid_common_id_data_s *common_id_data,
struct fc_rnid_general_topology_data_s *gen_topo_data);
@@ -228,7 +228,7 @@ u16 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc,
u32 d_id, u32 s_id, u16 ox_id);
u16 fc_rpsc_acc_build(struct fchs_s *fchs,
struct fc_rpsc_acc_s *rpsc_acc, u32 d_id, u32 s_id,
- u16 ox_id, struct fc_rpsc_speed_info_s *oper_speed);
+ __be16 ox_id, struct fc_rpsc_speed_info_s *oper_speed);
u16 fc_gid_ft_build(struct fchs_s *fchs, void *pld, u32 s_id,
u8 fc4_type);
@@ -251,7 +251,7 @@ u16 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id,
u32 s_id, u16 ox_id, wwn_t port_name);
u16 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
- u32 s_id, u16 ox_id);
+ u32 s_id, __be16 ox_id);
u16 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
u16 cmd_code);
@@ -261,7 +261,7 @@ u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn);
void fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask);
void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
- u16 ox_id);
+ __be16 ox_id);
enum fc_parse_status fc_els_rsp_parse(struct fchs_s *fchs, int len);
@@ -274,15 +274,15 @@ enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name,
wwn_t port_name);
u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
- u32 s_id, u16 ox_id, u16 rx_id);
+ u32 s_id, __be16 ox_id, u16 rx_id);
int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code);
u16 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
- u32 d_id, u32 s_id, u16 ox_id, int num_pages);
+ u32 d_id, u32 s_id, __be16 ox_id, int num_pages);
u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
- u32 d_id, u32 s_id, u16 ox_id, int num_pages);
+ u32 d_id, u32 s_id, __be16 ox_id, int num_pages);
u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len);
@@ -304,7 +304,7 @@ u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len);
u16 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
- u16 ox_id, u32 reason_code, u32 reason_expl);
+ __be16 ox_id, u32 reason_code, u32 reason_expl);
u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
u32 port_id);
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 135c4427801c..9c410b21db6d 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -15,17 +15,12 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_modules.h"
-#include "bfa_cb_ioim.h"
BFA_TRC_FILE(HAL, FCPIM);
BFA_MODULE(fcpim);
-
-#define bfa_fcpim_add_iostats(__l, __r, __stats) \
- (__l->__stats += __r->__stats)
-
-
/*
* BFA ITNIM Related definitions
*/
@@ -37,12 +32,12 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
#define bfa_fcpim_additn(__itnim) \
list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
#define bfa_fcpim_delitn(__itnim) do { \
- bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \
+ WARN_ON(!bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \
bfa_itnim_update_del_itn_stats(__itnim); \
list_del(&(__itnim)->qe); \
- bfa_assert(list_empty(&(__itnim)->io_q)); \
- bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \
- bfa_assert(list_empty(&(__itnim)->pending_q)); \
+ WARN_ON(!list_empty(&(__itnim)->io_q)); \
+ WARN_ON(!list_empty(&(__itnim)->io_cleanup_q)); \
+ WARN_ON(!list_empty(&(__itnim)->pending_q)); \
} while (0)
#define bfa_itnim_online_cb(__itnim) do { \
@@ -73,10 +68,8 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
} while (0)
/*
- * bfa_itnim_sm BFA itnim state machine
+ * itnim state machine event
*/
-
-
enum bfa_itnim_event {
BFA_ITNIM_SM_CREATE = 1, /* itnim is created */
BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */
@@ -107,9 +100,6 @@ enum bfa_itnim_event {
if ((__fcpim)->profile_start) \
(__fcpim)->profile_start(__ioim); \
} while (0)
-/*
- * hal_ioim_sm
- */
/*
* IO state machine events
@@ -221,8 +211,7 @@ static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
* forward declaration for BFA IOIM functions
*/
static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
-static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim);
-static void bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim);
+static bfa_boolean_t bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim);
static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
@@ -232,7 +221,6 @@ static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
-
/*
* forward declaration of BFA IO state machine
*/
@@ -260,14 +248,13 @@ static void bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
enum bfa_ioim_event event);
static void bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
enum bfa_ioim_event event);
-
/*
* forward declaration for BFA TSKIM functions
*/
static void __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
static void __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
- lun_t lun);
+ struct scsi_lun lun);
static void bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
static void bfa_tskim_cleanp_comp(void *tskim_cbarg);
static void bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
@@ -275,7 +262,6 @@ static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
-
/*
* forward declaration of BFA TSKIM state machine
*/
@@ -293,13 +279,12 @@ static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
enum bfa_tskim_event event);
static void bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
enum bfa_tskim_event event);
-
/*
- * hal_fcpim_mod BFA FCP Initiator Mode module
+ * BFA FCP Initiator Mode module
*/
/*
- * Compute and return memory needed by FCP(im) module.
+ * Compute and return memory needed by FCP(im) module.
*/
static void
bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
@@ -357,10 +342,6 @@ bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
static void
bfa_fcpim_detach(struct bfa_s *bfa)
{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
- bfa_ioim_detach(fcpim);
- bfa_tskim_detach(fcpim);
}
static void
@@ -387,56 +368,6 @@ bfa_fcpim_iocdisable(struct bfa_s *bfa)
}
void
-bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
- struct bfa_itnim_iostats_s *rstats)
-{
- bfa_fcpim_add_iostats(lstats, rstats, total_ios);
- bfa_fcpim_add_iostats(lstats, rstats, qresumes);
- bfa_fcpim_add_iostats(lstats, rstats, no_iotags);
- bfa_fcpim_add_iostats(lstats, rstats, io_aborts);
- bfa_fcpim_add_iostats(lstats, rstats, no_tskims);
- bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok);
- bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun);
- bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun);
- bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted);
- bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts);
- bfa_fcpim_add_iostats(lstats, rstats, iocom_utags);
- bfa_fcpim_add_iostats(lstats, rstats, io_cleanups);
- bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts);
- bfa_fcpim_add_iostats(lstats, rstats, onlines);
- bfa_fcpim_add_iostats(lstats, rstats, offlines);
- bfa_fcpim_add_iostats(lstats, rstats, creates);
- bfa_fcpim_add_iostats(lstats, rstats, deletes);
- bfa_fcpim_add_iostats(lstats, rstats, create_comps);
- bfa_fcpim_add_iostats(lstats, rstats, delete_comps);
- bfa_fcpim_add_iostats(lstats, rstats, sler_events);
- bfa_fcpim_add_iostats(lstats, rstats, fw_create);
- bfa_fcpim_add_iostats(lstats, rstats, fw_delete);
- bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled);
- bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps);
- bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds);
- bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps);
- bfa_fcpim_add_iostats(lstats, rstats, tm_success);
- bfa_fcpim_add_iostats(lstats, rstats, tm_failures);
- bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps);
- bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes);
- bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns);
- bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups);
- bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps);
- bfa_fcpim_add_iostats(lstats, rstats, io_comps);
- bfa_fcpim_add_iostats(lstats, rstats, input_reqs);
- bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
- bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
- bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
-}
-
-void
bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
@@ -454,128 +385,6 @@ bfa_fcpim_path_tov_get(struct bfa_s *bfa)
return fcpim->path_tov / 1000;
}
-bfa_status_t
-bfa_fcpim_port_iostats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *stats,
- u8 lp_tag)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- struct list_head *qe, *qen;
- struct bfa_itnim_s *itnim;
-
- /* accumulate IO stats from itnim */
- memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
- list_for_each_safe(qe, qen, &fcpim->itnim_q) {
- itnim = (struct bfa_itnim_s *) qe;
- if (itnim->rport->rport_info.lp_tag != lp_tag)
- continue;
- bfa_fcpim_add_stats(stats, &(itnim->stats));
- }
- return BFA_STATUS_OK;
-}
-bfa_status_t
-bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *modstats)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- struct list_head *qe, *qen;
- struct bfa_itnim_s *itnim;
-
- /* accumulate IO stats from itnim */
- memset(modstats, 0, sizeof(struct bfa_itnim_iostats_s));
- list_for_each_safe(qe, qen, &fcpim->itnim_q) {
- itnim = (struct bfa_itnim_s *) qe;
- bfa_fcpim_add_stats(modstats, &(itnim->stats));
- }
- return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_fcpim_get_del_itn_stats(struct bfa_s *bfa,
- struct bfa_fcpim_del_itn_stats_s *modstats)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
- *modstats = fcpim->del_itn_stats;
-
- return BFA_STATUS_OK;
-}
-
-
-bfa_status_t
-bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
-{
- struct bfa_itnim_s *itnim;
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- struct list_head *qe, *qen;
-
- /* accumulate IO stats from itnim */
- list_for_each_safe(qe, qen, &fcpim->itnim_q) {
- itnim = (struct bfa_itnim_s *) qe;
- bfa_itnim_clear_stats(itnim);
- }
- fcpim->io_profile = BFA_TRUE;
- fcpim->io_profile_start_time = time;
- fcpim->profile_comp = bfa_ioim_profile_comp;
- fcpim->profile_start = bfa_ioim_profile_start;
-
- return BFA_STATUS_OK;
-}
-bfa_status_t
-bfa_fcpim_profile_off(struct bfa_s *bfa)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- fcpim->io_profile = BFA_FALSE;
- fcpim->io_profile_start_time = 0;
- fcpim->profile_comp = NULL;
- fcpim->profile_start = NULL;
- return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_fcpim_port_clear_iostats(struct bfa_s *bfa, u8 lp_tag)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- struct list_head *qe, *qen;
- struct bfa_itnim_s *itnim;
-
- /* clear IO stats from all active itnims */
- list_for_each_safe(qe, qen, &fcpim->itnim_q) {
- itnim = (struct bfa_itnim_s *) qe;
- if (itnim->rport->rport_info.lp_tag != lp_tag)
- continue;
- bfa_itnim_clear_stats(itnim);
- }
- return BFA_STATUS_OK;
-
-}
-
-bfa_status_t
-bfa_fcpim_clr_modstats(struct bfa_s *bfa)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- struct list_head *qe, *qen;
- struct bfa_itnim_s *itnim;
-
- /* clear IO stats from all active itnims */
- list_for_each_safe(qe, qen, &fcpim->itnim_q) {
- itnim = (struct bfa_itnim_s *) qe;
- bfa_itnim_clear_stats(itnim);
- }
- memset(&fcpim->del_itn_stats, 0,
- sizeof(struct bfa_fcpim_del_itn_stats_s));
-
- return BFA_STATUS_OK;
-}
-
-void
-bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
- bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
-
- fcpim->q_depth = q_depth;
-}
-
u16
bfa_fcpim_qdepth_get(struct bfa_s *bfa)
{
@@ -584,32 +393,12 @@ bfa_fcpim_qdepth_get(struct bfa_s *bfa)
return fcpim->q_depth;
}
-void
-bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
-{
- bfa_boolean_t ioredirect;
-
- /*
- * IO redirection is turned off when QoS is enabled and vice versa
- */
- ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
-}
-
-void
-bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
- fcpim->ioredirect = state;
-}
-
-
-
/*
* BFA ITNIM module state machine functions
*/
/*
- * Beginning/unallocated state - no events expected.
+ * Beginning/unallocated state - no events expected.
*/
static void
bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -630,7 +419,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
}
/*
- * Beginning state, only online event expected.
+ * Beginning state, only online event expected.
*/
static void
bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -733,7 +522,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
}
/*
- * Waiting for itnim create response from firmware, a delete is pending.
+ * Waiting for itnim create response from firmware, a delete is pending.
*/
static void
bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
@@ -761,7 +550,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
}
/*
- * Online state - normal parking state.
+ * Online state - normal parking state.
*/
static void
bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -803,7 +592,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
}
/*
- * Second level error recovery need.
+ * Second level error recovery need.
*/
static void
bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -834,7 +623,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
}
/*
- * Going offline. Waiting for active IO cleanup.
+ * Going offline. Waiting for active IO cleanup.
*/
static void
bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
@@ -871,7 +660,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
}
/*
- * Deleting itnim. Waiting for active IO cleanup.
+ * Deleting itnim. Waiting for active IO cleanup.
*/
static void
bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
@@ -956,7 +745,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
}
/*
- * Offline state.
+ * Offline state.
*/
static void
bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -987,9 +776,6 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
}
}
-/*
- * IOC h/w failed state.
- */
static void
bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
enum bfa_itnim_event event)
@@ -1024,7 +810,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
}
/*
- * Itnim is deleted, waiting for firmware response to delete.
+ * Itnim is deleted, waiting for firmware response to delete.
*/
static void
bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -1069,7 +855,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
}
/*
- * Initiate cleanup of all IOs on an IOC failure.
+ * Initiate cleanup of all IOs on an IOC failure.
*/
static void
bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
@@ -1103,7 +889,7 @@ bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
}
/*
- * IO cleanup completion
+ * IO cleanup completion
*/
static void
bfa_itnim_cleanp_comp(void *itnim_cbarg)
@@ -1115,7 +901,7 @@ bfa_itnim_cleanp_comp(void *itnim_cbarg)
}
/*
- * Initiate cleanup of all IOs.
+ * Initiate cleanup of all IOs.
*/
static void
bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
@@ -1187,9 +973,6 @@ bfa_itnim_qresume(void *cbarg)
bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
}
-
-
-
/*
* bfa_itnim_public
*/
@@ -1401,7 +1184,7 @@ bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
if (itnim->fcpim->path_tov > 0) {
itnim->iotov_active = BFA_TRUE;
- bfa_assert(bfa_itnim_hold_io(itnim));
+ WARN_ON(!bfa_itnim_hold_io(itnim));
bfa_timer_start(itnim->bfa, &itnim->timer,
bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
}
@@ -1457,14 +1240,12 @@ bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns;
}
-
-
/*
- * bfa_itnim_public
+ * bfa_itnim_public
*/
/*
- * Itnim interrupt processing.
+ * Itnim interrupt processing.
*/
void
bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
@@ -1481,7 +1262,7 @@ bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
case BFI_ITNIM_I2H_CREATE_RSP:
itnim = BFA_ITNIM_FROM_TAG(fcpim,
msg.create_rsp->bfa_handle);
- bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
+ WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
bfa_stats(itnim, create_comps);
bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
break;
@@ -1489,7 +1270,7 @@ bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
case BFI_ITNIM_I2H_DELETE_RSP:
itnim = BFA_ITNIM_FROM_TAG(fcpim,
msg.delete_rsp->bfa_handle);
- bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
+ WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
bfa_stats(itnim, delete_comps);
bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
break;
@@ -1503,14 +1284,12 @@ bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
default:
bfa_trc(bfa, m->mhdr.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
-
-
/*
- * bfa_itnim_api
+ * bfa_itnim_api
*/
struct bfa_itnim_s *
@@ -1520,7 +1299,7 @@ bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
struct bfa_itnim_s *itnim;
itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
- bfa_assert(itnim->rport == rport);
+ WARN_ON(itnim->rport != rport);
itnim->ditn = ditn;
@@ -1568,31 +1347,6 @@ bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
}
-bfa_status_t
-bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
- struct bfa_itnim_ioprofile_s *ioprofile)
-{
- struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(itnim->bfa);
- if (!fcpim->io_profile)
- return BFA_STATUS_IOPROFILE_OFF;
-
- itnim->ioprofile.index = BFA_IOBUCKET_MAX;
- itnim->ioprofile.io_profile_start_time =
- bfa_io_profile_start_time(itnim->bfa);
- itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
- itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
- *ioprofile = itnim->ioprofile;
-
- return BFA_STATUS_OK;
-}
-
-void
-bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
- struct bfa_itnim_iostats_s *stats)
-{
- *stats = itnim->stats;
-}
-
void
bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
{
@@ -1608,14 +1362,11 @@ bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
*/
/*
- * IO is not started (unallocated).
+ * IO is not started (unallocated).
*/
static void
bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
{
- bfa_trc_fp(ioim->bfa, ioim->iotag);
- bfa_trc_fp(ioim->bfa, event);
-
switch (event) {
case BFA_IOIM_SM_START:
if (!bfa_itnim_is_online(ioim->itnim)) {
@@ -1635,7 +1386,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
if (ioim->nsges > BFI_SGE_INLINE) {
- if (!bfa_ioim_sge_setup(ioim)) {
+ if (!bfa_ioim_sgpg_alloc(ioim)) {
bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
return;
}
@@ -1662,7 +1413,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
* requests immediately.
*/
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
- bfa_assert(bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
+ WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
__bfa_cb_ioim_abort, ioim);
break;
@@ -1673,7 +1424,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * IO is waiting for SG pages.
+ * IO is waiting for SG pages.
*/
static void
bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1720,14 +1471,11 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * IO is active.
+ * IO is active.
*/
static void
bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
{
- bfa_trc_fp(ioim->bfa, ioim->iotag);
- bfa_trc_fp(ioim->bfa, event);
-
switch (event) {
case BFA_IOIM_SM_COMP_GOOD:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
@@ -1786,8 +1534,8 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
case BFA_IOIM_SM_SQRETRY:
- if (bfa_ioim_get_iotag(ioim) != BFA_TRUE) {
- /* max retry completed free IO */
+ if (bfa_ioim_maxretry_reached(ioim)) {
+ /* max retry reached, free IO */
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
bfa_ioim_move_to_comp_q(ioim);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
@@ -1804,17 +1552,15 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
-* IO is retried with new tag.
-*/
+ * IO is retried with new tag.
+ */
static void
bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
{
- bfa_trc_fp(ioim->bfa, ioim->iotag);
- bfa_trc_fp(ioim->bfa, event);
-
switch (event) {
case BFA_IOIM_SM_FREE:
/* abts and rrq done. Now retry the IO with new tag */
+ bfa_ioim_update_iotag(ioim);
if (!bfa_ioim_send_ioreq(ioim)) {
bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
break;
@@ -1858,7 +1604,7 @@ bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * IO is being aborted, waiting for completion from firmware.
+ * IO is being aborted, waiting for completion from firmware.
*/
static void
bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1894,7 +1640,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
case BFA_IOIM_SM_CLEANUP:
- bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
+ WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
ioim->iosp->abort_explicit = BFA_FALSE;
if (bfa_ioim_send_abort(ioim))
@@ -1981,7 +1727,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * IO is waiting for room in request CQ
+ * IO is waiting for room in request CQ
*/
static void
bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2025,7 +1771,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * Active IO is being aborted, waiting for room in request CQ.
+ * Active IO is being aborted, waiting for room in request CQ.
*/
static void
bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2040,7 +1786,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
case BFA_IOIM_SM_CLEANUP:
- bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
+ WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
ioim->iosp->abort_explicit = BFA_FALSE;
bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
break;
@@ -2076,7 +1822,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
/*
- * Active IO is being cleaned up, waiting for room in request CQ.
+ * Active IO is being cleaned up, waiting for room in request CQ.
*/
static void
bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2131,9 +1877,6 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
static void
bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
{
- bfa_trc_fp(ioim->bfa, ioim->iotag);
- bfa_trc_fp(ioim->bfa, event);
-
switch (event) {
case BFA_IOIM_SM_HCB:
bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
@@ -2213,11 +1956,6 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
}
-
-/*
- * hal_ioim_private
- */
-
static void
__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
{
@@ -2323,7 +2061,7 @@ bfa_ioim_sgpg_alloced(void *cbarg)
ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
- bfa_ioim_sgpg_setup(ioim);
+ ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
}
@@ -2335,13 +2073,16 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
{
struct bfa_itnim_s *itnim = ioim->itnim;
struct bfi_ioim_req_s *m;
- static struct fcp_cmnd_s cmnd_z0 = { 0 };
- struct bfi_sge_s *sge;
+ static struct fcp_cmnd_s cmnd_z0 = { { { 0 } } };
+ struct bfi_sge_s *sge, *sgpge;
u32 pgdlen = 0;
u32 fcp_dl;
u64 addr;
struct scatterlist *sg;
+ struct bfa_sgpg_s *sgpg;
struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
+ u32 i, sge_id, pgcumsz;
+ enum dma_data_direction dmadir;
/*
* check for room in queue to send request now
@@ -2359,22 +2100,61 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
*/
m->io_tag = cpu_to_be16(ioim->iotag);
m->rport_hdl = ioim->itnim->rport->fw_handle;
- m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
+ m->io_timeout = 0;
- /*
- * build inline IO SG element here
- */
sge = &m->sges[0];
- if (ioim->nsges) {
- sg = (struct scatterlist *)scsi_sglist(cmnd);
- addr = bfa_os_sgaddr(sg_dma_address(sg));
- sge->sga = *(union bfi_addr_u *) &addr;
- pgdlen = sg_dma_len(sg);
- sge->sg_len = pgdlen;
- sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
+ sgpg = ioim->sgpg;
+ sge_id = 0;
+ sgpge = NULL;
+ pgcumsz = 0;
+ scsi_for_each_sg(cmnd, sg, ioim->nsges, i) {
+ if (i == 0) {
+ /* build inline IO SG element */
+ addr = bfa_sgaddr_le(sg_dma_address(sg));
+ sge->sga = *(union bfi_addr_u *) &addr;
+ pgdlen = sg_dma_len(sg);
+ sge->sg_len = pgdlen;
+ sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
- bfa_sge_to_be(sge);
- sge++;
+ bfa_sge_to_be(sge);
+ sge++;
+ } else {
+ if (sge_id == 0)
+ sgpge = sgpg->sgpg->sges;
+
+ addr = bfa_sgaddr_le(sg_dma_address(sg));
+ sgpge->sga = *(union bfi_addr_u *) &addr;
+ sgpge->sg_len = sg_dma_len(sg);
+ pgcumsz += sgpge->sg_len;
+
+ /* set flags */
+ if (i < (ioim->nsges - 1) &&
+ sge_id < (BFI_SGPG_DATA_SGES - 1))
+ sgpge->flags = BFI_SGE_DATA;
+ else if (i < (ioim->nsges - 1))
+ sgpge->flags = BFI_SGE_DATA_CPL;
+ else
+ sgpge->flags = BFI_SGE_DATA_LAST;
+
+ bfa_sge_to_le(sgpge);
+
+ sgpge++;
+ if (i == (ioim->nsges - 1)) {
+ sgpge->flags = BFI_SGE_PGDLEN;
+ sgpge->sga.a32.addr_lo = 0;
+ sgpge->sga.a32.addr_hi = 0;
+ sgpge->sg_len = pgcumsz;
+ bfa_sge_to_le(sgpge);
+ } else if (++sge_id == BFI_SGPG_DATA_SGES) {
+ sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
+ sgpge->flags = BFI_SGE_LINK;
+ sgpge->sga = sgpg->sgpg_pa;
+ sgpge->sg_len = pgcumsz;
+ bfa_sge_to_le(sgpge);
+ sge_id = 0;
+ pgcumsz = 0;
+ }
+ }
}
if (ioim->nsges > BFI_SGE_INLINE) {
@@ -2391,10 +2171,17 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
* set up I/O command parameters
*/
m->cmnd = cmnd_z0;
- m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
- m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
- m->cmnd.cdb = *(scsi_cdb_t *)bfa_cb_ioim_get_cdb(ioim->dio);
- fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
+ int_to_scsilun(cmnd->device->lun, &m->cmnd.lun);
+ dmadir = cmnd->sc_data_direction;
+ if (dmadir == DMA_TO_DEVICE)
+ m->cmnd.iodir = FCP_IODIR_WRITE;
+ else if (dmadir == DMA_FROM_DEVICE)
+ m->cmnd.iodir = FCP_IODIR_READ;
+ else
+ m->cmnd.iodir = FCP_IODIR_NONE;
+
+ m->cmnd.cdb = *(struct scsi_cdb_s *) cmnd->cmnd;
+ fcp_dl = scsi_bufflen(cmnd);
m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
/*
@@ -2418,28 +2205,9 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
}
if (itnim->seq_rec ||
- (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1)))
+ (scsi_bufflen(cmnd) & (sizeof(u32) - 1)))
bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
-#ifdef IOIM_ADVANCED
- m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio);
- m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
- m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
-
- /*
- * Handle large CDB (>16 bytes).
- */
- m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
- FCP_CMND_CDB_LEN) / sizeof(u32);
- if (m->cmnd.addl_cdb_len) {
- memcpy(&m->cmnd.cdb + 1, (scsi_cdb_t *)
- bfa_cb_ioim_get_cdb(ioim->dio) + 1,
- m->cmnd.addl_cdb_len * sizeof(u32));
- fcp_cmnd_fcpdl(&m->cmnd) =
- cpu_to_be32(bfa_cb_ioim_get_size(ioim->dio));
- }
-#endif
-
/*
* queue I/O message to firmware
*/
@@ -2452,11 +2220,11 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
* at queuing time.
*/
static bfa_boolean_t
-bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
+bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim)
{
u16 nsgpgs;
- bfa_assert(ioim->nsges > BFI_SGE_INLINE);
+ WARN_ON(ioim->nsges <= BFI_SGE_INLINE);
/*
* allocate SG pages needed
@@ -2472,73 +2240,11 @@ bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
}
ioim->nsgpgs = nsgpgs;
- bfa_ioim_sgpg_setup(ioim);
+ ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
return BFA_TRUE;
}
-static void
-bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
-{
- int sgeid, nsges, i;
- struct bfi_sge_s *sge;
- struct bfa_sgpg_s *sgpg;
- u32 pgcumsz;
- u64 addr;
- struct scatterlist *sg;
- struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
-
- sgeid = BFI_SGE_INLINE;
- ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
-
- sg = scsi_sglist(cmnd);
- sg = sg_next(sg);
-
- do {
- sge = sgpg->sgpg->sges;
- nsges = ioim->nsges - sgeid;
- if (nsges > BFI_SGPG_DATA_SGES)
- nsges = BFI_SGPG_DATA_SGES;
-
- pgcumsz = 0;
- for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
- addr = bfa_os_sgaddr(sg_dma_address(sg));
- sge->sga = *(union bfi_addr_u *) &addr;
- sge->sg_len = sg_dma_len(sg);
- pgcumsz += sge->sg_len;
-
- /*
- * set flags
- */
- if (i < (nsges - 1))
- sge->flags = BFI_SGE_DATA;
- else if (sgeid < (ioim->nsges - 1))
- sge->flags = BFI_SGE_DATA_CPL;
- else
- sge->flags = BFI_SGE_DATA_LAST;
-
- bfa_sge_to_le(sge);
- }
-
- sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
-
- /*
- * set the link element of each page
- */
- if (sgeid == ioim->nsges) {
- sge->flags = BFI_SGE_PGDLEN;
- sge->sga.a32.addr_lo = 0;
- sge->sga.a32.addr_hi = 0;
- } else {
- sge->flags = BFI_SGE_LINK;
- sge->sga = sgpg->sgpg_pa;
- }
- sge->sg_len = pgcumsz;
-
- bfa_sge_to_le(sge);
- } while (sgeid < ioim->nsges);
-}
-
/*
* Send I/O abort request to firmware.
*/
@@ -2605,7 +2311,7 @@ bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
}
bfa_itnim_iodone(ioim->itnim);
} else
- bfa_tskim_iodone(ioim->iosp->tskim);
+ bfa_wc_down(&ioim->iosp->tskim->wc);
}
static bfa_boolean_t
@@ -2623,9 +2329,6 @@ bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
return BFA_TRUE;
}
-/*
- * or after the link comes back.
- */
void
bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
{
@@ -2653,11 +2356,6 @@ bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
}
-
-/*
- * hal_ioim_friend
- */
-
/*
* Memory allocation and initialization.
*/
@@ -2722,14 +2420,6 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
}
}
-/*
- * Driver detach time call.
- */
-void
-bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim)
-{
-}
-
void
bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
{
@@ -2742,7 +2432,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
iotag = be16_to_cpu(rsp->io_tag);
ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
- bfa_assert(ioim->iotag == iotag);
+ WARN_ON(ioim->iotag != iotag);
bfa_trc(ioim->bfa, ioim->iotag);
bfa_trc(ioim->bfa, rsp->io_status);
@@ -2773,13 +2463,13 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
case BFI_IOIM_STS_PROTO_ERR:
bfa_stats(ioim->itnim, iocom_proto_err);
- bfa_assert(rsp->reuse_io_tag);
+ WARN_ON(!rsp->reuse_io_tag);
evt = BFA_IOIM_SM_COMP;
break;
case BFI_IOIM_STS_SQER_NEEDED:
bfa_stats(ioim->itnim, iocom_sqer_needed);
- bfa_assert(rsp->reuse_io_tag == 0);
+ WARN_ON(rsp->reuse_io_tag != 0);
evt = BFA_IOIM_SM_SQRETRY;
break;
@@ -2808,7 +2498,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
bfa_sm_send_event(ioim, evt);
@@ -2825,39 +2515,12 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
iotag = be16_to_cpu(rsp->io_tag);
ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
- bfa_assert(ioim->iotag == iotag);
+ WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag);
- bfa_trc_fp(ioim->bfa, ioim->iotag);
bfa_ioim_cb_profile_comp(fcpim, ioim);
-
bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
}
-void
-bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
-{
- ioim->start_time = jiffies;
-}
-
-void
-bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
-{
- u32 fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
- u32 index = bfa_ioim_get_index(fcp_dl);
- u64 end_time = jiffies;
- struct bfa_itnim_latency_s *io_lat =
- &(ioim->itnim->ioprofile.io_latency);
- u32 val = (u32)(end_time - ioim->start_time);
-
- bfa_itnim_ioprofile_update(ioim->itnim, index);
-
- io_lat->count[index]++;
- io_lat->min[index] = (io_lat->min[index] < val) ?
- io_lat->min[index] : val;
- io_lat->max[index] = (io_lat->max[index] > val) ?
- io_lat->max[index] : val;
- io_lat->avg[index] += val;
-}
/*
* Called by itnim to clean up IO while going offline.
*/
@@ -2903,11 +2566,6 @@ bfa_ioim_tov(struct bfa_ioim_s *ioim)
}
-
-/*
- * hal_ioim_api
- */
-
/*
* Allocate IOIM resource for initiator mode I/O request.
*/
@@ -2936,7 +2594,6 @@ bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
fcpim->ios_active++;
list_add_tail(&ioim->qe, &itnim->io_q);
- bfa_trc_fp(ioim->bfa, ioim->iotag);
return ioim;
}
@@ -2946,18 +2603,13 @@ bfa_ioim_free(struct bfa_ioim_s *ioim)
{
struct bfa_fcpim_mod_s *fcpim = ioim->fcpim;
- bfa_trc_fp(ioim->bfa, ioim->iotag);
- bfa_assert_fp(bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit));
-
- bfa_assert_fp(list_empty(&ioim->sgpg_q) ||
- (ioim->nsges > BFI_SGE_INLINE));
-
if (ioim->nsgpgs > 0)
bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
bfa_stats(ioim->itnim, io_comps);
fcpim->ios_active--;
+ ioim->iotag &= BFA_IOIM_IOTAG_MASK;
list_del(&ioim->qe);
list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
}
@@ -2965,16 +2617,13 @@ bfa_ioim_free(struct bfa_ioim_s *ioim)
void
bfa_ioim_start(struct bfa_ioim_s *ioim)
{
- bfa_trc_fp(ioim->bfa, ioim->iotag);
-
bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
/*
* Obtain the queue over which this request has to be issued
*/
ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
- bfa_cb_ioim_get_reqq(ioim->dio) :
- bfa_itnim_get_reqq(ioim);
+ BFA_FALSE : bfa_itnim_get_reqq(ioim);
bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
}
@@ -2997,13 +2646,12 @@ bfa_ioim_abort(struct bfa_ioim_s *ioim)
return BFA_STATUS_OK;
}
-
/*
* BFA TSKIM state machine functions
*/
/*
- * Task management command beginning state.
+ * Task management command beginning state.
*/
static void
bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3040,9 +2688,8 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
}
/*
- * brief
- * TM command is active, awaiting completion from firmware to
- * cleanup IO requests in TM scope.
+ * TM command is active, awaiting completion from firmware to
+ * cleanup IO requests in TM scope.
*/
static void
bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3077,8 +2724,8 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
}
/*
- * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
- * completion event from firmware.
+ * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
+ * completion event from firmware.
*/
static void
bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3138,7 +2785,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
}
/*
- * Task management command is waiting for room in request CQ
+ * Task management command is waiting for room in request CQ
*/
static void
bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3173,8 +2820,8 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
}
/*
- * Task management command is active, awaiting for room in request CQ
- * to send clean up request.
+ * Task management command is active, awaiting for room in request CQ
+ * to send clean up request.
*/
static void
bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
@@ -3186,10 +2833,8 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
case BFA_TSKIM_SM_DONE:
bfa_reqq_wcancel(&tskim->reqq_wait);
/*
- *
* Fall through !!!
*/
-
case BFA_TSKIM_SM_QRESUME:
bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
bfa_tskim_send_abort(tskim);
@@ -3208,7 +2853,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
}
/*
- * BFA callback is pending
+ * BFA callback is pending
*/
static void
bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3233,12 +2878,6 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
}
}
-
-
-/*
- * hal_tskim_private
- */
-
static void
__bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
{
@@ -3268,8 +2907,8 @@ __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
BFI_TSKIM_STS_FAILED);
}
-static bfa_boolean_t
-bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
+static bfa_boolean_t
+bfa_tskim_match_scope(struct bfa_tskim_s *tskim, struct scsi_lun lun)
{
switch (tskim->tm_cmnd) {
case FCP_TM_TARGET_RESET:
@@ -3279,24 +2918,26 @@ bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
case FCP_TM_CLEAR_TASK_SET:
case FCP_TM_LUN_RESET:
case FCP_TM_CLEAR_ACA:
- return (tskim->lun == lun);
+ return !memcmp(&tskim->lun, &lun, sizeof(lun));
default:
- bfa_assert(0);
+ WARN_ON(1);
}
return BFA_FALSE;
}
/*
- * Gather affected IO requests and task management commands.
+ * Gather affected IO requests and task management commands.
*/
static void
bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
{
struct bfa_itnim_s *itnim = tskim->itnim;
struct bfa_ioim_s *ioim;
- struct list_head *qe, *qen;
+ struct list_head *qe, *qen;
+ struct scsi_cmnd *cmnd;
+ struct scsi_lun scsilun;
INIT_LIST_HEAD(&tskim->io_q);
@@ -3305,8 +2946,9 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
*/
list_for_each_safe(qe, qen, &itnim->io_q) {
ioim = (struct bfa_ioim_s *) qe;
- if (bfa_tskim_match_scope
- (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
+ cmnd = (struct scsi_cmnd *) ioim->dio;
+ int_to_scsilun(cmnd->device->lun, &scsilun);
+ if (bfa_tskim_match_scope(tskim, scsilun)) {
list_del(&ioim->qe);
list_add_tail(&ioim->qe, &tskim->io_q);
}
@@ -3317,8 +2959,9 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
*/
list_for_each_safe(qe, qen, &itnim->pending_q) {
ioim = (struct bfa_ioim_s *) qe;
- if (bfa_tskim_match_scope
- (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
+ cmnd = (struct scsi_cmnd *) ioim->dio;
+ int_to_scsilun(cmnd->device->lun, &scsilun);
+ if (bfa_tskim_match_scope(tskim, scsilun)) {
list_del(&ioim->qe);
list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_ioim_tov(ioim);
@@ -3327,7 +2970,7 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
}
/*
- * IO cleanup completion
+ * IO cleanup completion
*/
static void
bfa_tskim_cleanp_comp(void *tskim_cbarg)
@@ -3339,7 +2982,7 @@ bfa_tskim_cleanp_comp(void *tskim_cbarg)
}
/*
- * Gather affected IO requests and task management commands.
+ * Gather affected IO requests and task management commands.
*/
static void
bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
@@ -3359,7 +3002,7 @@ bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
}
/*
- * Send task management request to firmware.
+ * Send task management request to firmware.
*/
static bfa_boolean_t
bfa_tskim_send(struct bfa_tskim_s *tskim)
@@ -3394,7 +3037,7 @@ bfa_tskim_send(struct bfa_tskim_s *tskim)
}
/*
- * Send abort request to cleanup an active TM to firmware.
+ * Send abort request to cleanup an active TM to firmware.
*/
static bfa_boolean_t
bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
@@ -3425,7 +3068,7 @@ bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
}
/*
- * Call to resume task management cmnd waiting for room in request queue.
+ * Call to resume task management cmnd waiting for room in request queue.
*/
static void
bfa_tskim_qresume(void *cbarg)
@@ -3451,12 +3094,6 @@ bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
}
}
-
-
-/*
- * hal_tskim_friend
- */
-
/*
* Notification on completions from related ioim.
*/
@@ -3489,7 +3126,7 @@ bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
}
/*
- * Memory allocation and initialization.
+ * Memory allocation and initialization.
*/
void
bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
@@ -3522,14 +3159,6 @@ bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
}
void
-bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
-{
- /*
- * @todo
- */
-}
-
-void
bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
@@ -3538,7 +3167,7 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
u16 tsk_tag = be16_to_cpu(rsp->tsk_tag);
tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
- bfa_assert(tskim->tsk_tag == tsk_tag);
+ WARN_ON(tskim->tsk_tag != tsk_tag);
tskim->tsk_status = rsp->tsk_status;
@@ -3556,12 +3185,6 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
}
-
-/*
- * hal_tskim_api
- */
-
-
struct bfa_tskim_s *
bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
{
@@ -3579,13 +3202,13 @@ bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
void
bfa_tskim_free(struct bfa_tskim_s *tskim)
{
- bfa_assert(bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
+ WARN_ON(!bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
list_del(&tskim->qe);
list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
}
/*
- * Start a task management command.
+ * Start a task management command.
*
* @param[in] tskim BFA task management command instance
* @param[in] itnim i-t nexus for the task management command
@@ -3596,7 +3219,8 @@ bfa_tskim_free(struct bfa_tskim_s *tskim)
* @return None.
*/
void
-bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun,
+bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim,
+ struct scsi_lun lun,
enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
{
tskim->itnim = itnim;
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h
index db53717eeb4b..1e38dade8423 100644
--- a/drivers/scsi/bfa/bfa_fcpim.h
+++ b/drivers/scsi/bfa/bfa_fcpim.h
@@ -41,7 +41,7 @@
(__itnim->ioprofile.iocomps[__index]++)
#define BFA_IOIM_RETRY_TAG_OFFSET 11
-#define BFA_IOIM_RETRY_TAG_MASK 0x07ff /* 2K IOs */
+#define BFA_IOIM_IOTAG_MASK 0x07ff /* 2K IOs */
#define BFA_IOIM_RETRY_MAX 7
/* Buckets are are 512 bytes to 2MB */
@@ -94,12 +94,12 @@ struct bfa_fcpim_mod_s {
struct list_head ioim_resfree_q; /* IOs waiting for f/w */
struct list_head ioim_comp_q; /* IO global comp Q */
struct list_head tskim_free_q;
- u32 ios_active; /* current active IOs */
- u32 delay_comp;
+ u32 ios_active; /* current active IOs */
+ u32 delay_comp;
struct bfa_fcpim_del_itn_stats_s del_itn_stats;
bfa_boolean_t ioredirect;
bfa_boolean_t io_profile;
- u32 io_profile_start_time;
+ u32 io_profile_start_time;
bfa_fcpim_profile_t profile_comp;
bfa_fcpim_profile_t profile_start;
};
@@ -114,25 +114,24 @@ struct bfa_ioim_s {
struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
struct bfad_ioim_s *dio; /* driver IO handle */
- u16 iotag; /* FWI IO tag */
- u16 abort_tag; /* unqiue abort request tag */
- u16 nsges; /* number of SG elements */
- u16 nsgpgs; /* number of SG pages */
+ u16 iotag; /* FWI IO tag */
+ u16 abort_tag; /* unqiue abort request tag */
+ u16 nsges; /* number of SG elements */
+ u16 nsgpgs; /* number of SG pages */
struct bfa_sgpg_s *sgpg; /* first SG page */
struct list_head sgpg_q; /* allocated SG pages */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
- struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
- u8 reqq; /* Request queue for I/O */
- u64 start_time; /* IO's Profile start val */
+ struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
+ u8 reqq; /* Request queue for I/O */
+ u64 start_time; /* IO's Profile start val */
};
-
struct bfa_ioim_sp_s {
struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */
u8 *snsinfo; /* sense info for this IO */
- struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
- struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
+ struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
+ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
bfa_boolean_t abort_explicit; /* aborted by OS */
struct bfa_tskim_s *tskim; /* Relevant TM cmd */
};
@@ -143,35 +142,34 @@ struct bfa_ioim_sp_s {
struct bfa_tskim_s {
struct list_head qe;
bfa_sm_t sm;
- struct bfa_s *bfa; /* BFA module */
+ struct bfa_s *bfa; /* BFA module */
struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
- struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
- bfa_boolean_t notify; /* notify itnim on TM comp */
- lun_t lun; /* lun if applicable */
- enum fcp_tm_cmnd tm_cmnd; /* task management command */
- u16 tsk_tag; /* FWI IO tag */
- u8 tsecs; /* timeout in seconds */
+ struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
+ bfa_boolean_t notify; /* notify itnim on TM comp */
+ struct scsi_lun lun; /* lun if applicable */
+ enum fcp_tm_cmnd tm_cmnd; /* task management command */
+ u16 tsk_tag; /* FWI IO tag */
+ u8 tsecs; /* timeout in seconds */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct list_head io_q; /* queue of affected IOs */
- struct bfa_wc_s wc; /* waiting counter */
+ struct bfa_wc_s wc; /* waiting counter */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
enum bfi_tskim_status tsk_status; /* TM status */
};
-
/*
* BFA i-t-n (initiator mode)
*/
struct bfa_itnim_s {
- struct list_head qe; /* queue element */
- bfa_sm_t sm; /* i-t-n im BFA state machine */
- struct bfa_s *bfa; /* bfa instance */
- struct bfa_rport_s *rport; /* bfa rport */
- void *ditn; /* driver i-t-n structure */
+ struct list_head qe; /* queue element */
+ bfa_sm_t sm; /* i-t-n im BFA state machine */
+ struct bfa_s *bfa; /* bfa instance */
+ struct bfa_rport_s *rport; /* bfa rport */
+ void *ditn; /* driver i-t-n structure */
struct bfi_mhdr_s mhdr; /* pre-built mhdr */
- u8 msg_no; /* itnim/rport firmware handle */
- u8 reqq; /* CQ for requests */
+ u8 msg_no; /* itnim/rport firmware handle */
+ u8 reqq; /* CQ for requests */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
struct list_head pending_q; /* queue of pending IO requests */
struct list_head io_q; /* queue of active IO requests */
@@ -181,19 +179,19 @@ struct bfa_itnim_s {
bfa_boolean_t seq_rec; /* SQER supported */
bfa_boolean_t is_online; /* itnim is ONLINE for IO */
bfa_boolean_t iotov_active; /* IO TOV timer is active */
- struct bfa_wc_s wc; /* waiting counter */
- struct bfa_timer_s timer; /* pending IO TOV */
+ struct bfa_wc_s wc; /* waiting counter */
+ struct bfa_timer_s timer; /* pending IO TOV */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
struct bfa_itnim_iostats_s stats;
struct bfa_itnim_ioprofile_s ioprofile;
};
-
#define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
#define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
+#define BFA_IOIM_TAG_2_ID(_iotag) ((_iotag) & BFA_IOIM_IOTAG_MASK)
#define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \
- (&fcpim->ioim_arr[(_iotag & BFA_IOIM_RETRY_TAG_MASK)])
+ (&fcpim->ioim_arr[(_iotag & BFA_IOIM_IOTAG_MASK)])
#define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \
(&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
@@ -201,26 +199,26 @@ struct bfa_itnim_s {
(_bfa->modules.fcpim_mod.io_profile_start_time)
#define bfa_fcpim_get_io_profile(_bfa) \
(_bfa->modules.fcpim_mod.io_profile)
+#define bfa_ioim_update_iotag(__ioim) do { \
+ uint16_t k = (__ioim)->iotag >> BFA_IOIM_RETRY_TAG_OFFSET; \
+ k++; (__ioim)->iotag &= BFA_IOIM_IOTAG_MASK; \
+ (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \
+} while (0)
static inline bfa_boolean_t
-bfa_ioim_get_iotag(struct bfa_ioim_s *ioim)
+bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
{
- u16 k = ioim->iotag;
-
- k >>= BFA_IOIM_RETRY_TAG_OFFSET; k++;
-
- if (k > BFA_IOIM_RETRY_MAX)
+ uint16_t k = ioim->iotag >> BFA_IOIM_RETRY_TAG_OFFSET;
+ if (k < BFA_IOIM_RETRY_MAX)
return BFA_FALSE;
- ioim->iotag &= BFA_IOIM_RETRY_TAG_MASK;
- ioim->iotag |= k<<BFA_IOIM_RETRY_TAG_OFFSET;
return BFA_TRUE;
}
+
/*
* function prototypes
*/
void bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim,
struct bfa_meminfo_s *minfo);
-void bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim);
void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_ioim_good_comp_isr(struct bfa_s *bfa,
struct bfi_msg_s *msg);
@@ -232,7 +230,6 @@ void bfa_ioim_tov(struct bfa_ioim_s *ioim);
void bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim,
struct bfa_meminfo_s *minfo);
-void bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim);
void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_tskim_iodone(struct bfa_tskim_s *tskim);
void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
@@ -248,32 +245,14 @@ void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_itnim_iodone(struct bfa_itnim_s *itnim);
void bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
-void bfa_ioim_profile_comp(struct bfa_ioim_s *ioim);
-void bfa_ioim_profile_start(struct bfa_ioim_s *ioim);
-
/*
* bfa fcpim module API functions
*/
-void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
+void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
u16 bfa_fcpim_path_tov_get(struct bfa_s *bfa);
-void bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth);
u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa);
-bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa,
- struct bfa_itnim_iostats_s *modstats);
-bfa_status_t bfa_fcpim_port_iostats(struct bfa_s *bfa,
- struct bfa_itnim_iostats_s *stats, u8 lp_tag);
-bfa_status_t bfa_fcpim_get_del_itn_stats(struct bfa_s *bfa,
- struct bfa_fcpim_del_itn_stats_s *modstats);
-bfa_status_t bfa_fcpim_port_clear_iostats(struct bfa_s *bfa, u8 lp_tag);
-void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats,
- struct bfa_itnim_iostats_s *itnim_stats);
-bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa);
-void bfa_fcpim_set_ioredirect(struct bfa_s *bfa,
- bfa_boolean_t state);
-void bfa_fcpim_update_ioredirect(struct bfa_s *bfa);
-bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time);
-bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
+
#define bfa_fcpim_ioredirect_enabled(__bfa) \
(((struct bfa_fcpim_mod_s *)(BFA_FCPIM_MOD(__bfa)))->ioredirect)
@@ -291,48 +270,33 @@ bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
* bfa itnim API functions
*/
struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa,
- struct bfa_rport_s *rport, void *itnim);
-void bfa_itnim_delete(struct bfa_itnim_s *itnim);
-void bfa_itnim_online(struct bfa_itnim_s *itnim,
- bfa_boolean_t seq_rec);
-void bfa_itnim_offline(struct bfa_itnim_s *itnim);
-void bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
- struct bfa_itnim_iostats_s *stats);
-void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
-bfa_status_t bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
- struct bfa_itnim_ioprofile_s *ioprofile);
+ struct bfa_rport_s *rport, void *itnim);
+void bfa_itnim_delete(struct bfa_itnim_s *itnim);
+void bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec);
+void bfa_itnim_offline(struct bfa_itnim_s *itnim);
+void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
+bfa_status_t bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
+ struct bfa_itnim_ioprofile_s *ioprofile);
+
#define bfa_itnim_get_reqq(__ioim) (((struct bfa_ioim_s *)__ioim)->itnim->reqq)
/*
- * BFA completion callback for bfa_itnim_online().
- *
- * @param[in] itnim FCS or driver itnim instance
- *
- * return None
+ * BFA completion callback for bfa_itnim_online().
*/
void bfa_cb_itnim_online(void *itnim);
/*
- * BFA completion callback for bfa_itnim_offline().
- *
- * @param[in] itnim FCS or driver itnim instance
- *
- * return None
+ * BFA completion callback for bfa_itnim_offline().
*/
void bfa_cb_itnim_offline(void *itnim);
void bfa_cb_itnim_tov_begin(void *itnim);
void bfa_cb_itnim_tov(void *itnim);
/*
- * BFA notification to FCS/driver for second level error recovery.
- *
+ * BFA notification to FCS/driver for second level error recovery.
* Atleast one I/O request has timedout and target is unresponsive to
* repeated abort requests. Second level error recovery should be initiated
* by starting implicit logout and recovery procedures.
- *
- * @param[in] itnim FCS or driver itnim instance
- *
- * return None
*/
void bfa_cb_itnim_sler(void *itnim);
@@ -349,10 +313,8 @@ void bfa_ioim_start(struct bfa_ioim_s *ioim);
bfa_status_t bfa_ioim_abort(struct bfa_ioim_s *ioim);
void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
bfa_boolean_t iotov);
-
-
/*
- * I/O completion notification.
+ * I/O completion notification.
*
* @param[in] dio driver IO structure
* @param[in] io_status IO completion status
@@ -363,39 +325,31 @@ void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
*
* @return None
*/
-void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
- enum bfi_ioim_status io_status,
- u8 scsi_status, int sns_len,
- u8 *sns_info, s32 residue);
+void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
+ enum bfi_ioim_status io_status,
+ u8 scsi_status, int sns_len,
+ u8 *sns_info, s32 residue);
/*
- * I/O good completion notification.
- *
- * @param[in] dio driver IO structure
- *
- * @return None
+ * I/O good completion notification.
*/
-void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
+void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
/*
- * I/O abort completion notification
- *
- * @param[in] dio driver IO that was aborted
- *
- * @return None
+ * I/O abort completion notification
*/
-void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
+void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
/*
* bfa tskim API functions
*/
-struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
- struct bfad_tskim_s *dtsk);
-void bfa_tskim_free(struct bfa_tskim_s *tskim);
-void bfa_tskim_start(struct bfa_tskim_s *tskim,
- struct bfa_itnim_s *itnim, lun_t lun,
- enum fcp_tm_cmnd tm, u8 t_secs);
-void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
- enum bfi_tskim_status tsk_status);
+struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
+ struct bfad_tskim_s *dtsk);
+void bfa_tskim_free(struct bfa_tskim_s *tskim);
+void bfa_tskim_start(struct bfa_tskim_s *tskim,
+ struct bfa_itnim_s *itnim, struct scsi_lun lun,
+ enum fcp_tm_cmnd tm, u8 t_secs);
+void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
+ enum bfi_tskim_status tsk_status);
#endif /* __BFA_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index c94502dfac66..f674f9318629 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -19,9 +19,9 @@
* bfa_fcs.c BFA FCS main
*/
+#include "bfad_drv.h"
#include "bfa_fcs.h"
#include "bfa_fcbuild.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(FCS, FCS);
@@ -76,7 +76,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
fcs->bfad = bfad;
fcs->min_cfg = min_cfg;
- bfa_attach_fcs(bfa);
+ bfa->fcs = BFA_TRUE;
fcbuild_init();
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
@@ -110,14 +110,6 @@ bfa_fcs_init(struct bfa_fcs_s *fcs)
}
}
-/*
- * Start FCS operations.
- */
-void
-bfa_fcs_start(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_fabric_modstart(fcs);
-}
/*
* brief
@@ -140,22 +132,6 @@ 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;
-
-}
-/*
- * brief
* FCS instance cleanup and exit.
*
* param[in] fcs FCS instance
@@ -184,18 +160,6 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
}
-void
-bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
-{
- fcs->trcmod = trcmod;
-}
-
-void
-bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
-{
- bfa_wc_down(&fcs->wc);
-}
-
/*
* Fabric module implementation.
*/
@@ -232,31 +196,6 @@ static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
u32 rsp_len,
u32 resid_len,
struct fchs_s *rspfchs);
-/*
- * fcs_fabric_sm fabric state machine functions
- */
-
-/*
- * Fabric state machine events
- */
-enum bfa_fcs_fabric_event {
- BFA_FCS_FABRIC_SM_CREATE = 1, /* create from driver */
- BFA_FCS_FABRIC_SM_DELETE = 2, /* delete from driver */
- BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
- BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
- BFA_FCS_FABRIC_SM_CONT_OP = 5, /* flogi/auth continue op */
- BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* flogi/auth retry op */
- BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* from flogi/auth */
- BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* from flogi/auth */
- BFA_FCS_FABRIC_SM_ISOLATE = 9, /* from EVFP processing */
- BFA_FCS_FABRIC_SM_NO_TAGGING = 10, /* no VFT tagging from EVFP */
- BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
- BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* auth failed */
- BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* auth successful */
- BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
- BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
- BFA_FCS_FABRIC_SM_START = 16, /* from driver */
-};
static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
@@ -270,14 +209,8 @@ static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
-static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
- enum bfa_fcs_fabric_event event);
-static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
- enum bfa_fcs_fabric_event event);
static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
-static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
- enum bfa_fcs_fabric_event event);
static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
@@ -337,7 +270,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_DELETE:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
- bfa_fcs_modexit_comp(fabric->fcs);
+ bfa_wc_down(&fabric->fcs->wc);
break;
default:
@@ -410,7 +343,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_LOOPBACK:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_set_opertype(fabric);
break;
@@ -424,12 +357,12 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
break;
case BFA_FCS_FABRIC_SM_DELETE:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_delete(fabric);
break;
@@ -481,7 +414,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_AUTH_FAILED:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
break;
case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
@@ -495,7 +428,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
break;
case BFA_FCS_FABRIC_SM_DELETE:
@@ -511,7 +444,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
/*
* Authentication failed
*/
-static void
+void
bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
@@ -537,7 +470,7 @@ bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
/*
* Port is in loopback mode.
*/
-static void
+void
bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
@@ -573,7 +506,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_notify_offline(fabric);
break;
@@ -596,7 +529,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
/*
* Fabric is online - normal operating state.
*/
-static void
+void
bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
@@ -606,7 +539,7 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_notify_offline(fabric);
break;
@@ -617,7 +550,7 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_AUTH_FAILED:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
- bfa_lps_discard(fabric->lps);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
break;
case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
@@ -677,7 +610,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
bfa_trc(fabric->fcs, event);
wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Port is isolated due to VF_ID mismatch. "
"PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
pwwn_ptr, fabric->fcs->port_vfid,
@@ -697,7 +630,7 @@ bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_DELCOMP:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
- bfa_fcs_modexit_comp(fabric->fcs);
+ bfa_wc_down(&fabric->fcs->wc);
break;
case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -724,8 +657,8 @@ bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
- port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
- port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
+ port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
+ port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
}
/*
@@ -813,7 +746,7 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
return;
case BFA_STATUS_EPROTOCOL:
- switch (bfa_lps_get_extstatus(fabric->lps)) {
+ switch (fabric->lps->ext_status) {
case BFA_EPROTO_BAD_ACCEPT:
fabric->stats.flogi_acc_err++;
break;
@@ -840,26 +773,26 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
return;
}
- fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
+ fabric->bb_credit = fabric->lps->pr_bbcred;
bfa_trc(fabric->fcs, fabric->bb_credit);
- if (!bfa_lps_is_brcd_fabric(fabric->lps))
- fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps);
+ if (!(fabric->lps->brcd_switch))
+ fabric->fabric_name = fabric->lps->pr_nwwn;
/*
* Check port type. It should be 1 = F-port.
*/
- if (bfa_lps_is_fport(fabric->lps)) {
- fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
- fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
- fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
+ if (fabric->lps->fport) {
+ fabric->bport.pid = fabric->lps->lp_pid;
+ fabric->is_npiv = fabric->lps->npiv_en;
+ fabric->is_auth = fabric->lps->auth_req;
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
} else {
/*
* Nport-2-Nport direct attached
*/
fabric->bport.port_topo.pn2n.rem_port_wwn =
- bfa_lps_get_peer_pwwn(fabric->lps);
+ fabric->lps->pr_pwwn;
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
}
@@ -987,7 +920,7 @@ bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
INIT_LIST_HEAD(&fabric->vport_q);
INIT_LIST_HEAD(&fabric->vf_q);
fabric->lps = bfa_lps_alloc(fcs->bfa);
- bfa_assert(fabric->lps);
+ WARN_ON(!fabric->lps);
/*
* Initialize fabric delete completion handler. Fabric deletion is
@@ -1038,31 +971,6 @@ bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
}
-/*
- * Suspend fabric activity as part of driver suspend.
- */
-void
-bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
-{
-}
-
-bfa_boolean_t
-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_port_type
-bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
-{
- return fabric->oper_type;
-}
/*
* Link up notification from BFA physical port module.
@@ -1123,40 +1031,6 @@ bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
bfa_wc_down(&fabric->wc);
}
-/*
- * Base port is deleted.
- */
-void
-bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
-{
- bfa_wc_down(&fabric->wc);
-}
-
-
-/*
- * Check if fabric is online.
- *
- * param[in] fabric - Fabric instance. This can be a base fabric or vf.
- *
- * @return TRUE/FALSE
- */
-int
-bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
-{
- return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
-}
-
-/*
- * brief
- *
- */
-bfa_status_t
-bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
- struct bfa_lport_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
-{
- bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
- return BFA_STATUS_OK;
-}
/*
* Lookup for a vport withing a fabric given its pwwn
@@ -1176,18 +1050,6 @@ bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
return NULL;
}
-/*
- * In a given fabric, return the number of lports.
- *
- * param[in] fabric - Fabric instance. This can be a base fabric or vf.
- *
- * @return : 1 or more.
- */
-u16
-bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
-{
- return fabric->num_vports;
-}
/*
* Get OUI of the attached switch.
@@ -1207,7 +1069,7 @@ bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
u8 *tmp;
u16 oui;
- fab_nwwn = bfa_lps_get_peer_nwwn(fabric->lps);
+ fab_nwwn = fabric->lps->pr_nwwn;
tmp = (u8 *)&fab_nwwn;
oui = (tmp[3] << 8) | tmp[4];
@@ -1235,7 +1097,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
* external loopback cable is in place. Our own FLOGI frames are
* sometimes looped back when switch port gets temporarily bypassed.
*/
- if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT)) &&
+ if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
(els_cmd->els_code == FC_ELS_FLOGI) &&
(flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
@@ -1245,7 +1107,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
/*
* FLOGI/EVFP exchanges should be consumed by base fabric.
*/
- if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
+ if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
bfa_trc(fabric->fcs, pid);
bfa_fcs_fabric_process_uf(fabric, fchs, len);
return;
@@ -1358,13 +1220,13 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
return;
reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
- bfa_os_hton3b(FC_FABRIC_PORT),
+ bfa_hton3b(FC_FABRIC_PORT),
n2n_port->reply_oxid, pcfg->pwwn,
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_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag,
BFA_FALSE, FC_CLASS_3,
reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
FC_MAX_PDUSZ, 0);
@@ -1411,7 +1273,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
wwn2str(fwwn_ptr,
bfa_fcs_lport_get_fabric_name(&fabric->bport));
- BFA_LOG(KERN_WARNING, bfad, log_level,
+ BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
"Base port WWN = %s Fabric WWN = %s\n",
pwwn_ptr, fwwn_ptr);
}
@@ -1455,7 +1317,7 @@ bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -1502,7 +1364,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
* drop frame if vfid is unknown
*/
if (!fabric) {
- bfa_assert(0);
+ WARN_ON(1);
bfa_stats(fcs, uf.vfid_unknown);
bfa_uf_free(uf);
return;
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index 9cb6a55977c3..0fd63168573f 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -27,6 +27,22 @@
#define BFA_FCS_OS_STR_LEN 64
/*
+ * lps_pvt BFA LPS private functions
+ */
+
+enum bfa_lps_event {
+ BFA_LPS_SM_LOGIN = 1, /* login request from user */
+ BFA_LPS_SM_LOGOUT = 2, /* logout request from user */
+ BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */
+ 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 */
+ BFA_LPS_SM_SET_N2N_PID = 8, /* Set assigned PID for n2n */
+};
+
+
+/*
* !!! Only append to the enums defined here to avoid any versioning
* !!! needed between trace utility and driver version
*/
@@ -41,13 +57,12 @@ enum {
struct bfa_fcs_s;
#define __fcs_min_cfg(__fcs) ((__fcs)->min_cfg)
-void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
#define BFA_FCS_BRCD_SWITCH_OUI 0x051e
#define N2N_LOCAL_PID 0x010000
#define N2N_REMOTE_PID 0x020000
#define BFA_FCS_RETRY_TIMEOUT 2000
-#define BFA_FCS_PID_IS_WKA(pid) ((bfa_os_ntoh3b(pid) > 0xFFF000) ? 1 : 0)
+#define BFA_FCS_PID_IS_WKA(pid) ((bfa_ntoh3b(pid) > 0xFFF000) ? 1 : 0)
@@ -109,7 +124,7 @@ struct bfa_fcs_lport_loop_s {
struct bfa_fcs_lport_n2n_s {
u32 rsvd;
- u16 reply_oxid; /* ox_id from the req flogi to be
+ __be16 reply_oxid; /* ox_id from the req flogi to be
*used in flogi acc */
wwn_t rem_port_wwn; /* Attached port's wwn */
};
@@ -316,8 +331,6 @@ void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport);
void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport);
-void bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs);
void bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *vport);
@@ -359,9 +372,6 @@ bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
struct bfa_vport_attr_s *vport_attr);
-void bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
- struct bfa_vport_stats_s *vport_stats);
-void bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport);
struct bfa_fcs_vport_s *bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs,
u16 vf_id, wwn_t vpwwn);
void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
@@ -406,7 +416,7 @@ struct bfa_fcs_rport_s {
struct bfad_rport_s *rp_drv; /* driver peer instance */
u32 pid; /* port ID of rport */
u16 maxfrsize; /* maximum frame size */
- u16 reply_oxid; /* OX_ID of inbound requests */
+ __be16 reply_oxid; /* OX_ID of inbound requests */
enum fc_cos fc_cos; /* FC classes of service supp */
bfa_boolean_t cisc; /* CISC capable device */
bfa_boolean_t prlo; /* processing prlo or LOGO */
@@ -437,32 +447,18 @@ bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport)
/*
* bfa fcs rport API functions
*/
-bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
- struct bfa_fcs_rport_s *rport,
- struct bfad_rport_s *rport_drv);
-bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
- struct bfa_rport_attr_s *attr);
-void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
- struct bfa_rport_stats_s *stats);
-void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport);
struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port,
wwn_t rpwwn);
struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn(
struct bfa_fcs_lport_s *port, wwn_t rnwwn);
void bfa_fcs_rport_set_del_timeout(u8 rport_tmo);
-void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
- enum bfa_port_speed speed);
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);
struct bfa_fcs_rport_s *bfa_fcs_rport_create(struct bfa_fcs_lport_s *port,
u32 pid);
-void bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport);
void bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
struct fc_logi_s *plogi_rsp);
void bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port,
@@ -470,10 +466,8 @@ void bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port,
struct fc_logi_s *plogi);
void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
struct fc_logi_s *plogi);
-void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id);
+void bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id);
-void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport);
void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport);
void bfa_fcs_rport_fcptm_offline_done(struct bfa_fcs_rport_s *rport);
int bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport);
@@ -618,7 +612,7 @@ struct bfa_fcs_fdmi_hba_attr_s {
u8 option_rom_ver[BFA_VERSION_LEN];
u8 fw_version[8];
u8 os_name[256];
- u32 max_ct_pyld;
+ __be32 max_ct_pyld;
};
/*
@@ -626,9 +620,9 @@ struct bfa_fcs_fdmi_hba_attr_s {
*/
struct bfa_fcs_fdmi_port_attr_s {
u8 supp_fc4_types[32]; /* supported FC4 types */
- u32 supp_speed; /* supported speed */
- u32 curr_speed; /* current Speed */
- u32 max_frm_size; /* max frame size */
+ __be32 supp_speed; /* supported speed */
+ __be32 curr_speed; /* current Speed */
+ __be32 max_frm_size; /* max frame size */
u8 os_device_name[256]; /* OS device Name */
u8 host_name[256]; /* host name */
};
@@ -664,6 +658,57 @@ struct bfa_fcs_s {
};
/*
+ * fcs_fabric_sm fabric state machine functions
+ */
+
+/*
+ * Fabric state machine events
+ */
+enum bfa_fcs_fabric_event {
+ BFA_FCS_FABRIC_SM_CREATE = 1, /* create from driver */
+ BFA_FCS_FABRIC_SM_DELETE = 2, /* delete from driver */
+ BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
+ BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
+ BFA_FCS_FABRIC_SM_CONT_OP = 5, /* flogi/auth continue op */
+ BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* flogi/auth retry op */
+ BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* from flogi/auth */
+ BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* from flogi/auth */
+ BFA_FCS_FABRIC_SM_ISOLATE = 9, /* from EVFP processing */
+ BFA_FCS_FABRIC_SM_NO_TAGGING = 10, /* no VFT tagging from EVFP */
+ BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
+ BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* auth failed */
+ BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* auth successful */
+ BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
+ BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
+ BFA_FCS_FABRIC_SM_START = 16, /* from driver */
+};
+
+/*
+ * fcs_rport_sm FCS rport state machine events
+ */
+
+enum rport_event {
+ RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
+ RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
+ RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
+ RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
+ RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
+ RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
+ RPSM_EVENT_DELETE = 7, /* RPORT delete request */
+ RPSM_EVENT_SCN = 8, /* state change notification */
+ RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
+ RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
+ RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
+ RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
+ RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
+ RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
+ RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
+ RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
+ RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
+ RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continously */
+};
+
+/*
* bfa fcs API functions
*/
void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa,
@@ -672,16 +717,12 @@ void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa,
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_start(struct bfa_fcs_s *fcs);
/*
* bfa fcs vf public functions
*/
bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id);
-u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
/*
* fabric protected interface functions
@@ -689,32 +730,29 @@ u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
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);
void bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
struct bfa_fcs_vport_s *vport);
void bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
struct bfa_fcs_vport_s *vport);
-int bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric);
struct bfa_fcs_vport_s *bfa_fcs_fabric_vport_lookup(
struct bfa_fcs_fabric_s *fabric, wwn_t pwwn);
void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
-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_port_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);
-bfa_status_t bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf,
- struct bfa_fcs_s *fcs, struct bfa_lport_cfg_s *port_cfg,
- struct bfad_vf_s *vf_drv);
void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
wwn_t fabric_name);
u16 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
void bfa_fcs_port_attach(struct bfa_fcs_s *fcs);
+void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event);
+void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event);
+void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event);
/*
* BFA FCS callback interfaces
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c
index 9662bcdeb41d..e7b49f4cb51f 100644
--- a/drivers/scsi/bfa/bfa_fcs_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c
@@ -19,9 +19,9 @@
* fcpim.c - FCP initiator mode i-t nexus state machine
*/
+#include "bfad_drv.h"
#include "bfa_fcs.h"
#include "bfa_fcbuild.h"
-#include "bfad_drv.h"
#include "bfad_im.h"
BFA_TRC_FILE(FCS, FCPIM);
@@ -103,7 +103,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
break;
case BFA_FCS_ITNIM_SM_OFFLINE:
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -140,7 +140,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -181,7 +181,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
bfa_fcxp_discard(itnim->fcxp);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -217,7 +217,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
} else {
/* invoke target offline */
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
- bfa_fcs_rport_logo_imp(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
}
break;
@@ -225,7 +225,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
bfa_timer_stop(&itnim->timer);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -261,7 +261,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
bfa_fcb_itnim_online(itnim->itnim_drv);
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
wwn2str(rpwwn_buf, itnim->rport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Target (WWN = %s) is online for initiator (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
break;
@@ -269,7 +269,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
bfa_itnim_offline(itnim->bfa_itnim);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -301,11 +301,11 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
wwn2str(rpwwn_buf, itnim->rport->pwwn);
if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE)
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Target (WWN = %s) connectivity lost for "
"initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
else
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Target (WWN = %s) offlined by initiator (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
break;
@@ -330,7 +330,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -358,7 +358,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
- bfa_fcs_rport_itnim_ack(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_RSP_ERROR:
@@ -536,7 +536,7 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
if (bfa_itnim == NULL) {
bfa_trc(port->fcs, rport->pwwn);
bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv);
- bfa_assert(0);
+ WARN_ON(1);
return NULL;
}
@@ -688,7 +688,7 @@ bfa_cb_itnim_sler(void *cb_arg)
itnim->stats.sler++;
bfa_trc(itnim->fcs, itnim->rport->pwwn);
- bfa_fcs_rport_logo_imp(itnim->rport);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
}
struct bfa_fcs_itnim_s *
@@ -700,7 +700,7 @@ bfa_fcs_itnim_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
if (!rport)
return NULL;
- bfa_assert(rport->itnim != NULL);
+ WARN_ON(rport->itnim == NULL);
return rport->itnim;
}
@@ -729,7 +729,7 @@ bfa_fcs_itnim_stats_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
{
struct bfa_fcs_itnim_s *itnim = NULL;
- bfa_assert(port != NULL);
+ WARN_ON(port == NULL);
itnim = bfa_fcs_itnim_lookup(port, rpwwn);
@@ -746,7 +746,7 @@ bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
{
struct bfa_fcs_itnim_s *itnim = NULL;
- bfa_assert(port != NULL);
+ WARN_ON(port == NULL);
itnim = bfa_fcs_itnim_lookup(port, rpwwn);
@@ -778,6 +778,6 @@ bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
}
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 377cbfff6f2e..4e2eb92ba028 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -15,10 +15,10 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_fcs.h"
#include "bfa_fcbuild.h"
#include "bfa_fc.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(FCS, PORT);
@@ -159,7 +159,7 @@ bfa_fcs_lport_sm_online(
bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
list_for_each_safe(qe, qen, &port->rport_q) {
rport = (struct bfa_fcs_rport_s *) qe;
- bfa_fcs_rport_delete(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
}
}
break;
@@ -197,7 +197,7 @@ bfa_fcs_lport_sm_offline(
bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
list_for_each_safe(qe, qen, &port->rport_q) {
rport = (struct bfa_fcs_rport_s *) qe;
- bfa_fcs_rport_delete(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
}
}
break;
@@ -309,6 +309,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
return;
}
port->pid = rx_fchs->d_id;
+ bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
}
/*
@@ -323,6 +324,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
(void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
port->pid = rx_fchs->d_id;
+ bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
rport->pid = rx_fchs->s_id;
}
bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
@@ -349,8 +351,8 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
* This is a different device with the same pid. Old device
* disappeared. Send implicit LOGO to old device.
*/
- bfa_assert(rport->pwwn != plogi->port_name);
- bfa_fcs_rport_logo_imp(rport);
+ WARN_ON(rport->pwwn == plogi->port_name);
+ bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
/*
* Inbound PLOGI from a new device (with old PID).
@@ -362,7 +364,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
/*
* PLOGI crossing each other.
*/
- bfa_assert(rport->pwwn == WWN_NULL);
+ WARN_ON(rport->pwwn != WWN_NULL);
bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
}
@@ -491,7 +493,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
__port_action[port->fabric->fab_type].online(port);
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Logical port online: WWN = %s Role = %s\n",
lpwwn_buf, "Initiator");
@@ -511,37 +513,38 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
__port_action[port->fabric->fab_type].offline(port);
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
- if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
- BFA_LOG(KERN_ERR, bfad, log_level,
+ if (bfa_sm_cmp_state(port->fabric,
+ bfa_fcs_fabric_sm_online) == BFA_TRUE)
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Logical port lost fabric connectivity: WWN = %s Role = %s\n",
lpwwn_buf, "Initiator");
else
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Logical port taken offline: WWN = %s Role = %s\n",
lpwwn_buf, "Initiator");
list_for_each_safe(qe, qen, &port->rport_q) {
rport = (struct bfa_fcs_rport_s *) qe;
- bfa_fcs_rport_offline(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
}
}
static void
bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
{
- bfa_assert(0);
+ WARN_ON(1);
}
static void
bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
{
- bfa_assert(0);
+ WARN_ON(1);
}
static void
bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
{
- bfa_assert(0);
+ WARN_ON(1);
}
static void
@@ -573,7 +576,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
char lpwwn_buf[BFA_STRING_32];
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Logical port deleted: WWN = %s Role = %s\n",
lpwwn_buf, "Initiator");
@@ -584,33 +587,11 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
port->vport ? port->vport->vport_drv : NULL);
bfa_fcs_vport_delete_comp(port->vport);
} else {
- bfa_fcs_fabric_port_delete_comp(port->fabric);
+ bfa_wc_down(&port->fabric->wc);
}
}
-
-/*
- * fcs_lport_api BFA FCS port API
- */
-/*
- * Module initialization
- */
-void
-bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs)
-{
-
-}
-
-/*
- * Module cleanup
- */
-void
-bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
-}
-
/*
* Unsolicited frame receive handling.
*/
@@ -623,6 +604,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
bfa_stats(lport, uf_recvs);
+ bfa_trc(lport->fcs, fchs->type);
if (!bfa_fcs_lport_is_online(lport)) {
bfa_stats(lport, uf_recv_drops);
@@ -682,8 +664,11 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
* Only handles ELS frames for now.
*/
if (fchs->type != FC_TYPE_ELS) {
- bfa_trc(lport->fcs, fchs->type);
- bfa_assert(0);
+ bfa_trc(lport->fcs, fchs->s_id);
+ bfa_trc(lport->fcs, fchs->d_id);
+ /* ignore type FC_TYPE_FC_FSS */
+ if (fchs->type != FC_TYPE_FC_FSS)
+ bfa_sm_fault(lport->fcs, fchs->type);
return;
}
@@ -792,7 +777,7 @@ bfa_fcs_lport_del_rport(
struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport)
{
- bfa_assert(bfa_q_is_on_q(&port->rport_q, rport));
+ WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
list_del(&rport->qe);
port->num_rports--;
@@ -850,8 +835,8 @@ bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
lport->fcs = fcs;
lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
lport->vport = vport;
- lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
- bfa_lps_get_tag(lport->fabric->lps);
+ lport->lp_tag = (vport) ? vport->lps->lp_tag :
+ lport->fabric->lps->lp_tag;
INIT_LIST_HEAD(&lport->rport_q);
lport->num_rports = 0;
@@ -878,7 +863,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
vport ? vport->vport_drv : NULL);
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"New logical port created: WWN = %s Role = %s\n",
lpwwn_buf, "Initiator");
@@ -903,10 +888,12 @@ bfa_fcs_lport_get_attr(
port_attr->port_cfg = port->port_cfg;
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->port_type = port->fabric->oper_type;
+ port_attr->loopback = bfa_sm_cmp_state(port->fabric,
+ bfa_fcs_fabric_sm_loopback);
port_attr->authfail =
- bfa_fcs_fabric_is_auth_failed(port->fabric);
+ bfa_sm_cmp_state(port->fabric,
+ bfa_fcs_fabric_sm_auth_failed);
port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port);
memcpy(port_attr->fabric_ip_addr,
bfa_fcs_lport_get_fabric_ipaddr(port),
@@ -915,10 +902,10 @@ bfa_fcs_lport_get_attr(
if (port->vport != NULL) {
port_attr->port_type = BFA_PORT_TYPE_VPORT;
port_attr->fpma_mac =
- bfa_lps_get_lp_mac(port->vport->lps);
+ port->vport->lps->lp_mac;
} else {
port_attr->fpma_mac =
- bfa_lps_get_lp_mac(port->fabric->lps);
+ port->fabric->lps->lp_mac;
}
} else {
port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
@@ -998,6 +985,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
sizeof(wwn_t)) > 0) {
port->pid = N2N_LOCAL_PID;
+ bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
/*
* First, check if we know the device by pwwn.
*/
@@ -1007,7 +995,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
bfa_trc(port->fcs, rport->pid);
bfa_trc(port->fcs, rport->pwwn);
rport->pid = N2N_REMOTE_PID;
- bfa_fcs_rport_online(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
return;
}
@@ -1017,10 +1005,10 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
*/
if (port->num_rports > 0) {
rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
- bfa_assert(rport != NULL);
+ WARN_ON(rport == NULL);
if (rport) {
bfa_trc(port->fcs, rport->pwwn);
- bfa_fcs_rport_delete(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
}
}
bfa_fcs_rport_create(port, N2N_REMOTE_PID);
@@ -1569,6 +1557,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
struct fdmi_attr_s *attr;
u8 *curr_ptr;
u16 len, count;
+ u16 templen;
/*
* get hba attributes
@@ -1594,69 +1583,69 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
- attr->len = sizeof(wwn_t);
- memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), attr->len);
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = sizeof(wwn_t);
+ memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Manufacturer
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
- attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
- memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->manufacturer);
+ memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Serial Number
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
- attr->len = (u16) strlen(fcs_hba_attr->serial_num);
- memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->serial_num);
+ memcpy(attr->value, fcs_hba_attr->serial_num, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Model
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
- attr->len = (u16) strlen(fcs_hba_attr->model);
- memcpy(attr->value, fcs_hba_attr->model, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->model);
+ memcpy(attr->value, fcs_hba_attr->model, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Model Desc
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
- attr->len = (u16) strlen(fcs_hba_attr->model_desc);
- memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->model_desc);
+ memcpy(attr->value, fcs_hba_attr->model_desc, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* H/W Version
@@ -1664,14 +1653,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
if (fcs_hba_attr->hw_version[0] != '\0') {
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
- attr->len = (u16) strlen(fcs_hba_attr->hw_version);
- memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->hw_version);
+ memcpy(attr->value, fcs_hba_attr->hw_version, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
}
/*
@@ -1679,14 +1668,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
- attr->len = (u16) strlen(fcs_hba_attr->driver_version);
- memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;;
+ templen = (u16) strlen(fcs_hba_attr->driver_version);
+ memcpy(attr->value, fcs_hba_attr->driver_version, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Option Rom Version
@@ -1694,14 +1683,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
if (fcs_hba_attr->option_rom_ver[0] != '\0') {
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
- attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
- memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
+ memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
}
/*
@@ -1709,14 +1698,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
- attr->len = (u16) strlen(fcs_hba_attr->driver_version);
- memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->driver_version);
+ memcpy(attr->value, fcs_hba_attr->driver_version, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* OS Name
@@ -1724,14 +1713,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
if (fcs_hba_attr->os_name[0] != '\0') {
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
- attr->len = (u16) strlen(fcs_hba_attr->os_name);
- memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_hba_attr->os_name);
+ memcpy(attr->value, fcs_hba_attr->os_name, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
}
/*
@@ -1739,12 +1728,12 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
- attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
- memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
- len += attr->len;
+ templen = sizeof(fcs_hba_attr->max_ct_pyld);
+ memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
+ len += templen;
count++;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Update size of payload
@@ -1845,6 +1834,7 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
u8 *curr_ptr;
u16 len;
u8 count = 0;
+ u16 templen;
/*
* get port attributes
@@ -1863,54 +1853,54 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
- attr->len = sizeof(fcs_port_attr.supp_fc4_types);
- memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = sizeof(fcs_port_attr.supp_fc4_types);
+ memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
attr->len =
- cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* Supported Speed
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
- attr->len = sizeof(fcs_port_attr.supp_speed);
- memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = sizeof(fcs_port_attr.supp_speed);
+ memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
attr->len =
- cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* current Port Speed
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
- attr->len = sizeof(fcs_port_attr.curr_speed);
- memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = sizeof(fcs_port_attr.curr_speed);
+ memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* max frame size
*/
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
- attr->len = sizeof(fcs_port_attr.max_frm_size);
- memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = sizeof(fcs_port_attr.max_frm_size);
+ memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
/*
* OS Device Name
@@ -1918,14 +1908,14 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
if (fcs_port_attr.os_device_name[0] != '\0') {
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
- attr->len = (u16) strlen(fcs_port_attr.os_device_name);
- memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_port_attr.os_device_name);
+ memcpy(attr->value, fcs_port_attr.os_device_name, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
}
/*
* Host Name
@@ -1933,14 +1923,14 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
if (fcs_port_attr.host_name[0] != '\0') {
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
- attr->len = (u16) strlen(fcs_port_attr.host_name);
- memcpy(attr->value, fcs_port_attr.host_name, attr->len);
- attr->len = fc_roundup(attr->len, sizeof(u32));
- curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
- len += attr->len;
+ templen = (u16) strlen(fcs_port_attr.host_name);
+ memcpy(attr->value, fcs_port_attr.host_name, templen);
+ templen = fc_roundup(templen, sizeof(u32));
+ curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+ len += templen;
++count;
- attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
- sizeof(attr->len));
+ attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+ sizeof(templen));
}
/*
@@ -2103,7 +2093,7 @@ bfa_fcs_lport_fdmi_timeout(void *arg)
bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
}
-void
+static void
bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
{
@@ -2147,7 +2137,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
}
-void
+static void
bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
struct bfa_fcs_fdmi_port_attr_s *port_attr)
{
@@ -2560,7 +2550,7 @@ bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
bfa_fcs_lport_get_fcid(port),
- bfa_lps_get_peer_nwwn(port->fabric->lps));
+ port->fabric->lps->pr_nwwn);
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs,
@@ -2760,7 +2750,7 @@ bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
bfa_fcs_lport_get_fcid(port),
- bfa_lps_get_peer_nwwn(port->fabric->lps));
+ port->fabric->lps->pr_nwwn);
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs,
@@ -2836,7 +2826,7 @@ bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
ms->fcxp = fcxp;
len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
- bfa_os_hton3b(FC_MGMT_SERVER),
+ bfa_hton3b(FC_MGMT_SERVER),
bfa_fcs_lport_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
bfa_fcport_get_maxfrsize(port->fcs->bfa));
@@ -3593,7 +3583,7 @@ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
ns->fcxp = fcxp;
len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
- bfa_os_hton3b(FC_NAME_SERVER),
+ bfa_hton3b(FC_NAME_SERVER),
bfa_fcs_lport_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
bfa_fcport_get_maxfrsize(port->fcs->bfa));
@@ -4150,7 +4140,7 @@ bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
}
-void
+static void
bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
{
@@ -4163,7 +4153,7 @@ bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
for (ii = 0 ; ii < nwwns; ++ii) {
rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
- bfa_assert(rport);
+ WARN_ON(!rport);
}
}
@@ -4352,8 +4342,8 @@ bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
/* Handle VU registrations for Base port only */
if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
- bfa_lps_is_brcd_fabric(port->fabric->lps),
- port->pid, 0);
+ port->fabric->lps->brcd_switch,
+ port->pid, 0);
} else {
len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
BFA_FALSE,
@@ -4626,7 +4616,7 @@ bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
default:
- bfa_assert(0);
+ WARN_ON(1);
nsquery = BFA_TRUE;
}
}
@@ -4672,7 +4662,7 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
while ((qe != qh) && (i < nrports)) {
rport = (struct bfa_fcs_rport_s *) qe;
- if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
+ if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
qe = bfa_q_next(qe);
bfa_trc(fcs, (u32) rport->pwwn);
bfa_trc(fcs, rport->pid);
@@ -4720,7 +4710,7 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
while ((qe != qh) && (i < *nrports)) {
rport = (struct bfa_fcs_rport_s *) qe;
- if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
+ if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
qe = bfa_q_next(qe);
bfa_trc(fcs, (u32) rport->pwwn);
bfa_trc(fcs, rport->pid);
@@ -4771,7 +4761,7 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
while (qe != qh) {
rport = (struct bfa_fcs_rport_s *) qe;
- if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) ||
+ if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
(bfa_fcs_rport_get_state(rport) ==
BFA_RPORT_OFFLINE)) {
qe = bfa_q_next(qe);
@@ -4807,7 +4797,7 @@ bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
struct bfa_fcs_vport_s *vport;
bfa_fcs_vf_t *vf;
- bfa_assert(fcs != NULL);
+ WARN_ON(fcs == NULL);
vf = bfa_fcs_vf_lookup(fcs, vf_id);
if (vf == NULL) {
@@ -4853,7 +4843,7 @@ bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
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->fabric->num_vports;
port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
port_info->num_rports_inuse = port->num_rports;
} else {
@@ -4997,7 +4987,8 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
switch (event) {
case BFA_FCS_VPORT_SM_START:
- if (bfa_fcs_fabric_is_online(__vport_fabric(vport))
+ if (bfa_sm_cmp_state(__vport_fabric(vport),
+ bfa_fcs_fabric_sm_online)
&& bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
bfa_fcs_vport_do_fdisc(vport);
@@ -5080,13 +5071,13 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
switch (event) {
case BFA_FCS_VPORT_SM_DELETE:
bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
- bfa_lps_discard(vport->lps);
+ bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_lport_delete(&vport->lport);
break;
case BFA_FCS_VPORT_SM_OFFLINE:
bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
- bfa_lps_discard(vport->lps);
+ bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
break;
case BFA_FCS_VPORT_SM_RSP_OK:
@@ -5166,7 +5157,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
case BFA_FCS_VPORT_SM_OFFLINE:
bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
- bfa_lps_discard(vport->lps);
+ bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_lport_offline(&vport->lport);
break;
@@ -5266,7 +5257,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
switch (event) {
case BFA_FCS_VPORT_SM_OFFLINE:
- bfa_lps_discard(vport->lps);
+ bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
/*
* !!! fall through !!!
*/
@@ -5305,14 +5296,14 @@ bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
static void
bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
{
- u8 lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps);
- u8 lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps);
+ u8 lsrjt_rsn = vport->lps->lsrjt_rsn;
+ u8 lsrjt_expl = vport->lps->lsrjt_expl;
bfa_trc(__vport_fcs(vport), lsrjt_rsn);
bfa_trc(__vport_fcs(vport), lsrjt_expl);
/* For certain reason codes, we don't want to retry. */
- switch (bfa_lps_get_lsrjt_expl(vport->lps)) {
+ switch (vport->lps->lsrjt_expl) {
case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
@@ -5476,7 +5467,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
return BFA_STATUS_VPORT_EXISTS;
- if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
+ if (fcs->fabric.num_vports ==
bfa_lps_get_max_vport(fcs->bfa))
return BFA_STATUS_VPORT_MAX;
@@ -5618,33 +5609,6 @@ bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
}
-/*
- * Use this function to get vport's statistics.
- *
- * param[in] vport pointer to bfa_fcs_vport_t.
- * param[out] stats pointer to return vport statistics in
- *
- * return None
- */
-void
-bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
- struct bfa_vport_stats_s *stats)
-{
- *stats = vport->vport_stats;
-}
-
-/*
- * Use this function to clear vport's statistics.
- *
- * param[in] vport pointer to bfa_fcs_vport_t.
- *
- * return None
- */
-void
-bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport)
-{
- memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
-}
/*
* Lookup a virtual port. Excludes base port from lookup.
@@ -5684,7 +5648,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
/*
* Initialiaze the V-Port fields
*/
- __vport_fcid(vport) = bfa_lps_get_pid(vport->lps);
+ __vport_fcid(vport) = vport->lps->lp_pid;
vport->vport_stats.fdisc_accepts++;
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
break;
@@ -5697,7 +5661,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
break;
case BFA_STATUS_EPROTOCOL:
- switch (bfa_lps_get_extstatus(vport->lps)) {
+ switch (vport->lps->ext_status) {
case BFA_EPROTO_BAD_ACCEPT:
vport->vport_stats.fdisc_acc_bad++;
break;
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index 47f35c0ef29a..caaee6f06937 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -19,9 +19,9 @@
* rport.c Remote port implementation.
*/
+#include "bfad_drv.h"
#include "bfa_fcs.h"
#include "bfa_fcbuild.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(FCS, RPORT);
@@ -75,30 +75,6 @@ static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
struct fchs_s *rx_fchs, u16 len);
static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
-/*
- * fcs_rport_sm FCS rport state machine events
- */
-
-enum rport_event {
- RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
- RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
- RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
- RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
- RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
- RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
- RPSM_EVENT_DELETE = 7, /* RPORT delete request */
- RPSM_EVENT_SCN = 8, /* state change notification */
- RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
- RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
- RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
- RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
- RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
- RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
- RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
- RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
- RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
- RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continously */
-};
static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
enum rport_event event);
@@ -498,24 +474,24 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_LOGO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
bfa_fcs_rport_send_plogiacc(rport, NULL);
break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
case RPSM_EVENT_SCN:
@@ -824,7 +800,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
case RPSM_EVENT_DELETE:
@@ -856,7 +832,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
default:
@@ -878,7 +854,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
- bfa_rport_offline(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
break;
case RPSM_EVENT_SCN:
@@ -1459,7 +1435,7 @@ bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
twin->stats.plogi_accs++;
- bfa_fcs_rport_delete(rport);
+ bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
bfa_fcs_rport_update(twin, plogi_rsp);
twin->pid = rsp_fchs->s_id;
@@ -1992,13 +1968,14 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
/*
* allocate FC-4s
*/
- bfa_assert(bfa_fcs_lport_is_initiator(port));
+ WARN_ON(!bfa_fcs_lport_is_initiator(port));
if (bfa_fcs_lport_is_initiator(port)) {
rport->itnim = bfa_fcs_itnim_create(rport);
if (!rport->itnim) {
bfa_trc(fcs, rpid);
- bfa_rport_delete(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport,
+ BFA_RPORT_SM_DELETE);
kfree(rport_drv);
return NULL;
}
@@ -2032,7 +2009,7 @@ bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
bfa_fcs_rpf_rport_offline(rport);
}
- bfa_rport_delete(rport->bfa_rport);
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
bfa_fcs_lport_del_rport(port, rport);
kfree(rport->rp_drv);
}
@@ -2056,7 +2033,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
wwn2str(rpwwn_buf, rport->pwwn);
if (!BFA_FCS_PID_IS_WKA(rport->pid))
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
}
@@ -2075,12 +2052,12 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
wwn2str(rpwwn_buf, rport->pwwn);
if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Remote port (WWN = %s) connectivity lost for "
"logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
else
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Remote port (WWN = %s) offlined by "
"logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
@@ -2307,40 +2284,8 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
}
-/*
- * Called by bport/vport to delete a remote port instance.
- *
- * Rport delete is called under the following conditions:
- * - vport is deleted
- * - vf is deleted
- * - explicit request from OS to delete rport
- */
-void
-bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
-}
/*
- * Called by bport/vport to when a target goes offline.
- *
- */
-void
-bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
-}
-
-/*
- * Called by bport in n2n when a target (attached port) becomes online.
- *
- */
-void
-bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
-}
-/*
* Called by bport/vport to notify SCN for the remote port
*/
void
@@ -2350,23 +2295,6 @@ bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
bfa_sm_send_event(rport, RPSM_EVENT_SCN);
}
-/*
- * Called by fcpim to notify that the ITN cleanup is done.
- */
-void
-bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
-}
-
-/*
- * Called by fcptm to notify that the ITN cleanup is done.
- */
-void
-bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
-}
/*
* brief
@@ -2465,15 +2393,6 @@ bfa_cb_rport_qos_scn_prio(void *cbarg,
* Called to process any unsolicted frames from this remote port
*/
void
-bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
-{
- bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
-}
-
-/*
- * Called to process any unsolicted frames from this remote port
- */
-void
bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
struct fchs_s *fchs, u16 len)
{
@@ -2586,6 +2505,7 @@ bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
return bfa_sm_to_state(rport_sm_table, rport->sm);
}
+
/*
* brief
* Called by the Driver to set rport delete/ageout timeout
@@ -2602,7 +2522,7 @@ bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
bfa_fcs_rport_del_timeout = rport_tmo * 1000;
}
void
-bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
+bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
{
bfa_trc(rport->fcs, rport->pid);
@@ -2621,106 +2541,6 @@ bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
* fcs_rport_api FCS rport API.
*/
-/*
- * Direct API to add a target by port wwn. This interface is used, for
- * example, by bios when target pwwn is known from boot lun configuration.
- */
-bfa_status_t
-bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
- struct bfa_fcs_rport_s *rport, struct bfad_rport_s *rport_drv)
-{
- bfa_trc(port->fcs, *pwwn);
-
- return BFA_STATUS_OK;
-}
-
-/*
- * Direct API to remove a target and its associated resources. This
- * interface is used, for example, by driver to remove target
- * ports from the target list for a VM.
- */
-bfa_status_t
-bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
-{
-
- struct bfa_fcs_rport_s *rport;
-
- bfa_trc(rport_in->fcs, rport_in->pwwn);
-
- rport = bfa_fcs_lport_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
- if (rport == NULL) {
- /*
- * TBD Error handling
- */
- bfa_trc(rport_in->fcs, rport_in->pid);
- return BFA_STATUS_UNKNOWN_RWWN;
- }
-
- /*
- * TBD if this remote port is online, send a logo
- */
- return BFA_STATUS_OK;
-
-}
-
-/*
- * Remote device status for display/debug.
- */
-void
-bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
- struct bfa_rport_attr_s *rport_attr)
-{
- struct bfa_rport_qos_attr_s qos_attr;
- bfa_fcs_lport_t *port = rport->port;
- bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
-
- memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
-
- rport_attr->pid = rport->pid;
- rport_attr->pwwn = rport->pwwn;
- rport_attr->nwwn = rport->nwwn;
- rport_attr->cos_supported = rport->fc_cos;
- rport_attr->df_sz = rport->maxfrsize;
- rport_attr->state = bfa_fcs_rport_get_state(rport);
- rport_attr->fc_cos = rport->fc_cos;
- rport_attr->cisc = rport->cisc;
- rport_attr->scsi_function = rport->scsi_function;
- rport_attr->curr_speed = rport->rpf.rpsc_speed;
- rport_attr->assigned_speed = rport->rpf.assigned_speed;
-
- bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
- rport_attr->qos_attr = qos_attr;
-
- rport_attr->trl_enforced = BFA_FALSE;
- if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
- if (rport_speed == BFA_PORT_SPEED_UNKNOWN) {
- /* Use default ratelim speed setting */
- rport_speed =
- bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
- }
-
- if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
- rport_attr->trl_enforced = BFA_TRUE;
- }
-}
-
-/*
- * Per remote device statistics.
- */
-void
-bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
- struct bfa_rport_stats_s *stats)
-{
- *stats = rport->stats;
-}
-
-void
-bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
-{
- memset((char *)&rport->stats, 0,
- sizeof(struct bfa_rport_stats_s));
-}
-
struct bfa_fcs_rport_s *
bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
{
@@ -2752,22 +2572,6 @@ bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
}
/*
- * This API is to set the Rport's speed. Should be used when RPSC is not
- * supported by the rport.
- */
-void
-bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, bfa_port_speed_t speed)
-{
- rport->rpf.assigned_speed = speed;
-
- /* Set this speed in f/w only if the RPSC speed is not available */
- if (rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
- bfa_rport_speed(rport->bfa_rport, speed);
-}
-
-
-
-/*
* Remote port features (RPF) implementation.
*/
@@ -2827,7 +2631,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
case RPFSM_EVENT_RPORT_ONLINE:
/* Send RPSC2 to a Brocade fabric only. */
if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
- ((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) ||
+ ((rport->port->fabric->lps->brcd_switch) ||
(bfa_fcs_fabric_get_switch_oui(fabric) ==
BFA_FCS_BRCD_SWITCH_OUI))) {
bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
@@ -3093,7 +2897,7 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
num_ents = be16_to_cpu(rpsc2_acc->num_pids);
bfa_trc(rport->fcs, num_ents);
if (num_ents > 0) {
- bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
+ WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
bfa_trc(rport->fcs,
be16_to_cpu(rpsc2_acc->port_info[0].pid));
bfa_trc(rport->fcs,
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index d8464ae60070..977e681ec803 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -15,6 +15,7 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_modules.h"
#include "bfi_cbreg.h"
@@ -110,7 +111,7 @@ bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
{
int i;
- bfa_assert((nvecs == 1) || (nvecs == __HFN_NUMINTS));
+ WARN_ON((nvecs != 1) && (nvecs != __HFN_NUMINTS));
bfa->msix.nvecs = nvecs;
if (nvecs == 1) {
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index b0efbc713ffe..21018d98a07b 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -15,6 +15,7 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_modules.h"
#include "bfi_ctreg.h"
@@ -116,7 +117,7 @@ bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
void
bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs)
{
- bfa_assert((nvecs == 1) || (nvecs == BFA_MSIX_CT_MAX));
+ WARN_ON((nvecs != 1) && (nvecs != BFA_MSIX_CT_MAX));
bfa_trc(bfa, nvecs);
bfa->msix.nvecs = nvecs;
@@ -143,7 +144,7 @@ bfa_hwct_msix_install(struct bfa_s *bfa)
for (; i <= BFA_MSIX_RME_Q3; i++)
bfa->msix.handler[i] = bfa_msix_rspq;
- bfa_assert(i == BFA_MSIX_LPU_ERR);
+ WARN_ON(i != BFA_MSIX_LPU_ERR);
bfa->msix.handler[BFA_MSIX_LPU_ERR] = bfa_msix_lpu_err;
}
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 54475b53a5ab..c1f72c49196f 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -15,11 +15,11 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_ioc.h"
#include "bfi_ctreg.h"
#include "bfa_defs.h"
#include "bfa_defs_svc.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(CNA, IOC);
@@ -29,7 +29,7 @@ BFA_TRC_FILE(CNA, IOC);
#define BFA_IOC_TOV 3000 /* msecs */
#define BFA_IOC_HWSEM_TOV 500 /* msecs */
#define BFA_IOC_HB_TOV 500 /* msecs */
-#define BFA_IOC_HWINIT_MAX 2
+#define BFA_IOC_HWINIT_MAX 5
#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
#define bfa_ioc_timer_start(__ioc) \
@@ -42,11 +42,6 @@ BFA_TRC_FILE(CNA, IOC);
bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV)
#define bfa_hb_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->hb_timer)
-#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
-#define BFA_DBG_FWTRC_LEN \
- (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
- (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))
/*
@@ -59,17 +54,16 @@ BFA_TRC_FILE(CNA, IOC);
((__ioc)->ioc_hwif->ioc_firmware_unlock(__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))
-
-#ifdef BFA_IOC_IS_UEFI
-#define bfa_ioc_is_bios_optrom(__ioc) (0)
-#define bfa_ioc_is_uefi(__ioc) BFA_IOC_IS_UEFI
-#else
-#define bfa_ioc_is_bios_optrom(__ioc) \
- (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
-#define bfa_ioc_is_uefi(__ioc) (0)
-#endif
+#define bfa_ioc_notify_fail(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
+#define bfa_ioc_sync_join(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
+#define bfa_ioc_sync_leave(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
+#define bfa_ioc_sync_ack(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
+#define bfa_ioc_sync_complete(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
#define bfa_ioc_mbox_cmd_pending(__ioc) \
(!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
@@ -81,29 +75,22 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE;
* forward declarations
*/
static void bfa_ioc_hw_sem_get(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);
static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
-static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
-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 void bfa_ioc_check_attr_wwns(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);
-static void bfa_ioc_pf_enabled(struct bfa_ioc_s *ioc);
-static void bfa_ioc_pf_disabled(struct bfa_ioc_s *ioc);
-static void bfa_ioc_pf_failed(struct bfa_ioc_s *ioc);
+static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
+static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
-/*
- * hal_ioc_sm
- */
/*
* IOC state machine definitions/declarations
@@ -116,10 +103,11 @@ enum ioc_event {
IOC_E_ENABLED = 5, /* f/w enabled */
IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */
IOC_E_DISABLED = 7, /* f/w disabled */
- IOC_E_FAILED = 8, /* failure notice by iocpf sm */
- IOC_E_HBFAIL = 9, /* heartbeat failure */
- IOC_E_HWERROR = 10, /* hardware error interrupt */
- IOC_E_TIMEOUT = 11, /* timeout */
+ IOC_E_INITFAILED = 8, /* failure notice by iocpf sm */
+ IOC_E_PFFAILED = 9, /* failure notice by iocpf sm */
+ IOC_E_HBFAIL = 10, /* heartbeat failure */
+ IOC_E_HWERROR = 11, /* hardware error interrupt */
+ IOC_E_TIMEOUT = 12, /* timeout */
};
bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -127,7 +115,7 @@ bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
@@ -138,7 +126,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
{BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
{BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
{BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
- {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
+ {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
{BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
{BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
{BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
@@ -165,12 +153,6 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
/*
* Forward declareations for iocpf state machine
*/
-static void bfa_iocpf_enable(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_disable(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_fail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_initfail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_getattrfail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_stop(struct bfa_ioc_s *ioc);
static void bfa_iocpf_timeout(void *ioc_arg);
static void bfa_iocpf_sem_timeout(void *ioc_arg);
@@ -213,9 +195,14 @@ bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s,
+ enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s,
+ enum iocpf_event);
bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
static struct bfa_sm_table_s iocpf_sm_table[] = {
@@ -226,9 +213,12 @@ static struct bfa_sm_table_s iocpf_sm_table[] = {
{BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
{BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
{BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
+ {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
{BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
+ {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
{BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
{BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
+ {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
{BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
};
@@ -301,7 +291,7 @@ bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
static void
bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
{
- bfa_iocpf_enable(ioc);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
}
/*
@@ -318,13 +308,13 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
break;
- case IOC_E_FAILED:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
- break;
-
+ case IOC_E_PFFAILED:
+ /* !!! fall through !!! */
case IOC_E_HWERROR:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
- bfa_iocpf_initfail(ioc);
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ if (event != IOC_E_PFFAILED)
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
break;
case IOC_E_DISABLE:
@@ -333,7 +323,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
case IOC_E_DETACH:
bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
- bfa_iocpf_stop(ioc);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
break;
case IOC_E_ENABLE:
@@ -367,18 +357,16 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
- case IOC_E_FAILED:
- bfa_ioc_timer_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
break;
-
+ case IOC_E_PFFAILED:
case IOC_E_HWERROR:
bfa_ioc_timer_stop(ioc);
- /* fall through */
-
+ /* !!! fall through !!! */
case IOC_E_TIMEOUT:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
- bfa_iocpf_getattrfail(ioc);
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ if (event != IOC_E_PFFAILED)
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
break;
case IOC_E_DISABLE:
@@ -402,7 +390,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
bfa_ioc_hb_monitor(ioc);
- BFA_LOG(KERN_INFO, bfad, log_level, "IOC enabled\n");
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
}
static void
@@ -415,22 +403,24 @@ bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
break;
case IOC_E_DISABLE:
- bfa_ioc_hb_stop(ioc);
+ bfa_hb_timer_stop(ioc);
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
- case IOC_E_FAILED:
- bfa_ioc_hb_stop(ioc);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- break;
-
+ case IOC_E_PFFAILED:
case IOC_E_HWERROR:
- bfa_ioc_hb_stop(ioc);
+ bfa_hb_timer_stop(ioc);
/* !!! fall through !!! */
-
case IOC_E_HBFAIL:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- bfa_iocpf_fail(ioc);
+ bfa_ioc_fail_notify(ioc);
+
+ if (ioc->iocpf.auto_recover)
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ else
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+
+ if (event != IOC_E_PFFAILED)
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
break;
default:
@@ -443,8 +433,8 @@ static void
bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
{
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
- bfa_iocpf_disable(ioc);
- BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n");
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
}
/*
@@ -466,7 +456,7 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
* after iocpf sm completes failure processing and
* moves to disabled state.
*/
- bfa_iocpf_fail(ioc);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
break;
default:
@@ -499,7 +489,7 @@ bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
case IOC_E_DETACH:
bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
- bfa_iocpf_stop(ioc);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
break;
default:
@@ -509,16 +499,16 @@ bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
static void
-bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
+bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
{
- ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_trc(ioc, 0);
}
/*
- * Hardware initialization failed.
+ * Hardware initialization retry.
*/
static void
-bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
+bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
{
bfa_trc(ioc, event);
@@ -527,11 +517,21 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
break;
- case IOC_E_FAILED:
+ case IOC_E_PFFAILED:
+ case IOC_E_HWERROR:
/*
- * Initialization failure during iocpf init retry.
+ * Initialization retry failed.
*/
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ if (event != IOC_E_PFFAILED)
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
+ break;
+
+ case IOC_E_INITFAILED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+ break;
+
+ case IOC_E_ENABLE:
break;
case IOC_E_DISABLE:
@@ -540,7 +540,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
case IOC_E_DETACH:
bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
- bfa_iocpf_stop(ioc);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
break;
default:
@@ -552,21 +552,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
static void
bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
{
- struct list_head *qe;
- struct bfa_ioc_hbfail_notify_s *notify;
- struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
-
- /*
- * Notify driver and common modules registered for notification.
- */
- ioc->cbfn->hbfail_cbfn(ioc->bfa);
- list_for_each(qe, &ioc->hb_notify_q) {
- notify = (struct bfa_ioc_hbfail_notify_s *) qe;
- notify->cbfn(notify->cbarg);
- }
-
- BFA_LOG(KERN_CRIT, bfad, log_level,
- "Heart Beat of IOC has failed\n");
+ bfa_trc(ioc, 0);
}
/*
@@ -579,23 +565,19 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
switch (event) {
- case IOC_E_FAILED:
- /*
- * Initialization failure during iocpf recovery.
- * !!! Fall through !!!
- */
case IOC_E_ENABLE:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
break;
- case IOC_E_ENABLED:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
- break;
-
case IOC_E_DISABLE:
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
+ case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
+ break;
+
case IOC_E_HWERROR:
/*
* HB failure notification, ignore.
@@ -606,13 +588,10 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
}
}
-
-
/*
* IOCPF State Machine
*/
-
/*
* Reset entry actions -- initialize state machine
*/
@@ -668,22 +647,29 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_SEMLOCKED:
if (bfa_ioc_firmware_lock(ioc)) {
- iocpf->retry_count = 0;
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ if (bfa_ioc_sync_complete(ioc)) {
+ iocpf->retry_count = 0;
+ bfa_ioc_sync_join(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ } else {
+ bfa_ioc_firmware_unlock(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_sem_timer_start(ioc);
+ }
} else {
- bfa_ioc_hw_sem_release(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
}
break;
case IOCPF_E_DISABLE:
- bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_sem_timer_stop(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
- bfa_ioc_pf_disabled(ioc);
+ bfa_fsm_send_event(ioc, IOC_E_DISABLED);
break;
case IOCPF_E_STOP:
- bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_sem_timer_stop(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
@@ -726,7 +712,7 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
case IOCPF_E_DISABLE:
bfa_iocpf_timer_stop(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
- bfa_ioc_pf_disabled(ioc);
+ bfa_fsm_send_event(ioc, IOC_E_DISABLED);
break;
case IOCPF_E_STOP:
@@ -760,13 +746,18 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_SEMLOCKED:
- iocpf->retry_count = 0;
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ if (bfa_ioc_sync_complete(ioc)) {
+ bfa_ioc_sync_join(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ } else {
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_sem_timer_start(ioc);
+ }
break;
case IOCPF_E_DISABLE:
- bfa_ioc_hw_sem_get_cancel(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+ bfa_sem_timer_stop(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
default:
@@ -774,12 +765,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
-
static void
bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
{
bfa_iocpf_timer_start(iocpf->ioc);
- bfa_ioc_reset(iocpf->ioc, BFA_FALSE);
+ bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
}
/*
@@ -806,23 +796,16 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
*/
case IOCPF_E_TIMEOUT:
- iocpf->retry_count++;
- if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
- bfa_iocpf_timer_start(ioc);
- bfa_ioc_reset(ioc, BFA_TRUE);
- break;
- }
-
- bfa_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
if (event == IOCPF_E_TIMEOUT)
- bfa_ioc_pf_failed(ioc);
+ bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
case IOCPF_E_DISABLE:
- bfa_ioc_hw_sem_release(ioc);
bfa_iocpf_timer_stop(ioc);
+ bfa_ioc_sync_leave(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
@@ -831,7 +814,6 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
-
static void
bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
{
@@ -853,7 +835,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_ENABLE:
bfa_iocpf_timer_stop(ioc);
- bfa_ioc_hw_sem_release(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
break;
@@ -864,23 +846,15 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
*/
case IOCPF_E_TIMEOUT:
- iocpf->retry_count++;
- if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
- writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
- break;
- }
-
- bfa_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
if (event == IOCPF_E_TIMEOUT)
- bfa_ioc_pf_failed(ioc);
+ bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
case IOCPF_E_DISABLE:
bfa_iocpf_timer_stop(ioc);
- bfa_ioc_hw_sem_release(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
@@ -893,12 +867,10 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
-
-
static void
bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
{
- bfa_ioc_pf_enabled(iocpf->ioc);
+ bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
}
static void
@@ -914,20 +886,21 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
break;
case IOCPF_E_GETATTRFAIL:
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
case IOCPF_E_FAIL:
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
break;
case IOCPF_E_FWREADY:
- if (bfa_ioc_is_operational(ioc))
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
- else
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
- bfa_ioc_pf_failed(ioc);
+ if (bfa_ioc_is_operational(ioc)) {
+ bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
+ } else {
+ bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
+ }
break;
default:
@@ -935,7 +908,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
-
static void
bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
{
@@ -957,7 +929,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
case IOCPF_E_FWRSP_DISABLE:
case IOCPF_E_FWREADY:
bfa_iocpf_timer_stop(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
case IOCPF_E_FAIL:
@@ -968,7 +940,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
case IOCPF_E_TIMEOUT:
writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
case IOCPF_E_FWRSP_ENABLE:
@@ -979,13 +951,44 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
+static void
+bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf)
+{
+ bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/*
+ * IOC hb ack request is being removed.
+ */
+static void
+bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc_s *ioc = iocpf->ioc;
+
+ bfa_trc(ioc, event);
+
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ bfa_ioc_sync_leave(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+ break;
+
+ case IOCPF_E_FAIL:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
/*
* IOC disable completion entry.
*/
static void
bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
{
- bfa_ioc_pf_disabled(iocpf->ioc);
+ bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
}
static void
@@ -997,6 +1000,7 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_ENABLE:
+ iocpf->retry_count = 0;
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
break;
@@ -1010,11 +1014,64 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
}
}
+static void
+bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
+{
+ bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/*
+ * Hardware initialization failed.
+ */
+static void
+bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc_s *ioc = iocpf->ioc;
+
+ bfa_trc(ioc, event);
+
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ bfa_ioc_notify_fail(ioc);
+ bfa_ioc_sync_ack(ioc);
+ iocpf->retry_count++;
+ if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
+ bfa_ioc_sync_leave(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+ } else {
+ if (bfa_ioc_sync_complete(ioc))
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ else {
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+ }
+ }
+ break;
+
+ case IOCPF_E_DISABLE:
+ bfa_sem_timer_stop(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+ break;
+
+ case IOCPF_E_STOP:
+ bfa_sem_timer_stop(ioc);
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+ break;
+
+ case IOCPF_E_FAIL:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
static void
bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
{
- bfa_iocpf_timer_start(iocpf->ioc);
+ bfa_fsm_send_event(iocpf->ioc, IOC_E_INITFAILED);
}
/*
@@ -1029,47 +1086,77 @@ bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_DISABLE:
- bfa_iocpf_timer_stop(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
case IOCPF_E_STOP:
- bfa_iocpf_timer_stop(ioc);
bfa_ioc_firmware_unlock(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
- case IOCPF_E_TIMEOUT:
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
- break;
-
default:
bfa_sm_fault(ioc, event);
}
}
-
static void
-bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
+bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf)
{
/*
* Mark IOC as failed in hardware and stop firmware.
*/
bfa_ioc_lpu_stop(iocpf->ioc);
- writel(BFI_IOC_FAIL, iocpf->ioc->ioc_regs.ioc_fwstate);
-
- /*
- * Notify other functions on HB failure.
- */
- bfa_ioc_notify_hbfail(iocpf->ioc);
/*
* Flush any queued up mailbox requests.
*/
bfa_ioc_mbox_hbfail(iocpf->ioc);
- if (iocpf->auto_recover)
- bfa_iocpf_recovery_timer_start(iocpf->ioc);
+ bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+static void
+bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+ struct bfa_ioc_s *ioc = iocpf->ioc;
+
+ bfa_trc(ioc, event);
+
+ switch (event) {
+ case IOCPF_E_SEMLOCKED:
+ iocpf->retry_count = 0;
+ bfa_ioc_sync_ack(ioc);
+ bfa_ioc_notify_fail(ioc);
+ if (!iocpf->auto_recover) {
+ bfa_ioc_sync_leave(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ } else {
+ if (bfa_ioc_sync_complete(ioc))
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+ else {
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+ }
+ }
+ break;
+
+ case IOCPF_E_DISABLE:
+ bfa_sem_timer_stop(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+ break;
+
+ case IOCPF_E_FAIL:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
+{
}
/*
@@ -1084,24 +1171,16 @@ bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_DISABLE:
- if (iocpf->auto_recover)
- bfa_iocpf_timer_stop(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
- case IOCPF_E_TIMEOUT:
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
- break;
-
default:
bfa_sm_fault(ioc, event);
}
}
-
-
/*
- * hal_ioc_pvt BFA IOC private functions
+ * BFA IOC private functions
*/
static void
@@ -1139,16 +1218,10 @@ bfa_ioc_sem_get(void __iomem *sem_reg)
if (r32 == 0)
return BFA_TRUE;
- bfa_assert(cnt < BFA_SEM_SPINCNT);
+ WARN_ON(cnt >= BFA_SEM_SPINCNT);
return BFA_FALSE;
}
-void
-bfa_ioc_sem_release(void __iomem *sem_reg)
-{
- writel(1, sem_reg);
-}
-
static void
bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
{
@@ -1167,18 +1240,6 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
bfa_sem_timer_start(ioc);
}
-void
-bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
-{
- writel(1, ioc->ioc_regs.ioc_sem_reg);
-}
-
-static void
-bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
-{
- bfa_sem_timer_stop(ioc);
-}
-
/*
* Initialize LPU local memory (aka secondary memory / SRAM)
*/
@@ -1212,7 +1273,7 @@ bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
* If memory initialization is not successful, IOC timeout will catch
* such failures.
*/
- bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
+ WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
bfa_trc(ioc, pss_ctl);
pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
@@ -1258,8 +1319,8 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
int i;
u32 *fwsig = (u32 *) fwhdr;
- pgnum = bfa_ioc_smem_pgnum(ioc, loff);
- pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+ pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+ pgoff = PSS_SMEM_PGOFF(loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
@@ -1304,12 +1365,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
{
struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
- /*
- * If bios/efi boot (flash based) -- return true
- */
- if (bfa_ioc_is_bios_optrom(ioc))
- return BFA_TRUE;
-
bfa_ioc_fwver_get(ioc, &fwhdr);
drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
@@ -1342,7 +1397,6 @@ bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
writel(1, ioc->ioc_regs.lpu_mbox_cmd);
}
-
static void
bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
{
@@ -1362,22 +1416,6 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
boot_env = BFI_BOOT_LOADER_OS;
/*
- * Flash based firmware boot BIOS env.
- */
- if (bfa_ioc_is_bios_optrom(ioc)) {
- boot_type = BFI_BOOT_TYPE_FLASH;
- boot_env = BFI_BOOT_LOADER_BIOS;
- }
-
- /*
- * Flash based firmware boot UEFI env.
- */
- if (bfa_ioc_is_uefi(ioc)) {
- boot_type = BFI_BOOT_TYPE_FLASH;
- boot_env = BFI_BOOT_LOADER_UEFI;
- }
-
- /*
* check if firmware is valid
*/
fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
@@ -1405,8 +1443,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
* convergence, IOC will be in operational state when 2nd driver
* is loaded.
*/
- if (ioc_fwstate == BFI_IOC_DISABLED ||
- (!bfa_ioc_is_bios_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
+ if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
/*
* When using MSI-X any pending firmware ready event should
@@ -1442,7 +1479,7 @@ bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
bfa_trc(ioc, msgp[0]);
bfa_trc(ioc, len);
- bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
+ WARN_ON(len > BFI_IOC_MSGLEN_MAX);
/*
* first write msg to mailbox registers
@@ -1465,12 +1502,12 @@ static void
bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
{
struct bfi_ioc_ctrl_req_s enable_req;
- struct bfa_timeval_s tv;
+ struct timeval tv;
bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
bfa_ioc_portid(ioc));
enable_req.ioc_class = ioc->ioc_mc;
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
enable_req.tv_sec = be32_to_cpu(tv.tv_sec);
bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
}
@@ -1504,7 +1541,6 @@ bfa_ioc_hb_check(void *cbarg)
hb_count = readl(ioc->ioc_regs.heartbeat);
if (ioc->hb_count == hb_count) {
- printk(KERN_CRIT "Firmware heartbeat failure at %d", hb_count);
bfa_ioc_recover(ioc);
return;
} else {
@@ -1522,13 +1558,6 @@ bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
bfa_hb_timer_start(ioc);
}
-static void
-bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
-{
- bfa_hb_timer_stop(ioc);
-}
-
-
/*
* Initiate a full firmware download.
*/
@@ -1550,8 +1579,8 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
bfa_trc(ioc, bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)));
fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
- pgnum = bfa_ioc_smem_pgnum(ioc, loff);
- pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+ pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+ pgoff = PSS_SMEM_PGOFF(loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
@@ -1581,7 +1610,8 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
}
}
- writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+ writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+ ioc->ioc_regs.host_page_num_fn);
/*
* Set boot type and boot param at the end.
@@ -1592,11 +1622,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
swab32(boot_env));
}
-static void
-bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
-{
- bfa_ioc_hwinit(ioc, force);
-}
/*
* Update BFA configuration from firmware configuration.
@@ -1683,12 +1708,13 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
static bfa_status_t
bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
{
- u32 pgnum, loff, r32;
+ u32 pgnum, loff;
+ __be32 r32;
int i, len;
u32 *buf = tbuf;
- pgnum = bfa_ioc_smem_pgnum(ioc, soff);
- loff = bfa_ioc_smem_pgoff(ioc, soff);
+ pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
+ loff = PSS_SMEM_PGOFF(soff);
bfa_trc(ioc, pgnum);
bfa_trc(ioc, loff);
bfa_trc(ioc, sz);
@@ -1719,11 +1745,12 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
}
}
- writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+ writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+ ioc->ioc_regs.host_page_num_fn);
/*
* release semaphore.
*/
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
bfa_trc(ioc, pgnum);
return BFA_STATUS_OK;
@@ -1742,8 +1769,8 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
int i, len;
u32 pgnum, loff;
- pgnum = bfa_ioc_smem_pgnum(ioc, soff);
- loff = bfa_ioc_smem_pgoff(ioc, soff);
+ pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
+ loff = PSS_SMEM_PGOFF(soff);
bfa_trc(ioc, pgnum);
bfa_trc(ioc, loff);
bfa_trc(ioc, sz);
@@ -1773,35 +1800,38 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
}
}
- writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+ writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+ ioc->ioc_regs.host_page_num_fn);
/*
* release semaphore.
*/
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
bfa_trc(ioc, pgnum);
return BFA_STATUS_OK;
}
-/*
- * hal iocpf to ioc interface
- */
static void
-bfa_ioc_pf_enabled(struct bfa_ioc_s *ioc)
+bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
{
- bfa_fsm_send_event(ioc, IOC_E_ENABLED);
-}
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify_s *notify;
+ struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
-static void
-bfa_ioc_pf_disabled(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(ioc, IOC_E_DISABLED);
-}
+ /*
+ * Notify driver and common modules registered for notification.
+ */
+ ioc->cbfn->hbfail_cbfn(ioc->bfa);
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify_s *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+
+ bfa_ioc_debug_save_ftrc(ioc);
+
+ BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
+ "Heart Beat of IOC has failed\n");
-static void
-bfa_ioc_pf_failed(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(ioc, IOC_E_FAILED);
}
static void
@@ -1812,17 +1842,11 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
* Provide enable completion callback.
*/
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
- BFA_LOG(KERN_WARNING, bfad, log_level,
+ BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
"Running firmware version is incompatible "
"with the driver version\n");
}
-
-
-/*
- * hal_ioc_public
- */
-
bfa_status_t
bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
{
@@ -1838,7 +1862,7 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
/*
* release semaphore.
*/
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
return BFA_STATUS_OK;
}
@@ -1909,7 +1933,7 @@ bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
void
bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
{
- u32 *msgp = mbmsg;
+ __be32 *msgp = mbmsg;
u32 r32;
int i;
@@ -1962,7 +1986,7 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
default:
bfa_trc(ioc, msg->mh.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -2043,15 +2067,6 @@ bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
}
-/*
- * Return size of dma memory required.
- */
-u32
-bfa_ioc_meminfo(void)
-{
- return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
-}
-
void
bfa_ioc_enable(struct bfa_ioc_s *ioc)
{
@@ -2068,18 +2083,6 @@ bfa_ioc_disable(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_DISABLE);
}
-/*
- * Returns memory required for saving firmware trace in case of crash.
- * Driver must call this interface to allocate memory required for
- * automatic saving of firmware trace. Driver should call
- * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
- * trace memory.
- */
-int
-bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
-{
- return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
-}
/*
* Initialize memory for saving firmware trace. Driver must initialize
@@ -2089,19 +2092,7 @@ void
bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
{
ioc->dbg_fwsave = dbg_fwsave;
- ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->iocpf.auto_recover);
-}
-
-u32
-bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
-{
- return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
-}
-
-u32
-bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
-{
- return PSS_SMEM_PGOFF(fmaddr);
+ ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
}
/*
@@ -2265,14 +2256,13 @@ bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
}
/*
- * Add to IOC heartbeat failure notification queue. To be used by common
- * modules such as cee, port, diag.
+ * Reset IOC fwstate registers.
*/
void
-bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
- struct bfa_ioc_hbfail_notify_s *notify)
+bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
{
- list_add_tail(&notify->qe, &ioc->hb_notify_q);
+ writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+ writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
}
#define BFA_MFG_NAME "Brocade"
@@ -2306,7 +2296,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
else
ad_attr->prototype = 0;
- ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
+ ad_attr->pwwn = ioc->attr->pwwn;
ad_attr->mac = bfa_ioc_get_mac(ioc);
ad_attr->pcie_gen = ioc_attr->pcie_gen;
@@ -2317,7 +2307,8 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
ad_attr->cna_capable = ioc->cna;
- ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
+ ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna &&
+ !ad_attr->is_mezz;
}
enum bfa_ioc_type_e
@@ -2330,7 +2321,7 @@ bfa_ioc_get_type(struct bfa_ioc_s *ioc)
else if (ioc->ioc_mc == BFI_MC_LL)
return BFA_IOC_TYPE_LL;
else {
- bfa_assert(ioc->ioc_mc == BFI_MC_LL);
+ WARN_ON(ioc->ioc_mc != BFI_MC_LL);
return BFA_IOC_TYPE_LL;
}
}
@@ -2354,7 +2345,7 @@ bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
void
bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
{
- bfa_assert(chip_rev);
+ WARN_ON(!chip_rev);
memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
@@ -2386,7 +2377,7 @@ bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
{
struct bfi_ioc_attr_s *ioc_attr;
- bfa_assert(model);
+ WARN_ON(!model);
memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
ioc_attr = ioc->attr;
@@ -2455,27 +2446,6 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
}
-/*
- * hal_wwn_public
- */
-wwn_t
-bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
-{
- return ioc->attr->pwwn;
-}
-
-wwn_t
-bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
-{
- return ioc->attr->nwwn;
-}
-
-u64
-bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
-{
- return ioc->attr->mfg_pwwn;
-}
-
mac_t
bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
{
@@ -2488,18 +2458,6 @@ bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
return ioc->attr->mac;
}
-wwn_t
-bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc)
-{
- return ioc->attr->mfg_pwwn;
-}
-
-wwn_t
-bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc)
-{
- return ioc->attr->mfg_nwwn;
-}
-
mac_t
bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
{
@@ -2541,14 +2499,6 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
return BFA_STATUS_OK;
}
-/*
- * 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.
@@ -2701,13 +2651,16 @@ bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
* Save firmware trace if configured.
*/
static void
-bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
+bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
{
int tlen;
- if (ioc->dbg_fwsave_len) {
- tlen = ioc->dbg_fwsave_len;
- bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
+ if (ioc->dbg_fwsave_once) {
+ ioc->dbg_fwsave_once = BFA_FALSE;
+ if (ioc->dbg_fwsave_len) {
+ tlen = ioc->dbg_fwsave_len;
+ bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
+ }
}
}
@@ -2717,11 +2670,6 @@ bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
static void
bfa_ioc_recover(struct bfa_ioc_s *ioc)
{
- if (ioc->dbg_fwsave_once) {
- ioc->dbg_fwsave_once = BFA_FALSE;
- bfa_ioc_debug_save(ioc);
- }
-
bfa_ioc_stats(ioc, ioc_hbfails);
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
}
@@ -2734,45 +2682,8 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
}
/*
- * hal_iocpf_pvt BFA IOC PF private functions
+ * BFA IOC PF private functions
*/
-
-static void
-bfa_iocpf_enable(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
-}
-
-static void
-bfa_iocpf_disable(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
-}
-
-static void
-bfa_iocpf_fail(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
-}
-
-static void
-bfa_iocpf_initfail(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
-}
-
-static void
-bfa_iocpf_getattrfail(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
-}
-
-static void
-bfa_iocpf_stop(struct bfa_ioc_s *ioc)
-{
- bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
-}
-
static void
bfa_iocpf_timeout(void *ioc_arg)
{
@@ -2794,12 +2705,6 @@ bfa_iocpf_sem_timeout(void *ioc_arg)
* bfa timer function
*/
void
-bfa_timer_init(struct bfa_timer_mod_s *mod)
-{
- INIT_LIST_HEAD(&mod->timer_q);
-}
-
-void
bfa_timer_beat(struct bfa_timer_mod_s *mod)
{
struct list_head *qh = &mod->timer_q;
@@ -2843,8 +2748,8 @@ bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
void (*timercb) (void *), void *arg, unsigned int timeout)
{
- bfa_assert(timercb != NULL);
- bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer));
+ WARN_ON(timercb == NULL);
+ WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer));
timer->timeout = timeout;
timer->timercb = timercb;
@@ -2859,7 +2764,7 @@ bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
void
bfa_timer_stop(struct bfa_timer_s *timer)
{
- bfa_assert(!list_empty(&timer->qe));
+ WARN_ON(list_empty(&timer->qe));
list_del(&timer->qe);
}
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 9c407a87a1a1..ec9cf08b0e7f 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -18,10 +18,15 @@
#ifndef __BFA_IOC_H__
#define __BFA_IOC_H__
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#include "bfa_cs.h"
#include "bfi.h"
+#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
+#define BFA_DBG_FWTRC_LEN \
+ (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
+ (sizeof(struct bfa_trc_mod_s) - \
+ BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
/*
* BFA timer declarations
*/
@@ -47,7 +52,6 @@ struct bfa_timer_mod_s {
#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);
void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
bfa_timer_cbfn_t timercb, void *arg,
unsigned int timeout);
@@ -70,7 +74,7 @@ struct bfa_sge_s {
#define bfa_swap_words(_x) ( \
((_x) << 32) | ((_x) >> 32))
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
#define bfa_sge_to_be(_x)
#define bfa_sge_to_le(_x) bfa_sge_word_swap(_x)
#define bfa_sgaddr_le(_x) bfa_swap_words(_x)
@@ -115,8 +119,8 @@ struct bfa_dma_s {
static inline void
__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
{
- dma_addr->a32.addr_lo = (u32) pa;
- dma_addr->a32.addr_hi = (u32) (bfa_os_u32(pa));
+ dma_addr->a32.addr_lo = (__be32) pa;
+ dma_addr->a32.addr_hi = (__be32) (pa >> 32);
}
@@ -125,8 +129,8 @@ __bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
static inline void
__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
{
- dma_addr->a32.addr_lo = (u32) cpu_to_be32(pa);
- dma_addr->a32.addr_hi = (u32) cpu_to_be32(bfa_os_u32(pa));
+ dma_addr->a32.addr_lo = cpu_to_be32(pa);
+ dma_addr->a32.addr_hi = cpu_to_be32(pa >> 32);
}
struct bfa_ioc_regs_s {
@@ -145,8 +149,11 @@ struct bfa_ioc_regs_s {
void __iomem *host_page_num_fn;
void __iomem *heartbeat;
void __iomem *ioc_fwstate;
+ void __iomem *alt_ioc_fwstate;
void __iomem *ll_halt;
+ void __iomem *alt_ll_halt;
void __iomem *err_set;
+ void __iomem *ioc_fail_sync;
void __iomem *shirq_isr_next;
void __iomem *shirq_msk_next;
void __iomem *smem_page_start;
@@ -254,8 +261,12 @@ struct bfa_ioc_hwif_s {
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_notify_fail) (struct bfa_ioc_s *ioc);
void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc);
+ void (*ioc_sync_join) (struct bfa_ioc_s *ioc);
+ void (*ioc_sync_leave) (struct bfa_ioc_s *ioc);
+ void (*ioc_sync_ack) (struct bfa_ioc_s *ioc);
+ bfa_boolean_t (*ioc_sync_complete) (struct bfa_ioc_s *ioc);
};
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -325,7 +336,6 @@ void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
void bfa_ioc_detach(struct bfa_ioc_s *ioc);
void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
enum bfi_mclass mc);
-u32 bfa_ioc_meminfo(void);
void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa);
void bfa_ioc_enable(struct bfa_ioc_s *ioc);
void bfa_ioc_disable(struct bfa_ioc_s *ioc);
@@ -340,6 +350,7 @@ bfa_boolean_t bfa_ioc_is_initialized(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_reset_fwstate(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);
@@ -353,24 +364,16 @@ 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);
-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);
bfa_status_t bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
u32 *offset, int *buflen);
-u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
-u32 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr);
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(void __iomem *sem_reg);
-void bfa_ioc_sem_release(void __iomem *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,
@@ -381,13 +384,8 @@ bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc);
/*
* bfa mfg wwn API functions
*/
-wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc);
mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc);
-u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
/*
* F/W Image Size & Chunk
@@ -421,7 +419,7 @@ bfa_cb_image_get_chunk(int type, u32 off)
return bfi_image_ct_cna_get_chunk(off); break;
case BFI_IMAGE_CB_FC:
return bfi_image_cb_fc_get_chunk(off); break;
- default: return 0;
+ default: return NULL;
}
}
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
index 909945043850..e4a0713185b6 100644
--- a/drivers/scsi/bfa/bfa_ioc_cb.c
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -15,6 +15,7 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_ioc.h"
#include "bfi_cbreg.h"
#include "bfa_defs.h"
@@ -29,10 +30,14 @@ static void bfa_ioc_cb_firmware_unlock(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_notify_fail(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_cb;
+static struct bfa_ioc_hwif_s hwif_cb;
/*
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -46,8 +51,12 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init;
hwif_cb.ioc_map_port = bfa_ioc_cb_map_port;
hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
- hwif_cb.ioc_notify_hbfail = bfa_ioc_cb_notify_hbfail;
+ hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail;
hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
+ hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join;
+ hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave;
+ hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack;
+ hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete;
ioc->ioc_hwif = &hwif_cb;
}
@@ -58,6 +67,21 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
static bfa_boolean_t
bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
{
+ struct bfi_ioc_image_hdr_s fwhdr;
+ uint32_t fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ if (fwstate == BFI_IOC_UNINIT)
+ return BFA_TRUE;
+
+ bfa_ioc_fwver_get(ioc, &fwhdr);
+
+ if (swab32(fwhdr.exec) == BFI_BOOT_TYPE_NORMAL)
+ return BFA_TRUE;
+
+ bfa_trc(ioc, fwstate);
+ bfa_trc(ioc, fwhdr.exec);
+ writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+
return BFA_TRUE;
}
@@ -70,7 +94,7 @@ 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_ioc_cb_notify_fail(struct bfa_ioc_s *ioc)
{
writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
readl(ioc->ioc_regs.err_set);
@@ -108,9 +132,11 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
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.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
} else {
ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.alt_ioc_fwstate = (rb + BFA_IOC0_STATE_REG);
}
/*
@@ -181,10 +207,71 @@ bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
* will lock it instead of clearing it.
*/
readl(ioc->ioc_regs.ioc_sem_reg);
- bfa_ioc_hw_sem_release(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
}
+/*
+ * Synchronized IOC failure processing routines
+ */
+static void
+bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc)
+{
+}
+static void
+bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc)
+{
+}
+
+static void
+bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc)
+{
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+}
+
+static bfa_boolean_t
+bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc)
+{
+ uint32_t fwstate, alt_fwstate;
+ fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ /*
+ * At this point, this IOC is hoding the hw sem in the
+ * start path (fwcheck) OR in the disable/enable path
+ * OR to check if the other IOC has acknowledged failure.
+ *
+ * So, this IOC can be in UNINIT, INITING, DISABLED, FAIL
+ * or in MEMTEST states. In a normal scenario, this IOC
+ * can not be in OP state when this function is called.
+ *
+ * However, this IOC could still be in OP state when
+ * the OS driver is starting up, if the OptROM code has
+ * left it in that state.
+ *
+ * If we had marked this IOC's fwstate as BFI_IOC_FAIL
+ * in the failure case and now, if the fwstate is not
+ * BFI_IOC_FAIL it implies that the other PCI fn have
+ * reinitialized the ASIC or this IOC got disabled, so
+ * return TRUE.
+ */
+ if (fwstate == BFI_IOC_UNINIT ||
+ fwstate == BFI_IOC_INITING ||
+ fwstate == BFI_IOC_DISABLED ||
+ fwstate == BFI_IOC_MEMTEST ||
+ fwstate == BFI_IOC_OP)
+ return BFA_TRUE;
+ else {
+ alt_fwstate = readl(ioc->ioc_regs.alt_ioc_fwstate);
+ if (alt_fwstate == BFI_IOC_FAIL ||
+ alt_fwstate == BFI_IOC_DISABLED ||
+ alt_fwstate == BFI_IOC_UNINIT ||
+ alt_fwstate == BFI_IOC_INITING ||
+ alt_fwstate == BFI_IOC_MEMTEST)
+ return BFA_TRUE;
+ else
+ return BFA_FALSE;
+ }
+}
bfa_status_t
bfa_ioc_cb_pll_init(void __iomem *rb, bfa_boolean_t fcmode)
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 115730c0aa77..008d129ddfcd 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -15,12 +15,22 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_ioc.h"
#include "bfi_ctreg.h"
#include "bfa_defs.h"
BFA_TRC_FILE(CNA, IOC_CT);
+#define bfa_ioc_ct_sync_pos(__ioc) \
+ ((uint32_t) (1 << bfa_ioc_pcifn(__ioc)))
+#define BFA_IOC_SYNC_REQD_SH 16
+#define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff)
+#define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000)
+#define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH)
+#define bfa_ioc_ct_sync_reqd_pos(__ioc) \
+ (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH)
+
/*
* forward declarations
*/
@@ -29,10 +39,14 @@ static void bfa_ioc_ct_firmware_unlock(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_notify_fail(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_ct;
+static struct bfa_ioc_hwif_s hwif_ct;
/*
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -46,8 +60,12 @@ bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
- hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail;
hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+ hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join;
+ hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave;
+ hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack;
+ hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete;
ioc->ioc_hwif = &hwif_ct;
}
@@ -83,7 +101,8 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
*/
if (usecnt == 0) {
writel(1, ioc->ioc_regs.ioc_usage_reg);
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_fail_sync);
bfa_trc(ioc, usecnt);
return BFA_TRUE;
}
@@ -94,14 +113,14 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
/*
* Use count cannot be non-zero and chip in uninitialized state.
*/
- bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+ WARN_ON(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);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
bfa_trc(ioc, usecnt);
return BFA_FALSE;
}
@@ -111,7 +130,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
*/
usecnt++;
writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
bfa_trc(ioc, usecnt);
return BFA_TRUE;
}
@@ -139,25 +158,27 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
- bfa_assert(usecnt > 0);
+ WARN_ON(usecnt <= 0);
usecnt--;
writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
bfa_trc(ioc, usecnt);
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, 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)
+bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc)
{
if (ioc->cna) {
writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+ writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
/* Wait for halt to take effect */
readl(ioc->ioc_regs.ll_halt);
+ readl(ioc->ioc_regs.alt_ll_halt);
} else {
writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
readl(ioc->ioc_regs.err_set);
@@ -209,15 +230,19 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
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.alt_ioc_fwstate = rb + BFA_IOC1_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;
+ ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
} else {
ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_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;
+ ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
}
/*
@@ -235,6 +260,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
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);
+ ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC);
/*
* sram memory access
@@ -313,7 +339,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
if (ioc->cna) {
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
writel(0, ioc->ioc_regs.ioc_usage_reg);
- bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
}
/*
@@ -322,10 +348,80 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
* will lock it instead of clearing it.
*/
readl(ioc->ioc_regs.ioc_sem_reg);
- bfa_ioc_hw_sem_release(ioc);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+}
+
+/*
+ * Synchronized IOC failure processing routines
+ */
+static void
+bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc)
+{
+ uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ uint32_t sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc);
+
+ writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static void
+bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc)
+{
+ uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ uint32_t sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) |
+ bfa_ioc_ct_sync_pos(ioc);
+
+ writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static void
+bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc)
+{
+ uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+
+ writel((r32 | bfa_ioc_ct_sync_pos(ioc)),
+ ioc->ioc_regs.ioc_fail_sync);
}
+static bfa_boolean_t
+bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc)
+{
+ uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+ uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
+ uint32_t sync_ackd = bfa_ioc_ct_get_sync_ackd(r32);
+ uint32_t tmp_ackd;
+
+ if (sync_ackd == 0)
+ return BFA_TRUE;
+
+ /*
+ * The check below is to see whether any other PCI fn
+ * has reinitialized the ASIC (reset sync_ackd bits)
+ * and failed again while this IOC was waiting for hw
+ * semaphore (in bfa_iocpf_sm_semwait()).
+ */
+ tmp_ackd = sync_ackd;
+ if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) &&
+ !(sync_ackd & bfa_ioc_ct_sync_pos(ioc)))
+ sync_ackd |= bfa_ioc_ct_sync_pos(ioc);
+
+ if (sync_reqd == sync_ackd) {
+ writel(bfa_ioc_ct_clear_sync_ackd(r32),
+ ioc->ioc_regs.ioc_fail_sync);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate);
+ return BFA_TRUE;
+ }
+
+ /*
+ * If another PCI fn reinitialized and failed again while
+ * this IOC was waiting for hw sem, the sync_ackd bit for
+ * this IOC need to be set again to allow reinitialization.
+ */
+ if (tmp_ackd != sync_ackd)
+ writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync);
+ return BFA_FALSE;
+}
/*
* Check the firmware state to know if pll_init has been completed already
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h
index 15407ab39e77..ab79ff6fdeea 100644
--- a/drivers/scsi/bfa/bfa_modules.h
+++ b/drivers/scsi/bfa/bfa_modules.h
@@ -99,7 +99,6 @@ struct bfa_module_s {
void (*iocdisable) (struct bfa_s *bfa);
};
-extern struct bfa_module_s *hal_mods[];
struct bfa_s {
void *bfad; /* BFA driver instance */
@@ -116,8 +115,6 @@ struct bfa_s {
struct bfa_msix_s msix;
};
-extern bfa_isr_func_t bfa_isrs[BFI_MC_MAX];
-extern bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[];
extern bfa_boolean_t bfa_auto_recover;
extern struct bfa_module_s hal_mod_sgpg;
extern struct bfa_module_s hal_mod_fcport;
diff --git a/drivers/scsi/bfa/bfa_os_inc.h b/drivers/scsi/bfa/bfa_os_inc.h
deleted file mode 100644
index 65df62ef437f..000000000000
--- a/drivers/scsi/bfa/bfa_os_inc.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2005-2010 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_OS_INC_H__
-#define __BFA_OS_INC_H__
-
-#include <linux/types.h>
-#include <linux/version.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/idr.h>
-#include <linux/interrupt.h>
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/workqueue.h>
-#include <linux/bitops.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_transport_fc.h>
-#include <scsi/scsi_transport.h>
-
-#ifdef __BIG_ENDIAN
-#define __BIGENDIAN
-#endif
-
-static inline u64 bfa_os_get_log_time(void)
-{
- u64 system_time = 0;
- struct timeval tv;
- do_gettimeofday(&tv);
-
- /* We are interested in seconds only. */
- system_time = tv.tv_sec;
- return system_time;
-}
-
-#define bfa_io_lat_clock_res_div HZ
-#define bfa_io_lat_clock_res_mul 1000
-
-#define BFA_LOG(level, bfad, mask, fmt, arg...) \
-do { \
- if (((mask) == 4) || (level[1] <= '4')) \
- dev_printk(level, &((bfad)->pcidev)->dev, fmt, ##arg); \
-} while (0)
-
-#define bfa_swap_3b(_x) \
- ((((_x) & 0xff) << 16) | \
- ((_x) & 0x00ff00) | \
- (((_x) & 0xff0000) >> 16))
-
-#define bfa_os_swap_sgaddr(_x) ((u64)( \
- (((u64)(_x) & (u64)0x00000000000000ffull) << 32) | \
- (((u64)(_x) & (u64)0x000000000000ff00ull) << 32) | \
- (((u64)(_x) & (u64)0x0000000000ff0000ull) << 32) | \
- (((u64)(_x) & (u64)0x00000000ff000000ull) << 32) | \
- (((u64)(_x) & (u64)0x000000ff00000000ull) >> 32) | \
- (((u64)(_x) & (u64)0x0000ff0000000000ull) >> 32) | \
- (((u64)(_x) & (u64)0x00ff000000000000ull) >> 32) | \
- (((u64)(_x) & (u64)0xff00000000000000ull) >> 32)))
-
-#ifndef __BIGENDIAN
-#define bfa_os_hton3b(_x) bfa_swap_3b(_x)
-#define bfa_os_sgaddr(_x) (_x)
-#else
-#define bfa_os_hton3b(_x) (_x)
-#define bfa_os_sgaddr(_x) bfa_os_swap_sgaddr(_x)
-#endif
-
-#define bfa_os_ntoh3b(_x) bfa_os_hton3b(_x)
-#define bfa_os_u32(__pa64) ((__pa64) >> 32)
-
-#define BFA_TRC_TS(_trcm) \
- ({ \
- struct timeval tv; \
- \
- do_gettimeofday(&tv); \
- (tv.tv_sec*1000000+tv.tv_usec); \
- })
-
-#define boolean_t int
-
-/*
- * For current time stamp, OS API will fill-in
- */
-struct bfa_timeval_s {
- u32 tv_sec; /* seconds */
- u32 tv_usec; /* microseconds */
-};
-
-static inline void
-bfa_os_gettimeofday(struct bfa_timeval_s *tv)
-{
- struct timeval tmp_tv;
-
- do_gettimeofday(&tmp_tv);
- tv->tv_sec = (u32) tmp_tv.tv_sec;
- tv->tv_usec = (u32) tmp_tv.tv_usec;
-}
-
-static inline void
-wwn2str(char *wwn_str, u64 wwn)
-{
- union {
- u64 wwn;
- u8 byte[8];
- } w;
-
- w.wwn = wwn;
- sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
- w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
- w.byte[6], w.byte[7]);
-}
-
-static inline void
-fcid2str(char *fcid_str, u32 fcid)
-{
- union {
- u32 fcid;
- u8 byte[4];
- } f;
-
- f.fcid = fcid;
- sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
-}
-
-#endif /* __BFA_OS_INC_H__ */
diff --git a/drivers/scsi/bfa/bfa_plog.h b/drivers/scsi/bfa/bfa_plog.h
index 501f0ed35cf0..1c9baa68339b 100644
--- a/drivers/scsi/bfa/bfa_plog.h
+++ b/drivers/scsi/bfa/bfa_plog.h
@@ -151,9 +151,5 @@ void bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
void bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
enum bfa_plog_eid event, u16 misc,
struct fchs_s *fchdr, u32 pld_w0);
-void bfa_plog_clear(struct bfa_plog_s *plog);
-void bfa_plog_enable(struct bfa_plog_s *plog);
-void bfa_plog_disable(struct bfa_plog_s *plog);
-bfa_boolean_t bfa_plog_get_setting(struct bfa_plog_s *plog);
#endif /* __BFA_PORTLOG_H__ */
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c
index fff96226a383..3f8e9d6066ec 100644
--- a/drivers/scsi/bfa/bfa_port.c
+++ b/drivers/scsi/bfa/bfa_port.c
@@ -15,6 +15,7 @@
* General Public License for more details.
*/
+#include "bfad_drv.h"
#include "bfa_defs_svc.h"
#include "bfa_port.h"
#include "bfi.h"
@@ -29,14 +30,14 @@ static void
bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
{
u32 *dip = (u32 *) stats;
- u32 t0, t1;
+ __be32 t0, t1;
int i;
for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32);
i += 2) {
t0 = dip[i];
t1 = dip[i + 1];
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
dip[i] = be32_to_cpu(t0);
dip[i + 1] = be32_to_cpu(t1);
#else
@@ -96,13 +97,13 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
port->stats_busy = BFA_FALSE;
if (status == BFA_STATUS_OK) {
- struct bfa_timeval_s tv;
+ struct timeval tv;
memcpy(port->stats, port->stats_dma.kva,
sizeof(union bfa_port_stats_u));
bfa_port_stats_swap(port, port->stats);
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
port->stats->fc.secs_reset = tv.tv_sec - port->stats_reset_time;
}
@@ -124,7 +125,7 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
static void
bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
{
- struct bfa_timeval_s tv;
+ struct timeval tv;
port->stats_status = status;
port->stats_busy = BFA_FALSE;
@@ -132,7 +133,7 @@ bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
/*
* re-initialize time stamp for stats reset
*/
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
port->stats_reset_time = tv.tv_sec;
if (port->stats_cbfn) {
@@ -185,7 +186,7 @@ bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -432,9 +433,9 @@ void
bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
void *dev, struct bfa_trc_mod_s *trcmod)
{
- struct bfa_timeval_s tv;
+ struct timeval tv;
- bfa_assert(port);
+ WARN_ON(!port);
port->dev = dev;
port->ioc = ioc;
@@ -447,27 +448,13 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
- bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
+ list_add_tail(&port->hbfail.qe, &port->ioc->hb_notify_q);
/*
* initialize time stamp for stats reset
*/
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
port->stats_reset_time = tv.tv_sec;
bfa_trc(port, 0);
}
-
-/*
- * bfa_port_detach()
- *
- *
- * @param[in] port - Pointer to the Port module data structure
- *
- * @return void
- */
-void
-bfa_port_detach(struct bfa_port_s *port)
-{
- bfa_trc(port, 0);
-}
diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h
index dbce9dfd056b..c4ee9db6b470 100644
--- a/drivers/scsi/bfa/bfa_port.h
+++ b/drivers/scsi/bfa/bfa_port.h
@@ -48,7 +48,6 @@ struct bfa_port_s {
void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
void *dev, struct bfa_trc_mod_s *trcmod);
-void bfa_port_detach(struct bfa_port_s *port);
void bfa_port_hbfail(void *arg);
bfa_status_t bfa_port_get_stats(struct bfa_port_s *port,
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index c768143f4805..1d34921f88bf 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -15,11 +15,10 @@
* General Public License for more details.
*/
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
#include "bfa_plog.h"
#include "bfa_cs.h"
#include "bfa_modules.h"
-#include "bfad_drv.h"
BFA_TRC_FILE(HAL, FCXP);
BFA_MODULE(fcxp);
@@ -41,19 +40,6 @@ BFA_MODULE(uf);
#define BFA_LPS_MAX_VPORTS_SUPP_CB 255
#define BFA_LPS_MAX_VPORTS_SUPP_CT 190
-/*
- * lps_pvt BFA LPS private functions
- */
-
-enum bfa_lps_event {
- BFA_LPS_SM_LOGIN = 1, /* login request from user */
- BFA_LPS_SM_LOGOUT = 2, /* logout request from user */
- BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */
- 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 */
-};
/*
* FC PORT related definitions
@@ -66,7 +52,6 @@ enum bfa_lps_event {
((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
-
/*
* BFA port state machine events
*/
@@ -113,19 +98,6 @@ enum bfa_fcport_ln_sm_event {
} \
} while (0)
-
-enum bfa_rport_event {
- BFA_RPORT_SM_CREATE = 1, /* rport create event */
- BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */
- BFA_RPORT_SM_ONLINE = 3, /* rport is online */
- BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */
- BFA_RPORT_SM_FWRSP = 5, /* firmware response */
- BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */
- BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */
- BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */
- BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */
-};
-
/*
* forward declarations FCXP related functions
*/
@@ -159,6 +131,7 @@ static void bfa_lps_reqq_resume(void *lps_arg);
static void bfa_lps_free(struct bfa_lps_s *lps);
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_send_set_n2n_pid(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);
@@ -171,6 +144,8 @@ static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event
event);
static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
+static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
+ enum bfa_lps_event event);
static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
event);
@@ -312,6 +287,18 @@ plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
return 0;
}
+static u64
+bfa_get_log_time(void)
+{
+ u64 system_time = 0;
+ struct timeval tv;
+ do_gettimeofday(&tv);
+
+ /* We are interested in seconds only. */
+ system_time = tv.tv_sec;
+ return system_time;
+}
+
static void
bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
{
@@ -322,7 +309,7 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
return;
if (plkd_validate_logrec(pl_rec)) {
- bfa_assert(0);
+ WARN_ON(1);
return;
}
@@ -332,7 +319,7 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
- pl_recp->tv = bfa_os_get_log_time();
+ pl_recp->tv = bfa_get_log_time();
BFA_PL_LOG_REC_INCR(plog->tail);
if (plog->head == plog->tail)
@@ -437,29 +424,6 @@ bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
}
}
-void
-bfa_plog_clear(struct bfa_plog_s *plog)
-{
- plog->head = plog->tail = 0;
-}
-
-void
-bfa_plog_enable(struct bfa_plog_s *plog)
-{
- plog->plog_enabled = 1;
-}
-
-void
-bfa_plog_disable(struct bfa_plog_s *plog)
-{
- plog->plog_enabled = 0;
-}
-
-bfa_boolean_t
-bfa_plog_get_setting(struct bfa_plog_s *plog)
-{
- return (bfa_boolean_t)plog->plog_enabled;
-}
/*
* fcxp_pvt BFA FCXP private functions
@@ -637,15 +601,15 @@ bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp,
bfa_fcxp_get_sglen_t sglen_cbfn)
{
- bfa_assert(bfa != NULL);
+ WARN_ON(bfa == NULL);
bfa_trc(bfa, fcxp->fcxp_tag);
if (n_sgles == 0) {
*use_ibuf = 1;
} else {
- bfa_assert(*sga_cbfn != NULL);
- bfa_assert(*sglen_cbfn != NULL);
+ WARN_ON(*sga_cbfn == NULL);
+ WARN_ON(*sglen_cbfn == NULL);
*use_ibuf = 0;
*r_sga_cbfn = sga_cbfn;
@@ -657,7 +621,7 @@ bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp,
* alloc required sgpgs
*/
if (n_sgles > BFI_SGE_INLINE)
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -671,7 +635,7 @@ bfa_fcxp_init(struct bfa_fcxp_s *fcxp,
bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
{
- bfa_assert(bfa != NULL);
+ WARN_ON(bfa == NULL);
bfa_trc(bfa, fcxp->fcxp_tag);
@@ -708,7 +672,7 @@ bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
return;
}
- bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
+ WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
list_del(&fcxp->qe);
list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
}
@@ -757,7 +721,7 @@ hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
- bfa_assert(fcxp->send_cbfn != NULL);
+ WARN_ON(fcxp->send_cbfn == NULL);
hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
@@ -913,13 +877,13 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
BFA_FCXP_REQ_PLD_PA(fcxp));
} else {
if (fcxp->nreq_sgles > 0) {
- bfa_assert(fcxp->nreq_sgles == 1);
+ WARN_ON(fcxp->nreq_sgles != 1);
hal_fcxp_set_local_sges(send_req->req_sge,
reqi->req_tot_len,
fcxp->req_sga_cbfn(fcxp->caller,
0));
} else {
- bfa_assert(reqi->req_tot_len == 0);
+ WARN_ON(reqi->req_tot_len != 0);
hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
}
}
@@ -928,20 +892,20 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
* setup rsp sgles
*/
if (fcxp->use_irspbuf == 1) {
- bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
+ WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ);
hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
BFA_FCXP_RSP_PLD_PA(fcxp));
} else {
if (fcxp->nrsp_sgles > 0) {
- bfa_assert(fcxp->nrsp_sgles == 1);
+ WARN_ON(fcxp->nrsp_sgles != 1);
hal_fcxp_set_local_sges(send_req->rsp_sge,
rspi->rsp_maxlen,
fcxp->rsp_sga_cbfn(fcxp->caller,
0));
} else {
- bfa_assert(rspi->rsp_maxlen == 0);
+ WARN_ON(rspi->rsp_maxlen != 0);
hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
}
}
@@ -955,10 +919,6 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
}
/*
- * hal_fcxp_api BFA FCXP API
- */
-
-/*
* Allocate an FCXP instance to send a response or to send a request
* that has a response. Request/response buffers are allocated by caller.
*
@@ -990,7 +950,7 @@ bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
{
struct bfa_fcxp_s *fcxp = NULL;
- bfa_assert(bfa != NULL);
+ WARN_ON(bfa == NULL);
fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
if (fcxp == NULL)
@@ -1017,7 +977,7 @@ bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
void *reqbuf;
- bfa_assert(fcxp->use_ireqbuf == 1);
+ WARN_ON(fcxp->use_ireqbuf != 1);
reqbuf = ((u8 *)mod->req_pld_list_kva) +
fcxp->fcxp_tag * mod->req_pld_sz;
return reqbuf;
@@ -1044,7 +1004,7 @@ bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
void *rspbuf;
- bfa_assert(fcxp->use_irspbuf == 1);
+ WARN_ON(fcxp->use_irspbuf != 1);
rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
fcxp->fcxp_tag * mod->rsp_pld_sz;
@@ -1052,7 +1012,7 @@ bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
}
/*
- * Free the BFA FCXP
+ * Free the BFA FCXP
*
* @param[in] fcxp BFA fcxp pointer
*
@@ -1063,7 +1023,7 @@ bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
{
struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
- bfa_assert(fcxp != NULL);
+ WARN_ON(fcxp == NULL);
bfa_trc(mod->bfa, fcxp->fcxp_tag);
bfa_fcxp_put(fcxp);
}
@@ -1142,7 +1102,7 @@ bfa_status_t
bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
{
bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag);
- bfa_assert(0);
+ WARN_ON(1);
return BFA_STATUS_OK;
}
@@ -1157,7 +1117,7 @@ bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
{
struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
- bfa_assert(list_empty(&mod->fcxp_free_q));
+ WARN_ON(!list_empty(&mod->fcxp_free_q));
wqe->alloc_cbfn = alloc_cbfn;
wqe->alloc_cbarg = alloc_cbarg;
@@ -1178,7 +1138,7 @@ bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
{
struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
- bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
+ WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe));
list_del(&wqe->qe);
}
@@ -1199,12 +1159,6 @@ bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
fcxp->send_cbfn = bfa_fcxp_null_comp;
}
-
-
-/*
- * hal_fcxp_public BFA FCXP public functions
- */
-
void
bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
{
@@ -1215,7 +1169,7 @@ bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
default:
bfa_trc(bfa, msg->mhdr.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -1303,6 +1257,12 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
else
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+ /* If N2N, send the assigned PID to FW */
+ bfa_trc(lps->bfa, lps->fport);
+ bfa_trc(lps->bfa, lps->lp_pid);
+
+ if (!lps->fport && lps->lp_pid)
+ bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
} else {
bfa_sm_set_state(lps, bfa_lps_sm_init);
if (lps->fdisc)
@@ -1321,6 +1281,11 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_sm_set_state(lps, bfa_lps_sm_init);
break;
+ case BFA_LPS_SM_SET_N2N_PID:
+ bfa_trc(lps->bfa, lps->fport);
+ bfa_trc(lps->bfa, lps->lp_pid);
+ break;
+
default:
bfa_sm_fault(lps->bfa, event);
}
@@ -1389,9 +1354,59 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
break;
+ case BFA_LPS_SM_SET_N2N_PID:
+ if (bfa_reqq_full(lps->bfa, lps->reqq)) {
+ bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait);
+ bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
+ } else
+ bfa_lps_send_set_n2n_pid(lps);
+ break;
+
+ case BFA_LPS_SM_OFFLINE:
+ case BFA_LPS_SM_DELETE:
+ bfa_sm_set_state(lps, bfa_lps_sm_init);
+ break;
+
+ default:
+ bfa_sm_fault(lps->bfa, event);
+ }
+}
+
+/*
+ * login complete
+ */
+static void
+bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
+{
+ bfa_trc(lps->bfa, lps->lp_tag);
+ bfa_trc(lps->bfa, event);
+
+ switch (event) {
+ case BFA_LPS_SM_RESUME:
+ bfa_sm_set_state(lps, bfa_lps_sm_online);
+ bfa_lps_send_set_n2n_pid(lps);
+ break;
+
+ case BFA_LPS_SM_LOGOUT:
+ bfa_sm_set_state(lps, bfa_lps_sm_logowait);
+ 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);
+ bfa_reqq_wcancel(&lps->wqe);
+
+ /* 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:
case BFA_LPS_SM_DELETE:
bfa_sm_set_state(lps, bfa_lps_sm_init);
+ bfa_reqq_wcancel(&lps->wqe);
break;
default:
@@ -1540,15 +1555,16 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
struct bfa_lps_s *lps;
- bfa_assert(rsp->lp_tag < mod->num_lps);
+ WARN_ON(rsp->lp_tag >= mod->num_lps);
lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
lps->status = rsp->status;
switch (rsp->status) {
case BFA_STATUS_OK:
lps->fport = rsp->f_port;
+ if (lps->fport)
+ lps->lp_pid = rsp->lp_pid;
lps->npiv_en = rsp->npiv_en;
- lps->lp_pid = rsp->lp_pid;
lps->pr_bbcred = be16_to_cpu(rsp->bb_credit);
lps->pr_pwwn = rsp->port_name;
lps->pr_nwwn = rsp->node_name;
@@ -1587,7 +1603,7 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
struct bfa_lps_s *lps;
- bfa_assert(rsp->lp_tag < mod->num_lps);
+ WARN_ON(rsp->lp_tag >= mod->num_lps);
lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
@@ -1640,7 +1656,7 @@ bfa_lps_send_login(struct bfa_lps_s *lps)
struct bfi_lps_login_req_s *m;
m = bfa_reqq_next(lps->bfa, lps->reqq);
- bfa_assert(m);
+ WARN_ON(!m);
bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
bfa_lpuid(lps->bfa));
@@ -1665,7 +1681,7 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
struct bfi_lps_logout_req_s *m;
m = bfa_reqq_next(lps->bfa, lps->reqq);
- bfa_assert(m);
+ WARN_ON(!m);
bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ,
bfa_lpuid(lps->bfa));
@@ -1676,6 +1692,25 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
}
/*
+ * send n2n pid set request to firmware
+ */
+static void
+bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps)
+{
+ struct bfi_lps_n2n_pid_req_s *m;
+
+ m = bfa_reqq_next(lps->bfa, lps->reqq);
+ WARN_ON(!m);
+
+ bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
+ bfa_lpuid(lps->bfa));
+
+ m->lp_tag = lps->lp_tag;
+ m->lp_pid = lps->lp_pid;
+ bfa_reqq_produce(lps->bfa, lps->reqq);
+}
+
+/*
* Indirect login completion handler for non-fcs
*/
static void
@@ -1853,14 +1888,6 @@ bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
}
-/*
- * Initiate a lport logout (flogi).
- */
-void
-bfa_lps_flogo(struct bfa_lps_s *lps)
-{
- bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
-}
/*
* Initiate a lport FDSIC logout.
@@ -1871,24 +1898,6 @@ bfa_lps_fdisclogo(struct bfa_lps_s *lps)
bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
}
-/*
- * Discard a pending login request -- should be called only for
- * link down handling.
- */
-void
-bfa_lps_discard(struct bfa_lps_s *lps)
-{
- bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
-}
-
-/*
- * Return lport services tag
- */
-u8
-bfa_lps_get_tag(struct bfa_lps_s *lps)
-{
- return lps->lp_tag;
-}
/*
* Return lport services tag given the pid
@@ -1909,55 +1918,6 @@ bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
return 0;
}
-/*
- * return if fabric login indicates support for NPIV
- */
-bfa_boolean_t
-bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
-{
- return lps->npiv_en;
-}
-
-/*
- * Return TRUE if attached to F-Port, else return FALSE
- */
-bfa_boolean_t
-bfa_lps_is_fport(struct bfa_lps_s *lps)
-{
- return lps->fport;
-}
-
-/*
- * Return TRUE if attached to a Brocade Fabric
- */
-bfa_boolean_t
-bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
-{
- return lps->brcd_switch;
-}
-/*
- * return TRUE if authentication is required
- */
-bfa_boolean_t
-bfa_lps_is_authreq(struct bfa_lps_s *lps)
-{
- return lps->auth_req;
-}
-
-bfa_eproto_status_t
-bfa_lps_get_extstatus(struct bfa_lps_s *lps)
-{
- return lps->ext_status;
-}
-
-/*
- * return port id assigned to the lport
- */
-u32
-bfa_lps_get_pid(struct bfa_lps_s *lps)
-{
- return lps->lp_pid;
-}
/*
* return port id assigned to the base lport
@@ -1971,57 +1931,16 @@ bfa_lps_get_base_pid(struct bfa_s *bfa)
}
/*
- * Return bb_credit assigned in FLOGI response
- */
-u16
-bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
-{
- return lps->pr_bbcred;
-}
-
-/*
- * Return peer port name
- */
-wwn_t
-bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
-{
- return lps->pr_pwwn;
-}
-
-/*
- * Return peer node name
- */
-wwn_t
-bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
-{
- return lps->pr_nwwn;
-}
-
-/*
- * return reason code if login request is rejected
- */
-u8
-bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
-{
- return lps->lsrjt_rsn;
-}
-
-/*
- * return explanation code if login request is rejected
+ * Set PID in case of n2n (which is assigned during PLOGI)
*/
-u8
-bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
+void
+bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid)
{
- return lps->lsrjt_expl;
-}
+ bfa_trc(lps->bfa, lps->lp_tag);
+ bfa_trc(lps->bfa, n2n_pid);
-/*
- * Return fpma/spma MAC for lport
- */
-mac_t
-bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
-{
- return lps->lp_mac;
+ lps->lp_pid = n2n_pid;
+ bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
}
/*
@@ -2050,7 +1969,7 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
default:
bfa_trc(bfa, m->mhdr.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -2068,6 +1987,8 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
/*
* Start event after IOC is configured and BFA is started.
*/
+ fcport->use_flash_cfg = BFA_TRUE;
+
if (bfa_fcport_send_enable(fcport)) {
bfa_trc(fcport->bfa, BFA_TRUE);
bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
@@ -2138,7 +2059,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port disabled: WWN = %s\n", pwwn_buf);
break;
@@ -2178,7 +2099,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
bfa_fcport_update_linkinfo(fcport);
bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
- bfa_assert(fcport->event_cbfn);
+ WARN_ON(!fcport->event_cbfn);
bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
break;
@@ -2198,7 +2119,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port disabled: WWN = %s\n", pwwn_buf);
break;
@@ -2229,7 +2150,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
case BFA_FCPORT_SM_LINKUP:
bfa_fcport_update_linkinfo(fcport);
bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
- bfa_assert(fcport->event_cbfn);
+ WARN_ON(!fcport->event_cbfn);
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
@@ -2251,7 +2172,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port online: WWN = %s\n", pwwn_buf);
break;
@@ -2277,7 +2198,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port disabled: WWN = %s\n", pwwn_buf);
break;
@@ -2322,9 +2243,9 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port offline: WWN = %s\n", pwwn_buf);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port disabled: WWN = %s\n", pwwn_buf);
break;
@@ -2336,10 +2257,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
wwn2str(pwwn_buf, fcport->pwwn);
if (BFA_PORT_IS_DISABLED(fcport->bfa))
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port offline: WWN = %s\n", pwwn_buf);
else
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Base port (WWN = %s) "
"lost fabric connectivity\n", pwwn_buf);
break;
@@ -2349,10 +2270,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
bfa_fcport_reset_linkinfo(fcport);
wwn2str(pwwn_buf, fcport->pwwn);
if (BFA_PORT_IS_DISABLED(fcport->bfa))
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port offline: WWN = %s\n", pwwn_buf);
else
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Base port (WWN = %s) "
"lost fabric connectivity\n", pwwn_buf);
break;
@@ -2363,10 +2284,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
wwn2str(pwwn_buf, fcport->pwwn);
if (BFA_PORT_IS_DISABLED(fcport->bfa))
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port offline: WWN = %s\n", pwwn_buf);
else
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"Base port (WWN = %s) "
"lost fabric connectivity\n", pwwn_buf);
break;
@@ -2497,7 +2418,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port enabled: WWN = %s\n", pwwn_buf);
break;
@@ -2551,7 +2472,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
wwn2str(pwwn_buf, fcport->pwwn);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port enabled: WWN = %s\n", pwwn_buf);
break;
@@ -2803,12 +2724,6 @@ bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
}
}
-
-
-/*
- * hal_port_private
- */
-
static void
__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
{
@@ -2839,7 +2754,7 @@ bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event,
bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -2906,7 +2821,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
struct bfa_port_cfg_s *port_cfg = &fcport->cfg;
struct bfa_fcport_ln_s *ln = &fcport->ln;
- struct bfa_timeval_s tv;
+ struct timeval tv;
memset(fcport, 0, sizeof(struct bfa_fcport_s));
fcport->bfa = bfa;
@@ -2920,7 +2835,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
/*
* initialize time stamp for stats reset
*/
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
fcport->stats_reset_time = tv.tv_sec;
/*
@@ -3039,6 +2954,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
m->port_cfg = fcport->cfg;
m->msgtag = fcport->msgtag;
m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
+ m->use_flash_cfg = fcport->use_flash_cfg;
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);
@@ -3089,8 +3005,8 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
static void
bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
{
- fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
- fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
+ fcport->pwwn = fcport->bfa->ioc.attr->pwwn;
+ fcport->nwwn = fcport->bfa->ioc.attr->nwwn;
bfa_trc(fcport->bfa, fcport->pwwn);
bfa_trc(fcport->bfa, fcport->nwwn);
@@ -3127,7 +3043,7 @@ 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;
+ __be32 *sip = (__be32 *) s;
int i;
/* Now swap the 32 bit fields */
@@ -3140,12 +3056,12 @@ 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;
+ __be32 *sip = (__be32 *) s;
int i;
for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
i = i + 2) {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
dip[i] = be32_to_cpu(sip[i]);
dip[i + 1] = be32_to_cpu(sip[i + 1]);
#else
@@ -3162,7 +3078,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
if (complete) {
if (fcport->stats_status == BFA_STATUS_OK) {
- struct bfa_timeval_s tv;
+ struct timeval tv;
/* Swap FC QoS or FCoE stats */
if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
@@ -3174,7 +3090,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
&fcport->stats_ret->fcoe,
&fcport->stats->fcoe);
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
fcport->stats_ret->fcoe.secs_reset =
tv.tv_sec - fcport->stats_reset_time;
}
@@ -3233,12 +3149,12 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
struct bfa_fcport_s *fcport = cbarg;
if (complete) {
- struct bfa_timeval_s tv;
+ struct timeval tv;
/*
* re-initialize time stamp for stats reset
*/
- bfa_os_gettimeofday(&tv);
+ do_gettimeofday(&tv);
fcport->stats_reset_time = tv.tv_sec;
fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
@@ -3303,8 +3219,8 @@ bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
int link_bm = 0;
bfa_trc(fcport->bfa, fcport->cfg.trunked);
- bfa_assert(scn->trunk_state == BFA_TRUNK_ONLINE ||
- scn->trunk_state == BFA_TRUNK_OFFLINE);
+ WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE &&
+ scn->trunk_state != BFA_TRUNK_OFFLINE);
bfa_trc(fcport->bfa, trunk->attr.state);
bfa_trc(fcport->bfa, scn->trunk_state);
@@ -3396,12 +3312,6 @@ bfa_trunk_iocdisable(struct bfa_s *bfa)
}
}
-
-
-/*
- * hal_port_public
- */
-
/*
* Called to initialize port attributes
*/
@@ -3419,9 +3329,9 @@ bfa_fcport_init(struct bfa_s *bfa)
fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
- bfa_assert(fcport->cfg.maxfrsize);
- bfa_assert(fcport->cfg.rx_bbcredit);
- bfa_assert(fcport->speed_sup);
+ WARN_ON(!fcport->cfg.maxfrsize);
+ WARN_ON(!fcport->cfg.rx_bbcredit);
+ WARN_ON(!fcport->speed_sup);
}
/*
@@ -3441,8 +3351,28 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
switch (msg->mhdr.msg_id) {
case BFI_FCPORT_I2H_ENABLE_RSP:
- if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+ if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
+
+ if (fcport->use_flash_cfg) {
+ fcport->cfg = i2hmsg.penable_rsp->port_cfg;
+ fcport->cfg.maxfrsize =
+ cpu_to_be16(fcport->cfg.maxfrsize);
+ fcport->cfg.path_tov =
+ cpu_to_be16(fcport->cfg.path_tov);
+ fcport->cfg.q_depth =
+ cpu_to_be16(fcport->cfg.q_depth);
+
+ if (fcport->cfg.trunked)
+ fcport->trunk.attr.state =
+ BFA_TRUNK_OFFLINE;
+ else
+ fcport->trunk.attr.state =
+ BFA_TRUNK_DISABLED;
+ fcport->use_flash_cfg = BFA_FALSE;
+ }
+
bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
+ }
break;
case BFI_FCPORT_I2H_DISABLE_RSP:
@@ -3498,17 +3428,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
break;
}
}
-
-
-/*
- * hal_port_api
- */
-
/*
* Registered callback for port events.
*/
@@ -3732,8 +3656,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
attr->nwwn = fcport->nwwn;
attr->pwwn = fcport->pwwn;
- attr->factorypwwn = bfa_ioc_get_mfg_pwwn(&bfa->ioc);
- attr->factorynwwn = bfa_ioc_get_mfg_nwwn(&bfa->ioc);
+ attr->factorypwwn = bfa->ioc.attr->mfg_pwwn;
+ attr->factorynwwn = bfa->ioc.attr->mfg_nwwn;
memcpy(&attr->pport_cfg, &fcport->cfg,
sizeof(struct bfa_port_cfg_s));
@@ -3751,7 +3675,7 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
/* beacon attributes */
attr->beacon = fcport->beacon;
attr->link_e2e_beacon = fcport->link_e2e_beacon;
- attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
+ attr->plog_enabled = (bfa_boolean_t)fcport->bfa->plog->plog_enabled;
attr->io_profile = bfa_fcpim_get_io_profile(fcport->bfa);
attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
@@ -3818,89 +3742,6 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
return BFA_STATUS_OK;
}
-/*
- * Fetch FCQoS port statistics
- */
-bfa_status_t
-bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
- bfa_cb_port_t cbfn, void *cbarg)
-{
- /* Meaningful only for FC mode */
- bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
-
- return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-/*
- * Reset FCoE port statistics
- */
-bfa_status_t
-bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
-{
- /* Meaningful only for FC mode */
- bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
-
- return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
-}
-
-/*
- * Fetch FCQoS port statistics
- */
-bfa_status_t
-bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
- bfa_cb_port_t cbfn, void *cbarg)
-{
- /* Meaningful only for FCoE mode */
- bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
-
- return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-/*
- * Reset FCoE port statistics
- */
-bfa_status_t
-bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
-{
- /* Meaningful only for FCoE mode */
- bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
-
- return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
-}
-
-void
-bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- qos_attr->state = fcport->qos_attr.state;
- qos_attr->total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
-}
-
-void
-bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
- struct bfa_qos_vc_attr_s *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 = be16_to_cpu(bfa_vc_attr->total_vc_count);
- qos_vc_attr->shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit);
- qos_vc_attr->elp_opmode_flags =
- be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
-
- /* Individual VC info */
- while (i < qos_vc_attr->total_vc_count) {
- qos_vc_attr->vc_info[i].vc_credit =
- bfa_vc_attr->vc_info[i].vc_credit;
- qos_vc_attr->vc_info[i].borrow_credit =
- bfa_vc_attr->vc_info[i].borrow_credit;
- qos_vc_attr->vc_info[i].priority =
- bfa_vc_attr->vc_info[i].priority;
- ++i;
- }
-}
/*
* Fetch port attributes.
@@ -3924,60 +3765,6 @@ bfa_fcport_is_ratelim(struct bfa_s *bfa)
}
-void
-bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
-{
- 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, fcport->cfg.qos_enabled);
-
- bfa_trc(bfa, ioc_type);
-
- if (ioc_type == BFA_IOC_TYPE_FC) {
- fcport->cfg.qos_enabled = on_off;
- /*
- * Notify fcpim of the change in QoS state
- */
- bfa_fcpim_update_ioredirect(bfa);
- }
-}
-
-void
-bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- bfa_trc(bfa, on_off);
- bfa_trc(bfa, fcport->cfg.ratelimit);
-
- fcport->cfg.ratelimit = on_off;
- if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
- fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
-}
-
-/*
- * Configure default minimum ratelim speed
- */
-bfa_status_t
-bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
-{
- 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_PORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
- bfa_trc(bfa, fcport->speed_sup);
- return BFA_STATUS_UNSUPP_SPEED;
- }
-
- fcport->cfg.trl_def_speed = speed;
-
- return BFA_STATUS_OK;
-}
-
/*
* Get default minimum ratelim speed
*/
@@ -3990,32 +3777,6 @@ bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
return fcport->cfg.trl_def_speed;
}
-void
-bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- bfa_trc(bfa, status);
- bfa_trc(bfa, fcport->diag_busy);
-
- fcport->diag_busy = status;
-}
-
-void
-bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
- bfa_boolean_t link_e2e_beacon)
-{
- struct bfa_s *bfa = dev;
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- bfa_trc(bfa, beacon);
- bfa_trc(bfa, link_e2e_beacon);
- bfa_trc(bfa, fcport->beacon);
- bfa_trc(bfa, fcport->link_e2e_beacon);
-
- fcport->beacon = beacon;
- fcport->link_e2e_beacon = link_e2e_beacon;
-}
bfa_boolean_t
bfa_fcport_is_linkup(struct bfa_s *bfa)
@@ -4036,63 +3797,6 @@ bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
return fcport->cfg.qos_enabled;
}
-bfa_status_t
-bfa_trunk_get_attr(struct bfa_s *bfa, struct bfa_trunk_attr_s *attr)
-
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
- bfa_trc(bfa, fcport->cfg.trunked);
- bfa_trc(bfa, trunk->attr.state);
- *attr = trunk->attr;
- attr->port_id = bfa_lps_get_base_pid(bfa);
-
- return BFA_STATUS_OK;
-}
-
-void
-bfa_trunk_enable_cfg(struct bfa_s *bfa)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
- bfa_trc(bfa, 1);
- trunk->attr.state = BFA_TRUNK_OFFLINE;
- fcport->cfg.trunked = BFA_TRUE;
-}
-
-bfa_status_t
-bfa_trunk_enable(struct bfa_s *bfa)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
- bfa_trc(bfa, 1);
-
- trunk->attr.state = BFA_TRUNK_OFFLINE;
- bfa_fcport_disable(bfa);
- fcport->cfg.trunked = BFA_TRUE;
- bfa_fcport_enable(bfa);
-
- return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_trunk_disable(struct bfa_s *bfa)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
- bfa_trc(bfa, 0);
- trunk->attr.state = BFA_TRUNK_DISABLED;
- bfa_fcport_disable(bfa);
- fcport->cfg.trunked = BFA_FALSE;
- bfa_fcport_enable(bfa);
- return BFA_STATUS_OK;
-}
-
-
/*
* Rport State machine functions
*/
@@ -4606,8 +4310,8 @@ bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
mod->rps_list = rp;
mod->num_rports = cfg->fwcfg.num_rports;
- bfa_assert(mod->num_rports &&
- !(mod->num_rports & (mod->num_rports - 1)));
+ WARN_ON(!mod->num_rports ||
+ (mod->num_rports & (mod->num_rports - 1)));
for (i = 0; i < mod->num_rports; i++, rp++) {
memset(rp, 0, sizeof(struct bfa_rport_s));
@@ -4675,7 +4379,7 @@ bfa_rport_free(struct bfa_rport_s *rport)
{
struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
- bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport));
+ WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport));
list_del(&rport->qe);
list_add_tail(&rport->qe, &mod->rp_free_q);
}
@@ -4788,13 +4492,13 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
rp->fw_handle = msg.create_rsp->fw_handle;
rp->qos_attr = msg.create_rsp->qos_attr;
- bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
+ WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
break;
case BFI_RPORT_I2H_DELETE_RSP:
rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
- bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
+ WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
break;
@@ -4806,7 +4510,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
default:
bfa_trc(bfa, m->mhdr.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
@@ -4828,24 +4532,18 @@ bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
rp->bfa = bfa;
rp->rport_drv = rport_drv;
- bfa_rport_clear_stats(rp);
+ memset(&rp->stats, 0, sizeof(rp->stats));
- bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
+ WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
return rp;
}
void
-bfa_rport_delete(struct bfa_rport_s *rport)
-{
- bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
-}
-
-void
bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
{
- bfa_assert(rport_info->max_frmsz != 0);
+ WARN_ON(rport_info->max_frmsz == 0);
/*
* Some JBODs are seen to be not setting PDU size correctly in PLOGI
@@ -4861,43 +4559,15 @@ bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
}
void
-bfa_rport_offline(struct bfa_rport_s *rport)
-{
- bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
-}
-
-void
bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
{
- bfa_assert(speed != 0);
- bfa_assert(speed != BFA_PORT_SPEED_AUTO);
+ WARN_ON(speed == 0);
+ WARN_ON(speed == BFA_PORT_SPEED_AUTO);
rport->rport_info.speed = speed;
bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
}
-void
-bfa_rport_get_stats(struct bfa_rport_s *rport,
- struct bfa_rport_hal_stats_s *stats)
-{
- *stats = rport->stats;
-}
-
-void
-bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
- struct bfa_rport_qos_attr_s *qos_attr)
-{
- qos_attr->qos_priority = rport->qos_attr.qos_priority;
- qos_attr->qos_flow_id = be32_to_cpu(rport->qos_attr.qos_flow_id);
-
-}
-
-void
-bfa_rport_clear_stats(struct bfa_rport_s *rport)
-{
- memset(&rport->stats, 0, sizeof(rport->stats));
-}
-
/*
* SGPG related functions
@@ -4952,7 +4622,7 @@ bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
sgpg_pa.pa = mod->sgpg_arr_pa;
mod->free_sgpgs = mod->num_sgpgs;
- bfa_assert(!(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1)));
+ WARN_ON(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1));
for (i = 0; i < mod->num_sgpgs; i++) {
memset(hsgpg, 0, sizeof(*hsgpg));
@@ -4993,12 +4663,6 @@ bfa_sgpg_iocdisable(struct bfa_s *bfa)
{
}
-
-
-/*
- * hal_sgpg_public BFA SGPG public functions
- */
-
bfa_status_t
bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
{
@@ -5006,14 +4670,12 @@ bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
struct bfa_sgpg_s *hsgpg;
int i;
- bfa_trc_fp(bfa, nsgpgs);
-
if (mod->free_sgpgs < nsgpgs)
return BFA_STATUS_ENOMEM;
for (i = 0; i < nsgpgs; i++) {
bfa_q_deq(&mod->sgpg_q, &hsgpg);
- bfa_assert(hsgpg);
+ WARN_ON(!hsgpg);
list_add_tail(&hsgpg->qe, sgpg_q);
}
@@ -5027,10 +4689,8 @@ bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
struct bfa_sgpg_wqe_s *wqe;
- bfa_trc_fp(bfa, nsgpg);
-
mod->free_sgpgs += nsgpg;
- bfa_assert(mod->free_sgpgs <= mod->num_sgpgs);
+ WARN_ON(mod->free_sgpgs > mod->num_sgpgs);
list_splice_tail_init(sgpg_q, &mod->sgpg_q);
@@ -5060,8 +4720,8 @@ bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
{
struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
- bfa_assert(nsgpg > 0);
- bfa_assert(nsgpg > mod->free_sgpgs);
+ WARN_ON(nsgpg <= 0);
+ WARN_ON(nsgpg <= mod->free_sgpgs);
wqe->nsgpg_total = wqe->nsgpg = nsgpg;
@@ -5072,7 +4732,7 @@ bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
/*
* no one else is waiting for SGPG
*/
- bfa_assert(list_empty(&mod->sgpg_wait_q));
+ WARN_ON(!list_empty(&mod->sgpg_wait_q));
list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q);
wqe->nsgpg -= mod->free_sgpgs;
mod->free_sgpgs = 0;
@@ -5086,7 +4746,7 @@ bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe)
{
struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
- bfa_assert(bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
+ WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
list_del(&wqe->qe);
if (wqe->nsgpg_total != wqe->nsgpg)
@@ -5318,7 +4978,7 @@ uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
uf->data_ptr = buf;
uf->data_len = m->xfr_len;
- bfa_assert(uf->data_len >= sizeof(struct fchs_s));
+ WARN_ON(uf->data_len < sizeof(struct fchs_s));
if (uf->data_len == sizeof(struct fchs_s)) {
bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
@@ -5361,12 +5021,6 @@ bfa_uf_start(struct bfa_s *bfa)
bfa_uf_post_all(BFA_UF_MOD(bfa));
}
-
-
-/*
- * hal_uf_api
- */
-
/*
* Register handler for all unsolicted recieve frames.
*
@@ -5414,7 +5068,7 @@ bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
default:
bfa_trc(bfa, msg->mhdr.msg_id);
- bfa_assert(0);
+ WARN_ON(1);
}
}
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index e2349d5cdb93..331ad992a581 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -220,6 +220,18 @@ void bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
/*
* RPORT related defines
*/
+enum bfa_rport_event {
+ BFA_RPORT_SM_CREATE = 1, /* rport create event */
+ BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */
+ BFA_RPORT_SM_ONLINE = 3, /* rport is online */
+ BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */
+ BFA_RPORT_SM_FWRSP = 5, /* firmware response */
+ BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */
+ BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */
+ BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */
+ BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */
+};
+
#define BFA_RPORT_MIN 4
struct bfa_rport_mod_s {
@@ -432,6 +444,7 @@ struct bfa_fcport_s {
u8 myalpa; /* my ALPA in LOOP topology */
u8 rsvd[3];
struct bfa_port_cfg_s cfg; /* current port configuration */
+ bfa_boolean_t use_flash_cfg; /* get port cfg from flash */
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
struct bfa_reqq_wait_s reqq_wait;
@@ -500,30 +513,9 @@ void bfa_fcport_event_register(struct bfa_s *bfa,
void (*event_cbfn) (void *cbarg,
enum bfa_port_linkstate event), void *event_cbarg);
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_port_speed speed);
enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
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(void *dev, bfa_boolean_t beacon,
- bfa_boolean_t link_e2e_beacon);
-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_fcport_get_qos_stats(struct bfa_s *bfa,
- union bfa_fcport_stats_u *stats,
- bfa_cb_port_t cbfn, void *cbarg);
-bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn,
- void *cbarg);
-bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
- union bfa_fcport_stats_u *stats,
- bfa_cb_port_t cbfn, void *cbarg);
-bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_port_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,
@@ -537,14 +529,9 @@ bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
* bfa rport API functions
*/
struct bfa_rport_s *bfa_rport_create(struct bfa_s *bfa, void *rport_drv);
-void bfa_rport_delete(struct bfa_rport_s *rport);
void bfa_rport_online(struct bfa_rport_s *rport,
struct bfa_rport_info_s *rport_info);
-void bfa_rport_offline(struct bfa_rport_s *rport);
void bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed);
-void bfa_rport_get_stats(struct bfa_rport_s *rport,
- struct bfa_rport_hal_stats_s *stats);
-void bfa_rport_clear_stats(struct bfa_rport_s *rport);
void bfa_cb_rport_online(void *rport);
void bfa_cb_rport_offline(void *rport);
void bfa_cb_rport_qos_scn_flowid(void *rport,
@@ -553,8 +540,6 @@ void bfa_cb_rport_qos_scn_flowid(void *rport,
void bfa_cb_rport_qos_scn_prio(void *rport,
struct bfa_rport_qos_attr_s old_qos_attr,
struct bfa_rport_qos_attr_s new_qos_attr);
-void bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
- struct bfa_rport_qos_attr_s *qos_attr);
/*
* bfa fcxp API functions
@@ -619,38 +604,18 @@ void bfa_uf_free(struct bfa_uf_s *uf);
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);
void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa,
u16 pdusz, wwn_t pwwn, wwn_t nwwn,
bfa_boolean_t auth_en);
void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz,
wwn_t pwwn, wwn_t nwwn);
-void bfa_lps_flogo(struct bfa_lps_s *lps);
void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
-u8 bfa_lps_get_tag(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_npiv_en(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_fport(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_authreq(struct bfa_lps_s *lps);
-bfa_eproto_status_t bfa_lps_get_extstatus(struct bfa_lps_s *lps);
-u32 bfa_lps_get_pid(struct bfa_lps_s *lps);
+void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, u32 n2n_pid);
u32 bfa_lps_get_base_pid(struct bfa_s *bfa);
u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
-u16 bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps);
-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_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);
-void bfa_trunk_enable_cfg(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_enable(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_disable(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_get_attr(struct bfa_s *bfa,
- struct bfa_trunk_attr_s *attr);
-
#endif /* __BFA_SVC_H__ */
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 1f938974b848..44524cf55d33 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -32,7 +32,6 @@
#include "bfad_drv.h"
#include "bfad_im.h"
#include "bfa_fcs.h"
-#include "bfa_os_inc.h"
#include "bfa_defs.h"
#include "bfa.h"
@@ -50,7 +49,7 @@ int reqq_size, rspq_size, num_sgpgs;
int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
int bfa_io_max_sge = BFAD_IO_MAX_SGE;
-int log_level = 3; /* WARNING log level */
+int bfa_log_level = 3; /* WARNING log level */
int ioc_auto_recover = BFA_TRUE;
int bfa_linkup_delay = -1;
int fdmi_enable = BFA_TRUE;
@@ -61,12 +60,12 @@ int msix_disable_cb = 0, msix_disable_ct = 0;
u32 bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size;
u32 *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc;
-const char *msix_name_ct[] = {
+static const char *msix_name_ct[] = {
"cpe0", "cpe1", "cpe2", "cpe3",
"rme0", "rme1", "rme2", "rme3",
"ctrl" };
-const char *msix_name_cb[] = {
+static const char *msix_name_cb[] = {
"cpe0", "cpe1", "cpe2", "cpe3",
"rme0", "rme1", "rme2", "rme3",
"eemc", "elpu0", "elpu1", "epss", "mlpu" };
@@ -108,8 +107,8 @@ module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]");
module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
-module_param(log_level, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(log_level, "Driver log level, default=3, "
+module_param(bfa_log_level, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, "
"Range[Critical:1|Error:2|Warning:3|Info:4]");
module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, "
@@ -206,7 +205,7 @@ bfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event)
}
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_init(&bfad->bfa);
+ bfa_iocfc_init(&bfad->bfa);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
/* Set up interrupt handler for each vectors */
@@ -533,7 +532,7 @@ bfad_hal_mem_release(struct bfad_s *bfad)
(dma_addr_t) meminfo_elem->dma);
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
break;
}
}
@@ -725,7 +724,7 @@ bfad_bfa_tmo(unsigned long data)
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_timer_tick(&bfad->bfa);
+ bfa_timer_beat(&bfad->bfa.timer_mod);
bfa_comp_deq(&bfad->bfa, &doneq);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -882,8 +881,8 @@ bfad_drv_init(struct bfad_s *bfad)
goto out_hal_mem_alloc_failure;
}
- bfa_init_trc(&bfad->bfa, bfad->trcmod);
- bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
+ bfad->bfa.trcmod = bfad->trcmod;
+ bfad->bfa.plog = &bfad->plog_buf;
bfa_plog_init(&bfad->plog_buf);
bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
0, "Driver Attach");
@@ -893,9 +892,9 @@ bfad_drv_init(struct bfad_s *bfad)
/* FCS INIT */
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
+ bfad->bfa_fcs.trcmod = bfad->trcmod;
bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
- bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
+ bfad->bfa_fcs.fdmi_enabled = fdmi_enable;
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -913,7 +912,7 @@ bfad_drv_uninit(struct bfad_s *bfad)
spin_lock_irqsave(&bfad->bfad_lock, flags);
init_completion(&bfad->comp);
- bfa_stop(&bfad->bfa);
+ bfa_iocfc_stop(&bfad->bfa);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
wait_for_completion(&bfad->comp);
@@ -932,8 +931,8 @@ bfad_drv_start(struct bfad_s *bfad)
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_start(&bfad->bfa);
- bfa_fcs_start(&bfad->bfa_fcs);
+ bfa_iocfc_start(&bfad->bfa);
+ bfa_fcs_fabric_modstart(&bfad->bfa_fcs);
bfad->bfad_flags |= BFAD_HAL_START_DONE;
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -963,7 +962,7 @@ bfad_stop(struct bfad_s *bfad)
spin_lock_irqsave(&bfad->bfad_lock, flags);
init_completion(&bfad->comp);
- bfa_stop(&bfad->bfa);
+ bfa_iocfc_stop(&bfad->bfa);
bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
wait_for_completion(&bfad->comp);
@@ -1102,17 +1101,17 @@ bfad_start_ops(struct bfad_s *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
+ * value using the bfad_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 = bfad_get_linkup_delay(bfad);
+ bfad_rport_online_wait(bfad);
bfa_linkup_delay = -1;
} else
- bfad_os_rport_online_wait(bfad);
+ bfad_rport_online_wait(bfad);
- BFA_LOG(KERN_INFO, bfad, log_level, "bfa device claimed\n");
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n");
return BFA_STATUS_OK;
}
@@ -1167,7 +1166,6 @@ bfad_intx(int irq, void *dev_id)
spin_lock_irqsave(&bfad->bfad_lock, flags);
bfa_comp_free(&bfad->bfa, &doneq);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- bfa_trc_fp(bfad, irq);
}
return IRQ_HANDLED;
@@ -1524,7 +1522,7 @@ bfad_init(void)
if (strcmp(FCPI_NAME, " fcpim") == 0)
supported_fc4s |= BFA_LPORT_ROLE_FCP_IM;
- bfa_ioc_auto_recover(ioc_auto_recover);
+ bfa_auto_recover = ioc_auto_recover;
bfa_fcs_rport_set_del_timeout(rport_del_timeout);
error = pci_register_driver(&bfad_pci_driver);
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index ed9fff440b5c..a94ea4235433 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -25,7 +25,7 @@
/*
* FC transport template entry, get SCSI target port ID.
*/
-void
+static void
bfad_im_get_starget_port_id(struct scsi_target *starget)
{
struct Scsi_Host *shost;
@@ -40,7 +40,7 @@ bfad_im_get_starget_port_id(struct scsi_target *starget)
bfad = im_port->bfad;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- itnim = bfad_os_get_itnim(im_port, starget->id);
+ itnim = bfad_get_itnim(im_port, starget->id);
if (itnim)
fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
@@ -51,7 +51,7 @@ bfad_im_get_starget_port_id(struct scsi_target *starget)
/*
* FC transport template entry, get SCSI target nwwn.
*/
-void
+static void
bfad_im_get_starget_node_name(struct scsi_target *starget)
{
struct Scsi_Host *shost;
@@ -66,7 +66,7 @@ bfad_im_get_starget_node_name(struct scsi_target *starget)
bfad = im_port->bfad;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- itnim = bfad_os_get_itnim(im_port, starget->id);
+ itnim = bfad_get_itnim(im_port, starget->id);
if (itnim)
node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
@@ -77,7 +77,7 @@ bfad_im_get_starget_node_name(struct scsi_target *starget)
/*
* FC transport template entry, get SCSI target pwwn.
*/
-void
+static void
bfad_im_get_starget_port_name(struct scsi_target *starget)
{
struct Scsi_Host *shost;
@@ -92,7 +92,7 @@ bfad_im_get_starget_port_name(struct scsi_target *starget)
bfad = im_port->bfad;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- itnim = bfad_os_get_itnim(im_port, starget->id);
+ itnim = bfad_get_itnim(im_port, starget->id);
if (itnim)
port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
@@ -103,7 +103,7 @@ bfad_im_get_starget_port_name(struct scsi_target *starget)
/*
* FC transport template entry, get SCSI host port ID.
*/
-void
+static void
bfad_im_get_host_port_id(struct Scsi_Host *shost)
{
struct bfad_im_port_s *im_port =
@@ -111,7 +111,7 @@ bfad_im_get_host_port_id(struct Scsi_Host *shost)
struct bfad_port_s *port = im_port->port;
fc_host_port_id(shost) =
- bfa_os_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
+ bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
}
/*
@@ -487,7 +487,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
wait_for_completion(vport->comp_del);
free_scsi_host:
- bfad_os_scsi_host_free(bfad, im_port);
+ bfad_scsi_host_free(bfad, im_port);
kfree(vport);
diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c
index 1fedeeb4ac1f..c66e32eced7b 100644
--- a/drivers/scsi/bfa/bfad_debugfs.c
+++ b/drivers/scsi/bfa/bfad_debugfs.c
@@ -90,7 +90,7 @@ bfad_debugfs_open_fwtrc(struct inode *inode, struct file *file)
memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
spin_lock_irqsave(&bfad->bfad_lock, flags);
- rc = bfa_debug_fwtrc(&bfad->bfa,
+ rc = bfa_ioc_debug_fwtrc(&bfad->bfa.ioc,
fw_debug->debug_buffer,
&fw_debug->buffer_len);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -134,7 +134,7 @@ bfad_debugfs_open_fwsave(struct inode *inode, struct file *file)
memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
spin_lock_irqsave(&bfad->bfad_lock, flags);
- rc = bfa_debug_fwsave(&bfad->bfa,
+ rc = bfa_ioc_debug_fwsave(&bfad->bfa.ioc,
fw_debug->debug_buffer,
&fw_debug->buffer_len);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -208,7 +208,7 @@ bfad_debugfs_read(struct file *file, char __user *buf,
if (!debug || !debug->debug_buffer)
return 0;
- return memory_read_from_buffer(buf, nbytes, pos,
+ return simple_read_from_buffer(buf, nbytes, pos,
debug->debug_buffer, debug->buffer_len);
}
@@ -254,7 +254,7 @@ bfad_debugfs_read_regrd(struct file *file, char __user *buf,
if (!bfad->regdata)
return 0;
- rc = memory_read_from_buffer(buf, nbytes, pos,
+ rc = simple_read_from_buffer(buf, nbytes, pos,
bfad->regdata, bfad->reglen);
if ((*pos + nbytes) >= bfad->reglen) {
@@ -279,15 +279,31 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf,
u32 *regbuf;
void __iomem *rb, *reg_addr;
unsigned long flags;
+ void *kern_buf;
- rc = sscanf(buf, "%x:%x", &addr, &len);
+ kern_buf = kzalloc(nbytes, GFP_KERNEL);
+
+ if (!kern_buf) {
+ printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) {
+ kfree(kern_buf);
+ return -ENOMEM;
+ }
+
+ rc = sscanf(kern_buf, "%x:%x", &addr, &len);
if (rc < 2) {
printk(KERN_INFO
"bfad[%d]: %s failed to read user buf\n",
bfad->inst_no, __func__);
+ kfree(kern_buf);
return -EINVAL;
}
+ kfree(kern_buf);
kfree(bfad->regdata);
bfad->regdata = NULL;
bfad->reglen = 0;
@@ -339,14 +355,30 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
int addr, val, rc;
void __iomem *reg_addr;
unsigned long flags;
+ void *kern_buf;
+
+ kern_buf = kzalloc(nbytes, GFP_KERNEL);
+
+ if (!kern_buf) {
+ printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) {
+ kfree(kern_buf);
+ return -ENOMEM;
+ }
- rc = sscanf(buf, "%x:%x", &addr, &val);
+ rc = sscanf(kern_buf, "%x:%x", &addr, &val);
if (rc < 2) {
printk(KERN_INFO
"bfad[%d]: %s failed to read user buf\n",
bfad->inst_no, __func__);
+ kfree(kern_buf);
return -EINVAL;
}
+ kfree(kern_buf);
addr &= BFA_REG_ADDRMSK(bfa); /* offset only 17 bit and word align */
@@ -359,7 +391,7 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
return -EINVAL;
}
- reg_addr = (u32 *) ((u8 *) bfa_ioc_bar0(ioc) + addr);
+ reg_addr = (bfa_ioc_bar0(ioc)) + addr;
spin_lock_irqsave(&bfad->bfad_lock, flags);
writel(val, reg_addr);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 97f9b6c0937e..7f9ea90254cd 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -26,7 +26,23 @@
#ifndef __BFAD_DRV_H__
#define __BFAD_DRV_H__
-#include "bfa_os_inc.h"
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/idr.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <linux/bitops.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_transport.h>
#include "bfa_modules.h"
#include "bfa_fcs.h"
@@ -39,7 +55,7 @@
#ifdef BFA_DRIVER_VERSION
#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
#else
-#define BFAD_DRIVER_VERSION "2.3.2.0"
+#define BFAD_DRIVER_VERSION "2.3.2.3"
#endif
#define BFAD_PROTO_NAME FCPI_NAME
@@ -263,28 +279,21 @@ struct bfad_hal_comp {
*/
#define nextLowerInt(x) \
do { \
- int i; \
+ int __i; \
(*x)--; \
- for (i = 1; i < (sizeof(int)*8); i <<= 1) \
- (*x) = (*x) | (*x) >> i; \
+ for (__i = 1; __i < (sizeof(int)*8); __i <<= 1) \
+ (*x) = (*x) | (*x) >> __i; \
(*x)++; \
(*x) = (*x) >> 1; \
} while (0)
-#define list_remove_head(list, entry, type, member) \
-do { \
- entry = NULL; \
- if (!list_empty(list)) { \
- entry = list_entry((list)->next, type, member); \
- list_del_init(&entry->member); \
- } \
+#define BFA_LOG(level, bfad, mask, fmt, arg...) \
+do { \
+ if (((mask) == 4) || (level[1] <= '4')) \
+ dev_printk(level, &((bfad)->pcidev)->dev, fmt, ##arg); \
} while (0)
-#define list_get_first(list, type, member) \
-((list_empty(list)) ? NULL : \
- list_entry((list)->next, type, member))
-
bfa_status_t bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
struct bfa_lport_cfg_s *port_cfg,
struct device *dev);
@@ -316,8 +325,8 @@ void bfad_debugfs_exit(struct bfad_port_s *port);
void bfad_pci_remove(struct pci_dev *pdev);
int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
-void bfad_os_rport_online_wait(struct bfad_s *bfad);
-int bfad_os_get_linkup_delay(struct bfad_s *bfad);
+void bfad_rport_online_wait(struct bfad_s *bfad);
+int bfad_get_linkup_delay(struct bfad_s *bfad);
int bfad_install_msix_handler(struct bfad_s *bfad);
extern struct idr bfad_im_port_index;
@@ -337,7 +346,7 @@ extern int num_sgpgs;
extern int rport_del_timeout;
extern int bfa_lun_queue_depth;
extern int bfa_io_max_sge;
-extern int log_level;
+extern int bfa_log_level;
extern int ioc_auto_recover;
extern int bfa_linkup_delay;
extern int msix_disable_cb;
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 8ca967dee66d..c2b36179e8e8 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -21,7 +21,6 @@
#include "bfad_drv.h"
#include "bfad_im.h"
-#include "bfa_cb_ioim.h"
#include "bfa_fcs.h"
BFA_TRC_FILE(LDRV, IM);
@@ -93,10 +92,10 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
if (!cmnd->result && itnim &&
(bfa_lun_queue_depth > cmnd->device->queue_depth)) {
/* Queue depth adjustment for good status completion */
- bfad_os_ramp_up_qdepth(itnim, cmnd->device);
+ bfad_ramp_up_qdepth(itnim, cmnd->device);
} else if (cmnd->result == SAM_STAT_TASK_SET_FULL && itnim) {
/* qfull handling */
- bfad_os_handle_qfull(itnim, cmnd->device);
+ bfad_handle_qfull(itnim, cmnd->device);
}
}
@@ -124,7 +123,7 @@ bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio)
if (itnim_data) {
itnim = itnim_data->itnim;
if (itnim)
- bfad_os_ramp_up_qdepth(itnim, cmnd->device);
+ bfad_ramp_up_qdepth(itnim, cmnd->device);
}
}
@@ -183,7 +182,7 @@ bfad_im_info(struct Scsi_Host *shost)
bfa_get_adapter_model(bfa, model);
memset(bfa_buf, 0, sizeof(bfa_buf));
- if (ioc->ctdev)
+ if (ioc->ctdev && !ioc->fcmode)
snprintf(bfa_buf, sizeof(bfa_buf),
"Brocade FCOE Adapter, " "model: %s hwpath: %s driver: %s",
model, bfad->pci_name, BFAD_DRIVER_VERSION);
@@ -225,7 +224,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
}
bfa_trc(bfad, hal_io->iotag);
- BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n",
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
+ "scsi%d: abort cmnd %p iotag %x\n",
im_port->shost->host_no, cmnd, hal_io->iotag);
(void) bfa_ioim_abort(hal_io);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -241,7 +241,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
cmnd->scsi_done(cmnd);
bfa_trc(bfad, hal_io->iotag);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"scsi%d: complete abort 0x%p iotag 0x%x\n",
im_port->shost->host_no, cmnd, hal_io->iotag);
return SUCCESS;
@@ -257,10 +257,11 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
struct bfa_tskim_s *tskim;
struct bfa_itnim_s *bfa_itnim;
bfa_status_t rc = BFA_STATUS_OK;
+ struct scsi_lun scsilun;
tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
if (!tskim) {
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"target reset, fail to allocate tskim\n");
rc = BFA_STATUS_FAILED;
goto out;
@@ -273,7 +274,8 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
cmnd->host_scribble = NULL;
cmnd->SCp.Status = 0;
bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
- bfa_tskim_start(tskim, bfa_itnim, (lun_t)0,
+ memset(&scsilun, 0, sizeof(scsilun));
+ bfa_tskim_start(tskim, bfa_itnim, scsilun,
FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO);
out:
return rc;
@@ -300,6 +302,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
int rc = SUCCESS;
unsigned long flags;
enum bfi_tskim_status task_status;
+ struct scsi_lun scsilun;
spin_lock_irqsave(&bfad->bfad_lock, flags);
itnim = itnim_data->itnim;
@@ -311,7 +314,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
if (!tskim) {
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"LUN reset, fail to allocate tskim");
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
rc = FAILED;
@@ -326,8 +329,8 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
cmnd->SCp.ptr = (char *)&wq;
cmnd->SCp.Status = 0;
bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
- bfa_tskim_start(tskim, bfa_itnim,
- bfad_int_to_lun(cmnd->device->lun),
+ int_to_scsilun(cmnd->device->lun, &scsilun);
+ bfa_tskim_start(tskim, bfa_itnim, scsilun,
FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -336,7 +339,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
task_status = cmnd->SCp.Status >> 1;
if (task_status != BFI_TSKIM_STS_OK) {
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"LUN reset failure, status: %d\n", task_status);
rc = FAILED;
}
@@ -363,7 +366,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
for (i = 0; i < MAX_FCP_TARGET; i++) {
- itnim = bfad_os_get_itnim(im_port, i);
+ itnim = bfad_get_itnim(im_port, i);
if (itnim) {
cmnd->SCp.ptr = (char *)&wq;
rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
@@ -380,7 +383,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
task_status = cmnd->SCp.Status >> 1;
if (task_status != BFI_TSKIM_STS_OK) {
- BFA_LOG(KERN_ERR, bfad, log_level,
+ BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"target reset failure,"
" status: %d\n", task_status);
err_cnt++;
@@ -446,7 +449,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
struct bfad_im_s *im = itnim_drv->im;
/* online to free state transtion should not happen */
- bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE);
+ WARN_ON(itnim_drv->state == ITNIM_STATE_ONLINE);
itnim_drv->queue_work = 1;
/* offline request is not yet done, use the same request to free */
@@ -460,7 +463,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim);
wwn2str(wwpn_str, wwpn);
fcid2str(fcid_str, fcid);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"ITNIM FREE scsi%d: FCID: %s WWPN: %s\n",
port->im_port->shost->host_no,
fcid_str, wwpn_str);
@@ -544,7 +547,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
mutex_unlock(&bfad_mutex);
- im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad);
+ im_port->shost = bfad_scsi_host_alloc(im_port, bfad);
if (!im_port->shost) {
error = 1;
goto out_free_idr;
@@ -570,7 +573,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
}
/* setup host fixed attribute if the lk supports */
- bfad_os_fc_host_init(im_port);
+ bfad_fc_host_init(im_port);
return 0;
@@ -589,7 +592,7 @@ void
bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
{
bfa_trc(bfad, bfad->inst_no);
- BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n",
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Free scsi%d\n",
im_port->shost->host_no);
fc_remove_host(im_port->shost);
@@ -661,7 +664,7 @@ bfad_im_port_clean(struct bfad_im_port_s *im_port)
}
/* the itnim_mapped_list must be empty at this time */
- bfa_assert(list_empty(&im_port->itnim_mapped_list));
+ WARN_ON(!list_empty(&im_port->itnim_mapped_list));
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
}
@@ -681,7 +684,7 @@ bfad_im_probe(struct bfad_s *bfad)
bfad->im = im;
im->bfad = bfad;
- if (bfad_os_thread_workq(bfad) != BFA_STATUS_OK) {
+ if (bfad_thread_workq(bfad) != BFA_STATUS_OK) {
kfree(im);
rc = BFA_STATUS_FAILED;
}
@@ -694,14 +697,14 @@ void
bfad_im_probe_undo(struct bfad_s *bfad)
{
if (bfad->im) {
- bfad_os_destroy_workq(bfad->im);
+ bfad_destroy_workq(bfad->im);
kfree(bfad->im);
bfad->im = NULL;
}
}
struct Scsi_Host *
-bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
+bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
{
struct scsi_host_template *sht;
@@ -716,7 +719,7 @@ bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
}
void
-bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
+bfad_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
{
if (!(im_port->flags & BFAD_PORT_DELETE))
flush_workqueue(bfad->im->drv_workq);
@@ -726,7 +729,7 @@ bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
}
void
-bfad_os_destroy_workq(struct bfad_im_s *im)
+bfad_destroy_workq(struct bfad_im_s *im)
{
if (im && im->drv_workq) {
flush_workqueue(im->drv_workq);
@@ -736,7 +739,7 @@ bfad_os_destroy_workq(struct bfad_im_s *im)
}
bfa_status_t
-bfad_os_thread_workq(struct bfad_s *bfad)
+bfad_thread_workq(struct bfad_s *bfad)
{
struct bfad_im_s *im = bfad->im;
@@ -840,7 +843,7 @@ bfad_im_module_exit(void)
}
void
-bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
+bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
{
struct scsi_device *tmp_sdev;
@@ -868,7 +871,7 @@ bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
}
void
-bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
+bfad_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
{
struct scsi_device *tmp_sdev;
@@ -882,7 +885,7 @@ bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
}
struct bfad_itnim_s *
-bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id)
+bfad_get_itnim(struct bfad_im_port_s *im_port, int id)
{
struct bfad_itnim_s *itnim = NULL;
@@ -921,7 +924,7 @@ bfad_im_supported_speeds(struct bfa_s *bfa)
if (!ioc_attr)
return 0;
- bfa_get_attr(bfa, ioc_attr);
+ bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
if (ioc_attr->adapter_attr.max_speed == BFA_PORT_SPEED_8GBPS) {
if (ioc_attr->adapter_attr.is_mezz) {
supported_speed |= FC_PORTSPEED_8GBIT |
@@ -943,7 +946,7 @@ bfad_im_supported_speeds(struct bfa_s *bfa)
}
void
-bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
+bfad_fc_host_init(struct bfad_im_port_s *im_port)
{
struct Scsi_Host *host = im_port->shost;
struct bfad_s *bfad = im_port->bfad;
@@ -987,7 +990,7 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
rport_ids.port_name =
cpu_to_be64(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
rport_ids.port_id =
- bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
+ bfa_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
itnim->fc_rport = fc_rport =
@@ -1048,7 +1051,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
fcid2str(fcid_str, fcid);
list_add_tail(&itnim->list_entry,
&im_port->itnim_mapped_list);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"ITNIM ONLINE Target: %d:0:%d "
"FCID: %s WWPN: %s\n",
im_port->shost->host_no,
@@ -1081,7 +1084,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
wwn2str(wwpn_str, wwpn);
fcid2str(fcid_str, fcid);
list_del(&itnim->list_entry);
- BFA_LOG(KERN_INFO, bfad, log_level,
+ BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"ITNIM OFFLINE Target: %d:0:%d "
"FCID: %s WWPN: %s\n",
im_port->shost->host_no,
@@ -1108,7 +1111,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
kfree(itnim);
break;
default:
- bfa_assert(0);
+ WARN_ON(1);
break;
}
@@ -1171,7 +1174,6 @@ bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd
}
cmnd->host_scribble = (char *)hal_io;
- bfa_trc_fp(bfad, hal_io->iotag);
bfa_ioim_start(hal_io);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -1189,7 +1191,7 @@ out_fail_cmd:
static DEF_SCSI_QCMD(bfad_im_queuecommand)
void
-bfad_os_rport_online_wait(struct bfad_s *bfad)
+bfad_rport_online_wait(struct bfad_s *bfad)
{
int i;
int rport_delay = 10;
@@ -1217,7 +1219,7 @@ bfad_os_rport_online_wait(struct bfad_s *bfad)
}
int
-bfad_os_get_linkup_delay(struct bfad_s *bfad)
+bfad_get_linkup_delay(struct bfad_s *bfad)
{
u8 nwwns = 0;
wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index b038c0e08921..bfee63b16fa9 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -117,17 +117,17 @@ struct bfad_im_s {
char drv_workq_name[KOBJ_NAME_LEN];
};
-struct Scsi_Host *bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port,
+struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port,
struct bfad_s *);
-bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
-void bfad_os_destroy_workq(struct bfad_im_s *im);
-void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_scsi_host_free(struct bfad_s *bfad,
+bfa_status_t bfad_thread_workq(struct bfad_s *bfad);
+void bfad_destroy_workq(struct bfad_im_s *im);
+void bfad_fc_host_init(struct bfad_im_port_s *im_port);
+void bfad_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,
+void bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim,
struct scsi_device *sdev);
-void bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
-struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
+void bfad_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
+struct bfad_itnim_s *bfad_get_itnim(struct bfad_im_port_s *im_port, int id);
extern struct scsi_host_template bfad_im_scsi_host_template;
extern struct scsi_host_template bfad_im_vport_template;
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index 58796d1284b7..72b69a0c3b51 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -95,8 +95,8 @@ enum {
*/
union bfi_addr_u {
struct {
- u32 addr_lo;
- u32 addr_hi;
+ __be32 addr_lo;
+ __be32 addr_hi;
} a32;
};
@@ -104,7 +104,7 @@ union bfi_addr_u {
* Scatter Gather Element
*/
struct bfi_sge_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
u32 flags:2,
rsvd:2,
sg_len:28;
@@ -399,7 +399,7 @@ union bfi_ioc_i2h_msg_u {
*/
struct bfi_pbc_blun_s {
wwn_t tgt_pwwn;
- lun_t tgt_lun;
+ struct scsi_lun tgt_lun;
};
/*
diff --git a/drivers/scsi/bfa/bfi_cbreg.h b/drivers/scsi/bfa/bfi_cbreg.h
index 6f03ed382c69..39ad42b66b5b 100644
--- a/drivers/scsi/bfa/bfi_cbreg.h
+++ b/drivers/scsi/bfa/bfi_cbreg.h
@@ -208,6 +208,7 @@
#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC HOST_SEM5_INFO_REG
#define CPE_Q_DEPTH(__n) \
(CPE_Q0_DEPTH + (__n) * (CPE_Q1_DEPTH - CPE_Q0_DEPTH))
diff --git a/drivers/scsi/bfa/bfi_ctreg.h b/drivers/scsi/bfa/bfi_ctreg.h
index 62b86a4b0e4b..fc4ce4a5a183 100644
--- a/drivers/scsi/bfa/bfi_ctreg.h
+++ b/drivers/scsi/bfa/bfi_ctreg.h
@@ -522,6 +522,7 @@ enum {
#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC HOST_SEM5_INFO_REG
#define CPE_DEPTH_Q(__n) \
(CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
@@ -539,22 +540,30 @@ enum {
(RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
#define RME_CI_PTR_Q(__n) \
(RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
-#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \
- * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
-#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \
- * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
-#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \
- * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
-#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \
- * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
-#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \
- * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
-#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \
- * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
-#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \
- * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
-#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \
- * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
+#define HQM_QSET_RXQ_DRBL_P0(__n) \
+ (HQM_QSET0_RXQ_DRBL_P0 + (__n) * \
+ (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
+#define HQM_QSET_TXQ_DRBL_P0(__n) \
+ (HQM_QSET0_TXQ_DRBL_P0 + (__n) * \
+ (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
+#define HQM_QSET_IB_DRBL_1_P0(__n) \
+ (HQM_QSET0_IB_DRBL_1_P0 + (__n) * \
+ (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
+#define HQM_QSET_IB_DRBL_2_P0(__n) \
+ (HQM_QSET0_IB_DRBL_2_P0 + (__n) * \
+ (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
+#define HQM_QSET_RXQ_DRBL_P1(__n) \
+ (HQM_QSET0_RXQ_DRBL_P1 + (__n) * \
+ (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
+#define HQM_QSET_TXQ_DRBL_P1(__n) \
+ (HQM_QSET0_TXQ_DRBL_P1 + (__n) * \
+ (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
+#define HQM_QSET_IB_DRBL_1_P1(__n) \
+ (HQM_QSET0_IB_DRBL_1_P1 + (__n) * \
+ (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
+#define HQM_QSET_IB_DRBL_2_P1(__n) \
+ (HQM_QSET0_IB_DRBL_2_P1 + (__n) * \
+ (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h
index fa9f6fb9d45b..19e888a57555 100644
--- a/drivers/scsi/bfa/bfi_ms.h
+++ b/drivers/scsi/bfa/bfi_ms.h
@@ -47,10 +47,10 @@ struct bfi_iocfc_cfg_s {
*/
union bfi_addr_u req_cq_ba[BFI_IOC_MAX_CQS];
union bfi_addr_u req_shadow_ci[BFI_IOC_MAX_CQS];
- u16 req_cq_elems[BFI_IOC_MAX_CQS];
+ __be16 req_cq_elems[BFI_IOC_MAX_CQS];
union bfi_addr_u rsp_cq_ba[BFI_IOC_MAX_CQS];
union bfi_addr_u rsp_shadow_pi[BFI_IOC_MAX_CQS];
- u16 rsp_cq_elems[BFI_IOC_MAX_CQS];
+ __be16 rsp_cq_elems[BFI_IOC_MAX_CQS];
union bfi_addr_u stats_addr; /* DMA-able address for stats */
union bfi_addr_u cfgrsp_addr; /* config response dma address */
@@ -102,8 +102,8 @@ struct bfi_iocfc_set_intr_req_s {
struct bfi_mhdr_s mh; /* common msg header */
u8 coalesce; /* enable intr coalescing */
u8 rsvd[3];
- u16 delay; /* delay timer 0..1125us */
- u16 latency; /* latency timer 0..225us */
+ __be16 delay; /* delay timer 0..1125us */
+ __be16 latency; /* latency timer 0..225us */
};
@@ -188,7 +188,8 @@ 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 */
+ struct bfa_port_cfg_s port_cfg;/* port configuration */
+ u32 msgtag; /* msgtag for reply */
};
/*
@@ -202,7 +203,8 @@ struct bfi_fcport_enable_req_s {
struct bfa_port_cfg_s port_cfg; /* port configuration */
union bfi_addr_u stats_dma_addr; /* DMA address for stats */
u32 msgtag; /* msgtag for reply */
- u32 rsvd2;
+ u8 use_flash_cfg; /* get prot cfg from flash */
+ u8 rsvd2[3];
};
/*
@@ -210,7 +212,7 @@ struct bfi_fcport_enable_req_s {
*/
struct bfi_fcport_set_svc_params_req_s {
struct bfi_mhdr_s mh; /* msg header */
- u16 tx_bbcredit; /* Tx credits */
+ __be16 tx_bbcredit; /* Tx credits */
u16 rsvd;
};
@@ -231,7 +233,7 @@ struct bfi_fcport_trunk_link_s {
u8 state; /* bfa_trunk_link_state_t */
u8 speed; /* bfa_port_speed_t */
u8 rsvd;
- u32 deskew;
+ __be32 deskew;
};
#define BFI_FCPORT_MAX_LINKS 2
@@ -284,17 +286,17 @@ enum bfi_fcxp_i2h {
*/
struct bfi_fcxp_send_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 fcxp_tag; /* driver request tag */
- u16 max_frmsz; /* max send frame size */
- u16 vf_id; /* vsan tag if applicable */
+ __be16 fcxp_tag; /* driver request tag */
+ __be16 max_frmsz; /* max send frame size */
+ __be16 vf_id; /* vsan tag if applicable */
u16 rport_fw_hndl; /* FW Handle for the remote port */
u8 class; /* FC class used for req/rsp */
u8 rsp_timeout; /* timeout in secs, 0-no response */
u8 cts; /* continue sequence */
u8 lp_tag; /* lport tag */
struct fchs_s fchs; /* request FC header structure */
- u32 req_len; /* request payload length */
- u32 rsp_maxlen; /* max response length expected */
+ __be32 req_len; /* request payload length */
+ __be32 rsp_maxlen; /* max response length expected */
struct bfi_sge_s req_sge[BFA_FCXP_MAX_SGES]; /* request buf */
struct bfi_sge_s rsp_sge[BFA_FCXP_MAX_SGES]; /* response buf */
};
@@ -304,11 +306,11 @@ struct bfi_fcxp_send_req_s {
*/
struct bfi_fcxp_send_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 fcxp_tag; /* send request tag */
+ __be16 fcxp_tag; /* send request tag */
u8 req_status; /* request status */
u8 rsvd;
- u32 rsp_len; /* actual response length */
- u32 residue_len; /* residual response length */
+ __be32 rsp_len; /* actual response length */
+ __be32 residue_len; /* residual response length */
struct fchs_s fchs; /* response FC header structure */
};
@@ -325,7 +327,7 @@ enum bfi_uf_i2h {
struct bfi_uf_buf_post_s {
struct bfi_mhdr_s mh; /* Common msg header */
u16 buf_tag; /* buffer tag */
- u16 buf_len; /* total buffer length */
+ __be16 buf_len; /* total buffer length */
struct bfi_sge_s sge[BFA_UF_MAX_SGES]; /* buffer DMA SGEs */
};
@@ -340,6 +342,7 @@ struct bfi_uf_frm_rcvd_s {
enum bfi_lps_h2i_msgs {
BFI_LPS_H2I_LOGIN_REQ = 1,
BFI_LPS_H2I_LOGOUT_REQ = 2,
+ BFI_LPS_H2I_N2N_PID_REQ = 3,
};
enum bfi_lps_i2h_msgs {
@@ -352,7 +355,7 @@ struct bfi_lps_login_req_s {
struct bfi_mhdr_s mh; /* common msg header */
u8 lp_tag;
u8 alpa;
- u16 pdu_size;
+ __be16 pdu_size;
wwn_t pwwn;
wwn_t nwwn;
u8 fdisc;
@@ -368,7 +371,7 @@ struct bfi_lps_login_rsp_s {
u8 lsrjt_expl;
wwn_t port_name;
wwn_t node_name;
- u16 bb_credit;
+ __be16 bb_credit;
u8 f_port;
u8 npiv_en;
u32 lp_pid:24;
@@ -399,10 +402,17 @@ struct bfi_lps_cvl_event_s {
u8 rsvd[3];
};
+struct bfi_lps_n2n_pid_req_s {
+ struct bfi_mhdr_s mh; /* common msg header */
+ u8 lp_tag;
+ u32 lp_pid:24;
+};
+
union bfi_lps_h2i_msg_u {
struct bfi_mhdr_s *msg;
struct bfi_lps_login_req_s *login_req;
struct bfi_lps_logout_req_s *logout_req;
+ struct bfi_lps_n2n_pid_req_s *n2n_pid_req;
};
union bfi_lps_i2h_msg_u {
@@ -427,7 +437,7 @@ enum bfi_rport_i2h_msgs {
struct bfi_rport_create_req_s {
struct bfi_mhdr_s mh; /* common msg header */
u16 bfa_handle; /* host rport handle */
- u16 max_frmsz; /* max rcv pdu size */
+ __be16 max_frmsz; /* max rcv pdu size */
u32 pid:24, /* remote port ID */
lp_tag:8; /* local port tag */
u32 local_pid:24, /* local port ID */
@@ -583,7 +593,7 @@ struct bfi_ioim_dif_s {
*/
struct bfi_ioim_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 io_tag; /* I/O tag */
+ __be16 io_tag; /* I/O tag */
u16 rport_hdl; /* itnim/rport firmware handle */
struct fcp_cmnd_s cmnd; /* IO request info */
@@ -689,7 +699,7 @@ enum bfi_ioim_status {
*/
struct bfi_ioim_rsp_s {
struct bfi_mhdr_s mh; /* common msg header */
- u16 io_tag; /* completed IO tag */
+ __be16 io_tag; /* completed IO tag */
u16 bfa_rport_hndl; /* releated rport handle */
u8 io_status; /* IO completion status */
u8 reuse_io_tag; /* IO tag can be reused */
@@ -698,13 +708,13 @@ struct bfi_ioim_rsp_s {
u8 sns_len; /* scsi sense length */
u8 resid_flags; /* IO residue flags */
u8 rsvd_a;
- u32 residue; /* IO residual length in bytes */
+ __be32 residue; /* IO residual length in bytes */
u32 rsvd_b[3];
};
struct bfi_ioim_abort_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 io_tag; /* I/O tag */
+ __be16 io_tag; /* I/O tag */
u16 abort_tag; /* unique request tag */
};
@@ -723,9 +733,9 @@ enum bfi_tskim_i2h {
struct bfi_tskim_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 tsk_tag; /* task management tag */
+ __be16 tsk_tag; /* task management tag */
u16 itn_fhdl; /* itn firmware handle */
- lun_t lun; /* LU number */
+ struct scsi_lun lun; /* LU number */
u8 tm_flags; /* see enum fcp_tm_cmnd */
u8 t_secs; /* Timeout value in seconds */
u8 rsvd[2];
@@ -733,7 +743,7 @@ struct bfi_tskim_req_s {
struct bfi_tskim_abortreq_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 tsk_tag; /* task management tag */
+ __be16 tsk_tag; /* task management tag */
u16 rsvd;
};
@@ -755,7 +765,7 @@ enum bfi_tskim_status {
struct bfi_tskim_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
- u16 tsk_tag; /* task mgmt cmnd tag */
+ __be16 tsk_tag; /* task mgmt cmnd tag */
u8 tsk_status; /* @ref bfi_tskim_status */
u8 rsvd;
};
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
index 1b6f86b2482d..30e6bdbd65af 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
@@ -1,12 +1,13 @@
/* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#ifndef __57XX_ISCSI_CONSTANTS_H_
#define __57XX_ISCSI_CONSTANTS_H_
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
index 36af1afef9b6..dad6c8a34317 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
@@ -1,12 +1,13 @@
/* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI.
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#ifndef __57XX_ISCSI_HSI_LINUX_LE__
#define __57XX_ISCSI_HSI_LINUX_LE__
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index a44b1b33fa18..e1ca5fe7e6bb 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -1,6 +1,6 @@
/* bnx2i.h: Broadcom NetXtreme II iSCSI driver.
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
*
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#ifndef _BNX2I_H_
@@ -649,6 +650,7 @@ enum {
EP_STATE_OFLD_FAILED = 0x8000000,
EP_STATE_CONNECT_FAILED = 0x10000000,
EP_STATE_DISCONN_TIMEDOUT = 0x20000000,
+ EP_STATE_OFLD_FAILED_CID_BUSY = 0x80000000,
};
/**
@@ -717,14 +719,11 @@ extern struct device_attribute *bnx2i_dev_attributes[];
* Function Prototypes
*/
extern void bnx2i_identify_device(struct bnx2i_hba *hba);
-extern void bnx2i_register_device(struct bnx2i_hba *hba);
extern void bnx2i_ulp_init(struct cnic_dev *dev);
extern void bnx2i_ulp_exit(struct cnic_dev *dev);
extern void bnx2i_start(void *handle);
extern void bnx2i_stop(void *handle);
-extern void bnx2i_reg_dev_all(void);
-extern void bnx2i_unreg_dev_all(void);
extern struct bnx2i_hba *get_adapter_list_head(void);
struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba,
@@ -761,11 +760,11 @@ extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn,
struct iscsi_task *mtask);
extern void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba,
struct bnx2i_cmd *cmd);
-extern void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba,
- struct bnx2i_endpoint *ep);
-extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
-extern void bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
+extern int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep);
+extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
+extern int bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
+ struct bnx2i_endpoint *ep);
extern int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep);
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 8d9dbb33972f..96505e3ab986 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1,6 +1,6 @@
/* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver.
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
*
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#include <linux/gfp.h>
@@ -385,6 +386,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
struct bnx2i_cmd *bnx2i_cmd;
struct bnx2i_tmf_request *tmfabort_wqe;
u32 dword;
+ u32 scsi_lun[2];
bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -426,7 +428,10 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
default:
tmfabort_wqe->ref_itt = RESERVED_ITT;
}
- memcpy(tmfabort_wqe->lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
+ memcpy(scsi_lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
+ tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
+ tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
+
tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -697,10 +702,11 @@ void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba, struct bnx2i_cmd *cmd)
* this routine prepares and posts CONN_OFLD_REQ1/2 KWQE to initiate
* iscsi connection context clean-up process
*/
-void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
+int bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
struct kwqe *kwqe_arr[2];
struct iscsi_kwqe_conn_destroy conn_cleanup;
+ int rc = -EINVAL;
memset(&conn_cleanup, 0x00, sizeof(struct iscsi_kwqe_conn_destroy));
@@ -717,7 +723,9 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
kwqe_arr[0] = (struct kwqe *) &conn_cleanup;
if (hba->cnic && hba->cnic->submit_kwqes)
- hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
+ rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
+
+ return rc;
}
@@ -728,8 +736,8 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
*
* 5706/5708/5709 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
*/
-static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
- struct bnx2i_endpoint *ep)
+static int bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
+ struct bnx2i_endpoint *ep)
{
struct kwqe *kwqe_arr[2];
struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -737,6 +745,7 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
dma_addr_t dma_addr;
int num_kwqes = 2;
u32 *ptbl;
+ int rc = -EINVAL;
ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
ofld_req1.hdr.flags =
@@ -774,7 +783,9 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
ofld_req2.num_additional_wqes = 0;
if (hba->cnic && hba->cnic->submit_kwqes)
- hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+ rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+
+ return rc;
}
@@ -785,8 +796,8 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
*
* 57710 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
*/
-static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
- struct bnx2i_endpoint *ep)
+static int bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
+ struct bnx2i_endpoint *ep)
{
struct kwqe *kwqe_arr[5];
struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -795,6 +806,7 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
dma_addr_t dma_addr;
int num_kwqes = 2;
u32 *ptbl;
+ int rc = -EINVAL;
ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
ofld_req1.hdr.flags =
@@ -840,7 +852,9 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
num_kwqes += 1;
if (hba->cnic && hba->cnic->submit_kwqes)
- hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+ rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+
+ return rc;
}
/**
@@ -851,12 +865,16 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
*
* this routine prepares and posts CONN_OFLD_REQ1/2 KWQE
*/
-void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
+int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
+ int rc;
+
if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
- bnx2i_5771x_send_conn_ofld_req(hba, ep);
+ rc = bnx2i_5771x_send_conn_ofld_req(hba, ep);
else
- bnx2i_570x_send_conn_ofld_req(hba, ep);
+ rc = bnx2i_570x_send_conn_ofld_req(hba, ep);
+
+ return rc;
}
@@ -1513,7 +1531,7 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
task = iscsi_itt_to_task(conn,
nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
if (task)
- iscsi_put_task(task);
+ __iscsi_put_task(task);
spin_unlock(&session->lock);
}
@@ -1549,11 +1567,9 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
struct iscsi_task *task;
struct bnx2i_nop_in_msg *nop_in;
struct iscsi_nopin *hdr;
- u32 itt;
int tgt_async_nop = 0;
nop_in = (struct bnx2i_nop_in_msg *)cqe;
- itt = nop_in->itt & ISCSI_NOP_IN_MSG_INDEX;
spin_lock(&session->lock);
hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
@@ -1563,7 +1579,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
hdr->exp_cmdsn = cpu_to_be32(nop_in->exp_cmd_sn);
hdr->ttt = cpu_to_be32(nop_in->ttt);
- if (itt == (u16) RESERVED_ITT) {
+ if (nop_in->itt == (u16) RESERVED_ITT) {
bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
hdr->itt = RESERVED_ITT;
tgt_async_nop = 1;
@@ -1571,7 +1587,8 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
}
/* this is a response to one of our nop-outs */
- task = iscsi_itt_to_task(conn, itt);
+ task = iscsi_itt_to_task(conn,
+ (itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX));
if (task) {
hdr->flags = ISCSI_FLAG_CMD_FINAL;
hdr->itt = task->hdr->itt;
@@ -1721,9 +1738,18 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
break;
- if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx)))
+ if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) {
+ if (nopin->op_code == ISCSI_OP_NOOP_IN &&
+ nopin->itt == (u16) RESERVED_ITT) {
+ printk(KERN_ALERT "bnx2i: Unsolicited "
+ "NOP-In detected for suspended "
+ "connection dev=%s!\n",
+ bnx2i_conn->hba->netdev->name);
+ bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
+ goto cqe_out;
+ }
break;
-
+ }
tgt_async_msg = 0;
switch (nopin->op_code) {
@@ -1770,10 +1796,9 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
nopin->op_code);
}
-
if (!tgt_async_msg)
bnx2i_conn->ep->num_active_cmds--;
-
+cqe_out:
/* clear out in production version only, till beta keep opcode
* field intact, will be helpful in debugging (context dump)
* nopin->op_code = 0;
@@ -2154,11 +2179,24 @@ static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
}
if (ofld_kcqe->completion_status) {
+ ep->state = EP_STATE_OFLD_FAILED;
if (ofld_kcqe->completion_status ==
ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE)
- printk(KERN_ALERT "bnx2i: unable to allocate"
- " iSCSI context resources\n");
- ep->state = EP_STATE_OFLD_FAILED;
+ printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - unable "
+ "to allocate iSCSI context resources\n",
+ hba->netdev->name);
+ else if (ofld_kcqe->completion_status ==
+ ISCSI_KCQE_COMPLETION_STATUS_INVALID_OPCODE)
+ printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
+ "opcode\n", hba->netdev->name);
+ else if (ofld_kcqe->completion_status ==
+ ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY)
+ /* error status code valid only for 5771x chipset */
+ ep->state = EP_STATE_OFLD_FAILED_CID_BUSY;
+ else
+ printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
+ "error code %d\n", hba->netdev->name,
+ ofld_kcqe->completion_status);
} else {
ep->state = EP_STATE_OFLD_COMPL;
cid_addr = ofld_kcqe->iscsi_conn_context_id;
@@ -2339,26 +2377,32 @@ static void bnx2i_cm_remote_close(struct cnic_sock *cm_sk)
static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk)
{
struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;
+ u32 old_state = ep->state;
ep->state = EP_STATE_TCP_RST_RCVD;
- if (ep->conn)
- bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
+ if (old_state == EP_STATE_DISCONN_START)
+ wake_up_interruptible(&ep->ofld_wait);
+ else
+ if (ep->conn)
+ bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
}
-static void bnx2i_send_nl_mesg(struct cnic_dev *dev, u32 msg_type,
+static int bnx2i_send_nl_mesg(void *context, u32 msg_type,
char *buf, u16 buflen)
{
- struct bnx2i_hba *hba;
+ struct bnx2i_hba *hba = context;
+ int rc;
- hba = bnx2i_find_hba_for_cnic(dev);
if (!hba)
- return;
+ return -ENODEV;
- if (iscsi_offload_mesg(hba->shost, &bnx2i_iscsi_transport,
- msg_type, buf, buflen))
+ rc = iscsi_offload_mesg(hba->shost, &bnx2i_iscsi_transport,
+ msg_type, buf, buflen);
+ if (rc)
printk(KERN_ALERT "bnx2i: private nl message send error\n");
+ return rc;
}
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 50c2aa3b8eb1..72a7b2d4a439 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -1,6 +1,6 @@
/* bnx2i.c: Broadcom NetXtreme II iSCSI driver.
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
*
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#include "bnx2i.h"
@@ -17,8 +18,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
static u32 adapter_count;
#define DRV_MODULE_NAME "bnx2i"
-#define DRV_MODULE_VERSION "2.1.3"
-#define DRV_MODULE_RELDATE "Aug 10, 2010"
+#define DRV_MODULE_VERSION "2.6.2.2"
+#define DRV_MODULE_RELDATE "Nov 23, 2010"
static char version[] __devinitdata =
"Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -65,8 +66,6 @@ MODULE_PARM_DESC(rq_size, "Configure RQ size");
u64 iscsi_error_mask = 0x00;
-static void bnx2i_unreg_one_device(struct bnx2i_hba *hba) ;
-
/**
* bnx2i_identify_device - identifies NetXtreme II device type
@@ -211,13 +210,24 @@ void bnx2i_stop(void *handle)
{
struct bnx2i_hba *hba = handle;
int conns_active;
+ int wait_delay = 1 * HZ;
/* check if cleanup happened in GOING_DOWN context */
- if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
- &hba->adapter_state))
+ if (!test_and_set_bit(ADAPTER_STATE_GOING_DOWN,
+ &hba->adapter_state)) {
iscsi_host_for_each_session(hba->shost,
bnx2i_drop_session);
-
+ wait_delay = hba->hba_shutdown_tmo;
+ }
+ /* Wait for inflight offload connection tasks to complete before
+ * proceeding. Forcefully terminate all connection recovery in
+ * progress at the earliest, either in bind(), send_pdu(LOGIN),
+ * or conn_start()
+ */
+ wait_event_interruptible_timeout(hba->eh_wait,
+ (list_empty(&hba->ep_ofld_list) &&
+ list_empty(&hba->ep_destroy_list)),
+ 10 * HZ);
/* 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.
@@ -226,7 +236,7 @@ void bnx2i_stop(void *handle)
conns_active = hba->ofld_conns_active;
wait_event_interruptible_timeout(hba->eh_wait,
(hba->ofld_conns_active != conns_active),
- hba->hba_shutdown_tmo);
+ wait_delay);
if (hba->ofld_conns_active == conns_active)
break;
}
@@ -235,88 +245,10 @@ void bnx2i_stop(void *handle)
/* This flag should be cleared last so that ep_disconnect() gracefully
* cleans up connection context
*/
+ clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
}
-/**
- * bnx2i_register_device - register bnx2i adapter instance with the cnic driver
- * @hba: Adapter instance to register
- *
- * registers bnx2i adapter instance with the cnic driver while holding the
- * adapter structure lock
- */
-void bnx2i_register_device(struct bnx2i_hba *hba)
-{
- int rc;
-
- if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) ||
- test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
- return;
- }
-
- rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
-
- if (!rc)
- set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-}
-
-
-/**
- * bnx2i_reg_dev_all - registers all adapter instances with the cnic driver
- *
- * registers all bnx2i adapter instances with the cnic driver while holding
- * the global resource lock
- */
-void bnx2i_reg_dev_all(void)
-{
- struct bnx2i_hba *hba, *temp;
-
- mutex_lock(&bnx2i_dev_lock);
- list_for_each_entry_safe(hba, temp, &adapter_list, link)
- bnx2i_register_device(hba);
- mutex_unlock(&bnx2i_dev_lock);
-}
-
-
-/**
- * bnx2i_unreg_one_device - unregister adapter instance with the cnic driver
- * @hba: Adapter instance to unregister
- *
- * registers bnx2i adapter instance with the cnic driver while holding
- * the adapter structure lock
- */
-static void bnx2i_unreg_one_device(struct bnx2i_hba *hba)
-{
- if (hba->ofld_conns_active ||
- !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) ||
- test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state))
- return;
-
- hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
-
- /* ep_disconnect could come before NETDEV_DOWN, driver won't
- * see NETDEV_DOWN as it already unregistered itself.
- */
- hba->adapter_state = 0;
- clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-}
-
-/**
- * bnx2i_unreg_dev_all - unregisters all bnx2i instances with the cnic driver
- *
- * unregisters all bnx2i adapter instances with the cnic driver while holding
- * the global resource lock
- */
-void bnx2i_unreg_dev_all(void)
-{
- struct bnx2i_hba *hba, *temp;
-
- mutex_lock(&bnx2i_dev_lock);
- list_for_each_entry_safe(hba, temp, &adapter_list, link)
- bnx2i_unreg_one_device(hba);
- mutex_unlock(&bnx2i_dev_lock);
-}
-
/**
* bnx2i_init_one - initialize an adapter instance and allocate memory resources
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index fb50efbce087..f0dce26593eb 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1,7 +1,7 @@
/*
* bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver.
*
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
*
@@ -10,6 +10,7 @@
* the Free Software Foundation.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#include <linux/slab.h>
@@ -411,7 +412,9 @@ static void bnx2i_free_ep(struct iscsi_endpoint *ep)
bnx2i_ep->state = EP_STATE_IDLE;
bnx2i_ep->hba->ofld_conns_active--;
- bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
+ if (bnx2i_ep->ep_iscsi_cid != (u16) -1)
+ bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
+
if (bnx2i_ep->conn) {
bnx2i_ep->conn->ep = NULL;
bnx2i_ep->conn = NULL;
@@ -1383,6 +1386,12 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
ep = iscsi_lookup_endpoint(transport_fd);
if (!ep)
return -EINVAL;
+ /*
+ * Forcefully terminate all in progress connection recovery at the
+ * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
+ */
+ if (bnx2i_adapter_ready(hba))
+ return -EIO;
bnx2i_ep = ep->dd_data;
if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
@@ -1404,7 +1413,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
hba->netdev->name);
return -EEXIST;
}
-
bnx2i_ep->conn = bnx2i_conn;
bnx2i_conn->ep = bnx2i_ep;
bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
@@ -1461,21 +1469,28 @@ static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn,
struct bnx2i_conn *bnx2i_conn = conn->dd_data;
int len = 0;
+ if (!(bnx2i_conn && bnx2i_conn->ep && bnx2i_conn->ep->hba))
+ goto out;
+
switch (param) {
case ISCSI_PARAM_CONN_PORT:
- if (bnx2i_conn->ep)
+ mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
+ if (bnx2i_conn->ep->cm_sk)
len = sprintf(buf, "%hu\n",
bnx2i_conn->ep->cm_sk->dst_port);
+ mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
break;
case ISCSI_PARAM_CONN_ADDRESS:
- if (bnx2i_conn->ep)
+ mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
+ if (bnx2i_conn->ep->cm_sk)
len = sprintf(buf, "%pI4\n",
&bnx2i_conn->ep->cm_sk->dst_ip);
+ mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
break;
default:
return iscsi_conn_get_param(cls_conn, param, buf);
}
-
+out:
return len;
}
@@ -1599,8 +1614,6 @@ static struct bnx2i_hba *bnx2i_check_route(struct sockaddr *dst_addr)
struct bnx2i_hba *hba;
struct cnic_dev *cnic = NULL;
- bnx2i_reg_dev_all();
-
hba = get_adapter_list_head();
if (hba && hba->cnic)
cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI);
@@ -1640,18 +1653,26 @@ no_nx2_route:
static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic))
+ if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) && ep->cm_sk)
hba->cnic->cm_destroy(ep->cm_sk);
- if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state))
- ep->state = EP_STATE_DISCONN_COMPL;
-
if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) &&
ep->state == EP_STATE_DISCONN_TIMEDOUT) {
- printk(KERN_ALERT "bnx2i - ERROR - please submit GRC Dump,"
- " NW/PCIe trace, driver msgs to developers"
- " for analysis\n");
- return 1;
+ if (ep->conn && ep->conn->cls_conn &&
+ ep->conn->cls_conn->dd_data) {
+ struct iscsi_conn *conn = ep->conn->cls_conn->dd_data;
+
+ /* Must suspend all rx queue activity for this ep */
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
+ }
+ /* CONN_DISCONNECT timeout may or may not be an issue depending
+ * on what transcribed in TCP layer, different targets behave
+ * differently
+ */
+ printk(KERN_ALERT "bnx2i (%s): - WARN - CONN_DISCON timed out, "
+ "please submit GRC Dump, NW/PCIe trace, "
+ "driver msgs to developers for analysis\n",
+ hba->netdev->name);
}
ep->state = EP_STATE_CLEANUP_START;
@@ -1664,7 +1685,9 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
bnx2i_ep_destroy_list_add(hba, ep);
/* destroy iSCSI context, wait for it to complete */
- bnx2i_send_conn_destroy(hba, ep);
+ if (bnx2i_send_conn_destroy(hba, ep))
+ ep->state = EP_STATE_CLEANUP_CMPL;
+
wait_event_interruptible(ep->ofld_wait,
(ep->state != EP_STATE_CLEANUP_START));
@@ -1711,8 +1734,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
if (shost) {
/* driver is given scsi host to work with */
hba = iscsi_host_priv(shost);
- /* Register the device with cnic if not already done so */
- bnx2i_register_device(hba);
} else
/*
* check if the given destination can be reached through
@@ -1720,13 +1741,17 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
*/
hba = bnx2i_check_route(dst_addr);
- if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+ if (!hba) {
rc = -EINVAL;
goto nohba;
}
+ mutex_lock(&hba->net_dev_lock);
+ if (bnx2i_adapter_ready(hba) || !hba->cid_que.cid_free_cnt) {
+ rc = -EPERM;
+ goto check_busy;
+ }
cnic = hba->cnic;
- mutex_lock(&hba->net_dev_lock);
ep = bnx2i_alloc_ep(hba);
if (!ep) {
rc = -ENOMEM;
@@ -1734,23 +1759,21 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
}
bnx2i_ep = ep->dd_data;
- if (bnx2i_adapter_ready(hba)) {
- rc = -EPERM;
- goto net_if_down;
- }
-
bnx2i_ep->num_active_cmds = 0;
iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
if (iscsi_cid == -1) {
- printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n");
+ printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate "
+ "iscsi cid\n", hba->netdev->name);
rc = -ENOMEM;
- goto iscsi_cid_err;
+ bnx2i_free_ep(ep);
+ goto check_busy;
}
bnx2i_ep->hba_age = hba->age;
rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep);
if (rc != 0) {
- printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n");
+ printk(KERN_ALERT "bnx2i (%s): ep_conn - alloc QP resc error"
+ "\n", hba->netdev->name);
rc = -ENOMEM;
goto qp_resc_err;
}
@@ -1765,7 +1788,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
add_timer(&bnx2i_ep->ofld_timer);
- bnx2i_send_conn_ofld_req(hba, bnx2i_ep);
+ if (bnx2i_send_conn_ofld_req(hba, bnx2i_ep)) {
+ if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
+ printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
+ hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
+ rc = -EBUSY;
+ } else
+ rc = -ENOSPC;
+ printk(KERN_ALERT "bnx2i (%s): unable to send conn offld kwqe"
+ "\n", hba->netdev->name);
+ bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
+ goto conn_failed;
+ }
/* Wait for CNIC hardware to setup conn context and return 'cid' */
wait_event_interruptible(bnx2i_ep->ofld_wait,
@@ -1778,7 +1812,12 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) {
- rc = -ENOSPC;
+ if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
+ printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
+ hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
+ rc = -EBUSY;
+ } else
+ rc = -ENOSPC;
goto conn_failed;
}
@@ -1786,7 +1825,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep);
if (rc) {
rc = -EINVAL;
- goto conn_failed;
+ /* Need to terminate and cleanup the connection */
+ goto release_ep;
}
bnx2i_ep->cm_sk->rcv_buf = 256 * 1024;
@@ -1830,15 +1870,12 @@ release_ep:
return ERR_PTR(rc);
}
conn_failed:
-net_if_down:
-iscsi_cid_err:
bnx2i_free_qp_resc(hba, bnx2i_ep);
qp_resc_err:
bnx2i_free_ep(ep);
check_busy:
mutex_unlock(&hba->net_dev_lock);
nohba:
- bnx2i_unreg_dev_all();
return ERR_PTR(rc);
}
@@ -1898,12 +1935,13 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
cnic_dev_10g = 1;
switch (bnx2i_ep->state) {
- case EP_STATE_CONNECT_START:
+ case EP_STATE_CONNECT_FAILED:
case EP_STATE_CLEANUP_FAILED:
case EP_STATE_OFLD_FAILED:
case EP_STATE_DISCONN_TIMEDOUT:
ret = 0;
break;
+ case EP_STATE_CONNECT_START:
case EP_STATE_CONNECT_COMPL:
case EP_STATE_ULP_UPDATE_START:
case EP_STATE_ULP_UPDATE_COMPL:
@@ -1914,13 +1952,10 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
ret = 1;
break;
case EP_STATE_TCP_RST_RCVD:
- ret = 0;
- break;
- case EP_STATE_CONNECT_FAILED:
if (cnic_dev_10g)
- ret = 1;
- else
ret = 0;
+ else
+ ret = 1;
break;
default:
ret = 0;
@@ -1953,7 +1988,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
if (!cnic)
return 0;
- if (bnx2i_ep->state == EP_STATE_IDLE)
+ if (bnx2i_ep->state == EP_STATE_IDLE ||
+ bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
return 0;
if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
@@ -1979,9 +2015,10 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
if (session->state == ISCSI_STATE_LOGGING_OUT) {
if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
/* Logout sent, but no resp */
- printk(KERN_ALERT "bnx2i - WARNING "
- "logout response was not "
- "received!\n");
+ printk(KERN_ALERT "bnx2i (%s): WARNING"
+ " logout response was not "
+ "received!\n",
+ bnx2i_ep->hba->netdev->name);
} else if (bnx2i_ep->state ==
EP_STATE_LOGOUT_RESP_RCVD)
close = 1;
@@ -1999,9 +2036,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
else
close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
- /* No longer allow CFC delete if cm_close/abort fails the request */
if (close_ret)
- printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n",
+ printk(KERN_ALERT "bnx2i (%s): close/abort(%d) returned %d\n",
bnx2i_ep->hba->netdev->name, close, close_ret);
else
/* wait for option-2 conn teardown */
@@ -2015,7 +2051,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
destroy_conn:
bnx2i_ep_active_list_del(hba, bnx2i_ep);
if (bnx2i_tear_down_conn(hba, bnx2i_ep))
- ret = -EINVAL;
+ return -EINVAL;
out:
bnx2i_ep->state = EP_STATE_IDLE;
return ret;
@@ -2054,14 +2090,17 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
mutex_lock(&hba->net_dev_lock);
- if (bnx2i_ep->state == EP_STATE_IDLE)
- goto return_bnx2i_ep;
+ if (bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
+ goto out;
- if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
+ if (bnx2i_ep->state == EP_STATE_IDLE)
goto free_resc;
- if (bnx2i_ep->hba_age != hba->age)
+ if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) ||
+ (bnx2i_ep->hba_age != hba->age)) {
+ bnx2i_ep_active_list_del(hba, bnx2i_ep);
goto free_resc;
+ }
/* Do all chip cleanup here */
if (bnx2i_hw_ep_disconnect(bnx2i_ep)) {
@@ -2070,14 +2109,13 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
}
free_resc:
bnx2i_free_qp_resc(hba, bnx2i_ep);
-return_bnx2i_ep:
+
if (bnx2i_conn)
bnx2i_conn->ep = NULL;
bnx2i_free_ep(ep);
+out:
mutex_unlock(&hba->net_dev_lock);
- if (!hba->ofld_conns_active)
- bnx2i_unreg_dev_all();
wake_up_interruptible(&hba->eh_wait);
}
diff --git a/drivers/scsi/bnx2i/bnx2i_sysfs.c b/drivers/scsi/bnx2i/bnx2i_sysfs.c
index 96426b751eb2..9174196d9033 100644
--- a/drivers/scsi/bnx2i/bnx2i_sysfs.c
+++ b/drivers/scsi/bnx2i/bnx2i_sysfs.c
@@ -1,12 +1,13 @@
/* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver.
*
- * Copyright (c) 2004 - 2009 Broadcom Corporation
+ * Copyright (c) 2004 - 2010 Broadcom 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
*/
#include "bnx2i.h"
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index be5661707dfa..d2ad3d676724 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -825,7 +825,7 @@ unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *csk, unsigned int pmtu)
unsigned int idx;
struct dst_entry *dst = csk->dst;
- csk->advmss = dst_metric(dst, RTAX_ADVMSS);
+ csk->advmss = dst_metric_advmss(dst);
if (csk->advmss > pmtu - 40)
csk->advmss = pmtu - 40;
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index 6fae3d285ae7..b837c5b3c8f9 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -442,12 +442,19 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
sdev = q->queuedata;
if (sdev && sdev->scsi_dh_data)
scsi_dh = sdev->scsi_dh_data->scsi_dh;
- if (!scsi_dh || !get_device(&sdev->sdev_gendev))
+ if (!scsi_dh || !get_device(&sdev->sdev_gendev) ||
+ sdev->sdev_state == SDEV_CANCEL ||
+ sdev->sdev_state == SDEV_DEL)
err = SCSI_DH_NOSYS;
+ if (sdev->sdev_state == SDEV_OFFLINE)
+ err = SCSI_DH_DEV_OFFLINED;
spin_unlock_irqrestore(q->queue_lock, flags);
- if (err)
+ if (err) {
+ if (fn)
+ fn(data, err);
return err;
+ }
if (scsi_dh->activate)
err = scsi_dh->activate(sdev, fn, data);
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index d23a538a9dfc..9f9600b67001 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -854,7 +854,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
/* Cleanup the fc_lport */
fc_lport_destroy(lport);
- fc_fcp_destroy(lport);
/* Stop the transmit retry timer */
del_timer_sync(&port->timer);
@@ -876,6 +875,9 @@ static void fcoe_if_destroy(struct fc_lport *lport)
fc_remove_host(lport->host);
scsi_remove_host(lport->host);
+ /* Destroy lport scsi_priv */
+ fc_fcp_destroy(lport);
+
/* There are no more rports or I/O, free the EM */
fc_exch_mgr_free(lport);
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index bc17c7123202..625c6be25396 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -54,6 +54,7 @@ MODULE_LICENSE("GPL v2");
static void fcoe_ctlr_timeout(unsigned long);
static void fcoe_ctlr_timer_work(struct work_struct *);
static void fcoe_ctlr_recv_work(struct work_struct *);
+static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
@@ -176,6 +177,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
fip->mode = mode;
INIT_LIST_HEAD(&fip->fcfs);
mutex_init(&fip->ctlr_mutex);
+ spin_lock_init(&fip->ctlr_lock);
fip->flogi_oxid = FC_XID_UNKNOWN;
setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
@@ -231,6 +233,49 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
EXPORT_SYMBOL(fcoe_ctlr_destroy);
/**
+ * fcoe_ctlr_announce() - announce new FCF selection
+ * @fip: The FCoE controller
+ *
+ * Also sets the destination MAC for FCoE and control packets
+ *
+ * Called with neither ctlr_mutex nor ctlr_lock held.
+ */
+static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
+{
+ struct fcoe_fcf *sel;
+ struct fcoe_fcf *fcf;
+
+ mutex_lock(&fip->ctlr_mutex);
+ spin_lock_bh(&fip->ctlr_lock);
+
+ kfree_skb(fip->flogi_req);
+ fip->flogi_req = NULL;
+ list_for_each_entry(fcf, &fip->fcfs, list)
+ fcf->flogi_sent = 0;
+
+ spin_unlock_bh(&fip->ctlr_lock);
+ sel = fip->sel_fcf;
+
+ if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr))
+ goto unlock;
+ if (!is_zero_ether_addr(fip->dest_addr)) {
+ printk(KERN_NOTICE "libfcoe: host%d: "
+ "FIP Fibre-Channel Forwarder MAC %pM deselected\n",
+ fip->lp->host->host_no, fip->dest_addr);
+ memset(fip->dest_addr, 0, ETH_ALEN);
+ }
+ if (sel) {
+ printk(KERN_INFO "libfcoe: host%d: FIP selected "
+ "Fibre-Channel Forwarder MAC %pM\n",
+ fip->lp->host->host_no, sel->fcf_mac);
+ memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
+ fip->map_dest = 0;
+ }
+unlock:
+ mutex_unlock(&fip->ctlr_mutex);
+}
+
+/**
* fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port
* @fip: The FCoE controller to get the maximum FCoE size from
*
@@ -564,6 +609,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
* The caller must check that the length is a multiple of 4.
* The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
* The the skb must also be an fc_frame.
+ *
+ * This is called from the lower-level driver with spinlocks held,
+ * so we must not take a mutex here.
*/
int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
struct sk_buff *skb)
@@ -601,7 +649,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
switch (op) {
case ELS_FLOGI:
op = FIP_DT_FLOGI;
- break;
+ if (fip->mode == FIP_MODE_VN2VN)
+ break;
+ spin_lock_bh(&fip->ctlr_lock);
+ kfree_skb(fip->flogi_req);
+ fip->flogi_req = skb;
+ fip->flogi_req_send = 1;
+ spin_unlock_bh(&fip->ctlr_lock);
+ schedule_work(&fip->timer_work);
+ return -EINPROGRESS;
case ELS_FDISC:
if (ntoh24(fh->fh_s_id))
return 0;
@@ -922,11 +978,9 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
}
mtu_valid = fcoe_ctlr_mtu_valid(fcf);
fcf->time = jiffies;
- if (!found) {
- LIBFCOE_FIP_DBG(fip, "New FCF for fab %16.16llx "
- "map %x val %d\n",
- fcf->fabric_name, fcf->fc_map, mtu_valid);
- }
+ if (!found)
+ LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
+ fcf->fabric_name, fcf->fcf_mac);
/*
* If this advertisement is not solicited and our max receive size
@@ -945,6 +999,17 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
fcoe_ctlr_solicit(fip, NULL);
/*
+ * Put this FCF at the head of the list for priority among equals.
+ * This helps in the case of an NPV switch which insists we use
+ * the FCF that answers multicast solicitations, not the others that
+ * are sending periodic multicast advertisements.
+ */
+ if (mtu_valid) {
+ list_del(&fcf->list);
+ list_add(&fcf->list, &fip->fcfs);
+ }
+
+ /*
* If this is the first validated FCF, note the time and
* set a timer to trigger selection.
*/
@@ -1061,18 +1126,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
els_op = *(u8 *)(fh + 1);
if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
- sub == FIP_SC_REP && els_op == ELS_LS_ACC &&
- fip->mode != FIP_MODE_VN2VN) {
- if (!is_valid_ether_addr(granted_mac)) {
- LIBFCOE_FIP_DBG(fip,
- "Invalid MAC address %pM in FIP ELS\n",
- granted_mac);
- goto drop;
- }
- memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
+ sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) {
+ if (els_op == ELS_LS_ACC) {
+ if (!is_valid_ether_addr(granted_mac)) {
+ LIBFCOE_FIP_DBG(fip,
+ "Invalid MAC address %pM in FIP ELS\n",
+ granted_mac);
+ goto drop;
+ }
+ memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
- if (fip->flogi_oxid == ntohs(fh->fh_ox_id))
- fip->flogi_oxid = FC_XID_UNKNOWN;
+ if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ if (els_dtype == FIP_DT_FLOGI)
+ fcoe_ctlr_announce(fip);
+ }
+ } else if (els_dtype == FIP_DT_FLOGI &&
+ !fcoe_ctlr_flogi_retry(fip))
+ goto drop; /* retrying FLOGI so drop reject */
}
if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) &&
@@ -1326,20 +1397,39 @@ drop:
* fcoe_ctlr_select() - Select the best FCF (if possible)
* @fip: The FCoE controller
*
+ * Returns the selected FCF, or NULL if none are usable.
+ *
* If there are conflicting advertisements, no FCF can be chosen.
*
+ * If there is already a selected FCF, this will choose a better one or
+ * an equivalent one that hasn't already been sent a FLOGI.
+ *
* Called with lock held.
*/
-static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
+static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
struct fcoe_fcf *fcf;
- struct fcoe_fcf *best = NULL;
+ struct fcoe_fcf *best = fip->sel_fcf;
+ struct fcoe_fcf *first;
+
+ first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);
list_for_each_entry(fcf, &fip->fcfs, list) {
- LIBFCOE_FIP_DBG(fip, "consider FCF for fab %16.16llx "
- "VFID %d map %x val %d\n",
- fcf->fabric_name, fcf->vfid,
- fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
+ LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
+ "VFID %d mac %pM map %x val %d "
+ "sent %u pri %u\n",
+ fcf->fabric_name, fcf->vfid, fcf->fcf_mac,
+ fcf->fc_map, fcoe_ctlr_mtu_valid(fcf),
+ fcf->flogi_sent, fcf->pri);
+ if (fcf->fabric_name != first->fabric_name ||
+ fcf->vfid != first->vfid ||
+ fcf->fc_map != first->fc_map) {
+ LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
+ "or FC-MAP\n");
+ return NULL;
+ }
+ if (fcf->flogi_sent)
+ continue;
if (!fcoe_ctlr_fcf_usable(fcf)) {
LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
"map %x %svalid %savailable\n",
@@ -1349,21 +1439,131 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
"" : "un");
continue;
}
- if (!best) {
- best = fcf;
- continue;
- }
- if (fcf->fabric_name != best->fabric_name ||
- fcf->vfid != best->vfid ||
- fcf->fc_map != best->fc_map) {
- LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
- "or FC-MAP\n");
- return;
- }
- if (fcf->pri < best->pri)
+ if (!best || fcf->pri < best->pri || best->flogi_sent)
best = fcf;
}
fip->sel_fcf = best;
+ if (best) {
+ LIBFCOE_FIP_DBG(fip, "using FCF mac %pM\n", best->fcf_mac);
+ fip->port_ka_time = jiffies +
+ msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ fip->ctlr_ka_time = jiffies + best->fka_period;
+ if (time_before(fip->ctlr_ka_time, fip->timer.expires))
+ mod_timer(&fip->timer, fip->ctlr_ka_time);
+ }
+ return best;
+}
+
+/**
+ * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF
+ * @fip: The FCoE controller
+ *
+ * Returns non-zero error if it could not be sent.
+ *
+ * Called with ctlr_mutex and ctlr_lock held.
+ * Caller must verify that fip->sel_fcf is not NULL.
+ */
+static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
+{
+ struct sk_buff *skb;
+ struct sk_buff *skb_orig;
+ struct fc_frame_header *fh;
+ int error;
+
+ skb_orig = fip->flogi_req;
+ if (!skb_orig)
+ return -EINVAL;
+
+ /*
+ * Clone and send the FLOGI request. If clone fails, use original.
+ */
+ skb = skb_clone(skb_orig, GFP_ATOMIC);
+ if (!skb) {
+ skb = skb_orig;
+ fip->flogi_req = NULL;
+ }
+ fh = (struct fc_frame_header *)skb->data;
+ error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb,
+ ntoh24(fh->fh_d_id));
+ if (error) {
+ kfree_skb(skb);
+ return error;
+ }
+ fip->send(fip, skb);
+ fip->sel_fcf->flogi_sent = 1;
+ return 0;
+}
+
+/**
+ * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible
+ * @fip: The FCoE controller
+ *
+ * Returns non-zero error code if there's no FLOGI request to retry or
+ * no alternate FCF available.
+ */
+static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
+{
+ struct fcoe_fcf *fcf;
+ int error;
+
+ mutex_lock(&fip->ctlr_mutex);
+ spin_lock_bh(&fip->ctlr_lock);
+ LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
+ fcf = fcoe_ctlr_select(fip);
+ if (!fcf || fcf->flogi_sent) {
+ kfree_skb(fip->flogi_req);
+ fip->flogi_req = NULL;
+ error = -ENOENT;
+ } else {
+ fcoe_ctlr_solicit(fip, NULL);
+ error = fcoe_ctlr_flogi_send_locked(fip);
+ }
+ spin_unlock_bh(&fip->ctlr_lock);
+ mutex_unlock(&fip->ctlr_mutex);
+ return error;
+}
+
+
+/**
+ * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI.
+ * @fip: The FCoE controller that timed out
+ *
+ * Done here because fcoe_ctlr_els_send() can't get mutex.
+ *
+ * Called with ctlr_mutex held. The caller must not hold ctlr_lock.
+ */
+static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
+{
+ struct fcoe_fcf *fcf;
+
+ spin_lock_bh(&fip->ctlr_lock);
+ fcf = fip->sel_fcf;
+ if (!fcf || !fip->flogi_req_send)
+ goto unlock;
+
+ LIBFCOE_FIP_DBG(fip, "sending FLOGI\n");
+
+ /*
+ * If this FLOGI is being sent due to a timeout retry
+ * to the same FCF as before, select a different FCF if possible.
+ */
+ if (fcf->flogi_sent) {
+ LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n");
+ fcf = fcoe_ctlr_select(fip);
+ if (!fcf || fcf->flogi_sent) {
+ LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n");
+ list_for_each_entry(fcf, &fip->fcfs, list)
+ fcf->flogi_sent = 0;
+ fcf = fcoe_ctlr_select(fip);
+ }
+ }
+ if (fcf) {
+ fcoe_ctlr_flogi_send_locked(fip);
+ fip->flogi_req_send = 0;
+ } else /* XXX */
+ LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
+unlock:
+ spin_unlock_bh(&fip->ctlr_lock);
}
/**
@@ -1411,34 +1611,16 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
sel = fip->sel_fcf;
if (!sel && fip->sel_time) {
if (time_after_eq(jiffies, fip->sel_time)) {
- fcoe_ctlr_select(fip);
- sel = fip->sel_fcf;
+ sel = fcoe_ctlr_select(fip);
fip->sel_time = 0;
} else if (time_after(next_timer, fip->sel_time))
next_timer = fip->sel_time;
}
- if (sel != fcf) {
- fcf = sel; /* the old FCF may have been freed */
- if (sel) {
- printk(KERN_INFO "libfcoe: host%d: FIP selected "
- "Fibre-Channel Forwarder MAC %pM\n",
- fip->lp->host->host_no, sel->fcf_mac);
- memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
- fip->map_dest = 0;
- fip->port_ka_time = jiffies +
- msecs_to_jiffies(FIP_VN_KA_PERIOD);
- fip->ctlr_ka_time = jiffies + sel->fka_period;
- if (time_after(next_timer, fip->ctlr_ka_time))
- next_timer = fip->ctlr_ka_time;
- } else {
- printk(KERN_NOTICE "libfcoe: host%d: "
- "FIP Fibre-Channel Forwarder timed out. "
- "Starting FCF discovery.\n",
- fip->lp->host->host_no);
- reset = 1;
- }
- }
+ if (sel && fip->flogi_req_send)
+ fcoe_ctlr_flogi_send(fip);
+ else if (!sel && fcf)
+ reset = 1;
if (sel && !sel->fd_flags) {
if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
@@ -2475,7 +2657,7 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)
case FIP_ST_LINK_WAIT:
goto unlock;
default:
- WARN(1, "unexpected state %d", fip->state);
+ WARN(1, "unexpected state %d\n", fip->state);
goto unlock;
}
mod_timer(&fip->timer, next_time);
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 76365700e2d5..3242bcabad97 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -4273,8 +4273,10 @@ static int ioc_general(void __user *arg, char *cmnd)
}
rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info);
- if (rval < 0)
+ if (rval < 0) {
+ gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
return rval;
+ }
gen.status = rval;
if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index 0572b9bf4bd6..652754319a4b 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -365,8 +365,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len = 0;
begin = pos;
}
- if (pos > offset + length)
+ if (pos > offset + length) {
+ gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
goto stop_output;
+ }
}
}
gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
@@ -450,8 +452,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len = 0;
begin = pos;
}
- if (pos > offset + length)
+ if (pos > offset + length) {
+ gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
goto stop_output;
+ }
} while (drv_no != -1);
if (is_mirr) {
@@ -472,8 +476,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len = 0;
begin = pos;
}
- if (pos > offset + length)
+ if (pos > offset + length) {
+ gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
goto stop_output;
+ }
}
gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
@@ -542,8 +548,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len = 0;
begin = pos;
}
- if (pos > offset + length)
+ if (pos > offset + length) {
+ gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
goto stop_output;
+ }
}
}
gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b2fb2b2a6e70..12deffccb8da 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254},
-#define PCI_DEVICE_ID_HP_CISSF 0x333f
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F},
- {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
- {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
};
@@ -113,8 +109,6 @@ static struct board_type products[] = {
{0x3249103C, "Smart Array P812", &SA5_access},
{0x324a103C, "Smart Array P712m", &SA5_access},
{0x324b103C, "Smart Array P711m", &SA5_access},
- {0x3233103C, "StorageWorks P1210m", &SA5_access},
- {0x333F103C, "StorageWorks P1210m", &SA5_access},
{0x3250103C, "Smart Array", &SA5_access},
{0x3250113C, "Smart Array", &SA5_access},
{0x3250123C, "Smart Array", &SA5_access},
@@ -647,11 +641,6 @@ static void fixup_botched_add(struct ctlr_info *h,
static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
struct hpsa_scsi_dev_t *dev2)
{
- if ((is_logical_dev_addr_mode(dev1->scsi3addr) ||
- (dev1->lun != -1 && dev2->lun != -1)) &&
- dev1->devtype != 0x0C)
- return (memcmp(dev1, dev2, sizeof(*dev1)) == 0);
-
/* we compare everything except lun and target as these
* are not yet assigned. Compare parts likely
* to differ first
@@ -666,12 +655,8 @@ static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
return 0;
if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0)
return 0;
- if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0)
- return 0;
if (dev1->devtype != dev2->devtype)
return 0;
- if (dev1->raid_level != dev2->raid_level)
- return 0;
if (dev1->bus != dev2->bus)
return 0;
return 1;
@@ -1483,8 +1468,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
sizeof(this_device->vendor));
memcpy(this_device->model, &inq_buff[16],
sizeof(this_device->model));
- memcpy(this_device->revision, &inq_buff[32],
- sizeof(this_device->revision));
memset(this_device->device_id, 0,
sizeof(this_device->device_id));
hpsa_get_device_id(h, scsi3addr, this_device->device_id,
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index a203ef65cb50..19586e189f0f 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -45,7 +45,6 @@ struct hpsa_scsi_dev_t {
unsigned char device_id[16]; /* from inquiry pg. 0x83 */
unsigned char vendor[8]; /* bytes 8-15 of inquiry data */
unsigned char model[16]; /* bytes 16-31 of inquiry data */
- unsigned char revision[4]; /* bytes 32-35 of inquiry data */
unsigned char raid_level; /* from inquiry page 0xC1 */
};
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 57cad7e20caa..b7650613b8c2 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2493,23 +2493,23 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
}
static const struct ibmvfc_async_desc ae_desc [] = {
- { IBMVFC_AE_ELS_PLOGI, "PLOGI", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
- { IBMVFC_AE_ELS_LOGO, "LOGO", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
- { IBMVFC_AE_ELS_PRLO, "PRLO", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
- { IBMVFC_AE_SCN_NPORT, "N-Port SCN", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
- { IBMVFC_AE_SCN_GROUP, "Group SCN", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
- { IBMVFC_AE_SCN_DOMAIN, "Domain SCN", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_SCN_FABRIC, "Fabric SCN", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_LINK_UP, "Link Up", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_LINK_DOWN, "Link Down", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_LINK_DEAD, "Link Dead", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_HALT, "Halt", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_RESUME, "Resume", IBMVFC_DEFAULT_LOG_LEVEL },
- { IBMVFC_AE_ADAPTER_FAILED, "Adapter Failed", IBMVFC_DEFAULT_LOG_LEVEL },
+ { "PLOGI", IBMVFC_AE_ELS_PLOGI, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+ { "LOGO", IBMVFC_AE_ELS_LOGO, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+ { "PRLO", IBMVFC_AE_ELS_PRLO, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+ { "N-Port SCN", IBMVFC_AE_SCN_NPORT, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+ { "Group SCN", IBMVFC_AE_SCN_GROUP, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+ { "Domain SCN", IBMVFC_AE_SCN_DOMAIN, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Fabric SCN", IBMVFC_AE_SCN_FABRIC, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Link Up", IBMVFC_AE_LINK_UP, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Link Down", IBMVFC_AE_LINK_DOWN, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Link Dead", IBMVFC_AE_LINK_DEAD, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Halt", IBMVFC_AE_HALT, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Resume", IBMVFC_AE_RESUME, IBMVFC_DEFAULT_LOG_LEVEL },
+ { "Adapter Failed", IBMVFC_AE_ADAPTER_FAILED, IBMVFC_DEFAULT_LOG_LEVEL },
};
static const struct ibmvfc_async_desc unknown_ae = {
- 0, "Unknown async", IBMVFC_DEFAULT_LOG_LEVEL
+ "Unknown async", 0, IBMVFC_DEFAULT_LOG_LEVEL
};
/**
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index ef663e7c9bbc..834c37fc7ce9 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -542,8 +542,8 @@ enum ibmvfc_async_event {
};
struct ibmvfc_async_desc {
- enum ibmvfc_async_event ae;
const char *desc;
+ enum ibmvfc_async_event ae;
int log_level;
};
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 5bbaee597e88..9c5c8be72231 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -146,7 +146,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
}
},
{ /* CRoC */
- .mailbox = 0x00040,
+ .mailbox = 0x00044,
.cache_line_size = 0x20,
{
.set_interrupt_mask_reg = 0x00010,
@@ -1048,6 +1048,8 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
sizeof(res->res_path));
res->bus = 0;
+ memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+ sizeof(res->dev_lun.scsi_lun));
res->lun = scsilun_to_int(&res->dev_lun);
if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
@@ -1063,9 +1065,6 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
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;
@@ -1116,7 +1115,7 @@ static int ipr_is_same_device(struct ipr_resource_entry *res,
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,
+ !memcmp(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
sizeof(cfgtew->u.cfgte64->lun))) {
return 1;
}
@@ -2901,6 +2900,12 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
return;
}
+ if (ioa_cfg->sis64) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ ssleep(IPR_DUMP_DELAY_SECONDS);
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ }
+
start_addr = readl(ioa_cfg->ioa_mailbox);
if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
@@ -5743,7 +5748,7 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
}
if (ipr_is_gata(res) && res->sata_port)
- return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);
+ return ata_sas_queuecmd(scsi_cmd, res->sata_port->ap);
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ioarcb = &ipr_cmd->ioarcb;
@@ -7473,6 +7478,29 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
}
/**
+ * ipr_reset_get_unit_check_job - Call to get the unit check buffer.
+ * @ipr_cmd: ipr command struct
+ *
+ * Description: This function will call to get the unit check buffer.
+ *
+ * Return value:
+ * IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+ ENTER;
+ ioa_cfg->ioa_unit_checked = 0;
+ ipr_get_unit_check_buffer(ioa_cfg);
+ ipr_cmd->job_step = ipr_reset_alert;
+ ipr_reset_start_timer(ipr_cmd, 0);
+
+ LEAVE;
+ return IPR_RC_JOB_RETURN;
+}
+
+/**
* ipr_reset_restore_cfg_space - Restore PCI config space.
* @ipr_cmd: ipr command struct
*
@@ -7487,16 +7515,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
volatile u32 int_reg;
- int rc;
ENTER;
ioa_cfg->pdev->state_saved = true;
- rc = pci_restore_state(ioa_cfg->pdev);
-
- if (rc != PCIBIOS_SUCCESSFUL) {
- ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
- return IPR_RC_JOB_CONTINUE;
- }
+ pci_restore_state(ioa_cfg->pdev);
if (ipr_set_pcix_cmd_reg(ioa_cfg)) {
ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
@@ -7512,11 +7534,17 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
}
if (ioa_cfg->ioa_unit_checked) {
- ioa_cfg->ioa_unit_checked = 0;
- ipr_get_unit_check_buffer(ioa_cfg);
- ipr_cmd->job_step = ipr_reset_alert;
- ipr_reset_start_timer(ipr_cmd, 0);
- return IPR_RC_JOB_RETURN;
+ if (ioa_cfg->sis64) {
+ ipr_cmd->job_step = ipr_reset_get_unit_check_job;
+ ipr_reset_start_timer(ipr_cmd, IPR_DUMP_DELAY_TIMEOUT);
+ return IPR_RC_JOB_RETURN;
+ } else {
+ ioa_cfg->ioa_unit_checked = 0;
+ ipr_get_unit_check_buffer(ioa_cfg);
+ ipr_cmd->job_step = ipr_reset_alert;
+ ipr_reset_start_timer(ipr_cmd, 0);
+ return IPR_RC_JOB_RETURN;
+ }
}
if (ioa_cfg->in_ioa_bringdown) {
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index b28a00f1082c..13f425fb8851 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -218,6 +218,8 @@
#define IPR_WAIT_FOR_BIST_TIMEOUT (2 * HZ)
#define IPR_PCI_RESET_TIMEOUT (HZ / 2)
#define IPR_DUMP_TIMEOUT (15 * HZ)
+#define IPR_DUMP_DELAY_SECONDS 4
+#define IPR_DUMP_DELAY_TIMEOUT (IPR_DUMP_DELAY_SECONDS * HZ)
/*
* SCSI Literals
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index ec2a1aec2350..d21367d3305f 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -67,6 +67,11 @@ struct workqueue_struct *fc_exch_workqueue;
struct fc_exch_pool {
u16 next_index;
u16 total_exches;
+
+ /* two cache of free slot in exch array */
+ u16 left;
+ u16 right;
+
spinlock_t lock;
struct list_head ex_list;
};
@@ -108,7 +113,6 @@ struct fc_exch_mgr {
atomic_t non_bls_resp;
} stats;
};
-#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
/**
* struct fc_exch_mgr_anchor - primary structure for list of EMs
@@ -397,13 +401,23 @@ static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
static void fc_exch_delete(struct fc_exch *ep)
{
struct fc_exch_pool *pool;
+ u16 index;
pool = ep->pool;
spin_lock_bh(&pool->lock);
WARN_ON(pool->total_exches <= 0);
pool->total_exches--;
- fc_exch_ptr_set(pool, (ep->xid - ep->em->min_xid) >> fc_cpu_order,
- NULL);
+
+ /* update cache of free slot */
+ index = (ep->xid - ep->em->min_xid) >> fc_cpu_order;
+ if (pool->left == FC_XID_UNKNOWN)
+ pool->left = index;
+ else if (pool->right == FC_XID_UNKNOWN)
+ pool->right = index;
+ else
+ pool->next_index = index;
+
+ fc_exch_ptr_set(pool, index, NULL);
list_del(&ep->ex_list);
spin_unlock_bh(&pool->lock);
fc_exch_release(ep); /* drop hold for exch in mp */
@@ -636,10 +650,13 @@ static void fc_exch_timeout(struct work_struct *work)
if (e_stat & ESB_ST_ABNORMAL)
rc = fc_exch_done_locked(ep);
spin_unlock_bh(&ep->ex_lock);
- if (!rc)
- fc_exch_delete(ep);
if (resp)
resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
+ if (!rc) {
+ /* delete the exchange if it's already being aborted */
+ fc_exch_delete(ep);
+ return;
+ }
fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
goto done;
}
@@ -679,6 +696,19 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
pool = per_cpu_ptr(mp->pool, cpu);
spin_lock_bh(&pool->lock);
put_cpu();
+
+ /* peek cache of free slot */
+ if (pool->left != FC_XID_UNKNOWN) {
+ index = pool->left;
+ pool->left = FC_XID_UNKNOWN;
+ goto hit;
+ }
+ if (pool->right != FC_XID_UNKNOWN) {
+ index = pool->right;
+ pool->right = FC_XID_UNKNOWN;
+ goto hit;
+ }
+
index = pool->next_index;
/* allocate new exch from pool */
while (fc_exch_ptr_get(pool, index)) {
@@ -687,7 +717,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
goto err;
}
pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
-
+hit:
fc_exch_hold(ep); /* hold for exch in mp */
spin_lock_init(&ep->ex_lock);
/*
@@ -1247,7 +1277,7 @@ static struct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp)
list_for_each_entry(ema, &lport->ema_list, ema_list)
if ((!ema->match || ema->match(fp)) &&
- fc_seq_lookup_recip(lport, ema->mp, fp) != FC_RJT_NONE)
+ fc_seq_lookup_recip(lport, ema->mp, fp) == FC_RJT_NONE)
break;
return fr_seq(fp);
}
@@ -1343,7 +1373,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
}
if (ep->esb_stat & ESB_ST_COMPLETE) {
atomic_inc(&mp->stats.xid_not_found);
- goto out;
+ goto rel;
}
if (ep->rxid == FC_XID_UNKNOWN)
ep->rxid = ntohs(fh->fh_rx_id);
@@ -2181,6 +2211,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
goto free_mempool;
for_each_possible_cpu(cpu) {
pool = per_cpu_ptr(mp->pool, cpu);
+ pool->left = FC_XID_UNKNOWN;
+ pool->right = FC_XID_UNKNOWN;
spin_lock_init(&pool->lock);
INIT_LIST_HEAD(&pool->ex_list);
}
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 2924363d142b..cdc06cda76e5 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -57,6 +57,9 @@ struct kmem_cache *scsi_pkt_cachep;
#define FC_SRB_READ (1 << 1)
#define FC_SRB_WRITE (1 << 0)
+/* constant added to e_d_tov timeout to get rec_tov value */
+#define REC_TOV_CONST 1
+
/*
* The SCp.ptr should be tested and set under the scsi_pkt_queue lock
*/
@@ -96,7 +99,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
-static void fc_fcp_recovery(struct fc_fcp_pkt *);
+static void fc_fcp_recovery(struct fc_fcp_pkt *, u8 code);
static void fc_fcp_timeout(unsigned long);
static void fc_fcp_rec(struct fc_fcp_pkt *);
static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
@@ -120,14 +123,13 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
#define FC_DATA_UNDRUN 7
#define FC_ERROR 8
#define FC_HRD_ERROR 9
-#define FC_CMD_RECOVERY 10
+#define FC_CRC_ERROR 10
+#define FC_TIMED_OUT 11
/*
* Error recovery timeout values.
*/
-#define FC_SCSI_ER_TIMEOUT (10 * HZ)
#define FC_SCSI_TM_TOV (10 * HZ)
-#define FC_SCSI_REC_TOV (2 * HZ)
#define FC_HOST_RESET_TIMEOUT (30 * HZ)
#define FC_CAN_QUEUE_PERIOD (60 * HZ)
@@ -438,6 +440,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
void *buf;
struct scatterlist *sg;
u32 nents;
+ u8 host_bcode = FC_COMPLETE;
fh = fc_frame_header_get(fp);
offset = ntohl(fh->fh_parm_offset);
@@ -446,13 +449,16 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
buf = fc_frame_payload_get(fp, 0);
/*
- * if this I/O is ddped then clear it
- * and initiate recovery since data
- * frames are expected to be placed
- * directly in that case.
+ * if this I/O is ddped then clear it and initiate recovery since data
+ * frames are expected to be placed directly in that case.
+ *
+ * Indicate error to scsi-ml because something went wrong with the
+ * ddp handling to get us here.
*/
if (fsp->xfer_ddp != FC_XID_UNKNOWN) {
fc_fcp_ddp_done(fsp);
+ FC_FCP_DBG(fsp, "DDP I/O in fc_fcp_recv_data set ERROR\n");
+ host_bcode = FC_ERROR;
goto err;
}
if (offset + len > fsp->data_len) {
@@ -462,6 +468,9 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
goto crc_err;
FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
"data_len %x\n", len, offset, fsp->data_len);
+
+ /* Data is corrupted indicate scsi-ml should retry */
+ host_bcode = FC_DATA_OVRRUN;
goto err;
}
if (offset != fsp->xfer_len)
@@ -498,8 +507,10 @@ crc_err:
* If so, we need to retry the entire operation.
* Otherwise, ignore it.
*/
- if (fsp->state & FC_SRB_DISCONTIG)
+ if (fsp->state & FC_SRB_DISCONTIG) {
+ host_bcode = FC_CRC_ERROR;
goto err;
+ }
return;
}
}
@@ -517,7 +528,7 @@ crc_err:
fc_fcp_complete_locked(fsp);
return;
err:
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, host_bcode);
}
/**
@@ -962,7 +973,13 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
}
lport->tt.exch_done(seq);
}
- fc_io_compl(fsp);
+ /*
+ * Some resets driven by SCSI are not I/Os and do not have
+ * SCSI commands associated with the requests. We should not
+ * call I/O completion if we do not have a SCSI command.
+ */
+ if (fsp->cmd)
+ fc_io_compl(fsp);
}
/**
@@ -1073,6 +1090,21 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
}
/**
+ * get_fsp_rec_tov() - Helper function to get REC_TOV
+ * @fsp: the FCP packet
+ */
+static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
+{
+ struct fc_rport *rport;
+ struct fc_rport_libfc_priv *rpriv;
+
+ rport = fsp->rport;
+ rpriv = rport->dd_data;
+
+ return rpriv->e_d_tov + REC_TOV_CONST;
+}
+
+/**
* fc_fcp_cmd_send() - Send a FCP command
* @lport: The local port to send the command on
* @fsp: The FCP packet the command is on
@@ -1089,6 +1121,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
struct fc_rport_libfc_priv *rpriv;
const size_t len = sizeof(fsp->cdb_cmd);
int rc = 0;
+ unsigned int rec_tov;
if (fc_fcp_lock_pkt(fsp))
return 0;
@@ -1119,10 +1152,13 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
fsp->seq_ptr = seq;
fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */
+ rec_tov = get_fsp_rec_tov(fsp);
+
setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
- fc_fcp_timer_set(fsp,
- (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ?
- FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT);
+
+ if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
+ fc_fcp_timer_set(fsp, rec_tov);
+
unlock:
fc_fcp_unlock_pkt(fsp);
return rc;
@@ -1197,13 +1233,16 @@ static void fc_lun_reset_send(unsigned long data)
{
struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
struct fc_lport *lport = fsp->lp;
+ unsigned int rec_tov;
+
if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
return;
if (fc_fcp_lock_pkt(fsp))
return;
+ rec_tov = get_fsp_rec_tov(fsp);
setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp);
- fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+ fc_fcp_timer_set(fsp, rec_tov);
fc_fcp_unlock_pkt(fsp);
}
}
@@ -1282,27 +1321,27 @@ static void fc_tm_done(struct fc_seq *seq, struct fc_frame *fp, void *arg)
*
* scsi-eh will escalate for when either happens.
*/
- return;
+ goto out;
}
if (fc_fcp_lock_pkt(fsp))
- return;
+ goto out;
/*
* raced with eh timeout handler.
*/
- if (!fsp->seq_ptr || !fsp->wait_for_comp) {
- spin_unlock_bh(&fsp->scsi_pkt_lock);
- return;
- }
+ if (!fsp->seq_ptr || !fsp->wait_for_comp)
+ goto out_unlock;
fh = fc_frame_header_get(fp);
if (fh->fh_type != FC_TYPE_BLS)
fc_fcp_resp(fsp, fp);
fsp->seq_ptr = NULL;
fsp->lp->tt.exch_done(seq);
- fc_frame_free(fp);
+out_unlock:
fc_fcp_unlock_pkt(fsp);
+out:
+ fc_frame_free(fp);
}
/**
@@ -1341,13 +1380,10 @@ static void fc_fcp_timeout(unsigned long data)
if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
fc_fcp_rec(fsp);
- else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2),
- jiffies))
- fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
else if (fsp->state & FC_SRB_RCV_STATUS)
fc_fcp_complete_locked(fsp);
else
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_TIMED_OUT);
fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
unlock:
fc_fcp_unlock_pkt(fsp);
@@ -1373,6 +1409,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
fc_fcp_complete_locked(fsp);
return;
}
+
fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
if (!fp)
goto retry;
@@ -1383,15 +1420,15 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
FC_FCTL_REQ, 0);
if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
fc_fcp_rec_resp, fsp,
- jiffies_to_msecs(FC_SCSI_REC_TOV))) {
+ 2 * lport->r_a_tov)) {
fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
return;
}
retry:
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
- fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+ fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp));
else
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_TIMED_OUT);
}
/**
@@ -1445,7 +1482,6 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
* making progress.
*/
rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
- fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
break;
case ELS_RJT_LOGIC:
case ELS_RJT_UNAB:
@@ -1460,7 +1496,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
fc_fcp_retry_cmd(fsp);
break;
}
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_ERROR);
break;
}
} else if (opcode == ELS_LS_ACC) {
@@ -1498,12 +1534,12 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
}
fc_fcp_srr(fsp, r_ctl, offset);
} else if (e_stat & ESB_ST_SEQ_INIT) {
-
+ unsigned int rec_tov = get_fsp_rec_tov(fsp);
/*
* The remote port has the initiative, so just
* keep waiting for it to complete.
*/
- fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+ fc_fcp_timer_set(fsp, rec_tov);
} else {
/*
@@ -1575,7 +1611,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
fc_fcp_rec(fsp);
else
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_ERROR);
break;
}
fc_fcp_unlock_pkt(fsp);
@@ -1587,9 +1623,9 @@ out:
* fc_fcp_recovery() - Handler for fcp_pkt recovery
* @fsp: The FCP pkt that needs to be aborted
*/
-static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
+static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code)
{
- fsp->status_code = FC_CMD_RECOVERY;
+ fsp->status_code = code;
fsp->cdb_status = 0;
fsp->io_status = 0;
/*
@@ -1616,6 +1652,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
struct fcp_srr *srr;
struct fc_frame *fp;
u8 cdb_op;
+ unsigned int rec_tov;
rport = fsp->rport;
rpriv = rport->dd_data;
@@ -1640,8 +1677,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
rpriv->local_port->port_id, FC_TYPE_FCP,
FC_FCTL_REQ, 0);
+ rec_tov = get_fsp_rec_tov(fsp);
seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
- fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+ fsp, jiffies_to_msecs(rec_tov));
if (!seq)
goto retry;
@@ -1665,6 +1703,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
{
struct fc_fcp_pkt *fsp = arg;
struct fc_frame_header *fh;
+ unsigned int rec_tov;
if (IS_ERR(fp)) {
fc_fcp_srr_error(fsp, fp);
@@ -1691,11 +1730,12 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
switch (fc_frame_payload_op(fp)) {
case ELS_LS_ACC:
fsp->recov_retry = 0;
- fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+ rec_tov = get_fsp_rec_tov(fsp);
+ fc_fcp_timer_set(fsp, rec_tov);
break;
case ELS_LS_RJT:
default:
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_ERROR);
break;
}
fc_fcp_unlock_pkt(fsp);
@@ -1721,7 +1761,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
fc_fcp_rec(fsp);
else
- fc_fcp_recovery(fsp);
+ fc_fcp_recovery(fsp, FC_TIMED_OUT);
break;
case -FC_EX_CLOSED: /* e.g., link failure */
/* fall through */
@@ -1820,19 +1860,17 @@ static int fc_queuecommand_lck(struct scsi_cmnd *sc_cmd, void (*done)(struct scs
if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
fsp->req_flags = FC_SRB_READ;
stats->InputRequests++;
- stats->InputMegabytes = fsp->data_len;
+ stats->InputBytes += fsp->data_len;
} else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
fsp->req_flags = FC_SRB_WRITE;
stats->OutputRequests++;
- stats->OutputMegabytes = fsp->data_len;
+ stats->OutputBytes += fsp->data_len;
} else {
fsp->req_flags = 0;
stats->ControlRequests++;
}
put_cpu();
- fsp->tgt_flags = rpriv->flags;
-
init_timer(&fsp->timer);
fsp->timer.data = (unsigned long)fsp;
@@ -1946,18 +1984,29 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
break;
case FC_CMD_ABORTED:
FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
- "due to FC_CMD_ABORTED\n");
+ "due to FC_CMD_ABORTED\n");
sc_cmd->result = (DID_ERROR << 16) | fsp->io_status;
break;
- case FC_CMD_RECOVERY:
- sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
- break;
case FC_CMD_RESET:
+ FC_FCP_DBG(fsp, "Returning DID_RESET to scsi-ml "
+ "due to FC_CMD_RESET\n");
sc_cmd->result = (DID_RESET << 16);
break;
case FC_HRD_ERROR:
+ FC_FCP_DBG(fsp, "Returning DID_NO_CONNECT to scsi-ml "
+ "due to FC_HRD_ERROR\n");
sc_cmd->result = (DID_NO_CONNECT << 16);
break;
+ case FC_CRC_ERROR:
+ FC_FCP_DBG(fsp, "Returning DID_PARITY to scsi-ml "
+ "due to FC_CRC_ERROR\n");
+ sc_cmd->result = (DID_PARITY << 16);
+ break;
+ case FC_TIMED_OUT:
+ FC_FCP_DBG(fsp, "Returning DID_BUS_BUSY to scsi-ml "
+ "due to FC_TIMED_OUT\n");
+ sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
+ break;
default:
FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
"due to unknown error\n");
@@ -2004,7 +2053,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
fsp = CMD_SP(sc_cmd);
if (!fsp) {
/* command completed while scsi eh was setting up */
- spin_unlock_irqrestore(lport->host->host_lock, flags);
+ spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
return SUCCESS;
}
/* grab a ref so the fsp and sc_cmd cannot be relased from under us */
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
index 16d2162dda1f..eea0c3541b71 100644
--- a/drivers/scsi/libfc/fc_libfc.h
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -66,9 +66,21 @@ extern unsigned int fc_debug_logging;
#define FC_FCP_DBG(pkt, fmt, args...) \
FC_CHECK_LOGGING(FC_FCP_LOGGING, \
- printk(KERN_INFO "host%u: fcp: %6.6x: " fmt, \
+ { \
+ if ((pkt)->seq_ptr) { \
+ struct fc_exch *_ep = NULL; \
+ _ep = fc_seq_exch((pkt)->seq_ptr); \
+ printk(KERN_INFO "host%u: fcp: %6.6x: " \
+ "xid %04x-%04x: " fmt, \
(pkt)->lp->host->host_no, \
- pkt->rport->port_id, ##args))
+ (pkt)->rport->port_id, \
+ (_ep)->oxid, (_ep)->rxid, ##args); \
+ } else { \
+ printk(KERN_INFO "host%u: fcp: %6.6x: " fmt, \
+ (pkt)->lp->host->host_no, \
+ (pkt)->rport->port_id, ##args); \
+ } \
+ })
#define FC_EXCH_DBG(exch, fmt, args...) \
FC_CHECK_LOGGING(FC_EXCH_LOGGING, \
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 9be63edbf8fb..c5a10f94f845 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -288,6 +288,8 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
struct fc_lport *lport = shost_priv(shost);
struct timespec v0, v1;
unsigned int cpu;
+ u64 fcp_in_bytes = 0;
+ u64 fcp_out_bytes = 0;
fcoe_stats = &lport->host_stats;
memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
@@ -310,10 +312,12 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
fcoe_stats->fcp_input_requests += stats->InputRequests;
fcoe_stats->fcp_output_requests += stats->OutputRequests;
fcoe_stats->fcp_control_requests += stats->ControlRequests;
- fcoe_stats->fcp_input_megabytes += stats->InputMegabytes;
- fcoe_stats->fcp_output_megabytes += stats->OutputMegabytes;
+ fcp_in_bytes += stats->InputBytes;
+ fcp_out_bytes += stats->OutputBytes;
fcoe_stats->link_failure_count += stats->LinkFailureCount;
}
+ fcoe_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
+ fcoe_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
fcoe_stats->lip_count = -1;
fcoe_stats->nos_count = -1;
fcoe_stats->loss_of_sync_count = -1;
@@ -1703,8 +1707,10 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
info->sg = job->reply_payload.sg_list;
if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
- NULL, info, tov))
+ NULL, info, tov)) {
+ kfree(info);
return -ECOMM;
+ }
return 0;
}
@@ -1762,8 +1768,10 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
info->sg = job->reply_payload.sg_list;
if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
- NULL, info, tov))
+ NULL, info, tov)) {
+ kfree(info);
return -ECOMM;
+ }
return 0;
}
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index a84ef13ed74a..a7175adab32d 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -652,7 +652,7 @@ void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_RPORT_DBG(rdata, "Received a FLOGI %s\n", fc_els_resp_type(fp));
if (fp == ERR_PTR(-FC_EX_CLOSED))
- return;
+ goto put;
mutex_lock(&rdata->rp_mutex);
@@ -689,6 +689,7 @@ out:
fc_frame_free(fp);
err:
mutex_unlock(&rdata->rp_mutex);
+put:
kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
return;
bad:
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c15fde808c33..da8b61543ee4 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -505,6 +505,7 @@ static void iscsi_free_task(struct iscsi_task *task)
struct iscsi_conn *conn = task->conn;
struct iscsi_session *session = conn->session;
struct scsi_cmnd *sc = task->sc;
+ int oldstate = task->state;
ISCSI_DBG_SESSION(session, "freeing task itt 0x%x state %d sc %p\n",
task->itt, task->state, task->sc);
@@ -525,10 +526,10 @@ static void iscsi_free_task(struct iscsi_task *task)
/* SCSI eh reuses commands to verify us */
sc->SCp.ptr = NULL;
/*
- * queue command may call this to free the task, but
- * not have setup the sc callback
+ * queue command may call this to free the task, so
+ * it will decide how to return sc to scsi-ml.
*/
- if (sc->scsi_done)
+ if (oldstate != ISCSI_TASK_REQUEUE_SCSIQ)
sc->scsi_done(sc);
}
}
@@ -539,11 +540,12 @@ void __iscsi_get_task(struct iscsi_task *task)
}
EXPORT_SYMBOL_GPL(__iscsi_get_task);
-static void __iscsi_put_task(struct iscsi_task *task)
+void __iscsi_put_task(struct iscsi_task *task)
{
if (atomic_dec_and_test(&task->refcount))
iscsi_free_task(task);
}
+EXPORT_SYMBOL_GPL(__iscsi_put_task);
void iscsi_put_task(struct iscsi_task *task)
{
@@ -571,7 +573,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
task->itt, task->state, task->sc);
if (task->state == ISCSI_TASK_COMPLETED ||
task->state == ISCSI_TASK_ABRT_TMF ||
- task->state == ISCSI_TASK_ABRT_SESS_RECOV)
+ task->state == ISCSI_TASK_ABRT_SESS_RECOV ||
+ task->state == ISCSI_TASK_REQUEUE_SCSIQ)
return;
WARN_ON_ONCE(task->state == ISCSI_TASK_FREE);
task->state = state;
@@ -1335,17 +1338,16 @@ void iscsi_session_failure(struct iscsi_session *session,
{
struct iscsi_conn *conn;
struct device *dev;
- unsigned long flags;
- spin_lock_irqsave(&session->lock, flags);
+ spin_lock_bh(&session->lock);
conn = session->leadconn;
if (session->state == ISCSI_STATE_TERMINATE || !conn) {
- spin_unlock_irqrestore(&session->lock, flags);
+ spin_unlock_bh(&session->lock);
return;
}
dev = get_device(&conn->cls_conn->dev);
- spin_unlock_irqrestore(&session->lock, flags);
+ spin_unlock_bh(&session->lock);
if (!dev)
return;
/*
@@ -1364,17 +1366,16 @@ EXPORT_SYMBOL_GPL(iscsi_session_failure);
void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
{
struct iscsi_session *session = conn->session;
- unsigned long flags;
- spin_lock_irqsave(&session->lock, flags);
+ spin_lock_bh(&session->lock);
if (session->state == ISCSI_STATE_FAILED) {
- spin_unlock_irqrestore(&session->lock, flags);
+ spin_unlock_bh(&session->lock);
return;
}
if (conn->stop_stage == 0)
session->state = ISCSI_STATE_FAILED;
- spin_unlock_irqrestore(&session->lock, flags);
+ spin_unlock_bh(&session->lock);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
@@ -1599,27 +1600,23 @@ enum {
FAILURE_SESSION_NOT_READY,
};
-static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
{
struct iscsi_cls_session *cls_session;
- struct Scsi_Host *host;
struct iscsi_host *ihost;
int reason = 0;
struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_task *task = NULL;
- sc->scsi_done = done;
sc->result = 0;
sc->SCp.ptr = NULL;
- host = sc->device->host;
ihost = shost_priv(host);
- spin_unlock(host->host_lock);
cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data;
- spin_lock(&session->lock);
+ spin_lock_bh(&session->lock);
reason = iscsi_session_chkready(cls_session);
if (reason) {
@@ -1705,25 +1702,21 @@ static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi
}
session->queued_cmdsn++;
- spin_unlock(&session->lock);
- spin_lock(host->host_lock);
+ spin_unlock_bh(&session->lock);
return 0;
prepd_reject:
- sc->scsi_done = NULL;
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
reject:
- spin_unlock(&session->lock);
+ spin_unlock_bh(&session->lock);
ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
sc->cmnd[0], reason);
- spin_lock(host->host_lock);
return SCSI_MLQUEUE_TARGET_BUSY;
prepd_fault:
- sc->scsi_done = NULL;
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
fault:
- spin_unlock(&session->lock);
+ spin_unlock_bh(&session->lock);
ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
sc->cmnd[0], reason);
if (!scsi_bidi_cmnd(sc))
@@ -1732,12 +1725,9 @@ fault:
scsi_out(sc)->resid = scsi_out(sc)->length;
scsi_in(sc)->resid = scsi_in(sc)->length;
}
- done(sc);
- spin_lock(host->host_lock);
+ sc->scsi_done(sc);
return 0;
}
-
-DEF_SCSI_QCMD(iscsi_queuecommand)
EXPORT_SYMBOL_GPL(iscsi_queuecommand);
int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
@@ -1795,9 +1785,9 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
NULL, 0);
if (!task) {
spin_unlock_bh(&session->lock);
+ iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n");
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
spin_lock_bh(&session->lock);
- ISCSI_DBG_EH(session, "tmf exec failure\n");
return -EPERM;
}
conn->tmfcmd_pdus_cnt++;
@@ -2202,7 +2192,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
goto success_unlocked;
case TMF_TIMEDOUT:
spin_unlock_bh(&session->lock);
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
goto failed_unlocked;
case TMF_NOT_FOUND:
if (!sc->SCp.ptr) {
@@ -2289,7 +2279,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
break;
case TMF_TIMEDOUT:
spin_unlock_bh(&session->lock);
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
goto done;
default:
conn->tmf_state = TMF_INITIAL;
@@ -2370,7 +2360,7 @@ failed:
* we drop the lock here but the leadconn cannot be destoyed while
* we are in the scsi eh
*/
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
ISCSI_DBG_EH(session, "wait for relogin\n");
wait_event_interruptible(conn->ehwait,
@@ -2452,7 +2442,7 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc)
break;
case TMF_TIMEDOUT:
spin_unlock_bh(&session->lock);
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
goto done;
default:
conn->tmf_state = TMF_INITIAL;
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index fe8b74c706d2..5257fdfe699a 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -28,6 +28,17 @@
#include <scsi/scsi_transport_sas.h>
#include "../scsi_sas_internal.h"
+static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy *phy)
+{
+ struct sas_ha_struct *sas_ha = phy->ha;
+
+ if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
+ SAS_ADDR_SIZE) != 0 || (sas_ha->strict_wide_ports &&
+ memcmp(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE) != 0))
+ return false;
+ return true;
+}
+
/**
* sas_form_port -- add this phy to a port
* @phy: the phy of interest
@@ -45,8 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
unsigned long flags;
if (port) {
- if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
- SAS_ADDR_SIZE) != 0)
+ if (!phy_is_wideport_member(port, phy))
sas_deform_port(phy);
else {
SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
@@ -62,9 +72,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
port = sas_ha->sas_port[i];
spin_lock(&port->phy_list_lock);
if (*(u64 *) port->sas_addr &&
- memcmp(port->attached_sas_addr,
- phy->attached_sas_addr, SAS_ADDR_SIZE) == 0 &&
- port->num_phys > 0) {
+ phy_is_wideport_member(port, phy) && port->num_phys > 0) {
/* wide port */
SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
port->id);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 29251fabecc6..5815cbeb27a6 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -211,8 +211,7 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd,
unsigned long flags;
spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
- res = ata_sas_queuecmd(cmd, scsi_done,
- dev->sata_dev.ap);
+ res = ata_sas_queuecmd(cmd, dev->sata_dev.ap);
spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
goto out;
}
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 196de40b906c..746dd3d7a092 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -464,12 +464,29 @@ struct unsol_rcv_ct_ctx {
#define UNSOL_VALID 0x00000001
};
+#define LPFC_USER_LINK_SPEED_AUTO 0 /* auto select (default)*/
+#define LPFC_USER_LINK_SPEED_1G 1 /* 1 Gigabaud */
+#define LPFC_USER_LINK_SPEED_2G 2 /* 2 Gigabaud */
+#define LPFC_USER_LINK_SPEED_4G 4 /* 4 Gigabaud */
+#define LPFC_USER_LINK_SPEED_8G 8 /* 8 Gigabaud */
+#define LPFC_USER_LINK_SPEED_10G 10 /* 10 Gigabaud */
+#define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_16G
+#define LPFC_USER_LINK_SPEED_BITMAP ((1 << LPFC_USER_LINK_SPEED_16G) | \
+ (1 << LPFC_USER_LINK_SPEED_10G) | \
+ (1 << LPFC_USER_LINK_SPEED_8G) | \
+ (1 << LPFC_USER_LINK_SPEED_4G) | \
+ (1 << LPFC_USER_LINK_SPEED_2G) | \
+ (1 << LPFC_USER_LINK_SPEED_1G) | \
+ (1 << LPFC_USER_LINK_SPEED_AUTO))
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16"
+
struct lpfc_hba {
/* SCSI interface function jump table entries */
int (*lpfc_new_scsi_buf)
(struct lpfc_vport *, int);
struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
- (struct lpfc_hba *);
+ (struct lpfc_hba *, struct lpfc_nodelist *);
int (*lpfc_scsi_prep_dma_buf)
(struct lpfc_hba *, struct lpfc_scsi_buf *);
void (*lpfc_scsi_unprep_dma_buf)
@@ -545,7 +562,7 @@ struct lpfc_hba {
uint32_t hba_flag; /* hba generic flags */
#define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */
#define DEFER_ERATT 0x2 /* Deferred error attention in progress */
-#define HBA_FCOE_SUPPORT 0x4 /* HBA function supports FCOE */
+#define HBA_FCOE_MODE 0x4 /* HBA function in FCoE Mode */
#define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/
#define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
#define FCP_XRI_ABORT_EVENT 0x20
@@ -557,6 +574,7 @@ struct lpfc_hba {
#define HBA_FIP_SUPPORT 0x800 /* FIP support in HBA */
#define HBA_AER_ENABLED 0x1000 /* AER enabled with HBA */
#define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */
+#define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
struct lpfc_dmabuf slim2p;
@@ -606,6 +624,7 @@ struct lpfc_hba {
/* HBA Config Parameters */
uint32_t cfg_ack0;
uint32_t cfg_enable_npiv;
+ uint32_t cfg_enable_rrq;
uint32_t cfg_topology;
uint32_t cfg_link_speed;
uint32_t cfg_cr_delay;
@@ -716,6 +735,7 @@ struct lpfc_hba {
uint32_t total_scsi_bufs;
struct list_head lpfc_iocb_list;
uint32_t total_iocbq_bufs;
+ struct list_head active_rrq_list;
spinlock_t hbalock;
/* pci_mem_pools */
@@ -728,6 +748,7 @@ struct lpfc_hba {
mempool_t *mbox_mem_pool;
mempool_t *nlp_mem_pool;
+ mempool_t *rrq_pool;
struct fc_host_statistics link_stats;
enum intr_type_t intr_type;
@@ -784,6 +805,7 @@ struct lpfc_hba {
unsigned long skipped_hb;
struct timer_list hb_tmofunc;
uint8_t hb_outstanding;
+ struct timer_list rrq_tmr;
enum hba_temp_state over_temp_state;
/* ndlp reference management */
spinlock_t ndlp_lock;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c1cbec01345d..c06491b5862f 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -52,10 +52,6 @@
#define LPFC_MIN_DEVLOSS_TMO 1
#define LPFC_MAX_DEVLOSS_TMO 255
-#define LPFC_MAX_LINK_SPEED 8
-#define LPFC_LINK_SPEED_BITMAP 0x00000117
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8"
-
/**
* lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
* @incr: integer to convert.
@@ -463,7 +459,7 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
len += snprintf(buf + len, PAGE_SIZE-len,
" Menlo Maint Mode\n");
- else if (phba->fc_topology == TOPOLOGY_LOOP) {
+ else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
if (vport->fc_flag & FC_PUBLIC_LOOP)
len += snprintf(buf + len, PAGE_SIZE-len,
" Public Loop\n");
@@ -1981,6 +1977,13 @@ lpfc_param_show(enable_npiv);
lpfc_param_init(enable_npiv, 1, 0, 1);
static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL);
+int lpfc_enable_rrq;
+module_param(lpfc_enable_rrq, int, 0);
+MODULE_PARM_DESC(lpfc_enable_rrq, "Enable RRQ functionality");
+lpfc_param_show(enable_rrq);
+lpfc_param_init(enable_rrq, 0, 0, 1);
+static DEVICE_ATTR(lpfc_enable_rrq, S_IRUGO, lpfc_enable_rrq_show, NULL);
+
/*
# lpfc_suppress_link_up: Bring link up at initialization
# 0x0 = bring link up (issue MBX_INIT_LINK)
@@ -2837,14 +2840,8 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
/*
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
# connection.
-# 0 = auto select (default)
-# 1 = 1 Gigabaud
-# 2 = 2 Gigabaud
-# 4 = 4 Gigabaud
-# 8 = 8 Gigabaud
-# Value range is [0,8]. Default value is 0.
+# Value range is [0,16]. Default value is 0.
*/
-
/**
* lpfc_link_speed_set - Set the adapters link speed
* @phba: lpfc_hba pointer.
@@ -2869,7 +2866,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
struct Scsi_Host *shost = class_to_shost(dev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- int val = 0;
+ int val = LPFC_USER_LINK_SPEED_AUTO;
int nolip = 0;
const char *val_buf = buf;
int err;
@@ -2885,15 +2882,20 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
if (sscanf(val_buf, "%i", &val) != 1)
return -EINVAL;
- if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
- ((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
- ((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
- ((val == LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
- ((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)))
+ if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
+ ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
+ ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
+ ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
+ ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
+ ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb))) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2879 lpfc_link_speed attribute cannot be set "
+ "to %d. Speed is not supported by this port.\n",
+ val);
return -EINVAL;
-
- if ((val >= 0 && val <= 8)
- && (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
+ }
+ if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
+ (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -2906,11 +2908,9 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
} else
return strlen(buf);
}
-
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0469 lpfc_link_speed attribute cannot be set to %d, "
- "allowed range is [0, 8]\n",
- phba->brd_no, val);
+ "0469 lpfc_link_speed attribute cannot be set to %d, "
+ "allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);
return -EINVAL;
}
@@ -2938,8 +2938,8 @@ lpfc_param_show(link_speed)
static int
lpfc_link_speed_init(struct lpfc_hba *phba, int val)
{
- if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED)
- && (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
+ if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
+ (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
phba->cfg_link_speed = val;
return 0;
}
@@ -2947,12 +2947,12 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
"0405 lpfc_link_speed attribute cannot "
"be set to %d, allowed values are "
"["LPFC_LINK_SPEED_STRING"]\n", val);
- phba->cfg_link_speed = 0;
+ phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
return -EINVAL;
}
static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR,
- lpfc_link_speed_show, lpfc_link_speed_store);
+ lpfc_link_speed_show, lpfc_link_speed_store);
/*
# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
@@ -3305,12 +3305,12 @@ LPFC_ATTR_R(fcp_eq_count, LPFC_FP_EQN_DEF, LPFC_FP_EQN_MIN, LPFC_FP_EQN_MAX,
LPFC_ATTR_R(enable_hba_reset, 1, 0, 1, "Enable HBA resets from the driver.");
/*
-# lpfc_enable_hba_heartbeat: Enable HBA heartbeat timer..
+# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
# 0 = HBA Heartbeat disabled
# 1 = HBA Heartbeat enabled (default)
# Value range is [0,1]. Default value is 1.
*/
-LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat.");
+LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
/*
# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
@@ -3401,6 +3401,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_fdmi_on,
&dev_attr_lpfc_max_luns,
&dev_attr_lpfc_enable_npiv,
+ &dev_attr_lpfc_enable_rrq,
&dev_attr_nport_evt_cnt,
&dev_attr_board_mode,
&dev_attr_max_vpi,
@@ -3798,8 +3799,7 @@ sysfs_mbox_read(struct file *filp, struct kobject *kobj,
}
break;
case MBX_READ_SPARM64:
- case MBX_READ_LA:
- case MBX_READ_LA64:
+ case MBX_READ_TOPOLOGY:
case MBX_REG_LOGIN:
case MBX_REG_LOGIN64:
case MBX_CONFIG_PORT:
@@ -3989,7 +3989,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
if (vport->port_type == LPFC_NPIV_PORT) {
fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
} else if (lpfc_is_link_up(phba)) {
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
if (vport->fc_flag & FC_PUBLIC_LOOP)
fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
else
@@ -4058,23 +4058,26 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
if (lpfc_is_link_up(phba)) {
switch(phba->fc_linkspeed) {
- case LA_1GHZ_LINK:
- fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
+ case LPFC_LINK_SPEED_1GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
break;
- case LA_2GHZ_LINK:
- fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
+ case LPFC_LINK_SPEED_2GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
break;
- case LA_4GHZ_LINK:
- fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
+ case LPFC_LINK_SPEED_4GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
break;
- case LA_8GHZ_LINK:
- fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
+ case LPFC_LINK_SPEED_8GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
break;
- case LA_10GHZ_LINK:
- fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
+ case LPFC_LINK_SPEED_10GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
break;
- default:
- fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+ case LPFC_LINK_SPEED_16GHZ:
+ fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
+ break;
+ default:
+ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
}
} else
@@ -4097,7 +4100,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
spin_lock_irq(shost->host_lock);
if ((vport->fc_flag & FC_FABRIC) ||
- ((phba->fc_topology == TOPOLOGY_LOOP) &&
+ ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
(vport->fc_flag & FC_PUBLIC_LOOP)))
node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
else
@@ -4208,11 +4211,11 @@ lpfc_get_stats(struct Scsi_Host *shost)
hs->invalid_crc_count -= lso->invalid_crc_count;
hs->error_frames -= lso->error_frames;
- if (phba->hba_flag & HBA_FCOE_SUPPORT) {
+ if (phba->hba_flag & HBA_FCOE_MODE) {
hs->lip_count = -1;
hs->nos_count = (phba->link_events >> 1);
hs->nos_count -= lso->link_events;
- } else if (phba->fc_topology == TOPOLOGY_LOOP) {
+ } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
hs->lip_count = (phba->fc_eventTag >> 1);
hs->lip_count -= lso->link_events;
hs->nos_count = -1;
@@ -4303,7 +4306,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
lso->error_frames = pmb->un.varRdLnk.crcCnt;
- if (phba->hba_flag & HBA_FCOE_SUPPORT)
+ if (phba->hba_flag & HBA_FCOE_MODE)
lso->link_events = (phba->link_events >> 1);
else
lso->link_events = (phba->fc_eventTag >> 1);
@@ -4615,6 +4618,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_link_speed_init(phba, lpfc_link_speed);
lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
+ lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
lpfc_use_msi_init(phba, lpfc_use_msi);
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count);
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 7260c3af555a..0dd43bb91618 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
struct lpfc_iocbq *cmdiocbq,
struct lpfc_iocbq *rspiocbq)
{
- unsigned long iflags;
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
IOCB_t *rsp;
@@ -173,9 +172,10 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
int rc = 0;
spin_lock_irqsave(&phba->ct_ev_lock, flags);
- dd_data = cmdiocbq->context1;
+ dd_data = cmdiocbq->context2;
if (!dd_data) {
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+ lpfc_sli_release_iocbq(phba, cmdiocbq);
return;
}
@@ -183,17 +183,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
job = iocb->set_job;
job->dd_data = NULL; /* so timeout handler does not reply */
- spin_lock_irqsave(&phba->hbalock, iflags);
- 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, iflags);
-
bmp = iocb->bmp;
- rspiocbq = iocb->rspiocbq;
rsp = &rspiocbq->iocb;
- ndlp = iocb->ndlp;
+ ndlp = cmdiocbq->context1;
pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -220,7 +212,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
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);
lpfc_nlp_put(ndlp);
kfree(bmp);
@@ -247,9 +238,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
struct ulp_bde64 *bpl = NULL;
uint32_t timeout;
struct lpfc_iocbq *cmdiocbq = NULL;
- struct lpfc_iocbq *rspiocbq = NULL;
IOCB_t *cmd;
- IOCB_t *rsp;
struct lpfc_dmabuf *bmp = NULL;
int request_nseg;
int reply_nseg;
@@ -296,17 +285,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
}
cmd = &cmdiocbq->iocb;
- 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;
+ goto free_cmdiocbq;
}
INIT_LIST_HEAD(&bmp->list);
@@ -358,14 +340,12 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
cmd->ulpTimeout = timeout;
cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
- cmdiocbq->context1 = dd_data;
- cmdiocbq->context2 = rspiocbq;
+ cmdiocbq->context1 = ndlp;
+ cmdiocbq->context2 = dd_data;
dd_data->type = TYPE_IOCB;
dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
- dd_data->context_un.iocb.rspiocbq = rspiocbq;
dd_data->context_un.iocb.set_job = job;
dd_data->context_un.iocb.bmp = bmp;
- dd_data->context_un.iocb.ndlp = ndlp;
if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
creg_val = readl(phba->HCregaddr);
@@ -391,8 +371,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
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:
@@ -1220,7 +1198,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
int rc = 0;
spin_lock_irqsave(&phba->ct_ev_lock, flags);
- dd_data = cmdiocbq->context1;
+ dd_data = cmdiocbq->context2;
/* normal completion and timeout crossed paths, already done */
if (!dd_data) {
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
@@ -1369,8 +1347,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
ctiocb->context3 = bmp;
ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
- ctiocb->context1 = dd_data;
- ctiocb->context2 = NULL;
+ ctiocb->context2 = dd_data;
+ ctiocb->context1 = ndlp;
dd_data->type = TYPE_IOCB;
dd_data->context_un.iocb.cmdiocbq = ctiocb;
dd_data->context_un.iocb.rspiocbq = NULL;
@@ -1641,7 +1619,7 @@ job_error:
* This function obtains a remote port login id so the diag loopback test
* can send and receive its own unsolicited CT command.
**/
-static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
+static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi)
{
LPFC_MBOXQ_t *mbox;
struct lpfc_dmabuf *dmabuff;
@@ -1651,10 +1629,14 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
if (!mbox)
return -ENOMEM;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ *rpi = lpfc_sli4_alloc_rpi(phba);
status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID,
- (uint8_t *)&phba->pport->fc_sparam, mbox, 0);
+ (uint8_t *)&phba->pport->fc_sparam, mbox, *rpi);
if (status) {
mempool_free(mbox, phba->mbox_mem_pool);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_sli4_free_rpi(phba, *rpi);
return -ENOMEM;
}
@@ -1668,6 +1650,8 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
kfree(dmabuff);
if (status != MBX_TIMEOUT)
mempool_free(mbox, phba->mbox_mem_pool);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_sli4_free_rpi(phba, *rpi);
return -ENODEV;
}
@@ -1704,8 +1688,9 @@ static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi)
mempool_free(mbox, phba->mbox_mem_pool);
return -EIO;
}
-
mempool_free(mbox, phba->mbox_mem_pool);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_sli4_free_rpi(phba, rpi);
return 0;
}
@@ -2102,7 +2087,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
uint32_t size;
uint32_t full_size;
size_t segment_len = 0, segment_offset = 0, current_offset = 0;
- uint16_t rpi;
+ uint16_t rpi = 0;
struct lpfc_iocbq *cmdiocbq, *rspiocbq;
IOCB_t *cmd, *rsp;
struct lpfc_sli_ct_request *ctreq;
@@ -2162,7 +2147,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
goto loopback_test_exit;
}
- if (size >= BUF_SZ_4K) {
+ if (full_size >= BUF_SZ_4K) {
/*
* Allocate memory for ioctl data. If buffer is bigger than 64k,
* then we allocate 64k and re-use that buffer over and over to
@@ -2171,7 +2156,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
* problem with GET_FCPTARGETMAPPING...
*/
if (size <= (64 * 1024))
- total_mem = size;
+ total_mem = full_size;
else
total_mem = 64 * 1024;
} else
@@ -2189,7 +2174,6 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
sg_copy_to_buffer(job->request_payload.sg_list,
job->request_payload.sg_cnt,
ptr, size);
-
rc = lpfcdiag_loop_self_reg(phba, &rpi);
if (rc)
goto loopback_test_exit;
@@ -2601,12 +2585,11 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
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;
+ phba->fc_topology = LPFC_TOPOLOGY_PT_PT;
}
break;
case MBX_READ_SPARM64:
- case MBX_READ_LA:
- case MBX_READ_LA64:
+ case MBX_READ_TOPOLOGY:
case MBX_REG_LOGIN:
case MBX_REG_LOGIN64:
case MBX_CONFIG_PORT:
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index a5f5a093a8a4..17fde522c84a 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -31,7 +31,7 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
-int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
+int lpfc_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *);
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -40,7 +40,7 @@ int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_reg_rpi(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
- LPFC_MBOXQ_t *, uint32_t);
+ LPFC_MBOXQ_t *, uint16_t);
void lpfc_set_var(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
@@ -64,7 +64,7 @@ void lpfc_cleanup_pending_mbox(struct lpfc_vport *);
int lpfc_linkdown(struct lpfc_hba *);
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_mbx_cmpl_read_topology(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 *);
@@ -121,6 +121,7 @@ void lpfc_end_rscn(struct lpfc_vport *);
int lpfc_els_chk_latt(struct lpfc_vport *);
int lpfc_els_abort_flogi(struct lpfc_hba *);
int lpfc_initial_flogi(struct lpfc_vport *);
+void lpfc_issue_init_vfi(struct lpfc_vport *);
int lpfc_initial_fdisc(struct lpfc_vport *);
int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t);
int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
@@ -415,5 +416,13 @@ struct lpfc_iocbq *lpfc_sli_ringtx_get(struct lpfc_hba *,
int __lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
struct lpfc_iocbq *, uint32_t);
uint32_t lpfc_drain_txq(struct lpfc_hba *);
-
-
+void lpfc_clr_rrq_active(struct lpfc_hba *, uint16_t, struct lpfc_node_rrq *);
+int lpfc_test_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, uint16_t);
+void lpfc_handle_rrq_active(struct lpfc_hba *);
+int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *);
+int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *,
+ uint16_t, uint16_t, uint16_t);
+void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
+void lpfc_cleanup_vports_rrqs(struct lpfc_vport *);
+struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
+ uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 463b74902ac4..c004fa9a681e 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -48,14 +48,14 @@
#include "lpfc_vport.h"
#include "lpfc_debugfs.h"
-#define HBA_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver
- * incapable of reporting */
-#define HBA_PORTSPEED_1GBIT 1 /* 1 GBit/sec */
-#define HBA_PORTSPEED_2GBIT 2 /* 2 GBit/sec */
-#define HBA_PORTSPEED_4GBIT 8 /* 4 GBit/sec */
-#define HBA_PORTSPEED_8GBIT 16 /* 8 GBit/sec */
-#define HBA_PORTSPEED_10GBIT 4 /* 10 GBit/sec */
-#define HBA_PORTSPEED_NOT_NEGOTIATED 5 /* Speed not established */
+/* FDMI Port Speed definitions */
+#define HBA_PORTSPEED_1GBIT 0x0001 /* 1 GBit/sec */
+#define HBA_PORTSPEED_2GBIT 0x0002 /* 2 GBit/sec */
+#define HBA_PORTSPEED_4GBIT 0x0008 /* 4 GBit/sec */
+#define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */
+#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */
+#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */
+#define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */
#define FOURBYTES 4
@@ -1593,8 +1593,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
ae->un.SupportSpeed = 0;
+ if (phba->lmt & LMT_16Gb)
+ ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
if (phba->lmt & LMT_10Gb)
- ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
+ ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT;
if (phba->lmt & LMT_8Gb)
ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
if (phba->lmt & LMT_4Gb)
@@ -1612,24 +1614,26 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
switch(phba->fc_linkspeed) {
- case LA_1GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
+ case LPFC_LINK_SPEED_1GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
break;
- case LA_2GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
+ case LPFC_LINK_SPEED_2GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
break;
- case LA_4GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
+ case LPFC_LINK_SPEED_4GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
break;
- case LA_8GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
+ case LPFC_LINK_SPEED_8GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
break;
- case LA_10GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
+ case LPFC_LINK_SPEED_10GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
break;
- default:
- ae->un.PortSpeed =
- HBA_PORTSPEED_UNKNOWN;
+ case LPFC_LINK_SPEED_16GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
+ break;
+ default:
+ ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
break;
}
pab->ab.EntryCnt++;
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 7cae69de36f7..1d84b63fccad 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -68,6 +68,12 @@ struct lpfc_fast_path_event {
} un;
};
+#define LPFC_SLI4_MAX_XRI 1024 /* Used to make the ndlp's xri_bitmap */
+#define XRI_BITMAP_ULONGS (LPFC_SLI4_MAX_XRI / BITS_PER_LONG)
+struct lpfc_node_rrqs {
+ unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
+};
+
struct lpfc_nodelist {
struct list_head nlp_listp;
struct lpfc_name nlp_portname;
@@ -110,8 +116,19 @@ struct lpfc_nodelist {
atomic_t cmd_pending;
uint32_t cmd_qdepth;
unsigned long last_change_time;
+ struct lpfc_node_rrqs active_rrqs;
struct lpfc_scsicmd_bkt *lat_data; /* Latency data */
};
+struct lpfc_node_rrq {
+ struct list_head list;
+ uint16_t xritag;
+ uint16_t send_rrq;
+ uint16_t rxid;
+ uint32_t nlp_DID; /* FC D_ID of entry */
+ struct lpfc_vport *vport;
+ struct lpfc_nodelist *ndlp;
+ unsigned long rrq_stop_time;
+};
/* Defines for nlp_flag (uint32) */
#define NLP_IGNR_REG_CMPL 0x00000001 /* Rcvd rscn before we cmpl reg login */
@@ -136,7 +153,7 @@ struct lpfc_nodelist {
#define NLP_NODEV_REMOVE 0x08000000 /* Defer removal till discovery ends */
#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
#define NLP_SC_REQ 0x20000000 /* Target requires authentication */
-#define NLP_RPI_VALID 0x80000000 /* nlp_rpi is valid */
+#define NLP_RPI_REGISTERED 0x80000000 /* nlp_rpi is valid */
/* ndlp usage management macros */
#define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 884f4d321799..c62d567cc845 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -375,7 +375,8 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
err = 4;
goto fail;
}
- rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, 0);
+ rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
+ ndlp->nlp_rpi);
if (rc) {
err = 5;
goto fail_free_mbox;
@@ -523,7 +524,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
phba->fc_edtovResol = sp->cmn.edtovResolution;
phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_PUBLIC_LOOP;
spin_unlock_irq(shost->host_lock);
@@ -832,6 +833,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (lpfc_els_retry(phba, cmdiocb, rspiocb))
goto out;
+ /* FLOGI failure */
+ 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);
+
/* FLOGI failed, so there is no fabric */
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
@@ -843,13 +850,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
*/
if (phba->alpa_map[0] == 0) {
vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
+ if ((phba->sli_rev == LPFC_SLI_REV4) &&
+ (!(vport->fc_flag & FC_VFI_REGISTERED) ||
+ (vport->fc_prevDID != vport->fc_myDID))) {
+ if (vport->fc_flag & FC_VFI_REGISTERED)
+ lpfc_sli4_unreg_all_rpis(vport);
+ lpfc_issue_reg_vfi(vport);
+ lpfc_nlp_put(ndlp);
+ goto out;
+ }
}
-
- /* FLOGI failure */
- 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;
}
spin_lock_irq(shost->host_lock);
@@ -879,7 +889,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
*/
if (sp->cmn.fPort)
rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
- else if (!(phba->hba_flag & HBA_FCOE_SUPPORT))
+ else if (!(phba->hba_flag & HBA_FCOE_MODE))
rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
else {
lpfc_printf_vlog(vport, KERN_ERR,
@@ -1014,7 +1024,9 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (sp->cmn.fcphHigh < FC_PH3)
sp->cmn.fcphHigh = FC_PH3;
- if (phba->sli_rev == LPFC_SLI_REV4) {
+ if ((phba->sli_rev == LPFC_SLI_REV4) &&
+ (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_0)) {
elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
/* FLOGI needs to be 3 for WQE FCFI */
@@ -1027,7 +1039,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
icmd->ulpCt_l = 0;
}
- if (phba->fc_topology != TOPOLOGY_LOOP) {
+ if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
icmd->un.elsreq64.myID = 0;
icmd->un.elsreq64.fl = 1;
}
@@ -1281,6 +1293,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
uint32_t rc, keepDID = 0;
int put_node;
int put_rport;
+ struct lpfc_node_rrqs rrq;
/* Fabric nodes can have the same WWPN so we don't bother searching
* by WWPN. Just return the ndlp that was given to us.
@@ -1298,6 +1311,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
return ndlp;
+ memset(&rrq.xri_bitmap, 0, sizeof(new_ndlp->active_rrqs.xri_bitmap));
if (!new_ndlp) {
rc = memcmp(&ndlp->nlp_portname, name,
@@ -1318,12 +1332,25 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
if (!new_ndlp)
return ndlp;
keepDID = new_ndlp->nlp_DID;
- } else
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ memcpy(&rrq.xri_bitmap,
+ &new_ndlp->active_rrqs.xri_bitmap,
+ sizeof(new_ndlp->active_rrqs.xri_bitmap));
+ } else {
keepDID = new_ndlp->nlp_DID;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ memcpy(&rrq.xri_bitmap,
+ &new_ndlp->active_rrqs.xri_bitmap,
+ sizeof(new_ndlp->active_rrqs.xri_bitmap));
+ }
lpfc_unreg_rpi(vport, new_ndlp);
new_ndlp->nlp_DID = ndlp->nlp_DID;
new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ memcpy(new_ndlp->active_rrqs.xri_bitmap,
+ &ndlp->active_rrqs.xri_bitmap,
+ sizeof(ndlp->active_rrqs.xri_bitmap));
if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
@@ -1362,12 +1389,20 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
/* Two ndlps cannot have the same did on the nodelist */
ndlp->nlp_DID = keepDID;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ memcpy(&ndlp->active_rrqs.xri_bitmap,
+ &rrq.xri_bitmap,
+ sizeof(ndlp->active_rrqs.xri_bitmap));
lpfc_drop_node(vport, ndlp);
}
else {
lpfc_unreg_rpi(vport, ndlp);
/* Two ndlps cannot have the same did */
ndlp->nlp_DID = keepDID;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ memcpy(&ndlp->active_rrqs.xri_bitmap,
+ &rrq.xri_bitmap,
+ sizeof(ndlp->active_rrqs.xri_bitmap));
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
/* Since we are swapping the ndlp passed in with the new one
* and the did has already been swapped, copy over the
@@ -1428,6 +1463,73 @@ lpfc_end_rscn(struct lpfc_vport *vport)
}
/**
+ * lpfc_cmpl_els_rrq - Completion handled for els RRQs.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine will call the clear rrq function to free the rrq and
+ * clear the xri's bit in the ndlp's xri_bitmap. If the ndlp does not
+ * exist then the clear_rrq is still called because the rrq needs to
+ * be freed.
+ **/
+
+static void
+lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ struct lpfc_iocbq *rspiocb)
+{
+ struct lpfc_vport *vport = cmdiocb->vport;
+ IOCB_t *irsp;
+ struct lpfc_nodelist *ndlp;
+ struct lpfc_node_rrq *rrq;
+
+ /* we pass cmdiocb to state machine which needs rspiocb as well */
+ rrq = cmdiocb->context_un.rrq;
+ cmdiocb->context_un.rsp_iocb = rspiocb;
+
+ irsp = &rspiocb->iocb;
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+ "RRQ cmpl: status:x%x/x%x did:x%x",
+ irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->un.elsreq64.remoteID);
+
+ ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
+ if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || ndlp != rrq->ndlp) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2882 RRQ completes to NPort x%x "
+ "with no ndlp. Data: x%x x%x x%x\n",
+ irsp->un.elsreq64.remoteID,
+ irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpIoTag);
+ goto out;
+ }
+
+ /* rrq completes to NPort <nlp_DID> */
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "2880 RRQ completes to NPort x%x "
+ "Data: x%x x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout, rrq->xritag, rrq->rxid);
+
+ if (irsp->ulpStatus) {
+ /* Check for retry */
+ /* RRQ failed Don't print the vport to vport rjts */
+ if (irsp->ulpStatus != IOSTAT_LS_RJT ||
+ (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
+ ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
+ (phba)->pport->cfg_log_verbose & LOG_ELS)
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2881 RRQ failure DID:%06X Status:x%x/x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
+ }
+out:
+ if (rrq)
+ lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+ lpfc_els_free_iocb(phba, cmdiocb);
+ return;
+}
+/**
* lpfc_cmpl_els_plogi - Completion callback function for plogi
* @phba: pointer to lpfc hba data structure.
* @cmdiocb: pointer to lpfc command iocb data structure.
@@ -2722,7 +2824,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (cmd == ELS_CMD_FLOGI) {
if (PCI_DEVICE_ID_HORNET ==
phba->pcidev->device) {
- phba->fc_topology = TOPOLOGY_LOOP;
+ phba->fc_topology = LPFC_TOPOLOGY_LOOP;
phba->pport->fc_myDID = 0;
phba->alpa_map[0] = 0;
phba->alpa_map[1] = 0;
@@ -2877,7 +2979,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
retry = 1;
if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
- (phba->fc_topology != TOPOLOGY_LOOP) &&
+ (phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
!lpfc_error_lost_link(irsp)) {
/* FLOGI retry policy */
retry = 1;
@@ -3219,14 +3321,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
- /*
- * This routine is used to register and unregister in previous SLI
- * modes.
- */
- if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) &&
- (phba->sli_rev == LPFC_SLI_REV4))
- lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi);
-
pmb->context1 = NULL;
pmb->context2 = NULL;
@@ -3904,6 +3998,47 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
}
/**
+ * lpfc_els_clear_rrq - Clear the rq that this rrq describes.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @iocb: pointer to the lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * Return
+ **/
+static void
+lpfc_els_clear_rrq(struct lpfc_vport *vport,
+ struct lpfc_iocbq *iocb, struct lpfc_nodelist *ndlp)
+{
+ struct lpfc_hba *phba = vport->phba;
+ uint8_t *pcmd;
+ struct RRQ *rrq;
+ uint16_t rxid;
+ struct lpfc_node_rrq *prrq;
+
+
+ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt);
+ pcmd += sizeof(uint32_t);
+ rrq = (struct RRQ *)pcmd;
+ rxid = bf_get(rrq_oxid, rrq);
+
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
+ " x%x x%x\n",
+ bf_get(rrq_did, rrq),
+ bf_get(rrq_oxid, rrq),
+ rxid,
+ iocb->iotag, iocb->iocb.ulpContext);
+
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
+ "Clear RRQ: did:x%x flg:x%x exchg:x%.08x",
+ ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
+ prrq = lpfc_get_active_rrq(vport, rxid, ndlp->nlp_DID);
+ if (prrq)
+ lpfc_clr_rrq_active(phba, rxid, prrq);
+ return;
+}
+
+/**
* lpfc_els_rsp_echo_acc - Issue echo acc response
* @vport: pointer to a virtual N_Port data structure.
* @data: pointer to echo data to return in the accept.
@@ -4597,7 +4732,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
lpfc_set_disctmo(vport);
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
/* We should never receive a FLOGI in loop mode, ignore it */
did = icmd->un.elsreq64.remoteID;
@@ -4792,6 +4927,8 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
{
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+ if (vport->phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_els_clear_rrq(vport, cmdiocb, ndlp);
}
/**
@@ -4940,7 +5077,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
pcmd += sizeof(uint32_t); /* Skip past command */
rps_rsp = (RPS_RSP *)pcmd;
- if (phba->fc_topology != TOPOLOGY_LOOP)
+ if (phba->fc_topology != LPFC_TOPOLOGY_LOOP)
status = 0x10;
else
status = 0x8;
@@ -5194,6 +5331,97 @@ reject_out:
return 0;
}
+/* lpfc_issue_els_rrq - Process an unsolicited rps iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @did: DID of the target.
+ * @rrq: Pointer to the rrq struct.
+ *
+ * Build a ELS RRQ command and send it to the target. If the issue_iocb is
+ * Successful the the completion handler will clear the RRQ.
+ *
+ * Return codes
+ * 0 - Successfully sent rrq els iocb.
+ * 1 - Failed to send rrq els iocb.
+ **/
+static int
+lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ uint32_t did, struct lpfc_node_rrq *rrq)
+{
+ struct lpfc_hba *phba = vport->phba;
+ struct RRQ *els_rrq;
+ IOCB_t *icmd;
+ struct lpfc_iocbq *elsiocb;
+ uint8_t *pcmd;
+ uint16_t cmdsize;
+ int ret;
+
+
+ if (ndlp != rrq->ndlp)
+ ndlp = rrq->ndlp;
+ if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+ return 1;
+
+ /* If ndlp is not NULL, we will bump the reference count on it */
+ cmdsize = (sizeof(uint32_t) + sizeof(struct RRQ));
+ elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, did,
+ ELS_CMD_RRQ);
+ if (!elsiocb)
+ return 1;
+
+ icmd = &elsiocb->iocb;
+ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+
+ /* For RRQ request, remainder of payload is Exchange IDs */
+ *((uint32_t *) (pcmd)) = ELS_CMD_RRQ;
+ pcmd += sizeof(uint32_t);
+ els_rrq = (struct RRQ *) pcmd;
+
+ bf_set(rrq_oxid, els_rrq, rrq->xritag);
+ bf_set(rrq_rxid, els_rrq, rrq->rxid);
+ bf_set(rrq_did, els_rrq, vport->fc_myDID);
+ els_rrq->rrq = cpu_to_be32(els_rrq->rrq);
+ els_rrq->rrq_exchg = cpu_to_be32(els_rrq->rrq_exchg);
+
+
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+ "Issue RRQ: did:x%x",
+ did, rrq->xritag, rrq->rxid);
+ elsiocb->context_un.rrq = rrq;
+ elsiocb->iocb_cmpl = lpfc_cmpl_els_rrq;
+ ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
+
+ if (ret == IOCB_ERROR) {
+ lpfc_els_free_iocb(phba, elsiocb);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * lpfc_send_rrq - Sends ELS RRQ if needed.
+ * @phba: pointer to lpfc hba data structure.
+ * @rrq: pointer to the active rrq.
+ *
+ * This routine will call the lpfc_issue_els_rrq if the rrq is
+ * still active for the xri. If this function returns a failure then
+ * the caller needs to clean up the RRQ by calling lpfc_clr_active_rrq.
+ *
+ * Returns 0 Success.
+ * 1 Failure.
+ **/
+int
+lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
+{
+ struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
+ rrq->nlp_DID);
+ if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
+ return lpfc_issue_els_rrq(rrq->vport, ndlp,
+ rrq->nlp_DID, rrq);
+ else
+ return 1;
+}
+
/**
* lpfc_els_rsp_rpl_acc - Issue an accept rpl els command
* @vport: pointer to a host virtual N_Port data structure.
@@ -5482,7 +5710,7 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
(memcmp(&phba->fc_fabparam.portName, &fp->FportName,
sizeof(struct lpfc_name)))) {
/* This port has switched fabrics. FLOGI is required */
- lpfc_initial_flogi(vport);
+ lpfc_issue_init_vfi(vport);
} else {
/* FAN verified - skip FLOGI */
vport->fc_myDID = vport->fc_prevDID;
@@ -6201,7 +6429,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
cmd, did, vport->port_state);
/* Unsupported ELS command, reject */
- rjt_err = LSRJT_INVALID_CMD;
+ rjt_err = LSRJT_CMD_UNSUPPORTED;
/* Unknown ELS command <elsCmd> received from NPORT <did> */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -6373,7 +6601,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
if (!ndlp) {
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
if (!ndlp) {
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_disc_start(vport);
return;
}
@@ -6386,7 +6614,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
if (!ndlp) {
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_disc_start(vport);
return;
}
@@ -6408,18 +6636,31 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
}
if (vport->cfg_fdmi_on) {
- ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
- GFP_KERNEL);
+ /* If this is the first time, allocate an ndlp and initialize
+ * it. Otherwise, make sure the node is enabled and then do the
+ * login.
+ */
+ ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID);
+ if (!ndlp_fdmi) {
+ ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
+ GFP_KERNEL);
+ if (ndlp_fdmi) {
+ lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
+ ndlp_fdmi->nlp_type |= NLP_FABRIC;
+ } else
+ return;
+ }
+ if (!NLP_CHK_NODE_ACT(ndlp_fdmi))
+ ndlp_fdmi = lpfc_enable_node(vport,
+ ndlp_fdmi,
+ NLP_STE_NPR_NODE);
+
if (ndlp_fdmi) {
- lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
- ndlp_fdmi->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(vport, ndlp_fdmi,
- NLP_STE_PLOGI_ISSUE);
- lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
- 0);
+ NLP_STE_PLOGI_ISSUE);
+ lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0);
}
}
- return;
}
/**
@@ -6497,7 +6738,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
spin_unlock_irq(shost->host_lock);
if (vport->port_type == LPFC_PHYSICAL_PORT
&& !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
- lpfc_initial_flogi(vport);
+ lpfc_issue_init_vfi(vport);
else
lpfc_initial_fdisc(vport);
break;
@@ -6734,7 +6975,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
vport->fc_flag |= FC_FABRIC;
- if (vport->phba->fc_topology == TOPOLOGY_LOOP)
+ if (vport->phba->fc_topology == LPFC_TOPOLOGY_LOOP)
vport->fc_flag |= FC_PUBLIC_LOOP;
spin_unlock_irq(shost->host_lock);
@@ -6844,7 +7085,9 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
icmd->un.elsreq64.myID = 0;
icmd->un.elsreq64.fl = 1;
- if (phba->sli_rev == LPFC_SLI_REV4) {
+ if ((phba->sli_rev == LPFC_SLI_REV4) &&
+ (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_0)) {
/* FDISC needs to be 1 for WQE VPI */
elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1;
elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
@@ -7351,8 +7594,11 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
struct sli4_wcqe_xri_aborted *axri)
{
uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
+ uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
+
struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
unsigned long iflag = 0;
+ struct lpfc_nodelist *ndlp;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
spin_lock_irqsave(&phba->hbalock, iflag);
@@ -7361,11 +7607,14 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
&phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
if (sglq_entry->sli4_xritag == xri) {
list_del(&sglq_entry->list);
+ ndlp = sglq_entry->ndlp;
+ sglq_entry->ndlp = NULL;
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);
+ lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
/* Check if TXQ queue needs to be serviced */
if (pring->txq_cnt)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index a5d1695dac3d..f9f160ab2ee9 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -607,6 +607,8 @@ lpfc_work_done(struct lpfc_hba *phba)
/* Process SLI4 events */
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
+ if (phba->hba_flag & HBA_RRQ_ACTIVE)
+ lpfc_handle_rrq_active(phba);
if (phba->hba_flag & FCP_XRI_ABORT_EVENT)
lpfc_sli4_fcp_xri_abort_event_proc(phba);
if (phba->hba_flag & ELS_XRI_ABORT_EVENT)
@@ -966,6 +968,7 @@ lpfc_linkup(struct lpfc_hba *phba)
struct lpfc_vport **vports;
int i;
+ lpfc_cleanup_wt_rrqs(phba);
phba->link_state = LPFC_LINK_UP;
/* Unblock fabric iocbs if they are blocked */
@@ -1064,7 +1067,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mempool_free(pmb, phba->mbox_mem_pool);
- if (phba->fc_topology == TOPOLOGY_LOOP &&
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
vport->fc_flag & FC_PUBLIC_LOOP &&
!(vport->fc_flag & FC_LBIT)) {
/* Need to wait for FAN - use discovery timer
@@ -1078,9 +1081,8 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
/* Start discovery by sending a FLOGI. port_state is identically
* LPFC_FLOGI while waiting for FLOGI cmpl
*/
- if (vport->port_state != LPFC_FLOGI) {
+ if (vport->port_state != LPFC_FLOGI)
lpfc_initial_flogi(vport);
- }
return;
out:
@@ -1131,7 +1133,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
if (vport->port_state != LPFC_FLOGI) {
phba->hba_flag |= FCF_RR_INPROG;
spin_unlock_irq(&phba->hbalock);
- lpfc_initial_flogi(vport);
+ lpfc_issue_init_vfi(vport);
goto out;
}
spin_unlock_irq(&phba->hbalock);
@@ -1353,7 +1355,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
if (phba->pport->port_state != LPFC_FLOGI) {
phba->hba_flag |= FCF_RR_INPROG;
spin_unlock_irq(&phba->hbalock);
- lpfc_initial_flogi(phba->pport);
+ lpfc_issue_init_vfi(phba->pport);
return;
}
spin_unlock_irq(&phba->hbalock);
@@ -2331,7 +2333,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
phba->fcf.current_rec.fcf_indx, fcf_index);
/* Wait 500 ms before retrying FLOGI to current FCF */
msleep(500);
- lpfc_initial_flogi(phba->pport);
+ lpfc_issue_init_vfi(phba->pport);
goto out;
}
@@ -2422,6 +2424,63 @@ out:
}
/**
+ * lpfc_init_vfi_cmpl - Completion handler for init_vfi mbox command.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox data structure.
+ *
+ * This function handles completion of init vfi mailbox command.
+ */
+void
+lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ struct lpfc_vport *vport = mboxq->vport;
+
+ if (mboxq->u.mb.mbxStatus && (mboxq->u.mb.mbxStatus != 0x4002)) {
+ lpfc_printf_vlog(vport, KERN_ERR,
+ LOG_MBOX,
+ "2891 Init VFI mailbox failed 0x%x\n",
+ mboxq->u.mb.mbxStatus);
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ lpfc_vport_set_state(vport, FC_VPORT_FAILED);
+ return;
+ }
+ lpfc_initial_flogi(vport);
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ return;
+}
+
+/**
+ * lpfc_issue_init_vfi - Issue init_vfi mailbox command.
+ * @vport: pointer to lpfc_vport data structure.
+ *
+ * This function issue a init_vfi mailbox command to initialize the VFI and
+ * VPI for the physical port.
+ */
+void
+lpfc_issue_init_vfi(struct lpfc_vport *vport)
+{
+ LPFC_MBOXQ_t *mboxq;
+ int rc;
+ struct lpfc_hba *phba = vport->phba;
+
+ mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mboxq) {
+ lpfc_printf_vlog(vport, KERN_ERR,
+ LOG_MBOX, "2892 Failed to allocate "
+ "init_vfi mailbox\n");
+ return;
+ }
+ lpfc_init_vfi(mboxq, vport);
+ mboxq->mbox_cmpl = lpfc_init_vfi_cmpl;
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ lpfc_printf_vlog(vport, KERN_ERR,
+ LOG_MBOX, "2893 Failed to issue init_vfi mailbox\n");
+ mempool_free(mboxq, vport->phba->mbox_mem_pool);
+ }
+}
+
+/**
* lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
* @phba: pointer to lpfc hba data structure.
* @mboxq: pointer to mailbox data structure.
@@ -2528,7 +2587,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
FC_VPORT_FAILED);
continue;
}
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_vport_set_state(vports[i],
FC_VPORT_LINKDOWN);
continue;
@@ -2564,7 +2623,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
"2018 REG_VFI mbxStatus error x%x "
"HBA state x%x\n",
mboxq->u.mb.mbxStatus, vport->port_state);
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
/* FLOGI failed, use loop map to make discovery list */
lpfc_disc_list_loopmap(vport);
/* Start discovery */
@@ -2582,8 +2641,18 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
spin_unlock_irq(shost->host_lock);
if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
- lpfc_start_fdiscs(phba);
- lpfc_do_scr_ns_plogi(phba, vport);
+ /* For private loop just start discovery and we are done. */
+ if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
+ (phba->alpa_map[0] == 0) &&
+ !(vport->fc_flag & FC_PUBLIC_LOOP)) {
+ /* Use loop map to make discovery list */
+ lpfc_disc_list_loopmap(vport);
+ /* Start discovery */
+ lpfc_disc_start(vport);
+ } else {
+ lpfc_start_fdiscs(phba);
+ lpfc_do_scr_ns_plogi(phba, vport);
+ }
}
fail_free_mem:
@@ -2644,7 +2713,7 @@ out:
}
static void
-lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
+lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
{
struct lpfc_vport *vport = phba->pport;
LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL;
@@ -2654,31 +2723,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
struct fcf_record *fcf_record;
spin_lock_irq(&phba->hbalock);
- switch (la->UlnkSpeed) {
- case LA_1GHZ_LINK:
- phba->fc_linkspeed = LA_1GHZ_LINK;
- break;
- case LA_2GHZ_LINK:
- phba->fc_linkspeed = LA_2GHZ_LINK;
- break;
- case LA_4GHZ_LINK:
- phba->fc_linkspeed = LA_4GHZ_LINK;
- break;
- case LA_8GHZ_LINK:
- phba->fc_linkspeed = LA_8GHZ_LINK;
- break;
- case LA_10GHZ_LINK:
- phba->fc_linkspeed = LA_10GHZ_LINK;
+ switch (bf_get(lpfc_mbx_read_top_link_spd, la)) {
+ case LPFC_LINK_SPEED_1GHZ:
+ case LPFC_LINK_SPEED_2GHZ:
+ case LPFC_LINK_SPEED_4GHZ:
+ case LPFC_LINK_SPEED_8GHZ:
+ case LPFC_LINK_SPEED_10GHZ:
+ case LPFC_LINK_SPEED_16GHZ:
+ phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la);
break;
default:
- phba->fc_linkspeed = LA_UNKNW_LINK;
+ phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN;
break;
}
- phba->fc_topology = la->topology;
+ phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la);
phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
/* if npiv is enabled and this adapter supports npiv log
@@ -2689,11 +2751,11 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
"1309 Link Up Event npiv not supported in loop "
"topology\n");
/* Get Loop Map information */
- if (la->il)
+ if (bf_get(lpfc_mbx_read_top_il, la))
vport->fc_flag |= FC_LBIT;
- vport->fc_myDID = la->granted_AL_PA;
- i = la->un.lilpBde64.tus.f.bdeSize;
+ vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la);
+ i = la->lilpBde64.tus.f.bdeSize;
if (i == 0) {
phba->alpa_map[0] = 0;
@@ -2764,7 +2826,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
goto out;
}
- if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
+ if (!(phba->hba_flag & HBA_FCOE_MODE)) {
cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!cfglink_mbox)
goto out;
@@ -2874,17 +2936,17 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
/*
- * This routine handles processing a READ_LA mailbox
+ * This routine handles processing a READ_TOPOLOGY mailbox
* command upon completion. It is setup in the LPFC_MBOXQ
* as the completion routine when the command is
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
struct lpfc_vport *vport = pmb->vport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- READ_LA_VAR *la;
+ struct lpfc_mbx_read_top *la;
MAILBOX_t *mb = &pmb->u.mb;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
@@ -2897,15 +2959,15 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mb->mbxStatus, vport->port_state);
lpfc_mbx_issue_link_down(phba);
phba->link_state = LPFC_HBA_ERROR;
- goto lpfc_mbx_cmpl_read_la_free_mbuf;
+ goto lpfc_mbx_cmpl_read_topology_free_mbuf;
}
- la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA;
+ la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
memcpy(&phba->alpa_map[0], mp->virt, 128);
spin_lock_irq(shost->host_lock);
- if (la->pb)
+ if (bf_get(lpfc_mbx_read_top_pb, la))
vport->fc_flag |= FC_BYPASSED_MODE;
else
vport->fc_flag &= ~FC_BYPASSED_MODE;
@@ -2914,41 +2976,48 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if ((phba->fc_eventTag < la->eventTag) ||
(phba->fc_eventTag == la->eventTag)) {
phba->fc_stat.LinkMultiEvent++;
- if (la->attType == AT_LINK_UP)
+ if (bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP)
if (phba->fc_eventTag != 0)
lpfc_linkdown(phba);
}
phba->fc_eventTag = la->eventTag;
spin_lock_irq(&phba->hbalock);
- if (la->mm)
+ if (bf_get(lpfc_mbx_read_top_mm, la))
phba->sli.sli_flag |= LPFC_MENLO_MAINT;
else
phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
spin_unlock_irq(&phba->hbalock);
phba->link_events++;
- if (la->attType == AT_LINK_UP && (!la->mm)) {
+ if ((bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP) &&
+ (!bf_get(lpfc_mbx_read_top_mm, la))) {
phba->fc_stat.LinkUp++;
if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1306 Link Up Event in loop back mode "
"x%x received Data: x%x x%x x%x x%x\n",
la->eventTag, phba->fc_eventTag,
- la->granted_AL_PA, la->UlnkSpeed,
+ bf_get(lpfc_mbx_read_top_alpa_granted,
+ la),
+ bf_get(lpfc_mbx_read_top_link_spd, la),
phba->alpa_map[0]);
} else {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1303 Link Up Event x%x received "
"Data: x%x x%x x%x x%x x%x x%x %d\n",
la->eventTag, phba->fc_eventTag,
- la->granted_AL_PA, la->UlnkSpeed,
+ bf_get(lpfc_mbx_read_top_alpa_granted,
+ la),
+ bf_get(lpfc_mbx_read_top_link_spd, la),
phba->alpa_map[0],
- la->mm, la->fa,
+ bf_get(lpfc_mbx_read_top_mm, la),
+ bf_get(lpfc_mbx_read_top_fa, la),
phba->wait_4_mlo_maint_flg);
}
lpfc_mbx_process_link_up(phba, la);
- } else if (la->attType == AT_LINK_DOWN) {
+ } else if (bf_get(lpfc_mbx_read_top_att_type, la) ==
+ LPFC_ATT_LINK_DOWN) {
phba->fc_stat.LinkDown++;
if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -2964,11 +3033,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
"Data: x%x x%x x%x x%x x%x\n",
la->eventTag, phba->fc_eventTag,
phba->pport->port_state, vport->fc_flag,
- la->mm, la->fa);
+ bf_get(lpfc_mbx_read_top_mm, la),
+ bf_get(lpfc_mbx_read_top_fa, la));
}
lpfc_mbx_issue_link_down(phba);
}
- if (la->mm && la->attType == AT_LINK_UP) {
+ if ((bf_get(lpfc_mbx_read_top_mm, la)) &&
+ (bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP)) {
if (phba->link_state != LPFC_LINK_DOWN) {
phba->fc_stat.LinkDown++;
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -2996,14 +3067,15 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
}
- if (la->fa) {
- if (la->mm)
+ if (bf_get(lpfc_mbx_read_top_fa, la)) {
+ if (bf_get(lpfc_mbx_read_top_mm, la))
lpfc_issue_clear_la(phba, vport);
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
- "1311 fa %d\n", la->fa);
+ "1311 fa %d\n",
+ bf_get(lpfc_mbx_read_top_fa, la));
}
-lpfc_mbx_cmpl_read_la_free_mbuf:
+lpfc_mbx_cmpl_read_topology_free_mbuf:
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
@@ -3030,8 +3102,8 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
- if (ndlp->nlp_flag & NLP_IGNR_REG_CMPL ||
- ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
+ if (ndlp->nlp_flag & NLP_IGNR_REG_CMPL ||
+ ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
/* We rcvd a rscn after issuing this
* mbox reg login, we may have cycled
* back through the state and be
@@ -3043,10 +3115,6 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
spin_unlock_irq(shost->host_lock);
- if (phba->sli_rev == LPFC_SLI_REV4)
- lpfc_sli4_free_rpi(phba,
- pmb->u.mb.un.varRegLogin.rpi);
-
} else
/* Good status, call state machine */
lpfc_disc_state_machine(vport, ndlp, pmb,
@@ -3092,6 +3160,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
spin_unlock_irq(shost->host_lock);
vport->unreg_vpi_cmpl = VPORT_OK;
mempool_free(pmb, phba->mbox_mem_pool);
+ lpfc_cleanup_vports_rrqs(vport);
/*
* This shost reference might have been taken at the beginning of
* lpfc_vport_delete()
@@ -3333,7 +3402,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
/* FLOGI failed, use loop map to make discovery list */
lpfc_disc_list_loopmap(vport);
@@ -3355,7 +3424,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
ndlp->nlp_rpi = mb->un.varWords[0];
- ndlp->nlp_flag |= NLP_RPI_VALID;
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
ndlp->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -3413,7 +3482,7 @@ out:
/* If no other thread is using the ndlp, free it */
lpfc_nlp_not_used(ndlp);
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
/*
* RegLogin failed, use loop map to make discovery
* list
@@ -3429,7 +3498,7 @@ out:
}
ndlp->nlp_rpi = mb->un.varWords[0];
- ndlp->nlp_flag |= NLP_RPI_VALID;
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
ndlp->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -3762,6 +3831,8 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
NLP_INT_NODE_ACT(ndlp);
atomic_set(&ndlp->cmd_pending, 0);
ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
+ if (vport->phba->sli_rev == LPFC_SLI_REV4)
+ ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
}
struct lpfc_nodelist *
@@ -3975,7 +4046,7 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
* by firmware with a no rpi error.
*/
psli = &phba->sli;
- if (ndlp->nlp_flag & NLP_RPI_VALID) {
+ if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
/* Now process each ring */
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
@@ -4023,7 +4094,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
LPFC_MBOXQ_t *mbox;
int rc;
- if (ndlp->nlp_flag & NLP_RPI_VALID) {
+ if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mbox) {
lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
@@ -4035,8 +4106,9 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
}
lpfc_no_rpi(phba, ndlp);
- ndlp->nlp_rpi = 0;
- ndlp->nlp_flag &= ~NLP_RPI_VALID;
+ if (phba->sli_rev != LPFC_SLI_REV4)
+ ndlp->nlp_rpi = 0;
+ ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
return 1;
}
@@ -4059,11 +4131,16 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
int i;
vports = lpfc_create_vport_work_array(phba);
+ if (!vports) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+ "2884 Vport array allocation failed \n");
+ return;
+ }
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
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_REGISTERED) {
/* The mempool_alloc might sleep */
spin_unlock_irq(shost->host_lock);
lpfc_unreg_rpi(vports[i], ndlp);
@@ -4192,9 +4269,6 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
kfree(mp);
}
list_del(&mb->list);
- if (phba->sli_rev == LPFC_SLI_REV4)
- lpfc_sli4_free_rpi(phba,
- mb->u.mb.un.varRegLogin.rpi);
mempool_free(mb, phba->mbox_mem_pool);
/* We shall not invoke the lpfc_nlp_put to decrement
* the ndlp reference count as we are in the process
@@ -4236,15 +4310,15 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
lpfc_cancel_retry_delay_tmo(vport, ndlp);
if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
- !(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
- !(ndlp->nlp_flag & NLP_RPI_VALID)) {
+ !(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
+ !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
/* For this case we need to cleanup the default rpi
* allocated by the firmware.
*/
if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
!= NULL) {
rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID,
- (uint8_t *) &vport->fc_sparam, mbox, 0);
+ (uint8_t *) &vport->fc_sparam, mbox, ndlp->nlp_rpi);
if (rc) {
mempool_free(mbox, phba->mbox_mem_pool);
}
@@ -4436,7 +4510,7 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport)
if (!lpfc_is_link_up(phba))
return;
- if (phba->fc_topology != TOPOLOGY_LOOP)
+ if (phba->fc_topology != LPFC_TOPOLOGY_LOOP)
return;
/* Check for loop map present or not */
@@ -4788,7 +4862,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
}
}
if (vport->port_state != LPFC_FLOGI) {
- lpfc_initial_flogi(vport);
+ if (phba->sli_rev <= LPFC_SLI_REV3)
+ lpfc_initial_flogi(vport);
+ else
+ lpfc_issue_init_vfi(vport);
return;
}
break;
@@ -4979,7 +5056,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
pmb->context2 = NULL;
ndlp->nlp_rpi = mb->un.varWords[0];
- ndlp->nlp_flag |= NLP_RPI_VALID;
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
ndlp->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -5103,6 +5180,8 @@ lpfc_nlp_release(struct kref *kref)
spin_lock_irqsave(&phba->ndlp_lock, flags);
NLP_CLR_NODE_ACT(ndlp);
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
/* free ndlp memory for final ndlp release */
if (NLP_CHK_FREE_REQ(ndlp)) {
@@ -5254,6 +5333,10 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
vports = lpfc_create_vport_work_array(phba);
+ /* If driver cannot allocate memory, indicate fcf is in use */
+ if (!vports)
+ return 1;
+
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
shost = lpfc_shost_from_vport(vports[i]);
spin_lock_irq(shost->host_lock);
@@ -5269,7 +5352,7 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
"logged in\n",
ndlp->nlp_rpi, ndlp->nlp_DID,
ndlp->nlp_flag);
- if (ndlp->nlp_flag & NLP_RPI_VALID)
+ if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
ret = 1;
}
}
@@ -5550,7 +5633,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
* registered, do nothing.
*/
spin_lock_irq(&phba->hbalock);
- if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
+ if (!(phba->hba_flag & HBA_FCOE_MODE) ||
!(phba->fcf.fcf_flag & FCF_REGISTERED) ||
!(phba->hba_flag & HBA_FIP_SUPPORT) ||
(phba->fcf.fcf_flag & FCF_DISCOVERY) ||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 9b8333456465..96ed3ba6ba95 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -880,6 +880,24 @@ struct RLS_RSP { /* Structure is in Big Endian format */
uint32_t crcCnt;
};
+struct RRQ { /* Structure is in Big Endian format */
+ uint32_t rrq;
+#define rrq_rsvd_SHIFT 24
+#define rrq_rsvd_MASK 0x000000ff
+#define rrq_rsvd_WORD rrq
+#define rrq_did_SHIFT 0
+#define rrq_did_MASK 0x00ffffff
+#define rrq_did_WORD rrq
+ uint32_t rrq_exchg;
+#define rrq_oxid_SHIFT 16
+#define rrq_oxid_MASK 0xffff
+#define rrq_oxid_WORD rrq_exchg
+#define rrq_rxid_SHIFT 0
+#define rrq_rxid_MASK 0xffff
+#define rrq_rxid_WORD rrq_exchg
+};
+
+
struct RTV_RSP { /* Structure is in Big Endian format */
uint32_t ratov;
uint32_t edtov;
@@ -1172,7 +1190,10 @@ typedef struct {
#define PCI_VENDOR_ID_EMULEX 0x10df
#define PCI_DEVICE_ID_FIREFLY 0x1ae5
#define PCI_DEVICE_ID_PROTEUS_VF 0xe100
+#define PCI_DEVICE_ID_BALIUS 0xe131
#define PCI_DEVICE_ID_PROTEUS_PF 0xe180
+#define PCI_DEVICE_ID_LANCER_FC 0xe200
+#define PCI_DEVICE_ID_LANCER_FCOE 0xe260
#define PCI_DEVICE_ID_SAT_SMB 0xf011
#define PCI_DEVICE_ID_SAT_MID 0xf015
#define PCI_DEVICE_ID_RFLY 0xf095
@@ -1189,6 +1210,7 @@ typedef struct {
#define PCI_DEVICE_ID_SAT 0xf100
#define PCI_DEVICE_ID_SAT_SCSP 0xf111
#define PCI_DEVICE_ID_SAT_DCSP 0xf112
+#define PCI_DEVICE_ID_FALCON 0xf180
#define PCI_DEVICE_ID_SUPERFLY 0xf700
#define PCI_DEVICE_ID_DRAGONFLY 0xf800
#define PCI_DEVICE_ID_CENTAUR 0xf900
@@ -1210,8 +1232,6 @@ typedef struct {
#define PCI_VENDOR_ID_SERVERENGINE 0x19a2
#define PCI_DEVICE_ID_TIGERSHARK 0x0704
#define PCI_DEVICE_ID_TOMCAT 0x0714
-#define PCI_DEVICE_ID_FALCON 0xf180
-#define PCI_DEVICE_ID_BALIUS 0xe131
#define JEDEC_ID_ADDRESS 0x0080001c
#define FIREFLY_JEDEC_ID 0x1ACC
@@ -1368,7 +1388,6 @@ typedef struct { /* FireFly BIU registers */
#define MBX_READ_LNK_STAT 0x12
#define MBX_REG_LOGIN 0x13
#define MBX_UNREG_LOGIN 0x14
-#define MBX_READ_LA 0x15
#define MBX_CLEAR_LA 0x16
#define MBX_DUMP_MEMORY 0x17
#define MBX_DUMP_CONTEXT 0x18
@@ -1402,7 +1421,7 @@ typedef struct { /* FireFly BIU registers */
#define MBX_READ_SPARM64 0x8D
#define MBX_READ_RPI64 0x8F
#define MBX_REG_LOGIN64 0x93
-#define MBX_READ_LA64 0x95
+#define MBX_READ_TOPOLOGY 0x95
#define MBX_REG_VPI 0x96
#define MBX_UNREG_VPI 0x97
@@ -1823,12 +1842,13 @@ typedef struct {
#define FLAGS_IMED_ABORT 0x04000 /* Bit 14 */
uint32_t link_speed;
-#define LINK_SPEED_AUTO 0 /* Auto selection */
-#define LINK_SPEED_1G 1 /* 1 Gigabaud */
-#define LINK_SPEED_2G 2 /* 2 Gigabaud */
-#define LINK_SPEED_4G 4 /* 4 Gigabaud */
-#define LINK_SPEED_8G 8 /* 8 Gigabaud */
-#define LINK_SPEED_10G 16 /* 10 Gigabaud */
+#define LINK_SPEED_AUTO 0x0 /* Auto selection */
+#define LINK_SPEED_1G 0x1 /* 1 Gigabaud */
+#define LINK_SPEED_2G 0x2 /* 2 Gigabaud */
+#define LINK_SPEED_4G 0x4 /* 4 Gigabaud */
+#define LINK_SPEED_8G 0x8 /* 8 Gigabaud */
+#define LINK_SPEED_10G 0x10 /* 10 Gigabaud */
+#define LINK_SPEED_16G 0x11 /* 16 Gigabaud */
} INIT_LINK_VAR;
@@ -1999,6 +2019,7 @@ typedef struct {
#define LMT_4Gb 0x040
#define LMT_8Gb 0x080
#define LMT_10Gb 0x100
+#define LMT_16Gb 0x200
uint32_t rsvd2;
uint32_t rsvd3;
uint32_t max_xri;
@@ -2394,100 +2415,93 @@ typedef struct {
#endif
} UNREG_D_ID_VAR;
-/* Structure for MB Command READ_LA (21) */
-/* Structure for MB Command READ_LA64 (0x95) */
-
-typedef struct {
+/* Structure for MB Command READ_TOPOLOGY (0x95) */
+struct lpfc_mbx_read_top {
uint32_t eventTag; /* Event tag */
-#ifdef __BIG_ENDIAN_BITFIELD
- uint32_t rsvd1:19;
- uint32_t fa:1;
- uint32_t mm:1; /* Menlo Maintenance mode enabled */
- uint32_t rx:1;
- uint32_t pb:1;
- uint32_t il:1;
- uint32_t attType:8;
-#else /* __LITTLE_ENDIAN_BITFIELD */
- uint32_t attType:8;
- uint32_t il:1;
- uint32_t pb:1;
- uint32_t rx:1;
- uint32_t mm:1;
- uint32_t fa:1;
- uint32_t rsvd1:19;
-#endif
-
-#define AT_RESERVED 0x00 /* Reserved - attType */
-#define AT_LINK_UP 0x01 /* Link is up */
-#define AT_LINK_DOWN 0x02 /* Link is down */
-
-#ifdef __BIG_ENDIAN_BITFIELD
- uint8_t granted_AL_PA;
- uint8_t lipAlPs;
- uint8_t lipType;
- uint8_t topology;
-#else /* __LITTLE_ENDIAN_BITFIELD */
- uint8_t topology;
- uint8_t lipType;
- uint8_t lipAlPs;
- uint8_t granted_AL_PA;
-#endif
-
-#define TOPOLOGY_PT_PT 0x01 /* Topology is pt-pt / pt-fabric */
-#define TOPOLOGY_LOOP 0x02 /* Topology is FC-AL */
-#define TOPOLOGY_LNK_MENLO_MAINTENANCE 0x05 /* maint mode zephtr to menlo */
-
- union {
- struct ulp_bde lilpBde; /* This BDE points to a 128 byte buffer
- to */
- /* store the LILP AL_PA position map into */
- struct ulp_bde64 lilpBde64;
- } un;
-
-#ifdef __BIG_ENDIAN_BITFIELD
- uint32_t Dlu:1;
- uint32_t Dtf:1;
- uint32_t Drsvd2:14;
- uint32_t DlnkSpeed:8;
- uint32_t DnlPort:4;
- uint32_t Dtx:2;
- uint32_t Drx:2;
-#else /* __LITTLE_ENDIAN_BITFIELD */
- uint32_t Drx:2;
- uint32_t Dtx:2;
- uint32_t DnlPort:4;
- uint32_t DlnkSpeed:8;
- uint32_t Drsvd2:14;
- uint32_t Dtf:1;
- uint32_t Dlu:1;
-#endif
-
-#ifdef __BIG_ENDIAN_BITFIELD
- uint32_t Ulu:1;
- uint32_t Utf:1;
- uint32_t Ursvd2:14;
- uint32_t UlnkSpeed:8;
- uint32_t UnlPort:4;
- uint32_t Utx:2;
- uint32_t Urx:2;
-#else /* __LITTLE_ENDIAN_BITFIELD */
- uint32_t Urx:2;
- uint32_t Utx:2;
- uint32_t UnlPort:4;
- uint32_t UlnkSpeed:8;
- uint32_t Ursvd2:14;
- uint32_t Utf:1;
- uint32_t Ulu:1;
-#endif
-
-#define LA_UNKNW_LINK 0x0 /* lnkSpeed */
-#define LA_1GHZ_LINK 0x04 /* lnkSpeed */
-#define LA_2GHZ_LINK 0x08 /* lnkSpeed */
-#define LA_4GHZ_LINK 0x10 /* lnkSpeed */
-#define LA_8GHZ_LINK 0x20 /* lnkSpeed */
-#define LA_10GHZ_LINK 0x40 /* lnkSpeed */
-
-} READ_LA_VAR;
+ uint32_t word2;
+#define lpfc_mbx_read_top_fa_SHIFT 12
+#define lpfc_mbx_read_top_fa_MASK 0x00000001
+#define lpfc_mbx_read_top_fa_WORD word2
+#define lpfc_mbx_read_top_mm_SHIFT 11
+#define lpfc_mbx_read_top_mm_MASK 0x00000001
+#define lpfc_mbx_read_top_mm_WORD word2
+#define lpfc_mbx_read_top_pb_SHIFT 9
+#define lpfc_mbx_read_top_pb_MASK 0X00000001
+#define lpfc_mbx_read_top_pb_WORD word2
+#define lpfc_mbx_read_top_il_SHIFT 8
+#define lpfc_mbx_read_top_il_MASK 0x00000001
+#define lpfc_mbx_read_top_il_WORD word2
+#define lpfc_mbx_read_top_att_type_SHIFT 0
+#define lpfc_mbx_read_top_att_type_MASK 0x000000FF
+#define lpfc_mbx_read_top_att_type_WORD word2
+#define LPFC_ATT_RESERVED 0x00 /* Reserved - attType */
+#define LPFC_ATT_LINK_UP 0x01 /* Link is up */
+#define LPFC_ATT_LINK_DOWN 0x02 /* Link is down */
+ uint32_t word3;
+#define lpfc_mbx_read_top_alpa_granted_SHIFT 24
+#define lpfc_mbx_read_top_alpa_granted_MASK 0x000000FF
+#define lpfc_mbx_read_top_alpa_granted_WORD word3
+#define lpfc_mbx_read_top_lip_alps_SHIFT 16
+#define lpfc_mbx_read_top_lip_alps_MASK 0x000000FF
+#define lpfc_mbx_read_top_lip_alps_WORD word3
+#define lpfc_mbx_read_top_lip_type_SHIFT 8
+#define lpfc_mbx_read_top_lip_type_MASK 0x000000FF
+#define lpfc_mbx_read_top_lip_type_WORD word3
+#define lpfc_mbx_read_top_topology_SHIFT 0
+#define lpfc_mbx_read_top_topology_MASK 0x000000FF
+#define lpfc_mbx_read_top_topology_WORD word3
+#define LPFC_TOPOLOGY_PT_PT 0x01 /* Topology is pt-pt / pt-fabric */
+#define LPFC_TOPOLOGY_LOOP 0x02 /* Topology is FC-AL */
+#define LPFC_TOPOLOGY_MM 0x05 /* maint mode zephtr to menlo */
+ /* store the LILP AL_PA position map into */
+ struct ulp_bde64 lilpBde64;
+#define LPFC_ALPA_MAP_SIZE 128
+ uint32_t word7;
+#define lpfc_mbx_read_top_ld_lu_SHIFT 31
+#define lpfc_mbx_read_top_ld_lu_MASK 0x00000001
+#define lpfc_mbx_read_top_ld_lu_WORD word7
+#define lpfc_mbx_read_top_ld_tf_SHIFT 30
+#define lpfc_mbx_read_top_ld_tf_MASK 0x00000001
+#define lpfc_mbx_read_top_ld_tf_WORD word7
+#define lpfc_mbx_read_top_ld_link_spd_SHIFT 8
+#define lpfc_mbx_read_top_ld_link_spd_MASK 0x000000FF
+#define lpfc_mbx_read_top_ld_link_spd_WORD word7
+#define lpfc_mbx_read_top_ld_nl_port_SHIFT 4
+#define lpfc_mbx_read_top_ld_nl_port_MASK 0x0000000F
+#define lpfc_mbx_read_top_ld_nl_port_WORD word7
+#define lpfc_mbx_read_top_ld_tx_SHIFT 2
+#define lpfc_mbx_read_top_ld_tx_MASK 0x00000003
+#define lpfc_mbx_read_top_ld_tx_WORD word7
+#define lpfc_mbx_read_top_ld_rx_SHIFT 0
+#define lpfc_mbx_read_top_ld_rx_MASK 0x00000003
+#define lpfc_mbx_read_top_ld_rx_WORD word7
+ uint32_t word8;
+#define lpfc_mbx_read_top_lu_SHIFT 31
+#define lpfc_mbx_read_top_lu_MASK 0x00000001
+#define lpfc_mbx_read_top_lu_WORD word8
+#define lpfc_mbx_read_top_tf_SHIFT 30
+#define lpfc_mbx_read_top_tf_MASK 0x00000001
+#define lpfc_mbx_read_top_tf_WORD word8
+#define lpfc_mbx_read_top_link_spd_SHIFT 8
+#define lpfc_mbx_read_top_link_spd_MASK 0x000000FF
+#define lpfc_mbx_read_top_link_spd_WORD word8
+#define lpfc_mbx_read_top_nl_port_SHIFT 4
+#define lpfc_mbx_read_top_nl_port_MASK 0x0000000F
+#define lpfc_mbx_read_top_nl_port_WORD word8
+#define lpfc_mbx_read_top_tx_SHIFT 2
+#define lpfc_mbx_read_top_tx_MASK 0x00000003
+#define lpfc_mbx_read_top_tx_WORD word8
+#define lpfc_mbx_read_top_rx_SHIFT 0
+#define lpfc_mbx_read_top_rx_MASK 0x00000003
+#define lpfc_mbx_read_top_rx_WORD word8
+#define LPFC_LINK_SPEED_UNKNOWN 0x0
+#define LPFC_LINK_SPEED_1GHZ 0x04
+#define LPFC_LINK_SPEED_2GHZ 0x08
+#define LPFC_LINK_SPEED_4GHZ 0x10
+#define LPFC_LINK_SPEED_8GHZ 0x20
+#define LPFC_LINK_SPEED_10GHZ 0x40
+#define LPFC_LINK_SPEED_16GHZ 0x80
+};
/* Structure for MB Command CLEAR_LA (22) */
@@ -3016,7 +3030,6 @@ typedef union {
READ_LNK_VAR varRdLnk; /* cmd = 18 (READ_LNK_STAT) */
REG_LOGIN_VAR varRegLogin; /* cmd = 19 (REG_LOGIN(64)) */
UNREG_LOGIN_VAR varUnregLogin; /* cmd = 20 (UNREG_LOGIN) */
- READ_LA_VAR varReadLA; /* cmd = 21 (READ_LA(64)) */
CLEAR_LA_VAR varClearLA; /* cmd = 22 (CLEAR_LA) */
DUMP_VAR varDmp; /* Warm Start DUMP mbx cmd */
UNREG_D_ID_VAR varUnregDID; /* cmd = 0x23 (UNREG_D_ID) */
@@ -3026,6 +3039,7 @@ typedef union {
struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */
struct update_cfg_var varUpdateCfg; /* cmd = 0x1B (UPDATE_CFG)*/
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
+ struct lpfc_mbx_read_top varReadTop; /* cmd = 0x95 (READ_TOPOLOGY) */
REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 6e4bc34e1d0d..94c1aa1136de 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -64,29 +64,39 @@ struct lpfc_sli_intf {
#define lpfc_sli_intf_valid_MASK 0x00000007
#define lpfc_sli_intf_valid_WORD word0
#define LPFC_SLI_INTF_VALID 6
-#define lpfc_sli_intf_featurelevel2_SHIFT 24
-#define lpfc_sli_intf_featurelevel2_MASK 0x0000001F
-#define lpfc_sli_intf_featurelevel2_WORD word0
-#define lpfc_sli_intf_featurelevel1_SHIFT 16
-#define lpfc_sli_intf_featurelevel1_MASK 0x000000FF
-#define lpfc_sli_intf_featurelevel1_WORD word0
-#define LPFC_SLI_INTF_FEATURELEVEL1_1 1
-#define LPFC_SLI_INTF_FEATURELEVEL1_2 2
+#define lpfc_sli_intf_sli_hint2_SHIFT 24
+#define lpfc_sli_intf_sli_hint2_MASK 0x0000001F
+#define lpfc_sli_intf_sli_hint2_WORD word0
+#define LPFC_SLI_INTF_SLI_HINT2_NONE 0
+#define lpfc_sli_intf_sli_hint1_SHIFT 16
+#define lpfc_sli_intf_sli_hint1_MASK 0x000000FF
+#define lpfc_sli_intf_sli_hint1_WORD word0
+#define LPFC_SLI_INTF_SLI_HINT1_NONE 0
+#define LPFC_SLI_INTF_SLI_HINT1_1 1
+#define LPFC_SLI_INTF_SLI_HINT1_2 2
+#define lpfc_sli_intf_if_type_SHIFT 12
+#define lpfc_sli_intf_if_type_MASK 0x0000000F
+#define lpfc_sli_intf_if_type_WORD word0
+#define LPFC_SLI_INTF_IF_TYPE_0 0
+#define LPFC_SLI_INTF_IF_TYPE_1 1
+#define LPFC_SLI_INTF_IF_TYPE_2 2
#define lpfc_sli_intf_sli_family_SHIFT 8
-#define lpfc_sli_intf_sli_family_MASK 0x000000FF
+#define lpfc_sli_intf_sli_family_MASK 0x0000000F
#define lpfc_sli_intf_sli_family_WORD word0
-#define LPFC_SLI_INTF_FAMILY_BE2 0
-#define LPFC_SLI_INTF_FAMILY_BE3 1
+#define LPFC_SLI_INTF_FAMILY_BE2 0x0
+#define LPFC_SLI_INTF_FAMILY_BE3 0x1
+#define LPFC_SLI_INTF_FAMILY_LNCR_A0 0xa
+#define LPFC_SLI_INTF_FAMILY_LNCR_B0 0xb
#define lpfc_sli_intf_slirev_SHIFT 4
#define lpfc_sli_intf_slirev_MASK 0x0000000F
#define lpfc_sli_intf_slirev_WORD word0
#define LPFC_SLI_INTF_REV_SLI3 3
#define LPFC_SLI_INTF_REV_SLI4 4
-#define lpfc_sli_intf_if_type_SHIFT 0
-#define lpfc_sli_intf_if_type_MASK 0x00000007
-#define lpfc_sli_intf_if_type_WORD word0
-#define LPFC_SLI_INTF_IF_TYPE_0 0
-#define LPFC_SLI_INTF_IF_TYPE_1 1
+#define lpfc_sli_intf_func_type_SHIFT 0
+#define lpfc_sli_intf_func_type_MASK 0x00000001
+#define lpfc_sli_intf_func_type_WORD word0
+#define LPFC_SLI_INTF_IF_TYPE_PHYS 0
+#define LPFC_SLI_INTF_IF_TYPE_VIRT 1
};
#define LPFC_SLI4_MBX_EMBED true
@@ -450,35 +460,40 @@ struct lpfc_register {
uint32_t word0;
};
+/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */
#define LPFC_UERR_STATUS_HI 0x00A4
#define LPFC_UERR_STATUS_LO 0x00A0
#define LPFC_UE_MASK_HI 0x00AC
#define LPFC_UE_MASK_LO 0x00A8
+
+/* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */
#define LPFC_SLI_INTF 0x0058
-/* BAR0 Registers */
-#define LPFC_HST_STATE 0x00AC
-#define lpfc_hst_state_perr_SHIFT 31
-#define lpfc_hst_state_perr_MASK 0x1
-#define lpfc_hst_state_perr_WORD word0
-#define lpfc_hst_state_sfi_SHIFT 30
-#define lpfc_hst_state_sfi_MASK 0x1
-#define lpfc_hst_state_sfi_WORD word0
-#define lpfc_hst_state_nip_SHIFT 29
-#define lpfc_hst_state_nip_MASK 0x1
-#define lpfc_hst_state_nip_WORD word0
-#define lpfc_hst_state_ipc_SHIFT 28
-#define lpfc_hst_state_ipc_MASK 0x1
-#define lpfc_hst_state_ipc_WORD word0
-#define lpfc_hst_state_xrom_SHIFT 27
-#define lpfc_hst_state_xrom_MASK 0x1
-#define lpfc_hst_state_xrom_WORD word0
-#define lpfc_hst_state_dl_SHIFT 26
-#define lpfc_hst_state_dl_MASK 0x1
-#define lpfc_hst_state_dl_WORD word0
-#define lpfc_hst_state_port_status_SHIFT 0
-#define lpfc_hst_state_port_status_MASK 0xFFFF
-#define lpfc_hst_state_port_status_WORD word0
+#define LPFC_SLIPORT_IF2_SMPHR 0x0400
+#define lpfc_port_smphr_perr_SHIFT 31
+#define lpfc_port_smphr_perr_MASK 0x1
+#define lpfc_port_smphr_perr_WORD word0
+#define lpfc_port_smphr_sfi_SHIFT 30
+#define lpfc_port_smphr_sfi_MASK 0x1
+#define lpfc_port_smphr_sfi_WORD word0
+#define lpfc_port_smphr_nip_SHIFT 29
+#define lpfc_port_smphr_nip_MASK 0x1
+#define lpfc_port_smphr_nip_WORD word0
+#define lpfc_port_smphr_ipc_SHIFT 28
+#define lpfc_port_smphr_ipc_MASK 0x1
+#define lpfc_port_smphr_ipc_WORD word0
+#define lpfc_port_smphr_scr1_SHIFT 27
+#define lpfc_port_smphr_scr1_MASK 0x1
+#define lpfc_port_smphr_scr1_WORD word0
+#define lpfc_port_smphr_scr2_SHIFT 26
+#define lpfc_port_smphr_scr2_MASK 0x1
+#define lpfc_port_smphr_scr2_WORD word0
+#define lpfc_port_smphr_host_scratch_SHIFT 16
+#define lpfc_port_smphr_host_scratch_MASK 0xFF
+#define lpfc_port_smphr_host_scratch_WORD word0
+#define lpfc_port_smphr_port_status_SHIFT 0
+#define lpfc_port_smphr_port_status_MASK 0xFFFF
+#define lpfc_port_smphr_port_status_WORD word0
#define LPFC_POST_STAGE_POWER_ON_RESET 0x0000
#define LPFC_POST_STAGE_AWAITING_HOST_RDY 0x0001
@@ -511,10 +526,46 @@ struct lpfc_register {
#define LPFC_POST_STAGE_RC_DONE 0x0B07
#define LPFC_POST_STAGE_REBOOT_SYSTEM 0x0B08
#define LPFC_POST_STAGE_MAC_ADDRESS 0x0C00
-#define LPFC_POST_STAGE_ARMFW_READY 0xC000
-#define LPFC_POST_STAGE_ARMFW_UE 0xF000
+#define LPFC_POST_STAGE_PORT_READY 0xC000
+#define LPFC_POST_STAGE_PORT_UE 0xF000
+
+#define LPFC_SLIPORT_STATUS 0x0404
+#define lpfc_sliport_status_err_SHIFT 31
+#define lpfc_sliport_status_err_MASK 0x1
+#define lpfc_sliport_status_err_WORD word0
+#define lpfc_sliport_status_end_SHIFT 30
+#define lpfc_sliport_status_end_MASK 0x1
+#define lpfc_sliport_status_end_WORD word0
+#define lpfc_sliport_status_oti_SHIFT 29
+#define lpfc_sliport_status_oti_MASK 0x1
+#define lpfc_sliport_status_oti_WORD word0
+#define lpfc_sliport_status_rn_SHIFT 24
+#define lpfc_sliport_status_rn_MASK 0x1
+#define lpfc_sliport_status_rn_WORD word0
+#define lpfc_sliport_status_rdy_SHIFT 23
+#define lpfc_sliport_status_rdy_MASK 0x1
+#define lpfc_sliport_status_rdy_WORD word0
+#define MAX_IF_TYPE_2_RESETS 1000
+
+#define LPFC_SLIPORT_CNTRL 0x0408
+#define lpfc_sliport_ctrl_end_SHIFT 30
+#define lpfc_sliport_ctrl_end_MASK 0x1
+#define lpfc_sliport_ctrl_end_WORD word0
+#define LPFC_SLIPORT_LITTLE_ENDIAN 0
+#define LPFC_SLIPORT_BIG_ENDIAN 1
+#define lpfc_sliport_ctrl_ip_SHIFT 27
+#define lpfc_sliport_ctrl_ip_MASK 0x1
+#define lpfc_sliport_ctrl_ip_WORD word0
+#define LPFC_SLIPORT_INIT_PORT 1
+
+#define LPFC_SLIPORT_ERR_1 0x040C
+#define LPFC_SLIPORT_ERR_2 0x0410
+
+/* The following Registers apply to SLI4 if_type 0 UCNAs. They typically
+ * reside in BAR 2.
+ */
+#define LPFC_SLIPORT_IF0_SMPHR 0x00AC
-/* BAR1 Registers */
#define LPFC_IMR_MASK_ALL 0xFFFFFFFF
#define LPFC_ISCR_CLEAR_ALL 0xFFFFFFFF
@@ -569,14 +620,21 @@ struct lpfc_register {
#define LPFC_SLI4_INTR30 BIT30
#define LPFC_SLI4_INTR31 BIT31
-/* BAR2 Registers */
+/*
+ * The Doorbell registers defined here exist in different BAR
+ * register sets depending on the UCNA Port's reported if_type
+ * value. For UCNA ports running SLI4 and if_type 0, they reside in
+ * BAR4. For UCNA ports running SLI4 and if_type 2, they reside in
+ * BAR0. The offsets are the same so the driver must account for
+ * any base address difference.
+ */
#define LPFC_RQ_DOORBELL 0x00A0
#define lpfc_rq_doorbell_num_posted_SHIFT 16
#define lpfc_rq_doorbell_num_posted_MASK 0x3FFF
#define lpfc_rq_doorbell_num_posted_WORD word0
#define LPFC_RQ_POST_BATCH 8 /* RQEs to post at one time */
#define lpfc_rq_doorbell_id_SHIFT 0
-#define lpfc_rq_doorbell_id_MASK 0x03FF
+#define lpfc_rq_doorbell_id_MASK 0xFFFF
#define lpfc_rq_doorbell_id_WORD word0
#define LPFC_WQ_DOORBELL 0x0040
@@ -591,6 +649,11 @@ struct lpfc_register {
#define lpfc_wq_doorbell_id_WORD word0
#define LPFC_EQCQ_DOORBELL 0x0120
+#define lpfc_eqcq_doorbell_se_SHIFT 31
+#define lpfc_eqcq_doorbell_se_MASK 0x0001
+#define lpfc_eqcq_doorbell_se_WORD word0
+#define LPFC_EQCQ_SOLICIT_ENABLE_OFF 0
+#define LPFC_EQCQ_SOLICIT_ENABLE_ON 1
#define lpfc_eqcq_doorbell_arm_SHIFT 29
#define lpfc_eqcq_doorbell_arm_MASK 0x0001
#define lpfc_eqcq_doorbell_arm_WORD word0
@@ -628,7 +691,7 @@ struct lpfc_register {
#define lpfc_mq_doorbell_num_posted_MASK 0x3FFF
#define lpfc_mq_doorbell_num_posted_WORD word0
#define lpfc_mq_doorbell_id_SHIFT 0
-#define lpfc_mq_doorbell_id_MASK 0x03FF
+#define lpfc_mq_doorbell_id_MASK 0xFFFF
#define lpfc_mq_doorbell_id_WORD word0
struct lpfc_sli4_cfg_mhdr {
@@ -1048,12 +1111,18 @@ struct lpfc_mbx_mq_create_ext {
#define lpfc_mbx_mq_create_ext_async_evt_link_SHIFT LPFC_TRAILER_CODE_LINK
#define lpfc_mbx_mq_create_ext_async_evt_link_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_link_WORD async_evt_bmap
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_SHIFT LPFC_TRAILER_CODE_FCOE
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_MASK 0x00000001
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_WORD async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_fip_SHIFT LPFC_TRAILER_CODE_FCOE
+#define lpfc_mbx_mq_create_ext_async_evt_fip_MASK 0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_fip_WORD async_evt_bmap
#define lpfc_mbx_mq_create_ext_async_evt_group5_SHIFT LPFC_TRAILER_CODE_GRP5
#define lpfc_mbx_mq_create_ext_async_evt_group5_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_group5_WORD async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_fc_SHIFT LPFC_TRAILER_CODE_FC
+#define lpfc_mbx_mq_create_ext_async_evt_fc_MASK 0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_fc_WORD async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_sli_SHIFT LPFC_TRAILER_CODE_SLI
+#define lpfc_mbx_mq_create_ext_async_evt_sli_MASK 0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_sli_WORD async_evt_bmap
struct mq_context context;
struct dma_address page[LPFC_MAX_MQ_PAGE];
} request;
@@ -1307,7 +1376,7 @@ struct lpfc_mbx_query_fw_cfg {
#define lpfc_function_mode_dal_WORD function_mode
#define lpfc_function_mode_lro_SHIFT 9
#define lpfc_function_mode_lro_MASK 0x00000001
-#define lpfc_function_mode_lro_WORD function_mode9
+#define lpfc_function_mode_lro_WORD function_mode
#define lpfc_function_mode_flex10_SHIFT 10
#define lpfc_function_mode_flex10_MASK 0x00000001
#define lpfc_function_mode_flex10_WORD function_mode
@@ -1358,10 +1427,16 @@ struct lpfc_mbx_init_vfi {
#define lpfc_init_vfi_vf_SHIFT 29
#define lpfc_init_vfi_vf_MASK 0x00000001
#define lpfc_init_vfi_vf_WORD word1
+#define lpfc_init_vfi_vp_SHIFT 28
+#define lpfc_init_vfi_vp_MASK 0x00000001
+#define lpfc_init_vfi_vp_WORD word1
#define lpfc_init_vfi_vfi_SHIFT 0
#define lpfc_init_vfi_vfi_MASK 0x0000FFFF
#define lpfc_init_vfi_vfi_WORD word1
uint32_t word2;
+#define lpfc_init_vfi_vpi_SHIFT 16
+#define lpfc_init_vfi_vpi_MASK 0x0000FFFF
+#define lpfc_init_vfi_vpi_WORD word2
#define lpfc_init_vfi_fcfi_SHIFT 0
#define lpfc_init_vfi_fcfi_MASK 0x0000FFFF
#define lpfc_init_vfi_fcfi_WORD word2
@@ -2069,6 +2144,8 @@ struct lpfc_mcqe {
#define LPFC_TRAILER_CODE_FCOE 0x2
#define LPFC_TRAILER_CODE_DCBX 0x3
#define LPFC_TRAILER_CODE_GRP5 0x5
+#define LPFC_TRAILER_CODE_FC 0x10
+#define LPFC_TRAILER_CODE_SLI 0x11
};
struct lpfc_acqe_link {
@@ -2094,11 +2171,12 @@ struct lpfc_acqe_link {
#define LPFC_ASYNC_LINK_STATUS_UP 0x1
#define LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN 0x2
#define LPFC_ASYNC_LINK_STATUS_LOGICAL_UP 0x3
-#define lpfc_acqe_link_physical_SHIFT 0
-#define lpfc_acqe_link_physical_MASK 0x000000FF
-#define lpfc_acqe_link_physical_WORD word0
-#define LPFC_ASYNC_LINK_PORT_A 0x0
-#define LPFC_ASYNC_LINK_PORT_B 0x1
+#define lpfc_acqe_link_type_SHIFT 6
+#define lpfc_acqe_link_type_MASK 0x00000003
+#define lpfc_acqe_link_type_WORD word0
+#define lpfc_acqe_link_number_SHIFT 0
+#define lpfc_acqe_link_number_MASK 0x0000003F
+#define lpfc_acqe_link_number_WORD word0
uint32_t word1;
#define lpfc_acqe_link_fault_SHIFT 0
#define lpfc_acqe_link_fault_MASK 0x000000FF
@@ -2106,29 +2184,31 @@ struct lpfc_acqe_link {
#define LPFC_ASYNC_LINK_FAULT_NONE 0x0
#define LPFC_ASYNC_LINK_FAULT_LOCAL 0x1
#define LPFC_ASYNC_LINK_FAULT_REMOTE 0x2
-#define lpfc_acqe_qos_link_speed_SHIFT 16
-#define lpfc_acqe_qos_link_speed_MASK 0x0000FFFF
-#define lpfc_acqe_qos_link_speed_WORD word1
+#define lpfc_acqe_logical_link_speed_SHIFT 16
+#define lpfc_acqe_logical_link_speed_MASK 0x0000FFFF
+#define lpfc_acqe_logical_link_speed_WORD word1
uint32_t event_tag;
uint32_t trailer;
+#define LPFC_LINK_EVENT_TYPE_PHYSICAL 0x0
+#define LPFC_LINK_EVENT_TYPE_VIRTUAL 0x1
};
-struct lpfc_acqe_fcoe {
+struct lpfc_acqe_fip {
uint32_t index;
uint32_t word1;
-#define lpfc_acqe_fcoe_fcf_count_SHIFT 0
-#define lpfc_acqe_fcoe_fcf_count_MASK 0x0000FFFF
-#define lpfc_acqe_fcoe_fcf_count_WORD word1
-#define lpfc_acqe_fcoe_event_type_SHIFT 16
-#define lpfc_acqe_fcoe_event_type_MASK 0x0000FFFF
-#define lpfc_acqe_fcoe_event_type_WORD word1
-#define LPFC_FCOE_EVENT_TYPE_NEW_FCF 0x1
-#define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL 0x2
-#define LPFC_FCOE_EVENT_TYPE_FCF_DEAD 0x3
-#define LPFC_FCOE_EVENT_TYPE_CVL 0x4
-#define LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD 0x5
+#define lpfc_acqe_fip_fcf_count_SHIFT 0
+#define lpfc_acqe_fip_fcf_count_MASK 0x0000FFFF
+#define lpfc_acqe_fip_fcf_count_WORD word1
+#define lpfc_acqe_fip_event_type_SHIFT 16
+#define lpfc_acqe_fip_event_type_MASK 0x0000FFFF
+#define lpfc_acqe_fip_event_type_WORD word1
uint32_t event_tag;
uint32_t trailer;
+#define LPFC_FIP_EVENT_TYPE_NEW_FCF 0x1
+#define LPFC_FIP_EVENT_TYPE_FCF_TABLE_FULL 0x2
+#define LPFC_FIP_EVENT_TYPE_FCF_DEAD 0x3
+#define LPFC_FIP_EVENT_TYPE_CVL 0x4
+#define LPFC_FIP_EVENT_TYPE_FCF_PARAM_MOD 0x5
};
struct lpfc_acqe_dcbx {
@@ -2140,9 +2220,12 @@ struct lpfc_acqe_dcbx {
struct lpfc_acqe_grp5 {
uint32_t word0;
-#define lpfc_acqe_grp5_pport_SHIFT 0
-#define lpfc_acqe_grp5_pport_MASK 0x000000FF
-#define lpfc_acqe_grp5_pport_WORD word0
+#define lpfc_acqe_grp5_type_SHIFT 6
+#define lpfc_acqe_grp5_type_MASK 0x00000003
+#define lpfc_acqe_grp5_type_WORD word0
+#define lpfc_acqe_grp5_number_SHIFT 0
+#define lpfc_acqe_grp5_number_MASK 0x0000003F
+#define lpfc_acqe_grp5_number_WORD word0
uint32_t word1;
#define lpfc_acqe_grp5_llink_spd_SHIFT 16
#define lpfc_acqe_grp5_llink_spd_MASK 0x0000FFFF
@@ -2151,6 +2234,68 @@ struct lpfc_acqe_grp5 {
uint32_t trailer;
};
+struct lpfc_acqe_fc_la {
+ uint32_t word0;
+#define lpfc_acqe_fc_la_speed_SHIFT 24
+#define lpfc_acqe_fc_la_speed_MASK 0x000000FF
+#define lpfc_acqe_fc_la_speed_WORD word0
+#define LPFC_FC_LA_SPEED_UNKOWN 0x0
+#define LPFC_FC_LA_SPEED_1G 0x1
+#define LPFC_FC_LA_SPEED_2G 0x2
+#define LPFC_FC_LA_SPEED_4G 0x4
+#define LPFC_FC_LA_SPEED_8G 0x8
+#define LPFC_FC_LA_SPEED_10G 0xA
+#define LPFC_FC_LA_SPEED_16G 0x10
+#define lpfc_acqe_fc_la_topology_SHIFT 16
+#define lpfc_acqe_fc_la_topology_MASK 0x000000FF
+#define lpfc_acqe_fc_la_topology_WORD word0
+#define LPFC_FC_LA_TOP_UNKOWN 0x0
+#define LPFC_FC_LA_TOP_P2P 0x1
+#define LPFC_FC_LA_TOP_FCAL 0x2
+#define LPFC_FC_LA_TOP_INTERNAL_LOOP 0x3
+#define LPFC_FC_LA_TOP_SERDES_LOOP 0x4
+#define lpfc_acqe_fc_la_att_type_SHIFT 8
+#define lpfc_acqe_fc_la_att_type_MASK 0x000000FF
+#define lpfc_acqe_fc_la_att_type_WORD word0
+#define LPFC_FC_LA_TYPE_LINK_UP 0x1
+#define LPFC_FC_LA_TYPE_LINK_DOWN 0x2
+#define LPFC_FC_LA_TYPE_NO_HARD_ALPA 0x3
+#define lpfc_acqe_fc_la_port_type_SHIFT 6
+#define lpfc_acqe_fc_la_port_type_MASK 0x00000003
+#define lpfc_acqe_fc_la_port_type_WORD word0
+#define LPFC_LINK_TYPE_ETHERNET 0x0
+#define LPFC_LINK_TYPE_FC 0x1
+#define lpfc_acqe_fc_la_port_number_SHIFT 0
+#define lpfc_acqe_fc_la_port_number_MASK 0x0000003F
+#define lpfc_acqe_fc_la_port_number_WORD word0
+ uint32_t word1;
+#define lpfc_acqe_fc_la_llink_spd_SHIFT 16
+#define lpfc_acqe_fc_la_llink_spd_MASK 0x0000FFFF
+#define lpfc_acqe_fc_la_llink_spd_WORD word1
+#define lpfc_acqe_fc_la_fault_SHIFT 0
+#define lpfc_acqe_fc_la_fault_MASK 0x000000FF
+#define lpfc_acqe_fc_la_fault_WORD word1
+#define LPFC_FC_LA_FAULT_NONE 0x0
+#define LPFC_FC_LA_FAULT_LOCAL 0x1
+#define LPFC_FC_LA_FAULT_REMOTE 0x2
+ uint32_t event_tag;
+ uint32_t trailer;
+#define LPFC_FC_LA_EVENT_TYPE_FC_LINK 0x1
+#define LPFC_FC_LA_EVENT_TYPE_SHARED_LINK 0x2
+};
+
+struct lpfc_acqe_sli {
+ uint32_t event_data1;
+ uint32_t event_data2;
+ uint32_t reserved;
+ uint32_t trailer;
+#define LPFC_SLI_EVENT_TYPE_PORT_ERROR 0x1
+#define LPFC_SLI_EVENT_TYPE_OVER_TEMP 0x2
+#define LPFC_SLI_EVENT_TYPE_NORM_TEMP 0x3
+#define LPFC_SLI_EVENT_TYPE_NVLOG_POST 0x4
+#define LPFC_SLI_EVENT_TYPE_DIAG_DUMP 0x5
+};
+
/*
* Define the bootstrap mailbox (bmbx) region used to communicate
* mailbox command between the host and port. The mailbox consists
@@ -2210,7 +2355,7 @@ struct wqe_common {
#define wqe_rcvoxid_WORD word9
uint32_t word10;
#define wqe_ebde_cnt_SHIFT 0
-#define wqe_ebde_cnt_MASK 0x00000007
+#define wqe_ebde_cnt_MASK 0x0000000f
#define wqe_ebde_cnt_WORD word10
#define wqe_lenloc_SHIFT 7
#define wqe_lenloc_MASK 0x00000003
@@ -2402,7 +2547,6 @@ struct xmit_seq64_wqe {
uint32_t relative_offset;
struct wqe_rctl_dfctl wge_ctl;
struct wqe_common wqe_com; /* words 6-11 */
- /* Note: word10 different REVISIT */
uint32_t xmit_len;
uint32_t rsvd_12_15[3];
};
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b3065791f303..462242dcdd0a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -446,23 +446,25 @@ lpfc_config_port_post(struct lpfc_hba *phba)
/* Get the default values for Model Name and Description */
lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
- if ((phba->cfg_link_speed > LINK_SPEED_10G)
- || ((phba->cfg_link_speed == LINK_SPEED_1G)
+ if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_16G)
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G)
&& !(phba->lmt & LMT_1Gb))
- || ((phba->cfg_link_speed == LINK_SPEED_2G)
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G)
&& !(phba->lmt & LMT_2Gb))
- || ((phba->cfg_link_speed == LINK_SPEED_4G)
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G)
&& !(phba->lmt & LMT_4Gb))
- || ((phba->cfg_link_speed == LINK_SPEED_8G)
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G)
&& !(phba->lmt & LMT_8Gb))
- || ((phba->cfg_link_speed == LINK_SPEED_10G)
- && !(phba->lmt & LMT_10Gb))) {
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G)
+ && !(phba->lmt & LMT_10Gb))
+ || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G)
+ && !(phba->lmt & LMT_16Gb))) {
/* Reset link speed to auto */
lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
"1302 Invalid speed for this board: "
"Reset link speed to auto: x%x\n",
phba->cfg_link_speed);
- phba->cfg_link_speed = LINK_SPEED_AUTO;
+ phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
}
phba->link_state = LPFC_LINK_DOWN;
@@ -648,22 +650,23 @@ lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag)
mb = &pmb->u.mb;
pmb->vport = vport;
- lpfc_init_link(phba, pmb, phba->cfg_topology,
- phba->cfg_link_speed);
+ lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
lpfc_set_loopback_flag(phba);
rc = lpfc_sli_issue_mbox(phba, pmb, flag);
- if (rc != MBX_SUCCESS) {
+ if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0498 Adapter failed to init, mbxCmd x%x "
"INIT_LINK, mbxStatus x%x\n",
mb->mbxCommand, mb->mbxStatus);
- /* Clear all interrupt enable conditions */
- writel(0, phba->HCregaddr);
- readl(phba->HCregaddr); /* flush */
- /* Clear all pending interrupts */
- writel(0xffffffff, phba->HAregaddr);
- readl(phba->HAregaddr); /* flush */
+ if (phba->sli_rev <= LPFC_SLI_REV3) {
+ /* Clear all interrupt enable conditions */
+ writel(0, phba->HCregaddr);
+ readl(phba->HCregaddr); /* flush */
+ /* Clear all pending interrupts */
+ writel(0xffffffff, phba->HAregaddr);
+ readl(phba->HAregaddr); /* flush */
+ }
phba->link_state = LPFC_HBA_ERROR;
if (rc != MBX_BUSY || flag == MBX_POLL)
mempool_free(pmb, phba->mbox_mem_pool);
@@ -927,6 +930,35 @@ lpfc_hb_timeout(unsigned long ptr)
}
/**
+ * lpfc_rrq_timeout - The RRQ-timer timeout handler
+ * @ptr: unsigned long holds the pointer to lpfc hba data structure.
+ *
+ * This is the RRQ-timer timeout handler registered to the lpfc driver. When
+ * this timer fires, a RRQ timeout event shall be posted to the lpfc driver
+ * work-port-events bitmap and the worker thread is notified. This timeout
+ * event will be used by the worker thread to invoke the actual timeout
+ * handler routine, lpfc_rrq_handler. Any periodical operations will
+ * be performed in the timeout handler and the RRQ timeout event bit shall
+ * be cleared by the worker thread after it has taken the event bitmap out.
+ **/
+static void
+lpfc_rrq_timeout(unsigned long ptr)
+{
+ struct lpfc_hba *phba;
+ uint32_t tmo_posted;
+ unsigned long iflag;
+
+ phba = (struct lpfc_hba *)ptr;
+ spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
+ tmo_posted = phba->hba_flag & HBA_RRQ_ACTIVE;
+ if (!tmo_posted)
+ phba->hba_flag |= HBA_RRQ_ACTIVE;
+ spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
+ if (!tmo_posted)
+ lpfc_worker_wake_up(phba);
+}
+
+/**
* lpfc_hb_mbox_cmpl - The lpfc heart-beat mailbox command callback function
* @phba: pointer to lpfc hba data structure.
* @pmboxq: pointer to the driver internal queue element for mailbox command.
@@ -1374,6 +1406,8 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
struct lpfc_vport *vport = phba->pport;
uint32_t event_data;
struct Scsi_Host *shost;
+ uint32_t if_type;
+ struct lpfc_register portstat_reg;
/* If the pci channel is offline, ignore possible errors, since
* we cannot communicate with the pci card anyway.
@@ -1390,17 +1424,49 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
/* For now, the actual action for SLI4 device handling is not
* specified yet, just treated it as adaptor hardware failure
*/
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0143 SLI4 Adapter Hardware Error Data: x%x x%x\n",
- phba->work_status[0], phba->work_status[1]);
-
event_data = FC_REG_DUMP_EVENT;
shost = lpfc_shost_from_vport(vport);
fc_host_post_vendor_event(shost, fc_get_event_number(),
sizeof(event_data), (char *) &event_data,
SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
- lpfc_sli4_offline_eratt(phba);
+ if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ lpfc_sli4_offline_eratt(phba);
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ portstat_reg.word0 =
+ readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+
+ if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) {
+ /* TODO: Register for Overtemp async events. */
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2889 Port Overtemperature event, "
+ "taking port\n");
+ spin_lock_irq(&phba->hbalock);
+ phba->over_temp_state = HBA_OVER_TEMP;
+ spin_unlock_irq(&phba->hbalock);
+ lpfc_sli4_offline_eratt(phba);
+ return;
+ }
+ if (bf_get(lpfc_sliport_status_rn, &portstat_reg)) {
+ /*
+ * TODO: Attempt port recovery via a port reset.
+ * When fully implemented, the driver should
+ * attempt to recover the port here and return.
+ * For now, log an error and take the port offline.
+ */
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2887 Port Error: Attempting "
+ "Port Recovery\n");
+ }
+ lpfc_sli4_offline_eratt(phba);
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
+ break;
+ }
}
/**
@@ -1459,8 +1525,8 @@ lpfc_handle_latt(struct lpfc_hba *phba)
lpfc_els_flush_all_cmd(phba);
psli->slistat.link_event++;
- lpfc_read_la(phba, pmb, mp);
- pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
+ lpfc_read_topology(phba, pmb, mp);
+ pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
pmb->vport = vport;
/* Block ELS IOCBs until we have processed this mbox command */
phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
@@ -1853,6 +1919,14 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
m = (typeof(m)){"LPVe12002", "PCIe Shared I/O",
"Fibre Channel Adapter"};
break;
+ case PCI_DEVICE_ID_LANCER_FC:
+ oneConnect = 1;
+ m = (typeof(m)){"Undefined", "PCIe", "Fibre Channel Adapter"};
+ break;
+ case PCI_DEVICE_ID_LANCER_FCOE:
+ oneConnect = 1;
+ m = (typeof(m)){"Undefined", "PCIe", "FCoE"};
+ break;
default:
m = (typeof(m)){"Unknown", "", ""};
break;
@@ -2943,63 +3017,6 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
}
/**
- * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
- * @phba: pointer to lpfc hba data structure.
- *
- * This function uses the QUERY_FW_CFG mailbox command to determine if the
- * firmware loaded supports FCoE. A return of zero indicates that the mailbox
- * was successful and the firmware supports FCoE. Any other return indicates
- * a error. It is assumed that this function will be called before interrupts
- * are enabled.
- **/
-static int
-lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba)
-{
- int rc = 0;
- LPFC_MBOXQ_t *mboxq;
- struct lpfc_mbx_query_fw_cfg *query_fw_cfg;
- uint32_t length;
- uint32_t shdr_status, shdr_add_status;
-
- mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mboxq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2621 Failed to allocate mbox for "
- "query firmware config cmd\n");
- return -ENOMEM;
- }
- query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg;
- length = (sizeof(struct lpfc_mbx_query_fw_cfg) -
- sizeof(struct lpfc_sli4_cfg_mhdr));
- lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
- LPFC_MBOX_OPCODE_QUERY_FW_CFG,
- length, LPFC_SLI4_MBX_EMBED);
- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
- /* The IOCTL status is embedded in the mailbox subheader. */
- shdr_status = bf_get(lpfc_mbox_hdr_status,
- &query_fw_cfg->header.cfg_shdr.response);
- shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
- &query_fw_cfg->header.cfg_shdr.response);
- if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) {
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "2622 Query Firmware Config failed "
- "mbx status x%x, status x%x add_status x%x\n",
- rc, shdr_status, shdr_add_status);
- return -EINVAL;
- }
- if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "2623 FCoE Function not supported by firmware. "
- "Function mode = %08x\n",
- query_fw_cfg->function_mode);
- return -EINVAL;
- }
- if (rc != MBX_TIMEOUT)
- mempool_free(mboxq, phba->mbox_mem_pool);
- return 0;
-}
-
-/**
* lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async link completion queue entry.
@@ -3051,20 +3068,20 @@ lpfc_sli4_parse_latt_type(struct lpfc_hba *phba,
switch (bf_get(lpfc_acqe_link_status, acqe_link)) {
case LPFC_ASYNC_LINK_STATUS_DOWN:
case LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN:
- att_type = AT_LINK_DOWN;
+ att_type = LPFC_ATT_LINK_DOWN;
break;
case LPFC_ASYNC_LINK_STATUS_UP:
/* Ignore physical link up events - wait for logical link up */
- att_type = AT_RESERVED;
+ att_type = LPFC_ATT_RESERVED;
break;
case LPFC_ASYNC_LINK_STATUS_LOGICAL_UP:
- att_type = AT_LINK_UP;
+ att_type = LPFC_ATT_LINK_UP;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0399 Invalid link attention type: x%x\n",
bf_get(lpfc_acqe_link_status, acqe_link));
- att_type = AT_RESERVED;
+ att_type = LPFC_ATT_RESERVED;
break;
}
return att_type;
@@ -3088,36 +3105,32 @@ lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba,
switch (bf_get(lpfc_acqe_link_speed, acqe_link)) {
case LPFC_ASYNC_LINK_SPEED_ZERO:
- link_speed = LA_UNKNW_LINK;
- break;
case LPFC_ASYNC_LINK_SPEED_10MBPS:
- link_speed = LA_UNKNW_LINK;
- break;
case LPFC_ASYNC_LINK_SPEED_100MBPS:
- link_speed = LA_UNKNW_LINK;
+ link_speed = LPFC_LINK_SPEED_UNKNOWN;
break;
case LPFC_ASYNC_LINK_SPEED_1GBPS:
- link_speed = LA_1GHZ_LINK;
+ link_speed = LPFC_LINK_SPEED_1GHZ;
break;
case LPFC_ASYNC_LINK_SPEED_10GBPS:
- link_speed = LA_10GHZ_LINK;
+ link_speed = LPFC_LINK_SPEED_10GHZ;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0483 Invalid link-attention link speed: x%x\n",
bf_get(lpfc_acqe_link_speed, acqe_link));
- link_speed = LA_UNKNW_LINK;
+ link_speed = LPFC_LINK_SPEED_UNKNOWN;
break;
}
return link_speed;
}
/**
- * lpfc_sli4_async_link_evt - Process the asynchronous link event
+ * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async link completion queue entry.
*
- * This routine is to handle the SLI4 asynchronous link event.
+ * This routine is to handle the SLI4 asynchronous FCoE link event.
**/
static void
lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
@@ -3126,11 +3139,12 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
struct lpfc_dmabuf *mp;
LPFC_MBOXQ_t *pmb;
MAILBOX_t *mb;
- READ_LA_VAR *la;
+ struct lpfc_mbx_read_top *la;
uint8_t att_type;
+ int rc;
att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
- if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
+ if (att_type != LPFC_ATT_LINK_DOWN && att_type != LPFC_ATT_LINK_UP)
return;
phba->fcoe_eventtag = acqe_link->event_tag;
pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -3161,45 +3175,168 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
/* Update link event statistics */
phba->sli.slistat.link_event++;
- /* Create pseudo lpfc_handle_latt mailbox command from link ACQE */
- lpfc_read_la(phba, pmb, mp);
+ /* Create lpfc_handle_latt mailbox command from link ACQE */
+ lpfc_read_topology(phba, pmb, mp);
+ pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
pmb->vport = phba->pport;
+ /* Keep the link status for extra SLI4 state machine reference */
+ phba->sli4_hba.link_state.speed =
+ bf_get(lpfc_acqe_link_speed, acqe_link);
+ phba->sli4_hba.link_state.duplex =
+ bf_get(lpfc_acqe_link_duplex, acqe_link);
+ phba->sli4_hba.link_state.status =
+ bf_get(lpfc_acqe_link_status, acqe_link);
+ phba->sli4_hba.link_state.type =
+ bf_get(lpfc_acqe_link_type, acqe_link);
+ phba->sli4_hba.link_state.number =
+ bf_get(lpfc_acqe_link_number, acqe_link);
+ phba->sli4_hba.link_state.fault =
+ bf_get(lpfc_acqe_link_fault, acqe_link);
+ phba->sli4_hba.link_state.logical_speed =
+ bf_get(lpfc_acqe_logical_link_speed, acqe_link);
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "2900 Async FCoE Link event - Speed:%dGBit duplex:x%x "
+ "LA Type:x%x Port Type:%d Port Number:%d Logical "
+ "speed:%dMbps Fault:%d\n",
+ phba->sli4_hba.link_state.speed,
+ phba->sli4_hba.link_state.topology,
+ phba->sli4_hba.link_state.status,
+ phba->sli4_hba.link_state.type,
+ phba->sli4_hba.link_state.number,
+ phba->sli4_hba.link_state.logical_speed * 10,
+ phba->sli4_hba.link_state.fault);
+ /*
+ * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch
+ * topology info. Note: Optional for non FC-AL ports.
+ */
+ if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED)
+ goto out_free_dmabuf;
+ return;
+ }
+ /*
+ * For FCoE Mode: fill in all the topology information we need and call
+ * the READ_TOPOLOGY completion routine to continue without actually
+ * sending the READ_TOPOLOGY mailbox command to the port.
+ */
/* Parse and translate status field */
mb = &pmb->u.mb;
mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, acqe_link);
/* Parse and translate link attention fields */
- la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA;
+ la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
la->eventTag = acqe_link->event_tag;
- la->attType = att_type;
- la->UlnkSpeed = lpfc_sli4_parse_latt_link_speed(phba, acqe_link);
+ bf_set(lpfc_mbx_read_top_att_type, la, att_type);
+ bf_set(lpfc_mbx_read_top_link_spd, la,
+ lpfc_sli4_parse_latt_link_speed(phba, acqe_link));
/* Fake the the following irrelvant fields */
- la->topology = TOPOLOGY_PT_PT;
- la->granted_AL_PA = 0;
- la->il = 0;
- la->pb = 0;
- la->fa = 0;
- la->mm = 0;
+ bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
+ bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
+ bf_set(lpfc_mbx_read_top_il, la, 0);
+ bf_set(lpfc_mbx_read_top_pb, la, 0);
+ bf_set(lpfc_mbx_read_top_fa, la, 0);
+ bf_set(lpfc_mbx_read_top_mm, la, 0);
+
+ /* Invoke the lpfc_handle_latt mailbox command callback function */
+ lpfc_mbx_cmpl_read_topology(phba, pmb);
+
+ return;
+out_free_dmabuf:
+ kfree(mp);
+out_free_pmb:
+ mempool_free(pmb, phba->mbox_mem_pool);
+}
+
+/**
+ * lpfc_sli4_async_fc_evt - Process the asynchronous FC link event
+ * @phba: pointer to lpfc hba data structure.
+ * @acqe_fc: pointer to the async fc completion queue entry.
+ *
+ * This routine is to handle the SLI4 asynchronous FC event. It will simply log
+ * that the event was received and then issue a read_topology mailbox command so
+ * that the rest of the driver will treat it the same as SLI3.
+ **/
+static void
+lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
+{
+ struct lpfc_dmabuf *mp;
+ LPFC_MBOXQ_t *pmb;
+ int rc;
+
+ if (bf_get(lpfc_trailer_type, acqe_fc) !=
+ LPFC_FC_LA_EVENT_TYPE_FC_LINK) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "2895 Non FC link Event detected.(%d)\n",
+ bf_get(lpfc_trailer_type, acqe_fc));
+ return;
+ }
/* Keep the link status for extra SLI4 state machine reference */
phba->sli4_hba.link_state.speed =
- bf_get(lpfc_acqe_link_speed, acqe_link);
- phba->sli4_hba.link_state.duplex =
- bf_get(lpfc_acqe_link_duplex, acqe_link);
+ bf_get(lpfc_acqe_fc_la_speed, acqe_fc);
+ phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL;
+ phba->sli4_hba.link_state.topology =
+ bf_get(lpfc_acqe_fc_la_topology, acqe_fc);
phba->sli4_hba.link_state.status =
- bf_get(lpfc_acqe_link_status, acqe_link);
- phba->sli4_hba.link_state.physical =
- bf_get(lpfc_acqe_link_physical, acqe_link);
+ bf_get(lpfc_acqe_fc_la_att_type, acqe_fc);
+ phba->sli4_hba.link_state.type =
+ bf_get(lpfc_acqe_fc_la_port_type, acqe_fc);
+ phba->sli4_hba.link_state.number =
+ bf_get(lpfc_acqe_fc_la_port_number, acqe_fc);
phba->sli4_hba.link_state.fault =
- bf_get(lpfc_acqe_link_fault, acqe_link);
+ bf_get(lpfc_acqe_link_fault, acqe_fc);
phba->sli4_hba.link_state.logical_speed =
- bf_get(lpfc_acqe_qos_link_speed, acqe_link);
+ bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc);
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "2896 Async FC event - Speed:%dGBaud Topology:x%x "
+ "LA Type:x%x Port Type:%d Port Number:%d Logical speed:"
+ "%dMbps Fault:%d\n",
+ phba->sli4_hba.link_state.speed,
+ phba->sli4_hba.link_state.topology,
+ phba->sli4_hba.link_state.status,
+ phba->sli4_hba.link_state.type,
+ phba->sli4_hba.link_state.number,
+ phba->sli4_hba.link_state.logical_speed * 10,
+ phba->sli4_hba.link_state.fault);
+ pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!pmb) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "2897 The mboxq allocation failed\n");
+ return;
+ }
+ mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+ if (!mp) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "2898 The lpfc_dmabuf allocation failed\n");
+ goto out_free_pmb;
+ }
+ mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
+ if (!mp->virt) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "2899 The mbuf allocation failed\n");
+ goto out_free_dmabuf;
+ }
- /* Invoke the lpfc_handle_latt mailbox command callback function */
- lpfc_mbx_cmpl_read_la(phba, pmb);
+ /* Cleanup any outstanding ELS commands */
+ lpfc_els_flush_all_cmd(phba);
+
+ /* Block ELS IOCBs until we have done process link event */
+ phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
+
+ /* Update link event statistics */
+ phba->sli.slistat.link_event++;
+
+ /* Create lpfc_handle_latt mailbox command from link ACQE */
+ lpfc_read_topology(phba, pmb, mp);
+ pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
+ pmb->vport = phba->pport;
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED)
+ goto out_free_dmabuf;
return;
out_free_dmabuf:
@@ -3209,6 +3346,24 @@ out_free_pmb:
}
/**
+ * lpfc_sli4_async_sli_evt - Process the asynchronous SLI link event
+ * @phba: pointer to lpfc hba data structure.
+ * @acqe_fc: pointer to the async SLI completion queue entry.
+ *
+ * This routine is to handle the SLI4 asynchronous SLI events.
+ **/
+static void
+lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
+{
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "2901 Async SLI event - Event Data1:x%08x Event Data2:"
+ "x%08x SLI Event Type:%d",
+ acqe_sli->event_data1, acqe_sli->event_data2,
+ bf_get(lpfc_trailer_type, acqe_sli));
+ return;
+}
+
+/**
* lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
* @vport: pointer to vport data structure.
*
@@ -3247,10 +3402,12 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
if (!ndlp)
return 0;
}
- if (phba->pport->port_state < LPFC_FLOGI)
+ if ((phba->pport->port_state < LPFC_FLOGI) &&
+ (phba->pport->port_state != LPFC_VPORT_FAILED))
return NULL;
/* If virtual link is not yet instantiated ignore CVL */
- if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC))
+ if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC)
+ && (vport->port_state != LPFC_VPORT_FAILED))
return NULL;
shost = lpfc_shost_from_vport(vport);
if (!shost)
@@ -3285,17 +3442,17 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
}
/**
- * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
+ * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async fcoe completion queue entry.
*
* This routine is to handle the SLI4 asynchronous fcoe event.
**/
static void
-lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
- struct lpfc_acqe_fcoe *acqe_fcoe)
+lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
+ struct lpfc_acqe_fip *acqe_fip)
{
- uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
+ uint8_t event_type = bf_get(lpfc_trailer_type, acqe_fip);
int rc;
struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp;
@@ -3304,25 +3461,25 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
struct lpfc_vport **vports;
int i;
- phba->fc_eventTag = acqe_fcoe->event_tag;
- phba->fcoe_eventtag = acqe_fcoe->event_tag;
+ phba->fc_eventTag = acqe_fip->event_tag;
+ phba->fcoe_eventtag = acqe_fip->event_tag;
switch (event_type) {
- case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
- case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
- if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF)
+ case LPFC_FIP_EVENT_TYPE_NEW_FCF:
+ case LPFC_FIP_EVENT_TYPE_FCF_PARAM_MOD:
+ if (event_type == LPFC_FIP_EVENT_TYPE_NEW_FCF)
lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
LOG_DISCOVERY,
"2546 New FCF event, evt_tag:x%x, "
"index:x%x\n",
- acqe_fcoe->event_tag,
- acqe_fcoe->index);
+ acqe_fip->event_tag,
+ acqe_fip->index);
else
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
LOG_DISCOVERY,
"2788 FCF param modified event, "
"evt_tag:x%x, index:x%x\n",
- acqe_fcoe->event_tag,
- acqe_fcoe->index);
+ acqe_fip->event_tag,
+ acqe_fip->index);
if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
/*
* During period of FCF discovery, read the FCF
@@ -3333,8 +3490,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
LOG_DISCOVERY,
"2779 Read FCF (x%x) for updating "
"roundrobin FCF failover bmask\n",
- acqe_fcoe->index);
- rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
+ acqe_fip->index);
+ rc = lpfc_sli4_read_fcf_rec(phba, acqe_fip->index);
}
/* If the FCF discovery is in progress, do nothing. */
@@ -3360,7 +3517,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
"2770 Start FCF table scan per async FCF "
"event, evt_tag:x%x, index:x%x\n",
- acqe_fcoe->event_tag, acqe_fcoe->index);
+ acqe_fip->event_tag, acqe_fip->index);
rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
LPFC_FCOE_FCF_GET_FIRST);
if (rc)
@@ -3369,17 +3526,17 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
"command failed (x%x)\n", rc);
break;
- case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
+ case LPFC_FIP_EVENT_TYPE_FCF_TABLE_FULL:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"2548 FCF Table full count 0x%x tag 0x%x\n",
- bf_get(lpfc_acqe_fcoe_fcf_count, acqe_fcoe),
- acqe_fcoe->event_tag);
+ bf_get(lpfc_acqe_fip_fcf_count, acqe_fip),
+ acqe_fip->event_tag);
break;
- case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
+ case LPFC_FIP_EVENT_TYPE_FCF_DEAD:
lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
"2549 FCF (x%x) disconnected from network, "
- "tag:x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
+ "tag:x%x\n", acqe_fip->index, acqe_fip->event_tag);
/*
* If we are in the middle of FCF failover process, clear
* the corresponding FCF bit in the roundrobin bitmap.
@@ -3388,13 +3545,13 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
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);
+ lpfc_sli4_fcf_rr_index_clear(phba, acqe_fip->index);
break;
}
spin_unlock_irq(&phba->hbalock);
/* If the event is not for currently used fcf do nothing */
- if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
+ if (phba->fcf.current_rec.fcf_indx != acqe_fip->index)
break;
/*
@@ -3411,7 +3568,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
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);
+ "\n", acqe_fip->event_tag, acqe_fip->index);
rc = lpfc_sli4_redisc_fcf_table(phba);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3438,12 +3595,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
lpfc_sli4_perform_all_vport_cvl(phba);
}
break;
- case LPFC_FCOE_EVENT_TYPE_CVL:
+ case LPFC_FIP_EVENT_TYPE_CVL:
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);
+ " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);
vport = lpfc_find_vport_by_vpid(phba,
- acqe_fcoe->index - phba->vpi_base);
+ acqe_fip->index - phba->vpi_base);
ndlp = lpfc_sli4_perform_vport_cvl(vport);
if (!ndlp)
break;
@@ -3494,7 +3651,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
LOG_DISCOVERY,
"2773 Start FCF failover per CVL, "
- "evt_tag:x%x\n", acqe_fcoe->event_tag);
+ "evt_tag:x%x\n", acqe_fip->event_tag);
rc = lpfc_sli4_redisc_fcf_table(phba);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3522,7 +3679,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
default:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0288 Unknown FCoE event type 0x%x event tag "
- "0x%x\n", event_type, acqe_fcoe->event_tag);
+ "0x%x\n", event_type, acqe_fip->event_tag);
break;
}
}
@@ -3599,8 +3756,7 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
&cq_event->cqe.acqe_link);
break;
case LPFC_TRAILER_CODE_FCOE:
- lpfc_sli4_async_fcoe_evt(phba,
- &cq_event->cqe.acqe_fcoe);
+ lpfc_sli4_async_fip_evt(phba, &cq_event->cqe.acqe_fip);
break;
case LPFC_TRAILER_CODE_DCBX:
lpfc_sli4_async_dcbx_evt(phba,
@@ -3610,6 +3766,12 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
lpfc_sli4_async_grp5_evt(phba,
&cq_event->cqe.acqe_grp5);
break;
+ case LPFC_TRAILER_CODE_FC:
+ lpfc_sli4_async_fc_evt(phba, &cq_event->cqe.acqe_fc);
+ break;
+ case LPFC_TRAILER_CODE_SLI:
+ lpfc_sli4_async_sli_evt(phba, &cq_event->cqe.acqe_sli);
+ break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"1804 Invalid asynchrous event code: "
@@ -3948,7 +4110,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;
+ int longs, sli_family;
/* Before proceed, wait for POST done and device ready */
rc = lpfc_sli4_post_status_check(phba);
@@ -3963,6 +4125,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
init_timer(&phba->hb_tmofunc);
phba->hb_tmofunc.function = lpfc_hb_timeout;
phba->hb_tmofunc.data = (unsigned long)phba;
+ init_timer(&phba->rrq_tmr);
+ phba->rrq_tmr.function = lpfc_rrq_timeout;
+ phba->rrq_tmr.data = (unsigned long)phba;
psli = &phba->sli;
/* MBOX heartbeat timer */
@@ -4010,12 +4175,22 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
*/
buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) +
((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)));
- /* Feature Level 1 hardware is limited to 2 pages */
- if ((bf_get(lpfc_sli_intf_featurelevel1, &phba->sli4_hba.sli_intf) ==
- LPFC_SLI_INTF_FEATURELEVEL1_1))
- max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
- else
- max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
+
+ sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
+ max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
+ switch (sli_family) {
+ case LPFC_SLI_INTF_FAMILY_BE2:
+ case LPFC_SLI_INTF_FAMILY_BE3:
+ /* There is a single hint for BE - 2 pages per BPL. */
+ if (bf_get(lpfc_sli_intf_sli_hint1, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_SLI_HINT1_1)
+ max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
+ break;
+ case LPFC_SLI_INTF_FAMILY_LNCR_A0:
+ case LPFC_SLI_INTF_FAMILY_LNCR_B0:
+ default:
+ break;
+ }
for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE;
dma_buf_size < max_buf_size && buf_size > dma_buf_size;
dma_buf_size = dma_buf_size << 1)
@@ -4070,6 +4245,14 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
if (rc)
return -ENOMEM;
+ /* IF Type 2 ports get initialized now. */
+ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_2) {
+ rc = lpfc_pci_function_reset(phba);
+ if (unlikely(rc))
+ return -ENODEV;
+ }
+
/* Create the bootstrap mailbox command */
rc = lpfc_create_bootstrap_mbox(phba);
if (unlikely(rc))
@@ -4080,19 +4263,18 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
if (unlikely(rc))
goto out_free_bsmbx;
- rc = lpfc_sli4_fw_cfg_check(phba);
- if (unlikely(rc))
- goto out_free_bsmbx;
-
/* Set up the hba's configuration parameters. */
rc = lpfc_sli4_read_config(phba);
if (unlikely(rc))
goto out_free_bsmbx;
- /* Perform a function reset */
- rc = lpfc_pci_function_reset(phba);
- if (unlikely(rc))
- goto out_free_bsmbx;
+ /* IF Type 0 ports get initialized now. */
+ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_0) {
+ rc = lpfc_pci_function_reset(phba);
+ if (unlikely(rc))
+ goto out_free_bsmbx;
+ }
mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL);
@@ -5190,97 +5372,183 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *phba)
int
lpfc_sli4_post_status_check(struct lpfc_hba *phba)
{
- struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg;
- int i, port_error = -ENODEV;
+ struct lpfc_register portsmphr_reg, uerrlo_reg, uerrhi_reg;
+ struct lpfc_register reg_data;
+ int i, port_error = 0;
+ uint32_t if_type;
- if (!phba->sli4_hba.STAregaddr)
+ if (!phba->sli4_hba.PSMPHRregaddr)
return -ENODEV;
/* Wait up to 30 seconds for the SLI Port POST done and ready */
for (i = 0; i < 3000; i++) {
- sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
- /* Encounter fatal POST error, break out */
- if (bf_get(lpfc_hst_state_perr, &sta_reg)) {
+ portsmphr_reg.word0 = readl(phba->sli4_hba.PSMPHRregaddr);
+ if (bf_get(lpfc_port_smphr_perr, &portsmphr_reg)) {
+ /* Port has a fatal POST error, break out */
port_error = -ENODEV;
break;
}
- if (LPFC_POST_STAGE_ARMFW_READY ==
- bf_get(lpfc_hst_state_port_status, &sta_reg)) {
- port_error = 0;
+ if (LPFC_POST_STAGE_PORT_READY ==
+ bf_get(lpfc_port_smphr_port_status, &portsmphr_reg))
break;
- }
msleep(10);
}
- if (port_error)
+ /*
+ * If there was a port error during POST, then don't proceed with
+ * other register reads as the data may not be valid. Just exit.
+ */
+ if (port_error) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "1408 Failure HBA POST Status: sta_reg=0x%x, "
- "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, xrom=x%x, "
- "dl=x%x, pstatus=x%x\n", sta_reg.word0,
- bf_get(lpfc_hst_state_perr, &sta_reg),
- bf_get(lpfc_hst_state_sfi, &sta_reg),
- bf_get(lpfc_hst_state_nip, &sta_reg),
- bf_get(lpfc_hst_state_ipc, &sta_reg),
- bf_get(lpfc_hst_state_xrom, &sta_reg),
- bf_get(lpfc_hst_state_dl, &sta_reg),
- bf_get(lpfc_hst_state_port_status, &sta_reg));
-
- /* Log device information */
- phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr);
- if (bf_get(lpfc_sli_intf_valid,
- &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) {
+ "1408 Port Failed POST - portsmphr=0x%x, "
+ "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, scr1=x%x, "
+ "scr2=x%x, hscratch=x%x, pstatus=x%x\n",
+ portsmphr_reg.word0,
+ bf_get(lpfc_port_smphr_perr, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_sfi, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_nip, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_ipc, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_scr1, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_scr2, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_host_scratch, &portsmphr_reg),
+ bf_get(lpfc_port_smphr_port_status, &portsmphr_reg));
+ } else {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
- "FeatureL1=0x%x, FeatureL2=0x%x\n",
+ "2534 Device Info: SLIFamily=0x%x, "
+ "SLIRev=0x%x, IFType=0x%x, SLIHint_1=0x%x, "
+ "SLIHint_2=0x%x, FT=0x%x\n",
bf_get(lpfc_sli_intf_sli_family,
&phba->sli4_hba.sli_intf),
bf_get(lpfc_sli_intf_slirev,
&phba->sli4_hba.sli_intf),
- bf_get(lpfc_sli_intf_featurelevel1,
+ bf_get(lpfc_sli_intf_if_type,
+ &phba->sli4_hba.sli_intf),
+ bf_get(lpfc_sli_intf_sli_hint1,
&phba->sli4_hba.sli_intf),
- bf_get(lpfc_sli_intf_featurelevel2,
+ bf_get(lpfc_sli_intf_sli_hint2,
+ &phba->sli4_hba.sli_intf),
+ bf_get(lpfc_sli_intf_func_type,
&phba->sli4_hba.sli_intf));
+ /*
+ * Check for other Port errors during the initialization
+ * process. Fail the load if the port did not come up
+ * correctly.
+ */
+ if_type = bf_get(lpfc_sli_intf_if_type,
+ &phba->sli4_hba.sli_intf);
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ phba->sli4_hba.ue_mask_lo =
+ readl(phba->sli4_hba.u.if_type0.UEMASKLOregaddr);
+ phba->sli4_hba.ue_mask_hi =
+ readl(phba->sli4_hba.u.if_type0.UEMASKHIregaddr);
+ uerrlo_reg.word0 =
+ readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
+ uerrhi_reg.word0 =
+ readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
+ if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
+ (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "1422 Unrecoverable Error "
+ "Detected during POST "
+ "uerr_lo_reg=0x%x, "
+ "uerr_hi_reg=0x%x, "
+ "ue_mask_lo_reg=0x%x, "
+ "ue_mask_hi_reg=0x%x\n",
+ uerrlo_reg.word0,
+ uerrhi_reg.word0,
+ phba->sli4_hba.ue_mask_lo,
+ phba->sli4_hba.ue_mask_hi);
+ port_error = -ENODEV;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ /* Final checks. The port status should be clean. */
+ reg_data.word0 =
+ readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+ if (bf_get(lpfc_sliport_status_err, &reg_data)) {
+ phba->work_status[0] =
+ readl(phba->sli4_hba.u.if_type2.
+ ERR1regaddr);
+ phba->work_status[1] =
+ readl(phba->sli4_hba.u.if_type2.
+ ERR2regaddr);
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2888 Port Error Detected "
+ "during POST: "
+ "port status reg 0x%x, "
+ "port_smphr reg 0x%x, "
+ "error 1=0x%x, error 2=0x%x\n",
+ reg_data.word0,
+ portsmphr_reg.word0,
+ phba->work_status[0],
+ phba->work_status[1]);
+ port_error = -ENODEV;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
+ break;
+ }
}
- phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
- phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
- /* With uncoverable error, log the error message and return error */
- uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
- uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
- if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
- (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "1422 HBA Unrecoverable error: "
- "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
- "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
- uerrlo_reg.word0, uerrhi_reg.word0,
- phba->sli4_hba.ue_mask_lo,
- phba->sli4_hba.ue_mask_hi);
- return -ENODEV;
- }
-
return port_error;
}
/**
* lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map.
* @phba: pointer to lpfc hba data structure.
+ * @if_type: The SLI4 interface type getting configured.
*
* This routine is invoked to set up SLI4 BAR0 PCI config space register
* memory map.
**/
static void
-lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba)
-{
- phba->sli4_hba.UERRLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
- LPFC_UERR_STATUS_LO;
- phba->sli4_hba.UERRHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
- LPFC_UERR_STATUS_HI;
- phba->sli4_hba.UEMASKLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
- LPFC_UE_MASK_LO;
- phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
- LPFC_UE_MASK_HI;
- phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p +
- LPFC_SLI_INTF;
+lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
+{
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ phba->sli4_hba.u.if_type0.UERRLOregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_LO;
+ phba->sli4_hba.u.if_type0.UERRHIregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_HI;
+ phba->sli4_hba.u.if_type0.UEMASKLOregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_LO;
+ phba->sli4_hba.u.if_type0.UEMASKHIregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_HI;
+ phba->sli4_hba.SLIINTFregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ phba->sli4_hba.u.if_type2.ERR1regaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_1;
+ phba->sli4_hba.u.if_type2.ERR2regaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_2;
+ phba->sli4_hba.u.if_type2.CTRLregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_CNTRL;
+ phba->sli4_hba.u.if_type2.STATUSregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_STATUS;
+ phba->sli4_hba.SLIINTFregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
+ phba->sli4_hba.PSMPHRregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_IF2_SMPHR;
+ phba->sli4_hba.RQDBregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL;
+ phba->sli4_hba.WQDBregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_WQ_DOORBELL;
+ phba->sli4_hba.EQCQDBregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+ phba->sli4_hba.MQDBregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
+ phba->sli4_hba.BMBXregaddr =
+ phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
+ dev_printk(KERN_ERR, &phba->pcidev->dev,
+ "FATAL - unsupported SLI4 interface type - %d\n",
+ if_type);
+ break;
+ }
}
/**
@@ -5293,16 +5561,14 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba)
static void
lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba)
{
-
- phba->sli4_hba.STAregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
- LPFC_HST_STATE;
+ phba->sli4_hba.PSMPHRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
+ LPFC_SLIPORT_IF0_SMPHR;
phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
- LPFC_HST_ISR0;
+ LPFC_HST_ISR0;
phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
- LPFC_HST_IMR0;
+ LPFC_HST_IMR0;
phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
- LPFC_HST_ISCR0;
- return;
+ LPFC_HST_ISCR0;
}
/**
@@ -5542,11 +5808,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
}
/**
- * lpfc_dev_endian_order_setup - Notify the port of the host's endian order.
+ * lpfc_setup_endian_order - Write endian order to an SLI4 if_type 0 port.
* @phba: pointer to lpfc hba data structure.
*
- * This routine is invoked to setup the host-side endian order to the
- * HBA consistent with the SLI-4 interface spec.
+ * This routine is invoked to setup the port-side endian order when
+ * the port if_type is 0. This routine has no function for other
+ * if_types.
*
* Return codes
* 0 - successful
@@ -5557,34 +5824,44 @@ static int
lpfc_setup_endian_order(struct lpfc_hba *phba)
{
LPFC_MBOXQ_t *mboxq;
- uint32_t rc = 0;
+ uint32_t if_type, rc = 0;
uint32_t endian_mb_data[2] = {HOST_ENDIAN_LOW_WORD0,
HOST_ENDIAN_HIGH_WORD1};
- mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mboxq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0492 Unable to allocate memory for issuing "
- "SLI_CONFIG_SPECIAL mailbox command\n");
- return -ENOMEM;
- }
+ if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+ GFP_KERNEL);
+ if (!mboxq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0492 Unable to allocate memory for "
+ "issuing SLI_CONFIG_SPECIAL mailbox "
+ "command\n");
+ return -ENOMEM;
+ }
- /*
- * The SLI4_CONFIG_SPECIAL mailbox command requires the first two
- * words to contain special data values and no other data.
- */
- memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
- memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data));
- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
- if (rc != MBX_SUCCESS) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0493 SLI_CONFIG_SPECIAL mailbox failed with "
- "status x%x\n",
- rc);
- rc = -EIO;
+ /*
+ * The SLI4_CONFIG_SPECIAL mailbox command requires the first
+ * two words to contain special data values and no other data.
+ */
+ memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
+ memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data));
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+ if (rc != MBX_SUCCESS) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0493 SLI_CONFIG_SPECIAL mailbox "
+ "failed with status x%x\n",
+ rc);
+ rc = -EIO;
+ }
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
+ break;
}
-
- mempool_free(mboxq, phba->mbox_mem_pool);
return rc;
}
@@ -6416,36 +6693,124 @@ int
lpfc_pci_function_reset(struct lpfc_hba *phba)
{
LPFC_MBOXQ_t *mboxq;
- uint32_t rc = 0;
+ uint32_t rc = 0, if_type;
uint32_t shdr_status, shdr_add_status;
+ uint32_t rdy_chk, num_resets = 0, reset_again = 0;
union lpfc_sli4_cfg_shdr *shdr;
+ struct lpfc_register reg_data;
- mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mboxq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0494 Unable to allocate memory for issuing "
- "SLI_FUNCTION_RESET mailbox command\n");
- return -ENOMEM;
- }
+ if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+ GFP_KERNEL);
+ if (!mboxq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0494 Unable to allocate memory for "
+ "issuing SLI_FUNCTION_RESET mailbox "
+ "command\n");
+ return -ENOMEM;
+ }
- /* Set up PCI function reset SLI4_CONFIG mailbox-ioctl command */
- lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
- LPFC_MBOX_OPCODE_FUNCTION_RESET, 0,
- LPFC_SLI4_MBX_EMBED);
- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
- shdr = (union lpfc_sli4_cfg_shdr *)
- &mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
- shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
- shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
- if (rc != MBX_TIMEOUT)
- mempool_free(mboxq, phba->mbox_mem_pool);
- if (shdr_status || shdr_add_status || rc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0495 SLI_FUNCTION_RESET mailbox failed with "
- "status x%x add_status x%x, mbx status x%x\n",
- shdr_status, shdr_add_status, rc);
- rc = -ENXIO;
+ /* Setup PCI function reset mailbox-ioctl command */
+ lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+ LPFC_MBOX_OPCODE_FUNCTION_RESET, 0,
+ LPFC_SLI4_MBX_EMBED);
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+ shdr = (union lpfc_sli4_cfg_shdr *)
+ &mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+ &shdr->response);
+ if (rc != MBX_TIMEOUT)
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0495 SLI_FUNCTION_RESET mailbox "
+ "failed with status x%x add_status x%x,"
+ " mbx status x%x\n",
+ shdr_status, shdr_add_status, rc);
+ rc = -ENXIO;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ for (num_resets = 0;
+ num_resets < MAX_IF_TYPE_2_RESETS;
+ num_resets++) {
+ reg_data.word0 = 0;
+ bf_set(lpfc_sliport_ctrl_end, &reg_data,
+ LPFC_SLIPORT_LITTLE_ENDIAN);
+ bf_set(lpfc_sliport_ctrl_ip, &reg_data,
+ LPFC_SLIPORT_INIT_PORT);
+ writel(reg_data.word0, phba->sli4_hba.u.if_type2.
+ CTRLregaddr);
+
+ /*
+ * Poll the Port Status Register and wait for RDY for
+ * up to 10 seconds. If the port doesn't respond, treat
+ * it as an error. If the port responds with RN, start
+ * the loop again.
+ */
+ for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) {
+ reg_data.word0 =
+ readl(phba->sli4_hba.u.if_type2.
+ STATUSregaddr);
+ if (bf_get(lpfc_sliport_status_rdy, &reg_data))
+ break;
+ if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
+ reset_again++;
+ break;
+ }
+ msleep(10);
+ }
+
+ /*
+ * If the port responds to the init request with
+ * reset needed, delay for a bit and restart the loop.
+ */
+ if (reset_again) {
+ msleep(10);
+ reset_again = 0;
+ continue;
+ }
+
+ /* Detect any port errors. */
+ reg_data.word0 = readl(phba->sli4_hba.u.if_type2.
+ STATUSregaddr);
+ if ((bf_get(lpfc_sliport_status_err, &reg_data)) ||
+ (rdy_chk >= 1000)) {
+ phba->work_status[0] = readl(
+ phba->sli4_hba.u.if_type2.ERR1regaddr);
+ phba->work_status[1] = readl(
+ phba->sli4_hba.u.if_type2.ERR2regaddr);
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2890 Port Error Detected "
+ "during Port Reset: "
+ "port status reg 0x%x, "
+ "error 1=0x%x, error 2=0x%x\n",
+ reg_data.word0,
+ phba->work_status[0],
+ phba->work_status[1]);
+ rc = -ENODEV;
+ }
+
+ /*
+ * Terminate the outer loop provided the Port indicated
+ * ready within 10 seconds.
+ */
+ if (rdy_chk < 1000)
+ break;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
+ break;
}
+
+ /* Catch the not-ready port failure after a port reset. */
+ if (num_resets >= MAX_IF_TYPE_2_RESETS)
+ rc = -ENODEV;
+
return rc;
}
@@ -6536,6 +6901,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
struct pci_dev *pdev;
unsigned long bar0map_len, bar1map_len, bar2map_len;
int error = -ENODEV;
+ uint32_t if_type;
/* Obtain PCI device reference */
if (!phba->pcidev)
@@ -6552,61 +6918,105 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
}
}
- /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the
- * number of bytes required by each mapping. They are actually
- * mapping to the PCI BAR regions 0 or 1, 2, and 4 by the SLI4 device.
+ /*
+ * The BARs and register set definitions and offset locations are
+ * dependent on the if_type.
+ */
+ if (pci_read_config_dword(pdev, LPFC_SLI_INTF,
+ &phba->sli4_hba.sli_intf.word0)) {
+ return error;
+ }
+
+ /* There is no SLI3 failback for SLI4 devices. */
+ if (bf_get(lpfc_sli_intf_valid, &phba->sli4_hba.sli_intf) !=
+ LPFC_SLI_INTF_VALID) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2894 SLI_INTF reg contents invalid "
+ "sli_intf reg 0x%x\n",
+ phba->sli4_hba.sli_intf.word0);
+ return error;
+ }
+
+ if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+ /*
+ * Get the bus address of SLI4 device Bar regions and the
+ * number of bytes required by each mapping. The mapping of the
+ * particular PCI BARs regions is dependent on the type of
+ * SLI4 device.
*/
if (pci_resource_start(pdev, 0)) {
phba->pci_bar0_map = pci_resource_start(pdev, 0);
bar0map_len = pci_resource_len(pdev, 0);
+
+ /*
+ * Map SLI4 PCI Config Space Register base to a kernel virtual
+ * addr
+ */
+ phba->sli4_hba.conf_regs_memmap_p =
+ ioremap(phba->pci_bar0_map, bar0map_len);
+ if (!phba->sli4_hba.conf_regs_memmap_p) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "ioremap failed for SLI4 PCI config "
+ "registers.\n");
+ goto out;
+ }
+ /* Set up BAR0 PCI config space register memory map */
+ lpfc_sli4_bar0_register_memmap(phba, if_type);
} else {
phba->pci_bar0_map = pci_resource_start(pdev, 1);
bar0map_len = pci_resource_len(pdev, 1);
- }
- phba->pci_bar1_map = pci_resource_start(pdev, 2);
- bar1map_len = pci_resource_len(pdev, 2);
-
- phba->pci_bar2_map = pci_resource_start(pdev, 4);
- bar2map_len = pci_resource_len(pdev, 4);
-
- /* Map SLI4 PCI Config Space Register base to a kernel virtual addr */
- phba->sli4_hba.conf_regs_memmap_p =
+ if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "FATAL - No BAR0 mapping for SLI4, if_type 2\n");
+ goto out;
+ }
+ phba->sli4_hba.conf_regs_memmap_p =
ioremap(phba->pci_bar0_map, bar0map_len);
- if (!phba->sli4_hba.conf_regs_memmap_p) {
- dev_printk(KERN_ERR, &pdev->dev,
- "ioremap failed for SLI4 PCI config registers.\n");
- goto out;
+ if (!phba->sli4_hba.conf_regs_memmap_p) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "ioremap failed for SLI4 PCI config "
+ "registers.\n");
+ goto out;
+ }
+ lpfc_sli4_bar0_register_memmap(phba, if_type);
}
- /* Map SLI4 HBA Control Register base to a kernel virtual address. */
- phba->sli4_hba.ctrl_regs_memmap_p =
+ if (pci_resource_start(pdev, 2)) {
+ /*
+ * Map SLI4 if type 0 HBA Control Register base to a kernel
+ * virtual address and setup the registers.
+ */
+ phba->pci_bar1_map = pci_resource_start(pdev, 2);
+ bar1map_len = pci_resource_len(pdev, 2);
+ phba->sli4_hba.ctrl_regs_memmap_p =
ioremap(phba->pci_bar1_map, bar1map_len);
- if (!phba->sli4_hba.ctrl_regs_memmap_p) {
- dev_printk(KERN_ERR, &pdev->dev,
+ if (!phba->sli4_hba.ctrl_regs_memmap_p) {
+ dev_printk(KERN_ERR, &pdev->dev,
"ioremap failed for SLI4 HBA control registers.\n");
- goto out_iounmap_conf;
+ goto out_iounmap_conf;
+ }
+ lpfc_sli4_bar1_register_memmap(phba);
}
- /* Map SLI4 HBA Doorbell Register base to a kernel virtual address. */
- phba->sli4_hba.drbl_regs_memmap_p =
+ if (pci_resource_start(pdev, 4)) {
+ /*
+ * Map SLI4 if type 0 HBA Doorbell Register base to a kernel
+ * virtual address and setup the registers.
+ */
+ phba->pci_bar2_map = pci_resource_start(pdev, 4);
+ bar2map_len = pci_resource_len(pdev, 4);
+ phba->sli4_hba.drbl_regs_memmap_p =
ioremap(phba->pci_bar2_map, bar2map_len);
- if (!phba->sli4_hba.drbl_regs_memmap_p) {
- dev_printk(KERN_ERR, &pdev->dev,
+ if (!phba->sli4_hba.drbl_regs_memmap_p) {
+ dev_printk(KERN_ERR, &pdev->dev,
"ioremap failed for SLI4 HBA doorbell registers.\n");
- goto out_iounmap_ctrl;
+ goto out_iounmap_ctrl;
+ }
+ error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
+ if (error)
+ goto out_iounmap_all;
}
- /* Set up BAR0 PCI config space register memory map */
- lpfc_sli4_bar0_register_memmap(phba);
-
- /* Set up BAR1 register memory map */
- lpfc_sli4_bar1_register_memmap(phba);
-
- /* Set up BAR2 register memory map */
- error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
- if (error)
- goto out_iounmap_all;
-
return 0;
out_iounmap_all:
@@ -8149,6 +8559,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
goto out_unset_driver_resource_s4;
}
+ INIT_LIST_HEAD(&phba->active_rrq_list);
+
/* Set up common device driver resources */
error = lpfc_setup_driver_resource_phase2(phba);
if (error) {
@@ -8218,7 +8630,11 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
"0451 Configure interrupt mode (%d) "
"failed active interrupt test.\n",
intr_mode);
- /* Unset the preivous SLI-4 HBA setup */
+ /* Unset the previous SLI-4 HBA setup. */
+ /*
+ * TODO: Is this operation compatible with IF TYPE 2
+ * devices? All port state is deleted and cleared.
+ */
lpfc_sli4_unset_hba(phba);
/* Try next level of interrupt mode */
cfg_mode = --intr_mode;
@@ -8990,6 +9406,10 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BALIUS,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FC,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE,
+ PCI_ANY_ID, PCI_ANY_ID, },
{ 0 }
};
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index bb59e9273126..e3b790e59156 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -33,7 +33,7 @@
#define LOG_FCP_ERROR 0x00001000 /* log errors, not underruns */
#define LOG_LIBDFC 0x00002000 /* Libdfc events */
#define LOG_VPORT 0x00004000 /* NPIV events */
-#define LOF_SECURITY 0x00008000 /* Security events */
+#define LOG_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 */
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 62d0957e1d4c..23403c650207 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -263,18 +263,19 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
}
/**
- * lpfc_read_la - Prepare a mailbox command for reading HBA link attention
+ * lpfc_read_topology - Prepare a mailbox command for reading HBA topology
* @phba: pointer to lpfc hba data structure.
* @pmb: pointer to the driver internal queue element for mailbox command.
* @mp: DMA buffer memory for reading the link attention information into.
*
- * The read link attention mailbox command is issued to read the Link Event
- * Attention information indicated by the HBA port when the Link Event bit
- * of the Host Attention (HSTATT) register is set to 1. A Link Event
+ * The read topology mailbox command is issued to read the link topology
+ * information indicated by the HBA port when the Link Event bit of the Host
+ * Attention (HSTATT) register is set to 1 (For SLI-3) or when an FC Link
+ * Attention ACQE is received from the port (For SLI-4). A Link Event
* Attention occurs based on an exception detected at the Fibre Channel link
* interface.
*
- * This routine prepares the mailbox command for reading HBA link attention
+ * This routine prepares the mailbox command for reading HBA link topology
* information. A DMA memory has been set aside and address passed to the
* HBA through @mp for the HBA to DMA link attention information into the
* memory as part of the execution of the mailbox command.
@@ -283,7 +284,8 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
* 0 - Success (currently always return 0)
**/
int
-lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
+lpfc_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
+ struct lpfc_dmabuf *mp)
{
MAILBOX_t *mb;
struct lpfc_sli *psli;
@@ -293,15 +295,15 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
INIT_LIST_HEAD(&mp->list);
- mb->mbxCommand = MBX_READ_LA64;
- mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
- mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
- mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
+ mb->mbxCommand = MBX_READ_TOPOLOGY;
+ mb->un.varReadTop.lilpBde64.tus.f.bdeSize = LPFC_ALPA_MAP_SIZE;
+ mb->un.varReadTop.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
+ mb->un.varReadTop.lilpBde64.addrLow = putPaddrLow(mp->phys);
/* Save address for later completion and set the owner to host so that
* the FW knows this mailbox is available for processing.
*/
- pmb->context1 = (uint8_t *) mp;
+ pmb->context1 = (uint8_t *)mp;
mb->mbxOwner = OWN_HOST;
return (0);
}
@@ -516,18 +518,33 @@ lpfc_init_link(struct lpfc_hba * phba,
vpd = &phba->vpd;
if (vpd->rev.feaLevelHigh >= 0x02){
switch(linkspeed){
- case LINK_SPEED_1G:
- case LINK_SPEED_2G:
- case LINK_SPEED_4G:
- case LINK_SPEED_8G:
- mb->un.varInitLnk.link_flags |=
- FLAGS_LINK_SPEED;
- mb->un.varInitLnk.link_speed = linkspeed;
+ case LPFC_USER_LINK_SPEED_1G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_1G;
+ break;
+ case LPFC_USER_LINK_SPEED_2G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_2G;
+ break;
+ case LPFC_USER_LINK_SPEED_4G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_4G;
+ break;
+ case LPFC_USER_LINK_SPEED_8G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_8G;
+ break;
+ case LPFC_USER_LINK_SPEED_10G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_10G;
break;
- case LINK_SPEED_AUTO:
- default:
- mb->un.varInitLnk.link_speed =
- LINK_SPEED_AUTO;
+ case LPFC_USER_LINK_SPEED_16G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_16G;
+ break;
+ case LPFC_USER_LINK_SPEED_AUTO:
+ default:
+ mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
break;
}
@@ -693,7 +710,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
* @did: remote port identifier.
* @param: pointer to memory holding the server parameters.
* @pmb: pointer to the driver internal queue element for mailbox command.
- * @flag: action flag to be passed back for the complete function.
+ * @rpi: the rpi to use in the registration (usually only used for SLI4.
*
* The registration login mailbox command is used to register an N_Port or
* F_Port login. This registration allows the HBA to cache the remote N_Port
@@ -712,7 +729,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
**/
int
lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
- uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
+ uint8_t *param, LPFC_MBOXQ_t *pmb, uint16_t rpi)
{
MAILBOX_t *mb = &pmb->u.mb;
uint8_t *sparam;
@@ -722,17 +739,13 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
mb->un.varRegLogin.rpi = 0;
if (phba->sli_rev == LPFC_SLI_REV4) {
- mb->un.varRegLogin.rpi = lpfc_sli4_alloc_rpi(phba);
+ mb->un.varRegLogin.rpi = rpi;
if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
return 1;
}
-
mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
mb->un.varRegLogin.did = did;
- mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */
-
mb->mbxOwner = OWN_HOST;
-
/* Get a buffer to hold NPorts Service Parameters */
mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
if (mp)
@@ -743,7 +756,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
/* REG_LOGIN: no buffers */
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
"0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
- "flag x%x\n", vpi, did, flag);
+ "rpi x%x\n", vpi, did, rpi);
return (1);
}
INIT_LIST_HEAD(&mp->list);
@@ -1918,11 +1931,14 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
struct lpfc_mbx_init_vfi *init_vfi;
memset(mbox, 0, sizeof(*mbox));
+ mbox->vport = vport;
init_vfi = &mbox->u.mqe.un.init_vfi;
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VFI);
bf_set(lpfc_init_vfi_vr, init_vfi, 1);
bf_set(lpfc_init_vfi_vt, init_vfi, 1);
+ bf_set(lpfc_init_vfi_vp, init_vfi, 1);
bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
+ bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base);
bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
}
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 8f879e477e9d..cbb48ee8b0bb 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -113,11 +113,16 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
goto fail_free_mbox_pool;
if (phba->sli_rev == LPFC_SLI_REV4) {
+ phba->rrq_pool =
+ mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
+ sizeof(struct lpfc_node_rrq));
+ if (!phba->rrq_pool)
+ goto fail_free_nlp_mem_pool;
phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
phba->pcidev,
LPFC_HDR_BUF_SIZE, align, 0);
if (!phba->lpfc_hrb_pool)
- goto fail_free_nlp_mem_pool;
+ goto fail_free_rrq_mem_pool;
phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
phba->pcidev,
@@ -147,6 +152,9 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
fail_free_hrb_pool:
pci_pool_destroy(phba->lpfc_hrb_pool);
phba->lpfc_hrb_pool = NULL;
+ fail_free_rrq_mem_pool:
+ mempool_destroy(phba->rrq_pool);
+ phba->rrq_pool = NULL;
fail_free_nlp_mem_pool:
mempool_destroy(phba->nlp_mem_pool);
phba->nlp_mem_pool = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index bccc9c66fa37..d85a7423a694 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -386,7 +386,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
goto out;
rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
- (uint8_t *) sp, mbox, 0);
+ (uint8_t *) sp, mbox, ndlp->nlp_rpi);
if (rc) {
mempool_free(mbox, phba->mbox_mem_pool);
goto out;
@@ -632,7 +632,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- if (!(ndlp->nlp_flag & NLP_RPI_VALID)) {
+ if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
return 0;
}
@@ -968,7 +968,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
lpfc_unreg_rpi(vport, ndlp);
if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
- (uint8_t *) sp, mbox, 0) == 0) {
+ (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
switch (ndlp->nlp_DID) {
case NameServer_DID:
mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
@@ -1338,12 +1338,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
(ndlp == (struct lpfc_nodelist *) mb->context2)) {
- if (phba->sli_rev == LPFC_SLI_REV4) {
- spin_unlock_irq(&phba->hbalock);
- lpfc_sli4_free_rpi(phba,
- mb->u.mb.un.varRegLogin.rpi);
- spin_lock_irq(&phba->hbalock);
- }
mp = (struct lpfc_dmabuf *) (mb->context1);
if (mp) {
__lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -1426,7 +1420,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
}
ndlp->nlp_rpi = mb->un.varWords[0];
- ndlp->nlp_flag |= NLP_RPI_VALID;
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
/* Only if we are not a fabric nport do we issue PRLI */
if (!(ndlp->nlp_type & NLP_FABRIC)) {
@@ -2027,7 +2021,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
if (!mb->mbxStatus) {
ndlp->nlp_rpi = mb->un.varWords[0];
- ndlp->nlp_flag |= NLP_RPI_VALID;
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
} else {
if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
lpfc_drop_node(vport, ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 581837b3c71a..c97751c95d77 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -621,10 +621,13 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
struct sli4_wcqe_xri_aborted *axri)
{
uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
+ uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
struct lpfc_scsi_buf *psb, *next_psb;
unsigned long iflag = 0;
struct lpfc_iocbq *iocbq;
int i;
+ struct lpfc_nodelist *ndlp;
+ int rrq_empty = 0;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
spin_lock_irqsave(&phba->hbalock, iflag);
@@ -637,8 +640,14 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
psb->status = IOSTAT_SUCCESS;
spin_unlock(
&phba->sli4_hba.abts_scsi_buf_list_lock);
+ ndlp = psb->rdata->pnode;
+ rrq_empty = list_empty(&phba->active_rrq_list);
spin_unlock_irqrestore(&phba->hbalock, iflag);
+ if (ndlp)
+ lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
lpfc_release_scsi_buf_s4(phba, psb);
+ if (rrq_empty)
+ lpfc_worker_wake_up(phba);
return;
}
}
@@ -914,7 +923,7 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
}
/**
- * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * lpfc_get_scsi_buf_s3 - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
* @phba: The HBA for which this call is being executed.
*
* This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
@@ -925,7 +934,7 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
* Pointer to lpfc_scsi_buf - Success
**/
static struct lpfc_scsi_buf*
-lpfc_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
{
struct lpfc_scsi_buf * lpfc_cmd = NULL;
struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
@@ -941,6 +950,67 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
return lpfc_cmd;
}
+/**
+ * lpfc_get_scsi_buf_s4 - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * @phba: The HBA for which this call is being executed.
+ *
+ * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
+ * and returns to caller.
+ *
+ * Return codes:
+ * NULL - Error
+ * Pointer to lpfc_scsi_buf - Success
+ **/
+static struct lpfc_scsi_buf*
+lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+{
+ struct lpfc_scsi_buf *lpfc_cmd = NULL;
+ struct lpfc_scsi_buf *start_lpfc_cmd = NULL;
+ struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+ unsigned long iflag = 0;
+ int found = 0;
+
+ spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
+ list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+ spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
+ while (!found && lpfc_cmd) {
+ if (lpfc_test_rrq_active(phba, ndlp,
+ lpfc_cmd->cur_iocbq.sli4_xritag)) {
+ lpfc_release_scsi_buf_s4(phba, lpfc_cmd);
+ spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
+ list_remove_head(scsi_buf_list, lpfc_cmd,
+ struct lpfc_scsi_buf, list);
+ spin_unlock_irqrestore(&phba->scsi_buf_list_lock,
+ iflag);
+ if (lpfc_cmd == start_lpfc_cmd) {
+ lpfc_cmd = NULL;
+ break;
+ } else
+ continue;
+ }
+ found = 1;
+ lpfc_cmd->seg_cnt = 0;
+ lpfc_cmd->nonsg_phys = 0;
+ lpfc_cmd->prot_seg_cnt = 0;
+ }
+ return lpfc_cmd;
+}
+/**
+ * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * @phba: The HBA for which this call is being executed.
+ *
+ * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
+ * and returns to caller.
+ *
+ * Return codes:
+ * NULL - Error
+ * Pointer to lpfc_scsi_buf - Success
+ **/
+static struct lpfc_scsi_buf*
+lpfc_get_scsi_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+{
+ return phba->lpfc_get_scsi_buf(phba, ndlp);
+}
/**
* lpfc_release_scsi_buf - Return a scsi buffer back to hba scsi buf list
@@ -2744,18 +2814,19 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf;
phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd;
- phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
switch (dev_grp) {
case LPFC_PCI_DEV_LP:
phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3;
phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3;
phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3;
+ phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3;
break;
case LPFC_PCI_DEV_OC:
phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4;
phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4;
phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4;
+ phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -2764,7 +2835,6 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
return -ENODEV;
break;
}
- phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
phba->lpfc_rampdown_queue_depth = lpfc_rampdown_queue_depth;
phba->lpfc_scsi_cmd_iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
return 0;
@@ -2940,7 +3010,7 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
goto out_host_busy;
- lpfc_cmd = lpfc_get_scsi_buf(phba);
+ lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp);
if (lpfc_cmd == NULL) {
lpfc_rampdown_queue_depth(phba);
@@ -3239,7 +3309,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
return FAILED;
- lpfc_cmd = lpfc_get_scsi_buf(phba);
+ lpfc_cmd = lpfc_get_scsi_buf(phba, rdata->pnode);
if (lpfc_cmd == NULL)
return FAILED;
lpfc_cmd->timeout = 60;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 554efa6623f4..634b2fea9c4d 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -513,8 +513,344 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
}
/**
+ * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: nodelist pointer for this target.
+ * @xritag: xri used in this exchange.
+ * @rxid: Remote Exchange ID.
+ * @send_rrq: Flag used to determine if we should send rrq els cmd.
+ *
+ * This function is called with hbalock held.
+ * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an
+ * rrq struct and adds it to the active_rrq_list.
+ *
+ * returns 0 for rrq slot for this xri
+ * < 0 Were not able to get rrq mem or invalid parameter.
+ **/
+static int
+__lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+ uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
+{
+ uint16_t adj_xri;
+ struct lpfc_node_rrq *rrq;
+ int empty;
+
+ /*
+ * set the active bit even if there is no mem available.
+ */
+ adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+ if (!ndlp)
+ return -EINVAL;
+ if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+ return -EINVAL;
+ rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
+ if (rrq) {
+ rrq->send_rrq = send_rrq;
+ rrq->xritag = xritag;
+ rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
+ rrq->ndlp = ndlp;
+ rrq->nlp_DID = ndlp->nlp_DID;
+ rrq->vport = ndlp->vport;
+ rrq->rxid = rxid;
+ empty = list_empty(&phba->active_rrq_list);
+ if (phba->cfg_enable_rrq && send_rrq)
+ /*
+ * We need the xri before we can add this to the
+ * phba active rrq list.
+ */
+ rrq->send_rrq = send_rrq;
+ else
+ rrq->send_rrq = 0;
+ list_add_tail(&rrq->list, &phba->active_rrq_list);
+ if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) {
+ phba->hba_flag |= HBA_RRQ_ACTIVE;
+ if (empty)
+ lpfc_worker_wake_up(phba);
+ }
+ return 0;
+ }
+ return -ENOMEM;
+}
+
+/**
+ * __lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @xritag: xri used in this exchange.
+ * @rrq: The RRQ to be cleared.
+ *
+ * This function is called with hbalock held. This function
+ **/
+static void
+__lpfc_clr_rrq_active(struct lpfc_hba *phba,
+ uint16_t xritag,
+ struct lpfc_node_rrq *rrq)
+{
+ uint16_t adj_xri;
+ struct lpfc_nodelist *ndlp;
+
+ ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID);
+
+ /* The target DID could have been swapped (cable swap)
+ * we should use the ndlp from the findnode if it is
+ * available.
+ */
+ if (!ndlp)
+ ndlp = rrq->ndlp;
+
+ adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+ if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) {
+ rrq->send_rrq = 0;
+ rrq->xritag = 0;
+ rrq->rrq_stop_time = 0;
+ }
+ mempool_free(rrq, phba->rrq_pool);
+}
+
+/**
+ * lpfc_handle_rrq_active - Checks if RRQ has waithed RATOV.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with hbalock held. This function
+ * Checks if stop_time (ratov from setting rrq active) has
+ * been reached, if it has and the send_rrq flag is set then
+ * it will call lpfc_send_rrq. If the send_rrq flag is not set
+ * then it will just call the routine to clear the rrq and
+ * free the rrq resource.
+ * The timer is set to the next rrq that is going to expire before
+ * leaving the routine.
+ *
+ **/
+void
+lpfc_handle_rrq_active(struct lpfc_hba *phba)
+{
+ struct lpfc_node_rrq *rrq;
+ struct lpfc_node_rrq *nextrrq;
+ unsigned long next_time;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ phba->hba_flag &= ~HBA_RRQ_ACTIVE;
+ next_time = jiffies + HZ * (phba->fc_ratov + 1);
+ list_for_each_entry_safe(rrq, nextrrq,
+ &phba->active_rrq_list, list) {
+ if (time_after(jiffies, rrq->rrq_stop_time)) {
+ list_del(&rrq->list);
+ if (!rrq->send_rrq)
+ /* this call will free the rrq */
+ __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+ else {
+ /* if we send the rrq then the completion handler
+ * will clear the bit in the xribitmap.
+ */
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ if (lpfc_send_rrq(phba, rrq)) {
+ lpfc_clr_rrq_active(phba, rrq->xritag,
+ rrq);
+ }
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ }
+ } else if (time_before(rrq->rrq_stop_time, next_time))
+ next_time = rrq->rrq_stop_time;
+ }
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ if (!list_empty(&phba->active_rrq_list))
+ mod_timer(&phba->rrq_tmr, next_time);
+}
+
+/**
+ * lpfc_get_active_rrq - Get the active RRQ for this exchange.
+ * @vport: Pointer to vport context object.
+ * @xri: The xri used in the exchange.
+ * @did: The targets DID for this exchange.
+ *
+ * returns NULL = rrq not found in the phba->active_rrq_list.
+ * rrq = rrq for this xri and target.
+ **/
+struct lpfc_node_rrq *
+lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did)
+{
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_node_rrq *rrq;
+ struct lpfc_node_rrq *nextrrq;
+ unsigned long iflags;
+
+ if (phba->sli_rev != LPFC_SLI_REV4)
+ return NULL;
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+ if (rrq->vport == vport && rrq->xritag == xri &&
+ rrq->nlp_DID == did){
+ list_del(&rrq->list);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ return rrq;
+ }
+ }
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ return NULL;
+}
+
+/**
+ * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport.
+ * @vport: Pointer to vport context object.
+ *
+ * Remove all active RRQs for this vport from the phba->active_rrq_list and
+ * clear the rrq.
+ **/
+void
+lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport)
+
+{
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_node_rrq *rrq;
+ struct lpfc_node_rrq *nextrrq;
+ unsigned long iflags;
+
+ if (phba->sli_rev != LPFC_SLI_REV4)
+ return;
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+ if (rrq->vport == vport) {
+ list_del(&rrq->list);
+ __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+ }
+ }
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+}
+
+/**
+ * lpfc_cleanup_wt_rrqs - Remove all rrq's from the active list.
+ * @phba: Pointer to HBA context object.
+ *
+ * Remove all rrqs from the phba->active_rrq_list and free them by
+ * calling __lpfc_clr_active_rrq
+ *
+ **/
+void
+lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba)
+{
+ struct lpfc_node_rrq *rrq;
+ struct lpfc_node_rrq *nextrrq;
+ unsigned long next_time;
+ unsigned long iflags;
+
+ if (phba->sli_rev != LPFC_SLI_REV4)
+ return;
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ phba->hba_flag &= ~HBA_RRQ_ACTIVE;
+ next_time = jiffies + HZ * (phba->fc_ratov * 2);
+ list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+ list_del(&rrq->list);
+ __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+ }
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ if (!list_empty(&phba->active_rrq_list))
+ mod_timer(&phba->rrq_tmr, next_time);
+}
+
+
+/**
+ * __lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: Targets nodelist pointer for this exchange.
+ * @xritag the xri in the bitmap to test.
+ *
+ * This function is called with hbalock held. This function
+ * returns 0 = rrq not active for this xri
+ * 1 = rrq is valid for this xri.
+ **/
+static int
+__lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+ uint16_t xritag)
+{
+ uint16_t adj_xri;
+
+ adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+ if (!ndlp)
+ return 0;
+ if (test_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * lpfc_set_rrq_active - set RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: nodelist pointer for this target.
+ * @xritag: xri used in this exchange.
+ * @rxid: Remote Exchange ID.
+ * @send_rrq: Flag used to determine if we should send rrq els cmd.
+ *
+ * This function takes the hbalock.
+ * The active bit is always set in the active rrq xri_bitmap even
+ * if there is no slot avaiable for the other rrq information.
+ *
+ * returns 0 rrq actived for this xri
+ * < 0 No memory or invalid ndlp.
+ **/
+int
+lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+ uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
+{
+ int ret;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ return ret;
+}
+
+/**
+ * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @xritag: xri used in this exchange.
+ * @rrq: The RRQ to be cleared.
+ *
+ * This function is takes the hbalock.
+ **/
+void
+lpfc_clr_rrq_active(struct lpfc_hba *phba,
+ uint16_t xritag,
+ struct lpfc_node_rrq *rrq)
+{
+ unsigned long iflags;
+
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ __lpfc_clr_rrq_active(phba, xritag, rrq);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ return;
+}
+
+
+
+/**
+ * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: Targets nodelist pointer for this exchange.
+ * @xritag the xri in the bitmap to test.
+ *
+ * This function takes the hbalock.
+ * returns 0 = rrq not active for this xri
+ * 1 = rrq is valid for this xri.
+ **/
+int
+lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+ uint16_t xritag)
+{
+ int ret;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ ret = __lpfc_test_rrq_active(phba, ndlp, xritag);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ return ret;
+}
+
+/**
* __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool
* @phba: Pointer to HBA context object.
+ * @piocb: Pointer to the iocbq.
*
* This function is called with hbalock held. This function
* Gets a new driver sglq object from the sglq list. If the
@@ -522,17 +858,51 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
* allocated sglq object else it returns NULL.
**/
static struct lpfc_sglq *
-__lpfc_sli_get_sglq(struct lpfc_hba *phba)
+__lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
{
struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list;
struct lpfc_sglq *sglq = NULL;
+ struct lpfc_sglq *start_sglq = NULL;
uint16_t adj_xri;
+ struct lpfc_scsi_buf *lpfc_cmd;
+ struct lpfc_nodelist *ndlp;
+ int found = 0;
+
+ if (piocbq->iocb_flag & LPFC_IO_FCP) {
+ lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1;
+ ndlp = lpfc_cmd->rdata->pnode;
+ } else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
+ !(piocbq->iocb_flag & LPFC_IO_LIBDFC))
+ ndlp = piocbq->context_un.ndlp;
+ else
+ ndlp = piocbq->context1;
+
list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list);
- if (!sglq)
- 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;
+ start_sglq = sglq;
+ while (!found) {
+ if (!sglq)
+ return NULL;
+ adj_xri = sglq->sli4_xritag -
+ phba->sli4_hba.max_cfg_param.xri_base;
+ if (__lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) {
+ /* This xri has an rrq outstanding for this DID.
+ * put it back in the list and get another xri.
+ */
+ list_add_tail(&sglq->list, lpfc_sgl_list);
+ sglq = NULL;
+ list_remove_head(lpfc_sgl_list, sglq,
+ struct lpfc_sglq, list);
+ if (sglq == start_sglq) {
+ sglq = NULL;
+ break;
+ } else
+ continue;
+ }
+ sglq->ndlp = ndlp;
+ found = 1;
+ phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+ sglq->state = SGL_ALLOCATED;
+ }
return sglq;
}
@@ -598,6 +968,7 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
&phba->sli4_hba.abts_sgl_list_lock, iflag);
} else {
sglq->state = SGL_FREED;
+ sglq->ndlp = NULL;
list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
/* Check if TXQ queue needs to be serviced */
@@ -1634,7 +2005,6 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
case MBX_READ_LNK_STAT:
case MBX_REG_LOGIN:
case MBX_UNREG_LOGIN:
- case MBX_READ_LA:
case MBX_CLEAR_LA:
case MBX_DUMP_MEMORY:
case MBX_DUMP_CONTEXT:
@@ -1656,7 +2026,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
case MBX_READ_SPARM64:
case MBX_READ_RPI64:
case MBX_REG_LOGIN64:
- case MBX_READ_LA64:
+ case MBX_READ_TOPOLOGY:
case MBX_WRITE_WWN:
case MBX_SET_DEBUG:
case MBX_LOAD_EXP_ROM:
@@ -1746,11 +2116,6 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
kfree(mp);
}
- if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) &&
- (phba->sli_rev == LPFC_SLI_REV4) &&
- (pmb->u.mb.un.varUnregLogin.rsvd1 == 0x0))
- lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi);
-
/*
* If a REG_LOGIN succeeded after node is destroyed or node
* is in re-discovery driver need to cleanup the RPI.
@@ -3483,12 +3848,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
phba->pport->fc_myDID = 0;
phba->pport->fc_prevDID = 0;
- /* Turn off parity checking and serr during the physical reset */
- pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
- pci_write_config_word(phba->pcidev, PCI_COMMAND,
- (cfg_value &
- ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
-
spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~(LPFC_PROCESS_LA);
phba->fcf.fcf_flag = 0;
@@ -3508,9 +3867,18 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
/* Now physically reset the device */
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"0389 Performing PCI function reset!\n");
+
+ /* Turn off parity checking and serr during the physical reset */
+ pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
+ pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value &
+ ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
+
/* Perform FCoE PCI function reset */
lpfc_pci_function_reset(phba);
+ /* Restore PCI cmd register */
+ pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
+
return 0;
}
@@ -4317,6 +4685,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
struct lpfc_vport *vport = phba->pport;
struct lpfc_dmabuf *mp;
+ /*
+ * TODO: Why does this routine execute these task in a different
+ * order from probe?
+ */
/* Perform a PCI function reset to start from clean */
rc = lpfc_pci_function_reset(phba);
if (unlikely(rc))
@@ -4357,13 +4729,16 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
}
rc = lpfc_sli4_read_rev(phba, mboxq, vpd, &vpd_size);
- if (unlikely(rc))
- goto out_free_vpd;
-
+ if (unlikely(rc)) {
+ kfree(vpd);
+ goto out_free_mbox;
+ }
mqe = &mboxq->u.mqe;
phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
- phba->hba_flag |= HBA_FCOE_SUPPORT;
+ phba->hba_flag |= HBA_FCOE_MODE;
+ else
+ phba->hba_flag &= ~HBA_FCOE_MODE;
if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
LPFC_DCBX_CEE_MODE)
@@ -4372,13 +4747,14 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
phba->hba_flag &= ~HBA_FIP_SUPPORT;
if (phba->sli_rev != LPFC_SLI_REV4 ||
- !(phba->hba_flag & HBA_FCOE_SUPPORT)) {
+ !(phba->hba_flag & HBA_FCOE_MODE)) {
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
"0376 READ_REV Error. SLI Level %d "
"FCoE enabled %d\n",
- phba->sli_rev, phba->hba_flag & HBA_FCOE_SUPPORT);
+ phba->sli_rev, phba->hba_flag & HBA_FCOE_MODE);
rc = -EIO;
- goto out_free_vpd;
+ kfree(vpd);
+ goto out_free_mbox;
}
/*
* Evaluate the read rev and vpd data. Populate the driver
@@ -4392,6 +4768,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
"Using defaults.\n", rc);
rc = 0;
}
+ kfree(vpd);
/* Save information as VPD data */
phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev;
@@ -4428,7 +4805,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
if (unlikely(rc)) {
rc = -EIO;
- goto out_free_vpd;
+ goto out_free_mbox;
}
/*
@@ -4476,7 +4853,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
if (rc) {
phba->link_state = LPFC_HBA_ERROR;
rc = -ENOMEM;
- goto out_free_vpd;
+ goto out_free_mbox;
}
mboxq->vport = vport;
@@ -4501,7 +4878,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
rc, bf_get(lpfc_mqe_status, mqe));
phba->link_state = LPFC_HBA_ERROR;
rc = -EIO;
- goto out_free_vpd;
+ goto out_free_mbox;
}
if (phba->cfg_soft_wwnn)
@@ -4526,7 +4903,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
"0582 Error %d during sgl post operation\n",
rc);
rc = -ENODEV;
- goto out_free_vpd;
+ goto out_free_mbox;
}
/* Register SCSI SGL pool to the device */
@@ -4538,7 +4915,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
/* Some Scsi buffers were moved to the abort scsi list */
/* A pci function reset will repost them */
rc = -ENODEV;
- goto out_free_vpd;
+ goto out_free_mbox;
}
/* Post the rpi header region to the device. */
@@ -4548,7 +4925,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
"0393 Error %d during rpi post operation\n",
rc);
rc = -ENODEV;
- goto out_free_vpd;
+ goto out_free_mbox;
}
/* Set up all the queues to the device */
@@ -4608,33 +4985,33 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
}
}
+ if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+ /*
+ * The FC Port needs to register FCFI (index 0)
+ */
+ lpfc_reg_fcfi(phba, mboxq);
+ mboxq->vport = phba->pport;
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+ if (rc == MBX_SUCCESS)
+ rc = 0;
+ else
+ goto out_unset_queue;
+ }
/*
* The port is ready, set the host's link state to LINK_DOWN
* in preparation for link interrupts.
*/
- lpfc_init_link(phba, mboxq, phba->cfg_topology, phba->cfg_link_speed);
- mboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- lpfc_set_loopback_flag(phba);
- /* Change driver state to LPFC_LINK_DOWN right before init link */
spin_lock_irq(&phba->hbalock);
phba->link_state = LPFC_LINK_DOWN;
spin_unlock_irq(&phba->hbalock);
- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
- if (unlikely(rc != MBX_NOT_FINISHED)) {
- kfree(vpd);
- return 0;
- } else
- rc = -EIO;
-
+ rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
+out_unset_queue:
/* Unset all the queues set up in this routine when error out */
if (rc)
lpfc_sli4_queue_unset(phba);
-
out_stop_timers:
if (rc)
lpfc_stop_hba_timers(phba);
-out_free_vpd:
- kfree(vpd);
out_free_mbox:
mempool_free(mboxq, phba->mbox_mem_pool);
return rc;
@@ -5863,6 +6240,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
IOCB_t *icmd;
int numBdes = 0;
int i = 0;
+ uint32_t offset = 0; /* accumulated offset in the sg request list */
+ int inbound = 0; /* number of sg reply entries inbound from firmware */
if (!piocbq || !sglq)
return xritag;
@@ -5897,6 +6276,20 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
*/
bde.tus.w = le32_to_cpu(bpl->tus.w);
sgl->sge_len = cpu_to_le32(bde.tus.f.bdeSize);
+ /* The offsets in the sgl need to be accumulated
+ * separately for the request and reply lists.
+ * The request is always first, the reply follows.
+ */
+ if (piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
+ /* add up the reply sg entries */
+ if (bpl->tus.f.bdeFlags == BUFF_TYPE_BDE_64I)
+ inbound++;
+ /* first inbound? reset the offset */
+ if (inbound == 1)
+ offset = 0;
+ bf_set(lpfc_sli4_sge_offset, sgl, offset);
+ offset += bde.tus.f.bdeSize;
+ }
bpl++;
sgl++;
}
@@ -6028,11 +6421,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(els_req64_vf, &wqe->els_req, 0);
/* And a VFID for word 12 */
bf_set(els_req64_vfid, &wqe->els_req, 0);
- /*
- * Set ct field to 3, indicates that the context_tag field
- * contains the FCFI and remote N_Port_ID is
- * in word 5.
- */
ct = ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l);
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
iocbq->iocb.ulpContext);
@@ -6140,6 +6528,18 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
break;
case CMD_GEN_REQUEST64_CR:
+ /* For this command calculate the xmit length of the
+ * request bde.
+ */
+ xmit_len = 0;
+ numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
+ sizeof(struct ulp_bde64);
+ for (i = 0; i < numBdes; i++) {
+ if (bpl[i].tus.f.bdeFlags != BUFF_TYPE_BDE_64)
+ break;
+ bde.tus.w = le32_to_cpu(bpl[i].tus.w);
+ xmit_len += bde.tus.f.bdeSize;
+ }
/* word3 iocb=IO_TAG wqe=request_payload_len */
wqe->gen_req.request_payload_len = xmit_len;
/* word4 iocb=parameter wqe=relative_offset memcpy */
@@ -6320,7 +6720,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
return IOCB_BUSY;
}
} else {
- sglq = __lpfc_sli_get_sglq(phba);
+ sglq = __lpfc_sli_get_sglq(phba, piocb);
if (!sglq) {
if (!(flag & SLI_IOCB_RET_IOCB)) {
__lpfc_sli_ringtx_put(phba,
@@ -8033,29 +8433,66 @@ static int
lpfc_sli4_eratt_read(struct lpfc_hba *phba)
{
uint32_t uerr_sta_hi, uerr_sta_lo;
+ uint32_t if_type, portsmphr;
+ struct lpfc_register portstat_reg;
- /* For now, use the SLI4 device internal unrecoverable error
+ /*
+ * For now, use the SLI4 device internal unrecoverable error
* registers for error attention. This can be changed later.
*/
- uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
- uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
- if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
- (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+ if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+ switch (if_type) {
+ case LPFC_SLI_INTF_IF_TYPE_0:
+ uerr_sta_lo = readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
+ uerr_sta_hi = readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
+ if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
+ (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "1423 HBA Unrecoverable error: "
+ "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+ "ue_mask_lo_reg=0x%x, "
+ "ue_mask_hi_reg=0x%x\n",
+ uerr_sta_lo, uerr_sta_hi,
+ phba->sli4_hba.ue_mask_lo,
+ phba->sli4_hba.ue_mask_hi);
+ phba->work_status[0] = uerr_sta_lo;
+ phba->work_status[1] = uerr_sta_hi;
+ phba->work_ha |= HA_ERATT;
+ phba->hba_flag |= HBA_ERATT_HANDLED;
+ return 1;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_2:
+ portstat_reg.word0 =
+ readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+ portsmphr = readl(phba->sli4_hba.PSMPHRregaddr);
+ if (bf_get(lpfc_sliport_status_err, &portstat_reg)) {
+ phba->work_status[0] =
+ readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
+ phba->work_status[1] =
+ readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2885 Port Error Detected: "
+ "port status reg 0x%x, "
+ "port smphr reg 0x%x, "
+ "error 1=0x%x, error 2=0x%x\n",
+ portstat_reg.word0,
+ portsmphr,
+ phba->work_status[0],
+ phba->work_status[1]);
+ phba->work_ha |= HA_ERATT;
+ phba->hba_flag |= HBA_ERATT_HANDLED;
+ return 1;
+ }
+ break;
+ case LPFC_SLI_INTF_IF_TYPE_1:
+ default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "1423 HBA Unrecoverable error: "
- "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
- "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
- uerr_sta_lo, uerr_sta_hi,
- phba->sli4_hba.ue_mask_lo,
- phba->sli4_hba.ue_mask_hi);
- phba->work_status[0] = uerr_sta_lo;
- phba->work_status[1] = uerr_sta_hi;
- /* Set the driver HA work bitmap */
- phba->work_ha |= HA_ERATT;
- /* Indicate polling handles this ERATT */
- phba->hba_flag |= HBA_ERATT_HANDLED;
+ "2886 HBA Error Attention on unsupported "
+ "if type %d.", if_type);
return 1;
}
+
return 0;
}
@@ -8110,7 +8547,7 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba)
ha_copy = lpfc_sli_eratt_read(phba);
break;
case LPFC_SLI_REV4:
- /* Read devcie Uncoverable Error (UERR) registers */
+ /* Read device Uncoverable Error (UERR) registers */
ha_copy = lpfc_sli4_eratt_read(phba);
break;
default:
@@ -10155,16 +10592,20 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
length, LPFC_SLI4_MBX_EMBED);
mq_create_ext = &mbox->u.mqe.un.mq_create_ext;
- bf_set(lpfc_mbx_mq_create_ext_num_pages, &mq_create_ext->u.request,
- mq->page_count);
- bf_set(lpfc_mbx_mq_create_ext_async_evt_link, &mq_create_ext->u.request,
- 1);
- bf_set(lpfc_mbx_mq_create_ext_async_evt_fcfste,
+ bf_set(lpfc_mbx_mq_create_ext_num_pages,
+ &mq_create_ext->u.request, mq->page_count);
+ bf_set(lpfc_mbx_mq_create_ext_async_evt_link,
+ &mq_create_ext->u.request, 1);
+ bf_set(lpfc_mbx_mq_create_ext_async_evt_fip,
&mq_create_ext->u.request, 1);
bf_set(lpfc_mbx_mq_create_ext_async_evt_group5,
&mq_create_ext->u.request, 1);
- bf_set(lpfc_mq_context_cq_id, &mq_create_ext->u.request.context,
- cq->queue_id);
+ bf_set(lpfc_mbx_mq_create_ext_async_evt_fc,
+ &mq_create_ext->u.request, 1);
+ bf_set(lpfc_mbx_mq_create_ext_async_evt_sli,
+ &mq_create_ext->u.request, 1);
+ bf_set(lpfc_mq_context_cq_id,
+ &mq_create_ext->u.request.context, cq->queue_id);
bf_set(lpfc_mq_context_valid, &mq_create_ext->u.request.context, 1);
switch (mq->entry_count) {
default:
@@ -11137,7 +11578,8 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, struct list_head *sblist,
static int
lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr)
{
- char *rctl_names[] = FC_RCTL_NAMES_INIT;
+ /* make rctl_names static to save stack space */
+ static char *rctl_names[] = FC_RCTL_NAMES_INIT;
char *type_names[] = FC_TYPE_NAMES_INIT;
struct fc_vft_header *fc_vft_hdr;
@@ -11538,6 +11980,10 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
"SID:x%x\n", oxid, sid);
return;
}
+ if (rxid >= phba->sli4_hba.max_cfg_param.xri_base
+ && rxid <= (phba->sli4_hba.max_cfg_param.max_xri
+ + phba->sli4_hba.max_cfg_param.xri_base))
+ lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0);
/* Allocate buffer for acc iocb */
ctiocb = lpfc_sli_get_iocbq(phba);
@@ -11560,6 +12006,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
icmd->ulpLe = 1;
icmd->ulpClass = CLASS3;
icmd->ulpContext = ndlp->nlp_rpi;
+ ctiocb->context1 = ndlp;
ctiocb->iocb_cmpl = NULL;
ctiocb->vport = phba->pport;
@@ -12129,42 +12576,37 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp)
/**
* lpfc_sli4_init_vpi - Initialize a vpi with the port
- * @phba: pointer to lpfc hba data structure.
- * @vpi: vpi value to activate with the port.
+ * @vport: Pointer to the vport for which the vpi is being initialized
*
- * This routine is invoked to activate a vpi with the
- * port when the host intends to use vports with a
- * nonzero vpi.
+ * This routine is invoked to activate a vpi with the port.
*
* Returns:
* 0 success
* -Evalue otherwise
**/
int
-lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi)
+lpfc_sli4_init_vpi(struct lpfc_vport *vport)
{
LPFC_MBOXQ_t *mboxq;
int rc = 0;
int retval = MBX_SUCCESS;
uint32_t mbox_tmo;
-
- if (vpi == 0)
- return -EINVAL;
+ struct lpfc_hba *phba = vport->phba;
mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mboxq)
return -ENOMEM;
- lpfc_init_vpi(phba, mboxq, vpi);
+ lpfc_init_vpi(phba, mboxq, vport->vpi);
mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI);
rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
if (rc != MBX_SUCCESS) {
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_SLI,
"2022 INIT VPI Mailbox failed "
"status %d, mbxStatus x%x\n", rc,
bf_get(lpfc_mqe_status, &mboxq->u.mqe));
retval = -EIO;
}
if (rc != MBX_TIMEOUT)
- mempool_free(mboxq, phba->mbox_mem_pool);
+ mempool_free(mboxq, vport->phba->mbox_mem_pool);
return retval;
}
@@ -12854,6 +13296,7 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
struct lpfc_nodelist *act_mbx_ndlp = NULL;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
LIST_HEAD(mbox_cmd_list);
+ uint8_t restart_loop;
/* Clean up internally queued mailbox commands with the vport */
spin_lock_irq(&phba->hbalock);
@@ -12882,15 +13325,44 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
}
}
+ /* Cleanup any mailbox completions which are not yet processed */
+ do {
+ restart_loop = 0;
+ list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
+ /*
+ * If this mailox is already processed or it is
+ * for another vport ignore it.
+ */
+ if ((mb->vport != vport) ||
+ (mb->mbox_flag & LPFC_MBX_IMED_UNREG))
+ continue;
+
+ if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) &&
+ (mb->u.mb.mbxCommand != MBX_REG_VPI))
+ continue;
+
+ mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
+ ndlp = (struct lpfc_nodelist *)mb->context2;
+ /* Unregister the RPI when mailbox complete */
+ mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
+ restart_loop = 1;
+ spin_unlock_irq(&phba->hbalock);
+ spin_lock(shost->host_lock);
+ ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
+ spin_unlock(shost->host_lock);
+ spin_lock_irq(&phba->hbalock);
+ break;
+ }
+ }
+ } while (restart_loop);
+
spin_unlock_irq(&phba->hbalock);
/* Release the cleaned-up mailbox commands */
while (!list_empty(&mbox_cmd_list)) {
list_remove_head(&mbox_cmd_list, mb, LPFC_MBOXQ_t, list);
if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
- if (phba->sli_rev == LPFC_SLI_REV4)
- __lpfc_sli4_free_rpi(phba,
- mb->u.mb.un.varRegLogin.rpi);
mp = (struct lpfc_dmabuf *) (mb->context1);
if (mp) {
__lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -12948,12 +13420,13 @@ lpfc_drain_txq(struct lpfc_hba *phba)
while (pring->txq_cnt) {
spin_lock_irqsave(&phba->hbalock, iflags);
- sglq = __lpfc_sli_get_sglq(phba);
+ piocbq = lpfc_sli_ringtx_get(phba, pring);
+ sglq = __lpfc_sli_get_sglq(phba, piocbq);
if (!sglq) {
+ __lpfc_sli_ringtx_put(phba, pring, piocbq);
spin_unlock_irqrestore(&phba->hbalock, iflags);
break;
} else {
- piocbq = lpfc_sli_ringtx_get(phba, pring);
if (!piocbq) {
/* The txq_cnt out of sync. This should
* never happen
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index cd56d6cce6c3..453577c21c14 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -34,9 +34,11 @@ struct lpfc_cq_event {
union {
struct lpfc_mcqe mcqe_cmpl;
struct lpfc_acqe_link acqe_link;
- struct lpfc_acqe_fcoe acqe_fcoe;
+ struct lpfc_acqe_fip acqe_fip;
struct lpfc_acqe_dcbx acqe_dcbx;
struct lpfc_acqe_grp5 acqe_grp5;
+ struct lpfc_acqe_fc_la acqe_fc;
+ struct lpfc_acqe_sli acqe_sli;
struct lpfc_rcqe rcqe_cmpl;
struct sli4_wcqe_xri_aborted wcqe_axri;
struct lpfc_wcqe_complete wcqe_cmpl;
@@ -82,6 +84,7 @@ struct lpfc_iocbq {
struct lpfc_iocbq *rsp_iocb;
struct lpfcMboxq *mbox;
struct lpfc_nodelist *ndlp;
+ struct lpfc_node_rrq *rrq;
} context_un;
void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index c4483feb8b71..c7217d579e0f 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -137,9 +137,11 @@ struct lpfc_sli4_link {
uint8_t speed;
uint8_t duplex;
uint8_t status;
- uint8_t physical;
+ uint8_t type;
+ uint8_t number;
uint8_t fault;
uint16_t logical_speed;
+ uint16_t topology;
};
struct lpfc_fcf_rec {
@@ -367,23 +369,39 @@ struct lpfc_sli4_hba {
PCI BAR1, control registers */
void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for
PCI BAR2, doorbell registers */
- /* BAR0 PCI config space register memory map */
- void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */
- void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
- void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
- void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
- void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */
- /* BAR1 FCoE function CSR register memory map */
- void __iomem *STAregaddr; /* Address to HST_STATE register */
- void __iomem *ISRregaddr; /* Address to HST_ISR register */
- void __iomem *IMRregaddr; /* Address to HST_IMR register */
- void __iomem *ISCRregaddr; /* Address to HST_ISCR register */
- /* BAR2 VF-0 doorbell register memory map */
- void __iomem *RQDBregaddr; /* Address to RQ_DOORBELL register */
- void __iomem *WQDBregaddr; /* Address to WQ_DOORBELL register */
- void __iomem *EQCQDBregaddr; /* Address to EQCQ_DOORBELL register */
- void __iomem *MQDBregaddr; /* Address to MQ_DOORBELL register */
- void __iomem *BMBXregaddr; /* Address to BootStrap MBX register */
+ union {
+ struct {
+ /* IF Type 0, BAR 0 PCI cfg space reg mem map */
+ void __iomem *UERRLOregaddr;
+ void __iomem *UERRHIregaddr;
+ void __iomem *UEMASKLOregaddr;
+ void __iomem *UEMASKHIregaddr;
+ } if_type0;
+ struct {
+ /* IF Type 2, BAR 0 PCI cfg space reg mem map. */
+ void __iomem *STATUSregaddr;
+ void __iomem *CTRLregaddr;
+ void __iomem *ERR1regaddr;
+ void __iomem *ERR2regaddr;
+ } if_type2;
+ } u;
+
+ /* IF type 0, BAR1 and if type 2, Bar 0 CSR register memory map */
+ void __iomem *PSMPHRregaddr;
+
+ /* Well-known SLI INTF register memory map. */
+ void __iomem *SLIINTFregaddr;
+
+ /* IF type 0, BAR 1 function CSR register memory map */
+ void __iomem *ISRregaddr; /* HST_ISR register */
+ void __iomem *IMRregaddr; /* HST_IMR register */
+ void __iomem *ISCRregaddr; /* HST_ISCR register */
+ /* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */
+ void __iomem *RQDBregaddr; /* RQ_DOORBELL register */
+ void __iomem *WQDBregaddr; /* WQ_DOORBELL register */
+ void __iomem *EQCQDBregaddr; /* EQCQ_DOORBELL register */
+ void __iomem *MQDBregaddr; /* MQ_DOORBELL register */
+ void __iomem *BMBXregaddr; /* BootStrap MBX register */
uint32_t ue_mask_lo;
uint32_t ue_mask_hi;
@@ -466,6 +484,7 @@ struct lpfc_sglq {
struct list_head clist;
enum lpfc_sge_type buff_type; /* is this a scsi sgl */
enum lpfc_sgl_state state;
+ struct lpfc_nodelist *ndlp; /* ndlp associated with IO */
uint16_t iotag; /* pre-assigned IO tag */
uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */
struct sli4_sge *sgl; /* pre-assigned SGL */
@@ -532,7 +551,6 @@ int lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *);
struct lpfc_rpi_hdr *lpfc_sli4_create_rpi_hdr(struct lpfc_hba *);
void lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *);
int lpfc_sli4_alloc_rpi(struct lpfc_hba *);
-void __lpfc_sli4_free_rpi(struct lpfc_hba *, int);
void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
void lpfc_sli4_remove_rpis(struct lpfc_hba *);
void lpfc_sli4_async_event_proc(struct lpfc_hba *);
@@ -548,7 +566,7 @@ int lpfc_sli4_brdreset(struct lpfc_hba *);
int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *);
void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *);
int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *);
-int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_init_vpi(struct lpfc_vport *);
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);
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 7a1b5b112a0b..386cf92de492 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.18"
+#define LPFC_DRIVER_VERSION "8.3.20"
#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 a5281ce893d0..6b8d2952e32f 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -395,8 +395,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
* by the port.
*/
if ((phba->sli_rev == LPFC_SLI_REV4) &&
- (pport->fc_flag & FC_VFI_REGISTERED)) {
- rc = lpfc_sli4_init_vpi(phba, vpi);
+ (pport->fc_flag & FC_VFI_REGISTERED)) {
+ rc = lpfc_sli4_init_vpi(vport);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
"1838 Failed to INIT_VPI on vpi %d "
@@ -418,7 +418,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
if ((phba->link_state < LPFC_LINK_UP) ||
(pport->port_state < LPFC_FABRIC_CFG_LINK) ||
- (phba->fc_topology == TOPOLOGY_LOOP)) {
+ (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
rc = VPORT_OK;
goto out;
@@ -514,7 +514,7 @@ enable_vport(struct fc_vport *fc_vport)
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
if ((phba->link_state < LPFC_LINK_UP) ||
- (phba->fc_topology == TOPOLOGY_LOOP)) {
+ (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
return VPORT_OK;
}
@@ -665,7 +665,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
phba->link_state >= LPFC_LINK_UP &&
- phba->fc_topology != TOPOLOGY_LOOP) {
+ phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
if (vport->cfg_enable_da_id) {
timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
diff --git a/drivers/scsi/megaraid/Makefile b/drivers/scsi/megaraid/Makefile
index f469915b97c3..5826ed509e3e 100644
--- a/drivers/scsi/megaraid/Makefile
+++ b/drivers/scsi/megaraid/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_MEGARAID_MM) += megaraid_mm.o
obj-$(CONFIG_MEGARAID_MAILBOX) += megaraid_mbox.o
obj-$(CONFIG_MEGARAID_SAS) += megaraid_sas.o
+megaraid_sas-objs := megaraid_sas_base.o megaraid_sas_fusion.o \
+ megaraid_sas_fp.o
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index ad16f5e60046..1b5e375732c0 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1,15 +1,30 @@
/*
+ * Linux MegaRAID driver for SAS based RAID controllers
*
- * Linux MegaRAID driver for SAS based RAID controllers
+ * Copyright (c) 2009-2011 LSI Corporation.
*
- * Copyright (c) 2003-2005 LSI Corporation.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
- * This program is free software; you can redistribute it and/or
- * 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.
*
- * FILE : megaraid_sas.h
+ * You 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
+ *
+ * FILE: megaraid_sas.h
+ *
+ * Authors: LSI Corporation
+ *
+ * Send feedback to: <megaraidlinux@lsi.com>
+ *
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ * ATTN: Linuxraid
*/
#ifndef LSI_MEGARAID_SAS_H
@@ -18,9 +33,9 @@
/*
* MegaRAID SAS Driver meta data
*/
-#define MEGASAS_VERSION "00.00.04.31-rc1"
-#define MEGASAS_RELDATE "May 3, 2010"
-#define MEGASAS_EXT_VERSION "Mon. May 3, 11:41:51 PST 2010"
+#define MEGASAS_VERSION "00.00.05.29-rc1"
+#define MEGASAS_RELDATE "Dec. 7, 2010"
+#define MEGASAS_EXT_VERSION "Tue. Dec. 7 17:00:00 PDT 2010"
/*
* Device IDs
@@ -32,6 +47,7 @@
#define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079
#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073
#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071
+#define PCI_DEVICE_ID_LSI_FUSION 0x005b
/*
* =====================================
@@ -421,7 +437,6 @@ struct megasas_ctrl_prop {
* Add properties that can be controlled by
* a bit in the following structure.
*/
-
struct {
u32 copyBackDisabled : 1;
u32 SMARTerEnabled : 1;
@@ -701,6 +716,7 @@ struct megasas_ctrl_info {
#define MEGASAS_DEFAULT_INIT_ID -1
#define MEGASAS_MAX_LUN 8
#define MEGASAS_MAX_LD 64
+#define MEGASAS_DEFAULT_CMD_PER_LUN 128
#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
MEGASAS_MAX_DEV_PER_CHANNEL)
#define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \
@@ -769,7 +785,10 @@ struct megasas_ctrl_info {
*/
struct megasas_register_set {
- u32 reserved_0[4]; /*0000h*/
+ u32 doorbell; /*0000h*/
+ u32 fusion_seq_offset; /*0004h*/
+ u32 fusion_host_diag; /*0008h*/
+ u32 reserved_01; /*000Ch*/
u32 inbound_msg_0; /*0010h*/
u32 inbound_msg_1; /*0014h*/
@@ -789,15 +808,18 @@ struct megasas_register_set {
u32 inbound_queue_port; /*0040h*/
u32 outbound_queue_port; /*0044h*/
- u32 reserved_2[22]; /*0048h*/
+ u32 reserved_2[9]; /*0048h*/
+ u32 reply_post_host_index; /*006Ch*/
+ u32 reserved_2_2[12]; /*0070h*/
u32 outbound_doorbell_clear; /*00A0h*/
u32 reserved_3[3]; /*00A4h*/
u32 outbound_scratch_pad ; /*00B0h*/
+ u32 outbound_scratch_pad_2; /*00B4h*/
- u32 reserved_4[3]; /*00B4h*/
+ u32 reserved_4[2]; /*00B8h*/
u32 inbound_low_queue_port ; /*00C0h*/
@@ -1272,6 +1294,9 @@ struct megasas_instance {
u16 max_num_sge;
u16 max_fw_cmds;
+ /* For Fusion its num IOCTL cmds, for others MFI based its
+ max_fw_cmds */
+ u16 max_mfi_cmds;
u32 max_sectors_per_req;
struct megasas_aen_event *ev;
@@ -1320,6 +1345,16 @@ struct megasas_instance {
struct timer_list io_completion_timer;
struct list_head internal_reset_pending_q;
+
+ /* Ptr to hba specfic information */
+ void *ctrl_context;
+ u8 msi_flag;
+ struct msix_entry msixentry;
+ u64 map_id;
+ struct megasas_cmd *map_update_cmd;
+ unsigned long bar;
+ long reset_flags;
+ struct mutex reset_mutex;
};
enum {
@@ -1345,6 +1380,13 @@ struct megasas_instance_template {
struct megasas_register_set __iomem *);
int (*check_reset)(struct megasas_instance *, \
struct megasas_register_set __iomem *);
+ irqreturn_t (*service_isr)(int irq, void *devp);
+ void (*tasklet)(unsigned long);
+ u32 (*init_adapter)(struct megasas_instance *);
+ u32 (*build_and_issue_cmd) (struct megasas_instance *,
+ struct scsi_cmnd *);
+ void (*issue_dcmd) (struct megasas_instance *instance,
+ struct megasas_cmd *cmd);
};
#define MEGASAS_IS_LOGICAL(scp) \
@@ -1371,7 +1413,13 @@ struct megasas_cmd {
struct list_head list;
struct scsi_cmnd *scmd;
struct megasas_instance *instance;
- u32 frame_count;
+ union {
+ struct {
+ u16 smid;
+ u16 resvd;
+ } context;
+ u32 frame_count;
+ };
};
#define MAX_MGMT_ADAPTERS 1024
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 7451bc096a01..5d6d07bd1cd0 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1,27 +1,34 @@
/*
+ * Linux MegaRAID driver for SAS based RAID controllers
*
- * Linux MegaRAID driver for SAS based RAID controllers
+ * Copyright (c) 2009-2011 LSI Corporation.
*
- * Copyright (c) 2003-2005 LSI Corporation.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
- * This program is free software; you can redistribute it and/or
- * 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.
*
- * FILE : megaraid_sas.c
- * Version : v00.00.04.31-rc1
+ * You 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
*
- * Authors:
- * (email-id : megaraidlinux@lsi.com)
- * Sreenivas Bagalkote
- * Sumant Patro
- * Bo Yang
+ * FILE: megaraid_sas_base.c
+ * Version : v00.00.05.29-rc1
*
- * List of supported controllers
+ * Authors: LSI Corporation
+ * Sreenivas Bagalkote
+ * Sumant Patro
+ * Bo Yang
*
- * OEM Product Name VID DID SSVID SSID
- * --- ------------ --- --- ---- ----
+ * Send feedback to: <megaraidlinux@lsi.com>
+ *
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ * ATTN: Linuxraid
*/
#include <linux/kernel.h>
@@ -46,6 +53,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
+#include "megaraid_sas_fusion.h"
#include "megaraid_sas.h"
/*
@@ -65,12 +73,16 @@ module_param_named(max_sectors, max_sectors, int, 0);
MODULE_PARM_DESC(max_sectors,
"Maximum number of sectors per IO command");
+static int msix_disable;
+module_param(msix_disable, int, S_IRUGO);
+MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
+
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION);
MODULE_AUTHOR("megaraidlinux@lsi.com");
MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
-static int megasas_transition_to_ready(struct megasas_instance *instance);
+int megasas_transition_to_ready(struct megasas_instance *instance);
static int megasas_get_pd_list(struct megasas_instance *instance);
static int megasas_issue_init_mfi(struct megasas_instance *instance);
static int megasas_register_aen(struct megasas_instance *instance,
@@ -98,6 +110,8 @@ static struct pci_device_id megasas_pci_table[] = {
/* xscale IOP, vega */
{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
/* xscale IOP */
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
+ /* Fusion */
{}
};
@@ -111,23 +125,55 @@ static DEFINE_MUTEX(megasas_async_queue_mutex);
static int megasas_poll_wait_aen;
static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
static u32 support_poll_for_event;
-static u32 megasas_dbg_lvl;
+u32 megasas_dbg_lvl;
static u32 support_device_change;
/* define lock for aen poll */
spinlock_t poll_aen_lock;
-static void
+void
megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
u8 alt_status);
+static irqreturn_t megasas_isr(int irq, void *devp);
+static u32
+megasas_init_adapter_mfi(struct megasas_instance *instance);
+u32
+megasas_build_and_issue_cmd(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd);
+static void megasas_complete_cmd_dpc(unsigned long instance_addr);
+void
+megasas_release_fusion(struct megasas_instance *instance);
+int
+megasas_ioc_init_fusion(struct megasas_instance *instance);
+void
+megasas_free_cmds_fusion(struct megasas_instance *instance);
+u8
+megasas_get_map_info(struct megasas_instance *instance);
+int
+megasas_sync_map_info(struct megasas_instance *instance);
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
+void megasas_reset_reply_desc(struct megasas_instance *instance);
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+ struct LD_LOAD_BALANCE_INFO *lbInfo);
+int megasas_reset_fusion(struct Scsi_Host *shost);
+void megasas_fusion_ocr_wq(struct work_struct *work);
+
+void
+megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ instance->instancet->fire_cmd(instance,
+ cmd->frame_phys_addr, 0, instance->reg_set);
+}
+
/**
* megasas_get_cmd - Get a command from the free pool
* @instance: Adapter soft state
*
* Returns a free command from the pool
*/
-static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+struct megasas_cmd *megasas_get_cmd(struct megasas_instance
*instance)
{
unsigned long flags;
@@ -152,7 +198,7 @@ static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
* @instance: Adapter soft state
* @cmd: Command packet to be returned to free command pool
*/
-static inline void
+inline void
megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
unsigned long flags;
@@ -160,6 +206,7 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
spin_lock_irqsave(&instance->cmd_pool_lock, flags);
cmd->scmd = NULL;
+ cmd->frame_count = 0;
list_add_tail(&cmd->list, &instance->cmd_pool);
spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
@@ -167,7 +214,7 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
/**
-* The following functions are defined for xscale
+* The following functions are defined for xscale
* (deviceid : 1064R, PERC5) controllers
*/
@@ -210,7 +257,7 @@ megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
* megasas_clear_interrupt_xscale - Check & clear interrupt
* @regs: MFI register set
*/
-static int
+static int
megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
{
u32 status;
@@ -243,7 +290,7 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
* @frame_count : Number of frames for the command
* @regs : MFI register set
*/
-static inline void
+static inline void
megasas_fire_cmd_xscale(struct megasas_instance *instance,
dma_addr_t frame_phys_addr,
u32 frame_count,
@@ -323,15 +370,20 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
.read_fw_status_reg = megasas_read_fw_status_reg_xscale,
.adp_reset = megasas_adp_reset_xscale,
.check_reset = megasas_check_reset_xscale,
+ .service_isr = megasas_isr,
+ .tasklet = megasas_complete_cmd_dpc,
+ .init_adapter = megasas_init_adapter_mfi,
+ .build_and_issue_cmd = megasas_build_and_issue_cmd,
+ .issue_dcmd = megasas_issue_dcmd,
};
/**
-* This is the end of set of functions & definitions specific
+* This is the end of set of functions & definitions specific
* to xscale (deviceid : 1064R, PERC5) controllers
*/
/**
-* The following functions are defined for ppc (deviceid : 0x60)
+* The following functions are defined for ppc (deviceid : 0x60)
* controllers
*/
@@ -343,7 +395,7 @@ static inline void
megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
{
writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
-
+
writel(~0x80000000, &(regs)->outbound_intr_mask);
/* Dummy readl to force pci flush */
@@ -377,7 +429,7 @@ megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
* megasas_clear_interrupt_ppc - Check & clear interrupt
* @regs: MFI register set
*/
-static int
+static int
megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
{
u32 status;
@@ -406,7 +458,7 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
* @frame_count : Number of frames for the command
* @regs : MFI register set
*/
-static inline void
+static inline void
megasas_fire_cmd_ppc(struct megasas_instance *instance,
dma_addr_t frame_phys_addr,
u32 frame_count,
@@ -414,7 +466,7 @@ megasas_fire_cmd_ppc(struct megasas_instance *instance,
{
unsigned long flags;
spin_lock_irqsave(&instance->hba_lock, flags);
- writel((frame_phys_addr | (frame_count<<1))|1,
+ writel((frame_phys_addr | (frame_count<<1))|1,
&(regs)->inbound_queue_port);
spin_unlock_irqrestore(&instance->hba_lock, flags);
}
@@ -441,7 +493,7 @@ megasas_check_reset_ppc(struct megasas_instance *instance,
return 0;
}
static struct megasas_instance_template megasas_instance_template_ppc = {
-
+
.fire_cmd = megasas_fire_cmd_ppc,
.enable_intr = megasas_enable_intr_ppc,
.disable_intr = megasas_disable_intr_ppc,
@@ -449,6 +501,11 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
.read_fw_status_reg = megasas_read_fw_status_reg_ppc,
.adp_reset = megasas_adp_reset_ppc,
.check_reset = megasas_check_reset_ppc,
+ .service_isr = megasas_isr,
+ .tasklet = megasas_complete_cmd_dpc,
+ .init_adapter = megasas_init_adapter_mfi,
+ .build_and_issue_cmd = megasas_build_and_issue_cmd,
+ .issue_dcmd = megasas_issue_dcmd,
};
/**
@@ -570,6 +627,11 @@ static struct megasas_instance_template megasas_instance_template_skinny = {
.read_fw_status_reg = megasas_read_fw_status_reg_skinny,
.adp_reset = megasas_adp_reset_skinny,
.check_reset = megasas_check_reset_skinny,
+ .service_isr = megasas_isr,
+ .tasklet = megasas_complete_cmd_dpc,
+ .init_adapter = megasas_init_adapter_mfi,
+ .build_and_issue_cmd = megasas_build_and_issue_cmd,
+ .issue_dcmd = megasas_issue_dcmd,
};
@@ -744,6 +806,11 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
.read_fw_status_reg = megasas_read_fw_status_reg_gen2,
.adp_reset = megasas_adp_reset_gen2,
.check_reset = megasas_check_reset_gen2,
+ .service_isr = megasas_isr,
+ .tasklet = megasas_complete_cmd_dpc,
+ .init_adapter = megasas_init_adapter_mfi,
+ .build_and_issue_cmd = megasas_build_and_issue_cmd,
+ .issue_dcmd = megasas_issue_dcmd,
};
/**
@@ -751,18 +818,21 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
* specific to gen2 (deviceid : 0x78, 0x79) controllers
*/
+/*
+ * Template added for TB (Fusion)
+ */
+extern struct megasas_instance_template megasas_instance_template_fusion;
+
/**
* megasas_issue_polled - Issues a polling command
* @instance: Adapter soft state
- * @cmd: Command packet to be issued
+ * @cmd: Command packet to be issued
*
* For polling, MFI requires the cmd_status to be set to 0xFF before posting.
*/
-static int
+int
megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
- int i;
- u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
struct megasas_header *frame_hdr = &cmd->frame->hdr;
@@ -772,21 +842,12 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
/*
* Issue the frame using inbound queue port
*/
- instance->instancet->fire_cmd(instance,
- cmd->frame_phys_addr, 0, instance->reg_set);
+ instance->instancet->issue_dcmd(instance, cmd);
/*
* Wait for cmd_status to change
*/
- for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
- rmb();
- msleep(1);
- }
-
- if (frame_hdr->cmd_status == 0xff)
- return -ETIME;
-
- return 0;
+ return wait_and_poll(instance, cmd);
}
/**
@@ -804,8 +865,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
{
cmd->cmd_status = ENODATA;
- instance->instancet->fire_cmd(instance,
- cmd->frame_phys_addr, 0, instance->reg_set);
+ instance->instancet->issue_dcmd(instance, cmd);
wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
@@ -849,8 +909,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
cmd->sync_cmd = 1;
cmd->cmd_status = 0xFF;
- instance->instancet->fire_cmd(instance,
- cmd->frame_phys_addr, 0, instance->reg_set);
+ instance->instancet->issue_dcmd(instance, cmd);
/*
* Wait for this cmd to complete
@@ -1242,11 +1301,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
/**
* megasas_is_ldio - Checks if the cmd is for logical drive
* @scmd: SCSI command
- *
+ *
* Called by megasas_queue_command to find out if the command to be queued
- * is a logical drive command
+ * is a logical drive command
*/
-static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
+inline int megasas_is_ldio(struct scsi_cmnd *cmd)
{
if (!MEGASAS_IS_LOGICAL(cmd))
return 0;
@@ -1328,6 +1387,51 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
}
+u32
+megasas_build_and_issue_cmd(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd)
+{
+ struct megasas_cmd *cmd;
+ u32 frame_count;
+
+ cmd = megasas_get_cmd(instance);
+ if (!cmd)
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+ /*
+ * Logical drive command
+ */
+ if (megasas_is_ldio(scmd))
+ frame_count = megasas_build_ldio(instance, scmd, cmd);
+ else
+ frame_count = megasas_build_dcdb(instance, scmd, cmd);
+
+ if (!frame_count)
+ goto out_return_cmd;
+
+ cmd->scmd = scmd;
+ scmd->SCp.ptr = (char *)cmd;
+
+ /*
+ * Issue the command to the FW
+ */
+ atomic_inc(&instance->fw_outstanding);
+
+ instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
+ cmd->frame_count-1, instance->reg_set);
+ /*
+ * Check if we have pend cmds to be completed
+ */
+ if (poll_mode_io && atomic_read(&instance->fw_outstanding))
+ tasklet_schedule(&instance->isr_tasklet);
+
+ return 0;
+out_return_cmd:
+ megasas_return_cmd(instance, cmd);
+ return 1;
+}
+
+
/**
* megasas_queue_command - Queue entry point
* @scmd: SCSI command to be queued
@@ -1336,8 +1440,6 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
static int
megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
{
- u32 frame_count;
- struct megasas_cmd *cmd;
struct megasas_instance *instance;
unsigned long flags;
@@ -1376,42 +1478,13 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd
break;
}
- cmd = megasas_get_cmd(instance);
- if (!cmd)
+ if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
+ printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
return SCSI_MLQUEUE_HOST_BUSY;
-
- /*
- * Logical drive command
- */
- if (megasas_is_ldio(scmd))
- frame_count = megasas_build_ldio(instance, scmd, cmd);
- else
- frame_count = megasas_build_dcdb(instance, scmd, cmd);
-
- if (!frame_count)
- goto out_return_cmd;
-
- cmd->scmd = scmd;
- scmd->SCp.ptr = (char *)cmd;
-
- /*
- * Issue the command to the FW
- */
- atomic_inc(&instance->fw_outstanding);
-
- instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
- cmd->frame_count-1, instance->reg_set);
- /*
- * Check if we have pend cmds to be completed
- */
- if (poll_mode_io && atomic_read(&instance->fw_outstanding))
- tasklet_schedule(&instance->isr_tasklet);
-
+ }
return 0;
- out_return_cmd:
- megasas_return_cmd(instance, cmd);
out_done:
done(scmd);
return 0;
@@ -1492,15 +1565,44 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
return 0;
}
-static void megaraid_sas_kill_hba(struct megasas_instance *instance)
+void megaraid_sas_kill_hba(struct megasas_instance *instance)
{
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
- writel(MFI_STOP_ADP,
- &instance->reg_set->reserved_0[0]);
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)) {
+ writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
} else {
- writel(MFI_STOP_ADP,
- &instance->reg_set->inbound_doorbell);
+ writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
+ }
+}
+
+ /**
+ * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
+ * restored to max value
+ * @instance: Adapter soft state
+ *
+ */
+void
+megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
+{
+ unsigned long flags;
+ if (instance->flag & MEGASAS_FW_BUSY
+ && time_after(jiffies, instance->last_time + 5 * HZ)
+ && atomic_read(&instance->fw_outstanding) < 17) {
+
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ instance->flag &= ~MEGASAS_FW_BUSY;
+ if ((instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+ (instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+ instance->host->can_queue =
+ instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+ } else
+ instance->host->can_queue =
+ instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
}
}
@@ -1554,24 +1656,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
/*
* Check if we can restore can_queue
*/
- if (instance->flag & MEGASAS_FW_BUSY
- && time_after(jiffies, instance->last_time + 5 * HZ)
- && atomic_read(&instance->fw_outstanding) < 17) {
-
- spin_lock_irqsave(instance->host->host_lock, flags);
- instance->flag &= ~MEGASAS_FW_BUSY;
- if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
- instance->host->can_queue =
- instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
- } else
- instance->host->can_queue =
- instance->max_fw_cmds - MEGASAS_INT_CMDS;
-
- spin_unlock_irqrestore(instance->host->host_lock, flags);
- }
+ megasas_check_and_restore_queue_depth(instance);
}
static void
@@ -1749,7 +1834,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
writel(MFI_STOP_ADP,
- &instance->reg_set->reserved_0[0]);
+ &instance->reg_set->doorbell);
} else {
writel(MFI_STOP_ADP,
&instance->reg_set->inbound_doorbell);
@@ -1853,11 +1938,16 @@ static int megasas_reset_device(struct scsi_cmnd *scmd)
static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
{
int ret;
+ struct megasas_instance *instance;
+ instance = (struct megasas_instance *)scmd->device->host->hostdata;
/*
* First wait for all commands to complete
*/
- ret = megasas_generic_reset(scmd);
+ if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)
+ ret = megasas_reset_fusion(scmd->device->host);
+ else
+ ret = megasas_generic_reset(scmd);
return ret;
}
@@ -2000,8 +2090,8 @@ megasas_complete_int_cmd(struct megasas_instance *instance,
* @instance: Adapter soft state
* @cmd: Cmd that was issued to abort another cmd
*
- * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
- * after it issues an abort on a previously issued command. This function
+ * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
+ * after it issues an abort on a previously issued command. This function
* wakes up all functions waiting on the same wait queue.
*/
static void
@@ -2021,19 +2111,20 @@ megasas_complete_abort(struct megasas_instance *instance,
* megasas_complete_cmd - Completes a command
* @instance: Adapter soft state
* @cmd: Command to be completed
- * @alt_status: If non-zero, use this value as status to
+ * @alt_status: If non-zero, use this value as status to
* SCSI mid-layer instead of the value returned
* by the FW. This should be used if caller wants
* an alternate status (as in the case of aborted
* commands)
*/
-static void
+void
megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
u8 alt_status)
{
int exception = 0;
struct megasas_header *hdr = &cmd->frame->hdr;
unsigned long flags;
+ struct fusion_context *fusion = instance->ctrl_context;
/* flag for the retry reset */
cmd->retry_for_fw_reset = 0;
@@ -2126,6 +2217,37 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
case MFI_CMD_SMP:
case MFI_CMD_STP:
case MFI_CMD_DCMD:
+ /* Check for LD map update */
+ if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) &&
+ (cmd->frame->dcmd.mbox.b[1] == 1)) {
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ if (cmd->frame->hdr.cmd_status != 0) {
+ if (cmd->frame->hdr.cmd_status !=
+ MFI_STAT_NOT_FOUND)
+ printk(KERN_WARNING "megasas: map sync"
+ "failed, status = 0x%x.\n",
+ cmd->frame->hdr.cmd_status);
+ else {
+ megasas_return_cmd(instance, cmd);
+ spin_unlock_irqrestore(
+ instance->host->host_lock,
+ flags);
+ break;
+ }
+ } else
+ instance->map_id++;
+ megasas_return_cmd(instance, cmd);
+ if (MR_ValidateMapInfo(
+ fusion->ld_map[(instance->map_id & 1)],
+ fusion->load_balance_info))
+ fusion->fast_path_io = 1;
+ else
+ fusion->fast_path_io = 0;
+ megasas_sync_map_info(instance);
+ spin_unlock_irqrestore(instance->host->host_lock,
+ flags);
+ break;
+ }
if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
spin_lock_irqsave(&poll_aen_lock, flags);
@@ -2464,7 +2586,7 @@ static irqreturn_t megasas_isr(int irq, void *devp)
* states, driver must take steps to bring it to ready state. Otherwise, it
* has to wait for the ready state.
*/
-static int
+int
megasas_transition_to_ready(struct megasas_instance* instance)
{
int i;
@@ -2476,8 +2598,8 @@ megasas_transition_to_ready(struct megasas_instance* instance)
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
if (fw_state != MFI_STATE_READY)
- printk(KERN_INFO "megasas: Waiting for FW to come to ready"
- " state\n");
+ printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+ " state\n");
while (fw_state != MFI_STATE_READY) {
@@ -2498,11 +2620,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-
+ PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+ (instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_FUSION)) {
writel(
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
- &instance->reg_set->reserved_0[0]);
+ &instance->reg_set->doorbell);
} else {
writel(
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
@@ -2515,11 +2638,13 @@ megasas_transition_to_ready(struct megasas_instance* instance)
case MFI_STATE_BOOT_MESSAGE_PENDING:
if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+ (instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+ (instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_FUSION)) {
writel(MFI_INIT_HOTPLUG,
- &instance->reg_set->reserved_0[0]);
+ &instance->reg_set->doorbell);
} else
writel(MFI_INIT_HOTPLUG,
&instance->reg_set->inbound_doorbell);
@@ -2536,9 +2661,23 @@ megasas_transition_to_ready(struct megasas_instance* instance)
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
- PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+ PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+ (instance->pdev->device
+ == PCI_DEVICE_ID_LSI_FUSION)) {
writel(MFI_RESET_FLAGS,
- &instance->reg_set->reserved_0[0]);
+ &instance->reg_set->doorbell);
+ if (instance->pdev->device ==
+ PCI_DEVICE_ID_LSI_FUSION) {
+ for (i = 0; i < (10 * 1000); i += 20) {
+ if (readl(
+ &instance->
+ reg_set->
+ doorbell) & 1)
+ msleep(20);
+ else
+ break;
+ }
+ }
} else
writel(MFI_RESET_FLAGS,
&instance->reg_set->inbound_doorbell);
@@ -2590,7 +2729,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
* The cur_state should not last for more than max_wait secs
*/
for (i = 0; i < (max_wait * 1000); i++) {
- fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
+ fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
MFI_STATE_MASK ;
curr_abs_state =
instance->instancet->read_fw_status_reg(instance->reg_set);
@@ -2610,7 +2749,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
return -ENODEV;
}
}
- printk(KERN_INFO "megasas: FW now in Ready state\n");
+ printk(KERN_INFO "megasas: FW now in Ready state\n");
return 0;
}
@@ -2622,7 +2761,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
static void megasas_teardown_frame_pool(struct megasas_instance *instance)
{
int i;
- u32 max_cmd = instance->max_fw_cmds;
+ u32 max_cmd = instance->max_mfi_cmds;
struct megasas_cmd *cmd;
if (!instance->frame_dma_pool)
@@ -2673,7 +2812,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
u32 frame_count;
struct megasas_cmd *cmd;
- max_cmd = instance->max_fw_cmds;
+ max_cmd = instance->max_mfi_cmds;
/*
* Size of our frame is 64 bytes for MFI frame, followed by max SG
@@ -2760,14 +2899,15 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
* megasas_free_cmds - Free all the cmds in the free cmd pool
* @instance: Adapter soft state
*/
-static void megasas_free_cmds(struct megasas_instance *instance)
+void megasas_free_cmds(struct megasas_instance *instance)
{
int i;
/* First free the MFI frame pool */
megasas_teardown_frame_pool(instance);
/* Free all the commands in the cmd_list */
- for (i = 0; i < instance->max_fw_cmds; i++)
+ for (i = 0; i < instance->max_mfi_cmds; i++)
+
kfree(instance->cmd_list[i]);
/* Free the cmd_list buffer itself */
@@ -2795,14 +2935,14 @@ static void megasas_free_cmds(struct megasas_instance *instance)
* This array is used only to look up the megasas_cmd given the context. The
* free commands themselves are maintained in a linked list called cmd_pool.
*/
-static int megasas_alloc_cmds(struct megasas_instance *instance)
+int megasas_alloc_cmds(struct megasas_instance *instance)
{
int i;
int j;
u32 max_cmd;
struct megasas_cmd *cmd;
- max_cmd = instance->max_fw_cmds;
+ max_cmd = instance->max_mfi_cmds;
/*
* instance->cmd_list is an array of struct megasas_cmd pointers.
@@ -2816,6 +2956,7 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
return -ENOMEM;
}
+ memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
for (i = 0; i < max_cmd; i++) {
instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
@@ -3210,76 +3351,15 @@ megasas_io_completion_timer(unsigned long instance_addr)
jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
}
-/**
- * megasas_init_mfi - Initializes the FW
- * @instance: Adapter soft state
- *
- * This is the main function for initializing MFI firmware.
- */
-static int megasas_init_mfi(struct megasas_instance *instance)
+static u32
+megasas_init_adapter_mfi(struct megasas_instance *instance)
{
+ struct megasas_register_set __iomem *reg_set;
u32 context_sz;
u32 reply_q_sz;
- u32 max_sectors_1;
- u32 max_sectors_2;
- u32 tmp_sectors;
- struct megasas_register_set __iomem *reg_set;
- struct megasas_ctrl_info *ctrl_info;
- /*
- * Map the message registers
- */
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
- instance->base_addr = pci_resource_start(instance->pdev, 1);
- } else {
- instance->base_addr = pci_resource_start(instance->pdev, 0);
- }
-
- if (pci_request_selected_regions(instance->pdev,
- pci_select_bars(instance->pdev, IORESOURCE_MEM),
- "megasas: LSI")) {
- printk(KERN_DEBUG "megasas: IO memory region busy!\n");
- return -EBUSY;
- }
-
- instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
-
- if (!instance->reg_set) {
- printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
- goto fail_ioremap;
- }
reg_set = instance->reg_set;
- switch(instance->pdev->device)
- {
- case PCI_DEVICE_ID_LSI_SAS1078R:
- case PCI_DEVICE_ID_LSI_SAS1078DE:
- instance->instancet = &megasas_instance_template_ppc;
- break;
- case PCI_DEVICE_ID_LSI_SAS1078GEN2:
- case PCI_DEVICE_ID_LSI_SAS0079GEN2:
- instance->instancet = &megasas_instance_template_gen2;
- break;
- case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
- case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
- instance->instancet = &megasas_instance_template_skinny;
- break;
- case PCI_DEVICE_ID_LSI_SAS1064R:
- case PCI_DEVICE_ID_DELL_PERC5:
- default:
- instance->instancet = &megasas_instance_template_xscale;
- break;
- }
-
- /*
- * We expect the FW state to be READY
- */
- if (megasas_transition_to_ready(instance))
- goto fail_ready_state;
-
/*
* Get various operational parameters from status register
*/
@@ -3290,7 +3370,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
* does not exceed max cmds that the FW can support
*/
instance->max_fw_cmds = instance->max_fw_cmds-1;
- instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
+ instance->max_mfi_cmds = instance->max_fw_cmds;
+ instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
0x10;
/*
* Create a pool of commands
@@ -3333,6 +3414,90 @@ static int megasas_init_mfi(struct megasas_instance *instance)
if (instance->fw_support_ieee)
instance->flag_ieee = 1;
+ return 0;
+
+fail_fw_init:
+
+ pci_free_consistent(instance->pdev, reply_q_sz,
+ instance->reply_queue, instance->reply_queue_h);
+fail_reply_queue:
+ megasas_free_cmds(instance);
+
+fail_alloc_cmds:
+ iounmap(instance->reg_set);
+ return 1;
+}
+
+/**
+ * megasas_init_fw - Initializes the FW
+ * @instance: Adapter soft state
+ *
+ * This is the main function for initializing firmware
+ */
+
+static int megasas_init_fw(struct megasas_instance *instance)
+{
+ u32 max_sectors_1;
+ u32 max_sectors_2;
+ u32 tmp_sectors;
+ struct megasas_register_set __iomem *reg_set;
+ struct megasas_ctrl_info *ctrl_info;
+ unsigned long bar_list;
+
+ /* Find first memory bar */
+ bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
+ instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
+ instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
+ if (pci_request_selected_regions(instance->pdev, instance->bar,
+ "megasas: LSI")) {
+ printk(KERN_DEBUG "megasas: IO memory region busy!\n");
+ return -EBUSY;
+ }
+
+ instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+
+ if (!instance->reg_set) {
+ printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
+ goto fail_ioremap;
+ }
+
+ reg_set = instance->reg_set;
+
+ switch (instance->pdev->device) {
+ case PCI_DEVICE_ID_LSI_FUSION:
+ instance->instancet = &megasas_instance_template_fusion;
+ break;
+ case PCI_DEVICE_ID_LSI_SAS1078R:
+ case PCI_DEVICE_ID_LSI_SAS1078DE:
+ instance->instancet = &megasas_instance_template_ppc;
+ break;
+ case PCI_DEVICE_ID_LSI_SAS1078GEN2:
+ case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+ instance->instancet = &megasas_instance_template_gen2;
+ break;
+ case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+ case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+ instance->instancet = &megasas_instance_template_skinny;
+ break;
+ case PCI_DEVICE_ID_LSI_SAS1064R:
+ case PCI_DEVICE_ID_DELL_PERC5:
+ default:
+ instance->instancet = &megasas_instance_template_xscale;
+ break;
+ }
+
+ /*
+ * We expect the FW state to be READY
+ */
+ if (megasas_transition_to_ready(instance))
+ goto fail_ready_state;
+
+ /* Get operational params, sge flags, send init cmd to controller */
+ if (instance->instancet->init_adapter(instance))
+ return -ENODEV;
+
+ printk(KERN_ERR "megasas: INIT adapter done\n");
+
/** for passthrough
* the following function will get the PD LIST.
*/
@@ -3388,20 +3553,11 @@ static int megasas_init_mfi(struct megasas_instance *instance)
MEGASAS_COMPLETION_TIMER_INTERVAL);
return 0;
- fail_fw_init:
-
- pci_free_consistent(instance->pdev, reply_q_sz,
- instance->reply_queue, instance->reply_queue_h);
- fail_reply_queue:
- megasas_free_cmds(instance);
-
- fail_alloc_cmds:
- fail_ready_state:
+fail_ready_state:
iounmap(instance->reg_set);
fail_ioremap:
- pci_release_selected_regions(instance->pdev,
- pci_select_bars(instance->pdev, IORESOURCE_MEM));
+ pci_release_selected_regions(instance->pdev, instance->bar);
return -EINVAL;
}
@@ -3412,17 +3568,17 @@ static int megasas_init_mfi(struct megasas_instance *instance)
*/
static void megasas_release_mfi(struct megasas_instance *instance)
{
- u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1);
+ u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
- pci_free_consistent(instance->pdev, reply_q_sz,
+ if (instance->reply_queue)
+ pci_free_consistent(instance->pdev, reply_q_sz,
instance->reply_queue, instance->reply_queue_h);
megasas_free_cmds(instance);
iounmap(instance->reg_set);
- pci_release_selected_regions(instance->pdev,
- pci_select_bars(instance->pdev, IORESOURCE_MEM));
+ pci_release_selected_regions(instance->pdev, instance->bar);
}
/**
@@ -3609,8 +3765,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
/*
* Issue the aen registration frame
*/
- instance->instancet->fire_cmd(instance,
- cmd->frame_phys_addr, 0, instance->reg_set);
+ instance->instancet->issue_dcmd(instance, cmd);
return 0;
}
@@ -3687,12 +3842,18 @@ static int megasas_io_attach(struct megasas_instance *instance)
}
host->max_sectors = instance->max_sectors_per_req;
- host->cmd_per_lun = 128;
+ host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
host->max_channel = MEGASAS_MAX_CHANNELS - 1;
host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
host->max_lun = MEGASAS_MAX_LUN;
host->max_cmd_len = 16;
+ /* Fusion only supports host reset */
+ if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) {
+ host->hostt->eh_device_reset_handler = NULL;
+ host->hostt->eh_bus_reset_handler = NULL;
+ }
+
/*
* Notify the mid-layer about the new controller
*/
@@ -3733,7 +3894,7 @@ fail_set_dma_mask:
/**
* megasas_probe_one - PCI hotplug entry point
* @pdev: PCI device structure
- * @id: PCI ids of supported hotplugged adapter
+ * @id: PCI ids of supported hotplugged adapter
*/
static int __devinit
megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -3777,20 +3938,45 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
instance = (struct megasas_instance *)host->hostdata;
memset(instance, 0, sizeof(*instance));
atomic_set( &instance->fw_reset_no_pci_access, 0 );
+ instance->pdev = pdev;
- instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
- &instance->producer_h);
- instance->consumer = pci_alloc_consistent(pdev, sizeof(u32),
- &instance->consumer_h);
+ switch (instance->pdev->device) {
+ case PCI_DEVICE_ID_LSI_FUSION:
+ {
+ struct fusion_context *fusion;
+
+ instance->ctrl_context =
+ kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
+ if (!instance->ctrl_context) {
+ printk(KERN_DEBUG "megasas: Failed to allocate "
+ "memory for Fusion context info\n");
+ goto fail_alloc_dma_buf;
+ }
+ fusion = instance->ctrl_context;
+ INIT_LIST_HEAD(&fusion->cmd_pool);
+ spin_lock_init(&fusion->cmd_pool_lock);
+ }
+ break;
+ default: /* For all other supported controllers */
+
+ instance->producer =
+ pci_alloc_consistent(pdev, sizeof(u32),
+ &instance->producer_h);
+ instance->consumer =
+ pci_alloc_consistent(pdev, sizeof(u32),
+ &instance->consumer_h);
+
+ if (!instance->producer || !instance->consumer) {
+ printk(KERN_DEBUG "megasas: Failed to allocate"
+ "memory for producer, consumer\n");
+ goto fail_alloc_dma_buf;
+ }
- if (!instance->producer || !instance->consumer) {
- printk(KERN_DEBUG "megasas: Failed to allocate memory for "
- "producer, consumer\n");
- goto fail_alloc_dma_buf;
+ *instance->producer = 0;
+ *instance->consumer = 0;
+ break;
}
- *instance->producer = 0;
- *instance->consumer = 0;
megasas_poll_wait_aen = 0;
instance->flag_ieee = 0;
instance->ev = NULL;
@@ -3826,11 +4012,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&poll_aen_lock);
mutex_init(&instance->aen_mutex);
+ mutex_init(&instance->reset_mutex);
/*
* Initialize PCI related and misc parameters
*/
- instance->pdev = pdev;
instance->host = host;
instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
instance->init_id = MEGASAS_DEFAULT_INIT_ID;
@@ -3848,18 +4034,31 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
instance->last_time = 0;
instance->disableOnlineCtrlReset = 1;
- INIT_WORK(&instance->work_init, process_fw_state_change_wq);
+ if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)
+ INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
+ else
+ INIT_WORK(&instance->work_init, process_fw_state_change_wq);
/*
* Initialize MFI Firmware
*/
- if (megasas_init_mfi(instance))
+ if (megasas_init_fw(instance))
goto fail_init_mfi;
+ /* Try to enable MSI-X */
+ if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) &&
+ (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) &&
+ (instance->pdev->device != PCI_DEVICE_ID_LSI_VERDE_ZCR) &&
+ !msix_disable && !pci_enable_msix(instance->pdev,
+ &instance->msixentry, 1))
+ instance->msi_flag = 1;
+
/*
* Register IRQ
*/
- if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) {
+ if (request_irq(instance->msi_flag ? instance->msixentry.vector :
+ pdev->irq, instance->instancet->service_isr,
+ IRQF_SHARED, "megasas", instance)) {
printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
goto fail_irq;
}
@@ -3904,9 +4103,10 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, NULL);
instance->instancet->disable_intr(instance->reg_set);
- free_irq(instance->pdev->irq, instance);
-
- megasas_release_mfi(instance);
+ free_irq(instance->msi_flag ? instance->msixentry.vector :
+ instance->pdev->irq, instance);
+ if (instance->msi_flag)
+ pci_disable_msix(instance->pdev);
fail_irq:
fail_init_mfi:
@@ -3916,9 +4116,13 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
instance->evt_detail,
instance->evt_detail_h);
- if (instance->producer)
+ if (instance->producer) {
pci_free_consistent(pdev, sizeof(u32), instance->producer,
instance->producer_h);
+ megasas_release_mfi(instance);
+ } else {
+ megasas_release_fusion(instance);
+ }
if (instance->consumer)
pci_free_consistent(pdev, sizeof(u32), instance->consumer,
instance->consumer_h);
@@ -3990,7 +4194,9 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
if (instance->aen_cmd)
megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
-
+ if (instance->map_update_cmd)
+ megasas_issue_blocked_abort_cmd(instance,
+ instance->map_update_cmd);
dcmd = &cmd->frame->dcmd;
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -4046,7 +4252,10 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
pci_set_drvdata(instance->pdev, instance);
instance->instancet->disable_intr(instance->reg_set);
- free_irq(instance->pdev->irq, instance);
+ free_irq(instance->msi_flag ? instance->msixentry.vector :
+ instance->pdev->irq, instance);
+ if (instance->msi_flag)
+ pci_disable_msix(instance->pdev);
pci_save_state(pdev);
pci_disable_device(pdev);
@@ -4092,9 +4301,6 @@ megasas_resume(struct pci_dev *pdev)
* Initialize MFI Firmware
*/
- *instance->producer = 0;
- *instance->consumer = 0;
-
atomic_set(&instance->fw_outstanding, 0);
/*
@@ -4103,17 +4309,40 @@ megasas_resume(struct pci_dev *pdev)
if (megasas_transition_to_ready(instance))
goto fail_ready_state;
- if (megasas_issue_init_mfi(instance))
- goto fail_init_mfi;
+ switch (instance->pdev->device) {
+ case PCI_DEVICE_ID_LSI_FUSION:
+ {
+ megasas_reset_reply_desc(instance);
+ if (megasas_ioc_init_fusion(instance)) {
+ megasas_free_cmds(instance);
+ megasas_free_cmds_fusion(instance);
+ goto fail_init_mfi;
+ }
+ if (!megasas_get_map_info(instance))
+ megasas_sync_map_info(instance);
+ }
+ break;
+ default:
+ *instance->producer = 0;
+ *instance->consumer = 0;
+ if (megasas_issue_init_mfi(instance))
+ goto fail_init_mfi;
+ break;
+ }
- tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
- (unsigned long)instance);
+ tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
+ (unsigned long)instance);
+
+ /* Now re-enable MSI-X */
+ if (instance->msi_flag)
+ pci_enable_msix(instance->pdev, &instance->msixentry, 1);
/*
* Register IRQ
*/
- if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
- "megasas", instance)) {
+ if (request_irq(instance->msi_flag ? instance->msixentry.vector :
+ pdev->irq, instance->instancet->service_isr,
+ IRQF_SHARED, "megasas", instance)) {
printk(KERN_ERR "megasas: Failed to register IRQ\n");
goto fail_irq;
}
@@ -4171,10 +4400,12 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
int i;
struct Scsi_Host *host;
struct megasas_instance *instance;
+ struct fusion_context *fusion;
instance = pci_get_drvdata(pdev);
instance->unload = 1;
host = instance->host;
+ fusion = instance->ctrl_context;
if (poll_mode_io)
del_timer_sync(&instance->io_completion_timer);
@@ -4211,18 +4442,37 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
instance->instancet->disable_intr(instance->reg_set);
- free_irq(instance->pdev->irq, instance);
-
- megasas_release_mfi(instance);
-
- pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
- instance->evt_detail, instance->evt_detail_h);
-
- pci_free_consistent(pdev, sizeof(u32), instance->producer,
- instance->producer_h);
-
- pci_free_consistent(pdev, sizeof(u32), instance->consumer,
- instance->consumer_h);
+ free_irq(instance->msi_flag ? instance->msixentry.vector :
+ instance->pdev->irq, instance);
+ if (instance->msi_flag)
+ pci_disable_msix(instance->pdev);
+
+ switch (instance->pdev->device) {
+ case PCI_DEVICE_ID_LSI_FUSION:
+ megasas_release_fusion(instance);
+ for (i = 0; i < 2 ; i++)
+ if (fusion->ld_map[i])
+ dma_free_coherent(&instance->pdev->dev,
+ fusion->map_sz,
+ fusion->ld_map[i],
+ fusion->
+ ld_map_phys[i]);
+ kfree(instance->ctrl_context);
+ break;
+ default:
+ megasas_release_mfi(instance);
+ pci_free_consistent(pdev,
+ sizeof(struct megasas_evt_detail),
+ instance->evt_detail,
+ instance->evt_detail_h);
+ pci_free_consistent(pdev, sizeof(u32),
+ instance->producer,
+ instance->producer_h);
+ pci_free_consistent(pdev, sizeof(u32),
+ instance->consumer,
+ instance->consumer_h);
+ break;
+ }
scsi_host_put(host);
@@ -4986,6 +5236,7 @@ megasas_aen_polling(struct work_struct *work)
break;
case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
case MR_EVT_FOREIGN_CFG_IMPORTED:
+ case MR_EVT_LD_STATE_CHANGE:
doscan = 1;
break;
default:
@@ -5165,7 +5416,7 @@ err_dcf_attr_ver:
pci_unregister_driver(&megasas_pci_driver);
err_pcidrv:
unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
- return rval;
+ return rval;
}
/**
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
new file mode 100644
index 000000000000..53fa96ae2b3e
--- /dev/null
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -0,0 +1,516 @@
+/*
+ * Linux MegaRAID driver for SAS based RAID controllers
+ *
+ * Copyright (c) 2009-2011 LSI Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * FILE: megaraid_sas_fp.c
+ *
+ * Authors: LSI Corporation
+ * Sumant Patro
+ * Varad Talamacki
+ * Manoj Jose
+ *
+ * Send feedback to: <megaraidlinux@lsi.com>
+ *
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ * ATTN: Linuxraid
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+#include <linux/uio.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+#include <linux/blkdev.h>
+#include <linux/poll.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "megaraid_sas_fusion.h"
+#include <asm/div64.h>
+
+#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
+#define MR_LD_STATE_OPTIMAL 3
+#define FALSE 0
+#define TRUE 1
+
+/* Prototypes */
+void
+mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
+ struct LD_LOAD_BALANCE_INFO *lbInfo);
+
+u32 mega_mod64(u64 dividend, u32 divisor)
+{
+ u64 d;
+ u32 remainder;
+
+ if (!divisor)
+ printk(KERN_ERR "megasas : DIVISOR is zero, in div fn\n");
+ d = dividend;
+ remainder = do_div(d, divisor);
+ return remainder;
+}
+
+/**
+ * @param dividend : Dividend
+ * @param divisor : Divisor
+ *
+ * @return quotient
+ **/
+u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
+{
+ u32 remainder;
+ u64 d;
+
+ if (!divisor)
+ printk(KERN_ERR "megasas : DIVISOR is zero in mod fn\n");
+
+ d = dividend;
+ remainder = do_div(d, divisor);
+
+ return d;
+}
+
+struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return &map->raidMap.ldSpanMap[ld].ldRaid;
+}
+
+static struct MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u32 ld,
+ struct MR_FW_RAID_MAP_ALL
+ *map)
+{
+ return &map->raidMap.ldSpanMap[ld].spanBlock[0];
+}
+
+static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx];
+}
+
+static u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.arMapInfo[ar].pd[arm];
+}
+
+static u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef;
+}
+
+static u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.devHndlInfo[pd].curDevHdl;
+}
+
+u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.ldSpanMap[ld].ldRaid.targetId;
+}
+
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map)
+{
+ return map->raidMap.ldTgtIdToLd[ldTgtId];
+}
+
+static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span,
+ struct MR_FW_RAID_MAP_ALL *map)
+{
+ return &map->raidMap.ldSpanMap[ld].spanBlock[span].span;
+}
+
+/*
+ * This function will validate Map info data provided by FW
+ */
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+ struct LD_LOAD_BALANCE_INFO *lbInfo)
+{
+ struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap;
+
+ if (pFwRaidMap->totalSize !=
+ (sizeof(struct MR_FW_RAID_MAP) -sizeof(struct MR_LD_SPAN_MAP) +
+ (sizeof(struct MR_LD_SPAN_MAP) *pFwRaidMap->ldCount))) {
+ printk(KERN_ERR "megasas: map info structure size 0x%x is not matching with ld count\n",
+ (unsigned int)((sizeof(struct MR_FW_RAID_MAP) -
+ sizeof(struct MR_LD_SPAN_MAP)) +
+ (sizeof(struct MR_LD_SPAN_MAP) *
+ pFwRaidMap->ldCount)));
+ printk(KERN_ERR "megasas: span map %x, pFwRaidMap->totalSize "
+ ": %x\n", (unsigned int)sizeof(struct MR_LD_SPAN_MAP),
+ pFwRaidMap->totalSize);
+ return 0;
+ }
+
+ mr_update_load_balance_params(map, lbInfo);
+
+ return 1;
+}
+
+u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
+ struct MR_FW_RAID_MAP_ALL *map, int *div_error)
+{
+ struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
+ struct MR_QUAD_ELEMENT *quad;
+ struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
+ u32 span, j;
+
+ for (span = 0; span < raid->spanDepth; span++, pSpanBlock++) {
+
+ for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) {
+ quad = &pSpanBlock->block_span_info.quad[j];
+
+ if (quad->diff == 0) {
+ *div_error = 1;
+ return span;
+ }
+ if (quad->logStart <= row && row <= quad->logEnd &&
+ (mega_mod64(row-quad->logStart, quad->diff)) == 0) {
+ if (span_blk != NULL) {
+ u64 blk, debugBlk;
+ blk =
+ mega_div64_32(
+ (row-quad->logStart),
+ quad->diff);
+ debugBlk = blk;
+
+ blk = (blk + quad->offsetInSpan) <<
+ raid->stripeShift;
+ *span_blk = blk;
+ }
+ return span;
+ }
+ }
+ }
+ return span;
+}
+
+/*
+******************************************************************************
+*
+* This routine calculates the arm, span and block for the specified stripe and
+* reference in stripe.
+*
+* Inputs :
+*
+* ld - Logical drive number
+* stripRow - Stripe number
+* stripRef - Reference in stripe
+*
+* Outputs :
+*
+* span - Span number
+* block - Absolute Block number in the physical disk
+*/
+u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock,
+ u16 *pDevHandle, struct RAID_CONTEXT *pRAID_Context,
+ struct MR_FW_RAID_MAP_ALL *map)
+{
+ struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
+ u32 pd, arRef;
+ u8 physArm, span;
+ u64 row;
+ u8 retval = TRUE;
+ int error_code = 0;
+
+ row = mega_div64_32(stripRow, raid->rowDataSize);
+
+ if (raid->level == 6) {
+ /* logical arm within row */
+ u32 logArm = mega_mod64(stripRow, raid->rowDataSize);
+ u32 rowMod, armQ, arm;
+
+ if (raid->rowSize == 0)
+ return FALSE;
+ /* get logical row mod */
+ rowMod = mega_mod64(row, raid->rowSize);
+ armQ = raid->rowSize-1-rowMod; /* index of Q drive */
+ arm = armQ+1+logArm; /* data always logically follows Q */
+ if (arm >= raid->rowSize) /* handle wrap condition */
+ arm -= raid->rowSize;
+ physArm = (u8)arm;
+ } else {
+ if (raid->modFactor == 0)
+ return FALSE;
+ physArm = MR_LdDataArmGet(ld, mega_mod64(stripRow,
+ raid->modFactor),
+ map);
+ }
+
+ if (raid->spanDepth == 1) {
+ span = 0;
+ *pdBlock = row << raid->stripeShift;
+ } else {
+ span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
+ if (error_code == 1)
+ return FALSE;
+ }
+
+ /* Get the array on which this span is present */
+ arRef = MR_LdSpanArrayGet(ld, span, map);
+ pd = MR_ArPdGet(arRef, physArm, map); /* Get the pd */
+
+ if (pd != MR_PD_INVALID)
+ /* Get dev handle from Pd. */
+ *pDevHandle = MR_PdDevHandleGet(pd, map);
+ else {
+ *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
+ if (raid->level >= 5)
+ pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+ else if (raid->level == 1) {
+ /* Get alternate Pd. */
+ pd = MR_ArPdGet(arRef, physArm + 1, map);
+ if (pd != MR_PD_INVALID)
+ /* Get dev handle from Pd */
+ *pDevHandle = MR_PdDevHandleGet(pd, map);
+ }
+ retval = FALSE;
+ }
+
+ *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
+ pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
+ physArm;
+ return retval;
+}
+
+/*
+******************************************************************************
+*
+* MR_BuildRaidContext function
+*
+* This function will initiate command processing. The start/end row and strip
+* information is calculated then the lock is acquired.
+* This function will return 0 if region lock was acquired OR return num strips
+*/
+u8
+MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
+ struct RAID_CONTEXT *pRAID_Context,
+ struct MR_FW_RAID_MAP_ALL *map)
+{
+ struct MR_LD_RAID *raid;
+ u32 ld, stripSize, stripe_mask;
+ u64 endLba, endStrip, endRow, start_row, start_strip;
+ u64 regStart;
+ u32 regSize;
+ u8 num_strips, numRows;
+ u16 ref_in_start_stripe, ref_in_end_stripe;
+ u64 ldStartBlock;
+ u32 numBlocks, ldTgtId;
+ u8 isRead;
+ u8 retval = 0;
+
+ ldStartBlock = io_info->ldStartBlock;
+ numBlocks = io_info->numBlocks;
+ ldTgtId = io_info->ldTgtId;
+ isRead = io_info->isRead;
+
+ ld = MR_TargetIdToLdGet(ldTgtId, map);
+ raid = MR_LdRaidGet(ld, map);
+
+ stripSize = 1 << raid->stripeShift;
+ stripe_mask = stripSize-1;
+ /*
+ * calculate starting row and stripe, and number of strips and rows
+ */
+ start_strip = ldStartBlock >> raid->stripeShift;
+ ref_in_start_stripe = (u16)(ldStartBlock & stripe_mask);
+ endLba = ldStartBlock + numBlocks - 1;
+ ref_in_end_stripe = (u16)(endLba & stripe_mask);
+ endStrip = endLba >> raid->stripeShift;
+ num_strips = (u8)(endStrip - start_strip + 1); /* End strip */
+ if (raid->rowDataSize == 0)
+ return FALSE;
+ start_row = mega_div64_32(start_strip, raid->rowDataSize);
+ endRow = mega_div64_32(endStrip, raid->rowDataSize);
+ numRows = (u8)(endRow - start_row + 1);
+
+ /*
+ * calculate region info.
+ */
+
+ /* assume region is at the start of the first row */
+ regStart = start_row << raid->stripeShift;
+ /* assume this IO needs the full row - we'll adjust if not true */
+ regSize = stripSize;
+
+ /* If IO spans more than 1 strip, fp is not possible
+ FP is not possible for writes on non-0 raid levels
+ FP is not possible if LD is not capable */
+ if (num_strips > 1 || (!isRead && raid->level != 0) ||
+ !raid->capability.fpCapable) {
+ io_info->fpOkForIo = FALSE;
+ } else {
+ io_info->fpOkForIo = TRUE;
+ }
+
+ if (numRows == 1) {
+ /* single-strip IOs can always lock only the data needed */
+ if (num_strips == 1) {
+ regStart += ref_in_start_stripe;
+ regSize = numBlocks;
+ }
+ /* multi-strip IOs always need to full stripe locked */
+ } else {
+ if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
+ /* If the start strip is the last in the start row */
+ regStart += ref_in_start_stripe;
+ regSize = stripSize - ref_in_start_stripe;
+ /* initialize count to sectors from startref to end
+ of strip */
+ }
+
+ if (numRows > 2)
+ /* Add complete rows in the middle of the transfer */
+ regSize += (numRows-2) << raid->stripeShift;
+
+ /* if IO ends within first strip of last row */
+ if (endStrip == endRow*raid->rowDataSize)
+ regSize += ref_in_end_stripe+1;
+ else
+ regSize += stripSize;
+ }
+
+ pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec;
+ pRAID_Context->regLockFlags = (isRead) ? REGION_TYPE_SHARED_READ :
+ raid->regTypeReqOnWrite;
+ pRAID_Context->VirtualDiskTgtId = raid->targetId;
+ pRAID_Context->regLockRowLBA = regStart;
+ pRAID_Context->regLockLength = regSize;
+ pRAID_Context->configSeqNum = raid->seqNum;
+
+ /*Get Phy Params only if FP capable, or else leave it to MR firmware
+ to do the calculation.*/
+ if (io_info->fpOkForIo) {
+ retval = MR_GetPhyParams(ld, start_strip, ref_in_start_stripe,
+ &io_info->pdBlock,
+ &io_info->devHandle, pRAID_Context,
+ map);
+ /* If IO on an invalid Pd, then FP i snot possible */
+ if (io_info->devHandle == MR_PD_INVALID)
+ io_info->fpOkForIo = FALSE;
+ return retval;
+ } else if (isRead) {
+ uint stripIdx;
+ for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
+ if (!MR_GetPhyParams(ld, start_strip + stripIdx,
+ ref_in_start_stripe,
+ &io_info->pdBlock,
+ &io_info->devHandle,
+ pRAID_Context, map))
+ return TRUE;
+ }
+ }
+ return TRUE;
+}
+
+void
+mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
+ struct LD_LOAD_BALANCE_INFO *lbInfo)
+{
+ int ldCount;
+ u16 ld;
+ struct MR_LD_RAID *raid;
+
+ for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
+ ld = MR_TargetIdToLdGet(ldCount, map);
+ if (ld >= MAX_LOGICAL_DRIVES) {
+ lbInfo[ldCount].loadBalanceFlag = 0;
+ continue;
+ }
+
+ raid = MR_LdRaidGet(ld, map);
+
+ /* Two drive Optimal RAID 1 */
+ if ((raid->level == 1) && (raid->rowSize == 2) &&
+ (raid->spanDepth == 1) && raid->ldState ==
+ MR_LD_STATE_OPTIMAL) {
+ u32 pd, arRef;
+
+ lbInfo[ldCount].loadBalanceFlag = 1;
+
+ /* Get the array on which this span is present */
+ arRef = MR_LdSpanArrayGet(ld, 0, map);
+
+ /* Get the Pd */
+ pd = MR_ArPdGet(arRef, 0, map);
+ /* Get dev handle from Pd */
+ lbInfo[ldCount].raid1DevHandle[0] =
+ MR_PdDevHandleGet(pd, map);
+ /* Get the Pd */
+ pd = MR_ArPdGet(arRef, 1, map);
+
+ /* Get the dev handle from Pd */
+ lbInfo[ldCount].raid1DevHandle[1] =
+ MR_PdDevHandleGet(pd, map);
+ } else
+ lbInfo[ldCount].loadBalanceFlag = 0;
+ }
+}
+
+u8 megasas_get_best_arm(struct LD_LOAD_BALANCE_INFO *lbInfo, u8 arm, u64 block,
+ u32 count)
+{
+ u16 pend0, pend1;
+ u64 diff0, diff1;
+ u8 bestArm;
+
+ /* get the pending cmds for the data and mirror arms */
+ pend0 = atomic_read(&lbInfo->scsi_pending_cmds[0]);
+ pend1 = atomic_read(&lbInfo->scsi_pending_cmds[1]);
+
+ /* Determine the disk whose head is nearer to the req. block */
+ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
+ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
+ bestArm = (diff0 <= diff1 ? 0 : 1);
+
+ if ((bestArm == arm && pend0 > pend1 + 16) ||
+ (bestArm != arm && pend1 > pend0 + 16))
+ bestArm ^= 1;
+
+ /* Update the last accessed block on the correct pd */
+ lbInfo->last_accessed_block[bestArm] = block + count - 1;
+
+ return bestArm;
+}
+
+u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
+ struct IO_REQUEST_INFO *io_info)
+{
+ u8 arm, old_arm;
+ u16 devHandle;
+
+ old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+
+ /* get best new arm */
+ arm = megasas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock,
+ io_info->numBlocks);
+ devHandle = lbInfo->raid1DevHandle[arm];
+ atomic_inc(&lbInfo->scsi_pending_cmds[arm]);
+
+ return devHandle;
+}
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
new file mode 100644
index 000000000000..c1e09d5a6196
--- /dev/null
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -0,0 +1,2248 @@
+/*
+ * Linux MegaRAID driver for SAS based RAID controllers
+ *
+ * Copyright (c) 2009-2011 LSI Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * FILE: megaraid_sas_fusion.c
+ *
+ * Authors: LSI Corporation
+ * Sumant Patro
+ * Adam Radford <linuxraid@lsi.com>
+ *
+ * Send feedback to: <megaraidlinux@lsi.com>
+ *
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ * ATTN: Linuxraid
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+#include <linux/uio.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+#include <linux/blkdev.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "megaraid_sas_fusion.h"
+#include "megaraid_sas.h"
+
+extern void megasas_free_cmds(struct megasas_instance *instance);
+extern struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+ *instance);
+extern void
+megasas_complete_cmd(struct megasas_instance *instance,
+ struct megasas_cmd *cmd, u8 alt_status);
+int megasas_is_ldio(struct scsi_cmnd *cmd);
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
+
+void
+megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd);
+int megasas_alloc_cmds(struct megasas_instance *instance);
+int
+megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs);
+int
+megasas_issue_polled(struct megasas_instance *instance,
+ struct megasas_cmd *cmd);
+
+u8
+MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
+ struct RAID_CONTEXT *pRAID_Context,
+ struct MR_FW_RAID_MAP_ALL *map);
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map);
+struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
+
+u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+ struct LD_LOAD_BALANCE_INFO *lbInfo);
+u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
+ struct IO_REQUEST_INFO *in_info);
+int megasas_transition_to_ready(struct megasas_instance *instance);
+void megaraid_sas_kill_hba(struct megasas_instance *instance);
+
+extern u32 megasas_dbg_lvl;
+
+/**
+ * megasas_enable_intr_fusion - Enables interrupts
+ * @regs: MFI register set
+ */
+void
+megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+ writel(~MFI_FUSION_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+ /* Dummy readl to force pci flush */
+ readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_fusion - Disables interrupt
+ * @regs: MFI register set
+ */
+void
+megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+ u32 mask = 0xFFFFFFFF;
+ u32 status;
+
+ writel(mask, &regs->outbound_intr_mask);
+ /* Dummy readl to force pci flush */
+ status = readl(&regs->outbound_intr_mask);
+}
+
+int
+megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+ u32 status;
+ /*
+ * Check if it is our interrupt
+ */
+ status = readl(&regs->outbound_intr_status);
+
+ if (status & 1) {
+ writel(status, &regs->outbound_intr_status);
+ readl(&regs->outbound_intr_status);
+ return 1;
+ }
+ if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK))
+ return 0;
+
+ /*
+ * dummy read to flush PCI
+ */
+ readl(&regs->outbound_intr_status);
+
+ return 1;
+}
+
+/**
+ * megasas_get_cmd_fusion - Get a command from the free pool
+ * @instance: Adapter soft state
+ *
+ * Returns a free command from the pool
+ */
+struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
+ *instance)
+{
+ unsigned long flags;
+ struct fusion_context *fusion =
+ (struct fusion_context *)instance->ctrl_context;
+ struct megasas_cmd_fusion *cmd = NULL;
+
+ spin_lock_irqsave(&fusion->cmd_pool_lock, flags);
+
+ if (!list_empty(&fusion->cmd_pool)) {
+ cmd = list_entry((&fusion->cmd_pool)->next,
+ struct megasas_cmd_fusion, list);
+ list_del_init(&cmd->list);
+ } else {
+ printk(KERN_ERR "megasas: Command pool (fusion) empty!\n");
+ }
+
+ spin_unlock_irqrestore(&fusion->cmd_pool_lock, flags);
+ return cmd;
+}
+
+/**
+ * megasas_return_cmd_fusion - Return a cmd to free command pool
+ * @instance: Adapter soft state
+ * @cmd: Command packet to be returned to free command pool
+ */
+static inline void
+megasas_return_cmd_fusion(struct megasas_instance *instance,
+ struct megasas_cmd_fusion *cmd)
+{
+ unsigned long flags;
+ struct fusion_context *fusion =
+ (struct fusion_context *)instance->ctrl_context;
+
+ spin_lock_irqsave(&fusion->cmd_pool_lock, flags);
+
+ cmd->scmd = NULL;
+ cmd->sync_cmd_idx = (u32)ULONG_MAX;
+ list_add_tail(&cmd->list, &fusion->cmd_pool);
+
+ spin_unlock_irqrestore(&fusion->cmd_pool_lock, flags);
+}
+
+/**
+ * megasas_teardown_frame_pool_fusion - Destroy the cmd frame DMA pool
+ * @instance: Adapter soft state
+ */
+static void megasas_teardown_frame_pool_fusion(
+ struct megasas_instance *instance)
+{
+ int i;
+ struct fusion_context *fusion = instance->ctrl_context;
+
+ u16 max_cmd = instance->max_fw_cmds;
+
+ struct megasas_cmd_fusion *cmd;
+
+ if (!fusion->sg_dma_pool || !fusion->sense_dma_pool) {
+ printk(KERN_ERR "megasas: dma pool is null. SG Pool %p, "
+ "sense pool : %p\n", fusion->sg_dma_pool,
+ fusion->sense_dma_pool);
+ return;
+ }
+
+ /*
+ * Return all frames to pool
+ */
+ for (i = 0; i < max_cmd; i++) {
+
+ cmd = fusion->cmd_list[i];
+
+ if (cmd->sg_frame)
+ pci_pool_free(fusion->sg_dma_pool, cmd->sg_frame,
+ cmd->sg_frame_phys_addr);
+
+ if (cmd->sense)
+ pci_pool_free(fusion->sense_dma_pool, cmd->sense,
+ cmd->sense_phys_addr);
+ }
+
+ /*
+ * Now destroy the pool itself
+ */
+ pci_pool_destroy(fusion->sg_dma_pool);
+ pci_pool_destroy(fusion->sense_dma_pool);
+
+ fusion->sg_dma_pool = NULL;
+ fusion->sense_dma_pool = NULL;
+}
+
+/**
+ * megasas_free_cmds_fusion - Free all the cmds in the free cmd pool
+ * @instance: Adapter soft state
+ */
+void
+megasas_free_cmds_fusion(struct megasas_instance *instance)
+{
+ int i;
+ struct fusion_context *fusion = instance->ctrl_context;
+
+ u32 max_cmds, req_sz, reply_sz, io_frames_sz;
+
+
+ req_sz = fusion->request_alloc_sz;
+ reply_sz = fusion->reply_alloc_sz;
+ io_frames_sz = fusion->io_frames_alloc_sz;
+
+ max_cmds = instance->max_fw_cmds;
+
+ /* Free descriptors and request Frames memory */
+ if (fusion->req_frames_desc)
+ dma_free_coherent(&instance->pdev->dev, req_sz,
+ fusion->req_frames_desc,
+ fusion->req_frames_desc_phys);
+
+ if (fusion->reply_frames_desc) {
+ pci_pool_free(fusion->reply_frames_desc_pool,
+ fusion->reply_frames_desc,
+ fusion->reply_frames_desc_phys);
+ pci_pool_destroy(fusion->reply_frames_desc_pool);
+ }
+
+ if (fusion->io_request_frames) {
+ pci_pool_free(fusion->io_request_frames_pool,
+ fusion->io_request_frames,
+ fusion->io_request_frames_phys);
+ pci_pool_destroy(fusion->io_request_frames_pool);
+ }
+
+ /* Free the Fusion frame pool */
+ megasas_teardown_frame_pool_fusion(instance);
+
+ /* Free all the commands in the cmd_list */
+ for (i = 0; i < max_cmds; i++)
+ kfree(fusion->cmd_list[i]);
+
+ /* Free the cmd_list buffer itself */
+ kfree(fusion->cmd_list);
+ fusion->cmd_list = NULL;
+
+ INIT_LIST_HEAD(&fusion->cmd_pool);
+}
+
+/**
+ * megasas_create_frame_pool_fusion - Creates DMA pool for cmd frames
+ * @instance: Adapter soft state
+ *
+ */
+static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
+{
+ int i;
+ u32 max_cmd;
+ struct fusion_context *fusion;
+ struct megasas_cmd_fusion *cmd;
+ u32 total_sz_chain_frame;
+
+ fusion = instance->ctrl_context;
+ max_cmd = instance->max_fw_cmds;
+
+ total_sz_chain_frame = MEGASAS_MAX_SZ_CHAIN_FRAME;
+
+ /*
+ * Use DMA pool facility provided by PCI layer
+ */
+
+ fusion->sg_dma_pool = pci_pool_create("megasas sg pool fusion",
+ instance->pdev,
+ total_sz_chain_frame, 4,
+ 0);
+ if (!fusion->sg_dma_pool) {
+ printk(KERN_DEBUG "megasas: failed to setup request pool "
+ "fusion\n");
+ return -ENOMEM;
+ }
+ fusion->sense_dma_pool = pci_pool_create("megasas sense pool fusion",
+ instance->pdev,
+ SCSI_SENSE_BUFFERSIZE, 64, 0);
+
+ if (!fusion->sense_dma_pool) {
+ printk(KERN_DEBUG "megasas: failed to setup sense pool "
+ "fusion\n");
+ pci_pool_destroy(fusion->sg_dma_pool);
+ fusion->sg_dma_pool = NULL;
+ return -ENOMEM;
+ }
+
+ /*
+ * Allocate and attach a frame to each of the commands in cmd_list
+ */
+ for (i = 0; i < max_cmd; i++) {
+
+ cmd = fusion->cmd_list[i];
+
+ cmd->sg_frame = pci_pool_alloc(fusion->sg_dma_pool,
+ GFP_KERNEL,
+ &cmd->sg_frame_phys_addr);
+
+ cmd->sense = pci_pool_alloc(fusion->sense_dma_pool,
+ GFP_KERNEL, &cmd->sense_phys_addr);
+ /*
+ * megasas_teardown_frame_pool_fusion() takes care of freeing
+ * whatever has been allocated
+ */
+ if (!cmd->sg_frame || !cmd->sense) {
+ printk(KERN_DEBUG "megasas: pci_pool_alloc failed\n");
+ megasas_teardown_frame_pool_fusion(instance);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+/**
+ * megasas_alloc_cmds_fusion - Allocates the command packets
+ * @instance: Adapter soft state
+ *
+ *
+ * Each frame has a 32-bit field called context. This context is used to get
+ * back the megasas_cmd_fusion from the frame when a frame gets completed
+ * In this driver, the 32 bit values are the indices into an array cmd_list.
+ * This array is used only to look up the megasas_cmd_fusion given the context.
+ * The free commands themselves are maintained in a linked list called cmd_pool.
+ *
+ * cmds are formed in the io_request and sg_frame members of the
+ * megasas_cmd_fusion. The context field is used to get a request descriptor
+ * and is used as SMID of the cmd.
+ * SMID value range is from 1 to max_fw_cmds.
+ */
+int
+megasas_alloc_cmds_fusion(struct megasas_instance *instance)
+{
+ int i, j;
+ u32 max_cmd, io_frames_sz;
+ struct fusion_context *fusion;
+ struct megasas_cmd_fusion *cmd;
+ union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+ u32 offset;
+ dma_addr_t io_req_base_phys;
+ u8 *io_req_base;
+
+ fusion = instance->ctrl_context;
+
+ max_cmd = instance->max_fw_cmds;
+
+ fusion->req_frames_desc =
+ dma_alloc_coherent(&instance->pdev->dev,
+ fusion->request_alloc_sz,
+ &fusion->req_frames_desc_phys, GFP_KERNEL);
+
+ if (!fusion->req_frames_desc) {
+ printk(KERN_ERR "megasas; Could not allocate memory for "
+ "request_frames\n");
+ goto fail_req_desc;
+ }
+
+ fusion->reply_frames_desc_pool =
+ pci_pool_create("reply_frames pool", instance->pdev,
+ fusion->reply_alloc_sz, 16, 0);
+
+ if (!fusion->reply_frames_desc_pool) {
+ printk(KERN_ERR "megasas; Could not allocate memory for "
+ "reply_frame pool\n");
+ goto fail_reply_desc;
+ }
+
+ fusion->reply_frames_desc =
+ pci_pool_alloc(fusion->reply_frames_desc_pool, GFP_KERNEL,
+ &fusion->reply_frames_desc_phys);
+ if (!fusion->reply_frames_desc) {
+ printk(KERN_ERR "megasas; Could not allocate memory for "
+ "reply_frame pool\n");
+ pci_pool_destroy(fusion->reply_frames_desc_pool);
+ goto fail_reply_desc;
+ }
+
+ reply_desc = fusion->reply_frames_desc;
+ for (i = 0; i < fusion->reply_q_depth; i++, reply_desc++)
+ reply_desc->Words = ULLONG_MAX;
+
+ io_frames_sz = fusion->io_frames_alloc_sz;
+
+ fusion->io_request_frames_pool =
+ pci_pool_create("io_request_frames pool", instance->pdev,
+ fusion->io_frames_alloc_sz, 16, 0);
+
+ if (!fusion->io_request_frames_pool) {
+ printk(KERN_ERR "megasas: Could not allocate memory for "
+ "io_request_frame pool\n");
+ goto fail_io_frames;
+ }
+
+ fusion->io_request_frames =
+ pci_pool_alloc(fusion->io_request_frames_pool, GFP_KERNEL,
+ &fusion->io_request_frames_phys);
+ if (!fusion->io_request_frames) {
+ printk(KERN_ERR "megasas: Could not allocate memory for "
+ "io_request_frames frames\n");
+ pci_pool_destroy(fusion->io_request_frames_pool);
+ goto fail_io_frames;
+ }
+
+ /*
+ * fusion->cmd_list is an array of struct megasas_cmd_fusion pointers.
+ * Allocate the dynamic array first and then allocate individual
+ * commands.
+ */
+ fusion->cmd_list = kmalloc(sizeof(struct megasas_cmd_fusion *)
+ *max_cmd, GFP_KERNEL);
+
+ if (!fusion->cmd_list) {
+ printk(KERN_DEBUG "megasas: out of memory. Could not alloc "
+ "memory for cmd_list_fusion\n");
+ goto fail_cmd_list;
+ }
+
+ memset(fusion->cmd_list, 0, sizeof(struct megasas_cmd_fusion *)
+ *max_cmd);
+
+ max_cmd = instance->max_fw_cmds;
+ for (i = 0; i < max_cmd; i++) {
+ fusion->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd_fusion),
+ GFP_KERNEL);
+ if (!fusion->cmd_list[i]) {
+ printk(KERN_ERR "Could not alloc cmd list fusion\n");
+
+ for (j = 0; j < i; j++)
+ kfree(fusion->cmd_list[j]);
+
+ kfree(fusion->cmd_list);
+ fusion->cmd_list = NULL;
+ goto fail_cmd_list;
+ }
+ }
+
+ /* The first 256 bytes (SMID 0) is not used. Don't add to cmd list */
+ io_req_base = fusion->io_request_frames +
+ MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+ io_req_base_phys = fusion->io_request_frames_phys +
+ MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+
+ /*
+ * Add all the commands to command pool (fusion->cmd_pool)
+ */
+
+ /* SMID 0 is reserved. Set SMID/index from 1 */
+ for (i = 0; i < max_cmd; i++) {
+ cmd = fusion->cmd_list[i];
+ offset = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
+ memset(cmd, 0, sizeof(struct megasas_cmd_fusion));
+ cmd->index = i + 1;
+ cmd->scmd = NULL;
+ cmd->sync_cmd_idx = (u32)ULONG_MAX; /* Set to Invalid */
+ cmd->instance = instance;
+ cmd->io_request =
+ (struct MPI2_RAID_SCSI_IO_REQUEST *)
+ (io_req_base + offset);
+ memset(cmd->io_request, 0,
+ sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
+ cmd->io_request_phys_addr = io_req_base_phys + offset;
+
+ list_add_tail(&cmd->list, &fusion->cmd_pool);
+ }
+
+ /*
+ * Create a frame pool and assign one frame to each cmd
+ */
+ if (megasas_create_frame_pool_fusion(instance)) {
+ printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
+ megasas_free_cmds_fusion(instance);
+ goto fail_req_desc;
+ }
+
+ return 0;
+
+fail_cmd_list:
+ pci_pool_free(fusion->io_request_frames_pool, fusion->io_request_frames,
+ fusion->io_request_frames_phys);
+ pci_pool_destroy(fusion->io_request_frames_pool);
+fail_io_frames:
+ dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
+ fusion->reply_frames_desc,
+ fusion->reply_frames_desc_phys);
+ pci_pool_free(fusion->reply_frames_desc_pool,
+ fusion->reply_frames_desc,
+ fusion->reply_frames_desc_phys);
+ pci_pool_destroy(fusion->reply_frames_desc_pool);
+
+fail_reply_desc:
+ dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
+ fusion->req_frames_desc,
+ fusion->req_frames_desc_phys);
+fail_req_desc:
+ return -ENOMEM;
+}
+
+/**
+ * wait_and_poll - Issues a polling command
+ * @instance: Adapter soft state
+ * @cmd: Command packet to be issued
+ *
+ * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
+ */
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ int i;
+ struct megasas_header *frame_hdr = &cmd->frame->hdr;
+
+ u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
+
+ /*
+ * Wait for cmd_status to change
+ */
+ for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i += 20) {
+ rmb();
+ msleep(20);
+ }
+
+ if (frame_hdr->cmd_status == 0xff)
+ return -ETIME;
+
+ return 0;
+}
+
+/**
+ * megasas_ioc_init_fusion - Initializes the FW
+ * @instance: Adapter soft state
+ *
+ * Issues the IOC Init cmd
+ */
+int
+megasas_ioc_init_fusion(struct megasas_instance *instance)
+{
+ struct megasas_init_frame *init_frame;
+ struct MPI2_IOC_INIT_REQUEST *IOCInitMessage;
+ dma_addr_t ioc_init_handle;
+ u32 context;
+ struct megasas_cmd *cmd;
+ u8 ret;
+ struct fusion_context *fusion;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ int i;
+ struct megasas_header *frame_hdr;
+
+ fusion = instance->ctrl_context;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ printk(KERN_ERR "Could not allocate cmd for INIT Frame\n");
+ ret = 1;
+ goto fail_get_cmd;
+ }
+
+ IOCInitMessage =
+ dma_alloc_coherent(&instance->pdev->dev,
+ sizeof(struct MPI2_IOC_INIT_REQUEST),
+ &ioc_init_handle, GFP_KERNEL);
+
+ if (!IOCInitMessage) {
+ printk(KERN_ERR "Could not allocate memory for "
+ "IOCInitMessage\n");
+ ret = 1;
+ goto fail_fw_init;
+ }
+
+ memset(IOCInitMessage, 0, sizeof(struct MPI2_IOC_INIT_REQUEST));
+
+ IOCInitMessage->Function = MPI2_FUNCTION_IOC_INIT;
+ IOCInitMessage->WhoInit = MPI2_WHOINIT_HOST_DRIVER;
+ IOCInitMessage->MsgVersion = MPI2_VERSION;
+ IOCInitMessage->HeaderVersion = MPI2_HEADER_VERSION;
+ IOCInitMessage->SystemRequestFrameSize =
+ MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE / 4;
+
+ IOCInitMessage->ReplyDescriptorPostQueueDepth = fusion->reply_q_depth;
+ IOCInitMessage->ReplyDescriptorPostQueueAddress =
+ fusion->reply_frames_desc_phys;
+ IOCInitMessage->SystemRequestFrameBaseAddress =
+ fusion->io_request_frames_phys;
+
+ init_frame = (struct megasas_init_frame *)cmd->frame;
+ memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
+
+ frame_hdr = &cmd->frame->hdr;
+ context = init_frame->context;
+ init_frame->context = context;
+
+ frame_hdr->cmd_status = 0xFF;
+ frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+
+ init_frame->cmd = MFI_CMD_INIT;
+ init_frame->cmd_status = 0xFF;
+
+ init_frame->queue_info_new_phys_addr_lo = ioc_init_handle;
+ init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST);
+
+ req_desc =
+ (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)fusion->req_frames_desc;
+
+ req_desc->Words = cmd->frame_phys_addr;
+ req_desc->MFAIo.RequestFlags =
+ (MEGASAS_REQ_DESCRIPT_FLAGS_MFA <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+
+ /*
+ * disable the intr before firing the init frame
+ */
+ instance->instancet->disable_intr(instance->reg_set);
+
+ for (i = 0; i < (10 * 1000); i += 20) {
+ if (readl(&instance->reg_set->doorbell) & 1)
+ msleep(20);
+ else
+ break;
+ }
+
+ instance->instancet->fire_cmd(instance, req_desc->u.low,
+ req_desc->u.high, instance->reg_set);
+
+ wait_and_poll(instance, cmd);
+
+ frame_hdr = &cmd->frame->hdr;
+ if (frame_hdr->cmd_status != 0) {
+ ret = 1;
+ goto fail_fw_init;
+ }
+ printk(KERN_ERR "megasas:IOC Init cmd success\n");
+
+ ret = 0;
+
+fail_fw_init:
+ megasas_return_cmd(instance, cmd);
+ if (IOCInitMessage)
+ dma_free_coherent(&instance->pdev->dev,
+ sizeof(struct MPI2_IOC_INIT_REQUEST),
+ IOCInitMessage, ioc_init_handle);
+fail_get_cmd:
+ return ret;
+}
+
+/*
+ * megasas_return_cmd_for_smid - Returns a cmd_fusion for a SMID
+ * @instance: Adapter soft state
+ *
+ */
+void
+megasas_return_cmd_for_smid(struct megasas_instance *instance, u16 smid)
+{
+ struct fusion_context *fusion;
+ struct megasas_cmd_fusion *cmd;
+
+ fusion = instance->ctrl_context;
+ cmd = fusion->cmd_list[smid - 1];
+ megasas_return_cmd_fusion(instance, cmd);
+}
+
+/*
+ * megasas_get_ld_map_info - Returns FW's ld_map structure
+ * @instance: Adapter soft state
+ * @pend: Pend the command or not
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure. This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_ld_map_info(struct megasas_instance *instance)
+{
+ int ret = 0;
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ struct MR_FW_RAID_MAP_ALL *ci;
+ dma_addr_t ci_h = 0;
+ u32 size_map_info;
+ struct fusion_context *fusion;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ printk(KERN_DEBUG "megasas: Failed to get cmd for map info.\n");
+ return -ENOMEM;
+ }
+
+ fusion = instance->ctrl_context;
+
+ if (!fusion) {
+ megasas_return_cmd(instance, cmd);
+ return 1;
+ }
+
+ dcmd = &cmd->frame->dcmd;
+
+ size_map_info = sizeof(struct MR_FW_RAID_MAP) +
+ (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+ ci = fusion->ld_map[(instance->map_id & 1)];
+ ci_h = fusion->ld_map_phys[(instance->map_id & 1)];
+
+ if (!ci) {
+ printk(KERN_DEBUG "Failed to alloc mem for ld_map_info\n");
+ megasas_return_cmd(instance, cmd);
+ return -ENOMEM;
+ }
+
+ memset(ci, 0, sizeof(*ci));
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0xFF;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_READ;
+ dcmd->timeout = 0;
+ dcmd->pad_0 = 0;
+ dcmd->data_xfer_len = size_map_info;
+ dcmd->opcode = MR_DCMD_LD_MAP_GET_INFO;
+ dcmd->sgl.sge32[0].phys_addr = ci_h;
+ dcmd->sgl.sge32[0].length = size_map_info;
+
+ if (!megasas_issue_polled(instance, cmd))
+ ret = 0;
+ else {
+ printk(KERN_ERR "megasas: Get LD Map Info Failed\n");
+ ret = -1;
+ }
+
+ megasas_return_cmd(instance, cmd);
+
+ return ret;
+}
+
+u8
+megasas_get_map_info(struct megasas_instance *instance)
+{
+ struct fusion_context *fusion = instance->ctrl_context;
+
+ fusion->fast_path_io = 0;
+ if (!megasas_get_ld_map_info(instance)) {
+ if (MR_ValidateMapInfo(fusion->ld_map[(instance->map_id & 1)],
+ fusion->load_balance_info)) {
+ fusion->fast_path_io = 1;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * megasas_sync_map_info - Returns FW's ld_map structure
+ * @instance: Adapter soft state
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure. This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+int
+megasas_sync_map_info(struct megasas_instance *instance)
+{
+ int ret = 0, i;
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ u32 size_sync_info, num_lds;
+ struct fusion_context *fusion;
+ struct MR_LD_TARGET_SYNC *ci = NULL;
+ struct MR_FW_RAID_MAP_ALL *map;
+ struct MR_LD_RAID *raid;
+ struct MR_LD_TARGET_SYNC *ld_sync;
+ dma_addr_t ci_h = 0;
+ u32 size_map_info;
+
+ cmd = megasas_get_cmd(instance);
+
+ if (!cmd) {
+ printk(KERN_DEBUG "megasas: Failed to get cmd for sync"
+ "info.\n");
+ return -ENOMEM;
+ }
+
+ fusion = instance->ctrl_context;
+
+ if (!fusion) {
+ megasas_return_cmd(instance, cmd);
+ return 1;
+ }
+
+ map = fusion->ld_map[instance->map_id & 1];
+
+ num_lds = map->raidMap.ldCount;
+
+ dcmd = &cmd->frame->dcmd;
+
+ size_sync_info = sizeof(struct MR_LD_TARGET_SYNC) *num_lds;
+
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ ci = (struct MR_LD_TARGET_SYNC *)
+ fusion->ld_map[(instance->map_id - 1) & 1];
+ memset(ci, 0, sizeof(struct MR_FW_RAID_MAP_ALL));
+
+ ci_h = fusion->ld_map_phys[(instance->map_id - 1) & 1];
+
+ ld_sync = (struct MR_LD_TARGET_SYNC *)ci;
+
+ for (i = 0; i < num_lds; i++, ld_sync++) {
+ raid = MR_LdRaidGet(i, map);
+ ld_sync->targetId = MR_GetLDTgtId(i, map);
+ ld_sync->seqNum = raid->seqNum;
+ }
+
+ size_map_info = sizeof(struct MR_FW_RAID_MAP) +
+ (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0xFF;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_WRITE;
+ dcmd->timeout = 0;
+ dcmd->pad_0 = 0;
+ dcmd->data_xfer_len = size_map_info;
+ dcmd->mbox.b[0] = num_lds;
+ dcmd->mbox.b[1] = MEGASAS_DCMD_MBOX_PEND_FLAG;
+ dcmd->opcode = MR_DCMD_LD_MAP_GET_INFO;
+ dcmd->sgl.sge32[0].phys_addr = ci_h;
+ dcmd->sgl.sge32[0].length = size_map_info;
+
+ instance->map_update_cmd = cmd;
+
+ instance->instancet->issue_dcmd(instance, cmd);
+
+ return ret;
+}
+
+/**
+ * megasas_init_adapter_fusion - Initializes the FW
+ * @instance: Adapter soft state
+ *
+ * This is the main function for initializing firmware.
+ */
+u32
+megasas_init_adapter_fusion(struct megasas_instance *instance)
+{
+ struct megasas_register_set __iomem *reg_set;
+ struct fusion_context *fusion;
+ u32 max_cmd;
+ int i = 0;
+
+ fusion = instance->ctrl_context;
+
+ reg_set = instance->reg_set;
+
+ /*
+ * Get various operational parameters from status register
+ */
+ instance->max_fw_cmds =
+ instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+ instance->max_fw_cmds = min(instance->max_fw_cmds, (u16)1008);
+
+ /*
+ * Reduce the max supported cmds by 1. This is to ensure that the
+ * reply_q_sz (1 more than the max cmd that driver may send)
+ * does not exceed max cmds that the FW can support
+ */
+ instance->max_fw_cmds = instance->max_fw_cmds-1;
+ /* Only internal cmds (DCMD) need to have MFI frames */
+ instance->max_mfi_cmds = MEGASAS_INT_CMDS;
+
+ max_cmd = instance->max_fw_cmds;
+
+ fusion->reply_q_depth = ((max_cmd + 1 + 15)/16)*16;
+
+ fusion->request_alloc_sz =
+ sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *max_cmd;
+ fusion->reply_alloc_sz = sizeof(union MPI2_REPLY_DESCRIPTORS_UNION)
+ *(fusion->reply_q_depth);
+ fusion->io_frames_alloc_sz = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE +
+ (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE *
+ (max_cmd + 1)); /* Extra 1 for SMID 0 */
+
+ fusion->max_sge_in_main_msg =
+ (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
+ offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
+
+ fusion->max_sge_in_chain =
+ MEGASAS_MAX_SZ_CHAIN_FRAME / sizeof(union MPI2_SGE_IO_UNION);
+
+ instance->max_num_sge = fusion->max_sge_in_main_msg +
+ fusion->max_sge_in_chain - 2;
+
+ /* Used for pass thru MFI frame (DCMD) */
+ fusion->chain_offset_mfi_pthru =
+ offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL)/16;
+
+ fusion->chain_offset_io_request =
+ (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
+ sizeof(union MPI2_SGE_IO_UNION))/16;
+
+ fusion->last_reply_idx = 0;
+
+ /*
+ * Allocate memory for descriptors
+ * Create a pool of commands
+ */
+ if (megasas_alloc_cmds(instance))
+ goto fail_alloc_mfi_cmds;
+ if (megasas_alloc_cmds_fusion(instance))
+ goto fail_alloc_cmds;
+
+ if (megasas_ioc_init_fusion(instance))
+ goto fail_ioc_init;
+
+ instance->flag_ieee = 1;
+
+ fusion->map_sz = sizeof(struct MR_FW_RAID_MAP) +
+ (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+ fusion->fast_path_io = 0;
+
+ for (i = 0; i < 2; i++) {
+ fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
+ fusion->map_sz,
+ &fusion->ld_map_phys[i],
+ GFP_KERNEL);
+ if (!fusion->ld_map[i]) {
+ printk(KERN_ERR "megasas: Could not allocate memory "
+ "for map info\n");
+ goto fail_map_info;
+ }
+ }
+
+ if (!megasas_get_map_info(instance))
+ megasas_sync_map_info(instance);
+
+ return 0;
+
+fail_alloc_cmds:
+fail_alloc_mfi_cmds:
+fail_map_info:
+ if (i == 1)
+ dma_free_coherent(&instance->pdev->dev, fusion->map_sz,
+ fusion->ld_map[0], fusion->ld_map_phys[0]);
+fail_ioc_init:
+ return 1;
+}
+
+/**
+ * megasas_fire_cmd_fusion - Sends command to the FW
+ * @frame_phys_addr : Physical address of cmd
+ * @frame_count : Number of frames for the command
+ * @regs : MFI register set
+ */
+void
+megasas_fire_cmd_fusion(struct megasas_instance *instance,
+ dma_addr_t req_desc_lo,
+ u32 req_desc_hi,
+ struct megasas_register_set __iomem *regs)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&instance->hba_lock, flags);
+
+ writel(req_desc_lo,
+ &(regs)->inbound_low_queue_port);
+ writel(req_desc_hi, &(regs)->inbound_high_queue_port);
+ spin_unlock_irqrestore(&instance->hba_lock, flags);
+}
+
+/**
+ * map_cmd_status - Maps FW cmd status to OS cmd status
+ * @cmd : Pointer to cmd
+ * @status : status of cmd returned by FW
+ * @ext_status : ext status of cmd returned by FW
+ */
+
+void
+map_cmd_status(struct megasas_cmd_fusion *cmd, u8 status, u8 ext_status)
+{
+
+ switch (status) {
+
+ case MFI_STAT_OK:
+ cmd->scmd->result = DID_OK << 16;
+ break;
+
+ case MFI_STAT_SCSI_IO_FAILED:
+ case MFI_STAT_LD_INIT_IN_PROGRESS:
+ cmd->scmd->result = (DID_ERROR << 16) | ext_status;
+ break;
+
+ case MFI_STAT_SCSI_DONE_WITH_ERROR:
+
+ cmd->scmd->result = (DID_OK << 16) | ext_status;
+ if (ext_status == SAM_STAT_CHECK_CONDITION) {
+ memset(cmd->scmd->sense_buffer, 0,
+ SCSI_SENSE_BUFFERSIZE);
+ memcpy(cmd->scmd->sense_buffer, cmd->sense,
+ SCSI_SENSE_BUFFERSIZE);
+ cmd->scmd->result |= DRIVER_SENSE << 24;
+ }
+ break;
+
+ case MFI_STAT_LD_OFFLINE:
+ case MFI_STAT_DEVICE_NOT_FOUND:
+ cmd->scmd->result = DID_BAD_TARGET << 16;
+ break;
+
+ default:
+ printk(KERN_DEBUG "megasas: FW status %#x\n", status);
+ cmd->scmd->result = DID_ERROR << 16;
+ break;
+ }
+}
+
+/**
+ * megasas_make_sgl_fusion - Prepares 32-bit SGL
+ * @instance: Adapter soft state
+ * @scp: SCSI command from the mid-layer
+ * @sgl_ptr: SGL to be filled in
+ * @cmd: cmd we are working on
+ *
+ * If successful, this function returns the number of SG elements.
+ */
+static int
+megasas_make_sgl_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scp,
+ struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr,
+ struct megasas_cmd_fusion *cmd)
+{
+ int i, sg_processed;
+ int sge_count, sge_idx;
+ struct scatterlist *os_sgl;
+ struct fusion_context *fusion;
+
+ fusion = instance->ctrl_context;
+
+ cmd->io_request->ChainOffset = 0;
+
+ sge_count = scsi_dma_map(scp);
+
+ BUG_ON(sge_count < 0);
+
+ if (sge_count > instance->max_num_sge || !sge_count)
+ return sge_count;
+
+ if (sge_count > fusion->max_sge_in_main_msg) {
+ /* One element to store the chain info */
+ sge_idx = fusion->max_sge_in_main_msg - 1;
+ } else
+ sge_idx = sge_count;
+
+ scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+ sgl_ptr->Length = sg_dma_len(os_sgl);
+ sgl_ptr->Address = sg_dma_address(os_sgl);
+ sgl_ptr->Flags = 0;
+ sgl_ptr++;
+
+ sg_processed = i + 1;
+
+ if ((sg_processed == (fusion->max_sge_in_main_msg - 1)) &&
+ (sge_count > fusion->max_sge_in_main_msg)) {
+
+ struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
+ cmd->io_request->ChainOffset =
+ fusion->chain_offset_io_request;
+ sg_chain = sgl_ptr;
+ /* Prepare chain element */
+ sg_chain->NextChainOffset = 0;
+ sg_chain->Flags = (IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+ MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR);
+ sg_chain->Length = (sizeof(union MPI2_SGE_IO_UNION)
+ *(sge_count - sg_processed));
+ sg_chain->Address = cmd->sg_frame_phys_addr;
+
+ sgl_ptr =
+ (struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
+ }
+ }
+
+ return sge_count;
+}
+
+/**
+ * megasas_set_pd_lba - Sets PD LBA
+ * @cdb: CDB
+ * @cdb_len: cdb length
+ * @start_blk: Start block of IO
+ *
+ * Used to set the PD LBA in CDB for FP IOs
+ */
+void
+megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len,
+ struct IO_REQUEST_INFO *io_info, struct scsi_cmnd *scp,
+ struct MR_FW_RAID_MAP_ALL *local_map_ptr, u32 ref_tag)
+{
+ struct MR_LD_RAID *raid;
+ u32 ld;
+ u64 start_blk = io_info->pdBlock;
+ u8 *cdb = io_request->CDB.CDB32;
+ u32 num_blocks = io_info->numBlocks;
+ u8 opcode, flagvals, groupnum, control;
+
+ /* Check if T10 PI (DIF) is enabled for this LD */
+ ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr);
+ raid = MR_LdRaidGet(ld, local_map_ptr);
+ if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) {
+ memset(cdb, 0, sizeof(io_request->CDB.CDB32));
+ cdb[0] = MEGASAS_SCSI_VARIABLE_LENGTH_CMD;
+ cdb[7] = MEGASAS_SCSI_ADDL_CDB_LEN;
+
+ if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ cdb[9] = MEGASAS_SCSI_SERVICE_ACTION_READ32;
+ else
+ cdb[9] = MEGASAS_SCSI_SERVICE_ACTION_WRITE32;
+ cdb[10] = MEGASAS_RD_WR_PROTECT_CHECK_ALL;
+
+ /* LBA */
+ cdb[12] = (u8)((start_blk >> 56) & 0xff);
+ cdb[13] = (u8)((start_blk >> 48) & 0xff);
+ cdb[14] = (u8)((start_blk >> 40) & 0xff);
+ cdb[15] = (u8)((start_blk >> 32) & 0xff);
+ cdb[16] = (u8)((start_blk >> 24) & 0xff);
+ cdb[17] = (u8)((start_blk >> 16) & 0xff);
+ cdb[18] = (u8)((start_blk >> 8) & 0xff);
+ cdb[19] = (u8)(start_blk & 0xff);
+
+ /* Logical block reference tag */
+ io_request->CDB.EEDP32.PrimaryReferenceTag =
+ cpu_to_be32(ref_tag);
+ io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff;
+
+ io_request->DataLength = num_blocks * 512;
+ io_request->IoFlags = 32; /* Specify 32-byte cdb */
+
+ /* Transfer length */
+ cdb[28] = (u8)((num_blocks >> 24) & 0xff);
+ cdb[29] = (u8)((num_blocks >> 16) & 0xff);
+ cdb[30] = (u8)((num_blocks >> 8) & 0xff);
+ cdb[31] = (u8)(num_blocks & 0xff);
+
+ /* set SCSI IO EEDPFlags */
+ if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) {
+ io_request->EEDPFlags =
+ MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
+ MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
+ MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP |
+ MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG |
+ MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
+ } else {
+ io_request->EEDPFlags =
+ MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
+ MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
+ }
+ io_request->Control |= (0x4 << 26);
+ io_request->EEDPBlockSize = MEGASAS_EEDPBLOCKSIZE;
+ } else {
+ /* Some drives don't support 16/12 byte CDB's, convert to 10 */
+ if (((cdb_len == 12) || (cdb_len == 16)) &&
+ (start_blk <= 0xffffffff)) {
+ if (cdb_len == 16) {
+ opcode = cdb[0] == READ_16 ? READ_10 : WRITE_10;
+ flagvals = cdb[1];
+ groupnum = cdb[14];
+ control = cdb[15];
+ } else {
+ opcode = cdb[0] == READ_12 ? READ_10 : WRITE_10;
+ flagvals = cdb[1];
+ groupnum = cdb[10];
+ control = cdb[11];
+ }
+
+ memset(cdb, 0, sizeof(io_request->CDB.CDB32));
+
+ cdb[0] = opcode;
+ cdb[1] = flagvals;
+ cdb[6] = groupnum;
+ cdb[9] = control;
+
+ /* Transfer length */
+ cdb[8] = (u8)(num_blocks & 0xff);
+ cdb[7] = (u8)((num_blocks >> 8) & 0xff);
+
+ cdb_len = 10;
+ }
+
+ /* Normal case, just load LBA here */
+ switch (cdb_len) {
+ case 6:
+ {
+ u8 val = cdb[1] & 0xE0;
+ cdb[3] = (u8)(start_blk & 0xff);
+ cdb[2] = (u8)((start_blk >> 8) & 0xff);
+ cdb[1] = val | ((u8)(start_blk >> 16) & 0x1f);
+ break;
+ }
+ case 10:
+ cdb[5] = (u8)(start_blk & 0xff);
+ cdb[4] = (u8)((start_blk >> 8) & 0xff);
+ cdb[3] = (u8)((start_blk >> 16) & 0xff);
+ cdb[2] = (u8)((start_blk >> 24) & 0xff);
+ break;
+ case 12:
+ cdb[5] = (u8)(start_blk & 0xff);
+ cdb[4] = (u8)((start_blk >> 8) & 0xff);
+ cdb[3] = (u8)((start_blk >> 16) & 0xff);
+ cdb[2] = (u8)((start_blk >> 24) & 0xff);
+ break;
+ case 16:
+ cdb[9] = (u8)(start_blk & 0xff);
+ cdb[8] = (u8)((start_blk >> 8) & 0xff);
+ cdb[7] = (u8)((start_blk >> 16) & 0xff);
+ cdb[6] = (u8)((start_blk >> 24) & 0xff);
+ cdb[5] = (u8)((start_blk >> 32) & 0xff);
+ cdb[4] = (u8)((start_blk >> 40) & 0xff);
+ cdb[3] = (u8)((start_blk >> 48) & 0xff);
+ cdb[2] = (u8)((start_blk >> 56) & 0xff);
+ break;
+ }
+ }
+}
+
+/**
+ * megasas_build_ldio_fusion - Prepares IOs to devices
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to be prepared
+ *
+ * Prepares the io_request and chain elements (sg_frame) for IO
+ * The IO can be for PD (Fast Path) or LD
+ */
+void
+megasas_build_ldio_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scp,
+ struct megasas_cmd_fusion *cmd)
+{
+ u8 fp_possible;
+ u32 start_lba_lo, start_lba_hi, device_id;
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ struct IO_REQUEST_INFO io_info;
+ struct fusion_context *fusion;
+ struct MR_FW_RAID_MAP_ALL *local_map_ptr;
+
+ device_id = MEGASAS_DEV_INDEX(instance, scp);
+
+ fusion = instance->ctrl_context;
+
+ io_request = cmd->io_request;
+ io_request->RaidContext.VirtualDiskTgtId = device_id;
+ io_request->RaidContext.status = 0;
+ io_request->RaidContext.exStatus = 0;
+
+ req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
+
+ start_lba_lo = 0;
+ start_lba_hi = 0;
+ fp_possible = 0;
+
+ /*
+ * 6-byte READ(0x08) or WRITE(0x0A) cdb
+ */
+ if (scp->cmd_len == 6) {
+ io_request->DataLength = (u32) scp->cmnd[4];
+ start_lba_lo = ((u32) scp->cmnd[1] << 16) |
+ ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
+
+ start_lba_lo &= 0x1FFFFF;
+ }
+
+ /*
+ * 10-byte READ(0x28) or WRITE(0x2A) cdb
+ */
+ else if (scp->cmd_len == 10) {
+ io_request->DataLength = (u32) scp->cmnd[8] |
+ ((u32) scp->cmnd[7] << 8);
+ start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+ }
+
+ /*
+ * 12-byte READ(0xA8) or WRITE(0xAA) cdb
+ */
+ else if (scp->cmd_len == 12) {
+ io_request->DataLength = ((u32) scp->cmnd[6] << 24) |
+ ((u32) scp->cmnd[7] << 16) |
+ ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+ start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+ }
+
+ /*
+ * 16-byte READ(0x88) or WRITE(0x8A) cdb
+ */
+ else if (scp->cmd_len == 16) {
+ io_request->DataLength = ((u32) scp->cmnd[10] << 24) |
+ ((u32) scp->cmnd[11] << 16) |
+ ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
+ start_lba_lo = ((u32) scp->cmnd[6] << 24) |
+ ((u32) scp->cmnd[7] << 16) |
+ ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+
+ start_lba_hi = ((u32) scp->cmnd[2] << 24) |
+ ((u32) scp->cmnd[3] << 16) |
+ ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+ }
+
+ memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO));
+ io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo;
+ io_info.numBlocks = io_request->DataLength;
+ io_info.ldTgtId = device_id;
+
+ if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ io_info.isRead = 1;
+
+ local_map_ptr = fusion->ld_map[(instance->map_id & 1)];
+
+ if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
+ MAX_LOGICAL_DRIVES) || (!fusion->fast_path_io)) {
+ io_request->RaidContext.regLockFlags = 0;
+ fp_possible = 0;
+ } else {
+ if (MR_BuildRaidContext(&io_info, &io_request->RaidContext,
+ local_map_ptr))
+ fp_possible = io_info.fpOkForIo;
+ }
+
+ if (fp_possible) {
+ megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
+ local_map_ptr, start_lba_lo);
+ io_request->DataLength = scsi_bufflen(scp);
+ io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
+ << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
+ (io_info.isRead)) {
+ io_info.devHandle =
+ get_updated_dev_handle(
+ &fusion->load_balance_info[device_id],
+ &io_info);
+ scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG;
+ } else
+ scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
+ cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
+ io_request->DevHandle = io_info.devHandle;
+ } else {
+ io_request->RaidContext.timeoutValue =
+ local_map_ptr->raidMap.fpPdIoTimeoutSec;
+ io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+ io_request->DevHandle = device_id;
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
+ << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ } /* Not FP */
+}
+
+/**
+ * megasas_build_dcdb_fusion - Prepares IOs to devices
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to be prepared
+ *
+ * Prepares the io_request frame for non-io cmds
+ */
+static void
+megasas_build_dcdb_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd,
+ struct megasas_cmd_fusion *cmd)
+{
+ u32 device_id;
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+ u16 pd_index = 0;
+ struct MR_FW_RAID_MAP_ALL *local_map_ptr;
+ struct fusion_context *fusion = instance->ctrl_context;
+
+ io_request = cmd->io_request;
+ device_id = MEGASAS_DEV_INDEX(instance, scmd);
+ pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL)
+ +scmd->device->id;
+ local_map_ptr = fusion->ld_map[(instance->map_id & 1)];
+
+ /* Check if this is a system PD I/O */
+ if ((instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) &&
+ (instance->pd_list[pd_index].driveType == TYPE_DISK)) {
+ io_request->Function = 0;
+ io_request->DevHandle =
+ local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+ io_request->RaidContext.timeoutValue =
+ local_map_ptr->raidMap.fpPdIoTimeoutSec;
+ io_request->RaidContext.regLockFlags = 0;
+ io_request->RaidContext.regLockRowLBA = 0;
+ io_request->RaidContext.regLockLength = 0;
+ io_request->RaidContext.RAIDFlags =
+ MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
+ MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ } else {
+ io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+ io_request->DevHandle = device_id;
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ }
+ io_request->RaidContext.VirtualDiskTgtId = device_id;
+ io_request->LUN[0] = scmd->device->lun;
+ io_request->DataLength = scsi_bufflen(scmd);
+}
+
+/**
+ * megasas_build_io_fusion - Prepares IOs to devices
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to be prepared
+ *
+ * Invokes helper functions to prepare request frames
+ * and sets flags appropriate for IO/Non-IO cmd
+ */
+int
+megasas_build_io_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scp,
+ struct megasas_cmd_fusion *cmd)
+{
+ u32 device_id, sge_count;
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
+
+ device_id = MEGASAS_DEV_INDEX(instance, scp);
+
+ /* Zero out some fields so they don't get reused */
+ io_request->LUN[0] = 0;
+ io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
+ io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0;
+ io_request->EEDPFlags = 0;
+ io_request->Control = 0;
+ io_request->EEDPBlockSize = 0;
+ io_request->IoFlags = 0;
+ io_request->RaidContext.RAIDFlags = 0;
+
+ memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
+ /*
+ * Just the CDB length,rest of the Flags are zero
+ * This will be modified for FP in build_ldio_fusion
+ */
+ io_request->IoFlags = scp->cmd_len;
+
+ if (megasas_is_ldio(scp))
+ megasas_build_ldio_fusion(instance, scp, cmd);
+ else
+ megasas_build_dcdb_fusion(instance, scp, cmd);
+
+ /*
+ * Construct SGL
+ */
+
+ sge_count =
+ megasas_make_sgl_fusion(instance, scp,
+ (struct MPI25_IEEE_SGE_CHAIN64 *)
+ &io_request->SGL, cmd);
+
+ if (sge_count > instance->max_num_sge) {
+ printk(KERN_ERR "megasas: Error. sge_count (0x%x) exceeds "
+ "max (0x%x) allowed\n", sge_count,
+ instance->max_num_sge);
+ return 1;
+ }
+
+ io_request->RaidContext.numSGE = sge_count;
+
+ io_request->SGLFlags = MPI2_SGE_FLAGS_64_BIT_ADDRESSING;
+
+ if (scp->sc_data_direction == PCI_DMA_TODEVICE)
+ io_request->Control |= MPI2_SCSIIO_CONTROL_WRITE;
+ else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ io_request->Control |= MPI2_SCSIIO_CONTROL_READ;
+
+ io_request->SGLOffset0 =
+ offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4;
+
+ io_request->SenseBufferLowAddress = cmd->sense_phys_addr;
+ io_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
+
+ cmd->scmd = scp;
+ scp->SCp.ptr = (char *)cmd;
+
+ return 0;
+}
+
+union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+megasas_get_request_descriptor(struct megasas_instance *instance, u16 index)
+{
+ u8 *p;
+ struct fusion_context *fusion;
+
+ if (index >= instance->max_fw_cmds) {
+ printk(KERN_ERR "megasas: Invalid SMID (0x%x)request for "
+ "descriptor\n", index);
+ return NULL;
+ }
+ fusion = instance->ctrl_context;
+ p = fusion->req_frames_desc
+ +sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *index;
+
+ return (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)p;
+}
+
+/**
+ * megasas_build_and_issue_cmd_fusion -Main routine for building and
+ * issuing non IOCTL cmd
+ * @instance: Adapter soft state
+ * @scmd: pointer to scsi cmd from OS
+ */
+static u32
+megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd)
+{
+ struct megasas_cmd_fusion *cmd;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ u32 index;
+ struct fusion_context *fusion;
+
+ fusion = instance->ctrl_context;
+
+ cmd = megasas_get_cmd_fusion(instance);
+ if (!cmd)
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+ index = cmd->index;
+
+ req_desc = megasas_get_request_descriptor(instance, index-1);
+ if (!req_desc)
+ return 1;
+
+ req_desc->Words = 0;
+ cmd->request_desc = req_desc;
+ cmd->request_desc->Words = 0;
+
+ if (megasas_build_io_fusion(instance, scmd, cmd)) {
+ megasas_return_cmd_fusion(instance, cmd);
+ printk(KERN_ERR "megasas: Error building command.\n");
+ cmd->request_desc = NULL;
+ return 1;
+ }
+
+ req_desc = cmd->request_desc;
+ req_desc->SCSIIO.SMID = index;
+
+ if (cmd->io_request->ChainOffset != 0 &&
+ cmd->io_request->ChainOffset != 0xF)
+ printk(KERN_ERR "megasas: The chain offset value is not "
+ "correct : %x\n", cmd->io_request->ChainOffset);
+
+ /*
+ * Issue the command to the FW
+ */
+ atomic_inc(&instance->fw_outstanding);
+
+ instance->instancet->fire_cmd(instance,
+ req_desc->u.low, req_desc->u.high,
+ instance->reg_set);
+
+ return 0;
+}
+
+/**
+ * complete_cmd_fusion - Completes command
+ * @instance: Adapter soft state
+ * Completes all commands that is in reply descriptor queue
+ */
+int
+complete_cmd_fusion(struct megasas_instance *instance)
+{
+ union MPI2_REPLY_DESCRIPTORS_UNION *desc;
+ struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *reply_desc;
+ struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req;
+ struct fusion_context *fusion;
+ struct megasas_cmd *cmd_mfi;
+ struct megasas_cmd_fusion *cmd_fusion;
+ u16 smid, num_completed;
+ u8 reply_descript_type, arm;
+ u32 status, extStatus, device_id;
+ union desc_value d_val;
+ struct LD_LOAD_BALANCE_INFO *lbinfo;
+
+ fusion = instance->ctrl_context;
+
+ if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+ return IRQ_HANDLED;
+
+ desc = fusion->reply_frames_desc;
+ desc += fusion->last_reply_idx;
+
+ reply_desc = (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
+
+ d_val.word = desc->Words;
+
+ reply_descript_type = reply_desc->ReplyFlags &
+ MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+
+ if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
+ return IRQ_NONE;
+
+ d_val.word = desc->Words;
+
+ num_completed = 0;
+
+ while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) {
+ smid = reply_desc->SMID;
+
+ cmd_fusion = fusion->cmd_list[smid - 1];
+
+ scsi_io_req =
+ (struct MPI2_RAID_SCSI_IO_REQUEST *)
+ cmd_fusion->io_request;
+
+ if (cmd_fusion->scmd)
+ cmd_fusion->scmd->SCp.ptr = NULL;
+
+ status = scsi_io_req->RaidContext.status;
+ extStatus = scsi_io_req->RaidContext.exStatus;
+
+ switch (scsi_io_req->Function) {
+ case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
+ /* Update load balancing info */
+ device_id = MEGASAS_DEV_INDEX(instance,
+ cmd_fusion->scmd);
+ lbinfo = &fusion->load_balance_info[device_id];
+ if (cmd_fusion->scmd->SCp.Status &
+ MEGASAS_LOAD_BALANCE_FLAG) {
+ arm = lbinfo->raid1DevHandle[0] ==
+ cmd_fusion->io_request->DevHandle ? 0 :
+ 1;
+ atomic_dec(&lbinfo->scsi_pending_cmds[arm]);
+ cmd_fusion->scmd->SCp.Status &=
+ ~MEGASAS_LOAD_BALANCE_FLAG;
+ }
+ if (reply_descript_type ==
+ MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
+ if (megasas_dbg_lvl == 5)
+ printk(KERN_ERR "\nmegasas: FAST Path "
+ "IO Success\n");
+ }
+ /* Fall thru and complete IO */
+ case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
+ /* Map the FW Cmd Status */
+ map_cmd_status(cmd_fusion, status, extStatus);
+ scsi_dma_unmap(cmd_fusion->scmd);
+ cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
+ scsi_io_req->RaidContext.status = 0;
+ scsi_io_req->RaidContext.exStatus = 0;
+ megasas_return_cmd_fusion(instance, cmd_fusion);
+ atomic_dec(&instance->fw_outstanding);
+
+ break;
+ case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
+ cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
+ megasas_complete_cmd(instance, cmd_mfi, DID_OK);
+ cmd_fusion->flags = 0;
+ megasas_return_cmd_fusion(instance, cmd_fusion);
+
+ break;
+ }
+
+ fusion->last_reply_idx++;
+ if (fusion->last_reply_idx >= fusion->reply_q_depth)
+ fusion->last_reply_idx = 0;
+
+ desc->Words = ULLONG_MAX;
+ num_completed++;
+
+ /* Get the next reply descriptor */
+ if (!fusion->last_reply_idx)
+ desc = fusion->reply_frames_desc;
+ else
+ desc++;
+
+ reply_desc =
+ (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
+
+ d_val.word = desc->Words;
+
+ reply_descript_type = reply_desc->ReplyFlags &
+ MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+
+ if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
+ break;
+ }
+
+ if (!num_completed)
+ return IRQ_NONE;
+
+ wmb();
+ writel(fusion->last_reply_idx,
+ &instance->reg_set->reply_post_host_index);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * megasas_complete_cmd_dpc_fusion - Completes command
+ * @instance: Adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+void
+megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
+{
+ struct megasas_instance *instance =
+ (struct megasas_instance *)instance_addr;
+ unsigned long flags;
+
+ /* If we have already declared adapter dead, donot complete cmds */
+ spin_lock_irqsave(&instance->hba_lock, flags);
+ if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+ spin_unlock_irqrestore(&instance->hba_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&instance->hba_lock, flags);
+
+ spin_lock_irqsave(&instance->completion_lock, flags);
+ complete_cmd_fusion(instance);
+ spin_unlock_irqrestore(&instance->completion_lock, flags);
+}
+
+/**
+ * megasas_isr_fusion - isr entry point
+ */
+irqreturn_t megasas_isr_fusion(int irq, void *devp)
+{
+ struct megasas_instance *instance = (struct megasas_instance *)devp;
+ u32 mfiStatus, fw_state;
+
+ if (!instance->msi_flag) {
+ mfiStatus = instance->instancet->clear_intr(instance->reg_set);
+ if (!mfiStatus)
+ return IRQ_NONE;
+ }
+
+ /* If we are resetting, bail */
+ if (test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
+ return IRQ_HANDLED;
+
+ if (!complete_cmd_fusion(instance)) {
+ /* If we didn't complete any commands, check for FW fault */
+ fw_state = instance->instancet->read_fw_status_reg(
+ instance->reg_set) & MFI_STATE_MASK;
+ if (fw_state == MFI_STATE_FAULT)
+ schedule_work(&instance->work_init);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * build_mpt_mfi_pass_thru - builds a cmd fo MFI Pass thru
+ * @instance: Adapter soft state
+ * mfi_cmd: megasas_cmd pointer
+ *
+ */
+u8
+build_mpt_mfi_pass_thru(struct megasas_instance *instance,
+ struct megasas_cmd *mfi_cmd)
+{
+ struct MPI25_IEEE_SGE_CHAIN64 *mpi25_ieee_chain;
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_req;
+ struct megasas_cmd_fusion *cmd;
+ struct fusion_context *fusion;
+ struct megasas_header *frame_hdr = &mfi_cmd->frame->hdr;
+
+ cmd = megasas_get_cmd_fusion(instance);
+ if (!cmd)
+ return 1;
+
+ /* Save the smid. To be used for returning the cmd */
+ mfi_cmd->context.smid = cmd->index;
+
+ cmd->sync_cmd_idx = mfi_cmd->index;
+
+ /*
+ * For cmds where the flag is set, store the flag and check
+ * on completion. For cmds with this flag, don't call
+ * megasas_complete_cmd
+ */
+
+ if (frame_hdr->flags & MFI_FRAME_DONT_POST_IN_REPLY_QUEUE)
+ cmd->flags = MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+
+ fusion = instance->ctrl_context;
+ io_req = cmd->io_request;
+ mpi25_ieee_chain =
+ (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL.IeeeChain;
+
+ io_req->Function = MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST;
+ io_req->SGLOffset0 = offsetof(struct MPI2_RAID_SCSI_IO_REQUEST,
+ SGL) / 4;
+ io_req->ChainOffset = fusion->chain_offset_mfi_pthru;
+
+ mpi25_ieee_chain->Address = mfi_cmd->frame_phys_addr;
+
+ mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+ MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
+
+ mpi25_ieee_chain->Length = MEGASAS_MAX_SZ_CHAIN_FRAME;
+
+ return 0;
+}
+
+/**
+ * build_mpt_cmd - Calls helper function to build a cmd MFI Pass thru cmd
+ * @instance: Adapter soft state
+ * @cmd: mfi cmd to build
+ *
+ */
+union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ u16 index;
+
+ if (build_mpt_mfi_pass_thru(instance, cmd)) {
+ printk(KERN_ERR "Couldn't build MFI pass thru cmd\n");
+ return NULL;
+ }
+
+ index = cmd->context.smid;
+
+ req_desc = megasas_get_request_descriptor(instance, index - 1);
+
+ if (!req_desc)
+ return NULL;
+
+ req_desc->Words = 0;
+ req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+
+ req_desc->SCSIIO.SMID = index;
+
+ return req_desc;
+}
+
+/**
+ * megasas_issue_dcmd_fusion - Issues a MFI Pass thru cmd
+ * @instance: Adapter soft state
+ * @cmd: mfi cmd pointer
+ *
+ */
+void
+megasas_issue_dcmd_fusion(struct megasas_instance *instance,
+ struct megasas_cmd *cmd)
+{
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ union desc_value d_val;
+
+ req_desc = build_mpt_cmd(instance, cmd);
+ if (!req_desc) {
+ printk(KERN_ERR "Couldn't issue MFI pass thru cmd\n");
+ return;
+ }
+ d_val.word = req_desc->Words;
+
+ instance->instancet->fire_cmd(instance, req_desc->u.low,
+ req_desc->u.high, instance->reg_set);
+}
+
+/**
+ * megasas_release_fusion - Reverses the FW initialization
+ * @intance: Adapter soft state
+ */
+void
+megasas_release_fusion(struct megasas_instance *instance)
+{
+ megasas_free_cmds(instance);
+ megasas_free_cmds_fusion(instance);
+
+ iounmap(instance->reg_set);
+
+ pci_release_selected_regions(instance->pdev, instance->bar);
+}
+
+/**
+ * megasas_read_fw_status_reg_fusion - returns the current FW status value
+ * @regs: MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_fusion(struct megasas_register_set __iomem *regs)
+{
+ return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_adp_reset_fusion - For controller reset
+ * @regs: MFI register set
+ */
+static int
+megasas_adp_reset_fusion(struct megasas_instance *instance,
+ struct megasas_register_set __iomem *regs)
+{
+ return 0;
+}
+
+/**
+ * megasas_check_reset_fusion - For controller reset check
+ * @regs: MFI register set
+ */
+static int
+megasas_check_reset_fusion(struct megasas_instance *instance,
+ struct megasas_register_set __iomem *regs)
+{
+ return 0;
+}
+
+/* This function waits for outstanding commands on fusion to complete */
+int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance)
+{
+ int i, outstanding, retval = 0;
+ u32 fw_state, wait_time = MEGASAS_RESET_WAIT_TIME;
+
+ for (i = 0; i < wait_time; i++) {
+ /* Check if firmware is in fault state */
+ fw_state = instance->instancet->read_fw_status_reg(
+ instance->reg_set) & MFI_STATE_MASK;
+ if (fw_state == MFI_STATE_FAULT) {
+ printk(KERN_WARNING "megasas: Found FW in FAULT state,"
+ " will reset adapter.\n");
+ retval = 1;
+ goto out;
+ }
+
+ outstanding = atomic_read(&instance->fw_outstanding);
+ if (!outstanding)
+ goto out;
+
+ if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
+ printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
+ "commands to complete\n", i, outstanding);
+ megasas_complete_cmd_dpc_fusion(
+ (unsigned long)instance);
+ }
+ msleep(1000);
+ }
+
+ if (atomic_read(&instance->fw_outstanding)) {
+ printk("megaraid_sas: pending commands remain after waiting, "
+ "will reset adapter.\n");
+ retval = 1;
+ }
+out:
+ return retval;
+}
+
+void megasas_reset_reply_desc(struct megasas_instance *instance)
+{
+ int i;
+ struct fusion_context *fusion;
+ union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+
+ fusion = instance->ctrl_context;
+ fusion->last_reply_idx = 0;
+ reply_desc = fusion->reply_frames_desc;
+ for (i = 0 ; i < fusion->reply_q_depth; i++, reply_desc++)
+ reply_desc->Words = ULLONG_MAX;
+}
+
+/* Core fusion reset function */
+int megasas_reset_fusion(struct Scsi_Host *shost)
+{
+ int retval = SUCCESS, i, j, retry = 0;
+ struct megasas_instance *instance;
+ struct megasas_cmd_fusion *cmd_fusion;
+ struct fusion_context *fusion;
+ struct megasas_cmd *cmd_mfi;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ u32 host_diag, abs_state;
+
+ instance = (struct megasas_instance *)shost->hostdata;
+ fusion = instance->ctrl_context;
+
+ mutex_lock(&instance->reset_mutex);
+ set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+ instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
+ instance->instancet->disable_intr(instance->reg_set);
+ msleep(1000);
+
+ if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+ printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
+ "returning FAILED.\n");
+ retval = FAILED;
+ goto out;
+ }
+
+ /* First try waiting for commands to complete */
+ if (megasas_wait_for_outstanding_fusion(instance)) {
+ printk(KERN_WARNING "megaraid_sas: resetting fusion "
+ "adapter.\n");
+ /* Now return commands back to the OS */
+ for (i = 0 ; i < instance->max_fw_cmds; i++) {
+ cmd_fusion = fusion->cmd_list[i];
+ if (cmd_fusion->scmd) {
+ scsi_dma_unmap(cmd_fusion->scmd);
+ cmd_fusion->scmd->result = (DID_RESET << 16);
+ cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
+ megasas_return_cmd_fusion(instance, cmd_fusion);
+ atomic_dec(&instance->fw_outstanding);
+ }
+ }
+
+ if (instance->disableOnlineCtrlReset == 1) {
+ /* Reset not supported, kill adapter */
+ printk(KERN_WARNING "megaraid_sas: Reset not supported"
+ ", killing adapter.\n");
+ megaraid_sas_kill_hba(instance);
+ instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
+ retval = FAILED;
+ goto out;
+ }
+
+ /* Now try to reset the chip */
+ for (i = 0; i < MEGASAS_FUSION_MAX_RESET_TRIES; i++) {
+ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_1ST_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_2ND_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_3RD_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_4TH_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_5TH_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_6TH_KEY_VALUE,
+ &instance->reg_set->fusion_seq_offset);
+
+ /* Check that the diag write enable (DRWE) bit is on */
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
+ msleep(100);
+ host_diag =
+ readl(&instance->reg_set->fusion_host_diag);
+ if (retry++ == 100) {
+ printk(KERN_WARNING "megaraid_sas: "
+ "Host diag unlock failed!\n");
+ break;
+ }
+ }
+ if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
+ continue;
+
+ /* Send chip reset command */
+ writel(host_diag | HOST_DIAG_RESET_ADAPTER,
+ &instance->reg_set->fusion_host_diag);
+ msleep(3000);
+
+ /* Make sure reset adapter bit is cleared */
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ retry = 0;
+ while (host_diag & HOST_DIAG_RESET_ADAPTER) {
+ msleep(100);
+ host_diag =
+ readl(&instance->reg_set->fusion_host_diag);
+ if (retry++ == 1000) {
+ printk(KERN_WARNING "megaraid_sas: "
+ "Diag reset adapter never "
+ "cleared!\n");
+ break;
+ }
+ }
+ if (host_diag & HOST_DIAG_RESET_ADAPTER)
+ continue;
+
+ abs_state =
+ instance->instancet->read_fw_status_reg(
+ instance->reg_set);
+ retry = 0;
+
+ while ((abs_state <= MFI_STATE_FW_INIT) &&
+ (retry++ < 1000)) {
+ msleep(100);
+ abs_state =
+ instance->instancet->read_fw_status_reg(
+ instance->reg_set);
+ }
+ if (abs_state <= MFI_STATE_FW_INIT) {
+ printk(KERN_WARNING "megaraid_sas: firmware "
+ "state < MFI_STATE_FW_INIT, state = "
+ "0x%x\n", abs_state);
+ continue;
+ }
+
+ /* Wait for FW to become ready */
+ if (megasas_transition_to_ready(instance)) {
+ printk(KERN_WARNING "megaraid_sas: Failed to "
+ "transition controller to ready.\n");
+ continue;
+ }
+
+ megasas_reset_reply_desc(instance);
+ if (megasas_ioc_init_fusion(instance)) {
+ printk(KERN_WARNING "megaraid_sas: "
+ "megasas_ioc_init_fusion() failed!\n");
+ continue;
+ }
+
+ instance->instancet->enable_intr(instance->reg_set);
+ instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+
+ /* Re-fire management commands */
+ for (j = 0 ; j < instance->max_fw_cmds; j++) {
+ cmd_fusion = fusion->cmd_list[j];
+ if (cmd_fusion->sync_cmd_idx !=
+ (u32)ULONG_MAX) {
+ cmd_mfi =
+ instance->
+ cmd_list[cmd_fusion->sync_cmd_idx];
+ if (cmd_mfi->frame->dcmd.opcode ==
+ MR_DCMD_LD_MAP_GET_INFO) {
+ megasas_return_cmd(instance,
+ cmd_mfi);
+ megasas_return_cmd_fusion(
+ instance, cmd_fusion);
+ } else {
+ req_desc =
+ megasas_get_request_descriptor(
+ instance,
+ cmd_mfi->context.smid
+ -1);
+ if (!req_desc)
+ printk(KERN_WARNING
+ "req_desc NULL"
+ "\n");
+ else {
+ instance->instancet->
+ fire_cmd(instance,
+ req_desc->
+ u.low,
+ req_desc->
+ u.high,
+ instance->
+ reg_set);
+ }
+ }
+ }
+ }
+
+ /* Reset load balance info */
+ memset(fusion->load_balance_info, 0,
+ sizeof(struct LD_LOAD_BALANCE_INFO)
+ *MAX_LOGICAL_DRIVES);
+
+ if (!megasas_get_map_info(instance))
+ megasas_sync_map_info(instance);
+
+ /* Adapter reset completed successfully */
+ printk(KERN_WARNING "megaraid_sas: Reset "
+ "successful.\n");
+ retval = SUCCESS;
+ goto out;
+ }
+ /* Reset failed, kill the adapter */
+ printk(KERN_WARNING "megaraid_sas: Reset failed, killing "
+ "adapter.\n");
+ megaraid_sas_kill_hba(instance);
+ retval = FAILED;
+ } else {
+ instance->instancet->enable_intr(instance->reg_set);
+ instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+ }
+out:
+ clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+ mutex_unlock(&instance->reset_mutex);
+ return retval;
+}
+
+/* Fusion OCR work queue */
+void megasas_fusion_ocr_wq(struct work_struct *work)
+{
+ struct megasas_instance *instance =
+ container_of(work, struct megasas_instance, work_init);
+
+ megasas_reset_fusion(instance->host);
+}
+
+struct megasas_instance_template megasas_instance_template_fusion = {
+ .fire_cmd = megasas_fire_cmd_fusion,
+ .enable_intr = megasas_enable_intr_fusion,
+ .disable_intr = megasas_disable_intr_fusion,
+ .clear_intr = megasas_clear_intr_fusion,
+ .read_fw_status_reg = megasas_read_fw_status_reg_fusion,
+ .adp_reset = megasas_adp_reset_fusion,
+ .check_reset = megasas_check_reset_fusion,
+ .service_isr = megasas_isr_fusion,
+ .tasklet = megasas_complete_cmd_dpc_fusion,
+ .init_adapter = megasas_init_adapter_fusion,
+ .build_and_issue_cmd = megasas_build_and_issue_cmd_fusion,
+ .issue_dcmd = megasas_issue_dcmd_fusion,
+};
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
new file mode 100644
index 000000000000..82b577a72c8b
--- /dev/null
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -0,0 +1,695 @@
+/*
+ * Linux MegaRAID driver for SAS based RAID controllers
+ *
+ * Copyright (c) 2009-2011 LSI Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * FILE: megaraid_sas_fusion.h
+ *
+ * Authors: LSI Corporation
+ * Manoj Jose
+ * Sumant Patro
+ *
+ * Send feedback to: <megaraidlinux@lsi.com>
+ *
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ * ATTN: Linuxraid
+ */
+
+#ifndef _MEGARAID_SAS_FUSION_H_
+#define _MEGARAID_SAS_FUSION_H_
+
+/* Fusion defines */
+#define MEGASAS_MAX_SZ_CHAIN_FRAME 1024
+#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
+#define MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
+#define MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0
+#define MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST 0xF1
+#define MEGASAS_LOAD_BALANCE_FLAG 0x1
+#define MEGASAS_DCMD_MBOX_PEND_FLAG 0x1
+#define HOST_DIAG_WRITE_ENABLE 0x80
+#define HOST_DIAG_RESET_ADAPTER 0x4
+#define MEGASAS_FUSION_MAX_RESET_TRIES 3
+
+/* T10 PI defines */
+#define MR_PROT_INFO_TYPE_CONTROLLER 0x8
+#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f
+#define MEGASAS_SCSI_SERVICE_ACTION_READ32 0x9
+#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32 0xB
+#define MEGASAS_SCSI_ADDL_CDB_LEN 0x18
+#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20
+#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60
+#define MEGASAS_EEDPBLOCKSIZE 512
+
+/*
+ * Raid context flags
+ */
+
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT 0x4
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_MASK 0x30
+enum MR_RAID_FLAGS_IO_SUB_TYPE {
+ MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
+ MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1,
+};
+
+/*
+ * Request descriptor types
+ */
+#define MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO 0x7
+#define MEGASAS_REQ_DESCRIPT_FLAGS_MFA 0x1
+
+#define MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 1
+
+#define MEGASAS_FP_CMD_LEN 16
+#define MEGASAS_FUSION_IN_RESET 0
+
+/*
+ * Raid Context structure which describes MegaRAID specific IO Paramenters
+ * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames
+ */
+
+struct RAID_CONTEXT {
+ u16 resvd0;
+ u16 timeoutValue;
+ u8 regLockFlags;
+ u8 resvd1;
+ u16 VirtualDiskTgtId;
+ u64 regLockRowLBA;
+ u32 regLockLength;
+ u16 nextLMId;
+ u8 exStatus;
+ u8 status;
+ u8 RAIDFlags;
+ u8 numSGE;
+ u16 configSeqNum;
+ u8 spanArm;
+ u8 resvd2[3];
+};
+
+#define RAID_CTX_SPANARM_ARM_SHIFT (0)
+#define RAID_CTX_SPANARM_ARM_MASK (0x1f)
+
+#define RAID_CTX_SPANARM_SPAN_SHIFT (5)
+#define RAID_CTX_SPANARM_SPAN_MASK (0xE0)
+
+/*
+ * define region lock types
+ */
+enum REGION_TYPE {
+ REGION_TYPE_UNUSED = 0,
+ REGION_TYPE_SHARED_READ = 1,
+ REGION_TYPE_SHARED_WRITE = 2,
+ REGION_TYPE_EXCLUSIVE = 3,
+};
+
+/* MPI2 defines */
+#define MPI2_FUNCTION_IOC_INIT (0x02) /* IOC Init */
+#define MPI2_WHOINIT_HOST_DRIVER (0x04)
+#define MPI2_VERSION_MAJOR (0x02)
+#define MPI2_VERSION_MINOR (0x00)
+#define MPI2_VERSION_MAJOR_MASK (0xFF00)
+#define MPI2_VERSION_MAJOR_SHIFT (8)
+#define MPI2_VERSION_MINOR_MASK (0x00FF)
+#define MPI2_VERSION_MINOR_SHIFT (0)
+#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
+ MPI2_VERSION_MINOR)
+#define MPI2_HEADER_VERSION_UNIT (0x10)
+#define MPI2_HEADER_VERSION_DEV (0x00)
+#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
+#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
+#define MPI2_HEADER_VERSION_DEV_MASK (0x00FF)
+#define MPI2_HEADER_VERSION_DEV_SHIFT (0)
+#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | \
+ MPI2_HEADER_VERSION_DEV)
+#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
+#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100)
+#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004)
+#define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */
+#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06)
+#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00)
+#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02)
+#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000)
+#define MPI2_SCSIIO_CONTROL_READ (0x02000000)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x0E)
+#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F)
+#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00)
+#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F)
+#define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0)
+#define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004)
+#define MPI2_WRSEQ_1ST_KEY_VALUE (0xF)
+#define MPI2_WRSEQ_2ND_KEY_VALUE (0x4)
+#define MPI2_WRSEQ_3RD_KEY_VALUE (0xB)
+#define MPI2_WRSEQ_4TH_KEY_VALUE (0x2)
+#define MPI2_WRSEQ_5TH_KEY_VALUE (0x7)
+#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD)
+
+struct MPI25_IEEE_SGE_CHAIN64 {
+ u64 Address;
+ u32 Length;
+ u16 Reserved1;
+ u8 NextChainOffset;
+ u8 Flags;
+};
+
+struct MPI2_SGE_SIMPLE_UNION {
+ u32 FlagsLength;
+ union {
+ u32 Address32;
+ u64 Address64;
+ } u;
+};
+
+struct MPI2_SCSI_IO_CDB_EEDP32 {
+ u8 CDB[20]; /* 0x00 */
+ u32 PrimaryReferenceTag; /* 0x14 */
+ u16 PrimaryApplicationTag; /* 0x18 */
+ u16 PrimaryApplicationTagMask; /* 0x1A */
+ u32 TransferLength; /* 0x1C */
+};
+
+struct MPI2_SGE_CHAIN_UNION {
+ u16 Length;
+ u8 NextChainOffset;
+ u8 Flags;
+ union {
+ u32 Address32;
+ u64 Address64;
+ } u;
+};
+
+struct MPI2_IEEE_SGE_SIMPLE32 {
+ u32 Address;
+ u32 FlagsLength;
+};
+
+struct MPI2_IEEE_SGE_CHAIN32 {
+ u32 Address;
+ u32 FlagsLength;
+};
+
+struct MPI2_IEEE_SGE_SIMPLE64 {
+ u64 Address;
+ u32 Length;
+ u16 Reserved1;
+ u8 Reserved2;
+ u8 Flags;
+};
+
+struct MPI2_IEEE_SGE_CHAIN64 {
+ u64 Address;
+ u32 Length;
+ u16 Reserved1;
+ u8 Reserved2;
+ u8 Flags;
+};
+
+union MPI2_IEEE_SGE_SIMPLE_UNION {
+ struct MPI2_IEEE_SGE_SIMPLE32 Simple32;
+ struct MPI2_IEEE_SGE_SIMPLE64 Simple64;
+};
+
+union MPI2_IEEE_SGE_CHAIN_UNION {
+ struct MPI2_IEEE_SGE_CHAIN32 Chain32;
+ struct MPI2_IEEE_SGE_CHAIN64 Chain64;
+};
+
+union MPI2_SGE_IO_UNION {
+ struct MPI2_SGE_SIMPLE_UNION MpiSimple;
+ struct MPI2_SGE_CHAIN_UNION MpiChain;
+ union MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple;
+ union MPI2_IEEE_SGE_CHAIN_UNION IeeeChain;
+};
+
+union MPI2_SCSI_IO_CDB_UNION {
+ u8 CDB32[32];
+ struct MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
+ struct MPI2_SGE_SIMPLE_UNION SGE;
+};
+
+/*
+ * RAID SCSI IO Request Message
+ * Total SGE count will be one less than _MPI2_SCSI_IO_REQUEST
+ */
+struct MPI2_RAID_SCSI_IO_REQUEST {
+ u16 DevHandle; /* 0x00 */
+ u8 ChainOffset; /* 0x02 */
+ u8 Function; /* 0x03 */
+ u16 Reserved1; /* 0x04 */
+ u8 Reserved2; /* 0x06 */
+ u8 MsgFlags; /* 0x07 */
+ u8 VP_ID; /* 0x08 */
+ u8 VF_ID; /* 0x09 */
+ u16 Reserved3; /* 0x0A */
+ u32 SenseBufferLowAddress; /* 0x0C */
+ u16 SGLFlags; /* 0x10 */
+ u8 SenseBufferLength; /* 0x12 */
+ u8 Reserved4; /* 0x13 */
+ u8 SGLOffset0; /* 0x14 */
+ u8 SGLOffset1; /* 0x15 */
+ u8 SGLOffset2; /* 0x16 */
+ u8 SGLOffset3; /* 0x17 */
+ u32 SkipCount; /* 0x18 */
+ u32 DataLength; /* 0x1C */
+ u32 BidirectionalDataLength; /* 0x20 */
+ u16 IoFlags; /* 0x24 */
+ u16 EEDPFlags; /* 0x26 */
+ u32 EEDPBlockSize; /* 0x28 */
+ u32 SecondaryReferenceTag; /* 0x2C */
+ u16 SecondaryApplicationTag; /* 0x30 */
+ u16 ApplicationTagTranslationMask; /* 0x32 */
+ u8 LUN[8]; /* 0x34 */
+ u32 Control; /* 0x3C */
+ union MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
+ struct RAID_CONTEXT RaidContext; /* 0x60 */
+ union MPI2_SGE_IO_UNION SGL; /* 0x80 */
+};
+
+/*
+ * MPT RAID MFA IO Descriptor.
+ */
+struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR {
+ u32 RequestFlags:8;
+ u32 MessageAddress1:24; /* bits 31:8*/
+ u32 MessageAddress2; /* bits 61:32 */
+};
+
+/* Default Request Descriptor */
+struct MPI2_DEFAULT_REQUEST_DESCRIPTOR {
+ u8 RequestFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 LMID; /* 0x04 */
+ u16 DescriptorTypeDependent; /* 0x06 */
+};
+
+/* High Priority Request Descriptor */
+struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR {
+ u8 RequestFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 LMID; /* 0x04 */
+ u16 Reserved1; /* 0x06 */
+};
+
+/* SCSI IO Request Descriptor */
+struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR {
+ u8 RequestFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 LMID; /* 0x04 */
+ u16 DevHandle; /* 0x06 */
+};
+
+/* SCSI Target Request Descriptor */
+struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR {
+ u8 RequestFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 LMID; /* 0x04 */
+ u16 IoIndex; /* 0x06 */
+};
+
+/* RAID Accelerator Request Descriptor */
+struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
+ u8 RequestFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 LMID; /* 0x04 */
+ u16 Reserved; /* 0x06 */
+};
+
+/* union of Request Descriptors */
+union MEGASAS_REQUEST_DESCRIPTOR_UNION {
+ struct MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
+ struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority;
+ struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO;
+ struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
+ struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
+ struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR MFAIo;
+ union {
+ struct {
+ u32 low;
+ u32 high;
+ } u;
+ u64 Words;
+ };
+};
+
+/* Default Reply Descriptor */
+struct MPI2_DEFAULT_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 DescriptorTypeDependent1; /* 0x02 */
+ u32 DescriptorTypeDependent2; /* 0x04 */
+};
+
+/* Address Reply Descriptor */
+struct MPI2_ADDRESS_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u32 ReplyFrameAddress; /* 0x04 */
+};
+
+/* SCSI IO Success Reply Descriptor */
+struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u16 TaskTag; /* 0x04 */
+ u16 Reserved1; /* 0x06 */
+};
+
+/* TargetAssist Success Reply Descriptor */
+struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u8 SequenceNumber; /* 0x04 */
+ u8 Reserved1; /* 0x05 */
+ u16 IoIndex; /* 0x06 */
+};
+
+/* Target Command Buffer Reply Descriptor */
+struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u8 VP_ID; /* 0x02 */
+ u8 Flags; /* 0x03 */
+ u16 InitiatorDevHandle; /* 0x04 */
+ u16 IoIndex; /* 0x06 */
+};
+
+/* RAID Accelerator Success Reply Descriptor */
+struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
+ u8 ReplyFlags; /* 0x00 */
+ u8 MSIxIndex; /* 0x01 */
+ u16 SMID; /* 0x02 */
+ u32 Reserved; /* 0x04 */
+};
+
+/* union of Reply Descriptors */
+union MPI2_REPLY_DESCRIPTORS_UNION {
+ struct MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
+ struct MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply;
+ struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess;
+ struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess;
+ struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
+ struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
+ RAIDAcceleratorSuccess;
+ u64 Words;
+};
+
+/* IOCInit Request message */
+struct MPI2_IOC_INIT_REQUEST {
+ u8 WhoInit; /* 0x00 */
+ u8 Reserved1; /* 0x01 */
+ u8 ChainOffset; /* 0x02 */
+ u8 Function; /* 0x03 */
+ u16 Reserved2; /* 0x04 */
+ u8 Reserved3; /* 0x06 */
+ u8 MsgFlags; /* 0x07 */
+ u8 VP_ID; /* 0x08 */
+ u8 VF_ID; /* 0x09 */
+ u16 Reserved4; /* 0x0A */
+ u16 MsgVersion; /* 0x0C */
+ u16 HeaderVersion; /* 0x0E */
+ u32 Reserved5; /* 0x10 */
+ u16 Reserved6; /* 0x14 */
+ u8 Reserved7; /* 0x16 */
+ u8 HostMSIxVectors; /* 0x17 */
+ u16 Reserved8; /* 0x18 */
+ u16 SystemRequestFrameSize; /* 0x1A */
+ u16 ReplyDescriptorPostQueueDepth; /* 0x1C */
+ u16 ReplyFreeQueueDepth; /* 0x1E */
+ u32 SenseBufferAddressHigh; /* 0x20 */
+ u32 SystemReplyAddressHigh; /* 0x24 */
+ u64 SystemRequestFrameBaseAddress; /* 0x28 */
+ u64 ReplyDescriptorPostQueueAddress;/* 0x30 */
+ u64 ReplyFreeQueueAddress; /* 0x38 */
+ u64 TimeStamp; /* 0x40 */
+};
+
+/* mrpriv defines */
+#define MR_PD_INVALID 0xFFFF
+#define MAX_SPAN_DEPTH 8
+#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
+#define MAX_ROW_SIZE 32
+#define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
+#define MAX_LOGICAL_DRIVES 64
+#define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
+#define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
+#define MAX_ARRAYS 128
+#define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
+#define MAX_PHYSICAL_DEVICES 256
+#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
+#define MR_DCMD_LD_MAP_GET_INFO 0x0300e101
+
+struct MR_DEV_HANDLE_INFO {
+ u16 curDevHdl;
+ u8 validHandles;
+ u8 reserved;
+ u16 devHandle[2];
+};
+
+struct MR_ARRAY_INFO {
+ u16 pd[MAX_RAIDMAP_ROW_SIZE];
+};
+
+struct MR_QUAD_ELEMENT {
+ u64 logStart;
+ u64 logEnd;
+ u64 offsetInSpan;
+ u32 diff;
+ u32 reserved1;
+};
+
+struct MR_SPAN_INFO {
+ u32 noElements;
+ u32 reserved1;
+ struct MR_QUAD_ELEMENT quad[MAX_RAIDMAP_SPAN_DEPTH];
+};
+
+struct MR_LD_SPAN {
+ u64 startBlk;
+ u64 numBlks;
+ u16 arrayRef;
+ u8 reserved[6];
+};
+
+struct MR_SPAN_BLOCK_INFO {
+ u64 num_rows;
+ struct MR_LD_SPAN span;
+ struct MR_SPAN_INFO block_span_info;
+};
+
+struct MR_LD_RAID {
+ struct {
+ u32 fpCapable:1;
+ u32 reserved5:3;
+ u32 ldPiMode:4;
+ u32 pdPiMode:4;
+ u32 encryptionType:8;
+ u32 fpWriteCapable:1;
+ u32 fpReadCapable:1;
+ u32 fpWriteAcrossStripe:1;
+ u32 fpReadAcrossStripe:1;
+ u32 reserved4:8;
+ } capability;
+ u32 reserved6;
+ u64 size;
+ u8 spanDepth;
+ u8 level;
+ u8 stripeShift;
+ u8 rowSize;
+ u8 rowDataSize;
+ u8 writeMode;
+ u8 PRL;
+ u8 SRL;
+ u16 targetId;
+ u8 ldState;
+ u8 regTypeReqOnWrite;
+ u8 modFactor;
+ u8 reserved2[1];
+ u16 seqNum;
+
+ struct {
+ u32 ldSyncRequired:1;
+ u32 reserved:31;
+ } flags;
+
+ u8 reserved3[0x5C];
+};
+
+struct MR_LD_SPAN_MAP {
+ struct MR_LD_RAID ldRaid;
+ u8 dataArmMap[MAX_RAIDMAP_ROW_SIZE];
+ struct MR_SPAN_BLOCK_INFO spanBlock[MAX_RAIDMAP_SPAN_DEPTH];
+};
+
+struct MR_FW_RAID_MAP {
+ u32 totalSize;
+ union {
+ struct {
+ u32 maxLd;
+ u32 maxSpanDepth;
+ u32 maxRowSize;
+ u32 maxPdCount;
+ u32 maxArrays;
+ } validationInfo;
+ u32 version[5];
+ u32 reserved1[5];
+ };
+
+ u32 ldCount;
+ u32 Reserved1;
+ u8 ldTgtIdToLd[MAX_RAIDMAP_LOGICAL_DRIVES+
+ MAX_RAIDMAP_VIEWS];
+ u8 fpPdIoTimeoutSec;
+ u8 reserved2[7];
+ struct MR_ARRAY_INFO arMapInfo[MAX_RAIDMAP_ARRAYS];
+ struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
+ struct MR_LD_SPAN_MAP ldSpanMap[1];
+};
+
+struct IO_REQUEST_INFO {
+ u64 ldStartBlock;
+ u32 numBlocks;
+ u16 ldTgtId;
+ u8 isRead;
+ u16 devHandle;
+ u64 pdBlock;
+ u8 fpOkForIo;
+};
+
+struct MR_LD_TARGET_SYNC {
+ u8 targetId;
+ u8 reserved;
+ u16 seqNum;
+};
+
+#define IEEE_SGE_FLAGS_ADDR_MASK (0x03)
+#define IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00)
+#define IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01)
+#define IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02)
+#define IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
+#define IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80)
+#define IEEE_SGE_FLAGS_END_OF_LIST (0x40)
+
+struct megasas_register_set;
+struct megasas_instance;
+
+union desc_word {
+ u64 word;
+ struct {
+ u32 low;
+ u32 high;
+ } u;
+};
+
+struct megasas_cmd_fusion {
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+ dma_addr_t io_request_phys_addr;
+
+ union MPI2_SGE_IO_UNION *sg_frame;
+ dma_addr_t sg_frame_phys_addr;
+
+ u8 *sense;
+ dma_addr_t sense_phys_addr;
+
+ struct list_head list;
+ struct scsi_cmnd *scmd;
+ struct megasas_instance *instance;
+
+ u8 retry_for_fw_reset;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *request_desc;
+
+ /*
+ * Context for a MFI frame.
+ * Used to get the mfi cmd from list when a MFI cmd is completed
+ */
+ u32 sync_cmd_idx;
+ u32 index;
+ u8 flags;
+};
+
+struct LD_LOAD_BALANCE_INFO {
+ u8 loadBalanceFlag;
+ u8 reserved1;
+ u16 raid1DevHandle[2];
+ atomic_t scsi_pending_cmds[2];
+ u64 last_accessed_block[2];
+};
+
+struct MR_FW_RAID_MAP_ALL {
+ struct MR_FW_RAID_MAP raidMap;
+ struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
+} __attribute__ ((packed));
+
+struct fusion_context {
+ struct megasas_cmd_fusion **cmd_list;
+ struct list_head cmd_pool;
+
+ spinlock_t cmd_pool_lock;
+
+ dma_addr_t req_frames_desc_phys;
+ u8 *req_frames_desc;
+
+ struct dma_pool *io_request_frames_pool;
+ dma_addr_t io_request_frames_phys;
+ u8 *io_request_frames;
+
+ struct dma_pool *sg_dma_pool;
+ struct dma_pool *sense_dma_pool;
+
+ dma_addr_t reply_frames_desc_phys;
+ union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc;
+ struct dma_pool *reply_frames_desc_pool;
+
+ u16 last_reply_idx;
+
+ u32 reply_q_depth;
+ u32 request_alloc_sz;
+ u32 reply_alloc_sz;
+ u32 io_frames_alloc_sz;
+
+ u16 max_sge_in_main_msg;
+ u16 max_sge_in_chain;
+
+ u8 chain_offset_io_request;
+ u8 chain_offset_mfi_pthru;
+
+ struct MR_FW_RAID_MAP_ALL *ld_map[2];
+ dma_addr_t ld_map_phys[2];
+
+ u32 map_sz;
+ u8 fast_path_io;
+ struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
+};
+
+union desc_value {
+ u64 word;
+ struct {
+ u32 low;
+ u32 high;
+ } u;
+};
+
+#endif /* _MEGARAID_SAS_FUSION_H_ */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index 4b1c2f0350f9..8be75e65f763 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
* scatter/gather formats.
* Creation Date: June 21, 2006
*
- * mpi2.h Version: 02.00.15
+ * mpi2.h Version: 02.00.16
*
* Version History
* ---------------
@@ -61,6 +61,8 @@
* Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL.
* Added defines for product-specific range of message
* function codes, 0xF0 to 0xFF.
+ * 05-12-10 02.00.16 Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added alternative defines for the SGE Direction bit.
* --------------------------------------------------------------------------
*/
@@ -86,7 +88,7 @@
#define MPI2_VERSION_02_00 (0x0200)
/* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT (0x0F)
+#define MPI2_HEADER_VERSION_UNIT (0x10)
#define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -929,6 +931,9 @@ typedef struct _MPI2_MPI_SGE_UNION
#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00)
#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04)
+#define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST)
+#define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC)
+
/* Address Size */
#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index e3728d736d85..d76a65847603 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
* Title: MPI Configuration messages and pages
* Creation Date: November 10, 2006
*
- * mpi2_cnfg.h Version: 02.00.14
+ * mpi2_cnfg.h Version: 02.00.15
*
* Version History
* ---------------
@@ -121,6 +121,10 @@
* Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines.
* Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines.
* Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines.
+ * 05-12-10 02.00.15 Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT
+ * define.
+ * Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define.
+ * Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define.
* --------------------------------------------------------------------------
*/
@@ -333,7 +337,7 @@ typedef struct _MPI2_CONFIG_REQUEST
#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06)
#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07)
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* Config Reply Message */
@@ -379,6 +383,8 @@ typedef struct _MPI2_CONFIG_REPLY
#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064)
#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065)
+#define MPI2_MFGPAGE_DEVID_SSS6200 (0x007E)
+
#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080)
#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081)
#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082)
@@ -390,6 +396,8 @@ typedef struct _MPI2_CONFIG_REPLY
#define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E)
+
+
/* Manufacturing Page 0 */
typedef struct _MPI2_CONFIG_PAGE_MAN_0
@@ -729,6 +737,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
/* IO Unit Page 1 Flags defines */
#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800)
#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600)
+#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9)
#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000)
#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200)
#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400)
@@ -1347,6 +1356,7 @@ typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0
#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000)
#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000)
#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000)
+#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT (0x00000080)
#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040)
#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020)
#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000)
@@ -1469,11 +1479,15 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03)
#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04)
#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05)
+#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE (0x06)
#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF)
/* PhysDiskAttributes defines */
+#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK (0x0C)
#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08)
#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04)
+
+#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK (0x03)
#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02)
#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01)
@@ -1545,6 +1559,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03)
#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04)
#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05)
+#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY (0x06)
#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08)
#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09)
#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A)
@@ -1571,6 +1586,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000)
#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000)
+#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION (27)
#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000)
#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000)
#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
index bd6c92b5fae5..b1e88f26b748 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
@@ -291,6 +291,7 @@ mpi2_raid.h
* can be sized by the build environment.
* 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
* VolumeCreationFlags and marked the old one as obsolete.
+ * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
* --------------------------------------------------------------------------
mpi2_sas.h
@@ -301,6 +302,7 @@ mpi2_sas.h
* Request.
* 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
* to MPI2_SGE_IO_UNION since it supports chained SGLs.
+ * 05-12-10 02.00.04 Modified some comments.
* --------------------------------------------------------------------------
mpi2_targ.h
@@ -324,6 +326,7 @@ mpi2_tool.h
* and reply messages.
* Added MPI2_DIAG_BUF_TYPE_EXTENDED.
* Incremented MPI2_DIAG_BUF_TYPE_COUNT.
+ * 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
* --------------------------------------------------------------------------
mpi2_type.h
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
index c4c99dfcb820..20e6b8869341 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -6,7 +6,7 @@
* Title: MPI SCSI initiator mode messages and structures
* Creation Date: June 23, 2006
*
- * mpi2_init.h Version: 02.00.09
+ * mpi2_init.h Version: 02.00.10
*
* Version History
* ---------------
@@ -32,6 +32,7 @@
* Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
* Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
* 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it.
+ * 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request.
* --------------------------------------------------------------------------
*/
@@ -98,7 +99,13 @@ typedef struct _MPI2_SCSI_IO_REQUEST
U8 LUN[8]; /* 0x34 */
U32 Control; /* 0x3C */
MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
+
+#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */
+ MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion;
+#endif
+
MPI2_SGE_IO_UNION SGL; /* 0x60 */
+
} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index 495bedc4d1f7..761cbdb8a033 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006
*
- * mpi2_ioc.h Version: 02.00.14
+ * mpi2_ioc.h Version: 02.00.15
*
* Version History
* ---------------
@@ -101,6 +101,8 @@
* 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines.
* Added PowerManagementControl Request structures and
* defines.
+ * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete.
+ * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
* --------------------------------------------------------------------------
*/
@@ -456,7 +458,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
#define MPI2_EVENT_STATE_CHANGE (0x0002)
#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005)
#define MPI2_EVENT_EVENT_CHANGE (0x000A)
-#define MPI2_EVENT_TASK_SET_FULL (0x000E)
+#define MPI2_EVENT_TASK_SET_FULL (0x000E) /* obsolete */
#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F)
#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014)
#define MPI2_EVENT_SAS_DISCOVERY (0x0016)
@@ -517,6 +519,7 @@ typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
MPI2_POINTER pMpi2EventDataHardResetReceived_t;
/* Task Set Full Event data */
+/* this event is obsolete */
typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL
{
@@ -831,6 +834,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03)
#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04)
#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05)
+#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY (0x06)
#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08)
#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09)
#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
index 5160c33d2a00..bd61a7b60a2b 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2008 LSI Corporation.
+ * Copyright (c) 2000-2010 LSI Corporation.
*
*
* Name: mpi2_raid.h
* Title: MPI Integrated RAID messages and structures
* Creation Date: April 26, 2007
*
- * mpi2_raid.h Version: 02.00.04
+ * mpi2_raid.h Version: 02.00.05
*
* Version History
* ---------------
@@ -22,6 +22,7 @@
* can be sized by the build environment.
* 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
* VolumeCreationFlags and marked the old one as obsolete.
+ * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
* --------------------------------------------------------------------------
*/
@@ -260,6 +261,7 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002)
#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003)
+#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004)
/* RAID Action Reply ActionData union */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
index 2d8aeed51392..608f6d6e6fca 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2007 LSI Corporation.
+ * Copyright (c) 2000-2010 LSI Corporation.
*
*
* Name: mpi2_sas.h
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: February 9, 2007
*
- * mpi2.h Version: 02.00.03
+ * mpi2_sas.h Version: 02.00.04
*
* Version History
* ---------------
@@ -20,6 +20,7 @@
* Request.
* 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
* to MPI2_SGE_IO_UNION since it supports chained SGLs.
+ * 05-12-10 02.00.04 Modified some comments.
* --------------------------------------------------------------------------
*/
@@ -110,7 +111,7 @@ typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
/* values for PassthroughFlags field */
#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* SMP Passthrough Reply Message */
@@ -174,7 +175,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002)
#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001)
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* SATA Passthrough Reply Message */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 686b09b81219..5c6e3a67bb94 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -6,7 +6,7 @@
* Title: MPI diagnostic tool structures and definitions
* Creation Date: March 26, 2007
*
- * mpi2_tool.h Version: 02.00.04
+ * mpi2_tool.h Version: 02.00.05
*
* Version History
* ---------------
@@ -22,6 +22,7 @@
* and reply messages.
* Added MPI2_DIAG_BUF_TYPE_EXTENDED.
* Incremented MPI2_DIAG_BUF_TYPE_COUNT.
+ * 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
* --------------------------------------------------------------------------
*/
@@ -37,6 +38,7 @@
/* defines for the Tools */
#define MPI2_TOOLBOX_CLEAN_TOOL (0x00)
#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
+#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02)
#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
#define MPI2_TOOLBOX_BEACON_TOOL (0x05)
#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06)
@@ -102,8 +104,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
* Toolbox Memory Move request
****************************************************************************/
-typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
-{
+typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST {
U8 Tool; /* 0x00 */
U8 Reserved1; /* 0x01 */
U8 ChainOffset; /* 0x02 */
@@ -120,6 +121,44 @@ typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
/****************************************************************************
+* Toolbox Diagnostic Data Upload request
+****************************************************************************/
+
+typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST {
+ U8 Tool; /* 0x00 */
+ U8 Reserved1; /* 0x01 */
+ U8 ChainOffset; /* 0x02 */
+ U8 Function; /* 0x03 */
+ U16 Reserved2; /* 0x04 */
+ U8 Reserved3; /* 0x06 */
+ U8 MsgFlags; /* 0x07 */
+ U8 VP_ID; /* 0x08 */
+ U8 VF_ID; /* 0x09 */
+ U16 Reserved4; /* 0x0A */
+ U8 SGLFlags; /* 0x0C */
+ U8 Reserved5; /* 0x0D */
+ U16 Reserved6; /* 0x0E */
+ U32 Flags; /* 0x10 */
+ U32 DataLength; /* 0x14 */
+ MPI2_SGE_SIMPLE_UNION SGL; /* 0x18 */
+} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+Mpi2ToolboxDiagDataUploadRequest_t,
+MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t;
+
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
+
+
+typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER {
+ U32 DiagDataLength; /* 00h */
+ U8 FormatCode; /* 04h */
+ U8 Reserved1; /* 05h */
+ U16 Reserved2; /* 06h */
+} MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER,
+Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t;
+
+
+/****************************************************************************
* Toolbox ISTWI Read Write Tool
****************************************************************************/
@@ -162,7 +201,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11)
#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12)
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* Toolbox ISTWI Read Write Tool reply message */
@@ -248,7 +287,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
Mpi2ToolboxDiagnosticCliRequest_t,
MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* Toolbox Diagnostic CLI Tool reply message */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 12faf64f91b0..b2a817055b8b 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -65,7 +65,6 @@
static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
-#define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */
static int max_queue_depth = -1;
module_param(max_queue_depth, int, 0);
@@ -79,6 +78,10 @@ static int msix_disable = -1;
module_param(msix_disable, int, 0);
MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
+static int missing_delay[2] = {-1, -1};
+module_param_array(missing_delay, int, NULL, 0);
+MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
+
/* diag_buffer_enable is bitwise
* bit 0 set = TRACE
* bit 1 set = SNAPSHOT
@@ -515,9 +518,6 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
case MPI2_EVENT_EVENT_CHANGE:
desc = "Event Change";
break;
- case MPI2_EVENT_TASK_SET_FULL:
- desc = "Task Set Full";
- break;
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
desc = "Device Status Change";
break;
@@ -758,7 +758,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
if (smid < ioc->internal_smid) {
i = smid - ioc->hi_priority_smid;
cb_idx = ioc->hpr_lookup[i].cb_idx;
- } else {
+ } else if (smid <= ioc->hba_queue_depth) {
i = smid - ioc->internal_smid;
cb_idx = ioc->internal_lookup[i].cb_idx;
}
@@ -848,6 +848,7 @@ _base_interrupt(int irq, void *bus_id)
return IRQ_NONE;
completed_cmds = 0;
+ cb_idx = 0xFF;
do {
rd.word = rpf->Words;
if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
@@ -860,6 +861,9 @@ _base_interrupt(int irq, void *bus_id)
MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
reply = le32_to_cpu
(rpf->AddressReply.ReplyFrameAddress);
+ if (reply > ioc->reply_dma_max_address ||
+ reply < ioc->reply_dma_min_address)
+ reply = 0;
} else if (request_desript_type ==
MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
goto next;
@@ -1489,6 +1493,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
{
unsigned long flags;
int i;
+ struct chain_tracker *chain_req, *next;
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
if (smid >= ioc->hi_priority_smid) {
@@ -1511,6 +1516,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
/* scsiio queue */
i = smid - 1;
+ if (!list_empty(&ioc->scsi_lookup[i].chain_list)) {
+ list_for_each_entry_safe(chain_req, next,
+ &ioc->scsi_lookup[i].chain_list, tracker_list) {
+ list_del_init(&chain_req->tracker_list);
+ list_add_tail(&chain_req->tracker_list,
+ &ioc->free_chain_list);
+ }
+ }
ioc->scsi_lookup[i].cb_idx = 0xFF;
ioc->scsi_lookup[i].scmd = NULL;
list_add_tail(&ioc->scsi_lookup[i].tracker_list,
@@ -1819,6 +1832,97 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
}
/**
+ * _base_update_missing_delay - change the missing delay timers
+ * @ioc: per adapter object
+ * @device_missing_delay: amount of time till device is reported missing
+ * @io_missing_delay: interval IO is returned when there is a missing device
+ *
+ * Return nothing.
+ *
+ * Passed on the command line, this function will modify the device missing
+ * delay, as well as the io missing delay. This should be called at driver
+ * load time.
+ */
+static void
+_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
+ u16 device_missing_delay, u8 io_missing_delay)
+{
+ u16 dmd, dmd_new, dmd_orignal;
+ u8 io_missing_delay_original;
+ u16 sz;
+ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
+ Mpi2ConfigReply_t mpi_reply;
+ u8 num_phys = 0;
+ u16 ioc_status;
+
+ mpt2sas_config_get_number_hba_phys(ioc, &num_phys);
+ if (!num_phys)
+ return;
+
+ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys *
+ sizeof(Mpi2SasIOUnit1PhyData_t));
+ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
+ if (!sas_iounit_pg1) {
+ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ goto out;
+ }
+ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
+ sas_iounit_pg1, sz))) {
+ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ goto out;
+ }
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+ MPI2_IOCSTATUS_MASK;
+ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ goto out;
+ }
+
+ /* device missing delay */
+ dmd = sas_iounit_pg1->ReportDeviceMissingDelay;
+ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
+ dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
+ else
+ dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
+ dmd_orignal = dmd;
+ if (device_missing_delay > 0x7F) {
+ dmd = (device_missing_delay > 0x7F0) ? 0x7F0 :
+ device_missing_delay;
+ dmd = dmd / 16;
+ dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16;
+ } else
+ dmd = device_missing_delay;
+ sas_iounit_pg1->ReportDeviceMissingDelay = dmd;
+
+ /* io missing delay */
+ io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay;
+ sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay;
+
+ if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
+ sz)) {
+ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
+ dmd_new = (dmd &
+ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
+ else
+ dmd_new =
+ dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
+ printk(MPT2SAS_INFO_FMT "device_missing_delay: old(%d), "
+ "new(%d)\n", ioc->name, dmd_orignal, dmd_new);
+ printk(MPT2SAS_INFO_FMT "ioc_missing_delay: old(%d), "
+ "new(%d)\n", ioc->name, io_missing_delay_original,
+ io_missing_delay);
+ ioc->device_missing_delay = dmd_new;
+ ioc->io_missing_delay = io_missing_delay;
+ }
+
+out:
+ kfree(sas_iounit_pg1);
+}
+
+/**
* _base_static_config_pages - static start of day config pages
* @ioc: per adapter object
*
@@ -1855,6 +1959,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
+
}
/**
@@ -1868,6 +1973,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
static void
_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
{
+ int i;
+
dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
@@ -1932,6 +2039,20 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
}
kfree(ioc->hpr_lookup);
kfree(ioc->internal_lookup);
+ if (ioc->chain_lookup) {
+ for (i = 0; i < ioc->chain_depth; i++) {
+ if (ioc->chain_lookup[i].chain_buffer)
+ pci_pool_free(ioc->chain_dma_pool,
+ ioc->chain_lookup[i].chain_buffer,
+ ioc->chain_lookup[i].chain_buffer_dma);
+ }
+ if (ioc->chain_dma_pool)
+ pci_pool_destroy(ioc->chain_dma_pool);
+ }
+ if (ioc->chain_lookup) {
+ free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
+ ioc->chain_lookup = NULL;
+ }
}
@@ -1953,6 +2074,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
u32 sz, total_sz;
u32 retry_sz;
u16 max_request_credit;
+ int i;
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__));
@@ -1970,14 +2092,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
}
/* command line tunables for max controller queue depth */
- if (max_queue_depth != -1) {
+ if (max_queue_depth != -1)
max_request_credit = (max_queue_depth < facts->RequestCredit)
? max_queue_depth : facts->RequestCredit;
- } else {
- max_request_credit = (facts->RequestCredit >
- MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
- facts->RequestCredit;
- }
+ else
+ max_request_credit = facts->RequestCredit;
ioc->hba_queue_depth = max_request_credit;
ioc->hi_priority_depth = facts->HighPriorityCredit;
@@ -2083,7 +2202,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
* "frame for smid=0
*/
ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
- sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz);
+ sz = ((ioc->scsiio_depth + 1) * ioc->request_sz);
/* hi-priority queue */
sz += (ioc->hi_priority_depth * ioc->request_sz);
@@ -2124,19 +2243,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
ioc->request_sz);
- ioc->chain = ioc->internal + (ioc->internal_depth *
- ioc->request_sz);
- ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth *
- ioc->request_sz);
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
"depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
ioc->request, ioc->hba_queue_depth, ioc->request_sz,
(ioc->hba_queue_depth * ioc->request_sz)/1024));
- dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
- "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
- ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
- ioc->request_sz))/1024));
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
ioc->name, (unsigned long long) ioc->request_dma));
total_sz += sz;
@@ -2155,6 +2266,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
"depth(%d)\n", ioc->name, ioc->request,
ioc->scsiio_depth));
+ /* loop till the allocation succeeds */
+ do {
+ sz = ioc->chain_depth * sizeof(struct chain_tracker);
+ ioc->chain_pages = get_order(sz);
+ ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
+ GFP_KERNEL, ioc->chain_pages);
+ if (ioc->chain_lookup == NULL)
+ ioc->chain_depth -= 100;
+ } while (ioc->chain_lookup == NULL);
+ ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
+ ioc->request_sz, 16, 0);
+ if (!ioc->chain_dma_pool) {
+ printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create "
+ "failed\n", ioc->name);
+ goto out;
+ }
+ for (i = 0; i < ioc->chain_depth; i++) {
+ ioc->chain_lookup[i].chain_buffer = pci_pool_alloc(
+ ioc->chain_dma_pool , GFP_KERNEL,
+ &ioc->chain_lookup[i].chain_buffer_dma);
+ if (!ioc->chain_lookup[i].chain_buffer) {
+ ioc->chain_depth = i;
+ goto chain_done;
+ }
+ total_sz += ioc->request_sz;
+ }
+chain_done:
+ dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth"
+ "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
+ ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
+ ioc->request_sz))/1024));
+
/* initialize hi-priority queue smid's */
ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
sizeof(struct request_tracker), GFP_KERNEL);
@@ -2221,6 +2364,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
ioc->name);
goto out;
}
+ ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
+ ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth"
"(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply,
ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024));
@@ -2302,7 +2447,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
return 0;
out:
- _base_release_memory_pools(ioc);
return -ENOMEM;
}
@@ -3485,6 +3629,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
INIT_LIST_HEAD(&ioc->free_list);
smid = 1;
for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
+ INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
ioc->scsi_lookup[i].cb_idx = 0xFF;
ioc->scsi_lookup[i].smid = smid;
ioc->scsi_lookup[i].scmd = NULL;
@@ -3511,6 +3656,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
list_add_tail(&ioc->internal_lookup[i].tracker_list,
&ioc->internal_free_list);
}
+
+ /* chain pool */
+ INIT_LIST_HEAD(&ioc->free_chain_list);
+ for (i = 0; i < ioc->chain_depth; i++)
+ list_add_tail(&ioc->chain_lookup[i].tracker_list,
+ &ioc->free_chain_list);
+
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
/* initialize Reply Free Queue */
@@ -3708,12 +3860,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME);
_base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK);
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
- _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
r = _base_make_ioc_operational(ioc, CAN_SLEEP);
if (r)
goto out_free_resources;
+ if (missing_delay[0] != -1 && missing_delay[1] != -1)
+ _base_update_missing_delay(ioc, missing_delay[0],
+ missing_delay[1]);
+
mpt2sas_base_start_watchdog(ioc);
return 0;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 0b15a8bdebfc..283568c6fb04 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,8 +69,8 @@
#define MPT2SAS_DRIVER_NAME "mpt2sas"
#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION "06.100.00.00"
-#define MPT2SAS_MAJOR_VERSION 06
+#define MPT2SAS_DRIVER_VERSION "07.100.00.00"
+#define MPT2SAS_MAJOR_VERSION 07
#define MPT2SAS_MINOR_VERSION 100
#define MPT2SAS_BUILD_VERSION 00
#define MPT2SAS_RELEASE_VERSION 00
@@ -419,6 +419,18 @@ enum reset_type {
};
/**
+ * struct chain_tracker - firmware chain tracker
+ * @chain_buffer: chain buffer
+ * @chain_buffer_dma: physical address
+ * @tracker_list: list of free request (ioc->free_chain_list)
+ */
+struct chain_tracker {
+ void *chain_buffer;
+ dma_addr_t chain_buffer_dma;
+ struct list_head tracker_list;
+};
+
+/**
* struct request_tracker - firmware request tracker
* @smid: system message id
* @scmd: scsi request pointer
@@ -430,6 +442,7 @@ struct request_tracker {
u16 smid;
struct scsi_cmnd *scmd;
u8 cb_idx;
+ struct list_head chain_list;
struct list_head tracker_list;
};
@@ -704,8 +717,10 @@ struct MPT2SAS_ADAPTER {
wait_queue_head_t reset_wq;
/* chain */
- u8 *chain;
- dma_addr_t chain_dma;
+ struct chain_tracker *chain_lookup;
+ struct list_head free_chain_list;
+ struct dma_pool *chain_dma_pool;
+ ulong chain_pages;
u16 max_sges_in_main_message;
u16 max_sges_in_chain_message;
u16 chains_needed_per_io;
@@ -737,6 +752,8 @@ struct MPT2SAS_ADAPTER {
u16 reply_sz;
u8 *reply;
dma_addr_t reply_dma;
+ u32 reply_dma_max_address;
+ u32 reply_dma_min_address;
struct dma_pool *reply_dma_pool;
/* reply free queue */
@@ -832,6 +849,8 @@ int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
ulong timeout, struct scsi_cmnd *scmd);
void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
+void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
+void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
u16 handle);
struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 40cb8aeb21b1..e92b77af5484 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -81,6 +81,7 @@ enum block_state {
BLOCKING,
};
+#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
/**
* _ctl_sas_device_find_by_handle - sas device search
* @ioc: per adapter object
@@ -107,7 +108,6 @@ _ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
return r;
}
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
/**
* _ctl_display_some_debug - debug routine
* @ioc: per adapter object
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 1a96a00418a4..eda347c57979 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -931,31 +931,32 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
}
/**
- * _scsih_get_chain_buffer_dma - obtain block of chains (dma address)
+ * _scsih_get_chain_buffer_tracker - obtain chain tracker
* @ioc: per adapter object
- * @smid: system request message index
+ * @smid: smid associated to an IO request
*
- * Returns phys pointer to chain buffer.
+ * Returns chain tracker(from ioc->free_chain_list)
*/
-static dma_addr_t
-_scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
+static struct chain_tracker *
+_scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
{
- return ioc->chain_dma + ((smid - 1) * (ioc->request_sz *
- ioc->chains_needed_per_io));
-}
+ struct chain_tracker *chain_req;
+ unsigned long flags;
-/**
- * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns virt pointer to chain buffer.
- */
-static void *
-_scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
- return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz *
- ioc->chains_needed_per_io)));
+ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+ if (list_empty(&ioc->free_chain_list)) {
+ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+ printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
+ ioc->name);
+ return NULL;
+ }
+ chain_req = list_entry(ioc->free_chain_list.next,
+ struct chain_tracker, tracker_list);
+ list_del_init(&chain_req->tracker_list);
+ list_add_tail(&chain_req->tracker_list,
+ &ioc->scsi_lookup[smid - 1].chain_list);
+ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+ return chain_req;
}
/**
@@ -986,6 +987,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
u32 sgl_flags;
u32 sgl_flags_last_element;
u32 sgl_flags_end_buffer;
+ struct chain_tracker *chain_req;
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -1033,8 +1035,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
/* initializing the chain flags and pointers */
chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
- chain = _scsih_get_chain_buffer(ioc, smid);
- chain_dma = _scsih_get_chain_buffer_dma(ioc, smid);
+ chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
+ if (!chain_req)
+ return -1;
+ chain = chain_req->chain_buffer;
+ chain_dma = chain_req->chain_buffer_dma;
do {
sges_in_segment = (sges_left <=
ioc->max_sges_in_chain_message) ? sges_left :
@@ -1070,8 +1075,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
sges_in_segment--;
}
- chain_dma += ioc->request_sz;
- chain += ioc->request_sz;
+ chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
+ if (!chain_req)
+ return -1;
+ chain = chain_req->chain_buffer;
+ chain_dma = chain_req->chain_buffer_dma;
} while (1);
@@ -1094,28 +1102,24 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
}
/**
- * _scsih_change_queue_depth - setting device queue depth
+ * _scsih_adjust_queue_depth - setting device queue depth
* @sdev: scsi device struct
* @qdepth: requested queue depth
- * @reason: calling context
*
- * Returns queue depth.
+ *
+ * Returns nothing
*/
-static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+static void
+_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
{
struct Scsi_Host *shost = sdev->host;
int max_depth;
- int tag_type;
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
struct MPT2SAS_DEVICE *sas_device_priv_data;
struct MPT2SAS_TARGET *sas_target_priv_data;
struct _sas_device *sas_device;
unsigned long flags;
- if (reason != SCSI_QDEPTH_DEFAULT)
- return -EOPNOTSUPP;
-
max_depth = shost->can_queue;
/* limit max device queue for SATA to 32 */
@@ -1141,8 +1145,27 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
max_depth = 1;
if (qdepth > max_depth)
qdepth = max_depth;
- tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG;
- scsi_adjust_queue_depth(sdev, tag_type, qdepth);
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+}
+
+/**
+ * _scsih_change_queue_depth - setting device queue depth
+ * @sdev: scsi device struct
+ * @qdepth: requested queue depth
+ * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP
+ * (see include/scsi/scsi_host.h for definition)
+ *
+ * Returns queue depth.
+ */
+static int
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+{
+ if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP)
+ _scsih_adjust_queue_depth(sdev, qdepth);
+ else if (reason == SCSI_QDEPTH_QFULL)
+ scsi_track_queue_full(sdev, qdepth);
+ else
+ return -EOPNOTSUPP;
if (sdev->inquiry_len > 7)
sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
@@ -2251,13 +2274,13 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
struct scsi_target *starget = scmd->device->sdev_target;
- starget_printk(KERN_INFO, starget, "attempting target reset! "
+ starget_printk(KERN_INFO, starget, "attempting device reset! "
"scmd(%p)\n", scmd);
_scsih_tm_display_info(ioc, scmd);
sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
- starget_printk(KERN_INFO, starget, "target been deleted! "
+ starget_printk(KERN_INFO, starget, "device been deleted! "
"scmd(%p)\n", scmd);
scmd->result = DID_NO_CONNECT << 16;
scmd->scsi_done(scmd);
@@ -2576,9 +2599,9 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
&sas_expander->sas_port_list, port_list) {
if (mpt2sas_port->remote_identify.device_type ==
- MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
+ SAS_EDGE_EXPANDER_DEVICE ||
mpt2sas_port->remote_identify.device_type ==
- MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
+ SAS_FANOUT_EXPANDER_DEVICE) {
spin_lock_irqsave(&ioc->sas_node_lock, flags);
expander_sibling =
@@ -2715,9 +2738,10 @@ static u8
_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
u8 msix_index, u32 reply)
{
+#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
Mpi2SasIoUnitControlReply_t *mpi_reply =
mpt2sas_base_get_reply_virt_addr(ioc, reply);
-
+#endif
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
"sc_complete:handle(0x%04x), (open) "
"smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -3963,6 +3987,7 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
Mpi2ConfigReply_t mpi_reply;
Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
u16 attached_handle;
+ u8 link_rate;
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
"updating handles for sas_host(0x%016llx)\n",
@@ -3984,15 +4009,17 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
goto out;
for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
+ link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4;
if (i == 0)
ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
PhyData[0].ControllerDevHandle);
ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
AttachedDevHandle);
+ if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
+ link_rate = MPI2_SAS_NEG_LINK_RATE_1_5;
mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
- attached_handle, i, sas_iounit_pg0->PhyData[i].
- NegotiatedLinkRate >> 4);
+ attached_handle, i, link_rate);
}
out:
kfree(sas_iounit_pg0);
@@ -4336,14 +4363,14 @@ _scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
}
/**
- * _scsih_expander_remove - removing expander object
+ * mpt2sas_expander_remove - removing expander object
* @ioc: per adapter object
* @sas_address: expander sas_address
*
* Return nothing.
*/
-static void
-_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
+void
+mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
{
struct _sas_node *sas_expander;
unsigned long flags;
@@ -4354,6 +4381,11 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
spin_lock_irqsave(&ioc->sas_node_lock, flags);
sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
sas_address);
+ if (!sas_expander) {
+ spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
+ return;
+ }
+ list_del(&sas_expander->list);
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
_scsih_expander_node_remove(ioc, sas_expander);
}
@@ -4643,6 +4675,33 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
sas_device_backup.sas_address));
}
+/**
+ * mpt2sas_device_remove - removing device object
+ * @ioc: per adapter object
+ * @sas_address: expander sas_address
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
+{
+ struct _sas_device *sas_device;
+ unsigned long flags;
+
+ if (ioc->shost_recovery)
+ return;
+
+ spin_lock_irqsave(&ioc->sas_device_lock, flags);
+ sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+ sas_address);
+ if (!sas_device) {
+ spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+ _scsih_remove_device(ioc, sas_device);
+}
+
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
/**
* _scsih_sas_topology_change_event_debug - debug for topology event
@@ -4737,7 +4796,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
int i;
u16 parent_handle, handle;
u16 reason_code;
- u8 phy_number;
+ u8 phy_number, max_phys;
struct _sas_node *sas_expander;
struct _sas_device *sas_device;
u64 sas_address;
@@ -4775,11 +4834,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
parent_handle);
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
- if (sas_expander)
+ if (sas_expander) {
sas_address = sas_expander->sas_address;
- else if (parent_handle < ioc->sas_hba.num_phys)
+ max_phys = sas_expander->num_phys;
+ } else if (parent_handle < ioc->sas_hba.num_phys) {
sas_address = ioc->sas_hba.sas_address;
- else
+ max_phys = ioc->sas_hba.num_phys;
+ } else
return;
/* handle siblings events */
@@ -4793,6 +4854,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
ioc->pci_error_recovery)
return;
phy_number = event_data->StartPhyNum + i;
+ if (phy_number >= max_phys)
+ continue;
reason_code = event_data->PHY[i].PhyStatus &
MPI2_EVENT_SAS_TOPO_RC_MASK;
if ((event_data->PHY[i].PhyStatus &
@@ -4844,7 +4907,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
/* handle expander removal */
if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
sas_expander)
- _scsih_expander_remove(ioc, sas_address);
+ mpt2sas_expander_remove(ioc, sas_address);
}
@@ -5773,90 +5836,6 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
}
/**
- * _scsih_task_set_full - handle task set full
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Throttle back qdepth.
- */
-static void
-_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
- *fw_event)
-{
- unsigned long flags;
- struct _sas_device *sas_device;
- static struct _raid_device *raid_device;
- struct scsi_device *sdev;
- int depth;
- u16 current_depth;
- u16 handle;
- int id, channel;
- u64 sas_address;
- Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
-
- current_depth = le16_to_cpu(event_data->CurrentDepth);
- handle = le16_to_cpu(event_data->DevHandle);
- spin_lock_irqsave(&ioc->sas_device_lock, flags);
- sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
- if (!sas_device) {
- spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
- return;
- }
- spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
- id = sas_device->id;
- channel = sas_device->channel;
- sas_address = sas_device->sas_address;
-
- /* if hidden raid component, then change to volume characteristics */
- if (test_bit(handle, ioc->pd_handles) && sas_device->volume_handle) {
- spin_lock_irqsave(&ioc->raid_device_lock, flags);
- raid_device = _scsih_raid_device_find_by_handle(
- ioc, sas_device->volume_handle);
- spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
- if (raid_device) {
- id = raid_device->id;
- channel = raid_device->channel;
- handle = raid_device->handle;
- sas_address = raid_device->wwid;
- }
- }
-
- if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL)
- starget_printk(KERN_INFO, sas_device->starget, "task set "
- "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n",
- handle, (unsigned long long)sas_address, current_depth);
-
- shost_for_each_device(sdev, ioc->shost) {
- if (sdev->id == id && sdev->channel == channel) {
- if (current_depth > sdev->queue_depth) {
- if (ioc->logging_level &
- MPT_DEBUG_TASK_SET_FULL)
- sdev_printk(KERN_INFO, sdev, "strange "
- "observation, the queue depth is"
- " (%d) meanwhile fw queue depth "
- "is (%d)\n", sdev->queue_depth,
- current_depth);
- continue;
- }
- depth = scsi_track_queue_full(sdev,
- current_depth - 1);
- if (depth > 0)
- sdev_printk(KERN_INFO, sdev, "Queue depth "
- "reduced to (%d)\n", depth);
- else if (depth < 0)
- sdev_printk(KERN_INFO, sdev, "Tagged Command "
- "Queueing is being disabled\n");
- else if (depth == 0)
- if (ioc->logging_level &
- MPT_DEBUG_TASK_SET_FULL)
- sdev_printk(KERN_INFO, sdev,
- "Queue depth not changed yet\n");
- }
- }
-}
-
-/**
* _scsih_prep_device_scan - initialize parameters prior to device scan
* @ioc: per adapter object
*
@@ -6219,7 +6198,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
sas_expander->responding = 0;
continue;
}
- _scsih_expander_remove(ioc, sas_expander->sas_address);
+ mpt2sas_expander_remove(ioc, sas_expander->sas_address);
goto retry_expander_search;
}
}
@@ -6343,9 +6322,6 @@ _firmware_event_work(struct work_struct *work)
case MPI2_EVENT_IR_OPERATION_STATUS:
_scsih_sas_ir_operation_status_event(ioc, fw_event);
break;
- case MPI2_EVENT_TASK_SET_FULL:
- _scsih_task_set_full(ioc, fw_event);
- break;
}
_scsih_fw_event_free(ioc, fw_event);
}
@@ -6415,7 +6391,6 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
case MPI2_EVENT_SAS_DISCOVERY:
case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_PHYSICAL_DISK:
- case MPI2_EVENT_TASK_SET_FULL:
break;
default: /* ignore the rest */
@@ -6490,56 +6465,23 @@ static void
_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
struct _sas_node *sas_expander)
{
- struct _sas_port *mpt2sas_port;
- struct _sas_device *sas_device;
- struct _sas_node *expander_sibling;
- unsigned long flags;
-
- if (!sas_expander)
- return;
+ struct _sas_port *mpt2sas_port, *next;
/* remove sibling ports attached to this expander */
- retry_device_search:
- list_for_each_entry(mpt2sas_port,
+ list_for_each_entry_safe(mpt2sas_port, next,
&sas_expander->sas_port_list, port_list) {
+ if (ioc->shost_recovery)
+ return;
if (mpt2sas_port->remote_identify.device_type ==
- SAS_END_DEVICE) {
- spin_lock_irqsave(&ioc->sas_device_lock, flags);
- sas_device =
- mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
- mpt2sas_port->remote_identify.sas_address);
- spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
- if (!sas_device)
- continue;
- _scsih_remove_device(ioc, sas_device);
- if (ioc->shost_recovery)
- return;
- goto retry_device_search;
- }
- }
-
- retry_expander_search:
- list_for_each_entry(mpt2sas_port,
- &sas_expander->sas_port_list, port_list) {
-
- if (mpt2sas_port->remote_identify.device_type ==
- MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
+ SAS_END_DEVICE)
+ mpt2sas_device_remove(ioc,
+ mpt2sas_port->remote_identify.sas_address);
+ else if (mpt2sas_port->remote_identify.device_type ==
+ SAS_EDGE_EXPANDER_DEVICE ||
mpt2sas_port->remote_identify.device_type ==
- MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
-
- spin_lock_irqsave(&ioc->sas_node_lock, flags);
- expander_sibling =
- mpt2sas_scsih_expander_find_by_sas_address(
- ioc, mpt2sas_port->remote_identify.sas_address);
- spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
- if (!expander_sibling)
- continue;
- _scsih_expander_remove(ioc,
- expander_sibling->sas_address);
- if (ioc->shost_recovery)
- return;
- goto retry_expander_search;
- }
+ SAS_FANOUT_EXPANDER_DEVICE)
+ mpt2sas_expander_remove(ioc,
+ mpt2sas_port->remote_identify.sas_address);
}
mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
@@ -6550,7 +6492,6 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
sas_expander->handle, (unsigned long long)
sas_expander->sas_address);
- list_del(&sas_expander->list);
kfree(sas_expander->phy);
kfree(sas_expander);
}
@@ -6668,9 +6609,7 @@ _scsih_remove(struct pci_dev *pdev)
{
struct Scsi_Host *shost = pci_get_drvdata(pdev);
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
- struct _sas_port *mpt2sas_port;
- struct _sas_device *sas_device;
- struct _sas_node *expander_sibling;
+ struct _sas_port *mpt2sas_port, *next_port;
struct _raid_device *raid_device, *next;
struct MPT2SAS_TARGET *sas_target_priv_data;
struct workqueue_struct *wq;
@@ -6702,28 +6641,18 @@ _scsih_remove(struct pci_dev *pdev)
}
/* free ports attached to the sas_host */
- retry_again:
- list_for_each_entry(mpt2sas_port,
+ list_for_each_entry_safe(mpt2sas_port, next_port,
&ioc->sas_hba.sas_port_list, port_list) {
if (mpt2sas_port->remote_identify.device_type ==
- SAS_END_DEVICE) {
- sas_device =
- mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
- mpt2sas_port->remote_identify.sas_address);
- if (sas_device) {
- _scsih_remove_device(ioc, sas_device);
- goto retry_again;
- }
- } else {
- expander_sibling =
- mpt2sas_scsih_expander_find_by_sas_address(ioc,
+ SAS_END_DEVICE)
+ mpt2sas_device_remove(ioc,
+ mpt2sas_port->remote_identify.sas_address);
+ else if (mpt2sas_port->remote_identify.device_type ==
+ SAS_EDGE_EXPANDER_DEVICE ||
+ mpt2sas_port->remote_identify.device_type ==
+ SAS_FANOUT_EXPANDER_DEVICE)
+ mpt2sas_expander_remove(ioc,
mpt2sas_port->remote_identify.sas_address);
- if (expander_sibling) {
- _scsih_expander_remove(ioc,
- expander_sibling->sas_address);
- goto retry_again;
- }
- }
}
/* free phys attached to the sas_host */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index b55c6dc07470..cb1cdecbe0f8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -465,62 +465,149 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
return rc;
}
+/**
+ * _transport_delete_port - helper function to removing a port
+ * @ioc: per adapter object
+ * @mpt2sas_port: mpt2sas per port object
+ *
+ * Returns nothing.
+ */
+static void
+_transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
+ struct _sas_port *mpt2sas_port)
+{
+ u64 sas_address = mpt2sas_port->remote_identify.sas_address;
+ enum sas_device_type device_type =
+ mpt2sas_port->remote_identify.device_type;
+
+ dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
+ "remove: sas_addr(0x%016llx)\n",
+ (unsigned long long) sas_address);
+
+ ioc->logging_level |= MPT_DEBUG_TRANSPORT;
+ if (device_type == SAS_END_DEVICE)
+ mpt2sas_device_remove(ioc, sas_address);
+ else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
+ device_type == SAS_FANOUT_EXPANDER_DEVICE)
+ mpt2sas_expander_remove(ioc, sas_address);
+ ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
+}
/**
- * _transport_delete_duplicate_port - (see below description)
+ * _transport_delete_phy - helper function to removing single phy from port
* @ioc: per adapter object
- * @sas_node: sas node object (either expander or sas host)
- * @sas_address: sas address of device being added
- * @phy_num: phy number
+ * @mpt2sas_port: mpt2sas per port object
+ * @mpt2sas_phy: mpt2sas per phy object
*
- * This function is called when attempting to add a new port that is claiming
- * the same phy resources already in use by another port. If we don't release
- * the claimed phy resources, the sas transport layer will hang from the BUG
- * in sas_port_add_phy.
+ * Returns nothing.
+ */
+static void
+_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
+ struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
+{
+ u64 sas_address = mpt2sas_port->remote_identify.sas_address;
+
+ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
+ "remove: sas_addr(0x%016llx), phy(%d)\n",
+ (unsigned long long) sas_address, mpt2sas_phy->phy_id);
+
+ list_del(&mpt2sas_phy->port_siblings);
+ mpt2sas_port->num_phys--;
+ sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
+ mpt2sas_phy->phy_belongs_to_port = 0;
+}
+
+/**
+ * _transport_add_phy - helper function to adding single phy to port
+ * @ioc: per adapter object
+ * @mpt2sas_port: mpt2sas per port object
+ * @mpt2sas_phy: mpt2sas per phy object
*
- * The reason we would hit this issue is becuase someone is changing the
- * sas address of a device on the fly, meanwhile controller firmware sends
- * EVENTs out of order when removing the previous instance of the device.
+ * Returns nothing.
*/
static void
-_transport_delete_duplicate_port(struct MPT2SAS_ADAPTER *ioc,
- struct _sas_node *sas_node, u64 sas_address, int phy_num)
+_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
+ struct _sas_phy *mpt2sas_phy)
{
- struct _sas_port *mpt2sas_port, *mpt2sas_port_duplicate;
- struct _sas_phy *mpt2sas_phy;
+ u64 sas_address = mpt2sas_port->remote_identify.sas_address;
- printk(MPT2SAS_ERR_FMT "new device located at sas_addr(0x%016llx), "
- "phy_id(%d)\n", ioc->name, (unsigned long long)sas_address,
- phy_num);
+ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
+ "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
+ sas_address, mpt2sas_phy->phy_id);
- mpt2sas_port_duplicate = NULL;
- list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, port_list) {
- dev_printk(KERN_ERR, &mpt2sas_port->port->dev,
- "existing device at sas_addr(0x%016llx), num_phys(%d)\n",
- (unsigned long long)
- mpt2sas_port->remote_identify.sas_address,
- mpt2sas_port->num_phys);
- list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
+ list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
+ mpt2sas_port->num_phys++;
+ sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
+ mpt2sas_phy->phy_belongs_to_port = 1;
+}
+
+/**
+ * _transport_add_phy_to_an_existing_port - adding new phy to existing port
+ * @ioc: per adapter object
+ * @sas_node: sas node object (either expander or sas host)
+ * @mpt2sas_phy: mpt2sas per phy object
+ * @sas_address: sas address of device/expander were phy needs to be added to
+ *
+ * Returns nothing.
+ */
+static void
+_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
+struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
+{
+ struct _sas_port *mpt2sas_port;
+ struct _sas_phy *phy_srch;
+
+ if (mpt2sas_phy->phy_belongs_to_port == 1)
+ return;
+
+ list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
+ port_list) {
+ if (mpt2sas_port->remote_identify.sas_address !=
+ sas_address)
+ continue;
+ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
port_siblings) {
- dev_printk(KERN_ERR, &mpt2sas_phy->phy->dev,
- "phy_number(%d)\n", mpt2sas_phy->phy_id);
- if (mpt2sas_phy->phy_id == phy_num)
- mpt2sas_port_duplicate = mpt2sas_port;
+ if (phy_srch == mpt2sas_phy)
+ return;
}
+ _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
+ return;
}
- if (!mpt2sas_port_duplicate)
+}
+
+/**
+ * _transport_del_phy_from_an_existing_port - delete phy from existing port
+ * @ioc: per adapter object
+ * @sas_node: sas node object (either expander or sas host)
+ * @mpt2sas_phy: mpt2sas per phy object
+ *
+ * Returns nothing.
+ */
+static void
+_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
+ struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
+{
+ struct _sas_port *mpt2sas_port, *next;
+ struct _sas_phy *phy_srch;
+
+ if (mpt2sas_phy->phy_belongs_to_port == 0)
return;
- dev_printk(KERN_ERR, &mpt2sas_port_duplicate->port->dev,
- "deleting duplicate device at sas_addr(0x%016llx), phy(%d)!!!!\n",
- (unsigned long long)
- mpt2sas_port_duplicate->remote_identify.sas_address, phy_num);
- ioc->logging_level |= MPT_DEBUG_TRANSPORT;
- mpt2sas_transport_port_remove(ioc,
- mpt2sas_port_duplicate->remote_identify.sas_address,
- sas_node->sas_address);
- ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
+ list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
+ port_list) {
+ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
+ port_siblings) {
+ if (phy_srch != mpt2sas_phy)
+ continue;
+ if (mpt2sas_port->num_phys == 1)
+ _transport_delete_port(ioc, mpt2sas_port);
+ else
+ _transport_delete_phy(ioc, mpt2sas_port,
+ mpt2sas_phy);
+ return;
+ }
+ }
}
/**
@@ -537,11 +624,13 @@ _transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
{
int i;
- for (i = 0; i < sas_node->num_phys; i++)
- if (sas_node->phy[i].remote_identify.sas_address == sas_address)
- if (sas_node->phy[i].phy_belongs_to_port)
- _transport_delete_duplicate_port(ioc, sas_node,
- sas_address, i);
+ for (i = 0; i < sas_node->num_phys; i++) {
+ if (sas_node->phy[i].remote_identify.sas_address != sas_address)
+ continue;
+ if (sas_node->phy[i].phy_belongs_to_port == 1)
+ _transport_del_phy_from_an_existing_port(ioc, sas_node,
+ &sas_node->phy[i]);
+ }
}
/**
@@ -905,10 +994,12 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
mpt2sas_phy = &sas_node->phy[phy_number];
mpt2sas_phy->attached_handle = handle;
- if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
+ if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
_transport_set_identify(ioc, handle,
&mpt2sas_phy->remote_identify);
- else
+ _transport_add_phy_to_an_existing_port(ioc, sas_node,
+ mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
+ } else
memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
sas_identify));
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 0433ea6f27c9..b37c8a3c1bb0 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
/* create a bio for continuation segment */
bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
GFP_KERNEL);
- if (unlikely(!bio))
- return -ENOMEM;
+ if (IS_ERR(bio))
+ return PTR_ERR(bio);
bio->bi_rw |= REQ_WRITE;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 5e76a624cb08..321cf3ae8630 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -62,6 +62,7 @@
static unsigned int pmcraid_debug_log;
static unsigned int pmcraid_disable_aen;
static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+static unsigned int pmcraid_enable_msix;
/*
* Data structures to support multiple adapters by the LLD.
@@ -2227,12 +2228,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
/* Once either bist or pci reset is done, restore PCI config
* space. If this fails, proceed with hard reset again
*/
- if (pci_restore_state(pinstance->pdev)) {
- pmcraid_info("config-space error resetting again\n");
- pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
- pmcraid_reset_alert(cmd);
- break;
- }
+ pci_restore_state(pinstance->pdev);
/* fail all pending commands */
pmcraid_fail_outstanding_cmds(pinstance);
@@ -4691,7 +4687,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
int rc;
struct pci_dev *pdev = pinstance->pdev;
- if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+ if ((pmcraid_enable_msix) &&
+ (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
int i;
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 1134279604e8..4db210d93947 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -42,7 +42,7 @@
*/
#define PMCRAID_DRIVER_NAME "PMC MaxRAID"
#define PMCRAID_DEVFILE "pmcsas"
-#define PMCRAID_DRIVER_VERSION "2.0.3"
+#define PMCRAID_DRIVER_VERSION "1.0.3"
#define PMCRAID_DRIVER_DATE __DATE__
#define PMCRAID_FW_VERSION_1 0x002
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry {
__u8 lun[PMCRAID_LUN_LEN];
} __attribute__((packed, aligned(4)));
-/* extended configuration table sizes are of 64 bytes in size */
-#define PMCRAID_CFGTE_EXT_SIZE 32
+/* extended configuration table sizes are also of 32 bytes in size */
struct pmcraid_config_table_entry_ext {
struct pmcraid_config_table_entry cfgte;
- __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
};
/* resource types (config_table_entry.resource_type values) */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index bc8194f74625..44578b56ad0a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1309,6 +1309,31 @@ qla2x00_fabric_param_show(struct device *dev, struct device_attribute *attr,
}
static ssize_t
+qla2x00_thermal_temp_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ int rval = QLA_FUNCTION_FAILED;
+ uint16_t temp, frac;
+
+ if (!vha->hw->flags.thermal_supported)
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ temp = frac = 0;
+ if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+ test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+ DEBUG2_3_11(printk(KERN_WARNING
+ "%s(%ld): isp reset in progress.\n",
+ __func__, vha->host_no));
+ else if (!vha->hw->flags.eeh_busy)
+ rval = qla2x00_get_thermal_temp(vha, &temp, &frac);
+ if (rval != QLA_SUCCESS)
+ temp = frac = 0;
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d\n", temp, frac);
+}
+
+static ssize_t
qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -1366,6 +1391,7 @@ static DEVICE_ATTR(vn_port_mac_address, S_IRUGO,
qla2x00_vn_port_mac_address_show, NULL);
static DEVICE_ATTR(fabric_param, S_IRUGO, qla2x00_fabric_param_show, NULL);
static DEVICE_ATTR(fw_state, S_IRUGO, qla2x00_fw_state_show, NULL);
+static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL);
struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
@@ -1394,6 +1420,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_fabric_param,
&dev_attr_fw_state,
&dev_attr_optrom_gold_fw_version,
+ &dev_attr_thermal_temp,
NULL,
};
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 31a4121a2be1..903b0586ded3 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -103,7 +103,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
bsg_job->reply->reply_payload_rcv_len = 0;
- if (!IS_QLA24XX_TYPE(ha) || !IS_QLA25XX(ha)) {
+ if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))) {
ret = -EINVAL;
goto exit_fcp_prio_cfg;
}
@@ -753,7 +753,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
command_sent = INT_DEF_LB_LOOPBACK_CMD;
rval = qla2x00_loopback_test(vha, &elreq, response);
- if (new_config[1]) {
+ if (new_config[0]) {
/* Revert back to original port config
* Also clear internal loopback
*/
@@ -1512,6 +1512,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
if (((sp_bsg->type == SRB_CT_CMD) ||
(sp_bsg->type == SRB_ELS_CMD_HST))
&& (sp_bsg->u.bsg_job == bsg_job)) {
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld): mbx "
@@ -1527,6 +1528,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
bsg_job->req->errors =
bsg_job->reply->result = 0;
}
+ spin_lock_irqsave(&ha->hardware_lock, flags);
goto done;
}
}
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3a22effced5f..ccfc8e78be21 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2409,7 +2409,6 @@ struct qla_hw_data {
uint32_t enable_target_reset :1;
uint32_t enable_lip_full_login :1;
uint32_t enable_led_scheme :1;
- uint32_t inta_enabled :1;
uint32_t msi_enabled :1;
uint32_t msix_enabled :1;
uint32_t disable_serdes :1;
@@ -2426,6 +2425,9 @@ struct qla_hw_data {
uint32_t disable_msix_handshake :1;
uint32_t fcp_prio_enabled :1;
uint32_t fw_hung :1;
+ uint32_t quiesce_owner:1;
+ uint32_t thermal_supported:1;
+ /* 26 bits */
} flags;
/* This spinlock is used to protect "io transactions", you must
@@ -2864,6 +2866,7 @@ typedef struct scsi_qla_host {
#define ISP_UNRECOVERABLE 17
#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
#define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */
+#define ISP_QUIESCE_NEEDED 20 /* Driver need some quiescence */
uint32_t device_flags;
#define SWITCH_FOUND BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 9382a816c133..89e900adb679 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -36,6 +36,7 @@ extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *);
+extern int qla2x00_perform_loop_resync(scsi_qla_host_t *);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
@@ -45,12 +46,15 @@ extern void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
+extern void qla82xx_quiescent_state_cleanup(scsi_qla_host_t *);
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
+extern int qla2x00_get_thermal_temp(scsi_qla_host_t *, uint16_t *, uint16_t *);
+
extern void qla84xx_put_chip(struct scsi_qla_host *);
extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
@@ -68,6 +72,7 @@ extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
extern void qla2x00_async_tm_cmd_done(struct scsi_qla_host *, fc_port_t *,
struct srb_iocb *);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
+extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
extern fc_port_t *
qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
@@ -90,7 +95,6 @@ extern int ql2xfwloadbin;
extern int ql2xetsenable;
extern int ql2xshiftctondsd;
extern int ql2xdbwr;
-extern int ql2xdontresethba;
extern int ql2xasynctmfenable;
extern int ql2xgffidenable;
extern int ql2xenabledif;
@@ -549,9 +553,11 @@ extern void qla82xx_rom_unlock(struct qla_hw_data *);
/* ISP 8021 IDC */
extern void qla82xx_clear_drv_active(struct qla_hw_data *);
+extern uint32_t qla82xx_wait_for_state_change(scsi_qla_host_t *, uint32_t);
extern int qla82xx_idc_lock(struct qla_hw_data *);
extern void qla82xx_idc_unlock(struct qla_hw_data *);
extern int qla82xx_device_state_handler(scsi_qla_host_t *);
+extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);
extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
size_t, char *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 259f51137493..f948e1a73aec 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -498,6 +498,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
vha->flags.reset_active = 0;
ha->flags.pci_channel_io_perm_failure = 0;
ha->flags.eeh_busy = 0;
+ ha->flags.thermal_supported = 1;
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&vha->loop_state, LOOP_DOWN);
vha->device_flags = DFLG_NO_CABLE;
@@ -2023,6 +2024,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
&loop_id, &al_pa, &area, &domain, &topo, &sw_cap);
if (rval != QLA_SUCCESS) {
if (LOOP_TRANSITION(vha) || atomic_read(&ha->loop_down_timer) ||
+ IS_QLA8XXX_TYPE(ha) ||
(rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
DEBUG2(printk("%s(%ld) Loop is in a transition state\n",
__func__, vha->host_no));
@@ -2928,6 +2930,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
qla2x00_iidma_fcport(vha, fcport);
+ qla24xx_update_fcport_fcp_prio(vha, fcport);
qla2x00_reg_remote_port(vha, fcport);
atomic_set(&fcport->state, FCS_ONLINE);
}
@@ -3844,6 +3847,37 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
return (rval);
}
+/*
+* qla2x00_perform_loop_resync
+* Description: This function will set the appropriate flags and call
+* qla2x00_loop_resync. If successful loop will be resynced
+* Arguments : scsi_qla_host_t pointer
+* returm : Success or Failure
+*/
+
+int qla2x00_perform_loop_resync(scsi_qla_host_t *ha)
+{
+ int32_t rval = 0;
+
+ if (!test_and_set_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) {
+ /*Configure the flags so that resync happens properly*/
+ atomic_set(&ha->loop_down_timer, 0);
+ if (!(ha->device_flags & DFLG_NO_CABLE)) {
+ atomic_set(&ha->loop_state, LOOP_UP);
+ set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
+ set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
+ set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
+
+ rval = qla2x00_loop_resync(ha);
+ } else
+ atomic_set(&ha->loop_state, LOOP_DEAD);
+
+ clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags);
+ }
+
+ return rval;
+}
+
void
qla2x00_update_fcports(scsi_qla_host_t *base_vha)
{
@@ -3857,7 +3891,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
list_for_each_entry(vha, &base_vha->hw->vp_list, list) {
atomic_inc(&vha->vref_count);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
- if (fcport && fcport->drport &&
+ if (fcport->drport &&
atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
spin_unlock_irqrestore(&ha->vport_slock, flags);
@@ -3871,11 +3905,43 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
spin_unlock_irqrestore(&ha->vport_slock, flags);
}
+/*
+* qla82xx_quiescent_state_cleanup
+* Description: This function will block the new I/Os
+* Its not aborting any I/Os as context
+* is not destroyed during quiescence
+* Arguments: scsi_qla_host_t
+* return : void
+*/
+void
+qla82xx_quiescent_state_cleanup(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ struct scsi_qla_host *vp;
+
+ qla_printk(KERN_INFO, ha,
+ "Performing ISP error recovery - ha= %p.\n", ha);
+
+ atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
+ if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+ atomic_set(&vha->loop_state, LOOP_DOWN);
+ qla2x00_mark_all_devices_lost(vha, 0);
+ list_for_each_entry(vp, &ha->vp_list, list)
+ qla2x00_mark_all_devices_lost(vha, 0);
+ } else {
+ if (!atomic_read(&vha->loop_down_timer))
+ atomic_set(&vha->loop_down_timer,
+ LOOP_DOWN_TIME);
+ }
+ /* Wait for pending cmds to complete */
+ qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST);
+}
+
void
qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
- struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
+ struct scsi_qla_host *vp;
unsigned long flags;
vha->flags.online = 0;
@@ -3896,7 +3962,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
qla2x00_mark_all_devices_lost(vha, 0);
spin_lock_irqsave(&ha->vport_slock, flags);
- list_for_each_entry(vp, &base_vha->hw->vp_list, list) {
+ list_for_each_entry(vp, &ha->vp_list, list) {
atomic_inc(&vp->vref_count);
spin_unlock_irqrestore(&ha->vport_slock, flags);
@@ -5410,7 +5476,7 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
* the tag (priority) value is returned.
*
* Input:
- * ha = adapter block po
+ * vha = scsi host structure pointer.
* fcport = port structure pointer.
*
* Return:
@@ -5504,7 +5570,7 @@ qla24xx_get_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
* Activates fcp priority for the logged in fc port
*
* Input:
- * ha = adapter block pointer.
+ * vha = scsi host structure pointer.
* fcp = port structure pointer.
*
* Return:
@@ -5514,25 +5580,24 @@ qla24xx_get_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
* Kernel context.
*/
int
-qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *ha, fc_port_t *fcport)
+qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
{
int ret;
uint8_t priority;
uint16_t mb[5];
- if (atomic_read(&fcport->state) == FCS_UNCONFIGURED ||
- fcport->port_type != FCT_TARGET ||
- fcport->loop_id == FC_NO_LOOP_ID)
+ if (fcport->port_type != FCT_TARGET ||
+ fcport->loop_id == FC_NO_LOOP_ID)
return QLA_FUNCTION_FAILED;
- priority = qla24xx_get_fcp_prio(ha, fcport);
- ret = qla24xx_set_fcp_prio(ha, fcport->loop_id, priority, mb);
+ priority = qla24xx_get_fcp_prio(vha, fcport);
+ ret = qla24xx_set_fcp_prio(vha, fcport->loop_id, priority, mb);
if (ret == QLA_SUCCESS)
fcport->fcp_prio = priority;
else
DEBUG2(printk(KERN_WARNING
"scsi(%ld): Unable to activate fcp priority, "
- " ret=0x%x\n", ha->host_no, ret));
+ " ret=0x%x\n", vha->host_no, ret));
return ret;
}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 5f94430b42f0..4c1ba6263eb3 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
fcp_cmnd->additional_cdb_len |= 2;
int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+ host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1f06ddd9bdd1..d17ed9a94a0c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -321,6 +321,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
+ struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
uint32_t rscn_entry, host_pid;
uint8_t rscn_queue_index;
unsigned long flags;
@@ -498,6 +499,7 @@ skip_rio:
case MBA_LOOP_DOWN: /* Loop Down Event */
mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
+ mbx = IS_QLA82XX(ha) ? RD_REG_WORD(&reg82->mailbox_out[4]) : mbx;
DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
"(%x %x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3],
mbx));
@@ -2491,14 +2493,15 @@ skip_msix:
skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
- IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+ ha->flags.msi_enabled ? 0 : IRQF_SHARED,
+ QLA2XXX_DRIVER_NAME, rsp);
if (ret) {
qla_printk(KERN_WARNING, ha,
"Failed to reserve interrupt %d already in use.\n",
ha->pdev->irq);
goto fail;
}
- ha->flags.inta_enabled = 1;
+
clear_risc_ints:
/*
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index effd8a1403d9..e473e9fb363c 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4125,7 +4125,7 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
return QLA_FUNCTION_FAILED;
DEBUG11(printk(KERN_INFO
- "%s(%ld): entered.\n", __func__, ha->host_no));
+ "%s(%ld): entered.\n", __func__, vha->host_no));
mcp->mb[0] = MBC_PORT_PARAMS;
mcp->mb[1] = loop_id;
@@ -4160,6 +4160,71 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
}
int
+qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+ struct qla_hw_data *ha = vha->hw;
+
+ DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, ha->host_no));
+
+ /* High bits. */
+ mcp->mb[0] = MBC_READ_SFP;
+ mcp->mb[1] = 0x98;
+ mcp->mb[2] = 0;
+ mcp->mb[3] = 0;
+ mcp->mb[6] = 0;
+ mcp->mb[7] = 0;
+ mcp->mb[8] = 1;
+ mcp->mb[9] = 0x01;
+ mcp->mb[10] = BIT_13|BIT_0;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk(KERN_WARNING
+ "%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ ha->flags.thermal_supported = 0;
+ goto fail;
+ }
+ *temp = mcp->mb[1] & 0xFF;
+
+ /* Low bits. */
+ mcp->mb[0] = MBC_READ_SFP;
+ mcp->mb[1] = 0x98;
+ mcp->mb[2] = 0;
+ mcp->mb[3] = 0;
+ mcp->mb[6] = 0;
+ mcp->mb[7] = 0;
+ mcp->mb[8] = 1;
+ mcp->mb[9] = 0x10;
+ mcp->mb[10] = BIT_13|BIT_0;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk(KERN_WARNING
+ "%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ ha->flags.thermal_supported = 0;
+ goto fail;
+ }
+ *frac = ((mcp->mb[1] & 0xFF) >> 6) * 25;
+
+ if (rval == QLA_SUCCESS)
+ DEBUG11(printk(KERN_INFO
+ "%s(%ld): done.\n", __func__, ha->host_no));
+fail:
+ return rval;
+}
+
+int
qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
{
int rval;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 8d9edfb39803..fdb96a3584a5 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1079,11 +1079,55 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
/* Halt all the indiviual PEGs and other blocks of the ISP */
qla82xx_rom_lock(ha);
+
+ /* mask all niu interrupts */
+ qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
+ /* disable xge rx/tx */
+ qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
+ /* disable xg1 rx/tx */
+ qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+
+ /* halt sre */
+ val = qla82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
+ qla82xx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
+
+ /* halt epg */
+ qla82xx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
+
+ /* halt timers */
+ qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+
+ /* halt pegs */
+ qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+
+ /* big hammer */
+ msleep(1000);
if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
/* don't reset CAM block on reset */
qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
else
qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
+
+ /* reset ms */
+ val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+ val |= (1 << 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+ msleep(20);
+
+ /* unreset ms */
+ val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+ val &= ~(1 << 1);
+ qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+ msleep(20);
+
qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
/* Read the signature value from the flash.
@@ -1210,25 +1254,6 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
}
static int
-qla82xx_check_for_bad_spd(struct qla_hw_data *ha)
-{
- u32 val = 0;
- val = qla82xx_rd_32(ha, BOOT_LOADER_DIMM_STATUS);
- val &= QLA82XX_BOOT_LOADER_MN_ISSUE;
- if (val & QLA82XX_PEG_TUNE_MN_SPD_ZEROED) {
- qla_printk(KERN_INFO, ha,
- "Memory DIMM SPD not programmed. "
- " Assumed valid.\n");
- return 1;
- } else if (val) {
- qla_printk(KERN_INFO, ha,
- "Memory DIMM type incorrect.Info:%08X.\n", val);
- return 2;
- }
- return 0;
-}
-
-static int
qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
u64 off, void *data, int size)
{
@@ -1293,11 +1318,6 @@ qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
word[startword+1] |= tmpw >> (sz[0] * 8);
}
- /*
- * don't lock here - write_wx gets the lock if each time
- * write_lock_irqsave(&adapter->adapter_lock, flags);
- * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
- */
for (i = 0; i < loop; i++) {
temp = off8 + (i << shift_amount);
qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
@@ -1399,12 +1419,6 @@ qla82xx_pci_mem_read_2M(struct qla_hw_data *ha,
off0[1] = 0;
sz[1] = size - sz[0];
- /*
- * don't lock here - write_wx gets the lock if each time
- * write_lock_irqsave(&adapter->adapter_lock, flags);
- * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
- */
-
for (i = 0; i < loop; i++) {
temp = off8 + (i << shift_amount);
qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
@@ -1437,11 +1451,6 @@ qla82xx_pci_mem_read_2M(struct qla_hw_data *ha,
}
}
- /*
- * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
- * write_unlock_irqrestore(&adapter->adapter_lock, flags);
- */
-
if (j >= MAX_CTL_CHECK)
return -1;
@@ -1872,7 +1881,6 @@ qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)
qla_printk(KERN_INFO, ha,
"Cmd Peg initialization failed: 0x%x.\n", val);
- qla82xx_check_for_bad_spd(ha);
val = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);
read_lock(&ha->hw_lock);
qla82xx_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
@@ -2343,6 +2351,17 @@ qla82xx_set_qsnt_ready(struct qla_hw_data *ha)
qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
}
+void
+qla82xx_clear_qsnt_ready(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t qsnt_state;
+
+ qsnt_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+ qsnt_state &= ~(QLA82XX_DRVST_QSNT_RDY << (ha->portnum * 4));
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
+}
+
static int
qla82xx_load_fw(scsi_qla_host_t *vha)
{
@@ -2542,7 +2561,7 @@ qla2xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
- cur_seg++;
+ cur_seg = sg_next(cur_seg);
avail_dsds--;
}
}
@@ -2749,6 +2768,7 @@ sufficient_dsds:
goto queuing_error_fcp_cmnd;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+ host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
/* build FCP_CMND IU */
memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
@@ -3260,6 +3280,104 @@ dev_ready:
return QLA_SUCCESS;
}
+/*
+* qla82xx_need_qsnt_handler
+* Code to start quiescence sequence
+*
+* Note:
+* IDC lock must be held upon entry
+*
+* Return: void
+*/
+
+static void
+qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t dev_state, drv_state, drv_active;
+ unsigned long reset_timeout;
+
+ if (vha->flags.online) {
+ /*Block any further I/O and wait for pending cmnds to complete*/
+ qla82xx_quiescent_state_cleanup(vha);
+ }
+
+ /* Set the quiescence ready bit */
+ qla82xx_set_qsnt_ready(ha);
+
+ /*wait for 30 secs for other functions to ack */
+ reset_timeout = jiffies + (30 * HZ);
+
+ drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+ drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ /* Its 2 that is written when qsnt is acked, moving one bit */
+ drv_active = drv_active << 0x01;
+
+ while (drv_state != drv_active) {
+
+ if (time_after_eq(jiffies, reset_timeout)) {
+ /* quiescence timeout, other functions didn't ack
+ * changing the state to DEV_READY
+ */
+ qla_printk(KERN_INFO, ha,
+ "%s: QUIESCENT TIMEOUT\n", QLA2XXX_DRIVER_NAME);
+ qla_printk(KERN_INFO, ha,
+ "DRV_ACTIVE:%d DRV_STATE:%d\n", drv_active,
+ drv_state);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA82XX_DEV_READY);
+ qla_printk(KERN_INFO, ha,
+ "HW State: DEV_READY\n");
+ qla82xx_idc_unlock(ha);
+ qla2x00_perform_loop_resync(vha);
+ qla82xx_idc_lock(ha);
+
+ qla82xx_clear_qsnt_ready(vha);
+ return;
+ }
+
+ qla82xx_idc_unlock(ha);
+ msleep(1000);
+ qla82xx_idc_lock(ha);
+
+ drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+ drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ drv_active = drv_active << 0x01;
+ }
+ dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ /* everyone acked so set the state to DEV_QUIESCENCE */
+ if (dev_state == QLA82XX_DEV_NEED_QUIESCENT) {
+ qla_printk(KERN_INFO, ha, "HW State: DEV_QUIESCENT\n");
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_QUIESCENT);
+ }
+}
+
+/*
+* qla82xx_wait_for_state_change
+* Wait for device state to change from given current state
+*
+* Note:
+* IDC lock must not be held upon entry
+*
+* Return:
+* Changed device state.
+*/
+uint32_t
+qla82xx_wait_for_state_change(scsi_qla_host_t *vha, uint32_t curr_state)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t dev_state;
+
+ do {
+ msleep(1000);
+ qla82xx_idc_lock(ha);
+ dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ qla82xx_idc_unlock(ha);
+ } while (dev_state == curr_state);
+
+ return dev_state;
+}
+
static void
qla82xx_dev_failed_handler(scsi_qla_host_t *vha)
{
@@ -3438,15 +3556,28 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
qla82xx_idc_lock(ha);
break;
case QLA82XX_DEV_NEED_RESET:
- if (!ql2xdontresethba)
- qla82xx_need_reset_handler(vha);
+ qla82xx_need_reset_handler(vha);
break;
case QLA82XX_DEV_NEED_QUIESCENT:
- qla82xx_set_qsnt_ready(ha);
+ qla82xx_need_qsnt_handler(vha);
+ /* Reset timeout value after quiescence handler */
+ dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
+ * HZ);
+ break;
case QLA82XX_DEV_QUIESCENT:
+ /* Owner will exit and other will wait for the state
+ * to get changed
+ */
+ if (ha->flags.quiesce_owner)
+ goto exit;
+
qla82xx_idc_unlock(ha);
msleep(1000);
qla82xx_idc_lock(ha);
+
+ /* Reset timeout value after quiescence handler */
+ dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
+ * HZ);
break;
case QLA82XX_DEV_FAILED:
qla82xx_dev_failed_handler(vha);
@@ -3489,6 +3620,13 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
&ha->mbx_cmd_flags))
complete(&ha->mbx_intr_comp);
}
+ } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
+ !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
+ DEBUG(qla_printk(KERN_INFO, ha,
+ "scsi(%ld) %s - detected quiescence needed\n",
+ vha->host_no, __func__));
+ set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
} else {
qla82xx_check_fw_alive(vha);
}
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index 51ec0c5380e8..ed5883f1778a 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -523,8 +523,6 @@
# define QLA82XX_CAM_RAM_BASE (QLA82XX_CRB_CAM + 0x02000)
# define QLA82XX_CAM_RAM(reg) (QLA82XX_CAM_RAM_BASE + (reg))
-#define QLA82XX_PEG_TUNE_MN_SPD_ZEROED 0x80000000
-#define QLA82XX_BOOT_LOADER_MN_ISSUE 0xff00ffff
#define QLA82XX_PORT_MODE_ADDR (QLA82XX_CAM_RAM(0x24))
#define QLA82XX_PEG_HALT_STATUS1 (QLA82XX_CAM_RAM(0xa8))
#define QLA82XX_PEG_HALT_STATUS2 (QLA82XX_CAM_RAM(0xac))
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1644eabaafeb..c194c23ca1fb 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -37,12 +37,12 @@ static struct kmem_cache *srb_cachep;
static struct kmem_cache *ctx_cachep;
int ql2xlogintimeout = 20;
-module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
+module_param(ql2xlogintimeout, int, S_IRUGO);
MODULE_PARM_DESC(ql2xlogintimeout,
"Login timeout value in seconds.");
int qlport_down_retry;
-module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR);
+module_param(qlport_down_retry, int, S_IRUGO);
MODULE_PARM_DESC(qlport_down_retry,
"Maximum number of command retries to a port that returns "
"a PORT-DOWN status.");
@@ -55,12 +55,12 @@ MODULE_PARM_DESC(ql2xplogiabsentdevice,
"Default is 0 - no PLOGI. 1 - perfom PLOGI.");
int ql2xloginretrycount = 0;
-module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
+module_param(ql2xloginretrycount, int, S_IRUGO);
MODULE_PARM_DESC(ql2xloginretrycount,
"Specify an alternate value for the NVRAM login retry count.");
int ql2xallocfwdump = 1;
-module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR);
+module_param(ql2xallocfwdump, int, S_IRUGO);
MODULE_PARM_DESC(ql2xallocfwdump,
"Option to enable allocation of memory for a firmware dump "
"during HBA initialization. Memory allocation requirements "
@@ -73,7 +73,7 @@ MODULE_PARM_DESC(ql2xextended_error_logging,
"Default is 0 - no logging. 1 - log errors.");
int ql2xshiftctondsd = 6;
-module_param(ql2xshiftctondsd, int, S_IRUGO|S_IRUSR);
+module_param(ql2xshiftctondsd, int, S_IRUGO);
MODULE_PARM_DESC(ql2xshiftctondsd,
"Set to control shifting of command type processing "
"based on total number of SG elements.");
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(ql2xshiftctondsd,
static void qla2x00_free_device(scsi_qla_host_t *);
int ql2xfdmienable=1;
-module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
+module_param(ql2xfdmienable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xfdmienable,
"Enables FDMI registrations. "
"0 - no FDMI. Default is 1 - perform FDMI.");
@@ -106,27 +106,27 @@ MODULE_PARM_DESC(ql2xenablehba_err_chk,
" Default is 0 - Error isolation disabled, 1 - Enable it");
int ql2xiidmaenable=1;
-module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
+module_param(ql2xiidmaenable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xiidmaenable,
"Enables iIDMA settings "
"Default is 1 - perform iIDMA. 0 - no iIDMA.");
int ql2xmaxqueues = 1;
-module_param(ql2xmaxqueues, int, S_IRUGO|S_IRUSR);
+module_param(ql2xmaxqueues, int, S_IRUGO);
MODULE_PARM_DESC(ql2xmaxqueues,
"Enables MQ settings "
"Default is 1 for single queue. Set it to number "
"of queues in MQ mode.");
int ql2xmultique_tag;
-module_param(ql2xmultique_tag, int, S_IRUGO|S_IRUSR);
+module_param(ql2xmultique_tag, int, S_IRUGO);
MODULE_PARM_DESC(ql2xmultique_tag,
"Enables CPU affinity settings for the driver "
"Default is 0 for no affinity of request and response IO. "
"Set it to 1 to turn on the cpu affinity.");
int ql2xfwloadbin;
-module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
+module_param(ql2xfwloadbin, int, S_IRUGO);
MODULE_PARM_DESC(ql2xfwloadbin,
"Option to specify location from which to load ISP firmware:\n"
" 2 -- load firmware via the request_firmware() (hotplug)\n"
@@ -135,39 +135,32 @@ MODULE_PARM_DESC(ql2xfwloadbin,
" 0 -- use default semantics.\n");
int ql2xetsenable;
-module_param(ql2xetsenable, int, S_IRUGO|S_IRUSR);
+module_param(ql2xetsenable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xetsenable,
"Enables firmware ETS burst."
"Default is 0 - skip ETS enablement.");
int ql2xdbwr = 1;
-module_param(ql2xdbwr, int, S_IRUGO|S_IRUSR);
+module_param(ql2xdbwr, int, S_IRUGO);
MODULE_PARM_DESC(ql2xdbwr,
"Option to specify scheme for request queue posting\n"
" 0 -- Regular doorbell.\n"
" 1 -- CAMRAM doorbell (faster).\n");
-int ql2xdontresethba;
-module_param(ql2xdontresethba, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xdontresethba,
- "Option to specify reset behaviour\n"
- " 0 (Default) -- Reset on failure.\n"
- " 1 -- Do not reset on failure.\n");
-
int ql2xtargetreset = 1;
-module_param(ql2xtargetreset, int, S_IRUGO|S_IRUSR);
+module_param(ql2xtargetreset, int, S_IRUGO);
MODULE_PARM_DESC(ql2xtargetreset,
"Enable target reset."
"Default is 1 - use hw defaults.");
int ql2xgffidenable;
-module_param(ql2xgffidenable, int, S_IRUGO|S_IRUSR);
+module_param(ql2xgffidenable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xgffidenable,
"Enables GFF_ID checks of port type. "
"Default is 0 - Do not use GFF_ID information.");
int ql2xasynctmfenable;
-module_param(ql2xasynctmfenable, int, S_IRUGO|S_IRUSR);
+module_param(ql2xasynctmfenable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xasynctmfenable,
"Enables issue of TM IOCBs asynchronously via IOCB mechanism"
"Default is 0 - Issue TM IOCBs via mailbox mechanism.");
@@ -829,7 +822,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
srb_t *sp;
- int ret;
+ int ret = SUCCESS;
unsigned int id, lun;
unsigned long flags;
int wait = 0;
@@ -2064,6 +2057,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
ha->gid_list_info_size = 8;
ha->optrom_size = OPTROM_SIZE_82XX;
+ ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
ha->isp_ops = &qla82xx_isp_ops;
ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
@@ -2370,7 +2364,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
list_for_each_entry(vha, &ha->vp_list, list) {
atomic_inc(&vha->vref_count);
- if (vha && vha->fc_vport) {
+ if (vha->fc_vport) {
spin_unlock_irqrestore(&ha->vport_slock, flags);
fc_vport_terminate(vha->fc_vport);
@@ -3385,6 +3379,21 @@ qla2x00_do_dpc(void *data)
clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
}
+ if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
+ DEBUG(printk(KERN_INFO "scsi(%ld): dpc: sched "
+ "qla2x00_quiesce_needed ha = %p\n",
+ base_vha->host_no, ha));
+ qla82xx_device_state_handler(base_vha);
+ clear_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags);
+ if (!ha->flags.quiesce_owner) {
+ qla2x00_perform_loop_resync(base_vha);
+
+ qla82xx_idc_lock(ha);
+ qla82xx_clear_qsnt_ready(base_vha);
+ qla82xx_idc_unlock(ha);
+ }
+ }
+
if (test_and_clear_bit(RESET_MARKER_NEEDED,
&base_vha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &base_vha->dpc_flags)))) {
@@ -3588,13 +3597,16 @@ qla2x00_timer(scsi_qla_host_t *vha)
return;
}
- if (IS_QLA82XX(ha))
- qla82xx_watchdog(vha);
-
/* Hardware read to raise pending EEH errors during mailbox waits. */
if (!pci_channel_offline(ha->pdev))
pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
+ if (IS_QLA82XX(ha)) {
+ if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
+ start_dpc++;
+ qla82xx_watchdog(vha);
+ }
+
/* Loop down handler. */
if (atomic_read(&vha->loop_down_timer) > 0 &&
!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 76de9574b385..22070621206c 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -669,6 +669,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
def = 1;
else if (IS_QLA81XX(ha))
def = 2;
+
+ /* Assign FCP prio region since older adapters may not have FLT, or
+ FCP prio region in it's FLT.
+ */
+ ha->flt_region_fcp_prio = ha->flags.port0 ?
+ fcp_prio_cfg0[def] : fcp_prio_cfg1[def];
+
ha->flt_region_flt = flt_addr;
wptr = (uint16_t *)req->ring;
flt = (struct qla_flt_header *)req->ring;
@@ -696,10 +703,6 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
goto no_flash_data;
}
- /* Assign FCP prio region since older FLT's may not have it */
- ha->flt_region_fcp_prio = ha->flags.port0 ?
- fcp_prio_cfg0[def] : fcp_prio_cfg1[def];
-
loc = locations[1];
cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
for ( ; cnt; cnt--, region++) {
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 8edbccb3232d..cf0075a2d0c2 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.04-k0"
+#define QLA2XXX_VERSION "8.03.05-k0"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
-#define QLA_DRIVER_PATCH_VER 4
+#define QLA_DRIVER_PATCH_VER 5
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
index edcf048215dd..af62c3cf8752 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.c
+++ b/drivers/scsi/qla4xxx/ql4_dbg.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
index d861c3b411c8..abd83602cdda 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.h
+++ b/drivers/scsi/qla4xxx/ql4_dbg.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 0f3bfc3da5cf..2fc0045b1a52 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -175,7 +175,7 @@
struct srb {
struct list_head list; /* (8) */
struct scsi_qla_host *ha; /* HA the SP is queued on */
- struct ddb_entry *ddb;
+ struct ddb_entry *ddb;
uint16_t flags; /* (1) Status flags. */
#define SRB_DMA_VALID BIT_3 /* DMA Buffer mapped. */
@@ -191,7 +191,6 @@ struct srb {
struct scsi_cmnd *cmd; /* (4) SCSI command block */
dma_addr_t dma_handle; /* (4) for unmap of single transfers */
struct kref srb_ref; /* reference count for this srb */
- uint32_t fw_ddb_index;
uint8_t err_id; /* error id */
#define SRB_ERR_PORT 1 /* Request failed because "port down" */
#define SRB_ERR_LOOP 2 /* Request failed because "loop down" */
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 5e757d7fff7d..c1985792f034 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 6575a47501e5..8fad99b7eef4 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index dc01fa3da5d1..1629c48c35ef 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h
index 9471ac755000..62f90bdec5d5 100644
--- a/drivers/scsi/qla4xxx/ql4_inline.h
+++ b/drivers/scsi/qla4xxx/ql4_inline.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 5ae49fd87846..75fcd82a8fca 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 7c33fd5943d5..6ffbe9727dff 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -554,7 +554,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
/* mbox_sts[2] = Old ACB state
* mbox_sts[3] = new ACB state */
if ((mbox_sts[3] == ACB_STATE_VALID) &&
- (mbox_sts[2] == ACB_STATE_TENTATIVE))
+ ((mbox_sts[2] == ACB_STATE_TENTATIVE) ||
+ (mbox_sts[2] == ACB_STATE_ACQUIRING)))
set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
(mbox_sts[2] == ACB_STATE_VALID))
@@ -1077,7 +1078,7 @@ try_msi:
ret = pci_enable_msi(ha->pdev);
if (!ret) {
ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler,
- IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
+ 0, DRIVER_NAME, ha);
if (!ret) {
DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
set_bit(AF_MSI_ENABLED, &ha->flags);
@@ -1095,7 +1096,7 @@ try_msi:
try_intx:
/* Trying INTx */
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
- IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
+ IRQF_SHARED, DRIVER_NAME, ha);
if (!ret) {
DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n"));
set_bit(AF_INTx_ENABLED, &ha->flags);
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 2d2f9c879bfd..f65626aec7c1 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -81,23 +81,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
*/
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (is_qla8022(ha)) {
- intr_status = readl(&ha->qla4_8xxx_reg->host_int);
- if (intr_status & ISRX_82XX_RISC_INT) {
- /* Service existing interrupt */
- DEBUG2(printk("scsi%ld: %s: "
- "servicing existing interrupt\n",
- ha->host_no, __func__));
- intr_status = readl(&ha->qla4_8xxx_reg->host_status);
- ha->isp_ops->interrupt_service_routine(ha, intr_status);
- clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
- if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
- test_bit(AF_INTx_ENABLED, &ha->flags))
- qla4_8xxx_wr_32(ha,
- ha->nx_legacy_intr.tgt_mask_reg,
- 0xfbff);
- }
- } else {
+ if (!is_qla8022(ha)) {
intr_status = readl(&ha->reg->ctrl_status);
if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
/* Service existing interrupt */
@@ -934,7 +918,7 @@ int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
return status;
mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
- mbox_cmd[1] = srb->fw_ddb_index;
+ mbox_cmd[1] = srb->ddb->fw_ddb_index;
mbox_cmd[2] = index;
/* Immediate Command Enable */
mbox_cmd[5] = 0x01;
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c
index f0d0fbf88aa2..b4b859b2d47e 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.c
+++ b/drivers/scsi/qla4xxx/ql4_nvram.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h
index 7a8fc66a760d..b3831bd29479 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.h
+++ b/drivers/scsi/qla4xxx/ql4_nvram.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 474b10d71364..3d5ef2df4134 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2009 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -942,12 +942,55 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
/* Halt all the indiviual PEGs and other blocks of the ISP */
qla4_8xxx_rom_lock(ha);
+
+ /* mask all niu interrupts */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
+ /* disable xge rx/tx */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
+ /* disable xg1 rx/tx */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+
+ /* halt sre */
+ val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
+
+ /* halt epg */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
+
+ /* halt timers */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+
+ /* halt pegs */
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+
+ /* big hammer */
+ msleep(1000);
if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
/* don't reset CAM block on reset */
qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
else
qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
+ /* reset ms */
+ val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+ val |= (1 << 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+
+ msleep(20);
+ /* unreset ms */
+ val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+ val &= ~(1 << 1);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+ msleep(20);
+
qla4_8xxx_rom_unlock(ha);
/* Read the signature value from the flash.
@@ -1084,14 +1127,14 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
static int
qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
{
- int i;
+ int i, rval = 0;
long size = 0;
long flashaddr, memaddr;
u64 data;
u32 high, low;
flashaddr = memaddr = ha->hw.flt_region_bootload;
- size = (image_start - flashaddr)/8;
+ size = (image_start - flashaddr) / 8;
DEBUG2(printk("scsi%ld: %s: bootldr=0x%lx, fw_image=0x%x\n",
ha->host_no, __func__, flashaddr, image_start));
@@ -1100,14 +1143,18 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
if ((qla4_8xxx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
(qla4_8xxx_rom_fast_read(ha, flashaddr + 4,
(int *)&high))) {
- return -1;
+ rval = -1;
+ goto exit_load_from_flash;
}
data = ((u64)high << 32) | low ;
- qla4_8xxx_pci_mem_write_2M(ha, memaddr, &data, 8);
+ rval = qla4_8xxx_pci_mem_write_2M(ha, memaddr, &data, 8);
+ if (rval)
+ goto exit_load_from_flash;
+
flashaddr += 8;
memaddr += 8;
- if (i%0x1000 == 0)
+ if (i % 0x1000 == 0)
msleep(1);
}
@@ -1119,7 +1166,8 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
read_unlock(&ha->hw_lock);
- return 0;
+exit_load_from_flash:
+ return rval;
}
static int qla4_8xxx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index ff689bf53007..35376a1c3f1b 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -1,8 +1,8 @@
/*
- * QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2008 QLogic Corporation
+ * QLogic iSCSI HBA Driver
+ * Copyright (c) 2003-2010 QLogic Corporation
*
- * See LICENSE.qla2xxx for copyright and licensing details.
+ * See LICENSE.qla4xxx for copyright and licensing details.
*/
#ifndef __QLA_NX_H
#define __QLA_NX_H
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 0d48fb4d1044..3fc1d256636f 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -706,18 +706,22 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
/* don't poll if reset is going on */
- if (!test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags)) {
+ if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
+ test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+ test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags))) {
if (dev_state == QLA82XX_DEV_NEED_RESET &&
!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
- printk("scsi%ld: %s: HW State: NEED RESET!\n",
- ha->host_no, __func__);
- set_bit(DPC_RESET_HA, &ha->dpc_flags);
- qla4xxx_wake_dpc(ha);
- qla4xxx_mailbox_premature_completion(ha);
+ if (!ql4xdontresethba) {
+ ql4_printk(KERN_INFO, ha, "%s: HW State: "
+ "NEED RESET!\n", __func__);
+ set_bit(DPC_RESET_HA, &ha->dpc_flags);
+ qla4xxx_wake_dpc(ha);
+ qla4xxx_mailbox_premature_completion(ha);
+ }
} else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
!test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
- printk("scsi%ld: %s: HW State: NEED QUIES!\n",
- ha->host_no, __func__);
+ ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n",
+ __func__);
set_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags);
qla4xxx_wake_dpc(ha);
} else {
@@ -1721,6 +1725,14 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
if (!test_bit(AF_ONLINE, &ha->flags)) {
ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n");
+ if (is_qla8022(ha) && ql4xdontresethba) {
+ /* Put the device in failed state. */
+ DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
+ qla4_8xxx_idc_lock(ha);
+ qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA82XX_DEV_FAILED);
+ qla4_8xxx_idc_unlock(ha);
+ }
ret = -ENODEV;
goto probe_failed;
}
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index 9bfacf4ed137..8475b308e01b 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -1,8 +1,8 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2006 QLogic Corporation
+ * Copyright (c) 2003-2010 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
-#define QLA4XXX_DRIVER_VERSION "5.02.00-k4"
+#define QLA4XXX_DRIVER_VERSION "5.02.00-k5"
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 2f1f9b079b10..7b310934efed 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1805,6 +1805,7 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
devip->sense_buff[5] = (ret >> 8) & 0xff;
devip->sense_buff[6] = ret & 0xff;
}
+ scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
return check_condition_result;
}
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 824b8fc03ce5..45c75649b9e0 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
return rtn;
}
-static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
{
if (!scmd->device->host->hostt->eh_abort_handler)
return FAILED;
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
return scmd->device->host->hostt->eh_abort_handler(scmd);
}
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd: SCSI cmd to abort from Lower Level.
- *
- * Notes:
- * This function will not return until the user's completion function
- * has been called. there is no timeout on this operation. if the
- * author of the low-level driver wishes this operation to be timed,
- * they can provide this facility themselves. helper functions in
- * scsi_error.c can be supplied to make this easier to do.
- */
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
- /*
- * scsi_done was called just after the command timed out and before
- * we had a chance to process it. (db)
- */
- if (scmd->serial_number == 0)
- return SUCCESS;
- return __scsi_try_to_abort_cmd(scmd);
-}
-
static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
{
- if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+ if (scsi_try_to_abort_cmd(scmd) != SUCCESS)
if (scsi_try_bus_device_reset(scmd) != SUCCESS)
if (scsi_try_target_reset(scmd) != SUCCESS)
if (scsi_try_bus_reset(scmd) != SUCCESS)
@@ -1146,51 +1124,40 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
struct list_head *work_q,
struct list_head *done_q)
{
- struct scsi_cmnd *scmd, *tgtr_scmd, *next;
- unsigned int id = 0;
- int rtn;
+ LIST_HEAD(tmp_list);
- do {
- tgtr_scmd = NULL;
- list_for_each_entry(scmd, work_q, eh_entry) {
- if (id == scmd_id(scmd)) {
- tgtr_scmd = scmd;
- break;
- }
- }
- if (!tgtr_scmd) {
- /* not one exactly equal; find the next highest */
- list_for_each_entry(scmd, work_q, eh_entry) {
- if (scmd_id(scmd) > id &&
- (!tgtr_scmd ||
- scmd_id(tgtr_scmd) > scmd_id(scmd)))
- tgtr_scmd = scmd;
- }
- }
- if (!tgtr_scmd)
- /* no more commands, that's it */
- break;
+ list_splice_init(work_q, &tmp_list);
+
+ while (!list_empty(&tmp_list)) {
+ struct scsi_cmnd *next, *scmd;
+ int rtn;
+ unsigned int id;
+
+ scmd = list_entry(tmp_list.next, struct scsi_cmnd, eh_entry);
+ id = scmd_id(scmd);
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
"to target %d\n",
current->comm, id));
- rtn = scsi_try_target_reset(tgtr_scmd);
- if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
- list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
- if (id == scmd_id(scmd))
- if (!scsi_device_online(scmd->device) ||
- rtn == FAST_IO_FAIL ||
- !scsi_eh_tur(tgtr_scmd))
- scsi_eh_finish_cmd(scmd,
- done_q);
- }
- } else
+ rtn = scsi_try_target_reset(scmd);
+ if (rtn != SUCCESS && rtn != FAST_IO_FAIL)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset"
" failed target: "
"%d\n",
current->comm, id));
- id++;
- } while(id != 0);
+ list_for_each_entry_safe(scmd, next, &tmp_list, eh_entry) {
+ if (scmd_id(scmd) != id)
+ continue;
+
+ if ((rtn == SUCCESS || rtn == FAST_IO_FAIL)
+ && (!scsi_device_online(scmd->device) ||
+ rtn == FAST_IO_FAIL || !scsi_eh_tur(scmd)))
+ scsi_eh_finish_cmd(scmd, done_q);
+ else
+ /* push back on work queue for further processing */
+ list_move(&scmd->eh_entry, work_q);
+ }
+ }
return list_empty(work_q);
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index eafeeda6e194..9045c52abd25 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1278,11 +1278,10 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
}
if (scsi_target_is_busy(starget)) {
- if (list_empty(&sdev->starved_entry)) {
+ if (list_empty(&sdev->starved_entry))
list_add_tail(&sdev->starved_entry,
&shost->starved_list);
- return 0;
- }
+ return 0;
}
/* We're OK to process the command, so we can't be starved */
@@ -1403,11 +1402,6 @@ static void scsi_softirq_done(struct request *rq)
INIT_LIST_HEAD(&cmd->eh_entry);
- /*
- * Set the serial numbers back to zero
- */
- cmd->serial_number = 0;
-
atomic_inc(&cmd->device->iodone_cnt);
if (cmd->result)
atomic_inc(&cmd->device->ioerr_cnt);
@@ -1642,9 +1636,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
blk_queue_max_segment_size(q, dma_get_max_seg_size(dev));
- /* New queue, no concurrency on queue_flags */
if (!shost->use_clustering)
- queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
+ q->limits.cluster = 0;
/*
* set a reasonable default alignment on word boundaries: the
@@ -1984,8 +1977,7 @@ EXPORT_SYMBOL(scsi_mode_sense);
* in.
*
* Returns zero if unsuccessful or an error if TUR failed. For
- * removable media, a return of NOT_READY or UNIT_ATTENTION is
- * translated to success, with the ->changed flag updated.
+ * removable media, UNIT_ATTENTION sets ->changed flag.
**/
int
scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
@@ -2012,16 +2004,6 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
} while (scsi_sense_valid(sshdr) &&
sshdr->sense_key == UNIT_ATTENTION && --retries);
- if (!sshdr)
- /* could not allocate sense buffer, so can't process it */
- return result;
-
- if (sdev->removable && scsi_sense_valid(sshdr) &&
- (sshdr->sense_key == UNIT_ATTENTION ||
- sshdr->sense_key == NOT_READY)) {
- sdev->changed = 1;
- result = 0;
- }
if (!sshdr_external)
kfree(sshdr);
return result;
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 76ee2e784f75..4c68d36f9ac2 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -993,16 +993,14 @@ static int __remove_child (struct device * dev, void * data)
*/
void scsi_remove_target(struct device *dev)
{
- struct device *rdev;
-
if (scsi_is_target_device(dev)) {
__scsi_remove_target(to_scsi_target(dev));
return;
}
- rdev = get_device(dev);
+ get_device(dev);
device_for_each_child(dev, NULL, __remove_child);
- put_device(rdev);
+ put_device(dev);
}
EXPORT_SYMBOL(scsi_remove_target);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 332387a6bc25..f905ecb5704d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2200,3 +2200,4 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
MODULE_DESCRIPTION("iSCSI Transport Interface");
MODULE_LICENSE("GPL");
MODULE_VERSION(ISCSI_TRANSPORT_VERSION);
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_ISCSI);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 956496182c80..b65e65aa07eb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -583,7 +583,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
* quietly refuse to do anything to a changed disc until
* the changed bit has been reset
*/
- /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
+ /* printk("SCSI disk has been changed or is not present. Prohibiting further I/O.\n"); */
goto out;
}
@@ -1023,7 +1023,6 @@ static int sd_media_changed(struct gendisk *disk)
*/
if (!scsi_device_online(sdp)) {
set_media_not_present(sdkp);
- retval = 1;
goto out;
}
@@ -1044,17 +1043,8 @@ static int sd_media_changed(struct gendisk *disk)
sshdr);
}
- /*
- * Unable to test, unit probably not ready. This usually
- * means there is no disc in the drive. Mark as changed,
- * and we will figure it out later once the drive is
- * available again.
- */
- if (retval || (scsi_sense_valid(sshdr) &&
- /* 0x3a is medium not present */
- sshdr->asc == 0x3a)) {
+ if (retval) {
set_media_not_present(sdkp);
- retval = 1;
goto out;
}
@@ -1065,12 +1055,27 @@ static int sd_media_changed(struct gendisk *disk)
*/
sdkp->media_present = 1;
- retval = sdp->changed;
- sdp->changed = 0;
out:
- if (retval != sdkp->previous_state)
+ /*
+ * Report a media change under the following conditions:
+ *
+ * Medium is present now and wasn't present before.
+ * Medium wasn't present before and is present now.
+ * Medium was present at all times, but it changed while
+ * we weren't looking (sdp->changed is set).
+ *
+ * If there was no medium before and there is no medium now then
+ * don't report a change, even if a medium was inserted and removed
+ * while we weren't looking.
+ */
+ retval = (sdkp->media_present != sdkp->previous_state ||
+ (sdkp->media_present && sdp->changed));
+ if (retval)
sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
- sdkp->previous_state = retval;
+ sdkp->previous_state = sdkp->media_present;
+
+ /* sdp->changed indicates medium was changed or is not present */
+ sdp->changed = !sdkp->media_present;
kfree(sshdr);
return retval;
}
@@ -1175,6 +1180,12 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512);
u64 bad_lba;
int info_valid;
+ /*
+ * resid is optional but mostly filled in. When it's unused,
+ * its value is zero, so we assume the whole buffer transferred
+ */
+ unsigned int transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd);
+ unsigned int good_bytes;
if (scmd->request->cmd_type != REQ_TYPE_FS)
return 0;
@@ -1208,7 +1219,8 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
/* This computation should always be done in terms of
* the resolution of the device's medium.
*/
- return (bad_lba - start_lba) * scmd->device->sector_size;
+ good_bytes = (bad_lba - start_lba) * scmd->device->sector_size;
+ return min(good_bytes, transferred);
}
/**
@@ -1902,10 +1914,14 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
int old_rcd = sdkp->RCD;
int old_dpofua = sdkp->DPOFUA;
- if (sdp->skip_ms_page_8)
- goto defaults;
-
- if (sdp->type == TYPE_RBC) {
+ if (sdp->skip_ms_page_8) {
+ if (sdp->type == TYPE_RBC)
+ goto defaults;
+ else {
+ modepage = 0x3F;
+ dbd = 0;
+ }
+ } else if (sdp->type == TYPE_RBC) {
modepage = 6;
dbd = 8;
} else {
@@ -1933,13 +1949,11 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
*/
if (len < 3)
goto bad_sense;
- if (len > 20)
- len = 20;
-
- /* Take headers and block descriptors into account */
- len += data.header_length + data.block_descriptor_length;
- if (len > SD_BUF_SIZE)
- goto bad_sense;
+ else if (len > SD_BUF_SIZE) {
+ sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter "
+ "data from %d to %d bytes\n", len, SD_BUF_SIZE);
+ len = SD_BUF_SIZE;
+ }
/* Get the data */
res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
@@ -1947,16 +1961,45 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
if (scsi_status_is_good(res)) {
int offset = data.header_length + data.block_descriptor_length;
- if (offset >= SD_BUF_SIZE - 2) {
- sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
- goto defaults;
+ while (offset < len) {
+ u8 page_code = buffer[offset] & 0x3F;
+ u8 spf = buffer[offset] & 0x40;
+
+ if (page_code == 8 || page_code == 6) {
+ /* We're interested only in the first 3 bytes.
+ */
+ if (len - offset <= 2) {
+ sd_printk(KERN_ERR, sdkp, "Incomplete "
+ "mode parameter data\n");
+ goto defaults;
+ } else {
+ modepage = page_code;
+ goto Page_found;
+ }
+ } else {
+ /* Go to the next page */
+ if (spf && len - offset > 3)
+ offset += 4 + (buffer[offset+2] << 8) +
+ buffer[offset+3];
+ else if (!spf && len - offset > 1)
+ offset += 2 + buffer[offset+1];
+ else {
+ sd_printk(KERN_ERR, sdkp, "Incomplete "
+ "mode parameter data\n");
+ goto defaults;
+ }
+ }
}
- if ((buffer[offset] & 0x3f) != modepage) {
+ if (modepage == 0x3F) {
+ sd_printk(KERN_ERR, sdkp, "No Caching mode page "
+ "present\n");
+ goto defaults;
+ } else if ((buffer[offset] & 0x3f) != modepage) {
sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
goto defaults;
}
-
+ Page_found:
if (modepage == 8) {
sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index d7b383c96d5d..be6baf8ad704 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -104,14 +104,15 @@ static void sr_release(struct cdrom_device_info *);
static void get_sectorsize(struct scsi_cd *);
static void get_capabilities(struct scsi_cd *);
-static int sr_media_change(struct cdrom_device_info *, int);
+static unsigned int sr_check_events(struct cdrom_device_info *cdi,
+ unsigned int clearing, int slot);
static int sr_packet(struct cdrom_device_info *, struct packet_command *);
static struct cdrom_device_ops sr_dops = {
.open = sr_open,
.release = sr_release,
.drive_status = sr_drive_status,
- .media_changed = sr_media_change,
+ .check_events = sr_check_events,
.tray_move = sr_tray_move,
.lock_door = sr_lock_door,
.select_speed = sr_select_speed,
@@ -165,90 +166,96 @@ static void scsi_cd_put(struct scsi_cd *cd)
mutex_unlock(&sr_ref_mutex);
}
-/* identical to scsi_test_unit_ready except that it doesn't
- * eat the NOT_READY returns for removable media */
-int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr)
+static unsigned int sr_get_events(struct scsi_device *sdev)
{
- int retries = MAX_RETRIES;
- int the_result;
- u8 cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0 };
+ u8 buf[8];
+ u8 cmd[] = { GET_EVENT_STATUS_NOTIFICATION,
+ 1, /* polled */
+ 0, 0, /* reserved */
+ 1 << 4, /* notification class: media */
+ 0, 0, /* reserved */
+ 0, sizeof(buf), /* allocation length */
+ 0, /* control */
+ };
+ struct event_header *eh = (void *)buf;
+ struct media_event_desc *med = (void *)(buf + 4);
+ struct scsi_sense_hdr sshdr;
+ int result;
- /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION
- * conditions are gone, or a timeout happens
- */
- do {
- the_result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL,
- 0, sshdr, SR_TIMEOUT,
- retries--, NULL);
- if (scsi_sense_valid(sshdr) &&
- sshdr->sense_key == UNIT_ATTENTION)
- sdev->changed = 1;
-
- } while (retries > 0 &&
- (!scsi_status_is_good(the_result) ||
- (scsi_sense_valid(sshdr) &&
- sshdr->sense_key == UNIT_ATTENTION)));
- return the_result;
+ result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, sizeof(buf),
+ &sshdr, SR_TIMEOUT, MAX_RETRIES, NULL);
+ if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION)
+ return DISK_EVENT_MEDIA_CHANGE;
+
+ if (result || be16_to_cpu(eh->data_len) < sizeof(*med))
+ return 0;
+
+ if (eh->nea || eh->notification_class != 0x4)
+ return 0;
+
+ if (med->media_event_code == 1)
+ return DISK_EVENT_EJECT_REQUEST;
+ else if (med->media_event_code == 2)
+ return DISK_EVENT_MEDIA_CHANGE;
+ return 0;
}
/*
- * This function checks to see if the media has been changed in the
- * CDROM drive. It is possible that we have already sensed a change,
- * or the drive may have sensed one and not yet reported it. We must
- * be ready for either case. This function always reports the current
- * value of the changed bit. If flag is 0, then the changed bit is reset.
- * This function could be done as an ioctl, but we would need to have
- * an inode for that to work, and we do not always have one.
+ * This function checks to see if the media has been changed or eject
+ * button has been pressed. It is possible that we have already
+ * sensed a change, or the drive may have sensed one and not yet
+ * reported it. The past events are accumulated in sdev->changed and
+ * returned together with the current state.
*/
-
-static int sr_media_change(struct cdrom_device_info *cdi, int slot)
+static unsigned int sr_check_events(struct cdrom_device_info *cdi,
+ unsigned int clearing, int slot)
{
struct scsi_cd *cd = cdi->handle;
- int retval;
- struct scsi_sense_hdr *sshdr;
+ bool last_present;
+ struct scsi_sense_hdr sshdr;
+ unsigned int events;
+ int ret;
- if (CDSL_CURRENT != slot) {
- /* no changer support */
- return -EINVAL;
- }
+ /* no changer support */
+ if (CDSL_CURRENT != slot)
+ return 0;
- sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL);
- retval = sr_test_unit_ready(cd->device, sshdr);
- if (retval || (scsi_sense_valid(sshdr) &&
- /* 0x3a is medium not present */
- sshdr->asc == 0x3a)) {
- /* Media not present or unable to test, unit probably not
- * ready. This usually means there is no disc in the drive.
- * Mark as changed, and we will figure it out later once
- * the drive is available again.
- */
- cd->device->changed = 1;
- /* This will force a flush, if called from check_disk_change */
- retval = 1;
- goto out;
- };
+ events = sr_get_events(cd->device);
+ /*
+ * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE
+ * is being cleared. Note that there are devices which hang
+ * if asked to execute TUR repeatedly.
+ */
+ if (!(clearing & DISK_EVENT_MEDIA_CHANGE))
+ goto skip_tur;
+
+ /* let's see whether the media is there with TUR */
+ last_present = cd->media_present;
+ ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
+
+ /*
+ * Media is considered to be present if TUR succeeds or fails with
+ * sense data indicating something other than media-not-present
+ * (ASC 0x3a).
+ */
+ cd->media_present = scsi_status_is_good(ret) ||
+ (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a);
- retval = cd->device->changed;
- cd->device->changed = 0;
- /* If the disk changed, the capacity will now be different,
- * so we force a re-read of this information */
- if (retval) {
- /* check multisession offset etc */
- sr_cd_check(cdi);
- get_sectorsize(cd);
+ if (last_present != cd->media_present)
+ events |= DISK_EVENT_MEDIA_CHANGE;
+skip_tur:
+ if (cd->device->changed) {
+ events |= DISK_EVENT_MEDIA_CHANGE;
+ cd->device->changed = 0;
}
-out:
- /* Notify userspace, that media has changed. */
- if (retval != cd->previous_state)
+ /* for backward compatibility */
+ if (events & DISK_EVENT_MEDIA_CHANGE)
sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE,
GFP_KERNEL);
- cd->previous_state = retval;
- kfree(sshdr);
-
- return retval;
+ return events;
}
-
+
/*
* sr_done is the interrupt routine for the device driver.
*
@@ -533,10 +540,25 @@ out:
return ret;
}
-static int sr_block_media_changed(struct gendisk *disk)
+static unsigned int sr_block_check_events(struct gendisk *disk,
+ unsigned int clearing)
{
struct scsi_cd *cd = scsi_cd(disk);
- return cdrom_media_changed(&cd->cdi);
+ return cdrom_check_events(&cd->cdi, clearing);
+}
+
+static int sr_block_revalidate_disk(struct gendisk *disk)
+{
+ struct scsi_cd *cd = scsi_cd(disk);
+ struct scsi_sense_hdr sshdr;
+
+ /* if the unit is not ready, nothing more to do */
+ if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
+ return 0;
+
+ sr_cd_check(&cd->cdi);
+ get_sectorsize(cd);
+ return 0;
}
static const struct block_device_operations sr_bdops =
@@ -545,7 +567,8 @@ static const struct block_device_operations sr_bdops =
.open = sr_block_open,
.release = sr_block_release,
.ioctl = sr_block_ioctl,
- .media_changed = sr_block_media_changed,
+ .check_events = sr_block_check_events,
+ .revalidate_disk = sr_block_revalidate_disk,
/*
* No compat_ioctl for now because sr_block_ioctl never
* seems to pass arbitary ioctls down to host drivers.
@@ -618,6 +641,7 @@ static int sr_probe(struct device *dev)
sprintf(disk->disk_name, "sr%d", minor);
disk->fops = &sr_bdops;
disk->flags = GENHD_FL_CD;
+ disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST;
blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT);
@@ -627,7 +651,7 @@ static int sr_probe(struct device *dev)
cd->disk = disk;
cd->capacity = 0x1fffff;
cd->device->changed = 1; /* force recheck CD type */
- cd->previous_state = 1;
+ cd->media_present = 1;
cd->use = 1;
cd->readcd_known = 0;
cd->readcd_cdda = 0;
@@ -780,7 +804,7 @@ static void get_capabilities(struct scsi_cd *cd)
}
/* eat unit attentions */
- sr_test_unit_ready(cd->device, &sshdr);
+ scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
/* ask for mode page 0x2a */
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index 1e144dfdbd4b..e036f1dc83c8 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -40,7 +40,7 @@ typedef struct scsi_cd {
unsigned xa_flag:1; /* CD has XA sectors ? */
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
unsigned readcd_cdda:1; /* reading audio data using READ_CD */
- unsigned previous_state:1; /* media has changed */
+ unsigned media_present:1; /* media is present */
struct cdrom_device_info cdi;
/* We hold gendisk and scsi_device references on probe and use
* the refs on this kref to decide when to release them */
@@ -61,7 +61,6 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed);
int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
int sr_is_xa(Scsi_CD *);
-int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr);
/* sr_vendor.c */
void sr_vendor_init(Scsi_CD *);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 3cd8ffbad577..8be30554119b 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -307,7 +307,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot)
/* we have no changer support */
return -EINVAL;
}
- if (0 == sr_test_unit_ready(cd->device, &sshdr))
+ if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
return CDS_DISC_OK;
/* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 5b7388f1c835..1871b8ae83ae 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static const char *verstr = "20100829";
+static const char *verstr = "20101219";
#include <linux/module.h>
@@ -3729,9 +3729,11 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
b_size = PAGE_SIZE << order;
} else {
for (b_size = PAGE_SIZE, order = 0;
- order < ST_MAX_ORDER && b_size < new_size;
+ order < ST_MAX_ORDER &&
+ max_segs * (PAGE_SIZE << order) < new_size;
order++, b_size *= 2)
; /* empty */
+ STbuffer->reserved_page_order = order;
}
if (max_segs * (PAGE_SIZE << order) < new_size) {
if (order == ST_MAX_ORDER)
@@ -3758,7 +3760,6 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
segs++;
}
STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
- STbuffer->reserved_page_order = order;
return 1;
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d8e14b7aa93..ee74c934de89 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -653,13 +653,13 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
{
if (p->capabilities & UART_CAP_SLEEP) {
if (p->capabilities & UART_CAP_EFR) {
- serial_outp(p, UART_LCR, 0xBF);
+ serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(p, UART_EFR, UART_EFR_ECB);
serial_outp(p, UART_LCR, 0);
}
serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
if (p->capabilities & UART_CAP_EFR) {
- serial_outp(p, UART_LCR, 0xBF);
+ serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(p, UART_EFR, 0);
serial_outp(p, UART_LCR, 0);
}
@@ -752,7 +752,7 @@ static int size_fifo(struct uart_8250_port *up)
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
serial_outp(up, UART_MCR, UART_MCR_LOOP);
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
old_dl = serial_dl_read(up);
serial_dl_write(up, 0x0001);
serial_outp(up, UART_LCR, 0x03);
@@ -764,7 +764,7 @@ static int size_fifo(struct uart_8250_port *up)
serial_inp(up, UART_RX);
serial_outp(up, UART_FCR, old_fcr);
serial_outp(up, UART_MCR, old_mcr);
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_dl_write(up, old_dl);
serial_outp(up, UART_LCR, old_lcr);
@@ -782,7 +782,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
unsigned int id;
old_lcr = serial_inp(p, UART_LCR);
- serial_outp(p, UART_LCR, UART_LCR_DLAB);
+ serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
old_dll = serial_inp(p, UART_DLL);
old_dlm = serial_inp(p, UART_DLM);
@@ -836,7 +836,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
* recommended for new designs).
*/
up->acr = 0;
- serial_out(up, UART_LCR, 0xBF);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
serial_out(up, UART_LCR, 0x00);
id1 = serial_icr_read(up, UART_ID1);
@@ -945,7 +945,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
* Check for presence of the EFR when DLAB is set.
* Only ST16C650V1 UARTs pass this test.
*/
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
if (serial_in(up, UART_EFR) == 0) {
serial_outp(up, UART_EFR, 0xA8);
if (serial_in(up, UART_EFR) != 0) {
@@ -963,7 +963,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
* Maybe it requires 0xbf to be written to the LCR.
* (other ST16C650V2 UARTs, TI16C752A, etc)
*/
- serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
DEBUG_AUTOCONF("EFRv2 ");
autoconfig_has_efr(up);
@@ -1024,7 +1024,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
status1 = serial_in(up, UART_IIR) >> 5;
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
status2 = serial_in(up, UART_IIR) >> 5;
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
@@ -1183,7 +1183,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
* We also initialise the EFR (if any) to zero for later. The
* EFR occupies the same register location as the FCR and IIR.
*/
- serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(up, UART_EFR, 0);
serial_outp(up, UART_LCR, 0);
@@ -1952,7 +1952,7 @@ static int serial8250_startup(struct uart_port *port)
if (up->port.type == PORT_16C950) {
/* Wake up and initialize UART */
up->acr = 0;
- serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(up, UART_EFR, UART_EFR_ECB);
serial_outp(up, UART_IER, 0);
serial_outp(up, UART_LCR, 0);
@@ -2002,7 +2002,7 @@ static int serial8250_startup(struct uart_port *port)
if (up->port.type == PORT_16850) {
unsigned char fctr;
- serial_outp(up, UART_LCR, 0xbf);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
@@ -2363,7 +2363,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_cflag & CRTSCTS)
efr |= UART_EFR_CTS;
- serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(up, UART_EFR, efr);
}
@@ -2872,7 +2872,7 @@ static struct console serial8250_console = {
.device = uart_console_device,
.setup = serial8250_console_setup,
.early_setup = serial8250_console_early_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1,
.data = &serial8250_reg,
};
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 6ca7a44f29c2..e76d7d000128 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -7,6 +7,7 @@
*
* Copyright 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * Copyright (C) 2010 ST-Ericsson SA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,6 +49,9 @@
#include <linux/amba/serial.h>
#include <linux/clk.h>
#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/sizes.h>
@@ -63,21 +67,6 @@
#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
#define UART_DUMMY_DR_RX (1 << 16)
-/*
- * We wrap our port structure around the generic uart_port.
- */
-struct uart_amba_port {
- struct uart_port port;
- struct clk *clk;
- unsigned int im; /* interrupt mask */
- unsigned int old_status;
- unsigned int ifls; /* vendor-specific */
- unsigned int lcrh_tx; /* vendor-specific */
- unsigned int lcrh_rx; /* vendor-specific */
- bool oversampling; /* vendor-specific */
- bool autorts;
-};
-
/* There is by now at least one vendor with differing details, so handle it */
struct vendor_data {
unsigned int ifls;
@@ -85,6 +74,7 @@ struct vendor_data {
unsigned int lcrh_tx;
unsigned int lcrh_rx;
bool oversampling;
+ bool dma_threshold;
};
static struct vendor_data vendor_arm = {
@@ -93,6 +83,7 @@ static struct vendor_data vendor_arm = {
.lcrh_tx = UART011_LCRH,
.lcrh_rx = UART011_LCRH,
.oversampling = false,
+ .dma_threshold = false,
};
static struct vendor_data vendor_st = {
@@ -101,22 +92,535 @@ static struct vendor_data vendor_st = {
.lcrh_tx = ST_UART011_LCRH_TX,
.lcrh_rx = ST_UART011_LCRH_RX,
.oversampling = true,
+ .dma_threshold = true,
+};
+
+/* Deals with DMA transactions */
+struct pl011_dmatx_data {
+ struct dma_chan *chan;
+ struct scatterlist sg;
+ char *buf;
+ bool queued;
};
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_amba_port {
+ struct uart_port port;
+ struct clk *clk;
+ const struct vendor_data *vendor;
+ unsigned int dmacr; /* dma control reg */
+ unsigned int im; /* interrupt mask */
+ unsigned int old_status;
+ unsigned int fifosize; /* vendor-specific */
+ unsigned int lcrh_tx; /* vendor-specific */
+ unsigned int lcrh_rx; /* vendor-specific */
+ bool autorts;
+ char type[12];
+#ifdef CONFIG_DMA_ENGINE
+ /* DMA stuff */
+ bool using_dma;
+ struct pl011_dmatx_data dmatx;
+#endif
+};
+
+/*
+ * All the DMA operation mode stuff goes inside this ifdef.
+ * This assumes that you have a generic DMA device interface,
+ * no custom DMA interfaces are supported.
+ */
+#ifdef CONFIG_DMA_ENGINE
+
+#define PL011_DMA_BUFFER_SIZE PAGE_SIZE
+
+static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
+{
+ /* DMA is the sole user of the platform data right now */
+ struct amba_pl011_data *plat = uap->port.dev->platform_data;
+ struct dma_slave_config tx_conf = {
+ .dst_addr = uap->port.mapbase + UART01x_DR,
+ .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+ .direction = DMA_TO_DEVICE,
+ .dst_maxburst = uap->fifosize >> 1,
+ };
+ struct dma_chan *chan;
+ dma_cap_mask_t mask;
+
+ /* We need platform data */
+ if (!plat || !plat->dma_filter) {
+ dev_info(uap->port.dev, "no DMA platform data\n");
+ return;
+ }
+
+ /* Try to acquire a generic DMA engine slave channel */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param);
+ if (!chan) {
+ dev_err(uap->port.dev, "no TX DMA channel!\n");
+ return;
+ }
+
+ dmaengine_slave_config(chan, &tx_conf);
+ uap->dmatx.chan = chan;
+
+ dev_info(uap->port.dev, "DMA channel TX %s\n",
+ dma_chan_name(uap->dmatx.chan));
+}
+
+#ifndef MODULE
+/*
+ * Stack up the UARTs and let the above initcall be done at device
+ * initcall time, because the serial driver is called as an arch
+ * initcall, and at this time the DMA subsystem is not yet registered.
+ * At this point the driver will switch over to using DMA where desired.
+ */
+struct dma_uap {
+ struct list_head node;
+ struct uart_amba_port *uap;
+};
+
+static LIST_HEAD(pl011_dma_uarts);
+
+static int __init pl011_dma_initcall(void)
+{
+ struct list_head *node, *tmp;
+
+ list_for_each_safe(node, tmp, &pl011_dma_uarts) {
+ struct dma_uap *dmau = list_entry(node, struct dma_uap, node);
+ pl011_dma_probe_initcall(dmau->uap);
+ list_del(node);
+ kfree(dmau);
+ }
+ return 0;
+}
+
+device_initcall(pl011_dma_initcall);
+
+static void pl011_dma_probe(struct uart_amba_port *uap)
+{
+ struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL);
+ if (dmau) {
+ dmau->uap = uap;
+ list_add_tail(&dmau->node, &pl011_dma_uarts);
+ }
+}
+#else
+static void pl011_dma_probe(struct uart_amba_port *uap)
+{
+ pl011_dma_probe_initcall(uap);
+}
+#endif
+
+static void pl011_dma_remove(struct uart_amba_port *uap)
+{
+ /* TODO: remove the initcall if it has not yet executed */
+ if (uap->dmatx.chan)
+ dma_release_channel(uap->dmatx.chan);
+}
+
+
+/* Forward declare this for the refill routine */
+static int pl011_dma_tx_refill(struct uart_amba_port *uap);
+
+/*
+ * The current DMA TX buffer has been sent.
+ * Try to queue up another DMA buffer.
+ */
+static void pl011_dma_tx_callback(void *data)
+{
+ struct uart_amba_port *uap = data;
+ struct pl011_dmatx_data *dmatx = &uap->dmatx;
+ unsigned long flags;
+ u16 dmacr;
+
+ spin_lock_irqsave(&uap->port.lock, flags);
+ if (uap->dmatx.queued)
+ dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1,
+ DMA_TO_DEVICE);
+
+ dmacr = uap->dmacr;
+ uap->dmacr = dmacr & ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ /*
+ * If TX DMA was disabled, it means that we've stopped the DMA for
+ * some reason (eg, XOFF received, or we want to send an X-char.)
+ *
+ * Note: we need to be careful here of a potential race between DMA
+ * and the rest of the driver - if the driver disables TX DMA while
+ * a TX buffer completing, we must update the tx queued status to
+ * get further refills (hence we check dmacr).
+ */
+ if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
+ uart_circ_empty(&uap->port.state->xmit)) {
+ uap->dmatx.queued = false;
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ return;
+ }
+
+ if (pl011_dma_tx_refill(uap) <= 0) {
+ /*
+ * We didn't queue a DMA buffer for some reason, but we
+ * have data pending to be sent. Re-enable the TX IRQ.
+ */
+ uap->im |= UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ }
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+}
+
+/*
+ * Try to refill the TX DMA buffer.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * 1 if we queued up a TX DMA buffer.
+ * 0 if we didn't want to handle this by DMA
+ * <0 on error
+ */
+static int pl011_dma_tx_refill(struct uart_amba_port *uap)
+{
+ struct pl011_dmatx_data *dmatx = &uap->dmatx;
+ struct dma_chan *chan = dmatx->chan;
+ struct dma_device *dma_dev = chan->device;
+ struct dma_async_tx_descriptor *desc;
+ struct circ_buf *xmit = &uap->port.state->xmit;
+ unsigned int count;
+
+ /*
+ * Try to avoid the overhead involved in using DMA if the
+ * transaction fits in the first half of the FIFO, by using
+ * the standard interrupt handling. This ensures that we
+ * issue a uart_write_wakeup() at the appropriate time.
+ */
+ count = uart_circ_chars_pending(xmit);
+ if (count < (uap->fifosize >> 1)) {
+ uap->dmatx.queued = false;
+ return 0;
+ }
+
+ /*
+ * Bodge: don't send the last character by DMA, as this
+ * will prevent XON from notifying us to restart DMA.
+ */
+ count -= 1;
+
+ /* Else proceed to copy the TX chars to the DMA buffer and fire DMA */
+ if (count > PL011_DMA_BUFFER_SIZE)
+ count = PL011_DMA_BUFFER_SIZE;
+
+ if (xmit->tail < xmit->head)
+ memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count);
+ else {
+ size_t first = UART_XMIT_SIZE - xmit->tail;
+ size_t second = xmit->head;
+
+ memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first);
+ if (second)
+ memcpy(&dmatx->buf[first], &xmit->buf[0], second);
+ }
+
+ dmatx->sg.length = count;
+
+ if (dma_map_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE) != 1) {
+ uap->dmatx.queued = false;
+ dev_dbg(uap->port.dev, "unable to map TX DMA\n");
+ return -EBUSY;
+ }
+
+ desc = dma_dev->device_prep_slave_sg(chan, &dmatx->sg, 1, DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE);
+ uap->dmatx.queued = false;
+ /*
+ * If DMA cannot be used right now, we complete this
+ * transaction via IRQ and let the TTY layer retry.
+ */
+ dev_dbg(uap->port.dev, "TX DMA busy\n");
+ return -EBUSY;
+ }
+
+ /* Some data to go along to the callback */
+ desc->callback = pl011_dma_tx_callback;
+ desc->callback_param = uap;
+
+ /* All errors should happen at prepare time */
+ dmaengine_submit(desc);
+
+ /* Fire the DMA transaction */
+ dma_dev->device_issue_pending(chan);
+
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ uap->dmatx.queued = true;
+
+ /*
+ * Now we know that DMA will fire, so advance the ring buffer
+ * with the stuff we just dispatched.
+ */
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ uap->port.icount.tx += count;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&uap->port);
+
+ return 1;
+}
+
+/*
+ * We received a transmit interrupt without a pending X-char but with
+ * pending characters.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * false if we want to use PIO to transmit
+ * true if we queued a DMA buffer
+ */
+static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
+{
+ if (!uap->using_dma)
+ return false;
+
+ /*
+ * If we already have a TX buffer queued, but received a
+ * TX interrupt, it will be because we've just sent an X-char.
+ * Ensure the TX DMA is enabled and the TX IRQ is disabled.
+ */
+ if (uap->dmatx.queued) {
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ uap->im &= ~UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ return true;
+ }
+
+ /*
+ * We don't have a TX buffer queued, so try to queue one.
+ * If we succesfully queued a buffer, mask the TX IRQ.
+ */
+ if (pl011_dma_tx_refill(uap) > 0) {
+ uap->im &= ~UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Stop the DMA transmit (eg, due to received XOFF).
+ * Locking: called with port lock held and IRQs disabled.
+ */
+static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
+{
+ if (uap->dmatx.queued) {
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ }
+}
+
+/*
+ * Try to start a DMA transmit, or in the case of an XON/OFF
+ * character queued for send, try to get that character out ASAP.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * false if we want the TX IRQ to be enabled
+ * true if we have a buffer queued
+ */
+static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
+{
+ u16 dmacr;
+
+ if (!uap->using_dma)
+ return false;
+
+ if (!uap->port.x_char) {
+ /* no X-char, try to push chars out in DMA mode */
+ bool ret = true;
+
+ if (!uap->dmatx.queued) {
+ if (pl011_dma_tx_refill(uap) > 0) {
+ uap->im &= ~UART011_TXIM;
+ ret = true;
+ } else {
+ uap->im |= UART011_TXIM;
+ ret = false;
+ }
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ } else if (!(uap->dmacr & UART011_TXDMAE)) {
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr,
+ uap->port.membase + UART011_DMACR);
+ }
+ return ret;
+ }
+
+ /*
+ * We have an X-char to send. Disable DMA to prevent it loading
+ * the TX fifo, and then see if we can stuff it into the FIFO.
+ */
+ dmacr = uap->dmacr;
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) {
+ /*
+ * No space in the FIFO, so enable the transmit interrupt
+ * so we know when there is space. Note that once we've
+ * loaded the character, we should just re-enable DMA.
+ */
+ return false;
+ }
+
+ writew(uap->port.x_char, uap->port.membase + UART01x_DR);
+ uap->port.icount.tx++;
+ uap->port.x_char = 0;
+
+ /* Success - restore the DMA state */
+ uap->dmacr = dmacr;
+ writew(dmacr, uap->port.membase + UART011_DMACR);
+
+ return true;
+}
+
+/*
+ * Flush the transmit buffer.
+ * Locking: called with port lock held and IRQs disabled.
+ */
+static void pl011_dma_flush_buffer(struct uart_port *port)
+{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+
+ if (!uap->using_dma)
+ return;
+
+ /* Avoid deadlock with the DMA engine callback */
+ spin_unlock(&uap->port.lock);
+ dmaengine_terminate_all(uap->dmatx.chan);
+ spin_lock(&uap->port.lock);
+ if (uap->dmatx.queued) {
+ dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
+ DMA_TO_DEVICE);
+ uap->dmatx.queued = false;
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ }
+}
+
+
+static void pl011_dma_startup(struct uart_amba_port *uap)
+{
+ if (!uap->dmatx.chan)
+ return;
+
+ uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL);
+ if (!uap->dmatx.buf) {
+ dev_err(uap->port.dev, "no memory for DMA TX buffer\n");
+ uap->port.fifosize = uap->fifosize;
+ return;
+ }
+
+ sg_init_one(&uap->dmatx.sg, uap->dmatx.buf, PL011_DMA_BUFFER_SIZE);
+
+ /* The DMA buffer is now the FIFO the TTY subsystem can use */
+ uap->port.fifosize = PL011_DMA_BUFFER_SIZE;
+ uap->using_dma = true;
+
+ /* Turn on DMA error (RX/TX will be enabled on demand) */
+ uap->dmacr |= UART011_DMAONERR;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ /*
+ * ST Micro variants has some specific dma burst threshold
+ * compensation. Set this to 16 bytes, so burst will only
+ * be issued above/below 16 bytes.
+ */
+ if (uap->vendor->dma_threshold)
+ writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16,
+ uap->port.membase + ST_UART011_DMAWM);
+}
+
+static void pl011_dma_shutdown(struct uart_amba_port *uap)
+{
+ if (!uap->using_dma)
+ return;
+
+ /* Disable RX and TX DMA */
+ while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
+ barrier();
+
+ spin_lock_irq(&uap->port.lock);
+ uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ spin_unlock_irq(&uap->port.lock);
+
+ /* In theory, this should already be done by pl011_dma_flush_buffer */
+ dmaengine_terminate_all(uap->dmatx.chan);
+ if (uap->dmatx.queued) {
+ dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
+ DMA_TO_DEVICE);
+ uap->dmatx.queued = false;
+ }
+
+ kfree(uap->dmatx.buf);
+
+ uap->using_dma = false;
+}
+
+#else
+/* Blank functions if the DMA engine is not available */
+static inline void pl011_dma_probe(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_remove(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_startup(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_shutdown(struct uart_amba_port *uap)
+{
+}
+
+static inline bool pl011_dma_tx_irq(struct uart_amba_port *uap)
+{
+ return false;
+}
+
+static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
+{
+}
+
+static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
+{
+ return false;
+}
+
+#define pl011_dma_flush_buffer NULL
+#endif
+
+
static void pl011_stop_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
uap->im &= ~UART011_TXIM;
writew(uap->im, uap->port.membase + UART011_IMSC);
+ pl011_dma_tx_stop(uap);
}
static void pl011_start_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
- uap->im |= UART011_TXIM;
- writew(uap->im, uap->port.membase + UART011_IMSC);
+ if (!pl011_dma_tx_start(uap)) {
+ uap->im |= UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ }
}
static void pl011_stop_rx(struct uart_port *port)
@@ -203,7 +707,11 @@ static void pl011_tx_chars(struct uart_amba_port *uap)
return;
}
- count = uap->port.fifosize >> 1;
+ /* If we are using DMA mode, try to send some characters. */
+ if (pl011_dma_tx_irq(uap))
+ return;
+
+ count = uap->fifosize >> 1;
do {
writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -246,10 +754,11 @@ static void pl011_modem_status(struct uart_amba_port *uap)
static irqreturn_t pl011_int(int irq, void *dev_id)
{
struct uart_amba_port *uap = dev_id;
+ unsigned long flags;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
int handled = 0;
- spin_lock(&uap->port.lock);
+ spin_lock_irqsave(&uap->port.lock, flags);
status = readw(uap->port.membase + UART011_MIS);
if (status) {
@@ -274,7 +783,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
handled = 1;
}
- spin_unlock(&uap->port.lock);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
return IRQ_RETVAL(handled);
}
@@ -396,7 +905,7 @@ static int pl011_startup(struct uart_port *port)
if (retval)
goto clk_dis;
- writew(uap->ifls, uap->port.membase + UART011_IFLS);
+ writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
/*
* Provoke TX FIFO interrupt into asserting.
@@ -423,11 +932,18 @@ static int pl011_startup(struct uart_port *port)
cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
writew(cr, uap->port.membase + UART011_CR);
+ /* Clear pending error interrupts */
+ writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS,
+ uap->port.membase + UART011_ICR);
+
/*
* initialise the old status of the modem signals
*/
uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
+ /* Startup DMA */
+ pl011_dma_startup(uap);
+
/*
* Finally, enable interrupts
*/
@@ -467,6 +983,8 @@ static void pl011_shutdown(struct uart_port *port)
writew(0xffff, uap->port.membase + UART011_ICR);
spin_unlock_irq(&uap->port.lock);
+ pl011_dma_shutdown(uap);
+
/*
* Free the interrupt
*/
@@ -498,13 +1016,18 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int lcr_h, old_cr;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, clkdiv;
+
+ if (uap->vendor->oversampling)
+ clkdiv = 8;
+ else
+ clkdiv = 16;
/*
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 0,
- port->uartclk/(uap->oversampling ? 8 : 16));
+ port->uartclk / clkdiv);
if (baud > port->uartclk/16)
quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
@@ -532,7 +1055,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
if (!(termios->c_cflag & PARODD))
lcr_h |= UART01x_LCRH_EPS;
}
- if (port->fifosize > 1)
+ if (uap->fifosize > 1)
lcr_h |= UART01x_LCRH_FEN;
spin_lock_irqsave(&port->lock, flags);
@@ -588,8 +1111,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
uap->autorts = false;
}
- if (uap->oversampling) {
- if (baud > port->uartclk/16)
+ if (uap->vendor->oversampling) {
+ if (baud > port->uartclk / 16)
old_cr |= ST_UART011_CR_OVSFACT;
else
old_cr &= ~ST_UART011_CR_OVSFACT;
@@ -622,7 +1145,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
static const char *pl011_type(struct uart_port *port)
{
- return port->type == PORT_AMBA ? "AMBA/PL011" : NULL;
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+ return uap->port.type == PORT_AMBA ? uap->type : NULL;
}
/*
@@ -679,6 +1203,7 @@ static struct uart_ops amba_pl011_pops = {
.break_ctl = pl011_break_ctl,
.startup = pl011_startup,
.shutdown = pl011_shutdown,
+ .flush_buffer = pl011_dma_flush_buffer,
.set_termios = pl011_set_termios,
.type = pl011_type,
.release_port = pl010_release_port,
@@ -761,7 +1286,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
- if (uap->oversampling) {
+ if (uap->vendor->oversampling) {
if (readw(uap->port.membase + UART011_CR)
& ST_UART011_CR_OVSFACT)
*baud *= 2;
@@ -858,19 +1383,22 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
goto unmap;
}
- uap->ifls = vendor->ifls;
+ uap->vendor = vendor;
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
- uap->oversampling = vendor->oversampling;
+ uap->fifosize = vendor->fifosize;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
uap->port.iotype = UPIO_MEM;
uap->port.irq = dev->irq[0];
- uap->port.fifosize = vendor->fifosize;
+ uap->port.fifosize = uap->fifosize;
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
+ pl011_dma_probe(uap);
+
+ snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev));
amba_ports[i] = uap;
@@ -879,6 +1407,7 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
+ pl011_dma_remove(uap);
clk_put(uap->clk);
unmap:
iounmap(base);
@@ -902,6 +1431,7 @@ static int pl011_remove(struct amba_device *dev)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
+ pl011_dma_remove(uap);
iounmap(uap->port.membase);
clk_put(uap->clk);
kfree(uap);
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 3374618300af..25a8bc565f40 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
static void kgdboc_restore_input(void)
{
- schedule_work(&kgdboc_restore_input_work);
+ if (likely(system_state == SYSTEM_RUNNING))
+ schedule_work(&kgdboc_restore_input_work);
}
static int kgdboc_register_kbd(char **cptr)
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c
index 5fc699e929dc..d40010a22ecd 100644
--- a/drivers/serial/mfd.c
+++ b/drivers/serial/mfd.c
@@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned char cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
- u32 mul = 0x3600;
- u32 ps = 0x10;
+ u32 ps, mul;
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -943,31 +942,24 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
quot = 1;
+ ps = 0x10;
+ mul = 0x3600;
switch (baud) {
case 3500000:
mul = 0x3345;
ps = 0xC;
break;
- case 3000000:
- mul = 0x2EE0;
- break;
- case 2500000:
- mul = 0x2710;
- break;
- case 2000000:
- mul = 0x1F40;
- break;
case 1843200:
mul = 0x2400;
break;
+ case 3000000:
+ case 2500000:
+ case 2000000:
case 1500000:
- mul = 0x1770;
- break;
case 1000000:
- mul = 0xFA0;
- break;
case 500000:
- mul = 0x7D0;
+ /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
+ mul = baud / 500000 * 0x9C4;
break;
default:
/* Use uart_get_divisor to get quot for other baud rates */
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c
index f8c816e7725d..8e43a7b69e64 100644
--- a/drivers/serial/msm_serial.c
+++ b/drivers/serial/msm_serial.c
@@ -686,7 +686,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
msm_port = UART_TO_MSM(port);
msm_port->clk = clk_get(&pdev->dev, "uart_clk");
- if (unlikely(IS_ERR(msm_port->clk)))
+ if (IS_ERR(msm_port->clk))
return PTR_ERR(msm_port->clk);
port->uartclk = clk_get_rate(msm_port->clk);
printk(KERN_INFO "uartclk = %d\n", port->uartclk);
diff --git a/drivers/serial/omap-serial.c b/drivers/serial/omap-serial.c
index 14365f72b664..1201eff1831e 100644
--- a/drivers/serial/omap-serial.c
+++ b/drivers/serial/omap-serial.c
@@ -570,7 +570,7 @@ serial_omap_configure_xonxoff
unsigned char efr = 0;
up->lcr = serial_in(up, UART_LCR);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
up->efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, up->efr & ~UART_EFR_ECB);
@@ -598,7 +598,7 @@ serial_omap_configure_xonxoff
efr |= OMAP_UART_SW_RX;
serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
up->mcr = serial_in(up, UART_MCR);
@@ -612,14 +612,14 @@ serial_omap_configure_xonxoff
up->mcr |= UART_MCR_XONANY;
serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
/* Enable special char function UARTi.EFR_REG[5] and
* load the new software flow control mode IXON or IXOFF
* and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
*/
serial_out(up, UART_EFR, efr | UART_EFR_SCD);
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
serial_out(up, UART_LCR, up->lcr);
@@ -724,22 +724,22 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
* baud clock is not running
* DLL_REG and DLH_REG set to 0.
*/
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_out(up, UART_DLL, 0);
serial_out(up, UART_DLM, 0);
serial_out(up, UART_LCR, 0);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
up->efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
up->mcr = serial_in(up, UART_MCR);
serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
/* FIFO ENABLE, DMA MODE */
serial_out(up, UART_FCR, up->fcr);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
if (up->use_dma) {
serial_out(up, UART_TI752_TLR, 0);
@@ -748,52 +748,52 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
}
serial_out(up, UART_EFR, up->efr);
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_out(up, UART_MCR, up->mcr);
/* Protocol, Baud Rate, and Interrupt Settings */
- serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
up->efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
serial_out(up, UART_LCR, 0);
serial_out(up, UART_IER, 0);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
serial_out(up, UART_LCR, 0);
serial_out(up, UART_IER, up->ier);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, up->efr);
serial_out(up, UART_LCR, cval);
if (baud > 230400 && baud != 3000000)
- serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X);
+ serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE);
else
- serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X);
+ serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
/* Hardware Flow Control Configuration */
if (termios->c_cflag & CRTSCTS) {
efr |= (UART_EFR_CTS | UART_EFR_RTS);
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
up->mcr = serial_in(up, UART_MCR);
serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
up->efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */
- serial_out(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS);
serial_out(up, UART_LCR, cval);
}
@@ -815,13 +815,13 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
unsigned char efr;
dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, efr | UART_EFR_ECB);
serial_out(up, UART_LCR, 0);
serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0);
- serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, efr);
serial_out(up, UART_LCR, 0);
/* Enable module level wake up */
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index d2352ac437c5..4bc614e4221c 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -31,6 +31,7 @@
# define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
@@ -244,6 +245,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
@@ -280,6 +282,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
@@ -378,6 +381,7 @@
}
#if defined(CONFIG_CPU_SH3) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
@@ -391,6 +395,7 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377)
#define SCIF_FNS(name, scif_offset, scif_size) \
@@ -433,6 +438,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377)
@@ -632,6 +638,7 @@ static inline int sci_rxd_in(struct uart_port *port)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index e5e9e6735f7d..9739431092d1 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -198,6 +198,7 @@ int __init register_intc_controller(struct intc_desc *desc)
list_add_tail(&d->list, &intc_list);
raw_spin_lock_init(&d->lock);
+ INIT_RADIX_TREE(&d->tree, GFP_ATOMIC);
d->index = nr_intc_controllers;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 154529aacc03..a067046c9da2 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -352,8 +352,12 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer)
xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS;
if (xfer->tx_buf) {
+ /* tx_buf is a const void* where we need a void * for the dma
+ * mapping */
+ void *nonconst_tx = (void *)xfer->tx_buf;
+
xfer->tx_dma = dma_map_single(dev,
- (void *) xfer->tx_buf, xfer->len,
+ nonconst_tx, xfer->len,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, xfer->tx_dma))
return -ENOMEM;
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c
index 052b3c7fa6a0..8856bcca9d29 100644
--- a/drivers/spi/coldfire_qspi.c
+++ b/drivers/spi/coldfire_qspi.c
@@ -317,7 +317,7 @@ static void mcfqspi_work(struct work_struct *work)
msg = container_of(mcfqspi->msgq.next, struct spi_message,
queue);
- list_del_init(&mcfqspi->msgq);
+ list_del_init(&msg->queue);
spin_unlock_irqrestore(&mcfqspi->lock, flags);
spi = msg->spi;
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 90439314cf67..0838c79861e4 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws)
{
while (dws->write(dws))
dws->read(dws);
+ /*
+ * There is a possibility that the last word of a transaction
+ * will be lost if data is not ready. Re-read to solve this issue.
+ */
+ dws->read(dws);
transfer_complete(dws);
}
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
index ec9f0b1bf864..84439f655601 100644
--- a/drivers/spi/mpc52xx_spi.c
+++ b/drivers/spi/mpc52xx_spi.c
@@ -563,7 +563,7 @@ static struct of_platform_driver mpc52xx_spi_of_driver = {
.of_match_table = mpc52xx_spi_match,
},
.probe = mpc52xx_spi_probe,
- .remove = __exit_p(mpc52xx_spi_remove),
+ .remove = __devexit_p(mpc52xx_spi_remove),
};
static int __init mpc52xx_spi_init(void)
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 2a651e61bfbf..951a160fc27f 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:omap2_mcspi");
+#ifdef CONFIG_SUSPEND
+/*
+ * When SPI wake up from off-mode, CS is in activate state. If it was in
+ * unactive state when driver was suspend, then force it to unactive state at
+ * wake up.
+ */
+static int omap2_mcspi_resume(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
+ struct omap2_mcspi_cs *cs;
+
+ omap2_mcspi_enable_clocks(mcspi);
+ list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs,
+ node) {
+ if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) {
+
+ /*
+ * We need to toggle CS state for OMAP take this
+ * change in account.
+ */
+ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
+ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+ MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
+ __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+ }
+ }
+ omap2_mcspi_disable_clocks(mcspi);
+ return 0;
+}
+#else
+#define omap2_mcspi_resume NULL
+#endif
+
+static const struct dev_pm_ops omap2_mcspi_pm_ops = {
+ .resume = omap2_mcspi_resume,
+};
+
static struct platform_driver omap2_mcspi_driver = {
.driver = {
.name = "omap2_mcspi",
.owner = THIS_MODULE,
+ .pm = &omap2_mcspi_pm_ops
},
.remove = __exit_p(omap2_mcspi_remove),
};
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 709c836607de..b02d0cbce890 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -584,8 +584,7 @@ void spi_unregister_master(struct spi_master *master)
list_del(&master->list);
mutex_unlock(&board_lock);
- dummy = device_for_each_child(master->dev.parent, &master->dev,
- __unregister);
+ dummy = device_for_each_child(&master->dev, NULL, __unregister);
device_unregister(&master->dev);
}
EXPORT_SYMBOL_GPL(spi_unregister_master);
diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c
index e3b4f6451966..a99e2333b949 100644
--- a/drivers/spi/spi_fsl_espi.c
+++ b/drivers/spi/spi_fsl_espi.c
@@ -258,18 +258,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
return mpc8xxx_spi->count;
}
-static void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd)
+static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd)
{
- if (cmd[1] && cmd[2] && cmd[3]) {
+ if (cmd) {
cmd[1] = (u8)(addr >> 16);
cmd[2] = (u8)(addr >> 8);
cmd[3] = (u8)(addr >> 0);
}
}
-static unsigned int fsl_espi_cmd2addr(u8 *cmd)
+static inline unsigned int fsl_espi_cmd2addr(u8 *cmd)
{
- if (cmd[1] && cmd[2] && cmd[3])
+ if (cmd)
return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0;
return 0;
@@ -395,9 +395,11 @@ static void fsl_espi_rw_trans(struct spi_message *m,
}
}
- addr = fsl_espi_cmd2addr(local_buf);
- addr += pos;
- fsl_espi_addr2cmd(addr, local_buf);
+ if (pos > 0) {
+ addr = fsl_espi_cmd2addr(local_buf);
+ addr += pos;
+ fsl_espi_addr2cmd(addr, local_buf);
+ }
espi_trans->n_tx = n_tx;
espi_trans->n_rx = trans_len;
@@ -507,16 +509,29 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
/* We need handle RX first */
if (events & SPIE_NE) {
- u32 rx_data;
+ u32 rx_data, tmp;
+ u8 rx_data_8;
/* Spin until RX is done */
while (SPIE_RXCNT(events) < min(4, mspi->len)) {
cpu_relax();
events = mpc8xxx_spi_read_reg(&reg_base->event);
}
- mspi->len -= 4;
- rx_data = mpc8xxx_spi_read_reg(&reg_base->receive);
+ if (mspi->len >= 4) {
+ rx_data = mpc8xxx_spi_read_reg(&reg_base->receive);
+ } else {
+ tmp = mspi->len;
+ rx_data = 0;
+ while (tmp--) {
+ rx_data_8 = in_8((u8 *)&reg_base->receive);
+ rx_data |= (rx_data_8 << (tmp * 8));
+ }
+
+ rx_data <<= (4 - mspi->len) * 8;
+ }
+
+ mspi->len -= 4;
if (mspi->rx)
mspi->get_rx(rx_data, mspi);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index c68b3dc19e11..3918d2cc5856 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -383,6 +383,35 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env)
ssb_dev->id.revision);
}
+#define ssb_config_attr(attrib, field, format_string) \
+static ssize_t \
+attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
+}
+
+ssb_config_attr(core_num, core_index, "%u\n")
+ssb_config_attr(coreid, id.coreid, "0x%04x\n")
+ssb_config_attr(vendor, id.vendor, "0x%04x\n")
+ssb_config_attr(revision, id.revision, "%u\n")
+ssb_config_attr(irq, irq, "%u\n")
+static ssize_t
+name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n",
+ ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
+}
+
+static struct device_attribute ssb_device_attrs[] = {
+ __ATTR_RO(name),
+ __ATTR_RO(core_num),
+ __ATTR_RO(coreid),
+ __ATTR_RO(vendor),
+ __ATTR_RO(revision),
+ __ATTR_RO(irq),
+ __ATTR_NULL,
+};
+
static struct bus_type ssb_bustype = {
.name = "ssb",
.match = ssb_bus_match,
@@ -392,6 +421,7 @@ static struct bus_type ssb_bustype = {
.suspend = ssb_device_suspend,
.resume = ssb_device_resume,
.uevent = ssb_device_uevent,
+ .dev_attrs = ssb_device_attrs,
};
static void ssb_buses_lock(void)
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6e88d2b603b4..158449e55044 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -406,6 +406,46 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
out->antenna_gain.ghz5.a3 = gain;
}
+/* Revs 4 5 and 8 have partially shared layout */
+static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
+{
+ SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
+ SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
+ SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
+ SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
+ SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
+ SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
+ SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
+ SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
+
+ SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
+ SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
+ SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
+ SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
+ SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
+ SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
+ SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
+ SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
+
+ SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
+ SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
+ SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
+ SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
+ SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
+ SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
+ SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
+ SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
+
+ SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
+ SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
+ SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
+ SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
+ SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
+ SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
+ SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
+ SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
+}
+
static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
{
int i;
@@ -471,6 +511,8 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
sizeof(out->antenna_gain.ghz5));
+ sprom_extract_r458(out, in);
+
/* TODO - get remaining rev 4 stuff needed */
}
@@ -561,6 +603,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
sizeof(out->antenna_gain.ghz5));
+ sprom_extract_r458(out, in);
+
/* TODO - get remaining rev 8 stuff needed */
}
@@ -573,37 +617,34 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
memset(out->et1mac, 0xFF, 6);
+
if ((bus->chip_id & 0xFF00) == 0x4400) {
/* Workaround: The BCM44XX chip has a stupid revision
* number stored in the SPROM.
* Always extract r1. */
out->revision = 1;
+ ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
+ }
+
+ switch (out->revision) {
+ case 1:
+ case 2:
+ case 3:
sprom_extract_r123(out, in);
- } else if (bus->chip_id == 0x4321) {
- /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
- out->revision = 4;
+ break;
+ case 4:
+ case 5:
sprom_extract_r45(out, in);
- } else {
- switch (out->revision) {
- case 1:
- case 2:
- case 3:
- sprom_extract_r123(out, in);
- break;
- case 4:
- case 5:
- sprom_extract_r45(out, in);
- break;
- case 8:
- sprom_extract_r8(out, in);
- break;
- default:
- ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
- " revision %d detected. Will extract"
- " v1\n", out->revision);
- out->revision = 1;
- sprom_extract_r123(out, in);
- }
+ break;
+ case 8:
+ sprom_extract_r8(out, in);
+ break;
+ default:
+ ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
+ " revision %d detected. Will extract"
+ " v1\n", out->revision);
+ out->revision = 1;
+ sprom_extract_r123(out, in);
}
if (out->boardflags_lo == 0xFFFF)
@@ -618,7 +659,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
struct ssb_sprom *sprom)
{
const struct ssb_sprom *fallback;
- int err = -ENOMEM;
+ int err;
u16 *buf;
if (!ssb_is_sprom_available(bus)) {
@@ -645,7 +686,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
if (!buf)
- goto out;
+ return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
@@ -655,7 +696,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
if (!buf)
- goto out;
+ return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
@@ -677,7 +718,6 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
out_free:
kfree(buf);
-out:
return err;
}
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 6536a041d90d..f6c8c81a0025 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -59,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
struct ssb_bus *ssb;
int err = -ENOMEM;
const char *name;
+ u32 val;
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
@@ -74,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
goto err_pci_disable;
pci_set_master(dev);
+ /* Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_read_config_dword(dev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
+
err = ssb_bus_pcibus_register(ssb, dev);
if (err)
goto err_pci_release_regions;
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index ee079ab9fb28..5a0985d4ce15 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -405,10 +405,10 @@ int ssb_bus_scan(struct ssb_bus *bus,
/* Ignore PCI cores on PCI-E cards.
* Ignore PCI-E cores on PCI cards. */
if (dev->id.coreid == SSB_DEV_PCI) {
- if (bus->host_pci->is_pcie)
+ if (pci_is_pcie(bus->host_pci))
continue;
} else {
- if (!bus->host_pci->is_pcie)
+ if (!pci_is_pcie(bus->host_pci))
continue;
}
}
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 5eafdf435550..648142e6de64 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -51,9 +51,11 @@ source "drivers/staging/cx25821/Kconfig"
source "drivers/staging/tm6000/Kconfig"
-source "drivers/staging/cpia/Kconfig"
+source "drivers/staging/dabusb/Kconfig"
-source "drivers/staging/stradis/Kconfig"
+source "drivers/staging/se401/Kconfig"
+
+source "drivers/staging/usbvideo/Kconfig"
source "drivers/staging/usbip/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a97a955c094b..8185c00cefc1 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -8,8 +8,9 @@ obj-$(CONFIG_SLICOSS) += slicoss/
obj-$(CONFIG_VIDEO_GO7007) += go7007/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_TM6000) += tm6000/
-obj-$(CONFIG_VIDEO_CPIA) += cpia/
-obj-$(CONFIG_VIDEO_STRADIS) += stradis/
+obj-$(CONFIG_USB_DABUSB) += dabusb/
+obj-$(CONFIG_USB_VICAM) += usbvideo/
+obj-$(CONFIG_USB_SE401) += se401/
obj-$(CONFIG_LIRC_STAGING) += lirc/
obj-$(CONFIG_USB_IP_COMMON) += usbip/
obj-$(CONFIG_W35UND) += winbond/
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 8c95d8c2a4f4..016c6f7f8630 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
#define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO,
get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture);
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO,
class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture);
static int asus_oled_probe(struct usb_interface *interface,
const struct usb_device_id *id)
diff --git a/drivers/staging/autofs/root.c b/drivers/staging/autofs/root.c
index 0fdec4befd84..b09adb57971f 100644
--- a/drivers/staging/autofs/root.c
+++ b/drivers/staging/autofs/root.c
@@ -237,7 +237,7 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
*
* We need to do this before we release the directory semaphore.
*/
- dentry->d_op = &autofs_dentry_operations;
+ d_set_d_op(dentry, &autofs_dentry_operations);
dentry->d_flags |= DCACHE_AUTOFS_PENDING;
d_add(dentry, NULL);
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index b68a7e5173be..d85de82f941a 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -463,9 +463,6 @@ static void hardif_remove_interface(struct batman_if *batman_if)
return;
batman_if->if_status = IF_TO_BE_REMOVED;
-
- /* caller must take if_list_lock */
- list_del_rcu(&batman_if->list);
synchronize_rcu();
sysfs_del_hardif(&batman_if->hardif_obj);
hardif_put(batman_if);
@@ -474,13 +471,21 @@ static void hardif_remove_interface(struct batman_if *batman_if)
void hardif_remove_interfaces(void)
{
struct batman_if *batman_if, *batman_if_tmp;
+ struct list_head if_queue;
+
+ INIT_LIST_HEAD(&if_queue);
- rtnl_lock();
spin_lock(&if_list_lock);
list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
- hardif_remove_interface(batman_if);
+ list_del_rcu(&batman_if->list);
+ list_add_tail(&batman_if->list, &if_queue);
}
spin_unlock(&if_list_lock);
+
+ rtnl_lock();
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
+ hardif_remove_interface(batman_if);
+ }
rtnl_unlock();
}
@@ -507,8 +512,10 @@ static int hard_if_event(struct notifier_block *this,
break;
case NETDEV_UNREGISTER:
spin_lock(&if_list_lock);
- hardif_remove_interface(batman_if);
+ list_del_rcu(&batman_if->list);
spin_unlock(&if_list_lock);
+
+ hardif_remove_interface(batman_if);
break;
case NETDEV_CHANGEMTU:
if (batman_if->soft_iface)
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index 3904db9ce7b1..0e996181daf7 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -194,14 +194,15 @@ void interface_rx(struct net_device *soft_iface,
struct bat_priv *priv = netdev_priv(soft_iface);
/* check if enough space is available for pulling, and pull */
- if (!pskb_may_pull(skb, hdr_size)) {
- kfree_skb(skb);
- return;
- }
+ if (!pskb_may_pull(skb, hdr_size))
+ goto dropped;
+
skb_pull_rcsum(skb, hdr_size);
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
/* skb->dev & skb->pkt_type are set here */
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto dropped;
skb->protocol = eth_type_trans(skb, soft_iface);
/* should not be neccesary anymore as we use skb_pull_rcsum()
@@ -216,6 +217,11 @@ void interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
netif_rx(skb);
+ return;
+
+dropped:
+ kfree_skb(skb);
+ return;
}
#ifdef HAVE_NET_DEVICE_OPS
diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
index c8f1cf1b4409..a27bb0b4f581 100644
--- a/drivers/staging/brcm80211/README
+++ b/drivers/staging/brcm80211/README
@@ -88,7 +88,9 @@ with the driver.
Contact Info:
=============
-Brett Rudley brudley@broadcom.com
-Henry Ptasinski henryp@broadcom.com
-Dowan Kim dowan@broadcom.com
+Brett Rudley brudley@broadcom.com
+Henry Ptasinski henryp@broadcom.com
+Dowan Kim dowan@broadcom.com
+Roland Vossen rvossen@broadcom.com
+Arend van Spriel arend@broadcom.com
diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
index dbf904184899..24ebadbe4241 100644
--- a/drivers/staging/brcm80211/TODO
+++ b/drivers/staging/brcm80211/TODO
@@ -46,4 +46,6 @@ Contact
Brett Rudley <brudley@broadcom.com>
Henry Ptasinski <henryp@broadcom.com>
Dowan Kim <dowan@broadcom.com>
+Roland Vossen <rvossen@broadcom.com>
+Arend van Spriel <arend@broadcom.com>
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 1f177a67ff11..de784ff08caa 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -2295,8 +2295,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
usbduxsub_tmp->inBuffer = NULL;
kfree(usbduxsub_tmp->insnBuffer);
usbduxsub_tmp->insnBuffer = NULL;
- kfree(usbduxsub_tmp->inBuffer);
- usbduxsub_tmp->inBuffer = NULL;
+ kfree(usbduxsub_tmp->outBuffer);
+ usbduxsub_tmp->outBuffer = NULL;
kfree(usbduxsub_tmp->dac_commands);
usbduxsub_tmp->dac_commands = NULL;
kfree(usbduxsub_tmp->dux_commands);
diff --git a/drivers/staging/cpia/Kconfig b/drivers/staging/cpia/Kconfig
deleted file mode 100644
index 205d247ad373..000000000000
--- a/drivers/staging/cpia/Kconfig
+++ /dev/null
@@ -1,39 +0,0 @@
-config VIDEO_CPIA
- tristate "CPiA Video For Linux (DEPRECATED)"
- depends on VIDEO_V4L1
- default n
- ---help---
- This driver is DEPRECATED please use the gspca cpia1 module
- instead. Note that you need atleast version 0.6.4 of libv4l for
- the cpia1 gspca module.
-
- This is the video4linux driver for cameras based on Vision's CPiA
- (Colour Processor Interface ASIC), such as the Creative Labs Video
- Blaster Webcam II. If you have one of these cameras, say Y here
- and select parallel port and/or USB lowlevel support below,
- otherwise say N. This will not work with the Creative Webcam III.
-
- Please read <file:Documentation/video4linux/README.cpia> for more
- information.
-
- This driver is also available as a module (cpia).
-
-config VIDEO_CPIA_PP
- tristate "CPiA Parallel Port Lowlevel Support"
- depends on PARPORT_1284 && VIDEO_CPIA && PARPORT
- help
- This is the lowlevel parallel port support for cameras based on
- Vision's CPiA (Colour Processor Interface ASIC), such as the
- Creative Webcam II. If you have the parallel port version of one
- of these cameras, say Y here, otherwise say N. It is also available
- as a module (cpia_pp).
-
-config VIDEO_CPIA_USB
- tristate "CPiA USB Lowlevel Support"
- depends on VIDEO_CPIA && USB
- help
- This is the lowlevel USB support for cameras based on Vision's CPiA
- (Colour Processor Interface ASIC), such as the Creative Webcam II.
- If you have the USB version of one of these cameras, say Y here,
- otherwise say N. This will not work with the Creative Webcam III.
- It is also available as a module (cpia_usb).
diff --git a/drivers/staging/cpia/Makefile b/drivers/staging/cpia/Makefile
deleted file mode 100644
index 89e52f10d739..000000000000
--- a/drivers/staging/cpia/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-$(CONFIG_VIDEO_CPIA) += cpia.o
-obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
-obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
-
-EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/staging/cpia/TODO b/drivers/staging/cpia/TODO
deleted file mode 100644
index ccb1c0775eec..000000000000
--- a/drivers/staging/cpia/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-This is an obsolete driver for some cpia-based webcams that use the parallel port.
-We couldn't find anyone with this hardware in order to port it to use V4L2.
-
-Also, parallel-port webcams are obsolete nowadays.
-
-If nobody take care on it, the driver will be removed for 2.6.38.
-
-Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/cpia/cpia.c b/drivers/staging/cpia/cpia.c
deleted file mode 100644
index 0e740b8dafc3..000000000000
--- a/drivers/staging/cpia/cpia.c
+++ /dev/null
@@ -1,4028 +0,0 @@
-/*
- * cpia CPiA driver
- *
- * Supports CPiA based Video Camera's.
- *
- * (C) Copyright 1999-2000 Peter Pregler
- * (C) Copyright 1999-2000 Scott J. Bertin
- * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
- * (C) Copyright 2000 STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
-/* #define _CPIA_DEBUG_ 1 */
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ctype.h>
-#include <linux/pagemap.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <linux/mutex.h>
-
-#include "cpia.h"
-
-static int video_nr = -1;
-
-#ifdef MODULE
-module_param(video_nr, int, 0);
-MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfelt.com>");
-MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("video");
-#endif
-
-static unsigned short colorspace_conv;
-module_param(colorspace_conv, ushort, 0444);
-MODULE_PARM_DESC(colorspace_conv,
- " Colorspace conversion:"
- "\n 0 = disable, 1 = enable"
- "\n Default value is 0"
- );
-
-#define ABOUT "V4L-Driver for Vision CPiA based cameras"
-
-#define CPIA_MODULE_CPIA (0<<5)
-#define CPIA_MODULE_SYSTEM (1<<5)
-#define CPIA_MODULE_VP_CTRL (5<<5)
-#define CPIA_MODULE_CAPTURE (6<<5)
-#define CPIA_MODULE_DEBUG (7<<5)
-
-#define INPUT (DATA_IN << 8)
-#define OUTPUT (DATA_OUT << 8)
-
-#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
-#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
-#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
-#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
-#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
-#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
-#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
-#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
-
-#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
-#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
-#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
-#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
-#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
-#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
-#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
-#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
-#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
-#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
-#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
-#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
-#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
-
-#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
-#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
-#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
-#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
-#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
-#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
-#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
-#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
-#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
-#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
-#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
-#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
-#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
-#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
-#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
-#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
-#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
-
-#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
-#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
-#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
-#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
-#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
-#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
-#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
-#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
-#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
-#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
-#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
-#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
-#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
-#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
-#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
-
-#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
-#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
-#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
-#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
-#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
-#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
-#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
-#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
-
-enum {
- FRAME_READY, /* Ready to grab into */
- FRAME_GRABBING, /* In the process of being grabbed into */
- FRAME_DONE, /* Finished grabbing, but not been synced yet */
- FRAME_UNUSED, /* Unused (no MCAPTURE) */
-};
-
-#define COMMAND_NONE 0x0000
-#define COMMAND_SETCOMPRESSION 0x0001
-#define COMMAND_SETCOMPRESSIONTARGET 0x0002
-#define COMMAND_SETCOLOURPARAMS 0x0004
-#define COMMAND_SETFORMAT 0x0008
-#define COMMAND_PAUSE 0x0010
-#define COMMAND_RESUME 0x0020
-#define COMMAND_SETYUVTHRESH 0x0040
-#define COMMAND_SETECPTIMING 0x0080
-#define COMMAND_SETCOMPRESSIONPARAMS 0x0100
-#define COMMAND_SETEXPOSURE 0x0200
-#define COMMAND_SETCOLOURBALANCE 0x0400
-#define COMMAND_SETSENSORFPS 0x0800
-#define COMMAND_SETAPCOR 0x1000
-#define COMMAND_SETFLICKERCTRL 0x2000
-#define COMMAND_SETVLOFFSET 0x4000
-#define COMMAND_SETLIGHTS 0x8000
-
-#define ROUND_UP_EXP_FOR_FLICKER 15
-
-/* Constants for automatic frame rate adjustment */
-#define MAX_EXP 302
-#define MAX_EXP_102 255
-#define LOW_EXP 140
-#define VERY_LOW_EXP 70
-#define TC 94
-#define EXP_ACC_DARK 50
-#define EXP_ACC_LIGHT 90
-#define HIGH_COMP_102 160
-#define MAX_COMP 239
-#define DARK_TIME 3
-#define LIGHT_TIME 3
-
-/* Maximum number of 10ms loops to wait for the stream to become ready */
-#define READY_TIMEOUT 100
-
-/* Developer's Guide Table 5 p 3-34
- * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
-static u8 flicker_jumps[2][2][4] =
-{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
- { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
-};
-
-/* forward declaration of local function */
-static void reset_camera_struct(struct cam_data *cam);
-static int find_over_exposure(int brightness);
-static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
- int on);
-
-
-/**********************************************************************
- *
- * Memory management
- *
- **********************************************************************/
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return mem;
-}
-
-static void rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
-
-/**********************************************************************
- *
- * /proc interface
- *
- **********************************************************************/
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *cpia_proc_root=NULL;
-
-static int cpia_proc_show(struct seq_file *m, void *v)
-{
- struct cam_data *cam = m->private;
- int tmp;
- char tmpstr[29];
-
- seq_printf(m, "read-only\n-----------------------\n");
- seq_printf(m, "V4L Driver version: %d.%d.%d\n",
- CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
- seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n",
- cam->params.version.firmwareVersion,
- cam->params.version.firmwareRevision,
- cam->params.version.vcVersion,
- cam->params.version.vcRevision);
- seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n",
- cam->params.pnpID.vendor, cam->params.pnpID.product,
- cam->params.pnpID.deviceRevision);
- seq_printf(m, "VP-Version: %d.%d %04x\n",
- cam->params.vpVersion.vpVersion,
- cam->params.vpVersion.vpRevision,
- cam->params.vpVersion.cameraHeadID);
-
- seq_printf(m, "system_state: %#04x\n",
- cam->params.status.systemState);
- seq_printf(m, "grab_state: %#04x\n",
- cam->params.status.grabState);
- seq_printf(m, "stream_state: %#04x\n",
- cam->params.status.streamState);
- seq_printf(m, "fatal_error: %#04x\n",
- cam->params.status.fatalError);
- seq_printf(m, "cmd_error: %#04x\n",
- cam->params.status.cmdError);
- seq_printf(m, "debug_flags: %#04x\n",
- cam->params.status.debugFlags);
- seq_printf(m, "vp_status: %#04x\n",
- cam->params.status.vpStatus);
- seq_printf(m, "error_code: %#04x\n",
- cam->params.status.errorCode);
- /* QX3 specific entries */
- if (cam->params.qx3.qx3_detected) {
- seq_printf(m, "button: %4d\n",
- cam->params.qx3.button);
- seq_printf(m, "cradled: %4d\n",
- cam->params.qx3.cradled);
- }
- seq_printf(m, "video_size: %s\n",
- cam->params.format.videoSize == VIDEOSIZE_CIF ?
- "CIF " : "QCIF");
- seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n",
- cam->params.roi.colStart*8,
- cam->params.roi.rowStart*4,
- cam->params.roi.colEnd*8,
- cam->params.roi.rowEnd*4);
- seq_printf(m, "actual_fps: %3d\n", cam->fps);
- seq_printf(m, "transfer_rate: %4dkB/s\n",
- cam->transfer_rate);
-
- seq_printf(m, "\nread-write\n");
- seq_printf(m, "----------------------- current min"
- " max default comment\n");
- seq_printf(m, "brightness: %8d %8d %8d %8d\n",
- cam->params.colourParams.brightness, 0, 100, 50);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits contrast to 80 */
- tmp = 80;
- else
- tmp = 96;
-
- seq_printf(m, "contrast: %8d %8d %8d %8d"
- " steps of 8\n",
- cam->params.colourParams.contrast, 0, tmp, 48);
- seq_printf(m, "saturation: %8d %8d %8d %8d\n",
- cam->params.colourParams.saturation, 0, 100, 50);
- tmp = (25000+5000*cam->params.sensorFps.baserate)/
- (1<<cam->params.sensorFps.divisor);
- seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n",
- tmp/1000, tmp%1000, 3, 30, 15);
- seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n",
- 2*cam->params.streamStartLine, 0,
- cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
- cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
- seq_printf(m, "sub_sample: %8s %8s %8s %8s\n",
- cam->params.format.subSample == SUBSAMPLE_420 ?
- "420" : "422", "420", "422", "422");
- seq_printf(m, "yuv_order: %8s %8s %8s %8s\n",
- cam->params.format.yuvOrder == YUVORDER_YUYV ?
- "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
- seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n",
- cam->params.ecpTiming ? "slow" : "normal", "slow",
- "normal", "normal");
-
- if (cam->params.colourBalance.balanceMode == 2) {
- sprintf(tmpstr, "auto");
- } else {
- sprintf(tmpstr, "manual");
- }
- seq_printf(m, "color_balance_mode: %8s %8s %8s"
- " %8s\n", tmpstr, "manual", "auto", "auto");
- seq_printf(m, "red_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.redGain, 0, 212, 32);
- seq_printf(m, "green_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.greenGain, 0, 212, 6);
- seq_printf(m, "blue_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.blueGain, 0, 212, 92);
-
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits gain to 2 */
- sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2);
- else
- sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
-
- if (cam->params.exposure.gainMode == 0)
- seq_printf(m, "max_gain: unknown %28s"
- " powers of 2\n", tmpstr);
- else
- seq_printf(m, "max_gain: %8d %28s"
- " 1,2,4 or 8 \n",
- 1<<(cam->params.exposure.gainMode-1), tmpstr);
-
- switch(cam->params.exposure.expMode) {
- case 1:
- case 3:
- sprintf(tmpstr, "manual");
- break;
- case 2:
- sprintf(tmpstr, "auto");
- break;
- default:
- sprintf(tmpstr, "unknown");
- break;
- }
- seq_printf(m, "exposure_mode: %8s %8s %8s"
- " %8s\n", tmpstr, "manual", "auto", "auto");
- seq_printf(m, "centre_weight: %8s %8s %8s %8s\n",
- (2-cam->params.exposure.centreWeight) ? "on" : "off",
- "off", "on", "on");
- seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
- 1<<cam->params.exposure.gain, 1, 1);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits fineExp/2 to 127 */
- tmp = 254;
- else
- tmp = 510;
-
- seq_printf(m, "fine_exp: %8d %8d %8d %8d\n",
- cam->params.exposure.fineExp*2, 0, tmp, 0);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits coarseExpHi to 0 */
- tmp = MAX_EXP_102;
- else
- tmp = MAX_EXP;
-
- seq_printf(m, "coarse_exp: %8d %8d %8d"
- " %8d\n", cam->params.exposure.coarseExpLo+
- 256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
- seq_printf(m, "red_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
- seq_printf(m, "green1_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.green1Comp, COMP_GREEN1, 255,
- COMP_GREEN1);
- seq_printf(m, "green2_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.green2Comp, COMP_GREEN2, 255,
- COMP_GREEN2);
- seq_printf(m, "blue_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
-
- seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain1, 0, 0xff, 0x1c);
- seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain2, 0, 0xff, 0x1a);
- seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain4, 0, 0xff, 0x2d);
- seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain8, 0, 0xff, 0x2a);
- seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain1, 0, 255, 24);
- seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain2, 0, 255, 28);
- seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain4, 0, 255, 30);
- seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain8, 0, 255, 30);
- seq_printf(m, "flicker_control: %8s %8s %8s %8s\n",
- cam->params.flickerControl.flickerMode ? "on" : "off",
- "off", "on", "off");
- seq_printf(m, "mains_frequency: %8d %8d %8d %8d"
- " only 50/60\n",
- cam->mainsFreq ? 60 : 50, 50, 60, 50);
- if(cam->params.flickerControl.allowableOverExposure < 0)
- seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n",
- -cam->params.flickerControl.allowableOverExposure,
- 255);
- else
- seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n",
- cam->params.flickerControl.allowableOverExposure,
- 255);
- seq_printf(m, "compression_mode: ");
- switch(cam->params.compression.mode) {
- case CPIA_COMPRESSION_NONE:
- seq_printf(m, "%8s", "none");
- break;
- case CPIA_COMPRESSION_AUTO:
- seq_printf(m, "%8s", "auto");
- break;
- case CPIA_COMPRESSION_MANUAL:
- seq_printf(m, "%8s", "manual");
- break;
- default:
- seq_printf(m, "%8s", "unknown");
- break;
- }
- seq_printf(m, " none,auto,manual auto\n");
- seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n",
- cam->params.compression.decimation ==
- DECIMATION_ENAB ? "on":"off", "off", "on",
- "off");
- seq_printf(m, "compression_target: %9s %9s %9s %9s\n",
- cam->params.compressionTarget.frTargeting ==
- CPIA_COMPRESSION_TARGET_FRAMERATE ?
- "framerate":"quality",
- "framerate", "quality", "quality");
- seq_printf(m, "target_framerate: %8d %8d %8d %8d\n",
- cam->params.compressionTarget.targetFR, 1, 30, 15);
- seq_printf(m, "target_quality: %8d %8d %8d %8d\n",
- cam->params.compressionTarget.targetQ, 1, 64, 5);
- seq_printf(m, "y_threshold: %8d %8d %8d %8d\n",
- cam->params.yuvThreshold.yThreshold, 0, 31, 6);
- seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n",
- cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
- seq_printf(m, "hysteresis: %8d %8d %8d %8d\n",
- cam->params.compressionParams.hysteresis, 0, 255, 3);
- seq_printf(m, "threshold_max: %8d %8d %8d %8d\n",
- cam->params.compressionParams.threshMax, 0, 255, 11);
- seq_printf(m, "small_step: %8d %8d %8d %8d\n",
- cam->params.compressionParams.smallStep, 0, 255, 1);
- seq_printf(m, "large_step: %8d %8d %8d %8d\n",
- cam->params.compressionParams.largeStep, 0, 255, 3);
- seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n",
- cam->params.compressionParams.decimationHysteresis,
- 0, 255, 2);
- seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
- cam->params.compressionParams.frDiffStepThresh,
- 0, 255, 5);
- seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n",
- cam->params.compressionParams.qDiffStepThresh,
- 0, 255, 3);
- seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n",
- cam->params.compressionParams.decimationThreshMod,
- 0, 255, 2);
- /* QX3 specific entries */
- if (cam->params.qx3.qx3_detected) {
- seq_printf(m, "toplight: %8s %8s %8s %8s\n",
- cam->params.qx3.toplight ? "on" : "off",
- "off", "on", "off");
- seq_printf(m, "bottomlight: %8s %8s %8s %8s\n",
- cam->params.qx3.bottomlight ? "on" : "off",
- "off", "on", "off");
- }
-
- return 0;
-}
-
-static int cpia_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cpia_proc_show, PDE(inode)->data);
-}
-
-static int match(char *checkstr, char **buffer, size_t *count,
- int *find_colon, int *err)
-{
- int ret, colon_found = 1;
- int len = strlen(checkstr);
- ret = (len <= *count && strncmp(*buffer, checkstr, len) == 0);
- if (ret) {
- *buffer += len;
- *count -= len;
- if (*find_colon) {
- colon_found = 0;
- while (*count && (**buffer == ' ' || **buffer == '\t' ||
- (!colon_found && **buffer == ':'))) {
- if (**buffer == ':')
- colon_found = 1;
- --*count;
- ++*buffer;
- }
- if (!*count || !colon_found)
- *err = -EINVAL;
- *find_colon = 0;
- }
- }
- return ret;
-}
-
-static unsigned long int value(char **buffer, size_t *count, int *err)
-{
- char *p;
- unsigned long int ret;
- ret = simple_strtoul(*buffer, &p, 0);
- if (p == *buffer)
- *err = -EINVAL;
- else {
- *count -= p - *buffer;
- *buffer = p;
- }
- return ret;
-}
-
-static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
- size_t count, loff_t *pos)
-{
- struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
- struct cam_params new_params;
- char *page, *buffer;
- int retval, find_colon;
- int size = count;
- unsigned long val = 0;
- u32 command_flags = 0;
- u8 new_mains;
-
- /*
- * This code to copy from buf to page is shamelessly copied
- * from the comx driver
- */
- if (count > PAGE_SIZE) {
- printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
- return -ENOSPC;
- }
-
- if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
-
- if(copy_from_user(page, buf, count))
- {
- retval = -EFAULT;
- goto out;
- }
-
- if (page[count-1] == '\n')
- page[count-1] = '\0';
- else if (count < PAGE_SIZE)
- page[count] = '\0';
- else if (page[count]) {
- retval = -EINVAL;
- goto out;
- }
-
- buffer = page;
-
- if (mutex_lock_interruptible(&cam->param_lock))
- return -ERESTARTSYS;
-
- /*
- * Skip over leading whitespace
- */
- while (count && isspace(*buffer)) {
- --count;
- ++buffer;
- }
-
- memcpy(&new_params, &cam->params, sizeof(struct cam_params));
- new_mains = cam->mainsFreq;
-
-#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
-#define VALUE (value(&buffer,&count, &retval))
-#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
- new_params.version.firmwareRevision == (y))
-
- retval = 0;
- while (count && !retval) {
- find_colon = 1;
- if (MATCH("brightness")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100)
- new_params.colourParams.brightness = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- if(new_params.flickerControl.allowableOverExposure < 0)
- new_params.flickerControl.allowableOverExposure =
- -find_over_exposure(new_params.colourParams.brightness);
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
-
- } else if (MATCH("contrast")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100) {
- /* contrast is in steps of 8, so round*/
- val = ((val + 3) / 8) * 8;
- /* 1-02 firmware limits contrast to 80*/
- if (FIRMWARE_VERSION(1,2) && val > 80)
- val = 80;
-
- new_params.colourParams.contrast = val;
- } else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- } else if (MATCH("saturation")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100)
- new_params.colourParams.saturation = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- } else if (MATCH("sensor_fps")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- /* find values so that sensorFPS is minimized,
- * but >= val */
- if (val > 30)
- retval = -EINVAL;
- else if (val > 25) {
- new_params.sensorFps.divisor = 0;
- new_params.sensorFps.baserate = 1;
- } else if (val > 15) {
- new_params.sensorFps.divisor = 0;
- new_params.sensorFps.baserate = 0;
- } else if (val > 12) {
- new_params.sensorFps.divisor = 1;
- new_params.sensorFps.baserate = 1;
- } else if (val > 7) {
- new_params.sensorFps.divisor = 1;
- new_params.sensorFps.baserate = 0;
- } else if (val > 6) {
- new_params.sensorFps.divisor = 2;
- new_params.sensorFps.baserate = 1;
- } else if (val > 3) {
- new_params.sensorFps.divisor = 2;
- new_params.sensorFps.baserate = 0;
- } else {
- new_params.sensorFps.divisor = 3;
- /* Either base rate would work here */
- new_params.sensorFps.baserate = 1;
- }
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- }
- command_flags |= COMMAND_SETSENSORFPS;
- cam->exposure_status = EXPOSURE_NORMAL;
- } else if (MATCH("stream_start_line")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- int max_line = 288;
-
- if (new_params.format.videoSize == VIDEOSIZE_QCIF)
- max_line = 144;
- if (val <= max_line)
- new_params.streamStartLine = val/2;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("sub_sample")) {
- if (!retval && MATCH("420"))
- new_params.format.subSample = SUBSAMPLE_420;
- else if (!retval && MATCH("422"))
- new_params.format.subSample = SUBSAMPLE_422;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETFORMAT;
- } else if (MATCH("yuv_order")) {
- if (!retval && MATCH("YUYV"))
- new_params.format.yuvOrder = YUVORDER_YUYV;
- else if (!retval && MATCH("UYVY"))
- new_params.format.yuvOrder = YUVORDER_UYVY;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETFORMAT;
- } else if (MATCH("ecp_timing")) {
- if (!retval && MATCH("normal"))
- new_params.ecpTiming = 0;
- else if (!retval && MATCH("slow"))
- new_params.ecpTiming = 1;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETECPTIMING;
- } else if (MATCH("color_balance_mode")) {
- if (!retval && MATCH("manual"))
- new_params.colourBalance.balanceMode = 3;
- else if (!retval && MATCH("auto"))
- new_params.colourBalance.balanceMode = 2;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("red_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212) {
- new_params.colourBalance.redGain = val;
- new_params.colourBalance.balanceMode = 1;
- } else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("green_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212) {
- new_params.colourBalance.greenGain = val;
- new_params.colourBalance.balanceMode = 1;
- } else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("blue_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212) {
- new_params.colourBalance.blueGain = val;
- new_params.colourBalance.balanceMode = 1;
- } else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("max_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- /* 1-02 firmware limits gain to 2 */
- if (FIRMWARE_VERSION(1,2) && val > 2)
- val = 2;
- switch(val) {
- case 1:
- new_params.exposure.gainMode = 1;
- break;
- case 2:
- new_params.exposure.gainMode = 2;
- break;
- case 4:
- new_params.exposure.gainMode = 3;
- break;
- case 8:
- new_params.exposure.gainMode = 4;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- }
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("exposure_mode")) {
- if (!retval && MATCH("auto"))
- new_params.exposure.expMode = 2;
- else if (!retval && MATCH("manual")) {
- if (new_params.exposure.expMode == 2)
- new_params.exposure.expMode = 3;
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- new_params.flickerControl.flickerMode = 0;
- } else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("centre_weight")) {
- if (!retval && MATCH("on"))
- new_params.exposure.centreWeight = 1;
- else if (!retval && MATCH("off"))
- new_params.exposure.centreWeight = 2;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- switch(val) {
- case 1:
- new_params.exposure.gain = 0;
- break;
- case 2:
- new_params.exposure.gain = 1;
- break;
- case 4:
- new_params.exposure.gain = 2;
- break;
- case 8:
- new_params.exposure.gain = 3;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- new_params.exposure.expMode = 1;
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETEXPOSURE;
- if (new_params.exposure.gain >
- new_params.exposure.gainMode-1)
- retval = -EINVAL;
- }
- } else if (MATCH("fine_exp")) {
- if (!retval)
- val = VALUE/2;
-
- if (!retval) {
- if (val < 256) {
- /* 1-02 firmware limits fineExp/2 to 127*/
- if (FIRMWARE_VERSION(1,2) && val > 127)
- val = 127;
- new_params.exposure.fineExp = val;
- new_params.exposure.expMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("coarse_exp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= MAX_EXP) {
- if (FIRMWARE_VERSION(1,2) &&
- val > MAX_EXP_102)
- val = MAX_EXP_102;
- new_params.exposure.coarseExpLo =
- val & 0xff;
- new_params.exposure.coarseExpHi =
- val >> 8;
- new_params.exposure.expMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("red_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= COMP_RED && val <= 255) {
- new_params.exposure.redComp = val;
- new_params.exposure.compMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("green1_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= COMP_GREEN1 && val <= 255) {
- new_params.exposure.green1Comp = val;
- new_params.exposure.compMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("green2_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= COMP_GREEN2 && val <= 255) {
- new_params.exposure.green2Comp = val;
- new_params.exposure.compMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("blue_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= COMP_BLUE && val <= 255) {
- new_params.exposure.blueComp = val;
- new_params.exposure.compMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain1")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain1 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain2")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain2 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain4")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain4 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain8")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain8 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("vl_offset_gain1")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain1 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain2")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain2 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain4")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain4 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain8")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain8 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("flicker_control")) {
- if (!retval && MATCH("on")) {
- set_flicker(&new_params, &command_flags, 1);
- } else if (!retval && MATCH("off")) {
- set_flicker(&new_params, &command_flags, 0);
- } else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else if (MATCH("mains_frequency")) {
- if (!retval && MATCH("50")) {
- new_mains = 0;
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else if (!retval && MATCH("60")) {
- new_mains = 1;
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- } else if (MATCH("allowable_overexposure")) {
- if (!retval && MATCH("auto")) {
- new_params.flickerControl.allowableOverExposure =
- -find_over_exposure(new_params.colourParams.brightness);
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff) {
- new_params.flickerControl.
- allowableOverExposure = val;
- if(new_params.flickerControl.flickerMode != 0)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- }
- } else if (MATCH("compression_mode")) {
- if (!retval && MATCH("none"))
- new_params.compression.mode =
- CPIA_COMPRESSION_NONE;
- else if (!retval && MATCH("auto"))
- new_params.compression.mode =
- CPIA_COMPRESSION_AUTO;
- else if (!retval && MATCH("manual"))
- new_params.compression.mode =
- CPIA_COMPRESSION_MANUAL;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSION;
- } else if (MATCH("decimation_enable")) {
- if (!retval && MATCH("off"))
- new_params.compression.decimation = 0;
- else if (!retval && MATCH("on"))
- new_params.compression.decimation = 1;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSION;
- } else if (MATCH("compression_target")) {
- if (!retval && MATCH("quality"))
- new_params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_QUALITY;
- else if (!retval && MATCH("framerate"))
- new_params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_FRAMERATE;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("target_framerate")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if(val > 0 && val <= 30)
- new_params.compressionTarget.targetFR = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("target_quality")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if(val > 0 && val <= 64)
- new_params.compressionTarget.targetQ = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("y_threshold")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 32)
- new_params.yuvThreshold.yThreshold = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETYUVTHRESH;
- } else if (MATCH("uv_threshold")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 32)
- new_params.yuvThreshold.uvThreshold = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETYUVTHRESH;
- } else if (MATCH("hysteresis")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.hysteresis = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("threshold_max")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.threshMax = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("small_step")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.smallStep = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("large_step")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.largeStep = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("decimation_hysteresis")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.decimationHysteresis = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("fr_diff_step_thresh")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.frDiffStepThresh = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("q_diff_step_thresh")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.qDiffStepThresh = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("decimation_thresh_mod")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.decimationThreshMod = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("toplight")) {
- if (!retval && MATCH("on"))
- new_params.qx3.toplight = 1;
- else if (!retval && MATCH("off"))
- new_params.qx3.toplight = 0;
- else
- retval = -EINVAL;
- command_flags |= COMMAND_SETLIGHTS;
- } else if (MATCH("bottomlight")) {
- if (!retval && MATCH("on"))
- new_params.qx3.bottomlight = 1;
- else if (!retval && MATCH("off"))
- new_params.qx3.bottomlight = 0;
- else
- retval = -EINVAL;
- command_flags |= COMMAND_SETLIGHTS;
- } else {
- DBG("No match found\n");
- retval = -EINVAL;
- }
-
- if (!retval) {
- while (count && isspace(*buffer) && *buffer != '\n') {
- --count;
- ++buffer;
- }
- if (count) {
- if (*buffer == '\0' && count != 1)
- retval = -EINVAL;
- else if (*buffer != '\n' && *buffer != ';' &&
- *buffer != '\0')
- retval = -EINVAL;
- else {
- --count;
- ++buffer;
- }
- }
- }
- }
-#undef MATCH
-#undef VALUE
-#undef FIRMWARE_VERSION
- if (!retval) {
- if (command_flags & COMMAND_SETCOLOURPARAMS) {
- /* Adjust cam->vp to reflect these changes */
- cam->vp.brightness =
- new_params.colourParams.brightness*65535/100;
- cam->vp.contrast =
- new_params.colourParams.contrast*65535/100;
- cam->vp.colour =
- new_params.colourParams.saturation*65535/100;
- }
- if((command_flags & COMMAND_SETEXPOSURE) &&
- new_params.exposure.expMode == 2)
- cam->exposure_status = EXPOSURE_NORMAL;
-
- memcpy(&cam->params, &new_params, sizeof(struct cam_params));
- cam->mainsFreq = new_mains;
- cam->cmd_queue |= command_flags;
- retval = size;
- } else
- DBG("error: %d\n", retval);
-
- mutex_unlock(&cam->param_lock);
-
-out:
- free_page((unsigned long)page);
- return retval;
-}
-
-static const struct file_operations cpia_proc_fops = {
- .owner = THIS_MODULE,
- .open = cpia_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cpia_proc_write,
-};
-
-static void create_proc_cpia_cam(struct cam_data *cam)
-{
- struct proc_dir_entry *ent;
-
- if (!cpia_proc_root || !cam)
- return;
-
- ent = proc_create_data(video_device_node_name(&cam->vdev),
- S_IRUGO|S_IWUSR, cpia_proc_root,
- &cpia_proc_fops, cam);
- if (!ent)
- return;
-
- /*
- size of the proc entry is 3736 bytes for the standard webcam;
- the extra features of the QX3 microscope add 189 bytes.
- (we have not yet probed the camera to see which type it is).
- */
- ent->size = 3736 + 189;
- cam->proc_entry = ent;
-}
-
-static void destroy_proc_cpia_cam(struct cam_data *cam)
-{
- if (!cam || !cam->proc_entry)
- return;
-
- remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root);
- cam->proc_entry = NULL;
-}
-
-static void proc_cpia_create(void)
-{
- cpia_proc_root = proc_mkdir("cpia", NULL);
-
- if (!cpia_proc_root)
- LOG("Unable to initialise /proc/cpia\n");
-}
-
-static void __exit proc_cpia_destroy(void)
-{
- remove_proc_entry("cpia", NULL);
-}
-#endif /* CONFIG_PROC_FS */
-
-/* ----------------------- debug functions ---------------------- */
-
-#define printstatus(cam) \
- DBG("%02x %02x %02x %02x %02x %02x %02x %02x\n",\
- cam->params.status.systemState, cam->params.status.grabState, \
- cam->params.status.streamState, cam->params.status.fatalError, \
- cam->params.status.cmdError, cam->params.status.debugFlags, \
- cam->params.status.vpStatus, cam->params.status.errorCode);
-
-/* ----------------------- v4l helpers -------------------------- */
-
-/* supported frame palettes and depths */
-static inline int valid_mode(u16 palette, u16 depth)
-{
- if ((palette == VIDEO_PALETTE_YUV422 && depth == 16) ||
- (palette == VIDEO_PALETTE_YUYV && depth == 16))
- return 1;
-
- if (colorspace_conv)
- return (palette == VIDEO_PALETTE_GREY && depth == 8) ||
- (palette == VIDEO_PALETTE_RGB555 && depth == 16) ||
- (palette == VIDEO_PALETTE_RGB565 && depth == 16) ||
- (palette == VIDEO_PALETTE_RGB24 && depth == 24) ||
- (palette == VIDEO_PALETTE_RGB32 && depth == 32) ||
- (palette == VIDEO_PALETTE_UYVY && depth == 16);
-
- return 0;
-}
-
-static int match_videosize( int width, int height )
-{
- /* return the best match, where 'best' is as always
- * the largest that is not bigger than what is requested. */
- if (width>=352 && height>=288)
- return VIDEOSIZE_352_288; /* CIF */
-
- if (width>=320 && height>=240)
- return VIDEOSIZE_320_240; /* SIF */
-
- if (width>=288 && height>=216)
- return VIDEOSIZE_288_216;
-
- if (width>=256 && height>=192)
- return VIDEOSIZE_256_192;
-
- if (width>=224 && height>=168)
- return VIDEOSIZE_224_168;
-
- if (width>=192 && height>=144)
- return VIDEOSIZE_192_144;
-
- if (width>=176 && height>=144)
- return VIDEOSIZE_176_144; /* QCIF */
-
- if (width>=160 && height>=120)
- return VIDEOSIZE_160_120; /* QSIF */
-
- if (width>=128 && height>=96)
- return VIDEOSIZE_128_96;
-
- if (width>=88 && height>=72)
- return VIDEOSIZE_88_72;
-
- if (width>=64 && height>=48)
- return VIDEOSIZE_64_48;
-
- if (width>=48 && height>=48)
- return VIDEOSIZE_48_48;
-
- return -1;
-}
-
-/* these are the capture sizes we support */
-static void set_vw_size(struct cam_data *cam)
-{
- /* the col/row/start/end values are the result of simple math */
- /* study the SetROI-command in cpia developers guide p 2-22 */
- /* streamStartLine is set to the recommended value in the cpia */
- /* developers guide p 3-37 */
- switch(cam->video_size) {
- case VIDEOSIZE_CIF:
- cam->vw.width = 352;
- cam->vw.height = 288;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=0;
- cam->params.roi.rowStart=0;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_SIF:
- cam->vw.width = 320;
- cam->vw.height = 240;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=2;
- cam->params.roi.rowStart=6;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_288_216:
- cam->vw.width = 288;
- cam->vw.height = 216;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=4;
- cam->params.roi.rowStart=9;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_256_192:
- cam->vw.width = 256;
- cam->vw.height = 192;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=6;
- cam->params.roi.rowStart=12;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_224_168:
- cam->vw.width = 224;
- cam->vw.height = 168;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=8;
- cam->params.roi.rowStart=15;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_192_144:
- cam->vw.width = 192;
- cam->vw.height = 144;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=10;
- cam->params.roi.rowStart=18;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_QCIF:
- cam->vw.width = 176;
- cam->vw.height = 144;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=0;
- cam->params.roi.rowStart=0;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_QSIF:
- cam->vw.width = 160;
- cam->vw.height = 120;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=1;
- cam->params.roi.rowStart=3;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_128_96:
- cam->vw.width = 128;
- cam->vw.height = 96;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=3;
- cam->params.roi.rowStart=6;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_88_72:
- cam->vw.width = 88;
- cam->vw.height = 72;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=5;
- cam->params.roi.rowStart=9;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_64_48:
- cam->vw.width = 64;
- cam->vw.height = 48;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=7;
- cam->params.roi.rowStart=12;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_48_48:
- cam->vw.width = 48;
- cam->vw.height = 48;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=8;
- cam->params.roi.rowStart=6;
- cam->params.streamStartLine = 60;
- break;
- default:
- LOG("bad videosize value: %d\n", cam->video_size);
- return;
- }
-
- if(cam->vc.width == 0)
- cam->vc.width = cam->vw.width;
- if(cam->vc.height == 0)
- cam->vc.height = cam->vw.height;
-
- cam->params.roi.colStart += cam->vc.x >> 3;
- cam->params.roi.colEnd = cam->params.roi.colStart +
- (cam->vc.width >> 3);
- cam->params.roi.rowStart += cam->vc.y >> 2;
- cam->params.roi.rowEnd = cam->params.roi.rowStart +
- (cam->vc.height >> 2);
-
- return;
-}
-
-static int allocate_frame_buf(struct cam_data *cam)
-{
- int i;
-
- cam->frame_buf = rvmalloc(FRAME_NUM * CPIA_MAX_FRAME_SIZE);
- if (!cam->frame_buf)
- return -ENOBUFS;
-
- for (i = 0; i < FRAME_NUM; i++)
- cam->frame[i].data = cam->frame_buf + i * CPIA_MAX_FRAME_SIZE;
-
- return 0;
-}
-
-static int free_frame_buf(struct cam_data *cam)
-{
- int i;
-
- rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);
- cam->frame_buf = NULL;
- for (i=0; i < FRAME_NUM; i++)
- cam->frame[i].data = NULL;
-
- return 0;
-}
-
-
-static inline void free_frames(struct cpia_frame frame[FRAME_NUM])
-{
- int i;
-
- for (i=0; i < FRAME_NUM; i++)
- frame[i].state = FRAME_UNUSED;
- return;
-}
-
-/**********************************************************************
- *
- * General functions
- *
- **********************************************************************/
-/* send an arbitrary command to the camera */
-static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
-{
- int retval, datasize;
- u8 cmd[8], data[8];
-
- switch(command) {
- case CPIA_COMMAND_GetCPIAVersion:
- case CPIA_COMMAND_GetPnPID:
- case CPIA_COMMAND_GetCameraStatus:
- case CPIA_COMMAND_GetVPVersion:
- datasize=8;
- break;
- case CPIA_COMMAND_GetColourParams:
- case CPIA_COMMAND_GetColourBalance:
- case CPIA_COMMAND_GetExposure:
- mutex_lock(&cam->param_lock);
- datasize=8;
- break;
- case CPIA_COMMAND_ReadMCPorts:
- case CPIA_COMMAND_ReadVCRegs:
- datasize = 4;
- break;
- default:
- datasize=0;
- break;
- }
-
- cmd[0] = command>>8;
- cmd[1] = command&0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = datasize;
- cmd[7] = 0;
-
- retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
- if (retval) {
- DBG("%x - failed, retval=%d\n", command, retval);
- if (command == CPIA_COMMAND_GetColourParams ||
- command == CPIA_COMMAND_GetColourBalance ||
- command == CPIA_COMMAND_GetExposure)
- mutex_unlock(&cam->param_lock);
- } else {
- switch(command) {
- case CPIA_COMMAND_GetCPIAVersion:
- cam->params.version.firmwareVersion = data[0];
- cam->params.version.firmwareRevision = data[1];
- cam->params.version.vcVersion = data[2];
- cam->params.version.vcRevision = data[3];
- break;
- case CPIA_COMMAND_GetPnPID:
- cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);
- cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);
- cam->params.pnpID.deviceRevision =
- data[4]+(((u16)data[5])<<8);
- break;
- case CPIA_COMMAND_GetCameraStatus:
- cam->params.status.systemState = data[0];
- cam->params.status.grabState = data[1];
- cam->params.status.streamState = data[2];
- cam->params.status.fatalError = data[3];
- cam->params.status.cmdError = data[4];
- cam->params.status.debugFlags = data[5];
- cam->params.status.vpStatus = data[6];
- cam->params.status.errorCode = data[7];
- break;
- case CPIA_COMMAND_GetVPVersion:
- cam->params.vpVersion.vpVersion = data[0];
- cam->params.vpVersion.vpRevision = data[1];
- cam->params.vpVersion.cameraHeadID =
- data[2]+(((u16)data[3])<<8);
- break;
- case CPIA_COMMAND_GetColourParams:
- cam->params.colourParams.brightness = data[0];
- cam->params.colourParams.contrast = data[1];
- cam->params.colourParams.saturation = data[2];
- mutex_unlock(&cam->param_lock);
- break;
- case CPIA_COMMAND_GetColourBalance:
- cam->params.colourBalance.redGain = data[0];
- cam->params.colourBalance.greenGain = data[1];
- cam->params.colourBalance.blueGain = data[2];
- mutex_unlock(&cam->param_lock);
- break;
- case CPIA_COMMAND_GetExposure:
- cam->params.exposure.gain = data[0];
- cam->params.exposure.fineExp = data[1];
- cam->params.exposure.coarseExpLo = data[2];
- cam->params.exposure.coarseExpHi = data[3];
- cam->params.exposure.redComp = data[4];
- cam->params.exposure.green1Comp = data[5];
- cam->params.exposure.green2Comp = data[6];
- cam->params.exposure.blueComp = data[7];
- mutex_unlock(&cam->param_lock);
- break;
-
- case CPIA_COMMAND_ReadMCPorts:
- if (!cam->params.qx3.qx3_detected)
- break;
- /* test button press */
- cam->params.qx3.button = ((data[1] & 0x02) == 0);
- if (cam->params.qx3.button) {
- /* button pressed - unlock the latch */
- do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);
- do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);
- }
-
- /* test whether microscope is cradled */
- cam->params.qx3.cradled = ((data[2] & 0x40) == 0);
- break;
-
- default:
- break;
- }
- }
- return retval;
-}
-
-/* send a command to the camera with an additional data transaction */
-static int do_command_extended(struct cam_data *cam, u16 command,
- u8 a, u8 b, u8 c, u8 d,
- u8 e, u8 f, u8 g, u8 h,
- u8 i, u8 j, u8 k, u8 l)
-{
- int retval;
- u8 cmd[8], data[8];
-
- cmd[0] = command>>8;
- cmd[1] = command&0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = 8;
- cmd[7] = 0;
- data[0] = e;
- data[1] = f;
- data[2] = g;
- data[3] = h;
- data[4] = i;
- data[5] = j;
- data[6] = k;
- data[7] = l;
-
- retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
- if (retval)
- DBG("%x - failed\n", command);
-
- return retval;
-}
-
-/**********************************************************************
- *
- * Colorspace conversion
- *
- **********************************************************************/
-#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
-
-static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt,
- int linesize, int mmap_kludge)
-{
- int y, u, v, r, g, b, y1;
-
- /* Odd lines use the same u and v as the previous line.
- * Because of compression, it is necessary to get this
- * information from the decoded image. */
- switch(out_fmt) {
- case VIDEO_PALETTE_RGB555:
- y = (*yuv++ - 16) * 76310;
- y1 = (*yuv - 16) * 76310;
- r = ((*(rgb+1-linesize)) & 0x7c) << 1;
- g = ((*(rgb-linesize)) & 0xe0) >> 4 |
- ((*(rgb+1-linesize)) & 0x03) << 6;
- b = ((*(rgb-linesize)) & 0x1f) << 3;
- u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
- v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
- r = 104635 * v;
- g = -25690 * u - 53294 * v;
- b = 132278 * u;
- *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
- *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
- *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
- *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
- return 4;
- case VIDEO_PALETTE_RGB565:
- y = (*yuv++ - 16) * 76310;
- y1 = (*yuv - 16) * 76310;
- r = (*(rgb+1-linesize)) & 0xf8;
- g = ((*(rgb-linesize)) & 0xe0) >> 3 |
- ((*(rgb+1-linesize)) & 0x07) << 5;
- b = ((*(rgb-linesize)) & 0x1f) << 3;
- u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
- v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
- r = 104635 * v;
- g = -25690 * u - 53294 * v;
- b = 132278 * u;
- *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
- *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
- *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
- *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
- return 4;
- break;
- case VIDEO_PALETTE_RGB24:
- case VIDEO_PALETTE_RGB32:
- y = (*yuv++ - 16) * 76310;
- y1 = (*yuv - 16) * 76310;
- if (mmap_kludge) {
- r = *(rgb+2-linesize);
- g = *(rgb+1-linesize);
- b = *(rgb-linesize);
- } else {
- r = *(rgb-linesize);
- g = *(rgb+1-linesize);
- b = *(rgb+2-linesize);
- }
- u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
- v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
- r = 104635 * v;
- g = -25690 * u + -53294 * v;
- b = 132278 * u;
- if (mmap_kludge) {
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(r+y);
- if(out_fmt == VIDEO_PALETTE_RGB32)
- rgb++;
- *rgb++ = LIMIT(b+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(r+y1);
- } else {
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(b+y);
- if(out_fmt == VIDEO_PALETTE_RGB32)
- rgb++;
- *rgb++ = LIMIT(r+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(b+y1);
- }
- if(out_fmt == VIDEO_PALETTE_RGB32)
- return 8;
- return 6;
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- y = *yuv++;
- u = *(rgb+1-linesize);
- y1 = *yuv;
- v = *(rgb+3-linesize);
- *rgb++ = y;
- *rgb++ = u;
- *rgb++ = y1;
- *rgb = v;
- return 4;
- case VIDEO_PALETTE_UYVY:
- u = *(rgb-linesize);
- y = *yuv++;
- v = *(rgb+2-linesize);
- y1 = *yuv;
- *rgb++ = u;
- *rgb++ = y;
- *rgb++ = v;
- *rgb = y1;
- return 4;
- case VIDEO_PALETTE_GREY:
- *rgb++ = *yuv++;
- *rgb = *yuv;
- return 2;
- default:
- DBG("Empty: %d\n", out_fmt);
- return 0;
- }
-}
-
-
-static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,
- int in_uyvy, int mmap_kludge)
-{
- int y, u, v, r, g, b, y1;
-
- switch(out_fmt) {
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_RGB24:
- case VIDEO_PALETTE_RGB32:
- if (in_uyvy) {
- u = *yuv++ - 128;
- y = (*yuv++ - 16) * 76310;
- v = *yuv++ - 128;
- y1 = (*yuv - 16) * 76310;
- } else {
- y = (*yuv++ - 16) * 76310;
- u = *yuv++ - 128;
- y1 = (*yuv++ - 16) * 76310;
- v = *yuv - 128;
- }
- r = 104635 * v;
- g = -25690 * u + -53294 * v;
- b = 132278 * u;
- break;
- default:
- y = *yuv++;
- u = *yuv++;
- y1 = *yuv++;
- v = *yuv;
- /* Just to avoid compiler warnings */
- r = 0;
- g = 0;
- b = 0;
- break;
- }
- switch(out_fmt) {
- case VIDEO_PALETTE_RGB555:
- *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
- *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
- *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
- *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
- return 4;
- case VIDEO_PALETTE_RGB565:
- *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
- *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
- *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
- *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
- return 4;
- case VIDEO_PALETTE_RGB24:
- if (mmap_kludge) {
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(b+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(r+y1);
- } else {
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(r+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(b+y1);
- }
- return 6;
- case VIDEO_PALETTE_RGB32:
- if (mmap_kludge) {
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(r+y);
- rgb++;
- *rgb++ = LIMIT(b+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(r+y1);
- } else {
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(b+y);
- rgb++;
- *rgb++ = LIMIT(r+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(b+y1);
- }
- return 8;
- case VIDEO_PALETTE_GREY:
- *rgb++ = y;
- *rgb = y1;
- return 2;
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- *rgb++ = y;
- *rgb++ = u;
- *rgb++ = y1;
- *rgb = v;
- return 4;
- case VIDEO_PALETTE_UYVY:
- *rgb++ = u;
- *rgb++ = y;
- *rgb++ = v;
- *rgb = y1;
- return 4;
- default:
- DBG("Empty: %d\n", out_fmt);
- return 0;
- }
-}
-
-static int skipcount(int count, int fmt)
-{
- switch(fmt) {
- case VIDEO_PALETTE_GREY:
- return count;
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- case VIDEO_PALETTE_UYVY:
- return 2*count;
- case VIDEO_PALETTE_RGB24:
- return 3*count;
- case VIDEO_PALETTE_RGB32:
- return 4*count;
- default:
- return 0;
- }
-}
-
-static int parse_picture(struct cam_data *cam, int size)
-{
- u8 *obuf, *ibuf, *end_obuf;
- int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt;
- int rows, cols, linesize, subsample_422;
-
- /* make sure params don't change while we are decoding */
- mutex_lock(&cam->param_lock);
-
- obuf = cam->decompressed_frame.data;
- end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
- ibuf = cam->raw_image;
- origsize = size;
- out_fmt = cam->vp.palette;
-
- if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
- LOG("header not found\n");
- mutex_unlock(&cam->param_lock);
- return -1;
- }
-
- if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
- LOG("wrong video size\n");
- mutex_unlock(&cam->param_lock);
- return -1;
- }
-
- if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) {
- LOG("illegal subtype %d\n",ibuf[17]);
- mutex_unlock(&cam->param_lock);
- return -1;
- }
- subsample_422 = ibuf[17] == SUBSAMPLE_422;
-
- if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
- LOG("illegal yuvorder %d\n",ibuf[18]);
- mutex_unlock(&cam->param_lock);
- return -1;
- }
- in_uyvy = ibuf[18] == YUVORDER_UYVY;
-
- if ((ibuf[24] != cam->params.roi.colStart) ||
- (ibuf[25] != cam->params.roi.colEnd) ||
- (ibuf[26] != cam->params.roi.rowStart) ||
- (ibuf[27] != cam->params.roi.rowEnd)) {
- LOG("ROI mismatch\n");
- mutex_unlock(&cam->param_lock);
- return -1;
- }
- cols = 8*(ibuf[25] - ibuf[24]);
- rows = 4*(ibuf[27] - ibuf[26]);
-
-
- if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
- LOG("illegal compression %d\n",ibuf[28]);
- mutex_unlock(&cam->param_lock);
- return -1;
- }
- compressed = (ibuf[28] == COMPRESSED);
-
- if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) {
- LOG("illegal decimation %d\n",ibuf[29]);
- mutex_unlock(&cam->param_lock);
- return -1;
- }
- decimation = (ibuf[29] == DECIMATION_ENAB);
-
- cam->params.yuvThreshold.yThreshold = ibuf[30];
- cam->params.yuvThreshold.uvThreshold = ibuf[31];
- cam->params.status.systemState = ibuf[32];
- cam->params.status.grabState = ibuf[33];
- cam->params.status.streamState = ibuf[34];
- cam->params.status.fatalError = ibuf[35];
- cam->params.status.cmdError = ibuf[36];
- cam->params.status.debugFlags = ibuf[37];
- cam->params.status.vpStatus = ibuf[38];
- cam->params.status.errorCode = ibuf[39];
- cam->fps = ibuf[41];
- mutex_unlock(&cam->param_lock);
-
- linesize = skipcount(cols, out_fmt);
- ibuf += FRAME_HEADER_SIZE;
- size -= FRAME_HEADER_SIZE;
- ll = ibuf[0] | (ibuf[1] << 8);
- ibuf += 2;
- even_line = 1;
-
- while (size > 0) {
- size -= (ll+2);
- if (size < 0) {
- LOG("Insufficient data in buffer\n");
- return -1;
- }
-
- while (ll > 1) {
- if (!compressed || (compressed && !(*ibuf & 1))) {
- if(subsample_422 || even_line) {
- obuf += yuvconvert(ibuf, obuf, out_fmt,
- in_uyvy, cam->mmap_kludge);
- ibuf += 4;
- ll -= 4;
- } else {
- /* SUBSAMPLE_420 on an odd line */
- obuf += convert420(ibuf, obuf,
- out_fmt, linesize,
- cam->mmap_kludge);
- ibuf += 2;
- ll -= 2;
- }
- } else {
- /*skip compressed interval from previous frame*/
- obuf += skipcount(*ibuf >> 1, out_fmt);
- if (obuf > end_obuf) {
- LOG("Insufficient buffer size\n");
- return -1;
- }
- ++ibuf;
- ll--;
- }
- }
- if (ll == 1) {
- if (*ibuf != EOL) {
- DBG("EOL not found giving up after %d/%d"
- " bytes\n", origsize-size, origsize);
- return -1;
- }
-
- ++ibuf; /* skip over EOL */
-
- if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) &&
- (ibuf[2] == EOI) && (ibuf[3] == EOI)) {
- size -= 4;
- break;
- }
-
- if(decimation) {
- /* skip the odd lines for now */
- obuf += linesize;
- }
-
- if (size > 1) {
- ll = ibuf[0] | (ibuf[1] << 8);
- ibuf += 2; /* skip over line length */
- }
- if(!decimation)
- even_line = !even_line;
- } else {
- LOG("line length was not 1 but %d after %d/%d bytes\n",
- ll, origsize-size, origsize);
- return -1;
- }
- }
-
- if(decimation) {
- /* interpolate odd rows */
- int i, j;
- u8 *prev, *next;
- prev = cam->decompressed_frame.data;
- obuf = prev+linesize;
- next = obuf+linesize;
- for(i=1; i<rows-1; i+=2) {
- for(j=0; j<linesize; ++j) {
- *obuf++ = ((int)*prev++ + *next++) / 2;
- }
- prev += linesize;
- obuf += linesize;
- next += linesize;
- }
- /* last row is odd, just copy previous row */
- memcpy(obuf, prev, linesize);
- }
-
- cam->decompressed_frame.count = obuf-cam->decompressed_frame.data;
-
- return cam->decompressed_frame.count;
-}
-
-/* InitStreamCap wrapper to select correct start line */
-static inline int init_stream_cap(struct cam_data *cam)
-{
- return do_command(cam, CPIA_COMMAND_InitStreamCap,
- 0, cam->params.streamStartLine, 0, 0);
-}
-
-
-/* find_over_exposure
- * Finds a suitable value of OverExposure for use with SetFlickerCtrl
- * Some calculation is required because this value changes with the brightness
- * set with SetColourParameters
- *
- * Parameters: Brightness - last brightness value set with SetColourParameters
- *
- * Returns: OverExposure value to use with SetFlickerCtrl
- */
-#define FLICKER_MAX_EXPOSURE 250
-#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
-#define FLICKER_BRIGHTNESS_CONSTANT 59
-static int find_over_exposure(int brightness)
-{
- int MaxAllowableOverExposure, OverExposure;
-
- MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
- FLICKER_BRIGHTNESS_CONSTANT;
-
- if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) {
- OverExposure = MaxAllowableOverExposure;
- } else {
- OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
- }
-
- return OverExposure;
-}
-#undef FLICKER_MAX_EXPOSURE
-#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
-#undef FLICKER_BRIGHTNESS_CONSTANT
-
-/* update various camera modes and settings */
-static void dispatch_commands(struct cam_data *cam)
-{
- mutex_lock(&cam->param_lock);
- if (cam->cmd_queue==COMMAND_NONE) {
- mutex_unlock(&cam->param_lock);
- return;
- }
- DEB_BYTE(cam->cmd_queue);
- DEB_BYTE(cam->cmd_queue>>8);
- if (cam->cmd_queue & COMMAND_SETFORMAT) {
- do_command(cam, CPIA_COMMAND_SetFormat,
- cam->params.format.videoSize,
- cam->params.format.subSample,
- cam->params.format.yuvOrder, 0);
- do_command(cam, CPIA_COMMAND_SetROI,
- cam->params.roi.colStart, cam->params.roi.colEnd,
- cam->params.roi.rowStart, cam->params.roi.rowEnd);
- cam->first_frame = 1;
- }
-
- if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS)
- do_command(cam, CPIA_COMMAND_SetColourParams,
- cam->params.colourParams.brightness,
- cam->params.colourParams.contrast,
- cam->params.colourParams.saturation, 0);
-
- if (cam->cmd_queue & COMMAND_SETAPCOR)
- do_command(cam, CPIA_COMMAND_SetApcor,
- cam->params.apcor.gain1,
- cam->params.apcor.gain2,
- cam->params.apcor.gain4,
- cam->params.apcor.gain8);
-
- if (cam->cmd_queue & COMMAND_SETVLOFFSET)
- do_command(cam, CPIA_COMMAND_SetVLOffset,
- cam->params.vlOffset.gain1,
- cam->params.vlOffset.gain2,
- cam->params.vlOffset.gain4,
- cam->params.vlOffset.gain8);
-
- if (cam->cmd_queue & COMMAND_SETEXPOSURE) {
- do_command_extended(cam, CPIA_COMMAND_SetExposure,
- cam->params.exposure.gainMode,
- 1,
- cam->params.exposure.compMode,
- cam->params.exposure.centreWeight,
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
- if(cam->params.exposure.expMode != 1) {
- do_command_extended(cam, CPIA_COMMAND_SetExposure,
- 0,
- cam->params.exposure.expMode,
- 0, 0,
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- 0, 0, 0, 0);
- }
- }
-
- if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) {
- if (cam->params.colourBalance.balanceMode == 1) {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 1,
- cam->params.colourBalance.redGain,
- cam->params.colourBalance.greenGain,
- cam->params.colourBalance.blueGain);
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
- if (cam->params.colourBalance.balanceMode == 2) {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 2, 0, 0, 0);
- }
- if (cam->params.colourBalance.balanceMode == 3) {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
- }
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET)
- do_command(cam, CPIA_COMMAND_SetCompressionTarget,
- cam->params.compressionTarget.frTargeting,
- cam->params.compressionTarget.targetFR,
- cam->params.compressionTarget.targetQ, 0);
-
- if (cam->cmd_queue & COMMAND_SETYUVTHRESH)
- do_command(cam, CPIA_COMMAND_SetYUVThresh,
- cam->params.yuvThreshold.yThreshold,
- cam->params.yuvThreshold.uvThreshold, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS)
- do_command_extended(cam, CPIA_COMMAND_SetCompressionParams,
- 0, 0, 0, 0,
- cam->params.compressionParams.hysteresis,
- cam->params.compressionParams.threshMax,
- cam->params.compressionParams.smallStep,
- cam->params.compressionParams.largeStep,
- cam->params.compressionParams.decimationHysteresis,
- cam->params.compressionParams.frDiffStepThresh,
- cam->params.compressionParams.qDiffStepThresh,
- cam->params.compressionParams.decimationThreshMod);
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSION)
- do_command(cam, CPIA_COMMAND_SetCompression,
- cam->params.compression.mode,
- cam->params.compression.decimation, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETSENSORFPS)
- do_command(cam, CPIA_COMMAND_SetSensorFPS,
- cam->params.sensorFps.divisor,
- cam->params.sensorFps.baserate, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETFLICKERCTRL)
- do_command(cam, CPIA_COMMAND_SetFlickerCtrl,
- cam->params.flickerControl.flickerMode,
- cam->params.flickerControl.coarseJump,
- abs(cam->params.flickerControl.allowableOverExposure),
- 0);
-
- if (cam->cmd_queue & COMMAND_SETECPTIMING)
- do_command(cam, CPIA_COMMAND_SetECPTiming,
- cam->params.ecpTiming, 0, 0, 0);
-
- if (cam->cmd_queue & COMMAND_PAUSE)
- do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
-
- if (cam->cmd_queue & COMMAND_RESUME)
- init_stream_cap(cam);
-
- if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected)
- {
- int p1 = (cam->params.qx3.bottomlight == 0) << 1;
- int p2 = (cam->params.qx3.toplight == 0) << 3;
- do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0);
- do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0);
- }
-
- cam->cmd_queue = COMMAND_NONE;
- mutex_unlock(&cam->param_lock);
- return;
-}
-
-
-
-static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
- int on)
-{
- /* Everything in here is from the Windows driver */
-#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
- params->version.firmwareRevision == (y))
-/* define for compgain calculation */
-#if 0
-#define COMPGAIN(base, curexp, newexp) \
- (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
-#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
- (u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
-#else
- /* equivalent functions without floating point math */
-#define COMPGAIN(base, curexp, newexp) \
- (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2* newexp)) )
-#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
- (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
-#endif
-
-
- int currentexp = params->exposure.coarseExpLo +
- params->exposure.coarseExpHi*256;
- int startexp;
- if (on) {
- int cj = params->flickerControl.coarseJump;
- params->flickerControl.flickerMode = 1;
- params->flickerControl.disabled = 0;
- if(params->exposure.expMode != 2)
- *command_flags |= COMMAND_SETEXPOSURE;
- params->exposure.expMode = 2;
- currentexp = currentexp << params->exposure.gain;
- params->exposure.gain = 0;
- /* round down current exposure to nearest value */
- startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
- if(startexp < 1)
- startexp = 1;
- startexp = (startexp * cj) - 1;
- if(FIRMWARE_VERSION(1,2))
- while(startexp > MAX_EXP_102)
- startexp -= cj;
- else
- while(startexp > MAX_EXP)
- startexp -= cj;
- params->exposure.coarseExpLo = startexp & 0xff;
- params->exposure.coarseExpHi = startexp >> 8;
- if (currentexp > startexp) {
- if (currentexp > (2 * startexp))
- currentexp = 2 * startexp;
- params->exposure.redComp = COMPGAIN (COMP_RED, currentexp, startexp);
- params->exposure.green1Comp = COMPGAIN (COMP_GREEN1, currentexp, startexp);
- params->exposure.green2Comp = COMPGAIN (COMP_GREEN2, currentexp, startexp);
- params->exposure.blueComp = COMPGAIN (COMP_BLUE, currentexp, startexp);
- } else {
- params->exposure.redComp = COMP_RED;
- params->exposure.green1Comp = COMP_GREEN1;
- params->exposure.green2Comp = COMP_GREEN2;
- params->exposure.blueComp = COMP_BLUE;
- }
- if(FIRMWARE_VERSION(1,2))
- params->exposure.compMode = 0;
- else
- params->exposure.compMode = 1;
-
- params->apcor.gain1 = 0x18;
- params->apcor.gain2 = 0x18;
- params->apcor.gain4 = 0x16;
- params->apcor.gain8 = 0x14;
- *command_flags |= COMMAND_SETAPCOR;
- } else {
- params->flickerControl.flickerMode = 0;
- params->flickerControl.disabled = 1;
- /* Coarse = average of equivalent coarse for each comp channel */
- startexp = EXP_FROM_COMP(COMP_RED, params->exposure.redComp, currentexp);
- startexp += EXP_FROM_COMP(COMP_GREEN1, params->exposure.green1Comp, currentexp);
- startexp += EXP_FROM_COMP(COMP_GREEN2, params->exposure.green2Comp, currentexp);
- startexp += EXP_FROM_COMP(COMP_BLUE, params->exposure.blueComp, currentexp);
- startexp = startexp >> 2;
- while(startexp > MAX_EXP &&
- params->exposure.gain < params->exposure.gainMode-1) {
- startexp = startexp >> 1;
- ++params->exposure.gain;
- }
- if(FIRMWARE_VERSION(1,2) && startexp > MAX_EXP_102)
- startexp = MAX_EXP_102;
- if(startexp > MAX_EXP)
- startexp = MAX_EXP;
- params->exposure.coarseExpLo = startexp&0xff;
- params->exposure.coarseExpHi = startexp >> 8;
- params->exposure.redComp = COMP_RED;
- params->exposure.green1Comp = COMP_GREEN1;
- params->exposure.green2Comp = COMP_GREEN2;
- params->exposure.blueComp = COMP_BLUE;
- params->exposure.compMode = 1;
- *command_flags |= COMMAND_SETEXPOSURE;
- params->apcor.gain1 = 0x18;
- params->apcor.gain2 = 0x16;
- params->apcor.gain4 = 0x24;
- params->apcor.gain8 = 0x34;
- *command_flags |= COMMAND_SETAPCOR;
- }
- params->vlOffset.gain1 = 20;
- params->vlOffset.gain2 = 24;
- params->vlOffset.gain4 = 26;
- params->vlOffset.gain8 = 26;
- *command_flags |= COMMAND_SETVLOFFSET;
-#undef FIRMWARE_VERSION
-#undef EXP_FROM_COMP
-#undef COMPGAIN
-}
-
-#define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \
- cam->params.version.firmwareRevision == (y))
-/* monitor the exposure and adjust the sensor frame rate if needed */
-static void monitor_exposure(struct cam_data *cam)
-{
- u8 exp_acc, bcomp, gain, coarseL, cmd[8], data[8];
- int retval, light_exp, dark_exp, very_dark_exp;
- int old_exposure, new_exposure, framerate;
-
- /* get necessary stats and register settings from camera */
- /* do_command can't handle this, so do it ourselves */
- cmd[0] = CPIA_COMMAND_ReadVPRegs>>8;
- cmd[1] = CPIA_COMMAND_ReadVPRegs&0xff;
- cmd[2] = 30;
- cmd[3] = 4;
- cmd[4] = 9;
- cmd[5] = 8;
- cmd[6] = 8;
- cmd[7] = 0;
- retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
- if (retval) {
- LOG("ReadVPRegs(30,4,9,8) - failed, retval=%d\n",
- retval);
- return;
- }
- exp_acc = data[0];
- bcomp = data[1];
- gain = data[2];
- coarseL = data[3];
-
- mutex_lock(&cam->param_lock);
- light_exp = cam->params.colourParams.brightness +
- TC - 50 + EXP_ACC_LIGHT;
- if(light_exp > 255)
- light_exp = 255;
- dark_exp = cam->params.colourParams.brightness +
- TC - 50 - EXP_ACC_DARK;
- if(dark_exp < 0)
- dark_exp = 0;
- very_dark_exp = dark_exp/2;
-
- old_exposure = cam->params.exposure.coarseExpHi * 256 +
- cam->params.exposure.coarseExpLo;
-
- if(!cam->params.flickerControl.disabled) {
- /* Flicker control on */
- int max_comp = FIRMWARE_VERSION(1,2) ? MAX_COMP : HIGH_COMP_102;
- bcomp += 128; /* decode */
- if(bcomp >= max_comp && exp_acc < dark_exp) {
- /* dark */
- if(exp_acc < very_dark_exp) {
- /* very dark */
- if(cam->exposure_status == EXPOSURE_VERY_DARK)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_VERY_DARK;
- cam->exposure_count = 1;
- }
- } else {
- /* just dark */
- if(cam->exposure_status == EXPOSURE_DARK)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_DARK;
- cam->exposure_count = 1;
- }
- }
- } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
- /* light */
- if(old_exposure <= VERY_LOW_EXP) {
- /* very light */
- if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_VERY_LIGHT;
- cam->exposure_count = 1;
- }
- } else {
- /* just light */
- if(cam->exposure_status == EXPOSURE_LIGHT)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_LIGHT;
- cam->exposure_count = 1;
- }
- }
- } else {
- /* not dark or light */
- cam->exposure_status = EXPOSURE_NORMAL;
- }
- } else {
- /* Flicker control off */
- if(old_exposure >= MAX_EXP && exp_acc < dark_exp) {
- /* dark */
- if(exp_acc < very_dark_exp) {
- /* very dark */
- if(cam->exposure_status == EXPOSURE_VERY_DARK)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_VERY_DARK;
- cam->exposure_count = 1;
- }
- } else {
- /* just dark */
- if(cam->exposure_status == EXPOSURE_DARK)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_DARK;
- cam->exposure_count = 1;
- }
- }
- } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
- /* light */
- if(old_exposure <= VERY_LOW_EXP) {
- /* very light */
- if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_VERY_LIGHT;
- cam->exposure_count = 1;
- }
- } else {
- /* just light */
- if(cam->exposure_status == EXPOSURE_LIGHT)
- ++cam->exposure_count;
- else {
- cam->exposure_status = EXPOSURE_LIGHT;
- cam->exposure_count = 1;
- }
- }
- } else {
- /* not dark or light */
- cam->exposure_status = EXPOSURE_NORMAL;
- }
- }
-
- framerate = cam->fps;
- if(framerate > 30 || framerate < 1)
- framerate = 1;
-
- if(!cam->params.flickerControl.disabled) {
- /* Flicker control on */
- if((cam->exposure_status == EXPOSURE_VERY_DARK ||
- cam->exposure_status == EXPOSURE_DARK) &&
- cam->exposure_count >= DARK_TIME*framerate &&
- cam->params.sensorFps.divisor < 3) {
-
- /* dark for too long */
- ++cam->params.sensorFps.divisor;
- cam->cmd_queue |= COMMAND_SETSENSORFPS;
-
- cam->params.flickerControl.coarseJump =
- flicker_jumps[cam->mainsFreq]
- [cam->params.sensorFps.baserate]
- [cam->params.sensorFps.divisor];
- cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
-
- new_exposure = cam->params.flickerControl.coarseJump-1;
- while(new_exposure < old_exposure/2)
- new_exposure += cam->params.flickerControl.coarseJump;
- cam->params.exposure.coarseExpLo = new_exposure & 0xff;
- cam->params.exposure.coarseExpHi = new_exposure >> 8;
- cam->cmd_queue |= COMMAND_SETEXPOSURE;
- cam->exposure_status = EXPOSURE_NORMAL;
- LOG("Automatically decreasing sensor_fps\n");
-
- } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
- cam->exposure_status == EXPOSURE_LIGHT) &&
- cam->exposure_count >= LIGHT_TIME*framerate &&
- cam->params.sensorFps.divisor > 0) {
-
- /* light for too long */
- int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ;
-
- --cam->params.sensorFps.divisor;
- cam->cmd_queue |= COMMAND_SETSENSORFPS;
-
- cam->params.flickerControl.coarseJump =
- flicker_jumps[cam->mainsFreq]
- [cam->params.sensorFps.baserate]
- [cam->params.sensorFps.divisor];
- cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
-
- new_exposure = cam->params.flickerControl.coarseJump-1;
- while(new_exposure < 2*old_exposure &&
- new_exposure+
- cam->params.flickerControl.coarseJump < max_exp)
- new_exposure += cam->params.flickerControl.coarseJump;
- cam->params.exposure.coarseExpLo = new_exposure & 0xff;
- cam->params.exposure.coarseExpHi = new_exposure >> 8;
- cam->cmd_queue |= COMMAND_SETEXPOSURE;
- cam->exposure_status = EXPOSURE_NORMAL;
- LOG("Automatically increasing sensor_fps\n");
- }
- } else {
- /* Flicker control off */
- if((cam->exposure_status == EXPOSURE_VERY_DARK ||
- cam->exposure_status == EXPOSURE_DARK) &&
- cam->exposure_count >= DARK_TIME*framerate &&
- cam->params.sensorFps.divisor < 3) {
-
- /* dark for too long */
- ++cam->params.sensorFps.divisor;
- cam->cmd_queue |= COMMAND_SETSENSORFPS;
-
- if(cam->params.exposure.gain > 0) {
- --cam->params.exposure.gain;
- cam->cmd_queue |= COMMAND_SETEXPOSURE;
- }
- cam->exposure_status = EXPOSURE_NORMAL;
- LOG("Automatically decreasing sensor_fps\n");
-
- } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
- cam->exposure_status == EXPOSURE_LIGHT) &&
- cam->exposure_count >= LIGHT_TIME*framerate &&
- cam->params.sensorFps.divisor > 0) {
-
- /* light for too long */
- --cam->params.sensorFps.divisor;
- cam->cmd_queue |= COMMAND_SETSENSORFPS;
-
- if(cam->params.exposure.gain <
- cam->params.exposure.gainMode-1) {
- ++cam->params.exposure.gain;
- cam->cmd_queue |= COMMAND_SETEXPOSURE;
- }
- cam->exposure_status = EXPOSURE_NORMAL;
- LOG("Automatically increasing sensor_fps\n");
- }
- }
- mutex_unlock(&cam->param_lock);
-}
-
-/*-----------------------------------------------------------------*/
-/* if flicker is switched off, this function switches it back on.It checks,
- however, that conditions are suitable before restarting it.
- This should only be called for firmware version 1.2.
-
- It also adjust the colour balance when an exposure step is detected - as
- long as flicker is running
-*/
-static void restart_flicker(struct cam_data *cam)
-{
- int cam_exposure, old_exp;
- if(!FIRMWARE_VERSION(1,2))
- return;
- mutex_lock(&cam->param_lock);
- if(cam->params.flickerControl.flickerMode == 0 ||
- cam->raw_image[39] == 0) {
- mutex_unlock(&cam->param_lock);
- return;
- }
- cam_exposure = cam->raw_image[39]*2;
- old_exp = cam->params.exposure.coarseExpLo +
- cam->params.exposure.coarseExpHi*256;
- /*
- see how far away camera exposure is from a valid
- flicker exposure value
- */
- cam_exposure %= cam->params.flickerControl.coarseJump;
- if(!cam->params.flickerControl.disabled &&
- cam_exposure <= cam->params.flickerControl.coarseJump - 3) {
- /* Flicker control auto-disabled */
- cam->params.flickerControl.disabled = 1;
- }
-
- if(cam->params.flickerControl.disabled &&
- cam->params.flickerControl.flickerMode &&
- old_exp > cam->params.flickerControl.coarseJump +
- ROUND_UP_EXP_FOR_FLICKER) {
- /* exposure is now high enough to switch
- flicker control back on */
- set_flicker(&cam->params, &cam->cmd_queue, 1);
- if((cam->cmd_queue & COMMAND_SETEXPOSURE) &&
- cam->params.exposure.expMode == 2)
- cam->exposure_status = EXPOSURE_NORMAL;
-
- }
- mutex_unlock(&cam->param_lock);
-}
-#undef FIRMWARE_VERSION
-
-static int clear_stall(struct cam_data *cam)
-{
- /* FIXME: Does this actually work? */
- LOG("Clearing stall\n");
-
- cam->ops->streamRead(cam->lowlevel_data, cam->raw_image, 0);
- do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
- return cam->params.status.streamState != STREAM_PAUSED;
-}
-
-/* kernel thread function to read image from camera */
-static int fetch_frame(void *data)
-{
- int image_size, retry;
- struct cam_data *cam = (struct cam_data *)data;
- unsigned long oldjif, rate, diff;
-
- /* Allow up to two bad images in a row to be read and
- * ignored before an error is reported */
- for (retry = 0; retry < 3; ++retry) {
- if (retry)
- DBG("retry=%d\n", retry);
-
- if (!cam->ops)
- continue;
-
- /* load first frame always uncompressed */
- if (cam->first_frame &&
- cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
- do_command(cam, CPIA_COMMAND_SetCompression,
- CPIA_COMPRESSION_NONE,
- NO_DECIMATION, 0, 0);
- /* Trial & error - Discarding a frame prevents the
- first frame from having an error in the data. */
- do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
- }
-
- /* init camera upload */
- if (do_command(cam, CPIA_COMMAND_GrabFrame, 0,
- cam->params.streamStartLine, 0, 0))
- continue;
-
- if (cam->ops->wait_for_stream_ready) {
- /* loop until image ready */
- int count = 0;
- do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
- while (cam->params.status.streamState != STREAM_READY) {
- if(++count > READY_TIMEOUT)
- break;
- if(cam->params.status.streamState ==
- STREAM_PAUSED) {
- /* Bad news */
- if(!clear_stall(cam))
- return -EIO;
- }
-
- cond_resched();
-
- /* sleep for 10 ms, hopefully ;) */
- msleep_interruptible(10);
- if (signal_pending(current))
- return -EINTR;
-
- do_command(cam, CPIA_COMMAND_GetCameraStatus,
- 0, 0, 0, 0);
- }
- if(cam->params.status.streamState != STREAM_READY) {
- continue;
- }
- }
-
- cond_resched();
-
- /* grab image from camera */
- oldjif = jiffies;
- image_size = cam->ops->streamRead(cam->lowlevel_data,
- cam->raw_image, 0);
- if (image_size <= 0) {
- DBG("streamRead failed: %d\n", image_size);
- continue;
- }
-
- rate = image_size * HZ / 1024;
- diff = jiffies-oldjif;
- cam->transfer_rate = diff==0 ? rate : rate/diff;
- /* diff==0 ? unlikely but possible */
-
- /* Switch flicker control back on if it got turned off */
- restart_flicker(cam);
-
- /* If AEC is enabled, monitor the exposure and
- adjust the sensor frame rate if needed */
- if(cam->params.exposure.expMode == 2)
- monitor_exposure(cam);
-
- /* camera idle now so dispatch queued commands */
- dispatch_commands(cam);
-
- /* Update our knowledge of the camera state */
- do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
- do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
- do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
-
- /* decompress and convert image to by copying it from
- * raw_image to decompressed_frame
- */
-
- cond_resched();
-
- cam->image_size = parse_picture(cam, image_size);
- if (cam->image_size <= 0) {
- DBG("parse_picture failed %d\n", cam->image_size);
- if(cam->params.compression.mode !=
- CPIA_COMPRESSION_NONE) {
- /* Compression may not work right if we
- had a bad frame, get the next one
- uncompressed. */
- cam->first_frame = 1;
- do_command(cam, CPIA_COMMAND_SetGrabMode,
- CPIA_GRAB_SINGLE, 0, 0, 0);
- /* FIXME: Trial & error - need up to 70ms for
- the grab mode change to complete ? */
- msleep_interruptible(70);
- if (signal_pending(current))
- return -EINTR;
- }
- } else
- break;
- }
-
- if (retry < 3) {
- /* FIXME: this only works for double buffering */
- if (cam->frame[cam->curframe].state == FRAME_READY) {
- memcpy(cam->frame[cam->curframe].data,
- cam->decompressed_frame.data,
- cam->decompressed_frame.count);
- cam->frame[cam->curframe].state = FRAME_DONE;
- } else
- cam->decompressed_frame.state = FRAME_DONE;
-
- if (cam->first_frame) {
- cam->first_frame = 0;
- do_command(cam, CPIA_COMMAND_SetCompression,
- cam->params.compression.mode,
- cam->params.compression.decimation, 0, 0);
-
- /* Switch from single-grab to continuous grab */
- do_command(cam, CPIA_COMMAND_SetGrabMode,
- CPIA_GRAB_CONTINUOUS, 0, 0, 0);
- }
- return 0;
- }
- return -EIO;
-}
-
-static int capture_frame(struct cam_data *cam, struct video_mmap *vm)
-{
- if (!cam->frame_buf) {
- /* we do lazy allocation */
- int err;
- if ((err = allocate_frame_buf(cam)))
- return err;
- }
-
- cam->curframe = vm->frame;
- cam->frame[cam->curframe].state = FRAME_READY;
- return fetch_frame(cam);
-}
-
-static int goto_high_power(struct cam_data *cam)
-{
- if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0))
- return -EIO;
- msleep_interruptible(40); /* windows driver does it too */
- if(signal_pending(current))
- return -EINTR;
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -EIO;
- if (cam->params.status.systemState == HI_POWER_STATE) {
- DBG("camera now in HIGH power state\n");
- return 0;
- }
- printstatus(cam);
- return -EIO;
-}
-
-static int goto_low_power(struct cam_data *cam)
-{
- if (do_command(cam, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0))
- return -1;
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -1;
- if (cam->params.status.systemState == LO_POWER_STATE) {
- DBG("camera now in LOW power state\n");
- return 0;
- }
- printstatus(cam);
- return -1;
-}
-
-static void save_camera_state(struct cam_data *cam)
-{
- if(!(cam->cmd_queue & COMMAND_SETCOLOURBALANCE))
- do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
- if(!(cam->cmd_queue & COMMAND_SETEXPOSURE))
- do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
-
- DBG("%d/%d/%d/%d/%d/%d/%d/%d\n",
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
- DBG("%d/%d/%d\n",
- cam->params.colourBalance.redGain,
- cam->params.colourBalance.greenGain,
- cam->params.colourBalance.blueGain);
-}
-
-static int set_camera_state(struct cam_data *cam)
-{
- cam->cmd_queue = COMMAND_SETCOMPRESSION |
- COMMAND_SETCOMPRESSIONTARGET |
- COMMAND_SETCOLOURPARAMS |
- COMMAND_SETFORMAT |
- COMMAND_SETYUVTHRESH |
- COMMAND_SETECPTIMING |
- COMMAND_SETCOMPRESSIONPARAMS |
- COMMAND_SETEXPOSURE |
- COMMAND_SETCOLOURBALANCE |
- COMMAND_SETSENSORFPS |
- COMMAND_SETAPCOR |
- COMMAND_SETFLICKERCTRL |
- COMMAND_SETVLOFFSET;
-
- do_command(cam, CPIA_COMMAND_SetGrabMode, CPIA_GRAB_SINGLE,0,0,0);
- dispatch_commands(cam);
-
- /* Wait 6 frames for the sensor to get all settings and
- AEC/ACB to settle */
- msleep_interruptible(6*(cam->params.sensorFps.baserate ? 33 : 40) *
- (1 << cam->params.sensorFps.divisor) + 10);
-
- if(signal_pending(current))
- return -EINTR;
-
- save_camera_state(cam);
-
- return 0;
-}
-
-static void get_version_information(struct cam_data *cam)
-{
- /* GetCPIAVersion */
- do_command(cam, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
-
- /* GetPnPID */
- do_command(cam, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
-}
-
-/* initialize camera */
-static int reset_camera(struct cam_data *cam)
-{
- int err;
- /* Start the camera in low power mode */
- if (goto_low_power(cam)) {
- if (cam->params.status.systemState != WARM_BOOT_STATE)
- return -ENODEV;
-
- /* FIXME: this is just dirty trial and error */
- err = goto_high_power(cam);
- if(err)
- return err;
- do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
- if (goto_low_power(cam))
- return -ENODEV;
- }
-
- /* procedure described in developer's guide p3-28 */
-
- /* Check the firmware version. */
- cam->params.version.firmwareVersion = 0;
- get_version_information(cam);
- if (cam->params.version.firmwareVersion != 1)
- return -ENODEV;
-
- /* A bug in firmware 1-02 limits gainMode to 2 */
- if(cam->params.version.firmwareRevision <= 2 &&
- cam->params.exposure.gainMode > 2) {
- cam->params.exposure.gainMode = 2;
- }
-
- /* set QX3 detected flag */
- cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 &&
- cam->params.pnpID.product == 0x0001);
-
- /* The fatal error checking should be done after
- * the camera powers up (developer's guide p 3-38) */
-
- /* Set streamState before transition to high power to avoid bug
- * in firmware 1-02 */
- do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0,
- STREAM_NOT_READY, 0);
-
- /* GotoHiPower */
- err = goto_high_power(cam);
- if (err)
- return err;
-
- /* Check the camera status */
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -EIO;
-
- if (cam->params.status.fatalError) {
- DBG("fatal_error: %#04x\n",
- cam->params.status.fatalError);
- DBG("vp_status: %#04x\n",
- cam->params.status.vpStatus);
- if (cam->params.status.fatalError & ~(COM_FLAG|CPIA_FLAG)) {
- /* Fatal error in camera */
- return -EIO;
- } else if (cam->params.status.fatalError & (COM_FLAG|CPIA_FLAG)) {
- /* Firmware 1-02 may do this for parallel port cameras,
- * just clear the flags (developer's guide p 3-38) */
- do_command(cam, CPIA_COMMAND_ModifyCameraStatus,
- FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0);
- }
- }
-
- /* Check the camera status again */
- if (cam->params.status.fatalError) {
- if (cam->params.status.fatalError)
- return -EIO;
- }
-
- /* VPVersion can't be retrieved before the camera is in HiPower,
- * so get it here instead of in get_version_information. */
- do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
-
- /* set camera to a known state */
- return set_camera_state(cam);
-}
-
-static void put_cam(struct cpia_camera_ops* ops)
-{
- module_put(ops->owner);
-}
-
-/* ------------------------- V4L interface --------------------- */
-static int cpia_open(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- struct cam_data *cam = video_get_drvdata(dev);
- int err;
-
- if (!cam) {
- DBG("Internal error, cam_data not found!\n");
- return -ENODEV;
- }
-
- if (cam->open_count > 0) {
- DBG("Camera already open\n");
- return -EBUSY;
- }
-
- if (!try_module_get(cam->ops->owner))
- return -ENODEV;
-
- mutex_lock(&cam->busy_lock);
- err = -ENOMEM;
- if (!cam->raw_image) {
- cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
- if (!cam->raw_image)
- goto oops;
- }
-
- if (!cam->decompressed_frame.data) {
- cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE);
- if (!cam->decompressed_frame.data)
- goto oops;
- }
-
- /* open cpia */
- err = -ENODEV;
- if (cam->ops->open(cam->lowlevel_data))
- goto oops;
-
- /* reset the camera */
- if ((err = reset_camera(cam)) != 0) {
- cam->ops->close(cam->lowlevel_data);
- goto oops;
- }
-
- /* Set ownership of /proc/cpia/videoX to current user */
- if(cam->proc_entry)
- cam->proc_entry->uid = current_euid();
-
- /* set mark for loading first frame uncompressed */
- cam->first_frame = 1;
-
- /* init it to something */
- cam->mmap_kludge = 0;
-
- ++cam->open_count;
- file->private_data = dev;
- mutex_unlock(&cam->busy_lock);
- return 0;
-
- oops:
- if (cam->decompressed_frame.data) {
- rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
- cam->decompressed_frame.data = NULL;
- }
- if (cam->raw_image) {
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- }
- mutex_unlock(&cam->busy_lock);
- put_cam(cam->ops);
- return err;
-}
-
-static int cpia_close(struct file *file)
-{
- struct video_device *dev = file->private_data;
- struct cam_data *cam = video_get_drvdata(dev);
-
- if (cam->ops) {
- /* Return ownership of /proc/cpia/videoX to root */
- if(cam->proc_entry)
- cam->proc_entry->uid = 0;
-
- /* save camera state for later open (developers guide ch 3.5.3) */
- save_camera_state(cam);
-
- /* GotoLoPower */
- goto_low_power(cam);
-
- /* Update the camera status */
- do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
-
- /* cleanup internal state stuff */
- free_frames(cam->frame);
-
- /* close cpia */
- cam->ops->close(cam->lowlevel_data);
-
- put_cam(cam->ops);
- }
-
- if (--cam->open_count == 0) {
- /* clean up capture-buffers */
- if (cam->raw_image) {
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- }
-
- if (cam->decompressed_frame.data) {
- rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
- cam->decompressed_frame.data = NULL;
- }
-
- if (cam->frame_buf)
- free_frame_buf(cam);
-
- if (!cam->ops)
- kfree(cam);
- }
- file->private_data = NULL;
-
- return 0;
-}
-
-static ssize_t cpia_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *dev = file->private_data;
- struct cam_data *cam = video_get_drvdata(dev);
- int err;
-
- /* make this _really_ smp and multithread-safe */
- if (mutex_lock_interruptible(&cam->busy_lock))
- return -EINTR;
-
- if (!buf) {
- DBG("buf NULL\n");
- mutex_unlock(&cam->busy_lock);
- return -EINVAL;
- }
-
- if (!count) {
- DBG("count 0\n");
- mutex_unlock(&cam->busy_lock);
- return 0;
- }
-
- if (!cam->ops) {
- DBG("ops NULL\n");
- mutex_unlock(&cam->busy_lock);
- return -ENODEV;
- }
-
- /* upload frame */
- cam->decompressed_frame.state = FRAME_READY;
- cam->mmap_kludge=0;
- if((err = fetch_frame(cam)) != 0) {
- DBG("ERROR from fetch_frame: %d\n", err);
- mutex_unlock(&cam->busy_lock);
- return err;
- }
- cam->decompressed_frame.state = FRAME_UNUSED;
-
- /* copy data to user space */
- if (cam->decompressed_frame.count > count) {
- DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
- (unsigned long) count);
- mutex_unlock(&cam->busy_lock);
- return -EFAULT;
- }
- if (copy_to_user(buf, cam->decompressed_frame.data,
- cam->decompressed_frame.count)) {
- DBG("copy_to_user failed\n");
- mutex_unlock(&cam->busy_lock);
- return -EFAULT;
- }
-
- mutex_unlock(&cam->busy_lock);
- return cam->decompressed_frame.count;
-}
-
-static long cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct video_device *dev = file->private_data;
- struct cam_data *cam = video_get_drvdata(dev);
- int retval = 0;
-
- if (!cam || !cam->ops)
- return -ENODEV;
-
- /* make this _really_ smp-safe */
- if (mutex_lock_interruptible(&cam->busy_lock))
- return -EINTR;
-
- /* DBG("cpia_ioctl: %u\n", cmd); */
-
- switch (cmd) {
- /* query capabilities */
- case VIDIOCGCAP:
- {
- struct video_capability *b = arg;
-
- DBG("VIDIOCGCAP\n");
- strcpy(b->name, "CPiA Camera");
- b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
- b->channels = 1;
- b->audios = 0;
- b->maxwidth = 352; /* VIDEOSIZE_CIF */
- b->maxheight = 288;
- b->minwidth = 48; /* VIDEOSIZE_48_48 */
- b->minheight = 48;
- break;
- }
-
- /* get/set video source - we are a camera and nothing else */
- case VIDIOCGCHAN:
- {
- struct video_channel *v = arg;
-
- DBG("VIDIOCGCHAN\n");
- if (v->channel != 0) {
- retval = -EINVAL;
- break;
- }
-
- v->channel = 0;
- strcpy(v->name, "Camera");
- v->tuners = 0;
- v->flags = 0;
- v->type = VIDEO_TYPE_CAMERA;
- v->norm = 0;
- break;
- }
-
- case VIDIOCSCHAN:
- {
- struct video_channel *v = arg;
-
- DBG("VIDIOCSCHAN\n");
- if (v->channel != 0)
- retval = -EINVAL;
- break;
- }
-
- /* image properties */
- case VIDIOCGPICT:
- {
- struct video_picture *pic = arg;
- DBG("VIDIOCGPICT\n");
- *pic = cam->vp;
- break;
- }
-
- case VIDIOCSPICT:
- {
- struct video_picture *vp = arg;
-
- DBG("VIDIOCSPICT\n");
-
- /* check validity */
- DBG("palette: %d\n", vp->palette);
- DBG("depth: %d\n", vp->depth);
- if (!valid_mode(vp->palette, vp->depth)) {
- retval = -EINVAL;
- break;
- }
-
- mutex_lock(&cam->param_lock);
- /* brightness, colour, contrast need no check 0-65535 */
- cam->vp = *vp;
- /* update cam->params.colourParams */
- cam->params.colourParams.brightness = vp->brightness*100/65535;
- cam->params.colourParams.contrast = vp->contrast*100/65535;
- cam->params.colourParams.saturation = vp->colour*100/65535;
- /* contrast is in steps of 8, so round */
- cam->params.colourParams.contrast =
- ((cam->params.colourParams.contrast + 3) / 8) * 8;
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2 &&
- cam->params.colourParams.contrast > 80) {
- /* 1-02 firmware limits contrast to 80 */
- cam->params.colourParams.contrast = 80;
- }
-
- /* Adjust flicker control if necessary */
- if(cam->params.flickerControl.allowableOverExposure < 0)
- cam->params.flickerControl.allowableOverExposure =
- -find_over_exposure(cam->params.colourParams.brightness);
- if(cam->params.flickerControl.flickerMode != 0)
- cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
-
-
- /* queue command to update camera */
- cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
- mutex_unlock(&cam->param_lock);
- DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
- vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour,
- vp->contrast);
- break;
- }
-
- /* get/set capture window */
- case VIDIOCGWIN:
- {
- struct video_window *vw = arg;
- DBG("VIDIOCGWIN\n");
-
- *vw = cam->vw;
- break;
- }
-
- case VIDIOCSWIN:
- {
- /* copy_from_user, check validity, copy to internal structure */
- struct video_window *vw = arg;
- DBG("VIDIOCSWIN\n");
-
- if (vw->clipcount != 0) { /* clipping not supported */
- retval = -EINVAL;
- break;
- }
- if (vw->clips != NULL) { /* clipping not supported */
- retval = -EINVAL;
- break;
- }
-
- /* we set the video window to something smaller or equal to what
- * is requested by the user???
- */
- mutex_lock(&cam->param_lock);
- if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
- int video_size = match_videosize(vw->width, vw->height);
-
- if (video_size < 0) {
- retval = -EINVAL;
- mutex_unlock(&cam->param_lock);
- break;
- }
- cam->video_size = video_size;
-
- /* video size is changing, reset the subcapture area */
- memset(&cam->vc, 0, sizeof(cam->vc));
-
- set_vw_size(cam);
- DBG("%d / %d\n", cam->vw.width, cam->vw.height);
- cam->cmd_queue |= COMMAND_SETFORMAT;
- }
-
- mutex_unlock(&cam->param_lock);
-
- /* setformat ignored by camera during streaming,
- * so stop/dispatch/start */
- if (cam->cmd_queue & COMMAND_SETFORMAT) {
- DBG("\n");
- dispatch_commands(cam);
- }
- DBG("%d/%d:%d\n", cam->video_size,
- cam->vw.width, cam->vw.height);
- break;
- }
-
- /* mmap interface */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *vm = arg;
- int i;
-
- DBG("VIDIOCGMBUF\n");
- memset(vm, 0, sizeof(*vm));
- vm->size = CPIA_MAX_FRAME_SIZE*FRAME_NUM;
- vm->frames = FRAME_NUM;
- for (i = 0; i < FRAME_NUM; i++)
- vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i;
- break;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap *vm = arg;
- int video_size;
-
- DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame,
- vm->width, vm->height);
- if (vm->frame<0||vm->frame>=FRAME_NUM) {
- retval = -EINVAL;
- break;
- }
-
- /* set video format */
- cam->vp.palette = vm->format;
- switch(vm->format) {
- case VIDEO_PALETTE_GREY:
- cam->vp.depth=8;
- break;
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- case VIDEO_PALETTE_UYVY:
- cam->vp.depth = 16;
- break;
- case VIDEO_PALETTE_RGB24:
- cam->vp.depth = 24;
- break;
- case VIDEO_PALETTE_RGB32:
- cam->vp.depth = 32;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- if (retval)
- break;
-
- /* set video size */
- video_size = match_videosize(vm->width, vm->height);
- if (video_size < 0) {
- retval = -EINVAL;
- break;
- }
- if (video_size != cam->video_size) {
- cam->video_size = video_size;
-
- /* video size is changing, reset the subcapture area */
- memset(&cam->vc, 0, sizeof(cam->vc));
-
- set_vw_size(cam);
- cam->cmd_queue |= COMMAND_SETFORMAT;
- dispatch_commands(cam);
- }
- /* according to v4l-spec we must start streaming here */
- cam->mmap_kludge = 1;
- retval = capture_frame(cam, vm);
-
- break;
- }
-
- case VIDIOCSYNC:
- {
- int *frame = arg;
-
- //DBG("VIDIOCSYNC: %d\n", *frame);
-
- if (*frame<0 || *frame >= FRAME_NUM) {
- retval = -EINVAL;
- break;
- }
-
- switch (cam->frame[*frame].state) {
- case FRAME_UNUSED:
- case FRAME_READY:
- case FRAME_GRABBING:
- DBG("sync to unused frame %d\n", *frame);
- retval = -EINVAL;
- break;
-
- case FRAME_DONE:
- cam->frame[*frame].state = FRAME_UNUSED;
- //DBG("VIDIOCSYNC: %d synced\n", *frame);
- break;
- }
- if (retval == -EINTR) {
- /* FIXME - xawtv does not handle this nice */
- retval = 0;
- }
- break;
- }
-
- case VIDIOCGCAPTURE:
- {
- struct video_capture *vc = arg;
-
- DBG("VIDIOCGCAPTURE\n");
-
- *vc = cam->vc;
-
- break;
- }
-
- case VIDIOCSCAPTURE:
- {
- struct video_capture *vc = arg;
-
- DBG("VIDIOCSCAPTURE\n");
-
- if (vc->decimation != 0) { /* How should this be used? */
- retval = -EINVAL;
- break;
- }
- if (vc->flags != 0) { /* Even/odd grab not supported */
- retval = -EINVAL;
- break;
- }
-
- /* Clip to the resolution we can set for the ROI
- (every 8 columns and 4 rows) */
- vc->x = vc->x & ~(__u32)7;
- vc->y = vc->y & ~(__u32)3;
- vc->width = vc->width & ~(__u32)7;
- vc->height = vc->height & ~(__u32)3;
-
- if(vc->width == 0 || vc->height == 0 ||
- vc->x + vc->width > cam->vw.width ||
- vc->y + vc->height > cam->vw.height) {
- retval = -EINVAL;
- break;
- }
-
- DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
-
- mutex_lock(&cam->param_lock);
-
- cam->vc.x = vc->x;
- cam->vc.y = vc->y;
- cam->vc.width = vc->width;
- cam->vc.height = vc->height;
-
- set_vw_size(cam);
- cam->cmd_queue |= COMMAND_SETFORMAT;
-
- mutex_unlock(&cam->param_lock);
-
- /* setformat ignored by camera during streaming,
- * so stop/dispatch/start */
- dispatch_commands(cam);
- break;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit *vu = arg;
-
- DBG("VIDIOCGUNIT\n");
-
- vu->video = cam->vdev.minor;
- vu->vbi = VIDEO_NO_UNIT;
- vu->radio = VIDEO_NO_UNIT;
- vu->audio = VIDEO_NO_UNIT;
- vu->teletext = VIDEO_NO_UNIT;
-
- break;
- }
-
-
- /* pointless to implement overlay with this camera */
- case VIDIOCCAPTURE:
- case VIDIOCGFBUF:
- case VIDIOCSFBUF:
- case VIDIOCKEY:
- /* tuner interface - we have none */
- case VIDIOCGTUNER:
- case VIDIOCSTUNER:
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- /* audio interface - we have none */
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- retval = -EINVAL;
- break;
- default:
- retval = -ENOIOCTLCMD;
- break;
- }
-
- mutex_unlock(&cam->busy_lock);
- return retval;
-}
-
-static long cpia_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, cpia_do_ioctl);
-}
-
-
-/* FIXME */
-static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *dev = file->private_data;
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long page, pos;
- struct cam_data *cam = video_get_drvdata(dev);
- int retval;
-
- if (!cam || !cam->ops)
- return -ENODEV;
-
- DBG("cpia_mmap: %ld\n", size);
-
- if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
- return -EINVAL;
-
- /* make this _really_ smp-safe */
- if (mutex_lock_interruptible(&cam->busy_lock))
- return -EINTR;
-
- if (!cam->frame_buf) { /* we do lazy allocation */
- if ((retval = allocate_frame_buf(cam))) {
- mutex_unlock(&cam->busy_lock);
- return retval;
- }
- }
-
- pos = (unsigned long)(cam->frame_buf);
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- mutex_unlock(&cam->busy_lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- DBG("cpia_mmap: %ld\n", size);
- mutex_unlock(&cam->busy_lock);
-
- return 0;
-}
-
-static const struct v4l2_file_operations cpia_fops = {
- .owner = THIS_MODULE,
- .open = cpia_open,
- .release = cpia_close,
- .read = cpia_read,
- .mmap = cpia_mmap,
- .ioctl = cpia_ioctl,
-};
-
-static struct video_device cpia_template = {
- .name = "CPiA Camera",
- .fops = &cpia_fops,
- .release = video_device_release_empty,
-};
-
-/* initialise cam_data structure */
-static void reset_camera_struct(struct cam_data *cam)
-{
- /* The following parameter values are the defaults from
- * "Software Developer's Guide for CPiA Cameras". Any changes
- * to the defaults are noted in comments. */
- cam->params.colourParams.brightness = 50;
- cam->params.colourParams.contrast = 48;
- cam->params.colourParams.saturation = 50;
- cam->params.exposure.gainMode = 4;
- cam->params.exposure.expMode = 2; /* AEC */
- cam->params.exposure.compMode = 1;
- cam->params.exposure.centreWeight = 1;
- cam->params.exposure.gain = 0;
- cam->params.exposure.fineExp = 0;
- cam->params.exposure.coarseExpLo = 185;
- cam->params.exposure.coarseExpHi = 0;
- cam->params.exposure.redComp = COMP_RED;
- cam->params.exposure.green1Comp = COMP_GREEN1;
- cam->params.exposure.green2Comp = COMP_GREEN2;
- cam->params.exposure.blueComp = COMP_BLUE;
- cam->params.colourBalance.balanceMode = 2; /* ACB */
- cam->params.colourBalance.redGain = 32;
- cam->params.colourBalance.greenGain = 6;
- cam->params.colourBalance.blueGain = 92;
- cam->params.apcor.gain1 = 0x18;
- cam->params.apcor.gain2 = 0x16;
- cam->params.apcor.gain4 = 0x24;
- cam->params.apcor.gain8 = 0x34;
- cam->params.flickerControl.flickerMode = 0;
- cam->params.flickerControl.disabled = 1;
-
- cam->params.flickerControl.coarseJump =
- flicker_jumps[cam->mainsFreq]
- [cam->params.sensorFps.baserate]
- [cam->params.sensorFps.divisor];
- cam->params.flickerControl.allowableOverExposure =
- -find_over_exposure(cam->params.colourParams.brightness);
- cam->params.vlOffset.gain1 = 20;
- cam->params.vlOffset.gain2 = 24;
- cam->params.vlOffset.gain4 = 26;
- cam->params.vlOffset.gain8 = 26;
- cam->params.compressionParams.hysteresis = 3;
- cam->params.compressionParams.threshMax = 11;
- cam->params.compressionParams.smallStep = 1;
- cam->params.compressionParams.largeStep = 3;
- cam->params.compressionParams.decimationHysteresis = 2;
- cam->params.compressionParams.frDiffStepThresh = 5;
- cam->params.compressionParams.qDiffStepThresh = 3;
- cam->params.compressionParams.decimationThreshMod = 2;
- /* End of default values from Software Developer's Guide */
-
- cam->transfer_rate = 0;
- cam->exposure_status = EXPOSURE_NORMAL;
-
- /* Set Sensor FPS to 15fps. This seems better than 30fps
- * for indoor lighting. */
- cam->params.sensorFps.divisor = 1;
- cam->params.sensorFps.baserate = 1;
-
- cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */
- cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */
-
- cam->params.format.subSample = SUBSAMPLE_422;
- cam->params.format.yuvOrder = YUVORDER_YUYV;
-
- cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
- cam->params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_QUALITY;
- cam->params.compressionTarget.targetFR = 15; /* From windows driver */
- cam->params.compressionTarget.targetQ = 5; /* From windows driver */
-
- cam->params.qx3.qx3_detected = 0;
- cam->params.qx3.toplight = 0;
- cam->params.qx3.bottomlight = 0;
- cam->params.qx3.button = 0;
- cam->params.qx3.cradled = 0;
-
- cam->video_size = VIDEOSIZE_CIF;
-
- cam->vp.colour = 32768; /* 50% */
- cam->vp.hue = 32768; /* 50% */
- cam->vp.brightness = 32768; /* 50% */
- cam->vp.contrast = 32768; /* 50% */
- cam->vp.whiteness = 0; /* not used -> grayscale only */
- cam->vp.depth = 24; /* to be set by user */
- cam->vp.palette = VIDEO_PALETTE_RGB24; /* to be set by user */
-
- cam->vc.x = 0;
- cam->vc.y = 0;
- cam->vc.width = 0;
- cam->vc.height = 0;
-
- cam->vw.x = 0;
- cam->vw.y = 0;
- set_vw_size(cam);
- cam->vw.chromakey = 0;
- cam->vw.flags = 0;
- cam->vw.clipcount = 0;
- cam->vw.clips = NULL;
-
- cam->cmd_queue = COMMAND_NONE;
- cam->first_frame = 1;
-
- return;
-}
-
-/* initialize cam_data structure */
-static void init_camera_struct(struct cam_data *cam,
- struct cpia_camera_ops *ops )
-{
- int i;
-
- /* Default everything to 0 */
- memset(cam, 0, sizeof(struct cam_data));
-
- cam->ops = ops;
- mutex_init(&cam->param_lock);
- mutex_init(&cam->busy_lock);
-
- reset_camera_struct(cam);
-
- cam->proc_entry = NULL;
-
- memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template));
- video_set_drvdata(&cam->vdev, cam);
-
- cam->curframe = 0;
- for (i = 0; i < FRAME_NUM; i++) {
- cam->frame[i].width = 0;
- cam->frame[i].height = 0;
- cam->frame[i].state = FRAME_UNUSED;
- cam->frame[i].data = NULL;
- }
- cam->decompressed_frame.width = 0;
- cam->decompressed_frame.height = 0;
- cam->decompressed_frame.state = FRAME_UNUSED;
- cam->decompressed_frame.data = NULL;
-}
-
-struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel)
-{
- struct cam_data *camera;
-
- if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL)
- return NULL;
-
-
- init_camera_struct( camera, ops );
- camera->lowlevel_data = lowlevel;
-
- /* register v4l device */
- if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
- kfree(camera);
- printk(KERN_DEBUG "video_register_device failed\n");
- return NULL;
- }
-
- /* get version information from camera: open/reset/close */
-
- /* open cpia */
- if (camera->ops->open(camera->lowlevel_data))
- return camera;
-
- /* reset the camera */
- if (reset_camera(camera) != 0) {
- camera->ops->close(camera->lowlevel_data);
- return camera;
- }
-
- /* close cpia */
- camera->ops->close(camera->lowlevel_data);
-
-#ifdef CONFIG_PROC_FS
- create_proc_cpia_cam(camera);
-#endif
-
- printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
- camera->params.version.firmwareVersion,
- camera->params.version.firmwareRevision,
- camera->params.version.vcVersion,
- camera->params.version.vcRevision);
- printk(KERN_INFO " CPiA PnP-ID: %04x:%04x:%04x\n",
- camera->params.pnpID.vendor,
- camera->params.pnpID.product,
- camera->params.pnpID.deviceRevision);
- printk(KERN_INFO " VP-Version: %d.%d %04x\n",
- camera->params.vpVersion.vpVersion,
- camera->params.vpVersion.vpRevision,
- camera->params.vpVersion.cameraHeadID);
-
- return camera;
-}
-
-void cpia_unregister_camera(struct cam_data *cam)
-{
- DBG("unregistering video\n");
- video_unregister_device(&cam->vdev);
- if (cam->open_count) {
- put_cam(cam->ops);
- DBG("camera open -- setting ops to NULL\n");
- cam->ops = NULL;
- }
-
-#ifdef CONFIG_PROC_FS
- DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev));
- destroy_proc_cpia_cam(cam);
-#endif
- if (!cam->open_count) {
- DBG("freeing camera\n");
- kfree(cam);
- }
-}
-
-static int __init cpia_init(void)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
- CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
-
- printk(KERN_WARNING "Since in-kernel colorspace conversion is not "
- "allowed, it is disabled by default now. Users should fix the "
- "applications in case they don't work without conversion "
- "reenabled by setting the 'colorspace_conv' module "
- "parameter to 1\n");
-
-#ifdef CONFIG_PROC_FS
- proc_cpia_create();
-#endif
-
- return 0;
-}
-
-static void __exit cpia_exit(void)
-{
-#ifdef CONFIG_PROC_FS
- proc_cpia_destroy();
-#endif
-}
-
-module_init(cpia_init);
-module_exit(cpia_exit);
-
-/* Exported symbols for modules. */
-
-EXPORT_SYMBOL(cpia_register_camera);
-EXPORT_SYMBOL(cpia_unregister_camera);
diff --git a/drivers/staging/cpia/cpia.h b/drivers/staging/cpia/cpia.h
deleted file mode 100644
index 8f0cfee4b8a1..000000000000
--- a/drivers/staging/cpia/cpia.h
+++ /dev/null
@@ -1,432 +0,0 @@
-#ifndef cpia_h
-#define cpia_h
-
-/*
- * CPiA Parallel Port Video4Linux driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * (C) Copyright 1999 Bas Huisman,
- * Peter Pregler,
- * Scott J. Bertin,
- * VLSI Vision Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define CPIA_MAJ_VER 1
-#define CPIA_MIN_VER 2
-#define CPIA_PATCH_VER 3
-
-#define CPIA_PP_MAJ_VER CPIA_MAJ_VER
-#define CPIA_PP_MIN_VER CPIA_MIN_VER
-#define CPIA_PP_PATCH_VER CPIA_PATCH_VER
-
-#define CPIA_USB_MAJ_VER CPIA_MAJ_VER
-#define CPIA_USB_MIN_VER CPIA_MIN_VER
-#define CPIA_USB_PATCH_VER CPIA_PATCH_VER
-
-#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */
-#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
-
-#ifdef __KERNEL__
-
-#include <asm/uaccess.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-
-struct cpia_camera_ops
-{
- /* open sets privdata to point to structure for this camera.
- * Returns negative value on error, otherwise 0.
- */
- int (*open)(void *privdata);
-
- /* Registers callback function cb to be called with cbdata
- * when an image is ready. If cb is NULL, only single image grabs
- * should be used. cb should immediately call streamRead to read
- * the data or data may be lost. Returns negative value on error,
- * otherwise 0.
- */
- int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
- void *cbdata);
-
- /* transferCmd sends commands to the camera. command MUST point to
- * an 8 byte buffer in kernel space. data can be NULL if no extra
- * data is needed. The size of the data is given by the last 2
- * bytes of command. data must also point to memory in kernel space.
- * Returns negative value on error, otherwise 0.
- */
- int (*transferCmd)(void *privdata, u8 *command, u8 *data);
-
- /* streamStart initiates stream capture mode.
- * Returns negative value on error, otherwise 0.
- */
- int (*streamStart)(void *privdata);
-
- /* streamStop terminates stream capture mode.
- * Returns negative value on error, otherwise 0.
- */
- int (*streamStop)(void *privdata);
-
- /* streamRead reads a frame from the camera. buffer points to a
- * buffer large enough to hold a complete frame in kernel space.
- * noblock indicates if this should be a non blocking read.
- * Returns the number of bytes read, or negative value on error.
- */
- int (*streamRead)(void *privdata, u8 *buffer, int noblock);
-
- /* close disables the device until open() is called again.
- * Returns negative value on error, otherwise 0.
- */
- int (*close)(void *privdata);
-
- /* If wait_for_stream_ready is non-zero, wait until the streamState
- * is STREAM_READY before calling streamRead.
- */
- int wait_for_stream_ready;
-
- /*
- * Used to maintain lowlevel module usage counts
- */
- struct module *owner;
-};
-
-struct cpia_frame {
- u8 *data;
- int count;
- int width;
- int height;
- volatile int state;
-};
-
-struct cam_params {
- struct {
- u8 firmwareVersion;
- u8 firmwareRevision;
- u8 vcVersion;
- u8 vcRevision;
- } version;
- struct {
- u16 vendor;
- u16 product;
- u16 deviceRevision;
- } pnpID;
- struct {
- u8 vpVersion;
- u8 vpRevision;
- u16 cameraHeadID;
- } vpVersion;
- struct {
- u8 systemState;
- u8 grabState;
- u8 streamState;
- u8 fatalError;
- u8 cmdError;
- u8 debugFlags;
- u8 vpStatus;
- u8 errorCode;
- } status;
- struct {
- u8 brightness;
- u8 contrast;
- u8 saturation;
- } colourParams;
- struct {
- u8 gainMode;
- u8 expMode;
- u8 compMode;
- u8 centreWeight;
- u8 gain;
- u8 fineExp;
- u8 coarseExpLo;
- u8 coarseExpHi;
- u8 redComp;
- u8 green1Comp;
- u8 green2Comp;
- u8 blueComp;
- } exposure;
- struct {
- u8 balanceMode;
- u8 redGain;
- u8 greenGain;
- u8 blueGain;
- } colourBalance;
- struct {
- u8 divisor;
- u8 baserate;
- } sensorFps;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } apcor;
- struct {
- u8 disabled;
- u8 flickerMode;
- u8 coarseJump;
- int allowableOverExposure;
- } flickerControl;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } vlOffset;
- struct {
- u8 mode;
- u8 decimation;
- } compression;
- struct {
- u8 frTargeting;
- u8 targetFR;
- u8 targetQ;
- } compressionTarget;
- struct {
- u8 yThreshold;
- u8 uvThreshold;
- } yuvThreshold;
- struct {
- u8 hysteresis;
- u8 threshMax;
- u8 smallStep;
- u8 largeStep;
- u8 decimationHysteresis;
- u8 frDiffStepThresh;
- u8 qDiffStepThresh;
- u8 decimationThreshMod;
- } compressionParams;
- struct {
- u8 videoSize; /* CIF/QCIF */
- u8 subSample;
- u8 yuvOrder;
- } format;
- struct { /* Intel QX3 specific data */
- u8 qx3_detected; /* a QX3 is present */
- u8 toplight; /* top light lit , R/W */
- u8 bottomlight; /* bottom light lit, R/W */
- u8 button; /* snapshot button pressed (R/O) */
- u8 cradled; /* microscope is in cradle (R/O) */
- } qx3;
- struct {
- u8 colStart; /* skip first 8*colStart pixels */
- u8 colEnd; /* finish at 8*colEnd pixels */
- u8 rowStart; /* skip first 4*rowStart lines */
- u8 rowEnd; /* finish at 4*rowEnd lines */
- } roi;
- u8 ecpTiming;
- u8 streamStartLine;
-};
-
-enum v4l_camstates {
- CPIA_V4L_IDLE = 0,
- CPIA_V4L_ERROR,
- CPIA_V4L_COMMAND,
- CPIA_V4L_GRABBING,
- CPIA_V4L_STREAMING,
- CPIA_V4L_STREAMING_PAUSED,
-};
-
-#define FRAME_NUM 2 /* double buffering for now */
-
-struct cam_data {
- struct list_head cam_data_list;
-
- struct mutex busy_lock; /* guard against SMP multithreading */
- struct cpia_camera_ops *ops; /* lowlevel driver operations */
- void *lowlevel_data; /* private data for lowlevel driver */
- u8 *raw_image; /* buffer for raw image data */
- struct cpia_frame decompressed_frame;
- /* buffer to hold decompressed frame */
- int image_size; /* sizeof last decompressed image */
- int open_count; /* # of process that have camera open */
-
- /* camera status */
- int fps; /* actual fps reported by the camera */
- int transfer_rate; /* transfer rate from camera in kB/s */
- u8 mainsFreq; /* for flicker control */
-
- /* proc interface */
- struct mutex param_lock; /* params lock for this camera */
- struct cam_params params; /* camera settings */
- struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
-
- /* v4l */
- int video_size; /* VIDEO_SIZE_ */
- volatile enum v4l_camstates camstate; /* v4l layer status */
- struct video_device vdev; /* v4l videodev */
- struct video_picture vp; /* v4l camera settings */
- struct video_window vw; /* v4l capture area */
- struct video_capture vc; /* v4l subcapture area */
-
- /* mmap interface */
- int curframe; /* the current frame to grab into */
- u8 *frame_buf; /* frame buffer data */
- struct cpia_frame frame[FRAME_NUM];
- /* FRAME_NUM-buffering, so we need a array */
-
- int first_frame;
- int mmap_kludge; /* 'wrong' byte order for mmap */
- volatile u32 cmd_queue; /* queued commands */
- int exposure_status; /* EXPOSURE_* */
- int exposure_count; /* number of frames at this status */
-};
-
-/* cpia_register_camera is called by low level driver for each camera.
- * A unique camera number is returned, or a negative value on error */
-struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
-
-/* cpia_unregister_camera is called by low level driver when a camera
- * is removed. This must not fail. */
-void cpia_unregister_camera(struct cam_data *cam);
-
-/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
- * one byte 16bit DMA alignment
- */
-#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
-
-/* constant value's */
-#define MAGIC_0 0x19
-#define MAGIC_1 0x68
-#define DATA_IN 0xC0
-#define DATA_OUT 0x40
-#define VIDEOSIZE_QCIF 0 /* 176x144 */
-#define VIDEOSIZE_CIF 1 /* 352x288 */
-#define VIDEOSIZE_SIF 2 /* 320x240 */
-#define VIDEOSIZE_QSIF 3 /* 160x120 */
-#define VIDEOSIZE_48_48 4 /* where no one has gone before, iconsize! */
-#define VIDEOSIZE_64_48 5
-#define VIDEOSIZE_128_96 6
-#define VIDEOSIZE_160_120 VIDEOSIZE_QSIF
-#define VIDEOSIZE_176_144 VIDEOSIZE_QCIF
-#define VIDEOSIZE_192_144 7
-#define VIDEOSIZE_224_168 8
-#define VIDEOSIZE_256_192 9
-#define VIDEOSIZE_288_216 10
-#define VIDEOSIZE_320_240 VIDEOSIZE_SIF
-#define VIDEOSIZE_352_288 VIDEOSIZE_CIF
-#define VIDEOSIZE_88_72 11 /* quarter CIF */
-#define SUBSAMPLE_420 0
-#define SUBSAMPLE_422 1
-#define YUVORDER_YUYV 0
-#define YUVORDER_UYVY 1
-#define NOT_COMPRESSED 0
-#define COMPRESSED 1
-#define NO_DECIMATION 0
-#define DECIMATION_ENAB 1
-#define EOI 0xff /* End Of Image */
-#define EOL 0xfd /* End Of Line */
-#define FRAME_HEADER_SIZE 64
-
-/* Image grab modes */
-#define CPIA_GRAB_SINGLE 0
-#define CPIA_GRAB_CONTINUOUS 1
-
-/* Compression parameters */
-#define CPIA_COMPRESSION_NONE 0
-#define CPIA_COMPRESSION_AUTO 1
-#define CPIA_COMPRESSION_MANUAL 2
-#define CPIA_COMPRESSION_TARGET_QUALITY 0
-#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
-
-/* Return offsets for GetCameraState */
-#define SYSTEMSTATE 0
-#define GRABSTATE 1
-#define STREAMSTATE 2
-#define FATALERROR 3
-#define CMDERROR 4
-#define DEBUGFLAGS 5
-#define VPSTATUS 6
-#define ERRORCODE 7
-
-/* SystemState */
-#define UNINITIALISED_STATE 0
-#define PASS_THROUGH_STATE 1
-#define LO_POWER_STATE 2
-#define HI_POWER_STATE 3
-#define WARM_BOOT_STATE 4
-
-/* GrabState */
-#define GRAB_IDLE 0
-#define GRAB_ACTIVE 1
-#define GRAB_DONE 2
-
-/* StreamState */
-#define STREAM_NOT_READY 0
-#define STREAM_READY 1
-#define STREAM_OPEN 2
-#define STREAM_PAUSED 3
-#define STREAM_FINISHED 4
-
-/* Fatal Error, CmdError, and DebugFlags */
-#define CPIA_FLAG 1
-#define SYSTEM_FLAG 2
-#define INT_CTRL_FLAG 4
-#define PROCESS_FLAG 8
-#define COM_FLAG 16
-#define VP_CTRL_FLAG 32
-#define CAPTURE_FLAG 64
-#define DEBUG_FLAG 128
-
-/* VPStatus */
-#define VP_STATE_OK 0x00
-
-#define VP_STATE_FAILED_VIDEOINIT 0x01
-#define VP_STATE_FAILED_AECACBINIT 0x02
-#define VP_STATE_AEC_MAX 0x04
-#define VP_STATE_ACB_BMAX 0x08
-
-#define VP_STATE_ACB_RMIN 0x10
-#define VP_STATE_ACB_GMIN 0x20
-#define VP_STATE_ACB_RMAX 0x40
-#define VP_STATE_ACB_GMAX 0x80
-
-/* default (minimum) compensation values */
-#define COMP_RED 220
-#define COMP_GREEN1 214
-#define COMP_GREEN2 COMP_GREEN1
-#define COMP_BLUE 230
-
-/* exposure status */
-#define EXPOSURE_VERY_LIGHT 0
-#define EXPOSURE_LIGHT 1
-#define EXPOSURE_NORMAL 2
-#define EXPOSURE_DARK 3
-#define EXPOSURE_VERY_DARK 4
-
-/* ErrorCode */
-#define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */
-#define ALOG(fmt,args...) printk(fmt, ##args)
-#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __func__ , __LINE__ , ##args)
-
-#ifdef _CPIA_DEBUG_
-#define ADBG(fmt,args...) printk(fmt, jiffies, ##args)
-#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __func__, __LINE__ , ##args)
-#else
-#define DBG(fmn,args...) do {} while(0)
-#endif
-
-#define DEB_BYTE(p)\
- DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
- (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
- (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
-
-#endif /* __KERNEL__ */
-
-#endif /* cpia_h */
diff --git a/drivers/staging/cpia/cpia_pp.c b/drivers/staging/cpia/cpia_pp.c
deleted file mode 100644
index f5604c16a092..000000000000
--- a/drivers/staging/cpia/cpia_pp.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * cpia_pp CPiA Parallel Port driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
- * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>,
- * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.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.
- */
-
-/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
-/* #define _CPIA_DEBUG_ 1 */
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h>
-#include <linux/parport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <linux/kmod.h>
-
-/* #define _CPIA_DEBUG_ define for verbose debug output */
-#include "cpia.h"
-
-static int cpia_pp_open(void *privdata);
-static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata);
-static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
-static int cpia_pp_streamStart(void *privdata);
-static int cpia_pp_streamStop(void *privdata);
-static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
-static int cpia_pp_close(void *privdata);
-
-
-#define ABOUT "Parallel port driver for Vision CPiA based cameras"
-
-#define PACKET_LENGTH 8
-
-/* Magic numbers for defining port-device mappings */
-#define PPCPIA_PARPORT_UNSPEC -4
-#define PPCPIA_PARPORT_AUTO -3
-#define PPCPIA_PARPORT_OFF -2
-#define PPCPIA_PARPORT_NONE -1
-
-static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
-static char *parport[PARPORT_MAX] = {NULL,};
-
-MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
-MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
-MODULE_LICENSE("GPL");
-
-module_param_array(parport, charp, NULL, 0);
-MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
-
-struct pp_cam_entry {
- struct pardevice *pdev;
- struct parport *port;
- struct work_struct cb_task;
- void (*cb_func)(void *cbdata);
- void *cb_data;
- int open_count;
- wait_queue_head_t wq_stream;
- /* image state flags */
- int image_ready; /* we got an interrupt */
- int image_complete; /* we have seen 4 EOI */
-
- int streaming; /* we are in streaming mode */
- int stream_irq;
-};
-
-static struct cpia_camera_ops cpia_pp_ops =
-{
- cpia_pp_open,
- cpia_pp_registerCallback,
- cpia_pp_transferCmd,
- cpia_pp_streamStart,
- cpia_pp_streamStop,
- cpia_pp_streamRead,
- cpia_pp_close,
- 1,
- THIS_MODULE
-};
-
-static LIST_HEAD(cam_list);
-static spinlock_t cam_list_lock_pp;
-
-/* FIXME */
-static void cpia_parport_enable_irq( struct parport *port ) {
- parport_enable_irq(port);
- mdelay(10);
- return;
-}
-
-static void cpia_parport_disable_irq( struct parport *port ) {
- parport_disable_irq(port);
- mdelay(10);
- return;
-}
-
-/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
- * Link Flag during negotiation */
-#define UPLOAD_FLAG 0x08
-#define NIBBLE_TRANSFER 0x01
-#define ECP_TRANSFER 0x03
-
-#define PARPORT_CHUNK_SIZE PAGE_SIZE
-
-
-static void cpia_pp_run_callback(struct work_struct *work)
-{
- void (*cb_func)(void *cbdata);
- void *cb_data;
- struct pp_cam_entry *cam;
-
- cam = container_of(work, struct pp_cam_entry, cb_task);
- cb_func = cam->cb_func;
- cb_data = cam->cb_data;
-
- cb_func(cb_data);
-}
-
-/****************************************************************************
- *
- * CPiA-specific low-level parport functions for nibble uploads
- *
- ***************************************************************************/
-/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
-/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
-
-static size_t cpia_read_nibble (struct parport *port,
- void *buffer, size_t len,
- int flags)
-{
- /* adapted verbatim, with one change, from
- parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
-
- unsigned char *buf = buffer;
- int i;
- unsigned char byte = 0;
-
- len *= 2; /* in nibbles */
- for (i=0; i < len; i++) {
- unsigned char nibble;
-
- /* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
- * after every second nibble to signal that more
- * data is available. (the total number of Bytes that
- * should be sent is known; if too few are received, an error
- * will be recorded after a timeout).
- * This is incompatible with parport_ieee1284_read_nibble(),
- * which expects to find nFault LO after every second nibble.
- */
-
- /* Solution: modify cpia_read_nibble to only check for
- * nDataAvail before the first nibble is sent.
- */
-
- /* Does the error line indicate end of data? */
- if (((i /*& 1*/) == 0) &&
- (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
- DBG("%s: No more nibble data (%d bytes)\n",
- port->name, i/2);
- goto end_of_data;
- }
-
- /* Event 7: Set nAutoFd low. */
- parport_frob_control (port,
- PARPORT_CONTROL_AUTOFD,
- PARPORT_CONTROL_AUTOFD);
-
- /* Event 9: nAck goes low. */
- port->ieee1284.phase = IEEE1284_PH_REV_DATA;
- if (parport_wait_peripheral (port,
- PARPORT_STATUS_ACK, 0)) {
- /* Timeout -- no more data? */
- DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
- port->name, i/2);
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
- break;
- }
-
-
- /* Read a nibble. */
- nibble = parport_read_status (port) >> 3;
- nibble &= ~8;
- if ((nibble & 0x10) == 0)
- nibble |= 8;
- nibble &= 0xf;
-
- /* Event 10: Set nAutoFd high. */
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
-
- /* Event 11: nAck goes high. */
- if (parport_wait_peripheral (port,
- PARPORT_STATUS_ACK,
- PARPORT_STATUS_ACK)) {
- /* Timeout -- no more data? */
- DBG("%s: Nibble timeout at event 11\n",
- port->name);
- break;
- }
-
- if (i & 1) {
- /* Second nibble */
- byte |= nibble << 4;
- *buf++ = byte;
- } else
- byte = nibble;
- }
-
- if (i == len) {
- /* Read the last nibble without checking data avail. */
- if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
- end_of_data:
- /* Go to reverse idle phase. */
- parport_frob_control (port,
- PARPORT_CONTROL_AUTOFD,
- PARPORT_CONTROL_AUTOFD);
- port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
- }
- else
- port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
- }
-
- return i/2;
-}
-
-/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
- * (See CPiA Data sheet p. 31)
- *
- * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
- * nonstandard variant of nibble mode which allows the same (mediocre)
- * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
- * parallel ports, but works also for non-TRISTATE-capable ports.
- * (Standard nibble mode only send 4 bits per cycle)
- *
- */
-
-static size_t cpia_read_nibble_stream(struct parport *port,
- void *buffer, size_t len,
- int flags)
-{
- int i;
- unsigned char *buf = buffer;
- int endseen = 0;
-
- for (i=0; i < len; i++) {
- unsigned char nibble[2], byte = 0;
- int j;
-
- /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
- if (endseen > 3 )
- break;
-
- /* Event 7: Set nAutoFd low. */
- parport_frob_control (port,
- PARPORT_CONTROL_AUTOFD,
- PARPORT_CONTROL_AUTOFD);
-
- /* Event 9: nAck goes low. */
- port->ieee1284.phase = IEEE1284_PH_REV_DATA;
- if (parport_wait_peripheral (port,
- PARPORT_STATUS_ACK, 0)) {
- /* Timeout -- no more data? */
- DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
- port->name, i/2);
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
- break;
- }
-
- /* Read lower nibble */
- nibble[0] = parport_read_status (port) >>3;
-
- /* Event 10: Set nAutoFd high. */
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
-
- /* Event 11: nAck goes high. */
- if (parport_wait_peripheral (port,
- PARPORT_STATUS_ACK,
- PARPORT_STATUS_ACK)) {
- /* Timeout -- no more data? */
- DBG("%s: Nibble timeout at event 11\n",
- port->name);
- break;
- }
-
- /* Read upper nibble */
- nibble[1] = parport_read_status (port) >>3;
-
- /* reassemble the byte */
- for (j = 0; j < 2 ; j++ ) {
- nibble[j] &= ~8;
- if ((nibble[j] & 0x10) == 0)
- nibble[j] |= 8;
- nibble[j] &= 0xf;
- }
- byte = (nibble[0] |(nibble[1] << 4));
- *buf++ = byte;
-
- if(byte == EOI)
- endseen++;
- else
- endseen = 0;
- }
- return i;
-}
-
-/****************************************************************************
- *
- * EndTransferMode
- *
- ***************************************************************************/
-static void EndTransferMode(struct pp_cam_entry *cam)
-{
- parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
-}
-
-/****************************************************************************
- *
- * ForwardSetup
- *
- ***************************************************************************/
-static int ForwardSetup(struct pp_cam_entry *cam)
-{
- int retry;
-
- /* The CPiA uses ECP protocol for Downloads from the Host to the camera.
- * This will be software-emulated if ECP hardware is not present
- */
-
- /* the usual camera maximum response time is 10ms, but after receiving
- * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
-
- for(retry = 0; retry < 4; ++retry) {
- if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
- break;
- }
- mdelay(10);
- }
- if(retry == 4) {
- DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
- return -1;
- }
- return 0;
-}
-/****************************************************************************
- *
- * ReverseSetup
- *
- ***************************************************************************/
-static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
-{
- int retry;
- int upload_mode, mode = IEEE1284_MODE_ECP;
- int transfer_mode = ECP_TRANSFER;
-
- if (!(cam->port->modes & PARPORT_MODE_ECP) &&
- !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
- mode = IEEE1284_MODE_NIBBLE;
- transfer_mode = NIBBLE_TRANSFER;
- }
-
- upload_mode = mode;
- if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
-
- /* the usual camera maximum response time is 10ms, but after
- * receiving some commands, it needs up to 40ms. */
-
- for(retry = 0; retry < 4; ++retry) {
- if(!parport_negotiate(cam->port, mode)) {
- break;
- }
- mdelay(10);
- }
- if(retry == 4) {
- if(extensibility)
- DBG("Unable to negotiate upload extensibility mode\n");
- else
- DBG("Unable to negotiate upload mode\n");
- return -1;
- }
- if(extensibility) cam->port->ieee1284.mode = upload_mode;
- return 0;
-}
-
-/****************************************************************************
- *
- * WritePacket
- *
- ***************************************************************************/
-static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
-{
- int retval=0;
- int size_written;
-
- if (packet == NULL) {
- return -EINVAL;
- }
- if (ForwardSetup(cam)) {
- DBG("Write failed in setup\n");
- return -EIO;
- }
- size_written = parport_write(cam->port, packet, size);
- if(size_written != size) {
- DBG("Write failed, wrote %d/%d\n", size_written, size);
- retval = -EIO;
- }
- EndTransferMode(cam);
- return retval;
-}
-
-/****************************************************************************
- *
- * ReadPacket
- *
- ***************************************************************************/
-static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
-{
- int retval=0;
-
- if (packet == NULL) {
- return -EINVAL;
- }
- if (ReverseSetup(cam, 0)) {
- return -EIO;
- }
-
- /* support for CPiA variant nibble reads */
- if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
- if(cpia_read_nibble(cam->port, packet, size, 0) != size)
- retval = -EIO;
- } else {
- if(parport_read(cam->port, packet, size) != size)
- retval = -EIO;
- }
- EndTransferMode(cam);
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamStart
- *
- ***************************************************************************/
-static int cpia_pp_streamStart(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
- DBG("\n");
- cam->streaming=1;
- cam->image_ready=0;
- //if (ReverseSetup(cam,1)) return -EIO;
- if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamStop
- *
- ***************************************************************************/
-static int cpia_pp_streamStop(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
-
- DBG("\n");
- cam->streaming=0;
- cpia_parport_disable_irq(cam->port);
- //EndTransferMode(cam);
-
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamRead
- *
- ***************************************************************************/
-static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
-{
- int bytes_read;
-
- /* support for CPiA variant "nibble stream" reads */
- if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
- bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
- else {
- int new_bytes;
- for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
- new_bytes = parport_read(port, buffer+bytes_read,
- len-bytes_read);
- if(new_bytes < 0) break;
- }
- }
- return bytes_read;
-}
-
-static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
-{
- struct pp_cam_entry *cam = privdata;
- int read_bytes = 0;
- int i, endseen, block_size, new_bytes;
-
- if(cam == NULL) {
- DBG("Internal driver error: cam is NULL\n");
- return -EINVAL;
- }
- if(buffer == NULL) {
- DBG("Internal driver error: buffer is NULL\n");
- return -EINVAL;
- }
- //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
- if( cam->stream_irq ) {
- DBG("%d\n", cam->image_ready);
- cam->image_ready--;
- }
- cam->image_complete=0;
- if (0/*cam->streaming*/) {
- if(!cam->image_ready) {
- if(noblock) return -EWOULDBLOCK;
- interruptible_sleep_on(&cam->wq_stream);
- if( signal_pending(current) ) return -EINTR;
- DBG("%d\n", cam->image_ready);
- }
- } else {
- if (ReverseSetup(cam, 1)) {
- DBG("unable to ReverseSetup\n");
- return -EIO;
- }
- }
- endseen = 0;
- block_size = PARPORT_CHUNK_SIZE;
- while( !cam->image_complete ) {
- cond_resched();
-
- new_bytes = cpia_pp_read(cam->port, buffer, block_size );
- if( new_bytes <= 0 ) {
- break;
- }
- i=-1;
- while(++i<new_bytes && endseen<4) {
- if(*buffer==EOI) {
- endseen++;
- } else {
- endseen=0;
- }
- buffer++;
- }
- read_bytes += i;
- if( endseen==4 ) {
- cam->image_complete=1;
- break;
- }
- if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
- block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
- }
- }
- EndTransferMode(cam);
- return cam->image_complete ? read_bytes : -EIO;
-}
-/****************************************************************************
- *
- * cpia_pp_transferCmd
- *
- ***************************************************************************/
-static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
-{
- int err;
- int retval=0;
- int databytes;
- struct pp_cam_entry *cam = privdata;
-
- if(cam == NULL) {
- DBG("Internal driver error: cam is NULL\n");
- return -EINVAL;
- }
- if(command == NULL) {
- DBG("Internal driver error: command is NULL\n");
- return -EINVAL;
- }
- databytes = (((int)command[7])<<8) | command[6];
- if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
- DBG("Error writing command\n");
- return err;
- }
- if(command[0] == DATA_IN) {
- u8 buffer[8];
- if(data == NULL) {
- DBG("Internal driver error: data is NULL\n");
- return -EINVAL;
- }
- if((err = ReadPacket(cam, buffer, 8)) < 0) {
- DBG("Error reading command result\n");
- return err;
- }
- memcpy(data, buffer, databytes);
- } else if(command[0] == DATA_OUT) {
- if(databytes > 0) {
- if(data == NULL) {
- DBG("Internal driver error: data is NULL\n");
- retval = -EINVAL;
- } else {
- if((err=WritePacket(cam, data, databytes)) < 0){
- DBG("Error writing command data\n");
- return err;
- }
- }
- }
- } else {
- DBG("Unexpected first byte of command: %x\n", command[0]);
- retval = -EINVAL;
- }
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_open
- *
- ***************************************************************************/
-static int cpia_pp_open(void *privdata)
-{
- struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
-
- if (cam == NULL)
- return -EINVAL;
-
- if(cam->open_count == 0) {
- if (parport_claim(cam->pdev)) {
- DBG("failed to claim the port\n");
- return -EBUSY;
- }
- parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
- parport_data_forward(cam->port);
- parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
- udelay(50);
- parport_write_control(cam->port,
- PARPORT_CONTROL_SELECT
- | PARPORT_CONTROL_INIT);
- }
-
- ++cam->open_count;
-
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_registerCallback
- *
- ***************************************************************************/
-static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
-{
- struct pp_cam_entry *cam = privdata;
- int retval = 0;
-
- if(cam->port->irq != PARPORT_IRQ_NONE) {
- cam->cb_func = cb;
- cam->cb_data = cbdata;
- INIT_WORK(&cam->cb_task, cpia_pp_run_callback);
- } else {
- retval = -1;
- }
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_close
- *
- ***************************************************************************/
-static int cpia_pp_close(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
- if (--cam->open_count == 0) {
- parport_release(cam->pdev);
- }
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_register
- *
- ***************************************************************************/
-static int cpia_pp_register(struct parport *port)
-{
- struct pardevice *pdev = NULL;
- struct pp_cam_entry *cam;
- struct cam_data *cpia;
-
- if (!(port->modes & PARPORT_MODE_PCSPP)) {
- LOG("port is not supported by CPiA driver\n");
- return -ENXIO;
- }
-
- cam = kzalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
- if (cam == NULL) {
- LOG("failed to allocate camera structure\n");
- return -ENOMEM;
- }
-
- pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
- NULL, 0, cam);
-
- if (!pdev) {
- LOG("failed to parport_register_device\n");
- kfree(cam);
- return -ENXIO;
- }
-
- cam->pdev = pdev;
- cam->port = port;
- init_waitqueue_head(&cam->wq_stream);
-
- cam->streaming = 0;
- cam->stream_irq = 0;
-
- if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
- LOG("failed to cpia_register_camera\n");
- parport_unregister_device(pdev);
- kfree(cam);
- return -ENXIO;
- }
- spin_lock( &cam_list_lock_pp );
- list_add( &cpia->cam_data_list, &cam_list );
- spin_unlock( &cam_list_lock_pp );
-
- return 0;
-}
-
-static void cpia_pp_detach (struct parport *port)
-{
- struct list_head *tmp;
- struct cam_data *cpia = NULL;
- struct pp_cam_entry *cam;
-
- spin_lock( &cam_list_lock_pp );
- list_for_each (tmp, &cam_list) {
- cpia = list_entry(tmp, struct cam_data, cam_data_list);
- cam = (struct pp_cam_entry *) cpia->lowlevel_data;
- if (cam && cam->port->number == port->number) {
- list_del(&cpia->cam_data_list);
- break;
- }
- cpia = NULL;
- }
- spin_unlock( &cam_list_lock_pp );
-
- if (!cpia) {
- DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
- return;
- }
-
- cam = (struct pp_cam_entry *) cpia->lowlevel_data;
- cpia_unregister_camera(cpia);
- if(cam->open_count > 0)
- cpia_pp_close(cam);
- parport_unregister_device(cam->pdev);
- cpia->lowlevel_data = NULL;
- kfree(cam);
-}
-
-static void cpia_pp_attach (struct parport *port)
-{
- unsigned int i;
-
- switch (parport_nr[0])
- {
- case PPCPIA_PARPORT_UNSPEC:
- case PPCPIA_PARPORT_AUTO:
- if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
- port->probe_info[0].cmdset == NULL ||
- strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
- return;
-
- cpia_pp_register(port);
-
- break;
-
- default:
- for (i = 0; i < PARPORT_MAX; ++i) {
- if (port->number == parport_nr[i]) {
- cpia_pp_register(port);
- break;
- }
- }
- break;
- }
-}
-
-static struct parport_driver cpia_pp_driver = {
- .name = "cpia_pp",
- .attach = cpia_pp_attach,
- .detach = cpia_pp_detach,
-};
-
-static int __init cpia_pp_init(void)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
- CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
-
- if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
- printk(" disabled\n");
- return 0;
- }
-
- spin_lock_init( &cam_list_lock_pp );
-
- if (parport_register_driver (&cpia_pp_driver)) {
- LOG ("unable to register with parport\n");
- return -EIO;
- }
- return 0;
-}
-
-static int __init cpia_init(void)
-{
- if (parport[0]) {
- /* The user gave some parameters. Let's see what they were. */
- if (!strncmp(parport[0], "auto", 4)) {
- parport_nr[0] = PPCPIA_PARPORT_AUTO;
- } else {
- int n;
- for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
- if (!strncmp(parport[n], "none", 4)) {
- parport_nr[n] = PPCPIA_PARPORT_NONE;
- } else {
- char *ep;
- unsigned long r = simple_strtoul(parport[n], &ep, 0);
- if (ep != parport[n]) {
- parport_nr[n] = r;
- } else {
- LOG("bad port specifier `%s'\n", parport[n]);
- return -ENODEV;
- }
- }
- }
- }
- }
- return cpia_pp_init();
-}
-
-static void __exit cpia_cleanup(void)
-{
- parport_unregister_driver(&cpia_pp_driver);
- return;
-}
-
-module_init(cpia_init);
-module_exit(cpia_cleanup);
diff --git a/drivers/staging/cpia/cpia_usb.c b/drivers/staging/cpia/cpia_usb.c
deleted file mode 100644
index 58d193ff591c..000000000000
--- a/drivers/staging/cpia/cpia_usb.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * cpia_usb CPiA USB driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * Copyright (C) 1999 Jochen Scharrlach <Jochen.Scharrlach@schwaben.de>
- * Copyright (C) 1999, 2000 Johannes Erdfelt <johannes@erdfelt.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.
- */
-
-/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
-/* #define _CPIA_DEBUG_ 1 */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/usb.h>
-
-#include "cpia.h"
-
-#define USB_REQ_CPIA_GRAB_FRAME 0xC1
-#define USB_REQ_CPIA_UPLOAD_FRAME 0xC2
-#define WAIT_FOR_NEXT_FRAME 0
-#define FORCE_FRAME_UPLOAD 1
-
-#define FRAMES_PER_DESC 10
-#define FRAME_SIZE_PER_DESC 960 /* Shouldn't be hardcoded */
-#define CPIA_NUMSBUF 2
-#define STREAM_BUF_SIZE (PAGE_SIZE * 4)
-#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2)
-
-struct cpia_sbuf {
- char *data;
- struct urb *urb;
-};
-
-#define FRAMEBUF_LEN (CPIA_MAX_FRAME_SIZE+100)
-enum framebuf_status {
- FRAME_EMPTY,
- FRAME_READING,
- FRAME_READY,
- FRAME_ERROR,
-};
-
-struct framebuf {
- int length;
- enum framebuf_status status;
- u8 data[FRAMEBUF_LEN];
- struct framebuf *next;
-};
-
-struct usb_cpia {
- /* Device structure */
- struct usb_device *dev;
-
- unsigned char iface;
- wait_queue_head_t wq_stream;
-
- int cursbuf; /* Current receiving sbuf */
- struct cpia_sbuf sbuf[CPIA_NUMSBUF]; /* Double buffering */
-
- int streaming;
- int open;
- int present;
- struct framebuf *buffers[3];
- struct framebuf *curbuff, *workbuff;
-};
-
-static int cpia_usb_open(void *privdata);
-static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata);
-static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
-static int cpia_usb_streamStart(void *privdata);
-static int cpia_usb_streamStop(void *privdata);
-static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock);
-static int cpia_usb_close(void *privdata);
-
-#define ABOUT "USB driver for Vision CPiA based cameras"
-
-static struct cpia_camera_ops cpia_usb_ops = {
- cpia_usb_open,
- cpia_usb_registerCallback,
- cpia_usb_transferCmd,
- cpia_usb_streamStart,
- cpia_usb_streamStop,
- cpia_usb_streamRead,
- cpia_usb_close,
- 0,
- THIS_MODULE
-};
-
-static LIST_HEAD(cam_list);
-static spinlock_t cam_list_lock_usb;
-
-static void cpia_usb_complete(struct urb *urb)
-{
- int i;
- char *cdata;
- struct usb_cpia *ucpia;
-
- if (!urb || !urb->context)
- return;
-
- ucpia = (struct usb_cpia *) urb->context;
-
- if (!ucpia->dev || !ucpia->streaming || !ucpia->present || !ucpia->open)
- return;
-
- if (ucpia->workbuff->status == FRAME_EMPTY) {
- ucpia->workbuff->status = FRAME_READING;
- ucpia->workbuff->length = 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int n = urb->iso_frame_desc[i].actual_length;
- int st = urb->iso_frame_desc[i].status;
-
- cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- if (st)
- printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n", i, n, st);
-
- if (FRAMEBUF_LEN < ucpia->workbuff->length + n) {
- printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
- return;
- }
-
- if (n) {
- if ((ucpia->workbuff->length > 0) ||
- (0x19 == cdata[0] && 0x68 == cdata[1])) {
- memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
- ucpia->workbuff->length += n;
- } else
- DBG("Ignoring packet!\n");
- } else {
- if (ucpia->workbuff->length > 4 &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-1] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-2] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-3] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-4]) {
- ucpia->workbuff->status = FRAME_READY;
- ucpia->curbuff = ucpia->workbuff;
- ucpia->workbuff = ucpia->workbuff->next;
- ucpia->workbuff->status = FRAME_EMPTY;
- ucpia->workbuff->length = 0;
-
- if (waitqueue_active(&ucpia->wq_stream))
- wake_up_interruptible(&ucpia->wq_stream);
- }
- }
- }
-
- /* resubmit */
- urb->dev = ucpia->dev;
- if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
- printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __func__, i);
-}
-
-static int cpia_usb_open(void *privdata)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
- struct urb *urb;
- int ret, retval = 0, fx, err;
-
- if (!ucpia)
- return -EINVAL;
-
- ucpia->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ucpia->sbuf[0].data)
- return -EINVAL;
-
- ucpia->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ucpia->sbuf[1].data) {
- retval = -EINVAL;
- goto error_0;
- }
-
- ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
- if (ret < 0) {
- printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
- retval = -EBUSY;
- goto error_1;
- }
-
- ucpia->buffers[0]->status = FRAME_EMPTY;
- ucpia->buffers[0]->length = 0;
- ucpia->buffers[1]->status = FRAME_EMPTY;
- ucpia->buffers[1]->length = 0;
- ucpia->buffers[2]->status = FRAME_EMPTY;
- ucpia->buffers[2]->length = 0;
- ucpia->curbuff = ucpia->buffers[0];
- ucpia->workbuff = ucpia->buffers[1];
-
- /* We double buffer the Iso lists, and also know the polling
- * interval is every frame (1 == (1 << (bInterval -1))).
- */
- urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if (!urb) {
- printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
- retval = -ENOMEM;
- goto error_1;
- }
-
- ucpia->sbuf[0].urb = urb;
- urb->dev = ucpia->dev;
- urb->context = ucpia;
- urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = ucpia->sbuf[0].data;
- urb->complete = cpia_usb_complete;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->interval = 1;
- urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
- urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
- }
-
- urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if (!urb) {
- printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 1\n");
- retval = -ENOMEM;
- goto error_urb0;
- }
-
- ucpia->sbuf[1].urb = urb;
- urb->dev = ucpia->dev;
- urb->context = ucpia;
- urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = ucpia->sbuf[1].data;
- urb->complete = cpia_usb_complete;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->interval = 1;
- urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
- urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
- }
-
- /* queue the ISO urbs, and resubmit in the completion handler */
- err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL);
- if (err) {
- printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
- err);
- goto error_urb1;
- }
- err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL);
- if (err) {
- printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
- err);
- goto error_urb1;
- }
-
- ucpia->streaming = 1;
- ucpia->open = 1;
-
- return 0;
-
-error_urb1: /* free urb 1 */
- usb_free_urb(ucpia->sbuf[1].urb);
- ucpia->sbuf[1].urb = NULL;
-error_urb0: /* free urb 0 */
- usb_free_urb(ucpia->sbuf[0].urb);
- ucpia->sbuf[0].urb = NULL;
-error_1:
- kfree (ucpia->sbuf[1].data);
- ucpia->sbuf[1].data = NULL;
-error_0:
- kfree (ucpia->sbuf[0].data);
- ucpia->sbuf[0].data = NULL;
-
- return retval;
-}
-
-//
-// convenience functions
-//
-
-/****************************************************************************
- *
- * WritePacket
- *
- ***************************************************************************/
-static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_t size)
-{
- if (!packet)
- return -EINVAL;
-
- return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- packet[1] + (packet[0] << 8),
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- packet[2] + (packet[3] << 8),
- packet[4] + (packet[5] << 8), buf, size, 1000);
-}
-
-/****************************************************************************
- *
- * ReadPacket
- *
- ***************************************************************************/
-static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size)
-{
- if (!packet || size <= 0)
- return -EINVAL;
-
- return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- packet[1] + (packet[0] << 8),
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- packet[2] + (packet[3] << 8),
- packet[4] + (packet[5] << 8), buf, size, 1000);
-}
-
-static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data)
-{
- int err = 0;
- int databytes;
- struct usb_cpia *ucpia = (struct usb_cpia *)privdata;
- struct usb_device *udev = ucpia->dev;
-
- if (!udev) {
- DBG("Internal driver error: udev is NULL\n");
- return -EINVAL;
- }
-
- if (!command) {
- DBG("Internal driver error: command is NULL\n");
- return -EINVAL;
- }
-
- databytes = (((int)command[7])<<8) | command[6];
-
- if (command[0] == DATA_IN) {
- u8 buffer[8];
-
- if (!data) {
- DBG("Internal driver error: data is NULL\n");
- return -EINVAL;
- }
-
- err = ReadPacket(udev, command, buffer, 8);
- if (err < 0)
- return err;
-
- memcpy(data, buffer, databytes);
- } else if(command[0] == DATA_OUT)
- WritePacket(udev, command, data, databytes);
- else {
- DBG("Unexpected first byte of command: %x\n", command[0]);
- err = -EINVAL;
- }
-
- return 0;
-}
-
-static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamStart(void *privdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamStop(void *privdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
- struct framebuf *mybuff;
-
- if (!ucpia || !ucpia->present)
- return -1;
-
- if (ucpia->curbuff->status != FRAME_READY)
- interruptible_sleep_on(&ucpia->wq_stream);
- else
- DBG("Frame already waiting!\n");
-
- mybuff = ucpia->curbuff;
-
- if (!mybuff)
- return -1;
-
- if (mybuff->status != FRAME_READY || mybuff->length < 4) {
- DBG("Something went wrong!\n");
- return -1;
- }
-
- memcpy(frame, mybuff->data, mybuff->length);
- mybuff->status = FRAME_EMPTY;
-
-/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
-/* mybuff->length, frame[0], frame[1], */
-/* frame[mybuff->length-4], frame[mybuff->length-3], */
-/* frame[mybuff->length-2], frame[mybuff->length-1]); */
-
- return mybuff->length;
-}
-
-static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
-{
- if (!ucpia->streaming)
- return;
-
- ucpia->streaming = 0;
-
- /* Set packet size to 0 */
- if (try) {
- int ret;
-
- ret = usb_set_interface(ucpia->dev, ucpia->iface, 0);
- if (ret < 0) {
- printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret);
- return;
- }
- }
-
- /* Unschedule all of the iso td's */
- if (ucpia->sbuf[1].urb) {
- usb_kill_urb(ucpia->sbuf[1].urb);
- usb_free_urb(ucpia->sbuf[1].urb);
- ucpia->sbuf[1].urb = NULL;
- }
-
- kfree(ucpia->sbuf[1].data);
- ucpia->sbuf[1].data = NULL;
-
- if (ucpia->sbuf[0].urb) {
- usb_kill_urb(ucpia->sbuf[0].urb);
- usb_free_urb(ucpia->sbuf[0].urb);
- ucpia->sbuf[0].urb = NULL;
- }
-
- kfree(ucpia->sbuf[0].data);
- ucpia->sbuf[0].data = NULL;
-}
-
-static int cpia_usb_close(void *privdata)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
-
- if(!ucpia)
- return -ENODEV;
-
- ucpia->open = 0;
-
- /* ucpia->present = 0 protects against trying to reset the
- * alt setting if camera is physically disconnected while open */
- cpia_usb_free_resources(ucpia, ucpia->present);
-
- return 0;
-}
-
-/* Probing and initializing */
-
-static int cpia_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_cpia *ucpia;
- struct cam_data *cam;
- int ret;
-
- /* A multi-config CPiA camera? */
- if (udev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- interface = intf->cur_altsetting;
-
- printk(KERN_INFO "USB CPiA camera found\n");
-
- ucpia = kzalloc(sizeof(*ucpia), GFP_KERNEL);
- if (!ucpia) {
- printk(KERN_ERR "couldn't kmalloc cpia struct\n");
- return -ENOMEM;
- }
-
- ucpia->dev = udev;
- ucpia->iface = interface->desc.bInterfaceNumber;
- init_waitqueue_head(&ucpia->wq_stream);
-
- ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));
- if (!ucpia->buffers[0]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");
- goto fail_alloc_0;
- }
-
- ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));
- if (!ucpia->buffers[1]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");
- goto fail_alloc_1;
- }
-
- ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));
- if (!ucpia->buffers[2]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");
- goto fail_alloc_2;
- }
-
- ucpia->buffers[0]->next = ucpia->buffers[1];
- ucpia->buffers[1]->next = ucpia->buffers[2];
- ucpia->buffers[2]->next = ucpia->buffers[0];
-
- ret = usb_set_interface(udev, ucpia->iface, 0);
- if (ret < 0) {
- printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);
- /* goto fail_all; */
- }
-
- /* Before register_camera, important */
- ucpia->present = 1;
-
- cam = cpia_register_camera(&cpia_usb_ops, ucpia);
- if (!cam) {
- LOG("failed to cpia_register_camera\n");
- goto fail_all;
- }
-
- spin_lock( &cam_list_lock_usb );
- list_add( &cam->cam_data_list, &cam_list );
- spin_unlock( &cam_list_lock_usb );
-
- usb_set_intfdata(intf, cam);
- return 0;
-
-fail_all:
- vfree(ucpia->buffers[2]);
- ucpia->buffers[2] = NULL;
-fail_alloc_2:
- vfree(ucpia->buffers[1]);
- ucpia->buffers[1] = NULL;
-fail_alloc_1:
- vfree(ucpia->buffers[0]);
- ucpia->buffers[0] = NULL;
-fail_alloc_0:
- kfree(ucpia);
- return -EIO;
-}
-
-static void cpia_disconnect(struct usb_interface *intf);
-
-static struct usb_device_id cpia_id_table [] = {
- { USB_DEVICE(0x0553, 0x0002) },
- { USB_DEVICE(0x0813, 0x0001) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, cpia_id_table);
-MODULE_LICENSE("GPL");
-
-
-static struct usb_driver cpia_driver = {
- .name = "cpia",
- .probe = cpia_probe,
- .disconnect = cpia_disconnect,
- .id_table = cpia_id_table,
-};
-
-static void cpia_disconnect(struct usb_interface *intf)
-{
- struct cam_data *cam = usb_get_intfdata(intf);
- struct usb_cpia *ucpia;
-
- usb_set_intfdata(intf, NULL);
- if (!cam)
- return;
-
- ucpia = (struct usb_cpia *) cam->lowlevel_data;
- spin_lock( &cam_list_lock_usb );
- list_del(&cam->cam_data_list);
- spin_unlock( &cam_list_lock_usb );
-
- ucpia->present = 0;
-
- cpia_unregister_camera(cam);
- if(ucpia->open)
- cpia_usb_close(cam->lowlevel_data);
-
- ucpia->curbuff->status = FRAME_ERROR;
-
- if (waitqueue_active(&ucpia->wq_stream))
- wake_up_interruptible(&ucpia->wq_stream);
-
- ucpia->curbuff = ucpia->workbuff = NULL;
-
- vfree(ucpia->buffers[2]);
- ucpia->buffers[2] = NULL;
-
- vfree(ucpia->buffers[1]);
- ucpia->buffers[1] = NULL;
-
- vfree(ucpia->buffers[0]);
- ucpia->buffers[0] = NULL;
-
- cam->lowlevel_data = NULL;
- kfree(ucpia);
-}
-
-static int __init usb_cpia_init(void)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
- CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
-
- spin_lock_init(&cam_list_lock_usb);
- return usb_register(&cpia_driver);
-}
-
-static void __exit usb_cpia_cleanup(void)
-{
- usb_deregister(&cpia_driver);
-}
-
-
-module_init (usb_cpia_init);
-module_exit (usb_cpia_cleanup);
-
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
index 1d73334d2a44..b2656957aa8f 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/staging/cx25821/Kconfig
@@ -1,11 +1,11 @@
config VIDEO_CX25821
tristate "Conexant cx25821 support"
- depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+ depends on DVB_CORE && VIDEO_DEV && PCI && I2C
depends on BKL # please fix
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_DVB
select VIDEOBUF_DMA_SG
select VIDEO_CX25840
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 2a01dc057b2c..9a205a342c55 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -20,6 +20,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
@@ -42,11 +44,16 @@
#define AUDIO_SRAM_CHANNEL SRAM_CH08
-#define dprintk(level, fmt, arg...) if (debug >= level) \
- printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
-
-#define dprintk_core(level, fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (debug >= level) \
+ pr_info("%s/1: " fmt, chip->dev->name, ##arg); \
+} while (0)
+#define dprintk_core(level, fmt, arg...) \
+do { \
+ if (debug >= level) \
+ printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name, ##arg); \
+} while (0)
/****************************************************************************
Data type declarations - Can be moded to a header file later
@@ -173,12 +180,11 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)
tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
FLD_AUD_CLK_ENABLE);
- /* printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line,"
- "cmds_start(0x%x)= %d lines/FIFO, %d periods, "
- "%d byte buffer\n", buf->bpl,
- audio_ch->cmds_start,
- cx_read(audio_ch->cmds_start + 12)>>1,
- chip->num_periods, buf->bpl *chip->num_periods);
+ /*
+ pr_info("DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d byte buffer\n",
+ buf->bpl, audio_ch->cmds_start,
+ cx_read(audio_ch->cmds_start + 12)>>1,
+ chip->num_periods, buf->bpl * chip->num_periods);
*/
/* Enables corresponding bits at AUD_INT_STAT */
@@ -259,8 +265,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
/* risc op code error */
if (status & AUD_INT_OPC_ERR) {
- printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
- dev->name);
+ pr_warn("WARNING %s/1: Audio risc op code error\n", dev->name);
cx_clear(AUD_INT_DMA_CTL,
FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
@@ -269,8 +274,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
[AUDIO_SRAM_CHANNEL]);
}
if (status & AUD_INT_DN_SYNC) {
- printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
- dev->name);
+ pr_warn("WARNING %s: Downstream sync error!\n", dev->name);
cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
return;
}
@@ -388,8 +392,7 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
unsigned int bpl = 0;
if (!chip) {
- printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
- " Can't proceed with open\n");
+ pr_err("DEBUG: cx25821 can't find device struct. Can't proceed with open\n");
return -ENODEV;
}
@@ -479,8 +482,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
chip->period_size, chip->num_periods,
1);
if (ret < 0) {
- printk(KERN_INFO
- "DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
+ pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
goto error;
}
@@ -608,8 +610,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
if (err < 0) {
- printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
- __func__);
+ pr_info("ERROR: FAILED snd_pcm_new() in %s\n", __func__);
return err;
}
pcm->private_data = chip;
@@ -674,23 +675,21 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
int err;
if (devno >= SNDRV_CARDS) {
- printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
- __func__);
+ pr_info("DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__);
return -ENODEV;
}
if (!enable[devno]) {
++devno;
- printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
+ pr_info("DEBUG ERROR: !enable[devno] %s\n", __func__);
return -ENOENT;
}
err = snd_card_create(index[devno], id[devno], THIS_MODULE,
sizeof(struct cx25821_audio_dev), &card);
if (err < 0) {
- printk(KERN_INFO
- "DEBUG ERROR: cannot create snd_card_new in %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",
+ __func__);
return err;
}
@@ -712,16 +711,15 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
if (err < 0) {
- printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
+ pr_err("ERROR %s: can't get IRQ %d for ALSA\n",
chip->dev->name, dev->pci->irq);
goto error;
}
err = snd_cx25821_pcm(chip, 0, "cx25821 Digital");
if (err < 0) {
- printk(KERN_INFO
- "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
+ __func__);
goto error;
}
@@ -732,13 +730,13 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
chip->iobase, chip->irq);
strcpy(card->mixername, "CX25821");
- printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
- card->driver, devno);
+ pr_info("%s/%i: ALSA support for cx25821 boards\n",
+ card->driver, devno);
err = snd_card_register(card);
if (err < 0) {
- printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot register sound card %s\n",
+ __func__);
goto error;
}
@@ -778,8 +776,7 @@ static int cx25821_alsa_init(void)
}
if (dev == NULL)
- printk(KERN_INFO
- "cx25821 ERROR ALSA: no cx25821 cards found\n");
+ pr_info("ERROR ALSA: no cx25821 cards found\n");
return 0;
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index 1607b0d86e6f..7992a3ba526f 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-audio-upstream.h"
@@ -221,7 +223,7 @@ void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
if (!dev->_audio_is_running) {
printk(KERN_DEBUG
- "cx25821: No audio file is currently running so return!\n");
+ pr_fmt("No audio file is currently running so return!\n"));
return;
}
/* Disable RISC interrupts */
@@ -281,19 +283,19 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_audiofilename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!\n",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR "%s: File has no READ operations registered!\n",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -320,9 +322,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Audio file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+ __func__);
break;
}
}
@@ -346,7 +347,7 @@ static void cx25821_audioups_handler(struct work_struct *work)
container_of(work, struct cx25821_dev, _audio_work_entry);
if (!dev) {
- printk(KERN_ERR "ERROR %s(): since container_of(work_struct) FAILED!\n",
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
__func__);
return;
}
@@ -373,19 +374,19 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_audiofilename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!\n",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR "%s: File has no READ operations registered!\n",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -414,9 +415,8 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Audio file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+ __func__);
break;
}
}
@@ -459,7 +459,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_risc_virt_addr) {
printk(KERN_DEBUG
- "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
+ pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n"));
return -ENOMEM;
}
/* Clear out memory at address */
@@ -474,7 +474,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_audiodata_buf_virt_addr) {
printk(KERN_DEBUG
- "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning.\n");
+ pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n"));
return -ENOMEM;
}
/* Clear out memory at address */
@@ -490,7 +490,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_audio_lines_count);
if (ret < 0) {
printk(KERN_DEBUG
- "cx25821 ERROR creating audio upstream RISC programs!\n");
+ pr_fmt("ERROR creating audio upstream RISC programs!\n"));
goto error;
}
@@ -569,16 +569,16 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
spin_unlock(&dev->slock);
} else {
if (status & FLD_AUD_SRC_OF)
- printk(KERN_WARNING "%s: Audio Received Overflow Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received Overflow Error Interrupt!\n",
+ __func__);
if (status & FLD_AUD_SRC_SYNC)
- printk(KERN_WARNING "%s: Audio Received Sync Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received Sync Error Interrupt!\n",
+ __func__);
if (status & FLD_AUD_SRC_OPC_ERR)
- printk(KERN_WARNING "%s: Audio Received OpCode Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received OpCode Error Interrupt!\n",
+ __func__);
/* Read and write back the interrupt status register to clear
* our bits */
@@ -586,8 +586,8 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
}
if (dev->_audiofile_status == END_OF_FILE) {
- printk(KERN_WARNING "cx25821: EOF Channel Audio Framecount = %d\n",
- dev->_audioframe_count);
+ pr_warn("EOF Channel Audio Framecount = %d\n",
+ dev->_audioframe_count);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -644,9 +644,8 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
/* 10 millisecond timeout */
if (count++ > 1000) {
- printk(KERN_ERR
- "cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
- __func__);
+ pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n",
+ __func__);
return;
}
@@ -696,8 +695,8 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
@@ -726,7 +725,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
int str_length = 0;
if (dev->_audio_is_running) {
- printk(KERN_WARNING "Audio Channel is still running so return!\n");
+ pr_warn("Audio Channel is still running so return!\n");
return 0;
}
@@ -740,7 +739,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
if (!dev->_irq_audio_queues) {
printk(KERN_DEBUG
- "cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
+ pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
return -ENOMEM;
}
@@ -787,8 +786,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
retval =
cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Audio upstream buffers!\n",
+ pr_err("%s: Failed to set up Audio upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
index da0f56d50e27..94e8d685c889 100644
--- a/drivers/staging/cx25821/cx25821-cards.c
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index 300da319b065..a216b620b718 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/i2c.h>
#include <linux/slab.h>
#include "cx25821.h"
@@ -332,7 +334,7 @@ struct cx25821_dmaqueue mpegq;
static int cx25821_risc_decode(u32 risc)
{
- static char *instr[16] = {
+ static const char * const instr[16] = {
[RISC_SYNC >> 28] = "sync",
[RISC_WRITE >> 28] = "write",
[RISC_WRITEC >> 28] = "writec",
@@ -344,7 +346,7 @@ static int cx25821_risc_decode(u32 risc)
[RISC_WRITECM >> 28] = "writecm",
[RISC_WRITECR >> 28] = "writecr",
};
- static int incr[16] = {
+ static const int incr[16] = {
[RISC_WRITE >> 28] = 3,
[RISC_JUMP >> 28] = 3,
[RISC_SKIP >> 28] = 1,
@@ -353,7 +355,7 @@ static int cx25821_risc_decode(u32 risc)
[RISC_WRITECM >> 28] = 3,
[RISC_WRITECR >> 28] = 4,
};
- static char *bits[] = {
+ static const char * const bits[] = {
"12", "13", "14", "resync",
"cnt0", "cnt1", "18", "19",
"20", "21", "22", "23",
@@ -361,13 +363,13 @@ static int cx25821_risc_decode(u32 risc)
};
int i;
- printk("0x%08x [ %s", risc,
- instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
+ pr_cont("0x%08x [ %s",
+ risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
if (risc & (1 << (i + 12)))
- printk(" %s", bits[i]);
+ pr_cont(" %s", bits[i]);
}
- printk(" count=%d ]\n", risc & 0xfff);
+ pr_cont(" count=%d ]\n", risc & 0xfff);
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
@@ -620,16 +622,15 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
u32 risc;
unsigned int i, j, n;
- printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
- ch->name);
+ pr_warn("%s: %s - dma channel status dump\n", dev->name, ch->name);
for (i = 0; i < ARRAY_SIZE(name); i++)
- printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i * 4,
- name[i], cx_read(ch->cmds_start + 4 * i));
+ pr_warn("cmds + 0x%2x: %-15s: 0x%08x\n",
+ i * 4, name[i], cx_read(ch->cmds_start + 4 * i));
j = i * 4;
for (i = 0; i < 4;) {
risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
+ pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
i += cx25821_risc_decode(risc);
}
@@ -637,36 +638,35 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
risc = cx_read(ch->ctrl_start + 4 * i);
/* No consideration for bits 63-32 */
- printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
- ch->ctrl_start + 4 * i, i);
+ pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
+ i * 4, ch->ctrl_start + 4 * i, i);
n = cx25821_risc_decode(risc);
for (j = 1; j < n; j++) {
risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk(KERN_WARNING
- "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
+ pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
+ 4 * (i + j), i + j, risc, j);
}
}
- printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
+ pr_warn(" : fifo: 0x%08x -> 0x%x\n",
+ ch->fifo_start, ch->fifo_start + ch->fifo_size);
+ pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
+ ch->ctrl_start, ch->ctrl_start + 6 * 16);
+ pr_warn(" : ptr1_reg: 0x%08x\n",
+ cx_read(ch->ptr1_reg));
+ pr_warn(" : ptr2_reg: 0x%08x\n",
+ cx_read(ch->ptr2_reg));
+ pr_warn(" : cnt1_reg: 0x%08x\n",
+ cx_read(ch->cnt1_reg));
+ pr_warn(" : cnt2_reg: 0x%08x\n",
+ cx_read(ch->cnt2_reg));
}
EXPORT_SYMBOL(cx25821_sram_channel_dump);
void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
struct sram_channel *ch)
{
- static char *name[] = {
+ static const char * const name[] = {
"init risc lo",
"init risc hi",
"cdt base",
@@ -686,18 +686,18 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
u32 risc, value, tmp;
unsigned int i, j, n;
- printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
- dev->name, ch->name);
+ pr_info("\n%s: %s - dma Audio channel status dump\n",
+ dev->name, ch->name);
for (i = 0; i < ARRAY_SIZE(name); i++)
- printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n",
- dev->name, i * 4, name[i],
- cx_read(ch->cmds_start + 4 * i));
+ pr_info("%s: cmds + 0x%2x: %-15s: 0x%08x\n",
+ dev->name, i * 4, name[i],
+ cx_read(ch->cmds_start + 4 * i));
j = i * 4;
for (i = 0; i < 4;) {
risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
+ pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
i += cx25821_risc_decode(risc);
}
@@ -705,44 +705,43 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
risc = cx_read(ch->ctrl_start + 4 * i);
/* No consideration for bits 63-32 */
- printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
- ch->ctrl_start + 4 * i, i);
+ pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
+ i * 4, ch->ctrl_start + 4 * i, i);
n = cx25821_risc_decode(risc);
for (j = 1; j < n; j++) {
risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk(KERN_WARNING
- "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
+ pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
+ 4 * (i + j), i + j, risc, j);
}
}
- printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
+ pr_warn(" : fifo: 0x%08x -> 0x%x\n",
+ ch->fifo_start, ch->fifo_start + ch->fifo_size);
+ pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
+ ch->ctrl_start, ch->ctrl_start + 6 * 16);
+ pr_warn(" : ptr1_reg: 0x%08x\n",
+ cx_read(ch->ptr1_reg));
+ pr_warn(" : ptr2_reg: 0x%08x\n",
+ cx_read(ch->ptr2_reg));
+ pr_warn(" : cnt1_reg: 0x%08x\n",
+ cx_read(ch->cnt1_reg));
+ pr_warn(" : cnt2_reg: 0x%08x\n",
+ cx_read(ch->cnt2_reg));
for (i = 0; i < 4; i++) {
risc = cx_read(ch->cmds_start + 56 + (i * 4));
- printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
+ pr_warn("instruction %d = 0x%x\n", i, risc);
}
/* read data from the first cdt buffer */
risc = cx_read(AUD_A_CDT);
- printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
+ pr_warn("\nread cdt loc=0x%x\n", risc);
for (i = 0; i < 8; i++) {
n = cx_read(risc + i * 4);
- printk(KERN_WARNING "0x%x ", n);
+ pr_cont("0x%x ", n);
}
- printk(KERN_WARNING "\n\n");
+ pr_cont("\n\n");
value = cx_read(CLK_RST);
CX25821_INFO(" CLK_RST = 0x%x\n\n", value);
@@ -870,7 +869,7 @@ static int cx25821_get_resources(struct cx25821_dev *dev)
dev->name))
return 0;
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
+ pr_err("%s: can't get MMIO memory @ 0x%llx\n",
dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
return -EBUSY;
@@ -880,8 +879,8 @@ static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
{
dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
- printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
- dev->hwrevision);
+ pr_info("%s(): Hardware revision = 0x%02x\n",
+ __func__, dev->hwrevision);
}
static void cx25821_iounmap(struct cx25821_dev *dev)
@@ -901,9 +900,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
{
int io_size = 0, i;
- printk(KERN_INFO "\n***********************************\n");
- printk(KERN_INFO "cx25821 set up\n");
- printk(KERN_INFO "***********************************\n\n");
+ pr_info("\n***********************************\n");
+ pr_info("cx25821 set up\n");
+ pr_info("***********************************\n\n");
mutex_init(&dev->lock);
@@ -920,13 +919,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
if (dev->pci->device != 0x8210) {
- printk(KERN_INFO
- "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
- __func__, dev->pci->device);
+ pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
+ __func__, dev->pci->device);
return -1;
} else {
- printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
- dev->pci->device);
+ pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
}
/* Apply a sensible clock frequency for the PCIe bridge */
@@ -956,8 +953,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
if (cx25821_get_resources(dev) < 0) {
- printk(KERN_ERR "%s No more PCIe resources for "
- "subsystem: %04x:%04x\n",
+ pr_err("%s: No more PCIe resources for subsystem: %04x:%04x\n",
dev->name, dev->pci->subsystem_vendor,
dev->pci->subsystem_device);
@@ -985,11 +981,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->bmmio = (u8 __iomem *) dev->lmmio;
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, cx25821_boards[dev->board].name,
- dev->board, card[dev->nr] == dev->board ?
- "insmod option" : "autodetected");
+ pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ dev->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device, cx25821_boards[dev->board].name,
+ dev->board, card[dev->nr] == dev->board ?
+ "insmod option" : "autodetected");
/* init hardware */
cx25821_initialize(dev);
@@ -1004,8 +1000,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
cx25821_card_setup(dev);
if (medusa_video_init(dev) < 0)
- CX25821_ERR("%s() Failed to initialize medusa!\n"
- , __func__);
+ CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__);
cx25821_video_register(dev);
@@ -1017,13 +1012,12 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
if (video_register_device
(dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
cx25821_videoioctl_unregister(dev);
- printk(KERN_ERR
- "%s() Failed to register video adapter for IOCTL, so \
- unregistering videoioctl device.\n", __func__);
+ pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n",
+ __func__);
}
cx25821_dev_checkrevision(dev);
- CX25821_INFO("cx25821 setup done!\n");
+ CX25821_INFO("setup done!\n");
return 0;
}
@@ -1362,20 +1356,20 @@ void cx25821_print_irqbits(char *name, char *tag, char **strings,
{
unsigned int i;
- printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
+ printk(KERN_DEBUG pr_fmt("%s: %s [0x%x]"), name, tag, bits);
for (i = 0; i < len; i++) {
if (!(bits & (1 << i)))
continue;
if (strings[i])
- printk(" %s", strings[i]);
+ pr_cont(" %s", strings[i]);
else
- printk(" %d", i);
+ pr_cont(" %d", i);
if (!(mask & (1 << i)))
continue;
- printk("*");
+ pr_cont("*");
}
- printk("\n");
+ pr_cont("\n");
}
EXPORT_SYMBOL(cx25821_print_irqbits);
@@ -1405,12 +1399,12 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
if (pci_enable_device(pci_dev)) {
err = -EIO;
- printk(KERN_INFO "pci enable failed! ");
+ pr_info("pci enable failed!\n");
goto fail_unregister_device;
}
- printk(KERN_INFO "cx25821 Athena pci enable !\n");
+ pr_info("Athena pci enable !\n");
err = cx25821_dev_setup(dev);
if (err) {
@@ -1423,14 +1417,13 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
/* print pci info */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat, (unsigned long long)dev->base_io_addr);
+ pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
+ dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+ dev->pci_lat, (unsigned long long)dev->base_io_addr);
pci_set_master(pci_dev);
if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+ pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
err = -EIO;
goto fail_irq;
}
@@ -1440,15 +1433,14 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
- pci_dev->irq);
+ pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
goto fail_irq;
}
return 0;
fail_irq:
- printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ !\n");
+ pr_info("cx25821_initdev() can't get IRQ !\n");
cx25821_dev_unregister(dev);
fail_unregister_pci:
@@ -1510,9 +1502,10 @@ static struct pci_driver cx25821_pci_driver = {
static int __init cx25821_init(void)
{
INIT_LIST_HEAD(&cx25821_devlist);
- printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
- (CX25821_VERSION_CODE >> 16) & 0xff,
- (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
+ pr_info("driver version %d.%d.%d loaded\n",
+ (CX25821_VERSION_CODE >> 16) & 0xff,
+ (CX25821_VERSION_CODE >> 8) & 0xff,
+ CX25821_VERSION_CODE & 0xff);
return pci_register_driver(&cx25821_pci_driver);
}
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
index 2b14bcca6897..130dfebebe20 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821.h"
#include <linux/i2c.h>
@@ -32,10 +34,11 @@ static unsigned int i2c_scan;
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-#define dprintk(level, fmt, arg...)\
- do { if (i2c_debug >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (i2c_debug >= level) \
+ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
+} while (0)
#define I2C_WAIT_DELAY 32
#define I2C_WAIT_RETRY 64
@@ -98,7 +101,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
if (!i2c_slave_did_ack(i2c_adap))
return -EIO;
- dprintk(1, "%s() returns 0\n", __func__);
+ dprintk(1, "%s(): returns 0\n", __func__);
return 0;
}
@@ -163,7 +166,7 @@ eio:
retval = -EIO;
err:
if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
+ pr_err(" ERR: %d\n", retval);
return retval;
}
@@ -187,7 +190,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
if (!i2c_slave_did_ack(i2c_adap))
return -EIO;
- dprintk(1, "%s() returns 0\n", __func__);
+ dprintk(1, "%s(): returns 0\n", __func__);
return 0;
}
@@ -227,7 +230,7 @@ eio:
retval = -EIO;
err:
if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
+ pr_err(" ERR: %d\n", retval);
return retval;
}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index 1e11e0ce2d0a..fc780d0908dc 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821.h"
#include "cx25821-medusa-video.h"
#include "cx25821-biffuncs.h"
@@ -499,9 +501,8 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
/* validate the width - cannot be negative */
if (width > MAX_WIDTH) {
- printk
- ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
- __func__, width, MAX_WIDTH);
+ pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
+ __func__, width, MAX_WIDTH);
width = MAX_WIDTH;
}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
index 405e2db72b0f..e2efacdfb874 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-video-upstream-ch2.h"
@@ -211,8 +213,7 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
u32 tmp = 0;
if (!dev->_is_running_ch2) {
- printk
- ("cx25821: No video file is currently running so return!\n");
+ pr_info("No video file is currently running so return!\n");
return;
}
/* Disable RISC interrupts */
@@ -301,19 +302,19 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename_ch2, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk("%s: File has no READ operations registered!",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -340,9 +341,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -366,8 +366,8 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work)
container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
if (!dev) {
- printk("ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
+ __func__);
return;
}
@@ -393,21 +393,20 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename_ch2, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk
- ("%s: File has no READ operations registered! Returning.",
- __func__);
+ pr_err("%s(): File has no READ operations registered! Returning\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -435,9 +434,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -483,8 +481,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
if (!dev->_dma_virt_addr_ch2) {
- printk
- ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
return -ENOMEM;
}
@@ -504,8 +501,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
if (!dev->_data_buf_virt_addr_ch2) {
- printk
- ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for data buffer! Returning\n");
return -ENOMEM;
}
@@ -521,8 +517,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
dev->_lines_count_ch2);
if (ret < 0) {
- printk(KERN_INFO
- "cx25821: Failed creating Video Upstream Risc programs!\n");
+ pr_info("Failed creating Video Upstream Risc programs!\n");
goto error;
}
@@ -602,8 +597,8 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
}
if (dev->_file_status_ch2 == END_OF_FILE) {
- printk("cx25821: EOF Channel 2 Framecount = %d\n",
- dev->_frame_count_ch2);
+ pr_info("EOF Channel 2 Framecount = %d\n",
+ dev->_frame_count_ch2);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -714,8 +709,8 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
/* Start the DMA engine */
@@ -744,7 +739,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
int str_length = 0;
if (dev->_is_running_ch2) {
- printk("Video Channel is still running so return!\n");
+ pr_info("Video Channel is still running so return!\n");
return 0;
}
@@ -756,8 +751,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
create_singlethread_workqueue("cx25821_workqueue2");
if (!dev->_irq_queues_ch2) {
- printk
- ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
+ pr_err("create_singlethread_workqueue() for Video FAILED!\n");
return -ENOMEM;
}
/*
@@ -829,8 +823,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
dev->_line_size_ch2);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Video upstream buffers!\n",
+ pr_err("%s: Failed to set up Video upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
index 16bf74d65912..31b4e3c74c8d 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-video-upstream.h"
@@ -257,8 +259,7 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
u32 tmp = 0;
if (!dev->_is_running) {
- printk
- (KERN_INFO "cx25821: No video file is currently running so return!\n");
+ pr_info("No video file is currently running so return!\n");
return;
}
/* Disable RISC interrupts */
@@ -346,23 +347,20 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR
- "%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR
- "%s: File has no file operations registered!",
- __func__);
+ pr_err("%s(): File has no file operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR
- "%s: File has no READ operations registered!",
- __func__);
+ pr_err("%s(): File has no READ operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -388,10 +386,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to \
- read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -415,9 +411,8 @@ static void cx25821_vidups_handler(struct work_struct *work)
container_of(work, struct cx25821_dev, _irq_work_entry);
if (!dev) {
- printk(KERN_ERR
- "ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
+ __func__);
return;
}
@@ -443,23 +438,20 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR
- "%s: File has no file operations registered!",
- __func__);
+ pr_err("%s(): File has no file operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR
- "%s: File has no READ operations registered! \
- Returning.",
- __func__);
+ pr_err("%s(): File has no READ operations registered! Returning\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -487,10 +479,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more \
- bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -534,9 +524,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_risc_size = dev->upstream_riscbuf_size;
if (!dev->_dma_virt_addr) {
- printk
- (KERN_ERR "cx25821: FAILED to allocate memory for Risc \
- buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
return -ENOMEM;
}
@@ -556,9 +544,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_data_buf_size = dev->upstream_databuf_size;
if (!dev->_data_buf_virt_addr) {
- printk
- (KERN_ERR "cx25821: FAILED to allocate memory for data \
- buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for data buffer! Returning\n");
return -ENOMEM;
}
@@ -574,8 +560,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
dev->_lines_count);
if (ret < 0) {
- printk(KERN_INFO
- "cx25821: Failed creating Video Upstream Risc programs!\n");
+ pr_info("Failed creating Video Upstream Risc programs!\n");
goto error;
}
@@ -652,22 +637,20 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
spin_unlock(&dev->slock);
} else {
if (status & FLD_VID_SRC_UF)
- printk
- (KERN_ERR "%s: Video Received Underflow Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received Underflow Error Interrupt!\n",
+ __func__);
if (status & FLD_VID_SRC_SYNC)
- printk(KERN_ERR "%s: Video Received Sync Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received Sync Error Interrupt!\n",
+ __func__);
if (status & FLD_VID_SRC_OPC_ERR)
- printk(KERN_ERR "%s: Video Received OpCode Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received OpCode Error Interrupt!\n",
+ __func__);
}
if (dev->_file_status == END_OF_FILE) {
- printk(KERN_ERR "cx25821: EOF Channel 1 Framecount = %d\n",
- dev->_frame_count);
+ pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -775,8 +758,8 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
@@ -806,7 +789,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
int str_length = 0;
if (dev->_is_running) {
- printk(KERN_INFO "Video Channel is still running so return!\n");
+ pr_info("Video Channel is still running so return!\n");
return 0;
}
@@ -817,9 +800,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
if (!dev->_irq_queues) {
- printk
- (KERN_ERR "cx25821: create_singlethread_workqueue() for \
- Video FAILED!\n");
+ pr_err("create_singlethread_workqueue() for Video FAILED!\n");
return -ENOMEM;
}
/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
@@ -895,8 +876,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
/* Allocating buffers and prepare RISC program */
retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Video upstream buffers!\n",
+ pr_err("%s: Failed to set up Video upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index e7f1d5778cec..998c33acf7bd 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
@@ -92,7 +94,7 @@ int cx25821_get_format_size(void)
return ARRAY_SIZE(formats);
}
-struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
+struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
{
unsigned int i;
@@ -104,7 +106,7 @@ struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
if (formats[i].fourcc == fourcc)
return formats + i;
- printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
+ pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
return NULL;
}
@@ -159,15 +161,15 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
else
mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
if (bc != 1)
- printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
+ pr_err("%s: %d buffers handled (should be 1)\n",
__func__, bc);
}
#ifdef TUNER_FLAG
int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
{
- dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
- (unsigned int)norm, v4l2_norm_to_name(norm));
+ dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
+ __func__, (unsigned int)norm, v4l2_norm_to_name(norm));
dev->tvnorm = norm;
@@ -267,7 +269,7 @@ int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
struct v4l2_routing route;
memset(&route, 0, sizeof(route));
- dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
+ dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
dev->input = input;
@@ -400,8 +402,8 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
/* risc op code error */
if (status & (1 << 16)) {
- printk(KERN_WARNING "%s, %s: video risc op code error\n",
- dev->name, channel->name);
+ pr_warn("%s, %s: video risc op code error\n",
+ dev->name, channel->name);
cx_clear(channel->dma_ctl, 0x11);
cx25821_sram_channel_dump(dev, channel);
}
@@ -458,7 +460,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
btcx_riscmem_free(dev->pci,
&dev->channels[chan_num].vidq.stopper);
- printk(KERN_WARNING "device %d released!\n", chan_num);
+ pr_warn("device %d released!\n", chan_num);
}
}
@@ -590,7 +592,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
init_buffer = 1;
rc = videobuf_iolock(q, &buf->vb, NULL);
if (0 != rc) {
- printk(KERN_DEBUG "videobuf_iolock failed!\n");
+ printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
goto fail;
}
}
@@ -848,7 +850,7 @@ static int video_open(struct file *file)
pix_format =
(dev->channels[ch_id].pixel_formats ==
PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
+ fh->fmt = cx25821_format_by_fourcc(pix_format);
v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
@@ -1010,7 +1012,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (0 != err)
return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
fh->vidq.field = f->fmt.pix.field;
/* check if width and height is valid based on set standard */
@@ -1038,8 +1040,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
dev->channels[fh->channel_id].cif_width = fh->width;
medusa_set_resolution(dev, fh->width, SRAM_CH00);
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
+ dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width,
+ fh->height, fh->vidq.field);
v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
@@ -1070,14 +1072,14 @@ static int vidioc_log_status(struct file *file, void *priv)
u32 tmp = 0;
snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
+ pr_info("%s/2: ============ START LOG STATUS ============\n",
+ dev->name);
cx25821_call_all(dev, core, log_status);
tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 0 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
+ pr_info("Video input 0 is %s\n",
+ (tmp & 0x11) ? "streaming" : "stopped");
+ pr_info("%s/2: ============= END LOG STATUS =============\n",
+ dev->name);
return 0;
}
@@ -1119,7 +1121,7 @@ int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo
enum v4l2_field field;
unsigned int maxw, maxh;
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -1186,34 +1188,6 @@ int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-int cx25821_vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct cx25821_fh *fh = priv;
- struct videobuf_queue *q;
- struct v4l2_requestbuffers req;
- unsigned int i;
- int err;
-
- q = get_queue(fh);
- memset(&req, 0, sizeof(req));
- req.type = q->type;
- req.count = 8;
- req.memory = V4L2_MEMORY_MMAP;
- err = videobuf_reqbufs(q, &req);
- if (err < 0)
- return err;
-
- mbuf->frames = req.count;
- mbuf->size = 0;
- for (i = 0; i < mbuf->frames; i++) {
- mbuf->offsets[i] = q->bufs[i]->boff;
- mbuf->size += q->bufs[i]->bsize;
- }
- return 0;
-}
-#endif
-
int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
{
struct cx25821_fh *fh = priv;
@@ -1298,8 +1272,6 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
if (0 == INPUT(n)->type)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, iname[INPUT(n)->type]);
@@ -1319,7 +1291,7 @@ int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
*i = dev->input;
- dprintk(1, "%s() returns %d\n", __func__, *i);
+ dprintk(1, "%s(): returns %d\n", __func__, *i);
return 0;
}
@@ -1339,7 +1311,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
}
if (i > 2) {
- dprintk(1, "%s() -EINVAL\n", __func__);
+ dprintk(1, "%s(): -EINVAL\n", __func__);
return -EINVAL;
}
@@ -1390,7 +1362,7 @@ int cx25821_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_freque
if (0 != err)
return err;
} else {
- printk(KERN_ERR "Invalid fh pointer!\n");
+ pr_err("Invalid fh pointer!\n");
return -EINVAL;
}
@@ -1733,12 +1705,10 @@ static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1776,12 +1746,10 @@ static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1819,12 +1787,10 @@ static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1866,12 +1832,10 @@ static long video_ioctl_set(struct file *file, unsigned int cmd,
data_from_user = (struct downstream_user_struct *)arg;
- if (!data_from_user) {
- printk(
- "cx25821 in %s(): User data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): User data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -2022,9 +1986,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_log_status = vidioc_log_status,
.vidioc_g_priority = cx25821_vidioc_g_priority,
.vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
#ifdef TUNER_FLAG
.vidioc_g_tuner = cx25821_vidioc_g_tuner,
.vidioc_s_tuner = cx25821_vidioc_s_tuner,
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
index cc6034b1a95d..f4ee8051b8b3 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -40,19 +40,15 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
#define TUNER_FLAG
#define VIDEO_DEBUG 0
-#define dprintk(level, fmt, arg...)\
- do { if (VIDEO_DEBUG >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (VIDEO_DEBUG >= level) \
+ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
+} while (0)
/* For IOCTL to identify running upstream */
#define UPSTREAM_START_VIDEO 700
@@ -87,7 +83,7 @@ extern unsigned int vid_limit;
#define FORMAT_FLAGS_PACKED 0x01
extern struct cx25821_fmt formats[];
-extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
+extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc);
extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
extern void cx25821_dump_video_queue(struct cx25821_dev *dev,
@@ -133,7 +129,6 @@ extern int cx25821_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap);
extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f);
-extern int cx25821_vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
extern int cx25821_vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p);
extern int cx25821_vidioc_querybuf(struct file *file, void *priv,
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
index c94000125782..55115235f7f6 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/staging/cx25821/cx25821.h
@@ -519,9 +519,12 @@ extern struct sram_channel cx25821_sram_channels[];
#define Set_GPIO_Bit(Bit) (1 << Bit)
#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
-#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
-#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
-#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
+#define CX25821_ERR(fmt, args...) \
+ pr_err("(%d): " fmt, dev->board, ##args)
+#define CX25821_WARN(fmt, args...) \
+ pr_warn("(%d): " fmt, dev->board, ##args)
+#define CX25821_INFO(fmt, args...) \
+ pr_info("(%d): " fmt, dev->board, ##args)
extern int cx25821_i2c_register(struct cx25821_i2c *bus);
extern void cx25821_card_setup(struct cx25821_dev *dev);
diff --git a/drivers/staging/dabusb/Kconfig b/drivers/staging/dabusb/Kconfig
new file mode 100644
index 000000000000..87bdc425d3c5
--- /dev/null
+++ b/drivers/staging/dabusb/Kconfig
@@ -0,0 +1,14 @@
+config USB_DABUSB
+ tristate "DABUSB driver"
+ depends on USB
+ ---help---
+ A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
+ brought to you by the DAB-Team
+ <http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
+ as an example for URB-based bulk, control, and isochronous
+ transactions. URB's are explained in
+ <Documentation/usb/URB.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dabusb.
+
diff --git a/drivers/staging/dabusb/Makefile b/drivers/staging/dabusb/Makefile
new file mode 100644
index 000000000000..2ff2f228e5f9
--- /dev/null
+++ b/drivers/staging/dabusb/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_USB_DABUSB) += dabusb.o
+
diff --git a/drivers/staging/dabusb/TODO b/drivers/staging/dabusb/TODO
new file mode 100644
index 000000000000..f9c0314ea0c1
--- /dev/null
+++ b/drivers/staging/dabusb/TODO
@@ -0,0 +1,5 @@
+This is a driver for an experimental sample developed in 2003. The driver
+never supported any commercial product, nor had any known user.
+If nobody takes care on it, the driver will be removed for 2.6.39.
+
+Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/media/video/dabusb.c b/drivers/staging/dabusb/dabusb.c
index f3e25e91366d..f3e25e91366d 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/staging/dabusb/dabusb.c
diff --git a/drivers/media/video/dabusb.h b/drivers/staging/dabusb/dabusb.h
index 00eb34c863eb..00eb34c863eb 100644
--- a/drivers/media/video/dabusb.h
+++ b/drivers/staging/dabusb/dabusb.h
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c
index b996697e7eb2..15d7efeed292 100644
--- a/drivers/staging/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/dt3155v4l/dt3155v4l.c
@@ -876,9 +876,6 @@ static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
.vidioc_s_crop = dt3155_ioc_s_crop,
.vidioc_enum_framesizes = dt3155_ioc_enum_framesizes,
.vidioc_enum_frameintervals = dt3155_ioc_enum_frameintervals,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = iocgmbuf,
-#endif
*/
};
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
index 25961c23dc0f..884263b2775d 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/easycap/easycap.h
@@ -75,6 +75,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/usb.h>
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index a145a15cfdb3..8894ab14f167 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
t->value = temp; \
return count; \
} \
- static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+ static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
show_int(enable);
show_int(offline);
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index 3aecd30f0d1e..1da57df5cbcb 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,10 +1,10 @@
config VIDEO_GO7007
tristate "WIS GO7007 MPEG encoder support"
- depends on VIDEO_DEV && PCI && I2C && INPUT
+ depends on VIDEO_DEV && PCI && I2C
depends on BKL # please fix
depends on SND
select VIDEOBUF_DMA_SG
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select SND_PCM
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index b3f42f37a313..48d4e483d8a4 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -199,7 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
struct go7007 *go = i2c_get_adapdata(adapter);
struct v4l2_device *v4l2_dev = &go->v4l2_dev;
- if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL))
+ if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
return 0;
printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index c86d1498737d..1c1e98aee2d9 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
adis16220_write_reset, 0);
#define IIO_DEV_ATTR_CAPTURE(_store) \
- IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0)
+ IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
index fbae39fda5c0..5c455608b024 100644
--- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c
+++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
@@ -1269,7 +1269,7 @@ finish:
dbufs->output_bytes_produced = total_output;
str_info->status = str_info->prev;
str_info->prev = STREAM_DECODE;
- str_info->decode_ibuf = NULL;
kfree(str_info->decode_ibuf);
+ str_info->decode_ibuf = NULL;
return retval;
}
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
index 040e25ca6d33..67e23b6e2d35 100644
--- a/drivers/staging/line6/control.c
+++ b/drivers/staging/line6/control.c
@@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2);
VARIAX_PARAM_R(float, mix1);
VARIAX_PARAM_R(int, pickup_wiring);
-static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
pod_get_compression_threshold,
pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_delay_param_1_note_value,
pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
pod_get_band_2_frequency__bass,
pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
pod_get_band_3_frequency__bass,
pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_mod_param_1_note_value,
pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
pod_get_band_4_frequency__bass,
pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
pod_get_mod_param_1_double_precision,
pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
pod_get_delay_param_1_double_precision,
pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
pod_get_volume_tweak_pedal_assign,
pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_stomp_param_1_note_value,
pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 4304dfe6c166..ab67e889d2c4 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
return count;
}
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO,
midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO,
midi_get_midi_mask_receive, midi_set_midi_mask_receive);
/* MIDI device destructor */
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index e54770e34d2e..b9c55f9eb501 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev,
return count;
}
-static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
+static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume,
pcm_set_impulse_volume);
-static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
+static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period,
pcm_set_impulse_period);
#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 22e2cedcacf7..d9b30212585c 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
#undef GET_SYSTEM_PARAM
/* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
+static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel,
pod_set_channel);
static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
+static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf,
pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
+static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level,
pod_set_monitor_level);
static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
+static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
pod_set_routing);
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
+static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
+static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
pod_set_tuner_mute);
static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
#endif
/* control info callback */
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index 6a10b0f9749a..879e6992bbc6 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
return count;
}
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
toneport_set_led_green);
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 894eee7f2317..81241cdf1be9 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev,
#endif
/* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
+static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
+static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
variax_set_active);
static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
#endif
/*
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig
index fa790db75d7e..cdaff5903a8f 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/lirc/Kconfig
@@ -14,26 +14,19 @@ if LIRC_STAGING
config LIRC_BT829
tristate "BT829 based hardware"
- depends on LIRC_STAGING && PCI
+ depends on LIRC && PCI
help
Driver for the IR interface on BT829-based hardware
-config LIRC_I2C
- tristate "I2C Based IR Receivers"
- depends on LIRC_STAGING && I2C
- help
- Driver for I2C-based IR receivers, such as those commonly
- found onboard Hauppauge PVR-150/250/350 video capture cards
-
config LIRC_IGORPLUGUSB
tristate "Igor Cesko's USB IR Receiver"
- depends on LIRC_STAGING && USB
+ depends on LIRC && USB
help
Driver for Igor Cesko's USB IR Receiver
config LIRC_IMON
tristate "Legacy SoundGraph iMON Receiver and Display"
- depends on LIRC_STAGING && USB
+ depends on LIRC && USB
help
Driver for the original SoundGraph iMON IR Receiver and Display
@@ -41,31 +34,31 @@ config LIRC_IMON
config LIRC_IT87
tristate "ITE IT87XX CIR Port Receiver"
- depends on LIRC_STAGING && PNP
+ depends on LIRC && PNP
help
Driver for the ITE IT87xx IR Receiver
config LIRC_ITE8709
tristate "ITE8709 CIR Port Receiver"
- depends on LIRC_STAGING && PNP
+ depends on LIRC && PNP
help
Driver for the ITE8709 IR Receiver
config LIRC_PARALLEL
tristate "Homebrew Parallel Port Receiver"
- depends on LIRC_STAGING && PARPORT
+ depends on LIRC && PARPORT
help
Driver for Homebrew Parallel Port Receivers
config LIRC_SASEM
tristate "Sasem USB IR Remote"
- depends on LIRC_STAGING && USB
+ depends on LIRC && USB
help
Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module
config LIRC_SERIAL
tristate "Homebrew Serial Port Receiver"
- depends on LIRC_STAGING
+ depends on LIRC
help
Driver for Homebrew Serial Port Receivers
@@ -78,19 +71,19 @@ config LIRC_SERIAL_TRANSMITTER
config LIRC_SIR
tristate "Built-in SIR IrDA port"
- depends on LIRC_STAGING
+ depends on LIRC
help
Driver for the SIR IrDA port
config LIRC_TTUSBIR
tristate "Technotrend USB IR Receiver"
- depends on LIRC_STAGING && USB
+ depends on LIRC && USB
help
Driver for the Technotrend USB IR Receiver
config LIRC_ZILOG
tristate "Zilog/Hauppauge IR Transmitter"
- depends on LIRC_STAGING && I2C
+ depends on LIRC && I2C
help
Driver for the Zilog/Hauppauge IR Transmitter, found on
PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile
index 4da1f3397a16..94af218d8373 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/lirc/Makefile
@@ -4,7 +4,6 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
-obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o
obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
diff --git a/drivers/staging/lirc/TODO.lirc_i2c b/drivers/staging/lirc/TODO.lirc_i2c
deleted file mode 100644
index 1f0a6ff65439..000000000000
--- a/drivers/staging/lirc/TODO.lirc_i2c
+++ /dev/null
@@ -1,3 +0,0 @@
-lirc_i2c provides support for some drivers that have already a RC
-driver under drivers/media/video. It should be integrated into those
-drivers, in special with drivers/media/video/ir-kbd-i2c.c.
diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog
new file mode 100644
index 000000000000..6aa312df4018
--- /dev/null
+++ b/drivers/staging/lirc/TODO.lirc_zilog
@@ -0,0 +1,13 @@
+The binding between hdpvr and lirc_zilog is currently disabled,
+due to an OOPS reported a few years ago when both the hdpvr and cx18
+drivers were loaded in his system. More details can be seen at:
+ http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html
+More tests need to be done, in order to fix the reported issue.
+
+There's a conflict between ir-kbd-i2c: Both provide support for RX events.
+Such conflict needs to be fixed, before moving it out of staging.
+
+The way I2C probe works, it will try to register the driver twice, one
+for RX and another for TX. The logic needs to be fixed to avoid such
+issue.
+
diff --git a/drivers/staging/lirc/lirc_i2c.c b/drivers/staging/lirc/lirc_i2c.c
deleted file mode 100644
index 6df2c0e8d721..000000000000
--- a/drivers/staging/lirc/lirc_i2c.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * lirc_i2c.c
- *
- * i2c IR driver for the onboard IR port on many TV tuner cards, including:
- * -Flavors of the Hauppauge PVR-150/250/350
- * -Hauppauge HVR-1300
- * -PixelView (BT878P+W/FM)
- * -KNC ONE TV Station/Anubis Typhoon TView Tuner
- * -Asus TV-Box and Creative/VisionTek BreakOut-Box
- * -Leadtek Winfast PVR2000
- *
- * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- * modified for PixelView (BT878P+W/FM) by
- * Michal Kochanowicz <mkochano@pld.org.pl>
- * Christoph Bartelmus <lirc@bartelmus.de>
- * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
- * Ulrich Mueller <ulrich.mueller42@web.de>
- * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
- * Stefan Jahn <stefan@lkcc.org>
- * modified for inclusion into kernel sources by
- * Jerome Brock <jbrock@users.sourceforge.net>
- * modified for Leadtek Winfast PVR2000 by
- * Thomas Reitmayr (treitmayr@yahoo.com)
- * modified for Hauppauge HVR-1300 by
- * Jan Frey (jfrey@gmx.de)
- *
- * parts are cut&pasted from the old lirc_haup.c driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include <media/lirc_dev.h>
-
-struct IR {
- struct lirc_driver l;
- struct i2c_client c;
- int nextkey;
- unsigned char b[3];
- unsigned char bits;
- unsigned char flag;
-};
-
-#define DEVICE_NAME "lirc_i2c"
-
-/* module parameters */
-static int debug; /* debug output */
-static int minor = -1; /* minor number */
-
-#define dprintk(fmt, args...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG DEVICE_NAME ": " fmt, \
- ## args); \
- } while (0)
-
-static int reverse(int data, int bits)
-{
- int i;
- int c;
-
- for (c = 0, i = 0; i < bits; i++)
- c |= ((data & (1<<i)) ? 1 : 0) << (bits-1-i);
-
- return c;
-}
-
-static int add_to_buf_adap(void *data, struct lirc_buffer *buf)
-{
- struct IR *ir = data;
- unsigned char keybuf[4];
-
- keybuf[0] = 0x00;
- i2c_master_send(&ir->c, keybuf, 1);
- /* poll IR chip */
- if (i2c_master_recv(&ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) {
- dprintk("read error\n");
- return -EIO;
- }
-
- dprintk("key (0x%02x%02x%02x%02x)\n",
- keybuf[0], keybuf[1], keybuf[2], keybuf[3]);
-
- /* key pressed ? */
- if (keybuf[2] == 0xff)
- return -ENODATA;
-
- /* remove repeat bit */
- keybuf[2] &= 0x7f;
- keybuf[3] |= 0x80;
-
- lirc_buffer_write(buf, keybuf);
- return 0;
-}
-
-static int add_to_buf_pcf8574(void *data, struct lirc_buffer *buf)
-{
- struct IR *ir = data;
- int rc;
- unsigned char all, mask;
- unsigned char key;
-
- /* compute all valid bits (key code + pressed/release flag) */
- all = ir->bits | ir->flag;
-
- /* save IR writable mask bits */
- mask = i2c_smbus_read_byte(&ir->c) & ~all;
-
- /* send bit mask */
- rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask);
-
- /* receive scan code */
- rc = i2c_smbus_read_byte(&ir->c);
-
- if (rc == -1) {
- dprintk("%s read error\n", ir->c.name);
- return -EIO;
- }
-
- /* drop duplicate polls */
- if (ir->b[0] == (rc & all))
- return -ENODATA;
-
- ir->b[0] = rc & all;
-
- dprintk("%s key 0x%02X %s\n", ir->c.name, rc & ir->bits,
- (rc & ir->flag) ? "released" : "pressed");
-
- /* ignore released buttons */
- if (rc & ir->flag)
- return -ENODATA;
-
- /* set valid key code */
- key = rc & ir->bits;
- lirc_buffer_write(buf, &key);
- return 0;
-}
-
-/* common for Hauppauge IR receivers */
-static int add_to_buf_haup_common(void *data, struct lirc_buffer *buf,
- unsigned char *keybuf, int size, int offset)
-{
- struct IR *ir = data;
- __u16 code;
- unsigned char codes[2];
- int ret;
-
- /* poll IR chip */
- ret = i2c_master_recv(&ir->c, keybuf, size);
- if (ret == size) {
- ir->b[0] = keybuf[offset];
- ir->b[1] = keybuf[offset+1];
- ir->b[2] = keybuf[offset+2];
- if (ir->b[0] != 0x00 && ir->b[1] != 0x00)
- dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]);
- } else {
- dprintk("read error (ret=%d)\n", ret);
- /* keep last successful read buffer */
- }
-
- /* key pressed ? */
- if ((ir->b[0] & 0x80) == 0)
- return -ENODATA;
-
- /* look what we have */
- code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2);
-
- codes[0] = (code >> 8) & 0xff;
- codes[1] = code & 0xff;
-
- /* return it */
- dprintk("sending code 0x%02x%02x to lirc\n", codes[0], codes[1]);
- lirc_buffer_write(buf, codes);
- return 0;
-}
-
-/* specific for the Hauppauge PVR150 IR receiver */
-static int add_to_buf_haup_pvr150(void *data, struct lirc_buffer *buf)
-{
- unsigned char keybuf[6];
- /* fetch 6 bytes, first relevant is at offset 3 */
- return add_to_buf_haup_common(data, buf, keybuf, 6, 3);
-}
-
-/* used for all Hauppauge IR receivers but the PVR150 */
-static int add_to_buf_haup(void *data, struct lirc_buffer *buf)
-{
- unsigned char keybuf[3];
- /* fetch 3 bytes, first relevant is at offset 0 */
- return add_to_buf_haup_common(data, buf, keybuf, 3, 0);
-}
-
-
-static int add_to_buf_pvr2000(void *data, struct lirc_buffer *buf)
-{
- struct IR *ir = data;
- unsigned char key;
- s32 flags;
- s32 code;
-
- /* poll IR chip */
- flags = i2c_smbus_read_byte_data(&ir->c, 0x10);
- if (-1 == flags) {
- dprintk("read error\n");
- return -ENODATA;
- }
- /* key pressed ? */
- if (0 == (flags & 0x80))
- return -ENODATA;
-
- /* read actual key code */
- code = i2c_smbus_read_byte_data(&ir->c, 0x00);
- if (-1 == code) {
- dprintk("read error\n");
- return -ENODATA;
- }
-
- key = code & 0xFF;
-
- dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", key, flags & 0xFF);
-
- /* return it */
- lirc_buffer_write(buf, &key);
- return 0;
-}
-
-static int add_to_buf_pixelview(void *data, struct lirc_buffer *buf)
-{
- struct IR *ir = data;
- unsigned char key;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(&ir->c, &key, 1)) {
- dprintk("read error\n");
- return -1;
- }
- dprintk("key %02x\n", key);
-
- /* return it */
- lirc_buffer_write(buf, &key);
- return 0;
-}
-
-static int add_to_buf_pv951(void *data, struct lirc_buffer *buf)
-{
- struct IR *ir = data;
- unsigned char key;
- unsigned char codes[4];
-
- /* poll IR chip */
- if (1 != i2c_master_recv(&ir->c, &key, 1)) {
- dprintk("read error\n");
- return -ENODATA;
- }
- /* ignore 0xaa */
- if (key == 0xaa)
- return -ENODATA;
- dprintk("key %02x\n", key);
-
- codes[0] = 0x61;
- codes[1] = 0xD6;
- codes[2] = reverse(key, 8);
- codes[3] = (~codes[2])&0xff;
-
- lirc_buffer_write(buf, codes);
- return 0;
-}
-
-static int add_to_buf_knc1(void *data, struct lirc_buffer *buf)
-{
- static unsigned char last_key = 0xFF;
- struct IR *ir = data;
- unsigned char key;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(&ir->c, &key, 1)) {
- dprintk("read error\n");
- return -ENODATA;
- }
-
- /*
- * it seems that 0xFE indicates that a button is still held
- * down, while 0xFF indicates that no button is held
- * down. 0xFE sequences are sometimes interrupted by 0xFF
- */
-
- dprintk("key %02x\n", key);
-
- if (key == 0xFF)
- return -ENODATA;
-
- if (key == 0xFE)
- key = last_key;
-
- last_key = key;
- lirc_buffer_write(buf, &key);
-
- return 0;
-}
-
-static int set_use_inc(void *data)
-{
- struct IR *ir = data;
-
- dprintk("%s called\n", __func__);
-
- /* lock bttv in memory while /dev/lirc is in use */
- i2c_use_client(&ir->c);
-
- return 0;
-}
-
-static void set_use_dec(void *data)
-{
- struct IR *ir = data;
-
- dprintk("%s called\n", __func__);
-
- i2c_release_client(&ir->c);
-}
-
-static struct lirc_driver lirc_template = {
- .name = "lirc_i2c",
- .set_use_inc = set_use_inc,
- .set_use_dec = set_use_dec,
- .dev = NULL,
- .owner = THIS_MODULE,
-};
-
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
-static int ir_remove(struct i2c_client *client);
-static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg);
-
-static const struct i2c_device_id ir_receiver_id[] = {
- /* Generic entry for any IR receiver */
- { "ir_video", 0 },
- /* IR device specific entries could be added here */
- { }
-};
-
-static struct i2c_driver driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "i2c ir driver",
- },
- .probe = ir_probe,
- .remove = ir_remove,
- .id_table = ir_receiver_id,
- .command = ir_command,
-};
-
-static void pcf_probe(struct i2c_client *client, struct IR *ir)
-{
- int ret1, ret2, ret3, ret4;
-
- ret1 = i2c_smbus_write_byte(client, 0xff);
- ret2 = i2c_smbus_read_byte(client);
- ret3 = i2c_smbus_write_byte(client, 0x00);
- ret4 = i2c_smbus_read_byte(client);
-
- /* in the Asus TV-Box: bit 1-0 */
- if (((ret2 & 0x03) == 0x03) && ((ret4 & 0x03) == 0x00)) {
- ir->bits = (unsigned char) ~0x07;
- ir->flag = 0x04;
- /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */
- } else if (((ret2 & 0xc0) == 0xc0) && ((ret4 & 0xc0) == 0x00)) {
- ir->bits = (unsigned char) ~0xe0;
- ir->flag = 0x20;
- }
-
- return;
-}
-
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct IR *ir;
- struct i2c_adapter *adap = client->adapter;
- unsigned short addr = client->addr;
- int retval;
-
- ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
- if (!ir)
- return -ENOMEM;
- memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
- memcpy(&ir->c, client, sizeof(struct i2c_client));
-
- i2c_set_clientdata(client, ir);
- ir->l.data = ir;
- ir->l.minor = minor;
- ir->l.sample_rate = 10;
- ir->l.dev = &ir->c.dev;
- ir->nextkey = -1;
-
- switch (addr) {
- case 0x64:
- strlcpy(ir->c.name, "Pixelview IR", I2C_NAME_SIZE);
- ir->l.code_length = 8;
- ir->l.add_to_buf = add_to_buf_pixelview;
- break;
- case 0x4b:
- strlcpy(ir->c.name, "PV951 IR", I2C_NAME_SIZE);
- ir->l.code_length = 32;
- ir->l.add_to_buf = add_to_buf_pv951;
- break;
- case 0x71:
- if (adap->id == I2C_HW_B_CX2388x)
- strlcpy(ir->c.name, "Hauppauge HVR1300", I2C_NAME_SIZE);
- else /* bt8xx or cx2341x */
- /*
- * The PVR150 IR receiver uses the same protocol as
- * other Hauppauge cards, but the data flow is
- * different, so we need to deal with it by its own.
- */
- strlcpy(ir->c.name, "Hauppauge PVR150", I2C_NAME_SIZE);
- ir->l.code_length = 13;
- ir->l.add_to_buf = add_to_buf_haup_pvr150;
- break;
- case 0x6b:
- strlcpy(ir->c.name, "Adaptec IR", I2C_NAME_SIZE);
- ir->l.code_length = 32;
- ir->l.add_to_buf = add_to_buf_adap;
- break;
- case 0x18:
- case 0x1a:
- if (adap->id == I2C_HW_B_CX2388x) {
- strlcpy(ir->c.name, "Leadtek IR", I2C_NAME_SIZE);
- ir->l.code_length = 8;
- ir->l.add_to_buf = add_to_buf_pvr2000;
- } else { /* bt8xx or cx2341x */
- strlcpy(ir->c.name, "Hauppauge IR", I2C_NAME_SIZE);
- ir->l.code_length = 13;
- ir->l.add_to_buf = add_to_buf_haup;
- }
- break;
- case 0x30:
- strlcpy(ir->c.name, "KNC ONE IR", I2C_NAME_SIZE);
- ir->l.code_length = 8;
- ir->l.add_to_buf = add_to_buf_knc1;
- break;
- case 0x21:
- case 0x23:
- pcf_probe(client, ir);
- strlcpy(ir->c.name, "TV-Box IR", I2C_NAME_SIZE);
- ir->l.code_length = 8;
- ir->l.add_to_buf = add_to_buf_pcf8574;
- break;
- default:
- /* shouldn't happen */
- printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n", addr);
- kfree(ir);
- return -EINVAL;
- }
- printk(KERN_INFO "lirc_i2c: chip 0x%x found @ 0x%02x (%s)\n",
- adap->id, addr, ir->c.name);
-
- retval = lirc_register_driver(&ir->l);
-
- if (retval < 0) {
- printk(KERN_ERR "lirc_i2c: failed to register driver!\n");
- kfree(ir);
- return retval;
- }
-
- ir->l.minor = retval;
-
- return 0;
-}
-
-static int ir_remove(struct i2c_client *client)
-{
- struct IR *ir = i2c_get_clientdata(client);
-
- /* unregister device */
- lirc_unregister_driver(ir->l.minor);
-
- /* free memory */
- kfree(ir);
- return 0;
-}
-
-static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- /* nothing */
- return 0;
-}
-
-static int __init lirc_i2c_init(void)
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-static void __exit lirc_i2c_exit(void)
-{
- i2c_del_driver(&driver);
-}
-
-MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and "
- "Pixelview cards (i2c stack)");
-MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, "
- "Ulrich Mueller, Stefan Jahn, Jerome Brock");
-MODULE_LICENSE("GPL");
-
-module_param(minor, int, S_IRUGO);
-MODULE_PARM_DESC(minor, "Preferred minor device number");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Enable debugging messages");
-
-module_init(lirc_i2c_init);
-module_exit(lirc_i2c_exit);
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index f0076eb025f1..ad29bb1275ab 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -66,6 +66,7 @@ struct IR {
/* Device info */
struct mutex ir_lock;
int open;
+ bool is_hdpvr;
/* RX device */
struct i2c_client c_rx;
@@ -206,16 +207,12 @@ static int add_to_buf(struct IR *ir)
}
/* key pressed ? */
-#ifdef I2C_HW_B_HDPVR
- if (ir->c_rx.adapter->id == I2C_HW_B_HDPVR) {
+ if (ir->is_hdpvr) {
if (got_data && (keybuf[0] == 0x80))
return 0;
else if (got_data && (keybuf[0] == 0x00))
return -ENODATA;
} else if ((ir->b[0] & 0x80) == 0)
-#else
- if ((ir->b[0] & 0x80) == 0)
-#endif
return got_data ? 0 : -ENODATA;
/* look what we have */
@@ -841,15 +838,15 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key)
return ret < 0 ? ret : -EFAULT;
}
-#ifdef I2C_HW_B_HDPVR
/*
* The sleep bits aren't necessary on the HD PVR, and in fact, the
* last i2c_master_recv always fails with a -5, so for now, we're
* going to skip this whole mess and say we're done on the HD PVR
*/
- if (ir->c_rx.adapter->id == I2C_HW_B_HDPVR)
- goto done;
-#endif
+ if (ir->is_hdpvr) {
+ dprintk("sent code %u, key %u\n", code, key);
+ return 0;
+ }
/*
* This bit NAKs until the device is ready, so we retry it
@@ -883,7 +880,6 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key)
return -EFAULT;
}
-done:
/* Oh good, it worked */
dprintk("sent code %u, key %u\n", code, key);
return 0;
@@ -1112,12 +1108,14 @@ static int ir_remove(struct i2c_client *client);
static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg);
+#define ID_FLAG_TX 0x01
+#define ID_FLAG_HDPVR 0x02
+
static const struct i2c_device_id ir_transceiver_id[] = {
- /* Generic entry for any IR transceiver */
- { "ir_video", 0 },
- /* IR device specific entries should be added here */
- { "ir_tx_z8f0811_haup", 0 },
- { "ir_rx_z8f0811_haup", 0 },
+ { "ir_tx_z8f0811_haup", ID_FLAG_TX },
+ { "ir_rx_z8f0811_haup", 0 },
+ { "ir_tx_z8f0811_hdpvr", ID_FLAG_HDPVR | ID_FLAG_TX },
+ { "ir_rx_z8f0811_hdpvr", ID_FLAG_HDPVR },
{ }
};
@@ -1197,10 +1195,25 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
int ret;
int have_rx = 0, have_tx = 0;
- dprintk("%s: adapter id=0x%x, client addr=0x%02x\n",
- __func__, adap->id, client->addr);
+ dprintk("%s: adapter name (%s) nr %d, i2c_device_id name (%s), "
+ "client addr=0x%02x\n",
+ __func__, adap->name, adap->nr, id->name, client->addr);
/*
+ * FIXME - This probe function probes both the Tx and Rx
+ * addresses of the IR microcontroller.
+ *
+ * However, the I2C subsystem is passing along one I2C client at a
+ * time, based on matches to the ir_transceiver_id[] table above.
+ * The expectation is that each i2c_client address will be probed
+ * individually by drivers so the I2C subsystem can mark all client
+ * addresses as claimed or not.
+ *
+ * This probe routine causes only one of the client addresses, TX or RX,
+ * to be claimed. This will cause a problem if the I2C subsystem is
+ * subsequently triggered to probe unclaimed clients again.
+ */
+ /*
* The external IR receiver is at i2c address 0x71.
* The IR transmitter is at 0x70.
*/
@@ -1242,6 +1255,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
mutex_init(&ir->ir_lock);
mutex_init(&ir->buf_lock);
ir->need_boot = 1;
+ ir->is_hdpvr = (id->driver_data & ID_FLAG_HDPVR) ? true : false;
memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
ir->l.minor = -1;
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index 61685ccceda8..cc8d2840f9b6 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -826,6 +826,13 @@ const struct address_space_operations pohmelfs_aops = {
.set_page_dirty = __set_page_dirty_nobuffers,
};
+static void pohmelfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(pohmelfs_inode_cache, POHMELFS_I(inode));
+}
+
/*
* ->detroy_inode() callback. Deletes inode from the caches
* and frees private data.
@@ -842,8 +849,8 @@ static void pohmelfs_destroy_inode(struct inode *inode)
dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
__func__, pi, &pi->vfs_inode, pi->ino);
- kmem_cache_free(pohmelfs_inode_cache, pi);
atomic_long_dec(&psb->total_inodes);
+ call_rcu(&inode->i_rcu, pohmelfs_i_callback);
}
/*
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
index 8ec83d2dffb7..400a9fc386ad 100644
--- a/drivers/staging/pohmelfs/path_entry.c
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -83,10 +83,11 @@ out:
int pohmelfs_path_length(struct pohmelfs_inode *pi)
{
struct dentry *d, *root, *first;
- int len = 1; /* Root slash */
+ int len;
+ unsigned seq;
- first = d = d_find_alias(&pi->vfs_inode);
- if (!d) {
+ first = d_find_alias(&pi->vfs_inode);
+ if (!first) {
dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
return -ENOENT;
}
@@ -95,7 +96,11 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
root = dget(current->fs->root.dentry);
spin_unlock(&current->fs->lock);
- spin_lock(&dcache_lock);
+rename_retry:
+ len = 1; /* Root slash */
+ d = first;
+ seq = read_seqbegin(&rename_lock);
+ rcu_read_lock();
if (!IS_ROOT(d) && d_unhashed(d))
len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
@@ -104,7 +109,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
len += d->d_name.len + 1; /* Plus slash */
d = d->d_parent;
}
- spin_unlock(&dcache_lock);
+ rcu_read_unlock();
+ if (read_seqretry(&rename_lock, seq))
+ goto rename_retry;
dput(root);
dput(first);
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
index d746715d3d89..d83bec876d2e 100644
--- a/drivers/staging/quickstart/quickstart.c
+++ b/drivers/staging/quickstart/quickstart.c
@@ -355,7 +355,6 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type)
static void quickstart_exit(void)
{
input_unregister_device(quickstart_input);
- input_free_device(quickstart_input);
device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
device_remove_file(&pf_device->dev, &dev_attr_buttons);
@@ -375,6 +374,7 @@ static int __init quickstart_init_input(void)
{
struct quickstart_btn **ptr = &quickstart_data.btn_lst;
int count;
+ int ret;
quickstart_input = input_allocate_device();
@@ -391,7 +391,13 @@ static int __init quickstart_init_input(void)
ptr = &((*ptr)->next);
}
- return input_register_device(quickstart_input);
+ ret = input_register_device(quickstart_input);
+ if (ret) {
+ input_free_device(quickstart_input);
+ return ret;
+ }
+
+ return 0;
}
static int __init quickstart_init(void)
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index ddacfc6c4861..cd15daae5412 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -182,6 +182,7 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */
{USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */
{USB_DEVICE(0x2019, 0xED14)}, /* Planex Communications, Inc. */
+ {USB_DEVICE(0x0411, 0x015D)}, /* Buffalo Airstation WLI-UC-GN */
{} /* Terminating entry */
};
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index 46000d72f4c4..3bdf9b31cc4e 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -264,8 +264,12 @@ HwHSSIThreeWire(
udelay(10);
}
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
- panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
+ if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+ printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
+ " %#X RE|WE bits are not clear!!\n", u1bTmp);
+ dump_stack();
+ return 0;
+ }
/* RTL8187S HSSI Read/Write Function */
u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
@@ -298,13 +302,23 @@ HwHSSIThreeWire(
int idx;
int ByteCnt = nDataBufBitCnt / 8;
/* printk("%d\n",nDataBufBitCnt); */
- if ((nDataBufBitCnt % 8) != 0)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
- nDataBufBitCnt);
+ if ((nDataBufBitCnt % 8) != 0) {
+ printk(KERN_ERR "rtl8187se: "
+ "HwThreeWire(): nDataBufBitCnt(%d)"
+ " should be multiple of 8!!!\n",
+ nDataBufBitCnt);
+ dump_stack();
+ nDataBufBitCnt += 8;
+ nDataBufBitCnt &= ~7;
+ }
- if (nDataBufBitCnt > 64)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
- nDataBufBitCnt);
+ if (nDataBufBitCnt > 64) {
+ printk(KERN_ERR "rtl8187se: HwThreeWire():"
+ " nDataBufBitCnt(%d) should <= 64!!!\n",
+ nDataBufBitCnt);
+ dump_stack();
+ nDataBufBitCnt = 64;
+ }
for (idx = 0; idx < ByteCnt; idx++)
write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c
index f6569dce3012..0e9483bbabe1 100644
--- a/drivers/staging/rtl8712/usb_halinit.c
+++ b/drivers/staging/rtl8712/usb_halinit.c
@@ -37,7 +37,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
{
u8 val8 = 0;
u8 ret = _SUCCESS;
- u8 PollingCnt = 20;
+ int PollingCnt = 20;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
if (pregistrypriv->chip_version == RTL8712_FPGA) {
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
index eb44b60e1eb5..ac2bf11e1119 100644
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
@@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev,
}
return count;
}
-static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO,
get_silent_state, set_silent_state);
diff --git a/drivers/staging/se401/Kconfig b/drivers/staging/se401/Kconfig
new file mode 100644
index 000000000000..b7f8222ad21b
--- /dev/null
+++ b/drivers/staging/se401/Kconfig
@@ -0,0 +1,13 @@
+config USB_SE401
+ tristate "USB SE401 Camera support (DEPRECATED)"
+ depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
+ ---help---
+ Say Y here if you want to connect this type of camera to your
+ computer's USB port. See <file:Documentation/video4linux/se401.txt>
+ for more information and for a list of supported cameras.
+
+ This driver uses the deprecated V4L1 API and will be removed in
+ 2.6.39, unless someone converts it to the V4L2 API.
+
+ To compile this driver as a module, choose M here: the
+ module will be called se401.
diff --git a/drivers/staging/se401/Makefile b/drivers/staging/se401/Makefile
new file mode 100644
index 000000000000..b465d49783af
--- /dev/null
+++ b/drivers/staging/se401/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SE401) += se401.o
diff --git a/drivers/staging/se401/TODO b/drivers/staging/se401/TODO
new file mode 100644
index 000000000000..3b2c03836286
--- /dev/null
+++ b/drivers/staging/se401/TODO
@@ -0,0 +1,5 @@
+This is an obsolete driver for some old webcams that still use V4L1 API.
+As V4L1 support is being removed from kernel, if nobody take care on it,
+the driver will be removed for 2.6.39.
+
+Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/media/video/se401.c b/drivers/staging/se401/se401.c
index 41360d7c3e96..41360d7c3e96 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/staging/se401/se401.c
diff --git a/drivers/media/video/se401.h b/drivers/staging/se401/se401.h
index bf7d2e9765b0..2758f4716c3d 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/staging/se401/se401.h
@@ -3,7 +3,7 @@
#define __LINUX_se401_H
#include <linux/uaccess.h>
-#include <linux/videodev.h>
+#include "videodev.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
diff --git a/include/linux/videodev.h b/drivers/staging/se401/videodev.h
index b19eab140977..f11efbef1c05 100644
--- a/include/linux/videodev.h
+++ b/drivers/staging/se401/videodev.h
@@ -16,25 +16,6 @@
#include <linux/ioctl.h>
#include <linux/videodev2.h>
-#if defined(__MIN_V4L1) && defined (__KERNEL__)
-
-/*
- * Used by those V4L2 core functions that need a minimum V4L1 support,
- * in order to allow V4L1 Compatibilty code compilation.
- */
-
-struct video_mbuf
-{
- int size; /* Total memory to map */
- int frames; /* Frames */
- int offsets[VIDEO_MAX_FRAME];
-};
-
-#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
-
-#else
-#if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
-
#define VID_TYPE_CAPTURE 1 /* Can capture */
#define VID_TYPE_TUNER 2 /* Can tune */
#define VID_TYPE_TELETEXT 4 /* Does teletext */
@@ -328,9 +309,6 @@ struct video_code
#define VID_PLAY_RESET 13
#define VID_PLAY_END_MARK 14
-#endif /* CONFIG_VIDEO_V4L1_COMPAT */
-#endif /* __MIN_V4L1 */
-
#endif /* __LINUX_VIDEODEV_H */
/*
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index 24f47d6388f4..7162dee3b0d8 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
/* when resuming, restore pci data and fb cursor */
if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
retv = pci_set_power_state(pdev, PCI_D0);
- retv = pci_restore_state(pdev);
+ pci_restore_state(pdev);
if (pci_enable_device(pdev))
return -1;
pci_set_master(pdev);
diff --git a/drivers/staging/smbfs/cache.c b/drivers/staging/smbfs/cache.c
index dbb98658148b..f2a1323ca827 100644
--- a/drivers/staging/smbfs/cache.c
+++ b/drivers/staging/smbfs/cache.c
@@ -62,7 +62,7 @@ smb_invalidate_dircache_entries(struct dentry *parent)
struct list_head *next;
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -70,7 +70,7 @@ smb_invalidate_dircache_entries(struct dentry *parent)
smb_age_dentry(server, dentry);
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
/*
@@ -96,13 +96,13 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
}
/* If a pointer is invalid, we search the dentry. */
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dent = list_entry(next, struct dentry, d_u.d_child);
if ((unsigned long)dent->d_fsdata == fpos) {
if (dent->d_inode)
- dget_locked(dent);
+ dget(dent);
else
dent = NULL;
goto out_unlock;
@@ -111,7 +111,7 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
}
dent = NULL;
out_unlock:
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
return dent;
}
@@ -134,7 +134,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
qname->hash = full_name_hash(qname->name, qname->len);
if (dentry->d_op && dentry->d_op->d_hash)
- if (dentry->d_op->d_hash(dentry, qname) != 0)
+ if (dentry->d_op->d_hash(dentry, inode, qname) != 0)
goto end_advance;
newdent = d_lookup(dentry, qname);
@@ -145,8 +145,8 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
goto end_advance;
} else {
hashed = 1;
- memcpy((char *) newdent->d_name.name, qname->name,
- newdent->d_name.len);
+ /* dir i_mutex is locked because we're in readdir */
+ dentry_update_name_case(newdent, qname);
}
if (!newdent->d_inode) {
diff --git a/drivers/staging/smbfs/dir.c b/drivers/staging/smbfs/dir.c
index f088ea2f6ac9..78f09412740c 100644
--- a/drivers/staging/smbfs/dir.c
+++ b/drivers/staging/smbfs/dir.c
@@ -274,9 +274,13 @@ smb_dir_open(struct inode *dir, struct file *file)
* Dentry operations routines
*/
static int smb_lookup_validate(struct dentry *, struct nameidata *);
-static int smb_hash_dentry(struct dentry *, struct qstr *);
-static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
-static int smb_delete_dentry(struct dentry *);
+static int smb_hash_dentry(const struct dentry *, const struct inode *,
+ struct qstr *);
+static int smb_compare_dentry(const struct dentry *,
+ const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
+static int smb_delete_dentry(const struct dentry *);
static const struct dentry_operations smbfs_dentry_operations =
{
@@ -333,7 +337,8 @@ smb_lookup_validate(struct dentry * dentry, struct nameidata *nd)
}
static int
-smb_hash_dentry(struct dentry *dir, struct qstr *this)
+smb_hash_dentry(const struct dentry *dir, const struct inode *inode,
+ struct qstr *this)
{
unsigned long hash;
int i;
@@ -347,14 +352,17 @@ smb_hash_dentry(struct dentry *dir, struct qstr *this)
}
static int
-smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
+smb_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
int i, result = 1;
- if (a->len != b->len)
+ if (len != name->len)
goto out;
- for (i=0; i < a->len; i++) {
- if (tolower(a->name[i]) != tolower(b->name[i]))
+ for (i=0; i < len; i++) {
+ if (tolower(str[i]) != tolower(name->name[i]))
goto out;
}
result = 0;
@@ -367,7 +375,7 @@ out:
* We use this to unhash dentries with bad inodes.
*/
static int
-smb_delete_dentry(struct dentry * dentry)
+smb_delete_dentry(const struct dentry *dentry)
{
if (dentry->d_inode) {
if (is_bad_inode(dentry->d_inode)) {
@@ -390,9 +398,9 @@ smb_new_dentry(struct dentry *dentry)
struct smb_sb_info *server = server_from_dentry(dentry);
if (server->mnt->flags & SMB_MOUNT_CASE)
- dentry->d_op = &smbfs_dentry_operations_case;
+ d_set_d_op(dentry, &smbfs_dentry_operations_case);
else
- dentry->d_op = &smbfs_dentry_operations;
+ d_set_d_op(dentry, &smbfs_dentry_operations);
dentry->d_time = jiffies;
}
@@ -454,9 +462,9 @@ smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
add_entry:
server = server_from_dentry(dentry);
if (server->mnt->flags & SMB_MOUNT_CASE)
- dentry->d_op = &smbfs_dentry_operations_case;
+ d_set_d_op(dentry, &smbfs_dentry_operations_case);
else
- dentry->d_op = &smbfs_dentry_operations;
+ d_set_d_op(dentry, &smbfs_dentry_operations);
d_add(dentry, inode);
smb_renew_times(dentry);
diff --git a/drivers/staging/smbfs/inode.c b/drivers/staging/smbfs/inode.c
index 540a984bb516..244319dc9702 100644
--- a/drivers/staging/smbfs/inode.c
+++ b/drivers/staging/smbfs/inode.c
@@ -62,11 +62,18 @@ static struct inode *smb_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void smb_destroy_inode(struct inode *inode)
+static void smb_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(smb_inode_cachep, SMB_I(inode));
}
+static void smb_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, smb_i_callback);
+}
+
static void init_once(void *foo)
{
struct smb_inode_info *ei = (struct smb_inode_info *) foo;
diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c
index adb93f21c0d6..65b231178f05 100644
--- a/drivers/staging/speakup/fakekey.c
+++ b/drivers/staging/speakup/fakekey.c
@@ -62,7 +62,6 @@ void speakup_remove_virtual_keyboard(void)
{
if (virt_keyboard != NULL) {
input_unregister_device(virt_keyboard);
- input_free_device(virt_keyboard);
virt_keyboard = NULL;
}
}
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index cc79f9edfe9e..408bb9b3303e 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -984,8 +984,10 @@ int speakup_kobj_init(void)
* not known ahead of time.
*/
accessibility_kobj = kobject_create_and_add("accessibility", NULL);
- if (!accessibility_kobj)
- return -ENOMEM;
+ if (!accessibility_kobj) {
+ retval = -ENOMEM;
+ goto out;
+ }
speakup_kobj = kobject_create_and_add("speakup", accessibility_kobj);
if (!speakup_kobj) {
@@ -1002,7 +1004,7 @@ int speakup_kobj_init(void)
if (retval)
goto err_group;
- return 0;
+ goto out;
err_group:
sysfs_remove_group(speakup_kobj, &main_attr_group);
@@ -1010,6 +1012,7 @@ err_speakup:
kobject_put(speakup_kobj);
err_acc:
kobject_put(accessibility_kobj);
+out:
return retval;
}
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 4b7a9c2b965f..3cd00396a462 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -2253,17 +2253,17 @@ static int __init speakup_init(void)
err = speakup_add_virtual_keyboard();
if (err)
- return err;
+ goto out;
initialize_msgs(); /* Initialize arrays for i18n. */
first_console = kzalloc(sizeof(*first_console), GFP_KERNEL);
- if (!first_console)
- return -ENOMEM;
- err = speakup_kobj_init();
- if (err) {
- kfree(first_console);
- return err;
+ if (!first_console) {
+ err = -ENOMEM;
+ goto err_cons;
}
+ err = speakup_kobj_init();
+ if (err)
+ goto err_kobject;
reset_default_chars();
reset_default_chartab();
@@ -2299,11 +2299,20 @@ static int __init speakup_init(void)
speakup_task = kthread_create(speakup_thread, NULL, "speakup");
set_user_nice(speakup_task, 10);
- if (!IS_ERR(speakup_task))
- wake_up_process(speakup_task);
- else
- return -ENOMEM;
- return 0;
+ if (IS_ERR(speakup_task)) {
+ err = -ENOMEM;
+ goto err_kobject;
+ }
+ wake_up_process(speakup_task);
+ goto out;
+
+err_kobject:
+speakup_kobj_exit();
+ kfree(first_console);
+err_cons:
+ speakup_remove_virtual_keyboard();
+out:
+ return err;
}
module_init(speakup_init);
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
index c7932da03c56..63a9d0adf32d 100644
--- a/drivers/staging/spectra/ffsport.c
+++ b/drivers/staging/spectra/ffsport.c
@@ -656,7 +656,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
/* Here we force report 512 byte hardware sector size to Kernel */
blk_queue_logical_block_size(dev->queue, 512);
- blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
+ blk_queue_flush(dev->queue, REQ_FLUSH);
dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
if (IS_ERR(dev->thread)) {
diff --git a/drivers/staging/stradis/Kconfig b/drivers/staging/stradis/Kconfig
deleted file mode 100644
index 02f0fc504cf5..000000000000
--- a/drivers/staging/stradis/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config VIDEO_STRADIS
- tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)"
- depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS && BKL
- help
- Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
- driver for PCI. There is a product page at
- <http://www.stradis.com/>.
diff --git a/drivers/staging/stradis/Makefile b/drivers/staging/stradis/Makefile
deleted file mode 100644
index 0f1feab59e39..000000000000
--- a/drivers/staging/stradis/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
-
-EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/staging/stradis/TODO b/drivers/staging/stradis/TODO
deleted file mode 100644
index f48150fe2fa9..000000000000
--- a/drivers/staging/stradis/TODO
+++ /dev/null
@@ -1,6 +0,0 @@
-This is an obsolete driver for ancient stradis hardware.
-We couldn't find anyone with this hardware in order to port it to use V4L2.
-
-If nobody take care on it, the driver will be removed for 2.6.38.
-
-Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/stradis/stradis.c b/drivers/staging/stradis/stradis.c
deleted file mode 100644
index 807dd7eb748f..000000000000
--- a/drivers/staging/stradis/stradis.c
+++ /dev/null
@@ -1,2222 +0,0 @@
-/*
- * stradis.c - stradis 4:2:2 mpeg decoder driver
- *
- * Stradis 4:2:2 MPEG-2 Decoder Driver
- * Copyright (C) 1999 Nathan Laredo <laredo@gnu.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/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <linux/ioport.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/types.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#include "saa7146.h"
-#include "saa7146reg.h"
-#include "ibmmpeg2.h"
-#include "saa7121.h"
-#include "cs8420.h"
-
-#define DEBUG(x) /* debug driver */
-#undef IDEBUG /* debug irq handler */
-#undef MDEBUG /* debug memory management */
-
-#define SAA7146_MAX 6
-
-static struct saa7146 saa7146s[SAA7146_MAX];
-
-static int saa_num; /* number of SAA7146s in use */
-
-static int video_nr = -1;
-module_param(video_nr, int, 0);
-MODULE_LICENSE("GPL");
-
-#define nDebNormal 0x00480000
-#define nDebNoInc 0x00480000
-#define nDebVideo 0xd0480000
-#define nDebAudio 0xd0400000
-#define nDebDMA 0x02c80000
-
-#define oDebNormal 0x13c80000
-#define oDebNoInc 0x13c80000
-#define oDebVideo 0xd1080000
-#define oDebAudio 0xd1080000
-#define oDebDMA 0x03080000
-
-#define NewCard (saa->boardcfg[3])
-#define ChipControl (saa->boardcfg[1])
-#define NTSCFirstActive (saa->boardcfg[4])
-#define PALFirstActive (saa->boardcfg[5])
-#define NTSCLastActive (saa->boardcfg[54])
-#define PALLastActive (saa->boardcfg[55])
-#define Have2MB (saa->boardcfg[18] & 0x40)
-#define HaveCS8420 (saa->boardcfg[18] & 0x04)
-#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20)
-#define HaveCS3310 (saa->boardcfg[18] & 0x01)
-#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31])
-#define HaveCS4341 (saa->boardcfg[40] == 2)
-#define SDIType (saa->boardcfg[27])
-#define CurrentMode (saa->boardcfg[2])
-
-#define debNormal (NewCard ? nDebNormal : oDebNormal)
-#define debNoInc (NewCard ? nDebNoInc : oDebNoInc)
-#define debVideo (NewCard ? nDebVideo : oDebVideo)
-#define debAudio (NewCard ? nDebAudio : oDebAudio)
-#define debDMA (NewCard ? nDebDMA : oDebDMA)
-
-#ifdef USE_RESCUE_EEPROM_SDM275
-static unsigned char rescue_eeprom[64] = {
- 0x00, 0x01, 0x04, 0x13, 0x26, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x43, 0x63,
- 0x22, 0x01, 0x29, 0x15, 0x73, 0x00, 0x1f, 'd', 'e', 'c', 'x', 'l',
- 'd', 'v', 'a', 0x02, 0x00, 0x01, 0x00, 0xcc, 0xa4, 0x63, 0x09, 0xe2,
- 0x10, 0x00, 0x0a, 0x00, 0x02, 0x02, 'd', 'e', 'c', 'x', 'l', 'a',
- 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-};
-#endif
-
-/* ----------------------------------------------------------------------- */
-/* Hardware I2C functions */
-static void I2CWipe(struct saa7146 *saa)
-{
- int i;
- /* set i2c to ~=100kHz, abort transfer, clear busy */
- saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- saawrite(0x600, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- saawrite(0x600, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
-}
-
-/* read I2C */
-static int I2CRead(struct saa7146 *saa, unsigned char addr,
- unsigned char subaddr, int dosub)
-{
- int i;
-
- if (saaread(SAA7146_I2C_STATUS) & 0x3c)
- I2CWipe(saa);
- for (i = 0;
- i < 1000 && (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY);
- i++)
- schedule();
- if (i == 1000)
- I2CWipe(saa);
- if (dosub)
- saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |
- ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);
- else
- saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |
- 0xf1, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- /* wait for valid data */
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)
- return -1;
- if (i == 1000)
- printk("i2c setup read timeout\n");
- saawrite(0x41, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- /* wait for valid data */
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)
- return -1;
- if (i == 1000)
- printk("i2c read timeout\n");
- return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
-}
-
-/* set both to write both bytes, reset it to write only b1 */
-
-static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1,
- unsigned char b2, int both)
-{
- int i;
- u32 data;
-
- if (saaread(SAA7146_I2C_STATUS) & 0x3c)
- I2CWipe(saa);
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (i == 1000)
- I2CWipe(saa);
- data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);
- if (both)
- data |= ((b2 & 0xff) << 8) | 0xe5;
- else
- data |= 0xd1;
- saawrite(data, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,
- SAA7146_MC2);
- return 0;
-}
-
-static void attach_inform(struct saa7146 *saa, int id)
-{
- int i;
-
- DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr,
- id));
- if (id == 0xa0) { /* we have rev2 or later board, fill in info */
- for (i = 0; i < 64; i++)
- saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1);
-#ifdef USE_RESCUE_EEPROM_SDM275
- if (saa->boardcfg[0] != 0) {
- printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE "
- "BEEN IGNORED\n", saa->nr);
- for (i = 0; i < 64; i++)
- saa->boardcfg[i] = rescue_eeprom[i];
- }
-#endif
- printk("stradis%d: config =", saa->nr);
- for (i = 0; i < 51; i++) {
- printk(" %02x", saa->boardcfg[i]);
- }
- printk("\n");
- }
-}
-
-static void I2CBusScan(struct saa7146 *saa)
-{
- int i;
- for (i = 0; i < 0xff; i += 2)
- if ((I2CRead(saa, i, 0, 0)) >= 0)
- attach_inform(saa, i);
-}
-
-static int debiwait_maxwait;
-
-static int wait_for_debi_done(struct saa7146 *saa)
-{
- int i;
-
- /* wait for registers to be programmed */
- for (i = 0; i < 100000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)
- saaread(SAA7146_MC2);
- /* wait for transfer to complete */
- for (i = 0; i < 500000 &&
- (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)
- saaread(SAA7146_MC2);
-
- if (i > debiwait_maxwait)
- printk("wait-for-debi-done maxwait: %d\n",
- debiwait_maxwait = i);
-
- if (i == 500000)
- return -1;
-
- return 0;
-}
-
-static int debiwrite(struct saa7146 *saa, u32 config, int addr,
- u32 val, int count)
-{
- u32 cmd;
- if (count <= 0 || count > 32764)
- return -1;
- if (wait_for_debi_done(saa) < 0)
- return -1;
- saawrite(config, SAA7146_DEBI_CONFIG);
- if (count <= 4) /* immediate transfer */
- saawrite(val, SAA7146_DEBI_AD);
- else /* block transfer */
- saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
- saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);
- saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
- SAA7146_MC2);
- return 0;
-}
-
-static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count)
-{
- u32 result = 0;
-
- if (count > 32764 || count <= 0)
- return 0;
- if (wait_for_debi_done(saa) < 0)
- return 0;
- saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
- saawrite((count << 17) | 0x10000 | (addr & 0xffff),
- SAA7146_DEBI_COMMAND);
- saawrite(config, SAA7146_DEBI_CONFIG);
- saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
- SAA7146_MC2);
- if (count > 4) /* not an immediate transfer */
- return count;
- wait_for_debi_done(saa);
- result = saaread(SAA7146_DEBI_AD);
- if (count == 1)
- result &= 0xff;
- if (count == 2)
- result &= 0xffff;
- if (count == 3)
- result &= 0xffffff;
- return result;
-}
-
-static void do_irq_send_data(struct saa7146 *saa)
-{
- int split, audbytes, vidbytes;
-
- saawrite(SAA7146_PSR_PIN1, SAA7146_IER);
- /* if special feature mode in effect, disable audio sending */
- if (saa->playmode != VID_PLAY_NORMAL)
- saa->audtail = saa->audhead = 0;
- if (saa->audhead <= saa->audtail)
- audbytes = saa->audtail - saa->audhead;
- else
- audbytes = 65536 - (saa->audhead - saa->audtail);
- if (saa->vidhead <= saa->vidtail)
- vidbytes = saa->vidtail - saa->vidhead;
- else
- vidbytes = 524288 - (saa->vidhead - saa->vidtail);
- if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {
- saawrite(0, SAA7146_IER);
- return;
- }
- /* if at least 1 block audio waiting and audio fifo isn't full */
- if (audbytes >= 2048 && (debiread(saa, debNormal, IBM_MP2_AUD_FIFO, 2)
- & 0xff) < 60) {
- if (saa->audhead > saa->audtail)
- split = 65536 - saa->audhead;
- else
- split = 0;
- audbytes = 2048;
- if (split > 0 && split < 2048) {
- memcpy(saa->dmadebi, saa->audbuf + saa->audhead, split);
- saa->audhead = 0;
- audbytes -= split;
- } else
- split = 0;
- memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,
- audbytes);
- saa->audhead += audbytes;
- saa->audhead &= 0xffff;
- debiwrite(saa, debAudio, (NewCard ? IBM_MP2_AUD_FIFO :
- IBM_MP2_AUD_FIFOW), 0, 2048);
- wake_up_interruptible(&saa->audq);
- /* if at least 1 block video waiting and video fifo isn't full */
- } else if (vidbytes >= 30720 && (debiread(saa, debNormal,
- IBM_MP2_FIFO, 2)) < 16384) {
- if (saa->vidhead > saa->vidtail)
- split = 524288 - saa->vidhead;
- else
- split = 0;
- vidbytes = 30720;
- if (split > 0 && split < 30720) {
- memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead, split);
- saa->vidhead = 0;
- vidbytes -= split;
- } else
- split = 0;
- memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead,
- vidbytes);
- saa->vidhead += vidbytes;
- saa->vidhead &= 0x7ffff;
- debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO :
- IBM_MP2_FIFOW), 0, 30720);
- wake_up_interruptible(&saa->vidq);
- }
- saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);
-}
-
-static void send_osd_data(struct saa7146 *saa)
-{
- int size = saa->osdtail - saa->osdhead;
- if (size > 30720)
- size = 30720;
- /* ensure some multiple of 8 bytes is transferred */
- size = 8 * ((size + 8) >> 3);
- if (size) {
- debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR,
- (saa->osdhead >> 3), 2);
- memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size);
- saa->osdhead += size;
- /* block transfer of next 8 bytes to ~32k bytes */
- debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size);
- }
- if (saa->osdhead >= saa->osdtail) {
- saa->osdhead = saa->osdtail = 0;
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- }
-}
-
-static irqreturn_t saa7146_irq(int irq, void *dev_id)
-{
- struct saa7146 *saa = dev_id;
- u32 stat, astat;
- int count;
- int handled = 0;
-
- count = 0;
- while (1) {
- /* get/clear interrupt status bits */
- stat = saaread(SAA7146_ISR);
- astat = stat & saaread(SAA7146_IER);
- if (!astat)
- break;
- handled = 1;
- saawrite(astat, SAA7146_ISR);
- if (astat & SAA7146_PSR_DEBI_S) {
- do_irq_send_data(saa);
- }
- if (astat & SAA7146_PSR_PIN1) {
- int istat;
- /* the following read will trigger DEBI_S */
- istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- if (istat & 1) {
- saawrite(0, SAA7146_IER);
- send_osd_data(saa);
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- }
- if (istat & 0x20) { /* Video Start */
- saa->vidinfo.frame_count++;
- }
- if (istat & 0x400) { /* Picture Start */
- /* update temporal reference */
- }
- if (istat & 0x200) { /* Picture Resolution Change */
- /* read new resolution */
- }
- if (istat & 0x100) { /* New User Data found */
- /* read new user data */
- }
- if (istat & 0x1000) { /* new GOP/SMPTE */
- /* read new SMPTE */
- }
- if (istat & 0x8000) { /* Sequence Start Code */
- /* reset frame counter, load sizes */
- saa->vidinfo.frame_count = 0;
- saa->vidinfo.h_size = 704;
- saa->vidinfo.v_size = 480;
-#if 0
- if (saa->endmarkhead != saa->endmarktail) {
- saa->audhead =
- saa->endmark[saa->endmarkhead];
- saa->endmarkhead++;
- if (saa->endmarkhead >= MAX_MARKS)
- saa->endmarkhead = 0;
- }
-#endif
- }
- if (istat & 0x4000) { /* Sequence Error Code */
- if (saa->endmarkhead != saa->endmarktail) {
- saa->audhead =
- saa->endmark[saa->endmarkhead];
- saa->endmarkhead++;
- if (saa->endmarkhead >= MAX_MARKS)
- saa->endmarkhead = 0;
- }
- }
- }
-#ifdef IDEBUG
- if (astat & SAA7146_PSR_PPEF) {
- IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PABO) {
- IDEBUG(printk("stradis%d irq: PABO\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PPED) {
- IDEBUG(printk("stradis%d irq: PPED\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_I1) {
- IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_I0) {
- IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_LATE1) {
- IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_LATE0) {
- IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_E1) {
- IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_E0) {
- IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_TO1) {
- IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_TO0) {
- IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_UPLD) {
- IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr));
- }
- if (astat & SAA7146_PSR_DEBI_E) {
- IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr));
- }
- if (astat & SAA7146_PSR_I2C_S) {
- IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr));
- }
- if (astat & SAA7146_PSR_I2C_E) {
- IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A2_IN) {
- IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A2_OUT) {
- IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A1_IN) {
- IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A1_OUT) {
- IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr));
- }
- if (astat & SAA7146_PSR_AFOU) {
- IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr));
- }
- if (astat & SAA7146_PSR_V_PE) {
- IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr));
- }
- if (astat & SAA7146_PSR_VFOU) {
- IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr));
- }
- if (astat & SAA7146_PSR_FIDA) {
- IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr));
- }
- if (astat & SAA7146_PSR_FIDB) {
- IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN3) {
- IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN2) {
- IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN0) {
- IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_ECS) {
- IDEBUG(printk("stradis%d irq: ECS\n", saa->nr));
- }
- if (astat & SAA7146_PSR_EC3S) {
- IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr));
- }
- if (astat & SAA7146_PSR_EC0S) {
- IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr));
- }
-#endif
- count++;
- if (count > 15)
- printk(KERN_WARNING "stradis%d: irq loop %d\n",
- saa->nr, count);
- if (count > 20) {
- saawrite(0, SAA7146_IER);
- printk(KERN_ERR
- "stradis%d: IRQ loop cleared\n", saa->nr);
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-static int ibm_send_command(struct saa7146 *saa,
- int command, int data, int chain)
-{
- int i;
-
- if (chain)
- debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1)| 1,2);
- else
- debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2);
- for (i = 0; i < 100 &&
- (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++)
- schedule();
- if (i == 100)
- return -1;
- return 0;
-}
-
-static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
-{
- I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2);
- I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2);
-}
-
-static void initialize_cs4341(struct saa7146 *saa)
-{
- int i;
- for (i = 0; i < 200; i++) {
- /* auto mute off, power on, no de-emphasis */
- /* I2S data up to 24-bit 64xFs internal SCLK */
- I2CWrite(saa, 0x22, 0x01, 0x11, 2);
- /* ATAPI mixer settings */
- I2CWrite(saa, 0x22, 0x02, 0x49, 2);
- /* attenuation left 3db */
- I2CWrite(saa, 0x22, 0x03, 0x00, 2);
- /* attenuation right 3db */
- I2CWrite(saa, 0x22, 0x04, 0x00, 2);
- I2CWrite(saa, 0x22, 0x01, 0x10, 2);
- if (I2CRead(saa, 0x22, 0x02, 1) == 0x49)
- break;
- schedule();
- }
- printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i);
- return;
-}
-
-static void initialize_cs8420(struct saa7146 *saa, int pro)
-{
- int i;
- u8 *sequence;
- if (pro)
- sequence = mode8420pro;
- else
- sequence = mode8420con;
- for (i = 0; i < INIT8420LEN; i++)
- I2CWrite(saa, 0x20, init8420[i * 2], init8420[i * 2 + 1], 2);
- for (i = 0; i < MODE8420LEN; i++)
- I2CWrite(saa, 0x20, sequence[i * 2], sequence[i * 2 + 1], 2);
- printk("stradis%d: CS8420 initialized\n", saa->nr);
-}
-
-static void initialize_saa7121(struct saa7146 *saa, int dopal)
-{
- int i, mod;
- u8 *sequence;
- if (dopal)
- sequence = init7121pal;
- else
- sequence = init7121ntsc;
- mod = saaread(SAA7146_PSR) & 0x08;
- /* initialize PAL/NTSC video encoder */
- for (i = 0; i < INIT7121LEN; i++) {
- if (NewCard) { /* handle new card encoder differences */
- if (sequence[i * 2] == 0x3a)
- I2CWrite(saa, 0x88, 0x3a, 0x13, 2);
- else if (sequence[i * 2] == 0x6b)
- I2CWrite(saa, 0x88, 0x6b, 0x20, 2);
- else if (sequence[i * 2] == 0x6c)
- I2CWrite(saa, 0x88, 0x6c,
- dopal ? 0x09 : 0xf5, 2);
- else if (sequence[i * 2] == 0x6d)
- I2CWrite(saa, 0x88, 0x6d,
- dopal ? 0x20 : 0x00, 2);
- else if (sequence[i * 2] == 0x7a)
- I2CWrite(saa, 0x88, 0x7a,
- dopal ? (PALFirstActive - 1) :
- (NTSCFirstActive - 4), 2);
- else if (sequence[i * 2] == 0x7b)
- I2CWrite(saa, 0x88, 0x7b,
- dopal ? PALLastActive :
- NTSCLastActive, 2);
- else
- I2CWrite(saa, 0x88, sequence[i * 2],
- sequence[i * 2 + 1], 2);
- } else {
- if (sequence[i * 2] == 0x6b && mod)
- I2CWrite(saa, 0x88, 0x6b,
- (sequence[i * 2 + 1] ^ 0x09), 2);
- else if (sequence[i * 2] == 0x7a)
- I2CWrite(saa, 0x88, 0x7a,
- dopal ? (PALFirstActive - 1) :
- (NTSCFirstActive - 4), 2);
- else if (sequence[i * 2] == 0x7b)
- I2CWrite(saa, 0x88, 0x7b,
- dopal ? PALLastActive :
- NTSCLastActive, 2);
- else
- I2CWrite(saa, 0x88, sequence[i * 2],
- sequence[i * 2 + 1], 2);
- }
- }
-}
-
-static void set_genlock_offset(struct saa7146 *saa, int noffset)
-{
- int nCode;
- int PixelsPerLine = 858;
- if (CurrentMode == VIDEO_MODE_PAL)
- PixelsPerLine = 864;
- if (noffset > 500)
- noffset = 500;
- else if (noffset < -500)
- noffset = -500;
- nCode = noffset + 0x100;
- if (nCode == 1)
- nCode = 0x401;
- else if (nCode < 1)
- nCode = 0x400 + PixelsPerLine + nCode;
- debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);
-}
-
-static void set_out_format(struct saa7146 *saa, int mode)
-{
- initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1));
- saa->boardcfg[2] = mode;
- /* do not adjust analog video parameters here, use saa7121 init */
- /* you will affect the SDI output on the new card */
- if (mode == VIDEO_MODE_PAL) { /* PAL */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2);
- mdelay(50);
- saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1);
- if (NewCard) {
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, 0xe100, 2);
- mdelay(50);
- }
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- NewCard ? 0xe500 : 0x6500, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
- (1 << 8) |
- (NewCard ? PALFirstActive : PALFirstActive - 6), 2);
- } else { /* NTSC */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2);
- mdelay(50);
- saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1);
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- NewCard ? 0xe100 : 0x6100, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
- (1 << 8) |
- (NewCard ? NTSCFirstActive : NTSCFirstActive - 6), 2);
- }
-}
-
-/* Intialize bitmangler to map from a byte value to the mangled word that
- * must be output to program the Xilinx part through the DEBI port.
- * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0
- * transfer FPGA code, init IBM chip, transfer IBM microcode
- * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0
- */
-static u16 bitmangler[256];
-
-static int initialize_fpga(struct video_code *bitdata)
-{
- int i, num, startindex, failure = 0, loadtwo, loadfile = 0;
- u16 *dmabuf;
- u8 *newdma;
- struct saa7146 *saa;
-
- /* verify fpga code */
- for (startindex = 0; startindex < bitdata->datasize; startindex++)
- if (bitdata->data[startindex] == 255)
- break;
- if (startindex == bitdata->datasize) {
- printk(KERN_INFO "stradis: bad fpga code\n");
- return -1;
- }
- /* initialize all detected cards */
- for (num = 0; num < saa_num; num++) {
- saa = &saa7146s[num];
- if (saa->boardcfg[0] > 20)
- continue; /* card was programmed */
- loadtwo = (saa->boardcfg[18] & 0x10);
- if (!NewCard) /* we have an old board */
- for (i = 0; i < 256; i++)
- bitmangler[i] = ((i & 0x01) << 15) |
- ((i & 0x02) << 6) | ((i & 0x04) << 4) |
- ((i & 0x08) << 9) | ((i & 0x10) << 7) |
- ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
- ((i & 0x80) >> 7);
- else /* else we have a new board */
- for (i = 0; i < 256; i++)
- bitmangler[i] = ((i & 0x01) << 7) |
- ((i & 0x02) << 5) | ((i & 0x04) << 3) |
- ((i & 0x08) << 1) | ((i & 0x10) >> 1) |
- ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
- ((i & 0x80) >> 7);
-
- dmabuf = (u16 *) saa->dmadebi;
- newdma = (u8 *) saa->dmadebi;
- if (NewCard) { /* SDM2xxx */
- if (!strncmp(bitdata->loadwhat, "decoder2", 8))
- continue; /* fpga not for this card */
- if (!strncmp(&saa->boardcfg[42], bitdata->loadwhat, 8))
- loadfile = 1;
- else if (loadtwo && !strncmp(&saa->boardcfg[19],
- bitdata->loadwhat, 8))
- loadfile = 2;
- else if (!saa->boardcfg[42] && !strncmp("decxl",
- bitdata->loadwhat, 8))
- loadfile = 1; /* special */
- else
- continue; /* fpga not for this card */
- if (loadfile != 1 && loadfile != 2)
- continue; /* skip to next card */
- if (saa->boardcfg[0] && loadfile == 1)
- continue; /* skip to next card */
- if (saa->boardcfg[0] != 1 && loadfile == 2)
- continue; /* skip to next card */
- saa->boardcfg[0]++; /* mark fpga handled */
- printk("stradis%d: loading %s\n", saa->nr,
- bitdata->loadwhat);
- if (loadtwo && loadfile == 2)
- goto send_fpga_stuff;
- /* turn on the Audio interface to set PROG low */
- saawrite(0x00400040, SAA7146_GPIO_CTRL);
- saaread(SAA7146_PSR); /* ensure posted write */
- /* wait for everyone to reset */
- mdelay(10);
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- } else { /* original card */
- if (strncmp(bitdata->loadwhat, "decoder2", 8))
- continue; /* fpga not for this card */
- /* Pull the Xilinx PROG signal WS3 low */
- saawrite(0x02000200, SAA7146_MC1);
- /* Turn on the Audio interface so can set PROG low */
- saawrite(0x000000c0, SAA7146_ACON1);
- /* Pull the Xilinx INIT signal (GPIO2) low */
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- /* Make sure everybody resets */
- saaread(SAA7146_PSR); /* ensure posted write */
- mdelay(10);
- /* Release the Xilinx PROG signal */
- saawrite(0x00000000, SAA7146_ACON1);
- /* Turn off the Audio interface */
- saawrite(0x02000000, SAA7146_MC1);
- }
- /* Release Xilinx INIT signal (WS2) */
- saawrite(0x00000000, SAA7146_GPIO_CTRL);
- /* Wait for the INIT to go High */
- for (i = 0;
- i < 10000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2);
- i++)
- schedule();
- if (i == 1000) {
- printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr);
- return -1;
- }
-send_fpga_stuff:
- if (NewCard) {
- for (i = startindex; i < bitdata->datasize; i++)
- newdma[i - startindex] =
- bitmangler[bitdata->data[i]];
- debiwrite(saa, 0x01420000, 0, 0,
- ((bitdata->datasize - startindex) + 5));
- if (loadtwo && loadfile == 1) {
- printk("stradis%d: awaiting 2nd FPGA bitfile\n",
- saa->nr);
- continue; /* skip to next card */
- }
- } else {
- for (i = startindex; i < bitdata->datasize; i++)
- dmabuf[i - startindex] =
- bitmangler[bitdata->data[i]];
- debiwrite(saa, 0x014a0000, 0, 0,
- ((bitdata->datasize - startindex) + 5) * 2);
- }
- for (i = 0;
- i < 1000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2);
- i++)
- schedule();
- if (i == 1000) {
- printk(KERN_INFO "stradis%d: FPGA load failed\n",
- saa->nr);
- failure++;
- continue;
- }
- if (!NewCard) {
- /* Pull the Xilinx INIT signal (GPIO2) low */
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- saaread(SAA7146_PSR); /* ensure posted write */
- mdelay(2);
- saawrite(0x00000000, SAA7146_GPIO_CTRL);
- mdelay(2);
- }
- printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr);
- saa->boardcfg[0] = 26; /* mark fpga programmed */
- /* set VXCO to its lowest frequency */
- debiwrite(saa, debNormal, XILINX_PWM, 0, 2);
- if (NewCard) {
- /* mute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
- 0, 2);
- /* set VXCO to PWM mode, release reset, blank on */
- debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2);
- mdelay(10);
- /* unmute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CTL0,
- 0x2020, 2);
- }
- /* set source Black */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
- saa->boardcfg[4] = 22; /* set NTSC First Active Line */
- saa->boardcfg[5] = 23; /* set PAL First Active Line */
- saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */
- saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */
- set_out_format(saa, VIDEO_MODE_NTSC);
- mdelay(50);
- /* begin IBM chip init */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
- saaread(SAA7146_PSR); /* wait for reset */
- mdelay(5);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
- debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
- if (NewCard) {
- mdelay(5);
- /* set i2s rate converter to 48KHz */
- debiwrite(saa, debNormal, 0x80c0, 6, 2);
- /* we must init CS8420 first since rev b pulls i2s */
- /* master clock low and CS4341 needs i2s master to */
- /* run the i2c port. */
- if (HaveCS8420)
- /* 0=consumer, 1=pro */
- initialize_cs8420(saa, 0);
-
- mdelay(5);
- if (HaveCS4341)
- initialize_cs4341(saa);
- }
- debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
- debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
- if (NewCard)
- set_genlock_offset(saa, 0);
- debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
-#if 0
- /* enable genlock */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);
-#else
- /* disable genlock */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);
-#endif
- }
-
- return failure;
-}
-
-static int do_ibm_reset(struct saa7146 *saa)
-{
- /* failure if decoder not previously programmed */
- if (saa->boardcfg[0] < 37)
- return -EIO;
- /* mute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2);
- /* disable interrupts */
- saawrite(0, SAA7146_IER);
- saa->audhead = saa->audtail = 0;
- saa->vidhead = saa->vidtail = 0;
- /* tristate debi bus, disable debi transfers */
- saawrite(0x00880000, SAA7146_MC1);
- /* ensure posted write */
- saaread(SAA7146_MC1);
- mdelay(50);
- /* re-enable debi transfers */
- saawrite(0x00880088, SAA7146_MC1);
- /* set source Black */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
- /* begin IBM chip init */
- set_out_format(saa, CurrentMode);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
- saaread(SAA7146_PSR); /* wait for reset */
- mdelay(5);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
- debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
- if (NewCard) {
- mdelay(5);
- /* set i2s rate converter to 48KHz */
- debiwrite(saa, debNormal, 0x80c0, 6, 2);
- /* we must init CS8420 first since rev b pulls i2s */
- /* master clock low and CS4341 needs i2s master to */
- /* run the i2c port. */
- if (HaveCS8420)
- /* 0=consumer, 1=pro */
- initialize_cs8420(saa, 1);
-
- mdelay(5);
- if (HaveCS4341)
- initialize_cs4341(saa);
- }
- debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
- debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
- if (NewCard)
- set_genlock_offset(saa, 0);
- debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
- if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
- (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) {
- printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr);
- }
- if (HaveCS3310) {
- int i = CS3310MaxLvl;
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i << 8)| i),2);
- }
- /* start video decoder */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- /* 256k vid, 3520 bytes aud */
- debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- /* enable buffer threshold irq */
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- /* clear pending interrupts */
- debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
-
- return 0;
-}
-
-/* load the decoder microcode */
-static int initialize_ibmmpeg2(struct video_code *microcode)
-{
- int i, num;
- struct saa7146 *saa;
-
- for (num = 0; num < saa_num; num++) {
- saa = &saa7146s[num];
- /* check that FPGA is loaded */
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2);
- i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2);
- if (i != 0xa55a) {
- printk(KERN_INFO "stradis%d: %04x != 0xa55a\n",
- saa->nr, i);
-#if 0
- return -1;
-#endif
- }
- if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) {
- if (saa->boardcfg[0] > 27)
- continue; /* skip to next card */
- /* load video control store */
- saa->boardcfg[1] = 0x13; /* no-sync default */
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
- for (i = 0; i < microcode->datasize / 2; i++)
- debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA,
- (microcode->data[i * 2] << 8) |
- microcode->data[i * 2 + 1], 2);
- debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- saa->boardcfg[0] = 28;
- }
- if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) {
- if (saa->boardcfg[0] > 35)
- continue; /* skip to next card */
- /* load audio control store */
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
- for (i = 0; i < microcode->datasize; i++)
- debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA,
- microcode->data[i], 1);
- debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
- if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
- 0xe000, 1)) {
- printk(KERN_ERR "stradis%d: IBM config "
- "failed\n", saa->nr);
- return -1;
- }
- /* set PWM to center value */
- if (NewCard) {
- debiwrite(saa, debNormal, XILINX_PWM,
- saa->boardcfg[14] +
- (saa->boardcfg[13] << 8), 2);
- } else
- debiwrite(saa, debNormal, XILINX_PWM, 0x46, 2);
-
- if (HaveCS3310) {
- i = CS3310MaxLvl;
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
- (i << 8) | i, 2);
- }
- printk(KERN_INFO "stradis%d: IBM MPEGCD%d Inited\n",
- saa->nr, 18 + (debiread(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, 2) >> 12));
- /* start video decoder */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037,
- 2); /* 256k vid, 3520 bytes aud */
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- /* enable buffer threshold irq */
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- /* enable gpio irq */
- saawrite(0x00002000, SAA7146_GPIO_CTRL);
- /* enable decoder output to HPS */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
- saa->boardcfg[0] = 37;
- }
- }
-
- return 0;
-}
-
-static u32 palette2fmt[] = { /* some of these YUV translations are wrong */
- 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000,
- 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000,
- 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000
-};
-static int bpp2fmt[4] = {
- VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24,
- VIDEO_PALETTE_RGB32
-};
-
-/* I wish I could find a formula to calculate these... */
-static u32 h_prescale[64] = {
- 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808,
- 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460,
- 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f,
- 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000,
- 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000,
- 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000,
- 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000,
- 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000,
- 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000,
- 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000,
- 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,
-};
-static u32 v_gain[64] = {
- 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff,
- 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff,
- 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
-};
-
-static void saa7146_set_winsize(struct saa7146 *saa)
-{
- u32 format;
- int offset, yacl, ysci;
- saa->win.color_fmt = format =
- (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] :
- palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]];
- offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl;
- saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1);
- saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1);
- saawrite(saa->win.bpl * 2, SAA7146_PITCH1);
- saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight,
- SAA7146_PROT_ADDR1);
- saawrite(0, SAA7146_PAGE1);
- saawrite(format | 0x60, SAA7146_CLIP_FORMAT_CTRL);
- offset = (704 / (saa->win.width - 1)) & 0x3f;
- saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE);
- offset = (720896 / saa->win.width) / (offset + 1);
- saawrite((offset << 12) | 0x0c, SAA7146_HPS_H_SCALE);
- if (CurrentMode == VIDEO_MODE_NTSC) {
- yacl = /*(480 / saa->win.height - 1) & 0x3f */ 0;
- ysci = 1024 - (saa->win.height * 1024 / 480);
- } else {
- yacl = /*(576 / saa->win.height - 1) & 0x3f */ 0;
- ysci = 1024 - (saa->win.height * 1024 / 576);
- }
- saawrite((1 << 31) | (ysci << 21) | (yacl << 15), SAA7146_HPS_V_SCALE);
- saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN);
- saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V |
- SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 |
- SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H), SAA7146_MC2);
-}
-
-/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area
- * bitmap is fixed width, 128 bytes (1024 pixels represented)
- * arranged most-sigificant-bit-left in 32-bit words
- * based on saa7146 clipping hardware, it swaps bytes if LE
- * much of this makes up for egcs brain damage -- so if you
- * are wondering "why did he do this?" it is because the C
- * was adjusted to generate the optimal asm output without
- * writing non-portable __asm__ directives.
- */
-
-static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h)
-{
- register int startword, endword;
- register u32 bitsleft, bitsright;
- u32 *temp;
- if (x < 0) {
- w += x;
- x = 0;
- }
- if (y < 0) {
- h += y;
- y = 0;
- }
- if (w <= 0 || h <= 0 || x > 1023 || y > 639)
- return; /* throw away bad clips */
- if (x + w > 1024)
- w = 1024 - x;
- if (y + h > 640)
- h = 640 - y;
- startword = (x >> 5);
- endword = ((x + w) >> 5);
- bitsleft = (0xffffffff >> (x & 31));
- bitsright = (0xffffffff << (~((x + w) - (endword << 5))));
- temp = &clipmap[(y << 5) + startword];
- w = endword - startword;
- if (!w) {
- bitsleft |= bitsright;
- for (y = 0; y < h; y++) {
- *temp |= bitsleft;
- temp += 32;
- }
- } else {
- for (y = 0; y < h; y++) {
- *temp++ |= bitsleft;
- for (x = 1; x < w; x++)
- *temp++ = 0xffffffff;
- *temp |= bitsright;
- temp += (32 - w);
- }
- }
-}
-
-static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr)
-{
- int i, width, height;
- u32 *clipmap;
-
- clipmap = saa->dmavid2;
- if ((width = saa->win.width) > 1023)
- width = 1023; /* sanity check */
- if ((height = saa->win.height) > 640)
- height = 639; /* sanity check */
- if (ncr > 0) { /* rectangles pased */
- /* convert rectangular clips to a bitmap */
- memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
- for (i = 0; i < ncr; i++)
- clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
- cr[i].width, cr[i].height);
- }
- /* clip against viewing window AND screen
- so we do not have to rely on the user program
- */
- clip_draw_rectangle(clipmap, (saa->win.x + width > saa->win.swidth) ?
- (saa->win.swidth - saa->win.x) : width, 0, 1024, 768);
- clip_draw_rectangle(clipmap, 0,
- (saa->win.y + height > saa->win.sheight) ?
- (saa->win.sheight - saa->win.y) : height, 1024, 768);
- if (saa->win.x < 0)
- clip_draw_rectangle(clipmap, 0, 0, -saa->win.x, 768);
- if (saa->win.y < 0)
- clip_draw_rectangle(clipmap, 0, 0, 1024, -saa->win.y);
-}
-
-static long saa_ioctl(struct file *file,
- unsigned int cmd, unsigned long argl)
-{
- struct saa7146 *saa = file->private_data;
- void __user *arg = (void __user *)argl;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- memset(&b, 0, sizeof(b));
- strcpy(b.name, saa->video_dev.name);
- b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
- VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
- VID_TYPE_SCALES;
- b.channels = 1;
- b.audios = 1;
- b.maxwidth = 768;
- b.maxheight = 576;
- b.minwidth = 32;
- b.minheight = 32;
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p = saa->picture;
- if (saa->win.depth == 8)
- p.palette = VIDEO_PALETTE_HI240;
- if (saa->win.depth == 15)
- p.palette = VIDEO_PALETTE_RGB555;
- if (saa->win.depth == 16)
- p.palette = VIDEO_PALETTE_RGB565;
- if (saa->win.depth == 24)
- p.palette = VIDEO_PALETTE_RGB24;
- if (saa->win.depth == 32)
- p.palette = VIDEO_PALETTE_RGB32;
- if (copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- u32 format;
- if (copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
- if (p.palette < ARRAY_SIZE(palette2fmt)) {
- format = palette2fmt[p.palette];
- saa->win.color_fmt = format;
- saawrite(format | 0x60,
- SAA7146_CLIP_FORMAT_CTRL);
- }
- saawrite(((p.brightness & 0xff00) << 16) |
- ((p.contrast & 0xfe00) << 7) |
- ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
- saa->picture = p;
- /* upload changed registers */
- saawrite(((SAA7146_MC2_UPLD_HPS_H |
- SAA7146_MC2_UPLD_HPS_V) << 16) |
- SAA7146_MC2_UPLD_HPS_H |
- SAA7146_MC2_UPLD_HPS_V, SAA7146_MC2);
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip *vcp = NULL;
-
- if (copy_from_user(&vw, arg, sizeof(vw)))
- return -EFAULT;
-
- /* stop capture */
- if (vw.flags || vw.width < 16 || vw.height < 16) {
- saawrite((SAA7146_MC1_TR_E_1 << 16),
- SAA7146_MC1);
- return -EINVAL;
- }
- /* 32-bit align start and adjust width */
- if (saa->win.bpp < 4) {
- int i = vw.x;
- vw.x = (vw.x + 3) & ~3;
- i = vw.x - i;
- vw.width -= i;
- }
- saa->win.x = vw.x;
- saa->win.y = vw.y;
- saa->win.width = vw.width;
- if (saa->win.width > 768)
- saa->win.width = 768;
- saa->win.height = vw.height;
- if (CurrentMode == VIDEO_MODE_NTSC) {
- if (saa->win.height > 480)
- saa->win.height = 480;
- } else {
- if (saa->win.height > 576)
- saa->win.height = 576;
- }
-
- /* stop capture */
- saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
- saa7146_set_winsize(saa);
-
- /*
- * Do any clips.
- */
- if (vw.clipcount < 0) {
- if (copy_from_user(saa->dmavid2, vw.clips,
- VIDEO_CLIPMAP_SIZE))
- return -EFAULT;
- } else if (vw.clipcount > 16384) {
- return -EINVAL;
- } else if (vw.clipcount > 0) {
- vcp = vmalloc(sizeof(struct video_clip) *
- vw.clipcount);
- if (vcp == NULL)
- return -ENOMEM;
- if (copy_from_user(vcp, vw.clips,
- sizeof(struct video_clip) *
- vw.clipcount)) {
- vfree(vcp);
- return -EFAULT;
- }
- } else /* nothing clipped */
- memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);
-
- make_clip_tab(saa, vcp, vw.clipcount);
- if (vw.clipcount > 0)
- vfree(vcp);
-
- /* start capture & clip dma if we have an address */
- if ((saa->cap & 3) && saa->win.vidadr != 0)
- saawrite(((SAA7146_MC1_TR_E_1 |
- SAA7146_MC1_TR_E_2) << 16) | 0xffff,
- SAA7146_MC1);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- memset(&vw, 0, sizeof(vw));
- vw.x = saa->win.x;
- vw.y = saa->win.y;
- vw.width = saa->win.width;
- vw.height = saa->win.height;
- vw.chromakey = 0;
- vw.flags = 0;
- if (copy_to_user(arg, &vw, sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- {
- int v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v == 0) {
- saa->cap &= ~1;
- saawrite((SAA7146_MC1_TR_E_1 << 16),
- SAA7146_MC1);
- } else {
- if (saa->win.vidadr == 0 || saa->win.width == 0
- || saa->win.height == 0)
- return -EINVAL;
- saa->cap |= 1;
- saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
- SAA7146_MC1);
- }
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
- memset(&v, 0, sizeof(v));
- v.base = (void *)saa->win.vidadr;
- v.height = saa->win.sheight;
- v.width = saa->win.swidth;
- v.depth = saa->win.depth;
- v.bytesperline = saa->win.bpl;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
-
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
- v.depth != 24 && v.depth != 32 && v.width > 16 &&
- v.height > 16 && v.bytesperline > 16)
- return -EINVAL;
- if (v.base)
- saa->win.vidadr = (unsigned long)v.base;
- saa->win.sheight = v.height;
- saa->win.swidth = v.width;
- saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
- saa->win.depth = v.depth;
- saa->win.bpl = v.bytesperline;
-
- DEBUG(printk("Display at %p is %d by %d, bytedepth %d, "
- "bpl %d\n", v.base, v.width, v.height,
- saa->win.bpp, saa->win.bpl));
- saa7146_set_winsize(saa);
- return 0;
- }
- case VIDIOCKEY:
- {
- /* Will be handled higher up .. */
- return 0;
- }
-
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v, 0, sizeof(v));
- v = saa->audio_dev;
- v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
- v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- strcpy(v.name, "MPEG");
- v.mode = VIDEO_SOUND_STEREO;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- int i;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- i = (~(v.volume >> 8)) & 0xff;
- if (!HaveCS4341) {
- if (v.flags & VIDEO_AUDIO_MUTE)
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN, 0xffff, 2);
- if (!(v.flags & VIDEO_AUDIO_MUTE))
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN, 0x0000, 2);
- if (v.flags & VIDEO_AUDIO_VOLUME)
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN,
- (i << 8) | i, 2);
- } else {
- if (v.flags & VIDEO_AUDIO_MUTE)
- cs4341_setlevel(saa, 0xff, 0xff);
- if (!(v.flags & VIDEO_AUDIO_MUTE))
- cs4341_setlevel(saa, 0, 0);
- if (v.flags & VIDEO_AUDIO_VOLUME)
- cs4341_setlevel(saa, i, i);
- }
- saa->audio_dev = v;
- return 0;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit vu;
- memset(&vu, 0, sizeof(vu));
- vu.video = saa->video_dev.minor;
- vu.vbi = VIDEO_NO_UNIT;
- vu.radio = VIDEO_NO_UNIT;
- vu.audio = VIDEO_NO_UNIT;
- vu.teletext = VIDEO_NO_UNIT;
- if (copy_to_user(arg, &vu, sizeof(vu)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPLAYMODE:
- {
- struct video_play_mode pmode;
- if (copy_from_user((void *)&pmode, arg,
- sizeof(struct video_play_mode)))
- return -EFAULT;
- switch (pmode.mode) {
- case VID_PLAY_VID_OUT_MODE:
- if (pmode.p1 != VIDEO_MODE_NTSC &&
- pmode.p1 != VIDEO_MODE_PAL)
- return -EINVAL;
- set_out_format(saa, pmode.p1);
- return 0;
- case VID_PLAY_GENLOCK:
- debiwrite(saa, debNormal, XILINX_CTL0,
- pmode.p1 ? 0x8000 : 0x8080, 2);
- if (NewCard)
- set_genlock_offset(saa, pmode.p2);
- return 0;
- case VID_PLAY_NORMAL:
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_PAUSE:
- /* IBM removed the PAUSE command */
- /* they say use SINGLE_FRAME now */
- case VID_PLAY_SINGLE_FRAME:
- ibm_send_command(saa, IBM_MP2_SINGLE_FRAME,0,0);
- if (saa->playmode == pmode.mode) {
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- }
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_FAST_FORWARD:
- ibm_send_command(saa, IBM_MP2_FAST_FORWARD,0,0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_SLOW_MOTION:
- ibm_send_command(saa, IBM_MP2_SLOW_MOTION,
- pmode.p1, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_IMMEDIATE_NORMAL:
- /* ensure transfers resume */
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- ibm_send_command(saa, IBM_MP2_IMED_NORM_PLAY,
- 0, 0);
- saa->playmode = VID_PLAY_NORMAL;
- return 0;
- case VID_PLAY_SWITCH_CHANNELS:
- saa->audhead = saa->audtail = 0;
- saa->vidhead = saa->vidtail = 0;
- ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,1);
- ibm_send_command(saa, IBM_MP2_RESET_AUD_RATE,
- 0, 1);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- 0, 2);
- ibm_send_command(saa, IBM_MP2_CHANNEL_SWITCH,
- 0, 1);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- saa->playmode = VID_PLAY_NORMAL;
- return 0;
- case VID_PLAY_FREEZE_FRAME:
- ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_STILL_MODE:
- ibm_send_command(saa, IBM_MP2_SET_STILL_MODE,
- 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_MASTER_MODE:
- if (pmode.p1 == VID_PLAY_MASTER_NONE)
- saa->boardcfg[1] = 0x13;
- else if (pmode.p1 == VID_PLAY_MASTER_VIDEO)
- saa->boardcfg[1] = 0x23;
- else if (pmode.p1 == VID_PLAY_MASTER_AUDIO)
- saa->boardcfg[1] = 0x43;
- else
- return -EINVAL;
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- return 0;
- case VID_PLAY_ACTIVE_SCANLINES:
- if (CurrentMode == VIDEO_MODE_PAL) {
- if (pmode.p1 < 1 || pmode.p2 > 625)
- return -EINVAL;
- saa->boardcfg[5] = pmode.p1;
- saa->boardcfg[55] = (pmode.p1 +
- (pmode.p2 / 2) - 1) & 0xff;
- } else {
- if (pmode.p1 < 4 || pmode.p2 > 525)
- return -EINVAL;
- saa->boardcfg[4] = pmode.p1;
- saa->boardcfg[54] = (pmode.p1 +
- (pmode.p2 / 2) - 4) & 0xff;
- }
- set_out_format(saa, CurrentMode);
- case VID_PLAY_RESET:
- return do_ibm_reset(saa);
- case VID_PLAY_END_MARK:
- if (saa->endmarktail < saa->endmarkhead) {
- if (saa->endmarkhead -
- saa->endmarktail < 2)
- return -ENOSPC;
- } else if (saa->endmarkhead <=saa->endmarktail){
- if (saa->endmarktail - saa->endmarkhead
- > (MAX_MARKS - 2))
- return -ENOSPC;
- } else
- return -ENOSPC;
- saa->endmark[saa->endmarktail] = saa->audtail;
- saa->endmarktail++;
- if (saa->endmarktail >= MAX_MARKS)
- saa->endmarktail = 0;
- }
- return -EINVAL;
- }
- case VIDIOCSWRITEMODE:
- {
- int mode;
- if (copy_from_user((void *)&mode, arg, sizeof(int)))
- return -EFAULT;
- if (mode == VID_WRITE_MPEG_AUD ||
- mode == VID_WRITE_MPEG_VID ||
- mode == VID_WRITE_CC ||
- mode == VID_WRITE_TTX ||
- mode == VID_WRITE_OSD) {
- saa->writemode = mode;
- return 0;
- }
- return -EINVAL;
- }
- case VIDIOCSMICROCODE:
- {
- struct video_code ucode;
- __u8 *udata;
- int i;
- if (copy_from_user(&ucode, arg, sizeof(ucode)))
- return -EFAULT;
- if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
- strncmp(ucode.loadwhat, "dec", 3))
- return -EINVAL;
- if ((udata = vmalloc(ucode.datasize)) == NULL)
- return -ENOMEM;
- if (copy_from_user(udata, ucode.data, ucode.datasize)) {
- vfree(udata);
- return -EFAULT;
- }
- ucode.data = udata;
- if (!strncmp(ucode.loadwhat, "decoder.aud", 11) ||
- !strncmp(ucode.loadwhat, "decoder.vid", 11))
- i = initialize_ibmmpeg2(&ucode);
- else
- i = initialize_fpga(&ucode);
- vfree(udata);
- if (i)
- return -EINVAL;
- return 0;
-
- }
- case VIDIOCGCHAN: /* this makes xawtv happy */
- {
- struct video_channel v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- v.flags = VIDEO_VC_AUDIO;
- v.tuners = 0;
- v.type = VID_TYPE_MPEG_DECODER;
- v.norm = CurrentMode;
- strcpy(v.name, "MPEG2");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSCHAN: /* this makes xawtv happy */
- {
- struct video_channel v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- /* do nothing */
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int saa_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct saa7146 *saa = file->private_data;
- printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
- return -EINVAL;
-}
-
-static ssize_t saa_read(struct file *file, char __user * buf,
- size_t count, loff_t * ppos)
-{
- return -EINVAL;
-}
-
-static ssize_t saa_write(struct file *file, const char __user * buf,
- size_t count, loff_t * ppos)
-{
- struct saa7146 *saa = file->private_data;
- unsigned long todo = count;
- int blocksize, split;
- unsigned long flags;
-
- while (todo > 0) {
- if (saa->writemode == VID_WRITE_MPEG_AUD) {
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->audhead <= saa->audtail)
- blocksize = 65536 -
- (saa->audtail - saa->audhead);
- else
- blocksize = saa->audhead - saa->audtail;
- spin_unlock_irqrestore(&saa->lock, flags);
- if (blocksize < 16384) {
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- /* wait for buffer space to open */
- interruptible_sleep_on(&saa->audq);
- }
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->audhead <= saa->audtail) {
- blocksize = 65536 -
- (saa->audtail - saa->audhead);
- split = 65536 - saa->audtail;
- } else {
- blocksize = saa->audhead - saa->audtail;
- split = 65536;
- }
- spin_unlock_irqrestore(&saa->lock, flags);
- blocksize--;
- if (blocksize > todo)
- blocksize = todo;
- /* double check that we really have space */
- if (!blocksize)
- return -ENOSPC;
- if (split < blocksize) {
- if (copy_from_user(saa->audbuf +
- saa->audtail, buf, split))
- return -EFAULT;
- buf += split;
- todo -= split;
- blocksize -= split;
- saa->audtail = 0;
- }
- if (copy_from_user(saa->audbuf + saa->audtail, buf,
- blocksize))
- return -EFAULT;
- saa->audtail += blocksize;
- todo -= blocksize;
- buf += blocksize;
- saa->audtail &= 0xffff;
- } else if (saa->writemode == VID_WRITE_MPEG_VID) {
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->vidhead <= saa->vidtail)
- blocksize = 524288 -
- (saa->vidtail - saa->vidhead);
- else
- blocksize = saa->vidhead - saa->vidtail;
- spin_unlock_irqrestore(&saa->lock, flags);
- if (blocksize < 65536) {
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- /* wait for buffer space to open */
- interruptible_sleep_on(&saa->vidq);
- }
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->vidhead <= saa->vidtail) {
- blocksize = 524288 -
- (saa->vidtail - saa->vidhead);
- split = 524288 - saa->vidtail;
- } else {
- blocksize = saa->vidhead - saa->vidtail;
- split = 524288;
- }
- spin_unlock_irqrestore(&saa->lock, flags);
- blocksize--;
- if (blocksize > todo)
- blocksize = todo;
- /* double check that we really have space */
- if (!blocksize)
- return -ENOSPC;
- if (split < blocksize) {
- if (copy_from_user(saa->vidbuf +
- saa->vidtail, buf, split))
- return -EFAULT;
- buf += split;
- todo -= split;
- blocksize -= split;
- saa->vidtail = 0;
- }
- if (copy_from_user(saa->vidbuf + saa->vidtail, buf,
- blocksize))
- return -EFAULT;
- saa->vidtail += blocksize;
- todo -= blocksize;
- buf += blocksize;
- saa->vidtail &= 0x7ffff;
- } else if (saa->writemode == VID_WRITE_OSD) {
- if (count > 131072)
- return -ENOSPC;
- if (copy_from_user(saa->osdbuf, buf, count))
- return -EFAULT;
- buf += count;
- saa->osdhead = 0;
- saa->osdtail = count;
- debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- debiread(saa, debNormal,
- IBM_MP2_DISP_MODE, 2) | 1, 2);
- /* trigger osd data transfer */
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- }
- }
- return count;
-}
-
-static int saa_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev);
-
- lock_kernel();
- file->private_data = saa;
-
- saa->user++;
- if (saa->user > 1) {
- saa->user--;
- unlock_kernel();
- return 0; /* device open already, don't reset */
- }
- saa->writemode = VID_WRITE_MPEG_VID; /* default to video */
- unlock_kernel();
- return 0;
-}
-
-static int saa_release(struct file *file)
-{
- struct saa7146 *saa = file->private_data;
- saa->user--;
-
- if (saa->user > 0) /* still someone using device */
- return 0;
- saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */
- return 0;
-}
-
-static const struct v4l2_file_operations saa_fops = {
- .owner = THIS_MODULE,
- .open = saa_open,
- .release = saa_release,
- .ioctl = saa_ioctl,
- .read = saa_read,
- .write = saa_write,
- .mmap = saa_mmap,
-};
-
-/* template for video_device-structure */
-static struct video_device saa_template = {
- .name = "SAA7146A",
- .fops = &saa_fops,
- .release = video_device_release_empty,
-};
-
-static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
-{
- int retval;
- struct saa7146 *saa = pci_get_drvdata(pdev);
-
- saa->endmarkhead = saa->endmarktail = 0;
- saa->win.x = saa->win.y = 0;
- saa->win.width = saa->win.cropwidth = 720;
- saa->win.height = saa->win.cropheight = 480;
- saa->win.cropx = saa->win.cropy = 0;
- saa->win.bpp = 2;
- saa->win.depth = 16;
- saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];
- saa->win.bpl = 1024 * saa->win.bpp;
- saa->win.swidth = 1024;
- saa->win.sheight = 768;
- saa->picture.brightness = 32768;
- saa->picture.contrast = 38768;
- saa->picture.colour = 32768;
- saa->cap = 0;
- saa->nr = num;
- saa->playmode = VID_PLAY_NORMAL;
- memset(saa->boardcfg, 0, 64); /* clear board config area */
- saa->saa7146_mem = NULL;
- saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =
- saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =
- saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =
- saa->pagea1out = saa->pagea2in = saa->pagea2out =
- saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =
- saa->pageRPS2 = NULL;
- saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;
- saa->audhead = saa->vidtail = 0;
-
- init_waitqueue_head(&saa->i2cq);
- init_waitqueue_head(&saa->audq);
- init_waitqueue_head(&saa->debiq);
- init_waitqueue_head(&saa->vidq);
- spin_lock_init(&saa->lock);
-
- retval = pci_enable_device(pdev);
- if (retval) {
- dev_err(&pdev->dev, "%d: pci_enable_device failed!\n", num);
- goto err;
- }
-
- saa->id = pdev->device;
- saa->irq = pdev->irq;
- saa->saa7146_adr = pci_resource_start(pdev, 0);
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);
-
- saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
- if (saa->saa7146_mem == NULL) {
- dev_err(&pdev->dev, "%d: ioremap failed!\n", num);
- retval = -EIO;
- goto err;
- }
-
- memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
- saawrite(0, SAA7146_IER); /* turn off all interrupts */
-
- retval = request_irq(saa->irq, saa7146_irq, IRQF_SHARED | IRQF_DISABLED,
- "stradis", saa);
- if (retval == -EINVAL)
- dev_err(&pdev->dev, "%d: Bad irq number or handler\n", num);
- else if (retval == -EBUSY)
- dev_err(&pdev->dev, "%d: IRQ %ld busy, change your PnP config "
- "in BIOS\n", num, saa->irq);
- if (retval < 0)
- goto errio;
-
- pci_set_master(pdev);
- retval = video_register_device(&saa->video_dev, VFL_TYPE_GRABBER,
- video_nr);
- if (retval < 0) {
- dev_err(&pdev->dev, "%d: error in registering video device!\n",
- num);
- goto errirq;
- }
-
- return 0;
-
-errirq:
- free_irq(saa->irq, saa);
-errio:
- iounmap(saa->saa7146_mem);
-err:
- return retval;
-}
-
-static int __devinit init_saa7146(struct pci_dev *pdev)
-{
- struct saa7146 *saa = pci_get_drvdata(pdev);
-
- saa->user = 0;
- /* reset the saa7146 */
- saawrite(0xffff0000, SAA7146_MC1);
- mdelay(5);
- /* enable debi and i2c transfers and pins */
- saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |
- SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);
- /* ensure proper state of chip */
- saawrite(0x00000000, SAA7146_PAGE1);
- saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);
- saawrite(0x00000000, SAA7146_PAGE2);
- saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);
- saawrite(0x00000000, SAA7146_DD1_INIT);
- saawrite(0x00000000, SAA7146_DD1_STREAM_B);
- saawrite(0x00000000, SAA7146_DD1_STREAM_A);
- saawrite(0x00000000, SAA7146_BRS_CTRL);
- saawrite(0x80400040, SAA7146_BCS_CTRL);
- saawrite(0x0000e000 /*| (1<<29) */ , SAA7146_HPS_CTRL);
- saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);
- saawrite(0x00000000, SAA7146_ACON1);
- saawrite(0x00000000, SAA7146_ACON2);
- saawrite(0x00000600, SAA7146_I2C_STATUS);
- saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |
- SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |
- SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |
- SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,
- SAA7146_MC2);
- /* setup arbitration control registers */
- saawrite(0x1412121a, SAA7146_PCI_BT_V1);
-
- /* allocate 32k dma buffer + 4k for page table */
- if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
- dev_err(&pdev->dev, "%d: debi kmalloc failed\n", saa->nr);
- goto err;
- }
-#if 0
- saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */
- saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);
- for (i = 0; i < 12; i++) /* setup mmu page table */
- saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));
-#endif
- saa->audhead = saa->vidhead = saa->osdhead = 0;
- saa->audtail = saa->vidtail = saa->osdtail = 0;
- if (saa->vidbuf == NULL && (saa->vidbuf = vmalloc(524288)) == NULL) {
- dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
- goto err;
- }
- if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {
- dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
- goto errfree;
- }
- if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {
- dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
- goto errfree;
- }
- /* allocate 81920 byte buffer for clipping */
- if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
- dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);
- goto errfree;
- }
- /* setup clipping registers */
- saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
- saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);
- saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,
- SAA7146_PROT_ADDR2);
- saawrite(256, SAA7146_PITCH2);
- saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
- saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
- SAA7146_MC2);
- I2CBusScan(saa);
-
- return 0;
-errfree:
- vfree(saa->osdbuf);
- vfree(saa->audbuf);
- vfree(saa->vidbuf);
- saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;
-err:
- return -ENOMEM;
-}
-
-static void stradis_release_saa(struct pci_dev *pdev)
-{
- u8 command;
- struct saa7146 *saa = pci_get_drvdata(pdev);
-
- /* turn off all capturing, DMA and IRQs */
- saawrite(0xffff0000, SAA7146_MC1); /* reset chip */
- saawrite(0, SAA7146_MC2);
- saawrite(0, SAA7146_IER);
- saawrite(0xffffffffUL, SAA7146_ISR);
-
- /* disable PCI bus-mastering */
- pci_read_config_byte(pdev, PCI_COMMAND, &command);
- command &= ~PCI_COMMAND_MASTER;
- pci_write_config_byte(pdev, PCI_COMMAND, command);
-
- /* unmap and free memory */
- saa->audhead = saa->audtail = saa->osdhead = 0;
- saa->vidhead = saa->vidtail = saa->osdtail = 0;
- vfree(saa->vidbuf);
- vfree(saa->audbuf);
- vfree(saa->osdbuf);
- kfree(saa->dmavid2);
- saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
- saa->dmavid2 = NULL;
- kfree(saa->dmadebi);
- kfree(saa->dmavid1);
- kfree(saa->dmavid3);
- kfree(saa->dmaa1in);
- kfree(saa->dmaa1out);
- kfree(saa->dmaa2in);
- kfree(saa->dmaa2out);
- kfree(saa->dmaRPS1);
- kfree(saa->dmaRPS2);
- free_irq(saa->irq, saa);
- if (saa->saa7146_mem)
- iounmap(saa->saa7146_mem);
- if (video_is_registered(&saa->video_dev))
- video_unregister_device(&saa->video_dev);
-}
-
-static int __devinit stradis_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int retval = -EINVAL;
-
- if (saa_num >= SAA7146_MAX)
- goto err;
-
- if (!pdev->subsystem_vendor)
- dev_info(&pdev->dev, "%d: rev1 decoder\n", saa_num);
- else
- dev_info(&pdev->dev, "%d: SDM2xx found\n", saa_num);
-
- pci_set_drvdata(pdev, &saa7146s[saa_num]);
-
- retval = configure_saa7146(pdev, saa_num);
- if (retval) {
- dev_err(&pdev->dev, "%d: error in configuring\n", saa_num);
- goto err;
- }
-
- if (init_saa7146(pdev) < 0) {
- dev_err(&pdev->dev, "%d: error in initialization\n", saa_num);
- retval = -EIO;
- goto errrel;
- }
-
- saa_num++;
-
- return 0;
-errrel:
- stradis_release_saa(pdev);
-err:
- return retval;
-}
-
-static void __devexit stradis_remove(struct pci_dev *pdev)
-{
- stradis_release_saa(pdev);
-}
-
-static struct pci_device_id stradis_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146) },
- { 0 }
-};
-
-
-static struct pci_driver stradis_driver = {
- .name = "stradis",
- .id_table = stradis_pci_tbl,
- .probe = stradis_probe,
- .remove = __devexit_p(stradis_remove)
-};
-
-static int __init stradis_init(void)
-{
- int retval;
-
- saa_num = 0;
-
- retval = pci_register_driver(&stradis_driver);
- if (retval)
- printk(KERN_ERR "stradis: Unable to register pci driver.\n");
-
- return retval;
-}
-
-static void __exit stradis_exit(void)
-{
- pci_unregister_driver(&stradis_driver);
- printk(KERN_INFO "stradis: module cleanup complete\n");
-}
-
-module_init(stradis_init);
-module_exit(stradis_exit);
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h
index 1c1f157e167a..1159a500f49d 100644
--- a/drivers/staging/tidspbridge/core/_tiomap.h
+++ b/drivers/staging/tidspbridge/core/_tiomap.h
@@ -19,8 +19,19 @@
#ifndef _TIOMAP_
#define _TIOMAP_
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+/*
+ * XXX These powerdomain.h/clockdomain.h includes are wrong and should
+ * be removed. No driver should call pwrdm_* or clkdm_* functions
+ * directly; they should rely on OMAP core code to do this.
+ */
+#include <mach-omap2/powerdomain.h>
+#include <mach-omap2/clockdomain.h>
+/*
+ * XXX These mach-omap2/ includes are wrong and should be removed. No
+ * driver should read or write to PRM/CM registers directly; they
+ * should rely on OMAP core code to do this.
+ */
+#include <mach-omap2/cm2xxx_3xxx.h>
#include <mach-omap2/prm-regbits-34xx.h>
#include <mach-omap2/cm-regbits-34xx.h>
#include <dspbridge/devdefs.h>
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index de7ebb99d8f6..114eec8a630a 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_TM6000
tristate "TV Master TM5600/6000/6010 driver"
- depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL
+ depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL
select VIDEO_TUNER
select MEDIA_TUNER_XC2028
select MEDIA_TUNER_XC5000
diff --git a/drivers/staging/tm6000/TODO b/drivers/staging/tm6000/TODO
index 34780fc17b16..135d0ea3ad70 100644
--- a/drivers/staging/tm6000/TODO
+++ b/drivers/staging/tm6000/TODO
@@ -1,4 +1,6 @@
There a few things to do before putting this driver in production:
+ - IR NEC with tm5600/6000 TV cards
+ - IR RC5 with tm5600/6000/6010 TV cards
- CodingStyle;
- Fix audio;
- Fix some panic/OOPS conditions.
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 664e6038090d..455038bdfc9f 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -328,6 +328,47 @@ struct usb_device_id tm6000_id_table[] = {
{ },
};
+/* Control power led for show some activity */
+void tm6000_flash_led(struct tm6000_core *dev, u8 state)
+{
+ /* Power LED unconfigured */
+ if (!dev->gpio.power_led)
+ return;
+
+ /* ON Power LED */
+ if (state) {
+ switch (dev->model) {
+ case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
+ case TM6010_BOARD_TWINHAN_TU501:
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x00);
+ break;
+ case TM6010_BOARD_BEHOLD_WANDER:
+ case TM6010_BOARD_BEHOLD_VOYAGER:
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x01);
+ break;
+ }
+ }
+ /* OFF Power LED */
+ else {
+ switch (dev->model) {
+ case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
+ case TM6010_BOARD_TWINHAN_TU501:
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x01);
+ break;
+ case TM6010_BOARD_BEHOLD_WANDER:
+ case TM6010_BOARD_BEHOLD_VOYAGER:
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.power_led, 0x00);
+ break;
+ }
+ }
+}
+
/* Tuner callback to provide the proper gpio changes needed for xc5000 */
int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
{
@@ -521,13 +562,6 @@ int tm6000_cards_setup(struct tm6000_core *dev)
printk(KERN_ERR "Error %i doing tuner reset\n", rc);
return rc;
}
- msleep(10);
-
- if (!i) {
- rc = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
- if (rc >= 0)
- printk(KERN_DEBUG "board=0x%08x\n", rc);
- }
}
} else {
printk(KERN_ERR "Tuner reset is not configured\n");
@@ -545,7 +579,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
/* Load tuner module */
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
memset(&tun_setup, 0, sizeof(tun_setup));
tun_setup.type = dev->tuner_type;
@@ -683,7 +717,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
if (dev->caps.has_tda9874)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvaudio", I2C_ADDR_TDA9874, NULL);
+ "tvaudio", I2C_ADDR_TDA9874, NULL);
/* register and initialize V4L2 */
rc = tm6000_v4l2_register(dev);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 40a0206e2432..96aed4ace467 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -542,6 +542,26 @@ int tm6000_init(struct tm6000_core *dev)
int board, rc = 0, i, size;
struct reg_init *tab;
+ /* Check board revision */
+ board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
+ if (board >= 0) {
+ switch (board & 0xff) {
+ case 0xf3:
+ printk(KERN_INFO "Found tm6000\n");
+ if (dev->dev_type != TM6000)
+ dev->dev_type = TM6000;
+ break;
+ case 0xf4:
+ printk(KERN_INFO "Found tm6010\n");
+ if (dev->dev_type != TM6010)
+ dev->dev_type = TM6010;
+ break;
+ default:
+ printk(KERN_INFO "Unknown board version = 0x%08x\n", board);
+ }
+ } else
+ printk(KERN_ERR "Error %i while retrieving board version\n", board);
+
if (dev->dev_type == TM6010) {
tab = tm6010_init_tab;
size = ARRAY_SIZE(tm6010_init_tab);
@@ -563,13 +583,6 @@ int tm6000_init(struct tm6000_core *dev)
msleep(5); /* Just to be conservative */
- /* Check board version - maybe 10Moons specific */
- board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
- if (board >= 0)
- printk(KERN_INFO "Board version = 0x%08x\n", board);
- else
- printk(KERN_ERR "Error %i while retrieving board version\n", board);
-
rc = tm6000_cards_setup(dev);
return rc;
@@ -709,5 +722,5 @@ void tm6000_close_extension(struct tm6000_core *dev)
ops->fini(dev);
}
}
- mutex_lock(&tm6000_devlist_mutex);
+ mutex_unlock(&tm6000_devlist_mutex);
}
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 93f625fc852b..18de4748f27e 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -301,33 +301,11 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-#define mass_write(addr, reg, data...) \
- { static const u8 _val[] = data; \
- rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, \
- REQ_16_SET_GET_I2C_WR1_RDN, (reg<<8)+addr, 0x00, (u8 *) _val, \
- ARRAY_SIZE(_val)); \
- if (rc < 0) { \
- printk(KERN_ERR "Error on line %d: %d\n", __LINE__, rc); \
- return rc; \
- } \
- msleep(10); \
- }
-
-static struct i2c_algorithm tm6000_algo = {
+static const struct i2c_algorithm tm6000_algo = {
.master_xfer = tm6000_i2c_xfer,
.functionality = functionality,
};
-static struct i2c_adapter tm6000_adap_template = {
- .owner = THIS_MODULE,
- .name = "tm6000",
- .algo = &tm6000_algo,
-};
-
-static struct i2c_client tm6000_client_template = {
- .name = "tm6000 internal",
-};
-
/* ----------------------------------------------------------- */
/*
@@ -337,17 +315,20 @@ static struct i2c_client tm6000_client_template = {
int tm6000_i2c_register(struct tm6000_core *dev)
{
unsigned char eedata[256];
+ int rc;
- dev->i2c_adap = tm6000_adap_template;
+ dev->i2c_adap.owner = THIS_MODULE;
+ dev->i2c_adap.algo = &tm6000_algo;
dev->i2c_adap.dev.parent = &dev->udev->dev;
- strcpy(dev->i2c_adap.name, dev->name);
+ strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
dev->i2c_adap.algo_data = dev;
- i2c_add_adapter(&dev->i2c_adap);
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
+ rc = i2c_add_adapter(&dev->i2c_adap);
+ if (rc)
+ return rc;
- dev->i2c_client = tm6000_client_template;
dev->i2c_client.adapter = &dev->i2c_adap;
-
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
+ strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
tm6000_i2c_eeprom(dev, eedata, sizeof(eedata));
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
index 6022caaa739b..21e7da40f049 100644
--- a/drivers/staging/tm6000/tm6000-input.c
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -24,8 +24,7 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -38,6 +37,10 @@ static unsigned int enable_ir = 1;
module_param(enable_ir, int, 0644);
MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
+/* number of 50ms for ON-OFF-ON power led */
+/* show IR activity */
+#define PWLED_OFF 2
+
#undef dprintk
#define dprintk(fmt, arg...) \
@@ -51,8 +54,7 @@ struct tm6000_ir_poll_result {
struct tm6000_IR {
struct tm6000_core *dev;
- struct ir_input_dev *input;
- struct ir_input_state ir;
+ struct rc_dev *rc;
char name[32];
char phys[32];
@@ -61,13 +63,16 @@ struct tm6000_IR {
struct delayed_work work;
u8 wait:1;
u8 key:1;
+ u8 pwled:1;
+ u8 pwledcnt;
+ u16 key_addr;
struct urb *int_urb;
u8 *urb_data;
int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
/* IR device properties */
- struct ir_dev_props props;
+ u64 rc_type;
};
@@ -91,26 +96,49 @@ static int tm6000_ir_config(struct tm6000_IR *ir)
u8 buf[10];
int rc;
- /* hack */
- buf[0] = 0xff;
- buf[1] = 0xff;
- buf[2] = 0xf2;
- buf[3] = 0x2b;
- buf[4] = 0x20;
- buf[5] = 0x35;
- buf[6] = 0x60;
- buf[7] = 0x04;
- buf[8] = 0xc0;
- buf[9] = 0x08;
-
- rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
- msleep(100);
-
- if (rc < 0) {
- printk(KERN_INFO "IR configuration failed");
- return rc;
+ switch (ir->rc_type) {
+ case RC_TYPE_NEC:
+ /* Setup IR decoder for NEC standard 12MHz system clock */
+ /* IR_LEADER_CNT = 0.9ms */
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa);
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30);
+ /* IR_PULSE_CNT = 0.7ms */
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20);
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0);
+ /* Remote WAKEUP = enable */
+ tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
+ /* IR_WKUP_SEL = Low byte in decoded IR data */
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff);
+ /* IR_WKU_ADD code */
+ tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff);
+ tm6000_flash_led(dev, 0);
+ msleep(100);
+ tm6000_flash_led(dev, 1);
+ break;
+ default:
+ /* hack */
+ buf[0] = 0xff;
+ buf[1] = 0xff;
+ buf[2] = 0xf2;
+ buf[3] = 0x2b;
+ buf[4] = 0x20;
+ buf[5] = 0x35;
+ buf[6] = 0x60;
+ buf[7] = 0x04;
+ buf[8] = 0xc0;
+ buf[9] = 0x08;
+
+ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
+ msleep(100);
+
+ if (rc < 0) {
+ printk(KERN_INFO "IR configuration failed");
+ return rc;
+ }
+ break;
}
+
return 0;
}
@@ -145,17 +173,28 @@ static int default_polling_getkey(struct tm6000_IR *ir,
return 0;
if (&dev->int_in) {
- if (ir->ir.ir_type == IR_TYPE_RC5)
+ switch (ir->rc_type) {
+ case RC_TYPE_RC5:
poll_result->rc_data = ir->urb_data[0];
- else
- poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8;
+ break;
+ case RC_TYPE_NEC:
+ if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) {
+ poll_result->rc_data = ir->urb_data[0]
+ | ir->urb_data[1] << 8;
+ }
+ break;
+ default:
+ poll_result->rc_data = ir->urb_data[0]
+ | ir->urb_data[1] << 8;
+ break;
+ }
} else {
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
msleep(10);
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
msleep(10);
- if (ir->ir.ir_type == IR_TYPE_RC5) {
+ if (ir->rc_type == RC_TYPE_RC5) {
rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
REQ_02_GET_IR_CODE, 0, 0, buf, 1);
@@ -188,6 +227,7 @@ static int default_polling_getkey(struct tm6000_IR *ir,
static void tm6000_ir_handle_key(struct tm6000_IR *ir)
{
+ struct tm6000_core *dev = ir->dev;
int result;
struct tm6000_ir_poll_result poll_result;
@@ -200,12 +240,21 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir)
dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
- if (ir->key) {
- ir_input_keydown(ir->input->input_dev, &ir->ir,
- (u32)poll_result.rc_data);
+ if (ir->pwled) {
+ if (ir->pwledcnt >= PWLED_OFF) {
+ ir->pwled = 0;
+ ir->pwledcnt = 0;
+ tm6000_flash_led(dev, 1);
+ } else
+ ir->pwledcnt += 1;
+ }
- ir_input_nokey(ir->input->input_dev, &ir->ir);
+ if (ir->key) {
+ rc_keydown(ir->rc, poll_result.rc_data, 0);
ir->key = 0;
+ ir->pwled = 1;
+ ir->pwledcnt = 0;
+ tm6000_flash_led(dev, 0);
}
return;
}
@@ -218,9 +267,9 @@ static void tm6000_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int tm6000_ir_start(void *priv)
+static int tm6000_ir_start(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
schedule_delayed_work(&ir->work, 0);
@@ -228,30 +277,91 @@ static int tm6000_ir_start(void *priv)
return 0;
}
-static void tm6000_ir_stop(void *priv)
+static void tm6000_ir_stop(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int tm6000_ir_change_protocol(void *priv, u64 ir_type)
+int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
+
+ if (!ir)
+ return 0;
+
+ if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
+ ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
ir->get_key = default_polling_getkey;
+ ir->rc_type = rc_type;
tm6000_ir_config(ir);
/* TODO */
return 0;
}
+int tm6000_ir_int_start(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir = dev->ir;
+ int pipe, size;
+ int err = -ENOMEM;
+
+
+ if (!ir)
+ return -ENODEV;
+
+ ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ pipe = usb_rcvintpipe(dev->udev,
+ dev->int_in.endp->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ dprintk("IR max size: %d\n", size);
+
+ ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
+ if (ir->int_urb->transfer_buffer == NULL) {
+ usb_free_urb(ir->int_urb);
+ return err;
+ }
+ dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
+ usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
+ ir->int_urb->transfer_buffer, size,
+ tm6000_ir_urb_received, dev,
+ dev->int_in.endp->desc.bInterval);
+ err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
+ if (err) {
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ return err;
+ }
+ ir->urb_data = kzalloc(size, GFP_KERNEL);
+
+ return 0;
+}
+
+void tm6000_ir_int_stop(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir = dev->ir;
+
+ if (!ir)
+ return;
+
+ usb_kill_urb(ir->int_urb);
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ ir->int_urb = NULL;
+ kfree(ir->urb_data);
+ ir->urb_data = NULL;
+}
+
int tm6000_ir_init(struct tm6000_core *dev)
{
struct tm6000_IR *ir;
- struct ir_input_dev *ir_input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
- int pipe, size, rc;
if (!enable_ir)
return -ENODEV;
@@ -263,26 +373,27 @@ int tm6000_ir_init(struct tm6000_core *dev)
return 0;
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL);
- ir_input_dev->input_dev = input_allocate_device();
- if (!ir || !ir_input_dev || !ir_input_dev->input_dev)
- goto err_out_free;
+ rc = rc_allocate_device();
+ if (!ir | !rc)
+ goto out;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = ir_input_dev;
+ ir->rc = rc;
/* input einrichten */
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = tm6000_ir_change_protocol;
- ir->props.open = tm6000_ir_start;
- ir->props.close = tm6000_ir_stop;
- ir->props.driver_type = RC_DRIVER_SCANCODE;
+ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = tm6000_ir_change_protocol;
+ rc->open = tm6000_ir_start;
+ rc->close = tm6000_ir_stop;
+ rc->driver_type = RC_DRIVER_SCANCODE;
ir->polling = 50;
+ ir->pwled = 0;
+ ir->pwledcnt = 0;
+
snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
dev->name);
@@ -290,64 +401,37 @@ int tm6000_ir_init(struct tm6000_core *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
- err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER);
- if (err < 0)
- goto err_out_free;
-
- ir_input_dev->input_dev->name = ir->name;
- ir_input_dev->input_dev->phys = ir->phys;
- ir_input_dev->input_dev->id.bustype = BUS_USB;
- ir_input_dev->input_dev->id.version = 1;
- ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
- ir_input_dev->input_dev->dev.parent = &dev->udev->dev;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->map_name = dev->ir_codes;
+ rc->driver_name = "tm6000";
+ rc->dev.parent = &dev->udev->dev;
if (&dev->int_in) {
dprintk("IR over int\n");
- ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ err = tm6000_ir_int_start(dev);
- pipe = usb_rcvintpipe(dev->udev,
- dev->int_in.endp->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
- size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
- dprintk("IR max size: %d\n", size);
-
- ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if (ir->int_urb->transfer_buffer == NULL) {
- usb_free_urb(ir->int_urb);
- goto err_out_stop;
- }
- dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
- usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
- ir->int_urb->transfer_buffer, size,
- tm6000_ir_urb_received, dev,
- dev->int_in.endp->desc.bInterval);
- rc = usb_submit_urb(ir->int_urb, GFP_KERNEL);
- if (rc) {
- kfree(ir->int_urb->transfer_buffer);
- usb_free_urb(ir->int_urb);
- err = rc;
- goto err_out_stop;
- }
- ir->urb_data = kzalloc(size, GFP_KERNEL);
+ if (err)
+ goto out;
}
/* ir register */
- err = ir_input_register(ir->input->input_dev, dev->ir_codes,
- &ir->props, "tm6000");
+ err = rc_register_device(rc);
if (err)
- goto err_out_stop;
+ goto out;
return 0;
-err_out_stop:
+out:
dev->ir = NULL;
-err_out_free:
- kfree(ir_input_dev);
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -361,19 +445,12 @@ int tm6000_ir_fini(struct tm6000_core *dev)
if (!ir)
return 0;
- ir_input_unregister(ir->input->input_dev);
+ rc_unregister_device(ir->rc);
if (ir->int_urb) {
- usb_kill_urb(ir->int_urb);
- kfree(ir->int_urb->transfer_buffer);
- usb_free_urb(ir->int_urb);
- ir->int_urb = NULL;
- kfree(ir->urb_data);
- ir->urb_data = NULL;
+ tm6000_ir_int_stop(dev);
}
- kfree(ir->input);
- ir->input = NULL;
kfree(ir);
dev->ir = NULL;
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index c5690b2a8924..8fe017c3721f 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -545,11 +545,16 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
/* De-allocates all pending stuff */
tm6000_uninit_isoc(dev);
+ /* Stop interrupt USB pipe */
+ tm6000_ir_int_stop(dev);
usb_set_interface(dev->udev,
dev->isoc_in.bInterfaceNumber,
dev->isoc_in.bAlternateSetting);
+ /* Start interrupt USB pipe */
+ tm6000_ir_int_start(dev);
+
pipe = usb_rcvisocpipe(dev->udev,
dev->isoc_in.endp->desc.bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK);
@@ -986,15 +991,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
file->f_flags & O_NONBLOCK);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
-{
- struct tm6000_fh *fh = priv;
-
- return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
-}
-#endif
-
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct tm6000_fh *fh = priv;
@@ -1438,9 +1434,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static struct video_device tm6000_template = {
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 46017b603190..bf11eeec92c7 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -266,6 +266,7 @@ struct tm6000_fh {
int tm6000_tuner_callback(void *ptr, int component, int command, int arg);
int tm6000_xc5000_callback(void *ptr, int component, int command, int arg);
int tm6000_cards_setup(struct tm6000_core *dev);
+void tm6000_flash_led(struct tm6000_core *dev, u8 state);
/* In tm6000-core.c */
@@ -332,6 +333,8 @@ int tm6000_queue_init(struct tm6000_core *dev);
int tm6000_ir_init(struct tm6000_core *dev);
int tm6000_ir_fini(struct tm6000_core *dev);
void tm6000_ir_wait(struct tm6000_core *dev, u8 state);
+int tm6000_ir_int_start(struct tm6000_core *dev);
+void tm6000_ir_int_stop(struct tm6000_core *dev);
/* Debug stuff */
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index fed25105970a..b7ac16005265 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = {
__ATTR_RO(metrics_bytes_identical),
__ATTR_RO(metrics_bytes_sent),
__ATTR_RO(metrics_cpu_kcycles_used),
- __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+ __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store),
};
/*
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 832608d3e579..08bd26a245d5 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -799,20 +799,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
spin_unlock_irqrestore(&vdev->priv_lock, flags2);
}
-
- if (!vdev->ud.tcp_socket) {
- /* tcp connection is closed */
- usbip_uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n",
- urb);
-
- usb_hcd_unlink_urb_from_ep(hcd, urb);
-
- spin_unlock_irqrestore(&the_controller->lock, flags);
- usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
- urb->status);
- spin_lock_irqsave(&the_controller->lock, flags);
- }
-
spin_unlock_irqrestore(&the_controller->lock, flags);
usbip_dbg_vhci_hc("leave\n");
diff --git a/drivers/staging/usbvideo/Kconfig b/drivers/staging/usbvideo/Kconfig
new file mode 100644
index 000000000000..566d659e6ff3
--- /dev/null
+++ b/drivers/staging/usbvideo/Kconfig
@@ -0,0 +1,15 @@
+config VIDEO_USBVIDEO
+ tristate
+
+config USB_VICAM
+ tristate "USB 3com HomeConnect (aka vicam) support (DEPRECATED)"
+ depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
+ select VIDEO_USBVIDEO
+ ---help---
+ Say Y here if you have 3com homeconnect camera (vicam).
+
+ This driver uses the deprecated V4L1 API and will be removed in
+ 2.6.39, unless someone converts it to the V4L2 API.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vicam.
diff --git a/drivers/staging/usbvideo/Makefile b/drivers/staging/usbvideo/Makefile
new file mode 100644
index 000000000000..3c99a9a2d8d3
--- /dev/null
+++ b/drivers/staging/usbvideo/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
+obj-$(CONFIG_USB_VICAM) += vicam.o
diff --git a/drivers/staging/usbvideo/TODO b/drivers/staging/usbvideo/TODO
new file mode 100644
index 000000000000..3b2c03836286
--- /dev/null
+++ b/drivers/staging/usbvideo/TODO
@@ -0,0 +1,5 @@
+This is an obsolete driver for some old webcams that still use V4L1 API.
+As V4L1 support is being removed from kernel, if nobody take care on it,
+the driver will be removed for 2.6.39.
+
+Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/staging/usbvideo/usbvideo.c
index f1fcf9744961..f1fcf9744961 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/staging/usbvideo/usbvideo.c
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/staging/usbvideo/usbvideo.h
index c66985beb8c9..95638a072b19 100644
--- a/drivers/media/video/usbvideo/usbvideo.h
+++ b/drivers/staging/usbvideo/usbvideo.h
@@ -16,7 +16,7 @@
#ifndef usbvideo_h
#define usbvideo_h
-#include <linux/videodev.h>
+#include "videodev.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/staging/usbvideo/vicam.c
index dc17cce2fbb6..ecdb121297c9 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/staging/usbvideo/vicam.c
@@ -38,7 +38,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/videodev.h>
+#include "videodev.h"
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
diff --git a/drivers/staging/usbvideo/videodev.h b/drivers/staging/usbvideo/videodev.h
new file mode 100644
index 000000000000..f11efbef1c05
--- /dev/null
+++ b/drivers/staging/usbvideo/videodev.h
@@ -0,0 +1,318 @@
+/*
+ * Video for Linux version 1 - OBSOLETE
+ *
+ * Header file for v4l1 drivers and applications, for
+ * Linux kernels 2.2.x or 2.4.x.
+ *
+ * Provides header for legacy drivers and applications
+ *
+ * See http://linuxtv.org for more info
+ *
+ */
+#ifndef __LINUX_VIDEODEV_H
+#define __LINUX_VIDEODEV_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/videodev2.h>
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
+
+struct video_capability
+{
+ char name[32];
+ int type;
+ int channels; /* Num channels */
+ int audios; /* Num audio devices */
+ int maxwidth; /* Supported width */
+ int maxheight; /* And height */
+ int minwidth; /* Supported width */
+ int minheight; /* And height */
+};
+
+
+struct video_channel
+{
+ int channel;
+ char name[32];
+ int tuners;
+ __u32 flags;
+#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
+#define VIDEO_VC_AUDIO 2 /* Channel has audio */
+ __u16 type;
+#define VIDEO_TYPE_TV 1
+#define VIDEO_TYPE_CAMERA 2
+ __u16 norm; /* Norm set by channel */
+};
+
+struct video_tuner
+{
+ int tuner;
+ char name[32];
+ unsigned long rangelow, rangehigh; /* Tuner range */
+ __u32 flags;
+#define VIDEO_TUNER_PAL 1
+#define VIDEO_TUNER_NTSC 2
+#define VIDEO_TUNER_SECAM 4
+#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
+#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
+#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
+#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
+#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
+ __u16 mode; /* PAL/NTSC/SECAM/OTHER */
+#define VIDEO_MODE_PAL 0
+#define VIDEO_MODE_NTSC 1
+#define VIDEO_MODE_SECAM 2
+#define VIDEO_MODE_AUTO 3
+ __u16 signal; /* Signal strength 16bit scale */
+};
+
+struct video_picture
+{
+ __u16 brightness;
+ __u16 hue;
+ __u16 colour;
+ __u16 contrast;
+ __u16 whiteness; /* Black and white only */
+ __u16 depth; /* Capture depth */
+ __u16 palette; /* Palette in use */
+#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
+#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
+#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
+#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
+#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
+#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
+#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
+#define VIDEO_PALETTE_YUYV 8
+#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
+#define VIDEO_PALETTE_YUV420 10
+#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
+#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
+#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
+#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
+#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
+#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
+#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
+#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
+};
+
+struct video_audio
+{
+ int audio; /* Audio channel */
+ __u16 volume; /* If settable */
+ __u16 bass, treble;
+ __u32 flags;
+#define VIDEO_AUDIO_MUTE 1
+#define VIDEO_AUDIO_MUTABLE 2
+#define VIDEO_AUDIO_VOLUME 4
+#define VIDEO_AUDIO_BASS 8
+#define VIDEO_AUDIO_TREBLE 16
+#define VIDEO_AUDIO_BALANCE 32
+ char name[16];
+#define VIDEO_SOUND_MONO 1
+#define VIDEO_SOUND_STEREO 2
+#define VIDEO_SOUND_LANG1 4
+#define VIDEO_SOUND_LANG2 8
+ __u16 mode;
+ __u16 balance; /* Stereo balance */
+ __u16 step; /* Step actual volume uses */
+};
+
+struct video_clip
+{
+ __s32 x,y;
+ __s32 width, height;
+ struct video_clip *next; /* For user use/driver use only */
+};
+
+struct video_window
+{
+ __u32 x,y; /* Position of window */
+ __u32 width,height; /* Its size */
+ __u32 chromakey;
+ __u32 flags;
+ struct video_clip __user *clips; /* Set only */
+ int clipcount;
+#define VIDEO_WINDOW_INTERLACE 1
+#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
+#define VIDEO_CLIP_BITMAP -1
+/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
+#define VIDEO_CLIPMAP_SIZE (128 * 625)
+};
+
+struct video_capture
+{
+ __u32 x,y; /* Offsets into image */
+ __u32 width, height; /* Area to capture */
+ __u16 decimation; /* Decimation divider */
+ __u16 flags; /* Flags for capture */
+#define VIDEO_CAPTURE_ODD 0 /* Temporal */
+#define VIDEO_CAPTURE_EVEN 1
+};
+
+struct video_buffer
+{
+ void *base;
+ int height,width;
+ int depth;
+ int bytesperline;
+};
+
+struct video_mmap
+{
+ unsigned int frame; /* Frame (0 - n) for double buffer */
+ int height,width;
+ unsigned int format; /* should be VIDEO_PALETTE_* */
+};
+
+struct video_key
+{
+ __u8 key[8];
+ __u32 flags;
+};
+
+struct video_mbuf
+{
+ int size; /* Total memory to map */
+ int frames; /* Frames */
+ int offsets[VIDEO_MAX_FRAME];
+};
+
+#define VIDEO_NO_UNIT (-1)
+
+struct video_unit
+{
+ int video; /* Video minor */
+ int vbi; /* VBI minor */
+ int radio; /* Radio minor */
+ int audio; /* Audio minor */
+ int teletext; /* Teletext minor */
+};
+
+struct vbi_format {
+ __u32 sampling_rate; /* in Hz */
+ __u32 samples_per_line;
+ __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
+ __s32 start[2]; /* starting line for each frame */
+ __u32 count[2]; /* count of lines for each frame */
+ __u32 flags;
+#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
+#define VBI_INTERLACED 2 /* lines are interlaced */
+};
+
+/* video_info is biased towards hardware mpeg encode/decode */
+/* but it could apply generically to any hardware compressor/decompressor */
+struct video_info
+{
+ __u32 frame_count; /* frames output since decode/encode began */
+ __u32 h_size; /* current unscaled horizontal size */
+ __u32 v_size; /* current unscaled veritcal size */
+ __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
+ __u32 picture_type; /* current picture type */
+ __u32 temporal_reference; /* current temporal reference */
+ __u8 user_data[256]; /* user data last found in compressed stream */
+ /* user_data[0] contains user data flags, user_data[1] has count */
+};
+
+/* generic structure for setting playback modes */
+struct video_play_mode
+{
+ int mode;
+ int p1;
+ int p2;
+};
+
+/* for loading microcode / fpga programming */
+struct video_code
+{
+ char loadwhat[16]; /* name or tag of file being passed */
+ int datasize;
+ __u8 *data;
+};
+
+#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
+#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
+#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
+#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
+#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
+#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
+#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
+#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
+#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
+#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
+#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
+#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
+#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
+#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
+#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
+#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
+#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
+#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
+#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
+#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
+#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
+#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
+#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
+#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
+#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
+#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
+#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
+#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
+#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
+
+
+#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
+
+/* VIDIOCSWRITEMODE */
+#define VID_WRITE_MPEG_AUD 0
+#define VID_WRITE_MPEG_VID 1
+#define VID_WRITE_OSD 2
+#define VID_WRITE_TTX 3
+#define VID_WRITE_CC 4
+#define VID_WRITE_MJPEG 5
+
+/* VIDIOCSPLAYMODE */
+#define VID_PLAY_VID_OUT_MODE 0
+ /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
+#define VID_PLAY_GENLOCK 1
+ /* p1: 0 = OFF, 1 = ON */
+ /* p2: GENLOCK FINE DELAY value */
+#define VID_PLAY_NORMAL 2
+#define VID_PLAY_PAUSE 3
+#define VID_PLAY_SINGLE_FRAME 4
+#define VID_PLAY_FAST_FORWARD 5
+#define VID_PLAY_SLOW_MOTION 6
+#define VID_PLAY_IMMEDIATE_NORMAL 7
+#define VID_PLAY_SWITCH_CHANNELS 8
+#define VID_PLAY_FREEZE_FRAME 9
+#define VID_PLAY_STILL_MODE 10
+#define VID_PLAY_MASTER_MODE 11
+ /* p1: see below */
+#define VID_PLAY_MASTER_NONE 1
+#define VID_PLAY_MASTER_VIDEO 2
+#define VID_PLAY_MASTER_AUDIO 3
+#define VID_PLAY_ACTIVE_SCANLINES 12
+ /* p1 = first active; p2 = last active */
+#define VID_PLAY_RESET 13
+#define VID_PLAY_END_MARK 14
+
+#endif /* __LINUX_VIDEODEV_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h
index 9195adf98e14..d0d71f69bc8c 100644
--- a/drivers/staging/winbond/sysdef.h
+++ b/drivers/staging/winbond/sysdef.h
@@ -2,6 +2,9 @@
#ifndef SYS_DEF_H
#define SYS_DEF_H
+
+#include <linux/delay.h>
+
#define WB_LINUX
#define WB_LINUX_WPA_PSK
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 8c3c057aa847..d0e9e0207539 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -435,12 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
int ret = 0;
struct zram *zram = queue->queuedata;
- if (unlikely(!zram->init_done)) {
- set_bit(BIO_UPTODATE, &bio->bi_flags);
- bio_endio(bio, 0);
- return 0;
- }
-
if (!valid_io_request(zram, bio)) {
zram_stat64_inc(zram, &zram->stats.invalid_io);
bio_io_error(bio);
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
index 6c574a994d11..6b3cf00b0ff4 100644
--- a/drivers/staging/zram/zram_sysfs.c
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev,
return sprintf(buf, "%llu\n", val);
}
-static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
disksize_show, disksize_store);
static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
-static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store);
+static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 13c72c629329..7d0e63c79280 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -32,6 +32,8 @@
#include <linux/thermal.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -58,6 +60,22 @@ static LIST_HEAD(thermal_tz_list);
static LIST_HEAD(thermal_cdev_list);
static DEFINE_MUTEX(thermal_list_lock);
+static unsigned int thermal_event_seqnum;
+
+static struct genl_family thermal_event_genl_family = {
+ .id = GENL_ID_GENERATE,
+ .name = THERMAL_GENL_FAMILY_NAME,
+ .version = THERMAL_GENL_VERSION,
+ .maxattr = THERMAL_GENL_ATTR_MAX,
+};
+
+static struct genl_multicast_group thermal_event_mcgrp = {
+ .name = THERMAL_GENL_MCAST_GROUP_NAME,
+};
+
+static int genetlink_init(void);
+static void genetlink_exit(void);
+
static int get_idr(struct idr *idr, struct mutex *lock, int *id)
{
int err;
@@ -823,11 +841,8 @@ static struct class thermal_class = {
* @devdata: device private data.
* @ops: standard thermal cooling devices callbacks.
*/
-struct thermal_cooling_device *thermal_cooling_device_register(char *type,
- void *devdata,
- struct
- thermal_cooling_device_ops
- *ops)
+struct thermal_cooling_device *thermal_cooling_device_register(
+ char *type, void *devdata, const struct thermal_cooling_device_ops *ops)
{
struct thermal_cooling_device *cdev;
struct thermal_zone_device *pos;
@@ -1048,13 +1063,9 @@ EXPORT_SYMBOL(thermal_zone_device_update);
* section 11.1.5.1 of the ACPI specification 3.0.
*/
struct thermal_zone_device *thermal_zone_device_register(char *type,
- int trips,
- void *devdata, struct
- thermal_zone_device_ops
- *ops, int tc1, int
- tc2,
- int passive_delay,
- int polling_delay)
+ int trips, void *devdata,
+ const struct thermal_zone_device_ops *ops,
+ int tc1, int tc2, int passive_delay, int polling_delay)
{
struct thermal_zone_device *tz;
struct thermal_cooling_device *pos;
@@ -1214,6 +1225,82 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
EXPORT_SYMBOL(thermal_zone_device_unregister);
+int generate_netlink_event(u32 orig, enum events event)
+{
+ struct sk_buff *skb;
+ struct nlattr *attr;
+ struct thermal_genl_event *thermal_event;
+ void *msg_header;
+ int size;
+ int result;
+
+ /* allocate memory */
+ size = nla_total_size(sizeof(struct thermal_genl_event)) + \
+ nla_total_size(0);
+
+ skb = genlmsg_new(size, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ /* add the genetlink message header */
+ msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++,
+ &thermal_event_genl_family, 0,
+ THERMAL_GENL_CMD_EVENT);
+ if (!msg_header) {
+ nlmsg_free(skb);
+ return -ENOMEM;
+ }
+
+ /* fill the data */
+ attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \
+ sizeof(struct thermal_genl_event));
+
+ if (!attr) {
+ nlmsg_free(skb);
+ return -EINVAL;
+ }
+
+ thermal_event = nla_data(attr);
+ if (!thermal_event) {
+ nlmsg_free(skb);
+ return -EINVAL;
+ }
+
+ memset(thermal_event, 0, sizeof(struct thermal_genl_event));
+
+ thermal_event->orig = orig;
+ thermal_event->event = event;
+
+ /* send multicast genetlink message */
+ result = genlmsg_end(skb, msg_header);
+ if (result < 0) {
+ nlmsg_free(skb);
+ return result;
+ }
+
+ result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC);
+ if (result)
+ printk(KERN_INFO "failed to send netlink event:%d", result);
+
+ return result;
+}
+EXPORT_SYMBOL(generate_netlink_event);
+
+static int genetlink_init(void)
+{
+ int result;
+
+ result = genl_register_family(&thermal_event_genl_family);
+ if (result)
+ return result;
+
+ result = genl_register_mc_group(&thermal_event_genl_family,
+ &thermal_event_mcgrp);
+ if (result)
+ genl_unregister_family(&thermal_event_genl_family);
+ return result;
+}
+
static int __init thermal_init(void)
{
int result = 0;
@@ -1225,9 +1312,15 @@ static int __init thermal_init(void)
mutex_destroy(&thermal_idr_lock);
mutex_destroy(&thermal_list_lock);
}
+ result = genetlink_init();
return result;
}
+static void genetlink_exit(void)
+{
+ genl_unregister_family(&thermal_event_genl_family);
+}
+
static void __exit thermal_exit(void)
{
class_unregister(&thermal_class);
@@ -1235,7 +1328,8 @@ static void __exit thermal_exit(void)
idr_destroy(&thermal_cdev_idr);
mutex_destroy(&thermal_idr_lock);
mutex_destroy(&thermal_list_lock);
+ genetlink_exit();
}
-subsys_initcall(thermal_init);
+fs_initcall(thermal_init);
module_exit(thermal_exit);
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 81b46585edf7..c5f8e5bda2b2 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
if (msg->len < 128)
*--dp = (msg->len << 1) | EA;
else {
- *--dp = ((msg->len & 127) << 1) | EA;
- *--dp = (msg->len >> 6) & 0xfe;
+ *--dp = (msg->len >> 7); /* bits 7 - 15 */
+ *--dp = (msg->len & 127) << 1; /* bits 0 - 6 */
}
}
@@ -968,6 +968,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
{
struct gsm_msg *msg;
msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
+ if (msg == NULL)
+ return;
msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */
msg->data[1] = (dlen << 1) | EA;
memcpy(msg->data + 2, data, dlen);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c05c5af5aa04..35480dd57a30 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
tty_lock();
+ /* some functions below drop BTM, so we need this bit */
+ set_bit(TTY_HUPPING, &tty->flags);
+
/* inuse_filps is protected by the single tty lock,
this really needs to change if we want to flush the
workqueue with the lock held */
@@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
}
spin_unlock(&tty_files_lock);
+ /*
+ * it drops BTM and thus races with reopen
+ * we protect the race by TTY_HUPPING
+ */
tty_ldisc_hangup(tty);
read_lock(&tasklist_lock);
@@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
tty->session = NULL;
tty->pgrp = NULL;
tty->ctrl_status = 0;
- set_bit(TTY_HUPPED, &tty->flags);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
/* Account for the p->signal references we killed */
@@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
* can't yet guarantee all that.
*/
set_bit(TTY_HUPPED, &tty->flags);
+ clear_bit(TTY_HUPPING, &tty->flags);
tty_ldisc_enable(tty);
tty_unlock();
@@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
{
struct tty_driver *driver = tty->driver;
- if (test_bit(TTY_CLOSING, &tty->flags))
+ if (test_bit(TTY_CLOSING, &tty->flags) ||
+ test_bit(TTY_HUPPING, &tty->flags) ||
+ test_bit(TTY_LDISC_CHANGING, &tty->flags))
return -EIO;
if (driver->type == TTY_DRIVER_TYPE_PTY &&
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index d8e96b005023..4214d58276f7 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
/* BTM here locks versus a hangup event */
WARN_ON(!tty_locked());
ret = ld->ops->open(tty);
+ if (ret)
+ clear_bit(TTY_LDISC_OPEN, &tty->flags);
return ret;
}
return 0;
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a858d2b87b94..51fe1795d5a8 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -3,7 +3,7 @@
*
* Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
* Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
* Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
*
* Userspace IO
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index a8ea2f19a0cc..a84a451159ed 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -1,7 +1,7 @@
/*
* UIO Hilscher CIF card driver
*
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
* Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
*
* Licensed under GPL version 2 only.
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
index 5a18e9f7b836..5ffdb483b015 100644
--- a/drivers/uio/uio_netx.c
+++ b/drivers/uio/uio_netx.c
@@ -2,7 +2,7 @@
* 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) 2007 Hans J. Koch <hjk@hansjkoch.de>
* (C) 2008 Manuel Traut <manut@linutronix.de>
*
* Licensed under GPL version 2 only.
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 67eb3770868f..5a7c8f1d76c6 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -41,6 +41,7 @@ config USB_ARCH_HAS_OHCI
default y if MFD_TC6393XB
default y if ARCH_W90X900
default y if ARCH_DAVINCI_DA8XX
+ default y if ARCH_CNS3XXX
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx
@@ -66,6 +67,7 @@ config USB_ARCH_HAS_EHCI
default y if ARCH_AT91SAM9G45
default y if ARCH_MXC
default y if ARCH_OMAP3
+ default y if ARCH_CNS3XXX
default PCI
# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 44447f54942f..99ac70e32556 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc)
goto err1;
}
- sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
- if (sc->kthread == ERR_PTR(-ENOMEM)) {
+ /* Create worker thread, but don't start it here. Start it after
+ * all usbatm generic initialization is done.
+ */
+ sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
+ if (IS_ERR(sc->kthread)) {
uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
goto err2;
}
@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = {
static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usb = interface_to_usbdev(intf);
+ int ret;
uea_enters(usb);
uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (UEA_IS_PREFIRM(id))
return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
- return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ if (ret == 0) {
+ struct usbatm_data *usbatm = usb_get_intfdata(intf);
+ struct uea_softc *sc = usbatm->driver_data;
+
+ /* Ensure carrier is initialized to off as early as possible */
+ UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
+
+ /* Only start the worker thread when all init is done */
+ wake_up_process(sc->kthread);
+ }
+
+ return ret;
}
static void uea_disconnect(struct usb_interface *intf)
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 05bf5a27b5b0..989e16e4ab5c 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance)
* condition: callbacks we register can be executed at once, before we have
* initialized the struct atm_dev. To protect against this, all callbacks
* abort if atm_dev->dev_data is NULL. */
- atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+ atm_dev = atm_dev_register(instance->driver_name,
+ &instance->usb_intf->dev, &usbatm_atm_devops,
+ -1, NULL);
if (!atm_dev) {
usb_err(instance, "%s: failed to register ATM device!\n", __func__);
return -1;
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
/* temp init ATM device, set to 128kbit */
atm_dev->link_rate = 128 * 1000 / 424;
- ret = sysfs_create_link(&atm_dev->class_dev.kobj,
- &instance->usb_intf->dev.kobj, "device");
- if (ret) {
- atm_err(instance, "%s: sysfs_create_link failed: %d\n",
- __func__, ret);
- goto fail_sysfs;
- }
-
if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
goto fail;
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
return 0;
fail:
- sysfs_remove_link(&atm_dev->class_dev.kobj, "device");
- fail_sysfs:
instance->atm_dev = NULL;
atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
return ret;
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
/* ATM finalize */
if (instance->atm_dev) {
- sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
atm_dev_deregister(instance->atm_dev);
instance->atm_dev = NULL;
}
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 9eed5b52d9de..bcc24779ba0e 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -107,11 +107,19 @@ config USB_SUSPEND
If you are unsure about this, say N here.
config USB_OTG
- bool
+ bool "OTG support"
depends on USB && EXPERIMENTAL
depends on USB_SUSPEND
default n
-
+ help
+ The most notable feature of USB OTG is support for a
+ "Dual-Role" device, which can act as either a device
+ or a host. The initial role is decided by the type of
+ plug inserted and can be changed later when two dual
+ role devices talk to each other.
+
+ Select this only if your board has Mini-AB/Micro-AB
+ connector.
config USB_OTG_WHITELIST
bool "Rely on OTG Targeted Peripherals List"
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 61800f77dac8..ced846ac4141 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
*/
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+ if (hcd->self.uses_pio_for_control)
+ return ret;
if (hcd->self.uses_dma) {
urb->setup_dma = dma_map_single(
hcd->self.controller,
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index b690aa35df9a..1b125c224dcf 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -343,17 +343,19 @@ static int usbfs_empty (struct dentry *dentry)
{
struct list_head *list;
- spin_lock(&dcache_lock);
-
+ spin_lock(&dentry->d_lock);
list_for_each(list, &dentry->d_subdirs) {
struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
+
+ spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED);
if (usbfs_positive(de)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&de->d_lock);
+ spin_unlock(&dentry->d_lock);
return 0;
}
+ spin_unlock(&de->d_lock);
}
-
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
return 1;
}
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 7b5cc16e4a0b..8572dad5ecbb 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1047,9 +1047,9 @@ composite_unbind(struct usb_gadget *gadget)
kfree(cdev->req->buf);
usb_ep_free_request(gadget->ep0, cdev->req);
}
+ device_remove_file(&gadget->dev, &dev_attr_suspended);
kfree(cdev);
set_gadget_data(gadget, NULL);
- device_remove_file(&gadget->dev, &dev_attr_suspended);
composite = NULL;
}
@@ -1107,14 +1107,6 @@ static int composite_bind(struct usb_gadget *gadget)
*/
usb_ep_autoconfig_reset(cdev->gadget);
- /* standardized runtime overrides for device ID data */
- if (idVendor)
- cdev->desc.idVendor = cpu_to_le16(idVendor);
- if (idProduct)
- cdev->desc.idProduct = cpu_to_le16(idProduct);
- if (bcdDevice)
- cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);
-
/* composite gadget needs to assign strings for whole device (like
* serial number), register function drivers, potentially update
* power state and consumption, etc
@@ -1126,6 +1118,14 @@ static int composite_bind(struct usb_gadget *gadget)
cdev->desc = *composite->dev;
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+ /* standardized runtime overrides for device ID data */
+ if (idVendor)
+ cdev->desc.idVendor = cpu_to_le16(idVendor);
+ if (idProduct)
+ cdev->desc.idProduct = cpu_to_le16(idProduct);
+ if (bcdDevice)
+ cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);
+
/* stirng overrides */
if (iManufacturer || !cdev->desc.iManufacturer) {
if (!iManufacturer && !composite->iManufacturer &&
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index 5bdbfe619853..77b1eb577029 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -93,9 +93,9 @@ void fsl_udc_clk_finalize(struct platform_device *pdev)
/* workaround ENGcm09152 for i.MX35 */
if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
- v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+ v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
USBPHYCTRL_OTGBASE_OFFSET));
- writel(v | USBPHYCTRL_EVDO, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+ writel(v | USBPHYCTRL_EVDO, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
USBPHYCTRL_OTGBASE_OFFSET));
}
#endif
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 3b513bafaf2a..b015561fd602 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
ro = curlun->initially_ro;
if (!ro) {
filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
- if (-EROFS == PTR_ERR(filp))
+ if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES)
ro = 1;
}
if (ro)
@@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
if (filp->f_path.dentry)
inode = filp->f_path.dentry->d_inode;
- if (inode && S_ISBLK(inode->i_mode)) {
- if (bdev_read_only(inode->i_bdev))
- ro = 1;
- } else if (!inode || !S_ISREG(inode->i_mode)) {
+ if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
LINFO(curlun, "invalid file type: %s\n", filename);
goto out;
}
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6f4f8e6a40c7..f8970d151d2a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -147,6 +147,14 @@ config USB_W90X900_EHCI
---help---
Enables support for the W90X900 USB controller
+config USB_CNS3XXX_EHCI
+ bool "Cavium CNS3XXX EHCI Module"
+ depends on USB_EHCI_HCD && ARCH_CNS3XXX
+ ---help---
+ Enable support for the CNS3XXX SOC's on-chip EHCI controller.
+ It is needed for high-speed (480Mbit/sec) USB 2.0 device
+ support.
+
config USB_OXU210HP_HCD
tristate "OXU210HP HCD support"
depends on USB
@@ -286,6 +294,13 @@ config USB_OHCI_HCD_SSB
If unsure, say N.
+config USB_CNS3XXX_OHCI
+ bool "Cavium CNS3XXX OHCI Module"
+ depends on USB_OHCI_HCD && ARCH_CNS3XXX
+ ---help---
+ Enable support for the CNS3XXX SOC's on-chip OHCI controller.
+ It is needed for low-speed USB 1.0 device support.
+
config USB_OHCI_BIG_ENDIAN_DESC
bool
depends on USB_OHCI_HCD
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c
new file mode 100644
index 000000000000..708a05b5d258
--- /dev/null
+++ b/drivers/usb/host/ehci-cns3xxx.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/atomic.h>
+#include <mach/cns3xxx.h>
+#include <mach/pm.h>
+
+static int cns3xxx_ehci_init(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs
+ + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+ hcd->has_tt = 0;
+ ehci_reset(ehci);
+
+ retval = ehci_init(hcd);
+ if (retval)
+ return retval;
+
+ ehci_port_power(ehci, 0);
+
+ return retval;
+}
+
+static const struct hc_driver cns3xxx_ehci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "CNS3XXX EHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+ .reset = cns3xxx_ehci_init,
+ .start = ehci_run,
+ .stop = ehci_stop,
+ .shutdown = ehci_shutdown,
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+ .endpoint_reset = ehci_endpoint_reset,
+ .get_frame_number = ehci_get_frame,
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ehci_bus_suspend,
+ .bus_resume = ehci_bus_resume,
+#endif
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int cns3xxx_ehci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct usb_hcd *hcd;
+ const struct hc_driver *driver = &cns3xxx_ehci_hc_driver;
+ struct resource *res;
+ int irq;
+ int retval;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "Found HC with no IRQ.\n");
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Found HC with no register addr.\n");
+ retval = -ENODEV;
+ goto err1;
+ }
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+ driver->description)) {
+ dev_dbg(dev, "controller already in use\n");
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (hcd->regs == NULL) {
+ dev_dbg(dev, "error mapping memory\n");
+ retval = -EFAULT;
+ goto err2;
+ }
+
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval == 0)
+ return retval;
+
+ iounmap(hcd->regs);
+err2:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+ usb_put_hcd(hcd);
+
+ return retval;
+}
+
+static int cns3xxx_ehci_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+
+ usb_put_hcd(hcd);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+MODULE_ALIAS("platform:cns3xxx-ehci");
+
+static struct platform_driver cns3xxx_ehci_driver = {
+ .probe = cns3xxx_ehci_probe,
+ .remove = cns3xxx_ehci_remove,
+ .driver = {
+ .name = "cns3xxx-ehci",
+ },
+};
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e9062806d4a2..d0c8f7c03e05 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_octeon_driver
#endif
+#ifdef CONFIG_USB_CNS3XXX_EHCI
+#include "ehci-cns3xxx.c"
+#define PLATFORM_DRIVER cns3xxx_ehci_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index bce85055019a..a22d2df769a9 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -28,7 +28,7 @@
#define ULPI_VIEWPORT_OFFSET 0x170
struct ehci_mxc_priv {
- struct clk *usbclk, *ahbclk;
+ struct clk *usbclk, *ahbclk, *phy1clk;
struct usb_hcd *hcd;
};
@@ -168,17 +168,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
goto err_ioremap;
}
- /* call platform specific init function */
- if (pdata->init) {
- ret = pdata->init(pdev);
- if (ret) {
- dev_err(dev, "platform init failed\n");
- goto err_init;
- }
- /* platforms need some time to settle changed IO settings */
- mdelay(10);
- }
-
/* enable clocks */
priv->usbclk = clk_get(dev, "usb");
if (IS_ERR(priv->usbclk)) {
@@ -196,6 +185,28 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
clk_enable(priv->ahbclk);
}
+ /* "dr" device has its own clock */
+ if (pdev->id == 0) {
+ priv->phy1clk = clk_get(dev, "usb_phy1");
+ if (IS_ERR(priv->phy1clk)) {
+ ret = PTR_ERR(priv->phy1clk);
+ goto err_clk_phy;
+ }
+ clk_enable(priv->phy1clk);
+ }
+
+
+ /* call platform specific init function */
+ if (pdata->init) {
+ ret = pdata->init(pdev);
+ if (ret) {
+ dev_err(dev, "platform init failed\n");
+ goto err_init;
+ }
+ /* platforms need some time to settle changed IO settings */
+ mdelay(10);
+ }
+
/* setup specific usb hw */
ret = mxc_initialize_usb_hw(pdev->id, pdata->flags);
if (ret < 0)
@@ -230,6 +241,11 @@ err_add:
if (pdata && pdata->exit)
pdata->exit(pdev);
err_init:
+ if (priv->phy1clk) {
+ clk_disable(priv->phy1clk);
+ clk_put(priv->phy1clk);
+ }
+err_clk_phy:
if (priv->ahbclk) {
clk_disable(priv->ahbclk);
clk_put(priv->ahbclk);
@@ -273,6 +289,10 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
clk_disable(priv->ahbclk);
clk_put(priv->ahbclk);
}
+ if (priv->phy1clk) {
+ clk_disable(priv->phy1clk);
+ clk_put(priv->phy1clk);
+ }
kfree(priv);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 01bb72b71832..655f3c9f88bf 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -161,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
if (pdev->revision < 0xa4)
ehci->no_selective_suspend = 1;
break;
+
+ /* MCP89 chips on the MacBookAir3,1 give EPROTO when
+ * fetching device descriptors unless LPM is disabled.
+ * There are also intermittent problems enumerating
+ * devices with PPCD enabled.
+ */
+ case 0x0d9d:
+ ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
+ ehci->has_lpm = 0;
+ ehci->has_ppcd = 0;
+ ehci->command &= ~CMD_PPCEE;
+ break;
}
break;
case PCI_VENDOR_ID_VIA:
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
new file mode 100644
index 000000000000..f05ef87e934c
--- /dev/null
+++ b/drivers/usb/host/ohci-cns3xxx.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/atomic.h>
+#include <mach/cns3xxx.h>
+#include <mach/pm.h>
+
+static int __devinit
+cns3xxx_ohci_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ ret = ohci_init(ohci);
+ if (ret < 0)
+ return ret;
+
+ ohci->num_ports = 1;
+
+ ret = ohci_run(ohci);
+ if (ret < 0) {
+ err("can't start %s", hcd->self.bus_name);
+ ohci_stop(hcd);
+ return ret;
+ }
+ return 0;
+}
+
+static const struct hc_driver cns3xxx_ohci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "CNS3XXX OHCI Host controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+ .start = cns3xxx_ohci_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+ .get_frame_number = ohci_get_frame,
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int cns3xxx_ohci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct usb_hcd *hcd;
+ const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
+ struct resource *res;
+ int irq;
+ int retval;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "Found HC with no IRQ.\n");
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ hcd = usb_create_hcd(driver, dev, dev_name(dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Found HC with no register addr.\n");
+ retval = -ENODEV;
+ goto err1;
+ }
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+ driver->description)) {
+ dev_dbg(dev, "controller already in use\n");
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_dbg(dev, "error mapping memory\n");
+ retval = -EFAULT;
+ goto err2;
+ }
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval == 0)
+ return retval;
+
+ iounmap(hcd->regs);
+err2:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+ usb_put_hcd(hcd);
+ return retval;
+}
+
+static int cns3xxx_ohci_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+
+ usb_put_hcd(hcd);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+MODULE_ALIAS("platform:cns3xxx-ohci");
+
+static struct platform_driver ohci_hcd_cns3xxx_driver = {
+ .probe = cns3xxx_ohci_probe,
+ .remove = cns3xxx_ohci_remove,
+ .driver = {
+ .name = "cns3xxx-ohci",
+ },
+};
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5179acb7aa2f..5cb6731ba443 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1111,6 +1111,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_octeon_driver
#endif
+#ifdef CONFIG_USB_CNS3XXX_OHCI
+#include "ohci-cns3xxx.c"
+#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OMAP1_PLATFORM_DRIVER) && \
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index fef5a1f9d483..5d963e350494 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
u32 __iomem *addr, u32 port_status)
{
+ /* Don't allow the USB core to disable SuperSpeed ports. */
+ if (xhci->port_array[wIndex] == 0x03) {
+ xhci_dbg(xhci, "Ignoring request to disable "
+ "SuperSpeed port.\n");
+ return;
+ }
+
/* Write 1 to disable the port */
xhci_writel(xhci, port_status | PORT_PE, addr);
port_status = xhci_readl(xhci, addr);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index d178761c3981..1d0f45f0e7a6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->dcbaa = NULL;
scratchpad_free(xhci);
+
+ xhci->num_usb2_ports = 0;
+ xhci->num_usb3_ports = 0;
+ kfree(xhci->usb2_ports);
+ kfree(xhci->usb3_ports);
+ kfree(xhci->port_array);
+
xhci->page_size = 0;
xhci->page_shift = 0;
xhci->bus_suspended = 0;
@@ -1627,6 +1634,166 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
&xhci->ir_set->erst_dequeue);
}
+static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+ u32 __iomem *addr, u8 major_revision)
+{
+ u32 temp, port_offset, port_count;
+ int i;
+
+ if (major_revision > 0x03) {
+ xhci_warn(xhci, "Ignoring unknown port speed, "
+ "Ext Cap %p, revision = 0x%x\n",
+ addr, major_revision);
+ /* Ignoring port protocol we can't understand. FIXME */
+ return;
+ }
+
+ /* Port offset and count in the third dword, see section 7.2 */
+ temp = xhci_readl(xhci, addr + 2);
+ port_offset = XHCI_EXT_PORT_OFF(temp);
+ port_count = XHCI_EXT_PORT_COUNT(temp);
+ xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
+ "count = %u, revision = 0x%x\n",
+ addr, port_offset, port_count, major_revision);
+ /* Port count includes the current port offset */
+ if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
+ /* WTF? "Valid values are ‘1’ to MaxPorts" */
+ return;
+ port_offset--;
+ for (i = port_offset; i < (port_offset + port_count); i++) {
+ /* Duplicate entry. Ignore the port if the revisions differ. */
+ if (xhci->port_array[i] != 0) {
+ xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+ " port %u\n", addr, i);
+ xhci_warn(xhci, "Port was marked as USB %u, "
+ "duplicated as USB %u\n",
+ xhci->port_array[i], major_revision);
+ /* Only adjust the roothub port counts if we haven't
+ * found a similar duplicate.
+ */
+ if (xhci->port_array[i] != major_revision &&
+ xhci->port_array[i] != (u8) -1) {
+ if (xhci->port_array[i] == 0x03)
+ xhci->num_usb3_ports--;
+ else
+ xhci->num_usb2_ports--;
+ xhci->port_array[i] = (u8) -1;
+ }
+ /* FIXME: Should we disable the port? */
+ continue;
+ }
+ xhci->port_array[i] = major_revision;
+ if (major_revision == 0x03)
+ xhci->num_usb3_ports++;
+ else
+ xhci->num_usb2_ports++;
+ }
+ /* FIXME: Should we disable ports not in the Extended Capabilities? */
+}
+
+/*
+ * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
+ * specify what speeds each port is supposed to be. We can't count on the port
+ * speed bits in the PORTSC register being correct until a device is connected,
+ * but we need to set up the two fake roothubs with the correct number of USB
+ * 3.0 and USB 2.0 ports at host controller initialization time.
+ */
+static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
+{
+ u32 __iomem *addr;
+ u32 offset;
+ unsigned int num_ports;
+ int i, port_index;
+
+ addr = &xhci->cap_regs->hcc_params;
+ offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
+ if (offset == 0) {
+ xhci_err(xhci, "No Extended Capability registers, "
+ "unable to set up roothub.\n");
+ return -ENODEV;
+ }
+
+ num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+ xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
+ if (!xhci->port_array)
+ return -ENOMEM;
+
+ /*
+ * For whatever reason, the first capability offset is from the
+ * capability register base, not from the HCCPARAMS register.
+ * See section 5.3.6 for offset calculation.
+ */
+ addr = &xhci->cap_regs->hc_capbase + offset;
+ while (1) {
+ u32 cap_id;
+
+ cap_id = xhci_readl(xhci, addr);
+ if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
+ xhci_add_in_port(xhci, num_ports, addr,
+ (u8) XHCI_EXT_PORT_MAJOR(cap_id));
+ offset = XHCI_EXT_CAPS_NEXT(cap_id);
+ if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
+ == num_ports)
+ break;
+ /*
+ * Once you're into the Extended Capabilities, the offset is
+ * always relative to the register holding the offset.
+ */
+ addr += offset;
+ }
+
+ if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
+ xhci_warn(xhci, "No ports on the roothubs?\n");
+ return -ENODEV;
+ }
+ xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
+ xhci->num_usb2_ports, xhci->num_usb3_ports);
+ /*
+ * Note we could have all USB 3.0 ports, or all USB 2.0 ports.
+ * Not sure how the USB core will handle a hub with no ports...
+ */
+ if (xhci->num_usb2_ports) {
+ xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
+ xhci->num_usb2_ports, flags);
+ if (!xhci->usb2_ports)
+ return -ENOMEM;
+
+ port_index = 0;
+ for (i = 0; i < num_ports; i++) {
+ if (xhci->port_array[i] == 0x03 ||
+ xhci->port_array[i] == 0 ||
+ xhci->port_array[i] == -1)
+ continue;
+
+ xhci->usb2_ports[port_index] =
+ &xhci->op_regs->port_status_base +
+ NUM_PORT_REGS*i;
+ xhci_dbg(xhci, "USB 2.0 port at index %u, "
+ "addr = %p\n", i,
+ xhci->usb2_ports[port_index]);
+ port_index++;
+ }
+ }
+ if (xhci->num_usb3_ports) {
+ xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
+ xhci->num_usb3_ports, flags);
+ if (!xhci->usb3_ports)
+ return -ENOMEM;
+
+ port_index = 0;
+ for (i = 0; i < num_ports; i++)
+ if (xhci->port_array[i] == 0x03) {
+ xhci->usb3_ports[port_index] =
+ &xhci->op_regs->port_status_base +
+ NUM_PORT_REGS*i;
+ xhci_dbg(xhci, "USB 3.0 port at index %u, "
+ "addr = %p\n", i,
+ xhci->usb3_ports[port_index]);
+ port_index++;
+ }
+ }
+ return 0;
+}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
@@ -1809,6 +1976,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
if (scratchpad_alloc(xhci, flags))
goto fail;
+ if (xhci_setup_port_arrays(xhci, flags))
+ goto fail;
return 0;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 06fca0835b52..45e4a3108cc3 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1549,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
cmd_completion = command->completion;
cmd_status = &command->status;
command->command_trb = xhci->cmd_ring->enqueue;
+
+ /* Enqueue pointer can be left pointing to the link TRB,
+ * we must handle that
+ */
+ if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
+ == TRB_TYPE(TRB_LINK))
+ command->command_trb =
+ xhci->cmd_ring->enq_seg->next->trbs;
+
list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
} else {
in_ctx = virt_dev->in_ctx;
@@ -2272,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
/* 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;
+
+ /* Enqueue pointer can be left pointing to the link TRB,
+ * we must handle that
+ */
+ if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
+ == TRB_TYPE(TRB_LINK))
+ reset_device_cmd->command_trb =
+ xhci->cmd_ring->enq_seg->next->trbs;
+
list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
ret = xhci_queue_reset_device(xhci, slot_id);
if (ret) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 85e65647d445..170c367112d2 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -454,6 +454,24 @@ struct xhci_doorbell_array {
/**
+ * struct xhci_protocol_caps
+ * @revision: major revision, minor revision, capability ID,
+ * and next capability pointer.
+ * @name_string: Four ASCII characters to say which spec this xHC
+ * follows, typically "USB ".
+ * @port_info: Port offset, count, and protocol-defined information.
+ */
+struct xhci_protocol_caps {
+ u32 revision;
+ u32 name_string;
+ u32 port_info;
+};
+
+#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff)
+#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff)
+#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff)
+
+/**
* struct xhci_container_ctx
* @type: Type of context. Used to calculated offsets to contained contexts.
* @size: Size of the context data
@@ -1240,6 +1258,14 @@ struct xhci_hcd {
u32 suspended_ports[8]; /* which ports are
suspended */
unsigned long resume_done[MAX_HC_PORTS];
+ /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
+ u8 *port_array;
+ /* Array of pointers to USB 3.0 PORTSC registers */
+ u32 __iomem **usb3_ports;
+ unsigned int num_usb3_ports;
+ /* Array of pointers to USB 2.0 PORTSC registers */
+ u32 __iomem **usb2_ports;
+ unsigned int num_usb2_ports;
};
/* For testing purposes */
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 796e2f68f749..4ff21587ab03 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -3,7 +3,7 @@
/*
* uss720.c -- USS720 USB Parport Cable.
*
- * Copyright (C) 1999, 2005
+ * Copyright (C) 1999, 2005, 2010
* Thomas Sailer (t.sailer@alumni.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
@@ -776,6 +776,8 @@ static const struct usb_device_id uss720_table[] = {
{ USB_DEVICE(0x0557, 0x2001) },
{ USB_DEVICE(0x0729, 0x1284) },
{ USB_DEVICE(0x1293, 0x0002) },
+ { USB_DEVICE(0x1293, 0x0002) },
+ { USB_DEVICE(0x050d, 0x0002) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 719c6180b31f..ac5bfd619e62 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = {
.open = yurex_open,
.release = yurex_release,
.fasync = yurex_fasync,
+ .llseek = default_llseek,
};
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index e6669fc3b804..99beebce8550 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2116,12 +2116,15 @@ bad_config:
* Otherwise, wait till the gadget driver hooks up.
*/
if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+ struct usb_hcd *hcd = musb_to_hcd(musb);
+
MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_IDLE;
status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
+ hcd->self.uses_pio_for_control = 1;
DBG(1, "%s mode, status %d, devctl %02x %c\n",
"HOST", status,
musb_readb(musb->mregs, MUSB_DEVCTL),
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 36cfd060dbe5..9d6ade82b9f2 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -92,6 +92,59 @@
/* ----------------------------------------------------------------------- */
+/* Maps the buffer to dma */
+
+static inline void map_dma_buffer(struct musb_request *request,
+ struct musb *musb)
+{
+ if (request->request.dma == DMA_ADDR_INVALID) {
+ request->request.dma = dma_map_single(
+ musb->controller,
+ request->request.buf,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->mapped = 1;
+ } else {
+ dma_sync_single_for_device(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->mapped = 0;
+ }
+}
+
+/* Unmap the buffer from dma and maps it back to cpu */
+static inline void unmap_dma_buffer(struct musb_request *request,
+ struct musb *musb)
+{
+ if (request->request.dma == DMA_ADDR_INVALID) {
+ DBG(20, "not unmapping a never mapped buffer\n");
+ return;
+ }
+ if (request->mapped) {
+ dma_unmap_single(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->request.dma = DMA_ADDR_INVALID;
+ request->mapped = 0;
+ } else {
+ dma_sync_single_for_cpu(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+
+ }
+}
+
/*
* Immediately complete a request.
*
@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)
ep->busy = 1;
spin_unlock(&musb->lock);
- if (is_dma_capable()) {
- if (req->mapped) {
- dma_unmap_single(musb->controller,
- req->request.dma,
- req->request.length,
- req->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- req->request.dma = DMA_ADDR_INVALID;
- req->mapped = 0;
- } else if (req->request.dma != DMA_ADDR_INVALID)
- dma_sync_single_for_cpu(musb->controller,
- req->request.dma,
- req->request.length,
- req->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- }
+ if (is_dma_capable() && ep->dma)
+ unmap_dma_buffer(req, musb);
if (request->status == 0)
DBG(5, "%s done request %p, %d/%d\n",
ep->end_point.name, request,
@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
#endif
if (!use_dma) {
+ /*
+ * Unmap the dma buffer back to cpu if dma channel
+ * programming fails
+ */
+ if (is_dma_capable() && musb_ep->dma)
+ unmap_dma_buffer(req, musb);
+
musb_write_fifo(musb_ep->hw_ep, fifo_count,
(u8 *) (request->buf + request->actual));
request->actual += fifo_count;
@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
return;
}
#endif
+ /*
+ * Unmap the dma buffer back to cpu if dma channel
+ * programming fails. This buffer is mapped if the
+ * channel allocation is successful
+ */
+ if (is_dma_capable() && musb_ep->dma) {
+ unmap_dma_buffer(req, musb);
+
+ /*
+ * Clear DMAENAB and AUTOCLEAR for the
+ * PIO mode transfer
+ */
+ csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
+ musb_writew(epio, MUSB_RXCSR, csr);
+ }
musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
(request->buf + request->actual));
@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
if (!request)
return;
}
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
exit:
+#endif
/* Analyze request */
rxstate(musb, to_musb_request(request));
}
@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
request->epnum = musb_ep->current_epnum;
request->tx = musb_ep->is_in;
- if (is_dma_capable() && musb_ep->dma) {
- if (request->request.dma == DMA_ADDR_INVALID) {
- request->request.dma = dma_map_single(
- musb->controller,
- request->request.buf,
- request->request.length,
- request->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- request->mapped = 1;
- } else {
- dma_sync_single_for_device(musb->controller,
- request->request.dma,
- request->request.length,
- request->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- request->mapped = 0;
- }
- } else
+ if (is_dma_capable() && musb_ep->dma)
+ map_dma_buffer(request, musb);
+ else
request->mapped = 0;
spin_lock_irqsave(&musb->lock, lockflags);
@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
spin_unlock_irqrestore(&musb->lock, flags);
if (is_otg_enabled(musb)) {
+ struct usb_hcd *hcd = musb_to_hcd(musb);
+
DBG(3, "OTG startup...\n");
/* REVISIT: funcall to other code, which also
@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
musb->gadget_driver = NULL;
musb->g.dev.driver = NULL;
spin_unlock_irqrestore(&musb->lock, flags);
+ } else {
+ hcd->self.uses_pio_for_control = 1;
}
}
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 76f8b3556672..2dec50013528 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+ { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
@@ -794,6 +796,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 263f62551197..bf0867285481 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -114,6 +114,9 @@
/* Lenz LI-USB Computer Interface. */
#define FTDI_LENZ_LIUSB_PID 0xD780
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID 0xF070
+
/*
* Xsens Technologies BV products (http://www.xsens.com).
*/
@@ -721,6 +724,7 @@
*/
#define RTSYSTEMS_VID 0x2100 /* Vendor ID */
#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */
/*
* Bayer Ascensia Contour blood glucose meter USB-converter cable.
@@ -1077,6 +1081,11 @@
#define MJSG_HD_RADIO_PID 0x937C
/*
+ * D.O.Tec products (http://www.directout.eu)
+ */
+#define FTDI_DOTEC_PID 0x9868
+
+/*
* Xverve Signalyzer tools (http://www.signalyzer.com/)
*/
#define XVERVE_SIGNALYZER_ST_PID 0xBCA0
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 861223f2af6e..6954de50c0ff 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -51,6 +51,7 @@ static struct usb_driver usb_serial_driver = {
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.no_dynamic_id = 1,
+ .supports_autosuspend = 1,
};
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
@@ -1343,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver)
return -ENODEV;
fixup_generic(driver);
+ if (driver->usb_driver)
+ driver->usb_driver->supports_autosuspend = 1;
if (!driver->description)
driver->description = driver->driver.name;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 6ccdd3dd5259..fcc1e32ce256 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -481,6 +481,13 @@ UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64),
+/* Reported by Vitaly Kuznetsov <vitty@altlinux.ru> */
+UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999,
+ "Samsung",
+ "YP-CP3",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),
+
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
* Device uses standards-violating 32-byte Bulk Command Block Wrappers and
* reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index f442668a1e52..9b3ca103135f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -10,7 +10,6 @@
#include <linux/eventfd.h>
#include <linux/vhost.h>
#include <linux/virtio_net.h>
-#include <linux/mmu_context.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -143,7 +142,6 @@ static void handle_tx(struct vhost_net *net)
return;
}
- use_mm(net->dev.mm);
mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
@@ -208,7 +206,6 @@ static void handle_tx(struct vhost_net *net)
}
mutex_unlock(&vq->mutex);
- unuse_mm(net->dev.mm);
}
static int peek_head_len(struct sock *sk)
@@ -313,7 +310,6 @@ static void handle_rx_big(struct vhost_net *net)
if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
return;
- use_mm(net->dev.mm);
mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
hdr_size = vq->vhost_hlen;
@@ -392,7 +388,6 @@ static void handle_rx_big(struct vhost_net *net)
}
mutex_unlock(&vq->mutex);
- unuse_mm(net->dev.mm);
}
/* Expects to be always run from workqueue - which acts as
@@ -424,7 +419,6 @@ static void handle_rx_mergeable(struct vhost_net *net)
if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
return;
- use_mm(net->dev.mm);
mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
vhost_hlen = vq->vhost_hlen;
@@ -459,7 +453,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
move_iovec_hdr(vq->iov, vq->hdr, vhost_hlen, in);
else
/* Copy the header for use in VIRTIO_NET_F_MRG_RXBUF:
- * needed because sendmsg can modify msg_iov. */
+ * needed because recvmsg can modify msg_iov. */
copy_iovec_hdr(vq->iov, vq->hdr, sock_hlen, in);
msg.msg_iovlen = in;
err = sock->ops->recvmsg(NULL, sock, &msg,
@@ -501,7 +495,6 @@ static void handle_rx_mergeable(struct vhost_net *net)
}
mutex_unlock(&vq->mutex);
- unuse_mm(net->dev.mm);
}
static void handle_rx(struct vhost_net *net)
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
new file mode 100644
index 000000000000..099f30230d06
--- /dev/null
+++ b/drivers/vhost/test.c
@@ -0,0 +1,320 @@
+/* Copyright (C) 2009 Red Hat, Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * test virtio server in host kernel.
+ */
+
+#include <linux/compat.h>
+#include <linux/eventfd.h>
+#include <linux/vhost.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/rcupdate.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+
+#include "test.h"
+#include "vhost.c"
+
+/* Max number of bytes transferred before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others. */
+#define VHOST_TEST_WEIGHT 0x80000
+
+enum {
+ VHOST_TEST_VQ = 0,
+ VHOST_TEST_VQ_MAX = 1,
+};
+
+struct vhost_test {
+ struct vhost_dev dev;
+ struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX];
+};
+
+/* Expects to be always run from workqueue - which acts as
+ * read-size critical section for our kind of RCU. */
+static void handle_vq(struct vhost_test *n)
+{
+ struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_TEST_VQ];
+ unsigned out, in;
+ int head;
+ size_t len, total_len = 0;
+ void *private;
+
+ private = rcu_dereference_check(vq->private_data, 1);
+ if (!private)
+ return;
+
+ mutex_lock(&vq->mutex);
+ vhost_disable_notify(vq);
+
+ for (;;) {
+ head = vhost_get_vq_desc(&n->dev, vq, vq->iov,
+ ARRAY_SIZE(vq->iov),
+ &out, &in,
+ NULL, NULL);
+ /* On error, stop handling until the next kick. */
+ if (unlikely(head < 0))
+ break;
+ /* Nothing new? Wait for eventfd to tell us they refilled. */
+ if (head == vq->num) {
+ if (unlikely(vhost_enable_notify(vq))) {
+ vhost_disable_notify(vq);
+ continue;
+ }
+ break;
+ }
+ if (in) {
+ vq_err(vq, "Unexpected descriptor format for TX: "
+ "out %d, int %d\n", out, in);
+ break;
+ }
+ len = iov_length(vq->iov, out);
+ /* Sanity check */
+ if (!len) {
+ vq_err(vq, "Unexpected 0 len for TX\n");
+ break;
+ }
+ vhost_add_used_and_signal(&n->dev, vq, head, 0);
+ total_len += len;
+ if (unlikely(total_len >= VHOST_TEST_WEIGHT)) {
+ vhost_poll_queue(&vq->poll);
+ break;
+ }
+ }
+
+ mutex_unlock(&vq->mutex);
+}
+
+static void handle_vq_kick(struct vhost_work *work)
+{
+ struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
+ poll.work);
+ struct vhost_test *n = container_of(vq->dev, struct vhost_test, dev);
+
+ handle_vq(n);
+}
+
+static int vhost_test_open(struct inode *inode, struct file *f)
+{
+ struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
+ struct vhost_dev *dev;
+ int r;
+
+ if (!n)
+ return -ENOMEM;
+
+ dev = &n->dev;
+ n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
+ r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
+ if (r < 0) {
+ kfree(n);
+ return r;
+ }
+
+ f->private_data = n;
+
+ return 0;
+}
+
+static void *vhost_test_stop_vq(struct vhost_test *n,
+ struct vhost_virtqueue *vq)
+{
+ void *private;
+
+ mutex_lock(&vq->mutex);
+ private = rcu_dereference_protected(vq->private_data,
+ lockdep_is_held(&vq->mutex));
+ rcu_assign_pointer(vq->private_data, NULL);
+ mutex_unlock(&vq->mutex);
+ return private;
+}
+
+static void vhost_test_stop(struct vhost_test *n, void **privatep)
+{
+ *privatep = vhost_test_stop_vq(n, n->vqs + VHOST_TEST_VQ);
+}
+
+static void vhost_test_flush_vq(struct vhost_test *n, int index)
+{
+ vhost_poll_flush(&n->dev.vqs[index].poll);
+}
+
+static void vhost_test_flush(struct vhost_test *n)
+{
+ vhost_test_flush_vq(n, VHOST_TEST_VQ);
+}
+
+static int vhost_test_release(struct inode *inode, struct file *f)
+{
+ struct vhost_test *n = f->private_data;
+ void *private;
+
+ vhost_test_stop(n, &private);
+ vhost_test_flush(n);
+ vhost_dev_cleanup(&n->dev);
+ /* We do an extra flush before freeing memory,
+ * since jobs can re-queue themselves. */
+ vhost_test_flush(n);
+ kfree(n);
+ return 0;
+}
+
+static long vhost_test_run(struct vhost_test *n, int test)
+{
+ void *priv, *oldpriv;
+ struct vhost_virtqueue *vq;
+ int r, index;
+
+ if (test < 0 || test > 1)
+ return -EINVAL;
+
+ mutex_lock(&n->dev.mutex);
+ r = vhost_dev_check_owner(&n->dev);
+ if (r)
+ goto err;
+
+ for (index = 0; index < n->dev.nvqs; ++index) {
+ /* Verify that ring has been setup correctly. */
+ if (!vhost_vq_access_ok(&n->vqs[index])) {
+ r = -EFAULT;
+ goto err;
+ }
+ }
+
+ for (index = 0; index < n->dev.nvqs; ++index) {
+ vq = n->vqs + index;
+ mutex_lock(&vq->mutex);
+ priv = test ? n : NULL;
+
+ /* start polling new socket */
+ oldpriv = rcu_dereference_protected(vq->private_data,
+ lockdep_is_held(&vq->mutex));
+ rcu_assign_pointer(vq->private_data, priv);
+
+ mutex_unlock(&vq->mutex);
+
+ if (oldpriv) {
+ vhost_test_flush_vq(n, index);
+ }
+ }
+
+ mutex_unlock(&n->dev.mutex);
+ return 0;
+
+err:
+ mutex_unlock(&n->dev.mutex);
+ return r;
+}
+
+static long vhost_test_reset_owner(struct vhost_test *n)
+{
+ void *priv = NULL;
+ long err;
+ mutex_lock(&n->dev.mutex);
+ err = vhost_dev_check_owner(&n->dev);
+ if (err)
+ goto done;
+ vhost_test_stop(n, &priv);
+ vhost_test_flush(n);
+ err = vhost_dev_reset_owner(&n->dev);
+done:
+ mutex_unlock(&n->dev.mutex);
+ return err;
+}
+
+static int vhost_test_set_features(struct vhost_test *n, u64 features)
+{
+ mutex_lock(&n->dev.mutex);
+ if ((features & (1 << VHOST_F_LOG_ALL)) &&
+ !vhost_log_access_ok(&n->dev)) {
+ mutex_unlock(&n->dev.mutex);
+ return -EFAULT;
+ }
+ n->dev.acked_features = features;
+ smp_wmb();
+ vhost_test_flush(n);
+ mutex_unlock(&n->dev.mutex);
+ return 0;
+}
+
+static long vhost_test_ioctl(struct file *f, unsigned int ioctl,
+ unsigned long arg)
+{
+ struct vhost_test *n = f->private_data;
+ void __user *argp = (void __user *)arg;
+ u64 __user *featurep = argp;
+ int test;
+ u64 features;
+ int r;
+ switch (ioctl) {
+ case VHOST_TEST_RUN:
+ if (copy_from_user(&test, argp, sizeof test))
+ return -EFAULT;
+ return vhost_test_run(n, test);
+ case VHOST_GET_FEATURES:
+ features = VHOST_FEATURES;
+ if (copy_to_user(featurep, &features, sizeof features))
+ return -EFAULT;
+ return 0;
+ case VHOST_SET_FEATURES:
+ if (copy_from_user(&features, featurep, sizeof features))
+ return -EFAULT;
+ if (features & ~VHOST_FEATURES)
+ return -EOPNOTSUPP;
+ return vhost_test_set_features(n, features);
+ case VHOST_RESET_OWNER:
+ return vhost_test_reset_owner(n);
+ default:
+ mutex_lock(&n->dev.mutex);
+ r = vhost_dev_ioctl(&n->dev, ioctl, arg);
+ vhost_test_flush(n);
+ mutex_unlock(&n->dev.mutex);
+ return r;
+ }
+}
+
+#ifdef CONFIG_COMPAT
+static long vhost_test_compat_ioctl(struct file *f, unsigned int ioctl,
+ unsigned long arg)
+{
+ return vhost_test_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations vhost_test_fops = {
+ .owner = THIS_MODULE,
+ .release = vhost_test_release,
+ .unlocked_ioctl = vhost_test_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = vhost_test_compat_ioctl,
+#endif
+ .open = vhost_test_open,
+ .llseek = noop_llseek,
+};
+
+static struct miscdevice vhost_test_misc = {
+ MISC_DYNAMIC_MINOR,
+ "vhost-test",
+ &vhost_test_fops,
+};
+
+static int vhost_test_init(void)
+{
+ return misc_register(&vhost_test_misc);
+}
+module_init(vhost_test_init);
+
+static void vhost_test_exit(void)
+{
+ misc_deregister(&vhost_test_misc);
+}
+module_exit(vhost_test_exit);
+
+MODULE_VERSION("0.0.1");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Michael S. Tsirkin");
+MODULE_DESCRIPTION("Host kernel side for virtio simulator");
diff --git a/drivers/vhost/test.h b/drivers/vhost/test.h
new file mode 100644
index 000000000000..1fef5df82153
--- /dev/null
+++ b/drivers/vhost/test.h
@@ -0,0 +1,7 @@
+#ifndef LINUX_VHOST_TEST_H
+#define LINUX_VHOST_TEST_H
+
+/* Start a given test on the virtio null device. 0 stops all tests. */
+#define VHOST_TEST_RUN _IOW(VHOST_VIRTIO, 0x31, int)
+
+#endif
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 94701ff3a23a..38244f59cdd9 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -15,6 +15,7 @@
#include <linux/vhost.h>
#include <linux/virtio_net.h>
#include <linux/mm.h>
+#include <linux/mmu_context.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
@@ -29,8 +30,6 @@
#include <linux/if_packet.h>
#include <linux/if_arp.h>
-#include <net/sock.h>
-
#include "vhost.h"
enum {
@@ -157,7 +156,6 @@ static void vhost_vq_reset(struct vhost_dev *dev,
vq->avail_idx = 0;
vq->last_used_idx = 0;
vq->used_flags = 0;
- vq->used_flags = 0;
vq->log_used = false;
vq->log_addr = -1ull;
vq->vhost_hlen = 0;
@@ -178,6 +176,8 @@ static int vhost_worker(void *data)
struct vhost_work *work = NULL;
unsigned uninitialized_var(seq);
+ use_mm(dev->mm);
+
for (;;) {
/* mb paired w/ kthread_stop */
set_current_state(TASK_INTERRUPTIBLE);
@@ -192,7 +192,7 @@ static int vhost_worker(void *data)
if (kthread_should_stop()) {
spin_unlock_irq(&dev->work_lock);
__set_current_state(TASK_RUNNING);
- return 0;
+ break;
}
if (!list_empty(&dev->work_list)) {
work = list_first_entry(&dev->work_list,
@@ -210,6 +210,8 @@ static int vhost_worker(void *data)
schedule();
}
+ unuse_mm(dev->mm);
+ return 0;
}
/* Helper to allocate iovec buffers for all vqs. */
@@ -402,15 +404,14 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
kfree(rcu_dereference_protected(dev->memory,
lockdep_is_held(&dev->mutex)));
RCU_INIT_POINTER(dev->memory, NULL);
- if (dev->mm)
- mmput(dev->mm);
- dev->mm = NULL;
-
WARN_ON(!list_empty(&dev->work_list));
if (dev->worker) {
kthread_stop(dev->worker);
dev->worker = NULL;
}
+ if (dev->mm)
+ mmput(dev->mm);
+ dev->mm = NULL;
}
static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz)
@@ -881,14 +882,15 @@ static int set_bit_to_user(int nr, void __user *addr)
static int log_write(void __user *log_base,
u64 write_address, u64 write_length)
{
+ u64 write_page = write_address / VHOST_PAGE_SIZE;
int r;
if (!write_length)
return 0;
- write_address /= VHOST_PAGE_SIZE;
+ write_length += write_address % VHOST_PAGE_SIZE;
for (;;) {
u64 base = (u64)(unsigned long)log_base;
- u64 log = base + write_address / 8;
- int bit = write_address % 8;
+ u64 log = base + write_page / 8;
+ int bit = write_page % 8;
if ((u64)(unsigned long)log != log)
return -EFAULT;
r = set_bit_to_user(bit, (void __user *)(unsigned long)log);
@@ -897,7 +899,7 @@ static int log_write(void __user *log_base,
if (write_length <= VHOST_PAGE_SIZE)
break;
write_length -= VHOST_PAGE_SIZE;
- write_address += VHOST_PAGE_SIZE;
+ write_page += 1;
}
return r;
}
@@ -1092,7 +1094,7 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
/* Check it isn't doing very strange things with descriptor numbers. */
last_avail_idx = vq->last_avail_idx;
- if (unlikely(get_user(vq->avail_idx, &vq->avail->idx))) {
+ if (unlikely(__get_user(vq->avail_idx, &vq->avail->idx))) {
vq_err(vq, "Failed to access avail idx at %p\n",
&vq->avail->idx);
return -EFAULT;
@@ -1113,8 +1115,8 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
/* Grab the next descriptor number they're advertising, and increment
* the index we've seen. */
- if (unlikely(get_user(head,
- &vq->avail->ring[last_avail_idx % vq->num]))) {
+ if (unlikely(__get_user(head,
+ &vq->avail->ring[last_avail_idx % vq->num]))) {
vq_err(vq, "Failed to read head: idx %d address %p\n",
last_avail_idx,
&vq->avail->ring[last_avail_idx % vq->num]);
@@ -1213,17 +1215,17 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
/* The virtqueue contains a ring of used buffers. Get a pointer to the
* next entry in that used ring. */
used = &vq->used->ring[vq->last_used_idx % vq->num];
- if (put_user(head, &used->id)) {
+ if (__put_user(head, &used->id)) {
vq_err(vq, "Failed to write used id");
return -EFAULT;
}
- if (put_user(len, &used->len)) {
+ if (__put_user(len, &used->len)) {
vq_err(vq, "Failed to write used len");
return -EFAULT;
}
/* Make sure buffer is written before we update index. */
smp_wmb();
- if (put_user(vq->last_used_idx + 1, &vq->used->idx)) {
+ if (__put_user(vq->last_used_idx + 1, &vq->used->idx)) {
vq_err(vq, "Failed to increment used idx");
return -EFAULT;
}
@@ -1255,7 +1257,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
start = vq->last_used_idx % vq->num;
used = vq->used->ring + start;
- if (copy_to_user(used, heads, count * sizeof *used)) {
+ if (__copy_to_user(used, heads, count * sizeof *used)) {
vq_err(vq, "Failed to write used");
return -EFAULT;
}
@@ -1316,7 +1318,7 @@ void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
* interrupts. */
smp_mb();
- if (get_user(flags, &vq->avail->flags)) {
+ if (__get_user(flags, &vq->avail->flags)) {
vq_err(vq, "Failed to get flags");
return;
}
@@ -1367,7 +1369,7 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq)
/* They could have slipped one in as we were doing that: make
* sure it's written, then check again. */
smp_mb();
- r = get_user(avail_idx, &vq->avail->idx);
+ r = __get_user(avail_idx, &vq->avail->idx);
if (r) {
vq_err(vq, "Failed to check avail idx at %p: %d\n",
&vq->avail->idx, r);
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 073d06ae091f..2af44b7b1f3f 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -102,7 +102,7 @@ struct vhost_virtqueue {
* flush the vhost_work instead of synchronize_rcu. Therefore readers do
* not need to call rcu_read_lock/rcu_read_unlock: the beginning of
* vhost_work execution acts instead of rcu_read_lock() and the end of
- * vhost_work execution acts instead of rcu_read_lock().
+ * vhost_work execution acts instead of rcu_read_unlock().
* Writers use virtqueue mutex. */
void __rcu *private_data;
/* Log write descriptors */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 27c1fb4b1e0d..ab77297fbed2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1850,6 +1850,16 @@ config FB_PXA_PARAMETERS
<file:Documentation/fb/pxafb.txt> describes the available parameters.
+config PXA3XX_GCU
+ tristate "PXA3xx 2D graphics accelerator driver"
+ depends on FB_PXA
+ help
+ Kernelspace driver for the 2D graphics controller unit (GCU)
+ found on PXA3xx processors. There is a counterpart driver in the
+ DirectFB suite, see http://www.directfb.org/
+
+ If you compile this as a module, it will be called pxa3xx_gcu.
+
config FB_MBX
tristate "2700G LCD framebuffer support"
depends on FB && ARCH_PXA
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 485e8ed1318c..9260a898f343 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_PXA168) += pxa168fb.o
+obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
obj-$(CONFIG_FB_W100) += w100fb.o
obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index a4f4546f0be0..397d15eb1ea8 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -242,6 +242,7 @@ static int cr_backlight_remove(struct platform_device *pdev)
backlight_device_unregister(crp->cr_backlight_device);
lcd_device_unregister(crp->cr_lcd_device);
pci_dev_put(lpc_dev);
+ kfree(crp);
return 0;
}
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index cad7d45c8bac..c265aed09e04 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1029,10 +1029,6 @@ static int __init fb_probe(struct platform_device *device)
goto err_release_pl_mem;
}
- ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
- if (ret)
- goto err_release_pl_mem;
-
/* Initialize par */
da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
@@ -1060,7 +1056,7 @@ static int __init fb_probe(struct platform_device *device)
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
- goto err_free_irq;
+ goto err_release_pl_mem;
da8xx_fb_info->cmap.len = par->palette_sz;
/* initialize var_screeninfo */
@@ -1088,8 +1084,13 @@ static int __init fb_probe(struct platform_device *device)
goto err_cpu_freq;
}
#endif
+
+ ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+ if (ret)
+ goto irq_freq;
return 0;
+irq_freq:
#ifdef CONFIG_CPU_FREQ
err_cpu_freq:
unregister_framebuffer(da8xx_fb_info);
@@ -1098,9 +1099,6 @@ err_cpu_freq:
err_dealloc_cmap:
fb_dealloc_cmap(&da8xx_fb_info->cmap);
-err_free_irq:
- free_irq(par->irq, par);
-
err_release_pl_mem:
dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
par->p_palette_base);
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index affdf3e32cf3..5c3960da755a 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -80,6 +80,7 @@ static const struct fb_cmap default_16_colors = {
* @cmap: frame buffer colormap structure
* @len: length of @cmap
* @transp: boolean, 1 if there is transparency, 0 otherwise
+ * @flags: flags for kmalloc memory allocation
*
* Allocates memory for a colormap @cmap. @len is the
* number of entries in the palette.
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0e6aa3d96a42..4ac1201ad6c2 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1458,7 +1458,7 @@ static bool apertures_overlap(struct aperture *gen, struct aperture *hw)
if (gen->base == hw->base)
return true;
/* is the generic aperture base inside the hw base->hw base+size */
- if (gen->base > hw->base && gen->base <= hw->base + hw->size)
+ if (gen->base > hw->base && gen->base < hw->base + hw->size)
return true;
return false;
}
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
index e4c4d89b7860..be8ccb47ebe0 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/geode/lxfb.h
@@ -22,6 +22,7 @@
#define DC_HFILT_COUNT 0x100
#define DC_VFILT_COUNT 0x100
#define VP_COEFF_SIZE 0x1000
+#define VP_PAL_COUNT 0x100
#define OUTPUT_CRT 0x01
#define OUTPUT_PANEL 0x02
@@ -48,7 +49,8 @@ struct lxfb_par {
uint64_t vp[VP_REG_COUNT];
uint64_t fp[FP_REG_COUNT];
- uint32_t pal[DC_PAL_COUNT];
+ uint32_t dc_pal[DC_PAL_COUNT];
+ uint32_t vp_pal[VP_PAL_COUNT];
uint32_t hcoeff[DC_HFILT_COUNT * 2];
uint32_t vcoeff[DC_VFILT_COUNT];
uint32_t vp_coeff[VP_COEFF_SIZE / 4];
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
index 85ec7f64c42a..79e9abc72b83 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/geode/lxfb_ops.c
@@ -610,10 +610,15 @@ static void lx_save_regs(struct lxfb_par *par)
memcpy(par->vp, par->vp_regs, sizeof(par->vp));
memcpy(par->fp, par->vp_regs + VP_FP_START, sizeof(par->fp));
- /* save the palette */
+ /* save the display controller palette */
write_dc(par, DC_PAL_ADDRESS, 0);
- for (i = 0; i < ARRAY_SIZE(par->pal); i++)
- par->pal[i] = read_dc(par, DC_PAL_DATA);
+ for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+ par->dc_pal[i] = read_dc(par, DC_PAL_DATA);
+
+ /* save the video processor palette */
+ write_vp(par, VP_PAR, 0);
+ for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+ par->vp_pal[i] = read_vp(par, VP_PDR);
/* save the horizontal filter coefficients */
filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -706,8 +711,8 @@ static void lx_restore_display_ctlr(struct lxfb_par *par)
/* restore the palette */
write_dc(par, DC_PAL_ADDRESS, 0);
- for (i = 0; i < ARRAY_SIZE(par->pal); i++)
- write_dc(par, DC_PAL_DATA, par->pal[i]);
+ for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+ write_dc(par, DC_PAL_DATA, par->dc_pal[i]);
/* restore the horizontal filter coefficients */
filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -751,6 +756,11 @@ static void lx_restore_video_proc(struct lxfb_par *par)
}
}
+ /* restore video processor palette */
+ write_vp(par, VP_PAR, 0);
+ for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+ write_vp(par, VP_PDR, par->vp_pal[i]);
+
/* restore video coeff ram */
memcpy(par->vp_regs + VP_VCR, par->vp_coeff, sizeof(par->vp_coeff));
}
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 5c363d026f64..1ab2c2588675 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -53,11 +53,8 @@
#define LCDC_SIZE 0x04
#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
-#ifdef CONFIG_ARCH_MX1
-#define SIZE_YMAX(y) ((y) & 0x1ff)
-#else
-#define SIZE_YMAX(y) ((y) & 0x3ff)
-#endif
+#define YMAX_MASK (cpu_is_mx1() ? 0x1ff : 0x3ff)
+#define SIZE_YMAX(y) ((y) & YMAX_MASK)
#define LCDC_VPW 0x08
#define VPW_VPW(x) ((x) & 0x3ff)
@@ -623,7 +620,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
if (var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n",
info->fix.id, var->right_margin);
- if (var->yres < 1 || var->yres > 511)
+ if (var->yres < 1 || var->yres > YMAX_MASK)
printk(KERN_ERR "%s: invalid yres %d\n",
info->fix.id, var->yres);
if (var->vsync_len > 100)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 0a4dbdc1693a..de450c1fb869 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
abs(cmode->yres - mode->yres);
if (diff > d) {
diff = d;
+ diff_refresh = abs(cmode->refresh - mode->refresh);
best = cmode;
} else if (diff == d) {
d = abs(cmode->refresh - mode->refresh);
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 455c6055325d..083c8fe53e24 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -1,7 +1,7 @@
config FB_OMAP
tristate "OMAP frame buffer support (EXPERIMENTAL)"
- depends on FB && ARCH_OMAP && (OMAP2_DSS = "n")
-
+ depends on FB && (OMAP2_DSS = "n")
+ depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 2fd7e5271be9..9441e2eb3dee 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -551,7 +551,7 @@ void __init omap_vram_reserve_sdram_memblock(void)
if (!size)
return;
- size = PAGE_ALIGN(size);
+ size = ALIGN(size, SZ_2M);
if (paddr) {
if (paddr & ~PAGE_MASK) {
@@ -576,7 +576,7 @@ void __init omap_vram_reserve_sdram_memblock(void)
return;
}
} else {
- paddr = memblock_alloc(size, PAGE_SIZE);
+ paddr = memblock_alloc(size, SZ_2M);
}
memblock_free(paddr, size);
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
new file mode 100644
index 000000000000..b81168df253d
--- /dev/null
+++ b/drivers/video/pxa3xx-gcu.c
@@ -0,0 +1,772 @@
+/*
+ * pxa3xx-gc.c - Linux kernel module for PXA3xx graphics controllers
+ *
+ * This driver needs a DirectFB counterpart in user space, communication
+ * is handled via mmap()ed memory areas and an ioctl.
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (c) 2009 Janine Kropp <nin@directfb.org>
+ * Copyright (c) 2009 Denis Oliver Kropp <dok@directfb.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.
+ */
+
+/*
+ * WARNING: This controller is attached to System Bus 2 of the PXA which
+ * needs its arbiter to be enabled explictly (CKENB & 1<<9).
+ * There is currently no way to do this from Linux, so you need to teach
+ * your bootloader for now.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+
+#include "pxa3xx-gcu.h"
+
+#define DRV_NAME "pxa3xx-gcu"
+#define MISCDEV_MINOR 197
+
+#define REG_GCCR 0x00
+#define GCCR_SYNC_CLR (1 << 9)
+#define GCCR_BP_RST (1 << 8)
+#define GCCR_ABORT (1 << 6)
+#define GCCR_STOP (1 << 4)
+
+#define REG_GCISCR 0x04
+#define REG_GCIECR 0x08
+#define REG_GCRBBR 0x20
+#define REG_GCRBLR 0x24
+#define REG_GCRBHR 0x28
+#define REG_GCRBTR 0x2C
+#define REG_GCRBEXHR 0x30
+
+#define IE_EOB (1 << 0)
+#define IE_EEOB (1 << 5)
+#define IE_ALL 0xff
+
+#define SHARED_SIZE PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared))
+
+/* #define PXA3XX_GCU_DEBUG */
+/* #define PXA3XX_GCU_DEBUG_TIMER */
+
+#ifdef PXA3XX_GCU_DEBUG
+#define QDUMP(msg) \
+ do { \
+ QPRINT(priv, KERN_DEBUG, msg); \
+ } while (0)
+#else
+#define QDUMP(msg) do {} while (0)
+#endif
+
+#define QERROR(msg) \
+ do { \
+ QPRINT(priv, KERN_ERR, msg); \
+ } while (0)
+
+struct pxa3xx_gcu_batch {
+ struct pxa3xx_gcu_batch *next;
+ u32 *ptr;
+ dma_addr_t phys;
+ unsigned long length;
+};
+
+struct pxa3xx_gcu_priv {
+ void __iomem *mmio_base;
+ struct clk *clk;
+ struct pxa3xx_gcu_shared *shared;
+ dma_addr_t shared_phys;
+ struct resource *resource_mem;
+ struct miscdevice misc_dev;
+ struct file_operations misc_fops;
+ wait_queue_head_t wait_idle;
+ wait_queue_head_t wait_free;
+ spinlock_t spinlock;
+ struct timeval base_time;
+
+ struct pxa3xx_gcu_batch *free;
+
+ struct pxa3xx_gcu_batch *ready;
+ struct pxa3xx_gcu_batch *ready_last;
+ struct pxa3xx_gcu_batch *running;
+};
+
+static inline unsigned long
+gc_readl(struct pxa3xx_gcu_priv *priv, unsigned int off)
+{
+ return __raw_readl(priv->mmio_base + off);
+}
+
+static inline void
+gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val)
+{
+ __raw_writel(val, priv->mmio_base + off);
+}
+
+#define QPRINT(priv, level, msg) \
+ do { \
+ struct timeval tv; \
+ struct pxa3xx_gcu_shared *shared = priv->shared; \
+ u32 base = gc_readl(priv, REG_GCRBBR); \
+ \
+ do_gettimeofday(&tv); \
+ \
+ printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \
+ "STATUS " \
+ "0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \
+ "T %5ld)\n", \
+ tv.tv_sec - priv->base_time.tv_sec, \
+ tv.tv_usec / 1000, tv.tv_usec % 1000, \
+ __func__, msg, \
+ shared->hw_running ? "running" : " idle", \
+ gc_readl(priv, REG_GCISCR), \
+ gc_readl(priv, REG_GCRBBR), \
+ gc_readl(priv, REG_GCRBLR), \
+ (gc_readl(priv, REG_GCRBEXHR) - base) / 4, \
+ (gc_readl(priv, REG_GCRBHR) - base) / 4, \
+ (gc_readl(priv, REG_GCRBTR) - base) / 4); \
+ } while (0)
+
+static void
+pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
+{
+ QDUMP("RESET");
+
+ /* disable interrupts */
+ gc_writel(priv, REG_GCIECR, 0);
+
+ /* reset hardware */
+ gc_writel(priv, REG_GCCR, GCCR_ABORT);
+ gc_writel(priv, REG_GCCR, 0);
+
+ memset(priv->shared, 0, SHARED_SIZE);
+ priv->shared->buffer_phys = priv->shared_phys;
+ priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;
+
+ do_gettimeofday(&priv->base_time);
+
+ /* set up the ring buffer pointers */
+ gc_writel(priv, REG_GCRBLR, 0);
+ gc_writel(priv, REG_GCRBBR, priv->shared_phys);
+ gc_writel(priv, REG_GCRBTR, priv->shared_phys);
+
+ /* enable all IRQs except EOB */
+ gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB);
+}
+
+static void
+dump_whole_state(struct pxa3xx_gcu_priv *priv)
+{
+ struct pxa3xx_gcu_shared *sh = priv->shared;
+ u32 base = gc_readl(priv, REG_GCRBBR);
+
+ QDUMP("DUMP");
+
+ printk(KERN_DEBUG "== PXA3XX-GCU DUMP ==\n"
+ "%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n",
+ sh->hw_running ? "running" : "idle ",
+ gc_readl(priv, REG_GCISCR),
+ gc_readl(priv, REG_GCRBBR),
+ gc_readl(priv, REG_GCRBLR),
+ (gc_readl(priv, REG_GCRBEXHR) - base) / 4,
+ (gc_readl(priv, REG_GCRBHR) - base) / 4,
+ (gc_readl(priv, REG_GCRBTR) - base) / 4);
+}
+
+static void
+flush_running(struct pxa3xx_gcu_priv *priv)
+{
+ struct pxa3xx_gcu_batch *running = priv->running;
+ struct pxa3xx_gcu_batch *next;
+
+ while (running) {
+ next = running->next;
+ running->next = priv->free;
+ priv->free = running;
+ running = next;
+ }
+
+ priv->running = NULL;
+}
+
+static void
+run_ready(struct pxa3xx_gcu_priv *priv)
+{
+ unsigned int num = 0;
+ struct pxa3xx_gcu_shared *shared = priv->shared;
+ struct pxa3xx_gcu_batch *ready = priv->ready;
+
+ QDUMP("Start");
+
+ BUG_ON(!ready);
+
+ shared->buffer[num++] = 0x05000000;
+
+ while (ready) {
+ shared->buffer[num++] = 0x00000001;
+ shared->buffer[num++] = ready->phys;
+ ready = ready->next;
+ }
+
+ shared->buffer[num++] = 0x05000000;
+ priv->running = priv->ready;
+ priv->ready = priv->ready_last = NULL;
+ gc_writel(priv, REG_GCRBLR, 0);
+ shared->hw_running = 1;
+
+ /* ring base address */
+ gc_writel(priv, REG_GCRBBR, shared->buffer_phys);
+
+ /* ring tail address */
+ gc_writel(priv, REG_GCRBTR, shared->buffer_phys + num * 4);
+
+ /* ring length */
+ gc_writel(priv, REG_GCRBLR, ((num + 63) & ~63) * 4);
+}
+
+static irqreturn_t
+pxa3xx_gcu_handle_irq(int irq, void *ctx)
+{
+ struct pxa3xx_gcu_priv *priv = ctx;
+ struct pxa3xx_gcu_shared *shared = priv->shared;
+ u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL;
+
+ QDUMP("-Interrupt");
+
+ if (!status)
+ return IRQ_NONE;
+
+ spin_lock(&priv->spinlock);
+ shared->num_interrupts++;
+
+ if (status & IE_EEOB) {
+ QDUMP(" [EEOB]");
+
+ flush_running(priv);
+ wake_up_all(&priv->wait_free);
+
+ if (priv->ready) {
+ run_ready(priv);
+ } else {
+ /* There is no more data prepared by the userspace.
+ * Set hw_running = 0 and wait for the next userspace
+ * kick-off */
+ shared->num_idle++;
+ shared->hw_running = 0;
+
+ QDUMP(" '-> Idle.");
+
+ /* set ring buffer length to zero */
+ gc_writel(priv, REG_GCRBLR, 0);
+
+ wake_up_all(&priv->wait_idle);
+ }
+
+ shared->num_done++;
+ } else {
+ QERROR(" [???]");
+ dump_whole_state(priv);
+ }
+
+ /* Clear the interrupt */
+ gc_writel(priv, REG_GCISCR, status);
+ spin_unlock(&priv->spinlock);
+
+ return IRQ_HANDLED;
+}
+
+static int
+pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv)
+{
+ int ret = 0;
+
+ QDUMP("Waiting for idle...");
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ priv->shared->num_wait_idle++;
+
+ while (priv->shared->hw_running) {
+ int num = priv->shared->num_interrupts;
+ u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
+
+ ret = wait_event_interruptible_timeout(priv->wait_idle,
+ !priv->shared->hw_running, HZ*4);
+
+ if (ret < 0)
+ break;
+
+ if (ret > 0)
+ continue;
+
+ if (gc_readl(priv, REG_GCRBEXHR) == rbexhr &&
+ priv->shared->num_interrupts == num) {
+ QERROR("TIMEOUT");
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ QDUMP("done");
+
+ return ret;
+}
+
+static int
+pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
+{
+ int ret = 0;
+
+ QDUMP("Waiting for free...");
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ priv->shared->num_wait_free++;
+
+ while (!priv->free) {
+ u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
+
+ ret = wait_event_interruptible_timeout(priv->wait_free,
+ priv->free, HZ*4);
+
+ if (ret < 0)
+ break;
+
+ if (ret > 0)
+ continue;
+
+ if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) {
+ QERROR("TIMEOUT");
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ QDUMP("done");
+
+ return ret;
+}
+
+/* Misc device layer */
+
+static ssize_t
+pxa3xx_gcu_misc_write(struct file *filp, const char *buff,
+ size_t count, loff_t *offp)
+{
+ int ret;
+ unsigned long flags;
+ struct pxa3xx_gcu_batch *buffer;
+ struct pxa3xx_gcu_priv *priv =
+ container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+
+ int words = count / 4;
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ priv->shared->num_writes++;
+
+ priv->shared->num_words += words;
+
+ /* Last word reserved for batch buffer end command */
+ if (words >= PXA3XX_GCU_BATCH_WORDS)
+ return -E2BIG;
+
+ /* Wait for a free buffer */
+ if (!priv->free) {
+ ret = pxa3xx_gcu_wait_free(priv);
+ if (ret < 0)
+ return ret;
+ }
+
+ /*
+ * Get buffer from free list
+ */
+ spin_lock_irqsave(&priv->spinlock, flags);
+
+ buffer = priv->free;
+ priv->free = buffer->next;
+
+ spin_unlock_irqrestore(&priv->spinlock, flags);
+
+
+ /* Copy data from user into buffer */
+ ret = copy_from_user(buffer->ptr, buff, words * 4);
+ if (ret) {
+ spin_lock_irqsave(&priv->spinlock, flags);
+ buffer->next = priv->free;
+ priv->free = buffer;
+ spin_unlock_irqrestore(&priv->spinlock, flags);
+ return ret;
+ }
+
+ buffer->length = words;
+
+ /* Append batch buffer end command */
+ buffer->ptr[words] = 0x01000000;
+
+ /*
+ * Add buffer to ready list
+ */
+ spin_lock_irqsave(&priv->spinlock, flags);
+
+ buffer->next = NULL;
+
+ if (priv->ready) {
+ BUG_ON(priv->ready_last == NULL);
+
+ priv->ready_last->next = buffer;
+ } else
+ priv->ready = buffer;
+
+ priv->ready_last = buffer;
+
+ if (!priv->shared->hw_running)
+ run_ready(priv);
+
+ spin_unlock_irqrestore(&priv->spinlock, flags);
+
+ return words * 4;
+}
+
+
+static long
+pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ unsigned long flags;
+ struct pxa3xx_gcu_priv *priv =
+ container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+
+ switch (cmd) {
+ case PXA3XX_GCU_IOCTL_RESET:
+ spin_lock_irqsave(&priv->spinlock, flags);
+ pxa3xx_gcu_reset(priv);
+ spin_unlock_irqrestore(&priv->spinlock, flags);
+ return 0;
+
+ case PXA3XX_GCU_IOCTL_WAIT_IDLE:
+ return pxa3xx_gcu_wait_idle(priv);
+ }
+
+ return -ENOSYS;
+}
+
+static int
+pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned int size = vma->vm_end - vma->vm_start;
+ struct pxa3xx_gcu_priv *priv =
+ container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+
+ switch (vma->vm_pgoff) {
+ case 0:
+ /* hand out the shared data area */
+ if (size != SHARED_SIZE)
+ return -EINVAL;
+
+ return dma_mmap_coherent(NULL, vma,
+ priv->shared, priv->shared_phys, size);
+
+ case SHARED_SIZE >> PAGE_SHIFT:
+ /* hand out the MMIO base for direct register access
+ * from userspace */
+ if (size != resource_size(priv->resource_mem))
+ return -EINVAL;
+
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return io_remap_pfn_range(vma, vma->vm_start,
+ priv->resource_mem->start >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+ }
+
+ return -EINVAL;
+}
+
+
+#ifdef PXA3XX_GCU_DEBUG_TIMER
+static struct timer_list pxa3xx_gcu_debug_timer;
+
+static void pxa3xx_gcu_debug_timedout(unsigned long ptr)
+{
+ struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr;
+
+ QERROR("Timer DUMP");
+
+ /* init the timer structure */
+ init_timer(&pxa3xx_gcu_debug_timer);
+ pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout;
+ pxa3xx_gcu_debug_timer.data = ptr;
+ pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */
+
+ add_timer(&pxa3xx_gcu_debug_timer);
+}
+
+static void pxa3xx_gcu_init_debug_timer(void)
+{
+ pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer);
+}
+#else
+static inline void pxa3xx_gcu_init_debug_timer(void) {}
+#endif
+
+static int
+add_buffer(struct platform_device *dev,
+ struct pxa3xx_gcu_priv *priv)
+{
+ struct pxa3xx_gcu_batch *buffer;
+
+ buffer = kzalloc(sizeof(struct pxa3xx_gcu_batch), GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
+ &buffer->phys, GFP_KERNEL);
+ if (!buffer->ptr) {
+ kfree(buffer);
+ return -ENOMEM;
+ }
+
+ buffer->next = priv->free;
+
+ priv->free = buffer;
+
+ return 0;
+}
+
+static void
+free_buffers(struct platform_device *dev,
+ struct pxa3xx_gcu_priv *priv)
+{
+ struct pxa3xx_gcu_batch *next, *buffer = priv->free;
+
+ while (buffer) {
+ next = buffer->next;
+
+ dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
+ buffer->ptr, buffer->phys);
+
+ kfree(buffer);
+
+ buffer = next;
+ }
+
+ priv->free = NULL;
+}
+
+static int __devinit
+pxa3xx_gcu_probe(struct platform_device *dev)
+{
+ int i, ret, irq;
+ struct resource *r;
+ struct pxa3xx_gcu_priv *priv;
+
+ priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ for (i = 0; i < 8; i++) {
+ ret = add_buffer(dev, priv);
+ if (ret) {
+ dev_err(&dev->dev, "failed to allocate DMA memory\n");
+ goto err_free_priv;
+ }
+ }
+
+ init_waitqueue_head(&priv->wait_idle);
+ init_waitqueue_head(&priv->wait_free);
+ spin_lock_init(&priv->spinlock);
+
+ /* we allocate the misc device structure as part of our own allocation,
+ * so we can get a pointer to our priv structure later on with
+ * container_of(). This isn't really necessary as we have a fixed minor
+ * number anyway, but this is to avoid statics. */
+
+ priv->misc_fops.owner = THIS_MODULE;
+ priv->misc_fops.write = pxa3xx_gcu_misc_write;
+ priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl;
+ priv->misc_fops.mmap = pxa3xx_gcu_misc_mmap;
+
+ priv->misc_dev.minor = MISCDEV_MINOR,
+ priv->misc_dev.name = DRV_NAME,
+ priv->misc_dev.fops = &priv->misc_fops,
+
+ /* register misc device */
+ ret = misc_register(&priv->misc_dev);
+ if (ret < 0) {
+ dev_err(&dev->dev, "misc_register() for minor %d failed\n",
+ MISCDEV_MINOR);
+ goto err_free_priv;
+ }
+
+ /* handle IO resources */
+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&dev->dev, "no I/O memory resource defined\n");
+ ret = -ENODEV;
+ goto err_misc_deregister;
+ }
+
+ if (!request_mem_region(r->start, resource_size(r), dev->name)) {
+ dev_err(&dev->dev, "failed to request I/O memory\n");
+ ret = -EBUSY;
+ goto err_misc_deregister;
+ }
+
+ priv->mmio_base = ioremap_nocache(r->start, resource_size(r));
+ if (!priv->mmio_base) {
+ dev_err(&dev->dev, "failed to map I/O memory\n");
+ ret = -EBUSY;
+ goto err_free_mem_region;
+ }
+
+ /* allocate dma memory */
+ priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE,
+ &priv->shared_phys, GFP_KERNEL);
+
+ if (!priv->shared) {
+ dev_err(&dev->dev, "failed to allocate DMA memory\n");
+ ret = -ENOMEM;
+ goto err_free_io;
+ }
+
+ /* enable the clock */
+ priv->clk = clk_get(&dev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(&dev->dev, "failed to get clock\n");
+ ret = -ENODEV;
+ goto err_free_dma;
+ }
+
+ ret = clk_enable(priv->clk);
+ if (ret < 0) {
+ dev_err(&dev->dev, "failed to enable clock\n");
+ goto err_put_clk;
+ }
+
+ /* request the IRQ */
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0) {
+ dev_err(&dev->dev, "no IRQ defined\n");
+ ret = -ENODEV;
+ goto err_put_clk;
+ }
+
+ ret = request_irq(irq, pxa3xx_gcu_handle_irq,
+ IRQF_DISABLED, DRV_NAME, priv);
+ if (ret) {
+ dev_err(&dev->dev, "request_irq failed\n");
+ ret = -EBUSY;
+ goto err_put_clk;
+ }
+
+ platform_set_drvdata(dev, priv);
+ priv->resource_mem = r;
+ pxa3xx_gcu_reset(priv);
+ pxa3xx_gcu_init_debug_timer();
+
+ dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
+ (void *) r->start, (void *) priv->shared_phys,
+ SHARED_SIZE, irq);
+ return 0;
+
+err_put_clk:
+ clk_disable(priv->clk);
+ clk_put(priv->clk);
+
+err_free_dma:
+ dma_free_coherent(&dev->dev, SHARED_SIZE,
+ priv->shared, priv->shared_phys);
+
+err_free_io:
+ iounmap(priv->mmio_base);
+
+err_free_mem_region:
+ release_mem_region(r->start, resource_size(r));
+
+err_misc_deregister:
+ misc_deregister(&priv->misc_dev);
+
+err_free_priv:
+ platform_set_drvdata(dev, NULL);
+ free_buffers(dev, priv);
+ kfree(priv);
+ return ret;
+}
+
+static int __devexit
+pxa3xx_gcu_remove(struct platform_device *dev)
+{
+ struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
+ struct resource *r = priv->resource_mem;
+
+ pxa3xx_gcu_wait_idle(priv);
+
+ misc_deregister(&priv->misc_dev);
+ dma_free_coherent(&dev->dev, SHARED_SIZE,
+ priv->shared, priv->shared_phys);
+ iounmap(priv->mmio_base);
+ release_mem_region(r->start, resource_size(r));
+ platform_set_drvdata(dev, NULL);
+ clk_disable(priv->clk);
+ free_buffers(dev, priv);
+ kfree(priv);
+
+ return 0;
+}
+
+static struct platform_driver pxa3xx_gcu_driver = {
+ .probe = pxa3xx_gcu_probe,
+ .remove = __devexit_p(pxa3xx_gcu_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ },
+};
+
+static int __init
+pxa3xx_gcu_init(void)
+{
+ return platform_driver_register(&pxa3xx_gcu_driver);
+}
+
+static void __exit
+pxa3xx_gcu_exit(void)
+{
+ platform_driver_unregister(&pxa3xx_gcu_driver);
+}
+
+module_init(pxa3xx_gcu_init);
+module_exit(pxa3xx_gcu_exit);
+
+MODULE_DESCRIPTION("PXA3xx graphics controller unit driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(MISCDEV_MINOR);
+MODULE_AUTHOR("Janine Kropp <nin@directfb.org>, "
+ "Denis Oliver Kropp <dok@directfb.org>, "
+ "Daniel Mack <daniel@caiaq.de>");
diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/pxa3xx-gcu.h
new file mode 100644
index 000000000000..0428ed03dc49
--- /dev/null
+++ b/drivers/video/pxa3xx-gcu.h
@@ -0,0 +1,38 @@
+#ifndef __PXA3XX_GCU_H__
+#define __PXA3XX_GCU_H__
+
+#include <linux/types.h>
+
+/* Number of 32bit words in display list (ring buffer). */
+#define PXA3XX_GCU_BUFFER_WORDS ((256 * 1024 - 256) / 4)
+
+/* To be increased when breaking the ABI */
+#define PXA3XX_GCU_SHARED_MAGIC 0x30000001
+
+#define PXA3XX_GCU_BATCH_WORDS 8192
+
+struct pxa3xx_gcu_shared {
+ u32 buffer[PXA3XX_GCU_BUFFER_WORDS];
+
+ bool hw_running;
+
+ unsigned long buffer_phys;
+
+ unsigned int num_words;
+ unsigned int num_writes;
+ unsigned int num_done;
+ unsigned int num_interrupts;
+ unsigned int num_wait_idle;
+ unsigned int num_wait_free;
+ unsigned int num_idle;
+
+ u32 magic;
+};
+
+/* Initialization and synchronization.
+ * Hardware is started upon write(). */
+#define PXA3XX_GCU_IOCTL_RESET _IO('G', 0)
+#define PXA3XX_GCU_IOCTL_WAIT_IDLE _IO('G', 2)
+
+#endif /* __PXA3XX_GCU_H__ */
+
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index d7df10315d8d..47635fd14557 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -787,6 +788,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
found_rate_error = rate_error;
}
+ hdmi->var.width = hdmi->monspec.max_x * 10;
+ hdmi->var.height = hdmi->monspec.max_y * 10;
+
/*
* TODO 1: if no ->info is present, postpone running the config until
* after ->info first gets registered.
@@ -960,8 +964,12 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
mode1.xres, mode1.yres, mode2.xres, mode2.yres);
- if (fb_mode_is_equal(&mode1, &mode2))
+ if (fb_mode_is_equal(&mode1, &mode2)) {
+ /* It can be a different monitor with an equal video-mode */
+ old_var->width = new_var->width;
+ old_var->height = new_var->height;
return false;
+ }
dev_dbg(info->dev, "Switching %u -> %u lines\n",
mode1.yres, mode2.yres);
@@ -1057,8 +1065,11 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
* on, if we run a resume here, the logo disappears
*/
if (lock_fb_info(hdmi->info)) {
- sh_hdmi_display_on(hdmi, hdmi->info);
- unlock_fb_info(hdmi->info);
+ struct fb_info *info = hdmi->info;
+ info->var.width = hdmi->var.width;
+ info->var.height = hdmi->var.height;
+ sh_hdmi_display_on(hdmi, info);
+ unlock_fb_info(info);
}
} else {
/* New monitor or have to wake up */
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index b02d97a879d6..c05326b61235 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -54,8 +54,8 @@ static int lcdc_shared_regs[] = {
};
#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
-#define DEFAULT_XRES 1280
-#define DEFAULT_YRES 1024
+#define MAX_XRES 1920
+#define MAX_YRES 1080
static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
[LDDCKPAT1R] = 0x400,
@@ -914,22 +914,12 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
{
struct sh_mobile_lcdc_chan *ch = info->par;
- if (var->xres < 160 || var->xres > 1920 ||
- var->yres < 120 || var->yres > 1080 ||
- var->left_margin < 32 || var->left_margin > 320 ||
- var->right_margin < 12 || var->right_margin > 240 ||
- var->upper_margin < 12 || var->upper_margin > 120 ||
- var->lower_margin < 1 || var->lower_margin > 64 ||
- var->hsync_len < 32 || var->hsync_len > 240 ||
- var->vsync_len < 2 || var->vsync_len > 64 ||
- var->pixclock < 6000 || var->pixclock > 40000 ||
+ if (var->xres > MAX_XRES || var->yres > MAX_YRES ||
var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) {
- dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n",
- var->xres, var->yres,
- var->left_margin, var->right_margin,
- var->upper_margin, var->lower_margin,
- var->hsync_len, var->vsync_len,
- var->pixclock);
+ dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n",
+ var->left_margin, var->xres, var->right_margin, var->hsync_len,
+ var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
+ PICOS2KHZ(var->pixclock));
return -EINVAL;
}
return 0;
@@ -1226,7 +1216,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
if (!mode)
- max_size = DEFAULT_XRES * DEFAULT_YRES;
+ max_size = MAX_XRES * MAX_YRES;
else if (max_cfg)
dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
max_cfg->xres, max_cfg->yres);
@@ -1238,12 +1228,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
mode = &default_720p;
num_cfg = 1;
} else {
- num_cfg = ch->cfg.num_cfg;
+ num_cfg = cfg->num_cfg;
}
fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
fb_videomode_to_var(var, mode);
+ var->width = cfg->lcd_size_cfg.width;
+ var->height = cfg->lcd_size_cfg.height;
/* Default Y virtual resolution is 2x panel size */
var->yres_virtual = var->yres * 2;
var->activate = FB_ACTIVATE_NOW;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4a291045ebac..a5ad77ef4266 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -558,6 +558,9 @@ config IT8712F_WDT
This is the driver for the built-in watchdog timer on the IT8712F
Super I/0 chipset used on many motherboards.
+ If the driver does not work, then make sure that the game port in
+ the BIOS is enabled.
+
To compile this driver as a module, choose M here: the
module will be called it8712f_wdt.
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index a1debc89356b..3c5045a206dd 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -18,7 +18,6 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/reboot.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
@@ -220,14 +219,6 @@ static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
}
}
-static int bcm63xx_wdt_notify_sys(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- if (code == SYS_DOWN || code == SYS_HALT)
- bcm63xx_wdt_pause();
- return NOTIFY_DONE;
-}
-
static const struct file_operations bcm63xx_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -243,12 +234,8 @@ static struct miscdevice bcm63xx_wdt_miscdev = {
.fops = &bcm63xx_wdt_fops,
};
-static struct notifier_block bcm63xx_wdt_notifier = {
- .notifier_call = bcm63xx_wdt_notify_sys,
-};
-
-static int bcm63xx_wdt_probe(struct platform_device *pdev)
+static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -280,16 +267,10 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
wdt_time);
}
- ret = register_reboot_notifier(&bcm63xx_wdt_notifier);
- if (ret) {
- dev_err(&pdev->dev, "failed to register reboot_notifier\n");
- goto unregister_timer;
- }
-
ret = misc_register(&bcm63xx_wdt_miscdev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register watchdog device\n");
- goto unregister_reboot_notifier;
+ goto unregister_timer;
}
dev_info(&pdev->dev, " started, timer margin: %d sec\n",
@@ -297,8 +278,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
return 0;
-unregister_reboot_notifier:
- unregister_reboot_notifier(&bcm63xx_wdt_notifier);
unregister_timer:
bcm63xx_timer_unregister(TIMER_WDT_ID);
unmap:
@@ -306,25 +285,28 @@ unmap:
return ret;
}
-static int bcm63xx_wdt_remove(struct platform_device *pdev)
+static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev)
{
if (!nowayout)
bcm63xx_wdt_pause();
misc_deregister(&bcm63xx_wdt_miscdev);
-
- iounmap(bcm63xx_wdt_device.regs);
-
- unregister_reboot_notifier(&bcm63xx_wdt_notifier);
bcm63xx_timer_unregister(TIMER_WDT_ID);
-
+ iounmap(bcm63xx_wdt_device.regs);
return 0;
}
+static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
+{
+ bcm63xx_wdt_pause();
+}
+
static struct platform_driver bcm63xx_wdt = {
.probe = bcm63xx_wdt_probe,
- .remove = bcm63xx_wdt_remove,
+ .remove = __devexit_p(bcm63xx_wdt_remove),
+ .shutdown = bcm63xx_wdt_shutdown,
.driver = {
+ .owner = THIS_MODULE,
.name = "bcm63xx-wdt",
}
};
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 9c21d19043a6..f6bd6f10fcec 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
+#include <linux/fs.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/io.h>
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index f7e90fe47b71..b8838d2c67a6 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -32,6 +32,7 @@
* document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
* document number 320066-003, 320257-008: EP80597 (IICH)
* document number TBD : Cougar Point (CPT)
+ * document number TBD : Patsburg (PBG)
*/
/*
@@ -146,7 +147,8 @@ enum iTCO_chipsets {
TCO_CPT29, /* Cougar Point */
TCO_CPT30, /* Cougar Point */
TCO_CPT31, /* Cougar Point */
- TCO_PBG, /* Patsburg */
+ TCO_PBG1, /* Patsburg */
+ TCO_PBG2, /* Patsburg */
};
static struct {
@@ -235,6 +237,7 @@ static struct {
{"Cougar Point", 2},
{"Cougar Point", 2},
{"Patsburg", 2},
+ {"Patsburg", 2},
{NULL, 0}
};
@@ -350,7 +353,8 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
{ ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)},
{ ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)},
{ ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)},
- { ITCO_PCI_DEVICE(0x1d40, TCO_PBG)},
+ { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)},
+ { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 2ee7dac55a3c..86f7cac1026c 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -270,7 +270,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
return -ENOMEM;
}
- imx2_wdt.clk = clk_get_sys("imx-wdt.0", NULL);
+ imx2_wdt.clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(imx2_wdt.clk)) {
dev_err(&pdev->dev, "can't get Watchdog clock\n");
return PTR_ERR(imx2_wdt.clk);
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 428f8a1583e8..3939e53f5f98 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -231,7 +231,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
struct resource *r;
struct rdc321x_wdt_pdata *pdata;
- pdata = pdev->dev.platform_data;
+ pdata = platform_get_drvdata(pdev);
if (!pdata) {
dev_err(&pdev->dev, "no platform data supplied\n");
return -ENODEV;
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 2b17ad5b4b32..43f9f02c7db0 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -412,8 +412,16 @@ static int __init balloon_init(void)
register_balloon(&balloon_sysdev);
- /* Initialise the balloon with excess memory space. */
- extra_pfn_end = min(e820_end_of_ram_pfn(),
+ /*
+ * Initialise the balloon with excess memory space. We need
+ * to make sure we don't add memory which doesn't exist or
+ * logically exist. The E820 map can be trimmed to be smaller
+ * than the amount of physical memory due to the mem= command
+ * line parameter. And if this is a 32-bit non-HIGHMEM kernel
+ * on a system with memory which requires highmem to access,
+ * don't try to use it.
+ */
+ extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
(unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
for (pfn = PFN_UP(xen_extra_mem_start);
pfn < extra_pfn_end;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2811bb988ea0..31af0ac31a98 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -105,7 +105,6 @@ struct irq_info
static struct irq_info *irq_info;
static int *pirq_to_irq;
-static int nr_pirqs;
static int *evtchn_to_irq;
struct cpu_evtchn_s {
@@ -385,12 +384,17 @@ static int get_nr_hw_irqs(void)
return ret;
}
-/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
- * succeeded otherwise nr_pirqs won't hold the right value */
-static int find_unbound_pirq(void)
+static int find_unbound_pirq(int type)
{
- int i;
- for (i = nr_pirqs-1; i >= 0; i--) {
+ int rc, i;
+ struct physdev_get_free_pirq op_get_free_pirq;
+ op_get_free_pirq.type = type;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
+ if (!rc)
+ return op_get_free_pirq.pirq;
+
+ for (i = 0; i < nr_irqs; i++) {
if (pirq_to_irq[i] < 0)
return i;
}
@@ -423,7 +427,7 @@ static int find_unbound_irq(void)
if (irq == start)
goto no_irqs;
- res = irq_alloc_desc_at(irq, 0);
+ res = irq_alloc_desc_at(irq, -1);
if (WARN_ON(res != irq))
return -1;
@@ -611,10 +615,10 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
spin_lock(&irq_mapping_update_lock);
- if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
+ if ((pirq > nr_irqs) || (gsi > nr_irqs)) {
printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
- pirq > nr_pirqs ? "nr_pirqs" :"",
- gsi > nr_irqs ? "nr_irqs" : "");
+ pirq > nr_irqs ? "pirq" :"",
+ gsi > nr_irqs ? "gsi" : "");
goto out;
}
@@ -630,7 +634,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
xen_pv_domain())) {
irq = gsi;
- irq_alloc_desc_at(irq, 0);
+ irq_alloc_desc_at(irq, -1);
} else
irq = find_unbound_irq();
@@ -664,17 +668,21 @@ out:
#include <linux/msi.h>
#include "../pci/msi.h"
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc)
{
spin_lock(&irq_mapping_update_lock);
- *irq = find_unbound_irq();
- if (*irq == -1)
- goto out;
+ if (alloc & XEN_ALLOC_IRQ) {
+ *irq = find_unbound_irq();
+ if (*irq == -1)
+ goto out;
+ }
- *pirq = find_unbound_pirq();
- if (*pirq == -1)
- goto out;
+ if (alloc & XEN_ALLOC_PIRQ) {
+ *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
+ if (*pirq == -1)
+ goto out;
+ }
set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
handle_level_irq, name);
@@ -762,6 +770,7 @@ int xen_destroy_irq(int irq)
printk(KERN_WARNING "unmap irq failed %d\n", rc);
goto out;
}
+ pirq_to_irq[info->u.pirq.pirq] = -1;
}
irq_info[irq] = mk_unbound_info();
@@ -782,6 +791,11 @@ int xen_gsi_from_irq(unsigned irq)
return gsi_from_irq(irq);
}
+int xen_irq_from_pirq(unsigned pirq)
+{
+ return pirq_to_irq[pirq];
+}
+
int bind_evtchn_to_irq(unsigned int evtchn)
{
int irq;
@@ -1279,6 +1293,42 @@ static int retrigger_dynirq(unsigned int irq)
return ret;
}
+static void restore_cpu_pirqs(void)
+{
+ int pirq, rc, irq, gsi;
+ struct physdev_map_pirq map_irq;
+
+ for (pirq = 0; pirq < nr_irqs; pirq++) {
+ irq = pirq_to_irq[pirq];
+ if (irq == -1)
+ continue;
+
+ /* save/restore of PT devices doesn't work, so at this point the
+ * only devices present are GSI based emulated devices */
+ gsi = gsi_from_irq(irq);
+ if (!gsi)
+ continue;
+
+ map_irq.domid = DOMID_SELF;
+ map_irq.type = MAP_PIRQ_TYPE_GSI;
+ map_irq.index = gsi;
+ map_irq.pirq = pirq;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+ if (rc) {
+ printk(KERN_WARNING "xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n",
+ gsi, irq, pirq, rc);
+ irq_info[irq] = mk_unbound_info();
+ pirq_to_irq[pirq] = -1;
+ continue;
+ }
+
+ printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+ startup_pirq(irq);
+ }
+}
+
static void restore_cpu_virqs(unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
@@ -1422,6 +1472,8 @@ void xen_irq_resume(void)
unmask_evtchn(evtchn);
}
+
+ restore_cpu_pirqs();
}
static struct irq_chip xen_dynamic_chip __read_mostly = {
@@ -1506,26 +1558,17 @@ void xen_callback_vector(void) {}
void __init xen_init_IRQ(void)
{
- int i, rc;
- struct physdev_nr_pirqs op_nr_pirqs;
+ int i;
cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
GFP_KERNEL);
irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
- rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
- if (rc < 0) {
- nr_pirqs = nr_irqs;
- if (rc != -ENOSYS)
- printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
- } else {
- if (xen_pv_domain() && !xen_initial_domain())
- nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
- else
- nr_pirqs = op_nr_pirqs.nr_pirqs;
- }
- pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
- for (i = 0; i < nr_pirqs; i++)
+ /* We are using nr_irqs as the maximum number of pirq available but
+ * that number is actually chosen by Xen and we don't know exactly
+ * what it is. Be careful choosing high pirq numbers. */
+ pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+ for (i = 0; i < nr_irqs; i++)
pirq_to_irq[i] = -1;
evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index ef9c7db52077..db8c4c4ac880 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -49,6 +49,7 @@ static int xen_hvm_suspend(void *data)
if (!*cancelled) {
xen_irq_resume();
+ xen_console_resume();
xen_timer_resume();
}
diff --git a/firmware/Makefile b/firmware/Makefile
index 74d47cd0886c..0a9d1e28ad23 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,13 +32,13 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \
- bnx2x/bnx2x-e1h-6.0.34.0.fw \
- bnx2x/bnx2x-e2-6.0.34.0.fw
-fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \
+fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.5.0.fw \
+ bnx2x/bnx2x-e1h-6.2.5.0.fw \
+ bnx2x/bnx2x-e2-6.2.5.0.fw
+fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1.fw \
bnx2/bnx2-rv2p-09-6.0.17.fw \
bnx2/bnx2-rv2p-09ax-6.0.17.fw \
- bnx2/bnx2-mips-06-6.0.15.fw \
+ bnx2/bnx2-mips-06-6.2.1.fw \
bnx2/bnx2-rv2p-06-6.0.15.fw
fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index f22c4dfd0733..14aaee85d062 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -699,9 +699,9 @@ Found in hex form in kernel source.
Driver: BNX2 - Broadcom NetXtremeII
-File: bnx2/bnx2-mips-06-6.0.15.fw
+File: bnx2/bnx2-mips-06-6.2.1.fw
File: bnx2/bnx2-rv2p-06-6.0.15.fw
-File: bnx2/bnx2-mips-09-6.0.17.fw
+File: bnx2/bnx2-mips-09-6.2.1.fw
File: bnx2/bnx2-rv2p-09-6.0.17.fw
File: bnx2/bnx2-rv2p-09ax-6.0.17.fw
diff --git a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex
index e9bbdc3b0397..4c43b26af0a6 100644
--- a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex
+++ b/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex
@@ -1,19 +1,19 @@
:10000000080001180800000000004A68000000C84D
:1000100000000000000000000000000008004A6826
:100020000000001400004B30080000A00800000091
-:100030000000568800004B4408005800000000846F
-:100040000000A1CC08005688000001580000A25012
-:100050000800321008000000000072D00000A3A8C1
+:100030000000569400004B44080058200000008443
+:100040000000A1D808005694000001580000A25CEE
+:100050000800321008000000000072D00000A3B4B5
:10006000000000000000000000000000080072D046
-:100070000000002400011678080004900800040025
-:10008000000017D40001169C0000000000000000D2
+:100070000000002400011684080004900800040019
+:10008000000017D4000116A80000000000000000C6
:100090000000000000000000000000000000000060
-:1000A000080000A80800000000003BFC00012E70C2
+:1000A000080000A80800000000003BFC00012E7CB6
:1000B0000000000000000000000000000000000040
:0800C000000000000000000038
:0800C8000A00004600000000E0
-:1000D000000000000000000D636F6D362E302E31E1
-:1000E0003500000006000F020000000000000003C1
+:1000D000000000000000000D636F6D362E322E31DF
+:1000E0000000000006020102000000000000000302
:1000F000000000C800000032000000030000000003
:1001000000000000000000000000000000000000EF
:1001100000000010000001360000EA600000000549
@@ -1205,8 +1205,8 @@
:104B300008000ACC08000B1408000B9808000BE4CE
:044B400008000C203D
:0C4B44000A000028000000000000000033
-:104B50000000000D6370362E302E3135000000004D
-:104B600006000F040000000000000000000000002C
+:104B50000000000D6370362E322E31000000000080
+:104B60000602010400000000000000000000000038
:104B70000000000000000000000000000000000035
:104B80000000000000000000000000000000002005
:104B90000000000000000000000000000000000015
@@ -1215,11 +1215,11 @@
:104BC0000000002B000000000000000400030D4066
:104BD00000000000000000000000000000000000D5
:104BE00000000000000000001000000300000000B2
-:104BF0000000000D0000000D3C0208002442588413
-:104C00003C03080024635F50AC4000000043202BAD
+:104BF0000000000D0000000D3C020800244258A4F3
+:104C00003C03080024635F70AC4000000043202B8D
:104C10001480FFFD244200043C1D080037BD7FFCCA
:104C200003A0F0213C100800261000A03C1C080046
-:104C3000279C58840E0001AC000000000000000D0D
+:104C3000279C58A40E0001AC000000000000000DED
:104C400027BDFFE83C096018AFBF00108D2C500055
:104C5000240DFF7F24080031018D5824356A380C5B
:104C600024070C003C1A8000AD2A50003C04800A46
@@ -1303,13 +1303,13 @@
:105140008FB600288FB500248FB400208FB3001CC9
:105150008FB200188FB100148FB0001003E0000868
:1051600027BD0038107E001B000000001477FFCC24
-:10517000241000010E001598000000008F83001419
+:10517000241000010E00159B000000008F83001416
:105180001060FFCB0230F823029158238F87001064
:10519000017020210A0001973093FFFF8F830014D4
:1051A0001460FFCB3C110020AF5100300A000163B6
:1051B000000000000E00077D024028210A00015770
:1051C000004080210E00033A024028210A000157C6
-:1051D000004080210E001460022020210A000157A7
+:1051D000004080210E001463022020210A000157A4
:1051E000004080210E0000CD000000000A0001797F
:1051F00002D3382327BDFFE8AFB00010AFBF0014C3
:105200000E00003F000000003C028000345000709F
@@ -1321,7 +1321,7 @@
:10526000AF8700A83C010800AC2400380E000106FE
:10527000000000003C0308008C6300701060FFE633
:10528000006020213C0508008CA500683C06080051
-:105290008CC6006C0E001527000000003C010800C1
+:105290008CC6006C0E00152A000000003C010800BE
:1052A000AC2000708F4F000039EE000131C20001C8
:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6
:1052C0003C0508008CA5003C3C0408008C84003898
@@ -1349,10 +1349,10 @@
:105420000080382130A5FFFF000020210A00022A59
:10543000240600803087FFFF8CA40000240600387B
:105440000A00022A000028218F8300388F8600304E
-:105450001066000B008040213C07080024E759F843
+:105450001066000B008040213C07080024E75A1822
:10546000000328C000A710218C4400002463000121
:10547000108800053063000F5466FFFA000328C04F
-:1054800003E00008000010213C07080024E759FC55
+:1054800003E00008000010213C07080024E75A1C34
:1054900000A7302103E000088CC200003C0390000C
:1054A0003462000100822025AF4400208F45002097
:1054B00004A0FFFE0000000003E000080000000060
@@ -1417,7 +1417,7 @@
:105860008E0300003C0680002402004000033E023C
:1058700000032C0230E4007F006688241482001D9F
:1058800030A500FF8F8300282C68000A510000100B
-:105890008F910014000358803C0C0800258C56881A
+:105890008F910014000358803C0C0800258C56940E
:1058A000016C50218D49000001200008000000001B
:1058B00002B210213045FFFF0E000236240400849E
:1058C000162000028F90001CAF8000288F910014DA
@@ -1440,23 +1440,23 @@
:1059D000AF6B006C9208000CA3680036937F003E0A
:1059E00037F90020A379003E8F78007403058024E6
:1059F000360F4000AF6F007493640000308900FFE1
-:105A0000513402452404FF803C04080024845A7861
-:105A10000E00028D000000003C1008008E105A7825
+:105A0000513402452404FF803C04080024845A9841
+:105A10000E00028D000000003C1008008E105A9805
:105A20000E00025602002021240600042407000173
:105A3000A366007D020020210E00025FA36700051F
:105A40008F5F017807E0FFFE240B0002AF5001409A
:105A5000A34B01448F90001C3C081000AF48017814
:105A60000A000362AF8000282CAD003751A0FF98D8
-:105A70008F9100140005A0803C180800271856B02C
+:105A70008F9100140005A0803C180800271856BC20
:105A8000029878218DEE000001C00008000000009F
:105A90002418000614B80011000000003C0808009B
-:105AA0008D085A7824040005AF4800208E1F001886
+:105AA0008D085A9824040005AF4800208E1F001866
:105AB000AF7F00188F79004CAF79001C8F650050C4
:105AC000122000C0AF6500700A000362AF84002896
:105AD0002406000710A60083240300063C050800E6
-:105AE00024A55A780E000264240400818F90001CC3
+:105AE00024A55A980E000264240400818F90001CA3
:105AF0000011102B0A000362AF8200282407000463
-:105B000014A7FFF6240500503C1808008F185A7897
+:105B000014A7FFF6240500503C1808008F185A9877
:105B1000AF5800208E0F0008AF6F00408E090008BC
:105B2000AF6900448E14000CAF7400488E0E001054
:105B3000AF6E004C8E0D0010AF6D00848E0A001405
@@ -1464,10 +1464,10 @@
:105B5000AF64005893630000306B00FF116501D8FB
:105B6000000000008F7400488F6900400289702394
:105B700005C000042404008C1620FFDE240200036C
-:105B8000240400823C05080024A55A780E000287F0
+:105B8000240400823C05080024A55A980E000287D0
:105B9000000000008F90001C000010210A0003622A
:105BA000AF820028240F000514AFFFCC240520008D
-:105BB0003C0708008CE75A78AF4700208E060004A7
+:105BB0003C0708008CE75A98AF4700208E06000487
:105BC000AF66005C9208000824100008A36800215A
:105BD0008F9F001C93F90009A37900208F86001C79
:105BE00090D8000A330400FF10900011000000005C
@@ -1486,21 +1486,21 @@
:105CB000AF62006C9167000EA367003E9368003EE0
:105CC0000106F8241220014BA37F003E8F90001C98
:105CD0000A000362AF8500282407002214A7FF7F73
-:105CE000240300073C0B08008D6B5A781220000C2F
+:105CE000240300073C0B08008D6B5A981220000C0F
:105CF000AF4B00200A000362AF830028240C00335E
-:105D000010AC0014240A00283C05080024A55A7889
+:105D000010AC0014240A00283C05080024A55A9869
:105D10000E00023C240400810A0003EB8F90001C5B
-:105D20003C04080024845A780E00028D0000000014
+:105D20003C04080024845A980E00028D00000000F4
:105D30009363000024110050306200FF10510135C0
:105D4000000000008F90001C000018210A00036270
-:105D5000AF8300283C0D08008DAD5A7824040081E3
-:105D6000AF4D00203C05080024A55A780E00023CE7
+:105D5000AF8300283C0D08008DAD5A9824040081C3
+:105D6000AF4D00203C05080024A55A980E00023CC7
:105D7000A36A00348F90001C240200090A00036209
:105D8000AF82002802B288213225FFFF0E000236C2
:105D9000240400840A0003628F90001C1082FFA478
:105DA00024050400288B000311600170240C0004FA
:105DB000240300015483FF9E240540000A00043B95
-:105DC000240501003C04080024845A788F62004CAA
+:105DC000240501003C04080024845A988F62004C8A
:105DD0000E00028D8F6300508F90001C0000202168
:105DE0000A000362AF8400288E1000042404008A95
:105DF000AF50002093790005333800021700015F8F
@@ -1525,13 +1525,13 @@
:105F2000000028210E00022A2406000E928D000097
:105F3000240EFF800200282101AE8025A2900000DF
:105F4000240400040E000C5C240600300A0003EB5D
-:105F50008F90001C8E0800043C14080026945A7888
-:105F60003C010800AC285A78AF480020921F00037B
+:105F50008F90001C8E0800043C14080026945A9868
+:105F60003C010800AC285A98AF480020921F00035B
:105F700033F9000413200002240200122402000658
:105F8000A362003F920B001B2404FFC03165003F59
:105F900000A43825A367003E9206000330C200012A
:105FA00014400132000000008E020008AE8200089A
-:105FB0003C0208008C425A8010400131000249C264
+:105FB0003C0208008C425AA010400131000249C244
:105FC000A76900088E14000C240C0001240300149F
:105FD000AF74002C8E0E0010AF6E0030960D0016C0
:105FE000A76D0038960A0014A76A003AAF6C000C3F
@@ -1546,14 +1546,14 @@
:10607000004050218F89001C240700890140202105
:106080008D25001C240600010E00022A00000000DD
:106090000A0003EB8F90001C960D00023C140800D0
-:1060A00026945A7831AA0004514000B83C10600090
-:1060B0008E0E001C3C010800AC2E5A78AF4E00201A
+:1060A00026945A9831AA0004514000B83C10600070
+:1060B0008E0E001C3C010800AC2E5A98AF4E0020FA
:1060C000920700102408001430E200FF144800D6A4
:1060D00000000000960B00023163000114600165AE
:1060E000000000008E020004AE8200083C1408008C
-:1060F0008E945A801280015B000000008F7400743F
+:1060F0008E945AA01280015B000000008F7400741F
:106100003C0380002404000102835825AF6B007417
-:10611000A3600005AF64000C3C0708008CE75A80C0
+:10611000A3600005AF64000C3C0708008CE75AA0A0
:106120008F86001CA7640010000711C2A76400122C
:10613000A7640014A7640016A76200088CC80008B2
:1061400024040002AF68002C8CC5000CAF65003041
@@ -1562,14 +1562,14 @@
:106170008F89001C912E0013A36E00378F90001C96
:10618000960D0014A76D0038960A0016A76A003A0B
:106190008E0C0018AF6C00245620FDCCAF84002874
-:1061A0003C05080024A55A780E0002640000202156
+:1061A0003C05080024A55A980E0002640000202136
:1061B0008F90001C0A0004A7000020218E1000040C
:1061C00024070081AF500020936900233134001070
:1061D000128000170000000002002021000028218A
:1061E0002406001F0E00022A000000000A0003EB34
-:1061F0008F90001C3C05080024A55A780E000287E9
+:1061F0008F90001C3C05080024A55A980E000287C9
:10620000240400828F90001C000028210A000362F1
-:10621000AF8500283C0408008C845A780E0014E5F1
+:10621000AF8500283C0408008C845A980E0014E8CE
:10622000000000008F90001C0A000482000018216A
:106230000E00025602002021937800230200202144
:10624000370F00100E00025FA36F002300003821FB
@@ -1578,43 +1578,43 @@
:106270009618000EA4D8002C921F000C33F90002CF
:1062800013200005000038218E0200149608001229
:10629000ACC2001CA4C8001A0A0005432406000969
-:1062A0003C05080024A55A780E0002872404008BC0
+:1062A0003C05080024A55A980E0002872404008BA0
:1062B0008F90001C0011282B0A000362AF85002874
-:1062C000AF6000843C0A08008D4A5A783C0D0800F3
+:1062C000AF6000843C0A08008D4A5A983C0D0800D3
:1062D0008DAD0050240CFF803C02000C014D1821B4
:1062E000006C2024AF4400288E070014306B007F20
:1062F000017A282100A2C821AF2700D88E060014F9
:10630000AF9900D0AF2600DC8E080010251FFFFEDD
-:106310000A000408AF3F01083C0508008CA55A7824
+:106310000A000408AF3F01083C0508008CA55A9804
:106320003C1908008F39005024CCFFFE00B9C02171
-:1063300003047824AF4F00283C1408008E945A7848
+:1063300003047824AF4F00283C1408008E945A9828
:106340003C0908008D2900500289702131CD007F61
:1063500001BA502101478021AE0600D8AF9000D08D
:10636000AE0000DC0A0003B1AE0C0108548CFE3014
:10637000240540000A00043B240510000E00032EF3
:10638000000000000A0003EB8F90001C8E0F442CCD
-:106390003C186C62370979703C010800AC205A78CF
+:106390003C186C62370979703C010800AC205A98AF
:1063A00015E9000824050140979F00349786002CCA
:1063B0000280282103E6C82B132000112404009238
:1063C000240501400E000C7A240400023C01080060
-:1063D000AC225A78AF4200203C0508008CA55A78C0
+:1063D000AC225A98AF4200203C0508008CA55A9880
:1063E00010A00005240400830E00084500000000F2
-:1063F00010400009240400833C05080024A55A78B5
+:1063F00010400009240400833C05080024A55A9895
:106400000E000264000000008F90001C0011202B81
:106410000A000362AF8400280E0008490000000053
:106420000A00055F8F90001C0E00084D0000000060
-:106430003C05080024A55A780A00062F2404008B86
+:106430003C05080024A55A980A00062F2404008B66
:10644000240400040E000C7A240500301440002AB5
:10645000004050218F89001C240700830140202127
:106460008D25001C0A000551240600018E04000839
:106470000E000241000000000A00051BAE82000869
-:106480003C05080024A55A780E00023C240400872D
+:106480003C05080024A55A980E00023C240400870D
:106490008F90001C0A0005360011102B8F830038E6
:1064A0008F8600301066FE9D000038213C070800F2
-:1064B00024E759FC000320C0008728218CAC000091
+:1064B00024E75A1C000320C0008728218CAC000070
:1064C00011900061246A00013143000F5466FFFA05
:1064D000000320C00A0004F6000038213C05080033
-:1064E00024A55A780E000287240400828F90001C95
+:1064E00024A55A980E000287240400828F90001C75
:1064F0000A000536000010213C0B0008034B202148
:106500002403005024070001AF420020A0830000B4
:10651000A08700018F82001C90480004A08800180A
@@ -1623,7 +1623,7 @@
:10654000A098001B8F94001C928F0008A08F001C45
:106550008F89001C912E0009A08E001D8F8D001CBC
:1065600091AC000AA08C001E8F8B001C3C0C080014
-:10657000258C59FC9163000B3C0B0800256B59F8E6
+:10657000258C5A1C9163000B3C0B0800256B5A18A4
:10658000A083001F8F87001C90E8000CA0880020CB
:106590008F82001C9045000D24024646A0850021F4
:1065A0008F86001C90DF000EA09F00228F99001C98
@@ -1636,9 +1636,9 @@
:10661000ACCA0000AF88003011100006AF3F000088
:10662000000038218D25001C014020210A00055161
:1066300024060001250C00013184000F00003821E0
-:106640000A0006B8AF8400383C07080024E759F870
+:106640000A0006B8AF8400383C07080024E75A184F
:106650000087302100003821ACA000000A0004F6B9
-:10666000ACC000003C05080024A55A780A00062F9B
+:10666000ACC000003C05080024A55A980A00062F7B
:10667000240400878E0400040E0002410000000084
:106680000A00056AAE8200083084FFFF30C600FFB2
:106690008F4201B80440FFFE00064400010430258B
@@ -1693,7 +1693,7 @@
:1069A00000A62024148300108F84003C00054402BC
:1069B0003C09800000A980241480FFE9310600FF13
:1069C0002CCA00095140FFEB262300010006688015
-:1069D0003C0E080025CE578C01AE60218D8B000047
+:1069D0003C0E080025CE579801AE60218D8B00003B
:1069E0000160000800000000022010218FBF001C81
:1069F0008FB200188FB100148FB0001003E00008B0
:106A000027BD00200E0006D1240400841600FFD804
@@ -1715,7 +1715,7 @@
:106B000000042082314300FF388B00013164000112
:106B100010800002246C0001318300FF03E00008B4
:106B200000601021308BFFFF000B394230E600FF80
-:106B30003C09080025295978000640800109602198
+:106B30003C09080025295998000640800109602178
:106B40008D8700003164001F240A0001008A1804A8
:106B500030A500FF00E3202514A000020003102749
:106B600000E22024240F000100CF700401096821F5
@@ -1727,7 +1727,7 @@
:106BC000AC642018AC62200000000000000000004F
:106BD00003E000080000000027BDFFE82402FFFFDB
:106BE000AFBF0010AF82000C000020213C0608005F
-:106BF00024C659782405FFFF248900010004408041
+:106BF00024C659982405FFFF248900010004408021
:106C00003124FFFF010618212C87002014E0FFFA31
:106C1000AC6500000E0008160000202124020001CF
:106C20003C04600024050020AC822018AC852000C4
@@ -1745,7 +1745,7 @@
:106CE000000000003C0360008C6D200031AC000807
:106CF0001580FFF9000000008C6E201405C00020F4
:106D0000000000000E0007DA8F84000C00024080B3
-:106D10003C09080025295978010938218CE4000034
+:106D10003C09080025295998010938218CE4000014
:106D20000E0007DA00028140020220213090FFFFAE
:106D3000020020210E0007F8000028213C0C8000F2
:106D4000022C58253210FFFF3C116000240A00205D
@@ -1785,36 +1785,36 @@
:106F6000AE0F44088FBF00148FB000103C0C6000BF
:106F7000240E10003C0D020027BD0018AD8E4420E9
:106F800003E00008AD8D08100A0008BB24050001CD
-:106F90000A0008BB000028213C08080025085D8481
+:106F90000A0008BB000028213C08080025085DA461
:106FA0002404FFFF010018212402001E2442FFFFD9
:106FB000AC6400000441FFFD246300043C070800AA
-:106FC00024E75E008CE5FFFC2404001C240600017D
+:106FC00024E75E208CE5FFFC2404001C240600015D
:106FD000308A001F0146480424840001000910275C
:106FE0002C8300201460FFFA00A22824ACE5FFFCEB
-:106FF0003C05666634A4616E3C06080024C65EC08B
+:106FF0003C05666634A4616E3C06080024C65EE06B
:10700000AF840058AF88009C2404FFFF00C0182103
:107010002402001F2442FFFFAC6400000441FFFD76
-:10702000246300043C0766663C05080024A55E80D6
+:10702000246300043C0766663C05080024A55EA0B6
:10703000AF86004834E6616EAF8600982404FFFFF7
:1070400000A018212402000F2442FFFFAC640000BE
:107050000441FFFD246300043C0B66663C06080007
-:1070600024C65E003568616EAF8500A4AF880070ED
+:1070600024C65E203568616EAF8500A4AF880070CD
:107070002404FFFF00C018212402001F2442FFFF48
:10708000AC6400000441FFFD246300043C0D66660F
-:107090003C0A0800254A5F4035AC616EAF8600901F
+:107090003C0A0800254A5F6035AC616EAF860090FF
:1070A000AF8C005C2404FFFF014018212402000380
:1070B0002442FFFFAC6400000441FFFD2463000490
-:1070C0003C09080025295F508D27FFFC2404000699
+:1070C0003C09080025295F708D27FFFC2404000679
:1070D000240500013099001F0325C0042484000109
:1070E000001878272C8E002015C0FFFA00EF3824F6
:1070F000AD27FFFC3C09666624030400240403DC7E
:1071000024050200240600663522616E3C08080052
-:1071100025085A84AF820074AF830044AF83006CAB
+:1071100025085AA4AF820074AF830044AF83006C8B
:10712000AF830050AF830084AF8A008CAF840064CB
:10713000AF85004CAF860054AF840078AF85006007
:10714000AF86008001001821240200022442FFFFC4
:10715000AC6000000441FFFD24630004240400032C
-:107160002403000C3C0A0800254A5A90AF8A0068A4
+:107160002403000C3C0A0800254A5AB0AF8A006884
:107170000A00098E2405FFFF000418802484000102
:10718000006858212C8700C014E0FFFBAD650000AB
:107190003C0E666635CD616E240C17A024081800DD
@@ -1823,10 +1823,10 @@
:1071C00000003821000028210A0009A5AF8400A092
:1071D0001060000624E7000100C4302124A500014E
:1071E0002CC20BF51440FFFA2CA300663C090800E2
-:1071F00025295F4001201821240200032442FFFFBB
+:1071F00025295F6001201821240200032442FFFF9B
:10720000AC6000000441FFFD2463000410E0001A9C
:1072100024E3FFFF0003294210A0000A0000202100
-:107220002406FFFF3C03080024635F402484000120
+:107220002406FFFF3C03080024635F602484000100
:107230000085502BAC660000250800011540FFFBBF
:107240002463000430E2001F10400008000868803A
:10725000240C0001004C38040008588001692821E2
@@ -1849,8 +1849,8 @@
:10736000AFB3001CAFB20018AFB10014AFB0001043
:107370000A000A12AFA5003C504000018F9400683B
:1073800027DEFFFF13C00028269400048E92000021
-:107390003C03080024635D801240FFF70283102B3A
-:1073A0003C04080024845A84028410230002A8C0EC
+:107390003C03080024635DA01240FFF70283102B1A
+:1073A0003C04080024845AA4028410230002A8C0CC
:1073B000000098210A000A212411000100118840D0
:1073C000122000260000000002B380210251282470
:1073D0000200202110A0FFF9267300010E0009DE33
@@ -1862,10 +1862,10 @@
:107430008FBE00308FB7002C8FB600288FB5002488
:107440008FB400208FB3001C8FB200188FB10014CE
:107450008FB0001003E0000827BD00383C0E080084
-:1074600025CE5D80028E102B0A000A0DAE92000020
+:1074600025CE5DA0028E102B0A000A0DAE92000000
:1074700027BDFFD8AFB10014AFB00010AFBF0020E0
:10748000AFB3001CAFB2001800A0882110A0001FED
-:10749000000480403C13080026735A840A000A5AEC
+:10749000000480403C13080026735AA40A000A5ACC
:1074A0002412000112200019261000010E0009F517
:1074B00002002021000231422444FFA0000618806F
:1074C0003045001F2C8217A1007318212631FFFFC1
@@ -1876,7 +1876,7 @@
:107510008FB3001C8FB200188FB100148FB0001011
:1075200003E0000827BD00288F85009C00805821BB
:107530000000402100004821240A001F3C0C0800E4
-:10754000258C5DFC3C0D080025AD5D848CA60000FB
+:10754000258C5E1C3C0D080025AD5DA48CA60000BA
:1075500050C000140000402100AD1023000238C0CC
:10756000240300010A000A930000202115000003F3
:1075700000E410212448202400004821252900018E
@@ -1886,21 +1886,21 @@
:1075B000254AFFFF1540FFE5AF85009C512B0004D5
:1075C0002506DFDC0000402103E000080100102157
:1075D0000006614230C5001F000C50803C070800C7
-:1075E00024E75D8424040001014730211120000FAD
-:1075F00000A420043C05080024A55E0014800005BA
+:1075E00024E75DA424040001014730211120000F8D
+:1075F00000A420043C05080024A55E20148000059A
:107600002529FFFF24C6000410C50011000000005A
:10761000240400018CCF00000004C0270004204097
:1076200001F868241520FFF5ACCD00008F99007893
:1076300001001021032B482303E00008AF890078E4
-:107640003C05080024A55D840A000A9B0000402137
-:107650003C06080024C65D840A000AB42404000124
+:107640003C05080024A55DA40A000A9B0000402117
+:107650003C06080024C65DA40A000AB42404000104
:10766000308800FF240200021102000A24030003F4
:107670001103005C8F8900A4240400041104005F3E
:1076800024050005110500670000182103E000082B
-:10769000006010218F8900483C0C0800258C5EC0DA
-:1076A0003C04080024845F40240300201060000F85
+:10769000006010218F8900483C0C0800258C5EE0BA
+:1076A0003C04080024845F60240300201060000F65
:1076B00000005821240D0002240E00033C0F080096
-:1076C00025EF5EC08D27000014E0000B30F9FFFFAE
+:1076C00025EF5EE08D27000014E0000B30F9FFFF8E
:1076D000252900040124C02B53000001018048210A
:1076E0002463FFFF5460FFF88D270000016018211C
:1076F00003E0000800601021132000323C0500FF69
@@ -1918,15 +1918,15 @@
:1077B000AF89008C016018212549FFFF0A000AEB00
:1077C000AF89008000E52024000736021080FFD03A
:1077D000240A001800075402314600FF0A000AF389
-:1077E000240A00103C0C0800258C5E803C04080034
-:1077F00024845EC00A000ADA240300103C0C08004E
-:10780000258C5E003C04080024845E800A000AD9AE
+:1077E000240A00103C0C0800258C5EA03C04080014
+:1077F00024845EE00A000ADA240300103C0C08002E
+:10780000258C5E203C04080024845EA00A000AD96E
:107810008F89009000071A02306600FF0A000AF301
-:10782000240A00088F89008C3C0C0800258C5F40DE
-:107830003C04080024845F500A000ADA2403000490
+:10782000240A00088F89008C3C0C0800258C5F60BE
+:107830003C04080024845F700A000ADA2403000470
:10784000000A4080250B003024E6FFFF016018216C
:10785000AF8900480A000AEBAF86006C000AC982B3
-:10786000001978803C07080024E75E8001E72021AA
+:10786000001978803C07080024E75EA001E720218A
:10787000000A18428C8F00003079001F032C380456
:107880000007C02701F860240A000B08AC8C000038
:10789000000331420006288000AF28213062001F1B
@@ -1937,7 +1937,7 @@
:1078E000AF8A0060254B1030AF89009001601821ED
:1078F00025C9FFFF0A000AEBAF8900843086000724
:107900002CC2000610400014000000000006408059
-:107910003C030800246357B0010338218CE40000C5
+:107910003C030800246357BC010338218CE40000B9
:1079200000800008000000002409000310A9000ED8
:1079300000000000240A000510AA000B000000004F
:10794000240B000110AB0008000000008F8C00A089
@@ -1948,7 +1948,7 @@
:1079900010880068240E0005108E007F2CAF143074
:1079A0008FBF001003E0000827BD00182CA2003094
:1079B0001440FFFC8FBF001024A5FFD0000531C28A
-:1079C000000668803C07080024E75EC001A730215C
+:1079C000000668803C07080024E75EE001A730213C
:1079D0008CC900000005288230AC001F240B000178
:1079E000018B50048F840048012A4025ACC8000058
:1079F0008C83000050600001AF8600488F98006CB7
@@ -1956,16 +1956,16 @@
:107A1000AF8F006C24A600010006414200082080C0
:107A2000008718218C79000030C2001F2406000155
:107A30000046F804033F382410E0FFDA8FBF00103F
-:107A40000005C182001870803C0F080025EF5E80A1
+:107A40000005C182001870803C0F080025EF5EA081
:107A500001CF48218D2B00000005684231A5001F91
:107A600000A66004016C502527BD001803E0000843
:107A7000AD2A00002CA7003014E0FFCA8FBF001011
:107A800030B900071723FFC724A8FFCE00086A02F9
-:107A9000000D60803C0B0800256B5E80018B30215F
+:107A9000000D60803C0B0800256B5EA0018B30213F
:107AA0008CC40000000828C230AA001F240800016E
:107AB000014848048F8200A400891825ACC3000047
:107AC0008C5F000053E00001AF8600A40005704009
-:107AD000000E7942000F28803C04080024845EC018
+:107AD000000E7942000F28803C04080024845EE0F8
:107AE00000A418218C6B000025DF000131CD001FA0
:107AF000001F514201A86004016C4825000A108053
:107B0000AC690000004428218CA600008F9800601A
@@ -1973,7 +1973,7 @@
:107B2000270E000127BD0018ACAF000003E00008DD
:107B3000AF8E006024A5EFD02CB804001300FF998D
:107B40008FBF001000053142000658803C0A080033
-:107B5000254A5E00016A30218CC4000030A3001F5A
+:107B5000254A5E20016A30218CC4000030A3001F3A
:107B600024090001006910048F9900900082F82513
:107B7000ACDF00008F27000050E00001AF860090CE
:107B80008F8D00848FBF001027BD001825AC000129
@@ -1982,7 +1982,7 @@
:107BB00003E4C8210019384024F8143000B8402BE1
:107BC0001100FF788FBF001024A4EBD00E00021329
:107BD00000C0282100027942000F70803C0D08008F
-:107BE00025AD5F4001CD20218C8B0000304C001F63
+:107BE00025AD5F6001CD20218C8B0000304C001F43
:107BF00024060001018618048F89008C016350253A
:107C0000AC8A00008D25000050A00001AF84008CDC
:107C10008F9800808FBF001027BD00182708000133
@@ -2030,9 +2030,9 @@
:107EB00014400010000000008CA800842D06400033
:107EC00050C0000F240340008CAA0084008A482B75
:107ED000512000018CA3008400035A42000B208033
-:107EE0003C05080024A558000085182103E000087F
+:107EE0003C05080024A558200085182103E000085F
:107EF0008C62000014C0FFF4000000002403400066
-:107F000000035A42000B20803C05080024A55800BD
+:107F000000035A42000B20803C05080024A558209D
:107F10000085182103E000088C6200008F8300D0E8
:107F2000906600D024C50001A06500D08F8500D0E8
:107F3000906400D090A200D210440017000000000E
@@ -2378,252 +2378,253 @@
:109470005040FFA1241F0C008F8300D0906801137F
:109480003106003F0A00124634C20040AF9B00C8BC
:1094900003E00008AF8000EC3089FFFF0009404284
-:1094A0002D020041000929801440000200095040AB
-:1094B00024080040000879400008C0C001F8582185
-:1094C000256701A800EF702125CC007F240DFF80C7
-:1094D000018D18240065302100CA282125640088E8
-:1094E000240A00883C010800AC2A004C3C0108001A
-:1094F000AC240050AF8500D43C010800AC290060CA
-:109500003C010800AC2800643C010800AC27005472
-:109510003C010800AC2300583C010800AC26005C6C
-:1095200003E0000800000000308300FF30C6FFFFAA
-:1095300030E400FF8F4201B80440FFFE00034C00FE
-:10954000012438253C08600000E820253C03100079
-:10955000AF450180AF460184AF44018803E00008B5
-:10956000AF4301B88F86001C3C09601235270010FC
-:109570008CCB00043C0C600E35850010316A00066F
-:109580002D480001ACE800C48CC40004ACA43180B8
-:109590008CC2000894C30002ACA2318403E000082E
-:1095A000A78300E43C0308008C6300508F8400E82C
-:1095B0008F86001C2402FF800064C0210302C8249F
-:1095C000AF5900288CCD00043305007F00BA782104
-:1095D0003C0E000C01EE2821ACAD00588CC80008F0
-:1095E000AF8500D03C076012ACA8005C8CCC0010AA
-:1095F00034E80010ACAC000C8CCB000CACAB000819
-:1096000094AA00143C0208008C4200442549000141
-:10961000A4A9001494A400143083FFFF1062001763
-:109620008F8400D03C0A08008D4A0040A4AA001292
-:109630008CCE0018AC8E00248CCD0014AC8D002094
-:109640008CC70018AC87002C8CCC001424060001B9
-:10965000AC8C00288D0B00BC5166001A8D0200B442
-:109660008D0200B8A482003A948F003AA48F003C87
-:10967000948800D403E000083102FFFF3C09080091
-:109680008D290024A4A000148F8400D0A4A9001266
-:109690008CCE0018AC8E00248CCD0014AC8D002034
-:1096A0008CC70018AC87002C8CCC00142406000159
-:1096B000AC8C00288D0B00BC5566FFEA8D0200B80B
-:1096C0008D0200B4A482003A948F003AA48F003C2B
-:1096D000948800D403E000083102FFFF8F86001C4D
-:1096E0003C0C08008D8C0050240BFF808CCD0008B2
-:1096F0003C03000C000D51C0018A4021010B48249D
-:10970000AF8A00E8AF49002890C700073105007F05
-:1097100000BA10210043282130E4000410800039F1
-:10972000AF8500D090CF000731EE000811C000389F
-:10973000000000008CD9000C8CC400140324C02B42
-:1097400013000030000000008CC2000CACA20064CA
-:109750008CCD00182402FFF8ACAD00688CCC001052
-:10976000ACAC00808CCB000CACAB00848CCA001C71
-:10977000ACAA007C90A900BC01224024A0A800BC97
-:1097800090C300073067000810E000048F8500D008
-:1097900090AF00BC35EE0001A0AE00BC90D9000730
-:1097A00033380001130000088F8300D08F8700D06A
-:1097B0002404003490E800BC35030002A0E300BCA0
-:1097C0008F8300D0AC6400C090C90007312600022E
-:1097D00010C0000500000000906A00BC3542000483
-:1097E000A06200BC8F8300D09065011330AD003FB4
-:1097F000A06D01138F8C00D0958B00D403E000087E
-:109800003162FFFF8CC200140A0013020000000046
-:109810000A001303ACA0006427BDFFD8AFB000104E
-:109820008F90001CAFBF0024AFB40020AFB200186F
-:10983000AFB10014AFB3001C9613000E3C07600AD2
-:109840003C1460063264FFFF369300100E00125580
-:1098500034F404108F8400D43C11600E0E00099B78
-:1098600036310010920E00153C0708008CE70060AE
-:109870003C12601231CD000FA38D00F08E0E00045B
-:109880008E0D000896080012961F00109619001AF7
-:109890009618001E960F001C310CFFFF33EBFFFFE4
-:1098A000332AFFFF3309FFFF31E6FFFF3C010800C9
-:1098B000AC2B00403C010800AC2C00243C0108000B
-:1098C000AC2A0044AE293178AE26317C92020015D4
-:1098D0009603001636520010304400FF3065FFFF3B
-:1098E0003C0608008CC60064AE243188AE4500B446
-:1098F0009208001496190018241F0001011FC004CB
-:10990000332FFFFF3C0508008CA50058AE5800B867
-:10991000AE4F00BC920C0014AF8E00D8AF8D00DCAF
-:10992000318B00FFAE4B00C0920A0015AE670048B5
-:10993000AE66004C314900FFAE4900C8AE65007C00
-:109940003C0308008C6300503C0408008C84004CED
-:109950003C0808008D0800543C0208008C42005C62
-:109960008FBF0024AE6300808FB00010AE83007400
-:109970008FB3001CAE22319CAE4200DCAE2731A07A
-:10998000AE2631A4AE24318CAE233190AE28319472
-:10999000AE253198AE870050AE860054AE8500707B
-:1099A0008FB10014AE4700E0AE4600E4AE4400CCF8
-:1099B000AE4300D0AE4800D4AE4500D88FB40020EE
-:1099C0008FB2001803E0000827BD002827BDFFE084
-:1099D000AFB10014AFBF0018241100010E000845FC
-:1099E000AFB0001010510005978400E6978300CCBB
-:1099F0000083102B144000088F8500D42407000238
-:109A00008FBF00188FB100148FB0001000E010213C
-:109A100003E0000827BD00200E000C7A2404000596
-:109A2000AF8200E81040FFF6240700020E0008494C
-:109A30008F90001C979F00E68F9900E88F8D00C8DB
-:109A400027EF0001240E0050AF590020A78F00E639
-:109A5000A1AE00003C0C08008D8C00648F8600C80D
-:109A6000240A8000000C5E00ACCB0074A4C0000689
-:109A700094C9000A241FFF803C0D000C012AC02459
-:109A8000A4D8000A90C8000A24182000011F182535
-:109A9000A0C3000A8F8700C8A0E000788F8500C8A7
-:109AA00000003821A0A000833C0208008C42005036
-:109AB0008F8400E80044782101FFC824AF590028B2
-:109AC000960B000231EE007F01DA6021018D30211A
-:109AD000A4CB00D4960A0002AF8600D03C0E00044E
-:109AE00025492401A4C900E68E080004ACC800047E
-:109AF0008E030008ACC30000A4C00010A4C0001472
-:109B0000A0C000D08F8500D02403FFBFA0A000D14B
-:109B10003C0408008C8400648F8200D0A04400D2F2
-:109B20008E1F000C8F8A00D0978F00E4AD5F001C61
-:109B30008E19001024100030AD590018A5400030D7
-:109B4000A5510054A5510056A54F0016AD4E006812
-:109B5000AD580080AD580084914D006231AC000FCB
-:109B6000358B0010A14B00628F8600D090C9006336
-:109B70003128007FA0C800638F8400D02406FFFF37
-:109B80009085006300A31024A08200638F9100D011
-:109B900000E01021923F00BC37F90001A23900BC5F
-:109BA0008F8A00D0938F00F0AD580064AD5000C094
-:109BB000914E00D3000F690031CC000F018D582564
-:109BC000A14B00D38F8500D08F8900DCACA900E8C1
-:109BD0008F8800D88FBF00188FB100148FB000108D
-:109BE00027BD0020ACA800ECA4A600D6A4A000E0ED
-:109BF000A4A000E203E000080000000027BDFFE091
-:109C0000AFB000108F90001CAFB10014AFBF0018B0
-:109C10008E1900043C1808008F180050240FFF8094
-:109C2000001989C00238702131CD007F01CF602436
-:109C300001BA50213C0B000CAF4C0028014B4021D5
-:109C4000950900D4950400D68E0700043131FFFF3A
-:109C5000AF8800D00E000913000721C08E06000453
-:109C60008F8300C8000629C0AF4500209064003EE5
-:109C700030820040144000068F8400D0341FFFFF64
-:109C8000948300D63062FFFF145F000400000000E0
-:109C9000948400D60E0008A83084FFFF8E050004CF
-:109CA000022030218FBF00188FB100148FB0001038
-:109CB0002404002200003821000529C00A0012797E
-:109CC00027BD002027BDFFE0AFB100143091FFFF9A
-:109CD000AFB00010AFBF00181220001D000080219F
-:109CE0008F86001C8CC500002403000600053F027F
-:109CF0000005140230E4000714830015304500FF0E
-:109D00002CA800061100004D000558803C0C0800EE
-:109D1000258C57C8016C50218D4900000120000896
-:109D2000000000008F8E00EC240D000111CD0059C1
-:109D300000000000260B00013170FFFF24CA002044
-:109D40000211202B014030211480FFE6AF8A001C55
-:109D5000020010218FBF00188FB100148FB00010C7
-:109D600003E0000827BD0020938700CE14E00038F0
-:109D7000240400140E001335000000008F86001C20
-:109D8000240200010A00147CAF8200EC8F8900ECF1
-:109D9000240800021128003B24040013000028219D
-:109DA00000003021240700010E001279000000009D
-:109DB0000A00147C8F86001C8F8700EC24050002AB
-:109DC00014E5FFF6240400120E0012E60000000065
-:109DD0008F8500E800403021240400120E00127923
-:109DE000000038210A00147C8F86001C8F8300EC51
-:109DF000241F0003147FFFD0260B00010E001298D1
-:109E0000000000008F8500E800403021240200029D
-:109E10002404001000003821AF8200EC0E001279FB
-:109E2000000000000A00147C8F86001C8F8F00EC5D
-:109E30002406000211E6000B0000000024040010BC
-:109E400000002821000030210A0014992407000195
-:109E5000000028210E001279000030210A00147C35
-:109E60008F86001C0E0013A2000000001440001298
-:109E70008F99001C8F86001C240200030A00147CAA
-:109E8000AF8200EC0E00142E000000000A00147CCB
-:109E90008F86001C0E0012880000000024020002C1
-:109EA0002404001400002821000030210000382183
-:109EB0000A0014B6AF8200EC0040382124040010E0
-:109EC00097380002000028210E0012793306FFFFA8
-:109ED0000A00147C8F86001C8F8400C83C077FFF1B
-:109EE00034E6FFFF8C8500742402000100A61824CC
-:109EF000AC83007403E00008A082000510A00036C7
-:109F00002CA20080274A04003C0B00052409008095
-:109F1000104000072408008030A6000F00C5402133
-:109F20002D0300811460000200A048212408008055
-:109F3000AF4B0030000000000000000000000000F7
-:109F40001100000900003821014030218C8D0000F3
-:109F500024E7000400E8602BACCD0000248400045A
-:109F60001580FFFA24C60004000000000000000075
-:109F7000000000003C0E0006010E3825AF470030FF
-:109F80000000000000000000000000008F4F0000F3
-:109F900031E800101100FFFD000000008F42003C7E
-:109FA0008F43003C0049C8210323C02B1300000449
-:109FB000000000008F4C003825860001AF460038B5
-:109FC0008F47003C00A9282300E96821AF4D003CE1
-:109FD00014A0FFCE2CA2008003E0000800000000C7
-:109FE00027BDFFD03C020002AFB100143C11000CB1
-:109FF000AF450038AFB3001CAF46003C008098214D
-:10A00000AF42003024050088AF44002803512021CE
-:10A01000AFBF0028AFB50024AFB40020AFB2001826
-:10A020000E0014EEAFB000103C1F08008FFF004C74
-:10A030003C1808008F1800642410FF8003F3A82147
-:10A0400032B9007F02B078240018A0C0033A702112
-:10A050000018914001D12021AF4F00280E0014EECE
-:10A06000025428213C0D08008DAD0050240501202C
-:10A0700001B35821316C007F01705024019A4821AE
-:10A08000013120210E0014EEAF4A00283C080800E0
-:10A090008D0800543C0508008CA50064011338218C
-:10A0A00030E6007F00F0182400DA20210091202102
-:10A0B000AF4300280E0014EE000529403C020800C2
-:10A0C0008C4200583C1008008E1000601200001CEA
-:10A0D000005388212415FF800A0015713C14000CE0
-:10A0E0003226007F0235182400DA20210240282180
-:10A0F000AF430028009420210E0014EE2610FFC06C
-:10A100001200000F023288212E05004110A0FFF43A
-:10A11000241210003226007F00109180023518248E
-:10A1200000DA202102402821AF430028009420219A
-:10A130000E0014EE000080211600FFF30232882189
-:10A140003C0B08008D6B005C240AFF802405000294
-:10A1500001734021010A4824AF4900283C0408004B
-:10A16000948400623110007F021A88213C07000CA1
-:10A170000E000CAA0227982100402821026020210D
-:10A180008FBF00288FB500248FB400208FB3001C30
-:10A190008FB200188FB100148FB000100A0014EEB7
-:10A1A00027BD00308F83001C8C6200041040000328
-:10A1B0000000000003E00008000000008C640010B4
-:0CA1C0008C6500080A0015278C66000C56
-:04A1CC00000000008F
-:10A1D0000000001B0000000F0000000A0000000843
-:10A1E000000000060000000500000005000000045B
-:10A1F0000000000400000003000000030000000352
-:10A200000000000300000003000000020000000244
-:10A210000000000200000002000000020000000236
+:1094A0002D020041000921801440000200095040B3
+:1094B00024080040000830C0000811400046582130
+:1094C000256701A800E2C821272F007F2418FF800C
+:1094D00001F818240064302100CA702125CC00FF57
+:1094E000240DFF00018D202425650088240A0088B2
+:1094F0003C010800AC2A004C3C010800AC2500509F
+:10950000AF8400D43C010800AC2900603C01080095
+:10951000AC2800643C010800AC2700543C01080062
+:10952000AC2300583C010800AC26005C03E00008B6
+:1095300000000000308300FF30C6FFFF30E400FF72
+:109540008F4201B80440FFFE00034C00012438257F
+:109550003C08600000E820253C031000AF45018076
+:10956000AF460184AF44018803E00008AF4301B86F
+:109570008F86001C3C096012352700108CCB00043C
+:109580003C0C600E35850010316A00062D48000144
+:10959000ACE800C48CC40004ACA431808CC20008C8
+:1095A00094C30002ACA2318403E00008A78300E466
+:1095B0003C0308008C6300508F8400E88F86001CF9
+:1095C0002402FF800064C0210302C824AF59002890
+:1095D0008CCD00043305007F00BA78213C0E000CCE
+:1095E00001EE2821ACAD00588CC80008AF8500D032
+:1095F0003C076012ACA8005C8CCC001034E8001072
+:10960000ACAC000C8CCB000CACAB000894AA0014E2
+:109610003C0208008C42004425490001A4A9001422
+:1096200094A400143083FFFF106200178F8400D0D1
+:109630003C0A08008D4A0040A4AA00128CCE0018F3
+:10964000AC8E00248CCD0014AC8D00208CC700188B
+:10965000AC87002C8CCC001424060001AC8C0028B4
+:109660008D0B00BC5166001A8D0200B48D0200B84B
+:10967000A482003A948F003AA48F003C948800D4CE
+:1096800003E000083102FFFF3C0908008D29002497
+:10969000A4A000148F8400D0A4A900128CCE0018BE
+:1096A000AC8E00248CCD0014AC8D00208CC700182B
+:1096B000AC87002C8CCC001424060001AC8C002854
+:1096C0008D0B00BC5566FFEA8D0200B88D0200B418
+:1096D000A482003A948F003AA48F003C948800D46E
+:1096E00003E000083102FFFF8F86001C3C0C0800DD
+:1096F0008D8C0050240BFF808CCD00083C03000CA7
+:10970000000D51C0018A4021010B4824AF8A00E8B6
+:10971000AF49002890C700073105007F00BA10212B
+:109720000043282130E4000410800039AF8500D0C8
+:1097300090CF000731EE000811C000380000000093
+:109740008CD9000C8CC400140324C02B13000030EF
+:10975000000000008CC2000CACA200648CCD00188C
+:109760002402FFF8ACAD00688CCC0010ACAC0080DB
+:109770008CCB000CACAB00848CCA001CACAA007C67
+:1097800090A900BC01224024A0A800BC90C30007FF
+:109790003067000810E000048F8500D090AF00BC57
+:1097A00035EE0001A0AE00BC90D9000733380001AF
+:1097B000130000088F8300D08F8700D0240400346A
+:1097C00090E800BC35030002A0E300BC8F8300D00A
+:1097D000AC6400C090C900073126000210C000052B
+:1097E00000000000906A00BC35420004A06200BC8A
+:1097F0008F8300D09065011330AD003FA06D011341
+:109800008F8C00D0958B00D403E000083162FFFFFD
+:109810008CC200140A001305000000000A001306A1
+:10982000ACA0006427BDFFD8AFB000108F90001C23
+:10983000AFBF0024AFB40020AFB20018AFB1001426
+:10984000AFB3001C9613000E3C07600A3C14600680
+:109850003264FFFF369300100E00125534F40410EA
+:109860008F8400D43C11600E0E00099B363100102D
+:10987000920E00153C0708008CE700603C12601255
+:1098800031CD000FA38D00F08E0E00048E0D000868
+:1098900096080012961F00109619001A9618001EBE
+:1098A000960F001C310CFFFF33EBFFFF332AFFFF45
+:1098B0003309FFFF31E6FFFF3C010800AC2B0040FD
+:1098C0003C010800AC2C00243C010800AC2A0044F8
+:1098D000AE293178AE26317C92020015960300162F
+:1098E00036520010304400FF3065FFFF3C06080090
+:1098F0008CC60064AE243188AE4500B492080014D2
+:1099000096190018241F0001011FC004332FFFFF08
+:109910003C0508008CA50058AE5800B8AE4F00BCFE
+:10992000920C0014AF8E00D8AF8D00DC318B00FF9D
+:10993000AE4B00C0920A0015AE670048AE66004C00
+:10994000314900FFAE4900C8AE65007C3C03080009
+:109950008C6300503C0408008C84004C3C080800D8
+:109960008D0800543C0208008C42005C8FBF00242C
+:10997000AE6300808FB00010AE8300748FB3001C04
+:10998000AE22319CAE4200DCAE2731A0AE2631A41F
+:10999000AE24318CAE233190AE283194AE2531986F
+:1099A000AE870050AE860054AE8500708FB10014B3
+:1099B000AE4700E0AE4600E4AE4400CCAE4300D07B
+:1099C000AE4800D4AE4500D88FB400208FB2001846
+:1099D00003E0000827BD002827BDFFE0AFB1001459
+:1099E000AFBF0018241100010E000845AFB00010F1
+:1099F00010510005978400E6978300CC0083102B5C
+:109A0000144000088F8500D4240700028FBF00187F
+:109A10008FB100148FB0001000E0102103E00008A7
+:109A200027BD00200E000C7A24040005AF8200E858
+:109A30001040FFF6240700020E0008498F90001C1A
+:109A4000979F00E68F9900E88F8D00C827EF0001EF
+:109A5000240E0050AF590020A78F00E6A1AE0000F1
+:109A60003C0C08008D8C00648F8600C8240A80009E
+:109A7000000C5E00ACCB0074A4C0000694C9000AC0
+:109A8000241FFF803C0D000C012AC024A4D8000A2A
+:109A900090C8000A24182000011F1825A0C3000A3E
+:109AA0008F8700C8A0E000788F8500C800003821AB
+:109AB000A0A000833C0208008C4200508F8400E884
+:109AC0000044782101FFC824AF590028960B0002FA
+:109AD00031EE007F01DA6021018D3021A4CB00D46A
+:109AE000960A0002AF8600D03C0E000425492401EE
+:109AF000A4C900E68E080004ACC800048E03000868
+:109B0000ACC30000A4C00010A4C00014A0C000D0CA
+:109B10008F8500D02403FFBFA0A000D13C04080023
+:109B20008C8400648F8200D0A04400D28E1F000C71
+:109B30008F8A00D0978F00E4AD5F001C8E19001053
+:109B400024100030AD590018A5400030A551005434
+:109B5000A5510056A54F0016AD4E0068AD580080C7
+:109B6000AD580084914D006231AC000F358B001070
+:109B7000A14B00628F8600D090C900633128007F1E
+:109B8000A0C800638F8400D02406FFFF9085006387
+:109B900000A31024A08200638F9100D000E0102168
+:109BA000923F00BC37F90001A23900BC8F8A00D077
+:109BB000938F00F0AD580064AD5000C0914E00D3BB
+:109BC000000F690031CC000F018D5825A14B00D347
+:109BD0008F8500D08F8900DCACA900E88F8800D881
+:109BE0008FBF00188FB100148FB0001027BD002068
+:109BF000ACA800ECA4A600D6A4A000E0A4A000E2BB
+:109C000003E000080000000027BDFFE0AFB0001037
+:109C10008F90001CAFB10014AFBF00188E19000464
+:109C20003C1808008F180050240FFF80001989C0CD
+:109C30000238702131CD007F01CF602401BA50215C
+:109C40003C0B000CAF4C0028014B4021950900D47F
+:109C5000950400D68E0700043131FFFFAF8800D095
+:109C60000E000913000721C08E0600048F8300C870
+:109C7000000629C0AF4500209064003E30820040BD
+:109C8000144000068F8400D0341FFFFF948300D659
+:109C90003062FFFF145F000400000000948400D6CF
+:109CA0000E0008A83084FFFF8E050004022030213A
+:109CB0008FBF00188FB100148FB000102404002251
+:109CC00000003821000529C00A00127C27BD0020B1
+:109CD00027BDFFE0AFB100143091FFFFAFB000101F
+:109CE000AFBF00181220001D000080218F86001CCD
+:109CF0008CC500002403000600053F020005140285
+:109D000030E4000714830015304500FF2CA800063E
+:109D10001100004D000558803C0C0800258C57D4DC
+:109D2000016C50218D490000012000080000000056
+:109D30008F8E00EC240D000111CD005900000000B1
+:109D4000260B00013170FFFF24CA00200211202BD6
+:109D5000014030211480FFE6AF8A001C0200102170
+:109D60008FBF00188FB100148FB0001003E00008FF
+:109D700027BD0020938700CE14E00038240400148F
+:109D80000E001338000000008F86001C2402000122
+:109D90000A00147FAF8200EC8F8900EC24080002D7
+:109DA0001128003B2404001300002821000030216A
+:109DB000240700010E00127C000000000A00147F3E
+:109DC0008F86001C8F8700EC2405000214E5FFF647
+:109DD000240400120E0012E9000000008F8500E844
+:109DE00000403021240400120E00127C00003821B3
+:109DF0000A00147F8F86001C8F8300EC241F000351
+:109E0000147FFFD0260B00010E00129B0000000003
+:109E10008F8500E800403021240200022404001055
+:109E200000003821AF8200EC0E00127C0000000020
+:109E30000A00147F8F86001C8F8F00EC240600021E
+:109E400011E6000B0000000024040010000028218F
+:109E5000000030210A00149C240700010000282182
+:109E60000E00127C000030210A00147F8F86001C37
+:109E70000E0013A500000000144000128F99001C72
+:109E80008F86001C240200030A00147FAF8200ECBE
+:109E90000E001431000000000A00147F8F86001CA1
+:109EA0000E00128B000000002402000224040014A3
+:109EB0000000282100003021000038210A0014B9D8
+:109EC000AF8200EC004038212404001097380002D3
+:109ED000000028210E00127C3306FFFF0A00147FC9
+:109EE0008F86001C8F8400C83C077FFF34E6FFFF8D
+:109EF0008C8500742402000100A61824AC83007431
+:109F000003E00008A082000510A000362CA200800B
+:109F1000274A04003C0B000524090080104000077C
+:109F20002408008030A6000F00C540212D030081C9
+:109F30001460000200A0482124080080AF4B0030CC
+:109F400000000000000000000000000011000009F7
+:109F500000003821014030218C8D000024E70004EE
+:109F600000E8602BACCD0000248400041580FFFACB
+:109F700024C60004000000000000000000000000F3
+:109F80003C0E0006010E3825AF47003000000000EF
+:109F900000000000000000008F4F000031E80010BA
+:109FA0001100FFFD000000008F42003C8F43003C89
+:109FB0000049C8210323C02B130000040000000047
+:109FC0008F4C003825860001AF4600388F47003C93
+:109FD00000A9282300E96821AF4D003C14A0FFCE62
+:109FE0002CA2008003E000080000000027BDFFD085
+:109FF0003C020002AFB100143C11000CAF45003828
+:10A00000AFB3001CAF46003C00809821AF42003047
+:10A0100024050088AF44002803512021AFBF002849
+:10A02000AFB50024AFB40020AFB200180E0014F199
+:10A03000AFB000103C1F08008FFF004C3C18080018
+:10A040008F1800642410FF8003F3A82132B9007F29
+:10A0500002B078240018A0C0033A70210018914083
+:10A0600001D12021AF4F00280E0014F10254282105
+:10A070003C0D08008DAD00502405012001B358218E
+:10A08000316C007F01705024019A48210131202158
+:10A090000E0014F1AF4A00283C0808008D08005457
+:10A0A0003C0508008CA500640113382130E6007FD0
+:10A0B00000F0182400DA202100912021AF4300286D
+:10A0C0000E0014F1000529403C0208008C420058A3
+:10A0D0003C1008008E1000601200001C0053882104
+:10A0E0002415FF800A0015743C14000C3226007FF2
+:10A0F0000235182400DA202102402821AF4300282D
+:10A10000009420210E0014F12610FFC01200000F51
+:10A11000023288212E05004110A0FFF42412100005
+:10A120003226007F001091800235182400DA2021A9
+:10A1300002402821AF430028009420210E0014F192
+:10A14000000080211600FFF3023288213C0B08003A
+:10A150008D6B005C240AFF802405000201734021FE
+:10A16000010A4824AF4900283C0408009484006296
+:10A170003110007F021A88213C07000C0E000CAA47
+:10A180000227982100402821026020218FBF00284B
+:10A190008FB500248FB400208FB3001C8FB200183D
+:10A1A0008FB100148FB000100A0014F127BD0030E9
+:10A1B0008F83001C8C62000410400003000000002C
+:10A1C00003E00008000000008C6400108C650008AB
+:08A1D0000A00152A8C66000C40
+:08A1D800000000000000001B64
+:10A1E0000000000F0000000A000000080000000648
+:10A1F000000000050000000500000004000000044D
+:10A200000000000300000003000000030000000342
+:10A210000000000300000002000000020000000235
:10A220000000000200000002000000020000000226
:10A230000000000200000002000000020000000216
-:10A240000000000200000001000000010000000109
-:10A2500008000F2408000D6C08000FB808001060FB
-:10A2600008000F4C08000F8C0800119408000D889E
-:10A27000080011B808000DD8080015540800151C76
-:10A2800008000D8808000D8808000D88080012409D
-:10A290000800124008000D8808000D88080014E02E
-:10A2A00008000D8808000D8808000D8808000D883A
-:10A2B000080013B408000D8808000D8808000D88F8
+:10A240000000000200000002000000020000000206
+:0CA25000000000010000000100000001FF
+:04A25C0008000F24C3
+:10A2600008000D6C08000FB80800106008000F4CC3
+:10A2700008000F8C0800119408000D88080011B820
+:10A2800008000DD8080015540800151C08000D889A
+:10A2900008000D8808000D880800124008001240D0
+:10A2A00008000D8808000D88080014E008000D88DB
+:10A2B00008000D8808000D8808000D88080013B4F8
:10A2C00008000D8808000D8808000D8808000D881A
:10A2D00008000D8808000D8808000D8808000D880A
-:10A2E00008000D8808000D8808000D8808000FACD4
-:10A2F00008000D8808000D880800167808000D88F1
-:10A3000008000D8808000D8808000D8808000D88D9
+:10A2E00008000D8808000D8808000D8808000D88FA
+:10A2F00008000D8808000D8808000FAC08000D88C4
+:10A3000008000D880800167808000D8808000D88E0
:10A3100008000D8808000D8808000D8808000D88C9
:10A3200008000D8808000D8808000D8808000D88B9
:10A3300008000D8808000D8808000D8808000D88A9
-:10A340000800141008000D8808000D880800133458
-:10A35000080012A408001E2C08001EFC08001F1490
-:10A3600008001F2808001F3808001E2C08001E2C9B
-:10A3700008001E2C08001ED808002E1408002E1CF1
-:10A3800008002DE408002DF008002DFC08002E0820
-:10A39000080052E8080052A8080052740800524809
-:08A3A00008005224080051E0FE
-:08A3A8000A000C840000000013
-:10A3B000000000000000000D727870362E302E3143
-:10A3C0003500000006000F0300000000000000013F
-:10A3D000000000000000000000000000000000007D
+:10A3400008000D8808000D8808000D88080014100A
+:10A3500008000D8808000D8808001334080012A4B6
+:10A3600008001E2C08001EFC08001F1408001F28EF
+:10A3700008001F3808001E2C08001E2C08001E2C88
+:10A3800008001ED808002E1408002E1C08002DE41A
+:10A3900008002DF008002DFC08002E08080052F4DB
+:10A3A000080052B40800528008005254080052308D
+:04A3B000080051EC64
+:0CA3B4000A000C84000000000000000003
+:10A3C0000000000D727870362E322E310000000031
+:10A3D0000602010300000000000000010000000070
:10A3E000000000000000000000000000000000006D
:10A3F000000000000000000000000000000000005D
:10A40000000000000000000000000000000000004C
@@ -3418,2392 +3419,2394 @@
:10D5500000000000000000000000000000000000CB
:10D5600000000000000000000000000000000000BB
:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000080000000001B
-:10D59000000000000000000000000000000000008B
-:10D5A0000000000000000000000000000000000A71
-:10D5B0000000000000000000000000001000000358
-:10D5C000000000000000000D0000000D3C020800FB
-:10D5D000244273203C030800246377ACAC40000075
-:10D5E0000043202B1480FFFD244200043C1D080052
-:10D5F00037BD7FFC03A0F0213C100800261032103C
-:10D600003C1C0800279C73200E0010FE0000000048
-:10D610000000000D30A5FFFF30C600FF274301804A
-:10D620008F4201B80440FFFE24020002AC640000F7
-:10D63000A4650008A066000AA062000B3C0210006E
-:10D64000AC67001803E00008AF4201B83C0360007B
-:10D650008C624FF80440FFFE3C020200AC644FC0F5
-:10D66000AC624FC43C02100003E00008AC624FF80B
-:10D670009482000C2486001400A0382100021302BA
-:10D68000000210800082402100C8102B104000577B
-:10D690000000000090C300002C62000950400051BF
-:10D6A00090C20001000310803C030800246372D084
-:10D6B000004310218C4200000040000800000000E0
-:10D6C00090C300012402000A1462003A0000000026
-:10D6D000010610232C42000A1440003624C6000222
-:10D6E0008CE2000034420100ACE2000090C2000075
-:10D6F00090C3000190C4000290C5000300031C0009
-:10D7000000021600004310250004220000441025EA
-:10D710000045102524C60004ACE2000490C20000BD
-:10D7200090C3000190C4000290C5000300021600DF
-:10D7300000031C00004310250004220000441025B3
-:10D740000045102524C600040A000CB8ACE200080D
-:10D7500090C30001240200041462001624C60002D3
-:10D7600090C2000090C400018CE30000000212008F
-:10D77000004410253463000424C60002ACE2000C0F
-:10D780000A000CB8ACE3000090C3000124020003BF
-:10D790001462000824C600028CE2000090C300005E
-:10D7A00024C6000134420008A0E300100A000CB8AF
-:10D7B000ACE2000003E000082402000190C3000175
-:10D7C000240200021062000224C400020100202191
-:10D7D0000A000CB8008030210A000CB824C60001F1
-:10D7E00090C200010A000CB800C2302103E000081A
-:10D7F0000000102127BDFFE8AFBF0014AFB000103C
-:10D800000E00130200808021936200052403FFFEB6
-:10D8100002002021004310248FBF00148FB000109D
-:10D82000A36200050A00130B27BD001827BDFFE8FF
-:10D83000AFB00010AFBF00140E000F3C008080217D
-:10D840009362000024030050304200FF14430004A0
-:10D8500024020100AF4201800A000D3002002021A5
-:10D86000AF400180020020218FBF00148FB0001054
-:10D870000A000FE727BD001827BDFF80AFBE007864
-:10D88000AFB70074AFB20060AFBF007CAFB600703E
-:10D89000AFB5006CAFB40068AFB30064AFB1005C6B
-:10D8A000AFB000588F5001283C0208008C4231A0D4
-:10D8B0002403FF809365003F0202102100431024DF
-:10D8C000AF4200243C0208008C4231A09364000562
-:10D8D00030B200FF020210213042007F03421821C3
-:10D8E000000420273C02000A006218213084000155
-:10D8F000AF8300140000F0210000B8211480005311
-:10D90000AFA0005093430116934401128F450104C8
-:10D91000306300FF3C020001308400FF00A2282495
-:10D92000034310210344182124564000246740007B
-:10D9300014A001CD2402000193620000304300FFD7
-:10D94000240200201062000524020050106200062C
-:10D95000000000000A000D74000000000000000D2F
-:10D960000A000D7DAFA000303C1E080027DE736C5E
-:10D970000A000D7DAFA000303C0208008C4200DCA4
-:10D98000244200013C010800AC2200DC0E00139F81
-:10D99000000000000A000F318FBF007C8F4201049D
-:10D9A0003C03002092D3000D004310240002202BE2
-:10D9B00000042140AFA400308F4301043C0200402A
-:10D9C0000062182414600002348500400080282181
-:10D9D00032620020AFA500301440000234A600805F
-:10D9E00000A0302110C0000BAFA6003093C5000886
-:10D9F0008F67004C0200202100052B0034A5008118
-:10DA000030A5F0810E000C9B30C600FF0A000F2EDF
-:10DA1000000000009362003E304200401040000FC2
-:10DA200024020004564200072402001202002021B2
-:10DA300000E028210E0013F702C030210A000F3148
-:10DA40008FBF007C16420005000000000E000D2173
-:10DA5000000020210A000F318FBF007C9743011A7C
-:10DA600096C4000E93620035326500043075FFFFE6
-:10DA700000442004AFA400548ED1000410A000156F
-:10DA80008ED400089362003E3042004010400007F0
-:10DA9000000000000E0013E0022020211040000DC5
-:10DAA000000000000A000F2E000000008F620044FA
-:10DAB000022210230440016A000000008F62004827
-:10DAC0000222102304410166240400160A000E21DC
-:10DAD0008FC200048F620048022210230440000815
-:10DAE000000000003C0208008C423100244200018A
-:10DAF0003C010800AC2231000A000F2300000000A6
-:10DB00008F62004002221023184000128F840014FC
-:10DB10003C0208008C423100327300FC0000A82156
-:10DB2000244200013C010800AC2231008F63004018
-:10DB30009482011C022318233042FFFF0043102A65
-:10DB4000504000102402000C8F6200400A000DF2C9
-:10DB5000022210239483011C9762003C0043102B87
-:10DB600010400006000000009482011C00551023A4
-:10DB7000A482011C0A000DF72402000CA480011CE1
-:10DB80002402000CAFA200308F620040005120231D
-:10DB90001880000D02A4102A144001260000000085
-:10DBA0001495000602A410233A62000130420001DD
-:10DBB000144001200000000002A410230224882148
-:10DBC0000A000E093055FFFF0000202132620002DA
-:10DBD0001040001A326200109362003E3042004052
-:10DBE000504000118FC200040E00130202002021D9
-:10DBF00024020018A362003F936200052403FFFE85
-:10DC000002002021004310240E00130BA362000524
-:10DC100024040039000028210E0013C9240600182E
-:10DC20000A000F3024020001240400170040F80904
-:10DC3000000000000A000F3024020001104001081B
-:10DC4000000000008F63004C8F620054028210239A
-:10DC50001C40010302831023044200010060A02144
-:10DC6000AFA40018AFB10010AFB50014934201206B
-:10DC70008F6500409763003C304200FF0342102153
-:10DC8000004410218FA400543063FFFF2442400061
-:10DC90000083182B8FA40030AFA20020AFA500286E
-:10DCA00000832025AFA40030AFA50024AFA0002C36
-:10DCB000AFB400349362003E30420008504000117F
-:10DCC0008FC2000002C0202127A500380E000CB230
-:10DCD000AFA000385440000B8FC200008FA2003864
-:10DCE00030420100504000078FC200008FA3003C6B
-:10DCF0008F6200600062102304430001AF63006084
-:10DD00008FC200000040F80927A400108FA2003045
-:10DD10003042000254400001327300FE9362003E24
-:10DD200030420040104000378FA200248F62005420
-:10DD30001682001A326200012402001412420010FE
-:10DD40002A42001510400006240200162402000C8E
-:10DD500012420007326200010A000E7D000000003E
-:10DD600012420005326200010A000E7D0000000030
-:10DD70000A000E782417000E0A000E7824170010EF
-:10DD80000A000E7C24170012936200232403FFBDB7
-:10DD900000431024A36200233262000110400019E6
-:10DDA0008FA200242402000C1242000E2A42000D11
-:10DDB000104000062402000E2402000A124200074E
-:10DDC0008FA200240A000E9524420001124200088E
-:10DDD0008FA200240A000E95244200010A000E932F
-:10DDE000241700082402000E16E200022417001671
-:10DDF000241700108FA2002424420001AFA20024A7
-:10DE00008FA200248FA300148F76004000431021BE
-:10DE1000AF6200408F8200149442011C1040000940
-:10DE2000000000008F6200488F6400409763003C50
-:10DE3000004410233063FFFF0043102A1040000805
-:10DE40008FA20054936400368F6300403402FFFCBD
-:10DE50000082100400621821AF6300488FA20054B2
-:10DE60008FA600300282902130C200081040000EC0
-:10DE7000000000008F6200581642000430C600FF08
-:10DE80009742011A5040000134C6001093C50008A3
-:10DE90008FA700340200202100052B0034A500804C
-:10DEA0000E000C9B30A5F0808F62004000561023BE
-:10DEB0001840001B8FA200183C0208008C423198C9
-:10DEC000304200101040000D2402000197620068EB
-:10DED0001440000A240200018F8200149442011CA5
-:10DEE0001440000624020001A76200689742007AED
-:10DEF000244200640A000EE9A7620012A762001221
-:10DF00000E001302020020219362007D2403000111
-:10DF100002002021344200010A000EE7AFA30050A6
-:10DF20001840000A000000000E0013020200202129
-:10DF30009362007D2403000102002021AFA3005062
-:10DF4000344200040E00130BA362007D9362003E76
-:10DF5000304200401440000C326200011040000AC0
-:10DF6000000000008F6300408FC2000424040018EA
-:10DF7000246300010040F809AF6300408FA2003025
-:10DF80000A000F30304200048F6200581052001017
-:10DF9000000000008F620018022210231C400008BD
-:10DFA000240400018F6200181622000900000000FE
-:10DFB0008F62001C02821023044000050000000054
-:10DFC000AF720058AFA40050AF710018AF74001CBE
-:10DFD00012E0000B8FA200500E001302020020215D
-:10DFE000A377003F0E00130B0200202102E0302136
-:10DFF000240400370E0013C9000028218FA200500E
-:10E0000010400003000000000E000CA902002021B7
-:10E0100012A00005000018218FA200303042000439
-:10E020005040001100601021240300010A000F304D
-:10E03000006010210E001302020020219362007D77
-:10E0400002002021344200040E00130BA362007D65
-:10E050000E000CA9020020210A000F30240200014A
-:10E06000AF400044240200018FBF007C8FBE0078C7
-:10E070008FB700748FB600708FB5006C8FB40068D6
-:10E080008FB300648FB200608FB1005C8FB0005816
-:10E0900003E0000827BD00808F4201B80440FFFE66
-:10E0A00024020800AF4201B803E0000800000000AD
-:10E0B0003C02000803421021944200483084FFFFD4
-:10E0C000248400123045FFFF10A0001700A4102B7D
-:10E0D0001040001624020003934201202403001A7A
-:10E0E000A343018B304200FF2446FFFE8F820000D5
-:10E0F00000A6182B3863000100021382004310248D
-:10E10000104000058F84000434820001A74601946A
-:10E1100003E00008AF8200042402FFFE0082102406
-:10E1200003E00008AF8200042402000303E00008BB
-:10E13000A342018B27BDFFE0AFB10014AFB00010C8
-:10E14000AFBF001830B0FFFF30D1FFFF8F4201B8E2
-:10E150000440FFFE00000000AF440180AF440020F7
-:10E160000E000F42020020218F8300008F840004E4
-:10E17000A750019AA750018EA74301908F830008F2
-:10E1800030828000AF4301A8A75101881040000EE3
-:10E190008F82000493420116304200FC24420004A6
-:10E1A000005A10218C4240003042FFFF144000060C
-:10E1B0008F8200043C02FFFF34427FFF0082102464
-:10E1C000AF8200048F8200042403BFFF00431024A9
-:10E1D000A74201A69743010C8F42010400031C00D3
-:10E1E0003042FFFF00621825AF4301AC3C02100033
-:10E1F000AF4201B88FBF00188FB100148FB000106C
-:10E2000003E0000827BD00208F47007093420112F1
-:10E210008F83000027BDFFF0304200FF00022882FC
-:10E2200030620100000030211040004324A40003AC
-:10E230003062400010400010306220000004108066
-:10E24000005A10218C43400024A4000400041080D4
-:10E25000AFA30000005A10218C424000AFA200047E
-:10E2600093420116304200FC005A10218C424000BB
-:10E270000A000FC0AFA200081040002F000030219C
-:10E2800000041080005A10218C43400024A4000494
-:10E2900000041080AFA30000005A10218C424000FF
-:10E2A000AFA00008AFA200048FA800080000302132
-:10E2B00000002021240A00083C090800252901004B
-:10E2C00003A41021148A000300042A001100000A8C
-:10E2D0000000000090420000248400012C83000C08
-:10E2E00000A2102100021080004910218C42000081
-:10E2F0001460FFF300C230263C0408008C84310413
-:10E300008F4200702C8300201060000900473823E2
-:10E310003C030800246331080004108000431021EE
-:10E3200024830001AC4700003C010800AC23310409
-:10E33000AF8600082406000100C0102103E0000899
-:10E3400027BD00103C0208008C42003827BDFFD0DA
-:10E35000AFB50024AFB40020AFB10014AFBF0028A8
-:10E36000AFB3001CAFB20018AFB00010000088219E
-:10E370003C15080026B50038144000022454FFFF65
-:10E380000000A0219742010E8F8400003042FFFF61
-:10E39000308340001060000A245200043C02002038
-:10E3A0000082102450400007308280008F820004D9
-:10E3B0002403BFFF008318240A0010103442100009
-:10E3C000308280001040000A3C02002000821024AD
-:10E3D000104000078F8200043C03FFFF34637FFF7F
-:10E3E0000083182434428000AF820004AF83000011
-:10E3F0000E000F980000000014400007000000000D
-:10E400009743011E9742011C3063FFFF0002140076
-:10E4100000621825AF8300089742010C8F4340002B
-:10E420003045FFFF3402FFFF1462000300000000CC
-:10E430000A001028241100208F42400030420100C1
-:10E4400054400001241100108F840000308210001D
-:10E450005040001436310001308200201440000B7F
-:10E460003C021000008210245040000E36310001A2
-:10E470003C030E003C020DFF008318243442FFFFD2
-:10E480000043102B50400007363100013C020800C9
-:10E490008C42002C244200013C010800AC22002CDC
-:10E4A000363100053C0608008CC6003454C00023F9
-:10E4B0008F8500008F820004304240005440001FCE
-:10E4C0008F8500003C021F01008210243C031000D5
-:10E4D0005443001A8F85000030A202001440001738
-:10E4E0008F8500003250FFFF363100028F4201B8A5
-:10E4F0000440FFFE00000000AF4001800200202128
-:10E500000E000F42AF4000208F8300042402BFFFA3
-:10E51000A750019A006218248F820000A750018E34
-:10E52000A7510188A74301A6A74201903C02100011
-:10E53000AF4201B80A0010F5000010213C021000A3
-:10E5400000A210241040003A0000000010C0000F8C
-:10E550000000000030A201001040000C3C0302004B
-:10E560003C020F0000A2102410430008000000002D
-:10E570008F8200080054102400551021904200049E
-:10E58000244200040A00109F000221C00000000085
-:10E59000000516023050000F3A0300022E4203EF2E
-:10E5A000384200012C6300010062182414600073DB
-:10E5B000240200013C0308008C6300D02E06000CEE
-:10E5C000386200012C42000100461024144000155E
-:10E5D000001021C02602FFFC2C4200045440001110
-:10E5E00000002021386200022C4200010046102465
-:10E5F00010400003000512420A00109F0000202175
-:10E600000010182B0043102450400006001021C0B9
-:10E61000000020213245FFFF0E000F633226FFFB72
-:10E62000001021C03245FFFF0A0010F2362600021A
-:10E630008F4240003C0308008C63002430420100FC
-:10E640001040004630620001322200043070000D9C
-:10E65000144000022413000424130002000512C217
-:10E66000384200012E4303EF3042000138630001BD
-:10E6700000431025104000033231FFFB2402FFFB52
-:10E680000202802410C000183202000130A20100F2
-:10E6900010400015320200013C020F0000A21024BD
-:10E6A0003C0302001043000F8F8200082403FFFE8A
-:10E6B00002038024005410240055102190420004CD
-:10E6C000023330252442000412000002000221C05F
-:10E6D0003226FFFF0E000F633245FFFF12000027B6
-:10E6E00000001021320200011040000D320200042F
-:10E6F0002402000112020002023330253226FFFFFD
-:10E70000000020210E000F633245FFFF2402FFFEB0
-:10E7100002028024120000190000102132020004BD
-:10E72000104000162402000124020004120200021C
-:10E73000023330253226FFFF3245FFFF0E000F6304
-:10E74000240401002402FFFB020280241200000BBB
-:10E75000000010210A0010F52402000110400007FB
-:10E76000000010213245FFFF362600020000202164
-:10E770000E000F6300000000000010218FBF002872
-:10E780008FB500248FB400208FB3001C8FB2001807
-:10E790008FB100148FB0001003E0000827BD0030D7
-:10E7A00027BDFFD0AFB000103C04600CAFBF002C01
-:10E7B000AFB60028AFB50024AFB40020AFB3001C43
-:10E7C000AFB20018AFB100148C8250002403FF7F59
-:10E7D0003C1A8000004310243442380CAC825000B4
-:10E7E000240200033C106000AF4200088E020808BB
-:10E7F0003C1B80083C010800AC2000203042FFF0A8
-:10E80000384200102C4200010E001B85AF82001818
-:10E810003C04FFFF3C020400348308063442000C31
-:10E82000AE021948AE03194C3C0560168E021980E1
-:10E830008CA300003442020000641824AE02198048
-:10E840003C0253531462000334A47C008CA20004E5
-:10E85000005020218C82007C8C830078AF820010D5
-:10E86000AF83000C8F55000032A200031040FFFD63
-:10E8700032A200011040013D32A200028F42012865
-:10E88000AF4200208F4201048F430100AF8200009D
-:10E890000E000F3CAF8300043C0208008C4200C015
-:10E8A000104000088F8400003C0208008C4200C425
-:10E8B000244200013C010800AC2200C40A00126995
-:10E8C000000000003C020010008210241440010CE3
-:10E8D0008F8300043C0208008C4200203C030800A7
-:10E8E0008C63003800008821244200013C010800AC
-:10E8F000AC2200203C16080026D600381460000226
-:10E900002474FFFF0000A0219742010E30834000D5
-:10E910003042FFFF1060000A245200043C02002035
-:10E920000082102450400007308280008F82000453
-:10E930002403BFFF008318240A0011703442100022
-:10E94000308280001040000A3C0200200082102427
-:10E95000104000078F8200043C03FFFF34637FFFF9
-:10E960000083182434428000AF820004AF8300008B
-:10E970000E000F9800000000144000070000000087
-:10E980009743011E9742011C3063FFFF00021400F1
-:10E9900000621825AF8300089742010C8F434000A6
-:10E9A0003045FFFF3402FFFF146200030000000047
-:10E9B0000A001188241100208F42400030420100DB
-:10E9C00054400001241100108F8400003082100098
-:10E9D0005040001436310001308200201440000BFA
-:10E9E0003C021000008210245040000E363100011D
-:10E9F0003C030E003C020DFF008318243442FFFF4D
-:10EA00000043102B50400007363100013C02080043
-:10EA10008C42002C244200013C010800AC22002C56
-:10EA2000363100053C0608008CC6003454C0002373
-:10EA30008F8500008F820004304240005440001F48
-:10EA40008F8500003C021F01008210243C0310004F
-:10EA50005443001A8F85000030A2020014400017B2
-:10EA60008F8500003250FFFF363100028F4201B81F
-:10EA70000440FFFE00000000AF40018002002021A2
-:10EA80000E000F42AF4000208F8300042402BFFF1E
-:10EA9000A750019A006218248F820000A750018EAF
-:10EAA000A7510188A74301A6A74201903C0210008C
-:10EAB000AF4201B80A001267000010213C021000AA
-:10EAC00000A210241040003A0000000010C0000F07
-:10EAD0000000000030A201001040000C3C030200C6
-:10EAE0003C020F0000A210241043000800000000A8
-:10EAF0008F82000800541024005610219042000418
-:10EB0000244200040A0011FF000221C0000000009E
-:10EB1000000516023050000F3A0300022E4203EFA8
-:10EB2000384200012C630001006218241460008543
-:10EB3000240200013C0308008C6300D02E06000C68
-:10EB4000386200012C4200010046102414400015D8
-:10EB5000001021C02602FFFC2C420004544000118A
-:10EB600000002021386200022C42000100461024DF
-:10EB700050400003000512420A0011FF000020214E
-:10EB80000010182B0043102450400006001021C034
-:10EB9000000020213245FFFF0E000F633226FFFBED
-:10EBA000001021C03245FFFF0A0012523626000233
-:10EBB0008F4240003C0308008C6300243042010077
-:10EBC0001040004630620001322200043070000D17
-:10EBD000144000022413000424130002000512C292
-:10EBE000384200012E4303EF304200013863000138
-:10EBF00000431025104000033231FFFB2402FFFBCD
-:10EC00000202802410C000183202000130A201006C
-:10EC100010400015320200013C020F0000A2102437
-:10EC20003C0302001043000F8F8200082403FFFE04
-:10EC30000203802400541024005610219042000446
-:10EC4000023330252442000412000002000221C0D9
-:10EC50003226FFFF0E000F633245FFFF120000391E
-:10EC600000001021320200011040000D32020004A9
-:10EC70002402000112020002023330253226FFFF77
-:10EC8000000020210E000F633245FFFF2402FFFE2B
-:10EC9000020280241200002B000010213202000426
-:10ECA0001040002824020001240200041202000285
-:10ECB000023330253226FFFF3245FFFF0E000F637F
-:10ECC000240401002402FFFB020280241200001D24
-:10ECD000000010210A0012672402000150400019B0
-:10ECE000000010213245FFFF3626000200002021DF
-:10ECF0000E000F63000000000A00126700001021E0
-:10ED00002402BFFF00621024104000080000000031
-:10ED1000240287FF00621024144000083C020060B7
-:10ED20000082102410400005000000000E000D3489
-:10ED3000000000000A001267000000000E0012C769
-:10ED400000000000104000063C0240008F430124F8
-:10ED50003C026020AC430014000000003C02400074
-:10ED6000AF4201380000000032A200021040FEBD98
-:10ED7000000000008F4201403C044000AF420020F0
-:10ED80008F4301483C027000006218241064004266
-:10ED9000000000000083102B144000063C026000BD
-:10EDA0003C022000106200073C0240000A0012C32F
-:10EDB000000000001062003C3C0240000A0012C348
-:10EDC000000000008F4501408F4601448F420148FA
-:10EDD00000021402304300FF240200041462000AFF
-:10EDE000274401808F4201B80440FFFE2402001C2A
-:10EDF000AC850000A082000B3C021000AF4201B8BD
-:10EE00000A0012C33C0240002402000914620012EE
-:10EE100000061602000229C0AF4500208F4201B84B
-:10EE20000440FFFE2402000124030003AF450180DB
-:10EE3000A343018BA740018EA740019AA7400190F0
-:10EE4000AF4001A8A7420188A74201A6AF4001AC8C
-:10EE50003C021000AF4201B88F4201B80440FFFEEF
-:10EE600000000000AC8500008F420148000214023F
-:10EE7000A482000824020002A082000B8F420148F5
-:10EE8000A48200103C021000AC860024AF4201B8FE
-:10EE90000A0012C33C0240000E00131000000000E4
-:10EEA0000A0012C33C0240000E001BBA0000000022
-:10EEB0003C024000AF420178000000000A00112F20
-:10EEC000000000008F4201003042003E144000115B
-:10EED00024020001AF4000488F420100304207C0C9
-:10EEE0001040000500000000AF40004CAF40005053
-:10EEF00003E0000824020001AF400054AF4000408E
-:10EF00008F4201003042380054400001AF400044BD
-:10EF10002402000103E00008000000008F4201B855
-:10EF20000440FFFE24020001AF440180AF40018491
-:10EF3000A7450188A342018A24020002A342018B53
-:10EF40009742014A14C00004A7420190AF4001A4B7
-:10EF50000A0012EF3C0210008F420144AF4201A4AC
-:10EF60003C021000AF4001A803E00008AF4201B826
-:10EF70008F4201B80440FFFE24020002AF4401802A
-:10EF8000AF440184A7450188A342018AA342018BB3
-:10EF90009742014AA7420190AF4001A48F42014429
-:10EFA000AF4201A83C02100003E00008AF4201B8E4
-:10EFB0003C0290003442000100822025AF44002032
-:10EFC0008F4200200440FFFE0000000003E0000824
-:10EFD000000000003C028000344200010082202535
-:10EFE00003E00008AF44002027BDFFE8AFBF0014D6
-:10EFF000AFB000108F500140934301499342014844
-:10F0000093440148306300FF304200FF00021200C9
-:10F0100000622825240200191062007630840080E6
-:10F020002862001A1040001C24020020240200085C
-:10F0300010620077286200091040000E2402000BC5
-:10F0400024020001106200342862000250400005D2
-:10F050002402000650600034020020210A00139AA6
-:10F060000000000010620030020020210A00139A04
-:10F07000000000001062003B2862000C50400002BB
-:10F080002402000E24020009106200560200202112
-:10F090000A00139A00000000106200562862002146
-:10F0A0001040000F240200382402001C1062005897
-:10F0B0002862001D104000062402001F2402001BCD
-:10F0C0001062004C000000000A00139A00000000CB
-:10F0D0001062004A020020210A00139A000000007A
-:10F0E00010620045286200391040000724020080A9
-:10F0F0002462FFCB2C420002104000450200202178
-:10F100000A00139600003021106200090000000080
-:10F110000A00139A000000001480003D0200202124
-:10F120000A0013908FBF00140A00139624060001F2
-:10F130008F4201B80440FFFE24020002A342018B6B
-:10F14000A74501889742014AA74201908F42014496
-:10F15000A74201923C021000AF4201B80A00139C82
-:10F160008FBF00149742014A14400029000000009C
-:10F1700093620005304200041440002500000000A6
-:10F180000E001302020020219362000502002021DC
-:10F19000344200040E00130BA362000593620005C5
-:10F1A0003042000414400002000000000000000D86
-:10F1B0009362000024030020304200FF1443001437
-:10F1C000000000008F4201B80440FFFE2402000549
-:10F1D000AF500180A342018B3C0210000A00139A39
-:10F1E000AF4201B88FBF00148FB000100A0012F2B6
-:10F1F00027BD00180000000D020020210000302172
-:10F200008FBF00148FB000100A0012DD27BD001858
-:10F210000000000D8FBF00148FB0001003E0000845
-:10F2200027BD001827BDFFE8AFBF00100E000F3C40
-:10F2300000000000AF4001808FBF001000002021BF
-:10F240000A000FE727BD00183084FFFF30A5FFFF3D
-:10F25000000018211080000700000000308200012B
-:10F260001040000200042042006518210A0013AB80
-:10F270000005284003E000080060102110C00006CF
-:10F2800024C6FFFF8CA2000024A50004AC8200006D
-:10F290000A0013B52484000403E000080000000005
-:10F2A00010A0000824A3FFFFAC86000000000000AF
-:10F2B000000000002402FFFF2463FFFF1462FFFA36
-:10F2C0002484000403E0000800000000308300FFF5
-:10F2D00030A500FF30C600FF274701808F4201B8EC
-:10F2E0000440FFFE000000008F420128346340000C
-:10F2F000ACE2000024020001ACE00004A4E300083A
-:10F30000A0E2000A24020002A0E2000B3C0210006E
-:10F31000A4E50010ACE00024ACE00028A4E6001254
-:10F3200003E00008AF4201B827BDFFE8AFBF0010FF
-:10F330009362003F24030012304200FF1043000D8F
-:10F34000008030218F620044008210230440000AB4
-:10F350008FBF00108F62004824040039000028216C
-:10F3600000C2102304410004240600120E0013C939
-:10F37000000000008FBF00102402000103E000081D
-:10F3800027BD001827BDFFC8AFB20030AFB1002CB9
-:10F39000AFBF0034AFB0002890C5000D00809021B1
-:10F3A00030A400101080000B00C088218CC300081E
-:10F3B0008F6200541062000730A20005144000B5AF
-:10F3C000240400010E000D21000020210A0014BBBE
-:10F3D0000040202130A200051040000930A3001297
-:10F3E000108000AC240400018E2300088F620054BA
-:10F3F000146200A98FBF00340A00142C24040038C2
-:10F4000024020012146200A324040001022020211F
-:10F4100027A500100E000CB2AFA000101040001184
-:10F42000024020218E220008AF620084AF600040BD
-:10F430000E001302000000009362007D02402021B4
-:10F44000344200200E00130BA362007D0E000CA9B5
-:10F4500002402021240400382405008D0A0014B83D
-:10F46000240600129362003E304200081040000F54
-:10F470008FA2001030420100104000078FA300143B
-:10F480008F6200600062102304430008AF630060D5
-:10F490000A00144100000000AF6000609362003E6B
-:10F4A0002403FFF700431024A362003E9362003E52
-:10F4B00030420008144000022406000300003021FE
-:10F4C00093620034936300378F640084304200FFFE
-:10F4D000306300FF006618210003188000432821D4
-:10F4E00000A4202B1080000B000000009763003C5C
-:10F4F0008F6200843063FFFF004510230062182BE9
-:10F5000014600004000000008F6200840A00145D93
-:10F51000004580239762003C3050FFFF8FA300100E
-:10F520003062000410400004000628808FA2001CF6
-:10F530000A0014650202102B2E020218504000032C
-:10F54000240202180A00146E02051023306300041E
-:10F5500010600003004510238FA2001C00451023FB
-:10F56000004080212C420080544000012410008083
-:10F570000E0013020240202124020001AF62000CA1
-:10F580009362003E001020403042007FA362003EA4
-:10F590008E22000424420001AF620040A770003CAC
-:10F5A0008F6200509623000E00431021AF62005876
-:10F5B0008F62005000441021AF62005C8E22000474
-:10F5C000AF6200188E220008AF62001C8FA20010EC
-:10F5D000304200085440000A93A20020A360003685
-:10F5E000936200362403FFDFA36200359362003E7E
-:10F5F00000431024A362003E0A0014988E220008E3
-:10F60000A36200358E220008AF62004C8F62002496
-:10F610008F63004000431021AF62004893620000F6
-:10F6200024030050304200FF144300122403FF80E3
-:10F630003C0208008C4231A00242102100431024F9
-:10F64000AF4200283C0208008C4231A08E24000802
-:10F650003C03000C024210213042007F0342102183
-:10F6600000431021AC4400D88E230008AF82001460
-:10F67000AC4300DC0E00130B0240202124040038B0
-:10F68000000028212406000A0E0013C90000000013
-:10F69000240400018FBF00348FB200308FB1002CE2
-:10F6A0008FB000280080102103E0000827BD00383B
-:10F6B00027BDFFF827420180AFA20000308A00FF7B
-:10F6C0008F4201B80440FFFE000000008F46012871
-:10F6D0003C0208008C4231A02403FF80AF86004822
-:10F6E00000C2102100431024AF4200243C02080055
-:10F6F0008C4231A08FA900008FA8000000C2102109
-:10F700003042007F034218213C02000A00621821A7
-:10F71000946400D48FA700008FA50000240200028B
-:10F72000AF830014A0A2000B8FA30000354260003D
-:10F730003084FFFFA4E200083C021000AD26000068
-:10F74000AD040004AC60002427BD0008AF4201B83E
-:10F7500003E00008240200018F88003C9382002807
-:10F760008F8300143C07080024E7777800481023B3
-:10F77000304200FF304900FC246500888F8600403D
-:10F78000304A0003112000090000202124820004D7
-:10F790008CA30000304400FF0089102AACE3000075
-:10F7A00024A500041440FFF924E7000411400009D7
-:10F7B000000020212482000190A30000304400FFBB
-:10F7C000008A102BA0E3000024A500011440FFF9DB
-:10F7D00024E7000130C20003144000048F85003C80
-:10F7E000310200031040000D0000000010A00009CD
-:10F7F000000020212482000190C30000304400FF5B
-:10F800000085102BA0E3000024C600011440FFF97E
-:10F8100024E7000103E00008000000001100FFFDE4
-:10F8200000002021248200048CC30000304400FF2B
-:10F830000088102BACE3000024C600041440FFF93C
-:10F8400024E7000403E00008000000008F83003C70
-:10F850009382002830C600FF30A500FF004310232C
-:10F86000304300FF8F8200140080382100431021B4
-:10F8700014C00002244800880083382130E20003CD
-:10F880001440000530A2000314400003306200035E
-:10F890001040000D0000000010A000090000202111
-:10F8A0002482000190E30000304400FF0085102B0B
-:10F8B000A103000024E700011440FFF9250800011E
-:10F8C00003E000080000000010A0FFFD0000202160
-:10F8D000248200048CE30000304400FF0085102BDC
-:10F8E000AD03000024E700041440FFF925080004DC
-:10F8F00003E00008000000000080482130AAFFFF5C
-:10F9000030C600FF30E7FFFF274801808F4201B873
-:10F910000440FFFE8F820048AD0200008F420124A8
-:10F92000AD0200048D220020A5070008A102000AF4
-:10F9300024020016A102000B934301208D2200082F
-:10F940008D240004306300FF004310219783003AA8
-:10F95000004410218D250024004310233C0308009F
-:10F960008C6331A08F840014A502000C246300E88E
-:10F970002402FFFFA50A000EA5030010A506001231
-:10F98000AD050018AD020024948201142403FFF792
-:10F990003042FFFFAD0200288C820118AD02002C1E
-:10F9A0003C021000AD000030AF4201B88D220020B3
-:10F9B0000043102403E00008AD2200208F820014D1
-:10F9C00030E7FFFF00804821904200D330A5FFFFC1
-:10F9D00030C600FF0002110030420F0000E238255F
-:10F9E000274801808F4201B80440FFFE8F82004803
-:10F9F000AD0200008F420124AD0200048D220020E0
-:10FA0000A5070008A102000A24020017A102000BAA
-:10FA1000934301208D2200088D240004306300FFF1
-:10FA2000004310219783003A004410218F84001472
-:10FA3000004310233C0308008C6331A0A502000C96
-:10FA4000A505000E246300E8A5030010A50600121A
-:10FA5000AD0000148D220024AD0200188C82005CE1
-:10FA6000AD02001C8C820058AD0200202402FFFF72
-:10FA7000AD020024948200E63042FFFFAD02002870
-:10FA800094820060948300BE30427FFF3063FFFFAA
-:10FA90000002120000431021AD02002C3C021000B5
-:10FAA000AD000030AF4201B8948200BE2403FFF7DE
-:10FAB00000A21021A48200BE8D2200200043102449
-:10FAC00003E00008AD220020274301808F4201B8E7
-:10FAD0000440FFFE8F8200249442001C3042FFFF4E
-:10FAE000000211C0AC62000024020019A062000BE9
-:10FAF0003C021000AC60003003E00008AF4201B8E7
-:10FB00008F87002C30C300FF8F4201B80440FFFEF6
-:10FB10008F82004834636000ACA2000093820044EE
-:10FB2000A0A200058CE20010A4A20006A4A3000875
-:10FB30008C8200202403FFF7A0A2000A2402000206
-:10FB4000A0A2000B8CE20000ACA200108CE200042A
-:10FB5000ACA200148CE2001CACA200248CE20020B9
-:10FB6000ACA200288CE2002CACA2002C8C820024D9
-:10FB7000ACA200183C021000AF4201B88C820020F9
-:10FB80000043102403E00008AC8200208F8600149C
-:10FB900027BDFFE8AFBF0014AFB0001090C20063F4
-:10FBA000304200201040000830A500FF8CC2007CCD
-:10FBB0002403FFDF24420001ACC2007C90C200633A
-:10FBC00000431024A0C2006310A000238F83001400
-:10FBD00027500180020028210E0015D6240600823D
-:10FBE0008F82001490420063304200405040001960
-:10FBF000A38000448F83002C8F4201B80440FFFE95
-:10FC00008F820048AE02000024026082A602000833
-:10FC100024020002A202000B8C620008AE02001057
-:10FC20008C62000CAE0200148C620014AE0200184C
-:10FC30008C620018AE0200248C620024AE02002800
-:10FC40008C620028AE02002C3C021000AF4201B8CA
-:10FC5000A38000448F8300148FBF00148FB0001066
-:10FC60009062006327BD00183042007FA0620063ED
-:10FC70009782003A8F86003C8F850014938300287A
-:10FC800000461023A782003AA4A000E490A40063D9
-:10FC90008F820040AF83003C2403FFBF0046102149
-:10FCA00000832024AF820040A0A400638F82001450
-:10FCB000A04000BD8F82001403E00008A44000BEF5
-:10FCC0008F8A001427BDFFE0AFB10014AFB0001061
-:10FCD0008F88003CAFBF00189389001C954200E458
-:10FCE00030D100FF0109182B0080802130AC00FFCB
-:10FCF0003047FFFF0000582114600003310600FF69
-:10FD000001203021010958239783003A0068102B05
-:10FD10001440003C000000001468000724020001A9
-:10FD20008E0200202403FFFB34E7800000431024F0
-:10FD3000AE0200202402000134E70880158200058D
-:10FD40003165FFFF0E001554020020210A001691B4
-:10FD5000020020210E001585020020218F8400481A
-:10FD6000274301808F4201B80440FFFE240200189F
-:10FD7000AC640000A062000B8F840014948200E643
-:10FD8000A46200103C021000AC600030AF4201B829
-:10FD90009482006024420001A4820060948200608A
-:10FDA0003C0308008C63318830427FFF5443000FCE
-:10FDB000020020219482006024038000004310246C
-:10FDC000A48200609082006090830060304200FF57
-:10FDD000000211C200021027000211C03063007F30
-:10FDE00000621825A0830060020020210220282143
-:10FDF0008FBF00188FB100148FB000100A0015F9E2
-:10FE000027BD0020914200632403FF80004310259A
-:10FE1000A14200639782003A3048FFFF11000020A2
-:10FE20009383001C8F840014004B1023304600FF86
-:10FE3000948300E42402EFFF0168282B0062182459
-:10FE4000A48300E414A000038E02002001005821C6
-:10FE5000000030212403FFFB34E78000004310241E
-:10FE6000AE02002024020001158200053165FFFF6B
-:10FE70000E001554020020210A0016B99783003A9B
-:10FE80000E001585020020219783003A8F82003CE6
-:10FE9000A780003A00431023AF82003C9383001CEC
-:10FEA0008F8200148FBF00188FB100148FB0001024
-:10FEB00027BD002003E00008A04300BD938200445A
-:10FEC0002403000127BDFFE8004330042C4200203A
-:10FED000AFB00010AFBF00142410FFFE10400005AB
-:10FEE000274501803C0208008C4231900A0016D65A
-:10FEF000004610243C0208008C4231940046102435
-:10FF000014400007240600848F8300142410FFFF90
-:10FF1000906200623042000F34420040A0620062F2
-:10FF20000E0015D600000000020010218FBF001443
-:10FF30008FB0001003E0000827BD00188F83002455
-:10FF400027BDFFE0AFB20018AFB10014AFB0001092
-:10FF5000AFBF001C9062000D00A0902130D100FFC7
-:10FF60003042007FA062000D8F8500148E43001880
-:10FF7000008080218CA2007C146200052402000E07
-:10FF800090A20063344200200A0016FFA0A2006382
-:10FF90000E0016C5A38200442403FFFF1043004750
-:10FFA0002404FFFF52200045000020218E43000062
-:10FFB0003C02001000621024504000043C02000883
-:10FFC000020020210A00170E2402001500621024EE
-:10FFD000504000098E450000020020212402001438
-:10FFE0000E0016C5A38200442403FFFF1043003314
-:10FFF0002404FFFF8E4500003C02000200A21024F2
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000008000000000000000000B
+:10D5A000000000000000000000000000000000007B
+:10D5B00000000000000000000000000A0000000061
+:10D5C0000000000000000000100000030000000048
+:10D5D0000000000D0000000D3C02080024427320F2
+:10D5E0003C030800246377ACAC4000000043202BD0
+:10D5F0001480FFFD244200043C1D080037BD7FFC61
+:10D6000003A0F0213C100800261032103C1C08003A
+:10D61000279C73200E0010FE000000000000000D8B
+:10D6200030A5FFFF30C600FF274301808F4201B8BD
+:10D630000440FFFE24020002AC640000A465000860
+:10D64000A066000AA062000B3C021000AC67001844
+:10D6500003E00008AF4201B83C0360008C624FF861
+:10D660000440FFFE3C020200AC644FC0AC624FC4F9
+:10D670003C02100003E00008AC624FF89482000CFA
+:10D680002486001400A0382100021302000210803A
+:10D690000082402100C8102B1040005700000000FD
+:10D6A00090C300002C6200095040005190C200015C
+:10D6B000000310803C030800246372D00043102153
+:10D6C0008C420000004000080000000090C30001F0
+:10D6D0002402000A1462003A000000000106102330
+:10D6E0002C42000A1440003624C600028CE20000DE
+:10D6F00034420100ACE2000090C2000090C300017F
+:10D7000090C4000290C5000300031C000002160034
+:10D710000043102500042200004410250045102578
+:10D7200024C60004ACE2000490C2000090C30001D3
+:10D7300090C4000290C500030002160000031C0004
+:10D740000043102500042200004410250045102548
+:10D7500024C600040A000CB8ACE2000890C3000123
+:10D76000240200041462001624C6000290C20000C5
+:10D7700090C400018CE30000000212000044102558
+:10D780003463000424C60002ACE2000C0A000CB8AA
+:10D79000ACE3000090C300012402000314620008FF
+:10D7A00024C600028CE2000090C3000024C60001E1
+:10D7B00034420008A0E300100A000CB8ACE20000FC
+:10D7C00003E000082402000190C3000124020002CB
+:10D7D0001062000224C40002010020210A000CB8DB
+:10D7E000008030210A000CB824C6000190C200015C
+:10D7F0000A000CB800C2302103E00008000010212C
+:10D8000027BDFFE8AFBF0014AFB000100E00130239
+:10D8100000808021936200052403FFFE0200202186
+:10D82000004310248FBF00148FB00010A3620005C6
+:10D830000A00130B27BD001827BDFFE8AFB000108A
+:10D84000AFBF00140E000F3C0080802193620000E7
+:10D8500024030050304200FF14430004240201005E
+:10D86000AF4201800A000D3002002021AF4001804C
+:10D87000020020218FBF00148FB000100A000FE7B4
+:10D8800027BD001827BDFF80AFBE0078AFB700747A
+:10D89000AFB20060AFBF007CAFB60070AFB5006C38
+:10D8A000AFB40068AFB30064AFB1005CAFB0005874
+:10D8B0008F5001283C0208008C4231A02403FF80D5
+:10D8C0009365003F0202102100431024AF42002460
+:10D8D0003C0208008C4231A09364000530B200FF86
+:10D8E000020210213042007F034218210004202749
+:10D8F0003C02000A0062182130840001AF8300144A
+:10D900000000F0210000B82114800053AFA00050A7
+:10D9100093430116934401128F450104306300FFC5
+:10D920003C020001308400FF00A2282403431021A0
+:10D9300003441821245640002467400014A001CD60
+:10D940002402000193620000304300FF2402002003
+:10D950001062000524020050106200060000000062
+:10D960000A000D74000000000000000D0A000D7D8B
+:10D97000AFA000303C1E080027DE736C0A000D7D4E
+:10D98000AFA000303C0208008C4200DC24420001C1
+:10D990003C010800AC2200DC0E00139F00000000D8
+:10D9A0000A000F318FBF007C8F4201043C0300202E
+:10D9B00092D3000D004310240002202B00042140CC
+:10D9C000AFA400308F4301043C02004000621824E1
+:10D9D000146000023485004000802821326200205B
+:10D9E000AFA500301440000234A6008000A0302112
+:10D9F00010C0000BAFA6003093C500088F67004C25
+:10DA00000200202100052B0034A5008130A5F08103
+:10DA10000E000C9B30C600FF0A000F2E0000000015
+:10DA20009362003E304200401040000F2402000488
+:10DA300056420007240200120200202100E02821A3
+:10DA40000E0013F702C030210A000F318FBF007C97
+:10DA500016420005000000000E000D2100002021EC
+:10DA60000A000F318FBF007C9743011A96C4000E45
+:10DA700093620035326500043075FFFF00442004D6
+:10DA8000AFA400548ED1000410A000158ED400085D
+:10DA90009362003E3042004010400007000000004A
+:10DAA0000E0013E0022020211040000D00000000B5
+:10DAB0000A000F2E000000008F6200440222102393
+:10DAC0000440016A000000008F6200480222102317
+:10DAD00004410166240400160A000E218FC20004CE
+:10DAE0008F6200480222102304400008000000005A
+:10DAF0003C0208008C423100244200013C01080035
+:10DB0000AC2231000A000F23000000008F620040A9
+:10DB100002221023184000128F8400143C020800D7
+:10DB20008C423100327300FC0000A8212442000125
+:10DB30003C010800AC2231008F6300409482011C3C
+:10DB4000022318233042FFFF0043102A50400010E8
+:10DB50002402000C8F6200400A000DF20222102302
+:10DB60009483011C9762003C0043102B1040000678
+:10DB7000000000009482011C00551023A482011CA7
+:10DB80000A000DF72402000CA480011C2402000CE2
+:10DB9000AFA200308F620040005120231880000D9A
+:10DBA00002A4102A1440012600000000149500066B
+:10DBB00002A410233A620001304200011440012007
+:10DBC0000000000002A41023022488210A000E098C
+:10DBD0003055FFFF00002021326200021040001A81
+:10DBE000326200109362003E30420040504000110B
+:10DBF0008FC200040E00130202002021240200182C
+:10DC0000A362003F936200052403FFFE020020216F
+:10DC1000004310240E00130BA362000524040039F6
+:10DC2000000028210E0013C9240600180A000F3036
+:10DC300024020001240400170040F809000000003D
+:10DC40000A000F302402000110400108000000000B
+:10DC50008F63004C8F620054028210231C4001032A
+:10DC600002831023044200010060A021AFA4001829
+:10DC7000AFB10010AFB50014934201208F65004092
+:10DC80009763003C304200FF034210210044102102
+:10DC90008FA400543063FFFF244240000083182B00
+:10DCA0008FA40030AFA20020AFA50028008320255C
+:10DCB000AFA40030AFA50024AFA0002CAFB4003457
+:10DCC0009362003E30420008504000118FC20000B5
+:10DCD00002C0202127A500380E000CB2AFA00038EA
+:10DCE0005440000B8FC200008FA200383042010068
+:10DCF000504000078FC200008FA3003C8F6200607D
+:10DD00000062102304430001AF6300608FC2000073
+:10DD10000040F80927A400108FA200303042000212
+:10DD200054400001327300FE9362003E30420040D6
+:10DD3000104000378FA200248F6200541682001A10
+:10DD40003262000124020014124200102A4200151F
+:10DD500010400006240200162402000C12420007A4
+:10DD6000326200010A000E7D000000001242000530
+:10DD7000326200010A000E7D000000000A000E78E9
+:10DD80002417000E0A000E78241700100A000E7CDB
+:10DD900024170012936200232403FFBD00431024C4
+:10DDA000A362002332620001104000198FA20024F8
+:10DDB0002402000C1242000E2A42000D1040000600
+:10DDC0002402000E2402000A124200078FA200243F
+:10DDD0000A000E9524420001124200088FA200247E
+:10DDE0000A000E95244200010A000E932417000831
+:10DDF0002402000E16E20002241700162417001059
+:10DE00008FA2002424420001AFA200248FA200248C
+:10DE10008FA300148F76004000431021AF620040B2
+:10DE20008F8200149442011C104000090000000081
+:10DE30008F6200488F6400409763003C00441023C9
+:10DE40003063FFFF0043102A104000088FA20054E7
+:10DE5000936400368F6300403402FFFC008210049C
+:10DE600000621821AF6300488FA200548FA60030D3
+:10DE70000282902130C200081040000E0000000015
+:10DE80008F6200581642000430C600FF9742011A04
+:10DE90005040000134C6001093C500088FA700341D
+:10DEA0000200202100052B0034A500800E000C9BF1
+:10DEB00030A5F0808F620040005610231840001BF0
+:10DEC0008FA200183C0208008C42319830420010AA
+:10DED0001040000D24020001976200681440000AFF
+:10DEE000240200018F8200149442011C1440000699
+:10DEF00024020001A76200689742007A244200646D
+:10DF00000A000EE9A7620012A76200120E001302B7
+:10DF1000020020219362007D2403000102002021E1
+:10DF2000344200010A000EE7AFA300501840000A77
+:10DF3000000000000E001302020020219362007D09
+:10DF40002403000102002021AFA30050344200044A
+:10DF50000E00130BA362007D9362003E304200402E
+:10DF60001440000C326200011040000A0000000062
+:10DF70008F6300408FC20004240400182463000152
+:10DF80000040F809AF6300408FA200300A000F3054
+:10DF9000304200048F620058105200100000000050
+:10DFA0008F620018022210231C4000082404000184
+:10DFB0008F62001816220009000000008F62001C0A
+:10DFC000028210230440000500000000AF720058D8
+:10DFD000AFA40050AF710018AF74001C12E0000B2A
+:10DFE0008FA200500E00130202002021A377003FF1
+:10DFF0000E00130B0200202102E030212404003720
+:10E000000E0013C9000028218FA200501040000309
+:10E01000000000000E000CA90200202112A0000543
+:10E02000000018218FA2003030420004504000113F
+:10E0300000601021240300010A000F30006010214D
+:10E040000E001302020020219362007D02002021B5
+:10E05000344200040E00130BA362007D0E000CA9D5
+:10E06000020020210A000F3024020001AF400044CA
+:10E07000240200018FBF007C8FBE00788FB7007430
+:10E080008FB600708FB5006C8FB400688FB30064DA
+:10E090008FB200608FB1005C8FB0005803E00008C1
+:10E0A00027BD00808F4201B80440FFFE2402080013
+:10E0B000AF4201B803E00008000000003C02000885
+:10E0C00003421021944200483084FFFF2484001250
+:10E0D0003045FFFF10A0001700A4102B10400016C1
+:10E0E00024020003934201202403001AA343018B5E
+:10E0F000304200FF2446FFFE8F82000000A6182B4E
+:10E100003863000100021382004310241040000510
+:10E110008F84000434820001A746019403E00008C4
+:10E12000AF8200042402FFFE0082102403E00008F6
+:10E13000AF8200042402000303E00008A342018B25
+:10E1400027BDFFE0AFB10014AFB00010AFBF0018A3
+:10E1500030B0FFFF30D1FFFF8F4201B80440FFFE17
+:10E1600000000000AF440180AF4400200E000F42C9
+:10E17000020020218F8300008F840004A750019AA1
+:10E18000A750018EA74301908F8300083082800042
+:10E19000AF4301A8A75101881040000E8F820004F0
+:10E1A00093420116304200FC24420004005A102120
+:10E1B0008C4240003042FFFF144000068F82000472
+:10E1C0003C02FFFF34427FFF00821024AF82000434
+:10E1D0008F8200042403BFFF00431024A74201A63E
+:10E1E0009743010C8F42010400031C003042FFFFE3
+:10E1F00000621825AF4301AC3C021000AF4201B8E9
+:10E200008FBF00188FB100148FB0001003E000081A
+:10E2100027BD00208F470070934201128F830000BA
+:10E2200027BDFFF0304200FF00022882306201006B
+:10E23000000030211040004324A40003306240005D
+:10E24000104000103062200000041080005A10219D
+:10E250008C43400024A4000400041080AFA30000FD
+:10E26000005A10218C424000AFA2000493420116D4
+:10E27000304200FC005A10218C4240000A000FC0BE
+:10E28000AFA200081040002F0000302100041080D1
+:10E29000005A10218C43400024A400040004108084
+:10E2A000AFA30000005A10218C424000AFA000082C
+:10E2B000AFA200048FA80008000030210000202138
+:10E2C000240A00083C0908002529010003A41021A4
+:10E2D000148A000300042A001100000A0000000054
+:10E2E00090420000248400012C83000C00A2102125
+:10E2F00000021080004910218C4200001460FFF3DE
+:10E3000000C230263C0408008C8431048F42007027
+:10E310002C83002010600009004738233C030800CC
+:10E32000246331080004108000431021248300017D
+:10E33000AC4700003C010800AC233104AF86000864
+:10E340002406000100C0102103E0000827BD0010D2
+:10E350003C0208008C42003827BDFFD0AFB5002436
+:10E36000AFB40020AFB10014AFBF0028AFB3001CA2
+:10E37000AFB20018AFB00010000088213C150800B3
+:10E3800026B50038144000022454FFFF0000A021ED
+:10E390009742010E8F8400003042FFFF308340001F
+:10E3A0001060000A245200043C0200200082102465
+:10E3B00050400007308280008F8200042403BFFF9A
+:10E3C000008318240A0010103442100030828000AC
+:10E3D0001040000A3C020020008210241040000778
+:10E3E0008F8200043C03FFFF34637FFF0083182407
+:10E3F00034428000AF820004AF8300000E000F980B
+:10E400000000000014400007000000009743011EB8
+:10E410009742011C3063FFFF0002140000621825C0
+:10E42000AF8300089742010C8F4340003045FFFF47
+:10E430003402FFFF14620003000000000A001028ED
+:10E44000241100208F42400030420100544000015E
+:10E45000241100108F8400003082100050400014FE
+:10E4600036310001308200201440000B3C021000C5
+:10E47000008210245040000E363100013C030E0093
+:10E480003C020DFF008318243442FFFF0043102B91
+:10E4900050400007363100013C0208008C42002C3D
+:10E4A000244200013C010800AC22002C363100055A
+:10E4B0003C0608008CC6003454C000238F85000041
+:10E4C0008F820004304240005440001F8F850000BE
+:10E4D0003C021F01008210243C0310005443001A28
+:10E4E0008F85000030A20200144000178F850000C5
+:10E4F0003250FFFF363100028F4201B80440FFFE68
+:10E5000000000000AF400180020020210E000F42F9
+:10E51000AF4000208F8300042402BFFFA750019A60
+:10E52000006218248F820000A750018EA751018835
+:10E53000A74301A6A74201903C021000AF4201B8D8
+:10E540000A0010F5000010213C02100000A2102467
+:10E550001040003A0000000010C0000F0000000052
+:10E5600030A201001040000C3C0302003C020F00EE
+:10E5700000A2102410430008000000008F82000851
+:10E58000005410240055102190420004244200043D
+:10E590000A00109F000221C00000000000051602C2
+:10E5A0003050000F3A0300022E4203EF38420001C0
+:10E5B0002C6300010062182414600073240200011F
+:10E5C0003C0308008C6300D02E06000C386200016A
+:10E5D0002C4200010046102414400015001021C0F8
+:10E5E0002602FFFC2C4200045440001100002021B0
+:10E5F000386200022C420001004610241040000343
+:10E60000000512420A00109F000020210010182B64
+:10E610000043102450400006001021C000002021BB
+:10E620003245FFFF0E000F633226FFFB001021C0B2
+:10E630003245FFFF0A0010F2362600028F424000EA
+:10E640003C0308008C630024304201001040004667
+:10E6500030620001322200043070000D14400002CC
+:10E660002413000424130002000512C238420001E2
+:10E670002E4303EF304200013863000100431025B0
+:10E68000104000033231FFFB2402FFFB0202802412
+:10E6900010C000183202000130A201001040001525
+:10E6A000320200013C020F0000A210243C030200D1
+:10E6B0001043000F8F8200082403FFFE0203802412
+:10E6C00000541024005510219042000402333025DC
+:10E6D0002442000412000002000221C03226FFFF83
+:10E6E0000E000F633245FFFF1200002700001021CB
+:10E6F000320200011040000D320200042402000129
+:10E7000012020002023330253226FFFF00002021D2
+:10E710000E000F633245FFFF2402FFFE0202802439
+:10E7200012000019000010213202000410400016EF
+:10E7300024020001240200041202000202333025E8
+:10E740003226FFFF3245FFFF0E000F632404010055
+:10E750002402FFFB020280241200000B00001021A3
+:10E760000A0010F5240200011040000700001021EB
+:10E770003245FFFF36260002000020210E000F6305
+:10E7800000000000000010218FBF00288FB500247A
+:10E790008FB400208FB3001C8FB200188FB100140B
+:10E7A0008FB0001003E0000827BD003027BDFFD068
+:10E7B000AFB000103C04600CAFBF002CAFB6002817
+:10E7C000AFB50024AFB40020AFB3001CAFB2001847
+:10E7D000AFB100148C8250002403FF7F3C1A8000EC
+:10E7E000004310243442380CAC8250002402000351
+:10E7F0003C106000AF4200088E0208083C1B8008F5
+:10E800003C010800AC2000203042FFF038420010EC
+:10E810002C4200010E001B85AF8200183C04FFFF54
+:10E820003C020400348308063442000CAE0219484E
+:10E83000AE03194C3C0560168E0219808CA30000B3
+:10E840003442020000641824AE0219803C02535383
+:10E850001462000334A47C008CA200040050202128
+:10E860008C82007C8C830078AF820010AF83000C18
+:10E870008F55000032A200031040FFFD32A20001BC
+:10E880001040013D32A200028F420128AF42002019
+:10E890008F4201048F430100AF8200000E000F3C45
+:10E8A000AF8300043C0208008C4200C01040000806
+:10E8B0008F8400003C0208008C4200C42442000106
+:10E8C0003C010800AC2200C40A00126900000000EC
+:10E8D0003C020010008210241440010C8F830004BD
+:10E8E0003C0208008C4200203C0308008C63003886
+:10E8F00000008821244200013C010800AC220020D5
+:10E900003C16080026D60038146000022474FFFF6D
+:10E910000000A0219742010E308340003042FFFFEB
+:10E920001060000A245200043C02002000821024DF
+:10E9300050400007308280008F8200042403BFFF14
+:10E94000008318240A0011703442100030828000C5
+:10E950001040000A3C0200200082102410400007F2
+:10E960008F8200043C03FFFF34637FFF0083182481
+:10E9700034428000AF820004AF8300000E000F9885
+:10E980000000000014400007000000009743011E33
+:10E990009742011C3063FFFF00021400006218253B
+:10E9A000AF8300089742010C8F4340003045FFFFC2
+:10E9B0003402FFFF14620003000000000A00118807
+:10E9C000241100208F4240003042010054400001D9
+:10E9D000241100108F840000308210005040001479
+:10E9E00036310001308200201440000B3C02100040
+:10E9F000008210245040000E363100013C030E000E
+:10EA00003C020DFF008318243442FFFF0043102B0B
+:10EA100050400007363100013C0208008C42002CB7
+:10EA2000244200013C010800AC22002C36310005D4
+:10EA30003C0608008CC6003454C000238F850000BB
+:10EA40008F820004304240005440001F8F85000038
+:10EA50003C021F01008210243C0310005443001AA2
+:10EA60008F85000030A20200144000178F8500003F
+:10EA70003250FFFF363100028F4201B80440FFFEE2
+:10EA800000000000AF400180020020210E000F4274
+:10EA9000AF4000208F8300042402BFFFA750019ADB
+:10EAA000006218248F820000A750018EA7510188B0
+:10EAB000A74301A6A74201903C021000AF4201B853
+:10EAC0000A001267000010213C02100000A210246E
+:10EAD0001040003A0000000010C0000F00000000CD
+:10EAE00030A201001040000C3C0302003C020F0069
+:10EAF00000A2102410430008000000008F820008CC
+:10EB000000541024005610219042000424420004B6
+:10EB10000A0011FF000221C00000000000051602DB
+:10EB20003050000F3A0300022E4203EF384200013A
+:10EB30002C63000100621824146000852402000187
+:10EB40003C0308008C6300D02E06000C38620001E4
+:10EB50002C4200010046102414400015001021C072
+:10EB60002602FFFC2C42000454400011000020212A
+:10EB7000386200022C42000100461024504000037D
+:10EB8000000512420A0011FF000020210010182B7E
+:10EB90000043102450400006001021C00000202136
+:10EBA0003245FFFF0E000F633226FFFB001021C02D
+:10EBB0003245FFFF0A001252362600028F42400003
+:10EBC0003C0308008C6300243042010010400046E2
+:10EBD00030620001322200043070000D1440000247
+:10EBE0002413000424130002000512C2384200015D
+:10EBF0002E4303EF3042000138630001004310252B
+:10EC0000104000033231FFFB2402FFFB020280248C
+:10EC100010C000183202000130A20100104000159F
+:10EC2000320200013C020F0000A210243C0302004B
+:10EC30001043000F8F8200082403FFFE020380248C
+:10EC40000054102400561021904200040233302555
+:10EC50002442000412000002000221C03226FFFFFD
+:10EC60000E000F633245FFFF120000390000102133
+:10EC7000320200011040000D3202000424020001A3
+:10EC800012020002023330253226FFFF000020214D
+:10EC90000E000F633245FFFF2402FFFE02028024B4
+:10ECA0001200002B00001021320200041040002846
+:10ECB0002402000124020004120200020233302563
+:10ECC0003226FFFF3245FFFF0E000F6324040100D0
+:10ECD0002402FFFB020280241200001D000010210C
+:10ECE0000A001267240200015040001900001021A0
+:10ECF0003245FFFF36260002000020210E000F6380
+:10ED0000000000000A001267000010212402BFFF6B
+:10ED1000006210241040000800000000240287FF59
+:10ED200000621024144000083C020060008210249D
+:10ED300010400005000000000E000D34000000002F
+:10ED40000A001267000000000E0012C70000000059
+:10ED5000104000063C0240008F4301243C0260202A
+:10ED6000AC430014000000003C024000AF420138F8
+:10ED70000000000032A200021040FEBD00000000B2
+:10ED80008F4201403C044000AF4200208F430148C5
+:10ED90003C02700000621824106400420000000071
+:10EDA0000083102B144000063C0260003C0220004F
+:10EDB000106200073C0240000A0012C3000000007D
+:10EDC0001062003C3C0240000A0012C30000000038
+:10EDD0008F4501408F4601448F42014800021402D2
+:10EDE000304300FF240200041462000A274401801B
+:10EDF0008F4201B80440FFFE2402001CAC850000D5
+:10EE0000A082000B3C021000AF4201B80A0012C3FE
+:10EE10003C0240002402000914620012000616029F
+:10EE2000000229C0AF4500208F4201B80440FFFE18
+:10EE30002402000124030003AF450180A343018B9A
+:10EE4000A740018EA740019AA7400190AF4001A8BA
+:10EE5000A7420188A74201A6AF4001AC3C021000C6
+:10EE6000AF4201B88F4201B80440FFFE000000002D
+:10EE7000AC8500008F42014800021402A482000801
+:10EE800024020002A082000B8F420148A4820010DD
+:10EE90003C021000AC860024AF4201B80A0012C345
+:10EEA0003C0240000E001310000000000A0012C3D4
+:10EEB0003C0240000E001BBA000000003C02400073
+:10EEC000AF420178000000000A00112F000000008E
+:10EED0008F4201003042003E144000112402000124
+:10EEE000AF4000488F420100304207C0104000058B
+:10EEF00000000000AF40004CAF40005003E00008AD
+:10EF000024020001AF400054AF4000408F42010096
+:10EF10003042380054400001AF4000442402000158
+:10EF200003E00008000000008F4201B80440FFFE2B
+:10EF300024020001AF440180AF400184A74501884D
+:10EF4000A342018A24020002A342018B9742014A94
+:10EF500014C00004A7420190AF4001A40A0012EFC0
+:10EF60003C0210008F420144AF4201A43C02100059
+:10EF7000AF4001A803E00008AF4201B88F4201B8DA
+:10EF80000440FFFE24020002AF440180AF4401842C
+:10EF9000A7450188A342018AA342018B9742014AF7
+:10EFA000A7420190AF4001A48F420144AF4201A8A3
+:10EFB0003C02100003E00008AF4201B83C029000A0
+:10EFC0003442000100822025AF4400208F420020FF
+:10EFD0000440FFFE0000000003E000080000000005
+:10EFE0003C028000344200010082202503E000083A
+:10EFF000AF44002027BDFFE8AFBF0014AFB0001042
+:10F000008F50014093430149934201489344014882
+:10F01000306300FF304200FF00021200006228252A
+:10F020002402001910620076308400802862001AE1
+:10F030001040001C24020020240200081062007707
+:10F04000286200091040000E2402000B2402000177
+:10F0500010620034286200025040000524020006BD
+:10F0600050600034020020210A00139A00000000C2
+:10F0700010620030020020210A00139A00000000F4
+:10F080001062003B2862000C504000022402000E77
+:10F090002402000910620056020020210A00139A7F
+:10F0A0000000000010620056286200211040000F8E
+:10F0B000240200382402001C106200582862001D3F
+:10F0C000104000062402001F2402001B1062004CA6
+:10F0D000000000000A00139A000000001062004ABD
+:10F0E000020020210A00139A00000000106200456F
+:10F0F0002862003910400007240200802462FFCB00
+:10F100002C42000210400045020020210A00139604
+:10F110000000302110620009000000000A00139A6C
+:10F12000000000001480003D020020210A0013901E
+:10F130008FBF00140A001396240600018F4201B805
+:10F140000440FFFE24020002A342018BA745018870
+:10F150009742014AA74201908F420144A74201927F
+:10F160003C021000AF4201B80A00139C8FBF00148C
+:10F170009742014A144000290000000093620005F4
+:10F180003042000414400025000000000E0013026D
+:10F190000200202193620005020020213442000475
+:10F1A0000E00130BA36200059362000530420004B9
+:10F1B00014400002000000000000000D93620000F7
+:10F1C00024030020304200FF14430014000000001C
+:10F1D0008F4201B80440FFFE24020005AF500180B9
+:10F1E000A342018B3C0210000A00139AAF4201B8FF
+:10F1F0008FBF00148FB000100A0012F227BD001854
+:10F200000000000D02002021000030218FBF0014FB
+:10F210008FB000100A0012DD27BD00180000000D9D
+:10F220008FBF00148FB0001003E0000827BD001846
+:10F2300027BDFFE8AFBF00100E000F3C000000002C
+:10F24000AF4001808FBF0010000020210A000FE7AF
+:10F2500027BD00183084FFFF30A5FFFF00001821F4
+:10F260001080000700000000308200011040000202
+:10F2700000042042006518210A0013AB0005284055
+:10F2800003E000080060102110C0000624C6FFFF44
+:10F290008CA2000024A50004AC8200000A0013B573
+:10F2A0002484000403E000080000000010A000080F
+:10F2B00024A3FFFFAC860000000000000000000057
+:10F2C0002402FFFF2463FFFF1462FFFA248400047A
+:10F2D00003E0000800000000308300FF30A500FFBD
+:10F2E00030C600FF274701808F4201B80440FFFE6F
+:10F2F000000000008F42012834634000ACE20000AF
+:10F3000024020001ACE00004A4E30008A0E2000A2B
+:10F3100024020002A0E2000B3C021000A4E5001051
+:10F32000ACE00024ACE00028A4E6001203E00008F2
+:10F33000AF4201B827BDFFE8AFBF00109362003FA6
+:10F3400024030012304200FF1043000D00803021E2
+:10F350008F620044008210230440000A8FBF001017
+:10F360008F620048240400390000282100C21023C5
+:10F3700004410004240600120E0013C9000000001E
+:10F380008FBF00102402000103E0000827BD001811
+:10F3900027BDFFC8AFB20030AFB1002CAFBF003403
+:10F3A000AFB0002890C5000D0080902130A400105F
+:10F3B0001080000B00C088218CC300088F620054AD
+:10F3C0001062000730A20005144000B524040001BB
+:10F3D0000E000D21000020210A0014BB0040202156
+:10F3E00030A200051040000930A30012108000ACCC
+:10F3F000240400018E2300088F620054146200A9C7
+:10F400008FBF00340A00142C240400382402001298
+:10F41000146200A3240400010220202127A500106B
+:10F420000E000CB2AFA000101040001102402021CD
+:10F430008E220008AF620084AF6000400E0013020D
+:10F44000000000009362007D024020213442002031
+:10F450000E00130BA362007D0E000CA902402021B8
+:10F46000240400382405008D0A0014B82406001274
+:10F470009362003E304200081040000F8FA200103F
+:10F4800030420100104000078FA300148F6200601B
+:10F490000062102304430008AF6300600A001441B7
+:10F4A00000000000AF6000609362003E2403FFF79D
+:10F4B00000431024A362003E9362003E30420008E5
+:10F4C000144000022406000300003021936200343F
+:10F4D000936300378F640084304200FF306300FF85
+:10F4E00000661821000318800043282100A4202B67
+:10F4F0001080000B000000009763003C8F620084C6
+:10F500003063FFFF004510230062182B14600004D5
+:10F51000000000008F6200840A00145D0045802313
+:10F520009762003C3050FFFF8FA300103062000450
+:10F5300010400004000628808FA2001C0A001465F9
+:10F540000202102B2E02021850400003240202185F
+:10F550000A00146E020510233063000410600003DB
+:10F56000004510238FA2001C00451023004080217D
+:10F570002C42008054400001241000800E00130231
+:10F580000240202124020001AF62000C9362003E81
+:10F59000001020403042007FA362003E8E22000413
+:10F5A00024420001AF620040A770003C8F6200500F
+:10F5B0009623000E00431021AF6200588F62005066
+:10F5C00000441021AF62005C8E220004AF6200187C
+:10F5D0008E220008AF62001C8FA20010304200088B
+:10F5E0005440000A93A20020A360003693620036C4
+:10F5F0002403FFDFA36200359362003E0043102422
+:10F60000A362003E0A0014988E220008A36200350F
+:10F610008E220008AF62004C8F6200248F6300408E
+:10F6200000431021AF6200489362000024030050A1
+:10F63000304200FF144300122403FF803C02080004
+:10F640008C4231A00242102100431024AF42002816
+:10F650003C0208008C4231A08E2400083C03000CC0
+:10F66000024210213042007F03421021004310214A
+:10F67000AC4400D88E230008AF820014AC4300DCF9
+:10F680000E00130B02402021240400380000282122
+:10F690002406000A0E0013C9000000002404000123
+:10F6A0008FBF00348FB200308FB1002C8FB0002894
+:10F6B0000080102103E0000827BD003827BDFFF8B7
+:10F6C00027420180AFA20000308A00FF8F4201B8BC
+:10F6D0000440FFFE000000008F4601283C020800A5
+:10F6E0008C4231A02403FF80AF86004800C2102165
+:10F6F00000431024AF4200243C0208008C4231A099
+:10F700008FA900008FA8000000C210213042007FA6
+:10F71000034218213C02000A00621821946400D4BC
+:10F720008FA700008FA5000024020002AF83001401
+:10F73000A0A2000B8FA30000354260003084FFFFC1
+:10F74000A4E200083C021000AD260000AD04000455
+:10F75000AC60002427BD0008AF4201B803E00008F8
+:10F76000240200018F88003C938200288F830014BC
+:10F770003C07080024E7777800481023304200FF58
+:10F78000304900FC246500888F860040304A000321
+:10F790001120000900002021248200048CA3000015
+:10F7A000304400FF0089102AACE3000024A50004C7
+:10F7B0001440FFF924E70004114000090000202153
+:10F7C0002482000190A30000304400FF008A102B27
+:10F7D000A0E3000024A500011440FFF924E7000184
+:10F7E00030C20003144000048F85003C3102000346
+:10F7F0001040000D0000000010A0000900002021B2
+:10F800002482000190C30000304400FF0085102BCB
+:10F81000A0E3000024C600011440FFF924E7000122
+:10F8200003E00008000000001100FFFD000020219F
+:10F83000248200048CC30000304400FF0088102B99
+:10F84000ACE3000024C600041440FFF924E70004E0
+:10F8500003E00008000000008F83003C9382002832
+:10F8600030C600FF30A500FF00431023304300FFE7
+:10F870008F820014008038210043102114C0000240
+:10F88000244800880083382130E20003144000053A
+:10F8900030A2000314400003306200031040000D4A
+:10F8A0000000000010A000090000202124820001B7
+:10F8B00090E30000304400FF0085102BA1030000FE
+:10F8C00024E700011440FFF92508000103E00008C7
+:10F8D0000000000010A0FFFD000020212482000491
+:10F8E0008CE30000304400FF0085102BAD030000C6
+:10F8F00024E700041440FFF92508000403E0000891
+:10F90000000000000080482130AAFFFF30C600FF41
+:10F9100030E7FFFF274801808F4201B80440FFFE17
+:10F920008F820048AD0200008F420124AD02000426
+:10F930008D220020A5070008A102000A240200165B
+:10F94000A102000B934301208D2200088D240004A6
+:10F95000306300FF004310219783003A00441021D8
+:10F960008D250024004310233C0308008C6331A044
+:10F970008F840014A502000C246300E82402FFFF1A
+:10F98000A50A000EA5030010A5060012AD0500187B
+:10F99000AD020024948201142403FFF73042FFFFDC
+:10F9A000AD0200288C820118AD02002C3C02100030
+:10F9B000AD000030AF4201B88D220020004310247A
+:10F9C00003E00008AD2200208F82001430E7FFFF23
+:10F9D00000804821904200D330A5FFFF30C600FFD1
+:10F9E0000002110030420F0000E238252748018054
+:10F9F0008F4201B80440FFFE8F820048AD02000034
+:10FA00008F420124AD0200048D220020A5070008CA
+:10FA1000A102000A24020017A102000B9343012057
+:10FA20008D2200088D240004306300FF0043102164
+:10FA30009783003A004410218F8400140043102360
+:10FA40003C0308008C6331A0A502000CA505000E44
+:10FA5000246300E8A5030010A5060012AD00001401
+:10FA60008D220024AD0200188C82005CAD02001CC7
+:10FA70008C820058AD0200202402FFFFAD0200245A
+:10FA8000948200E63042FFFFAD02002894820060BD
+:10FA9000948300BE30427FFF3063FFFF00021200FC
+:10FAA00000431021AD02002C3C021000AD000030DC
+:10FAB000AF4201B8948200BE2403FFF700A21021D8
+:10FAC000A48200BE8D2200200043102403E0000821
+:10FAD000AD220020274301808F4201B80440FFFE81
+:10FAE0008F8200249442001C3042FFFF000211C0AC
+:10FAF000AC62000024020019A062000B3C0210005E
+:10FB0000AC60003003E00008AF4201B88F87002CE2
+:10FB100030C300FF8F4201B80440FFFE8F820048CF
+:10FB200034636000ACA2000093820044A0A20005F0
+:10FB30008CE20010A4A20006A4A300088C8200207E
+:10FB40002403FFF7A0A2000A24020002A0A2000BD7
+:10FB50008CE20000ACA200108CE20004ACA2001405
+:10FB60008CE2001CACA200248CE20020ACA2002895
+:10FB70008CE2002CACA2002C8C820024ACA20018D9
+:10FB80003C021000AF4201B88C82002000431024D8
+:10FB900003E00008AC8200208F86001427BDFFE838
+:10FBA000AFBF0014AFB0001090C20063304200201D
+:10FBB0001040000830A500FF8CC2007C2403FFDF4A
+:10FBC00024420001ACC2007C90C2006300431024B8
+:10FBD000A0C2006310A000238F830014275001806F
+:10FBE000020028210E0015D6240600828F82001400
+:10FBF000904200633042004050400019A38000440E
+:10FC00008F83002C8F4201B80440FFFE8F82004892
+:10FC1000AE02000024026082A60200082402000254
+:10FC2000A202000B8C620008AE0200108C62000C75
+:10FC3000AE0200148C620014AE0200188C62001830
+:10FC4000AE0200248C620024AE0200288C620028E0
+:10FC5000AE02002C3C021000AF4201B8A380004469
+:10FC60008F8300148FBF00148FB000109062006368
+:10FC700027BD00183042007FA06200639782003ADF
+:10FC80008F86003C8F850014938300280046102344
+:10FC9000A782003AA4A000E490A400638F820040F1
+:10FCA000AF83003C2403FFBF0046102100832024C3
+:10FCB000AF820040A0A400638F820014A04000BD6A
+:10FCC0008F82001403E00008A44000BE8F8A001455
+:10FCD00027BDFFE0AFB10014AFB000108F88003C2B
+:10FCE000AFBF00189389001C954200E430D100FF9B
+:10FCF0000109182B0080802130AC00FF3047FFFF46
+:10FD00000000582114600003310600FF012030215B
+:10FD1000010958239783003A0068102B1440003CD7
+:10FD20000000000014680007240200018E02002079
+:10FD30002403FFFB34E7800000431024AE020020C0
+:10FD40002402000134E70880158200053165FFFFB9
+:10FD50000E001554020020210A00169102002021F5
+:10FD60000E001585020020218F8400482743018062
+:10FD70008F4201B80440FFFE24020018AC6400006A
+:10FD8000A062000B8F840014948200E6A46200102D
+:10FD90003C021000AC600030AF4201B894820060B9
+:10FDA00024420001A4820060948200603C030800A9
+:10FDB0008C63318830427FFF5443000F02002021C2
+:10FDC000948200602403800000431024A482006019
+:10FDD0009082006090830060304200FF000211C2F8
+:10FDE00000021027000211C03063007F0062182556
+:10FDF000A083006002002021022028218FBF00186C
+:10FE00008FB100148FB000100A0015F927BD002033
+:10FE1000914200632403FF8000431025A142006348
+:10FE20009782003A3048FFFF110000209383001CA6
+:10FE30008F840014004B1023304600FF948300E4AD
+:10FE40002402EFFF0168282B00621824A48300E439
+:10FE500014A000038E020020010058210000302170
+:10FE60002403FFFB34E7800000431024AE0200208F
+:10FE700024020001158200053165FFFF0E001554B4
+:10FE8000020020210A0016B99783003A0E0015855A
+:10FE9000020020219783003A8F82003CA780003A1D
+:10FEA00000431023AF82003C9383001C8F82001418
+:10FEB0008FBF00188FB100148FB0001027BD002035
+:10FEC00003E00008A04300BD938200442403000126
+:10FED00027BDFFE8004330042C420020AFB00010E3
+:10FEE000AFBF00142410FFFE10400005274501801D
+:10FEF0003C0208008C4231900A0016D600461024BD
+:10FF00003C0208008C423194004610241440000743
+:10FF1000240600848F8300142410FFFF9062006287
+:10FF20003042000F34420040A06200620E0015D63D
+:10FF300000000000020010218FBF00148FB00010DD
+:10FF400003E0000827BD00188F83002427BDFFE0D1
+:10FF5000AFB20018AFB10014AFB00010AFBF001CBB
+:10FF60009062000D00A0902130D100FF3042007F50
+:10FF7000A062000D8F8500148E4300180080802140
+:10FF80008CA2007C146200052402000E90A2006383
+:10FF9000344200200A0016FFA0A200630E0016C51E
+:10FFA000A38200442403FFFF104300472404FFFF03
+:10FFB00052200045000020218E4300003C0200102A
+:10FFC00000621024504000043C020008020020217E
+:10FFD0000A00170E24020015006210245040000988
+:10FFE0008E45000002002021240200140E0016C5D8
+:10FFF000A38200442403FFFF104300332404FFFFC7
:020000040001F9
-:10000000104000163C0200048F8600248CC20014AD
-:100010008CC300108CC40014004310230044102B28
-:1000200050400005020020218E43002C8CC200109D
-:1000300010620003020020210A00173F2402001270
-:100040003C02000400A210245040001C00002021AB
-:10005000020020210A00173F2402001300A21024EE
-:10006000104000068F8300248C6200105040001363
-:10007000000020210A001739020020218C620010A4
-:10008000504000048E42002C020020210A00173F3D
-:10009000240200115040000900002021020020210C
-:1000A000240200170E0016C5A38200442403FFFF9C
-:1000B000104300022404FFFF000020218FBF001C1A
-:1000C0008FB200188FB100148FB000100080102183
-:1000D00003E0000827BD00208F83001427BDFFD850
-:1000E000AFB40020AFB3001CAFB20018AFB1001422
-:1000F000AFB00010AFBF0024906200638F91002C5E
-:100100002412FFFF3442004092250000A0620063E9
-:100110008E2200100080982130B0003F105200065F
-:100120000360A0212402000D0E0016C5A382004426
-:10013000105200542404FFFF8F8300148E220018F5
-:100140008C63007C10430007026020212402000E13
-:100150000E0016C5A38200442403FFFF104300498C
-:100160002404FFFF24040020120400048F830014E1
-:100170009062006334420020A06200638F850034E7
-:1001800010A0002000000000560400048F8200141C
-:10019000026020210A0017902402000A9683000AB8
-:1001A000944200603042FFFF144300048F8200201D
-:1001B0002404FFFD0A0017B7AF82003C3C02080090
-:1001C0008C42318C0045102B144000060260202127
-:1001D000000028210E001646240600010A0017B769
-:1001E000000020212402002D0E0016C5A382004429
-:1001F0002403FFFF104300232404FFFF0A0017B766
-:1002000000002021160400058F8400148E230014A2
-:100210002402FFFF506200180260202194820060D7
-:1002200024420001A4820060948200603C03080024
-:100230008C63318830427FFF5443000F02602021DD
-:10024000948200602403800000431024A482006094
-:100250009082006090830060304200FF000211C273
-:1002600000021027000211C03063007F00621825D1
-:10027000A0830060026020210E0015F92405000112
-:10028000000020218FBF00248FB400208FB3001CFA
-:100290008FB200188FB100148FB0001000801021B1
-:1002A00003E0000827BD00288F83001427BDFFE866
-:1002B000AFB00010AFBF0014906200638F87002CB6
-:1002C00000808021344200408CE60010A062006370
-:1002D0003C0308008C6331B030C23FFF0043102B59
-:1002E0001040004E8F8500302402FF8090A3000D47
-:1002F00000431024304200FF5040004902002021FA
-:100300000006138230480003240200025502004414
-:100310000200202194A2001C8F85001424030023D6
-:10032000A4A201148CE60000000616023042003F31
-:10033000104300103C0300838CE300188CA2007C67
-:10034000106200062402000E0E0016C5A3820044AF
-:100350002403FFFF104300382404FFFF8F830014A1
-:100360009062006334420020A06200630A0017FC20
-:100370008F83002400C31024144300078F830024BC
-:1003800090A200623042000F34420020A0A200621E
-:10039000A38800388F8300249062000D3042007FD4
-:1003A000A062000D8F83003410600018020020212D
-:1003B0008F8400308C8200100043102B1040000905
-:1003C00024020018020020210E0016C5A38200445A
-:1003D0002403FFFF104300182404FFFF0A00182421
-:1003E000000020218C820010240500010200202141
-:1003F000004310238F830024240600010E001646BC
-:10040000AC6200100A001824000020210E0015F92B
-:10041000240500010A0018240000202102002021E8
-:100420002402000D8FBF00148FB0001027BD0018EC
-:100430000A0016C5A38200448FBF00148FB00010BD
-:100440000080102103E0000827BD001827BDFFC869
-:10045000AFB20020AFBF0034AFB60030AFB5002C54
-:10046000AFB40028AFB30024AFB1001CAFB0001888
-:100470008F4601283C0308008C6331A02402FF80D2
-:10048000AF86004800C318213065007F034528214E
-:10049000006218243C02000AAF43002400A2282175
-:1004A00090A2006200809021AF850014304200FFCE
-:1004B00000021102A382003890A200BC3042000268
-:1004C0001440000224030034240300308F820014FF
-:1004D000A3830028938300388C4200C0A38000448B
-:1004E000AF82003C24020004106203148F84003C9D
-:1004F0008E440004508003118F84003C8E42001013
-:100500003083FFFFA784003A106002F7AF820040FB
-:100510008F8400142403FF80908200630062102403
-:10052000304200FF144002C79785003A9383003899
-:100530002402000230B6FFFF14620005000088218B
-:10054000938200282403FFFD0A001B11AF82003CA8
-:100550008F82003C02C2102B144002998F8400400D
-:100560000E0014EC00000000938300283C040800F7
-:1005700024847778240200341462002EAF84002C87
-:100580003C0A08008D4A77A82402FFFFAFA20010A2
-:10059000008038212405002F3C09080025297378A4
-:1005A000240800FF2406FFFF90E2000024A3FFFFC1
-:1005B0000006220200C21026304200FF0002108016
-:1005C000004910218C420000306500FF24E7000143
-:1005D00014A8FFF50082302600061027AFA20014F1
-:1005E000AFA200100000282127A7001027A60014A2
-:1005F00000C510239044000324A2000100A7182185
-:10060000304500FF2CA200041440FFF9A064000054
-:100610008FA2001011420007240200050240202191
-:100620000E0016C5A38200442403FFFF104300649C
-:100630002404FFFF3C0208009042777C1040000930
-:100640008F820014024020212402000C0E0016C5E7
-:10065000A38200442403FFFF104300592404FFFF3A
-:100660008F820014A380001C3C0308008C63777CFD
-:100670008C4400803C0200FF3442FFFF00621824DB
-:100680000083202B10800008AF830034024020211B
-:10069000240200190E0016C5A38200442403FFFFA4
-:1006A000104300472404FFFF8F87003C9782003AE5
-:1006B0008F850034AF8700200047202310A0003B27
-:1006C000A784003A8F86001430A200030002102392
-:1006D00090C300BC3050000300B0282100031882F2
-:1006E000307300010013108000A228213C03080091
-:1006F0008C6331A08F8200483084FFFF0085202B5F
-:100700000043102110800011244200888F84002CA7
-:100710001082000E3C033F013C0208008C427778B7
-:10072000004310243C0325001443000630E500FF7D
-:100730008C820000ACC200888C8200100A0018E98C
-:10074000ACC200980E001529000030219382001CD5
-:100750008F8500148F830040020238218F82003C75
-:10076000A387001C94A400E4006218218F82003447
-:1007700034841000AF83004000503021A4A400E472
-:100780001260000EAF86003C24E20004A382001C2D
-:1007900094A200E424C30004AF83003C3442200050
-:1007A000A4A200E40A001906000020218F82004064
-:1007B000AF80003C00471021AF82004000002021A4
-:1007C0002414FFFF109402092403FFFF3C080800D3
-:1007D0008D0877883C0208008C4231B03C03080049
-:1007E0009063777831043FFF0082102B1040001B8C
-:1007F0003067003F3C0208008C4231A88F830048DC
-:100800000004218000621821006418213062007FFA
-:10081000034228213C02000C00A228213C02008057
-:10082000344200013066007800C230252402FF8087
-:1008300000621024AF42002830640007AF42080471
-:100840008F8200140344202124840940AF460814F9
-:10085000AF850024AF840030AC4301189383003887
-:1008600024020003146201C72402000124020026AE
-:1008700010E201C928E200271040001324020032D0
-:100880002402002210E201C428E2002310400008E4
-:10089000240200242402002010E201B024020021DE
-:1008A00010E2013F024020210A001AF32402000B4B
-:1008B00010E201B92402002510E2001002402021BC
-:1008C0000A001AF32402000B10E201A628E200330A
-:1008D000104000062402003F2402003110E2009282
-:1008E000024020210A001AF32402000B10E2019DAD
-:1008F000024020210A001AF32402000B8F90002CE2
-:100900003C0308008C6331B08F8500308E040010EA
-:100910000000A8218CB3001430823FFF0043102B4D
-:100920008CB10020504001870240202190A3000D8F
-:100930002402FF8000431024304200FF5040018118
-:100940000240202100041382304200031440017D44
-:100950000240202194A3001C8F8200148E040028E2
-:10096000A44301148CA20010026218231064000337
-:10097000024020210A00197C2402001F8F820034CB
-:10098000006210210262102B104000088F830024A7
-:1009900002402021240200180E0016C5A382004444
-:1009A0001054016C2404FFFF8F8300248F840034D3
-:1009B0008C6200100224882100441023AC620010D5
-:1009C0008F820014AC7100208C4200680051102B03
-:1009D000104000098F830030024020212402001DB6
-:1009E0000E0016C5A38200442403FFFF10430159E3
-:1009F0002404FFFF8F8300308E0200248C630024C8
-:100A000010430007024020212402001C0E0016C5DE
-:100A1000A38200442403FFFF1043014E2404FFFF80
-:100A20008F8400248C82002424420001AC820024A4
-:100A3000123300048F8200148C4200685622000E8C
-:100A40008E0200008E0200003C0300800043102450
-:100A50001440000D2402001A024020210E0016C589
-:100A6000A38200442403FFFF1043013A2404FFFF44
-:100A70000A0019BA8E0200143C03008000431024BF
-:100A8000504000038E020014AC8000208E0200143F
-:100A90002411FFFF105100062402001B02402021F8
-:100AA0000E0016C5A38200441051012A2404FFFF42
-:100AB0008E0300003C02000100621024104000126E
-:100AC0003C020080006210241440000802402021F3
-:100AD0002402001A0E0016C5A38200442403FFFF5F
-:100AE0001043011C2404FFFF0240202102002821A2
-:100AF0000E0016E5240600012403FFFF1043011534
-:100B00002404FFFF241500018F83002402A030215C
-:100B10000240202194620036240500012442000195
-:100B20000A001AD7A46200368F90002C3C030800FC
-:100B30008C6331B08E13001032623FFF0043102BE4
-:100B4000104000898F8400302402FF809083000DC4
-:100B500000431024304200FF104000842402000DA6
-:100B60000013138230420003240300011443007F6A
-:100B70002402000D9082000D304200085440000411
-:100B80008F820034024020210A001A082402002427
-:100B9000504000048E03000C024020210A001A0875
-:100BA000240200278C82002054620006024020218B
-:100BB0008E0300088C820024506200098E0200140B
-:100BC00002402021240200200E0016C5A38200440A
-:100BD000105400712403FFFF0A001A3D8F84002483
-:100BE0002411FFFF145100048F86001402402021BD
-:100BF0000A001A38240200258E0300188CC2007CDB
-:100C0000106200032402000E0A001A38024020215C
-:100C10008E0300248C82002810620003240200212D
-:100C20000A001A38024020218E0500288C82002CF0
-:100C300010A200032402001F0A001A3802402021DB
-:100C40008E03002C14600003240200230A001A38CB
-:100C5000024020218CC200680043102B104000038A
-:100C6000240200260A001A38024020218C82001437
-:100C7000006518210043102B104000088F840024C9
-:100C800002402021240200220E0016C5A382004447
-:100C9000105100412403FFFF8F8400242403FFF739
-:100CA0009082000D00431024A082000D8F86001456
-:100CB0003C0308008C6331AC8F82004894C400E090
-:100CC0008F8500240043102130847FFF00042040E2
-:100CD000004410213043007F034320213C03000ED9
-:100CE000008320212403FF8000431024AF42002C06
-:100CF000A49300008CA2002824420001ACA200288A
-:100D00008CA2002C8E03002C00431021ACA2002CDE
-:100D10008E02002CACA200308E020014ACA2003473
-:100D200094A2003A24420001A4A2003A94C600E032
-:100D30003C0208008C4231B024C4000130837FFFA4
-:100D40001462000F008030212402800000823024D1
-:100D500030C2FFFF000213C2304200FF0002102722
-:100D60000A001A76000233C02402000D024020213E
-:100D70000E0016C5A38200440A001A7C0040182108
-:100D80008F82001402402021240500010E0015F975
-:100D9000A44600E0000018210A001B0E0060882114
-:100DA0008F90002C3C0308008C6331B08E0500103E
-:100DB00030A23FFF0043102B104000612402FF804F
-:100DC0008F8400309083000D00431024304200FFD8
-:100DD0005040005C024020218F8200341040000B04
-:100DE000000513828F8200149763000A944200600A
-:100DF0003042FFFF14430005000513828F8200205C
-:100E00002404FFFD0A001AEBAF82003C30420003CD
-:100E10001440000E00000000920200021040000585
-:100E20008E03002450600015920300030A001AA7E5
-:100E3000024020218C8200245062001092030003A3
-:100E4000024020210A001AAF2402000F9082000DF8
-:100E50003042000854400009920300030240202160
-:100E6000240200100E0016C5A38200442403FFFFD5
-:100E7000104300382404FFFF920300032402000201
-:100E80005462000C920200038F8200345440000927
-:100E900092020003024020212402002C0E0016C5FD
-:100EA000A38200442403FFFF1043002A2404FFFF11
-:100EB000920200030200282102402021384600103F
-:100EC0002CC600012C4200010E0016E5004630251C
-:100ED0002410FFFF1050001F2404FFFF8F830034F5
-:100EE00010600013024020213C0208008C42318C2B
-:100EF0000043102B144000070000000000002821D0
-:100F0000240600010E001646000000000A001AEB3D
-:100F1000000020212402002D0E0016C5A3820044EB
-:100F20001050000C2404FFFF0A001AEB00002021DF
-:100F30000E0015F9240500010A001AEB000020211B
-:100F4000024020212402000D0E0016C5A382004499
-:100F5000004020210A001B0E008088211514000E7D
-:100F6000000000000E00174C024020210A001B0E5A
-:100F7000004088210E0016C5A38200440A001B0E03
-:100F80000040882114620017022018212402002347
-:100F900014E200052402000B0E0017C002402021BD
-:100FA0000A001B0E0040882102402021A382004439
-:100FB0000E0016C52411FFFF0A001B0F0220182186
-:100FC00030A500FF0E001529240600019783003A82
-:100FD0008F82003CA780003A00431023AF82003C80
-:100FE000022018211220003E9782003A2402FFFDC1
-:100FF0005462003E8E4300208E4200048F83001412
-:1010000000561023AE420004906200633042007F1D
-:10101000A06200638E4200208F840014A780003AF3
-:1010200034420002AE420020A48000E490820063BB
-:101030002403FFBF00431024A08200630A001B5159
-:101040008E4300209082006300621024304200FF33
-:10105000104000239782003A90820088908300BD60
-:10106000248500883042003F2444FFE02C82002089
-:10107000A383001C10400019AF85002C240200013E
-:1010800000821804306200191440000C3C028000F9
-:1010900034420002006210241440000B3062002031
-:1010A0001040000F9782003A90A6000102402021D4
-:1010B000240500010A001B4B30C60001024020211C
-:1010C0000A001B4A240500010240202100002821BB
-:1010D000240600010E001646000000009782003A28
-:1010E0001440FD0C8F8400148E43002030620004F5
-:1010F000104000128F84003C2402FFFB0062102489
-:10110000AE420020274301808F4201B80440FFFE19
-:101110008F820048AC6200008F420124AC62000460
-:1011200024026083A462000824020002A062000B73
-:101130003C021000AF4201B88F84003C8F83001442
-:101140008FBF00348FB600308FB5002C8FB40028CD
-:101150008FB300248FB200208FB1001C8FB0001815
-:101160002402000127BD003803E00008AC6400C081
-:1011700030A500FF2403000124A900010069102B01
-:101180001040000C00004021240A000100A310239D
-:10119000004A380424630001308200010069302BCA
-:1011A00010400002000420420107402554C0FFF80F
-:1011B00000A3102303E00008010010213C020800F6
-:1011C000244260A43C010800AC22736C3C0208007D
-:1011D000244253083C010800AC227370240200062C
-:1011E00027BDFFE03C010800A02273743C021EDC16
-:1011F000AFB20018AFB10014AFBF001CAFB0001009
-:1012000034526F4100008821240500080E001B7233
-:1012100002202021001180803C07080024E7737819
-:101220000002160002071821AC620000000028210D
-:1012300024A200013045FFFF8C6200002CA60008AC
-:1012400004410002000220400092202614C0FFF852
-:10125000AC640000020780218E0400000E001B72A7
-:1012600024050020262300013071FFFF2E230100FA
-:101270001460FFE5AE0200008FBF001C8FB20018A3
-:101280008FB100148FB0001003E0000827BD0020CC
-:1012900027BDFFD8AFB3001CAFB20018AFBF00200E
-:1012A000AFB10014AFB000108F5101408F4801481A
-:1012B00000089402324300FF311300FF8F4201B84F
-:1012C0000440FFFE27500180AE1100008F42014410
-:1012D000AE02000424020002A6120008A202000BC3
-:1012E00024020014AE1300241062002528620015A9
-:1012F0001040000824020015240200101062003083
-:1013000024020012106200098FBF00200A001CADE9
-:101310008FB3001C1062007024020022106200379C
-:101320008FBF00200A001CAD8FB3001C3C020800D8
-:101330008C4231A02403FF8002221021004310249C
-:10134000AF4200243C0208008C4231A0022210214E
-:101350003042007F034218213C02000A006218213B
-:10136000166000BCAF830014906200623042000F30
-:1013700034420030A06200620A001CAC8FBF002023
-:101380003C0460008C832C083C02F0033442FFFFD5
-:1013900000621824AC832C083C0208008C4231A067
-:1013A0008C832C08244200740002108200021480F6
-:1013B00000621825AC832C080A001CAC8FBF0020EB
-:1013C0003C0208008C4231A02403FF80022210213D
-:1013D00000431024AF4200243C0208008C4231A09C
-:1013E0003C03000A022210213042007F03421021F8
-:1013F000004310210A001CABAF8200143C0208001D
-:101400008C4231A02405FF800222102100451024C7
-:10141000AF4200243C0208008C4231A0022210217D
-:101420003042007F034218213C02000A006218216A
-:101430009062006300A21024304200FF104000853B
-:10144000AF83001424620088944300123C02080019
-:101450008C4231A830633FFF000319800222102123
-:10146000004310213043007F034320210045102416
-:101470003C03000C00832021AF4200289082000D25
-:1014800000A21024304200FF10400072AF840024FC
-:101490009082000D304200101440006F8FBF00207A
-:1014A0000E0015C8000000008F4201B80440FFFE86
-:1014B00000000000AE1100008F420144AE020004A3
-:1014C00024020002A6120008A202000BAE130024A0
-:1014D0000A001CAC8FBF00202406FF8002261024C7
-:1014E000AF4200203C0208008C4231A031043FFF93
-:1014F000000421800222102100461024AF42002463
-:101500003C0308008C6331A83C0208008C4231A0E7
-:101510003227007F022318210222102100641821A3
-:101520003042007F3064007F034228213C02000AE1
-:101530000066182400A22821034420213C02000C4C
-:1015400000822021AF4300283C02000803471821F5
-:1015500000629021AF850014AF8400240E0015C8EE
-:10156000010080218F4201B80440FFFE8F820024D9
-:101570008F840014274501809042000DACB100001B
-:10158000A4B0000600021600000216030002102795
-:10159000000237C214C00016248200889442001250
-:1015A00032033FFF30423FFF1443001224026082A7
-:1015B000908300632402FF8000431024304200FF28
-:1015C0005040000C24026082908200623042000F82
-:1015D00034420040A082006224026084A4A2000879
-:1015E0002402000DA0A200050A001C963C02270060
-:1015F00024026082A4A20008A0A000053C022700EB
-:1016000000061C000062182524020002A0A2000BA4
-:10161000ACA30010ACA00014ACA00024ACA0002827
-:10162000ACA0002C8E42004C8F840024ACA2001889
-:101630009083000D2402FF8000431024304200FFFD
-:10164000104000058FBF00209082000D3042007FC7
-:10165000A082000D8FBF00208FB3001C8FB2001836
-:101660008FB100148FB000103C02100027BD00287D
-:0816700003E00008AF4201B8DD
-:08167800080034300800343092
-:10168000080033A8080033E0080034140800343898
-:0C16900008003438080034380800331813
-:04169C000A0001241B
-:1016A00000000000000000000000000D74706136B2
-:1016B0002E302E313500000006000F010000000022
-:1016C000000000000000000000000000000000001A
+:100000008E4500003C02000200A2102410400016A1
+:100010003C0200048F8600248CC200148CC30010A4
+:100020008CC40014004310230044102B50400005E2
+:10003000020020218E43002C8CC2001010620003AD
+:10004000020020210A00173F240200123C02000493
+:1000500000A210245040001C00002021020020219A
+:100060000A00173F2402001300A2102410400006CB
+:100070008F8300248C620010504000130000202168
+:100080000A001739020020218C6200105040000441
+:100090008E42002C020020210A00173F240200118A
+:1000A00050400009000020210200202124020017F6
+:1000B0000E0016C5A38200442403FFFF1043000274
+:1000C0002404FFFF000020218FBF001C8FB2001806
+:1000D0008FB100148FB000100080102103E00008E1
+:1000E00027BD00208F83001427BDFFD8AFB40020A8
+:1000F000AFB3001CAFB20018AFB10014AFB0001026
+:10010000AFBF0024906200638F91002C2412FFFF88
+:100110003442004092250000A06200638E2200104D
+:100120000080982130B0003F105200060360A021EB
+:100130002402000D0E0016C5A38200441052005484
+:100140002404FFFF8F8300148E2200188C63007C30
+:1001500010430007026020212402000E0E0016C585
+:10016000A38200442403FFFF104300492404FFFF3F
+:1001700024040020120400048F83001490620063A2
+:1001800034420020A06200638F85003410A000205C
+:1001900000000000560400048F8200140260202139
+:1001A0000A0017902402000A9683000A9442006015
+:1001B0003042FFFF144300048F8200202404FFFD1F
+:1001C0000A0017B7AF82003C3C0208008C42318C19
+:1001D0000045102B14400006026020210000282159
+:1001E0000E001646240600010A0017B70000202161
+:1001F0002402002D0E0016C5A38200442403FFFF35
+:10020000104300232404FFFF0A0017B70000202139
+:10021000160400058F8400148E2300142402FFFFAF
+:100220005062001802602021948200602442000184
+:10023000A4820060948200603C0308008C633188D3
+:1002400030427FFF5443000F0260202194820060FF
+:100250002403800000431024A48200609082006088
+:1002600090830060304200FF000211C2000210279C
+:10027000000211C03063007F00621825A083006077
+:10028000026020210E0015F9240500010000202144
+:100290008FBF00248FB400208FB3001C8FB20018D2
+:1002A0008FB100148FB000100080102103E000080F
+:1002B00027BD00288F83001427BDFFE8AFB00010D2
+:1002C000AFBF0014906200638F87002C00808021F4
+:1002D000344200408CE60010A06200633C0308003A
+:1002E0008C6331B030C23FFF0043102B1040004EF2
+:1002F0008F8500302402FF8090A3000D004310245E
+:10030000304200FF504000490200202100061382C5
+:10031000304800032402000255020044020020215C
+:1003200094A2001C8F85001424030023A4A20114AE
+:100330008CE60000000616023042003F1043001019
+:100340003C0300838CE300188CA2007C1062000642
+:100350002402000E0E0016C5A38200442403FFFFF2
+:10036000104300382404FFFF8F8300149062006361
+:1003700034420020A06200630A0017FC8F8300242F
+:1003800000C31024144300078F83002490A200624E
+:100390003042000F34420020A0A20062A38800383F
+:1003A0008F8300249062000D3042007FA062000D18
+:1003B0008F83003410600018020020218F840030E9
+:1003C0008C8200100043102B1040000924020018FA
+:1003D000020020210E0016C5A38200442403FFFF63
+:1003E000104300182404FFFF0A00182400002021F5
+:1003F0008C820010240500010200202100431023FC
+:100400008F830024240600010E001646AC62001003
+:100410000A001824000020210E0015F9240500010F
+:100420000A00182400002021020020212402000DCF
+:100430008FBF00148FB0001027BD00180A0016C52A
+:10044000A38200448FBF00148FB0001000801021E1
+:1004500003E0000827BD001827BDFFC8AFB2002089
+:10046000AFBF0034AFB60030AFB5002CAFB400283A
+:10047000AFB30024AFB1001CAFB000188F46012805
+:100480003C0308008C6331A02402FF80AF86004843
+:1004900000C318213065007F03452821006218241D
+:1004A0003C02000AAF43002400A2282190A200626F
+:1004B00000809021AF850014304200FF000211023D
+:1004C000A382003890A200BC304200021440000217
+:1004D00024030034240300308F820014A3830028F7
+:1004E000938300388C4200C0A3800044AF82003C5C
+:1004F00024020004106203148F84003C8E44000424
+:10050000508003118F84003C8E4200103083FFFF27
+:10051000A784003A106002F7AF8200408F84001475
+:100520002403FF809082006300621024304200FFA9
+:10053000144002C79785003A9383003824020002D2
+:1005400030B6FFFF14620005000088219382002866
+:100550002403FFFD0A001B11AF82003C8F82003C88
+:1005600002C2102B144002998F8400400E0014EC3C
+:1005700000000000938300283C040800248477785E
+:10058000240200341462002EAF84002C3C0A0800C0
+:100590008D4A77A82402FFFFAFA200100080382107
+:1005A0002405002F3C09080025297378240800FF42
+:1005B0002406FFFF90E2000024A3FFFF00062202B2
+:1005C00000C21026304200FF0002108000491021B6
+:1005D0008C420000306500FF24E7000114A8FFF5FD
+:1005E0000082302600061027AFA20014AFA2001030
+:1005F0000000282127A7001027A6001400C51023FB
+:100600009044000324A2000100A71821304500FFF8
+:100610002CA200041440FFF9A06400008FA2001077
+:100620001142000724020005024020210E0016C5D9
+:10063000A38200442403FFFF104300642404FFFF4F
+:100640003C0208009042777C104000098F82001421
+:10065000024020212402000C0E0016C5A382004493
+:100660002403FFFF104300592404FFFF8F8200146E
+:10067000A380001C3C0308008C63777C8C440080C2
+:100680003C0200FF3442FFFF006218240083202B4D
+:1006900010800008AF83003402402021240200199A
+:1006A0000E0016C5A38200442403FFFF1043004739
+:1006B0002404FFFF8F87003C9782003A8F85003427
+:1006C000AF8700200047202310A0003BA784003AFA
+:1006D0008F86001430A200030002102390C300BCD8
+:1006E0003050000300B0282100031882307300014D
+:1006F0000013108000A228213C0308008C6331A065
+:100700008F8200483084FFFF0085202B004310219A
+:1007100010800011244200888F84002C1082000E6B
+:100720003C033F013C0208008C42777800431024D0
+:100730003C0325001443000630E500FF8C820000D6
+:10074000ACC200888C8200100A0018E9ACC2009884
+:100750000E001529000030219382001C8F850014A3
+:100760008F830040020238218F82003CA387001C47
+:1007700094A400E4006218218F82003434841000B5
+:10078000AF83004000503021A4A400E41260000EAA
+:10079000AF86003C24E20004A382001C94A200E483
+:1007A00024C30004AF83003C34422000A4A200E430
+:1007B0000A001906000020218F820040AF80003C13
+:1007C00000471021AF820040000020212414FFFFC9
+:1007D000109402092403FFFF3C0808008D08778865
+:1007E0003C0208008C4231B03C03080090637778EB
+:1007F00031043FFF0082102B1040001B3067003F88
+:100800003C0208008C4231A88F83004800042180FC
+:1008100000621821006418213062007F0342282101
+:100820003C02000C00A228213C020080344200015E
+:100830003066007800C230252402FF800062102458
+:10084000AF42002830640007AF4208048F820014D2
+:100850000344202124840940AF460814AF850024B6
+:10086000AF840030AC4301189383003824020003A6
+:10087000146201C7240200012402002610E201C90B
+:1008800028E2002710400013240200322402002234
+:1008900010E201C428E200231040000824020024D2
+:1008A0002402002010E201B02402002110E2013FE6
+:1008B000024020210A001AF32402000B10E201B9C1
+:1008C0002402002510E20010024020210A001AF341
+:1008D0002402000B10E201A628E2003310400006BB
+:1008E0002402003F2402003110E200920240202145
+:1008F0000A001AF32402000B10E2019D024020219D
+:100900000A001AF32402000B8F90002C3C0308000D
+:100910008C6331B08F8500308E0400100000A82158
+:100920008CB3001430823FFF0043102B8CB10020A9
+:10093000504001870240202190A3000D2402FF8037
+:1009400000431024304200FF50400181024020212A
+:1009500000041382304200031440017D0240202134
+:1009600094A3001C8F8200148E040028A443011459
+:100970008CA20010026218231064000302402021A0
+:100980000A00197C2402001F8F82003400621021AB
+:100990000262102B104000088F83002402402021A7
+:1009A000240200180E0016C5A38200441054016CE6
+:1009B0002404FFFF8F8300248F8400348C62001096
+:1009C0000224882100441023AC6200108F8200149E
+:1009D000AC7100208C4200680051102B10400009BF
+:1009E0008F830030024020212402001D0E0016C516
+:1009F000A38200442403FFFF104301592404FFFF96
+:100A00008F8300308E0200248C6300241043000783
+:100A1000024020212402001C0E0016C5A3820044BF
+:100A20002403FFFF1043014E2404FFFF8F840024A2
+:100A30008C82002424420001AC8200241233000482
+:100A40008F8200148C4200685622000E8E02000035
+:100A50008E0200003C030080004310241440000D6F
+:100A60002402001A024020210E0016C5A382004471
+:100A70002403FFFF1043013A2404FFFF0A0019BAC0
+:100A80008E0200143C0300800043102450400003F9
+:100A90008E020014AC8000208E0200142411FFFF8F
+:100AA000105100062402001B024020210E0016C532
+:100AB000A38200441051012A2404FFFF8E0300008A
+:100AC0003C02000100621024104000123C02008031
+:100AD0000062102414400008024020212402001A61
+:100AE0000E0016C5A38200442403FFFF1043011C1F
+:100AF0002404FFFF02402021020028210E0016E5F9
+:100B0000240600012403FFFF104301152404FFFF06
+:100B1000241500018F83002402A0302102402021EF
+:100B20009462003624050001244200010A001AD70D
+:100B3000A46200368F90002C3C0308008C6331B017
+:100B40008E13001032623FFF0043102B10400089CB
+:100B50008F8400302402FF809083000D0043102416
+:100B6000304200FF104000842402000D0013138265
+:100B700030420003240300011443007F2402000DCF
+:100B80009082000D30420008544000048F820034EF
+:100B9000024020210A001A082402002450400004C8
+:100BA0008E03000C024020210A001A0824020027AC
+:100BB0008C82002054620006024020218E0300082F
+:100BC0008C820024506200098E0200140240202111
+:100BD000240200200E0016C5A382004410540071A8
+:100BE0002403FFFF0A001A3D8F8400242411FFFF15
+:100BF000145100048F860014024020210A001A3884
+:100C0000240200258E0300188CC2007C10620003B1
+:100C10002402000E0A001A38024020218E0300240C
+:100C20008C82002810620003240200210A001A3876
+:100C3000024020218E0500288C82002C10A2000387
+:100C40002402001F0A001A38024020218E03002CC3
+:100C500014600003240200230A001A3802402021F5
+:100C60008CC200680043102B1040000324020026B1
+:100C70000A001A38024020218C82001400651821D5
+:100C80000043102B104000088F84002402402021D4
+:100C9000240200220E0016C5A38200441051004118
+:100CA0002403FFFF8F8400242403FFF79082000DAC
+:100CB00000431024A082000D8F8600143C0308001E
+:100CC0008C6331AC8F82004894C400E08F8500248F
+:100CD0000043102130847FFF000420400044102195
+:100CE0003043007F034320213C03000E008320217A
+:100CF0002403FF8000431024AF42002CA493000083
+:100D00008CA2002824420001ACA200288CA2002C56
+:100D10008E03002C00431021ACA2002C8E02002C6C
+:100D2000ACA200308E020014ACA2003494A2003AAF
+:100D300024420001A4A2003A94C600E03C0208004C
+:100D40008C4231B024C4000130837FFF1462000F55
+:100D500000803021240280000082302430C2FFFF56
+:100D6000000213C2304200FF000210270A001A7668
+:100D7000000233C02402000D024020210E0016C5DF
+:100D8000A38200440A001A7C004018218F820014BC
+:100D900002402021240500010E0015F9A44600E0C0
+:100DA000000018210A001B0E006088218F90002C83
+:100DB0003C0308008C6331B08E05001030A23FFF69
+:100DC0000043102B104000612402FF808F8400300C
+:100DD0009083000D00431024304200FF5040005C1F
+:100DE000024020218F8200341040000B0005138246
+:100DF0008F8200149763000A944200603042FFFF24
+:100E000014430005000513828F8200202404FFFD97
+:100E10000A001AEBAF82003C304200031440000E7F
+:100E20000000000092020002104000058E03002422
+:100E300050600015920300030A001AA70240202107
+:100E40008C82002450620010920300030240202193
+:100E50000A001AAF2402000F9082000D30420008F1
+:100E60005440000992030003024020212402001094
+:100E70000E0016C5A38200442403FFFF1043003870
+:100E80002404FFFF92030003240200025462000CBA
+:100E9000920200038F820034544000099202000342
+:100EA000024020212402002C0E0016C5A38200441B
+:100EB0002403FFFF1043002A2404FFFF92020003D3
+:100EC0000200282102402021384600102CC60001D3
+:100ED0002C4200010E0016E5004630252410FFFFCD
+:100EE0001050001F2404FFFF8F8300341060001394
+:100EF000024020213C0208008C42318C0043102B20
+:100F00001440000700000000000028212406000112
+:100F10000E001646000000000A001AEB0000202117
+:100F20002402002D0E0016C5A38200441050000CB0
+:100F30002404FFFF0A001AEB000020210E0015F91F
+:100F4000240500010A001AEB0000202102402021A4
+:100F50002402000D0E0016C5A3820044004020218B
+:100F60000A001B0E008088211514000E00000000EE
+:100F70000E00174C024020210A001B0E0040882161
+:100F80000E0016C5A38200440A001B0E00408821F3
+:100F900014620017022018212402002314E2000525
+:100FA0002402000B0E0017C0024020210A001B0E75
+:100FB0000040882102402021A38200440E0016C573
+:100FC0002411FFFF0A001B0F0220182130A500FF8B
+:100FD0000E001529240600019783003A8F82003CF9
+:100FE000A780003A00431023AF82003C0220182162
+:100FF0001220003E9782003A2402FFFD5462003E18
+:101000008E4300208E4200048F830014005610236C
+:10101000AE420004906200633042007FA062006331
+:101020008E4200208F840014A780003A34420002D0
+:10103000AE420020A48000E4908200632403FFBF3E
+:1010400000431024A08200630A001B518E4300203D
+:101050009082006300621024304200FF10400023A1
+:101060009782003A90820088908300BD2485008892
+:101070003042003F2444FFE02C820020A383001C68
+:1010800010400019AF85002C2402000100821804D2
+:10109000306200191440000C3C028000344200020F
+:1010A000006210241440000B306200201040000F3A
+:1010B0009782003A90A600010240202124050001F9
+:1010C0000A001B4B30C60001024020210A001B4AC7
+:1010D00024050001024020210000282124060001EF
+:1010E0000E001646000000009782003A1440FD0CE6
+:1010F0008F8400148E4300203062000410400012E0
+:101100008F84003C2402FFFB00621024AE420020CA
+:10111000274301808F4201B80440FFFE8F820048C0
+:10112000AC6200008F420124AC62000424026083A0
+:10113000A462000824020002A062000B3C0210001E
+:10114000AF4201B88F84003C8F8300148FBF0034FE
+:101150008FB600308FB5002C8FB400288FB30024D9
+:101160008FB200208FB1001C8FB000182402000144
+:1011700027BD003803E00008AC6400C030A500FFC4
+:101180002403000124A900010069102B1040000C69
+:1011900000004021240A000100A31023004A380463
+:1011A00024630001308200010069302B10400002EE
+:1011B000000420420107402554C0FFF800A310237B
+:1011C00003E00008010010213C020800244260A452
+:1011D0003C010800AC22736C3C0208002442530816
+:1011E0003C010800AC2273702402000627BDFFE01A
+:1011F0003C010800A02273743C021EDCAFB2001850
+:10120000AFB10014AFBF001CAFB0001034526F413B
+:1012100000008821240500080E001B7202202021F6
+:10122000001180803C07080024E773780002160054
+:1012300002071821AC6200000000282124A200014E
+:101240003045FFFF8C6200002CA60008044100021C
+:10125000000220400092202614C0FFF8AC64000079
+:10126000020780218E0400000E001B72240500205E
+:10127000262300013071FFFF2E2301001460FFE5DB
+:10128000AE0200008FBF001C8FB200188FB1001497
+:101290008FB0001003E0000827BD002027BDFFD855
+:1012A000AFB3001CAFB20018AFBF0020AFB1001445
+:1012B000AFB000108F5101408F48014800089402E0
+:1012C000324300FF311300FF8F4201B80440FFFE9C
+:1012D00027500180AE1100008F420144AE0200048D
+:1012E00024020002A6120008A202000B240200142D
+:1012F000AE1300241062002528620015104000087B
+:101300002402001524020010106200302402001292
+:10131000106200098FBF00200A001CAD8FB3001CB3
+:101320001062007024020022106200378FBF00207C
+:101330000A001CAD8FB3001C3C0208008C4231A097
+:101340002403FF800222102100431024AF42002416
+:101350003C0208008C4231A0022210213042007F62
+:10136000034218213C02000A00621821166000BCEA
+:10137000AF830014906200623042000F34420030AC
+:10138000A06200620A001CAC8FBF00203C04600019
+:101390008C832C083C02F0033442FFFF00621824C7
+:1013A000AC832C083C0208008C4231A08C832C08B2
+:1013B000244200740002108200021480006218258A
+:1013C000AC832C080A001CAC8FBF00203C02080034
+:1013D0008C4231A02403FF800222102100431024FC
+:1013E000AF4200243C0208008C4231A03C03000ABA
+:1013F000022210213042007F0342102100431021BD
+:101400000A001CABAF8200143C0208008C4231A0E1
+:101410002405FF800222102100451024AF42002441
+:101420003C0208008C4231A0022210213042007F91
+:10143000034218213C02000A0062182190620063F6
+:1014400000A21024304200FF10400085AF8300143A
+:1014500024620088944300123C0208008C4231A8A8
+:1014600030633FFF00031980022210210043102146
+:101470003043007F03432021004510243C03000C2F
+:1014800000832021AF4200289082000D00A210248A
+:10149000304200FF10400072AF8400249082000DA3
+:1014A000304200101440006F8FBF00200E0015C89E
+:1014B000000000008F4201B80440FFFE0000000061
+:1014C000AE1100008F420144AE020004240200026B
+:1014D000A6120008A202000BAE1300240A001CACE6
+:1014E0008FBF00202406FF8002261024AF42002078
+:1014F0003C0208008C4231A031043FFF00042180EF
+:101500000222102100461024AF4200243C030800B0
+:101510008C6331A83C0208008C4231A03227007F46
+:101520000223182102221021006418213042007F7A
+:101530003064007F034228213C02000A0066182420
+:1015400000A22821034420213C02000C008220211B
+:10155000AF4300283C020008034718210062902195
+:10156000AF850014AF8400240E0015C8010080214F
+:101570008F4201B80440FFFE8F8200248F84001444
+:10158000274501809042000DACB10000A4B00006D8
+:10159000000216000002160300021027000237C2E4
+:1015A00014C00016248200889442001232033FFFC8
+:1015B00030423FFF14430012240260829083006394
+:1015C0002402FF8000431024304200FF5040000CF2
+:1015D00024026082908200623042000F3442004058
+:1015E000A082006224026084A4A200082402000DEC
+:1015F000A0A200050A001C963C022700240260827B
+:10160000A4A20008A0A000053C02270000061C00C0
+:101610000062182524020002A0A2000BACA3001057
+:10162000ACA00014ACA00024ACA00028ACA0002CFE
+:101630008E42004C8F840024ACA200189083000DD1
+:101640002402FF8000431024304200FF10400005B8
+:101650008FBF00209082000D3042007FA082000DDD
+:101660008FBF00208FB3001C8FB200188FB1001401
+:101670008FB000103C02100027BD002803E00008D6
+:04168000AF4201B8BC
+:0C1684000800343008003430080033A89F
+:10169000080033E0080034140800343808003438F7
+:0816A00008003438080033187B
+:0816A8000A000124000000000B
+:1016B000000000000000000D747061362E322E31E3
+:1016C0000000000006020101000000000000000010
:1016D000000000000000000000000000000000000A
:1016E00000000000000000000000000000000000FA
:1016F00000000000000000000000000000000000EA
:1017000000000000000000000000000000000000D9
:1017100000000000000000000000000000000000C9
:1017200000000000000000000000000000000000B9
-:1017300010000003000000000000000D0000000D7C
-:101740003C02080024421C003C030800246320944F
-:10175000AC4000000043202B1480FFFD2442000415
-:101760003C1D080037BD2FFC03A0F0213C100800F1
-:10177000261004903C1C0800279C1C000E00015CF5
-:10178000000000000000000D3084FFFF30820007E1
-:101790008F85001810400002248300073064FFF892
-:1017A0000085302130C41FFF03441821247B4000F2
-:1017B000AF85001CAF84001803E00008AF4400842C
-:1017C0003084FFFF308200078F8500208F8600283D
-:1017D00010400002248300073064FFF800852021B8
-:1017E0000086182B14600002AF8500240086202399
-:1017F0000344282134068000AF840020AF440080D9
-:1018000000A6202103E00008AF84003827BDFFD8E0
-:10181000AFB3001CAFB20018AFB00010AFBF0024D0
-:10182000AFB40020AFB100143C0860088D14500024
-:101830002418FF7F3C1A8000029898243672380CD6
-:10184000AD1250008F5100083C07601C3C0860003E
-:1018500036300001AF500008AF800018AF40008064
-:10186000AF4000848CE600088D0F08083C07601626
-:101870008CEC000031EEFFF039CA00103C0DFFFF88
-:10188000340B80003C030080034B48212D440001B1
-:10189000018D28243C0253533C010800AC23042052
-:1018A000AF890038AF860028AF840010275B400066
-:1018B00014A2000334E37C008CF9000403281821EF
-:1018C0008C7F007C8C6500783C0280003C0B08001B
-:1018D0008D6B048C3C0A08008D4A048834520070D9
-:1018E000AF85003CAF9F00403C13080026731C44AA
-:1018F0000240A0218E4800008F46000038C300013E
-:101900003064000110800017AF8800340280482145
-:101910008D2F00003C0508008CA5045C3C180800D5
-:101920008F18045801E8102300A280210000C8216C
-:101930000202402B03198821022838213C010800AB
-:10194000AC30045C3C010800AC2704588F4E00000A
-:1019500039CD000131AC00011580FFED01E04021DF
-:10196000AF8F00348E5100003C0708008CE7045C08
-:101970003C0D08008DAD04580228802300F0602142
-:10198000000070210190302B01AE1821006620214B
-:101990003C010800AC2C045C3C010800AC24045859
-:1019A0008F4601088F47010030C92000AF86000034
-:1019B000AF87000C1120000A00C040213C1808002D
-:1019C0008F18042C270800013C010800AC28042CC7
-:1019D0003C184000AF5801380A0001960000000092
-:1019E0009749010400002821014550213122FFFFC1
-:1019F000016258210162F82B015F502130D90200A9
-:101A00003C010800AC2B048C3C010800AC2A048883
-:101A10001720001524040F0010E40013000000003C
-:101A200024080D0010E8023B30CD000611A0FFE9AC
-:101A30003C184000936E00002409001031C400F0EF
-:101A40001089027124020070108202E58F88001450
-:101A5000250F0001AF8F00143C184000AF5801382B
-:101A60000A00019600000000974C01041180FFD984
-:101A70003C18400030C34000146000A1000000008A
-:101A80008F46017804C0FFFE8F87003824100800BD
-:101A9000240F00088CE30008AF500178A74F0140E5
-:101AA000A7400142974E01048F86000031C9FFFF15
-:101AB00030CD000111A002E1012040212531FFFEBF
-:101AC00024180002A75801463228FFFFA7510148F9
-:101AD0003C1908008F39043C172002D08F8C000C71
-:101AE00030DF002017E00002240400092404000174
-:101AF00030C20C0024050400504500013484000469
-:101B0000A744014A3C1108008E3104203C180048CB
-:101B10003C1000010238182530CF00020070282543
-:101B200011E00004000018213C19010000B928252B
-:101B30002403000130DF000453E00005AF830008F8
-:101B40003C06001000A6282524030001AF830008EE
-:101B5000AF45100000000000000000000000000081
-:101B6000000000008F8300081060002300000000C8
-:101B70008F45100004A1FFFE000000001060001E51
-:101B8000000000008F4410003C0C0020008C10244A
-:101B9000104000198F8E000031CD000211A00016F8
-:101BA00000000000974F101415E000130000000023
-:101BB000975910083338FFFF2711000600111882CB
-:101BC0000003308000C72821323000013223000397
-:101BD0001200032C8CA200000000000D00C7F821A9
-:101BE000AFE200003C0508008CA5043024A60001EB
-:101BF0003C010800AC2604308F6D00003402FFFF6A
-:101C0000AF8D00048CEC0000118202A600002021A0
-:101C10008CED000031AC01001180028A0000000050
-:101C20003C0208008C4204743C0308008C63044CA2
-:101C30003C1F08008FFF04703C1808008F180448F0
-:101C4000004838210068802100E8282B03E4302177
-:101C50000208402B0304882100C570210228782146
-:101C60003C010800AC30044C3C010800AC2F044897
-:101C70003C010800AC2704743C010800AC2E047041
-:101C80008F8400180120302131290007249F00088B
-:101C900033F91FFF03594021AF84001CAF9900188E
-:101CA000251B4000AF590084112000038F830020C2
-:101CB00024C200073046FFF88F84002800C3282183
-:101CC00000A4302B14C00002AF83002400A42823FA
-:101CD00003456021340D8000018D10213C0F100060
-:101CE000AF850020AF820038AF450080AF4F01784C
-:101CF0008F880014250F00010A0001EFAF8F001438
-:101D00008F6200088F67000024050030000776020C
-:101D100031C300F0106500A7240F0040546FFF4C42
-:101D20008F8800148F4B01780560FFFE00000000D3
-:101D300030CA020015400003000612820000000DA8
-:101D400000061282304D0003000D4900012D1821BC
-:101D500000038080020D40210008608001938021F3
-:101D60008E1F000017E00002000000000000000DC0
-:101D70008F6E000405C202BD92070006920E000598
-:101D8000920200043C090001000E18800070F82146
-:101D90008FED0018277100082448000501A9602173
-:101DA00000083082AFEC0018022020210E00059EB2
-:101DB00026050014920A00068F7900043C0B7FFF71
-:101DC000000A2080009178218DF800043566FFFF1D
-:101DD0000326282403053821ADE70004920E0005F0
-:101DE000920D0004960C0008000E10800051C821CE
-:101DF0008F230000974901043C07FFFF0067582428
-:101E00003128FFFF010DF82103EC50233144FFFF7F
-:101E100001643025AF26000092030007241800015A
-:101E200010780275240F0003106F02850000000077
-:101E30008E0500102419000AA7590140A745014248
-:101E4000921800048F860000240F0001A758014457
-:101E5000A74001469747010430D100023C050041EC
-:101E6000A747014800001821A74F014A122000038C
-:101E700030CB00043C050141240300015160000502
-:101E8000AF8300083C06001000A6282524030001AB
-:101E9000AF830008AF451000000000000000000004
-:101EA00000000000000000008F8A000811400004BC
-:101EB000000000008F4410000481FFFE00000000BD
-:101EC0008F6B0000920800043C1108008E3104441E
-:101ED000AF8B000497590104311800FF3C0E080035
-:101EE0008DCE04403325FFFF0305382102276021F2
-:101EF00000001021250F000A31E8FFFF0187482B61
-:101F000001C2682101A9F821311000073C01080035
-:101F1000AC2C04443C010800AC3F04401200000318
-:101F20008F8C00182506000730C8FFF8010C6821C7
-:101F300031BF1FFFAF8C001CAF9F0018AF5F008444
-:101F400097440104035F80213084FFFF308A00073B
-:101F500011400003261B4000248900073124FFF8AC
-:101F60008F8200208F850028008220210085702B21
-:101F700015C00002AF820024008520233C0B08001E
-:101F80008D6B048C3C0A08008D4A04880344882128
-:101F900034038000022310213C0F1000AF84002086
-:101FA000AF820038AF440080AF4F01780A0002963C
-:101FB0008F8800148F5001780600FFFE30D1020098
-:101FC00016200003000612820000000D0006128297
-:101FD000305F0003001F1900007F302100062080C1
-:101FE000009FC82100194880013380218E1800000D
-:101FF00013000002000000000000000D8F6C000CB8
-:10200000058001FB8F870038240E0001AE0E000012
-:102010008CE30008A20000078F650004000554024D
-:10202000314D00FF25A80005000830822CCB00416F
-:1020300015600002A20A00040000000D8F78000461
-:102040003C03FFFF00E02821330BFFFF256C000B52
-:10205000000C108200022080008748218D3F000084
-:1020600026040014A618000803E3C8240E00059EE9
-:10207000AD3900008F4F01083C11100001F13824E8
-:1020800010E001AB00000000974D0104920800072A
-:1020900025AAFFEC350600023144FFFFA206000727
-:1020A000960600082CC7001354E0000592030007B1
-:1020B00092110007362F0001A20F000792030007BC
-:1020C00024180001107801C224090003106901D509
-:1020D0008F88003830CBFFFF257100020011788314
-:1020E00031E400FF00042880A20F000500A8482169
-:1020F0008D2D0000974A01043C0EFFFF01AEF8242D
-:102100003143FFFF006B1023244CFFFE03ECC82576
-:10211000AD390000920600053C03FFF63462FFFF74
-:1021200030D800FF0018388000F08821922F00146A
-:102130003C04FF7F3487FFFF31EE000F01C65821BA
-:10214000316500FF00055080015068218DAC0020F2
-:102150000148F821A20B00060182C824AE0C000C35
-:10216000AFF9000C920900068E11000C03277824A9
-:102170000009C0800310702195C60026030828219D
-:1021800002272024AE04000CADCF0020ADC60024F1
-:10219000ACA600108F8800003C0B08008D6B048CEF
-:1021A0003C0A08008D4A0488241F001024190002EC
-:1021B000A75F0140A7400142A7400144A75901463B
-:1021C0009749010424070001310600022538FFFE6B
-:1021D000A75801483C050009A747014A10C0000361
-:1021E000000018213C05010924030001310C000402
-:1021F00051800005AF8300083C08001000A8282586
-:1022000024030001AF830008AF4510000000000068
-:102210000000000000000000000000009205000423
-:1022200024AE000231CD0007000D182330620007F4
-:10223000AE0200108F9000081200000400000000A1
-:102240008F4F100005E1FFFE000000008F710000BD
-:102250008F8E00183C0308008C630444AF91000487
-:102260009745010425CF001031E61FFF30A2FFFF84
-:10227000AF8E001CAF860018AF4600842449FFFED5
-:102280003C0C08008D8C0440974D010401208021F6
-:10229000000947C30070C02131A9FFFF0310F82BCC
-:1022A0000188C821033F202103463821313100072E
-:1022B0003C010800AC3804443C010800AC24044054
-:1022C0001220000324FB40002527000730E9FFF817
-:1022D0008F8600208F8400280126382100E4C02B3F
-:1022E00017000002AF86002400E4382303472021B2
-:1022F00034198000009910213C0F1000AF87002096
-:10230000AF820038AF470080AF4F01780A000296D5
-:102310008F8800149747010410E0FDAE3C18400080
-:102320008F5801780700FFFE30C5400010A0000361
-:102330003C1F00080000000D3C1F0008AF5F01407B
-:10234000241008008F860000AF50017897440104E4
-:1023500030D90001132000ED3086FFFF24CCFFFEB2
-:10236000240D0002A74D0146A74C01488F9100188B
-:102370002408000DA748014A8F630000262F00089B
-:1023800031E21FFF0342702130C90007AF83000410
-:10239000AF91001CAF82001800C03821AF4200840A
-:1023A0001120000325DB400024D800073307FFF885
-:1023B0008F8500208F84002800E5302100C4382B51
-:1023C00014E00002AF85002400C430238F84001481
-:1023D0000346F821340C8000AF86002003EC8021F6
-:1023E000AF460080249900013C0610003C184000D4
-:1023F000AF460178AF900038AF990014AF5801385C
-:102400000A000196000000008F630000975101044C
-:102410003067FFFF3228FFFF8F4F017805E0FFFE96
-:1024200030EC0007000CF82333F0000724F9FFFE1E
-:102430002404000AA7440140A7500142A7590144BF
-:10244000A7400146A74801488F45010830B8002041
-:1024500017000002240300092403000130CD00020C
-:10246000A743014A3C04004111A0000300001821C9
-:102470003C0401412403000130C90004512000053F
-:10248000AF8300083C0600100086202524030001CD
-:10249000AF830008AF4410000000000000000000FF
-:1024A00000000000000000008F8E000811C0000432
-:1024B000000000008F4210000441FFFE00000000F9
-:1024C0008F7F0000276400088F91003CAF9F0004BD
-:1024D000948500089490000A9499000C30AFFFFF97
-:1024E0000010C4003323FFFF11F100A603032025D1
-:1024F0003C0E08008DCE04443C0C08008D8C04403A
-:1025000000E888212626FFFE01C628210000682158
-:1025100000A6F82B018D2021009F80213C0108009E
-:10252000AC2504443C010800AC30044024E200081F
-:102530003042FFFF3047000710E000038F83001890
-:10254000244F000731E2FFF83106FFFF30C80007D3
-:102550000043802132191FFF0359C021AF83001CA3
-:10256000AF990018271B4000AF59008411000003E9
-:102570008F8C002024C5000730A6FFF88F84002828
-:1025800000CC282100A4F82B17E00002AF8C002417
-:1025900000A42823AF850020AF4500803C0408003C
-:1025A0008C84043403454821340E8000012E6821B8
-:1025B00010800005AF8D0038939100172406000E9F
-:1025C000122600112407043F3C021000AF4201789C
-:1025D0008F880014250F00010A0001EFAF8F00144F
-:1025E0000E0005C400E020218F8800143C0B080079
-:1025F0008D6B048C3C0A08008D4A0488250F00016D
-:102600000A0001EFAF8F00143C021000A7470148F9
-:10261000AF4201780A0004CE8F88001424040F0012
-:102620001184003D30CE002015C0000224030009B3
-:10263000240300010A00021AA743014A0A00020DFE
-:10264000A740014694EF000894F1000A94F0000CB2
-:102650008F8C003C001174003207FFFF31EDFFFF4B
-:1026600011AC003701C720253C1808008F1804441E
-:102670003C0F08008DEF0440000080210308682112
-:1026800001A8382B01F0702101C760213C0108002E
-:10269000AC2D04443C010800AC2C04400A00027A32
-:1026A0008F8400183C0208008C42047C3C03080024
-:1026B0008C6304543C1F08008FFF04783C1808000A
-:1026C0008F180450004838210068802100E8282B2A
-:1026D00003E430210208402B0304882100C5702147
-:1026E000022878213C010800AC3004543C01080069
-:1026F000AC2F04503C010800AC27047C3C010800CE
-:10270000AC2E04780A00027A8F840018A740014694
-:102710000A0004358F91001830CD002015A0FFC5A8
-:102720002403000D240300050A00021AA743014AEE
-:10273000974E010425C5FFF00A00038130A4FFFF76
-:102740008F9800401498FFC8000010213C05080035
-:102750008CA5046C3C1F08008FFF046800A8C821EA
-:102760000328302B03E22021008640213C01080091
-:10277000AC39046C3C010800AC2804680A00027AF9
-:102780008F8400188F8C0040148CFF5900E8C821FA
-:102790003C1808008F18046C3C1108008E31046846
-:1027A0002723FFFE03034821000010210123302BC3
-:1027B0000222702101C668213C010800AC29046C8A
-:1027C0003C010800AC2D04680A0004A524E20008BE
-:1027D0008F8800383C03FFFF8D02000C0043F82473
-:1027E00003E4C825AD19000C0A00038F30CBFFFFAE
-:1027F0000A0003C3AE000000974A010492040004DB
-:102800008E26000C014458212579FFF200C7C02410
-:102810003325FFFF03053825AE27000C0A0002E62A
-:102820008E0500103C0DFFFF8D0A0010014D58244D
-:1028300001646025AD0C00100A00038F30CBFFFF50
-:1028400097430104920E00048E290010006E10219F
-:10285000244DFFEE0127602431A8FFFF0188F825F1
-:10286000AE3F00100A0002E68E0500108E0F000C2D
-:10287000AE00000000078880023028210A0002B85C
-:10288000ACAF00201460000D3058FFFF3C04FFFF88
-:102890000044682401A47026000E602B000D102B4C
-:1028A000004CF82413E00002000000000000000DBE
-:1028B0008CAF00000A00025001E410253B03FFFF2B
-:1028C0000003882B0018802B0211202410800002A6
-:1028D000000000000000000D8CB900000A0002504A
-:1028E0003722FFFF3084FFFF30A5FFFF1080000775
-:1028F0000000182130820001104000020004204234
-:10290000006518211480FFFB0005284003E0000843
-:102910000060102110C00007000000008CA2000021
-:1029200024C6FFFF24A50004AC82000014C0FFFBF6
-:102930002484000403E000080000000010A0000848
-:1029400024A3FFFFAC860000000000000000000090
-:102950002402FFFF2463FFFF1462FFFA24840004B3
-:1029600003E0000800000000308EFFFF30D8FFFFBA
-:1029700000057C0001F8602539CDFFFF01AC502136
-:10298000014C582B014B4821000944023127FFFF1D
-:1029900000E830210006240230C5FFFF00A4182102
-:1029A0003862FFFF03E000083042FFFF3C0C0800E4
-:1029B0008D8C0484240BFF8027BDFFD0018450211F
-:1029C000014B4824AF4900203C0808008D080484CE
-:1029D000AFB20020AFB00018AFBF0028AFB30024E3
-:1029E000AFB1001C936600040104382130E4007F7D
-:1029F000009A10213C0300080043902130C50020BC
-:102A0000036080213C080111277B000814A000020C
-:102A1000264600702646006C92130004975101046C
-:102A2000920F00043267000F322EFFFF31ED00409D
-:102A300001C7282311A0000500004821925900BCBD
-:102A4000333800041700009000000000924300BCDF
-:102A5000307F000413E0000F0000000010A0000D04
-:102A600000000000960E0002240AFF8000A76021EB
-:102A700025CDFFFEA74D1016920B0004014B20241C
-:102A8000308200FF10400085010C40253C0F0400FF
-:102A9000010F40258F5301780660FFFE2404000AD1
-:102AA000A7440140960D00022404000931AC000740
-:102AB000000C5823316A0007A74A0142960200021F
-:102AC0002443FFFEA7430144A7400146975F01044A
-:102AD000A75F01488F5901083338002053000001D7
-:102AE00024040001920F000431EE001015C0000212
-:102AF0003483001000801821A743014A0000000021
-:102B0000000000000000000000000000AF481000BE
-:102B100000000000000000000000000000000000B5
-:102B20008F5110000621FFFE3113FFFF12600003DA
-:102B3000000000008F481018ACC800009603000683
-:102B4000307FFFFF27F90002001998820013888068
-:102B5000023B30218CD800001520005700183402A9
-:102B6000920300042405FF8000A3F82433F100FF42
-:102B70001220002C00000000924700BC30F200023E
-:102B80001240002800000000974B100C2562FFFE49
-:102B9000A7421016000000003C0A0400354900302E
-:102BA000AF4910000000000000000000000000001D
-:102BB000000000008F4C10000581FFFE00000000A7
-:102BC0009749100C8F51101C00C020213127FFFFA6
-:102BD00024F20030001218820003288000BBF82184
-:102BE0003226FFFFAFF100000E0005B300112C02EA
-:102BF0000013C880033B98218E7800000002740007
-:102C0000AFB800108FA80010310FFFFFAFAF00105A
-:102C10008FA4001001C46825AFAD00108FA600106E
-:102C2000AE66000097730008976D000A9766000C67
-:102C30008F8A003C000D5C0030CCFFFF3262FFFF4A
-:102C4000104A0036016C2025960600023C10100048
-:102C500024D300080E00013B3264FFFF974C0104AF
-:102C60000E0001493184FFFFAF5001788FBF00286B
-:102C70008FB300248FB200208FB1001C8FB00018DA
-:102C800003E0000827BD003010A0FF700000000026
-:102C900024A5FFFC0A0005EC240900048CD10000E7
-:102CA000AF5110188F5301780660FF7A2404000A90
-:102CB0000A0006010000000000A7C8218F88003824
-:102CC0008F4E101C0019C0820018788001E8202166
-:102CD000AC8E0000000E2C0200C020210E0005B3B7
-:102CE00031C6FFFF023B28218CAD000000025400DA
-:102CF00000403021AFAD00108FAC0010318BFFFFD2
-:102D0000AFAB00108FA2001001424825AFA9001000
-:102D10008FA700100A000631ACA700008F8F00407B
-:102D2000148FFFC90000000097420104960B0002B7
-:102D30003C0508008CA5046C3049FFFF316AFFFF99
-:102D40003C1108008E310468012A382124F2FFFE6C
-:102D500000B240210012FFC30112C82B023FC02164
-:102D6000031920213C010800AC28046C3C01080038
-:102D7000AC2404680A00066B0000000000A4102BBD
-:102D800010400009240300010005284000A4102B76
-:102D900004A00003000318405440FFFC0005284035
-:102DA00010600007000000000085302B14C00002F6
-:102DB00000031842008520231460FFFB0005284211
-:102DC00003E00008008010218F85002C27BDFFE85C
-:102DD000000530272CC300012CA40002008310251D
-:102DE00010400003AFBF00102405007FAF85002C0A
-:102DF0000005282730A5FFFF0E000592240426F5C4
-:102E00008F830030240402BD004030210083382B22
-:102E100010E0000924050001000420400083102B6D
-:102E200004800003000528405440FFFC00042040BB
-:102E300010A0000800C350210064402B15000002C0
-:102E4000000528420064182314A0FFFB0004204260
-:102E500000C350218FBF0010000A4C02312200FF36
-:102E600027BD0018AF8A002C03E00008AF890030AE
-:102E70000A00002A00000000000000000000000D11
-:102E8000747870362E302E313500000006000F00A9
-:102E900000000000000001360000EA6000000000B1
-:102EA0000000000000000000000000000000000022
+:101730000000000000000000000000001000000396
+:10174000000000000000000D0000000D3C02080039
+:1017500024421C003C03080024632094AC40000099
+:101760000043202B1480FFFD244200043C1D080090
+:1017700037BD2FFC03A0F0213C1008002610049078
+:101780003C1C0800279C1C000E00015C00000000AF
+:101790000000000D3084FFFF308200078F850018A5
+:1017A00010400002248300073064FFF800853021D8
+:1017B00030C41FFF03441821247B4000AF85001C68
+:1017C000AF84001803E00008AF4400843084FFFFBA
+:1017D000308200078F8500208F860028104000028D
+:1017E000248300073064FFF8008520210086182B31
+:1017F00014600002AF8500240086202303442821C2
+:1018000034068000AF840020AF44008000A6202171
+:1018100003E00008AF84003827BDFFD8AFB3001C39
+:10182000AFB20018AFB00010AFBF0024AFB40020BB
+:10183000AFB100143C0860088D1450002418FF7FDD
+:101840003C1A8000029898243672380CAD12500071
+:101850008F5100083C07601C3C08600036300001D6
+:10186000AF500008AF800018AF400080AF40008448
+:101870008CE600088D0F08083C0760168CEC000011
+:1018800031EEFFF039CA00103C0DFFFF340B800031
+:101890003C030080034B48212D440001018D282486
+:1018A0003C0253533C010800AC230420AF890038AC
+:1018B000AF860028AF840010275B400014A200030D
+:1018C00034E37C008CF90004032818218C7F007C11
+:1018D0008C6500783C0280003C0B08008D6B048C0A
+:1018E0003C0A08008D4A048834520070AF85003CE1
+:1018F000AF9F00403C13080026731C440240A02107
+:101900008E4800008F46000038C30001306400019B
+:1019100010800017AF880034028048218D2F00000E
+:101920003C0508008CA5045C3C1808008F1804587E
+:1019300001E8102300A280210000C8210202402BF0
+:1019400003198821022838213C010800AC30045CCE
+:101950003C010800AC2704588F4E000039CD00012F
+:1019600031AC00011580FFED01E04021AF8F003464
+:101970008E5100003C0708008CE7045C3C0D080019
+:101980008DAD04580228802300F0602100007021F2
+:101990000190302B01AE1821006620213C01080087
+:1019A000AC2C045C3C010800AC2404588F460108B0
+:1019B0008F47010030C92000AF860000AF87000CC0
+:1019C0001120000A00C040213C1808008F18042C88
+:1019D000270800013C010800AC28042C3C184000FA
+:1019E000AF5801380A000196000000009749010431
+:1019F00000002821014550213122FFFF01625821BA
+:101A00000162F82B015F502130D902003C0108002F
+:101A1000AC2B048C3C010800AC2A0488172000156C
+:101A200024040F0010E400130000000024080D003F
+:101A300010E8023B30CD000611A0FFE93C18400041
+:101A4000936E00002409001031C400F01089027167
+:101A500024020070108202E58F880014250F000117
+:101A6000AF8F00143C184000AF5801380A000196AF
+:101A700000000000974C01041180FFD93C18400081
+:101A800030C34000146000A1000000008F460178C0
+:101A900004C0FFFE8F87003824100800240F0008C0
+:101AA0008CE30008AF500178A74F0140A7400142E6
+:101AB000974E01048F86000031C9FFFF30CD000131
+:101AC00011A002E1012040212531FFFE241800026F
+:101AD000A75801463228FFFFA75101483C190800CA
+:101AE0008F39043C172002D08F8C000C30DF00208F
+:101AF00017E00002240400092404000130C20C0095
+:101B0000240504005045000134840004A744014A20
+:101B10003C1108008E3104203C1800483C100001A4
+:101B20000238182530CF00020070282511E000048B
+:101B3000000018213C19010000B9282524030001E8
+:101B400030DF000453E00005AF8300083C060010BE
+:101B500000A6282524030001AF830008AF4510002C
+:101B60000000000000000000000000000000000075
+:101B70008F83000810600023000000008F451000D4
+:101B800004A1FFFE000000001060001E0000000025
+:101B90008F4410003C0C0020008C102410400019D1
+:101BA0008F8E000031CD000211A000160000000051
+:101BB000974F101415E0001300000000975910080B
+:101BC0003338FFFF27110006001118820003308010
+:101BD00000C7282132300001322300031200032CF9
+:101BE0008CA200000000000D00C7F821AFE2000049
+:101BF0003C0508008CA5043024A600013C01080027
+:101C0000AC2604308F6D00003402FFFFAF8D00045E
+:101C10008CEC0000118202A6000020218CED000057
+:101C200031AC01001180028A000000003C02080073
+:101C30008C4204743C0308008C63044C3C1F080075
+:101C40008FFF04703C1808008F18044800483821A2
+:101C50000068802100E8282B03E430210208402B93
+:101C60000304882100C57021022878213C01080066
+:101C7000AC30044C3C010800AC2F04483C01080087
+:101C8000AC2704743C010800AC2E04708F8400184B
+:101C90000120302131290007249F000833F91FFF5C
+:101CA00003594021AF84001CAF990018251B400048
+:101CB000AF590084112000038F83002024C2000745
+:101CC0003046FFF88F84002800C3282100A4302B61
+:101CD00014C00002AF83002400A428230345602120
+:101CE000340D8000018D10213C0F1000AF850020C5
+:101CF000AF820038AF450080AF4F01788F88001465
+:101D0000250F00010A0001EFAF8F00148F62000859
+:101D10008F670000240500300007760231C300F011
+:101D2000106500A7240F0040546FFF4C8F880014EB
+:101D30008F4B01780560FFFE0000000030CA0200F2
+:101D400015400003000612820000000D00061282FA
+:101D5000304D0003000D4900012D18210003808043
+:101D6000020D402100086080019380218E1F000039
+:101D700017E00002000000000000000D8F6E00045C
+:101D800005C202BD92070006920E000592020004F1
+:101D90003C090001000E18800070F8218FED00183A
+:101DA000277100082448000501A96021000830823D
+:101DB000AFEC0018022020210E00059E260500141D
+:101DC000920A00068F7900043C0B7FFF000A2080F6
+:101DD000009178218DF800043566FFFF0326282442
+:101DE00003053821ADE70004920E0005920D0004B2
+:101DF000960C0008000E10800051C8218F230000AF
+:101E0000974901043C07FFFF006758243128FFFF72
+:101E1000010DF82103EC50233144FFFF016430250C
+:101E2000AF26000092030007241800011078027505
+:101E3000240F0003106F0285000000008E050010C3
+:101E40002419000AA7590140A7450142921800042D
+:101E50008F860000240F0001A7580144A7400146C7
+:101E60009747010430D100023C050041A7470148D3
+:101E700000001821A74F014A1220000330CB0004B4
+:101E80003C0501412403000151600005AF830008B7
+:101E90003C06001000A6282524030001AF8300089B
+:101EA000AF4510000000000000000000000000002E
+:101EB000000000008F8A00081140000400000000AC
+:101EC0008F4410000481FFFE000000008F6B0000B3
+:101ED000920800043C1108008E310444AF8B0004CA
+:101EE00097590104311800FF3C0E08008DCE0440C4
+:101EF0003325FFFF03053821022760210000102150
+:101F0000250F000A31E8FFFF0187482B01C2682135
+:101F100001A9F821311000073C010800AC2C044451
+:101F20003C010800AC3F0440120000038F8C0018F5
+:101F30002506000730C8FFF8010C682131BF1FFFDC
+:101F4000AF8C001CAF9F0018AF5F00849744010462
+:101F5000035F80213084FFFF308A000711400003B7
+:101F6000261B4000248900073124FFF88F820020BF
+:101F70008F850028008220210085702B15C000026B
+:101F8000AF820024008520233C0B08008D6B048C5D
+:101F90003C0A08008D4A04880344882134038000E9
+:101FA000022310213C0F1000AF840020AF820038C4
+:101FB000AF440080AF4F01780A0002968F8800146A
+:101FC0008F5001780600FFFE30D10200162000037A
+:101FD000000612820000000D00061282305F00032E
+:101FE000001F1900007F302100062080009FC821BB
+:101FF00000194880013380218E1800001300000270
+:10200000000000000000000D8F6C000C058001FB3B
+:102010008F870038240E0001AE0E00008CE300080C
+:10202000A20000078F65000400055402314D00FF37
+:1020300025A80005000830822CCB00411560000265
+:10204000A20A00040000000D8F7800043C03FFFF8B
+:1020500000E02821330BFFFF256C000B000C1082E1
+:1020600000022080008748218D3F000026040014D4
+:10207000A618000803E3C8240E00059EAD39000031
+:102080008F4F01083C11100001F1382410E001AB22
+:1020900000000000974D01049208000725AAFFECFC
+:1020A000350600023144FFFFA2060007960600082D
+:1020B0002CC7001354E0000592030007921100079B
+:1020C000362F0001A20F0007920300072418000119
+:1020D000107801C224090003106901D58F880038E7
+:1020E00030CBFFFF257100020011788331E400FF3F
+:1020F00000042880A20F000500A848218D2D0000B3
+:10210000974A01043C0EFFFF01AEF8243143FFFF64
+:10211000006B1023244CFFFE03ECC825AD390000F2
+:10212000920600053C03FFF63462FFFF30D800FF43
+:102130000018388000F08821922F00143C04FF7FA3
+:102140003487FFFF31EE000F01C65821316500FFD3
+:1021500000055080015068218DAC00200148F82115
+:10216000A20B00060182C824AE0C000CAFF9000CD3
+:10217000920900068E11000C032778240009C08004
+:102180000310702195C60026030828210227202469
+:10219000AE04000CADCF0020ADC60024ACA60010EC
+:1021A0008F8800003C0B08008D6B048C3C0A0800F3
+:1021B0008D4A0488241F001024190002A75F0140E3
+:1021C000A7400142A7400144A7590146974901048D
+:1021D00024070001310600022538FFFEA7580148F8
+:1021E0003C050009A747014A10C000030000182160
+:1021F0003C05010924030001310C00045180000555
+:10220000AF8300083C08001000A828252403000123
+:10221000AF830008AF451000000000000000000080
+:1022200000000000000000009205000424AE00023F
+:1022300031CD0007000D182330620007AE020010F8
+:102240008F90000812000004000000008F4F100063
+:1022500005E1FFFE000000008F7100008F8E001866
+:102260003C0308008C630444AF91000497450104CB
+:1022700025CF001031E61FFF30A2FFFFAF8E001CFC
+:10228000AF860018AF4600842449FFFE3C0C0800CE
+:102290008D8C0440974D010401208021000947C323
+:1022A0000070C02131A9FFFF0310F82B0188C8215D
+:1022B000033F202103463821313100073C0108004B
+:1022C000AC3804443C010800AC2404401220000354
+:1022D00024FB40002527000730E9FFF88F86002007
+:1022E0008F8400280126382100E4C02B170000024B
+:1022F000AF86002400E438230347202134198000EE
+:10230000009910213C0F1000AF870020AF820038E9
+:10231000AF470080AF4F01780A0002968F88001403
+:102320009747010410E0FDAE3C1840008F5801783B
+:102330000700FFFE30C5400010A000033C1F00084E
+:102340000000000D3C1F0008AF5F01402410080092
+:102350008F860000AF5001789744010430D9000106
+:10236000132000ED3086FFFF24CCFFFE240D000279
+:10237000A74D0146A74C01488F9100182408000D75
+:10238000A748014A8F630000262F000831E21FFF93
+:102390000342702130C90007AF830004AF91001CD5
+:1023A000AF82001800C03821AF4200841120000322
+:1023B00025DB400024D800073307FFF88F85002075
+:1023C0008F84002800E5302100C4382B14E000027F
+:1023D000AF85002400C430238F8400140346F82105
+:1023E000340C8000AF86002003EC8021AF460080D3
+:1023F000249900013C0610003C184000AF460178CB
+:10240000AF900038AF990014AF5801380A00019618
+:10241000000000008F630000975101043067FFFF48
+:102420003228FFFF8F4F017805E0FFFE30EC0007F8
+:10243000000CF82333F0000724F9FFFE2404000AFF
+:10244000A7440140A7500142A7590144A7400146B3
+:10245000A74801488F45010830B800201700000246
+:10246000240300092403000130CD0002A743014AE0
+:102470003C04004111A00003000018213C0401416C
+:102480002403000130C9000451200005AF83000877
+:102490003C0600100086202524030001AF830008BD
+:1024A000AF44100000000000000000000000000029
+:1024B000000000008F8E000811C000040000000022
+:1024C0008F4210000441FFFE000000008F7F0000DB
+:1024D000276400088F91003CAF9F0004948500089A
+:1024E0009490000A9499000C30AFFFFF0010C400D4
+:1024F0003323FFFF11F100A6030320253C0E080043
+:102500008DCE04443C0C08008D8C044000E88821EA
+:102510002626FFFE01C628210000682100A6F82B10
+:10252000018D2021009F80213C010800AC2504443E
+:102530003C010800AC30044024E200083042FFFFB8
+:102540003047000710E000038F830018244F000776
+:1025500031E2FFF83106FFFF30C800070043802159
+:1025600032191FFF0359C021AF83001CAF99001817
+:10257000271B4000AF590084110000038F8C0020FE
+:1025800024C5000730A6FFF88F84002800CC28213E
+:1025900000A4F82B17E00002AF8C002400A428232D
+:1025A000AF850020AF4500803C0408008C840434D3
+:1025B00003454821340E8000012E6821108000055B
+:1025C000AF8D0038939100172406000E12260011DB
+:1025D0002407043F3C021000AF4201788F880014AA
+:1025E000250F00010A0001EFAF8F00140E0005C493
+:1025F00000E020218F8800143C0B08008D6B048CB8
+:102600003C0A08008D4A0488250F00010A0001EFEA
+:10261000AF8F00143C021000A7470148AF42017879
+:102620000A0004CE8F88001424040F001184003D9A
+:1026300030CE002015C0000224030009240300014D
+:102640000A00021AA743014A0A00020DA7400146E8
+:1026500094EF000894F1000A94F0000C8F8C003C79
+:10266000001174003207FFFF31EDFFFF11AC00379E
+:1026700001C720253C1808008F1804443C0F0800AF
+:102680008DEF0440000080210308682101A8382B49
+:1026900001F0702101C760213C010800AC2D044409
+:1026A0003C010800AC2C04400A00027A8F84001818
+:1026B0003C0208008C42047C3C0308008C630454F8
+:1026C0003C1F08008FFF04783C1808008F18045046
+:1026D000004838210068802100E8282B03E43021DD
+:1026E0000208402B0304882100C5702102287821AC
+:1026F0003C010800AC3004543C010800AC2F0450ED
+:102700003C010800AC27047C3C010800AC2E047896
+:102710000A00027A8F840018A74001460A00043597
+:102720008F91001830CD002015A0FFC52403000DA7
+:10273000240300050A00021AA743014A974E010428
+:1027400025C5FFF00A00038130A4FFFF8F980040E9
+:102750001498FFC8000010213C0508008CA5046CEB
+:102760003C1F08008FFF046800A8C8210328302BF5
+:1027700003E22021008640213C010800AC39046CB2
+:102780003C010800AC2804680A00027A8F84001813
+:102790008F8C0040148CFF5900E8C8213C180800B9
+:1027A0008F18046C3C1108008E3104682723FFFE4B
+:1027B00003034821000010210123302B0222702145
+:1027C00001C668213C010800AC29046C3C010800EA
+:1027D000AC2D04680A0004A524E200088F880038A4
+:1027E0003C03FFFF8D02000C0043F82403E4C825DE
+:1027F000AD19000C0A00038F30CBFFFF0A0003C3A2
+:10280000AE000000974A0104920400048E26000CDA
+:10281000014458212579FFF200C7C0243325FFFF6A
+:1028200003053825AE27000C0A0002E68E050010CD
+:102830003C0DFFFF8D0A0010014D582401646025F6
+:10284000AD0C00100A00038F30CBFFFF974301044B
+:10285000920E00048E290010006E1021244DFFEE10
+:102860000127602431A8FFFF0188F825AE3F001042
+:102870000A0002E68E0500108E0F000CAE0000006C
+:1028800000078880023028210A0002B8ACAF00207F
+:102890001460000D3058FFFF3C04FFFF0044682423
+:1028A00001A47026000E602B000D102B004CF824A4
+:1028B00013E00002000000000000000D8CAF0000DB
+:1028C0000A00025001E410253B03FFFF0003882BA0
+:1028D0000018802B0211202410800002000000004C
+:1028E0000000000D8CB900000A0002503722FFFFE3
+:1028F0003084FFFF30A5FFFF108000070000182183
+:1029000030820001104000020004204200651821BE
+:102910001480FFFB0005284003E000080060102140
+:1029200010C00007000000008CA2000024C6FFFFBA
+:1029300024A50004AC82000014C0FFFB2484000422
+:1029400003E000080000000010A0000824A3FFFF1F
+:10295000AC86000000000000000000002402FFFF21
+:102960002463FFFF1462FFFA2484000403E00008DC
+:1029700000000000308EFFFF30D8FFFF00057C0014
+:1029800001F8602539CDFFFF01AC5021014C582BD7
+:10299000014B4821000944023127FFFF00E83021A4
+:1029A0000006240230C5FFFF00A418213862FFFF93
+:1029B00003E000083042FFFF3C0C08008D8C0484CB
+:1029C000240BFF8027BDFFD001845021014B4824F8
+:1029D000AF4900203C0808008D080484AFB20020F5
+:1029E000AFB00018AFBF0028AFB30024AFB1001CD8
+:1029F000936600040104382130E4007F009A10211E
+:102A00003C0300080043902130C500200360802172
+:102A10003C080111277B000814A000022646007024
+:102A20002646006C9213000497510104920F000493
+:102A30003267000F322EFFFF31ED004001C728231F
+:102A400011A0000500004821925900BC3338000451
+:102A50001700009000000000924300BC307F00048B
+:102A600013E0000F0000000010A0000D00000000A7
+:102A7000960E0002240AFF8000A7602125CDFFFEEC
+:102A8000A74D1016920B0004014B2024308200FF4A
+:102A900010400085010C40253C0F0400010F40252B
+:102AA0008F5301780660FFFE2404000AA74401400A
+:102AB000960D00022404000931AC0007000C5823D5
+:102AC000316A0007A74A0142960200022443FFFE32
+:102AD000A7430144A7400146975F0104A75F01484F
+:102AE0008F590108333800205300000124040001ED
+:102AF000920F000431EE001015C000023483001064
+:102B000000801821A743014A0000000000000000D7
+:102B10000000000000000000AF48100000000000AE
+:102B20000000000000000000000000008F511000B5
+:102B30000621FFFE3113FFFF1260000300000000BA
+:102B40008F481018ACC8000096030006307FFFFFC6
+:102B500027F900020019988200138880023B302177
+:102B60008CD800001520005700183402920300048E
+:102B70002405FF8000A3F82433F100FF1220002C6D
+:102B800000000000924700BC30F200021240002812
+:102B900000000000974B100C2562FFFEA7421016A4
+:102BA000000000003C0A040035490030AF49100025
+:102BB0000000000000000000000000000000000015
+:102BC0008F4C10000581FFFE000000009749100C9B
+:102BD0008F51101C00C020213127FFFF24F200304C
+:102BE000001218820003288000BBF8213226FFFF64
+:102BF000AFF100000E0005B300112C020013C880D5
+:102C0000033B98218E78000000027400AFB80010DA
+:102C10008FA80010310FFFFFAFAF00108FA400107E
+:102C200001C46825AFAD00108FA60010AE6600008D
+:102C300097730008976D000A9766000C8F8A003C16
+:102C4000000D5C0030CCFFFF3262FFFF104A0036FF
+:102C5000016C2025960600023C10100024D30008C9
+:102C60000E00013B3264FFFF974C01040E00014946
+:102C70003184FFFFAF5001788FBF00288FB300244D
+:102C80008FB200208FB1001C8FB0001803E0000845
+:102C900027BD003010A0FF700000000024A5FFFC3D
+:102CA0000A0005EC240900048CD10000AF51101873
+:102CB0008F5301780660FF7A2404000A0A00060197
+:102CC0000000000000A7C8218F8800388F4E101C1C
+:102CD0000019C0820018788001E82021AC8E000025
+:102CE000000E2C0200C020210E0005B331C6FFFFEC
+:102CF000023B28218CAD000000025400004030212E
+:102D0000AFAD00108FAC0010318BFFFFAFAB0010E8
+:102D10008FA2001001424825AFA900108FA7001014
+:102D20000A000631ACA700008F8F0040148FFFC946
+:102D30000000000097420104960B00023C050800C9
+:102D40008CA5046C3049FFFF316AFFFF3C1108007D
+:102D50008E310468012A382124F2FFFE00B240219E
+:102D60000012FFC30112C82B023FC021031920210A
+:102D70003C010800AC28046C3C010800AC24046849
+:102D80000A00066B0000000000A4102B1040000990
+:102D9000240300010005284000A4102B04A0000318
+:102DA000000318405440FFFC000528401060000755
+:102DB000000000000085302B14C000020003184200
+:102DC000008520231460FFFB0005284203E0000873
+:102DD000008010218F85002C27BDFFE800053027DB
+:102DE0002CC300012CA40002008310251040000316
+:102DF000AFBF00102405007FAF85002C00052827F9
+:102E000030A5FFFF0E000592240426F58F830030C5
+:102E1000240402BD004030210083382B10E000095B
+:102E200024050001000420400083102B04800003CF
+:102E3000000528405440FFFC0004204010A000087A
+:102E400000C350210064402B1500000200052842F9
+:102E50000064182314A0FFFB0004204200C350218B
+:102E60008FBF0010000A4C02312200FF27BD00185E
+:0C2E7000AF8A002C03E00008AF8900309E
+:042E7C000A00002A1E
+:102E800000000000000000000000000D74787036A3
+:102E90002E322E310000000006020100000000006A
+:102EA000000001360000EA600000000000000000A1
:102EB0000000000000000000000000000000000012
:102EC0000000000000000000000000000000000002
-:102ED00000000016000000000000000000000000DC
+:102ED00000000000000000000000000000000016DC
:102EE00000000000000000000000000000000000E2
:102EF00000000000000000000000000000000000D2
-:102F00000000000000000000000013880000000026
-:102F1000000005DC000000000000000010000003BD
-:102F2000000000000000000D0000000D3C02080041
-:102F300024423C203C03080024633DD4AC40000004
-:102F40000043202B1480FFFD244200043C1D080098
-:102F500037BD7FFC03A0F0213C100800261000A81C
-:102F60003C1C0800279C3C200E0002BA0000000018
-:102F70000000000D8F8300383C088000350700708A
-:102F80008CE50000008330253C02900000C2202523
-:102F9000AF850030AF4400208F4900200520FFFEA0
-:102FA0003C038000346200708C4500008F86003046
-:102FB0003C1908008F39007C3C0E08008DCE00784B
-:102FC00000A6202303245821000078210164682BE7
-:102FD00001CF6021018D50213C010800AC2B007C09
-:102FE0003C010800AC2A007803E000080000000063
-:102FF0000A000041240400018F8400383C05800051
-:1030000034A200010082182503E00008AF4300202D
-:1030100003E00008000010213084FFFF30A5FFFF0F
-:1030200010800007000018213082000110400002CB
-:1030300000042042006518211480FFFB0005284091
-:1030400003E000080060102110C00007000000002D
-:103050008CA2000024C6FFFF24A50004AC8200005F
-:1030600014C0FFFB2484000403E0000800000000FB
-:1030700010A0000824A3FFFFAC86000000000000A1
-:10308000000000002402FFFF2463FFFF1462FFFA28
-:103090002484000403E0000800000000308AFFFFE1
-:1030A00093A80013A74A014497490E1630C600FFA3
-:1030B0003C021000A7490146AF450148A346015212
-:1030C000A748015AAF4701608FA400188FA30014CE
-:1030D000A7440158AF43015403E00008AF42017810
-:1030E00003E00008000000003C0380003462007030
-:1030F0008C4900008F8800002484000727BDFFF85A
-:103100003084FFF8AF890030974D008A31ACFFFF63
-:10311000AFAC00008FAB0000016850232547FFFFD4
-:1031200030E61FFF00C4282B14A0FFF73C0C8000E2
-:10313000358B00708D6A00003C0708008CE7008426
-:103140003C0608008CC60080000810820149182344
-:103150000002788000E370210000202101C3C82B09
-:1031600000C4C02101FA4021031948212502400072
-:1031700027BD00083C010800AC2E00843C0108007B
-:10318000AC29008003E00008000000008F820000EE
-:103190002486000730C5FFF800A2182130641FFF05
-:1031A00003E00008AF8400008F8700388F8A00405A
-:1031B00027BDFFB88F860044AFB60040AFBF0044C4
-:1031C000AFB5003CAFB40038AFB30034AFB200309D
-:1031D000AFB1002CAFB000288F4501048D4900AC81
-:1031E000AF4700808CC8002000A938230000B02120
-:1031F000AF480E108F440E1000004821AF440E144B
-:103200008CC20024AF420E188F430E18AF430E1C21
-:1032100010E001252D230001936B0008116000D4FC
-:1032200000000000976E001031CDFFFF00ED602B15
-:10323000158000CF0000000097700010320FFFFFD4
-:10324000AF4F0E008F520000325100081220FFFDD8
-:103250000000000097540E088F460E043285FFFFD1
-:1032600030B3000112600132000000000000000DC8
-:1032700030B8A04024150040131500C030A9A000AC
-:103280001120012D00000000937F000813E00008CA
-:103290000000000097630010306BFFFF00CB402B55
-:1032A0001100000330AC0040118001230000000039
-:1032B000A785003CAF8600349366000800E0282113
-:1032C000AFA7002014C0012427B30020AF60000C7A
-:1032D0009782003C3047400014E0000224030016AF
-:1032E0002403000E24194007A363000AAF790014D9
-:1032F000938A003E8F740014315800070018AA40CA
-:1033000002959025AF7200149784003C8F700014D2
-:103310003091001002117825AF6F0014978E003C99
-:1033200031CD000811A00147000028218F6700144B
-:103330003C0210003C0C810000E22825AF6500141F
-:1033400097460E0A2408000E3405FFFC30C3FFFF29
-:10335000006C5825AF6B0004A3680002937F000A3D
-:1033600027E90004A369000A9786003C9363000ADA
-:1033700030CC1F00000C598301634021251F002819
-:10338000A37F000997490E0CA769001093790009E3
-:10339000272A0002315800070018A82332B100077D
-:1033A000A371000B93740009976400108F9100348F
-:1033B000978F003C329200FF024480210205702169
-:1033C00031ED004011A0000531C4FFFF0091282B12
-:1033D0003C12800010A000140000A0210224382B11
-:1033E00014E0011B8FA500208F4D0E14AF4D0E1061
-:1033F0008F420E1CAF420E18AF440E008F4F0000DC
-:1034000031EE000811C0FFFD0000000097540E08C7
-:103410000080882100009021A794003C8F500E046A
-:1034200024140001AF900034976400103095FFFF22
-:103430008E6800000111F82317E00009AE7F00003C
-:103440008F6500148F8B004434A60040AF660014D3
-:103450008F4C0E10AD6C00208F430E18AD6300240E
-:103460009367000814E000D2000000000E00009EE8
-:10347000240400108F8900483C08320000402821B5
-:10348000312600FF0006FC0003E850252539000125
-:10349000AF990048AC4A0000937800099370000A85
-:1034A000330400FF00047400320F00FF01CF6825D1
-:1034B000AC4D00048F820048064000EAACA2000830
-:1034C000ACA0000C9783003C306B00081560000234
-:1034D0002628000626280002974E0E148F450E1C43
-:1034E0008F670004936D000231C4FFFF31A200FF1B
-:1034F000AFA200108F6C0014AFA800180E00008B54
-:10350000AFAC0014240400100E0000C7000000003F
-:103510008E72000016400005000000008F64001449
-:103520002405FFBF00859824AF7300148F79000C29
-:1035300003353821AF67000C9375000816A000080A
-:103540000000000012800006000000008F7F0014C1
-:103550003C0BEFFF3568FFFE03E84824AF69001419
-:10356000A37400088FA500200A0002460220202133
-:10357000AF470E000A0000F5000000008F590178E7
-:103580000720FFFE241F08008F840000AF5F017832
-:10359000974B008A316AFFFF014448232528FFFF2B
-:1035A00031021FFF2C4300081460FFF900000000E7
-:1035B0008F8E00488F8D003800C0482103442021A1
-:1035C00025C60001240C0F00AF86004800E938230F
-:1035D0002486400031CA00FF11AC00052408000118
-:1035E0009391003E3230000700107A4035E8000128
-:1035F000000AAC003C18010002B8A025AC944000C1
-:103600008F93004830B2003630A40008ACD30004D9
-:103610001080009701123025974E0E0A8F8D000002
-:103620003C02810031CCFFFF25AB00080182402520
-:103630003C03100031651FFF25390006241F000ED2
-:10364000AF48016000C33025A75F015AAF85000075
-:10365000A759015814E0000A8F93003824120F0074
-:10366000527200022416000134C600408F580E101A
-:103670008F940044AE9800208F550E18AE9500240C
-:103680008F450E14AF4501448F590E1CAF590148A8
-:10369000A34A01523C0A1000AF460154AF4A0178D8
-:1036A00014E0FEDD2D2300010076A0251280001716
-:1036B0008FBF00448F84003824160F0010960084BA
-:1036C000000000008F45017804A0FFFE24150F00C4
-:1036D0001095006E000000008F470E142402024077
-:1036E0003C1F1000AF4701448F440E1CAF440148FB
-:1036F000A3400152A740015AAF400160A7400158C2
-:10370000AF420154AF5F01788FBF00448FB60040D5
-:103710008FB5003C8FB400388FB300348FB20030C7
-:103720008FB1002C8FB0002803E0000827BD0048AF
-:1037300014C0FED030B8A0408F420E148F840044D5
-:1037400000004821AC8200208F510E1CAC91002457
-:103750000A00020E2D2300018F910034978A003C4D
-:103760003C1280000220A821315800401700FF3091
-:103770000000A021976900108F9200343139FFFFBB
-:103780001332003500002021008048211480FEA063
-:1037900000A038218F420E148F840044AC82002098
-:1037A0008F510E1CAC9100240A00020E2D23000143
-:1037B000936A00099378000B315000FF330F00FF2C
-:1037C000020F702125C2000A3050FFFF0E00009E3C
-:1037D000020020218F8600483C1F410024CD0001BB
-:1037E000AF8D0048936C000930C600FF000644000E
-:1037F000318300FF246B0002010B4825013FC825DF
-:10380000AC5900008F67000C97440E1400F2282575
-:10381000AC4500048F450E1C8F670004936A0002BC
-:103820003084FFFF315800FFAFB800108F6F0014D5
-:10383000AFB100180E00008BAFAF00140A0001A654
-:1038400002002021AF6000040A00013EA3600002D4
-:103850000A00024600002021000090210A000170A9
-:10386000241400013C1280000A000195ACB2000C47
-:103870008F91000025240002A7440158263000083B
-:10388000320F1FFF0A0001F9AF8F0000AF40014C5B
-:103890001120002C000000008F590E10AF59014478
-:1038A0008F430E18240200403C1F1000AF43014814
-:1038B000A3400152A740015AAF400160A740015800
-:1038C000AF420154AF5F01780A0002278FBF004466
-:1038D000112000060000000097460E0830CC004082
-:1038E00015800002000000000000000D8F4D0178DF
-:1038F00005A0FFFE0000000097530E103C120500CB
-:10390000240E2000326AFFFF0152C025AF58014C3F
-:103910008F4F0E143C021000AF4F01448F500E1C0D
-:10392000AF500148A34001528F840038A740015A8C
-:10393000AF400160A7400158AF4E01540A00021584
-:10394000AF4201788F490E14AF4901448F430E1CDA
-:103950000A00028E240200403C0E20FF27BDFFE03B
-:103960003C1A80003C0F800835CDFFFDAFBF001C26
-:10397000AFB20018AFB10014AFB00010AF8F00406D
-:10398000AF4D0E000000000000000000000000002D
-:1039900000000000000000003C0C00FF358BFFFD24
-:1039A000AF4B0E003C0660048CC95000240AFF7F18
-:1039B0003C116000012A40243507380CACC7500088
-:1039C0008E24043824050009AF4500083083FFFF2A
-:1039D00038622F712450C0B3AF8000480E000068D9
-:1039E000AF80000052000001AE20442C0E000435D0
-:1039F0003C1180000E000ED9363000708F8A0040D6
-:103A00003C12080026523C88020088218E080000E3
-:103A10008F5F00003BF900013338000113000017ED
-:103A2000AF880030022048218D2700003C0F08009D
-:103A30008DEF006C3C0C08008D8C006800E8C02302
-:103A400001F828210000682100B8302B018D582191
-:103A5000016640213C010800AC25006C3C010800D7
-:103A6000AC2800688F4400003883000130620001F8
-:103A70001440FFED00E04021AF8700308E0C0000C5
-:103A80003C0508008CA5006C3C0408008C84006890
-:103A90000188302300A638210000102100E6402BC9
-:103AA000008218210068F8213C010800AC27006C56
-:103AB0003C010800AC3F00688F490100255900888F
-:103AC000AF990044AF890038AF4900208E0700004D
-:103AD000AF8700308F4D017805A0FFFE0000000089
-:103AE0008E0600003C0B08008D6B00743C0408003F
-:103AF0008C84007000C728230165F8210000102184
-:103B000003E5402B0082382100E8C8212409080081
-:103B10003C010800AC3F00743C010800AC39007067
-:103B2000AF49017893580108A398003E938F003E57
-:103B300031EE000115C000158F830038240E0D00F2
-:103B4000106E0019240F0F00106F001D0000000000
-:103B50009159000024180050332900FF1138000447
-:103B60003C1F4000AF5F01380A0002E70000000080
-:103B70000E00090E000000008F8A00403C1F40002C
-:103B8000AF5F01380A0002E700000000938D003E9D
-:103B900031AC0006000C51000E0000CE0152D821BD
-:103BA0000A0003438F8A00403C1B0800277B3D0826
-:103BB0000E0000CE000000000A0003438F8A004080
-:103BC0003C1B0800277B3D280E0000CE00000000B3
-:103BD0000A0003438F8A004090AA00018FAB0010B7
-:103BE0008CAC00103C0300FF8D680004AD6C00201D
-:103BF0008CAD001400E060213462FFFFAD6D002445
-:103C00008CA700183C09FF000109C024AD670028FB
-:103C10008CAE001C0182C82403197825AD6F000406
-:103C2000AD6E002C8CAD0008314A00FFAD6D001C5C
-:103C300094A900023128FFFFAD68001090A7000092
-:103C4000A5600002A1600004A167000090A300022B
-:103C5000306200FF00021982106000052405000197
-:103C60001065000E0000000003E00008A16A0001DA
-:103C70008CD80028354A0080AD7800188CCF00140D
-:103C8000AD6F00148CCE0030AD6E00088CC4002CDB
-:103C9000A16A000103E00008AD64000C8CCD001C9B
-:103CA000AD6D00188CC90014AD6900148CC80024D7
-:103CB000AD6800088CC70020AD67000C8CC20014F2
-:103CC0008C8300640043C82B132000070000000011
-:103CD0008CC20014144CFFE400000000354A008040
-:103CE00003E00008A16A00018C8200640A000399C5
-:103CF0000000000090AA000027BDFFF88FA9001C5B
-:103D0000A3AA00008FAE00003C0FFF808FA8001810
-:103D100035E2FFFF8CCD002C01C26024AFAC000067
-:103D2000A120000400E06021A7A000028FB80000DD
-:103D30008D2700040188182100A0582100C05021BF
-:103D4000006D28263C06FF7F3C0F00FF2CAD0001D4
-:103D500035EEFFFF34D9FFFF3C02FF00031930248A
-:103D6000000D1DC0010EC82400E2C02400C3702550
-:103D700003197825AD2E0000AD2F00048D450024D9
-:103D8000AFAE0000AD2500088D4D00202405FFFFDB
-:103D9000AD2D000C956800023107FFFFAD27001024
-:103DA0009166001830C200FF000219C25060000185
-:103DB0008D450034AD2500148D67000827BD00082F
-:103DC000AD27001C8C8B00CCAD2C0028AD20002C26
-:103DD000AD2B0024AD20001803E00008AD2000202A
-:103DE00027BDFFE0AFB20018AFB10014AFB00010B4
-:103DF000AFBF001C9098000000C088213C0D00FF60
-:103E0000330F007FA0CF0000908E000135ACFFFF84
-:103E10003C0AFF00A0CE000194A6001EA2200004D0
-:103E20008CAB00148E29000400A08021016C282492
-:103E3000012A40240080902101052025A6260002A9
-:103E4000AE24000426050020262400080E0000767B
-:103E500024060002924700002605002826240014AC
-:103E600000071E000003160324060004044000039C
-:103E70002403FFFF965900023323FFFF0E00007654
-:103E8000AE230010262400248FBF001C8FB2001820
-:103E90008FB100148FB00010240500030000302102
-:103EA0000A00008027BD002027BDFFD8AFB1001C4D
-:103EB000AFB00018AFBF002090A80000240200019E
-:103EC0008FB0003C3103003F008088211062001455
-:103ED0008FAA0038240B0005506B0016AFAA001003
-:103EE00000A0202100C028210E0003DC02003021A8
-:103EF000922400BC308300021060000326060030CC
-:103F0000ACC0000024C600048FBF00208FB1001C8D
-:103F10008FB0001800C0102103E0000827BD002862
-:103F2000014038210E00035AAFB000100A000420EF
-:103F3000000000000E0003A1AFB000140A0004202E
-:103F4000000000003C02000A034218213C04080063
-:103F500024843D6C2405001A000030210A000080F2
-:103F6000AF8300543C038000346200708C48000032
-:103F700000A0582100C04821308A00FFAF880030DF
-:103F80008F4401780480FFFE3C0C80003586007071
-:103F90008CC500003C0308008C6300743C180800CA
-:103FA0008F18007000A82023006468210000C82139
-:103FB00001A4782B0319702101CF60213C01080076
-:103FC000AC2D00743C010800AC2C00708F480E141E
-:103FD000AF480144AF47014CA34A0152A74B0158D7
-:103FE0009346010830C5000854A00001352910008F
-:103FF000934B090024070050316A00FF1147000766
-:10400000000000008F450E1CAF450148AF49015428
-:104010003C09100003E00008AF490178934D010806
-:1040200031A800081100001000000000934F0108A3
-:1040300031EE001051C00001352900083C04080091
-:1040400090843DD0A34401508F4309A4AF4301485D
-:104050008F4209A0AF420144AF4901543C0910000E
-:1040600003E00008AF4901783C1908008F393D8C06
-:10407000333800085700FFF1352900080A0004739F
-:104080000000000024070040AF470814AF400810AC
-:104090008F4209448F4309508F4409548F45095C6E
-:1040A0008F46094CAF820064AF830050AF84004C50
-:1040B000AF85005C03E00008AF860060934601090D
-:1040C00030C5007F000518C0000521400083102185
-:1040D00003E00008244200883C09080091293D9132
-:1040E00024A800023C05110000093C0000E830252E
-:1040F00000C5182524820008AC83000003E00008F6
-:10410000AC8000049347010B8F4A002C974F09089D
-:104110003C18000E0358482131EEFFFF000E41C04D
-:10412000AF48002C97430908952C001A00804021C5
-:1041300024030001318BFFFFAC8B00008D2D001C90
-:1041400000A0582100C06021AC8D00048D24002007
-:1041500030E70040AD04000891220019304400030C
-:10416000108300482885000214A000622406000283
-:104170001086005624190003109900660000000004
-:1041800010E0003A000000003C07080094E73D867C
-:1041900024E20001934F0934934709219525002A11
-:1041A00031EE00FF000E488230ED00FF9787005887
-:1041B00000093600000D1C003044FFFF00C310252D
-:1041C0000044C02500A778213C1940000319702540
-:1041D000000F4C00AD090004AD0E0000934D092006
-:1041E0003C03000625090014000D360000C32025FD
-:1041F000AD0400088F59092C24E5000130A27FFF8F
-:10420000AD19000C8F580930A782005825020028EC
-:10421000AD1800108F4F0938AD0F0014AD2B0004FE
-:104220008F4E0940AD2E0008934D09373C0508001C
-:1042300090A53D908F4409488F46094031A700FF63
-:1042400000EC1821008678230003C7000005CC008D
-:104250000319602531E8FFFC01885825AD2B000CBF
-:10426000AD20001003E00008AF4A002C3C0D080010
-:1042700095AD3D863C0E080095CE3D800A0004C9F0
-:1042800001AE10213C05080094A53D8A3C060800BB
-:1042900094C63D803C18080097183D7C952E00245C
-:1042A00000A6782101F86823000E240025A2FFF261
-:1042B0000082182524190800AD03000CAD19001464
-:1042C000AD0000100A0004C425080018952600243B
-:1042D000952500280006C40000057C00370E8100EB
-:1042E00035ED0800AD0E000CAD0D00100A0004C441
-:1042F000250800141480FFA200000000952400246B
-:104300000004140034430800AD03000C0A0004C488
-:10431000250800103C03080094633D8A3C05080012
-:1043200094A53D803C06080094C63D7C9539002448
-:1043300095380028006520210086782300196C003C
-:104340000018740025E2FFEE01C2202535A381008C
-:1043500024190800AD03000CAD040010AD190018BD
-:10436000AD0000140A0004C42508001C03E0000886
-:10437000240201F427BDFFE8AFB00010AFBF001466
-:104380000E0000600080802124050040AF45081425
-:104390008F8300508F84004C8F85005C0070182143
-:1043A0000064102318400004AF830050AF63005432
-:1043B0008F660054AF86004C1200000C0000000015
-:1043C0008F440074936800813409FA002D070007B8
-:1043D00010E0000500891021936C0081240B01F48A
-:1043E000018B500401441021AF62000C8F4E095C18
-:1043F00001C5682319A000048FBF00148F4F095C0A
-:10440000AF8F005C8FBF00148FB000100A000062F5
-:1044100027BD00188F8400648F8300508F82004C6A
-:10442000AF640044AF63005003E00008AF62005483
-:104430003C038000346200708C43000027BDFFF80D
-:10444000308700FF30A900FF30C800FFAF83003085
-:104450008F4401780480FFFE3C02800034590070D4
-:104460008F380000A3A700033C0708008CE7007406
-:104470008FAC00003C0608008CC600700303782354
-:104480003C0E7FFF00EFC82135CDFFFF000050211B
-:10449000018D282400CA1821000847C0032F202BB3
-:1044A00000A810250064C021AFA200003C01080054
-:1044B000AC3900743C010800AC380070934F010A1D
-:1044C000A3A000023C0E80FFA3AF00018FAC000050
-:1044D000312B007F35CDFFFF018D4824000B5600A6
-:1044E000012A4025240730002406FF803C051000E7
-:1044F00027BD0008AF48014CAF470154A740015801
-:10450000A346015203E00008AF45017827BDFFE84C
-:10451000AFBF0014AFB000108F6500743C06800080
-:10452000309000FF00A620250E000060AF640074EC
-:1045300093630005346200080E000062A362000568
-:10454000020020218FBF00148FB000102405000549
-:10455000240600010A00057027BD001827BDFFE0F2
-:104560003C038000AFB00010AFBF0018AFB1001423
-:10457000346200708C470000309000FF30A800FFCC
-:10458000AF8700308F4401780480FFFE3C18800024
-:10459000371100708E2F00003C0D08008DAD0074A7
-:1045A0003C0A08008D4A007001E7702301AE282103
-:1045B0000000582100AE302B014B48210126382144
-:1045C0003C010800AC250074000088213C01080073
-:1045D000AC2700701100000F000000008F62007413
-:1045E0002619FFFF3208007F0002FE0233E5007F3C
-:1045F00015000006332200FF2407FF800207202653
-:1046000024A3FFFF00838025320200FF00408021A9
-:10461000241110080E000060000000008F490818E7
-:104620003125000414A0FFFD3218007F001878C067
-:104630000018714001CF682125AC0088AF4C0818E4
-:10464000274A09808D4B0020AF4B01448D46002442
-:10465000AF460148A35001500E000062A740015828
-:10466000022010218FBF00188FB100148FB00010EE
-:1046700003E0000827BD002027BDFFE8308400FFCD
-:10468000AFBF00100E0005BB30A500FF8F830050A8
-:104690008FBF0010344500402404FF903C021000FE
-:1046A00027BD0018AF43014CA3440152AF4501544C
-:1046B00003E00008AF4201789343093E30620008EE
-:1046C0001040000D3C0901013528080AAC880000A3
-:1046D0008F470074AC8700043C06080090C63D90EC
-:1046E00030C5001050A00006AC8000088F6A006042
-:1046F000AC8A00082484000C03E00008008010212C
-:104700000A0006222484000C27BDFFE8AFBF001476
-:10471000AFB000109346093F00A05021000528804B
-:104720000085382330C200FF240300063C0908003E
-:1047300095293D8624E8FFD824050004104300375E
-:10474000240600029750093C3C0F02040006340086
-:10475000320EFFFF01CF6825AC8D0000934C093E5F
-:10476000318B0020116000080000000093430936DF
-:104770003C020103345F0300307900FF033FC02592
-:1047800024050008AC980004934309349359092187
-:104790000005F882306200FF0002C082332F00FF64
-:1047A00000186E00000F740001AE602501892025FD
-:1047B0003C09400000898025ACF0FFD893430937BD
-:1047C0008F4F09488F580940306200FF004AC821C6
-:1047D000033F702101F86023000E6F0001A65025F1
-:1047E0003185FFFC001F58800145482501683821AC
-:1047F000AD0900200E00006024F00028240400040D
-:104800000E000062A364003F020010218FBF00145D
-:104810008FB0001003E0000827BD00180A0006351D
-:104820002406001227BDFFD024090010AFB60028CF
-:10483000AFB50024AFB40020AFB10014AFB000108A
-:104840003C010800A0293D90AFBF002CAFB3001C75
-:10485000AFB2001897480908309400FF3C02000EE0
-:104860003107FFFF000731C0AF46002C974409080D
-:104870009344010B30B500FF0342802130830030A8
-:104880000000B0211060012500008821240C0004E4
-:104890003C010800A02C3D90934B093E000B5600B4
-:1048A000000A2E0304A0016000000000AF40004891
-:1048B000934F010B31EE002011C0000600000000F4
-:1048C0009358093E00189E00001396030640018984
-:1048D000000000009344010B30830040106000038F
-:1048E0008F9300508F8200502453FFFF9347093E5F
-:1048F00030E6000814C000022412000300009021DA
-:104900009619002C93580934934F0937A7990058EA
-:10491000330C00FF31EE00FF024E6821000D58807D
-:10492000016C5021015140213C010800A4283D8622
-:104930009205001830A900FF010918213C01080068
-:10494000A4233D88921100181620000200000000E8
-:104950000000000D3C010800A4233D8A3C01080032
-:10496000A4203D803C010800A4203D7C935F010B06
-:104970003063FFFF33F00040120000022464000A9D
-:104980002464000B3091FFFF0E00009E02202021C6
-:104990009358010B3C08080095083D8A00402021EF
-:1049A00000185982316700010E00049A010728217E
-:1049B000934C010B8F4B002C974E09083C0F000EB7
-:1049C000034F402131CDFFFF000D51C0AF4A002CF5
-:1049D000974309089505001A004038212404000176
-:1049E00030A9FFFFAC4900008D06001C00404821A3
-:1049F000318A0040AC4600048D020020ACE2000881
-:104A00009103001930630003106400EC2879000260
-:104A100017200118241000021070010C241F00033D
-:104A2000107F011E00000000114000DE00000000A9
-:104A30003C09080095293D8625220001935F093431
-:104A4000934E09219504002A33F900FF0019C08212
-:104A500031CF00FF978E005800184600000F6C0001
-:104A6000010D80253045FFFF02051025008E5021E5
-:104A70003C03400000433025000A6400ACEC000415
-:104A8000ACE60000935F09203C19000624EC0014FA
-:104A9000001FC60003197825ACEF00088F48092CC9
-:104AA00025CD000131A57FFFACE8000C8F50093007
-:104AB000A785005824E80028ACF000108F4409387E
-:104AC00001008021ACE40014AD9300048F53094031
-:104AD000AD930008934A09373C19080093393D907B
-:104AE0008F4309488F460940314200FF0052F821A8
-:104AF00000667023001F7F000019C40001F82825FC
-:104B000031CDFFFC00AD2025AD84000CAD80001040
-:104B1000AF4B002C934B093E317300081260000D1F
-:104B20003C06010134CC080AACEC00288F53007419
-:104B3000AD1300043C0B0800916B3D9031670010F1
-:104B400050E00003AD0000088F6A0060AD0A000865
-:104B50002510000C12C0003D000000009343093FE7
-:104B60002416000624060004306200FF105600C917
-:104B7000240700029758093C3C0F0204330DFFFF45
-:104B800001AF4025AE0800009345093E30A4002047
-:104B90001080000800000000935309363C0B01030D
-:104BA000357F0300327900FF033F7025AE0E00040D
-:104BB00024060008934F093493480921312AFFFF46
-:104BC00031ED00FF000D1082310300FF0002B6003E
-:104BD00000032C0002C56025018A98250012208060
-:104BE0003C0940000204502302695825AD4BFFD810
-:104BF000935F09378F4F09488F58094033F900FFF9
-:104C0000033270210006B08201D6682100074400FB
-:104C100001F82823000D1F000068302530A2FFFC9A
-:104C20002547FFD800C26025001680800207482172
-:104C3000ACEC0020253000280E0000602412000497
-:104C4000A372003F0E000062000000009347010BBA
-:104C500030F20040124000053C1900FF8E180000A1
-:104C6000372EFFFF030E3024AE0600000E0000C7F3
-:104C7000022020213C10080092103D9032110003C8
-:104C80001220000F02A028218F8900502533000137
-:104C9000AF930050AF7300508F6B00540173F82333
-:104CA0001BE00002026020218F640054AF640054B6
-:104CB0008F4C0074258401F4AF64000C02A02821FD
-:104CC00002802021A76000680E0005BB3C14100084
-:104CD0008F85005034550006AF45014C8F8A00483F
-:104CE0008FBF002C8FB3001C25560001AF960048E3
-:104CF0008FB20018A34A01528FB60028AF55015455
-:104D00008FB10014AF5401788FB500248FB4002008
-:104D10008FB0001003E0000827BD00309358093E13
-:104D200000189E000013960306420036241100026C
-:104D300093440923308300021060FEDD8F860060FB
-:104D40008F82005014C2FEDA000000000E000060E6
-:104D5000000000009369003F24070016312800FF7F
-:104D60001107000C240500083C0C0800918C3D90B4
-:104D7000358B00013C010800A02B3D90936A003F59
-:104D8000314300FF10650065240D000A106D005EC0
-:104D90002402000C0E000062000000000A000690D1
-:104DA000000000003C09080095293D863C0A0800E7
-:104DB000954A3D800A0006F3012A10213C090800AB
-:104DC00095293D8A3C04080094843D803C060800F7
-:104DD00094C63D7C95030024012410210046F8234D
-:104DE0000003CC0027F0FFF20330C025240F080099
-:104DF000ACF8000CACEF0014ACE000100A0006EEBA
-:104E000024E700183C010800A0313D90935F093E63
-:104E10002416000133F900201720FEA524110008F4
-:104E20000A000690241100048F6E00848F4D094003
-:104E300011A0FE9EAF8E0050240F00143C0108000C
-:104E4000A02F3D900A00068F00000000950E002460
-:104E5000950D0028000E6400000D2C00358981009E
-:104E600034A60800ACE9000CACE600100A0006EE1F
-:104E700024E700141460FEEC0000000095020024FA
-:104E800000021C0034640800ACE4000C0A0006EECA
-:104E900024E700100A000741240700123C02080022
-:104EA00094423D8A3C06080094C63D803C030800BD
-:104EB00094633D7C95100024951900280046F82144
-:104EC00003E3C02300106C0000197400270FFFEEED
-:104ED00001CF282535AC8100ACEC000CACE500100E
-:104EE00024070800AD2700182527001C0A0006EE3D
-:104EF000AD2000148F7F004CAF7F00548F79005499
-:104F00000A000699AF790050A362003F0E000062CC
-:104F1000000000000A0006900000000024020014B7
-:104F20000A000827A362003F27BDFFE8308400FF86
-:104F3000AFBF00100E0005BB30A500FF9378007EC8
-:104F40009379007F936E00809368007A332F00FF7F
-:104F500000186600000F6C0031CB00FF018D482562
-:104F6000000B52008FBF0010012A3825310600FFC8
-:104F70003444700000E628252402FF813C03100021
-:104F800027BD0018AF45014CAF440154A342015264
-:104F900003E00008AF43017827BDFFD8AFB2001887
-:104FA000AFB10014AFB00010AFBF0020AFB3001C12
-:104FB00093420109308600FF30B000FF000618C29E
-:104FC000320400023071000114800005305200FFED
-:104FD0009367000530E5000810A0000D30C80010F0
-:104FE000024020210E0005A70220282124040001F0
-:104FF0008FBF00208FB3001C8FB200188FB1001438
-:105000008FB000100080102103E0000827BD0028A9
-:105010001500003200000000934301090000282120
-:105020003062007F000220C00002F94003E49821B2
-:1050300026790088033B98218E7800248E6F000823
-:10504000130F0046000000008F6400842418000243
-:105050000004FD8233F900031338007C00000000D7
-:1050600093660083934A0109514600043205007C8F
-:1050700010A00060000000003205007C14A0005366
-:105080000240202116200006320400018E7F0024F9
-:105090008F59010417F9FFD60000202132040001C6
-:1050A0001080000A024020218F4209408F93006443
-:1050B00010530006000000000E00066D022028219B
-:1050C0008F430940AF630044024020210E000602D6
-:1050D000022028210A000860240400013C0908007D
-:1050E0008D290064252600013C010800AC260064DF
-:1050F00016000012000000008F6D00843C0E00C0FE
-:1051000001AE602415800005024020210E00082E0B
-:10511000022028210A00086024040001240500045C
-:105120000E00057024060001024020210E00082E0A
-:10513000022028210A000860240400010E0000411A
-:1051400024040001936B007D020B50250E000062C9
-:10515000A36A007D0A0008A38F6D00848F66007427
-:105160008F4801048E67002400064E021507FFB623
-:105170003126007F936B008326440001308A007F34
-:1051800011460043316300FF5464FFB08F64008414
-:105190002645000130B1007F30A200FF1226000436
-:1051A00024050001004090210A0008762411000126
-:1051B000240FFF80024F702401CF9026324200FF5F
-:1051C000004090210A000876241100010E00066DAF
-:1051D00002202821321800301300FFAA321000826A
-:1051E000024020210E0005A7022028210A000860A5
-:1051F000240400018F6E00743C0F8000240500031E
-:1052000001CF9025AF7200749371008324060001D2
-:105210000E000570322400FF0E000041240400013E
-:10522000936D007D020D60250E000062A36C007D71
-:105230003C0B08008D6B0054257000013C010800F8
-:10524000AC3000540A000860240400018F68007428
-:105250003C0980002405000401093825AF6700746B
-:1052600093630083240600010E000570306400FF84
-:105270000E000041240400019362007D0202982583
-:105280000E000062A373007D0A0008602404000180
-:10529000324D008039AC0080546CFF6C8F64008408
-:1052A0000A0008C92645000127BDFFC83C0A0008BE
-:1052B000AFBF0030AFB5002CAFB40028AFB30024AF
-:1052C000AFB20020AFB1001CAFB00018034AD82124
-:1052D00024090040AF490814AF4008108F42094428
-:1052E0008F4309508F4609548F47095C8F48094CFA
-:1052F000934401089345010BAF820064308400FFA2
-:1053000030A500FFAF830050AF86004CAF87005C34
-:105310000E00084AAF8800601440017D8FBF003046
-:10532000A7600068934D0900240B00503C1508004D
-:1053300026B53D4831AC00FF3C12080026523D58CE
-:10534000118B0003000000000000A8210000902144
-:10535000935101098F9F005024040010322E007FCA
-:10536000000E68C0000E6140018D282124B4008821
-:10537000AF5408188F4901048F4A09A43C0B000E52
-:10538000034BC021012A10233C010800AC223D6CD4
-:105390008F4309583C010800A0243D909747090815
-:1053A000007F30233C010800AC263D7030E8FFFF51
-:1053B0000008C9C03C010800AC3F3D94AF59002C27
-:1053C000974209089710002C8EB10000930F001827
-:1053D00003749821A7900058AF9300440220F80965
-:1053E00031F000FF304E000215C001B2304F000115
-:1053F00011E0014F000000009343093E30660008B1
-:1054000014C00002241400030000A0218F5809A436
-:10541000241300013C010800AC383D98934F093437
-:105420009351093731EC00FF322E00FF028E6821C4
-:10543000000D288000AC5021015058213C0108008B
-:10544000A42B3D883C010800A42A3D8693490934D9
-:10545000312200FF02022021249000103C010800AC
-:10546000A4303D84240700068F9F00503C010800B3
-:10547000AC273D8C8F88005C8F5909580000802133
-:10548000011F282304A00149033F20230480014772
-:1054900000A4302B10C00149000000003C010800AE
-:1054A000AC253D708E4200000040F809000000006D
-:1054B00030430002146000F80040882130440001AD
-:1054C000548000108E4200043C0908008D293D7470
-:1054D0003C0AC000012A8025AF500E008F45000015
-:1054E00030AB00081160FFFD00000000974D0E0872
-:1054F00024100001A78D003C8F4C0E04AF8C0034AB
-:105500008E4200040040F8090000000002228825B5
-:10551000322E000215C00180000000003C09080086
-:1055200095293D7C3C06080094C63D883C0A08004D
-:10553000954A3D7E3C1908008F393D740126602153
-:105540003C1808008F183D983C03080094633D9276
-:10555000018A20218F4E09400329F821248F00025F
-:1055600003E32821031968213C010800A42C3D8A8B
-:10557000AF8E00643C010800AC2D3D983C01080052
-:10558000A4253D800E00009E31E4FFFF8F87004878
-:10559000004020213C010800A0273D918E420008D8
-:1055A00024E80001AF8800480040F809000000002E
-:1055B0009344010B8F4C002C974A09083C0B000EBA
-:1055C000034B40213149FFFF000919C08F8B005068
-:1055D000AF43002C974309089506001A0040382174
-:1055E000308A004030DFFFFFAC5F00008D19001CE7
-:1055F00000404821AC5900048D180020AC58000828
-:10560000910F001931E30003107300F00000000057
-:10561000286200021440010924050002106500FD03
-:10562000240D0003106D010D00000000114000D991
-:10563000000000003C0A0800954A3D862542000112
-:10564000934D093493580921950E002A31A300FF88
-:1056500000032082331F00FF9798005800047E004B
-:10566000001FCC0001F940253049FFFF010910253A
-:1056700001D830213C0540000045502500066C0053
-:10568000ACED0004ACEA0000934309203C040006A2
-:1056900024ED00140003FE0003E4C825ACF9000863
-:1056A0008F49092C270F000131EE7FFFACE9000C78
-:1056B0008F480930A78E005824E90028ACE8001074
-:1056C0008F45093801204021ACE50014ADAB000442
-:1056D0008F420940ADA20008934B09373C1F0800D8
-:1056E00093FF3D908F4309488F4A0940316600FF80
-:1056F00000D42021006A78230004C700001FCC00DA
-:105700000319282531EEFFFC00AE1025ADA2000CD8
-:10571000ADA00010AF4C002C934C093E318B00081B
-:105720005160000F8E58000C3C06010134CA080A73
-:10573000ACEA00288F4B0074AD2B00043C0C080031
-:10574000918C3D903187001050E00003AD2000089F
-:105750008F620060AD2200082528000C8E58000CD6
-:105760000300F809010020213C19080097393D8AFF
-:105770003C1F080097FF3D7E033F782125E900028A
-:105780000E0000C73124FFFF3C0E08008DCE3D6C9B
-:105790003C0808008D083D7401C828233C0108001E
-:1057A000AC253D6C14A00006000000003C0308007E
-:1057B0008C633D8C346400403C010800AC243D8C7B
-:1057C000120000708F8C00448F470E108F900044A1
-:1057D000AE0700208F4D0E18AE0D00243C100800BF
-:1057E00096103D800E000060000000002402004082
-:1057F000AF4208148F8600508F8A004C00D01821C9
-:10580000006A582319600004AF830050AF6300544E
-:105810008F650054AF85004C1200000C00000000A2
-:105820008F440074936800813409FA002D0E00073C
-:1058300011C0000500891821937F0081241901F40B
-:1058400003F9780401E41821AF63000C8F44095C6C
-:105850008F83005C0083C0231B0000030000000056
-:105860008F50095CAF90005C0E00006200000000E9
-:105870008F8C00508E4700103C010800AC2C3D94EA
-:1058800000E0F809000000003C0D08008DAD3D6C03
-:1058900055A0FEF5240700068F45002497590908F6
-:1058A0008F8B00648F9400503C0F001F978200582C
-:1058B0008F8600548F93004C3328FFFF35E9FF801B
-:1058C00000A95024000871C032320100AF4E0024FC
-:1058D000A4C2002CAF4A0024AF6B0044AF74005048
-:1058E000AF73005416400080323800105700008615
-:1058F0008EA40004322300405460001B8EB10008C7
-:105900008EB0000C0200F809000000008FBF0030CC
-:105910008FB5002C8FB400288FB300248FB20020E5
-:105920008FB1001C8FB0001803E0000827BD0038BD
-:10593000934701098F8800380007FE0003E8C82557
-:10594000AF5900808F5809A08F5309A4AFB8001039
-:10595000AF580E148FB40010AF540E10AF530E1C7E
-:105960000A000962AF530E180220F8090000000077
-:105970008EB0000C0200F809000000000A000AA81E
-:105980008FBF0030A5800020A59300220A000A5B8B
-:10599000AD9300243C09080095293D863C0608008B
-:1059A00094C63D800A0009F4012610213C0108003C
-:1059B000AC203D700A00098E8E4200003C010800B8
-:1059C000AC243D700A00098E8E4200003C030800A2
-:1059D00094633D8A3C04080094843D803C1F080089
-:1059E00097FF3D7C951800240064C821033F78236D
-:1059F00000186C0025EEFFF201AE2825AC45000C26
-:105A000024020800ACE20014ACE000100A0009EF28
-:105A100024E70018950600249509002800062400B4
-:105A200000091C00349F810034790800ACFF000C91
-:105A3000ACF900100A0009EF24E700141460FEFB23
-:105A4000000000009518002400187C0035EE0800C6
-:105A5000ACEE000C0A0009EF24E700103C07080038
-:105A600094E73D803C04080094843D8A3C03080090
-:105A700094633D7C95190024951800280087F8212F
-:105A800003E378232407080000192C0000186C0099
-:105A900025EEFFEE01AE302534A28100AD270018BF
-:105AA0002527001CAD22000CAD2600100A0009EFCE
-:105AB000AD20001493520109000028210E000602B7
-:105AC000324400FF8FBF00308FB5002C8FB4002808
-:105AD0008FB300248FB200208FB1001C8FB000184C
-:105AE00003E0000827BD0038935F010933E400FF9D
-:105AF0000E00066D00002821323800105300FF7E92
-:105B0000322300408EA400040080F8090000000049
-:105B10000A000AA2322300401200FF5F00000000CA
-:105B20008F540E148F920044AE5400208F530E1CDD
-:105B30000A000A8AAE5300248F82001C0080402194
-:105B40003C0401009047008530E30020106000090C
-:105B5000000000003C0708008CE73D948F8300188C
-:105B600000E32023048000089389000414E3000369
-:105B70000100202103E00008008010213C04010006
-:105B800003E00008008010211120000B006738237B
-:105B90008F8C002024090034918B00BC316A0002F4
-:105BA000514000012409003000E9682B15A0FFF1E5
-:105BB0000100202100E938232419FFFC00B9C0248A
-:105BC00000F9782400F8702B15C0FFEA01E82021C5
-:105BD00030C200030002182314C000123069000311
-:105BE0000000302100A9702101C6682100ED602B62
-:105BF0001180FFE03C0401002D2F00010006482B1E
-:105C00000105382101E9302414C0FFDA24E4FFFC47
-:105C10002419FFFC00B9C0240308202103E0000878
-:105C2000008010218F8B002024060004916A00BCA4
-:105C3000314400041480FFEC00A970210A000B5EBF
-:105C40000000302127BDFFE8AFBF00108F460100E4
-:105C5000934A01093C1F08008FFF00902407FF8032
-:105C6000314F00FF31E8007F0008614003E6C821A2
-:105C7000032CC02127090120012770243C010800C2
-:105C8000A02F3DD0AF4E080C3C0D08008DAD00900C
-:105C90003C0400803482000301A65821016C1821C5
-:105CA0002465012030AA007801424025AF48081C35
-:105CB0003C1F08008FFF00908F88004003E6C02142
-:105CC0003319000703074824033A7821AF49002815
-:105CD00025E909C0952E00023C0D08008DAD008C11
-:105CE0003C0A08008D4A009031CC3FFF01A61821E4
-:105CF000000C5980006B282100A72024AF44002C01
-:105D0000952200023C1F08008FFF008C9107008540
-:105D100030593FFF03E678210019C1800146702108
-:105D200001F8682131CC007F31AB007F019A282136
-:105D3000017A50213C03000C3C04000E00A32821F2
-:105D40000144102130E6002027470980AF82002C53
-:105D5000AF88001CAF890024AF85002010C000066A
-:105D6000AF8700288D0200508CA4010C0044302322
-:105D700018C0007700000000910C0085240DFFDFA3
-:105D8000018D3824A10700858F8B001C8F8900248A
-:105D90008F8700288D65004CAF850018912F000D6E
-:105DA00031EE002011C0001700000000240900019E
-:105DB000A3890004AF80000C8CE400248F85000CC4
-:105DC000240A0008AF800008AF8000103C010800E2
-:105DD000A42A3D7E3C010800A4203D920E000B3217
-:105DE000000030218F8500248FBF0010AF82001487
-:105DF00090A8000D27BD00180008394203E00008F4
-:105E000030E20001913F00022418000133F900FF45
-:105E10000019218210980039240800021088005BC4
-:105E20008F86002C8CE5002414A0001B8F9F00207F
-:105E300091220000240A00053046003F10CA0047A6
-:105E4000240400018F860008A3840004AF8600109C
-:105E5000AF86000C8CE400248F85000C240A000817
-:105E60003C010800A42A3D7E3C010800A4203D928C
-:105E70000E000B32000000008F8500248FBF001041
-:105E8000AF82001490A8000D27BD00180008394209
-:105E900003E0000830E200018CF800088CF90024CF
-:105EA0008FEE00C4A38000048CE40024AF8E000CAD
-:105EB0008F85000C8F86000803197823240A0008B8
-:105EC000AF8F00103C010800A42A3D7E3C01080071
-:105ED000A4203D920E000B32000000008F850024AC
-:105EE0008FBF0010AF82001490A8000D27BD0018CE
-:105EF0000008394203E0000830E20001912300006D
-:105F00003062003F104400278F8500208CE400247D
-:105F100014800021000000008D2E00183C187FFF27
-:105F20008F850020370FFFFF01CF1824AF830008B3
-:105F30008F9F00088CA8008403E8C82B172000025C
-:105F400003E020218CA400840A000BEDAF8400083C
-:105F50008CA3010C0A000BCBAF8300188D2C00180A
-:105F60008F8600083C0D7FFF8F89002035A3FFFF3F
-:105F70000183582424040001AF8B0010AD2000CC15
-:105F8000A38400040A000BF9AF86000C8CCA00142D
-:105F90000A000BEDAF8A00088CA300C80A000C3081
-:105FA000AF8300088F84002C8CAC00648C8D0014AF
-:105FB000018D582B11600004000000008CA20064C9
-:105FC0000A000C30AF8200088C8200140A000C30EA
-:105FD000AF8200088F85000C27BDFFE0AFBF00181F
-:105FE000AFB1001414A00007AFB000108F860024DA
-:105FF0002402000590C400003083003F106200B608
-:106000008F8400208F91000800A080218F8C0028B1
-:106010003C0508008CA53D708D8B000431663FFF68
-:1060200000C5502B5540000100C02821938D00046D
-:1060300011A0007300B0F82B8F98002024040034C6
-:10604000930F00BC31EE000251C000012404003067
-:1060500000A4C82B172000D10000000000A42823B2
-:1060600000B0F82B3C010800A4243D7C17E0006838
-:10607000020020213C0308008C633D6C0083102B40
-:1060800054400001008018218F8800243C01080042
-:10609000AC233D74000048219104000D30830020A2
-:1060A000506000018F490E188F8300140123382B94
-:1060B00010E00059000000003C0408008C843D748E
-:1060C00000895821006B502B114000560090602B26
-:1060D0000069302300C020213C010800AC263D743B
-:1060E00012000003241FFFFC1090008A32270003D7
-:1060F000009FC8243C010800AC393D743C010800F5
-:10610000A4203D928F84000C120400078F8300208E
-:10611000AF910008020020218C7100CCAF90000CE0
-:1061200026300001AC7000CC3C0208008C423D746B
-:106130008F8A0010240700180082202301422823A0
-:10614000AF84000C10800002AF85001024070010FF
-:106150008F86001C3C010800A0273D9024070040CA
-:1061600090CC0085318B00C0116700408F8D0014EA
-:1061700014A0001500002021934A01098F420974E0
-:10618000314500FF0002260224A300013090007F69
-:106190003071007F1230007A2407FF80A0C3008393
-:1061A0003C0908008D293D8C8F880024240D0002B5
-:1061B000352C00083C010800A02D3DD13C01080011
-:1061C000AC2C3D8C24040010910E000D31C6002033
-:1061D00010C0000500801821240800013C010800BF
-:1061E000AC283D74348300018FBF00188FB10014B8
-:1061F0008FB000100060102103E0000827BD0020D0
-:106200003C010800A4203D7C13E0FF9A02002021FD
-:106210000A000C8100A020213C0408008C843D74FD
-:106220000090602B1180FFAE000000003C0F0800C2
-:1062300095EF3D7C01E4702101C6682B11A0000799
-:106240002C8200043C1F60008FF954043338003F57
-:106250001700FFE5240300422C8200041040FFA039
-:10626000240300420A000CDF8FBF0018152DFFC069
-:10627000000000008CDF00743C0380002405FF80D8
-:1062800003E3C825ACD9007490D80085240E00041F
-:1062900024040010330F003F01E54025A0C800850D
-:1062A0008F8800243C010800A02E3DD1240300016A
-:1062B0009106000D30C900201520000300000000E9
-:1062C0003C0308008C633D743C010800AC233D6C2A
-:1062D0000A000CD6000000008F8700108C88008414
-:1062E00000E8282B14A0000200E088218C91008493
-:1062F00024090001A38900048F440E1802202821DC
-:106300000E000B3202203021022080210A000C678F
-:10631000AF82001400071823306600033C01080018
-:10632000A4263D92122000058F8C0020918B00BC8A
-:10633000316A00041540001524CD00043C0F08000C
-:1063400095EF3D9201E4702100AE302B50C0FF6EFE
-:106350008F84000C2C85000514A0FFA324030042A9
-:106360003098000317000002009818232483FFFCD4
-:106370003C010800AC233D740A000CA3000000009F
-:1063800000A758240A000CCB016718263C0108001E
-:10639000A42D3D920A000D33000000003C010800CE
-:1063A000AC203D740A000CDE240300428F830010F1
-:1063B00014600007000010218F88002424050005C8
-:1063C0009106000030C400FF1085000300000000AB
-:1063D00003E0000800000000910A0018314900FFA6
-:1063E000000939C214E0FFFA8F85001C3C04080044
-:1063F00094843D7C3C0308008C633D943C19080068
-:106400008F393D743C0F080095EF3D920064C02128
-:106410008CAD00540319702101CF6021018D5823E8
-:106420001960001D00000000910E001C8F8C002CD4
-:10643000974B0E1031CD00FF8D850004016D302388
-:106440008D88000030CEFFFF000E510000AAC82149
-:106450000000382101072021032A182B0083C021C6
-:10646000AD990004AD980000918F000A01CF68211A
-:10647000A18D000A8F88002C974B0E12A50B0008E7
-:10648000950A003825490001A50900389107000D3B
-:1064900034E60008A106000D03E00008000000003B
-:1064A00027BDFFE0938700048F8F00248FAD001479
-:1064B0003C0E7FFF8F89000C35C8FFFFAFBF001C6B
-:1064C000AFB0001801A8182491EA000D000717C00A
-:1064D0003C1FBFFF006258252D2E00018F90001831
-:1064E00037F9FFFF3C1808008F183D943C0F080057
-:1064F00095EF3D8A01796824000E47803C07EFFF45
-:106500003C05F0FF01A818253149002034E2FFFFC7
-:1065100034ACFFFF0310582327A500102406000207
-:1065200025EA000200621824008080211520000264
-:10653000000040218F480E1CA7AA001205600037FA
-:106540002407000030FF00FF001FCF008F8B001CCE
-:1065500000793825AFA70014916F00853C0808002A
-:1065600091083D913C18DFFF31EE00C0370AFFFF74
-:10657000000E182B3C1F080097FF3D8400EA68249A
-:10658000A3A800110003174001A248258FB90010ED
-:10659000AFA900143C0A0800914A3D93A7BF00161A
-:1065A0008FA80014032CC0243C0B01003C0F0FFFEC
-:1065B000030B18253147000335EEFFFF010C68245B
-:1065C00000071600006EF8243C09700001A2C825DF
-:1065D00003E95825AFB90014AFAB00100E000076E8
-:1065E000A3A000158F8C0024260200089186000DC0
-:1065F00030C40020108000068FBF001C3C0508003E
-:1066000094A53D8024B0FFFF3C010800A4303D80EC
-:106610008FB0001803E0000827BD00208F980014F9
-:106620000118502B5540FFC7240700010A000DB682
-:1066300030FF00FF9382000427BDFFE0AFBF0018CA
-:106640001040000F008050218F880024240B00058B
-:106650008F890008910700008F8400200100282105
-:1066600030E3003F8F86002C106B000800003821BB
-:10667000AFA900100E00040EAFAA0014A3800004FE
-:106680008FBF001803E0000827BD00208D190018F7
-:106690003C0F08008DEF3D748F9800103C027FFF87
-:1066A0008D080014345FFFFF033F682401F8702158
-:1066B00001AE602301883821AFA900100E00040E3E
-:1066C000AFAA00140A000E04A38000048F870024E0
-:1066D0003C05080094A53D923C0208008C423D8C8C
-:1066E00090E6000D0005240030C300201060002C4F
-:1066F000004440258F85001C00006021240B000110
-:1067000090A3008500004821240A00013C0F80006E
-:1067100035EE00708DC70000AF8700308F580178CC
-:106720000700FFFE3C038000347900708F380000C2
-:106730003C0508008CA500743C0D08008DAD007070
-:106740000307782300AF38210000102100EF302B21
-:1067500001A22021008618213C010800AC2700740A
-:106760003C010800AC230070AF4B01483C19080005
-:106770008F393D94A7490144A74A0146AF59014CBE
-:106780003C0B0800916B3D91A34B0152AF48015463
-:106790003C081000A74C015803E00008AF480178FE
-:1067A0008F4B0E1C3C0A08008D4A3D7497490E160B
-:1067B000974D0E1401456021312AFFFF0A000E2774
-:1067C00031A9FFFF8F8300249064000D30820020E8
-:1067D0001040002900000000000048210000502166
-:1067E000000040213C07800034EB00708D67000002
-:1067F000AF8700308F4C01780580FFFE3C0D800094
-:1068000035AC00708D8B00003C0508008CA5007431
-:106810003C0408008C8400700167302300A67821B6
-:106820000000102101E6C82B0082C021031970214D
-:106830003C010800AC2F00743C010800AC2E007035
-:10684000AF4901483C0D08008DAD3D94A748014477
-:1068500024090040A74A01463C081000240AFF9181
-:10686000AF4D014CA34A0152AF490154A740015812
-:1068700003E00008AF4801788F490E1897460E12C2
-:1068800097450E1030CAFFFF0A000E5D30A8FFFFCB
-:106890008F83002427BDFFF89064000D3082002014
-:1068A0001040003A00000000240B000100004821C5
-:1068B000240A00013C088000350700708CE30000CA
-:1068C000AF8300308F4C01780580FFFE3C0E8000C6
-:1068D0003C04080090843DD035C700708CEC00006B
-:1068E0003C0508008CA50074A3A400033C19080013
-:1068F0008F3900708FAD00000183302300A638214E
-:10690000000010210322782100E6C02B01F860214D
-:1069100001AE4025AFA800003C010800AC27007480
-:106920003C010800AC2C00709346010A3C040800AE
-:1069300090843DD1A3A00002A3A600018FA3000074
-:106940003C0580FF3099007F34A2FFFF006278246D
-:106950000019C60001F87025240D3000AF4E014C1F
-:1069600027BD0008AF4D0154A7400158AF4B014867
-:10697000A7490144A74A01463C091000240AFF80A8
-:10698000A34A015203E00008AF4901788F4B0E186B
-:1069900097460E1297450E1030CAFFFF0A000E915F
-:1069A00030A9FFFF8F85001C2402008090A4008581
-:1069B000308300C0106200058F8600208F88000899
-:1069C0008F87000CACC800C8ACC700C403E0000847
-:1069D000000000003C0A0800254A39543C09080020
-:1069E00025293A203C08080025082DD43C0708003A
-:1069F00024E73B343C06080024C637C43C050800A5
-:106A000024A5353C3C040800248431643C03080080
-:106A10002463385C3C020800244236303C01080004
-:106A2000AC2A3D503C010800AC293D4C3C0108001B
-:106A3000AC283D483C010800AC273D543C0108000F
-:106A4000AC263D643C010800AC253D5C3C010800DF
-:106A5000AC243D583C010800AC233D683C010800D3
-:0C6A6000AC223D6003E0000800000000D4
+:102F000000000000000000000000000000000000C1
+:102F1000000000000000138800000000000005DC35
+:102F2000000000000000000010000003000000008E
+:102F30000000000D0000000D3C02080024423C206F
+:102F40003C03080024633DD4AC4000000043202B28
+:102F50001480FFFD244200043C1D080037BD7FFCA7
+:102F600003A0F0213C100800261000A83C1C08001B
+:102F7000279C3C200E0002BA000000000000000D5B
+:102F80008F8300383C088000350700708CE5000016
+:102F9000008330253C02900000C22025AF85003020
+:102FA000AF4400208F4900200520FFFE3C03800035
+:102FB000346200708C4500008F8600303C19080098
+:102FC0008F39007C3C0E08008DCE007800A62023AF
+:102FD00003245821000078210164682B01CF60216F
+:102FE000018D50213C010800AC2B007C3C01080005
+:102FF000AC2A007803E00008000000000A0000414D
+:10300000240400018F8400383C05800034A20001B4
+:103010000082182503E00008AF43002003E0000809
+:10302000000010213084FFFF30A5FFFF1080000753
+:1030300000001821308200011040000200042042EC
+:10304000006518211480FFFB0005284003E00008FC
+:103050000060102110C00007000000008CA20000DA
+:1030600024C6FFFF24A50004AC82000014C0FFFBAF
+:103070002484000403E000080000000010A0000801
+:1030800024A3FFFFAC860000000000000000000049
+:103090002402FFFF2463FFFF1462FFFA248400046C
+:1030A00003E0000800000000308AFFFF93A800132F
+:1030B000A74A014497490E1630C600FF3C02100093
+:1030C000A7490146AF450148A3460152A748015A06
+:1030D000AF4701608FA400188FA30014A7440158C4
+:1030E000AF43015403E00008AF42017803E0000859
+:1030F000000000003C038000346200708C49000036
+:103100008F8800002484000727BDFFF83084FFF873
+:10311000AF890030974D008A31ACFFFFAFAC0000A3
+:103120008FAB0000016850232547FFFF30E61FFFEB
+:1031300000C4282B14A0FFF73C0C8000358B0070D6
+:103140008D6A00003C0708008CE700843C060800FC
+:103150008CC6008000081082014918230002788084
+:1031600000E370210000202101C3C82B00C4C0214E
+:1031700001FA4021031948212502400027BD00081B
+:103180003C010800AC2E00843C010800AC29008002
+:1031900003E00008000000008F8200002486000782
+:1031A00030C5FFF800A2182130641FFF03E00008BB
+:1031B000AF8400008F8700388F8A004027BDFFB89A
+:1031C0008F860044AFB60040AFBF0044AFB5003CAF
+:1031D000AFB40038AFB30034AFB20030AFB1002CA1
+:1031E000AFB000288F4501048D4900ACAF47008087
+:1031F0008CC8002000A938230000B021AF480E1071
+:103200008F440E1000004821AF440E148CC20024DD
+:10321000AF420E188F430E18AF430E1C10E001256D
+:103220002D230001936B0008116000D40000000002
+:10323000976E001031CDFFFF00ED602B158000CFA1
+:103240000000000097700010320FFFFFAF4F0E001C
+:103250008F520000325100081220FFFD00000000D4
+:1032600097540E088F460E043285FFFF30B30001DD
+:1032700012600132000000000000000D30B8A040D4
+:1032800024150040131500C030A9A0001120012D05
+:1032900000000000937F000813E000080000000019
+:1032A00097630010306BFFFF00CB402B1100000331
+:1032B00030AC00401180012300000000A785003CD5
+:1032C000AF8600349366000800E02821AFA70020F5
+:1032D00014C0012427B30020AF60000C9782003C8B
+:1032E0003047400014E00002240300162403000EBF
+:1032F00024194007A363000AAF790014938A003EA3
+:103300008F740014315800070018AA4002959025C8
+:10331000AF7200149784003C8F700014309100103D
+:1033200002117825AF6F0014978E003C31CD000854
+:1033300011A00147000028218F6700143C021000F3
+:103340003C0C810000E22825AF65001497460E0A68
+:103350002408000E3405FFFC30C3FFFF006C582525
+:10336000AF6B0004A3680002937F000A27E9000402
+:10337000A369000A9786003C9363000A30CC1F00C3
+:10338000000C598301634021251F0028A37F0009F9
+:1033900097490E0CA769001093790009272A0002AB
+:1033A000315800070018A82332B10007A371000BA1
+:1033B00093740009976400108F910034978F003C3C
+:1033C000329200FF024480210205702131ED00405D
+:1033D00011A0000531C4FFFF0091282B3C12800092
+:1033E00010A000140000A0210224382B14E0011BBF
+:1033F0008FA500208F4D0E14AF4D0E108F420E1C66
+:10340000AF420E18AF440E008F4F000031EE00089F
+:1034100011C0FFFD0000000097540E0800808821B5
+:1034200000009021A794003C8F500E04241400014A
+:10343000AF900034976400103095FFFF8E68000055
+:103440000111F82317E00009AE7F00008F6500141A
+:103450008F8B004434A60040AF6600148F4C0E10D2
+:10346000AD6C00208F430E18AD63002493670008F5
+:1034700014E000D2000000000E00009E24040010A2
+:103480008F8900483C08320000402821312600FF87
+:103490000006FC0003E8502525390001AF990048DB
+:1034A000AC4A0000937800099370000A330400FFCF
+:1034B00000047400320F00FF01CF6825AC4D0004FA
+:1034C0008F820048064000EAACA20008ACA0000CC5
+:1034D0009783003C306B0008156000022628000628
+:1034E00026280002974E0E148F450E1C8F6700048D
+:1034F000936D000231C4FFFF31A200FFAFA20010A4
+:103500008F6C0014AFA800180E00008BAFAC001435
+:10351000240400100E0000C7000000008E7200009E
+:1035200016400005000000008F6400142405FFBF52
+:1035300000859824AF7300148F79000C033538216F
+:10354000AF67000C9375000816A00008000000008B
+:1035500012800006000000008F7F00143C0BEFFF7C
+:103560003568FFFE03E84824AF690014A37400081F
+:103570008FA500200A00024602202021AF470E003E
+:103580000A0000F5000000008F5901780720FFFEB7
+:10359000241F08008F840000AF5F0178974B008ADA
+:1035A000316AFFFF014448232528FFFF31021FFF36
+:1035B0002C4300081460FFF9000000008F8E0048C3
+:1035C0008F8D003800C048210344202125C600010A
+:1035D000240C0F00AF86004800E938232486400001
+:1035E00031CA00FF11AC0005240800019391003E90
+:1035F0003230000700107A4035E80001000AAC00C4
+:103600003C18010002B8A025AC9440008F930048FC
+:1036100030B2003630A40008ACD30004108000970C
+:1036200001123025974E0E0A8F8D00003C0281005A
+:1036300031CCFFFF25AB0008018240253C03100080
+:1036400031651FFF25390006241F000EAF480160B9
+:1036500000C33025A75F015AAF850000A759015864
+:1036600014E0000A8F93003824120F0052720002F7
+:103670002416000134C600408F580E108F94004469
+:10368000AE9800208F550E18AE9500248F450E146D
+:10369000AF4501448F590E1CAF590148A34A01524E
+:1036A0003C0A1000AF460154AF4A017814E0FEDD39
+:1036B0002D2300010076A025128000178FBF004443
+:1036C0008F84003824160F0010960084000000003C
+:1036D0008F45017804A0FFFE24150F001095006EA1
+:1036E000000000008F470E14240202403C1F10000F
+:1036F000AF4701448F440E1CAF440148A340015220
+:10370000A740015AAF400160A7400158AF420154A1
+:10371000AF5F01788FBF00448FB600408FB5003C8B
+:103720008FB400388FB300348FB200308FB1002CCB
+:103730008FB0002803E0000827BD004814C0FED069
+:1037400030B8A0408F420E148F84004400004821FE
+:10375000AC8200208F510E1CAC9100240A00020E96
+:103760002D2300018F910034978A003C3C12800089
+:103770000220A821315800401700FF300000A0218E
+:10378000976900108F9200343139FFFF13320035F2
+:1037900000002021008048211480FEA000A03821D4
+:1037A0008F420E148F840044AC8200208F510E1C77
+:1037B000AC9100240A00020E2D230001936A000937
+:1037C0009378000B315000FF330F00FF020F702180
+:1037D00025C2000A3050FFFF0E00009E020020218B
+:1037E0008F8600483C1F410024CD0001AF8D00486A
+:1037F000936C000930C600FF00064400318300FFCF
+:10380000246B0002010B4825013FC825AC5900007C
+:103810008F67000C97440E1400F22825AC45000475
+:103820008F450E1C8F670004936A00023084FFFFEF
+:10383000315800FFAFB800108F6F0014AFB10018FF
+:103840000E00008BAFAF00140A0001A60200202179
+:10385000AF6000040A00013EA36000020A000246B5
+:1038600000002021000090210A00017024140001B2
+:103870003C1280000A000195ACB2000C8F91000050
+:1038800025240002A744015826300008320F1FFFEC
+:103890000A0001F9AF8F0000AF40014C1120002C4D
+:1038A000000000008F590E10AF5901448F430E18CD
+:1038B000240200403C1F1000AF430148A3400152C6
+:1038C000A740015AAF400160A7400158AF420154E0
+:1038D000AF5F01780A0002278FBF00441120000665
+:1038E0000000000097460E0830CC00401580000212
+:1038F000000000000000000D8F4D017805A0FFFEC4
+:103900000000000097530E103C120500240E20000A
+:10391000326AFFFF0152C025AF58014C8F4F0E1481
+:103920003C021000AF4F01448F500E1CAF500148B5
+:10393000A34001528F840038A740015AAF40016074
+:10394000A7400158AF4E01540A000215AF4201785A
+:103950008F490E14AF4901448F430E1C0A00028E9A
+:10396000240200403C0E20FF27BDFFE03C1A8000EF
+:103970003C0F800835CDFFFDAFBF001CAFB2001873
+:10398000AFB10014AFB00010AF8F0040AF4D0E00CC
+:103990000000000000000000000000000000000027
+:1039A000000000003C0C00FF358BFFFDAF4B0E000C
+:1039B0003C0660048CC95000240AFF7F3C11600063
+:1039C000012A40243507380CACC750008E24043837
+:1039D00024050009AF4500083083FFFF38622F71CE
+:1039E0002450C0B3AF8000480E000068AF800000D4
+:1039F00052000001AE20442C0E0004353C11800022
+:103A00000E000ED9363000708F8A00403C1208003C
+:103A100026523C88020088218E0800008F5F00003B
+:103A20003BF900013338000113000017AF88003064
+:103A3000022048218D2700003C0F08008DEF006C0C
+:103A40003C0C08008D8C006800E8C02301F8282198
+:103A50000000682100B8302B018D582101664021FB
+:103A60003C010800AC25006C3C010800AC28006853
+:103A70008F44000038830001306200011440FFEDE4
+:103A800000E04021AF8700308E0C00003C050800AC
+:103A90008CA5006C3C0408008C84006801883023ED
+:103AA00000A638210000102100E6402B00821821DA
+:103AB0000068F8213C010800AC27006C3C010800BC
+:103AC000AC3F00688F49010025590088AF99004438
+:103AD000AF890038AF4900208E070000AF87003063
+:103AE0008F4D017805A0FFFE000000008E0600004B
+:103AF0003C0B08008D6B00743C0408008C84007043
+:103B000000C728230165F8210000102103E5402BA0
+:103B10000082382100E8C821240908003C0108007F
+:103B2000AC3F00743C010800AC390070AF4901782B
+:103B300093580108A398003E938F003E31EE000198
+:103B400015C000158F830038240E0D00106E00196B
+:103B5000240F0F00106F001D00000000915900009D
+:103B600024180050332900FF113800043C1F400086
+:103B7000AF5F01380A0002E7000000000E00090EE6
+:103B8000000000008F8A00403C1F4000AF5F0138FA
+:103B90000A0002E700000000938D003E31AC0006F1
+:103BA000000C51000E0000CE0152D8210A00034340
+:103BB0008F8A00403C1B0800277B3D080E0000CE8A
+:103BC000000000000A0003438F8A00403C1B0800ED
+:103BD000277B3D280E0000CE000000000A000343B2
+:103BE0008F8A004090AA00018FAB00108CAC0010AF
+:103BF0003C0300FF8D680004AD6C00208CAD001408
+:103C000000E060213462FFFFAD6D00248CA7001836
+:103C10003C09FF000109C024AD6700288CAE001CE0
+:103C20000182C82403197825AD6F0004AD6E002C05
+:103C30008CAD0008314A00FFAD6D001C94A9000254
+:103C40003128FFFFAD68001090A70000A5600002BA
+:103C5000A1600004A167000090A30002306200FF91
+:103C60000002198210600005240500011065000E95
+:103C70000000000003E00008A16A00018CD80028C1
+:103C8000354A0080AD7800188CCF0014AD6F001459
+:103C90008CCE0030AD6E00088CC4002CA16A0001EF
+:103CA00003E00008AD64000C8CCD001CAD6D001865
+:103CB0008CC90014AD6900148CC80024AD680008DC
+:103CC0008CC70020AD67000C8CC200148C8300648C
+:103CD0000043C82B13200007000000008CC2001412
+:103CE000144CFFE400000000354A008003E00008A7
+:103CF000A16A00018C8200640A00039900000000A0
+:103D000090AA000027BDFFF88FA9001CA3AA0000FD
+:103D10008FAE00003C0FFF808FA8001835E2FFFF38
+:103D20008CCD002C01C26024AFAC0000A1200004A7
+:103D300000E06021A7A000028FB800008D270004DA
+:103D40000188182100A0582100C05021006D2826AC
+:103D50003C06FF7F3C0F00FF2CAD000135EEFFFF5E
+:103D600034D9FFFF3C02FF0003193024000D1DC0B1
+:103D7000010EC82400E2C02400C370250319782571
+:103D8000AD2E0000AD2F00048D450024AFAE000025
+:103D9000AD2500088D4D00202405FFFFAD2D000C42
+:103DA000956800023107FFFFAD27001091660018EB
+:103DB00030C200FF000219C2506000018D4500347E
+:103DC000AD2500148D67000827BD0008AD27001C35
+:103DD0008C8B00CCAD2C0028AD20002CAD2B00240A
+:103DE000AD20001803E00008AD20002027BDFFE053
+:103DF000AFB20018AFB10014AFB00010AFBF001CDD
+:103E00009098000000C088213C0D00FF330F007F18
+:103E1000A0CF0000908E000135ACFFFF3C0AFF00F0
+:103E2000A0CE000194A6001EA22000048CAB0014BA
+:103E30008E29000400A08021016C2824012A40243E
+:103E40000080902101052025A6260002AE24000452
+:103E500026050020262400080E0000762406000215
+:103E600092470000260500282624001400071E00A3
+:103E70000003160324060004044000032403FFFF8C
+:103E8000965900023323FFFF0E000076AE23001088
+:103E9000262400248FBF001C8FB200188FB100149D
+:103EA0008FB0001024050003000030210A000080BC
+:103EB00027BD002027BDFFD8AFB1001CAFB0001850
+:103EC000AFBF002090A80000240200018FB0003C8A
+:103ED0003103003F00808821106200148FAA00384F
+:103EE000240B0005506B0016AFAA001000A0202183
+:103EF00000C028210E0003DC02003021922400BC07
+:103F0000308300021060000326060030ACC00000C1
+:103F100024C600048FBF00208FB1001C8FB0001892
+:103F200000C0102103E0000827BD0028014038210F
+:103F30000E00035AAFB000100A0004200000000079
+:103F40000E0003A1AFB000140A000420000000001E
+:103F50003C02000A034218213C04080024843D6C02
+:103F60002405001A000030210A000080AF830054AD
+:103F70003C038000346200708C48000000A058218F
+:103F800000C04821308A00FFAF8800308F4401789C
+:103F90000480FFFE3C0C8000358600708CC500005C
+:103FA0003C0308008C6300743C1808008F180070F4
+:103FB00000A82023006468210000C82101A4782BF8
+:103FC0000319702101CF60213C010800AC2D007461
+:103FD0003C010800AC2C00708F480E14AF4801441F
+:103FE000AF47014CA34A0152A74B01589346010821
+:103FF00030C5000854A0000135291000934B09007A
+:1040000024070050316A00FF11470007000000003C
+:104010008F450E1CAF450148AF4901543C091000C3
+:1040200003E00008AF490178934D010831A800086A
+:104030001100001000000000934F010831EE001045
+:1040400051C00001352900083C04080090843DD08F
+:10405000A34401508F4309A4AF4301488F4209A0F4
+:10406000AF420144AF4901543C09100003E000088D
+:10407000AF4901783C1908008F393D8C333800086E
+:104080005700FFF1352900080A0004730000000002
+:1040900024070040AF470814AF4008108F4209447E
+:1040A0008F4309508F4409548F45095C8F46094C52
+:1040B000AF820064AF830050AF84004CAF85005CDA
+:1040C00003E00008AF8600609346010930C5007F19
+:1040D000000518C0000521400083102103E00008FE
+:1040E000244200883C09080091293D9124A800023F
+:1040F0003C05110000093C0000E8302500C51825EA
+:1041000024820008AC83000003E00008AC800004B7
+:104110009347010B8F4A002C974F09083C18000E5B
+:104120000358482131EEFFFF000E41C0AF48002C7C
+:1041300097430908952C001A0080402124030001B0
+:10414000318BFFFFAC8B00008D2D001C00A058218F
+:1041500000C06021AC8D00048D24002030E70040B9
+:10416000AD04000891220019304400031083004878
+:104170002885000214A00062240600021086005662
+:1041800024190003109900660000000010E0003AB6
+:10419000000000003C07080094E73D8624E200018F
+:1041A000934F0934934709219525002A31EE00FFEA
+:1041B000000E488230ED00FF978700580009360056
+:1041C000000D1C003044FFFF00C310250044C02533
+:1041D00000A778213C19400003197025000F4C00FE
+:1041E000AD090004AD0E0000934D09203C0300060C
+:1041F00025090014000D360000C32025AD04000879
+:104200008F59092C24E5000130A27FFFAD19000C65
+:104210008F580930A782005825020028AD180010D9
+:104220008F4F0938AD0F0014AD2B00048F4E09409D
+:10423000AD2E0008934D09373C05080090A53D9030
+:104240008F4409488F46094031A700FF00EC182130
+:10425000008678230003C7000005CC000319602501
+:1042600031E8FFFC01885825AD2B000CAD20001073
+:1042700003E00008AF4A002C3C0D080095AD3D86D8
+:104280003C0E080095CE3D800A0004C901AE102105
+:104290003C05080094A53D8A3C06080094C63D8074
+:1042A0003C18080097183D7C952E002400A6782124
+:1042B00001F86823000E240025A2FFF200821825D1
+:1042C00024190800AD03000CAD190014AD00001056
+:1042D0000A0004C425080018952600249525002806
+:1042E0000006C40000057C00370E810035ED080093
+:1042F000AD0E000CAD0D00100A0004C4250800141A
+:104300001480FFA200000000952400240004140083
+:1043100034430800AD03000C0A0004C42508001053
+:104320003C03080094633D8A3C05080094A53D8049
+:104330003C06080094C63D7C953900249538002839
+:10434000006520210086782300196C000018740095
+:1043500025E2FFEE01C2202535A3810024190800C3
+:10436000AD03000CAD040010AD190018AD00001431
+:104370000A0004C42508001C03E00008240201F41C
+:1043800027BDFFE8AFB00010AFBF00140E00006003
+:104390000080802124050040AF4508148F83005021
+:1043A0008F84004C8F85005C0070182100641023FE
+:1043B00018400004AF830050AF6300548F66005470
+:1043C000AF86004C1200000C000000008F44007407
+:1043D000936800813409FA002D07000710E00005FA
+:1043E00000891021936C0081240B01F4018B50048F
+:1043F00001441021AF62000C8F4E095C01C5682397
+:1044000019A000048FBF00148F4F095CAF8F005CB0
+:104410008FBF00148FB000100A00006227BD001883
+:104420008F8400648F8300508F82004CAF640044FF
+:10443000AF63005003E00008AF6200543C0380000B
+:10444000346200708C43000027BDFFF8308700FF06
+:1044500030A900FF30C800FFAF8300308F440178DF
+:104460000480FFFE3C028000345900708F38000049
+:10447000A3A700033C0708008CE700748FAC000082
+:104480003C0608008CC60070030378233C0E7FFFB7
+:1044900000EFC82135CDFFFF00005021018D2824F9
+:1044A00000CA1821000847C0032F202B00A81025A0
+:1044B0000064C021AFA200003C010800AC390074C8
+:1044C0003C010800AC380070934F010AA3A0000221
+:1044D0003C0E80FFA3AF00018FAC0000312B007FAA
+:1044E00035CDFFFF018D4824000B5600012A4025E1
+:1044F000240730002406FF803C05100027BD00087B
+:10450000AF48014CAF470154A7400158A3460152A0
+:1045100003E00008AF45017827BDFFE8AFBF0014F6
+:10452000AFB000108F6500743C068000309000FF33
+:1045300000A620250E000060AF64007493630005A0
+:10454000346200080E000062A36200050200202110
+:104550008FBF00148FB00010240500052406000151
+:104560000A00057027BD001827BDFFE03C0380004E
+:10457000AFB00010AFBF0018AFB1001434620070CC
+:104580008C470000309000FF30A800FFAF8700305C
+:104590008F4401780480FFFE3C18800037110070C2
+:1045A0008E2F00003C0D08008DAD00743C0A080001
+:1045B0008D4A007001E7702301AE282100005821C8
+:1045C00000AE302B014B4821012638213C01080068
+:1045D000AC250074000088213C010800AC27007065
+:1045E0001100000F000000008F6200742619FFFF09
+:1045F0003208007F0002FE0233E5007F150000064E
+:10460000332200FF2407FF800207202624A3FFFF98
+:1046100000838025320200FF004080212411100811
+:104620000E000060000000008F49081831250004CA
+:1046300014A0FFFD3218007F001878C000187140E8
+:1046400001CF682125AC0088AF4C0818274A0980A3
+:104650008D4B0020AF4B01448D460024AF460148EE
+:10466000A35001500E000062A74001580220102103
+:104670008FBF00188FB100148FB0001003E0000846
+:1046800027BD002027BDFFE8308400FFAFBF00102A
+:104690000E0005BB30A500FF8F8300508FBF0010B8
+:1046A000344500402404FF903C02100027BD001850
+:1046B000AF43014CA3440152AF45015403E000084D
+:1046C000AF4201789343093E306200081040000D6C
+:1046D0003C0901013528080AAC8800008F470074A6
+:1046E000AC8700043C06080090C63D9030C5001021
+:1046F00050A00006AC8000088F6A0060AC8A0008F9
+:104700002484000C03E00008008010210A00062227
+:104710002484000C27BDFFE8AFBF0014AFB0001029
+:104720009346093F00A050210005288000853823CA
+:1047300030C200FF240300063C09080095293D868D
+:1047400024E8FFD8240500041043003724060002A3
+:104750009750093C3C0F020400063400320EFFFF64
+:1047600001CF6825AC8D0000934C093E318B0020B1
+:104770001160000800000000934309363C02010369
+:10478000345F0300307900FF033FC0252405000893
+:10479000AC98000493430934935909210005F88229
+:1047A000306200FF0002C082332F00FF00186E004D
+:1047B000000F740001AE6025018920253C094000EE
+:1047C00000898025ACF0FFD8934309378F4F094803
+:1047D0008F580940306200FF004AC821033F702112
+:1047E00001F86023000E6F0001A650253185FFFC03
+:1047F000001F58800145482501683821AD09002077
+:104800000E00006024F00028240400040E00006262
+:10481000A364003F020010218FBF00148FB000106E
+:1048200003E0000827BD00180A0006352406001220
+:1048300027BDFFD024090010AFB60028AFB5002473
+:10484000AFB40020AFB10014AFB000103C010800BD
+:10485000A0293D90AFBF002CAFB3001CAFB2001831
+:1048600097480908309400FF3C02000E3107FFFF13
+:10487000000731C0AF46002C974409089344010B50
+:1048800030B500FF03428021308300300000B021AA
+:104890001060012500008821240C00043C01080060
+:1048A000A02C3D90934B093E000B5600000A2E03AE
+:1048B00004A0016000000000AF400048934F010BCE
+:1048C00031EE002011C00006000000009358093EA0
+:1048D00000189E00001396030640018900000000A6
+:1048E0009344010B30830040106000038F9300500D
+:1048F0008F8200502453FFFF9347093E30E60008A3
+:1049000014C0000224120003000090219619002C0C
+:1049100093580934934F0937A7990058330C00FF77
+:1049200031EE00FF024E6821000D5880016C5021CD
+:10493000015140213C010800A4283D869205001841
+:1049400030A900FF010918213C010800A4233D887B
+:104950009211001816200002000000000000000D57
+:104960003C010800A4233D8A3C010800A4203D80AE
+:104970003C010800A4203D7C935F010B3063FFFFE6
+:1049800033F00040120000022464000A2464000B8B
+:104990003091FFFF0E00009E022020219358010B52
+:1049A0003C08080095083D8A0040202100185982E3
+:1049B000316700010E00049A01072821934C010B76
+:1049C0008F4B002C974E09083C0F000E034F4021DF
+:1049D00031CDFFFF000D51C0AF4A002C97430908AD
+:1049E0009505001A004038212404000130A9FFFF7A
+:1049F000AC4900008D06001C00404821318A00406F
+:104A0000AC4600048D020020ACE2000891030019BE
+:104A100030630003106400EC2879000217200118AD
+:104A2000241000021070010C241F0003107F011ECF
+:104A300000000000114000DE000000003C090800FA
+:104A400095293D8625220001935F0934934E092163
+:104A50009504002A33F900FF0019C08231CF00FF0E
+:104A6000978E005800184600000F6C00010D80253D
+:104A70003045FFFF02051025008E50213C03400009
+:104A800000433025000A6400ACEC0004ACE60000F2
+:104A9000935F09203C19000624EC0014001FC60097
+:104AA00003197825ACEF00088F48092C25CD0001AB
+:104AB00031A57FFFACE8000C8F500930A785005866
+:104AC00024E80028ACF000108F4409380100802150
+:104AD000ACE40014AD9300048F530940AD9300087B
+:104AE000934A09373C19080093393D908F43094890
+:104AF0008F460940314200FF0052F82100667023C2
+:104B0000001F7F000019C40001F8282531CDFFFCEB
+:104B100000AD2025AD84000CAD800010AF4B002C03
+:104B2000934B093E317300081260000D3C060101F1
+:104B300034CC080AACEC00288F530074AD13000489
+:104B40003C0B0800916B3D903167001050E0000372
+:104B5000AD0000088F6A0060AD0A00082510000C47
+:104B600012C0003D000000009343093F24160006D8
+:104B700024060004306200FF105600C9240700021A
+:104B80009758093C3C0F0204330DFFFF01AF40254D
+:104B9000AE0800009345093E30A4002010800008B4
+:104BA00000000000935309363C0B0103357F0300DE
+:104BB000327900FF033F7025AE0E00042406000882
+:104BC000934F093493480921312AFFFF31ED00FF4B
+:104BD000000D1082310300FF0002B60000032C001C
+:104BE00002C56025018A9825001220803C094000FA
+:104BF0000204502302695825AD4BFFD8935F093753
+:104C00008F4F09488F58094033F900FF0332702154
+:104C10000006B08201D668210007440001F828236D
+:104C2000000D1F000068302530A2FFFC2547FFD88B
+:104C300000C260250016808002074821ACEC0020ED
+:104C4000253000280E00006024120004A372003FEB
+:104C50000E000062000000009347010B30F200409C
+:104C6000124000053C1900FF8E180000372EFFFF90
+:104C7000030E3024AE0600000E0000C702202021E3
+:104C80003C10080092103D90321100031220000FDA
+:104C900002A028218F89005025330001AF930050D6
+:104CA000AF7300508F6B00540173F8231BE00002B8
+:104CB000026020218F640054AF6400548F4C007454
+:104CC000258401F4AF64000C02A028210280202179
+:104CD000A76000680E0005BB3C1410008F850050D3
+:104CE00034550006AF45014C8F8A00488FBF002C19
+:104CF0008FB3001C25560001AF9600488FB20018F4
+:104D0000A34A01528FB60028AF5501548FB1001449
+:104D1000AF5401788FB500248FB400208FB00010FD
+:104D200003E0000827BD00309358093E00189E009C
+:104D3000001396030642003624110002934409230F
+:104D4000308300021060FEDD8F8600608F8200508D
+:104D500014C2FEDA000000000E0000600000000037
+:104D60009369003F24070016312800FF1107000C4B
+:104D7000240500083C0C0800918C3D90358B000107
+:104D80003C010800A02B3D90936A003F314300FF97
+:104D900010650065240D000A106D005E2402000CF1
+:104DA0000E000062000000000A00069000000000F3
+:104DB0003C09080095293D863C0A0800954A3D803B
+:104DC0000A0006F3012A10213C09080095293D8AB2
+:104DD0003C04080094843D803C06080094C63D7C59
+:104DE00095030024012410210046F8230003CC0081
+:104DF00027F0FFF20330C025240F0800ACF8000CA8
+:104E0000ACEF0014ACE000100A0006EE24E7001836
+:104E10003C010800A0313D90935F093E241600013B
+:104E200033F900201720FEA5241100080A0006907F
+:104E3000241100048F6E00848F4D094011A0FE9E46
+:104E4000AF8E0050240F00143C010800A02F3D90AD
+:104E50000A00068F00000000950E0024950D002822
+:104E6000000E6400000D2C003589810034A6080076
+:104E7000ACE9000CACE600100A0006EE24E70014D2
+:104E80001460FEEC000000009502002400021C00EB
+:104E900034640800ACE4000C0A0006EE24E70010BD
+:104EA0000A000741240700123C02080094423D8A90
+:104EB0003C06080094C63D803C03080094633D7C9A
+:104EC00095100024951900280046F82103E3C0231B
+:104ED00000106C0000197400270FFFEE01CF282589
+:104EE00035AC8100ACEC000CACE5001024070800E8
+:104EF000AD2700182527001C0A0006EEAD2000147F
+:104F00008F7F004CAF7F00548F7900540A000699C0
+:104F1000AF790050A362003F0E0000620000000065
+:104F20000A00069000000000240200140A0008276E
+:104F3000A362003F27BDFFE8308400FFAFBF001031
+:104F40000E0005BB30A500FF9378007E9379007FAB
+:104F5000936E00809368007A332F00FF001866007C
+:104F6000000F6C0031CB00FF018D4825000B520073
+:104F70008FBF0010012A3825310600FF344470002D
+:104F800000E628252402FF813C03100027BD0018FD
+:104F9000AF45014CAF440154A342015203E0000865
+:104FA000AF43017827BDFFD8AFB20018AFB10014EE
+:104FB000AFB00010AFBF0020AFB3001C9342010997
+:104FC000308600FF30B000FF000618C23204000235
+:104FD0003071000114800005305200FF9367000516
+:104FE00030E5000810A0000D30C80010024020215C
+:104FF0000E0005A702202821240400018FBF0020F5
+:105000008FB3001C8FB200188FB100148FB0001046
+:105010000080102103E0000827BD002815000032A1
+:105020000000000093430109000028213062007F46
+:10503000000220C00002F94003E49821267900888C
+:10504000033B98218E7800248E6F0008130F0046D2
+:10505000000000008F640084241800020004FD8218
+:1050600033F900031338007C0000000093660083CE
+:10507000934A0109514600043205007C10A00060EB
+:10508000000000003205007C14A0005302402021E3
+:1050900016200006320400018E7F00248F5901047F
+:1050A00017F9FFD600002021320400011080000A09
+:1050B000024020218F4209408F9300641053000664
+:1050C000000000000E00066D022028218F430940D9
+:1050D000AF630044024020210E0006020220282176
+:1050E0000A000860240400013C0908008D290064BE
+:1050F000252600013C010800AC26006416000012C1
+:10510000000000008F6D00843C0E00C001AE6024E2
+:1051100015800005024020210E00082E02202821C3
+:105120000A00086024040001240500040E00057034
+:1051300024060001024020210E00082E0220282112
+:105140000A000860240400010E000041240400014C
+:10515000936B007D020B50250E000062A36A007D58
+:105160000A0008A38F6D00848F6600748F480104C5
+:105170008E67002400064E021507FFB63126007F19
+:10518000936B008326440001308A007F1146004360
+:10519000316300FF5464FFB08F6400842645000132
+:1051A00030B1007F30A200FF122600042405000168
+:1051B000004090210A00087624110001240FFF808E
+:1051C000024F702401CF9026324200FF0040902110
+:1051D0000A000876241100010E00066D0220282125
+:1051E000321800301300FFAA321000820240202142
+:1051F0000E0005A7022028210A00086024040001EF
+:105200008F6E00743C0F80002405000301CF9025B1
+:10521000AF72007493710083240600010E000570C4
+:10522000322400FF0E00004124040001936D007D34
+:10523000020D60250E000062A36C007D3C0B08008F
+:105240008D6B0054257000013C010800AC30005407
+:105250000A000860240400018F6800743C09800083
+:105260002405000401093825AF67007493630083A7
+:10527000240600010E000570306400FF0E0000419E
+:10528000240400019362007D020298250E00006252
+:10529000A373007D0A00086024040001324D0080E1
+:1052A00039AC0080546CFF6C8F6400840A0008C91C
+:1052B0002645000127BDFFC83C0A0008AFBF0030EB
+:1052C000AFB5002CAFB40028AFB30024AFB20020BC
+:1052D000AFB1001CAFB00018034AD8212409004028
+:1052E000AF490814AF4008108F4209448F4309505A
+:1052F0008F4609548F47095C8F48094C9344010835
+:105300009345010BAF820064308400FF30A500FF9D
+:10531000AF830050AF86004CAF87005C0E00084A98
+:10532000AF8800601440017D8FBF0030A760006827
+:10533000934D0900240B00503C15080026B53D484C
+:1053400031AC00FF3C12080026523D58118B00037F
+:10535000000000000000A8210000902193510109E5
+:105360008F9F005024040010322E007F000E68C072
+:10537000000E6140018D282124B40088AF54081824
+:105380008F4901048F4A09A43C0B000E034BC02136
+:10539000012A10233C010800AC223D6C8F430958C0
+:1053A0003C010800A0243D9097470908007F302366
+:1053B0003C010800AC263D7030E8FFFF0008C9C082
+:1053C0003C010800AC3F3D94AF59002C97420908BE
+:1053D0009710002C8EB10000930F001803749821D1
+:1053E000A7900058AF9300440220F80931F000FF65
+:1053F000304E000215C001B2304F000111E0014FE4
+:10540000000000009343093E3066000814C000020B
+:10541000241400030000A0218F5809A424130001C4
+:105420003C010800AC383D98934F0934935109373B
+:1054300031EC00FF322E00FF028E6821000D288023
+:1054400000AC5021015058213C010800A42B3D889C
+:105450003C010800A42A3D8693490934312200FF0B
+:1054600002022021249000103C010800A4303D8459
+:10547000240700068F9F00503C010800AC273D8C9C
+:105480008F88005C8F59095800008021011F282354
+:1054900004A00149033F20230480014700A4302BCE
+:1054A00010C00149000000003C010800AC253D701F
+:1054B0008E4200000040F809000000003043000266
+:1054C000146000F80040882130440001548000102E
+:1054D0008E4200043C0908008D293D743C0AC0003E
+:1054E000012A8025AF500E008F45000030AB000828
+:1054F0001160FFFD00000000974D0E082410000110
+:10550000A78D003C8F4C0E04AF8C00348E420004FB
+:105510000040F8090000000002228825322E000217
+:1055200015C00180000000003C09080095293D7C61
+:105530003C06080094C63D883C0A0800954A3D7E1A
+:105540003C1908008F393D74012660213C18080081
+:105550008F183D983C03080094633D92018A2021F6
+:105560008F4E09400329F821248F000203E32821EC
+:10557000031968213C010800A42C3D8AAF8E006409
+:105580003C010800AC2D3D983C010800A4253D805D
+:105590000E00009E31E4FFFF8F870048004020216D
+:1055A0003C010800A0273D918E42000824E800013C
+:1055B000AF8800480040F809000000009344010B48
+:1055C0008F4C002C974A09083C0B000E034B4021DE
+:1055D0003149FFFF000919C08F8B0050AF43002CE9
+:1055E000974309089506001A00403821308A004088
+:1055F00030DFFFFFAC5F00008D19001C0040482128
+:10560000AC5900048D180020AC580008910F001907
+:1056100031E30003107300F0000000002862000274
+:105620001440010924050002106500FD240D00034B
+:10563000106D010D00000000114000D900000000B5
+:105640003C0A0800954A3D8625420001934D0934E5
+:1056500093580921950E002A31A300FF00032082F0
+:10566000331F00FF9798005800047E00001FCC00F5
+:1056700001F940253049FFFF0109102501D83021EB
+:105680003C0540000045502500066C00ACED0004D0
+:10569000ACEA0000934309203C04000624ED00140A
+:1056A0000003FE0003E4C825ACF900088F49092C6B
+:1056B000270F000131EE7FFFACE9000C8F48093065
+:1056C000A78E005824E90028ACE800108F4509385F
+:1056D00001204021ACE50014ADAB00048F4209402D
+:1056E000ADA20008934B09373C1F080093FF3D9083
+:1056F0008F4309488F4A0940316600FF00D42021BA
+:10570000006A78230004C700001FCC000319282575
+:1057100031EEFFFC00AE1025ADA2000CADA00010D4
+:10572000AF4C002C934C093E318B00085160000FA8
+:105730008E58000C3C06010134CA080AACEA002865
+:105740008F4B0074AD2B00043C0C0800918C3D90F5
+:105750003187001050E00003AD2000088F62006028
+:10576000AD2200082528000C8E58000C0300F80913
+:10577000010020213C19080097393D8A3C1F080090
+:1057800097FF3D7E033F782125E900020E0000C708
+:105790003124FFFF3C0E08008DCE3D6C3C08080014
+:1057A0008D083D7401C828233C010800AC253D6CE0
+:1057B00014A00006000000003C0308008C633D8C30
+:1057C000346400403C010800AC243D8C12000070A1
+:1057D0008F8C00448F470E108F900044AE0700203E
+:1057E0008F4D0E18AE0D00243C10080096103D8021
+:1057F0000E0000600000000024020040AF420814C8
+:105800008F8600508F8A004C00D01821006A5823E0
+:1058100019600004AF830050AF6300548F650054DB
+:10582000AF85004C1200000C000000008F44007493
+:10583000936800813409FA002D0E000711C000059D
+:1058400000891821937F0081241901F403F9780459
+:1058500001E41821AF63000C8F44095C8F83005C66
+:105860000083C0231B000003000000008F50095C70
+:10587000AF90005C0E000062000000008F8C0050B2
+:105880008E4700103C010800AC2C3D9400E0F80964
+:10589000000000003C0D08008DAD3D6C55A0FEF5EC
+:1058A000240700068F450024975909088F8B006450
+:1058B0008F9400503C0F001F978200588F86005431
+:1058C0008F93004C3328FFFF35E9FF8000A9502457
+:1058D000000871C032320100AF4E0024A4C2002C77
+:1058E000AF4A0024AF6B0044AF740050AF73005454
+:1058F0001640008032380010570000868EA4000445
+:10590000322300405460001B8EB100088EB0000CA2
+:105910000200F809000000008FBF00308FB5002C96
+:105920008FB400288FB300248FB200208FB1001CE9
+:105930008FB0001803E0000827BD00389347010925
+:105940008F8800380007FE0003E8C825AF590080A3
+:105950008F5809A08F5309A4AFB80010AF580E1488
+:105960008FB40010AF540E10AF530E1C0A00096222
+:10597000AF530E180220F809000000008EB0000C92
+:105980000200F809000000000A000AA88FBF0030DA
+:10599000A5800020A59300220A000A5BAD93002495
+:1059A0003C09080095293D863C06080094C63D80C8
+:1059B0000A0009F4012610213C010800AC203D70CA
+:1059C0000A00098E8E4200003C010800AC243D70A4
+:1059D0000A00098E8E4200003C03080094633D8A51
+:1059E0003C04080094843D803C1F080097FF3D7CE8
+:1059F000951800240064C821033F782300186C0028
+:105A000025EEFFF201AE2825AC45000C240208006B
+:105A1000ACE20014ACE000100A0009EF24E7001823
+:105A200095060024950900280006240000091C00A2
+:105A3000349F810034790800ACFF000CACF90010F1
+:105A40000A0009EF24E700141460FEFB00000000C8
+:105A50009518002400187C0035EE0800ACEE000C10
+:105A60000A0009EF24E700103C07080094E73D8096
+:105A70003C04080094843D8A3C03080094633D7C08
+:105A800095190024951800280087F82103E378234E
+:105A90002407080000192C0000186C0025EEFFEE0A
+:105AA00001AE302534A28100AD2700182527001C47
+:105AB000AD22000CAD2600100A0009EFAD20001445
+:105AC00093520109000028210E000602324400FF13
+:105AD0008FBF00308FB5002C8FB400288FB3002407
+:105AE0008FB200208FB1001C8FB0001803E00008B7
+:105AF00027BD0038935F010933E400FF0E00066DF7
+:105B000000002821323800105300FF7E322300406D
+:105B10008EA400040080F809000000000A000AA218
+:105B2000322300401200FF5F000000008F540E146B
+:105B30008F920044AE5400208F530E1C0A000A8A34
+:105B4000AE5300248F82001C008040213C040100E1
+:105B50009047008530E3002010600009000000003D
+:105B60003C0708008CE73D948F83001800E3202356
+:105B7000048000089389000414E30003010020213D
+:105B800003E00008008010213C04010003E000084D
+:105B9000008010211120000B006738238F8C00201B
+:105BA00024090034918B00BC316A0002514000018D
+:105BB0002409003000E9682B15A0FFF10100202125
+:105BC00000E938232419FFFC00B9C02400F9782427
+:105BD00000F8702B15C0FFEA01E8202130C2000355
+:105BE0000002182314C000123069000300003021A5
+:105BF00000A9702101C6682100ED602B1180FFE033
+:105C00003C0401002D2F00010006482B010538211E
+:105C100001E9302414C0FFDA24E4FFFC2419FFFC5E
+:105C200000B9C0240308202103E0000800801021EF
+:105C30008F8B002024060004916A00BC31440004CC
+:105C40001480FFEC00A970210A000B5E00003021D7
+:105C500027BDFFE8AFBF00108F460100934A01093E
+:105C60003C1F08008FFF00902407FF80314F00FF8A
+:105C700031E8007F0008614003E6C821032CC02101
+:105C800027090120012770243C010800A02F3DD0E6
+:105C9000AF4E080C3C0D08008DAD00903C04008018
+:105CA0003482000301A65821016C182124650120CB
+:105CB00030AA007801424025AF48081C3C1F08006C
+:105CC0008FFF00908F88004003E6C0213319000742
+:105CD00003074824033A7821AF49002825E909C081
+:105CE000952E00023C0D08008DAD008C3C0A08008A
+:105CF0008D4A009031CC3FFF01A61821000C59803D
+:105D0000006B282100A72024AF44002C952200021C
+:105D10003C1F08008FFF008C9107008530593FFF22
+:105D200003E678210019C1800146702101F868213D
+:105D300031CC007F31AB007F019A2821017A5021BC
+:105D40003C03000C3C04000E00A328210144102158
+:105D500030E6002027470980AF82002CAF88001C66
+:105D6000AF890024AF85002010C00006AF8700284F
+:105D70008D0200508CA4010C0044302318C0007721
+:105D800000000000910C0085240DFFDF018D3824F8
+:105D9000A10700858F8B001C8F8900248F87002826
+:105DA0008D65004CAF850018912F000D31EE00205D
+:105DB00011C000170000000024090001A38900049D
+:105DC000AF80000C8CE400248F85000C240A0008AE
+:105DD000AF800008AF8000103C010800A42A3D7E7F
+:105DE0003C010800A4203D920E000B32000030213F
+:105DF0008F8500248FBF0010AF82001490A8000D83
+:105E000027BD00180008394203E0000830E2000115
+:105E1000913F00022418000133F900FF001921828C
+:105E200010980039240800021088005B8F86002C2F
+:105E30008CE5002414A0001B8F9F002091220000FD
+:105E4000240A00053046003F10CA00472404000120
+:105E50008F860008A3840004AF860010AF86000C74
+:105E60008CE400248F85000C240A00083C01080003
+:105E7000A42A3D7E3C010800A4203D920E000B3276
+:105E8000000000008F8500248FBF0010AF82001437
+:105E900090A8000D27BD00180008394203E0000853
+:105EA00030E200018CF800088CF900248FEE00C469
+:105EB000A38000048CE40024AF8E000C8F85000CBE
+:105EC0008F86000803197823240A0008AF8F00107A
+:105ED0003C010800A42A3D7E3C010800A4203D921C
+:105EE0000E000B32000000008F8500248FBF0010D1
+:105EF000AF82001490A8000D27BD00180008394299
+:105F000003E0000830E20001912300003062003F0E
+:105F1000104400278F8500208CE400241480002189
+:105F2000000000008D2E00183C187FFF8F85002098
+:105F3000370FFFFF01CF1824AF8300088F9F0008A1
+:105F40008CA8008403E8C82B1720000203E020215E
+:105F50008CA400840A000BEDAF8400088CA3010C14
+:105F60000A000BCBAF8300188D2C00188F86000819
+:105F70003C0D7FFF8F89002035A3FFFF018358244C
+:105F800024040001AF8B0010AD2000CCA3840004DA
+:105F90000A000BF9AF86000C8CCA00140A000BED46
+:105FA000AF8A00088CA300C80A000C30AF83000839
+:105FB0008F84002C8CAC00648C8D0014018D582BC8
+:105FC00011600004000000008CA200640A000C3084
+:105FD000AF8200088C8200140A000C30AF820008E7
+:105FE0008F85000C27BDFFE0AFBF0018AFB10014D4
+:105FF00014A00007AFB000108F8600242402000513
+:1060000090C400003083003F106200B68F840020EF
+:106010008F91000800A080218F8C00283C0508008B
+:106020008CA53D708D8B000431663FFF00C5502B61
+:106030005540000100C02821938D000411A0007379
+:1060400000B0F82B8F98002024040034930F00BC7C
+:1060500031EE000251C000012404003000A4C82B1E
+:10606000172000D10000000000A4282300B0F82B66
+:106070003C010800A4243D7C17E0006802002021B8
+:106080003C0308008C633D6C0083102B54400001DE
+:10609000008018218F8800243C010800AC233D7447
+:1060A000000048219104000D308300205060000161
+:1060B0008F490E188F8300140123382B10E00059EC
+:1060C000000000003C0408008C843D7400895821C5
+:1060D000006B502B114000560090602B006930235C
+:1060E00000C020213C010800AC263D7412000003D2
+:1060F000241FFFFC1090008A32270003009FC82451
+:106100003C010800AC393D743C010800A4203D92DC
+:106110008F84000C120400078F830020AF910008C9
+:10612000020020218C7100CCAF90000C26300001C1
+:10613000AC7000CC3C0208008C423D748F8A001089
+:10614000240700180082202301422823AF84000C7A
+:1061500010800002AF850010240700108F86001CFD
+:106160003C010800A0273D902407004090CC00850A
+:10617000318B00C0116700408F8D001414A00015F2
+:1061800000002021934A01098F420974314500FF24
+:106190000002260224A300013090007F3071007FAE
+:1061A0001230007A2407FF80A0C300833C09080056
+:1061B0008D293D8C8F880024240D0002352C000889
+:1061C0003C010800A02D3DD13C010800AC2C3D8CC9
+:1061D00024040010910E000D31C6002010C00005EF
+:1061E00000801821240800013C010800AC283D74FF
+:1061F000348300018FBF00188FB100148FB00010DE
+:106200000060102103E0000827BD00203C010800C9
+:10621000A4203D7C13E0FF9A020020210A000C819B
+:1062200000A020213C0408008C843D740090602B69
+:106230001180FFAE000000003C0F080095EF3D7C90
+:1062400001E4702101C6682B11A000072C82000414
+:106250003C1F60008FF954043338003F1700FFE5FE
+:10626000240300422C8200041040FFA024030042BB
+:106270000A000CDF8FBF0018152DFFC000000000C2
+:106280008CDF00743C0380002405FF8003E3C825F5
+:10629000ACD9007490D80085240E000424040010AA
+:1062A000330F003F01E54025A0C800858F880024FA
+:1062B0003C010800A02E3DD1240300019106000DF1
+:1062C00030C9002015200003000000003C03080036
+:1062D0008C633D743C010800AC233D6C0A000CD675
+:1062E000000000008F8700108C88008400E8282BB5
+:1062F00014A0000200E088218C9100842409000190
+:10630000A38900048F440E18022028210E000B32AE
+:1063100002203021022080210A000C67AF82001485
+:1063200000071823306600033C010800A4263D92B4
+:10633000122000058F8C0020918B00BC316A000474
+:106340001540001524CD00043C0F080095EF3D9248
+:1063500001E4702100AE302B50C0FF6E8F84000C22
+:106360002C85000514A0FFA32403004230980003ED
+:1063700017000002009818232483FFFC3C0108004A
+:10638000AC233D740A000CA30000000000A75824B1
+:106390000A000CCB016718263C010800A42D3D9291
+:1063A0000A000D33000000003C010800AC203D74E1
+:1063B0000A000CDE240300428F83001014600007E3
+:1063C000000010218F88002424050005910600009C
+:1063D00030C400FF108500030000000003E0000847
+:1063E00000000000910A0018314900FF000939C27D
+:1063F00014E0FFFA8F85001C3C04080094843D7C67
+:106400003C0308008C633D943C1908008F393D74AF
+:106410003C0F080095EF3D920064C0218CAD005404
+:106420000319702101CF6021018D58231960001DCF
+:1064300000000000910E001C8F8C002C974B0E105A
+:1064400031CD00FF8D850004016D30238D88000063
+:1064500030CEFFFF000E510000AAC82100003821F5
+:1064600001072021032A182B0083C021AD990004C5
+:10647000AD980000918F000A01CF6821A18D000A1C
+:106480008F88002C974B0E12A50B0008950A003838
+:1064900025490001A50900389107000D34E60008E0
+:1064A000A106000D03E000080000000027BDFFE08A
+:1064B000938700048F8F00248FAD00143C0E7FFF64
+:1064C0008F89000C35C8FFFFAFBF001CAFB00018AC
+:1064D00001A8182491EA000D000717C03C1FBFFF58
+:1064E000006258252D2E00018F90001837F9FFFF0C
+:1064F0003C1808008F183D943C0F080095EF3D8A2A
+:1065000001796824000E47803C07EFFF3C05F0FF4F
+:1065100001A818253149002034E2FFFF34ACFFFF09
+:106520000310582327A500102406000225EA0002C4
+:106530000062182400808021152000020000402104
+:106540008F480E1CA7AA0012056000372407000020
+:1065500030FF00FF001FCF008F8B001C0079382513
+:10656000AFA70014916F00853C08080091083D9189
+:106570003C18DFFF31EE00C0370AFFFF000E182B7A
+:106580003C1F080097FF3D8400EA6824A3A800117F
+:106590000003174001A248258FB90010AFA90014CD
+:1065A0003C0A0800914A3D93A7BF00168FA800142B
+:1065B000032CC0243C0B01003C0F0FFF030B1825DC
+:1065C0003147000335EEFFFF010C68240007160079
+:1065D000006EF8243C09700001A2C82503E9582583
+:1065E000AFB90014AFAB00100E000076A3A00015E9
+:1065F0008F8C0024260200089186000D30C40020F4
+:10660000108000068FBF001C3C05080094A53D804B
+:1066100024B0FFFF3C010800A4303D808FB000187B
+:1066200003E0000827BD00208F9800140118502BAC
+:106630005540FFC7240700010A000DB630FF00FFD8
+:106640009382000427BDFFE0AFBF00181040000F89
+:10665000008050218F880024240B00058F890008BA
+:10666000910700008F8400200100282130E3003FC3
+:106670008F86002C106B000800003821AFA9001095
+:106680000E00040EAFAA0014A38000048FBF0018F0
+:1066900003E0000827BD00208D1900183C0F0800FA
+:1066A0008DEF3D748F9800103C027FFF8D08001421
+:1066B000345FFFFF033F682401F8702101AE6023BF
+:1066C00001883821AFA900100E00040EAFAA0014F3
+:1066D0000A000E04A38000048F8700243C050800F4
+:1066E00094A53D923C0208008C423D8C90E6000D42
+:1066F0000005240030C300201060002C0044402519
+:106700008F85001C00006021240B000190A30085F0
+:1067100000004821240A00013C0F800035EE007083
+:106720008DC70000AF8700308F5801780700FFFE4B
+:106730003C038000347900708F3800003C0508006D
+:106740008CA500743C0D08008DAD00700307782304
+:1067500000AF38210000102100EF302B01A22021D2
+:10676000008618213C010800AC2700743C01080099
+:10677000AC230070AF4B01483C1908008F393D94A1
+:10678000A7490144A74A0146AF59014C3C0B0800F8
+:10679000916B3D91A34B0152AF4801543C0810004E
+:1067A000A74C015803E00008AF4801788F4B0E1C3E
+:1067B0003C0A08008D4A3D7497490E16974D0E14F9
+:1067C00001456021312AFFFF0A000E2731A9FFFF92
+:1067D0008F8300249064000D308200201040002937
+:1067E000000000000000482100005021000040216E
+:1067F0003C07800034EB00708D670000AF870030ED
+:106800008F4C01780580FFFE3C0D800035AC007098
+:106810008D8B00003C0508008CA500743C0408002A
+:106820008C8400700167302300A6782100001021BD
+:1068300001E6C82B0082C021031970213C01080029
+:10684000AC2F00743C010800AC2E0070AF49014829
+:106850003C0D08008DAD3D94A7480144240900403B
+:10686000A74A01463C081000240AFF91AF4D014C95
+:10687000A34A0152AF490154A740015803E0000860
+:10688000AF4801788F490E1897460E1297450E10A3
+:1068900030CAFFFF0A000E5D30A8FFFF8F8300247F
+:1068A00027BDFFF89064000D308200201040003AB0
+:1068B00000000000240B000100004821240A000110
+:1068C0003C088000350700708CE30000AF83003087
+:1068D0008F4C01780580FFFE3C0E80003C040800D0
+:1068E00090843DD035C700708CEC00003C0508005A
+:1068F0008CA50074A3A400033C1908008F39007014
+:106900008FAD00000183302300A638210000102144
+:106910000322782100E6C02B01F8602101AE40255A
+:10692000AFA800003C010800AC2700743C0108003F
+:10693000AC2C00709346010A3C04080090843DD1C1
+:10694000A3A00002A3A600018FA300003C0580FFC6
+:106950003099007F34A2FFFF006278240019C6003E
+:1069600001F87025240D3000AF4E014C27BD000802
+:10697000AF4D0154A7400158AF4B0148A74901440E
+:10698000A74A01463C091000240AFF80A34A01528D
+:1069900003E00008AF4901788F4B0E1897460E129E
+:1069A00097450E1030CAFFFF0A000E9130A9FFFF75
+:1069B0008F85001C2402008090A40085308300C0D5
+:1069C000106200058F8600208F8800088F87000CDA
+:1069D000ACC800C8ACC700C403E000080000000059
+:1069E0003C0A0800254A39543C09080025293A2068
+:1069F0003C08080025082DD43C07080024E73B3458
+:106A00003C06080024C637C43C05080024A5353CD4
+:106A10003C040800248431643C0308002463385C8F
+:106A20003C020800244236303C010800AC2A3D50AC
+:106A30003C010800AC293D4C3C010800AC283D4815
+:106A40003C010800AC273D543C010800AC263D64E5
+:106A50003C010800AC253D5C3C010800AC243D58DD
+:106A60003C010800AC233D683C010800AC223D60BD
+:086A700003E000080000000033
:00000001FF
/*
* This file contains firmware data derived from proprietary unpublished
diff --git a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex
index 7f39b4a7f331..68279b53e102 100644
--- a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex
+++ b/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex
@@ -3,17 +3,17 @@
:10002000000000380000565C080000A00800000036
:100030000000574400005694080059200000008436
:100040000000ADD808005744000001C00000AE5CBD
-:100050000800321008000000000090900000B01C62
-:100060000000000000000000000000000800909068
-:100070000000033C000140AC0800049008000400AC
-:10008000000012FC000143E8000000000000000036
-:1000900000000000080016FC00000004000156E407
-:1000A000080000A80800000000003D28000156E8F4
+:100050000800321008000000000092F80000B01CF8
+:10006000000000000000000000000000080092F8FE
+:100070000000033C00014314080004900800040041
+:10008000000012FC000146500000000000000000CB
+:1000900000000000080016FC000000040001594C9C
+:1000A000080000A80800000000003D280001595089
:1000B00000000000000000000000000008003D28D3
-:0800C000000000300001941063
+:0800C0000000003000019678F9
:0800C8000A00004600000000E0
-:1000D000000000000000000D636F6D362E302E31E1
-:1000E00037000000060011020000000000000003BD
+:1000D000000000000000000D636F6D362E322E31DF
+:1000E0000000000006020102000000000000000302
:1000F000000000C800000032000000030000000003
:1001000000000000000000000000000000000000EF
:1001100000000010000001360000EA600000000549
@@ -1387,8 +1387,8 @@
:1056800008001028080010748008010080080080BD
:04569000800800008E
:0C5694000A0000280000000000000000D8
-:1056A0000000000D6370362E302E313700000000F0
-:1056B00006001104000000000000000000000000CF
+:1056A0000000000D6370362E322E31000000000025
+:1056B00006020104000000000000000000000000DD
:1056C000000000000000000038003C000000000066
:1056D00000000000000000000000000000000020AA
:1056E00000000000000000000000000000000000BA
@@ -2823,7 +2823,7 @@
:0CB01000080049B808004C6408005050CB
:04B01C000A000C8496
:10B0200000000000000000000000000D7278703683
-:10B030002E302E3137000000060011030000000002
+:10B030002E322E3100000000060201030000000045
:10B0400000000001000000000000000000000000FF
:10B0500000000000000000000000000000000000F0
:10B0600000000000000000000000000000000000E0
@@ -3624,10 +3624,10 @@
:10E2100000000000000000000000000000000000FE
:10E220000000000A000000000000000000000000E4
:10E2300010000003000000000000000D0000000DB1
-:10E240003C020801244294003C03080124639634F4
+:10E240003C020801244296603C0308012463989C28
:10E25000AC4000000043202B1480FFFD244200044A
:10E260003C1D080037BD9FFC03A0F0213C100800B6
-:10E27000261032103C1C0801279C94000E001274DA
+:10E27000261032103C1C0801279C96600E0012BE2E
:10E28000000000000000000D3C02800030A5FFFFF0
:10E2900030C600FF344301803C0880008D0901B87E
:10E2A0000520FFFE00000000AC6400002404000212
@@ -3639,7 +3639,7 @@
:10E3000000062B0200051080004448210109182B4B
:10E310001060001100000000910300002C6400094F
:10E320005080000991190001000360803C0D080134
-:10E3300025AD9090018D58218D67000000E0000808
+:10E3300025AD92F8018D58218D67000000E000089E
:10E340000000000091190001011940210109302B42
:10E3500054C0FFF29103000003E000080000102108
:10E360000A000CCC25080001910F0001240E000AC0
@@ -3660,16 +3660,16 @@
:10E45000910400038D43000000072A0000A410254A
:10E460003466000425080004AD42000C0A000CCC00
:10E47000AD46000003E000082402000127BDFFE8CC
-:10E48000AFBF0014AFB000100E0015E50080802172
+:10E48000AFBF0014AFB000100E00167F00808021D7
:10E490003C0480083485008090A600052403FFFE1C
:10E4A0000200202100C310248FBF00148FB0001081
-:10E4B000A0A200050A0015EF27BD001827BDFFE840
+:10E4B000A0A200050A00168927BD001827BDFFE8A5
:10E4C000AFB00010AFBF00140E000FD40080802149
:10E4D0003C06800834C5008090A40000240200504F
:10E4E000308300FF106200073C09800002002021F9
-:10E4F0008FBF00148FB00010AD2001800A0010A65D
+:10E4F0008FBF00148FB00010AD2001800A00108F74
:10E5000027BD0018240801003C07800002002021DC
-:10E510008FBF00148FB00010ACE801800A0010A675
+:10E510008FBF00148FB00010ACE801800A00108F8C
:10E5200027BD001827BDFF783C058008AFBE0080DE
:10E53000AFB7007CAFB3006CAFB10064AFBF008475
:10E54000AFB60078AFB50074AFB40070AFB200687A
@@ -3682,7 +3682,7 @@
:10E5B000AFA0005090CD00002406002031A400FF41
:10E5C00010860018240E0050108E009300000000EA
:10E5D0003C1008008E1000DC260F00013C010800F2
-:10E5E000AC2F00DC0E00165E000000000040182179
+:10E5E000AC2F00DC0E0016F80000000000401821DF
:10E5F0008FBF00848FBE00808FB7007C8FB60078FD
:10E600008FB500748FB400708FB3006C8FB2006848
:10E610008FB100648FB000600060102103E000083B
@@ -3709,15 +3709,15 @@
:10E760008FB200688FB100648FB00060006010212C
:10E7700003E0000827BD00880E000D2800002021BE
:10E780000A000D75004018210A000D9500C02021D7
-:10E790000E0016AE02C020211440FFE10000000070
+:10E790000E00174802C020211440FFE100000000D5
:10E7A0003C0B8008356400808C8A003402CA482300
:10E7B0000520001D000000003C1E08008FDE310017
:10E7C00027D700013C010800AC3731001260000679
:10E7D000024020213C1408008E9431F42690000160
-:10E7E0003C010800AC3031F40E0015E53C1E8008F9
+:10E7E0003C010800AC3031F40E00167F3C1E80085E
:10E7F00037CD008091B700250240202136EE00047D
-:10E800000E0015EFA1AE00250E000CAC0240202139
-:10E810000A000DCA240300013C17080126F794F8EA
+:10E800000E001689A1AE00250E000CAC024020219E
+:10E810000A000DCA240300013C17080126F797607F
:10E820000A000D843C1F80008C86003002C66023E5
:10E830001980000C2419000C908F004F3C14080024
:10E840008E94310032B500FC35ED0001268E0001BA
@@ -3728,25 +3728,25 @@
:10E8900000B410233044FFFFAFA4005832A8000298
:10E8A0001100002E32AB00103C15800836B00080FD
:10E8B0009216000832D30040526000FB8EE200083E
-:10E8C0000E0015E502402021240A0018A20A0009C2
+:10E8C0000E00167F02402021240A0018A20A000927
:10E8D000921100052409FFFE024020210229902404
-:10E8E0000E0015EFA21200052404003900002821B3
-:10E8F0000E001689240600180A000DCA2403000120
+:10E8E0000E001689A2120005240400390000282118
+:10E8F0000E001723240600180A000DCA2403000185
:10E9000092FE000C3C0A800835490080001EBB00C6
:10E910008D27003836F10081024020213225F08118
:10E920000E000C9B30C600FF0A000DC10000000065
:10E930003AA7000130E300011460FFA402D4B02123
-:10E940000A000E1D00000000024020210E0016CB20
+:10E940000A000E1D00000000024020210E00176585
:10E95000020028210A000D75004018211160FF7087
:10E960003C0F80083C0D800835EE00808DC40038D7
:10E970008FA300548DA60004006660231D80FF68ED
:10E98000000000000064C02307020001AFA400548F
:10E990003C1F08008FFF31E433F9000113200015FC
:10E9A0008FAC00583C07800094E3011A10600012FD
-:10E9B0003C0680080E0020F8024020213C0308019C
-:10E9C0009063952930640002148001450000000026
+:10E9B0003C0680080E002192024020213C03080101
+:10E9C00090639791306400021480014500000000BC
:10E9D000306C0004118000078FAC0058306600FBDB
-:10E9E0003C010801A026952932B500FCAFA00058D3
+:10E9E0003C010801A026979132B500FCAFA0005869
:10E9F0008FAC00583C06800834D30080AFB40018B8
:10EA0000AFB60010AFAC00143C088000950B01209D
:10EA10008E6F0030966A005C8FA3005C8FBF003061
@@ -3773,7 +3773,7 @@
:10EB600001F1302318C00097264800803C070800B8
:10EB70008CE731E42404FF80010418243118007F5D
:10EB80003C1F80003C19800430F10001AFE300908D
-:10EB900012200006031928213C03080190639529DF
+:10EB900012200006031928213C0308019063979175
:10EBA00030690008152000C6306A00F73C10800864
:10EBB00036040080908C004F318B000115600042BC
:10EBC000000000003C0608008CC6319830CE0010D2
@@ -3786,2697 +3786,2735 @@
:10EC30008C67000002C7782319E000978FBF00544B
:10EC4000AC93002024130001AC760000AFB3005059
:10EC5000AC7F000417C0004E000000008FA90050D8
-:10EC60001520000B000000003C030801906395296B
+:10EC60001520000B000000003C0308019063979101
:10EC7000306A00011140002E8FAB0058306400FE56
-:10EC80003C010801A02495290A000D7500001821F7
+:10EC80003C010801A02497910A000D75000018218D
:10EC90000E000CAC024020210A000F1300000000FF
:10ECA0000A000E200000A0210040F80924040017EB
:10ECB0000A000DCA240300010040F80924040016CC
:10ECC0000A000DCA240300019094004F240DFFFE9A
:10ECD000028D2824A085004F30F900011320000682
-:10ECE0003C0480083C03080190639529307F0010A4
+:10ECE0003C0480083C03080190639791307F00103A
:10ECF00017E00051306800EF34900080240A0001D2
-:10ED0000024020210E0015E5A60A001292030025FC
+:10ED0000024020210E00167FA60A00129203002561
:10ED100024090001AFA90050346200010240202103
-:10ED20000E0015EFA20200250A000EF93C0D800826
+:10ED20000E001689A20200250A000EF93C0D80088B
:10ED30001160FE83000018218FA5003030AC000464
:10ED40001180FE2C8FBF00840A000DCB240300012C
:10ED500027A500380E000CB6AFA000385440FF4382
:10ED60008EE200048FB40038329001005200FF3F61
:10ED70008EE200048FA3003C8E6E0058006E682364
:10ED800005A3FF39AE6300580A000E948EE200041A
-:10ED90000E0015E5024020213C0380083468008005
-:10EDA000024020210E0015EFA11E000903C03021F2
-:10EDB000240400370E001689000028210A000F11D4
+:10ED90000E00167F024020213C038008346800806A
+:10EDA000024020210E001689A11E000903C0302157
+:10EDB000240400370E001723000028210A000F1139
:10EDC0008FA900508FAB00185960FF8D3C0D800853
-:10EDD0000E0015E502402021920C002524050001BB
-:10EDE000AFA5005035820004024020210E0015EF2F
+:10EDD0000E00167F02402021920C00252405000120
+:10EDE000AFA5005035820004024020210E00168994
:10EDF000A20200250A000EF93C0D800812240059D9
:10EE00002A2300151060004D240900162408000C68
:10EE10005628FF2732B000013C0A8008914C001BA5
:10EE20002406FFBD241E000E01865824A14B001BA2
-:10EE30000A000EA532B000013C010801A028952966
+:10EE30000A000EA532B000013C010801A0289791FC
:10EE40000A000EF93C0D80088CB500308EFE0008DB
:10EE50002404001826B6000103C0F809ACB600303F
-:10EE60003C030801906395293077000116E0FF818B
+:10EE60003C030801906397913077000116E0FF8121
:10EE7000306A00018FB200300A000D753243000481
:10EE80003C1080009605011A50A0FF2B34C60010DC
:10EE90000A000EC892EE000C8C6200001456FF6D42
:10EEA000000000008C7800048FB9005403388823D8
:10EEB0000621FF638FBF00540A000F0E0000000000
-:10EEC0003C010801A02A95290A000F3030F9000101
+:10EEC0003C010801A02A97910A000F3030F9000197
:10EED0001633FF028FAF00240A000EB0241E00106C
-:10EEE0000E0015E5024020213C0B800835680080AB
+:10EEE0000E00167F024020213C0B80083568008010
:10EEF00091090025240A0001AFAA0050353300040F
-:10EF0000024020210E0015EFA11300253C05080149
-:10EF100090A5952930A200FD3C010801A022952969
+:10EF0000024020210E001689A11300253C050801AE
+:10EF100090A5979130A200FD3C010801A022979195
:10EF20000A000E6D004018212411000E53D1FEEA94
:10EF3000241E00100A000EAF241E00165629FEDC07
:10EF400032B000013C0A8008914C001B2406FFBD32
:10EF5000241E001001865824A14B001B0A000EA598
:10EF600032B000010A000EA4241E00123C038000EF
:10EF70008C6201B80440FFFE24040800AC6401B8B0
-:10EF800003E00008000000000080502130A5FFFFD2
-:10EF900030C6FFFF3C0480008C8201B80440FFFEB5
-:10EFA00034880180AD0A00003C078008AC8A00204C
-:10EFB00094E300483067FFFF10E000423C0D800002
-:10EFC00024AB001200EB482B5120003F2404000327
-:10EFD00034820100945900208F8900002404001A13
-:10EFE0003338FFFF270BFFFE00EB782B39EE0001D3
-:10EFF00000096B8201AE6024A104000B518000491E
-:10F000008F8B00048F830004A50B0014346800016B
-:10F01000AF88000430CE004015C000333C048000AF
-:10F020003C02800034420180A445000E3C07800071
-:10F0300034EC0180A585001A8F85000C310B80000F
+:10EF800003E000080000000030A5FFFF30C6FFFFCF
+:10EF90003C0780008CE201B80440FFFE34EA0180A7
+:10EFA000AD440000ACE400203C0480089483004899
+:10EFB0003068FFFF11000016AF88000824AB001274
+:10EFC000010B482B512000133C04800034EF01005A
+:10EFD00095EE00208F890000240D001A31CCFFFF30
+:10EFE00031274000A14D000B10E000362583FFFEC5
+:10EFF0000103C02B170000348F9900048F88000490
+:10F00000A5430014350700010A001003AF87000470
+:10F010003C04800024030003348201808F890000B7
+:10F020008F870004A043000B3C088000350C018052
+:10F03000A585000EA585001A8F85000C30EB800099
:10F04000A5890010AD850028A58600081160000F75
-:10F050008F85001434EA0100954E001631CDFFFC77
-:10F0600025A40004008718218C67400030E6FFFFCC
-:10F0700014C000073C0480003C18FFFF370F7FFFDF
-:10F08000010F4024AF8800048F8500143C048000E9
-:10F090002402BFFF348301800102C824A479002622
-:10F0A00010A00004AC69002C00054402A465001007
-:10F0B000A46800263C091000AC8901B803E00008F0
-:10F0C000000000002404000335AC018030CE004075
-:10F0D0008F8900008F880004A184000B51C0FFD1EC
-:10F0E0003C0280003C048000AC8A00203C0F800879
-:10F0F00095EA00403143FFFF5060000834820180F0
-:10F1000000A3C02B5700000100A0182134990180F2
-:10F11000A723000E0A0010053C0780000A00100318
-:10F1200030C6FFBF2407FFFE016740240A000FFE20
-:10F13000AF88000427BDFFE88FA2002830A5FFFF9D
-:10F1400030C6FFFFAFBF0010AF87000CAF820014C6
-:10F15000AF8000040E000FDBAF8000008FBF0010F7
-:10F1600027BD001803E00008AF8000143C068000B3
-:10F1700034C4007034C701008C8A000090E500128E
-:10F180008F84000027BDFFF030A300FF000318822A
-:10F190003082400010400037246500030005C8801D
-:10F1A0000326C0218F0E4000246F0004000F6880EA
-:10F1B000AFAE000001A660218D8B4000AFAB000414
-:10F1C00094E900163128FFFC010638218CE6400046
-:10F1D000AFA600088FA900080000302100002821F8
-:10F1E0003C07080024E701000A00107E24080008FC
-:10F1F0009059000024A500012CAC000C0079C0211E
-:10F200000018788001E770218DCD00001180000684
-:10F2100000CD302603A5102114A8FFF500051A0023
-:10F220005520FFF4905900003C04800034870070A2
-:10F230003C0508008CA531048CE300002CA20020C2
-:10F2400010400009006A3823000548803C0B080084
-:10F25000256B3108012B402124AA0001AD070000D5
-:10F260003C010800AC2A310400C0102103E0000872
-:10F2700027BD0010308220001040000B0005588090
-:10F28000016648218D24400024680004000838806D
-:10F29000AFA4000000E618218C654000AFA0000874
-:10F2A0000A00106EAFA500040000000D0A00106FE8
-:10F2B0008FA9000827BDFFD83C058000AFB100141E
-:10F2C000AFB00010AFBF0024AFB40020AFB3001C3C
-:10F2D000AFB200188F87000034A401009483000EA1
-:10F2E00030E2400000008021104000103071FFFF2C
-:10F2F0003C08002000E8302410C0000D30EB8000F6
-:10F300008F890004240ABFFF00EA38243523100047
-:10F31000AF87000030F320001660000B3C1800049B
-:10F320002419FFBF0A0010CF0079102430EB8000B1
-:10F330001560004D3C0D002030F320001260FFF8F6
-:10F340008F8300043C18000400F8A0241280FFF50D
-:10F350002419FFBF3462004030FF010013E00010A9
-:10F36000AF8200048F820028104000063C0E80000F
-:10F370003C04002000E41824146000CE3C06000485
-:10F380003C0E800035CD010095AC001E95AB001CF5
-:10F390003189FFFF000B5400012A4025AF88000C83
-:10F3A0003C138000367401009692000C8E6340007E
-:10F3B000340FFFFF106F00843244FFFF30780100EC
-:10F3C000570000012410001030F9100053200008ED
-:10F3D0003612000130FF002017E000733C031000DC
-:10F3E00000E310241440006A3C0A0C0036120001AD
-:10F3F00030EC01001580000B3C0600018F880004F2
-:10F40000310D400015A0000800E628243C131F0120
-:10F4100000F378243C0E100011EE00AE3094020090
-:10F420003C06000100E6282410A000193C19100039
-:10F430003C0408008C84002430940002168000D91B
-:10F44000240300018FBF00248FB400208FB3001C61
-:10F450008FB200188FB100148FB00010006010211F
-:10F4600003E0000827BD002800ED60241180FFB3F1
-:10F4700030F320008F8E00043C12FFFF364F7FFFD9
-:10F4800000EF382435C380000A0010BEAF870000AB
-:10F4900000F9C0241700004E00002021AF800010AA
-:10F4A0003C0380003465010094AE000E8F91001083
-:10F4B00031CAFFFF108000C62553000430EF010061
-:10F4C00015E000703C180F003A2800022E7003EF80
-:10F4D0002D1900013A1F0001033F282414A0002227
-:10F4E000240400013C0308008C6300D02E25000C8E
-:10F4F000001121C0386C00012D8B00010165102422
-:10F50000144000143270FFFF262DFFFC2DA40004D0
-:10F510001480010300002021386A00022D460001FA
-:10F5200000C51824546000FF02002821262FFFF890
-:10F530002DEE000415C00007000000000007A242E5
-:10F540000011C02B0298482415200109020028212F
-:10F55000001121C002002821364600020E000FDBF8
-:10F560000000000000002021008018218FBF00242F
-:10F570008FB400208FB3001C8FB200188FB100141D
-:10F580008FB000100060102103E0000827BD0028A4
-:10F590003C090BFF00EA40243526FFFF00C8282B5A
-:10F5A00050A0FF93361200013C0B08008D6B002C1D
-:10F5B00036120005257000013C010800AC30002C1B
-:10F5C0000A0010F630EC01000A0010EB24100020B5
-:10F5D00000071602305F000F001F80C03C030801C7
-:10F5E00024639478020320211080FFADAF9F0010A8
-:10F5F000908800005100FFAB3C0380003C0D800070
-:10F6000035A90100952C000E240B00030240302187
-:10F61000318AFFFF25450004110B00D9000050215D
-:10F620009088000124140002311100FF123400BF41
-:10F6300030F80040310300FF24080001106800C8C2
-:10F6400030E200408C8A00048F8B00245560000655
-:10F6500034C60002254DFE002DAC0381558000010B
-:10F660003646004034C600020140202130A5FFFF8D
-:10F670000E000FDB30C6FFFF000040210A00110A18
-:10F680000100182100F8A0243C0902001289FF8F14
-:10F690003A28000290B100133270FFFF02002821C7
-:10F6A000322700FF24F30004001321C00A00115088
-:10F6B0003646000200E6282414A0FF323C0E8000EB
-:10F6C0000E0010543C1380008F8700000A0010E2E7
-:10F6D000AF82000C1680FF533C0600012624000474
-:10F6E0003085FFFF364600023C0380008C7101B874
-:10F6F0000620FFFE8F890008346A0180AD400000BB
-:10F70000112000B23C0D800024B800120138902B6B
-:10F71000124000AF240C0003347001009603002057
-:10F720002402001A30F94000307FFFFFA142000B95
-:10F73000132000AB27E3FFFE0123582B156000A91F
-:10F740002409FFFE35080001A5430014AF8800041A
-:10F750003C0E80002413BFFF0113782435C80180BC
-:10F76000A505000EA505001AA5060008A50F002690
-:10F77000A50700103C071000ADC701B80000182114
-:10F780008FBF00248FB400208FB3001C8FB20018ED
-:10F790008FB100148FB000100060102103E000084A
-:10F7A00027BD00283C1208008E5200D802202821D4
-:10F7B00024040080265100013C010800AC3100D82F
-:10F7C0000E000FDB240600030A0011D900001821E7
-:10F7D0008C65400030B1010012200046325900040F
-:10F7E0003C1F08008FFF002424140004172000028F
-:10F7F00033F0000D2414000200076AC239A400018E
-:10F800002E6C03EF30820001398B0001004B402544
-:10F81000110000033251FFFB2412FFFB021280246F
-:10F8200030E3010050600015321F00013C0A0F0058
-:10F8300000EA30243C07020010C7000F3C1980008A
-:10F840003725010090A900132418FFFE0218802418
-:10F85000312F00FF25EE0004000E21C0120000022F
-:10F86000023430253226FFFF0E000FDB3265FFFF2A
-:10F870001200FF3D00002021321F000113E0000DA7
-:10F88000320B000424080001120800020234302563
-:10F890003226FFFF000020210E000FDB3265FFFF44
-:10F8A0002402FFFE020280241200FF2F000020210C
-:10F8B000320B00045160000D240400010234302595
-:10F8C00024140004561400013226FFFF2411FFFB0C
-:10F8D0003265FFFF240401000E000FDB02119824A3
-:10F8E0001260FF2100002021240400010A001154AD
-:10F8F000008018213C0C08008D8C00243190000100
-:10F900005200FF19000020213265FFFF3646000239
-:10F910000E000FDB000020210A00115300002021FF
-:10F92000020028210A00115036460002130000068A
-:10F930000000000095300010949F000232190FFF64
-:10F9400013F9FF3D310300FF3C04080190849479D2
-:10F950001080FF3D240800010A00110A010018214F
-:10F960005040FF398C8A00040A00124B000000004E
-:10F970000E000FDB3246FFFB0A00114E001121C0C2
-:10F9800090830001240E0001106EFF3C240800014A
-:10F99000240F0002106F000430F30040240800011F
-:10F9A0000A00110A010018215260FFFD240800011D
-:10F9B000952500109487000230A9FFFF50E9FEA1B1
-:10F9C000010018210A00126124080001240C000320
-:10F9D00035AA0180A14C000B0A0011CE3C0E80001C
-:10F9E0002409FFFE0A0011CC0109402427BDFFC0F5
-:10F9F000AFB00018AFBF003C3C10600CAFBE003889
-:10FA0000AFB70034AFB60030AFB5002CAFB40028AC
-:10FA1000AFB30024AFB20020AFB1001C8E0E500077
-:10FA2000240FFF7F3C06800001CF682435AC380CE2
-:10FA3000240B0003AE0C5000ACCB00083C010800C6
-:10FA4000AC2000200E0017B0000000003C0A00109F
-:10FA5000354980513C066016AE09537C8CC70000C6
-:10FA60003C0860148D0500A03C03FFFF00E3202448
-:10FA70003C02535300051FC21082029B34C57C0018
-:10FA80008CBF007C8CA200783C1E600037C4202014
-:10FA90003C05080124A590C0AF820018AF9F001C50
-:10FAA0000E0016742406000A3C19000127399478C8
-:10FAB0003C010800AC3931DC0E00206BAF80001433
-:10FAC0008FD708082418FFF03C15570902F8B02416
-:10FAD00012D5028B24040001AF8000283C14800062
-:10FAE0003697010002E0F0218E90000032050003FD
-:10FAF00010A0FFFD3207000114E0005D3206000295
-:10FB000010C0FFF93C07800034E501408CB90000CB
-:10FB100024100040ACF9002090B8000833030070B6
-:10FB20001070010B286900411120000824080060B2
-:10FB3000241F0020107F000E3C0B40003C0680007C
-:10FB4000ACCB01780A0012B3000000001468FFFB80
-:10FB50003C0B40000E001F88000000003C0B4000E2
-:10FB60003C068000ACCB01780A0012B30000000014
-:10FB700090AB0009241100048CA70000316800FF3D
-:10FB80001111015D2512FFFA2E53000612600016B6
-:10FB90003C0680008CAA00048F86002494A3000AEF
-:10FBA000000A3E02310500FF10C000053064FFFF6F
-:10FBB0002CEC00081580000224E700042407000351
-:10FBC000240E000910AE01A128AF000A11E0018443
-:10FBD0002410000A2404000810A4001A000749C0D9
-:10FBE000012038213C0680008CD001B80600FFFEC1
-:10FBF00034C40180AC87000034C5014090B60008D1
-:10FC0000241900023C0B400032C200FF00028A00AF
-:10FC10000228F825A49F0008A099000B94A7000AC9
-:10FC20003C081000A48700108CB80004AC98002495
-:10FC3000ACC801B83C068000ACCB01780A0012B316
-:10FC400000000000000AC202330300FF2405000187
-:10FC50005465FFE4012038218F990020AF830024F0
-:10FC600027270001AF8700200A0012F20120382167
-:10FC70008FD100283C0B8008AE9100208FC6000475
-:10FC80008FCA000095690048AF860000AF8A000463
-:10FC90003128FFFF0E000FD4AF8800083C03080096
-:10FCA0008C6300C0106000258F8700003C0E0800A8
-:10FCB0008DCE00C425CD00013C010800AC2D00C450
-:10FCC0003C1F800037E901008D3900243C0760208B
-:10FCD000ACF90014000000003C0680003C08400025
-:10FCE000ACC80138000000005220FF853206000237
-:10FCF000262D0140262E00802404FF8001A4282404
-:10FD000001C47824000F194031CC007F00059940D0
-:10FD100031B2007F3C15200036A20002006C502555
-:10FD20000272B02502C2882501425825ACCB0830AA
-:10FD3000ACD108300A0012B9320600023C120010A1
-:10FD400000F2782415E000708F8300043C1808004E
-:10FD50008F18002097D6000E30F5400027130001C1
-:10FD60003C010800AC3300200000902112A000816B
-:10FD700032D3FFFF3C1F002000FFC8241320007E69
-:10FD800030E580008F8200042404BFFF00E43824A3
-:10FD900034431000AF87000030EB20001160007387
-:10FDA000240EFFBF3C0D000400ED60241180000212
-:10FDB000006E10243462004030EF010011E00010AA
-:10FDC000AF8200048F95002812A000073C18002085
-:10FDD00000F8B02412C000043C1F000400FFC82437
-:10FDE0001320016D0000000096E3001E96E8001C41
-:10FDF0003065FFFF0008140000A22025AF84000C2E
-:10FE000096EA000C8E8440003409FFFF10890085BB
-:10FE10003145FFFF3086010054C00001241200105C
-:10FE200030EB1000116000133656000130EC00205A
-:10FE30001580000A3C0E100000EE682411A0000D91
-:10FE40003C190C003C180BFF00F9B0243715FFFFDC
-:10FE500002B6782B11E00007365600013C1F08005F
-:10FE60008FFF002C3656000527F200013C010800E8
-:10FE7000AC32002C30E401001480000B3C06000181
-:10FE80008F880004310240005440000800E6282416
-:10FE90003C0A1F0100EA48243C0310001123010919
-:10FEA00030A602003C06000100E6282410A0003E17
-:10FEB0003C1810003C0D08008DAD002431AC000250
-:10FEC0001580000624030001006010211040FF830C
-:10FED0003C0680000A00132A3C1F80003C0F0800EB
-:10FEE0008DEF00D8026028212404008025EE000157
-:10FEF0003C010800AC2E00D80E000FDB24060003E6
-:10FF00000A0013AB000018212405BFFF0065682418
-:10FF100011A00007240F87FF006F702415C0000890
-:10FF20003C18006000F8202410800005000000004C
-:10FF30000E000D42000000000A0013AC000000009B
-:10FF40000E00159C000000000A0013AC0000000029
-:10FF50000E0015F4000000003C0B40003C06800041
-:10FF6000ACCB01780A0012B3000000000A0013674E
-:10FF7000006E102430E5800010A0FF878F830004FE
-:10FF80003C08002000E818245060FF838F830004A1
-:10FF90008F8900043C06FFFF34CA7FFF00EA382443
-:10FFA0000A00135E3523800000F8A82416A0001F65
-:10FFB00000004021AF8000103C0380003464010049
-:10FFC0009486000E8F93001030C5FFFF1100014E84
-:10FFD00024B5000430EA0100114000553A7F0002C8
-:10FFE0003C0E0F0000EE68243C0C020011AC0051E6
-:10FFF0002EB203EF908F001332B2FFFF31E400FF07
+:10F050008F85001435190100972A00163158FFFCDE
+:10F06000270F000401E870218DCD400031A6FFFF7D
+:10F0700014C000072403BFFF3C02FFFF34487FFF9A
+:10F0800000E83824AF8700048F8500142403BFFFF5
+:10F090003C04800000E3582434830180A46B0026E4
+:10F0A000AC69002C10A0000300054C02A465001000
+:10F0B000A46900263C071000AC8701B803E00008F3
+:10F0C000000000008F990004240AFFFE032A382460
+:10F0D0000A001003AF87000427BDFFE88FA20028B5
+:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99
+:10F0F000AF820014AF8000040E000FDBAF80000071
+:10F100008FBF001027BD001803E00008AF80001477
+:10F110003C06800034C4007034C701008C8A0000B3
+:10F1200090E500128F84000027BDFFF030A300FFA0
+:10F13000000318823082400010400037246500032D
+:10F140000005C8800326C0218F0E4000246F0004F4
+:10F15000000F6880AFAE000001A660218D8B4000DB
+:10F16000AFAB000494E900163128FFFC01063821FA
+:10F170008CE64000AFA600088FA9000800003021EF
+:10F18000000028213C07080024E701000A0010675E
+:10F19000240800089059000024A500012CAC000CA4
+:10F1A0000079C0210018788001E770218DCD000022
+:10F1B0001180000600CD302603A5102114A8FFF50C
+:10F1C00000051A005520FFF4905900003C0480000F
+:10F1D000348700703C0508008CA531048CE30000E6
+:10F1E0002CA2002010400009006A38230005488046
+:10F1F0003C0B0800256B3108012B402124AA00019B
+:10F20000AD0700003C010800AC2A310400C0102109
+:10F2100003E0000827BD0010308220001040000BE2
+:10F2200000055880016648218D24400024680004B0
+:10F2300000083880AFA4000000E618218C6540006B
+:10F24000AFA000080A001057AFA500040000000D91
+:10F250000A0010588FA9000827BDFFE03C07800076
+:10F2600034E60100AFBF001CAFB20018AFB100140C
+:10F27000AFB0001094C5000E8F87000030A4FFFFD0
+:10F280002483000430E2400010400010AF83002CC3
+:10F290003C09002000E940241100000D30EC800002
+:10F2A0008F8A0004240BBFFF00EB38243543100085
+:10F2B000AF87000030F220001640000B3C1900041C
+:10F2C000241FFFBF0A0010B7007F102430EC80001D
+:10F2D000158000423C0E002030F220001240FFF862
+:10F2E0008F8300043C19000400F9C0241300FFF5CB
+:10F2F000241FFFBF34620040AF82000430E20100EF
+:10F300001040001130F010008F83003010600006B4
+:10F310003C0F80003C05002000E52024148000C044
+:10F320003C0800043C0F800035EE010095CD001E26
+:10F3300095CC001C31AAFFFF000C5C00014B482556
+:10F34000AF89000C30F010001200000824110001F9
+:10F3500030F100201620008B3C18100000F890249B
+:10F36000164000823C040C002411000130E801002A
+:10F370001500000B3C0900018F85000430A94000F6
+:10F38000152000073C0900013C0C1F0100EC58242B
+:10F390003C0A1000116A01183C1080003C09000171
+:10F3A00000E9302410C000173C0B10003C18080086
+:10F3B0008F1800243307000214E0014024030001E9
+:10F3C0008FBF001C8FB200188FB100148FB00010D7
+:10F3D0000060102103E0000827BD002000EE682433
+:10F3E00011A0FFBE30F220008F8F00043C11FFFF00
+:10F3F00036307FFF00F0382435E380000A0010A685
+:10F40000AF87000000EB102450400065AF8000285B
+:10F410008F8C00303C0D0F0000ED18241580008803
+:10F42000AF83001030E8010011000086938F0010B8
+:10F430003C0A0200106A00833C1280003650010032
+:10F44000920500139789002E3626000230AF00FF88
+:10F4500025EE0004000E19C03C0480008C9801B811
+:10F460000700FFFE34880180AD0300003C198008CE
+:10F47000AC830020973100483225FFFF10A0015CCB
+:10F48000AF8500082523001200A3F82B53E0015993
+:10F490008F850004348D010095AC00202402001AF1
+:10F4A00030E44000318BFFFFA102000B108001927D
+:10F4B0002563FFFE00A3502B154001908F8F0004A1
+:10F4C000A50300148F88000435050001AF850004F2
+:10F4D0003C08800035190180A729000EA729001AD1
+:10F4E0008F89000C30B18000A7270010AF290028B9
+:10F4F000A72600081220000E3C04800035020100FF
+:10F50000944C0016318BFFFC256400040088182100
+:10F510008C7F400033E6FFFF14C000053C048000F0
+:10F520003C0AFFFF354D7FFF00AD2824AF85000466
+:10F53000240EBFFF00AE402434850180A4A800261D
+:10F54000ACA7002C3C071000AC8701B800001821C4
+:10F550008FBF001C8FB200188FB100148FB0001045
+:10F560000060102103E0000827BD00203C020BFFD3
+:10F5700000E41824345FFFFF03E3C82B5320FF7B14
+:10F58000241100013C0608008CC6002C24C5000193
+:10F590003C010800AC25002C0A0010D42411000501
+:10F5A0008F85002810A0002FAF80001090A30000CE
+:10F5B000146000792419000310A0002A30E601002D
+:10F5C00010C000CC8F860010241F000210DF00C97D
+:10F5D0008F8B000C3C0708008CE7003824E4FFFF09
+:10F5E00014E0000201641824000018213C0D0800FA
+:10F5F00025AD0038006D1021904C00048F85002C43
+:10F6000025830004000321C030A5FFFF3626000239
+:10F610000E000FDB000000000A00114D0000182151
+:10F6200000E8302414C0FF403C0F80000E00103D65
+:10F63000000000008F8700000A0010CAAF82000C93
+:10F64000938F00103C180801271896E0000F90C017
+:10F6500002588021AF9000288F85002814A0FFD386
+:10F66000AF8F00103C0480008C86400030C5010044
+:10F6700010A000BC322300043C0C08008D8C002438
+:10F6800024120004106000C23190000D3C04800080
+:10F690008C8D40003402FFFF11A201003231FFFBCC
+:10F6A0008C884000310A01005540000124110010EF
+:10F6B00030EE080011C000BE2419FFFB8F98002C0B
+:10F6C0002F0F03EF51E000010219802430E90100FF
+:10F6D00011200014320800018F87003014E000FB75
+:10F6E0008F8C000C3C05800034AB0100917F00132F
+:10F6F00033E300FF246A00042403FFFE0203802496
+:10F70000000A21C012000002023230253226FFFF1B
+:10F710000E000FDB9785002E1200FF290000182134
+:10F72000320800011100000D32180004240E0001FF
+:10F73000120E0002023230253226FFFF9785002E7E
+:10F740000E000FDB00002021240FFFFE020F80249B
+:10F750001200FF1B00001821321800045300FF188C
+:10F760002403000102323025241200045612000145
+:10F770003226FFFF9785002E0E000FDB24040100C8
+:10F780002419FFFB021988241220FF0D0000182104
+:10F790000A0010E9240300011079009C00003021C8
+:10F7A00090AD00012402000211A200BE30EA004028
+:10F7B00090B90001241800011338007F30E900409F
+:10F7C0008CA600049785002E00C020210E000FDBC0
+:10F7D0003626000200004021010018218FBF001CC6
+:10F7E0008FB200188FB100148FB00010006010218C
+:10F7F00003E0000827BD0020360F010095EE000C45
+:10F8000031CD020015A0FEE63C0900013C1880083D
+:10F81000971200489789002E362600023248FFFFD3
+:10F82000AF8800083C0380008C7101B80620FFFE01
+:10F83000346A0180AD4000001100008E3C0F800052
+:10F84000253F0012011FC82B1320008B240E00033C
+:10F85000346C0100958B00202402001A30E4400033
+:10F860003163FFFFA142000B108000A72463FFFE5D
+:10F870000103682B15A000A52408FFFE34A5000194
+:10F88000A5430014AF8500043C0480002412BFFF90
+:10F8900000B2802434850180A4A9000EA4A9001A16
+:10F8A000A4A60008A4B00026A4A700103C071000DE
+:10F8B000AC8701B80A00114D000018213C038000FC
+:10F8C00034640100949F000E3C1908008F3900D861
+:10F8D0002404008033E5FFFF273100013C010800CC
+:10F8E000AC3100D80E000FDB240600030A00114DD6
+:10F8F00000001821240A000210CA00598F85002C2C
+:10F900003C0308008C6300D0240E0001106E005EE2
+:10F910002CCF000C24D2FFFC2E5000041600002136
+:10F9200000002021241800021078001B2CD9000CA4
+:10F9300024DFFFF82FE900041520FF330000202109
+:10F9400030EB020051600004000621C054C00022C8
+:10F9500030A5FFFF000621C030A5FFFF0A00117D82
+:10F96000362600023C0908008D29002431300001B0
+:10F970005200FEF7000018219785002E362600025F
+:10F980000E000FDB000020210A00114D000018219D
+:10F990000A00119C241200021320FFE624DFFFF866
+:10F9A0000000202130A5FFFF0A00117D362600024D
+:10F9B0000A0011AC021980245120FF828CA6000499
+:10F9C0003C05080190A596E110A0FF7E24080001E7
+:10F9D0000A0011F0010018210E000FDB3226000191
+:10F9E0008F8600108F85002C0A00124F000621C060
+:10F9F0008F8500043C18800024120003371001801A
+:10FA0000A212000B0A00112E3C08800090A30001F6
+:10FA1000241100011071FF70240800012409000264
+:10FA20005069000430E60040240800010A0011F08B
+:10FA30000100182150C0FFFD240800013C0C80008B
+:10FA4000358B01009563001094A40002307FFFFF06
+:10FA5000509FFF62010018210A001284240800014F
+:10FA60002CA803EF1100FE56240300010A001239EE
+:10FA700000000000240E000335EA0180A14E000BB7
+:10FA80000A00121C3C04800011E0FFA2000621C005
+:10FA900030A5FFFF0A00117D362600020A0011A5DD
+:10FAA000241100201140FFC63C1280003650010096
+:10FAB000960F001094AE000231E80FFF15C8FFC08A
+:10FAC000000000000A0011E690B900013C060800A1
+:10FAD0008CC6003824C4FFFF14C00002018418241F
+:10FAE000000018213C0D080025AD0038006D1021E4
+:10FAF0000A0011B6904300048F8F0004240EFFFE0D
+:10FB00000A00112C01EE28242408FFFE0A00121A14
+:10FB100000A8282427BDFFC8AFB00010AFBF003435
+:10FB20003C10600CAFBE0030AFB7002CAFB6002861
+:10FB3000AFB50024AFB40020AFB3001CAFB20018C3
+:10FB4000AFB100148E0E5000240FFF7F3C068000E2
+:10FB500001CF682435AC380C240B0003AE0C5000E8
+:10FB6000ACCB00083C010800AC2000200E00184A75
+:10FB7000000000003C0A0010354980513C06601628
+:10FB8000AE09537C8CC700003C0860148D0500A0B2
+:10FB90003C03FFFF00E320243C02535300051FC237
+:10FBA0001482000634C57C000003A08002869821E0
+:10FBB0008E7200043C116000025128218CBF007C31
+:10FBC0008CA200783C1E600037C420203C05080150
+:10FBD00024A59328AF820018AF9F001C0E00170EBB
+:10FBE0002406000A3C190001273996E03C01080070
+:10FBF000AC3931DC0E002105AF8000148FD7080826
+:10FC00002418FFF03C15570902F8B02412D503243C
+:10FC100024040001AF8000303C148000369701803E
+:10FC20003C1E080127DE96E0369301008E9000000E
+:10FC30003205000310A0FFFD3207000110E000882C
+:10FC4000320600028E7100283C048000AE91002034
+:10FC50008E6500048E66000000A0382100C040219F
+:10FC60008C8301B80460FFFE3C0B0010240A0800DE
+:10FC700000AB4824AC8A01B8552000E2240ABFFF3B
+:10FC80009675000E3C1208008E52002030AC4000E9
+:10FC900032AFFFFF264E000125ED00043C010800B5
+:10FCA000AC2E0020118000EAAF8D002C3C18002003
+:10FCB00000B8B02412C000E730B980002408BFFFAC
+:10FCC00000A8382434C81000AF87000030E62000B8
+:10FCD00010C000EB2409FFBF3C03000400E328240C
+:10FCE00010A00002010910243502004030EA010092
+:10FCF00011400010AF8200048F8B003011600007AC
+:10FD00003C0D002000ED6024118000043C0F000435
+:10FD100000EF702411C00239000000009668001E38
+:10FD20009678001C3115FFFF0018B40002B690252C
+:10FD3000AF92000C30F910001320001324150001BD
+:10FD400030FF002017E0000A3C04100000E41024FB
+:10FD50001040000D3C0A0C003C090BFF00EA18247F
+:10FD60003525FFFF00A3302B10C0000830ED010047
+:10FD70003C0C08008D8C002C24150005258B0001FF
+:10FD80003C010800AC2B002C30ED010015A0000B4D
+:10FD90003C0500018F85000430AE400055C00007CF
+:10FDA0003C0500013C161F0100F690243C0F10009A
+:10FDB000124F01CE000000003C05000100E5302498
+:10FDC00010C000B13C0C10003C1F08008FFF002445
+:10FDD00033E90002152000732403000100601021A4
+:10FDE000104000083C0680003C188000370F0100DE
+:10FDF0008DEE00243C056020ACAE00140000000035
+:10FE00003C0680003C084000ACC8013800000000FF
+:10FE10005220001332060002262A0140262B0080C1
+:10FE2000240DFF80014D2024016D6024000C194039
+:10FE30003162007F0004A9403152007F3C1620004F
+:10FE400036C900020062F82502B2382500E988258B
+:10FE500003E9C825ACD90830ACD10830320600021D
+:10FE600010C0FF723C0F800035E501408CB80000E7
+:10FE700024100040ADF8002090AE000831C300709F
+:10FE8000107000D628680041510000082405006069
+:10FE9000241100201071000E3C0B40003C06800035
+:10FEA000ACCB01780A001304000000001465FFFBCE
+:10FEB0003C0B40000E002022000000003C0B4000E4
+:10FEC0003C068000ACCB01780A001304000000005F
+:10FED00090BF0009241900048CA7000033E900FF3B
+:10FEE000113901B22523FFFA2C72000612400016C8
+:10FEF0003C0680008CAB00048F86002494A2000A8C
+:10FF0000000B5602312500FF10C000053044FFFFF2
+:10FF10002D4C000815800002254A0004240A000325
+:10FF20002410000910B001F828AE000A11C001DC4D
+:10FF3000240F000A2404000810A40028000A41C06D
+:10FF4000010038213C0680008CC801B80500FFFE86
+:10FF500034D00180AE07000034C401409085000811
+:10FF6000240A00023C0B400030B900FF00198A004F
+:10FF70000229C025A6180008A20A000B948F000AC7
+:10FF80003C091000A60F00108C8E0004AE0E002459
+:10FF9000ACC901B83C068000ACCB01780A00130460
+:10FFA000000000003C0A8000354401009483000EEC
+:10FFB0003C0208008C4200D8240400803065FFFF1A
+:10FFC000245500013C010800AC3500D80E000FDBC1
+:10FFD000240600030A00137000001821000BC2025F
+:10FFE000330300FF240A0001146AFFD60100382100
+:10FFF0008F910020AF830024262B00010A0013CA32
:020000040001F9
-:1000000024870004000721C00240282136C60002D0
-:100010000E000FDB00000000000020210A0013ABDF
-:10002000008018210A0013812412002000072602F4
-:100030003099000F0019F8C03C120801265294783C
-:1000400003F240211100FFDCAF990010910900007C
-:100050001120FFDA3C0380003C138000366A010067
-:10006000954B000E2403000302C030213162FFFFD4
-:1000700024450004112300EC000020219109000117
-:10008000240D0002312E00FF11CD00FA313200FFA5
-:10009000240900011249001030FF00408D040004C3
-:1000A0008F8300241460000634D30002248BFE00EA
-:1000B0002D6203815440000136C6004034D3000253
-:1000C00030A5FFFF0E000FDB3266FFFF0000482166
-:1000D0000A0013AB0120182153E0FFF18D04000446
-:1000E0003C080801910894791100FFED24090001F2
-:1000F0000A0013AB012018213C0480008C8A01B84F
-:100100000540FFFE349601802415001CAEC7000098
-:10011000A2D5000B3C021000AC8201B83C0B4000A1
-:100120003C068000ACCB01780A0012B3000000004E
-:100130002EB203EF2FF900013A4900010329C02430
-:100140001700FFB6240400013C0308008C6300D0B4
-:100150002E65000C001321C0386B00012D620001D8
-:10016000004540241500FFA832B2FFFF266AFFFCBD
-:100170002D46000414C0001300002021386D000239
-:100180002DAC0001018518241460000F02402821C5
-:10019000266EFFF82DC5000414A0FF9B0000000090
-:1001A00000077A420013382B01E7A82456A0000864
-:1001B00002402821001321C0024028210A0013FD1B
-:1001C00036C60002024028210A0013FD36C600028E
-:1001D0000E000FDB32C6FFFB0A001467001321C0BC
-:1001E00010B0007200045A022406000B14A6FE7C14
-:1001F000000749C0314600FF00065600000A5E03B2
-:10020000056200B030C6007F000670C03C0F0801D8
-:1002100025EF947801CFA821A2A00001A2A00000A0
-:100220003C1360008E631820240D000100CD4804AB
-:1002300000096027000749C0006C90240120382184
-:10024000AE7218200A0012F2A6A0000214C0004BE1
-:100250008F8C0020000749C03C0B8000AD69002056
-:100260003C118008963F004013E000022405000185
-:10027000240500413C0480008C8A01B80540FFFE43
-:100280003496018024120003AEC90000A2D2000BF4
-:10029000A6C0000EA6C0001AA6C00010AEC000285E
-:1002A000A6C5000896D3002636750001A6D50026FF
-:1002B000AEC0002C3C021000AC8201B80A0012F261
-:1002C0000120382114C0FEF83C060001266B000412
-:1002D0003165FFFF36C600023C0380008C7301B815
-:1002E0000660FFFE8F8900083C0D800035AC018060
-:1002F000AD800000512000DD3C09800024AF0012D9
-:10030000012F702B51C000D93C09800096F20020CB
-:100310003C1980002418001A3256FFFF372A01804A
-:1003200030F54000A158000B12A000D526C3FFFEF7
-:100330000123F82B17E000D32404FFFE3508000149
-:10034000A5430014AF8800042413BFFF3C0B8000BA
-:100350000113502435680180A505000EA505001A7B
-:10036000A5060008A50A0026A50700103C071000F6
-:10037000AE8701B80A0013AB00001821000749C07E
-:100380002583FFFF1460FE16AF8300200120382173
-:100390000A0012F2AF8000240E001054000000008A
-:1003A0008F8700000A001379AF82000C240300FF3E
-:1003B0001163FE0B000749C010C00038000B760027
-:1003C000000B20C03C0908012529947800891821D8
-:1003D00024020001A06200003C16080126D6947891
-:1003E0003C0208012442947C00962821000749C061
-:1003F00000828821000AFC02AE290000A0BF000193
-:100400003C0460008C9818202419000101793804FC
-:100410000307302501203821A4AA0002AC86182049
-:100420000A0012F33C06800091030001241600012B
-:100430001076FF272409000124050002106500043E
-:1004400030E60040240900010A0013AB0120182106
-:1004500050C0FFFD24090001954C0010950A0002D0
-:100460003187FFFF5147FE98012018210A00150B24
-:100470002409000130EF004011E0FF1900000000E6
-:10048000955900109518000233350FFF1715FF140A
-:10049000313200FF0A00141E24090001000E6E0311
-:1004A00005A2000F316B007F10E30008000B20C095
-:1004B0003C10080126109478009018210A0014EED0
-:1004C000240200020A00147BAF8000203C0F0801C8
-:1004D00025EF9478008F18210A0014EE24020003FF
-:1004E0000A001523AF8B00200003A080028698210C
-:1004F0008E7200043C1160000A00129902512821FA
-:100500000A0012B0AF8400288C64400030930100D0
-:100510001260004B240900043C1908008F390024A4
-:1005200032D80004AFA90010170000033332000DC9
-:10053000241F0002AFBF001000071AC2386A000172
-:100540002EA603EF3142000138CB0001004B4025BD
-:100550001100000332D3FFFB2416FFFB0256902448
-:1005600030EC010011800016324800013C0E0F00F3
-:1005700000EE28243C0D020010AD00113C1F80004D
-:1005800037E90100913800138FAF00102419FFFEE6
-:10059000330400FF2487000402599024000721C07F
-:1005A00012400002026F30253266FFFF0E000FDBA3
-:1005B00032A5FFFF1240FE990000202132480001C1
-:1005C0001100000E324A00048FAB0010240200011B
-:1005D00012420002026B30253266FFFF000020212C
-:1005E0000E000FDB32A5FFFF2406FFFE024690241B
-:1005F0001240FE8A00002021324A00045140000EC1
-:10060000240400018FB600102403000412430002EA
-:10061000027630253266FFFF2413FFFB32A5FFFF71
-:10062000240401000E000FDB0253A82412A0FE7B5D
-:1006300000002021240400010A0013AB00801821CF
-:100640003C0C08008D8C0024319200015240FE7356
-:100650000000202132A5FFFF36C600020E000FDB8E
-:10066000000020210A0014000000202124020003C1
-:1006700035230180A062000B0A0014CC2413BFFFB5
-:100680002404FFFE0A0014CA010440243C03800035
-:10069000346401008C85000030A2003E1440000844
-:1006A00000000000AC6000488C87000030E607C006
-:1006B00010C0000500000000AC60004CAC600050B1
-:1006C00003E0000824020001AC600054AC6000406C
-:1006D0008C880000310438001080FFF90000000011
-:1006E0002402000103E00008AC6000443C038000E9
-:1006F0008C6201B80440FFFE34670180ACE4000066
-:1007000024080001ACE00004A4E500082405000270
-:10071000A0E8000A34640140A0E5000B9483000ABD
-:1007200014C00008A4E30010ACE000243C078000E3
-:1007300034E901803C041000AD20002803E00008EB
-:10074000ACE401B88C8600043C041000ACE6002444
-:100750003C07800034E90180AD20002803E0000858
-:10076000ACE401B83C0680008CC201B80440FFFE36
-:1007700034C7018024090002ACE40000ACE40004AA
-:10078000A4E50008A0E9000A34C50140A0E9000B77
-:1007900094A8000A3C041000A4E80010ACE0002477
-:1007A0008CA30004ACE3002803E00008ACC401B84B
-:1007B0003C03900034620001008220253C0380004D
-:1007C000AC6400208C65002004A0FFFE0000000047
-:1007D00003E00008000000003C02800034430001F8
-:1007E0000083202503E00008AC44002027BDFFE083
-:1007F0003C098000AFBF0018AFB10014AFB00010CB
-:10080000352801408D10000091040009910700086F
-:1008100091050008308400FF30E600FF00061A0052
-:100820002C820081008330251040002A30A50080F2
-:10083000000460803C0D080125AD90E8018D582131
-:100840008D6A000001400008000000003C038000A9
-:10085000346201409445000A14A0001E8F91FCB838
-:100860009227000530E6000414C0001A00000000C2
-:100870000E0015E502002021922A00050200202129
-:10088000354900040E0015EFA22900059228000545
-:100890003104000414800002000000000000000D7C
-:1008A000922D0000240B002031AC00FF158B0009B5
-:1008B0003C0580008CAE01B805C0FFFE34B101805C
-:1008C000AE3000003C0F100024100005A230000BD9
-:1008D000ACAF01B80000000D8FBF00188FB100143D
-:1008E0008FB0001003E0000827BD00200200202187
-:1008F00000C028218FBF00188FB100148FB00010E6
-:10090000240600010A0015B427BD00200000000DD8
-:100910000200202100C028218FBF00188FB10014D1
-:100920008FB00010000030210A0015B427BD002050
-:1009300014A0FFE800000000020020218FBF001873
-:100940008FB100148FB0001000C028210A0015D20A
-:1009500027BD00203C0780008CEE01B805C0FFFEDB
-:1009600034F00180241F0002A21F000B34F8014064
-:10097000A60600089719000A3C0F1000A6190010DF
-:100980008F110004A6110012ACEF01B80A00163056
-:100990008FBF001827BDFFE8AFBF00100E000FD4B7
-:1009A000000000003C0280008FBF001000002021EA
-:1009B000AC4001800A0010A627BD00183084FFFF5C
-:1009C00030A5FFFF108000070000182130820001D1
-:1009D0001040000200042042006518211480FFFB33
-:1009E0000005284003E000080060102110C0000747
-:1009F000000000008CA2000024C6FFFF24A5000414
-:100A0000AC82000014C0FFFB2484000403E0000853
-:100A10000000000010A0000824A3FFFFAC86000027
-:100A200000000000000000002402FFFF2463FFFF1D
-:100A30001462FFFA2484000403E0000800000000B0
-:100A40003C03800027BDFFF834620180AFA20000A4
-:100A5000308C00FF30AD00FF30CE00FF3C0B80003B
-:100A60008D6401B80480FFFE000000008FA9000023
-:100A70008D6801288FAA00008FA700008FA40000B6
-:100A80002405000124020002A085000A8FA30000B3
-:100A9000359940003C051000A062000B8FB80000A3
-:100AA0008FAC00008FA600008FAF000027BD0008AC
-:100AB000AD280000AD400004AD800024ACC000288B
-:100AC000A4F90008A70D0010A5EE001203E000082D
-:100AD000AD6501B83C06800827BDFFE834C500803D
-:100AE000AFBF001090A700092402001230E300FFFE
-:100AF0001062000B008030218CA800500088202359
-:100B0000048000088FBF00108CAA00342404003930
-:100B10000000282100CA48230520000524060012F1
-:100B20008FBF00102402000103E0000827BD001859
-:100B30000E001689000000008FBF00102402000183
-:100B400003E0000827BD001827BDFFC8AFB2003082
-:100B5000AFB00028AFBF0034AFB1002C00A080219F
-:100B600090A5000D30A6001010C00010008090214C
-:100B70003C0280088C4400048E0300081064000CC2
-:100B800030A7000530A6000510C000932404000122
-:100B90008FBF00348FB200308FB1002C8FB000288F
-:100BA0000080102103E0000827BD003830A70005B1
-:100BB00010E0000F30AB001210C00006240400014A
-:100BC0003C0980088E0800088D2500045105009C12
-:100BD000240400388FBF00348FB200308FB1002C56
-:100BE0008FB000280080102103E0000827BD0038E6
-:100BF000240A0012156AFFE62404000102002021E5
-:100C000027A500100E000CB6AFA000101440007C09
-:100C10003C198008372400809098000833110008A0
-:100C20001220000A8FA7001030FF010013E000A47B
-:100C30008FA300148C860058006610230440000423
-:100C40003C0A8008AC8300588FA700103C0A80083B
-:100C50003548008091090008312400081480000202
-:100C600024080003000040213C1F800893F100117C
-:100C700093F9001237E600808CCC0054333800FF23
-:100C800003087821322D00FF000F708001AE28216B
-:100C900000AC582B1160006F0000000094CA005C8B
-:100CA0008CC900543144FFFF012510230082182B0A
-:100CB00014600068000000008CCB0054016518230C
-:100CC00030EC00041180006C000830808FA8001CFC
-:100CD0000068102B1040006230ED00040066102305
-:100CE0002C46008010C000020040882124110080A2
-:100CF0000E0015E5024020213C0D800835A600803D
-:100D000024070001ACC7000C90C80008001148403F
-:100D100035A70100310C007FA0CC00088E0500042F
-:100D200024AB0001ACCB0030A4D1005C8CCA003CE9
-:100D30009602000E01422021ACC400208CC3003C6E
-:100D40000069F821ACDF001C8E190004ACF900002A
-:100D50008E180008ACF800048FB10010322F000884
-:100D600055E0004793A60020A0C0004E90D8004E4A
-:100D70002411FFDFA0F8000890CF000801F17024D3
-:100D8000A0CE00088E0500083C0B80083569008065
-:100D9000AD2500388D6A00148D22003024190050D2
-:100DA00001422021AD24003491230000307F00FF58
-:100DB00013F90036264F01000E0015EF02402021E6
-:100DC00024040038000028210E0016892406000A99
-:100DD0000A0016EE240400010E000D280000202158
-:100DE0008FBF00348FB200308FB1002C8FB000283D
-:100DF000004020210080102103E0000827BD0038BA
-:100E00008E0E00083C0F800835F00080AE0E0054B6
-:100E100002402021AE0000300E0015E50000000069
-:100E2000920D00250240202135AC00200E0015EF68
-:100E3000A20C00250E000CAC024020212404003836
-:100E40002405008D0E001689240600120A0016EEF5
-:100E50002404000194C5005C0A00172930A3FFFF99
-:100E60002407021811A0FF9E00E610238FAE001C7D
-:100E70000A00173101C610230A00172E2C6202182F
-:100E8000A0E600080A00175B8E0500082406FF8014
-:100E900001E6C0243C118000AE3800288E0D000809
-:100EA00031E7007F3C0E800C00EE6021AD8D00E04C
-:100EB0008E080008AF8C00340A001767AD8800E484
-:100EC000AC800058908500082403FFF700A3382465
-:100ED000A08700080A00170C8FA700103C05080027
-:100EE00024A55F043C04080024846E503C020800E2
-:100EF00024425F0C240300063C010801AC2594F851
-:100F00003C010801AC2494FC3C010801AC22950092
-:100F10003C010801A023950403E000080000000044
-:100F200003E00008240200013C028000308800FF3A
-:100F3000344701803C0680008CC301B80460FFFE8A
-:100F4000000000008CC501282418FF803C0D800A99
-:100F500024AF010001F8702431EC007FACCE0024F6
-:100F6000018D2021ACE50000948B00EA350960007A
-:100F700024080002316AFFFFACEA000424020001E9
-:100F8000A4E90008A0E8000BACE000243C07100036
-:100F9000ACC701B8AF84003403E00008AF85006837
-:100FA000938800448F89005C8F82003430C600FF34
-:100FB0000109382330E900FF0122182130A500FF84
-:100FC0002468008810C000020124382100803821E4
-:100FD00030E400031480000330AA00031140000D28
-:100FE000312B000310A000090000102190ED00003B
-:100FF000244E000131C200FF0045602BA10D00000E
-:1010000024E700011580FFF92508000103E000082E
-:10101000000000001560FFF30000000010A0FFFBBF
-:10102000000010218CF8000024590004332200FF36
-:101030000045782BAD18000024E7000415E0FFF907
-:101040002508000403E00008000000009385004428
-:10105000938800548F87005C000432003103007FC6
-:1010600000E5102B30C47F001040000F00642825DD
-:101070008F8400343C0980008C8A00ECAD2A00A4E7
-:101080003C03800000A35825AC6B00A08C6C00A032
-:101090000580FFFE000000008C6D00ACAC8D00EC04
-:1010A00003E000088C6200A80A0018198F8400343D
-:1010B000938800553C02800000805021310300FEDF
-:1010C000A383005530ABFFFF30CC00FF30E7FFFFBC
-:1010D000344801803C0980008D2401B80480FFFE63
-:1010E0008F8D006824180016AD0D00008D2201249C
-:1010F0008F8D0034AD0200048D590020A507000833
-:10110000240201C4A119000AA118000B952F012087
-:101110008D4E00088D470004978300588D59002498
-:1011200001CF302100C7282100A320232418FFFF6E
-:10113000A504000CA50B000EA5020010A50C0012C2
-:10114000AD190018AD18002495AF00E83C0B100055
-:101150002407FFF731EEFFFFAD0E00288DAC0084B1
-:10116000AD0C002CAD2B01B88D46002000C7282403
-:1011700003E00008AD4500208F880034008058212E
-:1011800030E7FFFF910900D63C02800030A5FFFF49
-:10119000312400FF00041A000067502530C600FF0C
-:1011A000344701803C0980008D2C01B80580FFFE8A
-:1011B0008F820068240F0017ACE200008D390124F3
-:1011C000ACF900048D780020A4EA0008241901C4B9
-:1011D000A0F8000AA0EF000B952301208D6E0008F7
-:1011E0008D6D00049784005801C35021014D60218A
-:1011F00001841023A4E2000CA4E5000EA4F9001061
-:10120000A4E60012ACE000148D780024240DFFFF4A
-:10121000ACF800188D0F007CACEF001C8D0E007830
-:101220003C0F1000ACEE0020ACED0024950A00BE8F
-:10123000240DFFF73146FFFFACE60028950C008037
-:101240009504008231837FFF0003CA003082FFFFD4
-:101250000322C021ACF8002CAD2F01B8950E0082FE
-:101260008D6A002000AE3021014D2824A5060082A1
-:1012700003E00008AD6500203C0280003445018099
-:101280003C0480008C8301B80460FFFE8F8A00401C
-:10129000240600199549001C3128FFFF000839C0B9
-:1012A000ACA70000A0A6000B3C05100003E000085E
-:1012B000AC8501B88F8700480080402130C400FF12
-:1012C0003C0680008CC201B80440FFFE8F89006894
-:1012D0009383006434996000ACA90000A0A30005CA
-:1012E0008CE20010240F00022403FFF7A4A20006E2
-:1012F000A4B900088D180020A0B8000AA0AF000B08
-:101300008CEE0000ACAE00108CED0004ACAD00140F
-:101310008CEC001CACAC00248CEB0020ACAB0028A7
-:101320008CEA002C3C071000ACAA002C8D0900248C
-:10133000ACA90018ACC701B88D05002000A320247B
-:1013400003E00008AD0400208F86003427BDFFE0D5
-:10135000AFB10014AFBF0018AFB0001090C300D4FD
-:1013600030A500FF30620020104000080080882176
-:101370008CCB00D02409FFDF256A0001ACCA00D065
-:1013800090C800D401093824A0C700D414A000409C
-:101390003C0C80008F840034908700D42418FFBF59
-:1013A0002406FFEF30E3007FA08300D4979F00580E
-:1013B0008F82005C8F8D003403E2C823A799005808
-:1013C000A5A000BC91AF00D401F87024A1AE00D458
-:1013D0008F8C0034A18000D78F8A0034A540008212
-:1013E000AD4000EC914500D400A65824A14B00D498
-:1013F0008F9000308F84005C97860058020428216B
-:1014000010C0000FAF850030A38000543C0780005F
-:101410008E2C000894ED01208E2B0004018D5021AC
-:10142000014B8021020620233086FFFF30C8000FC9
-:10143000390900013131000116200009A388005448
-:10144000938600448FBF00188FB100148FB0001036
-:1014500027BD0020AF85006003E00008AF86005C78
-:1014600000C870238FBF0018938600448FB100140A
-:101470008FB0001034EF0C00010F282127BD002091
-:10148000ACEE0084AF85006003E00008AF86005C2E
-:1014900035900180020028210E0018A62406008243
-:1014A0008F840034908600D430C5004050A0FFBA2D
-:1014B000A38000648F8500483C0680008CCD01B875
-:1014C00005A0FFFE8F8900682408608224070002BF
-:1014D000AE090000A6080008A207000B8CA30008B4
-:1014E0003C0E1000AE0300108CA2000CAE020014E3
-:1014F0008CBF0014AE1F00188CB90018AE19002460
-:101500008CB80024AE1800288CAF0028AE0F002C39
-:10151000ACCE01B80A0018DFA38000648F8A0034C3
-:1015200027BDFFE0AFB10014AFB000108F88005CA2
-:10153000AFBF001893890038954200BC30D100FF3E
-:101540000109182B0080802130AC00FF3047FFFFDD
-:101550000000582114600003310600FF01203021F3
-:1015600001095823978300580068202B1480002716
-:101570000000000010680056241900011199006352
-:1015800034E708803165FFFF0E0018570200202164
-:101590008F8300683C07800034E601803C058000B2
-:1015A0008CAB01B80560FFFE240A00188F8400345C
-:1015B000ACC30000A0CA000B948900BE3C08100018
-:1015C000A4C90010ACC00030ACA801B8948200805F
-:1015D00024430001A4830080949F00803C060800FF
-:1015E0008CC6318833EC7FFF1186005E000000005E
-:1015F00002002021022028218FBF00188FB1001483
-:101600008FB000100A0018CB27BD0020914400D4F1
-:101610002403FF8000838825A15100D497840058BB
-:101620003088FFFF51000023938C00388F850034F1
-:101630002402EFFF008B782394AE00BC0168502B8E
-:1016400031E900FF01C26824A4AD00BC514000395B
-:10165000010058213C1F800037E601008CD80004AF
-:101660003C190001031940245500000134E74000F3
-:101670008E0A00202403FFFB2411000101432024D3
-:10168000AE0400201191002D34E7800002002021DB
-:10169000012030210E0018573165FFFF9787005851
-:1016A0008F89005CA780005801278023AF90005CE1
-:1016B000938C00388F8B00348FBF00188FB10014CB
-:1016C0008FB0001027BD002003E00008A16C00D7F8
-:1016D0003C0D800035AA01008D4800043C09000142
-:1016E0000109282454A0000134E740008E0F002097
-:1016F0002418FFFB34E7800001F87024241900014E
-:10170000AE0E00201599FF9F34E7088002002021CB
-:101710000E0018253165FFFF02002021022028213C
-:101720008FBF00188FB100148FB000100A0018CBC3
-:1017300027BD00200A00198E000048210200202148
-:10174000012030210E0018253165FFFF97870058D2
-:101750008F89005CA7800058012780230A0019A503
-:10176000AF90005C948C0080241F8000019F302487
-:10177000A4860080908B0080908F0080316700FFEE
-:101780000007C9C20019C027001871C031ED007FE1
-:1017900001AE2825A08500800A00197602002021CC
-:1017A000938500642403000127BDFFE800A33004F3
-:1017B0002CA20020AFB00010AFBF001400C0182151
-:1017C000104000132410FFFE3C0708008CE7319006
-:1017D00000E610243C088000350501801440000517
-:1017E000240600848F890034240A00042410FFFF9B
-:1017F000A12A00FC0E0018A6000000000200102123
-:101800008FBF00148FB0001003E0000827BD001840
-:101810003C0608008CC631940A0019EE00C310245F
-:101820008F87004027BDFFE0AFB20018AFB10014B2
-:10183000AFB00010AFBF001C30D000FF90E6000D2D
-:1018400000A088210080902130C5007FA0E5000D18
-:101850008F8500348E2300188CA200D01062002ED9
-:10186000240A000E0E0019E1A38A00642409FFFF78
-:10187000104900222404FFFF520000200000202114
-:101880008E2600003C0C001000CC58241560003956
-:101890003C0E000800CE682455A0003F02402021E5
-:1018A0003C18000200D880241200001F3C0A0004EB
-:1018B0008F8700408CE200148CE300108CE500144C
-:1018C0000043F82303E5C82B132000050240202124
-:1018D0008E24002C8CF10010109100310240202148
-:1018E00024020012A38200640E0019E12412FFFFFB
-:1018F000105200022404FFFF000020218FBF001CB3
-:101900008FB200188FB100148FB00010008010212A
-:1019100003E0000827BD002090A800D43504002073
-:101920000A001A17A0A400D400CA48241520000BEE
-:101930008F8B00408F8D00408DAC00101580000B08
-:10194000024020218E2E002C51C0FFEC00002021EF
-:10195000024020210A001A32240200178D6600106E
-:1019600050C0FFE600002021024020210A001A3268
-:101970002402001102402021240200150E0019E16A
-:10198000A3820064240FFFFF104FFFDC2404FFFF3D
-:101990000A001A218E2600000A001A582402001498
-:1019A0003C08000400C8382450E0FFD40000202187
-:1019B000024020210A001A32240200138F850034CD
-:1019C00027BDFFD8AFB3001CAFB20018AFB10014F1
-:1019D000AFB00010AFBF002090A700D48F90004898
-:1019E0002412FFFF34E2004092060000A0A200D4BF
-:1019F0008E030010008098211072000630D1003F45
-:101A00002408000D0E0019E1A3880064105200257F
-:101A10002404FFFF8F8A00348E0900188D4400D003
-:101A20001124000702602021240C000E0E0019E191
-:101A3000A38C0064240BFFFF104B001A2404FFFF4B
-:101A400024040020122400048F8D003491AF00D4B0
-:101A500035EE0020A1AE00D48F85005010A00019F3
-:101A6000000000001224004A8F9800348F92FCB8C6
-:101A7000971000809651000A523000488F93003C26
-:101A80003C1F08008FFF318C03E5C82B1720001E78
-:101A900002602021000028210E00194024060001C8
-:101AA000000020218FBF00208FB3001C8FB20018D0
-:101AB0008FB100148FB000100080102103E00008E7
-:101AC00027BD00285224002A8E0500148F8400347C
-:101AD000948A008025490001A489008094880080B0
-:101AE0003C0208008C42318831077FFF10E2000E73
-:101AF00000000000026020210E0018CB2405000128
-:101B00000A001AA2000020212402002D0E0019E173
-:101B1000A38200642403FFFF1443FFE12404FFFFBA
-:101B20000A001AA38FBF002094990080241F800010
-:101B300024050001033FC024A498008090920080F7
-:101B4000908E0080325100FF001181C20010782772
-:101B5000000F69C031CC007F018D5825A08B00801B
-:101B60000E0018CB026020210A001AA200002021DA
-:101B70002406FFFF54A6FFD68F8400340260202184
-:101B80000E0018CB240500010A001AA20000202133
-:101B9000026020210A001ABC2402000A2404FFFD6E
-:101BA0000A001AA2AF93005C8F88003427BDFFE8BB
-:101BB000AFB00010AFBF0014910A00D48F87004867
-:101BC00000808021354900408CE60010A10900D436
-:101BD0003C0208008C4231B030C53FFF00A2182BF8
-:101BE000106000078F85004C240DFF8090AE000D23
-:101BF00001AE6024318B00FF156000080006C3822F
-:101C0000020020212403000D8FBF00148FB00010AC
-:101C100027BD00180A0019E1A383006433060003FE
-:101C2000240F000254CFFFF70200202194A2001CD1
-:101C30008F85003424190023A4A200E88CE800005A
-:101C400000081E02307F003F13F900353C0A008374
-:101C50008CE800188CA600D01106000800000000D7
-:101C60002405000E0E0019E1A38500642407FFFF80
-:101C7000104700182404FFFF8F85003490A900D47A
-:101C800035240020A0A400D48F8C0040918E000D3C
-:101C900031CD007FA18D000D8F8300501060001C9E
-:101CA000020020218F84004C8C9800100303782BB5
-:101CB00011E0000D2419001802002021A3990064EE
-:101CC0000E0019E12410FFFF105000022404FFFF52
-:101CD000000020218FBF00148FB000100080102161
-:101CE00003E0000827BD00188C8600108F9F00407D
-:101CF0000200202100C31023AFE2001024050001E0
-:101D00000E001940240600010A001B2E00002021AD
-:101D10000E0018CB240500010A001B2E0000202114
-:101D2000010A5824156AFFD98F8C0040A0A600FC38
-:101D30000A001B1BA386005630A500FF24060001E5
-:101D400024A9000100C9102B1040000C0000402104
-:101D5000240A000100A61823308B000124C60001CC
-:101D6000006A3804000420421160000200C9182BE8
-:101D7000010740251460FFF800A6182303E00008BF
-:101D80000100102127BDFFD8AFB000188F90004888
-:101D9000AFB1001CAFBF00202403FFFF2411002FB0
-:101DA000AFA30010920600002405000826100001D1
-:101DB000006620260E001B47308400FF00021E0034
-:101DC0003C021EDC34466F410A001B6F00001021EC
-:101DD00010A00009008018212445000130A2FFFF57
-:101DE0002C4500080461FFFA0003204000862026ED
-:101DF00014A0FFF9008018210E001B4724050020C5
-:101E00008FA300102629FFFF313100FF000342029B
-:101E1000240700FF1627FFE20102182600035027BF
-:101E2000AFAA0014AFAA00100000302127A80010AC
-:101E300027A7001400E6782391ED000324CE0001CB
-:101E400000C8602131C600FF2CCB00041560FFF9EB
-:101E5000A18D00008FA200108FBF00208FB1001C49
-:101E60008FB0001803E0000827BD002827BDFFD071
-:101E7000AFB3001CAFB00010AFBF0028AFB5002457
-:101E8000AFB40020AFB20018AFB100143C0C80001A
-:101E90008D880128240FFF803C06800A2510010050
-:101EA000250B0080020F68243205007F016F70242B
-:101EB000AD8E009000A62821AD8D002490A600FCD8
-:101EC0003169007F3C0A8004012A1821A38600564C
-:101ED0009067007C00809821AF83002C30E20002E4
-:101EE000AF880068AF85003400A0182114400002BC
-:101EF0002404003424040030A38400448C7200DCE9
-:101F000030D100FF24040004AF92005C12240004CE
-:101F1000A38000648E7400041680001E3C088000BC
-:101F20009386005530C7000150E0000F8F86005C9B
-:101F30008CA400848CA800842413FF800093602468
-:101F4000000C49403110007F013078253C192000F9
-:101F500001F9682530DF00FE3C038000AC6D0830DD
-:101F6000A39F00558F86005C8FBF00288FB500248B
-:101F70008FB400208FB3001C8FB200188FB10014F3
-:101F80008FB000102402000127BD003003E00008DC
-:101F9000ACA600DC8E7F0008950201208E67001041
-:101FA00003E2C8213326FFFF30D8000F33150001AC
-:101FB000AF87003016A00058A398005435090C00D4
-:101FC0000309382100D81823AD030084AF870060CF
-:101FD0008E6A00043148FFFF1100007EA78A005876
-:101FE00090AC00D42407FF8000EC302430CB00FFFD
-:101FF0001560004B97860058938E0056240D000202
-:1020000030D5FFFF11CD02A20000A0218F85005C1A
-:1020100002A5802B160000BC938800443C11800070
-:1020200096240120310400FF148500888F8400600D
-:102030008F980030331200035640008530A500FF12
-:102040008F900060310C00FF24060034118600954B
-:10205000AF90004892040004148001198F8E003460
-:10206000A38000388E0D00048DC800D83C0600FF08
-:1020700034CCFFFF01AC30240106182B1460012181
-:10208000AF8600508F87005C97980058AF87003C60
-:102090000307402310C000C7A78800588F91002C69
-:1020A00030C3000300035823922A007C31710003DF
-:1020B00002261021000A208230920001001248807E
-:1020C00000492821311FFFFF03E5C82B1320012001
-:1020D0008F8800348F8500308F8800601105025A88
-:1020E0003C0E3F018E0600003C0C250000CE68240B
-:1020F00011AC01638F84004830E500FF0E0017E14A
-:10210000000030218F8800348F87005C8F8500307D
-:102110000A001D4E8F8600500A001BEDAF8700603D
-:1021200090AC00D400EC2024309000FF1200001688
-:102130009386005590B5008890B400D724A80088F5
-:1021400032A2003F2446FFE02CD10020A3940038A7
-:102150001220000CAF880048240E000100CE20049D
-:10216000308A00191540012B3C06800034D800024B
-:10217000009858241560022E309200201640023438
-:10218000000000009386005530CE000111C0000F02
-:10219000978800588CA900848CAF00842410FF809D
-:1021A0000130C8240019194031ED007F006D382539
-:1021B0003C1F200000FF902530CB00FE3C18800023
-:1021C000AF120830A38B0055978800581500FF8484
-:1021D000000000008E630020306C00041180FF516D
-:1021E000938600552404FFFB006430243C038000E8
-:1021F000AE660020346601808C7301B80660FFFE75
-:102200008F8E0068346A01003C150001ACCE0000DE
-:102210008C62012424076085ACC200048D54000444
-:1022200002958824522000012407608324120002B2
-:102230003C1810003C0B8000A4C70008A0D2000B83
-:10224000AD7801B80A001BC29386005530A500FF87
-:102250000E0017E1240600018F8800683C0580000D
-:1022600034A909002502018893880044304A0007F8
-:10227000304B00783C0340802407FF800163C82571
-:10228000014980210047F824310C00FF2406003466
-:10229000ACBF0800AF900048ACB908105586FF6E7F
-:1022A000920400048F8400348E110030908E00D48C
-:1022B00031CD001015A000108F83005C2C6F00053D
-:1022C00015E000E400000000909800D42465FFFCB5
-:1022D000331200101640000830A400FF8F9F0060EA
-:1022E0008F99003013F900043887000130E20001B3
-:1022F000144001C8000000000E001B5A000000003E
-:102300000A001D8F000000008F84006030C500FFB0
-:102310000E0017E124060001938E0044240A0034C5
-:1023200011CA00A08F8500348F86005C9783005807
-:102330003062FFFF00C28823AF91005CA780005885
-:102340001280FF90028018212414FFFD5474FFA214
-:102350008E6300208E6900042403FFBF240BFFEF6F
-:102360000135C823AE79000490AF00D431ED007F71
-:10237000A0AD00D48E6600208F980034A78000584E
-:1023800034DF0002AE7F0020A70000BC931200D40F
-:1023900002434024A30800D48F950034AEA000EC83
-:1023A00092AE00D401CB5024A2AA00D40A001C6E25
-:1023B0008F8500348F910030AF80005C0227582158
-:1023C000AF8B0030000020212403FFFF108301B4F5
-:1023D0008F8500348E0C00103C0D08008DAD31B09F
-:1023E0009208000031843FFF008D802B12000023F3
-:1023F000310D003F3C1908008F3931A88F9F0068CC
-:10240000000479802408FF80033F2021008FC82129
-:10241000938500550328F8243C0600803C0F80007B
-:1024200034D80001001F91403331007F8F86003483
-:102430000251502535EE0940332B00783330000728
-:102440003C0310003C02800C01789025020E4821CC
-:102450000143C0250222382134AE0001ADFF08043B
-:10246000AF89004CADF20814AF870040ADFF0028E3
-:10247000ACD90084ADF80830A38E00559383005684
-:10248000240700035067002825A3FFE0240C000167
-:10249000146CFFAB8F8500342411002311B100842C
-:1024A000000000002402000B026020210E0019E150
-:1024B000A38200640040A0210A001CC98F8500345B
-:1024C00002602021240B000C0E0019E1A38B006494
-:1024D000240AFFFF104AFFBC2404FFFF8F8E003444
-:1024E000A38000388E0D00048DC800D83C0600FF84
-:1024F00034CCFFFF01AC30240106182B1060FEE144
-:10250000AF86005002602021241200190E0019E14C
-:10251000A3920064240FFFFF104FFFAB2404FFFFC2
-:102520000A001C1A8F8600502C7400201280FFDED7
-:102530002402000B000328803C110801263192EC94
-:1025400000B148218D2D000001A00008000000000E
-:102550008F85003000A7102193850038AF820030AE
-:1025600002251821A3830038951F00BC02262821CC
-:1025700037F91000A51900BC5240FF92AF85005CEE
-:10258000246A0004A38A0038950900BC24A400042E
-:10259000AF84005C35322000A51200BC0A001CEBA1
-:1025A000000020218F86005C2CCB00051560FF60A9
-:1025B000978300583072FFFF00D240232D1800058A
-:1025C00013000003306400FF24DFFFFC33E400FF4E
-:1025D0008F8500608F86003010A60004388F0001C0
-:1025E00031ED000115A00138000000008F84003497
-:1025F000908C00D435870010A08700D48F850034DC
-:102600008F86005C97830058ACA000EC0A001CC6C3
-:102610003062FFFF8CAA00848CB500843C0410005B
-:10262000014710240002894032B4007F0234302573
-:1026300000C460253C0880002405000102602021C0
-:10264000240600010E001940AD0C08300A001C5A87
-:102650008F8500348C8200EC1222FE7E02602021E5
-:1026600024090005A38900640E0019E12411FFFF6D
-:102670001451FE782404FFFF0A001CEC2403FFFF22
-:102680008F8F00488F8800348DF80000AD180088C7
-:102690008DE70010AD0700988F87005C0A001D4E83
-:1026A0008F8600502407FFFF1187000500000000FF
-:1026B0000E001AE3026020210A001D270040A0211D
-:1026C0000E001A68026020210A001D270040A02188
-:1026D0008F9000483C0908008D2931B08E11001000
-:1026E00032323FFF0249682B11A0000C240AFF8000
-:1026F0008F85004C90AE000D014E1024304C00FF31
-:1027000011800007026020210011C38233030003FF
-:10271000240B0001106B0105000000000260202165
-:102720002418000D0E0019E1A39800640040202138
-:102730008F8500340A001CC90080A0218F900048BA
-:102740003C0A08008D4A31B08F85004C8E04001081
-:102750000000A0218CB1001430823FFF004A602BA2
-:102760008CB200205180FFEE0260202190B8000D55
-:10277000240BFF800178702431C300FF5060FFE814
-:1027800002602021000443823106000314C0FFE4EC
-:102790000260202194BF001C8F9900348E0600280F
-:1027A000A73F00E88CAF0010022F202314C401398A
-:1027B000026020218F83005000C36821022D382B36
-:1027C00014E00135240200188F8A00408F82002C0B
-:1027D000024390218D4B001001637023AD4E001019
-:1027E000AD5200208C4C00740192282B14A001568D
-:1027F000026020218F84004C8E0800248C860024E7
-:1028000011060007026020212419001C0E0019E1A6
-:10281000A3990064240FFFFF104FFFC52404FFFF9E
-:102820008F8400408C87002424FF0001AC9F00248B
-:10283000125101338F8D002C8DB100741232013092
-:102840003C0B00808E0E000001CB5024154000751B
-:10285000000000008E0300142411FFFF1071000619
-:10286000026020212418001B0E0019E1A3980064C7
-:102870001051FFAF2404FFFF8E0300003C0800014D
-:102880000068302410C000133C0400800064A024C1
-:102890001680000902002821026020212419001A54
-:1028A0000E0019E1A3990064240FFFFF104FFFA051
-:1028B0002404FFFF02002821026020210E001A01DB
-:1028C000240600012410FFFF1050FF992404FFFF8D
-:1028D000241400018F9F00400260202102803021DB
-:1028E00097F100342405000126270001A7E70034F2
-:1028F0000E00194000000000000020218F850034E8
-:102900000A001CC90080A0218F9000483C140800D8
-:102910008E9431B08E07001030E83FFF0114302B49
-:1029200010C000618F86004C241FFF8090C5000DF1
-:1029300003E52024309200FF5240005C0260202119
-:102940008F8D005011A0000700078B828F85003407
-:102950008F89FCB894AF00809539000A132F00F6D8
-:102960008F87003C322C00031580006300000000BC
-:1029700092020002104000D7000000008E0A0024DE
-:10298000154000D8026020219204000324060002B2
-:10299000308800FF15060005308500FF8F94005039
-:1029A000528000F202602021308500FF38AD001017
-:1029B0002DA400012CBF000103E4302502002821D2
-:1029C0000E001A01026020212410FFFF105000BEEB
-:1029D0008F8500348F830050106000C424050001EF
-:1029E0003C1908008F39318C0323782B15E000B196
-:1029F0002409002D02602021000028210E0019402A
-:102A0000240600018F850034000018210A001CC92B
-:102A10000060A0210E00180C000000000A001D8FAD
-:102A200000000000AC8000200A001E0F8E0300147E
-:102A300000002821026020210E0019402406000118
-:102A40000A001C5A8F8500340A001D4E8F880034FE
-:102A50008CB000848CB900843C0310000207482429
-:102A600000096940332F007F01AFF82503E32825D3
-:102A7000ACC5083091070001240500010260202147
-:102A80000E00194030E600010A001C5A8F85003400
-:102A9000938F00442403FFFD0A001CCBAF8F005C22
-:102AA0000A001CCB2403FFFF026020212410000D2C
-:102AB0000E0019E1A3900064004018218F850034B6
-:102AC0000A001CC90060A0210E00180C00000000C4
-:102AD000978300588F86005C3070FFFF00D048233A
-:102AE0002D3900051320FE128F850034ACA200ECB6
-:102AF0000A001CC63062FFFF90C3000D307800084A
-:102B00005700FFA29204000302602021240200105B
-:102B10000E0019E1A38200642403FFFF5443FF9BCE
-:102B2000920400030A001EA98F85003490A8000DAE
-:102B30003106000810C000958F9400501680009E4A
-:102B4000026020218E0F000C8CA4002055E40005AB
-:102B5000026020218E1F00088CB9002413F9003A6E
-:102B600002602021240200200E0019E1A3820064EB
-:102B70002405FFFF1045FEEE2404FFFF8F8F004069
-:102B8000240CFFF72403FF8091E9000D3C14800E14
-:102B90003C0B8000012CC824A1F9000D8F8F002C64
-:102BA0003C0708008CE731AC8F8D006895E5007814
-:102BB0008F99004000ED902130BF7FFF001F204023
-:102BC0000244302130C8007F00C3C02401147021AA
-:102BD000AD78002CA5D100008F2A002825420001E5
-:102BE000AF2200288F29002C8E0C002C012C68218C
-:102BF000AF2D002C8E07002CAF2700308E0500145F
-:102C0000AF250034973F003A27E40001A724003A9B
-:102C100095F200783C1008008E1031B02643000178
-:102C200030717FFF1230005C006030218F83002CF8
-:102C300002602021240500010E0018CBA466007854
-:102C40000A001E38000020218E0700142412FFFF06
-:102C500010F200638F8C00348E0900188D8D00D027
-:102C6000152D005D026020218E0A00248CA2002810
-:102C700011420053240200210E0019E1A3820064D6
-:102C80001452FFBE2404FFFF8F8500340A001CC9C4
-:102C90000080A0212402001F0E0019E1A38200641D
-:102CA0002409FFFF1049FEA22404FFFF0A001DEBC8
-:102CB0008F830050026020210E0019E1A389006477
-:102CC0001450FF518F8500342403FFFF0A001CC9F4
-:102CD0000060A0218CCE00248E0B0024116EFF2AF0
-:102CE000026020210A001EBD2402000F0E0018CB36
-:102CF000026020218F8500340A001E7C000018210C
-:102D00008E0900003C050080012590241640FF45F7
-:102D10002402001A026020210E0019E1A38200643F
-:102D2000240CFFFF144CFECB2404FFFF8F850034DE
-:102D30000A001CC90080A0212403FFFD0060A0211F
-:102D40000A001CC9AF87005C2418001D0E0019E1A1
-:102D5000A39800642403FFFF1443FEA62404FFFF8E
-:102D60008F8500340A001CC90080A0212412002C89
-:102D70000E0019E1A39200642403FFFF1043FF50EB
-:102D80008F8500340A001E63920400030260202134
-:102D90000A001ED324020024240B8000006B702440
-:102DA00031CAFFFF000A13C2305100FF0011802713
-:102DB0000A001F04001033C00A001ED3240200279B
-:102DC0008E0600288CAE002C10CE00080260202158
-:102DD0000A001F172402001F0A001F172402000EFA
-:102DE000026020210A001F17240200258E04002CF7
-:102DF0001080000D8F83002C8C7800740304582BF6
-:102E00005560000C026020218CA800140086A021CF
-:102E10000114302B10C0FF5A8F8F00400260202118
-:102E20000A001F1724020022026020210A001F1737
-:102E3000240200230A001F172402002627BDFFD802
-:102E4000AFB3001CAFB10014AFBF0020AFB2001889
-:102E5000AFB000103C0280008C5201408C4B014806
-:102E60003C048000000B8C02322300FF317300FF12
-:102E70008C8501B804A0FFFE34900180AE120000E2
-:102E80008C8701442464FFF0240600022C83001385
-:102E9000AE070004A6110008A206000BAE13002422
-:102EA0001060004F8FBF0020000448803C0A0801DA
-:102EB000254A936C012A40218D04000000800008FF
-:102EC000000000003C0308008C6331A831693FFF1B
-:102ED0000009998000728021021370212405FF806F
-:102EE000264D0100264C00803C02800031B1007F5D
-:102EF0003198007F31CA007F3C1F800A3C19800452
-:102F00003C0F800C01C5202401A530240185382404
-:102F1000014F1821AC460024023F402103194821EB
-:102F2000AC470090AC440028AF830040AF88003429
-:102F3000AF89002C0E001897016080213C038000AF
-:102F40008C6B01B80560FFFE8F8700408F860034D0
-:102F50003465018090E8000DACB20000A4B000061A
-:102F6000000826000004160300029027001227C262
-:102F70001080008124C20088241F6082A4BF000842
-:102F8000A0A0000524020002A0A2000B8F8B002C41
-:102F9000000424003C08270000889025ACB20010F3
-:102FA000ACA00014ACA00024ACA00028ACA0002C65
-:102FB0008D6900382413FF80ACA9001890E3000D40
-:102FC00002638024320500FF10A000058FBF00209F
-:102FD00090ED000D31AC007FA0EC000D8FBF002004
-:102FE0008FB3001C8FB200188FB100148FB0001087
-:102FF0003C0A10003C0E800027BD002803E00008BA
-:10300000ADCA01B8265F01002405FF8033F8007FB8
-:103010003C06800003E578243C19800A031920212E
-:10302000ACCF0024908E00D400AE682431AC00FFF9
-:1030300011800024AF840034248E008895CD0012C6
-:103040003C0C08008D8C31A831AB3FFF0192482128
-:10305000000B5180012A402101052024ACC4002826
-:103060003107007F3C06800C00E620219083000D94
-:1030700000A31024304500FF10A0FFD8AF8400400B
-:103080009098000D330F001015E0FFD58FBF002082
-:103090000E001897000000003C0380008C7901B8F6
-:1030A0000720FFFE00000000AE1200008C7F0144EC
-:1030B000AE1F0004A611000824110002A211000B8B
-:1030C000AE1300243C13080192739528327000015E
-:1030D0005200FFC38FBF00200E0020D402402021E9
-:1030E0000A001FF18FBF00203C1260008E452C08A3
-:1030F0003C03F0033462FFFF00A2F824AE5F2C080B
-:103100008E582C083C1901C003199825AE532C0881
-:103110000A001FF18FBF0020264D010031AF007F54
-:103120003C10800A240EFF8001F0282101AE6024AB
-:103130003C0B8000AD6C00241660FFA8AF85003406
-:1031400024110003A0B100FC0A001FF18FBF002072
-:1031500026480100310A007F3C0B800A2409FF80C9
-:10316000014B3021010920243C078000ACE40024FD
-:103170000A001FF0AF860034944E0012320C3FFF5D
-:1031800031CD3FFF15ACFF7D241F608290D900D464
-:103190002418FF800319782431EA00FF1140FF77DB
-:1031A0000000000024070004A0C700FC8F87004037
-:1031B000241160842406000DA4B10008A0A6000517
-:1031C0000A001FDB240200023C0400012484951441
-:1031D00024030014240200FE3C010800AC2431EC5E
-:1031E0003C010800AC2331E83C010801A4229530E1
-:1031F0003C0408012484953000001821006430212B
-:10320000A0C30004246300012C6500FF54A0FFFC50
-:10321000006430213C07080024E7010003E00008B7
-:10322000AF87007400A058210080482100001021C1
-:1032300014A00012000050210A0020D0000000005D
-:103240003C010801A42095303C05080194A5953067
-:103250008F8200743C0C0801258C953000E2182107
-:1032600000AC2021014B302BA0890004000010216C
-:10327000A460000810C00039010048218F86007446
-:103280000009384000E940210008388000E6282184
-:1032900090A8000B90B9000A000820400088102177
-:1032A000000218800066C021A319000A8F850074EF
-:1032B00000E5782191EE000A91E6000B000E6840CF
-:1032C00001AE6021000C208000851021A046000B7B
-:1032D0003C0308019063952A106000222462FFFFDE
-:1032E0008F8300343C010801A022952A906C00FFD6
-:1032F0001180000400000000906E00FF25CDFFFF4C
-:10330000A06D00FF3C190801973995302723000173
-:103310003078FFFF2F0F00FF11E0FFC9254A0001A1
-:103320003C010801A42395303C05080194A5953083
-:103330008F8200743C0C0801258C953000E2182126
-:1033400000AC2021014B302BA0890004000010218B
-:10335000A460000814C0FFC90100482103E0000870
-:103360000000000003E000082402000227BDFFE087
-:10337000248501002407FF80AFB00010AFBF001804
-:10338000AFB1001400A718243C10800030A4007FC7
-:103390003C06800A008628218E110024AE030024FA
-:1033A00090A200FF14400008AF850034A0A00009DF
-:1033B0008FBF0018AE1100248FB100148FB0001021
-:1033C00003E0000827BD002090A900FD90A800FFA1
-:1033D000312400FF0E002082310500FF8F8500346C
-:1033E0008FBF0018A0A00009AE1100248FB10014F7
-:1033F0008FB0001003E0000827BD002027BDFFD0DC
-:10340000AFB20020AFB1001CAFB00018AFBF002CAE
-:10341000AFB40028AFB300243C09800095330116F7
-:1034200035320C00952F011A3271FFFF02328021D4
-:103430008E08000431EEFFFF248B0100010E68218D
-:10344000240CFF8025A5FFFF016C50243166007F0E
-:103450003C07800AAD2A002400C73021AF850070E8
-:10346000AF88006C3C010801A020952990C3000999
-:103470000200D02100809821306300FF28620005FF
-:1034800010400048AF860034286400021480008E8B
-:1034900024140001240D00053C010801A02D950D08
-:1034A00090CC00FD3C010801A020950E3C010801D4
-:1034B000A020950F90CB000A240AFF80318500FFE1
-:1034C000014B4824312700FF10E0000C0000582178
-:1034D0003C128008365100808E2F00308CD0005C6A
-:1034E00001F0702305C0018E8F87006C90D4000A14
-:1034F0003284007FA0C4000A8F8600343C1180080B
-:10350000363000808E0F00308F87006C00EF702304
-:1035100019C000EE0000000090D40009241200023F
-:10352000328400FF10920247000000008CC2005855
-:1035300000E2F82327F9FFFF1B2001300000000004
-:1035400090C500092408000430A300FF106800574C
-:10355000240A00013C010801A02A950D90C900FF32
-:10356000252700013C010801A027950C3C03080118
-:103570009063950D240600051066006A2C780005FE
-:10358000130000C4000090210003F8803C040801EF
-:10359000248493B803E4C8218F25000000A000080C
-:1035A00000000000241800FF1078005C00000000FC
-:1035B00090CC000A90CA00093C080801910895299E
-:1035C0003187008000EA48253C010801A0299514B4
-:1035D00090C500FD3C1408019294952A3111000118
-:1035E0003C010801A025951590DF00FE3C01080173
-:1035F000A03F951690D200FF3C010801A03295171C
-:103600008CD900543C010801AC3995188CD0005875
-:103610003C010801AC30951C8CC3005C3C010801E6
-:10362000AC3495243C010801AC23952016200008F9
-:103630008FBF002C8FB400288FB300248FB20020DE
-:103640008FB1001C8FB0001803E0000827BD0030C8
-:103650003C1180009624010E0E000FD43094FFFF21
-:103660003C0B08018D6B952C0260382102802821CB
-:10367000AE2B01803C1308018E73950C0160202154
-:10368000240600830E001046AFB300108FBF002C3D
-:103690008FB400288FB300248FB200208FB1001C9C
-:1036A0008FB0001803E0000827BD00303C18080068
-:1036B0008F1831FC270F00013C010800AC2F31FCB2
-:1036C0000A002165000000001474FFB9000000002A
-:1036D000A0C000FF3C0508008CA531E43C030800B5
-:1036E0008C6331E03C0208008C4232048F99003434
-:1036F00034A80001241F00023C010801AC23952CD2
-:103700003C010801A02895283C010801A022952B26
-:10371000A33F00090A00211E8F8600340E0020D42A
-:10372000000000000A0021658F8600343C1F08015C
-:1037300093FF950C2419000113F902298F87006C5F
-:103740003C100801921095103C06080190C6950E99
-:1037500010C000050200A0213C04080190849511CE
-:10376000109001E48F870074001088408F9F0074D0
-:10377000023048210009C880033F702195D8000815
-:10378000270F0001A5CF00083C0408019084951183
-:103790003C05080190A5950E0E0020820000000057
-:1037A0008F870074023020210004308000C7202160
-:1037B0008C8500048F82007000A240230502000661
-:1037C000AC8200048C8A00008F83006C01431023BC
-:1037D0005C400001AC8300008F86003490CB00FF7A
-:1037E0002D6C00025580002D241400010230F821B8
-:1037F000001F40800107282190B9000B8CAE000407
-:103800000019C04003197821000F188000671021AB
-:103810008C4D000001AE88232630FFFF5E00001FA4
-:10382000241400018C4400048CAA0000008A482360
-:1038300019200019240E00043C010801A02E950D4A
-:1038400090AD000B8CAB0004000D8840022D802150
-:1038500000101080004710218C4400040164602394
-:10386000058202009443000890DF00FE90B9000B2F
-:1038700033E500FF54B900040107A021A0D400FEE5
-:103880008F8700740107A0219284000B0E00208214
-:10389000240500018F860034241400011254009680
-:1038A0002E500001160000423C08FFFF24190002C0
-:1038B0001659FF3F00000000A0C000FF8F860034B3
-:1038C000A0D200090A0021658F86003490C7000944
-:1038D0002404000230E300FF1064016F2409000497
-:1038E000106901528F8800708CCE0054010E68233D
-:1038F00025B1000106200175241800043C010801CF
-:10390000A038950D3C010801A020950C90D400FD35
-:1039100090D200FF2E4F000215E0FF14328400FF0A
-:10392000000438408F89007490DF00FF00E410210C
-:10393000000220800089C8212FE500029324000B9B
-:1039400014A0FF0A2407000200041840006480212C
-:1039500000105880016928218CAC0004010C502310
-:103960000540FF02000000003C0308019063950E33
-:1039700014600005246F00013C010801A02495118A
-:103980003C010801A027950F3C010801A02F950ECE
-:1039900090CE00FF24E7000131CD00FF01A7882B66
-:1039A0001220FFE990A4000B0A002154000000003F
-:1039B0003C0508018CA5950C3C12000400A8F824D5
-:1039C00013F20006240200053C0908019129950D17
-:1039D0001520000224020003240200053C01080116
-:1039E000A022952990C700FF14E0012024020002C4
-:1039F000A0C200090A0021658F86003490CC00FF28
-:103A00001180FEDA240A00018F8C00708F89007407
-:103A1000240F0003018068211160001E240E0002A3
-:103A2000000540400105A02100142080008990215C
-:103A30008E510004019180230600FECC000000009E
-:103A40003C0208019042950E1440000524580001E4
-:103A50003C010801A02A950F3C010801A025951101
-:103A60003C010801A038950E90DF00FF01051021F0
-:103A70000002C88033E500FF254A00010329202108
-:103A800000AA402B1500FEB99085000B1560FFE5DC
-:103A9000000540400005404001051821000310804A
-:103AA0003C010801A02A950C3C010801A0259510B5
-:103AB000004918218C64000400E4F82327F9FFFF73
-:103AC0001F20FFE9000000008C63000000E3582382
-:103AD0000560013A01A3882310E301170184C02384
-:103AE0001B00FEA2000000003C010801A02E950D65
-:103AF0000A002293240B0001240E0004A0CE00092A
-:103B00003C0D08008DAD31F88F86003425A20001F0
-:103B10003C010800AC2231F80A00216500000000D9
-:103B20008CD9005C00F9C0231F00FE7B0000000060
-:103B30008CDF005C10FFFF658F8400708CC3005C1D
-:103B400000834023250200011C40FF6000000000AC
-:103B50008CC9005C2487000100E9282B10A0FE948A
-:103B60003C0D80008DAB01043C0C0001016C502425
-:103B70001140FE8F240200103C010801A02295296B
-:103B80000A002165000000008F9100708F860034CC
-:103B900026220001ACC2005C0A002220241400018D
-:103BA0008F8700342404FF800000882190E9000AF8
-:103BB0002414000101243025A0E6000A3C05080178
-:103BC00090A5950E3C040801908495110E0020826A
-:103BD000000000008F8600348F85007490C800FDBF
-:103BE000310700FF000740400107F821001FC08097
-:103BF0000305C8219323000BA0C300FD8F8500742B
-:103C00008F86003403056021918F000B000F7040F8
-:103C100001CF6821000D8080020510218C4B00002F
-:103C2000ACCB00548D8400048F830070006450235B
-:103C3000194000022482000124620001010748218A
-:103C4000ACC2005C0009308000C5402100E02021AA
-:103C5000240500010E0020829110000B8F86003495
-:103C600090C500FF10A0FF0C001070408F850074FD
-:103C700001D06821000D1080004558218D6400009E
-:103C80008F8C0070018450232547000104E0FF025F
-:103C9000263100013C0308019063950E2E2F00028F
-:103CA000247800013C010801A038950E3C01080170
-:103CB000A034950F11E0FEF8020038210A0022F32B
-:103CC000000740408F8400348F8300708C8500583B
-:103CD00000A340230502FE9AAC8300580A0021C9C4
-:103CE000000000003C07080190E7952A240200FF2D
-:103CF00010E200BE8F8600343C11080196319532E7
-:103D00003C03080124639530262500013230FFFF73
-:103D100030ABFFFF020360212D6A00FF1540008DCC
-:103D2000918700043C010801A42095328F8800345B
-:103D30000007484001272821911800FF0005308026
-:103D40002405000127140001A11400FF3C12080102
-:103D50009252952A8F8800748F8E006C264F000136
-:103D600000C820213C010801A02F952AAC8E00003C
-:103D70008F8D0070A4850008AC8D00043C03080101
-:103D80009063950C14600077000090213C010801BD
-:103D9000A025950CA087000B8F8C007400CC5021BF
-:103DA000A147000A8F820034A04700FD8F840034B1
-:103DB000A08700FE8F8600348F9F006CACDF00541C
-:103DC0008F990070ACD900588F8D00740127C021E5
-:103DD00000185880016DA021928F000A000F7040DA
-:103DE00001CF182100038880022D8021A207000B3B
-:103DF0008F86007401666021918A000B000A1040D2
-:103E0000004A20210004288000A64021A107000AC2
-:103E10003C07800834E900808D2200308F86003412
-:103E2000ACC2005C0A0022202414000190CA00FFEA
-:103E30001540FEAD8F880070A0C400090A002165FE
-:103E40008F860034A0C000FD8F9800342406000146
-:103E5000A30000FE3C010801A026950D3C010801CD
-:103E6000A020950C0A0021540000000090CB00FF18
-:103E70003C0408019084952B316C00FF0184502B89
-:103E80001540000F2402000324020004A0C2000910
-:103E90000A0021658F86003490C3000A2410FF8039
-:103EA00002035824316C00FF1180FDC100000000A6
-:103EB0003C010801A020950D0A00215400000000DB
-:103EC000A0C200090A0021658F86003490D4000A40
-:103ED0002412FF8002544824312800FF1500FFF40B
-:103EE000240200083C010801A02295290A0021654E
-:103EF00000000000001088408F8B006C02301821F9
-:103F00000003688001A72021AC8B00008F8A00701D
-:103F1000240C0001A48C0008AC8A00043C050801B4
-:103F200090A5950E2402000110A2FE1E24A5FFFFFD
-:103F30000A0021DF9084000B0184A0231A80FD8BEE
-:103F4000000000003C010801A02E950D0A002293FC
-:103F5000240B00013C010801A42595320A002345E9
-:103F60008F880034240B0001106B00228F980034DE
-:103F70008F85003490BF00FF33F900FF1079002BCC
-:103F8000000000003C1F080193FF9510001FC8406F
-:103F9000033FC0210018A0800288782191EE000A1A
-:103FA000A08E000A8F8D00743C0308019063951069
-:103FB00000CD88210A00236BA223000B26300001CC
-:103FC0000600003101A490230640002B24020003C8
-:103FD0003C010801A02F950D0A002293240B00013B
-:103FE0008F8900340A0021C9AD2700540A00221F1E
-:103FF00024120001931400FDA094000B8F8800345C
-:104000008F8F0074910E00FE00CF6821A1AE000AD0
-:104010008F910034A22700FD8F83006C8F900034B5
-:10402000AE0300540A00236C8F8D007490B000FE24
-:10403000A090000A8F8B00348F8C0074916A00FD71
-:1040400000CC1021A04A000B8F840034A08700FE12
-:104050008F8600708F850034ACA600580A00236C50
-:104060008F8D007494B80008ACA400040303782179
-:104070000A002213A4AF00083C010801A022950DFC
-:104080000A0021540000000090CF0009240D000414
-:1040900031EE00FF11CDFD85240200013C01080135
-:0C40A000A022950D0A0021540000000031
-:0440AC000800334491
-:1040B0000800334408003420080033F4080033D8E3
-:1040C0000800332808003328080033280800334C40
-:1040D0008008010080080080800800005F86543757
-:1040E000E4AC62CC50103A4536621985BF14C0E882
-:1040F0001BC27A1E84F4B556094EA6FE7DDA01E78E
-:10410000C04D7481080058D008005914080058B8F0
-:10411000080058B8080058B8080058B8080058D027
-:10412000080058B8080058B80800591C080058B8CA
-:1041300008005830080058B8080058B80800591C42
-:10414000080058B8080058B8080058B8080058B80F
-:10415000080058B8080058B8080058B8080058B8FF
-:10416000080058B8080058B8080058F0080058B8B7
-:10417000080058F0080058B8080058B8080058B8A7
-:10418000080058F4080058F0080058B8080058B85B
-:10419000080058B8080058B8080058B8080058B8BF
-:1041A000080058B8080058B8080058B8080058B8AF
-:1041B000080058B8080058B8080058B8080058B89F
-:1041C000080058B8080058B8080058B8080058B88F
-:1041D000080058B8080058B8080058F4080058F407
-:1041E000080058B8080058F4080058B8080058B833
-:1041F000080058B8080058B8080058B8080058B85F
-:10420000080058B8080058B8080058B8080058B84E
-:10421000080058B8080058B8080058B8080058B83E
-:10422000080058B8080058B8080058B8080058B82E
-:10423000080058B8080058B8080058B8080058B81E
-:10424000080058B8080058B8080058B8080058B80E
-:10425000080058B8080058B8080058B8080058B8FE
-:10426000080058B8080058B8080058B8080058B8EE
-:10427000080058B8080058B8080058B8080058B8DE
-:10428000080058B8080058B8080058B8080058B8CE
-:10429000080058B8080058B8080058B8080058B8BE
-:1042A000080058B8080058B8080058B8080058B8AE
-:1042B000080058B8080058B8080058B8080058B89E
-:1042C000080058B8080058B8080058B8080058B88E
-:1042D000080058B8080058B8080058B8080058B87E
-:1042E000080058B8080058B8080058B8080058B86E
-:1042F000080058B8080058B8080058B8080058B85E
-:10430000080058B80800593808007688080078EC8A
-:1043100008007694080074880800769408007720D6
-:10432000080076940800748808007488080074886F
-:10433000080074880800748808007488080074886D
-:10434000080074880800748808007488080076B42F
-:10435000080076A40800748808007488080074882F
-:10436000080074880800748808007488080074883D
-:10437000080074880800748808007488080074882D
-:1043800008007488080076A40800813408007FC003
-:10439000080080FC08007FC0080080CC08007EA8D0
-:1043A00008007FC008007FC008007FC008007FC0F1
-:1043B00008007FC008007FC008007FC008007FC0E1
-:1043C00008007FC008007FC008007FC008007FC0D1
-:1043D00008007FE808008B6C08008CC808008CA8D7
-:0843E0000800871008008B841F
-:0843E8000A000124000000009E
-:1043F000000000000000000D747061362E302E3178
-:10440000370000000600110100000000000000005D
-:10441000000000000000000000000000000000009C
-:10442000000000000000000000000000000000008C
-:10443000000000000000000000000000000000007C
-:10444000000000000000000000000000000000006C
-:10445000000000000000000000000000000000005C
-:10446000000000000000000000000000000000004C
-:104470000000000000000000000000001000000329
-:10448000000000000000000D0000000D3C020800CC
-:10449000244217203C03080024632A10AC4000008B
-:1044A0000043202B1480FFFD244200043C1D080023
-:1044B00037BD2FFC03A0F0213C100800261004900B
-:1044C0003C1C0800279C17200E0002620000000020
-:1044D0000000000D2402FF8027BDFFE000821024B1
-:1044E000AFB00010AF420020AFBF0018AFB1001452
-:1044F000936500043084007F034418213C020008C7
-:104500000062182130A50020036080213C080111C1
-:10451000277B000814A000022466005C2466005873
-:104520009202000497430104920400043047000FF4
-:104530003063FFFF308400400067282310800009AB
-:10454000000048219202000530420004104000059E
-:104550000000000010A000030000000024A5FFFCE4
-:1045600024090004920200053042000410400012A9
-:104570000000000010A000100000000096020002E1
-:1045800000A72021010440252442FFFEA742101667
-:10459000920300042402FF8000431024304200FFF5
-:1045A000104000033C0204000A000174010240258F
-:1045B0008CC20000AF4210188F4201780440FFFE09
-:1045C0002402000AA74201409602000224040009C6
-:1045D000304200070002102330420007A742014288
-:1045E000960200022442FFFEA7420144A740014672
-:1045F00097420104A74201488F420108304200203F
-:1046000050400001240400019202000430420010D6
-:10461000144000023483001000801821A743014A8F
-:10462000000000000000000000000000000000008A
-:10463000AF48100000000000000000000000000073
-:10464000000000008F4210000441FFFE3102FFFF16
-:1046500010400007000000009202000430420040B9
-:1046600014400003000000008F421018ACC200008C
-:10467000960200063042FFFF24420002000210436F
-:104680000002104003628821962200001120000DD4
-:104690003044FFFF00A710218F8300388F45101C86
-:1046A000000210820002108000431021AC4500007F
-:1046B00030A6FFFF0E00058D00052C0200402021D2
-:1046C000A6220000920300042402FF80004310246D
-:1046D000304200FF1040001F000000009202000561
-:1046E000304200021040001B000000009742100CF6
-:1046F0002442FFFEA7421016000000003C02040006
-:1047000034420030AF421000000000000000000002
-:1047100000000000000000008F4210000441FFFE76
-:10472000000000009742100C8F45101C3042FFFF24
-:10473000244200300002108200021080005B102131
-:10474000AC45000030A6FFFF0E00058D00052C02D1
-:10475000A622000096040002248400080E0001E94D
-:104760003084FFFF974401040E0001F73084FFFFFF
-:104770008FBF00188FB100148FB000103C021000E2
-:1047800027BD002003E00008AF4201783084FFFF1E
-:10479000308200078F850024104000022483000728
-:1047A0003064FFF800A4102130421FFF034218219B
-:1047B000247B4000AF850028AF82002403E000087E
-:1047C000AF4200843084FFFF3082000F8F85002CC1
-:1047D0008F860034104000022483000F3064FFF005
-:1047E00000A410210046182BAF850030004620237E
-:1047F00014600002AF82002CAF84002C8F82002C4A
-:10480000340480000342182100641821AF8300386B
-:1048100003E00008AF4200808F82001410400008BF
-:104820008F8200048F82FFDC144000058F82000419
-:104830003C02FFBF3442FFFF008220248F8200042D
-:1048400030430006240200021062000F3C02010106
-:104850002C62000350400005240200041060000F89
-:104860003C0200010A000230000000001062000556
-:10487000240200061462000C3C0201110A00022905
-:10488000008210253C02001100821025AF4210006A
-:10489000240200010A000230AF82000C00821025C1
-:1048A000AF421000AF80000C0000000000000000CC
-:1048B0000000000003E00008000000008F82000CF0
-:1048C00010400004000000008F4210000441FFFE71
-:1048D0000000000003E00008000000008F820010CC
-:1048E0002443F800000231C224C2FFF02C6303010C
-:1048F00010600003000210420A000257AC82000060
-:104900008F85001800C5102B1440000B00001821E3
-:1049100000C51023244700018F82001C00A2102133
-:104920002442FFFF0046102B544000042402FFFFE6
-:104930000A000257AC8700002402FFFF0A00026051
-:10494000AC8200008C820000000219400062182135
-:104950000003188000621821000318803C02080040
-:104960002442175C0062182103E000080060102157
-:1049700027BDFFD8AFBF0020AFB1001CAFB00018FB
-:104980003C0460088C8250002403FF7F3C066000DA
-:10499000004310243442380CAC8250008CC24C1CB2
-:1049A0003C1A8000000216023042000F104000073F
-:1049B000AF82001C8CC34C1C3C02001F3442FC0024
-:1049C00000621824000319C2AF8300188F42000848
-:1049D000275B400034420001AF420008AF80002452
-:1049E0003C02601CAF400080AF4000848C45000852
-:1049F0008CC3080834028000034220212402FFF007
-:104A0000006218243C0200803C010800AC22042013
-:104A10003C025709AF84003814620004AF850034AB
-:104A2000240200010A000292AF820014AF80001439
-:104A30008F42000038420001304200011440FFFC68
-:104A40008F820014104000160000000097420104FD
-:104A5000104000058F830000146000072462FFFFF0
-:104A60000A0002A72C62000A2C62001050400004C9
-:104A70008F83000024620001AF8200008F8300005A
-:104A80002C62000A144000032C6200070A0002AEE8
-:104A9000AF80FFDC1040000224020001AF82FFDC87
-:104AA0008F4301088F44010030622000AF8300046F
-:104AB00010400008AF8400103C0208008C42042C17
-:104AC000244200013C010800AC22042C0A00058AA3
-:104AD0003C0240003065020014A0000324020F00D5
-:104AE0001482026024020D0097420104104002C8A3
-:104AF0003C02400030624000144000AD8F8200381C
-:104B00008C4400088F4201780440FFFE2402080014
-:104B1000AF42017824020008A7420140A7400142A9
-:104B2000974201048F8400043051FFFF308200015E
-:104B300010400007022080212623FFFE24020002ED
-:104B40003070FFFFA74201460A0002DBA74301487D
-:104B5000A74001463C0208008C42043C1440000D72
-:104B60008F830010308200201440000224030009CB
-:104B700024030001006020218F830010240209001B
-:104B80005062000134840004A744014A0A0002F67E
-:104B90000000000024020F00146200053082002093
-:104BA000144000062403000D0A0002F5240300054A
-:104BB000144000022403000924030001A743014A12
-:104BC0003C0208008C4204203C0400480E00020C09
-:104BD000004420250E000235000000008F82000CEA
-:104BE0001040003E000000008F4210003C030020F7
-:104BF00000431024104000398F820004304200022C
-:104C0000104000360000000097421014144000339A
-:104C100000000000974210088F8800383042FFFFE4
-:104C200024420006000218820003388000E8302188
-:104C3000304300018CC400001060000430420003C7
-:104C40000000000D0A00033700E810215440001056
-:104C50003084FFFF3C05FFFF0085202400851826D7
-:104C60000003182B0004102B0043102410400005F3
-:104C700000000000000000000000000D0000000027
-:104C8000240002228CC200000A00033600452025C1
-:104C90003883FFFF0003182B0004102B004310245F
-:104CA0001040000500000000000000000000000DA2
-:104CB000000000002400022B8CC200003444FFFFDF
-:104CC00000E81021AC4400003C0208008C42043093
-:104CD000244200013C010800AC2204308F62000035
-:104CE0008F840038AF8200088C8300003402FFFFFD
-:104CF0001462000F000010213C0508008CA504542C
-:104D00003C0408008C84045000B0282100B0302BF3
-:104D100000822021008620213C010800AC2504549B
-:104D20003C010800AC2404500A000580240400085B
-:104D30008C820000304201001040000F0000102162
-:104D40003C0508008CA5044C3C0408008C840448F5
-:104D500000B0282100B0302B0082202100862021C5
-:104D60003C010800AC25044C3C010800AC2404487C
-:104D70000A000580240400083C0508008CA50444B2
-:104D80003C0408008C84044000B0282100B0302B83
-:104D900000822021008620213C010800AC2504442B
-:104DA0003C010800AC2404400A00058024040008EB
-:104DB0008F6200088F62000000021602304300F08C
-:104DC000240200301062000524020040106200E05E
-:104DD0008F8200200A0005882442000114A00005EB
-:104DE00000000000000000000000000D00000000B6
-:104DF000240002568F4201780440FFFE00000000AC
-:104E00000E00023D27A40010144000050040802140
-:104E1000000000000000000D000000002400025D02
-:104E20008E0200001040000500000000000000009D
-:104E30000000000D00000000240002608F62000CE2
-:104E400004430003240200010A00042EAE00000007
-:104E5000AE0200008F8200388C480008A2000007D4
-:104E60008F65000C8F64000430A3FFFF0004240250
-:104E700000852023308200FF0043102124420005DA
-:104E8000000230832CC20081A605000A14400005F0
-:104E9000A2040004000000000000000D000000005B
-:104EA000240002788F8500380E0005AB260400141C
-:104EB0008F6200048F430108A60200083C02100024
-:104EC00000621824106000080000000097420104EE
-:104ED000920300072442FFEC346300023045FFFFD9
-:104EE0000A0003C3A2030007974201042442FFF013
-:104EF0003045FFFF960600082CC200135440000501
-:104F0000920300079202000734420001A202000748
-:104F1000920300072402000110620005240200032E
-:104F20001062000B8F8200380A0003E030C6FFFFDA
-:104F30008F8200383C04FFFF8C43000C006418246F
-:104F400000651825AC43000C0A0003E030C6FFFFE3
-:104F50003C04FFFF8C4300100064182400651825F2
-:104F6000AC43001030C6FFFF24C2000200021083D1
-:104F7000A20200058F830038304200FF000210803B
-:104F8000004328218CA800008CA200002403000408
-:104F900000021702144300120000000097420104AF
-:104FA0003C03FFFF010318243042FFFF004610239B
-:104FB0002442FFFE00624025ACA8000092030005D9
-:104FC000306200FF00021080005010219042001457
-:104FD0003042000F004310210A000415A20200060F
-:104FE0008CA40004974201049603000A3088FFFF56
-:104FF0003042FFFF004610232442FFD60002140077
-:1050000001024025ACA800049202000792040005AA
-:10501000246300280003188300641821344200042C
-:10502000A2030006A20200078F8200042403FFFBF4
-:105030003442000200431024AF82000492030006B1
-:105040008F87003800031880007010218C440020E6
-:105050003C02FFF63442FFFF008240240067182123
-:10506000AE04000CAC68000C920500063C03FF7F08
-:105070008E02000C0005288000B020213463FFFF61
-:10508000010330249488002600A72821004310241F
-:10509000AE02000CAC860020AC880024ACA8001046
-:1050A00024020010A742014024020002A74001424E
-:1050B000A7400144A7420146974201043C0400086E
-:1050C0002442FFFEA7420148240200010E00020C08
-:1050D000A742014A9603000A9202000400431021ED
-:1050E0002442000230420007000210233042000731
-:1050F0000E000235AE0200108F6200003C03080073
-:105100008C63044424040010AF8200089742010419
-:105110003042FFFF2442FFFE00403821000237C327
-:105120003C0208008C420440006718210067282BCD
-:1051300000461021004510213C010800AC23044426
-:105140003C010800AC2204400A00051500000000E4
-:1051500014A0000500000000000000000000000D89
-:10516000000000002400030A8F4201780440FFFE83
-:10517000000000000E00023D27A4001414400005AA
-:1051800000408021000000000000000D0000000031
-:10519000240003118E020000544000069202000712
-:1051A000000000000000000D000000002400031CAF
-:1051B0009202000730420004104000058F82000474
-:1051C0002403FFFB3442000200431024AF8200049A
-:1051D0008F62000404430008920200079202000656
-:1051E0008E03000CAE000000000210800050102161
-:1051F000AC430020920200073042000454400009F2
-:105200009602000A920200053C0300010002108091
-:10521000005010218C46001800C33021AC46001805
-:105220009602000A9206000427710008022020213D
-:1052300000C2302124C60005260500140E0005AB6F
-:1052400000063082920400068F6500043C027FFF56
-:1052500000042080009120218C8300043442FFFF51
-:1052600000A2282400651821AC83000492020007E4
-:105270009204000592030004304200041040001420
-:1052800096070008308400FF000420800091202150
-:105290008C860004974201049605000A306300FFE3
-:1052A0003042FFFF004310210045102130E3FFFF93
-:1052B000004310232442FFD830C6FFFF0002140031
-:1052C00000C23025AC8600040A0004C9920300071E
-:1052D000308500FF0005288000B128218CA4000043
-:1052E00097420104306300FF3042FFFF004310216A
-:1052F000004710233C03FFFF008320243042FFFFC0
-:1053000000822025ACA400009203000724020001C3
-:105310001062000600000000240200031062001169
-:10532000000000000A0004EC8E0300109742010404
-:10533000920300049605000A8E24000C00431021FD
-:10534000004510212442FFF23C03FFFF008320248C
-:105350003042FFFF00822025AE24000C0A0004EC3E
-:105360008E03001097420104920300049605000A80
-:105370008E24001000431021004510212442FFEE2E
-:105380003C03FFFF008320243042FFFF00822025E2
-:10539000AE2400108E0300102402000AA742014030
-:1053A000A74301429603000A920200043C04004015
-:1053B00000431021A7420144A7400146974201043F
-:1053C000A7420148240200010E00020CA742014A34
-:1053D0000E000235000000008F62000092030004FE
-:1053E00000002021AF820008974201049606000ABF
-:1053F0003042FFFF00621821006028213C030800B2
-:105400008C6304443C0208008C420440006518216F
-:10541000004410210065382B004710213C01080092
-:10542000AC2304443C010800AC2204409204000474
-:10543000008620212484000A3084FFFF0E0001E949
-:1054400000000000974401043084FFFF0E0001F7C4
-:10545000000000003C021000AF4201780A000587FE
-:105460008F820020148200273062000697420104D8
-:10547000104000673C0240003062400010400005D0
-:1054800000000000000000000000000D000000000F
-:10549000240004208F4201780440FFFE240208000B
-:1054A000AF42017824020008A7420140A740014210
-:1054B0008F8200049743010430420001104000072E
-:1054C0003070FFFF2603FFFE24020002A7420146C0
-:1054D000A74301480A00053F2402000DA7400146EA
-:1054E0002402000DA742014A8F6200002404000834
-:1054F000AF8200080E0001E9000000000A00051953
-:1055000002002021104000423C0240009362000053
-:10551000304300F0240200101062000524020070E5
-:10552000106200358F8200200A00058824420001A5
-:105530008F620000974301043050FFFF3071FFFF7E
-:105540008F4201780440FFFE320200070002102360
-:10555000304200072403000A2604FFFEA74301404F
-:10556000A7420142A7440144A7400146A751014870
-:105570008F42010830420020144000022403000939
-:1055800024030001A743014A0E00020C3C04004022
-:105590000E000235000000003C0708008CE70444C0
-:1055A000021110212442FFFE3C0608008CC6044074
-:1055B0000040182100E33821000010218F65000011
-:1055C00000E3402B00C230212604000800C830212F
-:1055D0003084FFFFAF8500083C010800AC2704447D
-:1055E0003C010800AC2604400E0001E90000000068
-:1055F0000A000519022020210E00013B00000000D6
-:105600008F82002024420001AF8200203C02400033
-:10561000AF4201380A000292000000003084FFFF10
-:1056200030C6FFFF00052C0000A628253882FFFFAA
-:10563000004510210045282B0045102100021C02C6
-:105640003042FFFF0043102100021C023042FFFFE6
-:10565000004310213842FFFF03E000083042FFFF03
-:105660003084FFFF30A5FFFF0000182110800007E5
-:1056700000000000308200011040000200042042BF
-:10568000006518210A0005A10005284003E0000874
-:105690000060102110C0000624C6FFFF8CA200008D
-:1056A00024A50004AC8200000A0005AB2484000499
-:1056B00003E000080000000010A0000824A3FFFF82
-:1056C000AC86000000000000000000002402FFFF84
-:1056D0002463FFFF1462FFFA2484000403E000083F
-:0456E00000000000C6
-:0456E40000000001C1
-:0856E8000A00002A0000000086
-:1056F000000000000000000D747870362E302E314E
-:105700003700000006001100000000000000013614
-:105710000000EA600000000000000000000000003F
-:105720000000000000000000000000000000000079
-:105730000000000000000000000000000000000069
-:105740000000000000000000000000160000000043
-:105750000000000000000000000000000000000049
-:105760000000000000000000000000000000000039
-:105770000000000000000000000000000000000029
-:105780000000138800000000000005DC000000009D
-:105790000000000010000003000000000000000DE9
-:1057A0000000000D3C02080024423D883C03080034
-:1057B0002463403CAC4000000043202B1480FFFDDC
-:1057C000244200043C1D080037BD7FFC03A0F021EB
-:1057D0003C100800261000A83C1C0800279C3D88AF
-:1057E0000E00044E000000000000000D27BDFFB4B5
-:1057F000AFA10000AFA20004AFA30008AFA4000C4B
-:10580000AFA50010AFA60014AFA70018AFA8001CEA
-:10581000AFA90020AFAA0024AFAB0028AFAC002C8A
-:10582000AFAD0030AFAE0034AFAF0038AFB8003C22
-:10583000AFB90040AFBC0044AFBF00480E000591B7
-:10584000000000008FBF00488FBC00448FB90040AB
-:105850008FB8003C8FAF00388FAE00348FAD003072
-:105860008FAC002C8FAB00288FAA00248FA90020BA
-:105870008FA8001C8FA700188FA600148FA50010FA
-:105880008FA4000C8FA300088FA200048FA100003A
-:1058900027BD004C3C1B60048F7A5030377B50286A
-:1058A00003400008AF7A00008F86003C3C03900064
-:1058B0003C0280000086282500A32025AC4400205F
-:1058C0003C0380008C67002004E0FFFE0000000025
-:1058D00003E00008000000000A000070240400013A
-:1058E0008F85003C3C0480003483000100A3102518
-:1058F00003E00008AC82002003E000080000102153
-:105900003084FFFF30A5FFFF108000070000182142
-:10591000308200011040000200042042006518217E
-:105920001480FFFB0005284003E000080060102100
-:1059300010C00007000000008CA2000024C6FFFF7A
-:1059400024A50004AC82000014C0FFFB24840004E2
-:1059500003E000080000000010A0000824A3FFFFDF
-:10596000AC86000000000000000000002402FFFFE1
-:105970002463FFFF1462FFFA2484000403E000089C
-:105980000000000090AA00318FAB00108CAC0040EA
-:105990003C0300FF8D680004AD6C00208CAD00441A
-:1059A00000E060213462FFFFAD6D00248CA7004849
-:1059B0003C09FF000109C024AD6700288CAE004CF3
-:1059C0000182C82403197825AD6F0004AD6E002C48
-:1059D0008CAD0038314A00FFAD6D001C94A9003237
-:1059E0003128FFFFAD68001090A70030A5600002CD
-:1059F000A1600004A167000090A30032306200FFA4
-:105A00000002198210600005240500011065000ED7
-:105A10000000000003E00008A16A00018CD8002803
-:105A2000354A0080AD7800188CCF0014AD6F00149B
-:105A30008CCE0030AD6E00088CC4002CA16A000131
-:105A400003E00008AD64000C8CCD001CAD6D0018A7
-:105A50008CC90014AD6900148CC80024AD6800081E
-:105A60008CC70020AD67000C8CC200148C830070C2
-:105A70000043C82B13200007000000008CC2001454
-:105A8000144CFFE400000000354A008003E00008E9
-:105A9000A16A00018C8200700A0000E6000000008C
-:105AA0009089003027BDFFF88FA8001CA3A9000033
-:105AB0008FA300003C0DFF8035A2FFFF8CAC002CB3
-:105AC00000625824AFAB0000A100000400C05821C0
-:105AD000A7A000028D06000400A048210167C8218C
-:105AE0008FA50000008050213C18FF7F032C20264A
-:105AF0003C0E00FF2C8C0001370FFFFF35CDFFFF60
-:105B00003C02FF0000AFC82400EDC02400C278248E
-:105B1000000C1DC00323682501F87025AD0D0000A1
-:105B2000AD0E00048D240024AFAD0000AD040008CC
-:105B30008D2C00202404FFFFAD0C000C9547003293
-:105B400030E6FFFFAD0600109145004830A200FF8F
-:105B5000000219C2506000018D240034AD0400140D
-:105B60008D4700388FAA001827BD0008AD0B00280C
-:105B7000AD0A0024AD07001CAD00002CAD000018DC
-:105B800003E00008AD00002027BDFFE0AFB2001821
-:105B9000AFB10014AFB00010AFBF001C9098003040
-:105BA00000C088213C0D00FF330F007FA0CF000014
-:105BB000908E003135ACFFFF3C0AFF00A0CE000103
-:105BC00094A6001EA22000048CAB00148E290004B1
-:105BD00000A08021016C2824012A4024008090210B
-:105BE00001052025A6260002AE240004260500207B
-:105BF000262400080E00009224060002924700307E
-:105C0000260500282624001400071E0000031603A2
-:105C100024060004044000032403FFFF96590032C9
-:105C20003323FFFF0E000092AE2300102624002431
-:105C30008FBF001C8FB200188FB100148FB00010FE
-:105C400024050003000030210A00009C27BD00202D
-:105C500027BDFFD8AFB1001CAFB00018AFBF002008
-:105C600090A900302402000100E050213123003FC0
-:105C700000A040218FB000400080882100C0482152
-:105C8000106200148FA70038240B000500A020210B
-:105C900000C02821106B0013020030210E000128E3
-:105CA000000000009225007C30A400021080000358
-:105CB00026030030AE000030260300348FBF0020E2
-:105CC0008FB1001C8FB000180060102103E00008A5
-:105CD00027BD00280E0000A7AFB000100A00016F1A
-:105CE000000000008FA3003C01002021012028219A
-:105CF00001403021AFA300100E0000EEAFB0001441
-:105D00000A00016F000000003C06800034C20E0053
-:105D10008C4400108F850044ACA400208C430018F4
-:105D200003E00008ACA300243C06800034C20E004F
-:105D30008C4400148F850044ACA400208C43001CCC
-:105D400003E00008ACA300249382000C1040001B69
-:105D50002483000F2404FFF00064382410E00019AD
-:105D6000978B00109784000E9389000D3C0A601CED
-:105D70000A0001AC01644023010370210064282360
-:105D80001126000231C2FFFF30A2FFFF0047302B77
-:105D900050C0000E00E448218D4D000C31A3FFFFE0
-:105DA00000036400000C2C0304A1FFF30000302169
-:105DB00030637FFF0A0001A42406000103E000080D
-:105DC000000000009784000E00E448213123FFFF0B
-:105DD0003168FFFF0068382B54E0FFF8A783000EFE
-:105DE000938A000D11400005240F0001006BC023B1
-:105DF000A380000D03E00008A798000E006BC023ED
-:105E0000A38F000D03E00008A798000E03E0000830
-:105E10000000000027BDFFE8AFB000103C1080007C
-:105E200036030140308BFFFF93AA002BAFBF001455
-:105E3000A46B000436040E009488001630C600FFE0
-:105E40008FA90030A4680006AC650008A0660012A7
-:105E5000A46A001AAC6700208FA5002CA469001862
-:105E6000012020210E000198AC6500143C021000B6
-:105E7000AE0201788FBF00148FB0001003E000085D
-:105E800027BD00188F8500002484000727BDFFF878
-:105E90003084FFF83C06800094CB008A316AFFFF13
-:105EA000AFAA00008FA90000012540232507FFFFAE
-:105EB00030E31FFF0064102B1440FFF700056882D9
-:105EC000000D288034CC400000AC102103E0000815
-:105ED00027BD00088F8200002486000730C5FFF828
-:105EE00000A2182130641FFF03E00008AF84000007
-:105EF0008F87003C8F84004427BDFFB0AFB70044BC
-:105F0000AFB40038AFB1002CAFBF0048AFB600400F
-:105F1000AFB5003CAFB30034AFB20030AFB0002833
-:105F20003C0B80008C860024AD6700808C8A0020AA
-:105F300035670E0035690100ACEA00108C8800243A
-:105F40008D2500040000B821ACE800188CE3001097
-:105F500000A688230000A021ACE300148CE2001806
-:105F6000ACE2001C122000FE00E0B021936C00089F
-:105F7000118000F400000000976F001031EEFFFF69
-:105F8000022E682B15A000EF000000009772001091
-:105F90003250FFFFAED000003C0380008C74000044
-:105FA000329300081260FFFD0000000096D8000840
-:105FB0008EC700043305FFFF30B5000112A000E4D6
-:105FC000000000000000000D30BFA0402419004078
-:105FD00013F9011B30B4A000128000DF00000000A4
-:105FE000937300081260000800000000976D001015
-:105FF00031ACFFFF00EC202B1080000330AE0040DE
-:1060000011C000D500000000A7850040AF87003810
-:106010009363000802202821AFB10020146000F52E
-:1060200027B40020AF60000C978F004031F1400092
-:1060300016200002240300162403000E2405400746
-:10604000A363000AAF650014938A00428F700014A6
-:10605000315500010015124002024825AF690014B5
-:10606000979F00408F78001433F9001003194025E2
-:10607000AF680014979200403247000810E0016EAC
-:10608000000000008F6700143C1210003C118000DB
-:1060900000F27825AF6F001436230E00946E000ACC
-:1060A0003C0D81002406000E31CCFFFF018D202520
-:1060B000AF640004A36600029373000A3406FFFC79
-:1060C000266B0004A36B000A979800403308200059
-:1060D0001100015F000000003C05800034A90E00A3
-:1060E000979900409538000C97870040001940426E
-:1060F0003312C0003103000300127B0330F11000A3
-:10610000006F68250011720301AE6025000C20C0ED
-:10611000A764001297930040936A000A0013598203
-:106120003175003C02AA10212450003CA3700009E4
-:10613000953F000C33F93FFFA779001097700012CC
-:10614000936900090130F82127E5000230B9000702
-:106150000019C02333080007A368000B93710009DE
-:1061600097720012976F0010322700FF8F9100384E
-:10617000978D004000F21821006F702101C6602148
-:1061800031A6004010C000053185FFFF00B1102B83
-:106190003C12800010400017000098210225A82B17
-:1061A00056A0013E8FA500203C048000348A0E00DA
-:1061B0008D5300143C068000AD5300108D4B001C25
-:1061C000AD4B0018AD4500008CCD000031AC00088F
-:1061D0001180FFFD34CE0E0095C3000800A0882179
-:1061E00000009021A78300408DC600042413000105
-:1061F000AF860038976F001031F5FFFF8E9F0000CB
-:1062000003F1282310A0011FAE850000936200084F
-:10621000144000DD000000000E0001E7240400101F
-:106220008F900048004028213C023200320600FFD7
-:10623000000654000142F82526090001AF890048F4
-:10624000ACBF00009379000997780012936F000AA1
-:10625000332800FF3303FFFF0103382100076C00E0
-:1062600031EE00FF01AE6025ACAC00048F84004825
-:10627000978B0040316A20001140010AACA400084D
-:1062800097640012308BFFFF06400108ACAB000C96
-:10629000978E004031C5000814A000022628000691
-:1062A000262800023C1F800037E70E0094F90014F6
-:1062B0008CE5001C8F670004937800023324FFFFF5
-:1062C000330300FFAFA300108F6F0014AFA80018B6
-:1062D0000E0001CBAFAF0014240400100E0001FB30
-:1062E000000000008E920000164000050000000033
-:1062F0008F7800142403FFBF0303A024AF7400149D
-:106300008F67000C00F5C821AF79000C9375000869
-:1063100016A0000800000000126000060000000047
-:106320008F6800143C0AEFFF3549FFFE0109F8248D
-:10633000AF7F0014A37300088FA500200A00034F4D
-:1063400002202021AED100000A00022D3C03800073
-:1063500014E0FF1E30BFA0400E0001900000A021FD
-:106360002E9100010237B02512C000188FBF0048DF
-:106370008F87003C24170F0010F700D43C068000E4
-:106380008CD901780720FFFE241F0F0010FF00F6B4
-:1063900034CA0E008D56001434C701402408024050
-:1063A000ACF600048D49001C3C141000ACE9000858
-:1063B000A0E00012A4E0001AACE00020A4E0001865
-:1063C000ACE80014ACD401788FBF00488FB700440C
-:1063D0008FB600408FB5003C8FB400388FB30034C7
-:1063E0008FB200308FB1002C8FB0002803E000087E
-:1063F00027BD00508F910038978800403C128000E4
-:106400000220A8213107004014E0FF7C0000982101
-:10641000977900108F9200383338FFFF131200A8CD
-:10642000000020210080A021108000F300A088211E
-:106430001620FECE000000000A00031F2E9100016E
-:106440003C0380008C6201780440FFFE24080800B1
-:106450008F860000AC6801783C038000946D008A50
-:1064600031ACFFFF01865823256AFFFF31441FFF2F
-:106470002C8900081520FFF9000000008F8F0048CC
-:10648000347040008F83003C00E0A021240E0F00F8
-:1064900025E70001AF87004800D03021023488236F
-:1064A0003C08800031F500FF106E00052407000154
-:1064B00093980042331300010013924036470001C5
-:1064C000001524003C0A0100008A4825ACC90000E0
-:1064D0008F82004830BF003630B90008ACC20004DB
-:1064E0001320009900FF982535120E009650000ADF
-:1064F0008F8700003C0F81003203FFFF24ED00086E
-:1065000035060140006F60253C0E100031AB1FFFC7
-:10651000269200062405000EACCC0020026E9825C1
-:10652000A4C5001AAF8B0000A4D2001816200008E2
-:106530003C1080008F89003C24020F005122000291
-:1065400024170001367300400E0001883C108000C3
-:1065500036060E008CCB0014360A01400240202182
-:10656000AD4B00048CC5001CAD450008A1550012C0
-:10657000AD5300140E0001983C151000AE150178C3
-:106580000A00035200000000936F0009976E00128A
-:10659000936D000B31E500FF00AE202131AC00FF10
-:1065A000008C80212602000A3050FFFF0E0001E718
-:1065B000020020218F8600483C0341003C058000FA
-:1065C00024CB0001AF8B0048936A00099769001241
-:1065D00030C600FF315F00FF3128FFFF03E838219C
-:1065E00024F900020006C4000319782501E3702590
-:1065F000AC4E00008F6D000C34A40E00948B001480
-:1066000001B26025AC4C00048C85001C8F6700042F
-:10661000936A00023164FFFF314900FFAFA9001007
-:106620008F680014AFB100180E0001CBAFA80014A2
-:106630000A0002FD02002021AF600004A3600002F6
-:1066400097980040330820001500FEA30000302179
-:10665000A760001297840040936B000A3C108000F2
-:1066600030931F0000135183014BA82126A200285C
-:10667000A362000936090E00953F000C0A0002953E
-:10668000A77F00108F700014360900400E000188AB
-:10669000AF6900140A0002C9000000000A00034F9D
-:1066A000000020210641FEFAACA0000C8CAC000CCE
-:1066B0003C0D8000018D90250A0002EAACB2000C6E
-:1066C000000090210A0002C5241300011280000777
-:1066D0003C028000344B0E009566000830D3004029
-:1066E00012600049000000003C0680008CD0017858
-:1066F0000600FFFE34C50E0094B500103C030500F3
-:1067000034CC014032B8FFFF03039025AD92000C5A
-:106710008CAF0014240D20003C041000AD8F000449
-:106720008CAE001CAD8E0008A1800012A580001A5E
-:10673000AD800020A5800018AD8D0014ACC4017898
-:106740000A0003263C0680008F9F00003518014098
-:106750002692000227F9000833281FFFA71200180D
-:106760000A000391AF8800003C02800034450140DC
-:10677000ACA0000C1280001B34530E0034510E00EC
-:106780008E370010ACB700048E2400183C0B80003C
-:10679000ACA400083570014024040040A20000129F
-:1067A0008FBF0048A600001A8FB70044AE0000203B
-:1067B0008FB60040A60000188FB5003CAE04001450
-:1067C0008FB400388FB300348FB200308FB1002CFB
-:1067D0008FB000283C02100027BD005003E00008E5
-:1067E000AD6201788E660014ACA600048E64001CB5
-:1067F0000A00042A3C0B80000E0001902E9100013B
-:106800000A0003200237B025000000000000000D40
-:1068100000000000240003690A0004013C06800017
-:1068200027BDFFD8AFBF00203C0980003C1F20FFE0
-:10683000AFB200183C07600035320E002402001091
-:1068400037F9FFFDACE23008AFB3001CAFB1001464
-:10685000AFB00010AE5900000000000000000000C2
-:106860000000000000000000000000003C1800FFD5
-:106870003713FFFDAE5300003C0B60048D705000D9
-:106880002411FF7F3C0E00020211782435EC380CF5
-:1068900035CD0109ACED4C18240A0009AD6C50004F
-:1068A0008CE80438AD2A0008AD2000148CE54C1C9F
-:1068B0003106FFFF38C42F7100051E023062000F41
-:1068C0002486C0B310400007AF8200088CE54C1C42
-:1068D0003C09001F3528FC0000A81824000321C231
-:1068E000AF8400048CF108083C0F57092412F00013
-:1068F0000232702435F0001001D0602601CF6826E6
-:106900002DAA00012D8B0001014B382550E0000914
-:10691000A380000C3C1F601C8FF8000824190001A4
-:10692000A399000C33137C00A7930010A780000EDE
-:10693000A380000DAF80004814C00003AF800000AA
-:106940003C066000ACC0442C0E0005B93C10800031
-:106950000E000F24361101003C12080026523DF0B3
-:106960003C13080026733E708E030000386400015B
-:10697000308200011440FFFC3C0B800A8E26000090
-:106980002407FF8024C90240312A007F014B4021A7
-:1069900001272824AE060020AF880044AE0500245D
-:1069A0003C048000AF86003C8C8C01780580FFFEA3
-:1069B00024180800922F0008AC980178A38F004299
-:1069C000938E004231CD000111A0000F24050D006F
-:1069D00024DFF8002FF903011320001C000629C250
-:1069E00024A4FFF000041042000231400E00020215
-:1069F00000D2D8213C0240003C068000ACC20138E5
-:106A00000A0004A00000000010C50023240D0F00A0
-:106A100010CD00273C1F800837F900809338000014
-:106A2000240E0050330F00FF15EEFFF33C02400030
-:106A30000E000A40000000003C0240003C068000BE
-:106A4000ACC201380A0004A0000000008F830004DB
-:106A500000A3402B1500000B8F8B0008006B50210A
-:106A60002547FFFF00E5482B1520000600A3602303
-:106A7000000C19400E0002020073D8210A0004C461
-:106A80003C0240000000000D0E0002020000000069
-:106A90000A0004C43C0240003C1B0800277B3F70F6
-:106AA0000E000202000000000A0004C43C02400084
-:106AB0003C1B0800277B3F900E00020200000000F4
-:106AC0000A0004C43C0240003C0660043C09080083
-:106AD00025290104ACC9502C8CC850003C0580000D
-:106AE0003C02000235070080ACC750003C0408009F
-:106AF000248415A43C0308002463155CACA500089D
-:106B0000ACA2000C3C010800AC243D803C01080014
-:106B1000AC233D8403E000082402000100A03021E2
-:106B20003C1C0800279C3D883C0C04003C0B0002E8
-:106B3000008B3826008C40262CE200010007502BE9
-:106B40002D050001000A48803C03080024633D80B5
-:106B5000004520250123182110800003000010218A
-:106B6000AC6600002402000103E000080000000001
-:106B70003C1C0800279C3D883C0B04003C0A00029A
-:106B8000008A3026008B38262CC200010006482BD4
-:106B90002CE50001000940803C03080024633D808F
-:106BA0000045202501031821108000050000102158
-:106BB0003C0C0800258C155CAC6C00002402000124
-:106BC00003E00008000000003C0900023C0804004B
-:106BD00000883026008938262CC300010080282137
-:106BE0002CE40001008310251040000B0000302130
-:106BF0003C1C0800279C3D883C0A80008D4E000804
-:106C00002406000101CA6825AD4D00088D4C000C1A
-:106C100001855825AD4B000C03E0000800C0102191
-:106C20003C1C0800279C3D883C0580008CA6000C7D
-:106C3000000420272402000100C4182403E00008F7
-:106C4000ACA3000C3C0200021082000B3C0560006B
-:106C50003C070400108700030000000003E0000868
-:106C6000000000008CA908D0240AFFFD012A40245E
-:106C700003E00008ACA808D08CA408D02406FFFECE
-:106C80000086182403E00008ACA308D03C05601A75
-:106C900034A600108CC3008027BDFFF88CC500848B
-:106CA000AFA3000093A4000024020001108200039F
-:106CB000AFA5000403E0000827BD000893A700016A
-:106CC00014E0001497AC000297B800023C0F80005B
-:106CD000330EFFFC01CF6821ADA50000A3A000008A
-:106CE0003C0660008CC708D02408FFFE3C04601AF4
-:106CF00000E82824ACC508D08FA300048FA20000B0
-:106D00003499001027BD0008AF22008003E000087E
-:106D1000AF2300843C0B8000318AFFFC014B4821EB
-:106D20008D2800000A00057DAFA8000427BDFFE8FC
-:106D3000AFBF00103C1C0800279C3D883C0580002C
-:106D40008CA4000C8CA200043C0300020044282404
-:106D500010A0000A00A318243C0604003C04000212
-:106D60001460000900A610241440000F3C04040025
-:106D70000000000D3C1C0800279C3D888FBF0010C0
-:106D800003E0000827BD00183C0208008C423D804B
-:106D90000040F809000000003C1C0800279C3D88CA
-:106DA0000A0005A68FBF00103C0208008C423D84FB
-:106DB0000040F809000000000A0005AC00000000D7
-:106DC000000411C003E00008244202403C04080013
-:106DD00024843FD42405001A0A00009C00003021BE
-:106DE00027BDFFE0AFB000103C108000AFBF00181F
-:106DF000AFB1001436110100922200090E0005B651
-:106E00003044007F8E3F00008F89003C3C0F0080A3
-:106E100003E26021258800400049F821240DFF800D
-:106E2000310E00783198007835F9000135F1000213
-:106E30000319382501D14825010D302403ED5824CC
-:106E4000018D2824240A004024040080240300C06B
-:106E5000AE0B0024AE000810AE0A0814AE040818E9
-:106E6000AE03081CAE050804AE070820AE060808ED
-:106E7000AE090824360909009539000C3605098049
-:106E800033ED007F3338FFFF001889C0AE110800D2
-:106E9000AE0F0828952C000C8FBF00188FB100147E
-:106EA000318BFFFF000B51C0AE0A002C8CA40050A8
-:106EB0008FB000108CA3003C8D2700048CA8001C10
-:106EC0008CA600383C0E800A01AE102127BD0020A0
-:106ED000AF820044AF840050AF830054AF87004CB2
-:106EE000AF88005C03E00008AF8600603C09080042
-:106EF00091293FF924A800023C05110000093C003B
-:106F000000E8302500C5182524820008AC83000065
-:106F100003E00008AC8000043C0980003523090030
-:106F20009128010B906A001124020028008048215A
-:106F3000314700FF00A0702100C0682131080040E7
-:106F400010E20002340C86DD240C08003C0A8000AC
-:106F500035420A9A94470000354B0A9C35460AA0F0
-:106F600030F9FFFFAD3900008D780000354B0A8005
-:106F700024040001AD3800048CCF0000AD2F0008C0
-:106F80009165001930A300031064009A2864000280
-:106F9000148000B924050002106500A8240F000326
-:106FA000106F00BE35450AA4240A0800118A004D5E
-:106FB00000000000510000423C0B80003C048000B7
-:106FC000348309009067001230E200FF004D782101
-:106FD000000FC880272400013C0A8000354F0900BB
-:106FE00091E50019354C09808D87002830A300FFFA
-:106FF00000031500004758250004C4003C19600038
-:1070000001793025370806FFAD260000AD280004C1
-:107010008DEA002C25280028AD2A00088DEC0030D0
-:10702000AD2C000C8DE50034AD2500108DE400384A
-:10703000AD2400148DE3001CAD2300188DE7002063
-:10704000AD27001C8DE20024AD2200208DF9002820
-:10705000AD3900243C0980003526093C8CCF000066
-:10706000352A0100AD0E0004AD0F00008D4E000C5E
-:107070003523090035250980AD0E0008906C0012FB
-:107080008D47000C8CB900343C18080093183FF869
-:10709000318200FF004D582103277823000B370071
-:1070A0000018240000C4702531E9FFFC01C96825DF
-:1070B00025020014AD0D000C03E00008AD00001027
-:1070C00035780900930600123C05080094A53FE8B6
-:1070D00030C800FF010D5021000A60800A00063C04
-:1070E0000185202115000060000000003C08080018
-:1070F00095083FEE3C06080094C63FE801061021C3
-:107100003C0B80003579090093380011932A00194F
-:1071100035660A80330800FF94CF002A0008608299
-:10712000314500FF978A0058000C1E00000524001E
-:107130003047FFFF006410250047C02501EA3021D9
-:107140003C0B4000030B402500066400AD28000006
-:10715000AD2C0004932500183C03000625280014DC
-:1071600000053E0000E31025AD2200088F24002C0E
-:10717000254F000131EB7FFFAD24000C8F38001C40
-:10718000A78B0058AD3800103C0980003526093C1B
-:107190008CCF0000352A0100AD0E0004AD0F0000B9
-:1071A0008D4E000C3523090035250980AD0E0008F1
-:1071B000906C00128D47000C8CB900343C1808000C
-:1071C00093183FF8318200FF004D582103277823A0
-:1071D000000B37000018240000C4702531E9FFFCC3
-:1071E00001C9682525020014AD0D000C03E000085C
-:1071F000AD0000103C02080094423FF23C0508003C
-:1072000094A53FE835440AA43C07080094E73FE40E
-:10721000948B00000045C8210327C023000B1C00ED
-:107220002706FFF200665025AD2A000CAD200010A5
-:10723000AD2C00140A00063025290018354F0AA489
-:1072400095E50000956400280005140000043C004A
-:107250003459810000EC5825AD39000CAD2B0010DD
-:107260000A000630252900143C0C0800958C3FEEDE
-:107270000A000686258200015460FF4C240A08009B
-:1072800035580AA49706000000061C00006C502523
-:10729000AD2A000C0A000630252900103C03080026
-:1072A00094633FF23C07080094E73FE83C0F080076
-:1072B00095EF3FE494A40000957900280067102121
-:1072C000004F582300041C00001934002578FFEEFD
-:1072D00000D87825346A8100AD2A000CAD2F00104B
-:1072E000AD200014AD2C00180A0006302529001C22
-:1072F00003E00008240207D027BDFFE0AFB200186A
-:10730000AFB10014AFB00010AFBF001C0E00007C86
-:10731000008088218F8800548F87004C3C058008AE
-:1073200034B20080011128213C108000240200802A
-:10733000240300C000A72023AE0208183C068008E2
-:10734000AE03081C18800004AF850054ACC50004CF
-:107350008CC90004AF89004C122000093604098052
-:107360000E00070200000000924C00278E0B0074F4
-:1073700001825004014B3021AE46000C36040980D6
-:107380008C8E001C8F8F005C01CF682319A0000435
-:107390008FBF001C8C90001CAF90005C8FBF001C46
-:1073A0008FB200188FB100148FB000100A00007E59
-:1073B00027BD00208F8600508F8300548F82004CA1
-:1073C0003C05800834A40080AC860050AC83003CAF
-:1073D00003E00008ACA200043C0308008C630054E6
-:1073E00027BDFFF8308400FF2462000130A500FFB4
-:1073F0003C010800AC22005430C600FF3C0780006E
-:107400008CE801780500FFFE3C0C7FFFA3A400037D
-:107410008FAA0000358BFFFF014B4824000627C0D0
-:1074200001244025AFA8000034E201009043000A87
-:10743000A3A000023C1980FFA3A300018FAF0000AE
-:1074400030AE007F3738FFFF01F86024000E6E0079
-:107450003C0A002034E50140018D582535492000C3
-:107460002406FF803C04100027BD0008ACAB000CD4
-:10747000ACA90014A4A00018A0A6001203E0000804
-:10748000ACE40178308800FF30A700FF3C038000A7
-:107490008C6201780440FFFE3C0C8000358A0A00B3
-:1074A0008D4B00203584014035850980AC8B00046C
-:1074B0008D4900240007302B00061540AC890008D8
-:1074C000A088001090A3004CA083002D03E00008CA
-:1074D000A480001827BDFFE8308400FFAFBF001074
-:1074E0000E00076730A500FF8F8300548FBF001088
-:1074F0003C06800034C50140344700402404FF901E
-:107500003C02100027BD0018ACA3000CA0A4001280
-:10751000ACA7001403E00008ACC2017827BDFFE06F
-:107520003C088008AFBF001CAFB20018AFB1001418
-:10753000AFB00010351000808E0600183C078000A8
-:10754000309200FF00C72025AE0400180E00007C1A
-:1075500030B100FF92030005346200080E00007E87
-:10756000A2020005024020210E00077B02202821F4
-:10757000024020218FBF001C8FB200188FB1001471
-:107580008FB0001024050005240600010A00073C06
-:1075900027BD00203C05800034A3098090660008C8
-:1075A00030C200081040000F3C0A01013549080AAA
-:1075B000AC8900008CA80074AC8800043C0708006B
-:1075C00090E73FF830E5001050A00008AC800008BC
-:1075D0003C0D800835AC00808D8B0058AC8B0008CA
-:1075E0002484000C03E00008008010210A0007BF7B
-:1075F0002484000C27BDFFE83C098000AFB00010D8
-:10760000AFBF00143526098090C800092402000687
-:1076100000A05821310300FF352709000080802198
-:10762000240500041062007B2408000294CF005C53
-:107630003C0E020431EDFFFF01AE6025AE0C0000F0
-:1076400090CA0008314400201080000800000000AB
-:1076500090C2004E3C1F010337F90300305800FF71
-:107660000319302524050008AE06000490F9001126
-:1076700090E6001290E40011333800FF0018708289
-:1076800030CF00FF01CF5021014B6821308900FF2E
-:1076900031AAFFFF39230028000A60801460002C03
-:1076A000020C482390E400123C198000372F01009F
-:1076B000308C00FF018B1821000310800045F82159
-:1076C000001F8400360706FFAD270004373F09007E
-:1076D00093EC001193EE0012372609800005C0825A
-:1076E0008DE4000C8CC5003431CD00FF01AB1021BE
-:1076F0000058182100A4F8230008840000033F006C
-:1077000000F0302533F9FFFF318F00FC00D97025E0
-:107710000158202101E9682100045080ADAE000C21
-:107720000E00007C012A80213C088008240B000404
-:10773000350500800E00007EA0AB0009020010217C
-:107740008FBF00148FB0001003E0000827BD0018A1
-:1077500090EC001190E300193C18080097183FEED8
-:10776000318200FF0002F882307000FF001FCE005F
-:1077700000103C000327302500D870253C0F400046
-:1077800001CF68253C198000AD2D0000373F09006E
-:1077900093EC001193EE0012372F01003726098079
-:1077A0000005C0828DE4000C8CC5003431CD00FF93
-:1077B00001AB10210058182100A4F8230008840010
-:1077C00000033F0000F0302533F9FFFF318F00FC4C
-:1077D00000D970250158202101E96821000450805A
-:1077E000ADAE000C0E00007C012A80213C08800810
-:1077F000240B0004350500800E00007EA0AB0009BC
-:10780000020010218FBF00148FB0001003E00008A9
-:1078100027BD00180A0007D12408001227BDFFD099
-:107820003C038000AFB60028AFB50024AFB4002001
-:10783000AFB10014AFBF002CAFB3001CAFB2001843
-:10784000AFB000103467010090E6000B309400FFE9
-:1078500030B500FF30C200300000B0211040009968
-:1078600000008821346409809088000800082E00F8
-:1078700000051E03046000C0240400048F86005429
-:107880003C010800A0243FF83C0C8000AD8000487B
-:107890003C048000348E010091CD000B31A5002006
-:1078A00010A000073C078000349309809272000802
-:1078B0000012860000107E0305E000C43C1F800813
-:1078C00034EC0100918A000B34EB098091690008C7
-:1078D000314400400004402B3123000800C89823A5
-:1078E0001460000224120003000090213C1080006C
-:1078F00036180A8036040900970E002C9083001178
-:107900009089001293050018307F00FF312800FF96
-:10791000024810210002C880930D0018033F78210F
-:1079200001F1302130B100FF00D11821A78E00589D
-:107930003C010800A4263FEE3C010800A4233FF0D0
-:1079400015A00002000000000000000D920B010BCA
-:107950003065FFFF3C010800A4233FF2316A00407C
-:107960003C010800A4203FE83C010800A4203FE4BB
-:107970001140000224A4000A24A4000B3091FFFF50
-:107980000E0001E7022020219206010B3C0C0800AA
-:10799000958C3FF2004020210006698231A700014A
-:1079A0000E000601018728210040202102602821C5
-:1079B0000E00060C024030210E0007AB00402021D3
-:1079C00016C00069004020219212010B325600407F
-:1079D00012C000053C0500FF8C93000034AEFFFF91
-:1079E000026E8024AC9000000E0001FB02202021DA
-:1079F0003C0F080091EF3FF831F100031220001610
-:107A00003C1380088F8200543C0980083528008090
-:107A1000245F0001AD1F003C3C0580088CB90004C8
-:107A200003E02021033FC0231B000002AF9F00544E
-:107A30008CA400040E000702ACA400043C078000E4
-:107A40008CEB00743C04800834830080004B502190
-:107A5000AC6A000C3C138008367000800280202144
-:107A600002A02821A200006B0E0007673C148000D2
-:107A70008F920054368C0140AD92000C8F860048E6
-:107A80003C151000344D000624D60001AF96004886
-:107A90008FBF002CA18600128FB60028AD8D001478
-:107AA0008FB3001CAE9501788FB200188FB50024FB
-:107AB0008FB400208FB100148FB0001003E00008D5
-:107AC00027BD003034640980908F0008000F7600D5
-:107AD000000E6E0305A00033347F090093F8001BED
-:107AE000241900103C010800A0393FF833130002AC
-:107AF0001260FF678F8600548F8200601446FF6516
-:107B00003C0480000E00007C000000003C04800863
-:107B10003485008090A8000924060016310300FF78
-:107B20001066000D0000000090AB00093C07080043
-:107B300090E73FF824090008316400FF34EA0001AF
-:107B40003C010800A02A3FF81089002F240C000AED
-:107B5000108C00282402000C0E00007E00000000A3
-:107B60000A00086A8F8600540E0007C302402821CD
-:107B70000A0008B8004020213C0B8008356A0080CC
-:107B80008D4600548CE9000C1120FF3DAF86005457
-:107B9000240700143C010800A0273FF80A000869E8
-:107BA0003C0C800090910008241200023C01080067
-:107BB000A0323FF8323000201200000B24160001E2
-:107BC0008F8600540A00086A2411000837F80080E4
-:107BD0008F020038AFE200048FF90004AF19003CB7
-:107BE0000A0008763C0780008F8600540A00086A65
-:107BF00024110004A0A200090E00007E0000000075
-:107C00000A00086A8F860054240200140A000944FE
-:107C1000A0A2000927BDFFE8AFB000103C10800013
-:107C2000AFBF001436020100904400090E00076740
-:107C3000240500013C0480089099000E34830080E4
-:107C4000909F000F906F00269089000A33F800FF84
-:107C500000196E000018740031EC00FF01AE5025D1
-:107C6000000C5A00014B3825312800FF3603014033
-:107C70003445600000E830252402FF813C041000F8
-:107C8000AC66000C8FBF0014AC650014A06200123B
-:107C9000AE0401788FB0001003E0000827BD001883
-:107CA00027BDFFE8308400FFAFBF00100E0007675C
-:107CB00030A500FF3C05800034A40140344700405B
-:107CC0002406FF92AC870014A08600128F83005414
-:107CD0008FBF00103C02100027BD0018AC83000CC1
-:107CE00003E00008ACA2017827BDFFD8AFB00010B8
-:107CF000308400FF30B000FF3C058000AFB10014BD
-:107D0000AFBF0020AFB3001CAFB20018000410C218
-:107D100034A6010032030002305100011460000754
-:107D200090D200093C098008353300809268000534
-:107D30003107000810E0000C308A001002402021BA
-:107D40000E00078D02202821240200018FBF002091
-:107D50008FB3001C8FB200188FB100148FB00010C9
-:107D600003E0000827BD00281540003434A50A00B0
-:107D70008CB800248CAF0008130F004B0000382192
-:107D80003C0D800835B30080926C00682406000228
-:107D9000318B00FF116600843C06800034C2010074
-:107DA0009263004C90590009307F00FF53F90004A2
-:107DB0003213007C10E00069000000003213007CE8
-:107DC0005660005C0240202116200009320D00019F
-:107DD0003C0C800035840100358B0A008D65002441
-:107DE0008C86000414A6FFD900001021320D00017A
-:107DF00011A0000E024020213C1880003710010025
-:107E00008E0F000C8F8E005011EE00080000000055
-:107E10000E00084D022028218E19000C3C1F8008FE
-:107E200037F00080AE190050024020210E00077B81
-:107E3000022028210A000999240200013C050800BB
-:107E40008CA5006424A400013C010800AC2400645B
-:107E50001600000D00000000022028210E00077B04
-:107E600002402021926E0068240C000231CD00FFF8
-:107E700011AC0022024020210E00094B000000003E
-:107E80000A000999240200010E0000702404000178
-:107E9000926B0025020B30250E00007EA2660025A5
-:107EA0000A0009DD022028218E6200188CDF000400
-:107EB0008CB9002400021E0217F9FFB13065007F63
-:107EC0009268004C264400013093007F1265004008
-:107ED000310300FF1464FFAB3C0D8008264700010E
-:107EE00030F1007F30E200FF1225000B2407000173
-:107EF000004090210A0009A6241100012405000475
-:107F00000E00073C240600010E00094B0000000093
-:107F10000A000999240200012405FF80024520245B
-:107F200000859026324200FF004090210A0009A6F9
-:107F3000241100010E00084D0220282132070030D4
-:107F400010E0FFA132100082024020210E00078DB8
-:107F5000022028210A000999240200018E690018D4
-:107F60000240202102202821012640250E00096E12
-:107F7000AE6800189264004C24050003240600013A
-:107F80000E00073C308400FF0E0000702404000146
-:107F900092710025021150250E00007EA26A002574
-:107FA0000A000999240200018E6F00183C18800015
-:107FB0000240202101F87025022028210E00077BB5
-:107FC000AE6E00189264004C0A000A2524050004D5
-:107FD000324A0080394900801469FF6A3C0D8008EC
-:107FE0000A0009FE2647000127BDFFC0AFB00018F8
-:107FF0003C108000AFBF0038AFB70034AFB60030E0
-:10800000AFB5002CAFB40028AFB30024AFB200204E
-:108010000E0005BEAFB1001C360201009045000BFA
-:108020000E00098090440008144000E78FBF00381C
-:108030003C08800835070080A0E0006B3606098008
-:1080400090C50000240300503C17080026F73FB0FD
-:1080500030A400FF3C13080026733FC010830003C8
-:108060003C1080000000B82100009821241F00105F
-:108070003611010036120A00361509808E58002488
-:108080008E3400048EAF00208F8C00543C01080019
-:10809000A03F3FF836190A80972B002C8EF600007F
-:1080A000932A00180298702301EC68233C01080011
-:1080B000AC2E3FD43C010800AC2D3FD83C01080059
-:1080C000AC2C3FFCA78B005802C0F809315400FFCC
-:1080D00030490002152000E930420001504000C440
-:1080E0009227000992A90008312800081500000213
-:1080F000241500030000A8213C0A80003543090034
-:1081000035440A008C8D002490720011907000128A
-:10811000907F0011325900FF321100FF02B110218F
-:108120000002C08033EF00FF0319B021028F7021DD
-:1081300002D4602125CB00103C010800A4363FEE9C
-:108140003C010800AC2D40003C010800A42C3FF08D
-:108150003C010800A42B3FEC355601003554098042
-:1081600035510E008F8700548F89005C8E8500206A
-:1081700024080006012730233C010800AC283FF406
-:1081800000A7282304C000B50000902104A000B37C
-:1081900000C5502B114000B5000000003C01080054
-:1081A000AC263FD88E6200000040F80900000000B5
-:1081B0003046000214C0007400408021304B0001A2
-:1081C000556000118E6200043C0D08008DAD3FDC4F
-:1081D0003C0EC0003C04800001AE6025AE2C0000C7
-:1081E0008C980000330F000811E0FFFD0000000034
-:1081F000963F000824120001A79F00408E3900041A
-:10820000AF9900388E6200040040F80900000000B9
-:108210000202802532030002146000B30000000057
-:108220003C09080095293FE43C06080094C63FF04D
-:108230003C0A0800954A3FE63C0708008CE73FDC13
-:10824000012670213C0308008C6340003C080800B4
-:1082500095083FFA01CA20218ED9000C00E9282197
-:10826000249F000200A878210067C02133E4FFFFAB
-:10827000AF9900503C010800AC3840003C010800B8
-:10828000A42F3FE83C010800A42E3FF20E0001E7B6
-:10829000000000008F8D0048004020213C010800B4
-:1082A000A02D3FF98E62000825AC0001AF8C00487C
-:1082B0000040F809000000008F85005402A0302122
-:1082C0000E00060C004020210E0007AB00402021CC
-:1082D0008E6B000C0160F809004020213C0A080068
-:1082E000954A3FF23C06080094C63FE60146482105
-:1082F000252800020E0001FB3104FFFF3C050800A9
-:108300008CA53FD43C0708008CE73FDC00A7202366
-:108310003C010800AC243FD414800006000000009B
-:108320003C0208008C423FF4344B00403C01080002
-:10833000AC2B3FF4124000438F8E00448E2D001072
-:108340008F920044AE4D00208E2C0018AE4C0024BD
-:108350003C04080094843FE80E000704000000007D
-:108360008F9F00548E6700103C010800AC3F3FFC1B
-:1083700000E0F809000000003C1908008F393FD4E4
-:108380001720FF798F870054979300583C11800E77
-:10839000321601000E000733A633002C16C000452C
-:1083A000320300105460004C8EE500043208004097
-:1083B0005500001D8EF000088EE4000C0080F809C6
-:1083C000000000008FBF00388FB700348FB6003038
-:1083D0008FB5002C8FB400288FB300248FB20020FB
-:1083E0008FB1001C8FB0001803E0000827BD0040CB
-:1083F0008F86003C36110E0000072E0000A62025B7
-:10840000AE0400808E4300208E500024AFA30010E5
-:10841000AE2300148FB20010AE320010AE30001C3C
-:108420000A000A7FAE3000180200F80900000000C0
-:108430008EE4000C0080F809000000000A000B38F0
-:108440008FBF003824180001240F0001A5C00020B0
-:10845000A5D800220A000B1AADCF00243C01080069
-:10846000AC203FD80A000AB08E6200003C01080030
-:10847000AC253FD80A000AB08E62000092240009A1
-:108480000E00077B000028218FBF00388FB7003413
-:108490008FB600308FB5002C8FB400288FB3002426
-:1084A0008FB200208FB1001C8FB0001803E00008CD
-:1084B00027BD00403C14800092950109000028214E
-:1084C0000E00084D32A400FF320300105060FFB8C8
-:1084D000320800408EE5000400A0F809000000000A
-:1084E0000A000B32320800405240FFA89793005810
-:1084F0008E3400148F930044AE7400208E35001C1F
-:10850000AE7500240A000B29979300588F8200143F
-:108510000004218003E00008008210213C0780084D
-:1085200034E200809043006900804021106000091F
-:108530003C0401003C0708008CE73FFC8F830030BF
-:1085400000E32023048000089389001C14E3000347
-:108550000100202103E00008008010213C040100FC
-:1085600003E00008008010211120000B0067382371
-:108570003C0D800035AC0980918B007C316A000293
-:10858000114000202409003400E9702B15C0FFF1D0
-:108590000100202100E938232403FFFC00A3C824A4
-:1085A00000E3C02400F9782B15E0FFEA030820213E
-:1085B00030C400030004102314C000143049000329
-:1085C0000000302100A9782101E6702100EE682B1F
-:1085D00011A0FFE03C0401002D3800010006C82B6B
-:1085E000010548210319382414E0FFDA2524FFFC93
-:1085F0002402FFFC00A218240068202103E00008E8
-:10860000008010210A000BA8240900303C0C8000D7
-:108610003586098090CB007C316A00041540FFE963
-:10862000240600040A000BB7000030213C030800B8
-:108630008C63005C8F82001827BDFFE0AFBF00187D
-:10864000AFB1001410620005AFB00010000329C0E4
-:1086500024A40280AF840014AF8300183C10800073
-:1086600036020A0094450032361101000E000B89D3
-:1086700030A43FFF8E240000241FFF803C110080A7
-:108680000082C021031F60243309007F000CC94011
-:1086900003294025330E0078362F00033C0D1000CF
-:1086A000010D502501CF5825AE0C00283608098051
-:1086B000AE0C080CAE0B082CAE0A08309103006912
-:1086C0003C06800C0126382110600006AF8700347C
-:1086D0008D09003C8D03006C0123382318E00082D3
-:1086E000000000003C0B8008356A00803C108000D0
-:1086F000A1400069360609808CC200383C06800023
-:1087000034C50A0090A8003C310C00201180001AEA
-:10871000AF820030240D00013C0E800035D10A00EC
-:10872000A38D001CAF8000248E2400248F8500249C
-:10873000240D0008AF800020AF8000283C01080015
-:10874000A42D3FE63C010800A4203FFA0E000B8D4B
-:10875000000030219228003C8FBF00188FB1001418
-:108760008FB0001000086142AF82002C27BD0020AE
-:1087700003E000083182000190B80032240E0001AD
-:10878000330F00FF000F2182108E004124190002D8
-:108790001099006434C40AC03C03800034640A00A9
-:1087A0008C8F002415E0001E34660900909F003075
-:1087B0002418000533F9003F1338004E240300014C
-:1087C0008F860020A383001CAF860028AF8600247C
-:1087D0003C0E800035D10A008E2400248F850024B1
-:1087E000240D00083C010800A42D3FE63C010800D0
-:1087F000A4203FFA0E000B8D000000009228003CE0
-:108800008FBF00188FB100148FB0001000086142B4
-:10881000AF82002C27BD002003E000083182000158
-:108820008C8A00088C8B00248CD000643C0E800065
-:1088300035D10A00014B2823AF900024A380001CEF
-:10884000AF8500288E2400248F8600208F85002489
-:10885000240D00083C010800A42D3FE63C0108005F
-:10886000A4203FFA0E000B8D000000009228003C6F
-:108870008FBF00188FB100148FB000100008614244
-:10888000AF82002C27BD002003E0000831820001E8
-:1088900090A200303051003F5224002834C50AC055
-:1088A0008CB000241600002234CB09008CA60048AE
-:1088B0003C0A7FFF3545FFFF00C510243C0E8000B9
-:1088C000AF82002035C509008F8800208CAD006084
-:1088D000010D602B15800002010020218CA4006096
-:1088E0000A000C2CAF8400208D02006C0A000C06DC
-:1088F0003C0680008C8200488F8600203C097FFF68
-:108900003527FFFF004788243C048008240300012A
-:10891000AF910028AC80006CA383001C0A000C3AC5
-:10892000AF8600248C9F00140A000C2CAF9F0020FF
-:108930008D6200680A000C763C0E800034C4098009
-:108940008C8900708CA300140123382B10E00004E4
-:10895000000000008C8200700A000C763C0E800043
-:108960008CA200140A000C763C0E80008F85002437
-:1089700027BDFFE0AFBF0018AFB1001414A000087E
-:10898000AFB000103C04800034870A0090E600304D
-:108990002402000530C3003F106200B9348409008E
-:1089A0008F91002000A080213C048000348E0A00BA
-:1089B0008DCD00043C0608008CC63FD831A73FFF90
-:1089C00000E6602B5580000100E03021938F001CF1
-:1089D00011E0007800D0282B349F098093F9007CA7
-:1089E00033380002130000792403003400C3102B35
-:1089F000144000D90000000000C3302300D0282B11
-:108A00003C010800A4233FE414A0006E02001821DA
-:108A10003C0408008C843FD40064402B55000001C6
-:108A2000006020213C05800034A90A00912A003C06
-:108A30003C010800AC243FDC3143002014600003FB
-:108A40000000482134AB0E008D6900188F88002C7F
-:108A50000128202B1080005F000000003C0508006A
-:108A60008CA53FDC00A96821010D602B1180005C02
-:108A700000B0702B0109382300E028213C010800D8
-:108A8000AC273FDC12000003240AFFFC10B0008D6D
-:108A90003224000300AA18243C010800A4203FFA55
-:108AA0003C010800AC233FDC006028218F840024B7
-:108AB000120400063C0B80088D6C006C0200202123
-:108AC000AF91002025900001AD70006C8F8D0028C3
-:108AD00000858823AF91002401A52023AF840028BE
-:108AE0001220000224070018240700103C188008F8
-:108AF0003706008090CF00683C010800A0273FF8AF
-:108B00002407000131EE00FF11C7004700000000FC
-:108B100014800018000028213C06800034D1098010
-:108B200034CD010091A600098E2C001824C4000148
-:108B3000000C86023205007F308B007F1165007FBC
-:108B40002407FF803C19800837290080A124004CAD
-:108B50003C0808008D083FF4241800023C0108007E
-:108B6000A0384039350F00083C010800AC2F3FF415
-:108B7000240500103C02800034440A009083003C2D
-:108B8000307F002013E0000500A02021240A00010E
-:108B90003C010800AC2A3FDC34A400018FBF001860
-:108BA0008FB100148FB000100080102103E0000886
-:108BB00027BD00203C010800A4203FE410A0FF9442
-:108BC000020018210A000CCA00C018210A000CC1BA
-:108BD000240300303C0508008CA53FDC00B0702B5E
-:108BE00011C0FFA8000000003C19080097393FE4BD
-:108BF0000325C0210307782B11E000072CAA0004ED
-:108C00003C0360008C625404305F003F17E0FFE3D8
-:108C1000240400422CAA00041140FF9A24040042BC
-:108C20000A000D2E8FBF00181528FFB900000000A4
-:108C30008CCA00183C1F800024020002015F182526
-:108C4000ACC3001837F90A00A0C200689329003CA1
-:108C50002404000400A01021312800203C01080059
-:108C6000A024403911000002240500102402000154
-:108C70003C010800AC223FD40A000D243C028000D5
-:108C80008F8800288C8900600109282B14A000021D
-:108C9000010088218C9100603C048000348B0E0020
-:108CA0008D640018240A00010220282102203021AE
-:108CB000A38A001C0E000B8D022080210A000CB03C
-:108CC000AF82002C000458231220000731640003F7
-:108CD0003C0E800035C7098090ED007C31AC00046B
-:108CE00015800019248F00043C010800A4243FFAD9
-:108CF0003C1F080097FF3FFA03E5C82100D9C02BAD
-:108D00001300FF6B8F8400242CA6000514C0FFA362
-:108D10002404004230A200031440000200A21823E1
-:108D200024A3FFFC3C010800AC233FDC3C0108000D
-:108D3000A4203FFA0A000CF10060282100C770242B
-:108D40000A000D1701C720263C010800A42F3FFA96
-:108D50000A000D82000000003C010800AC203FDC4E
-:108D60000A000D2D240400428F8300283C0580005A
-:108D700034AA0A0014600006000010219147003058
-:108D80002406000530E400FF108600030000000008
-:108D900003E0000800000000914B0048316900FF2B
-:108DA000000941C21500FFFA3C0680083C04080097
-:108DB00094843FE43C0308008C633FFC3C190800AA
-:108DC0008F393FDC3C0F080095EF3FFA0064C0216B
-:108DD0008CCD00040319702101CF602134AB0E004B
-:108DE000018D282318A0001D00000000914F004CA9
-:108DF0008F8C0034956D001031EE00FF8D890004DA
-:108E000001AE30238D8A000030CEFFFF000E290016
-:108E10000125C82100003821014720210325182BF6
-:108E20000083C021AD990004AD980000918F000A25
-:108E300001CF6821A18D000A956500128F8A003448
-:108E4000A5450008954B003825690001A549003863
-:108E50009148000D35070008A147000D03E0000808
-:108E60000000000027BDFFD8AFB000189388001C99
-:108E70008FB000143C0A80003C197FFF8F870024CC
-:108E80003738FFFFAFBF0020AFB1001C355F0A00CD
-:108E90000218182493EB003C00087FC03C02BFFF7F
-:108EA000006F60252CF000013449FFFF3C1F0800D3
-:108EB0008FFF3FFC8F9900303C18080097183FF255
-:108EC00001897824001047803C07EFFF3C05F0FF44
-:108ED00001E818253C1180003169002034E2FFFFD1
-:108EE00034ADFFFF362E098027A5001024060002AE
-:108EF00003F96023270B0002354A0E000062182494
-:108F00000080802115200002000040218D48001CB7
-:108F1000A7AB0012058000392407000030E800FFED
-:108F200000083F00006758253C028008AFAB0014E2
-:108F3000344F008091EA00683C08080091083FF92E
-:108F40003C09DFFF352CFFFF000AF82B3C0208002C
-:108F500094423FECA3A80011016CC024001FCF4035
-:108F6000031918258FA70010AFA300143C0C0800AC
-:108F7000918C3FFBA7A200168FAB001400ED482494
-:108F80003C0F01003C0A0FFF012FC8253198000358
-:108F9000355FFFFF016D40243C027000033F382421
-:108FA00000181E0000E2482501037825AFAF001429
-:108FB000AFA9001091CC007C0E000092A3AC00156C
-:108FC000362D0A0091A6003C30C400201080000617
-:108FD000260200083C11080096313FE8262EFFFFCC
-:108FE0003C010800A42E3FE88FBF00208FB1001C79
-:108FF0008FB0001803E0000827BD00288F8B002CDD
-:10900000010B502B5540FFC5240700010A000E0E2E
-:1090100030E800FF9383001C3C02800027BDFFD88E
-:1090200034480A0000805021AFBF002034460AC0F7
-:10903000010028211060000E34440980910700309F
-:10904000240B00058F89002030EC003F118B000BB2
-:1090500000003821AFA900103C0B80088D69006C1E
-:10906000AFAA00180E00015AAFA90014A380001C7B
-:109070008FBF002003E0000827BD00288D1F004897
-:109080003C1808008F183FDC8F9900283C027FFFB6
-:109090008D0800443443FFFFAFA900103C0B80084B
-:1090A0008D69006C03E370240319782101CF6823D4
-:1090B00001A83821AFAA00180E00015AAFA9001468
-:1090C0000A000E62A380001C3C05800034A60A0042
-:1090D00090C7003C3C06080094C63FFA3C020800DA
-:1090E0008C423FF430E30020000624001060001E94
-:1090F000004438253C0880083505008090A30068AE
-:109100000000482124080001000028212404000157
-:109110003C0680008CCD017805A0FFFE34CF0140D5
-:10912000ADE800083C0208008C423FFCA5E50004C5
-:10913000A5E40006ADE2000C3C04080090843FF971
-:109140003C03800834790080A1E40012ADE70014EC
-:10915000A5E900189338004C3C0E1000A1F8002D32
-:1091600003E00008ACCE017834A90E008D28001C65
-:109170003C0C08008D8C3FDC952B0016952A0014C2
-:10918000018648213164FFFF0A000E8A3145FFFF46
-:109190003C04800034830A009065003C30A200202B
-:1091A0001040001934870E000000402100003821D3
-:1091B000000020213C0680008CC901780520FFFEBC
-:1091C00034CA014034CF010091EB0009AD480008DA
-:1091D0003C0E08008DCE3FFC240DFF91240C004076
-:1091E0003C081000A5440004A5470006AD4E000C45
-:1091F000A14D0012AD4C0014A5400018A14B002D4C
-:1092000003E00008ACC801788CE8001894E600126E
-:1092100094E4001030C7FFFF0A000EB33084FFFF54
-:109220003C04800034830A009065003C30A200209A
-:109230001040002727BDFFF8240900010000382155
-:10924000240800013C0680008CCA01780540FFFE1E
-:109250003C0280FF34C40100908D00093C0C0800E2
-:10926000918C4039A3AD00038FAB00003185007FA6
-:109270003459FFFF01665025AFAA00009083000A11
-:10928000A3A0000200057E00A3A300018FB8000088
-:1092900034CB0140240C30000319702401CF682521
-:1092A000AD6D000C27BD0008AD6C0014A560001862
-:1092B000AD690008A56700042409FF80A5680006C1
-:1092C0003C081000A169001203E00008ACC8017856
-:1092D00034870E008CE9001894E6001294E4001024
-:1092E00030C8FFFF0A000ED73087FFFF27BDFFE021
-:1092F000AFB100143C118000AFB00010AFBF001838
-:1093000036380A00970F0032363001000E000B8904
-:1093100031E43FFF8E0E0000240DFF803C0420004E
-:1093200001C25821016D6024000C4940316A007F60
-:10933000012A4025010438253C048008AE27083066
-:109340003486008090C500682403000230A200FF2C
-:10935000104300048F9F00208F990024AC9F006869
-:10936000AC9900648FBF00188FB100148FB000104B
-:1093700003E0000827BD00203C0A0800254A3AA85F
-:109380003C09080025293B383C08080025082F44E3
-:109390003C07080024E73C043C06080024C6392C9E
-:1093A0003C05080024A536803C040800248432844F
-:1093B0003C030800246339E03C0208002442377C67
-:1093C0003C010800AC2A3FB83C010800AC293FB47E
-:1093D0003C010800AC283FB03C010800AC273FBC72
-:1093E0003C010800AC263FCC3C010800AC253FC442
-:1093F0003C010800AC243FC03C010800AC233FD036
-:109400003C010800AC223FC803E000080000000057
-:109410008000094080000900800801008008008069
-:1094200080080000800E0000800800808008000096
-:1094300080000A8080000A00800009808000090006
+:10000000AF8B002000CA2024AF85000010800008BC
+:10001000AF860004240C87FF00CC5824156000082C
+:100020003C0D006000AD302410C000050000000051
+:100030000E000D42000000000A00137100000000D5
+:100040000E001636000000000A00137100000000C8
+:1000500030B980005320FF1DAF8500003C02002016
+:1000600000A2F82453E0FF19AF8500003C07FFFF12
+:1000700034E47FFF00A438240A00132B34C8800026
+:100080000A0013340109102400EC58245160005A6E
+:10009000AF8000288F8D00303C0E0F0000EE18243A
+:1000A00015A00075AF83001030EF010011E0007360
+:1000B000939800103C120200107200703C06800001
+:1000C00034D90100932800139789002E36A6000228
+:1000D000311800FF27160004001619C03C048000E8
+:1000E0008C8501B804A0FFFE34880180AD030000B8
+:1000F0003C158008AC83002096BF004833E5FFFF25
+:1001000010A001EBAF8500082523001200A3102BDF
+:10011000504001E88F850004348D010095AC00202B
+:10012000240B001A30E44000318AFFFFA10B000BC2
+:10013000108001E92543FFFE00A3702B15C001E7E5
+:100140008F9600048F8F0004A503001435E500018D
+:10015000AF8500043C08800035150180A6A9000E7B
+:10016000A6A9001A8F89000C30BF8000A6A7001036
+:10017000AEA90028A6A6000813E0000F3C0F8000DF
+:10018000350C0100958B0016316AFFFC25440004F4
+:10019000008818218C6240003046FFFF14C0000721
+:1001A0002416BFFF3C0EFFFF35CD7FFF00AD282496
+:1001B000AF8500043C0F80002416BFFF00B69024DA
+:1001C00035E50180A4B20026ACA7002C3C07100046
+:1001D000ADE701B80A001370000018210E00168E5A
+:1001E000000000003C0B40003C068000ACCB0178D6
+:1001F0000A001304000000008F85002810A00025CD
+:10020000AF80001090A3000010600072241F000354
+:10021000107F00FF0000302190AD0001240C00028F
+:1002200011AC015930EE004090BF000124190001CB
+:1002300013F9000930E900408CA600049785002ED0
+:1002400000C020210E000FDB36A600020000402176
+:100250000A001370010018215120FFF88CA6000439
+:100260003C07080190E796E110E0FFF42408000144
+:100270000A00137001001821939800100018C8C0DC
+:10028000033E4021AF8800288F85002814A0FFDDA1
+:10029000AF9800103C0480008C86400030C50100FF
+:1002A00010A0008732AA00043C0B08008D6B0024CC
+:1002B00024160004154000033172000D24160002BC
+:1002C0003C0480008C8D4000340CFFFF11AC012CED
+:1002D00032B5FFFB8C8F400031EE010055C00001AC
+:1002E0002415001030F8080013000038241FFFFB0D
+:1002F0008F99002C2F2803EF51000001025F9024FA
+:1003000030E9010011200014325900018F870030BC
+:1003100014E001278F8B000C3C0480003486010020
+:1003200090C5001330A300FF24620004000221C026
+:100330002408FFFE024890241240000202B6302535
+:1003400032A6FFFF0E000FDB9785002E1240FEA3A2
+:1003500000001821325900011320000D324700041B
+:10036000241F0001125F000202B6302532A6FFFFF3
+:100370009785002E0E000FDB000020212409FFFED0
+:10038000024990241240FE950000182132470004D3
+:1003900050E0FE922403000102B63025241600042A
+:1003A0005656000132A6FFFF9785002E0E000FDB88
+:1003B000240401002402FFFB0242A82412A0FE87AD
+:1003C000000018210A001370240300010A0014B968
+:1003D000025F902410A0FFAF30E5010010A00017CD
+:1003E0008F8600102402000210C200148F84000CBB
+:1003F0003C0608008CC6003824C3FFFF14C000026E
+:1004000000831024000010213C0D080025AD0038A9
+:10041000004D6021918B00048F85002C256A00041B
+:10042000000A21C030A5FFFF36A600020E000FDB38
+:10043000000000000A00137000001821240E0002C2
+:1004400010CE0088241200013C0308008C6300D009
+:100450001072008D8F85002C24C8FFFC2D1800041D
+:100460001700006300002021241900021079005DAC
+:100470002CDF000C24C2FFF82C4900041520FFE9F2
+:100480000000202130E3020050600004000621C07B
+:1004900054C0000530A5FFFF000621C030A5FFFFB6
+:1004A0000A00150436A600020E000FDB32A600017A
+:1004B0008F8600108F85002C0A001520000621C0B1
+:1004C0003C0308008C630024307200015240FE435C
+:1004D000000018219785002E36A600020E000FDBC3
+:1004E000000020210A001370000018219668000CFB
+:1004F000311802005700FE313C0500013C1F800806
+:1005000097F900489789002E36A600023328FFFF8E
+:10051000AF8800083C0380008C7501B806A0FFFE80
+:100520003C04800034820180AC400000110000E7F0
+:1005300024180003252A0012010A182B106000E37A
+:1005400000000000966F00203C0E8000240D001A71
+:1005500031ECFFFF35CA018030EB4000A14D000BAC
+:10056000116000E12583FFFE0103902B164000DFA0
+:100570002416FFFE34A50001A5430014AF85000436
+:100580002419BFFF00B94024A6E9000EA6E9001A0D
+:10059000A6E60008A6E80026A6E700103C07100023
+:1005A000AE8701B80A001370000018213C048000D7
+:1005B0008C8901B80520FFFE349601802415001CAB
+:1005C000AEC70000A2D5000B3C071000AC8701B8F5
+:1005D0003C0B40003C068000ACCB01780A001304C1
+:1005E0000000000013E0FFA424C2FFF80000202157
+:1005F00030A5FFFF0A00150436A600020E00103DCC
+:10060000000000008F8700000A001346AF82000C34
+:1006100090A30001241500011075FF0D24080001AE
+:10062000240900021069000430E60040240800019B
+:100630000A0013700100182150C0FFFD24080001BA
+:100640003C0B8000356A01009543001094A4000221
+:100650003062FFFF5082FDE1010018210A0015857C
+:10066000240800018F85002C2CAF03EF11E0FDDB87
+:10067000240300013C0308008C6300D02412000115
+:100680001472FF7624C8FFFC2CD6000C12C0FF7237
+:10069000000621C030A5FFFF0A00150436A600029F
+:1006A00010AF005700043A022406000B14A6FE24E3
+:1006B000000A41C0316600FF0006FE00001F5E0315
+:1006C0000562007230C6007F000668C001BE382196
+:1006D000A0E00001A0E000003C1660008ED21820CF
+:1006E000240C000100CC100400021827000A41C0AD
+:1006F0000243A824A4E0000201003821AED518204E
+:100700000A0013CB3C06800014C000368F8D0020F9
+:10071000000A41C03C1F80003C058008AFE8002073
+:1007200094B9004013200002240500012405004173
+:100730003C0480008C8701B804E0FFFE3495018002
+:1007400024020003AEA80000A2A2000BA6A0000E87
+:10075000A6A0001AA6A00010AEA00028A6A500081A
+:1007600096A3002634720001A6B20026AEA0002C8B
+:100770003C161000AC9601B80A0013CA01003821DB
+:100780000A0014B22415002011C0FEB53C088000F8
+:10079000351801009716001094B2000232CF0FFFF7
+:1007A000164FFEAF000000000A00148490BF000145
+:1007B0003C0A08008D4A0038254CFFFF1540000216
+:1007C000016C1024000010213C1808002718003884
+:1007D0000058782191EE000425CD00040A0014C5CC
+:1007E000000D21C0000A41C025ACFFFF1580FDD4DB
+:1007F000AF8C0020010038210A0013CAAF8000240A
+:10080000240300FF10E3FDCE000A41C010C0001712
+:1008100000078600000720C0009E18212402000166
+:100820003C05080124A596E4009E7821000A41C0F9
+:100830000085C821000B8C02A0620000AF280000D8
+:10084000A1F100013C0E60008DC6182024180001A3
+:1008500000F8500400CA202501003821A5EB000251
+:10086000ADC418200A0013CB3C06800000104603DC
+:100870000502000D30E7007F11430006000720C08D
+:10088000009E18210A001601240200020A0015AB7E
+:10089000AF800020009E18210A00160124020003E8
+:1008A0000A0012FFAF8400300A001617AF8700203D
+:1008B0008F8500043C19800024080003373801802C
+:1008C000A308000B0A00144F3C088000A2F8000B9C
+:1008D0000A00155A2419BFFF8F9600042412FFFE48
+:1008E0000A00144D02D228242416FFFE0A001558CF
+:1008F00000B628243C038000346401008C8500008D
+:1009000030A2003E1440000800000000AC60004827
+:100910008C87000030E607C010C000050000000012
+:10092000AC60004CAC60005003E000082402000101
+:10093000AC600054AC6000408C880000310438008A
+:100940001080FFF9000000002402000103E000080D
+:10095000AC6000443C0380008C6201B80440FFFEA0
+:1009600034670180ACE4000024080001ACE000041E
+:10097000A4E5000824050002A0E8000A3464014050
+:10098000A0E5000B9483000A14C00008A4E3001043
+:10099000ACE000243C07800034E901803C041000F6
+:1009A000AD20002803E00008ACE401B88C86000408
+:1009B0003C041000ACE600243C07800034E90180D0
+:1009C000AD20002803E00008ACE401B83C0680003C
+:1009D0008CC201B80440FFFE34C701802409000224
+:1009E000ACE40000ACE40004A4E50008A0E9000ABF
+:1009F00034C50140A0E9000B94A8000A3C04100093
+:100A0000A4E80010ACE000248CA30004ACE30028B0
+:100A100003E00008ACC401B83C039000346200015C
+:100A2000008220253C038000AC6400208C650020FF
+:100A300004A0FFFE0000000003E00008000000002A
+:100A40003C028000344300010083202503E00008BD
+:100A5000AC44002027BDFFE03C098000AFBF001878
+:100A6000AFB10014AFB00010352801408D10000068
+:100A7000910400099107000891050008308400FFE7
+:100A800030E600FF00061A002C820081008330252A
+:100A90001040002A30A50080000460803C0D080151
+:100AA00025AD9350018D58218D6A0000014000084A
+:100AB000000000003C038000346201409445000ABD
+:100AC00014A0001E8F91FCC09227000530E60004A0
+:100AD00014C0001A000000000E00167F0200202142
+:100AE000922A000502002021354900040E001689D3
+:100AF000A229000592280005310400041480000298
+:100B0000000000000000000D922D0000240B0020CA
+:100B100031AC00FF158B00093C0580008CAE01B89C
+:100B200005C0FFFE34B10180AE3000003C0F100064
+:100B300024100005A230000BACAF01B80000000D7E
+:100B40008FBF00188FB100148FB0001003E00008B1
+:100B500027BD00200200202100C028218FBF0018DF
+:100B60008FB100148FB00010240600010A00164E49
+:100B700027BD00200000000D0200202100C0282118
+:100B80008FBF00188FB100148FB00010000030210B
+:100B90000A00164E27BD002014A0FFE80000000048
+:100BA000020020218FBF00188FB100148FB00010F9
+:100BB00000C028210A00166C27BD00203C078000D9
+:100BC0008CEE01B805C0FFFE34F00180241F000246
+:100BD000A21F000B34F80140A60600089719000A6E
+:100BE0003C0F1000A61900108F110004A61100126E
+:100BF000ACEF01B80A0016CA8FBF001827BDFFE886
+:100C0000AFBF00100E000FD4000000003C028000B7
+:100C10008FBF001000002021AC4001800A00108F1F
+:100C200027BD00183084FFFF30A5FFFF10800007AC
+:100C30000000182130820001104000020004204210
+:100C4000006518211480FFFB0005284003E0000820
+:100C50000060102110C00007000000008CA20000FE
+:100C600024C6FFFF24A50004AC82000014C0FFFBD3
+:100C70002484000403E000080000000010A0000825
+:100C800024A3FFFFAC86000000000000000000006D
+:100C90002402FFFF2463FFFF1462FFFA2484000490
+:100CA00003E00008000000003C03800027BDFFF8BF
+:100CB00034620180AFA20000308C00FF30AD00FF35
+:100CC00030CE00FF3C0B80008D6401B80480FFFE35
+:100CD000000000008FA900008D6801288FAA000085
+:100CE0008FA700008FA40000240500012402000249
+:100CF000A085000A8FA30000359940003C05100034
+:100D0000A062000B8FB800008FAC00008FA600001F
+:100D10008FAF000027BD0008AD280000AD400004E3
+:100D2000AD800024ACC00028A4F90008A70D001075
+:100D3000A5EE001203E00008AD6501B83C0680088E
+:100D400027BDFFE834C50080AFBF001090A70009A1
+:100D50002402001230E300FF1062000B00803021FB
+:100D60008CA8005000882023048000088FBF00104A
+:100D70008CAA0034240400390000282100CA48232A
+:100D800005200005240600128FBF00102402000178
+:100D900003E0000827BD00180E0017230000000024
+:100DA0008FBF00102402000103E0000827BD0018D7
+:100DB00027BDFFC8AFB20030AFB00028AFBF0034CE
+:100DC000AFB1002C00A0802190A5000D30A600102E
+:100DD00010C00010008090213C0280088C44000468
+:100DE0008E0300081064000C30A7000530A6000533
+:100DF00010C00093240400018FBF00348FB2003074
+:100E00008FB1002C8FB000280080102103E0000873
+:100E100027BD003830A7000510E0000F30AB0012EE
+:100E200010C00006240400013C0980088E08000858
+:100E30008D2500045105009C240400388FBF003428
+:100E40008FB200308FB1002C8FB0002800801021AD
+:100E500003E0000827BD0038240A0012156AFFE6E7
+:100E6000240400010200202127A500100E000CB66A
+:100E7000AFA000101440007C3C198008372400808B
+:100E800090980008331100081220000A8FA7001064
+:100E900030FF010013E000A48FA300148C860058DB
+:100EA00000661023044000043C0A8008AC8300580C
+:100EB0008FA700103C0A800835480080910900087F
+:100EC000312400081480000224080003000040219F
+:100ED0003C1F800893F1001193F9001237E600805F
+:100EE0008CCC0054333800FF03087821322D00FFEA
+:100EF000000F708001AE282100AC582B1160006FEC
+:100F00000000000094CA005C8CC900543144FFFF0B
+:100F1000012510230082182B1460006800000000D7
+:100F20008CCB00540165182330EC00041180006C58
+:100F3000000830808FA8001C0068102B1040006251
+:100F400030ED0004006610232C46008010C0000223
+:100F500000408821241100800E00167F02402021CD
+:100F60003C0D800835A6008024070001ACC7000CAA
+:100F700090C800080011484035A70100310C007FDF
+:100F8000A0CC00088E05000424AB0001ACCB0030DF
+:100F9000A4D1005C8CCA003C9602000E01422021C4
+:100FA000ACC400208CC3003C0069F821ACDF001CFD
+:100FB0008E190004ACF900008E180008ACF800048B
+:100FC0008FB10010322F000855E0004793A6002093
+:100FD000A0C0004E90D8004E2411FFDFA0F80008FA
+:100FE00090CF000801F17024A0CE00088E05000803
+:100FF0003C0B800835690080AD2500388D6A0014EF
+:101000008D2200302419005001422021AD240034EB
+:1010100091230000307F00FF13F90036264F0100B6
+:101020000E001689024020212404003800002821E7
+:101030000E0017232406000A0A0017882404000162
+:101040000E000D28000020218FBF00348FB2003029
+:101050008FB1002C8FB0002800402021008010218B
+:1010600003E0000827BD00388E0E00083C0F800802
+:1010700035F00080AE0E005402402021AE0000305A
+:101080000E00167F00000000920D00250240202176
+:1010900035AC00200E001689A20C00250E000CAC09
+:1010A00002402021240400382405008D0E0017235F
+:1010B000240600120A0017882404000194C5005C6D
+:1010C0000A0017C330A3FFFF2407021811A0FF9ED8
+:1010D00000E610238FAE001C0A0017CB01C61023B8
+:1010E0000A0017C82C620218A0E600080A0017F5CB
+:1010F0008E0500082406FF8001E6C0243C11800014
+:10110000AE3800288E0D000831E7007F3C0E800CC1
+:1011100000EE6021AD8D00E08E080008AF8C003C31
+:101120000A001801AD8800E4AC80005890850008E2
+:101130002403FFF700A33824A08700080A0017A69D
+:101140008FA700103C05080024A5616C3C04080032
+:10115000248470B83C020800244261742403000611
+:101160003C010801AC2597603C010801AC24976460
+:101170003C010801AC2297683C010801A023976C50
+:1011800003E000080000000003E000082402000162
+:101190003C028000308800FF344701803C0680001C
+:1011A0008CC301B80460FFFE000000008CC501285C
+:1011B0002418FF803C0D800A24AF010001F8702440
+:1011C00031EC007FACCE0024018D2021ACE5000085
+:1011D000948B00EA3509600024080002316AFFFFA1
+:1011E000ACEA000424020001A4E90008A0E8000B16
+:1011F000ACE000243C071000ACC701B8AF84003C51
+:1012000003E00008AF8500709388004C8F8900646C
+:101210008F82003C30C600FF0109382330E900FF0F
+:101220000122182130A500FF2468008810C00002A8
+:10123000012438210080382130E4000314800003A9
+:1012400030AA00031140000D312B000310A000094B
+:101250000000102190ED0000244E000131C200FF7B
+:101260000045602BA10D000024E700011580FFF967
+:101270002508000103E00008000000001560FFF3EE
+:101280000000000010A0FFFB000010218CF80000FF
+:1012900024590004332200FF0045782BAD180000CC
+:1012A00024E7000415E0FFF92508000403E0000826
+:1012B000000000009385004C9388005C8F870064D9
+:1012C000000432003103007F00E5102B30C47F00A2
+:1012D0001040000F006428258F84003C3C098000EA
+:1012E0008C8A00ECAD2A00A43C03800000A35825A2
+:1012F000AC6B00A08C6C00A00580FFFE000000001D
+:101300008C6D00ACAC8D00EC03E000088C6200A892
+:101310000A0018B38F84003C9388005D3C02800073
+:1013200000805021310300FEA383005D30ABFFFF3E
+:1013300030CC00FF30E7FFFF344801803C098000DB
+:101340008D2401B80480FFFE8F8D007024180016D4
+:10135000AD0D00008D2201248F8D003CAD020004F4
+:101360008D590020A5070008240201C4A119000A14
+:10137000A118000B952F01208D4E00088D47000409
+:10138000978300608D59002401CF302100C72821A8
+:1013900000A320232418FFFFA504000CA50B000EBA
+:1013A000A5020010A50C0012AD190018AD180024FC
+:1013B00095AF00E83C0B10002407FFF731EEFFFF6C
+:1013C000AD0E00288DAC0084AD0C002CAD2B01B807
+:1013D0008D46002000C7282403E00008AD4500200A
+:1013E0008F88003C0080582130E7FFFF910900D62C
+:1013F0003C02800030A5FFFF312400FF00041A00EA
+:101400000067502530C600FF344701803C0980004A
+:101410008D2C01B80580FFFE8F820070240F00170D
+:10142000ACE200008D390124ACF900048D78002075
+:10143000A4EA0008241901C4A0F8000AA0EF000BD8
+:10144000952301208D6E00088D6D00049784006047
+:1014500001C35021014D602101841023A4E2000C3E
+:10146000A4E5000EA4F90010A4E60012ACE00014FC
+:101470008D780024240DFFFFACF800188D0F007C40
+:10148000ACEF001C8D0E00783C0F1000ACEE00207D
+:10149000ACED0024950A00BE240DFFF73146FFFF96
+:1014A000ACE60028950C00809504008231837FFF14
+:1014B0000003CA003082FFFF0322C021ACF8002CD9
+:1014C000AD2F01B8950E00828D6A002000AE30214C
+:1014D000014D2824A506008203E00008AD65002028
+:1014E0003C028000344501803C0480008C8301B8BC
+:1014F0000460FFFE8F8A0048240600199549001CED
+:101500003128FFFF000839C0ACA70000A0A6000BDF
+:101510003C05100003E00008AC8501B88F8700503F
+:101520000080402130C400FF3C0680008CC201B81E
+:101530000440FFFE8F8900709383006C3499600033
+:10154000ACA90000A0A300058CE20010240F00024B
+:101550002403FFF7A4A20006A4B900088D180020F8
+:10156000A0B8000AA0AF000B8CEE0000ACAE0010DB
+:101570008CED0004ACAD00148CEC001CACAC002471
+:101580008CEB0020ACAB00288CEA002C3C07100050
+:10159000ACAA002C8D090024ACA90018ACC701B876
+:1015A0008D05002000A3202403E00008AD040020E6
+:1015B0008F86003C27BDFFE0AFB10014AFBF00181D
+:1015C000AFB0001090C300D430A500FF30620020FF
+:1015D00010400008008088218CCB00D02409FFDF58
+:1015E000256A0001ACCA00D090C800D40109382493
+:1015F000A0C700D414A000403C0C80008F84003CA5
+:10160000908700D42418FFBF2406FFEF30E3007F4B
+:10161000A08300D4979F00608F8200648F8D003C70
+:1016200003E2C823A7990060A5A000BC91AF00D435
+:1016300001F87024A1AE00D48F8C003CA18000D7AB
+:101640008F8A003CA5400082AD4000EC914500D45B
+:1016500000A65824A14B00D48F9000388F840064DA
+:10166000978600600204282110C0000FAF85003863
+:10167000A380005C3C0780008E2C000894ED0120C4
+:101680008E2B0004018D5021014B80210206202366
+:101690003086FFFF30C8000F3909000131310001E9
+:1016A00016200009A388005C9386004C8FBF0018A9
+:1016B0008FB100148FB0001027BD0020AF850068E7
+:1016C00003E00008AF86006400C870238FBF0018D5
+:1016D0009386004C8FB100148FB0001034EF0C00D3
+:1016E000010F282127BD0020ACEE0084AF850068E3
+:1016F00003E00008AF8600643590018002002821D5
+:101700000E001940240600828F84003C908600D48D
+:1017100030C5004050A0FFBAA380006C8F850050F8
+:101720003C0680008CCD01B805A0FFFE8F890070BB
+:101730002408608224070002AE090000A608000801
+:10174000A207000B8CA300083C0E1000AE03001093
+:101750008CA2000CAE0200148CBF0014AE1F001847
+:101760008CB90018AE1900248CB80024AE180028DB
+:101770008CAF0028AE0F002CACCE01B80A0019794E
+:10178000A380006C8F8A003C27BDFFE0AFB100143E
+:10179000AFB000108F880064AFBF0018938900407D
+:1017A000954200BC30D100FF0109182B0080802138
+:1017B00030AC00FF3047FFFF0000582114600003E9
+:1017C000310600FF01203021010958239783006072
+:1017D0000068202B148000270000000010680056CD
+:1017E000241900011199006334E708803165FFFF77
+:1017F0000E0018F1020020218F8300703C0780004A
+:1018000034E601803C0580008CAB01B80560FFFE2A
+:10181000240A00188F84003CACC30000A0CA000B4F
+:10182000948900BE3C081000A4C90010ACC0003070
+:10183000ACA801B89482008024430001A4830080F6
+:10184000949F00803C0608008CC6318833EC7FFFF3
+:101850001186005E000000000200202102202821E5
+:101860008FBF00188FB100148FB000100A001965E7
+:1018700027BD0020914400D42403FF8000838825E5
+:10188000A15100D4978400603088FFFF51000023ED
+:10189000938C00408F85003C2402EFFF008B78235F
+:1018A00094AE00BC0168502B31E900FF01C26824EE
+:1018B000A4AD00BC51400039010058213C1F8000FC
+:1018C00037E601008CD800043C19000103194024BC
+:1018D0005500000134E740008E0A00202403FFFB7E
+:1018E0002411000101432024AE0400201191002D99
+:1018F00034E7800002002021012030210E0018F181
+:101900003165FFFF978700608F890064A7800060C2
+:1019100001278023AF900064938C00408F8B003CA4
+:101920008FBF00188FB100148FB0001027BD0020AA
+:1019300003E00008A16C00D73C0D800035AA01002F
+:101940008D4800043C0900010109282454A000012D
+:1019500034E740008E0F00202418FFFB34E780009E
+:1019600001F8702424190001AE0E00201599FF9F84
+:1019700034E70880020020210E0018BF3165FFFF08
+:1019800002002021022028218FBF00188FB10014EF
+:101990008FB000100A00196527BD00200A001A2820
+:1019A0000000482102002021012030210E0018BF34
+:1019B0003165FFFF978700608F890064A780006012
+:1019C000012780230A001A3FAF900064948C0080A6
+:1019D000241F8000019F3024A4860080908B00800B
+:1019E000908F0080316700FF0007C9C20019C0272F
+:1019F000001871C031ED007F01AE2825A085008060
+:101A00000A001A10020020219385006C24030001B3
+:101A100027BDFFE800A330042CA20020AFB00010C7
+:101A2000AFBF001400C01821104000132410FFFEA7
+:101A30003C0708008CE7319000E610243C08800049
+:101A40003505018014400005240600848F89003C80
+:101A5000240A00042410FFFFA12A00FC0E001940F4
+:101A600000000000020010218FBF00148FB0001092
+:101A700003E0000827BD00183C0608008CC631941E
+:101A80000A001A8800C310248F87004827BDFFE092
+:101A9000AFB20018AFB10014AFB00010AFBF001C60
+:101AA00030D000FF90E6000D00A08821008090213A
+:101AB00030C5007FA0E5000D8F85003C8E23001807
+:101AC0008CA200D01062002E240A000E0E001A7B99
+:101AD000A38A006C2409FFFF104900222404FFFFA1
+:101AE00052000020000020218E2600003C0C001037
+:101AF00000CC5824156000393C0E000800CE682444
+:101B000055A0003F024020213C18000200D880244C
+:101B10001200001F3C0A00048F8700488CE200146A
+:101B20008CE300108CE500140043F82303E5C82B78
+:101B300013200005024020218E24002C8CF100107F
+:101B4000109100310240202124020012A382006C77
+:101B50000E001A7B2412FFFF105200022404FFFF24
+:101B6000000020218FBF001C8FB200188FB100141D
+:101B70008FB000100080102103E0000827BD002076
+:101B800090A800D4350400200A001AB1A0A400D403
+:101B900000CA48241520000B8F8B00488F8D004809
+:101BA0008DAC00101580000B024020218E2E002CE1
+:101BB00051C0FFEC00002021024020210A001ACC75
+:101BC000240200178D66001050C0FFE6000020219F
+:101BD000024020210A001ACC2402001102402021D8
+:101BE000240200150E001A7BA382006C240FFFFF55
+:101BF000104FFFDC2404FFFF0A001ABB8E260000F2
+:101C00000A001AF2240200143C08000400C8382418
+:101C100050E0FFD400002021024020210A001ACC0D
+:101C2000240200138F85003C27BDFFD8AFB3001CF2
+:101C3000AFB20018AFB10014AFB00010AFBF0020BA
+:101C400090A700D48F9000502412FFFF34E2004090
+:101C500092060000A0A200D48E03001000809821FC
+:101C60001072000630D1003F2408000D0E001A7BD0
+:101C7000A388006C105200252404FFFF8F8A003CCB
+:101C80008E0900188D4400D0112400070260202125
+:101C9000240C000E0E001A7BA38C006C240BFFFF9B
+:101CA000104B001A2404FFFF240400201224000417
+:101CB0008F8D003C91AF00D435EE0020A1AE00D452
+:101CC0008F85005810A00019000000001224004A5F
+:101CD0008F98003C8F92FCC0971000809651000AAC
+:101CE000523000488F9300443C1F08008FFF318C16
+:101CF00003E5C82B1720001E0260202100002821C8
+:101D00000E0019DA24060001000020218FBF0020F8
+:101D10008FB3001C8FB200188FB100148FB0001069
+:101D20000080102103E0000827BD00285224002A6B
+:101D30008E0500148F84003C948A008025490001A0
+:101D4000A4890080948800803C0208008C4231887D
+:101D500031077FFF10E2000E00000000026020212A
+:101D60000E001965240500010A001B3C000020211B
+:101D70002402002D0E001A7BA382006C2403FFFFB7
+:101D80001443FFE12404FFFF0A001B3D8FBF002026
+:101D900094990080241F800024050001033FC02483
+:101DA000A498008090920080908E0080325100FFB5
+:101DB000001181C200107827000F69C031CC007F6C
+:101DC000018D5825A08B00800E001965026020212E
+:101DD0000A001B3C000020212406FFFF54A6FFD66A
+:101DE0008F84003C026020210E001965240500014B
+:101DF0000A001B3C00002021026020210A001B5623
+:101E00002402000A2404FFFD0A001B3CAF93006477
+:101E10008F88003C27BDFFE8AFB00010AFBF0014B3
+:101E2000910A00D48F8700500080802135490040FE
+:101E30008CE60010A10900D43C0208008C4231B0AD
+:101E400030C53FFF00A2182B106000078F8500549B
+:101E5000240DFF8090AE000D01AE6024318B00FF99
+:101E6000156000080006C382020020212403000D33
+:101E70008FBF00148FB0001027BD00180A001A7B16
+:101E8000A383006C33060003240F000254CFFFF736
+:101E90000200202194A2001C8F85003C24190023FD
+:101EA000A4A200E88CE8000000081E02307F003F7A
+:101EB00013F900353C0A00838CE800188CA600D08A
+:101EC00011060008000000002405000E0E001A7B19
+:101ED000A385006C2407FFFF104700182404FFFFB0
+:101EE0008F85003C90A900D435240020A0A400D404
+:101EF0008F8C0048918E000D31CD007FA18D000D9B
+:101F00008F8300581060001C020020218F84005431
+:101F10008C9800100303782B11E0000D2419001891
+:101F200002002021A399006C0E001A7B2410FFFFF1
+:101F3000105000022404FFFF000020218FBF001476
+:101F40008FB000100080102103E0000827BD0018AA
+:101F50008C8600108F9F00480200202100C31023B0
+:101F6000AFE20010240500010E0019DA240600017A
+:101F70000A001BC8000020210E001965240500017D
+:101F80000A001BC800002021010A5824156AFFD945
+:101F90008F8C0048A0A600FC0A001BB5A386005E3B
+:101FA00030A500FF2406000124A9000100C9102B60
+:101FB0001040000C00004021240A000100A6182354
+:101FC000308B000124C60001006A3804000420425E
+:101FD0001160000200C9182B010740251460FFF8AA
+:101FE00000A6182303E000080100102127BDFFD838
+:101FF000AFB000188F900050AFB1001CAFBF0020F1
+:102000002403FFFF2411002FAFA30010920600004D
+:102010002405000826100001006620260E001BE1A2
+:10202000308400FF00021E003C021EDC34466F417B
+:102030000A001C090000102110A0000900801821CE
+:102040002445000130A2FFFF2C4500080461FFFA7F
+:10205000000320400086202614A0FFF900801821EC
+:102060000E001BE1240500208FA300102629FFFF8E
+:10207000313100FF00034202240700FF1627FFE270
+:102080000102182600035027AFAA0014AFAA0010BF
+:102090000000302127A8001027A7001400E67823AD
+:1020A00091ED000324CE000100C8602131C600FF7D
+:1020B0002CCB00041560FFF9A18D00008FA2001049
+:1020C0008FBF00208FB1001C8FB0001803E0000804
+:1020D00027BD002827BDFFD0AFB3001CAFB0001054
+:1020E000AFBF0028AFB50024AFB40020AFB20018D6
+:1020F000AFB100143C0C80008D880128240FFF80B4
+:102100003C06800A25100100250B0080020F682480
+:102110003205007F016F7024AD8E009000A628214B
+:10212000AD8D002490A600FC3169007F3C0A80043C
+:10213000012A1821A386005E9067007C0080982108
+:10214000AF83003430E20002AF880070AF85003CFE
+:1021500000A018211440000224040034240400309C
+:10216000A384004C8C7200DC30D100FF24040004F6
+:10217000AF92006412240004A380006C8E740004EB
+:102180001680001E3C0880009386005D30C7000169
+:1021900050E0000F8F8600648CA400848CA800841B
+:1021A0002413FF8000936024000C49403110007F0D
+:1021B000013078253C19200001F9682530DF00FE48
+:1021C0003C038000AC6D0830A39F005D8F860064E7
+:1021D0008FBF00288FB500248FB400208FB3001C60
+:1021E0008FB200188FB100148FB0001024020001CC
+:1021F00027BD003003E00008ACA600DC8E7F00089D
+:10220000950201208E67001003E2C8213326FFFFEC
+:1022100030D8000F33150001AF87003816A00058E2
+:10222000A398005C35090C000309382100D8182355
+:10223000AD030084AF8700688E6A00043148FFFF59
+:102240001100007EA78A006090AC00D42407FF80B4
+:1022500000EC302430CB00FF1560004B9786006007
+:10226000938E005E240D000230D5FFFF11CD02A237
+:102270000000A0218F85006402A5802B160000BC01
+:102280009388004C3C11800096240120310400FF0B
+:10229000148500888F8400688F98003833120003FB
+:1022A0005640008530A500FF8F900068310C00FF7C
+:1022B0002406003411860095AF900050920400046B
+:1022C000148001198F8E003CA38000408E0D000405
+:1022D0008DC800D83C0600FF34CCFFFF01AC302491
+:1022E0000106182B14600121AF8600588F87006407
+:1022F00097980060AF8700440307402310C000C7D1
+:10230000A78800608F91003430C300030003582376
+:10231000922A007C3171000302261021000A2082DB
+:10232000309200010012488000492821311FFFFF30
+:1023300003E5C82B132001208F88003C8F850038CF
+:102340008F8800681105025A3C0E3F018E0600007E
+:102350003C0C250000CE682411AC01638F84005032
+:1023600030E500FF0E00187B000030218F88003C14
+:102370008F8700648F8500380A001DE88F8600581B
+:102380000A001C87AF87006890AC00D400EC2024C2
+:10239000309000FF120000169386005D90B5008813
+:1023A00090B400D724A8008832A2003F2446FFE062
+:1023B0002CD10020A39400401220000CAF880050C4
+:1023C000240E000100CE2004308A00191540012B94
+:1023D0003C06800034D80002009858241560022E74
+:1023E0003092002016400234000000009386005D09
+:1023F00030CE000111C0000F978800608CA90084C6
+:102400008CAF00842410FF800130C82400191940CB
+:1024100031ED007F006D38253C1F200000FF902526
+:1024200030CB00FE3C188000AF120830A38B005D5B
+:10243000978800601500FF84000000008E63002074
+:10244000306C00041180FF519386005D2404FFFB73
+:10245000006430243C038000AE66002034660180B6
+:102460008C7301B80660FFFE8F8E0070346A010025
+:102470003C150001ACCE00008C620124240760856D
+:10248000ACC200048D54000402958824522000013F
+:1024900024076083241200023C1810003C0B8000CB
+:1024A000A4C70008A0D2000BAD7801B80A001C5CDC
+:1024B0009386005D30A500FF0E00187B2406000106
+:1024C0008F8800703C05800034A90900250201882E
+:1024D0009388004C304A0007304B00783C03408022
+:1024E0002407FF800163C825014980210047F824A3
+:1024F000310C00FF24060034ACBF0800AF90005040
+:10250000ACB908105586FF6E920400048F84003C1D
+:102510008E110030908E00D431CD001015A0001027
+:102520008F8300642C6F000515E000E400000000BC
+:10253000909800D42465FFFC331200101640000868
+:1025400030A400FF8F9F00688F99003813F90004B2
+:102550003887000130E20001144001C8000000008B
+:102560000E001BF4000000000A001E2900000000FD
+:102570008F84006830C500FF0E00187B2406000120
+:10258000938E004C240A003411CA00A08F85003CB1
+:102590008F860064978300603062FFFF00C288234B
+:1025A000AF910064A78000601280FF900280182124
+:1025B0002414FFFD5474FFA28E6300208E69000472
+:1025C0002403FFBF240BFFEF0135C823AE790004BD
+:1025D00090AF00D431ED007FA0AD00D48E66002016
+:1025E0008F98003CA780006034DF0002AE7F00209F
+:1025F000A70000BC931200D402434024A30800D4D7
+:102600008F95003CAEA000EC92AE00D401CB5024DC
+:10261000A2AA00D40A001D088F85003C8F910038C3
+:10262000AF80006402275821AF8B003800002021C2
+:102630002403FFFF108301B48F85003C8E0C001033
+:102640003C0D08008DAD31B09208000031843FFF91
+:10265000008D802B12000023310D003F3C19080033
+:102660008F3931A88F9F0070000479802408FF8083
+:10267000033F2021008FC8219385005D0328F824A3
+:102680003C0600803C0F800034D80001001F9140C0
+:102690003331007F8F86003C0251502535EE0940D2
+:1026A000332B0078333000073C0310003C02800CD1
+:1026B00001789025020E48210143C02502223821CD
+:1026C00034AE0001ADFF0804AF890054ADF2081428
+:1026D000AF870048ADFF0028ACD90084ADF80830C2
+:1026E000A38E005D9383005E2407000350670028DB
+:1026F00025A3FFE0240C0001146CFFAB8F85003C88
+:102700002411002311B10084000000002402000BFA
+:10271000026020210E001A7BA382006C0040A021E1
+:102720000A001D638F85003C02602021240B000CF1
+:102730000E001A7BA38B006C240AFFFF104AFFBC1B
+:102740002404FFFF8F8E003CA38000408E0D000408
+:102750008DC800D83C0600FF34CCFFFF01AC30240C
+:102760000106182B1060FEE1AF86005802602021A0
+:10277000241200190E001A7BA392006C240FFFFF95
+:10278000104FFFAB2404FFFF0A001CB48F860058D3
+:102790002C7400201280FFDE2402000B000328802E
+:1027A0003C1108012631955400B148218D2D0000BF
+:1027B00001A00008000000008F85003800A710214C
+:1027C00093850040AF82003802251821A383004082
+:1027D000951F00BC0226282137F91000A51900BC5E
+:1027E0005240FF92AF850064246A0004A38A00402F
+:1027F000950900BC24A40004AF8400643532200095
+:10280000A51200BC0A001D85000020218F860064EF
+:102810002CCB00051560FF60978300603072FFFFCE
+:1028200000D240232D18000513000003306400FF80
+:1028300024DFFFFC33E400FF8F8500688F860038BB
+:1028400010A60004388F000131ED000115A00138F9
+:10285000000000008F84003C908C00D4358700106D
+:10286000A08700D48F85003C8F860064978300602A
+:10287000ACA000EC0A001D603062FFFF8CAA00844F
+:102880008CB500843C0410000147102400028940EC
+:1028900032B4007F0234302500C460253C0880003B
+:1028A0002405000102602021240600010E0019DA2F
+:1028B000AD0C08300A001CF48F85003C8C8200ECC3
+:1028C0001222FE7E0260202124090005A389006CEB
+:1028D0000E001A7B2411FFFF1451FE782404FFFF21
+:1028E0000A001D862403FFFF8F8F00508F88003C55
+:1028F0008DF80000AD1800888DE70010AD07009836
+:102900008F8700640A001DE88F8600582407FFFFA8
+:1029100011870005000000000E001B7D02602021D1
+:102920000A001DC10040A0210E001B0202602021F0
+:102930000A001DC10040A0218F9000503C090800F2
+:102940008D2931B08E11001032323FFF0249682BC1
+:1029500011A0000C240AFF808F85005490AE000D5A
+:10296000014E1024304C00FF11800007026020212E
+:102970000011C38233030003240B0001106B010517
+:1029800000000000026020212418000D0E001A7BB8
+:10299000A398006C004020218F85003C0A001D6335
+:1029A0000080A0218F9000503C0A08008D4A31B071
+:1029B0008F8500548E0400100000A0218CB10014FB
+:1029C00030823FFF004A602B8CB200205180FFEE26
+:1029D0000260202190B8000D240BFF800178702444
+:1029E00031C300FF5060FFE80260202100044382F1
+:1029F0003106000314C0FFE40260202194BF001CD4
+:102A00008F99003C8E060028A73F00E88CAF00108D
+:102A1000022F202314C40139026020218F83005823
+:102A200000C36821022D382B14E001352402001860
+:102A30008F8A00488F820034024390218D4B001012
+:102A400001637023AD4E0010AD5200208C4C007419
+:102A50000192282B14A00156026020218F8400547B
+:102A60008E0800248C8600241106000702602021B5
+:102A70002419001C0E001A7BA399006C240FFFFF81
+:102A8000104FFFC52404FFFF8F8400488C8700246B
+:102A900024FF0001AC9F0024125101338F8D0034BC
+:102AA0008DB10074123201303C0B00808E0E00009C
+:102AB00001CB502415400075000000008E03001467
+:102AC0002411FFFF10710006026020212418001B52
+:102AD0000E001A7BA398006C1051FFAF2404FFFF77
+:102AE0008E0300003C0800010068302410C0001371
+:102AF0003C0400800064A024168000090200282104
+:102B0000026020212419001A0E001A7BA399006C80
+:102B1000240FFFFF104FFFA02404FFFF0200282115
+:102B2000026020210E001A9B240600012410FFFFE2
+:102B30001050FF992404FFFF241400018F9F0048C8
+:102B4000026020210280302197F100342405000129
+:102B500026270001A7E700340E0019DA0000000064
+:102B6000000020218F85003C0A001D630080A02109
+:102B70008F9000503C1408008E9431B08E070010E6
+:102B800030E83FFF0114302B10C000618F860054E5
+:102B9000241FFF8090C5000D03E52024309200FF24
+:102BA0005240005C026020218F8D005811A0000768
+:102BB00000078B828F85003C8F89FCC094AF00801A
+:102BC0009539000A132F00F68F870044322C00033A
+:102BD000158000630000000092020002104000D740
+:102BE000000000008E0A0024154000D80260202159
+:102BF0009204000324060002308800FF1506000539
+:102C0000308500FF8F940058528000F2026020212E
+:102C1000308500FF38AD00102DA400012CBF00014D
+:102C200003E43025020028210E001A9B02602021B7
+:102C30002410FFFF105000BE8F85003C8F8300588A
+:102C4000106000C4240500013C1908008F39318C44
+:102C50000323782B15E000B12409002D0260202108
+:102C6000000028210E0019DA240600018F85003C9F
+:102C7000000018210A001D630060A0210E0018A6A4
+:102C8000000000000A001E2900000000AC800020A7
+:102C90000A001EA98E0300140000282102602021D2
+:102CA0000E0019DA240600010A001CF48F85003C8E
+:102CB0000A001DE88F88003C8CB000848CB9008429
+:102CC0003C0310000207482400096940332F007FAD
+:102CD00001AFF82503E32825ACC5083091070001B2
+:102CE00024050001026020210E0019DA30E60001FF
+:102CF0000A001CF48F85003C938F004C2403FFFDD9
+:102D00000A001D65AF8F00640A001D652403FFFFE4
+:102D1000026020212410000D0E001A7BA390006C8D
+:102D2000004018218F85003C0A001D630060A0212F
+:102D30000E0018A600000000978300608F860064D4
+:102D40003070FFFF00D048232D3900051320FE12FC
+:102D50008F85003CACA200EC0A001D603062FFFFD2
+:102D600090C3000D307800085700FFA292040003C2
+:102D700002602021240200100E001A7BA382006C46
+:102D80002403FFFF5443FF9B920400030A001F43E8
+:102D90008F85003C90A8000D3106000810C00095FA
+:102DA0008F9400581680009E026020218E0F000C28
+:102DB0008CA4002055E40005026020218E1F00082D
+:102DC0008CB9002413F9003A02602021240200206B
+:102DD0000E001A7BA382006C2405FFFF1045FEEE57
+:102DE0002404FFFF8F8F0048240CFFF72403FF808B
+:102DF00091E9000D3C14800E3C0B8000012CC8248E
+:102E0000A1F9000D8F8F00343C0708008CE731AC2E
+:102E10008F8D007095E500788F99004800ED902126
+:102E200030BF7FFF001F20400244302130C8007FA8
+:102E300000C3C02401147021AD78002CA5D100007E
+:102E40008F2A002825420001AF2200288F29002C5C
+:102E50008E0C002C012C6821AF2D002C8E07002C2D
+:102E6000AF2700308E050014AF250034973F003A9D
+:102E700027E40001A724003A95F200783C100800EE
+:102E80008E1031B02643000130717FFF1230005C9C
+:102E9000006030218F83003402602021240500016E
+:102EA0000E001965A46600780A001ED200002021D9
+:102EB0008E0700142412FFFF10F200638F8C003C79
+:102EC0008E0900188D8D00D0152D005D0260202127
+:102ED0008E0A00248CA200281142005324020021F3
+:102EE0000E001A7BA382006C1452FFBE2404FFFF65
+:102EF0008F85003C0A001D630080A0212402001F72
+:102F00000E001A7BA382006C2409FFFF1049FEA269
+:102F10002404FFFF0A001E858F83005802602021D1
+:102F20000E001A7BA389006C1450FF518F85003C62
+:102F30002403FFFF0A001D630060A0218CCE002443
+:102F40008E0B0024116EFF2A026020210A001F57F9
+:102F50002402000F0E001965026020218F85003CBD
+:102F60000A001F16000018218E0900003C05008091
+:102F7000012590241640FF452402001A02602021FA
+:102F80000E001A7BA382006C240CFFFF144CFECBB6
+:102F90002404FFFF8F85003C0A001D630080A021F0
+:102FA0002403FFFD0060A0210A001D63AF870064B9
+:102FB0002418001D0E001A7BA398006C2403FFFF49
+:102FC0001443FEA62404FFFF8F85003C0A001D6306
+:102FD0000080A0212412002C0E001A7BA392006C0A
+:102FE0002403FFFF1043FF508F85003C0A001EFDA5
+:102FF00092040003026020210A001F6D24020024B5
+:10300000240B8000006B702431CAFFFF000A13C23A
+:10301000305100FF001180270A001F9E001033C0AE
+:103020000A001F6D240200278E0600288CAE002C9B
+:1030300010CE0008026020210A001FB12402001FE8
+:103040000A001FB12402000E026020210A001FB1F5
+:10305000240200258E04002C1080000D8F83003484
+:103060008C7800740304582B5560000C02602021FA
+:103070008CA800140086A0210114302B10C0FF5A28
+:103080008F8F0048026020210A001FB12402002215
+:10309000026020210A001FB1240200230A001FB190
+:1030A0002402002627BDFFD8AFB3001CAFB1001427
+:1030B000AFBF0020AFB20018AFB000103C028000DC
+:1030C0008C5201408C4B01483C048000000B8C0268
+:1030D000322300FF317300FF8C8501B804A0FFFE8E
+:1030E00034900180AE1200008C8701442464FFF00C
+:1030F000240600022C830013AE070004A61100086A
+:10310000A206000BAE1300241060004F8FBF0020FA
+:10311000000448803C0A0801254A95D4012A402130
+:103120008D04000000800008000000003C0308003F
+:103130008C6331A831693FFF0009998000728021BA
+:10314000021370212405FF80264D0100264C0080CB
+:103150003C02800031B1007F3198007F31CA007F8E
+:103160003C1F800A3C1980043C0F800C01C52024C0
+:1031700001A5302401853824014F1821AC460024D4
+:10318000023F402103194821AC470090AC4400287D
+:10319000AF830048AF88003CAF8900340E0019317E
+:1031A000016080213C0380008C6B01B80560FFFE4C
+:1031B0008F8700488F86003C3465018090E8000DC1
+:1031C000ACB20000A4B000060008260000041603FC
+:1031D00000029027001227C21080008124C20088BC
+:1031E000241F6082A4BF0008A0A0000524020002E2
+:1031F000A0A2000B8F8B0034000424003C082700A1
+:1032000000889025ACB20010ACA00014ACA0002443
+:10321000ACA00028ACA0002C8D6900382413FF80DE
+:10322000ACA9001890E3000D02638024320500FF72
+:1032300010A000058FBF002090ED000D31AC007F85
+:10324000A0EC000D8FBF00208FB3001C8FB20018C0
+:103250008FB100148FB000103C0A10003C0E8000AB
+:1032600027BD002803E00008ADCA01B8265F0100B1
+:103270002405FF8033F8007F3C06800003E57824B6
+:103280003C19800A03192021ACCF0024908E00D471
+:1032900000AE682431AC00FF11800024AF84003CF4
+:1032A000248E008895CD00123C0C08008D8C31A82E
+:1032B00031AB3FFF01924821000B5180012A402190
+:1032C00001052024ACC400283107007F3C06800C97
+:1032D00000E620219083000D00A31024304500FF5C
+:1032E00010A0FFD8AF8400489098000D330F001055
+:1032F00015E0FFD58FBF00200E001931000000003F
+:103300003C0380008C7901B80720FFFE000000001C
+:10331000AE1200008C7F0144AE1F0004A61100080D
+:1033200024110002A211000BAE1300243C1308016B
+:1033300092739790327000015200FFC38FBF00203C
+:103340000E00216E024020210A00208B8FBF00203A
+:103350003C1260008E452C083C03F0033462FFFFF2
+:1033600000A2F824AE5F2C088E582C083C1901C02E
+:1033700003199825AE532C080A00208B8FBF00201C
+:10338000264D010031AF007F3C10800A240EFF80E3
+:1033900001F0282101AE60243C0B8000AD6C0024BC
+:1033A0001660FFA8AF85003C24110003A0B100FC0B
+:1033B0000A00208B8FBF002026480100310A007FC1
+:1033C0003C0B800A2409FF80014B30210109202495
+:1033D0003C078000ACE400240A00208AAF86003C51
+:1033E000944E0012320C3FFF31CD3FFF15ACFF7DF4
+:1033F000241F608290D900D42418FF8003197824F8
+:1034000031EA00FF1140FF770000000024070004AC
+:10341000A0C700FC8F870048241160842406000D9B
+:10342000A4B10008A0A600050A002075240200022D
+:103430003C0400012484977C24030014240200FE31
+:103440003C010800AC2431EC3C010800AC2331E81D
+:103450003C010801A42297983C0408012484979811
+:103460000000182100643021A0C30004246300017F
+:103470002C6500FF54A0FFFC006430213C070800CD
+:1034800024E7010003E00008AF87007C00A058217A
+:10349000008048210000102114A0001200005021DB
+:1034A0000A00216A000000003C010801A42097984E
+:1034B0003C05080194A597988F82007C3C0C08017C
+:1034C000258C979800E2182100AC2021014B302B6D
+:1034D000A089000400001021A460000810C0003979
+:1034E000010048218F86007C0009384000E9402116
+:1034F0000008388000E6282190A8000B90B9000A47
+:103500000008204000881021000218800066C021B9
+:10351000A319000A8F85007C00E5782191EE000A4E
+:1035200091E6000B000E684001AE6021000C208087
+:1035300000851021A046000B3C0308019063979280
+:10354000106000222462FFFF8F83003C3C010801D1
+:10355000A0229792906C00FF1180000400000000F0
+:10356000906E00FF25CDFFFFA06D00FF3C19080104
+:1035700097399798272300013078FFFF2F0F00FF1E
+:1035800011E0FFC9254A00013C010801A4239798D6
+:103590003C05080194A597988F82007C3C0C08019B
+:1035A000258C979800E2182100AC2021014B302B8C
+:1035B000A089000400001021A460000814C0FFC905
+:1035C0000100482103E000080000000003E00008BB
+:1035D0002402000227BDFFE0248501002407FF80AC
+:1035E000AFB00010AFBF0018AFB1001400A718248F
+:1035F0003C10800030A4007F3C06800A0086282111
+:103600008E110024AE03002490A200FF1440000895
+:10361000AF85003CA0A000098FBF0018AE110024A8
+:103620008FB100148FB0001003E0000827BD002008
+:1036300090A900FD90A800FF312400FF0E00211C7E
+:10364000310500FF8F85003C8FBF0018A0A0000946
+:10365000AE1100248FB100148FB0001003E00008F9
+:1036600027BD002027BDFFD0AFB20020AFB1001CA6
+:10367000AFB00018AFBF002CAFB40028AFB3002428
+:103680003C0980009533011635320C00952F011A44
+:103690003271FFFF023280218E08000431EEFFFFFD
+:1036A000248B0100010E6821240CFF8025A5FFFF5B
+:1036B000016C50243166007F3C07800AAD2A00244B
+:1036C00000C73021AF850078AF8800743C01080145
+:1036D000A020979190C300090200D021008098217A
+:1036E000306300FF2862000510400048AF86003CB0
+:1036F000286400021480008E24140001240D0005AB
+:103700003C010801A02D977590CC00FD3C010801FB
+:10371000A02097763C010801A020977790CB000A63
+:10372000240AFF80318500FF014B4824312700FF28
+:1037300010E0000C000058213C1280083651008037
+:103740008E2F00308CD0005C01F0702305C0018EFC
+:103750008F87007490D4000A3284007FA0C4000ACE
+:103760008F86003C3C118008363000808E0F003080
+:103770008F87007400EF702319C000EE0000000076
+:1037800090D4000924120002328400FF10920247F4
+:10379000000000008CC2005800E2F82327F9FFFF68
+:1037A0001B2001300000000090C50009240800041F
+:1037B00030A300FF10680057240A00013C010801F3
+:1037C000A02A977590C900FF252700013C01080138
+:1037D000A02797743C0308019063977524060005A1
+:1037E0001066006A2C780005130000C400009021C8
+:1037F0000003F8803C0408012484962003E4C821D7
+:103800008F25000000A0000800000000241800FF21
+:103810001078005C0000000090CC000A90CA0009FB
+:103820003C080801910897913187008000EA4825FB
+:103830003C010801A029977C90C500FD3C140801BB
+:1038400092949792311100013C010801A025977DC7
+:1038500090DF00FE3C010801A03F977E90D200FF60
+:103860003C010801A032977F8CD900543C0108012B
+:10387000AC3997808CD000583C010801AC3097845B
+:103880008CC3005C3C010801AC34978C3C010801FE
+:10389000AC239788162000088FBF002C8FB4002817
+:1038A0008FB300248FB200208FB1001C8FB000189E
+:1038B00003E0000827BD00303C1180009624010E73
+:1038C0000E000FD43094FFFF3C0B08018D6B9794D2
+:1038D0000260382102802821AE2B01803C130801B0
+:1038E0008E73977401602021240600830E00102F30
+:1038F000AFB300108FBF002C8FB400288FB300240B
+:103900008FB200208FB1001C8FB0001803E00008B8
+:1039100027BD00303C1808008F1831FC270F00012C
+:103920003C010800AC2F31FC0A0021FF0000000020
+:103930001474FFB900000000A0C000FF3C0508009F
+:103940008CA531E43C0308008C6331E03C020800A4
+:103950008C4232048F99003C34A80001241F0002DD
+:103960003C010801AC2397943C010801A0289790E2
+:103970003C010801A0229793A33F00090A0021B847
+:103980008F86003C0E00216E000000000A0021FF1F
+:103990008F86003C3C1F080193FF97742419000197
+:1039A00013F902298F8700743C1008019210977850
+:1039B0003C06080190C6977610C000050200A021C1
+:1039C0003C04080190849779109001E48F87007C73
+:1039D000001088408F9F007C023048210009C88079
+:1039E000033F702195D80008270F0001A5CF0008DC
+:1039F0003C040801908497793C05080190A59776CE
+:103A00000E00211C000000008F87007C0230202166
+:103A10000004308000C720218C8500048F8200784C
+:103A200000A2402305020006AC8200048C8A00003C
+:103A30008F830074014310235C400001AC830000BD
+:103A40008F86003C90CB00FF2D6C00025580002D2E
+:103A5000241400010230F821001F408001072821B2
+:103A600090B9000B8CAE00040019C04003197821F6
+:103A7000000F1880006710218C4D000001AE8823D4
+:103A80002630FFFF5E00001F241400018C44000458
+:103A90008CAA0000008A482319200019240E000473
+:103AA0003C010801A02E977590AD000B8CAB000473
+:103AB000000D8840022D8021001010800047102149
+:103AC0008C440004016460230582020094430008D2
+:103AD00090DF00FE90B9000B33E500FF54B90004FD
+:103AE0000107A021A0D400FE8F87007C0107A02140
+:103AF0009284000B0E00211C240500018F86003CDF
+:103B000024140001125400962E50000116000042A9
+:103B10003C08FFFF241900021659FF3F0000000077
+:103B2000A0C000FF8F86003CA0D200090A0021FF40
+:103B30008F86003C90C700092404000230E300FF98
+:103B40001064016F24090004106901528F88007805
+:103B50008CCE0054010E682325B1000106200175AA
+:103B6000241800043C010801A03897753C010801A5
+:103B7000A020977490D400FD90D200FF2E4F000239
+:103B800015E0FF14328400FF000438408F89007C68
+:103B900090DF00FF00E41021000220800089C8218E
+:103BA0002FE500029324000B14A0FF0A2407000253
+:103BB0000004184000648021001058800169282109
+:103BC0008CAC0004010C50230540FF0200000000F3
+:103BD0003C0308019063977614600005246F000190
+:103BE0003C010801A02497793C010801A0279777A0
+:103BF0003C010801A02F977690CE00FF24E700013A
+:103C000031CD00FF01A7882B1220FFE990A4000B03
+:103C10000A0021EE000000003C0508018CA5977405
+:103C20003C12000400A8F82413F200062402000548
+:103C30003C09080191299775152000022402000310
+:103C4000240200053C010801A022979190C700FFC3
+:103C500014E0012024020002A0C200090A0021FF92
+:103C60008F86003C90CC00FF1180FEDA240A000110
+:103C70008F8C00788F89007C240F000301806821DD
+:103C80001160001E240E0002000540400105A02125
+:103C900000142080008990218E510004019180231E
+:103CA0000600FECC000000003C020801904297761E
+:103CB00014400005245800013C010801A02A977710
+:103CC0003C010801A02597793C010801A0389776AE
+:103CD00090DF00FF010510210002C88033E500FFDE
+:103CE000254A00010329202100AA402B1500FEB916
+:103CF0009085000B1560FFE5000540400005404041
+:103D000001051821000310803C010801A02A9774C6
+:103D10003C010801A0259778004918218C64000413
+:103D200000E4F82327F9FFFF1F20FFE9000000004F
+:103D30008C63000000E358230560013A01A3882347
+:103D400010E301170184C0231B00FEA20000000045
+:103D50003C010801A02E97750A00232D240B0001B9
+:103D6000240E0004A0CE00093C0D08008DAD31F8F2
+:103D70008F86003C25A200013C010800AC2231F8EE
+:103D80000A0021FF000000008CD9005C00F9C0236C
+:103D90001F00FE7B000000008CDF005C10FFFF6551
+:103DA0008F8400788CC3005C0083402325020001CF
+:103DB0001C40FF60000000008CC9005C24870001EB
+:103DC00000E9282B10A0FE943C0D80008DAB01046F
+:103DD0003C0C0001016C50241140FE8F24020010A5
+:103DE0003C010801A02297910A0021FF0000000079
+:103DF0008F9100788F86003C26220001ACC2005CC7
+:103E00000A0022BA241400018F87003C2404FF809A
+:103E10000000882190E9000A2414000101243025C3
+:103E2000A0E6000A3C05080190A597763C0408012D
+:103E3000908497790E00211C000000008F86003CC2
+:103E40008F85007C90C800FD310700FF00074040CF
+:103E50000107F821001FC0800305C8219323000B30
+:103E6000A0C300FD8F85007C8F86003C0305602188
+:103E7000918F000B000F704001CF6821000D8080F2
+:103E8000020510218C4B0000ACCB00548D84000443
+:103E90008F830078006450231940000224820001BF
+:103EA0002462000101074821ACC2005C0009308097
+:103EB00000C5402100E02021240500010E00211C46
+:103EC0009110000B8F86003C90C500FF10A0FF0CE6
+:103ED000001070408F85007C01D06821000D10809B
+:103EE000004558218D6400008F8C00780184502398
+:103EF0002547000104E0FF02263100013C030801D0
+:103F0000906397762E2F0002247800013C0108016F
+:103F1000A03897763C010801A034977711E0FEF8AD
+:103F2000020038210A00238D000740408F84003CA6
+:103F30008F8300788C85005800A340230502FE9AE9
+:103F4000AC8300580A002263000000003C0708010F
+:103F500090E79792240200FF10E200BE8F86003C9B
+:103F60003C1108019631979A3C0308012463979805
+:103F7000262500013230FFFF30ABFFFF0203602136
+:103F80002D6A00FF1540008D918700043C01080157
+:103F9000A420979A8F88003C0007484001272821D9
+:103FA000911800FF0005308024050001271400014E
+:103FB000A11400FF3C120801925297928F88007C56
+:103FC0008F8E0074264F000100C820213C0108019B
+:103FD000A02F9792AC8E00008F8D0078A4850008EA
+:103FE000AC8D00043C030801906397741460007763
+:103FF000000090213C010801A0259774A087000BC8
+:104000008F8C007C00CC5021A147000A8F82003C9D
+:10401000A04700FD8F84003CA08700FE8F86003CF7
+:104020008F9F0074ACDF00548F990078ACD9005892
+:104030008F8D007C0127C02100185880016DA021C0
+:10404000928F000A000F704001CF18210003888072
+:10405000022D8021A207000B8F86007C0166602163
+:10406000918A000B000A1040004A20210004288099
+:1040700000A64021A107000A3C07800834E900801F
+:104080008D2200308F86003CACC2005C0A0022BA50
+:104090002414000190CA00FF1540FEAD8F880078FF
+:1040A000A0C400090A0021FF8F86003CA0C000FDCB
+:1040B0008F98003C24060001A30000FE3C0108018B
+:1040C000A02697753C010801A02097740A0021EEF4
+:1040D0000000000090CB00FF3C04080190849793FF
+:1040E000316C00FF0184502B1540000F24020003A7
+:1040F00024020004A0C200090A0021FF8F86003CB0
+:1041000090C3000A2410FF8002035824316C00FF82
+:104110001180FDC1000000003C010801A02097753E
+:104120000A0021EE00000000A0C200090A0021FFE1
+:104130008F86003C90D4000A2412FF800254482449
+:10414000312800FF1500FFF4240200083C0108019B
+:10415000A02297910A0021FF000000000010884073
+:104160008F8B0074023018210003688001A7202182
+:10417000AC8B00008F8A0078240C0001A48C00080E
+:10418000AC8A00043C05080190A597762402000142
+:1041900010A2FE1E24A5FFFF0A0022799084000BC6
+:1041A0000184A0231A80FD8B000000003C0108015F
+:1041B000A02E97750A00232D240B00013C01080155
+:1041C000A425979A0A0023DF8F88003C240B000166
+:1041D000106B00228F98003C8F85003C90BF00FF41
+:1041E00033F900FF1079002B000000003C1F08018C
+:1041F00093FF9778001FC840033FC0210018A0809C
+:104200000288782191EE000AA08E000A8F8D007C32
+:104210003C0308019063977800CD88210A002405AB
+:10422000A223000B263000010600003101A49023D8
+:104230000640002B240200033C010801A02F9775C3
+:104240000A00232D240B00018F89003C0A00226301
+:10425000AD2700540A0022B924120001931400FD76
+:10426000A094000B8F88003C8F8F007C910E00FE85
+:1042700000CF6821A1AE000A8F91003CA22700FD6B
+:104280008F8300748F90003CAE0300540A00240614
+:104290008F8D007C90B000FEA090000A8F8B003CB8
+:1042A0008F8C007C916A00FD00CC1021A04A000B8D
+:1042B0008F84003CA08700FE8F8600788F85003CAD
+:1042C000ACA600580A0024068F8D007C94B8000824
+:1042D000ACA40004030378210A0022ADA4AF0008B7
+:1042E0003C010801A02297750A0021EE00000000A1
+:1042F00090CF0009240D000431EE00FF11CDFD85A3
+:10430000240200013C010801A02297750A0021EE59
+:0443100000000000A9
+:0C43140008003344080033440800342043
+:10432000080033F4080033D8080033280800332885
+:10433000080033280800334C800801008008008002
+:10434000800800005F865437E4AC62CC50103A45D8
+:1043500036621985BF14C0E81BC27A1E84F4B556B4
+:10436000094EA6FE7DDA01E7C04D748108005B3876
+:1043700008005B7C08005B2008005B2008005B20D5
+:1043800008005B2008005B3808005B2008005B2009
+:1043900008005B8408005B2008005A9808005B2036
+:1043A00008005B2008005B8408005B2008005B209D
+:1043B00008005B2008005B2008005B2008005B20F1
+:1043C00008005B2008005B2008005B2008005B20E1
+:1043D00008005B5808005B2008005B5808005B2061
+:1043E00008005B2008005B2008005B5C08005B584D
+:1043F00008005B2008005B2008005B2008005B20B1
+:1044000008005B2008005B2008005B2008005B20A0
+:1044100008005B2008005B2008005B2008005B2090
+:1044200008005B2008005B2008005B2008005B2080
+:1044300008005B2008005B2008005B2008005B2070
+:1044400008005B5C08005B5C08005B2008005B5CAC
+:1044500008005B2008005B2008005B2008005B2050
+:1044600008005B2008005B2008005B2008005B2040
+:1044700008005B2008005B2008005B2008005B2030
+:1044800008005B2008005B2008005B2008005B2020
+:1044900008005B2008005B2008005B2008005B2010
+:1044A00008005B2008005B2008005B2008005B2000
+:1044B00008005B2008005B2008005B2008005B20F0
+:1044C00008005B2008005B2008005B2008005B20E0
+:1044D00008005B2008005B2008005B2008005B20D0
+:1044E00008005B2008005B2008005B2008005B20C0
+:1044F00008005B2008005B2008005B2008005B20B0
+:1045000008005B2008005B2008005B2008005B209F
+:1045100008005B2008005B2008005B2008005B208F
+:1045200008005B2008005B2008005B2008005B207F
+:1045300008005B2008005B2008005B2008005B206F
+:1045400008005B2008005B2008005B2008005B205F
+:1045500008005B2008005B2008005B2008005B204F
+:1045600008005B2008005B2008005B2008005BA0BF
+:10457000080078F008007B54080078FC080076F00A
+:10458000080078FC08007988080078FC080076F0BC
+:10459000080076F0080076F0080076F0080076F063
+:1045A000080076F0080076F0080076F0080076F053
+:1045B000080076F00800791C0800790C080076F0F5
+:1045C000080076F0080076F0080076F0080076F033
+:1045D000080076F0080076F0080076F0080076F023
+:1045E000080076F0080076F0080076F00800790CF4
+:1045F0000800839C08008228080083640800822841
+:1046000008008334080081100800822808008228EE
+:1046100008008228080082280800822808008228D2
+:1046200008008228080082280800822808008228C2
+:1046300008008228080082280800825008008DD4D3
+:1046400008008F3008008F100800897808008DEC72
+:104650000A00012400000000000000000000000D1E
+:10466000747061362E322E31000000000602010106
+:10467000000000000000000000000000000000003A
+:10468000000000000000000000000000000000002A
+:10469000000000000000000000000000000000001A
+:1046A000000000000000000000000000000000000A
+:1046B00000000000000000000000000000000000FA
+:1046C00000000000000000000000000000000000EA
+:1046D00000000000000000000000000000000000DA
+:1046E0000000000010000003000000000000000DAA
+:1046F0000000000D3C020800244217203C03080083
+:1047000024632A10AC4000000043202B1480FFFDDE
+:10471000244200043C1D080037BD2FFC03A0F021FB
+:104720003C100800261004903C1C0800279C172011
+:104730000E000262000000000000000D2402FF8055
+:1047400027BDFFE000821024AFB00010AF42002070
+:10475000AFBF0018AFB10014936500043084007F30
+:10476000034418213C0200080062182130A50020F3
+:10477000036080213C080111277B000814A000027F
+:104780002466005C246600589202000497430104EA
+:10479000920400043047000F3063FFFF3084004074
+:1047A00000672823108000090000482192020005BC
+:1047B00030420004104000050000000010A000037B
+:1047C0000000000024A5FFFC24090004920200055B
+:1047D00030420004104000120000000010A0001041
+:1047E000000000009602000200A7202101044025DD
+:1047F0002442FFFEA7421016920300042402FF8009
+:1048000000431024304200FF104000033C0204002B
+:104810000A000174010240258CC20000AF4210184A
+:104820008F4201780440FFFE2402000AA7420140A3
+:1048300096020002240400093042000700021023FF
+:1048400030420007A7420142960200022442FFFEC6
+:10485000A7420144A740014697420104A7420148EC
+:104860008F42010830420020504000012404000122
+:104870009202000430420010144000023483001001
+:1048800000801821A743014A00000000000000003A
+:104890000000000000000000AF4810000000000011
+:1048A0000000000000000000000000008F42100027
+:1048B0000441FFFE3102FFFF10400007000000002E
+:1048C0009202000430420040144000030000000047
+:1048D0008F421018ACC20000960200063042FFFF63
+:1048E00024420002000210430002104003628821AB
+:1048F000962200001120000D3044FFFF00A7102178
+:104900008F8300388F45101C000210820002108037
+:1049100000431021AC45000030A6FFFF0E00058DBE
+:1049200000052C0200402021A62200009203000472
+:104930002402FF8000431024304200FF1040001F7B
+:104940000000000092020005304200021040001BEF
+:10495000000000009742100C2442FFFEA7421016F0
+:10496000000000003C02040034420030AF4210005E
+:104970000000000000000000000000000000000037
+:104980008F4210000441FFFE000000009742100C0F
+:104990008F45101C3042FFFF24420030000210827D
+:1049A00000021080005B1021AC45000030A6FFFF24
+:1049B0000E00058D00052C02A622000096040002C0
+:1049C000248400080E0001E93084FFFF97440104AD
+:1049D0000E0001F73084FFFF8FBF00188FB1001465
+:1049E0008FB000103C02100027BD002003E000083B
+:1049F000AF4201783084FFFF308200078F850024AA
+:104A000010400002248300073064FFF800A4102146
+:104A100030421FFF03421821247B4000AF8500284D
+:104A2000AF82002403E00008AF4200843084FFFF1F
+:104A30003082000F8F85002C8F86003410400002DA
+:104A40002483000F3064FFF000A410210046182BCF
+:104A5000AF8500300046202314600002AF82002C96
+:104A6000AF84002C8F82002C340480000342182174
+:104A700000641821AF83003803E00008AF420080D3
+:104A80008F820014104000088F8200048F82FFDCA8
+:104A9000144000058F8200043C02FFBF3442FFFF38
+:104AA000008220248F82000430430006240200028A
+:104AB0001062000F3C0201012C620003504000050F
+:104AC000240200041060000F3C0200010A000230C2
+:104AD0000000000010620005240200061462000CB1
+:104AE0003C0201110A000229008210253C0200113B
+:104AF00000821025AF421000240200010A0002309B
+:104B0000AF82000C00821025AF421000AF80000C75
+:104B100000000000000000000000000003E00008AA
+:104B2000000000008F82000C104000040000000014
+:104B30008F4210000441FFFE0000000003E0000867
+:104B4000000000008F8200102443F800000231C2F0
+:104B500024C2FFF02C630301106000030002104226
+:104B60000A000257AC8200008F85001800C5102B88
+:104B70001440000B0000182100C510232447000139
+:104B80008F82001C00A210212442FFFF0046102B40
+:104B9000544000042402FFFF0A000257AC870000C3
+:104BA0002402FFFF0A000260AC8200008C82000039
+:104BB00000021940006218210003188000621821C9
+:104BC000000318803C0208002442175C0062182190
+:104BD00003E000080060102127BDFFD8AFBF002010
+:104BE000AFB1001CAFB000183C0460088C825000CC
+:104BF0002403FF7F3C066000004310243442380C3D
+:104C0000AC8250008CC24C1C3C1A80000002160280
+:104C10003042000F10400007AF82001C8CC34C1CB8
+:104C20003C02001F3442FC0000621824000319C239
+:104C3000AF8300188F420008275B40003442000118
+:104C4000AF420008AF8000243C02601CAF400080EF
+:104C5000AF4000848C4500088CC3080834028000F3
+:104C6000034220212402FFF0006218243C0200804D
+:104C70003C010800AC2204203C025709AF840038F4
+:104C800014620004AF850034240200010A0002927D
+:104C9000AF820014AF8000148F4200003842000140
+:104CA000304200011440FFFC8F82001410400016B7
+:104CB0000000000097420104104000058F830000AF
+:104CC000146000072462FFFF0A0002A72C62000A9A
+:104CD0002C620010504000048F8300002462000109
+:104CE000AF8200008F8300002C62000A1440000392
+:104CF0002C6200070A0002AEAF80FFDC1040000209
+:104D000024020001AF82FFDC8F4301088F440100C1
+:104D100030622000AF83000410400008AF84001010
+:104D20003C0208008C42042C244200013C01080093
+:104D3000AC22042C0A00058A3C02400030650200C7
+:104D400014A0000324020F001482026024020D004C
+:104D500097420104104002C83C024000306240000B
+:104D6000144000AD8F8200388C4400088F420178D7
+:104D70000440FFFE24020800AF420178240200082C
+:104D8000A7420140A7400142974201048F840004DA
+:104D90003051FFFF308200011040000702208021C7
+:104DA0002623FFFE240200023070FFFFA7420146C7
+:104DB0000A0002DBA7430148A74001463C02080065
+:104DC0008C42043C1440000D8F8300103082002080
+:104DD0001440000224030009240300010060202184
+:104DE0008F83001024020900506200013484000403
+:104DF000A744014A0A0002F60000000024020F0046
+:104E00001462000530820020144000062403000DC7
+:104E10000A0002F5240300051440000224030009DF
+:104E200024030001A743014A3C0208008C420420ED
+:104E30003C0400480E00020C004420250E00023500
+:104E4000000000008F82000C1040003E00000000B7
+:104E50008F4210003C030020004310241040003912
+:104E60008F82000430420002104000360000000033
+:104E700097421014144000330000000097421008BD
+:104E80008F8800383042FFFF24420006000218825B
+:104E90000003388000E83021304300018CC400005A
+:104EA00010600004304200030000000D0A000337C8
+:104EB00000E81021544000103084FFFF3C05FFFF44
+:104EC00000852024008518260003182B0004102BD1
+:104ED0000043102410400005000000000000000006
+:104EE0000000000D00000000240002228CC200001F
+:104EF0000A000336004520253883FFFF0003182BE6
+:104F00000004102B00431024104000050000000096
+:104F1000000000000000000D000000002400022B33
+:104F20008CC200003444FFFF00E81021AC440000B4
+:104F30003C0208008C420430244200013C0108007D
+:104F4000AC2204308F6200008F840038AF820008EA
+:104F50008C8300003402FFFF1462000F0000102158
+:104F60003C0508008CA504543C0408008C840450C3
+:104F700000B0282100B0302B0082202100862021A3
+:104F80003C010800AC2504543C010800AC2404504A
+:104F90000A000580240400088C82000030420100D1
+:104FA0001040000F000010213C0508008CA5044CA7
+:104FB0003C0408008C84044800B0282100B0302B49
+:104FC00000822021008620213C010800AC25044CF1
+:104FD0003C010800AC2404480A00058024040008B1
+:104FE0003C0508008CA504443C0408008C84044063
+:104FF00000B0282100B0302B008220210086202123
+:105000003C010800AC2504443C010800AC240440E9
+:105010000A000580240400088F6200088F620000E7
+:1050200000021602304300F0240200301062000536
+:1050300024020040106200E08F8200200A000588F0
+:105040002442000114A00005000000000000000040
+:105050000000000D00000000240002568F4201787D
+:105060000440FFFE000000000E00023D27A40010D7
+:105070001440000500408021000000000000000DE9
+:10508000000000002400025D8E02000010400005B8
+:1050900000000000000000000000000D0000000003
+:1050A000240002608F62000C04430003240200010C
+:1050B0000A00042EAE000000AE0200008F8200380D
+:1050C0008C480008A20000078F65000C8F64000464
+:1050D00030A3FFFF0004240200852023308200FF5C
+:1050E0000043102124420005000230832CC20081BD
+:1050F000A605000A14400005A204000400000000F8
+:105100000000000D00000000240002788F850038A8
+:105110000E0005AB260400148F6200048F430108C3
+:10512000A60200083C02100000621824106000086B
+:105130000000000097420104920300072442FFECA4
+:10514000346300023045FFFF0A0003C3A2030007D7
+:10515000974201042442FFF03045FFFF9606000805
+:105160002CC200135440000592030007920200076E
+:1051700034420001A202000792030007240200014A
+:1051800010620005240200031062000B8F820038B9
+:105190000A0003E030C6FFFF8F8200383C04FFFFA7
+:1051A0008C43000C0064182400651825AC43000CE7
+:1051B0000A0003E030C6FFFF3C04FFFF8C430010F1
+:1051C0000064182400651825AC43001030C6FFFFAA
+:1051D00024C2000200021083A20200058F8300385F
+:1051E000304200FF00021080004328218CA80000FC
+:1051F0008CA20000240300040002170214430012D2
+:1052000000000000974201043C03FFFF0103182443
+:105210003042FFFF004610232442FFFE006240257B
+:10522000ACA8000092030005306200FF000210806D
+:1052300000501021904200143042000F0043102112
+:105240000A000415A20200068CA40004974201047F
+:105250009603000A3088FFFF3042FFFF004610230C
+:105260002442FFD60002140001024025ACA800042D
+:1052700092020007920400052463002800031883AB
+:105280000064182134420004A2030006A2020007B1
+:105290008F8200042403FFFB3442000200431024E9
+:1052A000AF820004920300068F8700380003188045
+:1052B000007010218C4400203C02FFF63442FFFFB6
+:1052C0000082402400671821AE04000CAC68000C7A
+:1052D000920500063C03FF7F8E02000C000528802B
+:1052E00000B020213463FFFF01033024948800269E
+:1052F00000A7282100431024AE02000CAC86002039
+:10530000AC880024ACA8001024020010A742014081
+:1053100024020002A7400142A7400144A7420146DF
+:10532000974201043C0400082442FFFEA7420148C2
+:10533000240200010E00020CA742014A9603000A53
+:105340009202000400431021244200023042000770
+:1053500000021023304200070E000235AE0200109A
+:105360008F6200003C0308008C6304442404001096
+:10537000AF820008974201043042FFFF2442FFFE43
+:1053800000403821000237C33C0208008C42044030
+:10539000006718210067282B0046102100451021C6
+:1053A0003C010800AC2304443C010800AC2204404A
+:1053B0000A0005150000000014A000050000000010
+:1053C000000000000000000D000000002400030A9F
+:1053D0008F4201780440FFFE000000000E00023DF5
+:1053E00027A40014144000050040802100000000A4
+:1053F0000000000D00000000240003118E020000D8
+:105400005440000692020007000000000000000D5A
+:10541000000000002400031C920200073042000438
+:10542000104000058F8200042403FFFB3442000279
+:1054300000431024AF8200048F620004044300087C
+:1054400092020007920200068E03000CAE000000DC
+:105450000002108000501021AC430020920200078F
+:1054600030420004544000099602000A92020005EE
+:105470003C03000100021080005010218C460018EF
+:1054800000C33021AC4600189602000A92060004C0
+:10549000277100080220202100C2302124C6000507
+:1054A000260500140E0005AB0006308292040006AB
+:1054B0008F6500043C027FFF0004208000912021C2
+:1054C0008C8300043442FFFF00A2282400651821C9
+:1054D000AC830004920200079204000592030004CA
+:1054E000304200041040001496070008308400FF8A
+:1054F00000042080009120218C8600049742010442
+:105500009605000A306300FF3042FFFF0043102180
+:105510000045102130E3FFFF004310232442FFD851
+:1055200030C6FFFF0002140000C23025AC86000424
+:105530000A0004C992030007308500FF0005288097
+:1055400000B128218CA4000097420104306300FFC1
+:105550003042FFFF00431021004710233C03FFFFB0
+:10556000008320243042FFFF00822025ACA40000ED
+:1055700092030007240200011062000600000000F0
+:105580002402000310620011000000000A0004EC75
+:105590008E03001097420104920300049605000A4E
+:1055A0008E24000C00431021004510212442FFF2FC
+:1055B0003C03FFFF008320243042FFFF00822025B0
+:1055C000AE24000C0A0004EC8E0300109742010484
+:1055D000920300049605000A8E2400100043102157
+:1055E000004510212442FFEE3C03FFFF00832024EE
+:1055F0003042FFFF00822025AE2400108E030010F1
+:105600002402000AA7420140A74301429603000A70
+:10561000920200043C04004000431021A7420144D0
+:10562000A740014697420104A74201482402000115
+:105630000E00020CA742014A0E00023500000000D5
+:105640008F6200009203000400002021AF82000856
+:10565000974201049606000A3042FFFF00621821BB
+:10566000006028213C0308008C6304443C020800CD
+:105670008C42044000651821004410210065382B3D
+:10568000004710213C010800AC2304443C01080001
+:10569000AC22044092040004008620212484000AE5
+:1056A0003084FFFF0E0001E9000000009744010470
+:1056B0003084FFFF0E0001F7000000003C021000E4
+:1056C000AF4201780A0005878F82002014820027EC
+:1056D0003062000697420104104000673C0240001F
+:1056E0003062400010400005000000000000000093
+:1056F0000000000D00000000240004208F4201780B
+:105700000440FFFE24020800AF4201782402000892
+:10571000A7420140A74001428F8200049743010441
+:1057200030420001104000073070FFFF2603FFFEEB
+:1057300024020002A7420146A74301480A00053F90
+:105740002402000DA74001462402000DA742014A91
+:105750008F62000024040008AF8200080E0001E9F7
+:10576000000000000A00051902002021104000423C
+:105770003C02400093620000304300F0240200101D
+:105780001062000524020070106200358F82002034
+:105790000A000588244200018F620000974301043B
+:1057A0003050FFFF3071FFFF8F4201780440FFFE51
+:1057B0003202000700021023304200072403000ACF
+:1057C0002604FFFEA7430140A7420142A74401442B
+:1057D000A7400146A75101488F42010830420020EE
+:1057E000144000022403000924030001A743014AD6
+:1057F0000E00020C3C0400400E00023500000000C8
+:105800003C0708008CE70444021110212442FFFEEB
+:105810003C0608008CC604400040182100E33821F3
+:10582000000010218F65000000E3402B00C23021F2
+:105830002604000800C830213084FFFFAF8500082F
+:105840003C010800AC2704443C010800AC2604409D
+:105850000E0001E9000000000A00051902202021C5
+:105860000E00013B000000008F8200202442000156
+:10587000AF8200203C024000AF4201380A00029291
+:10588000000000003084FFFF30C6FFFF00052C0041
+:1058900000A628253882FFFF004510210045282B4F
+:1058A0000045102100021C023042FFFF004310217E
+:1058B00000021C023042FFFF004310213842FFFF6C
+:1058C00003E000083042FFFF3084FFFF30A5FFFFF8
+:1058D0000000182110800007000000003082000145
+:1058E0001040000200042042006518210A0005A1B2
+:1058F0000005284003E000080060102110C00006E9
+:1059000024C6FFFF8CA2000024A50004AC82000086
+:105910000A0005AB2484000403E000080000000036
+:1059200010A0000824A3FFFFAC86000000000000C8
+:10593000000000002402FFFF2463FFFF1462FFFA4F
+:0C5940002484000403E0000800000000C4
+:04594C000000000156
+:105950000A00002A00000000000000000000000D06
+:10596000747870362E322E310000000006020100DD
+:1059700000000000000001360000EA6000000000A6
+:105980000000000000000000000000000000000017
+:105990000000000000000000000000000000000007
+:1059A00000000000000000000000000000000000F7
+:1059B00000000016000000000000000000000000D1
+:1059C00000000000000000000000000000000000D7
+:1059D00000000000000000000000000000000000C7
+:1059E000000000000000000000001388000000001C
+:1059F000000005DC000000000000000010000003B3
+:105A0000000000000000000D0000000D3C02080036
+:105A100024423D883C0308002463403CAC40000025
+:105A20000043202B1480FFFD244200043C1D08008D
+:105A300037BD7FFC03A0F0213C100800261000A811
+:105A40003C1C0800279C3D880E00044E000000000E
+:105A50000000000D27BDFFB4AFA10000AFA20004FD
+:105A6000AFA30008AFA4000CAFA50010AFA60014B0
+:105A7000AFA70018AFA8001CAFA90020AFAA002450
+:105A8000AFAB0028AFAC002CAFAD0030AFAE0034F0
+:105A9000AFAF0038AFB8003CAFB90040AFBC004476
+:105AA000AFBF00480E000591000000008FBF004806
+:105AB0008FBC00448FB900408FB8003C8FAF0038D6
+:105AC0008FAE00348FAD00308FAC002C8FAB002830
+:105AD0008FAA00248FA900208FA8001C8FA7001870
+:105AE0008FA600148FA500108FA4000C8FA30008B0
+:105AF0008FA200048FA1000027BD004C3C1B600456
+:105B00008F7A5030377B502803400008AF7A00006E
+:105B10008F86003C3C0390003C02800000862825D4
+:105B200000A32025AC4400203C0380008C670020AB
+:105B300004E0FFFE0000000003E000080000000099
+:105B40000A000070240400018F85003C3C048000A2
+:105B50003483000100A3102503E00008AC8200207C
+:105B600003E00008000010213084FFFF30A5FFFF94
+:105B70001080000700001821308200011040000250
+:105B800000042042006518211480FFFB0005284016
+:105B900003E000080060102110C0000700000000B2
+:105BA0008CA2000024C6FFFF24A50004AC820000E4
+:105BB00014C0FFFB2484000403E000080000000080
+:105BC00010A0000824A3FFFFAC8600000000000026
+:105BD000000000002402FFFF2463FFFF1462FFFAAD
+:105BE0002484000403E000080000000090AA0031B3
+:105BF0008FAB00108CAC00403C0300FF8D680004AC
+:105C0000AD6C00208CAD004400E060213462FFFFE9
+:105C1000AD6D00248CA700483C09FF000109C02499
+:105C2000AD6700288CAE004C0182C824031978258A
+:105C3000AD6F0004AD6E002C8CAD0038314A00FF12
+:105C4000AD6D001C94A900323128FFFFAD68001033
+:105C500090A70030A5600002A1600004A1670000C9
+:105C600090A30032306200FF00021982106000052C
+:105C7000240500011065000E0000000003E000088C
+:105C8000A16A00018CD80028354A0080AD78001840
+:105C90008CCF0014AD6F00148CCE0030AD6E0008B8
+:105CA0008CC4002CA16A000103E00008AD64000C64
+:105CB0008CCD001CAD6D00188CC90014AD690014AA
+:105CC0008CC80024AD6800088CC70020AD67000CAC
+:105CD0008CC200148C8300700043C82B1320000773
+:105CE000000000008CC20014144CFFE4000000000F
+:105CF000354A008003E00008A16A00018C82007030
+:105D00000A0000E6000000009089003027BDFFF87F
+:105D10008FA8001CA3A900008FA300003C0DFF80EA
+:105D200035A2FFFF8CAC002C00625824AFAB000002
+:105D3000A100000400C05821A7A000028D060004A5
+:105D400000A048210167C8218FA5000000805021D4
+:105D50003C18FF7F032C20263C0E00FF2C8C0001FA
+:105D6000370FFFFF35CDFFFF3C02FF0000AFC82417
+:105D700000EDC02400C27824000C1DC00323682558
+:105D800001F87025AD0D0000AD0E00048D24002437
+:105D9000AFAD0000AD0400088D2C00202404FFFFEF
+:105DA000AD0C000C9547003230E6FFFFAD06001049
+:105DB0009145004830A200FF000219C25060000166
+:105DC0008D240034AD0400148D4700388FAA0018CC
+:105DD00027BD0008AD0B0028AD0A0024AD07001C4C
+:105DE000AD00002CAD00001803E00008AD0000205D
+:105DF00027BDFFE0AFB20018AFB10014AFB0001084
+:105E0000AFBF001C9098003000C088213C0D00FFFF
+:105E1000330F007FA0CF0000908E003135ACFFFF24
+:105E20003C0AFF00A0CE000194A6001EA2200004A0
+:105E30008CAB00148E29000400A08021016C282462
+:105E4000012A40240080902101052025A626000279
+:105E5000AE24000426050020262400080E0000922F
+:105E6000240600029247003026050028262400144C
+:105E700000071E000003160324060004044000036C
+:105E80002403FFFF965900323323FFFF0E000092D8
+:105E9000AE230010262400248FBF001C8FB20018F0
+:105EA0008FB100148FB000102405000300003021D2
+:105EB0000A00009C27BD002027BDFFD8AFB1001C01
+:105EC000AFB00018AFBF002090A90030240200013D
+:105ED00000E050213123003F00A040218FB000405E
+:105EE0000080882100C04821106200148FA700386C
+:105EF000240B000500A0202100C02821106B0013F6
+:105F0000020030210E000128000000009225007CD4
+:105F100030A400021080000326030030AE000030E1
+:105F2000260300348FBF00208FB1001C8FB00018F3
+:105F30000060102103E0000827BD00280E0000A724
+:105F4000AFB000100A00016F000000008FA3003CFA
+:105F5000010020210120282101403021AFA30010A1
+:105F60000E0000EEAFB000140A00016F0000000048
+:105F70003C06800034C20E008C4400108F85004423
+:105F8000ACA400208C43001803E00008ACA300245C
+:105F90003C06800034C20E008C4400148F850044FF
+:105FA000ACA400208C43001C03E00008ACA3002438
+:105FB0009382000C1040001B2483000F2404FFF088
+:105FC0000064382410E00019978B00109784000EAD
+:105FD0009389000D3C0A601C0A0001AC0164402357
+:105FE00001037021006428231126000231C2FFFF43
+:105FF00030A2FFFF0047302B50C0000E00E44821C4
+:106000008D4D000C31A3FFFF00036400000C2C0336
+:1060100004A1FFF30000302130637FFF0A0001A4D8
+:106020002406000103E00008000000009784000E31
+:1060300000E448213123FFFF3168FFFF0068382B5F
+:1060400054E0FFF8A783000E938A000D114000056D
+:10605000240F0001006BC023A380000D03E00008A3
+:10606000A798000E006BC023A38F000D03E000086B
+:10607000A798000E03E000080000000027BDFFE81D
+:10608000AFB000103C10800036030140308BFFFFA2
+:1060900093AA002BAFBF0014A46B000436040E00BB
+:1060A0009488001630C600FF8FA90030A46800064F
+:1060B000AC650008A0660012A46A001AAC67002054
+:1060C0008FA5002CA4690018012020210E00019842
+:1060D000AC6500143C021000AE0201788FBF0014C2
+:1060E0008FB0001003E0000827BD00188F85000066
+:1060F0002484000727BDFFF83084FFF83C068000A9
+:1061000094CB008A316AFFFFAFAA00008FA900007C
+:10611000012540232507FFFF30E31FFF0064102BFC
+:106120001440FFF700056882000D288034CC400041
+:1061300000AC102103E0000827BD00088F8200009A
+:106140002486000730C5FFF800A2182130641FFF25
+:1061500003E00008AF8400008F87003C8F84004478
+:1061600027BDFFB0AFB70044AFB40038AFB1002CCB
+:10617000AFBF0048AFB60040AFB5003CAFB300348E
+:10618000AFB20030AFB000283C0B80008C860024FA
+:10619000AD6700808C8A002035670E0035690100EC
+:1061A000ACEA00108C8800248D2500040000B82182
+:1061B000ACE800188CE3001000A688230000A021A2
+:1061C000ACE300148CE20018ACE2001C122000FECC
+:1061D00000E0B021936C0008118000F40000000082
+:1061E000976F001031EEFFFF022E682B15A000EF15
+:1061F00000000000977200103250FFFFAED0000088
+:106200003C0380008C740000329300081260FFFD94
+:106210000000000096D800088EC700043305FFFF79
+:1062200030B5000112A000E4000000000000000DE5
+:1062300030BFA0402419004013F9011B30B4A00066
+:10624000128000DF00000000937300081260000855
+:1062500000000000976D001031ACFFFF00EC202B18
+:106260001080000330AE004011C000D500000000D7
+:10627000A7850040AF8700389363000802202821DB
+:10628000AFB10020146000F527B40020AF60000C0F
+:10629000978F004031F140001620000224030016C1
+:1062A0002403000E24054007A363000AAF65001411
+:1062B000938A00428F70001431550001001512407E
+:1062C00002024825AF690014979F00408F780014A0
+:1062D00033F9001003194025AF680014979200406D
+:1062E0003247000810E0016E000000008F670014C4
+:1062F0003C1210003C11800000F27825AF6F0014B2
+:1063000036230E00946E000A3C0D81002406000E18
+:1063100031CCFFFF018D2025AF640004A36600028D
+:106320009373000A3406FFFC266B0004A36B000A7B
+:1063300097980040330820001100015F0000000022
+:106340003C05800034A90E00979900409538000C58
+:1063500097870040001940423312C0003103000308
+:1063600000127B0330F11000006F682500117203EA
+:1063700001AE6025000C20C0A76400129793004076
+:10638000936A000A001359823175003C02AA102159
+:106390002450003CA3700009953F000C33F93FFFE7
+:1063A000A779001097700012936900090130F82155
+:1063B00027E5000230B900070019C02333080007A1
+:1063C000A368000B9371000997720012976F001079
+:1063D000322700FF8F910038978D004000F218217E
+:1063E000006F702101C6602131A6004010C0000579
+:1063F0003185FFFF00B1102B3C12800010400017C8
+:10640000000098210225A82B56A0013E8FA5002050
+:106410003C048000348A0E008D5300143C0680003A
+:10642000AD5300108D4B001CAD4B0018AD45000066
+:106430008CCD000031AC00081180FFFD34CE0E0081
+:1064400095C3000800A0882100009021A783004088
+:106450008DC6000424130001AF860038976F00102A
+:1064600031F5FFFF8E9F000003F1282310A0011FCC
+:10647000AE85000093620008144000DD00000000BB
+:106480000E0001E7240400108F90004800402821EE
+:106490003C023200320600FF000654000142F8259B
+:1064A00026090001AF890048ACBF000093790009BC
+:1064B00097780012936F000A332800FF3303FFFF21
+:1064C0000103382100076C0031EE00FF01AE6025AA
+:1064D000ACAC00048F840048978B0040316A2000E8
+:1064E0001140010AACA4000897640012308BFFFF32
+:1064F00006400108ACAB000C978E004031C5000887
+:1065000014A0000226280006262800023C1F800056
+:1065100037E70E0094F900148CE5001C8F67000427
+:10652000937800023324FFFF330300FFAFA3001072
+:106530008F6F0014AFA800180E0001CBAFAF00148E
+:10654000240400100E0001FB000000008E920000E9
+:1065500016400005000000008F7800142403FFBFE0
+:106560000303A024AF7400148F67000C00F5C8214A
+:10657000AF79000C9375000816A000080000000019
+:1065800012600006000000008F6800143C0AEFFF54
+:106590003549FFFE0109F824AF7F0014A3730008FA
+:1065A0008FA500200A00034F02202021AED1000059
+:1065B0000A00022D3C03800014E0FF1E30BFA04003
+:1065C0000E0001900000A0212E9100010237B0259D
+:1065D00012C000188FBF00488F87003C24170F009F
+:1065E00010F700D43C0680008CD901780720FFFE0C
+:1065F000241F0F0010FF00F634CA0E008D56001441
+:1066000034C7014024080240ACF600048D49001C48
+:106610003C141000ACE90008A0E00012A4E0001A4D
+:10662000ACE00020A4E00018ACE80014ACD4017881
+:106630008FBF00488FB700448FB600408FB5003C35
+:106640008FB400388FB300348FB200308FB1002C7C
+:106650008FB0002803E0000827BD00508F9100385C
+:10666000978800403C1280000220A821310700409A
+:1066700014E0FF7C00009821977900108F92003879
+:106680003338FFFF131200A8000020210080A02152
+:10669000108000F300A088211620FECE000000002C
+:1066A0000A00031F2E9100013C0380008C620178D8
+:1066B0000440FFFE240808008F860000AC680178C3
+:1066C0003C038000946D008A31ACFFFF01865823A3
+:1066D000256AFFFF31441FFF2C8900081520FFF9B0
+:1066E000000000008F8F0048347040008F83003C12
+:1066F00000E0A021240E0F0025E70001AF8700482D
+:1067000000D03021023488233C08800031F500FF9E
+:10671000106E000524070001939800423313000116
+:106720000013924036470001001524003C0A010086
+:10673000008A4825ACC900008F82004830BF00366F
+:1067400030B90008ACC200041320009900FF98255E
+:1067500035120E009650000A8F8700003C0F810012
+:106760003203FFFF24ED000835060140006F60256D
+:106770003C0E100031AB1FFF269200062405000ED0
+:10678000ACCC0020026E9825A4C5001AAF8B000087
+:10679000A4D20018162000083C1080008F89003C0D
+:1067A00024020F005122000224170001367300401A
+:1067B0000E0001883C10800036060E008CCB0014C1
+:1067C000360A014002402021AD4B00048CC5001C5C
+:1067D000AD450008A1550012AD5300140E000198FC
+:1067E0003C151000AE1501780A00035200000000AD
+:1067F000936F0009976E0012936D000B31E500FF57
+:1068000000AE202131AC00FF008C80212602000A5E
+:106810003050FFFF0E0001E7020020218F86004864
+:106820003C0341003C05800024CB0001AF8B0048B5
+:10683000936A00099769001230C600FF315F00FFBC
+:106840003128FFFF03E8382124F900020006C400C4
+:106850000319782501E37025AC4E00008F6D000C04
+:1068600034A40E00948B001401B26025AC4C0004DB
+:106870008C85001C8F670004936A00023164FFFF5F
+:10688000314900FFAFA900108F680014AFB10018A4
+:106890000E0001CBAFA800140A0002FD0200202167
+:1068A000AF600004A3600002979800403308200006
+:1068B0001500FEA300003021A7600012978400405D
+:1068C000936B000A3C10800030931F00001351832B
+:1068D000014BA82126A20028A362000936090E0058
+:1068E000953F000C0A000295A77F00108F700014DE
+:1068F000360900400E000188AF6900140A0002C981
+:10690000000000000A00034F000020210641FEFAAB
+:10691000ACA0000C8CAC000C3C0D8000018D9025CF
+:106920000A0002EAACB2000C000090210A0002C585
+:1069300024130001128000073C028000344B0E003B
+:106940009566000830D30040126000490000000046
+:106950003C0680008CD001780600FFFE34C50E0096
+:1069600094B500103C03050034CC014032B8FFFF61
+:1069700003039025AD92000C8CAF0014240D200071
+:106980003C041000AD8F00048CAE001CAD8E0008DE
+:10699000A1800012A580001AAD800020A5800018FB
+:1069A000AD8D0014ACC401780A0003263C068000BB
+:1069B0008F9F0000351801402692000227F9000839
+:1069C00033281FFFA71200180A000391AF880000A8
+:1069D0003C02800034450140ACA0000C1280001B3A
+:1069E00034530E0034510E008E370010ACB7000443
+:1069F0008E2400183C0B8000ACA4000835700140C8
+:106A000024040040A20000128FBF0048A600001A14
+:106A10008FB70044AE0000208FB60040A6000018DB
+:106A20008FB5003CAE0400148FB400388FB300342F
+:106A30008FB200308FB1002C8FB000283C021000C4
+:106A400027BD005003E00008AD6201788E66001497
+:106A5000ACA600048E64001C0A00042A3C0B8000D3
+:106A60000E0001902E9100010A0003200237B0258C
+:106A7000000000000000000D000000002400036979
+:106A80000A0004013C06800027BDFFD8AFBF0020EC
+:106A90003C0980003C1F20FFAFB200183C0760009B
+:106AA00035320E002402001037F9FFFDACE2300849
+:106AB000AFB3001CAFB10014AFB00010AE5900006E
+:106AC00000000000000000000000000000000000C6
+:106AD000000000003C1800FF3713FFFDAE5300001C
+:106AE0003C0B60048D7050002411FF7F3C0E0002AF
+:106AF0000211782435EC380C35CD0109ACED4C1879
+:106B0000240A0009AD6C50008CE80438AD2A000856
+:106B1000AD2000148CE54C1C3106FFFF38C42F71EA
+:106B200000051E023062000F2486C0B3104000072B
+:106B3000AF8200088CE54C1C3C09001F3528FC0086
+:106B400000A81824000321C2AF8400048CF10808B7
+:106B50003C0F57092412F0000232702435F0001067
+:106B600001D0602601CF68262DAA00012D8B0001DF
+:106B7000014B382550E00009A380000C3C1F601C2D
+:106B80008FF8000824190001A399000C33137C002E
+:106B9000A7930010A780000EA380000DAF800048CF
+:106BA00014C00003AF8000003C066000ACC0442C61
+:106BB0000E0005B93C1080000E000F2436110100B4
+:106BC0003C12080026523DF03C13080026733E702C
+:106BD0008E03000038640001308200011440FFFC85
+:106BE0003C0B800A8E2600002407FF8024C9024047
+:106BF000312A007F014B402101272824AE060020C6
+:106C0000AF880044AE0500243C048000AF86003C01
+:106C10008C8C01780580FFFE24180800922F000854
+:106C2000AC980178A38F0042938E004231CD0001D1
+:106C300011A0000F24050D0024DFF8002FF9030137
+:106C40001320001C000629C224A4FFF000041042F7
+:106C5000000231400E00020200D2D8213C02400066
+:106C60003C068000ACC201380A0004A0000000000D
+:106C700010C50023240D0F0010CD00273C1F8008F5
+:106C800037F9008093380000240E0050330F00FFC6
+:106C900015EEFFF33C0240000E000A400000000029
+:106CA0003C0240003C068000ACC201380A0004A04F
+:106CB000000000008F83000400A3402B1500000B90
+:106CC0008F8B0008006B50212547FFFF00E5482B04
+:106CD0001520000600A36023000C19400E000202DC
+:106CE0000073D8210A0004C43C0240000000000DDB
+:106CF0000E000202000000000A0004C43C02400032
+:106D00003C1B0800277B3F700E00020200000000C1
+:106D10000A0004C43C0240003C1B0800277B3F9053
+:106D20000E000202000000000A0004C43C02400001
+:106D30003C0660043C09080025290104ACC9502C1C
+:106D40008CC850003C0580003C02000235070080E2
+:106D5000ACC750003C040800248415A43C03080080
+:106D60002463155CACA50008ACA2000C3C01080033
+:106D7000AC243D803C010800AC233D8403E00008C6
+:106D80002402000100A030213C1C0800279C3D8803
+:106D90003C0C04003C0B0002008B3826008C402683
+:106DA0002CE200010007502B2D050001000A48804D
+:106DB0003C03080024633D80004520250123182161
+:106DC0001080000300001021AC66000024020001C6
+:106DD00003E00008000000003C1C0800279C3D88E0
+:106DE0003C0B04003C0A0002008A3026008B382647
+:106DF0002CC200010006482B2CE500010009408050
+:106E00003C03080024633D80004520250103182130
+:106E100010800005000010213C0C0800258C155C3A
+:106E2000AC6C00002402000103E000080000000038
+:106E30003C0900023C0804000088302600893826FE
+:106E40002CC30001008028212CE4000100831025C0
+:106E50001040000B000030213C1C0800279C3D889E
+:106E60003C0A80008D4E00082406000101CA6825F6
+:106E7000AD4D00088D4C000C01855825AD4B000C24
+:106E800003E0000800C010213C1C0800279C3D883E
+:106E90003C0580008CA6000C000420272402000181
+:106EA00000C4182403E00008ACA3000C3C0200025C
+:106EB0001082000B3C0560003C07040010870003B3
+:106EC0000000000003E00008000000008CA908D0CA
+:106ED000240AFFFD012A402403E00008ACA808D0E2
+:106EE0008CA408D02406FFFE0086182403E00008C6
+:106EF000ACA308D03C05601A34A600108CC30080F7
+:106F000027BDFFF88CC50084AFA3000093A4000048
+:106F10002402000110820003AFA5000403E0000872
+:106F200027BD000893A7000114E0001497AC0002ED
+:106F300097B800023C0F8000330EFFFC01CF6821A0
+:106F4000ADA50000A3A000003C0660008CC708D0DF
+:106F50002408FFFE3C04601A00E82824ACC508D0D1
+:106F60008FA300048FA200003499001027BD0008F1
+:106F7000AF22008003E00008AF2300843C0B8000B8
+:106F8000318AFFFC014B48218D2800000A00057D55
+:106F9000AFA8000427BDFFE8AFBF00103C1C0800ED
+:106FA000279C3D883C0580008CA4000C8CA200042A
+:106FB0003C0300020044282410A0000A00A3182467
+:106FC0003C0604003C0400021460000900A61024E2
+:106FD0001440000F3C0404000000000D3C1C08009D
+:106FE000279C3D888FBF001003E0000827BD0018D4
+:106FF0003C0208008C423D800040F809000000007F
+:107000003C1C0800279C3D880A0005A68FBF001085
+:107010003C0208008C423D840040F809000000005A
+:107020000A0005AC00000000000411C003E00008E5
+:10703000244202403C04080024843FD42405001A62
+:107040000A00009C0000302127BDFFE0AFB0001017
+:107050003C108000AFBF0018AFB100143611010022
+:10706000922200090E0005B63044007F8E3F0000DA
+:107070008F89003C3C0F008003E26021258800409E
+:107080000049F821240DFF80310E007831980078F6
+:1070900035F9000135F100020319382501D14825E1
+:1070A000010D302403ED5824018D2824240A0040CA
+:1070B00024040080240300C0AE0B0024AE0008109E
+:1070C000AE0A0814AE040818AE03081CAE05080486
+:1070D000AE070820AE060808AE09082436090900E4
+:1070E0009539000C3605098033ED007F3338FFFFFA
+:1070F000001889C0AE110800AE0F0828952C000CAE
+:107100008FBF00188FB10014318BFFFF000B51C0EF
+:10711000AE0A002C8CA400508FB000108CA3003C51
+:107120008D2700048CA8001C8CA600383C0E800A19
+:1071300001AE102127BD0020AF820044AF84005073
+:10714000AF830054AF87004CAF88005C03E00008B9
+:10715000AF8600603C09080091293FF924A800028D
+:107160003C05110000093C0000E8302500C5182549
+:1071700024820008AC83000003E00008AC80000417
+:107180003C098000352309009128010B906A001109
+:107190002402002800804821314700FF00A0702110
+:1071A00000C068213108004010E20002340C86DD86
+:1071B000240C08003C0A800035420A9A94470000DB
+:1071C000354B0A9C35460AA030F9FFFFAD39000067
+:1071D0008D780000354B0A8024040001AD3800048E
+:1071E0008CCF0000AD2F00089165001930A300037B
+:1071F0001064009A28640002148000B9240500027B
+:10720000106500A8240F0003106F00BE35450AA4C6
+:10721000240A0800118A004D0000000051000042BD
+:107220003C0B80003C04800034830900906700120E
+:1072300030E200FF004D7821000FC88027240001B4
+:107240003C0A8000354F090091E50019354C098052
+:107250008D87002830A300FF000315000047582544
+:107260000004C4003C19600001793025370806FF8E
+:10727000AD260000AD2800048DEA002C252800284A
+:10728000AD2A00088DEC0030AD2C000C8DE50034EB
+:10729000AD2500108DE40038AD2400148DE3001CF2
+:1072A000AD2300188DE70020AD27001C8DE20024DF
+:1072B000AD2200208DF90028AD3900243C09800062
+:1072C0003526093C8CCF0000352A0100AD0E0004A4
+:1072D000AD0F00008D4E000C3523090035250980C7
+:1072E000AD0E0008906C00128D47000C8CB9003474
+:1072F0003C18080093183FF8318200FF004D5821D8
+:1073000003277823000B37000018240000C47025E1
+:1073100031E9FFFC01C9682525020014AD0D000C00
+:1073200003E00008AD000010357809009306001254
+:107330003C05080094A53FE830C800FF010D50212E
+:10734000000A60800A00063C0185202115000060CB
+:10735000000000003C08080095083FEE3C060800CD
+:1073600094C63FE8010610213C0B800035790900E6
+:1073700093380011932A001935660A80330800FFFC
+:1073800094CF002A00086082314500FF978A005898
+:10739000000C1E00000524003047FFFF006410258C
+:1073A0000047C02501EA30213C0B4000030B40257B
+:1073B00000066400AD280000AD2C000493250018E1
+:1073C0003C0300062528001400053E0000E31025BC
+:1073D000AD2200088F24002C254F000131EB7FFFE8
+:1073E000AD24000C8F38001CA78B0058AD3800105E
+:1073F0003C0980003526093C8CCF0000352A01006D
+:10740000AD0E0004AD0F00008D4E000C35230900B9
+:1074100035250980AD0E0008906C00128D47000CD8
+:107420008CB900343C18080093183FF8318200FFF3
+:10743000004D582103277823000B37000018240043
+:1074400000C4702531E9FFFC01C96825250200143C
+:10745000AD0D000C03E00008AD0000103C02080078
+:1074600094423FF23C05080094A53FE835440AA445
+:107470003C07080094E73FE4948B00000045C821D6
+:107480000327C023000B1C002706FFF200665025CF
+:10749000AD2A000CAD200010AD2C00140A000630FF
+:1074A00025290018354F0AA495E5000095640028A9
+:1074B0000005140000043C003459810000EC5825FC
+:1074C000AD39000CAD2B00100A0006302529001440
+:1074D0003C0C0800958C3FEE0A00068625820001D0
+:1074E0005460FF4C240A080035580AA4970600008F
+:1074F00000061C00006C5025AD2A000C0A00063066
+:10750000252900103C03080094633FF23C07080063
+:1075100094E73FE83C0F080095EF3FE494A4000097
+:107520009579002800671021004F582300041C00A3
+:10753000001934002578FFEE00D87825346A8100E0
+:10754000AD2A000CAD2F0010AD200014AD2C00189A
+:107550000A0006302529001C03E00008240207D099
+:1075600027BDFFE0AFB20018AFB10014AFB00010FC
+:10757000AFBF001C0E00007C008088218F88005463
+:107580008F87004C3C05800834B20080011128210F
+:107590003C10800024020080240300C000A72023A8
+:1075A000AE0208183C068008AE03081C18800004D0
+:1075B000AF850054ACC500048CC90004AF89004CF1
+:1075C00012200009360409800E00070200000000A6
+:1075D000924C00278E0B007401825004014B302125
+:1075E000AE46000C360409808C8E001C8F8F005C28
+:1075F00001CF682319A000048FBF001C8C90001CD1
+:10760000AF90005C8FBF001C8FB200188FB10014C8
+:107610008FB000100A00007E27BD00208F8600502A
+:107620008F8300548F82004C3C05800834A4008076
+:10763000AC860050AC83003C03E00008ACA2000420
+:107640003C0308008C63005427BDFFF8308400FF22
+:107650002462000130A500FF3C010800AC22005468
+:1076600030C600FF3C0780008CE801780500FFFE73
+:107670003C0C7FFFA3A400038FAA0000358BFFFF03
+:10768000014B4824000627C001244025AFA8000074
+:1076900034E201009043000AA3A000023C1980FFDD
+:1076A000A3A300018FAF000030AE007F3738FFFF8B
+:1076B00001F86024000E6E003C0A002034E5014011
+:1076C000018D5825354920002406FF803C04100018
+:1076D00027BD0008ACAB000CACA90014A4A0001896
+:1076E000A0A6001203E00008ACE40178308800FF97
+:1076F00030A700FF3C0380008C6201780440FFFE4D
+:107700003C0C8000358A0A008D4B002035840140F6
+:1077100035850980AC8B00048D4900240007302B8F
+:1077200000061540AC890008A088001090A3004C0A
+:10773000A083002D03E00008A480001827BDFFE807
+:10774000308400FFAFBF00100E00076730A500FFB8
+:107750008F8300548FBF00103C06800034C5014069
+:10776000344700402404FF903C02100027BD00185D
+:10777000ACA3000CA0A40012ACA7001403E0000806
+:10778000ACC2017827BDFFE03C088008AFBF001CF9
+:10779000AFB20018AFB10014AFB0001035100080C8
+:1077A0008E0600183C078000309200FF00C720259D
+:1077B000AE0400180E00007C30B100FF92030005FB
+:1077C000346200080E00007EA20200050240202163
+:1077D0000E00077B02202821024020218FBF001CC1
+:1077E0008FB200188FB100148FB00010240500056F
+:1077F000240600010A00073C27BD00203C0580004C
+:1078000034A309809066000830C200081040000FC1
+:107810003C0A01013549080AAC8900008CA80074B3
+:10782000AC8800043C07080090E73FF830E5001002
+:1078300050A00008AC8000083C0D800835AC0080EA
+:107840008D8B0058AC8B00082484000C03E00008EA
+:10785000008010210A0007BF2484000C27BDFFE828
+:107860003C098000AFB00010AFBF0014352609807E
+:1078700090C800092402000600A05821310300FF2F
+:107880003527090000808021240500041062007B58
+:107890002408000294CF005C3C0E020431EDFFFF8F
+:1078A00001AE6025AE0C000090CA000831440020F3
+:1078B000108000080000000090C2004E3C1F010331
+:1078C00037F90300305800FF03193025240500085C
+:1078D000AE06000490F9001190E6001290E4001149
+:1078E000333800FF0018708230CF00FF01CF5021E5
+:1078F000014B6821308900FF31AAFFFF392300289E
+:10790000000A60801460002C020C482390E40012EE
+:107910003C198000372F0100308C00FF018B1821AB
+:10792000000310800045F821001F8400360706FF81
+:10793000AD270004373F090093EC001193EE0012CD
+:10794000372609800005C0828DE4000C8CC5003408
+:1079500031CD00FF01AB10210058182100A4F823FD
+:107960000008840000033F0000F0302533F9FFFFDA
+:10797000318F00FC00D970250158202101E96821D0
+:1079800000045080ADAE000C0E00007C012A802166
+:107990003C088008240B0004350500800E00007EA2
+:1079A000A0AB0009020010218FBF00148FB000109F
+:1079B00003E0000827BD001890EC001190E30019C7
+:1079C0003C18080097183FEE318200FF0002F88251
+:1079D000307000FF001FCE0000103C000327302550
+:1079E00000D870253C0F400001CF68253C1980006D
+:1079F000AD2D0000373F090093EC001193EE00120B
+:107A0000372F0100372609800005C0828DE4000C65
+:107A10008CC5003431CD00FF01AB10210058182176
+:107A200000A4F8230008840000033F0000F0302584
+:107A300033F9FFFF318F00FC00D970250158202158
+:107A400001E9682100045080ADAE000C0E00007CFE
+:107A5000012A80213C088008240B000435050080A1
+:107A60000E00007EA0AB0009020010218FBF0014A1
+:107A70008FB0001003E0000827BD00180A0007D1EE
+:107A80002408001227BDFFD03C038000AFB60028B9
+:107A9000AFB50024AFB40020AFB10014AFBF002CCD
+:107AA000AFB3001CAFB20018AFB0001034670100D4
+:107AB00090E6000B309400FF30B500FF30C200307C
+:107AC0000000B02110400099000088213464098032
+:107AD0009088000800082E0000051E03046000C006
+:107AE000240400048F8600543C010800A0243FF8C1
+:107AF0003C0C8000AD8000483C048000348E0100C6
+:107B000091CD000B31A5002010A000073C0780009C
+:107B100034930980927200080012860000107E03E0
+:107B200005E000C43C1F800834EC0100918A000B82
+:107B300034EB098091690008314400400004402B77
+:107B40003123000800C898231460000224120003A7
+:107B5000000090213C10800036180A80360409008D
+:107B6000970E002C90830011908900129305001845
+:107B7000307F00FF312800FF024810210002C8803A
+:107B8000930D0018033F782101F1302130B100FF3F
+:107B900000D11821A78E00583C010800A4263FEE12
+:107BA0003C010800A4233FF015A0000200000000E3
+:107BB0000000000D920B010B3065FFFF3C01080037
+:107BC000A4233FF2316A00403C010800A4203FE8B2
+:107BD0003C010800A4203FE41140000224A4000A54
+:107BE00024A4000B3091FFFF0E0001E702202021AA
+:107BF0009206010B3C0C0800958C3FF200402021BE
+:107C00000006698231A700010E00060101872821C4
+:107C100000402021026028210E00060C0240302185
+:107C20000E0007AB0040202116C000690040202153
+:107C30009212010B3256004012C000053C0500FFB5
+:107C40008C93000034AEFFFF026E8024AC900000E5
+:107C50000E0001FB022020213C0F080091EF3FF8AD
+:107C600031F10003122000163C1380088F8200546B
+:107C70003C09800835280080245F0001AD1F003CCE
+:107C80003C0580088CB9000403E02021033FC02399
+:107C90001B000002AF9F00548CA400040E000702DA
+:107CA000ACA400043C0780008CEB00743C0480080A
+:107CB00034830080004B5021AC6A000C3C138008D8
+:107CC000367000800280202102A02821A200006BD3
+:107CD0000E0007673C1480008F920054368C0140E0
+:107CE000AD92000C8F8600483C151000344D000604
+:107CF00024D60001AF9600488FBF002CA186001249
+:107D00008FB60028AD8D00148FB3001CAE9501789E
+:107D10008FB200188FB500248FB400208FB10014EB
+:107D20008FB0001003E0000827BD003034640980E4
+:107D3000908F0008000F7600000E6E0305A0003340
+:107D4000347F090093F8001B241900103C0108003F
+:107D5000A0393FF8331300021260FF678F8600548A
+:107D60008F8200601446FF653C0480000E00007C9A
+:107D7000000000003C0480083485008090A80009C1
+:107D800024060016310300FF1066000D00000000FD
+:107D900090AB00093C07080090E73FF82409000871
+:107DA000316400FF34EA00013C010800A02A3FF8DA
+:107DB0001089002F240C000A108C00282402000CCB
+:107DC0000E00007E000000000A00086A8F86005442
+:107DD0000E0007C3024028210A0008B800402021F5
+:107DE0003C0B8008356A00808D4600548CE9000CFD
+:107DF0001120FF3DAF860054240700143C01080009
+:107E0000A0273FF80A0008693C0C80009091000808
+:107E1000241200023C010800A0323FF8323000205A
+:107E20001200000B241600018F8600540A00086A15
+:107E30002411000837F800808F020038AFE20004F8
+:107E40008FF90004AF19003C0A0008763C07800057
+:107E50008F8600540A00086A24110004A0A20009B9
+:107E60000E00007E000000000A00086A8F860054A1
+:107E7000240200140A000944A0A2000927BDFFE85B
+:107E8000AFB000103C108000AFBF001436020100FC
+:107E9000904400090E000767240500013C04800897
+:107EA0009099000E34830080909F000F906F002601
+:107EB0009089000A33F800FF00196E000018740062
+:107EC00031EC00FF01AE5025000C5A00014B382563
+:107ED000312800FF360301403445600000E83025BA
+:107EE0002402FF813C041000AC66000C8FBF00141C
+:107EF000AC650014A0620012AE0401788FB00010CF
+:107F000003E0000827BD001827BDFFE8308400FF0C
+:107F1000AFBF00100E00076730A500FF3C058000D2
+:107F200034A40140344700402406FF92AC8700147B
+:107F3000A08600128F8300548FBF00103C021000F7
+:107F400027BD0018AC83000C03E00008ACA2017848
+:107F500027BDFFD8AFB00010308400FF30B000FF65
+:107F60003C058000AFB10014AFBF0020AFB3001CD0
+:107F7000AFB20018000410C234A6010032030002A0
+:107F8000305100011460000790D200093C098008BC
+:107F900035330080926800053107000810E0000CBE
+:107FA000308A0010024020210E00078D0220282177
+:107FB000240200018FBF00208FB3001C8FB2001875
+:107FC0008FB100148FB0001003E0000827BD002817
+:107FD0001540003434A50A008CB800248CAF00088A
+:107FE000130F004B000038213C0D800835B3008092
+:107FF000926C006824060002318B00FF1166008439
+:108000003C06800034C201009263004C9059000984
+:10801000307F00FF53F900043213007C10E0006948
+:10802000000000003213007C5660005C02402021FA
+:1080300016200009320D00013C0C8000358401003F
+:10804000358B0A008D6500248C86000414A6FFD9A8
+:1080500000001021320D000111A0000E024020216D
+:108060003C188000371001008E0F000C8F8E0050DE
+:1080700011EE0008000000000E00084D022028212B
+:108080008E19000C3C1F800837F00080AE1900509C
+:10809000024020210E00077B022028210A000999B6
+:1080A000240200013C0508008CA5006424A4000102
+:1080B0003C010800AC2400641600000D0000000024
+:1080C000022028210E00077B02402021926E0068CA
+:1080D000240C000231CD00FF11AC0022024020210F
+:1080E0000E00094B000000000A000999240200015B
+:1080F0000E00007024040001926B0025020B302555
+:108100000E00007EA26600250A0009DD022028215B
+:108110008E6200188CDF00048CB9002400021E025D
+:1081200017F9FFB13065007F9268004C26440001CA
+:108130003093007F12650040310300FF1464FFABF1
+:108140003C0D80082647000130F1007F30E200FF3F
+:108150001225000B24070001004090210A0009A607
+:1081600024110001240500040E00073C2406000130
+:108170000E00094B000000000A00099924020001CA
+:108180002405FF800245202400859026324200FF0E
+:10819000004090210A0009A6241100010E00084D9C
+:1081A000022028213207003010E0FFA132100082A7
+:1081B000024020210E00078D022028210A00099983
+:1081C000240200018E69001802402021022028218B
+:1081D000012640250E00096EAE6800189264004C1E
+:1081E00024050003240600010E00073C308400FF34
+:1081F0000E00007024040001927100250211502528
+:108200000E00007EA26A00250A00099924020001DE
+:108210008E6F00183C1880000240202101F8702564
+:10822000022028210E00077BAE6E00189264004CDD
+:108230000A000A2524050004324A008039490080DA
+:108240001469FF6A3C0D80080A0009FE26470001F8
+:1082500027BDFFC0AFB000183C108000AFBF003892
+:10826000AFB70034AFB60030AFB5002CAFB40028C4
+:10827000AFB30024AFB200200E0005BEAFB1001CAA
+:10828000360201009045000B0E0009809044000862
+:10829000144000E78FBF00383C0880083507008095
+:1082A000A0E0006B3606098090C500002403005052
+:1082B0003C17080026F73FB030A400FF3C1308002D
+:1082C00026733FC0108300033C1080000000B821DB
+:1082D00000009821241F00103611010036120A00F8
+:1082E000361509808E5800248E3400048EAF00208D
+:1082F0008F8C00543C010800A03F3FF836190A80DB
+:10830000972B002C8EF60000932A001802987023F9
+:1083100001EC68233C010800AC2E3FD43C0108006E
+:10832000AC2D3FD83C010800AC2C3FFCA78B00587B
+:1083300002C0F809315400FF30490002152000E95D
+:1083400030420001504000C49227000992A9000861
+:108350003128000815000002241500030000A821A0
+:108360003C0A80003543090035440A008C8D002406
+:108370009072001190700012907F0011325900FF2E
+:10838000321100FF02B110210002C08033EF00FF64
+:108390000319B021028F702102D4602125CB001077
+:1083A0003C010800A4363FEE3C010800AC2D400023
+:1083B0003C010800A42C3FF03C010800A42B3FEC3A
+:1083C000355601003554098035510E008F87005411
+:1083D0008F89005C8E850020240800060127302349
+:1083E0003C010800AC283FF400A7282304C000B5D6
+:1083F0000000902104A000B300C5502B114000B52F
+:10840000000000003C010800AC263FD88E6200004E
+:108410000040F809000000003046000214C000745B
+:1084200000408021304B0001556000118E62000435
+:108430003C0D08008DAD3FDC3C0EC0003C048000CC
+:1084400001AE6025AE2C00008C980000330F0008B0
+:1084500011E0FFFD00000000963F0008241200011B
+:10846000A79F00408E390004AF9900388E62000447
+:108470000040F809000000000202802532030002DB
+:10848000146000B3000000003C09080095293FE497
+:108490003C06080094C63FF03C0A0800954A3FE6B7
+:1084A0003C0708008CE73FDC012670213C030800F4
+:1084B0008C6340003C08080095083FFA01CA20215F
+:1084C0008ED9000C00E92821249F000200A8782101
+:1084D0000067C02133E4FFFFAF9900503C01080062
+:1084E000AC3840003C010800A42F3FE83C010800E4
+:1084F000A42E3FF20E0001E7000000008F8D00481F
+:10850000004020213C010800A02D3FF98E620008A8
+:1085100025AC0001AF8C00480040F80900000000C5
+:108520008F85005402A030210E00060C004020214F
+:108530000E0007AB004020218E6B000C0160F80993
+:10854000004020213C0A0800954A3FF23C06080002
+:1085500094C63FE601464821252800020E0001FB93
+:108560003104FFFF3C0508008CA53FD43C07080000
+:108570008CE73FDC00A720233C010800AC243FD45B
+:1085800014800006000000003C0208008C423FF40A
+:10859000344B00403C010800AC2B3FF41240004338
+:1085A0008F8E00448E2D00108F920044AE4D00201F
+:1085B0008E2C0018AE4C00243C04080094843FE844
+:1085C0000E000704000000008F9F00548E6700100B
+:1085D0003C010800AC3F3FFC00E0F809000000004F
+:1085E0003C1908008F393FD41720FF798F8700543A
+:1085F000979300583C11800E321601000E0007338D
+:10860000A633002C16C00045320300105460004C05
+:108610008EE50004320800405500001D8EF0000871
+:108620008EE4000C0080F809000000008FBF0038C5
+:108630008FB700348FB600308FB5002C8FB4002870
+:108640008FB300248FB200208FB1001C8FB00018B0
+:1086500003E0000827BD00408F86003C36110E0065
+:1086600000072E0000A62025AE0400808E430020C7
+:108670008E500024AFA30010AE2300148FB2001060
+:10868000AE320010AE30001C0A000A7FAE30001877
+:108690000200F809000000008EE4000C0080F809D8
+:1086A000000000000A000B388FBF003824180001BA
+:1086B000240F0001A5C00020A5D800220A000B1A33
+:1086C000ADCF00243C010800AC203FD80A000AB01E
+:1086D0008E6200003C010800AC253FD80A000AB0B9
+:1086E0008E620000922400090E00077B0000282102
+:1086F0008FBF00388FB700348FB600308FB5002C95
+:108700008FB400288FB300248FB200208FB1001CDB
+:108710008FB0001803E0000827BD00403C14800023
+:1087200092950109000028210E00084D32A400FF97
+:10873000320300105060FFB8320800408EE500049C
+:1087400000A0F809000000000A000B3232080040C7
+:108750005240FFA8979300588E3400148F93004422
+:10876000AE7400208E35001CAE7500240A000B2963
+:10877000979300588F8200140004218003E00008C2
+:10878000008210213C07800834E200809043006999
+:1087900000804021106000093C0401003C070800F3
+:1087A0008CE73FFC8F83003000E320230480000827
+:1087B0009389001C14E300030100202103E000085A
+:1087C000008010213C04010003E00008008010211B
+:1087D0001120000B006738233C0D800035AC098068
+:1087E000918B007C316A0002114000202409003482
+:1087F00000E9702B15C0FFF10100202100E93823AA
+:108800002403FFFC00A3C82400E3C02400F9782B54
+:1088100015E0FFEA0308202130C400030004102300
+:1088200014C00014304900030000302100A9782151
+:1088300001E6702100EE682B11A0FFE03C0401006E
+:108840002D3800010006C82B0105482103193824E2
+:1088500014E0FFDA2524FFFC2402FFFC00A2182408
+:108860000068202103E00008008010210A000BA806
+:10887000240900303C0C80003586098090CB007CB8
+:10888000316A00041540FFE9240600040A000BB712
+:10889000000030213C0308008C63005C8F820018CC
+:1088A00027BDFFE0AFBF0018AFB100141062000594
+:1088B000AFB00010000329C024A40280AF840014CC
+:1088C000AF8300183C10800036020A009445003245
+:1088D000361101000E000B8930A43FFF8E240000EA
+:1088E000241FFF803C1100800082C021031F6024F0
+:1088F0003309007F000CC94003294025330E00785E
+:10890000362F00033C0D1000010D502501CF5825D6
+:10891000AE0C002836080980AE0C080CAE0B082CF3
+:10892000AE0A0830910300693C06800C012638210C
+:1089300010600006AF8700348D09003C8D03006C89
+:108940000123382318E00082000000003C0B80085F
+:10895000356A00803C108000A1400069360609801D
+:108960008CC200383C06800034C50A0090A8003C48
+:10897000310C00201180001AAF820030240D00015C
+:108980003C0E800035D10A00A38D001CAF8000246E
+:108990008E2400248F850024240D0008AF80002041
+:1089A000AF8000283C010800A42D3FE63C010800F0
+:1089B000A4203FFA0E000B8D000030219228003CCD
+:1089C0008FBF00188FB100148FB0001000086142F3
+:1089D000AF82002C27BD002003E000083182000197
+:1089E00090B80032240E0001330F00FF000F2182E7
+:1089F000108E0041241900021099006434C40AC08A
+:108A00003C03800034640A008C8F002415E0001EB3
+:108A100034660900909F00302418000533F9003FA8
+:108A20001338004E240300018F860020A383001C0E
+:108A3000AF860028AF8600243C0E800035D10A00A6
+:108A40008E2400248F850024240D00083C0108009A
+:108A5000A42D3FE63C010800A4203FFA0E000B8D38
+:108A6000000000009228003C8FBF00188FB1001456
+:108A70008FB0001000086142AF82002C27BD00209B
+:108A800003E00008318200018C8A00088C8B0024EE
+:108A90008CD000643C0E800035D10A00014B2823A5
+:108AA000AF900024A380001CAF8500288E240024F2
+:108AB0008F8600208F850024240D00083C010800CB
+:108AC000A42D3FE63C010800A4203FFA0E000B8DC8
+:108AD000000000009228003C8FBF00188FB10014E6
+:108AE0008FB0001000086142AF82002C27BD00202B
+:108AF00003E000083182000190A200303051003FB5
+:108B00005224002834C50AC08CB00024160000226C
+:108B100034CB09008CA600483C0A7FFF3545FFFF97
+:108B200000C510243C0E8000AF82002035C509002E
+:108B30008F8800208CAD0060010D602B1580000235
+:108B4000010020218CA400600A000C2CAF840020BE
+:108B50008D02006C0A000C063C0680008C820048E6
+:108B60008F8600203C097FFF3527FFFF00478824C0
+:108B70003C04800824030001AF910028AC80006C05
+:108B8000A383001C0A000C3AAF8600248C9F0014BB
+:108B90000A000C2CAF9F00208D6200680A000C7642
+:108BA0003C0E800034C409808C8900708CA30014B2
+:108BB0000123382B10E00004000000008C820070BC
+:108BC0000A000C763C0E80008CA200140A000C7681
+:108BD0003C0E80008F85002427BDFFE0AFBF00184A
+:108BE000AFB1001414A00008AFB000103C04800026
+:108BF00034870A0090E600302402000530C3003FAD
+:108C0000106200B9348409008F91002000A08021F7
+:108C10003C048000348E0A008DCD00043C06080020
+:108C20008CC63FD831A73FFF00E6602B558000017E
+:108C300000E03021938F001C11E0007800D0282B39
+:108C4000349F098093F9007C3338000213000079C7
+:108C50002403003400C3102B144000D9000000008E
+:108C600000C3302300D0282B3C010800A4233FE49C
+:108C700014A0006E020018213C0408008C843FD42C
+:108C80000064402B55000001006020213C0580005D
+:108C900034A90A00912A003C3C010800AC243FDCC6
+:108CA00031430020146000030000482134AB0E0063
+:108CB0008D6900188F88002C0128202B1080005F00
+:108CC000000000003C0508008CA53FDC00A96821DD
+:108CD000010D602B1180005C00B0702B010938235E
+:108CE00000E028213C010800AC273FDC1200000313
+:108CF000240AFFFC10B0008D3224000300AA1824BF
+:108D00003C010800A4203FFA3C010800AC233FDCF2
+:108D1000006028218F840024120400063C0B800888
+:108D20008D6C006C02002021AF9100202590000185
+:108D3000AD70006C8F8D002800858823AF910024D2
+:108D400001A52023AF840028122000022407001868
+:108D5000240700103C1880083706008090CF006878
+:108D60003C010800A0273FF82407000131EE00FF76
+:108D700011C70047000000001480001800002821DF
+:108D80003C06800034D1098034CD010091A6000951
+:108D90008E2C001824C40001000C86023205007FCE
+:108DA000308B007F1165007F2407FF803C1980080D
+:108DB00037290080A124004C3C0808008D083FF4AE
+:108DC000241800023C010800A0384039350F000883
+:108DD0003C010800AC2F3FF4240500103C02800049
+:108DE00034440A009083003C307F002013E00005EB
+:108DF00000A02021240A00013C010800AC2A3FDC2D
+:108E000034A400018FBF00188FB100148FB0001080
+:108E10000080102103E0000827BD00203C0108006D
+:108E2000A4203FE410A0FF94020018210A000CCAFD
+:108E300000C018210A000CC1240300303C050800C2
+:108E40008CA53FDC00B0702B11C0FFA80000000013
+:108E50003C19080097393FE40325C0210307782B0C
+:108E600011E000072CAA00043C0360008C6254044B
+:108E7000305F003F17E0FFE3240400422CAA000407
+:108E80001140FF9A240400420A000D2E8FBF0018E3
+:108E90001528FFB9000000008CCA00183C1F800094
+:108EA00024020002015F1825ACC3001837F90A003C
+:108EB000A0C200689329003C2404000400A01021F3
+:108EC000312800203C010800A02440391100000294
+:108ED00024050010240200013C010800AC223FD40C
+:108EE0000A000D243C0280008F8800288C890060D5
+:108EF0000109282B14A00002010088218C91006038
+:108F00003C048000348B0E008D640018240A00019C
+:108F10000220282102203021A38A001C0E000B8D84
+:108F2000022080210A000CB0AF82002C00045823DC
+:108F300012200007316400033C0E800035C7098011
+:108F400090ED007C31AC000415800019248F0004E2
+:108F50003C010800A4243FFA3C1F080097FF3FFA99
+:108F600003E5C82100D9C02B1300FF6B8F840024B8
+:108F70002CA6000514C0FFA32404004230A2000365
+:108F80001440000200A2182324A3FFFC3C010800A7
+:108F9000AC233FDC3C010800A4203FFA0A000CF19E
+:108FA0000060282100C770240A000D1701C7202681
+:108FB0003C010800A42F3FFA0A000D8200000000C7
+:108FC0003C010800AC203FDC0A000D2D24040042C7
+:108FD0008F8300283C05800034AA0A001460000634
+:108FE00000001021914700302406000530E400FF06
+:108FF000108600030000000003E0000800000000ED
+:10900000914B0048316900FF000941C21500FFFA89
+:109010003C0680083C04080094843FE43C030800BC
+:109020008C633FFC3C1908008F393FDC3C0F080083
+:1090300095EF3FFA0064C0218CCD00040319702124
+:1090400001CF602134AB0E00018D282318A0001D34
+:1090500000000000914F004C8F8C0034956D001083
+:1090600031EE00FF8D89000401AE30238D8A0000AF
+:1090700030CEFFFF000E29000125C8210000382155
+:10908000014720210325182B0083C021AD9900043E
+:10909000AD980000918F000A01CF6821A18D000AD0
+:1090A000956500128F8A0034A5450008954B00385D
+:1090B00025690001A54900389148000D35070008D1
+:1090C000A147000D03E000080000000027BDFFD805
+:1090D000AFB000189388001C8FB000143C0A8000C9
+:1090E0003C197FFF8F8700243738FFFFAFBF002078
+:1090F000AFB1001C355F0A000218182493EB003C46
+:1091000000087FC03C02BFFF006F60252CF000010B
+:109110003449FFFF3C1F08008FFF3FFC8F99003050
+:109120003C18080097183FF2018978240010478006
+:109130003C07EFFF3C05F0FF01E818253C118000DB
+:109140003169002034E2FFFF34ADFFFF362E098085
+:1091500027A500102406000203F96023270B000254
+:10916000354A0E000062182400808021152000027C
+:10917000000040218D48001CA7AB0012058000397B
+:109180002407000030E800FF00083F000067582572
+:109190003C028008AFAB0014344F008091EA0068B5
+:1091A0003C08080091083FF93C09DFFF352CFFFF20
+:1091B000000AF82B3C02080094423FECA3A80011DF
+:1091C000016CC024001FCF40031918258FA7001081
+:1091D000AFA300143C0C0800918C3FFBA7A2001623
+:1091E0008FAB001400ED48243C0F01003C0A0FFF38
+:1091F000012FC82531980003355FFFFF016D402422
+:109200003C027000033F382400181E0000E248258D
+:1092100001037825AFAF0014AFA9001091CC007CFA
+:109220000E000092A3AC0015362D0A0091A6003C5A
+:1092300030C4002010800006260200083C110800FF
+:1092400096313FE8262EFFFF3C010800A42E3FE8A0
+:109250008FBF00208FB1001C8FB0001803E0000802
+:1092600027BD00288F8B002C010B502B5540FFC5CC
+:10927000240700010A000E0E30E800FF9383001C53
+:109280003C02800027BDFFD834480A0000805021EE
+:10929000AFBF002034460AC0010028211060000E34
+:1092A0003444098091070030240B00058F89002089
+:1092B00030EC003F118B000B00003821AFA90010EB
+:1092C0003C0B80088D69006CAFAA00180E00015A93
+:1092D000AFA90014A380001C8FBF002003E000088A
+:1092E00027BD00288D1F00483C1808008F183FDC60
+:1092F0008F9900283C027FFF8D0800443443FFFF14
+:10930000AFA900103C0B80088D69006C03E370244A
+:109310000319782101CF682301A83821AFAA0018CA
+:109320000E00015AAFA900140A000E62A380001CAF
+:109330003C05800034A60A0090C7003C3C060800AB
+:1093400094C63FFA3C0208008C423FF430E3002010
+:10935000000624001060001E004438253C088008E8
+:109360003505008090A30068000048212408000112
+:1093700000002821240400013C0680008CCD0178E7
+:1093800005A0FFFE34CF0140ADE800083C02080014
+:109390008C423FFCA5E50004A5E40006ADE2000C0C
+:1093A0003C04080090843FF93C0380083479008035
+:1093B000A1E40012ADE70014A5E900189338004CB1
+:1093C0003C0E1000A1F8002D03E00008ACCE01789F
+:1093D00034A90E008D28001C3C0C08008D8C3FDC4D
+:1093E000952B0016952A0014018648213164FFFF51
+:1093F0000A000E8A3145FFFF3C04800034830A00D6
+:109400009065003C30A200201040001934870E0007
+:109410000000402100003821000020213C0680008F
+:109420008CC901780520FFFE34CA014034CF010009
+:1094300091EB0009AD4800083C0E08008DCE3FFCC2
+:10944000240DFF91240C00403C081000A5440004AA
+:10945000A5470006AD4E000CA14D0012AD4C001406
+:10946000A5400018A14B002D03E00008ACC801780E
+:109470008CE8001894E6001294E4001030C7FFFF57
+:109480000A000EB33084FFFF3C04800034830A00DE
+:109490009065003C30A200201040002727BDFFF857
+:1094A0002409000100003821240800013C06800046
+:1094B0008CCA01780540FFFE3C0280FF34C40100E5
+:1094C000908D00093C0C0800918C4039A3AD00033D
+:1094D0008FAB00003185007F3459FFFF01665025B6
+:1094E000AFAA00009083000AA3A0000200057E003E
+:1094F000A3A300018FB8000034CB0140240C30003E
+:109500000319702401CF6825AD6D000C27BD00083C
+:10951000AD6C0014A5600018AD690008A5670004D3
+:109520002409FF80A56800063C081000A16900120C
+:1095300003E00008ACC8017834870E008CE90018FD
+:1095400094E6001294E4001030C8FFFF0A000ED722
+:109550003087FFFF27BDFFE0AFB100143C11800052
+:10956000AFB00010AFBF001836380A00970F0032B6
+:10957000363001000E000B8931E43FFF8E0E0000F3
+:10958000240DFF803C04200001C25821016D60249D
+:10959000000C4940316A007F012A4025010438252A
+:1095A0003C048008AE2708303486008090C50068EF
+:1095B0002403000230A200FF104300048F9F00200C
+:1095C0008F990024AC9F0068AC9900648FBF00188D
+:1095D0008FB100148FB0001003E0000827BD0020F9
+:1095E0003C0A0800254A3AA83C09080025293B38CE
+:1095F0003C08080025082F443C07080024E73C04E9
+:109600003C06080024C6392C3C05080024A53680F9
+:109610003C040800248432843C030800246339E0BD
+:109620003C0208002442377C3C010800AC2A3FB8C9
+:109630003C010800AC293FB43C010800AC283FB015
+:109640003C010800AC273FBC3C010800AC263FCCE5
+:109650003C010800AC253FC43C010800AC243FC0DD
+:109660003C010800AC233FD03C010800AC223FC8BD
+:0896700003E000080000000007
+:08967800800009408000090098
+:10968000800801008008008080080000800E000033
+:10969000800800808008000080000A8080000A00A6
+:0896A000800009808000090030
:00000001FF
/*
* This file contains firmware data derived from proprietary unpublished
diff --git a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex
deleted file mode 100644
index 33b584c7c1ab..000000000000
--- a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex
+++ /dev/null
@@ -1,9476 +0,0 @@
-:1000000000003BB0000000680000070C00003C202E
-:1000100000001AF8000043300000007C00005E3051
-:10002000000079E800005EB0000000B40000D8A035
-:100030000000800C0000D9580000008800015968B9
-:10004000000039C4000159F800000090000193C07D
-:100050000000ABA80001945800000FFC000240080B
-:100060000000000400025008020400480000000FD5
-:100070000204005400000045020400580000000083
-:100080000204005C0000000602040070000000048E
-:1000900002040078000000000204007C1217000037
-:1000A00002040080221700000204008432170000BE
-:1000B00006040088000000050204009C12150000E0
-:1000C000020400A022150000020400A43215000062
-:1000D000060400A800000004020400B8021000009A
-:1000E000020400BC00100000020400C01010000058
-:1000F000020400C420100000020400C830100000F8
-:10010000060400CC00000004020400DC0010000023
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000060400EC00000004A1
-:100130000104012400000000010401280000000067
-:100140000104012C00000000010401300000000047
-:1001500002040004000000FF02040008000000FF89
-:100160000204000C000000FF02040010000000FF69
-:1001700002040014000000FF02040018000000FF49
-:100180000204001C000000FF02040020000000FF29
-:10019000020400240000003E0204002800000000C9
-:1001A0000204002C0000003F020400300000003F69
-:1001B000020400340000003F020400380000000088
-:1001C0000204003C0000003F020400400000003F29
-:1001D000020400440000003F020420080000021155
-:1001E0000204200C0000020002042010000002049F
-:1001F00002042014000002190204201C0000FFFF6A
-:10020000020420200000FFFF020420240000FFFF62
-:10021000020420280000FFFF0604203800000080B0
-:100220000204223807FFFFFF0204223C0000003FC7
-:100230000204224007FFFFFF020422440000000FD7
-:1002400001042248000000000104224C00000000CC
-:1002500001042250000000000104225400000000AC
-:1002600001042258000000000104225C000000008C
-:10027000010422600000000001042264000000006C
-:1002800001042268000000000104226C000000004C
-:10029000010422700000000001042274000000002C
-:1002A00001042278000000000104227C000000000C
-:1002B000020424BC000000010C042000000003E83C
-:1002C0000A042000000000010B0420000000000AC6
-:1002D0000605400000000D0002050044000000205B
-:1002E00002050048000000320205009002150020BF
-:1002F000020500940215002002050098000000305D
-:100300000205009C08100000020500A00000003358
-:10031000020500A400000030020500A80000003122
-:10032000020500AC00000002020500B0000000055C
-:10033000020500B400000006020500B8000000023B
-:10034000020500BC00000002020500C00000000021
-:10035000020500C400000005020500C800000002FC
-:10036000020500CC00000002020500D000000002DF
-:10037000020500D400000001020501140000000184
-:100380000205011C0000000102050120000000021E
-:1003900002050204000000010205020C00000040FA
-:1003A00002050210000000400205021C00000020AF
-:1003B00002050220000000130205022400000020B4
-:1003C000060502400000000A04050280002000002B
-:1003D000020500500000000702050054000000075D
-:1003E00002050058000000000205005C0000000843
-:1003F0000605006000000004020500D800000006A9
-:10040000020500E00000000D020500E40000002DE0
-:10041000020500E800000000020500EC00000020DA
-:10042000020500F000000000020500F400000020BA
-:10043000020500F800000000020500FC000000209A
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C0000406100002000020020600DC000000010B
-:1004D000010600D80000000004060200000302200C
-:1004E000020600DC0000000002060068000000B800
-:1004F0000206007800000114010600B800000000A8
-:10050000010600C8000000000206006C000000B8F0
-:100510000206007C00000114010600BC000000007F
-:10052000010600CC0000000007180400007B00005A
-:100530000818076000140223071C00002A1E000090
-:10054000071C800031E60A88071D00001DDD170228
-:10055000081D4470577202250118000000000000B9
-:10056000011800040000000001180008000000004D
-:100570000118000C0000000001180010000000002D
-:100580000118001400000000021800200000000103
-:1005900002180024000000020218002800000003D6
-:1005A0000218002C000000000218003000000004B7
-:1005B000021800340000000102180038000000009A
-:1005C0000218003C00000001021800400000000476
-:1005D000021800440000000002180048000000015A
-:1005E0000218004C00000003021800500000000038
-:1005F0000218005400000001021800580000000416
-:100600000218005C000000000218006000000001F9
-:1006100002180064000000030218006800000000D7
-:100620000218006C000000010218007000000004B5
-:100630000218007400000000021800780000000496
-:100640000218007C00000003061800800000000271
-:10065000021800A400003FFF021800A8000003FFDA
-:1006600002180224000000000218023400000000FA
-:100670000218024C00000000021802E4000000FF13
-:100680000618100000000400021B8BC000000001CF
-:10069000021B800000000034021B80400000001894
-:1006A000021B80800000000C021B80C000000020A4
-:1006B0000C1B83000007A1200A1B830000000138E7
-:1006C0000B1B8300000013880A1B834000000000FE
-:1006D0000C1B8340000001F40B1B8340000000054D
-:1006E000021B83800007A120021B83C0000001F4CD
-:1006F000061A100000000273041A19CC0001022728
-:10070000061A2008000000C8061A20000000000297
-:10071000041A499800040228061A2E280000000234
-:10072000061A2E2000000002061A0800000000022F
-:10073000061A080800000004061A08180000000243
-:10074000041A08B00002022C061A2FD0000000067E
-:10075000041A2FE80002022E041A2FC000040230EF
-:10076000041A300000010234061A300400000003AD
-:10077000041A301000010235061A3014000000037C
-:10078000041A302000010236061A3024000000034B
-:10079000041A303000010237061A3034000000031A
-:1007A000041A304000010238061A304400000003E9
-:1007B000041A305000010239061A305400000003B8
-:1007C000041A30600001023A061A30640000000387
-:1007D000041A30700001023B061A30740000000356
-:1007E000041A30800001023C061A30840000000325
-:1007F000041A30900001023D061A309400000003F4
-:10080000041A30A00001023E061A30A400000003C2
-:10081000041A30B00001023F061A30B40000000391
-:10082000041A30C000010240061A30C40000000360
-:10083000041A30D000010241061A30D4000000032F
-:10084000041A30E000010242061A30E400000003FE
-:10085000041A30F000010243061A30F400000003CD
-:10086000041A310000010244061A3104000000039A
-:10087000041A311000010245061A31140000000369
-:10088000041A312000010246061A31240000000338
-:10089000041A313000010247061A31340000000307
-:1008A000041A314000010248061A314400000003D6
-:1008B000041A315000010249061A315400000003A5
-:1008C000041A31600001024A061A31640000000374
-:1008D000041A31700001024B061A31740000000343
-:1008E000041A31800001024C061A31840000000312
-:1008F000041A31900001024D061A319400000003E1
-:10090000041A31A00001024E061A31A400000003AF
-:10091000041A31B00001024F061A31B4000000037E
-:10092000041A31C000010250061A31C4000000034D
-:10093000041A31D000010251061A31D4000000031C
-:10094000041A31E000010252061A31E400000003EB
-:10095000041A31F000010253061A31F400000003BA
-:10096000041A320000010254061A32040000000387
-:10097000041A321000010255061A32140000000356
-:10098000041A322000010256061A32240000000325
-:10099000041A323000010257061A323400000003F4
-:1009A000041A324000010258061A324400000003C3
-:1009B000041A325000010259061A32540000000392
-:1009C000041A32600001025A061A32640000000361
-:1009D000041A32700001025B061A32740000000330
-:1009E000041A32800001025C061A328400000003FF
-:1009F000041A32900001025D061A329400000003CE
-:100A0000041A32A00001025E061A32A4000000039C
-:100A1000041A32B00001025F061A32B4000000036B
-:100A2000041A32C000010260061A32C4000000033A
-:100A3000041A32D000010261061A32D40000000309
-:100A4000041A32E000010262061A32E400000003D8
-:100A5000041A32F000010263061A32F400000003A7
-:100A6000041A330000010264061A33040000000374
-:100A7000041A331000010265061A33140000000343
-:100A8000041A332000010266061A33240000000312
-:100A9000041A333000010267061A333400000003E1
-:100AA000041A334000010268061A334400000003B0
-:100AB000041A335000010269061A3354000000037F
-:100AC000041A33600001026A061A3364000000034E
-:100AD000041A33700001026B061A3374000000031D
-:100AE000041A33800001026C061A338400000003EC
-:100AF000041A33900001026D061A339400000003BB
-:100B0000041A33A00001026E061A33A40000000389
-:100B1000041A33B00001026F061A33B40000000358
-:100B2000041A33C000010270061A33C40000000327
-:100B3000041A33D000010271061A33D400000003F6
-:100B4000041A33E000010272061A33E400000003C5
-:100B5000041A33F000010273061A33F40000000394
-:100B6000041A340000010274061A34040000000361
-:100B7000041A341000010275061A34140000000330
-:100B8000041A342000010276061A342400000003FF
-:100B9000041A343000010277061A343400000003CE
-:100BA000041A344000010278061A3444000000039D
-:100BB000041A345000010279061A3454000000036C
-:100BC000041A34600001027A061A3464000000033B
-:100BD000041A34700001027B061A3474000000030A
-:100BE000041A34800001027C061A348400000003D9
-:100BF000041A34900001027D061A349400000003A8
-:100C0000041A34A00001027E061A34A40000000376
-:100C1000041A34B00001027F061A34B40000000345
-:100C2000041A34C000010280061A34C40000000314
-:100C3000041A34D000010281061A34D400000003E3
-:100C4000041A34E000010282061A34E400000003B2
-:100C5000041A34F000010283061A34F40000000381
-:100C6000041A350000010284061A3504000000034E
-:100C7000041A351000010285061A3514000000031D
-:100C8000041A352000010286061A352400000003EC
-:100C9000041A353000010287061A353400000003BB
-:100CA000041A354000010288061A3544000000038A
-:100CB000041A355000010289061A35540000000359
-:100CC000041A35600001028A061A35640000000328
-:100CD000041A35700001028B061A357400000003F7
-:100CE000041A35800001028C061A358400000003C6
-:100CF000041A35900001028D061A35940000000395
-:100D0000041A35A00001028E061A35A40000000363
-:100D1000041A35B00001028F061A35B40000000332
-:100D2000041A35C000010290061A35C40000000301
-:100D3000041A35D000010291061A35D400000003D0
-:100D4000041A35E000010292061A35E4000000039F
-:100D5000041A35F000010293061A35F4000000036E
-:100D6000041A360000010294061A3604000000033B
-:100D7000041A361000010295061A3614000000030A
-:100D8000041A362000010296061A362400000003D9
-:100D9000041A363000010297061A363400000003A8
-:100DA000041A364000010298061A36440000000377
-:100DB000041A365000010299061A36540000000346
-:100DC000041A36600001029A061A36640000000315
-:100DD000041A36700001029B061A367400000003E4
-:100DE000041A36800001029C061A368400000003B3
-:100DF000041A36900001029D061A36940000000382
-:100E0000041A36A00001029E061A36A40000000350
-:100E1000041A36B00001029F061A36B4000000031F
-:100E2000041A36C0000102A0061A36C400000003EE
-:100E3000041A36D0000102A1061A36D400000003BD
-:100E4000041A36E0000102A2061A36E4000000038C
-:100E5000041A36F0000102A3061A36F4000000035B
-:100E6000041A3700000102A4061A37040000000328
-:100E7000041A3710000102A5061A371400000003F7
-:100E8000041A3720000102A6061A372400000003C6
-:100E9000041A3730000102A7061A37340000000395
-:100EA000041A3740000102A8061A37440000000364
-:100EB000041A3750000102A9061A37540000000333
-:100EC000041A3760000102AA061A37640000000302
-:100ED000041A3770000102AB061A377400000003D1
-:100EE000041A3780000102AC061A378400000003A0
-:100EF000041A3790000102AD061A3794000000036F
-:100F0000041A37A0000102AE061A37A4000000033D
-:100F1000041A37B0000102AF061A37B4000000030C
-:100F2000041A37C0000102B0061A37C400000003DB
-:100F3000041A37D0000102B1061A37D400000003AA
-:100F4000041A37E0000102B2061A37E40000000379
-:100F5000041A37F0000102B3061A37F40000000348
-:100F6000041A3800000102B4061A38040000000315
-:100F7000041A3810000102B5061A381400000003E4
-:100F8000041A3820000102B6061A382400000003B3
-:100F9000041A3830000102B7061A38340000000382
-:100FA000041A3840000102B8061A38440000000351
-:100FB000041A3850000102B9061A38540000000320
-:100FC000041A3860000102BA061A386400000003EF
-:100FD000041A3870000102BB061A387400000003BE
-:100FE000041A3880000102BC061A3884000000038D
-:100FF000041A3890000102BD061A3894000000035C
-:10100000041A38A0000102BE061A38A4000000032A
-:10101000041A38B0000102BF061A38B400000003F9
-:10102000041A38C0000102C0061A38C400000003C8
-:10103000041A38D0000102C1061A38D40000000397
-:10104000041A38E0000102C2061A38E40000000366
-:10105000041A38F0000102C3061A38F40000000335
-:10106000041A3900000102C4061A39040000000302
-:10107000041A3910000102C5061A391400000003D1
-:10108000041A3920000102C6061A392400000003A0
-:10109000041A3930000102C7061A3934000000036F
-:1010A000041A3940000102C8061A3944000000033E
-:1010B000041A3950000102C9061A3954000000030D
-:1010C000041A3960000102CA061A396400000003DC
-:1010D000041A3970000102CB061A397400000003AB
-:1010E000041A3980000102CC061A3984000000037A
-:1010F000041A3990000102CD061A39940000000349
-:10110000041A39A0000102CE061A39A40000000317
-:10111000041A39B0000102CF061A39B400000003E6
-:10112000041A39C0000102D0061A39C400000003B5
-:10113000041A39D0000102D1061A39D40000000384
-:10114000041A39E0000102D2061A39E40000000353
-:10115000041A39F0000102D3061A39F40000000322
-:10116000041A3A00000102D4061A3A0400000003EF
-:10117000041A3A10000102D5061A3A1400000003BE
-:10118000041A3A20000102D6061A3A24000000038D
-:10119000041A3A30000102D7061A3A34000000035C
-:1011A000041A3A40000102D8061A3A44000000032B
-:1011B000041A3A50000102D9061A3A5400000003FA
-:1011C000041A3A60000102DA061A3A6400000003C9
-:1011D000041A3A70000102DB061A3A740000000398
-:1011E000041A3A80000102DC061A3A840000000367
-:1011F000041A3A90000102DD061A3A940000000336
-:10120000041A3AA0000102DE061A3AA40000000304
-:10121000041A3AB0000102DF061A3AB400000003D3
-:10122000041A3AC0000102E0061A3AC400000003A2
-:10123000041A3AD0000102E1061A3AD40000000371
-:10124000041A3AE0000102E2061A3AE40000000340
-:10125000041A3AF0000102E3061A3AF4000000030F
-:10126000041A3B00000102E4061A3B0400000003DC
-:10127000041A3B10000102E5061A3B1400000003AB
-:10128000041A3B20000102E6061A3B24000000037A
-:10129000041A3B30000102E7061A3B340000000349
-:1012A000041A3B40000102E8061A3B440000000318
-:1012B000041A3B50000102E9061A3B5400000003E7
-:1012C000041A3B60000102EA061A3B6400000003B6
-:1012D000041A3B70000102EB061A3B740000000385
-:1012E000041A3B80000102EC061A3B840000000354
-:1012F000041A3B90000102ED061A3B940000000323
-:10130000041A3BA0000102EE061A3BA400000003F1
-:10131000041A3BB0000102EF061A3BB400000003C0
-:10132000041A3BC0000102F0061A3BC4000000038F
-:10133000041A3BD0000102F1061A3BD4000000035E
-:10134000041A3BE0000102F2061A3BE4000000032D
-:10135000041A3BF0000102F3061A3BF400000003FC
-:10136000041A3C00000102F4061A3C0400000003C9
-:10137000041A3C10000102F5061A3C140000000398
-:10138000041A3C20000102F6061A3C240000000367
-:10139000041A3C30000102F7061A3C340000000336
-:1013A000041A3C40000102F8061A3C440000000305
-:1013B000041A3C50000102F9061A3C5400000003D4
-:1013C000041A3C60000102FA061A3C6400000003A3
-:1013D000041A3C70000102FB061A3C740000000372
-:1013E000041A3C80000102FC061A3C840000000341
-:1013F000041A3C90000102FD061A3C940000000310
-:10140000041A3CA0000102FE061A3CA400000003DE
-:10141000041A3CB0000102FF061A3CB400000003AD
-:10142000041A3CC000010300061A3CC4000000037B
-:10143000041A3CD000010301061A3CD4000000034A
-:10144000041A3CE000010302061A3CE40000000319
-:10145000041A3CF000010303061A3CF400000003E8
-:10146000041A3D0000010304061A3D0400000003B5
-:10147000041A3D1000010305061A3D140000000384
-:10148000041A3D2000010306061A3D240000000353
-:10149000041A3D3000010307061A3D340000000322
-:1014A000041A3D4000010308061A3D4400000003F1
-:1014B000041A3D5000010309061A3D5400000003C0
-:1014C000041A3D600001030A061A3D64000000038F
-:1014D000041A3D700001030B061A3D74000000035E
-:1014E000041A3D800001030C061A3D84000000032D
-:1014F000041A3D900001030D061A3D9400000003FC
-:10150000041A3DA00001030E061A3DA400000003CA
-:10151000041A3DB00001030F061A3DB40000000399
-:10152000041A3DC000010310061A3DC40000000368
-:10153000041A3DD000010311061A3DD40000000337
-:10154000041A3DE000010312061A3DE40000000306
-:10155000041A3DF000010313061A3DF400000003D5
-:10156000041A3E0000010314061A3E0400000003A2
-:10157000041A3E1000010315061A3E140000000371
-:10158000041A3E2000010316061A3E240000000340
-:10159000041A3E3000010317061A3E34000000030F
-:1015A000041A3E4000010318061A3E4400000003DE
-:1015B000041A3E5000010319061A3E5400000003AD
-:1015C000041A3E600001031A061A3E64000000037C
-:1015D000041A3E700001031B061A3E74000000034B
-:1015E000041A3E800001031C061A3E84000000031A
-:1015F000041A3E900001031D061A3E9400000003E9
-:10160000041A3EA00001031E061A3EA400000003B7
-:10161000041A3EB00001031F061A3EB40000000386
-:10162000041A3EC000010320061A3EC40000000355
-:10163000041A3ED000010321061A3ED40000000324
-:10164000041A3EE000010322061A3EE400000003F3
-:10165000041A3EF000010323061A3EF400000003C2
-:10166000041A3F0000010324061A3F04000000038F
-:10167000041A3F1000010325061A3F14000000035E
-:10168000041A3F2000010326061A3F24000000032D
-:10169000041A3F3000010327061A3F3400000003FC
-:1016A000041A3F4000010328061A3F4400000003CB
-:1016B000041A3F5000010329061A3F54000000039A
-:1016C000041A3F600001032A061A3F640000000369
-:1016D000041A3F700001032B061A3F740000000338
-:1016E000041A3F800001032C061A3F840000000307
-:1016F000041A3F900001032D061A3F9400000003D6
-:10170000041A3FA00001032E061A3FA400000003A4
-:10171000041A3FB00001032F061A3FB40000000373
-:10172000041A3FC000010330061A3FC40000000342
-:10173000041A3FD000010331061A3FD40000000311
-:10174000041A3FE000010332061A3FE400000007DC
-:10175000041A4CB000080333061A400000000124AC
-:10176000021A492000000000061A2500000000109F
-:10177000061A258000000012061A09C00000004861
-:10178000061A080000000002061A082000000012D5
-:10179000041A2FB00002033B041A4CF00002033D70
-:1017A000061A500000000004061A449000000124AC
-:1017B000021A492400000000061A2540000000100B
-:1017C000061A25C800000012061A0AE000000048A8
-:1017D000061A081000000002061A0868000000122D
-:1017E000041A2FB80002033F041A4CF80002034108
-:1017F000061A5010000000040200A468000AFFDC72
-:101800000200A280000000010200A294071D29111D
-:101810000200A298000000000200A29C009C042488
-:101820000200A2A0000000000200A2A40000020921
-:101830000200A4FCFF000000020100B4000000014F
-:10184000020100B800000001020100DC00000001FC
-:10185000020101000000000102010104000000017A
-:101860000201007C0030000002010084000000281A
-:101870000201008C000000000201013000000004A1
-:101880000201025C000000010201032800000000C8
-:101890000201055400000030020100C400000001F4
-:1018A000020100CC00000001020100F8000000016C
-:1018B000020100F000000001020100800030000081
-:1018C00002010088000000280201009000000000D2
-:1018D0000201013400000004020102DC00000001EA
-:1018E0000201032C0000000002010564000000302A
-:1018F000020100C800000001020100D00000000148
-:10190000020100FC00000001020100F400000001DF
-:10191000020C100000000028020C200800000A1130
-:10192000020C200C00000A00020C201000000A0427
-:10193000020C201C0000FFFF020C20200000FFFF13
-:10194000020C20240000FFFF020C20280000FFFFF3
-:10195000020C203800000020020C203C0000002176
-:10196000020C204000000022020C20440000002352
-:10197000020C204800000024020C204C000000252E
-:10198000020C205000000026020C2054000000270A
-:10199000020C205800000028020C205C00000029E6
-:1019A000020C20600000002A020C20640000002BC2
-:1019B000020C20680000002C020C206C0000002D9E
-:1019C000020C20700000002E020C20740000002F7A
-:1019D000020C207800000010060C207C0000004F54
-:1019E000020C21B800000001020C21BC0000000123
-:1019F000020C21C000000001020C21C40000000103
-:101A0000020C21C800000001020C21CC00000001E2
-:101A1000020C21D000000001020C21D400000001C2
-:101A2000020C21D800000001020C21DC00000001A2
-:101A3000020C21E000000001020C21E40000000182
-:101A4000020C21E800000001020C21EC0000000162
-:101A5000020C21F000000001020C21F40000000142
-:101A6000020C21F800000001060C21FC0000000F10
-:101A7000020C223807FFFFFF020C223C0000003F4F
-:101A8000020C224007FFFFFF020C22440000000F5F
-:101A9000010C224800000000010C224C0000000054
-:101AA000010C225000000000010C22540000000034
-:101AB000010C225800000000010C225C0000000014
-:101AC000010C226000000000010C226400000000F4
-:101AD000010C226800000000010C226C00000000D4
-:101AE000010C227000000000010C227400000000B4
-:101AF000010C227800000000010C227C0000000094
-:101B0000020C24BC000000010C0C2000000003E8C3
-:101B10000A0C2000000000010B0C20000000000A4D
-:101B2000020C400800000562020C400C0000055148
-:101B3000020C401000000555020C40140000057214
-:101B4000020C401C0000FFFF020C40200000FFFFC1
-:101B5000020C40240000FFFF020C40280000FFFFA1
-:101B6000020C403800000046020C403C0000000C13
-:101B7000060C40400000005E020C41B8000000016D
-:101B8000060C41BC0000001F020C423807FFFFFF9B
-:101B9000020C423C0000003F020C424007FFFFFFE6
-:101BA000020C42440000000F010C424800000000FB
-:101BB000010C424C00000000010C425000000000EB
-:101BC000010C425400000000010C425800000000CB
-:101BD000010C425C00000000010C426000000000AB
-:101BE000010C426400000000010C4268000000008B
-:101BF000010C426C00000000010C4270000000006B
-:101C0000010C427400000000010C4278000000004A
-:101C1000010C427C00000000010C4280000000002A
-:101C2000020C44C0000000010C0C4000000003E85E
-:101C30000A0C4000000000010B0C40000000000AEC
-:101C4000060D400000000A00020D004400000032B2
-:101C5000020D008C02150020020D009002150020DC
-:101C6000020D009408100000020D009800000033DF
-:101C7000020D009C00000002020D00A00000000008
-:101C8000020D00A400000005020D00A800000005E0
-:101C9000060D00AC00000002020D00B400000002BE
-:101CA000020D00B800000003020D00BC000000029D
-:101CB000020D00C000000001020D00C8000000027B
-:101CC000020D00CC00000002020D015C00000001CA
-:101CD000020D016400000001020D01680000000215
-:101CE000020D020400000001020D020C00000020A1
-:101CF000020D021000000040020D0214000000401E
-:101D0000020D022000000003020D02240000001852
-:101D1000060D028000000012040D030000180343AA
-:101D2000060D03600000000C020D004C00000001D5
-:101D3000020D005000000002020D005400000000DF
-:101D4000020D005800000008060D005C00000004B1
-:101D5000020D00C400000004020D0114000000097F
-:101D6000020D011800000029020D011C0000000AEC
-:101D7000020D01200000002A020D012400000000D5
-:101D8000020D012800000020020D012C00000000BF
-:101D9000020D013000000020020D0134000000009F
-:101DA000020D013800000020020D013C000000007F
-:101DB000020D014000000020020D0144000000005F
-:101DC000020D014800000020020D00040000000187
-:101DD000020D000800000001020D000C00000001CF
-:101DE000020D001000000001020D001400000001AF
-:101DF000020D001800000001020D001C000000018F
-:101E0000020D002000000001020D0024000000016E
-:101E1000020D002800000001020D002C000000014E
-:101E2000020D003000000001020D0034000000012E
-:101E3000020D003800000001020D003C000000010E
-:101E4000060E200000000800020E004C00000032C8
-:101E5000020E009402150020020E009802150020C8
-:101E6000020E009C00000030020E00A008100000CE
-:101E7000020E00A400000033020E00A80000003093
-:101E8000020E00AC00000031020E00B000000002A3
-:101E9000020E00B400000004020E00B800000000B2
-:101EA000020E00BC00000002020E00C00000000292
-:101EB000020E00C400000000020E00C80000000274
-:101EC000020E00CC00000007020E00D0000000024D
-:101ED000020E00D400000002020E00D80000000133
-:101EE000020E014400000001020E014C000000013E
-:101EF000020E015000000002020E02040000000168
-:101F0000020E020C00000040020E02100000004011
-:101F1000020E021C00000004020E0220000000203D
-:101F2000020E02240000000E020E02280000001B18
-:101F3000060E030000000012040E0280001B035B6B
-:101F4000060E02EC00000005020E00540000000C1A
-:101F5000020E00580000000C020E005C00000000A1
-:101F6000020E006000000010060E00640000000475
-:101F7000020E00DC00000003020E01100000000F42
-:101F8000020E01140000002F020E011800000000D4
-:101F9000020E011C00000020020E000400000001DF
-:101FA000020E000800000001020E000C00000001FB
-:101FB000020E001000000001020E001400000001DB
-:101FC000020E001800000001020E001C00000001BB
-:101FD000020E002000000001020E0024000000019B
-:101FE000020E002800000001020E002C000000017B
-:101FF000020E003000000001020E0034000000015B
-:10200000020E003800000001020E003C000000013A
-:10201000020E004000000001020E0044000000011A
-:102020000730040000B00000083007680013037692
-:1020300007340000332700000734800032520CCAF6
-:10204000073500001A8C195F083539A058CC037881
-:10205000013000000000000001300004000000001A
-:1020600001300008000000000130000C00000000FA
-:1020700001300010000000000130001400000000DA
-:1020800002300020000000010230002400000002A5
-:1020900002300028000000030230002C0000000085
-:1020A0000230003000000004023000340000000163
-:1020B00002300038000000000230003C0000000147
-:1020C0000230004000000004023000440000000024
-:1020D00002300048000000010230004C0000000304
-:1020E00002300050000000000230005400000001E7
-:1020F00002300058000000040230005C00000000C4
-:1021000002300060000000010230006400000003A3
-:1021100002300068000000000230006C0000000186
-:102120000230007000000004023000740000000063
-:1021300002300078000000040230007C0000000340
-:102140000630008000000002023000A400003FFFC3
-:10215000023000A8000003FF02300224000000004B
-:1021600002300234000000000230024C0000000087
-:10217000023002E40000FFFF0630200000000800EB
-:1021800002338BC000000001023380000000001AFF
-:10219000023380400000004E0233808000000010B7
-:1021A000023380C0000000200C3383000007A12010
-:1021B0000A338300000001380B33830000001388CA
-:1021C0000A338340000000000C338340000001F418
-:1021D0000B33834000000005023383800007A120F9
-:1021E000023383C0000001F406322A88000000C2D6
-:1021F00006322008000000C806322000000000025D
-:10220000063223E80000004004322E580004037A0E
-:10221000063250A000000004063250B80000000250
-:102220000632508000000006043250980002037EFF
-:10223000063250000000002006323000000004008A
-:1022400006321C0000000004043218300002038033
-:10225000063224E8000000B402322DB00000000075
-:1022600006324000000000B40632300000000020BA
-:10227000063231000000002006323200000000204B
-:102280000632330000000020063234000000002037
-:102290000632350000000020063236000000002023
-:1022A000063237000000002006323800000000200F
-:1022B000063239000000002006323A0000000020FB
-:1022C00006323B000000002006323C0000000020E7
-:1022D00006323D000000002006323E0000000020D3
-:1022E00006323F000000002006321C1000000002F1
-:1022F000063245A000000024063227B8000000B4D2
-:1023000002322DB400000000063242D0000000B4BA
-:1023100006323080000000200632318000000020AC
-:102320000632328000000020063233800000002098
-:102330000632348000000020063235800000002084
-:102340000632368000000020063237800000002070
-:10235000063238800000002006323980000000205C
-:1023600006323A800000002006323B800000002048
-:1023700006323C800000002006323D800000002034
-:1023800006323E800000002006323F800000002020
-:1023900006321C20000000020632463000000024F5
-:1023A0000720040000870000082007800010038237
-:1023B0000724000031A500000724800008190C6ADA
-:1023C00008248EB06C9003840120000000000000FF
-:1023D00001200004000000000120000800000000AF
-:1023E0000120000C0000000001200010000000008F
-:1023F0000120001400000000022000200000000165
-:102400000220002400000002022000280000000337
-:102410000220002C00000000022000300000000418
-:1024200002200034000000010220003800000000FB
-:102430000220003C000000010220004000000004D7
-:1024400002200044000000000220004800000001BB
-:102450000220004C00000003022000500000000099
-:102460000220005400000001022000580000000477
-:102470000220005C0000000002200060000000015B
-:102480000220006400000003022000680000000039
-:102490000220006C00000001022000700000000417
-:1024A00002200074000000000220007800000004F8
-:1024B0000220007C000000030620008000000002D3
-:1024C000022000A400003FFF022000A8000003FF3C
-:1024D000022002240000000002200234000000005C
-:1024E0000220024C00000000022002E40000FFFF76
-:1024F000062020000000080002238BC0000000011D
-:10250000022380000000001002238040000000121F
-:102510000223808000000030022380C00000000EF3
-:102520000C2383000007A1200A2383000000013848
-:102530000B238300000013880A238340000000005F
-:102540000C238340000001F40B23834000000005AE
-:10255000022383800007A120022383C0000001F42E
-:10256000062250000000004206222008000000C899
-:10257000062220000000000206224000000000C6E3
-:1025800004224318000503860622432C0000000B9A
-:10259000042243580005038B0622436C0000000B05
-:1025A0000422439800050390062243AC0000000B70
-:1025B000042243D800050395062243EC0000000BDB
-:1025C000042244180005039A0622442C0000000B44
-:1025D000042244580005039F0622446C0000000BAF
-:1025E00004224498000503A4062244AC0000000B1A
-:1025F000042244D8000503A9062244EC0000000B85
-:1026000004224518000503AE0622452C0000000BED
-:1026100004224558000503B30622456C0000000B58
-:1026200004224598000503B8062245AC0000000BC3
-:10263000042245D8000503BD062245EC0000000B2E
-:1026400004224618000503C20622462C0000000B97
-:1026500004224658000503C70622466C0000000B02
-:1026600004224698000503CC062246AC0000000B6D
-:10267000042246D8000503D1062246EC0000000BD8
-:1026800004224718000503D60622472C0000000B41
-:1026900004224758000503DB0622476C0000000BAC
-:1026A00004224798000503E0062247AC0000000B17
-:1026B000042247D8000503E5062247EC0000000B82
-:1026C00004224818000503EA0622482C0000000BEB
-:1026D00004224858000503EF0622486C0000000B56
-:1026E00004224898000503F4062248AC0000000BC1
-:1026F000042248D8000503F9062248EC0000000B2C
-:1027000004224918000503FE0622492C0000000B94
-:1027100004224958000504030622496C0000000BFE
-:102720000422499800050408062249AC0000000B69
-:10273000042249D80005040D062249EC0000000BD4
-:1027400004224A180005041206224A2C0000000B3D
-:1027500004224A580005041706224A6C0000000BA8
-:1027600004224A980005041C06224AAC0000000B13
-:1027700004224AD80005042106224AEC0000000584
-:1027800006224B000000001704224B5C00010426C7
-:1027900006224B600000000304224B6C000104275A
-:1027A000062238000000004006223000000002002F
-:1027B000042251C00004042806221000000000C0BA
-:1027C000062215C00000024004221EC80008042C86
-:1027D0000622390000000008022251180000000003
-:1027E000062251D00000000606221300000000025D
-:1027F00006221410000000300622392000000008D4
-:102800000222511C00000000062251E800000006D0
-:102810000622130800000002062214D00000003037
-:102820000216100000000028021700080000000235
-:102830000217002C000000030217003C00000004F7
-:1028400002170044000000000217004800000002C8
-:102850000217004C0000009002170050000000908A
-:102860000217005400800090021700580810000062
-:10287000021700600000008A021700640000008058
-:1028800002170068000000810217006C0000008041
-:10289000021700700000000602170078000007D041
-:1028A0000217007C0000076C02170038007C10043F
-:1028B000021700040000000F06164024000000026A
-:1028C000021640700000001C0216420800000001C1
-:1028D0000216421000000001021642200000000112
-:1028E00002164228000000010216423000000001DA
-:1028F000021642380000000102164260000000018A
-:102900000C16401C0003D0900A16401C0000009CCE
-:102910000B16401C000009C40216403000000008DD
-:10292000021640340000000C02164038000000106F
-:102930000216404400000020021640000000000182
-:10294000021640D8000000010216400800000001F5
-:102950000216400C000000010216401000000001A9
-:10296000021642400000000002164248000000002B
-:1029700006164270000000020216425000000000DD
-:1029800002164258000000000616428000000002B5
-:1029900002166008000006140216600C0000060013
-:1029A00002166010000006040216601C0000FFFF03
-:1029B000021660200000FFFF021660240000FFFFE7
-:1029C000021660280000FFFF021660380000002099
-:1029D0000216603C00000020061660400000000265
-:1029E00002166048000000230216604C000000241C
-:1029F00002166050000000250216605400000026F8
-:102A000002166058000000270216605C00000029D2
-:102A1000021660600000002A021660640000002BAD
-:102A2000021660680000002C0216606C0000002D89
-:102A30000616607000000012021660B80000000167
-:102A4000021660BC00000001061660C00000003ED7
-:102A5000021661B800000001061661BC0000001FEC
-:102A60000216623807FFFFFF0216623C0000003FBB
-:102A70000216624007FFFFFF021662440000000FCB
-:102A800001166248000000000116624C00000000C0
-:102A900001166250000000000116625400000000A0
-:102AA00001166258000000000116625C0000000080
-:102AB0000116626000000000011662640000000060
-:102AC00001166268000000000116626C0000000040
-:102AD0000116627000000000011662740000000020
-:102AE00001166278000000000116627C0000000000
-:102AF000021664BC000000010C166000000003E830
-:102B00000A166000000000010B1660000000000AB9
-:102B100002168040000000060216804400000005F6
-:102B2000021680480000000A0216804C00000005D2
-:102B30000216805400000002021680CC000000043F
-:102B4000021680D000000004021680D400000004A9
-:102B5000021680D800000004021680DC0000000489
-:102B6000021680E000000004021680E40000000469
-:102B7000021680E800000004021688040000000429
-:102B8000021680300000007C021680340000003DF8
-:102B9000021680380000003F0216803C0000009CB6
-:102BA000021680F000000007061680F40000000501
-:102BB0000216880C010101010216810800000000C4
-:102BC0000216810C000000040216811000000004AF
-:102BD0000216811400000002021688100801200469
-:102BE00002168118000000050216811C0000000575
-:102BF0000216812000000005021681240000000555
-:102C00000216882C200810010216812800000008F6
-:102C10000216812C00000006021681300000000719
-:102C200002168134000000000216883001010120E4
-:102C300006168138000000040216883401010101E3
-:102C400006168148000000040216883801010101BF
-:102C500006168158000000040216883C010101019B
-:102C6000061681680000000302168174000000014E
-:102C7000021688400101010102168178000000015E
-:102C80000216817C00000001021681800000000114
-:102C9000021681840000000102168844010101012E
-:102CA00002168188000000010216818C00000004D9
-:102CB00002168190000000040216819400000002B8
-:102CC00002168848080120040216819800000005B9
-:102CD0000216819C00000005021681A0000000057C
-:102CE000021681A4000000050216881420081001B5
-:102CF000021681A800000008021681AC0000000640
-:102D0000021681B000000007021681B40000000125
-:102D10000216881801010120021681B80000000186
-:102D2000021681BC00000001021681C000000001F3
-:102D3000021681C4000000010216881C0101010175
-:102D4000021681C800000001021681CC00000001BB
-:102D5000021681D000000001021681D4000000019B
-:102D60000216882001010101021681D8000000012D
-:102D7000021681DC00000001021681E00000000163
-:102D8000021681E4000000010216882401010101FD
-:102D9000021681E800000001021681EC000000012B
-:102DA000021681F0000000010216882801010101CD
-:102DB00002168240FFFF003F061682440000000218
-:102DC0000216824CFFFF003F0216825000000100F5
-:102DD000021682540000010006168258000000020C
-:102DE00002168260000000C002168264000000C06B
-:102DF0000216826800001E000216826C00001E008F
-:102E0000021682700000400002168274000040002A
-:102E100002168278000080000216827C000080008A
-:102E2000021682800000200002168284000020002A
-:102E30000616828800000007021682A40000000126
-:102E4000061682A80000000A021681F400000C0891
-:102E5000021681F800000040021681FC000001000B
-:102E600002168200000000200216820400000017F3
-:102E700002168208000000800216820C0000020088
-:102E8000021682100000000002168218FFFF01FFE8
-:102E900002168214FFFF01FF0216823C000000139D
-:102EA000021680900000013F021680600000014081
-:102EB00002168064000001400616806800000002CF
-:102EC00002168070000000C0061680740000000723
-:102ED0000216809C00000048021680A000000048F6
-:102EE000061680A400000002021680AC0000004814
-:102EF000061680B00000000702168238000080002D
-:102F000002168234000025E40216809400007FFF40
-:102F100002168220000000070216821C0000000733
-:102F2000021682280000000002168224FFFFFFFF25
-:102F300002168230000000000216822CFFFFFFFF05
-:102F4000021680EC000000FF0214000000000001E7
-:102F50000214000C000000010214004000000001F7
-:102F60000214004400007FFF0214000C0000000067
-:102F700002140000000000000214006C00000000B9
-:102F800002140004000000010214003000000001DF
-:102F900002140004000000000214005C00000000A5
-:102FA00002140008000000010214003400000001B7
-:102FB000021400080000000002140060000000007D
-:102FC00006028000000020000202005800000032CB
-:102FD000020200A003150020020200A40315002035
-:102FE000020200A801000030020200AC081000003C
-:102FF000020200B000000033020200B40000003002
-:10300000020200B800000031020200BC0000000310
-:10301000020200C000000006020200C4000000031B
-:10302000020200C800000003020200CC00000002FF
-:10303000020200D000000000020200D400000002E2
-:10304000020200DC00000000020200E000000006B6
-:10305000020200E400000004020200E80000000296
-:10306000020200EC00000002020200F00000000179
-:10307000020200FC00000006020201200000000025
-:103080000202013400000002020201B0000000014F
-:103090000202020C00000001020202140000000102
-:1030A00002020218000000020202040400000001F3
-:1030B0000202040C00000040020204100000004064
-:1030C0000202041C00000004020204200000002090
-:1030D0000202042400000002020204280000001F73
-:1030E00006020500000000120402048000200434DF
-:1030F000020200600000000F0202006400000007EE
-:1031000002020068000000000202006C0000000ED5
-:103110000602007000000004020200F40000000437
-:103120000202000400000001020200080000000189
-:103130000202000C00000001020200100000000169
-:103140000202001400000001020200180000000149
-:103150000202001C00000001020200200000000129
-:103160000202002400000001020200280000000109
-:103170000202002C000000010202003000000001E9
-:1031800002020034000000010202003800000001C9
-:103190000202003C000000010202004000000001A9
-:1031A0000202004400000001020200480000000189
-:1031B0000202004C00000001020200500000000169
-:1031C00002020108000000C802020118000000020B
-:1031D000020201C400000000020201CC0000000055
-:1031E000020201D400000002020201DC0000000221
-:1031F000020201E4000000FF020201EC000000FFF7
-:103200000202010C000000C80202011C00000002C2
-:10321000020201C800000000020201D0000000000C
-:10322000020201D800000002020201E000000002D8
-:10323000020201E8000000FF020201F0000000FFAE
-:1032400007280400008D00000828076800130454B4
-:10325000072C000033FC0000072C800038B20D0062
-:10326000072D000039171B2D072D800005D9297364
-:10327000082D8A204EBC04560128000000000000E2
-:1032800001280004000000000128000800000000E0
-:103290000128000C000000000128001000000000C0
-:1032A0000128001400000000022800200000000196
-:1032B0000228002400000002022800280000000369
-:1032C0000228002C0000000002280030000000044A
-:1032D000022800340000000102280038000000002D
-:1032E0000228003C00000001022800400000000409
-:1032F00002280044000000000228004800000001ED
-:103300000228004C000000030228005000000000CA
-:1033100002280054000000010228005800000004A8
-:103320000228005C0000000002280060000000018C
-:10333000022800640000000302280068000000006A
-:103340000228006C00000001022800700000000448
-:103350000228007400000000022800780000000429
-:103360000228007C00000003062800800000000204
-:10337000022800A400003FFF022800A8000003FF6D
-:10338000022802240000000002280234000000008D
-:103390000228024C00000000022802E40000FFFFA7
-:1033A0000628200000000800022B8BC0000000014E
-:1033B000022B800000000000022B8040000000185B
-:1033C000022B80800000000C022B80C000000066F1
-:1033D0000C2B83000007A1200A2B8300000001387A
-:1033E0000B2B8300000013880A2B83400000000091
-:1033F0000C2B8340000001F40B2B834000000005E0
-:10340000022B83800007A120022B83C0000001F45F
-:10341000062A3D4800000004042A3D5800020458D2
-:10342000062A3D6000000006062A30000000004821
-:10343000062A2008000000C8062A2000000000021A
-:10344000062A31280000008E062A33680000000397
-:10345000042A33740001045A062A3A780000000254
-:10346000042A3A800002045B042A3A700002045DD8
-:10347000042A3E280002045F042A3EB000040461CE
-:10348000042A250000020465062A25080000010020
-:10349000062A297000000004042A29600004046739
-:1034A000042A2F480002046B062A3378000000D853
-:1034B000022A3A3800000000062A3A88000000324A
-:1034C000042A3D880010046D062A502000000002E6
-:1034D000062A503000000002062A500000000002B8
-:1034E000062A501000000002022A50B80000000115
-:1034F000062A50480000000E042A3D780002047D90
-:10350000062A3C1800000026022A50400000000055
-:10351000062A36D8000000D8022A3A3C00000000F3
-:10352000062A3B5000000032042A3DC80010047FE8
-:10353000062A502800000002062A50380000000227
-:10354000062A500800000002062A50180000000257
-:10355000022A50BC00000001062A50800000000E24
-:10356000042A3D800002048F062A3CB00000002699
-:10357000022A504400000000021010080000000160
-:103580000210101000000264021010000003D000AE
-:10359000021010040000003D091018000200049100
-:1035A00009101100001006910610114000000008DB
-:1035B00009101160000806A1061011800000000229
-:1035C00009101188000606A9061011A000000018B5
-:1035D000021010100000000006102400000000E09F
-:1035E0000210201C0000000002102020000000013A
-:1035F000021020C0000000010210200400000001A1
-:10360000021020080000000109103C00000506AF70
-:1036100009103C20000506B409103800000506B961
-:1036200002104028000000100210404400003FFF3C
-:103630000210405800280000021040840084924A82
-:1036400006104C000000010002104058000000006D
-:103650000610806800000004021080000000108046
-:1036600006108028000000020210803800000010C0
-:10367000021080400000FFFF021080440000FFFFA6
-:1036800002108050000000000210810000000000C5
-:10369000061081200000000202108008000002B520
-:1036A0000210801000000000061082000000004A96
-:1036B000021081080001FFFF061081400000000297
-:1036C0000210800000001A80061090000000002404
-:1036D000061091200000004A061093700000004A76
-:1036E000061095C00000004A0210800400001080FF
-:1036F00006108030000000020210803C0000001024
-:10370000021080480000FFFF0210804C0000FFFF05
-:10371000021080540000000002108104000000002C
-:1037200006108128000000020210800C000002B583
-:103730000210801400000000061084000000004AFF
-:103740000210810C0001FFFF0610814800000002FA
-:103750000210800400001A800610909000000024DF
-:10376000061092480000004A061094980000004A93
-:10377000061096E80000004A0212049000E383401D
-:103780000212051400003C10021205200000000285
-:1037900002120494FFFFFFFF02120498FFFFFFFFD5
-:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5
-:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95
-:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75
-:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D
-:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D
-:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D
-:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4
-:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC
-:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C
-:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C
-:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C
-:1038500002120500FFFFFFFF02120504FFFFFFFF3A
-:1038600002120508FFFFFFFF0212050CFFFFFFFF1A
-:1038700002120510FFFFFFFF021204D4FFFF3330D6
-:10388000021204D8FFFF3340021204B4F0003000EB
-:1038900002120390000000080212039C00000008BE
-:1038A000061203A000000002021203BC0000000484
-:1038B000021203C400000004021203D00000000042
-:1038C000021203DC000000000212036C0000000181
-:1038D000021203680000003F021201BC0000004019
-:1038E000021201C000001808021201C400000803FF
-:1038F000021201C800000803021201CC00000040BF
-:10390000021201D000000003021201D400000803DB
-:10391000021201D800000803021201DC00000803B3
-:10392000021201E000010003021201E4000008039A
-:10393000021201E800000803021201EC000000037B
-:10394000021201F000000003021201F40000000363
-:10395000021201F800000003021201FC0000000343
-:103960000212020000000003021202040000000321
-:1039700002120208000000030212020C0000000301
-:1039800002120210000000030212021400000003E1
-:1039900002120218000000030212021C00000003C1
-:1039A00002120220000000030212022400000003A1
-:1039B00002120228000024030212022C0000002F31
-:1039C0000212023000000009021202340000001945
-:1039D00002120238000001840212023C000001833E
-:1039E0000212024000000306021202440000001905
-:1039F00002120248000000060212024C00000306F8
-:103A000002120250000003060212025400000306D4
-:103A10000212025800000C860212025C000003062B
-:103A20000212026000000306021202640000000697
-:103A300002120268000000060212026C000000067A
-:103A4000021202700000000602120274000000065A
-:103A500002120278000000060212027C000000063A
-:103A6000021202800000000602120284000000061A
-:103A700002120288000000060212028C00000006FA
-:103A800002120290000000060212029400000006DA
-:103A900002120298000000060212029C00000006BA
-:103AA000021202A000000306021202A4000000138A
-:103AB000021202A800000006021202B00000100468
-:103AC000021202B400001004021203240010644029
-:103AD0000212032800106440021201B0000000012D
-:103AE0000600A000000000160200A06CBF5C0000F1
-:103AF0000200A070FFF51FEF0200A0740000FFFF9E
-:103B00000200A078F00003E00200A07C00000000AA
-:103B10000200A0800000A0000600A08400000005B4
-:103B20000200A0980FE000000600A09C0000001416
-:103B30000200A0EC555400000200A0F05555555568
-:103B40000200A0F4000055550200A0F8F0000000AB
-:103B50000200A0FC555400000200A1005555555527
-:103B60000200A104000055550200A108F000000069
-:103B70000600A22C000000040200A0600000030761
-:103B80000200A10CBF5C00000200A110FFF51FEFB6
-:103B90000200A1140000FFFF0200A118F00003E0E2
-:103BA0000200A11C000000000200A1200000A000F3
-:103BB0000600A124000000050200A1380FE000006B
-:103BC0000600A13C000000140200A18C5554000026
-:103BD0000200A190555555550200A194000055557D
-:103BE0000200A198F00000000200A19C55540000C2
-:103BF0000200A1A0555555550200A1A4000055553D
-:103C00000200A1A8F00000000600A23C0000000491
-:103C10000200A06400000307000000000000000094
-:103C20000000002E00000000000000000000000066
-:103C30000000000000000000000000000000000084
-:103C40000000000000000000000000000000000074
-:103C50000000000000000000000000000000000064
-:103C60000000000000000000000000000000000054
-:103C70000000000000000000002E004D00000000C9
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA00000000000004D008B00000000000000003C
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000008B009000900094009400980000000079
-:103CE00000000000000000000000000000000000D4
-:103CF000000000000000000000000000009802DE4C
-:103D000002DE02E802E802F200000000000000000B
-:103D100000000000000000000000000000000000A3
-:103D20000000000000000000000000000000000093
-:103D30000000000000000000000000000000000083
-:103D40000000000000000000000000000000000073
-:103D50000000000000000000000000000000000063
-:103D60000000000000000000000000000000000053
-:103D70000000000000000000000000000000000043
-:103D80000000000000000000000000000000000033
-:103D90000000000000000000000000000000000023
-:103DA0000000000000000000000000000000000013
-:103DB0000000000000000000000000000000000003
-:103DC00000000000000000000000000000000000F3
-:103DD000000000000000000002F202FA00000000F3
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E000000000000000000000000000000000000B2
-:103E100000000000000000000000000000000000A2
-:103E20000000000000000000000000000000000092
-:103E300002FA02FF02FF030A030A03150000000052
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E60000000000000000000000000000000000052
-:103E70000000000000000000000000000000000042
-:103E80000000000000000000031503160000000001
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB000000000000316035700000000000000008F
-:103EC00000000000000000000000000000000000F2
-:103ED00000000000000000000000000000000000E2
-:103EE0000357037B000000000000000000000000FA
-:103EF00000000000000000000000000000000000C2
-:103F0000000000000000000000000000037B03BB75
-:103F100000000000000000000000000000000000A1
-:103F20000000000000000000000000000000000091
-:103F3000000000000000000003BB03F700000000C9
-:103F40000000000000000000000000000000000071
-:103F50000000000000000000000000000000000061
-:103F60000000000003F7043D043D045204520467BE
-:103F70000000000000000000000000000000000041
-:103F80000000000000000000000000000000000031
-:103F9000046704ED04ED04F204F204F700000000ED
-:103FA0000000000000000000000000000000000011
-:103FB00000000000000000000000000004F704F80A
-:103FC00000000000000000000000000000000000F1
-:103FD00000000000000000000000000000000000E1
-:103FE000000000000000000004F8050A00000000C6
-:103FF00000000000000000000000000000000000C1
-:1040000000000000000000000000000000000000B0
-:1040100000000000050A051F051F052205220525D1
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:1040400005250555000000000000000000000000EC
-:104050000000000000000000000000000000000060
-:10406000000000000000000000000000055505DC15
-:104070000000000000000000000000000000000040
-:104080000000000000000000000000000000000030
-:10409000000000000000000005DC05E305E305E783
-:1040A00005E705EB00000000000000000000000034
-:1040B0000000000000000000000000000000000000
-:1040C0000000000005EB062B062B06330633063BEB
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F000063B068806880695069506A20000000085
-:1041000000000000000000000000000000000000AF
-:1041100000000000000000000000000006A206AE43
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000006AE06B40000000001
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:104170000000000006B406B70000000000000000C8
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A00006B706BD0000000000000000000000008F
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000006BD06BE68
-:1041D00006BE06D006D006E2000000000000000087
-:1041E00000000000000000000000000000000000CF
-:1041F000000000000000000006E2074F0000000081
-:1042000000000000000000000000000000000000AE
-:10421000000000000000000000000000000000009E
-:1042200000000000074F0750075007630763077639
-:10423000000000000000000000000000000000007E
-:10424000000000000000000000000000000000006E
-:10425000000000000000000000000000000000005E
-:10426000000000000000000000000000000000004E
-:10427000000000000000000000000000000000003E
-:10428000000000000000000000000000000000002E
-:10429000000000000000000000000000000000001E
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000000000000000000000000000000000CE
-:1042F00000000000000000000000000000000000BE
-:1043000000000000000000000000000000000000AD
-:10431000000000000000000000000000000000009D
-:10432000000000000000000000000000000000008D
-:1043300000010000000204C00003098000040E40D8
-:1043400000051300000617C000071C80000821406C
-:1043500000092600000A2AC0000B2F80000C344000
-:10436000000D3900000E3DC0000F42800010474094
-:1043700000114C00001250C00013558000145A4028
-:1043800000155F00001663C00017688000186D40BC
-:1043900000197200001A76C0001B7B80001C804050
-:1043A000001D8500001E89C0001F8E800000934004
-:1043B00000002000000040000000600000008000BD
-:1043C0000000A0000000C0000000E00000010000AC
-:1043D0000001200000014000000160000001800099
-:1043E0000001A0000001C0000001E0000002000088
-:1043F0000002200000024000000260000002800075
-:104400000002A0000002C0000002E0000003000063
-:104410000003200000034000000360000003800050
-:104420000003A0000003C0000003E000000400003F
-:10443000000420000004400000046000000480002C
-:104440000004A0000004C0000004E000000500001B
-:104450000005200000054000000560000005800008
-:104460000005A0000005C0000005E00000060000F7
-:1044700000062000000640000006600000068000E4
-:104480000006A0000006C0000006E00000070000D3
-:1044900000072000000740000007600000078000C0
-:1044A0000007A0000007C0000007E00000080000AF
-:1044B000000820000008400000086000000880009C
-:1044C0000008A0000008C0000008E000000900008B
-:1044D0000009200000094000000960000009800078
-:1044E0000009A0000009C0000009E000000A000067
-:1044F000000A2000000A4000000A6000000A800054
-:10450000000AA000000AC000000AE000000B000042
-:10451000000B2000000B4000000B6000000B80002F
-:10452000000BA000000BC000000BE000000C00001E
-:10453000000C2000000C4000000C6000000C80000B
-:10454000000CA000000CC000000CE000000D0000FA
-:10455000000D2000000D4000000D6000000D8000E7
-:10456000000DA000000DC000000DE000000E0000D6
-:10457000000E2000000E4000000E6000000E8000C3
-:10458000000EA000000EC000000EE000000F0000B2
-:10459000000F2000000F4000000F6000000F80009F
-:1045A000000FA000000FC000000FE000001000008E
-:1045B000001020000010400000106000001080007B
-:1045C0000010A0000010C0000010E000001100006A
-:1045D0000011200000114000001160000011800057
-:1045E0000011A0000011C0000011E0000012000046
-:1045F0000012200000124000001260000012800033
-:104600000012A0000012C0000012E0000013000021
-:10461000001320000013400000136000001380000E
-:104620000013A0000013C0000013E00000140000FD
-:1046300000142000001440000014600000148000EA
-:104640000014A0000014C0000014E00000150000D9
-:1046500000152000001540000015600000158000C6
-:104660000015A0000015C0000015E00000160000B5
-:1046700000162000001640000016600000168000A2
-:104680000016A0000016C0000016E0000017000091
-:10469000001720000017400000176000001780007E
-:1046A0000017A0000017C0000017E000001800006D
-:1046B000001820000018400000186000001880005A
-:1046C0000018A0000018C0000018E0000019000049
-:1046D0000019200000194000001960000019800036
-:1046E0000019A0000019C0000019E000001A000025
-:1046F000001A2000001A4000001A6000001A800012
-:10470000001AA000001AC000001AE000001B000000
-:10471000001B2000001B4000001B6000001B8000ED
-:10472000001BA000001BC000001BE000001C0000DC
-:10473000001C2000001C4000001C6000001C8000C9
-:10474000001CA000001CC000001CE000001D0000B8
-:10475000001D2000001D4000001D6000001D8000A5
-:10476000001DA000001DC000001DE000001E000094
-:10477000001E2000001E4000001E6000001E800081
-:10478000001EA000001EC000001EE000001F000070
-:10479000001F2000001F4000001F6000001F80005D
-:1047A000001FA000001FC000001FE000002000004C
-:1047B0000020200000204000002060000020800039
-:1047C0000020A0000020C0000020E0000021000028
-:1047D0000021200000214000002160000021800015
-:1047E0000021A0000021C0000021E0000022000004
-:1047F00000222000002240000022600000228000F1
-:104800000022A0000022C0000022E00000230000DF
-:1048100000232000002340000023600000238000CC
-:104820000023A0000023C0000023E00000240000BB
-:1048300000242000002440000024600000248000A8
-:104840000024A0000024C0000024E0000025000097
-:104850000025200000254000002560000025800084
-:104860000025A0000025C0000025E0000026000073
-:104870000026200000264000002660000026800060
-:104880000026A0000026C0000026E000002700004F
-:10489000002720000027400000276000002780003C
-:1048A0000027A0000027C0000027E000002800002B
-:1048B0000028200000284000002860000028800018
-:1048C0000028A0000028C0000028E0000029000007
-:1048D00000292000002940000029600000298000F4
-:1048E0000029A0000029C0000029E000002A0000E3
-:1048F000002A2000002A4000002A6000002A8000D0
-:10490000002AA000002AC000002AE000002B0000BE
-:10491000002B2000002B4000002B6000002B8000AB
-:10492000002BA000002BC000002BE000002C00009A
-:10493000002C2000002C4000002C6000002C800087
-:10494000002CA000002CC000002CE000002D000076
-:10495000002D2000002D4000002D6000002D800063
-:10496000002DA000002DC000002DE000002E000052
-:10497000002E2000002E4000002E6000002E80003F
-:10498000002EA000002EC000002EE000002F00002E
-:10499000002F2000002F4000002F6000002F80001B
-:1049A000002FA000002FC000002FE000003000000A
-:1049B00000302000003040000030600000308000F7
-:1049C0000030A0000030C0000030E00000310000E6
-:1049D00000312000003140000031600000318000D3
-:1049E0000031A0000031C0000031E00000320000C2
-:1049F00000322000003240000032600000328000AF
-:104A00000032A0000032C0000032E000003300009D
-:104A1000003320000033400000336000003380008A
-:104A20000033A0000033C0000033E0000034000079
-:104A30000034200000344000003460000034800066
-:104A40000034A0000034C0000034E0000035000055
-:104A50000035200000354000003560000035800042
-:104A60000035A0000035C0000035E0000036000031
-:104A7000003620000036400000366000003680001E
-:104A80000036A0000036C0000036E000003700000D
-:104A900000372000003740000037600000378000FA
-:104AA0000037A0000037C0000037E00000380000E9
-:104AB00000382000003840000038600000388000D6
-:104AC0000038A0000038C0000038E00000390000C5
-:104AD00000392000003940000039600000398000B2
-:104AE0000039A0000039C0000039E000003A0000A1
-:104AF000003A2000003A4000003A6000003A80008E
-:104B0000003AA000003AC000003AE000003B00007C
-:104B1000003B2000003B4000003B6000003B800069
-:104B2000003BA000003BC000003BE000003C000058
-:104B3000003C2000003C4000003C6000003C800045
-:104B4000003CA000003CC000003CE000003D000034
-:104B5000003D2000003D4000003D6000003D800021
-:104B6000003DA000003DC000003DE000003E000010
-:104B7000003E2000003E4000003E6000003E8000FD
-:104B8000003EA000003EC000003EE000003F0000EC
-:104B9000003F2000003F4000003F6000003F8000D9
-:104BA000003FA000003FC000003FE000003FE001E8
-:104BB00000000000000001FF0000020000007FF87C
-:104BC00000007FF80000016A0000150000000001ED
-:104BD0000000FF00000000000000FF0000000000D7
-:104BE00000000000140AFF000000000100000000A7
-:104BF00000201001000000000100860000000100FC
-:104C00000000860200008604000086060000860878
-:104C10000000860A0000860C0000860E0000861048
-:104C20000000861200008614000086160000861818
-:104C30000000861A0000861C0000861E00008620E8
-:104C400000008622000086240000862600008628B8
-:104C50000000862A0000862C0000862E0000863088
-:104C60000000863200008634000086360000863858
-:104C70000000863A0000863C0000863E0000864028
-:104C800000008642000086440000864600008648F8
-:104C90000000864A0000864C0000864E00008650C8
-:104CA0000000865200008654000086560000865898
-:104CB0000000865A0000865C0000865E0000866068
-:104CC0000000866200008664000086660000866838
-:104CD0000000866A0000866C0000866E0000867008
-:104CE00000008672000086740000867600008678D8
-:104CF0000000867A0000867C0000867E00008680A8
-:104D00000000868200008684000086860000868877
-:104D10000000868A0000868C0000868E0000869047
-:104D20000000869200008694000086960000869817
-:104D30000000869A0000869C0000869E000086A0E7
-:104D4000000086A2000086A4000086A6000086A8B7
-:104D5000000086AA000086AC000086AE000086B087
-:104D6000000086B2000086B4000086B6000086B857
-:104D7000000086BA000086BC000086BE000086C027
-:104D8000000086C2000086C4000086C6000086C8F7
-:104D9000000086CA000086CC000086CE000086D0C7
-:104DA000000086D2000086D4000086D6000086D897
-:104DB000000086DA000086DC000086DE000086E067
-:104DC000000086E2000086E4000086E6000086E837
-:104DD000000086EA000086EC000086EE000086F007
-:104DE000000086F2000086F4000086F6000086F8D7
-:104DF000000086FA000086FC000086FE00008700A6
-:104E00000000870200008704000087060000870872
-:104E10000000870A0000870C0000870E0000871042
-:104E20000000871200008714000087160000871812
-:104E30000000871A0000871C0000871E00008720E2
-:104E400000008722000087240000872600008728B2
-:104E50000000872A0000872C0000872E0000873082
-:104E60000000873200008734000087360000873852
-:104E70000000873A0000873C0000873E0000874022
-:104E800000008742000087440000874600008748F2
-:104E90000000874A0000874C0000874E00008750C2
-:104EA0000000875200008754000087560000875892
-:104EB0000000875A0000875C0000875E0000876062
-:104EC0000000876200008764000087660000876832
-:104ED0000000876A0000876C0000876E0000877002
-:104EE00000008772000087740000877600008778D2
-:104EF0000000877A0000877C0000877E00008780A2
-:104F00000000878200008784000087860000878871
-:104F10000000878A0000878C0000878E0000879041
-:104F20000000879200008794000087960000879811
-:104F30000000879A0000879C0000879E000087A0E1
-:104F4000000087A2000087A4000087A6000087A8B1
-:104F5000000087AA000087AC000087AE000087B081
-:104F6000000087B2000087B4000087B6000087B851
-:104F7000000087BA000087BC000087BE000087C021
-:104F8000000087C2000087C4000087C6000087C8F1
-:104F9000000087CA000087CC000087CE000087D0C1
-:104FA000000087D2000087D4000087D6000087D891
-:104FB000000087DA000087DC000087DE000087E061
-:104FC000000087E2000087E4000087E6000087E831
-:104FD000000087EA000087EC000087EE000087F001
-:104FE000000087F2000087F4000087F6000087F8D1
-:104FF000000087FA000087FC000087FEFFFFFFFF2C
-:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
-:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399
-:1050200000BEBC20000000000000000500000003DE
-:1050300000BEBC20000000000000000500002000B1
-:10504000000040C000006180000082400000A3001A
-:105050000000C3C00000E4800001054000012600FC
-:10506000000146C000016780000188400001A900DE
-:105070000001C9C00001EA8000020B4000022C00C0
-:1050800000024CC000026D8000028E400002AF00A2
-:105090000002CFC00002F08000001140000080003C
-:1050A000000103800001870000020A8000028E00D8
-:1050B00000031180000395000004188000049C0088
-:1050C00000051F800005A300000626800006AA0038
-:1050D00000072D800007B100000834800008B800E8
-:1050E00000093B800009BF00000A4280000AC60098
-:1050F000000B4980000BCD00000C5080000CD40048
-:10510000000D578000005B0000007FF800007FF872
-:1051100000000166000015000000FF000000000014
-:105120000000FF0000000000000019000000000067
-:1051300000000000FFFFFFFF00007FF800007FF885
-:105140000000035F000035000000FF000FFFFFFFBD
-:105150000000FF000FFFFFFF000000FF0000FF0046
-:105160000FFFFFFF0000FF000FFFFFFF000000FF29
-:105170000000FF000FFFFFFF0000FF000FFFFFFF19
-:10518000000000FF0000FF000FFFFFFF0000FF0016
-:105190000FFFFFFF000000FF0000FF000FFFFFFFF9
-:1051A0000000FF000FFFFFFF000000FF0000FF00F6
-:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9
-:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9
-:1051D000000000FF0000FF000FFFFFFF0000FF00C6
-:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9
-:1051F0000000FF000FFFFFFF000000FF0000FF00A6
-:105200000FFFFFFF0000FF000FFFFFFF000000FF88
-:105210000000FF000FFFFFFF0000FF000FFFFFFF78
-:10522000000000FF0000FF000FFFFFFF0000FF0075
-:105230000FFFFFFF000000FF0000FF000FFFFFFF58
-:105240000000FF000FFFFFFF000000FF0000FF0055
-:105250000FFFFFFF0000FF000FFFFFFF000000FF38
-:105260000000FF000FFFFFFF0000FF000FFFFFFF28
-:10527000000000FF0000FF000FFFFFFF0000FF0025
-:105280000FFFFFFF000000FF0000FF000FFFFFFF08
-:105290000000FF000FFFFFFF000000FF0000FF0005
-:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8
-:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8
-:1052C000000000FF0000FF000FFFFFFF0000FF00D5
-:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8
-:1052E0000000FF000FFFFFFF000000FF0000FF00B5
-:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98
-:105300000000FF000FFFFFFF0000FF000FFFFFFF87
-:10531000000000FF0000FF000FFFFFFF0000FF0084
-:105320000FFFFFFF000000FF0000FF000FFFFFFF67
-:105330000000FF000FFFFFFF000000FF0000FF0064
-:105340000FFFFFFF0000FF000FFFFFFF000000FF47
-:105350000000FF000FFFFFFF0000FF000FFFFFFF37
-:10536000000000FF0000FF000FFFFFFF0000FF0034
-:105370000FFFFFFF000000FF0000FF000FFFFFFF17
-:105380000000FF000FFFFFFF000000FF0000FF0014
-:105390000FFFFFFF0000FF000FFFFFFF000000FFF7
-:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7
-:1053B000000000FF0000FF000FFFFFFF0000FF00E4
-:1053C0000FFFFFFF000000FF000000FF000000FFD4
-:1053D0000000FF00000000000000FF0000000000CF
-:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1054000000001000000020800000310000004180FA
-:1054100000005200000062800000730000008380E2
-:10542000000094000000A4800000B5000000C580CA
-:105430000000D6000000E6800000F70000010780B1
-:105440000001180000012880000139000001498096
-:1054500000015A0000016A8000017B0000018B807E
-:1054600000019C000001AC800001BD000001CD8066
-:105470000001DE000001EE8000000F0000000000CF
-:1054800000007FF800007FF80000021A00003500DD
-:1054900010000000000028AD00010001FFFFFFFF29
-:1054A000FFFFFFFF00220006CCCCCCC17058103C9F
-:1054B000000000000000FF00000000000000FF00EE
-:1054C000000000000000000000000001CCCC020140
-:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1
-:1054E000FFFFFFFF0000FFFF000000000000FFFFC4
-:1054F000000000000000FFFF000000000000FFFFB0
-:10550000000000000000FFFF000000000000FFFF9F
-:10551000000000000000FFFF000000000000FFFF8F
-:1055200000000000000E0000011600D60000FFFF82
-:10553000000000000000FFFF000000000000FFFF6F
-:10554000000000000000FFFF000000000000FFFF5F
-:10555000000000000000FFFF000000000000FFFF4F
-:10556000000000000000FFFF0000000000720000CB
-:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B
-:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F
-:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1
-:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E
-:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C
-:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D
-:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2
-:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6
-:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00
-:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6
-:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7
-:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE
-:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19
-:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E
-:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC
-:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E
-:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D
-:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E
-:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F
-:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D
-:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B
-:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C
-:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1
-:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5
-:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF
-:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5
-:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6
-:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD
-:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19
-:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D
-:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B
-:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D
-:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1
-:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91
-:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1
-:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70
-:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1
-:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F
-:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91
-:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D
-:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71
-:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08
-:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50
-:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0
-:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30
-:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0
-:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10
-:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70
-:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA
-:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C
-:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D
-:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B
-:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29
-:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A
-:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF
-:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3
-:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD
-:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3
-:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90
-:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE
-:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2
-:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE
-:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8
-:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B
-:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB
-:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B
-:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D
-:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A
-:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28
-:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19
-:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE
-:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2
-:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC
-:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2
-:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3
-:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA
-:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82
-:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD
-:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8
-:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A
-:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE
-:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E
-:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE
-:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D
-:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE
-:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C
-:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E
-:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A
-:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E
-:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05
-:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D
-:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD
-:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D
-:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD
-:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D
-:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D
-:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED
-:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D
-:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD
-:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C
-:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD
-:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B
-:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D
-:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29
-:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D
-:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04
-:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C
-:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC
-:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C
-:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC
-:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C
-:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C
-:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC
-:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C
-:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC
-:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B
-:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC
-:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A
-:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C
-:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28
-:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C
-:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03
-:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B
-:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB
-:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B
-:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB
-:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B
-:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B
-:105D7000CDCDCDCD000C0000000700C00002813069
-:105D8000000B81580002021000010230000F024097
-:105D900000010330000C0000000800C00002814038
-:105DA000000B81680002022000010240000702503F
-:105DB000000202C000100000000801000002818003
-:105DC000000B81A80002026000018280000E829810
-:105DD0000008038000028000000B8028000200E021
-:105DE000000101000000811000000118CCCCCCCCD7
-:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3
-:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E2000CCCCCCCC00002000000000000000000022
-:105E30001F8B080000000000000BFB51CFC0F003D7
-:105E40008A5B591918EC39107C7AE0A58C94E95FCB
-:105E5000C3CCC0B019882F00F12E66D2F57F9642D0
-:105E6000B0CF483030BC03E29D620C0C2B2411E211
-:105E7000D1D20C0CFF81FCD350313BA09EDD52945B
-:105E8000B97B140F0E7C471D957F5C15428740C57A
-:105E9000EFA2C99F80CACF5780D0F7D4B19BBB0077
-:105EA0002A0F0001FE3753600300000000000000CD
-:105EB0001F8B080000000000000BED7D0B7454D513
-:105EC000B9F037E735672633939390C704123C83C4
-:105ED00001820618303C54AA93F068E8A53A3C04C5
-:105EE000E447195034822411D39AB6FC7F4EC8E49B
-:105EF0000102C617A52DDA81E2BDD185BDD1466B61
-:105F0000FB6B5710A5B9B5772DA4A8B4451BD06B72
-:105F1000C10237DA72A1FFB2977F7F7BEF939C7348
-:105F20003293876257EF6AC3D2937DCE7E7CFB7B30
-:105F3000EDEF754E141803CA8D0097F0875CD7B942
-:105F40000020BBEF6ADE073556095900154145DFD1
-:105F50004A9EAD17237A7D09B97F85107E0AF0FE2F
-:105F6000B839300940C671790053F17FD300A4CC11
-:105F7000969C988FDC1357A6E3D59CCFBC5648005F
-:105F8000DA547CBE6D5CB2E7BDEB27E49E6E15E88B
-:105F9000CFA53100B5C76F9DFF9AD926FF8D027F2F
-:105FA000D68757935F66C08C4B22C027F98BD23BB4
-:105FB000F5D4F37D54D7A54963012ED42D9FFFDA84
-:105FC000D8FECFD78B50DD5EDCFFFE75A052BC80C3
-:105FD0006A28D1897DFB5E0FD0E9CE0468CEDFCC84
-:105FE000F69B4590752DB9DFF66F9A54D407E77A82
-:105FF00089F49BDA7F3F00069DD79CA7777CA2CBD4
-:1060000036DE39AE773E3E1E24F26F3A00ED42F6A0
-:106010003FCD15BB11EFBBF3171923497BFDFE5292
-:106020008815A786BF975E9F117E735C4A3AF27E01
-:106030009FEC6B6822AC071F2AAD375D47F8E8F785
-:10604000CF89E1CDC847BBC7CF8100B90F8C8F4C3A
-:106050003A9DDED790938C3F52D1E97F8387F29FA0
-:10606000C95F15C2CAF44EF8ECFC7537F2579A8531
-:10607000BFDA170F38DF67E5AFB893BF383ECEB44D
-:10608000B3FDC3AE118C2E9C5E4EFAA4A4CB671D4B
-:10609000D79F9FB6205EDDED8B8D9190849F38BC9D
-:1060A00026BD3E2FBC83F111402BA5334054C4F5CF
-:1060B000FBEEB3ABB7447381409B87711F23F83E5F
-:1060C00046C49AEE13089C7E682D1F1722EDEED56C
-:1060D0000B500EFCC7E79FC66B6371595719E997C0
-:1060E0001ED616CE23576F11B8709F5B70B2EB703F
-:1060F000BE4AA3B418E905B4FD8C7147C4403C40C6
-:10610000042007E06B7C4F00822E91B682BF8E493F
-:10611000B60F053A193E5C97DCFDC7A7DABFD23748
-:106120000E2E85F0FF1B01F737D8385840C6A988D6
-:106130000E83E23BC3314F7A843D37E9E3074B9B43
-:106140003C3F8ABF507CDFF757594F8347549DA887
-:1061500014A550D012D81FB40C89B4BD7388222264
-:10616000678D16EC31047D70BA340294B7FB28C3F6
-:10617000C1427F1F7CA7C145F7135C130F3591798E
-:10618000CF97F8C2943F34F2DFD4FEFB79B00E19FA
-:10619000D9D22EDE0BC8E771C24763C878A3989C9A
-:1061A00087084FE1F39A555FA5B95C9C2F9DFC01D0
-:1061B000BA341DC50C59855C0B858827F0F9F94365
-:1061C00072E071A8FC91B6C0421F183EBD82DC6E21
-:1061D000182A7F7CDEF54CBAF697AB7A4ED71A15A3
-:1061E0007C782E2F4A6A7FA4A6EB2394AEDE4288E9
-:1061F0002492E8E902978BCB8161D337F44AE823F4
-:10620000F692F77E1BBDC4DCE9CBF70C800F31CBD7
-:106210008E0F735E4FADA87F80CA4BD2049C4FC1D6
-:10622000F990CF828F1840CECFF3C8DB041F62EB0A
-:10623000944E6C432150BB8CFC74BA48DB138C2405
-:10624000B68618FF235D4CF8DCBA60C3AF94E5B5A1
-:10625000B561B9E1B2C2EFA955281C0AB511C83C15
-:106260001A9990A042F24127F2ADC9AFC80697AE85
-:10627000C4F6B76C7CD0A24F85647430F915D1CACE
-:10628000F8F55B43D32FCEF596D8E11DF2389FA4E5
-:106290007F683987528F93E043933E048915388194
-:1062A000850F9A6578C93519A0217F29C4C8DD6694
-:1062B0007C44CEB126BCE6211F4ED5E879D9E692C2
-:1062C000104EF35C856026ED37CDA5D3F904B59A61
-:1062D0009EABA22FC2CE57FE3C355C6CFD1CBD357B
-:1062E000A211FCE6426B4420F4914A20DC09A84745
-:1062F00023807C0061C61722B7D3CDF171CECF1EAB
-:10630000384AC713ED6A68F43CB3CBF15C913C2486
-:10631000F36C2982849BD2A955C5B6542401FA0591
-:10632000443FF9F2A6A39EE63FE28230C29F8EE789
-:106330002BF2C72CCEDF2EA2CF089E7D2576F9F654
-:106340003AE45FE2E7713F7D96C29F30AF4EFBEDCE
-:10635000FB2E6EBFA5818FD29B8F075F727BD5B45A
-:10636000DB4CBC660B40F109BF90134F85F8DE484B
-:106370007BE3BB1909DCB751165DDD48F0609C7406
-:10638000851B909E52A4279D3CFFF09F45EA2F65F8
-:106390002FADBD02D7DB5E678C2DB4D883DB25CD56
-:1063A0008B78DE139FAAC62C7AE66688BDE8B2F821
-:1063B0005FA160D3D8C26B28FF9DEC2EC2A3C2455B
-:1063C000F9CFE38B075F47B9E4F77BF1636D8BFD92
-:1063D000DB59B9C0CE4BB8A93442D66D41DD3592F8
-:1063E0003E365C04CE963CD6FE797D4E299E9F2D8E
-:1063F0007ED6FEA4FEFD483DE58B981A25F76A81FE
-:10640000E3A58BE085D25FCF5D3831355D9CFBDF46
-:10641000211DF6E0FE9FF01D993F1ECFCF99421837
-:10642000D1FE44CD116DB5051F2DEEB2B7111FA3DE
-:1064300020E102A45F3C8BCA4F107A7F22D8CEE3C2
-:10644000F2940F8769BFD1D19E52196F2DD75EC5C7
-:106450006B53F0F90C2A4F3047FB90CABFE8BA746F
-:10646000F5D0E53DD57E032E8826B3E7378A9954CB
-:10647000AE022564DF36BD9EAF517EE4F37E0D692A
-:1064800044F6B72783C04484678FDCBA3C9A84BF44
-:106490007FEE1268BF787C5E742DE533761E8CE645
-:1064A000E741E3E2DBC3C80F50A8E7227D242D4675
-:1064B000F5AD84E707E11F398BE915498DB48C27C9
-:1064C000FC1A3A2A8241C6855A33CA54D40F1A504C
-:1064D000FB05D1B96422DB2F9EAF6EC2712897995C
-:1064E000E47AC9B26F087AFBE4750CAEA3D0752EBE
-:1064F00003BDB3846983D37924B497E261968ADEBD
-:10650000979BCEA9C63BE91B7031F9DAD87021629E
-:1065100010FC351D7709222AC5D6424A2F95EBA6D5
-:106520000B724C45BB71CBD704D84BF130B09D12E8
-:1065300077D82992168DB8C8F89115DA5464A15409
-:10654000E3765608E58924F3960B4CEF6FA978A4FF
-:1065500095AABBD7ECFE9EBC3242ED52E2F79523E2
-:106560003DCC719E42C647B08FEC87F49739FF5DF2
-:10657000C85E940E49E4C0BC7E0FE11FDFD71EC584
-:10658000F9CBD9AF5AE4F6D5636C7ED3DEB9903738
-:10659000F0FC267E2E960B7018E1937A3C40E53D88
-:1065A0009BDA61A3391349B5846FC8BA3274D7E353
-:1065B00079B753808AF662BE69D2CFCDE9F3FDFC8C
-:1065C0004F3CD8EF3651A0F08C8AF46C41BD3F6A45
-:1065D0009300E88F548A3ABD9FBBB2FA804CEEB765
-:1065E0003442D8A7E33A6CDE96031E7A5E2A5990AD
-:1065F000F090FE8742399B915EEE3844DCA49FFB0D
-:106600005E2272D82E84844E9ECBB53103E19582F2
-:1066100051746FE060E82EB59BFA2D60E39BA64DA8
-:106620001B55ECD7AC6FEC0AA1DF522851BF45D106
-:10663000AA23945D3F25F830FD0A2217A138740A79
-:106640002554CF277CB483CAE8A67139DA350B3AD2
-:1066500089DCB6647CBD13E133A601954BB403D04D
-:10666000340089D813647CFC4E2DBC15F922CB7004
-:1066700059F97437C4B659F943D2DA297FB4FC45C5
-:106680005C9E4C2FDE2B307C5673BD77414ECC4741
-:10669000BC6EA92772E0EADFFF7A8EFFEF1A8B6EDD
-:1066A0001E4FF5133B7FCCE75D2EDD16AF1C7951F5
-:1066B000A1FB71DA2FF3B8FDD2944FEC178A07587B
-:1066C00080F64A1A277D5318E8737706240C428F08
-:1066D000341E178062667FA8E41FEAB9DCE576BB4A
-:1066E000C5EDB04F52D92DDF7445DBA95E232A09D1
-:1066F000E1DFE56A9D3F0EF19DC7FC46E7BEBBB8F2
-:10670000DF3857DC166A22703D992584DD7A1F3FF9
-:106710001470B978128C1397C83C7BF2059D58C051
-:10672000B0A746A0F6C9799DD9E7F08187F6BF8268
-:10673000C3D2B86911F58B7AF532979B6D75AA4D66
-:10674000BF38AF3EA53596EC5CF273FAA4CD8AD083
-:1067500038872F9CA0E70EEE33993DFE6071993A81
-:10676000909E938A94D5147FF965A725BCCE74FAC0
-:1067700045C9E7755EC16A4F8AA9FB0DF5BA85E088
-:10678000E9A46C9D3FAAE239E121E728CA85274C9C
-:106790008EA4005EB51C84DF130EFBE8B5BBB49C71
-:1067A000DD8F6EC5AB3AABE7F06CEAA74994EE7BA0
-:1067B0005462075AF031490C517CF6E2B750B0ED03
-:1067C0005F95AACB914FD57C01904FD5D8D7BB2EE2
-:1067D000E17C84FE6343C9F848E2FEA99D6FF69010
-:1067E000F30606A0C3E7E58B5F08A69F6CA717FD1D
-:1067F000B1C63D389D7BE9DF2F7EF1B7416F75163D
-:10680000A137E299D09BF9D7DA569433292E50FF5D
-:10681000C7EC77411863A39F74916852E237EF2A5F
-:1068200085A4FAF082A0D0FE443F94882CEEEAC200
-:1068300078E65C71533930B906F4B754E22F50BA98
-:1068400093F550CE9B3FAD5311EF6A4CA1F679976B
-:10685000ABAEB45E1A8E9E6470C16E66978C32CFFA
-:10686000D90D433B672F9043829DB3D5F43C92BA38
-:10687000ABD55202EF15F7B2F3116DB04CD21E4DED
-:10688000CEB7CE501FFF85F83A7271EBE17149CE59
-:10689000A3EFC53F39E046FD950FEC5CAB6D8FA0D3
-:1068A0005EF1E777E2B6F1BC5921127CE5151AA535
-:1068B000B8A591BBE6D17D7C57022A47177061824B
-:1068C0008F9D9B9FA8376611B98B443B0511FD62D4
-:1068D000A07A91D8B9DCAEB3AFFBFD4D4204F1EB29
-:1068E000C910F6A008FAEFED34DC16BD4CD6BD0792
-:1068F000D735CFBFBCC276C0F59D76414A7BE02F2D
-:1069000022F7B3A6D7A3DF950F0CCE873727EAD19E
-:106910004E2C7547EEA7F477F807BDF1251EC75E2C
-:1069200033D314227DD96FC93AF774C9B0159B9F30
-:1069300092DE96F8CE3D780E117DB3869F63774246
-:1069400034800FCF8240E36667E148E01A0B9D1F59
-:106950001215B64E8B7CB2DB12B75DDBCADAA6FE2F
-:10696000B97B97BD7D172CCA9108DEEE7A4C460F95
-:106970000DEE71F8A375A246F9FB6EA86E423C3489
-:10698000CA4C0ED668208D202ED2861F3F311DEDB9
-:10699000FF9D22F36F3E22FCA55BF4CD3A5F42419E
-:1069A0007CBDDF71CDD2EB01C7279A46A2BF9D0106
-:1069B00049CFCD3B5AECF00D06BF135E80CD14DEFF
-:1069C0005470486DAE48327B7A9F69B7727AD5AA07
-:1069D0008149180CB9E06157A30CA87D61BCE74957
-:1069E0003490750E70FB9158429359FEA27A065E60
-:1069F000071B7748D4B93E1FDEB83752ACB741ED1C
-:106A00005690FFAB24A3DC25F4C5A154B93A328AD1
-:106A10006C497EA9B493D8EAD67E2D43EC572E0C50
-:106A2000D0CF09EF694D3584C9FDE1BE1962C75069
-:106A30002E2E08B14AEAFF73B8DD886711AF12A5A0
-:106A4000278D8B84705D5F0BFAD11E5F07B5473CC5
-:106A5000BA64A37795A9078A80C673D28AECCF9DC2
-:106A6000F1923F8866FCBE93CA170D75922D0554AE
-:106A70005FA788F6E14CE94C6F7FB25E25EE6B3282
-:106A8000ED44F54B0DD72F95A03F34AB84CA178D3D
-:106A9000C3D5CC1F63201C35D97A18FD7009C211EB
-:106AA0003A8783AFAA2EBA2061F1ABABA41E05E5ED
-:106AB000A88AE86FEBFD8D4116274EA5B765507586
-:106AC0005F11DAB102C593A891B665DF9FB4BACA67
-:106AD000B91F94BE64007F776390C581D76C199B02
-:106AE000CEE229767D758E9F0F3FDFFF0305FD9770
-:106AF000B3CF9CB809F7B9FEFF8AA09275CFEDF726
-:106B000043273D37120A9E1BEB3AC4A471768006D8
-:106B10009617FF573FA5D7BAE7DD890564FCBA177A
-:106B2000DF9F0404BE739B7B0E8D42FBF919178B0C
-:106B3000771BDD931693FBEB2458154D325FA1C4F0
-:106B4000ECD4333F495B8EF2EB6A3B703B9DB77DE3
-:106B500099ECB69CDFA32499AE4BFA45F0B9F1B499
-:106B60002B3136895F62E619CE3CED62F0BD2453CD
-:106B70003F6F5DDB1E2546E0A86AFB98EA8BD9FFD4
-:106B8000FA6C00F150F59268B3E3AADAC44EF72428
-:106B90007A3D81578C9FBAA6239F707EE9D840E347
-:106BA000A695ED0F7E2C0670BC5D6F11BC843B1169
-:106BB000AFEF88E105D8FED1BF047482AA8F0E3FE3
-:106BC0001540BC9279572BE9189FB7F337CE7F3128
-:106BD000B3FF7C003D348F5BD5BE85ADE7D08B1F06
-:106BE000E12F79FDE3ABFF24D9F3E3D036B4FCED1C
-:106BF000FA67CF3F6990F5CE3CFF87270D02F7BDBE
-:106C0000FFFDC727BF8572F9338F867ABDEA99B732
-:106C10000260E1C3B512D3AFE70A88CB44FA9DFB0B
-:106C2000B53B8106C1B9577E3F5A27FB3DF7DC9F34
-:106C30007374D2BFE695B9B9B8FF9A1766E70E64C8
-:106C4000DF229F26DC56B812747EFD251733165EB0
-:106C5000E657075D0E761C1C8D709E3DE60E635A4E
-:106C6000AE8ADCAB9D8A74DA40CF596C6F22F8ADE6
-:106C7000DCDFFC31EA87FE7836460934A845D4606B
-:106C800010E9FCFE3C4A2FE8A1E7A3B37FD55142AF
-:106C9000C7C9A9E9761E3E5550CF55EDDFC2D67360
-:106CA000D0ED2CFE726D7FBA6D76D0ED3CDCFBFD35
-:106CB0003CCC97778CB0E5077AEDD4DEB878343DDC
-:106CC0003A807E30E57F30BCD2FC09812B2A451EFC
-:106CD00091508E9E4FEBA5EB02A4EBB3E74703E187
-:106CE0008B5372CFED781EF4BCE2D6303EB0EE95F9
-:106CF00077A85C9D7BE14D45A7E718F85CC4AE3CE6
-:106D000007BD3F87D1CEAC643E3E54EDF377BA0366
-:106D10007DF4A94C2C2CD703F4FE097A3FC1F8BDB1
-:106D2000327160892B09BD7E298D61FA3F914DF149
-:106D3000B261DF6F15F0D9E9E89A89743C310FEF41
-:106D4000A7A2A3B97F0DF73FC342CF7D4C4E9DFD57
-:106D50002B893CE279D74BD784EB1D482297E7F685
-:106D6000B8253CEFCEA15D95341FCAEC99E1E64D04
-:106D70000E39E5DACC9B703CA4E60F26DF83ED6F7D
-:106D8000B8F8EB90741B1F99783CF369727D7F9281
-:106D9000EB8B4A30CA475ED9DF0E91206A8C0AF528
-:106DA000C17B061D52C27F679E1169FCA7A9FD2009
-:106DB000D5DB4E3D518971CB24EBFDD15CEFA503B2
-:106DC00093509F9D79F527943F2BF79F50D0BE3F5E
-:106DD000D4F623A5BBB84F1EF03C4858CE83333FB2
-:106DE0003C3089E981E471515A6047E0AC7AD93E80
-:106DF0007FD5FE8F6DF3AF37DAA97D30D83A1F49C2
-:106E00009165B8DF8F0ECBD49FFCA85D4C1A27FE8E
-:106E10000F3C0F2D766DD39BF37E8BF9AD92235EE5
-:106E20001DCFCD8ECD91DCED68AF1D9181E60FA415
-:106E3000C81FDCA4DDF1A657C7BC73C791A5A26E1D
-:106E4000F1437FECC0E78CA3C66C3F996F4637F1E6
-:106E50007FF5FE7A63E671E25759F8A0E6CDF25C61
-:106E6000D4F7E887EAE371BD7010FD5C3130AF9C68
-:106E7000E5A505CD93F4BC66F3C9BE288D4FC99A2C
-:106E800000BA65DE5190A8C73C3AF87CCEBC4354AA
-:106E9000B5E697961F3E802E66D6E297F3709E0069
-:106EA000C4B50FA9FD09E14B03D85FCE3C8389CF60
-:106EB0005EF94B917748D36E0F1E80FEF3F5CFAF8E
-:106EC000C454CCAF34F9D6B4842CF995A660BFFC79
-:106ED0004A4426786871258F478C91CBE6E073E2AF
-:106EE0001DC7923D5F2E333EBF11BAEF5F8D7046D6
-:106EF000599E6696035F5FE2F8FAD964B271A242C6
-:106F00004B41976482DFD94B227199DC9FBBB2E77A
-:106F1000EA5769779EA731C60B97D2868EBFE1E606
-:106F2000E34ADD8B56CBD983E7E352E585FBE030BE
-:106F3000B83F9E69CB4F1C7CF7011AAF97A1BA25C9
-:106F4000648913E5747A208271FE2C9DDA87399D5D
-:106F5000F77C672DC699B3F2C31EE83F8F74F17AB0
-:106F60001ACF30F3F4527E84C6E5254D2F15E93A49
-:106F7000CB2298CF6FD681DA1FCDC181E33553E4A0
-:106F80009881F4942EDE40E715545E5730C47D7E20
-:106F90007B7180E23940F08CF24EFD1FDCDF71170F
-:106FA000CF87771B22E6C34F64D0FC404082228CFF
-:106FB000075C7079C39B43D02F1F9E8A7FB74B8697
-:106FC0004AE3247ABF7CF82ED9124F53311F4E8BDF
-:106FD000F9ECF970D557137C5D47FFC662EF86FA6E
-:106FE000FAF5C99D231F8E73615CC6689E8D764538
-:106FF0007306F0FC38CB8737F37CF8B38DD366A3E8
-:107000009E6DF698CF67B0FE66DBF8F5AB111FAD4D
-:1070100003A1EDD372CF66EC9F350AAA69FD9914DE
-:10702000855B2C7AF0B82CB13A5539F2BC6CAD279F
-:10703000E2FC60E67B0EBEFB7BCA57781D8374279B
-:107040007C8571A99CCED360D5ABE6D5E49F667DE7
-:10705000E0F8AE7C710ACD9398ED40562C1249C2EF
-:107060004757BAD9B963F271200809D4AF8199B1F1
-:10707000EFAC45BE0EFAC26914CE07689DC90E0D6D
-:10708000749AA770EC6387BE91F2EDF92CC2E516F5
-:1070900079E90FFF0D1C7EE61F9FD7781C306840F2
-:1070A0002C097CF2C512BA8F2972E4B7563C665D92
-:1070B00091BCCEF60E85EDA731BA92E5D12BEC79D5
-:1070C0004F4C335BE3A6D35CB153A837CCFCB9A0DB
-:1070D00046797EC330E3EAC1DE78B68EF580F71AD2
-:1070E000A8DFE495ED860BAF592C1F22AAB18FAD16
-:1070F0007C2C69DD4C0E1DF9BDB9E2198A971D8300
-:10710000D06F5B1DCBA76EADD3A8BDBDA52E48DB50
-:10711000CD753ABD36D545E8FDFEFCF4F3E01DC85B
-:10712000473E2FCD270DC6270FD585E97CF1BA99AB
-:107130006C5E97C9EFEE06E4774530E5C74FDB3E5E
-:10714000D1948F2CDADEEE62CFAF514653F931F98C
-:1071500079B0FD8989E994AEC39D3FE57E67F986E4
-:10716000B4DFF44EB6EE50D7713BD6D9314BA57A89
-:107170007947FE20EBB4B27506879FE16BDB81D3C4
-:10718000B45EC04DE4DF43F6E1D62249E5C1949FE9
-:10719000FEF3B8A9DE6ECE62F94FB9D0174165DEB5
-:1071A000ACF37C21916BB47FE4A29C32BC2F87AFFF
-:1071B000A2F5DC72B18FE6E3E4C29C3BB0BDEDC04A
-:1071C00016AD8CEA01819E5FB5D00D58974BC486F1
-:1071D000C663E5C2A2B5D85F43B9247064BA99FF0B
-:1071E00024175E77378E3F30E590DE9085E716E313
-:1071F0003FE8966CFCEF94FB94FA2B68AF5F04E9D0
-:107200004E40BF74DB94BB8AA87CAA967AC62475CC
-:107210007DA63E217A638D62A9E354608E8179D385
-:107220009DB7DE154EE62F91F3749D92DD7F1E73A0
-:107230007C851CDDA0B0BA74B0D7A527CF4737072F
-:10724000CD7C74B58AE7A814ECADA75B9047F0C27B
-:1072500052A9D05B4FE733EBE9C22CDFD54AFE25BC
-:10726000CB4B3BEBC42F573DDD16A5B79EAE00EBD5
-:10727000E97E2A43B813F3EA6F89E1BD7A7FBE73D2
-:10728000CEE77C2FC23C0752C965A762CF87E6C50F
-:10729000ECF950B8D3635BEF359497E2C1F5CBA816
-:1072A0000AFB3C05D5F6FAD72B6A336DED9031D247
-:1072B000D6FFCA9631B6E7635BAFB23D1FBF6BAA7C
-:1072C000AD3D21719DADFFD56D65B6F6C4F6AFD865
-:1072D000FA4F7E6991AD3DA57385ADFF355D6B6C51
-:1072E000CFA71D5E677B3EE3D8465BFBDAEE6FDA25
-:1072F000FAD712F34641B9CDE2F5C259B98235CF7A
-:10730000DA924DCE25E2B7EFC8260C43E3D9ACFEA6
-:107310004A618F7BF380CE7192AE44349AB71F37A7
-:1073200007AF20D5D0F354D273CA747A7FFA3CBC2D
-:107330004289BD0E56D1591D31FA65F67CBFBD1E7E
-:107340005811B7D1B206F7F12F77B926F5A7AB924E
-:107350006F9783A1D613CBBA63DC30E5E28C291793
-:1073600005442E683CED5311FD1E98E3A7F685C534
-:107370003FA27834FDA31B5488A3C968CA45E9CA53
-:107380009E51B48EAFD72F720BC3A95F33E52F6028
-:10739000D1FB91AC3E3DD33C7368FA554C5C63B372
-:1073A0000F9DD786C0BA54FA31E01E403F4E91A3DC
-:1073B000196EF42FA5880196F80B54CB36B8870ABE
-:1073C000E7673D07561386B3EA15134E85E86DCC83
-:1073D0002B352DBE893AF55003363ECD591EA5FEFC
-:1073E00009B10BAF76DBC633FBF06FCD4EFE8D6C73
-:1073F000DFA7692F9B780F84C2B49E04F204407FFC
-:10740000AE69562C88F1B416EC62F10F1F705F491B
-:10741000E7690C2A02D6B93776B1387B835ACDE2B8
-:107420000E72358DBF34640B5AB23AAE3BDD2CBFC1
-:107430002BD63E3876DF007C252AC9E30E0D7C7CF6
-:10744000C3816F74B17352D1D19F06E234BE6FC94C
-:10745000BF8970381A72E13A3BE83A010E57A040F2
-:1074600080FAD0E070DECCFD1DA976CB80704A0892
-:107470006712BA9870C611CE92D470FAB3CB687EF8
-:1074800052AADD46D731F1BACACDE8E584DBC4B7EC
-:107490000C91F2D9D83EF1E5284D8712B223BFEF07
-:1074A00098C9FC66A2D86DFC6AFA2D845FEB915FE7
-:1074B000258DF92FE6FB055F716B0CAF9C8EA067E5
-:1074C000D2B8432016A775E7FE18F3B7FBF40DE317
-:1074D0001BBF1C01EC2FF9049ABF5378BCC2ECF718
-:1074E0009E9BC5891A667547711FCDD74AB019F59D
-:1074F0000FD63763FC2E9FED378EFB22F0FCCC9D20
-:10750000C1F891AFEB8525E9B41052DC1F1C480F80
-:107510007B117F23FAEBE327DDFCBDE03CC863FA77
-:10752000B87819E6A353CDE3B44BCCFAE7E1D7B56D
-:1075300057D33846B36F6317C681CC381C044B92BF
-:10754000C6CDFBF0CAF2897DF45DA67712FA49D365
-:10755000A6523E69CEE7F4AD76D4E99A75DD9CAECD
-:10756000669C1B822CBE63D2D9D38BCFDD03E2D3C2
-:10757000C3E5C689CFAEFFA1F8FC11DA28E4EAF72B
-:10758000B3F7C2E1E03780E68DF2EDF2688E33F9B1
-:10759000DDB9FF536E7EBEFF0FDDBFC90FA9FB1B18
-:1075A00049FD1433FFE9E7FCA6E2DB4D44F1BC3EA4
-:1075B000F364CB955978FE32BFDA3F334EDFAB959B
-:1075C000C1D0502FF8CDFAD912FB7BA0DE62BB9D53
-:1075D000A53AFC1185D72DF57BCF95DB63CEF797C8
-:1075E0007AF1EBA0D7683545FE6A88EFFDECE4F947
-:1075F000B4BC9AD67AF46FF3EE6475F6BB65588521
-:107600007577232B0CC19B85F995D0736964FF793D
-:107610002F3F5C3F0A4972A71E42B3E17BAA6E8BE3
-:10762000EFE7DDDB5AEA65CFA7E03CBB54A677F372
-:10763000CA5B693D59C30BE3D3D16F79EDDD651AA0
-:107640009EF79F6415D2B8EED917DD11CCEF9DCD12
-:10765000840A5AB7F5E28C436897FFA1AE2B53B268
-:10766000F0C9D91FBE395D26443AFBFC9BD3254A9D
-:10767000AC84EDDCDF70E957D3116EA30C8AAA311C
-:10768000BFA629F47D932A95E5B3CC7A9C9D394A0F
-:10769000135E7FE261FA382757D881ED5A0C70A14A
-:1076A0009DC0E3EDD79FD197613D644697ECC27AC8
-:1076B000B9875D86E123D70B271EA6EF5D2B9DD5ED
-:1076C000183621F7C30711E5C658E6675C08415133
-:1076D00088E87DEFE1EAF1D43E76D42399FC2FCD02
-:1076E000061A97E8B9554DEC0D617C58FFF64AB281
-:1076F0005EC34A89D6CB6C970EAB5A123DF68667AD
-:107700008C0DEF7E1E2F3EF8EEDDADA564FCC62984
-:10771000AC8EDA77624A3A2491DFED7533E9FA816B
-:10772000BC93E5A508D6A7E4EEF43EBFC727819138
-:107730004E8E4839241832C18B6F26C0490BDF3575
-:107740000910D1C8F317EB80CED351A7D26B5B9D44
-:1077500036B69018FADFAD0BD2EB63753ABD3E52E8
-:1077600057449F3F5417B6C93DAE77B288B743A977
-:10777000E5F6725FF17DD8931638764E24524FE8C5
-:10778000B593E78B1E2C9E9ABE66807CC3EEBAAE84
-:107790001173C6726411FAE5D7687BB60E00FFEE6E
-:1077A0007AD7AA459837B94F8AEEA5FA3196B7C865
-:1077B000A21F1BE5581E1056BC5FC99C33278FCAF9
-:1077C00023959792C331C03A9BBC60AB0BE3D6794B
-:1077D00047D97DF3FD074A2F22683FCE9AE39251A5
-:1077E0006F16433B82A514C7A08CF49F91BDA414CF
-:1077F000EFC344FBFDE90A936F9CB78C5CA7AAD149
-:107800003615EDA6CC5DC6B3643F7FEA70EB988772
-:1078100079E8D53F2B187F8FFF5A51D18EC97BF95C
-:1078200004AD4B88BBBA156292C11B2D6BE748446F
-:10783000CFC4793E802A16C22771D4B1349EF9FB99
-:10784000F89C627CFF2476DADA7FA737761FB65180
-:10785000F1AA41C2471EB3FF9A78249FB4797DEB09
-:107860001B2DABE3066D93FE53583B4EC6BF9811DC
-:107870001B25107CF9EA57C5BBBE846DB3FFAA383F
-:10788000D6C31E52593D26F8622194B7DEB646DAB9
-:107890007E4B5B626D50D9D5DCEF86837F3E847A68
-:1078A000AEF265573B8246F41EC3FF4B0FD3EF2465
-:1078B000B4D575697199D3DFA40311C90941A07EBC
-:1078C0008A927025C610FD31817F1722AF24A2D77E
-:1078D000A37E4DC861D49B577899DD382141E6B12C
-:1078E000C8D58414DF1FA17959A4E33656D7DB8F9E
-:1078F000BF3CCC9EAF05632BFA0DB05FD668BE903F
-:10790000C71DCF98E71CF73FEFF5B0A6BCD9F05ED6
-:1079100085FA67B544E35AEB43ADA50A5967FD4FB5
-:10792000426172B242A387D51DACCF68CF994AF8A5
-:10793000A431C3DE7E98D7B906338C8CCC62AC0BF5
-:10794000787834E6ED2BA1F5F66F22BCBF64F9C15F
-:10795000D307AE4DBF9EB437FC92C5753774BCA932
-:10796000C4483FC1C3EB093AA67C05F757B94D009F
-:1079700021C4E433329EE039D27A9544F864A27788
-:10798000C45C4F01C0D363229A40F860FED68246A1
-:1079900015DB8A3601E566FED6C246E4ABF513CDAB
-:1079A000EF2414BE1E29E4F54C23719D07E21877DD
-:1079B000DEB7A2FC2B78CCE6084C6E0923D2FC9EE5
-:1079C0009811A779A7FF6C14685C1B53EE9BA66205
-:1079D0003D1D7449E4BA5361F4339AD8FB0CE47E3C
-:1079E0008B3C15E9C2DE1B228E24D5FB635F76D368
-:1079F00038726175E41E6A1768C592F5BD2CE0798E
-:107A0000E32BF03732CF780D4AF1BD80A73D2CFE35
-:107A100057B87CE97A1C27FA977851CE73C4844111
-:107A2000E7FF1E8B3BEF1412EDF81EA31128A4F400
-:107A3000DD19607C613C524CF9629F5076D57D84A3
-:107A40000E8DAED55BFF0DE99A51084857BCBF912A
-:107A5000DCDFC7E929668435A4DF3E4ECF784230AB
-:107A6000B07EC5BCFFA26BCD3D286FB76ED93F4736
-:107A70002578CD71475A47103A2CDFB23F1EBC968D
-:107A8000D2618C4AF0BEDCB33F8E74D8571F19A95F
-:107A900059DAE3FF42AC115A07BE9FCAB394F1C84A
-:107AA0003A9477F2FC3595F0E9D399A6BE60CF0BF6
-:107AB000C7F4EA8F0890B346ACEFD3272A391F0AE0
-:107AC0002DFDE710F9FEE727599DF997C87A28EFB1
-:107AD000641F343FDB33414AA0BFEB25B0A0DDE299
-:107AE0009D3886D6CF917D03DA253D13257ACE9A2F
-:107AF0007169F70481BEE78DFD911FBC05AC3F1194
-:107B00009428EA4D295F02D4EB92B83B3241C7700A
-:107B100030CBBBBAB485F43D514F9125CF0A7D756A
-:107B2000BAB41DA29F97B1B5C7BABBF3046257663A
-:107B30001D5FE81A4DE65BEAE1FE4616B1B7C9FDE6
-:107B4000151E662F3D1035BE8C210DD0BBF3A87ECF
-:107B500082E854BCE6DE56989B2C1FD277AE3BEDF4
-:107B6000EA6E6A3FECF009E5C9EA4F0BBD3CDEE086
-:107B70003B42BFE7510B44FE512ECCF764B9FE30B7
-:107B8000DF1F70D6FB9AFA44CE607BAC995F968B70
-:107B90007A40E2F5439216D6B0FEB1D45F42EDBE14
-:107BA000C7B99E120F5C7B33BE47A1A03E00D45FD5
-:107BB0003103F3FF3D79D08EFC2A052360CDD39AA3
-:107BC000FAA0A94EA5D7A7A68E2B4339796A6A4E8B
-:107BD000994664E0E0A49F7661DEE8FC6E26BFE78C
-:107BE0000FAF35687CC960F122642B1A67EC7C9476
-:107BF000BE27FB0329FA10AD7BC5FA0502D2B60CED
-:107C00007B7DD5082FABA3ADE2F036CAEC79731DAE
-:107C10008B072B17AFA671A9F3FCB93B76277DAF75
-:107C2000C24DCE327CCF5105C360DF196078C0F7FA
-:107C3000986C798B8B93E8F82A0FC3BF59CFE1ACCE
-:107C4000DB30E119CBE1E9FFDE849D1EA6FF65D2A2
-:107C5000C11C5FE38AE46A03F04DD545111296F822
-:107C6000475FFDB542EF9FC3BAF574ACB389B55E0B
-:107C70001F42394850FFC8E3AB01E0DF35A27C1A50
-:107C8000947AAC75E2698EBAF57EF2A2DBDBCEBAED
-:107C90008515C81CD3981EA7F5A6127CC745E87D9C
-:107CA00036EDBDE968D75611F5A062804832345CE4
-:107CB000FF1CB7F7A597EF8B8CD2FBF663C60BCCF6
-:107CC00076E54B0B691CA16A9F8FD6E357A2FE9BFA
-:107CD0008C75FD4697DB56CF1FE9C4FA39F9253676
-:107CE000DFE31C9E3F691579B8EF37B8FF9323C4D3
-:107CF00044F652CA618A87B827720C34A6CF24C2D0
-:107D00001371B3DEC2581B478761A702367B69A790
-:107D100097B5FF73CBDA789C9DB3DC9EF984DA3F8C
-:107D20008D1EB37D96EABB9D4A6B27EA3BE345B7C0
-:107D30008EE717194FDF93365614D173201E8291A8
-:107D40008887D73214AAE7E22FB8F7A29E9BAAC66B
-:107D50000EA916BFE16CC6DBA3D1FF4A329F619B1F
-:107D6000AF6078F391F53B10AFE6F3D73276768AC1
-:107D70006C9C4EBFAB917F78F46AD2CE79D14DDF47
-:107D8000EB31FD4D275F2A5E265F4D8EF7F314948D
-:107D9000371FEADB6A2A67EEA03DAF65CA9D7271A4
-:107DA000822DBEFF383F67152986A14AF2BC983E56
-:107DB000AFE2746DE27506A9D7C94CB1CE35549EB9
-:107DC00053AF339DCB3B703996B4DEEFB10CF01E50
-:107DD0009F33EFE1D453BDF2CAF5D0169C1FE3BA2E
-:107DE000101BE325D77589F6795E3A3A3609EDE03E
-:107DF0005F737FBCA8EDE157F1786E7147EEF24CEE
-:107E0000A3EF657D17AFC39587F95EE0F1947E7AA5
-:107E100088D95777327BB566FE546ADFD56C1FA3CD
-:107E20001903F8491517D36C7A48F0E8FC3B77063C
-:107E3000D547151703F4F9E55BCF637BBFA4FF7A41
-:107E40003EFADC5CEF5E879E3D38E9173B0BC9BA12
-:107E500035CFC982DBB24ECD73BC3EDF43F4AE5D9D
-:107E6000DE2328EF52087ABF4782FA619BC2DBC645
-:107E70008CC639F968D75AF4C34CB4BFFAC6E3F7D5
-:107E8000E5B679CDF19146B487FAF54F73F41F63E7
-:107E9000CE5F4EFB3BE131F50FB6D1DE92FEE2360E
-:107EA000E1A3FAEB61C1315FA6B9FE423A9F69775F
-:107EB0009F6BB9F57543423E6D2D45FFA9672DE8CF
-:107EC000F8DD871F48616FD8C2B7E75466F7575C83
-:107ED000BCD246EF3EBC8FB3DDFF7D5DD0564F7BFD
-:107EE00077AC86D6519F5339BD88654EC7ED1E6568
-:107EF000ABA3FD071C9F158EEB53C071C35F198E9A
-:107F0000904D3EFBE028B4DDFFAC704454A68FE7F3
-:107F1000F1EB5C8DBDD73A5777851BC8ADB9E4BE90
-:107F200087F0FA97C95525D7B912183EFA3DD20401
-:107F3000EB4FDAE8DFDFFC97FB3FB89126AA82B669
-:107F40003A0191D7613BF50EBE77CDEAD854DBF705
-:107F500042CCAB5764F594CEFBDD3C6EF0EDAB2B21
-:107F600001ED6962AB277DAFACD1C7FA811A146C01
-:107F7000716EDE36EB702F175C7FE4E7F4B7AFBEAF
-:107F80000930AE2B215C49FAB573B89AD408CDC339
-:107F9000C5B581BF07F359E191D34C3CDD40F124D5
-:107FA000A6C0D32A1FB72FB418F5939A825F0C3C52
-:107FB000B9BDF00C8C9F6FA43178E0E215948F442A
-:107FC0004EA7265FF2EFDB98F98F26F58B857F723F
-:107FD000DAD0E8BB87F7FBA2E95B3A44FA8E30F9C6
-:107FE0004DFB62E1593C4478AE35F92D18A1F4FA05
-:107FF000A2E0593B44787E6ED24BFF62F1F3C01091
-:10800000E139CBFB29692C3EDB54C4DEF7F08AD181
-:1080100087B0DE6130B9F016DAFD6C35DF6BAFB3D7
-:10802000FAC05EC7956A9FBFE1FB4C254F2BE44425
-:1080300036D2EF581D8B07BCCDFD93DF5434F86961
-:108040007CDEB14E5370AF7FA0B8CDFFAAB0BF3772
-:108050003B981C17A4B1FCCFAD31FBB865CBD31C4A
-:10806000756106FB4E30C75FAAF9FE5EF0361993C4
-:108070009843C01BC1577A6800BFE172E32B95DCBF
-:108080000D175F716D78F81A4CDED722BEA60D1D54
-:108090005FA6BCFEBDE24B1926BEFEDEF9ABF41FA7
-:1080A000F81A16BE160F571EB95DFBF78AAFA1CAA4
-:1080B000A3D36F23FE5D78A0F7FF2F37FE9CEB7FE5
-:1080C0005E3C9AF3AD48E1E7A5C2E7607098D76ED1
-:1080D000EF10F1EAF43FFFDA7875ACFFB9F1CAE7C7
-:1080E0001B365E0781C3BCFE11F13A0CBBAE4D617D
-:1080F000DFF574CE93ED67DF5B1BEFAA3E321FF313
-:10810000C75F15697EFAC8EE391BACF540D97E66AB
-:10811000FF1F299FBD81D65747D368EDD95121FC58
-:10812000EF2598575EC4C639E73FC2F1F55FBE0C34
-:108130001ECFD6B391AE47A38B07944728B7EC8BDD
-:10814000E68D2CF415FBE3FB08E8DB4B300FB12088
-:10815000391C269D53AD3B5CFA1E8DFE6058FA67B4
-:10816000B0FDFE876FA8767A82E2310B7AFFDECD12
-:108170005588CF3681D5C31DC75B79F8DD35A09D05
-:10818000962DCFDD83748AF9595EB043D13760FEF6
-:10819000C4BD78C1837E42B7A3B764B8DC167C5DEA
-:1081A000E3677ED5F495C9FDAE08E783BEF12E18CE
-:1081B0009F84BF27F37EB7AC64DF07032952B0C8A2
-:1081C000F21EE90ABE8EF9DC397EBE3F40C71F4D64
-:1081D000F15EFEF57CFE654B061E0FD5ECFB3B8485
-:1081E000EF0AACEFB1F6F219978FE3BED81C3F81CE
-:1081F000E76D57EC89AF211F4DF0B1F7802408617E
-:10820000FD95394F96049D0AC1FB07B25E8079CD7A
-:1082100024F37C75A07952E1D5DC8FB90E8A227ED9
-:108220004767AECAE28825118059183F7487EF630B
-:10823000F943C60799BC0E7146755AA21EFD5E89A8
-:10824000ECD3026FC7FF9BFD4FF8BCE388A0D1F7CA
-:10825000CF1D78184C3F6CE47C9325C6367B306F7D
-:10826000B2CA95F43B73EBFDECEF0C15F87BEBA574
-:10827000E83AE31E8BC9F87D8AA512CB7F114E2CFC
-:10828000B0FEDD9102CE07CE715922AB37827798CE
-:108290003CB7ED5D57904C7E7EC5E5B4C05F64ABE6
-:1082A000735C12BD4F46F95CB260A1ACFBF0B9CE75
-:1082B000F88DC3D1A6C40AA6F8FAF094520F71FC47
-:1082C000741C8B35E0773956D5BA689D40F126C6C7
-:1082D00077AB361D103690EB1E2E7F0B910696F96C
-:1082E0009EE0746DDBEB1D8DF0B799F91B9C98C077
-:1082F00071FB2EA0F990C7FD1F34613EA4DB053C45
-:10830000FF1B2DC7FC6F37AF6F7B8E3CAF4778E705
-:108310006453F91EB7E9E31AD4CF1D0AD0BF7BF12D
-:10832000BB2DEE04BE4F60F24BAF9ED874A10EEB96
-:10833000871F553A2722DF6437547F2D59FE743F3B
-:10834000A7C39F7CD1F46476A07935F5B9D96F9134
-:10835000A4CBC9FA2F2E779C6B1CEE11EECEB390F6
-:10836000248FD9CB878981EDB4B7B81EFF9523CF71
-:10837000BBE458F23863975FE0F396ADA7E796E168
-:10838000D669CD3487C7C45796C1F0B4748968D311
-:10839000B7AB16A439EC1E86D79BDDFA93B88F478E
-:1083A000F7FE62227D2FCA713E78C59882CFEF8694
-:1083B0004E19F5C42951A7D7B7EBECDFFD7E1B6240
-:1083C000DBA7E1F9592B2695ABF739FFBCBDFC8E35
-:1083D0005B28FC715143F84FAC1C71D34CD42FCBAC
-:1083E000E5F05832EE44FC7EFF5ACBFE7BED1A07D7
-:1083F0005CBFA9B863C0736BD9723BDDDA14661732
-:10840000185F6172780FE1D15994BFBAB7CF20EBF2
-:108410001F49644ED9CABA03FE7DA7C5FCF7534273
-:108420006CC70CA26F4E0B2C4F627C9DE98D258F83
-:10843000451B31757ABAF69A57BA49BF8B7C7FEFE4
-:10844000D50E7C3E3AF969DC63767B6FFA31507069
-:108450007CAC26F979B0554BE37FC72B3C1AF5CBA2
-:108460006D9B92F7FB213233A1EFE9FF162B92C5EA
-:108470002727680CDE55D1E4E327687EF61CCFA5DC
-:108480002478FE2090C6F59C361AF5F4AA14F076EE
-:1084900007D8F9F57EE303B7A11E3825D8F5F39187
-:1084A0000093D7F600E3EFD37B57C8D948A72697A8
-:1084B00086FC7032233C01F96D75FC047DDFE55FBD
-:1084C000020CEE43DEA81E9886F2B2686E36A14B0F
-:1084D000C74A08BBF4D4FABF2860EA7F16AF25E785
-:1084E000DF0778FE91A11F50FB438A8CBE75229D49
-:1084F0009AD6819F168C75B4CE70AF97D595427879
-:108500009AD58E9FCEE13EBD6F78F4BE25EAB0834A
-:10851000FAD97FAD9574DD7D691AD6A51C29173B64
-:108520006F24407EB82F8D7EBFD62917A9D61FAEE7
-:108530001D787ADFF0ECC0C1F6BD32101A921D78BA
-:10854000BEFCD11D2528474AEBA464FAD7D4D347F3
-:1085500079FCDDC93FE6B582F3C5A9C4C070DDBDB5
-:10856000CB0ECF6DD576784C79399568F0AE463C18
-:1085700041E744AB5D0A73A60D72CEB2FC542A38B3
-:108580003705EC7A02390FE9700FD737EFD53E1A6D
-:10859000B0D2C1B9FFD302F70F9E6475B963A3AB24
-:1085A000CBB2F53EFEDCC2E7BFDC7C699E33CE7900
-:1085B000FED6F9D03CE706E3C3AC14799C027C718B
-:1085C000998C5F2D690AE6EB0B023A6B83360F5FDD
-:1085D000D58299E6DF57D147E3FB5FA7F77AE97BBE
-:1085E000C0C6567702BFDB7E6AEFF513ACFBE9E24B
-:1085F000F459B524837E9EE294109E9F4BEBCE44AB
-:10860000FA9DB5B78F65CEC3F6A38705D4D0705B4E
-:10861000CD6A11F7F77A80BDB7B36AD39BD41E1C1D
-:108620002E9FAFAAB69FFF13701FD9163B4BEA29A6
-:1086300041FE49858717100FE8074517CE45FD7C99
-:10864000C72617D5B72FF279EE9022546F439C9D21
-:108650008FA0127C9023E4046E02F1F138FFAE94F7
-:108660001455ACEFC9ADDDF6C05CAC7B75CACB97D9
-:10867000D3199EA6A433BD7DC81B7B2F90DDA79F79
-:108680004FBAAA0FE4922EEB039AF91D5F2AA7E6D0
-:108690007ED673B8889DF62CFDBE30DF1FF438F807
-:1086A0004D68ADFC29E2BF4CA57681D74DF43ED68E
-:1086B00045FFC04BEBA84CB932ED1DE7F8A552CCF5
-:1086C00066377ECAF59ED976DA21FF382F92F71FDA
-:1086D000931E1A929C5EAEF36252FAE5392F04CED5
-:1086E00067CE73A357AE9BD8FB20278E7D32379978
-:1086F0005CDFF819E170CAF3A9BD5EF65DE31BFC0F
-:1087000054EFF4F953B909F4979D7281FE147EC7B2
-:10871000E3D1BD6F4CC4BADE13DB1FB82D193DAFDA
-:10872000D6781D7677AE2D9EB72600B4FE1BC87A8C
-:108730004F59E637C7F5CACB20F1CBA52BAEA5FE26
-:10874000E4DB2BAE1FBDBAB8BF5FD1AFBF2BF6F8CD
-:108750002DB86E3DF7A777B82BF626F303395EFBED
-:10876000C789EDF6FD2D9B4A1BD1A5DE9C76C397EC
-:108770006249D6EFF56B36258FC7FD9F74875F631F
-:1087800010BF86E0A37BA5189859D2E7D7741B5F6A
-:108790008C5FF33BE8F9F71954FE93C3F7643AB3DF
-:1087A000534F29B11DD712F84E13FFC740F911C816
-:1087B00038E497EF26F7D71EE1E37EB76998FAEA27
-:1087C00098DD9F49257FBD707D4EF96B537A0A5025
-:1087D0000FFC6ECFA7EF3E80FBD9E3A5F876CE73F2
-:1087E000A32672FFC24BF9D63C9F3B14A6FF7FF72E
-:1087F000D591F4EF553BE503A0F5A6EBC8F3E37B79
-:108800008529F81DC4B6BD6915C9FC9C159A8BFB5A
-:1088100017F6780F70FBEE16CE6FDADE67AAADF1B1
-:10882000E877B8BE32E300AFA4B37376C982850A95
-:10883000C67BD6F6C69B803A2BDA55F97BF03B52C5
-:108840006FF1F7B98C35FEA4EFC7FD82F3E56071D7
-:1088500088E52BED7182250B063E6F3E4C24AFCB95
-:1088600032F939D57AC33D5FDA12C3CB8B0DB64FDF
-:108870008F36347FE416A8FE12C63B964258C6EBEC
-:1088800012A89EF85382CA0F772DA6F0BC65FEDDB4
-:10889000E14FEF9F68B563FE8BE3FBFC92FBBF8A61
-:1088A000EAF21DA57A62B2F3C919F7792B053ECF1A
-:1088B00070BBE71DA433F2EB5231299DDDDC8F7FC5
-:1088C000672593A3FF0F425212950080000000001D
-:1088D0001F8B080000000000000BDD7D0D7C54D5CF
-:1088E00095F87DF3E62BC924992433934FC2840075
-:1088F0002206984008A80813422428950904080A6B
-:108900003A7C88817CAAD8B25BB74C0860A46E1B05
-:10891000566A5DAB74A0C152C536D1D422A638A028
-:1089200028FEABFF06EBBAB845775017F9924456CC
-:1089300017BBEB963DE7DC7B336F5E6620B6757741
-:108940007F1B7FEDE3BE773FCFF739F7DC3B972EF8
-:10895000C1DF0CC62EE99E8BAA5516B232FABB04B3
-:10896000FFAB9E9B145576D9ED8C3919FBC7A5AD8D
-:1089700089FE22C64E19E065096381C7D4E06E0501
-:10898000CA41FE5EF6E7B22B54FF547041AADF36AF
-:10899000783CF9BCEB5118774C649C65CDD1E386EB
-:1089A00059602D73C038C144FBEE0286FF0C592676
-:1089B00046DA77DA0D340E3B9569602EC6EE936D7C
-:1089C000E38CF7BB0DD0C15583EB571BBD26BB66AF
-:1089D0009E2B52DD8C4D8E94ABE746CF3335C54E82
-:1089E000DF19B3E7FB92193BBD2BD14BF0989E1CCE
-:1089F0001C05F3ACB0B2800DE6F9F093D7BCCF46BE
-:108A0000305625E051EDFBD484F0386DE8DF9C8CC6
-:108A1000EB7ACB60DF0D43951EF39AB4F05B9BA21B
-:108A200050FFA73B2E0FBFB5297C9E0B2AA3E7B7AB
-:108A3000F058625459BFDE7FFE9B072662BFFFFCE1
-:108A400037174DDAFE177D91CB421991F21D358A09
-:108A500037583478DC8E54F390E0DEA183E31D5F59
-:108A6000E453FF0E953577C65897C76EA5FA0B7D70
-:108A7000652627C073E5FD8A47812E8AED6E1A6F41
-:108A8000A591793B613ECCE8CEAF02B83B5B9BEF52
-:108A9000F3C5E8678D9DC3EF339B2FD57E19F8BDD5
-:108AA00023E841D65B64F49B62D55F5C130DDF3035
-:108AB0006395B1E67FFF57A44739BEBEFE50E7512C
-:108AC00097C2F932C312FA84A9F0E21CF453FA15E2
-:108AD000C6D5D5D78FFBD702EEF1C63FFD47B536D9
-:108AE000161CF60AF8FB7D403F31BF27D3F7B75875
-:108AF0007BE37EE2EF24CF6E0443C7CAEF01DAD9ED
-:108B0000EA39F7BD0AAFD91F920B68FCA5BEA315C1
-:108B10000856F6E5C3E311EF9F573EFCBD1298DA05
-:108B200069B3BF35191A9CDEA87802EEC1E3BC8593
-:108B3000EBB430F6F6062BADF70FD096F0330BFE04
-:108B40002F9BB131AAB70E850AFBB6C5BD5BC3B773
-:108B50008EF51737B0F18CED31FB36E21446DFFFAE
-:108B6000E93A86328F0569DE1F983C6B08DE8C116E
-:108B7000DF1FDF65DBB915EAFD3199E3032839DF33
-:108B8000374E23278C762A0F153FBF8B839FAF2A42
-:108B9000A7E43AE38D0390A7F9CE9F696B5352196E
-:108BA000EB36BBEFC4F5F4CF49B0EF0214CE377B00
-:108BB0006F46F8BC75D4606829A06E8D48A70BF885
-:108BC00010ACE09682EF8E2D41F963F226C054AAD4
-:108BD000A00DBB16E868A62D80FD95FC6EEED3882F
-:108BE0009F876B2C6E15FB9BEE7E4F85F2FC9B2CBA
-:108BF000EE8DD05F69EF88830EE87FE15CC5CEA083
-:108C0000FDAC39A39C61585FD27AE82707A7F79D8E
-:108C1000CAF2918C3D85835DC7F8840116F3155126
-:108C20000E3CD5360BE4C15867B7C106A05EB8ED5F
-:108C3000A9362BF4BBB9C597654F83C9A6B5B459FE
-:108C400087813E72797B6778189B9AD65A69BD01F5
-:108C5000D6F998EC6F539B378FB1170DFE0205BE06
-:108C6000DF91F644A511E6EF2894E377D2F7453774
-:108C7000ADD9BD0EFADFBCED50A511E7BD548EFF96
-:108C80005A65B911C69D26CB6F58B1EC4812ED71EB
-:108C9000BE5319338D88CCDF9805E3A7CBFABD9579
-:108CA000B3A0ED3B65CDE54618FFDD6DEFB41525AE
-:108CB0003036656E99DD0BE5F7D3CE5726017EBAC7
-:108CC00019D029943F48EBA7F93B5483E8FFD336EA
-:108CD000EF349C4F602C7E57029FB5551633D660FB
-:108CE0000DBF8AE4DAB43E6075C13F262B9C4EACC2
-:108CF000A6666F2EC0CEB4AF2C944BD369E7F4991F
-:108D0000171A877A6CA03C06CAE334E52C5EEEDEC7
-:108D1000C8EE88256F83E95CEE7527C6FE3E318D6F
-:108D2000CB03801BE993D463CCBB37865EC94EB3BB
-:108D3000513F871359C09A1EE1B779C0C353812FA1
-:108D40009995CF53F633487FA4713DCB02F3D2916E
-:108D50006FE66217B0F4428F1240BA66CD49C15136
-:108D6000483B2C645C80FA4335D07C9DAA72471541
-:108D7000F4E74A64FE2E783A331895A1BDB7CB16B6
-:108D8000E9EF0D41F71585BE0EECAF2233BBB8B548
-:108D900020D20FCC7B937562D4BC8D53D3F1FBFCF6
-:108DA000E2BB8B34F02CE2EB003AA07630CCD3332C
-:108DB000800FBA7BC78ED80AF3FB5027774B7BE72F
-:108DC0009B18D4DB9C2EE4899BB7779673F9D37FED
-:108DD00077527017F2A7D5538C7892EDE60AB897C0
-:108DE0003F30F78758AFBED7C42C506F5D57592618
-:108DF000BB8C5EACFFE27A169CA4291B4366943BB5
-:108E0000F55F4CA7F7E50FBC61463EC57EDCB0AE12
-:108E10007509DE4C0FC2AD3536FE196BA179D47FD2
-:108E200091C60293B4EF399C22FD3BE8FB95D61521
-:108E3000E94F65C18CCBF567A6EF0370370AB89B85
-:108E400063CFF35E49A7006F8386BE160A7A03E9F3
-:108E5000E7457978FC96A25D28EF23E36EA476DDE2
-:108E600046C023DA81BD896EB48B4B8D5C7E96F64D
-:108E7000A6DB034A843E245D48BC76A73797D17AA7
-:108E8000AB14FBAE82C1F3FA6B392FA14F3397FAC3
-:108E9000D5E59AF9497E80FEBB45FF2553897F9E23
-:108EA000E0FC007CB30CF917ED165C8727346E7E6E
-:108EB000F2E0F97F0CE485F5018F1CFEDFB005516F
-:108EC0000F48B80D867FEE15F0994FDF4B7B0F9959
-:108ED000719DF571F8F6DBE929346EE6B1508A1B15
-:108EE000EA9DB57379D5DD3929E17AE48BB9068637
-:108EF000220CD78DF66AE980BCBDE1F599A01F323E
-:108F00006519E5AD1BF130207F43566BA47EC3DFAE
-:108F1000DD306713D4775800FF4564875A99C69FA0
-:108F2000F8591A976353FD2CA6DDD2929E4CDF258B
-:108F3000BCFF7E7D39FB10D6F7AF76CE9753C301C9
-:108F400005F122F95A2FA78E083C1EFE1F9353CA23
-:108F500015E454959053FCFD6130F3B19ECB151A86
-:108F6000A7804E5CF1FAA451E8CFDC93A5BA3F028A
-:108F7000BE5AA078863D03FD565BDD9B93DD113A1A
-:108F8000A96656B70DE10E46D325D4FB7313A88C02
-:108F90007F68975C6857381D32776AF5B8F8724871
-:108FA000CEE39E2C338DB7E2C151A97EEDFC849EA9
-:108FB0009867093DC30A07F3B92CC3FC1B0CAAE64A
-:108FC000BB8DEBB3AC64EF87698087B7145643F36E
-:108FD000D1D94BFF21FC36BDBDB449D8914E342FB9
-:108FE000898F0DE49C66B659828C3709A09F9AD967
-:108FF000C904BF860CF51A3AB8989647F358BA18C0
-:109000003E4E00A6B4BE3CE1230D1F1DC1F9905E8B
-:10901000084D463E05B119358FA5AA2F4F41BB35E6
-:10902000D3E24139037822381C4E60C60418F73564
-:109030007822DE2AD4BB0F9A1C48078AA795A0BFC6
-:1090400053D8A72C84FA66DE8C24B25BD997F78EAE
-:10905000AC0278389338DD423F56D18F95E844C84A
-:10906000BDDFE65FBD0BF593949F120FEC4B95FAB5
-:1090700093DF0F2B557976281F765E55DCAA44DBEB
-:109080003F680F45ECA7C40767033F4EA9EC0C19D6
-:10909000EC285592E77C0BED70B09F12603D19E90A
-:1090A0005C0E1C2E08A829D8DF285807BC7A35D1B9
-:1090B0005FD46C8BE0036C1C3FE2CF6586A78DF319
-:1090C000073EBBD23932AECFE0CFCDE2E94AE1F57F
-:1090D000F5F4F6830CCE9F6B150EEFAD655C4EE894
-:1090E000EB8D17FD36580395AE115AFBCAC7900E8B
-:1090F0008D8CDB5913D2059D947378953FB0341550
-:10910000F5E6E7BD0B535951448E6E56FC760FD4ED
-:10911000DF6CF27D9FE21DFFA032F447CC697E7BBD
-:109120003AD4CB488AED2F57A7F3F966A03F0DF547
-:10913000BE27FC1DD317D7909F7D23DA65F03D2510
-:10914000AB9AE439C2D00DFDA6B2FE805D83BFD4D8
-:10915000A98628BFC1F4C5786AFFD5ED86E23876C6
-:10916000434994DD20C7D5DB0FEF6DC8A2F9CBF6DC
-:10917000CBB2DEAE609AFAB7B3F066ECEFF675B933
-:109180005171A27876C75A8127B4130231E7658EF0
-:109190007AFF1EF88901EDF8A7F8F891719380D154
-:1091A00022E34E48F7D6A5133F4DB39FBC061E6081
-:1091B000BB5F5249DF90DC07BDE4DD69237D548944
-:1091C000F25AFA47C8F7F654E4EBB27BD3276BF4B4
-:1091D000A368A797439F087FFA13A167528F497B23
-:1091E00031D1AD28117D33585F093DA3938B57B220
-:1091F000AF815E035AFDAFEFF787E97FAA5D59188B
-:10920000873E46FFB7D895A5D3FCEA38949B950ACC
-:109210001B058F29B3A2F5FCD3E9DCFF783A3D2981
-:10922000CA5F99BF34BADE2FB0DE647C260DC95FF9
-:10923000D1EA21454579C7FB6B14F45070E62DB394
-:109240001BE4EF19B483A0DED10CEFF348579B1257
-:1092500053C6A37ED8F99FE56376C2BCFBDF3479A1
-:10926000766177FB387D942D59D76A84F7A64EC571
-:109270006E6191F9D9D6774D5805EB3D28F054EF42
-:10928000E0EBA87784CC2361DC9C7A3E7E5EE741EC
-:10929000C5A8916F79B5BCDE6FD24D51FAE6B758CB
-:1092A000867EDE94FE070BB65494607DAF712B88EA
-:1092B000BE9C4E85E2C139CD0000A0831C0FEFDFBC
-:1092C000E6092A2B8B22EB6C335415A15E687325BB
-:1092D00079502F6439FCFF80EBAC3F1E0A2198A621
-:1092E0001CEF35A27D37D1E17D87F84AACD3ADDAEA
-:1092F0007350AE261DE7F36BD7D13B63DF15F3DA6E
-:10930000C5E5ADCA8E30C407CA0E18CFB5710CE9D9
-:109310002559DF952EF4848BF99F25BB8AB531C280
-:1093200017A375B8368E26FB5EE23362475D3D11AA
-:10933000EDA8C28742C615D06EFFE386CA5876E212
-:109340006702EEB08E3EED3AE2F185D463B29E291B
-:109350008E1F2DE93DA932B67D0A1A80BE972D7168
-:10936000DC8AEBAEDF6466162502FF890E9F21C3FF
-:1093700089F8DAA9206C247D6D4A7F4AC985F5DD1C
-:10938000BB86D955167FBEF5EB9F9BB04AE36F4174
-:10939000FF848F9D6656ABD5A7D29FC8C9E0F6F46F
-:1093A0006A872F0DC76DDCB7CD8CF85DD371C2AC69
-:1093B0008D770F5AC710E1A5D4723FA5BEC61AC457
-:1093C00075962D3112FEEA369983288FEAF7768555
-:1093D0000C684FDFCF3CC8EFF59D5DAFE6005C72D7
-:1093E000EBBD935577A4BFDCFAA082F3710111F6AF
-:1093F000929F1732A37ED6D335DAC36897BC9AC042
-:10940000F9FD5C992DA000FCCE99FCF558EF5C7637
-:109410009227501081F76B5DB38F28C0D2C9CF5A05
-:1094200042F86C33ECCAB242BDB6B1660FD2D14439
-:1094300087BF3403E0946EF47563FB3447B2A7052D
-:10944000DABA2D6C22E9E721C2618A8E1EA6DCCF32
-:10945000F9A4362345DA7B13510EF93278DC156313
-:1094600042289F5E35F1756C627CBE5DE9DE0AC400
-:1094700013B3A7D3B839F52105ED7DFDB8117AF204
-:10948000DE9CF115E81BEC3C33CAF53A2167CA961D
-:1094900074281F6AE8E0563064B05ECEDE9D0AFA9A
-:1094A00081F0BDA5C241F59905E5CC5EBE1F51070F
-:1094B000DFEFD4C815B98E18F26539C2D776BCF77C
-:1094C000152E5F42447F72BE7A7C3664B869FC1BFD
-:1094D000C12CA0F7E6C01837F4F7EA8844EA4FF247
-:1094E000BB9E3F1B049DE7D474281837702471BBC2
-:1094F00051CE4FD63B9A31F36E9CCF94CA5E8243D5
-:10950000438D91F026E75361F68D44FF6B83E8EFBE
-:10951000D0E2F7CD61286FFFD551A2C78676C54B43
-:109520007E41FB51F3428CCF057EA6623CF6666E0F
-:1095300092B0477E7994F4C8CDDD3C4ED0D0DD6545
-:109540005C698BD069C19943B7239D35745A5882A1
-:1095500082F8E376AB9E4E41BE10DDB38099F6B340
-:10956000403E06489E327F01FA2352FE7689B81F9C
-:10957000B3F1F77F27E62DFB8DC8CD04A2F7823328
-:10958000130F59019E0D1EC503A612D8DBBC1EF495
-:109590001F22F9CBD808F4CB64FF7AF81D10F679B6
-:1095A0000C3CEF40B8EAF588D4AB053B66327C4A08
-:1095B000FC1905DC65BFCF6498A9DF67328CDCBF7E
-:1095C0002BE3F1EB4D26AE3F36B55883C8D7AFA598
-:1095D000DD7844190F704A3787F079D8B0A21EBFE2
-:1095E0001FCEE1F368336C1CD3CCF5D7CF713E8727
-:1095F00016A7302E9FB83CDAFE1C9727F5011BF901
-:1096000089F5FEEA55B4FFE048F0A0BDCFFCAF9865
-:10961000172647E8418F5FF7B307CD6EF87E7327B3
-:10962000E78308DCB89E92740B728EF0DE952EF7FD
-:1096300023FC050857F0DF5B30CE20FDF794A5BE74
-:1096400040B27B30BF6608FF7DB2F0DF4D53AD7F87
-:1096500051FFBD6EFD6FB2B1BC36EB757A4A7E012B
-:109660003F318AAF7E2FF01D12CF0F04BDD4957409
-:10967000123FD47DD44C7C64ABE4F2C4763C5A0EE9
-:1096800032F6B7C22E7888E05091D479A38AFEF0E2
-:109690008F157B2B8B3FEFBB94E6FF7F2DE2A54B15
-:1096A000A57D29F62558F5A500D704010351EF3310
-:1096B00041EFE7F60022902F8DCDE6CBD9BF57EAD8
-:1096C0009785DE5610DF7502D6E7F6965FFB2F18FA
-:1096D0004FDC93EA19054B3FBB77C15FFD0BB43FED
-:1096E000D731C3837ADAD1EA23FAE9772678306E64
-:1096F000E850C1B2057A68E97C39E57ADC177B7AF3
-:10970000C244949B490EEE079E794E5D8FF0D9F8C6
-:10971000D35F4CC7EF75412503EDC6737B7EFC47D5
-:10972000D48BB51D4DE869B0D6A75F223BDC10DCB9
-:10973000C9DFEF4925FBF2F44FB64D47B8B776B60F
-:10974000D2F7333FD949E5433FFDC5817F477BC30E
-:1097500097E2C17A679EDBF69D7F473AAF4EF1E014
-:109760003AEAFD46BE6F2BE95B2FB7BA0E129F4A4D
-:109770007AB919F52EC2A986CB1F49CF1F887DA5BE
-:1097800015E5B63694671F6C4DAE8D154F9C20D6EF
-:109790008B31179263350AC5D3DA806A30AED19621
-:1097A000C8A6E233A92864CE8571162FED9A4E76AD
-:1097B0004FE0C46AACBF605F02DB4AF1370CDE8267
-:1097C000FD4FA4CED838108327C14F86DE3B2E81B3
-:1097D0007DFD0EC807D23B3AFB7F41DBEB7F403972
-:1097E0005A6D0D1F74BA23EFDB449C06EA93DE2901
-:1097F0005D173B1E3AC561137CCBF5664E77559ECF
-:109800009BE484C5334A63970E3BD6BC15C410CB8A
-:10981000A9EDBD11D771D398E593882E30CE87FA84
-:109820002760A3FE1B304E097C56E910F10F3B73F5
-:109830005C07E3571899C3864FC6DE36911CD94D95
-:10984000FD82FD417695FBA5C5BBD11E79C4E4CF51
-:109850009E8CFDB409BDD5C1E70DEDEDB85F0AFDE5
-:10986000D9AF9B48FDF49AD2A97D80B79FDDD1A2E4
-:1098700044E60B949A8F7A0BFB2BB1A19E09D4106E
-:109880007EDC665AD719AC924DEB1EBF6C5C847FB0
-:10989000F5F11D9467B80FBCDA51B6DCE18C3C657C
-:1098A000DC470FCFDDE2FB470EEF7207CE634F467A
-:1098B000945E8967AF1C5A7C9EEBDF174F90BC69A2
-:1098C000443AC6F1FD1F45E9DF95928E5F38417439
-:1098D000BC721FD7BF8DFB8ACD48B7673778D98751
-:1098E0006080368A7DD64794F06A8AF3BC9060C760
-:1098F000F8DD79A16FEA1E3A7112F74747ECCB26E3
-:10990000BFFEFC0B0935D8CF618381E07978D7356C
-:109910003B5B15ED3CB93F007630916A23D8A9DC5A
-:109920000E5EB50DFDB3865AE641FE6FD4D14FE30E
-:10993000BEA3442FD20E2ED8317F15B73F133C095A
-:10994000E8BFCDE2F628037B14EBA7CD0AB69889D1
-:10995000BE8A4B91BE0E2D3EB005F578E32C66C74E
-:10996000FE1F19E67D2197D6A330CC6779C4D43E7B
-:10997000D308ED1FA970DB019200B70EB27BD91896
-:10998000B3D073ABC85E6ECCBACD437CA697072F1D
-:10999000B490DDD5E84EA4F9DCBC4FB987DB2336A3
-:1099A000C6E7AF107DDE1CBC3E88FBCA9F08F849A5
-:1099B000389E37F5DE8EF038FF4B2044F87EF32CCE
-:1099C0004EAF69B33A498EBCF6C26CD2E3922E9385
-:1099D0009FB7903E4F37DA150FE9B505162D5EDBC0
-:1099E0004D5C2FA5093D53F810C7EF2F043FFDC272
-:1099F00061104FB3A073116FB107C6A3DEFD44E041
-:109A00009FC408CA77214F1A5685889FEAF7F2FE4D
-:109A10001C166FF1BD1AFA759473BD28E3FEB80FDA
-:109A20005015435EBC2DE651B063C536B4976F0246
-:109A3000BCA34AC91923E428D005C22DA7D6477470
-:109A40007093E32E8F5A40FB07E427F6B79859AC82
-:109A500038CF31B12E6786AF04E3CDCECC64B2737C
-:109A60009C6A992101DB152B9E5D6EDADF243BAFEA
-:109A7000DF99EDD915C5EFBE1203D43BE54AE67870
-:109A80000EFED6387F1CF2A15BFAE95176DF607FCB
-:109A90009BDB8D73DB03E3D10F91FB17120EC19695
-:109AA000C41AADFC7C5FC02178358FE7837D6FA33E
-:109AB000F8B51DC641BF7ED7F53FE17E7D2BD57B36
-:109AC000CDC1E31915B03EB4DB9C85BE755C9F2605
-:109AD0007B62C163B543DAE5B717A35FD9586DF36D
-:109AE00020BF6D7F515941F48CC141F4B7FDAB08E3
-:109AF0000F0CF080FCC0FCDC2F6D6CF60563D37B93
-:109B000015F15F23F29F42F44EF176A0F720A7777C
-:109B1000AEFFA4DF8FF2B12AC67EA8942F8DE6F0A7
-:109B200068A463C90F8DD3C3A3116E439527E74D76
-:109B3000C0FFC83F0007E41FC92FC9FB399F6C6DE8
-:109B40007197E1F7AD15CCDEAAD1477A7F09E78995
-:109B50007EA794EB590E5FBA13E30086D016CCA310
-:109B60009072B871FF83A363E5B949396C3572F916
-:109B7000660D26055B35F4857B7BC913E949793B86
-:109B800049EB63C745463979BC6EA879112ED4E5F7
-:109B9000286F762505515EC93891BEDF4CA7121596
-:109BA0008F917E0BEE2F60FD3227B7434A9C9C2E8F
-:109BB0006F72CA786C30CAEF711BFC27309F289EE9
-:109BC000FE92EDFE52712B398ED4A37AFCCBFD119F
-:109BD0005C4F5551FC7AED07B97CD2D3E37C617FB1
-:109BE000A5E25AE17F3F17FB5983F1CBFB6135C6F4
-:109BF000A8FCB73643576DACF8D7C10D222F6ABB0E
-:109C00007148F9753F17F5BF27F2BFD85263543E2C
-:109C100095CDE36EC1F8E9841E77B14AE3F2385678
-:109C2000F274F629EAE194A9ED63304FC9E98BDEBD
-:109C30001FC9AC498CDA7FC8F6A74795736B73A22E
-:109C4000EA0F6B1E11F57DF8FAB151DF0B0213A379
-:109C5000CA856DD745D51FD53E33AA7CD5A33745D8
-:109C6000D5BF3A383FAABCB5A5B306F172CD9E5B0D
-:109C7000A3DA4D30860DC5F07E5CE78AE83C311DE5
-:109C80003C67FE518D49873F7016103E27EC8B864E
-:109C900047EAD46878605A1CF697CA447F897FF0F7
-:109CA0005C2E8F3595193F0BCBF60583E98159ED75
-:109CB00025DAFC8308FD04A3F2DF661A55DD3C02B9
-:109CC0007F12FDC59BA7DC5F8BBB8E3870DB27E462
-:109CD00084848B492C2B757ACD65E162BA125C586D
-:109CE000D83314B8E8F7F706E2CDBAFE3626355277
-:109CF0003EF0DB58D0D8C761C147B2BC2890CAF546
-:109D0000906FC115EC681E07F65BF8FEA4FEFB45DC
-:109D100021D79C300782CF10F9FA7D8187E3C8D71D
-:109D2000E870EAF97AFDA78733517E5732F29BED4E
-:109D3000CD2D9FA2DEBAC31862C530EFED623D8F14
-:109D400008B9F0E8063BF5F398D87F7C7C839BDE6E
-:109D5000EFD830869EC10D1E7ABF6BC3547A7680D1
-:109D60003D87CF273754D273CF061FD57B6A430D6B
-:109D70003DF76EF0F3790DC2172B253BC7971133D2
-:109D80005EBA3CA00E094F4CCD8BA92FE3F6A32E53
-:109D9000BD6C1EF9FAE34BE6BCA2E11B8B2BD9414B
-:109DA000FB9953D814DCCFBC52FB8B1B6AE6BC3248
-:109DB0006AE87C24E9897D9931DA17237EE417F972
-:109DC000936F3B2F6E0DD8E2C32B4267B1E1546D08
-:109DD0003D9F83CEFA78B41934ED8FE9F8B8DA9F55
-:109DE0001AD36E287771FAACB1F0FDF7253AFEEE82
-:109DF00010DF3B5CDC2E7C378E9CB9CE6510FC1FDF
-:109E000030D17EE020BEFBDE0DB1E0DBED7247F12C
-:109E1000F112BF0EAFBA7EDE35B50FF3C4E0B32B3F
-:109E2000F523D7A76FB7C9C5E5D6AEFFA3FCF9EEFA
-:109E30009DC9E43F20DC9C9AF5BF7B67524DACB8CE
-:109E4000CC5E17DF1705EB9C15A493A91F30A3ADBB
-:109E50003886B9F93EEF483BC687641E407C7A35A8
-:109E6000521C8960A80E862BE0C36D2E84FE8D03E4
-:109E7000E3848C388EC710D16F9853C334E73CD439
-:109E8000C1F400ED0366CADF09E750DEE357A427FB
-:109E9000A63E3EEA72FB7483DA7F4539B3FD6B96CA
-:109EA0003392CFD9970F8F8AA5276B50CE5C07646A
-:109EB000E82AFE6EA0E8CAFD7E55F8D5A861DAB79B
-:109EC0001E32FCF6398614975A6F4D198FC6D5C5C8
-:109ED00004FE0CCC64FC3CD6FB0941B4F343629E07
-:109EE000E0F84FE07E75F3147CF664F90EB9A0FD3E
-:109EF0000A33F713F35CDE975D502F51EC039B336D
-:109F0000CD5BF0C9EC7C1DE3311F14BADA6270E757
-:109F1000E33A3E523C57A39F6237043DF84C61A19F
-:109F2000713CEF2EE847FF2CE39A4437FAB789A338
-:109F300019EBA578B82701E366E6A4F05B23D19F6F
-:109F40007DD148F1A1F198CF06E5F17F9F1B0C90E0
-:109F50003FE726F99021E0B615ED70683F8FF9DFF5
-:109F6000C5F99EB65B030698D7C3951313301F2A15
-:109F7000B4470D98F1BC42EFB9BFBB19D63DA1570C
-:109F8000A538F30436E9F59128577A4DB4DF5B67BD
-:109F9000640F21DFC483E7D96FC6CEEF2ACAE4720B
-:109FA0004FE66DE9BF2789EF67E3E411FF87D00B28
-:109FB000323FC624F3639CDECBE6C79874F93126A2
-:109FC000A38FE13EB069203F6629A3FC18E8479BB8
-:109FD0001F737666EC79A8997C1EA62F92E2F49BFB
-:109FE00042EFCF8EB8FC3A4D5F2444E55947DADBA7
-:109FF000E87DBCFC9C3C09A738F9495903F3CB66C2
-:10A00000810C6D3B4EBF9171F2E8BB4997E713F9A4
-:10A01000CEF37B36A5713A399865772C87AE97B326
-:10A02000B009E9F40E9BC384F1231FF374D1B91D69
-:10A03000A3A93F2CF96E04D6337E8076B601242D79
-:10A04000DAD977AC377D10D6C8A92A6F7499617DAB
-:10A050008DDC5D9FC568BE8963C7505EDF05E64E37
-:10A06000B55F466E2EB5AA56A366BDC7E3D80D7E72
-:10A07000019FE3D9B1E13727D31095A734B87D4AC2
-:10A08000D479B47BED979797085F7F86B67F3D1EA6
-:10A090001CF4FD4A7076B672FEEE2F5378FEFE5F1A
-:10A0A0001CDE69229F8D9F0B30E9F2D0D767B9394A
-:10A0B0005D0DCC9BE7A1BF6CF7ADC8A476EED1DAFD
-:10A0C0007300DD466FD244781E1772470F973D022A
-:10A0D000CEFA75778B7CFA4495357769E0AF5FEF00
-:10A0E000E3028FB2FE2613DFBF823F9F15F0B28CD2
-:10A0F0007139DB9A3942E485A719511E2EE55DB00E
-:10A1000065F657693F49C27910FC04DCF570F431FB
-:10A11000F7ED98B77D25782E3F9A6846B97FBBB595
-:10A12000FF30FAA6E15EC33B23E179C236F2640751
-:10A13000C37DB731CF1F62180FF1F0FC09368BECED
-:10A140001C2590AB5EBA66E876CE9614FF18E48BB9
-:10A150008F44BEB5D4435B72CE8CC6BCF9D4F4B286
-:10A160009A2C27C5DBBD19483FBFB670FA79147A1F
-:10A170008272D381AB77A27E69C9F22FCA9A1CC9B9
-:10A18000DF63DEFED1987FF055E1037F26A49F2B8D
-:10A19000C1675B26E37C98129B3E8EC4A10F3D5F96
-:10A1A000D0B9B292AF8F2F243CE57E859CDFA22CE4
-:10A1B0004E7FF229E1A6CF1B5A946510F5B8DC68F2
-:10A1C000C9F2119CFB867D7A3201E67E5C97E73509
-:10A1D00020BF86B87E09EFAF4BFE1E4F8C3DBFFE01
-:10A1E0004CBEAEFFA9F92D91F31B1F7B7EA6ACA13F
-:10A1F000CDCFC7FADF4FFB1AF417E07909E2996D6A
-:10A20000EA27B9783C3DF63C470E799E7ED3D7A12C
-:10A2100067257DB3C0F25ADAA7CF4A8CB94FBF0881
-:10A22000FC26F47BF4FBF5725F1EE407ADB7DADAC7
-:10A230007F7B06E27D9658B78B85D2701FF38085B1
-:10A24000E2FEFAF55F23D60FF02A4639C5E6F6534B
-:10A25000FCE2F8E8D872A1388BF3C540FD363E4EDB
-:10A26000BC7305D70AFEBCD2B90256E2A7B85F9903
-:10A27000D51652010FF7087C9873D77AD02E2CCBC5
-:10A280007AE318AE13E07F6E009E9A3CBE331B8EBD
-:10A29000D8479AE2CBED3AF5D9D2E618EB99E7F434
-:10A2A000CFC5750CD4DBF3BA7DA4065FE358D8C0E4
-:10A2B000CF45F71BA2FCE14CF695FC61AF95F34B43
-:10A2C0006ABA8FF401EA07D43B5BF65F5B8CC84443
-:10A2D000FB02F378FA9313498EB6E65C37C6AD817C
-:10A2E000676396B45BD538F6E29F97F71FB19794F2
-:10A2F00028BB35D2BF91DE4BFC94D9FE5F4C7CCCA1
-:10A30000737AEF453A1C9DEE5D874F3DFC020F4C82
-:10A310004B23FF18E13723D2DF00FEE3E0F9C74EFD
-:10A32000EF77B0BFDBC4F91945E6EF0DC4298CF611
-:10A3300093D608BC878A97EFE13FC03FDD91E5DD0A
-:10A340008A78315B043F321B9D0B97F60AD3D935CF
-:10A350006C2ACF275D96F5C61F30CEB32585B3ECAA
-:10A3600096EF24505EDD1D8ADD8CEB06FBE3BD1FFE
-:10A37000417D3F0BBDF76DDAC7927646927A296927
-:10A38000E8F3947EF295F2A80FA11D06F39969B047
-:10A39000D1BEE621209B6C901B33CDFC59361BA807
-:10A3A0000AFA9BA9E6F584615E9FB373E93740EB37
-:10A3B00044114F5C77747202D2E54CA3E98C566E5F
-:10A3C000E9E31C5D59D1718ECFD9DCEFD3DEEF18F4
-:10A3D000EEEF3F3C7766A636CE3210E710EB581012
-:10A3E00058CEE5A94ECE497966B0F2FB439897B9AD
-:10A3F000ED2E8A1771B883736D84F20DB28CCE097D
-:10A4000094A7092429D81ED67D8378B215FE2C94F2
-:10A410003398BE83E381D79785CFD66B3D6E7CCED4
-:10A42000507C463E8F20CF3764CD7958DF600DAB2E
-:10A43000FC5C1ECCC085EDE578BC9C2CCA9BAA2F89
-:10A44000DC7EA77B70FC82D992C9DE358B799DB604
-:10A45000DB0206786FB1854E535EAA78EAE31C17DB
-:10A460000D8100E6657F4B0DD27C935828D48B710B
-:10A47000092B80C040F1831348A7E0D534E23C1398
-:10A48000EC1742DF6698DFE855B09CA1D3474EDB5E
-:10A490003ACA7776FA8C3A3DE457906F326BF4EF14
-:10A4A000A3F593951DA773404AC8977529E3CA7110
-:10A4B0001A7D7CC63493A3B87F0DB77BDF49E4EDEA
-:10A4C000245D28D95CFF34A69B19E5B9B8AC56B415
-:10A4D000DBCF279FC2A396A837DA506F584D5E8214
-:10A4E00087D41F0DDD7733C44FE3BE2A86F4FA4FBD
-:10A4F0000ADFF70C2C53283F41DED75053C4DE84CB
-:10A50000966C59F6086AB7F0887F593D94ABDF60C6
-:10A51000E34250AF7886AF02EF65691DC73C1BA1CF
-:10A52000DC9AE07FE697B89EA32AF5D324CEC33207
-:10A5300066AFDB0BFDEFBC7598672B2EA9BC7F0BBC
-:10A54000E6FFF43FC8EC982F32884EBF84F501FE39
-:10A550007F82659877D32AFF13F741FDEC37988700
-:10A56000EA88EFE88B20DE14410FF87E06BC6F12FC
-:10A570007453D8A3F07D7B8785F226D8B14CE2973F
-:10A5800085563E4E534FD9BCC930AFC2DE4944C692
-:10A5900023A13EE635616601CFAB63E427EBEB8F89
-:10A5A000C4FA6E8A52F17C9A1C33DD7BC4849C9B76
-:10A5B000A2E3B7EB23F44FDF8B45B949E8A3283E6C
-:10A5C000C17EC02FF796F26D7C6AE7E0FCE061F295
-:10A5D0008FF3ED752CF287FD9647C621F93B4B7C36
-:10A5E0003BBC640EE5734F31860E225F5F2F9EC524
-:10A5F000E2897C6D05382E36361F76C27AD2D63384
-:10A600004F0B8EB2D4DD8AFD95309F8A702EB53FF8
-:10A61000D88AF3BB76E9D10CA4AFEDD985447FD3BA
-:10A62000AC9EC2042091D6A91E8F1D5ED52C550864
-:10A630002E0B6BAC41CC5B5B38704F8FBF6011F061
-:10A64000CD62BF22CECFFB0B966AE2B0329F6F91F4
-:10A6500005FCE718727A7B36B78764FB2671DE4407
-:10A660007E6FCFB6D1F76F66DFB82C9BF22A789E4B
-:10A6700033F0BD3F7B72448EC0B89487B280794D71
-:10A68000B8AE05826F25DF2FF4DE4B76EB425FB468
-:10A69000FDF94F0AC777608942F6E0E29ACBDBA763
-:10A6A0004DD9729F37CF7E3229F25ED29594DBF37B
-:10A6B000518FA3BCAD04BDADB18F977EEBCB346A97
-:10A6C00097F964C3A5E191F32D4DBAF32D8DE27C8A
-:10A6D0004BD3BE16930BE95D9C6F69EA39B1459B7C
-:10A6E000D727E134F87C4B3FE5332E32070FE2B930
-:10A6F0009F456B618D50FF65711EE2153C0F313136
-:10A700004247C9B7268478BE9C97F2F6F2EC491E00
-:10A71000CC3369334CA43CA1B694648F362F676B5D
-:10A720004B7305D693F941F23CCBA238FBC08F673F
-:10A73000733BF91185E76905965809DE4E951DD3DF
-:10A740009ECF7716FA283F6E59B69BF0FE88882375
-:10A75000603EE9247806C11CE3F8E2EDF5F201FA67
-:10A76000DB84FD95177A282FA63C95E79739337C33
-:10A77000C5F71445FAADEEE1F978D5BE4F5FE5793E
-:10A78000B55525084FBD3C97F4A597EB407F9D48F4
-:10A790008F170D5CEF44E4BB6FC99DD05FDF9B66F4
-:10A7A000CA9B63F77B1513B47BEE75BB07CFD16DE6
-:10A7B0002AF35555D077239DF373D5B09005BE97F6
-:10A7C000BC61DE85F97AB5ACDD8CFDD5EAF4D65AEC
-:10A7D000DB2B66E4CFB51DA6083D32CC33F414A2C2
-:10A7E000A0ABDF3B28EE41F247CA253D1DB391D116
-:10A7F000F2A758CA5B900B5C5F2DE57A8E3DA9608D
-:10A80000FCA72FF9942AFC67927793A590D2C9F9F7
-:10A81000C93DAF91BD321DE403FA670A96C7537D67
-:10A820002A83FC1C8379A3D7B344A2AF41768298D4
-:10A8300057C9C0BCB93D24E562D9546E6A4ABCC050
-:10A840003844CF729F6E32DEBF03CFEBC5B8DF3224
-:10A85000788B420AE289050D856847F8C9DED1DBAD
-:10A860003FA5D6E6242BAC6F2A6B27B938E5F02B31
-:10A87000242701CF9FA09CF9359378F65851CE54E8
-:10A8800060C29F8ACF683CCDB66D37229C6667E96F
-:10A89000F11130225CE7B807E189CE0778E3E0C91F
-:10A8A0002BE5088B962305EC4B7E1EF9C157EF4331
-:10A8B000BFF74A76C821A7DF9C43F233DA1E899797
-:10A8C0004F979A63137EEAD0F2E9FA4CDC4FB88EC8
-:10A8D0008557EF5506D3C5F9C3EBD52C0DFD48BA06
-:10A8E000DC2FF2EB959744BE6E4932E9B9885EE4FD
-:10A8F000F82F15A5EB90AE34F8BF615F4248057A9A
-:10A900002B16EDAF437A9818D18B2183CD6D8671CC
-:10A91000B7289E363506DE5DE96ED27F930C5E95D4
-:10A92000EC29E6C9403C03DE8B105E53AD9DAD467D
-:10A9300098E749B3E747E8AF943137E1BD4CA75FEB
-:10A94000CA6DD546E4CF72AB1EBF5EC27B857DD09B
-:10A950007BC39F82F7E18877A93F86607F02DE2B69
-:10A960007262EC13C6C3FB2D7F22DEF5F8967CDF06
-:10A9700095602FB7615CB796E7114F7A73642B9699
-:10A980005D0D0574BEA52BCDF3327D6FE6DF4B7AEE
-:10A99000BD2ADE9B58B80EBE43B9ABC0578EE5A6A4
-:10A9A000F50AC9CBC96FFB5BB13CF27EFEBD786393
-:10A9B000F3CB78FF585380B7DF7F7A0BDD2311DCB0
-:10A9C00022DA97B59763B9A98DB7FF38D91A40FF36
-:10A9D000BAF458B015DF5FFD109F87B4EB66083AF4
-:10A9E000EB529E7D99DAB5F37677BD6A4DE4C96E78
-:10A9F000DC4E9B2ED639E371BE4EC7873755BA81E0
-:10AA00000EEFEC0F98900E4E1AEA4B495EC6F1B766
-:10AA1000CA94F63C7CCE06B9C008DF409F23789EDE
-:10AA2000E92E18626B0EB78B647E26E6895769F0B3
-:10AA3000B53587FB09B29E2B9DF17CE2C792C96EAA
-:10AA400095F9A3A11F3205E300B846D2AF71F249D0
-:10AA500067173693BE9C3D5CE691868D2B60DCE2E9
-:10AA60004BFF7A632CFF7A9B18F794C87B97EF6BA8
-:10AA7000830506F43FBA9078E87EB5796FA25DD27F
-:10AA800085FBC19AFB41BA0A78F9C78FDDFCB76D27
-:10AA9000E0ACDE6568360650E8E72B74DFC92DBDF3
-:10AAA0002C949A3278FEB38D2CC4F31DF8FC57B762
-:10AAB0009A776DD5D8E90BA5D898368AF448B5C0F1
-:10AAC0009394170B05BE80BFF7207F2FB236935D9E
-:10AAD000B844C8F7352C48718A353AFEAEB37DF6D6
-:10AAE000BEC180F1B0683E6E80E970BDD0BFE35D4D
-:10AAF000807FEDA3C976D4F30D9DD1F56A1F7DF358
-:10AB000018B7AFA2F9BC56F279309ACFF1A649E254
-:10AB1000F31F8EA5FD17799E2FC1DAFF7E8045D6E3
-:10AB20003BA0DF75FC9780E7FBC6A0DF62E079857C
-:10AB3000A22CC7BDD0CEF57000F4B0F07348D45E3F
-:10AB4000383E2788F4502CF857F271B1D0E783F4DF
-:10AB500075A5DE8FD94EFC31499424DCA57E867E16
-:10AB6000483FCBF382A097DFF4927F0FFE27CE738E
-:10AB70006C34BF6C55403E1744FC15C0DB3F23DEF0
-:10AB8000401E5B799CA29DA13C8B6BF7DBD6C5B4C4
-:10AB9000FBC18FA07D80C1F67E28CA8ED7E32B9E95
-:10ABA0005D3F80AF04B09792D08F67242FF7E17399
-:10ABB00008F91C20A7FF3D967E361FE2F5FA77269E
-:10ABC00050BC40C6C725BFF5E572BBFA57595E9623
-:10ABD0008BFB57A2FFE377CFA67DEACF9897F6A924
-:10ABE00031CF2837469E04EE536FD2C4498FA7C594
-:10ABF0008E5B27E772BFE71BB97C5D794E6F4A2EEB
-:10AC00003C4F99795CFC54A278A6F07D85EC81FAE2
-:10AC10005C4E4C10E55322FFFA547A743C5DD62BFF
-:10AC200016F53EDA60B56ED2C815F70F2DCDA8AF78
-:10AC30009C85225F7D1DA7D7BE17D2766AEF699BE0
-:10AC4000965BF60D9C97B3D06BCEC638CB0B5C2FC2
-:10AC5000341AC366CC2BB9C1E1BF0AE1D4E866DE81
-:10AC600067B11F77D8BC00E0DC27F6E7FB4CDCDFE0
-:10AC7000E84BE04F39AF69B955DFC0767D7787493A
-:10AC80003E0C94ABC2C4FFD3727D346EDF42F95DDB
-:10AC900094FF969799F00FCB045F509C37465C77F2
-:10ACA000701C37FADE992673EC7D6596971C159F0C
-:10ACB0005DD6C3E386B75BD9965CF87E474F26F92D
-:10ACC0000FB52981D1768AE3FD7971D7BE61BDB414
-:10ACD000AEAD65FDF98F95D03E2EC57D1A7A5E2307
-:10ACE00039D720F9A43B9A4F96E40E6DFF431F1706
-:10ACF0001F02FFACC88DC13FCFA37E3245E07F8FDE
-:10AD0000C877AA50EBCB312E746115A373AFF7BC93
-:10AD1000AE123DDDF38C42F74048FBAC41C037DE5C
-:10AD20007AF0DC805B233FF0DC805BE39FE1B901DC
-:10AD30006D19CF0D68EBE3B901ED773C37A0FD8EBF
-:10AD4000E706B4E562B6B215E36C4D6DCC1E74F344
-:10AD50007304DAF6788E405BC67304DAF6788E40B8
-:10AD60005BBEC0381C2F3CAE529C1ECF1368DBDF8D
-:10AD7000F5FAA42CA49BEE049E3FC602DEDE2280E0
-:10AD8000CB2A01173C67A0EDEF6CCA8D4718D0DDC8
-:10AD9000AADED573F13961DFDAA8FEEAD47AA243DC
-:10ADA000D6CEE56E33FC47F2532D52711E9FEF5302
-:10ADB000584601DE1BAED39F3DDBB6A0E859138C8D
-:10ADC0007E5FC734F1DA82C171F98EDC64C7499EB7
-:10ADD0006B9CA38DD344E8C0E609E1FADF563DB190
-:10ADE000E8A0985D954AF199232AC61ED8C7ACF908
-:10ADF00091698A267EAF8387252B9A1E12DCD1F4B7
-:10AE00009034269A1E923DD1F4903A359A1ED2BCC7
-:10AE1000632F0BDF8CCA68FAD0C3772AFC87F09DBA
-:10AE2000883742625C09D68971DEBF147C7B75F07D
-:10AE3000FD9C4D2BB7B9E973B5B534629F941C697D
-:10AE4000A64D5A7DDC53C251DA09327E3999713FE1
-:10AE5000DD8AE72C0BD10EE0FE1BEA7F94AB27CDF9
-:10AE6000DC6F430A42397927F3933CBA53A7FFEFCB
-:10AE7000B26D37A3FE1FB45EB0B8F0BE40FD7AD10C
-:10AE80008E629A78925EFF2B3D4A28793C2EB74716
-:10AE9000CA65FF253276BCCA50E4C5719BF7739C26
-:10AEA0003F3A7ED6D2A8786F4C7B4ECE43C2458EB9
-:10AEB0006F61CD6A16D2F318BDFD15ED2F4BFF9AC9
-:10AEC0003AD5C4A3A57F2CFD133D9CD5E10564773D
-:10AED0004DB24BBFB8F7367C2FFD61BD1F7AA57D03
-:10AEE000A9050125FCA382883D7983782E10F122E3
-:10AEF00058D687BF87C6D314F7301C6FFEFEAB9CB5
-:10AF0000482F5B9466A69BDFB117A11FD5D09FC1C8
-:10AF1000E32FFEA8FDAAD79430CD7B11F36EC66750
-:10AF2000A388A73576BF46FBA88DDD3C5EC0F645FD
-:10AF3000E3456FEFAF659DE60265B0BD5FCF7AA9CF
-:10AF40003FBD7D3F884EAEA0C777E4C97B3B78BE4E
-:10AF5000001372A956C02B9E5F6044005F1BB9B7F7
-:10AF600013F8A12C6F72247FD6950E7E8C8A7918E7
-:10AF70006E73AC3C298697AA804DBAD2564D726248
-:10AF800065DBA0B88499F8A9FDF2EB9376C05FE584
-:10AF90003182FB883C37DF874A9C7BC48B9F4B7A8E
-:10AFA000F3B5E73E9ACCFCBC216B8E3E97BF3ACFFF
-:10AFB00020CF4DA94359FF60B8FE69F9F832FF0070
-:10AFC000E0B7460B3FB98F20D7F3C9E4DE27317EC7
-:10AFD000A826CFB2A25F9B9AEE6FCA73E2BD0CE1C6
-:10AFE000930ACA339B9BF243CEEF3BFD0EFAEF72FE
-:10AFF0007D8C851FC17B6D6BF7A9E40FD6EE7B9925
-:10B00000ECA2F8FE5EFBC0FD09627FE37E1C473FB9
-:10B010002F99CF5CA116A5863576FABC3C1E0F1879
-:10B0200035DCB711DB95FC2E2F05E76B1AD149F7FC
-:10B0300061F5DFC7ED6087CA6621FC40EF71BD6F27
-:10B0400033D2BE832329A0A6A01DB79CF1FBE73C09
-:10B05000CD1E2415755811C5695DF7A93EB4BFDF33
-:10B060005BB7320DCF29BB9257A515C2738685DF1A
-:10B0700047E3520C3E7EDE74451ADEFFB1CCC2F7C8
-:10B08000E50BBE99142A047E7BC9CCEF197524F90F
-:10B09000E9DE82FE3495E67366032C6D14EE7B7C4C
-:10B0A0003609EF1BC8F9D23611E7932DEEB3A8CFBE
-:10B0B000E3E7B7CF3E737112FAABEA251B9D6B979E
-:10B0C000F4E7288CEDAFCC17F06874F27CF7F3C28C
-:10B0D0007E3C2EF65B65FEFB3AB10F787CF4C0BD7A
-:10B0E000604ECC0B694CF0A62EC678C451156FCCBF
-:10B0F000609FD9BDA9696437F33CF675C27E382FCD
-:10B10000F23DD7CD999989FE45BC3CE997F2B8DD6F
-:10B11000FB75DD5329F34EE3C221CDC88C13E8BE85
-:10B1200025DFE5EABDF84735263C4F8AEFF1F2E529
-:10B13000DFCBE37E9BCC876FC47C7878B5EE85B29D
-:10B140004C76993CE946BC875C935F837E1AAEAF30
-:10B1500011EF21A7FB49CFD1FD1CD80FDE1776A533
-:10B16000FB22E70B3837621E7986F6BD9BBF1FE8CE
-:10B17000DF41DF9F12707BEA88A172578C79260E1F
-:10B18000E3EB1EEB34FA705FF29A10BFEF335E3DD3
-:10B19000797E3BDEBCBA67866FC779637E66ACF1A9
-:10B1A000BE147094F3ED4E0FAFF6F1FDBCD155C94E
-:10B1B0009AB2BD3F7FBE46BE4E11F8E9BE299C4FF4
-:10B1C000F700CCE1FE6B3C3C971A9B1584C31769D2
-:10B1D000FE5B50FEC97B8AF11E639EE711B82CBE50
-:10B1E000237056A3CE1D0C86B399BECBFEA4DC39CA
-:10B1F000FDA84A72E7F45B821F99D7A694A2BEE22B
-:10B200007C759AF1B8EEE976FEBB1F2BFC607B8261
-:10B21000FC58DE5137177FB763F5EE495B50FCE30E
-:10B22000FBFB41FE2CCF626C3A3C576C8ADE1FFB65
-:10B230009C3D447A6ED5437A7DE633A39C5DBD3D4B
-:10B24000BA7E2D7BE853B40F6A7576AF4BE85DBDCF
-:10B25000FDEB1926F27E4A59E95739DFF428F34EFF
-:10B260001946FA9FEFB74D16FBE9FAFA4FB8399C29
-:10B27000EFD9FDAF66FC29A078FD9E01793112FA65
-:10B280003DB7C14ECF6F0CF3CEC4FE970DF3570CF4
-:10B29000C338C4510EE70BF51756535CBA86DB0171
-:10B2A00016BC5C05FE69B9CD4A7EF40378BF18C0B0
-:10B2B000D962E1F685B4AB54F55E3505BE5FFB2F70
-:10B2C000ABD2707D8EA76757A2FFE17C3AC98BF89D
-:10B2D000D85AE62D46F9BDB5CA46FBC43B0DFCFE67
-:10B2E00041AB85EFCF059FBAF610868347766E9BFC
-:10B2F000897E86BDE76008E3126D06BEFFDA369DE3
-:10B3000089FBABF9784D3D555D38AFFC6A90F7D0BD
-:10B31000DFD6026FB15DD33F13F652A3C045DFAF56
-:10B32000AFFA3EDE77F5A32364AEC23A4750FC6B1A
-:10B330002CE37423F34BE8373134F1A273A07F98E8
-:10B34000E6DCF3D84E25644AA17BF5288E5DBF313B
-:10B35000E4BA0DF5E7CFF87EAD9C9FE3A5EC991814
-:10B36000EF97FAF436CC6FC338B0B07B9730F9C79B
-:10B37000F70B6A045D2F11F6EE6D491CCE2B9887F2
-:10B38000CE5DDD6A6529185FBEADBC7332DD7B5DC5
-:10B39000674A437B45C6BDE3E13D5E7CA6F1C964D7
-:10B3A0007E4F8ED23F1A3B398331909248BEBDBE4C
-:10B3B0009F8787097E1E2DECB491CC8BFB2C8D07CB
-:10B3C000AEA27C7C4B22DF5703F96645BC1E467D4E
-:10B3D0000EEB5EF3624288EF1B07C57D382C40FB05
-:10B3E000310732695FC151E8A57DF7F3A6703EC908
-:10B3F00003905F0AE8CEBDC37A6FC1DF6169CC01FB
-:10B400003B0ACAEF3EF1DE2D46A0C7C611E1D57852
-:10B410004FB8B2E3DF78796CF82496937628F3A8D6
-:10B420003C31BC5A85F2E81DA9F3A83D3A5040587A
-:10B430009376B8E6E139E233227EC93C61BA1FA8AF
-:10B4400071FF55066D7C70783EB737CF24F07A6770
-:10B450000AD81DF311DE63C2A3B5BF97A0E61B98FF
-:10B46000F65E65B94ED98E65C5EEFF45A107D68853
-:10B470007B7D6624B1B604BE5F1140FBEA959EABAE
-:10B48000082EC161E9025E61BAAF51F6A33FD72F22
-:10B49000C75D8B7A1BE5BA29FA1CD191615C5FC04C
-:10B4A000389B689C226F31DEC7D3383FAF18F10656
-:10B4B000F8320A7C19B91FB893CF0FFA4D1B4F7A97
-:10B4C0006412E689BDF225D42F88CC5B4F1F6F0B29
-:10B4D000FA58D3CAF799FAD30A898E662471FB8F7A
-:10B4E0009500FC408E8D16F01D9E9FC6E13780872B
-:10B4F0004C85FA6F15F0CBE3F5BFEA7A4F7E4DEB42
-:10B50000D5E0C98B79C7AFECBB9AF024D7C3D8B6C6
-:10B51000A87ECEB4E8DA4DE579298DE985D4EE012F
-:10B5200071BFBEBCAF18DB1540BB19E5FD93901F82
-:10B53000E47D6D2C309D9CF57A212D06EE5FEBE4C9
-:10B54000F9296CA497DF43347F6E89589F5DACCF97
-:10B55000AEBD8F6E800FDFEECFAFD6DC472DDF0F95
-:10B56000C07DA0BFA289A2BF287E8ED51FF2453C18
-:10B570007C64E573BAF88BE143CE5307CF0138EB17
-:10B58000E627E1897C4CED8AA2F949CE3369008F28
-:10B590003A7E2EF813C713F9FD0D7F25F221DDD178
-:10B5A000F4DCD05D60C0FD53D9AEADB3C587725E2B
-:10B5B000C6BB2DDD5501D47F4D3D6594B7D9F0ABA9
-:10B5C000679E0F40FBB5BFF8410A26D39E36B6BB37
-:10B5D000D0CEADDFBD39C58BFB25C6400ACACFD35F
-:10B5E00041B532D639C0C67C45FAD16447350A7DAB
-:10B5F00073E6A9EFDE82F0F8B7DD263BEAD1A63D7F
-:10B60000969085E2206BC88E82F2095E7EE053F44C
-:10B610004B9BF645DB496B7FFA03979BE829906BC0
-:10B62000C0332E2C94CBE0D9D861F2841C3C9E0808
-:10B63000C3B026D6BF05E7A76F8FF3F802F0DED4BC
-:10B64000A92EC7F3BCFAEF2049C80E6BEAFE2ED92B
-:10B650005D4DDA3803E0A1368EDD75477E74BEB5E8
-:10B66000840B0B3AC9AE69FDD90FC79FB0E13D9A73
-:10B67000BF49518AB4FA7223C1E942E7CA1FEF7782
-:10B68000C7D7ABE7D12EB068DB71BCBAF729B427B6
-:10B69000C17AF8B3DE144A413FBF7EA7C9039A9727
-:10B6A000D53FF39327713F84BD6BA17B0FEA9E3991
-:10B6B000FCCE7550AEEB3239E6F2E9DB1457043FAD
-:10B6C0004D6E6E9F487CAC7DEE30DD2F88EFD1AEA5
-:10B6D0009578A9EB3A6866E306C3AFBCF3A0F8BD62
-:10B6E000051D7E3A4FDC48F778FEECA219E9FAF422
-:10B6F000018565160C6E5FBBF3700AD21FC209FD8F
-:10B700004B89A701BC0DC257E896FD25548FE21A5C
-:10B71000F1F0E6CD677C9FE757CFFC1C7FFFAFF6CB
-:10B720009F2C1E5C7FEDCFEF4DC1757C6C6CE6F4F9
-:10B73000FDC4669717C6AD35055C767AF2F7B53B62
-:10B74000EE23BABBEBE87D2EFE3B1ADE6CC3545AE7
-:10B750006736AEEFCEC717D2FA56333FD15DED1341
-:10B760003C3EF1B9F81D063D3E4F0AFEF87897853C
-:10B770002E2DFA1813D1318FF02D55E4F9DECDB40A
-:10B78000F75780C54DE5CF457CE0C5017B805999D1
-:10B79000262EDBD4F1402FE2E7CC306F26EEAB0152
-:10B7A0001C02025E0ADEABAB1EADC8E4F8616EA3FC
-:10B7B0008C2B83FD5D8EEFB17EAFC99B303EAA9D81
-:10B7C000D8AFE7E3CBF804CC3B11F7FD3E76C53E9E
-:10B7D000B7E5182EF99FF5322D7DC5E3F78E078961
-:10B7E000AE3E7B9BF34D63B0AA92BEF79A4278A41B
-:10B7F000B83178B05A21796089BA6F69802E3A4C95
-:10B80000829FA3BFC33C8D8A16BE07785EEDEAED2A
-:10B8100096A87B102274638EBC2F88F0A7F4A3EE49
-:10B8200012FCAF5FAF5E1E9CD0C903F6B87348F739
-:10B83000C9D49B824F3E86FC0BFC8A7E66FD332674
-:10B84000F2F3CFEE7DF99D5B81CECF764ABE8D9629
-:10B85000AB7ABEAD7D76328BC5B7676D1E16936F22
-:10B86000E17D4CBEB545F669DCECEB93AB77C59159
-:10B87000AB89C3C57ECEC03996A254CC753FF35474
-:10B88000DD708A0BE8E02AFD59BDBCECC877C7948F
-:10B89000970CAF9ED2C051C24FD2E3DAA71B689C6F
-:10B8A00001BA957429E976802E07E55746C151FF04
-:10B8B000BD57C8A38173431BC14F413BF6D72AFD37
-:10B8C000FE491FCC650BC0BD6F6F01ED836E167610
-:10B8D0007E9FBD3F05E37A9B855FD18FF1C4D4C8BD
-:10B8E000FBFE049137E0EB4F49D3D845277AD414B7
-:10B8F000B4E3C2C1D8BF232BEFA70CC7F99D597978
-:10B900007EA942B5E5AFC7386D3BDF9F5CD5B23845
-:10B9100005E3197D3D85F43B4277BE0EFE2ECCB784
-:10B920004FC635035E637669E45ED3532C40FB95C6
-:10B930002B7BEA68BF501F07596DAB4EC5FD407D9C
-:10B940001CE42ECC83C23CE4C7A3DFAFC5F808E2F9
-:10B9500049474F7EA4A7ECC1F4543D5CF065312B00
-:10B960008EDA7F1572AD422DFA3EDA277DE0B7639D
-:10B970003C88A945BF457DFA39FAF1C8000127D1B5
-:10B98000699DFF94CCB322BA9674A7F7DFF5CF7305
-:10B99000BF7CAF14CF03D53FFFFBF13F82E7B9E790
-:10B9A000DF1DFD22967FF58FF9BF6783EB971FF8A8
-:10B9B00003F92B7D072C349FBE03AFE57F1BCBFB28
-:10B9C0002D1E9C6FDF460BFF1DE803C974DF74DF7B
-:10B9D000301E676BFDF5C5F161D2539B7812F27092
-:10B9E0007E4FEC859EFF781FEF55BDD0637163DC01
-:10B9F000A1E94012F9E14DFB13E87EF8BE5F5F2C30
-:10BA0000D5C68BFEDCF5348AF3167DC9AC06F35B34
-:10BA1000FAD2B8BFD6F4E2B53F692940BBF420DDC5
-:10BA2000575CFED27F8E47F9D3F72CB72BC03FDF90
-:10BA3000819B88DF1DFEDCF74DD978DE88915F7D24
-:10BA400095FB33F2AB07C385C3A10FE080EB02B8CF
-:10BA5000D03DDDF1E0B1EB7F2D3C3E257FA1BE67FF
-:10BA60000AF151042E0AFFDD919EE4A055A1F5F3E1
-:10BA7000F7072E8E473BE96C670BE9FD2BADFBE02A
-:10BA8000FFB9752BA1A1AC3BFCBF76DD9CFE570F27
-:10BA9000E7FA49CF0783E9FC57DFA4F2CF933D349F
-:10BAA000DF21F23F6EBFA27CFFEF5EFF7F01F65207
-:10BAB0009D150080000000001F8B080000000000A2
-:10BAC000000BD53C0B7454D5B5FBCEBDF3493249C0
-:10BAD000261F2008C19B2F51F2194802E1A7938429
-:10BAE0005050C409488B157000955F4822D89A566B
-:10BAF000DFCBC4440CD4D547D5565BD135A0509E7E
-:10BB0000CF3E530C96564207540AADD5D142054D4F
-:10BB1000E948AD480D6404157CA5E5EDBDCFBD99A0
-:10BB2000B9378988ABAEF55EB2C8F1DCF3DB67FFED
-:10BB3000F73EE7586F035F8713A03711E6EF28C47D
-:10BB400032053C900ED0F0E2C4A75AB20056777E80
-:10BB5000B408CA00EA764F0019EBD5BFFE477198CA
-:10BB6000FAEF903CE27B62C021E1F73D9F89EF7BD9
-:10BB7000CE1503961FEE90827212D6EFB32F0FD020
-:10BB8000BC9930BF03CBD6AE73C5612C01DA00CAB5
-:10BB900001AE546D5C9ED9FDF763523A95761570EF
-:10BBA0009D863D0940F337FC2A2E00387F6FD7B9B8
-:10BBB000F13E9CF722FD5C0BD0D38C538C8ED6CDFE
-:10BBC00065CFCE3F8DBF07BBD4BDF04EF1E358F635
-:10BBD000BC7034FF45AAFFE2AD51EF60597FC97DCB
-:10BBE000EFB52DC5F63BAE5419BEE8BEF7DAA08816
-:10BBF000F67B7011F5EFDD93E8B267117CFF180555
-:10BC000031FBBFD4BEAFF97FBA6F003FC01000ABAD
-:10BC1000EC7564237C0F4230A462793FC08C0E67C0
-:10BC20007F785651E3101A0721180A2083F891D320
-:10BC300057CE82242A377C2417D3F83933B2100E1A
-:10BC4000BF6A716F55A98785F1D03ED21DD880702B
-:10BC500081E25DBE19EBD62BEBDC1B78863B01C67F
-:10BC6000037CCBA1CD3774D60C09E76B6D41B8705E
-:10BC70009ED62116572BCEA3A896A0BD98CB77A908
-:10BC80007C60E87507685DC56983A036F622FE739F
-:10BC900002D60BB43AAE179F1B53C77F71B0CFA526
-:10BCA000E0FA716E0502B8253BC48CC7FE33551708
-:10BCB000EF331E027E97F3F2F1F4F825F064C68F9D
-:10BCC0008EB77E780270D07885FE8BF69FBE2144B9
-:10BCD00072A880E20F8BFD481725C2A73BC381F3F2
-:10BCE0005993EF706F90F8BBAA8CD7C659E8CF1A5A
-:10BCF000037E117F9EB8E2289E63E6E3FD9BF17C04
-:10BD0000B9F8D5E912077398CE71239DEE00C27F72
-:10BD1000BF2AF07E3FE25D92A2F8D5F166A6433DD0
-:10BD2000F14E7914FFD1728AEBFD314C48B888C8C6
-:10BD3000F557414123CE53234F09FB71FE331509BB
-:10BD40006E3BC98B0441691C969543AB00F7D193B8
-:10BD50006953A89C1AC13DC5C07BED79072831FB0A
-:10BD6000AB841443BD27339FC7573B861BC6F50CD6
-:10BD7000AF70D0F71A5796A1FFEB7149C55042E357
-:10BD8000A6CFA0F6AF655C651837FB78CFA6C5587F
-:10BD9000DE2885CB88397A0E2EA8227CCD54C71A8E
-:10BDA000FAED42B542F21CA991035B101FB5527027
-:10BDB0006831E2EDFA828946F8249846FBACB3205C
-:10BDC0006B61BF1BDC9586F61B2B661AE6ADF5D4BE
-:10BDD0001AEA754D9F82920630B9E90228A50063E0
-:10BDE000831D86F1A5077619FA27BD0A722296638C
-:10BDF0000FA9AD5496768752897D6D690EBF2519BE
-:10BE00005938ECADC6EDC0F80F1A5FA2B2C981F87F
-:10BE1000C0EFE7E24489F4623EF71F8B0BB422BC0B
-:10BE2000E72C011FE1E16E39504065FC883B8A2117
-:10BE30001BE064C6837232C10FBE632AF2C1C48F95
-:10BE400003AD54BFF64287EC233DBC5DF6DB4A8868
-:10BE5000EEB3127E4F7AB74302A27B9DD3E20990E4
-:10BE6000DD4AED285E1BC35F1F7E1B6EF516F6973D
-:10BE7000D74D7995119ABF2DC3B3712FE9CDAA3F44
-:10BE80002D92B3FBF703971209EB78C9A671DEEC8C
-:10BE900091384E4E9CE620BD1E5F2DF3BEE06BD662
-:10BEA000C0569C679DC51DA7093FDB57D774EB663D
-:10BEB00092EBF62CA11FE27F07AA84F0C7A7F9E452
-:10BEC000221AF71F126C85E87A4B2B80F791926546
-:10BED000117CAFB8862C2CA2F1895C1F5F21F00881
-:10BEE000B32C813C9C72EFD413FE44C443FC8D966A
-:10BEF0004CB4409054E1F95D2ED6C787DECC94490E
-:10BF000096A0C042FA640DAA37D227C31ECC7A7419
-:10BF10001F8D3F60853C2C962EF09CCDC5FAF767AF
-:10BF20005940C2F6CE8AAA84A218FC259D97402DBE
-:10BF30008DD6DBB3548623490903C971D27985DBD9
-:10BF4000A129DF42FA465F276981FAD6DA9875405F
-:10BF5000F1AC22B8375CDDAD92BE4A3A22F6091048
-:10BF6000CEF0E2D6FE86765125422AE18C8589FD07
-:10BF7000E9F0B7EDE5292AD231ADD29DE2A6F2670C
-:10BF800088E4498C673FA9BFEFD39F2BA8F6686868
-:10BF90001AB66F271D28DA83807CBCC1A6B5930A28
-:10BFA000C17A9AA4B5FB1FF54E233ACAC6FE25D91D
-:10BFB0007DFD3D8E8CE8FC53363F1A6A2BEC8FD703
-:10BFC000BD53ED6C87E3910FECD877CD5585C360F9
-:10BFD000003B11C56BC225F09A24F07A01B53DAE45
-:10BFE000739743ACF39EA48E22FE7AD882529F03AD
-:10BFF000F092CB579D554EF0078BE8FB9224CFB0C3
-:10C00000A9C86F9D36CFA8EF901EE98A736FC171E2
-:10C01000B5777EF85813C9F1ECBF15A007039D8AC8
-:10C0200027611CAED3E0FA94E5BF462E4C26FFA64E
-:10C030000F8FC4BFB8E6F72DD13AE983A4285E3D3F
-:10C04000B9D8BE2106CF0E07E92B51FFF7AC67BC6C
-:10C050006D44DFDB1C8CA7B59A0CB5A5C0460BF26E
-:10C06000FF59D7B6AF133F9CDD6E05F2933AA99105
-:10C07000EC638183E508D2C319B5C8F7456F58BC96
-:10C08000E48775237F78883F1AF30DF39D9DF25660
-:10C090006A118E3B9BAEA4127E56866D8CB7850AC4
-:10C0A00004EDA81F3BD36FABAEC4F6CE232AB777FF
-:10C0B00068F33C9BE7599EC576659AEB7DDC97E477
-:10C0C00099245F1C3338BDC862BEAFEB43C4730311
-:10C0D0006D3375703E68AB7404C8AF6CA8682924D2
-:10C0E0007BB026257F18E03E1AA6496C5F1B9A3E5E
-:10C0F00066BCEBF32BE76550D3A275778ECA7650FA
-:10C10000513CCC0FCA791BB7D7359D65BD8DE06416
-:10C1100091DCF4B408FDB6D10AB7D66259F74FF9ED
-:10C12000D65AEC5F872CC5F601F6D9D6C4E83FE8AD
-:10C13000F8A84FCF9720ED1E9EF5663CE9D55AC969
-:10C14000350F700F87B36DB5CA70ACC7B9E64958E3
-:10C150000F6CE9F5723DD335CF82F58EACDA5A65B6
-:10C1600022D687BB7E687103FC69CB4AD13FCB7571
-:10C1700098EA07B31E10ED89820F7E98755BADBFFC
-:10C1800090F8CBC97839D39EC0F231189E9735BD4F
-:10C1900068C04BBF7659BAD54B7C355FE8C153EBCD
-:10C1A000476C66FF2737944F6B6E273D8B781B8A51
-:10C1B000B4A9C07FAFA0DC3B100FE939E0B160FF4C
-:10C1C000F45FA0FDA1FEEF854611FE96FD222E280C
-:10C1D000213D563FF1928DECCF1259CD27B9FAF59A
-:10C1E00068DF7F935C9D4E0C717D59D31E86EB1FDB
-:10C1F000B92EE19FB822855EE4CFE5B0D146EDCB04
-:10C2000041394E7602B528FB312B9D2FDBC80F5BE1
-:10C21000F9B4F57838C68EAE82F03192D3BA67ADF4
-:10C22000C7C331F616687C0C7F1DB70838140D1F84
-:10C230004BE4D0229B806B2FC1B53A15FD7999CC88
-:10C240004368A88FFDA0BA028E4332E281F86EDD0A
-:10C25000156F17FB06B07B1DCD68E751E47634EF10
-:10C26000E2B21DE724BD334C09DBDC384FBDA69795
-:10C27000C7878EDB2066FC31CD7E25EF92B85DD777
-:10C2800017D176619FA0D033D68270AC9EF3EA14AA
-:10C29000A28B4ECF6B13A0232E95E9E2D6E8E226BF
-:10C2A000BAE8F8477C962A38EEE50B382E6B20BEAC
-:10C2B000D0F12FE0ED8C17FA22B2338EFD2433FC3F
-:10C2C000E7343ED0F791902DEA83C19F909D28E8F6
-:10C2D000FA2F863F215BC8B1791FBA1CF7C57D2DA7
-:10C2E00003FB293ADC97CF6721DB17E1335DCFD41D
-:10C2F00083AF80E6D7F58A8E671D4E1D5F9D14FFC4
-:10C300000C00A7D2F44BC37E945015050D50909DA0
-:10C310002DF458C74C203A284DBBB9DFE5EE47D77E
-:10C32000B783ED4BD7B3E6FDE9FA56DFA7AE77F555
-:10C33000FD4E4545C2FA10C3768AABAE3DEF33F8E9
-:10C34000BD95B0C2E017573BEE34D46B5CDF31F4DF
-:10C35000FF5A468BA17DA6BADED07E7DC10F0CF5BB
-:10C360001BDC3F36F9ED9B4D7EFB7F1ADAA7844339
-:10C37000EC67BFD63C031474ACAEF920C2FE76B0B5
-:10C38000D9C5F57DCD195CBEDCACB27CEF6F2EE07B
-:10C39000F240B39BBFFFB6B982CB579B3D5C869AF8
-:10C3A000BD5C9AF5C2ECE7BFA1507C5211DA584D42
-:10C3B000AA7C5B8EEFEE6CE487D72D81D644C4D384
-:10C3C000846EE18FC372B33D3E77EC1EB2EB2E9BC1
-:10C3D0009BEC61DBDE89923A803F9784F6CE13C3F3
-:10C3E0002F49B3C2E021BF07CDF340FC756FB6857E
-:10C3F000E9476A1F50EEE63BC09A8EF2367FBEE4F4
-:10C400006E15E6C00FA95C067DD83E5B013FD9FFE3
-:10C410005AA712B42731685E07C2394F8009766A7D
-:10C4200027FB9D9EA690DF7A137D4478658F0CD7FD
-:10C43000E0F77915BFFB8CE2E46F3A3BACC42737D9
-:10C440001FB8EFD43DD80E6DFE72928F3EBFC1FF74
-:10C45000B6E572FC867BB3855CF54AEE9087FC9D61
-:10C4600014C51DEBFFEBA5375BF8FFB35BFD721244
-:10C47000E233F206B01FA7CB23EEAF9DE0D7E5A2D3
-:10C48000D6A504472791BDFF4135F5AF3BA4325EE9
-:10C4900074B9D0E5408FFB7439A8919F6DA5FE67F4
-:10C4A0008E00C7CF137A7C1F3C4FFB34F99D15914A
-:10C4B0008DD514875D2A4E9C74BEE325EAB7A7D9B3
-:10C4C000C77CB4BB793E97C1E6E51A7F3672FDE5BD
-:10C4D000E626AEEF6FF67379A0B95DE3CF8DDCFE93
-:10C4E0006AF3635C7FAD39A0F1E976FEEECE11F61A
-:10C4F000F7E350F530E2BFA7B245DE061C951C47B6
-:10C500008022CA2FCA2775192F0A7FCAC41F66BE88
-:10C51000D0F901506F4888AF6FA29D25FB700BF8D2
-:10C520008B1663397FD946EB64E9CBF3C54A671BA9
-:10C53000FB1F667DB80282ACEFFAEB77E1FF5F4A42
-:10C54000BFCB189F92BDD2F5DF6A08F37C76F94E17
-:10C5500037E54FBE3ABBE2D2EC0A2CA6FE7D7176DF
-:10C560007CF722D972E9383B7BA418AFC7D9E83FE2
-:10C5700002D9E5DE80CC7EF5F2AC8D491C675744CC
-:10C5800092C80F58D125333D30CE548623DD9669AD
-:10C5900074EB81E01F892ECBA62CE33CDCF24DC668
-:10C5A000FDAC74DE941C5407F4D306DC673D3CF804
-:10C5B00011E5E3EA357CF17784A7A9FBE6992FC75B
-:10C5C000F4FB243B319DF355136002E103E177074F
-:10C5D00049CE0EC92C6783F1C5698C4F88CFCF3502
-:10C5E000CF9FF932F2FDE90BCD1C7FFD33FB811F9C
-:10C5F000F8477E75F45A97E74DC8E1BC5BD846F220
-:10C60000A3D36F1DE948847B5D95234081766FB984
-:10C610004BA1F57B258F4C7987DE77C1DD82F8ABA6
-:10C62000DCFD9B23241F950E279F1BE0267A62E9E1
-:10C6300039F190AFD589FD26BCEA91C97D2F7F39AC
-:10C64000DC4ADD747BA3DB9FC93D11D9C779815CCE
-:10C650009623C0D8E262CE17972373BCD94AF1263D
-:10C660002AA4B3CEE90CEFD920B8E97B348F25F2A8
-:10C670004B932F78E424846F9D161F4E7CCFCB7094
-:10C68000781C2AEB17BB164FDA332CF82D8A479704
-:10C69000CDB79DF29DF0AB38CEEB9AE19B9023F4A1
-:10C6A0007872AA7702E3D7A9E653DC5023F76C7BB4
-:10C6B0009CF8A133C14D791BB3BED5F5DB607E7B01
-:10C6C00083EBEC807EA45E3658C439C1B86AB59459
-:10C6D000E23FF22F292ED4E34473FF9ABCAAEB0861
-:10C6E000BE1A794AC84370B92C9FCBA70D4D1F7D48
-:10C6F0006E9CA6AFDFD055EE5A12930769CF91B466
-:10C70000FCAEE27ADF11A5DB17A5EFD4C87C83FD70
-:10C71000F9BFEEAFCD46374742192A9202C28F00C9
-:10C72000E14F2C8010978B20C2A50F3989CA25E0D4
-:10C73000E6F236F07219CEF535E790BF608D0C2524
-:10C74000393EF5C2DF0B892F4E5D33D995A546EDF5
-:10C75000AB6E6F2FD7AEC6D379D200FCF090C6B7C0
-:10C76000BADE1E943E26BDDD3B16F5834C79A1C88A
-:10C77000A21729DFBBC7EEDA1AA31FC06FF4170791
-:10C78000D317358A88DBB75BDCAF531ED1FF5A1A4B
-:10C790000C245F7A399BFC49E4C7E40561251BF949
-:10C7A0002D3FD5F334F1B3FF812929AC87498F5C44
-:10C7B000897478579CB7C00A299087FBDAD529EA93
-:10C7C00045B7A70424B6E741A6C742085B691FB76F
-:10C7D00002B0FE5C0C2A974BC1C374C199138A51F5
-:10C7E0009FDCDEA98CDB807095A446B249CE8A26F8
-:10C7F0001E4D9570FD62F2639D9C6369277F4387A0
-:10C80000F3448EF0632FE67876115D4B52431B1E86
-:10C8100026FF6EA705C8BF3B31F13B77408C7D1CDE
-:10C820009157D545FB784E12E77CFE2EBBC88F4151
-:10C8300064A837C6AF0EE756BF44F3FD568BE7A199
-:10C840007B3D9FFFD4BA044E61DA10C6018E1B45B2
-:10C85000FAA7BF9CF9795C09E97B91EFF34305AF37
-:10C86000CBF577724ED4B689FDF8C9AF1A91E73B84
-:10C87000447095D850A511FC4FD8035BD8FF691CB4
-:10C88000457988654FDA2D648F8FA23EA5F3CE7768
-:10C890009A1D5CFE09E3142AFF8C710A95EF629CD5
-:10C8A00042E55F304EA1F2F6F3635129231D723D3C
-:10C8B0007F617D39C83E06D7177ECDBF86F9039DBF
-:10C8C000D3756B7C5DDCF9DE7D09C407BB64771E24
-:10C8D0008250B453E17CC2E9DD130272562C5E7DB6
-:10C8E0001182A378D71F1E9A5C46E3149784FD4FEC
-:10C8F000EF3A3B94E31F137C7DF8E8B2097C68F0C3
-:10C900003E9712DA40E39FDB994D10A23E00C187AB
-:10C9100044CF01F261002DCC27CFE708FFF6467B1C
-:10C92000A42CF65C12C8F453DE51B31735F285A47B
-:10C9300070A1967F9D487C9DFB3AADE73F20431E4A
-:10C94000F3A731BF50902BF0A097455D362FE545FA
-:10C950009EEBFAE39CEB110FB327CD2C9763E42DEC
-:10C96000237788E837F1B39F3C9CCEFD5DB4D4CDEE
-:10C97000B0B9C685FD6E71EC7D8550B0D0F56E4DB9
-:10C980000AD66FCD90F653B958CD9A9EAA12B80127
-:10C99000DECFD282CAFDC462B3DCB536B2AF952415
-:10C9A0005431FAB3DA914027A07DF51A579AA1FEC7
-:10C9B000B58C1186FE33D51C43FBF505630CEDFAEF
-:10C9C000BAB3DCA5867E24AFE4FFE23E98EEB05514
-:10C9D000E6F394A29D1FBFBD8AF77F7319EDBF17C1
-:10C9E000F1674307E1838AF53F7A98D4C6CE7D4943
-:10C9F0007CBE6AF233EBBA9EDAEF5107F7333F8120
-:10CA0000DD03FA67F583F8675FD4CF44FDF110E9E1
-:10CA10008F92176EE2F3F2E7267E76854AFE722E3B
-:10CA2000FA9F884AB3FFD9ABF99F66FEE9E3534901
-:10CA3000157C7350667DABFBA166FE01B84FB3E376
-:10CA4000A2BC5C399FFDA6B03B7F25794F8BE56B7F
-:10CA5000AD34E5154A6C680728DFF77B19B6D08737
-:10CA60000B08878EFF9C28DFC36D9B5F195EC6DFB6
-:10CA7000FD89B864BD966768CED5FC8EBABDAF0C93
-:10CA80004F8FB6C35DEF1AFAC3BDD27E43BD2DCB27
-:10CA9000587FB0727FECF8C1F4D0B24D77DA7C9455
-:10CAA0005F7E44E41BCDED3A3C35FBE23CA42F9580
-:10CAB000DD768E6BEA5D1ECE832883E44174BD7003
-:10CAC000B30C8D03E9B70DDABCB3F6C581FC25E6DE
-:10CAD0003D8ABC42F0F87F21ECCCD1640F7863D65C
-:10CAE000F961AEC8039F4AD9F86F9F62BF53BF0474
-:10CAF00037A1FE548AD0B7C59D272C16B213F182F8
-:10CB00005F8A5D614B2ADD53599EE0A773E086156D
-:10CB1000897E3AFF29C98EFCD181A47F2277EE431A
-:10CB20000EE4BBB72D1683DDE9255D87F56D4FCF8C
-:10CB30009943E76DD7EF8B0B5ABEC47EB6511E9357
-:10CB4000EC549590F745C437FAF916CA47C3FD600F
-:10CB500038EFA2FD53FD58EED7DF7C84CE6B0E0A72
-:10CB6000F9C766A739AEBC2526AE844D427E1DF8B6
-:10CB70004BFECBCA9737DA28DEF9AAE47E6FAE33D4
-:10CB80001A5F8EEE2FCFBABC371C16F27E66F727DF
-:10CB90006F925E3F83F62E56DE757CE972DEF0986A
-:10CBA000CCF2A87F3FBD5B9E111800BFCF6A7C000E
-:10CBB000AE7CC3F9D79AA9E7E6905D5BD3A5F0B93F
-:10CBC000DE60F6BAA1DD78DEF5DC1EFB72711E2C8C
-:10CBD000F6D1ABDBD3AE4F522B0B45D9C2E7AE1B20
-:10CBE00035BD23FC18B4A3D674B2A3B512E7D10E99
-:10CBF000770DE37B15872508AAE3788A9B1C48B745
-:10CC0000B9623AFAEE247F0C320A145A678E46CF84
-:10CC1000B95A7E675ED7BC3CA2D71F3B971CF66013
-:10CC2000D327B939BCCF6F809FFDC1C329DE4CBA71
-:10CC30005F30BB55F0F7E194480FE5830E4F4D9000
-:10CC4000E85C09E76F8BF5F70E5BBD998DBC2FFD96
-:10CC50009CF16AF962C265C4B39A3E447AFA25111E
-:10CC60009731FF2BC31F64BE5A0181FD1E5CB7DEE6
-:10CC70001D64BF741588F8DCEC97D74FF9D0467661
-:10CC8000C11C4756EEDA7B84CE2FFAE5134CFC7AB2
-:10CC9000A9FC81397E1DCCAFCF4FF566E4C5E4EF2A
-:10CCA000CCFE799F1FAAFB515B13F87CE7A5A98FE7
-:10CCB0009E5E85F5BBB626B8285E3EF9A4DD4F7AA8
-:10CCC000F9E4167B40C2F693A9916E8A134EEE28C2
-:10CCD00072E30CB0CCA2FED7B364D79FB1325FE051
-:10CCE000CA86FB096BA6DECDF7F6D66C4D94E8FE3E
-:10CCF0000C6488763D76937F9AC87EC18AE787F375
-:10CD000079A56E5F483EE87CF98327E23CE4E49F26
-:10CD10003C303799F2763D969FF3B93CC8F71EA395
-:10CD200073F755DB12C7F1FD8B4260BA2DDF721528
-:10CD30009F536E547C9368FFD53FBD6118DD075B40
-:10CD4000F1872140FBE9DDFD3C9FE345FDF481FDDA
-:10CD5000BB33BB7392A1308A273D9FD7FE748B975C
-:10CD6000E85E2EA9E2BC051A3D23882F76D502CDB8
-:10CD70003B4E16F73D23EB13D82F35F35D6D9EF038
-:10CD800003EBF4BC411A3832487E7CC078E85D3F42
-:10CD9000660B9D6BADC84BD5EC74247F4ECC7DC229
-:10CDA0001AB9BB9EE2BD339BEC9CCFE8891BF83CD3
-:10CDB0006B615E0AC3B7CC613CFFAE6FFACC582FF3
-:10CDC000040FE99D71AD6AE99D58AED5F0DF92E997
-:10CDD000F5E5E17A2B3B7EF0C2AB8C974DDF7E9B75
-:10CDE000D63DE01479945705FECCFEFF3287C85734
-:10CDF000006C6678F5EF279E788BCF494FEC1C933B
-:10CE00002FCE7F43EF3F9EC5E7BEC7EEC172C781FD
-:10CE100037992E6678FB9DDF4912EFB78EF6914663
-:10CE2000E7B4DE6FE7F1FD1D11B72DD950C4F8D37B
-:10CE3000CFD17A4F0E1C9FE870EAF3EBF0E9F3EBE9
-:10CE4000FD5A357A5DA7C507A76CA1D37C1EFEC22B
-:10CE50001889F2747DDF5343C52931FCF255E5C5CD
-:10CE6000BFA9E5358E585ABE65A3FB6D1D0F5B7DCE
-:10CE7000B17AEF32F3E17D7EA00754D750614AD8F2
-:10CE80006EE1E694A1746EA7D54918B03E45034FF4
-:10CE90002278E8BE9F56C24A5F06E7BB693E99AE5C
-:10CEA0000F06B8DE5AE956A9BC56F22AE2BE5680F1
-:10CEB000F9723A348EA47D581C613EDFD2EFABCCC0
-:10CEC0004B59774316AED73604D6911FD3661572E9
-:10CED000E15F9CC0F19B8E27DDCE80ABD0605FDA36
-:10CEE0005CA02A38CF7C05DAADA9A2DF9588E7C31C
-:10CEF0000796BC427EC25B4AE3105AF7A8F3912220
-:10CF0000C942FE5D209162C4B7DF7CA6FCF7D8F76A
-:10CF10001DF04C7522FFDCF41B07EB7D733EE276BF
-:10CF2000F0717D1984AD1FE3B83F4FFC9FADFB202E
-:10CF3000BAAF3F4FFA7427C507B7A4DC574EE3F5E5
-:10CF4000FB93E67B7A275D4EBECF67BEAF7723F8B3
-:10CF500042C4CFE72CBE7A91FF689C40F6B737C534
-:10CF60000612F6EF1DA2E1E314303E7AADDAF88F37
-:10CF700054AE97558FE3BC229C53591F4F36D99B13
-:10CF8000B2311611875D14FDA7461483BD292BD13C
-:10CF9000F2367F57D92FBDF6BCF2B9F6A82E5FE462
-:10CFA00059CAD22C8D03F98756ADBD1582B2D88FE0
-:10CFB000F01326F7F1954726FAD56BF57AB267C8D4
-:10CFC0004FBD490E3F5D509CBC5BF0D76425B897C0
-:10CFD0004AD4AED0447EC52EB4773A1C74D697316D
-:10CFE00086F96092CE9F38D702ECB74E6AE4B8C596
-:10CFF00041FE0C961BA410C3710D44B8F46876BCB6
-:10D000000ADC5C4E032F97C89F5CCE404B42E5750F
-:10D01000D0C1E52C0809BB7F75B095ED19DCEBE2BA
-:10D02000F86FE6320BF91B65DF18385E187D493C56
-:10D03000A0C08DBF7C3C4C0794BB9C01F031B280FA
-:10D04000F587191F66F99C0A6199E59314430EE56B
-:10D05000095496D36AF070BDE60BE2A122EC533876
-:10D060004F63C647F5C07CE1D6F0F1E77C10E71FBF
-:10D070001A9D96E6AB5CD7E985729541FC6FA6A335
-:10D08000FEBD2CA1EA2C5D29BF7E5BE65CBA1F5574
-:10D09000565AB59654F282FCA2B9743FAA6C72D566
-:10D0A000F37474B9685BB1A89754955ADD68DF5A78
-:10D0B0004AE64EC3FE3EED3E31CC17FEF55D9ADFEB
-:10D0C000E26BF996DB8572E2CB74BA697F0E74EE7F
-:10D0D000E95E8A9C23CEF946CD08EEB362BFA38AEF
-:10D0E0006F7A3E9DF73982492AE2FDAE961ABE7FDD
-:10D0F000F6804DF4B7DB457E55DF177EF7C7617DBF
-:10D10000C78E316BA5ECC1D7C779E7E60F2138F29E
-:10D11000FC24AFBE9D925B50B26AD87C94CF9E90A7
-:10D1200015281FAAAF939EE99B4F7080239FF3643D
-:10D1300023347FA667C798314497A5F9DA7DAAF40E
-:10D14000AC52C25B43A67729CDDF9B28F86B29D16F
-:10D1500061C8E0E5F7F23D8B697EF3F7DEBF2200A0
-:10D1600038FEAE7CDF329AAF21E102DBF7D363FFFA
-:10D17000B02E9C15E5530989B400F7DDEA81808D56
-:10D18000ED8076CF5C3B77EABD1DE7413C94797D2D
-:10D19000ADA4D2262C888C27FD89F3AEA1751B6C1B
-:10D1A000E1516371DC23738FD9049F8D147CA6E950
-:10D1B000A1AE3D07EF1921AA5E8891AB863D9F7D08
-:10D1C000FA0EE2AFE18CD34DDDA3F2F4E3B51C4FD0
-:10D1D00082D3A03774399BB4CBCE7EF5E4DD57DD26
-:10D1E0004EFDA6FEA13B87F6756D7798CFB37ABB4F
-:10D1F000DE1A21E0D0E38D73D297B1BB74DECA7121
-:10D20000DC4E71DEBA466A7C2991EA3F93DC7E846B
-:10D21000FF846637F4B878B9B6AFD507B7AEA3BC0C
-:10D22000C8F24D4B67F17D9C80881B54FC25F9FFAB
-:10D23000045EE573EE55DBCDF144C446F45FDD6179
-:10D24000BAD743F130DD5F88D5EF03C4C34FE56B38
-:10D25000F9AE4CC8E47DC80B927D03E83B73BCFB80
-:10D2600018789EC9677FD62BD3FAE5CAC0F9842700
-:10D27000A2EF3B581E96696B139E9C1CEFDAC4BD4F
-:10D28000DF27D6BA5D54D7E47333F24A05F9D16D7E
-:10D290003F66FED7C7E9F2BAA25DDCAF864D69CC26
-:10D2A0007325DBEC1EA26BC9B6611C5F601CC47EDB
-:10D2B000DFE66DF676AAB7DE1FEF974B289F1CB905
-:10D2C00082F22AAD71E27D129947BAEF59922DF29E
-:10D2D0001CC774BDAED975FDDE6C5FFC9398CFF7AB
-:10D2E00093FBDAC38A21DE68D5FCE732828FFCC06B
-:10D2F00046AB889FE204FC7BDFF87A02F9B13B156C
-:10D300006F02E5A5CF1CCA4E8601F0A697E5685EC0
-:10D31000E073CE0BCBDF9A95F379F42A7B4CBB6795
-:10D32000AEF1E7AF9A3DF0176B941EFABE6AE46760
-:10D33000AB6D94E7B80D5C94F75873F0A9567A2753
-:10D34000B3663D7046E10CFDA178E1030B9F674F8A
-:10D350003A589A41FCD8A9E93B3ADF5563F86A3C50
-:10D360002585B07FF94808D0BBA138351ED498B8C0
-:10D3700038A120D5504F745F61189F5C916D68078C
-:10D38000BF2754383EEABFA678AE36F47F20693A0C
-:10D39000BFA3991ABA83F34A6933C619DAEDC8D71D
-:10D3A000745F013E16FE4F05FEB25D854699E09C16
-:10D3B0001C06F809F2DDA41EA37F5411DEC87160BB
-:10D3C000DC21C510D7DB2F91674A1AADC9D54818A3
-:10D3D00029F48319DFC67B0D6B0ECAECC7ADC944B7
-:10D3E000C7336B707CEBF2A7E37D88D788F761F3D6
-:10D3F0008D781EEE33E279C472239E331B8D78BE86
-:10D40000B2C988D72CBF118F39ED930CFDF3365676
-:10D4100019EAA31FBBCED0FFAAC01C437DCCF66F78
-:10D420001AFA17752C31B497EC5AF9B9741F1B5CB2
-:10D43000636837D3BDF4C0774D7CA8309ECBB577F9
-:10D44000553AFDFDF84BF49F0CDEE4A044E9407F23
-:10D450002BC9E3BF8AFEB3476BF75874FA7F41BD0F
-:10D460005AA8F94FE6F759B31384BE79EDC0994332
-:10D470001EACBFAE965A33C86FD2FC03AF7E1E619E
-:10D480008AFBF438E5C60AC974DE1E67386FBFD45C
-:10D49000FDB4F250D0501F7B48BC6B1A77C4FD120C
-:10D4A00095E5EF79E4D8774C133F66B3DC2FEED4E3
-:10D4B000EFB9E97113643CC971E8021D7E1282F173
-:10D4C000FDF38B7A7C6A8E5BF578B5FF3B29E1979B
-:10D4D000DC2D0F16C78AF8558F5BBF0E1E7E0F56C8
-:10D4E0003ED2B76E34DD9FB244D2A85D8F6709B1DA
-:10D4F000746EDC4B8865E7E2E05C4F21BF23E5BC3E
-:10D50000F7CA9657E6D27D7D04DF151E2FD23FF471
-:10D51000F3E468DFC6D1A8778F4BAE75A538F6B5B2
-:10D52000491F8EA2F91E1E2DF20C76193184F66762
-:10D53000D8020FD0F7FC54CF23A387F4BF676D2E1A
-:10D54000CDF77F3A9B835C2A2E37DFBF31E707C3D5
-:10D550001695FD4EFF7725BE6FF321013731EAAFF7
-:10D560009C69B7B2BF025A3CBE50C3BF9EB758A019
-:10D57000EDE7384EB11CEDEFC25DBF61BAACCAE851
-:10D58000D1F21D8DEC5F2F1DE91CC7F7C93CA56EBC
-:10D5900091E7D2F318232EEB9DC8A5F6BF2AE3A48A
-:10D5A000218F04CFA67DA1F3EDE8BEC5FCC7D78BC4
-:10D5B0007CE4F1F5999CFF8ECE7F9AF3490B1BDF3B
-:10D5C00030C8C5AD4D470D72B0D8FFAEA13D9C1E11
-:10D5D000B152FE30FCC2F0E9B720FE4EEDB4F33B91
-:10D5E00066E4833746C7E4CFC2EBC74CE3F79097B6
-:10D5F000DCE7870C47777388E9ABEFF358F311AE9C
-:10D60000879BC35C9AF7A9E729F4D2B60F0AE89E74
-:10D610007D448A77535ED89CBFB8DBA2BECFF72289
-:10D620000BB2B57382C6122FD34FE42BBAB577A1D4
-:10D63000DDDABBD06EED9D67B7F6AEB35B7BBFD9CD
-:10D640006B75B6535EA35B12F77716489E2717E3F8
-:10D650007AC9237D1F915C35AC8C142BB84E43499D
-:10D66000789184741E39C4F731E145C2706138BFC6
-:10D670000BF2F33DAF0F2CFE627A47E32EC8B88958
-:10D68000E2BC0FE2FDA7C91329D89E26EA362187FE
-:10D690001505FF60B97B0F27A3FDF97F2989BC928F
-:10D6A000336CA3775053D37D503044DCDFE2F72F47
-:10D6B000F89DF852CF73F65A851FD8ABF983F6025E
-:10D6C000710EE83095D944F3725A0F343FFFC17C94
-:10D6D0007E37B2C90EE4BFE2FAFC4E46BF67627EF7
-:10D6E0004733EED7767EEFA0E743471464F17CF42E
-:10D6F000BE86E432FD7B09ACB7201C1A45EF71FAF7
-:10D70000E03D24DE439EA23C724CFE794481F6CE7D
-:10D71000F13630BCE7597DF0F8318AB37E3DDA77D7
-:10D720006501CEBFC4A28E27BAAE4EDACBF9AEB138
-:10D73000052AAF8BF08AFDCAD046745AED08737E75
-:10D74000EC52F9F0C1F67FEAF6D08F0A39FFAB163A
-:10D75000F37B3A6D5D84636C414CDE5A87233ACF8C
-:10D76000E7F3BF9ED7D5EB279E78205FCBCBDFEAD0
-:10D770001DC09ECED0F0D26D1D388FBEB440C423E4
-:10D78000FDE8331A4D11DD538C471B81E53CC21374
-:10D79000E5816FC6FD707EC23396E8BB7A8E93DF5B
-:10D7A0008DEBF3E33CBE9F7FCE3A2D99DE1B89FFC4
-:10D7B00056368ABCBBDEDE2B09BAFAD78B3CE8EAC8
-:10D7C0003D478FD1FFBF60C54F8B4A39BED7C69B3F
-:10D7D000F18CF8E5F74D4B64716E85F85D40F39B75
-:10D7E000F3ED5F16AFBD99E27CB577F367A3E8DD93
-:10D7F000E86ABA7F46EFBCB4FC15741AF352882F5E
-:10D800003FE52BFA9F47019F6BD9353B62D7C78F06
-:10D81000540CE3BB9DDEB5C41F2F687A03FB072CB5
-:10D82000B87EA71E279BF2289D2191EFECCCB0B1CA
-:10D830009F4CFE0ED927DDDFB9EB0D91EFBC2B4BD2
-:10D84000F8D1041FD1573AB29FFD843EFB2FB95542
-:10D85000C29FDDEABB9FD607DF5AB65FF295485FED
-:10D860003ABFF8ED755A3E40D8C372CDFE95D33C11
-:10D87000E4E01426B35D2CD3D645FF91F36E13C1BB
-:10D88000D72A80D1F266EBF7731EE17F01BC43AE6D
-:10D89000E0704400000000000000000000000000F4
-:10D8A0001F8B080000000000000BFB51CFC0F003ED
-:10D8B0000917B0A1F2AFA1F1933951F93F5951F9CC
-:10D8C00017D0F884B02E1303C30A46D2F420E39D88
-:10D8D00040FD0780F838109F6322DF1C103E28CCE3
-:10D8E000C0F0458C816116906E01D26781F82B10D3
-:10D8F000DF06F245441818948178BE28034314903B
-:10D900005E0AC40522107D8780748D287976AAF37B
-:10D9100050E6E6514C195E298DCA2F55616058A614
-:10D92000CAC0F05A0DC25F8824CFA0CEC050A60254
-:10D9300061EBC931307400D5CC94C66EAE3E50BE9A
-:10D9400013282FA00EE10300D191FB3B68030000D8
-:10D9500000000000000000001F8B08000000000015
-:10D96000000BCD7D0B7855D595F03A8FFB7EE424E6
-:10D97000B9819B90C049081834E0490C0F11F12679
-:10D98000441A6CC41B8C1A6768BD606B231588C869
-:10D99000687C4C7381248497066D2D83FEF462AD00
-:10D9A0004329ADD16287A98FB9202D689D1A2D56C4
-:10D9B000ED4FFF46C6B1D42A7F44F1552CB3D7DAD8
-:10D9C000FB24E79CDC04D0CE7C838FC33E673FD62C
-:10D9D0005E7BBDF7DAFBBAA104E0128053F8873D05
-:10D9E0006F9000206FF0095EA3092200CD9A5B5F63
-:10D9F0005F0CF04DC538A857B1F7A365E3073ABEF1
-:10DA00009F580B610005EBE70318F83FD66E4D7089
-:10DA1000F5A84490BD531666E1D3ECDF7C36AB002D
-:10DA20005A257EDF3831D377F30929577F9F17E8CE
-:10DA3000CF29066AEBE1D727EF37CBECBF020845C9
-:10DA4000DE0AB0BF4C87E9A71480E3C10559691805
-:10DA5000BEBFB7DBBACF5327007CD4F6DAE4FD13A0
-:10DA6000867EFFA6022D3DE543DF4F0736E854C40E
-:10DA700047D21D9F3C38EF81790619922E64ED0143
-:10DA8000D29E1CF6DCB1F93CB56C104EE73C00921E
-:10DA90001CBF9FB39D2752932E60A50A29318BE0AE
-:10DAA00052D93FD300A82A5B97253B1A80E072C069
-:10DAB000DB11F9DBC03BEC7A897AC783AB3B91B4CD
-:10DAC000D6B838BDB4E7C9C66A184A2FE67A98783E
-:10DAD0003CD3F5B81D7C348E4947CDF2C211D7FD39
-:10DAE0007474743DD2D179FFFD7494FCDF4B471DF3
-:10DAF000D4CFFF323A02E8E6F8823E15C71F7CCF4A
-:10DB00009F91853D12D2192BF622DC457C28286A8C
-:10DB1000EDBC599EC2C41418CF9DC3E45651DFA278
-:10DB20007A847BF4E1797FC26767634DDDA56C7E03
-:10DB3000F94D3D2F7D893D23F1949460EB751FC80D
-:10DB40002854587F3725ABD9FCDAB1B399008F241C
-:10DB500017C592385F88018C02F8073127005957A2
-:10DB60005939447FCD340F37A4393EA4539EA1EDDB
-:10DB7000879B7F08DB99758AF1FF2B00E777BA76E0
-:10DB8000B0928F9764FF20BEC70C8E4FFDE4375BC9
-:10DB9000CA80F8B17FEFC5BF107E6FFE1F19AF00BE
-:10DBA0002A7D281F42F5B296C2FAD093ADB272E434
-:10DBB0002615D24C461454754B2EFDF4EBD2095069
-:10DBC000D7C3D7476A080DC2F79F2011FD8CBDE36C
-:10DBD000CDED6B19C99D581834883E3480DC9CA16A
-:10DBE000F3F94E1B12B2A5DC582325683CE3B95269
-:10DBF000D63ED9C8F5DE7DF50BB2ADF2CA23490297
-:10DC00006F4EFA005D9D866CC5E943AD9763BE29F2
-:10DC10005F9C3ED4CF491F792B2DEDE0ECD72B62D2
-:10DC2000DA0567481F5F743C735D87F2D52AB1AE91
-:10DC3000A53E607C7B6FDD828C76C6F0EB5A49FC9A
-:10DC40001EA987582A43BBFC81F54C0E7DB2F551C5
-:10DC50000696F716DB7A29A3A7356D1F011F4AC464
-:10DC60003E5FB35F5FABA2BF99CB8AAA26637F6E8C
-:10DC7000EC8FD1D9BAE8BD4960FC7002699BE143E1
-:10DC8000E9AE4863194AC1F881804066655F349601
-:10DC90005A4F7490A27531E1F3E8B20DFF6AC46F78
-:10DCA0002B435352B2C2EF6B75131C6E1C8FD1BB4A
-:10DCB000A2B10E192AD420A47D61ACC1E14732384B
-:10DCC000351ECB77DAE8A04BAF844CEB60D22BA2A9
-:10DCD00095D3EB9D67265F9CE335DAE13DE3764122
-:10DCE000557FCBA287866FA7C25BE6FA30247E0DF4
-:10DCF0003B983AB84E6B5DB0473A9FE9EBC2AB2117
-:10DD0000C1DEAEC54F17129D923DB3B6B05243BAB5
-:10DD1000821D928A709A7A14A23954AF42D2A91FF6
-:10DD2000D9DB02584F09C6E8697E1F1E2E417FC904
-:10DD3000D8DE52D6EFE5627D2F177A0DAA5C6FF61A
-:10DD40009970939E5507CB6C1EEFDECEFEC7E8247C
-:10DD50005921A57E200DFD5E8F7A91C9A57A7C6F31
-:10DD6000912B5B06F8204AEB552FBE3DFBC4AB134D
-:10DD70002F60F4D16B2880626BF5139E582DEBFF5A
-:10DD8000A58BA5944712F03238E70B385F88E5166B
-:10DD9000219DF6D67A888EE77FE9A30892F1B13DFE
-:10DDA000BF5133D1CBFC59AE4138D87FCBADF363F3
-:10DDB000FFFDF3C0BA14D238265C4B2B1582A37733
-:10DDC0009694C271F6FFFE8F775FC4E07CA14A3261
-:10DDD0003C3AC11B02365E6FECFDC8887E8739BEB7
-:10DDE0000E1AE2D339BEB91EE1314078853F30BC0E
-:10DDF000B2F19235FD7D6B10CF4724630D1B2F6B65
-:10DE000076EB381CA7589609DE75B3BCB2C2E8079A
-:10DE10005E1B25233E8382CFB3DCDDDEF10CCECE4C
-:10DE200009323CC45EAD2B1D599EB53BE499AAC591
-:10DE300063126BAF27B54A6504BE48C5E4BA4CF21D
-:10DE4000EE7989EBC98EE402AD14A7B7DF6E07A2A5
-:10DE50005E8A5BF42AB3179F97D8FC5D114EC7D931
-:10DE6000B5716E27F68E22F91510EB9135654116C6
-:10DE700064B083879D071B2893DD9C2D73F8E030E9
-:10DE8000EF5F35FBCF19B9FFB5A2FF8F9B25E845A2
-:10DE9000F8D4B817D71F621544CF7E419FB03287A0
-:10DEA000CAA6DCF594C5BB8AD93A7AA232E83ACE42
-:10DEB0002F49EBBC81AD712103C55FCBBEB3AA1B5B
-:10DEC0003E53C82EC9964F24930C8E0D7B6F049D34
-:10DED000D9A9FE680AA83CF9062FE26703530A7C19
-:10DEE000FC1EC0F1038C6C51BE06987CD551BEEA75
-:10DEF0003D699995D53A3062EC534833243F2399D4
-:10DF00007DD192552A7BDFBE10887E01AD080B7E45
-:10DF1000DBA32FC71406576713905DD319A9A1F986
-:10DF2000B597D7788BD1DEA957E93D9C64F830EDE1
-:10DF300010260FFD6510C3F136E4432A88BC549BBC
-:10DF400047F4E8D6F8FCF52DA590BE807DCF9EB6AF
-:10DF500017C74FFE231813F89024D754932ED44498
-:10DF60005242FFAE5533D667A0BB2D90C892A7DAB8
-:10DF7000E894F4AE136F596EB80CF1DB59C1E8BFE9
-:10DF800078683F85C83F8CDE52C6822B4A328C535C
-:10DF90002CEB441F6659FFD84DF00F577FB01EB3CE
-:10DFA0003373B1EB98847881DA08CD2F0706FEC46D
-:10DFB000B09C2BE63B0A5AA85E7446F75EE4B38237
-:10DFC000584F35E2E23BA1AB5FA2758307358C4722
-:10DFD00030684B4FE50ECA895890CB89E3864CF2E6
-:10DFE0003124A7B518EB20E4EB8D92B2D681FC88E2
-:10DFF0002C6CC2005EDFD63D19FDCB3018127E0FAF
-:10E00000196AD22A7FB280956DF61F1C2A9D46A4FC
-:10E01000C5F902B4BDC8325A59CB39D8DF7D0C20BE
-:10E020001FF393378612A42F3EF285A7E0601FC925
-:10E03000F1AC346F5F8676F76D8ADF588FF46070CD
-:10E04000FDE065FFA0FCCB9AA1DAE47176CC5ECE50
-:10E0500075E88DB94A90E69B7D39087D10AB9F30FD
-:10E060006A103E065903D2CDE65A1570BC6090C3C3
-:10E0700065C299AB9C4CCB40701C4138187A088E15
-:10E08000701990BFC7E039E280E788039E23567875
-:10E090005ABD7CBE4EBF7FB12CFC7EE6F7A21E3C73
-:10E0A00001EFC4EA90606245A457C21AAF1BF4F6B0
-:10E0B0009251A58146EBEFF4FBD9FA1CB7E9871919
-:10E0C000A2AC33BBBE84E0B37F8742A2132A2B30BD
-:10E0D000E0BF2E9E61E247BFE6FF32BEBBF1A00B60
-:10E0E00090AF18FF2AF8DD25BEDE28FCD8C5A8FFB2
-:10E0F00099DEFE1AC4C308DFBB2093BDFC2EBC1CF6
-:10E10000BEC02217EF93DD428FB305B5F22F185131
-:10E11000F4ABD56067AF1226349874269DA2753390
-:10E1200080FCEE20A7B7247857917DD1C5F5A3E9EF
-:10E13000F77DBDDBAEAFBFB1C55EBE01168C42FA46
-:10E14000BAE1DB2E48B17E6FB4DA1F6C7DEE9035FC
-:10E1500082EF1BD0D2A905C9CE6AC2792CD6404520
-:10E160003F6DE9BFFC9F698BD87CB60A3DFA3693B8
-:10E17000EBBA456F2C89A4DCB1F2A1F35B2319F350
-:10E180002F92869FDF5A57EF7CB40F929B5CE4D7A7
-:10E1900081D35FDBAD90BF666947F05EDF659FDFCF
-:10E1A000E9E6EF9C2FF35868BE4B762C22BD39DC94
-:10E1B0007CDC3BA4582A837E7BCCD48742BE98F477
-:10E1C0006DF275B206B8BDF7FF7CA9356CBC57502F
-:10E1D0003ED2FAB79CCFE3282DD3F179BA76BFFBB4
-:10E1E0009CEDFEF039DBBD29E4B8B3DD526F9F1B17
-:10E1F000D773B99AAC93E4413BDAEB6A898D61A895
-:10E2000070EDA94EA32966A9D77586F50E4A256734
-:10E2100054AF4E1EA1BF63C2CE38B0EBFBEE3EE45E
-:10E22000BF9D6FCC47FDFECD2715F0B2791DDB15E4
-:10E230008234D2A79A72A3BDB284D1558ACAE96941
-:10E24000575AEC2A46B1D4FF371F0D917DB0E471C7
-:10E250004FAA9EB55FF2B3FF98020C0FC756F7FFA7
-:10E26000720CD2EB4E89FB7FC9BE2957B2F74B54D3
-:10E27000B82E9E814E6485F3CB3BFF1A6842BB4F9C
-:10E28000DAB1F7ABD46FCF352E94CB66BD4F6417A0
-:10E290008DCBEAC5F07BF287526A82C4E16B983C71
-:10E2A000D4EF7EE78712876F8F2BE543F8766C7784
-:10E2B0002758BDE53BDE23BA9DF3E88FC38887E589
-:10E2C0007B149BBFBB7C8792F64CA1E71BF844CD27
-:10E2D00028317E5B26F875D9EEA5A40796F56C78F3
-:10E2E0000FF975F91E974DAE33BC1869C4EBAB8AB4
-:10E2F000518FE59FFE735867A87A3BBA33AC9553AC
-:10E30000BF8BDC8CAEAE98616F87FD7F9C33B43FD2
-:10E31000807E8A6B2EEF59C7C703AE6F4C3E7D1BC4
-:10E32000FF923F546F4C52ECFB0E27E08569148737
-:10E33000DC919BD18F33F585C9AFDFFCF1896D4945
-:10E3400036EE3B8FFF795B92C17FD35FDFDF7627AD
-:10E350009B173CE3D3500E2DDFF94A182C78AF55AC
-:10E36000B81F76EC87FFFCC856C62FC75EF7905DD6
-:10E3700077ECE93F8ED5D9BC8F3DF6C928B43B5721
-:10E380003E7DE968A4AF954FCC190D23F80F48AF37
-:10E39000298F755D53B4AEFA1E098330004F89A7EB
-:10E3A000637D9EDDADA43174FBEE6B9E9487E167C7
-:10E3B000397BD75A89EBB594F41096EF62785EB644
-:10E3C0006BED7BCA944CF84E8E91A3F8646C13C528
-:10E3D000F5BEF28A8BABF0E93274A40FE827F9EFAF
-:10E3E0006CB7FC105BD7F3875FC71370D28DF85FF3
-:10E3F000BE6B1D1FD7B18EEFE25F2ECCA0FF87ACA6
-:10E40000E34DDFDB8A1F77E7D2BA0FB78E4B9FB899
-:10E410006A44FFCC9407A7C36FB3C4E13A5F89ADE8
-:10E420005090AF1EFFD1235B237C7DEB19428EFD04
-:10E43000F8C4580C2E1F75F57F15E564FFD31EED4B
-:10E4400021D666C9D3AF129F1D7BE225B74E72124B
-:10E450008212D37BC760E04F2FEAC165122F2C7F59
-:10E460003894F68407D76959AAA14E0FD3FB37E831
-:10E470007D8AD3FFB2D4DE4629C3BAED544AB85CD4
-:10E480004EE5115E96EABD6E2D685F4F6906AEE3FC
-:10E490001B7391EE865B4773FE1ACE7FBA653D1FF4
-:10E4A000E67C3B1C7F1EDBEE51A5ACC1F53D26ECA6
-:10E4B00083E529E955C8C0B700AB39BCC3EC3F9A26
-:10E4C0004F273D3CECA007B3BD39EFD3F1F5E9E7A9
-:10E4D0007376F8FAB6A2DBE8C6C4DB3B2733CBFB86
-:10E4E000B49013CB205957307EA8BE52219E1C53A6
-:10E4F0003C086F678F4272FC9D1D0AD9E94EB9B086
-:10E500006C187FFCD70AB73F96EDD93B05E5D73BA2
-:10E51000FBFE55D021A7F365BBDE702785FC4F5964
-:10E52000E53FF697613D5E13702F7F2A737FCB77AF
-:10E53000BD97B1BFB7D5D83508FFDBBD2E48B22E89
-:10E54000DEEE5132C637F6292E5B1CB73334EDB5FB
-:10E550002C8C6F86FD3ACE7BCDEAD8AB49B4435EB6
-:10E560007601D981AA71D4C3BEAF09F969DF7B4DA9
-:10E57000F806D02D7ABADD8127351A273F588DC489
-:10E58000AB78EC3565F3475D9A6C831BD46421C688
-:10E59000537E5DFC4715FB7D11EDBF7306EBBFA8F5
-:10E5A00042472EEBEFC59864AC820CF12947FFF18E
-:10E5B000590AE8563A8B95C9D6F86A78DFED149770
-:10E5C00068859634C689A0107A7E60E9F7C1360D59
-:10E5D000D26C7CA82B93ADF1554F4B4BCCC3E028AC
-:10E5E0005CA995A06936DCF8452DB23DAE2DC65F1D
-:10E5F00021E209B063E7CE9DACDF3AFC56827E0C87
-:10E600008F5731778AEC9839420EFE9BB083F749D9
-:10E61000F1FDE867C5F4CD2ACA39A974B38AF6C4F6
-:10E62000BC93DDEA620B3DCE2B5D5588F472F0336E
-:10E63000A529135D35AA9CAE5615AF2DC4F6077DEE
-:10E64000B7157227344AF32C10F3DC5FF48D601F8A
-:10E65000EB776FF137364E6470D54515C0784B5D5A
-:10E6600064D1C60A36FF82438AE163E582E6A49A52
-:10E67000983C749C6D28EF19FE1E423C32F81F6EC8
-:10E680008B52F991369D9E3BDACAE8B9B3CDA0EF23
-:10E69000BBDA6650B9A7AD8E9E8FB7C5E97DF80E7F
-:10E6A0007F02E977775B13BDFF595B829E352AE7CE
-:10E6B000B779021F9679D33E58637B7835C6514CA3
-:10E6C000FC39F15DCB282E87F60D241DF13D5AE56E
-:10E6D00072C589D7D6D620D9A5DB24B0E1739ACAF2
-:10E6E000EDC8B880E3696FE23215F7F9EB4ACBC9A0
-:10E6F000EE81B881727A9B14BFA782F1CB81A2E927
-:10E7000051ABDC0D051371D5422F63BB787C66BA23
-:10E71000CAE5531DACDA9FC5E08B9D041DE9CC9C76
-:10E72000E7BE6ABD10E5E2BE550C9E72FC2E439911
-:10E7300085CECCFE660AF82098594E0FD22DE7FF01
-:10E74000E8CCB2CD1827668EA7314127ABDBD66E59
-:10E75000B36AC6BD75A263934E18FF1C288A503752
-:10E76000DC5F6C2EE6DF7D9CCE5BFBDEA3F856748F
-:10E7700014D8E28D1DCD32F9395B0FF3B8F489E678
-:10E7800092CD1359FD6A8637F4DB73E69566252C26
-:10E7900074BD51D0D3566F3C4B1B417F758A7A664E
-:10E7A000F9902FF12D5C97EF8EFB493ED2F356572F
-:10E7B000EA5A948FAD873DFA6A36A593817812BFE5
-:10E7C000C70BD97B06D289BA951E9A5A90EF3FB4EF
-:10E7D000DEA56F3EC7C2E721C3CED7DB5A478E4BBB
-:10E7E0009B706F43B84788CB9A709BEB71A2AEB118
-:10E7F000FF1B30140FCE7E73E6358E38FE83C8774C
-:10E800001EC2C3362BBD15B668B4CF60B637E7EB72
-:10E810006CEF9CEF60BEC299EDCFF4B82017D7F330
-:10E82000B1BF8CFDE98B804B1E57508E5DA7267AB9
-:10E8300010EFD3A085CAA0F6E723BFFCD6CFF970AE
-:10E840006BE723F9C4476AAA18F5C2998ED701F17C
-:10E850007835EA2D4336ACF2DC7CFE4235E30469C0
-:10E860008A1FD116331B520EDC15CD84E781FE0BB7
-:10E87000D577ACFB491B01B89F9EF6D23E070644F4
-:10E8800034562E3E0895EB597F3B853CA956B95F1F
-:10E8900078C1417DBBC2E3474A43C88247114F3527
-:10E8A000E3581D701768ACA95BADD88BD54D3EBC45
-:10E8B000C29DF82DE2CB1DD569FFDD1549105F81A2
-:10E8C000887FCF1271FA4B95C301945FADD01B388E
-:10E8D0001FF9F99002E41727C6135F5E34CC3EE1BE
-:10E8E0002E619FEF10F2FA1141370FA3BC66CFEAF9
-:10E8F0009EDE34B2F4AC875373F0F99090DF292197
-:10E90000BFC355FEB4C4ECCEBBA71D4DB43038BA5E
-:10E910008F1E5770294D793153C067CA87993E0EB3
-:10E9200047B8BFF366B4BFB7A1FC473DE73A30FE36
-:10E930001E86AF8E84DBF0907C89D7B5E03C0A65FB
-:10E940009AC7CF0B6B641F2B3F658081FD3DD816A6
-:10E9500023389EF2F6BFFF22C6F767B98D247B1FCE
-:10E960003E79FF2DD86F58FDD13FE0135213F8FCCC
-:10E97000855C32F9ED59D70109F5F9D38540E38576
-:10E980004FEEB90DEDE7F0C9E76FC77697A4A03653
-:10E99000C0EA072B767FF97CD67FD6E532A0091A2C
-:10E9A000ECEE4F74B3FAA5AD2DD538B57F93D201F7
-:10E9B000FC9E9CA7921C1C0BB15518E7C8DB9890D5
-:10E9C000F07BE8418EB78BB6F4FEAA1A109FDA3EB0
-:10E9D0001C6FBCAB98CB5FF9B939B8F7E2297AD391
-:10E9E00087EBFAECD11580F2CAF3814CFBF14F7F33
-:10E9F000B002BE61CDAF38AA668C838D7779F8BE40
-:10EA0000D5070BBAA7E89CBC907F66FEA9D64B7CC5
-:10EA1000FE02D8F661CDFD2AB37D859418EFCAA316
-:10EA20007D09BE7F25DA5FA4A02DC78A7F96F97E77
-:10EA3000693C15B0C641827F92E399ECCC2A974A93
-:10EA4000F0B41BB5477FCDC653A75F4DFA17BAED9B
-:10EA50007038DB3138AA381C1C3E138E2246EF3E3C
-:10EA600036FE53C77F978FF07D5C67EA95DE00FA2C
-:10EA7000F97B4FC8C46F9BFA81F4CABEAA7D5EC4FD
-:10EA8000E3C6AA1A3FB773383DE6087A7CB88ED73A
-:10EA90003F51C5F7F5E1E429DAF77289EF3979FBDF
-:10EAA000BCB457918C05ABA7A17E32FF58F2081871
-:10EAB0006E8A93F63C02B935C7562E8202477E4ACB
-:10EAC000C9A05C453FBB2EF2FC38064A48EC3B57D8
-:10EAD0009BFBD8CA6103E7FF80A9FFDABCF4DCDE48
-:10EAE000F25000E31CBF30E9A4B9670ECE6FD64DDB
-:10EAF0003DCF86D97C2E3ECAF7CD9C792928F75088
-:10EB0000CE6ED4D2B9563D0AAA87E031F7372E3EF1
-:10EB10006ACF5399E5C84319928F75967EE572972F
-:10EB20003DBFF0046C9C4474D15B625B9FED173277
-:10EB300037E6FCA1FEE540BFC27F8228976F3942CD
-:10EB4000AEDC7D87D28CF651F8B2CA6CEB7E68BB26
-:10EB50008BEF9BEDFFBD0730FEBEB6D64B711B732E
-:10EB6000DFDC5CF70D986485F90DED3F0B205E9FAF
-:10EB70008C94F8F0F9ECCC9D245FCDFD7F8F98D379
-:10EB8000EA993BBFDC8C72294F269DD251B86F0C9D
-:10EB9000EE27DE5BEBA5FDFD70A0AFE759560E7EBC
-:10EBA000E436703FFBE9EA7493D55FFDB18BEBA5CA
-:10EBB000FB5DC2CEDA68DF6F66FC70BF8B7DF70449
-:10EBC000E3B45F297B459E84C3AF31F111DE972FFB
-:10EBD000174FE6CF92C983F6F883827EB60AFF66A6
-:10EBE000A3B0CB9DFD14376BFBDC68E7DFA4552A8F
-:10EBF00019F8735CABDD2E286AB1D3FF98663BFD34
-:10EC0000878C02871D9126BD65EADFB5BEE078B42A
-:10EC1000BF2A997EE4F680265BF7D79DFA77A71A7C
-:10EC2000FB99EB2CEC907020DE82F876DAB5FB04D1
-:10EC3000DEFFA2C4D288DF801ADF47FDAA719237B7
-:10EC40004E3B61089CC0E09C3C229CBF3A1B384F65
-:10EC5000B71FF0911CDFF22203797616883C8B10E7
-:10EC6000D91F1D21EE9F74B8B85FD02FE8E80D972B
-:10EC700042F33B26CAB303D092397F8CC7878EA359
-:10EC80002182F54667CED7450B85BE8FC9FCFDB8FE
-:10EC90008BEFABCD1E37F2381F88717EADC6FEBF3D
-:10ECA000CBB26FF3A42BF69EB5FCA18BEF830DAC1A
-:10ECB00087C8C735EDA53D6AEC235786BCB49C795F
-:10ECC0002AEDDF9E00BFA130FC3C930FBB81C991B0
-:10ECD000672481CFDFFB488F99F81EB0A7517EA033
-:10ECE0003E381C4861FCC45C0773DFC59C87693FE4
-:10ECF00094B9B93C6174E37313DC71BE3F08699247
-:10ED00000F05826EB6FA16DE53CB9E77CF7CFB35AD
-:10ED1000CC4F78F7099F8E706DAA3A12B6CA4D682B
-:10ED2000B6D38FF9DEF5F118DA97BF554A8C765BCA
-:10ED3000E328917E37B67F46D2C97F4BBEA290DDD5
-:10ED4000FB8C949A44FBE82AD0FEC533374653EB3C
-:10ED50002DFB1B4EBB3EC7D7F7C0729C7733B39FCA
-:10ED600060E8BA9976B959C63C106BFBF96CD9B911
-:10ED70005DCDA6CBF8BA42CCDB50630A100926E879
-:10ED8000391D747A32FBDF7033BC5D00FDF9C84772
-:10ED9000AB03632FE2F6C67F1BDE66E378FFDBF092
-:10EDA0003648B74E3DCDF719F2041E42D042FBED76
-:10EDB000BF685ABC6E021BCF5D18247B35AFA9FD1E
-:10EDC00066398CD97DBD1AFA977962FF1B1AB97E14
-:10EDD00036F7A373EAEDFADCA9BF3DC2EEF00CA34F
-:10EDE000D79D727338BDBEC46DD7EB03F1E261E409
-:10EDF0009F335E7C7AF9A7DF535B8C7919B1576B2F
-:10EE0000D9BAEC9BA5527C333C1EAE8B5BE8E1B0DB
-:10EE10005BA1FE0EBB791C643DE3D7D4399CCFE1E6
-:10EE20001CD4074C01E1FE41919CC2FC9AB5C95427
-:10EE30001DE69BAD552768D675AC2E62762DC3EBCB
-:10EE4000A61A7FB3D5DE7ED3EFE271D840F541E458
-:10EE5000C7F260AA86DCBB1873FC46F13C4B5CB77A
-:10EE6000F334E8C37D570F70BDCD38C2CBF54AAD42
-:10EE7000F616E56326E0546024BD60CFBFDCA9A68A
-:10EE800056FB111F111E6F096D91281947E989A5BD
-:10EE9000D17F981C58B095E4901A2FC371F64E6339
-:10EEA000662FABFFE15E37D9393DA1312ADA95CF24
-:10EEB000C88BBFE766F3ED7FDD03B87FD2F3D9B926
-:10EEC000748EA12774D15CA4831E099827CBE6CF4A
-:10EED000F88727FB4000E3F4E13931C03865FF2FA4
-:10EEE000C078888DEF8AFE344E79BA100BC833583B
-:10EEF0003B1F7461BE8AF1A9FFFD4B18DD3D1EACBE
-:10EF0000BCEF7C18F4FB4D7FFF627FE231E4C78EDB
-:10EF100051BF6B463EEB62702A6487C5A2087765D5
-:10EF20009E4CFC0779C1D404F6BEFA60A416F3CF58
-:10EF3000AAD50A94340C0EBEDE877C892771BEB533
-:10EF40005A436D36AB5F7548277B656EF4E6FD5816
-:10EF50009E7698973BDC40F620F22F58F8AFFAE304
-:10EF6000B134BF5F0A39DE1E8DF5C6A411D64353F6
-:10EF70001DE737EC792B563AD0A6D9E820E1B2D27A
-:10EF8000C10C460793AD741093CE860EBE8D5838D3
-:10EF9000237EE17C729BC2F96628DDB77873CA874D
-:10EFA000F28739EEFAAA9C08FA19261F68D3EFD225
-:10EFB000B0EC59E4267FCFE40B931F4E7AF9BE02E2
-:10EFC000E38B3A1F7B3606F54B33F105FA7356FA9D
-:10EFD000BF72183E990FFDFB31C77EBE0AC92C26B1
-:10EFE000427E7DE1D1D2B116BA77E269FE2C098E5C
-:10EFF00058E4D1A953BC6CC1A33690F7AC9C39BE80
-:10F000005F56F58E8885EF3A99FD8C4661976C4086
-:10F010005E31F2DD62BF07FDD5FAC7A214CFF7C497
-:10F020009B294F6DFA3B811B181D7E384AD671F221
-:10F030001DFAE247897F5F0B00DA6D9BA62D1987C9
-:10F04000FEC9873726C6A13FB68EE1FF081937A94A
-:10F05000D132E53EF58DE6FB637A943F1351FE1EF7
-:10F06000C4F79428C744BD3EAAC7D6D9260F377B1C
-:10F07000397D6FF6723B709DBBDB8BFCD55FECA5D9
-:10F08000FD53B3DE250AB7DB6678787D38B946C70D
-:10F0900078D50C0F6F775F5B2AFEE6048473073D1B
-:10F0A00073EB5380F17F7F5952C7F8BB7735243219
-:10F0B000D97DF779791CC0BBEF9F68DF28B7D4A052
-:10F0C0003856A49EF56759AFF90C35594C7E30700F
-:10F0D0006348C71DBA9FECB0F9919A3FA95386AE19
-:10F0E0002FFE39625927EF5F95440FC50BF87EC696
-:10F0F0004AE1CFD59678892F3A5ADDDB712A0B3C4D
-:10F10000D9DC0E8DD48C982F8B7E53D283712E2F09
-:10F110003D713F23790EDFCF487AF87E46D2C3F7A0
-:10F1200033F089FB19F81DF733B0FC93B6189571CD
-:10F130005F03CBB8AF8165DCCFC032EE67E0734FC1
-:10F140005B333D7FDED642DF9F6A6BA5F2251E6EE4
-:10F1500067435932BA80E1B9EB76770CF7A9D789C2
-:10F16000F5793656926BB075F445B8DFE97BE15E10
-:10F17000C0F9F8A23C6ED419BD17AE67CFAEA9A1F5
-:10F180002EDC2FF63E1AA4A74FBD0FF420EE4F241D
-:10F190009B3153B6C5F3C41C95E9F7D2E8CD353998
-:10F1A000AC7CABE7C93518BF9AA8AF32166B836544
-:10F1B0003D54B9E4314B795CF976D5CFEADFB9F645
-:10F1C000E935C8A708071A6F1D9EF49C556CC9D372
-:10F1D0002540E735FA8BDD29A4B3AFE17A21FD782C
-:10F1E000B85DFF655813453F799CEEAE44FE60F56F
-:10F1F000D39C2ECFACFE3ADC94CA1BDA6EA47A7292
-:10F20000D519D5036584FEF0BB34423F1DB046C31B
-:10F21000B3631B9097312EE80B909FD6E5E27CD923
-:10F22000E5E3CFA35E73FFA8669E978D3B4FF06921
-:10F23000972F5E87F9CAFD93658A17F4B858179817
-:10F2400084DB5AFC9B1236EEADCFAB8071E694871F
-:10F25000DB3713C685B8BEBCD34BFAF24BE37EDC7A
-:10F260009EC3CA13BE6F18A8FF3680E1473A496EA5
-:10F2700094693FF74755E3731A58F5F3A63E918317
-:10F280007184CF047FA7F07C112BAFEAB8611CC654
-:10F29000953E7C89CBA547C538DB5DBD2DB49E531B
-:10F2A0008364370074935DB02AAAD23EBC9CCF9F82
-:10F2B0006E97F67758CFCD146F92C1E3FE6CBA9774
-:10F2C000FCEF8F3DE25C5A2FD90B6E5F42CB66EFAD
-:10F2D000BB9332F1FB1ACD9FC2D4FB0DC14A3A2732
-:10F2E0009B2C5729CF7A43398FD3054257A7D04E4D
-:10F2F000B867AF8FCB87A097F2AD52E5BB0FD6446E
-:10F30000F0296BC8EFA9D8823AC2BB266B94B7C567
-:10F31000FE46DF9B239497BD01C4BA34F37866C7D9
-:10F32000A84F7F85F1DB355FD70C715688F21EC977
-:10F33000B491F1DC6EFFBE00C2F315F39C51DFEA1D
-:10F3400000ABDFBE5833701DA66835751827ECD0AA
-:10F350006ABCC85781C9B5DE45248706F292E93CEC
-:10F360005B7B39B757F13BF225B4C37E3CBF3246D5
-:10F37000C8B24076A584764E473D858D306FD796CE
-:10F3800067D99E7319E5B12BF37308CE0E8879B156
-:10F390007EB29EC79DC704BD69B4E3C698F1434CD5
-:10F3A00031B6F811B937D9F394F39B55DB398ED1C7
-:10F3B000097B394FF805798E7CE64F3DE63E8A1D84
-:10F3C0004FCEF9E6461ECA467873F160B23E743EEF
-:10F3D000F7452A1B709E63343FC11DD55657A3FCC9
-:10F3E0001A0D2DAB90EECE1A5E079C53CADB7B71D3
-:10F3F000DDA7E82A9D5B381FFA5763BF1B049D7782
-:10F4000015DBF564CAC3FD06C68F95C88F18E74A99
-:10F410005AC6C7386FD232DEF8AE1C5B79427781AC
-:10F42000ADFE395B4A6CDF27A5CEB57D3F6F47A5A2
-:10F43000AD3CB967A6ADFEF97B6A6CE58AF465B6AA
-:10F44000FA171C5C602B4FEDFD3B5BFDE9AF2DB661
-:10F450007DBFB06F89EDFB454757D8CA17F7DF610D
-:10F46000AB6FDACD4EBD58EEFD7CF6B207CF75D945
-:10F47000E282767BDC694F7BFFBA465F8D722DECB2
-:10F4800026FA56518FB3F28ADBB93FE39D6DE82827
-:10F49000574A841C0D056317E2BA5587BDA40FD4E3
-:10F4A00020AFA706E792DD31760B934717A015082A
-:10F4B00003DF032897DB92F152D720DC3EAD9BCED1
-:10F4C000285487EB00E3BD667B558B412284E3E93A
-:10F4D000DC9E61DE22D6F3E9ACBD651ECFC8321DCD
-:10F4E000E9EE677ED74316BF6B383FCBE9579DA93E
-:10F4F0001F3556063F3EB74BF1167C96B7BC54837A
-:10F50000E974CCBFFA0AE261933BDEBC1DF7434AC3
-:10F51000FCB42F66FA575DC53DC417FDC52AE9172F
-:10F5200050F5F20596F8569797CBFB80F701F2EF6E
-:10F53000D492190775C4FB2A95E20E1B241E1F499D
-:10F54000B27540BDB66DE6D1F7FE91BDF79678C7AE
-:10F5500078993C329E75C770BFF33E81D712ADA239
-:10F5600086595CCCBE68D887CF893AB333D8B3AC60
-:10F570006CF33E7CDEE1E5F974E71A8FD5A02CF13F
-:10F58000CEE6F69F32C59D5A8DEBA7713886A33320
-:10F5900035670BDFAF2A55DF427A436BFB943C485B
-:10F5A000073EA403899E443FBE4890F4860F0F7720
-:10F5B0006159955201F63D521A9330CFA23ABC855B
-:10F5C000F6557C69BBBDCAFCCD2EC46BA4DEBEDE85
-:10F5D00001EF3682AF5DE2F1D7AE6CFD851A067F92
-:10F5E000575E490EC64E303ED16091379B85FDD6A1
-:10F5F000E4934DFD4FF24646DE983A68EF30FADF6D
-:10F60000228F47F8BA01E596EFAE6E407AF7696C43
-:10F6100035D1DEFE5692E8DFB4776F11BC555BD270
-:10F6200044FB5EEF472AC9BEF5B5FE2423FE7C7D70
-:10F630000AC42E181EAFE1895B49DF43895B47BBD3
-:10F64000A25577C7B667900786D007EB30CF03E1A6
-:10F6500011791E5D021FE6BEDBFB66FE93D807BE76
-:10F66000251B6CFB7FB7E4558E1EC91EF731BF2FDB
-:10F670006181771D1B07F1D271B2A12E4EFB80C0B4
-:10F68000CFA57D56BE9DCEFF0AFFC510F6CB0C0F51
-:10F69000C7EF5837909F3007E31717A0B7F9E53A3F
-:10F6A000E44B33DE71C49B43F83792A0B490BDE2C3
-:10F6B00032F5967CEA7C8259779B714A3279B95E41
-:10F6C00063FFEEC57314E3BBECE7932674DBCBE773
-:10F6D0006CB19727A5EC6566351F42BBA001387E4B
-:10F6E000CEDB61FFDE60C6F96AF9B90A2F1BF91497
-:10F6F000D7BFB673AC20F4BF194F2DEA4957A37892
-:10F700002D5C69D7AB0542CF1738F4676548213FB8
-:10F71000BFFA60643FDA8F66FCE510267F59E2A9E4
-:10F72000661CC529CFFD873703FB42FE72C2C3E3C7
-:10F730000B09E6DFB4168AB845117FBA14FDC585FA
-:10F7400064A7B59C83F2E9696FE2032F192DF67364
-:10F750000FC7EBD45F483A1F276119E7B6B2E497A9
-:10F76000F8F453944762C6314C3FFD642036CFCB4A
-:10F77000D67D83F172CBB318477ADD03D8CFA5CA03
-:10F780000B07DB587945914A798FDAF49BBEE7C7BE
-:10F7900038207E67E5EA627D34D1FF732EF2D7D739
-:10F7A0000A7A36CFE398718F6C1FB79F433ED32EF2
-:10F7B0004AFA455EAB1FEDDCF37630D96CD3733C6F
-:10F7C0009E66C6CD26F7D8BFF78094ABB1F53BBF98
-:10F7D000292573BB2A16ACB6C4D5CF15EB356561A8
-:10F7E000FADE85ACBC0B5295783F4485A00B63BF15
-:10F7F000FDFCD72890E89CC0A8438A9162F5A73CFD
-:10F8000065FF5EEE381F76AEF3BC9823CE1B52E048
-:10F81000BD456CBC8D7A8B84F273E34266C3B3F250
-:10F82000B93E912F3C112622FD5DAA048D34E2F7EA
-:10F830001585F486E78D735E5D84FAFC259E97A29C
-:10F840008DD737D7B2B2F62B85F49316808A8AE02B
-:10F85000605CF8FE5306B4BB06E34C3BD9BA964E47
-:10F8600040FFDA0BA8577EC2D617CB3DCC1FC7F29C
-:10F87000E3CC1FC7E76EE68FE3FB9F317F1CCB7B9A
-:10F88000983F8ECF9F337F1CDF3FC5FC712C2F0F1D
-:10F89000545FE28C5359E3768371AA3EC98C53A11D
-:10F8A0002839EED6699D07E255091EAF3A7D3F31F2
-:10F8B000B31F8A070EE947C405DFBDFD778FE079E6
-:10F8C000E9A5535777E1B957AFCB8C8BF13C08339F
-:10F8D0008FD9E4BFA5BB6FA6FD6077FEA1165C8F34
-:10F8E000DD5541BA53C8ED4A68281F9DFE97E97758
-:10F8F00039ED5FF3E9D4477EB4032E403BA99BE288
-:10F900003EEB5D5046E76025BF817CE18C439A7CED
-:10F91000FCA2AF24E3F9A5817C58119FF140CA8B6A
-:10F92000F132B724E629F2354984B12E36203F5B07
-:10F93000F28B83E5698A73048331B2BF24669791A1
-:10F940009DA625A21887EA1C26FFF541C1A7ABF2A8
-:10F95000DD746F44673EDFFFAF2D34A2D87E4DFECD
-:10F96000B4A8351FD6CCD7DD1F9AE6EDB3F4B72285
-:10F970005432A29E52985ED547D0AB8A87E7ABAF90
-:10F98000D977A117F390D70717F7A27DB53E1AA133
-:10F99000F3EA7BF3A791FD31503F3A83F29595202E
-:10F9A000B75B95A897EC5615E75F3E58DFACD72AB2
-:10F9B000E433633F8ACF05823D54CFA3C629FEE1DD
-:10F9C0008900ED5779BC3C5F20C8FC6BAF2D6ECA37
-:10F9D000C7BDD9C7E5DB7A3D11C776EBA3AA8EE296
-:10F9E000687D5925E1798DC0F39A3C53EF1B646F14
-:10F9F000F4083968F6B346F8EB6B9ADD6477C55BBB
-:10FA0000B363B5B9947FF903E4BFF5C187BC98CF60
-:10FA1000EECEAF1AB1DF27C5FA0DDFEF1B35B517F4
-:10FA200050BF3D3E36BE3BB458C37E5DC3E4D91FD4
-:10FA300014707E5EFB92614EA3FD2E30F56D2A6A36
-:10FA4000DD27763EFD68275E30B4DD52BD6F2EE6C1
-:10FA5000F9AA90ACF32B43CF292CDBC3EF9DDAA49A
-:10FA6000F692BDB3E9A494F1BC43965F12CEFE803A
-:10FA70001F6EB357C6087E1A23BEEB68AF14A35F90
-:10FA800069B72F2E38682F4FEDB597A7BFE6B4574B
-:10FA900062AFA0BDD228E45D2F93CF3C69A25F4541
-:10FAA00039104FA6AA11EE06E85985FB942E11676E
-:10FAB0006E14FAEA0AA1CF5C7E1E971DD3ECB7F94B
-:10FAC00089E6FD1985A2FFA2DAFD37B7A3708D9BE9
-:10FAD000F68F4EFE65D1BCC7AB494C3AECA0869878
-:10FAE000FDFCE9150E3BC7690F55ABDB29BFB2C062
-:10FAF000117F30F729719E780ED739FED98E6BF6BB
-:10FB0000B795E92DB457CC7B09E8DE2ED6BE484D1B
-:10FB10004B06C353410B50BEDF989510DB9E818E80
-:10FB2000A789751F82B7E42584B739E25D4190DF6C
-:10FB30007B5250ABA4F462CCDFEF21FDBDE0263652
-:10FB40001FB2974FD13EB4593F27BB672FEE136EBC
-:10FB5000AD97B8FF9804B243CC75DE1AE4E7651A96
-:10FB60002E965232B66F29A1F109AE92C1F5657891
-:10FB70003AC2F1C4F3CBAEACB39FEB6970D81B268D
-:10FB80003D5CE178FFBA4F23FA30F9E0DD0B5F9B73
-:10FB90003896C1B1544AD6059433D79316FE709D5A
-:10FBA000423EC4BF8FA2A9107FECF3FE54A3FC8099
-:10FBB000ECBE078091E4657E48D6CE02F8377FFF21
-:10FBC00079122B37F8CB3BBA2EC6E389FD3F42A30F
-:10FBD000CCE3A9B8B4AE68B0ECF75F4CE588188701
-:10FBE000B91649BEDE967B0A18BCDF15F9011B6207
-:10FBF000B059C11C4B59DB6C140FB6CBC176D2087F
-:10FC0000EDE2B059CDD02E68B663E8EA34EFF528BE
-:10FC1000C127FF2E0B78ACE3AB88374D0FD2B99DCF
-:10FC2000B9AA86790F5F148E51A79B770236BBC69F
-:10FC30000F6DC7C05E65C22F67863F85DFADE3BB32
-:10FC40004680FF6F8D8FD3F5E716DFCF1A3E567DC6
-:10FC5000F5A8E1E78B70B9E87E0C3D285BFAB9673F
-:10FC6000EF2714BF56AF053A97A3BA629AC1E8BC12
-:10FC70005CFB36F9E16A76AD8676C03A56463B6063
-:10FC80005D4F37C5A9CB4BEFED42A22F4FFB01E5EE
-:10FC9000C164D0B277B17E276B2A66E2807AF17EAA
-:10FCA00019E3DE7039D0B990ACBD7E7E8F45F1CCC2
-:10FCB000EFA37F949DEDA53850207BDAF7B9B1CB47
-:10FCC000E3C126FC81EA43351827571BC040565430
-:10FCD000A5145423934D02DA87F0C776DF86E72B0D
-:10FCE00099E223FD44773BA05E1571F1D19C64A09D
-:10FCF000CBAD35A09F907C5EA5F8FB68BCF2861169
-:10FD0000657979CE6684A73CC13A90107E1ED79A59
-:10FD10009C908D34EBBFF23DDE0EFE9D9F0760BED2
-:10FD200044D313C141BC9A7265B488974717DAE38C
-:10FD3000C9D0CFE6CCDA57FEFB821F603C61D410FD
-:10FD4000F9CDFD6BF3DE9CACF720FE04ED6BDAF52C
-:10FD5000865FDC4FE177DC7B302E683F8737C46FEE
-:10FD6000F8569CF480070CAF9BEC8B85643798FEAB
-:10FD7000C856AC88F1FF22E079D9CEF6D3787B88DB
-:10FD800072FFC4E367665E25FBBEC41FA37C1F0F22
-:10FD90002B333C4A6EF0E6B3F705328F8BAC9240C2
-:10FDA000C5F2E07869DAA75F2B195D8634E8FFAE0B
-:10FDB000D10CCA1F809539367BD9CC435D7163F174
-:10FDC000E81CF6CC1A3CFFA3213DAEC82B25FB391D
-:10FDD0009CDBF7F7285F8FAF5F7FA917E529E62F38
-:10FDE000CC04F8ABBFA323C9E4ADE7E331A05BECDF
-:10FDF000328FDA427130CFC7636DEFD36DF6F38285
-:10FE0000B1A05C8BE3E461F23EC683416BC776D55B
-:10FE1000603F17E8F938DF66A70FF65F687B9F66DB
-:10FE2000F68CF53E8AE1FB0F805E66ED7FFC30FDCF
-:10FE30004F74F4AF65EC7FB0DF5C5BBF1D2A8F8F22
-:10FE400026237E5A77A73D3039505310C81B217E98
-:10FE50001FE0F1C7B5D1168ADFD700637846279730
-:10FE60009C3CA2F0F36B40761B14DAE3F735827EFC
-:10FE700065461148BF97A8F67BC06683F35E30BB2A
-:10FE80003DD48B8C827E65A8AA97E2F89F0475F416
-:10FE9000BF86B3977BDB80E2C7B3037DB7E03EF557
-:10FEA000A51B1E7075CC10F9AF05CC8ED8D0732968
-:10FEB0009EF3EB15E7F33A2232E1255E339ACEDB6F
-:10FEC00098FDC4DD3001E5615CE6F909F4878DDF5A
-:10FED0009B57F0D0FA0CF8739EE76C8849F1520BEF
-:10FEE000DDF4CA0CAFD6F1E68CD9AE58E611F7C0F6
-:10FEF000541A4FD8B903E38DFA7CE3BD24E24EE6F1
-:10FF0000780D73EDF36B706B34BF06C1BFE6782FCD
-:10FF1000E1FC32E0F7B4E3C99C6E06C6FB927D7E3D
-:10FF20000D1E8DE6D720EEF51D186FD4E71B6FADC3
-:10FF3000AB258176DB6689F3FFDD817FED40BFED88
-:10FF4000FDFA1551D207C22EBE021BB07A57A87C0B
-:10FF5000BCF985DED42ACB785B991C88893CF7985C
-:10FF600007F337342AA7DAA2F47C88D9D931CADF5B
-:10FF700028A3EF8FB41954DED136839E663F6533D4
-:10FF8000F83D3393664919EDED5F06B8DFB8395F88
-:10FF9000BBF66BA897AAFDFCFCE38C8B2066B17FB7
-:10FFA0009941BCCF87FB2F574305EAB6895B38DC04
-:10FFB00091DA51295C3F7FC5FEDE3656F6B85C3AD1
-:10FFC000EA53C60BF14C7EEADE00F7C33D6E2EEF1E
-:10FFD0006126BFB770BED02BA0D44B2EC4C715D995
-:10FFE000B4DFBFA03116D218DE1A25E99552A1A7B9
-:10FFF000F0FCCA5562A99C767E043506EB37125395
-:020000021000EC
-:1000000052781FD15585079B502FC74357927F10B9
-:10001000670D73583F57093D59FD860730DF012EA4
-:1000200075131C8D8D767B7EB32FADA17DB2B92269
-:1000300002B83E0BEAEDDF3D6ECE8771C73D05F39A
-:100040004F736F01DD9D95218FD4199F7C32608F96
-:10005000439E80F27B6AF1636164C47B0B5604C0EB
-:10006000BCD73263FCC884E74D94635391DEF650ED
-:100070003CCC84AF404D4928AFC734EFB1E53531B2
-:10008000C492316CC6E141D955817E88733E5BA52F
-:100090005DF923DD535200EA5B7D65E21E4F69E89E
-:1000A000BC7F1710F9B703F39EF5622964E21F1EA7
-:1000B000779D7F503156E9837831F1F03FCD479DF0
-:1000C000018ECF17E77C50C5FDB742DB7D99E63D39
-:1000D000C0570E9455502DF47CC51237D93310EB10
-:1000E0002F47BA3B747180DFDB66DA2FE9D765B43E
-:1000F0005FBE78FFB1225BDEA6E877B8F572E61145
-:100100005ACE7D0EE6B9637E89C4F7B10A30CF2D91
-:10011000CCDF1FB1DB99B63CB7357B7F28619CEF04
-:1001200001CCC7B3EC5B8F61FE3CCACDC29BEC79BE
-:10013000754EB8CCBCAA8173B3B31AB55D3ADD93E2
-:10014000D88D17CF746D49C6C1921F699E1334FDB7
-:1001500069E7F94025C8EFCB8B8AF316CE78F06DAE
-:1001600072522B96301F35E5AD66CFF29C848147E5
-:10017000D36F539275F85E193DB319F1B0B0F54ED7
-:1001800003E3775A6EE6B8F442A1BF2F0A72BA3978
-:10019000EC4A17611C3B91537351302F43FDD66FCE
-:1001A000517FB387B97FBE51F4F380D0E7CEEF978C
-:1001B00007795CE59AA532DD67E183504A2AC67D5E
-:1001C000E3EE19742E6FD95623D3B9B783E144BD3A
-:1001D000151E5F293F6F0DD07321E26BDD5F1EECB2
-:1001E0007994A132E72F4192A3390AEFD7D2BE31D9
-:1001F00053FB673EF92D9D537E06CFA9CCC4FEB6B6
-:10020000CEC5F8F7A6813224252C678B72F2B6B9D9
-:10021000E8EF0D962BE6566319699011D9ABC1DA58
-:100220004EA4974D120862BC94D777F1FABBC5F77C
-:10023000D997BDF37D3C970BD3DCE4076E12F688AB
-:1002400009DFEB419E37F3FA69F079ABF81E447C85
-:1002500046CE0A9FB766C2C7EB39B1DB8253B19F66
-:100260001EBA17D2F717EF4ACC23FEA73630BEC608
-:10027000E6F080B1FB87F700B5FF5670EAD0F6F3E1
-:1002800072626DD86F70E9119A5FA83488EE0DAC78
-:100290009B0ED44F0638D666EAC75CD774169763B0
-:1002A00027D076CEC375E5F69FE2E98DE2FEBF5614
-:1002B00075FF2D1A93239DC5DD4D99E8FB3B21BEAB
-:1002C0004F9D3D4CBC7A97A0C757B5F877118E76F5
-:1002D000ED5EBA4FD52D71BB61DD8C3E902CED7E6D
-:1002E00015E2F519DCDFC3FAEE0BF93DA72186779D
-:1002F0004C300B5571F8D7E98700F3BA43D14394DA
-:10030000171AAAEA237EA7A30A059CAED05FF30AB8
-:10031000FB6C57F0DAB94817398A49777FEE443ACF
-:100320005406CB4497DB7378FB97427FEE4C3291B7
-:10033000BB8DD92F78EF46B280E78D38E7F72F21B4
-:100340004E1FF787638F23BC43F0E9E9FBFE3DAC0A
-:10035000FDA609FCBCCD6CB9B7E97AA4CBCB82640D
-:100360007FB1F74DD673C86F0A7CBD19E4F6D3A6EA
-:100370004FBCF4DDB91EC3D1EB0BA2FDE7A0D7172C
-:1003800032D109A3D77F477AB3D0EB0790995E0F9C
-:100390000D43AFAF607B275E9C6505625B707F5647
-:1003A000FD74EE0EEC4FFDF2AC2D8FB2A7F2E95DBD
-:1003B000495A4D43B29D2F35C7A99012FF11B4C8B9
-:1003C00077F33EEE1B83BCFF21FD4E9FB605E5D8BB
-:1003D00019F47B2C387568BF4F0539BCB32F0B2639
-:1003E000329D1FDF1252E9FB43213EFE707C7330C9
-:1003F000C4FDD9E1F8E65141578C6FFE7A267CF3B3
-:100400008741BE7187F2CE846FBE4D4F5F29E71BD7
-:100410003A863C7328DF40F2D54E94AF9DC59C2FA1
-:10042000466F7AB313E31C037C943C41DF95C132E1
-:10043000C963938FFE73D309E22367FBF030F75251
-:100440008D15F33E188E17E13C62E769EDFC9C4D7B
-:100450001FE9EDEDD0BFD74379B63CAFD59F4CC671
-:10046000B8D9D00B78BE7FA2C0C336F4C1D0CF9923
-:1004700026E24C6A2F2C080DE5E75055BACA7A9F40
-:10048000C0D362FC0F43F1C9A1A9385EDF24B4BF19
-:10049000865BA74A31DE3DD9B1CA5006FE3F9D1E9C
-:1004A000BA26C4CFBB5E23FAC9F98BB705ED4F2737
-:1004B000BFCF5EF6F33F3D32423F8DA27D7DE873B4
-:1004C000F37F7D2833FF5F1EB2F37F15DEB799817E
-:1004D000FF1B33B567FC7F55E86FCBEF8B4219F8F4
-:1004E00072E619E2FB6181EF87BF20BE570B3AB974
-:1004F000E3F3E3FB8E61F07DE719E27B7528837DF2
-:10050000C1F0BD2644F6CAE3047F480F521CBB6B02
-:100510003AEC964A32C2B1C1DA8F57E7FD30BC7F60
-:100520002031BA9FFD699791E99E19D6EE5E2BFCAA
-:1005300066BBCA9066266FDF8CFEF9035F0E52BC65
-:100540009FE9C7FBFFC674F050263A982D7339F423
-:1005500041F0B14E8CB37D81FE7F92A9FF6621D719
-:100560004F6717EC1574C1E6FD4468EA50F9B75DB2
-:10057000FC2ECAFDE1C45321C257DF3C9457DBEE89
-:10058000C891301E55184B4BE8273C2EF4D87921E2
-:100590009D9F6710EDB6A96909F359B6B568129E1B
-:1005A00037B2F4F74B1C6FB8FE9C7030F89EC3F165
-:1005B0003F0CC59EC767A598DFD9DA490DD9B19719
-:1005C00043A47FE287486E9F6397DBE63CE478377D
-:1005D000E5BDF86664FEDD96C783AAD063F1DF5BF4
-:1005E000E5FF2B0374C5FB3B5BFDC3E07B2BC4F530
-:1005F000CAD14CF039F1723A38F34203701EC77E0B
-:100600009D7ACAD99FE9B79AEBE4469D648DEB0CBD
-:10061000E8BDC45F897F3B643A87345FC893F93390
-:10062000B285DDAEF9B1FF07449CFC819BEEADC6FF
-:10063000FDEEED77691588828266AEF7F49BC652AF
-:10064000FCD317966C714CF339D0DEDD3309EF190A
-:1006500067E386C2ACDE25B3208D7E6316DA0D1407
-:100660008FD0E877BB723CDD518C9FAE93BA9B165E
-:10067000A35E9D17E4E74AA28DA7B9AF6DB58D6E55
-:10068000215A759AFAABA8BE16E8A6FB2FCEB8BEC3
-:10069000A7BB29537EC994B06CE275527824BC463E
-:1006A0002314D732F13B741CBE7ED5F11609F11D1F
-:1006B000AA92343C7A15627482F6925CDA4BF94C59
-:1006C0009757717A01E6978C7C7F46A769AFCD0A70
-:1006D000E77D71B8CC7AC38F27EA39CE2BE0BE17FD
-:1006E000C567835C8E5145563E7E303763DCDF7CC8
-:1006F000AE6DD30A5597B5FF14E179ED40FEB41104
-:10070000457BAB15383D42D44B7618DDCB6E59CFC7
-:1007100084589FEF66C5FF3E4CF019740F2168DACC
-:1007200019CD87B55B4CED54D62E74E6ED867F9AD5
-:10073000BF5767E871CBBD6726BF8E4E2401EF9986
-:10074000F1978326B1F58F84CC7D424E07DF0E9A58
-:10075000E5246D92C74BBB795EBE6ED209972B5ACA
-:10076000A0272657006CBEBBEE4BD149ACBFD2448C
-:1007700014AFD067E5032AF9E1BC0CC9BA03FB0B3F
-:10078000917FB4732583E9A9F6DA03072F067E5417
-:100790008A7E4FADF600C93BB38C175294B1B27F3D
-:1007A000A01CF34659B964A09CC4F236A12737DFD8
-:1007B0005D7BA03D48726CA3953FAA051DFEADE987
-:1007C0006FBBDEAEE13983645425BB6A9D831EF6A0
-:1007D00084F97D2C93B5C4365CD7F977F5AB787482
-:1007E000C55B1C09213F8C8B7E90C4FBF2C6CD12E9
-:1007F00069AAA5FC9E86EDD195C497DB715D80A7A3
-:1008000025607C72707D5299D7A72C45EBE3D7F910
-:100810007719CBE46FF3F85BA08CF3B3E6E1F1BD9D
-:10082000C704BDA6C33C7E9416F2352BDA4EFE9467
-:10083000B74EA6F871569D6CD31BF48B77D44EB58A
-:10084000DDFBFF7A4EE2A9B0452FB01AF132360F28
-:10085000FFA4480EEEBF5497A92BD1DFFE9EB0FF38
-:10086000D83A3D40EB5411F127486EC79FB5CA8F67
-:100870008175137839DDBAFDB62D61D4BA865FB7BC
-:10088000ABAF5532DE93F6DB30F75F8F35FDE7FD1A
-:10089000389DA5DE7EBABFBBAB7415C561CDB8ABC4
-:1008A0006777757A8C3E980FB83A109E854FE7B8F7
-:1008B000BF3DF95D8DCE897CE2C9B89F7452E0F9E5
-:1008C000505B13B5630B4CBFB7721D4E85E7B1D9B2
-:1008D000CEF199E711BE0A9C181AE38B2E4739B462
-:1008E000B849A17B1BAE037B3EC557CDBCAF563389
-:1008F0003F8EE77D25207B2EB2E1A2A4E3F722C044
-:10090000988BE7E887FC8E84D8DFFABA236FE29AE7
-:10091000A64546ADA8F73EFD3F45F369D4B9FC6D49
-:1009200034F8FD3D57C5AF356A2DFBD1AF7EA664C7
-:10093000CC9B9C9765E2236ED44E188A8FC571C9F3
-:10094000ADE9A7C7CB99E261915A31374F1F8A07AA
-:10095000E7FC19C636219EBFCEF08C76E770F860B2
-:10096000F5683D5EBD56A1DF8F99ABD4BB701FE427
-:10097000FA0689F698187EC3222FAEFE520BBC4EA3
-:100980003C3AF175FDD340E706AEFF4E88E26D2F8D
-:100990009BF8495F42FB17E6FE89659E4778FE9605
-:1009A00046F35C30A3E217786F42A25DA2FB1AD92E
-:1009B0007C6DFB808B219E85E716D8BC8F0CB3EE37
-:1009C000B6FD40277C4EF87D42AF38F7C5404D97C5
-:1009D000A31E9C9D25F605A78021F6C7B2281DB74A
-:1009E00034B3BC75DE3767D2D975AD0D03E362FF52
-:1009F000122406CA1A9ED77A4ED97415FBFB8A2890
-:100A0000FF1DC3F8B5B91DF86D3E98BF2F14A3FDA7
-:100A1000A6EB04FE1A98C787BF7D7609134EB8AFC0
-:100A2000373FE6D38396791EEF96EAC439AAACC65F
-:100A3000C9D82EB957993214DE1551FE7B858C0E1C
-:100A40003FB0D2A16F02BF47D68917135F8B06F163
-:100A500032E56CF0F22A2ACE3CDAAF213BB75FF2E6
-:100A6000D27978731F87FD35E966A2F3D6AC62614F
-:100A70000FF0799BF77701B4907DBF509CC73AEC9B
-:100A800082A6C7827C5FA7D222B76ECBA9BE35CB28
-:100A9000E2579BFB3AE67D51263D7FD51B4C2B9CB4
-:100AA0000E6DF7410DE63125288F49C9BA49477CBB
-:100AB00074E1A70BC9EE5985FD2B01BE5FE57BEE06
-:100AC000A75D57E983EBB7FE6B4F744F6565FFD7A2
-:100AD0007F93A44EF51CC25B48AC5BB55837133E00
-:100AE0007F397F6F593F1E3F2B13F133B18EC3E91E
-:100AF00009731DCD75433B0AE9D757A67E9AE9775E
-:100B0000F7607F553FF26922AA520E5D427AB383A5
-:100B1000EED9027D1BEEBF5FD7EAB2FDDE5202CFF7
-:100B2000E963FD753EE19718D47E713E6F0F65DC79
-:100B30006E1CA0FB246B6FC903026F7814AE5B1FA1
-:100B40006B8B7962ACBF51A8EFA1CB324EC9D0718B
-:100B500087EDCFD14E19D837310CC322AF1FCBE26E
-:100B60007AF278B4AA47CE107F319F8BBDB985AA9F
-:100B7000253FEC48BEB729E3EF0689FE06EE8D1B44
-:100B8000B013DF39B07FD6A09DB8C1F5C703078B7E
-:100B90002C7622FCF100F9ED03E5B3B3135FCFFA35
-:100BA00023D9891FFDDE43FAEA789D9FD621B775C8
-:100BB0000EFC079EB755F1B7FCC8BEA77B6FBCAD56
-:100BC00063683E92CA3087BF07A61B12E2FB4896B5
-:100BD000CEF7637548871870B9AA2121BEEE15FEBD
-:100BE00028A3B349D6DFFF3D22E66B8EE3F1421224
-:100BF000CF199BFD323A584579A5F5407AC4DC8778
-:100C000035F9D9ECE7589664CBAB3E03FE3D9635FB
-:100C10007528FFBE20B7FCE11FD17E7D5EA17CD090
-:100C2000AF446FA7F757B75E4FCF6B5B6FA4E7C7B3
-:100C3000423FDF2A253E463EED6DFACD576E63F406
-:100C4000BA7CB787CE952DBDF54F77237F7A5BD9D8
-:100C5000BA63BBAF5FFF9DA9ECBB7B824CF66B57C1
-:100C600011CFE770AF9278BC5F77D7ED66CFE670B3
-:100C7000F544CD02D77F01C39B58310080000000AE
-:100C80001F8B080000000000000BE57D0B7814D5D9
-:100C9000F5F89D9DD94792DDCDEEE6B5900713C2DC
-:100CA000230AC44D202128D60D011A2B81A0A8515A
-:100CB000826C0884008104B4B2552C1B021830D613
-:100CC00068B562B57C8B85D6B6DA06A52D6D23DDB9
-:100CD000085AA81463B50A562020B5286A228FB294
-:100CE000B6B6FEEF39F74E7666B21B82EDEFFBF734
-:100CF000F7FDE2D71EEEDC3BF771DEF7DC7367EB46
-:100D0000EC5347390A09216EBB811411B2CA42FF64
-:100D10002D1372F1E8FDEE05C984C45BAD1EFA84A3
-:100D2000989AB21F32D0323920921D148809647EFD
-:100D3000C5580ACD0CBA1D122185000D081D00539F
-:100D400008B184054292A09DC7D368A56529401CBF
-:100D500000C3123E370942453B7DFF0BF8BB2E0214
-:100D600095FE2C619190F1309EFE7D133EDF249B19
-:100D7000CAE07D3189CD43793F9BBF9FCDE76309B1
-:100D800027B07924E9FBB1B3E722696CB7F69FC7B6
-:100D90007D89A5231D741D7576EF288084741B2B17
-:100DA0006C84DC61FDFD61218F428B35245248FC4F
-:100DB000C68FBA7309FE7D311CFEBFCAF1FE184210
-:100DC00004D22D7C41879EF9B9101A46F11757229B
-:100DD00006D765532838CA274CA0CD4A8C1EC06759
-:100DE000D78864DB70D5F8C50E01F1F7BAE4B0C15D
-:100DF0003C2BA68915C1B1D87DCA1CE8675A4DD1D4
-:100E000066369C85A412329FFD9BBC2E6F6F194ED7
-:100E1000EB0301A36724A5E37C4B2008F39B4FA4BD
-:100E200040B7059B085F080865A988BF47E73B7F77
-:100E3000AAE88DB36BDA912FE83CC97AB26F04ED62
-:100E4000FF0E810F10A065FADE315E3C3EF5DCCD71
-:100E5000B08C6EE2300DA7EDEFE8AE9E41F2B0CA65
-:100E60000AFCB488B79BEF379EEAEB97FEAF3AA037
-:100E70002D2F28CE7F859281E225583601F8EC0A85
-:100E800003F2594D8BB6DDA277AFFF80D8A15FE9A1
-:100E9000541FBE619EE461C66FD39A1D32C5D3381C
-:100EA000878C749F39F5BDA9849667117233F43B22
-:100EB0006BAAE808D1D6AD7E03F1D2891FF28A4130
-:100EC00081AEED506EF781EB006FC5467907AC350A
-:100ED000973C785332D48F77009E2BE0D9106C4F1B
-:100EE00008B4735B8223E9B32EEF7BD61A15DF1D9E
-:100EF0002A7EEF0A1FA5D75603A98BC64F8434E17B
-:100F0000BCF6DD138FFD1C7F54089AE9FCA7899F6E
-:100F1000FF61229D4FCD7D468F59C6651980AE3346
-:100F20003C4C1E09F15AA7517CDE4158F93D525103
-:100F300014A2E3D7E41F2D31D37E6A360828A70A0E
-:100F4000FE29BE4FAAF1E66BAC480CC98877CD7379
-:100F5000DA9909F899E2F9640C3C9F54E3D9FFEE61
-:100F60009171FB54ED363B6CC9C0E7A480147C4101
-:100F70005173814C4E1C4FFAAF5B8117D71E1EB7C1
-:100F80006F24218F12EFC3A87748B754318ED2490E
-:100F900022DE687A60BA9DC9C134F123A4CFD96238
-:100FA00051067C1DF27F68A51C460E7D2E96019E83
-:100FB0008997369A1479EF870E13E279AB89780115
-:100FC000CF5B875A824DB4ABCE7BAE4CEB46FAC8B2
-:100FD0008F4F063AFEDE4876C8B1E76BF38B6404A8
-:100FE00065CC72BF8050A1DF307F1C91C647DA0DFF
-:100FF00023D1E7BF1BE498B64F59430C321DD719D4
-:1010000020DE6014BE50DA2DB7F44E9708B60F39C3
-:10101000E9FC56C886A040D79B2FC88CBF8D8DDEBB
-:1010200074DA54EA981D4827300F11E721D3F949A3
-:10103000747ED9FE042C0FF72721CCF13B118EF0E2
-:10104000A763FD487F0EC251FE6C7C3EDA3F06CBA3
-:10105000B9FEF108AFF0E723BCD27F0DC231FE52DA
-:101060006C37D65F82709CFF067C9EE7BF09E15516
-:10107000FED9083DFEB9589FEFAF4158E0AFC6E733
-:10108000E3FDCBB03CC17F27960BFD2B1116F9EF8A
-:101090004538D1DF8CB0D8DF84ED26F91FC0F2D5FA
-:1010A000FE6F23BCC6FF30C2C9FE27B11E1410E07C
-:1010B000219ECBE303F242079514E07019F83896AD
-:1010C000DC5DE4F668BEC37B1CF84E696732109F96
-:1010D000BABDD2EE1CB71B4EA06B94FE3EE1F4FAF3
-:1010E000C473F23BA349846E2DEEA60A2246E8653E
-:1010F000DE55124AA7FF5CB17B3601BD40729335C5
-:101100007CDA5F3FB0F51DE3FA6BABD4E515817F68
-:101110001B8927401F954F785D807EB6C952593094
-:101120000ABF8D761AF1BD710EDFBFC05E25649FC8
-:10113000DA07FA6456C0F18729C02F63937F3F8591
-:10114000F6376CBD0146A0AAC4D13985EA1D792ABB
-:1011500041BDB88D1094A76DF15A7B3ACCC9F041CE
-:1011600048FBFEE1284F230A98FDE9BE1EE4CB743C
-:10117000CF70B2391BE42D2448B4BFC02A42762870
-:101180003603DA6F5CF003A88FF467C2750E6B212B
-:101190002F59E844B2DBE4297114E66CF1BE144720
-:1011A0005F1919F44D89A7E5D1CF045E0278457B1C
-:1011B000704A02856376875EA2E6948C0B754FB108
-:1011C000D2F255FBC95E406B7E975C6AA3E5F1875E
-:1011D000BD7B291B90C26E5FA95D86F9049BED74EF
-:1011E0003E5B8F114F132D177FD426261215FD4D10
-:1011F000C4B7534517DB84AEA949F49F197739F278
-:1012000045785FEA8E738EED4F9F6DB06E5827B5AF
-:10121000233BE8BA32BC21C1A1E2931B9C4C6F5125
-:101220003A5CE5043BB4A65782756E5BEFB221FDD4
-:10123000E21D253064EF34E2785A063E96104FA640
-:101240000DC351DE15BEA3F8BD62B64D8D3741D139
-:101250006B75ED6363E3F70627D37FFF2DF87DC73A
-:10126000C1E421167E2DC02B932E2DC755CE3E39BD
-:10127000AE74A6C46ED7C4F1AFC7F33603D94F6DB1
-:10128000151D97F229932B12A04DD770FEBE145E48
-:10129000EFFE2FE3DB9B9C03E395C8C9A82729BF7A
-:1012A0005E417262EB1BE82F9AFD7A80E351A5E75D
-:1012B0004CE02FB638A89ECB89ADE76E755E427FB5
-:1012C000713D63E27A5C196F0BE7EFFDF68AEF8000
-:1012D000DC58371802206725C4867241DCC99C4F50
-:1012E0001CF1C02733444709E81B329AA01F9D30E8
-:1012F0003618807DCAB0805C20423350CA80C7A1B6
-:10130000B9C1CDB4EB6CEA674894FEB4AB10408B26
-:10131000EC302CA0EB4E54E4CD51ED56CB9B62EF5C
-:1013200023F2A8F0856BDBE66CC6AFB3A9FFF236FB
-:10133000C753A41F01DB6DFCC6D06D9B557A709B13
-:10134000DB8D65A57D2CFEBDA0F0EFFA75C407F21C
-:101350003139BADFF0BA53E47CDBEB053E0F7C8514
-:1013600038C09F71AE3F89FAC949F59380FA898DDB
-:101370009FE18FFF418096BB9CA95C9F3BE26FB1D0
-:10138000FDFFE3E71D4EC2F4D46447A748EB875145
-:101390003B24839C4EA6739F00F83221DD65C2E892
-:1013A000284F2641F07B29DE4206D0BF065B10ECB9
-:1013B0008CC9D4E60579262627AE7FBFDD77DC39D8
-:1013C000805C3812E47C206AAF335C66A5FCB731E0
-:1013D000DB110FE58F69B9D54DC77575135E6EB119
-:1013E000A2FCD0BFA148C510DD1B807D54CA5E0B96
-:1013F000B41FDE570E40792BF82457D3FE1FFEDBB7
-:10140000FEF51431B39DDE4F9C8CAF7B017A47D340
-:101410000D6A4E849F2FE50F28F219912747BE22AF
-:101420004FD563511FFEDD5918E92F967FB38BEB23
-:10143000CF04D7C0FE8DC2F797EDDFF0F97EC6F579
-:10144000522CF98F3BF0C696EDB4BCCA2DCAA7A8A2
-:101450007F671BFA569744CB16EA6FBE47CB064B05
-:101460009704EDCAA9845A29BEBDD4C983FD8765F6
-:10147000022BC31FEC3FCEB609654C5FCB8973C608
-:101480000D84C720AE6795DB84E3C58D1C9108727F
-:1014900065E77C4524210876DC5EEC9016607FDDF4
-:1014A000E446DA5FAECBA0916BD05BCF8F05BDE495
-:1014B0009260BF6EB69080CD15E91FCA890511FDF7
-:1014C00044F83EEE4EBE676A5BE7491C01727A88BB
-:1014D000C551DABEC9E4B23C8304D7819EF012D96B
-:1014E00041DBC711E58F0A2E2D1B7969C6DF05E2A6
-:1014F000A5F33FF87711A13082846C74BF57EE11C9
-:1015000042B00F34192C41B0A525432DC40465BB4E
-:10151000216806F93829E03A4D050941507E538784
-:10152000162776D3759C3BB8D7EA8B42FF5B7DD5F7
-:101530009EA9E363E3B1AFDDBC971D80C727E5F546
-:101540000EF023036E09E30E9BA0A94AAFDFEA3237
-:1015500029FED06C17F8430B7BD79B80DED9C9E8F6
-:101560000F91112EE4DB21EE5D9B4AC064D533FF61
-:1015700074280936A9FD2A85BF8EB87C73A19F27E0
-:10158000B91DA162D9350AE2555724BBC02F2D6978
-:1015900018DA01FEEE136B8967A111F5C14C68EFF3
-:1015A0004D6ACF07FE7DD2B3EB470F013ECD745F8E
-:1015B0000C7A7CFC51AB4CE95555B83705D6F3078E
-:1015C000DDFCFBFC0FFF37112FFA7DF03217DD0732
-:1015D0008342CC2379B00F3EE7B9293184BC9514FE
-:1015E00055BEABFCF7623FCA7EF85D6328D3115548
-:1015F0000EB5F856C6AF12D8BE961805A6FFB81D90
-:10160000A5FAE53E58277D0DEDA6D72C3C0DF6E654
-:101610009C67BC07EC762C7DA3CC87E27164852D9A
-:101620004ABD402AA2E989C75DCC5E5719E97E818F
-:10163000D60B2B0B1B615E5536AB007CA7B46BE65B
-:10164000ED147E56E25562E2E785407F880F465BE7
-:10165000FF7C229D57C7A39A41D65218BE3C51FC2D
-:101660009558F83A6C6C2B87791D5E249226DACF58
-:1016700039DFC43412E57D05BE037C43E9B21CF6B4
-:10168000FC852A7A8E888EBFC36BEB3C538D117A12
-:10169000F6ABAF8EAB04FB5D0978548DBB9FE3E5E1
-:1016A000848BD97B62F6C90E5A6F5AF098838C03EB
-:1016B0003D75BE306083B858EFCF9B80DEF7D930E0
-:1016C0005E51597DA1B0699C0A9FC5048DE4FCBDA3
-:1016D0004F3864FABC72E4FA948035361E4FB8D89D
-:1016E000BA1E800793301EB3D77519F11832D6850C
-:1016F000FC46F6C67942108FFC93E801BF01C6F59F
-:10170000A1FE64F1E4BB1C6C5E713A3FAFD2BF42F4
-:10171000A35F12C2020926A9CA523BC66713C212AE
-:101720003ED7CBDB0E178F3B717953F01F8B9E0A90
-:10173000FEF5CF431CEF87AB97C8103734C547F78A
-:1017400083D392040D5FBDB5D6A719EFED7F8A9ABA
-:10175000FDB202CF73FA9EF34D4A837855A5293026
-:10176000723072AEE0E7ADCF1F7740BF719F99A393
-:10177000CADFC7DC3E517BDA72B3ACB2A7B789EBE4
-:1017800001EF0912D76F3AB9F3825DA5F8BC0EECF0
-:101790002A9D62C225ECEA7C12E88438B27E7CC5C0
-:1017A0009EEAF94BB1AF7ABA297CE04CD2EA4B25DC
-:1017B0006E184BBE14B93AC2E55F8F7F3DBCD5A40D
-:1017C000F57B14F87E1F3DE24880EAC73B4BC420FE
-:1017D00011903FD03E1E7E4C407F33546D46BB5C23
-:1017E000531D87F1D99A7C11EB6B1E14D17E86A80C
-:1017F0007EA8A7F3F903D713FAF86C09113C5355E7
-:10180000EB9E39214E53BE6DD1B7FFB016E2CBC56A
-:101810004619C63B24B37873C02BA2FF4AFBF08461
-:10182000203EFDE8B51EB0670A3F1CF28A286F8192
-:1018300037450F0CDBC5E3D1875AF28322D059F02C
-:10184000F58D23E740FF3532D0E1887B8B03F45DD3
-:10185000DC3F1FAFA8C0FDA34FCE47BB499D553A03
-:10186000EF382EA7A5438B6F013B7EBCD548206E79
-:10187000747CCD3994E7EEB58D9EA92323F16525BF
-:101880003EAC8F33EBE3CBFDE2CABA78B2C20F7A3B
-:101890003EB939067F28FA2A167F503D5695947234
-:1018A000F97A4CD11FEFF075960EDDF26013C54347
-:1018B000C24211F1A0F0E591CFEFFF1EE8E138CA76
-:1018C0001FEB809FFFF9C397611F42960851E3C841
-:1018D000DFEBB37B942EB911BADCE65BD25706F18D
-:1018E0009F5BB7B2AF0CEBD7DB95D87A6D60BD3597
-:1018F0002C89C581F476472F0FFF69BB5359FD58DA
-:101900002EBC5F59BD280870D3504B1DE85FBD9EAB
-:10191000D0DB09653EFA79268445121CAF9EB78C50
-:10192000ED2276C284F57E8B3D0F9CF58B710C0603
-:10193000C00904BFF4585CB019C76BBCAA02E7DF4A
-:101940003811A09F78BA03B03E773CC60FDA325800
-:101950007BF1FA78E68F4F70E13A45C5213FEFC43D
-:1019600072335FC35897EFD9243A8F66AF210ECEFA
-:10197000154A6DD20108B9B44D31103389E049F1EF
-:10198000DF094406E87AB14E807D67BEC59483FEC8
-:10199000E92EE4DB6FD27D21E5F78307C55DDBE847
-:1019A000120F7AC62746F3CF1538CFFD0DD40BB7EB
-:1019B000F86B101EFDFADB5920AF770BBEDFC2BCFF
-:1019C000BA2A6B1E2CA4F369D82DE2B9D2BCBB8F06
-:1019D0008C62FB34EDF9A468B7E4421CA55988F782
-:1019E000801E51F0D86933A17E693ECAF460F309C4
-:1019F0008197D93E621FAF3FF7AE0DF7190ADEE9B6
-:101A00007A0EC1F8DE6F3B713DCA3EE3DF58CF91DD
-:101A100081D793E1407D017C2546E62FDA245C578F
-:101A20000F89F7C0FCFD3C1E44DE8D43BF59A16FFA
-:101A300003E73F85BE2B387D7B3A2E7CEB1ADABE5E
-:101A4000CDEBC253063193E07A7BDE4D40FE50D69B
-:101A50004BF9E06398DFDE0E6627DA8ED918BE6C8C
-:101A600045B9303FC5BF7624313F59BFEE2ABE4F3E
-:101A70000F27097DFE2DC4297CAE29E1A428F2A000
-:101A8000F8B514CFFF80FA1207391F24113C2BE35D
-:101A900028E32AEF9993B5F255C5E30AEF1A4925D1
-:101AA000C41361DC02D5FC56BB4ACCC929FDC7FD75
-:101AB00037E8E84ABE0C3A3648D6162191F4ED8B49
-:101AC000319426F79773BD9C091D9D9FC1F9BC5E9B
-:101AD000FE2F1A1A8940FB5D2DFA0EBB286CF69179
-:101AE0006E734E7F79B8941EA1F4BE32B9B0BF3E7A
-:101AF000192C9D0B93FBD1B93079003ACBAE8A8972
-:101B0000500FEB4F2FC07DDE2428839E300DC7F190
-:101B1000902F7B9D24F8346D94C4E328CA7C202E3A
-:101B20001147DF2B4BCE46FA0B120918693929D71A
-:101B30002380DE1F041F94A9E7F71FE0839B06E6BE
-:101B40008310FA25CB39BD972B7916BB06CEB31877
-:101B500004DDAA61DC8B064FAF2FFBF2E956DF9F55
-:101B60006EF503D3CDD700F2D36C22E7D10F2FAEA1
-:101B700076C378FBEDDE9389F4F99E26AE4FB22949
-:101B8000DD68FDCBC922EAAB47C895A887BF6230A4
-:101B9000E0FC7BA8FE7D3A3B1ADF0724177DFFE2BD
-:101BA0008D04CFE3E8FABE998CFE4F4080E7ABE7A7
-:101BB00013033C77CB4DC470197A6813D713AA75F9
-:101BC0006E52EB81287AA815EA293FDE05FC689160
-:101BD0001DD2407A68CBE5EBA12DFF613DF4FD817C
-:101BE000F9EFB2F9EA598677AD3E50F858D917C4E3
-:101BF000CA17A2F248D25DFDC725C483E7612576E6
-:101C00000BB3BB3B05B4B3CD27F27D58B659502971
-:101C10002876F8EC2E562F4E89EE0FFE3CD985FC27
-:101C2000BBBC7DA547D2E48104F0F943DEB38E113D
-:101C3000542F4E17ADB8BEA472163F54D64FF5ECD4
-:101C40008C69A93C6E4AD79394C9F09044FD013841
-:101C500047B3F3FD4162B1A4F1FB15BCAD162B04F3
-:101C6000887B3B9309A4DD50BF7ECD6838BF777A6F
-:101C7000B5ED5348EBA7220E42501E5CD47E431CA8
-:101C80002BA94CD70EF62179D05EF53CBBFF7EE246
-:101C90007832DF4F98881BEC0A11AB06E41BD57E27
-:101CA000E2FDE441EC273E4A56CEC7B5F6AB3D8E89
-:101CB000448D0BDC93C2F71FE79DE8FF8ADC6E4D75
-:101CC000EDCEC6FC94553619E305A2E8B1CCC8EEBA
-:101CD000FFBED36B20B26A7D4965F14456ED1F52B9
-:101CE0002A5C9A725AE5504DFB21BEE19AFAF4BA89
-:101CF0002B35F5998D059AF230FFD59AF6D9540017
-:101D0000D4E59C96AF69DA8F6CBB51531EBDE57666
-:101D10004DFB2B820B34F5639E59AAA91FD7BE4AEF
-:101D200053BE6AF73D9AF6CD3CEEABC7CBB51CAFC0
-:101D3000CD12D33B4DD6028C47365BB5F1C8B414F7
-:101D4000A67F4A1227E7421CBCF9647E2EE07B9FE7
-:101D5000FD6A8C8BC7E20BBD1E8BA53FF5CF8BF8C0
-:101D6000789FBC6432801CACD84BE5F52A5AB6BECD
-:101D7000B311D6D432969DA74A84E5F728E72BCA3B
-:101D8000FB7DE72B9287C557ED56B2390A5FA4A5B4
-:101D9000C851E39F0A1FC5C2DB3D83C4DB5778BB34
-:101DA0007F176FEF0AA4523D8F2A7E9EAD7F6F751D
-:101DB0008A819F07FB2A5398BF33211E3D7107CAB2
-:101DC000E3E5EA7F651E54FFD7A4A480FE7F63DEAF
-:101DD0006AD0FFBBCC1ED8937D52F946EDE332B4F6
-:101DE000AF65ED0D9E5CA04BACF8F7EA947EF1EF89
-:101DF0003A16FF8ED7E06D514AF4F877B3FDEF182D
-:101E0000FF6E3679720713FF5E043A2305E8C0F8C7
-:101E1000A38FBE3C7E1E6B1FE427E48000FB1EAB3D
-:101E200024C339D7A5F6B5743F9B0BE7A96DB06FF6
-:101E300052ED73E8FE96EF6FE2D02E50BBD79A8238
-:101E4000FA911C90E9F38B74DFBB5986A262FFBC48
-:101E50001ABFDC4C3C169388F47C04E849BE49EE7A
-:101E60008A13215E163A3839FBDFB2E7DF4BB90C33
-:101E70007B4E2E7D2E8776A79CAE7F5D14BF4B7F59
-:101E80000ED7E77F839F26E0791CE26903B58B704C
-:101E90001ED799C2ECF386A36C9FBCE1C46C37CA11
-:101EA0004D4AD180E77083D537BF4DE9E797FE36BD
-:101EB0006500BF5459FF2ABEEF9D268E6D8778E3DB
-:101EC000D9B009F12612961FD9B0DF4882484F9643
-:101ED00067ACD0D118DED805F6D948F479C572229E
-:101EE000ACDBB85F44FD4492597D80589AC0CF491D
-:101EF0002CD6DA2DA7576BB792CA5C3A3BA6B55BD6
-:101F000069955ABB35C4A7B55BE975053A3BA6B5DB
-:101F10005BC3FC5374764C6BB7725A6ED4D931AD37
-:101F2000DD1ABD456BB7AE086AEDD6986756E9EC89
-:101F300098D66E5DB57B9DA63E3FB459533F7EFF5C
-:101F4000239A7261D77735ED171F7801F36F261E3C
-:101F50007E5AD36E52F78F35ED28C2BB204F7B21BE
-:101F60009284906B4E3FAFA95FC8FDB46B7B7FAD91
-:101F7000E987B4B17CEB00FD0FE8F557E2338173DC
-:101F80002291DE57D2295D5704054F88365BB27B1C
-:101F90006711CCE3CCB1EBF7433F8BB768F3B49751
-:101FA00004B5E506323C11F44303E58B20E5936567
-:101FB00090BFADD26BCB48A31DF32106C9678B0F31
-:101FC000DC4430EF33E0ED82FC74659D0ABF793963
-:101FD000BF29F353D6BB8CFA7D2139B24E2FFD8F2A
-:101FE000ED23BB4DC0B7B5BB05F25DA1FF7AEA3A60
-:101FF0001EDE981E655DFA75E8FDCEBC546D1C7B37
-:102000009A68C5B8FED937450F8B0F6AE570D501C0
-:1020100016CF5FF59C80F1353D3E14BF34165EC48B
-:1020200000DB273424936050257F32C787D9AD95D4
-:10203000BFB3F00F98CF536210F282E2E4783DBF55
-:102040001585487F3C27E46AE5548F679B67685491
-:10205000BE92E97F308F5AC2CEA5F47CA5C7FB8A19
-:10206000DD0F9B402F5E2EDEE7A56ACF0795F38339
-:1020700012BA5A53943C3805AF745F5E935A187B7A
-:10208000DFDA907AD9FBD686D4FFECBEF59ED40178
-:10209000EC5C0FC4CBA85FA98F97F58F8FEDFD4C3B
-:1020A000B0631C9AC5BF7C1E0BCB57D1D9C95CB796
-:1020B000C64EF6ED7B4F0AC166DAF912BB7713CC38
-:1020C00067A9DDBB196099DDFB807ABDCD142F783F
-:1020D0003F87DAA99D51FCC3975315BFA802E3229D
-:1020E0001B4A587B7DBB9FA5B2FB3C9D29456EF4E6
-:1020F0003B4FE433FB692B1AD0EF7C889FE73C0011
-:10210000E7852323793C0FF273152A765EA0DB0660
-:1021100063855B9DE7FB48AA13C7B34F7ABE0BF2FA
-:102120009D9B1D06872083FF6CC073D1F55E6BD924
-:10213000AEB1ECBD64CD7B12DA6111F00DFEBC5581
-:10214000FABB9A6F5FA6B884FA58EB7C3995F9BB55
-:1021500046E2B580DE55CE738D27F32DA06F25C1E5
-:10216000E38896C769E4795253F879AEE860E7BB33
-:102170007D727E893CA97ABB6F9F9A6ECAB9EE1CAC
-:10218000BBF765A0AB5F0A98C1BFF45BA2EF7F5FAE
-:102190004D65FE470B5F1F7534918F707C7150F158
-:1021A000933753312E17C07CC5D5A2E734C4E70658
-:1021B0001BAF3A9EDACFFF399E3A70DCFC64229C5A
-:1021C0004F240E95703B21797281FF5BE0DF9330E5
-:1021D000BEFA3EBCDF2FFF5476F17C5A79C07C5AA0
-:1021E000A59FD94EEFC78057DA5F4F2ACBFB5B2FF5
-:1021F000AAFAB15FA21F8AA7DC46EBA0F0F739C3A9
-:102200009FE7340B265C5E5CD39CD62FDE674E1BAB
-:1022100020DE77F1E8E844384F56E256FA76167F2A
-:102220005286FA7E4C8B533BFEC6025676A531BAD7
-:102230002D4E647C3F8ACF43C90354E2D69619C41D
-:102240000BF71D1EE1F9D94A3FA3D26CD83ED13518
-:102250006514CC7763B680FBCA8D4E41B3BF3C9901
-:102260005A322A8DB69379FFA3D2189F6E1BCEE205
-:1022700033FA3CC833BCFD99D42908E99B57003E8A
-:102280004DA218158F63D2581EC64988911546E293
-:1022900067358FB1FB5D4ADC4C890312E2792B81F3
-:1022A000EA95F75A8D04E25A8B44EB46E0C3BEFB35
-:1022B00073FC5CDD41FF037B593DB602F38FFEDD0D
-:1022C000FB5B80CF04577F7B599AD6E7A7782EF324
-:1022D0001ED7D7D22EE3BCBD3B9EF16DAFCD8AF1A8
-:1022E0006C7DBB859C3EAD3C4E01FA1AEC864B24BE
-:1022F0008DD1ECC7C234C637178F9ABDE8C794C5D5
-:10230000633E8772FE2149C01B98061E0068F1A734
-:1023100067C07DA2BEF30F99E07B49562BBE27C94B
-:102320002464832BA1924780FCB26E53F7863498C5
-:10233000EFB58207EE0FA455393AD392E11EA18C76
-:1023400062B6319BD88BA13EDF80F5CE398E8D46AB
-:10235000C8BB96099C6413231DC746C7694DCBC6ED
-:10236000F5B7066EEA4CA3ED12E55E327C2CE8115F
-:10237000C77437C87125CB5FD7AFEF3E2E1FD60D80
-:1023800074DF00F890A3E781DFC7F98FEA99354041
-:102390008F1299EC62F7A2581E2AA45963BEA08737
-:1023A000E54B2740BE510ED33350FF90B3741DF060
-:1023B000B9225F22C737F0BD3A1FBE95E33B4927DC
-:1023C0009F0A3EE9004D900F21CD20C8D7B3AAA2A5
-:1023D000CFF7879CCECBED158FC07C674D6EC23C8E
-:1023E00077F2F9175F8845E0F43239A1EF1388439B
-:1023F000C42533FD1B27CBA88F8943C03C538BECEE
-:10240000A983729CF56A870876CFCCCF0B171A8800
-:1024100044E5AD94F7E3AD24C2FBB92CCECAF4ABCE
-:1024200044DE57E442E4C82902FBC9FEA85FD49AFF
-:1024300040D7536A3D88E78871231A4BE05EC1CBD1
-:10244000F3591F8FC4C8DB3F99C8E8E0127D6E03C3
-:10245000F8F4E4E4ABFB26239DAF841B9A0F6C7861
-:10246000F7D5FD993C7E0EF9E281775FF55ABF7C86
-:102470007EF9BEC7DF7D15F2CBBF3CFF7B04D0E306
-:10248000272963C1BCF5FCAFE8B3C3A2EFF0BD14CC
-:10249000FF3753A6F21700944815D29BE50FCDE104
-:1024A000780EFC9DE2D912C1F3CD1D07107F878DF8
-:1024B00074DE747CE314866AE33D893C1F2388FD47
-:1024C000DF62699B06FE4D8FA9370FC6ED79F1EDEE
-:1024D000CC00D52747EF3B672394FF8E4BBD367862
-:1024E0007E7ACD1B36C0D7D13522DE7FC37BC9AA09
-:1024F0007CA0F7395F95BA2B8E025FCD5FFBCF22B0
-:10250000B59F4DFC296877970445B8E3DBA7FF9694
-:102510003D93C0998E9597B72769CA8A3D5E6E8EA6
-:102520007E4F3CDDCDE8BEE4D96D26C8872F75FB14
-:102530007A409E4EF37C83D3BB6CB8BF52E6B3E0C7
-:10254000D97C13EC278F77984908F85EEA32128C11
-:1025500053796708946F7D9C0FF5F37C654F02F605
-:10256000B7E83111E348D5742C3FC5ABAF6309DB45
-:10257000DFEAD6B1E8A83C1DF4D5A24D0209C8ACEB
-:10258000FD1A4A379FFF7E3C5FD1AF536F5F2E909D
-:102590003526D0237AFBB290785A2683DD6AD33E63
-:1025A0005FDCF100F6BBF812E7314E37DF9F159183
-:1025B000895FE4409C7938E60BC6B237A7D732A1D1
-:1025C000FC70AD05E1476B1D088FA631BE5DB6BB43
-:1025D000F3957414EBAE22B04371074A2DB793887C
-:1025E000FF2C6DBB29F4A40C7CA9CD87ACE27856F6
-:1025F000FCE7C5FC9EC1A5FCE72A58E700F9905509
-:1026000083CC873CBB7FBC059E8F57F03191E203A2
-:10261000EDEFD8D7647269FB1B0B2FB1DE5B0EDFC9
-:1026200039888267456E8E723BB270FBEC8D43E950
-:10263000049A5FFC6B5637F2258B4328E754A27B44
-:102640006317AC5F24BAF85F80BC4954FCABE7CF9A
-:10265000C5C4C3EC8E95BD67E171893EBEEC7810B0
-:10266000F1AAF011DC2830B80186DC86E2FEDF0D2D
-:10267000E8F77D80366DF913637716E88DC5BA7873
-:10268000C12742F4FDD734F770B67ED93B1DF22244
-:1026900016918A8D2CAEDE86F8392DB5BD722FC805
-:1026A000F376264FCB7FF9DC2F404F2DFDD9637693
-:1026B000D0531F486DA9305EFD8E0D762FE82B2973
-:1026C0006087F73F088A51EFEB06DDFC1C9078AD80
-:1026D0009017B602590C042C3013F4E4DF76181D61
-:1026E00010476D78C61C32537CACD8C5F048CB2758
-:1026F00058F97EC457C36EAD1C2EFDE163A932EEBE
-:10270000E703E91C7FE9A0AA576C3762FEE88A3725
-:10271000450F0CD3407A717DFAF7611E614AB78686
-:1027200076B1DA94D8BF9E7A3C2690B3865D8C4E03
-:102730000D3A3FB38EEB653DBFB7E9F89CE205E388
-:10274000614A3E2B0932FDDCFCA3C7F34ED0797DF4
-:10275000B4FD55BB3036C2EF04B22E291DCEB6D71C
-:10276000CC873C83587CFE09978B3EBDCFED8CBC5B
-:102770009B4E0C7CFF0E06EB8D21FB35141FF5DB09
-:102780008C9E007D5CFF9CE8B5829F74C48CDF77D3
-:1027900058F6DCCB6F5D4DE7B76CA73179065B86E9
-:1027A00015F4B342A706E0EF82085D96BEF0B209C9
-:1027B000F220E1F91A57843ECB76769A20AF528FF9
-:1027C000C7D2F64E13932F1D9DDA4F4C07BBDCFC8E
-:1027D000A38B26E0830FF608045C48FDFB75DB5EE7
-:1027E000B683FE003C81FD50E8D547BF7E740BCD1B
-:1027F000FCF5046CE780739A58F45B09732944FE76
-:10280000FEE9AFE9F875EF983DB0FEBA9FDE698743
-:1028100075FC556A647CFEBD0DA9608FEB8C8154FC
-:102820000742F6BC6EEBD791FF16BFFEF554827AD5
-:10283000D33B04E497AE7308AC6FD15337E3FA6A25
-:10284000890FF9AFEE7B6205F88917245216CDCFB8
-:102850001F3284C9C95F9F36E3A6E0AF26C2BEC35C
-:10286000F14791E5F19195E8877C9DAF956A622CDF
-:102870005FB0303A7DCCED33E17AAC81B76AD87E77
-:102880003FEAB10F33BD6920EF140FDA78EAEBD3DA
-:10289000D2B8FEC3EFA5E07B94EF4AE139B4EF3242
-:1028A0007AE3F234EFF1BC5636FE5D7C7C3AEF7889
-:1028B00088CBFD3555BB7F55E05787287130D24511
-:1028C000D4FC154BEEB76F42BE3AFF26D32B2B82BA
-:1028D000B3CBB0BECB184A83FA60E71C01F502F512
-:1028E0002FA2C9F57623976B6D3D9DA724A8F1BB58
-:1028F00087DD8BAB7D94B653F92111BE31459E67C0
-:1029000047E453C9AF58ACF3CF14A8D70B4943B42D
-:102910007A41799F3C9512F51E56441F0490AEF5FE
-:10292000C6E00FBE0B727CC48CF70CEB9F33E2F752
-:1029300072CE3CBBF7ADDB29BF9F6957E457AB674D
-:10294000F5F25BF7FCCD249AFC9E49AE2051E59749
-:102950003E8F2ABFC92C7FFF7F5ACF2E8EA167AF33
-:102960001DD2CF9F48BC86163FFCF1B261B8CFD2D2
-:10297000E155C1A75E6FBEE596A3EA4DFAF7265171
-:10298000E151C19FC2974B7FB21CC7E9E35F853F0E
-:1029900015FEEDE34FFD7AB578D4D71BE0CE51613B
-:1029A00084EEC675747F0DE7AE2F8A78EEDA23F7D2
-:1029B000DA5D1097E579373D0E5E76B2726F8A69FF
-:1029C00023E80FE5796F1CCB43E8A9E8B53B557EBA
-:1029D000FD890ED10E79F5DDC1E8F912984901F1B2
-:1029E0008C18F914CAFDD969A235CB0FFBB2367623
-:1029F000DEB3B0E9563BF8D33D1D39B32AC18F3F52
-:102A000020A24FD513CFF3AB025E6908C56B0D5BF7
-:102A100032394D02DF013FBBA663D90CD8342E6C8E
-:102A2000D5E2A3D63A07CFB36A1F3546F88280BFF6
-:102A30001334819F55F794F6F952C8AB02FAE8F8BF
-:102A4000C8077C14E51EC646858FF2493EDB27F396
-:102A5000F32AAED7A68963675542FEE27E764FE23F
-:102A60006C874836C27A9FE5E7578114E4CF159406
-:102A70008FD571CE8F80CF46C7B6DF1FFDFC68D1E2
-:102A8000BDB449FD2FFE9CF724851FFDE2C8A8DFD9
-:102A900040F9976F67FD99F46F5FBAE7B33B308FEA
-:102AA000728F99C0BEA867CFEFB2EE85F2AFCD1E90
-:102AB0009867CF3AB63F0EECB1A15DEFC964FE5FF7
-:102AC000F38B17F3BAD13EAD477AED1CC2EEA99E47
-:102AD000EDF8C73101F2E93AE8AAC0EEF27D57C33A
-:102AE000AFE3707FDDF3E245CDBEF2DF5DCF0A7E5E
-:102AF0005FA9C7462AE17E718F93DDEF6CF8CDA404
-:102B0000EFC37DC5E5BB3A4D35B4BEF4B7FFCC038A
-:102B10007DD3F33CF327A87FBB155CEA8E275E6D5F
-:102B20003552FA7D023EDF50BAEFFE6E4239DCC309
-:102B3000E88F1786871E8A075817C54B1DE8C958A6
-:102B4000F8786308BB3FF2DF878F4FEF80F1EB3BF4
-:102B5000261288A747F02278D9731BE65DD0F5B31B
-:102B6000E77B2EE6817F74A9F57EFA7F6CBD8943F1
-:102B7000FFBBF9FDF12132CE4FCFF7FDF9FA977780
-:102B800063F9A7360FCE7790F27ED5D0FF5BF42E97
-:102B9000FF5F4BEF039CDE36079CA7F4BCF8CF2CFD
-:102BA0007219EBAEFF5FBAEE3E3FC7E0B14CA0F347
-:102BB0007B87046F2E1162E7713E3154BB8F98C939
-:102BC000FD8899C9B5E83FCCF4B2F84A3329D80F4B
-:102BD000F7D4025E11CF1D309986E2A16B4E7E10B4
-:102BE000F3B6A4C0C8EF401ED72DCB3DEC3B5FDA57
-:102BF000FDD5CCD4B232F0DF0E35D179D176876CE9
-:102C00000647335DC22CAF88FE1E85E8E7FD69CA22
-:102C10000D981732AB58BBCFB85DB76FB8B5525BE4
-:102C20007F0B793A05F2EF6EA93362BED0CDBAF6CA
-:102C3000AB873A709DB792C60D2C3E7379783AC037
-:102C4000F1D41F0F03E3AD1F9EF87E127379E4FEEB
-:102C50007833FBD8FED24C2BB8BFC5F3E4560D0A2F
-:102C60009F84EF3BCD7C6805BF662FFB5EA7AA5F04
-:102C7000C48B82F7CBC5B742273DDE15FC2A78D33B
-:102C8000D3E12938934889E03F02953C121F51E770
-:102C90005BCEECF31BAD88C7D7B6B3FB0AAF15D735
-:102CA000B4E643F95901FDB50B93C7130B5DEF2152
-:102CB00023D9CDEE7F79654751249F4528FE1D9E7F
-:102CC0002B403EA17A5F0AF984EA75413EA1BA0C15
-:102CD000F984EAF6904FA8AE877C42753DE413AACA
-:102CE000CB904FA86E0FF984EA32E413AADB433E7F
-:102CF000A1BA0CF984EAF6904FA8AE877C42753DE4
-:102D0000E413AACB904FA86E0FF984EA7AC827542F
-:102D1000D7433EA1BA0CF984EAF69047A8AE873CA7
-:102D200042753DE40DAACB902FA86E7F5DF8254D2E
-:102D3000B984BCAA695F6A7943539EE6F8B3A6FDDD
-:102D400057DDEF69EAAF97CF68EA15FADF907B4E5F
-:102D5000F31CCE2C0245B08F617FE59E7F68FA910F
-:102D60004805C6994DA411A105E2B714C69376840F
-:102D7000562AE6004B47F972D2815FB706360273D6
-:102D80001D9A74310BF4FF6B936F62F1077E4E3026
-:102D90000BFE2953264EF83C03F6B5CAB9A73D2CC5
-:102DA00092D078CA876101A1239C404249940FC305
-:102DB00071085DE1247C9E1476224C0EA7E3F39407
-:102DC000F01084A9E11C8469E16C84EEF01884435E
-:102DD000C257201C1A1E8FEFA587F3116684AFC15E
-:102DE000E799E14908B3C2A5F87C58B804A11CBE14
-:102DF000016176F87A84C3C33761BB9CF06C84238D
-:102E0000C273F1F9C8F06D0847856B108E0E572319
-:102E1000CC0D2F4378457809C22BC377E27B63C280
-:102E20002B118E0DDF8BCFC785BF81302FDC8CF04F
-:102E3000AA7013424FF8016C971FDE84B020FC6D1E
-:102E40007C3E3EFC30C209E127F17961F8098445F6
-:102E5000E1EF239C18DE86B038FC138493C23F4216
-:102E60007875F8057CEF9AF04E8493C3BFC1E7D71D
-:102E7000867F85F02BE1BDF8FCBA7027426FF855CC
-:102E80007C5E123E80704AF80D7C5E1A7E1DE1D495
-:102E9000F09FF1F9B4F01184D3C3EF21FC6AF80478
-:102EA000C2B2F01984D7873F40F8B5F0397CEF867D
-:102EB000F0A7086784FF81CFCBC39F21ECDBEF4FE6
-:102EC0008E752FD167F802F6CF56D7A0BEF345C84E
-:102ED00016CDB9D4E30976D493B3D6B03C928D2500
-:102EE000E7A6A25FBBD22CF3EF6BEAF4EAE756F059
-:102EF0001F3640CD10D607E401CEE3FCFB5AF1DECD
-:102F000014F097361674D7433CE4C1ECEE2A84E9FA
-:102F10002CBEBA9EC307D259BCF4F651CCCE56ADE6
-:102F20001C89E757247970EBF803D8E79448FBFA3B
-:102F30004C5EB6F666E1BD8041F633D87697CA8F0F
-:102F40005A95EE0BA6A35FA4BF9F37E8F79F413DBC
-:102F5000F1E5DF6F1FE8FDE39C5EF68C8A5D384F7C
-:102F6000C99B07F553D60D1193693FD5AD8203EC8C
-:102F700064CDFAFCE940BF02E2C578E2BC18795D95
-:102F800047D2599EC682462381B8E20299603C77B7
-:102F9000C12E96E70B71D072CA17759C2F966FDA07
-:102FA000690217B4AE7131CB3F0AB2389385FE0780
-:102FB000FCBCB47536E61F2D7B461B7FAA87B88EF6
-:102FC00008E7C8DAE70D3CCEA48F57EAE34B7F4C05
-:102FD000E7F1250FCB3B226206AEF7025D2FE473CB
-:102FE000F8EEB65940FF533CE03989B27E255EA920
-:102FF000E081F4BFCF8079A167F78FC43CB5B3B24D
-:103000009C06ED7C549CBAAC90FFE09B08CF29FE57
-:10301000309FA4B72901F3914E507D2E43E293C314
-:103020003711BE9FD6FD4E26E1DF6FD49E1B585A46
-:1030300031FFBADA4807A6EDAA7724E1FD47DA5F47
-:10304000DE6E8847EE30623E5080AC7293E2FEE75F
-:103050000A151B8CC81F0B763B597E58C0FB26E413
-:10306000EB2BF438B13E673AE4152D68C9CEC7B0F2
-:10307000DB6E23FA79CA79A942A7FE79D11589F0C6
-:103080007DC4A52DAF233D29BD34F5F5AD9FE2FDEF
-:10309000014AAF5331E8756A207A5932B4F482B8E4
-:1030A000F2AD50B92609E5B46A5D6864A38A1FF5DC
-:1030B000717A9261C5FB8E4A3E71D950460F2279D2
-:1030C0005281AEE75A0B915E7A3A95FDAB06E94123
-:1030D000DEB1E1F776E7E590F937D2E7F379DC7214
-:1030E0005EF3F5E83F676730BFFEB5B5906B49C842
-:1030F000EB6B2DC44B9DE737D63AB0FCA7B56E2CD1
-:10310000BFBD564678646D2EC2532696CFA3C81312
-:103110006500CCAB1B9DC1E4687486B2AFBACB0D21
-:1031200071E9B27FBD5108F93D2981E499D3AE45DB
-:10313000BF5B93A75139479B87D16DE4795E9B04B0
-:103140000F7C476541C5359AF624777CA40CF6833D
-:10315000E78D2C6871E2F7DB6E9B91A4697F4B4B86
-:10316000BAA67C5D868CF39B5D96A3797E7BD51891
-:103170004DB99AFF6E02B1C41BD4E753D4336279C0
-:10318000DE0ED6F67CE3C4B4D574FCF3078D58AFDD
-:10319000A7C7295300F7E381A7CD1EB043A7E11EBF
-:1031A000192D9FFE9388FAEEB491041C54759F1656
-:1031B000C87A804462F274E13093A7B27F8904F642
-:1031C000E1E4C7663CBFABD9229000DCA1EAA59838
-:1031D000A7E3DEF52333AE7BE11691F8F0BE92DC77
-:1031E0000EE7D677ED18ED8173CB7939A14CB8B7DE
-:1031F000D7FBF338CFD3B4B6A69BBD7F9AEEAF9D75
-:1032000090972414E0F9C1C7E56DB506C837100FD3
-:10321000A6809C7EFCBC88F194252BFF54E400BD65
-:10322000F64AFB5BC5749C536D228E7BE619F33620
-:1032300011E5DD9B06DF758DAC3B8871867DEE8ADE
-:10324000BA0CCAC71FD606F350EFAC61F1EDFEF819
-:10325000A1EB057A03BFAAF458C46EB17332AA7CFD
-:1032600086807EA8317AF0DCF454AB11CFF3A8FE4F
-:10327000C7F3FF536D4906A67F9E47BE5B20C92654
-:10328000F5B80B5A452FFB5D08D904F3250F8B3E8B
-:103290003211CA2C5F21D022F8D8798D96BE77AE34
-:1032A0009C88F78BF5F9530AFC84CA944F750EB4C9
-:1032B000F445763E4B26744BEAFC7125BE42DCACED
-:1032C0007FE53B3EF5C31FFFD6640ACF7AD92707B7
-:1032D0002F6CB7A17EFCC8F052D16A0ACF9407DEEA
-:1032E00097285D1A45DFA380CF6586D6AD029E8BF9
-:1032F000BCF72D388FFFF039A307C590E76B2DFD84
-:10330000F1926103E507C10CD8F972285570C357D3
-:103310007909E66FCC25ED3C3E1064E75830098A08
-:103320001F473D3BC77AAFD0B619EEE1D6E8EEEDC8
-:10333000BEC7EF2DFC3043D0D8E7BFF0728D81C9F6
-:1033400027D9C3BEBF08792F2354F654D1A7BFC8CD
-:10335000188EE3F6D955D28E7AA5967F1FB8FE193E
-:1033600033BBA7231307C8E312461E7216E4998ED7
-:10337000B3D4F4DC77809D17932EB4731F1A83B5F2
-:103380005DD9F0FEB6F52E7CDFE80982FC723B6069
-:10339000A18A03F4C762C2E6B7BC4D088654710A1D
-:1033A000E5F73808D80595BEE96F0FB4766011B718
-:1033B000778B882EDFA74D6B972A126CB8AEA56D60
-:1033C0003CEFB96F5E22F982E2ACD6177C6526CE5F
-:1033D0005BF004A3CC6331E90DC17780973FCBEE5E
-:1033E00003E9E7A55FC760E759EB993D15BE27DC08
-:1033F00037AE6EDE0ABE095C5052D141C17B6D8092
-:10340000E1B3B643407AFD85FB55CA3D3B85EE8B63
-:1034100049C54CD06B8B1FA5FBC2EC081FF4D9EB40
-:103420009D41F497CE9036BB95F27FFD969DB74CAB
-:1034300082F79E7ADD04FC5DE50A8D3438E1276968
-:10344000EEF956596614FBAEB3E7FF29FC101E6770
-:10345000C2F7283E166D1731AF41D58E9FEF07108A
-:103460004F7501827944756F8A9E66FAB40E7ECEDE
-:10347000A7E0F2E7ABE0E77F7ADE7A3F263B7360B6
-:103480003F46AF5FFAF9313AFB09F726C05EF6A670
-:10349000B03CF0F39237D1857A59A777530AF0BB45
-:1034A000A38ADEADE5764F196711D83B5A7E7FCBF4
-:1034B0000B76883FFCE5D11752318F02ECCBD888D0
-:1034C0007DB9BB868D77F72FE3306FE9E3F2AE3C31
-:1034D000F0FBAABEF73BBBFABBA6756EDF75993051
-:1034E0005F6E0F978BDBB21C600FFDD1F32AFAEDF4
-:1034F000BF62ADD3768975DAB4EB5C00EB54DD07BF
-:10350000A9E1EB3CD9C2D6F75E2B5BEFC27EEB0C98
-:10351000E039C8DDDF377B02E86784D08E9FDE2983
-:1035200012B87FD6E767E8ECFE05D2B615F0B17C9D
-:10353000D5DBC724CA174B4651FC503EA87AD88C1D
-:10354000767EC9CFD9F9E78742491A1EC0EF0BD959
-:10355000BF419F2FA5FE01F8179179F4D9FDC599B8
-:10356000852ABB3F48FCADE071A8151DBFC3DF8BAA
-:1035700012BC2C1F7285F21D98DDBAEFC0C8A003E3
-:10358000D83D790BD02983C86C9FA88DA7FE6DE428
-:10359000A777AC42FEEF1DA5FE5E6F437CC808F91D
-:1035A000BEBD3B05F48B96DF55622F2190DFCAE24A
-:1035B00060EB3399FD12BC5ECC7B3153BAC6D3F1BC
-:1035C000EECF94D973D9C1F2BA9F22F8DD1965BE46
-:1035D000FAE7101FB780FDB31AD0FEE9D7FF8B4C76
-:1035E000E62F2F170DE84FD79B985FDDC3BFFBF089
-:1035F00028AF7F3493F9D7DFE5F1811EF023E17C1A
-:10360000FA5A33FE5E0F2153314E2E11C67F92823D
-:103610003787F4499F7CA3BFDC9B0178BA83741978
-:10362000819E338B67CB706FE058AA05BFA344FF20
-:103630002AA09FB9BC9F4346764FE0188C41D735EE
-:1036400097C7938FC16740E9F8C78698D08F0DBCA4
-:1036500068463FE1FE7816EF23C98912F0F9ED5C68
-:103660004FCD9B6CF6C2F9C0DCC9F75700A4FD052D
-:1036700008C55795A577433E1DA7C9C0EC7C938B21
-:10368000E07D49B2BEBB10F07715758B214F9EAE21
-:103690007ED7174903F191F69E423DC415AE268CA4
-:1036A000C18A11BF9A72BD89D51FCC3C36F3D10CAB
-:1036B000BABF866C26B0338023E08BEA44DCE7CEC9
-:1036C000823C7E174009F9ED4689040C0CB658F18E
-:1036D0003B442CAF5F3907B9B9988412E9FA420725
-:1036E000B4F7286E0D1942A3E17C470A7502FE0C5F
-:1036F00016D9E8A0E35494090580F7FA75839BEF87
-:10370000F1CC0F70BEF5F0BD2B98E73704CCE799EC
-:103710004B851EF8F40E89EC130B18FD800F1B5C13
-:103720007200DBAD647CAEDCDF50E8924FBB57E348
-:10373000772E9F1FEDA7C50EEF9BA2C74DCE70F948
-:1037400050FCB4655C6E97297CF7AC565E6D5932BF
-:10375000FB9E1AF883146F73398CC5F7F159ACFFCF
-:10376000F82C165FFBDB658EB7DC4C42B8EE17CD4C
-:10377000484765DC591C5AB258FEB2320F857F6B40
-:103780004923E6DFD4F2788C816A12CCD36DFB3EFC
-:10379000E6F7EBF384A8838479674BB7EB9FABE242
-:1037A00039A2462F619C5330F52E84F9095F89F3C5
-:1037B00000BFCF35B5633C40DFCED826A09C1B5B55
-:1037C000A83F25F0F32D5A36B70AF8FB0E73337A6B
-:1037D000C7E1F7CAB95F5DCBE94AB5F774B80754DA
-:1037E0000BFE149E7FF1EF446D617EA4C4FDDF05E6
-:1037F000AD5A3F63EE7A959FC980E65EBD59971F2B
-:103800006EE4FEC67153EF38D0F7FA7BF6C70D6C45
-:10381000FE815482F991CA3D7B89FB930A3F0DC911
-:10382000326ACEC594FB9C55A0A7D8F70E74F95404
-:1038300056FCEE4A95C0BF57C9E38A67A9BF89DF26
-:1038400095391A87764B8933F694D8028644F89CCA
-:10385000252BCF4BBC7B26F89955769304F0A2A17B
-:103860001BC7592D76D9B2B32371DC8D25E3B74040
-:10387000DED0ACADA3675932F19483DF471AFB1A4F
-:10388000E4ADCFF99CCE1FCBE36679E9FEA8E7E56E
-:10389000DE3B2C54452FCACA9B25517BDEF358EFE3
-:1038A0005628AFCE9A384BA276B0E7C1DE2CF88608
-:1038B000F0EAADD7B0FA26A5BF6B66417E70CF1394
-:1038C000AC3C87D607C0CFE5F780AAAE1650CFAE86
-:1038D000E6F647891F55195E62700AFB9D8F4BB54E
-:1038E0000B6455AC063F47B49DC2DF13D82C7BB1A7
-:1038F0007C5F866F7E16ECA3660B0113DC8B7F3337
-:10390000388ADBAFA8BF7BB13A93C9E5BA61AC3F57
-:10391000055FB49FBAACC2CBEFC701FD146AFA5978
-:10392000F965E673B4FF7CEEF932F3F1CADAF928EF
-:10393000FE99F29DB957B2BDDF81F92DFB26DB0F51
-:10394000935356CDFDFF738DBF1C0576FFDCB3E6A8
-:1039500024E0C3653FFD55562DF87FDC1F3AD3792F
-:10396000C40479DF2BC2ECBB380D61F69D9C15BBFE
-:103970003A4DD3C7421E6BA7A95435BFFAC8EF5CB6
-:103980004937AAFC9827B30C3CDEC67ED771D94FC5
-:103990003FC0EF092E33B4BF0F79BEE46A1647D398
-:1039A000AFB399BF770CCEFDA3C40BB66531BFE3AF
-:1039B000628E3708EB5C9745B02CC6F86ED787BC93
-:1039C000BFAA78A6C76B8A6C1699E2BBF04D5F332D
-:1039D000E49DD63E955D20D2790433A6FC386BC0B9
-:1039E000F8662F8B6F76B0F86695ABEB2E6AA4C89D
-:1039F0005FB6CE7DC8722D21373C4EFAEEFB41DC1E
-:103A0000B0CCACC8CFAA595327B3781994F767D56F
-:103A10003F04F2B39FFF3EDBBC89E3E241CEBBB380
-:103A2000130C0E2AFF3BD3ABFF027C316FE2B5D300
-:103A3000E17989D936AA9AC5C7913F76A65784A05D
-:103A40001EDA43DCC3670AA5DC4AD7E1FBBD8879EF
-:103A5000D3BEBC045FB47B2A7BB8BDFA4B163B0FC8
-:103A6000DA6FA0F32C88CC43199F72FC5D5D10B710
-:103A70005A37241FFC687B46C9A9ACC2C8F8F60CAB
-:103A8000DFEBEAF1E972F3E0F960E77188D3E31460
-:103A9000A75BC56411BE94D0A7D76F9C9AA029CF0D
-:103AA000999144BCEAB8E99C744DB9B22A47D3FE57
-:103AB000F6856334F5E5E6AE098D97E1EF37D89EDC
-:103AC000C1FCDEA31D17DE9A0B7EEC76D123D0F568
-:103AD0002C7971C75B907F7D167E82A480C5C5D886
-:103AE000F71AF9798CE49534E731075E3081DFAE5F
-:103AF0008AF3EBEEE51DC438BEFE3C46C917FFB2A3
-:103B0000E731D230FDEF797EF40A5D1929DDDD89D8
-:103B1000F4693EC0F2989BA9DF02DF13FBEA2E7323
-:103B200010BEE1FEF1AF4E9864D5B94C43B8097FA1
-:103B300057B774F7093CB7D991C5F4F68A8E4F4D43
-:103B4000704FEAAB1D2B519EA753FD9548F9A6ABCC
-:103B5000938CDB05F1E46C1BE6E12C6BB91EE3D41E
-:103B600089E1B908EBDBAEC7FE96876FC2F20AFEA9
-:103B70007BBEFBE3BBA6831DDEFF0B27EE075F13B7
-:103B800043A39E847ECC36D40FE5E9F3D6819FB063
-:103B90003F3E30F64E3A5EF9CFBE8A79E82B760981
-:103BA00018372D17C97E01F2EFC371D85FB9F8C776
-:103BB000092BE9F31B4A995D2D071F87D68B45B664
-:103BC000CDF83DE918BF93E619C6F48AB19BCD7BC9
-:103BD0005A7836F6A7D4170D1BAEF99E9F3165BBF8
-:103BE000B4C01A598FB15B40F8B5F018840DBB66AC
-:103BF0004B907FFEFBDCEF27039E687BFC3E587FEB
-:103C00007D3C319144D15B0A34733D3C17F4309CC8
-:103C1000DB677B670C4B81DF23EC962CA047AD164E
-:103C200007F82F338BF3E55AD5BAC4976EC37B10D0
-:103C3000E6E45E23D8EFB914AAF5F6FC1876E6C6DA
-:103C400061CA3D9B26F6FBBB8A7E7FF7EBEC3BA867
-:103C50003C3EA0C8D375C30C9AEFE974094C2E0200
-:103C60003F67E702D3B37D0B61BE5D25A4F279D433
-:103C7000A35D59701FFD3F357F4A5F0BD0DF2E7566
-:103C80001388632C19A6D81D26CF979AFFAD7CBD4B
-:103C9000AF89C40F7CF1DA75D77579E9BC3AEF1DAD
-:103CA0003F1EEC8232DE3DC3589E2971F47E8EF9B0
-:103CB000867B126488EB97C399C784883F0FF98885
-:103CC000103F6CD8637E1A3E90DA60A7FB7B2BE432
-:103CD00005C685806F3B7F1B2781FD1833C277CFD8
-:103CE000B042783E7A2A7CC7C7DB619608FA41DE8B
-:103CF0007B015FB1E67B29FDA5C8A39ECF7C2D4C3F
-:103D0000FE7C5C0EAB39DF2EE072582D7912E13C5F
-:103D100066FE4111EF452E58238CDB05F101D98653
-:103D2000F7F4153954E4CD087C391EF893F1657D1C
-:103D3000D8C9E53B9BF7CBE4A05C64F976E5639CCE
-:103D4000B87F5E114EC2768ABC2A72BA3EDBF76338
-:103D500058777933956F3A8E6FDD9009202F113E99
-:103D60003139809F289FB86B557CD0DCF999047C51
-:103D7000629C2C209F98292C55F151459F7FE298F9
-:103D80009E4AE731737D367E4F59A9FF591FBF0CFC
-:103D90008EDF9FE2ED17584323C1AF3536C679E079
-:103DA0003BF2679365D463AB3609F8E384AB8C15BB
-:103DB000A5E05FAC7A42C0F81EF81DA07F8A0E37DE
-:103DC0009AD4E720B785F3F0BCFAA6F00884C10CBA
-:103DD000DF8BC017D5E15B381EF3A29EF79D6FBC49
-:103DE0001FE36AE783660FFBCE98367E57E8F5E05F
-:103DF000F99FF1A0916C9321EEE613F17C2F93389B
-:103E0000BE2DB0F81DC4F394F89B724EA7C4E1CC4C
-:103E1000F03D5C951DBD20B565C13EA45F3CAE8400
-:103E2000D9FD8FB61BD9BDADCE3F161968FD87D918
-:103E30005E8CCBED73FBDE86F52CBD31F853232D64
-:103E40002F7BF0053BC4CB157CB64BA191B05F6ACC
-:103E5000A77884F8607BAB581664FE4EC26C557E22
-:103E6000452CBE5E1ACE41FC28F646D1DFBF5CEB86
-:103E7000C64DA9A2C72F658714FE5ECEE56039C87E
-:103E80000151DB9BD915F0BB662457C07BAE117B7B
-:103E9000C3E441D1D394DF516ECA733231AEAEE880
-:103EA0006DBD3DDA2BB67FFB6A3847937D7132C515
-:103EB000CF949FFCE385776855FDF33F9A0A742AF7
-:103EC00019231038C7BC949EFC7FD95BF3F900809E
-:103ED000000000001F8B080000000000000BB55B15
-:103EE0000B7854D5B5DE67CE9C9949322FF28020ED
-:103EF000249C993C0825E0F08884879F0702018470
-:103F0000E0046F1135CA2422CF840494CF28F4CE64
-:103F100009090894DAA0D6528B7642C1528B6D788B
-:103F200058D38A303CA441AD1DAF7DD02A7450CA0D
-:103F30004B9088F582B754EE5A6B9F939933495052
-:103F4000DBAFE3E7B7B3CE5E7BEFB5D7FAD7DA6B7B
-:103F5000ED73100F7E2EC94318B3AE2C678A9DB146
-:103F60007BA12D81F63AFE6E634C624C69059AB1D5
-:103F7000A879A623F6DC299B18CBC0E70D8C153158
-:103F80003643E77B7F3963B73076BF9BF15F3D30C7
-:103F9000F565ECDA0013F14DB1B239FE42786E8E60
-:103FA00064C7CF57EA9920CBC09A270B34EF8C9582
-:103FB00051B32D1DF8EC36F7360FD0C5C3E4798523
-:103FC000317EF12BCA5D26329B900AF29AA32CB562
-:103FD00010E7D7E556F93A5F22779AC6FF3B91D5AD
-:103FE000B7C2F8DFDD765B4401B90EAC18314294FC
-:103FF00063EB15CB16DA5F591A8C1DC958C76BD6FF
-:10400000D016909BC17C02F05F7A6D50683D6CEDDC
-:1040100004EBB8C68056F7A6C8B8AFDA7D29C45FEE
-:104020009BEC0A09D05FEBECC8F7833C25FB93C2FD
-:104030006C28ACB33FC9CC60DD2B390F14CB45F8ED
-:104040007CE044C10942EFB59A19F0A9D9CA68D4F5
-:104050005B4FF2EBF225B6FAFE4BCB05D5E5626C71
-:104060005A89433541BBE86A0E6323185BBC762A44
-:10407000B5AF043341C98C4DBA5A0ECA60ACE6EAFA
-:104080009DF47CC9D514A2A77D3B528AFB61AF0881
-:104090006C1BC85FD6EFBE550CE46B4F6643F6C091
-:1040A000BEDABD59BE46E8AE6E9E4AFC65BF983C7E
-:1040B00005F7B5640F30E3B8022194877A3A653783
-:1040C000B1DE8C3D64E3E27F5AF7A791328CFF7436
-:1040D000A4631803D64362EB536304B2673BDA73FD
-:1040E000C2CFFEB1FB2FC0275D159902F258AF0A6F
-:1040F000D446E4C022D407F031067CD5BBFA8E0C3E
-:10410000D8BF0A9E7E25C98047A9FA1309F16485A4
-:10411000B624AE7F8E8693443DD6CA1CD75FD50F9A
-:10412000EEFB8A785A8578CAF88FE26915EAA91BEE
-:104130003C3522CEFE553CDDC08E3EE689E16CDA90
-:104140009B1C1F2CC7E1DBC6082F2477BB252BD473
-:10415000087CF7A25D115FD7591DEA730EDA372D7F
-:1041600086D7973C819FC4DBB93D592D5C5AF855E1
-:10417000EC7C37C3B8716F7A1D53E0F91C68E3E338
-:104180008615ED57D8757F3BBEA69D9FD5F8BFCC51
-:10419000CEAF6976666EB0E348B29F8C764DB43B85
-:1041A000DA15ED5EBBCFBAE546761D9C1B68EF2E97
-:1041B0004E3077B209E58CD9C57A27E2E6D3B099BB
-:1041C000A17FF564576913D7BB4EAF0E9BA784E858
-:1041D0003C6069E543082F47FF9DF85356D2FA77B4
-:1041E0005B2FC6CEC8757E33F0CF2A86AE9BB07FDC
-:1041F00069B362C6F8027F8EA1191566237D6AF441
-:10420000B2C844D8EFB4A73AFB55EC9F34CEA58D85
-:10421000670A6CAB93FFB45C1BD9407237733B06E3
-:10422000A266FF90387A24D08E38BA3881DECCF975
-:10423000F11C71D33C211EEF617E6138D2FA7C9A69
-:104240001FB08ED25E60BF197B04F77AB0F73DE3F2
-:104250002E59D03E6525D123FD60BFFF273FEAB729
-:1042600027C1738C83206FB2A7A159356BE3C17F3F
-:10427000AA35355A5B0545043B55170B21AFA7AB53
-:104280001E933DC6F30C7F66E3786619F9F5C6A365
-:104290001D69BC97C687AD5F63FDBBC63125D44D94
-:1042A0009CCCD4F9AE01ADCF0FBABB13F617EAC65A
-:1042B000DF640FF79F88C954C3405F059EEF35DB6D
-:1042C0006E05FB328E8F6F789EF6AB855C5C256148
-:1042D000BF3792D7E9D1FD38B65FD9383E7C237D10
-:1042E000A577D197868F0546BCB8CCFEC39F821CAC
-:1042F000AE74C1AD82FD97F893363017DA5FC7F719
-:104300008FFC4A7FD85F12EBC4AB11DF21FF44D092
-:10431000E312A6F76F69C673C96FEAE4E778DF2B8B
-:10432000748E2F00FCB8181F3FD1D3D2ACDAC91E4F
-:10433000D44F74EE0DF0DE9A408F4BF00F0DDFE49A
-:104340009F18B7413F79DDC48D4A4DBF1705361B15
-:10435000E35E6402CFF7225EDE3678787EB750D314
-:10436000E352AD8D24C7E9A17FCCCEF00BB302C3DD
-:10437000BE494F77A76BFB56C3FEE9B0AF482A1B77
-:1043800022004E56B4EC6D6ECA8A8DFF564BD88F04
-:104390007AE89C4FDD17C1B87FB7A6A78696FD11B6
-:1043A00095C73301FDAE86000138D823A822ECB3AF
-:1043B0000671D0CD3EA775F51B3561BC22DD607C52
-:1043C00079571C2A09E39994FE75C66B769A9E600C
-:1043D000C72909769C984057E874C810CFF438571D
-:1043E000D5B671756F9063F176018F098CD7166120
-:1043F0001863CF78DEF0DB47235E65A91FC4FC6736
-:104400003D6F456C80E5728C6784DFDF362B6097EB
-:104410003BD1DF897EDBAFB8103F75AB33813FE422
-:10442000F95DB30D58EF69DA28614EB3D5F34EB399
-:1044300019EC77F7C85F1CC1F9CCC2BB91E9C20D7A
-:10444000F0DA9CB08FCD09B49AC0FFF497C4F7A6F8
-:1044500084F12B13FA3724D09B12E8B5C6F195737B
-:1044600005F2934AB01F2AEECBFCE6D79ECE7CA184
-:10447000F33C13EC942719703FAD91D3873D27FD92
-:104480006B0BE3E8960FF47848389618FFDD9BCE67
-:10449000543C3FA41EE2D9AE9EE25941E279C7FBEB
-:1044A000FF8A7FF6C5BC9319CEE543A2913E20EA70
-:1044B000FED61179D88E0F75FA921FF3F169DF37A6
-:1044C000EE0BEA42ADFFA27F22F8FFB4EFEAFD1740
-:1044D000FD4ADC3E75FED27F5E1771BDBFB45CF055
-:1044E0006F85F92A2684F3EAB04DE52D9C33229E90
-:1044F00063B536EE4FA5AF897E3C672A92C379CB70
-:104500000AE3F6C95AF3719F075688641FB591D71D
-:104510002355CC6761500A1D70B9EA5F00FE432B3A
-:10452000C47A3CD74ED4A7F546F9077B79BD77C846
-:1045300035A0F783401F4899639181EFC0E393A8AA
-:104540003D282A6B3A00C7573DD7FCF641D8EF22E9
-:10455000FDFCBDE58ABF01E2F4158F4CE303A9EE33
-:10456000DE6D98AFAE97D83619E5F13D4FB8F98EAC
-:1045700075D87A90A3B261706FCCDFAABE575EDAAD
-:1045800017F8AA564B3E81F8D850943BB07E92055E
-:10459000FBE73669AD3A99DAFD5FEC7E7328F07778
-:1045A000AC137D5B8079DF55AFB30AE4FA3089C77D
-:1045B000E10F2EE43A51CEEF7A03A217EC5AE974D8
-:1045C000240B7878B865E74C9877438E62F616C569
-:1045D000F8F77F21CEC17CF3D50B55BD03403BBD21
-:1045E0001CAFFBAE56F5AE8A3BEFE75D34939EF70A
-:1045F0005BE48731BFDC9F9C25A8E4C7AD69E5E09B
-:104600002F73B5FC1AF052BFBB9B73FF1F1E917036
-:1046100076CA5ACF3E04101FF876C63894531F57F7
-:10462000F4FB40A303F1DC5F1E1E9F47BBB227DCF7
-:1046300084FB88E12CF51D3C2F298F063ACFEBDA5D
-:10464000A802AED821C8FF518E74A514FBD94A60C8
-:104650008038C6325BF3E3EF236279EA2A2D1E70BD
-:10466000BEE3AA83EAD6E33B924258CF1C57DF73DE
-:10467000307B3C3FF793F94E878A87F11987C38CCB
-:104680007A3D610E9E7E14C6CD7B4EA2383AEFB9BC
-:104690008C951D180FC09E79ACEBBAFFED9568DDC7
-:1046A0001EFD84C9E513C7C5F9893AA01CF7D39349
-:1046B0009FDCE61D50BEB5B0673F99AFE5EDA5CFD5
-:1046C000497EC4F9FC228799DD0C75F673AF6F4300
-:1046D0003CCE5F9A34DC0A82CF7FCE4AF68D3A1CFC
-:1046E000AA1BFA034E87B917B4FFA5E121DA90445B
-:1046F000758AD8DB42714F5C5324A37E4A4466B668
-:10470000C1B9223A7DB29FD34D6EA8DB563B8A6574
-:10471000B4EF0AAF4C7AEBEC77CDBE5D80BAE632EF
-:10472000EC230DC69DAB7FEA995120DF79169A35AF
-:104730000AF47E190D0DEB5CDE238654AC8BCD8A1A
-:10474000B90CE2DE02C6FDBDE6E86ECB78F8734137
-:10475000DDFCE9581F2D0C491F44B5DAE73AFCFF90
-:10476000197BCB82F9EDE2EDC6E7E03116F4AB9AA6
-:1047700056E3F35AB6E1137128B6E60FA205DA73D1
-:1047800058B7FEFD3F0F391CC757ED75A49F1E0C8F
-:104790007F0C67C341B3B04EA1EB2E845DBD48F2E0
-:1047A0008AAB9242A847319B9F0F9399104A42408F
-:1047B000B861DFB0EE95E0B121870110E2632348D4
-:1047C0002FA78280A781A00FA78DF8C5C7C4901519
-:1047D000D62D49634A2FD4E733E58C39489FAA1B6D
-:1047E000E8C9E975668C4FE7B4F85229307F2BF998
-:1047F000BD2F1BEBE379CF2591FDE63FBFF08F3F47
-:104800001889F62A4B8FF7A3C735DCC17CCC961AE2
-:104810009BE74CC3B7B2519E921F415D89F5A61824
-:1048200078E66E8A97293E8A5BEEE87746214E1A33
-:104830005286AD678893BED9DEC2D8F8F9AB56E48C
-:10484000F3F150AF3A315E25D17EAAF7580927958A
-:10485000EB4485CEC72C0B9D8F1F3425115DDDBF2A
-:1048600098FCACD2C402B80FC8053329AE7395B317
-:104870006A3B5376DB31CE6F88884EB28FAAD9CD92
-:1048800082F6D9E24DA3F5E7A08EE1DC3AE8D5F453
-:1048900062E2F861FB84D0368A4F7532FA7F85492F
-:1048A000A03897E88FBB3109C371D9BEFB715CCDCD
-:1048B0001356DF2A0F9741D4E5013CD59822F37EA9
-:1048C00088F3FED24AF71AB5B08F2427D517CA2E1F
-:1048D00090BFD6CCCC16BC9792793CD3E5A995CBAA
-:1048E00027234EA1FF9819FA6B1C3C1ED7F4E2F760
-:1048F0003DCC610B6D8B5F0F65CEE1E36427FAD988
-:1049000068C20BFABD09FA2F31DE5FE22C96A3F0E4
-:10491000BCDDC4D6E23D09CA336868DCBA40F71D85
-:104920008A785C6AF63AD00E69B366E37A2F891406
-:1049300097C0999E28C6FCEF257104D6B195EB0E61
-:10494000956E427AE730378A50F9F377E97C5AACB2
-:10495000E12C8A793F9E5740EF84F63D2FCF2F02FE
-:1049600022BFC779CFCBF37F5DAF7A7FCD3A89EC99
-:1049700051B39AE3A1A6E14F346F8D23D21BED51C1
-:10498000F3B2740BE2FA941627AA1AB2C61D037C7E
-:1049900054492EB7008FAAD5320BD2D5CD02D1FA09
-:1049A0007A35EBFED0DB54C8E7C3D6AAE128366FD0
-:1049B00046369E671FED48CBAE8CB3FB474DAF38F4
-:1049C000653BFA4D38CF8DF7304B937C5BC84FB9C0
-:1049D0003D3E6ACADB82F73473DD118700FD731F29
-:1049E000CE49C573EE843B6CC1FE13AD1E13D28A53
-:1049F000DB3D0E69C57C33D11F41086FD5EA56C433
-:104A0000F11281E3A67AC7218B17D64BCAE138BBD6
-:104A1000F8D2BBF9785F50931DC9C7F3177095DFC3
-:104A20000FEDF2A24079C2921DA292343486AB25DA
-:104A3000882BF0FF451AAE96EC79E511F4D3258862
-:104A4000A7E15D710975E5617ABEABA594F1F187C7
-:104A50001177FA790F749384F76A168D8675904EE4
-:104A6000CEE1B881FE89BC5F2DA47384452D980FDB
-:104A7000D78A3C4F007FCAC43CA2B64D523BE325C7
-:104A8000AE8BFD85B1FE9E703338879F27550D563E
-:104A90003A8F066B7A89AE7BD989B8B8F8D2A12350
-:104AA00063B0BEDA25B831DE77F1434D6FB5A82784
-:104AB00027ED93F2A25AD48B33A6A74E7FD3705121
-:104AC000CBB81E74BDD49A353DE9FDDAF8C21C8E10
-:104AD000C36AA6E975CF40EEEF9A7FEBE788BEBFC9
-:104AE000402A1FAFE3EBBE1C8EFB31DA3EAB013731
-:104AF000BE42C29762B945ABFBA1EBE2CE16BA3714
-:104B0000D2EDA9CBBD5C5B1FE2B4D22B3566E7A822
-:104B1000892DE8EE9EDAAFE94FB2F3B872B2A1DFA9
-:104B2000FDF5A0BF453B441F290F6BAEB875ADA680
-:104B3000A883F2D2C74437EEABE467E5B7E3BE75AE
-:104B4000DC49DB0573DB48AC337A91FE75F94AFA30
-:104B5000F86FEFC57117467974394F0A61B297BA89
-:104B60005370F33C376AC1FB43DD4F13E5BD2F475C
-:104B7000D0F201618C7033CAE393D1BF199C8324B6
-:104B80008FFDD80A5A4F3DBEC23334B6CE09D56127
-:104B900046BE138CC7011D9727B5FB8893AB5FA159
-:104BA0003C585FE7A1AEEB04EAD3BBAEA3F32FD62C
-:104BB000F875BF684FE5F82F69FA13F1E971167FB0
-:104BC000780FA7EB53D75B9C5F1AF4A3FB97EE4FCC
-:104BD000BA5DFF55BF622B33285F7D5CDB37F94838
-:104BE000EFD8B980F8C4F3CE6A015CDA0DE726E5A8
-:104BF0003593FB7F620974F35CD753E2F3583DE5CC
-:104C0000CE46FD4FB6679A300F604D998773E3F239
-:104C1000B20FF1BE0BE36906E3EF33187865DC7978
-:104C2000AEE76BFA790DBF0D9DB884F1B5E9CA39CD
-:104C3000EC5F3072693EE6119772BCB4EE79D66AC9
-:104C4000190FF3559F8D943AE558BD72EBDFC3A25F
-:104C50000BEF03F7780CF542F585C3E4DF352CB292
-:104C600006EBDBCA75EF968D42BBFF14F271E09B39
-:104C7000DBECA173EFDCD6074660295BB93A8FE81D
-:104C800085DB1EE4F43A9ECF55AE2E7A01EFE33F6A
-:104C90004C524A11DF1D1B0537D65B63B715ADBCFF
-:104CA00007FAC73A06F442B98F6FFDB06C0CD60D07
-:104CB000F522F98BB2F5A959D8AFB4893EDCEA5C8C
-:104CC000E65E790FE2DBEC227F3BA19D138D12C7DC
-:104CD000D91B5A9C38A8C58D831A0E4B1A1BF34D4D
-:104CE000B86E0B9C4FB0FF0A8BDC1AC6BAEFB53E0C
-:104CF000BE2DA82F285333014767059E7F2FB03064
-:104D00001BE2EAA814598EF21F5DEE18D6800288C5
-:104D1000D76E41BF50B43A0BEA265A57D797BEFE1A
-:104D2000512D8EE8F3E8E3DA319FC2F34393F75C49
-:104D3000D34F67619E706E7B5E2A8BD3FB39DC1785
-:104D4000E87B21C4C55DDDD47F7FCCD1EF23427CDD
-:104D50001DEDDEF0A8D4DC1FDFDF421E7F2A3E2FD0
-:104D60003FD39264433C421E6F7C2EF1F304F278F1
-:104D7000C373F09B53C67C5FABEFC40A57A09B384C
-:104D8000A4B78979FEB91C7BFAE914D625CFD7FDE3
-:104D90002E71BC9ED777DEB3BC6F4F781F33CAC568
-:104DA0006EB0FE852018066ABF16F45D907762CA61
-:104DB0003F7747B09E6CB6BAADA0DF53E857F81EF8
-:104DC000F06591E78936E60B032E4EFD61840FFDF9
-:104DD00070DEFBDCEFE6B50A217CC57E78E3E322DA
-:104DE000F23FB859607D84B83AEBE98DB3D0ED2E2F
-:104DF000FB026BFA02FFE5ED824F2509157B427D30
-:104E000075A4AFDC737DF5EFD655FA3D53A2DE33C2
-:104E100073B5FACAC77C46BDF3FA7C3FC0A7787861
-:104E200057BD5F0806A88EFA38B880DAD1AD2D25B7
-:104E3000FD40FE4BC2C927C6A2FF385C744F7221E9
-:104E400058472F013F6E1B716D06E8E755BBCB8DB0
-:104E500071E3E3603D3DEFC48B86CF5BF71C10FB35
-:104E600031E2DF3B16F8F7D95DF85AA39BF76DDC0A
-:104E7000BE9041F1F7A35ABDFDD0D2517DF0B9BE2D
-:104E8000DFF38F723BEBF29FDFFE8013F3D3033F20
-:104E90004CDB3B1AED9BE272238CE66F12596004E7
-:104EA00063A737F13874D6E67A613AE8EDECE63B71
-:104EB0007B633DF8A0D461F1C1BCBED7CA9D787FA9
-:104EC000F63773D4E9C616F8C32887392462FC1B69
-:104ED0003385D17BC0316133933DF48A9E7032FAC1
-:104EE00082391406FA237C3F88E7F6B564FE9E5E9D
-:104EF0007BEFF7E0AFF87D5AE7FD89768F3056DB20
-:104F0000EFC3B9A95C4FDAF39262FEFCCCE6DD3365
-:104F100070BE735B2537CAFBF15689E65F0475BC2A
-:104F200009707816F086F16BD1EF451F42FADC76F6
-:104F30005E272F02DCE27D71CD5249B1B8BAE2B1F1
-:104F400044E7DB2B507DADE37291122A25BD6BF84F
-:104F5000B4C17FD7E1C8E8C55AD7A03E1271FAAFF5
-:104F6000D6FD8B1197DDC583041CE8FAD2F110C37E
-:104F700027235CEA764F6D1D36BE1F0D50295EA8B3
-:104F8000135801E6058D165660461C98927DE8E799
-:104F9000F536E750BC67BA92C4DB474CEED7B15E3A
-:104FA000BE62922501DA13B91EB2C323A26F12D2D8
-:104FB000527A94EE07C4129362C2F3AED14AF12240
-:104FC00031DE3C9ECBE3703F041BB43FCE75532BC8
-:104FD000B13ACA1FF416369885F949794AEA673218
-:104FE000B03CBD75CA4C33ECAF7C6CEAF21CC82CEB
-:104FF000376F9D3113DFEB968F487DD90BF4F3B9F2
-:10500000659CBE39B54802BAA1E18E991381FFD5DE
-:105010005CE5C9DCA2D83AFABCF0FC7BB940BFDE43
-:1050200027B009DB5A8B7D2DC6FB4B42C712931864
-:10503000E37F4760275E1562745462D9984FFF186A
-:10504000DF7915F5DC9EC9555A72BB795EC5D86A01
-:10505000D46395FA9B6398AFC1CF6F03BCDDA1E128
-:10506000ADCA660F232ED85AE942272EBC18975C8A
-:1050700066F4EF199AB9EF30870FE0F841ACC97DBB
-:10508000DA46A9E0E6EB693DC779704C765A9F0F86
-:10509000F6774982FD825D05056C0D2E2580922BE9
-:1050A00020BE097B7FF339CEDBA8B26812D9A1C23A
-:1050B0008D71516001D375686B52000FA0A7652FE9
-:1050C0005F3C8CF05FA8E75399FCFB8CE51A1EEF60
-:1050D0008828DF6F01A1CE04597A2ED8FA223BF836
-:1050E000B119D63D670AFC06F55D6D7A2B7B998C6C
-:1050F0007EDBE8C4FCE5E2CF45DF741857ADE5ED93
-:10510000EC9A18BE0D9EB77B066D591F87A3482EDB
-:10511000CF172E78C2D92B307E7878DDC9AE1DCA64
-:105120005E01FC53BC538BF05C7A9A29FF931BF70A
-:105130007E7186B9FBEF2FDEBC89E73B6C2B3F5FAE
-:10514000AD66A63A52A9654ED0C75490A518680915
-:105150006891DEC787687DE473629E223F90C9DF55
-:10516000D7303FFAA36E47DD3E5DEC0622637E6ECC
-:10517000B23109FD6510DBEC46FFD6ED3749B4537B
-:10518000BC59F632BF8F5B26449BD2907E09CE4B32
-:10519000D497E6975DCFCD6D1634C582CD0F507C88
-:1051A000D2E3920CFF217EFE53F792D7F57373186A
-:1051B0001B86B8FAB27C478F4B601F4B5EC6D7B0D8
-:1051C0000FAA08F63B5F5B7B9258219B512F193643
-:1051D0001FC6E565CFE5D079C79A9E64F17C6C73F4
-:1051E0001AE1738D47243B96B5F563323C5AD826B5
-:1051F0003019CEB9E96D69443BAFF625BAEC277D8D
-:105200002660FEDFF9DEF22703893EF7C29B230307
-:10521000FC7EC586F3FB992E47612BE64397ED2074
-:1052200007D8C16F5F4BF7857ED659C708D705A44D
-:105230000125E84F8AA472BBD81AC8AFB57D2D737B
-:10524000733B2E3BCACFDD65E3F9FB3DB33AC8851E
-:105250007890DA451602FA9B47C5A230B0366A71DB
-:10526000D99A6962729C3D92E46426C7D56F4C5509
-:10527000225827CDD6709252906AE87F5C08482861
-:10528000D76CFB3CC28DC3779361BE4876693BE91E
-:1052900023C0F35B1D4F4CBC6046393F1B27B03425
-:1052A000C0C53767437FDCBCD2B84F260AD41AF397
-:1052B00062D0CBA91BE1696A9E86A7416C10E129E7
-:1052C000413FE01F947F5E86731CD326C82EBE3FED
-:1052D0000EE859ED120BC9946F92FF5C5652E8FE2E
-:1052E0007EB5A6271D77FE81CCA1C0BCAE62A3DE31
-:1052F0007A2946BDA54D31EA29C36FD44B9FD95EAB
-:10530000437FDFC0370CFDFD160C37D05975630C99
-:10531000FC03EA2718688F7ABB813F67ED4C039D39
-:10532000D77C8F817FE0A62A43FFA0D02243FFE0F5
-:10533000EDCB0CF490D6C70CFC37B7AD32F40F0BA5
-:10534000AF37F48F687FD24017459E35F08F3AB65D
-:10535000C5D03F3AFAA2A17FECD95D06FAD68E5F9E
-:105360001BF86FBB7AD0408F676F1AF84B6CEF1A3F
-:10537000E849EEF70CFC93333F34F44F953F32F499
-:105380004F2BF8D44097F9FE61E07FF6A6C0268C3B
-:105390003FB34D1B8EAB0CE3B3FCDD7180E7BBD29A
-:1053A000CDBE30327DCDBA2D94A7E5691A6E3F632C
-:1053B000F6FB4DDE2F8F83AB312FC8405C4F6778F3
-:1053C000DF7BB955205CF7743EBB20DF35C7EDA30A
-:1053D000976283023C46A74D711BE80C7FA681BFF4
-:1053E000CF6CD9D0DF375060E8EFB7C067A0B3EA21
-:1053F0008A0DFC03EA1503ED51A718F873D6FA0DD0
-:10540000745EF36C03FFC04D0143FFA0D00243FF65
-:10541000E0ED75067A486BBD81FFE636D5D03F2CAE
-:10542000BCD6D03FA2BDD94017453619F8471D0B51
-:1054300019FA4747B71BFAC79E6D35D0B776B4192E
-:10544000F86FBB1A36D0E3D951037F89ED1D033DB8
-:10545000C9FD6703FFE4CC9386FEA9F239437FF5CB
-:1054600047003FCC9F5F15E8FDD7B4824F0CFD523B
-:105470003AE4E9783FCD927DA2D0354FD7F3B732E9
-:10548000DFE786751E31D5D17771574C3CAFB3E459
-:105490007B097790BFDB6C1467E1841A42572D0DAE
-:1054A000989FBA54817087A94605DD17A6D37B055E
-:1054B0003A1A65FC0E0DF21B20524D1E0FD60F2915
-:1054C000B13CB4FFF5115F3D0F4DCF67FCBE293FE6
-:1054D00090949F81F5D8CE52AC4F1632750DCA010B
-:1054E000E7AB0BDF33BD9D64BC37D2DBA936D05FA1
-:1054F000DC7A47939AFB0FBF81DF4EB55D20FECE6D
-:1055000079B57B2501F6B72C6EFE27A06E324309D4
-:10551000D91C04FF023F7D32E826FAE96026D1CF8C
-:1055200004656A37050BA87D36E8A3FECDC162A2EB
-:105530009F0F2A44878253A8DD12F4D3F3ADC1D95B
-:1055400044BF100C50BB3DB880DA178375D4BF231D
-:10555000584FF4CF832AB5ADC1B5F47C57B099E864
-:105560003DC14D44FF3218A2B62DB89DDA5F075BEE
-:10557000A97F6FB08DE87DC130D1E1603BD1078359
-:1055800011A20F078F117D2418A5B63D7896DA3742
-:10559000821DD4FF56F02AD117B4FBFEF1F9FC5E50
-:1055A0004ED78B4E333691F0A0E7B533B06E4170D5
-:1055B000144B1F1BEA9684FA21D11EE7B575A40986
-:1055C000706C639E7353FE96C6B87CBF4C5BEFF164
-:1055D00064A62641FC6BC0621EA0D890CA428DF41E
-:1055E0007E95E7DDF3355CB2749E6FCFD3E49AAF5E
-:1055F000F94311E2B380F0F9D6D7A993F43AF95BF5
-:10560000FD03F7113EB34C2ADD13D843F998F78711
-:10561000FA0702F920DFE5BA078FD07A6E5F3E2ED7
-:1056200052660D67DC85F73F4745BA2FED69BD5AD5
-:10563000EDDF2FF4D8BFEF5C7F3C87A67C21D27DC5
-:10564000FADB926336DE8F2CD3F4B22CDF6468076A
-:1056500066F997A29C67F2EA5E7808582A96E6B93E
-:10566000306FBD034B6BF0FB72264BF47D2C535E09
-:10567000C74F26BF09891DD2773195DA9DFD028F6C
-:10568000E17EEE860202E9C0186B7677FB4994A7AB
-:105690004993A74993436F2766F91B71BE53798AD3
-:1056A000419E47B364ED7BF78EE751AEFF7DED93EE
-:1056B000D3424E4CDFFABDC49AF1DAF7534B05FDE5
-:1056C0003D35CF076D4CCF07A9BF6239BF9FB90FDA
-:1056D000EA327C5FF9BE160F2FD749142F2B846452
-:1056E0001FE6D397EB960FC4FD24C6CD0A18678238
-:1056F00071158C7F0F51F17E0AE10BE663F8DEAD88
-:10570000023277ACFFAAB3F47B8FA83D83CBA3E032
-:105710007BD8397BAD2D58A7024EB6104E468BAACA
-:1057200005EAE4B74DA17C41247C580490777E3A89
-:10573000E0A39BBC40C7C112EDDFC7E8CF015F3BD0
-:10574000507F1FFF6A5401BD37D9375A46FD359A3D
-:10575000C01E785FF386C8BF93C02B76FC8EC355FE
-:10576000D842DFF9631281F61AEDA0F721074456FB
-:10577000BFB39BF8F9DB7C5E5FBD9D294D09D1BCB1
-:10578000C6F77C47343B1ED1EC5B76F068D62330FD
-:10579000EF927689EA1D36325AE8EFE6FBA6DAFA8E
-:1057A00037FBE6C6EDA3B6ED24FF2E8A450BE3BF1B
-:1057B00087FA9BB6BE8E27D1E208B4D8E3E5E3F7BB
-:1057C0004580EBB7345C9FC6BC7E865576DD0543CD
-:1057D000A3A09A30B4811FB9E9BB3AFDFBBAB9CC9A
-:1057E0004FED7C8003E2D8AF6EA4FA77116BA5E78A
-:1057F0004B8A1FC846BA96754CCCC4FA656DC3EB8C
-:105800009920DD9DCD1B27E1FDF3CC50E5EBD8962B
-:105810006F154E63DD0D7E711CD78F0A75ABB124F9
-:10582000BD67C7F8D578CF3B43E476606F723B0025
-:105830008E1431B5EBFEC00F4EE178F003925FF7A6
-:10584000838A551C3FFABFC7E8F48BE2C57FED871A
-:10585000EF3ECC1DF45D48ED3E6B2AE26B11569E87
-:10586000627C5EA89FCF3C2F580C7901F29D97B8BF
-:10587000FDCF1F4FA27FF7725E007C0CEF8A7B3D4D
-:10588000CFBC62E2F76E8F88B04511EBE5A7484FB9
-:105890000B6CA1A1A827389FBF401C2EFAB075CD74
-:1058A00030BCEF9B10CAC67C557AD1EA6BF418E283
-:1058B0003CBB9E12BBC77B42E2F76A89F276C95BAA
-:1058C0008A8F7C8EF984D5C2547C9F04FECFFDFE66
-:1058D0000497FF8A2990798BC8F315AAA3FBFBA92B
-:1058E000FE67BD6DBEF542D7F59BB475DBFFC9EB16
-:1058F00069358BD1F7388972086EBE6EA23CD664CA
-:105900002E877EEE749587DB4197277FA087DF5334
-:10591000642BB4EF06532F8A5F97C440DE403C2FC0
-:10592000B5FB31BD8E6DF79CA1B8CEAE35F6E7DF85
-:10593000F7867B3A4F2F74D6CFDED879A7DF33B105
-:1059400071DDDF0BFA6D6E09ED3693F928EE0F620B
-:10595000EFEBFAA17BA6FF0732EFAAC6A039000041
-:1059600000000000000000001F8B08000000000085
-:10597000000B7BC8CEC0F0A31E82C539106C6271CB
-:105980002D0B03C37B56D2F5C17005507F3110E754
-:1059900001712610A700713C104701712810BF0249
-:1059A0009AFD14881F00F16D20BE06C41781F80C03
-:1059B000101F47B277291B03C31A36D2EDFF8DE4BF
-:1059C000E70940761910CF20231C46F1F0C0723C45
-:1059D0000C0C5ABC08FE5E5E5479791E047B99203B
-:1059E00065766D05EA070050DE58A18003000000CF
-:1059F00000000000000000001F8B080000000000F5
-:105A0000000BD57D0D7C54C5B5F8DCBD773FB3BB2D
-:105A1000D97C10120870F3014608B8240141B05E29
-:105A20003E8CD1A206B4482DD505F908494822DAA2
-:105A3000CAABBC66490209883628225AD4054141BE
-:105A4000898D7CD8D406FECB4731F6A98D1615ADCD
-:105A5000B641FB14154844119FB57FDF3967E666F0
-:105A6000F7DE6C08D6DAF75EF8F19BCCBD7367CE33
-:105A70009C39E7CCF99A898D6532CB10C6BEC69F9A
-:105A8000CB18BB59668C8D8994A3EFBCAEACA90032
-:105A90007EFF9BCDBF558DB4D3CB214CA2768CA578
-:105AA000323696B1CB1CF02BB49BF2FC893F5D944F
-:105AB000CCD87E26333B3C0A2B5392AE867EF67FB3
-:105AC000C5FCF8DEF2BC3BBDC38DDF05194B61ECB4
-:105AD0007B8C7F17CE50D37DB95861167CAE39E8E8
-:105AE00077E8276B63157C7FE60B377D6F86432F46
-:105AF000D957161616DF7C9D89FD2A9F75E4887A92
-:105B00000683C19980379DC6D5E13DF4CE0704EFE9
-:105B10000105E055638CEF00F89323F0EF67D7C5DC
-:105B2000B35C0EBF363602FF378587E6DF8FB1FAEA
-:105B30006AF5FBD956C6EEAE66DFCF1ECAD85DD574
-:105B40000EAAAFA8F651BDB63A95EAF50A7C0278DE
-:105B5000A8DFC64241F8DE5B00EDF5FEE0BF3BD7B3
-:105B600061A8DB92E17B47A4AEB8530D7547BA6AD2
-:105B7000A80338475261DE23F823181F7060C7F16D
-:105B80001D4CBB00DF0F25BC3805DE6A3DC36EC867
-:105B900004BC34BC22332419ABAACD42F886BA6DBA
-:105BA0006A08E01BE15E308D79615C6F8031685777
-:105BB000FB2063F7C2F3E1EEC20FF1F913D07F03CC
-:105BC000F42B7B1B8EDAE1FDAA0C9B2A235E762840
-:105BD000EF229E1CF00FF196B391D723F332D687B4
-:105BE00033A8EBF380EF7F9FB0FEA80470D466DB90
-:105BF00054BB1419A77B5DFAE87FD8BA73F73F54FA
-:105C00002D9E8C74AAF73B8C056A7CEEFFBDFD8E41
-:105C100000DC26E545FAD5C7E9B35F58FE62F876A1
-:105C2000D846160A4B3DC719AAFA8B82B8DE1B1557
-:105C300016CAE0CF93811F860A7EA84F9FE10AB85B
-:105C40007BC2C3A2C7C98CACCB50D536C7320ACAF7
-:105C5000EC996512D0075B17F55D262750E4975F36
-:105C600054FB881EEFAECEA1726BB54F433EB9FB1D
-:105C7000EFF2ACE6DC9E7CF8579453F0DD3D5646DF
-:105C80007418DCCE425B25ECAFEAE81CA8AF199D86
-:105C900092B75A25A02D28C774FA5E23A944DF4184
-:105CA000A06F947F66FEB8DB5A7C15D2FBAAD11692
-:105CB000A906F19CCDE97DA835ECC882E76BD665D5
-:105CC0008E0688D91AFFAB1D38EED0A1C388BE87D7
-:105CD0006773FAFFFD98F50E9483DDF35F9AA26572
-:105CE0002731168FEBE38EAC97EF3CE9C037310AD2
-:105CF0005F31E8401FE79FCD0FDF1D7D359E93BECE
-:105D0000D6F8333FB4C3FBADC0E7B2D413AEC42161
-:105D1000E1D4E2DC9EF436341BE80CD7C97F6E3A3E
-:105D200033976BAB43EC3D187C7D752AD1DDBA6AA5
-:105D300095CAD54887202751D6B0F150473AC4F5C7
-:105D40004A2FA07AAFFB155B4EFB51C2D410433EE5
-:105D5000598FF479093E5FA169B045F5CFD1EB2C9D
-:105D60006C01D9BF0EDF0FA0BA865BD85D925E7F53
-:105D700026A8C1F7FD7278BD507A26589B0DFD39D3
-:105D8000F9F745D2292D981EFDFD5D9A3631D21EB8
-:105D9000EAE1C9D9D1FD41FFB9D1F01CA4F67A7F5F
-:105DA000F3A4635A10EAEB9CBC7D8374F45FD2FFCA
-:105DB0006AA93115379A5552375EA89FD57A3DD8D2
-:105DC000A869B9917132963FAD05A3DFB3A70DEF76
-:105DD000C72E6F0C06016F0FB0E22C09D637715633
-:105DE000552AA844CC393BA459D568F838BE23F3CA
-:105DF0005B4FF0BAB2F9FB5CE98F5A6DD4FA4C9262
-:105E00005E0E22FCBA7E63E5A4057A4FFA6D2F027E
-:105E1000BD5BFBDBFCA467A443250DC69B1A642A6B
-:105E2000C06151830CE5815555DE8FE6039DFE0070
-:105E3000CE71046771D5AC5EE00C46C3A9C3D1171F
-:105E4000DC3A1CBDD3291FDF4C4F936F1CF78789A9
-:105E500040E2CE76AB1FF53C54995822FCF2D57D3A
-:105E60009A025DA6DC04B85769DD66B1AC9EFDF60A
-:105E70009F358085A2E6F9CF5ED72CAC8F21BCDDA3
-:105E80002C8D89AC2FD4E744E3719C6867A63F7DD5
-:105E90007E0E9C9F1A3DBF5A4D2988CC8F298DA913
-:105EA000C59EBEE7B7CE593CABD8DDB3DDEF25AE1E
-:105EB000474F9E31EE5AC6C72359928CE3E545C63B
-:105EC0004B9EA98F178A395EBFE2EF169F667ED47C
-:105ED000E17522BC19D1F0F2F5D7E15D6D05BE8DFB
-:105EE000B1FEDF35BCE7CB7F2E90BF2A7C6FC901A6
-:105EF000FECBED9DFFFED9FD25E3AF404F9F2A2C41
-:105F00007C19E0F1F6E98E50508AC8B97F35BE524F
-:105F1000F015ACDFED2FDD72EC320B5680AE47464C
-:105F2000C6AF905482BB37FAEE6D3E8C850CFDFCFB
-:105F30004FCDA737BC7ED772E87CE56BCDEB2E6EDC
-:105F4000DF65B310F27F7DDBE5F10CBEAF7F714AF8
-:105F50007F84C3DE308269F98CDD8F9F805E512F94
-:105F6000F45D767DDE79E919ABAB995607FACB1E65
-:105F70006F15E945F512A3EFD780DE16023DA6E0C6
-:105F8000952D8E396ED4ABEEA5B2DECA488F297836
-:105F9000E5906F0A4CC135347134DA79F54EFDF96C
-:105FA00091A22C787E57363C07D2A8F7F0FEE07914
-:105FB00031B68F1BCA9FF706571CA84D75517877CD
-:105FC000DA428158F2F17B160BE1E75ED4BBECA814
-:105FD000F7AB543A5D8D01243AD7609BBA39A3E7F9
-:105FE00077B32C5CEF5F3BF4D9306E73AB84FE76F5
-:105FF000E0F2C7892F5DD98D9A05BFF773D7C0BD71
-:1060000026FDCA9DABD753A529B067BA4CF5BBF5A1
-:106010007D37A84E427DCD2BF49D4935974EAA8DF4
-:106020007ECF2E9A84FBAEFEFEA69A31F43ED1516D
-:106030007574228C9F08F2B316594751A52AA4976C
-:10604000EB1363D2CBDA2B1DB342F07EEDE5C33206
-:10605000E6C7B0736015699DF57A529191AEEF1560
-:10606000FAEADD427F4D451E8F926B4EDEB45BAE89
-:10607000392FE072CD95A32E47BA4C2A627ED4B355
-:10608000D702FE0251EBE4CC01F9166577242AC64B
-:10609000797D57F37980693FB4F4EBBD7F337F3D61
-:1060A000C00273B07DA2D8A75C397E2990DBF7FCD3
-:1060B000CDF3ED6DDEDF17F884712A628DF3AFC288
-:1060C0004BA21BC629F8E78FE3C271A2FD45E78901
-:1060D00077D84784DF8DC9B80F98ED2A57814F6272
-:1060E00016AAB6A3FD9D84AF00EF1ED658340CF857
-:1060F0003AA978E5AD68AF79DEBEF243360AEA1D0B
-:1061000073A66159979BD73619DAC5FB7DD30B89E6
-:106110004E19E1791576467CB768F924981FE1009D
-:10612000F8EE51CB4D9382B99CBD71BD7F22E682C2
-:106130009AB7A2EFEB99B1E66163618E5FE96B7B81
-:10614000CFEF7B9BBF35F29DF0F72D213F695FDFDD
-:10615000B16936F21B06E11FDAA309A67EE2355BC0
-:10616000C4AFC8104F517578FF42375FDFFA2F195F
-:10617000CFC7EE75A8A807655B7C68A7C7335F0229
-:10618000EA7FAEA9A00880BCF02577052D6ADFEB79
-:106190005207A605ED674077D3A3F4DB3F5BB87EDB
-:1061A0009C3C636AC60AE8F74C01F70327F9B8DF9D
-:1061B000C13C9FBB603F0BDBA3EAB99B897F6B812E
-:1061C0009E32812F82B916F267AFCADEE98BE66B89
-:1061D000264B026F66FA60AA027894057DC8D9162C
-:1061E000CD39EADBD387FC0FD247DCB4A8EFD83730
-:1061F0005F2F8FFCCDE8E3DB8EA7AF6B4FBE5A2E2F
-:10620000D6759E03F59B95A933E263C9D9DED7F510
-:106210005E5A57B067B5508CFE13BBD733D8B34C1A
-:1062200011EB493FB719D64BEE3F76D6A673AD5B5F
-:10623000B2111F7ABFCEA5B2FA57145E8A8FFCE462
-:106240000ED1DF2AF5DE20EA2967706F077CC88D42
-:10625000A3C3B89FB26CE6DFCA9B901EE254B5D0D0
-:106260006AAE2FD3BAE8F0D9D22D86F194649701A3
-:10627000DF6C1668D951F03B97DA080E078E07E3FA
-:10628000C83EE85042FF3F0B3BBDD423F587437D1A
-:106290009D85F53B0D74509F9E1773BF53C4BAA2E2
-:1062A000B9CAE9F5CEF3932FE6F1AE37C27BDEDF54
-:1062B000B915F5FD283F5DEFDF29EC7D1D5F80C43A
-:1062C0001F77D33B5FA79556D622C5833C489DC90F
-:1062D000022AD4F115EC630D588E473ACCF3915E47
-:1062E000B04D52104E626915FFF3FD6E382AB5406D
-:1062F000B7164780F024BB3546EDD5F3DB0FCF5AF8
-:10630000B99E9C2C3143FB65B28DDE2BAC98A1BDB0
-:106310007CF69D2B52A95F0D1E8D8DC061EE77B866
-:106320001C58268F41B2E3F0E007E81F601D39E4F6
-:10633000CF4E13383B3B7F06D913BDC1F7A089BFB1
-:106340001E14F6012B2EE8635E9C8FCFC298EDD809
-:106350005E515D380E3B9E437CA08AF1370733E9DE
-:10636000F9E68673F3F92F110ED04F1FAD7650F971
-:1063700058B58F4AFDFD63C2EED922713B447FFEC2
-:10638000B9CCED845699EF179B1D8D4EF2431F7CBF
-:10639000F0CA61C05F038EC87E27E02F6B913F314A
-:1063A00010435EE865F61A23BF3179F639E15DFAEC
-:1063B000F6A4E987A2F8B149F624BF1F07BF5CCC59
-:1063C0002E46FAEBEBFBB3D5DAF44343BF3D5EB6A2
-:1063D000083BF4F3DA9797939E13BE8CF87380A072
-:1063E0009B01E55C1EA8752CA422FF7EF5358BA6CB
-:1063F0000FD8A92DE84F1F58C2D843D07EF33C8B4D
-:1064000086726BE05A5BC842FCAEAEC67ADA11996E
-:10641000ADA6BAE69E13E58F4F93DF5E0E14CC86D1
-:106420000AFD4CF7ABEBFEFF4141637C62208BF22F
-:10643000CB437F6942BF4B33F9F1BFED7AFCE57F77
-:10644000683D1E53FC2E5FD4F759122B8EB50F9E5C
-:1064500011FB54D6DD5BB83D52E266EF45C52BB665
-:1064600048FE44DC0C1E5DB373BF0DE35125CC3FE9
-:1064700014F09D5EE5B344C3A72871D48F9569E1FC
-:106480000BA0CB15736676EC45B9359119E4580C21
-:10649000F9A128F85D32971F8FAD99C1CBAF647217
-:1064A000EAA4055908E35B53E755EDB7A22828672E
-:1064B000E4EF4D2B094A08CF802AE65755A22BA2BC
-:1064C000AFB4D92CA4F178CD9154A08FC182BA0673
-:1064D000235DE0FEB3D418171A5865A48BB4126379
-:1064E0001CA83FD2057CD7DF442FE67E06A87E8A13
-:1064F000C765042D3C5E34CB18D749635D1F3E81D0
-:10650000F01D72FBC3384E9D715C73FF0A0B5CA0DB
-:10651000801CD9F3F3896002C3AE1C9C9C8478D99B
-:10652000EC288E27B982C1AB187E971EF4AAEB1D0A
-:10653000BDB48FC8D1A0C1BF662E1B86A6DC36179E
-:106540005AADF204188D1FCC20F96E15F1CA8319CB
-:106550003F75A05FA33E398FF213F6631DFD38EA45
-:10656000B0FED172DF8A7EA4A4487D85885799C782
-:106570002B54385DBECFB442C4C3687B3015E9D913
-:10658000AEA6E4231CF654D0BB627C374E71717BFF
-:10659000CFA77C698CABB97DEF8BE029F16172E20A
-:1065A00079E1235F09FC10C70F4E067302E93F91A2
-:1065B000856A717DAB1AF93E17697713D231B40B36
-:1065C00062FCBFBB5D00DA8D34B4BB45F4A719DAB9
-:1065D00015F7685722FA638671B51EE32E16ED484B
-:1065E000AFEB6EE7EFD1DF12312EE983DDEDD41E84
-:1065F000FDDDA1C36768E7EBD16E990E9F615C6614
-:106600001CB7FBFD705BA896F4CB62F2C71EE8577F
-:1066100048F472A85F6111C6C16F7BC1CA65C436F8
-:106620009EE7210BBADA2FDAD5B9395DD556B371A9
-:10663000E5201F1B44BE4AAD7BAE2310F55C5F3FD7
-:1066400078EE8BFD7C8983EC31F15C6970925F138D
-:106650009E933D56F777596C5A3F9B8C71CD0674CB
-:1066600054613D78758D960DFC9EA618EAABD2F963
-:10667000FBAFEBAEAE09A2A34F29A6F808D0E7F70F
-:1066800073A3F8B07BFC7F19FCDC7F1C81FF4735CE
-:106690009A120D3FAFEBF0EB75E720FE5EB6CE9E93
-:1066A0008CF35921F6F5CF946535E44FFE5F3BBF7F
-:1066B00045A6F55964581FBDAECFCF6A2DFD3F36B4
-:1066C000BF3B4CF3BBC334BF3B0CF3B35B974E0EE5
-:1066D000669FFFFCCCED565B8B49DEAEE8F7782A6F
-:1066E000C2B542F8A79D56AD6639C61DFA75EBDBFB
-:1066F00024DF4733ED6F2837FAFA6EA3A2927C7637
-:106700007A2C3C68D3CF161A9AC1E19A0172A1453E
-:10671000F171F92DE03C62AA7799EAF0CB97B86F56
-:10672000FA986E4F9AE47C1FFB5A7D06DF4F1A3CA5
-:106730009A44792E625FB3E9FBDAA099B48FAD4831
-:10674000CD23FB65FFA005248F56A60FEBCFF3F0FA
-:1067500052495ED9C55EF34035CF5BBB5FE407AD00
-:1067600048CFA376F7EBF19250BA61DF3CF0830596
-:106770004519201F4F1FE1F98AABADDC7EA8AF663B
-:106780001ACFC37350B90FFA0D408356D0F7B07CBF
-:106790000EF43D2C5BAA53A97CB65AA572278C8BAC
-:1067A000E5AFAAFD5436558FA352D7171F14FAE24E
-:1067B000F7D22DB47F3E56CDC62BD0FFA66A0795E3
-:1067C0008F56FBC62B40970F57A752795A9A31CE56
-:1067D0004AFED38EDA7858AF3DAF6653BED2C4744A
-:1067E00085FC1E4C09CBF10591E73A5E4F4B932F88
-:1067F000B502DE2F512DBC9D2354EB8DDD6E32F69C
-:106800003F4E55081EE60ECADEE498EDAEC0766334
-:106810009339DCCC17A8F5C4EE6F1A8E9B972CE049
-:106820004B566BDDB1FB9B8EED2E4A15F0A5761D08
-:10683000888BDD6E268E3B3255C097DE3E392EF6B4
-:10684000B83FC2FEFA2736521CE932B477A03F7B2C
-:10685000BABA897C16A2DDE64155CC0274DB3FA9A9
-:10686000B10ADB5D5A55CC32A1CC4C296616A07F0B
-:106870007B32BC077852453F13E6F1F79BF1BD2709
-:10688000EABDF87E7C09BC877A667FE37B7D3C7B32
-:1068900023D3E54998813CB0AF61DD793D584FB1D4
-:1068A000F0FA9DD60393296E69E3ED1FC13AF463B4
-:1068B000AF337E9FE2E2F57BF4F65EFEFDD3A27D70
-:1068C000FF443E6FE78D8E10C6C51EFDF79FA6CD17
-:1068D000CD8DCC77C8CF975E38376A7E8FFE7C35FA
-:1068E000BDD7E733A47A0DBDEF8D5F53675B981674
-:1068F00025B7521A73499F1C6DAF22B9337AC8CCA1
-:10690000F01C58176B31876BDF8A553535D9045722
-:1069100090F205045C0FFFC408D7A09F1AE17AF833
-:10692000A746B806DD716EB8565BB95CEB0D3E1834
-:106930005F8B1E3FB4DC38BE5A631C3F54631C5F40
-:10694000ADFDD6E387A3D7E5917F338E3FF867C6C9
-:10695000F11FF99971FCC1777EBBF1FF59FAB8D7E5
-:106960001AF80FABD0C7E568BDB32A68D03BA15D6C
-:10697000BB681794A3F5D840D0A0C742BBD7443B0F
-:10698000CDD0AEB847BBB7443B661857EB31EE5F8E
-:1069900074F82CD1FDF97BF4F757ABB0172CD1FD6F
-:1069A000A93DFAFB5087CFD0CED7A3DD29D11F3325
-:1069B0008CCB8CE3C24F0EE6F3DCC15C7EF4F72E89
-:1069C0009DDA40F1AFFE2C20A1DFCF97C4461FC255
-:1069D0007D398BE7DD27142E1D82FB784382D1DFC2
-:1069E000D5CFC6F729C52653BFBE38564579878E01
-:1069F00060DAF4A87C8B32D1AEFBBD3B98765DD4D7
-:106A0000FB14F17D83885727AD1C538B72C537105B
-:106A1000DAC7A0B7541BB70BF5F72CD9DFAE01BC12
-:106A20001B7E3C63CC6A163DAE95B71B22C64D8FCC
-:106A30000D5743061FB714C7CDC5E7BA7E114C23C7
-:106A4000BCF978A93F5FEFF9A9F457C04BFD548713
-:106A5000458E87F76BB89F53F7B727D8AA1C98B70E
-:106A60005B3BC8C236AB94877C4E3F4E5DB5D1EFE1
-:106A7000A9F88A35B4F70694F8F264D6FB770F15B7
-:106A8000598A62C51D0AC4BCEA4A263766C3F8ECB7
-:106A900090D17F0B84CDA2F36186CB81025B2CFF6A
-:106AA0006D1DF79FEA7A50C28073FB6F6B857ED1B4
-:106AB0003D0FE828D6FACD12F0B10D1C6F8A8EB7C3
-:106AC000C41964DF25D45CE9F0C5F86E95A97F2769
-:106AD0009BA161BBB8E446662179C2CF4DE87A55E7
-:106AE0009D6F33DF87D280A6300E94BC338CFC734D
-:106AF000A6809FA35052434189EC513E4F542BF145
-:106B0000274E0907D1DF386083C2C220B7D65A02A8
-:106B1000B36C185FC96E24FF98E2D324C4D3596BB9
-:106B2000E84A3A5700EAE266A927BCB7D8B83FF866
-:106B30002175C61F3262AC63894D35C4B7077C61CD
-:106B400063E1FCDEDB47DA71B8BAE93415E8732497
-:106B5000C90DA2D34A592BB7119FA7FBC8EFA8CBE9
-:106B6000579DFF459C7BEE38267ED41BFE04F358D0
-:106B7000D46665C83FEC2B681D15FF5924FC5F7374
-:106B8000855F751E2BF6E2CB93CC52847C7592BD4B
-:106B9000EACD8F5AAF069B8DC3D56025FF961ED7D1
-:106BA0009DDF6835F8BB166E30D617B019292897C7
-:106BB00016ACB3B210E07391C91FB614E70BF02FF7
-:106BC00064552B7DDCAE207D7AAE8F2949B0752CC3
-:106BD000FEF5C363E740FD17887718FF23A017353C
-:106BE0008AAF4ADD211BE647BDB73B7FE60486DF5F
-:106BF00087560E40799AC0629E2FBAA5C1085F5F82
-:106C0000F09BE165ACE69C7028DBA498FEAB877531
-:106C1000FE10EBB5D4E11DC540CE9C75F2B2DB9FF2
-:106C2000F26727C9F7BD4847B4DE5517F1FDA0EA62
-:106C3000622CFBFAEE80A03FF3778B1D1D36E48FAC
-:106C40004AA5AA48B244E24D766B401B08DF595B67
-:106C50002685073243BB86F36CD726659E57BB2239
-:106C6000CB39FA3B25E4E5F33B1EB3A15D76F2C9CF
-:106C700063D7201F96FD56660E68776A878785C999
-:106C80002E09D9509E94EE9663C667290300F056EC
-:106C9000F62B0FC989D29DF6D034F8BEF4D9F74649
-:106CA00031C0C3A99AAEC303711F7D52E271D26095
-:106CB000C728DCB74A157673718CFE3A04DD9DF85F
-:106CC0004D1CE5B548DBF6DF44FD36DF60B547C94E
-:106CD0008737705FE2EDB87F6DBB141A1A437EE808
-:106CE00071AD13DB250E5F8B35E444F8B66DB2054C
-:106CF000008ECA6D9F101D4DF9559317F150D92282
-:106D00001BFCBE95DBE4B07D1495C7B0C478890444
-:106D10007C5DC1B87CACD8BD98FCE115CD777D22F7
-:106D20007BF17B233D035EFC61C4EB1BB27F1AD673
-:106D3000773DE15501551FB56FF5225EA1DF39B6EC
-:106D4000788CEB1AFDD8D8FF17893DFB03CBDD8685
-:106D5000F455D9BC8A8F67E2978FF097B49EF113F0
-:106D6000BBDD934C7AA21E3FD996745E7A6259D3EA
-:106D700099478230DE899D1F3F1204B8CBFFFFA7E1
-:106D80008FDC897ACD3EA70FF9BDF2C9D7BC2C6A3A
-:106D90001FCCB073BE3BB5FD89C71F023E39F5A6B7
-:106DA0009DF2F24EEDFD6030E6D39E7AE6BF52547E
-:106DB000687FFBDECBC99EBF7DCF94FEE7DA0F91E3
-:106DC0004E43F668B842D4BFDA22A1B20586BC2889
-:106DD0004DEB7270B7CC9C00E7C9A3F610E63557AF
-:106DE000C2B3A579B84E8B49FE627D19E0B7624700
-:106DF000FD27F2A858780E0EB4A46209EC928AEB33
-:106E00007CDDB597166069F5AB4817AC8BE4A7F944
-:106E1000BBCA23B09E17F5BE7E67D85736CC3FA9B4
-:106E2000DCB18A8F6B5ABF93F8CBF89EEB7799DD74
-:106E300018FF3AC3CA1F7D085FEE4E8A19D7D5E303
-:106E40005F8BF7FCE09C7A932E07FAC26F89C4E14E
-:106E500072DBB56BEDC84F3B9F7AFCA164BEBED31D
-:106E60000021A79ACE0C66401FC7AD5D37A17CEC10
-:106E7000DA6BF7E17E5EBAF70DE2AF537B5EB1A944
-:106E8000241F995B023DE114EBFE6947BDA142E27C
-:106E900095CA2D9EB0DD1B59A78AD0F422D54BCFC1
-:106EA0008FD1F310A7FB8AD0FEEBA518EBB6D29ECC
-:106EB000C9E571A81FE165F1963FD9288E1DB59EE1
-:106EC000D2385CC76385F8BCB775D4E7EFC3F95F08
-:106ED0001CB59E5B38BFF6C697A736D915CC4BD0EC
-:106EE000D7F794C8BFAD0C496FB018FCAAEF6FDF9D
-:106EF000341EBADC440FFA7CFBE2E7BEE7F1CDF0CA
-:106F0000742B26578EE989AF135FC596EF1B857CDE
-:106F1000A860554503B27AEE4F0A188C033322F06D
-:106F20009EC05800D0D98927653A2FBBB2F920C935
-:106F300069B35CA8E8454F6EB2733BA7A265FF2812
-:106F4000945F270EFC86E8B062C7311BDA4787B72B
-:106F5000EDB275E446E81EE57F741EE689A7F78F5B
-:106F600022398DFDC7589FE744FF95ADC6FE2B77AC
-:106F70007C62E8BF2CD86C23BF681FE37CA4683711
-:106F8000E07C3F6AB732CCBBFFA8592E8AA5DF3C14
-:106F90006AB71AF3613C638FA25F514EB4A928EF20
-:106FA000EA966B6F04715F7CC5CACF3D2ADA51CC7B
-:106FB0000BA84DB0A968AFD6796632354A6E379ABC
-:106FC000F0E94BF64DC2B89A6F6A7141B4FDA4C3A3
-:106FD0009FA0590CF0DFEE29EA8FE79FD00E53F106
-:106FE0009CB1E227BFB2EC2D2CC2F9C83E8BCF1961
-:106FF000737FE6FD59DDC56437597D96EE5C13EC71
-:1070000077F4949923D075A630D5A0E7AF9DCAE355
-:10701000B8FAFCD70E621B19C8DDB552571BE6B390
-:1070200007AFE4F9814CD8E95EB4D3337AEA734C04
-:10703000D354943F247E787BA6459D0FB903C0B1FD
-:10704000601E8FC54FCAFC1DB246793D361C370BFA
-:10705000EDA7103D8F6361AA5B1C5CFE7858153D5F
-:107060008F671D8DD9D0F9DBF6E2B32837EF2D4AB3
-:107070009438DC61CADB4810E358E2D2D3CEC5FFB6
-:107080006CAA7222DAEF63671BC92E41B7E3D749B6
-:10709000113CE879717ABF6B9D1325DC6F707E031C
-:1070A000F15C8F3837EFEB9EAF46F57E7ADD340E1C
-:1070B000B6F48D155B2CB162405264BC2DA091FCDE
-:1070C0001C03583395E9AC9DCA44874F5208BEB79C
-:1070D000C92F6561EFB2AFE34CF09D873E7ED6A22B
-:1070E000BD1980B2D62A9EBFE3096D85FABA04663F
-:1070F000381F9CE9E0F264ACC3A2E72707A2EDAE1B
-:107100005A564E737726F3632CFA773F7004863B0A
-:10711000A2E219B2BB9DE77F09FB57B7D72F97971C
-:10712000F1F87B2AB7AB7B5B9F15D5C506BBDA5C54
-:1071300036F673CCD9C4087EEEA7921CFCFCB2C60E
-:10714000545F34FD61AECDD8E8BC464D23FB5EBC38
-:10715000B7C2F4F0A51DF128F7A4BF62A4BF7E4812
-:107160007F1DA2932EF25354CA81229C6F6A76959A
-:10717000C49F0724EECFD2649C6F8AE8DF12579E2B
-:1071800076AEBC2A360BE8232AAF659DB01F158565
-:1071900029AE3C8467A35877335D1AF354757DCDCF
-:1071A0002D6A76912FF7BB8257E93C8A92ECA6FCB8
-:1071B000147741DDAD789E5C61553E949F6E3DFF36
-:1071C000C4CFF30A75BBD89963CCE7B49BF257AD33
-:1071D000C2FEEE91CF2DF6DD7BF0410C7DD8BCEFE9
-:1071E00056394C7AB4F89E8D8B9D37A8EB61E74BEE
-:1071F000F7663BB2DCD17E9806F769946FA9087FE9
-:10720000C3A4EB7DE407EFDC21F1736B263AEADCE3
-:10721000193F0AE521F22FDE6F11279E4B3BF6EF57
-:1072200047BDA9CECBB484449273AA0C785F298D54
-:107230007648502EDEFDC9CBBF45FF7AABCC706BD4
-:10724000EE84B9B5E3FC142D01172B8EAD31ACEFF4
-:10725000379D4FCFB822E7B7253E9DDFDCF4FDE92F
-:107260001D129D9F92D98807F01C44659B9585E06F
-:10727000FD69C6FB3FBD91EB030B5F805160FD379D
-:1072800088F1715F8ADE3F928A5C4C8DCEE3096A99
-:10729000ED78FE7F9EC047BFE244C3FB8FE716B583
-:1072A000917F26B080F44F3C5716DD5F99BCEC020D
-:1072B0001C8F093F860AFF90FEF4F99FB5046C7C91
-:1072C0009F288E0F933E03F62FDA0D2189F295CC7D
-:1072D000FE8E8A1689F6A745B03FE1BD028B422695
-:1072E000FBD19447A7E3DB4C97071D421F7433770C
-:1072F0002F78F587797C94F86AC90B3C2F6C4993F9
-:1073000014A27CE68E0BE219E15926BFD107AC6AC4
-:107310003DEC1C11FA35E1CD9E6AC4B35335E23918
-:107320002EC788578FDF8847339EE3C7651ADA97E1
-:10733000C9E536223281E71CF88778063948F3A878
-:10734000807984D59EF82C695DBB12FD1B7DE2D14E
-:1073500084BF8F4DF83BC35AF7F3B720525388B51B
-:10736000797EA41226FE31F39B8EA7745FFB247AEC
-:10737000E6F790BF38557422CDE3DF0D703473E625
-:10738000C9F313BFE979C271DDFBE57BEC6B286FB4
-:107390009B7EE818C6D3CDFCB5114BE0EBE66A87BF
-:1073A0006F1E8CF77435F3CDB362BCDA47658C7D04
-:1073B00094FA077AA4FDE01E8C4B26235F2BA1CD07
-:1073C000DCE68A9B86E7FC5AAD3EF45BDE93D7751C
-:1073D0000DEAED95F3799EE38F5D7C5FBDD5C5FD2C
-:1073E000B08A8BE737AF2EB6300DEDFB563924A1AE
-:1073F000BFC8A7BD7019EA5DAD5695F6355FD7CB0E
-:107400003FA2F7F93E8CEFA6591A47231CD09EFCE9
-:10741000ED9DADEF796F89D2774EB5DC7721EE3BEC
-:107420000F5A58492C3D3EDBC9C73F95F36E0A926F
-:10743000E3624717D9D1F51D55C5382FDD8EB0ED64
-:10744000E6FEAD8A96E9A44F1E5AC0CF63EE39C15D
-:10745000CF6316CAB3BF3F12EAE35F53B8DC64DA06
-:10746000B43929D484D6711DE64B221FFCD512AA4B
-:1074700021FC34FE11E354B5FFA950BE6C4115BF89
-:107480001FE4B7DEC2362CC76ACDF9C8D7535B13E9
-:1074900026E17999CAB7795EE59876A33F87C9E571
-:1074A00007D10F76E628DF962F3EAA98ED2E19F722
-:1074B000E3F11DC6E713FAA0DBC94EB11F7959CA23
-:1074C00037C98BBDDBA25DE9E4712C3ACFE5576289
-:1074D000DB4F0FBBB87E057891504E7576317F0D2E
-:1074E000E0A973DE009A6FE767FCDC65E75772512D
-:1074F0002CFBE82627A797076D3C6EFBE002776818
-:1075000039FA4D17940E41BBE8F37F0B0C8915A790
-:1075100088D8072CDE427B9E16CFC6215FD4F1733C
-:1075200066AC312DD6F9799D1F74FED0F9226D819C
-:107530002B10CB7FF9AE93DB6F9317E44836A4D7BB
-:107540007D12C5784ED5005CE7C06390D50C4478B9
-:107550002A5B3E25FF82A335B61FFAE7785803E978
-:10756000B626B87C02E0EBA7C0D441E4075B6346D3
-:10757000ACFE836C1DF99BE663923B7EE7E07634BC
-:10758000531AD36678904FA65CB912E07C08F80FC6
-:1075900049FE41AB9FE00E2E668CFCAB0AE7FFF480
-:1075A0006BD8A6D551F6568373D23A5CEF754E1E52
-:1075B000EF480AF82584DBFFF7B35EECBFF30B3B23
-:1075C000ADDF00E1E7D1BFFB958E1F97760FD14B62
-:1075D000493209437FC0EB9B07FBFF452D80EF2815
-:1075E0007A8CAC5B90BE4B0C80EC2BC0F38C163AC3
-:1075F000BF82F616DA13954CFF0992F2A9F31F1E0B
-:1076000036C3735ABABC955AA5B007E46681C31D48
-:10761000467F4A6209CC1BE351CCC1FB6B37EAA31E
-:10762000287951EEA20CA07D5AD83BBA1CD6E5773A
-:107630005D029783756B15CAA7DCA87438D17F9C4F
-:10764000A1A99331B52A515129CF615009469C41D6
-:107650003E663D9CD0ADF74C60EC99BFCB31FD1B35
-:107660001F74E32BF02CE26B545BD701549FFC4E4C
-:107670009684EB5D28F49BF127B93CD2F3FB2B8574
-:10768000BD619647BF013A478131FE52BEEF8D3F43
-:10769000E9F623FD74CBA10585B48FE6B5E61FC4DA
-:1076A000FC9CBCB7393F32217FC07A23BC8C6D0B68
-:1076B000CA880FB3DCE94BDEE8F2C4BCCEA05C772D
-:1076C000D731752EBF0DF82C6AFF36CBA9374C7217
-:1076D000EA0C9BD8FF7235424F794BFD07ED51F410
-:1076E000A3CBA9083D85886ECDE348CCD15DF76575
-:1076F000A17C7951463F48E7241E9F0C221FA1BF61
-:10770000E2B3D09538FF75AD573891EE77B64D712D
-:10771000205B2D49E5E7BD94FDD70799209FE8B888
-:10772000AE953954770EE2C542F8907D508F9AD7C6
-:10773000E946499C7754E3AF8F713F825E2E49E55D
-:10774000E7B976B665C6733B334CEBDE4DF7C20F37
-:10775000A1F3854EEF66FAD6F9A19671BF84AE3FCC
-:10776000C852B3B00B8D7E815ADDCF1174529CF894
-:1077700076A10FD6BA87DD85D7DBD48527FB302EDF
-:1077800071BB2793F2996FEFC7F166C6835E567E91
-:1077900001FA6154DE79A5D2457EADCA2F6C86E729
-:1077A0003A5E7BC3878ED74B10AFD23F8ED7B36282
-:1077B0007DCDF8FD47E79DBE645CCC7373FF57E653
-:1077C0003D81057EDB4176173FB7A1D3972E2FC6AB
-:1077D000DEB6218D88A3DD78AE479723E35AAA0E43
-:1077E000A28A68961317B5B2EB104FE3C30A1DB116
-:1077F000ED4B6E7C86BFA4D1F98B592E8073F4F3C8
-:10780000B3CA76C0A3512A4B9A06408D6A57488E58
-:10781000B1F6F38B4335873F4B41FFA2AE979ADB1E
-:10782000E97AA9BEBFE871A0D5AEC0421C5F6A016B
-:10783000BE81F9D7FAB8BDDBE00C94E2F33880D909
-:1078400085B97639E10C6E9F1AF9B2373E8C33F167
-:107850005933E085CE21C03E3754EA09873E7E96F3
-:107860002B81C309D486FA4BFA58C607ABE0F7D987
-:10787000A58F6201DC87F1F826CEB3C1C5F7935519
-:10788000420FD3CB0667F17284DFAAB0A03DEF1F91
-:10789000875BF70BAE7669D52E18C751A4D13C068D
-:1078A000FA981FF5FA814AB3E4073812CB55A9DBE1
-:1078B00059A3EFDF78EE679A3A89CE9765333A1786
-:1078C0003B10F5A018EBF34B17F7572F76741CC637
-:1078D0009079E5B4AA22EF39E2D391FB06FCC24FBE
-:1078E00065CCC3E8DCFBC6208C4BBEF3EF9F7A303F
-:1078F000EEF417A5CB83701E5FF6470F9E377867AF
-:1079000019B7336E32E9333B053E7D71C5DB117F1C
-:107910003757FF7DACE1FCF8521E47591492D1E86D
-:10792000ECA6EFB26D71E49BD3EB8B9B930C759D32
-:107930004E17DB799E9479FEC785FDB468C726DBB8
-:107940004015C70FFC16C73F2EF4B5E3BB3DE4CF8F
-:10795000D0E199BB63B40DF1F09756BB88C3B75B18
-:1079600039FEB569183F0B88A530C379785F1CF5DF
-:1079700037FF7E99F48B3930D652A0EF40EB22B21C
-:10798000B3CDF398FF8E5AD81FD66FFE2A89F452D2
-:107990006CBF0CE821B0B49EE26CE679CE099AE3A4
-:1079A00099CBC84E37E779CC63EA5D133362E47B49
-:1079B000B4F238F9C23EEC9A775C425F18CB2EC61F
-:1079C0007CF4332CF717B96ADF76CDF16A46495A51
-:1079D0001F553BA83C51EDA372BB4BE5F1EC96FD66
-:1079E0008789BE94F6B1C8EF3BDBDE8BBB518DC8F7
-:1079F000EDEF6DFAF4E02FA19ECFB8FF46F78FCFE1
-:107A000016F8BE4CC8EF85421FC8FFE2DCF27B3699
-:107A1000CE77544F7875B93D1BEF938DC2832EC737
-:107A2000CDF838DD9615477EC638731CF8DBE1A526
-:107A3000B7EF16CBB1F30675FED92EE879DE96E9DD
-:107A40002B07C0F8B57B3F18CCEF036647503EE8E4
-:107A5000F469A63FC6AA6CC8CFDD74D67A37E14771
-:107A6000A70BE0A354117F4C45BBCF4C6F7DE513B2
-:107A70009DB2760C463960A6AF53128B79AF68621F
-:107A80001CF797CF53B542B443617B59C9E3745C8B
-:107A9000FE1C571A0FDF89FCB985F3C7E25F373D3B
-:107AA0008B72A7F457F77B51EE7CA834A6E078E5FB
-:107AB0005B577831CE7D5C097AF1FB0F4372CCBC09
-:107AC000C2057192906BC67C05D610BC06F9F6F320
-:107AD000AD561FFA192AB7D9791C7C37C71BD47940
-:107AE000FC7B77EC7C85D227EE4F51797EAA316FF3
-:107AF000618B95F24FD05F86C3F416C7ED8E0B37BE
-:107B00009F3BBE5DB9FBAE9879277A7E80996E6700
-:107B10009AE815F042764C10E021B7B8885BD76E32
-:107B20007F60D43180EBC496FFF04AB9D17E731EDA
-:107B30001F3FDD7CCBA318E2E98D5E4F09FA8EE88A
-:107B40000DA198790CE5D6B017EDF0F24D56B2EBD9
-:107B5000CA9B64E6C07C9637EDB46F9735FDEEF5B1
-:107B60004B00BEB267ACC9D3F834285F415FA7EEC3
-:107B70003C12B12EA5BB7EC7E3BDAAC82711EB53AB
-:107B8000F6CC7E1BE6C598F138A579BFADC3948FBE
-:107B900040EBD47CAC90CEE56D3F6BC3FDF4C37D70
-:107BA00012EB9FD1F3FB924DBFF3A27C403C515CA2
-:107BB0005EAC57EFF942E16B9E2BA076E487EB6D4C
-:107BC000FD2EC6351A43F4FDF473307EC95B76CAC8
-:107BD000572A79FA36CAEFF940A9E274FEF08A14FE
-:107BE000DC5F4BACC1141F95FC79C9233F21FA5BC4
-:107BF000F8CA4F52F8791E2D8DFB6D8269E4CFD8FB
-:107C0000F8039ADF021620FA2B79582E467FC919FD
-:107C100085153D13834FFE2CF8E483CD760CA2B27C
-:107C20000F84DF32F8AA2CEEFD35C793F8BD2B6721
-:107C3000841DBD2BCEA2E7693BA2EDAACA2DF5EDAE
-:107C4000B83E1F0DD2FAFB28AEAF0405BE24D2C742
-:107C50005FB9BCBF9063745F8CAEE74CC1E7D8BE20
-:107C6000DD4AF7C6447D67B8F7E576313EC0ED9250
-:107C70002E823225B63FD3ED9674F878FE8B4E5F98
-:107C8000BDF1FD169E4FF2D9112E57302F86DEB76B
-:107C90005BC3FD0DF93076C3BD22917C0FABE06B69
-:107CA000E37B8093F255BAF1BB4FA238EB82757635
-:107CB000631E5C37DD98EFBB31E6AF2C34E95B7AAD
-:107CC00069960B6FC699E2681BCF2F7FA5DC1AA2BD
-:107CD000BCA3F237ED643F9437598B111F1FEF3867
-:107CE000F8FA8D40E71F37EB7C6B94AF66BE2DD959
-:107CF0003986C5E2DB8FDD7E16936FE1794CBE7568
-:107D000047E2112AFBEEE4EBC25EE4ABC5DD431FA4
-:107D100088C7BCDC8F9E2C1B427E06135E75B96A39
-:107D200096971BE3D45EF2EAF87E1EC977E4F8D397
-:107D3000E9B1F4A9C5344E37DDEA74A9D36D2F79C2
-:107D40005A663C9ADFB7097964F6670427B31CBC0E
-:107D50005FAFD6C672D0FF1CB4B8FC5B3362E4756B
-:107D6000B0AA0B50CFA87167C4CCCFF5BB7D68C655
-:107D7000326BB22AC78A77FBA75862EAF1F96E71B3
-:107D80003F09D202EA936E8EB73A115F014B90F22F
-:107D9000FEE98C36C297E0257EB2C27346E72AFD23
-:107DA000746EDB1F67F9540515ECDA35430A15F4D8
-:107DB000A7E65B6ECB82FA823579850AACB37F8207
-:107DC000655726D44BD6E4F3FA45967C2B90E6E330
-:107DD000C182C2A9D0BE429FE7BC78837F43B11C59
-:107DE0005B8F7117E5392BAB85FA5DC0D78EBC4828
-:107DF000BC37CECE824EA8C7D9A084FACA8C3FAE7B
-:107E00004423F03E7BE06A37C9A3C92AE2F584CF58
-:107E100041F932B7FFE672CACF2C7373BFF1885DA8
-:107E200013E8FEDDEF60FC1FBBC7F43E7E9D95F7B7
-:107E30007362E7882988D71143F8555F3AFEF31437
-:107E4000959E3B9BF1E829F17F2A9EFFA84DB051FA
-:107E50003F65DDEB757E65ADC86B90E3381DC8F1FD
-:107E600096AA67A05C22D6FF36810FFC417BB973CE
-:107E70006FFFCDFCDEA7AEC1B8BEB27CFACFA8378B
-:107E800076FD38CE8FE757DE72717CDD10BFC63AC3
-:107E90001CEA798EC1B72151BF25EDF80996D77834
-:107EA00002FFCEF1CFC2D8DF8D37C9BC3F7795072F
-:107EB000EF519334AE474B4034B3010FB51A536DB5
-:107EC00059C8A2C67C0B59CEEB0AD3B81EC3B82C36
-:107ED0001DF64158A71BC6F375029CD2BEF8C638E2
-:107EE0005E9F15CAACED50098EBB118ED1F6D02025
-:107EF000B47F6E04B588D3B5D1FED6E3F495FF699F
-:107F0000213BB352526BDD50DFF53623B97CCAE515
-:107F100015F907FC7E19DD2F31FEA5B95370C90A8A
-:107F20005ACA781E87F043E971F433AC55C6C9F4D8
-:107F3000F0539BE4E104B686E4645FF1B1C7DD620F
-:107F40009F19C0067CC3F85893FB3CE263E96E5D61
-:107F50009F17F176B1FF9F7E3193F285140573F27E
-:107F600018B3A932A588E8DFED36C95F9D8E471E9C
-:107F7000F1DD8278197984DDCCEDA55EF2238E33B4
-:107F8000CA6B1EDD9143F91156737EC4510B253C1B
-:107F90008D7D215F457CD689B8F1378DDBEB71FF94
-:107FA0007CFEA8471CFF396F11C541F37DB1E3F892
-:107FB00097C8B329EEC05EE4EBA7C7F1999C2B23C9
-:107FC0009C67C28C25219C478CF7C55C9C1C94291E
-:107FD000ADE66DE3F34BCCE7594CEBFD57F37A9FDD
-:107FE0006F1EC487FC7EB5D16C14E54158451EC494
-:107FF000B32C705F741E848EC7BEF24CCC7925E61C
-:108000003C92B480114F034B861BDE0FAACA33D4B7
-:10801000872CBDC4D03E0336C2E87A56C35586F6D7
-:10802000431B6718EA176CB8D1D0FEC2D05CC3FB03
-:1080300011DB4ACFB9EE239B9718DECB96503EDE7C
-:108040000BA9AFFB452D3F8B4917FABAEB795A982C
-:108050006E84F81D03EBFE5006F98FA6486ACFF533
-:10806000F78783B42F7FD3F5CFF6087DE81BF2BBEB
-:108070001F898DF25AB99ED8697537A05E9C00B0F1
-:10808000A1BC35EB1709ADCFFF17FEDD899EF916B0
-:10809000EA72A4A33B646D3CEEF7FD447E649D450B
-:1080A0009C279DEC207DE01E8BE5E6E87B922FF57A
-:1080B000707BE0520FDF5F7E09FB26EE9303E358EF
-:1080C00090F64F0B8BDC6701F3F52631716FF1A64B
-:1080D0009553D3319ED991A326007F637D5044EE02
-:1080E000DF68576B311E305AE6721CE4FB959E7EAA
-:1080F000B8EF2CB372FD2768453C0F74B0A0378FE2
-:10810000F63D8A6B26B06469492E9A5EDDFB8BFAD8
-:108110003510C3C1D211F16807BD8C906090D6E1D3
-:10812000A2FDFF87BADC2BB990E4DE69B79E37A6C3
-:10813000D279C7D3F3B2E8F99B3701D701FFBC6905
-:1081400033DA457DF9A74A36DDE741FFFF9B39CC9D
-:1081500090675026F056861762E2B993D07FA6202A
-:108160005A3AE7FF6D18025D29B5AF44115DBFE1D2
-:10817000D662CADBDD3D3D88FE3FDDEFACF753D96B
-:108180003A8975DF230CFDDDF006F77FDDF037A3BC
-:108190003FF7671E7EEEE86762BC9950F8006F33C8
-:1081A000613D12B07C7E6221F2033C0F4B50BFB6A2
-:1081B0000D543FA0FBE9810C2BC2F347E67F6D0F06
-:1081C000C0B3C2A3D238D7B3622BC2F5FA4D8B3DF0
-:1081D000D8AEBB3FBD9F8178A613F6E984A03505D4
-:1081E000E8A7EB5289F67518CF81CF8B670F5C81BA
-:1081F0005B873EDEEB2C70F23558EF19CC4FFDEA71
-:10820000FD33E632C8C19D25657F49CA44F967211F
-:10821000FFC792BD76927F9DA5679BD6C3FB9B0748
-:10822000760C42FDE2ADD2BF0D43BCFC7083CC5452
-:1082300058FF475D81B59E28BCBD39EF530FBE077F
-:108240003D61EB7ADCE49FB2D339AFB74A9F1A168F
-:10825000AD57FFD233693DD21D1B777EF19E294F6A
-:108260005E48F6B64E5F8B047D2DD97E01E9834BC7
-:108270003CDDF4C5EB5BB3E83CD15889C5B423F1D0
-:10828000DE0FCC4BDF097485E708F77DC1F3C777B4
-:10829000BD98984FE751596047F4BC76BD7CE30820
-:1082A000F2B71E4D3E2F78912783A85F310EE74B22
-:1082B000823F66B526E50BFDAE05FBBFF1B7DB4F90
-:1082C000FE09F1B3F7A9AD77629B82F3C30713FBF5
-:1082D000985FE001F631B27F3A99CB6F8F61FF3C36
-:1082E00023F4AF3B2C1AD925672DC5227F9DDB21B6
-:1082F000B2C59F8A79DCCDAD721CE2CD8B068B2E88
-:108300005F4027F4E23D8CE2FE7C07D8672384FCC3
-:10831000F9C3DD9F16D671FF8E41AF2B38546AD05A
-:10832000E78AE11FCAFB8B37066AF14EEE5EF5BAAB
-:10833000B085ECE17F54BF7BF71F94F7273D9CFF8E
-:108340009B73B8FC6E0EBB42DC6E60F9A8EF35790A
-:10835000F97E7025E68900FE6DD2A91C07FCFEC9D6
-:10836000DD6756364C84E5CEE6F8C03AFDFD95361D
-:108370004EA7DDFADFA1E1FCEFCB8973C005E25C1B
-:10838000B4199E02E02BBEC9BA0CFA63F8F09774D8
-:10839000CEA52951FDC304D4E7414F41BE772A1D24
-:1083A000B68418F37B16E527D0F7382FDF3F1C2D56
-:1083B0003C0EE75035BAF7CCE9F38D467B496FFFA9
-:1083C000B187EBAD8B0FBF35D806EB74D2F2A21795
-:1083D000E308E57B767AD14C1E1517F07A51AEBED4
-:1083E000F9EA581FE55B6D1A8C766D7398C72746BE
-:1083F0002A2CA8C4B8B7B972433E5DFE5DB121898D
-:10840000CA0BD19F008F2AC37C9EA75A6A63DEDB0A
-:1084100059F9FFF60EC0757BAA1F3F2F35B2357F85
-:1084200021CA3F84C50A72EEC92F46507F43BDDC86
-:108430009E87F1157CCE58C882F71D3D25ECB553BB
-:108440005FC8D44EEF7764CB24D9076B991B6E3C81
-:1084500040F661AB5DC575766EE1F7C1395B9D2471
-:10846000F72AF75DC1EDB8041EF76C7275FD599CD3
-:108470006353314FD2E96B6489D07F938DEF8F17AF
-:108480000203EC74479EEBE3395B1FA0A4764736EA
-:10849000BF57CFA934B24BDDD178F710FC8582BE2F
-:1084A0009A5C610BE6ED74E15D950457044E46E37A
-:1084B000EA705E48FA7C93ADEB7D3C7F49E7EB5474
-:1084C0008483C3C95A2F5051AF70FA78FCD6E95350
-:1084D000FD41A9275C95A340CF057EBBA78645FE3D
-:1084E0003E06E6B1B9227507F044532613F761E55D
-:1084F000D4A37ED15D4781342EF2FD8FBC23EAEBFD
-:1085000026929D1394D1AE87D29388F3E4FC85F72D
-:1085100017F4CBE378403F719C83BFEF6E0FF4EE0E
-:108520004EA47B8DA99D3FDE177795C4BAEF35D554
-:10853000FD4EB74BE1F72F43FF56F8C028156029D1
-:108540007FFE39A2DB324BEBFA912A9E4B0CCCF723
-:10855000C278BF7EDB827F53917DB4DD49E79073A3
-:108560007EB389FCD5E6FEEA8FD6DC8B79D99DBF38
-:108570009154CC03EDB47651DCA8A2F5033AAF7860
-:1085800045CB313AB765890F5462BFE35A964F41E4
-:10859000FC8D678DB5E8DF03794871FAE6542E3F0C
-:1085A0004E1F19B6797914BEEFF70ABBB02B300411
-:1085B000F9A655F0E73ED46FA0DC23F4AC3DFB7F79
-:1085C00098157D0E2BC80E903FAC861DA2FC42FD77
-:1085D000796748A17360235E77DCAC45D1DB2F045B
-:1085E000BFFFC2CBF5A0ECF8C00A84B76CFFBB3666
-:1085F000AF8A79ACCD8351EE36831E76AE7CC64A07
-:1086000013DF74E7B71CE7F772C3BAD6C5C33A3DA8
-:10861000F57ACB70FCBB22003FA3FBAADEB493DC4F
-:10862000DC93C1F96FF96B9F8F42B9F5F9DEB22186
-:1086300088AF3BBC3CEE0F743ED985FCF40C23396B
-:10864000A6F3632EF223809EEBE37E945CA473E496
-:108650003F5B3BDD03DAB587DF0B01744E740F74AB
-:10866000EE43FD22D707744FDF5F40FCDCD46EE1A0
-:10867000E7C0418E0FA5FA64CA57696A9FEA237E54
-:10868000B6006AF3902FC307A89F667EE76D81E965
-:108690003ED78F3149634C443EFE9787CBFFE61CA3
-:1086A000351E6D84385936F041D43EC9EB621F95B2
-:1086B000E26FAC5F878946ED625F107AD73EA1E733
-:1086C000B2A35CDEDF26F6B225BFBBE4DA1D30DFE5
-:1086D000252FC95CFE0B3A3920F4E043D5A954C7D5
-:1086E000FD4285751A0325DE773756AB9A82DBCFBC
-:1086F000B8A2C683585E52DC3C058F4C4D9CD57E9B
-:10870000909F61D34620FDED3E70E508CADF7DD322
-:10871000CE304571F7975D7F7E12F351F701FE630E
-:10872000EC4BE89F6514BF29267AEC8D6E3AA58E36
-:108730006B26F8613ADEF22B14D8E82B9030001F3C
-:10874000AF794BEB8300D00FE3B5A3488F77FA02E4
-:108750005476BEF2650ACAF43D47DEF5A2BCDF6D71
-:10876000D346209DEDCE047B20067DFE4ED04F41AA
-:108770002F79155F7A797EFAB020BB0BE9A762B733
-:108780004C7FBFE0E46E59C373D8EF6B8114D47390
-:108790008EB3E0CC09B8BF0BBB763E473B9B8F7ACC
-:1087A000CB28BA2FC3606732799985EE7B6F95C865
-:1087B0003F5162D243CA59E3CA81B86FB46EB2E185
-:1087C0003C4AB718BF2F47FD651496E7B657BFF46C
-:1087D0000AFD258B65A1FE02F443FE89AED764FF36
-:1087E0006646F93D6D98DFF39485E307E425F1A132
-:1087F000AEC73CE1D34EA05E7DC223F613618F76F7
-:10880000354994DF7FE1369E777DC9717513E3F3B7
-:10881000A7BCB01221072F5178FCE2922359140F04
-:108820001DA731F2872C68954288C7125DAF13E708
-:108830002960DB25BD6E3C0BD5E2FD720BB7497498
-:108840000EA36C9BD17F5FBEE195C3681E2E6E3672
-:108850009D8F177831C73776E22F31E21B83E3858E
-:108860003F67301B6C386FD5767EE7AD3E16E7AFBD
-:108870005F15FDEBED26C473BAA910F32D0FC921C6
-:10888000F1F729DD987F7B8BA08F5B047D54B2B01C
-:108890000DF3F717AFE3F3656BAC867B8B17ECBE7C
-:1088A00095CE2398E9A864078FBB010229BE53B275
-:1088B000D1F8BE54E0A3D4848F8A8064828BEBDB32
-:1088C0003DE16A9E89EBBB788795FE4E8719AE33F2
-:1088D0006C36E511FDB3E133AFD375FA3A0D67C3DA
-:1088E0000DEB5474EEFB0922F68D51FF7DE6F0701E
-:1088F000CA7739DD9649FE039D3ECCFD140AFDF989
-:108900008A0D5CCF3CD932256E24DA452F2A7E09A8
-:10891000FAC97FE9332F9EF7C8DB2B338C0B76B671
-:10892000E6DF85E7B477B5655F87F751E4BDA4D08E
-:10893000BE91FF521EDD0B92F7525E5C16E551A808
-:1089400049880FE887F6DDCE17B3FF988BF2B36D39
-:108950006A01A279F98B7971A81FEC62DC1F21BD35
-:108960005490D411B58F94C773FFC0CAD4F7EE41A9
-:10897000FDFD8A67F8DF1FBCC2DAF532E61FEC6A3C
-:1089800053FCCBA15EFED2DC1ABCA7A27CBBE447A1
-:1089900035FB70FB92E41F219DB55A7D7682F72747
-:1089A00007F07D708744F78557EEBD7C4413E67968
-:1089B0006FCAF7479FCBCE4B50EFC3BC4A961647C2
-:1089C000F6F71583ACB49F9E1810F718DDC7A26D9B
-:1089D0002A44397BE2B95D363A37D824B15498C875
-:1089E000E1D4834FD3FD1ECFBE42F90A5376BF4276
-:1089F000F909BDC9FB93219985C9EE6EA47B611667
-:108A00006FD2EB1D740EA258E84D155B8E51BD144C
-:108A1000F57F18AF74A31C52E1D7837B7F4DF90D0E
-:108A2000153B787E03BC27F9538AF1533542E7732F
-:108A300019A783B942FE94317ECF5059233F47A7EF
-:108A4000DF8BA4D3F9FC1D73280FAD47BE19DA974D
-:108A500014876824FAEE79DF10A7EF1EF72499E84F
-:108A6000FB573A7D5FC82E44FAFE7C12CF0FFBFC09
-:108A700015575C2ECCE7F31764CABB3F079DD37E26
-:108A8000FAA2D8FF4F872DB43FE9ED4EB57C4AFBE3
-:108A900048E58BA76DA8AF16B67E42EB30AD75FFEB
-:108AA00054C4F3D52C508E78BBBA35CE877C3EADFE
-:108AB00083CBADAB5AED21F4535FCD9AEB707D3B88
-:108AC000F73D519788F4F238A7175D9E2D14F85C96
-:108AD00028F0B950E1F73D95E6EE5F8F6ACA558CF4
-:108AE000CB9BAB9A85BCD968C46FA7B55921BA197D
-:108AF00029B1C68C9EFB5D19EBA0738F9D6923E89D
-:108B0000EF4906C15E453DAC7C87390ECEEDFA0AD1
-:108B1000D37E7A205EDC67F00DEFC178D7B42ED318
-:108B2000BAF87E7615D013C643DAC235B928F77481
-:108B3000FC98D7A54DCD8A3FD779E79785DEAED78C
-:108B4000AF15F74C34FB1ADDD176F8153EBE9F9475
-:108B50008E9783B8AEDDF64AF6C151AA2562AF8082
-:108B60009DF2657C3F6EB78C86AE9F4F97597272AF
-:108B7000C45EA94FBD6F5A5E32DE1FC1E5C5A97143
-:108B8000D01FE60B288CE454E50E7B08ED0C3C77F7
-:108B90008476C07F03EEF3D8290080000000000037
-:108BA0001F8B080000000000000B8D577F6C14D74E
-:108BB000119E77BBF7C33EFBBC87CD116AE2AECFF7
-:108BC000BF3018B3312636A449D62E6928B8CE193D
-:108BD0001A429BB45C4814D284B351845C242AB1F9
-:108BE000B6898A42AA466AFF88AA28DA448A94A8E3
-:108BF000343A84514C655BE7C424B6532408D0183A
-:108C0000D4B427FEA069656383149C5691E8376F3E
-:108C1000F7B833366ACE92E7DE7BF3E6CD7CF3CD50
-:108C2000BC778F0E5EF7A5EB886283E21182AC2CD5
-:108C30008AFBB4A5441D44DE9246C80161A40872B3
-:108C4000D3755FBC8068BCB2A2280EBD1BAABE4C07
-:108C5000C3F8167F1ECECAAEAF15A262A24E48BDA3
-:108C6000383BDFA9A67DACDF39284C1BB2FFC3FF20
-:108C700094951712CD0CCD953D0DD9A8798896F213
-:108C8000FC0F57AB3877F6929FA2E538D8322FD039
-:108C9000FD44CF91F3D9A3111D5882F1E80B6D5417
-:108CA0008F0971B8949A61D74B460AFB3A2F2A86EE
-:108CB000A563FE9497A889A8E7B33F8F2E2921BA10
-:108CC000F6BE30FCBAB3FF570D18EFB60F2F81FE7A
-:108CD000CDF7846141FDB97B881EC2FC9ED7BD578C
-:108CE000D201E7AC5BF27FF2CA41E8258E05F4576A
-:108CF00030EAA1DE52826E2F1D963241AF5E57429E
-:108D0000B037D0E7635CC8CED91F257AF1DDF9F61C
-:108D100012A466C788EFC0DF5A3A4673D61FD50A39
-:108D20004BAE06F1A5966A6F29EC7FFE5181F36781
-:108D3000C615CD2F246E6F7E27179F3180B19CE71B
-:108D4000F34C429C33E70AEC3CE8FDFB10D66A8802
-:108D5000A60EC1B81F769A158987678323570F7FA0
-:108D600010E57C32FEF135447F1CFE6095C9FE9310
-:108D70004DB49EFD86DECA1CBF93702AC74FF865AE
-:108D8000A4705ED75F1503E6D9AF6A5F49D6AF938B
-:108D90006A3A64E4F063EE90D9315A8574890F65BC
-:108DA000BE3C6254CADBBC39A5C4ECBAEC18F1EC89
-:108DB00032B1FF27CC0BF843EA6C24063F7FA6E9CB
-:108DC00092273D834E7E3D438EC4F93B8871C19806
-:108DD000CF5FB0DE6AEDE5F59BE541B218B7AFAD08
-:108DE000361E7747157A05E3EECF5EA8A19CF3897E
-:108DF000FD447EBBBCB311E66DD7398FF4AFEBDC1D
-:108E00008D4825C65BE8AD4D1AC65B297998D73FDA
-:108E10008E069F675E5B7CEEB2AC9D2F8B14C77F86
-:108E20008E17F62CFABD63D78DB797B6491C7A5DBD
-:108E30005EED2E72E23DA8C5BBB90E67CEFD37824E
-:108E4000B0E9E4852B21CE5726DF77D6DD6DBF71E3
-:108E500002E373B3453FFF2478D030AE5A4588F320
-:108E6000C4649EDDC6B80CEDF9C741CEDB653F7129
-:108E70003D740FEFA921B61B8FAF8DA10E6F0EFFB2
-:108E8000622DE340A257FA65B17FF06B7AE062444D
-:108E9000C77C62E86284D71327D7FFCE82FEBA333D
-:108EA0000D5B79FEC4982AF9D770A651F2EFC45F22
-:108EB0001A8B2BD87132826C3731AEC6189FC478AA
-:108EC000E3A76DD04B9C696D147CCC99C662EE3FD4
-:108ED000EB04C5925817E395729C89E7379A22E311
-:108EE0009919011F302F28EAF0872AE7F1676FFFF1
-:108EF000691FC7B1774031737994D9F796A64A3B79
-:108F0000EF307F806F4F5298921FC71DB977E08472
-:108F10008CEF456F52E6BBE798D759FF9323895EE4
-:108F200093FB2C5A62311E9FF214F2B0C567AF203A
-:108F3000B838514E3B938BF4C3AAB090FB262EC594
-:108F4000BFCB7C996889D768750BF52C6A95F19031
-:108F500070F1EEF76EB617B157E1DA0B15D3AED854
-:108F600022EB5AD8E1CF161FC517F3E78B4C3D1102
-:108F70001DF58017E7DBBC1AF39FC82C588E3EDB2B
-:108F8000EEF6D9ED3FF29ABEB55827ED741ED6DB4A
-:108F900033FDB619FD0C7D21863FEE6FB1D76345D9
-:108FA0002940DA61CEEF73DB28E6A50AD8D93C7FE9
-:108FB000FE71EE97F52C5569E76E7DF022F7C1D56D
-:108FC000F8524DD5DC074929080AF0E6AB31AFA6C7
-:108FD000487FED4AEE0777C697E9331FA3FFE9E81C
-:108FE0007F63E87F2C7B6A3FAF4F038F89914BEF04
-:108FF0008765FFCCA32813F01B5847DC09CD3DFB48
-:109000000E7B3DB7EBF3C7F3F896C9CF34D1E664D6
-:10901000DDC2FC5C77EFB34460CA07B25217ED3B88
-:10902000E2411CAB14877F7E6FDC2C451CDE8196F1
-:109030005429F7D35A7451C437FD88B0B9CFC3CF80
-:10904000327F4E9F9F5E2EE47AF70E615BF83A52B4
-:10905000FBB9BCB713A9B33EE65375FFD32FCBBA08
-:10906000B5E80245B2797C2CE0DC97B7F397899795
-:1090700017758E0F7C96FDB8444AD6E7FBB1DDBD6F
-:109080000F1F6B9E9FBF1A3AFB8352F8F184290C85
-:109090007BB1BCEFBCEFF452FAF6795F158E1787FF
-:1090A00081C7CCD91B3BD6C0DE44ED3FCBF81EEDCB
-:1090B000BC0B7FEF0D3BB8760543F55484EE52A30D
-:1090C000F7A581C7F1C2F80A69C7F34D6815F1FE2B
-:1090D000F49B2F09CE0749FDBBD54B855B2F15614E
-:1090E000CDA98B125AC7BC7A4F73C6135E7B05F7A6
-:1090F00003AAC36366C3FFEFBB3DA73EA9E7BC5C01
-:109100001B19AFF7E5E46FEA25D43DDF23431F4584
-:10911000F4825C7E795C7EA9520AB1CDBD1FE7F373
-:109120006D8AF9C6F93EFE51FB93CC93FEED2542C4
-:10913000CFB93F4F9E0F55E5D89D1E54A43EA9E9D7
-:10914000EAC70B73FD7C59FA399D74EC11A5ABB7D6
-:10915000AFC95DEF73799B96BCFDF5CA7D31AEE377
-:109160000C6F557278DB39D041F23E72E34EFAF063
-:10917000057E59C37EFB1DACCF7867CBC23975F134
-:10918000AC8B73534A483E6E204B61BB4DB0F81414
-:109190008F554AA9900F504ACE13AD20E6F1FD2E0F
-:1091A0008F9BD4D488A8977A960A5E6EA4B352EFA8
-:1091B000219A95D2243478C85632A46C0EA4B67283
-:1091C000FBA84B2615E6532AA286AF828FDC4A16EF
-:1091D000CB5F367E95AE66F809653C6E76C516E9BE
-:1091E000D7BF75EBDCE0B71AE7799AECB731F52019
-:1091F000A5153EE40195362B88E7419502F9F0F775
-:10920000F8A847D6EF705AB7B97F19C5EEBE7F618F
-:109210001FC64DA653A77CD53CD5908DF74E1C3666
-:10922000C25E11EBA974C42B714CC9F31E66C71141
-:10923000770BE92A8F7BC3E56E9F9FFD399FF3FD76
-:1092400041BF7CE7780296C4E3485897790B02CF78
-:1092500010EC6C7C4DD024CE352A9C7833F637E266
-:10926000D557D4C0FA42EA634C93980F069C7D44CC
-:109270009B34C64BA4229E5BC16F8FEB4C84A4DF52
-:10928000A16766AF1D94EF36BFF6365C32063F9994
-:1092900014784F0BD3A403EC4FA020C5EF6BB06341
-:1092A0002AF75DFD4678F71FC2F047E89AC48BE2C3
-:1092B000A4F33B6319BDA1F1BDE161BD6207BE2FFF
-:1092C00081DF136EBFBB9CEFF48D77ED6DBA07F9AC
-:1092D000D8591230381F0D81B27504BBED85716904
-:1092E000F7B23856258DA8F67AB69BE17990CC6610
-:1092F000C659B8F93A1070ECCDE539926B92F91C69
-:10930000443B0FC0AFA3A88B00C656AB936FEBEFE7
-:1093100079761FCE9BF3C424197FA91801C9F76879
-:109320007CB209526D35F57D05FC64471CC16C1C8F
-:109330007D7C0EEE637A160F449061BFE6C4D3576E
-:10934000E059C9BF97FA28DFC0E388F6173A3CDB3B
-:10935000FF459E4DE50BFD1BF1C74738BE398F31E8
-:109360003921EFD17D4DDCEF18A7EF6570F2647104
-:10937000DA6947FBD2BAC4658CFBEB7D7EFBDE1459
-:10938000F6FDD46F57B1FF193C90204952CDC53935
-:10939000838FC6F9631E9BC85F26FFD12C4E47F30F
-:1093A0001D7CF0F3CDC141471ED72C8C3FC3A3FFDA
-:1093B000010A95CE3EB00E00000000000000000043
-:1093C0001F8B080000000000000B7BC9C7C0F0A382
-:1093D0001E81BDD0F8E8B89917BF3CA9588601C1D5
-:1093E000CEE6626008E060600804E2DD40BC078809
-:1093F000A539191842803814882703F95380380793
-:109400008893816A1B981918B6B13130EC05E223B4
-:10941000407C9A8D74FB9F8A3330A4C920F85B800E
-:10942000EC4D72D4F5E3281EBC38C600953F4713B7
-:1094300095BF449B81E12E929AB99AA4992F68C84E
-:10944000C02004C4008B7A89656803000000000016
-:1094500000000000000000001F8B0800000000005A
-:10946000000BED7D0B7854D5B9E8DA7BF6EC994921
-:1094700066263B0FC2248664E70501031D6288400F
-:10948000D14E5244B4D48E685BF478740848781393
-:10949000F09556BCD9900709093058AC81224E107E
-:1094A00011156AA4F8AAB40E88163DB64D5B5BD1BF
-:1094B0005A1B11410139296A9D5AAD67FDFF5A3B7C
-:1094C000B3F7CE4CC0F6DC73BFFBDD1BBF8FE5DA14
-:1094D000EBFDAFFFBDFEB5462645442A20E40BF860
-:1094E000FB1A21B9222164423C254452FB9C901274
-:1094F000ED8B62539E7C613B9FFC67A3CC798D9082
-:1095000061907E9F906C426EE365F42F00F9A93C58
-:10951000A3CF474F895F26D1B2783F5309CBABA287
-:1095200040BE10E0ABB95C1FA7C1E91D47D208F9E6
-:10953000C4C552AD861655D2F42D57A4A9901097E4
-:10954000102A66EBACFF4A702CA61743DA24905918
-:109550003DEE04F320AB195C76E788A42A3E7F6BCE
-:109560003D3D6D6A24243A2A9EB749FE288C4FA6B9
-:1095700010FF8309DA4DA4EB40F8B88904F0903964
-:109580003CDE154213E1BB9D04A2365CAF9FC03C9C
-:109590000F78AA8E84B208E99C22FB1DF079530E45
-:1095A00081797975B8CE2AC0BC0C799590AFC33F4C
-:1095B000B8DE685B319D47AA5F246BE9A7A69C0AC9
-:1095C000271D93AC9FF4575F88A6A9520F512075B1
-:1095D00093404FF9E0790689C8F7F12E723E70B0DA
-:1095E000EE8F1DD680ED6947D9F1F96EB0D379D1F0
-:1095F000F568134402F0595739332D94601FF47401
-:109600000DC0972EBCA5D18969D3C49969A41C7AD1
-:10961000EA9F05705E3F295B5C2BC4E1A2C3E1C0F9
-:10962000A4179D7DB45E3BDF9F4EDF4127B46BE7FF
-:10963000FB6E85DB7A800F2DAF2102CEBB6558CA49
-:10964000AC4802B8D4102F96AF77D176B08E1C12EA
-:1096500079B010E6D3D73587E6BD13950A80B715E4
-:109660007FA60E93B0BEDB4D220EDCDF803B8796DB
-:10967000A71236BE3B8FF8A3743D2EB7DBAFD2BC2A
-:10968000345124511DE6F8EF72D33E7849BD835022
-:109690007A4D9D326F061947F36AFF1118DFF9A65C
-:1096A000C31F800AE532B657E87F5F14D1FDF8DBAF
-:1096B00087584EDE16FC0FC2FC767078296C7C67EA
-:1096C000896C1ACFFEF93541806F47F98A9455426B
-:1096D0007CFDB2719FE9BA6D96BC7DECCC6F15AB89
-:1096E000C9F7D3DEE725D18B6865DB0D43EE7BC37D
-:1096F0009BE32F3D54169FCF8F8827EB3800EB62FA
-:109700007231D2FF39DA7FD2E8BFF4901DD7291A1F
-:10971000F950B2FA6D1CCFF47C7B21C513C4B33E63
-:10972000DFD563E3DF5FE5F841B46AE46F12DFBFC2
-:10973000F64B48BF8DC2B769ACACAEA67090DC7278
-:109740005418C7C6ECAF02BAA67FF0BDBCB557F03F
-:1097500042E636137F6C29BE8A328EE4F393B2CC94
-:10976000FBF365E1F73CC0EFC238FCEC249816052A
-:10977000BC0DFA103E1E7D1E977C478DAA09E0782D
-:1097800031A53B3A9E3D2B42128DABF341BF10F801
-:1097900035F01F9BEC47BE4526CB09F9A05D109123
-:1097A0004FC5E1EC94101F09FFDB1F42B8C30C9DAD
-:1097B000D91C7E8097252FFE0DE027A9249AEAC5A3
-:1097C000EFCD5205A5039568A994FFCB129120FF18
-:1097D00029007B02964F9533804F4CF38780FEED36
-:1097E0007C3C65B6EF6A4F7C3E9FF27D8D97877C0F
-:1097F000DF3695DBD97C3D9C7F28734C7831D03E99
-:109800009DB5B7AEF723C2D6FB29A547863F737C2B
-:10981000410FF4434CEB6E516F08D6AA280F3E85DA
-:10982000FACD5F09F4CC017AE5F2C02A5793F263CE
-:109830008B3CB5FB0C79F84731E05311FC9BA7201A
-:109840007D11AB1CE76960C43F270F69CB4472767A
-:109850009C203039A565E1FA753A225C4FD0F79B20
-:10986000F27593FC90613E94EFB948043B4F25514B
-:10987000CC7B483DE63F9E581115683F0EA9AF0DC1
-:10988000F89783F251AD70F0F81BB83C49B68E0DD5
-:109890009724E6FFF9807C80DFEE7A1242BCBD415E
-:1098A00001BA12B410F902E88B84B9FCF5FB60BF71
-:1098B0005A1B1BC83BA584A41CBC8EA863611FEA6D
-:1098C000038172D04B6815CA824949254B25BF6A6E
-:1098D000C4C7817D24ABF87841A43B8A17970AD08E
-:1098E000BFD38C3703F85142896E12E6D560C2FEB1
-:1098F000F87EF27A49F16760FFF5F5A832E2AB0530
-:109900002F5C958A00A84DB3BD309FE17C36C343E0
-:10991000ADCBC571B02FDAF49174ADC3FB66CF0047
-:10992000D1E979F38AF7415E3597571CAEA1FB94D4
-:10993000E657AE9E4653570911009E6DD0592EF43E
-:10994000F7A2564DD7DB049DD1FCF5AB9E0D686E9A
-:10995000861E66BD5254251D5F8A86D44B842F1CFB
-:1099600083DB275BBFDD22D70859717E7AD00DAC2F
-:109970009D46FF03BA4AB7F4931630F3710F31E4F2
-:109980006979F380DEB4FC7F643C85AC76AA14056B
-:10999000EDAAA844E8D869444997286AB8A64A2499
-:1099A0004AF34A567F4054CFBD2FCD844C677C3C50
-:1099B0004C8C78BC99D3B9AFB6B9B095F6FB71A50C
-:1099C000DB0F743E9CB2C1CC8CC1EBE9B0C8E18E18
-:1099D000F2BB11EF9B88E62C02BDBE5C44FDA54D99
-:1099E000DDAB18E5D0B33A3F19841F4495AA9035F2
-:1099F000207ED85431E0F2FEEBF861D57BCE173FE4
-:109A0000526F30EFC797DDAFC3801F13CE1F3FFEED
-:109A1000D5F1F47D4DC6977CB5B7A25DB1266F68D0
-:109A20003D7EF0BEAE46FEE952492092A0DD2F05F4
-:109A3000C12C7F8C69B6515EDC62DA2FA960DA91A5
-:109A4000EE21E021A91639A8F3B1069B7A2C133A2E
-:109A50005050DE38797FEDEADD1AE8ED1FE7018628
-:109A60005079125E1E1540AF2961F61D742002BDAB
-:109A7000A88108DA212097E8BE38F8FCEC3EB31E36
-:109A80006F5352CC7ADC2C4D30CEDFD520E33C9C9A
-:109A9000301EEDD741ED0518D79647A22E6F1C5FFB
-:109AA000612866AFDF795E78A0E32B8095E1ABB9E2
-:109AB0005DABAF22A15E3768BC6BCDF34DCA97ACEE
-:109AC000EDDC927ADCA06F246F2791E306BDC50719
-:109AD000B2C5B0FFAD76F2B440F5BC26DF77349C5A
-:109AE00037FC9303FC89A03CB3E5D490900A7252F2
-:109AF00065EDD40C265F7709267B5BFF9E7C1E6C90
-:109B0000BCD8CD84F482DC9154D47F93D56F6AF4B1
-:109B10007D55A242C8DEF0C06489EE5FF3AAC0ACF6
-:109B200020ADBFB671D764F8AED7AB11454EBF5468
-:109B30006C56811EC3F196D07A4EFC4ABE00FB885B
-:109B40007266D580472ED233592AC3AF7CFF883046
-:109B50004007B4CB25225BAF833C8DF5A023A847FB
-:109B6000B938CBD386906FB10702414A776BA5888D
-:109B700073054D5B5C3CAFF27C3ACF2B3C5FC8F386
-:109B8000643BE6ED32CDD375A5D8230AE65378BE03
-:109B900090E733783E9DE78B785ED88EF91699F57D
-:109BA000D721F5B0FE53785EE5F90C9E5778BE8854
-:109BB000E7C95E36BE83E553ED3DACFF549E2FE40E
-:109BC000F94C9E4FE7F9629E17F6623E299F2C637F
-:109BD000F08FF305066F1D0F09C0D5E4E78A5AF22E
-:109BE0000C5F32058687B16FEA78E347FE48DCF9FF
-:109BF000486FC3B9BFA1E906E66F20DC3F62F87E7B
-:109C000058057E334BF40F455F8F707EBA8BEBB1F6
-:109C10003B1B15D4BB7734FA30DDDEA8E2F748638E
-:109C200019A6DB1AFDF87D6BE3444CB7340630ED22
-:109C30006A9C8EE9A6C620A61B1B6761FD0D8D21BF
-:109C4000CCAF6B9C8F6947633DA6ED549F85744DE7
-:109C5000A386694B631BA64D8D614C7F7843C54B32
-:109C6000A0D27EEC1651CE279BFF85BB44131F1E4E
-:109C70001D31F3C5515D19A67C6938D754BFB8AD05
-:109C8000C8545EA88D319517345498F223EA279B67
-:109C9000EA5F30BFC694CF095D69AA3F2C38D394E0
-:109CA000CF987ABD29AF4CA935E5BD950B4D797795
-:109CB000F90A53FF2925DF37E59D79AB4DF53B5C6C
-:109CC000A19F8A942FC8596B4DF524F7DD6679352D
-:109CD00023EBBCF816F948CB06BCD2F98795DFDB3D
-:109CE000F2492080728BC99726C05BF0678D209166
-:109CF0000705F0235D7E18FC178E1226771C83E47F
-:109D0000A6B93FD9BDF38846C7A9F61EF6F519E8EE
-:109D10008C18ED4ECAF7FF2C32BFE2DABB989DDCFF
-:109D20007957627B19393BADD7F979623FED9F4492
-:109D30009B452F60764AE75D02D6FF57FBD7CBAD38
-:109D4000FDC6C7A37B5C65B05341EE4F60FFA7190A
-:109D5000F4137B5FFA1CB07B743BD6C6E9BCBACC6B
-:109D6000FF763385778B42FC0E9A6F71D710D02B1C
-:109D70003E5618DD931DF9686FEBF507CFCFA0575E
-:109D800020FF4931D9FB927B26F29796ACA1F532A0
-:109D9000396623512AAF6C3101FD72B2149C5E48C2
-:109DA000E9577ED5E65F45505E26B4DF09B91BE171
-:109DB00060B3E837CD732D7C6FEA085CB75DE76F61
-:109DC0005935F8BD59197A5E0E9817CC87CFCB1E3E
-:109DD0004BC5D41673E17C27C532313F31968EE9ED
-:109DE000C5B10B30AD8AE5603A21568C6965AC107F
-:109DF000D38B621762BB8AD8684CC7C72EC2EFFEEE
-:109E0000D8784CBF12FB2A7E1F179B84E9D8D8D77D
-:109E1000F17B79AC1AD30B63DFC0EF636257603A12
-:109E20003A760D7E2F8B5D8DE9A8D8BF613A3276E8
-:109E30001DA6A5B1399896C466635A1C5B84ED8A49
-:109E4000620B302D8CDD82DFD5D8724C0B627762CD
-:109E50009A1FFB1EA623624D98E6C556617A41AC57
-:109E600003DBE5C6DA31CD89FD00BFFB621B31CDD6
-:109E70008E6DC6343DF600962BB16E4CD3628FE2E8
-:109E8000776FEC614C3DB19FE07777EC714C536399
-:109E9000CFE2F794D83398BA62CFE37767EC00A6A5
-:109EA000E7DA2739CFCCC76D5929A6FCC463663ED3
-:109EB0005EF5A6998F57BE6AE6E315AF98F9B8FF2D
-:109EC00090998F8FDB6FE6E3E5FBCC7C7CCC6E3327
-:109ED0001F2FDB61E6E323B75E6FAA5FB2C9CCC771
-:109EE0008B3A179ACAD566331FCF5FF97D53FDBCF5
-:109EF0005B579BCA7317AF3595FBE69AF97736D94E
-:109F000062B6BFA76E37CB91298F98FA7357EEB51B
-:109F10009C034490CFA494FFD4D4CE597230A15D59
-:109F200063F57F0348244ADF779014FF5A61F07E7F
-:109F300066707E90097447D32C4E77C380EE689A82
-:109F4000F18DC5787EF4C937DB7E416D4392710196
-:109F5000FD673274BBA12640BFB7E6E879A209903D
-:109F60001F4198DF80BC5F8DE5852CDFD574AC5A2E
-:109F70002B477D9EFB154E57835FACD5C5F20FD99D
-:109F80005E59057E858CB440AE9FA63BEC89F9F8FE
-:109F9000633619E1714A0C6CB3D1F5FE6775DFEDDC
-:109FA000E00FFCD411DA6EA3DF173B4305E06AFE35
-:109FB000C01E7A4802BE48020FC0F73412D861436F
-:109FC0007E6DF67B36828140FBF98B187C18CA3394
-:109FD000AFDA857691BEEE56CFD0F3B9CFC6E45254
-:109FE0006B3A41BB51BB4746798A7F55713FD5BD1E
-:109FF000A9DE009477DE236F87F320BB3F9BC9095E
-:10A0000062911F9B5A9783CBD101FB6933FA3D7B49
-:10A0100031F5927EF47F2A441120D5D73FB0EE115E
-:10A020006CDD141E87603D32F84B697E75EA55136E
-:10A03000613D141E2F7078BC681B961C1E044E0ACE
-:10A04000AAB82A01FFEC164CFEC7778550AF8D9D4C
-:10A050005FE27C54CD8F707BC4C6FCDD3AFCE8DF48
-:10A06000AD19BA3F86B53B82FB60E94FEFA7D7C673
-:10A07000C7E7F250C7E34C918412C1BFA591F99F85
-:10A08000C9AEFC2FE5AFFECC2E261CC72E05F19CD9
-:10A090007410DFCBB2D8F5592138D385F38784E724
-:10A0A000A99364EECF900ACEEB3C4AF79790DDF986
-:10A0B000E755FF217DDD70BE908DA063FB74281FE6
-:10A0C000F3A5BC7D31D7EB9EFFD353D125940F74FC
-:10A0D0005230B3F348B33ED7B949C473F4E2114CDC
-:10A0E0003F6CE07A80839A0DAE710639DD69D60B3C
-:10A0F000DB7438EE37C3B19822F44F2BE8FFB80B6E
-:10A10000D8FC14F37A9AF5F55AE6D152EE2746BBFD
-:10A110005B1A1B1421EFD8C4E6611D9FF0F3035DA9
-:10A12000EF75B8B9DF4429C07EF571ADE310DB4AA5
-:10A130003C1F4AAA8F58C7F992E76F174989CF2F5A
-:10A14000E9FE209C4AB87E441AE81FCD8FE4F3D77D
-:10A15000FBD3CFE1F4FCF37FAAC3F3EDD6702DEA75
-:10A1600079AD3E26A7C967B477E88F24C617FD3CB2
-:10A170007C0DD88D60CF95D438B15D568169BF5CB8
-:10A18000A59B9C008F66E56E05D2B565AC5ECAE8FE
-:10A190001DFCFB76FCEEEAAA3F0CFAA28BEAAD129C
-:10A1A000C07BC4AD58AF595981FED9942EE6B74D46
-:10A1B000E1E5B925AB9D10A2911B0E38A11D5125DB
-:10A1C0007F29B4EB0A4F2F027F571BF14B6C0A4ECD
-:10A1D000D8C7ED1C0E7925520DB4CB0B6B9A0BDB57
-:10A1E0009100B4D3EB45F87AF3CBC45570AE901F11
-:10A1F0008E846BC04F574FFCA5F8FD60B4D0507FE4
-:10A200001BEF5709B3F993F9AC9E5EBE95F7E70EC5
-:10A21000D7F756433F9B58B92FAF12D837C9566B63
-:10A220004598CF3A8EB7CE424960E741ACFD161D46
-:10A23000CD2CF45E1A66FE4EBD5E179F870DBE974D
-:10A24000C7E97E0DB7E7F57A3FE4DD8DB4B40FF3CF
-:10A25000EF8E4AD6BE89DBFFFA7E97CACC2FAEE3DB
-:10A2600047327C256D067E060BD452CCF9860C93C2
-:10A270001D47EA73CDF9F945E6FAA131E6FCAC0ACF
-:10A2800073FDC06453F92703FE92880BFD22DC5F47
-:10A290003292D7D9D2C5F03CEE8FEB7319ED8B3CDF
-:10A2A0005E6F5B3D8B7369729F5F5C4918FC16C8DB
-:10A2B0002C981F46D1FB69ECC2EFAD81DA141877F8
-:10A2C00067D7D0FDFD84D3D5E39CAE1EE3FBB787F3
-:10A2D000EFC7A3DC1FF330F7C73CC4FD310F707F1D
-:10A2E0004C37F863E8F7FBC11FE3003F4D10D32D57
-:10A2F000E08F413F0DF3C7FC90FB6336803FC60102
-:10A30000F8D780E9C6F1E1EBC0CFD6C1FD32EDDC74
-:10A310002FE3B5337FE3C6CB02B950BEE3B2C4F638
-:10A32000AED7CEF024171414CABFF389164D01BA64
-:10A33000E82404CE5B9CAF680137CD8FDEC589640D
-:10A34000BF1648A5F9511196CFE3E3809CC0F8A74A
-:10A35000061617E3C8D3C86CD8A73CAAED50F8AED0
-:10A36000E1F8FA9AC4C68372A41B95F88C7CFB0DA5
-:10A370002170449A00FDB2F9B8422101CA86DFDAA1
-:10A38000AFC9B45C59DC1B80ADF2B6F544C17E5652
-:10A39000B528EA1B1BABFD87E13C6BF3EF6D7EE458
-:10A3A0001D59C4841FB4EF8476757E6C1BEAB7AD6B
-:10A3B000F53CBEA892D5CB4F627F8FD96196FF65E1
-:10A3C0005BCD764F6BC3CC21FDC5C36789167F92E9
-:10A3D000E55C608A191F5B036C5EC9FAF3569AE765
-:10A3E000E32E37F7D7EA1E7A3EAED855A8EF27C33B
-:10A3F000F332B1D66D9F10CF17C72EC5FA56FD4E5A
-:10A40000227E543EA4A97200CE79A5A94A00F45A2E
-:10A4100069AACA533FFF1EE0F920CB2B03E7DBB943
-:10A42000F661087FCBF97680C0F9F3C6D184D917DD
-:10A43000DA9CD5812934FF6D82F6C2EBD2B21A2D97
-:10A440008FD2CB0CA768FB0AE01B8B57D0E3BB3243
-:10A45000E5487B21E5E39B378A643BCDEF080F4D50
-:10A46000CF83E218DC01F4CF14772A1520BE93B510
-:10A47000DBD4294E4F14377031A72F728858F5E678
-:10A480008B61BD2D9D33159067D2B57EB40F88CA00
-:10A49000E6AFF3BFCC2D43EF5FBB65BEAE247E9B22
-:10A4A000EFE9F328637C53C7EFCCEF0F8D5FBA7EE3
-:10A4B00016EB114CFE9D61D706ABED142EAD9B89BA
-:10A4C000DF4DFB69FDDCC6FC64FB597C998EBF4DFA
-:10A4D00081A3C8AFF5F1739568B500F50F4C222A3A
-:10A4E000DDD791EE9088F6E001CADF81FE24AA75DF
-:10A4F000D2FACAFC6880FBC905D87FA5DEAF411E31
-:10A50000F603F806D89BBC3ECA8D7003550F29FD93
-:10A5100037815FB330CED7753C68F271FF3AD53BD7
-:10A52000B0F433BA3EDD1EA1FF8CEC62FBDC3A8C4A
-:10A53000F8719965F5C486FDB0382989EB8FAD9E19
-:10A54000DBF11C509BC0F4026A350704A82769445C
-:10A5500084F1E72AFEB5345BDC350EF98AA4680283
-:10A56000E0DB0C21741BEC771CAF7AD83A38DCACFA
-:10A5700070BF96F3D59424FB9922337D3B53F65F4D
-:10A5800009F6E4E67B287E2788779164D6CF039B83
-:10A5900066A68D56E3F4AA973F6253B19F387DCBF0
-:10A5A0002C4E2F6AB63FFE5FD7E377DBCD7174FF89
-:10A5B0005F8FFFBF5B8F5F3780AFE7D2DBD9FAC910
-:10A5C0002C73FF71FD5D53709E5DAC5CB7073A2C38
-:10A5D000FDEB7ABCAEDFEBFABCAEB793C17A3D9728
-:10A5E0007781D5010AD0516E961FD51A58AD419981
-:10A5F000C5CF61A36CCDE8AFF8C042D792DBAC7792
-:10A600009C3F3F9050DE13FF08133FCDCC1D5A6E88
-:10A61000E872F49311BADE1E427D9A949411A37EDF
-:10A62000B5B3A18608743D5B7DC4CF978EE3E4F299
-:10A630007539FB029A884E0D331FDE3AFFA06B94EA
-:10A64000819F3BDC3D01380F77FB7A217CC9C877BD
-:10A650004BE409C08FAB90AF39D530EECF5DA05F32
-:10A660004E180C57E073BE0CE8D1C25F48B017E239
-:10A670003D8AC7138CAB77409414E5030E3FE34F3C
-:10A6800049F9CC79C669E87113F9F40FF8CB2A209F
-:10A6900022D0879E36C7931385E289213E80BCD79E
-:10A6A000448CF17E3ADCADED9A951A2511BF7B43BF
-:10A6B000085D210F8127563F14B1F067AAB08910B9
-:10A6C0007F583C633AFA9706FC5192995F3B227A95
-:10A6D0001CCBFF2CDF9E2327E6DBC9DA0FC43D7FAE
-:10A6E000497F5D3B3F8FD7E97B80AE2DFD88E53DFF
-:10A6F000A42FC1F8EE7233DC534ACC76C53F802ECE
-:10A7000027C0F97186E9BBE4CE4DECFFE77199B53E
-:10A7100013F56D53BFFB478ABF0B0EDB09E827BA61
-:10A720009CD1FDB10B203E93EE4F2DC46BD27D9C8E
-:10A730004B825E28FC8088D341FFF880FCD67B9159
-:10A74000619F36CBCCFF4EDAEC47E11E901E877836
-:10A750007398E5F5F9D47599F3F3C8CC6C388798FC
-:10A76000B7C94E20EE7001918EF6E9F3A7FA4B3B84
-:10A770005C4CA0FDD691FA56E0672DDCDF5EAB1095
-:10A7800009E206973C755FD56C9A8F70FDE72485CA
-:10A79000BF6A882F5BE88EC8709EF0CEBE8BBEF37A
-:10A7A0005502ED23ADB9103F984E307ED00AF739EF
-:10A7B0006DE6F99D6BFED6F9EAF78692CD43DA2570
-:10A7C000248C73FBB1ACC72D6AE7759FE9B760FCB9
-:10A7D000A23FDE7C9FE95CED5EFB27DBBD29AB245D
-:10A7E000D1FDA973B57B3BC9784B9C7D32F08B655D
-:10A7F0005268BA50148FD392EDC1C0051414D2D34D
-:10A80000E3A370A464A8D7769EF50EC379C779D464
-:10A810009B2E0ED1DF194EC7BFD8FD800CF4F9C1B5
-:10A82000236F5F057AF5A2676D54A6D3F2DD1E1281
-:10A83000457B2322831C5BB8CF867E372245ABAE97
-:10A8400031F05F8C90A5FD2F7ACC8371150BF73A10
-:10A85000223368FB854FBE338E50389C59DDFFE2B2
-:10A8600005603F3C22B03842AD6FDC35F4FB4289D5
-:10A87000DC144CC407399E9F7E267516E091B0EB20
-:10A88000C08DD86FCF77ED0EC339DE5F65764F810F
-:10A89000D6C3F325ED6121522AB0F919EF2BE8F167
-:10A8A0009BA71F16D8FC9EB6475C30BF5DDD728843
-:10A8B000D65BB6EB2F88B75F7F6C8F17E0B0EC6983
-:10A8C0009B89BF2CDB658B3AC661FAB603EFB904EE
-:10A8D000DC02E5234B91C5D074DF128CF75EDAD32E
-:10A8E000F1179B17DA9BE987C2C51F05B8BE66F34F
-:10A8F000CF80FC4F1EF2821D78B2F7412FC095F633
-:10A900003B5BA67875E947063A23ACFF58C6E0FEE4
-:10A9100008E99701BF96F5B4B3F12CF47912FE273C
-:10A9200067B05C18E930CB858FC92B55A818EECAE3
-:10A930004C181F3F201738BD2EDAF3F1368D8E7B71
-:10A940007AEFA96D1A9DFFE27F7CB8ED4ED0037FB0
-:10A95000EE5280CF2C7BE4F75E62807BB583D1FB27
-:10A9600099871FDAB985D2CB99D71DA8B79CF9D999
-:10A97000897C95AEFBCCE37FCB867B02B7FEECB245
-:10A98000E100875B9FF8FAF0A1EC7EC0D788C3B8DE
-:10A99000AF11EC5F7D5A60C1F8FB796AD99FE7F788
-:10A9A0003D9F0FF3FCE08803EF152EA3DF1A2A600A
-:10A9B000BF9620DF87FC4A0AE7A5BBD7FCC5362E29
-:10A9C00011BCB50B441FA4946C7CB0DFD77CEB9218
-:10A9D0004A48ED7E15FA23FDC8B7ADED96BD4AF79E
-:10A9E000F52BC9F7F163F2990CF05FB6BB9D8D6B47
-:10A9F000D9C70FE07F260DDEC79B1CE6F3958FC9F4
-:10AA0000E2FB5197DF9799305E4ADFC7254F7C7B89
-:10AA1000483D40E707E782EF7C1EF757EE082C73AE
-:10AA2000005DED4DD57C6C7F233368D9993D1FE7E0
-:10AA3000138A1FEFD9FB6F043ED9FF3387B29D7E87
-:10AA40005FF8B3D790CECE3CF11B5965F79DDC0281
-:10AA5000D513CE9081BF5ED01B96F233E4653B3CAC
-:10AA6000518737BE4F4B23574F57BDF8FD6DFC1E26
-:10AA700061F8BF3472E05A21C1BE3DEC28627C39D6
-:10AA8000320CE1B284F4CA4AB9793F8589B08F6F3C
-:10AA90004F03BC4BB68FFAFA1558FFC586FDDCC1D3
-:10AAA000E8D65A7F29A54FF00B0EEC6B44788D2425
-:10AAB000A0D333DD0E09E27BCFD8CF713FF74BEA4D
-:10AAC0007F0F38929CBF71389C8BCECFB5BE2F0BB9
-:10AAD000BF8DE0B41E36188EA73F4BCCFF9F730886
-:10AAE0007C1EA1E9B9B6C1F2CB4602DA0585F1F9BF
-:10AAF000B6F6D890AF9FDE65C3FBA6563EB1942450
-:10AB00003EA7FEA53ECED307C6013F3B7DF0198E82
-:10AB1000970CEF97EE7E5BD6B83C8818E54112FFA4
-:10AB2000D46B9CDF2DDB9FB8BF65BBFF92B0BF939A
-:10AB300052E0BB30FF93BD76A2D12E4EF6D8A627A9
-:10AB4000D29F0E38EC26FDA9D55375248DB6B37966
-:10AB5000535418BA6975E035B0E7B4DFDAF11C83F5
-:10AB600048FEF71C704FD393A2AEA5F06AF2CE4315
-:10AB7000FFA3DE5FB3054E922FA8815D2A65052BEA
-:10AB8000998ECCE6AD97DB15D1346F2A67F3400E72
-:10AB9000BD35FE841DD6F9678B3EF86789B40EA7D4
-:10ABA000FDFD5913FCABD444F86DEE3FB4D24654CE
-:10ABB000A3FC73F4BF05F321CFB908C495D87EEE8A
-:10ABC000D2809F2CDBE68A38E87A9E7FE2939D0054
-:10ABD000B733F73B88C310275EC7EDAF134F7CB286
-:10ABE000EDEFB4FC0434A6E3D76DA3F5410FDF9D70
-:10ABF0008AC1FAFFB9376D1CA1FCB9EEB93BAF02AF
-:10AC0000FE52073443EBD73D361CF5BAE3C358FE7A
-:10AC1000F89E1111D897C53FF9D95290238B7E9C8D
-:10AC20004AC03479FE89D76E84FC99E73C18D778FE
-:10AC3000E6B91397021D50FD5935CAF105C67704D0
-:10AC400068BF8B20CFCA852F0CF1328B20A57C6387
-:10AC5000D1D36901F0131AEA61BB658EFEDBD151D5
-:10AC60004BB45C116D9C682ED0E1A25DE6F1F29CC4
-:10AC70004C7F5A26F7CF63F5C3B98C5E7BB1DD6894
-:10AC8000A7602AB7B6D7EB8F721659FA61ED973ADB
-:10AC9000487D22FCAFE4FD2EDAF5F928737F1AFF18
-:10ACA0006E1D877DBF4D60F74AC8E32E3C475B2C85
-:10ACB000474766507A7D5226F3816E177BA323D3D4
-:10ACC000E978CF723EB93885E6E9F75C3E0FA80F08
-:10ACD00079E2ECFB31ECEF92A75C04F07DC9731EC6
-:10ACE0003C6F59F2E427C77F44BF9F7E2215E3B42F
-:10ACF000973C7707EEF71247F446F06BF73FEE40CC
-:10AD00003FF2E9C75FCA073DE4B43D9A9F31847DB5
-:10AD1000BEA4070EC107AF83DA0565F5743EDA46B7
-:10AD20001677D64052FCAB68BF0DE0D7003C7ED30F
-:10AD3000C5E2A3F839EE0AEE0F3A3B574DC3F99737
-:10AD400033FFD60A7E4F7DC537D5E1E98679405C71
-:10AD500028B988903BE4FA51C0676DB16F1015FCBB
-:10AD6000EDB1624CF57A3685AA59706E90C5CEC9A0
-:10AD7000ED597E52570EED581C11715F394067BF77
-:10AD8000A65BBC62B33A1CFAFB7727E32F1DAEC06B
-:10AD90004227F21937DEF7C4755286A03DC1D6F5B9
-:10ADA00089C0D6659DEF2776CD01FC3C7EBECDCE19
-:10ADB0004D1A24F53538A72487395F1AB47E4667C3
-:10ADC00067950CA4337D1D1D8D0AF293F6461FA6D0
-:10ADD0006B1ACB888A71F87ECCDB383C1CE51AB143
-:10ADE000C1FD5795CDD5E10E06E05C02FA047FABBC
-:10ADF000CD1D42FC72F8EAD1F677BA991FD2E6D699
-:10AE0000481D4DED6E0627B8770A7092795EEA9A72
-:10AE10008170A5EDF1FB025768A313FD11634C7C13
-:10AE20004ACEAA30E507C14DC78B3DFFD3F02308BA
-:10AE30002FF0D3A8E83F9F88706B690C60FEFF007D
-:10AE4000FC9E61F09B4C5403FDC85935A67C52F81A
-:10AE50006DA6F0CB8AD395150E0D3C1E4DA7A764A9
-:10AE6000F4FBC34682CEBCBB1BBB30D5BF6724916D
-:10AE7000EB392E819FF78756C1F91F51985F856482
-:10AE80006924CFE04F223E0DEF31E19B2650EE6664
-:10AE90007E447D7F6D8A74DCCCFFD4D7603D77BC67
-:10AEA0006C17815FD91A1E20EF641AE87846D0A586
-:10AEB000229CFDE8BF6DE2F2B565603FCDF4D1D1D3
-:10AEC000A862BA8ED3C9064E271B61DFC13FE717C0
-:10AED000714F3BA713949FF7D03CB3EFA3C4E8D7BF
-:10AEE0004EF7F744ED74FF9127A998B2775E8E383C
-:10AEF00022A5B45D6A390900BEA41FF95E84BDDFD6
-:10AF0000D283F7FBD339FCC8FEA2F4EBF0FE34B1D8
-:10AF10003339456C2C0DDBC17EB2C2B7C97FD00975
-:10AF20007677B2F964FB35473E1D2FFB4D07F2EFF4
-:10AF3000AC1B7A8ED4D275B83B53D19ECCF6337C01
-:10AF400074FB43429D61FFB293E87D9B5D57385C83
-:10AF50008087107F4BF9F6DD5DC52E3CBFB0F7F85A
-:10AF6000800F76A43339A3CEA2A35D1C6F7796F32E
-:10AF7000476FA599FE757EAC4CA930E1B1CE6F3319
-:10AF8000A69AF15DE7B76F0EF0DB608E0BCE3563EE
-:10AF90005B911EADF8DF649735E12BF0DE06617E34
-:10AFA000A7B705F60ECB603E80F12867FB0AB7C352
-:10AFB0003B00AB79FCB346E905E50EF77FEA77B9CC
-:10AFC000F690609B5A08EF81500485776328FE0055
-:10AFD0003DACA7F843305EC8CFE96422A63A7E565E
-:10AFE00083F3C4A0B7D94A5E14D9FD0B11640E9146
-:10AFF000A81DE8063FD381494ED00B253B8B53E972
-:10B00000F7883D7036D6E29EE984F86821BD12F7D4
-:10B01000FDAF9EDA82A1CE5508C4F152BC51DC7E50
-:10B020007214C6817BBA40174A05017B728FBB3709
-:10B0300005EC1BBF4B349DE374B842D35C86FC58CF
-:10B04000189DEFDBD770FDAC1FEB783339BD933C17
-:10B050008D9418E85B8F0B25AA46CA0C74BEBA748F
-:10B060001A8173CDC1F49D848F3DF8DFC3C79A0A5E
-:10B0700022B86F762BDFC8A2FCDD8DA9262A30FF0F
-:10B08000BDCDFF361EF1AC0EE041DCDB07F497AF1F
-:10B09000150D9EA7956FC5E5918AFE2A2A8FEE9D14
-:10B0A000087C30893C3AF0A751DF9269F93B2FD9EF
-:10B0B00004A3BF6E7EAC1DE5415D6C1251E97C6B53
-:10B0C000BB7E80E9BCAE6EC4FBF7222D5ED8C7F70D
-:10B0D000DA983DF75EC41EC17884CFBEF8C2067E02
-:10B0E0007DC2FA7F6F6B13D623E07D318CFBDE5679
-:10B0F000D69E54AAA84F9FE56BACDDE008405CF9F2
-:10B100007B5DB4DD10F0AC056328817E8AF7FF21FA
-:10B11000D69FD48F023EA7D3FB1D32E54B0087B7E5
-:10B120001C09FDEC0B5C97AD03782F70053601BF51
-:10B1300021EE8CF37A87E21D91EABD08EF90F76A61
-:10B14000939F95F931DFE17A31712629F7F2F64ABA
-:10B15000E2F2259DA75EBC8BE65ACB434162B0AFBD
-:10B160006D84D9D74B9FAEE6EF7DB0F924C04FA6D2
-:10B17000CF763A900FCDE5FE201D5FE3F812F2F294
-:10B18000FBA0267C5A10DB88FB2D748CBD771285C2
-:10B19000DF87148FC02F27745C321CE868D5DAAFC4
-:10B1A0006EB881F6FFD12B36FC3E3FE6C2FAEFDFE8
-:10B1B000E5BFF706D0D77F69C733F68F0E5F86E706
-:10B1C000B1EFDBCD7E841B5318FDFED1C5EC917928
-:10B1D000B10E937E3CAF6D8E0CFEC779B1F5F87D54
-:10B1E0001E1CCAB07B1B87AA4BE0BC86E0F9E81F97
-:10B1F000DBDF9DBA1AE55905FAB1EAD63912DE232A
-:10B20000F9A34B35F19DBABE4EEC9750FD282B9B10
-:10B21000F767E01F7531B87402FBA311B867308F70
-:10B22000F39181F96DB59BF8C8FBAEC47E925303D0
-:10B23000EBFB2AD2D1E0F55DCAE84B1FB78FD15D99
-:10B240007C3DF74E4AB49EF83AA660FDF7D3138FC3
-:10B250009F91C2C63FDE389F04281FAA75D07A6E20
-:10B2600018FF96D68960676F4DCF100CEBAAEB5A8A
-:10B2700044028675D56D9D2DD71AFA8DEF83ED05A5
-:10B28000E33E64A4FC63EAEA7290DBC17F003DD533
-:10B29000765C322E847636E327EFD8FDF9C0574F1F
-:10B2A00074DD9290BE33522CFBD3C5F787EABD956F
-:10B2B00086FDD1F7C5DAFEF89FEAFE7A17F8013667
-:10B2C00033A52619BC06ED5B6162B89573FC3C4E54
-:10B2D000E56C08E1A63E7904F07A5D2AC6712687FE
-:10B2E000DF85243414FC92E8AF54DF294D9900E344
-:10B2F0001284435D17C38373C12D3E2EC783EAC4F6
-:10B30000EBB97E000F1A884609F6A87C2E3CB8934C
-:10B3100068CE21D6318007A34C7870FDDAFCCB8053
-:10B320001EDF033D65D4E0FD3F2A6BDEC9700EB41D
-:10B33000D686E74C4753B4ECEB597E3CF0E7A3DEEE
-:10B34000F055932BE3F9050F967A671BC63DD1762E
-:10B350008B37919FF5FA64F853A291F2AAFF7DF81A
-:10B36000F34E927B570B5CD537A6005F0E27F6E7AE
-:10B37000EAA9CEBF6D69EE01BB13E4E95177D15F55
-:10B3800023B4F451576801F47387A88E9B2DC4ED44
-:10B39000CF41FA67E3F44B8E9582BF3078C9313BD9
-:10B3A000EA43D81F01BDB290DFDF42FF460ECA0359
-:10B3B000EB79E9FA94C284E7AA2D8DF5171DC30035
-:10B3C000228D28867B6012617AD4A784F9BDF4F5BA
-:10B3D000C8F690E207FB522041C073BB146A833861
-:10B3E00028BB2F6BBC66806B670A8BFF731D3AD43A
-:10B3F0005648DBBBDE7D45C1B8153A0EF8D79C79BF
-:10B40000D259A37FDA9EC5E2124989E17B11C42794
-:10B41000D0BCC9CEA7F31DC24E7D566070D03C0E85
-:10B420007E0F4EB381DCBB4E7FF8024047F1E575DD
-:10B430003D0E446A66E5E97A71332BE7FECB65B5CC
-:10B44000CC3F69DDD7EBF6AFC177F5AEDB9F3307B5
-:10B45000FC58D7B947BD0BE70BCF820F1FF03D9DBE
-:10B46000C9656BBBC7389DFE5BB7A8D9E9BE1CB2E6
-:10B47000F71F84B876ED36F64EE2F5BF3F644FA570
-:10B48000E91BAF1EB5435CD14D10A043D7359BA837
-:10B490003253822308D739A4C7C3F23DC3667A8CDE
-:10B4A000FD515315FA5BCECE79AFFFFDAB9781F816
-:10B4B000A4FDB5407AD32B4486FE67EF535BD9B524
-:10B4C0003BDEDF7EDA9F18EF2F0E4799D9399213B2
-:10B4D000E112879313E1F6FA405CA4867E14039C84
-:10B4E00051DFD0E13C00B7B459579271C9E9E53A50
-:10B4F000F7C877C9B8F8BCAC70FE088A28BD3D9380
-:10B5000012F815D04D2425F06B48173BFBF3A5220C
-:10B51000BC77F83BE0B34B6DA182EC62BC8F386A1C
-:10B5200018C471F5263E5FB5D2E95B402F10CFCD30
-:10B53000E32B6FE4EB7BFE7B273C1837F9C46BF9F8
-:10B54000902EB1F5ADFB2ED0DB7FD850FF3EBB6F08
-:10B55000D49071696F717FC7C914FD3D16B6BE9B4B
-:10B56000B81E77D3BED408BC7B795383CDA4FFDE4D
-:10B57000D4C0E23888D43BEE5A931ED99CB41FB095
-:10B580003BADFDE8EB3B989F7B21D887F74F90556B
-:10B59000F03F1C78E5ECEB75349F32C289E7B2EBE3
-:10B5A000D239FE568BB8EFF7A70752C782DF696D15
-:10B5B000865FA3EB5CFB02E911297C0E8EBE3D5237
-:10B5C00043C75B7F89883EAB0DB107306E522B6756
-:10B5D000EF14295C1FDDD07BB40BF0F1C41107FA26
-:10B5E000FBED1E765F75AD3D980FFAFBBBDD72C2B9
-:10B5F00077EFFEEE96705DDD421FC6BBCD21612761
-:10B60000F08D7DBD3387C37CBC7EA200FA9FD86AD3
-:10B6100013F93D28EEE7884ACCCFAE492C1FE0A9AC
-:10B62000E232C6ABB54F9F8AF114733B7F8371C280
-:10B630005E7E9FC93A8F0B53D97C3DBD1957007C64
-:10B640003D53457CD3C8E3EFC778F182DE1A19DB9E
-:10B65000878521DB17AC54AE00B8427BE0FF05E7DD
-:10B66000D9BE3895C53B6DE47672B7DDDF3A95F605
-:10B67000D3BD2E5D80FDD0EB4D4965FACC89A9BACA
-:10B68000FF268CFE9BFC12C505EFA3E40790B8894A
-:10B69000A7328C71B8DBA11EF36F221CBA473F1989
-:10B6A00085F3E3B5201B609FED0C9FD6AE13D09FB2
-:10B6B00049E1970BF2E2DD7B1CDF807514B4090AC7
-:10B6C000D8DE344D38EF5BDD4E66B774DE8B762006
-:10B6D000B847A1DFFCADBFC3797992AC779B9BC122
-:10B6E000EBDD73E0475AAA9DDD1B6AE8E57652144C
-:10B6F000DF3F0CEBEFC2052AD9BB84524035C6A10F
-:10B70000C4E987D961749D0138DFAA9D2847C00F1D
-:10B7100020B675E33BBF73C20E72395D5FA7D01BC5
-:10B72000007AD12688FCFDADC05B00A7F51B8763BE
-:10B730003CDB1A31908FFE9DFF25E3F9D8C1C0D9BB
-:10B74000CD73687EDB4419E9E26080DD6BBD7F6507
-:10B750005137D8E19E861A7CB737A2E04BB8A4A92E
-:10B7600092BC0CF1A44D2B4545A0F5C341FD7E8153
-:10B7700092027831DEF6E11565707E9623822F897C
-:10B780009C10D8BB202D2B6B14D8D716254B30DA44
-:10B790002DB7A432F9F2ABF4E02DA934F5DD75B77D
-:10B7A0000231DD1B62991782BF506B9355F67E30D4
-:10B7B0007B4F2493EF4B66AF189DE7C5BC7B3E35AE
-:10B7C00091374C617ECA1F5C1962FE453893AC42CA
-:10B7D000FF22FFF3E1BE66F1DCDA312998D9B47AB1
-:10B7E0001ED6877EB2693F999562B48AF6BB3D3D0D
-:10B7F000B00DE5C9654E841391FABA004E91CB7233
-:10B80000FD10D77AF7A491BF8127A5320FF7CF0497
-:10B81000391A1991F24637F0A91659053ACF5C79D1
-:10B82000FC06F89EEEFFE12D906636FFE14E900794
-:10B83000E97D7F69C4EFD365937F2FF3CDF73F8711
-:10B84000F2CCA06CF2139E4E0FFE3095EEFBB6F2DA
-:10B850007018DE3DC51DCD8EAF63CFAADEE9F08E38
-:10B86000F589AB45FF765E8EEBDAA444D632B85547
-:10B87000825CD3E1B646547BE01D65ED2A27E247A2
-:10B8800009E9457E9503A7C8C5F17DC97CB37D391B
-:10B89000C44958E7F308A75BF883772531FE9ECAB1
-:10B8A0003139676A0AE0F5E315BD3ED0E3D7A52735
-:10B8B0008E4F38E966ED1D49EEA71FE7E5C012BBC4
-:10B8C0002A300D8C85D44DB43448F39CF83EE1E326
-:10B8D000A2FA47C4F3BB6D2AEC0FD4B7D3FD3BF0FB
-:10B8E000F249F40F1E08FF0ED317DC657A7FD16C86
-:10B8F000DA7E7DE551F6CEB7C270A4AE8DF18B3AFB
-:10B900005F9F13CE2BEACA89B29DE39BA6C319FCA5
-:10B910005D5C5ED55ECBE09A554EF0BC157C62F066
-:10B920004E5936D4A3F0CB6A5BB51CF791F46AC5C7
-:10B93000B4DE7AE817F6A799DD3B21A4CF89F41B82
-:10B94000B6E17923A5F75FC179626DE7703C6F8737
-:10B95000EBE9D05F061F3783F7D74DFB01FFDF8987
-:10B96000361BD98EFCAD97405E5D497119F1B3BFAE
-:10B97000BA8CF6AB562ACA5A1D0F743E4649632E3E
-:10B98000951700B7B99AB61CF0EFA8537919E6914C
-:10B99000BAC9A1C2FAE76E7AEA0ED05B527D7D6D1C
-:10B9A000C01FEA26B2F96674D2EFA8DFA8BF82FAF8
-:10B9B000759D0E958DC7E157C9F18CC3E1663EEFC9
-:10B9C0009BB7B279A78C8884013FEB5652B8425995
-:10B9D00088E13DB834BF1091AE0EC3FA3D5A36F639
-:10B9E0003B6C96852E2CF8A7AFAB96AFAB76255B5C
-:10B9F00017E1F444A715857E6B2BD93AE712D65E82
-:10BA000084EFB4FF9BF97A6AB52731BDB9CD61EAFD
-:10BA10007F5BD98E5E984F61B9AC0A0867F63E66C7
-:10BA20003E5F577E331B2FBFFC4984176930CC170C
-:10BA3000FDA2863CA5AB132F51C2A27AAE0081FCB9
-:10BA4000B4DFA3DF93F11CA56493795D27DA473D4A
-:10BA5000D009FECF7B643CAF785CF4BF558076A8FC
-:10BA6000AC32FEE3FFDD0CE0D33737E3BDA93DD5B3
-:10BA70000CFE27BE4922800FA587831900EFD2C391
-:10BA8000219ED6E33936DE13AB8AE331359DDA04E5
-:10BA9000E097B1E247E7031FA0FB0CFAE008E3BC24
-:10BAA000E9FC32DBB26B200E296B62468D8C4FFABB
-:10BAB0005ACA0F6F9909EFD7661DDA720B8C934340
-:10BAC0000CEBA1E5459E62A4BBCC43B414EA351C43
-:10BAD000BF0BF6A393BF2F5F0A33CBC0F410A4991A
-:10BAE00094BE3B32609E12995A11E7070FDE533520
-:10BAF0001EF80ADE29A9C0344A2A06F30D43FDD1F7
-:10BB0000BCBE2624A837DAA39AECF207EF99361ABE
-:10BB1000ECF7F5A027D27D6A27CA87101FA3F94545
-:10BB200084FB7A7BD4594EF36BA8DE08FACB86B23D
-:10BB30003F884077EBF7113FE04766F01F0EE33E8A
-:10BB4000CE71A7E3BA25997400FD1F1C7D7C3AECE9
-:10BB500053E48088EF48D4FCC2BD2515F4A1D75921
-:10BB6000FC49F74BF528BF6FCF9713BEC34CCEA14E
-:10BB7000275AEB6794CE443F5EC1A68DD3E13E4E7B
-:10BB8000DD74C97F39AD9DB5A9BA1AF4183548B12D
-:10BB90006B389DF7D6F1AB8008D519ECBC4A9DCE29
-:10BBA000BEAB5359DAD138FF22B0DBC3BB24173CFC
-:10BBB000853CA69DBD57D7517ED619A27A6965F5F9
-:10BBC0005EE737E9F76395540AD2EFC7A69C75C1C3
-:10BBD000F9CCFD95359900CF7D6D66BD8EC0636A49
-:10BBE000D40E1AEB08073C745E9DBF27084F9B23B9
-:10BBF000DA554BF3B6A7DCA0E10CB26FDA3BBB67BA
-:10BC0000019ECE2DC3F0E441EB3DCBE5C59C867E85
-:10BC1000BC5755A811768E1ABE1799F2CD9C6514A3
-:10BC20006ABDC8743C9B987D1296022F025F0E97E6
-:10BC3000876468A2F3B3CED2DA9DC0CFFE067A1D28
-:10BC4000C8B9FAF978FF11E9DF06FA507F7522BB0F
-:10BC500029989A82F33DB1F59AD7C03F3DB781E963
-:10BC6000FB055B3F14703FA8DE9743FB2FA8C4275A
-:10BC70002AC9DC9561E758D89F1291A82ACCA787DA
-:10BC8000809D10A6F2C70807BDDF7FB6FD3AB70357
-:10BC9000DB07C1781E165F8F9BAF27DF4FD793401E
-:10BCA0004E5FC5C7BDEDBE0F0F4C02F8AF64265204
-:10BCB00041F86DC169984781767EF3F816F447E143
-:10BCC000B9D3CDEE437B2AFBF0DE9195BF833A0FCB
-:10BCD00074BB2DF5CC7866DF9BF9E9A03CC72BEB54
-:10BCE000F77C0BBF1AEBE8B912F7770F7BEF9C10CC
-:10BCF0004AB74E7C065465EFC446F477C9EBA1DE23
-:10BD0000188F5B013CE81CFD870A80CF3AAE2FDC20
-:10BD10005C4ED05EBD39AF17F58539CD5C5F90FCC8
-:10BD2000ADC06453B7A693B506FD0143FCE188B1ED
-:10BD300099EB0BBAFCE772BBCED7DB867215F40326
-:10BD4000835CADD5985C2DF031B95ED746C75139CB
-:10BD5000325719F51226C7D54D5C7FE07238938FA4
-:10BD60009BD5C6E45526E8115E083FD0502EE35916
-:10BD70005E765C6F1956CEE46566E7E328D75E0110
-:10BD8000A7CB04E01B4C5E8EF8CDAB1A80C9473FB1
-:10BD900077513EFD142FF729543FCB88EB676B4456
-:10BDA0007ECE44987E88B1F5749E8FF1FAFAF71D25
-:10BDB0007C7E8F1FCAF806F0D707C345E36D06BA2D
-:10BDC00045AF27CDE757B273FAFC06764EEDF1CFBB
-:10BDD000DB69339C3F34BB99BDD9ACE35543D407F1
-:10BDE000FDE2FD40E4E3EC7DA976FE1E946E5F7DEE
-:10BDF0002795FB3538FE2493273A1FF29080B79C95
-:10BE0000C2F7586427F26B8DDA4BB0B663E1A6DC5B
-:10BE10008540EFE1AB2B61FEEB27FD15E32E0A9287
-:10BE2000D88B7F073B93C1E14BF175CFF457991D38
-:10BE3000DA2B26BC2733D123E13C7B24920AF07411
-:10BE400085D9FB84AE8972C2FA177A18DF943DEC6B
-:10BE50001ED1FA493BF17E6352F92C11CD96409EDA
-:10BE6000EAF2B613F6793221D5EE59AD1AF2FD4851
-:10BE7000D086FC95A0DD19E6BFFFA295C9E837EC96
-:10BE8000B4879DB01F1B2AF9BE2ACE6EB88FFEA5BF
-:10BE9000F785C203F6B93D2046E07E793BB554C72D
-:10BEA00032BF0EFE7ECE096ABF1BCF292EF3881C3F
-:10BEB0004EAA08F189056D0CBFD64F92711E6BC753
-:10BEC0006777DB0A8DFC97C12998CAE0B476D28BDC
-:10BED000885FE73BBF790D774E3E6638473CBEF939
-:10BEE000A1228073FC9D96C090F717E635FC66F2A0
-:10BEF0008E04E70303E56047B9C10E8C5C6F3C67B5
-:10BF0000F9770FB3AB431EB3FF0EF8AB1D8D8B4813
-:10BF10002EF897F65C12F1A2FF7E313BAF5DC0CFE9
-:10BF20006B4FEEB806DF53184BD1CA9E60DFDF6F50
-:10BF300034BFA7F0FE830FE532BF46C414E7B160FB
-:10BF4000E73363D8BB661AFF9D0CA26655B177AF85
-:10BF5000514EBFE8D71CF8EE5C10F9900CBF5301AE
-:10BF6000FE76A0E062B8D7DF83A91BE8B778F07B44
-:10BF70006E19540D43BB8B0431CD26F598FA481841
-:10BF8000D35CD283691ED8B9C52017FA31558922EE
-:10BF90001203DF2F227ECC979020A612EC5B66FC6A
-:10BFA0005C42DAE5C4F80B38BF00BAD7CF29F4F306
-:10BFB000FD199EDA4E0F327BF379C5524F609D0713
-:10BFC000E11F45BE3D87B3F0C33F1ED303F77B5649
-:10BFD000AC63F74B74BE8E760DEDFFD10C2607B423
-:10BFE000BB05E45FAB53AFBA14E1D8693F6D3C6F5A
-:10BFF000204E6709FCFE8BDEEF1CEE5F98C3E51F49
-:10C00000B8B7D9FD3B3FDEFF99037E0643391928B7
-:10C0100067F7AAF57EC4D42923873ADF33B4C778FB
-:10C02000E45A8BFE7F4EB96DC9CFB5B6FF8C4E2852
-:10C030003BEE877BF452359F9D3331B94D1149C595
-:10C04000766D8EB7D10E0B5F1630C2E510C77F5DDF
-:10C050009ECCB5F8F5ADE95C89D385A51F2AF9D248
-:10C06000E15E04BE6962A06BFDDD5BFD77D2160464
-:10C0700042720E6BE6C3773DF8BCC3646B4D0E4D48
-:10C08000DF83BCC19F7FD81BFAADC7608728817A48
-:10C0900091BFFF8774388FD3E165B6CE6AE06F2712
-:10C0A00042C40FF6C30252BF1EF431F2AA0DF9DBEF
-:10C0B0000574DE7205D86F44133330AFC1EFF97CDD
-:10C0C000D0C8EEE51CE7EF56EFE4EF249DE2EF5415
-:10C0D0008FEDBAE32AC08393FCBD6A9DFEF571C75C
-:10C0E000F6A4CE06B93FB6E7923AA8377697230A68
-:10C0F000702EDBD71E04BF10BCCF9242C7C9A3E38A
-:10C100003933808F1094B7A73A5322ABE93C4F756F
-:10C11000D9902F7F5C2EE23B23F0CCA58DCF2F2D25
-:10C1200003FAF9FB8DA0879CE47C447FEFF154B5C2
-:10C130008AF6F10B7BD608702FE1D46C15D77D2AD7
-:10C14000A7273F83C2C7E765F1E525BB1DD1223A8A
-:10C150008F858FBC5E540BFCAF28BC30D13973BACD
-:10C1600097F1BF534F108C873BE5E2BF4FE4ECF1F2
-:10C170001AFDACA95EC164179EF2F0DF39CA3B47D5
-:10C180003D1E5F4EDC3D5E46F73D5E388FBA37F5AB
-:10C19000C7787FEDF813EC9CE285CD75F9E08F1A36
-:10C1A000EE55D939FE9E9F60DC38AC03EC683A3F0F
-:10C1B00015E6776FEA5B27C1FF40DBE1FD0CBDDDD3
-:10C1C000F13D75AC7E17ADEF45B8136F05E0038305
-:10C1D0003BD9CDF884AE3F2E8A64E3EF2DC4CB4526
-:10C1E0002C8729BA28FCC7EEBE1ACFB5467B3398F8
-:10C1F0007C507AC6CCC4F987F3611D7B2E09E58398
-:10C200001FEFB8FE7B4E52381FE030C3131AED35D6
-:10C21000F0F7F7DF7E0AF97B9958FFE7BB002FF7AD
-:10C22000B2DF1FB9E3CD8DA2917F4CF432FFFABD8E
-:10C23000A94BBD701E757CE09D9C308BF7D9CFDE7D
-:10C24000615DC469EF7837B59F283CDEDFFD032CC4
-:10C250003F3EF08E4D0FC693BDBFFBF90C486B7986
-:10C260003C3F895C83F445E1D2E64C20AF06EE45C5
-:10C2700045D87DB733027F7FF43E1D6EF5F24CD377
-:10C280007915A3EFBCAD8587505F8E24BE276795D7
-:10C29000F7D6F764CF750FF828A7D363FC9D92A556
-:10C2A0009ED0B7BD09E4486DC7927C80732DDCA990
-:10C2B000C33887AF5E0EF636DE3761EFC946114EE2
-:10C2C000FA7BB1643C2B4F67F9C5DE2BD7804E74E7
-:10C2D0005C7F7F56FB1A2B2F64E56DBCFC254F70ED
-:10C2E0002E1B9FBD2744B9623AFC2E85CEFF92AF2C
-:10C2F000DFFCBB143F029E3C01FB5B8AFD49B4BFDF
-:10C30000B1FF7A7F3ABFF997FB71FEF7F6A3F361AD
-:10C31000A04B08D9237EFF98FF0EF8FDB3EDC9AC02
-:10C3200002133FFF6473712B9C037DCCDF0F71748C
-:10C33000AE2220976EDEB4D1F4BB26D677BD9A78B4
-:10C340003C895C4CE9CC40CFFBBD4C8FDECFF92162
-:10C35000FCB90DEFF9C05F673686DCA0FD378ABFF8
-:10C36000F35E46C2A85F8D213D9896935E4CC791BF
-:10C370007E4CF198B4185C7D7E1B7FAFB70A16BF68
-:10C38000D819BA1F42753F75849E017C82777B0560
-:10C390001BE8454B27C3FC7FEE55F4DFF52496DF01
-:10C3A0004B8BFF0E880A7ACD0CDF507A0D51A4D347
-:10C3B00003F11B45F8EEEF0B5EEC37D9EFBF2DB75D
-:10C3C000BC7FC2EE11EB7058427A300EE285AD2B85
-:10C3D0005E1E4DE1BF70B707E5C1C8ADCDF8FB5F8C
-:10C3E0000B496F36DC2F1DC9DF93205DECF785F418
-:10C3F00077224677394CEFD42DB1FCFED022FE7B5C
-:10C40000618B2CDFF5FB9B1DF021411C81F5FEE7C4
-:10C410003BDE24EF369527FE1D18EBFDCFDD3D22D8
-:10C42000C6F7AC80782121CEF746EFA87798F1AB1C
-:10C43000E7D212C3FB4E4D829FD9D39E94C083C2D4
-:10C44000E071462A0CBFF60842C238B26FA6897C5A
-:10C450001F9AC995B49FA6C59202F666532405CFCC
-:10C46000419B1466175EE0A971829D4ED2457C47C0
-:10C470006E9A6D0AC697CB4BA48BE0DCF3D0F685A1
-:10C48000BD707FA1C927A19FF68274760E4A7244BF
-:10C490007C1FA059D99B3E07F6C9CDCE1947282449
-:10C4A0000271F007BA6F1721DF44CD96E1308E108C
-:10C4B000EAC57B373912E1E7AF33C653FC2BE0F80E
-:10C4C00020914EBC7F3C75C93117C8F502BEEF13F1
-:10C4D000D20A99DF98EFE7B686A3E980A72F75B750
-:10C4E000FE761AEDCF1E9130AEB5ECF3A637A6D18D
-:10C4F000F1FABB658C67D5E190BF5232DD9FCDBBB1
-:10C50000D59C972DF788256228A7F9517C7C78C0A7
-:10C51000296A8CABCA0A3067A1E246FCB8284D20D4
-:10C52000786EC3F3A3214FF174973D5C03EF61EE86
-:10C53000FA93807E8783DDF30A304EFF995001E045
-:10C54000B78E0FD6FDFB1BD7872806B8F8FD6017FE
-:10C550001CD659F1A7B99194823FDA193994722106
-:10C56000ECE3613BBE23D5C2F56F89FF4EAF8E2F42
-:10C57000D6B4C582772D9F5F8378D74FF16EFB10BD
-:10C580007827292AEA09F63CE207F2B767F5E62A96
-:10C59000B4DD854FC97E3705D9B4C7CAD3409FB92A
-:10C5A000F0F9EBF09E2CC00BDF796C904BC1EE776D
-:10C5B000346495C2EF1D4D7BCC8DF878D6CDCE7FFF
-:10C5C000A486543F94377557F954035EB7362AA5AD
-:10C5D0005229BC6FEA2C85DF456A4DF23BCC23D251
-:10C5E000C520F897646EFFCF4B63F39D97968AE959
-:10C5F000CD3C7F9FA4CD84F9DF47F107E2050EDC37
-:10C60000CAF077458E13EF3DAF78A978F8507140A6
-:10C610003B1B7DA500B7ADB7D6A2DFA37AF921D722
-:10C62000E540E71EA702F868F38EBC770AE0FBCB73
-:10C6300076BCF7D5E4A952E718FAB37927A25FC907
-:10C64000266AB96014DD9976E4722907F045DB02A9
-:10C6500092A869C373974B943FEDF268B9022DEF2E
-:10C66000D8F03CCB0FD3B608B4FC071B7EC1EA8FD1
-:10C67000D072E1973F7EB4E13F5879A9B605F20F39
-:10C680006CF835CB836E41F5984737FCEE72B82FC6
-:10C69000DD64F7CF02FFCE8FE9FCCBE9FC7B78BAF3
-:10C6A000278DF973F4F2BDF09DC27B1F4FADE54FAE
-:10C6B000F2764F2729FF292FDF9FA4FF9FF376D122
-:10C6C00024ED0FF2768792B47F91B73B9CA4FC6572
-:10C6D0005EFE4A92FE7FC5DBF52669FF5BDEEED586
-:10C6E00024EDFFC0DB1D4952FE062F7FD3D2FF5B36
-:10C6F000BC7E1FFF9EE7697B43A37897D7CD5EF68C
-:10C700002CF3B4A1FEBEB5BE12F1BF6902D33374DF
-:10C710007CCF83784D9A2F52585C5591C2ECB85F0C
-:10C72000F0FEAB97976C00BC5BF14B1BCA532A47DA
-:10C73000F0F774B5E52CEE65C54BEC3EC88AE51202
-:10C74000BECFAEE3E32F2CF3DFC6E7D7CCE7FB5C2D
-:10C750005A113F6FF195CE30C67B2AE6BC93D213B7
-:10C7600084EC346731F952B6BCC6390AE407952F18
-:10C77000C0375BDC7214EED1B72812963767D52824
-:10C7800050AE2912CA9F96AC1AE71CF4E764A07F4A
-:10C79000A280C7ED352B12DEE397D2A762F9B4C7AA
-:10C7A0006628C0479B497F3ABCCFA7AD94F0BCF642
-:10C7B000407D0D7E2F48FF281DF8F38174B6AE43EF
-:10C7C0009E175DF08EAB749B88F26224C08F8E5BE7
-:10C7D000B4528CA8B4CA21658508F9079A99BCA2FD
-:10C7E0007F9EF186771477DD5EF532C4EF34AD932A
-:10C7F000F077B6E14F32C88312FE3BA5994A8649CD
-:10C800005EDDC7FDB89ACF8971782512F1197FBF17
-:10C810003253E1E769B619F88E5971D82C9F0ADBBB
-:10C82000CCEFD81458E493555E8DA8A7FCD150DF07
-:10C83000E1534CF9CFD3F87B167EE2077D66C5E362
-:10C840002B2E8750769D5FEBF2E5BF005F71521291
-:10C8500000800000000000001F8B080000000000A6
-:10C86000000BDD7D0B7854D5B5F03E67CE3C3349E7
-:10C8700066263393C97B1220040838811023BE2614
-:10C88000216044B403A2E2A338E11920C9044A2B71
-:10C8900056BC4C48C440B186DB8840810E2A8AF5DC
-:10C8A000D1A1458D18EC808878ABBDD1D25ED4D6AD
-:10C8B0008EC855501EA3B648BDB5FC7BADBD7732C2
-:10C8C000E724516CFDEEFDBE3FFDEC619FBDCF7EC8
-:10C8D000ACBDDE6BED3DE7CFD3BF2B09695D19BD64
-:10C8E00062A89E902D2B4DC314FA6CFD72DC4C5245
-:10C8F0004E4822D5E27F482264F54ADB3065182194
-:10C90000E779FB621B7DE92264AB129E4E9CF41911
-:10C9100051484B2121FB96C904CA4BB34C11236DDE
-:10C92000B2F4D5DF5D3D1CCA4B641FF1F67DAF7DCF
-:10C930003EBAD2330CC67F259D60BFFAA034ECD836
-:10C9400038FA6F25E809A41232A443391A3711FCCA
-:10C950003B4FFF2B6CA7E592BEB25E1FB0D9AC84F3
-:10C960001490A476743E8AA6AC771DB6074BA17FBF
-:10C9700005FBD7CE23AF99AE3FA95FA3C7A62AAFC9
-:10C98000969A4BC810FAA47305F8845D7264075D2B
-:10C9900067EEF2BB261CCB2024E7A0A58DC01A3A77
-:10C9A0001E24C44D880EC6A6EB5624BF97E808691E
-:10C9B0002B2CF349F479E8690B83539E15E16490BD
-:10C9C0007C99D7D0A7510ED8A07FFAE787FEEFCD8C
-:10C9D000B36C5F5B08C5A009E090BB9376984D8B64
-:10C9E000E1DC35FEA1749F28B8C904A8EF69F7D32C
-:10C9F000F5EF947ACBB5508E460CAC3D2131F8BFA3
-:10CA00005DB2C4EB895FF110F29424F1FA91B5356F
-:10CA1000B9B4BD621BA5F80899DD31BA5D7F39D480
-:10CA2000CBE27B3FA9A4EB83F17819E0F2C4015E6D
-:10CA30001FBEB4BD86CE6797418C4FC2D07E972C67
-:10CA4000B372B8BCBDE632DA5F35FF3E9CBFC69F0D
-:10CA50008BF3B9466727A4D97665BBF592BEF9B6C4
-:10CA6000D827B5B728849CF2C6D3E87691C6EDC71F
-:10CA7000DC8476B57A6630007024C44702A309F9D5
-:10CA80006FC98BF822F64FBFBB2A9C435F9D39F8D4
-:10CA9000455A297D8674F18329147E8D5D4193BEAC
-:10CAA00088C259EF0FE714F67DD7B87B1A095238C0
-:10CAB00085BACBF039C0778714F99FFACE64B88075
-:10CAC000F14EC5DE6C7A925635EA82EDD621D89EBB
-:10CAD000B0FD1F787DE2FB534FBE79238C77DA1BC4
-:10CAE000774F01BC8C51B80CF09D68DFD4554500E0
-:10CAF000EFFF62F1AFB48D27E4263BA333A234FBF2
-:10CB0000A07DD4D461F3D17AB3BE23E0A3EDE9567E
-:10CB100046E4CABEE72ADB506CAF7DAFA59FA8896B
-:10CB2000644CA5781D6E507C3B0894C329636879DA
-:10CB30005DA332AE854E6955D91FC69642F9192BB1
-:10CB400031D2726BC3014F29D091CF40287B21EBAA
-:10CB50002E8966011DB7351A663E42E7138D2DF505
-:10CB6000CC2BEDEBBFC54E098FCE7FCDCB94CE2E17
-:10CB7000A24F7DD42EC1F7C314027468B6D37DA62C
-:10CB800065739683840BA19D751DD0E31A7DB0B6A5
-:10CB90001ADA65C964071DD73C6C466D359D87C799
-:10CBA000254B3A9C47CD91F9B4BED56600CE467E62
-:10CBB0006B9FBD13E0F484E26B063A7CC26AB585D4
-:10CBC0006905E58D7EA05B6598330265A38E3447C9
-:10CBD000E9FC72CA48206AED9BE76F397FFCADCD56
-:10CBE00080F35D678E4EABA2FD5896CAB6301D6FBE
-:10CBF0004DE3869EC9749C9F363EFB460B7DBFD697
-:10CC0000AD109887D5A9C40C69148FAFA573A4F390
-:10CC10007EAA256003FE997029E4215A6F196A20C3
-:10CC2000DE243E682DA5E524FE94E154FC66FAFD61
-:10CC3000497BF0D7363AFEB8D70F9BE07BCF7859C7
-:10CC400006B2892A6C9FD3CAD5FDD82E53F7E3A824
-:10CC500051D73BA7AAEBDD33D4F59EDBD4E5ECB985
-:10CC6000EA722DE0DB786848E75C41D7C1AA8825E5
-:10CC7000FEC94A9286F0790BE06F29967D001F73FA
-:10CC8000E323C7E7D3FA1CE02774FE640C89ECA009
-:10CC9000FBB93FFF87DE3885B3D1D1ECB597F68776
-:10CCA000474E9EE91AD82FEB50C546687BEB1F4FC5
-:10CCB0007C09FD5B4952BB42808F3F0EFB0B7F1E00
-:10CCC0003A9F54F88717E0DDFCE7BB41EEBDA1F3C6
-:10CCD00001BC731A151CFFBE19DE88AE903527B44F
-:10CCE0007D1A6F9F665AD7A31B439F7F5CB34497FF
-:10CCF000D61FAE6ED22C015D52FC407941EA08CAC3
-:10CD00008B7B65520F7843C995407F36F880F29946
-:10CD1000890E03E2CDE71C7F28A6C950EFB6B13ECD
-:10CD20000D5973CD40CFF71C64F87F8F81F5D3DBAD
-:10CD30009F17074511047C52679755FD6CB0F1367B
-:10CD4000BCECB2B3F2AE038E6B802E37CC708C0588
-:10CD50003C31CA2408FDA5E79AFC23E8FACCAF1AB7
-:10CD6000C212ED345D2107F40EDADE426E0FD07987
-:10CD70006C3A6409EBE87BF3BC7FB711E01B7636B5
-:10CD8000EF5DAB7CBF033E90A853108E6657876D56
-:10CD90006C295B4398CECF01FFA0FCB16A58A70D68
-:10CDA000F6D35CD581F2DB5CD6D10170DA3455461E
-:10CDB0007DC23157467C36E745DF184ADFEBE7C9CD
-:10CDC00036E8CF4105BB8176F293DC8E4000FAA5B0
-:10CDD00030972B18AA40BFB8423A4E0687ABD3B95A
-:10CDE000FB0E89F69301FD8D61ED014E760EA75283
-:10CDF000BB17F1D3C9FBCD184ADB8F61FDB455F4E5
-:10CE0000F523F671532D89C0FCC4B8A29FDEFE89BC
-:10CE10005F02BEAAFF0D851BDD2729DF8493BB6758
-:10CE20001189180B013E81E6ED48D756F210D08BE0
-:10CE300033B71AF028FBD0E6E9F218F8CE82E3E81F
-:10CE4000E79108E071B6424C5738407F09201CB585
-:10CE5000F49A75A0E37A4A23BDFBA2A5DF2C85B422
-:10CE6000EB1CFDE938CBE9AC2E1E33003D6BE82509
-:10CE7000EB50E2FB80F45ABADE9672BA0CE04292B2
-:10CE8000DBEBBEBEACD345DF980C9B9549E50405B2
-:10CE90007DBE663C42FE6184B24464EFF921C0F776
-:10CEA000ED8C7F102AAF28B1EE1A6B9B68053A5DB6
-:10CEB0004210BFAA9F5B77CB6F687F6787196C2092
-:10CEC00057F20E75F4807C245DC1E1B00F5B94E0F5
-:10CED000CF5268FD96239904F8F61A339909F8ADF4
-:10CEE000703CD7CA97164E375E90739E7FFE29F42A
-:10CEF000C1E850F7281BA5BD96F5B14326D7FFA280
-:10CF00009E4586A19E957BA0A7C50AE377F8DB4DD9
-:10CF100014BEE6D759FB302D8715805F4301D0E161
-:10CF2000FEBCF90827E56D23013C1DADF347A04C7D
-:10CF3000DE3113E0BF3B9FB9ADDE0BFCC73DC50B37
-:10CF40007CE8DF81DE29BC3A38DD6BD7AF18FC41C5
-:10CF5000D027B4EFD7027C713F03C7EBE83E8E7E4B
-:10CF6000D840D6D2CA1279767B21D0C51ACA7F6939
-:10CF7000ED6C9DB7E94752DFFE3C61AE8AD8C1EE49
-:10CF800058692241235DD73989042971E639DFAC1C
-:10CF900002FE934F6212C8D9FC66AAF0025E2DB35E
-:10CFA000906012BEE79E53B0FD13667FC4CEF9BFFA
-:10CFB00089F2013DFB2779C21120754EC6A3407F3F
-:10CFC000D13F69790FF80671D6F87BED8D22C05FED
-:10CFD0002AF7E9784FF1F5EB290CF563E97F56392B
-:10CFE000661CD3BFFD2F397C14933506FC52B1BEAD
-:10CFF0007604F98B4D3999DCCE1461F2863490C8F1
-:10D000003089C105CBDFB3613987F25FE358D4FBC8
-:10D01000C34698671AB33F88DFEF75BA815E08028E
-:10D0200039D744DA4DB41D623BA5B72CD26346BD57
-:10D03000F900F1023D5088D93F4841964500AE5B6A
-:10D04000A8884EA603F12CB2B17D5296EBD05E1AA1
-:10D05000F59219E7A36F261133E84330370A6F655D
-:10D06000198928606F2D3760BB229B17BF339066EC
-:10D07000D4679FFAF2DD6CE0D39683541FBB08F6A9
-:10D0800059463E65B1A8E98F62287E17E7F8B17569
-:10D09000A50DF7B9D73E0B1EE6FB1C6F017991BFBA
-:10D0A000CCA1DA5FD12EF75C0E098E4BEE3782FDF4
-:10D0B000E50E3D209152A8CFC7FAAD2BBD5FD37FBF
-:10D0C000D120FD67211E0DDE7F2ED66F8D1DB65F30
-:10D0D0004741B12571C01EF0F6E9D75A38E72E5303
-:10D0E000F3E58BBAD4650117B3DEEF9C46616EFEA3
-:10D0F000BEECDB4EFBBBF888BA5D6DE1EFD1BEED57
-:10D100006B1F735E0FEDA9FDBD9DBEBDF4B8BA7D6A
-:10D11000A0EA653BD0715F7B36BF2BCFA9DB69F7F7
-:10D12000473B5F3A2FD70D49F39A6832AAEA67D690
-:10D13000F59B97EBA6A4795DE551B70FB60C3CAF14
-:10D140006B4A8C5F392FD1EE3B9517D64EBB8EEBD9
-:10D150006B8D83C09DB5BF69E685F57B6BFD57B7C9
-:10D16000BB7DB9769C30F2875AC93FCE41EB67C38D
-:10D170002BD017AD16D47BB5F812E1F26902E87333
-:10D18000F43935D53FC1419F954077F46978FC0F5C
-:10D19000B7007F39F4F4C84CE0EB3920E7109ECC9F
-:10D1A000AFB0ABC1837E8500A7532A4FDA805FEC16
-:10D1B000DA49BF4B63F34AD69F321A985D6123095F
-:10D1C000A467A12F39884D62F638D377061B47DB59
-:10D1D000FFDDDC1E98B37C22799FD2E1B3065B951C
-:10D1E00002F6D93609F58139357E5D2AC58F09EDFC
-:10D1F00012FA8DE6DCF9BD71C0572E39E6ED8AD3FF
-:10D20000F77322761F0CDBD443FC118A5799BA2599
-:10D210006577D3E703FBA9FEC3CB4B00DFAC7E2FC2
-:10D22000D81B753023DACF497D73990DF8E677ADB9
-:10D230007EE09B7533FC6FE17AFF4EB512DA6E1E0D
-:10D240005B3A79AE739AC14BF58CBADBBC95A0F70B
-:10D25000D445CD7E7C9A8862A1EBA8A3FA183C3312
-:10D260000D4431C3D3424CF0AC58C5F4AFB4CA80BE
-:10D27000A18E8E5FD7FDD85FE1BB054A6C1FD32717
-:10D2800023B8EEBAEE57FF06FADA3C7FC000FC6224
-:10D29000D44E03D349393E8C8EAACBC00F92CB65B6
-:10D2A000317579DC2175F92D07C38B3D526414EC7F
-:10D2B000CF1E2AE0C02E0E3F654479B17FAF11F733
-:10D2C00067F1C796EDE07F9AB8D88A7CFDE39F9B13
-:10D2D000D11FB5478E3E0DE5F0D3296857EF7B7B14
-:10D2E0004F8544CB8B7E912A43FD0B5FEA10CEB075
-:10D2F0001C3D7DBFF8E911DBD7D2F78BC7452B6CFE
-:10D30000F4FDB32309E9817A253206D6F7EC3F74A0
-:10D31000D87FE27163E4218A0F1F3FFFD8D377D112
-:10D32000F13F7E3CC721D17DB914E4016D37E16145
-:10D330009305EC8C091F3F3904F8C5E29D46D5BA28
-:10D34000B63A24AE3778D300DF06F3271E5DF31814
-:10D350007E5F72FC08E2DB1E7D58B6C0FAD730FC57
-:10D36000D2B67FC4C1E48D98077C5748F7E7CC0953
-:10D37000CBED7E5A1EBE510DDF111175F949079391
-:10D38000EFB349D2FB42E8AF68B507F4D4ED04F53A
-:10D390009992E37FBCA510F46823D31FB4F3788679
-:10D3A000CFE3E73FA7FD30FEA063FA335D31A5C7A9
-:10D3B000C51C8F5F9098FE4AFF96E550BC5D0C82BD
-:10D3C000BFA8EFFD62CD3C44FF4B1C8C6F38B95DAC
-:10D3D0009D785D87FBF1D1CAFA71C786F59FCF07AB
-:10D3E0002B9B47D4E8FBCAF3372E399845BF6BD83F
-:10D3F000E5423B51BC6F78FC25F7ADF4FDC99D8A31
-:10D400000F54D7869B1FFDF10468F7B82E0AF385E9
-:10D410007AF0479E8CBE9C06EDE66FB18FD525ED68
-:10D42000C3828DDF1F5193C40FBF293D08FA6DE001
-:10D43000F6ED73953D937300BF374A3E68B6387A70
-:10D44000C3F5D782AEB245E71B46EB2B1412D08D45
-:10D4500045D37B063C1B763D73309BD687F68EAF5B
-:10D460008075AD9503D78C06FCDFA6473F96162E38
-:10D47000A7F97ED3EF6332FD7EED8DD6FA8815FBDA
-:10D480003D00E5FD250FE9E2E067394EF9137B7FAA
-:10D4900044A63479BCFB9E31E04FDCA3B7B6039EB3
-:10D4A000EF4965FB107E4A877C9EC4D83A2670BF40
-:10D4B000F1E23F751A14FA3C7E7C555A15A323E419
-:10D4C0002FC0949D747DF50F8F46BA5BB0514D27E8
-:10D4D000A29D98EFC288BA5E8B1F6919C2DF404ACD
-:10D4E00092F14CDB2E636AD80074D5B09CF2E32431
-:10D4F000FDA7E1588701F426ED38A00112B1AF3A3B
-:10D50000C44FE2C5F59AD97AA9CA6AA2EBFD08FE12
-:10D51000C5FCDE12D8E58B245C22593C92D47829D4
-:10D520003C174F27B5F0DC23C57EACE3FC0CFDEFC8
-:10D530004FA5203F3B698B3FFA53C0BF27F37C6167
-:10D540005A95CDFD7227BDB134077D9E01BA00FC0E
-:10D55000B3B1F2A26ECACF297D7F7CCA807CBD2583
-:10D56000FA521AECD7C9A7CDB24CF7E5E35D19D54D
-:10D57000E0CF3919FD4D1AACEBA3684635F8E50646
-:10D58000E3375A3E25E4F97BF0CF4B287FCEF08F6E
-:10D59000C900F8B66580324E32339ACB9A07A07F25
-:10D5A000F19DD3D05CE605BEF15DAB0FE8F3D20C84
-:10D5B0002FBEAF93587FF0E7A7F59F1ECA7808F6F5
-:10D5C000FFD0BEE27490F39F126F3AF0DF29AEC035
-:10D5D0001519948F78AA7BFC3AF0FF4D21BE56FABC
-:10D5E000CDFB3ADF0F6C14CE7309953BF02C0F1A6C
-:10D5F000D05FD2E6C279CD51484CA1783A07E4E237
-:10D60000182C239CE76C9122AD741E73D7A9D739CF
-:10D61000BFD3D8B7BFF4BF8584324620A02D49EDD3
-:10D6200068FF0B41FE51F82D3291580AED77D12356
-:10D63000EAEF169318CEA7E1C9F3C681E0F8570EBA
-:10D64000C7292EFF4D192AFEA547FEB59804AE80C6
-:10D65000711773393BCFB80FE711BAF3CE1173A925
-:10D66000DE7066F95D23E666801F907D47364A8846
-:10D670007F8B6B482C8FCE6B71B7141B0D7AC061FA
-:10D68000B63FA27FB28DB5BB85EB29F3283C40EEB7
-:10D690004F78520AA7523B669E899A60C03FF8BAFB
-:10D6A000A03E9D96EB4907AEA791C4711EDFE3FB38
-:10D6B00007112980E75F0FB37D9B50BF5D07933A49
-:10D6C000B4AF221DF0EF33E2C3FDA3FA04313BFAFD
-:10D6D000E307C0DB9F049FFA2DEA327924A95C049A
-:10D6E000F0A4E5243837ED3E6FF40F00DF077AE54C
-:10D6F0004964C4B4D1A49FBEFA2E87FF0337CCCFB0
-:10D7000002FABF1FF4B76CDE4125F04B22FC113149
-:10D7100013EDDF328EA8FC13542FC272C74F5EB9CF
-:10D720007A632E211BF441F4F3CFD1050E4248EA6F
-:10D73000842BD809F83A47F6E72BC807FCC568A739
-:10D740002E67FBF1E0D8E611CD03D8A762FE1BA43B
-:10D75000684C067EF03C93EFA9E5097D3089BE9EBA
-:10D76000E6FC2D7D7FFC600EE0CD3312FAD3374905
-:10D77000A44DA270F6D06D0139B0497AEF20C88D62
-:10D780004D577B492BAD2FDF3D6DC9CB68E35A7CEC
-:10D79000109F68DC5DA56BB4E2FA999E99D2BC5DDE
-:10D7A000A6F599B7978C05FAA0EBBE7D3A7DFF2BC5
-:10D7B000BEDF5956860F9E55E1C2A5E04FDD1F58CA
-:10D7C000F232D0F5680BFAAD3229AC521DF86C0775
-:10D7D000FDD1435A2468F7401AEBDF25EB6E9F0614
-:10D7E000E5B1ACEC5821F91F42245E8FFD671AA900
-:10D7F000C9E060EF410FA6DDF977617D04F72D7375
-:10D80000627319F49739843D9D86582EF4F39AD8A3
-:10D81000EFEE2C19F8ED322E3797EDAACA74D0EF3F
-:10D820005F3B6952800FBEE6117A5CCC0A7A1C1904
-:10D830005AC2DA73F9B4AC6C6226E0AF335FDDEE46
-:10D840008CDE9F3E0EF8FC1B3A8CB7FCC5EA4FB746
-:10D85000D376971AD83AB4FBF8A70CA6D785CE4949
-:10D86000249264B787669E45FD38744E51BD3FB91A
-:10D87000D2442249767B43FDFEC9D0AE91F4AC067A
-:10D88000BC6A8CA69048129E5F6A19785C81DFA101
-:10D89000733A121E87E89B0BFEC5D7F489D5F300B7
-:10D8A0009FF64AE8070A517B389C3CAF7319249CC9
-:10D8B00031D03CDDEAF7743DAA72D7E7D88E54C662
-:10D8C000D3609CD3B6789A9DAF0FDA09B97526223A
-:10D8D00087F517617C8FC92FF0CF58997E3A0DF6E6
-:10D8E0005749A44D4FEDEB57D4437F8EA4759E9EB0
-:10D8F000692031DC97048E0B700B0F276473F727B8
-:10D90000062FC8F1EE7D0837812FC9F00B27C77BA2
-:10D910005A7B6232A5F9CC4ECBDAD21114F5F673EC
-:10D92000FA0E5BD7827FD1AD9355F49E52DE4BFF4A
-:10D93000C86E1E80E813FA2F53D7429CB9B7CCDBD0
-:10D94000F77E1F4E9B02F5E5A5ECFBC2CEF4FF5817
-:10D950000532887430BD5F49E4075293CA264DD919
-:10D960004ACBA393CA364DBD5353EFD1947359FBA1
-:10D9700093A9B17C9D8FDAB99D195314CA7F4E6665
-:10D98000C566514B94ACD3B9A7D4D072633993AB6D
-:10D990004DDD920F7D6E1C7E4D3EA6EF597D71C30D
-:10D9A0009C528043CF41E00F0D5D924DA274608D7B
-:10D9B000EE8A6119BEF3267D1795F0BB86E87BF8E9
-:10D9C000DDA0FD97C848E76B4B8EB276D10F517E34
-:10D9D000AF6EABC3B8B888FBEA48C09F23F5C57DDE
-:10D9E000059F3C9DE57F4966786D4BB68342D06FBD
-:10D9F00092BF45B47F6774F7EF413D4859F6490B34
-:10DA0000E8A17F6AFC703CE865EF7079B0418A8CD0
-:10DA100080713793E0089077DF6D1CB64FA6EDDE7E
-:10DA2000D5C7B7426C6B71E7A8290A6DF76E6A3CDF
-:10DA30004FA23CA6D15981F07CD715DF0AF07CC9F2
-:10DA400079312BE7C5F3645A5ED259C7DA0F8B6F71
-:10DA500085F226E7B5AC3C3A9EA7B38189731DC217
-:10DA60007F876D607A9EED647C44CCAFABC8FF5D70
-:10DA700027ACA781C991AD546F34517E396BD14722
-:10DA80004FEDA07098F5C314E4633B4E5E3F85E90B
-:10DA9000D5E18052017E53F687720EF9B5827A463F
-:10DAA00016C83647DF7EA4E6F778510E8C6CDE058B
-:10DAB000FA42E6AC529403A519FE0330AE78CECB01
-:10DAC000A64F0ACF034E1BE3CB3A19E3C89977A5BB
-:10DAD000A25E75BF99AD87D20DEEAF95EFC71D4E13
-:10DAE00026B7EE7032BBED868C49D8CFDB927F93A0
-:10DAF00089C2FD6D3D099B81CF2EB4A01E7CEB76C3
-:10DB0000CA3728DFEEE4F3EE5C9F158138F8AD12DA
-:10DB100009005F11FCA3D3EECF7224D9139D65B425
-:10DB20006CEDB31F3BA7F9B32C4E78BA6588970804
-:10DB3000BED459C8BE13F228B3958D9379FF888758
-:10DB4000601D290AF3FBCC9B59FC500BCAF5E9B8C0
-:10DB50007EE2F76781FFE0D8C22219FC41627FDED6
-:10DB60002AF2AF87F5DCC2FDE9629FC47E1E7032E7
-:10DB70007B788E8EEA0574BDFB5C415C3FD513C695
-:10DB800070BF13EA0907404627C19728F1F1F0FE5C
-:10DB9000FF23383DFB6DC0A97139E517F205F00B85
-:10DBA0000EBF0D524C9FC9F805DAC1F01EE4CEA697
-:10DBB0008CE07F3893F25266DDD5887AA19857CAF7
-:10DBC0001DCFD5DE44FAD399566F3B0CFBE5EAD363
-:10DBD0002F7DC27FC8C779F76D13C60BDE35449120
-:10DBE0006FBE4BED9816E02F3CDE5DF1C3C5AF81F3
-:10DBF0001D27FA9DE0D2617F6B247F16AC6F0DDD8F
-:10DC00007713CC7F9A01F57821573BED914D906FBA
-:10DC1000D079432EE61B9C212CAF23BC3C05DB5D59
-:10DC20002A1F25E08F4C5C62C37833C513ACEFBC70
-:10DC3000B918F33E283E84CD504FF109F2E33ACBB8
-:10DC4000E882A0BF9B47623DD8B9689FDE6CC2FEE8
-:10DC500006C013E6DF1DCEF21A3A0B391E2E2C42F7
-:10DC60003C74B7323F2251FC63A625C979B78BF1CA
-:10DC70008194F2F833FF0538BFCE8C7A29C8588CCE
-:10DC8000C57464627F74FFCF3B597C0BF16CEE8FDF
-:10DC900053791E99AF02E07A6F2AC3CB2D661627FF
-:10DCA000DA42F560E48B1C7F45FE5A90EB79F17AFD
-:10DCB000390DF4855457AF9FC00F763BFAA969FD23
-:10DCC000ECB8F41ED85DB3C3BA9811ECA8F649FEBF
-:10DCD00078921D027F1067BB9DF355B291A0FFEEB5
-:10DCE00076F82E0DFAB7A4415CF176F81EFCA42B51
-:10DCF00026A9E2670530E6F8BEF969F97E819857F2
-:10DD0000C783FEE47144FFDAFEA81DE975B910CEA1
-:10DD1000B174B0075A74B88FDA79C637327F737C22
-:10DD20006301E29DE86FB079FE5997F8BE44E5E0E3
-:10DD3000FC89CCBE16F6CB3C6EFF92156AFB0CFC40
-:10DD400023BD655DFFB2D6DE83B8B8BA3DD35B5262
-:10DD50004A13068C977825D5FC05BC0683C3E46F6F
-:10DD6000083721F71E34537EEA00335A42BCDD786F
-:10DD7000670ACA31A7213202F06A9ACB8BFD6E8600
-:10DD8000FC1494ABCCEEFDEC35E1AF50DBBB214B8A
-:10DD9000621BC02B646174747A6F2AD201191A9FB6
-:10DDA00005F95D67F61809E06F93142F06BA3E2D4A
-:10DDB000F9EBB05D4B8A17E8E97DB907E11D020870
-:10DDC000D27985C2FF837945A12EB5FD7B9AFE5796
-:10DDD0004FF1FDB41CAF807E043F00FA47BDA89E02
-:10DDE000C55B9A641206BBEA5279F64294FF376724
-:10DDF0009387F0FD7BC56047093E4FDB1D901C0CEF
-:10DE00006D805E1A38FC9AE4A3D8AE01F283008ECE
-:10DE1000605F815F0B2A93FCB14DEB3EC6FCA4A66C
-:10DE2000DDEA7D6EE8C303E9BC04DF25E105D271BC
-:10DE300098F301C2FC14352C5E9CCACB29B53D98E1
-:10DE4000AF14E27E0BD7FEF864E027A9E551329BC0
-:10DE50003E43C7999E31A17BFB4B600FDB6B7BF28E
-:10DE600000FD43DCAF27F659CCF392EEF5E8A7109E
-:10DE7000FA49929D3962BACA5FB00ABF03BB15C6A0
-:10DE80008BC3AB2CD87E26D73670B946E51FF2D7A8
-:10DE9000791DC351FE817C02BE24EC5EE053C01F9D
-:10DEA0004EB8AAB7009DB6B8AB1F74B9D878A8CF42
-:10DEB00083B174C9E0FE38011FD10EECDFAFF2B7B9
-:10DEC0003DC6F1D569E07C9730FFDAD2575DC2BF1D
-:10DED0008671B4A5923713F0F5035D10FD680B4809
-:10DEE00018FD3B0BC17F459F0D9CCEE773BFD07CD7
-:10DEF000EE0F02FF6C72BC0FFCA4C9E54584E12F54
-:10DF0000D969ECCB8301FF4D0D89A5D2FE1AC1BFA3
-:10DF100004CFA8FABB26926078DF75DEA88A277640
-:10DF2000B275DFCEF7DF5E13D1017FD864667E2540
-:10DF3000C13726AC60FEA7F4B1FEC27B00CF5FD52F
-:10DF4000A35FE2BFF9BE09384D71556F77D1F61660
-:10DF5000B0D3A0DD3D46E497C7A81CDEC5FD21D3A4
-:10DF6000C1FE5C191C0179DC44B1E527DBA7E2B9ED
-:10DF7000768FB91EF0E74D97ACC2AFD52E9677835A
-:10DF80007E22E4C729A86F53B63106F0ABA248C879
-:10DF9000433206FC53EFE9993FB7E9466B10FA8B21
-:10DFA000CB8CCFFC99F3B33FBB58DEE59F7BE515E7
-:10DFB000B7EF38FE88381DF86B92FDE41FF4B65FAA
-:10DFC000CFF36309AE77C3429E87DD8BC732F2A3DE
-:10DFD00094D200F2DD4BE56AE4478913562FC0A5C1
-:10DFE000F6E38685B08E4F675A08C4CBE672BFED64
-:10DFF0005948B873F5F969BF2E8E55BB7604F249BE
-:10E00000D1FE6F3027577F7FEF1ECEC7F61036DF69
-:10E01000709B91F9D7F9FCF71C1F19013CA67A6D8A
-:10E0200018F85C629799C93BAA87027FDDB37B78B9
-:10E0300004D6F39E9EE90B61CA7FD9F7C14DE00774
-:10E04000D9F34B970FF273428B3E1A03FAE39EE328
-:10E050003FFFD56FE1FD5EA30FECBD3DDCBFDE6091
-:10E060008815A3BECCF3121BD262C5E0F77981EF0D
-:10E07000578385964B4179083ADCAEBE38187C0749
-:10E08000EF8F46985E7E94303C08AF63F14A0ADF1A
-:10E090002C9847624D26C6D1605DB00FEFEF1D8D05
-:10E0A000F3DEA0E7EDEF63FADB515E3EFA7C19E6A2
-:10E0B000E99D091830AF36743FD317E7C8DE6DCB42
-:10E0C0008157BE9882FEC2799D6F605C23F4E305A0
-:10E0D00053A13EB468C575E42BFCFD205792FDD4D6
-:10E0E000A749221FEDE0FAA2688C8E7BBA7B848F51
-:10E0F00085ED3C18246AE2F99BC7287C61DE89BD66
-:10E100007A84FF85F60FEB05BB14E41BFAB593E3A5
-:10E110002A280FD47196AF2B9FD6C78BEFA4E3AFFD
-:10E1200070046BDC497A62E8C52CE477EFDFF7799D
-:10E130003EEA131D2C2E704CEF9F057462AF8919B7
-:10E140006627E95FB7B9B9DD61E47A23E583C9746D
-:10E150002FEA2BAAD574269EB7BA19BDA5F2387E30
-:10E16000FF7A91BF7ABD11E427732941BF5EECB7F6
-:10E1700080C7D7261C4FEC837CA8866819C6EF0A97
-:10E1800056C4902E29BC63A0FF1FDB94CAF8095D1A
-:10E1900026F433BF92A0DE3A5FC7F212E61BA91E37
-:10E1A000CCE438B6FF605326C2A16215D3FF12CF6C
-:10E1B00048C817459CB18EB0EF9F6B7B2FACA3ED89
-:10E1C000EB764A6594B592BAB62ACC5B58B4A510E2
-:10E1D000F77F02E7BF738CFEE24D806FCFA522BEB2
-:10E1E000D1F150DF6E80DCACB1C8970C200FEB771B
-:10E1F0004A642D498E8B6AF020A28EAB4C8832FE89
-:10E200000D728324E969420E81BC201AFD518D17DD
-:10E210006195DC6BE77015FC1F21F6157290EAD151
-:10E220006B808E2BAA19BD25764908E746D2CCE231
-:10E23000405C0EF5CE87CBB10F744C6ECE37AEC7B7
-:10E24000E73677218EBB08E225E8FF4F18802F0EB6
-:10E250008617DB06C10B810F3FE3EB68384E6297F0
-:10E26000D3F11A569058E318F64C1D837299C9677A
-:10E270001393CFF0B45C809CD6CA67AD3CD6CAE19C
-:10E280004C0393B7020F92FDF2A08F4C5811D1317D
-:10E29000FF6BAE0DF2F1C4BEDC90E17F227B7C9F70
-:10E2A000BE153A6232792F8272801459C1AF54552B
-:10E2B000914BD71FA2FC1BE82E85C2693B7DBF9501
-:10E2C000EBE54372BD081F0FCFBBD12B0152668512
-:10E2D0007DEA413B3AE12268D70AF86E4DA5DF8D11
-:10E2E00085EF183DF67E6F226D96A4EFABF798513F
-:10E2F0009E9C7D3E15F344A87C28B0D3FEDCEF50F5
-:10E30000FD9C964FEF4945F97E9AF37BA7F0579015
-:10E31000D5D8DF9BB0CF2EC0BAEA1CF0FB12694AF9
-:10E320000EB048A13736DA07F3D3F3FAC29E1B19B1
-:10E330009E1951CE9EB5C77F00653A1FCCEBFD0FED
-:10E34000BEEFA1DD13CBEE82787EC0EA63500D965E
-:10E3500081DE60D42DBB11FC4193752B1277D275F1
-:10E3600034E659315FB8A6E08F7FB899964FECD666
-:10E370001323ECFB8EEBD363F099E2F70C249F1789
-:10E3800046F4AAF3688B77AACB8D5175394492CEA7
-:10E39000AB51102CFF63D9150792F0E43377AA1321
-:10E3A000F7DF4B7C90EF4C74B7A50707E097E2F9D5
-:10E3B000F94ADF1507F4982FF6851BE9C06B00BDFD
-:10E3C0006636E0C300DFED7233BFA8D1D87C1CF203
-:10E3D000CE8D2F187D2DF4AB83EEA02ED305F64AFB
-:10E3E000E220ECA7B1E0E4189083D5057FC738D8C8
-:10E3F000D9BB890FE073D65C85FACDD94D662FD88D
-:10E40000659DF956E6AF78518A484C7F9F3ABE0227
-:10E41000E29EB80612DA78F5097648829864DC5FE5
-:10E420006ABD7880CFF8D19EFA609AC5B68A7E57C9
-:10E43000BF91C9DB06D293067CA03693E15D48F715
-:10E44000A4C144FF59D8E61FD142E7BB3860C1F3ED
-:10E4500031CA974A00F0EB5EE83249FF2FC8647278
-:10E46000A6D1143754C1F87F9F5BEB2AEAF36F19EA
-:10E47000F4CCBFA57495C572E8A70B96CF413BA716
-:10E48000378EBC89E5252DB8B30EDFBFB4C988EB44
-:10E49000FB60AF8478FEC156B6FE051BCD5EC89FFB
-:10E4A000BED2CEECD905F4BB81D77FD50958D7872A
-:10E4B0005BEEF0817FFE43C2C609DB981FEA431B77
-:10E4C0008B77435BE8E7C3DD43508FA9DFB8702A41
-:10E4D000E68B6DD5F9408F207B53D1BFB360EBF74E
-:10E4E0007F7B09F88FA6DF520E70B8D2BECC0DFE2E
-:10E4F00012DA2E10617A31CBC375543E0A7478E576
-:10E5000097137BAE047D692BA5934296E70E7AFAAA
-:10E5100081AD57A15EBA609AC50EEBF26ED9311982
-:10E52000E4C787D3B2655CCF5312B1011CECCBDDDD
-:10E53000F07E81A40406C2A777DDCCCF565560F5E6
-:10E54000C5E0BBDFEB104F285DDD08F2B371AB1EF9
-:10E55000F5DE03D3DFFEC3CDCE3EBA5AA0EBB871D1
-:10E560004292DE13DA72ADC01312AB007B8AC14453
-:10E570004B5FC68215C5301F2D9D2D58D55CCCE252
-:10E5800055DF8CDEC8164A6FA3A8BCCE94985FE313
-:10E59000C2E9AD3EF31BD01BC975A8ECA8FE7C2DCB
-:10E5A0008C7014FE7E938FF8775831AEEB9728DF8E
-:10E5B0005D9FA9603FEB33D9B920E56F4B77BE4E25
-:10E5C000E1E3CE0CFE3013F41FE22F033CF2266C85
-:10E5D000D570E6C7CAF538B285E9CDA0DFC37E6F36
-:10E5E000709147D726F91DEECB64F611A5FF56E8CA
-:10E5F000E7F45B7F3F08FBD3947F720C8B77FE05BB
-:10E60000E383D66E1657B6FA121837D73B03887FC6
-:10E6100082AF877C4CEE68D7753893D97321670237
-:10E62000FBF98587D1A1F0B76F5E6E413FE9666760
-:10E63000C4CCFC0A610272696AA58EC5C5B89E7514
-:10E640002DF73F9ACA5F22100F2397B1FCADD7CBAD
-:10E650005F523268F9B795937C786EAEFCE1F62292
-:10E6600058F7657A5E3F240CEBFE4F7F15D62FF5E9
-:10E67000E8BC40D753CB591E22A94F437FC9EBE5D5
-:10E68000EF3BE726CD3F404C5E2BC593E9D4C8490C
-:10E69000CE9BBBEE32B3D79A845F9F7648B54CDFF2
-:10E6A000F5A6CF18CDFC212887CBD5F058EA31E06C
-:10E6B000B82DEEAAA701CE575EC1F6E3A3A78C1131
-:10E6C000E07F1FF173285AF8EDCDE476E86D25AAB6
-:10E6D000F8BCD310CD07F9F8B1A4FE6E51BB0EE320
-:10E6E000E30BDB2512A1E37DF4F873F9C0C74FEC0F
-:10E6F000782E7F76D27CB4DF89E72B991C5FB91F17
-:10E7000050EBD71DCC9F2BDA9DD94882A6217DEDF9
-:10E71000CFD47F81FEDCD9DDDC1FECF70F75821DC5
-:10E72000C4DB6BFB4B70FC90BA24F477087FE6D116
-:10E73000430F43E4A477FFCCDD857272DEA1784EEF
-:10E74000E0FB763DEC1B5D8AB99D9507DBAFC1E828
-:10E75000711DC89FF17DFB76B47D483AC0D1D0646D
-:10E7600055083B0F56027AFA5662F1013D19B23D47
-:10E7700056E05FCB4D6963E09CCFE766F6745AE8DC
-:10E7800093EA6B79D925F8DD1D7200F3DB3E973BE8
-:10E79000F03CE01DBA66CC9BFE8CCBBB5C5B60D7CB
-:10E7A0007CB44FA298474DDAD5F075B732F991A8ED
-:10E7B00033A09C1270BE74F60FD04E1D607F3602DF
-:10E7C000DE6457B277A59E42AE2FC7314E60AE24AD
-:10E7D00036B0E75B2F09E37CC4FE84587322754B87
-:10E7E000A827437E4A8A03E3A161FE245607E98DE8
-:10E7F0000FA470BB9668E201946D85A19D9827B027
-:10E8000031C873B9DF1EED282EC7782AEA9FD02FB2
-:10E81000BC9F5DAAA03F1DDA19C67E3DBEF5E2256C
-:10E82000CF179C2ADED75B068C3F4C857337B47DAF
-:10E830001E9583A0FF119F5E75EE660BD59BC11ED2
-:10E8400013F15D9D1C2DF3A01DD21307FF88A1C2FB
-:10E85000E405B99AA28B96C0BE69E3BDB45D21CB35
-:10E8600033C8B5835C11E76A9A964F0C40DE7AAFE5
-:10E870009EB197D9474D7756E1FB89DDCC7F1E6A63
-:10E8800037E2B9C0509784F1AAA6802162423F8640
-:10E89000B705F62B4CF530B01B3BED2CCFA9F36A36
-:10E8A0009B2F4C92FDD7F16D77A1FFDA8A71BA7F69
-:10E8B000367E79269502E0A2A4F854BA89C911EEF1
-:10E8C000DF76737C12FB2FE859C43B534B0385A0C2
-:10E8D00071EF76DFFE1BCBF86F901742C6DEF7951F
-:10E8E000792164EFB570AECD04DA3CAF876951B9D8
-:10E8F000D97B4ECEECC5B8566F3DDC6F60EA92F81E
-:10E90000F78BAE9DA4601E282F57AE83BCEEFBCDC7
-:10E9100044355EF2FC144DFF7ADABFD5CBDB876F4E
-:10E92000BE66D2508CEFF272D78FFC747EF7EBD5B7
-:10E93000FD210A8A737DA6BEF12A72E4FBD65DD65C
-:10E9400027BFA93C5FE671F5C9F17BDF9EDA7191C3
-:10E9500017E8EB33CCAB15F238E46479225ABEB534
-:10E96000D22309FD773288D8D533EBF03E80DEF82C
-:10E970006EF7343FDC8B20E2BBA11501CCAF05F96B
-:10E98000EF41F97FF2837D04F4CB8F50FF0F9D534D
-:10E99000983F88EA1112C543537715FA3D216D144B
-:10E9A000E4A6D8FF455C2E81AE0EF81DDA72D30EB8
-:10E9B0001DAD7FC7E35F87FD723B503BDF1D1E66C9
-:10E9C000BF874AAA37013F208F4804E4F6DA924F06
-:10E9D00051CF687A7ED2F8E4FCF0855D0FB0FCE29E
-:10E9E0009DFA01D7BFC3A363F931CF3F83FECC8F1C
-:10E9F00022EC584ABD12593301FC2AF532685AA458
-:10EA00003C527733CAFF99741D745D3FE27227B49C
-:10EA1000F3FA30E4AB87E87F00B2CD81F9A8EF6F5D
-:10EA20009E69B242BC2654327B09D283CDE287F57F
-:10EA30006BE7D91B1FBED382FEC6B55DFA5AD09BC9
-:10EA40002AA89EF42B3ADF3CC7945A1FE54B39BAEB
-:10EA50005D65DFB3425C7D60395C9DCDF6B14D0AEA
-:10EA600084BF538EF98C24394FA7A08BE963DD1E38
-:10EA700083EA5E886E0FD3132F0BF74C049C7B51F7
-:10EA800089A7805E1C22FE4FC0CE2501AB17FA81FC
-:10EA90001B1540CF72AEF4A23FD7E48CFFE822D41E
-:10EAA0009B14B433841D71FA79E6FF1A9E157C1508
-:10EAB000F0B24217FFC977006E3F62E77589C2F86E
-:10EAC0004DFEF5D6B1E0AF323BE33FA9F5627E0DD6
-:10EAD000FA1FD22F6FC37D78D1496C009F89E13A2C
-:10EAE000454A9233826F4CEC3D17E3443F693567EA
-:10EAF0002FC3E86E7D6042146D3B9FD1A7171CFAAF
-:10EB0000FB0C055E0A7D413605D19EA99949ED436E
-:10EB1000C0CBD5898332F8E59D3DA82F3646251C0C
-:10EB2000A7B1E49798FFB698E759F5E63B2971CC71
-:10EB3000FF7ADF93C2E3036D4C6F253D68FF922798
-:10EB400019FCA9DCC4BCB03EBDBD05DB89FE0C3C94
-:10EB50009ED0C8FD351450587FDA23E209AB78FF08
-:10EB6000228F8D8D4B146F45B27F61C3342A49705B
-:10EB70005EDE3498EF13E6C0E7404747EB65E6CF2B
-:10EB80006E4F89C021CF0D528F1FFC8EE1B281CF15
-:10EB9000B358B3181EA5EF4F4C467FFFF383E5BB78
-:10EBA000B2FCD64DE347627E7879D72793013F4880
-:10EBB0002D417AA4FCE282F25DED595E1CEF5BCF41
-:10EBC00077F549FE87E83327CBAECE77F531B88BA2
-:10EBD00038A436CFF574564C617969F16D3B407EAF
-:10EBE000761931DF6D6AD72B47C00F39D544A2188B
-:10EBF00097D5E8012F665C3F348BAEE3CCA90FB606
-:10EC0000DD4320DFF9591FCB9F53CBF5C1F4788C3E
-:10EC10004D24D97B157C1FBE2D3D5EF0DD10B78BDA
-:10EC20003E96123F2E86F5EDD5D9063AA732314BE6
-:10EC3000E0DF20F91ADD03E76B887350B5F1425528
-:10EC40009CE95AB19E6F18B70A802F7980B895C297
-:10EC5000F3B01489B100926750C5AD147BF16071B7
-:10EC6000AB18D63F331CEBEFED17B762F9016D7BA4
-:10EC700033BDA0A737B8128F3EEA85FE0CD84FDB14
-:10EC8000F32911C83B6FE3F06FB8F0B8D5C2AC01FF
-:10EC9000E256DBB91EF67E891C3350B86E276CFE37
-:10ECA000E16E11BF92D11E4DDC9727E68FF567EE1E
-:10ECB0001B857E9F39222EF522F387CDE1F1A7F740
-:10ECC000A71763BED660709ED3AEF6EFDFC5E17CBA
-:10ECD000D65C857EF51FFCFB34F433CD077FFC90BA
-:10ECE000BE730984FBE5BCEDECBCB977A714F1B2A7
-:10ECF000F88849461DCF26C3FBC5941D6E06161A1B
-:10ED0000A65873317D2D51A8D17A6F1B2D53E55D27
-:10ED100059A3843DB4DDF62329E807BBD7E9C5F93B
-:10ED2000DEDBC6E2C4E175526418EB17EFF10AB7F7
-:10ED3000C97EE8E7A7594C5EFF2A8BF921BC9AFBF4
-:10ED400001DAF43CDECBC76B21720C9EB2C49EF795
-:10ED5000DA94DA81F400D15F9BBED95405F0CE631A
-:10ED6000F7859C35F867A29FD8518CF702B5A53678
-:10ED7000B7D7B27AA4D9B3E64400EB2F57986249CB
-:10ED8000BC0E98EFFA2CA6A768E13CAF435DD6C64F
-:10ED900069B4E7A0E690E0F0AC21FDCF09ADCF6209
-:10EDA00072ECECDA42BE2F3E8C7BB4E9BD6F1602EA
-:10EDB000BEAF61F7FEB4E432B8C979EC5964AFC1B3
-:10EDC000FBD9889DEB6384CDBFE872A704F4D066BD
-:10EDD0006778FBAFCE5B3BDF17B28A197CED8C5EA8
-:10EDE000DBD64811062F36EF0BF56FBC25F8D2B7EE
-:10EDF000C417DF977C8FC60AF13BE40BE1FBF448B4
-:10EE00007747492487E53FDA906FCEE6F6EA512E40
-:10EE1000AF36D717A5413C73CEF1D5787FCFC4EB81
-:10EE2000AD38FFA617CD688F35AE88E7033E6BE19E
-:10EE300008B355043F9521EF98B07B5FDAD5F139DF
-:10EE40006DDC7585239000F9D2541D2F86F8CF0311
-:10EE5000F2FBBB5E617C0DE563D38AC4A3E02F0E99
-:10EE600038829F43BB9377BE3D59F2E2E7C8DFCEBD
-:10EE7000EC1D8EE7FD66B7A9CF4F9175EAF81F69C3
-:10EE800077B073629DEAF7705E48F55DBF7820D376
-:10EE90004F36188223407FBCF20A96EF706AA14C6D
-:10EEA000603F4F99098FB30B3EEB2B4E9603CEEC90
-:10EEB000C1E41D6D0770E6F99DA27D23EC2BDDCF2B
-:10EEC00006BEAFA79EB9B818F6F5E4AE8B8B615FAE
-:10EED00037E83BFC4017275C414F36C597639302E8
-:10EEE000A8DF897CD60BC5B7E183CEEB7F470E97B1
-:10EEF00067FF737218FE92FD1E2FFE9DE59D86BB77
-:10EF0000D979D13E7FDB4778EFD59973B2047C780D
-:10EF1000B0FE5EF730BCF7984818FC1C15D571FCA4
-:10EF2000AEE20B99803E27F458EDFCAFE2F09B99DE
-:10EF3000EDFF15E8A3C23F5BCFFB36453E63FAF217
-:10EF40002312FA5F4DDE70DA04B48FE68DD3215FB1
-:10EF5000F9159E6720DD920DEC8C858FB460FDE97C
-:10EF6000AE39582F9B6231B0A71A693D94575FA6FE
-:10EF7000CE4FD6EF2E8B25DBAF741EBF00BB24C552
-:10EF80009930007E36817E4CA7D8A4303F7593938C
-:10EF9000A07FA4BC4B6DEF89F8EBE600BB5765730F
-:10EFA000B784F72BB90DC1C25CD8574D1C765EB63D
-:10EFB000BF0DF04EC4C3A7B8FC0BB259BC3C1FE058
-:10EFC000D494CDE617D78BF373EAF37D87F6DD880B
-:10EFD0007AD05F49207DE0BCB1882A4E3E9F9FBF1A
-:10EFE0009CCFCF5F027F8E69F87372B921296F2C95
-:10EFF0003650FC3F296F2CF9BBE4BCB1988AAF7541
-:10F00000F0F3094B313E1DA278BE7C6C1F1E3610FA
-:10F01000FEB731F13E9E4FD96944BF5803CF170D5B
-:10F02000D51F457B2304E75D183DB2BC6A7EEF40E7
-:10F0300003B5E3306F36AACE2BFD69F6B72B0F442C
-:10F04000BBC1FCDD8F0A7EC0E951AC4BACA3A15B18
-:10F0500062F4A399A7D67ED5FAAD85FD79A17C6926
-:10F06000CFB7BCEE6FCA975EF996F8523FFFFFD05C
-:10F07000449AEF5BF0FF9FF076B8C125D82E317C23
-:10F080009DACB3FA597C51C7F20FB47157EF648C41
-:10F09000270A7FABE9595D645521B6C7786AE3DE7C
-:10F0A00054CC07A8F7D6A39EAD8D332E22BB26C322
-:10F0B00016FC95BC86E7AAFED5B8FEE9ECDEB87E64
-:10F0C000E1378CEBFF35FB1BC4195FB27E96114C08
-:10F0D000C293EA52AAB0970E9E77A5CB61FB9EC25F
-:10F0E000F33F4C4A98D893BE1FECBB941C16677F25
-:10F0F00089E70BDD9F9A82E7E83D06768EC023B351
-:10F10000BCA677A8B69FE30239C0F6F167CFDF440B
-:10F11000204FF067FA289E6B0F375A7D20BF84BFBF
-:10F1200048F4DFCCFD98174A3F4539FFBB7CA33438
-:10F1300047FA6671B28D14064974A5A583C1BE1B3A
-:10F140008CAF5C9E13A8CC41BEE51F83F1860BE417
-:10F150004729E5945F837CDE6DF482BD60E2E75D64
-:10F16000C8BA2C95BD3DE7FE3C945BA7CCCC7E1085
-:10F17000E772C4FA0383C2FB9FD3EFF6B902D3014F
-:10F180004F8E55F931AFFFDE542657128FB3FC1E58
-:10F19000EDF914AD3C11E72BC47873C5FEFC1FF1EB
-:10F1A000D325023EFF223FA5F215FD2B83C653FB5C
-:10F1B0007D1F66F79154F7F8799C09CF2B887985E4
-:10F1C0007A585E5C0B9F5F2FBC38FF3F98E35F056A
-:10F1D000FB70F22D9309E297E5E58C7F3605ACE8EC
-:10F1E000FF6F8AB27C98A61504ED7C710ED59D192F
-:10F1F0005C07F878EFDB56BC07B4A96B7B7B11E6A4
-:10F20000090451AF3BFD167B7FD01DEC80FE432BE4
-:10F21000E2AA3843C5F9CF56D796E37CD14E771A88
-:10F22000D5E77B7E99C3EC6FF1FC452F7CA95D424D
-:10F23000BF3B59CFF2B0434EBFAD0AF303981F3B1B
-:10F24000C5DB83FEE7A6DD282408268542FD5DB9DF
-:10F2500088374DBBABCAF05C7FD45C86F7C1BC631A
-:10F2600045FBEAE49DD9111DF37B3F06EB4A2D8F48
-:10F270005C0DFA65011D07FCD827775D5D86FE40B1
-:10F280000DDD097AEB3DD779AB29D22AF5D1E3061A
-:10F290003D938F42AE3D08CA2CE647F0FCBEEE69B6
-:10F2A000649EB5AF6C75AAF31E67664F7A10E6F3DD
-:10F2B000608EC2E3D32C1E5E68A2D667517F3C2CC1
-:10F2C000E4F1F0693C8F81844D7DF90B455F1F0FA0
-:10F2D00017F31365110F4F39C7F4DB229B01F1229D
-:10F2E000B59DF10D42F102F4EBCB123D13E13CD59B
-:10F2F000D0CED86500AF74003FE691C67F7411C4CC
-:10F300001D3294CB20EEB06DF9D8FD2627F88F7A08
-:10F310002E87ADF176D8AAC1B47467060E039E108D
-:10F32000A5B904F0BFFAF77A966FB82605E57D67B0
-:10F330007E03E61B9E7EDBA83A47A37D86C92A0F83
-:10F34000F8898ADA7F877EFFD4DDD28079A419A07C
-:10F35000F48F67EDC1EF94DADE13AE043FCA7D127D
-:10F36000BB4B91CE5EF280FDAFC8A077CCE962E7DF
-:10F37000B1E774D8AB4DC84F251637B9CC897C524C
-:10F3800059738D0CF699D242F0DE324B2EF35B0F9F
-:10F39000EBB4C9B0EFBFFE5237603CEC6F1CBF212D
-:10F3A0007F0DC0D5684C1C8490BD88E389BCB5C175
-:10F3B000EE0317F248ABC7F6D35FB93CEAD5E335A5
-:10F3C000783CD87702BF053EFF5A4F500FFBB5641B
-:10F3D000C2735A02AFDB441EFE97CC8F5BC0F36250
-:10F3E0008EAEFD9F31EC3E3F110789B07B25F5F1D4
-:10F3F000D53908AFF8156158F76EBBDC548AFEAFFB
-:10F4000026EC670DBB7FACA07DC8AACA7278DA086B
-:10F4100080E0E89EC5054097618A07C306C0832344
-:10F42000392CFF48599382FBA6ACC79B968962771B
-:10F43000E3BE290FB0FD793387AD47C461859FF2E4
-:10F44000604EB004F26B7BCF572DB7B0F355FCDCA8
-:10F450006EEAF2B79F82734BDBB8BF78FF8BA3F0E5
-:10F460007710CEAE5124F01B9DB5D71580BD372E39
-:10F4700097E94BA94A0FB15993F1733FE6BD16EDD9
-:10F4800065F97B0ABFCF4859E3DC0EF02CCD08624A
-:10F490007EEFE56D31FC0981176DC730BE46F52260
-:10F4A0003CC7FCD1F392D08B54F250D86B5A3BEC52
-:10F4B000AADC6F572E7E9D9E343D572D072FD8BE58
-:10F4C000226A3BB3B7BDB01BB57684E6FBC1F41F1F
-:10F4D000E20FABF25BE6E57A851E87F23D9BF346D1
-:10F4E00091F7D27B0E9944CC709E017209C4FD58ED
-:10F4F00090FFB351B2F8404FD2E6FDF4E6E390E658
-:10F50000E12C1FA4F92276BF44F3C5F014794166BB
-:10F51000C80B49CE3F4D65793D66C80BA1EF5B072F
-:10F520003DB7EC6D81F13BEFB68973CBCCCF5E4B31
-:10F53000789CE1213CD79CB82117CFC94CAC65FE23
-:10F540003B47C020035E3EFB0F9D1FF86E82D22D0D
-:10F55000E8578EA1FE2CD0B7CCB41EF24D7ACF2D39
-:10F56000D79101CF2D8BBC2411A7CD1EBE4102F92E
-:10F57000D39B2F12EA3BCF0CE3762EF1A27FB83754
-:10F580007FE9BB04D7592DF88C49BD7F697ED62E03
-:10F590006DA601F50CB71C7C1CE3789B7BCC78BF77
-:10F5A000446E11EE5B6B6504EFB3759476A0FFB506
-:10F5B00025C3BF39D7D5873F627E64235BFF1938E7
-:10F5C000AF25F58D7B66E117F9A04F55771B191E06
-:10F5D0006AE6B1B9F7DE143A0E7DFE2297EDBF4F11
-:10F5E000A3DF8AE72F047D713E2CC61F6C9D021F8E
-:10F5F000BF4E6FD7E257B89AEFCFBBE608CB3B526E
-:10F60000E3D7FE95B5E38E515E726065009F67CCCF
-:10F61000525407F941E6C42CE08077E6CDBF0EEEE8
-:10F62000D338939AC887FB385AF2A77E07EEDF38A3
-:10F63000E34ABC0BE5CEBC7F63E561896D703FC7D3
-:10F64000CFF3145686B1B2097965CBB9EBC2A57870
-:10F65000AFD5EA1E904FE59A3C13CD3D02900F893D
-:10F66000F71E58D97E66F27C5452C3F577882CD1A8
-:10F67000726B56990FF208ACC4BBBB07EA738DECF2
-:10F68000BE01C2F29F5A8715B27C058EEF2497FB0C
-:10F690009F493C0CF8DB5A68C7EF7BF9F56E238F66
-:10F6A0003BB1F1DF78869D131379B684D8F240EF31
-:10F6B000B17A89AA2CEEE1208A2D0FCEDDB70ABFE0
-:10F6C0001E2F1FB1044FE426E9456F4CBAA3147FE7
-:10F6D0008FE3D9BB86C27AAF32A8EF33EEE5A7F944
-:10F6E0008C1F9EE1F7FE7558829F423F4752664D40
-:10F6F00086AB5467665419ECA8A73DAE037EE4E2DE
-:10F7000078619FC1E667AF0948F03B18E2DE3D57DC
-:10F7100050417F000976EA407EBA8E05309FAFC126
-:10F7200094C857287E7D610CFE03E8E16CDD7B3FC9
-:10F73000C03860F61BEF42FEC51BFA8E8969202F88
-:10F740000AF97D0ED4F00B3B41DE15A0DDD77B4FCF
-:10F75000E73009F9C3D419ECFCE9141255D0FF6263
-:10F7600063E7A1269717FA5AE9785379FEC6E4238E
-:10F770008134F0034CBE29AEB0784B4249CE97108D
-:10F780004FE2D17B93E9E06A6F5299C0FDBEEAF285
-:10F79000B53E75F93B955F0E4F2EA7533B206F3C4E
-:10F7A000F0AD389E270E5F426C6C5D2C2FF0E7DCCD
-:10F7B0006E1BE521A602C85B744A61B00B463D97FB
-:10F7C0008D7194E72A0996DD3B4D0F9992D7BF5E64
-:10F7D00066715AEEE716BFE3037520579F7DCB8D08
-:10F7E000F0725B65E4A7E001077CABC8315980BFCC
-:10F7F000EB389F17E7AF27A599F0FED5D625ECFE8D
-:10F800007FEDFD93AD7ADB3ED8C7D613740D749CA3
-:10F8100047520D31390DF68B1083B38F1F0BFC81CE
-:10F82000FEAE00BC1FCF7E678962F9D0E4FBBF5BF0
-:10F830005D6CAEAD772B3C3EC77EEFA1A4F7F71F02
-:10F8400028D9D1F6A05312A413161FCB13EB248A88
-:10F850001FDA67115166E7ACDCBC2CEEBD24A44A6C
-:10F86000C1FB7224D1AE05CB0FF27652F72B7F038A
-:10F87000FC189A46D7439F4BF2189F78587E632313
-:10F88000E28935E8053CF1A50C7CEEE7B63C46374D
-:10F8900093D22A3D9037D09AE5F3805E25E023DEAF
-:10F8A0008B7E45BD18CF973170BF4B78BF517E6EB0
-:10F8B000585BBF388FE96DBDE3EA69BFD6AF18D793
-:10F8C000A51EB7F7BBBC81BF13EF457BFC79A60A29
-:10F8D000A03306B7293C5F9594A8F35348A5CFC43D
-:10F8E000F8BD3A1FE52A694516D0E7D5A6C6EE3819
-:10F8F000FDFE158E2757C9C1BF40BCE19559C5070C
-:10F90000803E6BE18279DACF3524B61A90E54C550A
-:10F91000F067F621C82FDAF2E83A9A74C1E10E5A7C
-:10F920003EA5EF18BAA410E9EB9EBCF1FDE727F065
-:10F93000B0779E14FF60DF05FE69E72DF0805C174D
-:10F94000C5C4BCAD24864F0F61F9D0547EB1BC67ED
-:10F950006F5EDFBA28724E36350F05F9FE4A4B1836
-:10F96000F9CF55F69F60FED78305C1CD30AF99170B
-:10F970007D82F7DD104F1DEA5B74BE3FFDBF9C2FFB
-:10F98000A5AB2C782FF440A1EFF5CB033E6150E5F9
-:10F99000018BF969E958CC2344D83D4613BBB7A382
-:10F9A0007E179A61F5C1798D10E4B79663FC0BF36D
-:10F9B00085F770BB2C2CB1BCDD7EFAE2E0F9C2EC1D
-:10F9C0005C7FA38DDD6723EE45FA7E91B8EF86CD8F
-:10F9D0009BF22F7EDF0D963BEBBC68FFF5EA8DF3C3
-:10F9E000981E7A65B1A50DEE0FEC7FEF0DF3EF9148
-:10F9F000E78C5EAE27A2FCEE4C65E39C32B3FCF4D0
-:10FA0000243E4E2477DF7D5C1BF44C1FFC635E219B
-:10FA1000BB5F44F655C07E6C86B895AEBF1FF284BE
-:10FA20002BF867C0EB79A5FE7CF8898D3906E6676F
-:10FA3000A478B5A587409A5BF32370DFE4D5A4F9D9
-:10FA4000B03C04F1EABFA1FDCC519FB07B28FBF094
-:10FA5000EA0386576164825F47A72F6604CF40FBA5
-:10FA60004E7BF49DA67288331A11FE228F504BBF35
-:10FA700049F339A667F371C23DB7743E9F0F349FB7
-:10FA80000BC1EF643CCA240C8F07C373C8D74F1D4A
-:10FA9000DB87E7E92468C81F9F84EFAB7DEDBA21BF
-:10FAA00003CC5B67C57DBFF166168F09A5303D1598
-:10FAB000E232596EF03FB1F16F5CC3F0E346B3112F
-:10FAC000F1655A7723C65F480D8BA7F8E8FF603EC3
-:10FAD00033897F12FC54C6F5B66978FE72C6547538
-:10FAE000BC65A6E92A8CEFDC40983FEDC6197AD5B3
-:10FAF000EF000A38CC24EB3E817C8E999ADFFFD34D
-:10FB0000C2451BAF11F068ADFC6ABA1F91DF1BD76D
-:10FB100019FE0DE33ABE7C963F7741719D03FA04CE
-:10FB20009EBB7FD9B560CB124A17C37F5A8AF7664E
-:10FB30004F722F7C643D2D3FB67924965F76DFBAF5
-:10FB4000EC0DA8DF568CE51AF99359788F79C5CD5D
-:10FB500053E0BEF10366D68FC712EC84DF8FF08CC2
-:10FB6000291A0B26598D2181EDAEB9A8711CE4C16B
-:10FB7000D45858F9B5B2FF1A8BE5225E1EFBC24875
-:10FB8000281F903E9935505C6854891483DF89AAF8
-:10FB900071B0F653C73E9E0D7E829A6A561EE5AB43
-:10FBA0005A3304EAE54F670D248F67E573FB89EB51
-:10FBB0005B014EEFCFF9DF6B83735E01ABE483FC37
-:10FBC000FE40E57BEC9E2B13CB2308F8CB14B80743
-:10FBD000B1DACFFC7B13AD2D59C0FFAE0B1ACAC1F1
-:10FBE0008F6BB316B6C17DFFE99555E361BF275210
-:10FBF000350CE41FA5ABD9F94057177F929F867A41
-:10FC0000889AAE04DE4E13F454A3A61BCA0FEAD999
-:10FC10003EAAE981F6DB88FD5EAA964BBDFC5D43FA
-:10FC2000B75A7C1C54EE13351FEC954FABA3889745
-:10FC3000B9849DE3D90A78CAE8F7DF607E06B9C7C0
-:10FC40000BEF0B24DF484CAC18447F10F303B5874F
-:10FC50008CED3F2FF85384BEC86660B3B9615C5623
-:10FC60004FBFF3C38F7A8979D1F17F8CF059CDE6FC
-:10FC7000B3556AE6BF13C1F47261F73689F576A908
-:10FC8000D75B6161E7D13D84F21DF4DD978DFCAA5D
-:10FC90007987B89C9D610ADC67A46BB8C13E07F701
-:10FCA000F926127E06F49BD72CC108CC472787F78C
-:10FCB000C625F89D073FC693E93E6ECF4FD217C4C5
-:10FCC000BCB4F0681A84AF6AE7AD8543DFFEF4A0E8
-:10FCD0007E96C57F0FAE775D9AF5B4F2FBE01365B3
-:10FCE00046559EE86B752C0F56CCEB358994A09C3D
-:10FCF000942C1847EDF53B69F9DB20E7D2847C169C
-:10FD0000F3BC839F8BFA5C667CEF0E5D0CE7595069
-:10FD1000DB630638C6F38BD87DC67CFEAD95616C7F
-:10FD20006790A501E3C4F17C59E457A8F65BDC4F6A
-:10FD300026E25C02AE4E833717F33D35F09C6D3200
-:10FD40000E1C57D5C65F07692751F8E538FAC35925
-:10FD5000C4CBAED5FAE1AE66FEA96BB91F6E622DBB
-:10FD600083BF63792ADA6D8EF2371432BAEFFE64FC
-:10FD7000B11F3DCEE049C423253E1EFC04AF8F7F5A
-:10FD80000CE344E29E422D7CCE0D029FC1E861B09F
-:10FD9000F91FB104BE80714F493D789F59C263E39A
-:10FDA000CE836021D08BDD565805FE05CA57CF9F04
-:10FDB000076313AAE8FE2D770565B853EF2612985E
-:10FDC00004B9D78EDAA09EF9E709FA8797723B71DA
-:10FDD0001297EF9F3EC9CEC1D7F8473C7819E89FEC
-:10FDE00087F424E2853C6E069F4FB7E850AE2F782B
-:10FDF000759C07F4F3F739BE0DDF28AB7E2F6E44F8
-:10FE0000C4A2BA2F63D44E87AA3C3A9AAD6A7F51F6
-:10FE10005791AABE2C3652553FEED05855797CCF1B
-:10FE20000455FB8B8F54ABCA97C4A7A8DA5F7A7CC2
-:10FE3000BAAA7C79E216F57D1F617F4F891BEECB54
-:10FE400067F0B8F2DC6C55FB8FD3261F02BA9BBB60
-:10FE50008EE56D5791C5AAEF17EB1A301F9A7430D3
-:10FE60003DA699FE8F9F3757304F8CEAEF1900B7A8
-:10FE70008D6A3DA7BE7BFD6AE0B5FDEE99D0E83303
-:10FE80005AFD65B8B30EAE69269717B0F3EDE4627C
-:10FE90007231FFFD10EDBEE2B9FD4F0FEBD08E5871
-:10FEA000FA2AD3EF973EC5F2E18AC9B0743CCF7508
-:10FEB00048472212DC5FD0BCE132A94F8FD1C2C5C6
-:10FEC000E851EFB3D9ABDEE79412F53EA7FAD4FBC5
-:10FED0009C5EA9DE67BB5FBDCF19B5EA7D7605D410
-:10FEE000FB9C3953BDCF5941F53EE7D4ABF739AF51
-:10FEF00059BDCF05CBD5FB5A185EA4AA177C734811
-:10FF0000FB52D5FB56295A413925991BA8C77B1BA3
-:10FF10008675FC7040FC10FB1FA6FF63F4DC8CF9B7
-:10FF2000F5F3E9FE437EFD5FC9BA83108AD2E24150
-:10FF300053D77A8CAB7D533CB8BB80EBA762FF2FC5
-:10FF4000503FA5F2B015F802D5635617807D3D9C51
-:10FF5000DB1D8181F518C1B792F58664BB7A307ECE
-:10FF6000D64F4E723B7B5039A9B1B3DF82EC26D419
-:10FF7000C7D7A15FEB668ED79FC1AB4BC0AFFA343A
-:10FF8000CAFFB7E8442AE9BCDE8279D371DEB28CBD
-:10FF9000423FC8AD24A6C77802646EEAF0DE4BCCBF
-:10FFA000C3ACA37A393CE770FD601EF7937C610C0B
-:10FFB000EE2C60FE9102378C9BDBC3CE6FBD967139
-:10FFC00041F73BFC0EFE49DBFDA92010857E6A4C03
-:10FFD000DE650FD057FBB9FF894C65F99F44098C4A
-:10FFE0004EBE4FB1AF1F16377D410A06D1CECE327D
-:10FFF000F9C0CE1E95434C5920DF3C91228853FD19
-:020000022000DC
-:10000000BA4016712A942B23398E3C951D5D6A47A0
-:1000100078451C1827F886E3FEA6C07F10F041B48F
-:10002000FFBAF51A0CD125CC9FC07EBFE430DF9714
-:10003000876F34C6C02E1378742465D6419717FD98
-:10004000E187012E336FBA7A3594A5FD19DEA574C8
-:100050007E67EAE268DF53F81F81F11B4C14FE74DF
-:1000600089A7F282C3D301190219DC4919183DD0BE
-:100070007924319F8912C70B4BF03D1867BFDC9381
-:10008000EF0378283D78FE8E5851B921A70C03FB69
-:1000900003051CAA53F26EC3FB748D461FD817D5F7
-:1000A00012DBD76319B7CF82D8E23C39E08EE9542E
-:1000B000F33E03E335D8EA0AB28AC0AFC6E70D3F84
-:1000C000028A70F7960EE827E7F3861C128CEFDEA3
-:1000D0002D89DFCBC1F273613BC6338CF26787E1B8
-:1000E000F7FD12A3658CF76DB1D0AE29BEFF27874F
-:1000F000B7B8EF9CBE67F97916F6BD67838CF1A39C
-:10010000FF07EF54F02D0080000000001F8B080057
-:1001100000000000000BE57D097C94D5B5F8FDE6F4
-:100120009B2DC924992C6421102609598010266121
-:10013000111471588251034E006531E24C12206453
-:100140008100DAC64ACD40D854A8A122A2A20E0846
-:10015000141568B008A8D1372C527CDA8AADB52EB8
-:100160009597002A3B3168A57DBEFA3FE7DC7B33DB
-:10017000F37D244F7CCBEFD7F7FBC7D777B9DFDD13
-:10018000CF39F7DCB3DD3BEE31AF2E6043187B7E19
-:100190009ECDA92A8C7999C3CC54C6CA99CBCC32AE
-:1001A00018FB7CF4BFBFD1EA602CD2E1B13A8632B1
-:1001B000764F9C21F58334067F9E012591908C8C8F
-:1001C000632C99B1EFF1EFA6AB53C67C8CF5C074EC
-:1001D000B5810D636C929DD1DF2C180BDB4D662E23
-:1001E000138E7307F39870DC3F5C34BB5814A4067D
-:1001F000282F606C2AF3D1F7E9CC4FE95D2C40F54C
-:10020000EF66AD947F3F22AF773DCCAFE489EC4CF5
-:10021000066D2E795B8761F9DF2D9E549C6F8DD51D
-:10022000734F3C7CBFD0DBF36522D467EB60322395
-:100230007E78BE25383FA8F7591F779603F2E3ACC6
-:100240008E21F9E98C1D34B0CA661B948DEB41F305
-:1002500067467BE6A4815DF5B3943118FF58475497
-:100260001E1B8479972D19D67F335F3EBBD9555D10
-:100270008CEB2C546D2C1EE07FCCA1FA2D3066D176
-:10028000686F4F5C17FC45FAE2199BE852D9C3002E
-:10029000EFDF2E812F50EFB7F9AABF11EA4DDC3006
-:1002A000FE0CB62F1E3D795934AC7FFC77AD43026E
-:1002B0009016F5329D68CDE1637C0FFFFB866D1CC7
-:1002C0001703E9AD49BB8D0CE67F6B5F6D79712E2D
-:1002D000E4ADC1FC44660C96C3B807100EB18CD5D2
-:1002E000FF257FD4E190768C35A96E58F7AD8EC886
-:1002F000F82F0640B63FEBFF3DCE5B2D8DF6D8BA0A
-:1003000087EFB70DCE51874D304FC55582F861400C
-:100310006F6EA0A33223733577D1EEE94C45D00F31
-:10032000603781B1DBC55C3B8A2F9B2FC17A57397F
-:100330003CA5D8CFC2099FCFC4F53123FBDD608037
-:10034000DBBCDF03DCA0FC4403403E9BB1530D56F5
-:10035000E6B230F645839DF2A71B92283DDBE0A074
-:10036000F47C430E955F6C7052FED70EF72CECB701
-:100370006CD557464F2E632BC3241EF93C16093A01
-:100380005ED97BD89F9D30DECA774D94AF6C6E1AD4
-:100390001F01E9A2DE279646C0F7452F284EFC5ED6
-:1003A000DDE232DB603EB30E7B5620F9CC79B775C7
-:1003B00022808FD55E519807B690A5AF7B11D2D918
-:1003C000D03F9D4A40F87DD9309CE673A6C145F3E5
-:1003D00071B5B41D8983F6E71A8A287FD4E1BE1F60
-:1003E000E7E7625F99B1FE841D6DC614282F74295A
-:1003F0002E06E38E7231BF1FF0B7C1E4F120DD6C31
-:1004000048B63A1B213F7AE0A467EE8571DFE9E345
-:1004100069C4F677C49617C6C1F789C3BD46AC3721
-:10042000F53BC6302FE9FB87F7358747ADC0CB8555
-:10043000371582D385BD036EBF01FA7BF3A8CA547A
-:100440009857C71503CDABE3A3703F5382F516BE93
-:10045000A2125D2F1C68F6B334CC0F4864B9B84EB5
-:10046000E80CD69FA338583DD0DFB99D3F4D423CA4
-:10047000C8F1CFC536FFF513E8AFFD338373338D75
-:10048000DCFCC55390DFD72BC9F930E42E9AD83461
-:10049000DAA7AC2E6212D0D73C33F3F0BC6700E68B
-:1004A000CF85B37BDC901FB62B650CEE231CCF9160
-:1004B0001DE46B59BB9E487FC0111C6F7BF3AC4F92
-:1004C0009E82FC05BFC1678A8694355F7C0DC6F3AA
-:1004D0006DB139B7329CA7311CE7F98889CFCBB70A
-:1004E00035DCB9D581FDF9890F40B919CB6B5E7E3A
-:1004F000B227AEE37580C170C8BFBE3682F8DDEBAF
-:1005000026E7F17A6CF70CEFEF57BFB8FFC47E4CCB
-:10051000D7D416DC0F69C0114BF0AEF8E5DCFED87D
-:100520007E400AA007F8E34BFB9440581E6303D7B4
-:100530001D589A0CE30DDAD866E80969FE16A51174
-:10054000D301BD8B8EAAD0FF118783E63178479AFD
-:100550009A82DBB5A7FF939B3208700AE2AFBFC057
-:100560005FEEBAAFC6F4847467CFE6853150DE5FC4
-:10057000693EBB240DE9FCC3020FC1AF89FA79A51E
-:1005800065F21FEF62B80E5FB215E7ED353BB7A617
-:10059000F1E59A207F614FC6A687618D7B0DBE4D28
-:1005A00088775F99D5B915F1EEF63D89F8AE85FAF1
-:1005B0003EC8D7E6FBA2AE87F2DACFFA3A81A2585C
-:1005C000EF676F2E4278CCDBF3F8F89E50EFC2480D
-:1005D000E604126095AF5C1E8FED586FC690255CE7
-:1005E000D8D3983003DA3D923B6628D2975B6DA64C
-:1005F00071D87C3ECE13B01DAD0032D60AC0491072
-:10060000A40AF51E81CFF83DB625E6400A0BE26745
-:100610007ECB923423B41FE2B13A55DC3769BEE495
-:100620003A58EF7B5865049D7FA7717F269B45BF95
-:10063000F6C9A9EE1F71FE99C57926FB7BC2CC7C59
-:1006400061D04F6FF8AE40BA11FB85F2ADC057EAEA
-:10065000217D46CC1FC6BD82FB14DABB900FA7C01C
-:10066000219D0FF34C79C242E7C0B58E7FC9645B10
-:10067000A500DDCE0FE77C6C8C387FA7C535BED1D9
-:100680000AEB7D35DC634C83716689739F199D0E7F
-:10069000E4EFFE709729AD079EA3EDA9B806385781
-:1006A000C3303F4FF5F449C8A073353B1AF9BEF586
-:1006B000DACED577C35DD1D8FE5AEBEBF9EDA26F58
-:1006C0000C2C1FE860D1E316E2178DC897615D8D91
-:1006D00091C3ACC837D86143CD1138676FE42D3B67
-:1006E000FB5B1459407CA591B12EE1F526EC7F0F00
-:1006F000F09B009C131EE003A3AEB4AB9CDE8F1DE9
-:100700008A1E827C96B922817E6EBA62609E907348
-:1007100050DF0FE02B0FE1389A45304FC8B9EA623D
-:100720003166DCB7CC16FB5F5BB798FF4881BF91A1
-:100730001D1F45301BC203BEDBBA5FD71B625DFFC6
-:1007400082EB82745DA6DB85F0BFF16BBB11D777BE
-:10075000A3B12415E51A98F778FC3EEA6B8376DEA0
-:10076000DF856BF2D73AFFFB14E633E07EFCCAEC80
-:10077000C7FDD882C723C0B1656EAE1FF7FD5E33DB
-:10078000CFFBA2A01CF0D812C97CC8475A4A12FC61
-:10079000BE34E487508E7CA307E3E561A2FDF40438
-:1007A0006ADFD30220457E7057B8E8BFEE9D8158BE
-:1007B000BE2485F848A3C9BF2A1DFBFFB94A7CF8AF
-:1007C00023C1B7D7C504EE52A1DF755F25301CE702
-:1007D000231648998FE3548613DFBDC160B8A7C4C0
-:1007E00086F55CC9B100EFBDFF50E99C58970F79C1
-:1007F0001BF1ED69CDF07D5D892B391CFB2949305A
-:10080000D07C545647DFD378BB4F4CBCDE0C81AF55
-:100810008F057E605FD3BEF74C8C3022DDAE492B56
-:10082000F3A5911CE44A5660BE4F556432E49B33F5
-:10083000AA6E49237A697A82F8D7348103D91F36A0
-:10084000B00E43B999FF4D9FB5350CF17947655806
-:100850001B9CACECA3CAA5910E687F87470D5880FE
-:100860009FB22985AE4EB92E1DC775D1B8B5CDFD45
-:10087000324E85D0739905F804F4FF52986725ED40
-:10088000D3FDF954BE1F849AEF613F9DA8C8DC8553
-:10089000FB8A55C4111D3063A01CF1F066BB95E4C2
-:1008A000D4EEE8A111E13F48D029E26531C73BC849
-:1008B0006B946F9CD6DF8FED9F3371BAF1ED0E23F1
-:1008C000BC164DB2129E3BA6856FB240F93D826FB9
-:1008D000354E0B772950AFF1158BDF807C40E1F46A
-:1008E000E07B2392FAAD31F37CCDCB99444F7BCDA5
-:1008F000FE17B661F99B61440F35517CDC9AD752E3
-:1009000004BDB9D296E3B86F58880E6AC21DD1549F
-:10091000FEAF7144272EAB673BC203E8AE0EE588FD
-:100920001A73202B06E07B5CD0D5716883F8F3D571
-:1009300045D2BC69CB43DED3D87B33E2D363E6E553
-:10094000EC672A951FB7F3F18FAFE6E3973E5AFDA8
-:100950002E03BC1D778F4F9E05F3385E174172E35F
-:100960005FEAD580390AF59EF6F55950EFE2E29339
-:10097000C336C0FC5B977E9A8AF451BAB4B618DBD2
-:1009800095562D9E88E76677FBB2B406367FC83E43
-:100990007E3FCD15C0F55C48F31C423A989FDB3A88
-:1009A0001BE5E78BE663CFA2FE1115E73982DF2F47
-:1009B000BDFAE5362E57B767E17930CFC8E9439ED7
-:1009C000ABF305FDDD97EE7997CE89F0C04C3C3F47
-:1009D00022728F717EB7F8DAF8FCD996AD7B1518C4
-:1009E000A73ABC651EA5AA3F0FFB39A704A2940C29
-:1009F000829F07F7D3797B200AE1EE317079AE7AD6
-:100A0000BB765DF867847955E33FA05D75B3EA0A6C
-:100A1000435C33BF19E75FCDCCC1FA69413C413F2C
-:100A2000842766FBCBCC0700FE552FF42B40FDA19D
-:100A30003A66FF2F6EA07AD04EEE13F5EABC5CCF7B
-:100A4000D5F3E1EB3B2FE8FFBCA4FF6982FEC5F8BC
-:100A5000175F4DA4F1CF95F8B310FE171551EF05B0
-:100A60000BAF07D460C479FE9AD3D37A93CF80FCBE
-:100A7000C7F77346F45C1DD73C0CE122F910CCC1DA
-:100A80006780FAE776A5507DC9B7989B316C57BD52
-:100A90002B793397CF843E8B1385FA552FF1FE3196
-:100AA0008FFBF0EC8B29623C2E4FEBF1A75F6F447C
-:100AB000BA81E4A9F5927F47CA7DEE4C2A01F86716
-:100AC0006F306BEA5F8C34DFE3827EFBF9B5DF6564
-:100AD000FF89E95CFFEBA3C35B4FB5FD8005F7D34E
-:100AE000F38CF6AB7E5EA9A2DD8B2F76E249E5782A
-:100AF000033150D28783CBE12684F3C79DF8B83702
-:100B000005F86A35C2203D089FBDF99E14E4FF1721
-:100B1000318FE7420CE473510EE2F0967909673D9C
-:100B20009D2DFD78764A2BB4BF45C007109A88F4F6
-:100B3000D829BF98401FC9457DB472F0A94CD45341
-:100B4000EBFAC151D0B99ED91BF2ADB89FE66CCC7F
-:100B5000B79685E0A171FBE0A30E80F3F9ED46277F
-:100B6000B2E546A3FF17284F376E579B7D8CCAAD61
-:100B700008DFF3B683BFC77AB337C614A0BC2CDB3B
-:100B8000CFD9705FBF8A10B80FD8AEC5C3C0666D2D
-:100B90007ED07E6D7E32F286A13FBE5D7E409B1F81
-:100BA0007C549B67ED802DC0836AE578DA37DC7969
-:100BB000D40178EAE3579DF8A98F6DD2E409285F44
-:100BC0006C549D9950DE67B1FBB681903FBD719624
-:100BD00013D15CA9FAE63D0038ACFC74FC513C0F23
-:100BE000CFB1E60F27001E66B7AC351B1DB86E2DC2
-:100BF000DDEE35087A7D51213A98EBD7965FBDAF8F
-:100C000097083CB29C507AD2E31DC6BDD30513AA07
-:100C1000A95F34F8141C9995C540E800B311CD6B59
-:100C2000CD28B7FDF0383E2E0FDA5C0E848777387A
-:100C30002FBBBE7E2C3B3918FEB1FAFDF1386FEFA9
-:100C4000230AC90DDEDF641FC673A06DF7F45B29AC
-:100C5000BDB388D62FED79735A944024E4EDC31DBB
-:100C6000FB5BA1DD2CBFE2C479972DB304F919FC1D
-:100C7000AF62B56E1EEB42CA61FE73F61FF89B02AF
-:100C8000FD576ED4B69B0B7C16F957D596EF2DA168
-:100C9000DFA5DE787DCB2615D73D4BCEDF378AE149
-:100CA000BAAEE75559BC906F4E6106CE8D5B7BB8EE
-:100CB000D7A763BB75BC1DB04B2FAEB7D66676E029
-:100CC0007A6BAD2C1001F3381A6976D9E1FBE50D8A
-:100CD0009164479B6D0179B28052165680ED9CD18C
-:100CE000D8EE8BF7B83DAD368EE3BBF63985F4A868
-:100CF0005A347E62FE799E9FCB02B40EA41357E84D
-:100D0000FAFCDA3C6BE2FA578D317000E151C55ABA
-:100D1000B9FE04787449F801BC6A609D1FC5A2BC85
-:100D2000A56BCF9C1E1C77BE8DCB4FF3F77F6F0951
-:100D30002D977AA0D4533786733DF1B92C77388E2E
-:100D4000B35C713D6985792E17F2B56F6D18D1EFDF
-:100D50008C4DFCBC0139360BE1B26E6DB213E58CE3
-:100D600019209787E1BE991B4EF540DE25BB4C3B11
-:100D7000C8D59BD3B07E7300CF8D758FA7911C0D06
-:100D8000F22FC1A57D4D987FB38272309763D6ADA7
-:100D9000CD2639FC75794EADE1725717723195B396
-:100DA000442EC77F824B099183CFF4F07C901EB212
-:100DB000AE8AA5AE643C772A26990D68AF6295711C
-:100DC000D7243F6C1572643BAC1FD7714A711F3139
-:100DD00084C8A39FE37900E30C1BE3DA26EA39B168
-:100DE0005E85A1E4E19B70BCF506078ED7096F977D
-:100DF0002B0BE7716A6D5801D2D9B031DC5E743CBF
-:100E00009FF3F78821CCE587F4A238672E225F0F85
-:100E10004993C281FEA09F5385DC5E1D39C44D7687
-:100E20003A38AB89CFEBD7F177D14F85D9FDAF37C2
-:100E300076311F091F368ECB0BA716289BF9BC00F5
-:100E4000BF901FF6CB30B2EF9D12E78F8433D0CD29
-:100E500050B2D30B7EB556D0CB5A13A703DF5CAE8E
-:100E60003F05E985113DAC137AD60C815FB686CB80
-:100E7000B5402F1CCE6B9205BDC0DC911E0A1D5CD7
-:100E8000CEBE467D09F01E9BD1E36ABD49E29B19A7
-:100E9000FD43D1BED21DBE6BF7EDDCEB83F3B3EAAD
-:100EA000D78F4731A877C6D894E084F6355B97474B
-:100EB000B9203D6DF445D961FC337EB5C8DF05BC72
-:100EC0006FCF907665974D01FE330FFFE94079E7CC
-:100ED0009189B8BEBF6E35D99125CCDF6E21FD69F1
-:100EE000DE9EB9246743BE8DE7577EA5627EBFD6DE
-:100EF0007E5EF5ABC7131C046F5F8A2109D3400ADD
-:100F00008374DE1693338076E90F54270C037273D3
-:100F1000FB0A9C9FBE3DCEE30AE07B7EB3EA3547E9
-:100F20005F5D3E5FF097F97B1EF90AED7AF375F687
-:100F3000FA4AE1B7D0DBEB6FCA888CFF020DD3D73A
-:100F4000B1EB500E02B83803B86F613E994426DC0D
-:100F5000DEDBF8C213796D282F6C79274AC90DDAC8
-:100F6000EBA53FA3A3B9FCB9D71CDDEFC78BC26EBD
-:100F70001BC417E75B8EFD0AF20050D0795A630A52
-:100F800044DD00F0A8D964223E53B3F3F96D4F213C
-:100F90009D7D6CA1F3BC7AE75B1F5E8FF2EE6E5312
-:100FA0007C315F864D4908E269BE83DBC9245EAAB5
-:100FB0007EF396D931907F5F1C1BC44FF5EE03661C
-:100FC00036F06A388E6D3E606EB57581A7E6B6F173
-:100FD00064277AE15B33EE83336F2A2C31EDEAF636
-:100FE000959BDE8A42790CE184E792C45727FE7410
-:100FF000F5A1FF89AF0DA17A76D42BBAC39F03CF99
-:101000000ED4CBF745B21818BFF2138BBF18F1BA44
-:101010006B5114AEE34B631DA7F3679627A05C5793
-:1010200069F225D829E5DF2B9FBD8FE86F8E529797
-:1010300060CF25FA4E3690CCE04BC6F5CDDA780776
-:10104000AD6F36F310FD553EA3BAFD907E63644547
-:10105000BBBBD8276F6770BEF9E566402AACEF4B83
-:10106000B4DB20DFF8832AF4DC05747EDF27D6CAE0
-:10107000D842CA7F23E4B68D1952DE056922445F47
-:101080009CBF65E531C4CFD9DEAE449C27C0C127E3
-:10109000E0A57C0FFDAAEF172672FC3087719868D7
-:1010A00007E7E858FC8EF58F995C68F70E6927F41E
-:1010B000393EFEBD627C987738EAAB5F2670B95D39
-:1010C000BFBE6F3BF9003BC642E9ABBB7DBFE5212C
-:1010D000A2ABAF3FE07C659EBFA488CA8F9902890E
-:1010E00058EE3F304521BE606181AEF6F51693D8CB
-:1010F000D7DA7298A7510985EF9B5C0E9D0D725748
-:1011000020641F07E9C61CFC4EEBFEA558472BF9CF
-:10111000D3A41F6E8EE007FA75EBF9C3211D7F90F3
-:10112000EDD9C6AEFD4041BEE0A3716BE03C413954
-:10113000A3E6630B9D1B353B4D6E84CFB91D873EE7
-:101140009C817A68B3DCC75A7EABDFC7952F0FED61
-:10115000721F9F5B9DDFF53E86EF5DEEE3D50AF1E2
-:10116000B7FF2EBF85938EEC06DDEDD739DDF0DBC2
-:101170000B3A787EC372A36FC042BBB70FE147073B
-:1011800057094F3DFF5C9EE120F8EAF927FC7DC03E
-:1011900042E028E127E993310F8DD349C7924E25CC
-:1011A0001D77D2A97EBD5A38EACB77237F82F9B862
-:1011B0005F3571FB598B42F236B43B923284F6A90B
-:1011C0008B8E3FD67424253E34EFD7E59B75F55DB5
-:1011D000BABC5B57DFA3CBD769EAD7EC3F64E6FA2A
-:1011E000414053CF527F1BE91957CB117EEEF7D9FF
-:1011F000F395D98774D1ABDD8C7CD1B494F92251AD
-:10120000DE7D432579F792A33D0AE592E5615C6EA8
-:10121000BB6417F9189E6FEF615E817C517E6F0F82
-:10122000E376924BEEF6A898103DBDAD458D427B1E
-:101230006CAB9F1575654721CB28C0B5957557CE0A
-:10124000E5B742D5965A8FF6D026D50964C22A96BC
-:101250004C8DA2B887968CDBA7C1F7596FAB143EB3
-:1012600070299CDB1598CF65C4B883728E42769A3C
-:10127000F9D68F847595B7F0F8838AD55AFCCEB627
-:101280004D890E3890EF68E304E6A05E9781FA9EE0
-:10129000F67B155B4DF456A5DB171E61A7D5EF0B4A
-:1012A000775F112F90CFF2853D86FC1C0B05BF2E7A
-:1012B00054736F9F06F0BF74546516C877B4A86C5A
-:1012C00005AE778742FE1E7408E07E9B07FB12E79F
-:1012D00023E1731EF74D76F772C9F9573E1BF600EE
-:1012E000D2C9DE4FF39E86F4FCDE8FB35EC7FCBE30
-:1012F0003FA77ECAAEAE3FF6CDBFCD443E7CE94DA2
-:101300000B43FABEF4E66F53D12E78E9350BE9CBE7
-:1013100097965AB8BDF9CD483FFA232FF5E6726E7D
-:10132000E31BDFE6B5D2B9BB8CF0F5405F33979B8A
-:101330005AFEFD38DAAB3B5A6055284FBC1941FBC9
-:1013400067FE6B61E40FBFF4C6B7C342E326FEBB82
-:10135000EB91FEEE4B916CDACB48B742AE9FFFFAB1
-:1013600088E7D19F5BBBE780B91CCAC7FECB7FE48F
-:1013700021FFBCF43297932E9A5A9F455BE38A2D46
-:10138000CE5F9A92D13E079DF564ACCFD6BA49B8EC
-:101390004FAE860B87C3258003AE0BE052897CBF1E
-:1013A0003B783C83F0E8F1CF088FAF66727E761D04
-:1013B00043FF6F102E0AF723B444FAAD0AAD9F7FA6
-:1013C0007FF3DB3CE4373FB4DED7FF69F1FFBFB307
-:1013D000DE8FFF69F1CBE9DDDBD741F3D4D3FDD557
-:1013E00074BDEF2794DF15E9A4F95EE37EFFDBFF10
-:1013F00067F84ECCFCBF8AEFB705BE23EDE857BCBB
-:10140000F4C67FA4B21FB1EE61FF47D72DE5F531D9
-:10141000AAF3683ED47F87357FE04C23E9A34BB91C
-:10142000A33C5391FA1BE94763193FA7C75AAB493D
-:10143000DE1CDB6B0DC9C58DAC80FC10BE5E2AF9CD
-:101440006328F802E0F0DBA47C3FF9938C815E8B8B
-:10145000203F26A596E2B3F47AE3D8F00945288F19
-:101460001E5A02F3827E0E451AECE82B1ED74B0D56
-:1014700058F2286DC3F448EA6D47516E1967D3EAF4
-:101480004FB7E9F4A15B1CDAF222F6723CFACF8A7C
-:10149000724DCC0FF3198FF543F4C6D199765AE704
-:1014A0002DAC6999DDF6E3E1F49880D3D570F8CFDF
-:1014B000E176159C849E6C14F5F57033DA1E3E8639
-:1014C000ED8C0CF45EBE5ED297A5DEFB43F0644269
-:1014D0009F368AA1257C8DBDB89F34A45F828B8402
-:1014E000FB8F85B7C4931EEE12BE126E7A3CCC46BB
-:1014F00063548F20FC7B19F38DB8EF6E1472FC38A7
-:10150000630CCFF73AA6BA693FFA399D7FED34A252
-:101510007C32DA1643F19ACCD13B06E54C1431BF4C
-:101520004F61AC6C78CC3005D69B62643E0BE89B77
-:10153000E843233BEA4346FFD2341C87DB6B7B1B2B
-:10154000B95D1A76B72FBC80EABBCC90F73E3687E0
-:10155000B9A0BE378539155E9F45C752381A533139
-:101560002E0B526CE78DE6FD7A13997F29C727E190
-:10157000A52FA6E9D4AFCB10CBDB4715507B9F81BD
-:10158000B7771921ED93C1EDEBEDCB2DA47F785703
-:10159000F6CE42FE513C466B378EC8E2766699FE27
-:1015A00024CB41A96A7026A15C5CB6AC1FE9436AF2
-:1015B000B8BBF615B4F7EF8A207AF4AEB87BC25008
-:1015C0009CDFAE38274EEFECC4DDC378FDE9F7FDB4
-:1015D00009BE7BB687D1F7A7B23C473201AE67158B
-:1015E000C7CC57E043D91D87CC493084A7B9E40262
-:1015F000DAFF26FA76FF1EFD8C13A7A8547F22E39C
-:10160000718F6C5904F9A327F8BE3226417F13402D
-:10161000D9C0F2B6307BEA0298BF57D87BFF20F6DC
-:101620008B1ACE3C2F23BF5AD13B2B1DBE4F605D82
-:10163000C701DBB3B89D461DA36C44FF509FB1DCCE
-:101640001E2FEB633FD86F8280C76799DCEE24F3CF
-:101650000057AA5FB1CAD296817ACF2A53201BE3E2
-:10166000A773C6B4E13A8BD3D9F80D08F7FB55B68A
-:1016700099E6DBEE253B77648E03F1E00192A6F854
-:10168000C2A63407DABDDA463707D03FD0F6649AEF
-:10169000B3D14158A6781CA967B58D0EF445BB7C23
-:1016A0007B3EF7331CB7B746A27E586EB3527C8E92
-:1016B0008CEB9965E7FBBC4F63EB9AEB50EF7C5CDE
-:1016C000756E86FCACC7B9DFE5739BD5AFA0BEB61F
-:1016D0008EEF53B65A1BC7C3EC4EB2F794378D3614
-:1016E000A37E59617399719DC9D99EEF715DEC3BE1
-:1016F00080DF308CE364B419BC4D5E8A3351A36043
-:10170000DFE13E313AA250EFD5C701CD17713F322C
-:10171000FF5298C79A05702C8B76EC427A39519F0C
-:101720004176CF9B91EE107E18C788FE09636B321D
-:10173000CEE7D54C4E8FC5B1F62C1BD1731843386C
-:10174000B4990093906F5B1E66403F5BF1524ED799
-:10175000B0CFAC4668FF909185A3DFE043D1BE7463
-:1017600089D1BD09F2BDACCC18198B74954F74FDAD
-:10177000688EE7335CDFE99FB3E1480FE5ABD792B2
-:101780007F45D205331E1B1707E39CDE9A56807CEB
-:1017900053D2D1A33963FA6485D2C31485E800D249
-:1017A0000319440F93FA6279F19840DF85B9A88F45
-:1017B000D630179EEF49CC897242076B27FF6387AB
-:1017C000CDEC403B97E427926F005E5DD684201DF0
-:1017D0006C83F3DE68626C7B8395D2171BECCC08BC
-:1017E0003C6E474312E5773538286D6EC8A1EF2F60
-:1017F000373829BFA76138E5F736B828BFBFA188B9
-:10180000D2D71ADCF45DF225800BF121C957243FB1
-:101810002AB799DBD01F29F9929E6E660278471588
-:10182000507BE27B92DFE13A0C05417E24F19BAED6
-:10183000B87D4969C8C75AA723FE0BD5F33BF7A16A
-:101840005E5E6973929ECE38DFEB007A45B8A49A4B
-:10185000D97EB4BB362E70B5AD4C0BC2FFAE4A85F7
-:101860001943E8EAEEBA30660C3937EEA98FD1E4B5
-:101870004BEBFFF85622F43F2EDE332D0BE671FCC6
-:10188000C12F9EF9337C7FEEC1B399886F98C7D67C
-:101890002770DCC5E19DF388C5FC3213F9A3FA4833
-:1018A0003B08FC215ECA18DF6FCF3DF877DADF6DA9
-:1018B000F51607CAC39F209E00AE7F11782AABB7EA
-:1018C00010FCBCCB4FEEDC87FB7CB199F85CD932C5
-:1018D000B10F57013C43FCBB279219D923409AA66C
-:1018E00078F5133F370722A0FF130ADFBF0A080568
-:1018F000A518F7B7EAB71FE1FE57EA8F92FFDC633E
-:10190000B505480EF099CE87F6A7D41FA17AACB5DD
-:10191000570CDA11E91C43BE3FC46576C0BA91A6E4
-:10192000116F6539075932FA4D9A143B6E990AF1D5
-:10193000BD629542FE498CBB9902729F2F4B253C9C
-:10194000B6641A695FF5CC6242AE6BA2F349D26B02
-:10195000C56A6887FBA229DF3C3B840F9789EFE5C6
-:1019600039064AE5F726EC17FB5B953F0DE5899EA6
-:10197000589E8B69C134846F4FDB78A31282FF8736
-:10198000B3F8F82D997CFC9EB8D9E0FF1ECE4937FC
-:10199000CFCA45FCF0F34B8E539653B002E338CBDD
-:1019A000568F46EECB1A4DCEA478A8F718F643EB27
-:1019B000B17379C1CAE3956BBA393FA4FDEC34FE2B
-:1019C0007304AD9BECBA55BB5EDA8571FC559F5A2A
-:1019D00008BF558344FC54AE7FD86432346AEDD5D9
-:1019E000E35EFA2C8AFC0F7B785C25A4DC9EBAB8F7
-:1019F00092DB5F9DB0AFBAF0FF1CDEF569549776BD
-:101A0000EA3DEA35D9A9E72BDF45A1FC20D753F8F9
-:101A1000C63709340FE50AF97FE6BFB13CA1AB7BBD
-:101A2000377A7B75A73D5BD8EDF4E57A7BDD912CA9
-:101A30009D5FC0C8E81E97B4D73135371AEDFBDF7C
-:101A4000887B1EDDE935D2BE3D7F03741207FBD3D0
-:101A5000E888467FD5A56EE4E9A86C2E1F5C10F6D9
-:101A6000F04B3B54D2732EED88A4FD346FC763470F
-:101A7000D07F386F8B42D3A865C7086E004F660DC4
-:101A80003DC730DE2CEEEA7977F833A3F11CA97E4E
-:101A900029B20EE96C6EB3E2DA0AF3E9B03AA27B3E
-:101AA00084CCE7ACA0D76A4BF33082B3987FAB907D
-:101AB000B764BDB92D8F91FD18EA5D2439E8D711BF
-:101AC0008CDFFF68FF3DCEF3DCC6C14EF4FBCD6D6D
-:101AD000DE3D8FE4881D11761481CE8A3861D9CF1E
-:101AE0005F055DFF358BCB2FE7843FE8DC2E95F853
-:101AF00019CE13F7D759451B8FF79D68F75D1687E9
-:101B00009B1FF7778F60FDB9CD6D517DA1FE97FBCF
-:101B1000FF48A9399BAF6BAEED581E9EBF5FEE89A3
-:101B2000207FD6977B9E1EFF3A8C77A179743CEE7E
-:101B300007D97F7CB689E363A35A84F0627E1EF7DF
-:101B4000528BF01D1C3ACFB84DBEB4D07DC7E37E9A
-:101B5000CEEDF94D94213788CF5AABC79A9C8EFBB6
-:101B6000C7EB46BEF1B9C2E169DA33DA87F798E626
-:101B7000B7E433A467DA77C9547F9521A49ED9E4EA
-:101B800024A668DC5FE24A21388B7B48225E1EEF88
-:101B9000D5D1BDA2122BF927660E724CBD0BF9E40C
-:101BA0003B268E975E8E27507E9BF95E1CC54D2D81
-:101BB0004C734CC5F92F7A5FA578DF9983051F48D0
-:101BC0006A1D8A718B35AB14E68275B6A571B9A111
-:101BD000C6AF320FE47B023DF8001423B3D3053FB8
-:101BE0000D64E17DC0A72A0D2E339C7FC7CDCCA705
-:101BF000A2DDE8651ECF5C93CEE3869F42BA87B430
-:101C00002636901507FD9D17F8AC9914C8C238897F
-:101C10009A9793294EE2BC99FB2DF13BFA496B0A46
-:101C2000A03DD48B17F1B0D83E26847E6ACA9C0EA4
-:101C3000ACA7C63A1DF9369CAFFD22C9B1AF4432FC
-:101C400094630DFB22799CD3AFC2365B42F0E4CEA5
-:101C5000E67272BCC0239BC1E321D78B78ECF55BA5
-:101C600093FDA8BFC9FAEB4D9EE908075C07CAEFD0
-:101C700073CD4D5928DFCAF9CE8D6AA2799E17F42B
-:101C80003D37BC89C74B9B793C25D6C77C9B895186
-:101C90001C77FB0B168A27399B7C6C2F8E7FF68571
-:101CA0007E0CD7DF96E69FBD9FCA417E04BC55BD22
-:101CB0006809E07ACEBCC0EDCD674C5C1E3B539208
-:101CC000E440BC154DDA3093EC315B2C0AE2FD8C1C
-:101CD000C2CC4958BEB587D387ED1BEA294EBA0A54
-:101CE000D804DEC781B408EFD59CD9DA8FE2C3CE21
-:101CF000BCADE28D28FCBE0ABF7B58D3CC9F213CF3
-:101D0000B673FDE9EC8BFFDE2FF41E9A4CABB66880
-:101D1000E3E0249DC8F205D95C7F5920E07C5F3662
-:101D2000B737D44634AF4FA77572B8039E48EF0358
-:101D30000E13F9F4108C83C854906F3C0574F5347D
-:101D4000DA15B673FDEAEC0E13C58557ED8B7451A9
-:101D5000DCD9CAEB0C1407A17239BCCA00E0A35449
-:101D6000A17EAB26E5F81B49FE66A4C7B66F55C534
-:101D7000388CD970DDDB789C6F31CA8A543E90CAAA
-:101D8000CF88FC99BD0349AE83FE5D785FA9EA6701
-:101D90000F70384EAE7C97911DC34AFCB5A6D38F09
-:101DA00033321ACFBBDA953744E33D40F69ECA5032
-:101DB0003ED1C3E9B2D199887CF57036E75FD57B17
-:101DC0009F31233FA816F743AA5F54B83F19F6196D
-:101DD000DE93AC5E71C313449FBF37B14C58CFF94B
-:101DE000E6C7A242F1B14BF4D359DFECA4FAD550C7
-:101DF0001FFBA95EF14E14CD679B89E24CF478BCC1
-:101E0000E6F62FAAD7D4BE933E9AB91DE5AAF5B33C
-:101E1000633FF914FAFF7A4798D3475F9BE95ED98D
-:101E20003953F36C5CFFB99D61C48FCEC570FEF071
-:101E300025F04F5F36CEE3B647292EEB0F93E93EF0
-:101E4000DC1CBFB65F39EE6F906F63BC549C331AD5
-:101E5000E3FA6ADFE3FC0DF0723BB57FCF44EDF5AA
-:101E6000EBF8A568D7B93F7746103D9CEBC9F172F6
-:101E70006E57369D476D319CCE61BEA9787FEEDCF2
-:101E8000CEEC7CBA9786C20DD04395D06FCFC534C7
-:101E9000A7DA43CADB4C424F0B404DA41B6C0372C4
-:101EA0005F553D97ABAAADAB293E04E36A87155059
-:101EB0001AB0C45E1D1F0BF44AFA63780EDF5F0C84
-:101EC000C74B10F1DB24EF349B917F7B845C58B3CC
-:101ED000431F5FCBCBCF6477DA391DF1329E17E910
-:101EE000D0A7509C49F5B2057391CEABEBD6DE85F9
-:101EF000FB4CCEBFDAC88A500F6B53549A475B181D
-:101F0000BB67129E1BA1E384C86D5F07C761F6041F
-:101F10009257E91CBB92EDE074832726DE135DA681
-:101F2000ACA671D2A43ECBD725E104E030635C5F60
-:101F3000DB6851DECDBAE53CF5EB96F3B1E5707E9A
-:101F4000D496E6787424E2F9772ADDA7BDFCDDE0BB
-:101F5000E8D82EE4B2E0B96E0EC6B7C2FC9391F693
-:101F6000D0EE92CDE5F16A8C9F8579666DD4C67509
-:101F7000E76CD1E6FBEFD0E673F768F3792DDABCB6
-:101F8000F3B036AF887151CFC6FBBBA867638A7ABE
-:101F9000B6C3C2F56CCCA39E8D29EAD9F81DF56CA9
-:101FA000CCA39E8D79D4B3312FE18DFA36E651DF83
-:101FB000C6F25B73B83C5623E224110F48EFECD510
-:101FC00030CD7D9F4B6FF07B1C40077CDF4C37D3BF
-:101FD000BE790A6B90DEC1ED4A3D275B1D18EFBB51
-:101FE00038D633246728DEF738B62219F1666CA597
-:101FF000B8D3F9AFF1B8D39A82301BDA375A977F4A
-:10200000B902C339DDB19E1158FF92A97D1BC2B739
-:10201000B6FE10DD7B6F5DE278EF268E3FB2B3B087
-:10202000CA58929BBC78CEC5768F477DDC375BADB6
-:102030008DF3D6C77DEBE3BDF57420E5BDE74CED30
-:10204000C9C8D74FBE605D8DF33F1926EE9F4CB3D4
-:10205000EAFCFD424E5BA36CC6F37A464E2CF79F1A
-:102060001D05F9BC8B7356A6E55706931CDE995FD8
-:10207000AD18E85E5C52029D438BC49C5295F6B647
-:1020800095C8E7E61AE8DCBC0C72198E77F903955F
-:10209000E487EC0D06CD7AFAF9C335F435607BACF4
-:1020A000EE5E434F4DFD41FBD375F71AFA6BE3E843
-:1020B000A72C3980FAFDE4D58335F52ADC37E8E032
-:1020C00028E62DE4D70A383F5CB0BEA7166F484516
-:1020D000FC2E9ADBD1B612E5D357C2E85E5825FE36
-:1020E0003FE08B95D027DE67ACDC23EE03D76BCFC8
-:1020F000E172710E551A99CF1E1BA4C34A3B73C5DA
-:1021000040FBB9FD8FE50550AF78FB8FC3ECE9A824
-:10211000578C4E447E946A72511C6CCDEECC98253F
-:10212000D0EFA20CCF4339B0CF4E351DFA45299ED2
-:1021300087BBB9BE7772F56FA2284E4CD05BAAC997
-:102140001E8E78DFD4C4E3E3D03EA6C606E9625310
-:10215000535C785F5B70BD413AF88EF004F8E1762D
-:102160009CCA83E4F7E86816EB1DADF8509E96EB29
-:102170005B28CE15D697F773AFC89F12FA855CE738
-:10218000F97E07F21C78FFA2617FAA8AFCDCB063AB
-:102190005B32A4B916CF165C4FE5A6CC3F8F847195
-:1021A000AAFEC4D7F3F9BAB1512350FEDC69721606
-:1021B000437E65D3F366D4B3AB8C7E33C557BEB0D4
-:1021C000C98CF1C5376FDF44DF676FF7523CE51C00
-:1021D0005647FAE769F9EE808047E51865A31DE6E2
-:1021E0001DD68FF38FCA70EEBF03F9E82D7CF7E39D
-:1021F000F276251FE378A6B8779BBDF0FD0DC18F61
-:10220000F5FBA4E3DDC9853D081EFCBEC69F18682A
-:10221000F11957EF8BC957D2685F4CB93280F4B2CD
-:102220003B02FDB8FE9BABD37FDFE5EF2E74B4F02D
-:102230007D50690EC44FC67DF2A689E4DC5A386F22
-:102240008617A05ECDD8F590BA47AA1A7A9D3F2E80
-:102250004243CFD358C83E81FEEEC4A09190FC9477
-:10226000E20C4DFDA95306E8E8BF20584E7CE47A05
-:10227000CDFDBADAC53E874272E618ED77C6E304B3
-:1022800081436BDAD7B249C17A48DF5BB81C5CBBCB
-:10229000276633DAFB2A0D5C7F9AE6E1DFE7EDE79C
-:1022A000DFD934A6D9877D329C7FE6E7A289FC027C
-:1022B000D29E3E0DFFDD05FC4112E9BC1F8EF7E208
-:1022C000D11EA1B93F2DFC81386FC443ADB01BD5E1
-:1022D000E670BB51ADEF9819DF1D00F81BE362A952
-:1022E0009E350EE3239B14B22B62BA98E225B5719A
-:1022F00058D81FC631CE3BAA7A719FE8CB81EE78C1
-:102300001CFF6B3CAE74CE067D1CE46AF247CE43E4
-:102310007B5008DE6EE9E710FE38FF8A9E08BF6238
-:10232000259FEE45EE3860C638BB295362F271DF57
-:10233000E8E94BF275D8CFA47F77BC7B88E8ABA3E4
-:10234000D248F4FB437098E7E276543DDDCD66C792
-:10235000CC784F7CF61EC589FA28D64378F4447AA7
-:10236000D4C1232EF66A3848F874C26B8F3ECE8DE6
-:10237000C369CE7EC51FE8024EFA79770737B99E4A
-:10238000D91ECF78E40B725D7370FED83FCC1FFB73
-:10239000977E08365CBF3F33C83E35CFCDE363F54B
-:1023A000F430E90AB7BBDC79C548E99462ED7EC434
-:1023B00076B82FEEB89240E53F965EE6C13CF9FD57
-:1023C000A76BA313B90EC97783FB81DF1BF8A17735
-:1023D00081F476C73BFA09BBE3503654138F2CF8CF
-:1023E000AABEBD3E1E59CA01FAF3C51B69A0B8C9F1
-:1023F0000E5B3AC91792CF7AC4F9E159FE0DD5F3B5
-:10240000403D3E9B04CD79E311F6BF8591E9F41E72
-:1024100043EA92B804C49337CC4EF1F7DE252AC5BF
-:102420003D7BA19E23443E59B12C2315CF8B130F26
-:10243000653FEB03B9FDC4FDF109C3619C93CB4D2E
-:10244000F15647B0DE89E585A918A77172AD659A86
-:10245000BF0B7835F4E3E743ED831FD17976C1F004
-:102460006ED434685FB3FC95280CF3AF5ECECFF129
-:10247000C40CCF83FDC87FBB699B1DE167DF9487D8
-:1024800076DF35701C607B293F542D2F4C44F9A218
-:10249000E61F879EB5E33DEB25A604943FCF7C0065
-:1024A000E7A142E719C90DA7C3A00BF2A745921DEA
-:1024B000E1B4C25CE8573A6F38F0D795A817E63711
-:1024C000670520ADB578D6F443F97FF9F324B75406
-:1024D0003DBC244B55B1DFCCE8AEEC2632DD26CE38
-:1024E0006D94DF3145F91DE364507EC73CCAEF9817
-:1024F000A2FC8EDFE76FD0CA7FCF087FA1B427F799
-:10250000696CCF47FF9D6F0CCBA9A3F3D69683F2DE
-:10251000FA2225DC89FC6811CA4A98FF2C8CF458F1
-:10252000B625999FB702CFF556EE37FA56DCCFBDE8
-:10253000B11D64B210FABCE98A9585DE9B1DCD629F
-:1025400034F9B1D6644DFD427B9AA6FCE6A47E9A8E
-:10255000F25B1CF99AFC6D392334F52738476BF28E
-:10256000B70FBF4553BFC455A2C94F2E9AAEA97F1E
-:1025700087DBAB299F3A6DAEA67CBA6781267F5771
-:10258000E5FD9AFA77D72DD1947F6B008D14E8A5DD
-:1025900005F52E0BBE9F62A5F4A7AADD887C63D14A
-:1025A000EF326D88EF91630D755DD9F73F14741CA0
-:1025B00037C0F53ED24B6FF13E4E6FF1CECD293C88
-:1025C0007786A21F12A88AF4DD63C948BFFA7AFA97
-:1025D000F29111072F3B0087A35E34DF61043E3484
-:1025E000F2BA83833320FFD3176FE4F91B0EFE2664
-:1025F0001DF20D2F2EE5F941072F63B9F9A5313CE6
-:102600003F9991E8F148FF8E29184F32F2A6F4D590
-:102610004E6E27E9F29EB94C110E785F1BE180697E
-:1026200000E817D38340BF981E06FAAD00FE74047D
-:10263000E817D3A3A07FE2F77F05FD13D37741FF0F
-:10264000C4F4F7A077627A0CF44E4CFFD0308DD2F0
-:102650000F1A3CD4EEC3864A4A3F6AA8A3EF9F34C0
-:10266000D453FA97061F7D27473FB74333CDFD006C
-:10267000F433A23F71BFE97CA81F58FA2BA57FB2A3
-:10268000B18EB54620BF6835C67C610DFA1DBBB75B
-:102690000318D91721F258347345F42779A1979D6F
-:1026A000F8B7F8BEB38FC7DE1FE6F5A7B4C99983A4
-:1026B000553CB7EADE42B7EC9FC4FD7A7DBFA784E4
-:1026C000BCFC657F570F6C27FDEBD2BFDD193713BC
-:1026D000E27F3784C4EBD05F48DC8DF483CB389F36
-:1026E0001BADFC9EB1F473CB781ED95FE1D78CF89B
-:1026F000C3A85546925F228D2C80FDCBB89D51D644
-:10270000E67C8C63185563A37BB589F0DD5C40F5EE
-:102710005C2AA45BFE06F5F3827EF544317F28A790
-:10272000F9177EED213BEC28115780EDADBCDC871D
-:10273000ED47A16D6108A5C49F9EC17BBB05413FCC
-:102740003FD68FE0F503D85FDFBFC37851C17DD39B
-:102750003BB6391FF975EF7936BA17BA717480DE56
-:10276000B322A313C065B2D49FAC222FFD79DB1333
-:10277000C98E3456ECF50C87E766C4A7DB62FF2CE4
-:1027800082F659466FB44F9608F9F93FC15B31E2C2
-:102790004DC253E245E251E223247E8AF0D01D5E11
-:1027A000F5F8D4E351E2AFF0EB205E10AE57E32D25
-:1027B0008857B4E7FEB3E06D8891BF5F66A9B1D2D8
-:1027C000BB683F84C77BDAD9F868A872CAE139854B
-:1027D000E7BCF78AE308E6CBD9E8F1885A597EA12D
-:1027E0009B72CFD7EDA6E8107CDF28F01D9F06F581
-:1027F0007B5C5D5FD693EF31C8FE077753FF9D305A
-:102800001977E1B2E50F0BC63F2E2AE4F02F4A53A9
-:1028100009FE6373E7909CCC6C5CCE74C07FC89754
-:10282000C67FE7A6772DBF613BD073CBC6C76BE5EC
-:10283000D3229DDFFA562197DEAA934BF572A5BFEE
-:10284000BF902BD358DA8F7CAFF257FD89AF5EEB88
-:102850007B95FCBDD371629FA5083ACB70A86C2410
-:10286000D211F3D0397918DF3BCDC377417D94BFC6
-:1028700085F929BD8D05E87C9D008C18F3B733469A
-:10288000F7C80F454C2CC5BB7163078FED8BDF4339
-:10289000DE656BC17D3A4FF5FC9B3DE45DB683E39D
-:1028A0001C74BFF2A03583E42FDC87A6107BE0DB2D
-:1028B000703EF585F3E3109C5F98BE05E7575F58BF
-:1028C000EF6FE1FCC2FCAD394B18B61BEFD0C6ED83
-:1028D000C8F6B7D9C78262D23DFC6ECB7BB517C2B2
-:1028E000F79D98EC71683F7F27E6BA71B8DE776292
-:1028F000120D3CB598291DB8AF6F57F2A1DC07C186
-:10290000F1C6D3787AF84A78EAE128E1FB5F80E7FC
-:10291000175DC1F394909F3BAC7F8C4A4A47FF5DA3
-:102920009478C7F277792AE4CFE0D492315EF50645
-:102930009AE7A8FA11CC3898FC36B908D71A2B8731
-:1029400097DE6EC5B6241A42E377BF307BBEC5F171
-:10295000BFDCA8D2BDF10B2F87913DEAB49FDBDB32
-:102960008A14CF77488F35AA6335BE3FCADEE1EFC0
-:102970009CB1EF0EA54E8AFC1174BA85DFB7AFB1DA
-:102980008EEF128F529FFA0F878BF80813EF454A8C
-:10299000B9A29785BF4B20DF2FEC4ECE1816CEF98B
-:1029A000602F8B781741E015DA513E05FA19067C45
-:1029B0002EE5D170D22FEA7BB8E2070C0DDA113A7E
-:1029C0007A45F891DF8E0A0CA077B98A8EAA144F47
-:1029D0007C50C477DD3CA0CE960E78BA29D3933ACA
-:1029E00000D7A57EA7229F7917D61987F687A383DC
-:1029F0006DA43FFE483D346B80E017792C4F735F28
-:102A00004DD29D6AA3F89D8E0FF87DBC856FF3B8FB
-:102A1000CD853D548AFFD7C7C58D62598FA2BD7140
-:102A20006CBCC9E97704F98B7C07C89264608E108E
-:102A3000393BCC11CE1C21F389C889D5E4239D3DB7
-:102A400035F5A387A76BCA635CFD35E57145059A2B
-:102A50007C0FF7F59AFA89D3C668F2C99E5B35F503
-:102A6000532A2769F3B8EF00EEBDEB6668DAF5A9E3
-:102A70002FD3D44BF35569CA99CF752C2701F93858
-:102A8000FFCB58B55053FE7454118F1FB7CDA67BA2
-:102A90008A994D3FD3F427F19B12C7F1CB1CFC7CE4
-:102AA000F0C17FE4B710782E4CD29E1B63EDA30FCC
-:102AB000DB29D5DA35527E200E6ACE7F950E6A99D3
-:102AC000960EE2791C4FE1DB831D28C7E8F18FFEEB
-:102AD00088D075A23F22142EE88F08CDA33F22B4E0
-:102AE0003EFA2342CBD11F115A3EF8A816FF438F5E
-:102AF00069F17FDD4763FE533C8D68D5D2831E4F5D
-:102B0000379CD6D2C7284F38C1652CC86348EF120E
-:102B10004FD3E03F3AE7993B1AED06373117DD0B0B
-:102B2000F89FC2D7333A7C7DC3560FC5772E2F79D5
-:102B3000391FEFEE9C7FA28FEB79E41FEF0B3EAFC6
-:102B4000B703C87852DF188E4FDFF130E257DF1A33
-:102B50005A23F1FCF8A9DA4A76F964D6FE16BE3F8C
-:102B6000638AF7FC1AF95822460F40F95373EFCCE9
-:102B7000C7736EE6BF585251AE99D987BF27C87246
-:102B80005BE99D16399F99293CFE68DF00C1A79D2E
-:102B90003C0EE9B5015CBE8E74DA290EDA9BCB449B
-:102BA0009C274B9D3910E9F0DDB06CA4B375DCCEE9
-:102BB000D56A72505C8B0FE811FD94286FA33CDC42
-:102BC0005BC8A38D1F5BAD9CEE98E67CEFE7B76A10
-:102BD000E270076CB76BF2039B9334F507ED7768EF
-:102BE000CAF303399AF2C1479D9AFCD063C335F505
-:102BF000AFFBC8A5C98F682DD2D4BFE1B45B934F9A
-:102C000061ED4F223CBF1A90CEE3FB156107707057
-:102C1000BCCCFC6902DDA7917A848CCBF6083AD64D
-:102C2000EB237DCC1E8AF36E4C664EBA0F6215FA0A
-:102C300020D3EA291E11572DE579E6D3C655CB7866
-:102C4000EA4E7D46E82F529F0889A776E1FC653C55
-:102C50007527DEC5FB927AFAFC87C0BB7E1D7DCC52
-:102C6000FCFE57E3FD66BAC722E7A79FD7CD221E19
-:102C700070ABB5EBF7876CB9DC6EF068BADB980B1C
-:102C8000F59E85E389E079D578CE561FC0B7F1E788
-:102C900066E752C70F8F3773105F4F29BEAB9A4B51
-:102CA000EF74D2BD35396EAF5C4EDF863CA5CBF5F7
-:102CB000CD8CE6F15D2CDA4CF72EBA1F8FC335C9E7
-:102CC000CC96D13B49E21EC2DDAB9BD7606845A9DB
-:102CD000B9C9C4DFD5F79BD04E543C06E4C07CE0B4
-:102CE000135B77AEB381BCF66CBD91EC3E19B9F1C4
-:102CF000778204D979AFA40FE8694827C5887FE8AF
-:102D000077C3401EEF3C2E97AFAF50FDAEF33E8031
-:102D100045C3E7B9FED705DD113DCA75FC6FDD0F70
-:102D200090F4AB8793D4AF9938BFFA8A7949F87594
-:102D3000DA4F04FCE4FD0CC702937BB38DEE7914EB
-:102D4000615C99C4DF4B03395DFE04E13194D743E4
-:102D50007ED45DBD4235371AEDE01DCC116DFF010B
-:102D60007BF0FFD2BD09827F77F7BDBAE31357F13D
-:102D7000876EEE7F75479FF4F723EE8185F0091E7D
-:102D8000EF23F0E1EF6B20BFFACA48ED3EDE9ACBAD
-:102D9000E17BABD84F706EDBF2B57C82A15DBF7179
-:102DA000B92AF8C4ECCEDF9FC0EFB3969B48BE664D
-:102DB000CCBD1EE30C3E5F67A2B8D8512E46724CC4
-:102DC000D946C5BF49C173746412CEDFEBD39EC729
-:102DD0003731E70AF47F94AFD27E9F63E3BF53316C
-:102DE0004BFF6E8AD0D7E7FC80BEBE3E579CE34EB9
-:102DF000E624B94BF8FF2B451BBDDCD5E1E77E335C
-:102E0000D4B7556E77A2B83179BE3BD07F13F21E8E
-:102E100008C0333C07CFF165C62EE3F93AE1D94D3E
-:102E2000BCC2799B8857B0F1F88C8E3D61DCBF291C
-:102E3000FD4AA2FE79DF652AC7FAD8DB857C1E77BA
-:102E400021FD497A7F5587CD40FE968E3D91E49FC6
-:102E5000473F4E34D0C159C3EE84E169C1F9795A74
-:102E6000558D1F449F7A96BC42FA62628627908BEA
-:102E700071D846A7D509F9876C07E9FDA86261F703
-:102E8000D2CFB753EF1AC9DF77E9F07179B6A388CB
-:102E9000BFC3017C91E13E927108250CB45448BD3A
-:102EA0008111349F1FEBCF997C259FFB31AFDC4014
-:102EB000ED3DAB4650BECFB2350BF01ECC1D8D7331
-:102EC0004CE8C26E7D72716138346DEDED5F1A8E23
-:102ED000781BAD7469976F13E759AB2EBE5EA625BC
-:102EE000821FCD1B28F9B888435AA2D03E58A8307B
-:102EF0001997447C5CE62F37897C21CF2F5ACEF37B
-:102F0000ADE27DFD6DC28E82EBC614D78D7AFF0EC9
-:102F10006167C175638AEBC6EFC8B7308F7C0BF36E
-:102F2000C8B7308F7C0B53E45BF8BD8CB953F355B5
-:102F3000EE871A17BAEFAE58D9B890FD827EA8D0A6
-:102F40003CFAA142EBA31F2AB41CFD50A1E5E8877F
-:102F50000ACDA31F2AB43EFAA142F36CF82DC13C5E
-:102F6000F2395789263F19E4FC7121FB1BFD50A162
-:102F7000FDA31F4AD39F6781A6FD5DAC5ED31EFDF6
-:102F800050A1F5EFA957347EAA7BC43BA7E51BE20D
-:102F9000887E221DEED48180E77F8BF8C77DA674E2
-:102FA000C473CB5CAE97853B399E9B8A38DE0D8C13
-:102FB000E3B97D3AE179B199E70B797CB29E7ED095
-:102FC000DF33CEC4FD3D98A2BF0753F4F7608AFEFD
-:102FD0009E7199DCDF8329FA7BF03BFA7B30457FD9
-:102FE0000FA6E8EFC114FD3D98A2BF0753F4F760A8
-:102FF0003BF4F7608AFE1EFC8EFE1E4CD1DF83DFA1
-:103000008FA3DFC9149C17CAF17D35FA23D0A146DE
-:103010007FB46BF228C787D647393EB41CE5F8D099
-:103020007294E343F328C787D647393E343F33D7FA
-:1030300041FB0BE5F9D07628CF87E60736F9DE426B
-:10304000DBD9848D170F63DA1AA93CAB00CBB867C4
-:10305000E74B771A413E6B0D53526380739A94DDB0
-:10306000778E83BC47C4FFE5B17603E2DB23DE53F2
-:10307000F70418C55B0EFC5B32953F23EF87E11F19
-:10308000E03D7F0FA3DF2591FE62D9DEC9EC2AA6C1
-:10309000B27E30DF753DFDF8B21EF1CF9079E00DC4
-:1030A000608C57C95F6C2BC078CF6D0685E224B663
-:1030B0002DE571C27ABA7A6C20F78B6E33EC3E88BC
-:1030C000F740DABD0ADD07CE32B2A3A60284535D13
-:1030D000019EBF0F0C8C117EBEBAEBF1BE899CB76E
-:1030E000B46F029FA0FB7323DB8F8D8D867E3CBE69
-:1030F000D1F43B29C5662E37603BD42707F814D797
-:10310000E610FA5E3E90F34D8F8F8FFFABE726F20D
-:1031100076E1BCDDAF9E8B22384E5CA650BCD4C895
-:103120001DCC85F7737F21E63D604740C5F1BCCBE0
-:10313000F878B25FEFC654BAB7E865ADE392C84716
-:10314000A230E4DB126EB0BEC3B83E501B8EA27D2F
-:10315000FA5AEFFDDC3824A610E3E8580BA3772CCD
-:10316000270C795FB35E42FB30EA97CEB56C9F4285
-:10317000EF054FF42D598A6431C1B7E0AD1E587F79
-:103180000B73A639E828A27BB1723EFD5DBB0D70C2
-:103190002CB25C76CC10A620BED9A1B810FA819DC5
-:1031A0003F05F19DEF34D1FBBD2546BB89DE8FE89D
-:1031B00026FEE4B24DC69FE8E4055D9C49E3E28F3C
-:1031C00052D19EBC30D240F6DF85AFF0DF03F06C09
-:1031D0005088AF4939C82BE2D42E2F7BABC754841B
-:1031E000FB6E13F527E34F6A33FCA9068CABEFB9EE
-:1031F000292F562539E000F2C373BEDFDC391CEB02
-:103200002DE7EF585E5E764774807AE2FE9A0A01F7
-:10321000AF0A11C7E4C507BDD5E0EF69C9FB1DAC16
-:1032200089CB7BD29EE3FDDDE023885FEF33E25D57
-:10323000E9555EBA97AD8F239ABBCC44714773753D
-:103240007261B5900BAB7F402EFC78A04E2E94BFE0
-:103250009722DA30B5D78718B727EF25969AF8FE68
-:103260002FDDCDC80E5BBA64AC81DE417E85D34DC7
-:10327000E9122EDF94BEEAA2FB85525E7C4FC83174
-:1032800093AEA410DCFF28E4963B30BE12E05BDC7A
-:103290001A26E2B092299D7A85C75B4EB2713ED064
-:1032A000FA067F07A2C367E1F2D461C6DF31D3D14A
-:1032B0006589D16FC00B77CE914097909F80721037
-:1032C000F4370DE5A238A4F3B4428ADF2B52E8DECE
-:1032D0008B9ECE8B4D756F617C68F156E6F4B150D4
-:1032E0003A07FAC5FE7C0ABD0FE0117AADA45F3D36
-:1032F000BDCF8C10F6281BB73775DA255046C54769
-:10330000BA7DA6A918FF3A137D7B3D39C160DC590F
-:10331000642E2F8FDB659ABA0CEF2A7463A7507F57
-:1033200066267878E43B08DDD80DD05E807CF2EE2E
-:103330007BF3CD65217CF2E4A0318307F508E2BB85
-:10334000ACF3BE5F2EBD0BBAF0A14CFA3D9CEEE48F
-:10335000E172802BEE8B99D1ADF7E12FB315E431FB
-:10336000D7B824FC7D41261F210F601CE10C91BFC2
-:10337000272FEFCFAB6C0417CAE7ED8A9B8A712128
-:10338000B5D6D6F14876F3733D45788F31C89FDCCA
-:10339000AE1405F9537E0075C29BB3F83D2FBD3DB9
-:1033A000E29E3C5E5F6F9728CFE57C5BFE2ECA896C
-:1033B00087F6EDC2F34ACEFF4437BFC330358FCB1B
-:1033C000B3FF53F720F4F71F66F5F414E5C17CD77B
-:1033D0001BF87DFE9E6A1313F621F20B4B7EC1C4CF
-:1033E0003B1841BCBBE81DDDC687147BA87DCAB372
-:1033F0004AE1F7E8BBB1E3B09CF627B742BB990DB1
-:1034000066FA1DBFE7B238FD3C07F443BF97623E42
-:10341000F696352D08C74FEB7F69A2DFA561814C79
-:103420007C7F67465D9813F9F1C941EE9938EF88C2
-:103430005C27F1A1C183387D65C4BBBD7978FF6E7F
-:10344000F58167F13D81F92D69F47B25DEFDF92BCE
-:10345000F09D9393833CB3B1DC6BB3D37B1AF396AB
-:10346000C5D0F9353351DC0B65EDE46793F07F305F
-:103470008FEB89D73999F8BD2D71DF01186489A6C2
-:103480009E88EFD6ED0F6927D4DB19F4EF4B7467F4
-:103490005F90F604B41F9843EC8CD23E61CA393178
-:1034A0001DE58652B3F65EA24C7F2DE62FF5C0597E
-:1034B0009DE756EEF844948FD72A767A6FD2E69835
-:1034C0003A02F215474D18D9C98A631D667C7FA060
-:1034D0001DF08BF1D165B05F91CF948A38AD8A0D24
-:1034E0002368BF55F821EDE21D4E99DEB5F650EF89
-:1034F00057917E022EF25B56D85DE6D8907D5FDE56
-:10350000A468DE1D90F9E7F2545A672988E308BFE2
-:10351000BBEF4D33E3DB3EA5204660FCDFAF057D0E
-:10352000C876508FE2418AD3D911FE0E3CCC3B8D38
-:103530008F5710D27F5913BF372DF3509FE49F1739
-:10354000F222A93FAF1DD69D86A99DE609702038BD
-:10355000B5AF81FE1C340EE1A33CE037A1BE5D8A0D
-:103560007128909F61F79B709CB265FC1D13CF6A18
-:103570003E8E67558C7920CA4746BBB937C22F9C0F
-:103580009F57303F92232B002E781F0BEFBBE1D9C2
-:10359000A2878F57CCB7A22986DE51087E5F6B4287
-:1035A0007C4CEFE65D844F05DECB968DA6FBEB15DC
-:1035B0004617DD73F008F87EBE20EC61F40F4C5F17
-:1035C000F784290DFDF882CF7C2AE05A9C1EC8A4FE
-:1035D000F78A168439719ED3ED4DB4BE4EF83E0E77
-:1035E000F050F09D1B37C117E8C287717B15EBB413
-:1035F000F80CCE87C3B7629D97F6DB6CA3C76C0F40
-:103600009DC786039978AF6A3AEC6F7C5782D93DA3
-:10361000745FF28BC7A7A6D23A619E08D748A7630A
-:103620003CBE3F0474C2EFC188F5C87BDD72BCCBE1
-:1036300079FC1EFCE51FDC972E926B1A01BF68F720
-:10364000EE6E5F9A9171C3B8E60AFE3B12FA7D2ACC
-:10365000F7A7DC97729FCAFDFBACC91D4852827C5C
-:1036600006CED9BA97BB80D3E0411C0F33045E016C
-:10367000AE8743EF79F51AC4F15A9AAEDDEFD81F41
-:10368000F66B95E5630299F82E93AC2FC72D8DE567
-:10369000ED90EE91DEAC830C9DF517527DED3D95DE
-:1036A000F24E7EB1637902F28BDD0AF783AE39D434
-:1036B000FBA728BFEEE4F2EBB99AADF3F0BC644689
-:1036C0007F6AE8FBFEB340CE413E315B9CCF158163
-:1036D000AEF9C553599EE44121FBB9E2B19D591E93
-:1036E000CE6F02C86FFEB2F3F53F5DEF089EA77282
-:1036F0003D65ABDE37796DA1F0E37ACEC3391D7439
-:103700001FAFDC667660BC73F9322FF15F960472EE
-:10371000A112127FA6A30BEF3285EE9195D70FF37E
-:10372000ABFF837CBA7C7509BD7B20F126DF6791F6
-:10373000E7AB9CFF4831FF9B06F1F633047DCFA831
-:103740001C6D4E8E27B91BC32CD974F17D7A85F67A
-:103750007B27DE3AFDD7B92B70BFE0FD22D24F5652
-:103760009BB8BD6F07B73F9E5BB8EFF77742BDB31D
-:10377000EB37A532558B379453670B79758EB0FFB5
-:10378000758137F7A090389E39CF71BC95EFFADD7F
-:1037900067F89E5869BAE0776BF83B0065CDBB09C6
-:1037A0008FD357AD35A5213F1A94A6E1E3E575F90E
-:1037B00076B42BCF58B5C9847CC223E1A0DB0FA51A
-:1037C000224E58C219CF2525C4BF21EB237FC4F751
-:1037D000EFEF5D101685F13C729C87049D97D7C56D
-:1037E000C4E278E575DE5FA03E24CF03FD3A4F8644
-:1037F000F1FD5206FDE1BE3D39DA99BA303728CFE6
-:10380000EAEBFBC4BE7BDAC47FA72625A2F9058AB2
-:103810006B981FEE44FED1B76FAB1FC745FAC67950
-:103820009B0DFC776DFAD6B47E85F3E8CB785C0D02
-:10383000A6F83E16FA171220BFD9C0EF6FA5AB3C11
-:10384000DD26E003E5012C67F1ADF4FB1A2171B32D
-:103850001AFA35B32DF4FB89E67846EF9B497A9541
-:10386000FD487A95F4DCDDFA9EBDC6F59D4CE3F08B
-:10387000348BDF4DB9E6F559F8EFE8CA75C9F9811F
-:103880000CEFA2F73D1E1848F69E934B9CA91837E3
-:10389000D9FD7AD7152674B15EFD3AE5BE91B1F037
-:1038A0009DFEAC26EE7738A9C0F906ED4E2E08A392
-:1038B000F836B9AE1F6B0F3F382856D8775A2351C8
-:1038C000CE2C0D0FDE9747F81DAFE7BFAF2BBF4BD8
-:1038D000B940BE3327F9F7A93A716EB2D635B8BFF1
-:1038E000597D06BD7F72BCE96424BEC77272349FE5
-:1038F0009F6C77AF89DF4F66916607DE138BB8F751
-:10390000FDC244F40FAD4BCB57A0DDDDF5838FE353
-:10391000FBE3772F4B24FD7E96CDB102CFC559BE78
-:1039200034F20747ACCBFF02DFD19BB56C00FD6ED4
-:10393000EFBD0A73933E29F484D9ACF38FF4843934
-:1039400082AFCD417E89F7A5EA0FD1BB79B39D61E6
-:10395000F978BECFD9C0F58462035B85FEC43E8D85
-:10396000EEF1C8C7DA9F54F8EF3E6FD4BEC3959C02
-:10397000EDFE0CF98CFEDDBB7B4DCD2E5C07037993
-:1039800004ED4EB36C6E92EB4B05BD1C5FD746BF8A
-:103990009789F0A6DFCBD1D96FFA98F93DE2F648C6
-:1039A00003D9E300EFEFE1EF91E17BEB163A6FB45F
-:1039B000F69B3E0F0EA7DF6B93F7842A84DF49D274
-:1039C0008FF45FCDDA3499EE0FCD427BCDE0E0FD90
-:1039D000A915EBC6D2FB4E156B0BD7E3EFDCA40A9F
-:1039E000389E32B696207E4E6F4A8CC57BB915B58F
-:1039F0008D59785FA862D34ABA37747A5318DD1BA1
-:103A00001A672F1987BF1F327B23BF9F27F7A3CDCC
-:103A1000C9F76355ED58BAF7F3FF00B910AD8C0044
-:103A2000800000001F8B080000000000000BCD5636
-:103A30005B6C1465143EFF3F7BEFECA5ED527AA161
-:103A4000EDB6E5B2EAB69DA51403189834802412A9
-:103A50005D0805368176088114686B4593164364CA
-:103A600061951088711F5AA104CC52A1BEA8D986B5
-:103A70004621AE66A541A236B18117129266FB526D
-:103A80002E11BB564D69A2E039FFCC660997C44799
-:103A9000E7E5ECFFCFB97FDF39B3ED0F473EF1D457
-:103AA00000ECAA02F02C01F82B91178F3080F6431E
-:103AB000972A240E10B06A56650EC03E9EDCBCCC20
-:103AC00007708FC5074B84BE6FAE47067844CFAAF8
-:103AD000A7E5E421009F15A0E3BD9BC2CF7D3EFA80
-:103AE0007A18EDDB3B2EBAC8CFBEBE1B4B3D783FEC
-:103AF000B7462B541AC9EFB9418F0400A7CED5851C
-:103B00006A01BC0AFEC6FBF505A1CD61CC2BF3A36F
-:103B1000A40CF89E1FAFED1226DD903B6F8FBB2DDE
-:103B20001000D05260F190F480A500E51D097A12D2
-:103B300028D75743EB463977BF48417BACF38E3BE0
-:103B40005611C2FB3D83272B7C28EF3AF5F3B6C113
-:103B50002D3F810BF5CF5B2D407626B02868B7331B
-:103B6000C2D4384A682B0028C9C50F2A7922FF3DE4
-:103B7000A730A9C2DC3D405CDCDF35C13ACAA332C4
-:103B80009A09BE85F29629B50BB0CE5B5D7625828B
-:103B900058C88A4FE4732B26ADA5FBC83B0C1630E2
-:103BA0003A5F74CEC7F82D6EE8227BE792448A7B99
-:103BB000B1CFC3F98BA97DF8702802E8F4E8873506
-:103BC00092BCB60CDFEF1F621E2BBADC7FF9EA5AFB
-:103BD000D0CF00ECF9FDDCFB6005F81ECB7BEFF0ED
-:103BE00090C587F1DA3FC77A317E7B62E88752F46D
-:103BF000D3796947831E3706B014F3A09F18A773C3
-:103C000058EF4BC7F084656720E76787BFE0681906
-:103C100062BB29D1B8A50FF576106ECB910F752F29
-:103C20006C3D6C22E911FD0153A622E40438EEBF7D
-:103C30006ED1C8CFFB863FFFF5A3D5A2DE0D85F080
-:103C4000181F9A15B3B0CBDA633F845DAAC3710C19
-:103C5000EA01D44ED94432DA21BB489EE9E27E1310
-:103C6000F655650E45C27EF7D85C75E00698B1EB57
-:103C700032E9D065370F0DEDC61467F8981D90F73F
-:103C8000DD528C915C15E862D869307BB57D341FBC
-:103C9000C59060201A916294F7D4B7B71B28FECA6A
-:103CA000CAF41F802999D9CB5B57233FDE568CFA83
-:103CB00002E906E2F99C2BD04AFC3A6B8663F6C512
-:103CC00054770836D69217FC4DB8CFF2F805CC2FB2
-:103CD000C9529F92FF6CBD9F115FD14FC82A1F63CD
-:103CE00098E79F95DA41CAE30D66AE0D72C2405A5D
-:103CF00040FEA7CCFA7B889D546DC88B269D16503C
-:103D0000CE210248594B69B14CBC66AA0A3D18FF46
-:103D100048E0CA4EE2C7898C0DAC18376AF4A32973
-:103D2000E39860A8575EBA8E431DEAFBBCB00DED68
-:103D3000AF0478C48A799E005B9CF4C1B6464DFB03
-:103D4000F5188FAAD13FB7AB423F796D96A12C935E
-:103D50007E1F71A37E593753A2A8D3323D79F6173F
-:103D600094DB201EA4BEAEF66A7DB40FC6A7D74D65
-:103D70006888EF094FC2467346CFE3F9270FCCBAE4
-:103D80000A782EAFA9CCE4175F2F21695318DA35D2
-:103D900025A594B5EEE97CA68A7D268A837A294EEC
-:103DA000FA328F3346FA233729BF269B9C925C64F4
-:103DB00067FE356DCBD9C15879FEE44B20207E5487
-:103DC000065014D5715B69CC611697CB0A17B85CA5
-:103DD00036F0C9F64F248FF3B1DFA6CFC777F2E0F4
-:103DE00076E24F765EDF34EEA71F54BB69BF4C27E7
-:103DF0006BDC1078FE7CDEC0FD0A8B005EAB52BF30
-:103E0000A77EE1A3DAD07FB3D11FC41BC8AF64F88B
-:103E10006D36FAD42C73BD2F9B9EE88BC1932C0F6B
-:103E2000B2796771CEE207EF8E5D755709DC6A3FA4
-:103E30000281D7CFC4BBF1D9D10F70ACA0545227A7
-:103E4000B4AAFF235E29FB22E475A68F2B03C47F4F
-:103E50006AFC6221558EF5811FC43E68911CCAF12F
-:103E600067EC038DF6413DED839898F3199EB9CA2E
-:103E700019ED832E712E86CC61139EC779DA49F92C
-:103E8000A6EDC87A94EE60B5D8E36534D1353A4EE4
-:103E900034D7670F38078EA37E94A9FD36B48F9A66
-:103EA0008D79DF23C72FE0FD549C47CC18AF373FF7
-:103EB000DEBF1BEF7B9BE72911ECD314187A6D0E44
-:103EC000B11756702ECE9970517CA08AF471AEB1A4
-:103ED000CEDEF08BE23BFED543744E752F00FD7DA8
-:103EE00010169EA2F71BFCC2DF37D93DF3A153F891
-:103EF000EBDDA09638C4FB224EF6870B357BB091E4
-:103F000070D5F5F08F80D03B7D5A2D213C4E6FB49B
-:103F100008BD8F5928BC8BFCD4CACA05F49B0E3B44
-:103F2000BE1CD4E14831BC1FEFD1EBCDF2F7D585F3
-:103F3000FA1EAC8C4CF403B628D204FE2EE4FD38F5
-:103F4000F1B03E870F53118B821C4E593E46CC88F0
-:103F50009757C7EB087B1A2FAF8117EB41DEBA08E2
-:103F6000B784E8FF0CD771E896209D8735495C2916
-:103F7000B6A21CF36AF3F53AC74AE87D8B35DD1823
-:103F80000B109ED09678C61CD6D3929D23EA63343C
-:103F900067AD06CF5BB37C3CF8041FD3F3F227F385
-:103FA0000C3EA2FD4D472848F1EEB31B4BE972F4DD
-:103FB0001F69EBB3E22C0FEA7BE437ABB68CF4E17C
-:103FC000FC5C2EF688479FEBD1E0ED72FACEC0DFA5
-:103FD00023F3E8BBD35F187A85F4ECF333168DFA3C
-:103FE000599231533DE3E17BE5F47FA6B5E79A981A
-:103FF0009BFF9AE7BF3AB4AF4B200A0000000000D5
-:104000000000000000000000000000180000000098
-:104010000000000000000040000000000000000060
-:104020000000002800000000000000000000001058
-:104030000000000000000000000000200000000060
-:104040000000000000000010000000000000000060
-:104050000000000800000000000000000000000058
-:104060000000000000000000000000000000000050
-:104070000000000000000000000000000000000040
-:104080000000000000000000000000000000000030
-:104090000000000000000000000000000000000020
-:1040A0000000000000000000000000000000000010
-:1040B0000000000000000000000000000000000000
-:1040C00000000000000000000000000000000000F0
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000000000000000000000000000C0
-:1041000000000000000000000000000000000000AF
-:10411000000000000000000000000000000000009F
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000000000000000000006F
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:104170000000332800100000000000080000333069
-:1041800000100000000000020000332800100000B2
-:104190000000001000003A78000000000000000855
-:1041A000000000000000000000000000000000000F
-:1041B00000000000000000000000000000000000FF
-:1041C0000000000000003120000000000000000896
-:1041D00000003360000100040000000100003368AB
-:1041E000000000000000000200003370000000002A
-:1041F000000000080000337400000000000000020E
-:1042000000003A70000000000000000800003A4082
-:10421000000800000000000800003D880040000089
-:104220000000004000003A500008000000000008B4
-:1042300000003A60000800000000000800003A8812
-:1042400000C800000000009800003C180098000022
-:104250000000002800003C580098000000000028E2
-:1042600000003378036000300000036000003EB0BF
-:10427000000800000000000100003EB1000800003E
-:1042800000000001000020080010000000000010E5
-:1042900000002000000000000000000800000000F6
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000000000000000000000000000000000CE
-:1042F00000000000000000000000000000000000BE
-:1043000000000000000000000000000000000000AD
-:10431000000000000000000000000000000000009D
-:10432000000000000000000000000000000000008D
-:10433000000000000000000000000000000000007D
-:10434000000000000000000000000000000000006D
-:10435000000000000000000000000000000000005D
-:10436000000000000000000000000000000000004D
-:10437000000000000000000000000000000000003D
-:10438000000000000000000000000000000000002D
-:10439000000000000000000000000000000000001D
-:1043A000000000000000000000000000000000000D
-:1043B00000000000000000000000000000000000FD
-:1043C00000000000000000000000000000000000ED
-:1043D00000000000000000000000000000000000DD
-:1043E00000000000000000000000000000000000CD
-:1043F00000000000000000000000000000000000BD
-:1044000000000000000000000000000000000000AC
-:10441000000000000000000000000000000000009C
-:10442000000000000000000000000000000000008C
-:10443000000000000000000000000000000000007C
-:10444000000000000000000000000000000012C892
-:10445000008000000000008000000001000000005B
-:1044600000000000000040000490000000000490E4
-:10447000000019C8000000000000000800004948C2
-:1044800000080000000000080000492800080000A3
-:104490000000000800004938000800000000000883
-:1044A00000002008001000000000001000002000A4
-:1044B00000000000000000080000401004900040D0
-:1044C00000000040000049980008000000000001C2
-:1044D00000004999000800000000000100000000F1
-:1044E00000000000000000000000000000000000CC
-:1044F00000000000000000000000000000000000BC
-:1045000000000000000000000000000000000000AB
-:10451000000000000000000000000000000000009B
-:10452000000000000000000000000000000000008B
-:10453000000000000000000000000000000000007B
-:10454000000000000000000000000000000000006B
-:10455000000000000000000000000000000000005B
-:10456000000000000000000000000000000000004B
-:10457000000000000000000000000000000000003B
-:10458000000000000000000000000000000000002B
-:10459000000000000000000000000000000000001B
-:1045A000000000000000000000000000000000000B
-:1045B00000000000000000000000000000000000FB
-:1045C00000000000000000000000000000000000EB
-:1045D00000000000000000000000000000000000DB
-:1045E00000000000000000000000000000000000CB
-:1045F00000000000000000000000000000000000BB
-:104600000000000000000000000040000018000052
-:1046100000000018000043000040000000000040BF
-:1046200000004300004000020000000100004301C0
-:1046300000400002000000000000300000400000C8
-:10464000000000400000000000000000000000002A
-:1046500000003000000800400000000400003004AA
-:10466000000800400000000400004B00002800008B
-:104670000000002800004B50001000000000001057
-:1046800000003800008000000000008000003800BA
-:104690000008008000000002000039000020000037
-:1046A00000000020000020080010000000000010A2
-:1046B0000000200000000000000000080000510879
-:1046C0000008000000000008000051200008000061
-:1046D0000000000800005130000800000000000841
-:1046E000000051C00008000000000001000051C19E
-:1046F0000008000000000001000039400010000424
-:1047000000000004000051D000300018000000102C
-:10471000000051D800300018000000020000000026
-:104720000000000000000000000000000000000089
-:104730000000000000000000000000000000000079
-:104740000000000000000000000000000000000069
-:104750000000000000000000000000000000000059
-:104760000000000000000000000000000000000049
-:104770000000000000000000000000000000000039
-:104780000000000000000000000000000000000029
-:104790000000000000000000000000000000000019
-:1047A0000000000000000000000000000000000009
-:1047B00000000000000000000000000000000000F9
-:1047C00000000000000000000000000000000000E9
-:1047D000000000000000000000000000000023E8CE
-:1047E00000800000000000800000000100000000C8
-:1047F0000000000000002008001000000000001071
-:1048000000002000000000000000000800002DA0B3
-:10481000000800000000000800002DB8000800009B
-:1048200000000008000024E802D00028000002D0A8
-:1048300000002E58000800000000000100002E5962
-:10484000000800000000000100002D90000800009A
-:104850000000000800000000000000000000000050
-:104860000000000000000000000000000000000048
-:104870000000000000000000000000000000000038
-:104880000000000000000000000000000000000028
-:104890000000000000000000000000000000000018
-:1048A0000000000000000000000000000000000008
-:1048B00000000000000000000000000000000000F8
-:1048C00000000000000000000000000000000000E8
-:1048D00000000000000000000000000000000000D8
-:1048E00000000000000000000000000000000000C8
-:1048F00000000000000000000000000000000000B8
-:1049000000000000000000000000000000000000A7
-:104910000000000000000000000000000000000097
-:104920000000000000000000000000000000250062
-:1049300000400000000000080000250800400000C2
-:1049400000000028000009C001200010000000083D
-:104950000000000000000000000000000000000057
-:1049600000000000000000000000402002D00028ED
-:1049700000000008000030000000000000001000EF
-:10498000000050990000000000000001000050B03D
-:104990000000000000000002000045A00090000898
-:1049A00000000008000000000000000000000000FF
-:1049B00000002960000800000000000100002961DB
-:1049C0000008000000000001000029700008000439
-:1049D0000000000200002978000800040000000424
-:1049E00000002FB0000800000000000400002FB4F9
-:1049F000000800000000000400002FC000000000BC
-:104A00000000000800002FC800000000000000089F
-:104A100000003000000000000000001000005040C6
-:104A20000001000100000001000050000000000033
-:104A30000000002000000808001000000000000432
-:104A40000000080C0010000000000001000008B782
-:104A50000000000000000001000008B60000000097
-:104A600000000001000010000030001800000004E9
-:104A700000001004003000180000000400001008BE
-:104A800000300018000000020000100A003000187A
-:104A9000000000020000100C0030001800000001AF
-:104AA0000000100D00300018000000010000100E82
-:104AB0000030001800000001000010100030001845
-:104AC0000000000400001014003000180000000472
-:104AD00000003000010000800008000400003004E5
-:104AE00001000080000800040000000A000000002F
-:104AF000000000000000306801000080000000019C
-:104B00000000306901000080000000010000306CEE
-:104B100001000080000000020000306E01000080F3
-:104B2000000000020000307001000080000000045E
-:104B300000003074010000800000000400003066B6
-:104B400001000080000000020000306401000080CD
-:104B50000000000100003060010000800000000241
-:104B600000003062010000800000000200003050B0
-:104B700001000080000000040000305401000080AB
-:104B80000000000400003058010000800000000414
-:104B90000000305C01000080000000040000307C58
-:104BA00001000080000000010000307D0100008055
-:104BB0000000000100001C180010000000000004AC
-:104BC00000001C30001000000000000400001C3831
-:104BD00000100000000000040000000000000000C1
-:104BE00000000000000000000000000000000000C5
-:104BF00000000000000000000000000000000000B5
-:104C0000000000000000000000004C100008000040
-:104C10000000000200004C1200080000000000022A
-:104C200000004C14000800000000000400004C20AC
-:104C3000000800000000000800004C3000400008A0
-:104C40000000000800004C00000800000000000206
-:104C500000004C02000800000000000100004C04AD
-:104C6000000800000000000200004CD00008000016
-:104C70000000000800004CE00008000000000004F4
-:104C800000004CE4000800000000000100004CF0AF
-:104C9000000800000000000200004CF400080000C2
-:104CA0000000000200004D000008000000000004A9
-:104CB000000050000010000000000004000050043C
-:104CC0000010000000000004000050080010000068
-:104CD00000000004000014000008000000000002B2
-:104CE000000014020008000000000001000014048D
-:104CF000000800000000000200001410000800007E
-:104D0000000000020000141400080000000000026F
-:104D1000000014160008000000000002000019B88E
-:104D20000008000000000008000014200008000037
-:104D3000000000020000142400080000000000022F
-:104D4000000019C8000800000000000800002C1036
-:104D5000000800000000000100002C110008000005
-:104D60000000000100002C120008000000000001FB
-:104D700000002C13000800000000000100002C00BF
-:104D8000000800000000000200002C0200080000E3
-:104D90000000000100002C040008000000000002D8
-:104DA00000002C30000800000000000200002C323F
-:104DB000000800000000000200002C340008000081
-:104DC0000000000200002C2000080000000000018C
-:104DD00000002C21000800000000000100002C222F
-:104DE000000800000000000100002C230008000063
-:104DF0000000000100002C24000800000000000159
-:104E000000002C25000800000000000100002C26F6
-:104E1000000800000000000100001400000800006D
-:104E20000000000200001402000800000000000161
-:104E3000000014040008000000000002000014122A
-:104E400000C00018000000020000141000C000188C
-:104E5000000000020000141C00C000180000000840
-:104E60000000141400C000180000000800001427FF
-:104E700000C00018000000010000142400C0001849
-:104E8000000000020000142600C00018000000010D
-:104E9000000015900008000000000008000015A0A8
-:104EA0000008000000000008000015B00008000025
-:104EB00000000008000000000000000000000000EA
-:104EC00000000000000000000000000000000000E2
-:104ED00000000000000000000000000000000000D2
-:104EE00000000000000000000000000000000000C2
-:104EF00000000000000000000000000000000000B2
-:104F000000000000000000000000000000000000A1
-:104F10000000000000000000000000000000000091
-:104F20000000000000000000000000000000000081
-:104F30000000000000000000000000000000000071
-:104F40000000000000000000000000000000000061
-:104F50000000000000000000000000000000000051
-:104F60000000000000000000000000000000000041
-:104F70000000000000000000000000000000000031
-:104F80000000000000000000000000000000000021
-:104F90000000000000000000000000000000000011
-:104FA0000000000000000000000000000000000001
-:104FB00000000000000000000000000000000000F1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE00000000000000000000000000000000000C1
-:104FF00000000000000000000000000000000000B1
-:105000000000000000000000060022000000000078
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex
new file mode 100644
index 000000000000..1b535827a742
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex
@@ -0,0 +1,9483 @@
+:1000000000003BB0000000680000070C00003C202E
+:1000100000001AF8000043300000007C00005E3051
+:1000200000007A2C00005EB0000000B00000D8E0B4
+:10003000000080200000D99800000088000159C00D
+:100040000000398800015A5000000090000193E040
+:100050000000ABFC0001947800000FFC0002407827
+:100060000000000400025078020400480000000F65
+:100070000204005400000045020400580000000083
+:100080000204005C0000000602040070000000048E
+:1000900002040078000000000204007C1217000037
+:1000A00002040080221700000204008432170000BE
+:1000B00006040088000000050204009C12150000E0
+:1000C000020400A022150000020400A43215000062
+:1000D000060400A800000004020400B8021000009A
+:1000E000020400BC00100000020400C01010000058
+:1000F000020400C420100000020400C830100000F8
+:10010000060400CC00000004020400DC0010000023
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000060400EC00000004A1
+:100130000104012400000000010401280000000067
+:100140000104012C00000000010401300000000047
+:1001500002040004000000FF02040008000000FF89
+:100160000204000C000000FF02040010000000FF69
+:1001700002040014000000FF02040018000000FF49
+:100180000204001C000000FF02040020000000FF29
+:10019000020400240000003E0204002800000000C9
+:1001A0000204002C0000003F020400300000003F69
+:1001B000020400340000003F020400380000000088
+:1001C0000204003C0000003F020400400000003F29
+:1001D000020400440000003F020420080000021155
+:1001E0000204200C0000020002042010000002049F
+:1001F00002042014000002190204201C0000FFFF6A
+:10020000020420200000FFFF020420240000FFFF62
+:10021000020420280000FFFF0604203800000080B0
+:100220000204223807FFFFFF0204223C0000003FC7
+:100230000204224007FFFFFF020422440000000FD7
+:1002400001042248000000000104224C00000000CC
+:1002500001042250000000000104225400000000AC
+:1002600001042258000000000104225C000000008C
+:10027000010422600000000001042264000000006C
+:1002800001042268000000000104226C000000004C
+:10029000010422700000000001042274000000002C
+:1002A00001042278000000000104227C000000000C
+:1002B000020424BC000000010C042000000003E83C
+:1002C0000A042000000000010B0420000000000AC6
+:1002D0000605400000000D0002050044000000205B
+:1002E00002050048000000320205009002150020BF
+:1002F000020500940215002002050098000000305D
+:100300000205009C08100000020500A00000003358
+:10031000020500A400000030020500A80000003122
+:10032000020500AC00000002020500B0000000055C
+:10033000020500B400000006020500B8000000023B
+:10034000020500BC00000002020500C00000000021
+:10035000020500C400000005020500C800000002FC
+:10036000020500CC00000002020500D000000002DF
+:10037000020500D400000001020501140000000184
+:100380000205011C0000000102050120000000021E
+:1003900002050204000000010205020C00000040FA
+:1003A00002050210000000400205021C00000020AF
+:1003B00002050220000000130205022400000020B4
+:1003C000060502400000000A04050280002000002B
+:1003D000020500500000000702050054000000075D
+:1003E00002050058000000000205005C0000000843
+:1003F0000605006000000004020500D800000006A9
+:10040000020500E00000000D020500E40000002DE0
+:10041000020500E800000000020500EC00000020DA
+:10042000020500F000000000020500F400000020BA
+:10043000020500F800000000020500FC000000209A
+:100440000205000400000001020500080000000190
+:100450000205000C00000001020500100000000170
+:100460000205001400000001020500180000000150
+:100470000205001C00000001020500200000000130
+:100480000205002400000001020500280000000110
+:100490000205002C000000010205003000000001F0
+:1004A00002050034000000010205003800000001D0
+:1004B0000205003C000000010205004000000001B0
+:1004C0000406100002000020020600DC000000010B
+:1004D000010600D80000000004060200000302200C
+:1004E000020600DC0000000002060068000000B800
+:1004F0000206007800000114010600B800000000A8
+:10050000010600C8000000000206006C000000B8F0
+:100510000206007C00000114010600BC000000007F
+:10052000010600CC0000000007180400007B00005A
+:100530000818076000140223071C00002A040000AA
+:10054000071C800032110A82071D00001E0C1707CD
+:10055000081D4550575602250118000000000000F4
+:10056000011800040000000001180008000000004D
+:100570000118000C0000000001180010000000002D
+:100580000118001400000000021800200000000103
+:1005900002180024000000020218002800000003D6
+:1005A0000218002C000000000218003000000004B7
+:1005B000021800340000000102180038000000009A
+:1005C0000218003C00000001021800400000000476
+:1005D000021800440000000002180048000000015A
+:1005E0000218004C00000003021800500000000038
+:1005F0000218005400000001021800580000000416
+:100600000218005C000000000218006000000001F9
+:1006100002180064000000030218006800000000D7
+:100620000218006C000000010218007000000004B5
+:100630000218007400000000021800780000000496
+:100640000218007C00000003061800800000000271
+:10065000021800A400003FFF021800A8000003FFDA
+:1006600002180224000000000218023400000000FA
+:100670000218024C00000000021802E4000000FF13
+:100680000618100000000400021B8BC000000001CF
+:10069000021B800000000034021B80400000001894
+:1006A000021B80800000000C021B80C000000020A4
+:1006B0000C1B83000007A1200A1B830000000138E7
+:1006C0000B1B8300000013880A1B834000000000FE
+:1006D0000C1B8340000001F40B1B8340000000054D
+:1006E000021B83800007A120021B83C0000001F4CD
+:1006F000061A100000000273041A19CC0001022728
+:10070000061A2008000000C8061A20000000000297
+:10071000041A499800040228061A2E280000000234
+:10072000061A2E2000000002061A0800000000022F
+:10073000061A080800000004061A08180000000243
+:10074000041A08B00002022C061A2FD0000000067E
+:10075000041A2FE80002022E041A2FC000040230EF
+:10076000041A300000010234061A300400000003AD
+:10077000041A301000010235061A3014000000037C
+:10078000041A302000010236061A3024000000034B
+:10079000041A303000010237061A3034000000031A
+:1007A000041A304000010238061A304400000003E9
+:1007B000041A305000010239061A305400000003B8
+:1007C000041A30600001023A061A30640000000387
+:1007D000041A30700001023B061A30740000000356
+:1007E000041A30800001023C061A30840000000325
+:1007F000041A30900001023D061A309400000003F4
+:10080000041A30A00001023E061A30A400000003C2
+:10081000041A30B00001023F061A30B40000000391
+:10082000041A30C000010240061A30C40000000360
+:10083000041A30D000010241061A30D4000000032F
+:10084000041A30E000010242061A30E400000003FE
+:10085000041A30F000010243061A30F400000003CD
+:10086000041A310000010244061A3104000000039A
+:10087000041A311000010245061A31140000000369
+:10088000041A312000010246061A31240000000338
+:10089000041A313000010247061A31340000000307
+:1008A000041A314000010248061A314400000003D6
+:1008B000041A315000010249061A315400000003A5
+:1008C000041A31600001024A061A31640000000374
+:1008D000041A31700001024B061A31740000000343
+:1008E000041A31800001024C061A31840000000312
+:1008F000041A31900001024D061A319400000003E1
+:10090000041A31A00001024E061A31A400000003AF
+:10091000041A31B00001024F061A31B4000000037E
+:10092000041A31C000010250061A31C4000000034D
+:10093000041A31D000010251061A31D4000000031C
+:10094000041A31E000010252061A31E400000003EB
+:10095000041A31F000010253061A31F400000003BA
+:10096000041A320000010254061A32040000000387
+:10097000041A321000010255061A32140000000356
+:10098000041A322000010256061A32240000000325
+:10099000041A323000010257061A323400000003F4
+:1009A000041A324000010258061A324400000003C3
+:1009B000041A325000010259061A32540000000392
+:1009C000041A32600001025A061A32640000000361
+:1009D000041A32700001025B061A32740000000330
+:1009E000041A32800001025C061A328400000003FF
+:1009F000041A32900001025D061A329400000003CE
+:100A0000041A32A00001025E061A32A4000000039C
+:100A1000041A32B00001025F061A32B4000000036B
+:100A2000041A32C000010260061A32C4000000033A
+:100A3000041A32D000010261061A32D40000000309
+:100A4000041A32E000010262061A32E400000003D8
+:100A5000041A32F000010263061A32F400000003A7
+:100A6000041A330000010264061A33040000000374
+:100A7000041A331000010265061A33140000000343
+:100A8000041A332000010266061A33240000000312
+:100A9000041A333000010267061A333400000003E1
+:100AA000041A334000010268061A334400000003B0
+:100AB000041A335000010269061A3354000000037F
+:100AC000041A33600001026A061A3364000000034E
+:100AD000041A33700001026B061A3374000000031D
+:100AE000041A33800001026C061A338400000003EC
+:100AF000041A33900001026D061A339400000003BB
+:100B0000041A33A00001026E061A33A40000000389
+:100B1000041A33B00001026F061A33B40000000358
+:100B2000041A33C000010270061A33C40000000327
+:100B3000041A33D000010271061A33D400000003F6
+:100B4000041A33E000010272061A33E400000003C5
+:100B5000041A33F000010273061A33F40000000394
+:100B6000041A340000010274061A34040000000361
+:100B7000041A341000010275061A34140000000330
+:100B8000041A342000010276061A342400000003FF
+:100B9000041A343000010277061A343400000003CE
+:100BA000041A344000010278061A3444000000039D
+:100BB000041A345000010279061A3454000000036C
+:100BC000041A34600001027A061A3464000000033B
+:100BD000041A34700001027B061A3474000000030A
+:100BE000041A34800001027C061A348400000003D9
+:100BF000041A34900001027D061A349400000003A8
+:100C0000041A34A00001027E061A34A40000000376
+:100C1000041A34B00001027F061A34B40000000345
+:100C2000041A34C000010280061A34C40000000314
+:100C3000041A34D000010281061A34D400000003E3
+:100C4000041A34E000010282061A34E400000003B2
+:100C5000041A34F000010283061A34F40000000381
+:100C6000041A350000010284061A3504000000034E
+:100C7000041A351000010285061A3514000000031D
+:100C8000041A352000010286061A352400000003EC
+:100C9000041A353000010287061A353400000003BB
+:100CA000041A354000010288061A3544000000038A
+:100CB000041A355000010289061A35540000000359
+:100CC000041A35600001028A061A35640000000328
+:100CD000041A35700001028B061A357400000003F7
+:100CE000041A35800001028C061A358400000003C6
+:100CF000041A35900001028D061A35940000000395
+:100D0000041A35A00001028E061A35A40000000363
+:100D1000041A35B00001028F061A35B40000000332
+:100D2000041A35C000010290061A35C40000000301
+:100D3000041A35D000010291061A35D400000003D0
+:100D4000041A35E000010292061A35E4000000039F
+:100D5000041A35F000010293061A35F4000000036E
+:100D6000041A360000010294061A3604000000033B
+:100D7000041A361000010295061A3614000000030A
+:100D8000041A362000010296061A362400000003D9
+:100D9000041A363000010297061A363400000003A8
+:100DA000041A364000010298061A36440000000377
+:100DB000041A365000010299061A36540000000346
+:100DC000041A36600001029A061A36640000000315
+:100DD000041A36700001029B061A367400000003E4
+:100DE000041A36800001029C061A368400000003B3
+:100DF000041A36900001029D061A36940000000382
+:100E0000041A36A00001029E061A36A40000000350
+:100E1000041A36B00001029F061A36B4000000031F
+:100E2000041A36C0000102A0061A36C400000003EE
+:100E3000041A36D0000102A1061A36D400000003BD
+:100E4000041A36E0000102A2061A36E4000000038C
+:100E5000041A36F0000102A3061A36F4000000035B
+:100E6000041A3700000102A4061A37040000000328
+:100E7000041A3710000102A5061A371400000003F7
+:100E8000041A3720000102A6061A372400000003C6
+:100E9000041A3730000102A7061A37340000000395
+:100EA000041A3740000102A8061A37440000000364
+:100EB000041A3750000102A9061A37540000000333
+:100EC000041A3760000102AA061A37640000000302
+:100ED000041A3770000102AB061A377400000003D1
+:100EE000041A3780000102AC061A378400000003A0
+:100EF000041A3790000102AD061A3794000000036F
+:100F0000041A37A0000102AE061A37A4000000033D
+:100F1000041A37B0000102AF061A37B4000000030C
+:100F2000041A37C0000102B0061A37C400000003DB
+:100F3000041A37D0000102B1061A37D400000003AA
+:100F4000041A37E0000102B2061A37E40000000379
+:100F5000041A37F0000102B3061A37F40000000348
+:100F6000041A3800000102B4061A38040000000315
+:100F7000041A3810000102B5061A381400000003E4
+:100F8000041A3820000102B6061A382400000003B3
+:100F9000041A3830000102B7061A38340000000382
+:100FA000041A3840000102B8061A38440000000351
+:100FB000041A3850000102B9061A38540000000320
+:100FC000041A3860000102BA061A386400000003EF
+:100FD000041A3870000102BB061A387400000003BE
+:100FE000041A3880000102BC061A3884000000038D
+:100FF000041A3890000102BD061A3894000000035C
+:10100000041A38A0000102BE061A38A4000000032A
+:10101000041A38B0000102BF061A38B400000003F9
+:10102000041A38C0000102C0061A38C400000003C8
+:10103000041A38D0000102C1061A38D40000000397
+:10104000041A38E0000102C2061A38E40000000366
+:10105000041A38F0000102C3061A38F40000000335
+:10106000041A3900000102C4061A39040000000302
+:10107000041A3910000102C5061A391400000003D1
+:10108000041A3920000102C6061A392400000003A0
+:10109000041A3930000102C7061A3934000000036F
+:1010A000041A3940000102C8061A3944000000033E
+:1010B000041A3950000102C9061A3954000000030D
+:1010C000041A3960000102CA061A396400000003DC
+:1010D000041A3970000102CB061A397400000003AB
+:1010E000041A3980000102CC061A3984000000037A
+:1010F000041A3990000102CD061A39940000000349
+:10110000041A39A0000102CE061A39A40000000317
+:10111000041A39B0000102CF061A39B400000003E6
+:10112000041A39C0000102D0061A39C400000003B5
+:10113000041A39D0000102D1061A39D40000000384
+:10114000041A39E0000102D2061A39E40000000353
+:10115000041A39F0000102D3061A39F40000000322
+:10116000041A3A00000102D4061A3A0400000003EF
+:10117000041A3A10000102D5061A3A1400000003BE
+:10118000041A3A20000102D6061A3A24000000038D
+:10119000041A3A30000102D7061A3A34000000035C
+:1011A000041A3A40000102D8061A3A44000000032B
+:1011B000041A3A50000102D9061A3A5400000003FA
+:1011C000041A3A60000102DA061A3A6400000003C9
+:1011D000041A3A70000102DB061A3A740000000398
+:1011E000041A3A80000102DC061A3A840000000367
+:1011F000041A3A90000102DD061A3A940000000336
+:10120000041A3AA0000102DE061A3AA40000000304
+:10121000041A3AB0000102DF061A3AB400000003D3
+:10122000041A3AC0000102E0061A3AC400000003A2
+:10123000041A3AD0000102E1061A3AD40000000371
+:10124000041A3AE0000102E2061A3AE40000000340
+:10125000041A3AF0000102E3061A3AF4000000030F
+:10126000041A3B00000102E4061A3B0400000003DC
+:10127000041A3B10000102E5061A3B1400000003AB
+:10128000041A3B20000102E6061A3B24000000037A
+:10129000041A3B30000102E7061A3B340000000349
+:1012A000041A3B40000102E8061A3B440000000318
+:1012B000041A3B50000102E9061A3B5400000003E7
+:1012C000041A3B60000102EA061A3B6400000003B6
+:1012D000041A3B70000102EB061A3B740000000385
+:1012E000041A3B80000102EC061A3B840000000354
+:1012F000041A3B90000102ED061A3B940000000323
+:10130000041A3BA0000102EE061A3BA400000003F1
+:10131000041A3BB0000102EF061A3BB400000003C0
+:10132000041A3BC0000102F0061A3BC4000000038F
+:10133000041A3BD0000102F1061A3BD4000000035E
+:10134000041A3BE0000102F2061A3BE4000000032D
+:10135000041A3BF0000102F3061A3BF400000003FC
+:10136000041A3C00000102F4061A3C0400000003C9
+:10137000041A3C10000102F5061A3C140000000398
+:10138000041A3C20000102F6061A3C240000000367
+:10139000041A3C30000102F7061A3C340000000336
+:1013A000041A3C40000102F8061A3C440000000305
+:1013B000041A3C50000102F9061A3C5400000003D4
+:1013C000041A3C60000102FA061A3C6400000003A3
+:1013D000041A3C70000102FB061A3C740000000372
+:1013E000041A3C80000102FC061A3C840000000341
+:1013F000041A3C90000102FD061A3C940000000310
+:10140000041A3CA0000102FE061A3CA400000003DE
+:10141000041A3CB0000102FF061A3CB400000003AD
+:10142000041A3CC000010300061A3CC4000000037B
+:10143000041A3CD000010301061A3CD4000000034A
+:10144000041A3CE000010302061A3CE40000000319
+:10145000041A3CF000010303061A3CF400000003E8
+:10146000041A3D0000010304061A3D0400000003B5
+:10147000041A3D1000010305061A3D140000000384
+:10148000041A3D2000010306061A3D240000000353
+:10149000041A3D3000010307061A3D340000000322
+:1014A000041A3D4000010308061A3D4400000003F1
+:1014B000041A3D5000010309061A3D5400000003C0
+:1014C000041A3D600001030A061A3D64000000038F
+:1014D000041A3D700001030B061A3D74000000035E
+:1014E000041A3D800001030C061A3D84000000032D
+:1014F000041A3D900001030D061A3D9400000003FC
+:10150000041A3DA00001030E061A3DA400000003CA
+:10151000041A3DB00001030F061A3DB40000000399
+:10152000041A3DC000010310061A3DC40000000368
+:10153000041A3DD000010311061A3DD40000000337
+:10154000041A3DE000010312061A3DE40000000306
+:10155000041A3DF000010313061A3DF400000003D5
+:10156000041A3E0000010314061A3E0400000003A2
+:10157000041A3E1000010315061A3E140000000371
+:10158000041A3E2000010316061A3E240000000340
+:10159000041A3E3000010317061A3E34000000030F
+:1015A000041A3E4000010318061A3E4400000003DE
+:1015B000041A3E5000010319061A3E5400000003AD
+:1015C000041A3E600001031A061A3E64000000037C
+:1015D000041A3E700001031B061A3E74000000034B
+:1015E000041A3E800001031C061A3E84000000031A
+:1015F000041A3E900001031D061A3E9400000003E9
+:10160000041A3EA00001031E061A3EA400000003B7
+:10161000041A3EB00001031F061A3EB40000000386
+:10162000041A3EC000010320061A3EC40000000355
+:10163000041A3ED000010321061A3ED40000000324
+:10164000041A3EE000010322061A3EE400000003F3
+:10165000041A3EF000010323061A3EF400000003C2
+:10166000041A3F0000010324061A3F04000000038F
+:10167000041A3F1000010325061A3F14000000035E
+:10168000041A3F2000010326061A3F24000000032D
+:10169000041A3F3000010327061A3F3400000003FC
+:1016A000041A3F4000010328061A3F4400000003CB
+:1016B000041A3F5000010329061A3F54000000039A
+:1016C000041A3F600001032A061A3F640000000369
+:1016D000041A3F700001032B061A3F740000000338
+:1016E000041A3F800001032C061A3F840000000307
+:1016F000041A3F900001032D061A3F9400000003D6
+:10170000041A3FA00001032E061A3FA400000003A4
+:10171000041A3FB00001032F061A3FB40000000373
+:10172000041A3FC000010330061A3FC40000000342
+:10173000041A3FD000010331061A3FD40000000311
+:10174000041A3FE000010332061A3FE400000007DC
+:10175000041A4CB000080333061A400000000124AC
+:10176000021A492000000000061A2500000000109F
+:10177000061A258000000012061A09C00000004861
+:10178000061A080000000002061A082000000012D5
+:10179000041A2FB00002033B041A4CF00002033D70
+:1017A000061A500000000004061A449000000124AC
+:1017B000021A492400000000061A2540000000100B
+:1017C000061A25C800000012061A0AE000000048A8
+:1017D000061A081000000002061A0868000000122D
+:1017E000041A2FB80002033F041A4CF80002034108
+:1017F000061A5010000000040200A468000AFFDC72
+:101800000200A280000000010200A294071D29111D
+:101810000200A298000000000200A29C009C042488
+:101820000200A2A0000000000200A2A40000020921
+:101830000200A4FCFF000000020100B4000000014F
+:10184000020100B800000001020100DC00000001FC
+:10185000020101000000000102010104000000017A
+:101860000201007C0030000002010084000000281A
+:101870000201008C000000000201013000000004A1
+:101880000201025C000000010201032800000000C8
+:101890000201055400000030020100C400000001F4
+:1018A000020100CC00000001020100F8000000016C
+:1018B000020100F000000001020100800030000081
+:1018C00002010088000000280201009000000000D2
+:1018D0000201013400000004020102DC00000001EA
+:1018E0000201032C0000000002010564000000302A
+:1018F000020100C800000001020100D00000000148
+:10190000020100FC00000001020100F400000001DF
+:10191000020C100000000028020C200800000A1130
+:10192000020C200C00000A00020C201000000A0427
+:10193000020C201C0000FFFF020C20200000FFFF13
+:10194000020C20240000FFFF020C20280000FFFFF3
+:10195000020C203800000020020C203C0000002176
+:10196000020C204000000022020C20440000002352
+:10197000020C204800000024020C204C000000252E
+:10198000020C205000000026020C2054000000270A
+:10199000020C205800000028020C205C00000029E6
+:1019A000020C20600000002A020C20640000002BC2
+:1019B000020C20680000002C020C206C0000002D9E
+:1019C000020C20700000002E020C20740000002F7A
+:1019D000020C207800000010060C207C0000004F54
+:1019E000020C21B800000001020C21BC0000000123
+:1019F000020C21C000000001020C21C40000000103
+:101A0000020C21C800000001020C21CC00000001E2
+:101A1000020C21D000000001020C21D400000001C2
+:101A2000020C21D800000001020C21DC00000001A2
+:101A3000020C21E000000001020C21E40000000182
+:101A4000020C21E800000001020C21EC0000000162
+:101A5000020C21F000000001020C21F40000000142
+:101A6000020C21F800000001060C21FC0000000F10
+:101A7000020C223807FFFFFF020C223C0000003F4F
+:101A8000020C224007FFFFFF020C22440000000F5F
+:101A9000010C224800000000010C224C0000000054
+:101AA000010C225000000000010C22540000000034
+:101AB000010C225800000000010C225C0000000014
+:101AC000010C226000000000010C226400000000F4
+:101AD000010C226800000000010C226C00000000D4
+:101AE000010C227000000000010C227400000000B4
+:101AF000010C227800000000010C227C0000000094
+:101B0000020C24BC000000010C0C2000000003E8C3
+:101B10000A0C2000000000010B0C20000000000A4D
+:101B2000020C400800000562020C400C0000055148
+:101B3000020C401000000555020C40140000057214
+:101B4000020C401C0000FFFF020C40200000FFFFC1
+:101B5000020C40240000FFFF020C40280000FFFFA1
+:101B6000020C403800000046020C403C0000000C13
+:101B7000060C40400000005E020C41B8000000016D
+:101B8000060C41BC0000001F020C423807FFFFFF9B
+:101B9000020C423C0000003F020C424007FFFFFFE6
+:101BA000020C42440000000F010C424800000000FB
+:101BB000010C424C00000000010C425000000000EB
+:101BC000010C425400000000010C425800000000CB
+:101BD000010C425C00000000010C426000000000AB
+:101BE000010C426400000000010C4268000000008B
+:101BF000010C426C00000000010C4270000000006B
+:101C0000010C427400000000010C4278000000004A
+:101C1000010C427C00000000010C4280000000002A
+:101C2000020C44C0000000010C0C4000000003E85E
+:101C30000A0C4000000000010B0C40000000000AEC
+:101C4000060D400000000A00020D004400000032B2
+:101C5000020D008C02150020020D009002150020DC
+:101C6000020D009408100000020D009800000033DF
+:101C7000020D009C00000002020D00A00000000008
+:101C8000020D00A400000005020D00A800000005E0
+:101C9000060D00AC00000002020D00B400000002BE
+:101CA000020D00B800000003020D00BC000000029D
+:101CB000020D00C000000001020D00C8000000027B
+:101CC000020D00CC00000002020D015C00000001CA
+:101CD000020D016400000001020D01680000000215
+:101CE000020D020400000001020D020C00000020A1
+:101CF000020D021000000040020D0214000000401E
+:101D0000020D022000000003020D02240000001852
+:101D1000060D028000000012040D030000180343AA
+:101D2000060D03600000000C020D004C00000001D5
+:101D3000020D005000000002020D005400000000DF
+:101D4000020D005800000008060D005C00000004B1
+:101D5000020D00C400000004020D0114000000097F
+:101D6000020D011800000029020D011C0000000AEC
+:101D7000020D01200000002A020D012400000000D5
+:101D8000020D012800000020020D012C00000000BF
+:101D9000020D013000000020020D0134000000009F
+:101DA000020D013800000020020D013C000000007F
+:101DB000020D014000000020020D0144000000005F
+:101DC000020D014800000020020D00040000000187
+:101DD000020D000800000001020D000C00000001CF
+:101DE000020D001000000001020D001400000001AF
+:101DF000020D001800000001020D001C000000018F
+:101E0000020D002000000001020D0024000000016E
+:101E1000020D002800000001020D002C000000014E
+:101E2000020D003000000001020D0034000000012E
+:101E3000020D003800000001020D003C000000010E
+:101E4000060E200000000800020E004C00000032C8
+:101E5000020E009402150020020E009802150020C8
+:101E6000020E009C00000030020E00A008100000CE
+:101E7000020E00A400000033020E00A80000003093
+:101E8000020E00AC00000031020E00B000000002A3
+:101E9000020E00B400000004020E00B800000000B2
+:101EA000020E00BC00000002020E00C00000000292
+:101EB000020E00C400000000020E00C80000000274
+:101EC000020E00CC00000007020E00D0000000024D
+:101ED000020E00D400000002020E00D80000000133
+:101EE000020E014400000001020E014C000000013E
+:101EF000020E015000000002020E02040000000168
+:101F0000020E020C00000040020E02100000004011
+:101F1000020E021C00000004020E0220000000203D
+:101F2000020E02240000000E020E02280000001B18
+:101F3000060E030000000012040E0280001B035B6B
+:101F4000060E02EC00000005020E00540000000C1A
+:101F5000020E00580000000C020E005C00000000A1
+:101F6000020E006000000010060E00640000000475
+:101F7000020E00DC00000003020E01100000000F42
+:101F8000020E01140000002F020E011800000000D4
+:101F9000020E011C00000020020E000400000001DF
+:101FA000020E000800000001020E000C00000001FB
+:101FB000020E001000000001020E001400000001DB
+:101FC000020E001800000001020E001C00000001BB
+:101FD000020E002000000001020E0024000000019B
+:101FE000020E002800000001020E002C000000017B
+:101FF000020E003000000001020E0034000000015B
+:10200000020E003800000001020E003C000000013A
+:10201000020E004000000001020E0044000000011A
+:102020000730040000AF0000083007680013037693
+:1020300007340000331C00000734800032780CC8DD
+:10204000073500001A801967083539B058CA037877
+:10205000013000000000000001300004000000001A
+:1020600001300008000000000130000C00000000FA
+:1020700001300010000000000130001400000000DA
+:1020800002300020000000010230002400000002A5
+:1020900002300028000000030230002C0000000085
+:1020A0000230003000000004023000340000000163
+:1020B00002300038000000000230003C0000000147
+:1020C0000230004000000004023000440000000024
+:1020D00002300048000000010230004C0000000304
+:1020E00002300050000000000230005400000001E7
+:1020F00002300058000000040230005C00000000C4
+:1021000002300060000000010230006400000003A3
+:1021100002300068000000000230006C0000000186
+:102120000230007000000004023000740000000063
+:1021300002300078000000040230007C0000000340
+:102140000630008000000002023000A400003FFFC3
+:10215000023000A8000003FF02300224000000004B
+:1021600002300234000000000230024C0000000087
+:10217000023002E40000FFFF0630200000000800EB
+:1021800002338BC000000001023380000000001AFF
+:10219000023380400000004E0233808000000010B7
+:1021A000023380C0000000200C3383000007A12010
+:1021B0000A338300000001380B33830000001388CA
+:1021C0000A338340000000000C338340000001F418
+:1021D0000B33834000000005023383800007A120F9
+:1021E000023383C0000001F406322A88000000C2D6
+:1021F00006322008000000C806322000000000025D
+:10220000063223E80000004004322E580004037A0E
+:10221000063250A000000004063250B80000000250
+:102220000632508000000006043250980002037EFF
+:10223000063250000000002006323000000004008A
+:1022400006321C0000000004043218300002038033
+:10225000063224E8000000B402322DB00000000075
+:1022600006324000000000B40632300000000020BA
+:10227000063231000000002006323200000000204B
+:102280000632330000000020063234000000002037
+:102290000632350000000020063236000000002023
+:1022A000063237000000002006323800000000200F
+:1022B000063239000000002006323A0000000020FB
+:1022C00006323B000000002006323C0000000020E7
+:1022D00006323D000000002006323E0000000020D3
+:1022E00006323F000000002006321C1000000002F1
+:1022F000063245A000000024063227B8000000B4D2
+:1023000002322DB400000000063242D0000000B4BA
+:1023100006323080000000200632318000000020AC
+:102320000632328000000020063233800000002098
+:102330000632348000000020063235800000002084
+:102340000632368000000020063237800000002070
+:10235000063238800000002006323980000000205C
+:1023600006323A800000002006323B800000002048
+:1023700006323C800000002006323D800000002034
+:1023800006323E800000002006323F800000002020
+:1023900006321C20000000020632463000000024F5
+:1023A0000720040000870000082007800010038237
+:1023B000072400003165000007248000081D0C5A26
+:1023C00008248EB06C9003840120000000000000FF
+:1023D00001200004000000000120000800000000AF
+:1023E0000120000C0000000001200010000000008F
+:1023F0000120001400000000022000200000000165
+:102400000220002400000002022000280000000337
+:102410000220002C00000000022000300000000418
+:1024200002200034000000010220003800000000FB
+:102430000220003C000000010220004000000004D7
+:1024400002200044000000000220004800000001BB
+:102450000220004C00000003022000500000000099
+:102460000220005400000001022000580000000477
+:102470000220005C0000000002200060000000015B
+:102480000220006400000003022000680000000039
+:102490000220006C00000001022000700000000417
+:1024A00002200074000000000220007800000004F8
+:1024B0000220007C000000030620008000000002D3
+:1024C000022000A400003FFF022000A8000003FF3C
+:1024D000022002240000000002200234000000005C
+:1024E0000220024C00000000022002E40000FFFF76
+:1024F000062020000000080002238BC0000000011D
+:10250000022380000000001002238040000000121F
+:102510000223808000000030022380C00000000EF3
+:102520000C2383000007A1200A2383000000013848
+:102530000B238300000013880A238340000000005F
+:102540000C238340000001F40B23834000000005AE
+:10255000022383800007A120022383C0000001F42E
+:10256000062250000000004206222008000000C899
+:10257000062220000000000206224000000000C6E3
+:1025800004224318000503860622432C0000000B9A
+:10259000042243580005038B0622436C0000000B05
+:1025A0000422439800050390062243AC0000000B70
+:1025B000042243D800050395062243EC0000000BDB
+:1025C000042244180005039A0622442C0000000B44
+:1025D000042244580005039F0622446C0000000BAF
+:1025E00004224498000503A4062244AC0000000B1A
+:1025F000042244D8000503A9062244EC0000000B85
+:1026000004224518000503AE0622452C0000000BED
+:1026100004224558000503B30622456C0000000B58
+:1026200004224598000503B8062245AC0000000BC3
+:10263000042245D8000503BD062245EC0000000B2E
+:1026400004224618000503C20622462C0000000B97
+:1026500004224658000503C70622466C0000000B02
+:1026600004224698000503CC062246AC0000000B6D
+:10267000042246D8000503D1062246EC0000000BD8
+:1026800004224718000503D60622472C0000000B41
+:1026900004224758000503DB0622476C0000000BAC
+:1026A00004224798000503E0062247AC0000000B17
+:1026B000042247D8000503E5062247EC0000000B82
+:1026C00004224818000503EA0622482C0000000BEB
+:1026D00004224858000503EF0622486C0000000B56
+:1026E00004224898000503F4062248AC0000000BC1
+:1026F000042248D8000503F9062248EC0000000B2C
+:1027000004224918000503FE0622492C0000000B94
+:1027100004224958000504030622496C0000000BFE
+:102720000422499800050408062249AC0000000B69
+:10273000042249D80005040D062249EC0000000BD4
+:1027400004224A180005041206224A2C0000000B3D
+:1027500004224A580005041706224A6C0000000BA8
+:1027600004224A980005041C06224AAC0000000B13
+:1027700004224AD80005042106224AEC0000000584
+:1027800006224B000000001704224B5C00010426C7
+:1027900006224B600000000304224B6C000104275A
+:1027A000062238000000004006223000000002002F
+:1027B000042251C00004042806221000000000C0BA
+:1027C000062215C00000024004221EC80008042C86
+:1027D0000622390000000008022251180000000003
+:1027E000062251D00000000606221300000000025D
+:1027F00006221410000000300622392000000008D4
+:102800000222511C00000000062251E800000006D0
+:102810000622130800000002062214D00000003037
+:102820000216100000000028021700080000000235
+:102830000217002C000000030217003C00000004F7
+:1028400002170044000000000217004800000002C8
+:102850000217004C0000009002170050000000908A
+:102860000217005400800090021700580810000062
+:10287000021700600000008A021700640000008058
+:1028800002170068000000810217006C0000008041
+:10289000021700700000000602170078000007D041
+:1028A0000217007C0000076C02170038007C10043F
+:1028B000021700040000000F06164024000000026A
+:1028C000021640700000001C0216420800000001C1
+:1028D0000216421000000001021642200000000112
+:1028E00002164228000000010216423000000001DA
+:1028F000021642380000000102164260000000018A
+:102900000C16401C0003D0900A16401C0000009CCE
+:102910000B16401C000009C40216403000000008DD
+:10292000021640340000000C02164038000000106F
+:102930000216404400000020021640000000000182
+:10294000021640D8000000010216400800000001F5
+:102950000216400C000000010216401000000001A9
+:10296000021642400000000002164248000000002B
+:1029700006164270000000020216425000000000DD
+:1029800002164258000000000616428000000002B5
+:1029900002166008000006140216600C0000060013
+:1029A00002166010000006040216601C0000FFFF03
+:1029B000021660200000FFFF021660240000FFFFE7
+:1029C000021660280000FFFF021660380000002099
+:1029D0000216603C00000020061660400000000265
+:1029E00002166048000000230216604C000000241C
+:1029F00002166050000000250216605400000026F8
+:102A000002166058000000270216605C00000029D2
+:102A1000021660600000002A021660640000002BAD
+:102A2000021660680000002C0216606C0000002D89
+:102A30000616607000000012021660B80000000167
+:102A4000021660BC00000001061660C00000003ED7
+:102A5000021661B800000001061661BC0000001FEC
+:102A60000216623807FFFFFF0216623C0000003FBB
+:102A70000216624007FFFFFF021662440000000FCB
+:102A800001166248000000000116624C00000000C0
+:102A900001166250000000000116625400000000A0
+:102AA00001166258000000000116625C0000000080
+:102AB0000116626000000000011662640000000060
+:102AC00001166268000000000116626C0000000040
+:102AD0000116627000000000011662740000000020
+:102AE00001166278000000000116627C0000000000
+:102AF000021664BC000000010C166000000003E830
+:102B00000A166000000000010B1660000000000AB9
+:102B100002168040000000060216804400000005F6
+:102B2000021680480000000A0216804C00000005D2
+:102B30000216805400000002021680CC000000043F
+:102B4000021680D000000004021680D400000004A9
+:102B5000021680D800000004021680DC0000000489
+:102B6000021680E000000004021680E40000000469
+:102B7000021680E800000004021688040000000429
+:102B8000021680300000007C021680340000003DF8
+:102B9000021680380000003F0216803C0000009CB6
+:102BA000021680F000000007061680F40000000501
+:102BB0000216880C010101010216810800000000C4
+:102BC0000216810C000000040216811000000004AF
+:102BD0000216811400000002021688100801200469
+:102BE00002168118000000050216811C0000000575
+:102BF0000216812000000005021681240000000555
+:102C00000216882C200810010216812800000008F6
+:102C10000216812C00000006021681300000000719
+:102C200002168134000000000216883001010120E4
+:102C300006168138000000040216883401010101E3
+:102C400006168148000000040216883801010101BF
+:102C500006168158000000040216883C010101019B
+:102C6000061681680000000302168174000000014E
+:102C7000021688400101010102168178000000015E
+:102C80000216817C00000001021681800000000114
+:102C9000021681840000000102168844010101012E
+:102CA00002168188000000010216818C00000004D9
+:102CB00002168190000000040216819400000002B8
+:102CC00002168848080120040216819800000005B9
+:102CD0000216819C00000005021681A0000000057C
+:102CE000021681A4000000050216881420081001B5
+:102CF000021681A800000008021681AC0000000640
+:102D0000021681B000000007021681B40000000125
+:102D10000216881801010120021681B80000000186
+:102D2000021681BC00000001021681C000000001F3
+:102D3000021681C4000000010216881C0101010175
+:102D4000021681C800000001021681CC00000001BB
+:102D5000021681D000000001021681D4000000019B
+:102D60000216882001010101021681D8000000012D
+:102D7000021681DC00000001021681E00000000163
+:102D8000021681E4000000010216882401010101FD
+:102D9000021681E800000001021681EC000000012B
+:102DA000021681F0000000010216882801010101CD
+:102DB00002168240FFFF003F061682440000000218
+:102DC0000216824CFFFF003F0216825000000100F5
+:102DD000021682540000010006168258000000020C
+:102DE00002168260000000C002168264000000C06B
+:102DF0000216826800001E000216826C00001E008F
+:102E0000021682700000400002168274000040002A
+:102E100002168278000080000216827C000080008A
+:102E2000021682800000200002168284000020002A
+:102E30000616828800000007021682A40000000126
+:102E4000061682A80000000A021681F400000C0891
+:102E5000021681F800000040021681FC000001000B
+:102E600002168200000000200216820400000017F3
+:102E700002168208000000800216820C0000020088
+:102E8000021682100000000002168218FFFF01FFE8
+:102E900002168214FFFF01FF0216823C000000139D
+:102EA000021680900000013F021680600000014081
+:102EB00002168064000001400616806800000002CF
+:102EC00002168070000000C0061680740000000723
+:102ED0000216809C00000048021680A000000048F6
+:102EE000061680A400000002021680AC0000004814
+:102EF000061680B00000000702168238000080002D
+:102F000002168234000025E40216809400007FFF40
+:102F100002168220000000070216821C0000000733
+:102F2000021682280000000002168224FFFFFFFF25
+:102F300002168230000000000216822CFFFFFFFF05
+:102F4000021680EC000000FF0214000000000001E7
+:102F50000214000C000000010214004000000001F7
+:102F60000214004400007FFF0214000C0000000067
+:102F700002140000000000000214006C00000000B9
+:102F800002140004000000010214003000000001DF
+:102F900002140004000000000214005C00000000A5
+:102FA00002140008000000010214003400000001B7
+:102FB000021400080000000002140060000000007D
+:102FC00006028000000020000202005800000032CB
+:102FD000020200A003150020020200A40315002035
+:102FE000020200A801000030020200AC081000003C
+:102FF000020200B000000033020200B40000003002
+:10300000020200B800000031020200BC0000000310
+:10301000020200C000000006020200C4000000031B
+:10302000020200C800000003020200CC00000002FF
+:10303000020200D000000000020200D400000002E2
+:10304000020200DC00000000020200E000000006B6
+:10305000020200E400000004020200E80000000296
+:10306000020200EC00000002020200F00000000179
+:10307000020200FC00000006020201200000000025
+:103080000202013400000002020201B0000000014F
+:103090000202020C00000001020202140000000102
+:1030A00002020218000000020202040400000001F3
+:1030B0000202040C00000040020204100000004064
+:1030C0000202041C00000004020204200000002090
+:1030D0000202042400000002020204280000001F73
+:1030E00006020500000000120402048000200434DF
+:1030F000020200600000000F0202006400000007EE
+:1031000002020068000000000202006C0000000ED5
+:103110000602007000000004020200F40000000437
+:103120000202000400000001020200080000000189
+:103130000202000C00000001020200100000000169
+:103140000202001400000001020200180000000149
+:103150000202001C00000001020200200000000129
+:103160000202002400000001020200280000000109
+:103170000202002C000000010202003000000001E9
+:1031800002020034000000010202003800000001C9
+:103190000202003C000000010202004000000001A9
+:1031A0000202004400000001020200480000000189
+:1031B0000202004C00000001020200500000000169
+:1031C00002020108000000C802020118000000020B
+:1031D000020201C400000000020201CC0000000055
+:1031E000020201D400000002020201DC0000000221
+:1031F000020201E4000000FF020201EC000000FFF7
+:103200000202010C000000C80202011C00000002C2
+:10321000020201C800000000020201D0000000000C
+:10322000020201D800000002020201E000000002D8
+:10323000020201E8000000FF020201F0000000FFAE
+:1032400007280400008D00000828076800130454B4
+:10325000072C000034090000072C800038990D036A
+:10326000072D0000390C1B2A072D80000641296E0E
+:10327000082D8AB04EAA0456012800000000000064
+:1032800001280004000000000128000800000000E0
+:103290000128000C000000000128001000000000C0
+:1032A0000128001400000000022800200000000196
+:1032B0000228002400000002022800280000000369
+:1032C0000228002C0000000002280030000000044A
+:1032D000022800340000000102280038000000002D
+:1032E0000228003C00000001022800400000000409
+:1032F00002280044000000000228004800000001ED
+:103300000228004C000000030228005000000000CA
+:1033100002280054000000010228005800000004A8
+:103320000228005C0000000002280060000000018C
+:10333000022800640000000302280068000000006A
+:103340000228006C00000001022800700000000448
+:103350000228007400000000022800780000000429
+:103360000228007C00000003062800800000000204
+:10337000022800A400003FFF022800A8000003FF6D
+:10338000022802240000000002280234000000008D
+:103390000228024C00000000022802E40000FFFFA7
+:1033A0000628200000000800022B8BC0000000014E
+:1033B000022B800000000000022B8040000000185B
+:1033C000022B80800000000C022B80C000000066F1
+:1033D0000C2B83000007A1200A2B8300000001387A
+:1033E0000B2B8300000013880A2B83400000000091
+:1033F0000C2B8340000001F40B2B834000000005E0
+:10340000022B83800007A120022B83C0000001F45F
+:10341000062A3D4800000004042A3D5800020458D2
+:10342000062A3D6000000006062A30000000004821
+:10343000062A2008000000C8062A2000000000021A
+:10344000062A31280000008E062A33680000000397
+:10345000042A33740001045A062A3A780000000254
+:10346000042A3A800002045B042A3A700002045DD8
+:10347000042A3E280002045F042A3EB000040461CE
+:10348000042A250000020465062A25080000010020
+:10349000062A297000000004042A29600004046739
+:1034A000042A2F480002046B062A3378000000D853
+:1034B000022A3A3800000000062A3A88000000324A
+:1034C000042A3D880010046D062A502000000002E6
+:1034D000062A503000000002062A500000000002B8
+:1034E000062A501000000002022A50B80000000115
+:1034F000062A50480000000E042A3D780002047D90
+:10350000062A3C1800000026022A50400000000055
+:10351000062A36D8000000D8022A3A3C00000000F3
+:10352000062A3B5000000032042A3DC80010047FE8
+:10353000062A502800000002062A50380000000227
+:10354000062A500800000002062A50180000000257
+:10355000022A50BC00000001062A50800000000E24
+:10356000042A3D800002048F062A3CB00000002699
+:10357000022A504400000000021010080000000160
+:103580000210101000000264021010000003D000AE
+:10359000021010040000003D091018000200049100
+:1035A00009101100001006910610114000000008DB
+:1035B00009101160000806A1061011800000000229
+:1035C00009101188000606A9061011A000000018B5
+:1035D000021010100000000006102400000000E09F
+:1035E0000210201C0000000002102020000000013A
+:1035F000021020C0000000010210200400000001A1
+:10360000021020080000000109103C00000506AF70
+:1036100009103C20000506B409103800000506B961
+:1036200002104028000000100210404400003FFF3C
+:103630000210405800280000021040840084924A82
+:1036400006104C000000010002104058000000006D
+:103650000610806800000004021080000000108046
+:1036600006108028000000020210803800000010C0
+:10367000021080400000FFFF021080440000FFFFA6
+:1036800002108050000000000210810000000000C5
+:10369000061081200000000202108008000002B520
+:1036A0000210801000000000061082000000004A96
+:1036B000021081080001FFFF061081400000000297
+:1036C0000210800000001A80061090000000002404
+:1036D000061091200000004A061093700000004A76
+:1036E000061095C00000004A0210800400001080FF
+:1036F00006108030000000020210803C0000001024
+:10370000021080480000FFFF0210804C0000FFFF05
+:10371000021080540000000002108104000000002C
+:1037200006108128000000020210800C000002B583
+:103730000210801400000000061084000000004AFF
+:103740000210810C0001FFFF0610814800000002FA
+:103750000210800400001A800610909000000024DF
+:10376000061092480000004A061094980000004A93
+:10377000061096E80000004A0212049000E383401D
+:103780000212051400003C10021205200000000285
+:1037900002120494FFFFFFFF02120498FFFFFFFFD5
+:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5
+:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95
+:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75
+:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D
+:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D
+:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D
+:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4
+:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC
+:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C
+:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C
+:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C
+:1038500002120500FFFFFFFF02120504FFFFFFFF3A
+:1038600002120508FFFFFFFF0212050CFFFFFFFF1A
+:1038700002120510FFFFFFFF021204D4FFFF3330D6
+:10388000021204D8FFFF3340021204B4F0003000EB
+:1038900002120390000000080212039C00000008BE
+:1038A000061203A000000002021203BC0000000484
+:1038B000021203C400000004021203D00000000042
+:1038C000021203DC000000000212036C0000000181
+:1038D000021203680000003F021201BC0000004019
+:1038E000021201C000001808021201C400000803FF
+:1038F000021201C800000803021201CC00000040BF
+:10390000021201D000000003021201D400000803DB
+:10391000021201D800000803021201DC00000803B3
+:10392000021201E000010003021201E4000008039A
+:10393000021201E800000803021201EC000000037B
+:10394000021201F000000003021201F40000000363
+:10395000021201F800000003021201FC0000000343
+:103960000212020000000003021202040000000321
+:1039700002120208000000030212020C0000000301
+:1039800002120210000000030212021400000003E1
+:1039900002120218000000030212021C00000003C1
+:1039A00002120220000000030212022400000003A1
+:1039B00002120228000024030212022C0000002F31
+:1039C0000212023000000009021202340000001945
+:1039D00002120238000001840212023C000001833E
+:1039E0000212024000000306021202440000001905
+:1039F00002120248000000060212024C00000306F8
+:103A000002120250000003060212025400000306D4
+:103A10000212025800000C860212025C000003062B
+:103A20000212026000000306021202640000000697
+:103A300002120268000000060212026C000000067A
+:103A4000021202700000000602120274000000065A
+:103A500002120278000000060212027C000000063A
+:103A6000021202800000000602120284000000061A
+:103A700002120288000000060212028C00000006FA
+:103A800002120290000000060212029400000006DA
+:103A900002120298000000060212029C00000006BA
+:103AA000021202A000000306021202A4000000138A
+:103AB000021202A800000006021202B00000100468
+:103AC000021202B400001004021203240010644029
+:103AD0000212032800106440021201B0000000012D
+:103AE0000600A000000000160200A06CBF5C0000F1
+:103AF0000200A070FFF51FEF0200A0740000FFFF9E
+:103B00000200A078F00003E00200A07C00000000AA
+:103B10000200A0800000A0000600A08400000005B4
+:103B20000200A0980FE000000600A09C0000001416
+:103B30000200A0EC555400000200A0F05555555568
+:103B40000200A0F4000055550200A0F8F0000000AB
+:103B50000200A0FC555400000200A1005555555527
+:103B60000200A104000055550200A108F000000069
+:103B70000600A22C000000040200A0600000030761
+:103B80000200A10CBF5C00000200A110FFF51FEFB6
+:103B90000200A1140000FFFF0200A118F00003E0E2
+:103BA0000200A11C000000000200A1200000A000F3
+:103BB0000600A124000000050200A1380FE000006B
+:103BC0000600A13C000000140200A18C5554000026
+:103BD0000200A190555555550200A194000055557D
+:103BE0000200A198F00000000200A19C55540000C2
+:103BF0000200A1A0555555550200A1A4000055553D
+:103C00000200A1A8F00000000600A23C0000000491
+:103C10000200A06400000307000000000000000094
+:103C20000000002E00000000000000000000000066
+:103C30000000000000000000000000000000000084
+:103C40000000000000000000000000000000000074
+:103C50000000000000000000000000000000000064
+:103C60000000000000000000000000000000000054
+:103C70000000000000000000002E004D00000000C9
+:103C80000000000000000000000000000000000034
+:103C90000000000000000000000000000000000024
+:103CA00000000000004D008B00000000000000003C
+:103CB0000000000000000000000000000000000004
+:103CC00000000000000000000000000000000000F4
+:103CD000008B009000900094009400980000000079
+:103CE00000000000000000000000000000000000D4
+:103CF000000000000000000000000000009802DE4C
+:103D000002DE02E802E802F200000000000000000B
+:103D100000000000000000000000000000000000A3
+:103D20000000000000000000000000000000000093
+:103D30000000000000000000000000000000000083
+:103D40000000000000000000000000000000000073
+:103D50000000000000000000000000000000000063
+:103D60000000000000000000000000000000000053
+:103D70000000000000000000000000000000000043
+:103D80000000000000000000000000000000000033
+:103D90000000000000000000000000000000000023
+:103DA0000000000000000000000000000000000013
+:103DB0000000000000000000000000000000000003
+:103DC00000000000000000000000000000000000F3
+:103DD000000000000000000002F202FA00000000F3
+:103DE00000000000000000000000000000000000D3
+:103DF00000000000000000000000000000000000C3
+:103E000000000000000000000000000000000000B2
+:103E100000000000000000000000000000000000A2
+:103E20000000000000000000000000000000000092
+:103E300002FA02FF02FF030A030A03150000000052
+:103E40000000000000000000000000000000000072
+:103E50000000000000000000000000000000000062
+:103E60000000000000000000000000000000000052
+:103E70000000000000000000000000000000000042
+:103E80000000000000000000031503160000000001
+:103E90000000000000000000000000000000000022
+:103EA0000000000000000000000000000000000012
+:103EB000000000000316035700000000000000008F
+:103EC00000000000000000000000000000000000F2
+:103ED00000000000000000000000000000000000E2
+:103EE0000357037B000000000000000000000000FA
+:103EF00000000000000000000000000000000000C2
+:103F0000000000000000000000000000037B03BB75
+:103F100000000000000000000000000000000000A1
+:103F20000000000000000000000000000000000091
+:103F3000000000000000000003BB03F700000000C9
+:103F40000000000000000000000000000000000071
+:103F50000000000000000000000000000000000061
+:103F60000000000003F7043D043D045204520467BE
+:103F70000000000000000000000000000000000041
+:103F80000000000000000000000000000000000031
+:103F9000046704ED04ED04F204F204F700000000ED
+:103FA0000000000000000000000000000000000011
+:103FB00000000000000000000000000004F704F80A
+:103FC00000000000000000000000000000000000F1
+:103FD00000000000000000000000000000000000E1
+:103FE000000000000000000004F8050A00000000C6
+:103FF00000000000000000000000000000000000C1
+:1040000000000000000000000000000000000000B0
+:1040100000000000050A051F051F052205220525D1
+:104020000000000000000000000000000000000090
+:104030000000000000000000000000000000000080
+:1040400005250555000000000000000000000000EC
+:104050000000000000000000000000000000000060
+:10406000000000000000000000000000055505DC15
+:104070000000000000000000000000000000000040
+:104080000000000000000000000000000000000030
+:10409000000000000000000005DC05E305E305E783
+:1040A00005E705EB00000000000000000000000034
+:1040B0000000000000000000000000000000000000
+:1040C0000000000005EB062B062B06330633063BEB
+:1040D00000000000000000000000000000000000E0
+:1040E00000000000000000000000000000000000D0
+:1040F000063B068806880695069506A20000000085
+:1041000000000000000000000000000000000000AF
+:1041100000000000000000000000000006A206AE43
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:10414000000000000000000006AE06B40000000001
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:104170000000000006B406B70000000000000000C8
+:10418000000000000000000000000000000000002F
+:10419000000000000000000000000000000000001F
+:1041A00006B706BD0000000000000000000000008F
+:1041B00000000000000000000000000000000000FF
+:1041C00000000000000000000000000006BD06BE68
+:1041D00006BE06D006D006E2000000000000000087
+:1041E00000000000000000000000000000000000CF
+:1041F000000000000000000006E2074F0000000081
+:1042000000000000000000000000000000000000AE
+:10421000000000000000000000000000000000009E
+:1042200000000000074F0750075007630763077639
+:10423000000000000000000000000000000000007E
+:10424000000000000000000000000000000000006E
+:10425000000000000000000000000000000000005E
+:10426000000000000000000000000000000000004E
+:10427000000000000000000000000000000000003E
+:10428000000000000000000000000000000000002E
+:10429000000000000000000000000000000000001E
+:1042A000000000000000000000000000000000000E
+:1042B00000000000000000000000000000000000FE
+:1042C00000000000000000000000000000000000EE
+:1042D00000000000000000000000000000000000DE
+:1042E00000000000000000000000000000000000CE
+:1042F00000000000000000000000000000000000BE
+:1043000000000000000000000000000000000000AD
+:10431000000000000000000000000000000000009D
+:10432000000000000000000000000000000000008D
+:1043300000010000000204C00003098000040E40D8
+:1043400000051300000617C000071C80000821406C
+:1043500000092600000A2AC0000B2F80000C344000
+:10436000000D3900000E3DC0000F42800010474094
+:1043700000114C00001250C00013558000145A4028
+:1043800000155F00001663C00017688000186D40BC
+:1043900000197200001A76C0001B7B80001C804050
+:1043A000001D8500001E89C0001F8E800000934004
+:1043B00000002000000040000000600000008000BD
+:1043C0000000A0000000C0000000E00000010000AC
+:1043D0000001200000014000000160000001800099
+:1043E0000001A0000001C0000001E0000002000088
+:1043F0000002200000024000000260000002800075
+:104400000002A0000002C0000002E0000003000063
+:104410000003200000034000000360000003800050
+:104420000003A0000003C0000003E000000400003F
+:10443000000420000004400000046000000480002C
+:104440000004A0000004C0000004E000000500001B
+:104450000005200000054000000560000005800008
+:104460000005A0000005C0000005E00000060000F7
+:1044700000062000000640000006600000068000E4
+:104480000006A0000006C0000006E00000070000D3
+:1044900000072000000740000007600000078000C0
+:1044A0000007A0000007C0000007E00000080000AF
+:1044B000000820000008400000086000000880009C
+:1044C0000008A0000008C0000008E000000900008B
+:1044D0000009200000094000000960000009800078
+:1044E0000009A0000009C0000009E000000A000067
+:1044F000000A2000000A4000000A6000000A800054
+:10450000000AA000000AC000000AE000000B000042
+:10451000000B2000000B4000000B6000000B80002F
+:10452000000BA000000BC000000BE000000C00001E
+:10453000000C2000000C4000000C6000000C80000B
+:10454000000CA000000CC000000CE000000D0000FA
+:10455000000D2000000D4000000D6000000D8000E7
+:10456000000DA000000DC000000DE000000E0000D6
+:10457000000E2000000E4000000E6000000E8000C3
+:10458000000EA000000EC000000EE000000F0000B2
+:10459000000F2000000F4000000F6000000F80009F
+:1045A000000FA000000FC000000FE000001000008E
+:1045B000001020000010400000106000001080007B
+:1045C0000010A0000010C0000010E000001100006A
+:1045D0000011200000114000001160000011800057
+:1045E0000011A0000011C0000011E0000012000046
+:1045F0000012200000124000001260000012800033
+:104600000012A0000012C0000012E0000013000021
+:10461000001320000013400000136000001380000E
+:104620000013A0000013C0000013E00000140000FD
+:1046300000142000001440000014600000148000EA
+:104640000014A0000014C0000014E00000150000D9
+:1046500000152000001540000015600000158000C6
+:104660000015A0000015C0000015E00000160000B5
+:1046700000162000001640000016600000168000A2
+:104680000016A0000016C0000016E0000017000091
+:10469000001720000017400000176000001780007E
+:1046A0000017A0000017C0000017E000001800006D
+:1046B000001820000018400000186000001880005A
+:1046C0000018A0000018C0000018E0000019000049
+:1046D0000019200000194000001960000019800036
+:1046E0000019A0000019C0000019E000001A000025
+:1046F000001A2000001A4000001A6000001A800012
+:10470000001AA000001AC000001AE000001B000000
+:10471000001B2000001B4000001B6000001B8000ED
+:10472000001BA000001BC000001BE000001C0000DC
+:10473000001C2000001C4000001C6000001C8000C9
+:10474000001CA000001CC000001CE000001D0000B8
+:10475000001D2000001D4000001D6000001D8000A5
+:10476000001DA000001DC000001DE000001E000094
+:10477000001E2000001E4000001E6000001E800081
+:10478000001EA000001EC000001EE000001F000070
+:10479000001F2000001F4000001F6000001F80005D
+:1047A000001FA000001FC000001FE000002000004C
+:1047B0000020200000204000002060000020800039
+:1047C0000020A0000020C0000020E0000021000028
+:1047D0000021200000214000002160000021800015
+:1047E0000021A0000021C0000021E0000022000004
+:1047F00000222000002240000022600000228000F1
+:104800000022A0000022C0000022E00000230000DF
+:1048100000232000002340000023600000238000CC
+:104820000023A0000023C0000023E00000240000BB
+:1048300000242000002440000024600000248000A8
+:104840000024A0000024C0000024E0000025000097
+:104850000025200000254000002560000025800084
+:104860000025A0000025C0000025E0000026000073
+:104870000026200000264000002660000026800060
+:104880000026A0000026C0000026E000002700004F
+:10489000002720000027400000276000002780003C
+:1048A0000027A0000027C0000027E000002800002B
+:1048B0000028200000284000002860000028800018
+:1048C0000028A0000028C0000028E0000029000007
+:1048D00000292000002940000029600000298000F4
+:1048E0000029A0000029C0000029E000002A0000E3
+:1048F000002A2000002A4000002A6000002A8000D0
+:10490000002AA000002AC000002AE000002B0000BE
+:10491000002B2000002B4000002B6000002B8000AB
+:10492000002BA000002BC000002BE000002C00009A
+:10493000002C2000002C4000002C6000002C800087
+:10494000002CA000002CC000002CE000002D000076
+:10495000002D2000002D4000002D6000002D800063
+:10496000002DA000002DC000002DE000002E000052
+:10497000002E2000002E4000002E6000002E80003F
+:10498000002EA000002EC000002EE000002F00002E
+:10499000002F2000002F4000002F6000002F80001B
+:1049A000002FA000002FC000002FE000003000000A
+:1049B00000302000003040000030600000308000F7
+:1049C0000030A0000030C0000030E00000310000E6
+:1049D00000312000003140000031600000318000D3
+:1049E0000031A0000031C0000031E00000320000C2
+:1049F00000322000003240000032600000328000AF
+:104A00000032A0000032C0000032E000003300009D
+:104A1000003320000033400000336000003380008A
+:104A20000033A0000033C0000033E0000034000079
+:104A30000034200000344000003460000034800066
+:104A40000034A0000034C0000034E0000035000055
+:104A50000035200000354000003560000035800042
+:104A60000035A0000035C0000035E0000036000031
+:104A7000003620000036400000366000003680001E
+:104A80000036A0000036C0000036E000003700000D
+:104A900000372000003740000037600000378000FA
+:104AA0000037A0000037C0000037E00000380000E9
+:104AB00000382000003840000038600000388000D6
+:104AC0000038A0000038C0000038E00000390000C5
+:104AD00000392000003940000039600000398000B2
+:104AE0000039A0000039C0000039E000003A0000A1
+:104AF000003A2000003A4000003A6000003A80008E
+:104B0000003AA000003AC000003AE000003B00007C
+:104B1000003B2000003B4000003B6000003B800069
+:104B2000003BA000003BC000003BE000003C000058
+:104B3000003C2000003C4000003C6000003C800045
+:104B4000003CA000003CC000003CE000003D000034
+:104B5000003D2000003D4000003D6000003D800021
+:104B6000003DA000003DC000003DE000003E000010
+:104B7000003E2000003E4000003E6000003E8000FD
+:104B8000003EA000003EC000003EE000003F0000EC
+:104B9000003F2000003F4000003F6000003F8000D9
+:104BA000003FA000003FC000003FE000003FE001E8
+:104BB00000000000000001FF0000020000007FF87C
+:104BC00000007FF80000016A0000150000000001ED
+:104BD0000000FF00000000000000FF0000000000D7
+:104BE00000000000140AFF000000000100000000A7
+:104BF00000201001000000000100860000000100FC
+:104C00000000860200008604000086060000860878
+:104C10000000860A0000860C0000860E0000861048
+:104C20000000861200008614000086160000861818
+:104C30000000861A0000861C0000861E00008620E8
+:104C400000008622000086240000862600008628B8
+:104C50000000862A0000862C0000862E0000863088
+:104C60000000863200008634000086360000863858
+:104C70000000863A0000863C0000863E0000864028
+:104C800000008642000086440000864600008648F8
+:104C90000000864A0000864C0000864E00008650C8
+:104CA0000000865200008654000086560000865898
+:104CB0000000865A0000865C0000865E0000866068
+:104CC0000000866200008664000086660000866838
+:104CD0000000866A0000866C0000866E0000867008
+:104CE00000008672000086740000867600008678D8
+:104CF0000000867A0000867C0000867E00008680A8
+:104D00000000868200008684000086860000868877
+:104D10000000868A0000868C0000868E0000869047
+:104D20000000869200008694000086960000869817
+:104D30000000869A0000869C0000869E000086A0E7
+:104D4000000086A2000086A4000086A6000086A8B7
+:104D5000000086AA000086AC000086AE000086B087
+:104D6000000086B2000086B4000086B6000086B857
+:104D7000000086BA000086BC000086BE000086C027
+:104D8000000086C2000086C4000086C6000086C8F7
+:104D9000000086CA000086CC000086CE000086D0C7
+:104DA000000086D2000086D4000086D6000086D897
+:104DB000000086DA000086DC000086DE000086E067
+:104DC000000086E2000086E4000086E6000086E837
+:104DD000000086EA000086EC000086EE000086F007
+:104DE000000086F2000086F4000086F6000086F8D7
+:104DF000000086FA000086FC000086FE00008700A6
+:104E00000000870200008704000087060000870872
+:104E10000000870A0000870C0000870E0000871042
+:104E20000000871200008714000087160000871812
+:104E30000000871A0000871C0000871E00008720E2
+:104E400000008722000087240000872600008728B2
+:104E50000000872A0000872C0000872E0000873082
+:104E60000000873200008734000087360000873852
+:104E70000000873A0000873C0000873E0000874022
+:104E800000008742000087440000874600008748F2
+:104E90000000874A0000874C0000874E00008750C2
+:104EA0000000875200008754000087560000875892
+:104EB0000000875A0000875C0000875E0000876062
+:104EC0000000876200008764000087660000876832
+:104ED0000000876A0000876C0000876E0000877002
+:104EE00000008772000087740000877600008778D2
+:104EF0000000877A0000877C0000877E00008780A2
+:104F00000000878200008784000087860000878871
+:104F10000000878A0000878C0000878E0000879041
+:104F20000000879200008794000087960000879811
+:104F30000000879A0000879C0000879E000087A0E1
+:104F4000000087A2000087A4000087A6000087A8B1
+:104F5000000087AA000087AC000087AE000087B081
+:104F6000000087B2000087B4000087B6000087B851
+:104F7000000087BA000087BC000087BE000087C021
+:104F8000000087C2000087C4000087C6000087C8F1
+:104F9000000087CA000087CC000087CE000087D0C1
+:104FA000000087D2000087D4000087D6000087D891
+:104FB000000087DA000087DC000087DE000087E061
+:104FC000000087E2000087E4000087E6000087E831
+:104FD000000087EA000087EC000087EE000087F001
+:104FE000000087F2000087F4000087F6000087F8D1
+:104FF000000087FA000087FC000087FEFFFFFFFF2C
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399
+:1050200000BEBC20000000000000000500000003DE
+:1050300000BEBC20000000000000000500002000B1
+:10504000000040C000006180000082400000A3001A
+:105050000000C3C00000E4800001054000012600FC
+:10506000000146C000016780000188400001A900DE
+:105070000001C9C00001EA8000020B4000022C00C0
+:1050800000024CC000026D8000028E400002AF00A2
+:105090000002CFC00002F08000001140000080003C
+:1050A000000103800001870000020A8000028E00D8
+:1050B00000031180000395000004188000049C0088
+:1050C00000051F800005A300000626800006AA0038
+:1050D00000072D800007B100000834800008B800E8
+:1050E00000093B800009BF00000A4280000AC60098
+:1050F000000B4980000BCD00000C5080000CD40048
+:10510000000D578000005B0000007FF800007FF872
+:1051100000000166000015000000FF000000000014
+:105120000000FF0000000000000019000000000067
+:1051300000000000FFFFFFFF00007FF800007FF885
+:1051400000000361000015000000FF000FFFFFFFDB
+:105150000000FF000FFFFFFF000000FF0000FF0046
+:105160000FFFFFFF0000FF000FFFFFFF000000FF29
+:105170000000FF000FFFFFFF0000FF000FFFFFFF19
+:10518000000000FF0000FF000FFFFFFF0000FF0016
+:105190000FFFFFFF000000FF0000FF000FFFFFFFF9
+:1051A0000000FF000FFFFFFF000000FF0000FF00F6
+:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9
+:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9
+:1051D000000000FF0000FF000FFFFFFF0000FF00C6
+:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9
+:1051F0000000FF000FFFFFFF000000FF0000FF00A6
+:105200000FFFFFFF0000FF000FFFFFFF000000FF88
+:105210000000FF000FFFFFFF0000FF000FFFFFFF78
+:10522000000000FF0000FF000FFFFFFF0000FF0075
+:105230000FFFFFFF000000FF0000FF000FFFFFFF58
+:105240000000FF000FFFFFFF000000FF0000FF0055
+:105250000FFFFFFF0000FF000FFFFFFF000000FF38
+:105260000000FF000FFFFFFF0000FF000FFFFFFF28
+:10527000000000FF0000FF000FFFFFFF0000FF0025
+:105280000FFFFFFF000000FF0000FF000FFFFFFF08
+:105290000000FF000FFFFFFF000000FF0000FF0005
+:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8
+:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8
+:1052C000000000FF0000FF000FFFFFFF0000FF00D5
+:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8
+:1052E0000000FF000FFFFFFF000000FF0000FF00B5
+:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98
+:105300000000FF000FFFFFFF0000FF000FFFFFFF87
+:10531000000000FF0000FF000FFFFFFF0000FF0084
+:105320000FFFFFFF000000FF0000FF000FFFFFFF67
+:105330000000FF000FFFFFFF000000FF0000FF0064
+:105340000FFFFFFF0000FF000FFFFFFF000000FF47
+:105350000000FF000FFFFFFF0000FF000FFFFFFF37
+:10536000000000FF0000FF000FFFFFFF0000FF0034
+:105370000FFFFFFF000000FF0000FF000FFFFFFF17
+:105380000000FF000FFFFFFF000000FF0000FF0014
+:105390000FFFFFFF0000FF000FFFFFFF000000FFF7
+:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7
+:1053B000000000FF0000FF000FFFFFFF0000FF00E4
+:1053C0000FFFFFFF000000FF000000FF000000FFD4
+:1053D0000000FF00000000000000FF0000000000CF
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1054000000001000000020800000310000004180FA
+:1054100000005200000062800000730000008380E2
+:10542000000094000000A4800000B5000000C580CA
+:105430000000D6000000E6800000F70000010780B1
+:105440000001180000012880000139000001498096
+:1054500000015A0000016A8000017B0000018B807E
+:1054600000019C000001AC800001BD000001CD8066
+:105470000001DE000001EE8000000F0000000000CF
+:1054800000007FF800007FF80000021D00001500FA
+:1054900010000000000028AD00010001FFFFFFFF29
+:1054A000FFFFFFFF00050206CCCCCCC17058103CBA
+:1054B000000000000000FF00000000000000FF00EE
+:1054C000000000000000000000000001CCCC020140
+:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1
+:1054E000FFFFFFFF0000FFFF000000000000FFFFC4
+:1054F000000000000000FFFF000000000000FFFFB0
+:10550000000000000000FFFF000000000000FFFF9F
+:10551000000000000000FFFF000000000000FFFF8F
+:1055200000000000000E0000011600D60000FFFF82
+:10553000000000000000FFFF000000000000FFFF6F
+:10554000000000000000FFFF000000000000FFFF5F
+:10555000000000000000FFFF000000000000FFFF4F
+:10556000000000000000FFFF0000000000720000CB
+:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B
+:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F
+:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1
+:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E
+:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C
+:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D
+:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2
+:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6
+:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00
+:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6
+:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7
+:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE
+:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19
+:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E
+:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC
+:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E
+:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D
+:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E
+:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F
+:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D
+:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B
+:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C
+:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1
+:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5
+:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF
+:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5
+:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6
+:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD
+:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19
+:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D
+:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B
+:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D
+:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1
+:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91
+:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1
+:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70
+:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1
+:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F
+:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91
+:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D
+:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71
+:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08
+:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50
+:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0
+:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30
+:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0
+:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10
+:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70
+:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA
+:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C
+:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D
+:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B
+:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29
+:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A
+:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF
+:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3
+:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD
+:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3
+:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90
+:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE
+:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2
+:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE
+:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8
+:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B
+:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB
+:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B
+:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D
+:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A
+:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28
+:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19
+:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE
+:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2
+:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC
+:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2
+:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3
+:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA
+:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82
+:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD
+:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8
+:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A
+:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE
+:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E
+:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE
+:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D
+:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE
+:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C
+:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E
+:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A
+:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E
+:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05
+:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D
+:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD
+:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D
+:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD
+:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D
+:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D
+:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED
+:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D
+:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD
+:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C
+:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD
+:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B
+:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D
+:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29
+:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D
+:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04
+:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C
+:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC
+:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C
+:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC
+:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C
+:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C
+:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC
+:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C
+:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC
+:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B
+:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC
+:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A
+:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C
+:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28
+:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C
+:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03
+:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B
+:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB
+:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B
+:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB
+:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B
+:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B
+:105D7000CDCDCDCD000C0000000700C00002813069
+:105D8000000B81580002021000010230000F024097
+:105D900000010330000C0000000800C00002814038
+:105DA000000B81680002022000010240000702503F
+:105DB000000202C000100000000801000002818003
+:105DC000000B81A80002026000018280000E829810
+:105DD0000008038000028000000B8028000200E021
+:105DE000000101000000811000000118CCCCCCCCD7
+:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3
+:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2
+:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2
+:105E2000CCCCCCCC00002000000000000000000022
+:105E30001F8B080000000000000BFB51CFC0F003D7
+:105E40008ABB5819180238107C7AE0A58C94E9DFD7
+:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346
+:105E6000D8F7241818182419184E893130EC9244A8
+:105E700088E702D5084A3130DC858A0500D967A554
+:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6
+:105E900089A3C93F86CA6F5480D03FD5B19BBB0947
+:105EA0002A0F00FE694F6760030000000000000039
+:105EB0001F8B080000000000000BED7D0B7854D50F
+:105EC000B9E8DACFD933994C7642422610700703ED
+:105ED000040D30208FA85427E1D1E0E5E8F0462EEC
+:105EE000CA80AF0892448D356D39373B6412020287
+:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3
+:105F0000DC206A73DAD37B9152A52DB6413D281669
+:105F100068F49403BDD796BBFE7FAD3DD97B672661
+:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C
+:105F3000FAFF7FEDA8A242D44B08B9083FD712B2AE
+:105F40004E2084E4F55EADFB448B56935C42AA82FE
+:105F5000AAB1953E5B2F858DC669F4FE2562E809DE
+:105F600002F7C7CD21930851E0BD0242A6C2FFA6A9
+:105F70001322E7B40E8FFAE93D6955165CADF1AC1A
+:105F80006B954C883E159E6F1B97EA7972FE84D202
+:105F9000D3AD11FCB9388690FAE337CE7FC56AD30A
+:105FA000FF4692CCDC9397D35F6692991725423EC9
+:105FB0002A5C94D569A41FEF83862E5D1E4BC8F919
+:105FC0008615F35F19DBF7F97A89D4B697F6BD7FAA
+:105FD00015D1102F4433D5C8C4DE75AF27A4D39391
+:105FE00043C8E6C24D6CBDB9145957D2FB6DFFA230
+:105FF000CB25BD70AE9769BFA97DD7438889E35A89
+:10600000E324DF4F7439DE77BF971C8FBF4F64FAEC
+:106010006F0621D885AE7FBA10BD16EE7B0A1799A0
+:1060200023687BFD33E5245A9A1EFE24BD3E21FCE5
+:10603000D67B69E9C8FB7DB4BFA985D0F74EAAF12C
+:10604000EBAFA27CF4DEF7A5D026E0A33DE3E7901A
+:1060500000BD4F181F59743AB5BF69782AFE4847EA
+:10606000A7BF275EE43F8BBFAAC455599DE493F3B5
+:10607000D71DC05F1936FE6A5FDCEF789F94BF6260
+:106080006EFEE2F838DDCED64F760F6374E1F4721F
+:10609000D3272D5D3EE97B7DF9690BE0D5D3BED8D2
+:1060A0001C4152F01387D7A2D7A78577203E222420
+:1060B0008E74262422C1FCBDF7D935A3CC1080CF25
+:1060C00068F330AC23C8A622C15B5BEE16299C01A5
+:1060D00092681D5744DBDD6B1600DC81E3F34F81D2
+:1060E0003C34872AB4D974BDFA34E3A179F49A51C7
+:1060F000AA0BB09EAD44042540C7AB36CB4B815EA6
+:1061000004DB4F9BB7844DC0030913329C90FBF80E
+:106110009A08110D99B655F8754CAA75A8A493E183
+:1061200043B8E8E9FB7EBAF5ABBDEF918B45F0FFD4
+:106130007B08AC6FA0F74894BD67D27F80EF1CD777
+:1061400038FA1CDAB6F17D80D8DAF4F951F805F1A5
+:106150007DF717325F36D9A719543FA825A29E8034
+:10616000FEC4C896693BA3922A22781E24072945BB
+:1061700006A44B332195EDC08FA49D2C9CD80BDF3A
+:106180002922E07A0A6EDFB9A685AAAE7365FE10F1
+:10619000F079502764584EDFF56C6BA08C3CDED64E
+:1061A0000E3D87FC1FA37C3486BE6F86983DDC5A6B
+:1061B000F2B21EB5C977862070BE74F30731E419B8
+:1061C0002066C02AF45A2286BD814FCF1FB20B8FA2
+:1061D00083E50F7FD4461F32747A05B9DF3058FE4D
+:1061E000F8B4F35974ED2B578D165D3542E9B0A51F
+:1061F00078514AFF233D5DF711E89F5142C289144F
+:10620000EF8D12042E07A643DFE095D2474A92F79E
+:106210005E07BDA4FC192BF6F6830F29D7890F6BF7
+:106220005C6FBD64BC4B5522917511C653613CCA6D
+:10623000A75B820F9B84CAC339E06D8A0F293EA5F4
+:1062400013DAA498201FD29F4E81B6BDC170622B75
+:10625000F24102E962C1E73144077EE55C9FA34D4C
+:106260005698821D7E6FBD8A70A8E823D071743A5B
+:10627000204585EC279DC0B716BF021B5CBC14DA15
+:106280005F77F041AB3195A4A283C5AF8056C6AF0E
+:106290005F1F9C7E71CFB7C409EFA0DFF3CBC64967
+:1062A0009B1D4AFF9E4C4E5AF4A148AC82016C7C67
+:1062B000B059210784C98434152E23517A77333C91
+:1062C000A276AC05AE05E01F4E45BD40DA0419E0EC
+:1062D000B4EC2A09E660BFE98281E3895A2DEA1508
+:1062E000C91F66F6953F4F0F179B7FB8110FEB1430
+:1062F000BFF9241E16297DA8AE0C7512D09B610231
+:106300007C40428C2F24EEA75BEFC7383F7BC951FE
+:106310007C9F6A5753477BE694E3B9127D48C7D9FF
+:106320005242121EA4535C83B65C2213D81750FD50
+:10633000E42FA0FDB32CF697168400FE2C6E5FC9E7
+:106340002CCEDF02D56714CFFE694EF9F6B9E45FB3
+:10635000E6F6B88F3E4BB39FB0AE6EFFED3181FBDA
+:106360006F19C48FF4E6EF137F6A7FD5F2DB2CBC84
+:10637000E68904F1497EAA249E28E26BA3ED7BDE28
+:10638000CA4EC0BACD8AC89A668A07F36D21D40472
+:10639000F494C33D59F4F9C92725DC2FE52DABBF93
+:1063A00004E6DBDE608E2DB6F983DBE55A0DF04D99
+:1063B000F942B3DB8B1B48F405C1B6FFF2045BC6A0
+:1063C000160F43FE7BBBBB044C8580FCE7F5C78200
+:1063D000AF825CF2FB49FCD8DB52DF766E3EE1F621
+:1063E000F286F2309DB71574D7087C6C0A149ED6DD
+:1063F00002D6FE49E3F072B09FAD99ACFD51E33B8C
+:10640000E146E48BA816A1F7EA09C74B17C50BD2E2
+:10641000DFC8B7DB57F7D5BDFE1DB2EE033EDBEBA1
+:10642000CFB9AE04EC67991802B4EF8D1DD1D7D85F
+:10643000F0F14D4FC51B808F91242110A05F2C17C8
+:10644000E5C7F2E780F1A05DC0E5A9901CC67EA378
+:10645000233DE50ADC5AA1BF0CD796E073D9284F3B
+:10646000648E7E12E55F122E5E3E78794FB7DE8035
+:106470004022A9FCF9FBA51C94ABC034BA6E875E20
+:106480002FD4911FF9B85F031A81FEC8A6304D06BC
+:106490003D125F114931DE4F0411FB69600FAEA060
+:1064A00068285C56F66F74BD9A169EF22A85CB93C7
+:1064B000EB0F990836B3130697014FBC5103FC92BA
+:1064C000A31201F9D70AC391DB804F49242CD0FBDA
+:1064D0005A301CDA6AF45D9F4A987DC8A1D78B4C6C
+:1064E000BE09F4BF274FC7FE04EC85B5AE31009757
+:1064F0008A707D06F4CE15A70F4CE711A4BD1C8C45
+:10650000593A7A7FD6744EF7BE9BBE0181C9D7FD3A
+:106510004DE7C32695A796E3822881528C17235D09
+:10652000344E97F34A5403BF71CB5745B28FB61F11
+:10653000ADEFDF4F89819FE2B1D94D9DD16FE45D11
+:10654000FA5460A174EFEDBA4BAC4CA4E0A74A91A9
+:10655000E9FD2D773D1C1F0BF47CC5B9DF53568533
+:10656000D12FA5FBBE4AA087F59EB798D927B29F29
+:10657000AE87F657B83F723E6F511649318F75DDC1
+:10658000E382BF90E23995DCDC2771FF6A271BDFCD
+:10659000F277CE17F43FBE859F0B9522395C8A6453
+:1065A000F59152BE188AF7C2A4DF9D876D0F7F94C4
+:1065B000A8157D04EC5E6167395C15D2D3087CBAFE
+:1065C0004B2455A9E05B2B89085F61986E3DA8DEDE
+:1065D0002F3445D04CE45EC9C0FBF9AB6A0F2A9456
+:1065E0002EADA34808CCCC25301EE8D5835EB49FE1
+:1065F0006A2E4978A99E7EADE82B26D865BD908489
+:106600000116BD16F69CF43F6A5F0DFA5CD9183589
+:1066100011AE6004F708878A9621BD5BA87FE76109
+:106620000B71F0538B297602DFC6E9F8E00FC68DB7
+:106630000A94D773416AF9E1E7630ABFB5DFB8147A
+:10664000E242949400E70419E1A423317AEA0C2F82
+:106650002377CF229DD4EEB466EF427930AF242861
+:10666000AF32396C0A6067E48429527863554C1F55
+:1066700028B971C16EC7F690E88376BE91F54EF4E5
+:10668000FF5AFF2CAD4885D76A91E9B7FBB83E3C6D
+:10669000AFB4CF477FA399CA4751DFFE614E876FE2
+:1066A000C7163D381EF519B34BD6F32EC170C43151
+:1066B000475E50713D6EBF661EF76B5A0AA95F8335
+:1066C000F24E16801F93C1F9A305B0479F7BB249D4
+:1066D000C2A47064803F43FD1252CAFC128DFE03B7
+:1066E000FD97BFC2E9CF785C7E4B3A7FE66B42E410
+:1066F00007A8EFA8AA02F8770BF1F9E300DF057409
+:106700003F69F45D7717DF4FCE95B615B550B81ECB
+:10671000CB151DFC309ACBCB63C43C71913E8F17D7
+:106720008A06C01DAF17711DE70CE6B79377BD0E43
+:106730003BD16C2ED2884DFFECE0F2B4AD4173C872
+:10674000ADFBEA57E3D1480ABDA573FA64CC0A63EE
+:10675000FCC31F4A20FD619DA9FCF4074A2BB4FE2F
+:10676000F49F5CA2AE41FC15569C92E15AE6DE2FE6
+:10677000A51ED77D25763F534ADF6FB0D72D144F26
+:106780006F2B0E7FBC53827D9749D0FFF386A8A95B
+:106790000AC0551F0EF07B4354DCE0DA5D5E09F75A
+:1067A0008D59110DE4C8B2CFDE50642BDCCFFA92C4
+:1067B000BC05E8E52D174589D24F934D9263939B15
+:1067C000A970D3C6DF99545DDAF1A145BF52097EA5
+:1067D0002A2914C9580AC7E68F1B343B9DBAE836EC
+:1067E00084ED5B9D7C13AFEF5FCF7E5ABEF8B96836
+:1067F000C5439CF4C21F7B3C84D33949FF3E718D55
+:10680000FF1CF4D638FD0C4ABF4D06D093E90BBAF5
+:10681000F142FF21AE996168C70D43346D7AEC6394
+:106820003107F1205F90512FED5ED312067AE974A3
+:106830000C202DBD8653D9ED2E4145B9A27AE32A0D
+:10684000693A2A6401E29F73A58D48EFC728BD41CC
+:106850008F3D466ABB2EE6F6CABF1655D18FEF6A4A
+:1068600034CB1B8B87A237297CD4AF237B98FF7254
+:1068700089E5BFFC3DE59341F82BE7A9D1E0F6D8C7
+:106880000B7C25775396A670156E6476137CB51C29
+:10689000DA36A8DDEB147AF9D1C3E7514A1387C77A
+:1068A00023BD9DF6E9B1C297050FD8B76266DF54E4
+:1068B000B3330C7A26504CED1341FBB31AF033A2DC
+:1068C000245E0EED91BBE7E13ABE0D7EA81FEC0BF6
+:1068D000417C7C534C349A9466BE70A4539460FF00
+:1068E0004C707F67D1CF3D2FB57A484F5FB6B81750
+:1068F000E814A83D0CCBB4DBBD6A29AFD71E8E28A7
+:10690000E94475EBF617D2FA097F96F87E6C666358
+:1069100098B647C1AFD49FDC293EDE08FBB188277B
+:106920005C8F7477ED239271281EEF5E5B6609958C
+:10693000B1FC37749E3BBB140A00013F40B2C781D3
+:10694000EE04BB44F5CD5A6ED76E2591003C3C4316
+:10695000448CAF9D21470257D8F870A7A4B2795A4A
+:1069600095B7217E6FC5776F8BB3B6A57FEED8ED57
+:106970006CDF4E160D87F8EDED3B155CFF9DAE7D8F
+:106980006B4CD271DC3B486D0BE0A15921E827AC80
+:10699000D5890CF1D80D3FFCCE0CD8277C9BDB951C
+:1069A0000F287F1936FDB3CE9F50613FFB4EC715B0
+:1069B000CBAE26F07EA26504ECCBB3494A3B7A4BC2
+:1069C000AB13BE81E077C34BC8A67EE190DB849415
+:1069D000F1C3A724C11137ACD70293206872DECB74
+:1069E000AE6605D31FE66FBD8926F0132583F7AF8A
+:1069F0009DCCF21CB533E13AD07B3FE3FEE850DF9B
+:106A00003B9CE6BD0D5AB70AFC5F239B9582D81BC1
+:106A1000AFD294DAF04890E303E59D2389A35FEBBE
+:106A200020FB558AFDF473C37B4AD74C71725FB863
+:106A30006F20D1B740EECE8BD16A8C1370B83D80F9
+:106A40006709AE32D213E3274530AFBF55C882384D
+:106A50004A07FA275E4376D0BBC6D203542F41DCE7
+:106A600027A3C4F9DC1D57E949D2B513E50B43A2AE
+:106A7000744901CDDF2981BF58269F4EF6A7F355F3
+:106A8000C3BA266327D42F755CBF5413E3C159D30F
+:106A900050BE305E57377F8C0970D4E51921D30082
+:106AA000351A0AE3182EBEAAB92090846DFF5D2323
+:106AB000F7A8204735547FDBEFDF1364F1E4747AE5
+:106AC0005B219AE12F01BF56443C493A6DDBD6FD6C
+:106AD000515CA86C67FBAAAC25FDEC8BEF09B27882
+:106AE000F1DA2D63B358DCC5A9AFCE72FBF0936722
+:106AF0001E57BB41CF3C7DE27A58E7FAFF29118D42
+:106B0000CE7BF6994CD2897623A182DD58D721A578
+:106B1000B4878434B1FCF9F732915EEB9EF324160E
+:106B2000D0F7D7BDF0CE2442E13BBBA9E7B591E059
+:106B30004F3F2DB0B8B8D93D6931BDBF4E26AB53DC
+:106B4000C55926C86C1F72FA47192B407E85B6833B
+:106B500037E3B8EDCB15B0AB563F4356905F693F76
+:106B6000B4DBE6534262AC900A3E968F38FD94C087
+:106B7000E03BA0E0FE6F5DDB5E354AE1A869FB10FB
+:106B8000F5C5ECEF3D1B003CD41C901C7E5C4D9B7E
+:106B9000D4E99984D713708538AB3003F884F34B6C
+:106BA000C7068CAF56B73FF0A11480F79D7A8BE2F1
+:106BB00025D409787D530A2D80F60FFE316050549C
+:106BC0007D70F88900E0958EBB46CD8238BE93BFBC
+:106BD00061FC0B397DC7A39C8EF9DE9AF62D6C3EC5
+:106BE000975EFC007E29E81B878DC8CE3C3A691B66
+:106BF0005C9E77FDB3E71E35E97CA79FFBFDA326CE
+:106C000085FBAEBFFCFBA35F07B9FC67AF0E7ABD87
+:106C1000E6E95F06888D0FD7C92C7E707614DD42B9
+:106C2000D17E677FE549804370F6A5F7461B74BDAA
+:106C300067BFFFA7E106ED5FF7D2DC7C587FDDF38D
+:106C4000B3F3FBF363804F131E3B5C091CDF38205A
+:106C50003067E1457E75D1E550C7A1D100E7996362
+:106C60001EDC9FD5D07BF553814E1BD0CE427B23BB
+:106C7000C56FF5339B3F04FDD017CFE64811835F06
+:106C8000540D0681CEEFCC437A911EB48FEEFE35C3
+:106C900047291D27A7A7DB39F2B10A7AAEE6992D5D
+:106CA0006C3E17DDCEC02F57F6A5DB6617DDCE9103
+:106CB000BB1E2B80C46BC730471EC1BAF6C6CF239C
+:106CC00059917EF48325FF03E115F32C14AEA572D0
+:106CD000F81B32C8D1731949BA2E00BA3E7B6E3404
+:106CE000A17CF1BED27333D8839E973CFA3E7A7F63
+:106CF000DD4B6FA25C9D7DFE75D5403B46FC02F5E9
+:106D00002BCF92E4CF61F033AB99CF496AF6677627
+:106D10007A02BDF4A94E2CAC340278FF04DE4F3069
+:106D20007EAF4E1C5C22A4A0D7EBF218A6FF13790D
+:106D300088970DFB7FA312BF938E4219D0F1C43CFC
+:106D4000B89F8E8ED6FA7558FF4C1B3DF7333975B8
+:106D5000F7AFA6F208F62E49D784F02649219767A7
+:106D6000F77A64B07767C1AF4A993765FECC50F3C4
+:106D70002B3F939DF557C9FC0AC7437AFE60F23D4D
+:106D8000D0FA868ABF1FC9068EEBC6E3E98F53EBA4
+:106D9000FBF7B8BEA82666E5884BFBFA2132899836
+:106DA000238B7AE13D0D1B54CA7FA79F96301ED4DA
+:106DB000D27E08F5B65B4F54A7896F5E90999F50BD
+:106DC0007DE0E024D067A75FFE11F267F53327541A
+:106DD0008817BFD6F603B5BBB4571EC01E246CF689
+:106DE000E0F4770F4E627A808E9F824E8AC2C6AFE1
+:106DF00079D1397ECD331F3AC65F6FB6A37F30D0CD
+:106E00003C1FC8E1E5B0DE0F0E2B04F4E807ED529D
+:106E1000652ABFF6036E0F2D3CB5BC3EEF379007D9
+:106E20009B76C46780DDECD814CEDF0EFEDA1185C8
+:106E300080DE2672F8F71EDAEE78DD67407EBAE370
+:106E4000C832C9B0ED437FE8C2E7CCA3E6EC4C3AC8
+:106E5000DECCEEC8347051DD7AA3EC38DD57D9F8BA
+:106E6000A0EEF5CA7CD0F7B00F35C6C37CA120ECEC
+:106E700073A5C0BC4A96BF16756F4A7BCDC653FC3E
+:106E8000118C5729BA988C91C1B82349A211E2AB51
+:106E9000C4EF77E727229A3D0FB5E2F041D862E6CA
+:106EA0002E7EB100C60990987E12FD4F12BAD88F7F
+:106EB000FFE5CE4758F84CCA5F9AFC44867E73F0D3
+:106EC00020E93B5EDF3C4C5483F8768B7F6D6B9101
+:106ED0002D0FD312EC938799AB503CB40A2465BCB8
+:106EE00076BC52315FC9C3DD7134D5F39B1426578C
+:106EF000D792EE7BD7009C1196CF99E5C2D79738F1
+:106F0000BEFE79325D3855A1E5E05951FCCE5E12E6
+:106F10008E29F4FEDC553D97BF8CDD793EC71C2FD2
+:106F20005ECC183CFE869AB78B7816DDAE0C226FCD
+:106F3000972E7FDC0B87C9F7E3398E3CC6A1B7EEED
+:106F4000D7BA31CF50DB5A648BFB0DEFF49230E6A9
+:106F5000F10CF40F8777DEF9CDDB20EE9C5B18F2A5
+:106F600092BEE3C817AEC6B89195CF970BC39D10DC
+:106F7000EF9775A35CC279968721BFB0D960F9827B
+:106F8000CDC1FEE37A339468B382F1A86B705C5193
+:106F9000E3F507835CE737160710CF018A67907720
+:106FA000DCFFC0FA8E0B3C6FDE6D4A903F3C918D4A
+:106FB000F982804C4A201E705EF08536613EC19990
+:106FC000374FC7BFDB6513F3E6AD469FBCF97714B7
+:106FD0005BBE414B9337D7FC4B306FAE119BBF5B11
+:106FE000D4DBAF57EE5C7973180BE332DB67435C9D
+:106FF000A6399B38F2E6CD20F85711F29C72F56C59
+:10700000AC3BF3F2E7E6ACD9617B9B1C7F19DB3C20
+:10701000FEF4C7E6739BA07FEE48528B756A7284BC
+:107020002CB5E9C1F71416A7DDA0847FA8D8EB8E94
+:10703000383F58F99F436FBD877C05D73114AFCDDA
+:1070400094AF3CC857A7885DAF5A578B7F9A8DFE87
+:10705000F942BD3005E366C976D044BE0804A3E119
+:10706000708AF7267998DC5BF306CAA81EA5F2A6FB
+:107070001811CC47A93ADDF01A83873F1D5C169F93
+:10708000361B63581D944EB07E2FFD3AA6B13826AC
+:1070900044B8285CBB6EBC3DD49F9F63AD73861221
+:1070A0003E69C77BEE25A9EB77AB55B6EEE6C82A5D
+:1070B000965FAF72E653217D6D8FB34E17A2FFAE80
+:1070C000609C90E553452DC2F323A6151F0F26E3C0
+:1070D000E106D419DE65823E5456B59B025C7359B5
+:1070E0003E25578B7EACD8EC83AC7733B975E5077A
+:1070F000E74AA787845FAB2E6E6B838E7EFA9686F7
+:1071000020B6373718786D6908E37D371D9B8D975A
+:1071100083B7605D9A0FE3B2E9C67FB02184E3C410
+:107120001ACAD8783C6F4E486613F0952A5AF23244
+:107130000CDB7E893F370B9A40FEB60BECF9352D00
+:1071400097A2BC59FCB3C3E83F2E2D2566201F0C27
+:1071500075FCBEFCFA135C67F32C3FEAD781E42888
+:10716000AB93CD3BD87994A4BD60F3EC98A5E13CFA
+:107170003B72079827CEE619187E86AF6D074F61E0
+:107180001D8242F9015494A28753D7E97179EB3BF0
+:107190008E07F57C7390D585A9C5FE3028FF6683E0
+:1071A000E71B0B59BE512D195E01F7D5D065582745
+:1071B000AE96FA319FA7160FBF05DADB0E6ED12B04
+:1071C000C07E148A21AF0176BB9BC8B9283618BF90
+:1071D000558B4B6E83FE3AC83185639487EDB7D4E7
+:1071E000E2ABEE80F70F4E79CD68A2FD9B0B7D21BF
+:1071F0000FC85BB7ECE0FF41EB8942671E8DC854B6
+:107200005F50FDB56DCAED25289F9AAD4E3245BD44
+:10721000A04D6F6C506D7A4325734CC0433ABD430B
+:10722000EDEF7D6A5EDF71ACF73728917A15F54294
+:107230008438EBDD53E7B32D7A809B05F948399804
+:10724000ACD35B5030BC37BF6DD5E9B9F3DA71FA16
+:107250002F555EDB5D7FFE59D5E9ED5493757AA31A
+:10726000A04EEFC70A0975425EFE9752689FD197FC
+:10727000EFDCE3B9CF5B50FF47837D4E3AB9FC9911
+:10728000EACC9F16445D74BFD5EB98EF159097D26A
+:1072900081F5CBC82AE738A36A9D75B597D4E7383E
+:1072A000DA45E60847FF4B5BC7389E8F8D5FE6786F
+:1072B0003E7EF754477B42E22A47FFCBDB2A1CED98
+:1072C00089EDD739FA4F3EB0C8D19ED2B9D2D1FF9D
+:1072D0008AAEB58EE7D30FAF733C9F79EC1E47FBA8
+:1072E000CAEEAF39FAD753774805B9CDE575C8B9B5
+:1072F000F9A23D4FDB9A47ED12DDE7EFC8A30C83FF
+:10730000F16F56D7A5B2C7C9BCA1FB3DD950C33A4E
+:10731000E6FDC7CD812B91EBD09ECAC6F00A03EFE4
+:10732000CF98075732CD595FAB1AAC3E19F671CEE4
+:107330007A01679DB12A6DC33C9DE7F897BB8449EC
+:107340007DE9AA163AE560B075CA8AE17A6F88725B
+:1073500071DE928B51542E30FEF6B184E75AE6640A
+:10736000A27F61DB4F211EADFDD4351A89818B6967
+:10737000C945F9AA9E91AF62376B1FE51187521775
+:1073800067C95FC0A6F761BF62E999E6B2C1E95774
+:10739000297185C39F745F9B02EBD2E9C7028FCD31
+:1073A000BF77EBC7194AA4109E6B72D824B6780D2C
+:1073B000A9551C700F16CE4F6A07EEA20C4752E873
+:1073C0007195D462DD55CB8A300601481D71F0E914
+:1073D000CEC5FFA30CC6A57EE10CE73A995FE8F69F
+:1073E000A7A97E437F7A07F5A7D1DEB9F423D55349
+:1073F00026AFFF32981FC1F4A17B9D9F971FFD6FA1
+:10740000E0ACF643AF4051A812F787792281FD61C5
+:10741000F3AC4810E27356DDBCF55EABE7521C27B7
+:1074200096AB8A10BF8C75CDC5787D9316D5589EC6
+:10743000388AE334658B7AAA3AB13A0FCB176BF5E9
+:107440000F8CDDDF4FDC45534934553C6DA787E594
+:107450008362FADA2EB0A39979AA017BEED683A7CC
+:1074600022104792CB641DF6EB8402F38E2DBF47AA
+:107470004814E34C5A5044BBABD5EFC0F90782F730
+:10748000668FC0CF7D6CE9175EAF9A3AEE920EDE42
+:107490002D00EFB481E1F502BC4530FF369CBFC63C
+:1074A00063A4C4BF42C295B3816E27BE1CC1742BB6
+:1074B000651B908F1D656C5F4E0D8183BFAD7D0E8A
+:1074C000E5EF873D7958BF8A7C6D9D73B8D1A3E302
+:1074D0003C165D49610EC63502D1D8D862CA6F9993
+:1074E00051B69FEFD54F8C8F329530817896EC173F
+:1074F000313FA8F27888D5EF0F1C9F4DB3BA915E4B
+:107500009BAF94C926A1B7CE3A5648D735B9775D17
+:10751000FFC793CDF893CFEB234BB2B02E457A261D
+:10752000D89FDEF6717CB9F5F7F73C5C7F179002C7
+:10753000A6BF4B9743BE3BDD386E3FA69EC77987FB
+:107540005E5FCFCF17F8EFE982389315E723C16963
+:1075500029E3F2BD7865F9CA5EFA2E373A29FDE4CF
+:10756000E953314F6E9D57A0EACC592FCCE96BD12E
+:10757000D58AA393208B1F5974F626F1B9A75F7C97
+:107580007A415EAEE88BCF5F7978BEE1BF183E5F8F
+:10759000019F865E3333D9F97472E8AB04F35285E8
+:1075A0004E39B4DEB3F8DDBDFE3FFD17E5276BFDB8
+:1075B000163FA4EF6FA6DCD758F9D54CCE6F1A9CB6
+:1075C000B2A28AE7D5B2B75B2F85FD6BD08FFBBE29
+:1075D000CCB2189EEF5588A9835EC8B4F635FCBCC2
+:1075E0009155AFE42B75FA659A6BFFA2F2BAA83EEB
+:1075F000E76DB9FFE63E4795C4AF8B5E93B534F9AE
+:10760000B1419E3FDAC5F3750575F146D80F17DC19
+:10761000CAEAFDF7286435D4578EA832455F2EE4B8
+:107620006F8ABE9F41D75FF0E2438D238124B71A52
+:1076300045E0663CA3190E3B5C7057BCDCC79E4F0F
+:1076400081719ED298DE2DA88CE339E7A6E7C76743
+:10765000819FF0CA5BCB75880F7C945B8CFBA73352
+:107660002F78C2A0FFCFE4902AAC0B7B61E66BE0E1
+:10767000C7FFBEA12B47B6F1C999EFBE3E43A14457
+:107680003AF3DCEB33642456C231FF868BBF98019A
+:10769000709B15A4A416F277BA4A60DC1A8DE5CB6C
+:1076A000AC7A9F5DC3D516B8FED49BCDE289F9E2D2
+:1076B0000E68D743400CFC061ECFBFFAB4B11CEADB
+:1076C0002FB3BB1401EAF11E124CD34FAFE74F3C6E
+:1076D00024809FA576D6429885DE0F1D02949B6379
+:1076E000D9BEE47C112929A27ADF77B8763CFAD397
+:1076F000AE7A278BFFE5D904F37D3D376A09B0D711
+:10770000DB65E31BABC07EAF92B11E67BB7C18E5A7
+:10771000C24DC7E3DE31CEFA5C1E8F3EF4D61DF1BA
+:1077200072FAFE3D5344E457FF8929592485FC6EC3
+:107730006F28C3F903056F579603581FD3BB337ADD
+:10774000F7497E999859D4442A45A2A950BCF8CB50
+:107750000879DBC6772D2209EBF4F90B0D04C7E994
+:1077600068D0F0DAD6A08F2DA61B836F3504F1BA4E
+:10777000B3C1C0EBC30D25F8FCC1869043EE61BEDA
+:10778000B74B783B85BFF2795D1F68A0F3DAE0D88C
+:1077900035914A3DA5D72E9E8F7AA0746AD6DA7E9F
+:1077A000E2607B1ABA86CD19CB9105F5A675FADE93
+:1077B000ADFDC0BFA75158BD08FC9ABBE5C83ED47B
+:1077C0008FD1824536FD48FDB6024259F1DE961151
+:1077D00073E614A03CA2BC4C3B1C457FBC20181790
+:1077E000208E587094DDB7CE5B20BDA8A0FD307709
+:1077F0008EA080DE2C25ED00965A1A2515B4FFCCFC
+:10780000BC25E5709F4C74DE9FA132F986712BE890
+:1078100075B616F991361DBED3B1DB7C96AEE78FF7
+:107820001D1E03F23C0FBEFC2715F605B15FA91A19
+:10783000F831052F9EC0BA8798D0AD4265EC71AD86
+:107840007A8E4CF50C6E0631BE4A150BE59318E89E
+:10785000588C7FF6C4E6F8E1BC4BF494BDFF2E5F74
+:10786000F46E7E7224AC05291F25F317EB6361BA11
+:10787000E97C81E72F8E6BEB626621B469FF29AC4E
+:107880001DA3EFBF901D1D296643D14555ACEB4BA1
+:10789000D0B6FA57C5A0DEF64DAE77883F5A04F24F
+:1078A000966CEBB49D696BCBAC4D3476B5D6BBE131
+:1078B000D09F5E033D57FDA2D00EA051BDC7F07F03
+:1078C000E021ACBB6D6BE8D2630AA7BF45072A92E3
+:1078D000138204EBE9D484901843F5C704FE7D8A33
+:1078E000826961A311F46B420981DE0CF998DF38DB
+:1078F0002141C7B1C9D58434DF41C1BC2FD0711B30
+:10790000AB1B76F3D7B35E961FA827E656C88391C4
+:1079100067141DF3913C4E79DAB2737CBF7A979766
+:1079200035954DA6EF32D03F6B648C83AD2F8A978F
+:10793000AB749EF53F2A0A51CB0A7925AC6B589F50
+:10794000DD3E7C2ACB4B39DA0FF13ADA60B6990D7D
+:10795000E707AA0F3C341AEA02AA49FCE6AF01BCC9
+:10796000FFCAF28FA70E5E9975356D6FA06D88BF47
+:107970006EE8785D8DD27EC338DCD51D53AE83F5BD
+:10798000556F138958C4E4333C9EE2391CBF4CA6A2
+:107990007C72CDD69173BD94CE4F8D09EB22E583D9
+:1079A00095BE71CD1AB4557D02C8CD4ADFC466E0DC
+:1079B000ABF513F9F71AC8C457C332AF97A27C319D
+:1079C0006C4B430CEA13F6AFACBC0ECCEC7091C917
+:1079D0002D6544CC1F4AD931CC5BFCA1999D7781A0
+:1079E00094FE464A87629974C9F4BA4B65F4335BD6
+:1079F000648C17D3FBADCA54A04B3C8CE72B5A992F
+:107A0000DE1FFBA207E3CEC5B5E13BD12FD04B7102
+:107A10009F329A247F302F7D09FC46C719AF93729D
+:107A20003887F0632F8B1716AF58B61EDE93329748
+:107A3000F8705F2EB17350E4DB2C4EBD4B4CB46B31
+:107A400020E78162A4EFAE00E30BF3E152E48BFD8B
+:107A500062C56577435C5258B3F55F80AED9C50403
+:107A6000E80AF7EFA1F7F7737A4AD9211DE8B79F23
+:107A7000D33396104DA88FB1EEBF20ACBD13E46D8B
+:107A80009DF7F9391AC5EB704F383E8CD2E14EEFB5
+:107A9000F3B16001D2618C46F17EE7968E98368A0A
+:107AA0008ED3181EA1DBDAE3FF4CBD11CC4F76A0BC
+:107AB0003CCBD90FAF0379A7CF5FD1E83A9FCAE19A
+:107AC000FA823F2F1E93D41F61426D8DD4D8AB4FE5
+:107AD000346A1F8A6DFDE7507DF0E4A3AC8EFD7A19
+:107AE0003A1FC83B5D07E67F7B26C809A8CFF25145
+:107AF00058C06FF14D1C83F57974DD04FC929E89AA
+:107B000032DA592B8EED9920627C09FA033FF84650
+:107B1000B1FE545022A037E54219F7ABB2B4273C6E
+:107B2000C180F031CBEB0AFA423CB7EA2DB1E571E6
+:107B3000496F1D30B68BF033378EF6584F7781483A
+:107B4000FDCADCE30B85D174BC3BBCDCDFCEA5FEFB
+:107B500036BDBFDECBF4D2FD11F3CB10E220467769
+:107B600001EA2712990AD7FC9B8AF3A3FDD8A5BE88
+:107B70007E7537FA0F3BFCA9CF694EF7B1FD7C93B8
+:107B8000FF880EFC564FA8FC835CE88CDF2CFD615F
+:107B90009D4F70D7135BFA44C9666BAC9B5F910F26
+:107BA0007A40E6F549B21ED2A1BEB23C731AFA7D04
+:107BB0004F7A99DE930E5E79039CD350FF95E5854D
+:107BC000F678A3184FEA2920EDC0AF72304CECF9DB
+:107BD0005F4B1FB43468787D62EAB80A909327A699
+:107BE0000EAFD0A90C1C9AF4E32EC8339DDBC3E47E
+:107BF000F7DCE1DBF0FCE33993C59B80AD302ED997
+:107C0000F9089ED77D5C8E3C8875B5501F4141DADE
+:107C100096EDACDF2AE67831B97E6A56D8F3CD0D01
+:107C20002C7EAC5EB81CE35A2AD7E39EE8AD786E92
+:107C3000C3436D199CAFD48869B2EF1D303C688591
+:107C4000CEEF61A81726E1FBA697C58FAC7A117716
+:107C50005D8805CF0C0E4FDF73194E7A58FB2F8BC2
+:107C60000ED6FB7542385FEF876F6A2E4824618B12
+:107C70007FF4D677AB78FF2CD4C567411D4F347E97
+:107C80007511C84102F7475E7F1D21FCFB4AC8A75A
+:107C900041B9C75E879EE1AA8BEF232F86B3EDAE75
+:107CA0008B580FCCC1EBF8B09E5526DF1428BDCF02
+:107CB00064FC7606F8B535543D681020924D1DE6FB
+:107CC0003FCBFD7DF9C5BBC3230D1B9F0B86639F77
+:107CD000507D6021C6116AF6FBB1DEBF1AF4DF6485
+:107CE00038376076791CE705C29D509FA71C60E37A
+:107CF0003D09F0D0FB7FD4AB0A60DDC761FF93077D
+:107D0000F6242AB1432F87110F316FF818D1993E0D
+:107D100093294FC4B22D7D561D830DC32E9538FC7B
+:107D2000A55D3EDEF655C762A5BDF51FC7B5FF8749
+:107D3000FACDAAEF38AEFD07FA43BBD47827E83B6B
+:107D4000F3058F01F68BBE8FE777CD952568076227
+:107D5000456404E0E1956C15F55CEC79CF3ED07399
+:107D6000B3B5E89B9A6DDF7026FB8DD1B0FF4A3129
+:107D70009EE9186FD4D0C6A3F377005EADE7AF6479
+:107D8000EFC2738BF43D03F386858747AFA1EDE126
+:107D90002F78F0DC90B5DF74F3653E97AF16D77996
+:107DA0004015E4CD0FFAB616E5CC1374E6C12CB934
+:107DB000532F4C70E4039E043B4BE9A7CA51085172
+:107DC000D2E7A5F8DCE47CD6C2EB11D2CF93936660
+:107DD0009E2B509ED3CF3383CB3BE1722CEBC9EF6C
+:107DE000C2F4736ED09D2771EB29EB6AE9A96F711C
+:107DF000FE9449F40A1F9D675DA27D9E0FDF8E4EA3
+:107E0000023FF8038D9D832A697BE86530CFDFF45C
+:107E100084EFF74EC7735FFFE4CD1BBA3CACF4119F
+:107E20005E97D9470F31FFEA56E6AFD6CD9F8AFE5F
+:107E30005DDDF631BAFD9CA2FB5A7521C3A1878690
+:107E4000790DFEBD3D13F551D585003EFFECE6F3FF
+:107E50003ACEAFF49DCF8FCFADF9EE72E9D943930F
+:107E60007EBA0BCEB9D77D5F113DB679EABECFEBB6
+:107E7000FFBD54EF3AE53D0CF22E1791647D17E8F3
+:107E8000876DAAD50E37CF99057EAD4D3F9481FF02
+:107E9000D5FB3E7CE76E9B8FF7372B53F7CF70F502
+:107EA0001F638DBF10FBBBE149EA1FD88FD1FEF2E3
+:107EB0009F3D167CA8BF1E125DE3E558F3DF88E303
+:107EC000597EF7456DEDABA60C7C1A2F87FD53CF7D
+:107ED0006DC480EF4F3C2E877C213BDF6A8C5FAB0B
+:107EE0002E5CEAA0772FDEC739EEBFD71074D4EB33
+:107EF000DE11ADC33AED8B3CFE54453D737C6FCF34
+:107F000048479DEEDFE0F8A4705C9D068E6BBE6076
+:107F1000388A1CF2D90B47B1E3FE278563A1C6F46A
+:107F2000D7727E9DABB373B3730D21D4446FCDA5CF
+:107F3000F7BD94D7BF4CAF1ABDCE9589E9C7EFA264
+:107F400026587FDA86FDFD0D7FBEF7DD6B315115BA
+:107F500074D41548BCCEDBAD77E09C37AB77D31C2F
+:107F6000DF87B3AE3E89D56BBAEF7FE86378F9C699
+:107F7000E5D504FC69EAABA73CB7B6CB2FF0EF7DA3
+:107F80000645479C9BB7AD3ADFCF0A2E3983CDF724
+:107F90008DCBAF2710D79573537FDFEEA09FC1DF46
+:107FA000A285B14E3CA6F7FF5D9A4F0ACFF0243C64
+:107FB000D7209EA43478AAB5E0D1595EB025F8F94F
+:107FC000C0539261D1AD7FFC6CE570930B97201F7D
+:107FD000499C4E2DB07F4BD1DFCA7FB4689F2FFCE8
+:107FE000E141D2F7B98C2F86BE8B0649DF622E079E
+:107FF0002DFAE70BCFAD8384E73A8BDF8261A4D7FC
+:10800000E705CF570609CF318B5EC6E78B9FD62495
+:10801000FFF70FCF5F38DCF9192C0ED252C2CE9386
+:10802000F8A4C88345C2C072E12B76EEB3B5429F77
+:10803000B3CEE65D67DD57BA75FE9AAF339D3CADB2
+:1080400054127940BF630D2C1EF006DF9FFCBAAAC4
+:108050002913E3F3AE795A82FB32FB8BDBFCF72A60
+:10806000E7B9DC81E4785206CBFFDC1875BEB77C3B
+:108070004586AB8ECCC47E16FED28DF7D782B73044
+:1080800024310781378AAFACA27EF60D9F35BED270
+:10809000C9DD50F115D38786AF81E4FD2B43C4972A
+:1080A00025AF7FADF8CA077C4DFF1B7F0D165F8B98
+:1080B000FE268F43C2D7AD439547EED7FEB5E26BA0
+:1080C000B0F2E8DEB7D1FD5DA8BFEF0B7CD6F87348
+:1080D000CFFF69F1688DB732CD3E2F1D3E0782C3B9
+:1080E000BA7EE81B245EDDFBCF2F1AAFAEF93F3519
+:1080F0005EF97843C6EB007058577990F26DF975C8
+:108100006D6AEAEF888ECB64DF711B2FD41E990F46
+:10811000F9E3BF93303F7D64CF9C0DF67AA071994F
+:10812000CCDF3E52397B03C44FCF4532B0F6ECA8CA
+:1081300018FAF934C82B2F62EFB9C73FC2F1E5C96D
+:10814000CCB6E2BF7940D7A391C5FDCA23A9B4AD8F
+:108150000BF34636FA4A7DF17D8418DBA7411E6297
+:10816000416A382C3AA79B77A8F43D1A797C48FAE3
+:1081700067A0F5FE877FCC20F54F02FBE592E4DF98
+:10818000DDB90CF0D926B27AB8E370AB00BEEB468D
+:10819000B0D3F215F97B814E7767B2FC61876A6CC8
+:1081A00080FC8967F182073229DD8E2ECD16ECE73F
+:1081B0002FE764B2FDD78C55A9F75D0B391FF4BECC
+:1081C0002F90F129F83BCCFB2D5DC5BE3F46E4F076
+:1081D000A845B673A7EB5DCFFBD0233380701C4D51
+:1081E00073EE7F017F7FF992FEDF27B5ECFB3E94B3
+:1081F000EF46D9CFBD26F98CCBC7197F746926BD50
+:10820000BE2144BF731FF0D1043F3B37249322A803
+:10821000BFB2C6C99549A74AF1FEAE628C82BC6660
+:108220008A716ECE9C9E7E9C7478B5D663CD03A277
+:1082300008DFE999ABB138E2B43021B3207EE80918
+:10824000DDCDF2878C0F72781DE2CCDA8C4423EC02
+:108250007B65BA4E1BBC1DFF77F67F83E71D474445
+:108260001DCFB7BBF030907E68CA64F9E45C29BAD0
+:10827000C90B7993D542CAEFD86DCC647FEF6852B1
+:1082800066B25E0AE719B733AAC0F72F96C92CFF6A
+:10829000454874D442DBFC9338BFB9DFCB9558BD59
+:1082A000117993C973DBBE75A352C9CF2FB89C4E09
+:1082B000CA2C71D4392E89DCAD807C2E59B0503156
+:1082C000FCF0DCC0F1977238DAD4E8A829FE5E3CF5
+:1082D000A5D5431C3F1DC7A24DF0DD8FD5F502D6B5
+:1082E00009946E647CB77AE3417103BDEEE5F2B7A1
+:1082F0001068601BEFBB9CAE6DFB7CA301FEB664F7
+:10830000FE860E4CE1B87937C17CC893DB4FB7408D
+:108310003EA45B203C7F726325D43574F3FAB69794
+:10832000E9F346C0DF9C3C94EF711B3FAC03FDDCDE
+:10833000A1123C2FF3BB2D9E049C27B0F825A92742
+:10834000369E6F80FAE147D4CE89C037794DB5F7B4
+:10835000A5CA9FBEC4E9F0477F242B951F685D2DF9
+:108360007D6EF55B241B4AAAFE8B2B5D768DC33D8B
+:10837000CCD37986A4C86326F930D1BF9FF64BAE23
+:10838000C77FE1CAF32E39963ACEF82BCEBF6D895E
+:108390008AF568B74C0F9E43B1E0B1F0956B323C63
+:1083A0002D5B2239F4EDEA05192EBF87E1F5068F22
+:1083B000F128ACE3917D3F9D88E7A85CF6C1274595
+:1083C00055787E07E954404FBC2F19787DA3C1F939
+:1083D000775EDE20D1EDD3C17ED64B29E5EA8F9CB6
+:1083E0007FDE5871CB52843F26E900FF8955C3AE2A
+:1083F0002F03FDB24209C177D34FC4EECDBCCDB639
+:10840000FEA45FE382EBD755B7F46BB796AF70D29B
+:10841000AD4D657E81791D93C33B298FCE42FEEA27
+:10842000DE3E93CE7F249133652BEB4EE0EF4C2D57
+:10843000E6BFBF2F4677CCA4FAE694C8F224E657ED
+:1084400098DE58B233D20CA9D353F557BCD44DFBA8
+:1084500079038CEF7E5BDFBF7D74F3D3B89D4E7FD5
+:108460006FC631A2C2FBD1BAD4F6E0DB7A06FF7B3D
+:1084700062A1D1A05F6EDA98BADFFF0266A6F09C17
+:10848000FA8B54952A3E7995CEE05D1D49FDFE5547
+:108490007A267B0E7629059ECF0532B89ED3478378
+:1084A0009E5E9D06DE0F030184F79DE6FB6F823A18
+:1084B00090F75DDF817F27C0F8E26080F1F7A97D4A
+:1084C0002B953CA0538BA0033FBC9D1D9A00FCB68E
+:1084D000267602CFBB1CE0787ED3179912980EF255
+:1084E000B2686E1EA54BC72A12128CF4FAFFCA009E
+:1084F000F31B7279BC96DABF77C1FED157DF45FF17
+:10850000430E8FBE71222B81823AF053A2B90EEB3B
+:108510000CF7F9585D29094DB7FBF15FE6709CDA5D
+:108520003F347A2F8DB8FCA03EFE5FBC1AE7DD9F7A
+:10853000A1435DCA914AA9F35A0AE4C9FD19F87D1D
+:108540005CB75CA49B7FA87EE0A9FD43F303075AB8
+:10855000F78640D1A0FCC073958FEC980672A4C634
+:1085600027A5D2BF969E3ECAE3EF6EFEB1AE5FE591
+:108570007CF47EA27FB8EED8ED84E7A65A273C961D
+:10858000BCBC9F68F2AD013C91CE8976BF94CC997A
+:108590003E809D65F9A974706E77E909E03CA0C33F
+:1085A0009D5CDFFCB6FE91809D0EEEF59F12F9FEFC
+:1085B000E05156973B36B2A622CFE8E5CF6F7D4E0D
+:1085C0007C69D919F738FFD9F9D0B27303F1616E1C
+:1085D0009A3CCE2438E84CDF5F23EB2AE4EB2705F6
+:1085E0000CD626FA3C38AA45CA78DD283146C3F9AC
+:1085F000AF53FB7CF8F7A1CCAD9EC4582A02EFEF35
+:10860000BB7A827D3DBFE27CBA7A49367E7EE27DCE
+:1086100031343F1FEBCE24FC8EDB1BC772E641FBDF
+:1086200091C32268687253DD1A09D6F74680ED3B84
+:10863000576F7C1DFDC1A1F2F9EA5AA7FDBF8AAFB1
+:1086400023E967C93DD3807FD2E1E1358E87A591CB
+:108650008573413FDFB251407DFB1318872EE4162E
+:10866000398C7A9BC4987D241AC50735212760115F
+:10867000808F7FE0DFAD9223AAFD9CDC6DDBEE9F57
+:108680000BFEA15B5E5664313EAEC86276E14D5F83
+:10869000F40FA0EF2DFDFCB6507B309F76D918D09B
+:1086A000ADEF04A39C5AEBD9C8E1A27EDAB3F8FD82
+:1086B00062BE3ED2E3E237315EFD63C07F85867ED7
+:1086C00081CF43F53ED4453FEEC33A2A4BAE2C7FD3
+:1086D000C7FDFE3239EAF01B33B38A1CFEBBDB0F49
+:1086E000F99BBD48DDFF8AAC2FD65E5C9BF5D9D8DF
+:1086F0008B619CCFDC762329D72DEC3CC889631F86
+:10870000CD4D25D7914F08875B9EDFDFE763DF4DB7
+:10871000BE2613F54EEF7E2A3F01FB65B75CC07E97
+:108720000ABEFBF1C8BE9F4D84BADE13DBEFBF2942
+:10873000153D67E9CC6F22DDF98E78DEDA00C1FAEB
+:108740006F42E77BC236BEF55E525E06885F2E5BE7
+:108750007925EE27DF5879F5E835A57DF7157DFAFF
+:108760000BD17F580AF336F2FDF40E4FD5BE54FB01
+:10877000408ED7BE7162A77FBF746379336CA9370F
+:10878000655CF3A5688AF993FB9A8DA9E3710F7272
+:108790003D95DCD798745F43F1D1BD4A0A944DEB07
+:1087A000DDD7749B9FCFBEE677A4E7E73351FE5336
+:1087B000C3F73D8BBFD4E88E2B297CA7E8FEC70406
+:1087C000F911E97BC02FDF4ABD5F7B9CBFF7BB8DF2
+:1087D00043D457C79CFB9974F2F7BDCF48FEDAD457
+:1087E0009E51A0077EB7F7E3B7EE87F5ECF521BE03
+:1087F000DDE3447489EF2F7CC8B7967DEE5099FE77
+:10880000FFDDDF8DC0BF9BED960F42E2D75F459F36
+:108810001FDF274E81EF2CB6EDCBA84AB5CF59AF5D
+:108820000B3CBEE48CF710EEDF2DE5FCA6EF7BBA27
+:10883000D61E8F7E93EB2B2B0EF0BFB3989D5DB2AF
+:1088400060A10AF19EDB92F126829B15FDB2C2BDAA
+:10885000F0FD8B5FF2F35CE6DACC94E7E37EC3F1E4
+:108860003B501C62C52A679C60C982FEEDCDC9449D
+:10887000EABA2C8B9FD3CD3754FBD296185A5E6C34
+:10888000A0758ED007675F9692DA2F41BC631909F5
+:1088900029705D426A27FE98A2F2E4EEC508CF2F48
+:1088A000ADBF7FFCF1BD13ED7ECCFF0710F667274F
+:1088B00000800000000000001F8B08000000000086
+:1088C000000BDD7D0B7854459670DDBEFD4AD24924
+:1088D0003A9DEEBC091D020818620742001FD02114
+:1088E0004482B2DA810041519A87184948A2E2CA0B
+:1088F000FEBA438720467466C2AA8CBFE3B80D82D5
+:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17
+:10891000B3E846C7415E4322A32BB3CB0CFF39A774
+:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7
+:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8
+:108940005F4D628CFDABB579BCD3C1D859FC9B1E81
+:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC
+:1089600036558563D4FB53AA8931E8E85FE1C14AF3
+:10897000190B2D50C33B94C1F5B2705CACB7785E57
+:108980006A30463FF2B9A04665113BA3BFB3F06F12
+:10899000CD9C245DF922A753F4D39A182C62EC885D
+:1089A0001CF7513EEE91307F2FFBBB488C7B247C23
+:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3
+:1089C000B48AB9619C70A2734701C3FF8CD8264456
+:1089D000DBEF759A08AEEC48A689653076876C1B8C
+:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05
+:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE
+:108A000064C68E6E4BF4133CA6258747C13C2BED04
+:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A
+:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2
+:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF
+:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52
+:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36
+:108A600005A77359243D5A5E52ABF8C34583C77DB1
+:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB
+:108A8000CD1D31D655EEB453FDF981728B07E0B997
+:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6
+:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA
+:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209
+:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7
+:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51
+:108AE000D36D91DF33155E9C807ECA2E605C437D22
+:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2
+:108B000026F83F1800FA89F93D99BE7FC0DA1B7735
+:108B1000137F27F9762018B62FFF09A09DAD9C7D05
+:108B2000C75BF09A25A614D0FA16070E5412BB9D07
+:108B300079B018F1FE6DD5833F2985A91DB5065B77
+:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366
+:108B50001FA13CBD08FB639C6E67C2FF65333646B0
+:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93
+:108B700056CCD853D6C0FA64783FFAEEAFD73094CB
+:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E
+:108B90008EAD9BA05E6A0A97938CF9F203E335725F
+:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B
+:108BB000370E409EE6377786A34D4965ACCBEABDBC
+:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB
+:108BD000C10193A9A580BA35239DCEE343B0826B32
+:108BE0000AEE1F578AF2C7E24F80A954431B36157D
+:108BF000E868862384FD957E38E719C4CF83B536AF
+:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92
+:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1
+:108C20009E5E585FD25AE8270747B8B7AAC2CCD889
+:108C3000D3F89F97323E6180C55C45965F6C9B0977
+:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3
+:108C5000D312C872A6C1D236DFD7661FC658468661
+:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451
+:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED
+:108C80005499015EEE4239FE2B6DFECB613D57DDFE
+:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0
+:108CA000AA8A9130FFCB65F95FEC385F77926C0F41
+:108CB000F39DC298654474FEE62C18DF25CB9F54C3
+:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884
+:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE
+:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837
+:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79
+:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8
+:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD
+:108D20005E643CEAB181F218288FD794B378B96BAE
+:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D
+:108D4000CB03801BE993D483CCBF33865E1997E6AF
+:108D5000A07EF627B290DD15E5B76B8187A7005F8F
+:108D6000323B9FA7EC6790FE48E3729F85AE75216A
+:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1
+:108D8000907658C43C0FF5876AA2F97A5465493544
+:108D9000F49791C8829DF0F4A4332A437B7FA723E4
+:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1
+:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B
+:108DC000925B8B34F02CE2EB003AA07630CC33D3BC
+:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A
+:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C
+:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90
+:108E000002EE15F7CEF919D66BE8B1301BD45BD35F
+:108E1000599EC9CEA1171B4E5FC6C213356573C4D8
+:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2
+:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F
+:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B
+:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906
+:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828
+:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E
+:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205
+:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA
+:108EA000A7F5562BCE6D0583E775BF9C97D0A79984
+:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440
+:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B
+:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D
+:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA
+:108EF000FBACB8CE86387CFB802B85DA651E8CA453
+:108F000078A1DE19617774754C4CB80CF9628E89C2
+:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6
+:108F2000CC8132C85B2FE26140FE46ECF668FD1F43
+:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C
+:108F4000FEC4EE346EBF4D09B29876CBDFB9927590
+:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32
+:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97
+:108F70009C52CE23A7AA859CE2EFF783998FF53206
+:108F80003222E315D089CBDE9D380AFD99DBB2543D
+:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9
+:108FA0006F944E6A98DDEB40B883D17416F5FE9C41
+:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5
+:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5
+:108FD0003FA127AEB5459E658583F95C9661FEABE2
+:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884
+:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7
+:109000002F62233E3691739AD9660B33DE24847E19
+:109010006A660713FC1A313568E8C0EECAA3792CDA
+:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1
+:10903000437A213209F934C1C57476DE623590A7CE
+:10904000A0DD9A69F3A19C013C111CF62730730244
+:109050008CFB363C116F95EAAD7B2D6EA403C5D712
+:109060004AD0DF2AFC5616417D73EDF424B25BD959
+:1090700099DB4756033C3C499C6EA11FBBE8C74E99
+:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF
+:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B
+:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7
+:1090B0008E880958A825E4997D27D4AF4CE26B1E11
+:1090C000E9E27A707F41484DC1FE46C13AE0D55B86
+:1090D00089C1A26647141F60E304117F1956783ACC
+:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0
+:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77
+:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26
+:1091100030A44333E37696DF25E8A482C3ABE2DED6
+:10912000C5A9A837BFED999FCA8AA272F41E25E887
+:10913000F441FD7B2C819F52BCE35F5486FE883551
+:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B
+:1091500043BD9F087FC772FA62F2B317BAB83C4B9F
+:10916000C9AA21798E30F4A29FC2FA434E0DFE5255
+:10917000A798747E83E57431B5BF70BBA1248EDDE2
+:1091800050AAB31BE4B846FBE1D37559347FD9FE2E
+:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA
+:1091A000BA38513CBBE32E011FB4134231E765D5F9
+:1091B000BDFF14FCC49076FC237CFCE8B849C06871
+:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2
+:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F
+:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839
+:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED
+:1092000062A25751A2FA66B0BE127AC62017CF6783
+:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7
+:10922000A18FD1FF237665D9E541753CCACD2A854A
+:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F
+:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E
+:10925000438A8AF28EF7D728E8A1E0D807562FC8AC
+:10926000DFFF1276D017E9FEB791AE3624A614A31D
+:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99
+:109280005D9C3ECA17AD6935C37B4B87E2B4318D17
+:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20
+:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3
+:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1
+:1092C0006EA92CC5FA7EF326107D391D0AC583735D
+:1092D0009A01004007393EDEBFC31756961745D79F
+:1092E000D966AA2E42BDD09691E443BD30D61D3C2E
+:1092F0008CF4DF70281241304D3ED46346FBAEC281
+:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84
+:10931000ED067A070B59D0F9362E6F55F60E437CC1
+:10932000A0EC80F132D68F21BD24EB67B8849EC8B3
+:1093300060C117C8AE626D8CF0C5681D19EB47930C
+:109340007D2FF119B5A3C64E403BAAF0818879194B
+:10935000B4DBFD58ECF8BC45E81158074BF744D78F
+:10936000118F2FA41E93F52C71FC6849EF4955B15C
+:10937000ED53D000F4BD7C91FB3A5C77C3062BB370
+:109380002951F857B803E9389F9C8EAD0AC246D2DE
+:10939000D706D7D34A2EACEFF65B985365F1E7DBDF
+:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB
+:1093B000FA54FA1317A773FD73A73B3002C76DDC8D
+:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7
+:1093D0002FA58EFB290DB5F630AEB37C9199F057D1
+:1093E000BFC11A4679D4B0B33362427BFA6EE6430A
+:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78
+:10940000E53684159C4F0610610FF979112BEA6738
+:10941000235DA33D8C76C95B099CDF4F943B420AD8
+:10942000C0EF8425D880F54E6427F942055178BFF6
+:10943000DD39EB1D05583AF9055B049F6DA66D59A2
+:1094400076A8D736CEEA433AAA700767A5037C5CB4
+:10945000E64017B64F7327FB5AA0ADD7C626907EBD
+:109460001E221C261BE861F2DD9C4FFE263D45DADC
+:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD
+:109480001B189FEF3E977F01D1ABD345E3E63444F1
+:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56
+:1094A000CAF57A2167CA176D577EABA1837A3064FB
+:1094B000905E72766E55D00F84EF2D956EAACF6CAC
+:1094C000286776F2FD887AF87E9346AEC875C49018
+:1094D0002FB7217C1D877ADEE4F22542F427E76B63
+:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3
+:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE
+:109500006E57306EE04EE276A39C9FACF745FA8C26
+:10951000F5389FC9553D0487D5B566C29B9C4FA5BC
+:10952000353012FDAF76D1DFBE859F597BA1FCD0CF
+:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7
+:109540005CE8972AC663AFE62609DBF2D201D22394
+:109550005777F138C1EAAE4EF37247944E0B8EED59
+:10956000BB11E96C75878D2528883FBE5E239D82DF
+:109570007C21BA67212BED67817C0C913C65C1028F
+:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB
+:1095900046E56602D17BC1B109FBEC00CFD53EC5E3
+:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8
+:1095B00064FF46F8FD5AC8D518787E3E3D861E9158
+:1095C0007AB5E0F1190C9F127F660177D9EF9E748E
+:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2
+:1095E00036B4D8C3C8D76FA75DF98E520C707259C4
+:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D
+:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1
+:10961000E4F2A421E4203FB12158B382F61FDC0913
+:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9
+:10963000AFD50BDFAFEEE07C10855B5847B720E776
+:1096400008EFFB5C723F2258807005FFBD05E30CFC
+:10965000D27F4F591C08257B07F36BBAF0DF27092F
+:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3
+:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7
+:10968000FF41D04B7D6907F143FD97CDC4478E2A3A
+:109690002E4F1C87F47290B11F8BF53F40FD54266E
+:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335
+:1096B0003F4F45BC74AAB42FC5CE80555F06704D90
+:1096C000103010F52C6E1EF73EF1142002F9D2DC9A
+:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7
+:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7
+:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131
+:109700004FBF27C1877143B70A962DD0434BC71B64
+:109710002997E1BED833974C40B999E7E67C79ECBC
+:1097200045752DC267FD3F3C3F0DBFD7879574B48B
+:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26
+:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451
+:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F
+:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5
+:109770004FA4F39A141FAEA32168E6FBB692BE8DE8
+:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D
+:1097900091F4FC85D8575A56E1684379F6C5A6E49A
+:1097A000BA58F144BF582FC65C488ED52A144F6B67
+:1097B00003AAC1B8465B229B82CFA4A2883517C6F4
+:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9
+:1097D000268ABF61F016EC7F2275C6C683183C0C42
+:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA
+:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B
+:1098000026E234509FF44ED99AD8F1D02AB743D0EB
+:109810002DD79B395DD5795E921336DF288D5D3A61
+:10982000EC60F32610432CA7AEE74A5CC75563965D
+:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8
+:10984000B3456ECE4F194EE6BE14C6AF3433B703E0
+:109850009F8C7D642139B283FA05FB83EC2AEFEB00
+:109860000B77A03DB2C512CC9E84FDB409BDB59D59
+:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3
+:10988000A87D88B79FB5BD4589CE1728351FF51629
+:10989000F657EA403D13AA25FC78ADB4AE635825CF
+:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6
+:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E
+:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5
+:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14
+:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF
+:1098F000122BD2EDF1757EF65B30401BC53EEB16A8
+:10990000A57725C5795E497062FCEEA4D037F50FC6
+:109910007C7E18F74747ECCA26BFFEE42B09B5D872
+:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A
+:10993000007630916A23D8A9DC0E5EB119FDB3D54B
+:1099400075CC87FCDF68A09FC65D07885EA41D5CA0
+:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01
+:10996000EC51AC9F3633DC6225FA2A2943FADAB788
+:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0
+:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6
+:10999000004980DB76B27BD918ABD0732BC85E6EE2
+:1099A000CCBADE477C669407AFB490DDD5E84DA411
+:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94
+:1099C000BE2C8CFBCABF17F093703C69E9B911E15A
+:1099D00071F2252044F87EF54C4EAF69333B488E3A
+:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F
+:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F
+:109A00007C80E33722F82922F440C46DD5C75B9CE3
+:109A1000A162D4BBBF17F8273182F25DC893D52B62
+:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0
+:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D
+:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B
+:109A5000401708B79CBA00D1C155EE9B7D6A01ED55
+:109A60001F909FD8DF6265B1E23C47851CF5A407D3
+:109A70004A31DEECC94C263BC7A3969B12B05D89E8
+:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D
+:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C
+:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679
+:109AB0003F44EE5F4838845B126BB5F2B34FC02170
+:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57
+:109AD000B227B85FDF4AE31F74F3784625AC0FED79
+:109AE000364F61600DD7A7C9BE58F0B853E079DF93
+:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643
+:109B0000F48CC141F4B7832B080F0CF080FCC082A9
+:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3
+:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145
+:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9
+:109B4000F58E46B80D559E9CB400FF23FF001C9077
+:109B50007F24BF24EFE67CB2A9C55B8EDF37553288
+:109B600067AB461F19FD259C27FA9D52AE8F7507DE
+:109B70000A3D1807304536621E8594C38DBBEF1B26
+:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED
+:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663
+:109BA000718878FDD0F222325097A3BCD996144622
+:109BB0007925E344C67EC778145D3C46FA2DB8BFCC
+:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550
+:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31
+:109BE000398ED4A346FCCBFD115C4F7551FC7AED48
+:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06
+:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836
+:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533
+:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C
+:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82
+:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8
+:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785
+:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D
+:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D
+:109C8000B588978B9FBA4ED76E86D9692E01B88E4C
+:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A
+:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24
+:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB
+:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B
+:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368
+:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5
+:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F
+:109D0000037F84058D7DDC2BF84896178452B91E9D
+:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C
+:109D200070B9361AE640F019225F7F26F070281EBF
+:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3
+:109D4000D45B4BCC1186F4FF9058CF169117FAC80C
+:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A
+:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F
+:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A
+:109D800090CF6B10BE5819D93981F498F1D2A52122
+:109D9000754878626A5E4C7D19B71F75F139F3C852
+:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF
+:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6
+:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794
+:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7
+:109DE0009DF562B41934ED0F1AF8B826981AD36E9F
+:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB
+:109E000006D7779FC49133576798A43F6FA1FDC0D1
+:109E1000417CF7932B62C1777F8657C7C78B820639
+:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31
+:109E3000B1DDC3195C6EBDF8FF297F7E725332F924
+:109E40000F08378F66FD9FDC94541B2B2EF35A06A8
+:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD
+:109E60007C9F77A413E343320F203EBD9A298E4492
+:109E7000305407C315F0E1B51642FFE68171226642
+:109E80001CC7678AEA59CCA9619A731EEA607A8076
+:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE
+:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0
+:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21
+:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F
+:109ED0002EF790E2526BED29C50CFCBAEF12F83365
+:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD
+:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902
+:109F0000B99F383EC3FF119613C53EB035D3BA1181
+:109F10009FCCC9D7718958C74693371FD7F1A5E29F
+:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028
+:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B
+:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4
+:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853
+:109F6000C6F730F54D688743FB6B59F018CEEFA864
+:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031
+:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7
+:109F9000921E0BC59B2F612AC9F37A337B00F926E9
+:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F
+:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4
+:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE
+:109FD00060CB407ECC6246F931D08F363FE6F88CBC
+:109FE000D8F3708B79584E27C5E93785DE1F1F716E
+:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20
+:10A000007831FEF138F9496307FACF66A1746D3BE8
+:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8
+:10A020001BD2389DECCD72BA9742D74B59AF05E998
+:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59
+:10A040002BF96E04D6337F8176B609242DDAD94BED
+:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21
+:10A06000CA6234DFC4716328AFEF14F3A63ACF217C
+:10A070003717DB55BB59B3DE4371EC865B05FC0E2D
+:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5
+:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB
+:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714
+:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A
+:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9
+:10A0D0003D07D065F6274D80E72121778C70D99D0B
+:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F
+:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D
+:10A100007203E372EFE1CC11222F3CCD8CF270315F
+:10A11000EF82DDE07C8BF693249C07C14FC0DD0805
+:10A12000C700F3DE8879DBE783674796FF6184CB5E
+:10A13000D203895694FF37DAFBF7A38FDADB63FA91
+:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF
+:10A1500033658A8FE751B09964EF28A15CF5ECC5AF
+:10A1600043B77736A604C7207F7C29F2AEA53EDA36
+:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700
+:10A18000231DBD66E374F408F404E5A63D63B7A29D
+:10A190009E79302B5887F5641E1FF3F78FC63C84D9
+:10A1A0000B8513FC59908ECE07A7273219E1E75093
+:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C
+:10A1C00043C253EE5BC8F9D565713A944F093763C2
+:10A1D000FE505D9649D4E3F9880F660508CE7DC32D
+:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2
+:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5
+:10A20000879A5FBD9C5F71ECF965660D0D7E01D686
+:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326
+:10A220002157EC79960D799E41CB0FA16F257DB317
+:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7
+:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291
+:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D
+:10A26000BF42D011C0AB82E035A79FE2188746C736
+:10A27000960B15C6FA6D7C9C78E70BAECE528674B1
+:10A28000BE80950629FE576E774454C0C36D021FE9
+:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9
+:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB
+:10A2B0004259738CF5043DC11BB3347E50FD53EFFE
+:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C
+:10A2D0006417E41757639F988FE00A903E40FD8013
+:10A2E0007A67E3EEA925884CB433309FA73F3991B4
+:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A
+:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24
+:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5
+:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F
+:10A3300006F01F07CF1D1E7F3BF6D720CED1283257
+:10A340008F6F205E61761EB647E13D54BC248A784B
+:10A350001AD80D8F211D586D821F9983CE874BBB54
+:10A360008519EC1B3686FBB73764BDF7478CF76C55
+:10A370004CE12CBBF14709E4072E519C565C37D8C1
+:10A380001F9FFE1CEA0759E4D3BBC83F9476469250
+:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3
+:10A3A000996172D0FEE63E585F36C88D1956FE2C74
+:10A3B0009F055405FDCD50F3BA7B615EDFB2338952
+:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3
+:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2
+:10A3E00065737E7D31C2E57217C1A5F8959999DA3A
+:10A3F00078CB40BC43AC635E682997A7063927E554
+:10A4000099C9CEEF11617EE6756650DC88C33DA424
+:10A41000303394AF90657452A07CB9409282ED6164
+:10A42000DD5788275B16CC423983693C381E787F1C
+:10A4300059F86C9DEAF3E273BA1230F3798479DE4D
+:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9
+:10A450001C8F9793457943CDA91B6FF20E8E633005
+:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1
+:10A4700051CA4F154F63BCE33B532884F9D977AADF
+:10A48000619A6F128B447A303E61071098288EF0E3
+:10A4900007E403F06E1A719E09CE5391BB18E6399A
+:10A4A000FA152CA71BF491C7B186F29E3D01B3416A
+:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB
+:10A4C000488904B2CEA69F3F5E638CD35866701451
+:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610
+:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9
+:10A4F000A837DA506FD82D7E8287D41FABBB6E652C
+:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E
+:10A510003C05796F436D117B1F5AB2A6EC1134CE06
+:10A52000FC7782373440B9E63D363E02F54AA6074D
+:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB
+:10A54000F51C50A99F26712E963167FD4EE87FEBD2
+:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7
+:10A56000BC9141747A06D607F87F02CB30EFA6156E
+:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F
+:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F
+:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC
+:10A5A000D74E827915F64C24321E09F531BF093396
+:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2
+:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD
+:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8
+:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE
+:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6
+:10A60000D91CD98B7C7D9978968827F2B51DE0B846
+:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF
+:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391
+:10A63000E9485F4F6617123D5D6EF715260089B435
+:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0
+:10A65000DAFC81FB7A82050B806F160615718E3E3F
+:10A6600058B058138F95797D0B6CE047C7DA77CED9
+:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED
+:10A680007D655336E557F07C67E0FBDBB22745E597
+:10A69000088C4BF928F398DF82EB9A27F856F2FDE5
+:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE
+:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB
+:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847
+:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D
+:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0
+:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0
+:10A70000F4535EE3026B782F9EFF59B00AD608F52A
+:10A71000DF10E722DEC4731113A274947C5D4284BF
+:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0
+:10A73000176A4B49F669F37336B53457623D99276A
+:10A7400024CFB52C88B31FFC9C906B5B149EAF1577
+:10A750005A6427787B5476507B4EDF5318A03CB95F
+:10A76000A66C2F8DB345C41130AF74223CC3608EEC
+:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A
+:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3
+:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39
+:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733
+:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4
+:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71
+:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8
+:10A7E000762BF65767D05BAB1C6F5A913F576DB70E
+:10A7F00044E99161BEA1AF10055DC3CE41710F92D6
+:10A800003F522E19E9988DD4CB9F12296F412E709B
+:10A810007DB598EB39F6A482F19FBEE423AAF09FA0
+:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3
+:10A830000FE89F29582EA6FA5406F93906F3472F38
+:10A840006389445F83EC0431AFD28179737B48CA5A
+:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF
+:10A8600084F7F0C0F33231EE9D267F5144413CB174
+:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD
+:10A88000F54D61ED241727EF7F93E424E0F92CCAFE
+:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5
+:10A8A00034CBF19019E1342BCB888F9019E13ADB4E
+:10A8B0003B084F744EC01F074F7E2947985E8E1489
+:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3
+:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266
+:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE
+:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96
+:10A90000D264D27351BDC8F15F264A97225D69F0C7
+:10A910007FC5AE84880AF45622DA5F8AF43021AA11
+:10A9200017232687D70AE36E547C6D6A0CBC67B880
+:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C
+:10A9400043784DB177B49A619E87ADBE9FA3BF5245
+:10A95000CEBC84F772837EA970D498913F2BEC46CD
+:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F
+:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73
+:10A98000897723BE25DF7726382B1C18D7ADE3F94E
+:10A99000C413DF1FD98AE58CD50574CEA533CDF756
+:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370
+:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3
+:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0
+:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A
+:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011
+:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB
+:10AA00009BDFB227927C1276DA34B1CEE98FF175F2
+:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E
+:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9
+:10AA3000F00DF43982E79B6E83211ECBE17686CC44
+:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B
+:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE
+:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348
+:10AA7000497BCDCB60DC92B37FB832967FFD8418E2
+:10AA8000F788C87F97EFEBC20526F43F3A9178E844
+:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990
+:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8
+:10AAB000EE3DB9A68745525306CF7F96994578DE7D
+:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2
+:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65
+:10AAE0000BECCD64172E12F2FD1616A638C52D06F6
+:10AAF000FEAE777CF399C984F1303D1FAF86E970D3
+:10AB0000BDD0FFF82700FFBA47929DA8E75777E826
+:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC
+:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22
+:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B
+:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9
+:10AB50003F8744EDA943B3C3480F25827F251F9744
+:10AB6000087D3E485F5719FD9887883F268A928462
+:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11
+:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2
+:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08
+:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7
+:10ABB00037E22B9E5D3F80AF04B09792D08F67C481
+:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4
+:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA
+:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF
+:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A
+:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632
+:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7
+:10AC2000B83897C7B9978867B9781E1179D8475C43
+:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4
+:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A
+:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44
+:10AC6000719657B85E6834F75A31BFE41A77702A84
+:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0
+:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0
+:10AC90007AFB6EED25F93050AEEE25FEBF2637402B
+:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8
+:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A
+:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4
+:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554
+:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4
+:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021
+:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F
+:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520
+:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C
+:10AD3000B3D502BEF1D683E707BC1AF981E707BC99
+:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18
+:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7
+:10AD60006A63CEB0979F27D0B6C7F304DA329E2726
+:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5
+:10AD800078AE40DBFEE677276621DD7425F03C32A5
+:10AD900016F2F714015C5608B8E079036D7FC753CB
+:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA
+:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292
+:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A
+:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0
+:10ADE0003957E421E6B01C6D9C264A070E5F04D754
+:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5
+:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3
+:10AE100090E0D5D343D2183D3D24FBF4F4903A455D
+:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C
+:10AE3000FF207C27E0CD9018578275629CF72F0584
+:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737
+:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42
+:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF
+:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2
+:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99
+:10AE90001617DE1B685C2FDA514C134F32EA7FA580
+:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC
+:10AEB000455EFCDEE1B7E579681C662FD3C57B6390
+:10AEC000DA73721E122E727C1B6B56B3909EC718DB
+:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE
+:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0
+:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C
+:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F
+:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A
+:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3
+:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71
+:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520
+:10AF500040196CEF37B01EEACF68DF0FA293F3E819
+:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4
+:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169
+:10AF800066B8C08F51310FC36B8D9527C5F0721510
+:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF
+:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA
+:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA
+:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160
+:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C
+:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC
+:10AFF000D882F5871DEC3DACA03C7378293FE4E492
+:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF
+:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005
+:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4
+:10B030004B851F307978E0216C57FA615E0ACED7D4
+:10B0400032A283EEC5EABF83DBC16E95CD44F881A1
+:10B05000DEE37ADF61A67D077752484D413B6E29DA
+:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8
+:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4
+:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A
+:10B090002037D8F8BE7CC15F27450A81DF5EB7F252
+:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC
+:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA
+:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13
+:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164
+:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45
+:10B0F000E0A1D103F78379302FA431C19FBA10E3C7
+:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94
+:10B1100011F6C34991F7B966F68C4CF42FE2E54B72
+:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7
+:10B13000335F42F72E05CE55EFD53FAB31E1795A5B
+:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9
+:10B1500079A53C939D235FBA11EF23D7E4D7A09F35
+:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6
+:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D
+:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F
+:10B1900099378CCBA7711E7300F7252F8EF07B3F5C
+:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB
+:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5
+:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B
+:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4
+:10B1E000E190E00A06D11E91F715E37DC63CCF231E
+:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05
+:10B20000A4DC39FA884A72E7E807821F99DFA19423
+:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225
+:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A
+:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72
+:10B24000FDB16FD903A4E7563C60D467012BCAD97E
+:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5
+:10B26000BD6BB47F670C13F66F192BBB90734E8FB9
+:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14
+:10B2800097D3C36D3BFE60C59F048AD7EF319017FB
+:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69
+:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F
+:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A
+:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A
+:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F
+:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6
+:10B2F00089DF4368B7F1FDB9F0D353F7613878645B
+:10B30000C7E619E86738BBF746302ED166E2FBAFD7
+:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2
+:10B32000790FFD6D2AF0973835FD33612F350A5CB2
+:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478
+:10B34000C5BFC6314E3732BF847E1B43132F3A012F
+:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE
+:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A
+:10B370003D03E3FD529F5E8FF96D18071676EF22AD
+:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904
+:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6
+:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417
+:10B3B0003E99CCEFCB51FA476327C73006521ACDDE
+:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC
+:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5
+:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2
+:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9
+:10B400009B4FF200E49702BA73CFB04FAE31E3FD29
+:10B410002039604741F9F82F0E5F83BFCFD238A2A1
+:10B420007725DE179EFEF8595E1ED77B18CBC31E0C
+:10B430004FBC96CA137A57AA509EF278D6B5D41E3E
+:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF
+:10B45000F5D23D418DBB2F3269E38325F95C4E1F48
+:10B460004BE0F58E15B0257311DE637A476B7F379D
+:10B47000C1932FED526E97C975CA762C2B76FFEFCC
+:10B480000B3D708BB8DF677A126B4BE0FB1521B474
+:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC
+:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC
+:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E
+:10B4C000578278037C9905BECCDC0FDC4A78C67EB7
+:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44
+:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA
+:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6
+:10B5000019C043A642FDB70AF8E5F1FA17BADED32F
+:10B510003FD07A3578F263DEF19BBBC6129EA60C53
+:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA
+:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D
+:10B5400044E407796F1B0B4D2367BD41488B817B1A
+:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742
+:10B5600014EB736AEFA51BE0C38FFAF36B34F75249
+:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B
+:10B58000BE88878F71F97F617CC8791AE0390067BE
+:10B59000C3FC243C918FA95D919E9FE43C87E59B71
+:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51
+:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216
+:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F
+:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829
+:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8
+:10B5F000F97934AC56C53A0F181278907654A3D026
+:10B6000037C79EBEFF1A84C77FECB038518F363DD6
+:10B61000658BD8280E720BD95150FE9C97EFFD1AFE
+:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF
+:10B630009AF08C0B8BE43278366EB7F8226E1E4F80
+:10B6400084615813EBDF88F333B6C7799C06BC37A7
+:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742
+:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14
+:10B670004BB8B0B087EC9AD65FFEACF87307DEA784
+:10B68000F94F294A91565FAE27389DEA58FEF7BB1D
+:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C
+:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB
+:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2
+:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F
+:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476
+:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60
+:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF
+:10B70000E81E8565160C6E5FB7757F0AD21FC209E9
+:10B71000FD4B89A701BC0DC257E49ADDA5548FE209
+:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB
+:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4
+:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756
+:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76
+:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE
+:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3
+:10B78000B3E18F64B0AF30111DF3083F50459EEF19
+:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A
+:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C
+:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62
+:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3
+:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B
+:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14
+:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99
+:10B800004B048F163786F7D628240F6CBAFB9F0699
+:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745
+:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D
+:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A
+:10B84000E619D2BD320D96F0938F22FF02BFA29F60
+:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C
+:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0
+:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE
+:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA
+:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E
+:10B8A000292F195E41A581A3849FA4C755CFACA6BB
+:10B8B0007106E856D2A5A4DB01BA1C945FA983A344
+:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA
+:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03
+:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07
+:10B8F0004C8DBEEF4F10790381FE94348D5DF47949
+:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74
+:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65
+:10B9200068599882F18CBEEE42FA3DA19BDE057FFC
+:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642
+:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3
+:10B950007EA0310E7233E641611EF263FAF7AB301E
+:10B960003E827832D05310E9297B303DAD1C2EF653
+:10B970005F4B58896EFF55C8B54AB5E8A7689FF474
+:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B
+:10B99000843C44A7F5C12332CF8AE85AD29DD17F97
+:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B
+:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8
+:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7
+:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD
+:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033
+:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA
+:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD
+:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9
+:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0
+:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF
+:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4
+:10BA500018F9D553BD7FBA36E48805170E873E80A6
+:10BA600003AE0BE042F775C78347D7707E0FFFFF29
+:10BA70003E787C4DFE4243F764E2A3285C14FEFB53
+:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F
+:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5
+:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949
+:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50
+:10BAC00007ABA359F3008000000000001F8B0800A3
+:10BAD00000000000000BCD3C0B7814D5B9FFECCC76
+:10BAE0003E926CC22604084260F2244A1E0B791072
+:10BAF0001EA99B842008E206A4A2222EF8E015923B
+:10BB000008B6C66ACD622202F5B6516CAF6DD16F30
+:10BB10004141DADA6B8A41B1025D10115AAAAB8257
+:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30
+:10BB30004CB233243CFCAEDFD7E423C733E7CC3927
+:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1
+:10BB5000B1056806280648526D00FD004E6CFDFADE
+:10BB600090944CAD5D853480BAED710045D8FE31BE
+:10BB70002600124064DBA9129F13E01BFAB912A041
+:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443
+:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F
+:10BBA000433EC0B6D606BE565C2F120F3337213C3B
+:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2
+:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB
+:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3
+:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625
+:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D
+:10BC00005095E1EBC67B870DF208DFBDB3697E641A
+:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91
+:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8
+:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280
+:10BC40007A0F42D01F4006F123272F9C0209D4AE61
+:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C
+:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE
+:10BC7000B70EAD71AFE215EE042801F881435BAF5A
+:10BC8000FF948912AED7B40CE1C2759AFA595C4D93
+:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3
+:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E
+:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0
+:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02
+:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00
+:10BCE000A1138083DE57E8BF08FFE45521D2430546
+:10BCF000147F58E0237D23113DDD290E5CCFDAE768
+:10BD00000EF72A899FAB4A89F69E85FE2C31D01703
+:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9
+:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB
+:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE
+:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A
+:10BD500020A71ED7A992C785FDB8FE89D238B79D06
+:10BD6000F44582A03412DBF2FE15807874A4DA1454
+:10BD70006ACB3A11A72878AF3CED00250ABF72487C
+:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E
+:10BD9000F4BCCA956698FF464C423E14D07B1326ED
+:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2
+:10BDB000C245241C1D7B675510BD26A9230CF3B674
+:10BDC000A059217DEEAC9203EB901ED552B07F3E80
+:10BDD000D26D72CE68237C128C273C6B2C285A388B
+:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C
+:10BDF0004DC357A0F40518DB70169442B4E3C15646
+:10BE0000C3FB857BB618E627EC03391EDB11FBD597
+:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F
+:10BE2000D85B89E840C991FA57A86D70203DF0F9B8
+:10BE3000A918D122BF58CEFD8762024D08EF294BC9
+:10BE4000C04774B85B0EE4501B3BE88E7C48073853
+:10BE50009AF2B0DC87E0075FA78A7230FA8B401352
+:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3
+:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6
+:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7
+:10BE900059E596345CBF39C5D3B283EC66C587B328
+:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4
+:10BEB000511EE5F8F10EB2EBB19532E30557590387
+:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE
+:10BED000AFD7A409FB10FB175025843FB6AF4FCE58
+:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0
+:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6
+:10BF0000A6580259B864C241F76E2BF657E7EC7792
+:10BF10009119689B72D82F235DDA0E86CA24D4A5A6
+:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B
+:10BF30008FE558C8CE2C41B347766647D93339E4EC
+:10BF400027965C7EC500E8C1BEE96DC26909D4C20E
+:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2
+:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302
+:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB
+:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00
+:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9
+:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62
+:10BFB000DAD0781CDF4836518C0701E57A954D1BA5
+:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D
+:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA
+:10BFE0004F3BFBE55513AC01BB7431748DBB005D59
+:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5
+:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2
+:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3
+:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08
+:10C03000F59F39CD24378A276E24EE53E7FA8AED2F
+:10C0400041959CDB87E29D2E3A923CE39E3FB5747E
+:10C05000F7C93E2474D3D59389E3ABA2E8EC709082
+:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA
+:10C070003527428B05F5E1A46BC3F7491E4E6EB41C
+:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4
+:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0
+:10C0A00086F54E8E7B37290FDF3B99AC24117D1628
+:10C0B000866D4CB79B1508DAD15EB625DF5659CE92
+:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743
+:10C0D0007D8278499E31F237C37BE71779D04F7460
+:10C0E000FB8874AE2334937A9783E6724780E2CC60
+:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F
+:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18
+:10C110007C86CAF640513C2C0FCA691B8FD7349CD1
+:10C12000643B8EE0A491DE742C13F6AEC50AB754BE
+:10C13000635BF3BFF22DD538BF06430CF617B0D3BF
+:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8
+:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D
+:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF
+:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262
+:10C180009FE63A40FD0FD31EA95606623F5EC8C126
+:10C190006FD26AABFDB9245F4EA6CB891571AC1F77
+:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E
+:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C
+:10C1C000D344FCDA1F79538AFF5E45BD77201D9268
+:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2
+:10C1E000E6BD181394901F8B9F78C546FE68AEACD1
+:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B
+:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4
+:10C2100062A3F1F9A01C26BF614161A6B866A173B3
+:10C22000978DE2B2854F5B0F87A3FCEA22081F229D
+:10C230003DAD79D67A381CE57F81DE8F92AFC3168B
+:10C240000187A2D163AE1C9A6D13701D20B816270A
+:10C25000617C2F93BB08F5F7715C5493C379494A0D
+:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48
+:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD
+:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7
+:10C290002D128FEBF6A27B3C5ED025D733C2827085
+:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC
+:10C2B000716B7C71135F74FA233D0B157C6FD7593A
+:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3
+:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F
+:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3
+:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965
+:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E
+:10C31000A11EE0541A5E32E0A3842A28898071E9C4
+:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED
+:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5
+:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133
+:10C3500070392C30C4C9958E3B0DFD2AD73D86F926
+:10C3600057A52C338C4F52571AC627E73C62E85F1B
+:10C37000E3FEA5298E5F6B8AE37F63181F170E719A
+:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E
+:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29
+:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF
+:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9
+:10C3C0007764F87E928EF47BC312688A473A8D6A4E
+:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D
+:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6
+:10C3F00030250C1E8A7BD03DF7245F2DE916964729
+:10C4000032FB807A37D301D664D4B79933257713BA
+:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D
+:10C420004AD09EC0A0791D08E70C0126D8699CFC63
+:10C4300077725F85E2D6EBE821C22B7B64F81E3E63
+:10C440009F51FA97339437DFE86CB5929CDCB0E7E4
+:10C450008163F7E23834FB8B493FBAE206FFFB9673
+:10C460004B891B5A28AE443A462477C843F14EA262
+:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC
+:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E
+:10C490002E25382C81FCFD239534BF66BFCA74D18C
+:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802
+:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7
+:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF
+:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B
+:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB
+:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714
+:10C500008B50E50092BF17D3451D071CE59C478063
+:10C5100022DA8B95939A9497453C65920FB35CE829
+:10C52000F200683724A4D78DE867C93FDC04FEBC5D
+:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4
+:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75
+:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0
+:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3
+:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6
+:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9
+:10C5900014072CD826333F30CF540622DFE6697CBF
+:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3
+:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89
+:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED
+:10C5D0003119F1C99FC49142C128A207C2EF0E923E
+:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E
+:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0
+:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01
+:10C61000FF96938D44B8975738029468478A5D0A0D
+:10C62000ED1F913C723CF1E323702F43FA956F7D2F
+:10C63000ED20E947B9C3C9E708884447343F47EFCD
+:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1
+:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2
+:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4
+:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7
+:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA
+:10C69000CA7268D7F2497B8A053C517474D97C1BF5
+:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908
+:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1
+:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5
+:10C6D000EC318ED4DB3A8B38371859A91652FE4705
+:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8
+:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691
+:10C70000EF5FB7ADD83537AA0EB226433F5F505C16
+:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147
+:10C72000DA540C7324D4A13C2920E20810F1C42C63
+:10C7300008713B1B3AB9F5A124513B17DCDCDE063E
+:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE
+:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF
+:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711
+:10C77000CA1F93DD8E8C40FB807046368B73B148A8
+:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D
+:10C79000EE37B85EB84FE6BAA5D97E5429228F0786
+:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56
+:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347
+:10C7C000E52F535D223F9CEA80E4D364DBCE9ECC10
+:10C7D0009D8186602AC5A328CFA3923C7F227AFB45
+:10C7E0001F1A97C8E70F647F8622FF3E12E736B014
+:10C7F000400A64213DB6B4897EDEED898CDF4D10A0
+:10C80000643EDE0C612BE17F0B00DBDD39A0727B27
+:10C810002B78989FB8725C3EDAA1DBDB9491AB1069
+:10C82000CF82A4CE74D2CFBCD1EF254908573EC5E4
+:10C83000BF4EAECDACA03845C7C39229F0B82CD3BB
+:10C84000F336C15790145AB59AE2C2CD16A0B8F08B
+:10C85000D3D1F7DC01517EB524ABE220CD7B4E1263
+:10C86000E785FE6D76515783CEFEDEA878FCEBCCD3
+:10C87000CA43A4F7FF20D838FF5DC5E748D52E414D
+:10C880007B18DF8F6980EF0DF1E6F5A49F7EB68FF0
+:10C8900005444B5127F44329EFCBFDAF9EFAA2BAD2
+:10C8A00059E0E3A778AC24CB17A1FD0A6C680A090C
+:10C8B000FE27EC81751C37D50FA1FAC5BC27ED16F4
+:10C8C000F2E3EFA11DA673D30F1A1DDC7E88F90DCC
+:10C8D000B57FC3FC86DA8F30BFA1F6EF98DF507BBF
+:10C8E000FBE9112844003FCCF4FC6FC679F0E8DD89
+:10C8F000CE083C2212CCECE9BCEF5486C83FF2DBF8
+:10C900003E7E208EE4608BEC2639CDDBAC701DE2E0
+:10C91000F8D65101392D9AAEBEB84C84237FCBDBBB
+:10C920008F8E2DA2F7149784F38F6F39D99FF3263A
+:10C93000137C5DF4D86613F4D0E07D2E31B48ADE2A
+:10C940007F6E733A41887604841C123F7BA8A30152
+:10C950002C633EBE9E21E2A76BED9D45D1E79B4037
+:10C960002103D52B353F53259F4D08E76A75DBD151
+:10C9700024D7996FD07EFE3D420F91AF86BA44A571
+:10C9800026877A9BB7CDE6257D7A6EDB3BD32623BF
+:10C990001DA68E99542CABDDF30B33FBF1BE79A3AE
+:10C9A000CFFC6A7532CFE7738B1B606D950BE7DDAB
+:10C9B000E4D8F12A91E066D7475589D8BF2545DAF2
+:10C9C0004DED1C356D4212D90108F03EB7E694EFEB
+:10C9D00026119BE2AEB6915F2E27A58AB2BB958E3B
+:10C9E000383A49EDEA57B9FA1AFA57A50C32CC9FF2
+:10C9F000A46618C627E70C378CEBFB4E71171AE6B6
+:10CA000091BE52DC8C7830DF61BDCCE732799BBFC0
+:10CA1000787F11E37F4311E11F41FAD930B03852DA
+:10CA2000BAF217ABC96C6CDE99C0E7B4A6F8B4666D
+:10CA3000DB53BB3D6AEFF1E997B0B5C7B8AEB69727
+:10CA4000B8EE62E353B41F8F92FD2878E13A3E7747
+:10CA50007F6EF499CB54C4CB9789712BD93D53DCAD
+:10CA60001AD1E256B3FC74C9A9A40AB9D92B03C5DB
+:10CA7000417AFC6A961F800734FF2FDA4BD5F3A961
+:10CA80006F097FF50FD2F7BED172ADB5A67A44819A
+:10CA90000DFD0AD509FF2AC33A7A7016E1D0E99F45
+:10CAA000D12DF770DBDA570716F1737F3C6E59AB67
+:10CAB000D5277E95A99DF3D7EC78756072F738DCA1
+:10CAC000F591613EDC27ED36F49BD38CFD87CB7767
+:10CAD00047BFDF9B1D9AB7E64E9B8FEAD28F893AFC
+:10CAE000A5795C87A76A678C87ECA5B2D5CEF9508B
+:10CAF000ADCBC3F513A597FA896E176E90A1BE272B
+:10CB0000FBB65E5B77CACE1890BFC5BAEFA1AC107A
+:10CB10003CFE17859F79AF8F07BC51FBB4668AB87E
+:10CB2000EF5862CB8FBFC279C75E023791FE58A221
+:10CB3000B0B7F96D9F5A2CE4276285BCE4BBC2965E
+:10CB400024BAEF323FCE4FE7C9750BE2FD746E5445
+:10CB500090DEF98E0359BFE569DFA30E94BBF72D74
+:10CB60001683DF8990ADC3FE8E4CDF34F23B9377A2
+:10CB7000C6042DDF029F1D9920FC5A85D0F7D924C9
+:10CB800037FAB9189A9ABA07C1704E46F853FFCCD3
+:10CB9000D3B7BEF518C5BD7B85FEE3B0D39C8FDE51
+:10CBA00014958FC21AA1BF0EFCA53867E1AE161B03
+:10CBB000E549DF95DEB7673ABBF57BD8B9FAACEB50
+:10CBC0007BDD01A1EF27B67EF916D9F513E8EFA2B8
+:10CBD000F5BDCB2F6A7A5EF7B8CCFAA83F3FBE55B9
+:10CBE0009E18E881BEAF697200AE6CC3B9D992B22B
+:10CBF00053D3C8AF2DD9A6F079606FFEBA6E85F118
+:10CC00009CECB9EDF6F9E21C59E011D1FDE9B62F23
+:10CC100093CA7345BB8CCF6B5B34BB23E218F4A380
+:10CC2000D664F2A3D512D7DF0E6C1BC0F7330E48C3
+:10CC3000105447F212D739906FD3C572F4DC49F122
+:10CC400018A4E428B4CF348D9FD3B5BAD08C6D33FB
+:10CC5000B2885FEFB4CD3DE021F4B232587EAE072A
+:10CC60003FC7830712BDA9744F616A9390EF038990
+:10CC70009D1D54473A501627D17914AEDF1C1DEF85
+:10CC80001DB07A53EB192FFD7CF20AF99BB84BC803
+:10CC900083357B88FCF44B229F63F957063ECC72A8
+:10CCA000B50002BB3DB86FAD3BC871E9221079BD3C
+:10CCB000399EAF1DF7998DFC8239FF2CDFB2E3203E
+:10CCC0009D7B9C538730C9EB85EA0EE6BCB7B7FA6B
+:10CCD000C1A8246F615654DDCF1C9F77C5A17A1C73
+:10CCE000B53E8ECF855E29FBEFE38BB07FD7FA3858
+:10CCF00017E5D9479FB4FBC92E1F5D670F48387EE3
+:10CD000034A9B39DF28EA39BF2DCB802CCB3A8BFCA
+:10CD10007B96FCFA6FAD2C1700C67B0D4BCAEEE676
+:10CD2000FB7F4BD6C74B740F0752C4B89EF3C9CFD5
+:10CD3000C4735CB0E0F9817CCEA9FB17D20F3A979F
+:10CD40003EF2448C8782FCA37BA6F7A17A5F87E53D
+:10CD50000F7C9E0FF27D87E8BC7ED186F891143F50
+:10CD6000402E30DFE6AFBB9CCF377FAEF86610FEBB
+:10CD700095CF5C3380EE952D78BB1F103E91ADCFE3
+:10CD8000F3F95F779CDE737C77626B461FC8EDA674
+:10CD9000935E075CF1F4322FF1BD5852C5390DD4C2
+:10CDA0007B06915C6CA9065A77A42CEE8D76AE8C2E
+:10CDB000E3B8D42C773559220EACD1EB0D7DC1915F
+:10CDC00042FAE303A64364E5F075741ED69C95A46D
+:10CDD000F9E9CEEC6951F712ABE4F6DA97493ED7A0
+:10CDE000D8B90ED211D3F33958435622CF9FE7302A
+:10CDF0009E9BD7369C31F67331BFC3F74736A98562
+:10CE00007762BB54A3FFEA54EFBD59F8FEC2D64780
+:10CE10005ED8C77459F3C3F769DF3D4E517FD927F8
+:10CE2000E8678EFFE739449D03602DEFAF3FFFF4C5
+:10CE30008977F97CF5D3CDC3B3C5B971E8935FA702
+:10CE4000F179F1A17BB1DDB4E72DE68B19DE73CE6C
+:10CE5000FD2489F1AD213CFAD2F9AEF71182131904
+:10CE6000C179DBDC55794C3FFDFC2D72B4E7FC4405
+:10CE700087535F5F874F5F5F9FF76496C863666BFA
+:10CE8000F9C1315BE8389FA3BF305CA2FA5ED7F3EB
+:10CE9000A4507E6294BC7C57F5F41BB57AC841CB94
+:10CEA000B21FD8E89E5CEB6AAB2FDAEE5D621DBD67
+:10CEB0002B0EF480EAEA2F5C09FB2D444EE94FE784
+:10CEC0007D5A9F9401FBE334F0248287EE0D6A2D96
+:10CED0002CF4A5709D9CD693E91A6280FB4DE56EFB
+:10CEE00095DA2B25AF22EE7D0558FE2740FD60C266
+:10CEF000C3E208F3B9987ECF6546E2F26BD270BF09
+:10CF0000E67EB09CE29866ABD00BFF9C38CEDF7417
+:10CF10003AE97E065CB906FFD2EC0255C175662A75
+:10CF2000B0C29A24E60D453A1FD833F7558A13DE6E
+:10CF300055EAFBD1BEEF391FCB932C14DF05E22954
+:10CF4000477CFFADDF16FF15E77E009E3227CACF74
+:10CF500075AF39D8EE9BEB11B7838FFBF3206CFDD7
+:10CF600002DFFBDBE87FADDF09DD78FD6DCC579B91
+:10CF7000293FB829F181627A5FBF8769BEEF77D414
+:10CF8000E5E47B81E67B7FD782EF33B25BA72CBEE3
+:10CF90005A51FFA81F45FE3792680309E747FA690F
+:10CFA000F438064C8F88557BFF7395FB459523B964
+:10CFB0001E09A754B6C7634DFEA668B845E461DFF5
+:10CFC00088F9659D8AC1DF141568759BAF558E4B36
+:10CFD000AF3CAD9CD71F3D942DEC59515F4B7D4F1D
+:10CFE000F1A19A2DF4A70982B2C047C40963BBE43A
+:10CFF000CA2313FF6AB57E2DF93394A74882C34F25
+:10D00000171DC76E15F2355609EEA016AD2B34501C
+:10D010005CB105FD9D0E079D11A60C673918A3CBC9
+:10D0200027AE350BE72D97EA396F71503C83ED2A17
+:10D0300029C4707C0F3AB9F5687EBC02DCDC8E072F
+:10D040002FB7289FDC4E84166EAF86566EA74048D9
+:10D05000F8FD2B824DECCFE03E179F5B4C9A67A109
+:10D0600078A3E8FA9EF3850A8D4EBDD30115AEE490
+:10D07000D2E9300150EF327AA0C7E01CB61F667AC1
+:10D0800098F5B30CC232EB2719860CAA13A8ACA7EB
+:10D0900095E0E17ED545D2A134EC53B84E63A64766
+:10D0A00065CF723159A3C7BFB281E543E7D3FDD93C
+:10D0B0002A3FD7F9857A9542F26FE6A3FEBC28AEE7
+:10D0C000E2245D4DBF237BF874BA57555458B19490
+:10D0D0004CF2DD1BC64CA77B5545632B9EA723CF87
+:10D0E0007BB2C7897E4145A1D58D598B54367D3C95
+:10D0F000CEF769F79261A688AFEFD2E216DFB21FD2
+:10D10000B85DA827BE54A79BF07360704FF759E431
+:10D110000C713E38646270A715E71D527C73B2290A
+:10D120003E70041354A4FB5DCBAAF8DEDA4336311B
+:10D13000DF6E1775581D2F7CEE8FC1FEA64DC3976D
+:10D140004AE9BDEF8FEBD6D2BABE65597ED257DF22
+:10D1500066C92D3859316026EA6747C80A540FD589
+:10D16000F7C94EF52DCDE673DD6CAE930DD2E29985
+:10D170008E4DC387135FEECFD6EE6125A71512DD66
+:10D1800096A57AEFA7F99178215FF76B7CE8ADDD82
+:10D1900090EDB92FBBF8DCE7917F2000F8FECFB20D
+:10D1A0007D0FD07A757167D9BF1F1FF1F6F2705AE3
+:10D1B000B79C4AC8A459887793070236F603DA7DEC
+:10D1C00075EDBC2A723BAE837428F2FA9AC8A48D1E
+:10D1D0009AD55942F613D7FD2F5ED7161E3202DFBD
+:10D1E0007B6CFA219B90B3C142CE343BB46DFBDE25
+:10D1F0007B0789AE17A2F4AA6EFB99AF3E40FAD521
+:10D200009D70BA697AB73EFD7229E793E034D80D74
+:10D210005DCFC66CB1735C3D76EBE5B7D3BCB2B7FE
+:10D22000DB3308AF2BDBC37C0E16D9F6EE2001876B
+:10D230009E6F9C92BE8DDFA5735ACEE3368B73DA58
+:10D240002552FD2BF1D4FFBDE4F623FC9F6A7E43FB
+:10D25000CF8BE76B782DDEBB7E39D545E6AFB97550
+:10D260000ADFE30988BC41C55FD2FF2F611F9F8F92
+:10D270002FDA68CE273A6DC4FFC5ADA6FB40940FE8
+:10D28000D3BD8768FBDE433EBC3D5B3BA74D855469
+:10D29000C6439ED5C7D783BD33E7BB8F83E755967B
+:10D2A0004FF0CAB47FB1D2733DE1B9EEEF69581FB8
+:10D2B000E6697B139D9C9CEFDAC47DE12796BA5DFD
+:10D2C000D4D7F4732DCA4A29C5D19DBF64F9D7DFDD
+:10D2D000D3F575C10A712F1BD6F465992BD860F769
+:10D2E000105F0B360CE0FC02F3208EFBD66EB0AF65
+:10D2F000A07ED383B17EB980EAC99D97515DA529EF
+:10D30000467CE744EE91EE8916A48B3AC719DDAE50
+:10D310006B7E5DBF6FDB95FFC467F3BDE6AEF1B01A
+:10D3200062C8379AB4F8B988E0A338B0DE2AF2A709
+:10D330001801FF8E37BF1F4771EC66C51B4775E9A3
+:10D3400013FBD3FB400F74D3DB62742F709E73C644
+:10D35000E277A7649C8F5F458F6BF7D335F9FC6349
+:10D36000A307FE6EEDE6878E5795FC6CA58DEA1C33
+:10D37000B7818BEA1E4BF63ED544DFDB2C59095CA6
+:10D380005138417F285F3862E173F0317B0B53489D
+:10D390001EDB347B47E7C26A945C95505108E7175F
+:10D3A0000F86007D7F14A3C6821A9517C7E524193E
+:10D3B000FAF1EECB0CEFF7294D378C83DF13CA2D32
+:10D3C000E98E5F133D5718E63F943081BFC7290BA4
+:10D3D000DDC175A5BE13471AC6ED28D774CF01BEAF
+:10D3E00010F14F29FEB25F857A99E01C1B06F815F3
+:10D3F000CADD980E637C541A6EE13C3066BF62C889
+:10D40000EBED17A8335D3E4CD3ABC13058D8073392
+:10D41000BD8DF72196EC95398E5B928A81675AEF24
+:10D42000F4D6F54FA77B3FAF91EE03661AE93CD0E7
+:10D4300067A4F3A0F9463AA7D61BE93CB4C148D784
+:10D4400034BF918E192BC618E667B55418FAC31E5F
+:10D45000BFDA30FFF2C034437FF8C61B0DF3F35A36
+:10D46000E71AC60BB62C3C2FDF47049718C6CD7CB5
+:10D470002FDCF323931C2A4CE762EDFB2C9DFF7EEF
+:10D48000FC25FE8F056F9FA044E5407F13E9E3FF75
+:10D4900017FF170CD3CE1174FE5FA45DBD4AF3C312
+:10D4A000E6EFBCA6C6097BF3FA9E13FB3DD87F438B
+:10D4B0002DB4A650DCA4C5075EFD3CC294F7E97903
+:10D4C000CAB5A592E99C3EC6704E7FA17B6DC5A1F1
+:10D4D000A0A13F62BFF83E6AE441F72BD4167FEC6F
+:10D4E00091A3BF871AFD05BBE573F24EFD7E9C9E9E
+:10D4F0003741F3939C87CED2E127252839B7BEA8C0
+:10D50000E7A7E6BC55CF57CFFDDE4AC42577CBBD94
+:10D51000E5B1227FD5F3D6EF8387BF2BBB6AB06F0F
+:10D52000ED30B4FFB2A5B32F8DEBF92C1196CE8D53
+:10D53000234458FE6EE69DE99E5CFE1E95EBDE0BD5
+:10D54000A5B7A7D33D7F04DF152E11E51FFA796932
+:10D5500098EF77B4DE61C9B5BC10DF7D7DCC674341
+:10D5600068BDFF1926E237BB8C1442FF3360960773
+:10D57000E8F9A824CF7334DF7C3FDBDC9AEF0DB5EC
+:10D580003506B9555C6EBEB763AE0F862D2AC79DB2
+:10D59000FE1F497C4FE733026E7477BC726285953B
+:10D5A000E315D0F2F19B35FAEB758B591A3E877172
+:10D5B00089F9E87F6FDEF21AF365514A8756EFA8C2
+:10D5C000E7F8FAD6C1CE917C0FCD53E816752EBD83
+:10D5D0008E31E892BE2FB910FE8B528E1AEA48F0B7
+:10D5E0006CDF8B3ADFEEC65BAC7F78A5A8471E5E8A
+:10D5F00099CAF5EFEEF58F733DE9E6FA370D7A71CA
+:10D600004BC37B063D98E3FFC8301E4EEEB452FD7F
+:10D6100030FCC2C0093721FD8E6DB6F3F7D0280764
+:10D620001DC4577DFDF0CAE1E3F9BBCA0BE2F9194D
+:10D63000C3D1DE1862FEEA781E6A3CC8FD706398AA
+:10D640005B339E7A9D426F6D3B2187EEE7774AB14F
+:10D650006EAA0B9BEB17775BD44F480F1ECA49D7B6
+:10D66000E2B5FA022FF34FD42BDAB5EF4BDBB5EF6F
+:10D670004BDBB5EF45DBB5EF43DBB5EF402356E7BA
+:10D680000AAA6BB44BE2DECF2CC9F3E41CDC2F6D8D
+:10D69000B0CF994371FFC2CE7C05F7A92B08CF9676
+:10D6A00090CF79FD7C7DE8B984E9C240FE9EC8CF69
+:10D6B000F7C38E58FCF9F4FDCDE48D59D7511E788F
+:10D6C00024D67F9C2291CA9CB4EB28EF3B62137A4C
+:10D6D000387D63EC75A4771FE362849FFF2549D4EE
+:10D6E000959C611B7D3F3535D93728A758DCFBE277
+:10D6F000EF66F039C9A55EE78C58451C18D1E2C128
+:10D70000F41C710E989123E256BD2D239EE3F3E99C
+:10D71000D4B27E3E9CCDDF9BACB103C5AFB83F7F9A
+:10D720005FA3DF33317F7F33F24F76FE4E42AF8708
+:10D7300096E4A4F13AF45D0EE965F24FE2D86E4149
+:10D74000383484BEE3E98277BFF8AEF218D591A3EE
+:10D75000EACF2539A20E03B781E13BA0C57B0F1F9D
+:10D76000A23CEBFD61BE3144D7B916B584F8BA3896
+:10D770006107D7BBA6E4A8BC2FC2CBF8A2FD6926DF
+:10D780003E2D7684B93E76A17A786FF81FBB3DF4C2
+:10D790008B5CAEFFAAF9FC1D9EB62FC23185E8AFA7
+:10D7A000E3ADC3D1BDCEF9E55FAFEBEAFD4F9F78A6
+:10D7B000285BABCBDFE2EDC19FDEAAD1A5DDDA733A
+:10D7C0001DFD7E8DBFE7F0671800D5EDEDB1E823B4
+:10D7D000B0ADD7E874EC06C487EB139E11C4DFC567
+:10D7E000D39CFCFDB9BE3EAEE3FBC379F6599DEA7E
+:10D7F0005D48F82FAC1775777D3C2209BEFA578A31
+:10D800003AE8E2EDEF1DA2FF0FC28267F20A39BFCC
+:10D81000D7DE37D319E9CBDF45CD95C5B915D2F79A
+:10D820006EE2B3B9DEFE6DE91A4915E7AB91B56753
+:10D8300086D03DB2C5746F8DBE0FD3EA57D066ACAB
+:10D840004B21BDFC54AF38F73C0AF85CCBAEF91164
+:10D85000BBFEFE60C5F0FE31A7F7A7449F1734BB9F
+:10D8600081F30316DCBF4DCF934D7594B690A87726
+:10D87000B6A5D8384EA67887FC931EEFDCF5A6A88F
+:10D8800077DE9526E268828FF82B1DDCCD714297FA
+:10D89000FF97DC2AD1CF69F505687FF02D65FF255C
+:10D8A0000F45FED2F9C59FAFD6EA01C21F166BFE27
+:10D8B000AF98D6A10027B70FFBC5226D5F8C1FB9AB
+:10D8C000EE361A7C4D0218AD6EB672B7A18EF07F9F
+:10D8D000947817F25045000000000000000000009E
+:10D8E0001F8B080000000000000BFB51CFC0F003AD
+:10D8F0000917B1A1F26FA0F1533951F9BF5951F98C
+:10D9000097D0F884B02E1303C30A46D2F420E39DC7
+:10D9100040FD0780F838109F6322DF1C103E2CCC9E
+:10D92000C0F04D8C81610E906E03D2E781F83B1000
+:10D93000DF05F2C5441818548178A12803430C90E0
+:10D940005E0EC44522107D4780749D2879766AF268
+:10D9500050E6E6514C195E2D8DCA2F5701A647554A
+:10D960000686B76A10FE622479267506860A1508AF
+:10D97000DB408E81A10BA866B63476730D81F2DD93
+:10D9800040792175081F00B5882CEC680300000061
+:10D9900000000000000000001F8B080000000000D5
+:10D9A000000BCD7D097855D5B5F03EC39D879C24ED
+:10D9B000377033C9490C1835C04D0C838878120371
+:10D9C000064DF106D1C6FEB45ED0DA481922F26ADD
+:10D9D000B4B6B94012C2A441B4A568E98D554B79DB
+:10D9E000B646C53EDAA7F482F8446B6BB4D4E1695D
+:10D9F000FF469EB5D65FF9E280536DF9D75A7B9FFB
+:10DA0000E49C939B04B5EF7D0F87C33E670F6BAF1C
+:10DA1000BDE6BDF6BE6ED9C5D804C64EE09FF3186C
+:10DA2000BB5A628CE50D3D9937D6C4228C356B6E9E
+:10DA30007D530963DF546287F56A783F5E8EDDA30C
+:10DA4000E3FB49752CCC9882F5F3198BE1FFA0DD3F
+:10DA5000FAE0BA718920BC531667E1D3ECDF7C365B
+:10DA6000AB8C6955F87DCBA44CDFCD274BB906FABA
+:10DA7000BD8CFE9C2865ACF59597261F32CBF05FD8
+:10DA8000010B455E0FC05F66B0192714C6DE0D2E70
+:10DA9000CC4AB391FB7BB3ADFB4C7522631FB6BD83
+:10DAA00038F9D0C4E1DFBFA9B096DE8AE1EF673074
+:10DAB00018741AE223E98E4F1E9AF7E03C8380A483
+:10DAC000B3A13D63694F0E3C776F3B532D1F82D34B
+:10DAD000390FC6921CBF9FB39D27529B2E8052A523
+:10DAE00094984D70A9F0CF74C6A82AACCBB2DD8D46
+:10DAF0008CE072C0DB11F9E7C03BE27A897AEF066D
+:10DB0000D7753268B7DEC5E9A53D4F8EAD63C3E971
+:10DB1000C55C0F138F27BB1E37301F8D63D251B3E7
+:10DB2000BC78D4751F8B8EAE443A3AF3BF9F8E9269
+:10DB3000FF7BE9A883FAF95F46478C75737CB17E59
+:10DB400015C71F7ACF9F91C5BD12D21914FB10EED5
+:10DB5000623E142B6EEDBC569E02628AC59E3C0D41
+:10DB6000E45671FF9206847BFC2BF3FF8ACFCE45EF
+:10DB7000B5F573617EF94DBDCF5E00CF483C2525DC
+:10DB800060BDB63319850AF4B73C5903F36BC7CEB1
+:10DB90006631766F728991C4F93283B1718CFD8BD5
+:10DBA000981363B2AE4239447FCD340F374B737C48
+:10DBB00048273CC3DB8F34FF10B633EB94E0FF57AC
+:10DBC000339CDF58EDD81A3E5E12FE417C170E8D55
+:10DBD0004FFDE4375BCA0CF163FFDE877F21FC5EFB
+:10DBE000FB3F325E01ABF2A17C0835C85A0AEBB3A9
+:10DBF000DE6C15CA91E52A4B838C28A8EE965CFA58
+:10DC0000D8EBD2C9587D2F5F1FA9313404DF9F990B
+:10DC100044F473CA8DAFF56C00923BBE381823FAFA
+:10DC2000D018CBCD193E9FDBDB90902DE545B5524A
+:10DC300082C68B3D5906ED938BB8DEDBDEB030DB60
+:10DC40002AAF3C9224F0E6A40FA6ABD391AD387D69
+:10DC5000A80DB2E19BF2C5E943FD9CF491B7C6D291
+:10DC60008E7DF6F58A9876C149D2C7171DCF5CD74D
+:10DC7000E17CB556AC6B998F01DFDE5ABF30A39DB6
+:10DC800031F2BA5611BF471A9891CAD02E7F703D13
+:10DC900093C39FB03ECAE0F25E675B2F65FCF4A6BB
+:10DCA0009E51F0A144ECF335FBF5B52AFA6BB9505F
+:10DCB000543519FB73637F40671BA3B72619F0C364
+:10DCC00071A46DC087D25D99C6322B63B17B040409
+:10DCD00032947D5123B589E82045EB62C2E7D165D6
+:10DCE0001BFED588DF56664D49C90ABFAFD54D70BA
+:10DCF000B8713CA07745830E01156A90A57D61AC93
+:10DD0000C1E1473238712A96BF6DA3832EBD8A6563
+:10DD10005A07935E11AD9C5EBF7D72F2C539DE225B
+:10DD20003BBC27DD2EA8EAAF5BF4D0C8ED54F6BAB1
+:10DD3000B93E80C4ABB0836943EBB4C1C5F6495367
+:10DD4000415F175DC612F076037E3A9BE894EC992A
+:10DD50000D45551AD215DB2DA908A7A947593487B7
+:10DD6000EA554A3AF5237B5B18D65382063DCDEF40
+:10DD700023C325E82F691C28837EBF24D6F74B4296
+:10DD8000AFB16AD76BFD26DCA467D5A132CCE3ED39
+:10DD90001BE07F4027C94A29758F34FC7B03EA4585
+:10DDA000904B0DF8DE2257760CF24194D6AB417CB5
+:10DDB0007BECE117269D05F4D11753188AAD750F3A
+:10DDC0007B8C3AE8FFD973A5944712F0029C0B04B0
+:10DDD0009C4F1BB9C548A77D751EA2E305177C188B
+:10DDE00041323EB6EFF76A267A5930DB350407FC3C
+:10DDF000B7CA3A3FF8EF2783EB5244E39870ADA8D7
+:10DE000052088EBED9520AC739F4C7BFDC7C0EC097
+:10DE1000F974B514F3E8046F88C1787DC67B91511D
+:10DE2000FD0E737C9D69884FE7F8E67A840B19E153
+:10DE300095FD09F00AE3256B07FAD7239E8F4AB1B7
+:10DE4000F5305ED69CD609384E892C13BC1B677BF7
+:10DE50006505E887BD384E467C06059F67B9BBBDA2
+:10DE6000A7029C9D13657617BCDA5836BA3C6B77CF
+:10DE7000C833558B1B12B4D7935A95320A5FA40C42
+:10DE8000B93E93BC7B4AE27AB223B9502BC3E91D59
+:10DE9000B2DB81A897E216BD0AF6E25312CCDF1579
+:10DEA000E1749C5D17E77662DF38925F01B11E591D
+:10DEB000531666B10C76F088F3808132D9CDD93211
+:10DEC000878FBDC2FB57CDFE7346EF7F83E8FFA36C
+:10DED0006689F5217C6ADC8BEBCF8C4AA267BFA0F8
+:10DEE0004FB62687CAA6DCF594C7BB4A601D3D51D4
+:10DEF00099E93ACE2F49EBBC19D6B80840F1D7C101
+:10DF000077A8BAF9EF0AD925D9F2F16412E0D87CE2
+:10DF1000E01AA6839DEA8FA61895275FED45FC6C55
+:10DF200006A5C0C7EF65387E00C816E56B00E4ABF8
+:10DF30008EF255EF4DCB5056EB59CC804F212D260C
+:10DF4000F981640E464BD7AAF0BE7D3123FA65688D
+:10DF50004558F0DB1E7DCE5000AECE2646764D678E
+:10DF6000A496E6D75E51EB2D417BA741A5F7EC5374
+:10DF7000C0876987803CF4973303C7DB9CCF52414D
+:10DF8000E4A5BA3CA247B7C6E7AFEF2863E9B3E020
+:10DF90007BF6F403387EF23B2C36910F49724D35F7
+:10DFA000E9424D2425F4EF5AB5D8A60C74B7832561
+:10DFB000B2E469363A25BDEBC45B969B5D88F8ED0B
+:10DFC000AC04FA2F19DE4F11F20FD05B2AB6F0E243
+:10DFD000D20CE394C83AD18759D63F7213FC23D5AB
+:10DFE0001FAA0776662E766D4888175617A1F9E5A1
+:10DFF000B0C13F069673C57CC7B116AA179DD97DDF
+:10E0000000F9ACC0E8AD415CDC1EBAEC595A377679
+:10E01000A786F10880B6EC44EE909C30825C4EBC42
+:10E020001B93493E86E4B4664007215F5F9494B534
+:10E03000CEC88FC8C22600F0A6B6EEC9E85F8659E2
+:10E040004CC2EFA1989AB4CA9F2C06659BFDC78E5F
+:10E05000944D27D2E27CC1B403C8325A79CB69D837
+:10E06000DF7600C8077EF2965082F4C587BEF014B2
+:10E070001CEC43399E95E6EDCBD1EEBE5EF1C73682
+:10E08000213DC4B87EF0C23F28FFB266AA36799C13
+:10E090006DD8CBB90EBD314F09D27CB3BFC4843E1D
+:10E0A000301A268E1B820F206B44BAD956A7321C19
+:10E0B0002F18E4709970E62A9FA66546701C4538B3
+:10E0C000003D0447B89C91BF07F01C75C073D40194
+:10E0D000CF512B3CAD5E3E5FA7DFBF54167E3FF8AD
+:10E0E000BDA8078FB3B78C7A2418A398F44A58E3D5
+:10E0F0007583DE3E32AA34A6D1FA3BFD7E589F7767
+:10E100006DFA61A628EB60D797127CF6EFAC88E831
+:10E1100084CA0A1BF45F97CE34F1A37FF965E0BB94
+:10E120006B0EBB18F215F0AF82DF5DE2EB35C28FEC
+:10E130005D8AFA1FF4F6552C1E46F8DE6632D9CBFE
+:10E140006FB3E7C26759E4E276D92DF4382CA8956D
+:10E150007F592C8A7EB51AECEC53C2840693CEA468
+:10E1600013B46E31467E7790D35B9279D7927DD18E
+:10E17000C5F5A3E9F77DBDDBAEAFBFB1C35EBE9A07
+:10E180002D1C87F475F56D2E96827EAFB1DA1FB027
+:10E190003E37CA1AC1F70DD6D2A905C9CE6AC279CF
+:10E1A0002CD5988A7EDA8A7FFBE1F425309F9D4248
+:10E1B0008FBE09725DB7E88D659194DBA8183EBFEC
+:10E1C000F5526CC139D2C8F3DBE0EA5B80F64172EC
+:10E1D000AB8BFC3AE6F4D7F62AE4AF59DA11BC5718
+:10E1E00076D9E737D6FC9DF3058F85E6BB6CF71231
+:10E1F000D29B23CDC7BD5B325219F4DB03A63E147C
+:10E20000F2C5A46F93AF93B58CDB7BFFD7975A0F02
+:10E21000E3FD01E523AD7FCB541E47699981CFB162
+:10E22000DAFDE7E76CF7A7CFD9EE3521C79DED56AC
+:10E2300078FBDDB89EABD464BD240FD9D15E578B7B
+:10E240005108A870EDAB49A32966A9D77592F50EC0
+:10E250004BA52755AF5E1EA5BF63C2CE78E2BE1F99
+:10E26000BBFB91FFF6BCBA00F5FB37FF5D615E9822
+:10E27000D7B1FB422C8DF4A9A6DC68AF2C03BA4AB7
+:10E2800051393DFD128B5D05144BFD7FF3FE10D916
+:10E2900007CB1EF4A41AA0FDB25FFCD71406783891
+:10E2A000B66EE03F0A915EF748DCFF4BF64FB904CB
+:10E2B000DE2F53D915F10C74222B9C5FDEFA65A07A
+:10E2C00009ED3E69F781AF51BFBD5F76A15C36EBCA
+:10E2D0007D8CFB007954CFC0EFC99F4AA989128772
+:10E2E000AF71F270BFFBAD9F4A1CBE7DAE940FE1D3
+:10E2F000DBDDE34E40BD55BBDF21BA3DFFFE9F8510
+:10E30000110FABF629367F77D56E25ED9942CF57A1
+:10E31000F1899A51027E5B29F875E5DE15A407564E
+:10E32000F66E7E07F975D53E974DAE035E6269C401
+:10E33000EB0B4AAC01CB0FFD24AC03AADE8CEE093B
+:10E340006B15D4EF1237D0D5C533EDEDB0FF8F721A
+:10E3500086F7C7D800C53557F56EE4E331AE6F4C8C
+:10E360003E7D13FF923F5C6F9CAED8F71D8EB3A726
+:10E37000A7531C72776E463FCED41726BF7EF36735
+:10E38000C7772561DCB71EFC7FBB9200FFF27FBC24
+:10E39000B7EBDB302FB6DFA7A11C5AB5E70F6166DC
+:10E3A000C17B9DC2FDB0633FFDC9BD3B815F8EBD9A
+:10E3B000E421BBEED8A37F394587791F7BE0E37169
+:10E3C0006877AE7974EE78A4AF350F9F3F9E8DE2EB
+:10E3D0003F20BDA63CD6754DD1BAEAFB240CC23015
+:10E3E000F688783AD6E7B1BD4A1A43B76FBFE84915
+:10E3F00079003FABE05D6B15AED70AD24358BE093A
+:10E40000F0BCF2BE0DEF285332E13B592847F10929
+:10E410006C13C5F5BEE4E273ABF1E98AE9481F6C01
+:10E4200080E4BFB3DDAA23B0AE53475EC7E3EC532D
+:10E4300037E27FD57D1BF9B88E757C1BFF7276069F
+:10E44000FD3F6C1D97FF68277EDC9B4BEB3ED23A6D
+:10E45000AE78F8D251FD33531E8C85DF6689C33503
+:10E460005531562BC8570FFEEBBD3B237C7D1B005F
+:10E4700021C77E76FC140C2EBFE11AF81ACAC98196
+:10E48000473DDA5DD066D9A32F109F1D7BF859B7A1
+:10E490004E72920525D07BC7D8E09F3ED4832B25B2
+:10E4A0005E58757728ED090FADD3CA5463BD1EA61B
+:10E4B000F7AFD2FB14A7FF95A9038BA40CEBB647CB
+:10E4C00029E5723995477859A1F7B9B5A07D3DA5E1
+:10E4D00099B88EAFCE43BA1B691DCDF96B38FF19C1
+:10E4E00096F5BC9BF3ED48FC79ACC7A34A5943EBC6
+:10E4F0007B4CD807AB52D20B2C03DF32B68EC33B1A
+:10E50000C2FEA3F974D2C3DD0E7A30DB9BF31E8BFF
+:10E51000AFC79ECF67C3D76D8A6EA31B136F6F7D86
+:10E520009A59DEA7859C58C992F505A70ED7572A98
+:10E530008B270B4B86E0EDEC55488EBFB55B213B3E
+:10E54000DD2917568EE08FFF4EE1F6C7CA7D07A67C
+:10E55000A0FC7AEBE02F051D723A5F79DFABEEA4E9
+:10E5600090FF29ABFCC7FE32ACC78B02EE558F641F
+:10E57000EE6FD57DEF64ECEF4DD5F832C2FF669FAC
+:10E580008B25A18B377B958CF18D838ACB16C7EDBC
+:10E590000C4D7F310BE39B61BF8EF35EBFCE7821C4
+:10E5A0008976C8732E4676A01A7BC303DFD787FC13
+:10E5B000B4EFBD3E7C35D32D7ABADD8127351A27DD
+:10E5C0003F588DC4AB79EC3565F3475D9A6C839BFE
+:10E5D000A9C9228CA7FCAEE42F2AF6FB0CDA7FA790
+:10E5E0000DD57F46651DB9D0DF3386145BCB32C4B1
+:10E5F000A71CFDC7672B4CB7D299512E5BE3ABE14B
+:10E600008337505CA295B5A4314EC48A58EF3D962D
+:10E610007EEF6CD3581AC667F5E5B235BEEA696974
+:10E62000313C0047D11AAD144DB391C62F6E91ED18
+:10E63000716D31FE6A114F60BBF7ECD903FDD6E373
+:10E64000B752F46378BC0ADC29B263CE1772F0D7F4
+:10E65000C20E3E28C50FA19F65E8DB54947352D9C2
+:10E660003615ED89F99F76AB4B2DF438BF6C6D11E3
+:10E67000D2CBE1BF2B4D99E86A91CAE96A6DC98690
+:10E68000226C7FD8777D117742A334CF0231CF43FC
+:10E69000C5DF08F643BF074ABEB16512C0551F5516
+:10E6A00018C65BEA234BB654C2FC0B8E28311F946C
+:10E6B0000B9A936A62F2F07176A1BC07FCDD857853
+:10E6C00004F8EF6E8B52F9DE369D9EBBDBCAE9B9CA
+:10E6D000A72D46DFEF6B9B49E5DEB67A7A3ED8166A
+:10E6E000A7F7E11BFD09A4DFBD6D4DF4FE176D0911
+:10E6F0007AD6AA9CDFE60B7C58E64DFB608BDAC32A
+:10E70000EB308E62E2CF89EF3AA0B81CDA37907412
+:10E71000C4F77895CB15275E5B5B836497EE929880
+:10E720000D9FD3556E47C6051CBFF6262E54E1F942
+:10E730006E7D5905D93D2C1E4339BD4B8ADF5209E8
+:10E74000FCF244F18CA855EE66051371356FA87C78
+:10E750004A178FCFCC50B97CAA676B0F65017CC676
+:10E76000A74C473A33E779B0462F42B978702DC0AD
+:10E770005381DF65566EA133B3BF59023E16CC2CD0
+:10E78000A787E896F37F7456F9368C1383E3199BB9
+:10E79000A893D56D6BB74D35E3DE3AD1B14927C0AB
+:10E7A0003F4F1447A81BEE2F3697F0EF3E4EE7ADD4
+:10E7B000FDEF507C2B3A8ED9E28D1DCD32F9393BDD
+:10E7C0005FE171E9E3CDA5DB2641FD1AC01BFAED3F
+:10E7D00039F3CBB21216BADE22E869A7379EA58DAF
+:10E7E000A2BF3A453DB3FCBC2FF15D5C97EF4FF8FB
+:10E7F000793ED2F34E57EA72948FADAF78F475300C
+:10E80000A57F04E249FC1E2F82F700D2F1FA351EE3
+:10E810009A5A90EF3FB4DEA46F3BCDC2E7A1989D1A
+:10E82000AF77B58E1E9736E1DE85708F129735E192
+:10E8300036D7E378FDA2816FB0E17870F69B337F25
+:10E84000D1A8E3DF897CE7213CECB2D25B518B4657
+:10E85000FB0C667B73BECEF6CEF90EE52B9CDCFE80
+:10E860004CAF8BE5E27A3EF0B7531E7A86E192C751
+:10E8700015946357A8895E84673A6BA1325307F2F7
+:10E88000915F5EF473FADFD9796F3EF1919A2A4174
+:10E89000BD70B2E375B078BC06F5564C8E59E5B93B
+:10E8A000F97C5C35E304698A1FD116330C29076EA5
+:10E8B0008A66C2F360FF45EA5BD6FDA42D8C713FEA
+:10E8C0003DEDA57D0E0C8868502E39CCAA36417FCF
+:10E8D0007B843CA951B95F78D661BD47E1F123A59E
+:10E8E0003164C1A388A79A71AC0E7613D3A0A95B3B
+:10E8F000AD3C80D54D3E6C74279E477CB9A33AED64
+:10E90000BFBB2209E22B26E2DFC5224E3F57C419C6
+:10E91000EF69E571C65616BFF034E4EB230A23FF16
+:10E920003871AA8D7F9DF33C20E8EADF85FEFBA5C8
+:10E9300090DB65EA01290BFA0FBD913E1886E7BF0F
+:10E940000939FEB090E307B7FD4709E6137424DCEC
+:10E9500031C469B8DA9F96C00EBD79FA1BFA3550FA
+:10E96000BFA37B523BE267C31A1E977F08E53EB404
+:10E970007B40C8FD704BE7B5B46F27E44B91992FEE
+:10E9800020E4499190278F6D7B7EC9069C5FC24B26
+:10E99000E3B4B2F49318D7676B64B253C2BDDFBB64
+:10E9A0000EFBB9BFCDE0FD76EFF917B4EF7FE84D70
+:10E9B00057FD06E3FFB3DDB124CAA9D4449B9C0AEA
+:10E9C000F7EEBB1EEB857B9FBA81F261041E3C8F84
+:10E9D000C07CA14AD6AD87D321A857D89F46B31B88
+:10E9E000D6B567FEE9D05F59834CE1EAFBA4F8F99C
+:10E9F00021A48746BE0F9D55B9682DD6EF5EFE5CFB
+:10EA000012DB8F7BBA45C265CFF997BB6A107FF7DF
+:10EA100014BDF6640D3C27B94A880E82AFE8F93F71
+:10EA200061D87F3C7A8D3E321D3EB67C354339E657
+:10EA3000B94DA67DFA7B6E5BCDBE61CDBB58AE668F
+:10EA40008C8F4D7279F87ED66D0BFB50CE9AFB57AA
+:10EA5000852BEABCC4FF4F33DBFEACB98F65B6AF84
+:10EA60009412935C79B45FC1F7B544FB02056D3C29
+:10EA7000285E27733E88A77DD67C93E0B5723C1351
+:10EA80003C335C2AC1D31EABDBFD1F309E3AE33220
+:10EA9000D2CBACDB0E87B31DC03183C3C1E133E100
+:10EAA0002806932008E3DF3AFFF97C84EFA3FA41BC
+:10EAB0007DE347FFBFE376393D01D6676BBB4CFB77
+:10EAC000F707AB0F7A118F5BAA6BFDDCFEE1749741
+:10EAD00023F8E8EE7A99F8F67835DFEF679F9EA085
+:10EAE000FD3097F89E9377D04B7B18492358331D00
+:10EAF000D30FCC3F96FC02C04D55D26F939F726BE3
+:10EB00008E2DDFA0981538F2564A87EAA3FF5D7F65
+:10EB10004442BD1412FBD165E6FEB6F24A0CE77F13
+:10EB200087A917DBBCF4EC6939E8D301AEC75B8079
+:10EB30004E685EF6BC144F33A37915B4F07DB62D44
+:10EB40005ADF0137948B6E07D4EB68CFF5927C6166
+:10EB5000DD3C5FC0DCEF98B8DC9EB752E4C8B71963
+:10EB6000969FF519FDCC6B5DF67CC3E36CCBE94455
+:10EB70000F7DA5B675E9391BDC9AA9C3FDCDC17E11
+:10EB8000853FC5A25CCEE5F8F81837DFA834A3BDF1
+:10EB900014BEB02ADBBA3FDAE9E276D2A13F7A1896
+:10EBA000C6E337D479298E63EEA39BEBBD1593AEF4
+:10EBB00030DFA1FD5E1FD2CBCE48293D1F9BF594CF
+:10EBC000AF9FE890E70378C49CD6CD7A6A7E33E0A5
+:10EBD000F5877932E9988EA2E7F2717FF1D63A2F64
+:10EBE000EDF78703FDBD8F4139F87D770CF7B7EF5F
+:10EBF000A9493759FDD7FB5DDCDEDAE112FA6A8BF1
+:10EC00007DFF19F86007F2812718A7FD4BD92BF279
+:10EC1000261C7E8E898FF0C17CB964327F964E1E91
+:10EC2000B2CFEF1474B353C8FB2D42DE3BFB29690E
+:10EC3000D60EBAD1EE5FAE552919F87242ABDD4E51
+:10EC4000286EB1E7D51436DBE93E142B70D8156970
+:10EC5000D263A63EDEE00B9E8A745F05FA92DB0764
+:10EC60009A6CDD6F77EAE33DAAB1CF45F6EEC9D9DC
+:10EC700009E140BC05F1EDB4730F097CFF4D310E85
+:10EC8000227E036AFC908BF240E324679C76C330BB
+:10EC90003819C0397954387FEBFA0CF6D358FB0396
+:10ECA0001FCAF11DCF00C873B298C8BB08911CEEF3
+:10ECB00008717FA5C3C5FD8477C5BCFECBA550BF39
+:10ECC0000382BEE604584BE67C321E2F7A1F0D13DA
+:10ECD000AC373E73FE2E5A2CF4BD30F3F7F75D7C53
+:10ECE0009F6DCE84D1C7F900C781E7EF54E31D972C
+:10ECF000651FE75197F19ECB12A7F8C8A5717E302A
+:10ED0000D743E4E79AF6D33ED5F8D8DADE7CE6CCF2
+:10ED100057693FF738F3C714C0CFFE7CB697811C04
+:10ED2000D92F097CFED147794026BE07ED6B941F91
+:10ED3000A8075E09A4309E62AE83B90F332847440A
+:10ED4000FD33DC5C9E00DD04DC347E9CEF17B234C6
+:10ED5000C9870241373B7D8B6FA983E7CDB3DE7C4A
+:10ED600011F315DE7ED8A7235C5BAB8F86AD729363
+:10ED700035DBE9C77CEFFAA890F6E9BF2525F2DD7F
+:10ED800016BBDE15197063FBFD924EFE5CF20F0A96
+:10ED9000D923FBA5D4E964A8A88CF633F65F134DFC
+:10EDA0006DB2EC7738EDFC1C5FFF1DAB70DECD6003
+:10EDB0002FB10CF12961A70FDA1D517BFBB89B091C
+:10EDC0003B1BA60B7C5D29E61D530D05E198C61281
+:10EDD000F49CC1747A823F50E586FA67B1817CE485
+:10EDE000A3758153CEE176C67F1BDE8CFF8D781B29
+:10EDF000A25BBBDE36F71DF2041E42AC85F6DF1FB8
+:10EE00006F5ABA71228CE72E0A923D9CD7D47EAD00
+:10EE10001CC66CBF3E0DFDCD3CB11FCE1671FD6C06
+:10EE2000EE4FE734D8F5B9537F7B84BDE11941AF8C
+:10EE30003BE5E6487A7DB9DBAED707E3C723C83F99
+:10EE400067FC786CF9A7DF525782791AC60B756890
+:10EE5000D7CD5629DE193E955D11B7D0C3FF751386
+:10EE6000D1C193E7CD6C027E4D9DC6F99CA19F1048
+:10EE7000000584FB09C5720AF36D362453F5987FAB
+:10EE8000B6419DA859D7B1A698DBB35B6BFDCD56B3
+:10EE9000BBF6753F8FA75E1BA8790AE9AA2298AA3C
+:10EEA0002577CF0047701CCFBBC4753B5363FDB8BB
+:10EEB0000FEB615C6F034778B95EA9D35EA7FCCC0A
+:10EEC000043B11184D2FD8F331F7A8A9757EC4471C
+:10EED00084C75F423B244ACE517A8D34E6724D0D91
+:10EEE0002CBCD3CDF557398E73603A98BB50FF8355
+:10EEF000036EB2737A43852ADA93FBE5A53F423B62
+:10EF000070E0250FC3FD94DEBF9F41E71A7A43E707
+:10EF1000CC433AE8951878B6307FE01F9EFCC302D8
+:10EF200018B70F9F6F308C5B0E3CCE6277C1F8AE86
+:10EF3000E84371CADB6546409E09ED7CAC0BF35794
+:10EF4000629FF8DF3B0FE8EEC160D5F6A96C280E92
+:10EF500060FAFFE7F9130F219C1DE3FEB319F9AC2A
+:10EF60000BE054C80E33A20877559E4CFCC7F282C2
+:10EF7000A989F0BEE670A40EF3D16AD44A94340095
+:10EF8000075FEFE77D8947B19F3AADB12E1BEA5786
+:10EF90001FD1C95E9917BDF61096A7BFC2CB1D6ED3
+:10EFA00046F620F22FB3F05FCD47A7D0FC0E0B3909
+:10EFB000DE1E35FA0C6994F5D054C7790E7B1E8B92
+:10EFC000950EB4E9363A48B8AC743013E860B2959F
+:10EFD0000E0CE9B3D0C1F784BC1D9B5F389F5CAFBA
+:10EFE00070BE194EF72DDE9C8AE1FC618EBBA93AFA
+:10EFF0002782FBAB261F68336ED2B0EC59E28E231A
+:10F00000DF997C61F2C33FBC2E820BF8E2421F3CC9
+:10F010001705F5B999F802FD382BFD5F32029F2CD8
+:10F0200060038730E77E81CA925920427E77F61BC3
+:10F0300065A758E8DE89A705B32576D4228F4E9CB4
+:10F04000E0650B1EB5C13C68E5E4F1FD9CAA774480
+:10F050002C7CD709F6331A855D728CE59520DF2D5F
+:10F060000D7AA6E1F98607A214DFF7C49B296F6D1C
+:10F07000C65B81AB810E3F1827EB38F90E7DE9FDA9
+:10F08000C4BF2F0618DA6D5BA72F9B80FEC907D778
+:10F090002426609C7323E0FF281937A9F132E5424A
+:10F0A000F58FE7FB657A943F1351FE9E89EF295156
+:10F0B0003644BD7EAA07EB6C9387DBBD9CBEB77B55
+:10F0C000B95DB8D1DDED45FE1A28F1D27EAA59EF1F
+:10F0D0003C85DB6DB33C229EFCE97A1DFDFB591E8D
+:10F0E000DE6E7B5B2AFEDA448473373D731B520C61
+:10F0F000F703FCE5491DE3F1DE752C91C9EEBBDD9C
+:10F10000CBFD7FEFC11FD03E526E598CFCCE480321
+:10F11000F46759AF05809A2C901F00AE8174DCA172
+:10F12000FBC90E5B10A9FDAB3A65F8FAE29FA39606
+:10F1300075F2FE4349F472FF8CFC8B35C29FAB2BFA
+:10F14000F5125F74B4BA7B702A8B3CD9DCDE8DD4A7
+:10F150008E9A3F8B7E5312D639057E133E717F23E4
+:10F16000791ADFDFC032EE6FE013F737F089FB1B4F
+:10F17000F81DF737B0FCF33683CAB8CF8165DCE7FA
+:10F18000C032EE6F6019F737F0B9AFAD999EBF6A24
+:10F190006BA1EF8FB4B552F93C0FB7B3597932BABE
+:10F1A00010F0DC7583DBC07DEBCD627D1E334A73CE
+:10F1B00063B08EBE08F73B7D4FDFCA703EBE288F1E
+:10F1C0001775466F6557C2B36B5AA80B0359DEFB20
+:10F1D00083F4F4A9DB19C60D7649C9668CD0ADF667
+:10F1E000FCE27C15F47359F4DADA1C28B77A1E595C
+:10F1F0008F793B93F4B5B1A5DA50590F552D7BC0EB
+:10F20000529E50D1A3FAA1FE7736EC5F8F7C8A70B4
+:10F21000A0F1B6C173E0FCB5B0E4E95246E73706A9
+:10F220004ADC29A4B3AB70BD2622FCDCAEBF88AD9E
+:10F230008FA29F3C417757217F40FD34A7CB93ABF2
+:10F24000BF1937A9A60D6F375A3DB9FAA4EA31653F
+:10F2500094FEF0BB344A3F1D6CBD8667C936232F30
+:10F26000633E912F407E5A978BF365978F3FDFF473
+:10F2700072BFECD7DEDA8BBCF0BC48F069972F5E2A
+:10F280008F71CE81C932C50B7A5DD00526E5B69661
+:10F29000FCBE14C6FDD6532AC3B8F35D1E6EDF4C08
+:10F2A0009C10E2FAF2DB5ED297174CF8597B0E9471
+:10F2B00027FE381643FDB799C5FC4827C92D3C6E7B
+:10F2C000FAAFD5A7E63442F533A73D9C43713FC161
+:10F2D000DF293C6F04E5B51D574FC038C707CF7213
+:10F2E000B9F480A0B71E575F0BADE7B420D90D8CE1
+:10F2F00075935DB036AAD2BEBC9CCF9F6E97F615B3
+:10F30000ACE706C59B0478DC7F9FE125FFFB238FDC
+:10F3100038A7D647F682DB97D0B2E17D7752267EBA
+:10F320005FAFF953988ABF395845E76693152AE5C8
+:10F330005D6FAEE0F1B940E8B214DA09B71CF071C4
+:10F34000F910F452FE55AA62EFE1DA083E650DF9B4
+:10F350003D652CAC27BC6BB246795CF037FADE1CFD
+:10F36000A13CEDCD4CAC4BB34C7E60C7B84F7E3367
+:10F3700015F7BBBFAEC5C4D921CA8324D346C67313
+:10F38000BC03070308CF57CD7347FDEB0250BF7D89
+:10F39000A916C37598A2D5D6637CB043ABF5225F9E
+:10F3A0000526D77997901C1ACC53A6F36DED15DC82
+:10F3B0005EC5EFC897AC9D1DC2F32C85429605B281
+:10F3C000AB24B4733A1A286C8479BCB6BCCBF69CD7
+:10F3D0000B29AF5D599043707630C38BF5930D2A9E
+:10F3E000E9A5C2A0378D765CA11937C494638B1F41
+:10F3F00091BBDC9EB79CDFACDACE758C4FD8CB7955
+:10F40000C22FC873E4377FEA31F755EC7872CE37F4
+:10F4100037725736C29B8B0795F5E1F3D91EA96A5F
+:10F42000C479166A7E823BAAADAB41F9359EB5AC74
+:10F4300045BAFBCCF03AE09C52D1DE87EB3E455713
+:10F44000E91CC35436B00EFBDD2CE8BCABC4AE27C0
+:10F45000EFF228627FB7B6DA3B8DC7B99296F14BCF
+:10F46000927E96B48C776A578EAD3CB1BBC056FF86
+:10F47000B41DA5B6EFA7A7CEB07D3F737795AD3C81
+:10F48000B97796ADFED47DB5B67265FA425BFDB331
+:10F490000E2FB495A7F57DC5567FC68B4B6DDFCF7C
+:10F4A000EE5F66FB7ECE1BAB6DE573076EB4D537A2
+:10F4B000ED66A75E9CE2FD7CF6B207CF79D9E282C9
+:10F4C000767BDC694F7BFFB15E5F87722DEC26FA9D
+:10F4D00056518F4379F50DDC9FF1CE89E92857CA43
+:10F4E000845D931534CE41395A13F6923E5083BC55
+:10F4F0009E1A9C4776C7293B401E9D8556201BFCC3
+:10F500001E40B9DC968C97B986E0F669DD7466A179
+:10F51000265C4F7175B3BDAA192C11C2F1746ECF60
+:10F5200080B788F57C3AB4B7CC63BF2CD311EF0118
+:10F53000F0BBEEB2F85D23F9594EBFEA64FDA85363
+:10F5400064E6C7678F146FC16745CBB3B5985E0794
+:10F55000FED5158887ADEE78730FF4BBB5D4CFF721
+:10F56000C1847FD555D24B7C3150A2927E61AA5E78
+:10F57000B1D012DFDAE4E57A25E0BD83FC3BB57457
+:10F58000E6611DF1BE56A5B8C36689C74792B00EA5
+:10F59000A8D776CD7AE39DEFC07B6FA9B7D00BF2E9
+:10F5A00028F698DBC0FDCFED02AFA55A652D585C5B
+:10F5B000605F341EC4E7241DEC0C7896976F3B887F
+:10F5C000CF9BBC3CBFEE8CD803B5284BBC73B8FDB9
+:10F5D000A74C71A7D6E1FA691C8E91E84CCDD9C130
+:10F5E000F7A9CAD4D791DED0DA3E210FD1810FE935
+:10F5F00040A227D18F2F1224BDE1C38D1C2CAB520A
+:10F600002A00DF23658684791735E11DB4EFE64BC8
+:10F61000DBED55F03737215E230DF6F50E787711C7
+:10F620007CED128FBF7665EB4FD702FC5D79A53973
+:10F63000183BC1F844A345DE6C17FAF42B3ED9D42D
+:10F64000FF246FE85CD7B4217B07E87F877C2AC260
+:10F65000D7CD506EF96EEA6648EF3E0D5613EDEDCC
+:10F66000EF2689FE4D7BF73AC15B75A54DB4DFF5FA
+:10F670005EA48AEC5B5FEBCF33E2CFD7AF30E3AC75
+:10F6800091F11A9EB493F43D2B75EB6857B4EA6E72
+:10F69000A327833CA8F2703B6623E67D203C22EF43
+:10F6A000A34BE0C3DC6F7BCFCC8712FBBCD76533A9
+:10F6B000DBBEDF757955E347B3C77DE0F7252CF056
+:10F6C0006E8471102F1D9F36D6C769FF8FF1736A44
+:10F6D0007FAFE8A1F3C0C27FA91276D22C0A9A01AB
+:10F6E000DFB819F909E763FCE22CF4362FAA47BE0C
+:10F6F00034E31DAF7973A85E2CC99416B2575CA68B
+:10F70000DE924F4C259875B719A7249397EB35F8DF
+:10F71000F7009EAB38B5CB7E5E6962B7BD7CDA0E72
+:10F720007BF9F494BD0C56F311B40B1A19C7CF9999
+:10F73000BBEDDF1BCD385F1D3F67E185914F70FD4D
+:10F740006B3BD7CA84FE37E3A9C5BDE91A14AF45A0
+:10F750006BEC7AB540E8F90287FEAC0A29E4E7D7FA
+:10F760001C8E1C42FBD18CBF3CEFD36DF96F661C25
+:10F77000C529CFFDAF6C63F085FCE58487C7171200
+:10F78000E0DFB41689B845317FBA14FD99C564A786
+:10F79000B59C86F2E9D7DEC4075E325AECE720DE7C
+:10F7A000AD571F97743E4EC232CEF5E5C90BF8F443
+:10F7B00053945762C6314C3FFD1F01E322E4AFCDA5
+:10F7C000B1E75A1EC338D24B1E86FDCC559E3EDC97
+:10F7D00006E5D5C52AE5416A3396FFC88F7140FC1E
+:10F7E0000EE59A127D3CD1FF932EF2D737087A3678
+:10F7F000CFE798718F5C9FD03F3EC9DC87F08B3C90
+:10F80000573FDAB967EE06D96CD3733C9E66C6CD16
+:10F8100026F7DABFF732295783F59BDA9492B95D60
+:10F8200065046B2C71F533C47A4D599CBE753194C7
+:10F83000EF63A92ABC2FA252D045EC90FD3CD838EA
+:10F8400026D1B981714794580AEA4F79C4FEBDC2E6
+:10F85000715EEC0CE7F931479C37A4B07796C0781D
+:10F860005BF41609E5E796C560C343B9C227F28782
+:10F8700027B149487F7395602C8DF8FD83427AC388
+:10F88000F3EA692F2C417DFE2CCF4FD14ED5B7D551
+:10F890004159FB8D42FA490BB0CACAE0505CF87B73
+:10F8A0002762ACDD351467DA03EB5A3611FD6B2F96
+:10F8B00043BDF273585F2CF7823F8EE507C11FC727
+:10F8C000E75EF0C7F1FD2FC01FC7F23EF0C7F1F9A8
+:10F8D0002BF0C7F1FD23E08F63F9DA404D8D2FCF78
+:10F8E0001EA7B2C6ED86E254FD9219A74251F2BEA0
+:10F8F0009BD3FF60BC2AC1E35563F76398FD503C7E
+:10F9000070583F222EF8F60DFF792F9E9F5E316DC5
+:10F910005D179E83F5BACCB818CF7F30F39A4DFEB1
+:10F920005BB1F75ADA0F76E71F69C1F5D85B1DA402
+:10F930003B86DCAE8486F2D1E97F997E97D3FE3593
+:10F940009F4E7DE4473BE02CB493BA29EEB3C9C582
+:10F95000CAE95CACE48F215F38E390261F3FEB2BB4
+:10F96000CD789E69303F56C4673C2CE5C578995BDD
+:10F9700012F314F99B24C2A08BCDC8CF967CE36010
+:10F98000459AE21CC1A041F697047619D9695A221A
+:10F990008A71A8CE11F26177093E5D9BEFA67B24A8
+:10F9A0003AF3F9FE7F5D512C8AEDD7E74F8F5AF37A
+:10F9B00063CDFCDD43A1E9DE7E4B7FAB43A5A3EA2B
+:10F9C0002905F4AA3E8A5E553C3C7F7DFDC1B3BD4E
+:10F9D0009897BC29B8B40FEDAB4DD1089D5F3F900F
+:10F9E0003F9DEC8FC1FAD19994BFAC04B9DDAA4414
+:10F9F000BD64B7AA38FF8AA1FA66BD1B857C06F6EE
+:10FA0000A3F85C20D84BF53C6A9CE21F9E08A3FD3E
+:10FA10002A8F97E70B04C1BFF6DAE2A6421FFBB8B4
+:10FA20007CDBA427E2D86E5354D5511C6D2AAF223B
+:10FA30003CAF17785E9F67EAFD18D91B0F0A39683B
+:10FA4000F6B35EF8EBEB9BDD6477C55BB38DBA5C18
+:10FA5000CAC7FC09F2DFA6E05D5ECC6F77E7578F7F
+:10FA6000DAEFA363F6FB6A6DDD59D4EF83187F7676
+:10FA700087966AD8AF6B84BCFBA7447F9FD7BE0430
+:10FA8000CC69B4DFC54C7D9B8A5AF7899D4F3FDA1C
+:10FA900089670D6FB742EF9F8779BF2A4BD6FB95D9
+:10FAA000E1E71656EEE3F7506D55FBC8DED9FAA92B
+:10FAB00094F1FC43B6DFD43F837EB8CD5E2914FCBD
+:10FAC0005428BEEB68AF94A05F69B72FCE3A6C2F75
+:10FAD0004FEBB39767BCE8B4578C3FA0BDB248C8A2
+:10FAE000BB3E90CF3C6962404539104FA66A10EE8C
+:10FAF00046D6BB16F7295D22CEBC48E8AB8BCDFDC0
+:10FB0000477F36C15FD8ECB7F989E67D1A45A2FF79
+:10FB1000E2BA43D7B6A3708D9BF68F4EFE65F1FC1B
+:10FB2000076B484C3AECA046C37E1EF562879DE306
+:10FB3000B4876AD41ECAB72C70C41FCC7D4A9C27D8
+:10FB40009ECB758EFF59C735FBDB097A0BED15F39C
+:10FB50009E02BAC70BDA17AB692916A4FC2DCAF3AB
+:10FB60002B5CC38C9E0C743CD3CFE5DA30BC25CF24
+:10FB700023BC9D2FDE1504F93D2805754A4A2FE167
+:10FB8000F95F284F162E87F990BD7C82F6A1CDFA39
+:10FB900039D9BD942FB6B341E2FE6392911D62AE96
+:10FBA000F3CE203F3FD378AE9492B17D4B298D4F59
+:10FBB00070950EAD2FE0E928C713CF2FBBA4DE7ED2
+:10FBC000CEA7D1616F98F470B1E3FDCB3E7E4EDAE3
+:10FBD000E483B7CF7E71D22900C70A29591F504E3E
+:10FBE0005E4F5AF8C37502F910FF3E8EA642FC71B3
+:10FBF000D0FB9046F901D9FD773020C9063F4BD69E
+:10FC0000CD06BDE81F385382F225FEC91D5DE7E22F
+:10FC100071C5817F45A3CCE3A99A5B5F3C54F6FB99
+:10FC2000E7503922C601D722C9D7DB726F01C0FB6A
+:10FC300003911FB0D960DB14CCAD94B56DB192A126
+:10FC40007639D84E1AA55D9C6D5333B40B9AED00EE
+:10FC50005D9DE63D1FA5F8E4DF65018F757C15F11C
+:10FC6000A6E9413AC7334FD530EFE18BC2316EACD4
+:10FC70007927D836D7A9C3DB01D86B4DF8E5CCF08E
+:10FC8000A7F0BB757CD728F0FFB3F131567F6EF13A
+:10FC9000FD33C307D5D78D1B79BE08978BEECBD02C
+:10FCA00083B2A59F5B0E7C4CF16BF57246E77454F2
+:10FCB00097A1C580CE2BB4DBC80F57B3EB34B40388
+:10FCC000364219ED808DBDDD14A7AE28BBB50B897A
+:10FCD000BE22ED67280F26332DFB3EE877B2A662E1
+:10FCE000260E53CF3D2463DC9B7D89D13991AC0333
+:10FCF0007E7EAF45C9AC1FA37F949DEDA5385020F3
+:10FD00007BFA8FB9B1CBE3C126FC819A23B51827C2
+:10FD1000571B590C59519552AC0699EC7446FB107F
+:10FD20007E63EFF578DE12141FE927BAEB01F5AA1E
+:10FD3000888B8FE724C3BADC5A23FA09C9A7548AEF
+:10FD4000BF8F47D31488B2A222671BC25391800E83
+:10FD500024849FC7B52627E4581AFAAF7A87B76379
+:10FD6000BFE5E703C097687A3838845753AE8C17DD
+:10FD7000F1F2E8627B3C990DC09CA17DD56F17DE46
+:10FD800083F18471C3E437F7AFCD7B74B2DE61F1E8
+:10FD900087695FD3AE37FCE2BE0ABFE31E8492A040
+:10FDA000CB768FC130BFE1BB71D2031E16F3BAC947
+:10FDB000BE584C7683E98FECC48A18FF2F66FC5E30
+:10FDC0002B67FBE9BC3D8B72FFC4E30733AF0ABE70
+:10FDD0002FF31BA46F3D50063C4A6EE6CD87F70516
+:10FDE000328F8BAC95988AE5A1F1D2B44FBF418A8E
+:10FDF00075C5A421FF77BD16A3FC01B626C7662FE3
+:10FE00009B79A8ABAF29199F03CFACA1F3401AD2BD
+:10FE1000E3EABC32B29FC3B9FDFF07E5EBFB9B36BB
+:10FE2000CFF5A2FCC4FC8559F05FA0B32309F2D63C
+:10FE3000F35121D32D7699476DA13898E7A3536CE0
+:10FE4000EFD36DF6F3834650AEC371C607747E2EB2
+:10FE50008369EDD8AE86D9CF097A3ECAB7D9E943CE
+:10FE6000FD17D9DEA7C19EB1DE4F3172FF01A69703
+:10FE70005BFB3F7584FE2739FAD732F63FD46FAE6D
+:10FE8000ADDF0E95C74793113FADBBD31E981AA89F
+:10FE90002D0A4C1B257E1FE0F1C70DD1168ADFD736
+:10FEA000326078A093F33E3DAAF0F36C8CEC3656AA
+:10FEB000648FDFD70AFA958122907ECF53EDF782C7
+:10FEC000CD61CE7BC2ECF6D073C82830AE1CAAEE52
+:10FED000A338FEC7411DFDAF91ECE5BE3646F1E308
+:10FEE0003981FEEB709FFA82CD77BA3A668AFCD7E9
+:10FEF00002C62EDDFCC05CB4EFFBC479BD8E884C1D
+:10FF00007889D78EA7F337663F71379B88F2302EFA
+:10FF1000F3FC04FA03E3F7E515DCB52903FE9CE7DF
+:10FF20003B1B0D295E66A19B3E19F06A1DEFFCC2CA
+:10FF30001EC5328FB8874DA3F1849D3B38DEB8CF04
+:10FF400037DEB322EE648ED738CF3EBF46B746F3D6
+:10FF50006B14FC6B8EF72CCE2F037EC71C4FE67400
+:10FF60003338DE05F6F9357A349A5FA3B8E777704F
+:10FF7000BC719F6FBC0DAE9604DA6DDB24CEFFDD45
+:10FF8000815F75E0BABED7B03A4AFA40D8C5176368
+:10FF900003A877B1CAC75B50E44DADB58CB713E485
+:10FFA0008021F2DC0D0FE66F68544EB545E97917F4
+:10FFB000D8D906E56F94D3F77BDB6254DEDD369348
+:10FFC0009E663FE533F9BD33A7CF9632DADB870370
+:10FFD000DCCFDA96AF5D7E15EAA51A3F3F0F39F305
+:10FFE0001C6658EC5F30880FFA70FFE5325689BA0C
+:10FFF0006DD20E0E77A46E5C0AD7CF5F79A8AF0DD5
+:020000021000EC
+:10000000CA1E974B477D0ABC10CFE4A73E16E07E80
+:10001000B8C7CDE53D9BC5EF315C20F40A531A24E7
+:1000200017E2E3E26CDAEF5FB8C8086980B745927F
+:10003000F48732A1A7F0DCCAA562A99C767E0435BC
+:1000400006F41B319414DE4F7469D1E126D4CBF150
+:10005000D025E41FC4A1610EF473A9D09335AF7A03
+:1000600018E63BB0B96E8263D122BB3DBFCD97D6B7
+:10007000D03ED9561961B83E0B1BECDF3D6ECE87E2
+:1000800071C7BD050BC6B8C780EED2CA9047EA8CCF
+:100090004F3E1AB0C7218FB38A5BEAF0635164D434
+:1000A0007B0CD6609BBC21FD369C8E393CAFFB9906
+:1000B000F0DBF6513CCC84AF404D4928AF0B9BF7A9
+:1000C000D9F29A00B1640C9B7178A6DC57897E88BE
+:1000D000733E3BA5FBF247BBB7A480A9AFF7978B54
+:1000E0007B3DA5E1F37E2520F26F07E73DFB9932CA
+:1000F00096897F78DC75C16125B6561FC28B8987CA
+:10010000FF693EEA12787FE6FCF7ABB9FF5664BBA5
+:100110003FD3BC17F892C1B2CA540B3D5FBCCC4D63
+:10012000F60C33062A90EE8E9C1BE0F7B899F64B3E
+:10013000FA2519ED972FDEBF516CCBDB14FD8EB481
+:100140005ECE3C42CB39D0A13C77CC2F91F83E56C5
+:1001500001E6B985F9FBA3763BD396E7B6FEC04F1F
+:10016000258CF3DD81F978967DEB42F0E7516E1630
+:100170002DB7E7D539E132F3AA06CFD1CE5EA4DDA3
+:10018000A7D3BD89DD78114DD78E649C59F223CD5C
+:10019000F381A63FED3C17A804F9FD795171DEC249
+:1001A000190FBE5E4E6A2512E6A3A6BC35F09C92DE
+:1001B00093A8C2A3EAD72BC97A7CAF8C9FD58C7841
+:1001C00058DCFAED18C6EFB4DCCC71E9C5427F9F6C
+:1001D0001BE4F18E575CE9628C632FCDA93D373863
+:1001E0002D43FDD6EF527F7346B88FFEB220A7BFD6
+:1001F0003B843E777EBF588CF3E51532DD6FE163BB
+:10020000A1945482FBC6DD33E93CDECA9DB14CE7C4
+:10021000DE9E0A2716042D71075F193F7FCD58EF28
+:10022000D988AF8D7FBBB3F77E4065CEDF82244790
+:100230007314DEAFA5FD6599DAEFFFF8793AB7BC24
+:100240001FCFA9A09DCCEE9887FEDCD6C1324B4AC9
+:10025000181FCC16E5642BFF3E58AE9A578365A451
+:100260004120B29782733B915EB64A4C10E33C5EEC
+:10027000DFC5EBFF427C9F73E15B3FBE05E5FD748C
+:1002800037F9815B853D62C2F77290E7CDBC3C06D1
+:100290003E5BC5F720E233F299F0D99A091F2FE7A8
+:1002A0001837E0BAFB30930240F0FDCDBB06F3886F
+:1002B0007FD0C66257C11CEE88EDFDE92D8CDA2790
+:1002C000ADF461B6BF28C7581B24788ED2FC4265B6
+:1002D00041746FD8C6198CFAC900C7C64CFD98EB9B
+:1002E0007A308BCBB10FD1769E86EBCAED3FC5D36A
+:1002F00017C5FD7FADFA7BD76920473A4BBA9B32D1
+:10030000D1F7F7437C9F3A7B8478F5CF053DBEA4B7
+:10031000C57F8070B46BB7D2FDAA6E89DB0D1B67F9
+:10032000F633C9D2EEB7218E6F80BB07EBBBCFE6A9
+:10033000F79E8600EF986016AAE6F06FD48F30CC57
+:10034000EB0E458F505E68A8BA9FF89D8E2A1470F8
+:10035000BA427FCD2BECB39F07BF320FEFDBC85102
+:100360004CBA7BAB13E946192A131DF5E4F0F6BF2E
+:100370000FBDD5990491BB0BEC17BC872359C0F373
+:10038000469CF3FBA5807747D8D88BEB320C9F9E19
+:10039000FE1FDF02EDB74EE4E76DE6C87D4D572244
+:1003A0005D5E1824FB0BDE3759EFBF795DE0EBF59E
+:1003B00020B79FB67EECA5EFCEF518895E7F27DAD1
+:1003C0007F0E7AFD5D263A017A7D06E765A1D7F7B3
+:1003D00059667A7D7E047A7D21135E9C6585193B82
+:1003E000707F56FD64DE6EEC4FBD68F68EFBE1A9B2
+:1003F0007C725392563326D9CE979AE3544A893F5A
+:10040000072DF2DDBC9FFB9B41DEFFB07E674CDF1A
+:100410008172EC24FA1DC0F938FBDD1FE4F0CEB97F
+:100420003098C8746FD1CE10CF1BBF5BCC6B24BE8D
+:10043000792AC4FDD991F8E681D020DFB050DED80A
+:100440007CF3AAA80FEBE0C5FA63F3CD6DF4F49545
+:1004500071BEA163C8B386F30D4BBE487CD259C2AE
+:10046000F9227FEB9F3B31CE31C847C90FEC7C941A
+:10047000FCC0C6477FD9FA01D577B60F8F704F956C
+:100480003EC8FFF109380FE34CAD9D9FB3E927BD8E
+:10049000DDC3060E7828CF96E7B5FA9349839B0D06
+:1004A0007D0CEF3D2C1778D8853E18FA39D3459C42
+:1004B00049ED630B43C3F939549DAEB6DE23F06BAF
+:1004C00031FE47A1F8D4D0341CAFFF74B4BF465AF4
+:1004D000A76A517F5BB6511DCA40D763E9A1CB43E0
+:1004E000FCBCEBE502EE9CBF795BD0FE74F2FB9C9A
+:1004F00095BFFAEBBDA3F4739968BF20F4B9F97FF7
+:10050000412833FF5F1CB2F37F35DEBF9981FF2F97
+:10051000CBD41EF8FFCBA10CFCFF05F8FDCA50069A
+:100520007E9F1DE2FD8F85EF7B05BEEFFD82F86E9D
+:1005300017ED6F0A7D6EFBE0A65066FBE03BA169FC
+:100540002785EFF611F0DD1122781E24F8437A900A
+:10055000E2D85D33D85EA934231C5BADFD7875DE2F
+:100560000FE0FD7D09E87ECE275DB14CF7CE40BBA4
+:10057000DBACF09BEDAA439A99BC7D2DFAE7775C42
+:1005800014A4783FE8C71DFF643AB83B94413ECFBE
+:1005900091B91CFA20F820D9815FA0FFDE4CFD2F15
+:1005A000137436965DF098A00F98F7BF85A60D9747
+:1005B0007F3DE27752768413FB4384AFFEF928AF88
+:1005C00076DD9823613CAAC8484BE827EC15FA660B
+:1005D0007248E7E71944BB5D6A5AC27C965D2D9A62
+:1005E00084E78D2CFD1D0E4D1BB93F271C00DF6FCE
+:1005F0004224EF8CA7B15DF5901DF899ECA44BB2A5
+:100600008D2321D23FF1E7496E9F6697DBE63CE4FC
+:100610007837E5BDF86666FE1D97BD41D594FF7F2E
+:10062000B2CAFF17429AF9BB52D4DF67D53F00DF49
+:100630001B02BE3733C1E7C4CB58708E177A1EFA3F
+:100640007B3F939E72F667FAADE63AB9512759E2BD
+:100650003A5278D0EE656194DF1D329D435A20E412
+:10066000C98299D9C26ED7FCD8FF1D224E7EC7F22F
+:100670005B6B70BFBBE726AD125150D0CCF59EBE70
+:10068000FC148A7F0644BF4EF807DBBB7B4FC77B59
+:10069000C761DC2C1CF7BCD92C8D7E6316DA0D14D7
+:1006A0008FD0E877BC723CDD518C9F6E94BA9B96DC
+:1006B000A25E9D1FE4E74AA28BC6B8BF6D9D8D6EFA
+:1006C00059B47A8CFA6BA9BE16E8A6FB2F4EBABEB7
+:1006D000A7BB29537E492C2C9B76D199A3E2351ACE
+:1006E000A1B89689DFE1E3F0F5AB89B74888EF5010
+:1006F000B5A4E1D1AB10D009DA4B72591FE5337DB7
+:10070000A99AD30B03BF64F4FB333ACDF59E13CE05
+:10071000FBE27099F5461E4FD4739C57C07D2F8A1B
+:10072000CF06B91CA38A507EF7706EC6B8BFF9DC3D
+:10073000D0A615A92E6BFF29BE3F33983F1D8BA273
+:10074000BDD5CA383DB2A897EC30BAA7DDB29E4BF2
+:10075000C3DC7FFC4156FCAB61E2EF18DD4BC834D3
+:10076000EDA4E603EDAEA2762AB40B9D7CBB919F6F
+:10077000E6EFD7C5F4B8E51E34935FC727920CEFB8
+:1007800099F157304D82F58F84CC7D424E07B705E5
+:10079000CD729236C9E365DD3C2F5F37E984CB1516
+:1007A0002DD06BC8958C6DBF79FE05D1D3A1BFB29A
+:1007B0004414AFD487F213788F5A8EC2CBC0684FDF
+:1007C0001C227DA19D21C5404FB5CF7DE27031E354
+:1007D00047A5E8F7D5E63E81F9843D66192FA428A0
+:1007E00087B27FB06C78A3502E1D2C27B1BC4BE88C
+:1007F000C9ED37CF7DA23D4872EC662B7FD4083A15
+:10080000FC67D35F8FDEAEE13983645425BB6AA3F6
+:10081000831E7E157613FEA76A8914F2C5829B0695
+:10082000543CBAE22D8984901F2644DF4FE2FD79C3
+:1008300013668B34D5327E4F434F740DF1650FAE86
+:100840000BE36909189F1C5A9F54E6F5294FD1FA0A
+:10085000F875FE5DC632F9DB3CFE1628E7FCAC7984
+:10086000787CEF2141AF07C33C7E7450C8D7AC6899
+:100870003BF953DE7A99E2C759F5B24D6FD02FE0BC
+:10088000517DD5466F2FE724F6872D7A01962F5E8E
+:100890000EF3F09F1EC9C1FD979A72750DFADB3FEA
+:1008A00012F61FACD30F495E5446FC0992DBF1C728
+:1008B00033AE9BC0CB58EBF67C5B2256E71A79DD52
+:1008C0002EBB9CE7D33BDFBF28E4EAB1A63F7F0FF6
+:1008D000D965857780EEF3EE2A5B4B715833EEEAEB
+:1008E000D95B932ED487F201D705C2B3E95C8A6342
+:1008F000DCE73FFDBE46E7443EF664DC4FFA87C0C6
+:10090000F391B6266A070B4CBFBF72054E85E7B15F
+:10091000D9CEF199E711BEC638312C8A2FF912CA07
+:10092000A1A54D0ADDDB7005B3E7537CCDCCFB6A96
+:1009300035F3E378DE578265CF43365C9274FC7EF4
+:10094000048BCDC373F4C37E5742EC6F7DDD9137CA
+:10095000F1E5A625B13A51EF3DFA7F8AF0B748E7B5
+:10096000F277518CDFDF7369FCF2589D653FFA85A1
+:10097000BF2B19F3262FCA32F1118FD54D1C8E8F44
+:10098000A571C9ADE963E3E564F1B044AD9C97A7F7
+:100990000FC78373FE80B1AD88E7AF039ED1EE1C15
+:1009A000091F508FD6E385CB15FA3D99794A830B01
+:1009B000F741AE6C94688F09F01B1679710D732D99
+:1009C000F03AF1E8C4D7958F323A3770E5ED218AD5
+:1009D000B73D67E2277D1EED5F98FB2796791EE500
+:1009E000F95B1ACD73E1CCCAC7F1DE84443B485BA6
+:1009F0003E5FDB3EE05216CFC2730B30EFA323AC59
+:100A0000BB6D3FD0099F137E9FD02BCE7D31A6A614
+:100A10002B500F1A59625F700A8B89FDB12C4AC79F
+:100A20002DCB2C6F9DF7CD997476456BE3E0B8D84C
+:100A3000BFC41283650DCF6B3DA96CBD14FEBE3AD9
+:100A4000CA7FD7307E796E077E5BC0CCDF1B3268F1
+:100A5000BFE90A81BF46F0F8F0B7D0CE03E184FBCE
+:100A60007A0B0C9F1EB4CCF3DD6EA95E9CA3CA5A10
+:100A70003419DB250F285386C3BB3ACA7FBF10E861
+:100A8000F07D2B1DFA26F27B659D7831F175659618
+:100A9000D8379CC2A67C16BCBC848A731AEDD7904A
+:100AA0009D3B2079E93CBCB98F037F4DBA4174B6B8
+:100AB0006695083B80CFDBBCBF8BB116B2EF178BBE
+:100AC000F358AFB858D30341BEAF5365915B37E4D9
+:100AD000D4B46659EC6E735FC7BC2FCAA4E7AF7974
+:100AE000836985D3A1ED3EA8A13CA604E53129592F
+:100AF000CB75C447177E3A9BEC9EF5D8BF12E0FB3E
+:100B000055BE271FEABA541F5ABF4D573DDC3D0D55
+:100B1000CAFEAFFF3E499DEA3984B79058B71AB173
+:100B20006E267CFE0AFEDEB27E3C7E562EE26762B8
+:100B30001D47D213E63A9AEB867614D2AFAF5CFD2E
+:100B400024D3EFF0B143D503C8A789A84A39740963
+:100B5000E9B50EBA678BE9BB70FFFD8A5697EDF7D2
+:100B60009712784E1FEB6FF409BF2446ED97E6F31A
+:100B7000F6AC9CDB8D83749F84F6963C20E60D8F4B
+:100B8000C375EB87B6982706FD8D437DCFBA2CE35E
+:100B9000940E1F77C4FE1CED94C17D93582C669172
+:100BA000D70F65713DF96EB4BA57CE107F319F4BA8
+:100BB000BDB945AA253FEC68BEB729D3BDA4667F61
+:100BC00083F7C60DDA896F3F71A868C84EDCEC7AEE
+:100BD000C36E27B237BE909DF872D61B4FB4033C4C
+:100BE0001FFED143FAEADD7A3FAD436EEBF9ECBF6D
+:100BF000F0BCAD8ABFED47F63DDD7BE36D2DA4F97A
+:100C0000482A600E7F1F4C8F4988EFD7F0925E8C88
+:100C1000DFE92C1D02E072D59884F8BA55F8A3409C
+:100C200067A75BEF677D2D8BDB5BE6381E2F4BE202
+:100C30003963B35FA083B59457DAC0488F98FBB08F
+:100C4000263F9BFD0C64D9FDE093E0DF814CFCFB6B
+:100C5000B4DCF2A7EFA0FDFA9442F9A05F8DDE406C
+:100C6000EF2F6BBD929E97B75E43CF4FC478DF9254
+:100C7000129F64C17AF535FDFEABD703BDAEDAEB4A
+:100C8000A173652BBEF5D79B913FBDADB0EED8EEFD
+:100C9000EB57DE3E0DBEBB27CA64BF7615F37C0E54
+:100CA000F75A89C7FB75773DC650FE3F378B9AA828
+:100CB00000800000000000001F8B08000000000002
+:100CC000000BE57D097C54D5B9F8B973EF2C496662
+:100CD00026933D210B37842548C049202128D60979
+:100CE0005B632510C40525C0844008109280568798
+:100CF0004A654200A3468D75C3A5BC8162ABADFABF
+:100D00008252A56DA4137101A518ABB5B820417826
+:100D10004ADD12411EA3D5FACEF79D73927B6F6612
+:100D200042687DBF7FFFBF177FEDC7B9E7DCB37CAB
+:100D3000FBF9CE77EEAC7096E4BA0A09F90EFE2EF6
+:100D4000266485731A9649AAD3448A085963A3FF77
+:100D500056093973F8E6D4C5898444DBED6EFA840C
+:100D6000581AB3EF34D132D92F9347289063C8A2D1
+:100D7000F23C0AAD0C0E712984240134218C074801
+:100D8000FBB585244212A09DDBDD60A765C54F5CE5
+:100D900000430A3EB74852795B5EDF7C0414FDD9FC
+:100DA000423221E3613CE3FB167C7E8B6A2985F7A6
+:100DB000E504360FF17E0E7F3F87CFC7168A61F3B9
+:100DC0004830F6E364CF65D2D066EF3F8FF5B1537C
+:100DD00047B992004F9E5C80847499CB1D842CB4DB
+:100DE000BF72481A47A1CD1E9429243EF3A75DB9CE
+:100DF00004FFBE1B06FF5FE1FA700C2112E992BEF0
+:100E0000A343CFFA460A0EA5F88B2A91031BB229F9
+:100E1000945C651326D066256637E0B37378A263C9
+:100E20009866FC0B5C12E2EF75C5E58079964F97EA
+:100E3000CB0379D87DD2E5D0CFF4AAA25BD97036A6
+:100E4000924CC822F66FF2BABAA37918ADF7FBCD6F
+:100E5000EE11948E8B6CFE00CC6F1151FC5D366CE4
+:100E6000227D2721549522FE1E9DEFA269B227CA3A
+:100E7000A96B47BEA3F3241BC90BC369FF0B253E17
+:100E8000809F96E97BEFF3E29169A7AE80657411CC
+:100E90009765186DBFB0AB722619875576E0A7A588
+:100EA000BCDD229FF9786FBFF47F957E7D797171EB
+:100EB000FE4B940C142F81D209C067A34DC867550F
+:100EC000CDFA764BDFBBE46FC409FD2AC77BF10D79
+:100ED000F32477313A4F6F72A9144FE7BB542CCFEC
+:100EE0009A766C1AA1E5D9845C01FDCE9E26BB8260
+:100EF000B4758BCF443C74E2073D7240A26B3B98C3
+:100F0000DBB5FF62C05BB1597D04D69A4B6E9F9BE7
+:100F100008F5E35D80E772789686ED098176A9B6DB
+:100F2000C008FAACD373CC5EA5E1BB83C5C7467BD2
+:100F300029BDB69A484D387E22A411E9FAC24FA2C3
+:100F4000B19F23F748012B9DFF74F99B3F4DA4F3FC
+:100F5000A9FAA9D96D55715926A0EB4C3793474290
+:100F60003CF6E9149F0B092B1F23E545413A7E55BA
+:100F7000FEE1122BEDA76A9384722AF04FF1FD81F6
+:100F8000166FDE86F2D8A08A78D73DA79D59809F3C
+:100F9000299E3F8880E70FB478F6BDF7F6D817345E
+:100FA000ED5A5C8E44E07352400ABEA3A8394D2628
+:100FB000C78E27FDD72DE099F587C6BE3082907B7E
+:100FC00088E76E2E4F4AF9584A278578C2E9815240
+:100FD000279383E9F2A7489F93C5B20AF83AE8FB42
+:100FE000D84E398C1CFC462E053C130FED6C52DF9D
+:100FF0007B8FB92C48FFAD16E2013C6F1D620B34AC
+:10100000D2AE3A7E725E4A17D247BD7F32D0F1151A
+:101010003379448D3C5F874F26C3296396F9248436
+:10102000827E437D514419DFD76E28093FFFDF835D
+:101030001CD37924AD2326958E1BE7279E4018BE2E
+:1010400010ED56D97A662804DB07E3E8FCEA54532E
+:1010500040A2EBCD97183FDBCC0D9E74DA54699F0C
+:10106000E34F27300F19E7A1D2F929747ED9BE18B2
+:101070002C0FF32520CCF1C5211CEE4BC7FA11BE75
+:101080001C84237DD9F87C946F0C96737DE3118EBC
+:10109000F6E5233CCF7721C231BEA9D82ECF5782A7
+:1010A00070ACEF527C3ECE3717E1F9BE3908DDBE99
+:1010B000F9589FEFAB4258E0ABC4E7E37D2BB13C5E
+:1010C000C1772D960B7DAB1116F96E4438D1D784BC
+:1010D000B0D8D788ED26F96EC3F205BEBB115EE825
+:1010E000BB0BE164DF43580F0A08F010CDE5F13681
+:1010F00075898B4A0A70B80A7C1C49EEBEE2F6A8D4
+:10110000D2E5390AF64EB4B3988857DB5EB43BCDCE
+:10111000611CD0354C7F3D5C3F7FEEFEE0BE51A4AC
+:101120008F6ECDA98DE544EEA397755749309DFE8E
+:10113000B36EF71C027A81E426EAF8B4BF7E60EB56
+:10114000EBE2FA6BABD2E991817F1B88DB4F1F95F5
+:101150004D785D827EB6A94A69200CBF8D8E33E33F
+:101160007BE7BBBC248ECE2F26FBF80BA04F66FB83
+:101170005D7F9A02FC9297F8CA14DADFD08D2618A8
+:1011800081AA1257C714AA77D46904F5E2362A72E5
+:10119000B0DE6DD17A7B9A1DC7EC28216DFB86A14C
+:1011A0003C0D2F60F6A7EB12902FCB4F86915BB3CF
+:1011B00041DE829242FBF3AF21E4116133A0FDE6F0
+:1011C000C5BF84FABEFE2C4C8E9AC9F3363A91EC18
+:1011D00056754A1485395B3CCF47D1574604BC53FA
+:1011E000A26979D4A3FEE7018E6E0B4C89A170CC65
+:1011F000EEE0F3D49C92B1C1AE29765A3E7F1FD95E
+:101200000B68CDEF54A73A6879FC21CF5ECA06A4DB
+:10121000B0CB3BD5A9C27C024D4E3A9FADEF1377C0
+:10122000232D177FDA2AC7120DFD2DC4BB53431798
+:10123000C784CE6909F49F19D7B9F265785FE98A46
+:101240008ACBEB4F9F6DB06E5827B5238FD0756555
+:101250007882924BC327657192A0437E1CD8A175FA
+:101260003D0AAC73DBC67807D22FDA550243F64C41
+:1012700027AEED2AF0B18278B26C1A86F22EF88E83
+:10128000E277F41C87166F92D06B356D7991F15B24
+:10129000F66F86DFF7383F47C2AF0D7865D2D9E5E4
+:1012A00078615CAF1C5F03788DD4AE298EC9A7111D
+:1012B000CFDB4C641FB555745CCAA74CAE889F3613
+:1012C000BD89F3F7D9F0EAFB37C3EB157103E3955A
+:1012D000A889A82729BF8E263991F50DF417CE7E4F
+:1012E000DDCEF94DA3E72CE02F36BBA89ECB89AC11
+:1012F000E7AE8E3B8BFEE27AC6C2F5B818EF413EF0
+:10130000DE2BCEF22DA0BFEC9B4C7E90B312E240C0
+:10131000B920A9899C4F5CD1C02733655709E81BC8
+:10132000328AA01F1D9317F0C33E65A85F2D90A1C0
+:10133000192865C0E390DCC0ADB4EB6CEA67289473
+:10134000FEB4AB20409BEA322DA6EB8E15F2E6AA46
+:101350004CD5CA9BB0F77DF228F8227EDBADD98C44
+:101360005FE750FFE56DCE6F7DFD48D86EF3DA2163
+:10137000DB6ED5E8C16DA9A95816ED23F1EF19C1AF
+:10138000BF1B37102FC8C7E4F07EC31B7132E7DBE9
+:101390001E0FF0B9FF07C405FE4CDCC60F503FC559
+:1013A00051FD24A17E62E367F8A27FE9A7E53FC76C
+:1013B00025737DEE8ABED2F1FF8E9F7F45110BF320
+:1013C000183AD9D521D3FAA1D40EA920A793E9DCE4
+:1013D0002700BE2C487795303AAA934900FC5E8AD4
+:1013E000B7A009F4AFC911003B63B1B47A409E893C
+:1013F000250ED7FF8AD37B346E00B970C5A8F9409B
+:10140000D493715F95DA29FF6DCE764543B99B96EB
+:101410005B52E9B8F15D84979BED283FF46F085269
+:101420003148F706601F45D96383F6C37ACB7E281F
+:101430006F059FE402DAFF5D67F66DA488991BE7EC
+:10144000E989637C7D12F8DA338A6E5073FAF8F911
+:101450006CFE8090CF3E7972E50B79AACC437DF883
+:101460000DF42FFA8BE4DF3CC3F5A7237E60FF4623
+:10147000F0FD39FB377CBE7F07F92F8C2CFF51FB29
+:10148000DFD8B28396D7A4CAEA71EADF3986BCD521
+:10149000A9D0B28DFA9BC768D964EB54A05D1995A9
+:1014A000503BC5B7873A79B0FFB04D6065F883FD12
+:1014B000C7C956A994E96B35F6F2B103E13180F35F
+:1014C00059936AC1F1A2460C8F05B97272BE228A85
+:1014D00014003BEE2C76298BB1BF2E7219EDEF3C38
+:1014E0008E2721D7A0B79ECA03BD14AFC07EDD6A88
+:1014F000237E477C5FFF508E2DE8D34F84EFE3AE11
+:10150000E57BA6D60DEED8E120A707591CA5F52648
+:101510002697651924B001F48487A82EDA3E8A88BC
+:101520003F2AB8B46CE6A5995F4BC443E77FE06BF4
+:1015300019A1349C041D74BF57E69682B00FB4986D
+:101540006C01B0A525436CC40265A7296005F9F8B4
+:1015500040C2755A0A6202A0FCA60D298EEDA2EBCC
+:10156000387560AFDD1B86FE57792BDDD3C647C6C5
+:10157000636FBB052FBA008F0FA91B5DE047FA53BD
+:10158000158C3BDC024D357AFDEA786637A93F348D
+:10159000379EC2594B7A365A80DED989E80F91E1DD
+:1015A000F1C8B769A9BB6E29019355CBFCD321249F
+:1015B000D0A8F5AB047FBD1BEF5D104FE143DC8E7F
+:1015C00050B1EC1C09F1AAD189F1E09796D40F69CA
+:1015D000077FF781F5C4BDC48CFAA01CDA7B12DA50
+:1015E000F2817F1F72EF7AEC4EC0A795EE8B418F90
+:1015F0008F3F6C5729BD2A0AF726C17AFE6498BF2F
+:101600008015BE9B102FC67DF0AA78BA0F068538CC
+:101610008E8C837DF029F7DCD820F2564258F9AE43
+:10162000F0DD88FD88FDF07BE660A62BAC1CEAF1BE
+:101630002DC6AF90D8BE969825A6FFB81DA5FA6511
+:101640003DE097BE8676D36395B683BD39E51EEF40
+:1016500006BB1D49DF88F9503C8E287784A997483E
+:1016600079383DF1403CB3D71566BA5FA0F5D2EAB0
+:10167000C206985785C32E01DF89769BE2993D13F8
+:10168000FC2CE25572EC3785407F880F865BFF2289
+:10169000A27CA98D476D02594B62F87287F15722DF
+:1016A000E1EB90B9B50CE67568A94C1A693FA7BC87
+:1016B00013534898F7057C07F886D2A53E818DD74D
+:1016C0004BCFE1E1F177687D8D7B9AB98F9EFDEA82
+:1016D0002BA3E681FD9E0778D48CFB0AC7DF3181FE
+:1016E0001FAB5775D17ACBE27B5D642CE8A92F0B39
+:1016F000FD0E888BF5FCB611E8FD5307C62BE655A9
+:101700009E2E6C1CABC167314123B968EF032E9547
+:101710003E9F37626392DF1E198FC7381E6F8307A3
+:1017200093301EF322F2CD20E331242F1EF98DECED
+:101730008D7207211EF917D90D7E038CEB45FDC96B
+:10174000E2C9D7B9D8BCA20C7EDE3C5F9D4EBFC4B7
+:1017500084241248D09495368CCFC684147C6E9421
+:10176000B75F19E44DE03F123D05FE8DCF9FE7784E
+:101770003F54B95C85B8A1253ABC1F9C96C0E824AB
+:10178000CA6FADF7EAC6FBEBB7B26EBF2CE07F7352
+:10179000FA9EF24E4A8178D53C8B7FC460E45CE0CF
+:1017A000E7AD6FEE7741BF515F59C3CA5F37B74F9F
+:1017B000D49E365FA16AECE9D5F246C07B8CC2F5B7
+:1017C0009B41EE3C6057293E2F06BB4AA718731673
+:1017D000BBBA88F83B208E6C1C5FD853237F09FB73
+:1017E0006AA49BE08384041E37E4F41371C348F2B7
+:1017F00025E4EA5DE0DBC2FEF837C2AB2C7ABF47D6
+:10180000C013BDF488227EAA1FAF2D91034442FE6F
+:1018100040FB78E85E09FDCD60A515ED72556514B5
+:10182000C667ABF265ACAFBA5D46FB19A4FAA196E8
+:10183000CEE74F5C4F18E3B32544724FD3AC7BD651
+:1018400084285DF9EAA577FF693DC4978BCD2A8C82
+:10185000775065F166BF4746FF95F6E10E427CFA88
+:101860009E8BDC60CF043F1CF4C8286FFE376537C1
+:101870000CDBC9E3D1079BF30332D059F2F68EA3F8
+:10188000E640FF552AD0E1EDD42D2ED07751DFDE92
+:101890005F5E8EFB47AF9A8F76933AAB74DE515CF6
+:1018A0004EA70E29BE12ECF891163381B8D191756E
+:1018B000A7509EBBD637B8A78DE88B2F8BF8B031D9
+:1018C000CE6C8C2FF78B2B1BE2C9821F8C7C725540
+:1018D00004FE10FA2A127F503DB630E19FD06342D9
+:1018E0007FBCC3D73975C896DB1B291E6296C88892
+:1018F00007C1976F7F73F3CF410F4751FED800FCAC
+:10190000FCEDAF5E847D08592E858D23FF07E737F8
+:10191000BA4F744FCBEDA3CBD5DEE5BD6510FFF913
+:1019200035AB7BCBB07EA35D89ACD706D65BD9093E
+:101930002C0E6EB43B4679F8BEEDCEBCCA7B73E18B
+:10194000FD79954B03006F1962AB01FD6BD4134613
+:101950003B21E6639C674C482681F1DA79ABD8AE2F
+:10196000CF4E58B0DE67738E0367FD4C14837E70D4
+:1019700002C12F7D3F2AD084E3359C5F8EF36F98A0
+:1019800008D047DC5D7E585F6A34C60F5A33587BF7
+:10199000F99268E68F4F88C775CAC221FF320ECB15
+:1019A0004D7C0DE3E2BD4F02BF35794C5170AE3036
+:1019B000D5A1EC87904BEB1413B1923E3C09FF9DEF
+:1019C000406480AE17EB24D877E6DB2C39E89F3EE5
+:1019D000930074B889EE0B29BF1F3820EFDA4697C1
+:1019E00078C03D3E369C7F2EE082D4B5A817AEF479
+:1019F00055213CFCE3BF6681BC5E2F793B605E9D58
+:101A0000F3AA6E2FA4F3A9DF2DE3B9D282EBDF1E78
+:101A1000C9F669FAF349D969CB85384A9314ED06BA
+:101A20003D22F0D8E1B0A07E693ACCF460D3518970
+:101A300097D93EE2055E7FEA3D07EE3304DEE97AA0
+:101A40003A613D9EBBE3703D629FF12FACE75DE8DC
+:101A50002FF27A325CE80F005FC97DF3971D0AAE62
+:101A6000AB9B44BB61FE3E1E0F22EF45A1DF2CE87D
+:101A70005BCFF94FD0B78ED3B7BBFDF41D17D2F6AD
+:101A8000AD9E783C65903309AEB7FBBD18E40FB14D
+:101A90005ECA07DD80EFBDEDCC4EB4BEEF60F872DC
+:101AA00014E5C2FC847FED4A607EB271DD157C9F37
+:101AB000FE7502D34BE0DF429C6271FC94AF130AC7
+:101AC000C3B4E77E2DC5F3B780971217F93240FAF9
+:101AD000F02CC611E38AF7A212F5F255C1E30AEF22
+:101AE00099C93C8CD3D2710B34F35B1B5F12959870
+:101AF000D47FDC7F818E898903F2A59E8EF58ABD15
+:101B0000598A25BDFB620CA5A9FDE5DC2867527B3F
+:101B1000C757703E6F94FF33A60622D17E6F90BDEB
+:101B200087E2296CF2922E6B4E7F79389B1EA1F4CE
+:101B3000CE4B4CEAAF4F064BE78989FDE83C31714B
+:101B4000003A0F8B2F9F04F5B0FEF402DCE75D082E
+:101B500065D0139661381EF2654F1C096CA78D1273
+:101B6000781C45CC07E21251F4BD1F256623FD25E4
+:101B700085F8CDB49C90EB9640EF0F820F7EA49D2C
+:101B8000DFF7C007570CCC0741F44B56717AAF1200
+:101B90007916BB06CEB31804DDAA60DC3326778F36
+:101BA00037FBDCE956D79F6E7503D3CDBB1AEA9B92
+:101BB0002CE44BF4C38B2B5361BC579C9EE3B1F4D4
+:101BC000F99E46AE4FB229DD68FD8B8932EAAB9FA4
+:101BD00091F3500FFFC064C2F97753FDBB3D3B1C2E
+:101BE000DFFB9578FAFE99CB089EC7D1F5F9195F0E
+:101BF000FA25787EC3226282E7A96A23319D831E7B
+:101C0000BA8DEB09CD3A6F4B0C6397357AE80EA885
+:101C1000A7FC781DF0A34D752903E9A107CF5D0F3F
+:101C20003DF83DEBA14706E6BF73E6AB27C3E903EA
+:101C3000C1C7625F10295F88CA23498FEF3F2E21F9
+:101C40006E3C0F2B71DA98DDDD29A19D6D3A9AEF7C
+:101C5000C5B2C3864A41D8E193BB58BD3C25BC3FC1
+:101C6000F86C623CF2EFAAB6D56E459707E2477A68
+:101C7000DCE939E91A4EF5E20CD98EEB4B2863F119
+:101C800043B17EAA67674E4FE67153BA9E844C8675
+:101C90008704EA0FC0399A93EF0F628B159DDF2FEF
+:101CA000F076835C2E41DC3B2E9140DA0DF5EBD7CC
+:101CB0008D82F3FB388FBE7D1269F942C64108CA96
+:101CC000433CB5DF10C74A2835B4837DC83868AFB8
+:101CD000799EDD7F3F713491EF272C2415EC0A911A
+:101CE0002B06E41BCD7EE244E220F6139F278AF305
+:101CF00071BDFD6A8B2261E302EB92B8DFFD651CCA
+:101D0000FABF32B75BD3BAB2313F658D43C5788134
+:101D10002CBB6D33B3FBBF1FE7311155B3BE84D26B
+:101D200068A26AF60F49E5F1BA72CABC21BAF6692F
+:101D3000DE61BAFAF49AF374F5990D05BAF250DF40
+:101D400005BAF6D95400B4E59CE61FE9DA8F68BD00
+:101D50004C571EB5E51A5DFBD181C5BAFA318FAE7D
+:101D6000D0D58F6D5BA32B9FBFFB27BAF64D3CEE02
+:101D70006BC4CBC5494C3F37294CEF34DA0B301ECE
+:101D8000D964D7C723D338FE4B6227E7421CBCE98E
+:101D900083FC5CC0F70BCE0B302E1E892F8C7A2C67
+:101DA00092FE343E2FE6E37DFEBCC5047250B79729
+:101DB000CAEBF9B46C7F6733ACA9398F9DA72A842D
+:101DC000E5F788F315F17EEFF98AE266F155A79DF4
+:101DD000DC1A862FD292F4EF093D29F82812DE048E
+:101DE0003F9E0D6F9EEF096FEF49649E761E15FCB6
+:101DF0003CDBF8DEDA24133F0FF65E93C4FC9D094A
+:101E0000D1E889BB501ECF55FF8B7950FDBF3409F7
+:101E1000F7136F2CB801F4FF2EAB1BF6649FCF7B3A
+:101E2000A3FA7E15DA57B3F626772ED02552FC7B1F
+:101E30006D52BFF8770D8B7F47EBF0B64CC8BB21D6
+:101E40000ED7E4FC1AE3DF4D1677EE60E2DFCBA09D
+:101E50000F383FE474EEA52F8F9F47DA07F908D9B2
+:101E60002FC1BEC7AEA870CE75B67D2DDDCFE6C240
+:101E7000796A2BEC9B34FB1CBABFE5FB9B28B40BA7
+:101E8000D4EEDD9184EB22FB55FAFC0CDDF7DEAAE3
+:101E90004251D83F8FCE2FB712B7CD22233DEFC18D
+:101EA000F76E22D745C9102F0B1E989CFD2FD9F332
+:101EB000FF481A707F68B4AB673D9743BB5346D762
+:101EC000BF218CDF653C87EBF5BFC14F93F03C0E23
+:101ED000F1B489DA45388FEB4862F679D361B64FB1
+:101EE000DE74744E2ACA4D52D180E77083D5371DF7
+:101EF00049FDFCB58EA401FC35B1FE357CDF3B5DB0
+:101F0000CE6B8378E3C99005F12613961F59BFCF96
+:101F10004C02484F96672CE8680E6DEE04FB6C2669
+:101F2000C6BC623516D66DDE27A37E2289ACDE4F95
+:101F30006C8DE0E7C416EBED569C476FB7124AE391
+:101F40000D764C6FB752E6E9ED569A576FB7D26BE4
+:101F50000A0C764C6FB786FAA618EC98DE6EE5345C
+:101F60005F66B0637ABB356A8BDE6E8D0EE8EDD6A8
+:101F70009847D718EC98DE6E9DBF7B83AE3E3F78C6
+:101F8000ABAE7EFCBE9FE9CA859D0FEADA2FDBFF70
+:101F900034E6DF4C3CB45DD76E52D7AF75ED28C246
+:101FA0003B214F7B099284900B4F3CA5AB5FC2FD58
+:101FB000B48B7A7EAFEB87B4B27C6B3FFD0FE8F554
+:101FC00011F15AC0395148CF4BE994AE7501C91D82
+:101FD000A4CD96EFDE5904F3F8E4FD4BF6413FCB78
+:101FE000B6E8F3B49707F4E57A322C16F4433DE5EE
+:101FF0008B00E5939590BFADD16B2B498313F321F3
+:1020000006C967CBF6CF2598F7E9F774427EBA5830
+:10201000A7E0370FE737313FB1DE95D4EF0BAA7D4C
+:10202000EBF4D0FFD83EB2CB027C5BBD5B220F4A03
+:10203000FDD753D37ED7E6F430EB32AEC3E877BAA0
+:1020400093F5E754D3653BC6F54FBE29BB597C5089
+:102050002F876BF6B378FE9A27248CAF19F121FCF9
+:10206000D2487891FD6C9F509F4802018DFCA91CBD
+:102070001FD654BDFC9D847FC07C1E960390171410
+:10208000A5461BF9AD2848FAE33926572FA7463C49
+:102090003BDC43C2F2954AFF83795413762E65E404
+:1020A0002B23DEEB76DF6501BD78AE785F64C0BBC5
+:1020B000383F28A1ABB584C9831378A5FBF2A5C925
+:1020C0004991F7ADAB9325FDF9F2D9F7ADAB93BFCD
+:1020D000DFB8C9BAE401F6ADDD102FA37EA5315EED
+:1020E000D63F3EB6F72BC989716816FFF2BA6D2C40
+:1020F0005FC5602773537576B277DFFB8114680282
+:1021000039767A6E83F9D43A3D2D007FE4F4DCAE63
+:102110005D6F13C50BDECFA1766A6718FFF0E5642B
+:10212000E11795635C6453096B6F6CB7335941BC1D
+:10213000772415A5A2DF79349FD94F47D1807EE758
+:102140009DFC3CE736382F1CD197C7733B3F57A106
+:1021500062E701BA6D3297A76AF37CEF498EC3F14B
+:102160009C939EEA847CE72697C925A9E03F9BF0D3
+:102170005C74A3C75EBA2B8FBD97A87B8FDD3B92A3
+:1021800001DFE0CFDB95AFB57CFB32C525F41B69E1
+:102190009D2F27337FD74C3C36D0BBE23CD7FC4148
+:1021A000BE0DF4AD22B95DE1F238CD3C4F6A0A3F75
+:1021B000CF955DEC7CB757CECF922755E7F4BE9410
+:1021C000ACF117C4B9EE954ECFCB404F9FE2B7822A
+:1021D0007FE9B385DFFFFE89D3F156BE3EEA682270
+:1021E0001FE1F8F2A0E2276F25635CCE8FF98A37F2
+:1021F000C8EE13109F1B6CBCEA6872BFB8DC512D8F
+:102200001F1AE58FFA9FC763E17C22768882DB097B
+:10221000C59D0BFCDF0CFF9E84F1D513F07EBFFC47
+:1022200053359EE7D3AA03E6D38A7EE6C679BA93EE
+:1022300059DEDF17003DA35C1B654D3FCEB3F44371
+:10224000F194DB601F14FEFEC1F0E73EC18209E796
+:1022500016D78C4AE9E73F46A50CE03F9E393C2A59
+:1022600016CE9345DCCAD8CEE64BC8D0DE8F698E39
+:10227000D38FBFB9809513F9B8CB6319DFE7F2B2FA
+:10228000C80314716BDB4CE281FB0E3FE3F9D9A26A
+:102290009FDC1407B68F8B9F929B5208E76912EE62
+:1022A0002B37C749BAFDE5F1E4925C58CF30DE7FA9
+:1022B0006E0AE3D36DC3587CC69807F9196FFF59AE
+:1022C000F214849460A3019F16590E8BC7B1296C38
+:1022D000FEC76359BF227E56752FBBDF25E26622FB
+:1022E0000E483D83B762A85E39D6622610D75A2AB7
+:1022F000DB37031FF6DE9FE3E7EA2EFA1FD8CBCACF
+:10230000BC72CC3FFA57EF6F013E63E2FBDBCBE9D7
+:1023100029BDF6D27D8EF7B86632FC0CEEBCBD2B23
+:102320009AF16D8FC38EF16C63BB6A4E9F161EA728
+:10233000007D0D76235E260DE1EC4735C7FB99C382
+:10234000560FFA31A5D198CF21CE3F14CA9FB1F1D3
+:102350009806EE0768F3A567C07DA2DEF30F95E04F
+:102360007B09763BBEA7A824E8802BA18A5B82FC70
+:10237000B22E4BD7A61498EF45921BEE0FA454B87B
+:102380003A5212E11EA18A62B6399B388BA13EDF18
+:1023900084F57197BB369B21EF5A2570924DCC7412
+:1023A0001C071DE78E946C5C7F8B7F6E470A6D1750
+:1023B000ABF6906179A0475C3352418EE7B1FC7572
+:1023C000E3FAD6A730BCD937D17D03E0430D9F0790
+:1023D000BE3E85E501513D7313D0A34425BBD8BD56
+:1023E0002896870A69D6982FE866F9D231906F94BB
+:1023F000C3F40CD4DF15377523C88F902F99E31BD6
+:10240000F85E9B0F7F07C77782413E053EE9008D4E
+:10241000900FA1CC24C8D7B32BC2CFF7314EE77AA7
+:1024200067F93D30EEECC98D98E74EBEF9EE3BB949
+:10243000089C5E2627F47D027188A844A67FA354D9
+:1024400015F531714998676A53DD35508EB25FE0FA
+:1024500092C1EE59F979E1121351A8BC4DE5FD780E
+:10246000E611E9C35C166765FA55211F0AB9903970
+:10247000728AC07EB23FEA17B5C4D0F54CB51FC012
+:1024800073C4A8E10D2570AFE0C545AC8F9F45C86A
+:10249000DB3FCEF558BCEC4D35814F4F8EBDFA4237
+:1024A00006D2F93CB8A179DBA6C3AFEEBB88C7CF93
+:1024B000215FDC7FF8554FDE3F9F5FFED2FD875FD7
+:1024C00085FCF27F9EFFDD12E8F1E394B160DE4609
+:1024D000FE17FAEC90EC3D7423C5FF1594A97C051A
+:1024E00000155281F466F94397733CFBBFA678B69A
+:1024F000F5E1F98AF6FD88BF43663A6F3ABE790A7C
+:1025000043B5F927B13C1F2380FD5F696B9D0EFE2B
+:102510004DB7A5671C8CDBFDDC5F33FD549F1CFEB3
+:10252000E92907A1FC7744E971C0F313EBDE707869
+:10253000E87A0FAF93F1FE1BDE4BD6E4039DE07CFF
+:10254000353DB5FC08F0D5A2F5DF1669FD6CE24B10
+:1025500042BBBB3C20C31DDF5EFDB7F2D118CE7479
+:10256000ACBCAA2D415716F6789535FC3DF1CC54FC
+:1025700046F7E58F6FB3403EFCF454EF1730FE0989
+:102580009E6F70629703F757623E8B1FCFB7C07E76
+:10259000F248BB950481EF954E33C1389567A64448
+:1025A000F9D6CBF9D038CF97F6C4607F4BEF953191
+:1025B0008E5449C7F251BC7ADB97B3FDAD611D4B18
+:1025C0000FAB33405F2DBD45227E95B55F47E9E6F1
+:1025D000F5DD8CE72BC6751AEDCB69B2CE027AC455
+:1025E000685F961077F364B05BADFAE7CBDA6FC340
+:1025F0007E979DE53C262195DB9B2232F1BB1C8812
+:10260000330FC37CC148F6E6C47A26941FAFB721C6
+:10261000FC74BD0BE11150A614CF2B7777BC948EC0
+:1026200062DD590476286AFF54DB35A4CF7F56B6A5
+:10263000CD0D3EA4025FEAF3212B389E85FFBC8CB2
+:10264000DF33389BFF5C01EB1C201FB26290F990D6
+:1026500027F78DB7C1F3C2547E3E3591E203ED6F8B
+:10266000DE6B2A39BBFD8D849748EFAD82EF1C8469
+:10267000C1B3909B23DC8E2CD93167F3103A81A62D
+:10268000E73ECAEA42BE647108714E25A76EEE8429
+:10269000F5CBC410FFF3933789867F8DFCB98CB8D6
+:1026A00099DDB1B3F76C3C2ED1CB97EDB7235E0526
+:1026B0001FC18D02532AC060AAA9B8FF7703FA7D13
+:1026C0001FA0555FFEDCDC95057A6399215EF0B9A9
+:1026D000147EFFF5C3D4616CFDAA6706E4452C2582
+:1026E000E59B595CBD159F9F505A5FBA11E479076D
+:1026F00093A755CF3EF10CE8A915FF79AF13F4D499
+:10270000DF94D66418AFF6914D4ED0EB2714BF136B
+:10271000DEFF5B400E7B5F777BAA24F2E2ED901731
+:1027200056872C0602E69F057AF2BF1F31BB208E2A
+:102730005AFFA83568A5F8A8DBC5F048CB4759F97A
+:1027400066C457FD6EBD1CAEF8D5BDC92AEEE7FDC7
+:10275000E91C7FE9A0AAEB7698317FB4EE4DD90D44
+:10276000C3D4931E5C9FF17D984788D2ADBE4DAE19
+:10277000B4C4F6AFA71E8F05E4AC7E17A353BDC14A
+:10278000CFACE17AD9C8EF3F1372CFF99CE205E3F1
+:1027900061229F9504987E6E7AECFE7147E9BC3EFB
+:1027A000DDF1AA53CAEBE377025997145F27DBAA3E
+:1027B00016419E41243EFF9CCB45AFDEE77646DDC9
+:1027C0004D2706BE7F3B83B5E6A0F3428A8FDA6DC4
+:1027D00066B79F3EAE7D42F6D8C14F7ADB8ADF777F
+:1027E00058F9C48B6F5D40E7B772A73971265B86D5
+:1027F0001DF4B3A0533DF077411F5D563CFDA2058B
+:10280000F220E1F9BAF83EFAACDCD96181BC4A2386
+:102810001EA7B67558987C19E8D4767406D8E5A634
+:10282000C7CE58800FFEB64722E0421ADFAFD9F676
+:10283000A213F407E009EC87A0572FFDFAD12D3839
+:10284000EBF713B09D0BCE6922D1EF5A984B12F2E1
+:10285000F793BFA7E3D7BC6375C3FA6B9EBCD609D9
+:10286000EBF84869607CFEF34DC9608F6BCCFE6469
+:102870001742F6BC66EB8F91FF96BDFEE364827A49
+:10288000D39306F24BD79906EB5BFAF015B8BE6A04
+:10289000E245FEABF9B95C0E7EE269859486F3F3FE
+:1028A000D3D3989C7CB4DD8A9B828F2C847D87E374
+:1028B000CF32CBE323ABD10FF9315F2BD5C4583ED8
+:1028C0006D6374EA4E357139637AAC9EB7AADF71D5
+:1028D00033EAB18F333D2920EF140FFA78EAEBD3B6
+:1028E00053B8FEC3EFA5E07B94EFA6C27368DF691F
+:1028F000F6448DD3BDC7F35AD9F8D7F1F1E9BCA39B
+:10290000212EF751B27EFF2AE02569220E463A8930
+:1029100096BF22C9FD8E5B90AFBE7C93E995BAC08D
+:102920009C52ACEF340753A03ED071B9847A81FA3F
+:1029300017E1E47A8799CBB5BE9ECE5391B4F8DD0A
+:10294000C3EEC555DF43DB69FC903EBEB1F43DCF1D
+:10295000EE934F915FB1CCE09F0968D40B49697A3F
+:10296000FB27DE270F2785BD87D5A70FFC88B75A21
+:1029700073E0970F821CBF6DC57B86B54F98F17BC6
+:10298000399F3CBEF7AD6B28BF7FD226E457AF67B7
+:102990008DF25BF3D415249CFC7E92584EC2CA2F54
+:1029A0007D1E567E1359FEFEFFB69E5D1641CF5E1C
+:1029B0009CA6D7B3D49F88BD90163FFEF5CAA1B898
+:1029C000CF32E055E0D3A8370FA5AA885FA3DEA4D5
+:1029D0007F6F120D1E05FE045FAEF8CD2A1CA7976F
+:1029E0007F057F0AFEEDE54FE37AF57834D62B704C
+:1029F000E7A8B08FEEE60D747F0DE7AECFC978EE95
+:102A0000DAADF638E3212ECBF36EBA5DBC1CC7CA33
+:102A10003D4996CDA03FC4F39E289687D05DDEE366
+:102A20008CD3F8F547DB6527E4D57705C2E74B6023
+:102A3000264512DC128D54DFC8BF5B63CFF2C1BEE6
+:102A4000AC959DF72C69BCCA09FE74777BCEEC79F6
+:102A5000E0C7EF97D1A7EA8EE6F9557E8F9246F14F
+:102A60005AC5964C4E10FF7DE06757B5AF9C099B49
+:102A7000C6252D7A7C54DB2FC7F3ACEA7BCC7D7C5A
+:102A800041C0DF0958C0CFAA7958FF7C05E4550141
+:102A90007D0C7CE4053E0A730FA359F0513EC967D3
+:102AA000FB647E5EC5F5DA74396FF63CC85FDCC73F
+:102AB000EE499C6C97C96658EFE3FCFCCA9F84FC06
+:102AC0005947F9581BE7FC14F86C5464FBFDE96F97
+:102AD0000F17DD489BD43EF3EEB88728FCF499B776
+:102AE00047FE01CACFFE35EB5DD2BFFDD43D5F2D61
+:102AF000C43CCA3D5602FBA2EE3D2F67DD08E5DF70
+:102B00005BDDA8FF37B0FDB17F8F03ED7A7726F349
+:102B1000FF9A9E3B33AE0BEDD346A4D7D369EC9E10
+:102B2000EAC9F6BFBF2F413E5D3B5D15D85DBEEFE4
+:102B3000AAFF7D14EEAFBB9F3BA3DB57FEABEBA917
+:102B4000E3F795BA1D641EDC2FEE8E63F73BEBFFB7
+:102B500030E917705F71D5AE0E4B15AD9FFAC76F98
+:102B6000C781BEE97E8AF913D4BFDD0A2EF59E0720
+:102B70000EB49829FD3E079F6F0821573D682F83AB
+:102B80007B18FDF1C2F0D04DF100EBA278A9013D18
+:102B900019091F7FF9B7C5C7170B61FCDAF689045D
+:102BA000E2E97D78913CECB903F32EE8FAD9F33DE4
+:102BB00067C6817F74B6F59E4A63F765FEAFAC3792
+:102BC0006EC8BFEB7A19BF3F90A6E23C8D7CDF9FB9
+:102BD000AF9FBD1ECB4F3ADC38DF41CA7BFE90FF72
+:102BE0005BFC3DFBDF76BD67A3F77E4E6F870BCEA8
+:102BF00053BA9FFB368B9CC3BAEBFE3F5D77AF9F0A
+:102C00006372DB26D0F9BD430257944891F3381F15
+:102C10001AA2DF47CCE27EC4ACC46AF41F667958BE
+:102C20007CA58914EC837B6A7E8F8CE70E984C43DD
+:102C3000F1D079797E00F3B614FF88FB208FEBCAC0
+:102C4000556EF69D2FFDFE6A56726929F86F071BB7
+:102C5000E9BC68BB830E93AB892E61B647467F8F74
+:102C600042F4F3FE32E552CC0B995DACDF675C6356
+:102C7000D8375C354F5F7F25D99E04F97757D698B2
+:102C8000315FE80A43FBB5435CB8CEAB48C32616B8
+:102C90009F39373CBDCAF1D41F0F03E3AD1F9EF827
+:102CA0007E127379D4FE78B37AD9FED24A2BB8BF9C
+:102CB000C5F3E4D60C0A9F84EF3BAD7C68815FAB23
+:102CC000877DAF53D32FE245E0FD5CF12DE864C46E
+:102CD000BBC0AFC09B910E5BE14C42E38FF74191CB
+:102CE00047E225DA7CCB59BD7EA31DF1F8DA0E76DA
+:102CF0005FE1B5E2AA967C283F2EA1BF767AF278F2
+:102D000062A3EB3D6826BBD9FD2F8FEA2AEACB6789
+:102D1000918A5FC67305C827D4EE4B219F50BB2E06
+:102D2000C827D496219F50DB1EF209B5F5904FA815
+:102D3000AD877C426D19F209B5ED219F505B867C11
+:102D4000426D7BC827D496219F50DB1EF209B5F552
+:102D5000904FA8AD877C426D19F209B5ED219F50C7
+:102D60005B0FF984DA7AC827D496219F50DB1EF2D4
+:102D700008B5F59047A8AD87BC416D19F205B5EDD2
+:102D80002F0E3DAF2B97905775EDA7DADED095A7A4
+:102D9000BBDED5B5FF61EA315DFD25EA27BA7A4190
+:102DA000FF4B734FE99EC39985BF08F631ECAFCC5A
+:102DB000FD775D3F0A29C738B3853420B441FC96BE
+:102DC000C268D286D04EC51CE0F491DE11E9C0AFD6
+:102DD0005BFD9B81B90E4E3A9305FAFFB5C9735955
+:102DE000FC819F13CC867FAA948963BEC9807DAD88
+:102DF00038F7748664121C4FF930242174856248B8
+:102E00003081F261280A617C28019F2784E2102624
+:102E100086D2F17952280D61722807614A281B6118
+:102E20006A680CC2B4D068844342E3F1BDF4503EFA
+:102E3000C28CD085F83C3334096156682A3E1F1A8B
+:102E40002A41A8862E45981DBA04E1B0D05C6C9743
+:102E5000139A837078683E3E1F11BA1AE1C8501564
+:102E6000C251A14A84B9A19508478796233C2F7483
+:102E70002DBE3726B41A615EE8467C3E36B416E1B4
+:102E8000B85013C2F3438D08DDA1DBB05D7EE816B8
+:102E90008405A1BBF1F9F8D05D0827841EC2E7853F
+:102EA000A1071016857E817062681BC2E2D06F1088
+:102EB0004E0A3D86F082D0D3F8DE85A19D08278793
+:102EC000FE80CF2F0AFD0EE10F427BF1F9C5A10E66
+:102ED000849ED0ABF8BC24B41FE194D01BF87C6A6C
+:102EE000E87584D342EFE2F3E9A1B711CE081D43A0
+:102EF000F8C3D05184A5A14F105E12FA1BC21F85E2
+:102F00004EE17B9786BE403833F4777C5E16FA0A32
+:102F100061EF7E7F72A47B895ED37710D7B2C70F33
+:102F2000EA3B5F846CD19D4BDD1FE3443D397B1D43
+:102F3000CB23D95C726A1AFAB5ABAD2AFFBEA641A3
+:102F4000AF7E6307FF6113D4A4B13E200F7001E789
+:102F5000DFD78AF72681BFB4B9A0AB16E221B767E5
+:102F6000775500BC339DC5573773787B3A3BCFAC60
+:102F700018E9C272C5EA11787E451207B78ED78666
+:102F8000B0F744FBBA4C5EB6F764E1BD8041F6335E
+:102F9000D87667CB8FBA2EDDBB1DE5BCDFFDBC410B
+:102FA000BFFFEBF4C27FE9FDA7067AFF08A7972BC6
+:102FB000A3FC199CA7E21907F55336A4C989B49F4D
+:102FC000CA16C90576B26A63FE0CA05F01F1603CC7
+:102FD000714184BCAE7739FD16379809C41517AB1B
+:102FE00004E3B98B77B13C5F88839651BEA8E17C3E
+:102FF000B1EA969D1670416B1A96B1FCA3008B3313
+:10300000D9E87FC0CF2B5AE660FED1CA47F5F1A7B9
+:103010005A88EBC8708EAC7F5ECFE34CC678A53182
+:10302000BEF4663A8FFBBA59DE11913370BDA7E941
+:103030007A219FC37BBDC306FA9FE201CF49C4FA40
+:1030400045BC52E081F4BFCF8079A127F78DC03C09
+:10305000B593AA9A02EDBC549C3AED90FFE09D080E
+:10306000CF29FE309FA4A73106F3918E527DAE4248
+:10307000E293CB3B11BE9FD6F54E26E1DF6FD49F86
+:103080001BD85A30FFBAD24C07A6ED2A1F49C0FB05
+:103090008FB4BF71BB211EF98819F381FC644D2ADE
+:1030A00029EE7FAE50BEC98CFCB178771CCB0FF3F4
+:1030B0007BDE847C7D418FA31B7366405ED1E2E69C
+:1030C000EC7C0CBBED36A39F27CE4B059DFAE74564
+:1030D00097C7C2F7115734BF8EF4A4F4D2D5D7B630
+:1030E0007C81F70728BD8E47A0D7F181E8159DC1E7
+:1030F000E3816E912796177B1554AE4B4039ADD8BE
+:10310000101CD1A0E147639C9E64D8F1BEA3C827E0
+:103110002E1DC2E841147732D0F5544B21D2CB4852
+:10312000A7D27F54213DC83B0EFCDEEE821CB2E8E4
+:1031300032FA7C118F5B2E68BA04FDE79C0CE6D74F
+:10314000BFB61E722D09797DBD8D78A8F3FCC67AB5
+:103150001796FFB23E15CB7F5DAF227C7B7D2EC2E2
+:10316000E31696CF23E4893200E6D58DCE60723423
+:103170003A43ECABAE4B85B874E93FDE2884FC9E45
+:10318000247FD2ACE999E877EBF234E65DAECFC3A9
+:10319000E832F33CAF5B24377C476571F985BAF6BA
+:1031A00024777C5F19EC07CF1B59DC1C87DF6FBBD2
+:1031B0007A6682AEFD95CDE9BA7249868AFA754E75
+:1031C000698EEEF935156374E54AFEBB09C4166DC8
+:1031D000D29E4F51CAB23C6F176BFB65C3C4941BA0
+:1031E000E8F85F1E3063BD911EC72D7EDC8FFBB7F4
+:1031F0005BDD60874EC03D325A3EF11719F5DD099F
+:1032000033F1BBA8EA3E21918D0089C2E4E9F421A3
+:10321000264FA5FF9009ECC3C9AFAD787E57B545E1
+:10322000227EB843D543314FC7BDEE312BAE7BC9AB
+:10323000169978F1BE92DA06E7D6D73D32CA0DE785
+:10324000960B728299706FAFE7B751EEEDB4B6AAE4
+:103250008BBD7F82EEAFE3202F492AC0F383CFCA14
+:103260005AAB4D906F201F480239FDEC2919E32914
+:10327000CB57FFA5C8057AEDA5B6B78AE938C75B75
+:10328000651CF79347ADDB6494774F0A7CD7B56F25
+:10329000DD018C33BC945ABE2283F2C1C7D5817143
+:1032A000A877D6B1F8767FFCD0F502BD815F357A7C
+:1032B000ACCF6EB17332AA7CD2403F5499DD786EA8
+:1032C0007ABCC58CE77954FFE3F9FFF1D60413D338
+:1032D0003F4F21DF2D56548B76DCC52DB287FD2E56
+:1032E000846A81F992BB642F99086596AFE06F9666
+:1032F000BCECBC464FDF6B574FC4FBC5C6FC290175
+:103300003FA732E5D59C03AD788E9DCF92095D8AAB
+:10331000367F5CC457482AEB5F7CC7A776D8FD7719
+:103320004CA6F0A4877D72F0F40E07EAC74F4DCF8C
+:1033300017DD40E12765FE0F154A9706D97B5F062A
+:10334000E4EF985AB64A782E72EC0E388FFFF809DF
+:10335000B31BC590E76BADF8F5F2A103E507C10C0F
+:10336000D8F97230594A85AFF212CCDF984FDA782B
+:103370007C20C0CEFF6112143FAE5A768E75ACD061
+:10338000712BDCC3AD32DCDB3DC6EF2D3C96C1FCBE
+:1033900021619F3FE2E52A13934FB2877D7F11F2AF
+:1033A0005E866BECA9D0A7BB3386A1DEE8B5ABA4E3
+:1033B0000DF54A35FF3E70EDA356764F47252E900A
+:1033C000C7E584CB1FC8337D6F85E589FB809D975A
+:1033D000914EB4731F9B03D59DD9F0FEB68DF1F8C5
+:1033E000BED91D00F9E576C0461507E88F6584CD86
+:1033F0006F55AB14086AE214E2F73808D8058DBEA1
+:10340000E96F0FF4766029B7774B8921DFA7556FF5
+:1034100097CA631CB8AE15AD3CEFB9775E32F98E32
+:10342000E2ACDA1B786916CE5B7207C2CC6319E98D
+:1034300009C27780573DCEEE0319E7655CC760E7A8
+:1034400059ED9E330DBE27DC3BAE61DE02DF042E5C
+:103450002869E820F05EED67F8AC6E97905EFFC5D6
+:10346000FD2A71CF4ED07D19299F057A6DD93D7403
+:103470005F98DDC707BDF67A6700FDA54F48ABD35F
+:103480004EF9BF76CBCE2B27C17B0FBF6E01FEAEB0
+:10349000880F8E30C5C14FD2DC7847E94561ECBB5F
+:1034A000C19E7F5FF8213CCE84EF517C2CDD2163EF
+:1034B0005E83A61D3FDFF7337EF613CC23AA795334
+:1034C0007637D1A735F0733E05E73E5F819FFFED6C
+:1034D000791BFD989CCC81FD18A37EE9E7C718EC09
+:1034E00027DC9B007BD993C4F2C0BF543CB1F1A848
+:1034F000970D7A37A900BF3B2AF46E35B77B629CE3
+:10350000A560EF68F9C32D4F3B21FEF05FF73C9DAE
+:103510008C7914605FF2FAECCBF5556CBCEB9F8DA7
+:10352000C2BCA5CFCA3AC781DF57F1F3979DDAEF46
+:103530009AAE48F59664827EE6F67095BC2DCB0572
+:10354000F6D0173EAFA2DFFE2BD23A1D6759A74334
+:10355000BFCEC5B04ECD7D902ABECE0F9AD9FA8E81
+:10356000B5B0F52EE9B74E3F9E835CFF0BABDB8F0A
+:103570007E4610EDF8899D3281FB67BD7E86C1EEE7
+:103580009F26AD5B011FABD6FCF57D85F2C5F291A0
+:10359000143F940F2AEEB2A29D5FFE5B76FEF9B156
+:1035A00054928207F02F049D6BE9F315D43F00FF7E
+:1035B000A26F1EBD767F39E0B1D7EE0F127F753C4A
+:1035C0000E55D7FE32FE5E94E461F99075E23B3011
+:1035D000BB0DDF81514107B07BF236A0530651D9B4
+:1035E0003E511F4FFDEF115F2C5C83FCDF3352FB1C
+:1035F000BDDEFAE8A019F27D7B764AE817ADBAAED7
+:10360000C4594220BF95C5C1366732FB25793C9825
+:10361000F762A5748DA6E3DD92A9B2E7AA8BE575E2
+:103620003F4CF0BB3362BEC6E7101FB781FDB39BB2
+:10363000D0FE19D7BF3B93F9CBAB6413FAD3B516C1
+:10364000E65777F3EF3EDCC7EBEFCB64FEF5C399AB
+:103650002C9EDF0D7E249C4F5F64C5DFEB21641A36
+:10366000C6C915C2F84F117873299FF7CA37FACB2C
+:103670003D1980A785A4D30CF49C553C47857B035A
+:10368000EF27DBF03B4AF4AF1CFA99CFFB396866B1
+:10369000F704DE8731E8BAE6F378F2FBF019503A26
+:1036A000FEFB6916F463FDCF59D14FB8399AC5FBBB
+:1036B0004862AC027C7E0DD7530B265B3D703E30DA
+:1036C0007FF2CDE500697F7E42F15561EBD9944FE1
+:1036D000C76934313BDF184FF0BE24D9D85508F8FC
+:1036E0003B9FBAC590274F57BFEBBB8481F8487FFB
+:1036F0004FA116E20A1710C660C5885F5DB9D6C231
+:10370000EA0F661E99754F06217F866C26B03380BE
+:1037100023E08BCA58DCE7CE863CFE78800AF2DBD9
+:10372000650AF19B186CB6E37788585EBF3807B915
+:10373000A2980463E9FA82FBF5F728AE0A9A82A3FD
+:10374000E07C47097600FE4C36D5ECA2E394974A1C
+:103750000580F7DA0D839BEFD1CC8F67DD33999627
+:10376000E17B5730CFB512E6F3CCA7420F7CBA50BD
+:10377000212FC8058C7EC087F5F1AA1FDBAD667CC2
+:103780002EEE6F08BAE4D3EEB5F89DCFE747FB699C
+:1037900076C2FB96F07193CF32C53E8FF9692BB993
+:1037A000DCAE147CF7B85E5E63B354F63D35F007CB
+:1037B00029DEE6731889EFED59AC7F7B16E3FB1029
+:1037C00097C7C18EB7CA4A82B8EEE7AC484731EE18
+:1037D0006C0EA3B358FEB29887E0DF6AD280F93747
+:1037E000D53C1E63A29A04F3745B7F81F9FDC63C4D
+:1037F00021EA2061DED98A1DC6E79A788EACD34BC8
+:1038000018E7942C3D4B607ED20FA2DCC0EFF32D65
+:103810006D180F30B633B74A28E7E666EA4F49FC21
+:103820007C8B96AD2D12FEBEC3FC8C9EB1F8BD7292
+:10383000EE575773BA52ED3D03EE0155833F85E7CE
+:103840005FFC3B515B981FA970FF77718BDECF98AF
+:10385000BF51E36732A0BB576F35E4879BB9BF7197
+:10386000C4D23316F4BDF19EFD11139BBF3F996086
+:103870007EA4B867AF707F52F0537A9659773E2690
+:10388000EE7356809E62DF3B30E453D9F1BB2B15BB
+:1038900012FF5E258F2B9EA4FE267E57E67014DA5B
+:1038A0002D1167EC2E71F84DB1F0394B565E107B3F
+:1038B000FD2CF0332B9C1605E01953178E7383DC17
+:1038C000E9C8CEEE8BE36E2E19BF05F286E66CCD0D
+:1038D0009D6DCBC4530E7E1F69EC6B90CF7BF93787
+:1038E00074FE581E37DB43F747DD2FF62CB4511515
+:1038F000BD2CEBFCD90AB5E7DDF7F66C85F2DAAC46
+:103900006256BEBD270BBE21BC76EB64566E14FD1D
+:103910004D9E0D79F0DD0FB0F295B4DE0F7E2EBF17
+:1039200007547181847A762DB73F227E54617A9E46
+:10393000C129EC773ECED66E4356F9DACC24F8DEB8
+:10394000E771FC3D8116D5B316ECF5FA0C6F6516E0
+:10395000ECA3E6487E0BDC8B7F333092DBAFB0BF4D
+:103960007BB13693E5096F1C5A8EEF0B7CD17E56E6
+:1039700064159E7B3FF1FDFBB9F69F99CF91A16C39
+:103980007D9A7ED6FD33FD4C51F5F311FE99F8CEAC
+:10399000DCBE6CCF16E877E54D6C3F4C8EDB75F7DF
+:1039A000FF4F353C3B12ECFEA9C7AD09C0872B9FEA
+:1039B000FC5D5635F87FDC1FFAA4E36D0BE47DD780
+:1039C00085D87771EA43EC3B3975BB3A2C33F2204A
+:1039D0008FB5C3325533BFDABEDFB9522ED3F831BB
+:1039E0003FCF12F9DAEC771D573EF937FC9EE04ADB
+:1039F00053DB8790E74B2E607134E33A37F1F7DE03
+:103A00008773FF30F1825F70FDFB558E673BAC73AF
+:103A10006316C1F67284EF767DCAFBAB88667ABC0A
+:103A2000AAC8615329BE0BDFF43641DE69F5C3D95C
+:103A300005329DC7F68C298F037F448E6FF6B0F850
+:103A4000663B8B6F56C4775E478D14F9686BC59DD6
+:103A500036BACFBBF47ED27BDF0FE286A556213F7C
+:103A6000D7CE9E96C1E265507E256BD59D203FFB4B
+:103A7000F8EFB32D9838361AE4BC2B3BC6E4A2F21B
+:103A8000FF747AE547308F05132F9A01CF4BAC8E28
+:103A900091952C3E8EFCF1747AF9F3500FED21EEE6
+:103AA000E1B50493AEA2EBF0BE2263DEB4775C8C8A
+:103AB00037DC3D9520B7571F65313F6D9F89CEB3E9
+:103AC000A06F1E627CEA985DD70971AB0D69F9E0C1
+:103AD00047BB324A3ECC4AEA1BDF95E17D03CA620E
+:103AE0007CBADC71F07CB0F3E8E4F4F810E846FB53
+:103AF000299F2CC397127AF5FA65D36274E5CB67D8
+:103B000026108F366E7A79BAAE3CAF2247D7FE9A2E
+:103B1000256374F565D6CE090DE7E0EFD73B1EC5EA
+:103B2000FCDEC3EDA7DF9A0F7EEC0ED92DD1F52C6C
+:103B30007FEE91B720FFFA24FC0449018B8BB1EF93
+:103B400035F2F318C5A3E8CE63F63F6D01BF5D13F0
+:103B5000E737DCCB3B80717CE3798CC817FF67CFFC
+:103B6000632C43F9BEB8F7F73C3F7D89AE8C4CDD42
+:103B7000DD81F469DACFF2989BA8DF02DF13FBE165
+:103B80002E6B00BEE1FED9EF8E5A54CDB94C7DA804
+:103B9000117F5777EAEEA3786EF3AB2CA6B7EBDA7A
+:103BA000BFB0C03DA91FB6AF46799E41F5572CE581
+:103BB0009BCE0E327617C493B31D9887B3B2F91219
+:103BC0008C53C786E623AC6DBD04FB5B159A8BE571
+:103BD0003AFE7BBEFBA23B67801DDEF74C1CEE0766
+:103BE0005F9383231F827EAC0ED40F65E90B368072
+:103BF0009FB02FDA9F772D1DAFEC3F7F8879E87556
+:103C0000BB248C9B96C9649F04F9F7A128ECAF4CA8
+:103C1000FEF384D5F4F9A553995D2D031F87D6CB08
+:103C2000458E5BF17BD2117E27AD6028D32BE62E2B
+:103C300036EFE9A139D89FA82F1E3A4CF7DD18734B
+:103C4000D20E65B1BD6F3DE62E09E18F426310D6FD
+:103C5000EF9AA340FEF92BB9BF48043CD1F6F87D9A
+:103C6000B0FEFA78622C09A3B704B4723D3C1FF48D
+:103C7000309CD3677B660D4D82DF23EC526CA047EE
+:103C8000ED3617F82FB38AF3D56ACDBAE4E7AFC69D
+:103C90007B10D6C41E33F803F329D4EAED4511ECAA
+:103CA000CCE5434DDC7F6EC4F50A7B448EFF18CF14
+:103CB000B517F2F88090A792A1261D5E3A25261727
+:103CC000FEDFB27381D26C6F35CCB7B384CC7B0A84
+:103CD000F5686716DC47FFBEE64FE96B03FA3B95D4
+:103CE0002E02718C95BDF367F27CB6F95FCDE7FFCC
+:103CF0009A4C7CC017AF5D7C71A787CEABE3C6F151
+:103D0000E3C12E88F1D60D65F987C4D5F30DE61B06
+:103D1000EE895121AE5F06671E13FAFC79C847840D
+:103D2000F861FD1EEB76F8406ABD93EEEFED90175B
+:103D3000181504BEEDF8639402F663EC70EFBAA1B7
+:103D4000982F386A1A7CC7C7D36E5508FA419E9FD0
+:103D5000C2F348F33D9BFE12F268E4336F33933FA6
+:103D60002F97C34ACEB78BB91C562AEE58388F59B5
+:103D70007440C67B918BD7496377417C4075E03DA9
+:103D80007D218742DECCC097E3813F195FD686E272
+:103D9000B87C67F37E991C94C92CDFAE6C4C1CEE8A
+:103DA0009FEB4209D84EC8AB90D3CDD9DEC761DDB9
+:103DB000654D54BEE938DE0D6913405EFAF8C4E281
+:103DC000027EA27C925AADE183A68EAF14E013F37B
+:103DD0006409F9C44AE1540D1F95F7FA27AE19C9D1
+:103DE000741EB33666E3F79445FDCEA1C24F191C8D
+:103DF000BF6FE5FCB5D81E1C017EADB921CA0DDF31
+:103E0000913F99A8A21E5B738B843F4EB8C65C3E5F
+:103E100015FC8B350F4818DF03BF03F44FD1A10603
+:103E20008BF61CE4EAD0383CAF9E1B1A8E707B8662
+:103E3000F78F8087CAD0951C8FE3C29EF77DD9701B
+:103E400033C6D5BE0C58DDEC3B63FAF85DA1C78DD7
+:103E5000E77FE60366B24D85B89B57C6F3BD4CE2DB
+:103E6000BA5B62F13B88E789F89B38A71371382B5E
+:103E70007C0F5763474F2BAD59B00FE9178F2B615C
+:103E800076FFD31D66766FABE3CF45265AFF71B63A
+:103E900007E3722FA57ADF86F5ACB82CF0A49996CB
+:103EA00057DEFEB413E2E5029F6D4A7004EC97DA28
+:103EB000281E213ED8D622970698BF133347935F1A
+:103EC0001189AF578472103FC2DE08FDFDECFA5431
+:103ED000DC940A3D7E363B24F87B159783552007FA
+:103EE000446B6FE694C3EF9A915C09EFB9F6D91B66
+:103EF000260F424F537E47B929CBC9C4B8BAD0DB8D
+:103F0000467BB4576EBBFB02B0BBAA3746A5EB9B02
+:103F1000F29BBF3FFD0EADAA7DEAB16940A7923189
+:103F20001281734CA39EFC1F2B97089D00800000FC
+:103F3000000000001F8B080000000000000BB55BB4
+:103F40000B7854D5B55E67CE9C9949322F9210C23A
+:103F500023F1CCE441A8018747243CFC3C10082015
+:103F60000627F8155153994404C4BC40B9A642BF72
+:103F700039210902A53654ABD4A29D50B0D4AA8DE4
+:103F80008035AD3C06411A8AD569B5B7F416E828E4
+:103F90005CDE60C05AF116E5AEB5F7399939930485
+:103FA000B5FD3A7E7E9B75F6DA7BAFBDD6BFD65E99
+:103FB0006B9F9359C523E5058500D7E8772B80F8DB
+:103FC000E667923C1CC0BAA21C143BC0BDD896D870
+:103FD00063FD1280D28E3440D43CDB117BEE964DD3
+:103FE00000FDE979234011C02C9DEFC432800C8084
+:103FF000FBDCC07F0DC83410E08B1B38FF742BCC6A
+:10400000F3E3FA608E64C7CF37DD33D92B63FF50FB
+:1040100059E0F3AD889A6DE9C867B7B9B77890FEF3
+:1040200017E52E13C126A40238CD51482DA4F94D11
+:104030006C7E0095C9F36572F7D7F6F9AE080DED01
+:1040400038FEDD5B6F8D2828D7DEE5A3478B726CC9
+:10405000BDF1B285F195A5E1D831005DBBACA14DB4
+:104060002837E07C02F27FB46B58682D6EED18742F
+:104070005D05A4D59D2932EDAB6E770AE3AF4B7693
+:104080008504ECAF7376E5FB519E923D4961188142
+:10409000EBEC493203AEFB59CEFDE3E5227A3E74E8
+:1040A0008AE044A1775ACD807C2BB39509A4B7BE92
+:1040B000E4D7E54B6CF5FD97960BAACB0530B3C45E
+:1040C000A19AB05D7C25076034C043AB67B0F6F5BC
+:1040D00060262A1960EA957200DC5BCD953BD9F326
+:1040E000DA2B298C9EF9DD4829ED075E17600BCA93
+:1040F0005F36F85B2B01E5EB4C86E13B705F9DDEA4
+:104100002C5F137657B7CE60FC65BF9C369DF65585
+:10411000BB0399695C8110CA233D9DB09B48FE8713
+:104120006D5CFC8FEBFF3C46C6F11F8F718C046405
+:10413000DD27B63F395E60F6EC247B4EFEC53FB707
+:10414000FF0FF249574450501EEB1581B57F940381
+:10415000D5A427E40340BEEA6D03C704EC5F054F16
+:10416000BF9664C4A3547D49223C59B12D89EB9F6D
+:10417000A7E124518F4BBAF1F4D5FC609EC6FF65D0
+:10418000786AFECFE3A9B90F3CB5FC3B78BA8E1D27
+:104190007DE089E16CE6218E0FC871F8B600C30B93
+:1041A00093BBD392156A42BE7BC9AE84AF6B504FAE
+:1041B000FA9C47F64D8BE1F5979EC0CF494EDDCE78
+:1041C0009DC96AE192C2AF62E7BB81E2C6BDE9F573
+:1041D000A0E0F379D8C6C70D2BD9AFB0E7FE5EF9E2
+:1041E0009AF16EE357B4F31EB233E1C78D761CC368
+:1041F000EC27935D13ED4E7625BBD7EDB66EBA9ED8
+:104200005D87E7067E477A49B42BB8934D7073BC3F
+:104210005DAC77126E3E0E9B81FCAB2FBB4A1BB888
+:10422000DE75BA256C9E1E62E701A4950F6778398A
+:10423000F4EFE0A5ACA4FDEFB67E0067E4257E3385
+:10424000F2CF29C6AE41D4BFB45531537CC17F8E65
+:1042500067332A6063FAD4E8872353508E994F76E8
+:10426000F7ABD43F75A24B1B0F0A6EAB9BFFB45C40
+:104270001F59C7E46EE5FA0E44CDFEE171F418A4AF
+:104280001D71747102BD91F3D339E266F384D87362
+:10429000C29F308A687D3ECD0FA0ABB41FDA6FD6C7
+:1042A0000EC1BD16ED7DCFC48F2C649FB292E88104
+:1042B000C1B8DFABF2637E7B123EA73888F2DA3DED
+:1042C0002B5B55B3361EF558ADA9D1DA2E2822DA6C
+:1042D000A9BA5808793D3DF568F7E8B8D4D7C5A321
+:1042E000D5381E2C63BEDE78C2091BEF65E3C3D64A
+:1042F000AFB1FE5D134109F512270779B43879157E
+:10430000697D7ED4DD9DB8BF502FFEE6D5E68D9841
+:104310004C3580FAFA86E7E9565B16DA17383E0A1A
+:104320003D3FF4AB1C87A024ECF77AF2BA3DC6F30C
+:104330009F7EB2717CF87AFACAE8315EC3C7222345
+:104340005E5C66FFFE8F510E57BAE056D1FEB5FE99
+:10435000A475E022FBEBF80EF99521B8BF24E8C65E
+:10436000AB11DF6DFE29A8975AD0FB7FDA4AF1CA5C
+:104370006FEAE6E778DF29748F2F40FCB8808F2F33
+:10438000F56C6A550B993D583FA3CDD7C17B7B0295
+:104390003D31C13F347C33FFA4B88DFAC9EB256EA3
+:1043A000DCAFD9ED82007329EE4526F37C2FE2E5E0
+:1043B0006D9387E7770F697A7C586B23C9717A18F8
+:1043C00012B333FEC25060D837D3D3DDE9DABED59D
+:1043D000BDFEDB715F9154182E204EBED3B6ABB537
+:1043E000F996D8F860DB5E8693EEF9D43D113ADF9A
+:1043F000EFD6F4D4D4168E683812C8EF6A1820109D
+:10440000073B0455C47DD6100E7AD967594FBF516A
+:1044100013C62BD275C6DFD973BC92301EA4F4AF7D
+:10442000335EB3D3ED09769C9E60C7290974854E2F
+:10443000870CF14C8F73551DEB5B32508E87B60A9B
+:10444000744C50BCB608230136780EF9EDE308AF82
+:10445000B2341863FE46CFEF23B66100E514CF18DF
+:104460007EDF695572514EF27746BFEB576E22FCE4
+:10447000D4B76422FF264FA4D586ACF734AF972873
+:10448000A779C1F3C75633CE7BF7985F1EA0F9CC4E
+:10449000C2FB91DB3DD7C16B6BC23E3626D06A02B0
+:1044A000FF535F12DF9B13C6AF48E85F97406F482A
+:1044B000A0571BC757CE17989F54A2FD48715FE6BF
+:1044C000373B3DDDF942F77926D8599E64C0FDCCD3
+:1044D000264E1FF07CE85F6D8FA3DB8EFBC9DF7576
+:1044E0001C4BC07FF7A6834AE787D4473CDBD11734
+:1044F0008E0A12CF3BDEFF37FAE740CA3BC1702E6F
+:10450000EF138DF45E51F7B74B91470AE9A14E774F
+:10451000F90348CF7CC6B82FAC0BB5FE8BFE29E85B
+:10452000FF33BFAFF75FF453DCD3F7A9F3977E7E79
+:104530004DA4F58EB45DF06FC6FE8AC9E1BC7A94D5
+:10454000B32295B778CE88748ED5D9B83F95EE1240
+:10455000FD74CE542487F39616C6ED13DAF3699FE3
+:104560007B978BCC3E6A13AF47AAC067012C85F6B8
+:10457000BA5C0D2F20FFBEE562039D6BC71AD232D5
+:10458000A89E18EEE579DB3ED70D190F20BD3765E3
+:104590009E4546BEBD8F4F65ED9BA2B2AA0B71FC36
+:1045A0007F9ECFFDF661D4EF62FAF947DB157F23DA
+:1045B000FAC5671E99E93390EACEE8A07C75AD0490
+:1045C0005B6492C7F73CC3CDF7AC23D7A21C958D93
+:1045D000376650FE56F5C3F2D281C857D522F9048A
+:1045E000C6072348EEC0DAA916EA9FDFACB5EA3465
+:1045F000D6EEF962FBA111C8DFB546F46D42E6DDE7
+:1046000057BCCE2A94EB78128FC31F9ECF75929C15
+:10461000EBBD01C98B72543A1DC9021D1E6ED939FA
+:104620001BE77D2247B1788B62FC7BBE10E751BE51
+:10463000F9C6F9AA0CB29FDBCBF1BAFB4A55465535
+:10464000DC79BFE08299E9798F457E84F2CB3DC960
+:1046500059822A303DA795A3BFCCD7F26BC44BC378
+:10466000F65ECEFDCF3D22D3CB096B031C4710EF86
+:10467000FD6EFF8924A73EAEE8FD409383F03C44E5
+:104680001E159F47F7CB9E3C84F611C359DA1F08CD
+:10469000372C8F467AA8D7BD5E455CC13ECCFF491A
+:1046A0008E74A594CE0158810C18C720B33D3FFEEF
+:1046B0003E2296A7AED4E201E73BAA3A58DD7AF44F
+:1046C000A5A410D53347D5BF3AC01ECFCFFD64A1F6
+:1046D000D3A1D2617CCAE130935E8F998327BF8DCD
+:1046E000E3163C27B138BAE0B9FE2BBA281EA03D2C
+:1046F000F3A0E7BAAA5762F3F4E927E02937F8896B
+:104700002A972BF6BEFD6492572EBF9E9F2CD4F2A3
+:10471000F6D2E7243FE17C6191C30C18AF273FF745
+:10472000D616C2E3C22549A3AC28F8C2E7ACCCBE7A
+:1047300051874375637FC0E930F7A3B8EEE5712474
+:10474000DA98C4EA1431C3C2E29EB8AA4826FD949E
+:104750008860B6E1B9223A7DB29FD3CD6EACDB5A08
+:104760001CC532D9F73B5EEE0FDDFDAEB9B7095877
+:10477000D75CC67DA4E1B8330D4F3E3D16E53B0B3B
+:10478000A1396351EF97C9D0B8CEE51D6248A57332
+:10479000C2AC98CB30EE2D02EEEF3507B75B26E1C9
+:1047A0003F17D52FBC9DEAA30743D28751ADF6B979
+:1047B00086FF7F026F5B28BF7D68ABF1397A8C85FD
+:1047C000FCAAA6DDF8BC0ED65D1247506BFE305A2F
+:1047D000A03DC7751B8EFC65F8FE38BE5AAF23FDA1
+:1047E0002496E0300A46A166719D42D75D04BB065F
+:1047F00091C92BAE4C0A911EC56C7E3E4C03219490
+:10480000448070E3BE71DD4F838787EF4740888F18
+:104810008D667A3911443C0D457D386D8C5F7C4C3A
+:104820000C5971DD923450FA913E9F2E0770307D05
+:10483000AA6EA4A7A5D79B293E9DD3E24BA500FE57
+:1048400076E6F7BE6CAA8F173C97C4ECB7F0F90771
+:10485000FFFB4763C85E65E9F17EB446C31DCE0722
+:10486000B6D4D83CA71ABF934DF294FC04EB4AAAE5
+:1048700037C5C0D377B37899E26371CB1DFDDE589D
+:10488000C24963CAC8B540381998ED2D8C8D5FB800
+:1048900072793E1F8FF5AA93E25512DB4FF50E2B6E
+:1048A000C349E51A5161E76396859D8F1F3627310D
+:1048B000BA7A4831F3B34A1304681F980B66B2B84A
+:1048C000CE550ED57650B6DB29CEAF8B884E661FFF
+:1048D00055B39B85ECB3D99BC6FC771EE918CFADC9
+:1048E000FD84B322361FBF7FDA2D84B6B0F8542F73
+:1048F00093FF57980416E712FDF1352FCF5B2BB3CA
+:104900007DF7D1B89A27ACBE951E2E83A8CB8378AD
+:10491000AA314516FC98E6FD9595DD6BD4E13E92F3
+:104920009CACBE50B6A1FC7566305BE85E4AE6F111
+:104930004C97A74E2E9F4638C5FEC366ECAF71F06C
+:10494000785CD38FDFF780C316DA12BF1EC99CC311
+:10495000C7C94EF2B3710C2FE4F726ECFF08787F3D
+:1049600089B3588EE2F34E13ACA67B129267D888B7
+:10497000B875911E3882F0B8C4EC75901DD2E6CCA3
+:10498000A5F55E16595C42677AA298F2BF97C5D129
+:1049900054C756AED957BA81E85747BA4984CA575F
+:1049A000DE63E7D3431ACEA294F7D37985F4ABD86C
+:1049B0001ED5E24240E4F73847498FFD637AD5FBC4
+:1049C0006BD648CC1E352D1C0F358D7F66F3D6383F
+:1049D0002219648F9AD7A49B09D72735B9AB1AB38C
+:1049E000261E467C54492EB7808FAAD5320BD1D5CE
+:1049F000AD02A3F5F56AD6FC29C354C8E7A3D6AA2D
+:104A0000E128366FFF6C3ACFCEBD94965D1967F7FB
+:104A100073CDAF3B653BF94D38CF4DF7304B927CB2
+:104A20009B989F727B9C6BCEDB44F734F3DD118740
+:104A300080FDF31FC949A573EE983B6CA1FE63EDA1
+:104A40001E13D18ADB3D9168C57C13A3CF61086F2B
+:104A50002FD4C08B76AA15386EAA5FDA67F1E27A96
+:104A600029395C3F175E7E2F9FEE0B6AB223F974E3
+:104A7000FE22AEF207935D5E14589E50FB92A8246E
+:104A80008D88E1AA967085FEBF58C355ED8ED71F5D
+:104A9000253FAD253C8DEA894BAC2BF7B3E7DBDA3C
+:104AA0004A818FDF4FB8D3CF7BA49B25BA57B36819
+:104AB00034AE43B43D87EB1FFBA7F07EB5909D233A
+:104AC00010B5503E5C27F23C01FD2993F288BA0EE6
+:104AD00049ED8E97B42EF517C6FAFBC2CDF01C93A4
+:104AE00066672B3B8F86E770FF8BAE79CD49B8B8F0
+:104AF000F0F2BE03E3A9BEDA26B829DEF7F0434D93
+:104B00006F75A42727DB27CB8BEA482FCE989EBA58
+:104B1000FD4DC3451D703DE87AA9336B7AD2FBB5D4
+:104B2000F123343D5483A6D71D43B9BF6BFEAD9F1F
+:104B300023FAFE02A97CBC8EAF79DAFE266A6D35B7
+:104B4000E2C657C8F0A5586ED6EA7EECBAF06A1BEA
+:104B5000BB37D2EDA9CBFDA8B63EC669A55F6ACC2E
+:104B6000CE51132CEAED9E7AB6862BC9CEE3CA0746
+:104B70008D83EF6B40FD2D7E49F431E551CD15B7A6
+:104B8000AED51475B0BCF431D14DFB2AF945F96DA1
+:104B9000B46F1D77D256C1DC3186EA8C7E4CFFBAE9
+:104BA0007C2503FCB7F5E3B80B933CBA9C1F086166
+:104BB000662FF555C1CDF3DCA885EE0F753F4D94FA
+:104BC000779E666FD1298C176E22797C32F937E097
+:104BD00039C8E4B11F5ECED6538F2EF78C88AD73E3
+:104BE0004C759889EF18F038A0E3F203ED3EE283AC
+:104BF00096D7591EACAFB34CD34BDC3A8186F49EAA
+:104C0000EBE8FC351ABFEE179DA91CFF25CD7F668A
+:104C10007C7A9CA51FDDC3E9FAD4F516E79706FD5B
+:104C2000E8FEA5FB936ED77FD5AF60457F96AF3E7C
+:104C3000AEED9BF94846EC5C207CD27967B5202E1E
+:104C4000ED867393E535D3865CB2047A79AEEB29B1
+:104C5000F179AC9E726793FEA7D9334D94074073E8
+:104C6000E6FEDCB8BCEC38DD77513CED0FFC7D0690
+:104C70008694F8F35CCFD7F4F31A7FEBBA7189E32B
+:104C8000EBD29533D4BF68CC927CCA232EE578D979
+:104C9000BA67A1DD3209E7AB3E1D2975CAB17AE5D5
+:104CA00096BF874517DD07EEF018EA85EAF3FB9912
+:104CB0007FD7406415D5B7956BDE2B1B4B76FF393C
+:104CC000E6E3C837BFD5C3CEBD339BEF1F4DA56C00
+:104CD000654B1EA31FDCF200A7D7F07CAEB2A5E89F
+:104CE00005BA8F3F9EA49412BEBBD60B6EAAB72600
+:104CF0006C295A710FF64F70DCD08FE43EBAF97808
+:104D0000D978AA1B1A44E62FCAE627E750BFD2215A
+:104D1000FA68ABF3C1BDE21EC2B7D9C5FCED987607
+:104D20004E34491C676F6B71627F0E3F2FF76B38F3
+:104D30002C696ACA37D1BA6D783EE1FE2B2C727BA2
+:104D400098EABE5D037C9B485F58A666228E4E0B98
+:104D50003CFF5E64011BE1EAA0145946F21F5CE6C9
+:104D600018D9480288576FAEE2753A8B2F5837B181
+:104D700075757DE9EB1FD2D6D5E7D1C775523E4593
+:104D8000E78726EF99E69FCFA13CE1CCD6BC5488BB
+:104D9000D3FB19DA17EAFB418C8BDB7AA9FF0EE70C
+:104DA000E8F7AB21D62ED2EE0D0F4AAD43E8FD2D2C
+:104DB000E6F127E2F3F2536D4936C223E6F1C6E786
+:104DC000123F4F308F373C47BF3961CCF7B5FA4EB1
+:104DD000AC70057A89437A9B98E79FCBB1A79FBCBB
+:104DE000117AE4F9BADF258ED7F3FAEE7B9623F633
+:104DF00084F731635D709DF5CF07D13058FBFD948A
+:104E00007C17C74F49F97C7B84EAC956ABDB8AFA29
+:104E10003D417E45EF015F13799E68035F18717114
+:104E2000E24FA37DE4870B8E70BF5BD02E84E81524
+:104E3000FBFEF58F8BC4FFC0460106087175D65383
+:104E4000EBE790DB5DF605560D44FECB5B059FCA94
+:104E50002454EC09F5D5818172DFF5D5BF5B57E9A4
+:104E6000F74C897A1F94ABD5573EF019F5CEEBF38A
+:104E70003D089FE2513DF57E3E186075D4C5E022A5
+:104E8000D68E6B6F2B198CF27F247CF0C404F21F3A
+:104E9000878BDD939C0FD6B39780173B465F9D852C
+:104EA000FA79C3EE7253DCB8186C60CFBBF1A2E1A3
+:104EB000F3961D7BC5C1C0F8774E40FEDD7617BD69
+:104EC000D6E8E57D1BB72F40327F3FAAD5DB0F2FF9
+:104ED000193B809EEBFB3DFB6D6E675DFEB35BEFA8
+:104EE00077527EBAF7C7693BC7917D535C6E82D11A
+:104EF000C20D220446633EBC81C7A1D336D70B74D2
+:104F00005F7A7AE39D19540F3E2075597C38AF6F54
+:104F100057B993EE41FED71C75BAA945FE30C96159
+:104F20000E8914FFC64F07F61E707CD80CB287BDE1
+:104F3000A267381977DE1C0A237D8EDE0FD2B97D79
+:104F40003599BFA7D7DEFB3DF06B7E9FD67D7FA254
+:104F5000DD234CD0F6FB5FB9A91CE7DAF39262FEC1
+:104F6000FCD4C6EDB368BE339B2537C97B71B3C48F
+:104F7000E65F8C75BC0971781AF146F16BF1FBA202
+:104F80008F207D662BAF9317236EE9BEB86689A488
+:104F9000585C3DF158A2F3ED14587DADE372B112A7
+:104FA0002A657AD7F069C3FFAEE191D10FDA579144
+:104FB0003E1271FAAFD6FD35B9BDD7FD8938D0F5AF
+:104FC000A5E321864F60B8D4ED9EDA3E72D26036FA
+:104FD00040657A54274301E5054D162830130E4CE1
+:104FE000C93EF2F3069B7304DD337D9AC4DB474D63
+:104FF000EEB7A85EFED4244B02B6D15C0F1BFFA80F
+:10500000E89B4AB4941E65F70362894931D179D788
+:105010006465F12231DEACC9E571382B8FC79B2D59
+:10502000B96E9E3F423DCB1FF416379845F949793A
+:105030004AEA2732B23CBD79C66C33EEAF7C42EA15
+:10504000B21CCC2C9FDF7CC76C7AAF5B3E3AF53547
+:105050002FD2A1DC59BCFFA6D42209E9C646FFEC39
+:1050600029D8BF2B57792AB728B68E3E2F3E7F8688
+:105070009EFF7640E0D9DCFE749ED95753BCFF48B2
+:10508000E8AA358931FE3F0870EC0D21464725C856
+:10509000A67C7A4B2EB07DF4D59EC9557E9ADBCB8B
+:1050A000F32A8016D26395FADBC394AFE1CF6F4346
+:1050B000BCDDA1E1ADCA660F132E60B574BE1B172F
+:1050C0005E8A4B2E33F9F72CCDDC7798C37B69FCD5
+:1050D0003068769FB4B15470E3B5B4BEE33C3A2671
+:1050E0009CD4E7C3FD7D24E17ED1AE8282B6469793
+:1050F0001250C91518DF849DBFFD8CE66D52219AB0
+:10510000C4EC50E1A6F3488080E91AB63529880737
+:10511000D4D3D2D72EEC27F83FA8E75399FCFB8CC9
+:10512000651A1EEF8828CFB4A150A782909E8BB637
+:10513000BE006F5E34E3BA674C8183A4976AD3DB09
+:10514000D94B65F2DB2627E52F175E117DB7E3B853
+:105150006A2D6F87AB62F8567CDEE919B6696D1C63
+:105160008EFE98CBF394F39E70F6728A1F1E5E77C4
+:10517000C2D57DD9CB917FBA7746119D4B4F81F235
+:105180007E6EDCFBC559E6DEBFBFF8FD209E77C012
+:10519000667EBE5ACDA03A52590B4ED4C70C94A588
+:1051A0001869096991BD8F0F313B129F93F214F971
+:1051B000FE4CFEBE06FCE48FBA1D75FBF4B01B8AE4
+:1051C0004CF9B9C90612F9CB30D8E826FFD6ED372D
+:1051D00055B4B378B3F4357E1FB7548836A711FDA4
+:1051E000329E97A42FCD2F7B9E9B5B2C648A451B00
+:1051F000EF67F1498F4B32FE47F8F94FDD4B0A79E3
+:105200000E9EAF8C849184AB2FCB77F4B884F6B12B
+:10521000E57D1DFB908A70BF0BB5B5A78A15B299C5
+:10522000F4D2DFE6A3B8BCF4B91C76DEC1BA1FB075
+:10523000FB0F9D0F36A6317CAEF288CC8E651D83A8
+:1052400041C6470F760820E339777B471AA39D575D
+:105250000632BAEC67032653FEDFFDDEF267431920
+:105260007DE685436302FC7EC54672F84197A3B094
+:105270009DF2A1CB769403EDE0B7AF66F7857EE8AB
+:10528000AE63846B02D18812F2274552B95D6C8DF2
+:10529000CCAFB57D2D75733B2E3DC8CFDDA593F802
+:1052A000FB3DB33ACC4578903A450821FDCD836269
+:1052B0005118599BB4B86CCD34811C678F243919AF
+:1052C000E4B8FA0D54254275D25C0D272905A9864C
+:1052D000FEC785804472CDB52F60B871F80619E617
+:1052E0008B649776327D04787EABE309C4F36692D3
+:1052F000F3938902A4212EBE3917FBE3E695265EBF
+:105300009A22B0D69817A35E4E5C0F4F33F3B4F3D6
+:105310006E180C63784AD00FFA07CB3F2FE3394E53
+:1053200069136617CF4C447A4EA7042199E59BCCAC
+:105330007F2E2B29ECFEBE45D3938E3BFF50702869
+:1053400038AFABD8A8B77E8A516F69D38D7AEAEFB0
+:1053500037EA65C05CAFA17F60E01B86FEC18B466B
+:1053600019E8ACFAF106FE1B1A261B688F7A9B819E
+:105370003F67F56C039DD77A8F817FE8862A43FFCC
+:10538000B0D06243FF8D5B971AE8E1ED8F19F86F9B
+:10539000EA5869E81F195E6BE81FDDF903035D1425
+:1053A00079D6C03FF6F02643FFB8E88B86FE09A702
+:1053B000B719E85BBA7E63E0BFF5CA9B067A121C98
+:1053C00032F097D8DE33D053DD7F35F04FCB3C6ED3
+:1053D000E89F219F33F4CF2CF8D84097F9FE69E07D
+:1053E000DF3828F02CC59FB9A6754755A0F82C7F4B
+:1053F0007F22E2F9AE74B32F4C4C5FB36EDBA4C7CF
+:10540000410DB79F80FD3E93F7CBE3E0E35A5E305A
+:1054100055BC1DE8BEF772BBC070DDD7F9ECC27C8D
+:10542000D71CB78F7E8A0D0BF0189D36DD6DA0FB63
+:10543000FB330DFC03E6CA86FE81810243FFE04593
+:105440003E039D555F6CE0BFA14131D01E75BA810E
+:105450003F67B5DF40E7B5CE35F00FDD1030F40F14
+:105460000B2D32F4DFB8B5DE400F6F6F30F0DFD4B4
+:10547000A11AFA4786571BFA4777B61AE8A2C80658
+:1054800003FFD8C32143FFB8E85643FF84D3ED069A
+:10549000FA96AE0E03FFAD57C2067A121C34F0978F
+:1054A000D8FE60A0A7BAFF62E09F96F981A17F862F
+:1054B0007CC6D05F7D0EE147F9F31B027BFF35B35D
+:1054C000E092A15F4AC73C9DEEA721D9270A3DF390
+:1054D000743D7F2BF37D6658E751533DFB2EEE5311
+:1054E00013CFEB6CF9FC7E0BF3779B8DC5593CA178
+:1054F00086B3AB9646CA4F5DAAC07047A94605BBA6
+:105500002F4C67E72A3B1A65FA0E0DF31B24524D08
+:105510001E0FD50F29B13C74C8B5D15F3D0FCDC862
+:10552000078EFFFC404A7E11D563AF96527DF22074
+:10553000A8AB480E3C5F5DF49EE99D24E3BD91DE7F
+:10554000CEB0A1FEE2D63B98D43A64D475FC768600
+:10555000ED3CE3EF9E57BB5712707F4BE3E67F02B3
+:10556000EB26339690AD41F42FF4D31F04DD8C7EEF
+:105570002A98C9E8A783326B37040B58FB6CD0C755
+:10558000FA37068B19FD7C50617428389DB59B82D3
+:105590007EF67C73702EA35F080658BB35B888B5BD
+:1055A0002F06EB59FF4BC10646BF125459DB1E5C58
+:1055B000CD9E6F0BB6327A477003A37F150CB1B640
+:1055C00023B895B5BF09B6B3FE9DC10E46EF0E8652
+:1055D000191D0E7632FACD6084D1FB8387197D20A8
+:1055E00018656D67F0346B7F17EC62FD6F07AF30A5
+:1055F000FABC76DF5F926F7CAFA6D30053181EF41F
+:10560000BC7616D52D048E62E9A2A16E49A81F12A0
+:10561000ED71565B479A8CC736E53983F23735C54D
+:10562000E5FB7768EB3D9E0C6A12C6BF462AE61181
+:105630008A8DA9106A62EF5779DEBD50C325A4F3A5
+:105640007C7B8126D742CD1F8A089F050C9F6F7FE8
+:105650009D3A49AF93834302F3F2B15D9C6552D901
+:105660003D813D944F79FFA621812AC2EDE5FA07DD
+:105670000EB0F5DCBE7C5AA4CC1AEE7F17DDFF1C01
+:1056800014D97D695FEBD5697FBFD067FFEE3343E7
+:10569000E81C9AFE85C8EED3DF911C73E97EE49185
+:1056A0007CFE1EE3917C93A11D96E57F98E43C95DA
+:1056B00057FFC2C3C852B124CF4579EB1D545AA33A
+:1056C000DF97832CB1EF6341798B3E99FC262676D8
+:1056D00044DF052A6BB70F0EACA0F177630141746C
+:1056E00060BC35BBB7FD24CAB34AB3D3AA7C93A12F
+:1056F0002DCDF2B7D07C27F214833CCBB364EDEF11
+:1057000064BA9E27B9FEB1EBD2492127A66FFD5E90
+:1057100062D524EDFBA92582FE9E9AE78336D0F35D
+:1057200041D65FB18CDFCF7C0BEB327A5F79448B53
+:105730008797EB25162F2B84641FE5D397EB970DE6
+:10574000A5FD24C6CD0A1C67C27115C0BF87A83845
+:1057500092C2F085F301BD77ABC0CC9DEABFDA2CD5
+:10576000FDDE236AEFCFE551E83DECBC9DD636AABD
+:105770005311279B591C1B27AA16AC93DF3185F2C6
+:105780000591E1C322A0BC0BD3111FBDE4053A0E65
+:105790006AB5BF8FD19F23BE5EA1F92EFE7A6C0140
+:1057A0007B6FB27B9C4CFA6B32A13DE8BEE6772260
+:1057B000FF4E82AED8E93B0E57611BFBCE9F92088D
+:1057C000B2D738077B1FB2578486577B899FEF6A11
+:1057D000387A27539A1E62F31ADFF3756A76ECD48F
+:1057E000EC5BF6E6C1AC4771DEDA4E89D53B30267C
+:1057F0005AE8EFE5FBA6BA86430373E3F651D7F107
+:1058000001FF2E0AA285F1DF439DD2D6D7F1245A9B
+:105810001C81367BBC7CDDB87E47C3F549CAEB678B
+:105820005965D75D38348AAA09631BF8899B7D576F
+:10583000A77F5F371FFCAC5D8870201CFBD5F5ACE3
+:10584000FE5D0CEDEC796DF1FDD944D741D7944C58
+:10585000AA5F5637BE9589D2DDD9BA7E2ADD3FCF01
+:105860000E55BE456DF966E124D5DDE8177FA3F539
+:10587000A3427D0B95A4F7BC34A985EE796789DC3A
+:105880000E7088DB0171A488A93DF7877E7052F302
+:105890000326BFEE07152B397EF4BFC7E8F68BE26F
+:1058A00087FE3698DE7D98BBD8772175BBADA9847D
+:1058B000AFC554798AF179A17E3EF3BCE021CC0BCF
+:1058C00088EFACC4ED7FF66812FBBB97B302E263CE
+:1058D000544FDCEB79E6A7267EEFF6A8885B14A987
+:1058E0005E7E92E969912D3482F484E7330C255C65
+:1058F0001F6F5F3592EEFB2687B2295F955EB4FA83
+:105900009A3C86380FD75262F7784F48FC5E2D518B
+:10591000DE1E794BF181CF289FB05A40A5F749E8A8
+:10592000FFDCEF8F71F93F3505326F1679BEC2EAA1
+:10593000E8217E56FF4386CDB756E8B97EB3B66EF2
+:10594000E7E7BC9E56B3807D8F932887E0E6EB2681
+:10595000CA634DE672E8E74E4F79B81D74790A863E
+:105960007AF8FD7DB6C2F6DD68EAC7E2D747626025
+:10597000E8503A2FB5FB31BD8EEDF49C62711DAE3F
+:10598000360DE1DFF786FB3A4FCF77D7CFDED879F8
+:10599000A7DF33C1C4DEEF05FD36B744769B0D3E6D
+:1059A00016F787C1115D3FEC9EE9FF019ECDEE1811
+:1059B000B0390000000000000000000000000000FE
+:1059C0001F8B080000000000000B7BC4CEC0F0A3BA
+:1059D0001E822538106C62711D0B03C30756D2F569
+:1059E000C17025507F0910E703711610A7027102DC
+:1059F000104703711810BF069AFD0C881F02F11D95
+:105A000020BE0EC49780F82C109F40B277191B035C
+:105A1000C35A36D2EDFF83E4E78940763910CF24AC
+:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2
+:105A30005479051E047BB92065766D03EA0700E9F9
+:105A4000CD424A800300000000000000000000007A
+:105A50001F8B080000000000000BD57D0B7854D58B
+:105A6000B5F03E8F79253393C9839040C493970452
+:105A700009382421F2AA1E0842A4D406F42A5AAEF8
+:105A80000EC823869044B02DB7729B21092F411B6D
+:105A9000152D5AB483458B0A36F268D106EEF028EC
+:105AA000C65BB4D1A282D536D45B450B4944116F95
+:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370
+:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5
+:105AD000D9C6E42B19FB027FA09CA330C60644CA9A
+:105AE00051775EBB687B09FCFE99DDFFB8166967DC
+:105AF00094173389B1D1F09E653056CAD8954EF8C7
+:105B000015DA95BD70EA0F97A531B69F29CC018FA4
+:105B1000C26A59EAB7A09FFD9F333FBE975F706787
+:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2
+:105B300057881526E373DD49BF433FB99BEAE0FB75
+:105B4000B39FBAE97B2B1C46C93E9759587CF34555
+:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69
+:105B6000D780F7D0DBEF11BC075480578B33BE13BF
+:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D
+:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7
+:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82
+:105BA00083CA46153E01381AB7B0501050EF2E8404
+:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64
+:105BC000FA2988D455B766AA37BA2739036E1C1F3D
+:105BD000E6EEC0F19D5402984733001F978A79BAC8
+:105BE000B4E02C06EB91E7B66B2180E352F782E933
+:105BF0006C24B6CB27BCD9055E9764367420BC1FD5
+:105C0000433B06F31DE69EF23EF332F69FD94FF07A
+:105C1000796C606C203C5FFDEF751D12F4B732D3D8
+:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B
+:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9
+:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A
+:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63
+:105C600029E03C3525D2AF314EBFFD023954C0B7D3
+:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85
+:105C80002A0B65F3E769C01779FC57D6E49B94109B
+:105C9000288C8587458F93135997BC34FB1C19E8D2
+:105CA000292FE3FA4512D25573D4FAE63066F0CDC7
+:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7
+:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03
+:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5
+:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1
+:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A
+:105D0000B5A364A901F19CC7F921CF1676E662BF5D
+:105D1000CD39A382D88FFF55E287BCFC4B3405C632
+:105D20001D9627F861F4834E94873DF35F96AEE7A6
+:105D300015339664A103DF79D2816F42DF74F07569
+:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32
+:105D5000963CBBA664C7C295797138A3C21D4B6F30
+:105D6000797982CEFC7DD399B57CB03EC4DE011A30
+:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA
+:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A
+:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C
+:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035
+:105DB000D575DCCAEE928CF6CF0675C0778A683F3F
+:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620
+:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4
+:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9
+:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2
+:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF
+:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1
+:105E20006F64157912AC43E6F48A0C06EB6FAF6829
+:105E30000EE296DB039FC077647E0F12BCAE0CFEB1
+:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B
+:105E5000731441AFF20B594B8F00BD2A49763FE9CD
+:105E60001BD701D364C278B32A980670C969150C90
+:105E7000E58192A6BE1BCD0706FD019C6309CEC934
+:105E800015B37A8133180DA701477F701B70F44E4C
+:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C
+:105EA000F9515D48453C4157ECF35B8336789E3AA7
+:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128
+:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501
+:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC
+:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B
+:105EF0006DF75B49A2F1274D19F36DC6C7630E908C
+:105F00005FC9385E5164BCE469301E76A636C71D91
+:105F10002F65328CE7FCFAF069E547035E7B0CBC29
+:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6
+:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E
+:105F4000F94865E12B015F775CE524FDDE9073FF86
+:105F50006C7CA5E2A7B07E77BC547CE24A192B404A
+:105F6000D72322E3D74A1AED57BDD1776FF3810DBE
+:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63
+:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6
+:105F900037571E291BC8A05FDB9AE14C8749256350
+:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F
+:105FB0006F02A56BB7B782F4A29512A3EFD783DE69
+:105FC00016023DA6E4950DCE3958F7EF70CEC1719B
+:105FD0006D8CF4E992570EF9CA80CE5D23524629A2
+:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B
+:105FF0007FF0BC02DB2788F6BDC1959007F044AD69
+:106000007FA2BD395011477FD76599F0F390D0BB7F
+:10601000EE46BD0B047262424B00F56A57BA5D7BD7
+:106020004C8AFDEE265912F306BD0DEDEC115332EC
+:1060300051CF3A30E389157684AF90915C77E5854E
+:106040007419EAEE02CEDB0F59F67D37AE21E95D19
+:106050009952994ADF99EA77F7E831D913516FF3EA
+:1060600016F0F7650D574C6C8C7ECFFC1371FF3525
+:10607000DE071A4AE97DA6B3E2D804183F13E468A4
+:1060800023E02B536D96EA685DD3E2EA8F1BE63B73
+:10609000678500860D331ECC9E1F673F81D534F186
+:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104
+:1060B000820E41BEB978D31EF9E61ACAE55B4241A9
+:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE
+:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D
+:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03
+:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413
+:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA
+:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951
+:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB
+:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF
+:10614000EC79EBEAF7D1CE4EED9843F676536151F8
+:10615000DB246897E4F7CD984274CA08CF6BB1335B
+:10616000E2BBAA1513615E8D8CF3DD66F996895C3E
+:106170003FD069BDBF2B70062BAEA950477665395D
+:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5
+:10619000F94EF8FF9690DFB4BFEFD8743BF9118346
+:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F
+:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029
+:1061C0000AB63CD987F67A12F325AB2867278342B3
+:1061D00000A2D897D61D94B5FED7A589B1F29642F4
+:1061E0004E7733A2F4DC0E99EBC969332767AF848D
+:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1
+:10620000E1283FC7BAC2C7887F1B819E72802F8258
+:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36
+:106220007D304D2D15FA1FE047C99375D7C8AF4E85
+:106230001FCA97A48FC4E951DFB10B5FAF24E5C239
+:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9
+:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7
+:106260004F84E2F49FA64871FD39567D9EB1A5A6E4
+:10627000F5520696CEDADCD7BAA599F161F4EB5A5D
+:10628000A668FF85C24BF5915FDC29FA5BABDD1791
+:10629000C4FDF32CEEED800FA5795418F53D96C79B
+:1062A000FC8FF326A487B8343D443A24CADDD208D3
+:1062B0007CF62CD9349E9A9660C2379B05DA761408
+:1062C000FCAE657682C389E3C1388A0F3A94D0FF69
+:1062D000CFC22E2FF548FDE1505FE462FD4E131D45
+:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E
+:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA
+:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1
+:10631000CAC6F64849200F32AE67010DEAF80A36C0
+:10632000EB35588E453A2CF2915EB05552114E62C3
+:10633000690DFF737DBE10955BE84F7606084F8AA6
+:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88
+:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77
+:10636000578747A51138ACFD162A811F2A0390ECE8
+:10637000383CF801FA09584701F9B5F305CECE3D8E
+:10638000303389F5C15F0F59F8EB2189C3C92ACE93
+:10639000CFCE380763B6637B359040F1B29305C426
+:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5
+:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE
+:1063C000DFBF59D831C6F3738A4C70EC137CFF845D
+:1063D000B32281FCE7076F9C360CF82BE7A8E24755
+:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343
+:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D
+:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6
+:106410001D2F9B85FD79AEF1772B48CF095F49FC95
+:106420009923E448CE3C2E0F72AB594843FEFDFC45
+:106430000B164D1F6099109E32AB558DFC4D4C775D
+:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5
+:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6
+:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1
+:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44
+:1064800012FFF9EB105219D19D51D72456116FFF0D
+:10649000FB44D0A9B6E210B743C0F87B272A1E01FF
+:1064A000EB99829BC04F83F74D44BB35B886F9F317
+:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE
+:1064C000DFB117E5D50466925F71E4864DC5EFD262
+:1064D000B8DC080567F2F27385E265F9EB5908E369
+:1064E0005B9337D4ED47BF5E6635B79B33D7042542
+:1064F0003BD473EA981F87C9AD64BCFD6C16D27992
+:10650000BCE66806D0CD104137430C7A5966A69791
+:10651000C17596B8D01A737D20D2057C37D0422F32
+:10652000D67E723446F1B8BCF5328F17CD32C77DB6
+:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5
+:10654000F6AFB24001E265F70FDDFF590013FCD949
+:10655000FA49A98817902749244F2AE2DB3D31F4F4
+:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766
+:10657000CE0538D67A7446E307B349AE2B225E794E
+:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5
+:1065900019970C8C96F78AF02319F546E147B28ECD
+:1065A0003755E57AF07B4C9F8A7818E50864605C83
+:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF
+:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00
+:1065D0003377CA79E1A3440DDCA442199C04660414
+:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161
+:1065F0002E8879053DED02D06E84A9DD3C9C0FB458
+:10660000D34DED2A62DADD26FA63A671F598716B37
+:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777
+:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9
+:10663000A6719979DC9EF7A576E33DF9630FE44FE7
+:10664000217A39943FA57C2E8CB3F4451B97115BBE
+:10665000793E874157FB45BB26A4AB42CC5B6163C7
+:10666000AA294F85E7AD34BA673A0351CF7BE8CA10
+:106670003DD317FFF95C537B758D8BE9C5F49CDA2C
+:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C
+:10669000AE69D05590630354537D4D86786FBBA689
+:1066A000810262223E02B2F29B8551FCDD33FE3F45
+:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1
+:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7
+:1066D000F7FFE6F95559E65765995F95697EF69596
+:1066E00055938279FF97E6B7CC32BF6596F92D3383
+:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A
+:10670000F35F27FD7FAD88E326ACD41B56E07BE02A
+:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9
+:10672000548DE482D323935C60F9F6507E36876BF8
+:1067300026C885E7541F97DF02CED72CF50F2D759D
+:10674000F8E56FB86FFA9861475AE47C3FFBDACA04
+:106750004CBE9FACF2F8E5E87D4D15B83938A094F1
+:10676000E44FA38FCB9FFD03843C4A837D8DFC4483
+:106770001924AF6C425EDD57CFF3D89A457E506343
+:106780005A11E1A759D80B2C9465DA370F4C9CD2DB
+:10679000867EAB334779DEE23A1BD7C756D6339DA8
+:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F
+:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C
+:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56
+:1067D000503E20F4C52BD264F2576CAE872D339F08
+:1067E000F4482A1FA9F78D5561BC9FD46750FD233B
+:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8
+:1068000069429A4AFB2F53C34A5249E4B981D78F50
+:10681000A44957E077E33264DECE196AF4C66F57B5
+:1068200086EDC664A8040F7307156F5ADC76E5364B
+:10683000C04BA95BF4E70B347AE2F7F72D6C57E411
+:1068400016FDA5698DEEF8FDCDC47147FA381E58C6
+:1068500046474362FC763760BB429F986F56584E5E
+:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8
+:10687000476D69DA66292A3E141A50C164A0F39460
+:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024
+:10689000679B1BDE17624E138F478DBF0EDEA33E34
+:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50
+:1068B000A397AF613D793C98BC646B32D79365CEAA
+:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767
+:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723
+:1068E000A27D4A0A9FB76B8A338471B147BE7B4948
+:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01
+:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2
+:106910002D977B7264516E25371792FC1CE5A820D9
+:10692000B9336A60A98EFCACACE770FD87EDAE862A
+:10693000863C822B88F2C680EB278BCD700DAE3162
+:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1
+:10695000E083F1F5E8F11FFD37F3F8437E601EFF99
+:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765
+:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28
+:1069800051FA78922D70C426F45D255AEFAC0B981D
+:10699000F45368F78A681754A2F5D840C0A49F4200
+:1069A000BBD76D42DF35B5AB8869F707D11F338D93
+:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB
+:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B
+:1069D0004BB463A67199795CF82950A19FEFB30479
+:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0
+:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08
+:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F
+:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C
+:106A2000BB8399D746BD1F28BE5F23E2D469F6D247
+:106A300046942BBEC1D03E8EBF22538C6BBC67697F
+:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729
+:106A5000BB588C9B151FAE35D97CDC45386E213E6A
+:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC
+:106A70000578593DD9292B49F07E3DF76F1A7EF6EE
+:106A8000647B9D13F3761B2F92D963D82EAB6F3F97
+:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401
+:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759
+:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C
+:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0
+:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB
+:106AE000939E959C3293F4ABE486AB9DBE38DFADAC
+:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC
+:106B0000614DBEC7F83E94093209E33F693BC2C8F4
+:106B10003F674BF8790A3523149428CEC1E7896A78
+:106B200025FE24AAE1A00CED076D54593895B1FB60
+:106B3000E5C08D881F575E33F9C7549F2E219ECE26
+:106B4000D94257D379025017E3E57FCCB3733FF0B6
+:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E
+:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421
+:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679
+:106B80007C35F85FC4B7E78E61E247BBE10F308F19
+:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643
+:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB
+:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48
+:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14
+:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C
+:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294
+:106BF0005F3D528A7943CD769EAFF301D08B16C5A7
+:106C00005755EE901DEDF97776155F3F9EE1F7A1A0
+:106C10005583509E26B3B8E78C6E5D6386AF3FF810
+:106C2000ADF032D640F0F60687BA558AEBBF7AD47B
+:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF
+:106C4000297F74917CDF27E80836C0CBB89CAFBBA6
+:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF
+:106C6000AE5C92237126872DA00F86EF6C7B268663
+:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E
+:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791
+:106C9000201F2EFAB5C29CD0AE739B8785715F50C2
+:106CA0004376942755BB94B871598AFCC3FC17FDF1
+:106CB000C24372A26A8723341DBEAFFAE53B231993
+:106CC000E0A1B3A1FBF060DC479F92787C34D8311F
+:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0
+:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E
+:106CF000C7C4BE04EDB87FED4929941F477E18F143
+:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016
+:106D1000386AB77E487454F68BED5EC443ED1EC5E9
+:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA
+:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222
+:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D
+:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3
+:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA
+:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27
+:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367
+:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9
+:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02
+:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78
+:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9
+:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9
+:106DE00091C7A4ED9150D902435E94967539B84B82
+:106DF000612E80F3F4314708F39A6BE1D9B2225C3B
+:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7
+:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2
+:106E2000946069A338492DEB26F969FDAEF628ACCC
+:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2
+:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88
+:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6
+:106E6000BDC99003FDE1B752E270791C7A8503F940
+:106E700069C7D34F3C9CC6D7773A20A473FBD9216E
+:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D
+:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E
+:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57
+:106EB000C83AD58466946B5E7A7E829E8738DDD729
+:106EC00084F65F27C559B7D58E1C2E8F433C696F5A
+:106ED000F1963FD899DBBC9ED2185CC71353F0796A
+:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA
+:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D
+:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4
+:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20
+:106F2000AF539FC797EF8F382401475DF9A0DCD896
+:106F3000FD496515C1C1D911784F8973B3A79E5218
+:106F4000424178BEAAE520C969AB5CA8E9454F7EFD
+:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55
+:106F6000093BDA4787B7EEB4771446E81EE57F742D
+:106F70005EE4A967F68F24398DFDC7599F5F0B79B1
+:106F800057DB6AEEBF76DB87A6FE17055BECE417DE
+:106F9000ED679C0F54FD069CEF07ED368679F71FD1
+:106FA000B428E5F1F49B90C366CA835AE5293D866F
+:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607
+:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93
+:106FD000EB991625B79B2DF8F4A5F926625CCD3701
+:106FE000B9A224DA7E32E04FD66513FC7778CA075F
+:106FF000E27909B4C3344C3250FDE45756BC53CA4D
+:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B
+:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436
+:10702000BF7AEF641EC735E67FEF456C1303B97B6B
+:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB
+:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3
+:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4
+:10706000533E8F1DC7CD45FB2944CF135998EA8A5B
+:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D
+:10708000F8D401CFEF2B4F9138DC61CAD74816E313
+:10709000C88959997DF13F9BAC9E8AF6FB38D8266A
+:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21
+:1070B0000912EE3738BFC178AE479C9FF7F5CC5721
+:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5
+:1070D00054056F0D68263FC720D64265166BA73250
+:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6
+:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE
+:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0
+:10711000865F26106D7735B26A9ABB2B8D1F63315F
+:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2
+:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B
+:10714000CAFA0A935D6D2D9B0738E76C66043FF71A
+:1071500053494E7E7E59679A2F9AFE605C67697428
+:107160003EA3AE937D2FDEDB607AF8D28178546245
+:10717000E96F06D2DF68A4BF0ED14937F9296E57EF
+:107180000257E37C33F2EA24FE3C2071BF97AEE065
+:107190007CD345FF72627566A08F79B259401F514A
+:1071A000792D1B84FDA8AA4C4D284278368975B7E5
+:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4
+:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2
+:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592
+:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E
+:1071F000830FE2E8C3D67DF77667FC3C2436267E13
+:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C
+:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413
+:10722000CFAD59E8A86B47D2489487C8BF78CF45FF
+:10723000A2782E6DDBBF1FF5A6262FD3935348CE21
+:10724000694A2E9E971AE594A05CBCEBC3977F8D8C
+:10725000FEF55685E1D6DCE536E2937A322E5622EB
+:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C
+:107270006EFAFECC3689CE4F296CF88FF1FC436D47
+:107280009B8D85E0FD19C6FB3FB389EB030B5F8443
+:1072900051F03CA8181FF7A5E8FD23B53C8169D142
+:1072A000793C41BD1DCFFFCF13F8185091627AFF92
+:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A
+:1072C00091B27C2825E1093F8606FF90FE8CF99F4C
+:1072D000930376BE4F542485499F01FB17ED86909A
+:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B
+:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC
+:107300007DE066EE5EF0EA0F97507C94F86AC98BD8
+:107310003C2F6CC976294479CC1D439318E159213F
+:10732000BFD17BACEE41D83922F46BC19B23C38C17
+:10733000679766C673628119AF1EBF198F563C27C7
+:107340008DC931B55FA454DB89C8049E0BE01FE2F0
+:1073500019E420CDA306E611D662F159D97AEF2AB5
+:10736000F46FF48B470BFE4E59F07796B5EEE76F4E
+:107370005985339D589BE69DA986897FACFC66E0C4
+:1073800029CBD73E919EF93DE42FCE109D48F3F8CE
+:1073900077839C2D9C798AFCC46F467E7062CF7E79
+:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA
+:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA
+:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29
+:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940
+:1073E0004F51F735A8B7D7CEE7798E372770FFEB27
+:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50
+:10740000554212FA8B7CFA8B57A2DED56AD3685F9D
+:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195
+:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D
+:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3
+:10744000E77424C7C5CE6EB2A35777D455E0BC0C01
+:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B
+:1074600073F7297E1E738A32FB9B23A03EF6359567
+:10747000CB4DA64F9F93CE5328701D3760BE24F28C
+:10748000C17FC9A106C24FF3EF314ED5F81795A1C0
+:10749000FE5852B780F69F5F7BA7B46159AAB71414
+:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28
+:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C
+:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55
+:1074D000623FF2B2F40BC98BFD91AC4F73917F9474
+:1074E0009FE3F2ABF1EDA74713B87D037891504EBF
+:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE
+:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D
+:10751000F6A105EED00A98C781055517A35DF4C9F9
+:10752000BF052E8E17A788D8072C49A63D4F4F625E
+:1075300063902F9AF8F932D69C19EFFCBCC10F0664
+:107540007F187C91B9202110CF7FF98E8BCF6FD21D
+:107550008202CA83EDDC27518CA7B301E0EA038FD6
+:1075600041D63018E1A9DDF311F9179CADF1FDD03A
+:10757000F5784803E9B621B8623CE0EB7BC0D44122
+:10758000E4077B7376BCFE836C03F99B16B834E288
+:10759000B74E27B7A399DA9C39D3837C5276F52A64
+:1075A00080F361E03F24F9876C7E823BB89831F22A
+:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4
+:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B
+:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046
+:1075E0004F5982FE23FC9E55A69130F407BCBE790C
+:1075F000B0FF5FB607F01D27BFCBD077520220FB4C
+:10760000009E14B74CE756D0DE427BA296193F414C
+:10761000523E0DFEC34366783ECB90B752AB14F694
+:1076200080DC2C71BAC3E84F49A98479633C8A395C
+:10763000797FED667D14252FCA5D94013C599EDB50
+:107640003B861C36E477533297834DF7AAA146094F
+:10765000D3DF3B5CE83FCED6B549985A95A26A94F1
+:10766000E7705125F3075148E63E92DCA3F78C679B
+:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2
+:10768000F135B2ADFB00AA4F7E174BC5F59E22F433
+:107690009BB1A7B93C32F2FA6B85BD619547CF012A
+:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884
+:1076B000A10553681F2D6A2D3E88F939456F717EEB
+:1076C0006442FE80F54678296D0B2A880FABDCE911
+:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52
+:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2
+:1076F000C2C0ABB4083D152DF31F7444D18F21A730
+:1077000022F414223AB48E2331674FDD978BF2E5D1
+:1077100088827E90AE893C3EB942F051F2C7A1AB5F
+:1077200071FE1B5AA7BA90EE77B4953991AD966465
+:10773000F0735EEAFEEB824C904F745CD7C69C1AE5
+:107740009E291F0F2B8FF8507C508F9AD79966492E
+:107750009C73D492AE8B733F82512EC9E0E7B8760A
+:10776000B4E524713B334CEBDE43F7C20F61F08587
+:1077700041EF56FA36F8A19171BF84A13F28528B90
+:10778000B00BCD7E8146C3CF1174519CF80EA10F72
+:1077900036BA2F5937017E6D0A4FF2615CE20E4F07
+:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB
+:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669
+:1077C000860F03AFE310AFD297C7EBA7B8BEA36392
+:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17
+:1077E000057EDD4176173FB761D097212F4A976E0E
+:1077F000CC24E26837DFEB65C891317BEA0EA28AC0
+:1078000068951397B5B26B114F63C32AC3A32EFDBE
+:10781000C98D8FF1974C3A7F716302F0DFA817662C
+:107820002DDA068F466A2C753A0035B25D2539C6C9
+:10783000DACF2F0ED512FE381DFD8B865E1A8357C8
+:10784000A1971AFB8B11075A9710A8C4F1A53DC048
+:10785000375ECC3FE5F6EE5A57605102B44F0498BC
+:107860001330D7AE209CCDED53335FF6C687891613
+:107870003E6B01BCD03904D8E7F2A558388CF1F33F
+:107880001292399C406DA8BF6495323E580DBFCF0F
+:107890002E6B240BE03E8CC736719E6B85FE759770
+:1078A000A55CEBAA68C079D9541674147D79B80D1B
+:1078B000BFE0BA043D88F87096EB348FC13EE647CE
+:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA
+:1078D000379EFB99AE4D44BA189CC7E83CEC60D487
+:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A
+:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F
+:10790000E8DAFBC64518977CFBDF3FF260DCE94F05
+:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C
+:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6
+:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0
+:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC
+:107950000E9E27659DFFFBC28EBA6DDB66FB600D38
+:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819
+:10797000E66E1B65473CFCA9D521E2F0ED368E7F13
+:107980007D3AC6CF026229AC701EDE9748FDCD7FDE
+:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC
+:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44
+:1079B0001CE821B06C35C5D9ACF39C13B4C6339721
+:1079C000939D6ECDF398C7B47513B2E3E47BB4F224
+:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5
+:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3
+:1079F000775279AADE47E553091A8F67EFD97F9846
+:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56
+:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4
+:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97
+:107A3000C858780DB93D1BEF958DC28321C7ADF8AD
+:107A400038D3969B887421255AE3C05F0D2FBD7DE6
+:107A5000B758899F3768F0CF53C21F306FCB8C5512
+:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B
+:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A
+:107A800005F05186883F66A0DD67A5B7FEF2893A0A
+:107A90006D1D43500E58E9AB536271EF154D4DE427
+:107AA000FEF2799A3E05ED50D85E56F1381D973FAB
+:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB
+:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF
+:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF
+:107AE0000B1325E10F37E72BB035C16B906F3F7952
+:107AF000DCE6433F43ED56078F83EFE278833A8F0E
+:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1
+:107B1000D862A3FC13F497E130BDC5717BE2C22D9E
+:107B20007DC7B76B77AD8B9B7762E40758E9F606A4
+:107B30000BBD025EC88E09023CE4161771EBC62726
+:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745
+:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52
+:107B600043286E1E43B52DEC453BBC7AB38DECBA71
+:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB
+:107B80007100DFA2676D69D3F934285FC158A79EE1
+:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E
+:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95
+:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2
+:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09
+:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27
+:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE
+:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2
+:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62
+:107C1000F8CA77D3F9791E3D93FB6D829938BFF985
+:107C20009BFE85E6B7800588FE2A1F512AD05F7229
+:107C30005665E5CFC6E1933F093E79EF310706511E
+:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA
+:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B
+:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED
+:107C70001F7FE5AA81428ED13D31869E5386CFB1CA
+:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91
+:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0
+:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99
+:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C
+:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA
+:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B
+:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255
+:107CF0009477547DDC41F643F5765B05E2E3AFDB38
+:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612
+:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86
+:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6
+:107D30000792302FF783A7165D4C7E060B5E0DB9B8
+:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0
+:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1
+:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3
+:107D7000084E620578AF5EA39D15A0FF392827F84D
+:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D
+:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14
+:107DA000C797B8B95CD98BB40065B59BE3AD49C43E
+:107DB00057C012A4BC7FF429123F257B899F6CF029
+:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE
+:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF
+:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391
+:107DF0006CF494C950AF31E6392FC9E4DF50E51374
+:107E00000F62DC457D9EDF17B70EF8DA591489F74B
+:107E1000263A58D05584F7344209F555D9BF5F85C5
+:107E200046E00647E01A37C9A3491AE2F594CF495C
+:107E3000F932773C7715E56756BBB9DF78F8CEF1B4
+:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05
+:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3
+:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4
+:107E7000EA9EF53ABFB251E43528899C0E9424B9A4
+:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8
+:107E9000F0317EDF53F7105C5F4539F347D41BBBED
+:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE
+:107EB000A81739872C45A27E53DAF65D2CBFED0951
+:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44
+:107ED0009F26E95C8F96806866031E1A75A6D97383
+:107EE0009145CDF9168A52D41DA6713DA671591639
+:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9
+:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D
+:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF
+:107F20003BB356D21ADD50DFF91623B9DC99E015C0
+:107F3000F907FCDE19C32F31F6A5B965B864257BB6
+:107F400016F13C0EE18732E2E86759AB829389F182
+:107F5000535BE4E178B69EE4647FF1B19FBB457C5E
+:107F60006C101B7481F1B167DCE7111FBBC86DE8B1
+:107F7000F322DE2EF6FF334772285F485531278FF4
+:107F800031BBA6508A88F1DD2E8BFC35E878C451D0
+:107F9000DFAD88971147D92DDC5EEA253FE224A3A7
+:107FA000BCE6511D05941F61B3E6471C9329E1A966
+:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F
+:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F
+:107FD00094D914776047F8FA19717CA6142A08E737
+:107FE000D930D86008E751F3DF01B93C2DA8505AC9
+:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305
+:1080000020DEE7F7AA8D6223290FC226F2207EC95F
+:1080100002F747E7411878EC2FCFC49A5762CD2377
+:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29
+:10803000978D33B5CF868D30BA9EBB669AA97D7E6B
+:10804000F34C537DE8C69B4CED8785E69ADE0FDF47
+:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D
+:1080600058F7CBF6FC202E5D18EB6EE46961BA116F
+:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751
+:1080800083B42F5FE8FAE77B843E7481FC3E0A8963
+:108090000DE3443AD713BB6CEE35A81727036C28C1
+:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022
+:1080B0008EBEAFE86371BF1F20F2239B64719E7474
+:1080C0009293F4817B64F996E87BE4AFF0703972A7
+:1080D0008587FB557E02FB26EE9383135990F64F5E
+:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649
+:1080F0004FC078664781968C2205EADF88C8FD9BD1
+:108100001C5A23C60346295C8E837C9FE6198DFB8F
+:10811000CE721BD77F8236C4F360270B7A8B68DF61
+:10812000A3B866324B939614A2E9D5B3BF685F003B
+:10813000311CAC1A9E8476D0CB383406699D09B4C4
+:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7
+:108150008E67E6E5D2F3E33703D701FF1CB79BED4B
+:10816000A2FEFC53959BEFF7A0FFFF780133E519C2
+:10817000547BB81D55ED5178BC3CF49774444BD7F3
+:10818000FCCF2E41A06BA5F65528A2576FBCBD822F
+:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C
+:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E
+:1081B000E9E179D7778AF1AE87C20778BB1EEFF481
+:1081C000C6F2850953901FE0795882FAB7DB40F573
+:1081D00003BA9F11C8B6213CBF67FED7764B98AF54
+:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA
+:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5
+:108200001B12EDEB309E139F57CC1EBC12B70E63B2
+:10821000BCD759E0F46BB0DE33999FFA35FA672C7E
+:10822000C1240777542EFA536A0ECA3F99FC1F4B9C
+:10823000F63A48FE75559DDBFE20BCBF6570C7450C
+:10824000A85FBC59F5D92588971B372A4C83F50FB1
+:108250002504EEF344E1EDF8BC8F3CF81EF484C72E
+:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14
+:108270004D9E893FF6E03E39E6FCE23D654F0D2319
+:108280007BDBA0AFDB047D2D797228E9834B3CE6D4
+:108290007B53963C9E4BE7894A2516D78EC47B3F7D
+:1082A000302F7D07D0159E23DCF729CF1FDF7924DF
+:1082B000A598CEA3B2C07684CF68BFF3E59B865362
+:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53
+:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE
+:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4
+:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8
+:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91
+:108310001045F667601E774BAB928878F3A2C16276
+:10832000C817D009BD78FFA2B83FDD09F6D9702182
+:108330007FDA3D1F4F69E27108935E5772A8CAA4A5
+:10834000CF55C03F94F7976F0A34E23D8DBDEA7573
+:108350006199ECE12FABDFBDF325E57DA787F37FC6
+:108360004B0197DF2DE18410B71B5831EA7BCFE03A
+:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318
+:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826
+:108390009DF6E87F872EE57F674E9C032E11E7A2AE
+:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990
+:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076
+:1083C00027C799DF2F517E027D8FF572FBC4B987D5
+:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC
+:1083E00089FD66F1E13787D8619D4ECB47BC1847C0
+:1083F000A8DEBDC38B66F2658981242FC64B8EBF74
+:108400005AEAA37CABCD43D0AE6D09F3F8C408950E
+:1084100005D538F735D76E2CA64BBF6B36A652392B
+:108420000CFD09F0A836CCE7D9B9A731259EBD5D72
+:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4
+:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417
+:108450003F185FC5E7209164BCEFE86961AF757EA6
+:10846000AA503BA3DF117B262A3E58CBC270F301F2
+:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C
+:1084800057BB6F2AB7E39279DC737B42F71FC5397C
+:1084900036FABB042E5F334B81FEB7DBF9FE380C96
+:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9
+:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789
+:1084C000ABED096119F376BA81261F23B822703209
+:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71
+:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D
+:1084F0004FF307A558B86A47829E0BFC764F038B53
+:10850000FC7D04CC634B88D49DC013DB739890072B
+:10851000C3564FCE8AAE83401A13F97EF63DC35739
+:10852000374D203B27A8A05D0FA52705E7C9F737E2
+:10853000BCBF604011C703FA89139DFC7D4F7B27A8
+:10854000BFB24475F376FE245FE23489F5DC676AD6
+:10855000F89DEE90C2EF5E89FEADF081911AC05297
+:10856000FDC2F344B78BE4D6074768782E31B000DC
+:10857000E9F5576FC90CEF47FAE049179D432E788C
+:108580006E33F9ABADFDAD3ED6701FE665773D2786
+:10859000699807DA65EBA6B8514DEB7B745E71EA1A
+:1085A0009E13746E4B490AD47947635EC48A32C401
+:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350
+:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8
+:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF
+:1085E000CC8D3E87156407C81FD6C00E517EA1F101
+:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9
+:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC
+:10861000585B86A0DC6D013DACAF7CC65A0BDFF425
+:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22
+:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3
+:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2
+:10865000F3DA0C3A9F9480FCF42C233966F0632102
+:10866000F2A384F742713F4A21D239F29FBD7D1AAD
+:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A
+:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D
+:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F
+:1086A0002FC307A89F16FADB75ACC4729FEB294C49
+:1086B000D21810918F7FF3703E6D29D092FC309FBD
+:1086C000444531F141D43EC9EB621F957F74D3EA32
+:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A
+:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3
+:1086F0005CFE0B3A3920F4E043F51954C7FD428380
+:10870000751A0D25DE0754AAD7E19F2F6163CA9B16
+:108710000F6239AEA2A50C8F4C4D98D57E909F610B
+:10872000D38723FDED3A70F570CADF3DEE6098A265
+:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809
+:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10
+:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48
+:10876000AA56E3BD803725E9C7911E97FB02C79142
+:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF
+:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451
+:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B
+:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54
+:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25
+:1087C0003292EECB30D9994C592ED33DEFAD12F900
+:1087D000272A2D7A48356B5E3518F78DD6CD769CD5
+:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E
+:1087F000D05F72592EEA2F403FE49FE87E4DF13F53
+:10880000C628BFA70DF37B9E96397E405E121F1AC5
+:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7
+:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D
+:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3
+:10884000A333F2872C68954288C74A43AF13E729C0
+:1088500060DB25BD6E2C0B35E2FD720BB74A740E42
+:1088600063D156B3FFBE7AE32B87D13C5CDC62391F
+:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8
+:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC
+:10889000AAE8DF68372189D34D8D986F754809891B
+:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE
+:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44
+:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6
+:1088D000E6F755021F55167CD404240B5C5CDF8E32
+:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570
+:1088F000B3298FE81F0D9F759DAE33D6E95276A937
+:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53
+:10891000F92E67DA72C87F60D087B59F29427F9EA3
+:10892000BA91EB99A7F794258E40BBE888EA97A007
+:108930009FE2973EF6E2798FA2BD0AC3B860576BFB
+:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE
+:108950008DE2978AE85E90A2978A1273298F424B24
+:10896000457C403FB4EF761DC9FB7D21CACFB6C917
+:108970002588E615478A12513FD8C9B83F427AA9DF
+:1089800024B5236A1F599CC4FD03AB32DEB907F539
+:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9
+:1089A000F5AF807AF54B731BF09E8AEA27253FAA24
+:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12
+:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D
+:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B
+:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE
+:1089F000F31494B3A79EDF69A77383DB2596011355
+:108A0000399C71F019BADFE397AF50BE42D9AE5727
+:108A1000283FA137797F3AA4B030D9DDCD742FCC6F
+:108A2000E2CD46BD83CE415408BDA966CB09AA5705
+:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA
+:108A4000A1661BCF6F80F7247FAA307EAA45E87C01
+:108A50002EE3743057C89F458CDF33B4A8999FA389
+:108A600033EE4532E87CFEB639948716936F86F66E
+:108A700025C5219A89BE63EF1BE2F46DBD77C84A14
+:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7
+:108A90002521B110E6F3C98B0AE5DDF741E7B49F64
+:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F
+:108AB000D41E3963477D754AEB87B40ED35BF74FFD
+:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63
+:108AD000E0726B5AAB23847EEA6FB196265CDFAE00
+:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43
+:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5
+:108B00009737D35A84BCD964C66F97AD4525BA1937
+:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E
+:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93
+:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989
+:108B40007E360DE809E3216DE18642947B067EAC1A
+:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F
+:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47
+:108B700010D7B5C75EC93B38529323F60AD8299F50
+:108B8000250DE076CB28E8FA852C85A5A545EC9542
+:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E
+:108BA000BE80CA484ED56E7384D0CEF81F84BFB83D
+:108BB000BB008000000000001F8B080000000000C8
+:108BC000000B8D576D6C53E7153EF7C31F8913FBE0
+:108BD0009A78662C34BB31F9202584DB109A40D773
+:108BE000F626A51D83141C58296AABE2B65BD90A88
+:108BF0004E5085281295B889A9D6956942DA7E54D7
+:108C0000EA56DD226D621BAB4C096A9892C8A1A19D
+:108C100025E990A0401BD0D659FC60EB9490C0345D
+:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4
+:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E
+:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89
+:108C500020EA20F2449A60FB242343B0ABAF7B139D
+:108C6000254423558B4209CCBBA1EAF335B46FF1FF
+:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F
+:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA
+:108C9000A2C981E98AE760576832FE71FFF796A89A
+:108CA000D877EA928F6295D8D8322FD0FD442F9290
+:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC
+:108CC00039B5C0AF878C0CD6755E540C4B47FF0985
+:108CD0000F513351F7277F1A9E1721BAF6AE64F869
+:108CE0007467FDAB8D683F6FEF9F87F9377F27195A
+:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA
+:108D0000EB96F89FBEB217F39247FCFA1B687553B7
+:108D10004F39616E0FED1736493FBBAE04E1AF2FFF
+:108D2000E5655CC82E581F23DA7E78A6BF24A9F912
+:108D300036F2DBF397D68EE182F1355A69E46A00A8
+:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F
+:108D50002481DBDBDF2AC4E734C058C0FD4526216F
+:108D6000CFC973257611E6FD731FC66A89C6F7C1A0
+:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B
+:108D800019FFC452A23F0CBE7F2FF30109883A6C31
+:108D90003F8C798B0BE24E23A88238119791C17ECC
+:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA
+:108DB00014F0637A9FD9315C8D72492745BD64698F
+:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77
+:108DD000299717A44E45E388F3590D45043FBBFB83
+:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4
+:108DF00066EDE0F19B9501B218B72FAD766EEF8E60
+:108E000029F406DABB3F79A9960AF6278E13F5ED09
+:108E1000F24C4599B75DE764115FD7B91BD12AB40D
+:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834
+:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC
+:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C
+:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98
+:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535
+:108E7000375BF5F34F83078D23AA15429EC7C68A39
+:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5
+:108E9000C16DB5C47E138965719CC39B833F5EC65B
+:108EA0003890D423E2B2383EC435D17731AAA33FFB
+:108EB000397031CAE3C9E32B7E6161FEF2338DEB79
+:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B
+:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9
+:108EE000B7635EF24C5B93C4DB9C692A63FD592E29
+:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE
+:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46
+:108F1000CE63479F6216F228B7EE90A60A3FBF6560
+:108F2000FE804FDD69C914FC38EAD81D7DC7447E38
+:108F3000DB3D6951EFEE231E67FC8F8E253A28D664
+:108F40005934CF623C3EE62ED461ADD75E480871FD
+:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67
+:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9
+:108F700077AF678D3D87BF2AF6873C8265B4353E63
+:108F8000C77838ECF067AD971273C5F379EE3C11F2
+:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3
+:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF
+:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202
+:108FC00080B4C39CA9731B29EEA145F0B36666FF6C
+:108FD00013AC970D6C55E1E76E3AF829EBE0127C83
+:108FE000A9A11AD641524A021278F3EFD31E4D11AD
+:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2
+:1090000034F48F6D77DD670D59E0313A74E9DDB0E6
+:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E
+:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6
+:10903000D7E786E6D421E91FF782ACD4453B5F979A
+:109040009147BDE2F0CFE74998E5C8C3D3D79A2945
+:10905000673DAD838A22BF8947259B751E7156F8EF
+:109060000A747E628124C6776F966C0B5F87EA3E36
+:1090700013F7763273D6CB7CAAE97DEE35716E2D6F
+:10908000BA40D17C1D37F89DFBF276FD72F9F2A053
+:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E
+:1090A000869699F5ABA5B38F95238E274DC9B0E76A
+:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9
+:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07
+:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77
+:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85
+:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E
+:10910000E874849633AF7EAF69CEB9F5D80B590FAA
+:10911000A81E8F9995FF5F77BB4F7CD4C075B93679
+:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B
+:109130004B0AF925BBFC528595A48DEEFD38936F43
+:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437
+:1091500082FBF3F8F9607581DF897E45CC27355BAA
+:10916000F34469619CAF893827D28E3FA26CCDA6AB
+:10917000A585E32997B759C1DB9F2CDE19E7739CBE
+:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B
+:10919000202E6BD067FF06E3939EA98A70C1B9F8B1
+:1091A000A18B737346127C5C4996C27E9BE1F119D8
+:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D
+:1091C0001E37AB9921A941CCB354F072159D15F30C
+:1091D0001EA229614D82C0C3B691216C8B3FB38E14
+:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C
+:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378
+:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F
+:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88
+:10922000745816E77730ABDBAC5F4699BBEE0BACFE
+:1092300043BBD974CE295F35CF34E6F3BD138755D0
+:10924000F017E2792ABDEE113866C47E0F73E0C8CC
+:10925000BB957495DBA970A5C3679A7A96F779A434
+:10926000DF27DE39B2DF1278FC34ECD433003C83E4
+:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45
+:10928000BE5023CF77EE31B4690CFD01BFB38E68B9
+:10929000B5C6784999A87C2BF0F5719D8C92883BD6
+:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D
+:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D
+:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6
+:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01
+:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD
+:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F
+:1093000097A523D5C2896AAF60BF399E07C86C6133
+:109310009C25B75E7BFC8EBFE922C7F299643E07AD
+:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71
+:10933000C84E61BF69392EC8F88A62F805DF6389B3
+:10934000B16658B5CDD47796F0931D7904F279A41F
+:10935000781FDCC7F4033C1041865D9A934FAA4402
+:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F
+:109370006B914D95B3E33BE94B9CE4FCA665636CB4
+:1093800054DCA33B9B59EF18A7EFE47092F3386DC0
+:10939000B163A9AC2E7019619DBECF67DF93C1BACE
+:1093A000A77C7635C79FC303051224D55C9C73F850
+:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147
+:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF
+:1093D000EBB00E00000000000000000000000000E4
+:1093E0001F8B080000000000000B7BCBC7C0F0A360
+:1093F0001E81FDD0F8E8B89D17BF3CA9588601C171
+:10940000CEE7626008E160600805E2FD407C00880C
+:10941000E53919182280381288A703F93380B8007B
+:1094200088D3816A9B99191876B131301C04E213F4
+:10943000407C9E8D74FB3F88333054C820F8C78031
+:10944000EC2372D4F5E3281EBC38CF0095BF4E1331
+:1094500095BF4D9B81E13D929AF59AA499AF6CC856
+:10946000C0A002C4003A4CE95968030000000000A3
+:1094700000000000000000001F8B0800000000003A
+:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B
+:10949000494218421E3B2140800487102250B0935D
+:1094A00014142DB5113D2D7ABC3A8447906740AB1A
+:1094B000E9114F3624840001068A3572224E103499
+:1094C0005AA841F1D1536C878716ADED8DD656DB86
+:1094D000FA88A8A0A89C5445A7E7D472D7FFAFB5D7
+:1094E00093BD273301DBDE73EFF7DD9B7E75F1EF74
+:1094F000F5FED7FF5AFFFAD71A45B411F9EB849C51
+:10950000873F9AE68A849021FD2921B2D6E3809490
+:10951000E8E7475860725EBA18F82FA3ADB0CEDB0B
+:10952000FD1742B208F91ECFA37F21806770C018D3
+:109530008F9192A04262C5FDEDCC200CD644819C57
+:1095400017E0AB35DFE8A7DEE11B4FD208F9C2C94F
+:1095500052BD8A6695D3F44D67B4B1801087101E52
+:10956000C1C65377497529A69742DA2890B95D9EFE
+:1095700024E320EB08994493FDC34452D13FFEC439
+:109580007246DAD44048CCDE0FCB3209256BB78265
+:109590008E1FDA7D5F0857E0783C44067C281C1F4C
+:1095A00036122484CEEB88FFF2C03C3AFED6694ADC
+:1095B000D00E193B874165E233F038371F610787CA
+:1095C0002B89C6F11D6B1941EB398322D944A1A621
+:1095D000822A07292164EB94CF03613A1EA71C213C
+:1095E0002AA49EE4E3BB9A88BC9DBBC8C5CC3B7152
+:1095F0003D6458A349088A302F63BCDB6C745C99C6
+:10960000743D2689641F85B794CF4983F118F3729E
+:10961000A4E8A719F03A9A90CD0D0E4C9B26CF499D
+:1096200023508FF4CE85F5DD3A254BDC24F4973FAB
+:1096300032E539470F9D6F23AFD7AA1D7540796377
+:109640009D13F1B695E32744041CF7E652D7DC6876
+:10965000C9C07184880FF3B73A692598879744F792
+:1096600015400B3D6DF329EC9BAC966DD206D2CB29
+:109670008C523918A3E3F4783C413BCDF704587D74
+:10968000C7EB4254C3FA21CF305ADE65ACFF64B158
+:109690001F9FF4FF3E524D08E5475F4EEF6BD08FA2
+:1096A000FD757B3044BFBBFFFCE96BF369BBE46D28
+:1096B00021B80FFA25AB2CEB45F632BCDA54FA6F21
+:1096C0009AEF9AB668364CC1FDE5E3D580B78D4573
+:1096D000AB5D6B61AD8AD9FAA9F47FE70B69FB9AA0
+:1096E00062E9DF665EDF02204D2BEC1E39E7DB23EB
+:1096F000B4D4F4E1EEF19158062D2CDD88EB9DAA4F
+:109700005CFDEB132E3B6EEAB78D78334FB9E93F22
+:109710002E2597229F5FA0FE170DC1CB8EDB70DE3A
+:10972000A259DEA42ABF9ED3471F9D1550FA28C117
+:10973000F50C5C53DAFFFD25A00BE007BD12E51820
+:10974000F2229D6FF374D22BD1F5681AA968EB2829
+:109750001EECAA12137CACCF5EA02FF807AD6A2FC7
+:109760006AEE16C603F03D8B1C6C19FAAFC1D82007
+:10977000E34B5C87AF8ABF18E06F5C3FFEECA43A16
+:109780002D06EB5D1D40FC78F938364CBF5D8BD162
+:10979000F96CC8FE61E86D62C2E3A58CCFFAC6938E
+:1097A0001325E6FE0DFEBA4408BD08F89194E06B5F
+:1097B000618A0F325509EE4B322F596072A51FCFC7
+:1097C0000E99187802FA3DAC07AEF1E290AA1D2678
+:1097D0003CDB03CFFD19F0276792987B3C7E6F92AC
+:1097E000D3A9FCCA24BA3B0D5B9101FE332940FE8C
+:1097F000A4F9339432900B9707C3B49F661BEF4FC5
+:109800005D6B59D73FF375EDCFD703FF64C9B761DF
+:109810007BCD5E2E37D4461CDF80FA7E563F71BE6C
+:109820007F02393A09CAA99C7E1A03A06F1CC39A09
+:10983000671D01BC8FAEEB9A0F735409E2C190FF14
+:109840005401122847F5C39FA19E43AB46BCDB736E
+:1098500042248C78B3EAD3947239418F0EA02795B5
+:10986000C2461B85F0DF1C15F98D24EA6F9E8672B7
+:109870002F4A0F3626F0156D2AA99E291598BC256A
+:109880007A26CE5F36E880DB0736031D3B193FABF7
+:10989000BC5F05C643E5A19344B17137A57480BD93
+:1098A000A40EE173A1B298007423938D20E7EC21FC
+:1098B00091E80503FBDFCAF549AA796C9D925C0F1C
+:1098C000E40A4C0F489E3ABE1E37AAC067821E2685
+:1098D000E781DF4884EBBF20AEF786867AF20E9DE3
+:1098E0008CEBE89544A3F423E7D48542B49E04BCF2
+:1098F000484534F194B3540E6A66FAEA5B47B216EF
+:10990000DBB351B4C03C6D1EC73C321E52F51A4C3D
+:109910008BC72E04FEB0A55D5E0FA61CA59B4A0159
+:10992000FA7724A72BE2A14C3A0561AD3A697F7C16
+:10993000BD79B994F4D5471FC67C35A5DA3B906E46
+:109940005CE5AA00AC40C16E18CF503E9AA1E1E69A
+:1099500055E27858B7C8AC51747D86F6CC43FDE427
+:109960007DFDCA0F605EEB4BCA4E8009971654AF5F
+:10997000B99CAEA7AB980880EF8DD0D85468E1842D
+:109980005E097A1DFE994DC8FF109E09E91E463EEC
+:10999000567B53D464439E8883DA2FC279FBC0FA86
+:1099A00029E53331F10FEAF1D517672FDDC8FAD376
+:1099B000E9FF80EFFC09FA342D646A97007EACFD64
+:1099C0006C00BA41FCAEFA6FE94F253B1C1AD81D5A
+:1099D00045A21AA57DA711D54F653171CD9009E833
+:1099E0001335A75787E5BDD0BAAC276416CA51CA4C
+:1099F000B7663A6FE7722050D354D04CDB3D57EE38
+:109A000009821C184AC56646FAC0F96C4EB0B337D5
+:109A100097EC41F9D848E9A810ECFD1211EDA18DA1
+:109A2000458FA9667DF53343DE0CA00FA2C915282A
+:109A30003A08A1F8918AC49073FCDF4F1F8976D24F
+:109A4000C5D287FB46EB7A7CD5F5FA659FFD7D7123
+:109A5000F4F1F7F667AC6B2AB945D715EDEF166D43
+:109A6000CEA0F6CBC075DD81EBEA2A22A16472B8E4
+:109A70005B10ACFAC99C9AF507B9D5B25EB64BBF7C
+:109A800033F78141F0619B6B9DAFD1AEB35ED2DE07
+:109A9000053B5656511F19FB878DDA0E1DECF973E5
+:109AA0003984D97B91553101ECA022827610342083
+:109AB00052D8A985A29B0446FFB02E867D63A3E6FB
+:109AC00098B93F497559FB9FAB0BE6F13BEB151C71
+:109AD0008703FA03BEF4D00669BB520E8939D1FE62
+:109AE00064EB075DB17DFC9D17450706BD025A1961
+:109AF000BD5AEB3507CA48B2F51BD0DF75D6F1A6C3
+:109B0000944B89F53CB276CA648FA4AE2793532652
+:109B1000BB66789FFF4237ECB9A7056A173606BEC9
+:109B2000A3E3B8E13F54BFB6404AF59934AC8A8408
+:109B300035D0931AE3132D9DE9DF4EC1B20F37BE26
+:109B4000A71E07EB2FBE90D222C83559B3D8CB89B8
+:109B5000696343E06B32254A77FD0353E589D48876
+:109B60005D1B9A5B4DCB6F6CE89C0ADF8D723345B1
+:109B700063FF4DD5A6C93E96092DE7C0AFE4FC446E
+:109B8000F8A812CDA4DF1DA40BF3E957BE7E04D7BD
+:109B900001ED2ADA649DA861BB0A791ACB414350D2
+:109BA0008E4AF1A972316B0EE0CDB65008C7254739
+:109BB0001CAB29DF6D767258E3B09FC32A870B3840
+:109BC0004CF504C06E85C23475DA222AC22E0E17F7
+:109BD00070389DC37E0E177258D881F06685B5B770
+:109BE000498EB2F65D1CD6389CCE6195C3851C2685
+:109BF0007B58FF7606BB6C51D6BE9BC3051CCEE0DE
+:109C0000B09FC323382CEC4138D5FAB98A3A199E53
+:109C1000FAE442573F8CCA83E3B50F8E25C08C5EB1
+:109C200032044687F16F19741344F9483C79C86FC0
+:109C3000E31C6CBD1BF797A15F82703F8AE9FB09AB
+:109C4000D0C7E73AC5E060FCF5432E4F77829D4BC5
+:109C5000D3ED0D2AA6DB1A0268F76E69D0B85FA5AE
+:109C600018BF6F6C0822BCA16132A6EB1B42F8BD85
+:109C7000B16116C29D0DD5983ED83017D3BD0D6188
+:109C80004CF7342CC672D1863A8477537B17D2F6C0
+:109C9000061DD35D0D2D98DFD61041F891FD65CFDF
+:109CA00017513D7D2E2CA29E4F35FEA173AD7E90A7
+:109CB00021D556B9983E23DD92AF4ECBB6FA4DCAA8
+:109CC0000B2DB0A764AC0576159559DA73E44CB545
+:109CD000E42B99551658F65C6581C744E758E0D1E6
+:109CE0006D3758DA1B19A9B1E48F685962C92FD0B2
+:109CF000575BE0FCFA7FB194CFAD5B67C9DFE60C40
+:109D00003F235279357CF1264BB961E11DD67DDDCB
+:109D1000ECCC8B925BE4333DCBECCF4894F7521EF6
+:109D20000985506F31FDD208740B7EAF5C12DD27C0
+:109D300080FFEA8A13B0EFB01731BD33607F99D04E
+:109D40009EE279F0359DF653E93B11E831F11909AE
+:109D500098EA51B97F5264FBE64D77B17D75EB5DB2
+:109D6000C9F7D728D9E93C5ABF4CEEBFED11256E93
+:109D700007E9967D4AEB5D0296FF7BDB37F213DB4A
+:109D8000EDEF8FD25C85D90E891A7E51A267F5EF6F
+:109D9000776D3DFEF9B0EF31F6B912E7F3CAB9C1FC
+:109DA000B79B289FAC5709FA0DD77BAA08D815E7AF
+:109DB00054C6F7646F1EEEC78DF203C767B22B500F
+:109DC000FEB8AC7E5ACF1C942FEB3307B7CB94B8B8
+:109DD00084FE3B292E9018D53B8A5C3DAB808E4B90
+:109DE00079450AAE25A87F92EEEF09D981789012C5
+:109DF000EC9BA60509726F462ECEDB66C8B7CC2A4F
+:109E0000FCDEA40E3E2E3B8C0BC6C3C7658BBB315C
+:109E100095E24E1CEF947806C293E37E4C2F8D0F93
+:109E2000C7B4223E0CD349F1119896C70B309D1848
+:109E30001F87F5CAE263309D109F88DF83F1099880
+:109E40005E12FF1A7E1F1F9F826969FC1BF8BD24EA
+:109E50005E89E9B8F837F1FBD8F895988E895F8B61
+:109E6000DF8BE3D7603A3AFECF988E8A5F8FE9C8DE
+:109E7000F87C4C8BE2F3301D115F8AF50AE3B76082
+:109E80005A10BF15BF6BF15598E6C7EFC4342FFECB
+:109E90007D4C73E38D98E6C4D7623A3CBE19EB65FE
+:109EA000C737623A2CFE03FC1E886FC7342B7E2F07
+:109EB000A6FEF80398AFC63B304D8BFF08BFFBE210
+:109EC0000F63EA8D3F8EDF3DF18398BAE33FC5EF24
+:109ED000AEF84F3075C68FE17747FC08A6175A27B2
+:109EE00025C72AC7A54C97059EFC6EBA853E2A5EFB
+:109EF000B7CAF1F2570A2DF9652F5AE578F078992B
+:109F0000051E7F78AAA57CC9A12A0B3C76BF558E79
+:109F100017EFB5CAF151ED56395EB4D32AC70B5BC2
+:109F2000AD725C6BB2CAF1BC3556399E739B558ECF
+:109F3000672FB3CAEFC002ABFCCE22BBACFBEF195C
+:109F40007BAC7A6DDA2396F63CE58F25EC57A22898
+:109F5000675C25FF6EA9E7283A9A209F7526A7120D
+:109F6000FCE5801299F2F71DC415349FAB18693ACD
+:109F7000970719C07734CDE47C3704F88EA6E9DF63
+:109F80005C86E74C5F7CABE5174DB4B1F4E184F936
+:109F900005F44855887E6F1EC661FA45003897A0C3
+:109FA0009F80E8672AC12FD65CC0E07F934E55EAB8
+:109FB000CC7FCBF2C95996EF64F0238DBF5A0BF9D1
+:109FC000E969D1EC204D1FB12597D38F49ECBCED49
+:109FD000AC18EA90E87CFFA3B2E776F0A3FDD51EAB
+:109FE000DE27D1EFCB1CE17C704D7F6C0B3F2483CF
+:109FF0005C24A107E17B1A093D24A1BCB6FA451BEC
+:10A00000C1E0A6ED7C2656EF87FC8CAB17A35FCA98
+:10A010009877B377F0F14425A6979AFD04F78DFA67
+:10A0200011859F2311765E0329D583F7B87D21C85A
+:10A03000DF7044D963A7EB60CBC99A4FC6B36216F1
+:10A04000FD116B5E057AD8017A680448F92E4C3D03
+:10A05000A49B9D1B915E4C55A20A901AF3EF9B772F
+:10A060002E9B37C5C72F24DC1FD461F975EEAB27B3
+:10A07000C37C283E4EC0778A8FE7A521A9F141E035
+:10A0800064818E3FCFA0A2FD82C5FFF8BE10FE8D79
+:10A0900064F263E6D507713F794052111F06FEE86E
+:10A0A000DF6DE9863F86D5FB23F69BD09ECCCFC5DE
+:10A0B0007E23F1FEB93E34E8384324E1647ADD388A
+:10A0C000F7219D795FC99F2D28CC2E49ECC72657D3
+:10A0D000E379EA00B99799B0AFCF0CC3A250FD491C
+:10A0E000F56592714D57B87F4ACEBFA8F32BC35F79
+:10A0F00042F6E77DA5F32EA004286F901C399E87B9
+:10A100007090EBDF02B0EBA83D72EC8DA762CBA99B
+:10A110001CD85044752DFA2DACF6DC869888E7EBF8
+:10A12000057E2A706863F5DC0E90B93D68F42B3724
+:10A1300059FD299B6D7C7F7BD88AC7024AD0FF4E90
+:10A14000B7DCC493CFC6C7CF2D8D76F6F48DDF3A3A
+:10A150008E074AA83964C2676129251D18478C8D6E
+:10A1600023B17FC2CF170CFE913DDC6FA2E663BB2B
+:10A1700046BF89FD1069369E27A5C2EF807EBEE2EC
+:10A18000795D859CFCBC93AE0FE2696C8AF535CE97
+:10A19000EB0CF8D81BB578FEDDDC59837654738060
+:10A1A0009FB3FF85B60AED1092D45EDCCBF1BB897C
+:10A1B000EF17F746AA1C582F33DFB24E45DB67B8BE
+:10A1C000000F4D6A553AA4FB76B27223EFBECE154E
+:10A1D00066765B3AA49B8AD977D798BD0E567E8F58
+:10A1E0000AE9E612F6DD5D7AC8C1CA333F2DA9A798
+:10A1F0007FA673A022B55A14CA41FF92904C619772
+:10A200001A25E04776AB5D981AE3CE8E88E2185A9D
+:10A2100025BB33947E25F8DDEA4870241BAA03D6BB
+:10A2200039CA972FC7C8AFA7F9B4BD313B8F564283
+:10A230003DE7CEBD95576AFDE577F3FEC774465BF3
+:10A240000AA17C8EB5BD76DE9EB3B3EB04F89B29E4
+:10A250008EB13D237F17CFB7437E26521BD6974B37
+:10A26000DE8DC1798681E740B1D8087022BF1BED31
+:10A27000B4F171043BA3912AE867AE751C3F34C862
+:10A28000B29384A21E933CE0F9119EBF01F6FDB487
+:10A290003FB993F9518DFCADC63823AC7E23F70B43
+:10A2A00018781DC3E591413FA9E898E8A265FF46EB
+:10A2B000EA5D56B8CE64DF01BC38DB9A1F2EB4C20B
+:10A2C00073C75AE15099159E3CD5D2DE177D7E9416
+:10A2D000A813FD25DC8F62F85E76A935B8CFE9F7C3
+:10A2E000D3455C588EEF3B7278B987EB98BFA5D108
+:10A2F000C3F985FB5D9C5C2E3617B17D499F5DC11E
+:10A30000F1DDC5FD1A8F36B4B1F8940BD8C3EDBC9E
+:10A31000DE2E7EFED8C6FD323F04FCDB61BD985FB9
+:10A3200026C2FD325BC12F43D356F0CBD8813F9973
+:10A330005FA605FC32343DC0FD323F02BF0C851FD5
+:10A3400006BF0C4D1FE27E997DDC2FF300F86528D7
+:10A350007C7042F75CF0B775807F86C2F773FF8C24
+:10A360009FCBE58333A3D9E00F7B6466F27DB1DF39
+:10A37000C6FCEEB960A850FAB884048FA1BF9B8ACE
+:10A3800061F0774FAC0B362A9960B732BC4D0C07A1
+:10A390001B6DE560B73238DFC6F428E80BD01FE448
+:10A3A00030F327503ECB047C6FE1745976222CCCDD
+:10A3B000A3E3F8A3CCF5A2460218B7C0F902F24114
+:10A3C0009EBC21845E972741BB04C795BFB7AE0AE8
+:10A3D000C468F1D3D5475DB4DCA8AEE03A707D1611
+:10A3E00095A8E05920CE224D84F5395819443FDA1A
+:10A3F00096DF4AC13DD06626B1D0031D1BCABD31D0
+:10A40000063CCD4A0F97C477A3FDDB5C37270DE9E7
+:10A41000492383EEC7FD21EB3E286DB2D59FD5BC05
+:10A4200097B5938A6E8ADBADF6C4A89DD67D54732A
+:10A43000D19C41FDCF45ADD6FE0B9B12EA7B06AF0A
+:10A440009F1FBF1AEDFB54F43D4EAC49B34DEA8754
+:10A450003DF1CBB07CA27D2703A150BB4D3EAE6049
+:10A4600048957C5C0D815D2B1FD7781AE4DF431C77
+:10A47000AE66B0CAE220A83D986B1B82EB9370BE1B
+:10A480001D2270FE7C109501FDBFBE705D88D2DC80
+:10A49000C17F22B8DF78435E55A55378D76C8728F3
+:10A4A0005D02F4C6E21914BE5E194A746301D0C39A
+:10A4B000C322017A78A473703E1E10E7E009A17FE1
+:10A4C000A6A0492D03F59DAADECE2671563449BBC0
+:10A4D00053395F91E324D16E9E0AF35DDF34474523
+:10A4E0003D725D10F7074463E337E45C46FAE0EB46
+:10A4F000B7ABC17ABE964D92DBA16B6C9CDF8A999B
+:10A500007C34E83FE3C1C1DBDFC0DB8F770916FF96
+:10A51000CE90EBAA2B6D99B8DF097A408E7E293157
+:10A520003FD961169F66F05363D10E179437FACF67
+:10A53000CE89C1F684341F99C2E226287E713F7805
+:10A5400084CAF11294E368F73917D785989F3C8243
+:10A55000F10DCEBAA00EED481E462FB0DFE4E57136
+:10A560003C1BF78A1872D13897D9AD869C37E8A082
+:10A5700031C0FDEB7365E667FB0B9D9FB11F81FD4D
+:10A58000A15A87E77BCD93D87C6C992C0EC4561CBE
+:10A590008BC1D959B377D15A98AFBED0D0D73CEE42
+:10A5A00082B0B82B231E0FF003E7E0056DE3518E58
+:10A5B0001878FCB610AE073EB265EA4218E7D185BE
+:10A5C000ED1B784BC4FB77B93C1D9EC20F97A6309C
+:10A5D000B99EA1A85781BCDD7284D277927DBD93CC
+:10A5E00097EB88CDD90636A2C1AF46FE0149C37E9E
+:10A5F0000CB820AEB0B8BE9875FFF1FFBA1DFFA829
+:10A60000CD1A77F7FFEDF8FFDBED789A0F7648F873
+:10A6100002763CB7F3F7F6D16F829D5E2C1FC130F6
+:10A62000BA047B3EAB7846AC0AF23BBBBAD18E9FF4
+:10A630003CB81D4F12EC77C3AE37EC77C39E37ECB6
+:10A640007532D09EE7FAEF1BEB4232C48911D47FFA
+:10A65000E39ABFB14E87FE13FC1E12157366FF45C9
+:10A660002FF0F910133F78AC76C3C5CB0719F53F2F
+:10A6700009E65AE46B46F6E0768E11EFFD45AE61D1
+:10A68000AF87D83968513131DB634D548EFBE87C9C
+:10A69000DAE7B2F329C2E578B6E197290EFB47A3C2
+:10A6A0007CB7CADDF6C5353A9EA394133C7FF4E42B
+:10A6B0007485E07C3C6B6E04ED492A7F8B1593FC1E
+:10A6C0002D68AB4039A773FB32119F20EF0265D094
+:10A6D0004F829C21C19745C8CF85B36BE087A88086
+:10A6E000FA03E234C60F226F2E325EC3889FC8A3DE
+:10A6F0007F206736C86C7CE4696BFC3951297D5436
+:10A70000F4DBCDE4FDF98239EECFB06312EB51B941
+:10A71000A026937B6F08E16F2983D047A23F8A244C
+:10A72000C8692A8844E8BF60F62CF433F5F9A564BB
+:10A73000ABDC9603463CCB7FAFFCAE55FEC6B8F310
+:10A74000AFE8B7DBC8E5F3007E4E68472CE9223D51
+:10A7500049FAF79458F1EE2AB2DAF302085B881F3F
+:10A76000CEB19E93CB9EECE4E7003C3EB366B2B123
+:10A770006CDA77FF48F9E4961336BC4762E81DC3EC
+:10A780002F7B0BC469D2F5A981B84D4ACF0B48B5D0
+:10A790000F323F2622C6837D4C5EF64D34ADD37D0D
+:10A7A0008AC2FA69B19D847B42463CE2C20883FBBF
+:10A7B000F0DF668517913959701EB168A70D38888A
+:10A7C000DC42E4933DC6F8297F6F51587C752DA972
+:10A7D0006B0639B69EC773D7A84486F8C1E54FDD2E
+:10A7E00057318FC27BB9FFF60CC5BF66B28397782D
+:10A7F000A20A9C2BBC7368E277BE46A07EB4391BCC
+:10A80000E208A9BD0A718489789FDF621DDF85C6D1
+:10A810009F385EE35E51AA71C89D4228D9FEE0319F
+:10A82000C51AEF76A1FB4EBF53347EDE6CBDEF74CC
+:10A83000A17A7F543492EC9ED485EAF5FC8DFDBD5F
+:10A8400097A2DE72478F027260A51C9E2514F6C780
+:10A850006B29B6EAD0708A0AF9E90931385A32957B
+:10A860006BB9C8722760637111E5668983B4779606
+:10A87000F3F12FF63FA0007F7EFCC8DB57C379CDF4
+:10A88000D29F4AC441E77576BF97C470DF11554027
+:10A890007F2D392431FF9B1CABB8D6247F315296D3
+:10A8A000E27BE9A35E8CAF58F2983D3A9BD65FF20B
+:10A8B000E43BE309C5C3D975BDCF0D87FDC42302B1
+:10A8C0008B27D47BC65F4BBF2F91C9CDD549E4A060
+:10A8D000646774FED14FDC73818E84CE233761BBF5
+:10A8E0005DDFB5D94D76FF7F2A36A31C9E33E90F75
+:10A8F0000BD191021B9FF99E8411C7F9D1C3021B92
+:10A90000DFD3B6A813C6D7D9A18469B9959D7F4274
+:10A91000BAFDC6A3077C8087954F4B16F9B2B25398
+:10A920008AD9C763FAB61DCFAF421E81CA911528D6
+:10A9300062687A6839C67DAFE8DAFC27C907F5ADE9
+:10A94000FC43F1128C015E5F9582B3017EFC211FF6
+:10A95000EC07CF74EFF3015E69BBF3144A57977DA0
+:10A9600066E233C2DA8FA70F6C8F5A380AD0D7CA83
+:10A97000AE8DACBF04FE3C03FF1836502F8CB55B88
+:10A98000EDFA73E4C50ADC877766248D93EFD30B69
+:10A990009C5F971E38B75BA7FD7EF4D887BB753ADE
+:10A9A000FE657FFD74F79D6057FECCA9829C59F926
+:10A9B000C86F7DC484F79976C6EF671F7EE8C15DD6
+:10A9C000945FCEFEDE8EFBD1B3CF9CCED3E8BCCF5E
+:10A9D0001EFC739646CBDFF6CCCCA18087DB9EF8BD
+:10A9E000C6D0C1F6E740AF51BB795DA3B8AEDAD3AC
+:10A9F000020BCA3FCCD384F53976E8581E8CF3E3BA
+:10AA0000D7EC780F7125FD565F06EBB51CE53EC00F
+:10AA10006B289E57ECDFF027697C327CEBC345B88E
+:10AA2000F34628DB0460BDAFFDF6F472486D410DBE
+:10AA3000DA23BD28B713EBAD7C85AEEB25A9D7F1A2
+:10AA40001CF98B02F85FB97F23EB37611D3F867FCE
+:10AA50004C19B88EF3ED56FD7E8E2CBB1F6DFD4359
+:10AA60001949E3A68C755CFEC43F0D6A0718F2E035
+:10AA700042F85DCCE3FF82F6D0AD76E0ABC7DC7A7E
+:10AA800080AD6F7436CD3B7BE05C1E186BEFDB7ADC
+:10AA90006F0239D9FB8C5D85FDFA92675E453E3BBE
+:10AAA000FBC44B8A86729278046A279C257D7FDDE1
+:10AAB0006037AC60B63059B9D71BB3FBFAD76945DC
+:10AAC000F49A599A0FBFBF8DDFA38CFE57448F5C59
+:10AAD000272459B703F6422697A343102FCB49B733
+:10AAE000A29658D753980CEBF8F6E54077A9D6D143
+:10AAF00098BF0AF3BFD4B49E7B19DF26965F41F955
+:10AB000013FC837DEB1A155E2549F8F46C875D868E
+:10AB100038DFB329CED9FBEEEF7E45FBEF217B8AF0
+:10AB2000FD3BC7C385F8FC42F3FBAAF8BB1B82BF01
+:10AB3000260DC4E3477F492EFF8FD999FF6C050985
+:10AB4000CFCA9606EA2F8984F4E105FDE36DEE9203
+:10AB500050AE7FD42945A16AA29C5891C24FF89269
+:10AB6000D1CFD347C6833CFBE8E84F385D32BA5FAC
+:10AB7000B1FF6D45E7FA206AD60729FC547FE4ED62
+:10AB8000AD3C9CBCBD95FBFF94B4BD3372E8BB30BB
+:10AB9000FE33DD36A2D326CE744949FDABCFDA6D44
+:10ABA000D638716FC56B69B49EE47369D075E3BA2A
+:10ABB000D0ABB09FD35FB611BC4F2B07DFB7D3FC30
+:10ABC00046AF4BDB44F1D5E85B847E48A3BDA604C9
+:10ABD0003CC9816A1DFC1C72667539B391A396FD50
+:10ABE000B04D152DE3A67A3607F4D09B134EDB60EB
+:10ABF0009E6F25D8836FC9A479286DEF2D5D08AEAF
+:10AC0000D592D1B7B5FDF01A896866FD67EF7D135F
+:10AC1000C6437EEE2470BE22FDCCA9833C59B9DB2D
+:10AC200019B5D3F91C7BE28B07016F67EFB713BB34
+:10AC3000295EBC56656D9C7EE28BDDFF45F34F437C
+:10AC400065DA7FED6E5A1EECF0FD6E0CDAFF8FC7F1
+:10AC5000D2C6132A9F6B7F7EE7D5205F6A41A6D2BA
+:10AC6000F2B58F0E45BBEED410069F3A901B85754A
+:10AC700059F6F8332B408F2CFDB19B80ABE0D813F5
+:10AC8000AFDE04F0D99F7B31BEF1ECCF4F5F067C85
+:10AC900040ED67CDACC76F31BF3340DB5D0A30CBD1
+:10ACA00017CE735907FB92A59052B9B1F4E934BCA1
+:10ACB000BF632A87F556DA7B6F0FA27F45CF1671E7
+:10ACC0008F13CB063E5CDA69ED4F73303FE84AA53F
+:10ACD00077112B1FC966FCDA8DF54A1D9C4E797ED3
+:10ACE000627DA3FC384761423BACFE0A3BA94B4660
+:10ACF000FF931D4CDF2FEDFC72B4B53D9D7F4FECF3
+:10AD0000877DFF9EC0EE9790834E8C235AA6C44643
+:10AD1000A5537E7D52218B816F97F962A3FCB4BF4E
+:10AD20009F7239B9CC4561FA3D9B8F03CA034C1C15
+:10AD30003D3F86F55DFE949300BD2FFFB917CF5FB1
+:10AD4000963FF9C5A97FA3DF3F7AC28DFE92E53F0A
+:10AD5000BF03D77BB93D7613F8517A0FDAC91E5A73
+:10AD6000FEA383CFE7811DF2912D96973EC8FE7C0E
+:10AD700079979D5F6AB0CE83EE0B8AEBE878F4EDAD
+:10AD80002CFEAC9EB8826B21AE041C0740C7AF3BC3
+:10AD9000D939213FB75DCDFD499F2CD0D270FC251C
+:10ADA000CCAFB59AFB0F567F4B1BEA378D03E243BE
+:10ADB000C94442EE50EA46839C95E2DF241A85E5B9
+:10ADC000F8084C8D7292CAFCD05226F3B7D9328360
+:10ADD000A4B604EAB17822E2B9AA8FCFFE275DE2D9
+:10ADE000D5F76A43A1BD790E664F6F7386563870EA
+:10ADF0003FE3C17BA1384F2A10F427D8BCBE10D83E
+:10AE0000BC12C7FB854DB7833CEF3FCF66E727F504
+:10AE1000B2F6AA06F33FC1E5D280F9333EFB444DBA
+:10AE2000473E33E6B1B9414579B2B12180E9868622
+:10AE300062A2615C7F106189E3C35EA21309EEC95F
+:10AE40006A6CAC764F7508FC56D026F83B254F1837
+:10AE5000E9CB1EA8C3BDBFC3C3FC94924727B51E50
+:10AE6000F487219EE0BC05F0A470586E9B8D78A5F8
+:10AE7000F5F1FB7267F86EC08B2367AC454E2999DC
+:10AE800065167800DE0CBA38F0DF8D3F82F8023F9D
+:10AE90008DC6EF4500DEE05E04C0FF07F0F70CC38F
+:10AEA000DF542AA3CCF8ABB2C029F1772FC55F6677
+:10AEB0003F5F25E2A19EC7A519FC948A7FE15E0948
+:10AEC0005C1AD8D1D086A9F13D3D855ECF7532B9E7
+:10AED000564FC2782E4654E65721993AC931F99314
+:10AEE0004840C7FB4C782F1AF23DCC8F68ACAFA41A
+:10AEF000CAA7ACF24F7B15E673C70B3611E4955425
+:10AF0000FF0079C7748E26CDAE766A88E720FA7581
+:10AF10001BB97E5DDFB79E56FED8DCA061BA85F313
+:10AF2000C936CE27DB61DDC13F1714714D5B671158
+:10AF3000D49F775398EDEF6396732B7FB02B06F178
+:10AF40000E2893344C6328BF5EB34747D27AEE1283
+:10AF500012027AF1BFF6FD28CE957405C01FEAE70C
+:10AF6000F823870BFDD7B377106C4C4F1189A511CF
+:10AF70001BEC9F12F1DB183CEA807D77AAF1640597
+:10AF8000757B1EED2FEB753BCAEFCC1BBB5EABA1F7
+:10AF9000F3F0B4BA713F991564F4E80986855AD381
+:10AFA000FA65A5B0FBEE735EE976D2F5F4401C2E8F
+:10AFB000A5C71D6D239C781E64EB0A801CDCEC6722
+:10AFC0007A469B4B7BBBB4BFDEE70E667FF9CAAD0A
+:10AFD000FC6FC863755A99858E0D799B3EC34AEF05
+:10AFE00086BCEDE993B7D5B9309E8C783BF26322ED
+:10AFF000FD37DA145DA0764A23D89260DFBD2DB00C
+:10B0000078DB817200E3513EE929D803EF05ACE318
+:10B0100071D03AE517D43BDCFF699CB71F20D52DD2
+:10B02000F07E4B0BA52302EFCC50FA2118AF538CC6
+:10B030006984D20FE393C9981AF439139C2726FF29
+:10B04000B954F49CC8EE6188A073884CF7811EF057
+:10B05000331D99E200BB50B6054F80FCEAF58A5DCE
+:10B060001097B0DE33C70171D482BF1CD7FD736F58
+:10B070004DFE60E729F01208D08DEA09929325FD74
+:10B08000F77525B58CC07EF280A71BCFFBCA9DA2A9
+:10B09000C59EDCE60C5FE534C1A5D03B5FB7AFE3EE
+:10B0A000FC93DFFBFD0EE77792A39322137F1BF146
+:10B0B000A144D349B189CFD78DBC9CC039E740FEAC
+:10B0C0004E21C7F6FD63E458637E14D7CD9628372A
+:10B0D00032A97CF760AA8B2A8CFF50D33F4F403AAD
+:10B0E0005B0AF8209E3D7DF6CBD70B078E33516E61
+:10B0F000F5EB230DFD55541FDD3319E4600A7D7413
+:10B10000E48DD1DF86F8A9779E9704B3BF6E717C7A
+:10B1100023EA83DAF814A2D1F1D6B4FD00D3456D49
+:10B120001D48F7EF47D7FB303EA685EDE7DE8FDA07
+:10B13000A25201D2ED7909FCFA84B5FF7E7B2396F9
+:10B1400023E07D31F5FB7E3BAB4FCA35B4A73FE131
+:10B1500073ACD9660FC139CDFB6DB4DE20F8AC817C
+:10B16000CD5012FB14DF0180987F52371AE49CC146
+:10B17000EF7728542E011EDEB427F5B32F77CEDCEF
+:10B180000E7CBDDC196A839478D22FEA3D8A77441D
+:10B190006AF722BEC3BE6B2C7E56E6C77C87DBC532
+:10B1A000C49122DFC7EBABC9F397B77EF8DC5D141F
+:10B1B0006A2E095713D3FE5A226C7FBDE2E94AFE7C
+:10B1C0002E081B4F12FA64F66CAB1DE5D002EE0F91
+:10B1D00032E8B59F5EC23E7E2FD4424FB7C4B7E37C
+:10B1E0007A0B9B4BEF9942F1F729A523F0CB099BF2
+:10B1F000A70F053E5ABBE96BDB6EA4ED7FF6A28478
+:10B20000DF17C79D58FE83BB82F7DC08F6FAAF6CE8
+:10B2100018DFF4D98999780EFB81CDEA47A871B17E
+:10B22000FDCD5B4E962E8A6FB6D8C78B5AE62BE0C3
+:10B230007F5C14DF8ADF17C1A10CDECFF8F078A5A0
+:10B240000CE73504CF47DFDA787AC63AD46765E889
+:10B25000C7AADD624F7A9FE42DA766913BB53DAD4D
+:10B26000D82EA1F65166166FCF243F6AE370F90419
+:10B27000D6472770DF601197237DE36BB759E4C889
+:10B2800007CEE47E92FFE89BDFD7908F06CEEF32A9
+:10B29000C65F46BF3D8CEFFAE773CF9464F3E99F36
+:10B2A000C7342CFF813F79FF591CCFA71A16931082
+:10B2B000954335765ACE03FDDFDA3C19F6D9EDFE1B
+:10B2C00074C134AFDAB6A524643EA76C9FA7D498A6
+:10B2D000DAED5F07DBB39545FDEB90E52233611DA9
+:10B2E000EE73568B2EDA5FCDE6E9E3C3B8CF66F294
+:10B2F000E41D5B300FE4EAE9B65B93F277962B61CD
+:10B300007DDAF8FA50BBB7DCB43EC6BA24D63FF5B6
+:10B3100046EDE777811FE05E66D4A4C2D780752B27
+:10B32000488EB7A08BE9975354CF86116FDA93AF4D
+:10B33000015D6F71631C676AFC8D23E1C1F097C2E8
+:10B340007EA5F6CE18D710E897201E6ADB181D5C84
+:10B35000086FFDFD723AA84C3E9F9BFAE8A09EE85C
+:10B3600094614F2A17A2833B89EE18641E7D7430C6
+:10B37000E659333FDEB449433A781FEC94D103D702
+:10B38000FFA4A2FBA6C239D02609CF994EBAF4ACCD
+:10B390001B183C01E4F3495FE4EAA9E5FDF02DFB4D
+:10B3A00046FAE699FA3DDD72AB2F999FF5A654F463
+:10B3B00053A493928AFF7DF4F38E2D79FCF2726789
+:10B3C000650DF0018924F7E71AA921BFA5344FDFE5
+:10B3D000BE13F4E9494FE1E7519AFBA833BC1CE8DE
+:10B3E000E20E511B3F4FE8DF7F0EB03F1B664D7FE3
+:10B3F0007724F80BABA7BF6B437B08DB23605716A2
+:10B40000F0B808F46F0C437D90785EBAC35590F4A1
+:10B410003C767D43DD4468973874A29AE3E008B334
+:10B42000A3FE9330BF97311FC51656E15E9A229056
+:10B430006AA0739B1C6E817BBCB640E604DD84D79A
+:10B44000888BF9BF9CC78FB714D0FACEF75E5461D2
+:10B45000D076DA0FF8D71C39F22766FFB42D93C5E2
+:10B46000279222D3F742884FA0B0659F4FC73BC8B1
+:10B470003EF5A702C383EEB5333F0FD125D07BD76E
+:10B480003B89F187F6F7EF8D3810B989E5FB8DEC34
+:10B490002696CFFD972B6B987F32715DAF3FBCA195
+:10B4A0001BEC99EB0F0FC3FB74D77B46BF07E70B71
+:10B4B0003F051F3ED0BB9FE9E5C47A8F733EFDE791
+:10B4C0000E51B7D175396EEB3DEA86F17E8FBDBF67
+:10B4D00078C36F8FDBDC34FDC32B276D104F7433C3
+:10B4E00004E8D079CD239AC28CE028D69F4FBABC0D
+:10B4F0000CEE1A32C76B6E8F6E55A1BD55EC9CF7E2
+:10B5000086DFBE3213D4276D6F3DA437BF48146861
+:10B510007FDE21AD995DBFE3ED1DA6ED89FDEDF563
+:10B52000E391DF2B941D88977E3C39106F069EF0C7
+:10B5300002478505CF686F1878EEC35BDADCABC8CD
+:10B54000F8D4FC72BD67D47BEC7E221B57229E3F51
+:10B55000832CCA6FCFB8422F03DFEC75857E03E9D9
+:10B5600032476F9E5C88F70F5F05BE5C2185F3B3A1
+:10B5700046E0BDC4D143E05D98EEE4E7AB897CFAD8
+:10B5800026F00BC475F338CB9BF8FC8E7DFFB41707
+:10B59000E3289F78350FD2E552CF96EF02BFFD52D8
+:10B5A00042FBFB9343A3078D477B93FB3BCEBA8CB7
+:10B5B0007759D8FC6EE676DCCD87DC517847F3E628
+:10B5C0007AC962FFDE5CCFE23888DC3DFE3A8B1D33
+:10B5D000D9C4E31D06B603FBCEC4768CF91DCDCBD2
+:10B5E0001E07FBC3FB27291AF81F8EBCF8C9EF6B97
+:10B5F00029ECCA75E0B9EC163FA7DF4A11D7FD7EEA
+:10B600007FC85D0A7EA74DE9419DCE73D3B3A44B9D
+:10B61000A4F8393AE6F628C4216E9D2EA2CF6A5BC3
+:10B62000FC814815D42B61EF15A9DC1EDDD67DB257
+:10B630000DE8F1F46B76F4F73BBD128E6393AD3AEF
+:10B640000FECF7F73A94A4EFE39DF7C82C8E58E877
+:10B65000C178B7F924E200B971A87BCE50188F2FBA
+:10B66000485420FFD3ED92C8EC64C3CF1193999F47
+:10B670005D97191CE2A9EA34C7AB6D9C3503E32939
+:10B6800016B4BE84F7297DE5C9DF87BAC4CDEED9EB
+:10B690007ABBD3AF04FC7A6788F8B69137D82B40D1
+:10B6A000BDFCEE2A05EB478441EBE7AF51AF04BC8C
+:10B6B000427D90FFF917597FB49BC53B6DE7FBE4D2
+:10B6C0000E5BB079066DA7638B5F80F530CA85DCB1
+:10B6D000CC9E393DC3F0DFB0B8F6BC22D509EFA44B
+:10B6E000E48590B989B73C82F1B77BA01CF36F2247
+:10B6F0001E3AC63C1983F3E34DA01B609D6D8C9EE2
+:10B70000366D11D09F49F1970DFAE2BDBBEDDF8494
+:10B7100079E4B7082AECBD699A74DCF51E07A3F337
+:10B72000D67B701F08EE516837AFFD37382E6F8A11
+:10B73000F9EEF130FA78EF02F491E1667E9BBCFA03
+:10B740006EBE4F8AE13B8911C013C0A172F63EA1C3
+:10B750001CD2CC7128FDFCC3F661749E2138DFAA8F
+:10B7600099AC44C10F20B674E07BC0F32376720518
+:10B770009D5FABD01D027ED12789FC1DAED09B8082
+:10B78000A7ADDB87623CDB06319487FE9D7F55F0D9
+:10B790007CEC68E8937BE13DDDDD9315E48BA32130
+:10B7A00076BFF5FE35851DB00FF7D657E13BBF518B
+:10B7B0005541C9D2584E5E180DE7836B4455A0E53C
+:10B7C00023D5C63D0315EF314C903EBDB218CECF08
+:10B7D0008689E04B22A705F63EC8FA35552AACEB20
+:10B7E0007A355330EF5BEE7033FDF2B2BFFA0E37AD
+:10B7F000C563E0AE1D2A35E3297F668C037FA1DE99
+:10B80000A268C63D7178572483AF4B46B7185BE4F6
+:10B8100043D8B3986E91B74D637ECA1F5C1566FE20
+:10B82000453893AC40FF22FF0BE0BA667268D358EC
+:10B8300017023BD72DC2F2D04E166D27A35C8C5554
+:10B84000D076F7F843BB519FCC74209E88DCD3069A
+:10B85000788ACECC0E425CEB8E29A35E82FB551912
+:10B86000277AE7801E8DE6BAFED001726ABDA2017A
+:10B870009F67AC3975237CF7077F782BA4194DBFE0
+:10B88000BB13F481BFE74F0DF87D9662F1EF65BC05
+:10B89000FEC197909F51AD58FC84BDFEEA5D809734
+:10B8A000DD2591488DC6BE87B2FAE771606DF72C31
+:10B8B00078F7FAF43562700FCFC779ED54A39B186F
+:10B8C000DECA41AF1978DB206A5DF02EB37EB50386
+:10B8D000E9A38874A3BC1A06A7C8234CF4FAFAC6D5
+:10B8E00055102791389E1F73BE853F785F12D60A88
+:10B8F000E25194612CAEFE60597700ECF82DFEE425
+:10B90000F109673DACBE3DC53DF5331E460F201223
+:10B91000DBCA300D9542EA217A1AA4398E10C4C7C9
+:10B920001E14B53F229DEF9034581F286FA3EB776C
+:10B93000E48533E81F3C12F90DA6CF7B8A8DF662B1
+:10B9400059F03E6EF9493C1FD9AA321AA96D61F22D
+:10B95000A236D0E380F38ADA12A2EEE1F4A61B78D5
+:10B96000067F17D75735D731BC6696103C6F059FB9
+:10B9700018BC579605E528FE325BD6AEC27524DDAD
+:10B98000FA085A6E2BB40BEBD32412D66E8F03F940
+:10B990003722E17923E5F75FC379624DEB503C6FC5
+:10B9A000876BEAD05E3AEF379DB7D741DB01FFDF07
+:10B9B000E91609EFB140D80BC0DA1A4ACB489FBD4F
+:10B9C00095C5B45DAD5C5537197460C831CA1A0BA2
+:10B9D000A8BE00BC2DD0F555407F271DEA0B300EC8
+:10B9E000F74EBB06F35FB0F3A93BC06E71077A5AFE
+:10B9F000403ED44E66E34D6FA5DFD1BED17E0DE54E
+:10BA00006B5BED1AEB8FE3AF9CD319C7C3423EEEDD
+:10BA100085ED6CDCAEDC6804E8B3760DC52BE485FF
+:10BA200019DD834BF3BC887C7502E6EFD5B3B0DD3E
+:10BA3000217313F82281FE8C79D5F079D5AC61F3AE
+:10BA4000229C9FE8B062D06E4D399BE702C2EA8B20
+:10BA5000F09DB6BF90CFA7467F12D3852D764BFBC6
+:10BA6000BB8BF776E37DB612451310CFEC9DCC3C33
+:10BA70003EAFBC26D65F5EC993882F526F1A2FFA4D
+:10BA8000454D30E5ABD3CF53C6A276AE90E74062CA
+:10BA90003AF97D05CF518A765AE7757AE3E8075A75
+:10BAA000C1FF79B782E71507C5E09BF9B80F553498
+:10BAB000267F82BF990D727A615310E4F8814A861D
+:10BAC000FFD3DF2251A0879127AAD301DF234F8420
+:10BAD000795A87E7D81421429FDCA3E3A35BA7161A
+:10BAE00001E4657CC48F16831CA0EB0CF660AE7974
+:10BAF000DC747C192D59551087943939BD4AC1A77A
+:10BB00007F13F24FEC9A03EFD8661EDF752BF433E8
+:10BB10008C98E643F3477947B0FB57C7692E94AB3F
+:10BB20003F7517AC472B7F8F7E248C2C1DD3E39061
+:10BB30006650FEDE9C0EE394C98CB27E79B0EFEEC7
+:10BB40008A092057F0EE4819A6315236506E98CA2D
+:10BB50008FE1E5752149B952AF66D997EFBBFBF28A
+:10BB600031B07FDF0A76621ABCE7A77E0AF1317A2C
+:10BB70005044BC6FB5C51C2599F05EB848C07ED94D
+:10BB800056FC3B11F86EEB211204FAC8A8FEABDD9F
+:10BB9000BC8EB51E3FCE5B56C866E0FFA3634ECD9C
+:10BBA00082758A1E11F13D89AA5F7876B9C11EFAA5
+:10BBB0003D8B3FE978BE0EF5F7ED794AD2F79AC989
+:10BBC00005ECC4C4F2E923E7A01F2F7FE7767C17BA
+:10BBD000B676961CBC8296CEDC595909768C564DA9
+:10BBE000A96B281D77FB84B5C084DA6C765EA5CD81
+:10BBF00062DFB5192CDDDCB07822ECDB239DB2B31B
+:10BC0000888E77EC46F66EDDE6924F1C616A979659
+:10BC1000573EE6F816FDFE6E39D582F4FBBBD33EE7
+:10BC200071C2F9CCFDE5551980CF432D56BB8EC0AE
+:10BC3000A36A741F546A8F84BC745CADBF25884F9F
+:10BC4000C91E6BABA1B0F494072C9C01FB9B8DAD7E
+:10BC50001D73814E17146378F280F97ECEF5C9FC0E
+:10BC6000FADE59705FA94027EC1C35720F0AE58592
+:10BC70005C6414E8DD2874BC3BD9FE2422879E0353
+:10BC8000B91C29092B50C59067AD236B1E0479F6AA
+:10BC900025B7EB48DD62BC0789FC2F813DD45B9959
+:10BCA0006CDF749DDB857475BAFDDA57C13FBDA0AA
+:10BCB0009ED9FBF9ED9F0AB81ED4EE1B46DBCF2FB1
+:10BCC000C7A72AC98235114729AC4F9148340DC600
+:10BCD000D345609F10A1FAC78C07A3DDBFB5FE76E0
+:10BCE0008F1DEB5F079BE749FDF3F1F0F9E405E9F0
+:10BCF0007C92E8E939BCDFEFDDF7E9912980FF3577
+:10BD00006C8B941F795B7098C691AF5FDC38AE8501
+:10BD1000F6283E1FF1B07B0BDEF21EBC679428DFD5
+:10BD2000C19C07BEDDED3E3B81EDEFADF27400CC72
+:10BD3000E92AF17B5E82BC2AB577E13DD0D603ECDF
+:10BD40005D74D87943BE40448DBD171B35DE2FAFDF
+:10BD5000837263BD1E15E8A075CCEFCA003F5BB8C7
+:10BD6000BDB0B084E07E75614E37DA0BF39BB8BD91
+:10BD700020079B41C8BADBFD6493C97E405309B6D6
+:10BD8000D04DDC5E30F43FD7DBB581EE16D4AB4D41
+:10BD9000EC7E6A9F9DA133BD9A1F607ABDB685F681
+:10BDA000A37162AE30DB254C8F6B3BB9FDC0F570E3
+:10BDB00006EF37B385E9AB0CB0237C107EA0A35E01
+:10BDC000C6B3BCAC7EBB654809D39719AD0751AF6C
+:10BDD0007583D36508C80DA62F735F7A45073405B0
+:10BDE000E8E7362AA77FEA667234A052FB2CBDDF53
+:10BDF0003EDB20F27326C2EC438CADA7E37C9CB7FC
+:10BE0000677CDFCBC777F078FA3741BEEE8B144EF4
+:10BE1000904C7C6BDCDBCA2B67E7F479F5EC9CDAA1
+:10BE20001B5CF4A0643A7F68F1B077AE5A0CBAAAF2
+:10BE30008F05A05DBC4788725C41BFDA4678170A5F
+:10BE4000E885EFAF6E70F3778D38FDA4D227861C9E
+:10BE5000F29290AF84E2F7DDE88328AF75BA5F8293
+:10BE6000B9BD1B69CC5E02FC1EB9A61CC6BF75CA53
+:10BE7000E71877919F62BF78DED8677E45B9EE9D5F
+:10BE8000F50ADB87768B49EFC94CF3CA389F2E99A8
+:10BE9000B8019FCE087BA7D03959495AFE122F937B
+:10BEA0009B2E2F7BA760EB9407F15E634AFD2C135A
+:10BEB0005D4AA24F0D7DDB0AEB3C9590999E1B9A43
+:10BEC0007594FBD16A09E52BC17D6784FF5E8C5EAA
+:10BED000ACA0DFB0D51671C07A6C2BE7EBAA3A3A6A
+:10BEE000E05EFA575E178A0F58E78D21312A14C099
+:10BEF0003A47D552E6D7C177394ED3FDBBF99CE21C
+:10BF00004A2FF36775C99A08F189F92D8CBEB64E90
+:10BF100051701C9B266475480566F9CBF0749D9B97
+:10BF2000D1D7A629CF217D5DECF816D5DF39F55D97
+:10BF3000D339E2A97B1F2A043CF7BFCB121AF4FEC7
+:10BF4000C2A2FA97A6EE4D723ED0970FFB280FECD7
+:10BF500003A33798CF59E6F1F55DE0B5FAEF40BE9F
+:10BF6000DA707311CD06FFD281E9511FFAEF97B154
+:10BF7000F3DA5BF879ED99BDD7E2BB07A570973688
+:10BF8000C9BA7FD0607D07E2837D0F6533BF46D499
+:10BF9000625FDDF2E04FC6B2776574FE7B1A44CB78
+:10BFA000AC60EF5FA39E7E2EA8DBA5FE77CD8C77DD
+:10BFB000D82EF65DB7746A86E1BE8B54639A45EA63
+:10BFC000300D9008A6D9A40BD31CD8E7C2FB6BA4F4
+:10BFD00017538DA82231C9FD421244B88854632AF0
+:10BFE000C3BA65F49F4BC89D0E8CBF80F30BE07BFA
+:10BFF000E39CC238DFAFF6D644BC49CE2B567B4318
+:10C00000DBBDA8576228B7E773117EE2C763BBE0C8
+:10C010007ECFEA2DEC7E8921D7715F43DBFF513A59
+:10C02000D303FA0E01E5D73AF7D597211E5B6D1FB2
+:10C0300099CF1B88C35104BF1B63B43B9FFB17E61A
+:10C0400073FD07EE6D76FF2E88F77FE6839FC19420
+:10C050004FFAF2D97D6AA31DD13D6DD460E77BA66E
+:10C06000FA188F5C9360FF5F506F27C00B12EBFFD5
+:10C07000850E28ABDF0FF7A3CBB43C76CEC4F436E5
+:10C0800025240DEBB5D8DFC67D586466C88C9713A0
+:10C090009CFE0D7DB220C1AF9F982E90395F24B4D5
+:10C0A00043359F1FEECDE0DB2626BE36DEBF357E54
+:10C0B0005FEB96505819C6AA05601D553EEE0869FB
+:10C0C000AF1A46D3F70136F9F35FF4857FE735C53C
+:10C0D00043A9A13AD1FCFED222CE8733A5D64A90FD
+:10C0E0006FA7C32408FB875B48DD56B0C7C82B1277
+:10C0F000CAB7E174DCF0BB3FB970A0918EB0AED08E
+:10C10000F4E306762FE754C2FBD51FF277914ADBA2
+:10C11000EEB81AE8E00C7FB7DAE07FA3DFD22EF7A3
+:10C120003CD0FBA55DD36BA15C69A71D7FE7A9F897
+:10C13000D0C66AF00BC13B2D2EDA4F0EEDCF910E1B
+:10C140007284A0BEFDB0D5155D47C7F9619B8472AE
+:10C15000F95C8988EF8DC07397121F5F5A3AB4F368
+:10C160005F37811D7286CB11E3DDC70F2B35DC1FD6
+:10C170003F7B608300F7123E9CA7E1BC3F1CD69535
+:10C18000974EF193E363F7738AF6DB6385741C4B78
+:10C190001EF97D610DC8BFC2C89264E7CC437C4CD8
+:10C1A000FE7DF804C178B80F9DFC778D1C5D3EB311
+:10C1B0009F35CD2758E4D6875EFEFB48391728C740
+:10C1C000E3CB89A7CBC7F8BECB07E751F7B87F8C85
+:10C1D000F7D74E3DC1CE299EBDB7360FFC51C37D6A
+:10C1E0001A3BF73EF038C68DC33C601F4DC7A7C150
+:10C1F000F8EE71BF7906FC0FB41EDECF30EA9D3A2F
+:10C2000050CBCAB7D1F23EC43BF195013D30BC934F
+:10C21000FD4C4E18F6E3D26816FEEE427FBE88F95A
+:10C22000304427C57FE9FE6BF05CABD497CEE8596C
+:10C23000ED1A3B07C71FC983791C981ECE033FDE4A
+:10C2400029E377A0E4481EE0A1DA1B2EF599E6FF6A
+:10C25000C1DB4FA17C2F16EBDEBA0BE8F231F63BC7
+:10C260002477BCBE5D34CB8F69F0837893607E2BDE
+:10C270007C701E75AAEFBD9C088BF739CCDE635D20
+:10C28000CA79EF5407DD3F517C7CB0FF07987FAA45
+:10C29000EF3D9B2E8C27FB60FFB174486B783C3FD1
+:10C2A000895E8BFC45F1D2E248A2AFFAEE4545D952
+:10C2B0007DB7B3027F87F43E036F75CA1CCB791537
+:10C2C000E3EF9CF682E3682F4793DF934BD4F78923
+:10C2D000EFCA5EE81EF049CEA7EFF277D1567BC3D6
+:10C2E000D7FB505F58F548CDE6E57980E71AB8539B
+:10C2F00087710ED3AF80FD36DE3761EFCAC6104FAF
+:10C300007DEFC64EBC02E21C4FF9195CE79BBD41B4
+:10C31000E77864EFD256B2FA052CBF95E7FFCA5B07
+:10C32000BD98F54F04F6BB46363FFC3E8521FF52D3
+:10C33000CFDFFAFB14F7834C1E82EDADF60DC16C16
+:10C3400081CDE7EF6BCF90377F773B8E7F6C3B865D
+:10C350001C06BE84903D120C8EFD47E0EF6FAD4F82
+:10C36000E6E65BE4F917F78E688673A0730182F145
+:10C37000CFF6D6B504F4D2C29DDB93FEBE5D1FCCD2
+:10C38000E349941194CF4CFC1CF3313B3DC6E521AD
+:10C39000FCC1F9CC2842F87B1794A6B230E406F72A
+:10C3A0007FA3F97BEFC52482F6D558D2856909E9C8
+:10C3B000C6743CE9C5148F494780AB2F28F1777BC1
+:10C3C0002B60F2CB1CE1FB2154F7AFF6F033404F6A
+:10C3D000F07EAF20815DB4622A8CFFA84F357E07C6
+:10C3E0009424FCAE5AFFEF816860D7CC0E0C66D760
+:10C3F0001055FEA82F7EA390BDFFCBF821D5EFC42A
+:10C4000025FCFE24BF476CE06139E9C2388867DB50
+:10C4100057BF3086E27FC97E2FEA8351ED4DF83B4E
+:10C42000604B487716DC2F1DC5DF93206DEC1D0F88
+:10C43000E39D88316D76CBBB1ECB137E876829FFC9
+:10C44000DDB0A509DF8DFB9B9BE143923882C4FBE5
+:10C450009FA77D29DE612D49FE7B3089F73FF77765
+:10C460008918DFB31AE285847EB937666F9DDD4A8D
+:10C470005F5D971599DE7B6A14826C3FED7585F6DA
+:10C480000903FB19AB323BEE8020248D23BB268DA4
+:10C49000EF174913B98AB6D3B84C5661BFD918758E
+:10C4A000E13968A3CAF685C3BD550ED8A713BFA846
+:10C4B000C2FD94CBA569185FAE2C9727C2B9E7F1EE
+:10C4C0003D4BBAE1FE426340463FED703F3B0725DE
+:10C4D000C3447C1FA0497DCC3F1FD6C9C3CE19736E
+:10C4E0005582BF637AA4E37611E046BA6D190AFD5E
+:10C4F00008E16EBC77334C26FCFC75F6044A7FF9E4
+:10C500009C1E64D28AF78F672C7FD7097A3D9FAF34
+:10C51000FB94B4029C87CCD77377FD493FD0E9F3F5
+:10C520001DCD2F5F4EDBB345658C6B2DFEB2F10F39
+:10C5300097D3FE7A3B148C6735F090B746B6DC9FF4
+:10C54000CDB9CD0A2B09F7886562CAA7F038DE3F5E
+:10C550003CB81A33C755658698B350F5E0FDE04BFB
+:10C56000D304661773B814608A924E5BA4CA45C799
+:10C57000D9F986807E87A31D8BF2314EFF27E17C9F
+:10C58000A06F831E12D7EF4BB087908F7427BF1F09
+:10C59000EC84C3BA44FA696A2023C11FED881E7770
+:10C5A0008D83753C61C3F7A4D673FB5BF6B0F87757
+:10C5B000835E12D3F50974B7FECB6B91EE7A29DD59
+:10C5C000257B17CEA827AB1ADA09B61C1204F6B0E1
+:10C5D000657667ABB4DEB8A794A087A2ECF2474BB0
+:10C5E000D2C09E1977EC7AF65E1FC517BEF758AF1A
+:10C5F0008C847DBFBD3E73A49C01E53C488F9F7831
+:10C60000D8F98F5CEF0E427E6347454033D1757396
+:10C61000833A521E09EFA53A46C2EF2335A7F89D8B
+:10C62000E65CBF580DFE2585EFFF97A4B1F12E49BA
+:10C6300073637A0B87EF93F53930FEFB28FD40BC1E
+:10C64000C091DB18FDAE1EE6C07BCFAB9F1F3174DF
+:10C65000B038A0071B0223016FEDB7D5A0DFA3728E
+:10C66000D571E715C0E75E870AF428F946DD330D7A
+:10C67000E8FD051BDEFB6AF45668F34DED49BEC9C3
+:10C68000E85792443D1B36450D697FB8421E06F4BB
+:10C69000A2EF024DB461DB11067BF56C81E66FDB26
+:10C6A000F62C8387E8BB049A7FCFB6E7199CAB676B
+:10C6B000C32F80DCBFED570C1EA9EF02F8A16D2F30
+:10C6C00031186C0B6AC73CBAEDB75780EFA7D1168B
+:10C6D0009C0BFE9D1FD3F197D8E0BD5A961EE478BF
+:10C6E00031F21F83EF14DF87789A98FF24AFF77435
+:10C6F0008AFC7FE7F98753B4FF335E2F96A2FE5181
+:10C700005EEF788AFACFF17A2752E4BFC0F35F4C2C
+:10C71000D1FEAF79BDEE14F55FE6F55E4951FF77C6
+:10C72000BCDE6B29F2FFC0F35F4F68FF4D5EBE8732
+:10C730007FCFF1B6FC41A77497D3C15EF82CF6B653
+:10C74000A0FDDE5E578EF4DF3889D91906BDE740BB
+:10C75000BC26C85B95C5558D52D93EEE9769CCDE97
+:10C76000A85C55B40DE86EF5AF24D4A7548FE0EF64
+:10C77000F0EAAB58DCCBEAE7D97D90D5AB647C27F7
+:10C78000CDA047A3BE31FEDD7C7C4D7CBCC7D20A68
+:10C79000F9794B60E46C73BCA76A851D949F206493
+:10C7A000A72993E997E255558ED1A03FA87E01B9FC
+:10C7B000B9DEA3C4E01EFD7A55C6FCA6CC2A15F24C
+:10C7C000755546FDB33EB3CA311FFD39E9E89FC830
+:10C7D000E7717B4DAA8CF7F865FF0CCCBFFCD1D973
+:10C7E0002AC8D126D2EBAF84F9AD91F1BCF6485DF1
+:10C7F000157ECFF77FE607F9FCAC9FE1FDB8F7396E
+:10C8000027BCE72A7F4F447D81F8A3FD16AE11A314
+:10C810001A2D725C5D2D02FC4013D357F4CF3BA15F
+:10C8200082C771D0BFCEDB2B5E80F89DC62D721003
+:10C83000CE73E04F36E98322FE7BA54355B66F34B5
+:10C84000F4D57DDC8FAB071C188757249380F977CC
+:10C850002C87AAFC3C8DBF63362262D54F052DD6AE
+:10C86000776CF213F453A2BECAADA3F2D154DE1E0C
+:10C87000502DB0A0B2F72CFE17044CD03900800028
+:10C88000000000001F8B080000000000000BDD7D91
+:10C890000B7854D5D5E83E67CE3C3349669299640F
+:10C8A00026CF49801020C0044204449D848011B1E9
+:10C8B0000E0F15D4E2846780BCA0A858E9C7840491
+:10C8C0000C1435FE46047EA003A28516ECD0A2020D
+:10C8D000063B2022FEC53658DB8B8FDA11B9883C27
+:10C8E000C747953ED4BBD7DA7B27734E12C5B6F740
+:10C8F000FFEF77D3CF1EF6D98FB3F65A6BAFB5F6ED
+:10C900005A6BEF215EE2FD5A47C8E23D8B6FB410CF
+:10C9100042C6FFA228395A44C85253D210924CC87A
+:10C92000D7F07703214DCBC3D7F7D513B269B9A997
+:10C930009F429F4D5F0E9F464A0889255A7CDB2403
+:10C9400042562DB7F553FA75B51F68A32F9D846C19
+:10C9500056829389833E430A69CC23E4D0129940DE
+:10C9600079B1DB1432D2268B5FFBFD4DFDA1BC48B3
+:10C97000F6124F577FEDF399E5AE7EF0FDDF50984C
+:10C98000605C7D40EA777A38FDB71270F91309E9E7
+:10C99000D3AA9C8A9A08FE7D4DFFCB6BA1E5C2AE5F
+:10C9A000B25EEFB7D9AC84E492B876141E4553D684
+:10C9B0003BDFB4078A607C05C7D7C291DD40E71F23
+:10C9C00037AED165539557490D85A40F7D52580157
+:10C9D0003F41A71C7A9ACE336BE983A34FA71292EB
+:10C9E00079D4D20C7825AD4F129246880EBE4DE711
+:10C9F000AD483E0FA17468CE2BF64AF479EC590B82
+:10CA0000C353B615F16490BCE937D3A751F6DB6088
+:10CA10007CFAE783F11FCAB66C5D9307C58009F005
+:10CA200090B5830E98418BC19CD53E85D289A29B3F
+:10CA30008C86FA375A7C745E3BA4CE722594C3214F
+:10CA4000036B4F4804FE6F8F2CF17AE2535C84EC49
+:10CA500096245E5F54599145DB2BB6418A9790B975
+:10CA6000AD435BF4D741BD2CFAFBC8483A3FF81EF2
+:10CA70002F035E7E7E84D707AF6BA9E84BC737884C
+:10CA8000EF9320B4DF23CBAC1C2C6D81F17797F3AF
+:10CA9000FE41CF6ADF1884E7669D9D9025B6B216E9
+:10CAA000ABBB0BDE95F61B5B1AE9FC2E7AA2497430
+:10CAB0001AA476EBE93442875A352DE0073C12E29E
+:10CAC00025FEC1849C9528724774D14FBFB72C981E
+:10CAD000495F5D3EFAB7A422FAACD7458F2650FCD9
+:10CAE000D5EE0B98F4F914CF7A5F3033AFAB5FED2E
+:10CAF000DE492440F9A6BEBD189F3DF43BA6C8FF01
+:10CB0000543F93E12ABE7731F246DD2E5A55AB0BE6
+:10CB1000B458FB607BC2E8DFF3FC44FF8BBBDEB89C
+:10CB20001DBE77C9134D9B007C19A178E9A19F68B0
+:10CB30005FB7AF8C00DF5FB1F89A6CF4FD5D76B63D
+:10CB4000CE88D2E085F66153ABCD4BEBCDFA56BF24
+:10CB500097B6A7A40CC923BB9EAB6C7D713CED7B43
+:10CB6000EDFA099B48EA44CAD7C11AC5FB34817261
+:10CB70003061082DAFAD55863752905614FF71586D
+:10CB800011949FB312232D37D51C7115C13AF21A97
+:10CB900008152F64EDA8B01BD67173AD61DA76E08D
+:10CBA000DFC862D79CA2AEF157DAF508F7EA57E87A
+:10CBB0003A1B4A9FFAB05D82FEFD1402EBD06CA7CF
+:10CBC00074A665B33B8504F3A09D752DACC7D5FA5B
+:10CBD000406539B473CBE469FA5D73BFA995E51478
+:10CBE0000E975396740847C5C9B9B4BEC96600C943
+:10CBF00046DEB0CFDC0578FAB9E26D8075F873AB2C
+:10CC0000D516A4155436FA60DD2AFD1C21281B75A3
+:10CC1000A4214CE1CB2C26FEB0B50BCE376094118D
+:10CC2000F03420BC6BCDE14965741CCB62D916A4ED
+:10CC3000DF5B5DBBAE633CFDCE7FD63E7FA291BE87
+:10CC40005F93A61080C3EA50228624CAC7B7501843
+:10CC500029DCBB1BFD36909F31A742B6D17A4B5FD2
+:10CC600003F1C4C9416B112DC7C9A75487E233D35F
+:10CC7000FE317BE0651BFDEEF0D7DF34417FD70846
+:10CC80005986651356189D934AD4E3D8C6A8C74958
+:10CC9000A950D73B26AAEBD3A6AAEB5D77ABCB195D
+:10CCA000B3D5E58982DFA8CCB196D279B02A628962
+:10CCB0007EBC9C24217EDE02FC5B0A642FE0C75C04
+:10CCC000BBFDEC5C5A9F09F284C24F8690D0D3948E
+:10CCD0009E87737EE889523C1B531A3CF6A2EEF8FD
+:10CCE000C8CC36DD0CF4B2F6556C84B6B7BEFBD1B9
+:10CCF0009730BE95C4B5CB03FCF84E037DE1CF451C
+:10CD0000E149847F7800DF0D7FFE11E8BD133A2FE3
+:10CD1000E03BB356C1EF3F3CD513D2E5B1E684B654
+:10CD20004FE2ED934C6B3B7443E8F3DDD58B7449D4
+:10CD3000DDF19A461A245897943F505F902A82FA60
+:10CD4000E221995403DFD0E54A603C1B74A072E6EF
+:10CD5000C61403F2CDDFB97EA59C26437D9A8D8D46
+:10CD60006970CF36C37A5E7994F1FF4A031BA773CB
+:10CD70003C0F7E145510C849A35DC6F1C438EB6C56
+:10CD8000BC0D2F3BEDACBCE748CACDB02ED74D4D06
+:10CD900019067C62944900C64BCE32F906D0F99947
+:10CDA0005F3304253A68B2428EE853687B0BB9C7FB
+:10CDB0004FE1D870CC12D4D1F7E639FF61A34826F1
+:10CDC000857606F79E15DEDF831C8855298847B3D4
+:10CDD000B3D536AC88CD2148E14B817F50F958D688
+:10CDE000AFCD06F43497B5A2FE3617B7B6029E361D
+:10CDF0004C94D19E48992D233F9BB3C327FAD2F779
+:10CE0000FA39B20DC64BA18ADD4007793CABD5EFAC
+:10CE1000877129CEE552C62A302ECE907E2795E323
+:10CE2000D5E1D87BBF44C74985F186B0F680273B62
+:10CE3000C793D7EE41B81D7CDCD4BEB4FD10364E8E
+:10CE40007369D738828E1B2A4908E013DF15E37413
+:10CE50008E4F7C12C855FD6F28DE289DA41C13023E
+:10CE6000B772010919F3003FFE86ADB8AEAD641B81
+:10CE7000AC17475639F051C6B18D93E521D0CF821A
+:10CE8000DFD1CF2121E0E30C8598AE4F01FBC58FA8
+:10CE900078D4AE57F791D629748D74D245BB7EDD18
+:10CEA0000A69D1A5745FC76E87A3BC60480FEB59B0
+:10CEB000B35EDCC762F702D36BD7F596844BC580AF
+:10CEC0001712DF5EF7ED659D2E7C623C102B9DEA0C
+:10CED000098AFA1CCDF708F9CA086589C89EAFFB14
+:10CEE00080DCB7F3F540F5155DAC7B86D9C65A6199
+:10CEF0009D2E22C85FE52FACBDF33774BCCFFB1964
+:10CF00006CA057B28FB576807E24FB02FD810E9B0C
+:10CF100094C04F1268FDA693E904E4F66A339906BB
+:10CF2000FCAD703ED7EA97957CDD7840CFB9FEF92D
+:10CF3000A7B007C37DD306D9E8DA5BF9D8E1632649
+:10CF4000E77FA39D45FAA39D9575A4A3D10ADF6F42
+:10CF50002D6F3151FC9A5F67ED9B6939A800FE6A1D
+:10CF600072611D1ECE9E8B7852DE3612E0D3C13A1E
+:10CF70005F08CAE41D3301F9BBE3B9BBAB3D207FB9
+:10CF8000D22678400EADE3EBBDCD2EF5882FC5E05F
+:10CF90000B803DA17DFF08E017E9E93F5B45E938DB
+:10CFA000F8290359432B0BE5992D79B02E5653F9E7
+:10CFB0004B6B67EA3C753F96BAE8F30B73D9763B47
+:10CFC000EC3B969B48C048E775452201BA38B31D33
+:10CFD0006F9481FCC9211109F46C4E03357881AF3F
+:10CFE000965848208EDFB3AE28D8FE1766DF763B12
+:10CFF00097FF262A07F4EC9FE4E7297E52E560328A
+:10D000000AEC17FD2ECBFB203788A3C2D7B9DFC8A7
+:10D0100007FEA57A9F7E6F0F9FBF9EE2503F8CFE5A
+:10D02000679523C621DDDB3FCFF1A398AC11909724
+:10D030008AF5F849942F36E5427C3B5388E91B5228
+:10D040004342FD2486172CFFC086E54C2A7F8DC302
+:10D05000D0EE0F1A01CE24B6FF203E9FC79106EBFB
+:10D06000852092B34CA4C544DB21B7D3F5E6261D39
+:10D0700066B49B8F100FAC078A31FB9904145904D6
+:10D08000F0BA8990CAF875209E0536462765A90E24
+:10D09000F74B835E36233CFA061232833D04B051CF
+:10D0A0007C2B4B484881FDD65203B62BB079B09FFC
+:10D0B0008134A03DBBFBCBF732404E5B8E527B6C84
+:10D0C00028D059463965B1A8D71F218D88A7D39C90
+:10D0D0003F362FB7219D3BF7678137399DA38DA040
+:10D0E0002F7296A4A8E82BDA655DC92481E1F1E3EB
+:10D0F0008670DCACBE47245204F53958BF79B9E7D5
+:10D100005BC6CFEF657C37F251EFE36761FDE6C8A0
+:10D110009BF6EF51546C8A1DB1FB3D5DF6B516CF01
+:10D12000594BD47279E83E7559E0C5ACF7392651B0
+:10D130009C9BEF95BD5BE978D79C54B7ABCCFB03C8
+:10D14000EE6FBBDA471C53A03DDD7F6FA56FAF3D8F
+:10D15000AB6EEF2F7BC50EEBB8AB3D83EF862BEAB2
+:10D16000765AFA68E1A570396F8B836BACC9A8AAAF
+:10D170009F56D50D2EE71D7170DDE852B70F34F6BE
+:10D180000CD7CD85C66F844BB4BB75E4D5B5D3CE73
+:10D19000634AA5B117BCB3F6774CBBBA71EFAAFED0
+:10D1A000E676F72CD57E2788FC7EB3E4BB26853E49
+:10D1B00067C22BB017AD16B47BB5FCB29DEBA7EBE5
+:10D1C000C19EA34F7FA2EF7AE83706D61D2D1B76AE
+:10D1D000FEF14E902FC79E1D980E723D13F41CE277
+:10D1E00093F915F6D4B8D0AF3095AF53AA4F9A4102
+:10D1F0005EECD941FB2531B8E2EDA7D41AB6AFB049
+:10D200009118AE67612FA5109BC4F6E3CCDEE9ED63
+:10D210003BDAF11BED0CEE594BC7920FE83A7CDE7E
+:10D22000602B53607FB645427B6056854F9748F927
+:10D2300063748B847EA3590FFC6038C89551A73D59
+:10D24000FBA2F4FDAC90DD0B9FADEB20BE10E5AB77
+:10D2500074DDA2E21FD1E71387A9FDC3CB8B80DF6A
+:10D26000AC3E0FEC37AA00223ACE057D43B10DE467
+:10D27000E6F7AD3E909B55537D6FE17CFF41AD12CB
+:10D28000DA6E0E9B3A79A16D92C143ED8CAABB3D3B
+:10D2900023C1EEA90A9B7DF83411C542E75145ED43
+:10D2A0003178A61B886286A78598E059BA82D95F33
+:10D2B0004923FD862AFAFDAAF69FFE05FACD5322E0
+:10D2C00087983D19C27957B5BFF657B0D7E6F8FC35
+:10D2D000069017837618984DCAF96170585D0679E3
+:10D2E000105F2E8EA8CBC38FA9CB7F4A61F83D205B
+:10D2F0008506017D0E500507FBE2E06E23EA8BC335
+:10D30000078D489F85E72D5BC1FF3476A115E5FAAF
+:10D31000F99F99D11F75400E3F0BE5E0B309B8AFF7
+:10D320003EF4F68152899617FC225186FA17BFD433
+:10D33000219E613A7AFA7EE1B303B6AEA1EF170EF1
+:10D340000F97DAE8FBE70712D201F54A6808CCEF3D
+:10D35000F9AF74387E6CA731B48DF2C3F9FD3F7D0F
+:10D36000F641FAFDF33B3353244A976B411FD076C5
+:10D37000A39F3259609F31FAFCAE3E202F16EE304B
+:10D38000AAE6B53545E2FB194F12F05B6FFEC453B8
+:10D39000AB7F8AFD0BCF9E447E3BA00FCA1698FF41
+:10D3A0006AC65FDAF63B52D87A127040BF3C4A9F99
+:10D3B000CB1F59EE013F5AFFF56AFC0E08A9CB615D
+:10D3C0000ED74C12F73E0FC6CB5FE5023B752B41E3
+:10D3D0007BA6F0ECBB77E6811D6D64F683168EFDAF
+:10D3E0001C8E9FFD8C8EC3E4838ED9CF74C6743D92
+:10D3F0002EE47CFCA2C4EC57FAB72493F2ED425021
+:10D40000FCF95DEF176AE010E3DFCBC777F07D75BD
+:10D41000EC751DD2E3DCF2EAE1A7FB7587E7CCF2FD
+:10D42000860115FAAEF2DCF58B8EBA69BF9A3D4ED5
+:10D43000DC278AF7353B5F4EBB8BBEBFB043F18222
+:10D44000E95A33FD99474643BB9DBA30C00BF53EC0
+:10D450003ADF0BE15792A0DDDC4DF661BA383ACCE9
+:10D460005B7FEF808A3879F85DD78358BF357C7F42
+:10D47000FBC2C88EF199C0DFEB252F345B18BE6D5F
+:10D48000CA2D60AB6CD279FBD1FA5285F875C370A6
+:10D49000EB3D159E357B9E3B9A41EBEB0F8E28852D
+:10D4A00079AD91FD370F06FEDFA2473F96162F9FFD
+:10D4B000707AD3FE1199F65F73BBB53A64C5718F6C
+:10D4C00040F970E1361DF8D993CE52F9C4DE9F942D
+:10D4D000E99A3CDBBE7208F8130FE8AD2DC0E707F0
+:10D4E00012191D82BB7528E74984CD6334F71B2FC1
+:10D4F000FC539B41A1CFB367572495B17584F205C6
+:10D5000084B283CEAFFAA9C1B8EEE6AD57AF13D15E
+:10D510004EC03B3FA4AED7F2474AAA5857A4309E0C
+:10D52000CFB4ED5227060DB0AE6A9652791C67FF54
+:10D53000D49C6E3580DDA4FD0E588044D05587FC08
+:10D54000493C385F339B2F35594D74BEE7E05FCCC3
+:10D55000EF2DC1BE7C818453240B07920A0FC5E7CF
+:10D56000C2C9A4129E07A4C8233A2ECFD0FFBE3B47
+:10D5700001E5D9055BF499FF04FEDB95ED0DD2AA18
+:10D580000CEE97BBE08924A5D0E7655817C07F361D
+:10D59000565ED04EE5395DDFE72F1A50AE37865F15
+:10D5A0004E027A5D78D62CCB942EE7F7A496833F73
+:10D5B000E742F8374930AF73E1D472F0CBF5266F0C
+:10D5C000B4724AE8F3F7E19FA3A89D96EA1B960A76
+:10D5D000FB9DE65430C6497A6A4371430FEB5FF412
+:10D5E00073181A8A3D2037BE6FF5C2FABC21D5C325
+:10D5F000F486C4C6833F1FADFFE458EA36A0FFB1EE
+:10D600004305C9A0E73F219E6490BFB739FDE5A956
+:10D61000B4BDABBCC3A703FFDF04E26DA27D3ED067
+:10D6200079EFB3513CCF2654EFC0B32460407F491B
+:10D63000B313E19AA5908842F97416E8C5215846BB
+:10D640003CCFDA24859A281CB3D7AAE739B7CDD8BE
+:10D65000455FFADF7C4205232CA04D71EDE8F8F31D
+:10D6600041FF51FC2D309148021D77C17675BF8571
+:10D670002482F0D4ECFADAD8131EFFC2F1789BD3DF
+:10D680007757AA4A7EE9517E2D24FEEBE1BB0BB908
+:10D690009E9D633C8470D43FF0C080D9D46EB8BCEA
+:10D6A000F4C101B353C10FC8FA91F512F2DFC20AF7
+:10D6B00012C9A6702D6C972283C10E7893D1478C26
+:10D6C0004FB6B07677723B650EC507E8FDD1BBA4B7
+:10D6D0006022DDC7CC31D12D18C80F3E2FA84FA630
+:10D6E000E56AD28AF3A9255184E37E4E3F8848013A
+:10D6F0003EFFF226A3DBE8EAAD3A00EAD8A1528C5D
+:10D70000CB7D4ABC483F6A4F10734A77FE007CFBD2
+:10D71000E2F053BD495D26DBE3CAF9804F5A8EC360
+:10D7200073DDDEAF8DBE1EF0FB44A73E090D9834BD
+:10D730009874B357DFE3F87FE2B6B96E58FF8F8273
+:10D74000FD96C1071809F292087F44C444C7B70C7C
+:10D75000272AFF04B58BB0DCF6F86B37ADCF226417
+:10D760009D3E807EFE593AFF5108497DE60CAC078C
+:10D77000BACE927D390ACA015F01EE5397327A3CE4
+:10D7800039AC6140430FFB5301FF3A291C91411E04
+:10D79000EC67FA3DB124A60FC4ADAF5F72F9967C79
+:10D7A000387A3413F8E63909FDE91B24D22C513CB0
+:10D7B000BB2859400F6C90DE3F0A7A63C34D1ED2DE
+:10D7C00044EB4BF64E5AF40AEE712D5E884FD4EEC0
+:10D7D0002DD3D55A71FECCCE4C68D82AD3FAF47B1F
+:10D7E0000A87C1FAA0F3BE67327DFF02A7B7DBCA82
+:10D7F000F8C1B52298B718FCA987FD8B5E81753DED
+:10D80000D8827EAB748AABC4147CB680FDE8228DCE
+:10D8100012B45BE594901EABAAC8B45F1621D7285A
+:10D82000C929EC79923E258534831F365DA1F628FF
+:10D830007BDF0CDF792289C1E59475F74C027B7898
+:10D84000182BA72C937CDB90F91F437CA51B492543
+:10D85000CC1BDE83FD4CC1F0EDC1FA10C29D3EB67B
+:10D86000A118E048EFC39E0E43240BC6392EF8A43E
+:10D87000DD2D839C5EC2F5ED923D65E929B4FFF193
+:10D880000B2605E4E77197B0FF2256B0FF48DF4250
+:10D89000D69EEBB525C563D381EF1D39EA7697F5A2
+:10D8A000BEE4E1A01F4EE8304EF399D5976CA7ED8A
+:10D8B000AE35B07968E97F96D3B5FE8A444271FBF4
+:10D8C000FDFA699FA35D5D7F4551BDBFB0DC444259
+:10D8D00071FBFD9AEAC3E3A15D2DE95805FC581BD5
+:10D8E0004E20A1B8F571ADA5E7EF8A75517F454788
+:10D8F00082C391EDB3C02F795C1F5B3507F8F0A0B0
+:10D9000084FEA37ABA8F0EC6C375259504537B8215
+:10D91000334DFD9ECE4755DEF705B62323A349F0D0
+:10D920009D4BB668929DCF0FDA097D77392407F5B4
+:10D9300043312EC8F41EF875ACCCAE9D04F455628C
+:10D94000499313BBC615F5305E4ADC3C2F4D33902E
+:10D9500008D22586DF05BC05FB13B2B1FD63830742
+:10D96000F47FFB21C49BE09778FC05E3E3444D1D65
+:10D970001199CA8A7C876D4DD100CA7A87855C4827
+:10D9800059037EC9349DAC921309259D7203C5D4F9
+:10D990001310B5423993BAA6624C7C99B5EFEAEF01
+:10D9A00098007ECF9222D6BFC8E1FCAF157DE17D05
+:10D9B0002B93BB4A2CC79F18573669CA565A1E1C50
+:10D9C00057B669EA1D9A7A97A69CC5DA5F488CE437
+:10D9D000E8BC54DF3BDC13142A2F2FB82333E80EA6
+:10D9E00096AC6DCA9C5041E5586D09D3C775ED9250
+:10D9F000177D751C7F755E66275ABD51C3AC22C06A
+:10DA000043C751902B35FB249B44D78135BC2782DB
+:10DA100065E8E789EB1796B05F4DF87DECD7EBF83A
+:10DA20008532AEF33585A758BBF087A8F757355731
+:10DA3000613C5DC48B75C4EFCB94BAE2C542BE5E57
+:10DA400072FB5E96195FDBE2F74FF5306E9C9F46E6
+:10DA5000B47F6770FB1FC0AC4858F27123D8AF7F0A
+:10DA6000AAFD7004D873EF40935120AF4303E0BB8D
+:10DA70001B496000E8C9EFD7F63B24D376EFE9A352
+:10DA80009B2126769FA318F1F75E62345BA2326673
+:10DA900069DBB5ACEC8C6E067CFEB66D0C2B674773
+:10DAA000B3655A5EE698C7CAFDA29BA1BCBD6DF2E4
+:10DAB0000485E2FBBDC1D16C1DED9F1F9C32A1828C
+:10DAC000D63F6DEB793DD73A981C11F0FD57BEAFAC
+:10DAD000DA01F3A961FA6733B5374D545ECE587059
+:10DAE0006EF7D3140F337E988072ECE90B53263017
+:10DAF0007B3CE8574AC1DFCAFE503FA29C57D03E4C
+:10DB000071834E4CE9A247624E8707F5C7C0863D38
+:10DB10006067A4CF2842FDE14DF5FD0EBE2B9EF7B8
+:10DB200067B0E7EF1C3626B77532C69FD31F4C444B
+:10DB30007BEC51339B0F5D37485F2BA7C70A07F378
+:10DB40004BAF70303FEAF4D47138CEDB926F8389EB
+:10DB5000E2FD6D3D099A41CECEB7A0FD7CD7562A95
+:10DB60003792C18FCFE06E7BCC1D82F8F95D12F148
+:10DB7000835C11F2A3CDEE73A7C4ED43DA8A69D9B1
+:10DB8000DAB5EF6C9BE4735B1CF04C9321CE22E47E
+:10DB9000525B1EEB27F4517A13FB4EFAA303B6C176
+:10DBA0003C1214E62F9A33AD605B23DA03937FE7D0
+:10DBB000007BD9E77383DFE1F4FC7C19FC48823EEB
+:10DBC000E7F37D9BA0FE4EEE87177412F4FC1D9FB9
+:10DBD000F72C1DB527E87C8F3B03381EB52F8670C8
+:10DBE0007F15DA17BF03DD1E875FA24447C0FBFF26
+:10DBF0008FF07408E8FEAFE2A976299517F255C8B0
+:10DC00000B8EBF7552449FCEE405EE9FE13DE89D2B
+:10DC1000CDA9813FC0F8E2FB331EAC457B52C095D5
+:10DC200070FF0B957790EEEB4C6BEFFD19E81567E5
+:10DC3000977A85DF917FE7BDB74D186778CF10469B
+:10DC4000B9F91EDDFF34827CE171F2D21F2E3C0E49
+:10DC5000FB3F31EE38A70EC75B2DF9DC30BFD59402
+:10DC6000EE26807F9201ED7FA157DBECA10D90A7FE
+:10DC7000D0765B16E6295C262C1F24B83401DB5DC8
+:10DC80002B9F22E0C78C8DB2619C9AF209D6B74DCA
+:10DC90002FC07C11CA0F4133D4537E82BCBAB66206
+:10DCA0003A21186FFA40AC87FD31EE6BA79B70BC30
+:10DCB0001EF884F985FBB37C88B63CCE87F3F391DC
+:10DCC0000FD39A98FF9128BE2193E2F47C9E93F99A
+:10DCD0007D124AA2CFFD2FE0F9B566B46741C76255
+:10DCE0000CA7351DC7A3F4B738991F00F96CF623AC
+:10DCF000893CFFCC5B0A787D2891F1E526338B2F98
+:10DD00006DA2F633CA45CEBF22EF2DC0EDBC68B57B
+:10DD10009C04F682CBD9E95FF0C17E1FFDDBB47EA7
+:10DD200066547A1FF66B3383BA8811F65F2DE37C55
+:10DD3000D1B8FD0BFC417CEE1E2E57C97A827EBF06
+:10DD40007BA05F128C6F498278E43DD01FFCABCB87
+:10DD5000C6A9E26E039D6C7D0BF8B4727FA093C9D7
+:10DD6000490AB72FFE3B627CED7874FF39C8E9445D
+:10DD70003C4792611FD1A8433A6AE18CAE677EEAC4
+:10DD8000E8FA5CE43B315E6F70FE5917BB57A27A2C
+:10DD900070EE58B62F17FB9E397CDF4C96A9F775AD
+:10DDA000E057E92CEBBA97B5FB4488A7ABDB33BB54
+:10DDB00025A12866C0388B4752C12FF0D51B1E26DF
+:10DDC0007D47BC09BDF7A499CAD314D87E4BC8B708
+:10DDD000EB1F48403DE6308406005FDDEDF460BB9C
+:10DDE0008D90D7827A95ED973F3D2EFC1CEA7D728F
+:10DDF000BD25B605F0556F61EBE8D2C1445C07A4C0
+:10DE00006F7406E4855D3E6024C0BF7552B400D6D1
+:10DE1000F525C95785ED1A133CB09E3E903B10DFA7
+:10DE2000F580410A577DF0EF988F54BF4FBD6FBE0C
+:10DE300044FFABA6FC7E498E96C238421EC0FA470C
+:10DE4000BBA89AC569EA6412847DD5B5F2CCF9A85D
+:10DE5000FFA767906DF8FEFD02D84709394FDB1D1B
+:10DE6000915218DBC07AA9E1F8AB934F61BB1AC895
+:10DE70002B023CC2FE0AFC615019E7C7AD5B7B1E5A
+:10DE8000F39AEAF6AAE95CD3C507D2D712F48BE37A
+:10DE90000B5CC741A41BDAD9B0EE2B589C39919783
+:10DEA000132A3B30CFA99EFB3B9C87A3E3419E24D2
+:10DEB0009684C94CFAAC3FCBEC8CD1ED5B5F867D90
+:10DEC000B4BDB2231BD8BF9EFB03059D059CA3DAFE
+:10DED0001F43FF86B04FE2F6990326ABFC0C2BB034
+:10DEE0001FEC5BE17B5178E506F233BDB68EEBB5F6
+:10DEF00004D80083FE6BED8FFA0FF413C825B1EF41
+:10DF0000053905F2E13367F94F418EAD4D2BDFC680
+:10DF1000E419E52FB0E761B334AA773F9EC08F685C
+:10DF200007FBDF6FF2D3FD92F3ABC3C0E52E617E3A
+:10DF3000B9C5AF39855F0EE36F8B254F3AF0EB190A
+:10DF40005D00FD6FF34810FD42F3C1EF459F357C46
+:10DF50009DCFE5FEA4B9DC8F047EDDF83821F857AB
+:10DF6000E3CB0B08E35FB2C3D8953F037E9F0A1251
+:10DF700049A4E3D5825F0A9E6175BF3A12637CBFF4
+:10DF8000EF6BA32A0ED9C6E67D0FA7BFBD22A4035F
+:10DF9000F9B0C1CCFC51426E8C5EC6FC56C9C37C44
+:10DFA000792B81CF5FD3A33FE37F73BA093CDDE6D2
+:10DFB0002CDF05F8B7C03E0DDAAD34A2BC3C4DF500
+:10DFC000F01EEE47990CFBCFE5810190FF4D145BED
+:10DFD0004EFCFE543CD71C305703FFFC89EB31F15B
+:10DFE000FE31A79EF9E15730FE8D3526A0BD4DC507
+:10DFF000C610E0AFD27CA10FC910F06BBDAF677E39
+:10E00000E0BADBAD01182F2A3339738ECBB3734ED0
+:10E01000967F27CA9DFB3BCE3F22BE077E9E78FFA0
+:10E02000FAC79DED1FE37624C1F9AE9BCFF3B73B52
+:10E03000F95846799450E447B97BAD5C8EF228F6E6
+:10E0400091D50378A93C5F331FE6F1C9340B8138C1
+:10E05000DB6CEEEF95D2EC0887F0EF7E5BFCAB72E9
+:10E06000CD009493A23DC472A1BFD64F7C80CBB1AA
+:10E070000384C11B6C3632BF3C87FFC0D98121E0CD
+:10E08000636AD70641CEC5F69899BEA37628C8D74D
+:10E09000037BFB87603EEFEB99BD10A4F297F50F71
+:10E0A0006C003FC8815F3ABD90D753BFE0DC10B031
+:10E0B0001F0F9CFDD9AF7E0BEF0F1ABDB0DF3BC029
+:10E0C000FDF235864801DACB3C9FB1262952007E0D
+:10E0D0009F1739BD6A2CB44CDF579802D96923BA0F
+:10E0E000E267D00FDE9F0A31BBFC14617C105CCB71
+:10E0F000E29C14BF6E8023B63A1DE36F302FA0C39D
+:10E1000007070723DCEBF4BCFDC3CC7E3BC5CBA7E4
+:10E11000F617637EDF65BF01F371EB1F65F6E22C36
+:10E12000D9B36529C8CA9712D0CF38A7ED04C64322
+:10E13000EA1F993711EAEB172CFB1EF9863801E824
+:10E140009578FFF62512CBC17D70757E3842BF7B76
+:10E15000A97D809785FB5C185CAAE3799FA7297E3F
+:10E1600001EED8413DE2FF6AC747876129D36FE8D6
+:10E170000F8F8FC7A03E50C767BEAD7C491F2D785B
+:10E18000807E3F9812B835CDC9C41DD0BDFE25375D
+:10E19000CABB0F1EFE2207ED8956164F38ADF7CDCC
+:10E1A000807562AF881866C6D95FF3D2F8BEC3C85F
+:10E1B000ED462A07E3D7BDA82F2D57AF33F19C9B1F
+:10E1C000C6ECC9441EFFEF5E2FF25EA718417F32F6
+:10E1D00097128CEBC17173795C6EF4D9D821C8A306
+:10E1E000AA091763DC2F775904D725C57704ECFFFC
+:10E1F000D31B12993CA1D38471E68E2468B7CED587
+:10E20000B17C86B9466A07333D8EEDCF6C48473CFA
+:10E2100094AE60F65FEC3909E5A2884F5611D6FF3F
+:10E2200085E6F7833ADABE6A87544C452BA96A2EF5
+:10E23000C37C87059BF290FEA3B9FC9D65F4156C29
+:10E24000007E7B2111F98D7E0FEDED1AC8E91A864B
+:10E2500072C900FAB07A8744D690F878AA860F423D
+:10E26000EA78CCE83093DFA037489C9D26F410E88C
+:10E270000BA2B11FD57C11E4712A469FC701AF23C1
+:10E28000BAE43F62EC1BF420B5A3DB601D9796B3A4
+:10E29000F516DB23219E6B49038B1F713DD4090FBB
+:10E2A000D76367744C6FCE353E86CF9D697908C7BA
+:10E2B0000288B360DC206600B9D81B5FECEC852FC8
+:10E2C000043FFC8CCFA3E62C895C47BF57B38C443A
+:10E2D0006A87B067E210D4CB4C3F9B987E86A7E557
+:10E2E0002AF4B4563F6BF5B1560FA71B98BE157CA8
+:10E2F00010EF97077B64F4B2908EF95FB36C90C710
+:10E3000027E8323DD57730C3D9656FD59F34993C26
+:10E3100043A1EC27F956F02B95556681DF9ACA6F19
+:10E32000587709144F5BE9FBCDDC2E1F91C5E6EF52
+:10E33000E2F93A7AC54F8AAD40A70EDC47C79C0484
+:10E34000F7B502BF9B1369BF61D08FADC7CEFE2664
+:10E35000D26C89EB5F7EC08CFAE4F3FD89985F4252
+:10E36000F543AE9D8E97F60EB5CF69F9D28144D4B0
+:10E37000EF97B8BC77087F055985F4FD13A7739014
+:10E38000946782DF9748133241440ABBB1D6DE9BC3
+:10E390009F9ED7E775DCCEF8CC887AF6737BF43E87
+:10E3A000285378301FF80F5C2ED4EF1D5BFC20E45F
+:10E3B00001F8AD5E86D54031D80D46DD92DBC11F38
+:10E3C000345EB72CF6009D476DB615F38C2B72DFCB
+:10E3D000FDE3745AFE68AF9E1881EE4F4F498E40A0
+:10E3E00037C5E7EA493FCF0FE955E7D816EE509712
+:10E3F0006BC3EA723D893BE74651B0F4DDE2EB8F37
+:10E40000C4F1C95769898E338308C8142FE44913AE
+:10E41000DDDDC9811EE4A5787EB1DC7BFD113DE622
+:10E4200099E9D3591E8D01EC9A99C00F3DF46B4FB9
+:10E4300063768DD1D87016F2D58D2F1ABD8DB4D7D5
+:10E4400089B44012F4AF936347819EC6DC0B43400E
+:10E450000F96E7FE03E3679FFF8878013F9F9BCB02
+:10E46000D0BEF97C83D903FBB2B61C2BF357BC2476
+:10E47000852466BF4F1C510AF1529C03A95F7FD3CC
+:10E4800047EC700531C9485FBA7B71819CF1E17E30
+:10E49000EACC248B6D05ED57BD9EE9DB1AD29104C1
+:10E4A00072604A3AA79F6E97C144FF99D7EC1BD080
+:10E4B00048E15DE8B7E0B91AE54BC50FFCF5100C73
+:10E4C0001967FF0F4C67F2A0D6143594C1F7FF31DE
+:10E4D000BBD299DFE5DF32E8997F4BD9571CC9A43D
+:10E4E0005DE72D9D85FB9CCEF8F30696CF34EF813A
+:10E4F0002A7CFFF20623CEEFCC4109F9FCCC66362C
+:10E50000FF79EBCD1EC8BBBEC1CEF6B3F368BF9E8C
+:10E51000E77FE34730AF0F37DDEF05FFFC87847DF2
+:10E520002768637EA80F6D2C4E0E6D619C0FF7F669
+:10E53000413BA67AFDFC899867B659E7053B821CEA
+:10E540004C44FFCEBCCDF7FE7614F88F26DF59027F
+:10E5500078B8C1BE240DFC25B49D3FC4EC6296BFC3
+:10E560009B32F2195887377C39B6E306B09736D319
+:10E570007592C7F2E3C14E3FB2F946B44BE74DB2D4
+:10E58000D8615E9E4D4F8F07FDF1E1A40C19E7B3F2
+:10E590005B2236C0837D691ABC9F2729FE9EF8E95D
+:10E5A000A334E6672BCBB57A23D0EF0F3AE413BA46
+:10E5B000AE6E07FD59BB598F76EF91C96FFF71BAE7
+:10E5C000A36B5DCDD3B5DE3E3ACEEEA9DF748BE012
+:10E5D00013122985FD14C389767D19739715003CA4
+:10E5E000DA75366F4543018B577DB7F54636B1F581
+:10E5F00056932E91AFE5EFB4DE7E90EEBCFAF54671
+:10E60000B25254FBA8EE722D88ED84BFDFE425BE24
+:10E61000A7AD18D7F549E0974B57B07E533ADBCFFB
+:10E62000287F5DBCE3755817E9819500472EF115E9
+:10E63000031F7962B672382B64E5761CD9C4EC6688
+:10E64000B0EF81DEEB9CE49935717E87F5E9EC3C17
+:10E650001B5DFF8FC03897DEFAC751A04F5DCE8596
+:10E66000212CDEF919C607ADED2CAE6CF5C630DEF7
+:10E67000AE77F891FF845CAFF732BDA39DD79FD3EF
+:10E68000D9F98B7A470CC739E062EB50F8DB372EAB
+:10E69000B5A09F74A32364667E852001BD3471A458
+:10E6A0008EC5C5B89D750BF73F9A4A5E26100F239D
+:10E6B0006358DED7EB252F2BA9B4FCDB91E3BC78A4
+:10E6C000DEAEE4A9967C98F7183DAFEF138479FF8E
+:10E6D000CE5786F58B5D3A0FACEB89252C7F915494
+:10E6E00027A1BFE4F5920F1CB3E3E0F71393C74AE9
+:10E6F000F96432DDE4C4E7DB7D6F8CD9638DE3AF71
+:10E700004F5AA54A66EF7A92A70E66FE10D4C3252B
+:10E710006A7C2C7619F0BB6BD3CAF6039E6FB89E49
+:10E72000D1E3DC6E6308E4DF397E7E458BBF63E9AD
+:10E73000DCCF7A77A12A3EEF308473403F9E97D496
+:10E74000FD16B4E8303E3EBF452221FABD733B5F63
+:10E75000C80139FED1D32FE4CC8C8347DB4F3CDF9B
+:10E760004857FB01B57EDDDEFCB9A2DDE5F524608E
+:10E77000EAD3D5FE72F5DFD09F3BB39DFB837DBE10
+:10E78000BE0ED807F1F6DAF1FECEF943DA27A1BFC3
+:10E7900043F8334F1D7B0A22279DF433B7E7C9F1B5
+:10E7A000F98AE2399AD36D0AD08D4EC5DCC2CABD52
+:10E7B000D1ABB7F5F8643A8343D0ED544B9F64C0B6
+:10E7C000A3A1CEAA10768EAC10ECF4CDC4E285F5F0
+:10E7D00064C87059417E8973F85F98D9D361A14F9D
+:10E7E0006AAF65671462BFFB653FE6C57D21B7E28E
+:10E7F00039C2FB750D986FFD15FF5E96CDBF672E74
+:10E80000EE4FC2987F4D5AD4F84D6B62FA2356658D
+:10E81000403D25F07CEDCCFB709FDA037DD603DF15
+:10E82000648C64EFAE71E571BF4614E304E691C4F5
+:10E8300006FBF9A651418447D0A79E352752BB84D9
+:10E840007632E4B524A4603C34C89FC49A423AE3CB
+:10E8500003097C5F4B34F1002AB682D04EC00962B6
+:10E860000CF2631EB5875B0B4A309E8AF6278C0B31
+:10E87000EF671629E84F87768661DFCE6F9D7CC9EA
+:10E88000F30C278AF7D5961EE30F13E1BC0E6D9F9C
+:10E890004DF520D87FC4AB579DD7D944ED66D88FAE
+:10E8A00089F8AE4E0E17BB701FD21105FF88A1D498
+:10E8B000E401BD9AA00B1702DDB4F15EDA2E8FE5FC
+:10E8C0001964D941AF88F338754BC7FA21DFBDD33E
+:10E8D000CE38C8F647750F94E1FBB1EDCC7F5EDF13
+:10E8E00062C4F384F5FB248C57D5F90D2113FA315A
+:10E8F0003C8D40AF20B5C360DFD86667F9516D37F6
+:10E90000D9BC4112EFBF8E6E7910FDD7568CD3FD66
+:10E91000B3F1CBCB89140143E3E253C926A647B830
+:10E920007F3B8DF393A0BF58CF22DE9958E4CF03ED
+:10E930008BFBD7EB66FFC6E2FC2E7921D73E0C7924
+:10E940001FBDE7851CBD05F2464C60CDF37A008BF8
+:10E95000EACDCEF375660FC6B53AEBE15E04D33E61
+:10E9600089F7FFC12DE3FA62FE283F5F77DD5AC8C1
+:10E97000637ED44C54DF8B874FD18CAFA7E35B3DD4
+:10E98000A2FD3D378F5330BECBCB2FFDD847E17F63
+:10E9900054AF1E0F59509C0734757DAF3233E1E1FF
+:10E9A000B563BAF437D5E7CB5DCE2E3DFED0DB1391
+:10E9B0005B877A607D7D8AF9B8421FD73B589E8875
+:10E9C000566EAD7149C2FE1D0F2A76D5B42ABC47DA
+:10E9D000A033BEDB3EC907F72988F86EFD323FE65B
+:10E9E000E582FE77A1FEBF70E61001FBF21CDAFFA4
+:10E9F000F55714E60FA2768444F9D0D45E867E4F94
+:10EA0000483705BD29E8BF80EB25B0D581BFEB377E
+:10EA1000DDF1B40EEC6597EF491C97EF03B5F08676
+:10EA20005DCC5EAF2F2CDF00F2806C9708E8ED35EF
+:10EA3000859FA09D51B77FDC88F8BCF2F9FB9E60F2
+:10EA400079C93BF43DCE3FECD2A17CABDBFF1CFA95
+:10EA500033CF85D871966A25B47A34F855AA65B053
+:10EA6000B44849A86A3AEAFF69741EE03704BD0356
+:10EA700076CA8E2941C873AFA7FF01CA36FAE7A24A
+:10EA8000BDBF719AC90AF19AFAC2998B703DD82C10
+:10EA90003E98BF16CECEF8F00316F437AED9A7AF26
+:10EAA00004BBA994DA49BFA2F066A74CA8F452B9F6
+:10EAB00094A9DB53FC032BC4D57BD6C35333981ED8
+:10EAC0006E96FCC15B4B300F92C4E7E9E4EE63F64F
+:10EAD000D8AB2E66BF89F7AF42E223C5E79860C77F
+:10EAE00058E0B997946802D8C5F5C4F731EC73893A
+:10EAF000DFEA8171E02606B0B31CCB3DE8CF3539A3
+:10EB0000A23F1E8A769382FB0CB18FB8B49FF9BFE7
+:10EB100046B9036F021D4B75D1C76F05BCFD989DAB
+:10EB2000F3250A93373953ACC3C05F6576441FAFF2
+:10EB3000F4607E0DFA1F92AF6B463ABCE42036C0FB
+:10EB4000CFD8609522C5E9192137C6769EA771A056
+:10EB50009FB49C8B977E945A674CC8A2CD5FA776D2
+:10EB6000D905C7FE31558197C25E904D01DCCF5467
+:10EB70004CA3FB43E0CB55B1A332F8E51D1D682F34
+:10EB8000D68625FC4E6DE12F31FF6D21CFB3EACC47
+:10EB90007752A298FF75C995C0F56333E34BD281D4
+:10EBA000FB5FB28BE19FEA4DCC0BEBB2DB1BB19D5F
+:10EBB00018CFC0E309B5DC5F431185F57F7589780F
+:10EBC000C20AEEAF12796CECBB44F194C6FB17D6C7
+:10EBD0004DA29A04E1F22401BCBF30FB65376D7F82
+:10EBE000AA5A66FEEC9684101C0E5D2775F8C0EFDD
+:10EBF000182CEEF91C4CBA5BE279B2B1F1E8EFDF08
+:10EC0000DF5B9E2CCB8BDD306220E69597ECFB78AA
+:10EC10003CF007A924B81EA9BCB8AA3CD92C375B84
+:10EC200047FFCFE4C97A25DF36FA1CECB6ABF364B4
+:10EC3000BD8C5E227EA9CD8FBDE48E282C9F2DBA7F
+:10EC4000E569D0BBFB8C98273771DFAB27C17F39D3
+:10EC5000D144C218CFD5D80FAFA54E29053A5DBE15
+:10EC60007866CB4A02F9D5CF7B59DE9DDA1EE8CD16
+:10EC7000FEC79846DC3EB1D2FDEFB5FF85BCAEE7DE
+:10EC8000FBA9F352EC910298DF419DADA77331B718
+:10EC900089EFF796E7D1DE739E8738775519CD5304
+:10ECA000C5A7EEE91CEFBBC5BB66820FBA87789794
+:10ECB000C2F3B71489890E926D50C5BB147B416FA6
+:10ECC000F1AE08D63FD71FEB1FEA16EF627905CDEC
+:10ECD00007D33D60DFD73863CF3CE381F10C384E7A
+:10ECE000F3FE8410E4B93773FCD75C7DBCEB41774D
+:10ECF0000FF1AEADDC7EFBA0508E18285EB7120679
+:10ED00007FB05DC4BD64DCC7C61ECE16F063FDE5F2
+:10ED10008707A1BF68968867BDC4FC68B378DCEA42
+:10ED200083C90598E7D51B9E67B5A8E3020F039E2C
+:10ED30009DE8E7437FFC7DFF3109FD5373C18FDF01
+:10ED4000A7EB1C04E1FE3C4F0B3BDFEED921853CD9
+:10ED50002CAE6292D136B4C9F07E2115A31B41F4CA
+:10ED60000629D75C435F4B146BB4DED34CCBD4E89D
+:10ED700057562B41176DB7F56402FACF1E72781003
+:10ED8000DE879A597C39B8560AF563E3E2BD61C162
+:10ED900066D907E3EC7633BFD32B6EA6FF3C9AFB14
+:10EDA000089AF53C4ECCBFD748E4083C65893D1F26
+:10EDB000B229953DD90F62BC667D83A90CF09DCD2B
+:10EDC000EE27F9DCE09B86FEE59402BC87A839B10A
+:10EDD000A1A592D5E39AFDDC1CF363FD750A3348C7
+:10EDE000892705E07DCACDEC1B2D9EE7B4AACBDABE
+:10EDF000F88EF6DCD52C12E8EFEED3FD5CD2536E24
+:10EE0000A6FF3E5F93C7E9E2C57849B3DEF3461E2D
+:10EE1000F0FB6A76CF506316C39B9CCD9EF9F60A31
+:10EE2000BC0F8ED8B91D4718FCF9D73924580FCD1F
+:10EE300076C6B7FF2ADC5A785F771730FCDAD97AC2
+:10EE40006D5E2D8518BE18DC57EB1739FF6F968B5A
+:10EE50001F48DE672279D80FE542F0613DAEBB5313
+:10EE60002494C9F2266D283767F27DEE675CCF6D7A
+:10EE7000ACCE4F8238E8ACB3ABF0BEA0B153AC0817
+:10EE80007FDD4B66DCC7D52E8BE6003F6BF108D0EB
+:10EE90002A429ED2FA990EC2EE996951C7F5B4F191
+:10EEA000DA608A5F8678505D79B400E2464FC81F09
+:10EEB000EC7995C935D4AB75CB62CF809F796A4A1E
+:10EEC000C09C41F173E181B7C74B1EEC8EF2EDF2AD
+:10EED000C1FE78BE7066B3FABC1659AB8E1B929613
+:10EEE00014762EAD4DFD1ECE27A9FA758B2332BBAD
+:10EEF000669D213000ECCE1BAE67791217E7CB047C
+:10EF0000E879D14C787C5EC8596F41BC1E28E07608
+:10EF10006F77BAD27680679E172ADAD7025D293DCD
+:10EF20006B385D2F3E774D01D0F5C29E6B0A80AEE7
+:10EF3000EBF4AD3E58179F390303011FA7C7F9D162
+:10EF40002E1479B057CB6FA332FE67F5F078819716
+:10EF5000EFA887E12FDE5FF2D23F58BE6AB09D9DD9
+:10EF60004FEDF2D39DC37BB62E5F912590C3BD8D2F
+:10EF70007792EF935C261204FBABB43C8AFD4AFF08
+:10EF80002613B00385FDAB857F3AC7DF820CDF4BCC
+:10EF90002EC023F7EB56F3B14DA14F999DBD5D42B5
+:10EFA000BFADC9134C1A8DFBAA39C37528577E858E
+:10EFB000E72048BB6483FDC9FCED8D587F69DF2CD9
+:10EFC000AC974D9108ECC36A693D94578D51E73574
+:10EFD000EBF71647E2F7BD148E03B09F4970C40CDF
+:10EFE000C09F7560575310EB14E6DFAE7310F4AB9F
+:10EFF00094EC53EF1345DC76A39FDDE3B2B15DC221
+:10F00000FB9CD20C81BC2CA0AB267E7B7F866F1D27
+:10F01000AC571147BFCDE97B2083E597E5009E8281
+:10F02000190C9F51BD38AFA73E4F78ECD0ED680763
+:10F03000FD85F8937BCE370BA9E2EB73F979CFB955
+:10F04000FCBC27C8E788463EC7976BE2F2CD223D5D
+:10F05000E50DC4E59BC5F78BCF378BA8E41A5BFFA2
+:10F06000E9BAC518D7AEA77CBE7458171FD610FED4
+:10F07000B73EF6019E6BD961447F5A0DCF33ADAFD9
+:10F080003E85FB947A3827C3D623CBC7E6F71CD43A
+:10F09000D0FD1FE6DB86D5F9A8BB7B951BFF77FC6F
+:10F0A000E4FB843CE0EB51CC4BCCA3A65D62EB4788
+:10F0B00003A776DFABF5778B7DEBD5CAA5E3FFC35E
+:10F0C00072E9AD7F935CEA1637E81B4BF2FE1BE258
+:10F0D000061F795AD3C095D822317E1DAFB3FA5896
+:10F0E0005C52C7F216B4F15ACF788C430A3FADE9AF
+:10F0F000795D68451EB6C7386CEDC144CC23A8F6CF
+:10F1000054A39DAD8D4F2E207BC60309FE428EE396
+:10F1100079AC7F351F806476E603E47DC77C0063AD
+:10F12000E677884FBE6CFD343510C727E545D460BF
+:10F130002FEA3D5FCB99C9F82E81E78D989420B1D5
+:10F14000C7F5EFAD5F7626CB037B99E7193D9A981B
+:10F1500080E7F65D0676FEC025B37CA8332E7F6E71
+:10F16000E608D0038C8E3FD97F0781FCC29FE8C39D
+:10F17000788E3E586BF582FE127E2631FE83DCCF00
+:10F1800072B5EBA724F3DFBB7EBE4D6E5C2FBE775E
+:10F19000B5F1B5F5140771EB4ABB0E7AEBD79B5C62
+:10F1A000B935D33F2113E5966F08C629AE521E2507
+:10F1B0009450790DFA79AFD103FB05133F2743D65D
+:10F1C000BA55FBED598F66A3DEBA6866FB07719EE0
+:10F1D00047CC7F66AFF8FEE7ECBBE34EFF6C98CF01
+:10F1E000E9321F9E07782891E995D84E9617A43DDD
+:10F1F000D7A2D527E25C86F8DE7DFF667EF8AEF208
+:10F20000B4497CFF5F94A754BFA27FA5D7386CB7E1
+:10F21000FE419E9FD9E1E3F1293CE720E0AAEF609F
+:10F22000F9748F674A2A7FF37D5CFE9FCCF4B501A9
+:10F230001D2EBC653241DCB3A484C9CF3ABF15E3AF
+:10F24000067561964753B78CE03E5F9C5FCD4B0FD0
+:10F250006C0139F5D0DB56BC77B46EDFD6967CCC2A
+:10F260002F08A05D77E92DF6FE445A601B8C5FBF26
+:10F270002CAA8A4F947EFDE9AACA128417F7E90ED8
+:10F28000A3FA5CD0914CB6FF16CF439DF8A5FB12B4
+:10F29000DAEF4235CBDFAE77F86C659857C0FCDF0C
+:10F2A000099E0EF45BD7ED452541309914EA1FCC39
+:10F2B00042BEA9DB5B568CF70884CDC578FFCC3BFA
+:10F2C00056DC5F5D782023A463FEF2FD006F624987
+:10F2D000E826B02F73E977C0FF7D61CF4DC5E80FF9
+:10F2E000D4AC3BB1DE3ACF83DE650A35495DEB71C4
+:10F2F0009D9EE947A1D77682318B79153C2FB07D51
+:10F30000129963ED2A5B1DEA7CC90519E376023C7C
+:10F310003B33591E8988A3E799E8EE33BF3B1FE6CC
+:10F32000F138FA249EFF4082A6AEBC87FC6F8FA303
+:10F330000BF84459C4D113AE30FB36DF6640BE48EB
+:10F340006C61728350BE00FB7A4CAC632C9CC3EAA8
+:10F35000DB161903F84A06F463FE69F4C743215E1D
+:10F3600091AA8C8178C596A5C30E9B1CE03FEAB894
+:10F370000E48E369B595C3D6322FDD7F06F59ED2E0
+:10F380005008FC5FFE073DCB535C9D80FABE2DA765
+:10F3900006F3142FBD6D549DBFD13E8364850BFCD5
+:10F3A00044F92DBFC77841E25EA9C7FCD37E60F463
+:10F3B0008F60EDC1EF94D8D2111C097E9487257619
+:10F3C0007723855E72C1FE5F91C1EE98B58F9DE394
+:10F3D0009ED56A2F37A13C9558BC658C03E5A4B235
+:10F3E000FA6619F6674A23C17BD2B2B2D839817E58
+:10F3F0006D3619E8FEEB2F753DC6D112B2985E85C9
+:10F40000BC374057AD31761442FD22FE27F2DDC4F1
+:10F410007EA853BEF2FBC4853ED2DAB1DDEC57AE16
+:10F420008F3AED780D1FF7D64FF0B7E0E75FEB09A5
+:10F43000DA61BF964C78BE4BF075B3C8DFFF92F926
+:10F440007173793ECDA9357F1FC2EE0F14F1931071
+:10F45000CB83D247576522BEA2D70761DE7BED7210
+:10F460005D11FABFEA709CD5ECBEB3DC963E2B462C
+:10F4700096C0D3460005A70E2CCC857519A47CD068
+:10F48000AF073E3897C9F29694D5094837E531BCA5
+:10F49000D99928F634A49BF204A3CF69CEE7227E43
+:10F4A0002BFC94273303A3B39C71E7B2965AD8B9C7
+:10F4B0002C7EDE3771E9DBBBE1BCD316EE2F3EFCC0
+:10F4C000D220FCDD85CF572B12F88D3EB757E5C211
+:10F4D0007E6F1CA76BA2D2416CD678FE3C8CF9B231
+:10F4E000F90759DE9FC2EF4F52563BB6023EBDA907
+:10F4F00001CC0BBEAE39823F59F092ED34C6E5A87F
+:10F500005D84E79FCFED97845DA4D28762BFA6DDBF
+:10F51000874DCFFAEFB5936667A9F71557BDBF22A0
+:10F52000EA7D66677BB16FD4EE2334FD7BB37F88C1
+:10F530002FA8CA8BB99FE7450BFD9EC165A3C8974D
+:10F54000E93CBF4C42663807910CB9AF4CAF63DE63
+:10F55000D07AC9E2053B499B2FD499C7431AFAB325
+:10F560003C9286A1EC5E8A866BE029F289CC904FB2
+:10F57000129FB79AC8F281CC904F42DF37F57ADEFE
+:10F58000D9D308DF6FFB914D9C77667EF64AC2E3C4
+:10F590000CDBF03C74ECB62C3C5F33B692F9EF52C6
+:10F5A000FC0619F8F2F9AF743E90BB31BA6EC1BED9
+:10F5B0004AE9EB7383BD65A6F590A7D279DEB98AD7
+:10F5C000F478DE59E43389F86E46FF7512E89FCE71
+:10F5D0003C93FAAE73D0F0DDB6451EF40F77E63DEE
+:10F5E0007D9FE03CCB859C31A9E997E463ED92A631
+:10F5F00019D0CE4893033B318EB7B1C38CFE8AAC91
+:10F600007CE4ABA69121BC3F37A5A815FDAF2B53D9
+:10F610007DBBB24674F18F808FAC67F3BF0CE7BC43
+:10F62000A4AEEF5E9EFFB71CB0A7CADB8D8C0F3572
+:10F63000706CECBC6F857E873E0F6531FA7B35F6CA
+:10F64000AD781E12FCCEE5B0F87E6FF314FCF86DB9
+:10F6500076BB96BF82E59C3EEF99432C5F49CD5F18
+:10F660008797570E3F4D65C991E57E7C5E364B61AD
+:10F670001DE4159963334002FE38BBFE7B700FC753
+:10F68000E5C4580EDCE3F178CE6DB7C23D1D979D01
+:10F69000B1F7A0FC4CF643ACDC2FB605EEF568CF15
+:10F6A0004E6465F85606216F6D926E0D5AF11EADCF
+:10F6B000551DA09F4A34F9299AFB07208F12EF4B62
+:10F6C000B0327AA6F33C5652C1ED77882CD17293B2
+:10F6D000BBD80BF90756E2D9DB01F55946764F0145
+:10F6E0006179534DFDF2589E03E77792C5FDCF2413
+:10F6F0001A04FE6DCAB363FF4E79BDD7C8E34EEC62
+:10F70000FB279E63E7CB447E2E21B66CB07BAC1EFC
+:10F71000A22A8BFB3B8862CB86F3FA4DC2AFC7CBE4
+:10F72000EF5A027FCF8AB38B4E8CBBBF087FFFE3BB
+:10F73000F907FBC27C6F34A8EF4F16CF65394CFE3A
+:10F740005EE6F70CB659024A362D9F4C98311EAE34
+:10F750006E9D965A66B0A39DB65307F2C8C9F9C20A
+:10F760003E95C167AFF04BF0BB1BE29E3F67404147
+:10F770007F0009B4E9407F3A4FFB310FB0C614CB8C
+:10F7800051F2C1AB1FB065431CB0EAFDFB300E98CF
+:10F7900071E23DC8DB38A16F1D9B04FA228FDF03A5
+:10F7A00041377E415A3E9A998BFBBECE7B41FB4945
+:10F7B000281F264E65E7562790B082FE171B3B4751
+:10F7C00035BE24CFDB44BF3791E77D8C3FE94F0244
+:10F7D0003FC0F83BA20A8BB7C494F83C0BF1242E2F
+:10F7E000BD277E1DDCE4892B13B84F585DBEC5AB29
+:10F7F0002EDF3AF2CBFEF1E564E21B04F37C518A82
+:10F80000E239E4E0286263F362F9843FE3FBB64146
+:10F810002E62CA857C478714847DC1A01732308E42
+:10F82000F2C24882E5B41DA66DA6F8F93F26B338AA
+:10F830002DF7738BDF0D823AD0ABCFBF9586F84A98
+:10F84000B3CA284FC1030EFC569A69B2807CD771A7
+:10F85000392FCE6D8F4B32E17DAF4D8BD8EF0D68D8
+:10F86000EFBB6CD2DB0E011D9B3EA273A0DFD99EC5
+:10F870006888C849402F420C8E2E792CF807C6BBE9
+:10F880001EF87E04FB5D27CAE57DE3EF1B6F723235
+:10F89000589B7EA4F0F81CFB7D89C2CEDF9BA0CBD9
+:10F8A0008EB6079B92E03A61F1B16C314FA2F8A09D
+:10F8B000BD9B88323B9F95C6CBE29E4D42CA14BC8D
+:10F8C000674712ED1AB1FC246F27B5BFFA57E08FD6
+:10F8D000BE49743EF4D994CDE4C453F289F5C827E7
+:10F8E000D68007F8C49BD0F379A1BA6CB66EC62552
+:10F8F0008D7441DE4093DBEB02BB4AE0A7F33D1F72
+:10F9000057D48BEF79537B1EB7898F1BE6E78DB5F4
+:10F91000F53FCA66765BE7F87A3AAEF51BBEEB5464
+:10F920007FB7ABBEB77EECBD688F3F07550AEB8C47
+:10F93000E16D02CF732585EAFC1432D26B62F25E70
+:10F940009D8F72A3B4CC0DEBF326536D7B94F67FA1
+:10F9500095F3C98D72E0338837BC3AA3E008ACCF89
+:10F960004AB8D09E8E733389AC0266B95C16F889AA
+:10F97000BD0FCA8B75208FEA7481FE29B47C51DFDC
+:10F98000DA77511EAEAF27B34774874FF061279CDB
+:10F9900094FF80EE82FFB4700B3E20DF0B6342DFEA
+:10F9A0006612C1A78BB03C6AAABF58BEB427BB6B16
+:10F9B0005E9439C79B1AFA827E7FB53188F2E7469A
+:10F9C000FBE39837B63337B00BD6FDB4A11FE33D48
+:10F9D00039C45585F6168577F7FF24BC745DB9E107
+:10F9E000BDB00385BDD72D7FF823832A7F58C0A7DC
+:10F9F0005DC7028E7AC2EE3F1ADBBE15EDBBFAA9D7
+:10FA0000562F9CF3A887BCD8128C7F619EF101BE53
+:10FA10002F0B4A2CDFB79BBDD87B9E31BB0FA0D6E6
+:10FA2000C6EEC111F729DD9B2FEEC9617053F9C5F0
+:10FA3000EFC9C1725B9507F77F9D76E31C6687DE91
+:10FA4000506069867B07BBDF97C3FC7BE405A38717
+:10FA5000DB89A8BFDB12D9772E9A595E7B9C1C27C5
+:10FA6000525AD73D5EEBF4CC1EBC949DC7E278B2EF
+:10FA7000B714E8B111E256BAEE7EC8CF9C818F81EF
+:10FA80004FE614F972E0273D6619989F91F2D5A6CA
+:10FA90000E02E9710DDBE17ECB9B48C39B721FE434
+:10FAA000AB2F807FA60DFA98DD7BD9C55757185F1D
+:10FAB0000551087EDB3A7D2D3520E58CC03CEF7783
+:10FAC000EA4A20CE6844FC8BFC43EDFA8D83E7B410
+:10FAD0009EC1E3807B75293CE61C677778AE86BFC4
+:10FAE000E3F9289D303EEE8DCF21CF3F7158179F0F
+:10FAF0002793800BE0EFE4F755DE165D9F1EE0D6FE
+:10FB00005991EEB74F67F198FA0466A7425CC69D1B
+:10FB100006FE27F6FDDB5733FEB8DD6C447E99D434
+:10FB20005E8BF11752C1E2295EFA3F80671AF18DB0
+:10FB3000839FE698629B84E736A74E54C75BA699DD
+:10FB40006EC4F8CE6D84F9D36E9FAA57FDEEA0C0A7
+:10FB5000C334B2F663C8E798A6F9BD412D5EB4F18F
+:10FB60001A818FA691DFBCEEAFCD4974609CD8435B
+:10FB7000FA7FC7B84E790ECB9FBBAAB8CE117D0CC9
+:10FB8000CFEBBFE29CB769115D17FDFFB308EFE94A
+:10FB90001E97367FFB63B4FCD38D03B1FC4ADA5D5C
+:10FBA0004B4E40FD96022C57C81FCFC07BD34BA7AE
+:10FBB0004F80FBCD8F98D9382E4BA00D7EAFC2352C
+:10FBC000247F186CC92A0C316C77F3D0DAE19007E6
+:10FBD000536161E5E3C5FF6B1896F37979D88B0320
+:10FBE000A17C44FA78464F71A1418552047E97AAC0
+:10FBF0002285B59F386C6706F8092ACA597990B7EB
+:10FC00006C751FA8973F99D1933E6EE0F6B1B0B7DF
+:10FC1000FC7CBDBFE07BBF19CE87F9AD9217CE0546
+:10FC2000F847BECFEEC732B13C02BFAF5881FB13DD
+:10FC3000CB7DCCBF37D6DAE806F9F7BD80A104FC4E
+:10FC4000B8366B5E33FCBE40F2C8B21140EFB1D49F
+:10FC50000C03FD47D7D5125C57D77C9C93847688DC
+:10FC60007A5D09BE9D24D653857ADD5079F04346EE
+:10FC700047F57AA0E32E87F7D3AE55EBA54EF9AE44
+:10FC800059B75A7EEC55EF13B51CECD44FABC2C834
+:10FC90009759849DFFD90C7CCAD66F2BC061903BCD
+:10FCA0003CF03E57F20EC4C48A5EEC07011F983D3B
+:10FCB000645877B8E04F11F62283C0664B83EFB2E9
+:10FCC0007ADACF073F2226E0A2DF0F217E56317875
+:10FCD000364B0DFC7729985D2EF6BD7562BEFBD4C0
+:10FCE000F32DB5B073EC2E42E50EFAEE8B077E13C2
+:10FCF000DCF55CCF4E35F91F36D239DC669F857452
+:10FD0000BE83049F03FBA6C312F825D05B27070F11
+:10FD10004625F85D091FC693291D7F9513672F0897
+:10FD2000B8B4F8A8EB45AE6AE1D6E2A18B3E1D68F7
+:10FD30009FB9F9EFCF75CE4B339F267EFF7CACD8B1
+:10FD4000A8CA133D5EC5F260055CC72552887A5289
+:10FD5000B2601CB5D3EFA4956FBD9C6713FA59C070
+:10FD6000793F3F4FF585CCE4DEFDBA08C2995BD9F7
+:10FD700061063C7E92C3FC2E02FEA691416C679008
+:10FD8000A51EE3C49FE4C8C25FA6A2B7B8D74CC4FF
+:10FD9000B9045E1D064F16E67B6AF039D364EC3970
+:10FDA000AEAA8DBFF6D24EA2F8CB4CE98E67112FCA
+:10FDB000BB45EB87BB89F9A76EE17EB8B1950CFF17
+:10FDC000294B1371DF965272422183BBEE5D16F40C
+:10FDD00078C711F82A07E316D111E027787DC44FC0
+:10FDE000314E24EE37D4E2C792DB337E7A5B0FBD0F
+:10FDF000C1FFAEC56FCDA5E35C943AF01EB4BFBBA6
+:10FE00006C7CDC401EAC17BB2DAF0CFC0B54AE7EE3
+:10FE1000FD356C36A10AE8E70C38729DB03EFCE374
+:10FE200020F73AA532A067FE7982FEE1C57C9F38B3
+:10FE30008EEBF74F76B1F3F315BE014F8E01FBF356
+:10FE4000989E843C90C7CDF0F3C9261DEAF579AFA2
+:10FE50000D77817DFE01E7B7FEEB65D5EFD30D0889
+:10FE60005954F76C0CDA91A22A0F0E67A8DA0FDD4D
+:10FE700097AFAA2F8E0C54D50F3F364C551ED1315B
+:10FE80005AD5FE9A93E5AAF2A8E80455FB6BCF4E2B
+:10FE90005695AF8BDDA9BE2724E8EB284C83FBF9F0
+:10FEA000193E6EB83253D5FE7CD2F863B0EE66AF21
+:10FEB0006579DB6564A1AAFF425D0DE64393566652
+:10FEC000C734D0FF213D75772B982746EDF754C0F6
+:10FED000DB7AB59D53DDFED82A90B5DDEEA7D0D8EC
+:10FEE000335AFBA5BFA30AAE7726B7E6F2BC936BE5
+:10FEF000C835FCF74AB474C5F3FE9FBCA9C37DC4E2
+:10FF0000E2D7987DBF7837CB872B20FD92F11CD8A4
+:10FF1000311D094970EF41C3BA3152971DA3C58BFA
+:10FF2000D1A5A6B3D9A3A67342A19ACE895E359D69
+:10FF30009347AAE96CF7A9E99C5AA9A6B3D3AFA63F
+:10FF400073FA34359DDD01359D33ABD574CE6E50DB
+:10FF5000D33977A99AAE79C105AA7A2137FBB42C97
+:10FF600056BD6F92C2A5545292D9FE6ABCEFA15FF2
+:10FF7000EB0F7BE40F41FF20FD1F5BCF0D985F3F30
+:10FF800097D21FF2EBFF42D61E855094960FEAF6E9
+:10FF90003D8671B5EFCA078F6AE97F95F629D58747
+:10FFA0004F803CA176CC7A900FD3FAF37D87BF6760
+:10FFB0003B46C8AD78BB217E5FDD9B3CEBA627F9B5
+:10FFC0003EBB573DA9D967BF05D94D688FAF45BF27
+:10FFD000D674CED79FC2AB51E0577D16F5FF5B14A8
+:10FFE000909114AEB7006EFA9DB72C83D00F7217A4
+:10FFF00089E8F19E6BC8DCD4E17D9998875945ED7D
+:020000022000DC
+:100000007278CEE2F6C11CEE27F9CA183890CBFC04
+:1000100023B969F0DDAC0E76EEEB78EA55DD0BF135
+:100020007BF827F8DD73FD87619C0A9367C913F499
+:10003000D561EE7F221359FE2751FC83E3EF61EC7B
+:100040001A87C54D5F940201DC67BB4D5ED8670F10
+:10005000CA242637E83757281FE25427347A652008
+:10006000E791DD19E1C576C4572805E304DFF1BB4C
+:100070007FCAF59D047E10EDBF6DBE06437811F377
+:1000800027B0DF4B7993D3E5A9DB8D11D897093ED3
+:100090003A9930E3A8D383FEF033C86F77DCB40A13
+:1000A000CAD2E154CF620ADFE5AA28EEEF29FECFDB
+:1000B00001DE6A4C14FF748A17B303FD938119FCA7
+:1000C000A9DC49E91FDCD3792401CF58897DFF5D84
+:1000D0004BE05318E7B0DC91E3057C281D786E8F68
+:1000E00058D1B821170D3DFB03051ECA13B2EFC648
+:1000F0007B788D462FEC2FCA2546D7D3A9F7CC8025
+:10010000D8E21CD99F16D1A9E0963C00B7AD2AD7FA
+:100110004DF9F1FF00AA42FBD90080000000000069
+:100120001F8B080000000000000BE57D0B7854D504
+:10013000B5F03E7366CE4C924932492024848499AE
+:10014000843C20214C82202AE2F0088D1A30BC1415
+:1001500030E2E401843C2080DEC6963603E1A5420D
+:100160001B2C2A2ACA8040D102068B801AEC206AF6
+:10017000F16A356DB5A55AB90950E54D0C3E68EBED
+:10018000ADFF5A6BEF9D9973480AF6DEFB7DFDBE0D
+:100190003FDEDECD3EFBBDD6DA6BAFD7DE73DEE2EF
+:1001A000CD8C561963B6DE8CDD00A9D999531CC9D4
+:1001B000D8B7F8774B3065CCC718546954E09FBD69
+:1001C00020F723C5BFCDC5F81FE4F7FB62FC0F4144
+:1001D000DE6ABAF4C114C8770C36B9B740D1C6701C
+:1001E000E83A9FB1F7B11EF4FFB405F2B1F47D35E2
+:1001F0007E4F08E7ED131E33F91BA17DF198971789
+:10020000B2EB187B76BEDDADC258A5CCA931985FA4
+:1002100039F3682C8DB1BF8CFEFBC1362763FD9D81
+:10022000DEBECE618CDD1B674AF980E6E1CD9E041F
+:10023000F36623E3184BBC72FEC67530B6C6C4869F
+:100240003336D9C197301BD705EDA6308F05C79936
+:10025000C6BC161CF77717340F8B82D404E530DF49
+:10026000BB988FBECF607E4AEF6601AA7F0F6BA35B
+:10027000FC6F237293EB617E931ECF4C67D0E662D6
+:1002800069DB702CFF87D5EB76C2B83536EFBDBD84
+:10029000E0FBF964EF677D10EEEB39DCAF36DF4948
+:1002A0000A87DFC5FEC52370DDE36CCEEBF2521981
+:1002B0007BDDC42A9BED5036AE37CD9F991DE99367
+:1002C0000777D7CF32C6A05D6B67542E1B82798F1C
+:1002D0003D11D6FF3D81C2EF79AA8B709D05AA9D85
+:1002E000F502F8B73A55BF15C62C1C5DDA17D705CD
+:1002F0007F913EC0D3448FCA10CFBF5E0A5FA0DE9D
+:10030000AFF3543FD2C4C40DE34F63FBA2D1539665
+:1003100047C3FAC77FD3765D00D2C27E96E36D599C
+:100320007C8C6FE17F5FB28DE36220BD2D618F9980
+:10033000C1FC6F1BA02F2FCA81BC2D989FC8CCC1B8
+:100340007218F710C201E8A7FECF79A3DE0869C7CB
+:1003500058935A0CEB2E7146F6FA3402B283D8A0A9
+:100360006F71DE6A49B4D7DE337CBF6E708F7A035B
+:1003700068F276C553EE24BA706A48FF6566E6698E
+:10038000EEA6DDAE7445D00F60379EB13BC45C3B3A
+:100390008B2E691761BD4F3ABDF3B19F4513FE32F5
+:1003A0000BD7C7CCEC3743016EF3DF03B841F9F14B
+:1003B00006807C2663271B6CCC6365ECD30607E5BF
+:1003C0004F3524507AA6C149E9B9862C2ABFD0E01E
+:1003D000A6FC2167F1F7B1DFB2D59F9BBD398CAD8B
+:1003E0000A9378E4F3582CE87855F2F03FBA61BCF0
+:1003F00055EF5A285FD9DC341EC1B138F9F8B2087C
+:10040000F8BEF839C58DDFAB5B3C9A1DE633FB0DBA
+:10041000EF4A249FB9EFB64D04F0B1DACB0AF3E20C
+:10042000161A50BC02C71BF6E1C97884DF670D239A
+:10043000683EA71B3C341F4F4BFB5B71D0FE6C43E7
+:1004400021E53F72163F8CF53DEC730DEB4FD8D98B
+:100450006E4E82F2028FE2C1FD3DCAC3FC7EC0DF58
+:10046000068BD78B74B321D1E6C6FD3E7AF0E4A7A4
+:10047000EF83713FE9EF7D14E97A5A6C79411C7C76
+:100480009F38A2D48CF5EEFA8631CC4BFABEFABE78
+:10049000E6F0A8157839FF9A42703ABF2FFB8E9B81
+:1004A000A0BFD78EA84C8579755E36D1BC3A8F86B1
+:1004B000FB9912ACB7E82595E87AD160CDCF5C986E
+:1004C000CFEEC372709DD019AC3F4B71B27AA0BF12
+:1004D000B3BBBE9F807890E39F8D6DFEEA23E47BE3
+:1004E0009F70BEC758F3A74F225FEC97E07E08725B
+:1004F000172C6C3AED5356173119E86BBEC6BC3C4D
+:10050000EFCDC6FCD970766F31E487EF4E1A83FBCE
+:1005100008C7736606F95AC6EEC7537FE80C8EB754
+:10052000A379F6474F42FEBCDFE4B34443CA9A2F97
+:10053000BC827C79ABDDBD8DE13CCDE138CF872D30
+:100540007C5EBE6DE1EE6D4EECCF4F7C00CA352C6B
+:10055000AF79F189BEB88E5701062320FFEABA08A9
+:10056000E277AF5ADCC7EAB1DDD3BCBF9FFFE481BD
+:10057000E307305D5B9BFF00A4BF73C612BC2B1E5C
+:10058000993708DB6727017A803FFE62BF1208CBEC
+:10059000656CF0FA43CB1261BC211BDB4D7D21CD94
+:1005A000DBAA34629A9D5C784485FE8F3A9D348F35
+:1005B000A13B5D6A126ED7BEFE8F6E4923C02988AB
+:1005C000BF41027F39EB3F1FD317D25D7D9B17C51B
+:1005D00040F920A5F9CC5217D2F91FF2BD04BF266D
+:1005E000EAE7A59629BFBF9BE13A7C89369C77A9AB
+:1005F000E6A6F309966B81FCF9BD699B1F8235EE77
+:1006000033F936D3F95566736F43BC17FB9E407CB4
+:10061000D7427D1FE46BF37C51374279ED2703DC31
+:1006200040512CF999EF15223CE6EF7D747C5FA8D0
+:10063000777E24730309B0CA972E8DC7762C993123
+:100640006409E7F736C6CF84760FE78C1986F45530
+:10065000AC36D3386C011FE77171EEB136004EBC79
+:100660002055A8F7307CC6EFB12D31879258103F46
+:100670000B5A96BACCD0FE3AAFCDADE2BE71F912AC
+:10068000EBECC17314CEBFBFE17E4BD444BF8E29C7
+:1006900029C5DFE1FCD3C47926FB7B5C63BE30E86F
+:1006A0002719BE2B783E6BFCDCDE067CA53E3F782E
+:1006B0006EC3B8E1AE61D4DE837C38090EE93C98A4
+:1006C00067D2E3563A07AE75FC8B16FB6A05E876EF
+:1006D0004138E76363C4F93B3DAEF1601BACF760A2
+:1006E000B837DE05F5668B739F99DD4EE4EF5BC38B
+:1006F0003D7D70FC1A5B470AAE01CED524CCCF57A6
+:10070000BDFDE3D3E85CD5C933579B476BB8C785BC
+:10071000EDAFB5BE91DF2EFED2C4F2800E163F6A59
+:10072000257ED1887C19D6D51839DC867C83BD61BD
+:10073000AA790BCED99B79CBAEFE1647E6135F693B
+:1007400064AC5B78BD06FBDF0BFC2600E78417F882
+:10075000C0A8CB1D2AA7F7D6C3D1D7219F659E4835
+:10076000A09F5B2E9B9837E41C34F603F8F2201C04
+:1007700047B308E60D39573D2C46C37DCBECB1FF9E
+:10078000DABAC5FC470AFC8DEC3C1AC1EC080FF83C
+:100790006EEF795D07C5BA7E85EB82747B7AF16472
+:1007A00084FFCD5F38CCB8BE9BCD935250AE8179DB
+:1007B0004FC7798FFAC2A49FF737E1BAFCB5CEFFD5
+:1007C0007E85F94CB81F3FD7FCB81F5BF078043822
+:1007D000B6CCCBF1E3BEDFA7F1BC2F4A23B9B625D7
+:1007E00092F9908FB44C8AF7FB5CC80F19977B7B0A
+:1007F000335E1E26DACF88A7F67DAD0052E4077778
+:10080000878BFEEBDE198CE54B93888F345AFCAB5B
+:1008100053B1FF1FA9C4878F0ABEBD3E2670B70A19
+:10082000FDAEFF3C9EE13847592069018E53194EB9
+:100830007CF72693E9DE4976ACE7498C0578EFFB37
+:10084000874AE7C4FA3CC8DB896F4F6F86EFEB2716
+:100850007912C3B19F49F1269A8FCAEAE8BB8BB7D8
+:10086000FBC8C2EBCD14F8FA93C00FEC6BDAF7DEDD
+:10087000891166A4DB4DAEB247683F304FA202F348
+:100880007DB2229D21DF9C5975AB8BE8A5E971E211
+:100890005FD3050E647FD8C0361CE566FE3763F66D
+:1008A000B630C4E7B4CAB0763859D9D1CA65914ECA
+:1008B000683FCDAB06ACC04FD9D4024F975C978A46
+:1008C000E37A68DCDAE681692743E8B9CC0A7C027E
+:1008D000FA7F21CCFB04CDEB401E951F00A1E65B07
+:1008E000D84FC72BD277E3BE621571427F0994239C
+:1008F0001E5EEBB0919CDA133D3422FC87083A452A
+:10090000BC2CE17807798DF28DD307913EB3C9C233
+:10091000E9C6B7278CF05A38D94678EE9C1EBED966
+:100920000AE5F70ABED5383DDCA340BDC697AC7ECC
+:10093000938BF424AAE73B1849FDD6683C5FF36229
+:100940003AD1D33ECDFFDC762C7F2D8CE8A1268AD0
+:100950008F5BF34A92A0378F6B058E7BD04A745021
+:1009600013EE8CA6F2FF8C233A1967F3BE82F000D7
+:10097000BAAB4339A2460B64C4007C8F09BA3A066D
+:100980006D107FBEBA489A376D79C87B1B93B7202C
+:100990003EBD1A2F673F50A9FC98838F7F6C0D1FB7
+:1009A000BFE4A7D5EF32C0DBB1E2F189B3611EC766
+:1009B000EA22486EFC73BD1AD0A250EFE9782C03EE
+:1009C000EA5D587262F806987FDBB28F53903E4A18
+:1009D00096D51661BB92AA2513F1DCEC695F96D41B
+:1009E000C0E60FD9C7275C9EDFE17ABE75793FC4A8
+:1009F0007DBF20A76D0ECACF17B4D66750FF888D74
+:100A0000F31EC5EF175FFE6C3B97AB3B32F03C9893
+:100A10006FE6F421CFD50582FE56A57A8FD1391124
+:100A20001E9885E747444E2BE7774BAE8DCF9F69E5
+:100A3000D9B64F8171AAC35BE653AAFA73B19FB3CB
+:100A40004A204A4923F879713F9D7304A210EE5E53
+:100A50001397E7AA77E8D7857F66985735FE03DABC
+:100A60005537AB9E30C435F36B38FF6AA605EBBB38
+:100A70008278827E084FCCFEE7593F04F8573D3715
+:100A8000301FF587EA98033FB989EA413BB94FD453
+:100A90002BF3723D57CE87AFEF9CA0FF7392FEA75A
+:100AA0006B529FA7F12FBCDC87C63F3BC99F81F0EB
+:100AB000BFA0887ACF59793DA00633CEF3054E4FBB
+:100AC0008F597CA670B20B30A2E7EAB8E6E10817AE
+:100AD000C987600E3E13D43FBB3B89EA4BBEC58A33
+:100AE00019C376D5BB13B770F94CE8B33851A85F7A
+:100AF000F50BDE3FE6711F9E793E498CC7E5692301
+:100B0000FE8CEB4D4E35D17A1F93FC3B52EE737742
+:100B1000C224807FE6064D57FF42A476AF07FA1D38
+:100B2000E8D77F97FD0F4C55483EEB6FC05B5FB534
+:100B3000E39015F7D3B38CF6AB715EEE54AE373E4F
+:100B4000FF7C179E548E371003257D38B91C6E41EB
+:100B500038FFA90B1FF725015FAD4618A406E1B3C6
+:100B60002FCF9B84FCFF02E6F15C88817C0ECA419A
+:100B70001CDE322FE16CA4B3657F9A93D406EDEFAF
+:100B800046F810BF77F7417AEC925F2CA08FE4A073
+:100B90003E5A39F4643AEAA97503E128E85ACF9C31
+:100BA0000D7936DC4F7337E6D9CA42F0D0B863E826
+:100BB0001127C0F9DC0EB31BD972A3D9FF1394A778
+:100BC0001B77A8CD3E46E53684EF39FBEBEF61BDE0
+:100BD000391B63F2515E96EDE76EB87F604508DC25
+:100BE000B377E8F130B8599F1F72409F9F8DBC6169
+:100BF000D8776F9717D0E7871ED1E75907600BF0BA
+:100C0000A0DA389EF68F701F71029EFAFB55377E70
+:100C1000EA6F9F3C6502CA171B55773A94F75F52FB
+:100C20007CFB60C89FDA38DB8D68AE547DF37F08AB
+:100C300038ACFC78FC113C0FCFB2E63F4C003CCC0A
+:100C40006959A7999DB86E3DDDEE33097A7D9EDB2B
+:100C5000D9E6F9F5E557EEEBA5028F2C2B949E8C87
+:100C6000788771EFF4C0846AEA170F3D094766651B
+:100C700011103AC0EC86E6751ACA6D571FC7C7E552
+:100C800041BBC789F0281DC1CB6EAC1FCB4E0C8574
+:100C90007FACF9ED789C77E9C30AC90DA5BFCC7C80
+:100CA00003CF81F63D336EA3F4CE425ABFB4E7CDF5
+:100CB0006D51029190778C701E688376B3FD8A1B0C
+:100CC000E75DB6DC1AE467F0BF8A358679AC0F2998
+:100CD00087F9CF3D70E8AF0AF45FB951DF6E1EF0BF
+:100CE00059E45F555BBFB5867E977AE38D2D9B55A2
+:100CF0005CF76C397FDF2886EBBA915765BD847C41
+:100D0000731233706E4CEB5DBC2315DBADE7ED80E9
+:100D10005D96E27A6BED9A13D75B6B63810898C797
+:100D20009148CDE380EF973644921D6D8E15E4C94E
+:100D30007C4A59583EB6734763BB4FDFE7F6B4DAD7
+:100D4000388EEFDA4D0AE951B568FCC4FCB33C3F7C
+:100D50008F05681D48279ED0F5F9F579D6C4F5AF03
+:100D60001A73E010C2A38AB571FD09F0E891F0038F
+:100D700078D5C03A8FC6A2BC6568CFDC5E1C77818F
+:100D80009DCB4F0B0E7C6B0D2D977AA0D453A57D78
+:100D900077534671388EB342F13C618379AE10F2DD
+:100DA000B56F5D18D1EFCCCDFCBC01393603E1B293
+:100DB0007E5DA21BE58C99209787E1BE99174EF5C1
+:100DC00040DE25BB4C07C8D55B5C58BF3980E7C601
+:100DD000FA475D244783FC4B70E9581BE6DFA2A06D
+:100DE0001CCCE598F5EB32490E7F559E536BB9DC70
+:100DF000D58D5C4CE5AC0F97E33FC2A584C8C15FBD
+:100E0000F4F67E9ADA3BB8AE8A659E443C772A2691
+:100E10006B26B457B1CAB86B921FB60939B203D664
+:100E20008FEB38A914BF650A9147BF16E7C8F031A8
+:100E30009EEDA29E1BEB5598263D740B8EF798C92C
+:100E400089E375C1DBE3C9C0799C5C17968F743662
+:100E50007C0CB7171DCBE3FC3DE23AE6F1E3799A4F
+:100E6000C6FB6569265D9A100EF407FD9C2CE0F622
+:100E7000EAC8EB8AC94E076735F179E33AECA29FDD
+:100E80000AADF83F6FEE663E123E6C1C97174E2E71
+:100E900054B6F079017E213FFC9130B2EF9D14E70A
+:100EA0008F8433D0CD30B2D30B7EB54ED0CB3A0B3E
+:100EB000A703DF3CAE3F05E985113DAC177AD64C60
+:100EC000815FB696CBB5402F1CCE6B1305BD30F6B7
+:100ED00037A487022797B3AF515F02BC0F48EB7D61
+:100EE000A5DE24F1CDCCFE61FFCC2F52BB7FD73ED7
+:100EF0001F9C9F552F3C1AC5A0DE697353BC1BDA9B
+:100F0000D76C5B11E581F494D917E580F14FFBD5DF
+:100F1000427F37F02E4D9376658F5D01FE331FFFC4
+:100F2000E94479E7E189B8BEAFB6591CC81216EC9E
+:100F3000B092FE347FEF3C92B321DFCEF3AB3E574D
+:100F4000317F406F3FAFFAF9A3F14E82B72FC994BA
+:100F500080692089413A7FABC51D40BBF407AA1BBD
+:100F60008601B9B96325CECFD81EE77119F0BDA0AF
+:100F7000592DD5A2AF2C5F20F8CB82BD0F7F8E7686
+:100F8000BD05067B7DA5F05B18EDF593D2227B7D38
+:100F90009A0DFFB89E5D8F7210C0C51DC07D0BF30A
+:100FA000492732E1F6DEC6E71ECF6D477961EB3B9C
+:100FB000514A4ED05E2FFD199DCDE59B5E71F6BC6A
+:100FC0001F2F08BB6D105F9C6F390F28C80340416D
+:100FD000E7698D25107513C0A366B385F84CCDAEB7
+:100FE00067B73F8974F6272B9DE7D5BBDEFCC38D21
+:100FF00028EFEEB1F42AE2CBB02BF1413C2D707218
+:101000003B99C44BD52FDFD49C83F9F725B141FC24
+:1010100054EF39A4B1C157C2716CF321ADCDDE0DCF
+:101020009E9ADBC7939DE8B9AF35DC07A75F53589D
+:101030001FD795ED2B37BF1985F218C209CF258927
+:10104000AF2EFC19EA43FF135FB98EEA3950AFE8BF
+:10105000097FF97876A05EBE3F92C5C0F8951F590A
+:10106000FD4588D7DD8BA3701D9F99EB389D3FBD53
+:10107000221EE5BA4A8B2FDE4129FF5EF9CCFD44E2
+:101080007F7395BA78470ED177A28964065F22AE46
+:101090006FF6C669B4BE39CC4BF457F9B45AEC8735
+:1010A000F44B332BDCD3CD3EF958F0A5CFB600522C
+:1010B000617D9FA1DD06F9C6EF54A1E72EA4F3FBE5
+:1010C0007EB156C61651FE4B21B7ED4E33497B9685
+:1010D0002D545F5CB075552BE2E74CB2A70FCE13D1
+:1010E000E0E013F052BE857ED5DF16F4E1F8614EE4
+:1010F000F370D10ECED1B1F81DEBB75A3C68F70EA4
+:101100006927F4393EFE7D627C987738EAAB9FC54B
+:1011100073B9DDB8BEB001920FB056164A5F3DED0F
+:10112000FBAD0F125D7DF101E72BF3FD930AA9BC26
+:10113000D512E883E5FE435315E20B5616E86E5FC1
+:101140006FB5887DAD2F87799A9550F8BEC6E5D0EA
+:101150003920770542F671906EB4E0775AF7236232
+:101160001D6DE44F937EB8B9821F18D76DE40F1F31
+:101170001AF8836CCF3676EF070AF2051F8D5B03F2
+:10118000E709CA19357FB2D2B951B3CB528CF039C5
+:10119000BBF3F01F66A21EDA2CF7B19EDF1AF771BF
+:1011A000E58BC3BADDC767D7E475BF8FE17BB7FBBB
+:1011B000788D42FCED7FCA6FE1A423BB414FFB75E4
+:1011C0006E0FFCF6DB34E11715F0FC92E544DF848A
+:1011D000858ED2FE841F035C253C8DFCF3F1342701
+:1011E000C1D7C83FE1EF03160247093F499F8C79F9
+:1011F000699C2E3A96742AE9B88B4E8DEBD5C3D1F3
+:10120000587E18F913CCA7F8650BB79FB528246F43
+:1012100043BBB792AEA37DEAA1E38F35BD95D42B36
+:1012200034EF37E49B0DF53D867CB1A1BED790AF7E
+:10123000D3D5AF397058E3FA414057CF5A7F3BE9D5
+:101240001957CA117EEEF7D9FBB9E643BAE8D7A120
+:10125000215FB42C63BE4894770FAA24EF5E7476A6
+:1012600044A15CB2228CCB6D171D221FC3F31DBDA0
+:10127000B595C817E5F78E306E27B958DC111513F0
+:10128000A2A7B7B7A851688F6DF3B3C2EEEC28647C
+:101290001905B8B6B19ECAB9FC56A0DA53EAD11EF8
+:1012A000DAA4BA814C58C5D2BBA228EEA125ED8E96
+:1012B000E9F07DF6DB2A850F5C0CE77605E6F3980E
+:1012C00031EEA09CA3909D62BEC746C2BACA5B78AD
+:1012D000FC41C51A3D7EE7D8A746079CC877F47144
+:1012E000027351AF4B437D4FFFBD8AAD217AAB32C4
+:1012F000EC0BAFB0D31AF745D900B12FF2589EB01E
+:10130000C7909F6391E0D7056ACE1DD301FE178F6A
+:10131000A8CC0AF9CE1695ADC4F5EE54C8DF830EFD
+:1013200001DC6FF3615FE27C247CCEE1BEC9EC5945
+:101330002E39F7D227C37F8874B2EFE3DCA7203DB4
+:10134000B7EF4F19AF627EFF1F533E6657D61FFBA4
+:10135000DA5F67211FBEF89A95217D5F7CEDD72962
+:101360006817BCF88A95F4E58BCBACDCDEFC5AA49C
+:101370001FFD911793B99CDB78F0EBDC363A779739
+:1013800013BED60ED0B8DCD4F2F76368AFEE6C8132
+:1013900055A13CF15A04ED9F05AF84913FFCE2C199
+:1013A000AF8787C64DFC4FD723FDDD1723D9F41730
+:1013B000916E855CBFE0D51B9E457F6EEDDE435A86
+:1013C00039948FFDD57FE722FFBCF82297932E58E2
+:1013D000DA9E415BE386AD373C624944FB1C74D620
+:1013E00017D0B5ED81C9B84FAE840B87C3458003D4
+:1013F000AE0BE052897CBF2778BCF06F0B8FCF67B4
+:10140000717E763D43FF6F102E0AF723B444FA6DC8
+:101410000AAD9F7F7FEDEB5CE437575BEF6F70BDEC
+:10142000BDFFFF59EFD97F5BFC727A5F3CC049F387
+:1014300033D2FD9574BDFF3F28BF3BD24DF3BDC6EF
+:10144000FD1E91FEEFBAFEFF1B7C0FFCB75DEFD5D2
+:10145000F0FDB6C077A403FD8A170FFE770AFB0ED6
+:10146000EB2E4CFF77DDD7FF7CDD525E1FA3BA8FDA
+:10147000E441FD7758F3076E17491FDDCA1DF707D2
+:10148000E3EF483F1ACBF8393DD6564DF2E6D87E09
+:101490006B492E6E64F9E487F0F553C91F43C117F9
+:1014A00000875F27E4F9C99F640EF45B0CF93149AA
+:1014B000B5149F65D41BC7864F284479F4F0529821
+:1014C00017F47338D2E4405FF1B87E6AC09A4B6972
+:1014D0003BA66FA5DC7E04E5967176BDFE74BB412C
+:1014E0001FBAD5A92F2F642FF642FF59618E85F9B7
+:1014F000613EE3B17E88DE3825DD41F0BA95352DB9
+:1015000077D8BF3B9CB6A5733DF94A38FC73B85DEC
+:101510000127A1279B457D23DCCCF6875AB19D99F5
+:1015200081DECBD74BFAB2D47BAF064F26F469B33A
+:10153000185AC2D7DC8FFB4943FA25B848B87F5701
+:10154000784B3C19E12EE12BE166C4433D1AA37AA6
+:1015500007E1DFCF9C67C67D77B390E3C7996378D7
+:10156000BE5FAB5A4CFBD1CFE9FC0BB719E593D169
+:10157000F6188AD764CEE418D46751C4FC3609E45F
+:10158000CE1131C315586F9299F9ACA06FA20F8D8F
+:10159000ECA80F9AFDCB5C380EB7D7269BB95D1A25
+:1015A00076B72F3C9FEA7B34C897FE6C2EF340FD44
+:1015B000D224E656787D161D4BE1684CC5B82C4800
+:1015C000B15D6934EFB7B40FF32FE3F824BC0CC05E
+:1015D0003495FAF5986279FBA87C6AEF33F1F61E30
+:1015E00033C67BA571FB7AC70A2BE91FA5AB9233E3
+:1015F000907F148DD1DB8D9333B89D59A6AB33F812
+:101600007E574DEE04948BCB960F247D480D2FAE64
+:101610007D09EDFDBB23881E4B57DE336118CE6F6D
+:10162000779C1BA77766E29EE1BCFE8CFB3F84EFB4
+:10163000DE1D61F47D6786F7683AF4774671CE7AED
+:10164000093E944D3BAC25C010DEE649E7D1FE379C
+:10165000D1B7E73DF4334E9CAA52FD898CC73DB209
+:10166000E511E48F9EE0FBDC9C00FD4D006503CBA3
+:10167000DBC31C290B61FEA5C2DE7B52EC17359C37
+:10168000795FB4E3BC923352E1FB04D67D1C706AEF
+:1016900086A83F46D988FEA1FE63B93D5ED6C77EC7
+:1016A000B0DF2C018F8BE9DCEE24F30057AA5FB189
+:1016B000DADA9E867ACF6A4B2013D25959632EE12B
+:1016C0003A8B52D9F80D08F70754B685E6DB514A34
+:1016D00076EEC82C27E2C10B244DF1854D2E27DA7A
+:1016E000BDDA473707D03FD0FE84CBDDE8242C534A
+:1016F0003C8ED4B3DA470706A05DBE238FFB198E5C
+:1017000039DA22513F2CB7DB283E47C6F5CC76F0BC
+:101710007DDEBFB16DEDF5A8773EAABAB7407EF683
+:10172000A3DCEFF217BBCDAFA0BEB69EEF53B6461B
+:101730001FC7C31C6EB2F794378DD650BFACB07BB9
+:10174000345C6776A6372603F7D13700BFE118C7A8
+:10175000C96833943695529C891A05FB0EF789D9CE
+:1017600019857AAF310E688188FB91F917C2BC7D6B
+:1017700033004E65D1CEDD482FC7EBD3C8EE3943D9
+:10178000D05D11C631A27FC2DC9688F379078DB88F
+:10179000307E51AC23C34EF41CC6100EED16470626
+:1017A000D277FB8A3013FAD98A9671BA867D66336E
+:1017B00043FB07CD2C1CFD06A7D279BF254BCDC519
+:1017C0009B21DFCFC6CC91B148577944D79BB3BC9E
+:1017D00017D3A1FF533F6223901ECAD7AC23FF8AC1
+:1017E000A40B666E1D1707E39CDAE6CA47BE29E91B
+:1017F0006873D6983C844B173D4C55880E203D9419
+:1018000046F430793896178D090C589483FA680D90
+:10181000F3E0F99EC0DC282774B20EF23F76DA3589
+:1018200027DAB9243F917C03F0EAB1C507E9603BB0
+:101830009CF7660B633B1A6C943EDFE06066E071D8
+:101840003B1B1228BFBBC149697343167D7FB1C1E1
+:101850004DF9BD0D2328BFAFC143F9030D8594BEDB
+:10186000D2504CDF255F02B8101F927C45F2A37264
+:10187000BBD68EFE48C9978C74330BC03B2A9FDAC7
+:1018800013DF93FC0ED761CA0FF22389DF54A5D86A
+:1018900097E0423ED63603F15FA09EDBB51FF5F21E
+:1018A0004ABB9BF474C6F95E27D02BC2254563075B
+:1018B000D0EEDAB8D0D3BECA1584FFDD950A3387DF
+:1018C000D0D53D7561CC1C726EDC5B1FA3CB97D469
+:1018D000FFFECD3ED0FF1DBDBC55487FC77EFCE955
+:1018E000D37F84EF9B7E7C261DF10DF3D8F6388ED6
+:1018F000BB24BC6B1EB1985F6E217F547F6907814A
+:101900003FC44B19E3FB6DD38FFF46FBBBBDDEEA43
+:101910004479F823C413C0F5CF024F65F556825FB2
+:10192000E98A13BBF6E33E5FA2119F2B5B2EF6E123
+:101930006A8067887FF77822237B0448D314AF7EC0
+:10194000FC475A2002FA3FAEF0FDAB805050827146
+:101950007FAB7F7D14F7BF527F84FCE75E9B3D40E9
+:101960007280CF722EB43FA5FE2DAAC7DAFAC5A0A9
+:10197000BD84CEB15BD0EFE8D19CB06EA469C45BEE
+:1019800059D6EB2C11FD264D8A03B74C85F85EB174
+:101990005AE1FE49B33B612AC87D8F64A884C7F72A
+:1019A000D2CDB42F733298885F68A2F349D26BC549
+:1019B0001A6887FBA2294F9B13C287CBC4F7F22C6E
+:1019C00013A5F2FB16D16FDFD579D3519EE88BE5D5
+:1019D0003998E64F47F8F6B58F372B21F8DF986135
+:1019E00016F3E0E3E7E06683FF7B282B559B9D839E
+:1019F000F8E1E7971CA72C2B7F25C67196AD198DB2
+:101A0000DC97355ADC09BDA0DEB6AE7E1C5C5EB04C
+:101A1000F178E59A1ECE0F693F3B85FFBC81D64D1C
+:101A200076DDAADDBFD88D71FC551F5B09BF55431C
+:101A300044FC548E7FF8143234EAEDD5E37EF1494C
+:101A400014F91FF6F2B84A48B93D754925B7BFBA2F
+:101A5000615F75E3FF7963F7C751DDDAA9F7AAD7AC
+:101A600064A75EA07C1385F2835C4FC1C12FE3693C
+:101A70001ECA65F2FF2C38B822BEBB7B37467B7589
+:101A8000973D5BD8ED8CE5467BDDD10CBD1D1B047D
+:101A900044BAC725ED754CCD8946FBFE97E29E47BB
+:101AA0004F7A8DB46F2FD8009DC4C1FE343BA3D1B3
+:101AB0005F75B10779DA99C9CFFBF3C21E7E71A7B2
+:101AC0004A7ACEC59D91B49FE6EFFCD95BE83F9C76
+:101AD000BF55A169D4B256821BC093D942CF318C75
+:101AE000378BBB72DE9DFEF4683C47AA7F11598795
+:101AF0007436AF59F16C83F974DA9CD1BD43E6F3C7
+:101B00008DA0B36A6BF37082B39C3FF2C5DEC17ADD
+:101B1000F35A7E46F663A87781E4A0172218BFFF28
+:101B2000D1F11ECEF3ECC6A16EF4FBCD6BDE339F7C
+:101B3000E4889D110E1481CE883861D98F2D938F42
+:101B400067CBE472CB59E10F3ABB5B257E86F3C4C9
+:101B5000FD7546D1C7E345897651026E2FE2FEEE50
+:101B60001DAC3FAFB93D6A00D4FFECC0EF294DC8B2
+:101B7000E47C609EBD3517CFDFCFF646903FEBB3D8
+:101B8000BD4F8D7F15C63BDF3CBA17EE07D97F46A8
+:101B9000A685EA9FDFA81622BC989FC7BDD4227CE9
+:101BA0008786CE336EB3CF15BAEF78DCCFD9BDBF01
+:101BB0008C32E504F1596BF3DA125371FF9416235A
+:101BC000DF38A538A99E65EF681FDE635AD092C73B
+:101BD000909E69DF2552FDD5A6907A9AC54D4CD1CD
+:101BE0007C60922789E02CEE21897879BC5747F7F1
+:101BF0008A26D9C83F316B88F3AEBB914FBE63E1F3
+:101C000078E9E77C1CE5B759EFC751DCD42297F39C
+:101C10002E9CFFE2DFAA14EF3B6BA8E003096DC323
+:101C2000306EB166B5C23CB0CE7617971B6AFC2AFF
+:101C3000F342BE2FD0830F4031313355F0D34006ED
+:101C4000DE077CB2D2E4D1E0FC3BA6319F8A76A3CA
+:101C500017793C734D2A8F1B7E12E91ED29AD84009
+:101C6000461CF4774EE0B366722003E3246A5E4CB0
+:101C7000A43889731AF75BE277F493D6E4437BA820
+:101C8000D74BC4C362FB9810FAA929733BB19E1AC3
+:101C9000EB76E6D971BE8E0B24C7BE14C9508E35C3
+:101CA000ED8FE4714E3F0FDB620DC15399A0B75E1B
+:101CB000028F6C268F877C4CC4633FB62DD18FFA80
+:101CC0009BACFF98C53B03E180EB40F97D9ED69429
+:101CD00081F2AD9CEFBCA8269AE73941DFF3C29BA5
+:101CE00078BCB4C6E329B13EE6DB2D8CE2B83B9E5E
+:101CF000B3523CC999C4D67D38FE99E706325C7F61
+:101D0000BBCB3FE7009583FC0878AB7ADE1AC0F5C1
+:101D10009C7E8EDB9B4F5BB83C767A528213F156E9
+:101D20003879C32CB2C76CB52A88F7D30AD312B05E
+:101D30007C5B6FB70FDB37D4539C7415B009BC8F35
+:101D4000036921DEAB39BD6D20C5879D7E5BC51B58
+:101D500051F87D357EF7B2A6593F4078ECE0FAD3D2
+:101D600099E7FF3E30F41E9A4CABB6EAE3E0249DBF
+:101D7000C8F246B12F1B059C5765F273AB36A2F92A
+:101D8000B1545A27873BE089F43E38F8239FBA0EB6
+:101D9000E320D215E41B4F025D3D8576851D5CBFB7
+:101DA0003AB3D34271E155FB233D1477B6EA7A1377
+:101DB000C541A85C0EAF3201F82855A8DFAAC95961
+:101DC00074DF17E04D7A6CC736558CC3981DD7BDAC
+:101DD0009DC7F916A1AC48E583A9FCB4C89FDE37BE
+:101DE00098E43AE8DF83F795AA7EF0430EC7299579
+:101DF000EF32B263D888BFD674F9714646E379579B
+:101E0000BBEAA668BC07C8DE5719CA2746385D3248
+:101E1000BBFB205FFD83E05FD5FB9ED6901F548BFC
+:101E2000FB21D5CF2BDC9F0CFB0CEF4956AFBCE957
+:101E300071A2CFF72C2C1DD673AEF96751A1F8080B
+:101E400008BED6555F7353FD6AA88FFD54AF7C273B
+:101E50008AE6B3DD427126463C5E73FBE7D56B6ACA
+:101E6000DF451FCDDC8E72C5FA59EB7F7C0CFD7F00
+:101E7000B133CCEDA3AFCD74AFECACA5790EAEFF12
+:101E8000ECAE30E2476763387FF80CF8A72F13E712
+:101E900071FB4F292EEB7753E83EDC5CBFBE5F3908
+:101EA000EE9BC8B7319E24CE1D8D717DB5EF73FEBC
+:101EB0000678B983DABF6FA1F6C6756C15FCBE6BE8
+:101EC0007FEE8A207A38DB97E3E5ECEE4C3A8FDA46
+:101ED00063389DC37C53F0FEDCD95D9979742F0D76
+:101EE000851BA0872AA1DF9E8D694E718494B75B04
+:101EF000849E16809A4837D806E4BEAA7A2E575593
+:101F0000DBD6507C08C6D50ECFA734608DBD323EDF
+:101F100016E895F4C77E597C7F311C2F5EC46F9301
+:101F2000BCD3AC21FFF60AB9B066A731BE9697FFC5
+:101F30005DEC4F9C6D2F19CF8B74E85328CEA47A9B
+:101F4000F9C27948E7D575EBEEC67D26E75F6D6689
+:101F500085A887B52B2ACDA33D8CDD3B19CF8DD02D
+:101F60007142E4362DABCB9ECA1CF124AFD2391698
+:101F70009EE5E474832726DE135DAEACA1715C524E
+:101F80009FE5EB927002706818D7D73E5A94F7B06D
+:101F90006E394FE3BAE57C52B2B89DA4DDE5FCE9A9
+:101FA00048C4F36F54BA4F7BE99BA1D1B1DDC8653A
+:101FB000C1735D0BC6B7C2FCB391F6D0EE92C9ED0A
+:101FC000A8D5183F0BF3CCD8A88FEBCEDAAACF0F49
+:101FD000DAA9CFE7ECD5E7735BF479F71BFA7C1C41
+:101FE0008EDB9BEBD9787F17F56C4C51CF765AB9C5
+:101FF0009E8D79D4B331453D1BBFA39E8D79D4B35B
+:10200000318F7A36E625BC51DFC63CEADB585E22CA
+:10201000E05423E224110F48EFECE530DD7D9F8B87
+:1020200007F93D0EA003BE6F6668B46F9EC41AA484
+:102030007770BB52DF293627C6FBFA62BDE3B38651
+:10204000E17D8FD695898837731BC59D2E7885C70E
+:102050009DD6E487D9D1BED1B6E2B39518CE393535
+:10206000D67B7B566FBCCFD9B11DE15B5B7F98EE11
+:10207000BDB72D75BE7F0BC71FD95958652CC94DEB
+:10208000A578CEC5F68C4763DC375BA38FF336C6E5
+:102090007D1BE3BD8D7420E5BD4D968E44E4EB279A
+:1020A0009EB3ADC1F99F0813F74FA6DB0CFE7E214E
+:1020B000A7AD55B6E0795D9315CBFD4947403EEF9E
+:1020C000E69C9569F9E5A1248777E5D72826BA1714
+:1020D00097104FE7D06231A714A5A37D15F2B97907
+:1020E000263A372F815C86E35DFA4025F921738318
+:1020F00049B79E81FE701D7D65EF8835DC6BE8ABCE
+:10210000AB3FE440AAE15EC3207D1CFDD4A587500F
+:10211000BF9FB266A8AE5E45F14D06388A790BF9CD
+:10212000B502CE0F0FACEFC9251B5210BF8BE77560
+:10213000B6AF42F9F4A530BA175689FF0FF86225F9
+:10214000F489F7192BF78AFBC0F5FA73B85C9C4346
+:102150009566E673C406E9B0D2C13C31D07EDEA0FC
+:10216000D6DC00EA156FFF7EB82315F58AD17D9085
+:102170001FA5583C14075BB3273D6629F4BB22CD4D
+:10218000FB14D2DDC9A6C33F29C1F3700FD7F74EA8
+:10219000ACF96514C589097A4BB138C211EF9B9B24
+:1021A000787C1CDAC7D4D8205D6C6E8A0B1F600F58
+:1021B000AE374807DF109E003FDC8E53F93AF93DF9
+:1021C0003A9BC57A472B3E94A7E5FA168973850D8D
+:1021D000E0FDDC27F227857E21D7796EE0A15C2720
+:1021E000DEBF683890A2223F37EDDC9E08A9DBEA0B
+:1021F000DD87FBAE7273FA1F47C238551FF2F5FC3C
+:1022000065FDD8A81B50FEDC657117417E55D3B320
+:102210001AEAD95566BF46F195CF6DD630BEF87B28
+:102220003B36D3F7393B4A299E722EAB23FDF394FC
+:102230007C7740C0A3728CB2D101F34E1AC8E5BEC0
+:10224000CA70EEBF03F9E84D7CF7E3D20E250FE329
+:1022500078A616EFD14AE1FBFB82CF18F749E7BB1E
+:10226000530A7A133CF87D8D0F1968F16957EE8B8C
+:1022700029975DB42FA65ECE26BD6C5A6020D77F0D
+:10228000730CFAEFBBFCDD85CE16BE0F2AB540AF4E
+:1022900029B84F5EB3909C5B0BE7CD887CD4AB191B
+:1022A000BB11D2E291AA8E5E178C8BD0D1F374163B
+:1022B000B24FA0BF3B316824243FB5284D57FFAE35
+:1022C000A9D906FACF0F96131FB95177BFAE7689F9
+:1022D000CFA9909C3946FF9DF13841C66ED3B5AF6A
+:1022E000659383F590BEB77239B8766FCC16B4F7A4
+:1022F000559AB8FE34DDCBBFCF3FC0BFB3E94CB772
+:102300000FFBA7B9FFC8CF450BF905A43D7D3AFEE9
+:10231000BB1BF8C349DE753F1CEFC5A33D42777F69
+:102320005AF80371DE88875A6137AACDE276A35A3C
+:102330005FAB86EF0E00FCCD71B154CF1687F191E3
+:102340004D0AD915315D42F192FA382CEC0FE318A1
+:10235000E71F514B719F18CB2BF1DD1FC4EF2B3CB6
+:10236000AE74EE06631CE41AF247CE477B5008DEDB
+:10237000EE1EE814F28A7F655F845F919247F72230
+:10238000771ED230CE6EEAD4983CDC3746FA927C87
+:102390001DF633E9DF9DEF1E26FAEAAC3413FD5E2D
+:1023A0000D0EF33DDC8E6AA4BB39AC55C37BE273E2
+:1023B000F62A6ED447B11EC2A32FD2A3011E71B15B
+:1023C00057C241C2A70B5E7B8D716E1C4E730F28E6
+:1023D000FE40377032CEBB27B8C9F5CCF17AC7239F
+:1023E0005F90EB9A8BF3C7FE61FED8BFF443B01148
+:1023F000C6FD9946F6A9F9C53C3ED6480F932F7302
+:10240000BBCB9D97CD944E2DD2EF476C87FB62DA04
+:10241000E5782AFFAEF4321FE6C9EF3F5D1B9DC889
+:102420007548BE1BDC0FFCDEC0D5DE0532DA1DE7C9
+:102430000E14F1C8C3D8305D3CB2E0ABC6F6C67826
+:1024400064290718CF97D24813C54D76DA5349BE91
+:10245000907CD62BCE0FEF8A2FA99E17EAF1D9C414
+:10246000EBCE1BAFB0FF2D8A4CA5F7185296C6C510
+:10247000239E4AC31C147F5FBA54A5B8E752A8E74D
+:102480000C914F562E4F4BC1F3E2F88399CFF84091
+:102490006E3FFE40AFF81130CE8915965E3667B0BC
+:1024A000DEF115052918A771629D75BABF1B78ADBD
+:1024B0001BC8CF87DA1F1FA5F3ECBCE9DDA8E9D064
+:1024C000BE66C54B5118E65FBD829FE303D3BC4D8A
+:1024D000037BE379BE79BB03E1E7D89C8B76DF4DC4
+:1024E000701C607B293F54AD28E883F245CD3F0E38
+:1024F0003FE3C07BD64B2DF1287F9EFE00CE438567
+:10250000CE33921B4E854117E44F8B243BC2298565
+:1025100079D0AF74CE74E8AB55A817E635670420C0
+:102520005D68F56E1A88F2FF8A67496EA97A686954
+:1025300086AA62BFE9D1DDD94D64BA5D9CDB28BFB4
+:10254000638AF23BC6C9A0FC8E7994DF3145F91D40
+:10255000BF2FD8A097FF5E10FE42694FEEDFD891E3
+:1025600087FE3BDF18965547E7AD3D0BE5F5C54ABD
+:10257000B81BF9D162949530FF4918E9B16C6B2210
+:102580003F6F059EEB6DDC6FF4B5B89F7B7307C89A
+:102590006421F479CB651B0BBD373B9AC5E8F26328
+:1025A0006D89BAFA050E97AEFC7B090375E5B73A5B
+:1025B000F374F9DBB36ED0D59FE01EADCBDF31E213
+:1025C000565DFD499E49BAFC94C219BAFAD38A4BAA
+:1025D00075E5774D9FA72B9FE15DA8CBDF5DF98067
+:1025E000AEFE3D754B75E55F9B4023057A6941BDA5
+:1025F000CB8AEFA7D828FDBEEA3023DF58FC9B74B6
+:102600003BE27BE458535D77F6FD53421E4ACFF61A
+:102610009C407A4916EFE3248B776EBE1AC8F19975
+:10262000C480AA48DF6D4D44FA35D633968F8C7836
+:10263000FD92137058FC7CF43433F08991D7BF3E7F
+:10264000340DF20F3E3F9EE76F7AFD97A9905FF73A
+:10265000FCC3D3CCC0A7460E79FD129627FCE276C8
+:102660009E9FC248F4787AD0DFA7FA70FEB7A4AE76
+:1026700071733B49B7F7CC658A70C0FBDA08074C29
+:102680000340BF98BE0EF48BE91B40BF15C09FDE10
+:1026900002FAC5F408E89FF8FD3F41FFC4F45DD09D
+:1026A0003F317D0FF44E4C5B41EFC4F4770DD329DD
+:1026B000FDA0C14BEDFED05049E9D1863AFAFE515A
+:1026C000433DA57F6EF0D1F7D841D28E1160BAFBA1
+:1026D00001E867447FE201CBB9503FB0F4574AFFAD
+:1026E00064631D6B8B407ED1668EF9D416F43BF685
+:1026F0006C0730B34F43E4B168E6491E44E3F77317
+:1027000090DF487CFF557F6FEA20E03B1FBAA6A40C
+:102710000F55F1DCAA7B13DDB21F8AFBF5C67EBF25
+:1027200012F4F1D7419E4C6C27FDEBD2BFDD15377B
+:1027300013E27F3785C4EBD05F48DC8DF483CB3860
+:102740009F9B6DFC9EB1F473CB781ED95FC1178C33
+:10275000F8C3A8D566925F22CD2C80FDCBB89D51E1
+:10276000B6E63C8C63185563A77BB57DE0BB964FFE
+:10277000F53C2AA45BFF0AF573837EF53E62FE50AA
+:102780004EF32FF8C24B76D85122AE00DBDB78B97E
+:102790000FDB8F42DBC27594127F7A1AEFEDE607EA
+:1027A000FDFC583F82D70F607F03FE06E34505F727
+:1027B0004D726C731EF2EBE4F976BA17BA7174803D
+:1027C000DEB322A313C0658AD49F6C222FFD793B10
+:1027D000FA901D69ACD8EBC39CDE1988CF62ABE3DD
+:1027E0009308DA6769C9689F9C24E4E77F82B75938
+:1027F000D84EC253E245E251E223247E8AF0D01340
+:102800005E8DF834E251E2AFE08B205E10AE57E20D
+:102810002D8857B4E7FEBBE0ED3A337FBFCC5A6357
+:10282000A377D1AE86C77B3BD8F868A8F295D3FBD7
+:1028300015F2CFD2CBCEB7305FCE468F47D4CAF297
+:102840006F7B28F77ED161890EC1F7CD02DF19AE0B
+:10285000EEEBCB7AF23D06D97F410FF5DF0993719C
+:10286000171E7BDEF060FCE3E2020EFF42974AF0A7
+:102870001F9B3397E46466E772A613FE43BE34FEE3
+:102880009B627AD7F24BB6133DB76C7C2FBD7C5A56
+:1028900068F05BDF26E4D2DB0C72A951AE7C71904C
+:1028A000F067BB98EB3BBE57F932E76BD7FA5E2572
+:1028B0007FEF749CD8674982CED29C2A1B8974C44E
+:1028C000BC744EBE81EF9DE6E2BBA03ECADFCAFCEF
+:1028D00094DECE0274BE4E00468CF93B18A37BE416
+:1028E00087232696E0DDB8B143C70EC0EF21EFB2D3
+:1028F000BD87F39BAF7AFFCB11F22EDBEBE39C7429
+:10290000BFF2755B1AC95FB80F2D21F6C0B7E17C25
+:102910001A00E7C76138BF307D13CEAF01B0DE5F6C
+:10292000C3F985F9DBB296326C37DEA98FDB91ED06
+:102930006F778C05C5A467F8DD9EFB723F84EF3B83
+:102940003199E3D07EFE4ECCF5E370BDEFC4F43197
+:10295000F1D4AA513A78FF80EEE443B90F82E38DB7
+:10296000A7F18CF095F034C251C2F75F80E7E5EE35
+:10297000E0F995909F3B6DBF8F4A4845FF5D947885
+:10298000C7F237B92AE44FE3D412315EF5269AE74D
+:10299000A8FA1B987928F96D7210AE35360E2FA360
+:1029A000DD8A6DED630A8DDF3DA379C3B2619CCFF3
+:1029B00036AA746FFCFC8B61648F3AE5E7F6B6DBF0
+:1029C000156F5436CCAF4675AEC1F747D93BFC9D69
+:1029D00033F6CDE194C991DF814EB7F2FBF635B6FF
+:1029E000F1DDE251EA53D12E0FED7326DE8B9472A6
+:1029F000453F2B7F9740BE5FD8939C313C9CF3C1F1
+:102A00007E56CEB7255EA11DE593A09FE1C0E7925B
+:102A10007E1A4EFA45636F4F06AE4FDA113AFB4508
+:102A2000F891DF8E0A64D3BB5C8547548A277E5DAC
+:102A3000C4777D2FBBCE9E0A789A94EE756793BEBD
+:102A4000F98D8A7CE65D58671CDA1F8E0CB593FE03
+:102A5000F81DF5D011D9825FE4B25CDD7D35497790
+:102A6000AA9DE2773A3FE0F7F116BDCDE33617F5C0
+:102A70005629FEDF1817378A65FC14ED8D637B59E4
+:102A8000DC7E6790BFC87780AC0926E60C91B3C3A3
+:102A90009CE1CC19329F88AC585D3ED2DD57573F40
+:102AA0007A44AAAE3CC63348571E5798AFCBF72E90
+:102AB000BE5157BFCFF431BA7CA2F7365DFDA4CA30
+:102AC000C9FA3CEE3B807B72DD4C5DBBFEF565BA1E
+:102AD0007A2E5F95AE9CF93CAD59F1C8C7F95FDA23
+:102AE000EA45BAF2A7A20A79FCB87D0EDD534C6F15
+:102AF000FA81AE3F89DFA4388E5FE6E4E7830FFEFC
+:102B000023BF85C0734182FEDC18EB18FD8683521B
+:102B1000BD5D23E92A71500FFCAB7450CBF474D027
+:102B20008BC7F114BC3DD489728C11FFE88F085D0E
+:102B300027FA2342E182FE88D03CFA2342EBA33FEE
+:102B400022B41CFD11A1E5438FE8F13FAC558FFF86
+:102B5000EB8F8EF9A778BAA14D4F0F463CDD744A32
+:102B60004F1FA3BCE10497B1208F21BD4B3C4D8783
+:102B7000FFE89C67C5D16837B88579E85EC0FF1665
+:102B8000BE5EC816F62381AF2FD99A61F8CEE5C58F
+:102B900052CEC77B3AE79FEBEF7909F9EE09E4F3F0
+:102BA000C3AEB403C87852DF188E4FDFB130E2579E
+:102BB0005F9BDA22F1FCF8BEDA4676F944D6F126BC
+:102BC000BE3FE3E8E53D84FCA80F460F40F993F3D0
+:102BD000EECCC3736ED6AFAC2928D7CCEACFDF13C7
+:102BE00064396DF44E8B9CCFAC241E7FF476B6E036
+:102BF000D36E1E87F46E36B7FF44BA1D14075D9A74
+:102C000023DEA131B3945983910EDF0DCB443A5B9F
+:102C1000CFED5C6D1627C5B5F8801ED14F89F23611
+:102C2000CAC3C9421E6DFC93CDC6E98EE9CEF781B9
+:102C30007E9B2E0E377B8743971FDC9CA0AB3FE427
+:102C40008053579E17C8D2950F3DE2D6E587B58EC3
+:102C5000D0D5BFFEA84797BFA1AD5057FFA653C51B
+:102C6000BA7C12EB7802E1A9E6A4123CFA2BC20E60
+:102C7000E0E47899F5FD78BA4F23F5081997ED153A
+:102C8000746CD447FA6B5E8AF36E4C646EBA0F6252
+:102C900013FA20D3EB295E11572DE579E6D3C755FA
+:102CA000CB78EA2E7D46E82F529F0889A7F6E0FCF4
+:102CB000653C7517DEC5FB9246FA74E408BF906167
+:102CC0001DFD357EFFABF1018DEEB1C8F919E73579
+:102CD00043C4036EB375FFFE504A0EB71B6C4E2DF6
+:102CE0008ECF817ACFC0F144F0BC623C779B0FE07D
+:102CF000DBF823CDBDCC79F5F1660DE1EB29C17789
+:102D00005573E89D4EBAB726C7CD15E3F6CA55BA36
+:102D10005DDFAC681EDFC5A235BA77D1F3781CAE93
+:102D2000091A5B4EEF24897B08F7AC695E9B094565
+:102D3000255A9385BFABEFB7A09DA8680CC88179D1
+:102D4000C027B6ED5B6F07F9E7997A33D97D86E541
+:102D500024DFE91B10BC57D21FF434A49322C43FD4
+:102D6000F4FBFC601EEF7C670E5F5F81FA4DD77D40
+:102D700000AB8ECF73FDAF1BBA237A94EBF8BFBACA
+:102D80001F20E9D70827A95F33717E0D10F392F059
+:102D9000EBB29F08F8C9FB19CE8596E22D76BAE70B
+:102DA00051887165127F070773BA5C2DE081F59039
+:102DB0001FF554AF40CD89463B782773463BAE6242
+:102DC0000FFE3FBA3741F0EFE9BE574F7CE20AFEF3
+:102DD000D0C3FDAF9EE893FEBEC33DB0103EC1E33D
+:102DE0007D043EFC034CE4575F15A9DFC7FB73B8B5
+:102DF000DDA544EC2738B7ED797A3EC1D0AEDFB817
+:102E000042157C624ED7EF4FE0F7D92B2C245F336D
+:102E100056FC18C619FC65BD85E262477918C931B0
+:102E2000651B15FF6605CFD1910938FF529FFE3C07
+:102E3000BE85B957A2FFA37CB5FEFB5C3BFF9D8A14
+:102E4000D9C6775384BE3EF72AFAFA8E1C718EBB20
+:102E5000999BE42EE1FFAF146D8C7257A79FFBCDB9
+:102E600050DF56B9DD89E2C6E4F9EE44FF4DC87B78
+:102E70002000CFF02C3CC7979BBB8DE7EB82670F00
+:102E8000F10AE7EC225EC1CEE3333AF78671FFA682
+:102E9000F42B89FAE77C97A81CEB636FE7F378DCE7
+:102EA00085F42719FD559D7613F95B3AF746927F15
+:102EB0001EFD38D14007674C7BE247B882F3F3B67A
+:102EC000A93A3F8831F52E7D89F4C58169DEDF217D
+:102ED0005F3F6B76DBDC907FD0FE3ABD1F5524EC64
+:102EE0005EC6F976E95D23F9FB2E9D3E2ECF761660
+:102EF000F27738802F32DC47320E6112032D15D263
+:102F0000D2C00D349FEFEACF9972398FFB312FDF9A
+:102F100044EDBDAB6FA07CFFE56B17E23D98698D7A
+:102F2000732DE8C26E7B62494138346D4BF62F0B2E
+:102F300047BC8D56BAB5CB5F12786B33C4D7CBB4D0
+:102F40005CF0237C438EF3251187B454A17DB048F7
+:102F500061322E89F8B8CC5F6A12F9029E5FBC829A
+:102F6000E7DBC4FBFADB851D05D78D29AE1BF5FE1B
+:102F70009DC2CE82EBC614D78DDF916F611EF9160C
+:102F8000E6916F611EF916A6C8B7F07B192B4EC9E2
+:102F900053B91F6A5CE8BEBB6C63E342F60BFAA14F
+:102FA00042F3E8870AAD8F7EA8D072F4438596A3DA
+:102FB0001F2A348F7EA8D0FAE8870ACDB311B7064E
+:102FC000F3C8E73C9374F92920E78F0BD9DFE88732
+:102FD0000AED1FFD50BAFEBC0B75EDEF66F5BAF6B3
+:102FE000E8870AAD7F6FBDA2F353DD2BDE392DDFFD
+:102FF00010C7E9C759EC1E0C74F05F11FFB8DF92DF
+:103000008A786E99C7F5B27037C7735321C7BB89E9
+:10301000713C77CC203C2FD178BE80C7271BE907B5
+:10302000FD3DE32CDCDF8329FA7B30457F0FA6E8EA
+:10303000EF1997CEFD3D98A2BF07BFA3BF0753F47A
+:10304000F7608AFE1E4CD1DF8329FA7B30457F0F63
+:10305000B6437F0FA6E8EFC1EFE8EFC114FD3DF8DE
+:10306000FD18FA9D2CC179A11C3F40A73F021DEA23
+:10307000F447872E8F727C687D94E343CB518E0F8B
+:103080002D47393E348F727C687D94E343F3753964
+:103090004EDA5F28CF87B643793E343FB8C9F7266A
+:1030A000DACE266CBCF006A66D91CA330AB08C85C8
+:1030B000BBF6DE897EB9B63025250638A74579E509
+:1030C000CE7190F78AF8BF5CD661427C7BC57BEA03
+:1030D000DE00A378CBC17F4DA4F217C4BD7EFA03F6
+:1030E000BCE7ED65F4BB24D25F2CDBBB9943C55430
+:1030F000D60FE6BBAF671C5FD623FE19320FBC01AB
+:103100008CF12A794BECF918EFB9DDA4509CC4F688
+:10311000653C4ED84857DB045FDA6EDAF33ADE03DB
+:10312000E92855E83E7086991DB1E4239CEAF2F146
+:10313000FC5D3B3846ACABEE46BC6F22E72DED9B09
+:10314000C027E8FEDCC88ED6B1D1D08FD7379A7EA3
+:1031500027A548E37203B6437D32DBA778B684D057
+:10316000F7E38339DFF4FAF8F83FDF3491B70BE780
+:10317000ED7EBE298AE03871B942F1522377320FD1
+:10318000DECFF58B7967EF0CA8385EE9723E9EECD6
+:10319000B774630ADD5B2C656DE312C847A230E4A7
+:1031A000DB126EB0BE37707DA0361C41FBF4B5DE7D
+:1031B000FBB9F9BA98028CA3632D8CDEB19C70DD4B
+:1031C0006F75EB25B40FA77EE95CCBF429F45EF0B4
+:1031D00044DFD265A86E4CF02D7CB337D6DFCADC55
+:1031E0002E271D45742F56CE6790678F098E459602
+:1031F000C35A4D610AE29B1D8E0BA11FD8F95311D2
+:10320000DF796E0BBDDF3BC9ECB0D0FB113DC49F35
+:103210005CB2CBF81383BC608833695C723405ED13
+:10322000C98B224D64FF5DF412FF3D00EF0685F867
+:103230009A94834A459CDAA5E56FF6BE0BE1BEC7BA
+:1032400042FDC9F893DA347F8A09E3EAFB6ECE8D3A
+:1032500055490EF8FD6094037CBFBC7304D65BC176
+:10326000DFB1BCB47C5A74807AE2FE9A0A01AF0ADC
+:1032700011C7548A0F7AABC1DFD392F73B5813972B
+:10328000F7A43DA7F43743DF42FC963E2DDE955E62
+:103290005D4AF7B28D7144F3965B28EE689E412E2D
+:1032A000AC167261F555E4C2B3830D72A1FCBD1476
+:1032B000D186A9FDFE80717BF25E628985EFFF9267
+:1032C0003D8CECB0254BC79AE81DE49738DD942C73
+:1032D000E5F24DC9CB1EBA5F28E5C5F7851C33F969
+:1032E0007212C1FDF7426E9986F19500DFA2B630E9
+:1032F00011879548E95D9779BCE5643BE7036D0765
+:10330000F93B109D3E2B97A7DE60FC1D33035D4EFD
+:1033100032FB4D78E1CE3D12E812F213500E82FEE0
+:10332000A6A35C148774EE2AA0F8BD4285EEBD18F2
+:10333000E9BCC852F726C687166D636E1F0BA573CE
+:10334000A05FECCFA7D0FB005EA1D74AFA35D2FB35
+:10335000AC08618FB2737B53975D0265547CA4DB2C
+:10336000177517CA8DB3D0B7D797130CC69D45E60E
+:10337000F0F2F4DD51772D4725A7073B85FA038D41
+:10338000E0E195EF20F46037407B01F2C97BEECBA2
+:10339000D3CA42F8E49743C6140CE91DC47759D741
+:1033A0007DBF1C7A1774D183E9F47B383DC9C3E52E
+:1033B0000057DC17B3A2DBEEC75F661B97CB3CE37D
+:1033C00046E0EF0B32F9087900E308678AFCC2DCBB
+:1033D000EBFF88BAEDAC089EF7ECEE7717C685D404
+:1033E000DADAC623D92DC8F116E23DC6207F2AF6C7
+:1033F0002429C89FF202A813CEC810E78FC11EB1BE
+:1034000030D7C9D769B04B94E770BE2D7F17E5F868
+:1034100083FB77E37925E77FBC87DF6198976BFAB9
+:103420005FBD0761BCFFF0FDBEDE99B9D0FF63262A
+:103430007E9FBFAFDAC4847D88FCC2925F30F10EFC
+:103440004610EF1E7A47B7F141C5116A9FF2AE569A
+:10345000F83DFA1EEC382CABE3896DD06E568346EE
+:10346000BFE3B72983D3CF26A01FFABD14ADF54D16
+:103470009B2B08C78FEB1FB1D0EFD2B0403ABEBF35
+:1034800033B32ECC8DFCF8CB21C575B9C3F0F7480A
+:10349000DCC4870A30861CCFF35EC58B713DB56BEB
+:1034A0000E3D83EF092C6871D1EF95941EC85B899E
+:1034B000EF9C7C39C45B8FE5A57607BDA7317F798A
+:1034C0000C9D5FB3FA887BA1AC83FC6C12FE4DC2ED
+:1034D0007E75AB9B89DFDB12F71D80414ED2D5EBA9
+:1034E000DE8E27ED84463B83F17D899EEC0BD29ED8
+:1034F00080F6032DC4CE28ED1396ACE333506E282E
+:10350000D1F4F712657A2857E8B9420F9CDD756E41
+:10351000E58CEF83F2F13AC541EF4DDA9D77DD009E
+:10352000F98A23168CEC6445B14E0DDF1FE800FCD0
+:10353000627C7419EC57E43325224EAB62C30DB4A0
+:10354000DF2AFC9076F30EA74CEF5E7738F965A47E
+:103550009F8087FC96150E8F161BB2EFCB9B14DD58
+:10356000BB0332BF2797DBE34A602B23FCEEB9CFC6
+:10357000A5E1DB3E25204660FCDFA15CA7CE7F0CE9
+:10358000F5281EA42895BDC5DF818779BBF878F999
+:1035900021FD9735F17BD3320FF549FE793537920E
+:1035A000F057EA8075BB3075D03C010E04A78EB58C
+:1035B000D09F93C6217C9407FC16D4B74B300E05E0
+:1035C000F2331D7E0B8E53B69CBF63E25DC3C7F121
+:1035D000AE8ED106A37C647668C9083FF13BAD305E
+:1035E0003F92232B002E781F0BEFBBE1D962844F53
+:1035F000A9986F45530CBDA310FCBECE82F898D19C
+:10360000C3BB08E705DD962D1F4DF7D72BCC1EBA9F
+:10361000E7E015F0FDCBC2B087D03F3063FDE31685
+:1036200017E43F11F47B5EECBBA2D4403ABD57B423
+:1036300030CC8DF39CE168A2F575C1F7518087828B
+:10364000EFDC14137C812E7C18B757B15E8FCFE06E
+:103650007C387C2BD697D27E9B63F66A8ED0796CB1
+:1036600038948EF7AA66C0FEC6772598C34BF72517
+:103670003F7DF4AE145A27CC13E11AE9768EC7F7D2
+:1036800087804EF83D18B11E79AF5B8E6719C2EF87
+:103690009D5A8670FB59CFFBD243724D23E017ED44
+:1036A000DE3DED4B0D19378CAB55F0DF9130EE530D
+:1036B000B93FE5BE94FB54EEDF672CC5810425C8F5
+:1036C00067E09CAD7BB11B38150CE1789829F00AB6
+:1036D000707D23F49E57EE10BE9F4B52F5FB1DFBF1
+:1036E000C37EFB0EE1782F191348C77799647D39A3
+:1036F0006E492C6F87748FF4D6578C87F517517DE0
+:10370000938E5F9477F18B9D2BE2915FEC51B81F04
+:1037100074EDE1E4EFA3FCBA8BCBAF676BB6CDC71A
+:10372000F39299FD29A1EFFBCF063907F9C41C716B
+:103730003E5704BAE7173B33BCD94342F673C5CFB3
+:1037400076657839BF0920BFF9F3AE573FBCD11970
+:103750003C4FE57ACA56FFD6526A0F859F22DE1D7E
+:10376000E9A4FB78E576CD89F1CEE5CB4B89FFB2B4
+:1037700004900B9590F833035D942E57E81E597909
+:10378000FD70BFFABFC8A7CBD74CA2770F24DEE4E9
+:10379000FB2CF27C95F39F28F0356908DF87330511
+:1037A0007DCFAC1CAD25F622B91BC32CD90CF17D05
+:1037B0004685FE7B17DEBAFCD7392B71BFE0FD22B0
+:1037C000D24FD658B8BD6F27B73F9E5DB4FFBD3B03
+:1037D000A1DE99C736A730558F379453E70879751E
+:1037E000AEB0FF7583B73294DB647EEE268EB7F2FF
+:1037F000DDBFF904DF132B4915FC6E2D7F07A0AC4C
+:10380000790FE171C6EA751617CA75435CBAF736C7
+:10381000CAEBF21C68579EB97AB305F9C4A2211C01
+:103820008EC6FD5022E284259CF15C5242FC1BB204
+:103830003EF2477CFFFEBE85615118CF23C7794A0F
+:10384000D07D795D4C2C8E575E57FA13D487E4797E
+:10385000605CE78930BE5FCAA03FDCB72746BB5338
+:1038600016E504E55963FD47041D3E65E1BF53932A
+:1038700014D1FC1CC5352C087723FF1830A0CD8F40
+:10388000E3227DE3BC3513FF5D9B01356D9FE33C77
+:1038900040D4A6B81A4CF17D2C14BDE321BFC5C499
+:1038A000EF6FA5AA3C3D20E003E5012C67BDDAE8F7
+:1038B000F73542E26675F4ABB1ADF4FB895A2F4699
+:1038C000EF9B497A95FD487A95F4DCD3FA9AAF716B
+:1038D0007D275C1C9E9AF8DD946B5E9F95FF8EAEF3
+:1038E0005C979C1FC8F01E7ADFE38783C9DE736292
+:1038F000A93B05E3267B5EEFFA82F86ED66B5CA7E8
+:10390000DC373216BECB9FD5C4FD0E271438DFA09E
+:10391000DD89856114DF26D7F55DEDE11F0C899502
+:10392000EFF947A29C59121EBC2F8FF03B56CF7F58
+:103930005F577E9772817C674EF2EF9375E2DC648D
+:103940006D6B717FB3FA347AFFE458D389487C8F6A
+:10395000E5C4683E3FD9EE3E0BBF9FCC223527DE43
+:10396000138BB8EFB7057DD03FB4DE95A740BB7B86
+:10397000EA871EC3F7C7EF59DE87F4FBD976E74A1B
+:103980003C1767FB5CE40F8E589FF729BEA3377B7B
+:103990007936FD6EEF7D0A2B267D52E8097358D7E4
+:1039A0001FE90973055F9B8BFC12EF4BD51FA677B0
+:1039B000F3E6B8C3F2F07C9FBB81EB094526B61A4B
+:1039C000FD89FD1B8BC7231FEB7842E1BFFBBC5178
+:1039D000FF0E577666F1453C1F8CEFDEDD6769F61A
+:1039E000E03A18C82368779A6D2FE672BDE09FC74A
+:1039F000D6B7D3EF6522BCE9F7720CF69BFE1ABF6F
+:103A000047DC1169227B1CE0FD7DFC3D327C6FDDD3
+:103A10004AE78DDE7ED3FFC723E8F7DAE43DA10A4B
+:103A2000E177FA7F89106A7A0080000000000000C8
+:103A30001F8B080000000000000BCD567D4C535733
+:103A4000143FF7BE7E53E8E31B44B08060B7157C9B
+:103A500005257126FA066A4C66B4B8A13451A851FE
+:103A6000192A65CC2C019739AB9DCE68B6B10415E7
+:103A7000892C8529FB675B4A249B666C6924CE6C84
+:103A8000928CC83F266CA4240BA299A16359906420
+:103A9000D39D735F9B1A3F92FDB9F7CF79F7DEF3A1
+:103AA00075CFEF77CE7B506FE29005D06C02F1ECD2
+:103AB000ED7B2D0BAC28BB25B05702F4D0E62A8055
+:103AC000135D35591127C09E4FD69FF597011430CD
+:103AD000708750EF375DA4165600CCF465A71D65BE
+:103AE00078EE0B94029EEFE9FBA080E44C9FB93E78
+:103AF000887AEBE4DA75A919004D17525D921DE042
+:103B0000113D6BD18F82469900FB7D35D95004D091
+:103B1000F270E453B918E31702C8E8F7AF5052D077
+:103B20008F2A2D47AE14481C40317A7395950007B3
+:103B3000F8F0B655E8E71E0B0EE40A7D7BB66C4D37
+:103B4000F87D524E1F01B01B017CEFDD167EEEF3B7
+:103B5000D1CD1EB46FF15D4E213F07CE8C57C9B851
+:103B6000FF42B1B744C924BF7D03B28477EFEE2B87
+:103B700077E33D4A1510796E4A736FF3605ED11F8B
+:103B800025A5DFFEFC78CD5730E9CAC47A67D06638
+:103B900000AC9F370C0699A40C86349433127484BD
+:103BA000506E2A82C6ADD6C4FEAA585D666C9D05CD
+:103BB0006EDCDF3770AEC08EF26EB2B6DE31B0FDB5
+:103BC000274841FD8B4603E1E5D5814141BBDD7EC0
+:103BD000A6065142731A406E227E8D92048075DBD8
+:103BE000D78D49A527F6018262FFAE0E36521E4BD5
+:103BF0000251D75B282774E1BD84EB449B59F11730
+:103C0000124E7691CF44A7B481F6FD6F332861B48C
+:103C1000BE9CBC14E337D8A08DEC935784C21C71B2
+:103C2000F60DA556481AA504BF5A656DB15EB26E71
+:103C3000C8C3F383834C36A2CB8357AF6F006D0D9F
+:103C4000C09E5FCFFD0F5683FDB1BCF70F0D1AEC80
+:103C500018AFE50BBC2FC66F090DFEB008FDB45EB2
+:103C6000D955A9C5ED04A8C23CE815E3B40E6975A1
+:103C7000F10D4D19763B137E7639D24EE421B64DC7
+:103C8000A135DBCFA0DE2EC2ED6580C3E515F5477B
+:103C9000979294C5BD41172D7027039C72DC327832
+:103CA000C9CFFB317F8E5B278AC47D6BD3E1313E68
+:103CB000BCA1E8855DDC1EEB21ECC23ECB49580E71
+:103CC000A0B65A7524033E6B0AC90B6DDCA1C3BABA
+:103CD000AACCA24858EF0E534A39D800E6CD9A1C18
+:103CE000B668B29DBB079B30C5793E6606E47DBBD6
+:103CF000D4C948AE75B631AC34C819DEC3C4DF1CB4
+:103D0000083110850833CA7BF6BB3B95147FCD92F2
+:103D1000C89F8029E9995ABF0EF9715C9105FEE0B0
+:103D20008C5412CF33AF4123F1AB570F27CD15740D
+:103D30006F376C2D232FF84EB82FF0E025CC6F98FD
+:103D4000853F23FFF1FB5E25BEA21FB7D17A9261AA
+:103D50009E06BBF723CA630BD397B93861209590B1
+:103D6000FF59BD760E9DE75413F2A25AA305E473E2
+:103D7000F00352D6B028C74ABC66AA0A1D18FF989D
+:103D8000F3DA6EE2C7E9A8098C183710AB4775D48F
+:103D900032C5502F7FD1460EE5A86FCF801D687FBA
+:103DA000CDC9FD46CCF3349882A40FA6F56AC4A110
+:103DB000C57884F3C5C0CDAAD01FBEB1C050E649B6
+:103DC0007F8CD8503FAF9D2901D469989BEEFD1997
+:103DD000E50E08BAA8AE5B32BC9FD3BC999CDB3819
+:103DE000E5457C4FCB2113F5193D8FE73F7C6821DA
+:103DF000258D27F29A8D4E7FF9CD0A922685A15DF9
+:103E0000F5B01436963F9DCF6C8E5D4771502FCC28
+:103E100049DFCA838C91FEC86DCAAFDA640D4B29A5
+:103E200064A7FF3D624AD8C1587EEAF44B20207E49
+:103E300094079015D0705B13EBC3382E37152E7096
+:103E4000B919C3275E3F913CF6C74193D61FDF5B8C
+:103E50000776127FE2FDFA666C7FEE41918DE6CB2C
+:103E6000DC70B10D9CCFEFCF719CAFB00CE75CA1C3
+:103E70003A4EB8E3A39AD07F5DAC3E8837905F2975
+:103E8000E6B72E56A73A2BD7EAF2FA137589F12432
+:103E9000CE8378DE719CE3F8C13B63D76D8502B7B2
+:103EA000B28F41E0F52BC59F5C183D8E6D058B24CC
+:103EB00075CA5BF87FC42B6C5E86BC8E9EE14A3F60
+:103EC000F19F0A5F21A4CAF17EE000310F1A248B12
+:103ED00072EA19F3C04BF36039CD834ED1E7F33C5E
+:103EE0007A9D339A076D629D03D1A33A5C4FF248E5
+:103EF00032E51B3123EB5116BA8AC43CCAA38E2E7D
+:103F0000D670A2BEEE3D94DC7F0AF5034C3D6F42B5
+:103F1000FB803ED6EFFBACC14BB83F1BE47E3DC6F9
+:103F2000EB4A0D9E6FC2FDAEBAC58A1FEB340B3152
+:103F3000BD668B980BAB3917EBA8272BD85F48FAD7
+:103F4000D8D778CF2ECF8BE23BFEF543744EF72EB9
+:103F500001EDDC05A5DD745EEB10FEBE8DCF990F83
+:103F60009385BFAE5A35D722CEB338D91F4FF7E667
+:103F7000B93209574D0F7F04845E4F8F9A4B78F406
+:103F80006C3508BDB3CCEDD94B7ECAACCA25F41B49
+:103F9000F158BE1AD0E00833DC9FECD0EE1BE7AF3F
+:103FA000A7549B834BFC53E7E93FC45F0D8E36E477
+:103FB000FD24F17079021FA6221669099CE27CF4A7
+:103FC000EB11AF0C0DAF63EC69BC326278B10EE45B
+:103FD0006D0AE11612F59FE71A0EED124492F04EAB
+:103FE0001257728C282732BC55DA3DC772E9BCC122
+:103FF0001859D9E9243CA139F48C3E7CC5A5F53982
+:10400000D0571479DE18E379639C8FEF3EC1C7C89F
+:10401000E2D4E9A4181FD1FE178BBB86E2DD67E36B
+:1040200055B439FA8F54FFAC389B5CDA7FC99CD108
+:10403000FB2AE9C3C56C2EE688ACF5F5A8EB4E3E2D
+:104040007D67E0EF91C5F4DDE94D776F263DF3D252
+:10405000A8C14BF5CC8DEAE93E939E7BF9F43FD3A2
+:10406000D87143F4CD7FCDF35F8E8A94E2B00A001D
+:104070000000000000000000000000180000000028
+:1040800000000000000000400000000000000000F0
+:1040900000000028000000000000000000000010E8
+:1040A00000000000000000000000002000000000F0
+:1040B00000000000000000100000000000000000F0
+:1040C00000000008000000000000000000000000E8
+:1040D00000000000000000000000000000000000E0
+:1040E00000000000000000000000000000000000D0
+:1040F00000000000000000000000000000000000C0
+:1041000000000000000000000000000000000000AF
+:10411000000000000000000000000000000000009F
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:10414000000000000000000000000000000000006F
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:10417000000000000000000000000000000000003F
+:10418000000000000000000000000000000000002F
+:10419000000000000000000000000000000000001F
+:1041A000000000000000000000000000000000000F
+:1041B00000000000000000000000000000000000FF
+:1041C00000000000000000000000000000000000EF
+:1041D00000000000000000000000000000000000DF
+:1041E00000003328001000000000000800003330F9
+:1041F0000010000000000002000033280010000042
+:104200000000001000003A780000000000000008E4
+:10421000800000000000000000000000800000009E
+:10422000000000000000000080000000000000000E
+:104230000000000000003120000000000000000825
+:10424000000033600001000400000001000033683A
+:1042500000000000000000020000337000000000B9
+:10426000000000080000337400000000000000029D
+:1042700000003A70000000000000000800003A4012
+:10428000000800000000000800003D880040000019
+:104290000000004000003A50000800000000000844
+:1042A00000003A60000800000000000800003A88A2
+:1042B00000C800000000009800003C1800980000B2
+:1042C0000000002800003C58009800000000002872
+:1042D00000003378036000300000036000003EB04F
+:1042E000000800000000000100003EB100080000CE
+:1042F0000000000100002008001000000000001075
+:104300000000200000000000000000088000000005
+:10431000000000000000000080000000000000001D
+:10432000000000000000000000000000000000008D
+:10433000000000000000000000000000000000007D
+:1043400000000000000000008000000000000000ED
+:1043500000000000800000000000000000000000DD
+:10436000800000000000000000000000800000004D
+:1043700000000000000000008000000000000000BD
+:1043800000000000800000000000000000000000AD
+:10439000800000000000000000000000800000001D
+:1043A000000000000000000080000000000000008D
+:1043B000000000008000000000000000000000007D
+:1043C00080000000000000000000000080000000ED
+:1043D000000000000000000080000000000000005D
+:1043E00000000000000000000000000000000000CD
+:1043F00000000000000000000000000000000000BD
+:1044000000000000000000000000000000000000AC
+:10441000000000000000000000000000000000009C
+:10442000800000000000000000000000800000008C
+:1044300000000000000000008000000000000000FC
+:10444000000000000000000000000000000000006C
+:10445000800000000000000000000000800000005C
+:1044600000000000000000008000000000000000CC
+:10447000000000000000000000000000000000003C
+:10448000000000000000000000000000000000002C
+:10449000000000000000000000000000000000001C
+:1044A000000000000000000000000000000000000C
+:1044B000000000000000000000000000000012C822
+:1044C00000800000000000800000000100000000EB
+:1044D0000000000000004000049000000000049074
+:1044E000000019C800000000000000080000494852
+:1044F0000008000000000008000049280008000033
+:104500000000000800004938000800000000000812
+:104510000000200800100000000000100000200033
+:10452000000000000000000800004010049000405F
+:104530000000004000004998000800000000000151
+:104540000000499900080000000000018000000000
+:1045500000000000000000008000000000000000DB
+:1045600000000000800000000000000000000000CB
+:10457000800000000000000000000000800000003B
+:1045800000000000000000008000000000000000AB
+:10459000000000008000000000000000000000009B
+:1045A000800000000000000000000000800000000B
+:1045B000000000000000000080000000000000007B
+:1045C000000000008000000000000000000000006B
+:1045D00080000000000000000000000080000000DB
+:1045E00000000000000000000000000000000000CB
+:1045F00000000000000000000000000000000000BB
+:1046000000000000000000000000000000000000AA
+:10461000000000000000000000000000000000009A
+:10462000000000008000000000000000000000000A
+:1046300080000000000000000000000000000000FA
+:1046400000000000000000008000000000000000EA
+:1046500000000000800000000000000000000000DA
+:10466000800000000000000000000000800000004A
+:1046700000000000000000000000400000180000E2
+:10468000000000180000430000400000000000404F
+:104690000000430000400002000000010000430150
+:1046A0000040000200000000000030000040000058
+:1046B000000000408000000000000000000000003A
+:1046C000000030000008004000000004000030043A
+:1046D000000800400000000400004B00002800001B
+:1046E0000000002800004B500010000000000010E7
+:1046F000000038000080000000000080000038004A
+:1047000000080080000000020000390000200000C6
+:104710000000002000002008001000000000001031
+:104720000000200000000000000000080000510808
+:1047300000080000000000080000512000080000F0
+:1047400000000008000051300008000000000008D0
+:10475000000051C00008000000000001000051C12D
+:1047600000080000000000010000394000100004B3
+:1047700000000004000051D00030001800000010BC
+:10478000000051D800300018000000028000000036
+:104790000000000000000000800000000000000099
+:1047A0000000000080000000000000000000000089
+:1047B00080000000000000000000000080000000F9
+:1047C0000000000000000000800000000000000069
+:1047D0000000000080000000000000000000000059
+:1047E00080000000000000000000000080000000C9
+:1047F00000000000000000000000000000000000B9
+:1048000000000000000000000000000000000000A8
+:104810000000000000000000000000000000000098
+:104820000000000000000000800000000000000008
+:1048300000000000800000000000000000000000F8
+:10484000000000000000000000000000000023E85D
+:104850000080000000000080000000010000000057
+:104860000000000000002008001000000000001000
+:1048700000002000000000000000000800002DA043
+:10488000000800000000000800002DB8000800002B
+:1048900000000008000024E802D00028000002D038
+:1048A00000002E58000800000000000100002E59F2
+:1048B000000800000000000100002D90000800002A
+:1048C0000000000880000000000000000000000060
+:1048D00080000000000000000000000080000000D8
+:1048E0000000000000000000800000000000000048
+:1048F0000000000080000000000000000000000038
+:1049000080000000000000000000000080000000A7
+:104910000000000000000000000000000000000097
+:104920000000000000000000000000000000000087
+:104930000000000000000000000000000000000077
+:1049400000000000000000008000000000000000E7
+:1049500000000000800000000000000000000000D7
+:1049600000000000000000000000000080000000C7
+:1049700000000000000000008000000000000000B7
+:1049800000000000800000000000000000000000A7
+:104990008000000000000000000000000000250072
+:1049A0000040000000000008000025080040000052
+:1049B00000000028000009C00120001000000008CD
+:1049C00080000000000000000000000080000000E7
+:1049D00000000000000000000000402002D000287D
+:1049E000000000080000300000000000000010007F
+:1049F000000050990000000000000001000050B0CD
+:104A00000000000000000002000045A00090000827
+:104A1000000000088000000000000000000000000E
+:104A2000000029600008000000000001000029616A
+:104A300000080000000000010000297000080004C8
+:104A400000000002000029780008000400000004B3
+:104A500000002FB0000800000000000400002FB488
+:104A6000000800000000000400002FC0000000004B
+:104A70000000000800002FC800000000000000082F
+:104A80000000300000000000000000100000504056
+:104A900000010001000000010000500000000000C3
+:104AA00000000020000008080010000000000004C2
+:104AB0000000080C0010000000000001000008B712
+:104AC0000000000000000001000008B60000000027
+:104AD0000000000100001000003000180000000479
+:104AE000000010040030001800000004000010084E
+:104AF00000300018000000020000100A003000180A
+:104B0000000000020000100C00300018000000013E
+:104B10000000100D00300018000000010000100E11
+:104B200000300018000000010000101000300018D4
+:104B30000000000400001014003000180000000401
+:104B40000000300001000080000800040000300474
+:104B500001000080000800040000000A00000000BE
+:104B6000000000000000306801000080000000012B
+:104B70000000306901000080000000010000306C7E
+:104B800001000080000000020000306E0100008083
+:104B900000000002000030700100008000000004EE
+:104BA0000000307401000080000000040000306646
+:104BB000010000800000000200003064010000805D
+:104BC00000000001000030600100008000000002D1
+:104BD0000000306201000080000000020000305040
+:104BE000010000800000000400003054010000803B
+:104BF00000000004000030580100008000000004A4
+:104C00000000305C01000080000000040000307CE7
+:104C100001000080000000010000307D01000080E4
+:104C20000000000100001C1800100000000000043B
+:104C300000001C30001000000000000400001C38C0
+:104C400000100000000000048000000000000000D0
+:104C500000000000800000000000000000000000D4
+:104C60008000000000000000000000008000000044
+:104C7000000000000000000000004C1000080000D0
+:104C80000000000200004C120008000000000002BA
+:104C900000004C14000800000000000400004C203C
+:104CA000000800000000000800004C300040000830
+:104CB0000000000800004C00000800000000000296
+:104CC00000004C02000800000000000100004C043D
+:104CD000000800000000000200004CD000080000A6
+:104CE0000000000800004CE0000800000000000484
+:104CF00000004CE4000800000000000100004CF03F
+:104D0000000800000000000200004CF40008000051
+:104D10000000000200004D00000800000000000438
+:104D200000005000001000000000000400005004CB
+:104D300000100000000000040000500800100000F7
+:104D40000000000400001400000800000000000241
+:104D5000000014020008000000000001000014041C
+:104D6000000800000000000200001410000800000D
+:104D700000000002000014140008000000000002FF
+:104D8000000014160008000000000002000019B81E
+:104D900000080000000000080000142000080000C7
+:104DA00000000002000014240008000000000002BF
+:104DB000000019C8000800000000000800002C10C6
+:104DC000000800000000000100002C110008000095
+:104DD0000000000100002C1200080000000000018B
+:104DE00000002C13000800000000000100002C004F
+:104DF000000800000000000200002C020008000073
+:104E00000000000100002C04000800000000000267
+:104E100000002C30000800000000000200002C32CE
+:104E2000000800000000000200002C340008000010
+:104E30000000000200002C2000080000000000011B
+:104E400000002C21000800000000000100002C22BE
+:104E5000000800000000000100002C2300080000F2
+:104E60000000000100002C240008000000000001E8
+:104E700000002C25000800000000000100002C2686
+:104E800000080000000000010000140000080000FD
+:104E900000000002000014020008000000000001F1
+:104EA00000001404000800000000000200001412BA
+:104EB00000C00018000000020000141000C000181C
+:104EC000000000020000141C00C0001800000008D0
+:104ED0000000141400C0001800000008000014278F
+:104EE00000C00018000000010000142400C00018D9
+:104EF000000000020000142600C00018000000019D
+:104F0000000015900008000000000008000015A037
+:104F10000008000000000008000015B000080000B4
+:104F200000000008800000000000000000000000F9
+:104F30008000000000000000000000008000000071
+:104F400000000000000000008000000000000000E1
+:104F500000000000800000000000000000000000D1
+:104F60008000000000000000000000008000000041
+:104F700000000000000000008000000000000000B1
+:104F800000000000800000000000000000000000A1
+:104F90008000000000000000000000008000000011
+:104FA0000000000000000000800000000000000081
+:104FB0000000000080000000000000000000000071
+:104FC00080000000000000000000000080000000E1
+:104FD0000000000000000000800000000000000051
+:104FE0000000000080000000000000000000000041
+:104FF00080000000000000000000000080000000B1
+:105000000000000000000000800000000000000020
+:105010000000000080000000000000000000000010
+:105020008000000000000000000000008000000080
+:1050300000000000000000008000000000000000F0
+:1050400000000000800000000000000000000000E0
+:1050500080000000000000000000000000000000D0
+:1050600000000000000000008000000000000000C0
+:105070000000000000000000060205000000000023
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex
deleted file mode 100644
index 54f36f1d256d..000000000000
--- a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex
+++ /dev/null
@@ -1,13178 +0,0 @@
-:1000000000004F48000000680000070C00004FB8D7
-:1000100000001ED4000056C800000094000075A027
-:1000200000009EFC00007638000000CC000115386E
-:100030000000DC6400011608000000940001F2706A
-:10004000000040180001F308000000A4000233285B
-:100050000000F378000233D000000FFC00032750AB
-:100060000000000400033750020400480000000FA5
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:10018000020400140000007F02040018000000FFB9
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200604203C0000001FBB
-:10024000020420B800000001060420BC0000005F8A
-:100250000204223807FFFFFF0204223C0000003F97
-:100260000204224007FFFFFF020422440000000FA7
-:1002700001042248000000000104224C000000009C
-:10028000010422500000000001042254000000007C
-:1002900001042258000000000104225C000000005C
-:1002A000010422600000000001042264000000003C
-:1002B00001042268000000000104226C000000001C
-:1002C00001042270000000000104227400000000FC
-:1002D00001042278000000000104227C00000000DC
-:1002E0000C042000000003E80A04200000000001C4
-:1002F0000B0420000000000A0605400000000D006D
-:100300000205004400000020020500480000003201
-:10031000020500900215002002050094021500203D
-:1003200002050098000000300205009C0810000043
-:10033000020500A000000033020500A40000003008
-:10034000020500A800000031020500AC0000000218
-:10035000020500B000000005020500B40000000620
-:10036000020500B800000002020500BC0000000207
-:10037000020500C000000000020500C400000005E6
-:10038000020500C800000002020500CC00000002C7
-:10039000020500D000000002020500D400000001A8
-:1003A00002050114000000010205011C000000010B
-:1003B0000205012000000002020502040000000105
-:1003C0000205020C0000004002050210000000407F
-:1003D0000205021C0000002002050220000000139C
-:1003E0000205022400000020060502400000000A69
-:1003F00004050280002000000205005000000007F4
-:10040000020500540000000702050058000000002B
-:100410000205005C00000008020500600000000109
-:100420000605006400000003020500D80000000675
-:1004300002050004000000010205000800000001A0
-:100440000205000C00000001020500100000000180
-:100450000205001400000001020500180000000160
-:100460000205001C00000001020500200000000140
-:100470000205002400000001020500280000000120
-:100480000205002C00000001020500300000000100
-:1004900002050034000000010205003800000001E0
-:1004A0000205003C000000010205004000000001C0
-:1004B000020500E00000000D020500E80000000059
-:1004C000020500F000000000020500F80000000036
-:1004D000020500E40000002D020500EC00000020F1
-:1004E000020500F400000020020500FC00000020CE
-:1004F000020500E00000001D020500E800000010F9
-:10050000020500F000000010020500F800000010D5
-:10051000020500E40000003D020500EC0000003090
-:10052000020500F400000030020500FC000000306D
-:10053000020500E00000004D020500E80000004058
-:10054000020500F000000040020500F80000004035
-:10055000020500E40000006D020500EC00000060F0
-:10056000020500F400000060020500FC00000060CD
-:10057000020500E00000005D020500E800000050F8
-:10058000020500F000000050020500F800000050D5
-:10059000020500E40000007D020500EC0000007090
-:1005A000020500F400000070020500FC000000706D
-:1005B0000406100002000020020600DC000000011A
-:1005C000010600D80000000004060200000302201B
-:1005D000020600DC00000000010600B80000000078
-:1005E000010600C8000000000206016C00000000C7
-:1005F000010600BC00000000010600CC0000000065
-:1006000002060170000000000718040000910000BD
-:10061000081807D800050223071C00002BDC000087
-:10062000071C80002DE90AF8071D00002F521673E1
-:10063000071D800015DB2248081DB0B049EA0225DD
-:100640000118000000000000011800040000000074
-:1006500001180008000000000118000C0000000054
-:100660000118001000000000011800140000000034
-:1006700002180020000000010218002400000002FF
-:1006800002180028000000030218002C00000000DF
-:1006900002180030000000040218003400000001BD
-:1006A00002180038000000000218003C00000001A1
-:1006B000021800400000000402180044000000007E
-:1006C00002180048000000010218004C000000035E
-:1006D0000218005000000000021800540000000141
-:1006E00002180058000000040218005C000000001E
-:1006F00002180060000000010218006400000003FE
-:1007000002180068000000000218006C00000001E0
-:1007100002180070000000040218007400000000BD
-:1007200002180078000000040218007C000000039A
-:100730000618008000000002021800A400003FFF1D
-:10074000021800A8000003FF0218022400000000A5
-:1007500002180234000000000218024C00000000E1
-:10076000021802E4000000FF061810000000040058
-:10077000021B8BC000000001021B8000000000343F
-:10078000021B804000000018021B80800000000C4B
-:10079000021B80C0000000200C1B83000007A1206A
-:1007A0000A1B8300000001380B1B83000000138824
-:1007B0000A1B8340000000000C1B8340000001F472
-:1007C0000B1B834000000005021B83800007A12053
-:1007D000021B83C0000001F4021B14800000000112
-:1007E0000A1B148000000000061A1000000003B36A
-:1007F000041A1ECC00010227061A1ED000000008B1
-:10080000061A2008000000C8061A20000000000296
-:10081000041AAF4000100228061A3718000000041E
-:10082000061A371000000002061A500000000002ED
-:10083000061A500800000004061A501800000004B0
-:10084000061A502800000004061A50380000000460
-:10085000061A504800000004061A50580000000410
-:10086000061A506800000004061A507800000002C2
-:10087000041A52C000020238061A40500000000656
-:10088000041A40680002023A041A40400004023C84
-:10089000041A800000010240061A800400000003D0
-:1008A000041A801000010241061A8014000000039F
-:1008B000041A802000010242061A8024000000036E
-:1008C000041A803000010243061A8034000000033D
-:1008D000041A804000010244061A8044000000030C
-:1008E000041A805000010245061A805400000003DB
-:1008F000041A806000010246061A806400000003AA
-:10090000041A807000010247061A80740000000378
-:10091000041A808000010248061A80840000000347
-:10092000041A809000010249061A80940000000316
-:10093000041A80A00001024A061A80A400000003E5
-:10094000041A80B00001024B061A80B400000003B4
-:10095000041A80C00001024C061A80C40000000383
-:10096000041A80D00001024D061A80D40000000352
-:10097000041A80E00001024E061A80E40000000321
-:10098000041A80F00001024F061A80F400000003F0
-:10099000041A810000010250061A810400000003BD
-:1009A000041A811000010251061A8114000000038C
-:1009B000041A812000010252061A8124000000035B
-:1009C000041A813000010253061A8134000000032A
-:1009D000041A814000010254061A814400000003F9
-:1009E000041A815000010255061A815400000003C8
-:1009F000041A816000010256061A81640000000397
-:100A0000041A817000010257061A81740000000365
-:100A1000041A818000010258061A81840000000334
-:100A2000041A819000010259061A81940000000303
-:100A3000041A81A00001025A061A81A400000003D2
-:100A4000041A81B00001025B061A81B400000003A1
-:100A5000041A81C00001025C061A81C40000000370
-:100A6000041A81D00001025D061A81D4000000033F
-:100A7000041A81E00001025E061A81E4000000030E
-:100A8000041A81F00001025F061A81F400000003DD
-:100A9000041A820000010260061A820400000003AA
-:100AA000041A821000010261061A82140000000379
-:100AB000041A822000010262061A82240000000348
-:100AC000041A823000010263061A82340000000317
-:100AD000041A824000010264061A824400000003E6
-:100AE000041A825000010265061A825400000003B5
-:100AF000041A826000010266061A82640000000384
-:100B0000041A827000010267061A82740000000352
-:100B1000041A828000010268061A82840000000321
-:100B2000041A829000010269061A829400000003F0
-:100B3000041A82A00001026A061A82A400000003BF
-:100B4000041A82B00001026B061A82B4000000038E
-:100B5000041A82C00001026C061A82C4000000035D
-:100B6000041A82D00001026D061A82D4000000032C
-:100B7000041A82E00001026E061A82E400000003FB
-:100B8000041A82F00001026F061A82F400000003CA
-:100B9000041A830000010270061A83040000000397
-:100BA000041A831000010271061A83140000000366
-:100BB000041A832000010272061A83240000000335
-:100BC000041A833000010273061A83340000000304
-:100BD000041A834000010274061A834400000003D3
-:100BE000041A835000010275061A835400000003A2
-:100BF000041A836000010276061A83640000000371
-:100C0000041A837000010277061A8374000000033F
-:100C1000041A838000010278061A8384000000030E
-:100C2000041A839000010279061A839400000003DD
-:100C3000041A83A00001027A061A83A400000003AC
-:100C4000041A83B00001027B061A83B4000000037B
-:100C5000041A83C00001027C061A83C4000000034A
-:100C6000041A83D00001027D061A83D40000000319
-:100C7000041A83E00001027E061A83E400000003E8
-:100C8000041A83F00001027F061A83F400000003B7
-:100C9000041A840000010280061A84040000000384
-:100CA000041A841000010281061A84140000000353
-:100CB000041A842000010282061A84240000000322
-:100CC000041A843000010283061A843400000003F1
-:100CD000041A844000010284061A844400000003C0
-:100CE000041A845000010285061A8454000000038F
-:100CF000041A846000010286061A8464000000035E
-:100D0000041A847000010287061A8474000000032C
-:100D1000041A848000010288061A848400000003FB
-:100D2000041A849000010289061A849400000003CA
-:100D3000041A84A00001028A061A84A40000000399
-:100D4000041A84B00001028B061A84B40000000368
-:100D5000041A84C00001028C061A84C40000000337
-:100D6000041A84D00001028D061A84D40000000306
-:100D7000041A84E00001028E061A84E400000003D5
-:100D8000041A84F00001028F061A84F400000003A4
-:100D9000041A850000010290061A85040000000371
-:100DA000041A851000010291061A85140000000340
-:100DB000041A852000010292061A8524000000030F
-:100DC000041A853000010293061A853400000003DE
-:100DD000041A854000010294061A854400000003AD
-:100DE000041A855000010295061A8554000000037C
-:100DF000041A856000010296061A8564000000034B
-:100E0000041A857000010297061A85740000000319
-:100E1000041A858000010298061A858400000003E8
-:100E2000041A859000010299061A859400000003B7
-:100E3000041A85A00001029A061A85A40000000386
-:100E4000041A85B00001029B061A85B40000000355
-:100E5000041A85C00001029C061A85C40000000324
-:100E6000041A85D00001029D061A85D400000003F3
-:100E7000041A85E00001029E061A85E400000003C2
-:100E8000041A85F00001029F061A85F40000000391
-:100E9000041A8600000102A0061A8604000000035E
-:100EA000041A8610000102A1061A8614000000032D
-:100EB000041A8620000102A2061A862400000003FC
-:100EC000041A8630000102A3061A863400000003CB
-:100ED000041A8640000102A4061A8644000000039A
-:100EE000041A8650000102A5061A86540000000369
-:100EF000041A8660000102A6061A86640000000338
-:100F0000041A8670000102A7061A86740000000306
-:100F1000041A8680000102A8061A868400000003D5
-:100F2000041A8690000102A9061A869400000003A4
-:100F3000041A86A0000102AA061A86A40000000373
-:100F4000041A86B0000102AB061A86B40000000342
-:100F5000041A86C0000102AC061A86C40000000311
-:100F6000041A86D0000102AD061A86D400000003E0
-:100F7000041A86E0000102AE061A86E400000003AF
-:100F8000041A86F0000102AF061A86F4000000037E
-:100F9000041A8700000102B0061A8704000000034B
-:100FA000041A8710000102B1061A8714000000031A
-:100FB000041A8720000102B2061A872400000003E9
-:100FC000041A8730000102B3061A873400000003B8
-:100FD000041A8740000102B4061A87440000000387
-:100FE000041A8750000102B5061A87540000000356
-:100FF000041A8760000102B6061A87640000000325
-:10100000041A8770000102B7061A877400000003F3
-:10101000041A8780000102B8061A878400000003C2
-:10102000041A8790000102B9061A87940000000391
-:10103000041A87A0000102BA061A87A40000000360
-:10104000041A87B0000102BB061A87B4000000032F
-:10105000041A87C0000102BC061A87C400000003FE
-:10106000041A87D0000102BD061A87D400000003CD
-:10107000041A87E0000102BE061A87E4000000039C
-:10108000041A87F0000102BF061A87F4000000036B
-:10109000041A8800000102C0061A88040000000338
-:1010A000041A8810000102C1061A88140000000307
-:1010B000041A8820000102C2061A882400000003D6
-:1010C000041A8830000102C3061A883400000003A5
-:1010D000041A8840000102C4061A88440000000374
-:1010E000041A8850000102C5061A88540000000343
-:1010F000041A8860000102C6061A88640000000312
-:10110000041A8870000102C7061A887400000003E0
-:10111000041A8880000102C8061A888400000003AF
-:10112000041A8890000102C9061A8894000000037E
-:10113000041A88A0000102CA061A88A4000000034D
-:10114000041A88B0000102CB061A88B4000000031C
-:10115000041A88C0000102CC061A88C400000003EB
-:10116000041A88D0000102CD061A88D400000003BA
-:10117000041A88E0000102CE061A88E40000000389
-:10118000041A88F0000102CF061A88F40000000358
-:10119000041A8900000102D0061A89040000000325
-:1011A000041A8910000102D1061A891400000003F4
-:1011B000041A8920000102D2061A892400000003C3
-:1011C000041A8930000102D3061A89340000000392
-:1011D000041A8940000102D4061A89440000000361
-:1011E000041A8950000102D5061A89540000000330
-:1011F000041A8960000102D6061A896400000003FF
-:10120000041A8970000102D7061A897400000003CD
-:10121000041A8980000102D8061A8984000000039C
-:10122000041A8990000102D9061A8994000000036B
-:10123000041A89A0000102DA061A89A4000000033A
-:10124000041A89B0000102DB061A89B40000000309
-:10125000041A89C0000102DC061A89C400000003D8
-:10126000041A89D0000102DD061A89D400000003A7
-:10127000041A89E0000102DE061A89E40000000376
-:10128000041A89F0000102DF061A89F40000000345
-:10129000041A8A00000102E0061A8A040000000312
-:1012A000041A8A10000102E1061A8A1400000003E1
-:1012B000041A8A20000102E2061A8A2400000003B0
-:1012C000041A8A30000102E3061A8A34000000037F
-:1012D000041A8A40000102E4061A8A44000000034E
-:1012E000041A8A50000102E5061A8A54000000031D
-:1012F000041A8A60000102E6061A8A6400000003EC
-:10130000041A8A70000102E7061A8A7400000003BA
-:10131000041A8A80000102E8061A8A840000000389
-:10132000041A8A90000102E9061A8A940000000358
-:10133000041A8AA0000102EA061A8AA40000000327
-:10134000041A8AB0000102EB061A8AB400000003F6
-:10135000041A8AC0000102EC061A8AC400000003C5
-:10136000041A8AD0000102ED061A8AD40000000394
-:10137000041A8AE0000102EE061A8AE40000000363
-:10138000041A8AF0000102EF061A8AF40000000332
-:10139000041A8B00000102F0061A8B0400000003FF
-:1013A000041A8B10000102F1061A8B1400000003CE
-:1013B000041A8B20000102F2061A8B24000000039D
-:1013C000041A8B30000102F3061A8B34000000036C
-:1013D000041A8B40000102F4061A8B44000000033B
-:1013E000041A8B50000102F5061A8B54000000030A
-:1013F000041A8B60000102F6061A8B6400000003D9
-:10140000041A8B70000102F7061A8B7400000003A7
-:10141000041A8B80000102F8061A8B840000000376
-:10142000041A8B90000102F9061A8B940000000345
-:10143000041A8BA0000102FA061A8BA40000000314
-:10144000041A8BB0000102FB061A8BB400000003E3
-:10145000041A8BC0000102FC061A8BC400000003B2
-:10146000041A8BD0000102FD061A8BD40000000381
-:10147000041A8BE0000102FE061A8BE40000000350
-:10148000041A8BF0000102FF061A8BF4000000031F
-:10149000041A8C0000010300061A8C0400000003EB
-:1014A000041A8C1000010301061A8C1400000003BA
-:1014B000041A8C2000010302061A8C240000000389
-:1014C000041A8C3000010303061A8C340000000358
-:1014D000041A8C4000010304061A8C440000000327
-:1014E000041A8C5000010305061A8C5400000003F6
-:1014F000041A8C6000010306061A8C6400000003C5
-:10150000041A8C7000010307061A8C740000000393
-:10151000041A8C8000010308061A8C840000000362
-:10152000041A8C9000010309061A8C940000000331
-:10153000041A8CA00001030A061A8CA40000000300
-:10154000041A8CB00001030B061A8CB400000003CF
-:10155000041A8CC00001030C061A8CC4000000039E
-:10156000041A8CD00001030D061A8CD4000000036D
-:10157000041A8CE00001030E061A8CE4000000033C
-:10158000041A8CF00001030F061A8CF4000000030B
-:10159000041A8D0000010310061A8D0400000003D8
-:1015A000041A8D1000010311061A8D1400000003A7
-:1015B000041A8D2000010312061A8D240000000376
-:1015C000041A8D3000010313061A8D340000000345
-:1015D000041A8D4000010314061A8D440000000314
-:1015E000041A8D5000010315061A8D5400000003E3
-:1015F000041A8D6000010316061A8D6400000003B2
-:10160000041A8D7000010317061A8D740000000380
-:10161000041A8D8000010318061A8D84000000034F
-:10162000041A8D9000010319061A8D94000000031E
-:10163000041A8DA00001031A061A8DA400000003ED
-:10164000041A8DB00001031B061A8DB400000003BC
-:10165000041A8DC00001031C061A8DC4000000038B
-:10166000041A8DD00001031D061A8DD4000000035A
-:10167000041A8DE00001031E061A8DE40000000329
-:10168000041A8DF00001031F061A8DF400000003F8
-:10169000041A8E0000010320061A8E0400000003C5
-:1016A000041A8E1000010321061A8E140000000394
-:1016B000041A8E2000010322061A8E240000000363
-:1016C000041A8E3000010323061A8E340000000332
-:1016D000041A8E4000010324061A8E440000000301
-:1016E000041A8E5000010325061A8E5400000003D0
-:1016F000041A8E6000010326061A8E64000000039F
-:10170000041A8E7000010327061A8E74000000036D
-:10171000041A8E8000010328061A8E84000000033C
-:10172000041A8E9000010329061A8E94000000030B
-:10173000041A8EA00001032A061A8EA400000003DA
-:10174000041A8EB00001032B061A8EB400000003A9
-:10175000041A8EC00001032C061A8EC40000000378
-:10176000041A8ED00001032D061A8ED40000000347
-:10177000041A8EE00001032E061A8EE40000000316
-:10178000041A8EF00001032F061A8EF400000003E5
-:10179000041A8F0000010330061A8F0400000003B2
-:1017A000041A8F1000010331061A8F140000000381
-:1017B000041A8F2000010332061A8F240000000350
-:1017C000041A8F3000010333061A8F34000000031F
-:1017D000041A8F4000010334061A8F4400000003EE
-:1017E000041A8F5000010335061A8F5400000003BD
-:1017F000041A8F6000010336061A8F64000000038C
-:10180000041A8F7000010337061A8F74000000035A
-:10181000041A8F8000010338061A8F840000000329
-:10182000041A8F9000010339061A8F9400000003F8
-:10183000041A8FA00001033A061A8FA400000003C7
-:10184000041A8FB00001033B061A8FB40000000396
-:10185000041A8FC00001033C061A8FC40000000365
-:10186000041A8FD00001033D061A8FD40000000334
-:10187000041A8FE00001033E061A8FE400000007FF
-:10188000041A62C00020033F061AD0000000007254
-:10189000061AD24800000010061AD6B00000002038
-:1018A000061AD47000000090061AD46800000002E6
-:1018B000061AA000000001C4061A30000000001043
-:1018C000061A308000000010061A310000000010D7
-:1018D000061A318000000010061A330000000012C2
-:1018E000061A339000000070061AD4580000000257
-:1018F000061AD34800000002061AD3580000002040
-:10190000061AA710000001C4061A3040000000109B
-:10191000061A30C000000010061A31400000001006
-:10192000061A31C000000010061A334800000012E9
-:10193000061A355000000070061AD460000000023C
-:10194000061AD35000000002061AD3D80000002067
-:10195000021AAE2000000000061A5000000000022B
-:10196000061A508000000012041A40000002035FB3
-:10197000041A63C000020361061A7000000000042C
-:10198000061A320000000008021AAE24000000000F
-:10199000061A501000000002061A50C8000000127B
-:1019A000041A400800020363041A63C800020365B6
-:1019B000061A701000000004061A32200000000809
-:1019C000021AAE2800000000061A50200000000293
-:1019D000061A511000000012041A4010000203679A
-:1019E000041A63D000020369061A70200000000484
-:1019F000061A324000000008021AAE2C0000000057
-:101A0000061A503000000002061A51580000001259
-:101A1000041A40180002036B041A63D80002036D15
-:101A2000061A703000000004061A32600000000838
-:101A3000021AAE3000000000061A504000000002FA
-:101A4000061A51A000000012041A40200002036F81
-:101A5000041A63E000020371061A704000000004DB
-:101A6000061A328000000008021AAE34000000009E
-:101A7000061A505000000002061A51E80000001239
-:101A8000041A402800020373041A63E80002037575
-:101A9000061A705000000004061A32A00000000868
-:101AA000021AAE3800000000061A50600000000262
-:101AB000061A523000000012041A40300002037768
-:101AC000041A63F000020379061A70600000000433
-:101AD000061A32C000000008021AAE3C00000000E6
-:101AE000061A507000000002061A52780000001218
-:101AF000041A40380002037B041A63F80002037DD5
-:101B0000061A707000000004061A32E00000000897
-:101B10000200A468000B01C80200A294071D29114D
-:101B20000200A298000000000200A29C009C042475
-:101B30000200A2A0000000000200A2A4000002090E
-:101B40000200A270000000000200A2740000000069
-:101B50000200A270000000000200A2740000000059
-:101B60000200A270000000000200A2740000000049
-:101B70000200A270000000000200A2740000000039
-:101B8000020160A000000001020160A400000262E6
-:101B9000020160A800000002020160AC0000001811
-:101BA0000201620400000001020100B40000000113
-:101BB000020100B800000001020100DC0000000189
-:101BC0000201010000000001020101040000000107
-:101BD0000201007C003000000201008400000028A7
-:101BE0000201008C0000000002010130000000042E
-:101BF0000201025C00000001020103280000000055
-:101C0000020160580000FFFF020160700000000741
-:101C10000201608000000001020105540000003054
-:101C2000020100C400000001020100CC000000011C
-:101C3000020100F800000001020100F000000001B4
-:101C4000020100800030000002010088000000282E
-:101C500002010090000000000201013400000004B5
-:101C6000020102DC000000010201032C0000000060
-:101C70000201605C0000FFFF0201607400000007C9
-:101C800002016084000000010201056400000030D0
-:101C9000020100C800000001020100D000000001A4
-:101CA000020100FC00000001020100F4000000013C
-:101CB000020C100000000028020C20080000021195
-:101CC000020C200C00000200020C20100000020494
-:101CD000020C201C0000FFFF020C20200000FFFF70
-:101CE000020C20240000FFFF020C20280000FFFF50
-:101CF000020C203800000020020C203C00000021D3
-:101D0000020C204000000022020C204400000023AE
-:101D1000020C204800000024020C204C000000258A
-:101D2000020C205000000026020C20540000002766
-:101D3000020C205800000028020C205C0000002942
-:101D4000020C20600000002A020C20640000002B1E
-:101D5000020C20680000002C020C206C0000002DFA
-:101D6000020C20700000002E020C20740000002FD6
-:101D7000020C207800000010060C207C00000007F8
-:101D8000020C209800000011020C209C00000012A0
-:101D9000020C20A000000013060C20A40000001D6F
-:101DA000020C211800000001020C211C000000019F
-:101DB000020C212000000001060C21240000001D5F
-:101DC000020C219800000001060C219C0000000775
-:101DD000020C21B800000001020C21BC000000012F
-:101DE000020C21C000000001020C21C4000000010F
-:101DF000020C21C800000001020C21CC00000001EF
-:101E0000020C21D000000001020C21D400000001CE
-:101E1000020C21D800000001020C21DC00000001AE
-:101E2000020C21E000000001020C21E4000000018E
-:101E3000020C21E800000001020C21EC000000016E
-:101E4000020C21F000000001020C21F4000000014E
-:101E5000020C21F800000001060C21FC0000000724
-:101E6000020C221800000001060C221C00000007D2
-:101E7000020C223807FFFFFF020C223C0000003F4B
-:101E8000020C224007FFFFFF020C22440000000F5B
-:101E9000010C224800000000010C224C0000000050
-:101EA000010C225000000000010C22540000000030
-:101EB000010C225800000000010C225C0000000010
-:101EC000010C226000000000010C226400000000F0
-:101ED000010C226800000000010C226C00000000D0
-:101EE000010C227000000000010C227400000000B0
-:101EF000010C227800000000010C227C0000000090
-:101F00000C0C2000000003E80A0C20000000000177
-:101F10000B0C20000000000A020C40080000101109
-:101F2000020C400C00001000020C401000001004D5
-:101F3000020C401400001021020C401C0000FFFFA6
-:101F4000020C40200000FFFF020C40240000FFFFB5
-:101F5000020C40280000FFFF020C40380000004641
-:101F6000020C403C00000010060C40400000000243
-:101F7000020C404800000018020C404C000000F029
-:101F8000060C40500000001F020C40CC0000000175
-:101F9000060C40D00000003A020C41B800000001DD
-:101FA000060C41BC00000003020C41C80000000107
-:101FB000020C41CC00000001060C41D00000001AC8
-:101FC000020C423807FFFFFF020C423C0000003FBA
-:101FD000020C424007FFFFFF020C42440000000FCA
-:101FE000010C424800000000010C424C00000000BF
-:101FF000010C425000000000010C4254000000009F
-:10200000010C425800000000010C425C000000007E
-:10201000010C426000000000010C4264000000005E
-:10202000010C426800000000010C426C000000003E
-:10203000010C427000000000010C4274000000001E
-:10204000010C427800000000010C427C00000000FE
-:10205000010C4280000000000C0C4000000003E86E
-:102060000A0C4000000000010B0C40000000000AB8
-:10207000060D400000000A00020D0044000000327E
-:10208000020D008C02150020020D009002150020A8
-:10209000020D009408100000020D009800000033AB
-:1020A000020D009C00000002020D00A000000000D4
-:1020B000020D00A400000005020D00A800000005AC
-:1020C000060D00AC00000002020D00B4000000028A
-:1020D000020D00B800000003020D00BC0000000269
-:1020E000020D00C000000001020D00C80000000247
-:1020F000020D00CC00000002020D015C0000000196
-:10210000020D016400000001020D016800000002E0
-:10211000020D020400000001020D020C000000206C
-:10212000020D021000000040020D021400000040E9
-:10213000020D022000000003020D0224000000181E
-:10214000060D028000000012040D03000018037F3A
-:10215000060D03600000000C020D004C00000001A1
-:10216000020D005000000002020D005400000000AB
-:10217000020D005800000008060D005C000000047D
-:10218000020D00C400000004020D00040000000164
-:10219000020D000800000001020D000C000000010B
-:1021A000020D001000000001020D001400000001EB
-:1021B000020D001800000001020D001C00000001CB
-:1021C000020D002000000001020D002400000001AB
-:1021D000020D002800000001020D002C000000018B
-:1021E000020D003000000001020D0034000000016B
-:1021F000020D003800000001020D003C000000014B
-:10220000020D011400000009020D011C0000000A6B
-:10221000020D012400000000020D012C000000004E
-:10222000020D013400000000020D013C0000000B13
-:10223000020D014400000000020D011800000029F9
-:10224000020D01200000002A020D012800000020DC
-:10225000020D013000000020020D013800000020B6
-:10226000020D01400000002B020D0148000000207B
-:10227000020D011400000019020D011C0000001ADB
-:10228000020D012400000010020D012C00000010BE
-:10229000020D013400000010020D013C0000001B83
-:1022A000020D014400000010020D01180000003969
-:1022B000020D01200000003A020D0128000000304C
-:1022C000020D013000000030020D01380000003026
-:1022D000020D01400000003B020D014800000030EB
-:1022E000020D011400000049020D011C0000004A0B
-:1022F000020D012400000040020D012C00000040EE
-:10230000020D013400000040020D013C0000004BB2
-:10231000020D014400000040020D01180000006998
-:10232000020D01200000006A020D0128000000607B
-:10233000020D013000000060020D01380000006055
-:10234000020D01400000006B020D0148000000601A
-:10235000020D011400000059020D011C0000005A7A
-:10236000020D012400000050020D012C000000505D
-:10237000020D013400000050020D013C0000005B22
-:10238000020D014400000050020D01180000007908
-:10239000020D01200000007A020D012800000070EB
-:1023A000020D013000000070020D013800000070C5
-:1023B000020D01400000007B020D0148000000708A
-:1023C000060E200000000800020E004C0000003243
-:1023D000020E009402150020020E00980215002043
-:1023E000020E009C00000030020E00A00810000049
-:1023F000020E00A400000033020E00A8000000300E
-:10240000020E00AC00000031020E00B0000000021D
-:10241000020E00B400000004020E00B8000000002C
-:10242000020E00BC00000002020E00C0000000020C
-:10243000020E00C400000000020E00C800000002EE
-:10244000020E00CC00000007020E00D000000002C7
-:10245000020E00D400000002020E00D800000001AD
-:10246000020E014400000001020E014C00000001B8
-:10247000020E015000000002020E020400000001E2
-:10248000020E020C00000040020E0210000000408C
-:10249000020E021C00000004020E022000000020B8
-:1024A000020E02240000000E020E02280000001B93
-:1024B000060E030000000012040E0280001B0397AA
-:1024C000060E02EC00000005020E00540000000C95
-:1024D000020E00580000000C020E005C000000001C
-:1024E000020E006000000010020E006400000010E8
-:1024F000060E006800000003020E00DC000000036E
-:10250000020E000400000001020E0008000000019D
-:10251000020E000C00000001020E0010000000017D
-:10252000020E001400000001020E0018000000015D
-:10253000020E001C00000001020E0020000000013D
-:10254000020E002400000001020E0028000000011D
-:10255000020E002C00000001020E003000000001FD
-:10256000020E003400000001020E003800000001DD
-:10257000020E003C00000001020E004000000001BD
-:10258000020E004400000001020E01100000000FC6
-:10259000020E011800000000020E012000000000E1
-:1025A000020E012800000000020E01140000002F9E
-:1025B000020E011C00000020020E01240000000099
-:1025C000020E012C00000000020E01100000001F8E
-:1025D000020E011800000010020E01200000000091
-:1025E000020E012800000000020E01140000003F4E
-:1025F000020E011C00000030020E01240000000049
-:10260000020E012C00000000020E01100000004F1D
-:10261000020E011800000040020E01200000000020
-:10262000020E012800000000020E01140000006FDD
-:10263000020E011C00000060020E012400000000D8
-:10264000020E012C00000000020E01100000005FCD
-:10265000020E011800000050020E012000000000D0
-:10266000020E012800000000020E01140000007F8D
-:10267000020E011C00000070020E01240000000088
-:10268000020E012C000000000730040000C800000A
-:10269000083007D8000503B207340000332C0000CF
-:1026A0000734800030AC0CCC07350000353318F807
-:1026B000073580002A7126450736000018DA30E217
-:1026C00008364670373203B40130000000000000C5
-:1026D000013000040000000001300008000000008C
-:1026E0000130000C0000000001300010000000006C
-:1026F0000130001400000000023000200000000142
-:102700000230002400000002023000280000000314
-:102710000230002C000000000230003000000004F5
-:1027200002300034000000010230003800000000D8
-:102730000230003C000000010230004000000004B4
-:102740000230004400000000023000480000000198
-:102750000230004C00000003023000500000000076
-:102760000230005400000001023000580000000454
-:102770000230005C00000000023000600000000138
-:102780000230006400000003023000680000000016
-:102790000230006C000000010230007000000004F4
-:1027A00002300074000000000230007800000004D5
-:1027B0000230007C000000030630008000000002B0
-:1027C000023000A400003FFF023000A8000003FF19
-:1027D0000230022400000000023002340000000039
-:1027E0000230024C00000000023002E40000FFFF53
-:1027F000063020000000080002338BC000000001FA
-:10280000023380000000001A023380400000004EB6
-:102810000233808000000010023380C000000020DE
-:102820000C3383000007A1200A3383000000013825
-:102830000B338300000013880A338340000000003C
-:102840000C338340000001F40B338340000000058B
-:10285000023383800007A120023383C0000001F40B
-:1028600002331480000000010A33148000000000CD
-:10287000063280000000010206322008000000C875
-:10288000063220000000000204328EA0001003B6C1
-:1028900006323EB00000000606323ED800000002BC
-:1028A00006323E800000000A04323EA8000203C641
-:1028B00006323E00000000200632500000000400F6
-:1028C0000632400000000004043274C0000203C855
-:1028D00006324110000000020632D0000000003035
-:1028E0000632DD40000000440632DA00000000D06D
-:1028F0000632DEA0000000020632E0000000080000
-:1029000006328450000001180632100000000188D1
-:102910000632500000000020063251000000002066
-:102920000632520000000020063253000000002052
-:10293000063254000000002006325500000000203E
-:10294000063256000000002006325700000000202A
-:102950000632580000000020063259000000002016
-:1029600006325A000000002006325B000000002002
-:1029700006325C000000002006325D0000000020EE
-:1029800006325E000000002006325F0000000020DA
-:1029900006328DF00000000204328E00000203CAED
-:1029A00006328E08000000020632DE9000000002AF
-:1029B00006321C4000000038063288B000000118C2
-:1029C00006321620000001880632508000000020E8
-:1029D00006325180000000200632528000000020A4
-:1029E0000632538000000020063254800000002090
-:1029F000063255800000002006325680000000207C
-:102A00000632578000000020063258800000002067
-:102A1000063259800000002006325A800000002053
-:102A200006325B800000002006325C80000000203F
-:102A300006325D800000002006325E80000000202B
-:102A400006325F800000002006328DF80000000290
-:102A500004328E10000203CC06328E1800000002F1
-:102A60000632DE980000000206321D200000003809
-:102A700002328D50000000000632401000000002BB
-:102A800002328D5400000000063240200000000297
-:102A900002328D5800000000063240300000000273
-:102AA00002328D5C0000000006324040000000024F
-:102AB00002328D600000000006324050000000022B
-:102AC00002328D6400000000063240600000000207
-:102AD00002328D68000000000632407000000002E3
-:102AE00002328D6C000000000632408000000002BF
-:102AF000072004000091000008200780001003CE8A
-:102B0000072400002B0B00000724800015080AC3CF
-:102B10000824AA10692403D001200000000000004E
-:102B20000120000400000000012000080000000057
-:102B30000120000C00000000012000100000000037
-:102B4000012000140000000002200020000000010D
-:102B500002200024000000020220002800000003E0
-:102B60000220002C000000000220003000000004C1
-:102B700002200034000000010220003800000000A4
-:102B80000220003C00000001022000400000000480
-:102B90000220004400000000022000480000000164
-:102BA0000220004C00000003022000500000000042
-:102BB0000220005400000001022000580000000420
-:102BC0000220005C00000000022000600000000104
-:102BD00002200064000000030220006800000000E2
-:102BE0000220006C000000010220007000000004C0
-:102BF00002200074000000000220007800000004A1
-:102C00000220007C0000000306200080000000027B
-:102C1000022000A400003FFF022000A8000003FFE4
-:102C20000220022400000000022002340000000004
-:102C30000220024C00000000022002E40000FFFF1E
-:102C4000062020000000080002238BC000000001C5
-:102C500002238000000000100223804000000012C8
-:102C60000223808000000030022380C00000000E9C
-:102C70000C2383000007A1200A23830000000138F1
-:102C80000B238300000013880A2383400000000008
-:102C90000C238340000001F40B2383400000000557
-:102CA000022383800007A120022383C0000001F4D7
-:102CB00002231480000000010A2314800000000099
-:102CC000062210000000004206222008000000C872
-:102CD00006222000000000020622B000000000C60C
-:102CE0000422B318000503D20622B32C0000000B07
-:102CF0000422B358000503D70622B36C0000000B72
-:102D00000422B398000503DC0622B3AC0000000BDC
-:102D10000422B3D8000503E10622B3EC0000000B47
-:102D20000422B418000503E60622B42C0000000BB0
-:102D30000422B458000503EB0622B46C0000000B1B
-:102D40000422B498000503F00622B4AC0000000B86
-:102D50000422B4D8000503F50622B4EC0000000BF1
-:102D60000422B518000503FA0622B52C0000000B5A
-:102D70000422B558000503FF0622B56C0000000BC5
-:102D80000422B598000504040622B5AC0000000B2F
-:102D90000422B5D8000504090622B5EC0000000B9A
-:102DA0000422B6180005040E0622B62C0000000B03
-:102DB0000422B658000504130622B66C0000000B6E
-:102DC0000422B698000504180622B6AC0000000BD9
-:102DD0000422B6D80005041D0622B6EC0000000B44
-:102DE0000422B718000504220622B72C0000000BAD
-:102DF0000422B758000504270622B76C0000000B18
-:102E00000422B7980005042C0622B7AC0000000B82
-:102E10000422B7D8000504310622B7EC0000000BED
-:102E20000422B818000504360622B82C0000000B56
-:102E30000422B8580005043B0622B86C0000000BC1
-:102E40000422B898000504400622B8AC0000000B2C
-:102E50000422B8D8000504450622B8EC0000000B97
-:102E60000422B9180005044A0622B92C0000000B00
-:102E70000422B9580005044F0622B96C0000000B6B
-:102E80000422B998000504540622B9AC0000000BD6
-:102E90000422B9D8000504590622B9EC0000000B41
-:102EA0000422BA180005045E0622BA2C0000000BAA
-:102EB0000422BA58000504630622BA6C0000000B15
-:102EC0000422BA98000504680622BAAC0000000B80
-:102ED0000422BAD80005046D0622BAEC00000005F1
-:102EE0000622BB00000000530422BC4C0001047207
-:102EF0000622BC50000000030422BC5C00010473E5
-:102F00000622BC60000000030422BC6C00010474B3
-:102F10000622BC70000000030422BC7C0001047582
-:102F20000622BC80000000030422BC8C0001047651
-:102F30000622BC90000000030422BC9C0001047720
-:102F40000622BCA0000000030422BCAC00010478EF
-:102F50000622BCB0000000030422BCBC00010479BE
-:102F60000622880000000100062280000000020006
-:102F7000042212700010047A06223000000000C003
-:102F800006226700000001000622900000000400F5
-:102F900004226B080020048A022212C0FFFFFFFFF8
-:102FA000062211E800000002062212C800000009F3
-:102FB000062212EC0000000906228C000000000826
-:102FC0000222114800000000062213200000000623
-:102FD000062233000000000206226040000000309C
-:102FE00006228C20000000080222114C0000000084
-:102FF00006221338000000060622330800000002F3
-:10300000062261000000003006228C40000000080B
-:10301000022211500000000006221350000000069A
-:103020000622331000000002062261C000000030BA
-:1030300006228C60000000080222115400000000EB
-:103040000622136800000006062233180000000262
-:10305000062262800000003006228C8000000008FA
-:103060000222115800000000062213800000000612
-:1030700006223320000000020622634000000030D8
-:1030800006228CA0000000080222115C0000000053
-:1030900006221398000000060622332800000002D2
-:1030A000062264000000003006228CC000000008E8
-:1030B0000222116000000000062213B0000000068A
-:1030C0000622333000000002062264C000000030F7
-:1030D00006228CE0000000080222116400000000BB
-:1030E000062213C800000006062233380000000242
-:1030F0000622658000000030021610000000002843
-:1031000002170008000000020217002C0000000354
-:103110000217003C000000040217004800000002F3
-:103120000217004C000000900217005000000090B1
-:103130000217005400800090021700580810000089
-:10314000021700600000008A02170064000000807F
-:1031500002170068000000810217006C0000008068
-:10316000021700700000000602170078000007D068
-:103170000217007C0000076C02170038007C100466
-:10318000021700040000000F061640240000000291
-:10319000021640700000001C0216420800000001E8
-:1031A0000216421000000001021642200000000139
-:1031B0000216422800000001021642300000000101
-:1031C00002164238000000010216426000000002B0
-:1031D0000C16401C0003D0900A16401C0000009CF6
-:1031E0000B16401C000009C4021640300000000805
-:1031F000021640340000000C021640380000001097
-:1032000002164044000000200216400000000001A9
-:10321000021640D80000000102164008000000011C
-:103220000216400C000000010216401000000001D0
-:103230000216424000000000021642480000000052
-:103240000616427000000002021642500000000004
-:1032500002164258000000000616428000000002DC
-:1032600002166008000012240216600C0000121002
-:1032700002166010000012140216601C0000FFFF0E
-:10328000021660200000FFFF021660240000FFFF0E
-:10329000021660280000FFFF0216603800000020C0
-:1032A0000216603C0000002006166040000000028C
-:1032B00002166048000000230216604C0000002443
-:1032C000021660500000002502166054000000261F
-:1032D00002166058000000270216605C00000029FA
-:1032E000021660600000002A021660640000002BD5
-:1032F000021660680000002C0216606C0000002DB1
-:1033000002166070000000EC0216607400000011EC
-:1033100002166078000000120616607C0000000FA4
-:10332000021660B800000001021660BC0000000137
-:10333000061660C00000000C021660F000000001DC
-:10334000061660F400000031021661B800000001AA
-:10335000061661BC0000000D021661F000000001BD
-:10336000061661F4000000110216623807FFFFFF25
-:103370000216623C0000003F0216624007FFFFFF9A
-:10338000021662440000000F0116624800000000AF
-:103390000116624C0000000001166250000000009F
-:1033A000011662540000000001166258000000007F
-:1033B0000116625C0000000001166260000000005F
-:1033C000011662640000000001166268000000003F
-:1033D0000116626C0000000001166270000000001F
-:1033E00001166274000000000116627800000000FF
-:1033F0000116627C000000000C166000000003E86B
-:103400000A166000000000010B1660000000000AB0
-:1034100002168040000000060216804400000005ED
-:10342000021680480000000A0216804C00000005C9
-:103430000216805400000002021680CC0000000436
-:10344000021680D000000004021680D400000004A0
-:10345000021680D800000004021680DC0000000480
-:10346000021680E000000004021680E40000000460
-:10347000021680E800000004021688040000000420
-:10348000021680300000007C021680340000003DEF
-:10349000021680380000003F0216803C0000009CAD
-:1034A000021680F000000007061680F400000005F8
-:1034B0000216880C010101010216810800000000BB
-:1034C0000216810C000000040216811000000004A6
-:1034D0000216811400000002021688100801200460
-:1034E00002168118000000050216811C000000056C
-:1034F000021681200000000502168124000000054C
-:103500000216882C200810010216812800000008ED
-:103510000216812C00000006021681300000000710
-:1035200002168134000000000216883001010120DB
-:1035300006168138000000040216883401010101DA
-:1035400002168148000000000216814C00000004B1
-:10355000021681500000000402168154000000028F
-:103560000216883808012004021681580000000560
-:103570000216815C00000005021681600000000553
-:1035800002168164000000050216883C2008100124
-:1035900002168168000000080216816C0000000617
-:1035A00002168170000000070216817400000001FD
-:1035B00002168840010101200216817800000001F6
-:1035C0000216817C000000010216818000000001CB
-:1035D00002168184000000010216884401010101E5
-:1035E00002168188000000010216818C0000000490
-:1035F000021681900000000402168194000000026F
-:10360000021688480801200402168198000000056F
-:103610000216819C00000005021681A00000000532
-:10362000021681A40000000502168814200810016B
-:10363000021681A800000008021681AC00000006F6
-:10364000021681B000000007021681B400000001DC
-:103650000216881801010120021681B8000000013D
-:10366000021681BC00000001021681C000000001AA
-:10367000021681C4000000010216881C010101012C
-:10368000021681C800000001021681CC000000046F
-:10369000021681D000000004021681D4000000024E
-:1036A0000216882008012004021681D800000005B7
-:1036B000021681DC00000005021681E00000000512
-:1036C000021681E40000000502168824200810017B
-:1036D000021681E800000008021681EC00000006D6
-:1036E000021681F0000000070216E40C0000000042
-:1036F00002168828010101200616E41000000004CB
-:103700000216E000010101010216E42000000000A1
-:103710000216E424000000040216E428000000045D
-:103720000216E42C000000020216E0040801200446
-:103730000216E430000000050216E4340000000523
-:103740000216E438000000050216E43C0000000503
-:103750000216E008200810010216E44000000008EC
-:103760000216E444000000060216E44800000007C8
-:103770000216E44C000000000216E00C01010120DA
-:103780000616E450000000040216E01001010101D9
-:103790000216E460000000000216E4640000000469
-:1037A0000216E468000000040216E46C0000000247
-:1037B0000216E014080120040216E470000000055F
-:1037C0000216E474000000050216E478000000050B
-:1037D0000216E47C000000050216E0182008100123
-:1037E0000216E480000000080216E48400000006CF
-:1037F0000216E488000000070216E48C00000001B5
-:103800000216E01C010101200216E49000000001F4
-:103810000216E494000000010216E4980000000182
-:103820000216E49C000000010216E02001010101E3
-:103830000216E4A0000000010216E4A40000000447
-:103840000216E4A8000000040216E4AC0000000226
-:103850000216E024080120040216E4B0000000056E
-:103860000216E4B4000000050216E4B800000005EA
-:103870000216E4BC000000050216E0282008100132
-:103880000216E4C0000000080216E4C400000006AE
-:103890000216E4C8000000070216E4CC0000000194
-:1038A0000216E02C010101200216E4D00000000104
-:1038B0000216E4D4000000010216E4D80000000162
-:1038C0000216E4DC000000010216E03001010101F3
-:1038D0000216E4E0000000010216E4E40000000427
-:1038E0000216E4E8000000040216E4EC0000000206
-:1038F0000216E034080120040216E4F0000000057E
-:103900000216E4F4000000050216E4F800000005C9
-:103910000216E4FC000000050216E0382008100141
-:103920000216E500000000080216E504000000068B
-:103930000216E508000000070216E03C0101012024
-:1039400002168240003F003F021682440000000041
-:103950000216E524003F003F0216E52800000000A3
-:1039600002168248000000000216824C003F003F11
-:103970000216E52C000000000216E530003F003F73
-:10398000021682500100010002168254010001005B
-:103990000216E534010001000216E53801000100BD
-:1039A00006168258000000020216E53C00000000E6
-:1039B0000216E540000000000216826000C000C050
-:1039C0000216826400C000C00216E54400C000C0B8
-:1039D0000216E54800C000C0021682681E001E00E4
-:1039E0000216826C1E001E000216E54C1E001E0010
-:1039F0000216E5501E001E000216827040004000B4
-:103A000002168274400040000216E5544000400057
-:103A10000216E558400040000216827880008000BF
-:103A20000216827C800080000216E55C8000800027
-:103A30000216E560800080000216828020002000CF
-:103A400002168284200020000216E5642000200077
-:103A50000216E56820002000061682880000000299
-:103A60000216E56C000000000216E5700000000080
-:103A700002168290000000000216829400000000EE
-:103A80000216E574000000000216E5780000000050
-:103A900002168298000000000216829C00000000BE
-:103AA0000216E57C000000000216E5800000000020
-:103AB000021682A000000000021682A4000000018D
-:103AC000061682A80000000A021681F400000C0805
-:103AD000021681F800000040021681FC000001007F
-:103AE0000216820000000020021682040000001767
-:103AF00002168208000000800216820C00000200FC
-:103B000002168210000000000216821801FF01FF59
-:103B10000216821401FF01FF0216E51001FF01FFEA
-:103B20000216E50C01FF01FF0216823C00000013A3
-:103B3000021680900000013F0216806000000140E4
-:103B40000216806400000140061680680000000232
-:103B500002168070000000C0061680740000000786
-:103B60000216809C00000048021680A00000004859
-:103B7000061680A400000002021680AC0000004877
-:103B8000061680B000000007021682380000800090
-:103B900002168234000025E40216809400007FFFA4
-:103BA00002168220000F000F0216821C000F000F69
-:103BB0000216E518000F000F0216E514000F000FA3
-:103BC000021682280000000002168224FFFFFFFF79
-:103BD0000216E520000000000216E51CFFFFFFFFB3
-:103BE0000216E6BC000000000216E6C0000000025B
-:103BF0000216E6C4000000010216E6C80000000339
-:103C00000216E6CC000000040216E6D00000000612
-:103C10000216E6D4000000050216E6D800000007F0
-:103C2000021680EC000000FF0214000000000001FA
-:103C30000214000C0000000102140040000000010A
-:103C40000214004400007FFF0214000C000000007A
-:103C500002140000000000000214006C00000000CC
-:103C600002140004000000010214003000000001F2
-:103C700002140004000000000214005C00000000B8
-:103C800002140008000000010214003400000001CA
-:103C90000214000800000000021400600000000090
-:103CA00006028000000020000202005800000032DE
-:103CB000020200A003150020020200A40315002048
-:103CC000020200A801000030020200AC081000004F
-:103CD000020200B000000033020200B40000003015
-:103CE000020200B800000031020200BC0000000324
-:103CF000020200C000000006020200C4000000032F
-:103D0000020200C800000003020200CC0000000212
-:103D1000020200D000000000020200D400000002F5
-:103D2000020200DC00000000020200E000000006C9
-:103D3000020200E400000004020200E800000002A9
-:103D4000020200EC00000002020200F0000000018C
-:103D5000020200FC00000006020201200000000038
-:103D60000202013400000002020201B00000000162
-:103D70000202020C00000001020202140000000115
-:103D80000202021800000002020204040000000106
-:103D90000202040C00000040020204100000004077
-:103DA0000202041C000000040202042000000020A3
-:103DB0000202042400000002020204280000002085
-:103DC000060205000000001204020480002004AA7C
-:103DD000020200600000000F020200640000000701
-:103DE00002020068000000000202006C0000000EE9
-:103DF000020200700000000E0602007400000003C2
-:103E0000020200F4000000040202000400000001AD
-:103E100002020008000000010202000C0000000184
-:103E20000202001000000001020200140000000164
-:103E300002020018000000010202001C0000000144
-:103E40000202002000000001020200240000000124
-:103E500002020028000000010202002C0000000104
-:103E600002020030000000010202003400000001E4
-:103E700002020038000000010202003C00000001C4
-:103E800002020040000000010202004400000001A4
-:103E900002020048000000010202004C0000000184
-:103EA000020200500000000102020108000000C8E8
-:103EB0000202011800000002020201C4000000001A
-:103EC000020201CC00000000020201D40000000246
-:103ED000020201DC00000002020201E4000000FF17
-:103EE000020201EC000000FF0202010000000000DD
-:103EF0000202010C000000C80202011C00000002C6
-:103F0000020201C800000000020201D0000000000F
-:103F1000020201D800000002020201E000000002DB
-:103F2000020201E8000000FF020201F0000000FFB1
-:103F3000020201040000000002020108000000C8A3
-:103F40000202011800000002020201C40000000089
-:103F5000020201CC00000000020201D400000002B5
-:103F6000020201DC00000002020201E4000000FF86
-:103F7000020201EC000000FF02020100000000004C
-:103F80000202010C000000C80202011C0000000235
-:103F9000020201C800000000020201D0000000007F
-:103FA000020201D800000002020201E0000000024B
-:103FB000020201E8000000FF020201F0000000FF21
-:103FC000020201040000000002020108000000C813
-:103FD0000202011800000002020201C400000000F9
-:103FE000020201CC00000000020201D40000000225
-:103FF000020201DC00000002020201E4000000FFF6
-:10400000020201EC000000FF0202010000000000BB
-:104010000202010C000000C80202011C00000002A4
-:10402000020201C800000000020201D000000000EE
-:10403000020201D800000002020201E000000002BA
-:10404000020201E8000000FF020201F0000000FF90
-:10405000020201040000000002020108000000C882
-:104060000202011800000002020201C40000000068
-:10407000020201CC00000000020201D40000000294
-:10408000020201DC00000002020201E4000000FF65
-:10409000020201EC000000FF02020100000000002B
-:1040A0000202010C000000C80202011C0000000214
-:1040B000020201C800000000020201D0000000005E
-:1040C000020201D800000002020201E0000000022A
-:1040D000020201E8000000FF020201F0000000FF00
-:1040E00002020104000000000728040000A10000F3
-:1040F000082807B8000904CA072C000034F700009C
-:10410000072C800039250D3E072D000037CD1B8878
-:10411000072D80003292297C072E00001AF33621E9
-:10412000082E4390378E04CC0128000000000000C8
-:104130000128000400000000012800080000000021
-:104140000128000C00000000012800100000000001
-:1041500001280014000000000228002000000001D7
-:1041600002280024000000020228002800000003AA
-:104170000228002C0000000002280030000000048B
-:10418000022800340000000102280038000000006E
-:104190000228003C0000000102280040000000044A
-:1041A000022800440000000002280048000000012E
-:1041B0000228004C0000000302280050000000000C
-:1041C00002280054000000010228005800000004EA
-:1041D0000228005C000000000228006000000001CE
-:1041E00002280064000000030228006800000000AC
-:1041F0000228006C0000000102280070000000048A
-:10420000022800740000000002280078000000046A
-:104210000228007C00000003062800800000000245
-:10422000022800A400003FFF022800A8000003FFAE
-:1042300002280224000000000228023400000000CE
-:104240000228024C00000000022802E40000FFFFE8
-:104250000628200000000800022B8BC0000000018F
-:10426000022B800000000000022B8040000000189C
-:10427000022B80800000000C022B80C00000006632
-:104280000C2B83000007A1200A2B830000000138BB
-:104290000B2B8300000013880A2B834000000000D2
-:1042A0000C2B8340000001F40B2B83400000000521
-:1042B000022B83800007A120022B83C0000001F4A1
-:1042C000022B1480000000010A2B14800000000063
-:1042D000062A9AF800000004042A9B08000204CE73
-:1042E000062A9B1000000006062A90800000004865
-:1042F000062A2008000000C8062A2000000000024C
-:10430000062A91A800000086062A900000000020DE
-:10431000062A93C800000003042A93D4000104D0A5
-:10432000062A9DA800000002042A9498000404D1E3
-:10433000042A9D58000104D5062A9D5C0000001146
-:10434000042ACB20001004D6042A3000000204E620
-:10435000062A300800000100062A40400000001034
-:10436000042A4000001004E8042A8408000204F82B
-:10437000062A9DA000000002062AB000000000509E
-:10438000062ABB7000000070062AB150000000022F
-:10439000062ABB6000000004062AD00000000800C6
-:1043A000062AC00000000150062A94A8000000322E
-:1043B000062A502000000002062A503000000002A9
-:1043C000062A500000000002062A501000000002D9
-:1043D000022A520800000001042A9B28000204FA65
-:1043E000062A963800000022042A96C0000104FC28
-:1043F000062A96C400000003062A976800000022DF
-:10440000042A97F0000104FD062A97F40000000337
-:10441000062A989800000022042A9920000104FE30
-:10442000062A992400000003062A99C800000022E9
-:10443000042A9A50000104FF062A9A54000000033F
-:10444000062AB14000000002062AC54000000150C3
-:10445000062A957000000032062A5028000000024B
-:10446000062A503800000002062A50080000000208
-:10447000062A501800000002022A520C0000000117
-:10448000042A9B3000020500062A96D00000002274
-:10449000042A975800010502062A975C00000003D1
-:1044A000062A980000000022042A988800010503CB
-:1044B000062A988C00000003062A9930000000228A
-:1044C000042A99B800010504062A99BC00000003DB
-:1044D000062A9A6000000022042A9AE800010505D5
-:1044E000062A9AEC00000003062AB14800000002E8
-:1044F000022ACA8000000000042A9B38001005062A
-:10450000062A50480000000E022ACA84000000005B
-:10451000042A9B7800100516062A50800000000E21
-:10452000022ACA8800000000042A9BB80010052651
-:10453000062A50B80000000E022ACA8C00000000B3
-:10454000042A9BF800100536062A50F00000000EE1
-:10455000022ACA9000000000042A9C380010054678
-:10456000062A51280000000E022ACA94000000000A
-:10457000042A9C7800100556062A51600000000E9F
-:10458000022ACA9800000000042A9CB800100566A0
-:10459000062A51980000000E022ACA9C0000000062
-:1045A000042A9CF800100576062A51D00000000E5F
-:1045B000021010080000000102101050000000015D
-:1045C000021010000003D000021010040000003D93
-:1045D0000910180002000586091011000010078656
-:1045E0000610114000000008091011600010079625
-:1045F000061011A00000001806102400000000E0C2
-:104600000210201C00000000021020200000000109
-:10461000021020C00000000202102004000000016F
-:10462000021020080000000109103C00000507A648
-:1046300009103800000507AB09103820000507B045
-:1046400006104C000000010002104028000000107D
-:104650000210404400003FFF0210405800280000B4
-:10466000021040840084924A02104058000000006A
-:104670000210800000001080021080AC00000000DA
-:1046800002108038000000100210810000000000BD
-:10469000061081200000000202108008000002B510
-:1046A0000210801000000000061082000000004A86
-:1046B000021081080001FFFF061081400000000287
-:1046C0000210800000001A800610900000000024F4
-:1046D000061091200000004A061093700000004A66
-:1046E000061095C00000004A0210800400001080EF
-:1046F000021080B0000000010210803C0000001099
-:104700000210810400000000061081280000000251
-:104710000210800C000002B502108014000000009E
-:10472000061084000000004A0210810C0001FFFF07
-:1047300006108148000000020210800400001A8068
-:104740000610909000000024061092480000004AD5
-:10475000061094980000004A061096E80000004AEF
-:104760000210800000001080021080AC00000002E7
-:1047700002108038000000100210810000000000CC
-:10478000061081200000000202108008000002B51F
-:104790000210801000000000061082000000004A95
-:1047A000021081080001FFFF061081400000000296
-:1047B0000210800000001A80061090000000002403
-:1047C000061091200000004A061093700000004A75
-:1047D000061095C00000004A0210800400001080FE
-:1047E000021080B0000000030210803C00000010A6
-:1047F0000210810400000000061081280000000261
-:104800000210800C000002B50210801400000000AD
-:10481000061084000000004A0210810C0001FFFF16
-:1048200006108148000000020210800400001A8077
-:104830000610909000000024061092480000004AE4
-:10484000061094980000004A061096E80000004AFE
-:104850000210800000001080021080AC00000004F4
-:1048600002108038000000100210810000000000DB
-:10487000061081200000000202108008000002B52E
-:104880000210801000000000061082000000004AA4
-:10489000021081080001FFFF0610814000000002A5
-:1048A0000210800000001A80061090000000002412
-:1048B000061091200000004A061093700000004A84
-:1048C000061095C00000004A02108004000010800D
-:1048D000021080B0000000050210803C00000010B3
-:1048E0000210810400000000061081280000000270
-:1048F0000210800C000002B50210801400000000BD
-:10490000061084000000004A0210810C0001FFFF25
-:1049100006108148000000020210800400001A8086
-:104920000610909000000024061092480000004AF3
-:10493000061094980000004A061096E80000004A0D
-:104940000210800000001080021080AC0000000601
-:1049500002108038000000100210810000000000EA
-:10496000061081200000000202108008000002B53D
-:104970000210801000000000061082000000004AB3
-:10498000021081080001FFFF0610814000000002B4
-:104990000210800000001A80061090000000002421
-:1049A000061091200000004A061093700000004A93
-:1049B000061095C00000004A02108004000010801C
-:1049C000021080B0000000070210803C00000010C0
-:1049D000021081040000000006108128000000027F
-:1049E0000210800C000002B50210801400000000CC
-:1049F000061084000000004A0210810C0001FFFF35
-:104A000006108148000000020210800400001A8095
-:104A10000610909000000024061092480000004A02
-:104A2000061094980000004A061096E80000004A1C
-:104A3000021205B0000000010212049000E383405E
-:104A40000212051400003C100212066C0000000166
-:104A5000021206700000000002120494FFFFFFFF24
-:104A600002120498FFFFFFFF0212049CFFFFFFFFEA
-:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA
-:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA
-:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82
-:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
-:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
-:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
-:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
-:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
-:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
-:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
-:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
-:104B200002120504FFFFFFFF02120508FFFFFFFF4F
-:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
-:104B4000021204D4FF809000021204B4F00050005E
-:104B5000021204B8F00010000212039000000008D6
-:104B60000212039C00000008021203A000000008CB
-:104B7000021203A400000002021203BC00000004A1
-:104B8000021203C000000005021203C4000000046A
-:104B9000021203D0000000000212036C00000001AA
-:104BA000021203680000003F021201BC0000004036
-:104BB000021201C000001808021201C4000008031C
-:104BC000021201C800000803021201CC00000040DC
-:104BD000021201D000000003021201D400000803F9
-:104BE000021201D800000803021201DC00000803D1
-:104BF000021201E000010003021201E400000803B8
-:104C0000021201E800000803021201EC0000000398
-:104C1000021201F000000003021201F40000000380
-:104C2000021201F800000003021201FC0000000360
-:104C3000021202000000000302120204000000033E
-:104C400002120208000000030212020C000000031E
-:104C500002120210000000030212021400000003FE
-:104C600002120218000000030212021C00000003DE
-:104C700002120220000000030212022400000003BE
-:104C800002120228000024030212022C0000002F4E
-:104C90000212023000000009021202340000001962
-:104CA00002120238000001840212023C000001835B
-:104CB0000212024000000306021202440000001922
-:104CC00002120248000000060212024C0000030615
-:104CD00002120250000003060212025400000306F2
-:104CE0000212025800000C860212025C0000030649
-:104CF00002120260000003060212026400000006B5
-:104D000002120268000000060212026C0000000697
-:104D10000212027000000006021202740000000677
-:104D200002120278000000060212027C0000000657
-:104D30000212028000000006021202840000000637
-:104D400002120288000000060212028C0000000617
-:104D500002120290000000060212029400000006F7
-:104D600002120298000000060212029C00000006D7
-:104D7000021202A000000306021202A400000013A7
-:104D8000021202A800000006021202B00000100485
-:104D9000021202B400001004021203240010644046
-:104DA0000212032800106440021205B40000000142
-:104DB000021201B0000000010600A0000000000C7B
-:104DC0000200A050000000000200A05400000000FB
-:104DD0000200A0EC555400000200A0F055555555B6
-:104DE0000200A0F4000055550200A0F8F0000000F9
-:104DF0000200A0FC555400000200A1005555555575
-:104E00000200A104000055550200A108F0000000B6
-:104E10000200A18C555400000200A1905555555533
-:104E20000200A194000055550200A198F000000076
-:104E30000200A19C000000000200A1A000010000EF
-:104E40000200A1A4000050140200A1A8000000006C
-:104E50000200A45C00000C000200A61C000000037D
-:104E60000200A06CFF5C00000200A070FFF55FFF75
-:104E70000200A0740000FFFF0200A078F00003E031
-:104E80000200A07C000000000200A0800000A00042
-:104E90000600A084000000050200A0980FE00000BA
-:104EA0000600A09C000000070200A0B8000004005B
-:104EB0000600A0BC000000030200A0C80000100013
-:104EC0000600A0CC000000030200A0D800004000B3
-:104ED0000600A0DC000000030200A0E800010000C2
-:104EE0000600A22C000000040200A10CFF5C0000E0
-:104EF0000200A110FFF55FFF0200A1140000FFFFF8
-:104F00000200A118F00003E00200A11C0000000054
-:104F10000200A1200000A0000600A124000000055E
-:104F20000200A1380FE000000600A13C00000007CD
-:104F30000200A158000008000600A15C0000000368
-:104F40000200A168000020000600A16C0000000320
-:104F50000200A178000080000600A17C0000000390
-:104F60000200A188000200000600A23C000000042C
-:104F70000200A030000000000200A0340000000089
-:104F80000200A038000000000200A03C0000000069
-:104F90000200A040000000000200A0440000000049
-:104FA0000200A048000000000200A04C0000000029
-:104FB00000000000000000000000003000000000C1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE0000000000000300031000000000000000060
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:10501000003100520000000000000000000000000D
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000052008995
-:1050400000000000000000000089008D008D00912C
-:1050500000910095009500990099009D009D00A188
-:1050600000A100A500A500A900A900AE00AE00B1F6
-:1050700000B100B4000000000000000000000000CB
-:105080000000000000000000000000000000000020
-:105090000000000000B40309030903130313031DF8
-:1050A000031D03240324032B032B03320332033990
-:1050B00003390340034003470347034E034E0355A0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:105170000355035B0000000000000000035B035CBC
-:10518000035C035D035D035E035E035F035F036017
-:1051900003600361036103620362036300000000B4
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000363036D036D037B1B
-:1051D000037B0389000000000000000000000000C5
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:105220000389038A00000000000000000000000065
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000038A03D6F8
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000003D604010000000050
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000040104330000000000000000C2
-:1052B0000433043A043A0441044104480448044FC6
-:1052C000044F04560456045D045D04640464046BD6
-:1052D000046B04A4000000000000000004A404A863
-:1052E00004A804AC04AC04B004B004B404B404B81E
-:1052F00004B804BC04BC04C004C004C404C4051342
-:105300000513052A052A05410541054305430545C1
-:1053100005450547054705490549054B054B054D1D
-:10532000054D054F054F0551055105E805E805E90F
-:1053300005E905EA05EA05EF05EF05F405F405F9C9
-:1053400005F905FE05FE0603060306080608060D18
-:10535000060D0612061206130000000000000000F1
-:10536000000000000000000000000000000000003D
-:10537000000000000000000000000000000000002D
-:1053800006130624000000000000000000000000DA
-:10539000000000000000000000000000000000000D
-:1053A0000000000000000000000000000624063994
-:1053B0000639063C063C063F0000000000000000E5
-:1053C00000000000000000000000000000000000DD
-:1053D0000000000000000000063F0675000000000D
-:1053E00000000000000000000000000000000000BD
-:1053F00000000000000000000000000000000000AD
-:1054000000000000067507780000000000000000A2
-:10541000000000000000000000000000000000008C
-:10542000000000000000000000000000000000007C
-:105430000778077F077F078307830787000000003F
-:10544000000000000000000000000000000000005C
-:10545000000000000000000000000000078707C8EF
-:10546000000000000000000007C807D107D107DADC
-:1054700007DA07E307E307EC07EC07F507F507FE94
-:1054800007FE080708070810081008670867087C67
-:10549000087C089108910894089408970897089A3E
-:1054A000089A089D089D08A008A008A308A308A6BC
-:1054B00008A608A908A908B2000000000000000022
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00008B208B800000000000000000000000042
-:1054F00000000000000000000000000000000000AC
-:1055000000000000000000000000000008B808BB18
-:10551000000000000000000000000000000000008B
-:10552000000000000000000000000000000000007B
-:10553000000000000000000008BB08C100000000DF
-:10554000000000000000000000000000000000005B
-:10555000000000000000000000000000000000004B
-:10556000000000000000000000000000000000003B
-:1055700008C108D008D008DF08DF08EE08EE08FDF3
-:1055800008FD090C090C091B091B092A092A0939FC
-:10559000093909AA00000000000000000000000016
-:1055A00000000000000000000000000000000000FB
-:1055B00000000000000000000000000009AA09BF70
-:1055C00009BF09D009D009E109E109E209E209E3CB
-:1055D00009E309E409E409E509E509E609E609E75B
-:1055E00009E709E809E809E90000000000000000F7
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000000000000000000009A
-:10561000000000000000000000000000000000008A
-:10562000000000000000000000000000000000007A
-:10563000000000000000000000000000000000006A
-:10564000000000000000000000000000000000005A
-:10565000000000000000000000000000000000004A
-:10566000000000000000000000000000000000003A
-:10567000000000000000000000000000000000002A
-:10568000000000000000000000000000000000001A
-:10569000000000000000000000000000000000000A
-:1056A00000000000000000000000000000000000FA
-:1056B00000000000000000000000000000000000EA
-:1056C000000000000000000000010000000204C013
-:1056D0000003098000040E4000051300000617C0F7
-:1056E00000071C800008214000092600000A2AC08B
-:1056F000000B2F80000C3440000D3900000E3DC01F
-:10570000000F42800010474000114C00001250C0B2
-:105710000013558000145A4000155F00001663C046
-:105720000017688000186D4000197200001A76C0DA
-:10573000001B7B80001C8040001D8500001E89C06E
-:10574000001F8E80000093400000200000004000F9
-:1057500000006000000080000000A0000000C00009
-:105760000000E000000100000001200000014000F6
-:1057700000016000000180000001A0000001C000E5
-:105780000001E000000200000002200000024000D2
-:1057900000026000000280000002A0000002C000C1
-:1057A0000002E000000300000003200000034000AE
-:1057B00000036000000380000003A0000003C0009D
-:1057C0000003E0000004000000042000000440008A
-:1057D00000046000000480000004A0000004C00079
-:1057E0000004E00000050000000520000005400066
-:1057F00000056000000580000005A0000005C00055
-:105800000005E00000060000000620000006400041
-:1058100000066000000680000006A0000006C00030
-:105820000006E0000007000000072000000740001D
-:1058300000076000000780000007A0000007C0000C
-:105840000007E000000800000008200000084000F9
-:1058500000086000000880000008A0000008C000E8
-:105860000008E000000900000009200000094000D5
-:1058700000096000000980000009A0000009C000C4
-:105880000009E000000A0000000A2000000A4000B1
-:10589000000A6000000A8000000AA000000AC000A0
-:1058A000000AE000000B0000000B2000000B40008D
-:1058B000000B6000000B8000000BA000000BC0007C
-:1058C000000BE000000C0000000C2000000C400069
-:1058D000000C6000000C8000000CA000000CC00058
-:1058E000000CE000000D0000000D2000000D400045
-:1058F000000D6000000D8000000DA000000DC00034
-:10590000000DE000000E0000000E2000000E400020
-:10591000000E6000000E8000000EA000000EC0000F
-:10592000000EE000000F0000000F2000000F4000FC
-:10593000000F6000000F8000000FA000000FC000EB
-:10594000000FE000001000000010200000104000D8
-:1059500000106000001080000010A0000010C000C7
-:105960000010E000001100000011200000114000B4
-:1059700000116000001180000011A0000011C000A3
-:105980000011E00000120000001220000012400090
-:1059900000126000001280000012A0000012C0007F
-:1059A0000012E0000013000000132000001340006C
-:1059B00000136000001380000013A0000013C0005B
-:1059C0000013E00000140000001420000014400048
-:1059D00000146000001480000014A0000014C00037
-:1059E0000014E00000150000001520000015400024
-:1059F00000156000001580000015A0000015C00013
-:105A00000015E000001600000016200000164000FF
-:105A100000166000001680000016A0000016C000EE
-:105A20000016E000001700000017200000174000DB
-:105A300000176000001780000017A0000017C000CA
-:105A40000017E000001800000018200000184000B7
-:105A500000186000001880000018A0000018C000A6
-:105A60000018E00000190000001920000019400093
-:105A700000196000001980000019A0000019C00082
-:105A80000019E000001A0000001A2000001A40006F
-:105A9000001A6000001A8000001AA000001AC0005E
-:105AA000001AE000001B0000001B2000001B40004B
-:105AB000001B6000001B8000001BA000001BC0003A
-:105AC000001BE000001C0000001C2000001C400027
-:105AD000001C6000001C8000001CA000001CC00016
-:105AE000001CE000001D0000001D2000001D400003
-:105AF000001D6000001D8000001DA000001DC000F2
-:105B0000001DE000001E0000001E2000001E4000DE
-:105B1000001E6000001E8000001EA000001EC000CD
-:105B2000001EE000001F0000001F2000001F4000BA
-:105B3000001F6000001F8000001FA000001FC000A9
-:105B4000001FE00000200000002020000020400096
-:105B500000206000002080000020A0000020C00085
-:105B60000020E00000210000002120000021400072
-:105B700000216000002180000021A0000021C00061
-:105B80000021E0000022000000222000002240004E
-:105B900000226000002280000022A0000022C0003D
-:105BA0000022E0000023000000232000002340002A
-:105BB00000236000002380000023A0000023C00019
-:105BC0000023E00000240000002420000024400006
-:105BD00000246000002480000024A0000024C000F5
-:105BE0000024E000002500000025200000254000E2
-:105BF00000256000002580000025A0000025C000D1
-:105C00000025E000002600000026200000264000BD
-:105C100000266000002680000026A0000026C000AC
-:105C20000026E00000270000002720000027400099
-:105C300000276000002780000027A0000027C00088
-:105C40000027E00000280000002820000028400075
-:105C500000286000002880000028A0000028C00064
-:105C60000028E00000290000002920000029400051
-:105C700000296000002980000029A0000029C00040
-:105C80000029E000002A0000002A2000002A40002D
-:105C9000002A6000002A8000002AA000002AC0001C
-:105CA000002AE000002B0000002B2000002B400009
-:105CB000002B6000002B8000002BA000002BC000F8
-:105CC000002BE000002C0000002C2000002C4000E5
-:105CD000002C6000002C8000002CA000002CC000D4
-:105CE000002CE000002D0000002D2000002D4000C1
-:105CF000002D6000002D8000002DA000002DC000B0
-:105D0000002DE000002E0000002E2000002E40009C
-:105D1000002E6000002E8000002EA000002EC0008B
-:105D2000002EE000002F0000002F2000002F400078
-:105D3000002F6000002F8000002FA000002FC00067
-:105D4000002FE00000300000003020000030400054
-:105D500000306000003080000030A0000030C00043
-:105D60000030E00000310000003120000031400030
-:105D700000316000003180000031A0000031C0001F
-:105D80000031E0000032000000322000003240000C
-:105D900000326000003280000032A0000032C000FB
-:105DA0000032E000003300000033200000334000E8
-:105DB00000336000003380000033A0000033C000D7
-:105DC0000033E000003400000034200000344000C4
-:105DD00000346000003480000034A0000034C000B3
-:105DE0000034E000003500000035200000354000A0
-:105DF00000356000003580000035A0000035C0008F
-:105E00000035E0000036000000362000003640007B
-:105E100000366000003680000036A0000036C0006A
-:105E20000036E00000370000003720000037400057
-:105E300000376000003780000037A0000037C00046
-:105E40000037E00000380000003820000038400033
-:105E500000386000003880000038A0000038C00022
-:105E60000038E0000039000000392000003940000F
-:105E700000396000003980000039A0000039C000FE
-:105E80000039E000003A0000003A2000003A4000EB
-:105E9000003A6000003A8000003AA000003AC000DA
-:105EA000003AE000003B0000003B2000003B4000C7
-:105EB000003B6000003B8000003BA000003BC000B6
-:105EC000003BE000003C0000003C2000003C4000A3
-:105ED000003C6000003C8000003CA000003CC00092
-:105EE000003CE000003D0000003D2000003D40007F
-:105EF000003D6000003D8000003DA000003DC0006E
-:105F0000003DE000003E0000003E2000003E40005A
-:105F1000003E6000003E8000003EA000003EC00049
-:105F2000003EE000003F0000003F2000003F400036
-:105F3000003F6000003F8000003FA000003FC00025
-:105F4000003FE000003FE00100000000000001FF12
-:105F50000000020000007FF800007FF80000014010
-:105F600000003500000000010000FF0000000000FC
-:105F70000000FF00000000000000FF000000000023
-:105F80000000FF00000000000000FF000000000013
-:105F90000000FF00000000000000FF000000000003
-:105FA0000000FF000000000000000000140AFF00D5
-:105FB00000000001000000000020100100000000AF
-:105FC0000100900000000100000090020000900419
-:105FD00000009006000090080000900A0000900C5D
-:105FE0000000900E0000901000009012000090142D
-:105FF00000009016000090180000901A0000901CFD
-:106000000000901E000090200000902200009024CC
-:1060100000009026000090280000902A0000902C9C
-:106020000000902E0000903000009032000090346C
-:1060300000009036000090380000903A0000903C3C
-:106040000000903E0000904000009042000090440C
-:1060500000009046000090480000904A0000904CDC
-:106060000000904E000090500000905200009054AC
-:1060700000009056000090580000905A0000905C7C
-:106080000000905E0000906000009062000090644C
-:1060900000009066000090680000906A0000906C1C
-:1060A0000000906E000090700000907200009074EC
-:1060B00000009076000090780000907A0000907CBC
-:1060C0000000907E0000908000009082000090848C
-:1060D00000009086000090880000908A0000908C5C
-:1060E0000000908E0000909000009092000090942C
-:1060F00000009096000090980000909A0000909CFC
-:106100000000909E000090A0000090A2000090A4CB
-:10611000000090A6000090A8000090AA000090AC9B
-:10612000000090AE000090B0000090B2000090B46B
-:10613000000090B6000090B8000090BA000090BC3B
-:10614000000090BE000090C0000090C2000090C40B
-:10615000000090C6000090C8000090CA000090CCDB
-:10616000000090CE000090D0000090D2000090D4AB
-:10617000000090D6000090D8000090DA000090DC7B
-:10618000000090DE000090E0000090E2000090E44B
-:10619000000090E6000090E8000090EA000090EC1B
-:1061A000000090EE000090F0000090F2000090F4EB
-:1061B000000090F6000090F8000090FA000090FCBB
-:1061C000000090FE00009100000091020000910488
-:1061D00000009106000091080000910A0000910C57
-:1061E0000000910E00009110000091120000911427
-:1061F00000009116000091180000911A0000911CF7
-:106200000000911E000091200000912200009124C6
-:1062100000009126000091280000912A0000912C96
-:106220000000912E00009130000091320000913466
-:1062300000009136000091380000913A0000913C36
-:106240000000913E00009140000091420000914406
-:1062500000009146000091480000914A0000914CD6
-:106260000000914E000091500000915200009154A6
-:1062700000009156000091580000915A0000915C76
-:106280000000915E00009160000091620000916446
-:1062900000009166000091680000916A0000916C16
-:1062A0000000916E000091700000917200009174E6
-:1062B00000009176000091780000917A0000917CB6
-:1062C0000000917E00009180000091820000918486
-:1062D00000009186000091880000918A0000918C56
-:1062E0000000918E00009190000091920000919426
-:1062F00000009196000091980000919A0000919CF6
-:106300000000919E000091A0000091A2000091A4C5
-:10631000000091A6000091A8000091AA000091AC95
-:10632000000091AE000091B0000091B2000091B465
-:10633000000091B6000091B8000091BA000091BC35
-:10634000000091BE000091C0000091C2000091C405
-:10635000000091C6000091C8000091CA000091CCD5
-:10636000000091CE000091D0000091D2000091D4A5
-:10637000000091D6000091D8000091DA000091DC75
-:10638000000091DE000091E0000091E2000091E445
-:10639000000091E6000091E8000091EA000091EC15
-:1063A000000091EE000091F0000091F2000091F4E5
-:1063B000000091F6000091F8000091FA000091FCB5
-:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A
-:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
-:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
-:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
-:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
-:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
-:10644000FFFFFFFF0000000300BEBC2000000000B3
-:10645000000000050000000300BEBC20000000009A
-:10646000000000050000000300BEBC20000000008A
-:10647000000000050000000300BEBC20000000007A
-:10648000000000050000000300BEBC20000000006A
-:10649000000000050000000300BEBC20000000005A
-:1064A000000000050000000300BEBC20000000004A
-:1064B000000000050000000300BEBC20000000003A
-:1064C0000000000500002000000040C000006180C6
-:1064D000000082400000A3000000C3C00000E48070
-:1064E0000001054000012600000146C00001678050
-:1064F000000188400001A9000001C9C00001EA8034
-:1065000000020B4000022C0000024CC000026D8013
-:1065100000028E400002AF000002CFC00002F080F7
-:10652000000011400000800000010380000187008E
-:1065300000020A8000028E00000311800003950013
-:106540000004188000049C0000051F800005A300C3
-:10655000000626800006AA0000072D800007B10073
-:10656000000834800008B80000093B800009BF0023
-:10657000000A4280000AC600000B4980000BCD00D3
-:10658000000C5080000CD400000D578000005B0010
-:1065900000007FF800007FF8000000D50000150023
-:1065A0000000FF00000000000000FF0000000000ED
-:1065B0000000FF00000000000000FF0000000000DD
-:1065C0000000FF00000000000000FF0000000000CD
-:1065D0000000FF00000000000000FF0000000000BD
-:1065E000000019000000000000000000FFFFFFFF96
-:1065F0000000000003938700000000000393870061
-:1066000000007FF800007FF80000069200001500EF
-:106610000000FF000FFFFFFF0000FF000FFFFFFF64
-:10662000000000FF0000FF000FFFFFFF0000FF0061
-:106630000FFFFFFF000000FF0000FF000FFFFFFF44
-:106640000000FF000FFFFFFF000000FF0000FF0041
-:106650000FFFFFFF0000FF000FFFFFFF000000FF24
-:106660000000FF000FFFFFFF0000FF000FFFFFFF14
-:10667000000000FF0000FF000FFFFFFF0000FF0011
-:106680000FFFFFFF000000FF0000FF000FFFFFFFF4
-:106690000000FF000FFFFFFF000000FF0000FF00F1
-:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4
-:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4
-:1066C000000000FF0000FF000FFFFFFF0000FF00C1
-:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4
-:1066E0000000FF000FFFFFFF000000FF0000FF00A1
-:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84
-:106700000000FF000FFFFFFF0000FF000FFFFFFF73
-:10671000000000FF0000FF000FFFFFFF0000FF0070
-:106720000FFFFFFF000000FF0000FF000FFFFFFF53
-:106730000000FF000FFFFFFF000000FF0000FF0050
-:106740000FFFFFFF0000FF000FFFFFFF000000FF33
-:106750000000FF000FFFFFFF0000FF000FFFFFFF23
-:10676000000000FF0000FF000FFFFFFF0000FF0020
-:106770000FFFFFFF000000FF0000FF000FFFFFFF03
-:106780000000FF000FFFFFFF000000FF0000FF0000
-:106790000FFFFFFF0000FF000FFFFFFF000000FFE3
-:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3
-:1067B000000000FF0000FF000FFFFFFF0000FF00D0
-:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3
-:1067D0000000FF000FFFFFFF000000FF0000FF00B0
-:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93
-:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83
-:10680000000000FF0000FF000FFFFFFF0000FF007F
-:106810000FFFFFFF000000FF0000FF000FFFFFFF62
-:106820000000FF000FFFFFFF000000FF0000FF005F
-:106830000FFFFFFF0000FF000FFFFFFF000000FF42
-:106840000000FF000FFFFFFF0000FF000FFFFFFF32
-:10685000000000FF0000FF000FFFFFFF0000FF002F
-:106860000FFFFFFF000000FF0000FF000FFFFFFF12
-:106870000000FF000FFFFFFF000000FF0000FF000F
-:106880000FFFFFFF0000FF000FFFFFFF000000FFF2
-:10689000000000FF000000FF000000FF000000FFFC
-:1068A000000000FF000000FF000000FF000000FFEC
-:1068B0000000FF00000000000000FF0000000000DA
-:1068C0000000FF00000000000000FF0000000000CA
-:1068D0000000FF00000000000000FF0000000000BA
-:1068E0000000FF00000000000000FF0000000000AA
-:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
-:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
-:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
-:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
-:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
-:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
-:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
-:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
-:106970000000100000002080000031000000418075
-:10698000000052000000628000007300000083805D
-:10699000000094000000A4800000B5000000C58045
-:1069A0000000D6000000E6800000F700000107802C
-:1069B0000001180000012880000139000001498011
-:1069C00000015A0000016A8000017B0000018B80F9
-:1069D00000019C000001AC800001BD000001CD80E1
-:1069E0000001DE000001EE800001FF0000000F80CA
-:1069F00000007FF800007FF8000003400000150051
-:106A000010000000000028AD000100010022000677
-:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41
-:106A20000000FF00000000000000FF000000000068
-:106A30000000FF00000000000000FF000000000058
-:106A40000000FF00000000000000FF000000000048
-:106A50000000FF00000000000000FF000000000038
-:106A60000000000000000001CCCC0201CCCCCCCC5A
-:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80
-:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70
-:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60
-:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F
-:106AB000000E0000011600D6002625A0002625A005
-:106AC000002625A0002625A000720000012300F367
-:106AD000002625A0002625A0002625A0002625A00A
-:106AE0000000FFFF000000000000FFFF00000000AA
-:106AF0000000FFFF000000000000FFFF000000009A
-:106B00000000FFFF000000000000FFFF0000000089
-:106B10000000FFFF000000000000FFFF0000000079
-:106B20000000FFFF000000000000FFFF0000000069
-:106B30000000FFFF000000000000FFFF0000000059
-:106B40000000FFFF000000000000FFFF0000000049
-:106B50000000FFFF000000000000FFFF0000000039
-:106B60000000FFFF000000000000FFFF0000000029
-:106B70000000FFFF000000000000FFFF0000000019
-:106B80000000FFFF000000000000FFFF0000000009
-:106B90000000FFFF000000000000FFFF00000000F9
-:106BA0000000FFFF000000000000FFFF00000000E9
-:106BB0000000FFFF000000000000FFFF00000000D9
-:106BC0000000FFFF000000000000FFFF00000000C9
-:106BD0000000FFFF000000000000FFFF00000000B9
-:106BE0000000FFFF000000000000FFFF00000000A9
-:106BF0000000FFFF000000000000FFFF0000000099
-:106C00000000FFFF000000000000FFFF0000000088
-:106C10000000FFFF000000000000FFFF0000000078
-:106C20000000FFFF000000000000FFFF0000000068
-:106C30000000FFFF000000000000FFFF0000000058
-:106C40000000FFFF000000000000FFFF0000000048
-:106C50000000FFFF000000000000FFFF0000000038
-:106C60000000FFFF000000000000FFFF0000000028
-:106C70000000FFFF000000000000FFFF0000000018
-:106C80000000FFFF000000000000FFFF0000000008
-:106C90000000FFFF000000000000FFFF00000000F8
-:106CA0000000FFFF000000000000FFFF00000000E8
-:106CB0000000FFFF000000000000FFFF00000000D8
-:106CC0000000FFFF000000000000FFFF00000000C8
-:106CD0000000FFFF000000000000FFFF00000000B8
-:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329
-:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66
-:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB
-:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44
-:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316
-:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23
-:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC
-:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC
-:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA
-:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD
-:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2
-:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5
-:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304
-:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85
-:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7
-:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45
-:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328
-:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65
-:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389
-:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43
-:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315
-:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22
-:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB
-:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB
-:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9
-:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC
-:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1
-:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4
-:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304
-:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84
-:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386
-:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44
-:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC
-:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98
-:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB
-:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76
-:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B
-:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55
-:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B
-:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33
-:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B
-:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F
-:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B
-:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7
-:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B
-:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7
-:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB
-:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77
-:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5
-:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63
-:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387
-:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41
-:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313
-:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20
-:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9
-:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9
-:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7
-:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA
-:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B
-:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5
-:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD
-:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5
-:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3
-:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42
-:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4
-:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62
-:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367
-:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40
-:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312
-:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F
-:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396
-:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C
-:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6
-:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9
-:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE
-:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1
-:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320
-:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81
-:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9
-:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75
-:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9
-:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95
-:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8
-:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73
-:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398
-:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52
-:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378
-:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30
-:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358
-:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C
-:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338
-:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4
-:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318
-:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4
-:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8
-:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74
-:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8
-:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94
-:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7
-:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72
-:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397
-:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51
-:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377
-:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F
-:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357
-:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B
-:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337
-:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3
-:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317
-:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3
-:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7
-:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73
-:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7
-:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93
-:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6
-:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71
-:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396
-:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50
-:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376
-:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E
-:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356
-:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A
-:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336
-:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2
-:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316
-:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2
-:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6
-:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72
-:1074E000000C0000000700C000028130000B815832
-:1074F0000002021000010230000F024000010330C0
-:10750000000C0000000800C000028140000B8168F0
-:10751000000202200001024000070250000202C0E7
-:10752000001000000008010000028180000B81A80B
-:107530000002026000018280000E82980008038031
-:107540000010000000010100000281100009013854
-:10755000000201C8000101E8000E01F8000002D895
-:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B
-:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B
-:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B
-:10759000CCCCCCCCCCCCCCCC040020000000000067
-:1075A0001F8B080000000000000BFB51CFC0F00350
-:1075B0008A37B231306CE344F0E98159181818F871
-:1075C00099C8D7BF0668C01620BE0CC47B5848D7E0
-:1075D0007F5E1AC15E20C9C0700488BBC51918EA55
-:1075E000A510E296320C0C3780FCC5503109A09EE4
-:1075F00069D2E4BB79140F1E9C648ACA773586D0A1
-:10760000374D2074329ABC1B545E500F42A79862CB
-:107610003757488F38FB1354D0EC57C1AF3E5D034A
-:10762000951F8EA6DE0FCA0700DCEC914ED8030032
-:1076300000000000000000001F8B08000000000098
-:10764000000BED7D0B7815D5B9E89AC79E3DFB99E7
-:1076500049086127049C8400C1F2D84280A0142705
-:107660001030B6D46E5E12BD081B1F95872411D34F
-:10767000635A39CD401E2401243E4AE92DD50DC55B
-:10768000367A6D1B6D6A698FF66C442D9EDBD303D1
-:10769000942AADE0096A2D58A0B1A71C68BFB6DCDA
-:1076A000F5AF47F6CC64761E3EFAF57CB7F193C988
-:1076B0009A59CFFFBDFEFF5F2B0A2A443957217428
-:1076C000057EAE47C8101042D3534F744F86887260
-:1076D00010FABC8AC8CF255F7832CA40A84EA5CF21
-:1076E000FBFDE17DF06CAB4728391EBE8F4EA0300C
-:1076F0004201848AE56C68E18F3E5100CF9A29B13E
-:1077000049E439139E594844683894F3B57703B473
-:10771000EF2B12FEE764BC0CC693E82B24A3D268BF
-:1077200092B47F00A119A979A09ACF6AB1506ADEFC
-:10773000CEA7A42928C9EA5E817FA41519F160FAB1
-:10774000FA752785EFBE64A93F1685B2C9BC6424CB
-:107750009379B1F60899C83A3F673F97EAD1775FC6
-:107760001ADB176EE9C6E5706BA957C9B3B95E435A
-:10777000492F42B899D139113F83C8D837B16FBB6F
-:10778000722430F8B1F9C0383AAE8FFF4718EE8D49
-:10779000D92811001CA2B80D6E8DC1C5AAE1D21F57
-:1077A0007FA26C0CB76236E7C2BEEBF5C1BC301CE1
-:1077B0007C302F17782E87794DEF3B2F5F91735ECA
-:1077C0006B90153E439D977F024247001FB2811088
-:1077D000C1CB7DB6FE44CD30BB5DFA438C2E649D9B
-:1077E000AD6F90780A148BA9F1010EBADF465FDE07
-:1077F00048969DDE9C740DF020F86A67F0894994E4
-:107800001FCC141EF13350AA0BA890148F00DE2257
-:107810000CEE913B9BEF15315F8551A2651CE6870D
-:1078200048F7EA85C067E193379E459331FCA25340
-:10783000D579784D5A89FED002FC0C4CD404A0D7DF
-:1078400036E0B36BA1BF5BCC325C6E80CEF270D100
-:10785000BCC93009DC0C1BDC30E47419973DF06BBB
-:10786000A10BFC502F1E842BDEBEEDD3C1CF832C89
-:10787000F823FCBCD1469769F11EA7ED4CFC1FE034
-:107880002BCBD18F566EE7F330B294F1F7A7E01708
-:1078900002EF7BFF26E365A27DAA5E82D75B2C6A9E
-:1078A00009A88FF44C1997031532023996998D0E59
-:1078B000628C0C889746842A80FF11EA448B26A5A7
-:1078C000E6F7AF8CBF723FF7E8EA66CC4F174B8301
-:1078D00051E0AF8886D0B0ACBEEBD9CEE44B6F3967
-:1078E000FA2C8A4F84F1122D85785E66548C3E0105
-:1078F000F3297E518B5BF8E574AF7C71D207D2E53A
-:10790000194C1E60F848C5A2E19BFCE1E943FA80EE
-:10791000F4118C2B36BE1C2ABE2E0C913E3EEC7808
-:107920001CAF7DF96A33C36BA30AF2AC455FDCAFD1
-:10793000BEEA8BD77D08EA078A91917069F75F5696
-:107940007DE17C5AE4BB538E4A236654EEED0F6F03
-:10795000D97678F07E7D7592FECE305C9435225FCC
-:1079600015A6075A230F9B08D3DD45903D181E52DC
-:10797000FB354928A32244E810FF24055CF6458C1A
-:10798000441BA18304C10B9F9F57176DF095B3ED66
-:107990007218559A8275FEBE3A85CC4381F1B2C108
-:1079A0002EC01D6250C84194F485A1069D3FA8A435
-:1079B0002B63A06CB7335AF4A9C80D0F32C3AB20A8
-:1079C000707A7D6070F2C539DE52FB7C07DD2E28AF
-:1079D000EBEFF2362E723AD54E46EF72FC6020CEB7
-:1079E000E1761DC3D3560F3A204CC1F220FF66B09A
-:1079F00014D056F8340BDB21F0CCC5E5FCA9442E9D
-:107A0000A00E4186799221311E11D677502F20E8A1
-:107A1000A41F51AD2172450A1AE4C9BFA79F171DC3
-:107A2000BFB7ACC6AB003F6B228ADE86E7B85E32DA
-:107A3000F4CD4017D3B07CD2E1FDB872D0731E8173
-:107A4000CEEB4B422E59879CD59243ECB234F6DDF7
-:107A50001A19F3E454F8BE7D5C7FFC84129E9E6E7E
-:107A60000B3C9DF6E0DD02B6073F817F99896602F7
-:107A70001C7F1F5D9C91EC075FEFD51FD6E4B129F9
-:107A80007BD0F97DBD846ADCE440B3A052BE544D86
-:107A900005EC03BEEEF5982FBC59C0E75BE87AB35E
-:107AA000B3097CD777BCAAC916FE5B8FD58C776AE1
-:107AB000DFF57078F37E7ADB270EDBDA3BDBF5F659
-:107AC000C7E505B68781CE391D0484F83601BFF7B6
-:107AD00046179B7930FED36514FF69E6DF8BAF0F45
-:107AE000387FDE6E20BAFAFDFE8666D04FEF2AEDB3
-:107AF000375D8BE9E837CF48D12DF8EB9A3DE3CBE2
-:107B0000C16E7A97D137C7D3D9FD0D396EF4910E76
-:107B10004FAF0A3E320EA7AF35E28A7EE96120FA06
-:107B2000FA9E93BE3A977C2CF475C4495F0C1EE70D
-:107B30003AE9FAD1EE61142F0C5F4EFCA4C5CB07D5
-:107B40006DD7979E7E2160BEF6762E71A727365F91
-:107B50008EAF0F3BDF81E82847370C0D8F3F02DBEC
-:107B60003102E88F12144DEA60D745A9DE8A52BD72
-:107B7000C5E5126F7F41A0769A8C8E93F6124A9AD1
-:107B80001AB1B7ED76C67C09BFC4FD3416A384973D
-:107B9000EC8B0C95E8A9621951FD67047371FD0C1B
-:107BA000C47EA4D951587706B3FFD16CA67F056C6B
-:107BB0006FE1F5054BECF687DF619F48B05F08BBCE
-:107BC000D85B43DC1FFB44B63F0EA020D1477C7F2F
-:107BD0009C863F7BF7C50CAEC315648878DDCA610F
-:107BE0004F628B00DA0D11FD8C4E0A09EA2F40C559
-:107BF00060376F14F2A2A00FF03EAF27037F7FF72C
-:107C00009B12D10F75919A554DB0EC9BEBC677E363
-:107C1000711FAE47D38A3CA9F11E96DB5580776B66
-:107C2000D146CDBAAEAF09F102D1A2777C11655A27
-:107C3000D134184E7EAB1BC343C48004FEF3071F30
-:107C40008DBCAC03FCE8FB5E3859CB52DF7236D8F2
-:107C50003C79A498043BAE3584A89D8F460A65986C
-:107C60000E5A3DFCFBEB65B0DF6DF5D1F29E2DB3F6
-:107C7000369B501ECEEA9B95F47B2E2DDF273E517E
-:107C800006DF139978CD5380AC13953117FEBE4FA4
-:107C9000A47E95067346EC2E323D6A7F5DC5F7D90A
-:107CA0004B6E8ABE0CBF14E923C07F220563C4BE9D
-:107CB0009198BD266B26D5E36AF4F0780CEF51C796
-:107CC000256462388C6A3F5AE6057A0F723B2D8A2A
-:107CD00096E2F675CC1FA022BA3F06BFCE1542C76A
-:107CE000FA08D8B720B0CF2CFB7689D963BD78725B
-:107CF000E0ED11B986E06D6B7EEDE1023CBEB9505E
-:107D00008C02D96CCD2FCC5C6DC1E3B7D4B9952270
-:107D1000D8318DD9C42EE1FB64601828E792290080
-:107D2000683BCBC078CCC7920F613A1D1DEB29038D
-:107D300014E895DA8B648F8BCAB577895D2509576E
-:107D40003E31783B0AD62D02BD62FA7DC2B2DE61B9
-:107D5000028AB9C9DD157216C1CBB00ABCDE7EFC41
-:107D6000049FC7FA84DA677135164A3F4EBA797EA6
-:107D700008786E01BE188912044E03C1351D3C9B64
-:107D800023CF661279FD11C3355D7B273C870994AB
-:107D90005F56C8A5845F06EBDF6981FD14DEAF3650
-:107DA000811F0E3F1B981FCED9DE27B7A3A80B7EDD
-:107DB0007DBADD3FA458E91EFF5F2BEA541F049DE6
-:107DC0007E228A67A75E58C0F4425304EB052A0F4F
-:107DD00017821E0830F8374511F9AE8450C2C4DF4F
-:107DE00003A00FB09D852652F9AFE2FF80DF465415
-:107DF000DAF58132487DF08E107B99F0174621CC60
-:107E00006FB7D07EE338A09F5C6A8F476E6F89584A
-:107E1000FD05B522D5775C9F3D56D43B6F023F2FC1
-:107E20009BC36358A4023D26F2176710BFDD9D0176
-:107E30009B7C8A7C6931D9FF5AE899EC73DB997F86
-:107E4000341DFE342511779387BA249279858D9E4F
-:107E500024F8FC0821E7309721236B0A7F64DB8735
-:107E600085A7F61C1E83D7FBF83522B11BE5D97216
-:107E7000D283E12B97BE5229E0E7E3B03680C72CCE
-:107E800044E834A82F382B813E96BBD122DC5FB06A
-:107E9000C2B92FB69425E8A76725D1DF563F753FB5
-:107EA000FBB8C13E1B30BCDEB2F03F42B10AD0B3DA
-:107EB0003296E36D88B84BF3605CD9D072805E6413
-:107EC000231A24CFEEB20A5A8EB5C177DFECE8D17F
-:107ED00072E0434D26F23EA152BCF17EE74805B662
-:107EE000FD5BA6E6F08FCA6625D0814F5710D0A75C
-:107EF0002FAE180917FCD48A329377763AE1F4D181
-:107F00008F9CFB5074714AE47E6A3BDE6DF451989D
-:107F1000C22B6F17ECE3A7B2E3D559FEA8F1E99B9A
-:107F20004DF189303E99BFA40DE01C344504761113
-:107F3000AF17900A6DF8095EC61B2B6CE7EC2E4359
-:107F4000956EFA292029A43EE6FB7289DAE502D86B
-:107F5000DBF3A53D06D079A208E306F7DFE2C126F0
-:107F6000112EB76C16395E89BCADDDD252B619D769
-:107F700069392988D214A09BE5049F3EE6F7B9E44D
-:107F8000312B0A71BBB65122DAA783FEE9DFBFD5D8
-:107F9000506FF76F815F01ECEFFC1A6D2A80395D3D
-:107FA000BB5D3562859BFFEB2E89FABF76D41C6BD7
-:107FB0002766E84BF67D876785011408FB8FBBA415
-:107FC000E9A976A112EAD74071BC1E5CDFC3D733A2
-:107FD0001CD3673FF18AFFCDF4092FE7B1788EB348
-:107FE000DE4F2446873A8597CAE8F05241FFF4CF26
-:107FF000E173B9456271901E1F227A7738F1DFE98B
-:108000006C5D9279A40CFA9151F766D887EC12D185
-:108010001AEA578E117D1366E33D5EFA7B1FD4BBCF
-:1080200041A6F27294D1D30A781EB54944E0C77EC6
-:108030004AD249D72356D41CF4E0F7AD9B5134887B
-:108040005F8D867E71BB57C62A44EEABD954EEAB2A
-:10805000B59804703D15EF6B745C6E3DD88A40AFE7
-:1080600087F1C6094C5EBD1489E0E7F6D4759B30F4
-:108070006EB8344AECD0436367907DD583D928EA43
-:10808000D5537281D3D1839B161B40072D781F06D1
-:10809000E596A22D2AF8B12F16CBA48CFE8CE1C355
-:1080A000FD85F81FDDA474D35A40E72B4FEC462220
-:1080B000E15B95E053D6E8FA5B43DF34617EE65A34
-:1080C00044EC23B06F497C468EAA20CFF377CF26AD
-:1080D000FC236BED02D0C346147FCA4A27523049B5
-:1080E000E6DFFA1789D9EF2F6D06FB7D247485CB67
-:1080F000AF4AE7370FC51EE171416E8FB4C99D8449
-:108100000F4DCC63A06FB87DE22BEA24F4F9DF8C2D
-:10811000BE07DBBFAFD8EE4775DA2B4E3BA556D472
-:108120006C76A9735D973CC91B617E6DB998BF0BD6
-:10813000FA8E775CA2FB923D91C5FF51A0A7FAE1B0
-:10814000DFB97DC4CBF9971502EFC1D7C7F20DF6A1
-:108150005E06E5A3D19C4FBFD03F9F723EBA84918B
-:108160007E04F0239B2AE123A398F011E70FA9DBFB
-:108170006C1983E94CAF13C1238DC04CCFC2E5AB62
-:10818000307D2785149D8E62E3CA1313EDE35DE80D
-:10819000ECB15AD120FEEF28EE067F0F9B4788995D
-:1081A000E92F4E70BABA0874C5E92C7FF702B2AE57
-:1081B0005781A0A7835E7597233F62760ED2F61B88
-:1081C000563FAD0F35BAC7CF6B1FEF377EAE167D6A
-:1081D000B8F87948B6FBB3066A3FD4B8B9747918D1
-:1081E000A18FDE32DB873AEBC565265F4FEEB3C168
-:1081F000A50F3CA4EDD1783F74A27E487F3FD159B2
-:10820000838083138E3364E667F998E0E88C6BBF54
-:10821000CCE4FC40F2C06F1849710CF8C510F5DBD6
-:108220000411F3DBD8E9FDF14D94DEFD21712F88B7
-:10823000A870ED11D36B990FA6F725F2F014BDE7E6
-:10824000152793801FA7FE49A7770692B72B55E302
-:1082500036D925CF84EFB3537904988B5DF208D2D9
-:10826000E2B5E6A3C923182CBC7BFD962C2FE0F6C3
-:108270005246B7D8707803C365ED610FB1EFB1FE18
-:1082800093ACF1B2B56C7F773BDB1FDE896261F89E
-:10829000781E8915C02FE7D1B1F0340BDDEF9415AE
-:1082A000CA2F2D9EB7C06FCAE3E077B5D3329FCFF8
-:1082B000DDBBEDE5CFA1C539E0AFFBDCA31EF020AF
-:1082C000A0B50EBF593D10049EFFDDA8A619F0D63B
-:1082D000E4A176E8ED1A92216EBDE1075F9FB11A25
-:1082E000EC13667FBC87E5B26EB19FD605130AE03A
-:1082F000F7EDAE69375F87A07DA2390FE2D7998885
-:10830000EC479D70BEA3C53EBF81E6EF9C2F425B4C
-:10831000FA9D87DC21B8C659F7CBF6386BBA7C29B1
-:108320009E27F5924CF16FCE45C47E32DF0C241AA5
-:10833000883EA1795203B57F15DA4FFFE0ED7F3615
-:10834000C0F81BD49E05C4CECA3663E0EFE1F1BE8F
-:108350002A54638CC4BFCACF2F3281E77AEB45061B
-:1083600059AFA8FF7AE9E67D56534D714A6AFE5F20
-:1083700013E2276597F5DF2FC5ABA07F2FE0418281
-:10838000A74CF04DFCBB18BFD572B045C8803CA6C9
-:108390002EB2CFF3E9B28D1EAAE117906BC554AE91
-:1083A000058AEDDF9D7EDFDFF5E23D49F88F84969B
-:1083B00075B01F824909FC32A5F2B9DEFA78BC2AF1
-:1083C0005817EC93508CC88D5A8DD6AF42FACED93F
-:1083D0002584FFC8BEBBB6750C8997D70ED7A3E01E
-:1083E000879551D4207D38E8AEFAB28012167D58B8
-:1083F0002DF728C067D5D82EB2BEDF18916CFE5776
-:10840000E7D383543D584CFDB9C43FA4E1B265DDC8
-:10841000BF6F17585E8A9EB1B41FBFDCC608F5F364
-:10842000DEDE3A3683FA03EDF2F702DB1FFDE4E904
-:108430006F28E0BF3FFFD4E99B00DEEBFF45422AF7
-:10844000E4653C1D4249628F2514B0C7D67549AE1C
-:10845000FE0392390371CDEF8608BED63DEB4D2C5D
-:10846000C4EDD73DF7F66484E777614BCF2B23C18A
-:108470006E7E4AA07E6BB37BF212FC7E9D8C56B959
-:10848000F9058A3DD44E3DF7C34025F0B7D0717051
-:1084900025E9B773B9C76BD95F5FE5F1F07AD42EE0
-:1084A0007F52488C15DCE647F33ACE3D29D0F91DC2
-:1084B000F0247C30BF8EBD4A1CCFA3BAE37D224F8F
-:1084C000E67DF7DB618043F501C9A607AA3BA4A4BA
-:1084D0007732799E8627C483841940278C5EBA360A
-:1084E00090385055E7B6F7C14F517DC02ED7305C5C
-:1084F000A24980EBEB52742194BFF7ADB08E41F5E9
-:10850000DE9127C20057DCEF6A2503F48D9DBEA1E2
-:10851000FFCB597DFB43A887C4E1AA3B5BE9785DAB
-:108520009FF90DE8956A87FC7C0F7EC9ED6BCFC47F
-:108530003C0EBBB0637071B8F5DFBEF89889C73DDB
-:10854000F7EC6F1F33F1FCEFF9EB7F3DF600F0E73E
-:108550008F7D1AC8FFEAA77E1146167A5CE7A1FC58
-:10856000786114327371BD0BBFF4264CFCEAC20B68
-:10857000BF19ADE3755F78E68F393AAE5FFBC2FC99
-:10858000110087DAEFCF1BD1DF7E1BE835E1B5CED6
-:108590002B41F0AA1F10A811F43C7B3AF073A8EB12
-:1085A000D06898E7F913DE28D83DD5F85DDD54C0D2
-:1085B000D706A28FA1BC09C3B9EAE9ADEF839CE855
-:1085C0000B6F73A4489CF0C991E08CAFEA7A7B01F1
-:1085D000C11BEA217AD459BFFA38C6E794F4F8BB34
-:1085E00088FEAC80BCAB7EBA958ED789F117EE8B36
-:1085F000BFF3F0CBACBEF86B71E0EF22BAE7F15CF1
-:108600004868EB1A668B7FF2672AEE17CB88F52352
-:108610002FB83C1808BE6B043AAF651E63B707F865
-:10862000EAD9402F7E17027EBF7D7134C2F471C635
-:10863000D3B312E466CF0B5E6D1F7EBFEE85D70904
-:108640009F5DF8FE51452779972828E4B0FC2FFA62
-:108650007304E47015DDCBA1EAFDA1A4379CC253DD
-:10866000556251851E26EF4F93F7094AFF558983BE
-:108670004B0517BC1DF314523B2A319CC065C3FE49
-:1086800037146A5FA6F02994023E4F2F80F7E9F075
-:10869000C9D7AFC1FA675AF0BA9FF2ADB37E15E6FB
-:1086A0004FD07B7DF09B105E87E785BD5E19F4DEC1
-:1086B00005B0BF827DF19E823FB57F86BA5FF9A982
-:1086C00093BF795C98C1213D7D98CC0EE87F7D43B6
-:1086D00085DF8F3CBA8D8E381CCFFDD95DFE9F6142
-:1086E00072A30A99157916FB44F560FB04F2C65093
-:1086F000CC1C59909AEF39D84760FA3BF79444E282
-:1087000030CD9D87881C77CA8BAA34FEBF3FF2F11B
-:108710000E1C9C0C72EDDC8B3F24F459F5F46905BA
-:10872000FC63AF747C4FE99E98E207D00F098B7E03
-:1087300038F79D8393A93C70DFFF2A0AEDBFFA79D1
-:108740007BFFD54FBF6FEB7FBDD9A9D0FC84FEC79F
-:10875000794F3696C37ADF3BE241204FDFEB945CE2
-:10876000FDADBF05FD68C9336B3EBAE00D88DF97EC
-:108770001CF3EBA047BBB618237680BD76CC8340B4
-:108780007E23D9F82DC497BB8EFA75C87BE83A765C
-:10879000B3A45BFC133F70C073E671735E08F737D8
-:1087A000B33B56025B28A7DC283D2942CCA277FECA
-:1087B000B5472B4680DC6F047B7E3C8C178D90F890
-:1087C00077784105CD0B14359FABFEA6FD79589CFB
-:1087D000DCA38948B7D223DF6F31BF4F73D0DDFFF1
-:1087E0005CA670FB108F6B9183D856AD74C35B8908
-:1087F00042F741E9BE970EF07DB6C2F200D27CEF9F
-:10880000E56F861F2524C6DCE63D99F5E3F4ABA6AB
-:1088100093071ED6CF144567FDD3F502BC1759F256
-:10882000DD47A2C466F07FA160D019678EA9D63853
-:1088300073E591831057CE5EF27C2EC03F8C1AB543
-:1088400077891D8FA257FAB1639D716567BE61BAC2
-:1088500038B31AAC3A91447DFBEB1B5737485CBDEB
-:1088600031BF5CB5C6D51BB53E71F50D0A1EB729E3
-:108870000D1E3EABCCBD17BE63B333EEF6BD49A1B2
-:10888000FEABEB51F7F756C33CA3342E3FDB01AFF1
-:108890004F3278FD780C5E38563D6548973D18BEDE
-:1088A000F3961A8D2002E7AFE8597F10F88CC7E5E0
-:1088B000CDF1E295C0E0E137D47C8795EAE20795F7
-:1088C00041E43B202DCB552FA4E66132BE89907D3B
-:1088D000128FBF1C3A75B70A724B46F18A024B3CA5
-:1088E0008CE4D1E3FE72923E64E0F92A9A4EECEDFC
-:1088F0009CE4DAAFDE05F1722D9FC41FA4CBD71123
-:10890000FFA1B35F291235499E57502F932CE334B2
-:1089100067D3788CACC55CF381572AF1A761BDD2CF
-:10892000E539A45F51A5F10C141C5C1EEC5796842C
-:10893000097C550C5F908F0464B02E960FF5D09291
-:1089400030D133BEC39EBDF0DD17A4F951F78BFEC5
-:1089500028E44F39F3A3CADEA4F196E6D30289A333
-:1089600070FA6D2EA8B90AE4783FF9512F2B16BF83
-:108970007ABAFC285FF04E921FE5FBC0F951917264
-:10898000B0C79A337919AB133C8F6696EFF42BE599
-:10899000F03CD04FCD2C3F0A99AFCE23F57919D5B5
-:1089A0001C32E03BCBA7CAD9DADC00F5B347A29A68
-:1089B0004EE2CF33D0328B9CF579699CF9CB8AF1AA
-:1089C0009F8A45EE71FCFB7AE96AAB0AFA1B3F49C4
-:1089D000BCB219D315D8ED39C95664D547FCC9E9DD
-:1089E000A8B9A8FF789D7CF91AE2C7E765554B182E
-:1089F000864B7D43A57A82D32FC4D3402FA97AFC1E
-:108A0000AB77013D6707A3014A97244ED61224EEA7
-:108A1000A93EEB6829BA9DC4BD2E6AD4DBCDE9B866
-:108A2000EFFCE7B0F9179A405F1783288A5CE45F90
-:108A30006A1D25641D2B1543F55AE0987D957BBE74
-:108A4000E9762F5D4F536C45EC2E98C91A7BDC9567
-:108A5000E75FF0FA01213E1CFAF564D3B8ABA852E7
-:108A60007E4BE10BAB0A8B7FB301AD308104E41583
-:108A70009DE4C8A2AC2548FD31BEF868AF2D3ED7B5
-:108A80004DE3B88E78E27CE91ECADF03E06F07DBB6
-:108A90009F6C83B8DB7888CF45D8B93D9DC5E90C7C
-:108AA0009A2F94869E5A8AFA8F43B5D74749FB9DE1
-:108AB000F5A5340F4940CCAFFDF506A013704B501F
-:108AC000BADFDF007C1092385F3C45CA0F0AB41C45
-:108AD000DFDA45F8E6D0A9D72BEFC0F4D16CF8095E
-:108AE000FF0FB43E2D3183E075A8E3F45D2F1DB771
-:108AF000C50892FDEE40EBD69274DCC18EC3E3E371
-:108B0000A9F5A9649C667D8071DAE93803CF9FF2EC
-:108B1000C98E836B2B20AEAC62FEF7E1F7EAEC1E48
-:108B2000E4161FCA60FC73E89497C8EB966C9AC76A
-:108B3000EB290E1AD40968EFDF3331672E39C7509D
-:108B40007235C98BDF71B095C81905C6C1553CD1C6
-:108B5000E06ADA2E6EC0F9D970398A825FDF539CE1
-:108B60007307BCAF43EDB1B9A0874BE9B92D4F7185
-:108B7000F15DD04F26F0259EC73495E67D788AAF0B
-:108B8000BD1BEA1F9CFE5ABC01E0544AE9001DCE01
-:108B9000B5C1B1592FE4E771FAE57B4FA93D6E816C
-:108BA00054BF2D6F09C94B49BC1CCB856D5E8BFF33
-:108BB0001BEBC59D50F6A01213ECBD5DB7DC1CB5D8
-:108BC000F2F39795D8C3548EF03C2CCEE7EEF970B3
-:108BD000CDD93CAF2CAE4A2570FEA8374F7A61AE96
-:108BE00035AF8BE54907799E7494C6E1DAF17F6E63
-:108BF0007971CEF3891F559EF477BC6C3F1C40A35E
-:108C0000204FFA471E144DE279B7FD428A421E8C6E
-:108C1000933E9CFD39F3FB7BED9134FCFC6B008EA5
-:108C200045EEE5C61D78BBD347E2737CBC97403E5A
-:108C30004D1C984F47AEB1F733AAC67EEEEAAA3A6A
-:108C40007BBCAAC0CCB3D51FD35268FB3EB6FD6A2D
-:108C5000DBF7F1BBA7DACA1312D7DAEA7FA263AE59
-:108C6000AD3CA9F353B6FA530E2CB695AF49DE6A64
-:108C7000AB3FEDF0EDB6EFD38FACB37D9F7962A340
-:108C8000AD3CABFB8BB6FA75D83C51483E1C8D37DA
-:108C9000A1ED23452B7DB66662BD9281E1988909DD
-:108CA0008626EB937833CD314EE51938DB49458A7A
-:108CB000A161FE95F471E51AC91FBC93F09154941B
-:108CC000335727EF672C00BF132AA1E7AF7CAC3FD7
-:108CD0004F114AC2B94B39E8C0AF232EED91B6937C
-:108CE00078AA72F286C342B82F5E3D11679EE2E019
-:108CF000E2DAB2EE683744BEC854595C7B14E60B26
-:108D0000E247FCB344CE3D9787887D60D9DF1038B9
-:108D1000F2FDCD1C1535024C395F94ADE81949F2CE
-:108D2000D97BF7355E7128F9C67DF58A97D85D5CE9
-:108D3000CE0CA457A4C4345B1E82F389E5DF14155E
-:108D4000F6E1E15B893CEADD17F4CAC7D854F8EED6
-:108D500091A3443EF6CABF8E3C9B5C18AC7DE69462
-:108D6000D36D20F4C9791F77791D863C302C971E6E
-:108D70005C72138983A15A643BE79753195341EFFF
-:108D800061BBAC42B5EC9FC3A5D43EFB7BB353BDE6
-:108D90006CBDBD74CAEC550ED76105353112D70BC9
-:108DA0008908F6550DB3A311F003B64015CB3E6DFF
-:108DB000973A86C8D1C6A02282BFB4F1F07C121FB8
-:108DC000F0FA622AE4D135786215B0AE864C517360
-:108DD000CB77DAA252FF8C521798B6BF1FFA501405
-:108DE000BCEF7759EF3E95FA5D1AB5C58741CF655F
-:108DF00085141D526E9B0FCE5A04E3CA0B650DF607
-:108E0000B5086FE2DEB6C41521DF1711F88B442FC9
-:108E10002A756132FE40F3BD47A57E066F9DAFDF28
-:108E2000F97A15773F45BAF96E85F9660F3C5F6FA1
-:108E300036CD5FF5D605C9F8FF0C1759B8C0DF83EA
-:108E40008C96725CAFE9F40DED458462689EDE237A
-:108E50000BA7123AC582DA46BF7C1F81E937A10E03
-:108E60004FEDDFF939D5BB559A97C0F18A74EA8F77
-:108E7000181697C9BE372B4EF7BF29F941E928CB01
-:108E80001345E45C57BE4CE292E0A6B1FA31FECA4B
-:108E9000F671DE4F4609BE5A3F23A32D406F457839
-:108EA0003D70DEF6308D3BB57AA295B1606A3CDE4E
-:108EB000FE4D860F192DCD20F95BD2C2889BFDD9BE
-:108EC0004BE70C6E4E39FB632E6773512E95B3132F
-:108ED00097C311A174FD38ED0D7EBE67E8E74EDA49
-:108EE000093C5BF31F257634F78FA148C900FE1EAD
-:108EF0001A2F4DE179B99EC478946F9C4A9C7EAD3F
-:108F0000450CCF358EFC5D86678E5FEEB747916C62
-:108F1000C2D71CDF12C0137025CD8EF4A7AF24C6B4
-:108F2000374E789EF91F0ACF9FC31AF0336B145E39
-:108F30003FF0CDA11B11898339F891B7E374EF5C41
-:108F4000BFEAFB9FBD7E4E0FE9EB9BAEFB0F1ED72A
-:108F50000D317A5399DE7CB9F4AD1638272267D3E8
-:108F6000FD6EA8B491DCD322235303FF5A889FCB14
-:108F700061E732793E957FA27DFFC1F30B4919F37A
-:108F8000BB87ED3FFADC9BC2EC2C7E4EDF397F279E
-:108F9000BEE6F8DCF30751BEBBDFD5198FE3F10D58
-:108FA0009E07CBE300040E78FD9E59628CC8BF1269
-:108FB00064EC75914FCB7C542F74BDE8237912A1DA
-:108FC0004A85F863F34A926550CEAB4151D013D72E
-:108FD0009E3982E2B8D3B17E2AF7F34A1202F83DF5
-:108FE000F2CED1BCD85D2C5E99579B10565BC679EA
-:108FF000C047E5ECA553F713F9F8E2289A877E5F9E
-:1090000019B5DF8E446E6F2F83714B693E7908EF7F
-:1090100017216F2C74C24BF26F514937023F2AD689
-:109020000266087F3F538FA6DE3916F2BE54F23C2B
-:1090300057AF91E7A151CAC1EB71BD8D057E1DFAF5
-:109040006D2AF4D373BB2195ECF7FF3BF373C4AFE8
-:109050007AA13E42EAB77CC9207645E3C1B3C46F2A
-:109060001830A645A91FD5905029CCE788017E0E5F
-:109070002447F5C5F0FDD02F493D4989FFD204FBB7
-:10908000E45685ECEF010E104F68F0D17CB9ADBE0F
-:109090009A48263C0BD0AA452EF0BED5C7E34CAA71
-:1090A000A4E4A4F29094D2A49401FEE412D439165C
-:1090B000E46553A20CF4345AABE9304EBE9A28034F
-:1090C000FF71FE1A2D0A3E74A594DE23C2F1E1F170
-:1090D000A1D83341A89714EEC5E316FAA9DECC3B1C
-:1090E0009120F70C5D3A35D3D5FEBFFF6419F9BE68
-:1090F000BDBEE258B9859F8369E2950F14CD7DD43A
-:1091000087FBFD196C7486A7EF973F07DBEFCF7CD9
-:10911000549F1E3A357E04D8977569F2A8250DE351
-:109120006918954FE08FD838561F9119B4F643E16E
-:1091300021BDF8438AD789943E1BBE3F3E03FA7D8A
-:10914000E9D4720DFC7DBFCF2E22FB86F3CF790DC3
-:10915000B05FCE67A13524DFF2B999AFC0FEF0B79A
-:10916000F587B3648B5C3CFF9DA3333CB8BFF3CF62
-:109170001E9D2113E64AD8F6F11BAEFC7C06D809E9
-:10918000E65C545C839FD59A82A0DF6A95AE83E744
-:10919000C9EDCA519AE1393F9049DAE78C101F8432
-:1091A000B2A4FE7CF43BD3C8BA695C81C571F0FA05
-:1091B0001A8284AE35BC018178A1E91D0DF1AC5352
-:1091C0005E427F970A5071C114F00B4AA45DCF5ADA
-:1091D00094807C0A255903EC897C3F4D20E09BC09C
-:1091E00071ED20A13576CF5BABAF90D121CD23DCE3
-:1091F0007CEAFEF1001F2ED7E57988C4337A6E51E0
-:1092000013608F3E2CEB5F590176E06D3299072E8B
-:10921000FB34173C2E0F14DAE092C5E2131CAFE9C1
-:10922000E8645B3D8A166178FFB85E8DC2F8CFD7DF
-:109230006BA4FCA3FA08291FA8D7C9F3B9FA62F2F4
-:10924000ECAA8F92EF1DF5A5E4C9F3FAC8D65E2209
-:10925000F674AC0CF4D032EA87D374D1807C850CE0
-:1092600019A9C3B0A9A29DFC4925ECB741AE64641D
-:1092700011BE17A07D36CBF31B9E3BB7B54C4FC933
-:10928000572E4F1B3C48007964CEA27E8610F4878F
-:10929000DB672F45E82D8B5CBF82FF79AB98AD0F64
-:1092A000CF27C3B07F77D60FCB7801597DDB61B96B
-:1092B00048CAA97EDDE137D427F8CBDFB2D0F7AEBC
-:1092C000E978D5988E7609548E3DC8BEEF983E2336
-:1092D000E37628CF9A9141F27F67215DC370DCA9C4
-:1092E0008BA62723557F4FFDE19CF2B14C07819C53
-:1092F000AAD5F6B659F631F9265A15B3D0CBCE1AFF
-:10930000B9621FB133E2B98B27917C63E6D7DE5790
-:109310006ECC26FD927241DBA17293E915903373F6
-:109320002E533DD4AB7FFE4CDF73BDA730FC6F9F47
-:10933000BD450A039F803C057959124773F13C8370
-:109340009FA4F1EF59EF2411E4F72951FC1EEC51D1
-:1093500085E69BE4451202949FF4C5A6FA613F920C
-:10936000B53BB90FE3FB0F5D5E1DE28D5D2FFE91F6
-:10937000E46748931515F83BEFF9D3246F4912BB06
-:1093800015D8F12E6BBB7ABE0CF62C4C84DC2B80EE
-:109390001535C6B394C3D667763695031CC5F85900
-:1093A0006BFD5DFEF8BD74C78C0C3582F9C1C7DA60
-:1093B0009BE39B8C7C5CF6D0F2B2B6714DE66C28D8
-:1093C000E3FA99B4DC88ED846D999D111197839B24
-:1093D0008B9A0E8F8232AF5FD464E2F631A60F50C3
-:1093E000305E00FCDE5BD670396429CBB48C54FA55
-:1093F000E4EBDD70E88FAF8CC470A87A5EE82421BE
-:10940000BEE7F70AB0EEBC037BE9B9800422FBFE9D
-:10941000BC849080A39B1DF587B546EE5CE378C1C4
-:10942000A2614284DE1BA4243C51D85E4E60F782C8
-:1094300070BA782640F5C084046E6F8D4B3BEE0900
-:1094400099C0EEA1212403F2723B3DE7EBA4F3F1B6
-:10945000ACBF3A64B649A0B79FF668243ECEFCEC98
-:10946000E7B8DDC4FC39F730079E678BE9BF1AE423
-:10947000DF6A99F881D7172436631B0AADFF614173
-:10948000145BACA8C947E9657D6667CE544C2F4D87
-:1094900099F67203CB9F8F649A995913217FE8A1A3
-:1094A000D190DF5385DA577E11E6FB531A0F3F7BCD
-:1094B0007056C675B8BCE1A7348EB1A1EBA802F412
-:1094C000BDC3CFF28EBAAEF914ACAF6ABB48CEC5FD
-:1094D000015F1AE3F1748DF6AB654C2FFF1A383932
-:1094E000DF87F1FD64A1A189D720F4C6B6779BD4AC
-:1094F0004FE2B2A24D00FA7863DBF926A0AFF5B3D4
-:10950000F87D76E75F368A58FE2306DE8EB6D94DA3
-:10951000700E63FFAD159F02732B47A4FC8B09925D
-:10952000C4B5A5CC46727EEF774D22B19FC145BA36
-:1095300009C3BD48468765FCDCA5607C029F35CB2E
-:10954000441EE2F72D1E829776727F086AA1F751BA
-:109550008C7DDEBB1AECECA21A632DB1B7B589C4C1
-:109560000F301AF5FE903C89AB1095BFE3355426B9
-:10957000E37A2501EA2F2FAABC793DB493424BFD33
-:10958000C0EF3952C224FD7F8DCAE15D62A253054E
-:10959000B91C2E24F8DD15A674613E3C91D0C57E21
-:1095A00071EED560173509ABDB5E05BC66169273AC
-:1095B000AEF07E23AC9FE1B3418BAA80BFFD0C9F30
-:1095C000D25ED1847C4DFE7E9B70FB5A80EB3BFECD
-:1095D0008DF3550CD71CAFD1320CE3E16DFFC6A65D
-:1095E000C82C828742157F7FBBEDDE2615E365FF21
-:1095F00066234FB394C7FF054B752207EE257CDD2C
-:10960000187C741D2821FCFD65F07F3C99C5F99EEE
-:109610007E2F2AEC952306D8A50D664AAEA8582FB2
-:109620001459EA9763B9F0CDC72482D7C3783C9028
-:1096300013781D26D07DCF0499D8057E3C173F2E88
-:10964000FB2715927C5BBC6EE407BB61924CF43C3B
-:109650008FE32813446237437DA0077F6E21C99FA3
-:10966000C3F23A06E77CA4088DEB48D21E03F33020
-:109670000AB0FC7D415B44EE17F1155BF20A40FE37
-:109680003AF210244779ACB73B17CE2B659F5C2488
-:109690008CC67839ED6771996CBC8FC5EF7FEDA7EB
-:1096A000E71BEF8F993740BE0CD2BB73693C2A365B
-:1096B000159E236E2B1AD19FFFA5EF7E354AEC979E
-:1096C00047F265D77CB0E702745FE41D5544EECBEA
-:1096D000A84398FF812FF8FD2A4C7E7898BDE03C86
-:1096E00027C0E5892793AEB1B675DE88AC60EA1C69
-:1096F0009C143454900707B5A919608FEA01CAEF8A
-:109700008DC9599F05BB4566F2608F8F9E8FEDC94D
-:10971000449DFB10D8BF5164CD4BE0F2607BBD4A45
-:109720009E4FCC1947E2974FCCC9990BF18A43D78A
-:10973000BE47F6BF17F750FEBD78E465B823095D54
-:1097400034E9F95C202BE2974F3E42EE01F9861C8A
-:10975000DB49F2E5215F074F6967A63D0FF38900FA
-:10976000F59BFE89C927ACB7C9777E3F877CF91383
-:10977000C40FBC95C95D355E4EF695E0C6D3812E0B
-:10978000503BB96789C3C1792F877C793269FF273C
-:109790003F853FCF5F72E629F1F9FC80CDA7EF7DD1
-:1097A000AE767C70BF06C7036F5F2B1823B47EE8CC
-:1097B000A6FAB2841296BC90D4B90D85BCBF00E75E
-:1097C0005D32E05E9578FB7505C007096227FA8275
-:1097D0008DB6FB595144EEB19E2F0938CEBB38F9F6
-:1097E00005EE05063DADE8FD9F6BF935DEE6F2BC02
-:1097F0005C92A72EA3AF825D7B3EF0E60CF0C755CE
-:10980000633101AE72249BE43CE905B62F919FBF02
-:10981000979CE7E1F3E3FE385EAE3AB088F8E9AA38
-:10982000F707C9799EAA0495831B54F3B057B4E691
-:10983000DD1A49C8B7F51CA0FDE980038C8F3F688D
-:109840006B7261FD81BA3133E19C498E5873D568E2
-:10985000808F4CF100FBE56783E49CAE0C7A9C8F13
-:10986000FB4BB60F5CC6EC9100324580A7E48F76C7
-:10987000237A66D190B17D24F5CABDAB9B801F765B
-:1098800039ECAD5D7E5ADEBCEDEAA646AA9F895C46
-:109890005CD6F62FC41E6AF2F1F273444EEE52DA31
-:1098A000932027CDE7BC3AE83DDC9E9C63376F2DC3
-:1098B00026FA432A447900B77270B480FC7BCEBB91
-:1098C0000FFC0C4FFAE231BF65BF733E746234EC9B
-:1098D0002B5DFA336DFD8D1E5A7F78FC2EC003FF81
-:1098E0005E1EDE4DFAC7ED88BF03E51F7913DBBAB4
-:1098F00028E7392F3967B8C763B7B7F97337933398
-:109900002D8E7B39D478A3019B73CE9FCEFB9339E8
-:10991000BFCA9727D8F2A474A69F65D9005725FE21
-:109920003E917CFF939FD2410BCBC7493F4E569A45
-:1099300071EC71BBBEE3CC60720231FE97B5DEFB09
-:1099400036FBC97F75C6179DF28D3FB97CCB0E5093
-:10995000FE8A09F1AE001E675DA273819FF2E76483
-:10996000E0CF3B995E2AEE78E84550EBDF528DF769
-:10997000013F2B55636C60F8D0F9E70D369E8BFCE8
-:10998000A276D91A6AE7D6B64EFB14946B77146A9E
-:10999000A64BBC883FD75C0ED8E4D70EBFCEEE45B1
-:1099A00034891C5B73394CBE7F74E3F96CE7D9FAD8
-:1099B0008E1724DFF978F738E4F3A16BFF6D572990
-:1099C000A6E3DA673CA2D7324EED33EC1C900FCB06
-:1099D0006B3BBF1BC0EF7201EACD5304F9B053617A
-:1099E000651335835DF4A4553E9482DD966A0FF7C6
-:1099F00011EEF4F3F6BEE6F27C97FA0147FD42DE83
-:109A00007F26E9DF391F2E7FA00C769AFC172F9F47
-:109A10001F915F0F898EFEB2F8F879A43F6EAF7F79
-:109A2000A1ADF01553063A4D948DA4FE1D1DEC809A
-:109A30006FC851BFF59EAB2FF8A9DC5C73798C0D14
-:109A4000DF29B88FB3BDFF4D7DC496AF7F77BC963D
-:109A50009CD3F802F327AEC1163D69B767A42D4F1A
-:109A6000FF1FF3F8A0F3B82ECD3CE6FC8DE7516064
-:109A7000E3CFD43C8A6CEF3FE83C7EE0A3F2F805EC
-:109A8000F69CAFD17B01E6EB02F15BCFC7757D9809
-:109A9000D66FC04F153FE7CBC80C92FB6B13B43E9B
-:109AA0002E833FE0B37FB9EF9DEBC97DCF06C9C7D9
-:109AB000E1F74EF1FB1007BA9FC8F9771B9CDF0353
-:109AC00069EE5FFD6290C2E9A129372192BF1E8C29
-:109AD0009338C1C1DC0511B0D3BF32A58A3C1B73DA
-:109AE0006744401E35843E67CB37C77B04D773B0CD
-:109AF000EFB17ED1E51B44EB7994AD701EC5A53E58
-:109B00008F8B6D55F9FD801FCF7A777F4CEB2D0D34
-:109B100051FDB9558D93B86073E4E399FFB3413AB1
-:109B2000CE4353E6203ADF39491AF75174EB796096
-:109B3000FE3C189A11817536642E88003D3766CE3A
-:109B4000B0AD474AB39E957C3DDAC7BB9E7FEFC55B
-:109B5000C7075DCF02D73C5839DBFDDEF9C6101DC3
-:109B60006F6B244EE8ECE35AD7990F8DA7A1AD2B6C
-:109B70008BADEB8E20DD476CD5291F05A4D87F1453
-:109B80000803F3E1407F4F0415E9E260F2F07EC57F
-:109B9000E0958E7F6FF52486C3BC4ED4D3FDF36B66
-:109BA000EC3EA95FAD690811BFB6639CADF9FB42FD
-:109BB000FDF939FED71AFBF9F481E48619A471A0E6
-:109BC0005BE2F676CB2B03AEF79B60F8ED2C2848D2
-:109BD000C1B30FFE3F62B8A5A3C7A1C2AD393234ED
-:109BE000B80DC40777C0253783801BA7B774FDFC69
-:109BF000FF4267BB83D46E1804BC087DFDADE0F561
-:109C0000F74A5FCF0E9EBEFE012FA23707475F5C6B
-:109C10008E7528F49E45673FEF84E83D9BE3859A67
-:109C20006337427CE13312F1F71EDB53BE0189D664
-:109C30007A54BF1CAB98B781E4BBC60208EECF3A9A
-:109C40002E46FFBD04E20E8B693B67FFC7187C5EA2
-:109C50000E65B27DBE3E1CFC08C7634BFA5D1FAAB1
-:109C6000B0AC8BE4655AEEA392FAC2F718D277949F
-:109C700080BF69A1FB3C383ED38D3B547C1E8F7D59
-:109C80006348F81C68BD5DA1C1EAA504C14336EA7A
-:109C9000FD3B1857033C3B449ACF710A5ECD82FBD3
-:109CA000C910A9B4BC7204B9E76C4A98E53D29FA19
-:109CB00006F09379972CDC16C2783BBE2C53B0DEAD
-:109CC0007F2686A9DD326385BB5D9811A674906AF4
-:109CD0002FA0F17ADF7A7F65F6E3B215F45E2A24CD
-:109CE0001BA3165BCED54D08DBBF3BDB47C2613201
-:109CF000CE71C1FD7E583F9BC7F2A5FDB747B5C3E6
-:109D0000D8E16D6D92DBFD829C3FFE4F283E2C8C8E
-:109D1000EBBF26C4BFFE79A0A309411AF7905101F9
-:109D2000C4EB793FD9324A2A18EEEF78B449E0A75C
-:109D300075E927BFBF7ED2C195AF878F03AC08F707
-:109D4000B2E0FD23D92F961808CD867DA2377A2F51
-:109D50003D6C48E9208BE5CFCCAC092436839D27A8
-:109D6000E3755AE6DBF5A7799F86EF5DC7446D4B37
-:109D7000415F380C241FCAC234DE902DC5B7F8C02D
-:109D80003FB64A70BDDFECDA30FDFB23E742BD7120
-:109D9000F55130CEB847E31EB8E7E06696DF845051
-:109DA0007CD422CBF8E7189D38DB654B341E8D5EE2
-:109DB000A7FCDCB16FDD2837FEF939E3D373A1626C
-:109DC0005B1ECED2D8BD1EE0CFA50B1779F4207C48
-:109DD000D729BDB1797428F151D70453704A2B8724
-:109DE000187CBA4EC41BE07E8755750289234DDC72
-:109DF00044E96ED5A683E206FCDCCBF86F91806C5B
-:109E00007990F730BC76ECF38F86F977703F1D744C
-:109E10008CE7B17237227EAF3B1FFCF456B84BB5CE
-:109E20005B40CC4F76A002F20DBA599E8889BF6F75
-:109E300006F8950F27F31DB7E9FD5A90CF5D0A226A
-:109E4000E7E5FEB3D54BFE6E05A7975E39B1E95243
-:109E50003D24DD3DA2242701DD0C6FA8F9BC9B9FAA
-:109E6000FC0136CF3F0463196E762E7F7279CEEBFC
-:109E70002D96758F5BFD25157639C6E73DCC9B3C4D
-:109E8000EF765F432F1D26FAD77BBF60729CE3BD40
-:109E900017DF27DCF7455F6172AF2331773DD15B78
-:109EA000A6570779C8E7C3E1956D5238DDBC54B2B7
-:109EB000C9DB550B038EF34814AE9FF5EA8FC13A08
-:109EC0001ED9F76F93000F4EFDE097E20A7CBF1B8F
-:109ED000253D2027CE483A79BE566FBF47FA351444
-:109EE000DF311DF4679DE4CA57CF32BCBC5679C739
-:109EF0003232FF464983F99F5E31ECA652902F958E
-:109F00009E28E44F9E6EBC2F749765FD5CDF39E799
-:109F1000F5AB3577F4ABB79657DAF1D6A150BBC0A5
-:109F2000FC14E5C3B558DECC26F4D5BD63261EFF70
-:109F30005822EB9A365A1DC1DF695CC27E3F23C6A8
-:109F40001F9C89E5CD5991FAC3CC7FA27263E9A326
-:109F5000B12688F39EAD9BF64237AEF713A607DE17
-:109F6000ACEB5F3F3AE969DCA3F6FB29679C400A4A
-:109F7000B48FD7BAEB835B32034CBE4447837CB9C2
-:109F80006D937BBD7F86E44A0CEFB37F95D6B8E531
-:109F90006D5ED6E87C57C5DCDB5FD642F43BE82536
-:109FA00017387F2F2340E5BCAC8D0639BD2ACD7C08
-:109FB000BF9B1126FDBCDD74FF6D10EF3B23DAE57E
-:109FC000F3DE0C4A17F519543E9FDD77AB6738E096
-:109FD000A959D0801EDECA8C4E007A5BDD789AF8D3
-:109FE00011FE89D5AF0CC67E171E0EFCB278FE702E
-:109FF0008C97AE15282AE8E9E5FF25C63FD912BDA2
-:10A00000C700EBBF7740FFE1A6EF10FB433646DF0A
-:10A0100032895ED90879856745731DC943D9E7A799
-:10A020007947283ADD7ABF8C2783C2EFECFEA1E1A5
-:10A030007B592CD0AF1D7F0CB5579171F707348831
-:10A040003F1EAB9092D7E349BEBB3FB0572AE8CB47
-:10A0500017E9C61FAA1D7876FFD0ECC081D6FD890E
-:10A060008C8241D9F5172B1E79B004F848699FEC12
-:10A07000267FB99C3ECEFC564EFAE1CF998C2ECE6F
-:10A0800024FA9FD7DDBBEDF3B9ADC63E1FCE2F67D7
-:10A09000120D7EC80FC7A34FB2DAA5A87CFA00E75D
-:10A0A0001CA8FF37DD3C3F9D6197134079104F5B43
-:10A0B000CBE4CD9B758F84AD7870AEFFACC8F6074E
-:10A0C0008FD1BCADB1B1D57387EB29FAAC6470F810
-:10A0D000A8E992EB19673F7FEF74C8F5DC4074C8BC
-:10A0E000E582B3FD3988F3E3A5AF963505E232E7A3
-:10A0F000C23A2D236D011C9141A5ECDC32D247C33D
-:10A10000B99BB3FBFC08FECEA6D9E64D8CC52C70DE
-:10A1100066DF7513ACEBF90AC3CFAAA59970AD0D34
-:10A12000A693E88D23487E8144EEEB7AED44D60277
-:10A13000283F724404098D6EAB5D2DC1FA1ECDA07F
-:10A14000FBCE559B8E127B70A874BEAAC6AEFF2FA5
-:10A15000B375F4DA59724F09D04F3A383466503833
-:10A160002C8B2D9A0FF2F98E4D0291B74D193AF5BD
-:10A17000D7CA0691DBA891EA47A462786015721AE3
-:10A180001601F0F832FBFB63724CB19E4FBA6BFBC9
-:10A19000FDF3C13E74F24B0ED34F481399BC8F7F31
-:10A1A0003B637A4A3EBF25D41C1C81AB5C9BA1F16A
-:10A1B000FB61099FF2F55C9B41D787EDB46F93BFBC
-:10A1C000BBC4D687A20E7A13DBAB7E04F09FAB1222
-:10A1D000BBC0EFC5721FF2E6BEE1D768DE1CE52BFF
-:10A1E0006EEF38DBDF2CC76D76E3FF05B9373CBD7A
-:10A1F0001DF20F7DE15EFF7D06B7BF95BEF8CB4730
-:10A20000A42F8E86759B9DC5F5C6FF03C8D629333E
-:10A2100000800000000000001F8B0800000000000C
-:10A22000000BDD7D0D7854D5B5E83E73664E669221
-:10A23000996492CCE41F9C49000324780221444095
-:10A2400098240482609D408060030E081A2584A82B
-:10A250005879AFDCE684440C14BDF1E7AAB55EEF93
-:10A2600010D0F25ABC0D965A54DA8E54507BF53603
-:10A27000F88BFDA2466B292085E8AB57DB8F5BDEB0
-:10A280005AFB2773CEC94C08DAF6F2BDF0F19DEC0B
-:10A29000B3F7D93FEB7FADBDF6CE098B3A3FD34341
-:10A2A00088B655264F10423E3CF65935961FE8B504
-:10A2B000B82528AFD8B84A0E390949C692979013E5
-:10A2C000E1C529583E8F3FB3873E6F7A44269142BD
-:10A2D000427FCEC3FFEB5B920CE513DD890182E385
-:10A2E000CD7285C7FA09D9AF108D9412F2C1B6CCE0
-:10A2F000F0162857DB89E69C4CC8F4141F1DCFB319
-:10A30000F98B56F724984FF77F14937C98DF3D77AD
-:10A31000AE08150D1DF72F6E0B215361009FCF4224
-:10A320003208B9C3CEC65C9D4C02D83F81F19ED0A5
-:10A33000F52FBE7BBB9590C8E5503F06BE2B8B7EAC
-:10A3400067EE7FE975578EC675BF7DDD8CD1AB8A10
-:10A35000A2DFC583C35229F42F4B70DC365945B8B0
-:10A36000EEB937A1B13B06DCBE8D709D3A747CFC22
-:10A37000B1C23A16F3DF976CAEB8CB0520D9923450
-:10A38000EBAA508CF1DF26A17BA6C278DA66369E56
-:10A39000799C6BF8386FD7DFB004E1FFB926BB6555
-:10A3A00080477F839C5C8EDFD5DBD4B1D07FBF76C6
-:10A3B000BB6BAD6E9EBF8D039FDF36DEE08A8507E7
-:10A3C000F15C566FA4830FC8C06BD3709CDDB1E7FE
-:10A3D000B75ED09712BAF74A98DFC9AB655583F9D3
-:10A3E0009CB4C077482F8FC277BEA1DFADE2DF7D7E
-:10A3F000B07978BA5C5C639CCF92638946BAB490BA
-:10A40000C69E18EB59FF15E97E05D2BD3D5ADEA365
-:10A410000C8C72C3F71FEC3CF7DE9DB89E9D89142F
-:10A42000DEE67E9253653ADE49E41384D7F604CE25
-:10A43000275DCDCFC1771F5C93A36E2143F9839035
-:10A44000AE6F4C87FABE6E4BC976A8DAD39DD4188E
-:10A450008E31DFF1A98C0E3CB2963801DA93771871
-:10A460003E90DC906F96707A7377FFB08558A2DFCC
-:10A47000BD83749040C81BAD76FADCE1B6D3F1EB36
-:10A4800016D62A3E1867AD9504107EF407FA754F6C
-:10A49000C8DBB91D867ACBC2CADA6AE03F69E87CBC
-:10A4A000BEC7E9724F78D1B0F0AD6F900DF0AC5BE4
-:10A4B0006884AF993E8F872D35B1D62FE839DE7885
-:10A4C000D7D9C25EC4D331BEDEB7F97A7FDBD8EE0E
-:10A4D000C2F6E671F684BB87E5836F361AE9E2427D
-:10A4E000EB3CE6F653B82E0F19BF5B566F5CEF12CC
-:10A4F000D272150152594A541B3EEB484BF173007E
-:10A50000CAE38F2CA6F3798B909A1E9CEFB9DB8B54
-:10A510006B8BA3FD1FE6F0FEBCEEF66B50ECBCA30C
-:10A52000B414BB63CCE72D0E2781EFB7E2C0F379FB
-:10A530002E77DF413C23BD2E9563E2F96DCE47EFC8
-:10A54000340CCF474BEB86C7F3EFDD6EDE4F7B223B
-:10A55000AEF38418F75136EE89307B2FFAFBFDDF1E
-:10A56000887FFB89760BA5E370A21BF58807C9439A
-:10A57000A7475A53B9FE291C5E8F88E71B42AE9A43
-:10A58000DAD75903363D3E4ADC8CCF45B96EA1710E
-:10A590009EEF27BBD9B8C43D3AE8D2C90DAE5F855E
-:10A5A000BE7BE0C989EFA3FEF471FEAF0B7E6A4368
-:10A5B00078807CBDCB85EB7ADDE246F95A762C605B
-:10A5C000D3C3EFCA1406BF93BB8787DF955C1E5DBC
-:10A5D00048CE9AD7FBC13FDD3D19FBFDE09FBEB0E1
-:10A5E000E9FB5FFA652E89A447CBD7D74B81700C66
-:10A5F0003EBBDDAD8C08EEB79BE078FD97A369FF0D
-:10A600001E99B4F4C45A17CA37E87749B0C2E605B0
-:10A6100078DEB0595225E882A4B27E6E10F2CEEAFE
-:10A620001B5D0B70F7B6B7DC118CD14F3987F79FE4
-:10A630009CC194587C36C81F9C1E44BBA5D6902D47
-:10A64000567BB35EEDE77C6E6EB700E9D13B727A64
-:10A650001CB4834CED473A8FE9298C2FD313227F0A
-:10A660004479448A8C76D805C735B5378F3B1FE1CE
-:10A670003E35FEF827FF2A37C682C3B75319FD8639
-:10A6800082403F31EB5DB4FE75C2F4AB164EA2FAC8
-:10A69000F0C4EE1BEE45F3EDC6F9771C4135F972B7
-:10A6A000B29F8EDF103C5A8D6025E71E988478FF9C
-:10A6B000BCE6817B4B616A279550BB0B3E38B945A0
-:10A6C000A2768B799CD7B93E7913E5E9E5D81F616D
-:10A6D000743B077ACB06B0CB81752854C8B7137C7E
-:10A6E0007A3BD5B3E98B563209ED87E01617BC1FCC
-:10A6F000B7F9D38DA8970909D3EF3FB2A93753789B
-:10A700001366E7F6753B776E8776AF25337C10A22C
-:10A710008E0E16EBE484D54DCB23C5CF1B71F073A1
-:10A72000B1724AAC33DE380079FA7D6D95B353BA15
-:10A7300002ED1DF71D088F816A97BB1BD6539B1036
-:10A740005880EB3BFABAC5D2E6A7DD527B6511FE15
-:10A750000643FBAFF67F17ED99450BE58003CA7DF5
-:10A76000F81EC65B52E9D4A41450116F2CFC11E200
-:10A77000E781BA049F0C24513BDBFD4719DAD7CEA1
-:10A780004BF26D8172596F7E9B07EAEB6A2437F6B4
-:10A79000F7E2C229AE7E585FD226E827073B3B5E30
-:10A7A000533586901FE2AFD3099B30C0E20D22EAF9
-:10A7B000D3B6CD017930C1BBDFE204508F494BDB0A
-:10A7C000668779DED516CC72A742BBFB4E74DAAF32
-:10A7D00022242323D03B5B2524E1FE5335F651B0E0
-:10A7E000CE47797FDA279D8199A04F2D21BF04F5AF
-:10A7F00093EEB7CEB75E09F82F10FD676DC3FA254B
-:10A800007357ACDD0FF5756913E65BA1FFB2063136
-:10A810009F2BE65759E1FD4CD1BED481F3F5248935
-:10A8200032CCB79C105B7E74FED62C183F4D94CB77
-:10A83000E7CF816FDFAA68A9B242FF7BD2666D2B9A
-:10A84000721032ADA6C21D80F53C75FF92F94940E9
-:10A850003FFB09D029D4EFBB7FD97C9CBF47B6B062
-:10A86000FEB57A3ABFB2066D02D64BA4615B0DAC61
-:10A870007BBDBDFF0892EB864D9A3D037E49921841
-:10A880009DD86D2D815C80BBED404524974EA78BF4
-:10A89000D1675EA418F5D860B910CAC5BA72162B74
-:10A8A000EFDF42AE8F256F5BD299DCDB9F18BB5E7A
-:10A8B0004A63F218E046F549CA3112D81B43AF9CEF
-:10A8C0004875D276871389664F8BF2DBB5C0C3E536
-:10A8D000C097C4CEE629FA1942D75CEE10EDDA34FF
-:10A8E00094A70B399D16A812F577494B52782C3A4C
-:10A8F000D824625D8C2248B6D0F97A65E9FA5AE824
-:10A900002F239184F6C1D39B4E6819BE0FEC73467A
-:10A91000FB7B95B116A92E08EEC6FEAA33B34BDA1F
-:10A92000FDD17E60DE1DF6C986795BCBD3B07E514A
-:10A93000C9AD453A7816B175001DD0EF60981FCDAE
-:10A9400006BED8DF3B211FEDF7A7538D7C5DD65B9C
-:10A950006923F0FD92742E4F7CEC7B6F15933F03BF
-:10A96000B72685915F895D2D09EAECCEDC34068F30
-:10A97000AABB173E8CED9A7A6D2401DA6DDC5791F3
-:10A980004986D18B4D5FCE20E129BAB235A2A0DC39
-:10A9900069FA72167D5F75F7AB0AF229F6E38379DF
-:10A9A0006D74043255845B7B6CFC83434EE7DDF4AD
-:10A9B000652AD1A6E8DF333845FBF7D0FA0BAD2B7B
-:10A9C000DA9F4CC2E9C3F5A7D0FA41B85B39DC95F0
-:10A9D000D8F3ACE4F042785B74F575486F4E2AFD0D
-:10A9E000681CA5EF1B45DD28EFA3E36EA1FDEFB7C3
-:10A9F000021ED10EEC4DF4A15D5C6605F9E9C1FEC5
-:10AA0000D2DC9A14A50F411702AFFBD35A2AE87A79
-:10AA1000AF91DCDD31ECF8F9827F16327B2CB3216B
-:10AA200024AFD2D1BFE007E87F3FEFBFB49CF2CFA5
-:10AA3000BF327E00BE5981FC8B760BD2A11A295EF3
-:10AA4000E41A3AFF674076607BC02383FF35CE303F
-:10AA5000CE47C06D28FC732F80CFD1B4BEACF79029
-:10AA600082F4D614876F17A427D3EF328F4592D183
-:10AA7000AF7D8EDB1DFB7BA63866205F2CB41014E7
-:10AA800061B86EB457CB660AF9FDC42B95207F33AD
-:10AA90004519E5AD0FF130287F23767BB4FD550FC6
-:10AAA0003C31BF03E57302E0BF88DAA176A2F32749
-:10AAB00036A53139561E2231ED96DA7466B708781C
-:10AAC0007F6F5315F91DACEF502AE3CBF27E4D5A40
-:10AAD0005514E56BB39C7A98E3F141FEFCC7CB2992
-:10AAE000E90272AA96CB29F6FE3098F9D82E2323D4
-:10AAF000522C814E5CFDCA94B1E8CFDC9625FB3E1A
-:10AB000006BE5A2CA9A39E827EEBEC3E1A27137434
-:10AB10005247EC3E27C21D8CA6F312DA070E5AC626
-:10AB20001FB44B3EEB92181D125F4A5D717C3924B5
-:10AB3000E6715B9642C75BBD6D6C4A483F3FAE27EE
-:10AB4000AE4D883C450A86F2B928C3FCD75B645DEC
-:10AB5000BD93E9B33FB8024FA741F9288F43812243
-:10AB600003A72A3AFEAFB93E31DB4B8B93399FA046
-:10AB70007949F9D8429DD3CCCE8430619F68E8A74B
-:10AB800066F6303ACA6C88589A747470242D8F36E1
-:10AB90006A5806956077D5D8AB021FEBE4D8CB1284
-:10ABA000A9A7710412998A7CFA521A31CCA3410EDA
-:10ABB000E64968B76626A82867004F140E871DC4AB
-:10ABC000EA80715F8227E2AD5ABEF5059B07E94036
-:10ABD00052DB29F47772FB944450DF5C3B3B89DA0B
-:10ABE000ADE4DCED63305EE14D62740BFDD8793F7E
-:10ABF000764A275CEEFD66F4F86ED44F427E0A3C3E
-:10AC0000907332ED4FD41F966AF3DC503EECBDBC1E
-:10AC1000A45D32DA3F680F45EDA7DBB6CDB3A2BD28
-:10AC2000D313B1000BB5691BE7DF897638D84F0E17
-:10AC300058CF47694C0F1EF66B7232F63716D601A5
-:10AC4000AF8E24868A5A9C517C808D1342FC6528E5
-:10AC5000F07432FEC0675B3AE33397873D97F16744
-:10AC600046326B6FA6B79B787D00790F9EDB2B98E1
-:10AC70009C30B7FB6FCEBFEBED5A4D46BEDEBE0A31
-:10AC800012A4432B6176D65F39DE409F517855DDA3
-:10AC9000DD90827AF3F3DE2529A4282A476DF63762
-:10ACA000467F0C72244216FF33F2ABF2964CD05E14
-:10ACB000BECB067400ED94D4903B0D9EE949B1FDE6
-:10ACC000E6317C9DE9E85743BB7BB9DF63FB722229
-:10ACD000F5B733B87D969C5547E53AC2D207704E1A
-:10ACE00021039A5B87C794728BC17FB07D39897EBF
-:10ACF0007FF1F643491CFBA1D4603F8871CD76C437
-:10AD00007BAD5974FEE2FB15596F56135DFB95A49C
-:10AD1000FF2EEC6FE5C65C43BC289EFD319DC3074A
-:10AD2000ED052DE6BC14C3FBF7C05FD4F4E39F60D0
-:10AD3000E347C74D02868B8EFBD7B4C08C741A0FC5
-:10AD40009AE93E3E111E60C39F97A9DE61FA1A9EE2
-:10AD50003B9D542FD5A0DC167E12F2BF3B05F9BBFC
-:10AD6000A22ADDABD393FC3BB33C3AC8E31A07B944
-:10AD7000BE493926ECC6449F2445F5CE50BDC5EDED
-:10AD800062937CBC909D0D74ABE9ED8021FC92FE3A
-:10AD900055EDCB8238F431EE1F625F96CD0CC9C5FC
-:10ADA000283F6B2432161ED3E618F5FDB7D39D74E9
-:10ADB0005DDF0686D3FB2D8B1A8CED5AD399BFD25B
-:10ADC0008AEDBC1786A75E1F4932CA3DD65F33CADB
-:10ADD0001BC0B3FFD4EB8A0FE4F0F3DC1EDAE50905
-:10ADE0006C45BAE8484C9E847AA223717418E31229
-:10ADF0003BFFBBAA7027FAE9AFD9D46EECF600F39B
-:10AE0000F32B966F6CB7C27B5B8FE44E20D1793AFF
-:10AE100037498135404AF7737C3579D87A9A3C11A5
-:10AE2000650C8C9FD3C4E691D7F38264D5C9BBBCB3
-:10AE300046D6EEB1749B41FF8479F9F17411EF08A5
-:10AE4000B7559762FB8015F741727A241A1FCE69B5
-:10AE50000140003DE4A8AC7FA71A966E288AAEB7E1
-:10AE6000D3525B847AA2332349453D71CA137A12C7
-:10AE7000F9A8A92F1241704DEBEBB5A2BD67F506FD
-:10AE80007E807010EBF4C9EE1C94B3497D6C7E5D3E
-:10AE900026BA27E4BB3C3EDBCDE4AF4C5E268817E8
-:10AEA0009421305EC69642AAA744FB8C34AE37325A
-:10AEB00048E8696A67914E42F146E83A32B68CA397
-:10AEC000F6BEC06BD4AE1A3F19EDAA821D11EB6A13
-:10AED000B45B1F8B1DAF3FCCE50FAC2342E5C481B3
-:10AEE00091C565443B5B1CBF5AD07D524D6C7B15B0
-:10AEF0003401ADAF58EEB90ED7DDD4A19004290AC4
-:10AF00007FAB37F806CE27A767A784B031D3594760
-:10AF1000DA0FA55C58E7ED3713B74CE2CFBB699366
-:10AF20001C58A3E7E70E85E265A762DCDF137EC647
-:10AF300069AE8FCABDC1DFE1F8CD07EE5310CF3740
-:10AF4000EFFE50196E5F67A470931A99FFD2546F89
-:10AF50000FE37A2B965B291ED7752861944F4D7BA2
-:10AF6000F7452C68676F262AF27F53CFBE2339003E
-:10AF70009FDCA6C054D9A7F39F9BC212CE2703889B
-:10AF8000B1B788CA4D05F5B699BED14E467BE58866
-:10AF900083F1FFE90AA786F1B4D3B65013B63B9DFF
-:10AFA0009DA46AFE28DC5FDA37EF650958DCF5748A
-:10AFB00042049F9D96EE2C3BB4EB9CA0A8484F56B4
-:10AFC0006FC8EE8175A45983FBF1FB548F4B6D83E1
-:10AFD0006F7D096432D5D72384C334135D4CDBCC39
-:10AFE000F865BA2759D88193512EE57B5CC28EA2B1
-:10AFF000F2EA888DADA383B0F9B6A507323D48B714
-:10B00000EE343A6E4E5344423FC03C6E94AE02A3BF
-:10B010003CDE8B99678F82727E1D973715CB774BFD
-:10B02000BFD3D1419187EDCFE6ECDD29A17F08F5B3
-:10B030006DD51EDA9E24A0BCD9CBFCE27550BF565C
-:10B04000275FC43A62C89929383F675FEF8B4CCEBF
-:10B050004428FD89F99AF139DBC3ECBBB96026D0ED
-:10B06000F78A56E883FE8EE427D2FE04DF9BF9744C
-:10B07000B687D1794EFD6EC95244E382D49E14F353
-:10B0800013ED76792AAB3C140EBD140EEBEBAD2C10
-:10B09000DEC0E753AD04C7A05F56EB61FB5D87964A
-:10B0A000BDAFF443F9C19F1DA5F4B8BE4B0A507F54
-:10B0B000A1EBA8B204E376DAFF91314EBB80992868
-:10B0C000E4A19F1EA57A65C17E168F5FBF7F9FF5A5
-:10B0D0000667944EFDA70EAD443A5BDF93401C1209
-:10B0E000E28FADD74CA7206728DD134DA1FB5C2074
-:10B0F00027352A5749C88F7E8A90C36DE97C5FCE79
-:10B10000C9DEAFE1F316FD46E5A783D2BBFFD4E469
-:10B11000437680E77A5552C174023BDC47DB43FF3C
-:10B12000112A878144D15F13FD9BE1D7E5617A2D18
-:10B13000069E5B3C31F489D0B3FEC72B093E05FE69
-:10B14000AC1CEE83FADDA3D07E5B3D563A9F8E0A9F
-:10B1500016D7EEB0313DD2D1660F235FBF943AF7D8
-:10B160006509E4A52B4D89E0F3B0657513D61FCEB4
-:10B1700061F3E8B46C296C617A4CF350FC2513261A
-:10B180009F983C7AF0274C9E34694EEA3F3685EA18
-:10B19000D6D07D098F43C57D09127A5159E28AD2F2
-:10B1A0008319BFBEA75F507C50BFA087F141146ECA
-:10B1B0004C5F09BA053947F1DE26E2888037842BD7
-:10B1C000F8F56D187F107E7D72435073F986F26B2F
-:10B1D0003AF7EBA772BFDE566EFF9BFAF5EB36FD32
-:10B1E00007F5836EC97A853E05BF80FF68E0ABA78F
-:10B1F000B89F763F7FEEE7FCB9AEB487F2C3BA8F53
-:10B200005B281F396B983C71F619E52021F7F0F5A2
-:10B21000EF60F498D43317F725AAFF4D72B793F86F
-:10B22000F3BE496AF94FCC9321FB78FEC639B0F2E0
-:10B23000CB00AE0E0E03DEEE08E7FBD37B0011C899
-:10B2400097D61665387BF842FD92C89B12E27B1DAB
-:10B2500087F5E9BD5557FE1EE38C7B52683ECB2730
-:10B260007B17FFAFDFC3F7A777CF56514F7BDA834A
-:10B27000947E06BC0E15E3A7203E6B24A087B69EE5
-:10B280005F25CFC0FDB21F5D3119E5E67B7C9EA72F
-:10B290007E226F42F86CF9C18F6761FDBAB0948E5F
-:10B2A000F6E3E93DFFF657D48B8DBB37D0BCB4F63F
-:10B2B0001FFD92DAE596F04EF67E4F0AB5334FEE5B
-:10B2C000BA6F16C2BDBDA79DD69FDAB593960FFD86
-:10B2D000E0C7BFF80BDA1DC16415DB9DFAC97DDF3D
-:10B2E000F90BD2795DB28AEB680A59D97EAEA06FAC
-:10B2F000B3DCDAF702E553412F0B50EF229CEA99B9
-:10B30000FC11F4FC11DF6F5ACDF7B13EDAEE6A8C16
-:10B31000156794BC6CBD188BA172AC5EA271B64E61
-:10B32000A01A8C77742692727C261545945C186757
-:10B3300059C3BE59D4EED13EBC11DB2F3EE020DB19
-:10B34000695C0E83BAD17DB0621083C7C16F86DE9F
-:10B35000779F07BA7D1BE403D53B267F6071E72BFF
-:10B360007F46395A67EF7F0145A178DFC9E337D0BF
-:10B370009EEA9DB28DB1E3A40EAF93EB6DA6377339
-:10B38000F6D7E6F9A89C4850C7EAECD351C75AB69D
-:10B39000637A524E63EF5C5CC7D585ABA650BAC0EA
-:10B3A000F81FEA1FCD49FB5F8FF14BE0BF1C2F93C5
-:10B3B0009F196EE2990EE3575B89C7894F42DEB44D
-:10B3C0005139F204ED17EC0F6A57F97EB9EC09B464
-:10B3D000471EB285B2A7623F9D5C6FED66F386EFB4
-:10B3E000DDB88F0AFDB9A74FA6FDF4DAD2E8F71A47
-:10B3F000FB7EDEEE36293A5FA0D4D1A8B7B0BF52AB
-:10B4000027EA19AD9EE2C7A7D0759DC226D974DD83
-:10B4100093561447F9D71CF7417986FBC3E5DE8ABA
-:10B42000295E6FF429E2416678DE89F5D0CF33DEFC
-:10B43000007D923D467F3B9EBD7268D919A67F9FD5
-:10B44000FF90CA9B66A4631C3FF4B141FFDE20E875
-:10B45000F8D90F291DDF7080E9DFE603250AD2ED58
-:10B4600027AD01F23B30409B2B816E817E1F92FA0B
-:10B470006FA4F92ECF3ADC18D73BC3F5CDBA1D1F08
-:10B480001E97011EF907B2A99F7FE659473DF67343
-:10B49000D862A1F03CDC3D7167BBA49F27F30BC0D1
-:10B4A0000EA6A4DA0C762AB383D7DC877EDAFA46B6
-:10B4B000A222FF379BE8A7F9C0514A2FC20EF63FE0
-:10B4C000BE680DB33F1DAA03FDB839CC1E25608FA1
-:10B4D00062FBD439E13685D2574919D2D7A165BF6D
-:10B4E000D88A7ABC790E7163FF0F8D0A3C9B4BD7CB
-:10B4F0002311CC7379C8D6556985EF1FAAF6B90117
-:10B500009200B7DDD4EE25850AD7736BA8BDDC9C0D
-:10B51000F54D95F299591E3CDB46EDAE665F229DD6
-:10B52000CF8203D26DCC1E7112367F89D2E782F0B2
-:10B530008C30C6CFFEC8E127E078C6D6BB12E171D9
-:10B54000E6A7408850BF600EA3D7D4393D548EBCC7
-:10B55000F4EC3CAAC7055DBA9E49A0FA3CCDEA9638
-:10B5600054AAD71627E8F1DA65637A2995EB998210
-:10B570001D0CBF6D5EA697DABC16FE548CF117B792
-:10B580003609F5EE1F39FEA91841F9CEE5C9FA359D
-:10B5900011CA4F4D7B597F9E8440C9ED3AFAF5544C
-:10B5A00031BD28F603707FA03686BC7892CFC3FFEA
-:10B5B000F8EAFBD05EBE1AF08E2A25A790CB51A0E8
-:10B5C0000B845B4E6390D2C1D59E9B54CC4FF5A6A5
-:10B5D00013EA2F0EB4292456DCE7877C5DDEF46085
-:10B5E00029C6A1BD992E6AE778E50A8B03BF2B9186
-:10B5F000D46E1FDDF7A476DE80375BED36F07BB0CE
-:10B60000D402ED4E64B8189EC3BFB12E2A463EF454
-:10B61000097FDD60F70DF5BB99DDB8B04B9B847EEB
-:10B6200088D8D7107008B725D6EBE5670F976FE17C
-:10B63000F12C9E0AF6BD93C6B5DD300EFAF7DD3368
-:10B640007631FFBE9DB6FB9E97D947D5B03EB4DBA1
-:10B65000BC05C18D4C9FBAD458F028E77AE5D0B22A
-:10B660009525E85736D73955E4B7079F9756537A4B
-:10B67000C66021FADDA135140F04F080FC4042CCF5
-:10B680002F6D6E098663D37B2DE5BF66E43F89D2BB
-:10B690003B8DC303BD8719BD33FD27FC7F948FFA13
-:10B6A000BC432107847C6956FAC7211D0B7E689E26
-:10B6B000D53F0EE136527972C606FC8FFC0370400E
-:10B6C000FE11FCE27A8EF1C9F6365F05D66FAF2621
-:10B6D000EE769D3E32FB4B384FF43B855C3FE509EF
-:10B6E0007E8CF2B7D912D98AF915420E373FB76D61
-:10B6F0005CACFC372187ED5626DFECE1A470BB8EF5
-:10B70000BE70CFCF35993E693E4FD2A6D8F1912F6A
-:10B71000BC4E1EC71F59BE4406EA729437DD493439
-:10B72000AF5DC48BCCFD9EE4F426F022FC16DC77E2
-:10B73000C0F6E9198C5E940CC69F7919223E1B361F
-:10B74000F83D3E4BE843CC338AA7BFC4777FABF8C4
-:10B75000951847E85133FEC5BE09AEA7B6287EBB93
-:10B76000AE17987C32D3E3182E373EC4B5C2FF7FA4
-:10B77000E7FB5C43F1CBFA21A1F186BCB84ECBBE0E
-:10B78000C65871B0175A79BED463E3479477F7EF80
-:10B79000BCFDBD3C2F8CAC196FC8B372AABE368CF1
-:10B7A000A35E71D05722D371591CCB358B7C8A7A1A
-:10B7B00038B9BCAB10CF4D7883C6FD92CCFA44C3E8
-:10B7C0007E447628CD50CE6DCC31B41FD5926FA873
-:10B7D000BF6CD30443BD5F9B6C2817744E37B41FF6
-:10B7E000DB5569285FFEC8D586F6E3C38B0CE5ED13
-:10B7F0006D3DF58897897BAE337C7785B5DF520246
-:10B80000EF8B7B561BF3C74CF0ACFCAB1C930E6F5D
-:10B81000CAF0537C5D71C0088F9472233C305D0E7A
-:10B82000E19C42787F897F5687CB6F4D21D63FF5CB
-:10B830008BEFFD43E981D8DDA5FABC8428FD840D9A
-:10B84000798B9556D9340FED2BD15FBC798AFDB633
-:10B85000B8EB8803B7ED837CCFE062E3CB4A995520
-:10B860003F2C5C6C17820BE957470217F37EDF60B1
-:10B87000DCD9D4DF96A4669A27FC261674F6717F6D
-:10B88000ABF13CCC522D85E9A1E0E20BD8D12C0ED6
-:10B890001C4A60FB95E6FA57B85CFC03C084CE678F
-:10B8A000847CFD3EC7431FCF9F1FC2D79B3E3D9C5C
-:10B8B00089F2BB8650BFD9DDD2F629EAADEBAD11D6
-:10B8C0005202F37E90AFE7212E171E6975D37E1EBC
-:10B8D000E5FB918FB5FAE8FBC75B0BE933DCAAD235
-:10B8E000F7DDADE5F4B91BEC397C3ED95A439F7BBB
-:10B8F0005A83B4DD0F5BEBE9736F6B88CD6B08BEC9
-:10B900004819B57382E931E3A5AB347944782272E2
-:10B910005E4C7D19B71FB961D8FCF24D7DD28F5FA7
-:10B92000D4F1CDBB192E0FDDDF9C46A6E1FEE685E6
-:10B93000BEFFA295FCF8C5B123E723414FE45CFAB2
-:10B94000B8608CF85188E7553E9911FAAEE68C0F35
-:10B95000AF289DC586539DFD4C0E3AEB93D066D023
-:10B960007D2FCE9F88725D2825A6DDE0CD64F45939
-:10B970009FC0F6E3979BF8FB5BBCFE5B994CDFBD79
-:10B980001B47CE38332DC29FB7D1FDC1217C77EF45
-:10B9900055B1E0BB35D367E063F3B915733FEFDA18
-:10B9A000BA46A931F8EC42FD88F599BF5B9AC9E423
-:10B9B000D6C64CC2E4E4FF67FCF9EE5A17F51F1037
-:10B9C0006E5EDDFADF5D9B541F2B2EF39D4C1BF347
-:10B9D000B703A0B3D3A8A9AF29682B16121FDBF7B2
-:10B9E0001DE3C6F890C80B884FAF561A47A2309493
-:10B9F00087C215F0E1530AA07FEBE038112B8EA32C
-:10BA00005AA2FA0D736D88EEFC873C941EE07B4DC4
-:10BA1000A1793DFD3938BF8BA527223F3676B87D09
-:10BA2000BA21DF5FA49CB931F3EF2B67049F9373B6
-:10BA30000F8C8DA527EB51CE4C075193F9289333EA
-:10BA400017E8F762E1572FF7D3FDEB11C3EF8067DB
-:10BA50004471A92F1CC993D0B8DA6467CF3B139304
-:10BA6000BBF1F9856374982413F200CE13DA69955B
-:10BA7000849DDF7A5FF84D2DD3E8FE4A76F05F3281
-:10BA8000A17EB5C2FCC53319818732615D897C5FB7
-:10BA90003891EF0B2B99CA562C9340215DD7247017
-:10BAA00097316EB1D5E21B8DEBFA5852C7A3DFE296
-:10BAB000B684557C26934831CBCF0B87D05F4B9F04
-:10BAC00098E8437F37711C21BD343EAE3A308EA6D4
-:10BAD00024F5BF3E06FDDBE7AD345E3409F351A12A
-:10BAE0003CE97BB9618DCE3348E5453A87E376B4CE
-:10BAF000CBE1FBEF4BA1A770DE27DD76CD02F37A19
-:10BB0000A0738A230DDE47F6C89A9282F931A7EF17
-:10BB10005F00EBBDA257A671E72BC89457C6A09C47
-:10BB2000E9B5D1FDDF7556B203F9281E7C3FF95601
-:10BB3000EC3C30922519F2BBCCF51F703DF0499CCE
-:10BB40007CE3DF70392AF2676C227FC61B18367FD0
-:10BB5000C666CA9FB1598304F7856D83F9330D8496
-:10BB6000E6CF403FFAFC994F2A63CFE31D3E0FDB3F
-:10BB7000974971FA4DA6EF3FC91F7E9DB62F1D86CE
-:10BB80007CECE8F74EFA3E5EFECE001FFF9338F9DC
-:10BB90004BA707FBCF265ABAFE3B46CFD171F268BE
-:10BBA000BDCD940714AD67F93F1DA98C4E5EC872D8
-:10BBB0007B5641D7AB483F3DCF79BDD363C3785265
-:10BBC00090A8FBE8F91EAB6DA05FF0613EB6B37EB6
-:10BBD0008476B705242FDADDD76FB27DD4AF935BBF
-:10BBE000B5016399607B9D1C5E88316CE4A7098573
-:10BBF00034FFEF33E24B710F23471BEC72D0AA5B8B
-:10BC0000475F1C3BA2348BC1A72F3B36FC466559CE
-:10BC10000C79CB43BF4FE6E73ED839B4DBDDC3CB6D
-:10BC20004F846F285DDFBF190F1E5A7F21387BDBE1
-:10BC3000197F0F54482CCFFF6F0EEF549EEFC6CEE6
-:10BC40000FD84CF9EA0BB3CDF366F9EAF7A706CBA8
-:10BC5000B2D02EB3FAC6E9CF0BECB7069226C3B327
-:10BC60008FCB1D335C3667317BCFBCEEFD3CEF3EA6
-:10BC700051262DFB74F037AFB785E351B4EFB0B167
-:10BC8000FD2C147C76907B2B0893B3CBB2F2F93960
-:10BC900097542BE2AB81754156B88FD0FD2501E753
-:10BCA00021F0E37037C331487C2B31BFFB42F05C9D
-:10BCB00075345141B9BFD23E70187DD5FE5ECBDBE5
-:10BCC00063E0F9A173CCF1DD04F7E10A9F39443058
-:10BCD0003EA2B27C0A3287DA3D92962B9F9F387241
-:10BCE000BB676B72A810F9E26389C56B853EDA9A6F
-:10BCF000736A1CE6D7BF9F5651943D95C6DF03E992
-:10BD0000483F3F4F60F4F308F404E50DBF184FCFF0
-:10BD1000C12FC90E4DC8F646F3FB4860601CE623F0
-:10BD20005C2C7CE0C786F47321F8ACCD62FCDD9717
-:10BD30001C9B3E1EE37C7821BEA0E7CF4AFF7E7CA1
-:10BD400021E029F62FC4FC266433392C9E026EE6CE
-:10BD50003CA209D916DE8EE5112DC90E52389F1D61
-:10BD6000F5E97107CCBD4F897DAF434F1CFE30AF65
-:10BD70005FC0FBEF257FFB1263CFEFC5FFE1F91535
-:10BD8000E3FC008E7D9362CFEFDD11CE2F4806DEFF
-:10BD90004FFD3BE82FC07331F21DE918A072B12F9F
-:10BDA0002DF63CBF1CF13C43B6BF879E15F44DB445
-:10BDB000558D74DF3E2B31E6BEFD52F0A3D00F321D
-:10BDC000EFDF8B7D7A901F74BD75F68195E988F75A
-:10BDD000397CDD1924928AFB9ABF48A0FB0043E41A
-:10BDE0001AE77380978DC26BE1008D67F48D8B2D00
-:10BDF000176CD90C5E83ED3BD938F1CE1FB8387F74
-:10BE00005EE8FC01290DD1386085DD1991010FB77D
-:10BE1000717C28B9B7A868175664BD7A0CD709F0A9
-:10BE20003F3D084F5D5EDFA9D697DD636CF1E5F617
-:10BE30003AF9E9B29618EBF167847C280F06DBED3E
-:10BE400079C53D4687AF62D26F61E7A7072C06FF31
-:10BE500038935C947FFC3307E3E7F7D382541FA049
-:10BE60007E40BDB3F5B92B4B1099685F605ECF8003
-:10BE70002B91CAD1F69CE9853E1D3C2BB3855D29EB
-:10BE8000C7B117BFDEB980A8BD2419ECD668FF562C
-:10BE9000FA5EE0A7C2F9EB98F8F06704E6213C3FB0
-:10BEA0004F0BD4E03ACDF0D3EE9E994AFD6584DF86
-:10BEB000EC687F83F88F83E75B33028BB0BF89E93F
-:10BEC0003E16BF10F97C83710BABFBB83D0AEF91B6
-:10BED000E2E55EFC05FCD5DBB2032BB17F2581F3E7
-:10BEE0002371D2F3E3C25E2126BB8694B3FCD21544
-:10BEF00059AFFE19E33E5B9319CB6EFD8E83E6D9F5
-:10BF00005D2FB9155C37D81FEF7D1FDA8748E4BD78
-:10BF10006FD37D2D616724C9E793463E4FE1375FBC
-:10BF200028BFFA10DA61309F4A8B93EE731E02B27B
-:10BF3000C906B951A9B067C53CA02AE8AF52CE3BAB
-:10BF4000D80FF3FA9C9C4EBB0ABE4EE4F1C58D4758
-:10BF5000A73A902E2BADB6537AB9658E7BDC956DE2
-:10BF60008C7B7C4E16FE33DD0B2E64FEFF030B2B09
-:10BF700033F57197C1B8873897A6AD62F2D424E73C
-:10BF8000843CB3D8D93D2324407CEE0C1A3F627028
-:10BF900007E71AEFBDBA4A94D13981F24C8E2409D1
-:10BFA000BF87755FC59F6475280BE50CA6F3E07825
-:10BFB000E0F565E1B3FD4AD587CFD952D0CAE61185
-:10BFC00066F987A4250FDB5BECFD328E2FE214743B
-:10BFD0002619D88F1897955DBCDC51F7D9CAB5BE24
-:10BFE000A1F10CE27451BB57E1F33BE9766A165DAF
-:10BFF0009C23C1193949F356F9D31CEFB853D634F1
-:10C00000CCDB4E243D545E3A9D7FD410186EE296F0
-:10C01000B0FC7D29F433E4B7E34A17F1C3FBB33F27
-:10C02000FF8220FED2F16458013E8DFAC9EBDC4854
-:10C03000F3A1BD41AB492F8524E4A3CC7AF37BA3C4
-:10C04000BEB2933E7A6E488A04B3CEA75F388E1391
-:10C050002F7E63AB64A81FB899D9C36F27B2EFDFF7
-:10C060004E64DF1DE37AA6394D212CBE63B7A33D94
-:10C070007FC675028F6AA23EE9447D62B705285EDD
-:10C08000855E59BFFF5682786B3E504BE1F05B896D
-:10C09000ED8F6A2B249AC7B094E7DFD51791D702AA
-:10C0A00038B59C7CA6CF5E0EAD688272DDABA4383D
-:10C0B00002ED4A6607ABF15E97F662A26E8172BB33
-:10C0C00023F4D44F711D47D93D631BF8795AC0C47E
-:10C0D000BABDD0FFCEEB46A9DB714955035B314FAA
-:10C0E00068601B71635EC910FA3D07FC00F4B00B79
-:10C0F000CB30EF0D6B42FF7A07B4CF7E95A8B40D1D
-:10C10000AF471F05F12771BAC0F7B3E1FD064E47EF
-:10C11000050725B6BFEF61F77FD1CEF17E2E3BFB41
-:10C1200075C3C18A6BA7C2BC0A7AA750F21E03ED81
-:10C1300031FF093310587B6289D57E0CB6F7E17E5A
-:10C140003EC30FC951E8BD4984CBBF69263E9C114F
-:10C15000E5075A5FC2CB1BB89E32F00DF603FE7A9C
-:10C16000A08C6DF7D3EF3C8C3F54227E183F4F27B5
-:10C17000D11FECB72A3A0E95CB7378DDE1E5F36970
-:10C18000DEF7346BE405E4F719FC59C29FC8EF767B
-:10C1900080E3326BCB612FAC27751351DB709406B3
-:10C1A0005F3BF6574A8232C2B9CCBDAD1DE7776519
-:10C1B000C3D174A4AF753905949E66DAD502079091
-:10C1C000487BB9AABA0BF09E3189C26549BD3D8C46
-:10C1D000F96D4B06EFF909F99702FF2C0BB1BC661C
-:10C1E0002C37E8E2B522EF6F6902F8D531E4F7BAEF
-:10C1F0001C662789EF37F07329A2FEA61C96FF71F3
-:10C200004DCEDCD21C9A97C4F2A181FFA76159C818
-:10C21000151897E6AB2C26011BAE6B31E75FC1FF0B
-:10C220004B02B7537B7649D06897FE5662F8D69694
-:10C230004BD44E5C563FBCDD3A3747EC07E7B98F2D
-:10C240002745DF0BBA12F27C11EA7794C335A0CFF1
-:10C25000757673C39DE752E977994FAE3F7F59F4E6
-:10C260001CCC06D33998667E0E66C381365B06D237
-:10C270003B3F07B3E1E0875BF5F97F024E43CFC157
-:10C280000CD0BCC7A54AF8053C1FB4F4165823B41B
-:10C29000FF153F37F1229E9B981CA523D7758E086A
-:10C2A000CBAB0BD0FCBE3C77928AF9289D96C93463
-:10C2B0009FA833D9A5EAF377B6B7B554633B914746
-:10C2C00024CEBD2C8DB35F7C7B0EB3B71F92583E3E
-:10C2D00097B6DC4EE1ED95C931FDF97E6F4190E6F0
-:10C2E000D195E6F8447B1A5FC0BCD329F00C839942
-:10C2F000C6F0C5BE37CB07E8AF03FBAB2A5069FEDB
-:10C300004C550ACB43F3A6074B6E2B8AF65B77900E
-:10C31000E5EDD5053F3DC2F26F6B4B119EF1E4BADE
-:10C32000597F01FD75E6C488D3DF29879A91FE6C99
-:10C3300095C1E56BA1DFB3AF2934CF8E6C0E4836C3
-:10C3400068F79357DC2A9EBFEBA808D656D37A2B02
-:10C350003D1F98514F2209505FFAAAD28DF97D8D69
-:10C36000A44BC17E1A4D7AEC16E78B0AF2E92DBB7D
-:10C370006D51BA249897A816A0C06BDA3B242E42C0
-:10C38000E590904F667A26638C72A844C85D900F42
-:10C390002CAFAF81E93DF2A484F1A1B3AE1332F723
-:10C3A000AFA9DC9B2A849549DE4F3DF812B567049E
-:10C3B0003C6781BC403F4EC2F793D8116EBABFA50F
-:10C3C0004985986F3A8324527A1B6247F0F9950E9B
-:10C3D000CE9FD94D424E56943393D48C1F188FD292
-:10C3E000B9D8E79B8AF7FAC073061FFF0B4BA0284A
-:10C3F000E2477C91B005E0BC556AA17AC78EF99FEF
-:10C40000F0DC2E85A85CFC99A6C908D72B49CBE2A5
-:10C41000857E8AF72339543EF626211E8E2BAA1DCF
-:10C42000EBAB3151903E8DF89AE77CD08AF09A9729
-:10C4300065C68B6645F8CEF70DC1173D571088834A
-:10C44000AF80902BC42857FCE41C3BD7BCEDC81D23
-:10C45000E81F5FC83E793023D48FF2339E9D122FA0
-:10C460001FEF2497C723CDC73B6B637EC574D27F74
-:10C47000E35E69289D9C39BC49CED2D193A0D3E715
-:10C48000787EBEF44B9EEF5BEAA2FA2FAA2F191D0D
-:10C4900094F1D274A42F1D1D5C75C01191619D256E
-:10C4A000FCFBE9480F93A3FA326271FA947CC4BB97
-:10C4B000DA29CB43EDE48C341FC5FF144B80E27FB7
-:10C4C0002A51D3B9DDA9E4C2FACBED3DED561FC523
-:10C4D000FFF7D1BFA9203E8AFF0A93DEA972D65981
-:10C4E000914EAAEC663C0728FEABDD43DE5BBE0A3C
-:10C4F000FE2F43FC0BBD3202FB14F0EFCB1D669FF9
-:10C50000311EFEC7E73A795CE3E2F06FC6BB9003E9
-:10C51000FB1CEE2A27C6831B593EF294D7C6B46390
-:10C520003963BD9F9E93D997AAFE8AD6B7B0FAD237
-:10C53000DE808CF732166C847A28EFF307ABB0BC40
-:10C54000619344E5E8D43743ED581EB399D5976C11
-:10C5500069F915DE6FB64163DF3F77722BBDA72205
-:10C56000BC957F5FD15585E50D9DECFB3FB8EC1A7E
-:10C57000FAE565C7C2EDF87EFC0E360F61F7CDE631
-:10C58000F4B64F7AFA57F4BB2EF6DD4D47EC89CC62
-:10C590005F6276DC2CBECED98FB1757A7E77758DD1
-:10C5A0000FE0BE7640B351B961692AA372348E9F01
-:10C5B000562175E5E1731EC80942F10E749ACFF257
-:10C5C00055BB6188B5B9CC0E11799E986F5EABC32F
-:10C5D000D7DA5CA66F45BB8C34C2F2921F65F7CDEB
-:10C5E0008A3CD4C8C344C2F801AE91EADF3879A9C5
-:10C5F000F30A5AA83E9D7799C847EDB7AE86714BAE
-:10C60000CEFFDFB9B1FCF2263EEE099E3F2FDE37AA
-:10C6100086FD16F44FF621F1D0FB7F7EFE1ADA2D4F
-:10C62000FB701F5977FFC83E3F2BFFEFDC67EFE938
-:10C630000427F7264B8B554325305AA2F7A97CA334
-:10C640009744529287CE7F9E954458DE049BFF8D7F
-:10C65000ED4AF7769D1DBF44888F9963A95EA9E3D3
-:10C660007812726309C717F0793BF2C7527B0BB59A
-:10C670001B9713A6D76F26611ADFB8D9C4E7EB9CC6
-:10C680007F7ADF82F6F31E233FAF87E9B07DF58125
-:10C69000C7DF05F8373EE272A3FE5FDF636CD7F8B1
-:10C6A000C86BC798FD65E4F746C1EF6123BF8341BE
-:10C6B000C1F8FDE10974DF469C0B74D807DED7484A
-:10C6C00074BD837ADFC47F0E3C2758887E8D85E554
-:10C6D00027F2B218F7B32EA69735D0CBDC0FA222E3
-:10C6E000F7B3BE05340FBE44E8512E67043F977080
-:10C6F0003D3F448FD798FD9D07299F4CE125B3FE10
-:10C70000167A5B9C3F847EA9FE067DFD5A00E6DB1F
-:10C710006B718611DE51BD1DA67C34D90EF2DA4252
-:10C72000F1F73CCAE9A91C6FED5CAFC7F50F9C1B84
-:10C7300063FA07E06FD07D84A17E41C460EF9BF176
-:10C7400016CFFE1FC49B03ECA924F4F709E3E31CF6
-:10C7500032A2FC1090DBEFE40EA3B79543ECFDC0D2
-:10C760004E078D2F8838BBE0BFDFE4B1F8C277B346
-:10C7700003EF613F7D7CBC3EDE7FDFADF3E8BEF7BB
-:10C780009F4880EE7B631E536E8CBC0BDCF7EED0B3
-:10C79000C54BFB5263C7C13FE17260621E5BDF198C
-:10C7A0006FE034F2D50985C5D94F24F26732DBA793
-:10C7B000F82297C57B27E6B1A72B8FCB119EDF7D93
-:10C7C00022CD189F17ED52F8F3E3567BB043170FB5
-:10C7D000F73D9CD0827ACC5BC0F3E137323A3EFB26
-:10C7E0006CEA4EFDFD7039791513F3304FA420A08B
-:10C7F00064637CE659A62F9AADFD0ADEEB93E20D49
-:10C80000D9F2302EE32381A7B11F5FBFB218E07DBC
-:10C8100096EFF79FE5F7009D75B0A798574E5EED30
-:10C8200044FCEEECADFD546E0C966BFBA95CC8C9E4
-:10C830000BD271CF2E11F5BC7C0F2B13EE57567017
-:10C840003EA171E31871E2A17161E33D371B94D8F9
-:10C85000FBD424CF6588F7AE38C8E2902BED646B2B
-:10C860002ED45F7F3093FA1B8DC9DA38A487AF1BB3
-:10C87000C73D3BAA97AE6B7BC5C0E8474BE9BE30CE
-:10C880008D17AD3FF812957FEB05DFEC37F2CDB495
-:10C89000BC91EDA798E3EC23E0A78ABC61ECA0670C
-:10C8A000507FD9A278B88DE75155CB4D551857FA1E
-:10C8B0006C0DA1E76B6F7B45A67475DB5312BD6FE2
-:10C8C00042D871EB399CE3AD0BCF27F8747205CFDA
-:10C8D00027F8747E1D9E4FD097F17C82BE3D9E4FFF
-:10C8E000D0D7E3F9047D3D9E4FD0974BC80DED188E
-:10C8F000A7DBD049DC611F3BAFA0FF1ECF2BE8CBED
-:10C90000785E41FF3D9E57D0973F230C6E9F3D269A
-:10C91000D3F83F9E5BD07F7FD32B3F298BE0B21DA6
-:10C920002C3FADDD01F0473AD402BD45009F351CD8
-:10C930003E78AE41DFEF27C9735F46FCACE9BD71BD
-:10C94000213EAF38708BA15FD2C5E4710BFC433838
-:10C95000DE488229E8CF4D26034730DED11C9654AD
-:10C960001CF7A6478C727BF01E93B0F1FD3AA28BA8
-:10C97000FFFA87C6FD3BF25C9EE32CB739471FEFF9
-:10C9800089D283538D201CDE94D558F450422E4F0B
-:10C99000A1719E97658C61903F909687664ABAFD1B
-:10C9A00001133C12B28C74E1F019E922A9D04817A6
-:10C9B0002ED5481729E546BA480D4C1816BEE9355C
-:10C9C000463A59273751BE17702E877F08E7C97836
-:10C9D0003325C217D689F162337C1B0FDEB715ED04
-:10C9E000FE8B856F4F1EDF57E1F0FD9CCCAC72FAD9
-:10C9F00068759DBD2C6AC794BEDC423781CDF1536A
-:10CA000001476147883828E87F6A4F47FD7AE6EF9B
-:10CA1000817DF04B94C3C715E6E72125A1DC5C4B73
-:10CA200042543EAD35D90737391F54D03E18B25E57
-:10CA3000B0CCF0DE42F37AD1DE22BAB894D93E907F
-:10CA40000E4A11D7245CEE4121A743E7A931149087
-:10CA50004622377EE40ABC85720B1D457B99216E08
-:10CA60001CD3EE13F3107011E3279016390BE9B9BC
-:10CA7000D06C9F19FD6BE18F8B78BB886B0B7F5A55
-:10CA8000F8316638CB97F9DB91FEA7B8851FDDFB3F
-:10CA90004D7C2FFC67B3DF3A781E00218BE76D7861
-:10CAA0009CFE6EEF6A3BBB8F8FF19D78BFD5B3289C
-:10CAB00065B83CCCBB5A8DE75F60198161CF13210B
-:10CAC000C83270DF89605085ECB8E6483FDEB1B30C
-:10CAD000E31BBF1E78119EDB8B9FECDF8275E7CED8
-:10CAE000CB08D7C1783E61E78315FE9D92B7F55616
-:10CAF000D4A389AA957CA4A30B3B68AA8F0AF9B892
-:10CB0000A827B206EB7FA3DFD7FF473DBF0BF0F9A5
-:10CB100068EC30F58ADA1833AFD6042F710D86A38E
-:10CB200068EE49B44F1C44B76EAA0F7565390A2FD9
-:10CB3000AA5A657A5E4AD407F0DE92AFBB2EC4FBD8
-:10CB400047367D3972F4639B7EFE619657600D1205
-:10CB5000CCBB553C50AFD72F8374080C55A65BDF78
-:10CB600008D6854C83EE27B34B18BEFF56EBEA3050
-:10CB7000E10BFB0D665CD2F3D32EF1F9452E71FC6F
-:10CB800092DA4B1B7E81DA4B1B7EDA253EBFC8252D
-:10CB90008E5FB2E8D29E5F60D1A58D5FED129F5F80
-:10CBA000E412C72F597C69C32FB0F8D2869F7689CB
-:10CBB000CF2F7269E357A376A0B33C42F05E095FC2
-:10CBC0000751FD3E3059E135FAF3052AA1791A845F
-:10CBD000FB25F9DC2FB96F474B3DBA50BB34C54735
-:10CBE000E341E0DF6741FD78C2EA77752EA271D696
-:10CBF000B651E372F09E2A67E7DC93786E6FBCC68D
-:10CC0000FC71F3DF0BAB0D18FFEEDAB5E5E986F248
-:10CC1000D45EE3BD15DF6C2C30D42F0F4D34FDDD19
-:10CC2000BC29C6BF47169C61BA7FE156A23F0F9947
-:10CC30004F222AC657F2EFB154E2BE99157DE62B7A
-:10CC4000E1FF6E857E17807F7AFF251F3CA1C1FE24
-:10CC5000FD0837C5D0BFD3547FB1E74F9F19CDE34F
-:10CC600031A6F3A7042F978C71DEDC9C8749AC3783
-:10CC7000D3F89CC0D7DDDB2CD4E5FD7C07A1F73BC6
-:10CC800056857D167AFF39C7DB444E7A62DDE15660
-:10CC9000E339F47C8D54223E0B3A8805E36BFEDDCC
-:10CCA000440D101A17A274B24B8B4D27BB88BB12D0
-:10CCB000EFE3DA1526F4EF6309BAB8DBE6CBC17D02
-:10CCC000B5899D8C1E049DF8904E92312FC87CDF53
-:10CCD00080195F647204E6BA6B477E9A3E1F95EC3A
-:10CCE0006570B7C3BFE1F055B8DB882F1FD195BF82
-:10CCF00002BE4E7F4D7C299E6024C583F14CE2C369
-:10CD00003CA9C3A3C659101EFE4E95FAFF35D00CA0
-:10CD1000E1ECEF64F7A8093C89FE76B492C81C9D4B
-:10CD2000FFE75723018473B55C5489F9E73B4B69EE
-:10CD3000C878087E76127722C6BD77765A12E9DD6A
-:10CD4000D407002FC584FCD7B6A5298550DFED2771
-:10CD50008978BF56779B85DE57D6FDAC546FBC4FA4
-:10CD6000399260C9A2EB48B094D3A7953D03FC4922
-:10CD7000ACAC3E226379F4E621F77DC8589F5A6334
-:10CD8000FA7B812420617BEB652C8F332560BCC747
-:10CD9000C6566E940700C6DEAC328CB7707AE7F7E1
-:10CDA000A386AB4918FFCED7655CEE98E928F5AEAF
-:10CDB000459498DA467D8BCAB3EE3685C2DFC6E568
-:10CDC00015D9CCE842837F484FA9263A72A9463A42
-:10CDD000B2C979340F57F095988F18BF6D5446A299
-:10CDE00095CECB4AEFC1B699E584697E4E0C06021A
-:10CDF000EE9C1E120E43BD4D63FC41E43EFADE364E
-:10CE00008D9074FF5798E7D7944F575F16FB7CFCC3
-:10CE1000C5CA2717EFF3EEA96C9D9FABEC3EEBAABA
-:10CE20000E46EFAE1D8CDEF12437CBD70A2CCCD6C4
-:10CE3000EDABEEE772CA0C37576FA00AE979AEFC8A
-:10CE40006A00F323EE7993D17FDBA8B75FC6F28E39
-:10CE50007B18FCFD2AC333D08B1A81A9DF7397930B
-:10CE6000E6054F29057C21FE5F35CA93A9BD4638EA
-:10CE70001698E4863F0E5CCDFC1A0FAE7708B89684
-:10CE8000015C0B2E1EAE8AC6E473EA4C76BFE2E16B
-:10CE9000510AFBBBBC1A83636A40A5F277AE7C2EB5
-:10CEA0009202EDEE0B80BC8179D60418BCDD33858F
-:10CEB0001C37C253C81701FF7C0E7FB7EA7E05FFFF
-:10CEC000BE8B53B3129F84F0FDAF00DA115D538522
-:10CED000BC192088B79400A35B01E7AEAB189CF3A4
-:10CEE000031CCE9D1C6E129110CE667A35CBE79452
-:10CEF000AF09E76E01E70C52F655E07C5F12BB3FCD
-:10CF0000D93686C1D5E61C88A09CEDF45BE9BA5EF3
-:10CF1000F02BB4BEB398D53F9CB4320BF56DA77718
-:10CF20006B16D2659BFFC62C94EF8E2C2E6748C0E3
-:10CF3000995D163D77502DEFA0F78F6EF529143FC0
-:10CF40002E5F6CF995323364A7E31459894CE1F0F4
-:10CF5000981A0B0EF652C5202F731B8DF04D32C15F
-:10CF6000D7F135E5C37F7E4DF9803947D8EEEEB174
-:10CF7000E27E862E3BD54FE5B7D0B879011F6BDB3B
-:10CF80008EFBD97BAED774EF6BF2519E38AD2AC2BF
-:10CF900033DEBC859DF338BF0FE67E7E9F4B17BF07
-:10CFA000CFE55E7E9FCB0E7E9FCB76BCCF059E9D50
-:10CFB000789FCBE5684F07E853BE278DDE3BF839F5
-:10CFC00026B0FBF1DE9C3324D6FD247ECDA8FF2EB7
-:10CFD000DB64BC9F2CBDC6A8E75203463D87FB5EC1
-:10CFE000FA7A976ABCAF2DA9D0785F9BC367BCAFB4
-:10CFF0006DCF6521D907F0FD7FB1B1C61E0080005D
-:10D00000000000001F8B080000000000000BDD7D09
-:10D0100009785445B670DDBEB73B9DA4BBD3095912
-:10D0200081849B950E84D040C0A0416F16302A8326
-:10D030009D088A8A1A013140481075CC3C9D97861C
-:10D0400004081830A0A8332E34EBE0B845272A2A6C
-:10D05000321D04069FBEA1595474D4BF757C0AC802
-:10D06000480417FC9ECBAB73AA6EF7BD371D088A28
-:10D07000FFE77BF1934ADDDACF56E79C3A55313B27
-:10D08000CB88DF4AF0E747F8C7DB4D3C76CC9A48BF
-:10D090003221D9BC6CBCF8B0355840C8B2B6EA38B9
-:10D0A0005200F594402A2D8F85429990A566777F8E
-:10D0B0000FFD1EDB366B227110B2B88910FF604283
-:10D0C0005A9BAC982E4CB7B8FD89846C7853744742
-:10D0D000D12616C5A33869FDAEF42584D0EFCB9CCC
-:10D0E00084A464D2EFCEF984641122D101049A970A
-:10D0F000DA261C2185B4C1D4B9848C09CF67599B29
-:10D10000C9ED2F22242ADEE686F14981F45190965A
-:10D1100039E97F3FD2F63FC2CF45E1348AB0725C35
-:10D12000278C236BF204C6D39737BE273CBD5353DD
-:10D130003E58B6277E028B3D8F9CF7A34853715A09
-:10D140005C8D8DA6AD09848CED39DE374DE4E99D0B
-:10D15000B90850429220AD25004F89F7B934BEDAA4
-:10D160004A6C6138ABDF173B197CA30412B1DF16A0
-:10D17000806B54382F11A274003E061645ACAFA642
-:10D180001403848C26A4ADC9BFEF6373F8BBAD84D0
-:10D19000B6B7F5AC5F298B38EF29B28CED6C929F56
-:10D1A00038693DBB9BB6D7C0C5A69CDDF8F4A7285F
-:10D1B00091AED7C1E9863C214880572BCFC70A35AD
-:10D1C00053E424C09787229BD62B56484D011B4F12
-:10D1D00051DB09904AE42357185FF0E3A4E50CA45F
-:10D1E00090D272ABBE5C4E467861BF52B8BDF2A31E
-:10D1F000D0FBBC7FA914F0F851EE69CA2DEE5AE0BD
-:10D2000027E3F77F974D2A1CBB1329DC44BEDE08B9
-:10D2100070FC772D1C451B83638B90B93548F9CD85
-:10D22000AC38DC1423A43451EE00BE6C516CC897AA
-:10D230002D891D81329A3F5964724357F6DC32E4DE
-:10D24000C796FEBB0FCD04B84EDA737823424D0962
-:10D2500054A8F0A5E5765765A042C50709E32B86DB
-:10D26000FFBE7CD8E6E0229AF6BB7C1A715252B11E
-:10D27000A5588848F1129D5B61ADB185F163815F6E
-:10D28000E8F798C4094744CAF7316E0D1EE1FF1F45
-:10D29000591EE141176F19B8E41601882235546F01
-:10D2A0002FCC47923DE1F991738F2F329002298D57
-:10D2B000A6923B15E4654F7AF732BEE7F57AE70BA5
-:10D2C000566FBC3831F5460A97D637A87C04BE7035
-:10D2D00031B960B6327CB61225F546DA55EB40C955
-:10D2E000ED857CE274941F4B52AB5B417E7E95686A
-:10D2F00022A200DF1759417EC0EFDA71933C26E28B
-:10D30000D7E027656A8C4EEEB7CAD528CF7A9B67DF
-:10D310005A8DBEFD805A7DFBF4F909BABCDA2E3A6B
-:10D32000F5B20315FDC2F96592C70A726471E26A2B
-:10D33000A14643DFF1F93507E5D1E1BC397512B6F5
-:10D340008B4A2F8A382FBF4B3904F5E9FA991CB65E
-:10D350002546943FF7F17DE87EBE0F9D699D0FF253
-:10D36000FA7FE4F51F6E72621AC267CE6C1D5E967C
-:10D370002651794DFBDB0C5534E33F23D71C07FEC8
-:10D380000BE3D914860F306DC11C13F0ABDA4F4B91
-:10D39000D274C49BBA9EDEE6D7CAE5BF5ACF2A79BB
-:10D3A00089BB00F91EE57008EEB21E5F05995C6E40
-:10D3B0006C9CAD1B7767FC84A99994EE961C14496C
-:10D3C00014CA11FDFA7AD2AB7E1D4B12D9FA7BA793
-:10D3D0006FC3BAA94408CD0BF309867C7F43FD2CAB
-:10D3E00043F91043F94843FE7C43FD3243FE524368
-:10D3F000FD6A43FE1A43FDE986F23986F20586FC92
-:10D40000BFE9EB17313CDFAE7E3B8D7C01BC1AEBF4
-:10D410004B9282F8950CF8353BF5F82D4D2F3D3F9A
-:10D4200013F7855A1D7E55FAEC2B7E96521917007C
-:10D430007E926A987E523C8768E961496216EE1FC7
-:10D44000622971B3564C4E5978B998C6C6A3FA9A58
-:10D450008E8EBAD267A1FE481E4C6072F30C742106
-:10D4600090047DB9D23F5C9E05FF9E5BBA38331DA8
-:10D47000FBF8BE7BFA79AB7277CB20CFBC4C901710
-:10D480003EAA4F0F0BC3490EE9D37430CA77EB1392
-:10D49000892F8AEE77EBBD26CC7F954A07027DA5C2
-:10D4A00062B64EFF262428403F4639B00AE4144DA8
-:10D4B000EF013945D3BB9B52315DBAC2943613FAA2
-:10D4C0009B6841FDB8DFF0255E09D2B2E27CD8BF8F
-:10D4D000EF1EB64531D1BCFD9448FCA3A8BE5078E0
-:10D4E0004D312C2776FCF4D49D30DC77749C31C010
-:10D4F0009D04958C7515C4671E4EC88A1D6997BA20
-:10D5000068BF728EE48E86B202F7422911EB79C1B0
-:10D510006C90A5EE3DD9343F28C784FA85B9B8BBD5
-:10D5200009F47775DE2B2EA5844B2B6656BA4D5E1B
-:10D530000A823B07D5DC0B701AD4464C0ACDCB5E71
-:10D540005900B9F666A68CF0DEF02265C86C18A802
-:10D550003B0DF6D9AF575816C13C7BC713114DC5CB
-:10D560003F3D55FB413DB33F7E57402ECB129210BD
-:10D570005DE57FB52B346F1359FE95CC239E459AFC
-:10D58000FCE399479C906F1B9561827564263A1461
-:10D590005F04BADA0FF298AE7BC38A5983B4FBA05A
-:10D5A000319527D27E53685AC053A0B5F300FE3C94
-:10D5B00095F9F754967F0DE046FB951B7979224B40
-:10D5C000CFF538C6FE0F643A55BDB43FB71F0B6C9C
-:10D5D000C9A7D54FF783BC32EAA754D0F5073A5F05
-:10D5E0004BED4913ED7BED0A0BF1529E5A9B4ED049
-:10D5F0004EF42EB3F836017F4872FF2B357A976FC1
-:10D6000059F23580179F40A66AE5E4FD1CCE2BB386
-:10D6100004AE671DF38A947ED7D26D13C4ED5AE22F
-:10D620008C067D24846FEF098FA2C1F78559A5ABC5
-:10D63000BC30AF996CDFCC0AC9B3BC8512ED671D55
-:10D64000F443F3EB5A4D38BFB5DB28FFD2A1BEBA85
-:10D65000EB2313E8CDC388DF04EB1B4A7C98BAC8E0
-:10D660007C1300A583EB191B39FFE651FE467B07AF
-:10D67000441F2DF70CAAF91AF8228EC89897BD4EB0
-:10D68000A4A7FA6DF16591F4039265E27626A99557
-:10D69000C6703B87C199648DEE097F33998F70BF47
-:10D6A000DDE53141B96DEB3EFF005AF4DCDB7ABABF
-:10D6B00005A8546BE44E0A1F27CEED5144DACFB6CD
-:10D6C0008C9A58685F5FFBC5EE64E8DAEBC5F6A399
-:10D6D000B29C58EF1A7FC778E866B83B5806B4305A
-:10D6E000ACB26B0790CC50651D9819C4557CCB8E9D
-:10D6F0007E32CCA326318BD6CF0B044B817C6CB50C
-:10D70000FBFCC9389F0B4D4017D9301F4E1F5548A1
-:10D710005F32D2898A6FA0872A9ABFA68EC1875AA4
-:10D7200083584E24A76EFEEB17533AB1F5A4137B32
-:10D7300016D38F866485EC2B623EBD7D35242B820B
-:10D740007DA5C2A5BAD36D067781E709E762B081EE
-:10D7500026F9BA7746D3EF8B326A4640BBA2073D23
-:10D76000CD407FB66D012FD453E1642B092802D63A
-:10D77000538A00AE6BEF2A2BC37DA19DA0BDD49B25
-:10D780009E6B2E31E9FD38A41DD791DBAED7D3298E
-:10D790001DE37EDE838EEF0AD1718CD62FA1EE3F82
-:10D7A000BE36538C0BEC0C6A7F605FBDC891CD7C9C
-:10D7B0005F52E95AFD9E4322FB19A686E19D2A9EEF
-:10D7C0001EDE5323C1DB01FC918DFC320DCA9DA4EA
-:10D7D0001BCB07DDA5E797FAAD5FEC1E40E76F2B8B
-:10D7E0009247027ED4F167717AA6743C13E9F8C1BE
-:10D7F000EEDDB0AF0DBA8BD1F13CD03592C2F478EA
-:10D80000BB4BB919C651E9CCB89E9B787F8B323C93
-:10D81000F3B0DE831DBBA2B19DA701F2B60703FEE4
-:10D82000681286EF200EDFA8DF87F0EC04F9513D87
-:10D83000D1BD0BF6678FCB391ED24972770BA81674
-:10D84000D7D68A3ABDCF885F4A5FBF877514114F1C
-:10D85000B9208036DB61C6FDB317BA09EF9B5E5570
-:10D860007EDC7506B9BD2C121EFADAFF890C4F3B1F
-:10D87000B44FA8F490D3D96D3DE6D5C77AAADF2C72
-:10D88000ACC7FA747AAC4AF7CB5BABD1DE52F1A0ED
-:10D890007E5FDC5A5D9909746E93DC91EC9FD07EBB
-:10D8A000C3E9FC514EE7ABB9FED5CEF5AF954D328D
-:10D8B000CAF7B62617A6CB9BDCDC1F5A8CE9E226FA
-:10D8C00005EB89CB4E94A2FD7E1741BFD6A2D8426C
-:10D8D00021125D657AF5FAFEA0463DDEFB55EAEDC4
-:10D8E000EF78ADBE4CFF8F2BCED295DBDD4374E5D8
-:10D8F000B1AE91BA7CB47CBEAEFE964135AF015D4F
-:10D900005912CB74F548F00B9D7EABC271BC380D3B
-:10D91000F57D0A4F660F707D562D27A48668ED149D
-:10D92000759D6D063D7639C011E1CBE0D80E70448F
-:10D93000F81673785632BB89DB3D31AADD93BF7A86
-:10D94000EAF444D4A7515E2D4CB7E0FEBC3C93E909
-:10D95000DB3DE82755233F29CF2F5DC6F673551FC2
-:10D96000DF95FE5625E8B5EB534D2827D727EE70F7
-:10D970006DC07C8C9BEDA7DE7617C59FD9C5FDD504
-:10D980009462D3E87AED9C6F969A09FABF9727D9EB
-:10D99000DCE007B3BB664DC47A867109B98568EDD2
-:10D9A0003FF271AD4EEF20D26CDD3A43F32FB2B0AF
-:10D9B0007E0422403F0905161DFEAC4493CF84F936
-:10D9C0005AC278CC84F5723C19F41CA39F421DCF37
-:10D9D0003951BFDF2CCD67EDBBD23723DE8DF0751B
-:10D9E00054E8E97739A78B96A4F5C887C6FAC6FE2E
-:10D9F00049498CCEFE5BEE3ABD9F44B5A7D57A600F
-:10DA0000473B23D437DAD1E7C25E77E278FAFD2EBE
-:10DA100082BDEECED6F893547887F0A0FA17B91DE0
-:10DA2000A6FAADD5FE24C2FAC33CFAB7BD28FF1E44
-:10DA30008875A01D9963B3F84016E6D079001DB72C
-:10DA4000FC21D6B788E657C54EEA8EA3F99C8DA275
-:10DA50008CE5360F9EDB74AD99D03F48C77D48A852
-:10DA6000199FADF1C36D8CFF6D2AD307A48F822E51
-:10DA7000607201ED5CEFAA510105F4F17CE2DE4435
-:10DA8000C00A66E52A3D116D5EEC99FF3C9BEDFBFB
-:10DA9000A9D792F91D11F0DF9CCDF6D1B01CF7C4C7
-:10DAA000A0BCE6723C87C36B537B758C568E6BBEF5
-:10DAB000C745A2AB7325BF5B407E0F8671F62BB8BE
-:10DAC0006F17112EBF9F22BF46F93D27B36621D0A5
-:10DAD0009BD978DE2705517E0F939545501E07F69A
-:10DAE0001EE0E5068A9708EB7881E3EDD78A177583
-:10DAF0005FDDD4FE2CC34B818A97952492FDFB2BCE
-:10DB0000C04B27C0BDC7BE4A82780EDB3D50790EA0
-:10DB1000F8F11959791ED2107EAE8ACC379FFEC219
-:10DB2000F87994DBADAB397EDAB97F7C25C74F1B22
-:10DB3000DFAF9773FCB4F2FD7A09E027EAECF966EF
-:10DB400050A31E3FFD2A630CF8D0E327AE588F1F69
-:10DB5000BB5B8F9F58D710033EF4F889CB91991E79
-:10DB600099AAC7530FBE3983BDE2807E22F83706DB
-:10DB7000D6044AE18CABFFD48E2E3374E2692F8534
-:10DB8000545DEFC306BB544DE372983C4C2D8F8C13
-:10DB9000F7EF38DEFF98A5FCB78E8F2F8ECCC7A687
-:10DBA0001C56FF13591172B4747559E4FA565EFF8E
-:10DBB000E020252A47D33FFDB94F3C8DBD605C7FF7
-:10DBC000ACA0C4E5E03AE4AD418AFB8D0BD939E461
-:10DBD000C668B903CEF3BD0B6DEE4D32F6E4B182EB
-:10DBE0007DC4FB21DE38EC37830F33C8B6E75B38E2
-:10DBF000F7CB9C31B0FFCDB43C7341EAD11A9AE621
-:10DC0000E464239CB26ADD3B00CEA2636A7F767E29
-:10DC10003CCDF9C9504A6AFE7EC28F60703B13FA50
-:10DC2000742E47E520EA817422BE4D944EA324222F
-:10DC3000D91360BD0AAECB0C7AAC08EB6DC77C0C77
-:10DC4000E9C0D44602ECFC9ADBA3A37332115E4E0A
-:10DC5000E2447B3581B83155F9D89A48A4A491D8CB
-:10DC60007F4BD448821BFE0560AFDA06AE5B0E36F2
-:10DC70008D42A130065905E121DCB71BD74F5C442A
-:10DC800066FEB6BB9C189FF01A5DDFD0BEAFAFAF8B
-:10DC9000F5BE8976149238421AAD2CBD23C6B11E4A
-:10DCA000D26FA2337CE0B43A3FBBE63780576F199E
-:10DCB00041FDC3FB41ACAF19273BFF3C661FF4B9E4
-:10DCC0009F2BCF513F379CA37E6A813FCED4CFDDBF
-:10DCD000F0EB5838C7F4D4C1B82DF16350EF54536A
-:10DCE000235CFD2E653EF42B590F647CDC2FACB712
-:10DCF000D9DE13506F6B11FC04FC94DE0F05D4AF1A
-:10DD00004801C3934D26AECCE1E17E6CEEF98398D9
-:10DD1000BF8BF97B16BE7FC760D0BF1F889D148C58
-:10DD2000A3ED37ECA37A1EC4D194BBDFADA5F49468
-:10DD3000D4CFE25E4FE9A71FB793A3568CD95B4BB4
-:10DD40007FFD6C30932F5B9AF6385BA840B24BEEA8
-:10DD50004B46D276367E7E4BC48941D01BED632480
-:10DD600019CE38F2457F25CC97349808F0C5437515
-:10DD7000FAF3DC2579F9D89F9A1FC0CF734991D463
-:10DD80001D8AB3A17AFCEA1C1E57E3200ED00BA516
-:10DD90001F94B848710F6AAACEAF2891EE5B71E06C
-:10DDA00017A49C42D3A2363F067F94B9FD56D06398
-:10DDB000D7F888D742E1F4D874CF6CE8AFADD81368
-:10DDC0000B7AF99A83D5970DA3F30E04253780E0DB
-:10DDD000A5C10938CF8022AE88A5DFB7BE6772C261
-:10DDE000FA36F0F66D1E01F9FFA169C4E7A5F0D877
-:10DDF00050B7C32A82DE1B30915CD473A9C135862B
-:10DE0000BB4E64F0D732BEBF6370127EEC0C2C8820
-:10DE100007B8AC8ABD30A0D0FEAB2A99DF79823832
-:10DE20007017F41B68B3207E9278FC9140AA507F53
-:10DE30004E98A6D197E9FF761E0715B88D60DC5382
-:10DE4000DC681BC6013C1764E7460F5532BFB3833D
-:10DE5000F871FC09E2B66813FDDE592939819EE2AA
-:10DE60000CFAB90DFAA324D7F920EBCF3182F5676C
-:10DE700037C44159D57939E9BC28FE44BB8478764A
-:10DE800056EAE3A71C867636C3787B01CF20970637
-:10DE9000923CC0F349CF6F471DC052B71C297EA2E8
-:10DEA000AD89042A34F116B65EFC875FE431BAB559
-:10DEB000A4EDB4C2BC4E7ADE4A0477D71BDFEFFE76
-:10DEC000F81E487FF88FCE06BAAEFFFCF6D0C6A784
-:10DED000018E8D77EF473AE476550A4C81CE67572D
-:10DEE0009505E1385A61FE0152D4B5D35C84E578DA
-:10DEF000AEB5624734960F2826BE680ACF019292CB
-:10DF00007613F06B40742F94A113C5963686B0A398
-:10DF10002A9A5F713D251C2A1F92A629229C1F8CDC
-:10DF200017DF20768AEF358A20B3F8376117F05370
-:10DF30007A85807658FA414F34D0C3C9C9268C7F80
-:10DF4000595875E525B9B4FF474A25F43754569416
-:10DF50005E0DE5030E327A71DCC6F047E1E4AFA056
-:10DF6000FC907D90F9138A48D0EDA7E503DCC49CB2
-:10DF700008FBC7340A60985F1BC70FF70F1415051D
-:10DF8000BC0054BB5B8F47A7018F46BC5A73391E38
-:10DF9000F3493EB3EB98FE58C5EBACA91885F6EBF8
-:10DFA0004332F19A87F7C4D77EAA3F2A54FF0B5019
-:10DFB000FD11D2BF53FD11D24EAA3F426A574A2FDC
-:10DFC0002BA2F30D24D17E81FF268E5E04E7038F02
-:10DFD0008CBBF9CE7FD174343F67A3949F5046E148
-:10DFE0005A0D5CCCF2AB15BA671E281275F915896B
-:10DFF000927A8EE7853DD59E66E2E73CE5F7427969
-:10E000005BAAC4CFF5583EBB80E8F29D134DBAFC25
-:10E01000053B34FD0F04FC4461BE20F7B9D55E4DCD
-:10E02000F9B23C9AA7E57BB93E5735CFE4591F8139
-:10E030007EE7E432BD4AFA8178058AAF2F7308DAA9
-:10E04000E9A24941F94DF224795384F83442A81CDD
-:10E05000D4DAD73954AE6AFC23FBF3B85FDD53CA78
-:10E06000FC6C24FCF3DD181E6745E07B5B00F48844
-:10E07000256F5FEFF693DEE5AE39553AAAA5934BCF
-:10E08000543AC825B930FE97A4646F29D059FB28AB
-:10E0900009E8A188F301E17A1CAA8A947E5E3871AE
-:10E0A000FFEB8A0C765AABB32517E37EAEC8D5F8E2
-:10E0B0001B1627CD1A05FB991AF7434885F313BAA7
-:10E0C0002EC17BA509F4B6DEF514897CA2814757E1
-:10E0D000D58438D8076C5C8E1BEB2F6EDAFA168C61
-:10E0E000BFB4A903535BA207858C55F2A2FFC6EF0C
-:10E0F000AAA985795907D2728D1CB624D2763A3BEB
-:10E100006020D3BB543C3889491BA7BAA66D644C28
-:10E110001405461BDD2F403EAF095447C3386DEE52
-:10E1200091A7F55F9D894F36541C2089148ECFBF6F
-:10E130003DE9F5C934DD07FC46F7C1E738DFA41730
-:10E140003FF3CEAD3A7E399C5066D3F2CBE1D54A4F
-:10E150008E965F58BE777E29B917CA3B53255D3E20
-:10E160001DF84593DF10E217960FF30BEDBF84CA3D
-:10E1700085372D985F9D7B78B557537E67DE613D6F
-:10E18000BF8C173DEB23E801815C26EFCF35BFDC68
-:10E19000C7F7913EF3CB3FCE8E5F9ECEE57ACECFD2
-:10E1A000E7971773937E397EF1F4915F3C3DF9E573
-:10E1B000EF3F855FDA9C7E8C076C9B6CAAF445C0B0
-:10E1C0007703978FAADF7B34F753944F53AE1E0625
-:10E1D000FA2C8F5B53E369DAA6B1FD7B61D504DCD1
-:10E1E0002F37EC63FBA5BA3FF3A35DCA4FCC8F3149
-:10E1F0003AC0F6CDA46201DB4F52049F4C7F6DA361
-:10E200002A413FD8AF4B04D22EC352E757E50A61EB
-:10E21000BD898E877AD3236E16374B0E327DC74A5F
-:10E22000FF037ABABCD8ACDB57538CFA9721AF9E68
-:10E2300063AAE7978F405C0285C7D72ADD18F65B93
-:10E24000150E6B0E96A11EF2D540CB69CFABDAF856
-:10E250007A43FA5491A734923F6C7A1E8B93B8DDBF
-:10E26000A54879A3613FBE11F75D753F37EECB9DA1
-:10E270001507F472C65BD84F2767BC85F7EAE40C34
-:10E28000CFF72A6748119687F6659E0FEDCB3C1FA6
-:10E29000DA97793E2467A0FF92F0BE3C6873E1BD37
-:10E2A0005A393307F27DD897AFCBFB65E4CC5FCE0C
-:10E2B00056CE9CE5BE5C9277CEE4CC84BC5F50CE5B
-:10E2C00054819C893BB39CA9023953A09333D7E670
-:10E2D000FD043963AFEBF2C2F9FD35BDD0BDC8F521
-:10E2E000A5D939CA0CE89F4CEC5BDCB691AEBAAA52
-:10E2F000362F4E067A71333BAFB7F6F6C6BFBCD5A4
-:10E30000A2898BB64B0176BFA2F179FC7E6DDD3E12
-:10E31000F4979D69BED3F308A6C67DB4AB6AB71562
-:10E32000E9D66DC233F19F3A8FB6C98C2FDFDCF48A
-:10E3300002EAB70F80DF2FA9A79EABE2B5AFFA8F35
-:10E3400071DC865C19D7611CFF4C744BE9F421A089
-:10E35000D393036F1B0A769E68BF2F16E0F52BD868
-:10E360000F3B7E0A9D0672193EFBB0EE977EC97583
-:10E37000FF0CFEDC0BF33ADB755F97D7E775BFF355
-:10E380004BAEFB67D80B9FFF9475CFC9256ADC0D98
-:10E39000DE9771C22F944F567F9FF721F82F56FFBB
-:10E3A00030E4195867FBB7D675E0BF20DFFD283A87
-:10E3B000B5F7A708BB3763E7EDEC1E761FC659A972
-:10E3C000B91F45C2F7A5703DE8DF0895EF8D745F72
-:10E3D000EE974E411FF9C87C9A720BF3DB19BFBF51
-:10E3E0009323B07B6C425534C4C5774DDE81F10672
-:10E3F0006D9347E2B995514F51DB753629E84F6A65
-:10E400006BF260BAB2A932007E93E70F7C20403CE9
-:10E4100058D1813ADCDF568CB97400C6F18D2B8A55
-:10E4200081FC4A839EE2E07ACA90C16FEBF48A8E47
-:10E430003FD5ADF69684FD50F784F417DA4ED6D862
-:10E4400049340FE410B29320AFB393E6A15FA11358
-:10E45000F4175AFFBCC1F356471A678589D482FE68
-:10E46000B2A2CE5419497F793727B25F81E6F1DC39
-:10E470002DDA6EF52DCA047D86D468FD6A67D25FF9
-:10E48000FE34F82CFD0A6769274D1E7C6EF4971048
-:10E49000DF72BD253E5FB91E5CB2E74A4E0CE8A3B1
-:10E4A0009C18D0534EDC3AF827C8897773587CB54E
-:10E4B0004A5F1B6437FA93DB2A09FA1FDB028BFAE7
-:10E4C00015D2FC73752622D0FCED6F32BFF09A6234
-:10E4D000E2837BB46B0612CC07DC8C0E2688B6DF99
-:10E4E000801FBCB382DA4F32F8EDAEA802D8AE8AF4
-:10E4F0009D747734A597AA628980DD34412CC1715F
-:10E50000020A8B0FADB291DF44815D354E228BCE76
-:10E51000C26F6D170B04CA91943FE578E0DBDEFC17
-:10E52000D146FF3311DF70E33D27831FFA6CFDCF27
-:10E530006B07FF6CFF33F2DF179BEBAA311EFC0C5D
-:10E54000F478DD601933C67DCAC8C72A3DF5467F19
-:10E5500036D0934669F2FC1EEEBBFC7CD9067AD21B
-:10E56000A8305D74558D898B147FA5A6B18D2FBE03
-:10E57000A5BD8F172B75607FB18DDBF0FB7D10374C
-:10E5800000EB93DC284F1F2BA37238C2FCB637CDAB
-:10E590003F08F2735B5323A61749DD6202ADFF52B9
-:10E5A00093F720C06D6B532BA6CF37B5637967D334
-:10E5B0008398DED3E4C37445D3164CEF6EEAC0F4FF
-:10E5C000B12C364E89E4C77E2E3A45FBD7D0D1B860
-:10E5D0006E3A8E06DF171CF6EACAC7065B75E5E7DA
-:10E5E0001D6AD7E547071ED4D57796F874E5B3734F
-:10E5F0006A3E01BE74146DD17DB71574E8DAF5D5A5
-:10E600002E38D7F532AC4FC1313989877B1770FF6F
-:10E610000AEE0D513E4E69A4E295E61FB5733F47E1
-:10E62000073B274F25A11FA44BBC7245EB77D95957
-:10E630001C64731A6BDFFC3B967F349D9D1FA97190
-:10E640009AA23544D744480E9FE73F6AE7F7947291
-:10E65000585C6446810F3C12240302D4E03CA48839
-:10E660009D93A9E7DECDDCEFF0A8996C15A83ED903
-:10E670002CB1F9372BC4B790D66B2E60F9872A8856
-:10E68000CF04F357A8144FD69C7337EEFE56280CD0
-:10E690009F9793210A9ED788FC9C3D74EE1DFD4FE9
-:10E6A00082E7FA1C5E8B623FC738DAF8C66E01F863
-:10E6B0002BA5B1BB0BE6F7E8EF2D72247BA8EBF797
-:10E6C0005FA701DFACFDDDD769C0EC6B43F133DD43
-:10E6D000D1DAF8990C0E97B58D5918BFB0B6D6A1FE
-:10E6E000BB07A729C77886AF6AF9FB044442BB6819
-:10E6F00080330C579F1A3F2242DC1D5D7F76F8FE67
-:10E70000E9CF8DAF59DBB880C5D70C243CBE66126B
-:10E71000DA932A1ED6423ABCE7BDDE5F3ABEE68CEB
-:10E7200071358638071DFD42DE6BA46F19F112C5E5
-:10E73000E95BB88BC545A419E8468DBB50E9528DFD
-:10E74000CF50E335D4F80D0B8FEBA0C3F2B8E6C879
-:10E75000F465D9415C70EF4D34C5B8D7679E398EEA
-:10E7600060812B8B6F0EF387B37E59FCC057839566
-:10E770005B5C49E17E07B8945B5DA3C37935DD003E
-:10E78000BF8EA55DB88315A0AFE6172BCD709F2F68
-:10E79000A188E03D9DA26201D3FC832CBFD82562F5
-:10E7A000BB7F77317F939ABF5C515E85F671867629
-:10E7B0009787DA99B1DE932EA6E73DE992D8BC7926
-:10E7C0001CF2244EDF4BC78A2C3EBA426072030E05
-:10E7D00054C7F0FD90C2EF72E29C92A3F1BB5EC100
-:10E7E000B1B5B289C5F7A9F1D07F7F53C478685B12
-:10E7F000B1A71CEE9E8D0E04FC70BE5EB491381362
-:10E8000064985F50017E5C987EFF0E888778EE12D8
-:10E8100076667BF941A62F5C517C33BE37E2F84E19
-:10E82000447FACB3C4EEF6C14013CD6CFF57E3A1F7
-:10E830008BF5FA4295415FB8FC0CEF7F24906E2F68
-:10E84000EC935B5C067F2C7F07A437F91D7E078461
-:10E85000C98722DEA7ADD8190DFEEBFC8326BCEEDE
-:10E86000296E5444BC1FDBC6E23C9E0B784E7B1FD6
-:10E87000753F876380CB89BFF338C94E2E27DEE50D
-:10E8800072E210C8099ABEC5E3240FF23849E37D4D
-:10E8900089B6A6CA035A7DC798DA05BF07E3A04622
-:10E8A0004804EFDFF5F2DE87DD4DFBD1C5312E44A4
-:10E8B000FAD9197F7F29EAA31E13EA95F7952869EB
-:10E8C00091ECBBFBA6949D36FE7065D3D4032DA7B7
-:10E8D00099A7C3A2B767D4F45B977A3FAE1DEF5BED
-:10E8E000A42826027155695619EFFFADEC52CFF7F7
-:10E8F000ADBE68585F9D8DFC5313A7D23E2DE081BD
-:10E90000F2154512DECF51FB8D2BA6F3D1FAF92B70
-:10E910003FC278E995E382A9A0CFDC37F693A9B985
-:10E92000102FB24F2440063DE6ED62FE76755D295C
-:10E93000D27C21529C7A6FEBFA90B757E3C58DF0E9
-:10E94000EF55EF808880D3DFB7B2E427F58CDFEB9B
-:10E95000C33CD16EFD76CBFCC970BFB7AFEF5FC4CF
-:10E96000723A4C9B49A2819FCE448F3673379E1BCF
-:10E97000DD3333F2B951763EC3F73D25FBD9FB2297
-:10E980000591E7D1935ED97C5648B47FDA6F7B4915
-:10E99000E4FEAFC81754BA7E07E4557BA509F50A13
-:10E9A0003B159F10176F1F47F520F0E328EC9DA241
-:10E9B0002F4BD8F98C515EF418BF84C257636F1B7C
-:10E9C000E55071BE4D671F9F1C3839CE1F89AE7848
-:10E9D000AAC25195433DE148F09CA91DE088708A88
-:10E9E000CCD7617C2D540FD16ACE705F6F5224FA60
-:10E9F000E90D0F467A5831D313E70778BDFA2D9108
-:10EA0000C1B955A2E7C7DEE06784D7F5BF30BC8C3B
-:10EA1000E517E773FF481FD7D9E77A542F726AF4D6
-:10EA200062B8142DD1FC389EBFC22B041FA2724BBA
-:10EA3000D8F637D47BC6F1F40A48E9FEB84DF0FFAA
-:10EA4000F31FB4718920A703D2AA5F1A0C1E32B239
-:10EA50004498AFD37F960BEE432FA35FA8BB1FD480
-:10EA60001B4F6A2486641FAEEB6F42B01936AC2B85
-:10EA700089B218D27AD26E8176F59D7F3B04E3D4B9
-:10EA80007746FB45704E6E351FD3FA8D666BEF8F60
-:10EA900064C22B1A1D964C3A9FB95BF4E7A4752407
-:10EAA00080FDCDEBD07F37DE1F11440A18789C2003
-:10EAB00014FF5A82F1BD249A954B439C5CCE75E7B6
-:10EAC00069DF33ABE5F0AAB5DAFCF0BE10F1E9E797
-:10EAD000297139B48BCA31EB48BC0FF3A77CBAEE6D
-:10EAE000234EABD744F5E5E4849A7A80C78D44B6CB
-:10EAF000B094E90DEABA8893E173866DB205E03B04
-:10EB0000A3D5B80EC502F3B9A9FDF4EB53F1FEFF8E
-:10EB1000F209C2BD355FC6745ECCC43D0A14170548
-:10EB200032B4EF4134C0FE00FC35BF9F8E7FDF5012
-:10EB3000E99128625FD6DF13AE39E82753E1DA3B6B
-:10EB40009DEAFD642F44B37953F8ED0539A0C28FD7
-:10EB5000483585D0AFBA9E7F8D0E6CF6C3B9AA9D9D
-:10EB6000BD03F54142CD9B00EFF443C14F043A751C
-:10EB70006293F3609D9F6F3DF29698155E1F21C1D1
-:10EB8000FB213EBA76ABE85C0EEBD9FAEA21A0F79E
-:10EB9000DED6A5C6C7527A40B8D1797D14695E9F8A
-:10EBA000FD96DC007AC978B140E747798EEF276B94
-:10EBB0000A3C87617E4507063A60BEE6AC8EDDFD05
-:10EBC000E93CBA6F1730AE36512415003F351EE1CF
-:10EBD000844D423B3B31D62B3A68BEFB46E25E0F8A
-:10EBE000D370CF7703A988E905EEE5946E926F178D
-:10EBF0003D204FDEBF6D46FC0C9A26DB67C667D30F
-:10EC0000F4A228E28DA6FD250B264F073AA1A6C740
-:10EC10004FA1F3BC2E8ACE93E6337F1BEBCFA6FC2D
-:10EC2000F6570BB102BD26C6D6AC1A0FE3C48B381B
-:10EC30009FA3544F94A81C2BBDFACB51563A5EFFAC
-:10EC4000EF6C23613E698DE5E49F1494FBF3995FBB
-:10EC5000F1B327BF1905F7C0C51F6D6EBC67CEE9BC
-:10EC60002F319BC1C388EFAD9CAEDE8B61F64E7D2C
-:10EC7000926509F8DB3FE7F60F515C682FDCC6EDC3
-:10EC800085F762981DF45E9EEA5FF22769F5DBFA6C
-:10EC90006825EE2A301EA89E04F1CE5F3A95B8781A
-:10ECA000A8473CC8B7B771BBF973422A81CE6F5BE6
-:10ECB000569E9240DB2735333818E7377808DB9FBC
-:10ECC000EB4E5182D6F8CFEA24BF05F486BA53162C
-:10ECD000DDF7F7A91EEDD5DC57BFEEF0C1F130BF6F
-:10ECE000EB497031D4BFFEB658E6B8E7FCDAC9E7A5
-:10ECF000D11B5CEAE325225178D40BC473BA7A2F76
-:10ED0000FF204684EFA421AC3CA93CF2FAC60F6177
-:10ED10007A5FF9D2890F009DD507CCA8CBDFF662C8
-:10ED200069CAE9F4E7FA5317109FC6FF572F051178
-:10ED30001EF5A72EC4EFE54B8F5980EEA11F997EDB
-:10ED4000BF2D5A49017F6D6F70DECAF5A0FA53F1ED
-:10ED5000C4DB4FFB9DF177B8FF442CFF3387DB9F6B
-:10ED6000F7982A23C5772DE0EB1E92247940EF1AFD
-:10ED7000EA27CABA08E3AAF5921322EBC5EABC3A1D
-:10ED8000CB82D7C3BCCFAB204AA4F1667238AAF3BA
-:10ED9000ED4C08CEF2207D76E7C13B13A1BCB33B1E
-:10EDA00043FB8EC4235C1E745E1ACC80FE3FBF24DE
-:10EDB000F2BD1D15CF63B8BEFCB7849A4E901FD329
-:10EDC000AEA2194A1F29D3FC26763F85F15B6FF866
-:10EDD0000EC35924BE51A783B305CBD5FE8EECE7F5
-:10EDE000FC48ED708853BF91CBFF1B37CEC5B827C9
-:10EDF000554E1D795044397504F7169AFA04D45FBC
-:10EE0000A7D7509D8ACA95599BCA77C37670632A43
-:10EE1000211726B0EF7741DA62D6F9FBD5F1661CEF
-:10EE2000F2A09E35B34DBFCFD592B62F403F38B23A
-:10EE30009FC903CADF1690C7B3EED3F753BBF1B235
-:10EE40004F617EB506BB3C99EFCF463DEFA121DC7B
-:10EE5000BF3F868C391BBBBC9E92C510DC173C2281
-:10EE6000CC63B4A47F674B4DE30A199D2CD874D2B0
-:10EE7000E2907BEFF728952339B4DF63D41E87F443
-:10EE8000C521CA934368BBE3FB185C5E1B52F30CBD
-:10EE90008C777C1F5BFF89BA13B3E09D183295E92C
-:10EEA0000D5170F980FE1A75ADD5D74CD7BB948A39
-:10EEB000A968B81714C5F411550F13C55B45072D84
-:10EEC0001FFB5F33E3619D898F5F5C09FD253D1E5C
-:10EED000AB00DC96972A2340DE2FAFB2B9E1BECA61
-:10EEE0003A4A86C5B4BD95F603FB89EFCF6377C078
-:10EEF00071644EC7AA3278F7C5B9ADCB3F80AEABCF
-:10EF0000D5C4DEC968BD90B89B4978BC866D55CF25
-:10EF1000C0BC3226D3FD41807BF4CA08A7A67FC2BD
-:10EF2000F5AB7A8E93E3AF0CBEE702B897B04744D7
-:10EF3000F5F1445D16DAF54308A32735FE1EC60633
-:10EF40003D5285DF31BA5F114D9CDA900EC16FA63C
-:10EF5000EB9AD7F90CBEC751B7C89F7C2DECB78F81
-:10EF6000496C1FE5F34BFC6B5A99EC08EFBFD70ACD
-:10EF70004ED423553DF96AA2FE14A0BF702AE78340
-:10EF8000ABB97E7C6D2C83F374E2CE8076D7588942
-:10EF9000C34461766D79C7E8F9B0EFCE35C7837E9B
-:10EFA000036B8984773535EA412A1FD66FB67BC15A
-:10EFB000EFFAB9D09D079D1C35333EEB7E25CAB7CD
-:10EFC0003E33427F7CFFAACFE37A5D0E51E0FE40E4
-:10EFD000FDF6C1781F2C2A86E27124CA3F2BE0750A
-:10EFE00017ECFF74DDB35F8EF6E3BD30F5BD32275D
-:10EFF000F1DAE9380DDB53D6839E9198AD8C5840F9
-:10F00000FBFBDC1CCC407941E59B40F7D6D4A14BFF
-:10F01000A64894AFEAFB53BD8BE6C73F7EEF148949
-:10F02000D2637D56709689E6E73DFE04CB0F097EDC
-:10F0300002F93B1E7F81D51F199C25D2FCEAC777B8
-:10F04000B17238C3A684B5F6F137A680FD7F349E31
-:10F05000E90FC41DBC1EE8A7FEA5C1A6E59AF5DE12
-:10F060003D94C9D1A3D1ACDED14C724335C0DB1580
-:10F07000CCABD69CCB350C0DF96F589C165FA7DA3C
-:10F080008EA446EE7F306F37BB9CD5BB2896B44626
-:10F09000B3FB755ED0C7766E1B8C70B10D4DE0F082
-:10F0A000A2FD1485FB51E1A8F6A78E3B07F67590EB
-:10F0B000FB662AF73572A66828C31B1DA705C7295A
-:10F0C0005046C03B56F5D5034700DE28BE248E2FA0
-:10F0D000C98A8FABAD63F3A3FDC617E23E330AFCCA
-:10F0E000CA3BBFA3F533C3F336D287C2C799DDCC81
-:10F0F000EEF777C767231D5D14CBF4455244E14713
-:10F10000E5D9EAA16CFFB97B683C5B5F080F290277
-:10F11000F6DFCCE13790D53FDBF556FF42EBD5E08B
-:10F120004901FFCACEADF98827753D84ACD2F5738D
-:10F1300074A1A15D31653C98474236B65B1A4DAC6F
-:10F14000F89DAC0FB5CBA4ED2E2AEF1E05FC308F39
-:10F15000EBC3C47B21C635D4716931AF356001BFC3
-:10F16000F4BC0EE6272739747D401FD5138BF8FABF
-:10F170009C7C7D4EB63E9F8E3EC9C1EE8CC9F69EEC
-:10F18000741B827BA8BF8291BC3F1D3F47EA0FF8EA
-:10F19000A2377CB40C65FBD439C3873A4F033C4398
-:10F1A0007036CC4F8527F031B62BD0F3933ACF3B56
-:10F1B0007AE3E7CC9F385E296B37EF77148FA0FF97
-:10F1C000C87A7A9ED799699A5E106ED7DAB1D00361
-:10F1D000723E5690991FBCB3CA0BFB5FC3B652F484
-:10F1E00053CD7BE1C9E7BDB4FD9CA7D73820B8EA71
-:10F1F00088D49E0C7A70DDA6C50E781FEEB0E4753B
-:10F2000080FC3CE21323FA07FFC1F1A0EA5DF57C24
-:10F21000BF39FAE7BB27013CBEDE64C67B860D5BC7
-:10F22000A2FC51E837998DFA18CD7FC8F24BBF0088
-:10F230003BB661AB5E7F9AF3A735C9E80F23DE01C9
-:10F24000263C04F30F80C3B0FA8D663C4FA93F28DB
-:10F25000BAE930A481742F81F919DBC33C4E51BC4B
-:10F2600037748837427C9FB19C4A12D4C71A3AEF50
-:10F27000463DADA1F3924F41AF6830C453D4F6A2DE
-:10F2800087BD3194EB61FC9D74153EC49784FA4DA3
-:10F29000F3630F147E48E7756CE3EB0EA140BB6F80
-:10F2A0002E423C9DE898B1F625B9F7FDF573D00FD5
-:10F2B000A2B4ED187EE5AD023B18DAC6D23AB3DF50
-:10F2C00001FE81BA756637DD8149DD931B36FF117A
-:10F2D000ECCB77A2DC106A3AF7C95D6F9D4FF373F0
-:10F2E0009F31274E64D3B7C139B78A2788D9003DEB
-:10F2F00045C5CB9CBFECB2C8C3D877D07B55FCCCFE
-:10F300007DA6CB02F7FC8C702CEFE8B2603CAC1110
-:10F310004F1D1F4E0015A4F9B16F2C40DF47B60BEF
-:10F32000F8EEBDB17DEDBA5D0EA0438013D8A12AE1
-:10F33000BE42F8EB8137FFA4978AB01EFA43CE8411
-:10F34000BF270047A391CE9F7A09FC28EF46B90159
-:10F350000EB54FDDEA80F57C2ACD67F4FEC8E26485
-:10F36000782FAFD6EC4D7662CABED73E7A3BD2E15B
-:10F37000CDFB6E4F66EF482869EC1D4D6F1AACF35C
-:10F38000A687A7E03A67911AA4C3DA47987FE32BD0
-:10F3900089543E13815FA614B07DE4D3F551101C4F
-:10F3A000443E8573043837D92FE2BDFB1EEF22910E
-:10F3B0000598FF8AFB17F20B42EF1F5A41BF6BE023
-:10F3C000B51A362E0D009E8EA62B29E0B7A570F03B
-:10F3D00072B809F0EEBBB86F7C0AC31391E13C042C
-:10F3E000DB517DBC1CBE43FD8059892ED4B5E3EFB3
-:10F3F000DBB0F155FF069D770C9CA77F9ACCE2F21B
-:10F400008CEB6BE1EBA33F01A2A5B3DEF87FE33207
-:10F41000A4AF2F0F32FEA9F755556279C0EC4F818A
-:10F42000725FD76401E54394EEFC3C441F1BCD9C06
-:10F43000BFF5E5749E92A085EF7601DFD354E965B0
-:10F44000D67D51BAF3FA30FDE8DF8B52F955B5B3EA
-:10F450006EE6F2C0B86EA37CF01418FE8EC2C349EB
-:10F460007DF27FD7997D9BFF08FC4CF9D72B033F9A
-:10F470009BD13FF0D913AFBE750DA5FBCF3A543EDB
-:10F48000D6CB5B231FD73E3B9A44E2E3CF6C6E1290
-:10F49000918FE9F7887C6C63F7A6FF7FC9DB9B7BC4
-:10F4A00091B7FF56A097B75F9182B80B08EC337302
-:10F4B000F1BD57237C55BBD72847130AE4887294C3
-:10F4C000FE1C241A78AA7054E973CEE3F3709C10E2
-:10F4D0001DAB74AAD271884E8DEBD6C3D3587E2152
-:10F4E000CC5D1307615E44ED18D0735F117DEBE9CD
-:10F4F000D48ED3B92CA1F03FFE4426C61B2DE67650
-:10F50000C07167B703E2C71673BBA31BFC9271E11E
-:10F51000EFDDD14C5F3AEEE976C46BF4A60FB78904
-:10F520000ED0F3823E5219C99F442536CE23487A25
-:10F530002B67E762C7B93FF438F7778E176D198DDF
-:10F54000E0076E677FF764E6C2AB1C702E707C5BD1
-:10F55000F63DC07F37BD26B2773DBD8A04711233B8
-:10F560001808C861E2BDBF84AE73C6B6B918DF60C3
-:10F57000F4A3CCB26DC4F385AFC85D981AFD2773B0
-:10F58000C0CF02F4FEB0E1FBB6CB90BEE618E8AB0C
-:10F5900006E82BAD277DED56F9750419A1BD7FB6A0
-:10F5A00080CBBDF162C13DA0CF1CA7763EC61288BC
-:10F5B000057B61DFFD0AEC7E600C6F12D2EDDC9AF8
-:10F5C000C316FE8E33D2BB4A87467BDF981E7BEE86
-:10F5D000FD3177D22A75CFFFA3F0219A1E7BFE9DC5
-:10F5E000BC9721FFC2DB19FF203DEB976FFF16EDA3
-:10F5F0009BE3DBA3703EC7B7FF2DE34EC8BF148566
-:10F60000E7AFC71745615C9477BBDD07F7F98EA7B5
-:10F6100033BF5DF32BDF1462FC0569617A48818595
-:10F62000A5DBFEFB03889F3EB12D4A063F45C3F68E
-:10F6300058B4DB1B5E8AC6B897E3AF7C3346EB67F2
-:10F64000FAB9EBA9E7E7FCC7ED64EAB340CFF1CC28
-:10F65000BE6B7879EC0688979BD7D96581F381F2E8
-:10F66000BF7E5F0872E9F8B34CFFA0F6FCA3F0D2AE
-:10F67000E1F70575F79B29BC3F071D91DAE17F187B
-:10F68000F6E4956087F7840B83C3710A07581785E2
-:10F690004B2DC8D3DEE09138ECD70A8F2FD0BEA80F
-:10F6A000DB761EF251182E82C2BEDB7D5601D7CF0B
-:10F6B000BE6FFFA610F4A9CF3A16A25E70A6758F92
-:10F6C000FA3FB76EC1DF977557C3BA937E8DEB666D
-:10F6D000F47F88EF57463EE849E72FFC16F34FD9F1
-:10F6E000DD38DF3EF2FF82FF6B787F56C073F9335F
-:10F6F000E17DD5FF5ABCBFC6F16E77427CD9F15788
-:10F70000BECF209AF59F69DD1DFF4BD71DD28F44D8
-:10F710008F159EB86F23FE00DC5F5FDC8B9EF2FED0
-:10F7200030D52FC1EC10357E474C9C837A8698B833
-:10F730001CF586C584BD83EC954DFC3D3616F7DD82
-:10F740003AD0ED43BFA8E4A95D47F3E64175EEE585
-:10F75000D883DE3E13932756829FA579219D17ED0E
-:10F76000A739C9E46C96E19976933FAA10D30F218B
-:10F770005D9A7CE91E1857B2E9DFABB519EC8D989C
-:10F780001C8B3EAE98EC70C27975B45B82B7DCA975
-:10F790002AAB7FDFF6E5612CFE2386F8306EF36C32
-:10F7A000E1642FD4DB6B463819E1A3C2AD079CB8E6
-:10F7B0003DAABEC72F252E0F001F4A84DA936C3D49
-:10F7C0006887C2DF9182F31A73DC2CF772769E226F
-:10F7D00087DEF18738086E6F86DE99954D6897AAA7
-:10F7E00070D6F487EB37C2F96CE1ABE2259A54236B
-:10F7F0009EA307DADC3E3AFFC53283FB620A7778C4
-:10F800005F5C85AF0A37231E8240A34961F88753A6
-:10F810007DBC8EB78CB8E09C65BC5812F482BE5C8F
-:10F820001C8BFAF23181F8056ABF1D2B4D2E03BBEC
-:10F83000E258BA4582745C375D9366BE179DB28606
-:10F84000FE861EE44B49BC2E7F2C3D0FDB975BD31D
-:10F8500074EDF642DC36B5DB8FA5155BF13CD4992F
-:10F86000A96B3729D6B11ECAF7421C378E3F01ED6E
-:10F870009B8B53F375FD4CFAE8D8C337D2742BB782
-:10F88000ABBBC799D11F7FECB5696500C74BE411CD
-:10F89000BAFAFB883309888AAEAF02D677996BAC87
-:10F8A0006EDCBA0F77E4811FE237EE52DDF7CB8BC7
-:10F8B0002FD1F5E3B106FD40DE554A95EE7B5DE3C1
-:10F8C000D744EA47C8058DDF11691455DFFD1DBA1D
-:10F8D0007E46EDD9AAABEF0E38CB41651C79C8FD49
-:10F8E0002AA46A3CBBA59FD56BA2E9B00FCB4438D4
-:10F8F000F71CFD714D33B8A12F38465C4007E791E6
-:10F90000183C0FEC2DEEFD1B93AF06D67987E873FC
-:10F91000411A33605621ACEB486A9B08C7D20F09E5
-:10F92000355714523E1BFBA5AF19F2177DD7218224
-:10F930003DD9BC45C4FB75E3C589B1FF09F2B843A5
-:10F94000C018FF3A9B09FDF09F257414DEAAA13B65
-:10F95000356EC7C8C7FD4795DE5448E9AD255569E2
-:10F96000EF02795AF6FEF56284FBAEC4A97F97AE2A
-:10F97000FF284F2B9CD3AB714931E5220B6EBFD8CA
-:10F980008CFE9225267734170AB8EF3A2798D701CC
-:10F99000BF7FCFE546CCEB44067F504CBF1A11EE3B
-:10F9A000D9917B048C6B51C79B51CCE2ED9714AA83
-:10F9B000EF9B3893AE1B06EDED2C5E007C69D06E9C
-:10F9C000A209F594AE719FA2FD1B73B9291DEEE14A
-:10F9D000398A95D773687E4C607F3ADA59A418E368
-:10F9E0006D16F0389994B6CC077640FB3D668C3B9B
-:10F9F0009E314D399943F32B27B2FB819DC565B1EB
-:10FA0000C334F0739C1288AC892BF8BE50C6793889
-:10FA1000A420DE0F739C92B09C044730FB8F8FE3D1
-:10FA20009826BF7DAB661C22297361DECB87BC277D
-:10FA3000831C731C22FCEF8804F1EFE4413C123E6E
-:10FA400080260553AF8B70EFEEE896D1F16087F713
-:10FA50002B75E33DC17E4F8AA17BB2201657C23F72
-:10FA6000788FB6FAED0A5ABE0564232BF7134ACFF6
-:10FA7000CB2D6A39152D2EFECE2196575F55017874
-:10FA800014F5F5876785EA2BD6D470FFCF1456BFDF
-:10FA9000DD52D013AE5DE3A2707F8EA17400FAE553
-:10FAA00082FC8294D3C5E93B4EC59E01AE0E06D7BB
-:10FAB000EFE82E901CF6277E2CC819405FF7C2F5A0
-:10FAC000006A37AF8EAFD90A741C23FA87C1F7E9F1
-:10FAD0000E25651CA5B74E8B92F13BF48B4463BC9D
-:10FAE00057D52D9F3D0857C41C938EBAA866433A3C
-:10FAF00025257624F8A59C5FA31C50E3DAC270A4E8
-:10FB0000F44BC75C690AE7412E38C27055E06DE0DE
-:10FB1000E51A385B69BE8AC3F5E45333AF4238CD8A
-:10FB2000B4225DDCCA79A8259EB4435CDD49E7E6D2
-:10FB30002B811E4E6E3163F06A2714C2BEE9B2B249
-:10FB4000BFE393184C85BFDB326C9F09FD79EF5101
-:10FB5000FA50803EFC2310EE6A7F274BDE4E80FB7E
-:10FB6000122713A50480CF9CA005E1769D44FCF0EC
-:10FB70005E6A67E2CCF2525ADE7948C6F20EDECFF8
-:10FB80009051CAFB85B88FF3FBBECAF922BC8FDA4D
-:10FB90001BBE8CE7F7E00F3E3FA1773A6829B5E23C
-:10FBA0007B430DC50B0B605F58109F87F1570D15F8
-:10FBB00002EEBB0D8D5F22DCD5FEA553229135717F
-:10FBC000524F80F73049F36EFC290B96D7359E448F
-:10FBD000F94DA793097C738C9F6FB69BC90D553463
-:10FBE000ADFB41BCA1CA86E794ADB07FD4911D9610
-:10FBF000051AF9473ABE08C9FBE11477F74EDC1F36
-:10FC00000372B54A704E8147062EEDF05F05E7F7A7
-:10FC100055D1CE2970DE9FE4FEF355707E5F95EEE0
-:10FC20009C02E7FBB94FC74EC5F234E71AF84BA068
-:10FC3000D5EE5C96CF74BE09F90B8797B1BC9DD108
-:10FC400041CCD31953BDB87FDB102E275A637DA753
-:10FC50007B77E4E6C6977570E9512E0A180785810F
-:10FC60001A947EFEB56C007B073727807159E9C373
-:10FC70000535FE8B142784E37513B38902E7A98940
-:10FC80002F44B3775A3F0E6400FC6E7E21DA0F7E5C
-:10FC9000C8798FBC6A81FD67BA28E7015F8D1F5D57
-:10FCA000933D3C09FC2501CCDFDCB81DE775E74836
-:10FCB000FEF7AC9CDD05E0AFAAE571CEB58678DF36
-:10FCC00039B69DE87F9BB351EF679B4B821F009F26
-:10FCD000D63D71FA38DF8F4C6C1E1287C7743170B5
-:10FCE000BD85CD6BCC70389F49E8C23863C91948CF
-:10FCF000AE41F8D6B9D03E498DC17B344BFABF5BDB
-:10FD000018E97D988E26BADF53967BB6692BA6D26A
-:10FD10000882EB4991821637EDA79ECBE531818FA2
-:10FD20002CDA78C12B385CE3B6B2F36E631CEC15A9
-:10FD3000C3ED3CBE9D9D2BCFAB7EA304F0A2E2F3AE
-:10FD4000A258D281F1AA09C4CDF1E206BCA8F00FF5
-:10FD50009F2FD3769991E842853F61F175314C5ED2
-:10FD6000743F178DFA9471FE757CBEEA3ABCC39954
-:10FD70007DD3DBFCBD30FFA4733F7FEF7059F7DE0E
-:10FD8000ADBA0E958F43F6E0C2C87A8A3AEFB3A7B0
-:10FD9000B380A52F74A6CA997A52E3423F2C972BC1
-:10FDA0002A9CD579AAF0EAEC25BE556A7C51B71E8B
-:10FDB00029508697E31F19CEEE374A1D9760889524
-:10FDC000D4B80DEB9DED7A5479DBDBBA54396B5C1A
-:10FDD0009F2A6FD575AA72575DEF382A48501EC208
-:10FDE0005B0F02D80B353AFDB7146E2868CF7DAC97
-:10FDF000B7E8F2E39DBFD3D5BF3875A1AEFC127949
-:10FE000099AEFC32D72A5DFE37EE3F18F4F875BA8A
-:10FE1000F22AE5315D794930500E7AF6DF9B2A31BE
-:10FE20007EFBC2C3DDAF42DEDFE4C4FC8EA6544CD1
-:10FE30007736C9C8DFBB9B5C98EE6972E3F7FF6851
-:10FE40002AC6F48D2605D340930753A35C98F497F4
-:10FE5000AB24D0D38B03EDA8FF678DA83906F270D1
-:10FE6000AFC9D76CA7703AEF3DA68F139F713FFEC5
-:10FE7000E6833B615F77B27B4D2D5D630539823E42
-:10FE8000E7A0FB9DA2A117C7C42081F36407891CCA
-:10FE900067F9C570768E8BF1799436A75AD93BB63F
-:10FEA00053A70A188F3895B0FB0934F5D7D0F2491B
-:10FEB00012F1C2FE5F6593F0FC89F0FBC253D834A7
-:10FEC000E13D756F14ECDF89FDF07ED264F848E700
-:10FED0002B2A22C6B14E297E1DE3FFAEB1B1BF93DE
-:10FEE00075F59E45FFBA93969316EF6876FF417DB0
-:10FEF00027E45DD3D9E80D5FC09D02380F12DCEC1A
-:10FF0000EFA4C44B6EADFEAFA6BB8633FD7F52336C
-:10FF1000BF1FB08FA01EA7F2235D5F2BCC5FE58BC8
-:10FF20002AA7E41FEC80FD7E5539D4AF3B28235C23
-:10FF300054BE50F940B5FF543E182F3ED10CF54F3A
-:10FF40001C62EF929D77ACE6F05FE838FF03F207A2
-:10FF5000233E0080000000001F8B0800000000000E
-:10FF6000000BB53A09705455B6E7F5EB2DA4937420
-:10FF7000428084CD0E110C64EB74D210B6E1911066
-:10FF8000DC101BD42F20420332614D62C02F8EFE45
-:10FF9000EAC63018F8D69F8C5A7EFDA2D53082CCA6
-:10FFA00068151948303343B0418D30E348545090C0
-:10FFB000882D322CDF848E2C223354F9CF39F73D33
-:10FFC000BA5F2761B1BE49A54EEEF2EE3DFBF61ECB
-:10FFD0005CF95182BE002BAD00E00028EEAC2B4D49
-:10FFE000C27F0B82F560A439FCF911FF0AF7358155
-:10FFF000312B321EF343FDBBB46FB7CF0B4613C09A
-:020000021000EC
-:100000002EDF0C8641DF22300E05D8EBABE2F17B10
-:10001000BE553C6EF1F919EEF3D532FCABAF8ED77D
-:100020003FF4BDC4E38F7C0186ADBEAD3CFF96D3EB
-:100030000ED007E0426B693F6F0E409A3A06EBC460
-:10004000344F0242A38033082117422B9852531198
-:10005000CE909C35C0F37E486118F4E2FAB2B4BF8A
-:1000600080B137A3EFB122BD0F80FA93DADB08230A
-:1000700001EE0741FF03C57FBB2C25D2C09B251590
-:1000800001CC4AEB05EB258087C09F3B0FE18CF24A
-:100090003AD35889D627D94F223F24FF17861FB35A
-:1000A0009127F433A12B4444E1A4C6371960896D2C
-:1000B0008D19860020978E8790BF0690E0C70C8030
-:1000C000C5103403ADBF6E3A1E8AE2F352800CC8ED
-:1000D00044FCDF32F17E6D1EE8F9A873E552198AFF
-:1000E00053886F0EE6D37208F17916F95167958D32
-:1000F000EEAB33D339B1F72EB1BD67C64137F7B692
-:10010000F2F3D7BB57935305C03CDABF264DA9DBAA
-:1001100083E72EEFD536473674C30FBBB1F3EA79C8
-:10012000C887DAE1F8BC1BF14F9864F5229E65B2EE
-:100130000D0C28C770400E58F09C45197589742E17
-:100140002A6622E0FCE26699E50146C5988E722B8C
-:1001500057E5D60EC1CF482EE5E3CAA700CA6FD136
-:10016000063D3D4B6C2798EF176157B7F456C0B367
-:10017000DFC9895DE9AD1877FB293AAF42E51BCFAE
-:10018000235EABDAA46DEF45ED5BEA4C483D198F79
-:10019000FF8C8251C417A4C31944FD397750765A95
-:1001A000A067FD38EB03D6F74B3ED8F61EEAFFD921
-:1001B0002B38D11FEDD159F2927FDCCF273763A1C5
-:1001C00067B593EC09F584EC4893E35AD42140BC1D
-:1001D000D79658037EE467D86D37D2FD61295093D6
-:1001E0004872B90CCED5C8EF89BB3E384C7632D1B7
-:1001F0006A0B12DF9088F668B94E6817D3E34F0494
-:100200006A1270FFD836BF4C663BFAA0B7C686E3C9
-:10021000511F2A2869F433EF796492FB765F13F358
-:10022000A1DE57CF30623FB7B29D413ACE65DEB80E
-:100230009DC1235603F9B5152A4E35C9506740872D
-:1002400075DE36594E403ACE07C149F305071D35D4
-:100250008457619B2227225EEE13DE1AC27B2D8A11
-:100260004141C18D6AF7CB49386F3142D0827EC49B
-:10027000926600258AAFA32F046AC80F6A7EEDED4F
-:1002800038C1C70957EA65F25B76B377EB46E427D6
-:10029000FC39CEB9D9D115EF1D4E03EBFFB114CF08
-:1002A0000E9687CD31CC934BFAD3BEE515D29F86FF
-:1002B00078A7059F83183FADF945ED1C8D6F1A1F78
-:1002C0002BEDE751C6A807ABCEB3DF8BBDB7D2008D
-:1002D000DE7AE4BBABD451588DE7B4AF86B9D370A6
-:1002E0005C674298D375FFBBAE9216C2AF4C1ED767
-:1002F000AA105E76C335F5BA72D5777C7F8FEBEAAC
-:10030000FD95CD6EFB7C5B64DE5820093F0F46FBFC
-:10031000496B449E372AF7F19D3374716BC20F5EAF
-:100320005DDC9A889E367ABDD4FAA86E5C667F4200
-:10033000B7FFF6B4D5BAF53B1DEB74EB7767FD5606
-:1003400037BEC7F9B26EFFBDC51B75EBD394DFEBAB
-:10035000D6A7CAA0486873B952C044763613EA19C2
-:10036000CE86568673A093A1173589E07C70327CC7
-:10037000043C0CE7B8BCFF22B9844D9D7DC9EE3B1F
-:1003800076FE2B87F4A2E31763ED198E485CD6E264
-:10039000F4CDC6E35E66945337FA905860603969CD
-:1003A000FEBE47F9C4F8FB7001FA13C473BDA17314
-:1003B000CE5F508FFCBB2DF6CD51FE0435D240F1FF
-:1003C00058B3DB9EFC4B99115301B4C7AD06E781CE
-:1003D0001574CE47BDA13BFBD2E0D41F90D1A88FAE
-:1003E00049B343C621A86F1753144701E2EF7F6654
-:1003F0005CF2C96CD5BFDC8272F8DAC0FE0F164B16
-:1004000081A14857538318E72E4C0E489C07045986
-:100410001E0F43C84474CC05607F3B0F1C0C178033
-:10042000C272C193E3F3D0CF2C6C30BAD6235EF9FD
-:10043000299D43C8CE72471F4991F0FE3C742FA4FA
-:10044000FFF906A8A53C45C3734181F0074F162864
-:1004500045056E7AAE75FDF3787F67A30136E13905
-:10046000A7463FF14B888AAB2FBB4A46D3BE6D12DD
-:1004700028141FFDCD96C0E60CBABFB32FF9756DD9
-:10048000DF1C57E904DA37B900F87CA87F0788CF6A
-:10049000D3EC82A730A90FF3009F1B4CFEA7AB9DA6
-:1004A000F959DEF9141FFA839828E67B79FC60C1BC
-:1004B000E6196B72981E3FE5632FBBBC1EC6DF8C2E
-:1004C0002E8DF07FD512D8C47953D56009F12C7FD9
-:1004D000CD62A0387E04FD2CDC0670D46765F8A5DB
-:1004E000CFCEF02B5F1AC3AF7D0E86DFF8B2182E89
-:1004F000FC010940391E2E50E692FC7AA2A3677FC8
-:1005000021E8084B30A3DED6757D86AAD7790D2762
-:100510009E8E273D68929D431185DC465438C4FB6E
-:10052000ECAE510139239AAFDE6584475ED3A7CF85
-:100530008D2DA2E78C7609F79F6D3ADF97EC301688
-:10054000BFABFC68360B7EA8F86E4B6E5D4FCF6F6D
-:100550006B1C4218A23F00A187244FA93B3A56B317
-:100560001CF30B44BCB9D7D25964B745E8034A150C
-:10057000305E54ABF1A24CBE9218427CA6D1B9A316
-:1005800049AF6F3D40F7F9F7C93094F513E67AA209
-:10059000ECFC75950F1ACC6D367B0278FEB6E6CF73
-:1005A000A6DF8D7C983AE64EB71C656F2F10136856
-:1005B000DFE8CBFFF37C2AEFB7D355336163991D96
-:1005C000F73D64DDF33EB1E061FBD765C9389E9B22
-:1005D00026B5109CE7C8989CE22074034CCF82ACEF
-:1005E000892DA462539CD3CC94174C24A38AF29FE8
-:1005F000A5564CB274FEBAB76E7C7BDA00DDFE3BCA
-:100600001D99BAF5BBB3B275EBDABD539C85BA7DC3
-:1006100064AF9437231D2C77D82C07864AA407177C
-:10062000BE58CAF4CF2C22FAC3C83F332600A78B8A
-:10063000D7BDF83CB98DC6BD89649FB1F9E9B2E672
-:10064000DFB5288E9EF3D30AF02405A59EF3D29E33
-:10065000F2BA1BCD4FD18F3C477E247FE7FDF61ABF
-:10066000C463DBE8CBFD1D48DFDE02CC5BC9FFC500
-:10067000E4AD61356F8DD5A3ABFA2A3984FEEC97D2
-:10068000D9EF6AF96BAC1E013C2DFC8D0A6FD6DEEA
-:10069000A77E22E2CF3FC8EE7B47EBB70A0305BA3D
-:1006A00078916FC67880F2E9FCBB0C9B68E20AE2A5
-:1006B000A1C92133A2FFF0C8C6F7D38B78DE4FF96A
-:1006C0006905C5073CFF0AE51F84EFB23DEFA7A708
-:1006D00046D661E5D7BAFDF094D4A21BAFC9D08F3E
-:1006E0009F9DD812FD7C4FFEA87CC3A3662FFAE91C
-:1006F000F2172425D08D3FD2F029DB1BA790DF34E1
-:10070000EEB2705D54615740B151F68371A49BF80D
-:10071000ACF98799325475E7E72C2E91674DD91BB8
-:1007200007F24F38F708EA0AE1E37F5BC49B2349ED
-:100730000A78A2EE497109BC3B92EBFEE37BDCD761
-:10074000F1277012EB3B9285DFCD6B38653050FCA2
-:10075000EB25F425CF1E32A4200C2F8AF703DA53A1
-:10076000E5E204BF211FD787747E6645D1F7DF9E7F
-:10077000FCB215E5F685C1A08B3F61F27938CE74E5
-:1007800025CF5C83FFDFBD372E68F809F46462CCA7
-:10079000627F5A22EC7E0EE98DB84701743995BF0D
-:1007A00006ED5E85FC04D14FE3D9DB538FBC407965
-:1007B000EC7EE10770D9165B973E145597C206612F
-:1007C000BF56FCA53CA60202936D54FF07D1FEE183
-:1007D000E7B3FF092E5BC4CE6FEB6AD79ADD571ED5
-:1007E00012767F6ED7C54FC8CF9FC3F8176DF71A23
-:1007F000DF347BAF7C4966BBD4E6CFEE92EF087462
-:10080000C3E7E1AABE81E2647BADB68B7BABC75F79
-:100810009A4E71AEBA19252475BD478395B5323805
-:10082000A2EED9B6DBB228608BD011D6E26BF3C54D
-:1008300094893902AEA6F80B75AAFF11790DC65539
-:10084000532AC5D5699273338243CDFD4A887F8789
-:1008500024083A5C7CC4FD56C4EF3E711CCDDB28F5
-:100860003F83B42C23DD335D95EB7D6A9FE881E601
-:10087000078692BFFFAC61FE21059756B83299CE2C
-:1008800007C1CFF9E1A164CFA01588E7D41AA1E789
-:1008900087923BDBA9AF74687CBC5423F1F96BA24F
-:1008A000F3BF4326CFA02AA64BED2F2923E41FE355
-:1008B0006FA2EE55FD22CAD32F893A8DEDC098FE66
-:1008C0002CF70B1643A045C17B2B9C41CE5397823E
-:1008D000A8EF63F3F48A71DF9A293EC4D695139B7F
-:1008E000F61C96F2BAE947C4E8EDF5FA0FB1F56CDB
-:1008F0004F79FEC514CF8BAEA83E606CBE7E352FFF
-:10090000D5F2AACDF1814D88CFBBE3FFFBEC521CA1
-:10091000AFDC1C6FA7FAF9CC6B163FF9E7339B2CC1
-:100920000109D7CFA474B651DD70667BAE134F803A
-:100930007283E3CDB728CEFFC1C47A01E014F6710B
-:10094000554F1F3F46FEAE7A738204945F7BC5BA53
-:1009500056CBC96F24709EB078477AC02245E20C0E
-:10096000D98703538BD3AFC62994F49FD9775F12ED
-:10097000F5A1DA0D7F1CCC7D2DF9A9634FE0734BF7
-:10098000B724B8289F801C60B92DDA347C23E5C7D2
-:100990002F9ABC4D447FE91BF7F4CBA0F33FED0346
-:1009A000444F78D78EBE941F45F2F6EEF3BD73BB6D
-:1009B00032932027C227AD2F58FBFA6A0FC93D5E3C
-:1009C00072F0BC11AA9401A4174DD380CE75C992C0
-:1009D0004276D9B92E9EF3D458BD3BE01275CA3287
-:1009E000AD8FD01BAC69643F5E603E84D7656F5AA3
-:1009F0008F7C3AE54A51E375E7B0E9B9D1FAD956A7
-:100A000041F5DFB90D16EE6FB4C7E9F3060D1E759B
-:100A100025F3FE72EB055D3FA162D565FD38071435
-:100A2000F23BAE1A47E1A30857A8FCEF18E139E6FC
-:100A3000423C97D4FF76E787CC970DFFFE05DDBBE0
-:100A4000CF26FA2A1F0AFEC5D603E556D1BF00D825
-:100A5000C8F76BF3A75EFD3C8FF4F05463F6309259
-:100A6000E37CB9F5E42B48E7D984D6634F22DCBE9A
-:100A7000EF13964B2CBEB17D987649627A97111D83
-:100A8000385FE6F65C2039A320B88E9BBF3E97F90D
-:100A90005726E724911CC367BAAF57343CB5F335EA
-:100AA000FCB4F3B57D52A190578BDAE7EB30B79EDB
-:100AB00025F976ECCC96A8CF77753EA5352F394A27
-:100AC0005F7EAEFEFA2CB5CF71D8B0FA3133EA634F
-:100AD0007BFDF3266FB4DFBBC9BEFAD57C5001871E
-:100AE000BDAF08251CB79038238EC76B6332061C38
-:100AF0008F53D193081FB4CBF12A8425DE34EE9BAB
-:100B0000D37908E320C0E39A894E07C1099287FB95
-:100B1000175ADD3019AA06121D066B88FB7D6BA8DB
-:100B2000CF8879CB03C96BEFC9C0FBD6F481B594EC
-:100B3000CFAC3109BBF0CF8BE77A4EE3931667C099
-:100B40009EA38B2F6BECE030E239338C506B4A1153
-:100B5000FB6E413E1FDA37FF7DEA9F7E6EACEA43B3
-:100B6000F71EB1BD902B1928CF0B2450CDF8C52707
-:100B70007F70FF1DF71E05653CE515F77F6065BFBB
-:100B80001FDB9F58085E1E9743C874019FFB6AF4E1
-:100B90003F37EF85085D5F8DF9BE91EA8487929FAC
-:100BA00076D3F3FE12C8A2B874292E318FE85965A6
-:100BB00015F0F15E899B089EB1DBFCD45FBD143754
-:100BC0003840F1F415C97B6F611F7E8EEB58FFB181
-:100BD000F800C5BBC7656F05F79393CD20E1FE70A4
-:100BE0001F952F1DC07C099BD4FDDF39785C54EA2A
-:100BF000E27E235C72B05F1E1B13778AB20DA23EA9
-:100C0000FB51EC1FDF69D4C59DA27CB59FF32F0774
-:100C1000E7A9137E305E332E75148A7AB7A8B7A180
-:100C2000AABB7C718DBA5E034159F47944BE30F69B
-:100C3000AA7E2932C9B1421D57505C43BD0A275ACA
-:100C4000FD32D23B7697D0B3B1C6E01E82E8656133
-:100C500015E5174D18F7343CD0AF405A36EBC318A2
-:100C60004D4FF1ACD9B86FAD54C5758C95F21A845F
-:100C7000EBA556C6E317D0C95051E3790938194E90
-:100C8000020F43D4538677401DC3BBA09EE1146876
-:100C900015F17F44B086E31A3C65E7F71877961B99
-:100CA00028EF287AB0FBFA61CB75F9808637F2E637
-:100CB000F93019D0FE32BBE1C7C02CF623B1FC8855
-:100CC000B5D3F11092D94EC9416452FFC0C1F65A52
-:100CD0000A0A8FCB6E900FC521AF91FB37B1FC286C
-:100CE000ED5E2FB6A9FC5840BAD62722A713850E71
-:100CF0001E6BF242FB4AA33C34568EDA7C517CC90F
-:100D00007907BAE2BF157E39D388F1ABA8B0644544
-:100D1000268EBFDCD121C6634B760CC1F15785E12D
-:100D200099C674D2EF92429313AB18A973E6241CB0
-:100D30007BC93EF309A21D923FF38AFA78A59AC7B0
-:100D400078573FE6B4A3BD7807D99C44A71593FD17
-:100D500038E4A39C29DE1F0EBE23B8D784FBBE3225
-:100D6000795BC87E975B83890EE4FFCAD565FDC8B1
-:100D7000753E6316FB2D16D17FD5E8C3797F1C8E97
-:100D8000B76FCF5E210DB93E1E78FE413ADFBB7AC8
-:100D9000A89FECD7DB283985644BFACD401EB6B747
-:100DA0009A80FAA6DA7D4F8DF01EA1FDE070B2FFA9
-:100DB0001EA0E639EDDBB3B3494E270AD5F7C3A928
-:100DC0001985C4C7A3233C27687F3841E8DB098A1B
-:100DD000E5EE9EA1AD48395ED8CD7CF81F88003E77
-:100DE0007FB1D07B9AD62BE3AF70DC3F5BF0E9DAC2
-:100DF0005046446F2514DA6CA4BF46818099E3C342
-:100E000038FBD53C95FCDD423C07F951E4F1D69026
-:100E10008B1B35BB7324F9553CF73C9F6B0E0D2E95
-:100E2000C0E75EB8EF9859E8DD40A177AA5F6ADEB7
-:100E3000BDFFC90162E881283BABDC7DF9FBA3C89B
-:100E4000BFCA7336276D8FD8D7CB2BB8DE049BCEA5
-:100E50008F687637A6C9C2F9F6D85DC317D2BEF13E
-:100E60009FB665125D13DA42FC3E2CDCFCF9008172
-:100E70008756875C927E4A3C3EA5C6895356111719
-:100E8000E8FD2ED77B8DE2FD6EB5DAE7AC6E9602FB
-:100E90007EF63FA27E5EA4D2B77C7F630BF54F1631
-:100EA0006D583085F52820EA0A07FE925F5872587F
-:100EB000D4CD4BB7EAEB8D4AAA9B693F04CDA40F72
-:100EC000CBEB63D6379472DD5C19EDFFBBA99B8732
-:100ED00015A9FDB1413088E992672779BBF187B147
-:100EE00075710528B9459CF77A64BADF6DECBEFFD1
-:100EF000909427E9FAB5E5EADDC4271BF3C5CCF5E4
-:100F000044F5AB2B9C761AAB76BB1175A798F2ED26
-:100F1000DA03DC5FD69ED3EC7871ADC475076CE85C
-:100F2000CD3A98BFC5A210BDF95BFA711D82F512CA
-:100F3000E7871BB7586A695CF3EB5E7E399FFAD08E
-:100F40009DFDA90F531387F9A6E8E783E4E23E0C61
-:100F5000F745E617A97E5FCD032058A0ABE76BD419
-:100F6000F85F9D30AC1F56CE917DFBD275F5498D53
-:100F70009A6F17119E94376EED2FD6E3041D7B3EBA
-:100F8000FEB778CA7B1B8D9E78EA6B9F3B3884EB5B
-:100F9000989EF8EEC63004D778DFE8FE7C4AE6B5C6
-:100FA000E456F49251F04BD5DB3FFB14F8C6149194
-:100FB0008B465F99FC56A999FA228F809DFA24D519
-:100FC000FB7F5763A5BA701D7007E21C087D3E7752
-:100FD000DAC0EFCF4742D66FC6E1D87DDAE80CE041
-:100FE000F30DAA5FA4F7C88E283DB3A8FDDF3847EC
-:100FF0002F7044D5D1F15929BA7182B3BFEEB9A48B
-:10100000E221BA75E4F7263A1FFC4A6BCEC848DEE7
-:101010009BAC8CD03DF74CE2E47D6CF7ADBFE4BEF9
-:1010200054EF3B5C7A7CE45D32F903B820F2A562B0
-:10103000FC257B1B05FE1A92C798767D1E551CAABF
-:10104000E3BA31EEA051D707B05CA72FF59C665FDD
-:101050000361A0F01BB1FCD67F4751BD5FE67CAFBA
-:101060007A1026AA19DDF1FB561DBF357BD4F8DEB8
-:10107000C7A3E77BBF197A7EA77BF5FC1EB048CFDC
-:10108000EF41557A7EDFB24ACFD70CBF9E8F99B51C
-:101090006374FB87D695E8C6B7BD74976EFFF0C042
-:1010A00074DD387BEB2CDDFEDCFAF9BAF5FCA62505
-:1010B0003724FF8260B56E5FACFC0BF7FDEA9AF255
-:1010C000F7E3AF903FB03C8A511E41C7FF9F1E7CA3
-:1010D0001AAB0737E867DF249B15DF2584FCA407DC
-:1010E000C5F1AC2753E385DFF968DFB9830A8E0FBA
-:1010F000380A4D699467A9F98347F5435A3D135B54
-:1011000037DE5B2CC5BCB78FD3BDB7BFDEF771EE42
-:10111000D6A06E5C7010F8FB17D761E7BB04DD2723
-:10112000146E778D3C5DF52EC1D117386C77A957B9
-:10113000B5EFEC62EB2D701E64BF3F5B7B2F434627
-:1011400031B26B7F52ABC7B43A37B6FED5EADEAEEA
-:10115000759AC863BAD61BCE3423E7D15ECEAB3FB7
-:1011600090BCDCE77C65B8D7E67653118075B28118
-:10117000EAE4508D60A602F41E3A4CFF7312F2ECC2
-:101180002CEAC7879381FBE7CAEADA597E1BA36F73
-:101190000F8D14ED23FAB9D5EDEDEB46B91E97ECA2
-:1011A0006B0BF1D98FC67C3B98F29174B7F85ECC8B
-:1011B0002223A7302EF59BAD00CD5F4C51FAD3FD15
-:1011C0005ABFA427BD89FDCEA8C1176468B43BF9F6
-:1011D0003BA4D8FE62C8E0E0FCD4FF2B89BFDFF956
-:1011E00096901B1DC963CED59A388F01B59E7F5846
-:1011F000E5BFD6F798ADD2731C8F588471F9E1A67C
-:101200000F582E4BD3DAD57E4915E7E30B06DA5C8F
-:10121000FC5D9B52E8147D32AD0F3240BE99BCEBB1
-:101220007AF42F4D3BA3EB43C15BBD6FE87D79841E
-:101230006E71FEF175A29F797CDD20EE9F47CE3F57
-:10124000CBFDA887AB3ED6D9C7DC554774F630CF67
-:10125000FFB56E3D94DA69A2FE636867FAE4879091
-:101260007F1D8D9691240FD48307DD51FDB7D0BA31
-:10127000EC4974EFF5E9FC96F168F3B5B27C353AC8
-:101280008FF90EF338E40BC57C6726E8D4FA1C1AF4
-:1012900034EF852C23BD4F947A39A9AFDC53FF433B
-:1012A000B3B3F3EE21AC9F970C8E93A24F54358AC3
-:1012B000F2BFB6897D4B08EFB64166A380C3C43840
-:1012C000BDD82AC693EF201836D96AA92FD226890D
-:1012D000EF82664BCA6BF3F0DEC7867B57917E5771
-:1012E0002EE9CC23FBABCC0FCD91F0FCB37DBC4FF2
-:1012F000127F242C2FD253980EFE7EECB4C19F2770
-:10130000A1A9BCDD787416D58DA77BF9CF5286B222
-:10131000CDFDF92CAA1B4F9B853DBED3189CE5A79C
-:10132000FA090F233AFD7F92447FCA16324FC373E6
-:1013300092FA789FA1F3E9BB307ABF47F3A49F5A92
-:10134000BF346C12796258CD17FFCB2DF2D9DFB8BC
-:10135000C5FB3F0DFE9EDEC1E0DF3B04D95F3F3B96
-:101360008CFAE9E7365880F25BBC5F311445BE5F0A
-:10137000E98BB4501EFBBE59D499AE772C41F25381
-:101380005A5F75933B83CF49CD14FDD2D4FF44BF40
-:101390004576186A1D3C2D210ADF83C07DEC0EEADC
-:1013A0004747F5B137B9453F141E117EAF63DD00E5
-:1013B000EEB72FDF7FFC18F9AF32B7770BD13DDFE7
-:1013C000E018497E6F79E21EEE9B35B91D7C2FE255
-:1013D000CBF4A21F5A43725A6E0D719FED7A7DF5C0
-:1013E0009EE8EF58D8FA620EF7911D79A437DABD5E
-:1013F0008847933BAAFFADE11139E7DA76A0F5877C
-:10140000B5F1A9579F19A6F6F7E77ABA89AF07DCB5
-:1014100022BF6F3375DF8FFF5F559E5DE4731B0046
-:10142000F5FF2DBD30F6236C233ED1FBDF99480F2D
-:10143000F737940292EFF2E93627F1593B1FCFF1CB
-:10144000FEF11AF7748CF07C467ABFA44AF4EFB52B
-:10145000F5B024E4EA5F27FAA9CB771F39F624DE3A
-:10146000B2F88DDC428A07DAF3B17C46FE0EE3EF78
-:10147000E864F1FE0BF9FB0D9D1FDBB7FFA97C0DA6
-:101480000F12EF69C31B2F0F76E0F3CBE9BBB63C1D
-:10149000D20FD1FF82067D5F0BF9E5A7FE46D7F795
-:1014A0005AC0EFC72C6A3CB168CF0F34EA9E7F3335
-:1014B000C1F34FC27FA7EA37707FC080F737A8FE1D
-:1014C000A941ADBB63FB2F0DADA26FDA9066E63C80
-:1014D0009AF21F5AD7F29F951F8BBEE9CA0C9167EB
-:1014E000139E2467E9700BE70B57FBE212C67BE4FF
-:1014F0006382D99B309274D2BB82E3997C0BCA99E8
-:10150000DE87FCF52EB58F20E2A35B8D876E3A87D0
-:10151000F0CA49E23859A4DE8BF505F7EF46835748
-:10152000CD1FD4FEDBBA16EE3FFC1F5946A94AB0C8
-:1015300030000000000000001F8B080000000000C9
-:10154000000BFB51CFC0F0030947B3A3F20FA3F187
-:10155000E7B0A1F233B9D0D4B3A0F283D0F4A3E3BF
-:10156000762606064626FC6AF061116606061920F4
-:101570005601621D66F2CD0161235106866209069D
-:10158000062E20FD5F9C81C10BC82E01625F20BF2B
-:101590001D886700B11450FC029096156360782E88
-:1015A0000AD1670D647F1323CF4E4B5ECADC3C8AA1
-:1015B00029C3E6B2A87C013506064F750686891A4E
-:1015C00010BE1E92FC0AA098A01A847D481E98DEC8
-:1015D000807C5559ECE61E06CAEB02E5776AE0B757
-:1015E0007FBB0E2ADFC10C959F8B26DFE882CAD70E
-:1015F0007043E5EBB84368003560D6A4D80300001B
-:1016000000000000000000001F8B08000000000028
-:10161000000BCD7D0B7C54D599F8B98F99B93399CE
-:1016200099DC241398BCE02604881A6012121E8AE2
-:10163000781302461BC304D1E22EDB1D686B23CF57
-:1016400001ADC6C736139290204482765D162D1DDB
-:101650007C15156B4AB14BBB6A27402B55B70E164C
-:101660001FDDDA6E60FDB76A955F50A9F868F99FD3
-:10167000EF3BE74EEEBD998447BBFBDBF8B839F78B
-:101680009EC777BEF3BDCF774E9CA484A8E30939EB
-:10169000033F5710F21AA13FB9434F427A09A98676
-:1016A000E7801C9E02CF187FCF9E81A57D02ED02B0
-:1016B0008A4932839022C27E8A5A36AE13A71232EA
-:1016C00096847E31B99896079635103F2DBF75D513
-:1016D000BBF0DCB8B8B67EBE4648DE92BE2357D219
-:1016E00067201C1722E584DC474442F2A1BFD25890
-:1016F0008D97900EE8EC5242C6C4F2F45839147437
-:101700005A20E49B0A1F88889A4CCB3EFC75681EC1
-:10171000C693102749946145E18C6B787B7B7DE310
-:10172000E98376469D62F8FF7A02F33B5B3B720BDE
-:101730001B2F46FF3943F15230343EF693D76C2AC3
-:1017400013C08FF5BB9EC2FBBAFF95F1F249A55BB2
-:10175000ABA2F36D10D538D4277D59322D0756C969
-:101760002421D0EF55BD82433BFBBA6C24A4BECFED
-:101770008BF8159A7C43F05D47049CCFB83BDEDEC6
-:10178000D51520E4D4526F08E9432524277BF87C43
-:10179000FEB9959084CB545E5C2B4470BCD02F4A2C
-:1017A00069FBD86231F428C0D3B0280BDE1BF56E7C
-:1017B000E3E30CA70FA2C9148F32A70FB941D4DD00
-:1017C00053FF7AFA902F903E726F31B523E7BF5ED8
-:1017D00088F7EA73A78FBF763C635D87F3551BC21A
-:1017E00031EE8E5237A1EB7F6FFDA2CC489A7A235F
-:1017F000AF6B25F27BA081E8F134ED36C17AE23C93
-:10180000631679834FBA3E526A796FB6AC973476D5
-:10181000C6925DA3E0430A58E76BF4EB6C91B4B752
-:101820007368515645E84FE6FD6D5497C708D02DB3
-:10183000D036C587D45B9120943F4890841EE51034
-:1018400088B4EC54F5F8DD0294E2B82E067C4AA97F
-:101850006819CF51E8B1AC07591213CCF03B5B9C2F
-:1018600008870C6CC2E55D18851B831B8638330125
-:10187000CA775AD65FF692849BCAD54DA595C4BC4B
-:101880000E069D0A8241A7779E9B5CB18FB7D80A4E
-:10189000E739B7F3CADAEF8D3625A3B593C9EF0D53
-:1018A0003C51E4FD0A7E31AD7B9783EC17A611D243
-:1018B0005EB831066FBBE07FB3913E416891AEC226
-:1018C0004A15E889EC166480D36D9047301BEBED28
-:1018D000221AD2534CB895403DC91B463C19DF47EC
-:1018E000868BD35D4CEF2FA5FD5EC3BBBD86EB336E
-:1018F00052E5787BC080BB04E73154A6F3F8E0766C
-:10190000FA3F4A1FB10A21FEA830FC7B03E8432AB4
-:101910008F1AE0BD499EB804AB3C6BE0DF0E3EF38E
-:10192000C6A4E9941E93218980B8DAF08C4BAFA34A
-:10193000FD1FB95C88BB040E2FADDFC8E17C59CF19
-:101940002902FA4CD6B9907E1BAFFC2400E47B62DE
-:10195000FFAFE474FCDA38C7310407FD6FAD797E60
-:10196000F4BF313006F2651DD29101D7EA4A09E190
-:1019700048CE11E230CEA1DFFEE19ECB289C2F574E
-:1019800009219786F0FA081D2FA97F14184D4E10D3
-:10199000637C8DA8804FFBF8A9F550424B802F9BAC
-:1019A00055A776371D6FA5143A0C7A8C8C65FAA171
-:1019B000599D5407EB23098C3EE60979D8AEDDBB6F
-:1019C000610CAEBBB434ADBC6AA68A42AD84EF5B99
-:1019D000268D0A67DC313860A2EB96B78AEF39644E
-:1019E00082738AE00BFC3E83FE3293CC8475FED07A
-:1019F000BB28334146EEEFBD56A54D7610F249ABFC
-:101A000076CF21C7F0EF2B2512ED2B1FFEFE6A418A
-:101A1000E1F88839C13E33E69D9AA73780F4BD12BC
-:101A2000C42F25F595BBDD6DB259FED8E691C2EF06
-:101A300005B65302EB63F91AF05B64A100FDC8F42C
-:101A40009F1943FCB8724F13E33B1BBC9D81BF0D34
-:101A5000BC67E3E30FBD1B3682BDDAEE60F4D291C2
-:101A60002B863690E1F462AC8781C7735D8F2D823F
-:101A70001BF9C3A0A36671E9A8EB7E363ABA15E854
-:101A8000E892FF793ABA0FE8A8FAFF241D6DFFBF6C
-:101A9000484743E52BD15E58C8FBEA1FF8EF6F8338
-:101AA0007C7E5D9750EEBD3E87C9FFD7234C2E2626
-:101AB00049A4A71AF4C15109E554526FF721BCD4C7
-:101AC0002486791C81DFE8F847B9BDF46AAB42127D
-:101AD0009371FE458BE8F757AFFAA410F4D7AB74B7
-:101AE0006DC1FE266450D769FB5752656A8043D9A1
-:101AF000CDCA836DA763609F270556FE69DB693DEC
-:101B000086E36DD97825C5E742F895C271DD1C21C1
-:101B1000AD1DF6A2E06478A92316BD4AD7E545813C
-:101B2000D28BB298DAA188BF3041FFB094DA09268F
-:101B3000FBA2051418C8E57A17EA3F7BFFAFF079DE
-:101B4000DAEDB8EBE6D438405FB8169F940728FC6E
-:101B50000B170B0E660FC5886A825BD4051DF44017
-:101B6000788EEB21D07F619938D434F358A8BB2C00
-:101B700076D749AEC7285E9630BF452B6A9A325455
-:101B8000FFA4A17F6DF319892E8C7918E5C5734EDA
-:101B90001ECAA1709106213451033AD58ABEE233A0
-:101BA000F79F61D8373EC0DBEB4BAECD647410417C
-:101BB000BD6AD0D32F8E7DC33100EFEB72502E5D06
-:101BC00017962CF6E4B5F51996795D3FE7DA51EDF5
-:101BD000701231E1C144F7FE0282744AFE8BDA29A9
-:101BE000944E63B58311B45B8E0B5A3B2D67CE6D5B
-:101BF000190FFDDE2966637D616ECBE401B4B71673
-:101C000020FD67F03E339DD13F94805C9D289287F4
-:101C100034B04747F70B3A016F9387CA8E402426AA
-:101C200050BC6931B5521A05DF715DAC4F47AF1337
-:101C300044B66E9DB1456A290074C82A37B2EAA23B
-:101C400068FF19F5291D4F107361DC18BE4FD17163
-:101C5000379D176DE761B608C9BC78512619651E16
-:101C60001DB6F5A7E25F4F27675772F8C87ED6BF4B
-:101C7000219332B369FF69EA1BCF2EDEFFE990485A
-:101C80009200A71C56001E52564BCCFD10BD02CB35
-:101C90004E5E7405C34A31C5A7AB5C846990CEF231
-:101CA000877459033CC470BD37D3B52D34F1E5E6D4
-:101CB0003F4BE8E7AF144BDA406E6CEEBF89681417
-:101CC0001F9E609C6079CA8D0AE0693375B29230BC
-:101CD000BEDC47008E8C42FA3B1D274325718DF6F2
-:101CE000276B7D099196E57A12D2E9279F1A123C5B
-:101CF000D4FF3E102C6993E9FB8EA504E52301AFC8
-:101D0000DC443F1DC1577509E867090901C01D8101
-:101D1000E538CF8DE5CBBB8BE9FB530D32C60FC841
-:101D200017145EC3AFA77E86A78CE830DEE63C12B0
-:101D3000F7A21DAC237E9D2A5B3F6D7B29494CA7F2
-:101D4000DFB366F4C3F8B17F22A1896C48946B328B
-:101D5000972744A6F407E3B7A8A1BBD3D09F42229C
-:101D60003789D5A67556C3E8C7DAF196E924570333
-:101D70007E3B2A281FA4917BB78A22D2413CB468BB
-:101D800061499A71EE1435944F46593BED44F8473A
-:101D9000AA3F544F26891CE85A17002F241CC0F96B
-:101DA0006593D48F0EE51C3EDF31248AF582B37A29
-:101DB000FB81DFF2F5BE1AC0C53FFBAE3F82EB46AA
-:101DC0001E54C18EA5D0969EC9199217A073607E2D
-:101DD0001F8644F43B7C6242D569073E773288CE49
-:101DE000AF46302E97094D28C077B72A1D6097F867
-:101DF000494880EFBE901C33DBF59984962DF11491
-:101E000072B474069216E30FA2F603EBA865D169CB
-:101E100000CC7D7EFDE7E0376DF145D00FFBC4EDD2
-:101E20009F0A83DDE6F13F04CF4FDCE3E2E89F85C4
-:101E300098BFA5D07F40DE65CE922DFE4D966E2DCB
-:101E4000E7D8FCB0059217E799750DE1FE95DE30F5
-:101E500071CC105C14A226A0976D753201FFDFEBE8
-:101E600065F018F0E54877CD0478291CC7010E8A83
-:101E70001684E314F922014BEC2F23183FA5701DA3
-:101E8000B7C175DC06D771335C2D0A9BAFDD5E8C64
-:101E9000D592B22805EE3991FB1FD46E02BBF11426
-:101EA000795FAF07C2095F8D7AD6AFB2365E2589FA
-:101EB000C10A95A8480776BB91AED38716FF6B166B
-:101EC0002F6B4480795038ADDF4921D20B96259293
-:101ED0008A0B2F9F65E04BFBF26F28FFDD74D84122
-:101EE00080BF281F4BF0DDC1BFDEC4E3C3CBC1BF41
-:101EF000A6F8FB1A09FB01BE0F888871A80FC8ABB2
-:101F0000FEE926397942E4F6092CB1998F4928086F
-:101F1000725CF66E4C4A7E4483416FC2195CC710F6
-:101F200093F35E467731A2B4A13EEC66FEA7114F53
-:101F3000FD7AAFD51FFEC6766BF946B2680CC44B6E
-:101F40006FFCB683C469BF3799FD7BBA4EAF892A4F
-:101F5000C2F70D12DD0876499783D91BCB55224372
-:101F6000FC73F5BF7D67C6323A9F53200FAAC17E2E
-:101F7000A7E09BF4C88A40DCA9970F9F5FBB106A5B
-:101F8000BC4C18797E5D8E6423F8DFB11E07DA99A8
-:101F9000C41E07DD27611CD4D40EE1FD6AB7757E2F
-:101FA000679BBF7DBE84DC8BF35DB17B19DAE723D1
-:101FB000CDC7B99BDA9B69F49D57122C711F83AF73
-:101FC0000D7AB7F37795A4B1B80E558368AFFC2EA0
-:101FD00023DE8EEB1B9D09EB7BB6F6B3A17DEE8570
-:101FE000B79FFB578E3FEF2CED572B830B60BD3710
-:101FF000057AC3C09F461C6B0D89E905F457C7B32A
-:10200000EB6260BAA5EA05CFB15E21AD279D43BD65
-:10201000D2D1FB3BC1ED9217F63CEC043BF5832794
-:102020008E35821DB0F2DF25A2507A38B1C7471233
-:1020300068AFC49D60DFACA07417C77262C6B526D6
-:102040007B985234AEC3CAA77D6847ACD8EB8A37B9
-:10205000D0F62B7EF4DF5309C5C3890D833F2F00D3
-:102060007A7E426071D7D8C0D46BE9FB1532F9C7CC
-:10207000701A3A5A26317E7AFFC7194BC04E147631
-:10208000F77F05FBEDFBB2C365D2C74B24078E4B30
-:10209000EBA11F117B5C884F14187C667FC088778A
-:1020A000BFFFB8C0E0DBEF88BB01BEDDBB9C115AAF
-:1020B0006FEDEE9348D7F39E7ECA0F7858BBDF6A68
-:1020C000A7AFDD2D255C53F1790C9EA041851980C9
-:1020D0004FC6CF6BF6AD46BDB1A66FF349E0E7B58D
-:1020E000FB1D16F94FF1124A005EDF90420D50FEC3
-:1020F000E1F7FC1A45D57BC947FD8057DAEF322757
-:10210000A5AB85B3ACEDA0FFD3D9C3FBA39E21FA49
-:10211000CD6BFB36B1F1F65DF30790B76B09D35386
-:10212000063FBF07BFE40DD7339B246B7CEB1479CC
-:102130007906FA81BB73D2FACF865E31F87AE5531D
-:10214000A776C6E8F8EFEFFDE3CE189DC7AABF7CDF
-:10215000B4F34EF0979E77AB20AFD63EF19A9F989E
-:10216000F0FF88C4F6034E3CFEBDC776503E39F101
-:102170006B17DA81279EFBC3388DCEFFC40F3E1D3F
-:102180000376EA2DCFCD1F0BF8B8E599796347B3F5
-:10219000D7816EE32EF3FAC6B17F6DBF009B20841A
-:1021A0003CCB9FB6753AB84F4A4088E083375D71A3
-:1021B00017C5CF5AFAAEA512D66D35EA2B28DF45E2
-:1021C000F1BD664FD749696A3ABCC70AC4203C13BF
-:1021D000052408EB7EEDC2CBABE0E908694027643B
-:1021E00010F584BDDDDAA3747DA78DBC9ED49E70EE
-:1021F00002FED7EED9C4C6EDA3EBE91FBE9E1FC0F9
-:102200002FB387AFE741C91A673A45567D77077CF8
-:10221000DCC7FCCE91D673F533D78DEADF19F2E136
-:102220006C786E16185C5B25FD5712F0E3DE271FF5
-:10223000DB1160EBDC401173E2A953E36093F71DFF
-:10224000C7E057404E0E3EE752C1AE5EF1DC1BC800
-:1022500077279E39E2D4707F9A7805AA274F90D4C9
-:102260004F12F4E61A8115D63EE24BB8FC43EBB5AB
-:1022700026DE54AFF9F1FD317C1F67FCB026DEBFCE
-:102280005848B37E5EB984E9A7782EE265B59674A6
-:10229000AA5EEBBA0AB3603D8F2D00FA1B693D8D33
-:1022A000F9AB30FF99A6757D84F1F148FC7A62970D
-:1022B0004B163287AFF3096E57AC8D0B6FA45B776B
-:1022C0004236B0F8DE08716FE369A70BA76CE573BF
-:1022D000A3BD31FFB3F1F9D9E7757E783BC5F5B5FC
-:1022E0001D7FEF7F915E0F94C802D75BBDF5F92685
-:1022F0007DE776503D560C76673456503C04EFC669
-:102300003E09E5FBFBBB25B4F7ED7262CD087E7D8F
-:10231000C818677FFF549067EF1FF831A74746EF53
-:102320006BF61C73C6B85E889BF502F497663D2E6B
-:10233000E5FDAD7D367D7F6BF79C4CDBDF7BB2FE30
-:102340006580FFBDA483C46817EFF54969E324A540
-:10235000B2C362676DF4CD783393B693FC1E0DE67D
-:10236000DDBE417F2306F6C8AB0E82F6A31C7AC7FA
-:1023700045BFB7FB3CB8DFD2EEBF916826FDDD61FB
-:10238000C3931C0CA31F2D07C2556C2F346EF1672D
-:102390001DAA68819BC8B142D8E7FC65F11F64E8BB
-:1023A00017E2699A292EF48A4C3A73687FAFE842A3
-:1023B000A88DA4896BD9FA0FCF918866A6337DBC0E
-:1023C000688E2FFA0FDC8E718D16124D40BC891469
-:1023D00092BE474DFD3ED8AAB1B86B78BC688EFF5F
-:1023E000B9A251DD45E128BC452D01FF6DA4F18B5B
-:1023F000A2D67D5F63FCF53C1E41763FF1C413B469
-:102400003C1EBE616A45BCCD09F13795D937F3B89A
-:102410003CFC29B79F0F08E1436087E977C56490CA
-:102420007782D626839D51FF454C5E6EA2C77AED1A
-:10243000641EE8D5EFFE595A928E4EF773BA6AFBC6
-:10244000A71FE541FCEE01F76D85CC990D237C8536
-:102450007C9E878ABEE185EFFDAB6FF44EA6F8291E
-:10246000084A04E2350581655B2A60FE47A5905B5A
-:102470001BDEBFF1DCC9E37A0FB5AA28FF1F690D87
-:1024800062F9318ED7DDAD65F87CA23584DFF7B413
-:10249000CEC2725F6B3D3EF7B686F1BDFF8E17056B
-:1024A000A03BF22DD207F19A7DAD4BF0FB8F5A2362
-:1024B000F87C94CFA71EF0E2B5CC1FE331FB3BAE16
-:1024C000D800F118038F76BCD7D1A962FF9AA0017A
-:1024D0009DDF2E33F962C7EF38574208D3724B9411
-:1024E000E52BECE4716363BEFF2A337B731F87E740
-:1024F000C7EEC8F765D86FAA2F2DE7F1F110C8EF26
-:102500009D42786B05E59F178A6606CD72B8C8179D
-:10251000D9279BE8675C378BF7EC9099BC1A4F4E34
-:10252000F66752BCEB5F100DE8CE98EF811AAD1044
-:10253000E4E40141C0F5D6BF10499989EE8CFEBE96
-:10254000238B7C7F23BDDC1EA263260FB2AF92CB10
-:10255000C0AF3D453C2189C2DB9947F681DFD209F6
-:10256000740976F26F33304E6CF8375BF87A67BBDC
-:10257000D9F7536FF9E2207F46F27B36F2FA1F72E9
-:10258000B856CBE15FC9B8AF1C1758BE4302E398F9
-:10259000056C2A944E976EA56B45EEB9F4BD3721B4
-:1025A0003EF8C1336E0DE0EAA93AEE37E391AC9202
-:1025B000DF37EFEB18EFF34F17203EFF1F891C3377
-:1025C000E339BF79D009ED3B056D5B1DCCEB3509D7
-:1025D000F9AF53885F84F13399A05FD07953300EFF
-:1025E00072CF68E70B59F93BDB1D5EB20CE6DDEC00
-:1025F0000CC5D2C8A7DF666816F9E00A5ADB0741A6
-:102600006756B3B246E9B382303911927509FCB40A
-:102610006A12C1E74CA2E133CF11F90CE6319D8477
-:1026200035807343C6B8CBD8FEC1FF18DE14C7FF90
-:1026300041BC19F41ABCB46C1BE41F903B44DC6F22
-:1026400069874F263A5FE810387E1594E7053CAE5F
-:102650004FE5FF0B4501EC86C549D40C9483057CFE
-:10266000C3A065E024C67783E3088FBBC731DF6969
-:10267000C72A11FDF507DE12E290EC726A55C99186
-:1026800049B47D0DE573589FECAB4A33CDFB0C0686
-:102690007F3CA08433D551E2FC065F18E57F19FF2B
-:1026A000BC007268DBF8E7FB413FE40F08211063D0
-:1026B000F9DEE864904735BF7B3C0FBEFFC6139937
-:1026C000635E9F1DABA3E3014EAF2F3C17DE870B6C
-:1026D000E33780BC3B557F8B0B97D9CBF25E5AEE2C
-:1026E000D2B64DD6465E9F9D2DA3EFDF18F3DA7963
-:1026F0008EF332D6EB54FDE228E8713B9EECFD668A
-:102700005FB578D4F11F04BDE2C2F92F35CFBF30D9
-:10271000AA627E8BD1DE98AFBDBD7DBE43FBC0E714
-:102720009617D4E72039B0DE3FF87CDC0F5F2140FC
-:10273000126109E89FF2E71A806706894A8C1FC276
-:102740001AC87F839E778C792C0FF5821C2F4679CF
-:10275000778EE3759270B806ECB2901832DB2BC618
-:10276000B33D45E7098CABBAB81C1133EE0AA6C3DA
-:1027700073AAFF42CAFFA63CA62D84B078544241FA
-:10278000390F814295961D8749E5DDB4BF66079BE9
-:10279000478DCCE221D30F6BBB241657959A7C262C
-:1027A0003CF2FD0623BEDB49EE22AA067E45453FEC
-:1027B0005437F8F4E7CEC8B71D908717D430DFD36D
-:1027C0001188086C3F8EED0F15717E9D2F2D55C021
-:1027D0002E6921E17AB04BC85189B03C3CC6D72E56
-:1027E000631F8CF3B1CB4D783C38C8F89AF77390DF
-:1027F000FBA53FE5F6C9B3DC3EF909D827B45CF484
-:10280000F1E00180733FD8292EB03742F87D1FB721
-:1028100053FCB77812E01FEE6DD5B1FC706B333E00
-:10282000EFB9F5709B1FFA7FEE4707FD14BEEFB4BA
-:1028300010E4D71692FCC54A80372A627C63576B36
-:1028400014FBCDDF923C007B24BD2D077485BEEFC9
-:102850008AD68A6E5A6F6715C1F8C64E85E21DE4A6
-:10286000631F41F908EE12CA2F2E9F32D79522FF1F
-:10287000F654EDBD0AF051788D88DB2F06BFB9BA4A
-:10288000070656D2F283CD7BDD4086D9B9C9F52F34
-:10289000815E9F43E5AD06EB92EC5E40D7B7A06842
-:1028A00091328F96FD7D1BD7817EF6EFBBFF66F0E0
-:1028B0008FFDCF3EF14D2817D8EC59FFBEFDB7B1C3
-:1028C0007A2FDE0EF50A0ED379D0F653D563FD309C
-:1028D0007F8ABF81CDB49EA3CA9AEFF894613F74FA
-:1028E00012A4ABED3FD82FC2FC0303E11AD8AE19F6
-:1028F000F366B41FC8A7F01D86FF5DAB3A76413F73
-:10290000EF3A8A919E1E6839001175F29D6FBE8E56
-:10291000F47C70D57A02F4E05A25635CB160F52D41
-:10292000E41B2679E16A91D3C699DF75B8907E3BA6
-:10293000572D4E4EE2640A7C38EEF63A05E5C5CBDB
-:10294000D67C07637F781789BCEB40FE62FBC4B27C
-:10295000CAF6932FA148077B89AC15599E5FB8CF63
-:102960006D8E1F16AE16C3E9E0F8D421E3BC3AA27F
-:1029700075EFBC48E72BCFBC15ED52D26B1DDF18AD
-:102980008F8EFFA9C3947F22AB0C2E8D84441F1D14
-:1029900077CF5E4F3E944F470D7D95C0FDD3A72B5B
-:1029A000C4C4780ADFBDBD22E6A11CAC67FAABE760
-:1029B00016B6AFD5C3CB3BFAA801563CC44F863FF1
-:1029C000B023CAF6BFC91767D0BEF0723ECAAE7850
-:1029D00055C1FD8998EEADA1EFA71183DFC4A175A4
-:1029E00007FB658B950EC48E6C4B59A3C6BA39EFA5
-:1029F00018360D5365D4A74715F0274FF5C904ECD9
-:102A000097697C7FC88ECF1D9CAF7742DE0CF81D86
-:102A1000ABF6BA350AF7CF0C3A6989EAA0178BEE04
-:102A20000AC798DF63CDA3868C10C07311DF87229D
-:102A3000D25B15480FCFB23C5A631FD15168CDAB62
-:102A40002EB7E58317D9F2A8CF37EE52EDB4C7E31E
-:102A5000B65C84FA42F3A31CCBE7633D329BBAF920
-:102A6000D386C75F52FDF2F802E9F5E37AE673799F
-:102A700078CF1D5233F80BFE159559E638E9D54E3F
-:102A8000E6C71CFAAD0BE979679DC2F73D59BEA7B1
-:102A900083AF7B9353C37A3B7B6F55009F5D81125D
-:102AA00037F473F0D29FB8315F85E7AD1AF278033F
-:102AB0007D7F13EDEF3BB922EAA4CEC257F360BF8E
-:102AC000FEDE3A05F352FD19037D0769D97BA73372
-:102AD0000479233B6B124BC226B86E7732BDB6D455
-:102AE000C9F787B658F33A285F2C7542DE98378AC3
-:102AF000FB99A2C2F37B6D7EBF810FFF81ABC4E265
-:102B000029EC593205FC54262FE33CDF6A27D70B0A
-:102B1000867DB183FBAD5BB8DF6AEFB7B4593F8008
-:102B2000F6D92AB5124254F6F59DD06D959FC53160
-:102B30002B3F8C6FB1F2435134DF52BFA0B9C4F2C6
-:102B4000DD17BAD866B72498BE236C7DBADCDE09DF
-:102B500020472AA93EE6F607CAB791F47DB343DFC2
-:102B6000E004B9768E76883F231C85789BDDCEBE47
-:102B700087AFCF3FC8FA16E88FFA75F760BF725C6F
-:102B800060E787AC76C93038B99C1B05CE7F719E53
-:102B9000877D76B6FD37FBBEDB6D5278FB2BF439B3
-:102BA0003793E54976FA989FDF09F1555A7E8ECF23
-:102BB000EFFB4E099FFFCECB733368FD34FC6DC431
-:102BC0005D7F0A0939506F6CFAFC4BB08CF07B4189
-:102BD000FAEF3F75B27DEEB9E3471FA79F8FB3C5EC
-:102BE000A13FEB34C5F7BA9CFAF3E6F24127DB9735
-:102BF00036E8C2C8AF34ECB45B1DFA2173FDA1A75F
-:102C00005D5EB2FD915CBE9E3EC2F8EF674B966F73
-:102C10009A48F9D959E845FB277749C73AD10F793E
-:102C2000494915FC845C2EBFC96226378DFDF6EC40
-:102C300006AB5CB59FC372F17C7997FDFC0D97AF35
-:102C4000767A1C49BE1EB3C9D7545C7B04BAB2C79E
-:102C5000B55BE057667F72FB389CB968CAC8F4F868
-:102C6000CBD6C19E431387CAAFC0B99AB474C0F61D
-:102C700019FD07DE6D585C05FB795208645CB235BE
-:102C800031F7ED8943F22B3C27EB67100F0DD76529
-:102C9000A1BC690CFEA9E7500E95CB7AFFDCB74DBD
-:102CA000F34CAA14DA09A3F089EEF8CCCC5FDF0369
-:102CB000590F76111F6F2BC7A7DDBEEE12632EE8EA
-:102CC000F76332A00BC5A3CFBB03F136E0053A1B77
-:102CD00069DED35D4CBEFB67454310BF739D919089
-:102CE0000F5CE30D3B268476CC0C5716A3676F0967
-:102CF000EEEF51FF7DB01FD6C1CBF2FE0DFDF89176
-:102D00001167E57AEFE62C56DEDCCAE2CAAE83B381
-:102D1000DFD0683BDFCB0E0271CC4D54AE437CB0AC
-:102D20009BDAF9F0DD5F354020BEDE4EEB474CFE0E
-:102D3000787BA85685FDC68EF24A05EC0A694A15CD
-:102D400096E5E24AB5968E39A5EBFE79B9101F2FAC
-:102D50001531DF761A2DB79552BA76A938BF5F962E
-:102D6000BDED05FB2C1B82A9D543EBE9A88AE8122F
-:102D700085C711546B214723A5B7399DD1F70F4162
-:102D80007ED1F784C86C179DFF2FF9B9AC2E67B4BC
-:102D90006C3DF84372CC0571C01685ED4F003D7453
-:102DA0004C1F82BB96E3D7CDC74DF9477C3D3F967C
-:102DB000076290F2DA2592E674EBD3E06272AE43DA
-:102DC000D5D551E949953FB3E455CF61FCE40C50AA
-:102DD0007A32F1F548F25A728517BB7287F298E899
-:102DE000C2AAC8A784D981C6B99F3F38F52558CF54
-:102DF000CBF04A0AB3914EE9FBF99EEA0B91FBDA5C
-:102E0000D63ABA6E07E6541DC17856D2817124FFB6
-:102E100004F28F663BE4251706E3E893C52DEFA681
-:102E2000F4119FCCE21504E826832A62D89F2C1265
-:102E3000E30F1503BCBBEA27D0FEBAE489D4521FC6
-:102E4000EAA7A688F9033DB59E66B35FF0C70CB646
-:102E50002F739BB7E619171DA7DC1BAF45F30BB209
-:102E600036C7B0735540C797A8644010410E860915
-:102E7000D39B2185C54DEB543847259008399331B4
-:102E80009A7EB49EB77A428E6FF0003E022C0EE618
-:102E9000DB2E6092A0D4A7273C2012BC8BBA5CA882
-:102EA000C7C365304EFF0C0FF1D2FA7FEA77E23EDE
-:102EB000789FAF4006BC3E2F2EFFAE93CE77F0D763
-:102EC0002ECC7BECFBF3C59897DFE7BB6C01C8ED1C
-:102ED0003E811CA6CA9ED49C2EE049882403F6FF9E
-:102EE000FCF37402FB30833F2368FF39822FCD7DD2
-:102EF0007B3A4E3C439C45DBB949B79BB60B7DE61C
-:102F0000F9E80A4A577BBD95F74D2343F11623CEC6
-:102F1000529711D90974D139E63F9B816FBA299C28
-:102F200012FA137A10E0AECC15312E4972BDF18938
-:102F3000F47DCDE1401DE495D6C8159832EB9FC7CE
-:102F4000D6FB379EC86E986F9DDA549745EB571D98
-:102F5000D550CE2E08AE3B04E5196FB172A793F1A0
-:102F60000BC4918849EED69C1E87F3FB21A7938E54
-:102F7000A09ED48551F9C6761EC19A4767A603C89C
-:102F80007F37D141C461A68359940EA698E94017B2
-:102F9000CE870EDA50595F08FFE86FD40943F1BCC1
-:102FA000E17CB04EC92E1FCE2F061C775765074017
-:102FB0008E1A7CA1CEBC0BE5AA6B99330CFB2D06B7
-:102FC0009F18FCF1A9DB817C48F9A411F87DB15769
-:102FD0009B9F8E4FC00F31F3C3B523F04D23193C97
-:102FE00014A08D1A6512CBA4A2E497B3DF291D6744
-:102FF000E2033BDE1AE708E4B8459EB1B209AF6AC6
-:10300000EADCA374EEF87F55D63A03263EDC48FD91
-:10301000103096BBC51001BD52ED5DFE29D0A5DC78
-:10302000F08320F8830E57B819F36967BE9F7123A8
-:10303000A5CB3F8D1135987CA7B6FC69E4E7373303
-:1030400008D8273D3356603CF84F3745C6839ED895
-:1030500044F17F1CF5727CAC88B9990363D93EBCFE
-:103060001664CF4890BD27FC7B9C97755E6F00EB84
-:10307000D175B6C8C71E37A3F71E37D3179B9CBDA3
-:103080000AF0DB60B1A29AF3A0AF90981D5BA5F0A7
-:103090007DA92FDA35881B5629ACDD7DAD7D687F93
-:1030A0006C6ADD8FCF9C8638813C2B4F594C83FD59
-:1030B00070E52FF30407F0F1C56CDF16DEB799EC6D
-:1030C000AF710AF36395BF4811E04F65434CCB36AF
-:1030D000C959451422E9ECE8AD6E99B5DB40F0BB67
-:1030E00072E05F719F3BA734247C1DCA1B7A49881C
-:1030F000F6E34EB0F781525DF89AA9DF40439F4551
-:10310000CF35D225C8AC44EB09CFC1746A1EDC1799
-:103110006B0CD4BE2B4F1D4E47F073DC440F06FCE6
-:10312000C6FEEC2DDCFFAE2B5190FF3A5B9CBB4002
-:1031300035372ACC2EFA38503BEA3902D897A59673
-:103140001BFAB9F084FDD9D864B63F0B65D89F85CA
-:1031500027ECCFC213F667E13BECCF42F9FBAD3A67
-:1031600096619F16CAB04F1B9BCCF665632EB62F97
-:103170000BCFFDADCDF8FC496B14BF3FDBDA82E528
-:103180002B5CCCBF2165B120D8CBDDB73B75C8BF68
-:10319000E9E47470502FC909D1757507589CC0FDBA
-:1031A000F2BD780EDA1D1471DF7563F05EF255FA28
-:1031B000ECAEF675431E8CF2B4179F6EF93EA2E199
-:1031C000BE6CAC1922A7AB94E97532B5134A83EBF8
-:1031D0006AB36979BD32BB03F21127696DA1E5EAD3
-:1031E0005059F355AEF881A93CBE7C97ECA1F56F20
-:1031F000EBBEAC03E401C001FBC86DCADC3AB0E32E
-:103200001225D45001B956EC8C033D7F0DD66B22AC
-:10321000C0CFFCA92F91F620C435C66BCE4AE0433F
-:103220005A3FC1E8FFDCEA774210387778BBD1EA31
-:103230008955E7548F48A3F407DF85D1FA21ED6A59
-:1032400092C2BE196406D8476EB6FFDBED60FCDFA4
-:10325000ED66CFB739DFFFD85D3BDF4DF968BE9B28
-:10326000F161B73B5C0FE75006A788A18708EE9B8A
-:10327000C4DC7028A1A5F857705EE8D6176502FB7C
-:103280000A0F72BE9D38DEC7F4F49D0AEAE92BC727
-:103290003FD5914DCB131F0E8540EF6E26210FD0E9
-:1032A000496C8B88F9294F564DC86EA2D52FA97E3F
-:1032B000261BF4CFA70AB377E3DCDF68EBBC713CD5
-:1032C000C4FFFE7484C9BF2739BDED7224A3B89E24
-:1032D000D55EB457A8C380F6485B50C6BC22318F78
-:1032E0003D9D0EF5EFA09E932AFC1885C7F9E7993E
-:1032F0000AC63F4EBBF8BD1749B4539CEE889A45A9
-:10330000DFF7C644E4F776D51307BB7AB3B712CF1D
-:103310009BC6CA653C77B2B95C64E7657CD7C7C118
-:103320003ED9DAEF66F2C1AB605E69BC7CDFE1DA00
-:10333000003C4515F83DAE2FAA47BCABA28AF9A9BF
-:10334000F437FCDE1CC0732A1023C7EFCD2CFEDC43
-:1033500039E6B397A641BECED7D510BF8B00F3BFD9
-:10336000D1E412619F68F04006C0F30FC63D06032A
-:103370001B3268FD8EE56A08D661AA5A5B0FF90513
-:103380009D6A2DFA391953EA9465288752E734F07B
-:10339000BE8C8E7219F38BE03BF025E92087E09C10
-:1033A000BCB1FF9C915529807DD5D980613E38C73D
-:1033B00060C937EFC8BE1ACF27498DD9086727D112
-:1033C00015A81F6B9051FF15789504EE3F18E7ED97
-:1033D000E1E88529DE90B3CA7A7E23AF59B69C17FF
-:1033E0001F1BB1967379FC20D776CEE34F8AB16F5D
-:1033F00066C5937DBE398187B200DE1C38E0AB0D17
-:103400009FCF7D81CA26986781EA41B883EA861AF0
-:10341000905F6349B40DE8EEBCE1B5C139B5BC239A
-:1034200009EB3E559389A641BC7D7003F4BB99D34B
-:103430007977B1551F3FA848063F4E75E7429C512A
-:103440002431D3F810878C99C69BD09D6D294FEC01
-:10345000CDB7D49FBCBDC4F2FDA2F8C596EF97ECE2
-:10346000AEB494A7F45D6AA93F6D7FADA55C91B839
-:10347000DA527FFAE145967275F2EF2CF567BEB924
-:10348000DCF27DF6C00ACBF7CBDE596F295F3E78C0
-:1034900087A5BE61AFDBF56299FBC2EC7417DC1F38
-:1034A0006189CB5AFD00BB1DAFFCA55DDB0072CD71
-:1034B000EF44FA96418FD3F2FADB991FA5CC0D6940
-:1034C0002057C671395AE4D3AB418ED6F815D407CC
-:1034D000B297D593BD0BD0FE18B79DCAA3E9606D16
-:1034E00092D4F70C90CBADB1B9A5A678935BEDC59E
-:1034F000335B35FE7A02F179A3BDACEA2402FD40CC
-:103500001004E2E7D44B857A6E8DB637CDEB795156
-:10351000C4A3D183D4DF7BC8E4EF8DE4DFD9FDB948
-:1035200073F5DFC689C483E70D8470149EE5D1234B
-:10353000B590264CFDBA1B807E7B9CE1E65DB4DF36
-:103540009E120FEE5F1A7E5D77711FF2C560B18C1F
-:10355000FA85C85AB9391ED7C1D737437912FD4AFF
-:103560008A7794B706DE370B03F176903BB77B5032
-:103570001E8EFB2FD7ABC05F4A8952A0D0F7A18324
-:103580004E1DF6B7EFE3782D512B6A21A4541A6C27
-:103590003A00CF491AB533E8B3AC6CDB0178DEEA08
-:1035A0006679C217877E500BB24499CBEC3F79AA5B
-:1035B00033BE81F623A9148E347E85F194FCDBD9C9
-:1035C000FE45A9FC7BA037B0EACFD029D4642B7884
-:1035D000FF8C1BE840C027D28F3BE045BDE186430E
-:1035E000AF5096857886C0EC53D89FABC9DE8EEB82
-:1035F0006ED8AD60CF46989FDB01F41568B0AE770A
-:1036000086F27DC45387C0E2DEDD59DACBB574DCC7
-:10361000EEDC926C88B1425CA4C9246F7AB8DEFEFD
-:103620008A47E4F96F4CDEFC05FAAC1EB27728FD40
-:103630006F1727007CBD04E496FBAE5E02F4EE56E5
-:10364000E96AA25D1FD3C2A84F99BD7B3387A9AE9B
-:103650006409EEFB7F14A844FBD6DDF27C5AFCB96A
-:103660000724A24F1F19AFFE493B50DF9312A70654
-:1036700076458BE6D477A59107E5DC0FD934CE38B3
-:10368000E7CACEDB76737C18F1D0549C91C7D38CFB
-:1036900038A3D1CFCDB9956347B3C7DDD4BF8C98DC
-:1036A000E0DD44C701BC747ED1548F7890093BA7FC
-:1036B000FBE7F25D904765F849E5DC7EA9E2F81D7D
-:1036C000E724E827CC83B8490E78B55FAA07BE3453
-:1036D000E22CBF03638BD60BC588C4E26A0E436F2E
-:1036E0008967A621CC9A7306BBE28BE5A332BD465F
-:1036F000FFED87F36413BAADE73527F65ACB93B7DE
-:103700005BCB17C5AD656A351F05BB006C348C5BA0
-:10371000ECB67E6F32F603EAD8F932858E7C86E904
-:103720005FCB7D3984EBFF7CDE4F515FA206C46B1B
-:10373000E12D56BD9ACFF57CBE4D7F56FA248C27DD
-:10374000D41C0E1C02FBD188FBFCC6A359EE7530BD
-:10375000E2377679EE796B1BA15FD02F8FB8581CBA
-:1037600003E2C39F14F17849218F978CE3F19222F1
-:10377000162F7148DA2B4B05CC0B3DE9463B233A1B
-:103780008DC569D839AF0FEBE59F091A1B2F621A57
-:10379000EFB6B2D8950C0DF13CA867C44D8CB8803B
-:1037A000D7A7CF073EDB1C7A357A90D249EDAF5DC3
-:1037B00004FA992FBD7CB815E45B918CF9DCEACC56
-:1037C00055DFF5401C12BED3726DB13616F9E01705
-:1037D0000E8C0F7471BA36CE271A7116BF87D94571
-:1037E0001E8F60EC037978BEBE07ECDD4B76535A32
-:1037F000B4E83B16CF33E27653FAACDFFB8890A3F4
-:10380000D2759CB6242E32FB4AF7D698F21D2FE6CD
-:10381000EB367569E2DEA5B4BC87C42BE11EBA0A9B
-:103820004E1FA143D673B1638880E7A2C61C9542A0
-:10383000715A7FEAB3D6EFE5B673B317DBCFD1DAAF
-:10384000F6857C1239B98C8EB7458B0A2047B72C88
-:10385000A5B63C2D4FF6F0FDA2496412D0E17CC91B
-:103860001B4A007E5F93707FCB756CF21B90C7483C
-:103870008EB07C247502CB8B545F92504FA919A453
-:10388000A2C23BB48F74FF9910817D1123AEF50461
-:103890005D57D02B7BA85F5EEA003F5BC5721FF5CA
-:1038A000CBA1BC97FAE5F0DC47FD72780FF94850E0
-:1038B000DE4FFD7278FE84FAE5F0FE59EA9743F98F
-:1038C000366FCD7C4F2EEC1B9521BD782AF629133F
-:1038D00028BC5D8A4305FAB0CBA19A9A9B95C59402
-:1038E000A4FECEF514EE5FD4CE67F9D3F33D4FCDF1
-:1038F0006B93ADF13573FC7128BE362018F1350895
-:10390000791EE3FB0CA9385B84C5D9CEDE8F6EF43B
-:103910008371CD61FDF0F8E607B7FFE763EDF4D3FF
-:10392000EAEA7BBB3D25709E234ACCFBC7C6390F14
-:10393000637EABF7B5619E8C33EF6814D6755F95E7
-:1039400017EFFA713A222AC85BBB3F67F871767BA2
-:10395000DA78DAF59B8FDB1546DCB4C741307F3A65
-:1039600026507B02EC8BD6F8DCB71D23C7535FF7DC
-:10397000F0734536B9903A37C0E33E2EB066E93C65
-:103980009D02C707CF6747D158C2E27AE6B8AAA717
-:10399000348E87D53D5E1DED3A81DA7B68FFA991B3
-:1039A00020C4D136C2398134F37B98F37B5B9E13FC
-:1039B000ED8D8D790ADA497585A120B46FCF9B1101
-:1039C000349F1B30CE351CF2CD50064CFDADF79523
-:1039D0008CAAFF24AAAFB551F4B5E462E77ADA0FF6
-:1039E000CC56E0BC46B7777912FCE8EE6000E3EF16
-:1039F000FD793330AF27553F380BCF75485E660FE2
-:103A00004B4105ED6119E65F3E54DFA8D7EA6174CA
-:103A100042D919E38B6E6F2FD673C961BC4FC215A3
-:103A20006079772E95EDC7794A45A298E485316E85
-:103A30008B87C5A3BBCB232AC459BA8332E6E97767
-:103A40006B9588E7768EE7F622C39E08A11DF36F7B
-:103A50001CCF463FED3C0ED0DEEC447B2EDC92A525
-:103A6000C2D52F5E5F780FF073B7778302FB92CEDB
-:103A7000BCAA51FB3DC0E5F6C8FD568CA99B8EFD46
-:103A8000FE1BF4EBF42D57A15FC708E7915EE170D0
-:103A90005EA8DD6ADFC7A3D006CDF928F6A78FDBC5
-:103AA0009FF676ABCB079CB0EE9B1EB19E5F761067
-:103AB000769E6BCDFE75C8E73D7212EDA89E2F84F1
-:103AC000B4E7C2C66418FA2CE5DF5BECA002CE4F67
-:103AD00005FC3B901AE88B8A84D56E997ED85AAE45
-:103AE0004E5ACB33DFB4DB41FA6B60072DE6722F01
-:103AF00049E53D4B861994011FE158BC06E06E2252
-:103B00007D6D9027E1E071F2C55CFF2DE4FAD19B59
-:103B1000C1E2BD05CD1E8BFF49F8FD7F85BCFFA22C
-:103B2000BA43EB3A40C8860DBB4A43BFB5E8AABDCD
-:103B300035282E6DF655936E3DDFBFD0663FD9ED2B
-:103B4000AC1A7917E6E9E6DBE21AC67E2ECC13EE54
-:103B500039B08F7FBEE31AFD411E16C837E3FE174A
-:103B6000BC6F98B62F92134288E2291FCEE7507897
-:103B70000A6E21FAAE34747C395FF761788B5D810F
-:103B8000789BC7DFE57BD9BD5DF975525C2B86F369
-:103B90000E7D680F2C5A45E78376F819CC8331EAFD
-:103BA0006767F5F5C3BEE78E0681F9A53182768D8C
-:103BB000B1CE3BBCEC5C61D3E5425C84F6D1121C17
-:103BC0001FE12A195A5F8AA7E30C4F2CCFF0DA7A4B
-:103BD000EBF9C7269BFD62D0C342DBFB010FDB176D
-:103BE00037F8E083D96F4E1A47E1582DF4D6674C69
-:103BF00038777D69E20FC719E043F87D0C4B7D01F2
-:103C0000FE38A0FC50057E7F3E6BE0014249B229A0
-:103C100083C4EA28F1FDD433788940CB4B363FDDAD
-:103C2000D95D04C7BA079F0423CFD5B56F7EBDA960
-:103C3000ECB93B81E5001F07B616D97A9BEE83A14C
-:103C4000A8DB0979F360E7EA649B04B9B6A2BA2D50
-:103C5000543CD42E1BDA09A3B40B936D729A765E92
-:103C6000A31D45D746B8EF89CFCBC3BF8B1C1EF32E
-:103C7000F832E04DD5BC78BE7181AC425EC65F0BB8
-:103C8000C798B3CD3B42B639260C6F47C16E33E0BF
-:103C900017D3C31F87EFE6F11DA3C0FFB7C6C7D96F
-:103CA000FA73F2EFE70D1FADBE61CCC8F305B81C87
-:103CB000780F91E6154DFD6CEDFF14E3E2F20D0473
-:103CC000CF2FCA0E5D85FDBC72F5DBE8DFCB5975E1
-:103CD0002AD8019B6819EC804D7DBD18FF2E2FBDA1
-:103CE000B71B88BE3CE121200FA610356B0FED7786
-:103CF0008A2AC3892B225F7E4884783AB98660DE9F
-:103D00004866BF87DD1B547CE9C3E06F656529B851
-:103D10009F919135E36166F4B238B3017F46CDD10E
-:103D20005A88BFCB4D2424005C429CD400935D4450
-:103D3000707FC3A3EFBB0DCE1B1099E927BC3B07D7
-:103D4000F42A8FB78F652443BA9D6A13E6AFBC2867
-:103D5000631C6B2C5C0D4689B2BC3C7B1BC0531EA4
-:103D6000A11D08003F8B974D8988A104EDBFF22467
-:103D70006B47FE839D2BA1BEC99267BC437835E497
-:103D8000CA581E870F2EB5C6A9C9209D336D5FF98D
-:103D90001F8B1E8538C59861F29BF9ED1E0E67E6F4
-:103DA000491286FE030D56BDE1E179D71EDBBD3217
-:103DB000953E87F53E68BBFFF0AD30EA0117092953
-:103DC0004EB42F96A2DD60F8253BA022D8E34584AF
-:103DD000E5E7DBDBCF60ED4990F9292E0F51944ADE
-:103DE000FA7D8547C77C43172D533C0A4EA2E4D188
-:103DF000F7F9228BB7B4094486F2D07809CC337036
-:103E0000295FEA00FBE580321DEF4B33FCEA763593
-:103E1000847910A4ACD662371BF95EEB2B4AC6C27C
-:103E2000F7CC31A9B8930A74B93EB714ED687FCEC8
-:103E3000C0DF839CFD6CB37F81723995A39087713D
-:103E400029E523AF7B636C0E1DF77401D14CF69905
-:103E50004B8E629CCD757A9CE57DA2D57ABE5AF7D1
-:103E60008A75304E9197F1610D513BA05D0DB19E69
-:103E7000A3769DCEB3D8EB43FD175ADE27A85D632A
-:103E8000BEF767E4FE33885666EE7FC208FD4FB288
-:103E9000F5AFA6ED7FA8DF1C4BBF9D328BBFC602DE
-:103EA0009EB4F750567B6B4BBCD523EF0F5479591A
-:103EB0005CB32B18C5FD815A42199FD2CB155F1CEC
-:103EC00097D8F95E82F61B29B4EE0FD4723A162900
-:103ED00065001D5F215BEF339E4BECF71B5BEDA292
-:103EE0003720B845F125FAAA92B84FF0A957033FF9
-:103EF0006C24BB39D94A303E3D3763E066D807BFF2
-:103F000066CB7867E72CCC67467FFEEFB7542DE091
-:103F1000F781B2BCE680887809D78EC5F35B463F4F
-:103F20006127990872312CB23C08FCA1E32773F396
-:103F3000310FD13EAEFDFC7B932ECC2D35CD2B0920
-:103F40007985E6F1E615EC924CF308BB48358EC74F
-:103F5000EDDDD478632E6CBC233C9E658CD7B4C059
-:103F60003ABF26A78AF36BE27C6C8C7704E697064F
-:103F7000BF671D8FE74DA6C6BBD23ABF26978AF30F
-:103F80006BE2F7EFA6C61B7361E319719D2E6734D0
-:103F90000A7438527CC788EB5CEF7AD212D721E4DE
-:103FA000C97935A5846C1398FCD8E9ADD90874F1AA
-:103FB00051C3FA32D42BDCBEC67B56A93E5E2833F1
-:103FC000781B0BBDF136131EE1BC8D3E19CE49287E
-:103FD0004477B173133A9EA308E2F3216AAFEB98DA
-:103FE0005F5286DF1F6B0D617977EB2C7C1AFD9495
-:103FF000CD62F7815D3447486BB7BFEE65FEECB626
-:104000003CF586AF817EABF1B07CDF599711DD6462
-:104010004753C3FA009C9FEBB99E54808E9CB49D7D
-:10402000C11DA81B1387F5F7541C4AB6421C5476D1
-:104030006898EFAAA5FFFB0647BC4CDFB85CAC3D17
-:10404000B98CDD8BDA983A17D480F9478D0BB330F1
-:104050001F61D162DDA752BC2D1684D74AB9BE8339
-:10406000F350D7F1A5B6FB0B01D03C74BD02BA14D6
-:10407000877BE3AE2B7C798940FB0DFBAE453F236C
-:104080004C1B66D37EAEE3FAB6E6988B403C82CCFE
-:1040900077A2FC5ABCD8EA176C732754B073B65594
-:1040A00004481B6DB7A8C1FADDE5627C15B6DD0BCF
-:1040B000D378967B628C7C5B3B7EEC71D397BCFCA7
-:1040C0009E181E1F3D45CAF1DCB991976B6F6FC4F6
-:1040D000413700AF835C7532F9309C0F183C7FE4A8
-:1040E000727047EB9B184733E0CB97E302C8FB8223
-:1040F000E6372D79EF14B168541BFB0444DA538181
-:104100007AD8369F1DC29EBCD1EE89CA27F2EF072E
-:10411000CAF8DF331086CFFBBD61F39EF34A29490D
-:10412000C73F2C1EDC78580AB569437831F0F0BFE0
-:10413000CD47F773BCBF32EFE32AE607165AFE6E8F
-:1041400080717EEBDA545926B2899E17AE70EACCA4
-:104150005F1D2C07BA3C7A794688FDFD0B6E07255A
-:104160007E2D821DF4D7F7AF1759F29A79BF23AD90
-:10417000973D9FD2740E99A4F68D20FFA52D14446F
-:104180007B609D88FB1FF951968F07DF8F5BED5693
-:104190004B3E5E7BFFE302C40D1F80FC44D339BB62
-:1041A00082E63EA113ECBBB6388B4324683D0A7708
-:1041B000617342E8281FCAFBB2CBF5C255D67CC159
-:1041C000CE398BD53D1AE4D5D4F6C285609BB6B303
-:1041D0003897513F15EFE2E7511D244AE0FC85E492
-:1041E00065F1E620BFAFE36CF9BB9F8831B5B81825
-:1041F000F276E34A0D5DB7077322753E885F062AA3
-:10420000A3BB803EE510E6792F6DB9330C714235C2
-:10421000277D1C7C29B70F16FA585CE52D47A208AC
-:10422000E2E6C99CDA85BEEA34F55BBE85FDCD1DAC
-:10423000E11EFA66DECF03627A79B08C7FFFF26A04
-:1042400011EF1772131F9E577597F6CE027C3CB084
-:10425000664728DD39CB196A246286C75DCAEE0736
-:1042600020A46F36CC73D3E70FF63D4DE79DFDB923
-:1042700017E56CB6C4FA35B56FF6E50E6FFFFCA70F
-:10428000EC1CF2F3FCBE75424AAF04BFB1275526C1
-:1042900031B88FBD278B976302FB9E2AFFFB02F884
-:1042A0007B4A3D40A394F8FEE8FBE54688C3F60848
-:1042B0008413EB2B0B206EDFC3EF773F0CDF69FB22
-:1042C000B957BFFFF056D007339CE86FF6707BC735
-:1042D00080EF031FCBFBF9C0C7F87D247CDECDF156
-:1042E000E9057C06CE0B9F77A7C3C755017D33BC7C
-:1042F0007743260805C1FDB9720BE45BFF6B2B0900
-:104300007F8DCEE181D0BEC7E14C116D7F6FBAF6D3
-:104310003FCED1EF8375F2AE3E8EF3F3957A4380B4
-:104320008A4D3309F693068E07D2F563AC6B288B62
-:10433000C93977267B6673FB5272258390BFA056DE
-:10434000DD7FB34AF97E63717249BA38F1E37E6664
-:10435000F7678D10174F70FC5E991D7E12E0EE50CE
-:10436000EF457FCF299030D4DF346B8008A676FFED
-:10437000E567F8A670FF10E076CE66F756FB28DEFC
-:104380002141CE57C5E0DFA41D2590FFEE0B1EC5D1
-:10439000BC565FD500F23B8AC27C4657E00F2ADC50
-:1043A0007E4BF8FE7B01D04DB664D0DD37BB806E0E
-:1043B000A4A1F29550DE95CDDAFF3FFF37BBC05F79
-:1043C000DCE9A46D400EE63BD1BEB1CFEF250EAFC8
-:1043D000ACEA3F87F90DC3A76BE0E1ADB47DCF44F4
-:1043E000767FCB5C31B9E4AB4097577BD13EA3EFEE
-:1043F0009798EF1F3BCDE9ED34F7E77B3E55F0BBD7
-:104400007D3D46A2D7810BA7D78111E8F5988D5E37
-:104410003F26E9E9F59D74F283D2EBBBD0DE8E171F
-:104420007B5922FA76D857963F5BB01BFA93BF347C
-:1044300067FBD3F4297DB62586AB19122CE7998743
-:10444000E47DE4135FEED03D03C6DF2DFA27208420
-:10445000DC34FDCE9CB11DE4D839F42BFAD3F49BA7
-:10446000F43178E75EED8DA4BB376E8F9FE5C7FF13
-:10447000C8CFEA8DC4376FF9597ECA487C73D09F84
-:10448000E29B6C80E36C7CF311AF4FD721DF7F4E52
-:104490007CF36D7CBA4B19DFE0FC2F1DCE3724B6C0
-:1044A000AC0BE4F1C662C61797DCB306F922C54728
-:1044B000B156FC2E0D95517E1B7CF4E93DAD58DFC5
-:1044C000DEDE3FC23D819529FE0F57C03CF44BD440
-:1044D0000E763E6900CFE1EE2283FD2ECC13667985
-:1044E000B99E584C67E64192C07D1297723CEC042D
-:1044F0001F0DFCA0193C9E2527C922DF707EF655B2
-:1045000025AACCF7BE1CE1ED3D99E11A187F1719D9
-:10451000C0FB9A465AA7051CDE33D9FA027F1A3A25
-:104520003F9B1E5AE967E7E556F27EB23F57A2600D
-:104530009FDAF97DEE9A9FBCFBD828FD34F3F61183
-:104540000EFF05F07FC49F867F29FF2F83F726FE8D
-:10455000AF124AD2F27FB33FBDBEBAC9FFB7E5F78B
-:104560006FA6E3CB463FE3F7B3E17BBF9FE9FDFDD9
-:104570001C4F178AEFFB79FB7B2E1CDFF78C80EF3B
-:10458000ADE788EFFBD3B5A7F8FE173FCAFFBD081C
-:10459000BF4FF362BCBC7B26D92794A485E3BBE65E
-:1045A0007E148DF54379EA6381D2FDDCCFBA43E90D
-:1045B000EE45A2ED1E4BD76E815F3592CFD7E1FD60
-:1045C0005F5FF2E2BE02D58F4FFC8DE9E047E9E87C
-:1045D00060AEC8E490E2BFAC0BF4FD5FD1FF817424
-:1045E000FDDFC5E5FAD9EC82D786EC825FF8AB87B0
-:1045F000CBBF5DFC7CB2AC46927E8CDB0F5C05F2DF
-:104600006AE71DD902C4BB0AF584007EC2CFB91E79
-:10461000BB022E0DAA1E6AB7534E08F0773A7646B3
-:104620005501CE4B99FAFBCFD1FAB3C341E1FBADB3
-:104630001FE59DFE3B782EE0F33B5F3BA93F5BFF10
-:10464000BD1FF54FF81D78EA93AD72DB988718EE21
-:104650006579B6B3D2FF5DCB9FFB64AEC7C227CDF1
-:10466000F2FFDD145DB1FECE57FF50F83EF333BDCF
-:10467000F2453AF8EC78391B9C17F965434F39330A
-:10468000D3E8297B7F869F6DAC135C8B618EFBE446
-:1046900064A6F47736F4E7ED14F11C552397278DC3
-:1046A000B3B2B8DDAE7AA0FF07781CFE8155F7D60D
-:1046B000C0BEFAAEBBD40A40417E33D37BDAAA71C6
-:1046C000185F2DCA142CF933C633D5DED97711FC07
-:1046D000BD083A6E318C7BC51C9200BF3113EC06CD
-:1046E0008C57A8F8778DB35DBD4188CF6E127A974D
-:1046F0002C07BD7A95979D8B092E3ECB7D991B2C5F
-:10470000744B825567A9DF86F5D58C5EBC3FE59C6E
-:10471000EBBB7AD3DA59B599A2E14F5C9E593D0AB9
-:104720005E83018C7B19F81D3E0E5BBF9A705400AE
-:104730007CFBAA041552EF7C944EC05E124B9398FA
-:1047400037754D15A31742FD92D1EF5FD968C0159B
-:104750001E75BDCF112EA3DEC8E3F17AB6F316A9FC
-:10476000BF3FE665720C2BD2F2878773D2EE2B180F
-:10477000CFAE5655872B923F54B54CFCBB1DA9BC00
-:10478000EF507091EF7FBEDED0BCE22C3E6AAB9F53
-:10479000BA7F24A8A0FD877FD7C344479B3299DF07
-:1047A000EACC0A7F2B13E56508EF9FA5E518AC0757
-:1047B0005168D987E50DF85D4D953BB01C64F589CE
-:1047C000AA9E13DE69BBCDD84E4EF5D383656F6AC2
-:1047D000DCAD386E2055DE86E54256FF5CC71976A3
-:1047E000FF4A52C2F97F2CEB99B06F7A7DCB5731DB
-:1047F000BE7443CB4DF8EC6E556B204E67DC4372B4
-:10480000FD0D5F55C19FBEE1EBF7E1BEBED1FF429A
-:10481000F03B80FF35B91EEC2567B1187EC43BC460
-:104820007F43707460B95166F7FC2F9C75B2A7C3C3
-:1048300014BF53E0EFA5437E8D66BA07830CC9C34E
-:10484000EF09FAD399E741CFC3E749C8214ABF1F0F
-:104850007B4BE331A4E75A351DDF18F31DA97F63B5
-:10486000BE23C91B036F297A2AE57F5FD716BF7461
-:104870004FACC3FC9F850287D3C7EF8BE4F51AE9E1
-:10488000387BCB912E34A0DB46EEDFD9F58331EEB9
-:10489000F784C8EB801F8813DF55391CBFE78A37C0
-:1048A000A3FFB19118817BB93CE504F7C5023E63D3
-:1048B0005F9DC9B56F7B8D720C934BC2A5BD28E778
-:1048C000DC9A21F7989E5433FA74B1828EB3F5CCFA
-:1048D00095C18B200F3412848B0869F905B8E7392C
-:1048E0005B6265123BF3C2A142D007EAC54288D29F
-:1048F00043C7E72F1C2E22ECE822FEFDF4CF5F40D9
-:10490000FBC228C385BD65B4EC4995752548CB2508
-:10491000A9720CCA3BB9DD7766EBE72F74A03E0B9A
-:104920007F6696AB355CAE9EAF3CFDFFDA45D4E9C1
-:1049300000800000000000001F8B08000000000045
-:10494000000BE57D0B7854D5B5F03E73E6956426F3
-:1049500099BC278190131E12157012480848DB0974
-:10496000AF862B8FC1074609304978846700AD4E6A
-:104970009596810082628DAD0FBC2A0E16BDB6D50C
-:10498000DE68E92D7F8BFC83A0424B3156AB684536
-:10499000A350A56A4D04B98E56CBBFD6DA7B67CE3D
-:1049A000399909A1DAFFEFFF5DF874B3CFD9673FFA
-:1049B000D67BAFB5F69EB367E1CFB7183B6B2A192C
-:1049C0000B3396CBD80E6D8367FC28A879ADBE213A
-:1049D0001A635BF05541BCDD051E3B63158C3D98A9
-:1049E000197479A09CBEA6CBEA8476CE921C77D0AF
-:1049F000C558B1F79370357C5F3C8E310DBF1D9C5F
-:104A0000C5D818E8D77BBD62CF817218F3288CDE39
-:104A1000ADF740FB1C3763ED50326B84B1618CDD28
-:104A2000E59275980F9481D208EB80E7A91A7F6F01
-:104A3000C13A3C571D6C651BD4D34A993F02758F10
-:104A400083CD0BE0F81E0BAD63844715A542F3CD73
-:104A5000F06E601AB477D658FC112833B074E9D7D9
-:104A6000BF81DA8DF058A994F0989213BCC8837076
-:104A700061ACA60DE7C5A281525847EA853959B7FE
-:104A800042ADBAD47A3D83211F5ACB02F36D8C55C7
-:104A90007A0229081757594E6A7018D5CBF07BD780
-:104AA000464B98015CAA993BA294C4E102334F0D96
-:104AB000B893E3E395B5C1C0445BCFF7B29C758D65
-:104AC0001AD0AF439613110E308F8F6AFF7C0F2ED2
-:104AD00067B9B3CBCE06023E07DF19602AAE47A303
-:104AE000F7CE5D33A3FDE0FD8ADDAB18CE777D5AAE
-:104AF000FA38C4A379DC57BEB8D71380F7299F3999
-:104B0000026D09C65B22E0FCF2DA5AFA0EBAD7ACA3
-:104B1000798CCDC3A50C6484D00E27964C39EBA0BC
-:104B2000E5BD3C18DECF659C18AE0CD44F6300D7B2
-:104B3000865A95A925F85D777B7616EA733BEAA736
-:104B4000B2115009D94EE07327FC3D0BFD0659E622
-:104B5000640F3CAE0FF3E7D41EFE5BC07C9373E1A1
-:104B6000BBC6CDA6E76F4CF90B4BC7F7D6131DA5F7
-:104B7000F1FEAFAEAD0F4C14ED4ED3FF23B49E2B20
-:104B800035E647BC5DE94B8B8461895705AE094C1E
-:104B90002C8DF7F7EA97EA3C848B191EBFEA86470B
-:104BA000203071484F78340414BB473B375CFA0A15
-:104BB000877A6BD9E45CAD271CCCEB0788DD8E705F
-:104BC0005E0070BEB524393CA01DE1E3D56BA01D8D
-:104BD0002C65B23AD566013834CE54984321F8A6F4
-:104BE000B341D8CE3F75926EBE66389AE1D5F8349F
-:104BF000F345A1DFC6BBDD3EA070F607099F280084
-:104C0000AD12E4096FAA5FE73B387F0FFCC5755E04
-:104C10005E55F66C0ECC23B841F131BEDE77F4EB75
-:104C20006B60818CA842EB7E2709DEDFD1AFD33CDD
-:104C30003FF3FC53505881FC0BBD51F28303BA760D
-:104C4000CC1A1D1618CED8E31E77CEBB69501FC1F3
-:104C50007C6781AFCEB0711923F1FDE01CE26F33A8
-:104C60005D7CBA56FBC1019B9ECF399DCD0BCDEC2F
-:104C70001E17FB5758B0BBEE013807AE516FBF0A85
-:104C8000FEFDCAC1EC8DF86CB557D54E6423BC60EF
-:104C9000BD842F3F6392BE1896E17D2AC06F2673B4
-:104CA0006A2EE8E75B20A4CEC25AA6FB5334976E67
-:104CB0001DA75A951A94A380BC8C2B87C7D76B9ECF
-:104CC000F76AAF9DC6037AFC444F8F66B8BC523B6F
-:104CD0002803E5C80B71B88C381FB84C42660678BB
-:104CE00078B25954013C7729CEC8C330A7BAD0CD89
-:104CF000818923112E2C6C07D179C25342F251AE17
-:104D0000DBC6E49F950CE5699D9D05715D6FD858E4
-:104D1000ED932E2CA345E53AB9F55E76F50994D3CB
-:104D2000B25E17FA3EF50F84487428E979AED315C0
-:104D300055391D7ED84D3724CFEA3CEF5E4C786262
-:104D400067619D6AC6320DD7ADA6A58F60198C6DBF
-:104D5000C626B04E7B66A00BE5BF9A362082F4973C
-:104D60007ACD8F37733CFEA866960E8F290B7E1185
-:104D7000A6CEB52C03FCD304FEAA05FE524A9D66BE
-:104D8000FC31E4D370298B3CA2081040FDD4607F35
-:104D900004F93699DE90F84C29B57EDEA1A76BD6D2
-:104DA0004AF097786407467521BF06BD56762BBD3D
-:104DB0002F25F8043D123E5D36D427F342B653FA50
-:104DC0007E8205F323EBF0BB2D0E1F3E6BB068799E
-:104DD000D80EE0E4413DCE4A7D3EE41F1686EF2426
-:104DE0003D215CD198D0F5DF016B2828C7FE407AC1
-:104DF000E2779B75E30CEC396E375F99FB357DA745
-:104E0000AA603F901DE1F3F974F2BB2493DB0FA776
-:104E1000BCA3DA2C0393C3AFC199EDB766C7EBEF20
-:104E200014386B2309F480EC4FEAF32C35E8B5E035
-:104E3000DAC23B0F1E18877AD873114832769BED81
-:104E4000A183078B1892086385F8BF870EFA5D640B
-:104E500077883A1026CC7F476A77DDEFF4427D6091
-:104E6000773D8CF5ED301C1B0B764BE6430737C0C6
-:104E7000F79F1E7390FE3A55931A41E6C90E4D6096
-:104E8000C761DE5630733280D4A00863E90CF5A305
-:104E9000F52856801CC03B5BF32908EFCB3335A2C5
-:104EA00007ABC6A26E985CB6D5A720BC7E68674DDE
-:104EB000426E5C385367BF5C9EC9ED0E398EC3C924
-:104EC000C229E5F17E19F3AD433D629DCA48AF00AA
-:104ED0009F93DD26F95BF6333793EBCF6EFE3C37BD
-:104EE0003FCFCD4CC0CF872D2BDFFA1EDAB3BF5595
-:104EF000D923B09439DEEFD2F359A1462AAF092D58
-:104F0000A6B2498CF767166CC27EDA6B5F9A732380
-:104F1000D06FF32E870FD5F2F21BFEF2830A0DE15C
-:104F20000478C7EF1634DE5D01EFED432C64CF6EDD
-:104F30002E62B5484FF6750AD9475B347BCD2E28D3
-:104F4000EFCDA8BE2733373EAF7B3326529DD568C1
-:104F500016A4F3D54E4EE79F1EBBC5DB8076A5CBCE
-:104F600045FC625F57728705EAEC10CC9BA1FC60A0
-:104F70006467A80E5E6ECEB4123D6D16F415167001
-:104F800077C610C99CAE57C2F84E6B98A19DED8CA8
-:104F900059E9B95D81F925A053D99F33064C3A12DE
-:104FA000C7337F6FA7E7B82EFC5ECD6606BBE7CEA2
-:104FB0004C6E37DFD93D8F343E8F6C733FE9FCB9BF
-:104FC000E03FF33C3EF04CB81BE17F6F86FF9E4C08
-:104FD000B2C33B6C28CFE7BA7E7B5419D11779DC7A
-:104FE000A1A03C9EFE85122D06F8A554AB91F52597
-:104FF000A8D73CD346011DB06A9B0FE1D93E38C704
-:105000003D5037FE6302FF2F5A3D6E9C676012D8F9
-:10501000D544DF2CF74AEC67526325977F6070E92F
-:10502000F4EC8BDACECD0351FE866DB45F9AE70CBB
-:1050300047707E3ABB4D39CBE5B266AD8CDB7FF372
-:1050400026AAFE94F49EF61D6C430E90FD2765790A
-:1050500018EAF0DD9BA2FAD6C4D357E1323A98C7DA
-:105060003E506F0FE26EA912ED1BFE675EC868F737
-:1050700099EDC286AAB2E7000D009748CD28A4B3E7
-:105080000B2D44677DB59701D39C5E26B578705F84
-:10509000F5A09013D3271E9F887263069856D8EF09
-:1050A0008C89AA270AADB7862CCC0F133FE2572371
-:1050B0000AACED4869C7A16F21DCAA6C1AE9AD52B0
-:1050C00076FB1539F87EA407E11C107608B4E7FAE0
-:1050D000CDEB8C0C8167EDFEE3AE461DDD1DA93ADC
-:1050E0007E21EE5740EE3525A227C6D6D1BC0EDC78
-:1050F000944AFDBC75971271C0FC27A95FFC7E34F1
-:10510000DAB3DFB3F91C1A2DCB82789DEA6362E330
-:10511000EA774DD2D901C759A092ECCAB263D50E35
-:10512000B45F372AC4A712FEF342467B33B812ECB1
-:1051300032ADA77D0A9DD9919EFB6A9F9AEDABCFB8
-:1051400033C1AE023A67E5AC5C6F5725D353D2AE9C
-:10515000B232BF92457AA8C38A7A773A3C4824078C
-:10516000AECD5008AF93D40F093FA7AA540DE175F7
-:1051700024F4BE0BF7E347BE50F93ED89F6BB0E373
-:10518000F2B3B85F60BB1D0C32F86E7BA133B20E78
-:10519000BADA77D345F91D841FEDDE7188C7DFDAEF
-:1051A000480E279BAF3BA4B2C14098D3420A951248
-:1051B0007FC5A11466D5E987629678FEA5597CFE65
-:1051C000B96B9845837133C3CC9F687F2CDBC1BE1C
-:1051D00078B29551FB6826CC6FC5600BD1A7DC1F58
-:1051E000A7D8C2FE7EB07EDB9E5561DC2717C3FCCC
-:1051F000701E1ACC0FF56549288DEA0343D9540E69
-:105200000A65523938D48FDE0F090DA2F282500997
-:105210003D1F1ABA98EAA5A191545E182AA3F2A2DA
-:10522000D0A5545E0C7A13DB0D0B5553393C741921
-:105230003D1F11BA82CA4B4233A9F48566D3FBB233
-:10524000502395E5A17A7A3E32B494EAA342D7512D
-:10525000BD22B48ACACAD0CD548E0EB55059155A43
-:1052600047EDC6846EA3FAD8D08FA8BC34742795B6
-:10527000E342F7D37B69B7A40A7EBC4D9BEF417F25
-:105280000750B886749C8CEF1665713DF042A67F7E
-:10529000465645BC9DDD027ADCD5B35D6316D76307
-:1052A0009988D704FDCDCDE2F2F923DF3BF70C65F9
-:1052B00071BC6DF1F6EECF60A589F71B71F9C0D70F
-:1052C000373D4BA372BBB5DDAF22FDAE64BE303CB3
-:1052D0009A36EA4505E5CB0ECD5A93C8BEBB37CB0F
-:1052E00046DF3D98195C81EB4C2B397100E5C98C88
-:1052F000B0E7F7E3915E86E5FC763CF457BCC1422B
-:10530000DB7D8D79F6A17F4D9BC8482E4ABF12D810
-:1053100075067D7A87800B636D0707123F0D2EE7B8
-:10532000FAA7630AF297FDA681B47FDF6E8F2A5633
-:10533000B46F5633A6B7FFB76F6A7814DFC7FBB3F5
-:10534000D33C8B37B367D0C42E69D5C6A740396824
-:105350009BFF9914F8644824383E15EA431F0B3F1D
-:1053600083E5856D91F169505EBC3BFA0C6EE38676
-:10537000473BC6BBA07EC941B61FD9BFAC5D9BE011
-:1053800086FAC8A3FEFD4006ACA22338215DC3F90E
-:10539000445AD2613EDBDF04430FEA551FB6AAB080
-:1053A0001D8AE31FEC38B4DF245EDCA3DA2766C372
-:1053B0003FFB5FEF2953F17B6B474AE6B09EF8D97C
-:1053C00081EBC675821E7904D6D5DF1F553C3A3A6B
-:1053D000F98DE067C0C34328E7A45F72C7862CF24B
-:1053E0004BEE48F554E3905D9398E7610DE9D84A98
-:1053F00070B26F1C48FE384977005F833D7B87A001
-:10540000BBEDDDF66E62F8FE46C8BF7F15F8FE5BA9
-:1054100016E78764F07522AD8C39371F1F167C099B
-:105420007C7C50CFC7E6761F0B3899E1BCC3C20E17
-:1054300082AE8271814E395F31F4A37D28E8FB5C36
-:10544000707DF75F8C6EF70B39910CAE4CCB213928
-:1054500009F47A21FAC792C91BBBD8CF98DFFFADF8
-:10546000A79CE37E5B0FC8B941C9E5DCF302DF49C5
-:10547000E597903376937FC799CDF9A6D213B0679D
-:105480005724F0537B730C7EEAA9AAA71AE50D1BDB
-:10549000CAC88E4E1B1609E33EA538AC95ABD80C96
-:1054A0008532C2B1B094FC0F2560675801FFD0551A
-:1054B000144BA7E6B134A0FF5DF29BA7DEABE73744
-:1054C000A9EFE3FC28E9226BC7ADDC2FA9CD04FBD3
-:1054D000E5DBD9C2AFDFDD0FF7836CFA6EE18E5BDF
-:1054E00075727087D74B75D93E19FD2E10EF776C0A
-:1054F000584FF0748E4B6C375467F3B8C2767B9775
-:105500001FE93CFC4DE6417B2673C33B249F32419F
-:105510003E29249FF8F8FD43A98F86A1EECFCE1334
-:105520007E004FEA2CF7FF3B7ACE459B0AE5D43844
-:10553000CF3E15E334A08734E4D37130F751082F00
-:105540003BE15D631C8FDA381641BB17E016C57D61
-:105550007BD8E2263F93DDDEEA477E66F64C5A7F33
-:10556000A5273823BB17BEF0A4696588D46076DB15
-:105570001417D0DFA6124F2AD6E7407D6B158C9BFF
-:10558000D5C1447D8B6BCC3FEEF708FEE8E787364C
-:10559000C078FBB2FC73919E81AE8358FA877AACD7
-:1055A000E4AFF6F6CD1E90FC19E7274F99E4A7FA71
-:1055B00061240F9760BFB2BF64F6CDE06C2EE76E3A
-:1055C000166532FB46D2FD79DB3762BE8BB37BE7D3
-:1055D000FF570EFE68DB4EA6F33716DED36ED5D02E
-:1055E0009FC1FD3416673BF5E716FE463FFA1B8167
-:1055F0000E9C83791DFF24F21727876384E623FD21
-:105600008CD29F982EE88A599508EAF1F42A8FB532
-:1056100081FAEB6097437FDBB2B9BE917C8D72EB70
-:10562000A9612897B2ACB85F477F923B2BDE3FD68B
-:1056300033CAE3F289897DDC7562CEADEB7D19E872
-:10564000720E1FE17E94D6EF73BE9CD69F45D6A303
-:105650009CF033CD03ED5398FCE337F893A77EAE6F
-:1056600000EF821EFC5CA55219CCA26ED8EF4DF360
-:105670002951DC07DA2DCE08EAD2EA4227C3F8A680
-:105680003DDD12C1F888FD1D85D6692F4F8BA0F036
-:105690009B5858958171CCD387F7BB8209F07F75F1
-:1056A000B0DEE0FF32C3B1BBDD9C673D08C7FBCF76
-:1056B00011A77D3EBB3B4EBB0FF972FAFCAE0D76D7
-:1056C0002D1EA795F1C702EFAE2DD5A8B29671FB9E
-:1056D000B49045D6E9ED2A5D1CF477D8CFFDF138BA
-:1056E00068FB05FA386873E11EB477EFEB8E83062A
-:1056F000F712DF65B79521FDDEEFDBF5933B109EDA
-:105700000E11AF1879CCA5A19FBE627F2EAEE7F730
-:10571000A6F9CB52FAF1CCFBE03F651BE30BA77D6A
-:1057200057644489B6B213F2B7F42FCAFD30FA0FAA
-:105730003D09F9D0086F397E9DC2F7B5CCA670F946
-:1057400027F428C897BF921C8830D29B7E87F230FE
-:10575000EA9BD3BE913E8A7B269137723E00C721D9
-:1057600089E2BF305EC238AB2387EBA93A1BF79BB7
-:105770002AAB2A56E2BCEADC2EC5A1F3F79F16FA43
-:10578000CC1C175233BEA8080ABF77A2F59BE33B97
-:10579000A7515FE47278E9FDE4E782D7515B2BC53E
-:1057A0000F8F2E50D93AEC27383A9F25F85E96AFE6
-:1057B00023DD0C61EC18C2B84287CF24F1A2A36BA1
-:1057C0009B28CE6C8EA775BFAF4FA945FD5D8B7032
-:1057D000D48D5B25E0375394CC11D43CF0DEDE70E1
-:1057E000B78761FC6BC827156137FAC5BA7E89F1A6
-:1057F0000BF63D37F92B6AEBCF54AC1BAE83671524
-:10580000E3F1D9FDF77934785E3B64436ED8951C9B
-:105810008E3373381C6FC30763C81F333287FB375F
-:10582000FBE48F61C3785C88ED4FA1F869CA1F550E
-:105830001FDA0D382ED703DC9F7CBD889B98E37858
-:10584000B5A11506F9921653584417BF48B3B6913F
-:105850007F362D66A5E7667ECBCD31F29B847F3205
-:105860007C4AF89B9FFB72F87A8ED62FD6D06F6851
-:105870004F4D6C07DF22DAC9BA391F2159DC7DBED2
-:10588000C0EBE9E0987CF457D5DAC343FAC2E712DB
-:105890003EE7CA739893C3F5B8FB9A97441C4FDD53
-:1058A00080BD49BD9A66ED3D1EEB37C563D346F515
-:1058B00088E7FD53E2B1EB7284DFF03CE3B15304BF
-:1058C000DD9E2B0FE56ABBD1EE91E52C81C7D3C1DC
-:1058D000141606F9785DB54A7128A00FD28F47EFEC
-:1058E00056C8DE8CD63B482F37D6A7907FB6B14C32
-:1058F000A5F78DB7ABA43FA3201F96817CF8BD9080
-:105900001366FF6C35530CF1F3E9A3520CF56B16DB
-:10591000FCE8F76BD1BF5C65D370BC231AF73787FF
-:10592000FD2AD9AFD0872F8AFEE9BBBEE1437D2691
-:10593000E9E1885F257E0BBFACFA70D876E18F3E37
-:10594000B2B92C82792A4C89C7E9B541D87F23C5E1
-:10595000815FF36EA33867CA97F70602B47F0C6ABB
-:1059600065A43779FC3445F0E984C2AA59A8C7DF99
-:10597000DA6A63E8377A6BCD69E2E78EB52B292FB7
-:1059800042FA97A57FD8EC6736FB977BF8954DFEDA
-:10599000E464F90CCF26A10F29AF92D10788ADC3DB
-:1059A000FF881C93F2E375B1CE0985DB6E5F07704B
-:1059B000489BAF121C245DBEF6C52D0FA21C4E01E4
-:1059C000FA58CF109EFFF12CEE43D86225A11FD9C3
-:1059D0002DE53AE64F94C6F1724D7071771DD97F6F
-:1059E00076D32A43DE8759AF24976BBDCBAD3B728C
-:1059F000B8BFC2AC77CCFCF075EB9DDAFABB4BF1CB
-:105A0000FBDAFA05112CB7143A9B50FE9AE583593C
-:105A10004FCC32C9D9B87E505964A47EDE1AB58BFA
-:105A2000EB093BBDFF3485E73B849CBCBC3135FDB5
-:105A3000612C3F4DE1F90E61340AD14E7D332DD2F8
-:105A400042FBF295A3914E42CCD711C6757A53C949
-:105A50008FD0DA9FB753A7A472BBFC4035AD5795E2
-:105A600086F9866AE29B16B19607B28345B980E74C
-:105A700016BF2505E30B13DCD643E87A691D6F6179
-:105A80000E1687573C2F847914F89EDE29B8FF2C18
-:105A900073DA07919D3A2417F1F17DD81F02DD1FBB
-:105AA0003EACEEDA014B3DEC1B9991C84EEFD603AC
-:105AB000A638F2B1EFBC3A00F9F6CF2CE8CBA5F846
-:105AC00071E3ED181F6EDEAD527C69CE0DAF5D4007
-:105AD00076B7294EA9A63B4BD19FD2A2A4FA509EDD
-:105AE0004838EE73DB49CEB41C4BA3FD44CBDB8AB4
-:105AF000A8BB491E4AB81F807605A33057C94D720E
-:105B000053C21FD6E5C775493C54B3E8E171255F20
-:105B1000695D97F5BEAEFE1EB20F90CED4F83A5432
-:105B2000B795D6D7C9527D38BF90F00FB137D2683C
-:105B3000FF27F1DC2CE851E27985C073E79E333F03
-:105B4000B814DAB7FAB328EAA016318243E71B6E1D
-:105B5000A2130907B96EA08B20CE53AE7BFF9E9196
-:105B60004783F87D7A2AC5F1A5DD2DF30ECCEBAF86
-:105B700013FBF7A5B94AB7DD8BFE8BF6ECF14B733F
-:105B80002B12B417F62EC07B05C2BBDAC33E89B018
-:105B9000F83E2F597EC34DB946BEEB437EC34DB987
-:105BA000B93DC7FD0AF8DC88FDF5159FCD56D766CF
-:105BB00025230E6FB96F2696D67AF2BF99FF243E41
-:105BC000943DFB3EC338BE592EDCA8AE640A8CB3AC
-:105BD0006938E74BB68669941F64E29773C91BC0A6
-:105BE0007F04F1944CEEF415FF3FEB89FF9FF5869F
-:105BF000FFD6ECC013084F1CAA5F39ED0BFF13DB77
-:105C0000A33CB10FA4F1886EBB3219E5B3C9FC18EF
-:105C1000391F9927B317935673757938A53E05F543
-:105C2000441FE863AF7E7E5F037D1CEA9DDFA3C453
-:105C3000A7CB05FE97CBBC8C5DBDE765F4017F4724
-:105C400013E1EF46D5D7152CE93BFE8EF7C4DFF103
-:105C5000DEF1177C17F1D762679F90FD5E55EF4527
-:105C60007AA9F4F82FC77C9DBDEB84DC2901FC9553
-:105C7000A0BDA4925CFB21BB88E4F6372D169A6F79
-:105C800027C8EB87953EADF3BF73C94E095BB3A040
-:105C9000DF1BAF6014DFF36AEB14ACE76BA0A7B5B2
-:105CA000BEAF57C9EBB15E25AF777965CDCB25FA8D
-:105CB000BC1EE9D3A979ACBDC92B4FDE79CB2B4FE4
-:105CC000DED72BAFFAE59D875EED03FC87E0FC9203
-:105CD000C989BEE681029FB27E593DC7879D2EC508
-:105CE000D5AAD39D5C6F3FA9083D5E16A4BADB49D7
-:105CF000C2E280D0F3A776F1F7EAF8C476E588BC73
-:105D00002C9EAFD0B62A6035E49384E9F91DFE538A
-:105D10009EC12AE669BB683DD9D3B81F52AE5FE683
-:105D200069A78BF56417F175671FE379ED125EE9DA
-:105D300062BF91516535EC2324DC6E54030AFAD11D
-:105D4000337318A649C03E6198827EAE4CBFB1BD88
-:105D500084772EDBFAB18A295F35C6F7B9B89F1967
-:105D600081EF75CF13EC5F013FA5983F764D9EF014
-:105D70003FD89917F51153EB7AA523DDFE249847F8
-:105D80007197DEF7270BF364BCDDA8F7DA525842AF
-:105D90003FC327821FC05E217FB32AF4DCC48E126A
-:105DA000CA7759EDD6C8FFA0AA3EE7D4929EDF6716
-:105DB000FA81BD75F0C8AE49659ADEDF12C832D4EB
-:105DC000F36B0B0DED0B82030DEFFB355D64785F1C
-:105DD000B4B2DC502F0E8D35B42F01C0EAEB833600
-:105DE000FF9BA1FD90D6CB0DF5A1DBAE35B4BF3046
-:105DF000D260787FF1634B0CEF87B7AD36D42FD9E3
-:105E00007D93A17D8BF0239BE1F2AB3CBE7F6BB118
-:105E10007239B4CE554EFECD1697D1BF79A7807F8B
-:105E200075C6B852F4ABB7BC53568AF03E903E9656
-:105E3000FCECC9E8C22CD792C953F3F33631DE47E4
-:105E4000CFD82D48D72BF603DF5E0275D7EB9B70BA
-:105E50004D5B86F1F8AC8DF17C2119AF91DF77C7EE
-:105E60006BAC3EEEAF4D77B15B13D0C59D799A51C7
-:105E7000CE0AB929E92819DC243D9E0B6EBB057CAE
-:105E8000BF2ADCDE5078BEAB5E1F3C99605E1FE728
-:105E900059447C39F8873C6E0F8D4A254BDE43FC14
-:105EA00078BEFA40CE03F4C131AE0F8C79BA1FD55B
-:105EB000BEB4F05E0DDB2FE4ED2DBE52C44B327F3D
-:105EC000FAC7026E3A7F7A13F7A7A71AE0F696E4AC
-:105ED00077935FAF25FD73F2A7B7D87DA57DF1A7B6
-:105EE000BF05DF22FC77E771FAE8C6AFF0C727DB12
-:105EF0004785183B84E72198CBAAE9F74DC9F6C737
-:105F0000529EC3FEB814E3B4ADB8FF5212EA414743
-:105F10007E05ED9F491FB4821E74909F801DD2A004
-:105F20007EE3040BBB558BAF5BDAF30EE673DA55F9
-:105F3000C2AB1BBF67DF67D7A7A85FCB3ED39BDF92
-:105F4000EBBEC4AC67CF19EF233B6D1AAC7FBD6EBF
-:105F50007F2DE1638EEF49F84CF3F1F8DD46D08FE9
-:105F600018DFDB97CBF5F446D87F231C3DD901EF32
-:105F700000B4E7E1F9C3888EDC4AE21F0957739C3D
-:105F8000AFAF72676C7E0F3B6E6C7E2F769C5CFFB2
-:105F90006AB17F9EA40E6B433FE6A9989DE0A632AE
-:105FA0009E77D97CD0C62284479EBF2CF1688B6D2A
-:105FB0006A47FD6C63E67C652D03D76F3BC8CF89CC
-:105FC000B11CFE3ECC9CEBD0EEC9A832EAAF4CBF70
-:105FD000517F65D76499F499517FE5D71AF55741F8
-:105FE000D0A8BFFA35959BF499517F1587C69BF4CD
-:105FF00099517F0DDA7CB9499F19F5D7D06D46FDCF
-:106000007561C4A8BF2E7E6CB5499F19F5D725BB15
-:10601000D71BDE97456F35BC1F79F087867A45FB25
-:10602000BF1BDA2F3AF40BCAEB197DF46143BB3185
-:106030001D3F35B40380B763FEF77C420963979E2A
-:106040007CCAF07EBEB0D7BED1F56B433FAC95E7BE
-:106050007187E12FE2EB3D16B4A39162655DCFF548
-:1060600003BCAE8828BE28345BBCFBC94A9CC7076A
-:106070006F4E3988FD2CDA66CCFF5E1C31D69BD979
-:10608000C00C940BCD401711A093A59817AE936F39
-:106090004BD94A712EB06F74B6E8D0158CF249C353
-:1060A000FE76CC7B97EB94F4E617F426E727D7BB74
-:1060B00014ECBFA8165FA71FFEF2FD66871DE976E8
-:1060C000E16E85FDBBD2733D4D7BEEDCD42FC1BAB2
-:1060D000CCEB30DBA13FC937FAC727A92E8A179C22
-:1060E0007A59F5717FA3910F571FE27182D54F281E
-:1060F000E4AF33C343DAA7C9E0A286F9BEA139876A
-:1061000045223AFED3043C1C5E23FF9DC27FE07C07
-:106110001E5023986F94A2A59AE9AD32CA7AC2396B
-:10612000ADD4C8A76638BB7D8509E94A83BF388FDF
-:1061300085E2FCA199AECC705FB1FB4E3BCAC3F3C4
-:1061400085FBD1FCC47109D076A3EC09F2EB245C89
-:1061500061DFFE26CACD64FBD9F7F395F33D5FF40A
-:10616000BE5E0E7F0DFBD933BDE9B94EF4B7817D1C
-:1061700069F6B399F5B0B267FF674A3AF9B53B1CC7
-:10618000C877419F93E7C198F46469A9414F76EFBE
-:106190007BDF5168DFBB2BC36FF5C2FA0E65F86D6C
-:1061A0005EB48732FC76AFCE0E6D01B8D0B91FD089
-:1061B000534F26B013C77BA57D1420BFC9C66ADE26
-:1061C000DEDCEE222F3F27B42FB7D24BF6E7DB659C
-:1061D0005EB23FDD95BDDA9F778838D16D18871C98
-:1061E00012CF0FBA5DC46B80EDFC88B78DB68057B7
-:1061F0009F3FECF666D2BCD2C73CD58E79D42D1E1B
-:106200008B47D1B0E4F9DC1B5CD69A9DE2BB1CC382
-:10621000777C9E2AC21BE06A75593FD7D3ED782F51
-:10622000A3F7C9D639DECBED5E1B0BDE8EF6908C64
-:106230000FDBDEA976A2BC6B617E0F97933E8F3E8B
-:10624000FFC3C6783C78BC880FCBE7AAE71FCBC357
-:106250003A9211AC463C9AF3B06ECCF08FC7E7216E
-:106260006BD8817667C899785F5C23F0AA8AF5823B
-:10627000014A7445F350CF3FFE03F6E61538EE8D24
-:106280006A98F2245BDC95A54157DFFD5C73BD9CE9
-:106290006F75F6D15C3D9D9AF913ECD3CBF11C9947
-:1062A0003FA3D04ADB0EABAF14E1BD19FF3D86FC26
-:1062B000B40BF0FB1E79AFE21C2EECE37ACDE39534
-:1062C000FDECCBF22FF3F27CC3155E9E6FB841D587
-:1062D000F5937E8E7EA49FA30F7EAB35DEC4FED1E8
-:1062E00093A8DFFB0AC75BBC3DECCC5BBCBDD89977
-:1062F0009F1E1B9A81F16CE9EF32B793E722657D0F
-:1063000073A671FC4DE5BCFE4381BF3F8A7B3A1EFC
-:1063100015F3709ACE8B3AA732BAA7439E3395FDF8
-:106320003CEA7553FBB5D9E31FC5F96E2A51681FC6
-:10633000BA295331EC47EBBDD58F225E23A2FF472C
-:1063400005FDEE18C8FD39E63CCC25D8BE024BDE73
-:106350002F9E6B45396657D58470FC9997FB8B2E21
-:10636000878EB07FE9776BBC5B11FB27E3BD08C06C
-:10637000E7AFA481FC39BED546E75E17A8AE4D480D
-:106380008FC9EE39A81F16A0FCA7AF7A7E0CE19941
-:1063900096D553AFEEF776EB55DF799E23FBADF73D
-:1063A0003CE2FD1DA99C4EBBDC2EF29B9BDB9D10AD
-:1063B000F8D92AFC1A28D751BF64A96C65223D730D
-:1063C00042C8D57FFC5C33BFCF23DBE5A2EFCCE72F
-:1063D0009A3BEC1D1BF371BEDF507C787E21BFCE53
-:1063E000B32F3F07CF316AE4E3DB54C2D2ABF07D79
-:1063F0009985DE675EE9D964C3BC6F8D61E63EB303
-:10640000C1386E18C755C0E3385BC357ECCB8776ED
-:10641000195A171B388CCE7B4FF622DFD6F2FC7947
-:10642000F3FABE14FCE1DA08FB0B848796380FFD03
-:106430004B417F206FBE403AAFD6D82E7E2E8BE7E1
-:10644000C1225952BEA28FE76BA761BED3202E6F27
-:1064500048DF644DB014E4C6F94B15F0369FE7767B
-:10646000159CDF79EE197589E73BB480AFEB4F19C6
-:10647000812C1C77C6B875DC1FF6C5D9B36A251AFE
-:10648000C79C4FE07B86FE8A941C2E8753348DE494
-:1064900032F32894E7EAD47C4D584F718DF5A86803
-:1064A000273B785C92CDB730BC5F6582E8C75FCB95
-:1064B00094774BB95F96CB592B7B57D2BF2A805329
-:1064C000897A96FF01FB696B1AAC6782EB30C527AE
-:1064D0005306AFACC6730DCFCEE37DFC30C9B90116
-:1064E00079DEBDFB5C3F7BF8B0E15CFFC6070E1BAD
-:1064F000CEF5871F38FC55CEF54FBCEF81C3FFCCDE
-:1065000073FD529E1D5583476F06F85F0544152A9B
-:10651000C7D2CAEA08DF5E82DB9502CEE1CF01CEA8
-:10652000CE389CAFDA7388E077D406F386F16DE35A
-:1065300039A86D3765445A482E4668DC59CED6498D
-:10654000B8EFECB4778DC0713B9F7EB5280CF2E4B8
-:10655000D8F74EBB19D0DF5BD62E373E3FB9E625C4
-:1065600037C2EBD81A95EC353A17ADCB475A28E825
-:10657000EAD982C01CA4AB796BBFACD4DBE32C940A
-:106580004BFA777144A5D42B29FF963E9626888E28
-:10659000D797B7651BEA522F2F77243EA7FE6001DD
-:1065A00097438B1FDF61EFA7E1F8C1E60298C74967
-:1065B00091DF7072979BF661723E0D8F97D971DFF4
-:1065C000F9D61E078B921FB8DDC6C89FE59FAAE4C7
-:1065D000E13D46FC8F799ECFED4DA3FE16DCAD92DA
-:1065E000DFA91EC60A015C837B16F37DB0691D0B13
-:1065F0008E6993515E2DD8A2B0B0C6DBAFC1FB331C
-:1066000042B7501CC6BC4EB37E5994E4FE9C457BF9
-:106610006EA3EFE733FF6D68CF2E6835BF9FF21E84
-:1066200012F9A273C4737E5820F44E251B7D761098
-:10663000C58F32866BE7D63B27D772267D7FAD9319
-:10664000CA0FD77AA89C53A0111E96EEDEF75C3FC6
-:1066500062F3F64AD44BAF1C6C4CBB568BDBDD951A
-:106660003BAEDB7F3F91BC313FB34EC07DB4C8CB66
-:106670005C24CE3D541CED3D2FB30EE131A2E77CEE
-:10668000A59D5D67F2FB4ABBDB0C8F530727A42156
-:106690007DFC52C26534C045FDEA7049F6DD729555
-:1066A000DF9B667E2EF9688EA0EBF93B676E2A842D
-:1066B000F15B9E7E6F4007D129F75F54087855B88B
-:1066C00036B5E3FA2B98C96F18662F331D3D033D8D
-:1066D000A9A877CC742BE989BDCCBF770ABF463710
-:1066E000BDEEB99DE02BE90A4F3A58D0866351AF11
-:1066F000A5EADCF75C2D6835D63FB2750C4079B25F
-:10670000C8E46FF84849BC7F7BBE60202D76BEE6AA
-:106710009F8CF9170B586013F7CFF3FB714E5A5B40
-:106720009FBB19F97C27E7B3E5BF7AE2BF507E2D06
-:10673000F9CFBBD3517EFDC5DA9A87E32D7B646325
-:10674000BA1FE598359C8EDFFF25A2263C473CB852
-:106750005091F9FA2ECC535B41A406FFCD0F4F4761
-:10676000F9F9DF8FD83CE8876D7ECC1175003C5677
-:10677000ECE27084FADBBC7E0BC1AB79B7912F974A
-:10678000FCC7DD791AF903C2FD04FCFAA1085FB168
-:10679000D34679AD2B5E567D384C33EBA2F599BFCD
-:1067A000C779C4006FCD6D6ABD3DA3E77BB084ECB3
-:1067B000C86FCDBB383E9B77717C359BECD02621D2
-:1067C000B7CDF49F5328E2BA82EE013EE45793F925
-:1067D000B62CC2E577CB4FEE1DF136CCEFC39DBF93
-:1067E0004B5786C5E99F615628C0ED545BE33C7B5F
-:1067F0002FF7F57C24F8A45B2F083DA4ED8689E5EE
-:1068000043750F2F97D9A2E997025C96EDB0F9C2B4
-:10681000F078D913AADF8576D46B0EBA7F62E913BC
-:10682000CFBE3216E6B7F4495BCE54BE0C17CA6F22
-:1068300089AF66A4F3F2387E96FCE2593BE669E242
-:10684000F33559713C2D7D729F1DF33ECDF09CD0E8
-:10685000B6CFCEF9CD84AFB6B727A3DE6EF9C9A700
-:1068600076A487BFEC55587E49CFEF9B763C9B8E34
-:106870007206E184FA45E2AD1B8F3DF0179DFEEBF9
-:1068800051D4CE83719E73E1F1133C835041F4FEE9
-:10689000F35FC33C9A5E77F8100E4D3FBF2E1DD7B5
-:1068A000F39E7525A7FB0737E6A1DE6EB285F33CA4
-:1068B00054F2E74DDBBF43F4B8E8C5EFF0FB9C981A
-:1068C000BF00F919D65B80EB5CF0C055B4CE852CC7
-:1068D00048F4D8F420BFDFF08C95D524DA0F3C249F
-:1068E000F8E6BD871DB47978CFCEF87D217F50C5FD
-:1068F0007D58ABC85EF98E58334868AA9F71727C88
-:10690000AD2E94717F2EDF9A45ABE69DB7907C7BD0
-:10691000BFC89F8FFC0F7030FA675F9C942FE422F2
-:10692000DDEB42DF01FD4DC0E7D8BEDDE64F19616A
-:10693000F84EE4DFF2F1AF17E3C3BC53D1CFF75EFB
-:106940009E719F2BCB2385D2AFC6DA999ECE92C97A
-:10695000819D5B88BE3E7999CB9915919935F4BE9E
-:10696000DD16CDC7F7917D572A2427C00E49C4E70D
-:106970003B6D82CF8DEF619E56450FDFBDFCFC9EC7
-:10698000A4978577417B1D5FC7E9C71E7F5E12E72D
-:106990005799BFB1C864CFC9D22C27EE33C909F9C2
-:1069A0003D7B2037E1F988B87C0813FC96D9228F0B
-:1069B000FE3BF2F56B0E3A17B9EC091BDDEFF3C1A4
-:1069C000E3FB5FB916E8FF8336C9CF46F96BE6E70C
-:1069D000A6A7AE6289F8F9839C004BC8CFF03C2192
-:1069E0003FE7F0F306FFB7E4EFA224F2F740614F70
-:1069F000BBE352A8BEFFD3A5C5B43F33C157C2D530
-:106A00002C4F67A3B190DB539EC29F97990E9E12A5
-:106A10008E924E97FC6C398DD34DCF925E253D778B
-:106A2000D3AB79DD46789ADFDF827BA7DC38FE6D59
-:106A3000EB615F8EF1DAA755CACFEBD4BAD2B3605F
-:106A4000DC8D22BFA7D323EA99BCDE956BDF84F2ED
-:106A5000443EEF4AE1F90E9D81AEF44CDD7EE0ED5F
-:106A60003D6A3A9E07E88824CECBA08C0DF483249F
-:106A7000C9DB90E77E3B53B9BFAF3395FBF926A93D
-:106A8000AE0121DCDFB5F2F8D2FC7557A7E3FEBEFC
-:106A900073CFA019B5B81F38A4F29CA3B0DF5A0079
-:106AA000F06DE44B672759F89E7168BFEF593A15AE
-:106AB000FB99BFD5089785AE9D76ECE70C5B43E567
-:106AC000C2BB6C713A81FF9660BE16D2F903A6E78D
-:106AD0007B2E23BA5A62A2AB20D25582F32419FD31
-:106AE000045D95B132BEDF16F13121F726A9C366E8
-:106AF000D4623EE5417EDEE3D41E956DC2F53E2EA6
-:106B0000E265E15CA2D71540DF7ABFE987487743A9
-:106B100093EBF90F7F79ACF26668B2ECBFFE34E21A
-:106B20007E283FFCAFD72EF80DD67FF5EA803FB127
-:106B30009EED27ECFD6C2EE575EE75D0BDA69D7B18
-:106B40009F1F7033D67FEDA0FB453BD7F37D767852
-:106B5000AF9BF47F6711B7175B9EFE744407E92F64
-:106B60007E6FF0D87EFCBCEDA93D7F7B53C17CBE1F
-:106B70003DB02A948F62FFD6FCEB14DAA7773EFD76
-:106B8000A9617FFA55D7B3429CBBEA74B35A3C273C
-:106B9000DD99C9CFA936FF66CC8FF1DCE5F25DFB4C
-:106BA000EC8DF07EC2FFFE7204CAA1CEA7B8DD0153
-:106BB000F6F076E6033CF46BBDDD06F8FB086D44A9
-:106BC000E09937FBB54FC3F3243DE1C2E1D0097032
-:106BD000C075015C9A507E268347DDBF2C3C3E9EEB
-:106BE0008BE32FDB339AEE198EC345F1F3E76ECAC0
-:106BF000F780F5F3E77B3F1D8176D4B9D67B533F11
-:106C00007EEEE77FCA7AB7FDCBAE97D3BB864E99AF
-:106C10008A9E74DF93AE7F7503D57FEEF6D17CFB41
-:106C2000C8EFBBFF87D1F72BFFDFE2FB90C0B7DBDC
-:106C3000837199CEA7BF1CC0CE63DD67FE65F1DC12
-:106C4000FBBABBED1E8BCF390AE6F73A8B5C55AD2C
-:106C500024CF1F1DD85FFA1FF83E43DEC33D3D67BA
-:106C600021D911D3FDDC1FD3C2CA0FE239BBB05FFB
-:106C7000A5F80525EF001CDAAF2C8B509E98353C0B
-:106C8000E41ECC1B9BB5DCC7EF2B33EEBFA6E7D5CC
-:106C9000D4A03D77641DCC0BDA1D715B3C2DB08414
-:106CA000197E95EC3F28C9EEFBE3F8CB280F65462B
-:106CB00095711F72AD693F7175ADF1FD2CF6702EA7
-:106CC000E6FBCD6AB2517ED255E6FD477F0FADF3AC
-:106CD0006AB67223F7E79C1F9C2EEFCFF7633DE166
-:106CE000D03BDC7AC049EC37297748EB093747902D
-:106CF000EF3F1DF042D85B222F6F759FE0C9C4BEE5
-:106D0000D4218696F075F8F9BDA3BA7E092E12EE4D
-:106D1000E70B6F892733DC257C25DCCC781882E7EC
-:106D20003D2BE2F08F97C67BB599B01BA777DB8D23
-:106D30002E82E30B3BF9798917AA1AB79661FD7188
-:106D40007E1FFC9971239913D67BC4C676535CC809
-:106D5000EFD73C95F1FC19A5EA798A4F60FEA27E37
-:106D6000BF8AF98BFA7561FEA2BE8EF98BFAF6988E
-:106D7000BFA87F8FF98BFAF798BFA8AF63FEA2BEBA
-:106D80003DE62FEAEB98BFA86F8FF98BFA3AE62F12
-:106D9000EADB63FEA2FE3DE62FEADF63FEA2BE8EC3
-:106DA000F98BFAF698BFA87F8FF98BFAF798BFA8EE
-:106DB000AF63FEA2BE3DE62DEADF63DEA2FE3DE646
-:106DC00029EAEB989FA86FFFADD833867A35FB9DF3
-:106DD000A1FD04E74B86FA24CF9F0CEDBFED3D6E7D
-:106DE000783F45FBC0F05EE2FFB2D2D386E718FBE6
-:106DF0000857E23E86FF99E6FB9BA11F2B0B509C98
-:106E0000D4CE5652E9447F2F94A9AC8D4A17B0399D
-:106E100096EF0D0D3EDE1FE9757B781312D7913189
-:106E20009F0E40F9FFC2B82BB85F42C41766E03F1F
-:106E30003520E2B42FFAE33E57C64FD3632A8B8E38
-:106E4000043A8C29547A62692C9A0D74184BA13239
-:106E50002B964DCFB3639954E6C4FAD1F3DC5801B5
-:106E60009579B14154E6C74AA8F4C62EA6B2207659
-:106E7000219585B191F45DBF581995FD6397D2F3C3
-:106E8000A2D8182A07C426D0F3E25835955AEC3216
-:106E90002A4B6253A81C18BB82DA0D8ACDA47270EB
-:106EA0006C363D1F12BB86CA0B628D540E8DD553B6
-:106EB000591A5B4AE585B1C5545E14BB8EBEBB381A
-:106EC000B68ACA61B19BE9F9F0D877A91C116BA108
-:106ED000F292D83A2A7DB1DBA85D596C0B95E5B1E9
-:106EE0001FD1F391B13BA91C15BB9F9E57C4EEA3C4
-:106EF000B232F6632A47C776505915FB199563627B
-:106F00003FA1726CEC17F4DDA5B127A91C17FB0D8E
-:106F10003DFF46EC7F51F9CDD87E7AFEADD83E2AB2
-:106F2000FDB1DFD1F3EAD8212AC7C75EA2E7136219
-:106F30002F523931F6277A3E29F61A959363C7A95D
-:106F4000FC76EC6D2A6B621F503925F6172AFF2D4F
-:106F5000769ABEBB2CF6319553637FA3E7D3629F2D
-:106F600051D9BDFF1F97F477052C6771FFECCAEA72
-:106F7000D37D6577A6A5935C9CBE86CBC57BD33EAF
-:106F80003A4072728C437390F0DB668877D18F48F9
-:106F9000C0BE6FDF98F7FAA3BDB3A9FAF81BD7A15B
-:106FA0003E5BE560429F99E4EE172EE1EF64988F17
-:106FB0003847D0F50B55FB73D18EDA54DEB10CFD9A
-:106FC00026B79774D4615950C4ED098F28F38B7894
-:106FD0005CE9EF43B9FEAD5B3584FFBE404EDFD6C2
-:106FE000374BE8EDEEF6033C5C5FB8BA06D079BDEE
-:106FF0003EF6D3D776E7CAC3FA5BFFE0F0A2047986
-:1070000058F1F3837DEEA7F26BEAE75B7DE9E72DAC
-:1070100081F7878A02138A101E56FF087C3F7E7D07
-:10702000818ABFAB52BF55F120BD346E289B8C784E
-:107030002D677EF24BCE49924FB658E0B561A58DD3
-:10704000A17FB24163E41F6ED8C5F390D19F3A0D82
-:10705000E8A549D0CBF22D1F93DFA969E5229EF761
-:1070600014E1FE29F93B364B5B773C876EBD33EC70
-:1070700030E5C72F7DCCE8BF6A16FEA9E56DA6E70F
-:107080002BBF9DD0EF69F64B3514093FB28FE73D1A
-:1070900031B53FADFB0CAC1BF3498237B89DA83727
-:1070A000001E14879170907E4F090FD6F3DC05E522
-:1070B000AF9E3A3884F2E44E695A3EB60BA6F3DF2F
-:1070C000B352ACC1D1F81CE048F92C5DEBD2281FBB
-:1070D000EA6DD0031A265E7982A3F1FEB88ED78BB3
-:1070E00098B8BFD2188F706EA53CF17A9803E6A5C8
-:1070F000D43F924DE736A1BF11BBD1AFF9888DF2D5
-:1071000091C26CB59755F58C570436DA882E1A76ED
-:1071100067F2FCB4B0FF653C5720F1F2F68641936C
-:1071200031AFA961734919B9EB76DBC83E94715947
-:1071300089AF9EF9DB3C5FA099453661EA12E0EB2E
-:1071400044427CB5EE23BC02DE4E24C1DB89DEF076
-:10715000765F91F027FA64BEDAB08CABF1E59A6CF9
-:10716000E2E7BAF5D1212B75F469F6FFB3F963E9CB
-:10717000DE1399FF5C53287F67CC9787F83DBDB538
-:1071800082F066C657CDDF1B092FEC7537DD3B3C1F
-:1071900067109B77393C9F27FC9E735AA690FDFD94
-:1071A0005411DF17BCB016733F197B71AD93F9C151
-:1071B000F87E69AD87EA7F5CEBA5FAAB6B352A5F99
-:1071C0005B5B4AE5093BCF2B92FC058440F97DBB14
-:1071D000055FED2E92F19FEBBDE8E7AEF9FB4B1595
-:1071E00016127DC7A64F2A22BBDD902F527BA531F8
-:1071F0001FA4C326F2CDB6283EBC4FA62170A9A17C
-:107200003D2B1D19AFA3FE11F92B0D9B33E91EBBBE
-:107210006BA6661BDACFDADCCF506F2FD2F87D6A0F
-:1072200035830CCFAFADBBD850AF17BF1FC1B42A49
-:10723000E21B19FF02CDCDF1E2E16D3F59393AFF72
-:107240004618FF93C3367A6FC6C7097B98F6F3E1F9
-:10725000871D3E8CEF9DC4F36F503FF94795F28B2D
-:107260004EDA58D80322FEA4C23660C9AC9CAFCE19
-:107270001CE57C55F37795E13E9EFDD441F1C1C6F6
-:107280006D0A0BE3DD0C5D007918F7FA9F3868DDB5
-:10729000F3B7A92C48E7ABB4368C935FFFC8501FF7
-:1072A000C647E70C8A16E179C3AE5FA6F8F0DC5753
-:1072B0006307FFFE24ECCF33313F4A29A778C45F30
-:1072C000A7B52EB460BE9D7A3817F9F5AF4FF1DF40
-:1072D000355BBCEA8F951E80F392E7DA5EA9827176
-:1072E0004EB4AA34EE078F3976A8C4F7FE7CBCDF13
-:1072F00036BEEE08F929A614063E43F9FEFEC2C8C2
-:1073000008923F6BB87FBC277C60BD886FA4579DF7
-:107310003C8BEB371E7F0321548072A2D1E6A3B8C9
-:10732000EC89AD368A17823EA07C8313ADD9162E28
-:10733000879E22BA6BB06A76FDB80D5B553FFF7D24
-:107340000CCD8EF36577AA41361AEB3C3F22BC592F
-:1073500009F2F88F11BFD7AD1A4DE7A2CD795CB213
-:10736000FC08782AA88B2B2D799AC77FD9A80EAB59
-:107370003ECF5DFA6758B0CA709FD1B281F7FE6008
-:107380001C94A7FCFCEAC5333BDD24273FB43C53E7
-:107390007923941F4C0BBF6B05BCBCA806870CC09F
-:1073A000BC21CBD6ED0AC5558EFF00E3FEEF3F6151
-:1073B000F3111B8ABCB1253F5D4CF1A9E4F602F341
-:1073C000F2F875344FF1E2EDC48CF24566B336E164
-:1073D0005F88F03C039C04C0C7B38CC7C58E57B808
-:1073E0006FC5F3C38DA6F3C6C7C5398BAA01DC6E82
-:1073F00092FAFAC6015C0E345A387FB2BDFC1E4ABE
-:10740000F97B71528E4B792BE575CD009EC722E535
-:107410002C636D245F168AFB92973DE6E0E78B3480
-:10742000E641382EE668621B0770BE5E627FE21E90
-:1074300024EB45AC9DF4DEFBB6C8C2F612FC7EC759
-:10744000862CFADEE68B201F47E4EFD159498E2CBB
-:10745000627C9ECB5B954854E7EF90BF4FC2504F84
-:10746000E8E44E0FBD60D2070B84FE5BC04CF946CA
-:10747000AD463D154873D3BA96B48A3CECEE79A973
-:10748000EC2CC6BB8291E7A6D3BC155F24C13C1689
-:10749000B1AE28DE8BBCFC717E8EC93C2FF33AFA6C
-:1074A0003ACF85BE9913F17EE5EE714DF396F06605
-:1074B00078B04A870709F785610ECF857B14C2D75C
-:1074C0009F85BD25CF079AF1BF8805A6A39C5B7455
-:1074D00017EC334BE2F420E960F193113A0FF80115
-:1074E0006B4D77013F2CDBF6E4AC31F0FDA2075E7B
-:1074F000B423BDD7654587583261FF199E70474D4B
-:107500005102BD6FD2F35F179C98F05BD177009763
-:10751000053B55CAA3D0B513790461E287A630FFB5
-:107520003DC1A697555F0B3C6DC29F392A3FFFF9BD
-:107530004AB8FDB3E76DB66B760DE8DDAE31CB9B97
-:107540001E768D499FE2790ED49F5DB93C3FFD13B5
-:10755000AB3F238BE4B4490EE796D37DAC520E2F9C
-:10756000147A508EB300F51FD4DFDDF68B74F46708
-:10757000FCF9AE5FE451BE06EA9B61717D73432363
-:107580001FEF865FA550BED45FA7B58F407BB0EEDE
-:10759000C1E7D3F5F7BD7E5010FC03CA5BA91F9766
-:1075A000AB3B06E0EF1A4A397BCE7D5BB275BACFB2
-:1075B000B14EB7719D0DB84EDD399546B1CE7736D7
-:1075C000F3F51DDFCAD73BBFC73AC31457B9E1C7AC
-:1075D0000E5F98EC8E28E9F5934FAA0CF759DD76EB
-:1075E00087C90E38C35AB7233C96AF7EF54D2BD0D2
-:1075F000C5E20B003E400775773A48EF2FFE258F16
-:10760000A7BEAF54E75340FF4034FDBBF07C09D820
-:107610000B686FC4E7D16D077C3E406F07F4117EA5
-:107620002B845F6BC59EE7E977B4143FCFC75C211D
-:10763000EFB5D96DBAD7464319C0CFF93B114FFD0D
-:10764000CDF77171FFEC7F0FF978EE6AA2FFAE0BF8
-:10765000F4E7D89A53A336CC43EE7A52213B69F92A
-:10766000F5D5E9D50CCFB771BF5A7E31D76F8ADF18
-:107670004FF9350EC06B2A8C5758ACF1FBAF340F65
-:10768000CF377F80D13D3A72BEE6E7E86F77A23E02
-:107690007459481F9AD73FA598EBCDE5AA85ECEB26
-:1076A00065766E67778AFB2B868A790C2DE6796082
-:1076B000C38BB99FA113ED4A8C777FC341BF63C4CD
-:1076C000D844F2BB5B19A73FAB849BC7FA51377F05
-:1076D00093FDDCD51FE13497B5D3EF224EAF9AA9C5
-:1076E000E1798637F39C744F14FC09603FB3453F42
-:1076F000476CFCFCC29B3806AC6BB6F04FBF89D719
-:10770000A3C2F86F16D8C9AE0D3FED20BBE1965469
-:10771000EE3F64391956E4876B859C9A33CEE14776
-:10772000B93E7BDC2D012CA1BF300378D539BB36A7
-:1077300096C138EB2C5CDFAFCB62DC2FB0A1A3028B
-:10774000E1770998C998BF0FABDF7536BB373A327E
-:107750009E9F58867E86B18C135815C1D7505F66A0
-:10776000E7EFE73DF41F33EEEACFD81F306B0AF5A1
-:107770000CC208E9A23E83F6BF33F07C4116965650
-:10778000A2B7CBAD2C6CE1E56617DDABE435FC2E82
-:10779000EC55552C9A01EB8B1E329EEFB83A6A8954
-:1077A0000EC5789135BA0FE167716A360F8C13A850
-:1077B00051CA11EECBD6F76DBEAB1F7A6AC65DE338
-:1077C000A08EF779E13CBFAB50BED06C607AA4D3F9
-:1077D000B95676402DE7F8433A6CCED2C2D46E1536
-:1077E000A77379AE44E2A50CBAD7C377B6981FF455
-:1077F000B3391DBFB727F6AB7CBF58C6E3B8BDB6DB
-:1078000054F0ED5249778F1BF935827C83FC84F666
-:1078100021C06DB62893D1FD83822F1E2CE6FBCCB0
-:107820002DC5729FD9B7F1963B5894D6FDB483F01D
-:1078300028C79D21CAFB8BB9DD29E721E977215BA8
-:1078400049F93C0B859FC6029284F2835B7FCCFD95
-:1078500042A6BC23309428BF6DC94EF3739D9F4749
-:1078600035C825F29B2AF6AEF9383FE59B293EA4A0
-:10787000F7D9F636F20F98DBD9F0F75331EEB61997
-:10788000EC2A45C4CBA0EED8AAD0EF5ECCEEDF3513
-:107890001CF53948EBC9742E54D8DB0B057E1DE26C
-:1078A0007EAB85685F615C0DED2B84D7366E575AD1
-:1078B000853DDCB0D5686FCCDEA0B33B7961B81FE5
-:1078C000C061CA53B709BBE32D7BD77094FBE6FBBD
-:1078D00002DEB2F07584F318BF573387BFB70AFBD7
-:1078E00052D2D513C53643DC4D9E3BAD4379C5EF2F
-:1078F0006D30E569B9E8FE983A85DFDF29FD906FC4
-:1079000088F214D8A1745FCEB1348A839BFD939D15
-:10791000D5EEB045E7A79C9371C374844F5DBADD83
-:107920008AE51BDDF78A75D0F8C73C03C9FED95438
-:107930003D721BE627FDF9A153339C45144D11E719
-:10794000A73E7D01F3E9AFFC02D643F5D80C3F8E8C
-:10795000F36CD75C2788EEBF157F36C30A7ABEF377
-:10796000EEAEED58776B9600D56FEF1A80772EBB91
-:1079700023765E5F27FBB307304FB9F33E5E7FFF90
-:10798000217B00F39FEAC4B9A5BAB10AC9DF54C18B
-:107990005FD2CF5467798697E3F9EFA29CAB5D9EE7
-:1079A00016482DCEC5FB504FD0EF2F940CF4A716E0
-:1079B00043BBF401C133582E99A984ED78DEFFE56D
-:1079C000C80542AF25FC9D9054A1A70A4A02F4BD08
-:1079D000F4A3433F7FC7FECFD5CFFF016BCEE90AAB
-:1079E00000800000000000001F8B08000000000065
-:1079F000000BD57D0D5C5455DAF8B973E70B6606BC
-:107A0000464003F9700604B140470545A51A011127
-:107A10003FD041CD2CAD4634454341ABCDDDDC7785
-:107A20000651336B0BABB7DCB2763273ADD75A323B
-:107A3000412C3F06B5D26C6B4C6AA9D4C532BFB29B
-:107A400022D35DFAAFBBFECFF39C739939D7416D5A
-:107A500077DFFDFD5EFCF93B3CF79C7BEE739EEF10
-:107A6000E739E75E2E5DA23F371312D94B43482E0C
-:107A700021BFB7B9227B752764FAC2F46877162153
-:107A800051296E838DC2F3CA24AFBE3F21A4C5978E
-:107A9000E1B210329E1067BD99904BFCFE4BAA7963
-:107AA000EEB35F368FF59F99E74FAA79EE94E8BD64
-:107AB00043E97FE2B0C1FD77A439B360DE7BFE8B82
-:107AC000B8611E52345C43061372AF91E0CF8FD57C
-:107AD0005B338C39B4DD648825763AEEF56D29B3D5
-:107AE000E93C6431BD2981906F9A3FD3DBE83C0BC0
-:107AF0003A64E28C25A4AA43C276C196667D311D04
-:107B00005745DBC210FC2A39BE84B469275A82D794
-:107B100007D828BEDDE1FA6A6CEF79FDB4D64DC70F
-:107B2000DDA3A93FF16C1CBD3C4C72BC6CBB7C9DC1
-:107B300009FCBEA38494D4675DDE3FC426617F5DEB
-:107B4000BA7330AC339ECE01B0AC61EB558FF7F217
-:107B5000F9A64792BB5CB47FE6608BD146E99DDB1A
-:107B6000E2AEB5503C66AFB50F94E91C03520A9CD7
-:107B7000301F99354CA057494F4202B03E6D7B0FE4
-:107B800042DB1FB7E746138AD7F498C07D64002113
-:107B90000FFA32EA8CC9848C7D868EE989B7380960
-:107BA000BDB7C4C061EF8DAEA27C0AFF4346F84E5C
-:107BB000DB903A2F9D671FE043E7B963487624E9DD
-:107BC00047A9673769ACD1F4E6E4190F021E770CB8
-:107BD000B9B118AE8F30583266207D09CA8733D9C3
-:107BE00035C596CBC613BA0EB7DEDFFD56BA0EF713
-:107BF000FBB2C34BD7E1EE6772FBC2D06D32A7C3B5
-:107C000083362BCAD13E0DC57360100FE5F9845839
-:107C1000EF0BD0F98E2F4D18B08ACEF7BBE411BF11
-:107C200082E729CFFF5DB27B4EE8F32946FDE0FAFB
-:107C3000B5E2318BE3F12BE01B9DC7954FE58CD36B
-:107C4000FA12FD3FB1C824C093C7C5126766109EE3
-:107C500032395180A74E4F13C6DF3EEB06A1BFD489
-:107C600010C8A93607E55B8D8FD25246215E559626
-:107C70008D5184A27864FB854FA7513DF97EBDEC00
-:107C80009028AE7377BCFCE9703AEA1C5D702CA5B5
-:107C9000DB392705E87ACF6D917D5E3BC887535B62
-:107CA000DA83900A988A8E9FBFFF4DFD08FA6B45D4
-:107CB000F59C71C0C7B93EDD976D21785E2017F540
-:107CC0002495EAC346F17A1579F407B91F407EBDC1
-:107CD0002B9BCE53AFEAAF1E759244C138ED976D22
-:107CE000CA3AE9F3171FB63FB63764DDCFD92C7116
-:107CF000276EA0BF0C24032FC9F0BCB3EFD215929E
-:107D0000C2A666E453ED7ED901225A9B2C1189AE9E
-:107D100073D416832F82AAD6B7DB8EE96D945E7F6B
-:107D2000F5D81EDBAB03FDAF212416EE3BA66FA3F7
-:107D3000D787DB6C48A705DB7FD013CAF751DB1769
-:107D4000A25E17533B164DE527D04CB2B7D0F9BD14
-:107D5000768BE3653AFF3D2B4713328890E88E69B6
-:107D6000D856D68DC6F9E6774C4278418709E17D31
-:107D700091816242F1D8D7D88DD4523C3E92FD1900
-:107D8000CFC13C060BDA89D2C43B96C2BAF7457A1A
-:107D9000B3EEA5CF2BFDC3A812A0EB822D9213E466
-:107DA000AC5426FBA418C03702E72B953FCE5948A8
-:107DB000AF8F2DB47835D1D84F08ED97075B5611AA
-:107DC0000ACB7A6A2FC2C8E77BDCBEE8DA18DE236A
-:107DD0003BCA703EA5FF8FB654945B05D6755FAF66
-:107DE0002D3707D7A36B93B01DD37103B6555BCA6C
-:107DF000B436FA9CF7335F8A033AD1F1667758BB01
-:107E00003C249A84B15F4A6BE0F6781AD8633AEF63
-:107E1000DE54E757A087E397B4698D604FCD46EBFA
-:107E2000CB540EC6E70DB0CD0E5997BCFB3662A3FE
-:107E30007264886BD739E9FCD3681B6ABFEFEAC26A
-:107E4000DF9CEEB4DF35B85EC52F91CC2584503968
-:107E5000BFD3CAF056F4EA533E5EB93F2031FDF07D
-:107E600036187C2FD3DF8FA4BAFF06F8064690A9F8
-:107E70009BD19E0652CA2CFF3EFC297F8DC0FF2855
-:107E80006D1B89017F6657F0677A7D35FCBFB33182
-:107E9000FFFA914C16835C7C74F3CD0127C5ABF9D6
-:107EA000C14183C03F28CFEB66D7E338626DBF087E
-:107EB000F25AB5D3645B45D7574A790370FB0E83FA
-:107EC0006F9D1DAF13290E5AC33A89F65745B56702
-:107ED00080FF29DC15E107B96DDE15A1053FF24EE3
-:107EE000BABB9BBD3B5CEF532451F9766E376841BA
-:107EF0000E7AD89C3170BD2B7CAF66C7147D54CBF5
-:107F0000997B25D33F37D7C3195C6ECBB91ECED032
-:107F10003AA21FA078DFF5814CC08E972F91B2B79F
-:107F2000E4804DB338D243F450D1371DC8E52090DA
-:107F30004F2697951DDDB87EDBF9BC4C0F4AA9830F
-:107F400006FA94DED0CD07FABDA02316C729FAAAF7
-:107F5000E869629A7B04ACBBB496EA377D8E7B6994
-:107F6000420EE84B504EF45690272A27F1B343E4D3
-:107F7000A0B6F9272DC8892E5F423931D0B63044DA
-:107F80008E5C9D718AB5B807C563FC32BB66150966
-:107F9000F617DB19FFAF55DE0771F92A37FBD3352A
-:107FA000743E5D75846329C5EB5C9C0DEDD8A2879A
-:107FB000294049B048E72A843863D16F2507D85F44
-:107FC000883FC0FE0C6EADD6BB43F0BBADA31FB166
-:107FD000513A4DEAE88DED8014F7647B2EF0670A84
-:107FE000A7633F6C892D4F03F8DC67647EE67CF560
-:107FF0004377C2F3CEFB0C0E781E21798CDF1CDF99
-:108000005CA7E3BA0700BF0F74E4453AFE54845BF3
-:1080100006BD3C954CAC4F521467AEA17CA6F39EB6
-:10802000D211AF95F2731685DD007723CE6E034132
-:10803000EFE83A43FCCA056D5D0A49A3FC5DF4A76D
-:10804000A35A6A0AE76604FAF9E973A78F60FEFF8C
-:10805000EC7A1DFAFFCAE68F076B68FF19BBF33A8B
-:10806000426DEFE89EEE05C0D779137DAFEB287C1B
-:10807000CF6FDE8C1A6A0BD2B35EEB4FD7D2FBEB1D
-:10808000291DBD14AFFA47E5121F8B7B4C65D957EC
-:1080900097EB791D69481FC5DF28F67BAB279E2E1D
-:1080A0002268C7AFE68714F99ECFF5603EE8010964
-:1080B000F53765AE1120879992239D84FA1BA60F90
-:1080C0008A9DA6F28E7A539A96ECA82541BBADF60E
-:1080D000477BE4FA2787D1F52E4D75FB80DF05FF3E
-:1080E000F3B7373FA75D959B5F29023E8DB84122CC
-:1080F000B2742D76F2271DDAC9256504ED246D438F
-:10810000EDA4AE8B38FD65FBCFB3F34FF2F134BE77
-:10811000C5B811EC78E87C47520BB6C23AB6DB25FD
-:1081200036DFBF096FB57DDFDEA9AFD766DF5FE55C
-:10813000785FCDBE7FC4EDBBDA9E133A1FD8F3EF54
-:1081400077F4F581BD3F4AA8FD07FFB6DD647B9952
-:10815000DB7BF40791D1BE2BD9FBBAF4991F756173
-:10816000EF0340B77FD5DE2BF2A5D607B51EA8E5F5
-:108170007EEC2334FE023E6D9508D8D760BC455096
-:108180008EF7A5323956F42624FE423F4FF5C197AB
-:108190006EBF5C2F7FACFE538E0DF2CD1CCB002248
-:1081A00005E55DD11745DED57E644EAA5B4ACD0D4F
-:1081B000EA49E566B51FE84A9EB6E9207FD555FE37
-:1081C000C0FC006D43FD4057F18E3EF5E7E9C179F3
-:1081D000FBB5C50B09A97A9CF77F519E12804E61B1
-:1081E000E4A967EABF204F57E023FA1945CEC61E1F
-:1081F00060F241D258BC4FE505F1DEA74FF6D5DA63
-:10820000C1EE317B38F612A9067ADEC5EB098ABCCD
-:1082100016A5B96F0AE533C4F710B75F6B5C382D4C
-:10822000AE9A38E9F5BB681B6A370CC0BF30F17DE8
-:1082300061EACFF3F30352AF8DCF93399FFF8D7176
-:10824000E15DA961EC047132FF1FE48B6112C8CDBE
-:108250008F7E2D01FDEA8AAFBA358CEE0ABCDCAF09
-:1082600055FC6B2CF8572A2FEED47F21DE2C2DAC39
-:108270003F6FA4A1DF7FAD1B5EA61D4AF3F43CC295
-:10828000EB1FF9AB9D5AB02FF4F7613823D6473E68
-:108290009239ECBDF16011C563EC939DFD5EE81F62
-:1082A000991FDD594F81544219FFEB75C30E3E8A69
-:1082B00078D7313EBADBB4AEEC103887C2961038AE
-:1082C0004F05AF65E3C18F58711E1FB3F7747E6908
-:1082D00020C0CA7C5C0F487B71378817B74856A806
-:1082E00087DC9EFFBD1EF8535AD8F66E225DEFEA7A
-:1082F000754565E6BEF43AD8418AEF8BEBC6ADF61C
-:108300006AF9FD3DB03E863F867AC929533E55E65F
-:1083100049BE54FBE5747C3155F467F0A315EF2793
-:10832000FA9C9F773FE82FDE9F8AF7FB0D3FE3F92A
-:10833000B7E613A72F8C9DFC8362272F5258999F75
-:10834000D26E523DCBC3D5E3B7F2F1018D663EA1AB
-:10835000F4DAB5CEBD1AEA652309938FE6757795F1
-:1083600079991C12A76ABD57C2F7E55431BF831F24
-:108370009B78BFFF4AF4FA9FCBE8C5E5A3429497E8
-:1083800068AD6BEF8F148FE838C90A71ED0257C4DE
-:10839000A310BF97162AF23DAFCC9944D71741845A
-:1083A000FA5F50BEEF292BA274594094F1F3578322
-:1083B0005F72693AC73379DF2E75DE9F49E5074B57
-:1083C00071F4FE2FD655AEF666213FB01F61ED1554
-:1083D000E4BD5E05E7ABF483CB37EA27D86D4A9F4F
-:1083E000F43076A383D3E75B894C05BB172860F193
-:1083F0005E2095B5F1692CBE23696C9C318DF339F3
-:1084000032840E49413ED31F3FE41121EB463ADD51
-:1084100016A7ACFBD1B271745D8118922D513989C8
-:10842000495BB97A59889CC4A53D8A72129C6FD564
-:1084300041A0E36D9C4EF1698F1CE4722481DECD76
-:108440004781A072B045F2CA749DF3410EC2ACF3ED
-:10845000CBCBE5C8ABBADFA9BBC2FDA72EBFDFA956
-:10846000BA9FE8E27ECEFD9C4FE3547C2C51F1B1E3
-:1084700048054F57609F60CF143B57DEB47A798F21
-:1084800038A8374AE026C05EEBA5018464BFF4DF5C
-:1084900065E60490579B2E91DAFC012F3D73D0487E
-:1084A000ED5919D83394DF35AB9DBDA97E83BE232A
-:1084B000FCDB32677F909FEAE5F174FC90979E5D4C
-:1084C0006DA4436F5FB65A0731CDF097D6AED6D2C2
-:1084D000796FCBF9C3BB309FB6E68583E3A42BC885
-:1084E0006B9D6A1D6B55B05735FEA9ABD8F765AAD1
-:1084F000FB97A8FA1F55C16B54F04AF1FE19B3243B
-:10850000D49319947F40B8ABE94D595A679ED1E98D
-:10851000CF2433C64982DC8FAD65F0B4973695AD74
-:108520003487C069AF9781BE2B72AC23EC675A1CAD
-:10853000F182FFD07561CF46A7752147996A7FC741
-:10854000FAFF0CBF26E03E8BE097F7C822DC2C2B0D
-:10855000786F3F785F165C54E0B7CBA07ED1E5BE64
-:1085600007D95606FB1E631FE7B0B7A90CE23465B6
-:108570009DCAF8E2BF5F92E1790BD39ACAD6C3BE17
-:108580004A813F1DEAF5D363584BFD8C0C7EAC8AC3
-:10859000D73B8A77C82EF033D323FDE98BB242D67E
-:1085A00049EA33609DCD0FCAC81F6F2DCB47CA89DA
-:1085B000430FF58AE6E8E8C51BE8F83D0FCA8BC112
-:1085C000AF1D5D1CDB03F289DD692CDFDB13DDAB46
-:1085D000C7DD146E36DDA5877A6DF34323B1DD2D3B
-:1085E0003B57B453397EFCA5F7D0CF379BA2913EC1
-:1085F0008FA4ED29ABA17AF1589A0DEF77C7587B7C
-:108600003441BCBA4A47A05E4D88E305949BDF180D
-:1086100006ACA278CCA8B901F78FCAFFBBAC3881F1
-:108620008E2B5FAEC37D05FAD30FF076AF1AA98704
-:10863000FE59CB78EB1D85EDAE7FBC79A01F1DDF09
-:10864000FEB0EC584707EFEC488D2AA7787D15C19E
-:10865000ECF097677B47019E7D7ABB9F4DA37C9D85
-:1086600011658994C079586D5113E9BCBDD39DCF74
-:10867000A5E506C7EFFA878CFB606F9F2DEF01FC25
-:108680007B99DBEF9D1DE53DCA43FCFDEC6FB548D2
-:10869000E75D7ADB7D105FEE8A4C96BCA8C7F5B12A
-:1086A00050B79DC5E36B2A2F8BDF0CE3F79F4893F0
-:1086B00071DEE386C5E42B2AC4CD8F74CF073C95C9
-:1086C000FB94FD375D926D60681CBDAE57C11BB059
-:1086D0008EA09C1D3D087283713485B7BFF4F96A82
-:1086E0002FF8C23D34FE073CE29CC5E007C8925813
-:1086F000B60F1A5F9F115A8F08C6A94BB93D60E3A8
-:108700008E782D98B71ED914E1837CE688F70B4B41
-:1087100068FD5DD1933951162F38E393168B16E817
-:108720007A54EB39F14BD8377C5E877674F6F3DDFB
-:1087300097B4833DA0FC847A90FAB93D7AEB709EA1
-:10874000AEF707BF11F5847C53E63477AD279FBEA3
-:1087500074A66CBDB96B3D99C3E3F6E2E7752E9044
-:10876000F339B9162DECD3153CFFCECB208F731601
-:10877000460C3450C4E73C6F40FEB6592C5E2BECDF
-:10878000234659B4DD68FB0D9787B69A08CC53E4AD
-:108790001E7AB47BF28A5C1BD0A750265A23F52B95
-:1087A0007294C3E662F032A81B2EB7E4D980BFB141
-:1087B000BD993E74F6474F1D23F50BEE9B9D5EFC65
-:1087C000E4D343287E67886FCA10FBBFBE8F56452F
-:1087D0005CD1507FFCDFDA47D3F6B6C49DA0A97800
-:1087E000701F2D2BFA5610BFC532E22D2F8DF001D0
-:1087F0003DE514E627461109F7D18895AE3F3BB811
-:108800008F26FF6A10D2E7B887CA551F4A972823D8
-:108810008E977F25FB0CF4B985B1ACDE2A3F5D460F
-:10882000605F8DD2D56BA5F0A8B86ADC5FF3829D3E
-:1088300001FD9688AB1EF5DF910279F2ECE72390FB
-:108840008F735E98FBE96F73806FA571A1FAD48B6B
-:10885000CB1F9D8F186382F39CACF9750AE053F827
-:108860003B9A5F42DE29BB9FBE0DEDA609F7DB8870
-:10887000B5ED3743405E6A4C03A04E3EE7F9849461
-:10888000D4ACE0FD73963E98C1EEA7796B14D8ADD9
-:10889000085C4FE51603CACB8C876527FAC9643D8F
-:1088A000FAC92F9745205C999487FA3643C3F6DFBF
-:1088B000684C188FF69D919C549A89F34D33D8FBE0
-:1088C000470332E38F97F34D0FFC19D63B169F7F7A
-:1088D00017D098FAAFDB7B73BA68981C919D12EEA3
-:1088E0003711526D033B305D23A1BD53EBE5D8DE5C
-:1088F0006C9F6F468AE34EB86FFE6306C7523BC358
-:108900004156F0A179D37C4D6036EC43924603D6B4
-:1089100037AAE83A22A2D8B987CD14FF2A2DD1EA86
-:10892000A13E6563764DC1A7CA56360AE495F6B7EF
-:108930006A69FF7C0BB3CBF3BBB1BA0FB1187D2FC3
-:10894000873E0F704E63F7D9A240DF86A2BC80FE3F
-:108950006B68FFF784F51746E5D9DAB270FF7E251C
-:10896000D44B009FBEFD429E4BE1847E208F0BB511
-:10897000A916E043EC94A9F0BCD764B44F54A91EE7
-:10898000CB8338F0357910E4B3331EDE53BC06E0F8
-:10899000370658018519AF1F423F750F97B33688C8
-:1089A000FFC16F51F80DDADEDB9BD907B7CCEA398E
-:1089B000F7F69684FD50A57FFEC33AE4C7FCE54C6C
-:1089C0001EE6D7FC09E79D6F09F4007ECC6FD00D41
-:1089D00006B95EC2ED45794D727E2B958F725DB4FE
-:1089E00055A2972ABDA57A802BEB248495E7CD7FED
-:1089F000F8931E9A2C361FB4062E47C179BBA78068
-:108A00005FFB66536CCA8C10BE7FB36C6B14EC6B4F
-:108A10007F15E14FB7423D666184631DEA29E3C7D4
-:108A200037CBD2D741BD6696356081FDF059F7A5A9
-:108A3000C580BF3B6AF5EBA1FF68BD5D03B0D36A9B
-:108A4000CD07D8A9ED8FF037FC9C0AFE503E2D9043
-:108A500098DC546EDAA34FA5CF7B91D3E7DBD70E1A
-:108A60006540DD607E4A2003FC3095AB8C44E0CB52
-:108A7000AB12C60B0B36C9CE887E41B95A0072457F
-:108A8000F57F1E97AB055BB63E007ABA00E469E05D
-:108A9000E57249F3CBBD787DF38BC584DDBF17E468
-:108AA0004EF1FB145EA683FA9A9EC3F43900AFE33D
-:108AB000F4A7FD45ACDF9B85FE84B4E9212EAE9280
-:108AC00059BC40F5291EE289AA269DB72DC43E2E29
-:108AD00080FEAC607F5772B3A737DF2FAB31A05F4A
-:108AE000DAC3F5AFEDE18628908B6F5FDBF3EE30F4
-:108AF000C8B3364B56B0FB97E921A75B15D0290ABE
-:108B0000D789F15115D0252A48A74E7DE3725145EA
-:108B1000181D14BA5469399D947E7EFF5E4E874AB3
-:108B2000C2E9BAA50FD377AEDF5462D08F28EB73BA
-:108B3000C788E7072EF0F57DCCDB4A2A378E2C94C8
-:108B40002FA77E30CFFF69D7B76FBC88F523859FED
-:108B50000ADE96749B62A79DDD62827C6ED3908A4A
-:108B600070F5EA539C7E3A33B32BC76A12EF5C4C24
-:108B7000E9376F93EC40E241EE15F25C83A6CD82BB
-:108B8000F1E9AF642BACABF07FCAC6C0BA15B9D35C
-:108B90006D94B44DB04F48BA21FD15FC0AAF738DEA
-:108BA000E9C6E4CE0FF828781E93FCC82FEF1B927D
-:108BB00095C5BB6D7AA8232A7AAAC6F702C7578E35
-:108BC000928649FD011F870DF49B503F88F8985B02
-:108BD0001FC4E7798F3C68EF177CCE51AF450BE39C
-:108BE0008E12660714B93CC6EB12C7966FC578584B
-:108BF000798E29FDB2E7B817C75DFE1C65BC9CCE17
-:108C0000F453D18B7D314CFE0B97FD09C7297616A5
-:108C10007EA01EA7D053A15B885E0AF451F44BD10D
-:108C20002785AFFFAC5E9125DD316E7D88AF1B756A
-:108C3000A447D02F807C82BF33E8D939B810BF89D0
-:108C400071CDA8A41FF4EE30D7153AA9AF07F32AC7
-:108C50006B0AD07F94391EF7CBC9B2F8BDBD43E291
-:108C6000B3AFA0EE05F6F415D987F69450AD0CF12C
-:108C7000E74ADC56B370947504C8D72609CF1D297E
-:108C8000FE9BFE3CDA29A774BE8A9C8519104FAC66
-:108C90004C4F65FE2CCE791AEEAF3C15288EB205EE
-:108CA000F3971BCFFBE568A80F6EB10BF943E5D92D
-:108CB000BDA8E7F3496005E4BB331E3E543A04F80F
-:108CC000FF8A0ECF2FCCAAB3A3FF3BBD7EE6204880
-:108CD0006D672C4F4778EECB7733F86116D7CD58B8
-:108CE0009EBB01EAF35F45388B41CEDB574B56C83C
-:108CF000BF86BF9CBBE476DA3FDCD2AB1BE07B6473
-:108D0000FD57A5C3208F582CA3DE38D73F3905FA6D
-:108D10009D4DB20396388B5897DC0E72AE8D46BDD2
-:108D200053CE35D6EA98BCCD4C67FE725A3AB31B87
-:108D3000D3B8FC16D6D666C0B982F617A99F82FDB5
-:108D400075BDADDE0F79E08EEB1CEBE873AA68DA37
-:108D50001A4FE5E994C4E2F10A3D31827CEDD70572
-:108D6000EE07FCF7DF6F19500308C8170797B3BC6D
-:108D70001DED0CCDA3F0B90ABD94E797F3E72AF3F4
-:108D800028F7ED83B80AFC08C7F7F4B257A640BC31
-:108D9000707A637A0C09A1FB695817A5F75C6A1F02
-:108DA0003787C907ABD2957AAB0FDB0A5E47DCAFDA
-:108DB000AB4B82FD5C1AD71F0F8DCF4FBE186104DD
-:108DC000B9A471BD785DC7FC0A8DE785EB547F04BB
-:108DD000B833DF93A747BBC3D823A555C7FB4BD3F5
-:108DE000CDAA73732CDE57F44F7DBF12DF77D65DAB
-:108DF0007AFFBC735D673D9431542186417046EF24
-:108E00002F32FDFD4D387F39BBCE603550FA1E073D
-:108E1000FD827DC10699C58B46A66FC7770CF041D0
-:108E20005D61F661E2F05378768BECB0D1F17B575F
-:108E30003F84E73BEE5E2B91EBA490BCEBA9D553AE
-:108E400040DDCE39DC2B12E8F8731BD97914DA6DCA
-:108E500056E55BEF26D8BACEB7FE5D7996527F52C3
-:108E6000D37F733ACFB71CC421D29FE5EDBBA818BE
-:108E7000E50DBC9CFE673D6ECCABBEF354603BB4CD
-:108E8000FEC5C244BA8EEFA5638F0D073DB24463A1
-:108E9000FDE4ACA71A3707BF6B1A74713CA5D3DB8E
-:108EA000E6682BD88FEF3C8BF17AA7DC7039BD7167
-:108EB0004BB39C4870FCF6E174FC4E73346C7784C1
-:108EC000D987637C569FBFB977E190EBE0BAB2DEF9
-:108ED00033BF64FC56F03FB3716614C4ABCDCFC54D
-:108EE0006E1F0A7C36455B4114E6F0733827D63096
-:108EF0007B74CA18BD611CA5DBA9B5937A407E7846
-:108F0000B7AE5DEFA0F33A769445417DE46B6D5BBF
-:108F100094155A3ADE0F78687D32D8C1612504F77E
-:108F20000787F9B5C466C7AD7B949FA167B53EC8F6
-:108F30009BBF817D43F0E31723D9FE3DDF0FBC7B50
-:108F40001BABB375D655787D61385F6F74468CB2B4
-:108F50000F84D70BF3D8F5936BDF1C0FF39D5EAF37
-:108F6000B302BEDFADD7E1FCF3687EAFA1F2786A51
-:108F7000233B2F306F3BCD93ED60472494DF795432
-:108F80007E8D207F0B754E7DF4E57259B891E5D743
-:108F9000F3EA25CCB715F99CE7F41523DDB99C1A43
-:108FA000E9BF4BD4757423F52B801E5DC9EB3F5B85
-:108FB0000FD06784AF07A8E541A19B22174139254F
-:108FC000289F0AFF63EA078C48C41BBC484F6F0107
-:108FD000C98478A1564F32E13C945713E900BDFF94
-:108FE0006B44543FA8432D36B2F681C8A875D0FE15
-:108FF0003522C50778FF55637D07F2AC5F67D871EE
-:109000009E07649B4EA2BF4E8A6B2B423750A871BD
-:109010006AC00FD61AD08EA8ED505A06F33FDB3344
-:1090200008CAFDCD19EC9CB88E54637CA1B4341EE3
-:109030004886F8A5CC1473018E923B36F49804FB55
-:10904000BD65C363EE4FA39167DE86A4495A2AE744
-:109050006583621A52293C2C2391F5F78FC9D551AB
-:10906000B8A626795211856FCD70F6CB08798E326D
-:109070002FBD3E2083E23132C19D03FD557AF34A74
-:10908000F003DF4BED0B347270FC41891C7D5B0AF1
-:10909000C26D3A9202F1F6CD807FF7AEDB1519CEA4
-:1090A0001B33C25C2F276439D425CABDEFB54A688B
-:1090B000CF88CB48F93981CB5FB9D1EC473BB75268
-:1090C00077B6533E52C14E456B81EFE339DB2768DB
-:1090D000FDCD707F5FB2CC7AC288A1E2DA4BB15D80
-:1090E000DB7FAAA8E484321F5DDFF73ABA5ECA5775
-:1090F000C949794D554CA2449E4EED9DB4FDBD9F8E
-:1091000060DE5A2F698B403E4CB7829F92885B731A
-:1091100089B6F34D542EFA434BE5818E5BD4F0EDC6
-:109120005E508BB94A9CE5CEC378F13E2B5B0F7144
-:109130000F4379BD9FCBEB490FA98652D1844020C4
-:109140000A8EC29E1DEFCF00FB5022BB6703BD4EAF
-:10915000AEAD4D5A44E5E7DBCD06C7383AFE94EF95
-:10916000CD28F0AB953CDE271765FFCDB47F9FBDC2
-:10917000EFBA5521F25595C1FCFE59BB3FE541B010
-:10918000337696AF928B7B521EA4E34B5247E7AEE9
-:10919000422A381766E0BE05DBAF18AF0D7F7E634D
-:1091A00072128B53C87AE68F0D5AE2B5C4604BA297
-:1091B000289D46535CF2E05C2A8565DCCFF7E1F33D
-:1091C000615C14C435B699F16CBF87B8C06E29FCD8
-:1091D00055F876193F29CA10D76B8C4407EBED4B35
-:1091E000D65A41FF15BE9EE4FA78D2C8F470A46C3A
-:1091F000463BB5A881D5F51649CCDE2EDA21B1FA69
-:10920000E665FEB66105D8E48AB533D19E2976CCF1
-:1092100046FF817CCDB3BAA2FDB67FC2EFAE2DBCB6
-:10922000267BE653ECD9003200E4EF6AF19262C784
-:10923000287B7E9F11B29F7C557E01C9E8BAE770FA
-:109240001C47CAD36D5AA04B77A303ECF9A2E7D30E
-:10925000D04F92F36BB08EA28C236B63517E57D8A4
-:1092600065E46B695322B1D14B739B243C273BAE21
-:109270002916E1A88E04844B7F7F5D01ACBB731F70
-:10928000F4F77D103EBDE1408E9BD5698C80878BC5
-:10929000287864D583FF3967A678503ABBCC2BB1C8
-:1092A000EEE8229DF990744902984A0DE89D53E733
-:1092B00065FC31D6A0FEF3752DE27AB5683FF3D791
-:1092C0008B46B0FD42ADB76F34F05FB74F263E0A14
-:1092D000DFB25FCEF5D3A1B5DC9E1BE235C416C26A
-:1092E000B7085B24B185F087789D01C8B7A672796D
-:1092F000792882D97D53668C306EAA7936CA4F2080
-:10930000A5781FACD7E2E829CC4BDC2C3E56E46AAA
-:109310000AAF9B8F27EDCBC04FDE3295F687CCA7E7
-:10932000CBFF01FD862E5F8CAB295D8E5F499ECE03
-:1093300064F0F74EFA92BE284F2AFA50FD407F7F24
-:10934000AE85BD7F42A39267F2293C659F8EF86887
-:10935000FF724E17885B21FF39E7B4A0DE28721731
-:1093600000BF47ED5C749E48B76E4E916EB12522EA
-:109370007DBABB447A5C373555E84F705F2FF427D0
-:10938000560C14E0E4EA61C2F85E8B0B04D8EE1DC3
-:10939000238C4F5B395180D3EB6E17C6F759532E90
-:1093A000F4F7F5CD13FA6FD8B84880B3EB7F258C6E
-:1093B000EFDFB454E81FE05F25F40FDAF78400E72D
-:1093C000069E15C60F695D27F40F6D7B55E81F7E5D
-:1093D0006AB300DFD8FE9630FEE68EDD023C821CCA
-:1093E00010C6171A0F09F048EB17C2F851F15F09C0
-:1093F000FDA36DDF08FD63337F14E0E53CCE2975E6
-:10940000FC4DB82F4096A5831CA725B987F7C1BA94
-:10941000CF292DE85FEB1D128985FC67DF242BEA3D
-:10942000FDCFCC030BFB70BBC8E5F80231DF09E7C9
-:10943000D9AF6617ED3C9E18298FC3F7AACED5B3D6
-:109440007A87DAAF2BF15C3475CBDA90E776731A52
-:1094500069421F84634BAC02DCDD152F8CBF6EAA02
-:109460004DE84F70670AFD89150E014EAECE13C64A
-:10947000F75AEC1460BBB744189FB6D225C0E97503
-:109480005385F17DD6B885FEBEBE0AA1FF868DD577
-:10949000029C5DBF5818DFBFC92BF40FF0AF14FA60
-:1094A00007EDAB13E0DCC01A61FC90569FD03FB4CF
-:1094B0006DA3D03FFC54BD00DFD8DE248CBFB9C300
-:1094C0002FC023C87E617CA1F1A0008FB47E268CC2
-:1094D0001F157F4CE81F6D3B2DF4577EE3F0E3BE74
-:1094E000D4DBEC7D57259E1B9BF983304E1747E359
-:1094F0007DA87F9348079CF7EF2ACE57E2C052C75A
-:109500004FC273FFAA61F1F9AB7DD8FB690FC82C7C
-:109510004EACF5BAF07C5E0C1C78A57A12ED955035
-:10952000FE20C59A8EF5C838F4B7E8326D70DE8D2E
-:10953000C6411488D1D8ED90879882716CD2A5412C
-:10954000D71EC736F52188C7C93EEED7402FE7D5CD
-:10955000BF510C79CE5CE25D017850BF1B0DFB580A
-:109560001F4688F528A51D6DA4740C79DEFE88BA07
-:10957000A48157D0DFD1C6B338BE735E5EAF92E828
-:10958000FA1685CCFF18CDBFB4544FEB3C54CF68CE
-:10959000A2FD84C78AF0539E78849FF6D8B05DE31D
-:1095A000C9C4F6598F03FBD77AF2107EC1E344D8C1
-:1095B000E729C1769DC785D7D77BA622BCC1E3C664
-:1095C00076A3A702DB573DD5D8BFC9B318E1D73D75
-:1095D0005E6CEB3D2BF1FA664F1DC25B3C6B106E6F
-:1095E000F4F8B06DF26CC4F62D4F3DF66FF73421F0
-:1095F000BCD3E347D8EFD987F06E4F00E1BD9E564C
-:1096000084DFF5B461BBCF730ADBF73DEDD8FF8192
-:10961000A703E1B37C3FE1EB3EE2BE9D021352841F
-:10962000F2A0C4BFE321EF01E1C8D37D27E43DAA46
-:10963000FC43CD8F33FC39BA021AFE42FCD33363AC
-:109640005D6D485EF0037FDE4391C41B41F5A1468A
-:10965000C3EA02353104DF0F233C3E9FC3E592C4C9
-:10966000B1B87C36C76B0ED7835C90CF4C94CF0FCC
-:109670007E4E9EA5E4DB51296E2993E2312F59E3FA
-:10968000C5BA8399BD873F20C5AD85EBE7AAEF7EBC
-:10969000179F677564C0434A0DFEEEB7423D69BF30
-:1096A0008C75D8AE9E57C5DF93E8B27FE7E924F00A
-:1096B0004725FF90B15EFFA1CE3215EA2D3D32194C
-:1096C0005D7A646A84F6AD145777C0E7647AF586EC
-:1096D0007BA5E0FBFF132035A77A5E466C3A3C87FA
-:1096E0004B9CEFC0AB37B7D0800FE05B89175B674F
-:1096F000B23B25B33B9C97F421EC1E664809B71E8C
-:10970000353E99992C7ECFCCD408ED9F525C7D00DC
-:109710009FE3E94E011F732F1B3F57DFFE02E0F569
-:10972000971D3F9C90D282F456EA1B2B46F0735A49
-:109730000B25651F9CC58946A2C489D83FFD7E566E
-:10974000EF51FCE5E1CE96D9C373D53AB49BD3A5CE
-:109750004807C4DBE7AAEFEF0FFB8577D07C0FF655
-:109760004F153B3A9DC21A0A4F27ECDCC5F4C316CD
-:109770009433B57DA5F711D8EF9B4E4906F9E3A5C3
-:10978000143BAEE743D70F3A9897C4B5E37BAB548D
-:109790006E4A809EF386CAF8FD860F35BE0C494698
-:1097A00079D14B14FF3971545EC2C40B8A5C2CE032
-:1097B000EFE528D7A9BC4D047A7EB76D4826EED3D5
-:1097C000EC1C6A037AD66AD87B75DEF765762E03C1
-:1097D0004AF9706E243AEB457CBF00820BE0DF5003
-:1097E0000BBE5FD02C93C56F84B1A7F772B9FA3066
-:1097F0005E57E2C379C57DC54ACED74ACEEFD2DDEA
-:10980000FB93E1BDC105FB749817919CB62C57984A
-:109810007355558B1FF945EF1039AF6A3AC6CE63C1
-:1098200091B6ACD073588FF07915F992F516F78B85
-:10983000E650FC3AE57C11D095CAF90988FBC71BB4
-:109840006CD1B7D25BDB2869FCB475FFCE8AE7F92F
-:1098500094737DB3880BDB3994DD20D72EEF6A7CBF
-:10986000AF7E1EA9C7EB0BF266A6005C45DA8BE261
-:10987000E97CB7ACAC79279E6237A96EF548A8732E
-:109880004FF4CD7807DAB2F5D209AF0DF5A416F88A
-:10989000D026552FEF499F77FBA611CBA18E3C5EBA
-:1098A000667C2007181FA83C39E598CBD747F5629E
-:1098B00015E04FF502F157F462FA52E294E282EFBA
-:1098C0008174EA49DE3D7F4E843D166D3B9E43A97F
-:1098D000DA698881FAC93CC2FC76B00EC4FCB5A234
-:1098E0000767748CEF675E93F03D9B3312C1EF39CD
-:1098F00074153728F127D53FA677474D4CFE655E96
-:10990000D74B71C70F4C0BFAE7331ADFE0A834F4DA
-:10991000DF1B801EBA02F7A303E0BCDEEB92A39626
-:10992000E272A69B2F859D13E8F403E49229582741
-:109930007C4CC7EA76EA7857594757781AF4C40B33
-:10994000FB5952DEBB3F411C7239BEEEF8C1942E6A
-:10995000B5C022A84B16B86CE1F058C69FBFEFEF18
-:109960002C1FF726133C17A4A6A76465CFE9AABE4F
-:109970006A8864F8287E4AC1F372BC18BF0E66324A
-:109980007BA1E0478835D34A9FAFD5463A405FCBAD
-:10999000B4EE00C887527F53F2E27DF693E80FC819
-:1099A000C5DA2476FED8DF951F3EDB998FA706FD2A
-:1099B000A452C722F9E1EB912EA315EDD744E24062
-:1099C0007FD1971C56E885752C197608B1CEEBC669
-:1099D0007518C05ED33602EA28E82F7DB82E13E052
-:1099E00085EB0A404584AC3645211D86B512B4D3BB
-:1099F000C3600D74BD3B8E111F9CA76ABE30A5D0FD
-:109A000042FB777CABC53CE819D3EB89F01D891D7F
-:109A1000A73F4D847A4FCD854684079F2D3ECDEAE2
-:109A20006787A7C17C6F9FD7DB0C18072C443A28A7
-:109A300075CAB70971C03E68DE67667CCF38B7A5C6
-:109A4000DE8474E375B57CBEEEFCF3AC1EB213800D
-:109A5000A1340F68D7137F48BCACB38A701E09814C
-:109A6000EDF0480A87D4397E6EFE68EACBEB2043DE
-:109A7000C890D0BA1AE98809FB3E957A1F3147622F
-:109A8000789FC874C5F5C5B86CA2CCE8FD0F19E87D
-:109A900075B3D99700F16DF3DC0D0910EF3E63FA51
-:109AA00007D2F1D9BFEB1380AE7523FE827EA48E60
-:109AB000DE1B80FC57EB8B2058FF9A8F75E09BB91B
-:109AC0009F7DF6E297249ED2B32E8FA0FF24DC0F59
-:109AD0002BFD7517CF55003F2FE41B6D60173278B3
-:109AE0003DB4E6A6FF17DF16428F1D34AEF65306CF
-:109AF000BF4DE36A3F8DFDB7D1B81A6078EF14DA35
-:109B0000061A5743EBA37135B42FD0B81AC6415C7F
-:109B10000DEDB334AE86760D8DABA17D9AC6D530F2
-:109B2000EE291A5743FB048DABE17ADDC5F242C43E
-:109B3000A795E0FBF54B4D511AB0AF14FF48A80BA9
-:109B40007DE41C1809F4B8E9BC46E06FFED9480171
-:109B50001E763C26C85FE0FFE19E42FFE09654A1DE
-:109B6000DFEEBD5E807B2D1E28C0501F0ABD3FB1B9
-:109B7000A2408013DC6384F1D74D9D28C0DD5DB722
-:109B80000BE3634BCA85FEC7A3547CF4556A443E7D
-:109B9000B2EF2B5CC837E3F9CAAEE4F409CE17057F
-:109BA0007EF297F2D47075DBB97D35423ED093E3F7
-:109BB000B6B0AF0DAFEF3D32E4958C1CE087866DFB
-:109BC0009B3ADB4DBD295F329ED410385788270E53
-:109BD000287E567EDF9305E74C20977B4AF511C01F
-:109BE0009F5DCE8248809796EA1342E5A8CEEE1E8E
-:109BF00088EF29B8D9FA94FB1F2F9878C57DF427F0
-:109C000040FEFA5CA17FCCBC54D087CBE8482A70D8
-:109C1000BF3648C789F87D27E2AE10F057EB0581C3
-:109C20004DFA0478AE51A4A733F561A0C3B34F69D0
-:109C3000F11C56E77CFC7E65BE91F245535BD6E590
-:109C4000F8EF72B2F134FE8D00BAD06709F8C5386A
-:109C50006C23803EBFE5FAF6DF5CDF9EE17C853C4D
-:109C600016606265F7297CABAB78627406E84D1E1E
-:109C7000C36BDDE427243037B1C451630DA1EB532E
-:109C80001C8F17F8BAD6C2BC14EE3ED92901FD527A
-:109C900016BB24D0B75E4BDA107E96EB7752753B3D
-:109CA0005E4FBECF8F6DCF8A00F68F9437E13A3A80
-:109CB000E9E010E9A8E6938FAF47993778FFE6FD12
-:109CC000206F179C0CFF28AFD909FE22CA6B75B014
-:109CD000D6C65B8703EC7E94D7C9E1EA2C801BF8DB
-:109CE000BAA2BC5E847D7C5D751571FB37D882CFCE
-:109CF00023B62A4DA8BFE94A9E9A38FD1B399DD448
-:109D0000F735E8BC83AC61F44A69157F3AB44D235A
-:109D1000E8F99056D14E7D04BF303FF0495F881B73
-:109D2000BC2E99EF5F211D2775E64BD3519E569BA4
-:109D3000EE3C00F9F6E41699307F3BFE1DB09787A4
-:109D4000461BD09F368F1E951C2A77CA3AB672BA28
-:109D50000FF53A8FDC47C797B90C8021755FCEE4C9
-:109D6000FBE97CAE71B203F6A15A3AFD89CBC4CEB1
-:109D70003B307F3291E3BC7BDCA447E0F9875AA8F3
-:109D80005DB005F154FA1B4A268DCD063E06181F1C
-:109D9000BBA2CF7B9C5FEF70BCF6707E3573F9DEA3
-:109DA000C5FDC90EEE4FDE067F6200BF93C7D7C365
-:109DB000FC4903F7277F047F42DB03DC9FEC077F2E
-:109DC00042DB9CD169456837E12536F4273441C12F
-:109DD000F3040B847529789524C9027F8AE34C0229
-:109DE000FF8ACCB1427F813651809D175305F8A67A
-:109DF000F3D7ABFC94E857861D1FA6F25305023C2F
-:109E0000B8658C70FFF89C49023C2E6B9A008FE974
-:109E10003D538009DF0FCB65BF93DCC8B532E6B98F
-:109E20007CDF4989A70E95C8B86F33F413D911AAFE
-:109E3000B7B9A4739F4C03FB64347CB16995F952A4
-:109E4000857E8CA35A74AE4438BF575346E590B60E
-:109E5000F92D344EC3E223956B1AF7E6BA46611C1E
-:109E600048E3A541C88776B6DFA4EC5B0D55ED3F0E
-:109E7000B98AC4FDA9DCABEC4FDD747D1771597E46
-:109E8000EC35C56554BF30FE7AC674E71E909B6DF5
-:109E90009FD13815E2DCCF7E81F1D7073094EAEB11
-:109EA000D6AF7F81F1EDD64E7D710BFA92CBF5B630
-:109EB000B125B5A98DEA5B4E37C9C1498DFA92C764
-:109EC000D794736CD1348C775A34187F91922AECE2
-:109ED0001FCCEF6F685D6A12DF5B0A897B306E8F83
-:109EE0000CCA0BE4932446ECB786C8672A635AE889
-:109EF0007842AE57CD3750050F538D2F50C1635464
-:109F0000E327AAE0DB55E3CB85FEA6B689578CBBD9
-:109F100015BBAE8CCBD5BA644718BB3BB8458C0794
-:109F200089AB4A38FFD07C6436DACFC6C32B389F62
-:109F30002A043EED569ED342E99D75F9FD055AAFC0
-:109F4000A91F95878216ADA3C616E4A3C22702797E
-:109F500071C87C854659D0E3A656E61FBB5AE74E2A
-:109F60006EA7B7737FF3962A8E93FF7EFED0042AE6
-:109F7000278D6D1ACCB31A5B0A62F1FDC18BB31049
-:109F8000DFA6560DBE4FB6F1D5F1B7D46883F829D8
-:109F9000F8E47CB2D404E7832E507F047296A37356
-:109FA000C65AC3D05D2D5F5DCDABC82F25542CD0D4
-:109FB0006517F547787E98DB55852EBB8F3C8D74F1
-:109FC000DFD6CAF0BDB943F48737B68BFE70F8A967
-:109FD0001801CE39C6E242EA7F71DE1C7EEEEE6ADF
-:109FE00078ABF502764844B8A738FE1AE3826D5C78
-:109FF0004E1A389FB64538A6867BFFA8E1A8BE2238
-:10A00000F4FB0A27AF67F5B993D7B3B83BE79806D7
-:10A01000F35CAAF7686F875AEBE4EA30F30C3BAEC7
-:10A0200051E52D9102FD7E6EDEFAE5F57CDF53658C
-:10A030001FBBBA5FB18F05CA77541C93C29E930DA4
-:10A04000F2819FAF54D19338C2DBDFCBF9A69C4B92
-:10A0500057F1AF8BFB83F378D579F5A5EB619EB60D
-:10A0600032F43BAB4D0BB85D5F8076FD839FB85DEE
-:10A07000FFA93109AE1F18B03509F4E840AEF23D32
-:10A0800058CABD907C5AD1A3F75B3E3685C6FB63A8
-:10A0900038EE3B320F8DED1FC2CFAEF0DCC7E5E7E7
-:10A0A0005D1EF7ECE57ABE9BC73D7E887BFA803D5E
-:10A0B000C8E4F680E5D16FF1B8A789C73D8D3CEEC5
-:10A0C00039C8F3E88F20EEC13888E5D10D99F7E261
-:10A0D000F7C52E242971CF786D383E8FB689766A00
-:10A0E00054BC4990B7915631DE2934260AE3479093
-:10A0F00034A1FFE68EEB55FA2DC63BC34F8979F4A8
-:10A10000D036318F1ED22AE6D1138BC478C7952F53
-:10A11000C63BCA3EC22EAB84E7B1C6E788F1CF2E5C
-:10A12000F885F63718D9F9AC86CC4957B4C37E6E9A
-:10A1300087FFC8F5FB3DCE9F7778FEB093D37F07AE
-:10A14000D01FE3521667E69E77EF89B6817DA8603F
-:10A15000F9426615E6D537725CB67AAA597C7A411F
-:10A16000637650BEEC32B3386B57E6CCF3F0DEFFCB
-:10A1700005ABC906F599033A37C2BB32251B7C6F84
-:10A18000508D5F6EABCACFF1784191CF5D2D5FA24C
-:10A190007FDBD9716D7E5519F71E998475979B5A8F
-:10A1A000083184A92F5CCDBF5EED39EAF1E0C7C369
-:10A1B000F91FF573C674B86542F577476BE04948F7
-:10A1C0008BC6F8E7CAF05DA8C1ADEE42E0EBDE4C0D
-:10A1D000C90AFBE9745C21EC4BBC77F1E3B1707DFB
-:10A1E000E779ADC680FB4E56C11F7D7091D21FE44A
-:10A1F00025939D4FF2B77EF9487FA8F31A657C7FBF
-:10A2000064D7C58171A1747BFC0619ED4A43964160
-:10A2100003F5E686F35AE20F89F71A3B52CDD036A2
-:10A2200064CAFC7A00EDC37337B073AB3BE87CCCF7
-:10A230005ED8100F451EFCE73525E1BEBFF31C7F3D
-:10A240005EEEC53F9B20BF7CF77CB909ECD3CE56B0
-:10A25000F69CDC256D26A0DB818E7566B8BE2B735F
-:10A2600010CEDF9CFD907920C84DAB86EDE7F0F86D
-:10A270004679DEAEAC398F0E8075B7B2BC6CD7F9BB
-:10A28000CD7BA2402FD64B0E16BF307BA68C6F38ED
-:10A29000CFEB4D3E76CE2D97783FCD06FDE9F17B95
-:10A2A0003DC839F1569250FB576815ED4841ABCA8D
-:10A2B0004FB92B511F143E946A6385FE039F4D9C3A
-:10A2C0005C067C33B3F7DB769E5F1A3711F4C2ACC1
-:10A2D0006371B38FDD3F2E58AFC1F7B594EFB0D4A3
-:10A2E000643F70A814EE6F607CCD358BF81CE85B82
-:10A2F0009BB880CED7B0C5E410D67798E0FA76390F
-:10A30000DE9C8E75ED2C03EA61E185BDE6B6903AE0
-:10A3100051679CD8B2DB3C08E87C5623D04DA1C3E2
-:10A32000A83C317FDC91B907C75F38CBE89E4BAAC8
-:10A330000FF567755873E9E060FE95DBC1EAE373DA
-:10A340007D22DE43378AF9E77C557CA4AE9FE76720
-:10A35000CD1927E4573C6ECAE37193BA4E5EAA3515
-:10A3600088F509559D3C575D27FF67E3249D7B1ABF
-:10A37000BE0F17987C4DF1C3501A6BC6E3F95EEF20
-:10A380009320D76FF1F872A8BEEEDE04AA220DB2B8
-:10A390007B38EE5BF03A9D72FF55E325AB97C40D19
-:10A3A0000EC98789F604E4972B618F13F9E265E7FC
-:10A3B0005955F376156F28FB23F945CCFF3C63FA1A
-:10A3C00010E38BC6AF597C013F6D3D60BF9EA01F5F
-:10A3D0006EFE5A8FFB276F8F66FBDE4ABC328938D0
-:10A3E00071DF667CDE79ED6F6CB09F7367F67CDAA7
-:10A3F000BEFD5923E6996F77E69975429E99CFE5A0
-:10A40000725BBBC61B0BF941ABC14742F6DB95FE45
-:10A41000C6F6F247B2410E031A94C3E66FF504BEC6
-:10A42000BFD7B8DD8078379ED5633CBA6DBB89C98C
-:10A4300035AF3F2BFADACAFDE2A79C9F07B85FDC75
-:10A44000CFFDE27BBC5EF30E8F5BF6F07A4D338F6F
-:10A450005B7681DFA4ED9676AE774B4C1C4F569F12
-:10A4600055F0BCAB4FDB112DE56BD57783D7403D65
-:10A47000EA36B7A80FB74E15E3937159627C32A63E
-:10A48000B7588F29494A13EE2F8EBB41E82F320F60
-:10A4900012ED9676B8003B2F8AF1C984BCB1A23C7C
-:10A4A0003943E213CCAFC57CF796D07CD70E7C62E3
-:10A4B000F9CCB6D627D04F6C3B9E1A1DFA9DE0AD65
-:10A4C0009CCEDB8E33BFBCF5F0394B68BFD29EE229
-:10A4D000E3CE707E9CE5FC9894E0BC238BCACA85D1
-:10A4E000E3E7F470FEA32B3956EE57EE3BE5FB2A6B
-:10A4F0002AD4EF7D0DCC08393FF46DE31719684F6E
-:10A50000AE512F6A2DECBC5B831489EFE15FEDFD4A
-:10A51000962559A95C29ABFBB3FDD1EA21D06ED0B9
-:10A52000B912E13DA806C9356D3EECF3FE561FF6A3
-:10A53000EF4AD46649CA39F426F00B32D76FB249D4
-:10A54000D2827C4570F045E2AECDEA0E45B16A1C80
-:10A55000249B5D04D6B545479AC0BF1327B1597BEC
-:10A5600010B655469FF3976CF7C3404F29C0F6913C
-:10A57000A95BC5EF7EC0112DF8FE16B4B05F663042
-:10A58000B2F70F22B3DC8FC3FCF05DDBE881306FE4
-:10A59000411ADB4FF5A39D9EC6E7D598B627E3B9D0
-:10A5A00055759EC4EDB5A2779D74AD14DF4B51DB9C
-:10A5B00059A5BEBBCDEE9A162E1F7D258BE59F4D6E
-:10A5C0005F8D97E1B939C62827FB3EA45386F7C1B2
-:10A5D000B69D18639A1146CEF6F69BF10AAC4781F8
-:10A5E0007302F532FF7B151AB1CEA5F103BF2F9888
-:10A5F000F5A8D74361C13197CFA7B6CF798755F674
-:10A60000B9739FBF4E8273679DF2040C01FE1F64F5
-:10A61000DFD5B89A3CA9F7EFBFC84AE5EF4D557FA3
-:10A6200001E74CE468339EB3D972D0B84EB65F9E52
-:10A630001F36F0BA9F1AFFE6CF6627621DE993D94D
-:10A64000ACFE07861DBF9B563D05DED3EB8461FD46
-:10A65000D00F1FB4C3EF002D60FDA315B86A0AC464
-:10A66000AB5B47B0F19F6F0A3C0DDF05DB7A07EF6C
-:10A67000278FB1F10AEC5D386504C03A568FB9E511
-:10A680003536FEE2F5CE2F803F9159CEC320A7AFDD
-:10A6900082EED0B6E87AE751B8FE05C8186D3FEEF5
-:10A6A000EB6C837E05EED6D7F965687F6367DE2B9A
-:10A6B000D6FD8728F1E0E1727E5DCD77C5AF5CB94C
-:10A6C000DEFF2197D30FB89CBECFEBFDFB78DEFBFE
-:10A6D0002ECF7BF782FFE803F9B083E7C3793C1FF5
-:10A6E0006679D7769EF7BEC5EBFD4D3CEF6DE479FC
-:10A6F0006FCE271359BD1FBE3B2841DEDB2F6CDE1A
-:10A700003B214FF42BA50ED1AF8CCD14FDCA685B55
-:10A71000A22A4F4E53E5C93708FD85C641AA3C79A8
-:10A72000B82A4F16FDCA8DED635479B2B87FFC4547
-:10A73000968DEF27DDAECA97C57DE4201FBBAA47E3
-:10A740002F0ACBC7AD2D8B0E5CCBBECDBFBB7EF130
-:10A7500021E7E3079C8FEF2BFB369F7C8CF9DD858F
-:10A76000F384F3F175F9FF62FD6242DEA4B07C2C44
-:10A77000754C53C9DBCC2EF8F84FEAA3F9CA75A87B
-:10A78000FF943ED6B6C4307DD42A75A8EFE470F1AC
-:10A79000CCFF357DA471C163D9D7A08F6AFFAEBC51
-:10A7A000B7A8C40D9D71028FC7947C690BA5157C59
-:10A7B00077A22141CFBEBBA175F784B843A1D7EFE3
-:10A7C000B259BCD3F8C502D48BC1E0CFC3D0F55584
-:10A7D0003EEED56C2BB6F09E64E440382DED65F16D
-:10A7E0004FF4382B3B5F4502F01DAA2BC44DAF66DA
-:10A7F000770FC64B5A6B35013ECA068D17BEC34B49
-:10A8000064239EBF6B80380ACE59ABE2A82FB3ED0C
-:10A81000CAF7782598F70B3EAFD4F22E9EF3FE4B85
-:10A82000B6730BCE5FE868877DC8C6237ADC67699C
-:10A830008C60DF4351C75B1F6667F0F79719FDE037
-:10A840003D805F803F850FC6A2FFFD52F49F1048F8
-:10A8500050784324EB0F647F35C59B14F4D79FBF1A
-:10A8600076FE69F8BE6C86B9E74C383F20ADF1C67C
-:10A87000B07D4B3FEA973A6EEB32FE55C5697FCE0D
-:10A88000747E0472720EFC72773C5FE5D40EECFAB3
-:10A89000FE0D91AE7BD877619C323C57A153A7FD4A
-:10A8A000CD6671DC877CBE4EBA287205DFA98909A6
-:10A8B000791F5685BF42AF1507F704E028E3CF5D47
-:10A8C0008FB28E30F2E3BA4ADC7D0EE8A0961F32DA
-:10A8D000CEC1DFD70D1FF7E9781C19CAFF61B82E6A
-:10A8E0009FC27F327220BC07A3BCBFCEECA1F2EEA8
-:10A8F0004C8CB5CE6AA77A74678B8CEF1F12BE1F83
-:10A90000AEEDE467BE04F6495B2C91D890784F5DBC
-:10A910008754C7A9EAF365F9677B0AF04DE75355F9
-:10A9200079E4F5AA3C73902A0F15ED51715CA130C2
-:10A93000BE2469AC2ACFBDF239002DD12ADF1BE23B
-:10A94000FBF6920DBEC3A365140AEDE7DF0362F4C4
-:10A950005ED6451EA49CA3FD4BB60DC775EAC75A2B
-:10A960006263FCF30A7F1F4A1FCFF8FBF860C58FB4
-:10A9700039B0EE6EF0CF657FEFC921BE4FBCCE631C
-:10A98000FCBC4807EFD990CF8BD2F1FC0EB62F78E4
-:10A99000E2B15DEBB161FBAC2713C7ADF138107EBE
-:10A9A000DA9387ED531E275E7FC25382709DC78561
-:10A9B000F0A39EA9D8AEF2B8F17A6FADDB0B7F1F82
-:10A9C000B1F74A82E74BD3EBE8F342E89CB692E258
-:10A9D000114247BBD72AC0BD16C70BE393AB6D42EC
-:10A9E0007F6245A6D09FE07608F07553F384F1DDD1
-:10A9F0005D4E018E2D2911C67773BA04D8E2982ACC
-:10AA00008C3765BA85FEDD370D8B6EBB823E3FE12C
-:10AA1000711E013A3CEA711D29C2F7A44A105EE595
-:10AA2000998AEDDC7EDD50AF62B401CC8F6272ACEE
-:10AA300060B121BFC5FDBF58AD43EA16327F6C0936
-:10AA40009D4FC097CE27D4277D389FC5E13A22E29B
-:10AA50003D55B88F3E0BFDE4043E66A49C64817CAA
-:10AA6000EC607E2C7EB7F5119DB53487EAF1479FE7
-:10AA7000B0EFE4C21626096347BFE6718DA99F11A6
-:10AA8000F3C5094F4998DF11C2EE9FDD92E608FD3C
-:10AA9000BB504AFBD1AFD977874CBBB7D9403E26D4
-:10AAA000E4CF888D08D97F99E0FFA92801E71B3002
-:10AAB0003882CACD843533F433B382EB53C6CD7EAE
-:10AAC0004AACFF06E5DF67E4711CAED3C0C7AC4AF1
-:10AAD0005A87D757655E79BFE60C5FD7291EAF9DB1
-:10AAE000E071F7715E7FFB92C76B6D3C5E3BCAEB1A
-:10AAF0006F8779DCFD39AFBFB5F27DAB4F79BCD63E
-:10AB0000C2E3B58F79DCBD2A7333FE9D980B9BD8C9
-:10AB1000DF25EA0A9F7B368AF1DA5C9F18AFCD59B0
-:10AB200023C66B77D789F1DACC9562BC36C32BC6C6
-:10AB30006B772D16E3B53BAA45FB38ADA250806F6D
-:10AB4000738B75B95BA78A71B7C2A75B5CA29D9C2A
-:10AB50005422C6DD5DADF76DFF68DC7702667E15B9
-:10AB6000E20F43BE0B2F9C7BCCB13A0B61FF2697C3
-:10AB7000B86A61BFE6464DE010EC33914F65FC1EAC
-:10AB80006413DC3194EAEB85C1E326D842FC8E578E
-:10AB9000949FE987C5F311B7DF27D2B5AC52AC77E4
-:10ABA000EA4B44BA3A93C4F36793547E87707FA804
-:10ABB00067BF9322D795FD90C65489EF2DFD5C7F2A
-:10ABC000A427EA7364CC1FE17353857EF447C6FE65
-:10ABD000EC7DA5C1FC7D859A88211FC0BEDDEECF2E
-:10ABE000D87B0694EC81DEF4FE9B08A3B7DE380A1E
-:10ABF000BF23B743C7DE1FD89560762CA55D375DB0
-:10AC000064EF09900E2D9E2373C3FB23A930AF7808
-:10AC10008E2C37A015CE99E955FD89E013AF880F2A
-:10AC20003B4FF79FC3879FE3E84FFAE3F988B6F0FD
-:10AC3000EF1D74C6712AFF1CBCCEE456B147397EA5
-:10AC4000EF213B5D578E2A5E32F075694CD3F1FBE4
-:10AC500063864F09BE7F9FA7F1C6C277B6C8390D7C
-:10AC60007EF7650411EDC2E47157CEC747C58B76F8
-:10AC700061B42D4D95F7DDA0CA0B45BB6020AA3805
-:10AC8000A78D9D4F34B09585F623DD26F78F51DED5
-:10AC9000DF417AD51C5B81E7EFB625F3F751B85C4D
-:10ACA0000DE7EB1D9EC4CE2FE6F17A71DE0F8B64AB
-:10ACB0000BBD6E385ECCCF312E71601C7B96F12BB4
-:10ACC0008FFE037EE69110FE013F0F8BFC34A8FA45
-:10ACD000E7807CE586C387C9D57F1E1F7E8E529193
-:10ACE0002F73CC55F6EDC2CBD788805386F783DE21
-:10ACF000B14AB82FFD4EA03A00DF89FC319ED5271E
-:10AD00001E4A9AA865DF6D719A4752BA17F375E625
-:10AD1000F17DB1460F09405CB2C563C496906A3CB0
-:10AD20001FBD227E512CF8CBC61477229C076CECF9
-:10AD3000DE6D199C1368D0754B0AF71E41B36E087F
-:10AD4000FAD7C6E6042D7C577E84D6AA85FB462416
-:10AD500095CB90278E82F74DE20026B81FB6C5E34B
-:10AD60000F14E1B950379E1FA2EB2884F8B5C83AFA
-:10AD700003FFDE63F32754FE6D101777C37DE3BD39
-:10AD8000DDD9F96B83959D6F2D8E63FBB0390EF67F
-:10AD9000FDBE9C24B3C307D3C5B3EFF854D07F974F
-:10ADA0005283FE81EABBF07D9F212404B6237F04F9
-:10ADB000F839357F54E71157B4F273736DE1F76BCF
-:10ADC000FECCE309E57CFB611E4F7CCEEB3F0779AF
-:10ADD0003CB182C7137E1E4F1CE2F1C45E1E4FBC05
-:10ADE000CBE3897D3C9E789FC7131FF07842910B7F
-:10ADF000C34A6233C07BB4C904EBF2F1CB245F09D0
-:10AE0000ECB3BB196C98C5F64F7B25D5B90AE2A007
-:10AE10005FE718057239D53B12D6113FBDBD02C69A
-:10AE20002524E96D4E3BBC9FB40ADF2B51DE0B9B02
-:10AE3000C5E5E6367731DADD595C4F88BC3617F365
-:10AE4000D33AF1FB71096E5DF0BB49F4FF0C157D3F
-:10AE50006F537D57492F317BF1BE6277079141A136
-:10AE6000748FE7748F98C1E90E2F5D85D197359C5B
-:10AE7000EE0A5D9A6F1A6661EBA810E2C243F963AD
-:10AE80002C206F2D497C3EFEBE8C8B3F6722D70F56
-:10AE9000655E657FF6F1822B9F6FFA888FEB848168
-:10AEA0002FD121F3143CA883EF92DFEAFF6532E84B
-:10AEB00049F07D1A07C6E123E5FC3F423E1DE0EF65
-:10AEC0001F28F6720AE1B4523DEF90E7CAEFED1C7D
-:10AED0002A18AB83EF764FF6FF12FFDE83415B1D2E
-:10AEE0001F7ABEB785E3F750D9BDF877E00229EDA8
-:10AEF000F8BE9AC165B0417CDE2BC9B11CE8179F32
-:10AF0000D456C4EBA12A7FB5B6390EE4AB1FFB368D
-:10AF1000E2FF072D97429600800000001F8B08007B
-:10AF200000000000000BED7D097855D5B9E8DAE79F
-:10AF3000EC3364E484C98326B813A658194E263826
-:10AF40000987B003C1460D7002018284709230C43B
-:10AF50008A367632BD8F363B24246110F03EEB8377
-:10AF60004AF080436B3FEF355AEBEB40FB4544E53D
-:10AF7000BE673128B4D8DB62982CB7AF03566BC7D5
-:10AF80007B7DFFFFAFB5CED97B7312A085567B0BBF
-:10AF90009F2ED65E6BAFF5AF7F58EB9FD63E6DA56B
-:10AFA000255903A98C2D0DAFAB645319FB00FFCCC1
-:10AFB00066CCC354632097E11FC7070AFC3FCA341D
-:10AFC000753A3EC7279676F64136FEBF9985D3E09F
-:10AFD00079E5C7FF83A533B6983507FAE0BDFEC211
-:10AFE000C0281F8CCF6A5C67B17F2EFCFD20273EF6
-:10AFF0008F2C1733F5AC79BC9420F4F78A3AA3F977
-:10B00000E27568EFEA669A671854FE04D08D86F7F9
-:10B01000B14D83E72A4BF34D86792B3FEDD5A1CC7B
-:10B02000C974D47B605D0BB33EB5928D843EF33D15
-:10B03000BE09005757A8E8270550EFD2D769B83C9A
-:10B04000ECB70EFAFDB0ECBE2C6D721CAEAECDAC02
-:10B050003402F374657DCEBF360DFBBDDF1AC17EB1
-:10B060002E56D30BEB3A31E7FF65669BFA3F3DADB9
-:10B07000ECE6C02818B002FE3786B189EE484E6073
-:10B08000F2C5EB65CC600CBAB495263356C8D8E946
-:10B090007A25EA01406ABA017F53B1FD42133E8F1F
-:10B0A000747BB42D0820D353E7C33AD77014B0C8CB
-:10B0B000848EA23E58EF9A6E4E37F6A0EB34E2CF64
-:10B0C0000B7F11BF59CDEA6933FE224C3D6DC66F2F
-:10B0D0000D33B543DD8D7300BCE581B4916FDF0C9A
-:10B0E000FF2E60051F3839FD11BF35A26F52FDE2FA
-:10B0F000610CD6C3FC80BCE28BD7B5FC774ED6374B
-:10B100008211C3B0A2F8F337578F4B8EE07BC8375C
-:10B110005EC157D388669A1BF82A199FE460C9DB81
-:10B1200061692F105FB5B8E27C96836CE63262707D
-:10B13000E758C66308EF52731DDF37F4E3E301FEFF
-:10B14000958CF3C7CA505325F227FB0CE72F2F3CF1
-:10B1500014E3C4F90FC6A90ABBE27526E8355AC044
-:10B16000097F96943FD6FB6F30FE633BF3E7235F86
-:10B170002DF9829339A15E0DDDB05E5DA344A380FD
-:10B18000D3A5A15B889E4B6DFC9D5C6D1DFFAD0D35
-:10B190000534CEAA4A180769B1C1D44EF0ED247C1B
-:10B1A0005631DF26942789D7B7B3D97806787C61E2
-:10B1B000F7BABDC82FE71EF0300FAE1BDF05BCD6B7
-:10B1C000730AB2E3691CAE9F6E56A2FB61FCB3BB6F
-:10B1D0003DC4776FAF51A20CE9CF7C4FA0BC76077E
-:10B1E00032689E734991BD9F87F686AE9480017840
-:10B1F000EB1EDE7C4F18E63D9711A9C3711ABA6E9B
-:10B200007618D83FD9F0E6E0B80DCEC07E9862B986
-:10B210000A381D0E25FCFB0628EBBB4DF482FF8E81
-:10B220000614E2FB050E16E94DBD987F92F2149AC2
-:10B230001F11EE31C1BF20C741F09E78D043F0A668
-:10B24000E469344E7D30494F4A473A325DCD077844
-:10B2500032F5B108E75905E413F8EDCC12C540FC0E
-:10B2600030800BDF77DF70FD3E94A727C43ACFDE36
-:10B270003F632CF2F3990CDE7EDA9F1CC5759DD6D8
-:10B2800078DDF0A7461F477AA891DCA5697C1D0AE6
-:10B29000F0418380AB4173E84940DF860797DD8545
-:10B2A000746EF06FBB17CBE369469A02EFFF74B779
-:10B2B0009321BE111FDE7C6C2F5987ED76BCFC3AC2
-:10B2C0009043EB41FC8D00BCBDBDAB3D2D82FBA688
-:10B2D0008F45DCA3E378A8DFF9BFEF53F07DC6F715
-:10B2E0005FAF90138599F663E0DFE59ADBA8807184
-:10B2F000D8A1F1C4B7CB7D9CFFDDC59B46E5F06EC0
-:10B30000A931FED0A8BE0DF7F70651AF47BE05BC68
-:10B310002E4779998AF8183E1DF79B9AD5D67D79E4
-:10B32000D3C88DF72F8675AE09BA9813DAD7F855BA
-:10B330000B5F57B558F91CD66DA9FBF218D1A17B4C
-:10B34000B8E0CF4ECE9F8C85C786A7C4F9E2CB016B
-:10B3500007E107A1730D817F3B5E3F6A78388DFC62
-:10B360000AE7CD992C6D6F318C77A61EF887C3C57F
-:10B370009C2679A8EFF610DFC3CEEE463C017FBADB
-:10B38000ABA6C4F945E2A77E571BF163BDE0BB86BF
-:10B390006DC03FE9263EB2E10BD7ACCA79C6C5F90C
-:10B3A0008CDA13F0D977021C6E297FF52C5CC79CD0
-:10B3B00017CBB52C89CE2548CFBB6A8C4C1CC52039
-:10B3C000BAEE282D1946FC2EE8A1C6E9E145BAA53A
-:10B3D000CBBAC18EE17E9E26EA192DCA9BE505D027
-:10B3E0005FD0C9533E10ED83A6E12DCE37CB475039
-:10B3F0001F4D85FE23043ED881194F4F1C1D3F6F02
-:10B40000D2C479A03A33C7607B3AB3EA3D236CEBF0
-:10B410006785AA3837F839FB80CB3706F7E364B184
-:10B42000BFAF9B374EC17E0F280AED3F9E0AD5C2A3
-:10B4300027AA4D8FC9C97388FDCE90FC4DE7AD5B3F
-:10B44000E83349631C2417BFC984035589E3C3CD7E
-:10B450008760C3FBB4DE3E68AFF37B035186F0F236
-:10B46000F3A10C88D067E2AFEACA14D66782639E64
-:10B470006F84A5FE71FF0D96FEB76AE32CEDB7E76A
-:10B48000DE6C699F1F28B0D4DDCC74AE239C031CF6
-:10B49000EF6E816753BB3C97FB918E8BC53A76B8B4
-:10B4A00023FE30E06BB17F2DD1A3ADF4137ED44BDE
-:10B4B0003D7E4E57B7D0279326ACF6911E51C9E575
-:10B4C00027087F910EED38C898389FB96DE7AD5DBC
-:10B4D000FEECFA64631EE83D2950F918FB18E93DBB
-:10B4E000A9C313EA3776FD0DCE0807F26BB2A0D7D9
-:10B4F0003C672A9D1B5DD55C9FEBCA5DC4F5A5DC4E
-:10B500004F125D17887ECC7090DEBA54AC5FEA5F54
-:10B51000AFB532D60747F38E12AE672D0D5EA83653
-:10B52000EBE5B2DC82FD26C5EBC9A17DBA9E40CF1A
-:10B530006C13FC95A2F3F6A55EA6E23924DB378AEC
-:10B54000F376A938B717821C23DF86B1349DCFDB91
-:10B55000C538DB63FCCAFAF361DD4E013F7B4A511B
-:10B56000110F49A2BA8F45B6E715219E0DEAE44CAA
-:10B570000D3392EF3F0176A1DF02D1AF2C6F75CF73
-:10B5800067817F3DD56901B42D3CC1FAC7BF54889E
-:10B59000FA514AC0A1C5F99DEC0EA88FCCE5FC5E1E
-:10B5A00093E90D50B3A11F1B0FE3558BF66A21CF12
-:10B5B000A35833C9C145768C97F3E5E0760CDF7F5D
-:10B5C000E47C1EB1AF30E78600F15D98EFFB0EF82A
-:10B5D0008B7CB7A4C6CA57CB2243F3596F9ED0AF1A
-:10B5E00067B019C46791F5C4171ED167C7D88361C6
-:10B5F00092F7A09391BC0BFB46EA9D47822F12FF66
-:10B600001FC91D50F5D438BF487D7C41C8A947B13A
-:10B61000BD9825FBE01C39E21AC87C00FAB954D663
-:10B62000A7E2DE2BF4F2F4E0B2DB7CB0AED78A5FA7
-:10B63000F19D4A6583EAF3767E9F08FFC07D7EF325
-:10B6400084B7FD08C76617345D8FCDBFAA4178B6B1
-:10B6500063BD04FB9FAF2983F6ED49B2FEEE2E6C6D
-:10B660007F2299D77FF5CC1F771921A207F14D8A48
-:10B67000C0778AD4CF279BF00678F68ECCA77DC4FE
-:10B680006BC3A75D6F770A7DDB69937FFBBC67A502
-:10B69000BC0B3A0CB6EE8BE005D6FBD8D07CFF8B0A
-:10B6A0003C3A0F9B2D7C7FF1387DA49FAF10EB7649
-:10B6B000A41CC88A2490DF18FED7BB7E6EB6070094
-:10B6C000CFDF5450AFD5E1EDE99C55701C25F8F261
-:10B6D000EFF17C577619C3118F4EE880E7B80B2C39
-:10B6E000408447CA6312F28113F1DE47ED709E0E6B
-:10B6F00028E370905A1FF2A702FD3F40FC5CEE3E2B
-:10B700005861B513DDB87E18CFDDCDCA3CE9683786
-:10B7100036EEDF5C88E7983B40FA57F78532A41392
-:10B72000B4EB1E2A2FE8747EFB1D9673E585D23F8D
-:10B730009C7F1458B3B3DF19F0C07B1DD800F074A0
-:10B7400086BECD50BF7E77320BE0E2EB22BE796E33
-:10B750000DE5A1EF44C784387C275A597FB92B5E89
-:10B76000EF3F98E4D660B111E35E2FD2E5AD0DED69
-:10B77000539E433B3BE8F1A1DED6BFB1DE40649C63
-:10B780001863F4224EBBD40843FBDDBDE17FCEC37A
-:10B79000FDF384CB080C87B27BE3CEBBF1BCD2B502
-:10B7A000CA8A6C807B7FB75A114D60CF7C229FEF95
-:10B7B000AF475EB873FF66F4378C710792609E01E5
-:10B7C000F45F00FDBA5C46168E7FA2AD3D0BE5A38B
-:10B7D000ABBE2B7010FBB5790234FF6E6F0D8EDBA4
-:10B7E00095B5D6BFD634BEF70677333EEFBFDEED54
-:10B7F0001E47EB7927CD0FEBE8DE50300279B373AB
-:10B800008C7B6C23B637AC631AE8856EBFE142FED1
-:10B81000F2AA6C17EE0337FA2F7C7F06DA439A639D
-:10B82000FAC7A1FF7D8148793ED0B1A6E5D43CD8C6
-:10B830000199BB3C63139E3F9D024EB90F49FA0E1E
-:10B840008C69F062BFCE4823F7B3F81DF548E78551
-:10B85000631C61DC7F3A436BBC13C5F375E917E3E6
-:10B86000A513FD2AD3104E58D714ECF77E6B04FABB
-:10B870000D64B96B12E13122F0E86D5F97D302706D
-:10B8800077EEF6FA103F9D4A64573DE0CBC84E0D67
-:10B890003CAE5DFCDE53E23DC91F402792C34F3CE6
-:10B8A0003B7AB7311EF5514E47C08BD7653A179F8B
-:10B8B0009E56B626DFE4BFB868DE319D741E742A3A
-:10B8C0005CAE9F7A76EA6E03EA8140E46E7CAFABB1
-:10B8D0001B78791AAD732CEAF383C9CF8068EF6CBB
-:10B8E000F3D44413C8FFC06A279B348C97D74139DF
-:10B8F00071A373AC92003F03590D39D9781E40BB38
-:10B9000003C619D8EDE5253CCF81E76F0EC29F53E2
-:10B91000F2F9793E796AB81DE9CF2647C88FF772E8
-:10B920005E7813D5D94E3FDA171F01FEDDF321E112
-:10B930005F3A0F23F937137F31DF708B5E3AD8FE01
-:10B940001916FB715BE91F9AF0FCDF5AECD13C261B
-:10B95000BF9FD4939327737D243CE1B100ECDC6C52
-:10B9600071701D3F2F2BB9FFCF077F13F9FFC23630
-:10B97000FF5FB2AD2EF5CF43F9423F117A70A6B604
-:10B98000333C07ED8B579D8128D03D0B5F1889FE16
-:10B990003125DA976D82F726B78097EB6B0BC57967
-:10B9A000F4A3562F2B9FC06276DB72B18E054DEF4C
-:10B9B0003C8676F402A16732243ECC5F3D999FDF3E
-:10B9C000D26E5B849D814597E772BB002C2B7EDE97
-:10B9D000382B8B901F1632AB7EB788D9F4B9D55C63
-:10B9E0001F93F6DA0A9BFE60B70BAA6DED3B60CEA3
-:10B9F0007ED4FB54B04600CEF782053B0A00EEBA77
-:10BA0000E0A14D0309F69BE378DEC07ADF68D5DF5D
-:10BA1000EC80736753F5D7BD03F0FE56B5D78B7234
-:10BA2000B2B5F2D36928275B6B9D248F475B2BA8A7
-:10BA3000DF6BAD612AFF2B3F23E6FFEA93F601C0DF
-:10BA4000B120A0BF8FFB8AD4D3AA2BCBDEEC30D1A0
-:10BA50007751F9AD967A3854F56687DD7F897CE6B3
-:10BA600064CD89FC6E530BA47F45B7F83999F3A9CF
-:10BA70004024417F59021FBD67C6576A8155BF3DAB
-:10BA8000129C3B6C28BD46AE5BE24BE243B60F0610
-:10BA9000EF6FF2A51DF297C19B7385F0DAE194F088
-:10BAA0000FD63F8C9B5909C2DBB6DC48453A46F2BB
-:10BAB0000B00CFD515192FA14FE20D95CBD31B7AD3
-:10BAC0005AD400785E9ACCEDFD945C16453FAE9D4D
-:10BAD000CE2915F5F3705FBB14BD93430AD9A14B72
-:10BAE0007425AAC33F6F1176E996C98CECD2B6D201
-:10BAF000AF1D4E2BC478878B897DA672BEC98E4A36
-:10BB0000A9E571881D6E16E8C3F7A6A40636C2F330
-:10BB10006A944394CFB0EBB4D90F0276D069B31CCA
-:10BB2000D9F79B145BBCA1AA40E8DFD301EFE3E2A5
-:10BB3000781FCC0E198C4FC07A28C2F3CA8EA77B0F
-:10BB40006CF8B1C723C207AAACED9769FFECEF2EE2
-:10BB50007C6924EA1BE54A6002E0E3756C82F79297
-:10BB6000F56728ECB1B940F0A5B0EBAAA55DB70820
-:10BB7000EC7920C111D40B86515C692CFAA5E3EB5A
-:10BB8000E3765C20A07FBAA06870388E89F7BAAAE5
-:10BB900012EB0BC7505F98C6CBEBA09CB8686E56F3
-:10BBA000227DE1587123D717A01DF58463BB2B7844
-:10BBB00009CFCDFA02AB28B8045EDA68BD49130A92
-:10BBC000872592BBD7A7457622BFCB7A4A6E332B07
-:10BBD00037F149539EFE4001C535B8DF41CE07E736
-:10BBE000FC21B33E669FEF997C1FC773C5083A37A7
-:10BBF000647929FAA9BE66867CB6D5A5D7609CC0B3
-:10BC0000EE377AA680C727BA73F4266C67A9F9972E
-:10BC100018B74DEED7B979A34D7E4B9B5D28EDA8A3
-:10BC20007DD868B20F551FB70F93332F1CF241D345
-:10BC3000DA82C8F388AF5917A286A310E3A90AE9EC
-:10BC4000519E4CE622FFC9E5DA6397D9AF7B23DF2B
-:10BC50007FBA1AB8DFBD2C4FA57A72C4B99FE248EB
-:10BC6000C25F1316CB48D6DF217B6C01E803C23FCD
-:10BC7000437AD509E1D70AB36617DA7DA9AEA8974A
-:10BC8000E2BE36FF4C4DA6A36F22EC1F35C10BD58B
-:10BC90001AC539ADFE9D1A2DE7D028D1EE83724129
-:10BCA00098FB7B96A2BF07C7AF8E76E7E0BE165023
-:10BCB000033AE3F61E9EB7CB1AEF9BF29076F5FCA3
-:10BCC0003DD28F24F546E9AF82F3A57B04D265AE61
-:10BCD000A2910FC0E60FB2FB7FC2C21F63F713D958
-:10BCE000FD42BF2DC8267A483D4CFA6BDE2FB0EAE4
-:10BCF00063FF09E281FDB614C35106F2BDC5C5B2AA
-:10BD000076C2F8E9FAB2DB705F7EADEC151FEA1B74
-:10BD1000FF5960F3675EE6FEF663D887CEA0BEF6F5
-:10BD2000E21817EADD55CDF5E437B4CB89BF90EFC3
-:10BD300073C985A99678717F6B8B783FC9C0F3A6CC
-:10BD40006ABC3B9A046BAAD2F938972B4F1979FA3F
-:10BD5000C8C25164978CC69205C02E99827689908C
-:10BD60007BC1DFAC7C143B638E937AC15E4933C3E5
-:10BD700021D67185F3238DCDF35C0A6F3B4A4BBC12
-:10BD80006EF447002C4ECE57BE989F3E07FD3BEB0E
-:10BD900035B35E5187F18902D43F158A53C8E7262F
-:10BDA0003FB98AFC9B9C19D1C309F6D5E5850E4B9A
-:10BDB0009C34E667CF65141792E3A8CCDF46728007
-:10BDC000B22AE17126F0C70B781B259FB380D78379
-:10BDD00071DE6D4EC6F30FB89CC8B8835A1CAEC84E
-:10BDE000C6F8F02625601014358750BF5F2DE4C8D3
-:10BDF0002DFC70F678D16A2957CEF5A4A735EEB49C
-:10BE0000C6D1EC7131BB7E2EFDFA2A4C82707F5E6A
-:10BE1000D2090E78E7D078D847EBFC3BC583E4C362
-:10BE2000CA82BBFC98BFD29914D9558FF1EB1E2F53
-:10BE3000F945BAB00BCA4B1FFC457F7B4FF0D12DA3
-:10BE4000F05E77A193DEEB54783ECBA1319FA3FD4A
-:10BE500043F259B7E0B39B0A35EAE7C57D09448848
-:10BE60006572BB56E6AFBC3686EBABEE10CFFF7902
-:10BE70002AF3D0EB65042DCF63C90DC5F358CA0072
-:10BE80003F5304FE7227AC263B764A88E7B14C7ECE
-:10BE9000CE6AB7DE9EEBB2D473ED76ABADBEA750E3
-:10BEA000EC7BB6FC95783C6D11E961127EBB5C7D44
-:10BEB000B595C755BE06762B964FB5FAA8FCD75652
-:10BEC0003F95BDAD1AE969CFB6E672BFBBC0FB5660
-:10BED000D7053A17CF65B9290F42FA29A5BFFC3B10
-:10BEE00085DC0FC5421C9E85624DF39C996918E75D
-:10BEF0003A1AE2FAE160FBCCE20A6B3C6F49D81ACD
-:10BF0000CF5B56638DE77D7AAA7EA010F5AAC9BFE4
-:10BF10007BF551E479117F5A23F0B0E3211E5F9243
-:10BF2000E31FFD02A7BFAC9F1378F83EF207C68F50
-:10BF30000E8A7DF4C1AA5B681FF5E55F965E785CAA
-:10BF4000C867CA469F2B00E357F52D77E3386B7619
-:10BF5000C138A9973FCEE609A3B3ACF1864FDE8185
-:10BF6000EF1F8DC51BEEB903E30D4745BCE1FC7324
-:10BF7000CD5F467BEBA642FD27880747A17E12CB0B
-:10BF8000F308CF28AA0FE0B922EBF0E770C6E8214A
-:10BF9000FDFAE70B13F8F59D739584F6E93B85DC14
-:10BFA0009E86F3EB97F81EF3C6FC6A17789D9F53A5
-:10BFB0006A119FBFFD47AC09C769FF366B7A3681AE
-:10BFC0005EFFC742458EF73B3A0FFDF23C0CFF2166
-:10BFD000D1784E4FD558C4F73917CF83B18FA716F4
-:10BFE000B9E5788E227C2733069F5A641A6F07E0E2
-:10BFF000A01FE9A4FAD2288EC9EEA678A7E4A394DC
-:10C000003ADF7CCC53000393E13E93F2BC6F7E2178
-:10C01000E6D9FD605CE07136385D7F26F8EBBC90B8
-:10C02000B3B751CE409ECEA29C41791AE50C9E0F2B
-:10C03000A09C4179B23540CF7FDC1AA4F247AD3ADB
-:10C0400095275A2BA8FC416B98FA1D6BADA1F2F510
-:10C05000D6083D3F5AFEF55B289EF69442795583FB
-:10C06000C173D757ADF27567D42A5FEB7659E56B8C
-:10C07000CD4E6BBCBCB1DB1A2FAF37ACF1F2552DF6
-:10C08000D678F9CAE69996FE2B9AE65AEACB23B7F8
-:10C090005BFA2FAB596CA9EB455C5F5C125E617972
-:10C0A0006F7145A3A55FCA22164944FF8A22CE9F1D
-:10C0B000074305C30686D877DC2DB7FF04F59458EF
-:10C0C0005D8D30D4EBDD2D0BE8F9D6A4705D38C161
-:10C0D000F875457CBFEB2C5F1D9EC3D0FF7B8BD3D7
-:10C0E000ACFFAC9F16595464B273DD7E6E97BD3BB6
-:10C0F000FEBD17F1985854FECE4BD7E139D5CF028B
-:10C100000AF0950E6A9F1FB6EC22A3CD791DD4AB21
-:10C1100033C18E34ADBBF833FBDA47C3F399EB5F21
-:10C12000983B12CAFCBC485D11DA5115A7DAF1FD43
-:10C130003995792A8ACDD60C467AE9B9096EB27753
-:10C14000EC707FAA48B1C4B3AE749FEE6CB5C6E57F
-:10C1500073FC3CFE95E3E7F12EA853BCEBE9699133
-:10C160004F217CF09CE25E5D596B73703F192C8E01
-:10C17000F490A097F42B48B8769472788E8A78C39E
-:10C18000107E852F168D1A1CEE73220ED1F5254FC9
-:10C19000C2F8CB3911873827E3100F2D4E18873896
-:10C1A000374FF815A01DFD09E776D7F0725EE390D2
-:10C1B0007108B93ED88F1EA4FD27168710FABEF06D
-:10C1C000A3BF3E4DFF5FB88EA63C7D17F67B7F8AEE
-:10C1D000BE1BEB474DF150DF68533CB4FC154B3CA4
-:10C1E000F499FCC83E7C6F226E693064BBC1069234
-:10C1F000C6617C367C4F223EFE9722A967F7FD453B
-:10C20000F15A535CD5F1C1CDECB2E30297DD2FC8F2
-:10C21000F350EC7A4E0A620486E8C6AE70CE3E5900
-:10C22000183988EBEFC8785EE3F9568EF8FE8187FF
-:10C230009F7679F3250B3B15CF2B3CB78E81C4E05D
-:10C240003EB33DA399FC2AFD026FF6F28D22414FC9
-:10C25000E61B89F47DB230FC3AD28F3DD7AB511E3C
-:10C260009B78CE722FCF5E7DC21DFE09EEEF9D73CF
-:10C270009C1ACF1B64E4BF9894EB8BA27E2BF5B085
-:10C280005FE27E49F92803E3DDB0CE76FDC554CCEC
-:10C29000FF7E6B8F8A1930EC2B69CC8570877361B8
-:10C2A0007F8375CCF1476E1C6A5FC4041E4790F80B
-:10C2B0004271F8A91CC14B43C1E7F6FEAFED796F9F
-:10C2C00014EAE55FE9E1F1B0493DABBD0DA6F173BC
-:10C2D000A6F37DA73393C35FA72B512D1BE1B9F0C4
-:10C2E000FD19186FD11CE4EF786BC36F8E2F43FFDD
-:10C2F00063C8199840F577A9DEAF390A307EFD96FC
-:10C30000FFD7C7B1FFA42FAC194DB68EC0C7AA0D79
-:10C31000054F203EEE0B4494E9304F7FE8DDB471C9
-:10C32000A678DA2A858513E93163A673BADDA637C4
-:10C33000DF81FBE66DBA87615E737F9987F0FE95BA
-:10C34000598A86F6EE42E475680FEF51C98F0DF8F1
-:10C35000588FEDAF065218CE3B477F46C5FAFB53C8
-:10C360001476DD10E7F015E335F4EE2894C3B790AA
-:10C37000FF12C0FF4BB96F0A399AA882DCE723FE8F
-:10C380000FA59AFD95929FFEA9501F37BD08FD7F0E
-:10C3900091A630E9B98B2EC1871B093F0BBF1AA5A7
-:10C3A0001884E7B1E6EB5982FB0DAF09F9B03F2FD6
-:10C3B0009CCECFC95F0BB998D4F3DEABB7629C7942
-:10C3C000838BF2116E2A0C4F47786276D755DE3791
-:10C3D00064BE5A7F5021FB0DD4699AA71F245005D3
-:10C3E0007A2529C9014E4FEEA7F38AFD0FFAE9C35A
-:10C3F000A0DF2AD6DB87FE3EA6EA3B9DD07F73B145
-:10C400008BE8BD6CA52B0DE9128F9F052CF686BD20
-:10C410001C1071B3CE562FE56BF47738B99E0F7FA1
-:10C42000401387461EB767C6948775F8E713228FB7
-:10C43000F493C15B1FC67C9AE30E5E6F08DE7AC37D
-:10C44000468C7B8F6D3EBE04E3160F2881360DCBE4
-:10C450007DBB1A30CFA345095440BDAEEFF37E74C7
-:10C460008935747848C73FB56912E989EFFA990FA1
-:10C47000F5C46563B8DC34F6B3A8233B6EE79ECC05
-:10C48000E2F113B463E74DC76D97E3E39F5BFB08ED
-:10C490007E4F0B8F9B0C0FF0B86972BF1A884297C2
-:10C4A0008F6F7B87ECE0B0DFAD219E47301E578950
-:10C4B00064A606300E1AF4F3B84AB27EEFF125F006
-:10C4C000DEF07295E7B70D707BB809FEE2391261B4
-:10C4D0008136DC9F465458EDE4425B7C459E6F1EDE
-:10C4E000FB7315EC5178DE36DD7ACF6330FFBD2C5F
-:10C4F0009F033D02D7F7BC88E77E13F475A4D3B73A
-:10C50000415FC7F200E8EBF8FC7BA0AF63D907FA04
-:10C510003A9607415FC7F210E8EB58BE0CFA3A961C
-:10C5200087415FC7F7FE0FE8EB58BE0AFA3A3E7F35
-:10C530006E16DF473AB3DCD18D8067EF9F808B01A9
-:10C540002F9D2EF663E42FA3CCA3F17C7CDEAF2BD2
-:10C550006322EDF3FD4AE4138CE781688F633DEDC0
-:10C56000C21F7F85F54DD964873055FBE600F4EF97
-:10C57000F87C76600B54BBDDFCBC1F38CA7CA83746
-:10C580009C5EA24C45BDE9CC7CA55701FDA67FBEB3
-:10C5900042FAC44414BDFCF83E5AF29EB61FE76B43
-:10C5A0004F63821FF7F5E8C07FA71126E2D7B43AA0
-:10C5B000B48F677B643DB90EDBEB5B1461A7A6EF1C
-:10C5C00045FEED92FD8DEB7AB07F87AD7ECC21EB01
-:10C5D0004D7BB07E3C365FFD0A1CEF788E6C6FA8F9
-:10C5E000D5E1CC184892F3CD5C89FDFB15D93FAF5E
-:10C5F00007EDE43359B2FFDA15D87E2666473FB619
-:10C6000092DA47F1FE93BE3BE211B49BAFF678EDB0
-:10C6100011BE3FC33EA69BE33A2D25DCBF10F39F1E
-:10C62000EA8AC57F2AFDF68E94DAEB30EEE6D9C8A9
-:10C63000F3B406B20275785E0FE64735F9F9C98F93
-:10C640003ABB24767FC0EA2FD5159E47EF6311CB06
-:10C65000FD369127EFCE34F9ED84AC5F8EFF50C6E6
-:10C660004BA4FFB0461FDA7F5833CBEA3F947912D0
-:10C6700083F90FE57D04E93F0CAFB6FA071746AE24
-:10C68000CC7F58CBFA5C686F315D2179A9F5F5BE96
-:10C69000341AEDFAB31AF90F9976381ABB7FA0D184
-:10C6A000309A633ADE23E3F5D3772B7EB41FB6DCF2
-:10C6B000AD8CC6F2E4DDCAF5284767EF567C2857F3
-:10C6C000BF98C1EFB7149D0F1CD6705FF53B021CDD
-:10C6D0001DE12FE03E1C5E9DA16D41BADEAD0CC791
-:10C6E000FE2B3F93E1C6F303F44B21371F3C8C7CB8
-:10C6F000E54C512CF5C2B1924FF73C8C72317B84E2
-:10C70000E4C3C57BB05EE696EF7F710FCAC9F288BD
-:10C7100022FADFBB07E5F0F81CD97F782DF65F32EF
-:10C720004E8EB7770F8E3F3B45D61FA4F6EED878D6
-:10C730005FA3F97E882721D5B7EDD1C7C37C55E229
-:10C74000DC323E46E377D6CAF7EFE92983F1568813
-:10C75000738A191F2739273F33BD0F7A3AD4FF5DFB
-:10C76000EC030D337EBF02E5E68E58FBEF69BDB5E5
-:10C77000A2BE7AC6937B30DFECEF7E7D7FE5F9ECDD
-:10C78000F595AC7FDE758571B9B09F8BCB8BF9BE0B
-:10C79000126C7A068F2756DBBCCF89F2887E001197
-:10C7A0007FAA0E237F7B9D943717F687C9EF691FF9
-:10C7B000E7FD195CCFFECC0C6B3CADD3164F0B6381
-:10C7C0003C2D7BF071EA8AF938DD7312DBB34F4FF1
-:10C7D0009BD33A63545C3F4055D00D6529940E2895
-:10C7E000FF3425B26946115EE6E1FE16E9BF5E2020
-:10C7F000F288DB4ABF1C9E83F7928A5D01E1FEEE60
-:10C8000037C777D56DDCFFBF62CE05CA0B5BD3E9B6
-:10C81000D1F6631E4B87C85373A652FC41BDC1BD00
-:10C820008FF679113F8D60BE710ECE33F4BD0DFBD6
-:10C83000FD1943ACF7DDD01617EEDB35E56A9F5BDB
-:10C84000C48F79BE9835BE2CE3C56579E329AEDC8B
-:10C8500098E9A5BCE22ACC0F41D910F1EE3AD1BF3C
-:10C86000B1E58530E2BD7EA793A11E78A5F1E5FA7A
-:10C87000B091F539787F41791AD7E76CF1E69A865D
-:10C88000277517B41F055C8FC00E225E2EEF85C47E
-:10C89000EE1F883874443C5F1ADBFF2BD371FFF422
-:10C8A00074811D86EF8B38B38C4757D9CE81FAD06F
-:10C8B000DC74F2D70654B21FD54BDCB3CE29E1F9B4
-:10C8C00068321E7D7886351EBDD5C5FD7FDD3956A3
-:10C8D0007E2B29E1F6EC2471EE1E2C4DEE4B42FD31
-:10C8E0009A79C9CED882FE9A61DCDE40FF84DD6F82
-:10C8F000A3B6AC20FF22B62BC07F4AEECBBFC7FB4E
-:10C900006A582F81FE2ADE578175A8A90EBAAF2971
-:10C91000FD3BA886CCCB273FCF49E463B5A58EC6A7
-:10C9200091F7D307F3F3FC6C86D40F7A5DD86F854B
-:10C93000FFE51338DF5FECE7117696EC1FD6789EA3
-:10C94000CBF0199A8C5BBAF8FD3DE65A3485FC2190
-:10C95000EFA17CB2C9BD1AC221F7A345C5CFAEC0B5
-:10C96000FD88E9A3D819D3BD08FBBE20F78BD87C7E
-:10C970007EFE7EDDB7BEBBC2183978BC2227148B81
-:10C980002FA8419C7FA48C2FE82EACC7CF595850BC
-:10C99000D072CED636FD37386763FABD31B616DBB6
-:10C9A0003F6AF0035FCD0E52BE14F7B37DD4E07F33
-:10C9B000A5485F8A7C78ADE7F956517835CEB359F2
-:10C9C000D16B52793030A00C1D17BC0BFBDBE3821E
-:10C9D00097F257FCC33F31B47FE24B416B1CFFC35E
-:10C9E000E29FF867C029EE93204F4F923C85B83CF8
-:10C9F000FDBDEF7FB0DE57B85CF44693C75D7DFFA9
-:10CA0000C09385916388CF895A6A3D9EE3308F86B3
-:10CA1000F217F37B20DC418BDF634FD335F07BC013
-:10CA20003ACF125DCB395DFF0EE8F65F749EEB5C8A
-:10CA30009FF83BE4CBEB8B915EBD7C7D7F83F93F20
-:10CA400046F33FC5F9258E1FAE2799F053DBF4B7A7
-:10CA5000C14F29C1F74D0EDF47809ED5046F80C3BB
-:10CA60007B29FBFBCE193C7E02EFADA0F70A391FF4
-:10CA7000DC85FA35B7CBE762BE80B4CB33F2F45530
-:10CA8000D80FF4DC7A3E4F4CCF6D281E35A4DDBCA8
-:10CA9000B67868BB797DF147C86EDE2DF0168FCF72
-:10CAA00044E93E1C9CE41447AE137DB7B42CBEEDA4
-:10CAB0002680FB37807FAC7B703D4ED37AB254B278
-:10CAC0009FEDF7D48E883C08B92ED5593B0CF5085C
-:10CAD00089CF23E99A1BEF4335E84A272603CE3551
-:10CAE000DEA175BB750FE91F37FA7D9D187F5DAC20
-:10CAF000F3F5BB9B7C74EF45DE7393F74E1AFAC6D1
-:10CB0000BCEC86F7B680FD3206C65F586EBD876204
-:10CB1000D72F545BBDE5C7D9DB0F99FA3F566CCBD5
-:10CB20001F743E5541F94386427A1713F9840D620A
-:10CB30008CB6D23B92FD5C8FD3100F73773ED08FB3
-:10CB40007133B7E1A4EF30FDB655DB7E08442A69A6
-:10CB5000F3BBB4BEDFC0FAC8C8ADE4F1FA4611AF0A
-:10CB600067363F8527F9E72EF44F4B3C26DDCFF3A0
-:10CB70003CDCC153E574AFB1764D7F11EF4BFE073E
-:10CB80009543C6E47735AAC438553ACFAB5CEA770B
-:10CB900058F284EC7E0C95A9B6BCF881974620BF6C
-:10CBA000015EBF8CEC91CBFD10C94CA7EF7024B790
-:10CBB0002D1ED687DDCA5D96EFA12C0CDDCBCCF601
-:10CBC00072B28D2F3D367F839D2FEDF4F8818D1E3F
-:10CBD0008FAB5C2FED3CE6247F79E783ABBBD17F45
-:10CBE0006E3CE8207FC65999070240A23F7F198B0F
-:10CBF000E197F4E5CEE68C28FAE1255D96EDE4F9BF
-:10CC000021D4CBE477672C9399BFCFB14CF817EEC2
-:10CC100060BD74BF61251B70A11CAC4257BA13FDE7
-:10CC2000E21A958DCCD8C4087F91EE6C98EFF1E6AE
-:10CC30001101F46BF75DEFCA783B97DB1189F4D7EC
-:10CC4000785C56656F9BFCFCFFF06B5DAE5FCB695B
-:10CC5000D0F7FDFCEE287EDFEF527EAD97453C42DB
-:10CC6000FAB5CEEEE4DFD5E817F72AFA5DDAD89DFB
-:10CC7000A9D84FE3DFCBE85E761BC2FBDAE6577C30
-:10CC800003B44FB20DA387FE0EC4D4920476E1F72D
-:10CC900067309E17973D9085F999275DD6BC5B5903
-:10CCA000CE0FB9C5BDECC88C12935ECC7CB13CCD27
-:10CCB000E212F257F1FBD9D2CFB4B620528ACF6735
-:10CCC0005D60640F7A2A95A882F919A9CA4B8A1661
-:10CCD0009F9FD9F3E5FF1107E3DFB712F8E94FE2B1
-:10CCE00079B3FDD9ACE6D904F4C99EC5CFCFFEBC5B
-:10CCF000C4F493EDA097DC83F443BB299D33CBCFE1
-:10CD0000DD43FB133E5B9220CF58D2F7C9D9FA7DA1
-:10CD10009CEEBC9E941FF902D6DB23E19FD0F7EB7B
-:10CD2000B639B536C47F9F762488F2F945A70FE35C
-:10CD3000DDD73ABE377C46F665C5F77E81F81D45DE
-:10CD40007C2FF4C67FAA433D708BB4CB84DEB862DF
-:10CD5000B8A90E5B71C931DEFF1B25D3F71AEAE0D3
-:10CD60007AE6FA0377F4A01E29F54CA8AFC4BA7C82
-:10CD70009FB1DBC796815EDBD824E388B7EF453DE2
-:10CD8000373EDF92BDA8079F7559C7977AEA2B25D2
-:10CD9000E57B71BC706CFEF2BD08FF800D7EFADE93
-:10CDA00024D4DF28D1F7A2DE5BCF64BB4EF901713A
-:10CDB0007FE27AB25B8FBB65FB27285F607B361F03
-:10CDC000FFD503EB7BF03B691F3678AEF5F857DAF9
-:10CDD0007F307DFFA48BE7071AA09F615E4890F526
-:10CDE0003AB9F0E96E27F07F89AED07EF4EB109768
-:10CDF000D770AA43CCD3D2437C512AF11AA53C8FD9
-:10CE0000C1F8EECE03DF7818D71D87FB1B2B900EE1
-:10CE100031B88DF575E81792701FC5FE30DE8A7B3C
-:10CE2000EEF4239C2B627E8DB61EECD79921EB93FA
-:10CE3000F6627DB0795786B6F5E0BC2B62F8798052
-:10CE4000DE5F912CDFDF65CD4F317A565AE15A6DA6
-:10CE5000C1E7F70EF4F4205C615F74D368F2073227
-:10CE6000FAFEE71D4D6D94BF1D97A3AD592447FEF3
-:10CE700058BDC72A479F26B8AF365CB09FFA67E215
-:10CE8000F995CBEDC3ABBF6ED82771DDDB145AB774
-:10CE9000E4A35A9F89DFE19C6BD464FD9EBAA6C9C6
-:10CEA00057635E6EE7867FCEE8FC93F2C48C884DB4
-:10CEB0007E2E6FBCF6D41CCA9F00FB4A4F946F7D38
-:10CEC000D70C45FA31E7103E83D26E6652EFB86553
-:10CED000E62893DEA1C5F48E0AEA6FD33B3A451EDD
-:10CEE00055A7B86FA2438BDF94E7337E168FD3B676
-:10CEF0008B3CCDC28DE1B5663BFB89D91C9EC766D4
-:10CF0000733994DFAB3DD3A4501E58FBB611E9989A
-:10CF10003F7B2AD3B700CFB5FE6C4700AF2E9F14DE
-:10CF2000DFCBECFFBC27EB33F0FC44762AD9A927F2
-:10CF30003276A6E13D855301A738679E7B8BFC5D69
-:10CF4000717FA281E78AF417AE9ED94EFEBF3735B6
-:10CF50005E0FCC7EFE2D8AB7E5DAEF7186488F71C1
-:10CF6000DF22BED32BBEB729F5A5AA4D8F7E896CD3
-:10CF700060A1BFC8F3D37EAF13FFB8CCFA57879335
-:10CF8000EB5F7EDECFCF06DA3E30E9DDDE41BEF379
-:10CF90005A23EF11DAF429BB7ECCC4774DA57E9ECF
-:10CFA0003CB281FCFAC94DD67EA73A5EAC0CC2FAFF
-:10CFB000BA024ECAB3BA3DD7AA474B3DECB68E472C
-:10CFC000C90E05BDD0D22EF36B6F67BD1D74FF5B1C
-:10CFD0003B7CC8393A6E77B4FBAA484F69C8851ABA
-:10CFE000ACE7F8FF284B2B42FD609B13BFF0CA73E0
-:10CFF000EB4DEB807E2EC748DAA7038A62CE076A24
-:10D000007B04E5229E0FC4EB713FFC7D8FE07E1018
-:10D01000F317B37B5659FC9BC632EA1FF38719619D
-:10D020006A3FA30AFF97B1EA11DCCFE2FEB11FF617
-:10D0300058FC6346E523C84F32BECA8CFB29AF6F4C
-:10D04000A94FC2F3A31EACB7EBFC3CF9E6773C2733
-:10D05000F17B4057DA1FE4F379944316E6FB9DBD5C
-:10D06000BDE458B43D5DE875F83D0ABB9C27857862
-:10D070007E5DB99ED7314AE37E2B0FD0475FE95CD6
-:10D0800089FC1ACF5329A6EFA2350E9257322FC42E
-:10D09000E5F7F0CC548B3D6ECF4F691471E8C1C6F3
-:10D0A000A92FE571F67EC557CDCF6527C373B9ECBF
-:10D0B0008171A9783D55F62B2DE5FBC19FA6E8C7E8
-:10D0C00071FD763FDA59F4A3A1AC0A7FC722C13BB8
-:10D0D000EA4EEB774BCE64F0EF962CDA26BE935EE9
-:10D0E000F197F9CDCECFB4DEAB1F2CFFA1B894EFF2
-:10D0F0006379A55727FFE189645D477C9D83BEE87E
-:10D1000017BC281F42E439C83C08772887E76D30F0
-:10D110009E0FD16EF0EFF15DF57B2CD22E290CA77E
-:10D1200084F05CA8E1E788E4B3BE991AE7BFF30195
-:10D13000E23FC977D03F23847C5DCDFB979CE7DF3E
-:10D14000B790FA45D281933D6DE3E91CBA2E643E57
-:10D15000875263F71EC784129C4347E7EA37F0E71C
-:10D1600086C86788DC182A4AF87E762881FD3C79D3
-:10D170006A783C3D8FDDD7D42784FE91FF00D3260B
-:10D18000CE3B691C24EF44EA85F5DFFBE94A03FA4C
-:10D190007D30475F1032D9AD31FD7280EB3B31BD40
-:10D1A000D2984AFBE235D01B57854C7935D760FCC5
-:10D1B000BB88EF265BF528B4FFCDCF3F6C761CC053
-:10D1C000B791F022E2267FC6FB5B42A678CD5F01D5
-:10D1D000DE5D2193FEFF21C4E75384CF0F2F7C7DBA
-:10D1E000045F25A7F7CC99313E7D31311F5C36FFB6
-:10D1F000FFDF90296E6E1AF7083DAF1C3A2E07FD2F
-:10D20000DEB0F68BBDFF03F3B843BCFFEF047FAC89
-:10D210005FECFD93F45CF0E75590F3F366FA5E8300
-:10D220007DE43D5AEF783EFEE992D83A7E6B7EFE71
-:10D230000F7FD925F93C6B16E2AB99F3D365E8D99A
-:10D24000E366F1FC9608F7D31A52AF99289E0FE0D7
-:10D25000BDD105C8D7A3E85EDE4D38BECEB89D1B54
-:10D26000B34B8CDD7BAD76090C34D972DEEF35DB48
-:10D270001DFAAC7D7B115EE75CDEBFE8BBE9AB70FD
-:10D28000FDF63AE825336659F3328338FFA5C6C563
-:10D29000F83FBD678BFF9BDAE7CCB2E42F703D16F9
-:10D2A0008E70AF0768FCC35AE7C806A857CEE27A6B
-:10D2B0002CE82109EF6F57CE8AF9132A693E918F26
-:10D2C000712CECA47B80317D8579C9AE8AE953C687
-:10D2D000D7C84F14D7A7FE85F8A954D077D5777B48
-:10D2E000EB049CCBF8FAC53A2EDD7F25F5F7F3FE6B
-:10D2F00009DAEBA93D93C3C9520F9F755AE2156C29
-:10D30000BC6374FC7740CA5C4B668D047DE56007A6
-:10D310008F47D5770BFA1ADFDA6BB513B9FC2D17E7
-:10D32000FCDEFADDBE3AE4FFE5EF49789D7CFD3195
-:10D330007F5F1FADFF4DE19748FB5E9F84EFB30415
-:10D340009FC6E1BB06E3B711DD19C74F0D335CA3E0
-:10D3500087C8B3D82CE80FEF75D37B5E0E574D44CA
-:10D3600071F1B8CB2917F279DD3196D0DFB473961D
-:10D370005BBEBF93DE4F15F66C20F1BDDD87E2F199
-:10D380009387A8BF8FCFE780F31FEBA1C8D1B94027
-:10D390001EFCDE1CD935E17255C7EF2C84831716AD
-:10D3A00031D377E5641CBCECFEF1BD680F269727EE
-:10D3B00071BBD16BFD7D0ACFDCFB721FD4485AE9EB
-:10D3C0003BB54B041354316B5C34419CCBE27791F9
-:10D3D000FE9125B1B85426D9B9EEADFCF7A158B5E8
-:10D3E000358E99DCC2C8CFB5C050A21A8CEFD1AD32
-:10D3F000FE96C8066D3BFABB54D515D0B58BE39AA3
-:10D40000F6DFB998ED657A7A3EE5A37C6FD6A87809
-:10D410001ECAE9EE71A92887763BFAF4607674B7E4
-:10D42000D58EEE9776B47E75ECE8A3B3AC76F4DED9
-:10D4300082F01BC4EFAA4EFBDBC1D29245685FBCF1
-:10D440002BF228061E54D3110FC6367E6FE1948846
-:10D45000F3CB78FF40314BC5DF3B1868F3103E0734
-:10D46000D6644453E0BD74635D25FECE81B4A7113C
-:10D47000F3E80793DF27B6DBDDC941A0E7341233B9
-:10D48000B2B7077C3EBACFBCB0437C4742E40B48FE
-:10D490007B5BDE7B6F2CE7F7A7D17367FE7D8B8507
-:10D4A000C21E977679DFBF31C59C07B08805289FDB
-:10D4B000A09A85A95C2ABE9F58E3639B10A8F7A792
-:10D4C000447E47FCBF87F309DBAED2EF570D6C7B80
-:10D4D000807E1F6AB0FB0C6AA9BCCF60509CF61A14
-:10D4E000D8FB49A5A6FDE332F69B61D45FE572DC6B
-:10D4F00086F77C47C5BF1FD12FFCC2DB33B83F6521
-:10D500007C29F737D94BF97D882B3D3FE0FCBCB136
-:10D51000D46AD76BA597777E4EA4F7C4F7294663E4
-:10D520003C88EF4B379572BD404B27BF0A6CD14307
-:10D53000E703044A8788EBB24BE713044B13E41369
-:10D54000FC42E8236B0B22B370FC591718F1AD3D78
-:10D55000EE2FFB1D473F5582FDB659F8DBCA8045CB
-:10D560001DF917DFDBFF61AB7E1275BCE3AD15540F
-:10D570009E508D34CCDF3A22EEEDC30894CF24F3D5
-:10D58000A2E4B835B56527CF9AF6AB85F31EA33C68
-:10D59000B3F6DCFD871580F394C8F7EA4FF36D47C7
-:10D5A000BFB371947F476A69F5AD27CF9AF60F3BF9
-:10D5B000BC98176580A8DF59CABF5FF76299A76F4B
-:10D5C00036C8E1EA6D5C0E576F3BE5427F665D4B06
-:10D5D0003D8B4CA1BC2915E97B6C26FFCEC2C2A0B5
-:10D5E000931926B832F2F486528A7B845713BDE32E
-:10D5F00079816BB05EE6D2D331AF5DFA2965DCA0EC
-:10D60000B4F467A43FF767309A3FEC67518CBFCF03
-:10D61000D5B3DD03187FF1FBC8AF5A57AAF1DFABD2
-:10D62000EBD847F02487DE2178CA54C0F7F08BF19D
-:10D630002DE5A253E0DBB46EC2F760F2BB709E9A98
-:10D6400086F83D82F4827E9BC43EF09A7A21D5977B
-:10D6500080EEB1F78265167C7BFC1516BAB5EBE35C
-:10D66000D2713D92CEF5A2ED7487F3FB48C7F73037
-:10D67000AF8DE898381FE228D26B12B497727FB44E
-:10D68000A4579DC1E9556794713C056F758FA178CA
-:10D6900080D28BF7251BCBEB19DA0B6E3D83BEFFD7
-:10D6A0002FE9B7A81CE8678217E4F1E15293DEF98D
-:10D6B00067F8D91F2D35E9C1D73A0E00F33D43F382
-:10D6C000D9F372FF4A71888BBFDBC3F7DD3705BF23
-:10D6D000D84BB9EF0E9ADF6C54AE6AFA33E0907211
-:10D6E0008372DBA660FEA4E2423E0BA3FC4E417DAA
-:10D6F000EE3F36615CB4C1CF7A712F7C08E508F04B
-:10D70000E6AEC870A3FCD47767135FA0FD4FF81492
-:10D71000FBF44BA54C9E5327E97913E78BBF75FCAF
-:10D7200007E0B940F0D48AFB051FB2F854564558BB
-:10D730009D8DFE597D1F9D2F7D33E5F79A5816F775
-:10D74000935F593CD4A3F3FC3119174D1007D594BE
-:10D750003F230E6A8FAF0E16174D1007B5E8EB8307
-:10D76000C541992D5E6A8F83DED63182E2D0B765DE
-:10D770003A28FF51EAFD32FEF96AC7D7E97B47AF85
-:10D780004E565846F6C571D26DC23FC650AB33AD4A
-:10D79000FF4416FFDEF596315EFA8E28FE719AF28E
-:10D7A000F1E07CF07A60DE8E794ED24BABB2F7DBE3
-:10D7B000F1EA1676C965E155C6D9DD1D3CCEEEF11C
-:10D7C00033FA3D4D49C7F8F7749FA7DF8B642ACF22
-:10D7D000D3ABCFF5515EAB9D0E9E8EB67BE9779CA9
-:10D7E0007CD3D75129E8EFF15F9C3FA84AF812E4B7
-:10D7F0000FFED9F4BC041DDDCE0D5E14B98BE8A973
-:10D800001D4CC5EF8ADF1670FA342D4E4749D78B71
-:10D81000E9E7A3FD45C6B96F2A0CDF857223BFD3A4
-:10D8200024E97B228BE3F7CC4D2C2ABF4F66A62739
-:10D83000E05FA77B77B96C1FE11FF330A75ECC17C1
-:10D840009E5C837EC7D39D5CE927B992F8D50E1004
-:10D850005DDA9B7D0B507F3A5AEEA2BC9504FC40EA
-:10D86000BF5B7B297EB888EEDBF8EF845E29FDEE96
-:10D87000287E5CCF4EC01FD790AE15C14474C57CC6
-:10D8800086BF80AE278AF4C791AE929E3715EA5FB5
-:10D89000995D64965F83DB312CF1F76D9E16792DCF
-:10D8A00030CEBFE27BBD686391FF50EFC5FAE21B4B
-:10D8B0005973A2EF823D5BC6CFDD5AD6FBD268B466
-:10D8C000FBCE3291B71938ACA19FA6655CC2BCCD26
-:10D8D000E3F86121E8BFD0CFF639C4FEEA30E16950
-:10D8E00040E46FBE89F99B60E7BE3C3B9BD6B10527
-:10D8F000F338E1F92991E7598B63E33CA0CF627CCF
-:10D900009EA91186F7D3FB63DF6769A373379E8FE8
-:10D91000F1EB47ACDF67E1F58599B23D356A898364
-:10D92000327F04EDB6B8FD35356A39EF5830628D77
-:10D9300083F27C1D79BE6DD4E7440C731C9455D0E2
-:10D94000F8276B65FF1DD1B2C9E638E8E2A86E8EF4
-:10D95000731AF3A3E638279CAF54977EE8C7FBEE13
-:10D960008FA05E3F796AE43CD25FDE9B870348C7A5
-:10D97000DF9D73FB7DFBD10E07FB00AFE40FAA57C1
-:10D980007FD8CBFF0F02C2B069008000000000000A
-:10D990001F8B080000000000000BE53C0D7454D5FF
-:10D9A00099F7CD7BF393644226017480A02F01DCAC
-:10D9B0005843187E020109BCF9C94F157480A0B103
-:10D9C000207D842CA55D5A83959676EDE6416248CC
-:10D9D0008240E8D2EDCFE9CF88D03DAEEE69E87164
-:10D9E0002991D20E6229964A634B8EB14B75B0597C
-:10D9F000165BDBA295DAEEF194FDBEEFDE3BF3663B
-:10DA0000323128B4C7EE8EC77373DFBDF7BBDFF7C3
-:10DA1000DDEFFFDDC79DC58CB105F03FF3C60C8D72
-:10DA2000B18110FC3911FB7ED380B1955364BF22C4
-:10DA3000669433B6384FF6AB4C6321639D2EB99E86
-:10DA4000590CE6BFC09CD4DF66844C6B2A63C16569
-:10DA5000AA985F4FF05F5A2DE7EF8E0501DE2A8707
-:10DA6000E85B2B628697B10F31D95F4AFDD5C97E3D
-:10DA700094FAF732BEFF81F84ED382F58FCD894EEE
-:10DA800034C6C3B348AF1E9DFEB787FF3945E233A6
-:10DA9000C5C4F1F73BBEC0EF7AA312C1737EFF0D80
-:10DAA000E0BB86E4E330C7F77D88DFFDC4CF2738CD
-:10DAB0007EEF037CDA099F5EC027FF2FBFDF0F2BAD
-:10DAC0008D3DB8DF5F808EAFD1B997733AAE60FEFF
-:10DAD000A34477809F43E6F8C4A08F311C9FC3E125
-:10DAE000BDE8147264359B28F709D9C77383FE8299
-:10DAF0003372BFCD7A50B3E3BF99F46455119FFFE1
-:10DB0000EBF8A74DAB38D5879F81E72ED7FF06C727
-:10DB1000D3D67F8AD67767ECE712E3CAB1AD846FBC
-:10DB20008A5E8BE6F767CC6F14F4151CEB8C5936C4
-:10DB30007E306B3BF1276997AC9D6497065CB2BF62
-:10DB400083F4665709873FE1D8CE18E20FFC3B45C6
-:10DB5000FC9ECAF9F7FF9D1FBF3584BC94717E48B7
-:10DB6000397C6C8EF13B94B3F71BBE707E6A707C7F
-:10DB70004AFEFF0AFB15D27E429FDEEDFAA43E0A62
-:10DB8000BFCF9624F93B2908CF2784741AAFDA70E7
-:10DB9000307C3DFCB9BAE511D544B830878D632C93
-:10DBA0009A60B16DB0E7AD2CA632F061D180C97C2E
-:10DBB000E536BD665F243C5C5E87E87F83ECDFAAC8
-:10DBC00045E25CD8600CE38B14DEDEB5784E49BCD0
-:10DBD000D9D7D2F05E78CCFB88A03B10B4E9C9B5A8
-:10DBE00086EF0F015F6CF150B22FF8B3EA135F9E1E
-:10DBF0008C7C58552AE17E3386705E2C94700FD24F
-:10DC0000BEAB92FB7C8FF773E5FC1FD1FC145E0367
-:10DC1000661A5ED6CF28EE92783D766C80CECBE544
-:10DC20008B3D74DD1C689B958005E7F1A10D5B556C
-:10DC3000D36E1758AF1E04FF760F4BF649AE5276DF
-:10DC4000A097F6BDD6786D0A0AFE083D4DE29960B0
-:10DC5000018BD9F13BCCCFE71AEF6FB30BF7A3DC05
-:10DC60005E7BBEC79DD7DBF82EF560B52FA9DF061A
-:10DC7000F300DF7509E707E606EFD5EF0B72BED3B9
-:10DC80006E4FAE9E8EFE1AA2E3357E2E29FBF31355
-:10DC900033DDFE5C317E8F046DFEFCDDAEFFB760D0
-:10DCA000BA9ED9ECCFE348779BD7E1423E9B7E6694
-:10DCB000C400DE65FC2D4EB513420AD9A7A47E56DA
-:10DCC000F1F52B76B396DE2CF3AF0F39685EDB539C
-:10DCD0006C432FC00DBA2E36476DF3E2413E7E34C1
-:10DCE000A8500BF41D25FE6FE1F89D0AEAB45F9081
-:10DCF00069CC009D6A5831B918F16BFB398707E987
-:10DD0000125B9E9F827741C093FB1C5B96DF18F3EA
-:10DD1000A6C69F15FB9C0A723AD0FF133F1FE474FE
-:10DD2000A8051BFD085FCD5384FEFC9AF8DAE114C8
-:10DD30007DEB0DF26B03493BF43B92F7956E29970F
-:10DD40006F91FECB78FD8DE0FFC4AC85883F638E7C
-:10DD500059F675BF253B38DABA84F417EDE2BCAC4E
-:10DD6000E4799D43BC475BAF869516E29387C51562
-:10DD7000F01F2EBF6F5F3790525E61BC8A7C3E31D0
-:10DD8000D3F815B6A3C1013E5DA47379203D1FB140
-:10DD90008DBF194CCB072E6E8C221CD8D90DE7F6FF
-:10DDA000C26A755C13F0EDCF783E95941FD4DBCF3B
-:10DDB00045B67F4E9DCB9F8369F17C38BF12F488B6
-:10DDC0004D7004A6E9C3D779438A9433714EDA23A0
-:10DDD00048474752DF787F57211FCF79DAB956E895
-:10DDE000535E08F77952F097F9C6E17EACFC645CAB
-:10DDF0009D0BFE95257F8603FA6BF12FD87F207C43
-:10DE0000CE8972B0A65DB9323DE914F01F4E9EDF97
-:10DE100084D078826BB2B9C27FC06FE0235B096E99
-:10DE20006333C0CDA22F53429C7F5342493E4D21C4
-:10DE3000FC0D0ED731273A0DE1C254E69E9582BF04
-:10DE400046E01D74468F5E0F72D061293ADA557331
-:10DE5000CBDACE12E4ABE60C4C83E626E414ACEB52
-:10DE6000F0977AD1CF3D27F643782E3847F425FE38
-:10DE7000229AC73468E7D66F3A0EE0D8DBD3CD4A92
-:10DE8000C4A32ABA278C642D683C781CDB3BC04CA9
-:10DE9000639CB275D157A221D8A77FBE3380A2065A
-:10DEA000D159FF54C0AB41E0A51975AFB2319045CF
-:10DEB000B958203E07FDBA37B00D9E37347F64094C
-:10DEC000AB803951E750C283C498EC7229C2D58621
-:10DED00012659C6797C1C62DDBE24CF511371CF724
-:10DEE000A4C657DCC8EDD3AA10F0D32677DF17F409
-:10DEF0007D5FF07337E0D05F4E00F219EA0DDBE092
-:10DF000040FE991E8E67BFB5E2B69B81E04B652C43
-:10DF100080A36EA44F4DD19798AC05DC3A898B77DE
-:10DF2000E975B0AF38D7D3AD60EBFE0EC05A9C4E4A
-:10DF30004D5D5D10B7C9F1E931260B60DC56663DD9
-:10DF4000C4404EC2E61E6702F0B8B1F9F50D18F7ED
-:10DF5000AD31DD7A1DA078CF065F0DC6B52B4CC163
-:10DF60009725CE57906E0FFC877C71C55FFD810BA6
-:10DF7000F9BC50611300FE9D113E2EF9E266DA2BCA
-:10DF800076BE6819FD2D674B763D639B7F5F287FCA
-:10DF9000DCF95BE08FD96CF665A093A9DEA588CF8C
-:10DFA000A576C5A796D03407033A5D823F07DA37D6
-:10DFB0003D877ABAC6AF051CC887258CF8D728F6E6
-:10DFC00078AB55DFF50CC4AAE12D7B7A4A00CE3D33
-:10DFD000675486FCEA587D0021E1CF83F034211795
-:10DFE0008EBCAFF66B304FFBACCA703FC947E0B791
-:10DFF0006F2E3C3F3700EB61EA3D55C027D8F70E46
-:10E00000C3ADEB302F77E1EBEDC8A75CD6121F0B49
-:10E01000FDBBFC0E16F7A4E802BA2DC117C7658533
-:10E02000F6D235B9AF236D9CF892FB99306368BB8B
-:10E030002DA37F2ACC5B26E5B61DCE13CE6199C1F8
-:10E04000CF439E2B8B707995E7929B21AFEE2A6789
-:10E050004A3EB3C86BE639C432CEE180C6F52471BE
-:10E0600046A5B822B1571B53057D6BAF83F418F258
-:10E07000B4C34A01FC11579806FCBF5BE04B3FE07C
-:10E08000DB8196C2587749EA3CEE2E3BF127A58208
-:10E09000F159D7A5EC11C32416FA7789DEDD5FB2FA
-:10E0A0008A507E3FC47A9DA8D7F762C60CF87C9848
-:10E0B000F95CD86F62016AE1BC5DC8AF037B9FCE9B
-:10E0C000473B129FE82C3C5F46AAC2EC7632B34530
-:10E0D0004E9C9774C3E4B8B49F1ED34F76D90B2DD2
-:10E0E000D9698361BFB026E231B3F891F86CF38748
-:10E0F0006807655FF3B530C4E3EBB3A3CF72BBCB66
-:10E10000D74FAD307E84FD83B38C53D87E13E33D6F
-:10E11000F00F17430F525EF2F674E334DAB54C3B5E
-:10E12000760EED989E9287E519F220EDD820DA312F
-:10E13000185A8EFA0A7C63F55767C7CE4939F8003A
-:10E14000FB00F207E8F925D97F0DE801BEBC84E7A2
-:10E150003E8361F52DCE8A884CDD07F829023F7C8D
-:10E16000AE807D57B6FCF04FCA18DE5F00F3147125
-:10E17000AE9846D6A0DFF87AC0E39982F6C21C4476
-:10E18000BA33F9028ED9497999FFC420CA8D23EF99
-:10E19000BB93CD2C7E3079AE1B9DAF25E9423D82ED
-:10E1A000481EE95098E9B88CF4F8008909EF241763
-:10E1B00016C941C75285E8EB28618D68CFDB7168CD
-:10E1C0003E63DB972ABDF8FCF170118F97A6F2B879
-:10E1D000707B618B3F00F3B63B613EDAF33293AD67
-:10E1E000989E82FB7858A5F937CF31F2D07141DC87
-:10E1F00047F1928C57E53C5F98C79563C33CCE28A6
-:10E20000AF881685719F7126F11DE2A8B1D4F7C6BB
-:10E21000638EEB445D84FF74872D8E1898D4C2D032
-:10E22000BFBB0DEEDF33E9BC219CF4EB3710BCBD66
-:10E23000D2AF1B37227E8BC7FA1AD0CEB900EF7D42
-:10E2400025297F7D68E9E754D896DD122E21FCAAA6
-:10E250009AF7B45D07E71D0C4EF1A27B8F57B7F814
-:10E26000D1EF6D9FC0F996B9EF9630F783736E10BA
-:10E27000F304BFA4DFF740F8ED847D30CD77601C58
-:10E2800050CCE3807BC3A5B44EC60330DF72C1BC63
-:10E29000E04DA0A718374FE37032F7BB57F033E5D6
-:10E2A0006F030568AF196B217F1115FEE48556E3F6
-:10E2B000A52110CA81D67A6AC1FEF747C0C00D6A8F
-:10E2C000567E200B1D77D63CE041386DC54D1EF4BF
-:10E2D0009F1D4698E036AE0EBE3464B3B7DB8BD9D3
-:10E2E00064C4EFAE860FBE3464D3B7FE7C8E2FFAC3
-:10E2F00019CB9D82BB12E504F03D1E74C717034382
-:10E30000DD7E16739750EBD4314F0CEB341E35D6AF
-:10E310003213F3F1AA731AD5BF0A5972FE5638DACE
-:10E32000703123BF1EF5B7305CE7863ECE8F2E7C62
-:10E330009DE6DF59A532CB8627D89F35145065C49A
-:10E340004BBB51C0006EC77C25B60DF068F0AF27FF
-:10E35000FFB375512E3D877D09BF3BA63593DF92F4
-:10E36000F15547241220FF7495F1547C76F47EC455
-:10E37000CBE54FDAD507485E5376757398DBD54FFA
-:10E38000E173693FF61D7F81ECC77685CBE176E0CE
-:10E39000F7B7B3C8C756A107DB0BB3CBCF9785BC84
-:10E3A000BE3D3DDA86F00DF069FE59EF3DDEEC90A2
-:10E3B000F1A6E0E3D5F207F8F12F619B5D067E7CC4
-:10E3C000313C7E381FE0D78EF64295D6E2094543B0
-:10E3D000F9CF11DD47981943381ED64293546F94F4
-:10E3E000A1BF1B0E27CE70DD2A41DFBBB5C7DF8280
-:10E3F000F086DB35E38930E5853AB7A3C22E33D604
-:10E4000023FCEE7BB3DB671C604FB1DE8D8F6CF3BA
-:10E410008F8A73EEAB348F229D37E9DEB5782E5D9F
-:10E420008AE1F74EC1BAA7D9887ACACA668DB2CF37
-:10E43000568233506A6E88929D5F3ECAFC6D625F61
-:10E4400041675911F911D8F74BB96AAA3F1A5D878C
-:10E45000C2C64F11EF3633FA0BD4BBED650EDD5259
-:10E46000A8253DECAECA8929D0CF9965BE887C0528
-:10E4700011319C00BABBEC0D8A8BDC4B148AD3DCC7
-:10E480001EC8E0B2C8F979E16F20D6A07176D6F047
-:10E49000DBEB1D8511477ADE0B2261D8EB171147A4
-:10E4A00013D6E5A53FC3BAC9B7B3C8C545A14FAA9E
-:10E4B0007B539ABFCC9CF746D845F39488A84B0869
-:10E4C000FFB7D2CDF32BF663C0CFE65FFB2A437FC5
-:10E4D000203DB098A5D8FCA2F48334627BEEC6BA86
-:10E4E00013D279261D8EA4B328C2D2F605797544BD
-:10E4F000781D438D54A6C657AA8CD73DFAD3F9058B
-:10E50000F8782264A7D8D008F8ECCF8ACF603A3EDA
-:10E5100045117E2E7D954611C203FF3C16DBCE10C1
-:10E52000C85F16FE7E6B46E87AC45363566769C9B6
-:10E530003BC6AD37201CD9B7C5AD7A24DDBE9644A5
-:10E54000B87D2D8D907DCDBE6F85E0DBD5DA87F768
-:10E55000AAF73BF0CF2C7AD49D7832AF02F070BB93
-:10E56000AD4F92BE96CF1A45DFB87E7FF886FE4942
-:10E5700048E751219F68DB31DE30741E8F7C22C258
-:10E58000E53878538CE63D3542FC919C078CC1BA46
-:10E59000DC4871C8FCF71887742F1CC8A338E4CD79
-:10E5A0007D79E8EF9F1A0A658D438E16F74CCA16DF
-:10E5B00087F48D1087AC8FF078F5F87FB928AEA876
-:10E5C000BEC0FD7CF5851E15E3898D119DF83E7F4B
-:10E5D000A85F35414EAA310E01387D220EC1F914D3
-:10E5E00087BCD9A3225EF32FF4D3BA6AE8631C3246
-:10E5F0007F843804B05051EE0E5777FF0CCF2D9327
-:10E60000DE5315E666BBDC5625FAE93D895CD75D2D
-:10E61000B62DCFA4734E979BF86C8E6F6A1D97F73B
-:10E62000CC7923C9578DEA2DC3FA4017CB0D201F93
-:10E63000DECA1953C10A785E837171174E05BABBE1
-:10E64000CEE6C52CCCAB3D7CFCD3B963F6612BED9B
-:10E650008F47E8C55B3937C4441E6414C0FA4FAB1A
-:10E66000467C31F8A1AEA99FF7717A36911E6D16DE
-:10E67000BC09EDD1289FBE55C48332FE7A6EA51227
-:10E680007353D2652C590AF3E709F8AE393C3FAC15
-:10E6900055BD346F4719A379B75A17A97E313FE1A9
-:10E6A000D275E8CF4BACE7F9A2FADD937918EFDF2A
-:10E6B000A231159EAF6C8FB6917C9E75513DC38083
-:10E6C000FF503F2BCFF412DFF2865C69758E5CB091
-:10E6D00064715BDCE2CAE833757541363B24DBCC00
-:10E6E0003AC4C188C83F2BD88CCBC0974BECC14EE5
-:10E6F000A4CD3D2D74FC51367CBDAC2F6C9C617C4F
-:10E7000007E563AA33F1EFDF017EF5BDE6A2F73A34
-:10E710007D7BF7DE5E81758B1E8DEABA329F01CA62
-:10E720008A96613E8B3CA0BAF4E92694CB23F9B2D9
-:10E730000F060DF03E82092BF9BD8F3619B6FEA9E2
-:10E74000C843AFA0DF3B325ECE7F95AF977D2BD124
-:10E7500084F7358E4CE0FD4B11F5518BCE37A1512E
-:10E760001EBDE597DE6CF6F1744DBABCDE51B5897D
-:10E77000CBEB28EBC0AEBF18C9B22E67A9B9633A7C
-:10E78000F0E3C89083EA389067C5313ED838C37C3F
-:10E7900019F9B57D90F3F5C86BF7FBF09CDC6313BA
-:10E7A0000F64B3F3BF11FE285E1DA3BCAB7BA6C8EC
-:10E7B00077D990867E6BF7A2A74E55C03EA7E74F4C
-:10E7C0009BA50209C00B0FC6CB72BDBB86E77129A2
-:10E7D000FC9E579BD0FEBCF64A43367DAF8C98BF5B
-:10E7E0008FA4CDE7EF45DB7A34E27FD189BA7D781B
-:10E7F000EF275EDDD3AFC1F9F6FDC6C1304FE99B0F
-:10E80000CEE3FE11F10A005E455784D7DE7959E464
-:10E810000DF072D58C1F8ED74F6A187FEF53617839
-:10E820006A2A87E3C9441D7381B0F739AF7E9EEA37
-:10E830008E7D0907154F2E0DED5351F464FDBB7B02
-:10E84000B0142320B678C9391545CA7C504DD3BBC6
-:10E850007983B969FD7B5BC6A6F5576D9894D24361
-:10E86000F87F79644A5ADFEDFF405A3FC866A7F542
-:10E870001B96DC9A06AFC6174EEBD7F96F4F9BFF7E
-:10E88000417D455AFFF6B25569F39706D6A58D57D7
-:10E89000FBF63C84E5A368F94C6D2C23799C897CBC
-:10E8A000CD3B63903C6E1FBCDF877211AF8E521E52
-:10E8B0003D90DF5F8CF5EBE79CD9EB0B0FD6A8D230
-:10E8C0007F17A3BF3718CFD7E4FC606922AD2EBFF6
-:10E8D000AE86FBE735354AD63A41A63F967E58FAD2
-:10E8E000E5CCFD33FD6EA6BFBDF3E67D1E5EEFE712
-:10E8F0007E7FA59083B6B29F7A13485703AF2374E7
-:10E900001703BD5EBA8F41FA757CE5DD93F1BD5A00
-:10E910006E9939D65D92F2D7E1B218FB258CE7FAF1
-:10E92000626CCA741C8FB175D3A92EAD85CBF9F377
-:10E930009BC4F3F5D8829FAEB5F12DD3FF063D33CE
-:10E940007F50C052F14AC31F8D4801E0775BF3410D
-:10E950006D1CB461EF31CD6E874E57FF6ADC087EC7
-:10E96000FA633519FA84EBFA8696BFA31F78B99536
-:10E97000D7DD0FB57A581CE83BDBEAA3F6E7AD7E9E
-:10E980007AFE7CAB4E6D476B19B5F1D6008DFFACAE
-:10E99000B58ADA675A0D6A4FB4D6537BB2354AF35B
-:10E9A0007ED4DA48ED8F5B4D7ABE4BE8E9FB051F5C
-:10E9B000A34CD615A2C71D0AF1B501AFEA2EB86067
-:10E9C000A8763B0F7CFD4236BEBE577F12AFEE9D50
-:10E9D000847206FE2AAB3EF5D6C8B83E79DE84972F
-:10E9E0008C87317F413991753AC0EF31C4CF8DF5B5
-:10E9F000B9A2ABC7EF88A8DF1C29648DDF1670961B
-:10EA0000E5A33DFF4A3444F67CFC4CB2E77EA6A564
-:10EA1000DBF39261F67C2DE91D3B897552AC2FD258
-:10EA20007B8A8C3A4841AD4EEB641D64D11F791D41
-:10EA30006434FA81EE9368B7A4DDBE52BA879DC7ED
-:10EA40006CE327C83FE99F87F90F7323F98F2AA149
-:10EA5000B34C7B93E2C43C41CFEE579617A07D7137
-:10EA600023823C4F3758159E3393F701F66D281ECD
-:10EA70000EF7E5EA5EF2E73B9271CEEB14C70CF7B6
-:10EA80005FE97CC058C8EEDF810FAFA6FB45CE879B
-:10EA90001AF5BB896DE09F8F2418AF93CDE1EFEBA2
-:10EAA000A41F3C7281D7312E694A8CC1D185584B45
-:10EAB000CF3C680F7F8E8D8BC2395B931D810330F5
-:10EAC00035EFE93EDD03F38209736C0E8C57C57395
-:10EAD000685D68C9CC18F61BA2AF937D0A69E97E10
-:10EAE0001223D4A4DFA1225851467F626ABE8AE76E
-:10EAF0005B9AEA03DCF5B34DAD16CE65F9C516A6F3
-:10EB0000978B7AAA37AB7FDFA8D8EA6C1A0B7422EE
-:10EB10001DDA6776F0F77A19F226F924EB6D320FD9
-:10EB20007F8419BEDA2CF143BB78EF92F9BEE50F72
-:10EB3000D34D7F2DF05DF19DA0F72D6C03E3F723FE
-:10EB40001C909F20FFC6B862074A86CBDDC1591FC3
-:10EB50009C5C4BFA6D29D7266FEF51286F177913FC
-:10EB6000D3EF73D8F318993765E6470F0B3BBB0B10
-:10EB7000ED2CB40F3B19E55B1D4A6E609F92CA975E
-:10EB8000C06FCE40BA16D58AF72FAC651EAF177E80
-:10EB90002E2D5F1A116F91973893E75EEC3B9F978C
-:10EBA0003A77AFABC78FF71CBB667EB5B109F936B4
-:10EBB000D343EF399916D7D1EE64D2C37C161B37F5
-:10EBC0003775DE2AD3CE637DB61382197CDFBB1383
-:10EBD000BF040078F901475ADC5350951EB7DD5D3C
-:10EBE0002BEDECB5A1030580DE6F4B3C5954D45599
-:10EBF00079FCE911CFDB756E2F18DA3BDBFBF5767C
-:10EC0000AFE1F1D9CE7F3B9E8F7B647CD492761F9F
-:10EC1000D6C17BBC0ED2EF4E5DEBC2FB1E9D5E8D5E
-:10EC2000C737BAA33EDBFD95DDB58AA09BE3E513AC
-:10EC300078A9C1E514078DB45FB79017D9CF2D37E8
-:10EC40000DD2473D10C53CB9CD3B4EC1FAA81CFFC3
-:10EC500068AD22E485D797BB445C955BD61B77A053
-:10EC60009C4D583F1BD9E68138E93C3CF794F7525C
-:10EC70005CE59DE832B3E1FDCF025E9733504F79FA
-:10EC80007FBE8361DEDF5592DD8FFE632D8F33DB28
-:10EC9000F459519C6F015FA629C3E77D5CC8C1434D
-:10ECA0004E9043D8BF6BDA5D744FAC6B3223FB5D83
-:10ECB0005A37FDD1ADDE2C72A8DF47E7E7F431F912
-:10ECC000FE3DEDBE449BDED0B816F6D59E6701B47E
-:10ECD0001999FAE69CB0BC712DDEB7A8CA0DE0FC0C
-:10ECE0001AF5C716F2B123C0A8DEA115367BA8EE2F
-:10ECF0005CACD1FD08892FC4EB8FA19D1A4DBE33AA
-:10ED0000F181FD48EE463ADF4CFC28949FF50EF366
-:10ED10000BCDC66816783F4FEA55BA7C394791AF9C
-:10ED2000D1E849F3AFC529FFFA6CEDA675784F6DB0
-:10ED300027E3E3A76A4394EF67F6AF959EB7693D73
-:10ED40008D782E6D535D247F99EBBB4A385EDD27AD
-:10ED5000AAC5BE3E05E57F5755510EDA772F1A6AD0
-:10ED60001B5F9FA930CFD5DAE2A6C2482F8FDB6B9D
-:10ED700019C9AF578FFAA6825C78CFA82053C07705
-:10ED8000C7DB7F3CA7BF773EB21E83E4964C3B9720
-:10ED90005BF636F0A54088F518F6703FBF2FB299A4
-:10EDA000E6497EEDBEF1B781F83BF06DCCC2F4FAD6
-:10EDB000D4BBAD3F2975F9E388CF392C07F97C899D
-:10EDC0003DA890FF8E18A477BEA45DE5F756C6C98E
-:10EDD0002E90837D123925559762F8DE03F5CB64BA
-:10EDE00014DFD0CCEBC42B2FA2DB47EB260930136A
-:10EDF000F1428D8AF2CFEDEE25F61ADF1F96E1BDC6
-:10EE000015C572909FBD11E51AE69530F34FE7B234
-:10EE1000DCE799EC6B3EB80EDA4975A29E26E8193C
-:10EE20008D1F12EFBF94DCCAF820B38E2AEBAC1D05
-:10EE3000A2CE3A5A1D956917896F32FECDACABD27E
-:10EE40008D3AD08FB76ED25837F19DC70BA93CDFF2
-:10EE5000CAE375787EFF6E9EA0EBF0D9A45FA4E7AD
-:10EE6000D26E65D2F9E4287EB1FB4C7B1EC2694BA1
-:10EE700034517DFE907FDB2905E3DC844B67367DD2
-:10EE80003D9C9FEE373A84FDDB5627EAF0E73EA52E
-:10EE9000627D609EDF52F1DE5E5522407EA14DC94B
-:10EEA000FEDEA1BB8EFB9B617E22E3FDCC7FE6787C
-:10EEB00063AE5296F41FAAA053FA57E08F62D7BBF5
-:10EEC00043F2BE9761E8BEB9A9F8B3FBE98F321DE2
-:10EED000E323BFADEE5B9A65FF617163BA5F5006D5
-:10EEE000F9FD30C9D76E9177B7F9F979CC4102B203
-:10EEF000F801887F3F5B07F254D99F6E6FF2CAD248
-:10EF0000ED4D663CECF6302BD7060FE2E1D63A52D7
-:10EF1000DEF478B6B89E91BC1E2EB454ACFF8413B8
-:10EF200006C3F3D08A4D86E7E1F2BFF37934D6F118
-:10EF300078A1A3AC298A7993AC3FEF5E741BD957B3
-:10EF4000F0A33D75B6BC49DE7778B7F52829AF5AEE
-:10EF5000867E66D6A5BA17FE3DD5A1DAFC4D27B14F
-:10EF6000AE7408E411F5ED70BE9987F725ADE7554D
-:10EF700076401F5EBFCAA44BD6A1C6D78B7B2BE7BA
-:10EF80005CF1C5788F7290BFA7D0064DBA7F02F4AE
-:10EF9000D07BA279E23D5166DDC9ED6EA1F773F138
-:10EFA000EA9655F6BAB3E45BA390E797AB4DBA3750
-:10EFB000D43142FD4FCE7333C31A87EFC7AB3F4BFB
-:10EFC000FCC6CFCD302F97752D7D86F9BD3A98E7D9
-:10EFD000BA68AAE375CCE72C3A87BC7F6224642C1C
-:10EFE00057891D80F54F2F7A8AF2CDDF27D8587CBC
-:10EFF0007F92CC37359E6FCA3C56DA8D1AF589CE92
-:10F0000052183F7C46A33838EFE9AE5358770F9E2D
-:10F010005947399FA1ACCCC37DE43D2689F7D5E69D
-:10F02000AB9598AFDADEB748B8DF69ADFF05CAC562
-:10F0300093AD516AFB5A0D6ABB5B1BA9ADD28C30F4
-:10F04000FAA5AA7ECA00D9822118B7E1517516D651
-:10F05000DBCE7F5785F9DFC8B7CAFE68DABCBCB221
-:10F06000C6B479902FFF1AE7697ECE4FD71285EE8E
-:10F0700027DC39C81E52F42C76E1FFAE5DCAAFBF63
-:10F080003676A9A89EF29791EC1223BDAB1A14EF25
-:10F090005DA57D12FAF7789D4E7A91D4437CFF4AA4
-:10F0A000FECDA2F59DF8E77CA067CCC7B81D4BDD6F
-:10F0B000F3A0EF1B83E2BBEB9B4F2EDA8FF7803A76
-:10F0C0005E94E3CBF71BB67166D534E3F726C73001
-:10F0D0005986B873C7C9F1CDF45DB6F8AE26DC58D1
-:10F0E000583CC052F71F33F9B5AB9EC7EBF27E4DCB
-:10F0F00090F1FA9A1CFF64BDC8E3801CACE3C9FB25
-:10F1000013B9237C47F4F17A6E0F3E23F8D4E9E279
-:10F11000F71716677C2F1212FB8EF4BDC836313EEE
-:10F12000DAF721ABC47E4D62BFC7E6446FA3738B91
-:10F13000F2EF329AC5F30567626D633068F4B3ACE1
-:10F1400070960B7BFA6C3DBF97ECF21B1A9E0BC0BE
-:10F150006B20788DFCBEA61C5F702139DE48E30D64
-:10F160007C7CC10593EA4AF23BBDE5F565FBB74EF1
-:10F170004DDDD3E9C0FA8417BF57E1F79FBE26F0F3
-:10F18000CF6CE5F72A77F9C47D1F3675BF81700C07
-:10F19000FE7DE6EDF5B70CE177C7B0FF06DA5F7CE0
-:10F1A0009FB300E9ADA4E7FF40CF33FE9D81F5F5A5
-:10F1B00093F78BEF7AEE433D612D1CEFE4BF9B602C
-:10F1C000CDD96FFF4E6841FDEC66317F33C1DBC0A6
-:10F1D000E7679107218F73F7634DF60AE0B512BC1C
-:10F1E000D51CBF5BEA757EDE19728BDFFF139EE2D2
-:10F1F0007BA133D1751EB4E7C97F07C09A4EFB5D72
-:10F20000019F76121C53EEC7C4BD28AE1752FEA54F
-:10F210003C7C4BC8DFEC7A45CAD517687DF335A333
-:10F22000FF1B042FE3FBA4D1E828AF887E93D6F917
-:10F2300093F793FF95FA57898FFC9E2C532FBE2787
-:10F24000E8877DFF83CE0BE22FC413F63D742DF6C5
-:10F2500005B87182E349C23D762DE032FDCAEE99D0
-:10F26000FC2FBAA2684270460000000000000000B7
-:10F270001F8B080000000000000B93E16660F8514E
-:10F280000FC121486C62F17A76068678160686B937
-:10F29000AC0C0C3540ACC8499AFE5540FD4B81780A
-:10F2A0000110CF06E269403C11887B80B81D88655B
-:10F2B00080E68903B11010F3023107103303F13FE8
-:10F2C0000E06869F1C08736E03C51E93683708DB05
-:10F2D000F220D8E781FEDF02C437C80887513C3CE2
-:10F2E00070163F03439D00822F2C882A9FCD8F608C
-:10F2F000F38A5266971C503F008DFE9C5880030095
-:10F3000000000000000000001F8B0800000000004B
-:10F31000000BE57D0B7854D5B5F03A73CE3C333312
-:10F320003909794C20E049483055C0214004A1F505
-:10F330001010432FD78ED42AF5A2774004E49554B9
-:10F34000B1D2AB6D46264050F4060B0A0A3A50A8DB
-:10F35000D08246C4962A7A07454BFFB6365A6F7D4F
-:10F36000D4F6C6DAEBAB18E28362FBEBEFDD6BEDB4
-:10F37000BD33E79CCC24A0C5DAFB874F77F6D9AF25
-:10F38000B5D76BAFBDF6DA3B1EA884C273013EC68B
-:10F390001F96DEE60180E24C3AEAFAAF2EDA3386B7
-:10F3A000FDFE7F3DD11D46A69E4C4F0305602C2BD4
-:10F3B0000713A004E05C1FFB95D59BFCD323BF3D46
-:10F3C000AB08E020A8E0659FD2DAE401FFCCFA396F
-:10F3D000F82144B1DCF5D360796710DB25A8DD970F
-:10F3E00080B74B5718E5FA70CC800BBF9B3EFA9D57
-:10F3F000F5337473136B7FEC8320B577C22153F818
-:10F40000D00569D1E6E34AEC577BBFB346E42B80D5
-:10F410000D0E02DE29007519780FFDEE7582F77169
-:10F420008DC16B6419DFC7E02FCAC07F10BE9A0F71
-:10F43000C339FC665D06FE938587E6CFF09C6C368B
-:10F440001EA9AA0658DB0C8F54B901D634FB28BF7D
-:10F45000BA59A7FCCAE608A5498D356170247742E0
-:10F460002AC1501F8AB2FAB27FF65FA0CA67CBFBEF
-:10F47000CA755BDE53C4FAA9C9E4B5A061CB278382
-:10F48000F5BE7810C76773F7E2F83E4A1998CF4582
-:10F49000183ECEE455C16F246602A34775D063A41D
-:10F4A000D83CCE0CCE9B0E61AC7719E1CD23F07A1F
-:10F4B00075D98A4E84F77D560F58BD338253DFC409
-:10F4C0007AFFA7E2FB7C1E1B014AD9F7D5DF6EEA63
-:10F4D00054587F2BCB3CC60A36AF7BD9F8ADA75B1F
-:10F4E000F0B85BFB03E2CDC7FE211E6B36F37C66F2
-:10F4F000DEF6FC19C0F272DE15997E4EB6DF61EBC6
-:10F50000FBEEB7DA88D523BFCA7E87417C851EFC17
-:10F51000FCF67B26C3F980DA4CBF729C7EFB65EC5F
-:10F5200010636D876D86545AE93D4EB5116D4820C4
-:10F530003F6CD62055C1BF1731B9A81672D1A2CFE2
-:10F5400008205F39E101EB389519BA54177966BB89
-:10F55000189F54472E5EA4205FADB7B4AB049072E1
-:10F56000F3EFCD3A986C1EB734D750BAA3596F4712
-:10F57000B9B9E5237566FBF0DEF2F8DF425FDDEA3C
-:10F5800006E2BFC42E48ED50B0BFA61766B3FCDA42
-:10F590005125B53719989FE942FDE0177CBC5631DB
-:10F5A0002EA9C4FACFA8807AD0290FB7B8635F46D6
-:10F5B000795833CAA5AC403C577179A876A77D43EA
-:10F5C000D9F7B5EB2B473188616DF4599287EAEA98
-:10F5D00061868AF25025E461ECED3ED4873DF35F0D
-:10F5E0005ED25E3500201FE913CCD04B3F413ED0A8
-:10F5F000275AF0F519CAC3A9E3AFB63EF96B6DB44B
-:10F60000F24D2F2BDF51E53154A5375C85A7A5239B
-:10F61000B1E1BDF9ADBA4AF059B46F3E73A62B9B68
-:10F6200053F02A1BFCF6E608F1DDFA6683D29B054F
-:10F630001F7A91A7C6B3BCE043281F43F99CEB1681
-:10F64000DC487CE92E4A01CAC9EDC89FE7E0702B6F
-:10F650004D7322D3913522CF9648175B03D663F9B9
-:10F6600040CA9B508EFC29CBF7264CD6BEB8869755
-:10F6700037287B13B866DCEEE7E55F56BACDC444A5
-:10F680004BFBC4CDA6599EA9CFF2E97ACDDA1FEB88
-:10F690007FB8051E3844F5657FF39457797F7EDE89
-:10F6A000FE26E52533517EEAFBBF49698B30D30244
-:10F6B000D638FAB9A927BFCE348767C6A9BCF17E70
-:10F6C0003311B496DF6F229E64F938655D22C1EA7A
-:10F6D0006F845895C2E85038B329C24C23F0CF4A02
-:10F6E000996EC30A1FC777667EB713BC812A5E3E38
-:10F6F000E2C6E7CC6455A67CB2F2AB04C2EF2F8A17
-:10F700008321EC055C1FDD9CC5981D547ECD2F1810
-:10F71000DFBB4B3D51B23BCA59A68C7D8FC4C1AAF9
-:10F720000FDC11ED35AB3C4B3E64F09E43F0C69AC6
-:10F7300066E68037618557C2D31FFC128EDCFCCA97
-:10F74000C777F255FDA5E37E3591B1BABFC31D451C
-:10F75000B3014D282864BF7CF85D53615D965CCE93
-:10F76000686010FD66C2D0DEFD96CE1C08298BDCD9
-:10F77000FFADE95B85798EB7D94A7186CE2C7F853E
-:10F78000158FE7887A4E3E94F3F3F49ADF15B6F9B5
-:10F7900081D6168985FA9FDF7A7F7C662CD8BBDEFE
-:10F7A000D38A42E3D7CF18F715E0E381B782962CCE
-:10F7B000136A33E3155D2CC74B651DAF38766AF1CC
-:10F7C000E9944B09AFBF17BCDFB5C17B939BC96FF1
-:10F7D00016FA9F6A78034CBF9E941CD69C981C9E78
-:10F7E000AA7E8BF057C65FEF69903E97E175D98589
-:10F7F0003EB2FBA5FEFBACF15782458C9ECB7E79D9
-:10F80000C52BE7BA30C3F87C4466FC26C520B87324
-:10F81000F17BAEF900A46CFDFCBDE6930BAFA75ADB
-:10F820002F9DA8BE5DF19B00A07CADAE8214DA18BE
-:10F83000AB0F9F970FACBFD5BF985C8A70785BCF3A
-:10F84000047334C0066CC2EC8DD5D2FEB8A8F68421
-:10F85000EC8F9B9AA1BD85D9350F859BC85E5AADAB
-:10F8600000B567FB524831BB66CC33DB7DB311FE7C
-:10F87000E86D94AE76B3F2207E3FA44F66530854F1
-:10F88000178E62E883D57EF9FDB986A1ECFBCD55D4
-:10F89000EC3B638DD521DE1FFB1EC3FA79D5FC7BC3
-:10F8A0002EB8F26A183C16BCFB3DA978367D59EF9C
-:10F8B0007211FCB7A13DE6C5FD8041A93FD01647B6
-:10F8C000A60B0CF118DB2A7AB79BE5E2FB8175D514
-:10F8D0003F4AE3D67A8DB0EB1E3FEFFBD089FAA208
-:10F8E000AACD7461FB28771DDCE6B0BB82C3657EC0
-:10F8F000A03299751070E46FE9B1E32A27A11D17B2
-:10F900001676D0792BCE9D84EB6C4F398CB295CF87
-:10F910005971F624B4DB0A7D4D2F4C64E317327D18
-:10F920009A44D1D10CA509EDFF8B0AB3F2CBBA6989
-:10F93000BE992956BEEEBC61155766D9FF302AD252
-:10F940007C657E40839DAF6F1376EC2DC2AE2D4754
-:10F95000191F2BF88F098B9F57EDD16BFED3B95E22
-:10F960000BD41837225F0E688028DADFEB18FEE22E
-:10F97000163AF96BECFAAD50B3CFEB54CD67239840
-:10F9800097B9C6E6EEDF295F1B217E25D62F14EB43
-:10F9900056A026AAC487F73F7FE77C73CDFB2B02D6
-:10F9A0009F6C9CABB38DF359E1A530C8C619F3B772
-:10F9B0001F2780E358D7B113C43B2CDE6EE27E1BB9
-:10F9C0006510F7737E98124DD33EEF7AF2D35D2B1C
-:10F9D000FA84F8261DED1C82394BBF5A9527E36F38
-:10F9E000C3FFA9B3F2B3D145A6CB5F7EA7E090A534
-:10F9F000FE7657A8E835DCD49F0D677FAC66DA83C6
-:10FA0000F0076A128E60A14D9F1E6FEE2E38C4F46F
-:10FA1000C6CDFA0CD2C7B9C6FB21D3A3692657BB02
-:10FA20009A7D94DEDBAC43DA8B7E8B08A5DF63F234
-:10FA300087DFB7B27D24A6F73447E9FB96E67194D9
-:10FA4000DED56C52BAA9B981D23B9A63546F43F3A5
-:10FA50004C4A7BF0F9211BAF4EAC6FCCCE3A7366AB
-:10FA60002AE1423FEE3E885633FCAEC6EF16F8D789
-:10FA7000B9263D4E7232D34F7E8F02E1F70840CA5D
-:10FA8000ACC276CFA9B00372CF2B29E67581EAE22A
-:10FA9000E36B35347840CACB6EA075AB640A5BB7B4
-:10FAA000185DB582ED85885796A7EF056C3D43FF3D
-:10FAB000A07F0AA4FD23A98986ED8B44FBD6A08BE9
-:10FAC000EAADABD168DD73F2C508D0A75561E59802
-:10FAD0008FFCD4BE90C6EB4FE4E3159CCF143DB32E
-:10FAE000EB5B751775BA6E0C5F3FFD358C5F2C7242
-:10FAF0005130F50F486928572B691EEBC2535E64DD
-:10FB0000DD317ED4CB2A583F77B02D35AE6BBBB6F6
-:10FB1000BFABCFB6D039A8727B7DC4AC773B10BFEA
-:10FB2000233426D76C1C757B2085EB0EA3878AF0C7
-:10FB3000E60B0532C2C7E7ADB6406A9B9229D70BE8
-:10FB400038DE47E85113D7B99EEF7EF1DDE84EABC2
-:10FB5000D82E05D16D46A63C24DB99F67621D92E08
-:10FB6000018A86EDD6B37690290FCB7630CAD62E91
-:10FB70002CDBC1B3268DB7D1DECE5F207026E61F09
-:10FB80001E1775C52DFAC15F65BAB8DCD8E9948B2C
-:10FB90007F8A40D0E1F184F231E2630ACF2B8AAF51
-:10FBA000F56317FAB3EC721D1E63A71B5459F28C50
-:10FBB0007417A1EC16931DD480F6C6B6D6ECF4DA11
-:10FBC000A0C5A655E3FC266AB6F9493A6DF0093A94
-:10FBD000B606B2D269832EE8B8006C7496F4DA20C7
-:10FBE000E9B52C3BBD36E4A0D70649AFE5F67692E1
-:10FBF0005E1B72D06B83A4D7627B3B492F273DC22B
-:10FC0000E3D28A9D6E6D943F55F470EA850E97415C
-:10FC1000DF5DBB4D7D12EA871B34DA57438DAEE0C2
-:10FC20007E00CA4F70FD8026C075612DFE2AED331F
-:10FC3000368F5D788EC5ECAB39C95727A11D1E5490
-:10FC400064F9A14968876FF3F0FC75C9E393D00E9E
-:10FC50007FC4159BAB92BD93021ADF812F6F2C05D9
-:10FC60001B1948A76B4D3F43BE397DBB2B9A3032E1
-:10FC7000F07881E305B7EF1F6759BF72CF43E017F4
-:10FC8000EB0C3D2138BF45706A299A772F382F62D7
-:10FC90007032BBC240FE66FC6BB49E1A38612E5FA8
-:10FCA0002F7AD667C7FED7D9FE8CED2E1BDFD46C1A
-:10FCB0000ED8F866D8FA425BBE6AED405BBEB2A5CC
-:10FCC000D296376E38C3D6DF9065B5B67CF9E2734D
-:10FCD0006CF98173EB6DED7BF10B707ED9A9BE7C65
-:10FCE00023E2B9870E899A7AA283A8BF3B59536F42
-:10FCF000E3A71CE55FF9B666FA18FEB5220FAD431F
-:10FD000000D7107E24BEF275487850BF140553E723
-:10FD1000B3F2806E26D02FA0EA26A01DE1D2E39494
-:10FD20007747ECF275211A4A8CFE5FD9A5816F4C9A
-:10FD30009FFD9B9FA4FFFEE6E5E417B9BEAB457CA3
-:10FD40005DBD836D97D0DF9360FA71071BD7CDCC73
-:10FD50001C7F18F942F00FE367D42B459A22F6175F
-:10FD6000272767D529BBFE19BAD10E7F459B431FB4
-:10FD70009D207F7F56F2DB1FFE364034817ABC3FE8
-:10FD8000FC8DD114A1FF4E4EFE872CB3E3A77CB1AE
-:10FD9000C721277F5FFCB5AA20F8A2A91EF112DABD
-:10FDA0000C705305DA5DCFEAD9EC0AC92F77CCBACB
-:10FDB0002D60B5F7618CC776FE2EC7A1BC9A2DFFCA
-:10FDC00079E313A847FB2394E03EA46DAD39E62FF9
-:10FDD000E8BDE1A2CA80753DFFBCCF3F43E76F9FFE
-:10FDE00054FB480FBCE5FA6B7916F81DFBB2DEED4B
-:10FDF000135C5EE27E97554FB29F1AB4B7821088AB
-:10FE0000229E8FFBC323219FED0F7D3C3DD5FBB68A
-:10FE10005DB3F8FE26F1725EAA1AF189FA1DCF8D44
-:10FE20005F1E9122BA5FE482DBB17CB88BCAAF0B54
-:10FE300084B7215C5F57E3D76BC508EF9014C55FAB
-:10FE400068697D46C8324F6117C9F9E7B28F56B568
-:10FE50005C5B6F5BEFE0E27AF4634A7EBCAB654DBE
-:10FE6000BDB03B5AB5CF957D9413CE2D1AD99B9F2B
-:10FE70004FFB4885ECFDFCA3D847BFD096AEB0DB66
-:10FE8000470F733A88FA1D2D0FD79F48B9B48F02D8
-:10FE9000418FD8D73BEC971A661FE1795250D82F83
-:10FEA0003529B257FC35296EBFD4487BC6BE7E5D6E
-:10FEB0008B066871C63EEAA37FF393F4DFDFBC7262
-:10FEC000ADEFFEA0B48FDAB87DC4708DF1276A0D56
-:10FED000F77BA88EF57D9CFB7FBB7D945D7EFBC38D
-:10FEE000DF0668E3F6513FF89B990B7FFFE0F6D100
-:10FEF0006E0DA47EFFFFC43ECAC527FFBBEDA30C59
-:10FF00009DFF36768ED3AE9176C4A9B66FA47DC21E
-:10FF1000EC981A0DF51EB3B3D08E39EE6AF7DDCE2C
-:10FF2000E6739DCAB03514E356F87EE6062DB6C1D9
-:10FF30004DFE8DB48E76C666D4E763859E45B90FB7
-:10FF40008AB83D2D0A334660FDF866B7E51C420DC0
-:10FF5000A6F59E739BCF111E989D679FBFC08BC453
-:10FF6000C37E7781DCF79C1DE3F3FA31E101D2DC3B
-:10FF7000DED2D23E4CFF43AC6FB41E1759F1C1F133
-:10FF8000A3468D14EA03D6FE3FDCC536BCF86C7878
-:10FF900061EB101F0F546ECFC9EF3C0D8CD115F4DF
-:10FFA00087B36C07F2EF002C3298BC415BC330D6AC
-:10FFB000FF80D8AA6F60FC5CE8E5696F02D3BF03DD
-:10FFC0003A674FC7B46578EDE17A562F3FAA5F389C
-:10FFD000D5C07515C8AFB8063BA3F3505772D270A1
-:10FFE000718EC3E4F9D995C7853C9B60B7CB5D861C
-:10FFF00026FD4995B9E585FD281F7B7BB7CF251FD9
-:020000022000DC
-:100000006EAB5C937C5E7D62F2399DCB7582FD4365
-:100010007D51E0E827DFB4AF1321B0E459F98782BE
-:100020008F01BEF1998CA7C36D3E03E34FAA5C3AE2
-:10003000C64DE6835E80FC1798A201C659EA45DDED
-:100040000974C1F6479716E14747BBFF42CB7EA232
-:10005000C0C3E5B568C6948A95ACDF6363787CFE5F
-:10006000009DC7813AE77333CA97D7921FBE8DCEE2
-:100070004D938C9F2AF9FE86CE6FD654EDD5ADEB0D
-:10008000D4688FF47338F9832DE175C29E66F851F8
-:10009000AB5C26DA019F963FD44FC81F79D31DE78A
-:1000A0004927492F53DCBB3851FEF8B4E349BAF66F
-:1000B00096AB1B894F8B66CCF5A1DDBF2A32A3CF4F
-:1000C00073D4DE74BD8DE81AA8023395A5FFF33C06
-:1000D0004A26AEC0195F6BD91F39ED75B5B46EE60F
-:1000E000D6BEE856E4B4CB78BFFEE5AAF147545E2D
-:1000F0009A4EEB804FF4B7C6B82D81FAF318DA0C9C
-:100100000C1F6ADBA834EA4FA882E80E5E85E23F46
-:10011000FC8649FB703AEFAECBC0E72977D9C6D34E
-:100120008A02F6F3E79909C50ABF7FB987E0F0E1D3
-:1001300078A8A775D6A182F730B87FAFD7FED16176
-:1001400037AC2EAFCD1A67A0FDADF6AB17D9E13DA8
-:10015000E17641CD78CD6247E56EA7C16B167BAAEB
-:100160000DF9DDC207ABDCB05F61EB70327231C4F8
-:100170000D96C7A23280564CC7231FD6F2757DA7B5
-:1001800042E7C324D206FEC7CF892EF318D49FCBF3
-:1001900017273CA94113A8BE7162E748C707F3F8C7
-:1001A000A422056CF5EFF778A85F0D62749E7EFCC3
-:1001B00077E747A85F937DAACBC0E1ECF7324FFC0D
-:1001C0007E4F31B21D87071B903F621CF70BD0DDBD
-:1001D0001CD6EEF8BA19749F28177C9B1CF2B549FF
-:1001E000C465416C4C3FF3E2727C9C8DD981F5B5BE
-:1001F0005880EE2DB5717B68B0187FC7B219F47DB9
-:10020000C7FABEE57C8BB08FEE42FB88EC1C9DF2FA
-:100210003D708978B33B057CF27B8D97C7671D15D0
-:1002200072BFC36706E85EC013D3025F60F255F980
-:100230009C1AC523CCB2356D057D8D3F70AEDD3F78
-:1002400072B2F11D9D9E5011D9D18EF88E5CED6574
-:100250005CC7A7C5CB9D621F53E35D90A4F393F4E5
-:10026000B9249F95428F542E03B2E3062F8694C182
-:10027000EA1ACBDA47A591AF3FFC18AC7C3218A242
-:100280002E20BD600667D7D1BD094EBF36179D53DE
-:100290000FBECA93C290B661C20E838DFC3E83BC72
-:1002A00077B1C3175DE1457DD74A961F5426ECF719
-:1002B000440683E57E04D32383D0AE637A6990E35A
-:1002C000FBA7A54381F7EF43874D5A9B5FB7B42F38
-:1002D0005320966DFD3BDDCBF9B4ECCAF779FCD722
-:1002E0000D417855CEBF12E9D9568074B86BEEB384
-:1002F00093F0DE49A215A2781765C8727B1C449D55
-:10030000378FDFEB00338DF6F2CAD917773E8A7448
-:100310009D0836FD95456FD479E93E08D71B9BE6CD
-:10032000CEE0E9872AF149D53248E13DA3296D4D58
-:1003300007DD2C5FBE1CE8DCBCBC35A1A03FABF2E6
-:100340000688E23083D181C7F255B32065D2FA0521
-:10035000CF45EA68A9A39F0AE4135C775AECF773C8
-:1003600086DC60E78BAA56FB7D9C52C117A50EBEAA
-:1003700070F65369B44D4378872E73F17B3B33EDB0
-:10038000F76BAAA0FDCDEFE37C0E05A3C8EF556B7C
-:10039000EDE33AFBD720FE75C4CB434B374F3B9D73
-:1003A000D5DFB2AC7E00E265872F964FF7A2F01240
-:1003B00051967D712F7E95F6468EFA19FD99B0C53E
-:1003C000333BD3D5D525D7CC61B5D6841240E327AE
-:1003D000BE4E7ADD2DE4F589C1F3E85ED7AAA25AB4
-:1003E0008A0B3B8879B4A7CA87955AF5BD1BE3767B
-:1003F0000764F22B518F66E1F3E5822F5F077339B3
-:10040000E26194B72982E37ACA4BDE9BCDC663CB07
-:100410009F99CAD26EA137C0E7AB6B7FB5DF6F0A79
-:10042000EAAF894B6C24874527E657B8D21BBF1922
-:10043000C74FD4B36D04EE3F0B219544FA36B5098E
-:100440007F7B4FBD36512F81F73B7BEAC5DBC0BABE
-:10045000DF64F536887AA6AD5EAC57BD3B453DB04E
-:100460008D6BF61AF71E091F58FB8BF6EA6FBBB7A8
-:1004700098C307D6FE8C5EFDED92F0D9EAE9BDEA9D
-:10048000DD27FA03DBB8601FB7A77CA44794C72811
-:10049000FEFDF1E2A9C41F878AA736E07DC46B7E0A
-:1004A000E6163AE2725AAF55C1570745BD96602D20
-:1004B000D90DC966685DCCF696AD787FB81AEFF1B4
-:1004C000CEA17DBEFC2EE9C7BEEBD9BF5F4DF77E46
-:1004D000E577ADD54F71E4EC3BEDC35A3E52851F35
-:1004E0006EC0143CA76C8DB884FFFBB5A459C5E45D
-:1004F000BD4CB3E5D794F3F251ADAF2513789F48C7
-:100500008BD1FD146F041E196ED1233DE37F66F07D
-:10051000F3738C0CFCEF3BE07FDF06BFCCFB07F3F3
-:10052000F2B1BE639313ECD795A84BD97E7998AFFF
-:10053000B885D6F3CFEDFC5C2DA6669D1FCF67E690
-:10054000C7F3727E67FBD429FF58F3D31DF3D31D85
-:10055000F3D36DF31BEF2B9882FC78A2F373D6BB19
-:10056000D91D8BA0DDBAB2F84764FFAF1C0CD4EFE5
-:1005700004DF8BC91BB19CC97607F56794A2BE1F27
-:1005800005E6085F71FFED9EC62072DCA786787CC9
-:100590002A147BC439702C82FECDB7BCBA889FE385
-:1005A000707A7C3ADF37897CA523CF7EF92BAE9B0E
-:1005B000189EC8F7910E3DDFDFBA5651321AD7B5F3
-:1005C000D690A958D7354FCFBA7631AD6B2B23D9FA
-:1005D000D735DC36D3BE48AC357734F3F7043688EC
-:1005E000FBB12BCB6BA9DE06793F253195F49B5CE3
-:1005F000371FFFDABC860AA61FDF7D8EBF1F71C0C2
-:10060000C7FD3FAB9BA19DBF87E0A3F431D66F9C94
-:100610005538C0EC3D4C1F66F61EA6FB9B2394FE8E
-:10062000A8D9A0742F1B17D3FB9BA394EE691E4778
-:10063000E95DC25EDC24FCBD5F2A77D1FAF9BD66B4
-:1006400058AB55A39FD747E93DCDFA5ACD8DF665F6
-:1006500084D23F2B3316FAC85FD199CC67F47AE87D
-:10066000D92ABA373EB15C237F076869357F4CE6EB
-:10067000BBC4EB9F95FA461FA3D339868BD7F3A54E
-:1006800092E1ECF59661BD718646F04030A1868B13
-:10069000B2D6FB16C25157C4E1063D9E0C65EFEF82
-:1006A0003BD85F6D9180AFC84806B3F797C4FECEC4
-:1006B0008A08F822DD8FE765AFD78AFD8D8808F8B4
-:1006C000CA3BEAF3B28F7B0BD62B2D6CA37B3BE7A7
-:1006D0002E06E26F6FB9B1957C15A2DEB6C14DE072
-:1006E000627C5B3AA0AD09EB7DB12906952CAD2C5F
-:1006F00089818BF1BFB78895337822A29F097379DE
-:10070000F9362C0F59CA45FBF10B5839CB5796DAFD
-:10071000CBE578DE3690FA24CD8C50F0AE859EFB8A
-:10072000D5982F71F1FC1EDFBF4C41B92F11E74E58
-:100730001D22EF6DB1B72F09F07C1ACBD938256196
-:10074000DEBE53D42F2DE4F3F65FEAA338E17BBE7F
-:10075000FDCDB239C333F33DED3BCBBF30C732BF24
-:100760007BBE731395CBF99CD6BC96CA73C96B64D8
-:10077000960B4C8BDE2A691B4EF6A4B40F479D7670
-:10078000717A36A38B3BC6E1EA6EAD6C5951457068
-:1007900025E85C55C0B5E55A3B5C83BF69876BCBE8
-:1007A00037ED700DBEAE6FB80EF8B85ECB051F1BEF
-:1007B000DFB48E9FBAD13EBEB1C23E7E6A857D7CDB
-:1007C00023F9A9C74F5BE972F7B7ECE30FF937FBE1
-:1007D000F877FF9B7DFC21D77FBAF1FF56F6B8E989
-:1007E0008B7FE413F6AE6AB53B9B1236BB93D57391
-:1007F000F985BDAB5AEDD878C266C7B27A5E51CFE3
-:10080000B4D58BF5AA17F40B7BDC36AED96BDC02C2
-:10081000512FEDB2F617EDD55F8984CF65EDCFE8A6
-:10082000D5DF20D19F69ABA7F7AA6788FEC0362E17
-:10083000D8C70511FF759D88FF2AF070795D1EE706
-:10084000FBEC52882BB8DFD707C0A843B83E0FE5B2
-:10085000EF21154C5D7E1ADA27CAD4E5A7E3FAD753
-:100860005A00B67DDB343FDFAF8DF3AB348E9E078D
-:100870004D580EBE44D98596FBAE5B45BD9EF260D9
-:10088000A2ECAB96F22F8BF6ADE2BEE0F96B3A5AD2
-:1008900050CFE88358FD2CFC375DF627CAA128DA33
-:1008A0006132B8375E3663EC4D601DD7CDE13A4D0D
-:1008B0008C5B9E1DAED60A3E6E4A8CBBD52FED8D4D
-:1008C0004419E151E7A9FC7E7BE89BCA1F197E60B1
-:1008D000BBCFF61E5081A7E9DE0A064772B00BF0C7
-:1008E0007EC2EAF2BEFD392DCD76BFA7A6C7E81EAF
-:1008F000F9C0057AAD0AB9DBDDD9E06AC876EE3019
-:100900005FCCA765417D5B15C277C8EEBF650C0E55
-:10091000D67BC89779E2F391CF7AF96F5B7CB67D8D
-:100920007E4149DFF7BEE4FDA89E79B08EB2D1EDDD
-:1009300056BF38E77A8EF72FEF9B1514BA68DF7928
-:100940006C383F2F80441958EDB18281F53EEBF8A9
-:100950006B1CE3F9618689F6272E53282F9E2A48BF
-:10096000E1FDBA40519B5E81EB42A483CE0141DCA4
-:100970007393FDB64466D07EFC98B8FFAA45DA268C
-:10098000B9487E047CBAD055629C811B354833BD82
-:1009900076C81DBFD55F6CA59BA920FE8EBB53E416
-:1009A0000F4A5630FA2BBDE7BFC9CFEF8FDD69CCB8
-:1009B000F8554516FADEED376CF70D077EE081F449
-:1009C000E8DCF533F5385C3D7C1B61FC3A82F40AC7
-:1009D000F1ED368FB9CD9F2DCE42EA0771FE3D670E
-:1009E0001C881FE392DFB2795C75D80D284FF29E08
-:1009F0008D3C17BA4AF8C7E6083FEC5C8885B1F031
-:100A00006D70D1FDB1B7E1D9F0680BFD1FF3F3F3C1
-:100A10000526E0E4FF92E7BD57B6B96DFEB0F91BBD
-:100A2000EDF97930A304F5D6BCF56E48317C5EE56E
-:100A3000F097DD27E63B1F9A56A11DB0D2CDFDF2FF
-:100A40007374D006B0A565C98FB7D4CD66F92705F4
-:100A5000DEDF627C6358E46D6130E5C1B89B57F717
-:100A60008DBE780260FBD4AA81A86F0B20EB7B704F
-:100A700057B4DAE1EB0F7E27BC002B08DE5C706810
-:100A80003B95ACFEAD5FFBEDE789B9E23B64BCC5CD
-:100A900031E423AB1FE6F779A924F94779DC457FD8
-:100AA000EDFFDA4FFB25BE4E0FCA4FA3D6D4A0B838
-:100AB00032E7525E77DC1CC4E6E9DE3F293D086C74
-:100AC000F55AFBAED73D15485F32C358CDD45B0A0B
-:100AD000AC1ECAE5810B13B67A55ACDED0DCF5BA94
-:100AE000845EFDE9EEEF79701FF7F60F5EB900E561
-:100AF00072D1232AF8D8B85DBB4390A67D4CCA8337
-:100B0000FBB485FBD4ACE7B81429C0F0B0E8FE1004
-:100B1000AD970BF77A53D359FB853F7A7524303C58
-:100B200074ADE87E6A10AEBB3F50F8796AA27324B8
-:100B3000AE6B0B35F8D75896FE2201CE87477E92D2
-:100B400047F78E959D072FA77EDB2F717B2DFA220D
-:100B50003FE0A679B17ADC1FB74B495567D127F240
-:100B6000FCEBC82E85C3B7DF9DF2237C3BB77AE24E
-:100B70000C8EC69DEF105F4DBE7F4F18F1D0B85F51
-:100B8000B59DE736EE54D3DE9194BEE2A57BA9660F
-:100B900050A9437C72FDB874DF12F29F2F6DBFF92C
-:100BA0001D358CEDEDFCCDF0124D235E9F57A3D388
-:100BB00031FFE0BD6183A1EAAD8E1D61C42BEB77EF
-:100BC000B6271FCF7FED7E6FECFF83C2DEFD31CBFA
-:100BD000DD83FCD5D8BE868FB7EF9F5F47FDD2E897
-:100BE00090A3B7F097B2DEE72E66C071EEB273C085
-:100BF00009D9978BF61CBB3BC1C63DB2F74F77278F
-:100C000018FC8BFFDF7B775F8F76D0637E1DF5400E
-:100C1000E30FFE330C9675F3D2005FC7BA76DDFBA7
-:100C2000FD3B997C74BDE8A5F5A3EBD1D787E03BEC
-:100C3000295D0FFCA5C460F5973D7A1EF901963D2C
-:100C400034B9B4AFF513F935E5B5C29522BA1AFB3C
-:100C50001534CE98A12D52077D9ED8A7829FC1F949
-:100C6000F60B5EBA1FD5C8BE2DAF457A2D21BD8CBF
-:100C7000F91B189E97EE5EFD8E3A321BBE13835C05
-:100C800078D90098184690DE5FFDCA17C760EAA6BB
-:100C9000F39546E826BDEA6CD7F81CA3EB59B9E9F1
-:100CA000780C3EF4E0E15FE3EE357CDC7646C7701D
-:100CB0006F3ABE8DBF8CEF4DC76F39E8780C16DFE9
-:100CC000732716EE1B90F53C589E9F2D79E86B7D9F
-:100CD000DA5B522FF487E7050A87EBBC80B92680E0
-:100CE000F2BAF787DFBFB388D3793A434CD79E6314
-:100CF0004380F1C91BEEEECB513F763FEAD571BD83
-:100D00005FF8E8F3246F5D0F3DE331C84E87A0C262
-:100D1000EC8D2EE8F9E940FB63293FAB82C6EDA1DB
-:100D2000B4379CA1D7D2D4850D4698BEBF42DF53BD
-:100D30005C0E96A60E5EA464A1DFC100BFC70DA91C
-:100D400062C2CB92EDBFF540D04E57651CD2F395F1
-:100D5000A9F83D173DE5FC759CFFD916BA6EE7F280
-:100D60009B4B4EBBB67A358C6770D2B94BBC9BD2CD
-:100D700098529ECF4677B90E9EECB9EA01A77C8BBC
-:100D800079F727DFFDCFE7E4F0F5C38061E31B8946
-:100D9000B7231F66D7FBCF0B7DB1149A1A060EED51
-:100DA000BD0E6A6CE339A82203EF118C7364FC76E4
-:100DB000E4076A2AC1BEAF6A7F82F4B7534F2CCDD5
-:100DC0006167BF21C7DB7F7024EAB3238FFF84F8FC
-:100DD00071E9EE573CE8AF796AE7839ECEE119FEF0
-:100DE000C775C1FA7EC691FB0E8E24FD8DFD67A1ED
-:100DF000CF31D17FE3017BFF8DBBDFB1F5BF28D1C0
-:100E0000EE21FF6A3FE3BCA59997E07CDFEA70031F
-:100E1000BE97F456BBDA90CD0E7A29E0B6C553AD35
-:100E20000AD5BD80FE49B5D063A0FE6BB9D17C3E2A
-:100E300081EBE5336EFE8EA566BE80E7D7C9028FD3
-:100E400081FBDE96D0C56058F4789B039F7A913E73
-:100E500009F703FA94D818EBFE4BC25F60BA6CF046
-:100E60002F0B35941A41BE8F33F07D0A2D4AFE694F
-:100E7000353CB581EED5EB2EDD9F75DDE6FDB98302
-:100E800031DA77B975171816FE1A35F9E233D1053C
-:100E9000A78161DB0FAC9BC2CF83E5FCD70D86CD6C
-:100EA000C0F4F03AA5FB30BE439498C6E30BA57D91
-:100EB0000762DF1FC67D7F456F7B0F4CD3407D44AB
-:100EC000EAC8E0E39B96FBCD99F85D305C14C71C43
-:100ED000A54D8006718A13F26194C550DC77B55335
-:100EE0001A64EA0DD373F3B85EF24237E56F6BF81C
-:100EF000039D7394E6C5C6E41563BE50E1F348D381
-:100F00003E4F5EDF77E59597F5A50F608A76C4EAD8
-:100F10004FF2C266DACFA03BF3E30119BCC8383BFD
-:100F2000D9EF3AFF447A1F03E73908DF6BC3C78D57
-:100F30004AF8F9019FB749F96299778C8335F53AF8
-:100F4000B1049368C615F750BCA7D7467E9381D0ED
-:100F50004E693974505AE8D3158DE07B99FC5D2EAB
-:100F6000F8037C9CE780EF04EC78A7FD7D9D6ABECA
-:100F70001867744C8A7DCEFA027B1C523C8FEF13AB
-:100F800096E5B964DC73DCBA6F4BC262C281BF887C
-:100F90003F4B26DB7D372FBE20CFB29F55831D3CB4
-:100FA000AECCB15F3E4FBD81CE455647FA8EE75A73
-:100FB00029E2C27395B715FB666F05829FFBC114CA
-:100FC0001F8FEF36C1D0ADFC88B13D75D67849D3BF
-:100FD000F68E8E1BF950453C2728F5A35CB1340FE3
-:100FE000F98AD1E156C18721E8149D7493FF639B70
-:100FF00027BE0AE71BA96A52F8F7B8C2FD65A68AA0
-:10100000F32D11FDBBF21697C5FB9827CC647C62CB
-:10101000899B592FE8A269A0056A119ECD82FE4ED8
-:10102000FEB4C7BF4ABB2E28725E1187F7E49867EB
-:10103000E97D31AD2848F12FC1312DDF708DC4F924
-:1010400037E9A8578332BE25CAE315E5BEDAF9EEC3
-:101050008BD71117EB16FBF75E71E2623DBE153FB1
-:1010600064B19B9DEBF17D7939DE131A973D1E51DA
-:10107000DA699F94FFE5FE73B1AFE3290242372995
-:101080009E53137E8B4917E9E46F3FBA5BE1EF1182
-:101090003AF8E9E8DEFC91A82F519EF15DF33CF1AE
-:1010A0005DD97DF020DA572D61300B0A49FF192AEE
-:1010B000C3FF2A65944F61E9927DEF3CFD08FAF188
-:1010C0000FA880EFB91D0DCA7350B3008996076B46
-:1010D0006D74FEA4F3EA7D8EC9E5EF6A5DCA5F9088
-:1010E000DABDBB5BA17B622A9C7907BE73D578D839
-:1010F0000D2956FE2EF07EDFDDCCED86F93F7BB06C
-:101100008E49026C14F0E0FA655D67063404C0B0E5
-:10111000F04944AE0B09B303DF7F9E2BF0531C2B29
-:10112000B4D593F3FBD39C86C3E4FF89CF23FB158F
-:10113000DF11B4F60FC23F62B07FC8974E3C1C77F8
-:10114000C53D40EB4A2C3F4D7610DB4FE3FE23A517
-:1011500044116EA73F65E97E85D6B3ABD87A86EF9A
-:101160004B5F9572EC471DEF224BFC3BF9D61D14EB
-:101170007C1B84600E3C47D3FC7C96E4EEEA9FF136
-:10118000B8B4ABF728F48E93DA797A3E10DE55F2D4
-:101190004BBD0E4DB7B31526C3DF0EFC792376BCCD
-:1011A000FB0D3BDEF36AECF80D45ED7874E2397F18
-:1011B0005CA5ADFE2275B187984FE0BB86FD437CF0
-:1011C000333D49F358CAE691367AE373C18175AB72
-:1011D000D05FD22F1E1DF81BE1C0DF313870909711
-:1011E00042CC5742A24FF32ED3D224574E39947893
-:1011F0002AD73B26D1B76888FCD411D1893297B75A
-:101200001BE86BE742551B253994F1C9793DEBEAA0
-:10121000ABF0314BAFB9F0D02B7320B7DCB537FB57
-:10122000A2739950DFD70CD1B9D5785EAE53BA19F5
-:10123000EB9FD5E77A4BE3B921AAD37A22CE4D8E24
-:101240000EE7EF5AB5A7DF2F41FBEFD6DAEE0BD052
-:10125000EE6FBC92C75B7E2FC4D7DF1F8BF4FC9070
-:1012600087F4DD4D311798E82F38A0A614F443E930
-:10127000E6CFCE45BBED80DBA0F54FEF7EFA5FA851
-:101280007CB48EE7CC65AEB651382EAB4FFEFEA3D4
-:10129000075E0D5F61B18FBAF67FF70BB83E6D72D6
-:1012A000C1826CFB80F9413E7E57CD1F4A902D973D
-:1012B000F8BA695FBEBAD3EE67F3ECE37EB8A5FB7C
-:1012C0002F247BF4D03CFE0EE74347F87DD4A9EAF7
-:1012D000AC7F1AC1F2E3FF53E37A15CCE9B34BA814
-:1012E0000AD133E9677866785C8FF19B28177F74A1
-:1012F000A5F0EF1C8CFF227FE769FC8B7812C68A71
-:101300009AF8BBF18F84A71EC674CA0185FC478D6D
-:1013100047F8FA36B6C3EE273A7B0AD30BACFFBACE
-:1013200003DCBF55D7C9CF07CE7EC15E6F7CA73D1A
-:101330003FA11FFE5D1914FBC830949C4C7C6EDAF3
-:101340006DAE0D72BB8AEE9345B5ECFBAF57437C97
-:101350007FC4F041F33FDA0DD1156C1E47E70E9CB8
-:1013600084F7938EBECFCF1B8E7EA83664DB5F6D75
-:101370000D727ED9E4E1E7C79BE6055337B2793CAD
-:101380003E6FE169B8AFFAF3B7E2A7E97DD9254C22
-:1013900045B8684D34F3611CCA470BBFE7066D655D
-:1013A000D9DE51967221E544CA47D9BC403C9B5FC7
-:1013B000B45ACCAF7E5E0DC5E3763DA6D01953D7A7
-:1013C0000A06571F784CC08A41084FE3FEF7C84F02
-:1013D000E13B90DDDF7D3018E67CBB2271E30486C3
-:1013E000AF6F32E14EA03C78DA2AB2F59F80F5E487
-:1013F000BFDA19E4FCDCE5E3FB70D0DACAF0BD88A3
-:10140000AEFD93A7AD6270DEC9E40FD7EF4DEE28B5
-:10141000C19D5802F4EE1F887B85E517C0D69B2C32
-:10142000FBB59F07273D1F64F37C3EC8E39306C4CA
-:10143000A30AC21DFDE87818FB3FFA8197E83750F0
-:10144000F88B64BB7783DC0E5F1D329F217E595081
-:10145000444A311A0F47E78E06386B3FC3779638F8
-:1014600033691715C6990E1C83EF58BAF87918DB43
-:10147000A7E1FEA311E44F828C54297F78D90DEFA8
-:101480008949BDAB1C50D221A63FC7F88269F4CB75
-:10149000142E70E1DB3BCC1EF5F1FE3AEC762B6AA4
-:1014A00060D4BFA80378D03EDF1F497D2CF5784B70
-:1014B00001D77F2DEB34D28F9BB54E3FFAA52B4C35
-:1014C000A35E33E8FD568AB718BC80CB7BDED02DF7
-:1014D000053D76D10480073E52B3FA47CE10FCB4E6
-:1014E0003A14FF0BE27BE4E1EEC7D1BC8AFA61005B
-:1014F000D27BAAB07BC6BFCDF591BC5FD028F625C4
-:101500004E7DB4C92FEC1868FB359EDBFFE48F1AC3
-:10151000DD9FEED13FF3A6D27A0AEAF02790BF26EC
-:10152000FC5C6C0F84FE61BB3DC2CBD9BF88271128
-:101530000EA7BE19074C2F29FDEB1D279D9911DE23
-:1015400093C710BED187999C59DA3BF5D4C0905807
-:1015500067859E3A06134BCF3332FC54BB3CFA846A
-:10156000D7C23F524F65F829457CE81C47015F4FC1
-:101570005E1F8AFAE5172AFA518E4EE27FFFE709CD
-:101580009423468782F753D3901FD61F38DF8F7C72
-:10159000BFF7F0641F8AD5D5117EDF4C3B7851022E
-:1015A00004FB58CF95DDE0338235880F17E141D534
-:1015B00059DE32FEBB6D8AB86F69E45F94E55D6CFD
-:1015C000995E1DE1F7C9F61EAECCE7FBD134D1BD63
-:1015D00087EF85FF42CA85E477277F4B7948B2566B
-:1015E0002E8B1DA12AED62FF68F72324851D91949F
-:1015F000EFCE24CAC83E5C26ECC36470D8CD13D9A4
-:10160000AF2DE97A1DCF3D96852A29BE7A5931C77B
-:101610009F131F326DFC80D98B9638F846AD9BFC2A
-:10162000638D1F786CDF257E73E145E2F71CC4AF44
-:10163000F2C9F17B4EC820FE70E2F9D3CEBFFCEABE
-:101640007159EFF1FDA3CC7F02C41FE9247F2CBFA9
-:101650004F22F94DEA8FBA6B5A937946465FC8FB21
-:101660002052EF48FD72F6E2B627F2B2E80FA7DE8D
-:1016700088BAF52BD632FC459F0CD23B1D4E3DF26D
-:101680003EFE52467EB7BB434C2E1F78EA2D17FA1A
-:101690004D1E7A98CD9D95470F4EE17EC18E133B2E
-:1016A000EF9276ABB4579DF5A4BD2AD71D79DED451
-:1016B000118AEF09317C29FB993C313C2475BE4FDE
-:1016C000FE7930DE8E70E5319803180B5893AEE04A
-:1016D000FB59BBBCE692CF3C87FCB5A7355AFF123D
-:1016E0006CFDAB567AC321C79F1F12EF0930AE4382
-:1016F000BBA6BC0EF8604BF97B01E523218EEB33D2
-:101700005E2BC5793E2DD6995F85F8FA2CD39F07BD
-:10171000633F45F8DD1A24BCB59F1C6EE95FEC08F9
-:10172000994F229E7C0D26CD63900E51B4F7076928
-:10173000ED4A94C151B8D8507A9C3D725D67FD0D59
-:101740009A6E4C42391A84770AB03EDA4759E8F368
-:101750004A88FBC197F83A9F4213BE717A5343B847
-:101760008FF3F5CC3B0851E1E7B2C7811C7DF4F95A
-:10177000C178FEF9BB6FBF17C273ADFFD2BA430881
-:10178000E71B37FC3A84F7217E7703DF7F5CEEB0FE
-:10179000733E10F8BC241C3B8AF3FDD7E68FEA6C3D
-:1017A000EFAF2CE7E73357A554DC94F6F0FBA29D8E
-:1017B00079E4DB93F925ED036C79C9A74BBC3C6E4A
-:1017C000CB39FFB3C2FC1CFDAADD5B3D830C1C3F83
-:1017D000AE84D9F86F083BEE8D7D21F27F4878E624
-:1017E000EC1EE5413CFCD701AF38F7EF7073FC9B72
-:1017F000D3F17C2E2E48E184F3A9C7F2A8BF2B3782
-:10180000A86477CC66632D67FC1D3F7015EDC39D02
-:10181000F3B8F277C6D45246BF2BD72864AF62FD27
-:101820001B183FC497AFA6733CE73C67271CF12306
-:10183000C2AE70C699CC3FC0CFDFE78271F3C48AD5
-:101840002C712707A6D1B9DBFC7EF63D5561B1EFBF
-:10185000A983B3316EFE180CFFF7E146FFFB9E37FC
-:101860009A8182C8DE6AF6517AA459A7F428EA4F11
-:101870003C3FDF7FF029E233ADA30EE57EEFE15779
-:10188000F32E35327AFC4B5BDF7BE22E961F0DDCAC
-:10189000CF23FDEDB304DECF15FA7CBEB017467F33
-:1018A000D0B73E9F85F818D91B5EA9C767E1DF2135
-:1018B000B4E041EA75273EDE3D3C340FF9E3FCB06D
-:1018C000F3BCF9D3E12557BB256AF678462947478B
-:1018D000439CAFE76EBF70D540367EF2D1D7877498
-:1018E000723DF11CEA09C9A7004D1E9463273F4AC7
-:1018F0003EE9E1BB03B7109E247F30B98A8873CEDE
-:1019000008EE0F9DFCD75F7C5397BB7308EA052751
-:101910009F7539EE43CBF4EB61EE7F9F6B9853716B
-:10192000BFCA969B55FC3C90EBA337B4B6A7AE4715
-:1019300079DDCEE565C98FF7FC08F5D0C2FB3784A9
-:10194000510FBDA9B595E0788B77AC0CE3B9FA1BC4
-:101950005A228CEDDF4CA959E31FEF0F2BF2EF75E4
-:10196000DAE224A0357101CAF19F77B8753C076BA4
-:10197000DCE9E5E7EEFB38DE589E9FB7EFCB1E278C
-:10198000B1F0DE0D25068FA7B5C74B6C7793FF022C
-:10199000FD6B384CAEF3E29EF3E7F6BECFD31BF7F8
-:1019A00089389B7DD3B2C64BC8B804271FDFE3E05C
-:1019B0005F861FF2FB25185CE46E17E7E4C95D77CC
-:1019C0008C7C85C17764FBCFC3CA70AB3F9E9FC739
-:1019D000BFDB7EC53D3E576EFEED12FC9EB1275229
-:1019E00059E32716BBD361DC572DDEEAA67DE0E282
-:1019F0003D2AE03B78F0A297D6F3457B9EFCCD399B
-:101A00000CBE450FB88BA6F369509C84A4574F1C9D
-:101A10008BA0CFC2079FE4E7CB86886711745AF486
-:101A2000C0410FC6E538F139B9FDA0A7D311074170
-:101A3000F46A7F652ADD27DC75DC83EBEC9B8F295C
-:101A4000F4F7399DED176C7D328CFA02F144710088
-:101A5000826EB9E396D2173C3C86EA91DFAE3F3AFC
-:101A600036A32C8E257EBFEF6106C78297BC143F3C
-:101A7000B5E0BE6B28CEE875AD89F3FD969525B827
-:101A8000FE2E70274A744AF9F705775F4BFC38FF42
-:101A9000996B4BC47DA432EEEF4994E13CAFDCFC82
-:101AA000359AE73C88133F2ED8A2C6D0CF724C831C
-:101AB0008607B2C8CD17F2B9DCBCBECD8B8FE8C0AB
-:101AC000EBC2CF997856157F3FD2795EC5DF8B394F
-:101AD00026F6DF1F89F5187075B3ECC71AB7AFEE9D
-:101AE000403ABD35D82CD5299E404B08BCD1BBEB24
-:101AF000EA33E7950AFD46EFDC483B68327EC7FAD9
-:101B00001D6E7AEFC6D2CEF65ECD32313E833BA05B
-:101B10009CC5D292EC7ED099F9522F88F81BC967E8
-:101B2000B9F4C0761ECFF2FE735CCF605C0E957781
-:101B3000B8D3A5B6781CAFEDDE7526CEC42DE4DC97
-:101B40005ECEE0A478991EFC3EA6A4F0FD63C92FEA
-:101B5000F3D67BEDF1793DFCE37CAFC71E3F33DF6D
-:101B60006197C9B4D7FA9FEF38AFDB7C62F1338B52
-:101B7000DD298A7F5AFCA297F6278BF7B8638897EE
-:101B80003FED7EE2379732BEFF53BB9463BBDE75F9
-:101B9000CAF182BD63219B1CFF291885AC72CCBEA3
-:101BA0006795E360E65CC38053AF77E7E7D0BB1788
-:101BB00038F0C9EC867C8C237EEB078B4E237F8527
-:101BC00003BF52DF3AF5E86B6183F0DC3BDE8FAF99
-:101BD000FB99784C8E47C99F0B7FB884C6E9E163B7
-:101BE000C9A7928F73C48D39F1E92C2F44DFD9D85E
-:101BF000DE7E91443DD4E0DF674A7A80BFF3E60A97
-:101C000044917FFB3BEF7C36BF42BEFB7616DF176D
-:101C1000F2F3CE6850C7BF5401EE2243CD76CE1EFC
-:101C20009DECCA6AFF27F2F9B9463EFA2318DE1E78
-:101C3000CE37F8BD0735261C79ED748F81CE56114D
-:101C4000CE8230C9995BC4A9B09EE93E7A34CFF503
-:101C50009EC1FAD892FFD4F91AA36F74B4EB9AA17B
-:101C60002CFF50FE4BE76BE8AF9DE07AB092E57F2A
-:101C70009CFF5B9E3FCB35DACD587527BC7CFE14AC
-:101C8000567FA998F752E92769196BF39368AE5705
-:101C90006EC7F31CED61372459FE6626F7BEDACC19
-:101CA00039739E17127E96CFF3B094E55755FC7AA0
-:101CB000156E229F0EC4EFCA277CD51B88E723BA76
-:101CC0008FE27796FDE43C8A237D389FC7BD9FF95C
-:101CD000E004FAFB8EA7108EDDF9C5B9E16871F357
-:101CE0007E8EEC3D7332E2F9CCD3D0A796A147ADFE
-:101CF00066D0773F437B82DBFD11BCDF922CF05036
-:101D00003F0FE74BFA9D582AE35ED43CCE176ABEDC
-:101D1000ABE901961E14FCF0B8C00BFEE0BEFBE878
-:101D2000A3A5DBF8BB56DD4390DEAAFAEEEFD1DEC9
-:101D3000ECBE2C8FFE7EC84B018EB797021C6F97AE
-:101D4000E4AF759FC1BED7FA865C834CFF92B2FBAD
-:101D50005A4CB7EBF15F723C401AFBBDF47295F739
-:101D60001B6C0AE17B718AC9ED708531D32C868F9B
-:101D7000A4098667288AB03DFE43556BBBD3347EE9
-:101D8000C8363E94B37593C9F925E339BD186E6919
-:101D90001D7D7E1CCF4BF866A62A939D06C1F37B62
-:101DA000E48F51DED460DC4F5DCACC2AC8F25E7885
-:101DB00057809F6F7661FB9199F881C6FF76D17E3F
-:101DC000B611E7C0F20F1E01F1770AF9BB3BD2EF63
-:101DD00031FE975793FF7BCCFE453CCE44F8BBE4E5
-:101DE000797EDD217E3EE7F46F4D80B5A44FC73B81
-:101DF000F4E884FDFF44FAB5BFF3B9BF48BD3A101B
-:101E0000069EE4F91CE896F3B9FF01DBE0C6DF00AB
-:101E1000800000001F8B080000000000000BB55A76
-:101E20007B7054559AFF6EDF7E25DDE9F48B100838
-:101E3000869B0448421E36498010706CDE4C8C1222
-:101E400060406418695021E6D56CD6416A748B0EE7
-:101E500041459DB2326A29556BCD5E18DC45496615
-:101E60001B4934BA9D4C0710120437082830AE665F
-:101E7000DC1D44973C645670D42AF6FBCE39977E1D
-:101E80002428F3C790A24E9F7BCF3DF73BBFEFF7CF
-:101E9000BDCEB91E3D7883F900D7E9DF9D91B62A02
-:101EA0005902980EF44F0729000D66FCA5005C3915
-:101EB00091990C385EAF07909D004645865267E4C5
-:101EC000B9B66D38CE14E9BF93ACB0790ACED81F3D
-:101ED000001BB5B00E0AA3E6B5F37917CA568012F7
-:101EE0009CFF12A8A60C8069FD392FCFC1BEA1C7E7
-:101EF000002ABD979EA0FBE7746A00459BD1FBBBFF
-:101F0000E2305EDA91602B84DBF195A93A50CC6C1B
-:101F10005EB88EFF1394445072227D4B8E33A62FF1
-:101F200027DAF64032FE0878FB52518E627E0B9221
-:101F30003CE363E679C7B6A487E42EB66FAC20B95C
-:101F4000934B3363E68113FACFFAB19F837FD73384
-:101F500069A995C96194BF082ABD12CAEBF9183C5A
-:101F600061947FC6193E4E7BCE130EC83EC4B1F4B9
-:101F7000E3D8EB6510D5C779B67EFC95E348943C71
-:101F8000A5F624F7C53CFC311EC65F9747C5D113A3
-:101F9000269CCEC81E540334F4E22037B65F800A74
-:101FA00088DB34284C0686AB0C2AF6DF04DF0B7383
-:101FB000B0BDB66DD8716472044F8737164FD79293
-:101FC000583CC754C6E23976752C6EE37CB138A50F
-:101FD000554D8DB97FDBE6A298FEC4AD6531E33384
-:101FE00002F362FA593BCB63C64F6E5E1ED3CFDE5F
-:101FF000B526667CAEBA21E67EDEBEEA5BD27F41C4
-:10200000B021665CBCFE6FEFF855CCBC65F25A1986
-:1020100032233C08E01FF1A088544CFA473D84610C
-:10202000A4FE67BA03C4F8BF59FF5B49FF9628FDB9
-:10203000CB6B937DD691F6ABB59A5EFF89D63A9D70
-:10204000F48A73A070D748CF786DC860DD2961EB42
-:1020500040EEACC5EB5BCDFCFAA3029F6B09E92A0D
-:10206000ADDF113AF657095B540BB3C3C02716B561
-:102070000979F3A8AC3412AF5E942B254079D25085
-:1020800075BA2CE4910EAAC8AF3CA7D3ADAB8C9225
-:10209000EF793B0E1E43AD8EB5FF6C445BC5F7A6D2
-:1020A0005920602E62CFD1DAE89F1770DD36170312
-:1020B00005FF55EC5C3001EF3BFA731407E02DECA3
-:1020C000DF06702191CB7B2191CBB9C6A434F59367
-:1020D000FF90D5C924CF5EBBEF5FECF89E0BD2E337
-:1020E000067C3318DC0103D95D9A1902367C5F93B4
-:1020F00001D65562DF016EA901DB6478C54EF68515
-:102100006228D7911487ABF392FBF1FAFB24C23813
-:10211000B2318F0E6600DCA7F9C3AA5CE60FAFE010
-:102120001AFB48A17A2519B0BDF26016BB7EFE7E6F
-:10213000B442B4A7F3468E8786C325E127BFDC6689
-:1021400066EDE56DF618BF59B5FB852405E7399FA7
-:10215000034B8251F8750BFCBAED32D3E7A0FAE7D6
-:10216000148267E8A1EFA690D07EA9EF492B0E79E3
-:102170006AD73F5402EAC1D8B62C803A815F18155D
-:10218000365E9BC71F9A0B84033196E6BBF723D8B4
-:102190004CF2DDFB1DB651EFEBB31BD8737DE27D36
-:1021A000ABB0B1236EAB502F0E6A8FCD5944768100
-:1021B000D7C312F697F68081EC61992FC340F29C49
-:1021C00006CFD97694E78F76FEFE9F41A581E4FA8B
-:1021D000F0FEBA241A77633E6D1E14D681F1E42313
-:1021E00047C090827E6BF80EC9B34761EF33D3F5D9
-:1021F000CAB5694F5895C8FB3E04DFC059D4F77281
-:10220000F0B079B5F9D1F262FCE21B55359FBA32D4
-:10221000C91FEAC04CFEB0D3C4FCE150F5B5D69757
-:10222000F0FEBAB4FEDB8CF8DC85EAEFA6102EF7E0
-:10223000ED924141FDFF39C9F739F147C3E3FC8312
-:102240007F49A2FB6B4CEAAB2FA11DC07E93E755E3
-:10225000A0E7F6B3E7B4715FD9E75EB653FC2C454F
-:10226000A066DDDC3E35FCE7BF9E3B9678A6F1EB31
-:1022700061C1AF86D7B2C7129F1A926EF08BF75F1B
-:10228000CD1A4BFC9A21715EC6CFDB85FC52B27130
-:10229000DDC82B0579D5F5CD3C17F98983279CC579
-:1022A00024A71E7C3A47141F0EBEBF268FEEC339EB
-:1022B000F72DC94BB6194039EF052EE749611FAB21
-:1022C00043AE62D23BDA9DCD81E3D6FCC76B037F80
-:1022D000247C3AF7BFFA188D29B9353C34FF7420B5
-:1022E00091C7231071CE2370C13897A3475187201F
-:1022F000D143F9C2CDFCD601F20BC8AB6B3A747C6A
-:1023000059E4AF2A81FC82053C0AB5E865DE9B8D65
-:102310007A6CEAD6C133D8B59153D3FC4F29F66510
-:102320009DF03FE035A7621C11FE29E737EA921DB8
-:10233000CC7EBCD6F533984B6472951CA9AEA0F741
-:10234000421FFA7194B512FF281ECC86CD87135018
-:10235000CE19BB303FC07133CFF1FB9A5F9F15D6CA
-:10236000AD3726D3B85F7F25DB08A2D83830FB48CD
-:10237000F9E734EF6C887A6E94F830C711971FDC58
-:10238000627C584C0100710FE670FF1E0C27AA8179
-:102390000C366D716501BA26B43DBAFFEF6E1E476B
-:1023A0008CD2608E19FDF05DBFD9B373E71CA4C356
-:1023B000248E0BF59BF4844531E3F18DBCF1C854B8
-:1023C000E60FE17B948AF0B20B99E3E42941BBE389
-:1023D000C1D8139377868F7E6BEBC775B43A95FFA0
-:1023E000247D0D635E437E2141DF6F748CB2BE3766
-:1023F000C9BF22FF9F77E898BCE60EC9ABE2FBCDD0
-:102400008A17245C4382DD3E4D9622E3173A78BE5C
-:102410005B77F442BA11F535A03B61CBC7F96BDBB2
-:10242000DFB0E1F2618BCD57457CAE39FFC10C0ABC
-:102430005D00BBD32B9308A7CC64B2A7023D04F484
-:102440004523E5F0EFC2C520E5EB77B9589BDB21CA
-:10245000B1F5F9C37C9D831D4DCE68BF71E3B93FD3
-:10246000748E27BDED1F03ABC91F17848A37118FE8
-:10247000491603EAE2F56FF2D87CDB1C194C2FF801
-:102480007E3D5D075075CB71D07E033E87F30E7E97
-:1024900023B371DABC051D73653BF2283FDC7C88F1
-:1024A000F2C2849049213D27EC058E4B2881F945E5
-:1024B0007FD762A0FC75C8011E09EFB7260E7F42C8
-:1024C000BC18EE34297B24C2AF199C387FAB91C76E
-:1024D000CF5C348437AC91EBDAFB12422F03F92B3B
-:1024E000E48757A5FBFA66B8C31A8D7B12C35D75E6
-:1024F000705EB526867556F2FBC8C93D4CAE889C09
-:10250000C0DEABC999CBEA8056E3F0C5C7DC4C2EE0
-:102510003BF12117B89C10CA565EA5E7ED5EB68E5A
-:1025200004BBE2094823E5F217625E8C76F7DC769D
-:10253000B861E764F7FEC448DF8C36D19AC9F90D5B
-:1025400081B33B17CC89EA93C32A8D3CDFEE38B7C1
-:1025500073C704561F0564E48305DB2427AD93C7C6
-:102560003F340DEF98228E830771B298F9FD1BE37B
-:1025700091EF56EA5BF9384FB2DD522E31BB01B212
-:102580009B7AE1671E91C217EF44D57E1D3E54A889
-:10259000A02CB5C7DE61BCADD1855E2A20FF98E8CE
-:1025A000FB03F9F7B73ED6810DD7FFE56B096A0546
-:1025B000E291F3F6EE14AF75E47C4F9DDBFE7C1ADE
-:1025C000E9FB6D4941A4312F1C4E27F9EA439F1BBB
-:1025D000BDD82EEEF89391E2D32F9CBE5EB283D28B
-:1025E0008EC6F984DF2C686EB25B995FF4114F835D
-:1025F000A9DC7F5C3933654F6314DE43C2BE60D80B
-:102600003791EC2624ECB38BF21F6CDB451ED6DE33
-:102610007D5F965210792E0087D200E7DC0E47D2FC
-:1026200008E71BF3A9FA25C4A7BC0FCDEBBC517C6E
-:10263000FB42D8FB17E27D01A7EF53C2A1A6FB33F3
-:10264000A30DD7E5FF9F603AC5A720E669F61FF006
-:102650008BFE38BBF1EB878D34DE7F09981F41BDBF
-:10266000EE48463DEDFFB063EA7A2B931F9271DD91
-:10267000EDE74DCC6FB66770FB6B3C7BB590FCD63D
-:10268000D5CE9A8984D7298741E3F9BC44B2A70300
-:10269000C0FC98668FF9648F287A3EF1BC84FAB941
-:1026A0006CBE56635F39B3BF761D90FD21CF19EF25
-:1026B00091E776CA3FF2EDC87BF67C36B3E7D63EAB
-:1026C0000C78D80FA01F9FCCFAF35650BFB56F817E
-:1026D0009DD9B30EA12D22BB0C1F62F304B1A6221B
-:1026E000D54950199DA72E74D898BC9A7F5C21ECCF
-:1026F0003498A3247B703D16598EB183A878C9FB0A
-:10270000229EAE759A9E7E71025993880B222FEB02
-:10271000127930F88A99BFFF4711CB1ADE2D5BDAA8
-:1027200082EB6D382973FF2F787248E4C947B6A54C
-:10273000B23EC50B05F5341D5B2FFAD319DECDF380
-:1027400029FC942E693E4C6D596570BE81E2E2EA27
-:10275000BEC3066ECE79C4BFB6433FCDD313DFCF21
-:102760009B2001456CFB76F893D711872D5D88FF80
-:1027700028710997C3F887119DF1F166BC1992FA87
-:10278000EF99EDC1FACF39EEA7FA04B41F2206E2A1
-:1027900071BB73ECD30114A8C3E92D72227E9FB8DC
-:1027A0007CAC1D3AF56D0AF9F4F6339FD9C8DFB752
-:1027B00019BD79C4B3B64CAC1746E1E744A781F91B
-:1027C000FB12536C9EAEB52B9DBCAE9A12806789EE
-:1027D0003FF56DB25D457D0FB4C95E23E65117BD6F
-:1027E000BE143D427A0902AB66537C17F5EF431CD9
-:1027F000767888F2178C331B5F34C4D4A5B5625F3A
-:10280000231BFA9F4C439CFC7B2556D756C5E523DA
-:10281000B594BF14527DB1DB48EBA9DE1B370FE541
-:10282000318534EE87EBDC954E91C7644116E53176
-:10283000C823564F0F9F953D7B2806EAA1C784FC0D
-:10284000DDAFE338A1DF64F6A8E533896EEF22B28D
-:10285000FB450E9EB7B48ABA75B8555299FDEC4344
-:102860003F8FFDB24BCA6EE0389C499D41EBE1BC05
-:102870002CD3F3F165A10C667FA55EACE771DD1B7F
-:10288000B19E5769DD5A9EA71AD8FA31FCB23C6F47
-:1028900016A84D361CB7699FC4F67D6AF61962F218
-:1028A0003CBFC0A776D7A9A3544ED605E3EE0B7C58
-:1028B000FC71F8BC413F668DC4E9574EB11F900EC4
-:1028C000E9D1F91EF43847AD0B347CB43CFB7F0DE5
-:1028D0003CBFF840CCAF8DDBE5E47EB4DE0B6CFF93
-:1028E000A856955595E783D6F5C89707045F1E103F
-:1028F0007CF1031F57B74F52C314AF7ECDF56EC6A0
-:102900003FC2E5A1E0FA4569CA485E550B3CAA5AA8
-:102910000C2CFF05D86C24FBAC7A256E9CC0A53A24
-:102920000E977A9F14271FCFC7FF56F96A0C7CBFFA
-:10293000A606F91550FE7EF2C6EBEF0D8DE753614A
-:102940006A8CFE96B86E497FF179F281A3532DF41B
-:10295000FC959E4CB60FA1F1267E9E4522CF5EBC13
-:102960008BE7A3031DF32D05544F9DD07B249CA71B
-:10297000F8E4FFD90A108FA24E192A708AA150F1EB
-:10298000B3015CE7C19E492B148C0F4527F52CBE83
-:10299000149F2C52A9AE293A5964C94A62C6E3A2CF
-:1029A0007A01E761F179E8C4A4D3F9E4677B16946E
-:1029B00010EC8D278A2C94471C04BEAF219D2C71EE
-:1029C000F547C59BF79C325BD793A9FFFD1CE5F942
-:1029D0008B0F183C948F2C360CBF3FDB4DEFD77B11
-:1029E0001AB15F7B72C3F604D2FB6B9287D2F1A35C
-:1029F0007D0DEE9F937E4306BB89C9FBCB43743F9D
-:102A0000D0227926E3787FE7C2BC56EC17ED2EF68C
-:102A100010CCDAFB8A1CCA0B15942F8EB3B03A7E09
-:102A2000F16D0616772F8FB7FC8EF2A56AEFEE4593
-:102A3000E48F2FBF73D048FE60A85582545CC8D184
-:102A4000D4C3BF0FE03A2FBF79CA4849F9FCB65347
-:102A5000C6FE1FC827065419C2AC7E6F36521D54DD
-:102A6000B75BEBF71B494F9522BFAADFFB27D6AF19
-:102A7000A63A01DF57FD8AAC2AF8F370E75B46C23D
-:102A8000BBBE4582B11951F7F74AECBEC6FB0DC07B
-:102A900079B041F8A71AB10F5943FB90781D7672AF
-:102AA0007FA3F1FEC17DCB8E52F87EA839D60F3DB3
-:102AB0002C78BE89EA52567FFB8CA4D74DBBE2C668
-:102AC000099E3FFC233C4F76093F950BB9C4F3ABFD
-:102AD00073793CB97A2AD1928FEBBADA2B7B007EDC
-:102AE00090EF2CFE9E10F9C295B08EC5336DDC6060
-:102AF000C75F58BCF19FB862A4FC7651E82BA68F43
-:102B00008A50F702C2FB6EF0D5127E77872C76B220
-:102B1000FF8A7EEE0FCA432695F6C1EF86E00ED2FD
-:102B2000F350D7BFED70126FFE95F30684BFDB2420
-:102B300070DD2470DD840EDF852EB63ABFFB252CB8
-:102B400007A01CB81F2A0F0A3FF44A2CCE1879EEB2
-:102B5000277DD5874CF00CDEBF4BF8A3BB5AB83F9E
-:102B60008A8F93F5621F60685CDE52B6DF8AF52EAD
-:102B7000E571B52DB1F8D78B7D81FAB8389CE9E2C3
-:102B800079C28FD5FFF17A5A10A7A78A61CE9F72BA
-:102B90008A7BB8FE9EF0F67CDAB7D3F08AD7538FE3
-:102BA00092953C5A3DABB5EF8BBC5FEB2F057EFE9B
-:102BB00014B4375BA3EBF8D75D3CFE54CF9203A46B
-:102BC000E71BF5CEA4C3858A2E52EF609DB3D635A0
-:102BD0009DD73DD370EA63136470BB23F5CE53A930
-:102BE0002F541451BED2C2FDC86029CE974CF93C77
-:102BF00030FFE56F31A954A7F8913FACCE21DE60DC
-:102C00005B199216126FB07EA872218ECB68EB18FA
-:102C10007158D6C1F39E650BBE627CEB9DC4D77B19
-:102C200045AF8C1DAD9ED0EA88FA6F789EAA5DAF45
-:102C300047BBA7F1F52189D5C56D87FE9A9E81FE18
-:102C400073A8F35AFA7A6C5F76F13C4ECB53873116
-:102C50004FCD14790AE5CF1BB9CA6013A6C35B91A7
-:102C6000871B459C036907B3937A4A76896FED12F7
-:102C7000DFC7791B2FCC44FFFB4122CB63063FE427
-:102C8000E743F4FCE398470D6E081E71E2F8ABAD24
-:102C9000128B7F1B31C7FD49D1487BAF13BC6C84BD
-:102CA000EDA22EDBC1DAF29C039F3D46FEA8C5AC27
-:102CB000907F1DEC6832B2FD6535EAF9CC91F95090
-:102CC0009DE06FDD8FEC6BBD1EC74B5C07CB6F8744
-:102CD0007A65BB4962F8FD767C344E22FF693B94ED
-:102CE000C0F43C74CAAA529EFFA5E0DF65B1EFDED6
-:102CF000582A335C74B3789BD7F55626E995F4E0EF
-:102D0000A37D94AEB7A67AD93E9FCAF858B34FA612
-:102D1000C3BE88FC410BDB0BD5FA1ABE7E812FCADD
-:102D200035C5E88EC8D5AEEFB77946B11B493AC470
-:102D3000F4A69362EB5CFFDB72A51A654FB89E7533
-:102D4000E4DF42821FA01F4E21BF1C76294CBEC665
-:102D500010D7B3AE93B7F8FE557CDFC6C0DE3FE2B6
-:102D6000FEBC402DDDBF9A6101C6936F0215D4DF12
-:102D70009229333FB5E583EA6C887A3F48BC1EF759
-:102D80001B8653583D7C4AC7E4F39FBA9232C94A26
-:102D90007E70F7027B3EF937EE1F8E665AAA88DFF7
-:102DA000017AEFD8C83CE52E7E9E00B4DE54CA6698
-:102DB0005EE4F38AF56E87E50C87ED8267DD221FFE
-:102DC000C5BAE93CD9637CDD74B37C37AA7E6378ED
-:102DD0005D9DAB9CFE39F2A0A8571FA07AFDE0399B
-:102DE000EE271A3B377D4A75B0FF8209C84F6CE960
-:102DF000DA944D71187CBEDB29BFBBDAF5F0ED6CBF
-:102E0000FF52DACEE40A907CA994379D4DA17CA8AC
-:102E1000AEF36C0A8BEBEDD35FA03C09F3A2BBE8E9
-:102E20003AE62B8C7F45274B18FF0E9E2871659143
-:102E3000E0E0B1D0BC75BDFA4AC2A7AEB7E4BD0AA6
-:102E4000CA5F4ECE637992961715533D4E7952EF75
-:102E5000A4983C69D8C5F3A4A1EE04B6FF2141268D
-:102E6000E70F4C8AE14F6DDBBB2C9FA8ED90BDD1E5
-:102E70003CD29ED3BBF57C7FD42DF81394BC8C1F21
-:102E800007785BDB7190ADAFC61064FA6E6C31F001
-:102E9000FBADBC0568E6FB2CE00C101EEFD125D481
-:102EA00043B9519D40FBEBC733787D11AF8F67DD90
-:102EB000FC1CEBF879DF44E2CBF1B9BE6CFB287166
-:102EC0002300F378DD2D09BCDB0C2CAF8C1FF7B48D
-:102ED0009BEF4FD85C1073DEA8B5BF7473FE941BD4
-:102EE000F93E55FCFDB96E614F289A0E7971BAC250
-:102EF000607F46D413E3D0DFDE23FCED8ABB0D2CCC
-:102F0000EF382DCE99EED1FC6E298FDFDA7EFFB23D
-:102F100057E0092CFFE16BC867E760CBBCB17E6F5F
-:102F2000A5C8AF562C89BB2EF2A9953F924FCD7202
-:102F30008BBA610A4CE17583D542FBA25FF718ECAE
-:102F400032935B9D545930729D9ABF392ACE877A4D
-:102F5000D00F52DB98FB11DBA73ADE7DFEF70EE6C1
-:102F600047132093EF3BB2FDFABA9BECD737DEB0A4
-:102F7000D39FC5F04ED3D300E5F9F923F5B452E061
-:102F80005D67BE6C64E796B079A74E8E9C539A0C31
-:102F90003E6F1AAEC3D031374CE7978DB926962FC6
-:102FA0000D2C9454F2F72867BA29CADF0F8CE3F985
-:102FB000D7965512DB17EECEFD88C5F1BA709F91FA
-:102FC0007835A56DFD13CC7E037086EA254D9F4BA9
-:102FD000CD3C7EDED0A3B65EBAA9D0FA9C01EE97B6
-:102FE000DDACA5F1142FEF11F1716969ACFEB2A14E
-:102FF0006F11ED8FDCEB9558BE7433BD2F5F3DED47
-:103000005DA2DBADEABFD9EDDBEAA6FDA2BE2BAB2C
-:10301000687FF778EEE7E9145FEB6FC2E726C177C8
-:10302000BF859F8BF92DFC3CCC93AD34F5233E2618
-:10303000876FBB9BFC87EE7BDB54A079FA7FDB209C
-:10304000917E80E9E56676F4B498F769B79DFB6FE9
-:10305000373F1FB2529FECD9A04E203F01F9B776FF
-:10306000CED7F8F6B142D2D360776FA1314A9F979D
-:103070001BD01F507CE93C9CA258A3F9A6137CD31B
-:10308000B35692968BB819CBBFCBC43FD2FF81C346
-:10309000F7505D38D0B6C22D295171B5FDB46D72AF
-:1030A000D4BC0321998DC77A6CCACAA468399F60C1
-:1030B000720E04F97C00FD53561444DF6F123CEE8F
-:1030C000673C7E2A67333B77D778AC07CEE3FA8E2E
-:1030D00065C0E2945877D0883FA8CEE832A9744EF4
-:1030E00041FBED8E283B392EEC63261607C4CF59E1
-:1030F000109069DE9938E35AEAEB21AC77D2796017
-:1031000058E6E7DD1380783D43F07AA63EDC2D15C6
-:10311000B271EC5CAA0CFAD8B89FC0306BBD60D716
-:10312000533B0F3CAC2D3587EF2277921F0CB2EF4B
-:1031300092C2297AC745333B2A85D1F41759BF1E5D
-:103140002E6A3CC5C198F4B07DFCF8715F0B7FEF2F
-:10315000A11C8EF43C006C1FEE0EE897E925B3F538
-:10316000B084BE27BB430FE64494F7C0111DB3E7FC
-:10317000AE7E45257FE67189E7BEC0E7B03FD3CB81
-:10318000ED9642107DB7A2AD371E87329C8FF605B3
-:1031900067EAB1F2653886D9FBEE24C171DD73416F
-:1031A000D153FF923B437CEFC6EBB4F9A24ED399C7
-:1031B000030C8F418A8F63F8798E0DE7296B96E0B7
-:1031C0001C9DCF64F1F56AF39761284DA67C5AAC3B
-:1031D00097B6C2CF39F9398F8D9DCF2DB0135E527E
-:1031E000384577DD72EBB80EA50093DBF6C0F0E052
-:1031F000632591F32E4FE8D839FA2E47F27AD97722
-:103200003D1EB3354CF939B2E37274DEAD1BB30128
-:10321000C6E0FA24C5CEF0021F28947F8C8D7CEF87
-:1032200002D75D91EF6908C64B2991F37DEDFB9ABA
-:103230007DEA7245877A59ED367B482F45E6F46280
-:10324000AA07F7DA7D30867D67D332994DA657A756
-:10325000572645F86E016F29E1AD9DEB4B427F3754
-:103260003BB7275B259E5BD0EDD37741CFA2BD98BE
-:103270009DA37D7FC4CFF3D10A15FAEE081E9FAF40
-:10328000D077014F3ACC9E67C8CFD1FA2C91F53553
-:1032900099F9F7044D66FE5D00EC98CEF6CF1E114D
-:1032A000E7114D565D0ED55B4D90E8A1925E93F708
-:1032B0009124CEC747FECBC2CE47E3E5FE3ED19771
-:1032C0004FF86AF23F2A7BCE61EE1383E71C0D4F65
-:1032D0005D04CFD56A6653BFC2F02BA1E7A799D48E
-:1032E000DB685F648D897FBFA4E1860A65A4B60BA5
-:1032F0007D68F8D949DFB40E2FEA5BE34B6604BF63
-:103300006713396E06FA72228B3DABB0F3FC385C62
-:1033100034DEFD3FD45368B1102A000000000000E5
-:1033200000000000000000001F8B080000000000EB
-:10333000000B7BCFCFC0F0A31E81FDD1F8E8389100
-:103340000F534C94118257B3E0D78B0D5B3122D8C9
-:103350009EDC0C0CB29C0C0C7240DC01C49D40FC49
-:103360001288B5B81818B4813801C84E04624B20D1
-:1033700076E086E8A96567606805E25E209ECA4E31
-:10338000BAFDBF2518181A6411FC0B4036AF02E9CC
-:10339000E68CE2A1897F1BA2F245B451F9F6BAC0CE
-:1033A000F46184E08B6A9366FE36A0DEED46B8E5F4
-:1033B00079CC51F9CC96A8FC6E3354BEAA3B840656
-:1033C000009B2185B9B80300000000000000000048
-:1033D0001F8B080000000000000BC57D0B7C54D53E
-:1033E00099F8B977EEDC794F260FC20021B9794000
-:1033F00002267188E1A5A013040B886CC017B4AE37
-:103400000EE111DE44B49AAEB8B99010420861B42E
-:10341000A8C18D3841405468830D4A57AB03524BC5
-:103420006DB71B1505772D0D688358A0298A4CFFB1
-:103430006BEBFF7CDF393773EF6426E0BAFFFDA743
-:10344000BF7A38F79C7BEE39DFF79DEF7DCEC8243D
-:1034500087A4DD44C837F0474BBF891032205A9209
-:103460007255206308F9A195E09FD62FB6ACAB2129
-:10347000246C2124B290904E27ED28555949212DD6
-:10348000EF982E92744292E07D85907AA1EA686E60
-:103490002921EA5091ECA28F3664CC4E0A38138F62
-:1034A000BB978FFB931A2B96ED351E2C5FAEF16206
-:1034B000D951A390703E21AFD4146079B0C687CFA4
-:1034C000FFB5661C96AFD7F8B17CA3662A96E19A41
-:1034D000722C0FD7CCC1F2484D00DF7BBB66319612
-:1034E000476BAAF0F93B35D558FEB646C5E7BFABEA
-:1034F00069C0B2B32688E57B352D581EAB0961BF84
-:103500000F6BF66079A2A61D9FFF47CD412C3FAE01
-:1035100009637937494678DE79E725EB3CBADEFC6A
-:10352000671E7C6F5A1A215B468B3E0057FE339F05
-:103530007A0385D1756FF99B694E7B1CB8DC450415
-:103540001C678B8B60FB96431F11A58890E6D15DAD
-:103550005E95D6A7F1EF8CD875CC3AAF30DA2F76DE
-:103560009C3F12131BC74CDB69BFE1DB587FAD7D6D
-:103570001A7C6774B47D77CB7BD6F94E7D3B7BFF9D
-:10358000F9D6F7AC80BFCD11898411EF2A21B4B4EC
-:103590002B3D2D03289E6D272CC4924DF1AFB49383
-:1035A0002E3A4EF3F827C36229AC9B7653609DEF09
-:1035B0001381C2417511A40705C6181BFDCE582200
-:1035C000E23CF29F39C6BE73C7252CDFF8AB4C082E
-:1035D0007DAFF94E21E4A0E3374FBCE8F503BDA968
-:1035E0002F9880DE905C15F84F97B79C8EBD65E2F2
-:1035F000875E95C269F3DFDE9F331FE86F14F1C168
-:10360000F7361FFA3951A0BDA807E157CBD7BD79CE
-:10361000EEBC2C4F6162BAA49444C47174B94EE2FA
-:103620000FC581EF3F0210287C4C9E10AEC94EFBA7
-:10363000C5C3C33F1219FB6D76957F007051EF34FF
-:10364000FB76D179DFEC0B936E6774DE50FF84D686
-:103650009D5F8689C905F33EEB35D1F53BC6C9D7D9
-:10366000D9E86C9C3D3D27E07DE784457E587BF39F
-:10367000A82EEF22DADF5AD089EB253EE21B46C79F
-:10368000B517A8647E21C0C184788D9DCF7C80F75A
-:1036900000C0D3575EC08946871FDCF1BEB542D754
-:1036A000FF798D3E04465FA4296C9DE58AB63FA351
-:1036B000B5DB18FD10ABB17D5B0C1D938C04ED6682
-:1036C0000A68C49718DA2520DCADB38BFACEBB2983
-:1036D000FC6BDC074E5FD81A88B32EBA4FACC077AC
-:1036E000924A451FC0AB7922DD2F85D1755E69DF17
-:1036F0003570B86C2E9DED82F1AFC4B78ADA4512F1
-:103700002EE03C93FEFFDA83763AF3687D5438C5A9
-:1037100050BFEEE86043FFD19D3986F6B127461AC7
-:10372000DAC7779518EA377C76BDA1FFC49E498633
-:10373000FA4D91E986FE65E47643FD66EB0F0CFDDC
-:10374000A778E61BDABFE75D66689FA63C60A8DF46
-:103750005AF088A1FF6DBE5A43FB3F8CDB64689F23
-:10376000E5FFB1A17EFBD47F31F4BFB3FC3943FB4D
-:10377000DD735E32B4CF0DFCCC50AFB4074E027E89
-:103780007EB0F835C37BFF58F596A1FE012153E3C7
-:10379000E197088CCF500AF2745FC3FB5316E70120
-:1037A0009A033A1EC0E8B4A02D019FE4ED2FEC7CF3
-:1037B000CFBAD0C027CD8C8E07B1F63DA1F7E2BFBE
-:1037C0003F94EF13D2699DEDD2B7B3795DF357CA39
-:1037D0005FA15D52BF157F75797CD85FE3AB94BE66
-:1037E00009B99EC2571DA2AAF83D3A1EE59726B612
-:1037F00064524D189F22E4017CAEC97D9241C226DD
-:103800003A6EAD2BA3AD116042C796D2A05EB8034D
-:10381000EAA2E2275D71E06AF2C8063CC5C29738A9
-:10382000532831F7C76755849F3A851448F07DC106
-:10383000EE5B4BD72B91C060813EBF2C06BC30F9AC
-:10384000874DEAAF02D9D1FE6B27D27F42FF5342A8
-:10385000681DF657108EB545C40F72431D24877638
-:1038600065233C2DC04FB4F7E803A58BCD57FD264B
-:10387000D75067F3BD62FDEB7C635D1BF79F8CF057
-:10388000A47086FA7DBCD267DD3E394AB726E8C708
-:10389000EA8A28906F900F1ADBB5EF5CB6B98B49B6
-:1038A00012C5A395950FDBDD3BA0BC6CCB0C11378B
-:1038B00021C562609240E1A04E62F0514F3A42B59C
-:1038C000385ED5D8F222806F7C7D8190756C7F7CCC
-:1038D0003C4DD4AF2311DE3682DE961FADDB32289D
-:1038E0005DC5E1CB77094CFE511A95605C0B61B464
-:1038F000E53005EE8279CAA4DC2F225E7D04E677EE
-:1039000068D893732A28FE9A26C83EEC1BA40A277F
-:10391000D54FA55EB84EC5BA95D7E7090A8EBF3117
-:10392000F9B03587AE77B34FE47A4110C76BC8FE64
-:10393000CA0B7CDC26058907CABCF8727AA52072FE
-:103940003C3E4AAE461F8EC5CF48FA3AE32F04E10B
-:10395000A7CD6FCBD0B03507E8713CD3879BC7F5B7
-:103960002F57D673B8D6727D78B3323B8938A3EB24
-:103970009612CC6B03D7A309E99903786FC84E1749
-:1039800061DF6E1018DF3994FDB615F84793E7B084
-:1039900015C60B08D96CBD31F06D487E0FF5FA5A8B
-:1039A000977D4E280E3E03821BD7D900388375259C
-:1039B000132EB7552FE0CDAA784A1A95BE7434D984
-:1039C000F525CECB594A140BEDEF4C63EFDB3E16D9
-:1039D000420ABEEF770EA2F37070FAB02B46F9BA26
-:1039E00076E22D2AE8910FE71032109FDE6FC09328
-:1039F000A3343003E8DFF457138E4B06B17949A4A2
-:103A0000EA0FF361FC42C6A73CF47FDFD031AC790A
-:103A1000317CEBD834DCBFB2877D9F982674DE44BE
-:103A2000E72BE58B034D74AD2673A71FF4B18D5DB5
-:103A30006D3E55077F594F07C0873E9E769614C34B
-:103A40007775E3C3FBC3666FC9ED879E4C5D6E124D
-:103A5000BE0EBE7B4FBFF4E1FAB8ED9D233AB8BC71
-:103A600021B8D2BA016863C958E4135778FF724D80
-:103A7000E89D23C370BDE2D5D0797DCC3EDF90CDEB
-:103A8000F5398AEF593A3DEDB2C0F439A296211CBE
-:103A9000258EC70D13490FC895CDD9B2B20EF0517E
-:103AA0002A8781849052E9F7CDF00F809B52DFC9BD
-:103AB0009EFFD0C047D70F99E90B2B89E727A5C5F3
-:103AC000E0F10AEBAF06F8E9FA7703FCAE89C2CF62
-:103AD0004CCA93C240DBC1A948BF6E6D1E13EF52A2
-:103AE000F4F3E885E30D6C7F9AD354124F2FADE5C4
-:103AF000F0BB53F45F047E67927D2702409F39320A
-:103B0000DA27B1FD478A8C0F45E16C95004F76C2EC
-:103B1000FF668410EEF4AFDC9ACEE147FFCC196F5C
-:103B2000FF5500BAA366B3A3189FD74925747F79C0
-:103B300089EAA0F2C12E1109EA59C06C4763FB64FF
-:103B40003905F6F12D3ED477CDFC7B9E36AF5E4F26
-:103B5000CF12195EA3ED21EF9D8676338EB7C1C5D6
-:103B6000F51BCF7306BAE87D3F39BEDC192832FD5C
-:103B7000274BF470FA790EED39F3D0BB1A0E517859
-:103B8000D7E5FB7D15B0400F413868F243931754D9
-:103B90008E64890300FE010278973CE558C6CAE3AB
-:103BA000847C3C460E9B0B6403DF217AFD2607FED6
-:103BB0009BE1C1FD4662E53F2FCBA75FD5BEAA8D35
-:103BC000D95726125F2EDD2E32FD91A869B87E6D81
-:103BD0005F11AE5F68F8A7F2C140AF32CC87321CEC
-:103BE0001B09E1E00E6A6641DD45AAB07E695C49C9
-:103BF00058A0E358A4AE06E0CB96712251B3E3D8A7
-:103C0000555C0E255AC79689F1E5C4CDA29BD9C74C
-:103C1000CE2ADC1784DC837AA1A006C837A81F0649
-:103C2000B9BCF479018F1B6BAAC927743F590FCF18
-:103C3000457BDD9CA7FAC1DE075901FA23C9286537
-:103C4000A5E453F4F4D98B47B216C7333919FEE50E
-:103C500034AA17E7207D2C00FA205623FDF4D24920
-:103C6000461AC80A9887521E775C8E57DE2F211D90
-:103C7000F5D281B62E4586F162E9C35E4A2D0E115A
-:103C8000AB9D309F811C7B0303F5F78BC5809FE0C4
-:103C9000D4E1140F03BBE6A13C737179525F38FB8A
-:103CA00028A874493ECFAC5B14B0F3890070DD08DE
-:103CB000835D0FE3CD5D5B46EBEB61B0C1B4BA6EE3
-:103CC0006699EA646462D44B4545D2F430B15FBD75
-:103CD00046F8C6D2F7FD44EBB7C4C83B42565F9DD9
-:103CE0001E750FFB9E4AFF07FB2B39469E26F98D5A
-:103CF000FCDD15F39D17019608DFFBFF57BEE7219A
-:103D00008F5B154A0A963CD113A2B499443CC96012
-:103D100027D92753FB8DD63D193D2A4CE94A78A96E
-:103D2000E7762AA1FB534FCF6F727EE9ADA8CBAEE9
-:103D3000A7E35E2A75FA805E0752F6989AD2773D1D
-:103D40009BB8DED75B2FDC8174BD9ED211E8C36ABD
-:103D5000A188FEA68D792F7BF472F194C657FAD014
-:103D60000751244D2EE7C03E14FDB6E2EF4E1FE68C
-:103D700018385F2D7D38EE31E2E3DBE2EBC2B7A409
-:103D80008FEFFABDFA44FE07CE9F285E51FF6E50BA
-:103D9000FAB703FAE2F571C4AB9DDA2FF1F8ED172B
-:103DA000BDF8548DF288DBFF51B961B4FBA5AC5B63
-:103DB0004EB4F5030F29564FE6E3DAAA4DCAA7A978
-:103DC0003080C760EF6C541E5741FFBE047A34E860
-:103DD0007BC132F4FF923CE68F850144D0FB157F16
-:103DE00008FD0C209F74724DCE30EAFDA634BB5105
-:103DF0001ECF5105FDFC6DD532CEC30ADF4B437F8C
-:103E00006D08BE6BF290B0CD1DA557F814B3F71F27
-:103E1000B92A3A3069EF091ABD1ADFDB905142E244
-:103E2000E1AFCFF7EE30CE37215F8A7DCF2929DD94
-:103E30003ABD23F17B12E9D6E92F376A711D8EA7AF
-:103E40007A33392850FDAFD67B170928489F28C7F9
-:103E50001AA0A4F2B4DE5BE241F9BC4788B1CF15E9
-:103E6000464F4A0AF617AD4CBFD2EA89E7C3BE1BDC
-:103E70008D1329A81F27EA5F5B33EE0989321B7374
-:103E8000F55B5B256AFFD4ADF5CF29A7FD1B6B8ED3
-:103E90006E958645FB2D3169F639159F6340AFE17C
-:103EA000F44B683F849B48BE01FB8972684527E755
-:103EB0006DA473AB84769FC2F14884DEFD4087DC3D
-:103EC000CAD7692127B01F0C84761CE9C271E1456D
-:103ED000A8AF37FBFDE5144E8D52C8BA1AF8B98D5C
-:103EE000D7155E4FE6750FAF67F33AD98175B34CBE
-:103EF000EBB07FCD210FD6EDBC9ECDEB29BC9ECC87
-:103F0000EB39BC2EECC0FA7A998DB7496A67E3DBCE
-:103F1000795DE1F5145EF7F07A0EAF9397D9F72D3E
-:103F2000ACEE30B7B3F11DBC9ECDEBA9BC9ECCEB83
-:103F3000B9BC2EBC8CF584FCB280C13FCA1F18BC32
-:103F4000357A240057831FAB2BA69DD18B49205C6B
-:103F50000FAB42FDFFD0D0BBBCE06F5C7FAAD20BA1
-:103F6000F4537F9B464F01E49F24E356E463662DA0
-:103F7000EE98B67A0EECFFFA0C19ED49C2FD305AF4
-:103F8000FB86E4C0D46CF0577C6022F1EC2EAD6C63
-:103F9000E57CF769D07BA97EDEC2E3914FF278E43D
-:103FA000568847D23208F1485A36F37864138F475F
-:103FB00036F27864038F47FE04E291F910E79C83A0
-:103FC000E58B108FA4CFF7403C9296BB211E499FF2
-:103FD000EF8478242D77403C923E0F413C9296DB53
-:103FE000793CB23EADE428E81D97AA45D40712CD2E
-:103FF0007F6895917F0E596C8C4B0C0A18E3120365
-:10400000E718E31203CA8D718964BF312E9134CE53
-:10401000189770F98C71094781312E61538C718921
-:104020006B0FCE36D48BDABF6FE87FCD9E0A43FB91
-:1040300088D052437B7ECB6A437D58F09F0CFD7342
-:104040001BD619DA9F32E5207D65AB8D867E59D56A
-:104050008F1BEA95767FB709FD946957E5AF265F18
-:10406000AAE97A7E192B1F4C99C4EF4739C7E4118E
-:10407000FA6081FE8632BF94F5E3EF1D057BDD9289
-:10408000C7E4944589B13B63C6939DBB4FA8F43BFD
-:1040900065EEA3DE2EDD7E245EDD7B60EF488C4F77
-:1040A000363ECAECF1265EF65D473DF66BFA5B7C68
-:1040B000BBDC269962F40866D7343D2A60FFEF3AEC
-:1040C000BED61E3B6EF47B141563F4F66D48F3AF59
-:1040D000923A9DBE60EE4A9E4F50CE33FBD7C4F756
-:1040E0007B5981EF541D85F77A0FF159687DBD73B7
-:1040F000929FE925A2824276CD6D68A76BFDB579C6
-:10410000D5396733FE42D947D8C0A7EC063FC1FA7C
-:10411000B4FEF53739622261AA97982202FAF56453
-:10412000A97C6A36D5C7E56326DF5AC067027B9F44
-:1041300090C7193FF48A063AAE5BA0F13F1F9B1F60
-:10414000CFBBD0F85B6DDA247C5EE7E97F5E169822
-:1041500017CC87CFCB1C7160698AD870BEE323A9C6
-:10416000581F1749C6726C640896632283B01C1DE1
-:10417000C9C5B234928DE575916BF0BD92C8082C1B
-:104180004745AEC3E7BEC8282CAF8DDC80CF8B235C
-:10419000E3B12C8ADC8CCF0B2365585E13B9159FD5
-:1041A0008F8C4CC37244E4767C5E109985657EE406
-:1041B00007580E8FCCC57258643E9679917958E6AF
-:1041C0004696E17B3991255866471EC0E74AE47E52
-:1041D0002CB3228F609919F911964323B558664480
-:1041E000D6623924B209DF1B1CD988E5A0C88FF13B
-:1041F000B937F21896E9916D5826479EC3764FA4B9
-:104200000DCBA4C84BF8DC1D79014B57E467F8DCF3
-:1042100019D98FA523F21A3EB7477E8EA52DF21627
-:104220003EB7460E6179253C5D490F1EF7A9918F77
-:104230008FF9D8C8C74B8F19F978C96F8D7CDC7797
-:10424000C4C8C78B5F37F2F1C20E231F1FB9D7C88E
-:10425000C70B761AF9F8F056231FCFDB6AE4E3396F
-:104260004D463EAED419F978E61A231FCF78D0C850
-:10427000C7072F37F26FEF0223FF4E274F1BEDF4D6
-:10428000C93B0CEDEE092F1AC67396BE1C63D7848A
-:1042900090BFD80BFFD5F09E35EF700C5F56197F9D
-:1042A0008AF19F0348207EF930B1FBC0AE89C56713
-:1042B0000AE707A9B0EF6899C6F7DD00D877B44CD4
-:1042C000B97502C6A952678E9B07FEB8CBA7040535
-:1042D00074226166753EE841294308F32790FC9BF0
-:1042E000FDB45E3B48AB135580FA5082FE0588FC56
-:1042F000617B36ABFFB2EE91491007AE35F376B570
-:104300007612F8D56A6DAC7EACAE621DF82352927F
-:10431000FC83215169A7393E3FFF5892113E032586
-:10432000FF6F245AFEB9ACEB21F027FECA1AF877CA
-:1043300089C263B935900521B4F3E6C0F3203A721F
-:10434000047F27F42B12FCEF4AC8CF8D7ED35B404D
-:1043500070D2F6A152F987D09E3A730FDA171A1C61
-:104360006A5DFDCFE79D5EF944504E6AFE8AA71C48
-:104370006EB43F1B9F904310373717A4A37CA84D02
-:10438000262C1E0A71218C0BB3FAAEA14AA891E922
-:104390008B46B9B2B5FE7E884758413EE5EAFDA797
-:1043A0005DE83F4D024B2117FC033D99122D575AF2
-:1043B000C2F52057BE4AEE3C2998102E1761FD0F1A
-:1043C0004D0F61FF758E99E3605D142E5FC07A29F1
-:1043D0005CBE944627860BFD2BF78EE1AA05FC6791
-:1043E000AF60F05F3A4C81BFC3383229C7F115D5B1
-:1043F00087F03B2E79F07D0D8EF4EFC19431D1F82A
-:104400003F7D4F360FE83B9E36CEDF25FE7D2E1FCB
-:1044100035FAAE4E20AFB47825516FFB567EEFC310
-:10442000B218F73B66A91CE3B47DF8619A511E9A55
-:10443000D258DE83498A1F7746C7318CDF3AF3AA08
-:10444000E2D99ABF85D4DD7655FD1BB4FED44084F5
-:10445000FEB91A9E5A6F437A1CC6DFCFE57ADE5B3F
-:10446000BF7F556D02BACC2398CF11ABDF356E15E7
-:10447000911E739399BEA8C15BE2FAA1F65DA9C92A
-:10448000A827BE2673BB78EBD5C17F0F877F2EC5CB
-:10449000F3BF96F49D07D93993ADC7C3AA0545C1AB
-:1044A0007720DF64580BAB4B5BE97C8A13CF87F036
-:1044B000B884B68FA416D69FEC318EDBE7BBA61965
-:1044C000BE78F1B384DFF99671BEF966639C4F7BC9
-:1044D0009FE20BF19DC7F528524DFFE8BCF2891110
-:1044E0008E5ABC4FABBFF5FBB1184FAF0D96B078ED
-:1044F000B993C973F2351D7D0CB8BBE2E3418BA7BC
-:10450000D671FBB2DEBB03F3D9C85E239DCA831606
-:10451000E0F3C6820A0FCB4763FD2C431FC4FCC8DF
-:10452000C682D5E8CF955BFD56B06BE502D107306A
-:10453000979227F3F649D86E69657AA705DA15D000
-:104540005B77AE45D1100C35807F98A4493E086357
-:104550004AAD8106E82735101C8700EBA3F3D9C1CB
-:10456000F198E195D695D17F6604CBC3367C8FF860
-:1045700087E9FA85F87A33331E0F43BFCC6055675D
-:1045800019F8FDAA088E9F99B103CDF2C19ED96298
-:1045900099EEBDED7CFCCD7C3FD9827E0FBE1760CD
-:1045A000F98CB1FB577BAF955786A75594C1B8F6E8
-:1045B000607939BED7CADFE3FD9EE6FD86417B29DF
-:1045C0005227CEA777BFF37E2D7C1EF5DCDE1F1EA3
-:1045D00064799F75DCEED7FA3DC9C7B3589F7B0657
-:1045E000FC8EF941E68FD5DA83BC5DCBBB904B8D59
-:1045F000F9A31D66B65F3F97197FD2E826111D9378
-:10460000061DDF83F8A36A37D6AB530CF61FA91A31
-:104610006CAC2FCE31F60F8C34D6E79418FBFBAF81
-:1046200037B45FEEF5BB846C98EFCDFD2EF97CBFFF
-:104630003CDD5A827647D4DFD765D3DB27197CACC3
-:10464000ED551576787F770BDF27DC3F63D3EC974A
-:10465000BCD5D8AEAD7B3BDF271BC0FF6101BCB42E
-:1046600030BFCAA8AA7746503CEEF9C0E4DBA124CB
-:10467000865B223FCE46C027EE3F9657FE24F7E3E7
-:1046800004B91FA719FC38F9E0CFF1737FCE54AC01
-:104690001FE07E9C9FF1BCF2FDDC8FF3539E57BE62
-:1046A0008FE795BFC4FD382FF0BCF21D3CAFFC2650
-:1046B000CEA71BA6F807835F6DE794F876F14D321D
-:1046C0008BFF4CA7EA1641F9DE23A0FF7C1CD555D1
-:1046D000E87AB3AA7AD6CAB49E7E0F835B56A0A7A7
-:1046E0000CFCE99EC9AC3E83CB55901F204F8897A8
-:1046F000EB3B1974C752786FE1749E59DD13867CC9
-:10470000165B866714B8406DFCBBB4CD8BF9FC9C7E
-:104710008E6DD55561682726BF5D1E00E3B379E530
-:104720001CE99904E14DDF89CEC380CEE2CE76113B
-:10473000FA159606D7510B9B380A4322F0AB86B286
-:1047400040E388B428BEE82C0C7441E788722B53F0
-:10475000E3BF138C742147B6A37E5C5B353B09E94C
-:104760004F61FD8727907303E718EDA664BFD1FF63
-:10477000555B3DBB5F7FB4EF75E3FBC51D46BBAB2F
-:1047800036AFFFF70BF71ADF1FB933E6FD16B68E0B
-:1047900044EFE74466A27DF07C6B7CBEF00FA68AF6
-:1047A000898007ADEE8EDC88FD63F53E09F4B95CC7
-:1047B00070BFCB7ED07F25C5E3C7BC2445E1A58F64
-:1047C0003FF7F37A39D6A97E385D1E8D7831E887B8
-:1047D00026CA902116D23082703BE3EB75FE0C5A4C
-:1047E000BF93A01DE290AD37AB13807F2C34F855FA
-:1047F00052E5AA330AECD7C74494253B83FDF3BBAB
-:104800003E79114E3FC68F729B3C25A638F8D6CA1A
-:10481000AD4DE2D47871B1259CAED737CDF6A05C12
-:1048200038123F8F44EB4FD7BF44D6E5930CB88383
-:10483000E7099C63F96C83392DA52EED9F0EAE36EA
-:10484000BF63AFB6EF9C2C6F44A3FBD4E1FDD389CB
-:10485000A67F464222E9847D2155D9F148C21D3EFA
-:10486000CC770701AADF27B57F7BA011F8A6FA2332
-:1048700011F9C8803BAA443D1EB4790C56C265B0FC
-:104880007F6B0F2D1121DF3EBFA54AC4731387082C
-:10489000FF0E9570B4B42D0EF9999F8CE559DAAAE4
-:1048A00002EBE0F9F016062FB04F797F940F1BABA7
-:1048B00067FB018FBB33888FE7AF18FC75BB9DA2E8
-:1048C0000A7AE625CAAF5051F89ACE4BB3EB28F0DE
-:1048D000F25B996BB676180939A1DD3F15E1A5E5C4
-:1048E000EBD9B65D5471DE031E0AE37993514C0F88
-:1048F0003093CE30C616A4802AD0F1D7073C3EC8EC
-:104900004FCC6D29667E99BC20E651AC16037B80A6
-:10491000EE357898D3DA316FA536C179810D9C9F39
-:104920004B24BEFDD1C9F970AAEC9B0EF6E89E2778
-:1049300028FDC7F10BBCC3C7796EEBECA4114A7418
-:10494000FF6AEDC74169D3CD2B3722B33CC1966FC7
-:10495000A7EFDF6C263CBFCAF89E49F219ECAD21E7
-:104960006605FB6975C969E467573F4F09F9122964
-:104970009C6EC073AABB7FBAD6F6CDE5A1317A474B
-:104980005E01D27354EF10899BC2B5358FD30BA74C
-:10499000274D8EC805414FBED0974E5AAB4BF0BC49
-:1049A000C9A509940EE99FC5D3EE07BF816B4218D4
-:1049B000D237800ECE021D0CCA53D70A4827631087
-:1049C000DEED5CEE593DCCBF123B6F4DAF03BBCA71
-:1049D0009B0223C7D83724F81ED077EE0888190227
-:1049E000DDD0CF51BA960AFAB7EFAE365EADC58FBD
-:1049F00033E91FD8371D806FE0E39FC5F8A93C5409
-:104A00004F1DA393EF9F3D80FB2316FEB1EFD57999
-:104A10002679E2F16D620A782CA313D34BAC3D4D9D
-:104A2000FAE4AD3D88FCC332632ADAC9BD7675EB82
-:104A30004C5CB785DB8BE63C6E47F6B11BEFF1F5BE
-:104A4000274FCC19DF2D3F74A425BEDD98E8FDDE8D
-:104A5000BCD06FE977D8C8F3EC34FBA3D7EE881944
-:104A6000472C6C8F7B0EC3596884BB3DCFA877144D
-:104A70009AD9FEB4788D7E63B367707CFF26CF4FE2
-:104A8000AB18A7E149B9FB3FE97E5B72D44C1AA190
-:104A9000CAED5CCDAFB404F2D4281D5740DE1AC570
-:104AA000D30252EE86C6F344C47C98F3E43DF77516
-:104AB000BA7D1FB0F073010DE6D3709E42CBC75A8A
-:104AC0001864756D3E952DC6FA22323B1DFCAC8BE9
-:104AD000B69A09E45F2D21D2E92E6DFE940F945B06
-:104AE000981E5449AAEA81AFADE7FEC30A0F912090
-:104AF0007F6AC5ABCF8C81F33995166E8751F82B41
-:104B0000BA3C9BA5CE900CFED14F3AAEBBEB060251
-:104B1000EF87EA0797629E3BE651C5C27D7E8371AF
-:104B20007E579A7FEC7CB5731789E621ED11E29EE2
-:104B30003FFCA14530C4E7AE742EE41908820D484D
-:104B40007C2EE44AEFEFF88EEF3FFF1DDFDF6B6155
-:104B5000F49BE8FD15D69E5B30CE9F56558EFE5ACF
-:104B60009ED7B19204FCE03A37BD3E4B1DA2E8FA55
-:104B700079AFB25F06ED67BA8A7E79FD8F7781EFF4
-:104B8000F35FED7D4E86FD7BFEC55333412F58F616
-:104B90009A8958214F6DAF8B9FFF0AC920EF9676F7
-:104BA00098985F410A8FB95D971F082758018ECBEF
-:104BB0007EEAC278F2D2972DA119F4FDA5AF7C52FE
-:104BC0004C281C2EACEB797B08E83F2F0A2CDF4ADF
-:104BD000ED2ABE9D3E5F2A91FBCAE3F9D12D4C4FD1
-:104BE00039F773C71CA03361CFA17B71DCF6BBCD55
-:104BF000169D5C3864316BFDD8F9AA1784D03081DA
-:104C0000CD4F9FEFADE5B99D7B4160F33B680ED979
-:104C1000607E7BDAE400EDB76ACF5F90AE6FFEE9AD
-:104C20003E37C061D5419381FFACDA630A5B8AB13C
-:104C30003C65417EEF770A63009E04E5F7CA8E1556
-:104C40009817BBB27DD35F4C6E78DFB8BF285C7C11
-:104C50006180EB71936F06D47FF6BC1BF2893FEF46
-:104C6000DCE506B8D271E7C994AE6EFC52B70F0905
-:104C70001B3F92D2773C427A64A0AF55ED1BD9F727
-:104C80003A6E3B03FC6D55CC3EFE1CFE31A8AFFCDA
-:104C9000B818233F2E91DF8E017D83EC498D9B67F1
-:104CA000D02B3FF8BE5EB6EFD276381F7CEEE53FE4
-:104CB0006D07BD7EF9DFBFD8FE08F803DEB079804E
-:104CC0001FAD7AF10337D1C1DF65657CE1C20BCF3F
-:104CD000EF7E9AEE930B1F5950CFB9F08B33990AA0
-:104CE0005DFF85FD7F4D07BDFEC15F4C1908F07863
-:104CF000F0C0CD03FBB363806E43163D7E43885FF7
-:104D0000E5A0C092975FE7650C9EDEEA782B13E67C
-:104D100079FE8405CF71ADA2CFAA4B006F2B503E18
-:104D2000407D0D85F7CABD1BFE622A8E0777758808
-:104D3000E885323C847801EFB7FFC3C45228CD3EEA
-:104D400005C6233DC8DF63DF5B758CE2F7DAC4F884
-:104D5000BC44BE9601FEABF66E64DF6DA7F874F737
-:104D6000C5E779F8C7F8BEF82CB4C6E273F9B3E822
-:104D700063EC488D9B17A7E173C5813BFBD51B34C2
-:104D8000FE7025382F16D8BC2216FF042BECB397E3
-:104D90001DAA97E1393483B65DD8772993503AF943
-:104DA000CCDC732FF0C99E5F583C60772CFDC57139
-:104DB000DC77170EBC2B2BECFC8853A07AC505D2F0
-:104DC000FBD7097AC64A815556ED74852DEE28BE6B
-:104DD0005686664D55DCF8FC143E0FB1FDB03274BA
-:104DE000E80E210EFE1EB2E630FD333400E1B28241
-:104DF0005A449E42235E857180CF53B700FD25C281
-:104E0000A7B67E0FAC7FAC0EAF3BD93E8EEDBF9206
-:104E1000EE57E0C37DF01B128E4379A1CD22413EB7
-:104E2000E4057E9E2516EF51F8F3F390DF525FAC58
-:104E3000B226883370385C69BF5F697DDF167EF704
-:104E40005A151C37168EE7BE8E2F0F9A38FF584919
-:104E5000AAA60ED6C9338B99CAB36CD0F7CAD5218E
-:104E60004274BEF5EDECBCDDB93DA610C88B587E92
-:104E7000B132817DFCB495F9BF571E3C540C7CEDDA
-:104E8000DCE19F73BA6474BF72EF2959E5F221A483
-:104E9000970F09FC283BF9BC57BD1E7FBC557BFF13
-:104EA0001277BCCF25FFDD30FFCF3BCD44A5437C3F
-:104EB000DE6E9A1A4FDF6AB69A8D79B5AE312792B7
-:104EC000E87B26B71DCF33D6AEF31F57412F79CFDE
-:104ED0008CFE1522F93EB3E0F969BB02F1E55AF701
-:104EE000223CD7A28D57170327C95B8EFE0929AD37
-:104EF000BC94E9D421833D6DF688867953B99B0132
-:104F000072E9E4A8336658E71F62F4C73F48A47EFD
-:104F1000201DEF0FAAE05BABC4B3178DE307D69853
-:104F200088A29787969E93301FF2A68D40BE9AE97D
-:104F30000D9B0AFC64D5761BC6D5DF3A707937C065
-:104F4000EDC2B3161ECF6479B595DC5E3B73E0F21B
-:104F5000F6FFA2ED67E065FAFDCAEDB43FE8ED7B30
-:104F60001D98E4FCE797938A09E5D3956F3E3213C9
-:104F7000F84B25C4C069FFCA9F0E0C41EE42F700F2
-:104F800056EFDE3734047859FEB35FAC0479B2ECE7
-:104F9000270E0224F9D681E3F742FDC29B2ECCEF07
-:104FA000BAF0E6991B611F507D5BD1CBF525FAF372
-:104FB000DB74DC655067EDC2379CD7811DB30C4AAA
-:104FC0004AEFCB0E26E179075D3F7C6F95A5E7217F
-:104FD000BCC885A88345B489C283611F2EDB63FCEE
-:104FE000DE592BB32B56C93D8B58FFE060B65F3BB3
-:104FF000F1BDAF38DD6BEDB1EF6BFDBFE4FC333AD3
-:105000000E7B7FA58554C5A37FC1C6C65DB6E76F7D
-:10501000F9C6F118BDF6FD0E7BFE4381E5E393FD75
-:10502000368C132C97C3C353E87E7D45268B61DFF6
-:105030002E77878727D3EFBDC6F9E5723BADD3E75F
-:1050400083F93CA03FD489B5EB2780DF15AFDA08A0
-:10505000D0FB8A375DE8575EF1CAE5EE7FA1CFCF7E
-:105060001D70A0DF6FC59B0F23BE5758C2F7829FEC
-:10507000AE67BF85ECA0FDCFEDFF7526E823E7CC3A
-:10508000E1CC947EFC432BDA2DFCF217E33AA85DC9
-:10509000505045E7A33EC6F270AA09BB47A09AE765
-:1050A00079908F6DEC9C328F4BADE67EA28B0B948A
-:1050B000249CFF845BD973EE275A7D9B323059378D
-:1050C0000FC89323D751BB44AECA073E6B8ADC4A54
-:1050D000145A9722B9586AFD4C701F4321E427B037
-:1050E000B8A039CD472A69F9700A09E0F948E7F410
-:1050F000DE7DF6EF14C5ABB7290361BC9136C65F00
-:105100002AEDFEB136E433C67B14D4036C5D97F907
-:10511000FD08B1F3BD6C562DC0CFA3F13A962758C8
-:105120002D29C7C1FF4E8E72BED467FD6C9F5DF402
-:10513000A4E03ED3D6B1A9C683FC04E265506EA8B4
-:1051400029204A3EE47BF8B06EE2F0B014AA04CE07
-:10515000F7C21E843F8BB3DC2FB2F83001FFABC91E
-:105160001940FAB278ABD05760E5F7E9989C2AA9C4
-:10517000A4A5D9C9E004E7F6004E32AF4B2D331099
-:10518000AEF47D7C7E933D702FC0C59A31D2C0A70E
-:10519000E4B41243BD0FDC34BAD8F7BF0D3F82F040
-:1051A00002BF8E8271CC7108B7F5357EACFF7F806F
-:1051B0005F3D83DFF544D1ED1F396D92A19E107ED6
-:1051C000DB28FCD2A2FB2A160ED53C0F47DB4F8909
-:1051D000F6EF933504832F8FD7B460A93D4F492054
-:1051E000D7CFD8985CAF2681B566E0531EE68721FD
-:1051F000692AC9D0F99F8857C5731FE8EB87F68CD9
-:105200005BD17FA9E1D7E491BA8DFC4F390EEB79E0
-:10521000F81DB308FCCA54FD1CF92455B78F6794D8
-:10522000DB1484B30FE303B55CBEAEEFC5A7717F9B
-:105230006CAA51B0DCCCF7C916BE4F1E03BCC37DAF
-:105240000E702F05FD5ED35482F2F3095A67F67E85
-:1052500098E8FDE1C9BEF6B099E21F79928225FA7D
-:10526000ABC9094B685836C455891FE825F9C48F66
-:1052700042B856D28EE72592B57B5D5ECF499E8BB4
-:10528000F11F6266728A98581934831D150BDF5A14
-:10529000DF612BD8E189E65376728900DFBB3C974A
-:1052A000C5CCD2EE693F01F73C389B1C6857A6FB82
-:1052B000AAB23291BF5A905E9DBE8050A9C3637A54
-:1052C00002FDEF21FBB40F801E3F843C445A3EDEBA
-:1052D000926B03386F32B77B811F6EE2E7C5953959
-:1052E000140ABAFBC2DEE47CD25D6AE4031A5FF6FC
-:1052F0004C2831D0B3C67753261BE95EE3BB2FD8C9
-:10530000985FA3D25E7E06E6931A69C57D19BB0F2E
-:105310006ACDB22A5C8BF7CB30FFD32981C5D5FB90
-:10532000F2038CBB5FECCADE01E7A9B5FD13BB7EBF
-:10533000A9611A7EA7571F34C7CF07182230B9DEDC
-:1053400040E98D605E82828868A6744678DE02DB62
-:105350004FE3B0D4E8781D613C44ED10D93CB9BFAF
-:10536000563B7BB3CE5AE2073CAE6F677B68A09D8D
-:10537000C749D344905D44A2F6A4933E920E8DB7E4
-:10538000827E29997D47810FF6B8C47688E3AE778F
-:10539000CEB6421C44482E45FAF9CA5591D55F5CF9
-:1053A00007EE5303FAF3387DE474219E8745BFB0BE
-:1053B000C95342C02EDDE7ECB4633E935D34C49F15
-:1053C0002AED810CBB4E4F2D82AF73BCC3B0FB12D4
-:1053D0009CB72CE0EB21192AC9D3F189DEFB8F148D
-:1053E0009514E8F8C5BA61B7E0FD4A7DF944027E3C
-:1053F000B8EB7F861FD6668510AFE658FE93E6C7EA
-:105400003B9D68A9C2D508263274FD0F92914E27A4
-:10541000023C887347AF1E74534EDF79C6F2BFA8B3
-:105420005C53D00F46E5DA53E3809F26946B55F723
-:10543000211D370D51808E0F353FF22CD43F69B6B8
-:1054400028C0BF1645361285CEB732321ECBC52DC9
-:105450003FC6B2A2A58D6E2242D66EAE6C9E0BFDEB
-:10546000B799D0FFD31DBAEE4235AD773759507F8B
-:10547000EF6E7D200BF4BFEE268702F7AB74B78E7C
-:1054800036B63798709F75B79843261E0F36413C45
-:105490008270FE0E5E20DD7C49A9827AFCC5987878
-:1054A0004BC5168B5F7027867F454B7C7DB216FE01
-:1054B000C9CEA3E5037F2D3BF9A32CA00F8DCF3CD4
-:1054C0009C42F91EC0EFA485C48B0BDC649FB2C460
-:1054D0003E004AFFFD768CEF5FDD3D589F8854EF1C
-:1054E000463C05DCB30C7E5FE657FD84EBE5C49AD1
-:1054F000A0DDCDDFF7C46F5FD1F4A7B71FA5B50D51
-:105500008546BFB609FCD502D8E3B3F8FD196C3E59
-:1055100071E89AE9D34D16E42B0BB83F4AA3F32860
-:105520009D05DCFC9C9E810E97441E43BE276C2A81
-:105530007A6A3C85DF1794FE803E844D1307027C17
-:10554000D736DEB0E51E3AFE97BF35E1F3C5111B35
-:10555000F63FFBA8EFA97BC05EF83733E6917C7974
-:10556000740AC691CF9A8D7E8C1B1C6CDF1FE4FBE6
-:105570007F516493413F5FD4305F063FE8A24833D8
-:105580003E5F044124CC8BBFFB976579105F229866
-:10559000CF72D07EC79475284F4BD08F56B9D91291
-:1055A00037AFFFA05D31F2ABAE261C9750FD2C2D1E
-:1055B0009D8FA7E33B959154DC1FC4A312C8EF5EF7
-:1055C000C4F94FEFFC5ACD06FE73D616DF4F73D4E5
-:1055D000CEE4C2A2C80DB8EFFAAEEF467CBE48FBDF
-:1055E0006E17DBA7D1F53C353EDE7AA2EB9880FD45
-:1055F000CF26C7FFFE9FF9F7BB6B16133FE55F157C
-:1056000016DACF09DF7FA07E1CD8F9ADC929826EDA
-:105610005D952DCB885FB7AECAD679B2FEBEC928DC
-:105620001EEEFF659914C5C39F1B974F595708FA83
-:1056300042F97FC23EAAD834B1388076FE4684F360
-:1056400027665F26F0E3332D0FB8E3E50FFFD9AEF1
-:1056500018FC1C952D1C3F54EF2ED5E147C34BEC95
-:10566000FBDDBFAFFCEA51E053DB5C06BE125BF62C
-:10567000C15B767CB8D91C1ADC0A4800E1A6BC7272
-:1056800002E87AB3C307749D187ED790407FF04B31
-:10569000A03F533D4B748C86EF12665FB6303AB82C
-:1056A00012DCA2DFE57450167F3D63F97EEBAEA9F4
-:1056B000262ADDB0A7E52BD1C12344B5F6B38E5E13
-:1056C0003A78C24007631D9B910E3E03FD27BF2F12
-:1056D000FE4FCBAAFB7AD0771A4D18F73A6D57D305
-:1056E000BFCFEAA3803F9F7607675E5F1AAD2FD9D1
-:1056F00035CCADBFA7F14C0385431CF88D75C4ECC8
-:105700006F8D7EF2545238E6FF1DFD7C92E0DCCBBB
-:105710004DF6B21B009F2418DF9FAC95BDE7AA93FE
-:105720009CBD762FC8D1D3CE9CAF42B4B5C11EF874
-:105730009E83B6D7253F8472FEF46901E5F0DADF77
-:105740003F9C0F7CB88FFE5B1379FAD361E8B7FCFE
-:10575000974FCDA84FE1B884EA3F200730671CED92
-:105760008021E8674914CF5D0197F98E8EC675B523
-:10577000F8EDFA9ACE1FC3F8C4AA128FFEFC00619E
-:10578000FAD8FF8179E8FCF3B239E0F181BD2B90C2
-:1057900072A07BB3C4F2D7CDDEB451AA0ECECB1C1F
-:1057A0004C9FB41D39D2904DDFB72DFC770FF8F91F
-:1057B0002CF43B505A33A48B7A7FB996F745F27498
-:1057C000CF7320BF82D60D7E073ADF7EECE6D7048A
-:1057D000EDBE4F15EF2B9EAB5D5800A0A374F39167
-:1057E00096BF22D5B1F664ADB98EB5733FEAAA0A69
-:1057F000E6277D6B5E12C24F5BD7DCD737E07D6951
-:10580000735F1F341FFC69739DF97F0478BE06899E
-:105810003540F7C94C3EC7D2C566CE7F7ED026AA9A
-:10582000663ADE1173CF6107EC8B1F0A68577FFF62
-:1058300083236620F9FF3876DA0CF723DC078945E5
-:10584000743DF3882233253A84EFCF27ED2E566F2F
-:105850001F00F79946C7A326338C773F8B3F7FFF06
-:10586000836353408CD2F1D64379DF6F890CE3CF49
-:10587000EB50EAD9B1273EDEEB743C313A5E2FFCA7
-:10588000242BC2230A1F2BC2EBA3DE73242AEA17A0
-:105890003AF8A2BEA2C1B716E046E1373769CE7426
-:1058A000529C78BFCC750EFF23298ECE2716BE5F83
-:1058B00042D320385FE67F09F6CD3F3BFC7BA15CFD
-:1058C0006EEDC99472F0BC573BECCB95A640563AAE
-:1058D000A5ABF34303F903E0505067FC386FEC3E8F
-:1058E0003D09FBE55A28E9BE8079F07329F7F27586
-:1058F000BEF5A3332ED897F5078E6742B9C2D4B54B
-:10590000F96ED86FBF31A1FE79B123BFDFBCBA9366
-:10591000DCEF72D4A1DDA3C1D6791FD7E7EEEB701F
-:1059200084D652D2B8AFDAD46B5F015DDF57CDF2C7
-:105930004F88D4597C87419FACE3E7D4FA8E03F6B5
-:1059400042EC38DA3A0F670EBE06ECCB6747CB68FD
-:10595000471CFAEDC58F2A69DD3ED48A76C2E6641B
-:105960004EBF65CC6E7D36D9EF2802FF57638A4F54
-:10597000A5EB6CFC256917299C0E8F782834A91497
-:10598000EE7916D177B625F25C7012BC57C8EE9945
-:10599000F170BD744BE7E916A0C733272C1877F8D0
-:1059A000C465C2F9369ACB33418FFF639B1CF7FE67
-:1059B000B28F5C12CEB74DE8C23CBDF92468057EBB
-:1059C000D1D1397B20CCC7ED231E20FF33AD2691EA
-:1059D000DD6FA6F95BC212F3F7AB12ABFB79E9B14D
-:1059E000E9EF17DB387532E6792C687A17CFB1B951
-:1059F0004BE3DFEB6373B2F9BA3A53A6017C5D93D4
-:105A000045CCC376F97A04782FAB73928CEF078577
-:105A10007EDFCF5AE399067085F781CF675DE5FB9E
-:105A20008293E5693DC6EDEC36B3AF7E321DA76DBE
-:105A300073B200F8D0FA0D7632BE7266B2E64762F3
-:105A400079C299791E5B1E9D77A61F37377195061F
-:105A5000F11CD30EE8C7FCAC0887B611AF84218EC9
-:105A6000DD08FE15C0B399D153E36601FDAA147E8B
-:105A700083414EFCF109CBADB08EAC06C103B63B01
-:105A80002DE3CE7BB6CBCAE8BCE929B40BC14D0BE4
-:105A9000E366B6BE8FF3722558EF1A4E1F7FBC0225
-:105AA0007D9C77303F54667527BFDF2E8CF7D80575
-:105AB000014E50F797F2FBEAFC8A3E3F26BA7FD6AA
-:105AC000723A247E88B3558C9343E047101BDAF07A
-:105AD0009ED4F9410BF91E5D5F93C0EE1D55478BB7
-:105AE000FCFE24FF498053F36303310F6F83E8CF3B
-:105AF0000439ACFEB38C71BAC3FE8BDBE03EF8ED2B
-:105B0000E364DC1787FDEC5CE1B36B72DA204EE9ED
-:105B1000AA9ED4329F8E17F260462CA92D25EFE461
-:105B2000439C728DE81168FF60B996B7EDC17CF2B5
-:105B300051A62FA615401C6F90883EA53302BBA727
-:105B400061FD9A491EC0EB7A4F9AA0B75F66713A21
-:105B50003891523ECB49E1E37DF4710F9C85DB1215
-:105B600049BD06FC886A83ACEC62F142BCDF21953A
-:105B7000E325B5530C2F7263DDB9989ACA5B2630C2
-:105B80007FE98FA707989F1362A363D0CFC9FFBC9B
-:105B900088D7345E6B1C69C7CAD6758BB03F8C93AF
-:105BA0004EC7492D15C363207F2DD9BF1DFD7653E8
-:105BB000AC08272275B5009C425306633EF8E3E328
-:105BC00087BF0BF9E3A9477B66831C0D0DB5FF4723
-:105BD0001BF0A9F5B202FB3C754DF73DF03CD9F73F
-:105BE000E40350A6D67DF808F0E9E4AEBFD4E0F3B4
-:105BF000A9B2C1BF98FAF1D9BF417B6AB96CF05321
-:105C00007E9552FEA093C2677B613058A1B0E7FE3B
-:105C1000F4E83AF6ADED9C0AF7D89F9925B2F33235
-:105C200084F1C3AD5B3DDA39E552900B1ADC36885E
-:105C30004A7B18D635D38AF491473A915F0D826832
-:105C4000766E142FA91F6FBC1FF23562E7D3E014E4
-:105C50007ACF51C3BD80786E3107CE1F4EB6035D3B
-:105C6000EF2FE9F4823EBF39C1FD9D475DEC7D8B8E
-:105C7000C8FCACB1ED47783BB0C496122CFD455042
-:105C80003A899A046586D50FF9CFFB45E53F91CE59
-:105C90001F3729801FE86FA6F83BF4CEE7E85F3C8A
-:105CA000147C1FCBE75C05DA78E174FA7E73E9694E
-:105CB0008CD3347B188D5436307E51E9EDB242DC02
-:105CC000A4B2907876707A53353883BF8CCBAB8A88
-:105CD0003B185CD30A09C67DC11704F74BA5433FA7
-:105CE0000ABFB486B5F7231E49A79A4BFB35C3B844
-:105CF000809F3A91B071BBACB87F83268C7BD2FD7C
-:105D0000FE3BF06B55340DC4B83F1C0F86F152F8C2
-:105D10007753F8786D741CF01F9E6930E1B9004824
-:105D2000BF81BAB286D232D2674F59011D5729F5C9
-:105D3000781A353AD0F818DD1A0BA8BC00B82D50E7
-:105D4000D5FB81FE4E5B3DEFC03C1C5B2D0AAC7F5A
-:105D5000C1D6571F06FDC5E1ED6A00FE50398ECD54
-:105D600037A5893E473D47F91DF4AF6CB228EC7B5F
-:105D70001C7EA59CCE381C16F2792F6C65F3B60FED
-:105D80000D05813E2BD750B8425B80D13DB844BF52
-:105D900011715F1D85F5BBD4741C77C09C987D1173
-:105DA000437FDABA2AF8BA2AD6B07511BE9FE8B492
-:105DB000C2306E45295BE702C2DE17E1391D7F2143
-:105DC0005F4F85FA0A960B1B2C86F1B717ECEC8413
-:105DD000F96417CA8A807066F71B66F27565D6B1DA
-:105DE000EF6516BE82F022D5BAF9A25F5557A7FB20
-:105DF000EACCAFE9C682C3FF70D0808E7BFA47EC55
-:105E00009E81BCADC6759DD998FF1C9CF7FEE40928
-:105E100019E3DEFB45DFC92CB4476585F11FDFFBC5
-:105E200033804F2FACF3011FDF57C6E07FE63612F9
-:105E3000027A1876B43C05E03DEC68809755184F1F
-:105E4000A700117AF91E9D1F35991A04E09791DC7D
-:105E50009716031F18C7CEF70CD5CF9BCE2FB521B1
-:105E60007D12E443A58D4B9924E315DE31ED479F68
-:105E70009E0DF78FA61D79FA01F8CE20A25B0FD0F8
-:105E8000833B979D6739425BA15F75F7A3808F269F
-:105E90007E9FFC3098590A9647A04CA5FB7B530A7D
-:105EA000CC5322934BA2FC60D7136346015FC1948D
-:105EB000A7122CC3A4A42FDFD0F51FC1FBAB429CBB
-:105EC0007E16B762B0CF773D71CB08B0E39B414FF0
-:105ED0004C827B383D5F409E8EEA1311EECDE6B0DA
-:105EE000B5300DEEA51609E82F5B0A3E1461DF35CB
-:105EF00077101FD0476AF9DF2D7A3C96B9D8EFEDBD
-:105F00004832D904FBFFF088EEA980A7D02111AF59
-:105F10001898F42BE7D30ED0873E6279306DBFAE70
-:105F200042F9FD50A61CF73E5D72053D31B67FCAB1
-:105F3000B0D9E8CFCBDAFA18DEE7593955F27D8FC0
-:105F4000F64EDB5A56067A8C524EA96B209D77EBA3
-:105F5000A8B5F83B103358BC4C99CA9E2B9359B93D
-:105F6000A9E6E88FC16E0FEE916C7974BE2337B24B
-:105F70007BC436155EB406A85E5A5AF6B2F536FAF8
-:105F8000FCD3522A05E9F34F275CB4417CE7D9D210
-:105F900049A900CF8E06A35E47E0722B6A0F155900
-:105FA000827E179D57D30704E169B2845B2A68DDBE
-:105FB000F4AA13349C3E76CEC6A6B63940A70B0A87
-:105FC0006474DBC7AEB793CB8BF9D53D53E1DEFCF0
-:105FD0006C9530FF7EF02964CA0B39CBC8563B91D3
-:105FE000E9B8B632FB2428F9DF06BE1C2C0CC8F039
-:105FF0008AC6CF9A8655EC067E76DCC5EF0BA95A89
-:106000008CE7CA70FF9B401FEA298B6737153BED71
-:106010004C9F6DBDFD38F8A91754337D3FABF50B90
-:1060200001F141F5BE4174FCAC52BC5A902C58139E
-:10603000B416017EF244A228309F7602764290CABE
-:106040001F3D1CB471FFBBEF2F7359701DC5A03BE2
-:106050008F8EAEC7C9D793E9A3EB8923A70BE1BB0A
-:1060600090EFF3CC1787C603FCD73013292B784A5F
-:10607000B0EAE691A55EDD3C8AF83AEA5CECBC85C4
-:10608000ABB44BC0FB6B62F83BA8F3B06FB73B2ED1
-:106090008C62F6BD919FF6A973BA8A7D9E19C3AF33
-:1060A0008A2CEDD311BFFBD8BDD584D07D6BC5EB59
-:1060B0001B1576CF6748BB5FBA0AFA8D74393D402D
-:1060C000074D233E2C01F86CE6FAC2C24282F6EA82
-:1060D000C28C4ED417E6D7717D41F2D5039375B4C7
-:1060E0002613ED7E18D01F50550213BA8EEB0B9A73
-:1060F000FCE772BBD2DBD98072B58E9DF7EBD5334E
-:10610000542657B3BC4CAE5736D0EF289C98C7E8FE
-:10611000F51226C795AD5C7FE07238957F37AD816B
-:10612000C9AB54D023DC9006A1A25CC618567A54A1
-:106130006F1950C8E4656AD37E946B2F3A199F4C4F
-:10614000DBCAE4E5D0778FA900262F7DDC42F9F485
-:1061500013BCDDEBA1FA594A543FDB20F2781361FE
-:10616000FA21E6FCD3796EE6FDB5E73BF9FCF61FB4
-:1061700049B915F8EBAE600E9E2BD7F62D7A3F6924
-:106180003D93DF879059CDE2E42EDFA2DDFAF3677D
-:10619000152E76CF50858BDD07EFAA0E7B615CBC98
-:1061A0005701F9B88CFEC58D545F42FF13B7AF4A53
-:1061B0009DFC3E194E3F89E489C6875CC4EF2EA43E
-:1061C000F0FD34B41BF9B54AED2558DBA7C1DAC19F
-:1061D0004B61BF076795C2FC9BC77F85F91F5909B3
-:1061E000ECC58F343BF35BF275D7D463CC0EED1462
-:1061F000E39EEF497733FF43BB441C004F5B90DDC8
-:106200001B671B27C7ED6F7333BBEB53BE1F9BC7C9
-:10621000EFC6F39909E5B34454531C79AAC9DB26A8
-:10622000C0F3F574DDAE5FD5E3EF0849A17213F258
-:10623000578276679074A11DA916C8E8376C32079B
-:10624000AD808F2DA51CAF1E6B1B9CCBFCD678A1FF
-:10625000F0003C6FF48B21211BF01CF21431BF0EB7
-:10626000DEDB7986DAEFFA7845AE5BE47052F087D0
-:10627000F6B21A187D358F97711E8DA3D2DB4CD9DB
-:106280007AFE2B70FEC9E8AB71FCDB485F573BBF61
-:1062900045D52F3DF3A92E9ED8BDEDF91C8073F492
-:1062A000FE0B7FBFE7291655FF65EBCE387182DE06
-:1062B00076B0A39C600786BE6F886BBAD9BC6F743A
-:1062C0001BFD77C05FCD685C8406837F69DFC49067
-:1062D0001BDE236B58DC76098FDB7EBEF3763CAF8A
-:1062E0005E44C9CA1C07EF676B8CE7D5CFEE7A7E98
-:1062F00030F36B840CF1B325BB7F3ED2101FF61335
-:10630000256D0CBBB718E5F4DB3ED5628ADE3F2075
-:10631000C3EF0DE446EFD1B293762C9DB07F69E9CF
-:10632000263D587A401CE5829DE4C3328D946399E2
-:106330004EAAB0F492209683493B961960E7E68214
-:106340005CE8C152211E91E8F87E0EF1613D8F9408
-:10635000632901DE52A37109698F15F337207E018D
-:10636000FB3ED1B9B391EE8A656E8477D5B5E598D9
-:106370004FCEE21533DCFEE56E942F61E4DFF33996
-:106380002B3FFA9391ED70FE68F56676EE45E3EFEC
-:1063900068DFD0EFBC94C2E481FAB8807C6C9D6366
-:1063A000E68D08CF26F3397DBC8158AD79F0FB1E10
-:1063B000DAB8F3B99F613E9783E0EE66E7077D7830
-:1063C0003E693EF81B74EDA4B79DDD4BA38D233AC7
-:1063D000260CEF2FDEA77B1FF3A32B62ED802BC9CA
-:1063E000EF98FA82D8F7BFA6134A8FFAE35EBA5144
-:1063F000C9447AE5F29B129482EF35584EA13D16BE
-:106400009CE2D7C3E539CEE734B9B22026DF23B604
-:106410005C20F1FD11330E9580C970EF1ADE29A1C1
-:10642000DBDFDA7DA4DAEF642DF107E441EC352FF0
-:10643000E0D1C3E71D24AD9306D1F233A8EBFCFBFA
-:10644000BF4B0AEC77EBF68BC7CFEE59203C2EB151
-:106450009CEFC729A6A632E0736702C40776C41270
-:1064600052E5BE01FCF9C7D8FDC443E8BCE512B053
-:10647000E3882AA6605D85DF6B395FC3CE0975F3BB
-:10648000FB6876F37B85FFC4EF112E6A797826D0FE
-:10649000C1E7FC1E9A828E8DE5E0F7296A77CC036E
-:1064A000B95FD43EB112DA8BF658D8EFF0703EA146
-:1064B000CD0B8EB9DBE97732E8F7AC29C04F08CABB
-:1064C000DDF34DF610FC7ECFF97613BB47B550C413
-:1064D00073F770EDA089CF2F2905BEF75FF7823ED5
-:1064E000F239E727DDEE64862F4915D434484B2175
-:1064F0003ED06B1E73ACC473908B9CA1DD4FA74143
-:106500007EB8D5B78E7EFFD0FE5733E1F9538E9516
-:1065100058FE69DBF14CE05BE70F1C97E3D1ED0A15
-:10652000292C837F6A59872042FCA4AC7D9E0CF104
-:1065300091457B0FA15F79852780EDCB5BF6637D6D
-:10654000F2DE77317E323449417C9F1F14403F6F29
-:106550005E8B250C3F59B22F27B8346EDC3E89F193
-:10656000DDC71C6FE0F84F39DE781BE1B2CD82E762
-:106570003F0E6DFB158E7BEEC0AB7CBE04F305CFEA
-:10658000DBDA4FFE13C8AFFDFC3CA6B5D3ADF70771
-:10659000FF9DF375AD7E5EFB1D9D8C2BF4D37E8F2E
-:1065A000C7D9E9667CA9D30D71B345ED0C0E7F32D6
-:1065B0008765D02397B50B0AFC3E5ED9DE363C0FCB
-:1065C000B8ACC38AE72596013C006E145E08979626
-:1065D0004338FF0C80CB6858C7FB988F9FD741E1A9
-:1065E000521C5DF7326700F7ABB65E0A07B6EE7D68
-:1065F00057C253C088A7967765F0CB2CEF10107E5A
-:10660000CBF7B2792CEA60F39ABC771EE2FFDC018B
-:10661000A280BFA57BFFF1CF613DE70F58F1FE5E81
-:106620006D5E944E89BB04F60FA353D2C1F8AAA69F
-:1066300077AF08A5E3EF0CF4B6EF65BF330A20B3DC
-:10664000517A2DEA988571C162205EA0534FFB48B4
-:10665000F67B81C14C80EBBE89E14C98F739ED7730
-:106660004CA56026E065A43B509CA4DBE7674FBDCA
-:106670008A72B140ACFAC3A3B08F5F66BFBBF1F0C2
-:10668000C78F897A784C841F4A1E0D70FB9D1BE1D1
-:10669000D67B7F4B90E54B9100EEC7457C3F9E6FCC
-:1066A000A376275DFFD9969F61FBF941C6FCAA3FFF
-:1066B000B5BC950270ABE0E73148E876E447142EAC
-:1066C0000DD63872BEF75C5B889D57BC2010BC2F7E
-:1066D000537D46835B953CDB10E763FC30A335FBC1
-:1066E00008DA19A1F8E71C63F5A4D8FB5113E503F8
-:1066F0009CE6FCEC537E4F97267767B8033F481A19
-:1067000090F8BC77C5A6159900EF0A381B89F711D8
-:10671000BDF13DC823C57343EC5ED430C0A75BBB5D
-:10672000F79474B0F664565F9DF46F1BE03C58B765
-:10673000768FAA7A98B567B3F666DEBEC75DBE34BB
-:1067400009E53C11D8EFF99893E1771934B991181C
-:106750000EC6DF6568830B3706E0780FE278121DFE
-:10676000AFE8BB8FA7F1E9EF3C8EF57F761C4D7E3D
-:10677000C1FE84D447E2F38DFC9F80DF7FF77D125A
-:106780005C68D85797B7E5D6431CED9297DF03D3E3
-:10679000B496803C5FB8F531C3EF7AC4DEE354CBE6
-:1067A000F372E45CBADF74FBFA7012B3730E27095C
-:1067B000BDF794437C6B3821FC9E29AAE2A5F37BAC
-:1067C00025A9FE91CFEF2D2F2041D44F4792762C53
-:1067D0000B492796C5A4074B0C33E782ABD487E55A
-:1067E0009FCBBAC6C0E2975B03CFDA44CC3B7813A9
-:1067F000F6C9F9A181E7E1DED9758E95D7C3FC8F83
-:106800002479F83CC286DF5721FADFBF50401F9C35
-:10681000E1ED4F1F241EE95C6FDE4B0EDE5BFB9B40
-:1068200024C443A2DF41BB3FE6DE1B762E5C83C35C
-:106830000AB84987F6FF65EB6ABCC76FE95E17EADD
-:10684000C9C35BEBF0F7AF9692CE7438273C9CDF60
-:1068500023425AD8FD2DDAFD20235A2C86FB4B56B5
-:10686000C4FCFECE32FE7B59CB627F8F8A9FC3DD94
-:10687000040FE2E463C49EE33D9B14FF7715496176
-:10688000FCDF3F893DC7BBB75DC4FCA8D59077A5A9
-:10689000B32F46ECACB218E94BF94D9E5957177C13
-:1068A000CC1FE1B2FB77097DBF5394CCF4807D828D
-:1068B00010371FEF760FB7B7491D994EC7F9BFD4F0
-:1068C000AD220900800000001F8B080000000000BE
-:1068D000000BDD7D0B7894C5D5F0BCBBEF5EB349F2
-:1068E0007693CD6673DF4080201737185244AC6F23
-:1068F00042C4886817A48ADAE2060402E406A58A7C
-:106900002D2D1B122120D6F83522D0842E7829581F
-:10691000F5DBB4A848835D3022DEFA87D6B654ADE5
-:10692000DF827C8A88B06A4BEDC5FA9F7366267B4E
-:1069300021116CFDBFEF79FEF4B12FF3CEBC3367AC
-:10694000CE9CDB9C7366B6B55EB56F608CB506AD4C
-:106950009ADE094FBB2EA8143396975A655E0265DE
-:10696000E6D0D94778189BA69F72C853CE98B141FC
-:10697000BDC404E5BE1D4BFA0D506E75ABCCA440F2
-:106980007B878E3128B31C5D700494DBEC3F73CCA5
-:106990001FCBD8481BBC877E0AEC2CE8817EF76FA2
-:1069A000BF5D87E5D666C6B2711CC5DFEFA1EF54A7
-:1069B000F630C33F6D46998BB122FC278CA3B28D74
-:1069C0001FEAD318AB6E386E89D8E07DA476061B1B
-:1069D000CFD86576F87822D4BF79F57B58DEB6F249
-:1069E00098C30FE3BDB87DEDAFA7417F8620C005FA
-:1069F0005D947EDAFAFA34182FBADDC87640F9339E
-:106A0000FCBB82B1C255EAB1889906649FC17FF987
-:106A10002B12CB4606E552512E4638E2EAA13C0E37
-:106A2000C7CFC2D21C167661BD80D7A9310670329D
-:106A3000BBCDF9CE18C62EB52BECB361B1F2C5585B
-:106A40000694EC3474545901CE9D7F54BC2D507D76
-:106A500060FBC2229CDFD967FC457698C74A73DA8F
-:106A600078961E8377E099EE11E3062C3A373EC301
-:106A700016E68EB51FFD50B3C90FFDB4AD66DEE35B
-:106A800023183307FBAC63701D0F19BC50647729C2
-:106A90006C4E08EA551BD34230CE388742FD253F65
-:106AA000EF5AED79B9C4101BF7AE4FAF9F83EB1BC4
-:106AB0004DB56A3B9473E192DFA9764F00D7D7902A
-:106AC000CFBC29309EC1D99F6B87EFC63C6DF4DAED
-:106AD0000065D3FE736C7A04C61DF3DC4DCC93CAFB
-:106AE000F185F0AA2B8DDEE3998C99563ABDEA2503
-:106AF000D8CE46F4F891CD183421FE57DEDD81F56D
-:106B0000ADDB2BDC9EB1B171D7AEB67B5580B36BDC
-:106B1000B5D9ABC204D78AF925C357E0D0F982F0C2
-:106B20009D51C7FC585F0FEB80F4536F4FA1E752A4
-:106B30003B87BF5B0DCC42F8BB817E5A905E57709D
-:106B4000FA5D9E630E229D2F7F7178361B3BC8BA7B
-:106B500088E723ABDDDE1280A36BC53C37834F2B68
-:106B600097F559AE82F92F4F35DB911EF569231F3A
-:106B70009882F4FE9281215FB5A65678E6C7F5A704
-:106B80004F9BE4467CE875815C6667ACC57E4B8DA7
-:106B90009A83F412D8CABC8CADEFA8AA512F857283
-:106BA0006A205781FAFB3AA6F1FAACC05605EAB75B
-:106BB000744CE7F505815C1D94B7775CC7CB230265
-:106BC0005BB1BCAB63162F8F03187219EBE9B8A148
-:106BD0002600E3B71ABC73BC30EE1300FF58803FA9
-:106BE000249E3F177891F53FC3F780EFDDE2995C73
-:106BF000FF94F86ECF10F57B457DEF10FD3F2BBE67
-:106C00000B0FF1FD01F15DDF10DF1F14DF1D1AA274
-:106C1000FE2551FFCA10FDFF4A7CD73FC4F7BF16BF
-:106C2000DFBD36C4F7BF13DF1D19A2FE7551FF6625
-:106C300052FF6F89F611F13E3FB5FDF500D05D3E84
-:106C4000C82DFC2B4D6DCF40BAEB6A2E27FA6F9DF5
-:106C500008743E3646EFF90AF361B9D4A1527FA514
-:106C6000288FE1F9AAE8BF7259C9BD4877CB5FD533
-:106C70007B910E5B15EF113FF41F58A6F3A2DC5D6C
-:106C8000FEA29ED3F93235C8E2F8FBD524F8B70945
-:106C9000F8DA04BCCFDB87517DD14AB77786949769
-:106CA000C8F7F6C4B219F84983F1DB9C5CBF942E97
-:106CB000AB328F42FD01FA05E5E65D3663D804E3A9
-:106CC000DF6557A9BECD5965C7FA805D25FD73976D
-:106CD000B3CA3C1FE5AA0D845D058C67E77DB7D973
-:106CE000D59A20CA0F4735D54FFBCF197694A36D9F
-:106CF0002CEAA8C4F9AD02BD02DFEF6FAEA2F745E2
-:106D00008E3F39503EBF9CC1F9BF2FF5A0A518DAC0
-:106D1000A9DFD691BE186957498F0D5BA50B7AA0E4
-:106D2000499F7DB90ECB0FB6717D057FA965307E79
-:106D3000091F9EEDBCBDE2A552D467F7A85E8F8700
-:106D4000BF53E3F44109EA2BD05F398E0C2E1F8527
-:106D5000BEEA2E671AF61B709B830F43BF252A736A
-:106D60006766C4F09EE3D07339AF9FE145BD36BC82
-:106D700023513F15B7C7E92786FA32513F25EBABC0
-:106D80008266908F71DF9BDCF684B2DE914AFA094D
-:106D9000648CF733187A79CFF2ABAC2C26AF93F52D
-:106DA00051ABD00F52EEB67E7A49827E907239593D
-:106DB0003F9C5FBEFEE6EA51448720AD3CE797B3B7
-:106DC000AF221DC03A1AFC0AE90FA6FADDBED4F3C1
-:106DD000E3CB60F0D9EDB6F3E3CD90F51AD9150603
-:106DE000BF4AFD9FA357CE8357D9CE687EB0FB38EC
-:106DF000E8B53FBD7947290396590BB8A1F5CFD225
-:106E0000051F8679E7AFFC6937F69F77D0DA867879
-:106E100036BAE777B7E17C3A1E600CE8496FE6F4D2
-:106E200064CCA9B2E3F7AA4E73670C87F2AEDFDD3C
-:106E3000AC003DE9339BBD0CD6EDD0132F655C83D0
-:106E4000F87BD5407C6ED2F9EC6C388143F4B6AE59
-:106E5000C0BA7D03D1B1DF8C78CADF69263DC0029C
-:106E6000DBD76B40D4ADB01C6C32D67F7DBD06F84D
-:106E7000D9A90C94AFC6722868E4ED4144E3FFF54C
-:106E8000E81451CF341558F3714511F5FF59533DAE
-:106E900005DAABF6312AE89DFAFB7ED66EB81CEB1C
-:106EA00075F27B8D4D82F9E278A2ACC2FAFCB44F48
-:106EB000D407C2EDD5C0443D46393E0B60FB1E9D54
-:106EC0008E9703CFB463FF8F5789EF030FAED7F2CE
-:106ED000099E6BF40EC6BEE3E86BB75D1A83F7EE4E
-:106EE0008C97DA5B607E1F782269B09CAC61FB7185
-:106EF00017EAE775739A7D8837247C1FE8C414BDB0
-:106F000087E86960DD76CF0CE441ED99837F4B1B08
-:106F10000B554DFAC8C114C05FC39E66B301BE379E
-:106F2000197C81BCE2D8770DBB6BC99E69EA2DA3A1
-:106F3000E720DF1D5287FD4BDF998D1730DE07E11B
-:106F40005F373E06550DFAE6769B9EDA33BEFE832A
-:106F5000CF4F7EFFC163BFBE01C73BED89B8A643DB
-:106F6000EB7561C0CB20DFC9F68D7B66D2F3D729E4
-:106F7000DA7A07F0752DC82E92576AB317DB87CCE3
-:106F80001D762F20DA62E8F0A1DE00D40775936247
-:106F9000CF8D8E126A9FFC3E99BF4266963903E5FB
-:106FA00078BD4A7A2A640EA48C87F246D887B4004A
-:106FB000486BCA7E37612C969FB431DC97B4D6F704
-:106FC000B9C7225F798D0CEDDD8D97867290CFDB8E
-:106FD0001A8C731E027842E1E5EE0571F6D6DD19D2
-:106FE000069AD7FAE781EF2E86A721E450F0FB112D
-:106FF000A03780942D0EBF19F739969C0C1628C621
-:1070000076B68DC89FEB0DFE9A2A6C97A323FD627E
-:107010001931BBA60AE07067E9143DC1517D6421B6
-:10702000EA37BB1135283B9231EF6788A79FAADE6C
-:1070300066E4C39FDA6CF60054808CD450FEA9231A
-:107040009C412C9BF4AC19F5785E19E8F3383BF6BB
-:1070500088909F471C468277A32534B312FAB12E3D
-:10706000D7D90330DEFA864DFDD3609C1F353C75C1
-:10707000B805DE6F70A90CE1B039D5B011F48FE11D
-:107080005A8011E07EBCC56747F91ACD52D90EA8C7
-:10709000B7961899274E5ED9C642394E4E663A5574
-:1070A000CD02DF9FCDF0BFE880712F79F535337EBB
-:1070B000EF9EA8D321DB8454BECE69E589FDD8A715
-:1070C00024F693519D58EF9C9158EF9A9D58EFFEEE
-:1070D000466239F7B6C4F22C496F20736CA08FADAD
-:1070E000BC8A59231FAE467D0BF8F903E2DF3A5202
-:1070F000E745FC581A1E3AB110EAF3509EE07E684C
-:107100003C23BD7BA0F03B1EB40B4C19CD1EC7D851
-:1071100073F1915760BE06D7CB56A2DA19B4B7BD4A
-:10712000F9DEA7D8BF8DC5B52B46FC6827113FF8FF
-:10713000E7067852F11F1EC477F37F7D0FF5E261F9
-:10714000BD17F19DD7A0D2F8F7CCF604F5DC9E7000
-:10715000A33D9326DAA79937F6EB419EA7BDB97EEA
-:1071600019EE7B93F1EA62CD0AF225D007DF6FD7E3
-:1071700032D21FEB74AC0EE906F708D81F994720EE
-:107180002FAECD34129E1461EFA0E6C07A97B09F67
-:107190008C39B759908FEF3AC8E9FF2E23EF67A0DB
-:1071A0003F0F0D8A24CF504EA666E812FAD9641715
-:1071B0006D4439CBC1CB3D7D19D7205F6E9A9D318F
-:1071C00001E9C484FB2EE82F3DDFAC8D86F9595EC2
-:1071D000340614E8345D657D0658CB1E2BBBD507FD
-:1071E000706C39640DE8E1BD65C17FD8D14E1B9F3D
-:1071F000C1E9BE678DF7372807A2B52AE1D192D53C
-:10720000619F3096CF2100F02139A05EAC1CD1499E
-:10721000769EA5B283F4BBA5ACA303F1B465868EBC
-:10722000EC8D8CDB7444CF9682D0E112F4132CD019
-:10723000D9B1BF0C50FC46E8E487F91D3E1FF60BA0
-:1072400038D7557052C17E6986304EA6C0ABD3B9CF
-:10725000FB0E05FAC9C4FEC6F3F6882787C053455E
-:107260008687E0768A7E334BA0FD78DE4F5B45ACA7
-:107270001FB98E5B6A5810E193E3CA7E06FA679ADB
-:107280008272D5F032E00DD64929341370772D6122
-:10729000B43FEE59E36BDE4E7C6D233F47AE33BF08
-:1072A0000AE928F7D0D659BAF1F89D95C6312C6075
-:1072B00041A4E35C9599BF9A81F68D8FF098CCAF8D
-:1072C000397D1DD7A39D2AD725997F7354D6AECF7C
-:1072D00038978F739CCEAA91E307E1E7247EC939E2
-:1072E00014FD36127D325F6F4B395D867861F1EDAA
-:1072F000F5E72FEBF5A1C3E8E761D9A02700F585F5
-:1073000049E331F64F139615A6F37C361CE5BE43D0
-:10731000D031E82B60D69E09F6A936E4D3658CE817
-:10732000ABEAE98D37BF0CFD9D1D61B4A35E293822
-:10733000D4D18FFA91EDF18FC275E852FD3F4E81A5
-:10734000FAAE23D90CE5F67A0BDF8FA982CE93F53E
-:10735000CBDD197C3FE6413DE7FED79FD23E0C9541
-:10736000B8C6D881F7EEFE8F2B5F3467FD0FDA5970
-:10737000ECD1F51A94F3FBFA5B6C38FE7DCFB79B2A
-:1073800001BF965779FB0D500EA888BF7AF2671D92
-:1073900028584878525F3731A4D3717A2D8865F622
-:1073A0008685A1FCDDF9E437EA3C287F5CD33D28E3
-:1073B00087BA04BF6F15CFE4F9AB46CD8FF644F220
-:1073C000FBCE01B9E43B510BEB38EE4123DB0095DA
-:1073D000A5BA79EDB8BF8BAE07F90BB5F3F49EC62D
-:1073E000BBE3F6B7EDD6CA4733E0BBEED566E6079A
-:1073F0008339FF1385F981390B9CBFAE44F953C81B
-:10740000C20AEAD9C266307891AE5658993F8EDEEC
-:10741000F33F51A97DBB557B34238BBF37831C3091
-:10742000F07FB29F66F858AD93CB28B45F0C8F59AC
-:107430008FA2DC60CE6A6D603F320CE917F43E8C9F
-:10744000F7B498B70170689800FFD97461D3F873E6
-:10745000DBF70A79AE9A6D619497AAED9523245FC4
-:10746000ECEAA9F876B8EF262156CFC82F8B78A181
-:10747000F2B7EC54CE03F96B9A40767F00F7DF81C8
-:1074800034BE1F619AE671BA905F182139DFCCDAF9
-:10749000CDD08EA81DF82D87F55BC86EEE631EE477
-:1074A00007F4B0BD9342228B215EBB18AB89E70382
-:1074B000F9947E0975A59EF653639EB3103C8666CB
-:1074C00016B4A03D84B001BED5152CA816C7FC8209
-:1074D000A50E0F7D6764CD64CF3EFEE95BB928A79A
-:1074E000AD07C11EBB18D7594772CA6A4DE43FC6E3
-:1074F0005A084F27057D74AFB6D33A0FECDFFCAFC7
-:1075000089758EB4A0BE285C9191B0BEB25DFE2795
-:1075100079CC7F497CBF41EA2FBFA44F41BF4CFECD
-:10752000278554DFBDDA739EFE870DD17F0ED1D142
-:10753000D0FDE7537D77F835C775808AAE689FC365
-:10754000E789D9D7C978CE5F9128972FDE935896CF
-:1075500078B11834E74CC0B9E5DB3AEF76E8EF2BA9
-:107560004712DBD514FF96F6BFB1F661E7F5D81EDA
-:10757000F6E7DBE1ED652712DBFB2A9F77201FC7CB
-:10758000DA73F8AEF824B15DF2FA24C30B70657DAE
-:107590003D0EAEA9665342FD9CDA73E0CABA310EC5
-:1075A000AEABDC89EDFD2D83C3754DA9E973E19286
-:1075B000EDBE36E9C2DA25CFE3FA1AD31078E7ED4B
-:1075C0006F9C7361FDDE52F7F9ED6E5D993C4E8064
-:1075D000F8A551A75D9E09CF79F80AED459B95EC7A
-:1075E000DE647A7954E8A76A343CA0BF8BD2B4EA4F
-:1075F0004C785649BE137E86434F5C948D723D4F46
-:10760000F8D199F02BF4D4BBC9AF70B3680FFAA4CA
-:107610000DE545CF4EF82E8DC3156F3F65D6F37D32
-:10762000859D45899FA5BD94C1EC0ADF8F737B675B
-:10763000A87192FB5F97C1E19EBF722A7B1BF8F095
-:1076400029A3BD52C5FDD93685EC81F9D59A3E15E1
-:10765000E86372BB427EA5F977FEE687E88FB9F44E
-:10766000B8674F04DECF0F3ABC386C633FD3304E5F
-:1076700090AD5F56F63D78DE7F00EC1F515E86F4DC
-:1076800066D33CB8DFA84588A09F5386E6323BCA44
-:10769000CD6FDA34949BB5B3B53FD07CFF0156096A
-:1076A000B45BC0A7CE9EEE9C69C47847ED373C938F
-:1076B000D0EEA90D59347A9A996A8579D4823D869B
-:1076C000CF6C23532DF8B432333E2BD670FB2B6D89
-:1076D00092CF580BE3D7F6FEE4CFF8DD2235BC9FFE
-:1076E000DB93419A776DEF8B7F457B6D81E633A20B
-:1076F000BC18B3D3C86D52410FE34289659407F1BA
-:10770000E5B27062F9924389E5F771E1607D260B7D
-:107710003FD6817D2692DB4BDFB792FDB917141E51
-:10772000EE93038F9B487F4C5D6AA3F57AFFA475A7
-:107730003BFAF5F6BF6EA5F64B7E6AE1ED75A12723
-:10774000B01C782285F6D94B3343151900F72F3E2C
-:10775000D513BE715A06ECFF89D1DB3760FD25A138
-:107760000A8C8B3D751163FD58AF06C7E33C9FFA49
-:1077700027F75B477799823BA0DFF79FF9C913DFB3
-:10778000C57177E56528B03E97A15E8076931F347A
-:107790005B71BF31F9FDC786A3DC58BAD39430BF03
-:1077A0009D998A88AB79D290EE86F23B1E5BFF13DF
-:1077B000FABEF4C411A2BBBD86800EE37881F59CAD
-:1077C000CEF65AB89F74AFA53088EBF47426D73B39
-:1077D00097E976FCA811EDCB57B91D3254FFA5EE01
-:1077E000F9DDD583F81907EA61DC6258E733EF5910
-:1077F0006FD5008E519B13D7697430B1FC4B31AFFC
-:10780000792CEE7D31C2336CAD1BE1D9CE089ED20E
-:10781000136FDE5C8CF6B889DB21C9E31ECAE4F283
-:10782000E1D147A11F2E67F4DC0E078C015F2F15F5
-:10783000FCF00B85DBC1F0B7220FE87F291A10C3DB
-:1078400062EF9726C121FBFFAEC0D3C7E6B41DA8E7
-:10785000CF9D464EF727571FFA21C63165BB775695
-:107860006B5A759C5F79E1E665077360FDEB7BB24F
-:10787000689F29DFD7EF7ACE750BBC3FB553F5A2D1
-:10788000E95B7FD3233F988CED76E9430827D6A3A5
-:107890003FF354E8F9346CB7B0CB3101FD25F2FB6E
-:1078A000459BAFD4AAE3E4E917E527C9FFF5627F5A
-:1078B000FCF4A4FE697980EFA59B152F365B1AFABC
-:1078C000FAF5D7A2ADD3A5F7627CA342653EFD04CD
-:1078D000DABACFC6677DCF930773A1BE69DFC40A4A
-:1078E0009CD7069DEF9A71C82FDB0CE4074B5E1FF7
-:1078F000E6E4EB0CDF8775F0FD861B6C75181781CD
-:107900007EFBB07CA074871EFDF8692740BEF1F7AE
-:10791000477420334FF4DE351EF62C40C7B676E4AC
-:107920008FBDE8B8C0711ED7939E60613E8FC9C2FB
-:10793000FFBCF48F9D46159E274EAC49ABE4FC4737
-:10794000EB8442DD09F3AB7B701CF1EBA2CD89FC2B
-:1079500025DB4978170713EB93E9C2E394FE0A5637
-:107960001A4F5FC9ED3267048CC88FF52B419EC753
-:10797000F14DFDF10E23DA5DC9E3A005C9E4BAEAD1
-:10798000892E612C9CAF85CF174C5E33CCF724FE3B
-:107990008BFBCD15DCD72F51688A6CE945ACDA0337
-:1079A000F85C3A8BD5E053CAC3539342E3B1FD5E12
-:1079B00043E4911F911C4C257970CA1E4E43BF525F
-:1079C000AEF0EB9DF284D350CE9D11713BACC7F26B
-:1079D000925ED007C0D7EF7F6024BDD0127A2E0D03
-:1079E000D7EBD413169D0ED6E5FD9ECC2AF4079D49
-:1079F0000ABD9C86F33A19CAAC42BFDE50722259C6
-:107A0000BE497BE028FEF352C6AE746A9A13E51DA8
-:107A100006197240DF643697350FC2F7F23BA7B103
-:107A2000B90CF334A2DFB47951CE5EEBF4D0FB5A3B
-:107A300085F7877F18DFFBE850E60E5CFF43FB47C6
-:107A4000A6A39DF011F3A4A3DC9EEBF2F99CB09EDB
-:107A5000EEAA7E8AEBBBA7336F2B7CF3B6DE7BBB33
-:107A60001DF0761B03BD85CF72BF91FC2D6D5904AF
-:107A7000D77C958555A0D3F9A857C75399EC98F9A9
-:107A80005D4AB015E0B86D63E23C17769A62EB0B85
-:107A9000FF2D6620109181BAE2DA41FF8B517F02FF
-:107AA000FE9698593805FA5DF250E2774B5998E006
-:107AB000A97FEC33D36078FCB3C0E35C97B618F1D0
-:107AC000A8CC32135CDF7A5C21FDE6147EC6E8FDAB
-:107AD000E9418C872D15FA7A81693FC1D37467AD6E
-:107AE000761BD0CD9995F3B5DB3279CA08EDCB364C
-:107AF0002B44874BAB59B800E05BDAAB84C7A13DA0
-:107B0000F11A5F27D92FDBC6DBDD2CEC9D05801732
-:107B1000B41F263FA60452417E2E30C3560EE58880
-:107B2000981FD6A743B98E75D0BC1A5884E0588BDD
-:107B3000EBC8FD7904FF9F5FE3EB37B96EBB1E8195
-:107B40003AB4BF82E27F1F332FAD23D825CC927188
-:107B50002E9D20DEB5383CD5752596D94371E5615B
-:107B6000885728C7E1BB71F767266D103CDF3FA03F
-:107B70004F82A3678E63E7D8BD6F8975B8FFEB0BA3
-:107B800073500EDC8BF66BAEE86012CA4D26FD1A00
-:107B90006133F46FBD8425F839C0BEA2F283CE995B
-:107BA000D337E733B6C9E0A778C17CBDEF2086B6EE
-:107BB000FEE9F2FF04D777BE4E2B54491E682369B5
-:107BC000BFBB92AFC703139A47370FB2CF95F06F81
-:107BD0005242611DCA8367B87D905A1E35F8E3F89A
-:107BE0006CBF9073E9072207F3905E9E54C82FBFC5
-:107BF00045616D0AE0D90DCB82FA608B72F420EA00
-:107C00008F2D577B582BD497EF9EB9EC79DA2B5BED
-:107C100029AFA76177A5BEC146F3E7F66A4AF376B6
-:107C20001DD467DF5A3A01F904E67DEB2C787F50CA
-:107C3000F06D8E8DD3837B4DA07839FA650FF89661
-:107C40003D8FFC3DCE4AFEAF6C33FA7AE9D98E7691
-:107C5000A89BB528D8EEFE34DE7F964E7FEB4C2CE9
-:107C60004FE0E58C558AB68388F83EEA3FDBC46A6C
-:107C7000107E7C8FF63474A7F5507D90E69B3DB561
-:107C8000B90CFBCB1ECE9F4E63381FFB796560BDE0
-:107C9000FD3A94BB2B84FE5CB1BD2A1BE5E42BA707
-:107CA000CC2ACAC357DCD20E0CDBD00E6425A5BC8F
-:107CB000BDD0532BCAA66623FD3A0B13DB9D31685A
-:107CC000E997A0BC3FACA7B8CD9F6C5ABA03DA5D68
-:107CD00066E4F3485EC7A8D0AB4D9F282C18B7FFC9
-:107CE0006F9A7396ECECA64FD484F7A7569B593045
-:107CF0006EFF5F5F77601AB66B60FD6B91AE1A42E4
-:107D0000292C1847E79759071F57D277D3277A1698
-:107D100018745C63E2FB4F32592073B076AEC4F73F
-:107D2000308F84F29EBF0CCC03DFB3499134F487CB
-:107D3000CE40BD06E533415DC000F2E41503D757E0
-:107D4000A7ED91047D76DA13E1FA0CFD3D366E6FF6
-:107D5000CFC47556A369B35263E3C87AFC3E236E61
-:107D6000BEA7E7185998D6274A7020FE02A318DB51
-:107D7000DAFBA111F35CEA7BF713FE24DDC4E331E7
-:107D8000101F3F6AED0FEB80F7C7DCDFB961EC68CD
-:107D900058B20382CF039B36605CD8A5D725F07D0F
-:107DA0004AF9801C20B1733F46B3C81FFAC086EA67
-:107DB000FCB8B2683FF07D60F374AC2F1FCBBF9F5F
-:107DC00078FF9697D65032480797A36AB4D0971A8F
-:107DD000573627956D501E1757B627D53B93EADDCA
-:107DE00049E57CDEFE546AB850EF05E0EFEF9E8E69
-:107DF000F95CA772C27331FF6BA33E38BD1ACA0D7E
-:107E0000E55CCF36F62A5EF2E109FC357AB9FD670A
-:107E1000F3468C98779652DE7F10E544FD1EC5AE82
-:107E2000003FD8423D612AE3779EB8EF420A7D5772
-:107E30001F3A4ADF0DD97FA98EF87D43E931DE2E46
-:107E4000F42EE9F3756DCB28CE2EE3C87AE6D7F28F
-:107E500094581C59CACBD339DA73242FF72976E406
-:107E6000CF013AC57EE3FC37B2FD1BE37A7F8BE698
-:107E700042CA8A0F5BD02EFD63C3BB13D14E7B4336
-:107E8000E8854D4A70348EBB95F947A3DEFB66C387
-:107E900088FD3A68F79621D28DB1B2D5F73F49F8FF
-:107EA0007B2B355280F9742D59E1E9984FF75656DE
-:107EB000A41BF1F9FBACFDBCBE205280F97377DD49
-:107EC000FF3EAF1F11E9C6F2E359BFE7F5E3220514
-:107ED0007A3B6E758E4CAF86FA87ED83F3F5ED59DC
-:107EE0005C9E48F8869768CBB2D00EABE7FAA41B2D
-:107EF000F63666909B73979C7CFC61C0C3DCEFA454
-:107F0000903C7BF8D4F5D3B99D1DF0A915E887E521
-:107F10007FA4EF486EABB4FFCD411D97115B8FD4AA
-:107F2000C27E0FE9838B9A7BD06EC89E3B96F4C1CC
-:107F3000579DDA111C573EBF9F074F687F24CBCE59
-:107F4000E5B35E4771E9ECEFA6929D75AF85CF076B
-:107F5000F886D6D726D6E3EE2CAEBFEECEE2FBB740
-:107F600045CE2BA9BF9B855DDCB93EB8CB02F87F1F
-:107F70005DE6BBDCC7EDEC5BB6835C0139DEE9D0C6
-:107F800072509EDC22F2D7A4FCC0F71971FB8BCE95
-:107F90003228DB62FBC8CE995A8ED5894F970EE303
-:107FA0002F521E7516F3EFA45ECA6EE5E366DF3B43
-:107FB0007A07CE2345E57EA4057346EE6821FD3E93
-:107FC0008BE6CD342D4781FE8E2F1EA643FF925C9B
-:107FD0009FEA12ED61ACBF59F8E7E53AC9F53C22DA
-:107FE000E63D5F0FF601CCF3772E3FCD1FEC85F118
-:107FF000C28F45F6C2115CE3AC187E991A9988EFDE
-:10800000FF3FC2D34B5F069E1A5682BCD05D80BC38
-:1080100010F8DBA4840DD95C5ED0BE18DFA3DE7936
-:10802000CCE97F0BFB97E3CFFD6E03D98712AE94AB
-:108030003B9EAEB9919DCB67C9F6DB09B15ED2CE4E
-:10804000F44A7FA418E7ADD7CD147F78CB1822B9B6
-:10805000F916EC6B5A50BE88F879C57796BE82FB4C
-:108060003AD9EF752E9ED76791EBAEF87A16166364
-:108070003E090B98711E338DB4EE52EF763A787E3E
-:1080800048E79D79941F72864518F9352731928FFC
-:108090004007541FBDC945FC0FED03166CBFF82205
-:1080A0006A0F741120F9709395F6219D186FC6FA26
-:1080B0009B4A8398CF82FB5FA2B7C53A1A77107AA2
-:1080C000E17EE3513C5F42D28DAB95FB6798AA8D70
-:1080D0009F19A7E72F72713F514A79E4C9DFA37D49
-:1080E000BAD142F629EA588AED7464533FB0FE993A
-:1080F0002EBEBF273ABBED07A9222FCD5B81785D4D
-:1081000097CAE9B2CBC2E34E5D600F935C14F42BC7
-:10811000F3E2FCC2DE8BD4E9D2D05E28760DF80DF6
-:1081200034DCC793DF1BEAE74594A3B8FF9A17D066
-:10813000874DB89F6ABF528BC4ED47F00FE376B707
-:108140000AB9CA3633F203DE8ADFA561FFD6348C62
-:1081500053DE8ADFA3DF75D59509F1B84B5C9CBF70
-:10816000257CC972FF120957C7035AFC38B2FFE4D5
-:10817000FE605F59EECA223C87D3717D5BF4B47E0A
-:10818000C970463673FF75647311D19DEC6F283842
-:10819000FF4B1FFDB6027A70E154BEDF96FB9805D7
-:1081A000623FCC5625EED3D05F3250D69F5B4EDE79
-:1081B000F7619C3DB13DB75B52C6468DC4B71E25E5
-:1081C000017E89AFA1F070F317C49BD47B0F588058
-:1081D0000F32703BAD10FD6EBE3385F498D3181C82
-:1081E0008D74B5C0E5A1765B31DF85F42ADFFF7EB3
-:1081F000FC8AF45F24EE7B9BACD16D88AF262B23E9
-:108200007E3ABD2F95F8879544E662BED899BD2683
-:1082100086F4DBA84446A2DC3AAD68B5D4AE25C5E9
-:10822000837C24FD036F3FC5FD034D884980AF2942
-:10823000F077CA576ADA93B81F3E0DFFD501DD9F6C
-:10824000D6452AB03F290FC08ED6C83EAAE3719CFE
-:10825000461D0BE03EEB32DDBCC59CCF73D90E7AD8
-:108260007F74E4F2383B1DDAF529199C7C906FEAA3
-:10827000051E1B75C7A85D3DE61D213E71BF85FE2D
-:108280002EAC8CF3CF366E7C9FF29E1A7727AE779A
-:108290007D8C1E94CF14FC2E8E3E889F03421E3090
-:1082A000EEB7A8E671E854514EA9E9A73CA826E12B
-:1082B000C7C83A1099867225B53CC4E6C1B3E90433
-:1082C000B73726F76E7F0EF7C78E9AFE02648326B5
-:1082D000E1EF93EB2DE1BCB4F73EF25B483B256E3A
-:1082E000DF397A5682FF600D7D87FB581C2F82AFE5
-:1082F00072900CB87EDB24F41BE84192B70B3A462F
-:10830000911E443D85F249EE83515EA19CF8A7ABD6
-:10831000AA07F9755376D563AE2C3E1ED9F5B8A9D8
-:10832000BA74683F9DC48F6C87FBE1CFF3C3F5221D
-:10833000DD66C5FCE3045139E64D6749BF1BC5E75F
-:10834000962B9E6CA4DB77F47EF2AF2D6201F2F7E0
-:108350002C46BF163CEB05BF2F147EA285C23F847E
-:108360007EDBF83822FA4FE3CB4B583F971B3B4D4F
-:10837000B1FC1AF4E754B3702AF4D780FE267C8649
-:1083800012BF6B6451FAAE69CF67A6843865279F28
-:10839000F7AD62FD1DD5413DCA892D16EE6792F2FB
-:1083A00063F22AEE8F4A9FA015DF8574FEA281FC3E
-:1083B00014FF2DD66D40CFBBAA9E42BD62D5F3F30C
-:1083C00068D1BB4C24378F833EEE11FE9159B80F14
-:1083D0005DCD34CC5F67AABD307E9F2A9F1BF65AC5
-:1083E000EA907EDE75E912E8EB472E9ECF437E23AE
-:1083F00092CB29A477417C8C47FAAA1826F5221B38
-:108400008FFEAAA362DFDC7883CD8FFD45745CDE2E
-:10841000FCC9C5F7017F72F17C4E591ED8E709FAF5
-:1084200091F13FF4DFC4FBCFFF3ED0FE3E9177CB0E
-:1084300068BE9B168BFCEE013AD6915C4A19EB2381
-:10844000F97B99AE8AE452F43D9B07F152F37EFD2D
-:10845000629CC74773AC748EEF36E1CF4DC976503E
-:10846000BFD27F7BBEB858CD86D1242F65FB34DCCC
-:10847000A0649DEB07DE2BE4D85EC6E10D9CB0F254
-:108480007C13950550AEED0D8D0E22BCB5C2FF805C
-:10849000F60DCAD7E8937C1D99CAEDA1BDBDE38254
-:1084A00048EF470DFE2D0BD09FD36320FF1A538357
-:1084B000BB1EC17E9ECDF162FECF695D74DBAFA0B5
-:1084C000DDDE138FE661BC67AFF0BBD71BC323C9EA
-:1084D0006E16F98EF569E191E807FA8558AF7A2BA7
-:1084E00094E17DAAC53F2A3B2B1617C3EFF0FDB1DF
-:1084F00020B7CB8F314E07818D3CEE09F8CD5980E6
-:10850000F0AECFA6B81AAE0BAEC3DBFBC6D1BC36FD
-:108510001944FB67146AAFCC2A9D4B7A61832913F7
-:10852000F17FC667A47CDDA67BB9DD385FE7D9B6ED
-:108530001265E5B32934BF059D8729DED1F4834553
-:10854000740EB269C9AAEBD8E7C40150AFC4FBAF3F
-:108550004FB36821ED87EB8685C200C7E9DED15EA7
-:108560001EC6E3E76A1A455EE87103D310EEE83EE3
-:108570004370B0F37E43F58FF3C5FD29EA37F273FC
-:10858000C7C75B481F24C65FCE573E6D888CBC139F
-:10859000C65F9BE9BF293BCE5E6C7A3687E4DDDBA4
-:1085A000F7FCA590EC8A0E1E2F386ED0E6229F387D
-:1085B000AAC3C6797176D8B26C6E97CE3709FB1113
-:1085C000E4603CDFCBFA8AAA443E93CFE66C6E8728
-:1085D000A48AFC8073EB65FED9F526D49FDCB584B4
-:1085E000FD72795D24E26E934F44F7639E557DA83A
-:1085F0008CE27A45ABC2C49780EF30DAFFC7B7A4EC
-:10860000727902D3C47E164E6264BF2ED4F37C8787
-:108610008526B087B91EA7F6EF6CC9263C54ACE19D
-:108620007660F44985E4A28C3FD632FEFDD36D47D7
-:10863000037A685FBB532903D1CA6ADB2A291F6208
-:10864000495731ADFF64217FE79BB4915B90DE9E7B
-:10865000E6F12B188FECEE7ACCF99A4072C988FAC1
-:10866000B06EA7C2F0DCB09C7F72BC8F0513E32D07
-:1086700093435C7EA3DE6071F69AD443A82F589290
-:108680001D9948178104BDD78D789D1893FF84B13B
-:10869000CFD183604F6F43FAA9A8E2FC17ED5108D0
-:1086A000CF0DAC99C787841E1A8047E8B177F45C78
-:1086B0006F2E34DD47CF9FE321B02CD48311AE075A
-:1086C00041AFA15C1C8A2E7E3E045D487AD82DE81D
-:1086D000A3FE040B5F0EE3D5AF62E186F1FC993A8D
-:1086E0009EF432D7CF66AE9FF169BD003D9DAC9F31
-:1086F00093F571B21ECE36727D2BE920DE4F8FF6D8
-:10870000C8E455413DF7C3E6DB31CF4FAECB22A7DE
-:10871000D6979715B3B79A8E98CD9E8BB1EC63C35D
-:108720006CE85FAAF415A0FF5CE5E78D53004FDB12
-:1087300071FD847D7E79015F47B7C8E731A83E5659
-:1087400066C375EAA7FD74348B517EB6C46F772A71
-:108750007C3701BFE3FC38F0BD99B559E3BEAFDA11
-:108760006B21FD72F699543A57C6547F9103FA7300
-:10877000BD01763A944FEF4D25FD7E5AC87BA7F494
-:108780005BB0B5B41EEFE23A4F44AAABCA43FF2F29
-:1087900053A6E7313A6FCDEDC606C7507E7B515FD9
-:1087A000DC7F03A73313E9D9B38EC8ED58067828C8
-:1087B0005FF8BF04FD36ED9E5AF65D8CF3FB6C5EF0
-:1087C0008E557F19DA0D26FD8A1BCC7A3C77BF2A9D
-:1087D0007A27CCA3A1C04679C8D5456FFEEE2628DE
-:1087E000BFB7DB40E715173F7C7D7A183F5335F75D
-:1087F00060FA7971D090700E6EE9CEC4724328B1E0
-:10880000DC9474EE7DE59BDB5FEA8BAB37BB539D5D
-:10881000B4FE1EE6C53C6AA6FF46BA7F1079299FC2
-:108820007F591D7CA96F04E5A1A5BB797E8D11ED53
-:108830009A79480F837C77309BDB352653F309CC3C
-:108840006737FDC244E7E3DFC8F6BBDDE85FD64526
-:108850000FE27A9A8A4E8D473D5855F40F8A8B9DC8
-:10886000FD1EF3227ECE5A2AC9BE39BBC5E2C1FD28
-:108870005967A18DE8A0F35925A870FB7DC6C40AED
-:108880008C83D21C58D3E6ABDFE3872F98999FA740
-:1088900087DD8B1BE58C46FBA977665AED6BE0BB49
-:1088A000BACD5CDFD6B3FE349403DF748BF5D33FCF
-:1088B0006634C33F8BDBB4D12D00EF529F95CEDDE4
-:1088C000A89FAA74DE7C1D761967FF97BBB93C6828
-:1088D00030478C9538FE3F56D4A06B4CFAB94C0605
-:1088E000BF86E7BB0C7BCAC279F06AD1CAE7689F32
-:1088F00033104FDEC7E5D6A23BF7D37B65560DCDCF
-:10890000F71D982FE2E5B92D269AEF3B0536DA6779
-:10891000BED3CDF7BF8BECC6A099EC8D4F32F15C86
-:10892000EC3BDD063A8F7E2E3EAEA2F3A9EF76BD7C
-:10893000407EB877191F37B05B4FF6CABBF6684563
-:1089400018F1E8694E437BB76EF3623ADFBAA85B71
-:10895000EF4379B6A8FBDBBFBA14FD47B36E2EC751
-:10896000295DE158E1F2D862F5D24E5533263D82B9
-:108970007C78C5A753FBAF407BA91BF8A498E7CF31
-:10898000A39DDED77D15D9A58B665A1D382F4FD7ED
-:10899000C3D3507FBC3B3397CEE32E7A5C6178051E
-:1089A000C322C74A17BE5FA4A8BEC1E8E9E36C3D75
-:1089B000E1B5B2C8E60DE377BFD5139D005FDD805A
-:1089C000FAB3A1DB40766FDFACD77F779333C6571E
-:1089D000CAACCDD74DC6F63F3150FB017BA7EB5A51
-:1089E000492F2C5C81FB2A8EB7643E3315AD1A8962
-:1089F0007025F3DBA235CD2379FCEA8BF11DEBE288
-:108A0000E773EF70F3FB23BE00DF7DFF8BF01DCB20
-:108A1000CF48D84F9D2BDF02D44EFAFFCD5EA63D46
-:108A20006CA378AFA680FCFD0906AC27E2939F3BC0
-:108A300052FFBA7CE7AB809F316E7F07F26F11D394
-:108A4000CA506F7AA2F62A3C536413F61CEB32C963
-:108A50007D00D9F79BB2D8231BE2FC0F0FBAF93E79
-:108A600009E4C016ECE7F41FFE7110D7A9B1F0D4E9
-:108A700078F4FB367DF2278A17DA7A79BCD9E68D4D
-:108A8000523CDDE0F4111D4AF9DEE4E5FA27795E97
-:108A900027DD061EE77546A99F17723C54EE14F1B8
-:108AA00095AD2BADE44FDDEA0C5AB87F21C0503FA5
-:108AB000CD98A4E77132616F5D2BFC91E6F2E71867
-:108AC000C6C7D8149EDFF56AF9736A26947F35E924
-:108AD0004A2F9DCB2B7FB07D18CE7B8A41D40FA728
-:108AE0007B33FE8F5649F5CBDD7A0FF2F78C729E01
-:108AF000DFC8EAD2C86FF26AF9DBCEDBE2E0F73119
-:108B0000B3C70674330B98353E9FEEBA29168F2DE6
-:108B10008E7E3EEA506AB8DDEB499F3D8EFB4548AC
-:108B20001F9727E263B9DB48E36ECAAEEC43BAB9DC
-:108B3000E2AB7C3D4E3E6E0AA21C3C29CEB924E33A
-:108B4000EF376EE1A7534727C4ED9DC65021EAC910
-:108B5000F795C4EF96B4EB296EBEB85D614118EF8E
-:108B6000E4AEA70B519EBFF7F0D385F3E2E049FED8
-:108B70004E3EFFE816F42AFC82C97EDEA1FCBBB2A1
-:108B8000DD99CDCC6F1E1E6B7FA6EE6FE4DF9DD707
-:108B90002BFCC39A56E2C4FD90689FDC9F3997D3A3
-:108BA00087B24721BF87F46F1E3BF420465206D69A
-:108BB000CFD25BAC8BCF4B94CFC962DDAEC7758390
-:108BC000A958DA7979A8F51A8A1F77083D24D7EDD4
-:108BD00058FBF074C4A3B1D1A6327EDEAC14EDF51F
-:108BE0006E66F5223FFD45E4A73AADF0043BCD9813
-:108BF000EBB6A13C93E7FBEFB0A6EDC0E75F44FE08
-:108C0000AAD30A4FE8A720B794FAFB8BCE47FBBA4A
-:108C10003BF41D740E3145F049360B2B0A8636960F
-:108C20003EA550FE567B22BE5DAD5C8F446B8DA48D
-:108C3000BF24DE2F9B773BED5F0759AFCD4847B987
-:108C400093F8BBEA9C62E1EF88501CC13289D9716C
-:108C50007FDF7A6980E090EBD5C49B33A55721FB79
-:108C600019F3585232285E1A104F66CB6003F18315
-:108C700014B1DF6549F1826CB0BBB19D8413CA9415
-:108C80000F73AF23D43192C75BC92EC57EF1FDBCF3
-:108C9000B12AF9DBB19D71C2F9E96F804E457EE1E1
-:108CA0000CF9BECE3A687C62069EF3C17500FD8861
-:108CB0007621F31A12CEF974813D8DFB3419FFD55C
-:108CC000EB42656EDA9FF447D07F62AC307B50DFB9
-:108CD000A6E843A5B87EC9F1606857CCF310F21D31
-:108CE000A867E4399EC695537D18A702FB2360C68A
-:108CF000F59BC9D7AFF1CE4A7AAFCC2A6D41FA6A5B
-:108D00005AC5E8BE81A9BD3D94EFD454C3EDB1A6C8
-:108D10003D478D0CE8779EF0E730E17F7689753D21
-:108D200026ECEF58BC2BB20DF3B73B17E7D3B9DDF8
-:108D3000E4BC922F1AEF3C930A08B9382E8E956E38
-:108D4000E67A46ACBFE46F19D74A1DEB2B464BFCC5
-:108D5000C507DE7BD99AF545F2469EBDE773F3461B
-:108D6000D8F4EBB0DE8C56BEA84730408F0E9CCBBB
-:108D7000B37828EE35508FF72998F72822EFE4ECE6
-:108D8000B5579650DEA8E8AF6F23E67FDF6B610929
-:108D9000E3C5C3A726F56F80FE6D1ED9FEF83557D3
-:108DA000AA14FF15F04FDD88E7FAEE3524F64724C4
-:108DB00028CF119A63E3F9BA7E70CFC6FC983E07BC
-:108DC000FDBE3167624CAFAF7B7D46C7C51EE4AFC9
-:108DD0008F290F57EAE72627CF234996630FE470C0
-:108DE000790E76F13454B9EBE62CA3FB0706E2BF0B
-:108DF000BDB51ADAC332FEDBB4CA47F9B8600FFC5E
-:108E00002887EC8153EFEC6768779EA47D41D327D8
-:108E10002AF713815D81F7C9987B2BC91F8A69A640
-:108E200023E2D67F89D05368C3233F3475DDF8B081
-:108E30001EEA3FCED11EA27E0D83DF27B52F87DB32
-:108E4000F14DA5555B501EB08714BACF6943E94771
-:108E50006477343E73E5C4F87CF2C57BEEE7F9C86D
-:108E60003B0D83CE7F5F0E8F0B373EF324F93B4FD4
-:108E700006F931983A35B81EEDD0BA3A1D5A5EACB3
-:108E80003C587B13D90373601E30AF0773387E9A4A
-:108E9000765E1FC0FCF626F84F81575B7D0B695F3D
-:108EA000B0758ED986719CA6D279CB88FEED560D11
-:108EB000E79F0C672CCE6CA573C81BF6186AD08E82
-:108EC000AA00BBE9E7006F41C6F41A2FC8A53C7D94
-:108ED0004FD9B76C18771F5C2FDF92C7ED8036C56E
-:108EE00017F85A39F939597C1E4FD11E6E9FBD961D
-:108EF000C3ED43F9FEB51C6E374E09F44F459A7B1E
-:108F0000568DA4A09DDCC4B40F71FFCB7C360FF945
-:108F100077198FB33B577BC8BF6B7646EEBE98EC94
-:108F20002895E2CC727F71FA19EE17BB22D77F1415
-:108F3000D7B1421FF9E1D7106F77ABC24FCCE54CE8
-:108F4000E1F5B609E8C7B238233FACF150FE0DF9A0
-:108F500025D22F6FA37578D6C9EC889FA9815A5561
-:108F600089D333526E4C1D3887E324FF6915176B84
-:108F70006C04ACD63B6622D1B6CF326376C2A17FF9
-:108F8000CC56F1A5B41F74663FED73AAE7C0BE11BD
-:108F9000E9726DF4A00EFDF5CE7EB21F1B420A8D64
-:108FA000D350FA33CA8F5B2AF2B006F2A1D408E597
-:108FB00087FD3D2745E8C7364E0FAC9FF6C5EC311F
-:108FC0008E7FD09B943716B3E35BF8BD67A23FA3B7
-:108FD000883334083F0E208AEA8DB9C2AE137E8DE5
-:108FE000589E1B1F97A99E8A78BFC3A699A04908BF
-:108FF0002E4F1AC2DB6EF5A5E7025CC7EA7484A2A5
-:1090000063ED2974BFD426A55F437F64A08CE7C5B8
-:1090100026D351891837FD40741AEA93E83343E5A3
-:10902000C5F23CD82D132FA27CF2F23D1F4E43FA1D
-:1090300060358CF8B171CF85E5C58E16EBF1A5E7EB
-:10904000C57A156D073C2FC97524E6C57A39DE65EA
-:109050007C32391FF6744E58E5796B916D0FE3FE43
-:109060007B8F89F23D66EC79E108FA276798598889
-:10907000E2B54976C061E7F55310DF673E7867DBFC
-:109080005D0CF3A29FF2F27392897A7D28BB9E62F7
-:109090001671FBBFEBE4FA7F4976BD94BB4D629F2E
-:1090A000F4BE12FDC1489CDF3EBD7DB0732DB7E418
-:1090B000CA38D710F91CBD83E773C8735F3591E2D6
-:1090C00084F8D382017AFE62F1AC3AD48113CF8D59
-:1090D00067A9223F4B55B808600E9EBF23E3596A2B
-:1090E000CF688A539962F1AC301B249EA58AF8D0D0
-:1090F0003A83564BFE967D260FDF0FFB480EB5F5E3
-:109100006479514E352D39F9041ECD571DD3DCA895
-:10911000FFDB04FEEB2F3C9ED5923BF1DC78D6764C
-:10912000617FBD5DAA0B1B01AFDB1997A3815E199F
-:10913000D7D2D1FE347A4F01C1ADCC3213DC6F3FB0
-:109140006BDA817EA6F9325EF52CF793CD1771A903
-:10915000B7678D243FD250789EDF9EE8F7FF21E26B
-:10916000398BFC78E46FBFFD3F66929F7D21FAE961
-:1091700087C7CE2F30E1AFF3B4F3F3ED9E9D0ADD48
-:109180002F8A64A223DBD24EF78C2E0571B81545C9
-:109190006800A8E62BF05AD12968D778DAA00CC667
-:1091A000BBBA5E0DB8A1DDF62329E41F5CE7F488A5
-:1091B000FC331E3F0E6C54822378BF74AF58A04D11
-:1091C000A7613F3FCFE57EA59773B95FC293741F38
-:1091D000419B41C481C5782D0CD61D9E3A853FD751
-:1091E000897BEB92F121FB6B33349BD14F172DE040
-:1091F000F7939C356A73C87F9C3192EE216A4B6D60
-:109200006EAFE1F5C4B3672D511FD55FAE72C39247
-:10921000793210DE5DB922EF2E09CF0B3A12CBC99D
-:10922000F19BE47353F3997F54CEF073CF15ED4265
-:10923000B909FD9FDD502CD6C54BF1903683E7D799
-:10924000C51407E5F70CB5E473BCE90AF87398A3F5
-:109250009AEE8B037EE1F618E3F00FBBDCA920BF8A
-:10926000B43938DDFEBB7027C3FB9BDC91445F6DD6
-:109270000ECEAF6DEB9520C71787FB42FD1D1F4A31
-:10928000B9F425C9C5B715EF23E162FA8EE443E0CE
-:109290001E03F1DD5E0B3F0F29E51525E8E03E5288
-:1092A000EC5BFF2EF4D6FC136BE9BEA0AD75C3D208
-:1092B00030EE39F57A1BCDA3F1597EDEB66155A4A7
-:1092C00010E9BAB12A32B27910BCE200AA94AFD048
-:1092D0006E9E93F17B67DA13E378C9F1D9B5999A59
-:1092E00005E33FF7EBDEEE7901D7BBC7427AB271F7
-:1092F00055F411F403DC9CE9B7E7017D9CBAF3F562
-:10930000698A873E23BBFCCCBE51744E705E5BE223
-:10931000B92BB631313EC8DA33F8F9B2CEC4F7789A
-:10932000BE28E1BB73E285DC4ED964F48F463BF284
-:109330008AAFF27C880F16EB18AEEB0716BEFE81E3
-:109340007B5285BCF68E8CD707E3F2865A5F68376E
-:1093500016E3F23C0F54B66FC0F58575AD17EBFB05
-:10936000C1935F1989EB7BAAE72B23717D37193AEB
-:1093700034E48F7FBAFC6588AFE357FAC8CE93799F
-:10938000AF174A775ADEFFAE3EBE56E2E50BEA6300
-:10939000FC8BF77F3CFB0F7DC042FA859F338DF934
-:1093A000E14ED27D5B673ED129288F87EAEFBF85EA
-:1093B000DFC96D6601F477545445E8BB8ABFE918EC
-:1093C000DA75D29E4D86DF2FE05F96A7BD9C83F3B2
-:1093D000107EDB3AD1B739F831B79B1F52C82F6BDB
-:1093E000F604D226D33E69C1257A922F3FA7730F88
-:1093F000AC57B1E37E63F1432D547F7ACF7CAAD77B
-:1094000099C361DC5735403D96D74D49CC6336EE64
-:10941000E6711DB98F05385E4038529C5123D267E2
-:1094200023DAC90062A3CAFDD78D4EE60D30B46BB6
-:1094300013F77D323EBBD5C7EF73D9DAABD0BD4E43
-:109440002EA3BF381FD735294EFBFD3CAD3B2F2E39
-:109450005E3ED7A505B0EC34B242C4D3BA3C8ECF41
-:1094600088419EBF4A3C0F7868FF0D640FFD99F953
-:10947000D207CF2B0B26C4D1178A739B0BC5B94DCE
-:1094800094D3E124391D5FAE8FCB2B0B0F961F10A9
-:10949000975716FF5D7C5E5938419E7588730CCBDB
-:1094A000297EDD0474BE72428C0EEB99F8DB1C7DC4
-:1094B0009BCEB1EC34917FAC5EE49536D51DA37D97
-:1094C00047139E8BE1FCA8F173D1DC1EAA87FD1C1B
-:1094D000E5D78612F34F770F2937FEDFF8C17F29D2
-:1094E000E581E047392F398FFA5E85F34F129CC929
-:1094F000FBD8647FB6DC875EB0FFFF7F592E4592B4
-:10950000F0F0AFCAA573E20225D134EF97101778B7
-:10951000CFD3E142D7A0CC036EDFC7F380A7E96DBC
-:109520001A8F43EA799E42723CD6338DE28D32FE29
-:109530006B7E4A1F5C534CEDBD98BFD5B02F95F2A2
-:1095400006EA3C75647727C72197B09E69B8147FF7
-:1095500066AFD039AC7F3BFE9F2FEE09F6B0E22F0D
-:109560001AFFCFE7FBAE0B8A433E67FB38D31F479A
-:109570002F5563C1801F3B747E56413E5FFF14919F
-:1095800027625603CC11F7FD50DF8DC8E7795FCF16
-:1095900089BCA27B5353E81CBEDBC8CF1DB8753C09
-:1095A000FFE9E31CDF2884DFECE1EBF9E3676E649D
-:1095B000788EECC786109D8B0F34D8BCA8C7A4FF4B
-:1095C00048F6DF9EC3E1BA503E9A92FFE5F2D1F928
-:1095D000E4C7B47CE58BC5D136030EE2F82B991FA6
-:1095E00086FA6E28F97263BE6F16A70B6D3CC51F15
-:1095F0002E502EA59483DC463DBDDBE4C1FD03FA6D
-:1096000051483F6ECC91FB6F7E4FC0BD05A4BF3E5D
-:10961000B0F0FD843CC73380BF21F1FDAFD979BFE5
-:1096200073F9EAF3D1BEABD4E81CC0BA54AE5FA262
-:10963000BB781E50F2799664BD22CF63C8F1BEFF9D
-:1096400025D3C31795AB77CBF1FF4DB90A7A96F6C0
-:109650002F43C65BCFF93E20F231FB3591F742E74D
-:109660001A245C4DFD3C7FEE47827EE5FBEF09FD51
-:109670001BC9D7BA90AE4EFDC16CC67866793997D2
-:109680009F8D3E1BC5031A433C4FA67115A37DBF9A
-:109690003CB73AC6ED7F04D76FDDEB36BA87B471BD
-:1096A000CFF6F6619447E027FBEEF41FF8FB37B2E4
-:1096B000FD8F62BBA6559184B843C5671FAFAD2926
-:1096C000277869DFEE34259E077A259FEFC7E5F3FB
-:1096D000C501FCC2FE04BE3B55C7F3B59B9C9ABDB9
-:1096E00092F207B85F3BC5D34F7EA0C6DDA4241815
-:1096F000258F62FD77F3896E1A775796D17D002109
-:109700004B19DD27F306BF7FE9D49DB9413DF783AF
-:10971000EF477853CB8357A39D5904E3A0497AAA16
-:10972000E7EA32F20F26F19DE4B78173A0B7988380
-:10973000AD4A8C1F3719B89E94FAAD27DFC3FDCE12
-:109740004E9107D83B932DB0C5CA3667627EE4B20E
-:10975000BC2B7B707D7AF25511BFE6F1F26233ECDF
-:109760003E879D4B87C5225E3E53E439B0803996D3
-:10977000DF30ECFCF172099F2CCB7879CA27E2BE6E
-:109780007FBB91E822B59DCB0D06748176F6946877
-:10979000FF543C7F55D2199E82F84A47F453BE6964
-:1097A000E4EE8B310E91A94EC138C4B695130E600C
-:1097B0007C545DDF7F392E8DA7C35E855BCC316E17
-:1097C000DFE97CB2079B4B91FEAB7E6BE07989EBC6
-:1097D0005348DF7716D6535EE2E9D74D09E76D921D
-:1097E0009F01B6C68D7EA361EDBFA13840EA6E65CC
-:1097F000D07CD371053691B7B8C68D7EA8D4F6FE5D
-:10980000C024F4ABDCA3F0BB1C017AC58DFB7F55F3
-:109810008776C7FC3DFCFCF6FC0E479599E4A9C28F
-:10982000E328539C2427D5F5D7E8709FA6B630BA15
-:1098300037ADA480DF9B3AA2D3AEC375FFE5A7FA8C
-:1098400041E3639905B13C37445783297AD05D1CC5
-:109850008BEBC9FCB6A1EE2397FA28D99E3DC78EA3
-:1098600015FA68C09E4FA2E3A1BE93F42DE9F997C3
-:10987000064676D82F15339DEB9274DD26F3F53F1F
-:10988000E57EDD229137736CC3DFC7F373EB322EB5
-:1098900012E4F7711A226BF3085F91AF0670DEBB1A
-:1098A0001DBAC6B1E40F6BA47ED6F3FBCE8ADA876D
-:1098B000AF99548E4F3B530084637B9716215F060C
-:1098C000800E460C42071FE5F37327EAFA145A3755
-:1098D000F53EBAE999A90E17AD9B7A3F5F9F53F900
-:1098E0007C3E322E2BFD96917C7F55C1C4B87358B7
-:1098F0002BADFC1C9638E79BBAF2F5C7F17CD3364A
-:10990000E13F3EF0EC18FA9D86B3EB5505EDD4B37C
-:109910008E5AFA5DA26B0BB8BD94AAF633BB2D9E8E
-:109920003E0F507EECB07D3CCF4F15E798D5F5CE7D
-:10993000ED88CFAF3AFD94077C795B987ECAE059F9
-:10994000FB718AB7815D44E7554F3EA348BB284170
-:109950001FCA7D5BF27EACB6E07FD64EAA2F48F4DC
-:109960007B5CF03E8B25EE3707DACBFD63F27E227F
-:10997000E9FBA1EC1FA60512F25D568B3C68A9DF3E
-:1099800073856C94793003E79659D082E71EF29183
-:109990002927C6F28198C813DAAC58BD682F0D95F7
-:1099A0000F3490AFC39A2FE6FEC8E6AFE053E6133C
-:1099B000C97C210BE68D649E9B3762C1BC914CFC37
-:1099C0003D0B7EFE59E67DB41A3C944712F81EA367
-:1099D00078A032AB86FC75193E23D1DF1916DC82E4
-:1099E000F7B90766DBE89C379E0B42BA8F2A6EEA0E
-:1099F000776A8D26DBEBB0FDC0BD80B58CEA334ABB
-:109A0000B41CB4C32C508FF7150F9C7B5EC0EF4F76
-:109A10004FCE1B91F94B329E9B3BEA2905FDA2E8F4
-:109A2000F6A73C826F89EF8A793F9DDFF490DC7066
-:109A3000B5F2FCA4E8A5CC8E7EF92A297FCC89EB6F
-:109A4000BA49F117237F6EB2F273FFDDCCDBAE872C
-:109A5000F21D05C3B85F8779F6EB486077D0EF2F2A
-:109A6000743AB5A70AB262F424E1629BF9BCCFE074
-:109A7000392F2536DE99C57F2B44FBAAAAD7C4E926
-:109A80003269FCAD03F7AE042DA84F5E2E6044672B
-:109A9000DE247B573E5F96FC26E4B21C7FA8F94982
-:109AA000FA3C9F1D2FE96F287A0B5489757A2B8514
-:109AB000EC0F496F0756EFA47B01FB5687E879C688
-:109AC000A284F4783ED6129D8B92B17FDB9FAEC309
-:109AD0007B39CEA4460BF15E8F377FFCD7AFE1BD5B
-:109AE0001D67B2A26F61F954E1381FD58F886EC32C
-:109AF0007B3E743FEEE1F5B89EB960BF173CF2B50E
-:109B0000808DEEC95ADB8F7AAB3C291F25E93E8256
-:109B100014F17B3ED93623D993D922AEC7AA855DED
-:109B2000CFF8EFA2B5E694511CCFC63CBBFBB13ECB
-:109B3000DFC4EF2D6040FF583FA298E735303E6FFD
-:109B4000962FFCD32C12A0DFE72B76D0F703727C84
-:109B5000B749C4A7F8F8879FE47144999FCB98BD93
-:109B600000ED219B872594E57D1E4CB517E0F9FD9E
-:109B700056E9F713E52753FCC6C238BD7CF8CA3B4B
-:109B8000C6D2EF843CF5DD12949B571913EF59961A
-:109B9000CFE78B389D9C11F70936A5F8D30B61DD13
-:109BA0008FA4CC9D8657C3CEC9AC343AC87EDBA502
-:109BB00047399525E8C3319BC3E7A8F629F8FB1C74
-:109BC000F23EBF2CBF4A7E02E6EFD4A35ECD3AEE52
-:109BD000A3BCBF7A73B4107F47E505B33F0FE13CE8
-:109BE0005B7BF4768A17E61E7E0BF3340E1B3AA6D7
-:109BF000A6A11E2916F742604016CA07F38A683FDD
-:109C000038201F462814CF9C319B9F5F9DCE422A4F
-:109C1000AEF3343B3F4F35ADBCD8DB0AE3CD107912
-:109C20001ED38EF8D250BE4DBB31A2F27B2BA26A5E
-:109C30007C5E857C32B7C113CF0F577BE2CA0CEF35
-:109C40001D4E2C5FEB4D2C7F6DD2A7A3E2CBE3140E
-:109C5000AD02E7F90B45DCFF00F285CF8BE70F3E45
-:109C60002AF67363DCCC5C84F98D4E2580FB85314C
-:109C70004FE7529CE5E9498CCAAE9DE61DE6F8F92E
-:109C8000DFA7E37168E10797BF338475A86F9FFA78
-:109C9000838BF0E5B281BC7592F4217A3B20F8F613
-:109CA00080E0D38A3CB315E5FF0183A78BE83CD560
-:109CB000EC413FD5FE5423DDE3DABA8CFF4E8192AE
-:109CC000666646E8573F8F97A11DD80650AE3053C1
-:109CD0005EC801916FDDFA3D95FC5C588FF7EBEAA9
-:109CE0007F6025FF76755AE937B05E9F66A4F30E54
-:109CF000FB532BFC623CBA5FFEA15473187FEF202C
-:109D0000F93ECDC30817E20DE07A98C341FCA8AF35
-:109D100030921D2ECF9F433F147FD3E79A69BC0337
-:109D20000EFB7EA4BBD6F7C8D283FA491ECCE392C1
-:109D3000F45D9D36897E3F04B8AF24FEBE74BDCB72
-:109D4000EBE1E766F9EF62940EFC4E060C0BEDF0CA
-:109D5000378518F12D8FE71548BC3355C3F6394CBC
-:109D600096F9B931D740B952A5FB7F14596EA1F2CB
-:109D700003A25EDEFF79A890CB29A5F785BF22DD7F
-:109D800096A4015E609DBC29839F5B7AA090F3ED51
-:109D9000B9EB57E146BFBF82F31C1B9BFF0187D77E
-:109DA000ED8B2B0FB22E41A4B7E4753960F17AD058
-:109DB000CF76FEFE385EE53CF4B91C9F03F3C81C69
-:109DC0007C1E87C43C42E29C7572FDEE426EBF7EF3
-:109DD00089F31C94FEFEE579BA12E7F925C2195100
-:109DE000BE0438F585009F2D061FFD0C5805CA4D91
-:109DF0004E7FD3459E322B4DCC4B6293BC666E2F6B
-:109E000026E6215DA574B5A17E7D40C4B95F107CB6
-:109E10007530E5FB25686FBD3077641FC9DBF496AC
-:109E200036642E299FA5FC3F9B73B402CBA007DEAE
-:109E3000443D73FBB0C373B1F33EC70325A8AF40E5
-:109E40006EFEB170E2B9704AFE1D8017F817F9482E
-:109E5000F26F32FC928FD875214ACCEC66617ABAE7
-:109E600019CF8307BB84EE2B679E82D8FC80C9A7DD
-:109E7000999BF93C5A0204F7558E1F52FEDF598F09
-:109E8000FF23846BCEC51FD27D48CC5D3B0AF5080D
-:109E9000C0FBF1FF26BC209F72F0BDB4F393EDFA36
-:109EA000F3E5834B3893E5A1844799B593ECF82605
-:109EB000B0E379BEB842F2BEA94EC7E5F01E85EC0C
-:109EC000FA46D033A8A7E4FDBA578CB4B6E1BD8FEB
-:109ED0007B0DDC9F1A78D2E449BC2729396F5CECF2
-:109EE000275631B95FE0F74134D8F93D4842CF7485
-:109EF0007E7B98BC2789EB43D05309F724D57A128F
-:109F0000EF491A62BF00FB02B2CF58BA4EEC0BB851
-:109F10009EEEBCD4630F30F23FF3DF7BBCC928EC6C
-:109F200041C0852B768F1BEC03E87EBAAF14158BEE
-:109F30007BB282FCF73584FD9FEC8FFEA7CB3FB947
-:109F400008E87DC158AD107FEA65BE91FB9B81DEBC
-:109F5000BAFA19A63F363F84F7955ECD9A5FD30DC6
-:109F6000277AD3B0FD9C311FF27B4C63F456599491
-:109F7000C5F5122A99F3F1F161A77F7AD144C45F44
-:109F8000E80DBCCF7C6BAF89F02DF34B93F93B0E02
-:109F90009EE3060E8F53AF2778660D06CF85D07DE2
-:109FA0003C5D65334EDF43D13F9EE3489D10A3FFE8
-:109FB000718ABF16C71DE083B57CDF750EDC7A1B86
-:109FC000ADF70D37F1B85C538ADC276B33725CE870
-:109FD00087E4E3DFB09ED3C50DB53C8F68666F03A1
-:109FE000C5E158358FAB79E17F08CF0121DF663BB2
-:109FF000CB0C487A7F66DF30A09F73F68CC4F8DB09
-:10A000001CF35514EFBB61B621E1F72A251EE68843
-:10A01000DFC39E93F43B95C978498EDB0DC80331AD
-:10A02000DF3CFCFD1678E6337E7E2647FCAE585BAF
-:10A03000D1C0F9DE515F30BE7777D11788EFF519BF
-:10A04000A2744FC3F3598BBA9601DF8CFAD158BA78
-:10A050007FFD4AD7E287EE83F24FB65E44E5E75DC7
-:10A06000B7AC388CF5DB4652B95AF7E15CE483D2E1
-:10A070008A9BA6E37DF57D16DE8FDBEAEFC4DF3138
-:10A08000718F1F3601F380AB8D516A77CDC50D9767
-:10A09000603E54B595975F29FBFD042A0F13E5092F
-:10A0A000BFB808CB7DCA8773078B0F8E2955C2F8BE
-:10A0B0007B65D519BCFD8C09BB72D15F545DC5CBE6
-:10A0C00063BC95EB8763BDEEA3B983D923CF140995
-:10A0D000BF91B0AF7D82DF9FD68EB6E179409F4DB4
-:10A0E000F1E2B90FDFA4A3FC7E3433CF2BF1696515
-:10A0F0002ADE9F59A5713FEF545B4B0ECAC5EBFC9E
-:10A10000C672F4E7DB6DC56D6817A74FAA9C88EB94
-:10A110003DD5CC889E80AFF6E13ACCF9CA878569F7
-:10A1200048CCB644BE92743B53F2537522DF803C58
-:10A13000788ECB83447E807E0F11BF5E96A8AF06DB
-:10A14000E47D12DF26D3E39076014B9483313A0D00
-:10A1500029F1F4D98DFCCAF9F70F088751D7EFC15F
-:10A16000F7458AF7224AB419C2BE90F0A1DB924D9E
-:10A1700038172EFC53A53DCE21B0DB5D382EAF87BE
-:10A18000EF34FC713909178CFF1EE1672D87A75B3F
-:10A190006916BF57C2F761D2DFD128E7BB2771BE6E
-:10A1A00015567E7F811BFD3D14C329BBE8F3E06E8D
-:10A1B00012FA77B6D9778F09E6F075C77C5AE71B94
-:10A1C00041033A60FEBB52FC7F4778F4BAC0BE88B8
-:10A1D00082BF37A2513E0CACE33FF83AF275917062
-:10A1E00025E3E3FF02863CEC3E0080000000000017
-:10A1F0001F8B080000000000000BE57D097C54D592
-:10A20000D5F87DF3664B324926098484409824644E
-:10A21000830426611164712004A3020E8B028AF864
-:10A22000C21AB20B5D624B9B81B0A9684345A5166B
-:10A23000754040B0408302A2463A2C2A56ADA94B45
-:10A24000EBD2F22548658718AAE2576BFFE79C7BA3
-:10A250006F66DE4B52A45FBFDFAFDFEF0FB597FB3A
-:10A26000EE7ECEB9E79EEDDEA9B43B02EA00C698C9
-:10A2700087F5ED16CF9802FF642EF8EF80E57C732A
-:10A2800016A33FFF4865ACB7096AC44279E3EB5FA8
-:10A290002B587F5583C2D218EBC59A12314D64D525
-:10A2A000944F60EE35AA8AAD7AC57CD69F31FCE723
-:10A2B0003F6E60AC2E12FED18DB1D63C9B7F330E2B
-:10A2C0006286FF0633F6567186FF7EC85FB238D6C7
-:10A2D00028D19057589619EAF99470F7D614C6BE4B
-:10A2E0000A8B1AC0E07BB7704807323662CE0F2661
-:10A2F000B1A88EF3ADB1F37A3F0C8FDA8CE90D196A
-:10A30000E12B4CD1D83ED98FF5BB85433A2038FF9D
-:10A31000AF4C4CB3C37C7FA8C23A545C47EB32339A
-:10A320008CF704ABA7FC68172C7A08633DDAD7E3F7
-:10A3300053BCB98C594DCADD5E07AC09FFDC104C2B
-:10A3400047BB4C8C752770290CE65529E1E85298DB
-:10A350001DF27344BE52C0BB9BD5D50BFB31C279F5
-:10A360008EDDD642F05D53E869B607BFB3FAC73C4D
-:10A37000A1FD74554F01B826C576843FCC9FE637C2
-:10A38000B1A6C07B320EC717F8B83792F031F1DEB4
-:10A3900031F45D9992A534C3BC0A8A5C94C60EFE62
-:10A3A000BD99E5125E6634E404F174B2BB76B30B7A
-:10A3B000D76B6E1E321970FBF69067F234283F6E31
-:10A3C000622558CF089FDB113E433AC247C2C308FB
-:10A3D00087AEE6BF2FC23BC305FD5C509A8662A1E3
-:10A3E000BDA753C05D4B41FCC43853C6C420DCBF7D
-:10A3F00081718732360D8B00CF0FC66B1AB69BCE9C
-:10A40000BC8566586F6C9166D11C349C09E7B3D843
-:10A41000C9E753A83A882EDB762A7E1BD41BE7C9EE
-:10A420007E6C24E4AB8E59981FCADB18A7DBB68D6F
-:10A43000AADF07F4B2F08DE78706E0D3A7824E3398
-:10A440003798984BE203FECBF68733575630DF7FC1
-:10A450007BAC2E9FDBD053577FE081545D795EA0AB
-:10A460009FAE7CD0B17C5D7E48D3F5BAFAD77D38FB
-:10A4700056971FDE7CB3AEFE88D35374F951AD7787
-:10A48000E8EAD785C1FE1988E0F63465015CE60983
-:10A490003CDD70658EAEDDB9A8F1C7705FCD5BBBEA
-:10A4A0007002EEAB31AC4CD70FABB79C40BAAC8668
-:10A4B000BF88CF05CC1B1D007815B2D6D792007E81
-:10A4C000957EC58D705BB881D793ED161DB8676C0E
-:10A4D0000CA67EFDF732660EE6A19F9A3F6DFAED5F
-:10A4E000D190F271CE6213D2DF465764B7CF2210FB
-:10A4F00010ECBA7FA89DE2D71D40FCBDAFBA6DF04D
-:10A5000069F11B2AED83C5BB143F837E33587A342F
-:10A51000E6AB8EA9CC0FF83FC5AA1F1D09E957B5B8
-:10A52000FEDF1E4D0FC2C796A0C773984B8FE788FA
-:10A530002C3D9E23DD7A3C470FD3E339C6A3C77376
-:10A540005C911ECFDDBD7A3CF798A1C773A2A6C768
-:10A550007352891ECFBDABF578EE53A3C7678AAFA0
-:10A56000548F3F03FE25FF4D5BB35857AF9D0EBC84
-:10A570002513304DAFFF91AEDF32B5DC0A1868A766
-:10A58000071FFC457AC864CC1D003857021E02AE76
-:10A590008E7450D2B86E55D2BF40077F42FCF70F81
-:10A5A000C1BF3A2B5AEB845FCB54E23557F19C4044
-:10A5B0007EF6A54BFB0BA633323F4F3603DF60DE42
-:10A5C000E24C6F6490EF3116606C68907FF5C6B511
-:10A5D000E5333A8FCC4383E751577CADC3393A49D1
-:10A5E0009E3F5D9CA3AEDE413E0800F988F95E699E
-:10A5F000A641D69A701E33055D1F0EE77479198B3C
-:10A6000086433DA8330CE6F511CE1BC6F928BCFFE6
-:10A6100051DCA777B0060BF63F8B35513A9BB5520C
-:10A62000AA31A715D339CC4DE93CE6A5F475BB6634
-:10A630004B017894DB9B873298FF97C5BF3FAEE014
-:10A6400064DE8AC3C9760957C9AFDFC37F42BD91B3
-:10A6500029DEE814E0BFE3ECAEEF3D029F0EE339E4
-:10A6600081FC77421CCD9799BDB953723BEB67399A
-:10A670009D1B2F2B9A867CD79768776F85B5F54FF2
-:10A6800062F6443CE712FCA953003FC929FAF3B72C
-:10A690009FA0895D3D1B16C7201E993F16CF876B73
-:10A6A0001DB75F8A271DD72FEB5F6DBD566BC33D6E
-:10A6B00038CFD60A877B33D0E7FB021F4FDF6E0B04
-:10A6C000A851413AFA3062F66BDD016F5511DA207C
-:10A6D000EC7FC6F49B56615E391CE75A0CF3BB5401
-:10A6E0000CF0E6F0BF8EC35FEB130F4BBCD05BCB1F
-:10A6F0008C46F87B39FCE11FB9DE4EE7CFE753A06B
-:10A70000F0F1F745681EECE7B0A929D98DF0303794
-:10A710000DC576CCD19DFAB960E570E90A0E6323C8
-:10A720007ACFC275CDB3D9DC2AF43956E1783D1918
-:10A7300077F7EC2AF8E77C93373EA0EAE63D09F18B
-:10A740005DEE2CEE93087473C122E66DEF2EE0EE01
-:10A75000CAC17DD5D5BCEBB07F94037FA2F8510E62
-:10A76000A43F907FC117E3BF1FF236D3E5F7A7A23E
-:10A77000FC926B726F86A28DE1D035D0FB3B02DE7E
-:10A780004F58201F4BDFD7E0F78470DE3EE1519336
-:10A79000BF0EDA7BC7BE48787ABAD241EB29662E63
-:10A7A0002B6EB2B9CC4374FF97317F7BA519F05162
-:10A7B0009EA22D44B8DD1D674A7E9FE6A1F547792C
-:10A7C000878DFC6EF42FF7E914275FC27C01B7A9CF
-:10A7D000CC43FBEE36A65970DC772F5A3DC83FDFDD
-:10A7E00015FC643AF3D1F799CC4FE99D2C40F5EF75
-:10A7F00062CD94FF7DC480DE3530BFC98F65A6234E
-:10A800007F0D81FB4F08EE76EDEE6E9C5E4EF540BF
-:10A81000B8AFEFFE9DE877B2A017D8AF2B71DDB0CF
-:10A820005F07E7A586EC9B719C5E98D999FECFF6F1
-:10A830004D531B3F2F80313A1261FD370A14DEE879
-:10A8400029A37302E5AC6E00FF26974A7256D19891
-:10A850001633CE7FDBE79C8FBDBE8C45FAA0FCF59E
-:10A86000312A437C4DDA30FE0CB67B8B05BA0D865F
-:10A87000FA8557B4A3D1B0FE49C0DF8123B3A25EED
-:10A88000704E849C4B3727AC1B8772C4CD7DF5DF9F
-:10A890006F61F52AC26F428EFE5C9984E78AAC072D
-:10A8A000E31D4238C4763C5FB6A708F9A21FEB77D8
-:10A8B0002DE74BA5C9F36BE223406748F773CCCC77
-:10A8C000D3D97E73642A928F91DC72AB18BB6DC2B0
-:10A8D00065EB2558EFA914ED25EC67F1C4BFCC4614
-:10A8E0007E0C7AD4DB83F01CFD9DCAEE87F213B593
-:10A8F0000071385C4FD6DA9907049CCF6A9D943F6B
-:10A900005D9B40E9D95A17A5E76BB3A8FC62AD9BE4
-:10A91000F251A9DE23D8EF9C359F9B518E5A1D26FC
-:10A92000F1C7E7B144D0EFEA30AE472D895CF26160
-:10A93000318CBB840E4038AF1BEAC723584A0F3412
-:10A94000BC86297C571D58BE4E71E3F934FFA8B66A
-:10A950000AC967E15BCD9390ED0CF9E0643CC2ADB0
-:10A96000E28AC234D84A3F48F7BC8BE39FAA1D460F
-:10A97000F33A53EBA179791A5B5E8B83F6E76A8B26
-:10A98000289F99EAFD10E9DBC33EB762FB893B5B78
-:10A99000CC49505EE8513CB8BF477B98DF0FF8DBED
-:10A9A00060E1E7C506382F907EC6E44E79E27B88E9
-:10A9B000B614ED048E735BECDCC238A4AB61C566E3
-:10A9C000AC37FD1B90B95282F47DB57D72E1A04297
-:10A9D000F0B9703086E021E15421F075617FFF5BB2
-:10A9E0004740BF07418E54617E6D574C34BFB60F50
-:10A9F000C3FD282418DB2FDE97D68339709DD0D86D
-:10AA000086F9FE3D18E021C2FEF413A8979DDBF500
-:10AA1000C304C4CBB9D8862F3F46BEF767CEF7181C
-:10AA20006BF8EC71E48BBD12DCF743EEA205F43455
-:10AA3000D26BAA23F05CACB4328DE7B5FE983F1719
-:10AA4000CE487F1DBA3B692CEE271CCF9519E46BCD
-:10AA5000598A8BD500DD67EC7E2CF5C730EFED0D04
-:10AA6000F33F7E1CD20B7E93CF02E7D605D670F162
-:10AA700025E4CB5B1CEEAD0CEB9BC3B1FE03163E95
-:10AA80002FDF56D0DB5DD89F9FF800945BB1BCFCF4
-:10AA9000B95FF4C4F9BF8C7209E45F5E1741FCEE44
-:10AAA000658BFB780DB67B82F7F7CC43F79E388039
-:10AAB000E98315F9F742DA273596E03DEFE78BFA9F
-:10AAC000617B38F75922F0C75FBDA004C2006EB9A0
-:10AAD000EB0F2D4F84F1066E6C31F584346F8B5281
-:10AAE0008769FFDE45C7F0BC4D4F75D13C06ED4C84
-:10AAF00051519EECD7D3FFF10D240FE8E5849CF56E
-:10AB00009F8FEDC982F2423FA5E1EC32A087D5BD0F
-:10AB1000FF90CFF5C47AEA675FE3D4F7EE64B80E2E
-:10AB2000904470DEC556B253E0722D90BFB0376DC1
-:10AB300013DA33F69B7C9BE8FC9AC3E5950B5EDF4A
-:10AB40002F90CE2AA0BE0FF21579BEA8EBA1BCE2D1
-:10AB5000CF7DDD4051ACF7933716213C2AF73E32CA
-:10AB6000BE27D4BB3092B90115AC64DFE5F1D88EB5
-:10AB7000F586B5603F7BEBE2EF80760FE48C1D82BB
-:10AB800074E5551B681C56C5C7794C9C7BAC198075
-:10AB9000132F5809D47B003EE3F7D8C69843492CBD
-:10ABA000889FAAC66529686F19ACD9DD2AEE9B1467
-:10ABB0005F62B523788EC2F977632AD44BB48A7E5C
-:10ABC0009D5393BDD770FE59C57926FB7BCCCA7CBB
-:10ABD00061B15C6E56F07CB6F2737B2BF0979AFCF9
-:10ABE000E0B90DE34E4FE5ED495E4E82433A0FE684
-:10ABF00099F498CD4FB2C1771C5FCA5B55427F91E3
-:10AC000072CB8CB8BA579A61BD8F456873717DF36A
-:10AC1000C5B9CFCC6E17CA453F8DF0CC4B25B9AB2B
-:10AC20003519D700E76A09E62B5590C3D242E430C4
-:10AC3000FB773B577744782AB1FD77AD6FE4BB4B88
-:10AC4000BE30B13CA083258FD8484FAD13F6863A6D
-:10AC500061DFAA8B1C6A477EC18E9ACA5F83F37636
-:10AC600014EFA1BDDF2591F9C44FEA18EB146E076C
-:10AC7000810F68C07702706E68C00F465F695539F2
-:10AC8000DD371D891E8CFC9679225D680730312DD9
-:10AC9000E43C35F603787B08E1398645302DE4DC69
-:10ACA000F4B0182BEE5FE688FD97D63F52E04FAE2A
-:10ACB00063A4B0E78D6CFB3002F9E6922FF2897F36
-:10ACC00076B5BE57C4FA7E83EB83D492E9DD84F86F
-:10ACD00018F557A719D739CA3C3919E51C98FF331D
-:10ACE000F87DF45F4DFAF97F13AECB7FD7757C5FAB
-:10ACF000613E13EECFCFAD7EDC9F8D40DFB89F1B52
-:10AD000017E5F8910FEC87FD6047BD668A95E4DC96
-:10AD10004661276DECEE24FBD2CB169EF7CD14EDE9
-:10AD2000C3189D238D337B52FB9EB6EA3773B1FF68
-:10AD3000BA08E29F8D16FF9A54ECFF27716E1FE050
-:10AD40004BC5F36310E81B827FD7590277AAD8DF7F
-:10AD5000E75686E3AD8F09245541FDF58B7A52FD08
-:10AD60000F419442FBDD0893E9EEC90E2CF724C68F
-:10AD7000427EFFB72A9D1BEBF320EF203E4EF6C02C
-:10AD8000F5933D89E1DD308D37D17C54564DDF534D
-:10AD900078BB8F2DBCDE1D027F1F09FCC03E273E05
-:10ADA000A04D8A30231D5F4C9DD342FB8379121541
-:10ADB00098CFE3F3D219F2D13B4A6F4A21BAA97F67
-:10ADC0008CF8D90C8103D91F36B00F45399AFF99F9
-:10ADD000397F6B18E2F3B69230B28F7E58B23CD214
-:10ADE00005ED6FD3D4800DEDC6D30A3DA1FAF8C5A9
-:10ADF000540F8D5BD1909D763284AEE7D8806F4042
-:10AE0000FF6BC2B5D348CFEC401E951F00E1E61F93
-:10AE1000B0AF4ECC4BDF4D768D79528F0CCC45BC0C
-:10AE20001E6CB533D44FBAA2873AC403F4DB479CF7
-:10AE3000EB44AF88FF19E15CCF3103BD40BEAE21CA
-:10AE40009BF49CA72CCCA320BEF6D908FF4553EC5D
-:10AE50001EB23FCE08DF6483F2BB053FAB9B114EB1
-:10AE6000DFEB5E89F49B14D29F28EFDB63A176E5CC
-:10AE700056FF8E6DD04FF9C16C3A6FF65BC5B82F97
-:10AE800045F0F2284FCACAC158DE83E8E0658B2B33
-:10AE90009ACADF50199587073262008E91615A581D
-:10AEA000DA10A43BC0B303FBE5DF8F0BFA3A0EDDEB
-:10AEB00022FE7CD591D42F6D7DC86B75BD37233EA6
-:10AEC000352B2F673F52A9FCB8D393381FF2C7AB7D
-:10AED00093685ED2CE74DC6B25BA3F5EAE90BCF454
-:10AEE000A71A35600DB5E34FD97E5F06B4FBF4A019
-:10AEF00085EC78B37E56F6167E9FB5BC82EC91B396
-:10AF00004A97929FE0E2D24F876E80F5342FFF245C
-:10AF1000590BB14BCF2A8756A176D5344F6A1AE028
-:10AF2000E7D6342D1DD75795D3BC00E5EB8BD6A6BD
-:10AF300027515F7075D3B2F0FBA5174F6DE37277A1
-:10AF40006B069E1395664E27F2BCAD1274F85F69CE
-:10AF5000DA00EC0FE0361BCF95889C26CEFF967E5C
-:10AF600037FE7FB671EB7E05C6290B6FACA454F596
-:10AF70000FC07ECE298128258DE0A8E1BE3AEF0CD6
-:10AF80004421FC351397F3CAB6EBD7857FCCF16823
-:10AF9000376364072F6B503D61B80F98DF8AF32F3A
-:10AFA00063D660FD9420BEA01FC21773FC69F68FA4
-:10AFB000010FA53BB2F351BF288B39F0D008AA0787
-:10AFC000EDE47E513BE6E57A3ACE87AFEFBCD80799
-:10AFD000E7E18B05E965A74DEAF934FEC5177BD09B
-:10AFE000F8F1629F5C5404BDEE08E374E58675E1F8
-:10AFF0003C7FCDE9EA51C92777F07ECAE27C26E49E
-:10B000004B65B54EA22BC997602EB4BFCEED4EA2B4
-:10B0100076928F312F63547F77E2662EBF097D17BA
-:10B02000270CF54B7FC5C7C13CF2F3B3CF26C971DE
-:10B0300049DE369EC7C6752F49E3F62938A77BFC43
-:10B04000337D312B61EE13F30685AC27D22AF882CB
-:10B050003B61722EFA17ACBA7E2F465AEFF638D003
-:10B06000CFA0FF2EFBAB4DE3FA641F039E7BAAAD7E
-:10B07000876CB80F9F66746E18E7B14AB47BF6D937
-:10B0800076BCAAC29ECE5C929E5C5C9E27FC7D64D0
-:10B0900095F8FB5E12F0E33284556A108EFBF3B430
-:10B0A000243C372E0AFFD0FE18C8E7A03CC5F12289
-:10B0B000F3121F46BA5CFED18224F4473D2FE168AB
-:10B0C00080F732802B96D75940BFC9413DF7D8C38E
-:10B0D00027D383EBF9ACD6E39917925FB021CF8EDB
-:10B0E000FB71E1C63CFB9C107CD46D1F74CC0570D9
-:10B0F0003FBFDDEC46F65E67F63F84727ADD76B5DB
-:10B1000001E908CAED08EFF38EC3BFC37A0B36C658
-:10B11000E4A31C2EDB2FDC50E899178287FEDBF5B9
-:10B1200078C96DD0E7071ED0E75F4119B4FBB5B70A
-:10B13000CB0BE8F3838EE9F3AC15B03714E5018E41
-:10B14000B71786B98FB9006F7DFCAA1B3FF5714C0C
-:10B15000993A11E5888DAA3B1DCAFB2CF5DE827257
-:10B16000C5E98DF3DD88F612D557F963C069C927A3
-:10B17000E38FE1B97A8E35FC6122E06541E33AABB9
-:10B18000D985EBD6D3FB7E93A0DF67B9FD6E915FC7
-:10B190005FDE912F2C93FEC1AC50FA32D2018C7B32
-:10B1A000BB0726545EF3DEC3C8174A2600E1039DA1
-:10B1B0000D6F586745F9EFEAE3F8B87CE9F0B8108D
-:10B1C0001EC5C378D9F53505EC53D8776CEDEFC7BC
-:10B1D000E3BC8B1F5048FE287E3EF328D257CB9EFF
-:10B1E0009937537A7B11AD5FDA0917362A8148C83F
-:10B1F0003B87B90E3443BBF97E6EEF98B3C216E4B9
-:10B20000870CFD648679AC0F2987F92F3C70E86BB9
-:10B2100005FA2FD9A86FB708F8349E3FA55BFE61E9
-:10B220000BFD2EF5D1EB1B37A9B8EEF962FEF2FC4F
-:10B2300064BED1E4A7B89E376127F1FFE0DC991D19
-:10B24000AF297DBB07CFD1EBD7F3F6C0768B71DD8D
-:10B25000150EAB0BD75D6167810898CFB148ABC7BE
-:10B2600009DF2F6F88243BDD021BC8ABF994B23095
-:10B27000F47B3037F9CB3E7B4725B9A7228EE3BD5F
-:10B28000E22985F4B40A34AE62FE699E5FC402B45A
-:10B290001EA4174FE83AFDFA3CABE7FA5DB93970E6
-:10B2A00008E152CA9AB97E06F8F484F8BBCB619DD6
-:10B2B0001FC6A2FC6668CFDC1AF9F11C5C1EAB3A13
-:10B2C000F00F5B68B9D433A51E2CEDC74F6578C36A
-:10B2D000711C8B909BD7DFE7C9C0F9AEB4783210F0
-:10B2E0000EBE7561A4EFDFB1899F5FEB63408EED09
-:10B2F00046F233C9E377285C3E6733393F1C617AF5
-:10B300002E80E74DEB2331EECD2EAA4FE7D8FA077A
-:10B31000B3B9FCFFAD4AF250EB3A1E17B13E8FC3F2
-:10B320006FFD83B95CFE97E75E7746FD7594B73D88
-:10B33000196887600FF3797D8C4B0A91AFBF8DD769
-:10B340006EE81BB23E2997B392EFE6CFD82AE234DB
-:10B350005AD785F9D19F7152F1BE660A916FBD7DB2
-:10B36000F9393174AC679BA8477E8F79A6C9F7DF9E
-:10B3700000F39AF7A8C985F6B776787B3C19787EF2
-:10B380009E5C17968F7436742CB7471DCFE37C3FB5
-:10B390006230F3F8219D29FA9DD9D7A44B13C281BD
-:10B3A000FEA09F9385DC1E1E39D84B76C0AD2ECEF5
-:10B3B000F78DEB982FFA9967F5FE765427F3917085
-:10B3C00061E3B8DC71F21E65339F17E01BF2437F27
-:10B3D0001E46F6C393E25C92F005BAA1B807C9B75E
-:10B3E00062DAE9C5BF230CE8659D85D381D4DB42D1
-:10B3F000E845E0BF37E1F70E815FF66098A01713CC
-:10B40000FB6F8463A193D3C335EA5F80EF9F20BEB7
-:10B410008D7A98C43733FB87FC33BF4BC50BBBF623
-:10B42000FB40CE28FDF523510CEA9D31D7C7BBA1C7
-:10B430007DF9D695511E484F9B7D514E18FF8C5F6C
-:10B440002DF27702EF97FB4AFBB5C7A184F849CFED
-:10B450003EFBC0245CE7975B2D4E640955DB6DA471
-:10B460008F55EE5D44F23AE45B787EF5E7E837AD60
-:10B470003AA0B7CF973EF348BC8BE0ED4B32256046
-:10B480001A486290566EB1B4FB91611890BF5B5739
-:10B49000E1FC8CED711E5700DF550D6AB135BA63C2
-:10B4A0007995E02F557B1FF81CED86557B6F3A850B
-:10B4B000FCBECAE0172811FE11A35FE0577DF571AD
-:10B4C00007001F8A33F0C1BCD2895CB85DB96EC772
-:10B4D00063035A507ED8F266949213F40F48BF4922
-:10B4E0005BC3DCA75E7275BD2F2F0AFB70106F9CCB
-:10B4F0007FB90E2818AC048A3F4FCB2D81A811A824
-:10B50000EF6DB290FC5BBEEBE96D8F239D7D64A374
-:10B51000F3BD6CD7AB7FB81EE5E73D966E13F832EE
-:10B520001C4A485C4E958BDBE3247E4A9F7FD5EA1C
-:10B53000CAE5DF97C606F154B6E79015E3838CF0B1
-:10B540002C6838646D767482AF8696F16487DAF180
-:10B550009515F7C799830AEB91D2B17DC9A657A378
-:10B56000503E4338E1F924F1D68E47437DE87FD23F
-:10B570004B83A99E13F594ABE1F181BE8CE056F1AB
-:10B5800042248B8179947C6CF34F40FCEE5E1285F3
-:10B59000EB3965AEE674FFC4CA7894F74A2CBE78DE
-:10B5A00027A5FC7BC993DF277A5CA854C73B738827
-:10B5B000DE134D244BF812719DF337DE46EB5CC071
-:10B5C00034A2C7922754AF1FD22FCCAC684F27FBB1
-:10B5D000E6BA74BE6F4E6D06E4C23A4F89F82CDFAE
-:10B5E000BBAAD0A3EFA1F3FCFB62CD8C2DA6FC1768
-:10B5F000429E0B4B6F8FAFB287EAA1555B56372146
-:10B600009ECEF6F6F4C079021C7C026ECA3FA05FA3
-:10B61000F5F7853D389E980BE317A81D9CAB05F800
-:10B620001DEB37593C68670F6927F4443EFEF7C4A9
-:10B63000F830EF70D4834FC5771EFFB500D7C7E74A
-:10B64000D7141AFFD5251FD8721FD1D75FDFE77C2B
-:10B65000A6D23FB988CA9B2C811E58EE3F344D219B
-:10B660003E616381CEF6F9168BD8E7FA7298A75936
-:10B670000985EF412E9F4A7A5900725920444E089D
-:10B68000D28F35F89DD6FF73C1E79AC99F27FD80F9
-:10B690000B057F30AEDFC82FF2D23B8F53611B3BCF
-:10B6A000F73F05F9848FC62D87F31DE591F28F6C66
-:10B6B000244794EFB278114EE7761EF9C31DA8DF38
-:10B6C00036C87DADE7C3C67D5DF2DC904EF7F5B9B7
-:10B6D000B5799DEF6BF8DEE9BE5EAB10BFFB9FF264
-:10B6E0006138F9C82E71B5FDBBB00B3E3C2B5DCF68
-:10B6F00087BF6039D123B0D059DC87F06480AF8434
-:10B70000AB91AFB6F57575CA5719867484C053C22C
-:10B7100051D22B631A8DD34ED7926E255DB7D3AD20
-:10B7200071DD7A781ACB9311F73075EF8B1692177B
-:10B73000CA1B797C22B4A378BA2AB4CF53EDFAD7C6
-:10B7400092BA85E6FD867C83A1BEC790F71AEA6BA4
-:10B75000867CB5AE7EF9812356AE3F0474F56C3518
-:10B76000B7903ED251CEF073BFD3DECFAD3EA48FA3
-:10B770005EAD56E49396E5CC1709ED5B5F5149EE5B
-:10B78000B9E46A8D42B965651897EB2E39453E8656
-:10B79000E75BBB5B57219F94DF5BC3B81DE692B7A5
-:10B7A000352A26449F6F6954A3D0FEDBEC67459D84
-:10B7B000C7B7D4115C9B5957E55CBEBB14CEED0DE9
-:10B7C00097C2B9BDA1507524D7A01DB69EC711CE92
-:10B7D0005B363D8AE2301AD36E9D01DFE7BF4161DF
-:10B7E00006184767C6F887B91C95EC34F3513CE15D
-:10B7F000DC461E07316FAD1ECF0B1C5B285EEE0BC7
-:10B80000B694D205EBF5F10BA56C2DD159C946C301
-:10B81000F7C65B689F941AF68926ECC3C67D72480A
-:10B82000F29F3C96A78B9314FCBC50CDB97506E0F3
-:10B83000E3D23195D920DFD6A8B25583795C2CFAB2
-:10B840009F5021C1FD5709FB15E52609AFF3B88FBD
-:10B8500032BB965FCEEFFBF3D01F23DDECFF64C05D
-:10B860002F213DBFFFA38C9731FFC21F933F611D66
-:10B87000EB171CFC7A36F2E94B076D0CE9FDD2C1DF
-:10B88000D793D11E79E9251BE9D99796DBB89DFBA3
-:10B8900060A41F8F984BBDB95C5CF7CA57039AE947
-:10B8A0005C5E41F83B9F6EE5F255E3DF8EA33DBD44
-:10B8B000AD1156857CFF6004EDA7AA97C2C8CE7C67
-:10B8C000E995AF8686DAE7FEA7EB91FEF74B916C20
-:10B8D000C67348C7315C2FA87A79F8D3E85FAED831
-:10B8E0007BC83A17CA0B7EF3F701C8572F3DC7E54F
-:10B8F000A98B96E627D1C6F955FA999F5B86A39D39
-:10B900000F3AEB09BB3B237BAA2FA733B870385CF7
-:10B910000238E0BA002E25781E74058FA88CFF54DB
-:10B92000787C3E9BF3B7EB18FAA38370513CFC7B09
-:10B93000A4DFAED0FAF9F7835F0D40FE73B5F5E6EC
-:10B94000FC7FB6DE9BFF63D7CBE9FD5D5442867476
-:10B95000A4FB8E74FDC20F28BF3BD24DF3FD8EFBBE
-:10B96000BD14D7DFFD3F71FDFF3BF85EF31FBBDE6B
-:10B97000ABE1FB0D81EF4827FA332FBDF2F7647678
-:10B980000DEB7EE6FF289D4B397EACEA3E9607F52F
-:10B99000DF640DEFBB53481AE9540E793F43AF3FC4
-:10B9A00015307E4E17D8CB48FE2CE8F520C9CB7554
-:10B9B0002C9FFC17BE5E2AF975280804E0F07A4235
-:10B9C0001EDDB362E640AF25901F9B5441F16246F5
-:10B9D000BDB2207C6211CAA74796C1BCA09F23912B
-:10B9E0002627FAA8C7F55203B60194B660FA5AF2B0
-:10B9F0002D14F73FCEA1D7AF6E31E84937B9F4E542
-:10BA000045ECB96EE8B72BCAB1D0FD8AF1583F4476
-:10BA1000AF7C2EC349EBBC89D5AF703AAE1D4EE664
-:10BA20004C0EA78E70F8E770EB0027A1479B457D71
-:10BA300023DCCC8EFB9BB09D99815ECCD74BFAB4B6
-:10BA4000D48BAF064F26F46DB3185AC2D7DC8BFBEC
-:10BA50006743FA25B848B85F2BBC259E8C7097F0D9
-:10BA6000957033E2E18F194CE8B71CFEBDCC7966C6
-:10BA7000DC77A3845C3FCE1CC3F3BD9A542FED4703
-:10BA80003FA7F3BFBACD28D78F71C4501CA9F1FED0
-:10BA9000C29C61314315586F9299F96CA087A2EF4F
-:10BAA0008DECAEF799FDCB53701C6EDFED6DE6F6B5
-:10BAB0006BD8DDBEF07CAAEFB142BEF8E185CC03C5
-:10BAC000F58B93985BE1F559742C85C73115E3C468
-:10BAD00020C576C5D1BCDFE21ECCBF9CE393F082CB
-:10BAE000661FB46F40BF1E532C6F1F954FED7D2610
-:10BAF000DEDE6386B44F1A8F53685DC9EDF2C5ABC5
-:10BB00007B6720FF9830566F675E9AC9ED2E323DF5
-:10BB10009DE92278A9267702DDA758914DFA911A5E
-:10BB2000EEADD88776FADD3C4EA778D55D1387E079
-:10BB3000FC76C7B9717A6727ED19CAEBCFFCFE070F
-:10BB4000F05DDB1E46DF1D59DA7599180FA0B86647
-:10BB5000EF830F736E3B624D8021B486C917D04EC0
-:10BB600038C9B7E777E89F9C344DA5FA93188FC37F
-:10BB7000642B22280E73A2EF737302F43711940E14
-:10BB80002C6F097326DF03F32F16F6E102B15FD4A1
-:10BB900070A63DE7C079F5CE4885EF1359E7F1C9A6
-:10BBA000CB447CB23A56D9887EA63E05DC7E2FEB8C
-:10BBB000633FD8EFEA4C6EAF9F24529907B852FD0D
-:10BBC000796B6C2D69A8FFACB10432213D943D76B0
-:10BBD0000AAE73422A1BBF01E17EAFCA36D37C5B3B
-:10BBE0008BC9AF1099E5423C6840D2E45FA94F7120
-:10BBF000A15DAC654C4300FD092DBF4871D7B90864
-:10BC0000CB140F24F5AD963181BE68C76FCDE37EAE
-:10BC100089E3CEE648D417E73AECFCFEA4882B9AD9
-:10BC20002FEED1F4A96B7EF03AD4431F51C95F3394
-:10BC3000FF117E3FEC2F0EBB5F41BD6D3DDFA76C5A
-:10BC4000AD3E8E8839DD64079A5B3FC68AFAE63CD2
-:10BC500087C78AEB5C9BA5556722DF16F711FB218E
-:10BC600012A0CBE2FA628A5751A360DFE13E31BBFA
-:10BC7000A2500F36C6215589B823995F13AEDD8BCC
-:10BC8000709A13EDDA8DF472A2268DECA30704DD11
-:10BC90004DC0B84AF467989B13713EFDF03B8C3F52
-:10BCA00021D699E1207A0E630887168B3303E9BB0E
-:10BCB00065659809FD72139673BA867D663743FBF6
-:10BCC000FBCC2C1CFD0C378A7E672D337B3741BEA5
-:10BCD000979D99236391AEF288AECDFDB449B8BE6D
-:10BCE000D33F61C3901EE6AE5D47FE184917CCDC1A
-:10BCF000342E0EC639BD35251FF9663B9FEE37B68B
-:10BD00001EDBB5D3C33485E800D24369440F531E0C
-:10BD1000217A181BE8BB3807F5D172E6C1F33D81E3
-:10BD2000B9514E6863ADE4AF6C73585D68FF92FC27
-:10BD300044F20D795F56D2C13638EFCD16C6B6D76C
-:10BD4000DA297DB6D6C9CCE98CEDAC4DA0FCEE5A13
-:10BD500017A50DB559F4FDB95A37E5F7D60EA3FC72
-:10BD6000FE5A0FE50FD41651FA52AD97BE4BBE04E2
-:10BD700070213E24F98AE447731DD616F45F4ABE4B
-:10BD800064A49BD900DED1F9D49EF89EE477B80E66
-:10BD9000537E901F49FCA62A5E5F420AF2B1E699E3
-:10BDA00088FF42F5FCAE17502F2F71B8494F679CA2
-:10BDB000EFB501BD225C92ADEC00DA65EBEEF1B4BB
-:10BDC000AC4E09C2FFCE12859943E8EAAEEA30666E
-:10BDD0000E3937EEAE89D1E567D5BCF76A0FE87F3B
-:10BDE0004677ED0DC4DBF19F7EF6C41FE1FB533FA8
-:10BDF0003D9B8EF886796C7D0CC75D1ADE3E8F58B0
-:10BE0000CCAFB0909FAB8FB09FF411F613FC137AB8
-:10BE10009FF9A99FFE37EDF3961A9B0BE5E28F1170
-:10BE20005F00DF3F097CCDA9B1111C8B577EBAEBB7
-:10BE300005DCEF4BADC4EFE6AC10FBD1700FFA445C
-:10BE40002223BB0448D514CF7EE227D64004F47FDA
-:10BE500042E1FB5801E16016C61FAE79FD43E403E1
-:10BE60004ACD31F2BF6B786F0FE7E7B39CD7DDABFC
-:10BE7000AE798DEAB1E65E31685F94F79223067B76
-:10BE8000AC2E583FD236E26F4ED66196887E967AB7
-:10BE9000C589A2DF3CF17DDE1A85FC9A18C7330DF7
-:10BEA000E4BFB64C95F0999B69A6F4018CC127F9C3
-:10BEB000AE9ECE2949B7F3D6423BDC1FF579D605B5
-:10BEC00021FC788EF83E37CB44A9FC6ECAE2FDF621
-:10BED0005C933703E58A9E589E8369FE0C846F4FFE
-:10BEE000C778B3124207DF88F173C5F80FE0A68365
-:10BEF000FFDD9F956A9D9F43F701E91C93E3CCC941
-:10BF0000CA5F85F1A573D68E412ECCEA2CEE846EE5
-:10BF100068BFCB92FD88FBD8761E475DDEC539220F
-:10BF2000ED6AA7F19FC369DD64F72DDDFDABDD7818
-:10BF3000BFA0F4131BE1B774A088DBCAF10F9D4AC0
-:10BF40000648BD3D7BDCAFFE1C457E8ABD3CBE1372
-:10BF5000526E675D5AC2EDB26ED85F9DF88B8EEE61
-:10BF6000FE24AA533BF65EF53BD9B1AB946FA250C9
-:10BF70008E90EB297CE58B789A877285FC4455AFCF
-:10BF8000AC8CEF2CCECB68C76EB7770BBB5ED5D22F
-:10BF9000A24EEDDD46FBDDF02C83FFC0CCE89E9980
-:10BFA000B4DF3135271AFD005F88FB275DE939D200
-:10BFB000FE5DB5013A8903BA34BBA2D1BF75A90BA6
-:10BFC000F97A59163FFF2F087BF9A59D2AE93D977D
-:10BFD0007646D2BEAADCF9F06BE877ACDCA2D034AE
-:10BFE0002A5813C10FE0CAECA1E71AC6B1C5759C67
-:10BFF000779B3F3D1ACF95B25F455623BD2D6A50C2
-:10C000003C5B613E6D765774F790F9DC85F406F47D
-:10C0100053666B184AF016F39F9AC5F9A4ACB7A8FB
-:10C02000F161B22F43BD8B2417FD3A82F1FB29AD9C
-:10C03000BFC3799EDB38C88DFEC2450D7B2A49AE51
-:10C04000D819E144BBC25911B7DCDE8FA0EF4559C6
-:10C050005C8E3927FC47E776F37700709EB8CFCE29
-:10C060002ADC0EDD8E6FD1AE4AC02D368BEF3359F0
-:10C070007F51434B545FA87FEAC07B94DE2BD6B53B
-:10C08000C8D13400CFE3537B23C8FF756AEF2FC7B5
-:10C09000BF0CE35D6818D30DF785EC7F759685EAD4
-:10C0A0005FD8A81621BC989FC7CD54207C0785CEA9
-:10C0B000336E932F2574FFF1F8A1737B9F8F32E5C8
-:10C0C00004F15961AFB6279A701FDDE345FA8E403F
-:10C0D000E2817AD6BD937D78865535E631A46BDA58
-:10C0E0007F89547F8D29A49ECDE2A63853CB8162EF
-:10C0F0000FBF6722EE458938FE423587FC8AB307B9
-:10C10000BAA6DF897CF24D0BE16371B66B3AF2A7F8
-:10C11000CB4D2AC3792E4E6101944F96DC1BB90991
-:10C12000CF3139EFD983383F285FA3300FACAFDC74
-:10C13000AF320DD29E807F1FD25342F3108C936C8E
-:10C1400049E172858C1F7DBCC4E4B1C239B8272B8C
-:10C1500056F059ED17F3D17F36258BF4B9E356E647
-:10C1600053D1AEF41C8F2F2D4FE571CD8F8B78F806
-:10C17000F2D840461CF4775EE0B77C4A2003E32EF9
-:10C18000CA9F4BA4B88BF356EEF7C4EFE8672DCFE8
-:10C1900087F60E7A674393ED6342E8A97C8EDB85D0
-:10C1A000F5D458B72BCF81F3755E2439775F2443DC
-:10C1B00039D7F442248F9B7A266CB32D046FAF0AD3
-:10C1C000FA93EF77B03B789CD1A3161E97FAE8D686
-:10C1D00044BF3F045E8F5AB49908075C07CAF78BC7
-:10C1E000ACF51928FFCAF92E8AAAA7799E17F4BEC2
-:10C1F00028BC9EC7738BFBC0581FF32D220EBD7544
-:10C20000878DE280CE2636EDC7F1CFEEC866B8FE48
-:10C210009614FF8203540EF225E0B3F4595B00D765
-:10C22000736607B7479FB17079EDCCE40417E2B7A6
-:10C2300068CA86D964AFD96253D0CE774661D60436
-:10C240002CDFDA9DE2CF4B6B6B287EBB14D806DE69
-:10C250001F82B408EF019DD99A4DF16667F0DD06A3
-:10C2600085BEAFC1EF1AAB9FFD2384C776AE5F9D3D
-:10C270007DF66FD9A1F1DE322DDDA28FAF9374224E
-:10C28000CB3FCBE2FAD067595C9F3B9BC5ED1115C4
-:10C29000110D8FA6D23A39DC014FFC1D1BD61CF9BB
-:10C2A000CBC1184F91AE201F799C05327E897687CD
-:10C2B000ED5CFF3ABBD34271EBA52F447A288E6D1B
-:10C2C000F575268AA750B99C5E6A02F041AAFC74F3
-:10C2D0003BC597757B362CDF46F239233DB775ABEE
-:10C2E0002AC6015D10D7BD8DC71D4F405992CA7334
-:10C2F000A9FC8CC89FD99F4B721FF4EFC1FB55A5B9
-:10C300003FFA3187E3D492B7B8DC65277E5BDEEE77
-:10C31000E719198DE760C5EA11D1785F91BDA332A5
-:10C32000945B8C70BA6C76F7403E3B3C5BF0DDFD75
-:10C330004F907FAA4CDC23287B56E17E68D8877813
-:10C340009FB36CD588C7883E7F6761E9B09EF30DC7
-:10C350000F4785E2232D9BF3C5F6FA5637D52F8379
-:10C36000FAD84FD9AA37A3683EDB2C14AF62C4E3D6
-:10C37000776EFFACFA9DDAB7D34703B7B374583F73
-:10C380006BFAC127D0FF5F7786B97DF4B581EEC126
-:10C390009DB3342CC0F59FDB15467CEB5C0CE70F9E
-:10C3A000A7809FFA32711EB7FC8CE2BBDE9D4AF774
-:10C3B000F716FAF5FDCA71B3B22D3CFE2ACE1D8DDB
-:10C3C000F18215EF703E0878B995DABF63A1F6C621
-:10C3D00075D8B239FF6FDF9FBB22881ECEF5E47897
-:10C3E00039B73B93CEA796184EE730DF64BCEF77A2
-:10C3F0006E57661EDDA343A107E8A154E8BFE762BC
-:10C400001A929D21E52D16A1C705A026D20DB601D1
-:10C41000FE5E5AC3E5AD32FB5A8A2FC178DDA1F921
-:10C4200094066CB11DE36E815E49BFACCDE6E7209A
-:10C43000C3F1E2459C38C9410D56E4DB9A9017CB15
-:10C44000771AE37679F96CD91EAF64C83861A443D2
-:10C450009F42712A652BEE5944F1F7D5EBEEC47D6E
-:10C4600026E75F666645A8A7B5282ACDA3258CDDFB
-:10C470003D05E5CAD07142E4B945D9EDF656E68CE2
-:10C4800027399684FE8A6C17A71B3C41F19EE20A6D
-:10C49000652D8D9322F55DBE2E0927008715E304D7
-:10C4A0005BC688F22ED62DE7695C77BBDC95CDF9AB
-:10C4B000514B8AEB672311CF6FAB74FFF7F23783D1
-:10C4C000A2633B91D382E7BC35182F0BF37F289BE7
-:10C4D000D1FCA7647339BD0CE371619E191BF5F1A2
-:10C4E000E2595BF4F97E3BF5F99CBDFAFC80467D90
-:10C4F000DE7D549FFF018E3B84EBE178DF18F57001
-:10C500004C510F77D9B81E8E79D4C331453D1CBF2D
-:10C51000A31E8E79D4C3318F7A38E625BC511FC74C
-:10C520003CEAE358FE9B6C7E3E968B784BC403D26C
-:10C530003B7B314C771FE9D22BFC7E09D001DF37E2
-:10C5400033ADB46F1EC71AA48F70BB53CFA9761733
-:10C55000C60FAF8AD3766477C77B284DAB12116FB5
-:10C56000E6668A63AD7A89C7B196E78739D0FED18E
-:10C57000BCF2D42A0C0FBD234EDB8DF52F595AB7D0
-:10C58000217C2B6A8ED07DFDE665AE776EE0F823C8
-:10C590003B0C2B892539AA18CFB9D8AEF1688C2766
-:10C5A000676BF5F1E3C67872631CB9910EA4FCF7D2
-:10C5B00094A53511F9FAA73BEC6B71FE9F8689FBB8
-:10C5C0003033EC86780007F193C50F2A9BF1BC7ECF
-:10C5D000279BDFCB6E3B06F27A27E7AC4CE75E1970
-:10C5E0004472797B7EAD62A2F874CD43E7D01231FC
-:10C5F000A764A5B56535F2B945263A372F83BC4601
-:10C60000F2E0FB2AC90FF8AE56E87AF05DAD50FAB9
-:10C61000C277B5F4F7257AEAEAE3BB5AFAFB12FDD2
-:10C62000F4F1F9D3961D42BD7FEADA41BA7AF3BC40
-:10C63000230C7014F316F2EC3C383F3C285F2EDDDF
-:10C64000908CF85DB2A8AD6535E077C9BE303796FD
-:10C6500097E0FF015F2C813EF1DE65C95E717FB915
-:10C66000467F0ECF15E7508999F99CB1413A2C715C
-:10C67000324F0CB45FD4AF6900BE9FB5E88DF7862A
-:10C680003A5351CF18D303F951B2C54371B5E57B85
-:10C69000D2639641BFCD7DB56F91EE4ED61F7968BE
-:10C6A000169E877BB8FEF7E9DAE7A328BE4CD05B7D
-:10C6B000B2C5198E78DF54CFE3EBD07EA6C606E96B
-:10C6C00062537D5C785F4770BD413AF886F004F8AC
-:10C6D000E1769E92C3E417696B10EB1DA3F850CE70
-:10C6E00096EB93EF6EB115BC9FEF89FC49A16FC823
-:10C6F000759ECF3E34C085F73A6A0F24ABC8CF4D44
-:10C700003BB7A11E72C5A625F61B82F1A0E97FC426
-:10C7100077D84A3FE0EBF9CBFA82A8E1287FEEB266
-:10C72000B827407E75FDD356D42B4ACD7E2BC567E6
-:10C73000EED864C578E51BB76FA2EF0BB617533C74
-:10C74000E642564DFAE869F94E828047C95865A31A
-:10C7500013E65DDB8FF38F9270EEDF03F9E8557C13
-:10C76000A7E4F276250FE37CA679F7588BE17BBE30
-:10C77000A867DC276D6F4D2DEC4EF0E0F7403E6072
-:10C78000A0DDA775DC1753AFA4D0BE9876A53FE90E
-:10C7900069B705B2B93E9C63D087DF52B93DAF910E
-:10C7A000EF83126BA0DB54DC27072D24E75698F9A2
-:10C7B0003B4F15F0EFEB21F58E5475F45A352E42B0
-:10C7C00047CF3358ACEE3ECDED185412929F362130
-:10C7D0004D577FFAB4FE06FACF0F96131FB95E7756
-:10C7E000EFAF62A9CFA5909C3956FF9DF1F842C6E4
-:10C7F0006ED6B5AF605382F590BEB7285CEFD91BFB
-:10C80000B319ED802526AE3FCDD0F8F7CA03FC3B27
-:10C810009BC174FBB04F9AFB8FFC5CB490DF40DA95
-:10C82000DB67E0BF3B813F63E1EDF7D8F11E3FDA04
-:10C830002774F7BB85BF10E78D78A810F6A48A2C63
-:10C840006E4FAAF03559F19D0480BF392E96EAD972
-:10C85000E330AEB25E217B23A64B29CE521FA785C3
-:10C86000FD61FC63E531B518F789B1BC04DF2942ED
-:10C87000FCBEC4E3522BD12E14D5F17DB44AB413BF
-:10C88000A17DCBF01EDAA17E2E211FF957F5443889
-:10C890004E50F2E8DEE6CE43568CCF9B362D260F67
-:10C8A000F78F91CE247F877D4D71856D6F1D213A65
-:10C8B0006B2B31131D5F0D1E951E6E6735D2DF0287
-:10C8C000D664C5FB290BF62A6ED44BB11EC2A52730
-:10C8D000D2A5012E71B11DE121E1D40E3743F942F9
-:10C8E000C6E1B5F080E247FED8014E027EC6F97778
-:10C8F000053FB9AE059A361EF9845CDF425C078EAF
-:10C9000003EBC071A4DF820D33EED734B25F557AEA
-:10C91000799CAD913EA65CE17699DBAF98299D3676
-:10C9200041BF3FB11DEE93DBAEC453F9B5D24F25E5
-:10C93000CC13CF856BA51BB91EC98F83FB84DF4B3E
-:10C94000B8DA3B4746FBE4DBFD847D72081BA28B13
-:10C950006F16FCD6D8DE18DF2CE503E3B9531C694B
-:10C96000A278CB36472AC91D92FF6AE25CD1567E77
-:10C9700041F534A8C767E3D19D439AB0132E8E4C7E
-:10C98000A577249297C5C523BE8AC39C14D75FBCE4
-:10C990004CA538EA62A8E70A915B56AD484BC673CE
-:10C9A000E4C47D994FFA409E3F716FB7F86130CE75
-:10C9B000A72B2DDDECAE60BD132B0B9331BEE3D363
-:10C9C00075B619FE4EE0F59538372A7EFA219D732B
-:10C9D000174C6F45CD80F6E52BF745E1F581B29513
-:10C9E000FC7C5FDE57FBB21FF97D376D7322FC9C28
-:10C9F0009B06A09DD8C261DA2E5794AE2CEC8172B2
-:10CA000047F9B7479E74E2BDF0659678944BCFBC6A
-:10CA10000FE7A442E71CC913A7C3A00BF2C345D27A
-:10CA2000FB67A715E6417FD479D3A12F57A3BE9802
-:10CA3000D7901180F47ABB66E98F7AC1CAA7499E64
-:10CA400029BD7F5906BE43A82D4B8FEECC9E22D325
-:10CA50006DE23C47B91E5394EB31BE06E57ACCA398
-:10CA60005C8F29CAF5F8BD6A835E2E8C127E4A69F6
-:10CA700077EE53D79A877E3FDF5896554DE7B083C0
-:10CA8000DE055EA284BB913F2D41190AF37F8E2003
-:10CA9000BB037BFF261D9EE5BBC1F25DE051AD20CF
-:10CAA000AB85EC931BAED859E83DDD312C46972F72
-:10CAB000B027EAEA173A5374E5372664EBCA6F7277
-:10CAC000E5E9F2B7640DD7D59FE81EA3CBDF3AECBA
-:10CAD000265DFDC99EC9BAFCD4A299BAFAB7798B72
-:10CAE00075E5D3672CD295CFD4EED1E5EF2CB957AD
-:10CAF00057FFAEEA65BA72F94E7223EA63367CFFDD
-:10CB0000C54EA97C2FF9872AA3F7D8461698B89D59
-:10CB1000D1C6CFA3256FA73B42E9E0D6FE5C2FDD4F
-:10CB200095E3B9B9FF90E07B98F29DCBBBFA73BC5B
-:10CB300026B180C2F5E1A644A463633D63F9C888C9
-:10CB4000C3975D80CBD7FA1FB9CD8CEF475E77785E
-:10CB5000501AE4A372C26EA7FC88C3CFA7423E7EE0
-:10CB6000E7AD3C3FF0F0652CF7E744F1FC5446A2FA
-:10CB700049EACEDDB7613CCAC81B52D7BAB91DA578
-:10CB8000D3FBEE324578E03D718407A601A0634CEB
-:10CB90000F031D637A14E8789E05E605748CE9316D
-:10CBA000D04FF1FB6F413FC5F42DD04F31FD1DE853
-:10CBB000A59836815E8AE9BBB533287DBF56A3763A
-:10CBC0007FA82DA1F4C3DA6AFAFE716D0DA57FAAC4
-:10CBD000F5D1F77BFB4BFB4340F7DE6857EF8A4A02
-:10CBE0003FA7F46BD655B3E608E41BCDE698CFEC2F
-:10CBF000417F65D7760233FB2C445ECB553C2BFA44
-:10CC0000D3F8BD9C749F427C77A468F7217FF820FD
-:10CC1000656AFA2015CFB1EA5731D4E60353E7EF3E
-:10CC200047DE25E8C397E37908DB8DB2F3FBC9A3A0
-:10CC3000ECFCFEF12873531DD257DDD7CC85F13FB4
-:10CC40008722F9BB1F75F799FD680755AEF07D3E49
-:10CC5000BA1BA37CDDD7CD745F7994D39D80E79513
-:10CC6000CCB7FBFDF14F489C8FF4C3CBF89E7157B6
-:10CC70009A0A505E18EDB0BA908F84C60DA0BFFD21
-:10CC800050E467723E0CC793FEFD2D5FB380694090
-:10CC9000D08F3FCADE94827683D1DFB3BB43E39665
-:10CCA000A4BF5EB9D2ACA25D55C627C971E47C238E
-:10CCB000CDD05F7E30FE6894B3210FFD1D75150E3B
-:10CCC000EAAF077CB7E6533D8F4AED1AF2D02E3714
-:10CCD000BADC4171B0324EA0875837D4A3758EBBF1
-:10CCE000A2519CC468112781FDD879B90FFB19DDC9
-:10CCF0002D90887160A3ABF93B644F28D03E3F185C
-:10CD0000B780F52342F62DCE13FBEDFBDF305F94A9
-:10CD1000A33C1E82EF54A9D7B9445EFA1DED63C946
-:10CD2000BE552078CDF214ED1DA423AFCDF9E70850
-:10CD3000DADF69BDD16E3A59C8F5FF845EDEFFF7D0
-:10CD4000D08B87E3BB17237B9B916E245E249EBB15
-:10CD5000A22389F7903833C2737BDC98E8C7485F19
-:10CD60005DD195A4A751768E77C42BC6A9493A52B6
-:10CD7000AEF077DD4697DBE9BC937464A4838E74D0
-:10CD8000C4E9B2EEFB76EAAF231D05F18FF0F8D7C8
-:10CD9000E9A85945FFD5B5D2CFDDAD6C7C3414156B
-:10CDA000A46A77215D145F71BD86F9B96CCC7824D3
-:10CDB00029593EA18B72EDAFAD96E8103A1B25E8DC
-:10CDC0006C4917F5653DF9EE85ECFF61ACDFBD639D
-:10CDD000FD3785DCF066988C53F138F28606E34621
-:10CDE000971472FA2A4A5149EE28C8E1EF9F330797
-:10CDF00097B35DF017F9F1CD4C3B1A9D82EF947A11
-:10CE0000E97DD2F1DD0CEF930AF9BCC8E0E7BF3948
-:10CE1000E74692CF6FBECA3BD7C373C43DB71496E3
-:10CE2000728DEF907A72483FFCAEEF90F2F76BC7CD
-:10CE300089FD9E24E829CDA5B291B1F89EBB66C6B6
-:10CE4000C3E528BE5F3B00DF79F551FE26E6A7F477
-:10CE50001616203962221C4498BF154458CC1F89ED
-:10CE600098340BEF1C160C2AE88BDF43DED9BB0D80
-:10CE7000E757A96AFFE50C7967EFF03817DD5F3DEA
-:10CE80006C4F233914F7AB25C45EFA069CCF7D6145
-:10CE90007D47E0FCC6F45538BFFBC239FA3A9CDF47
-:10CEA00098BF396B19C376E35DFAB827D9FE1667C8
-:10CEB00001286A5DC3EF96012FF642F8BE19933937
-:10CEC0000EE9E2CD98EBC6E17ADF8CE961E2A9CD0B
-:10CED0004A69EE0B7D3B9393E57E088E379EC63301
-:10CEE000C257C2D3084709DF7F019EB539433AC212
-:10CEF000F32ED423D07E6B7F2F2A2115FD9B9CCF50
-:10CF00005644248BF748DF1EA0A662BCEF089AE7C0
-:10CF1000E89AE1CC8CFE763B87D3A95AE643F89E8B
-:10CF2000C125A0C1DB60DF63E6B1A6D038E83D369D
-:10CF30006D1DE2F5D44695EEEB5F782E8CEC76A76E
-:10CF4000FDDC2E5969D21EC5F272D5B5D68DF2E63A
-:10CF50009B2A7F47F49B23C95322AF815EB7F077AA
-:10CF60000ECAEDE33BC5A7D42F67A57AEEE2F20D1A
-:10CF7000D3FD1E452F1B7F0F42BE4BD995BC3534C8
-:10CF80009CF3BD5E36CEAF257E375A851C00FD0C66
-:10CF9000053E9BF4B370D2B71E8CF7EC463C801E66
-:10CFA00043EF4FB5F58AA4F3E9B0888B1B1DE84F1A
-:10CFB000EFAD1589DF1D785DBCE77E58C4CB3564C5
-:10CFC000682F62FBD75D877BA1FDE106C6FD403778
-:10CFD00039F8FBF9D7AA9F1FCA11FAF90036E09A6F
-:10CFE0007E27A1BB4AF72946B30CF2C317E07C9118
-:10CFF000CFBD31D78CE764C8EF24D0BAFEAFFD4E69
-:10D000000263AD2AAE2BC9A9B0C753AEFD77135446
-:10D01000A157C9DF4F28E2451D7E37E19751453CB6
-:10D020002EDFB1A0D3DF4D4812EF5A33173F37E45C
-:10D03000EF261426E8CF9102E798A34E4AF5769E94
-:10D04000A4ABC48F29B9E2FCB856FC5730C27F7B31
-:10D050009C69371EFF345AEBF733B4CF1774B3B85B
-:10D06000FDAE8E74F09FF6BB285DE1C9F87B2946C2
-:10D070003C197F3F25492D37D33B90024F33E02F9A
-:10D08000E2E906F1FB16E3F0F72DD8BF0F6FC30CF2
-:10D0900078FB82AD1D82EF965E2AE67CBDAB73FF06
-:10D0A0004B9767742EF0BD9B05DF97F61119976BB0
-:10D0B000FCFD24690790F1BABEB11CDFBEE311E4A8
-:10D0C000BFFAA1DA1C89E7CC7113FFBDA4C4EEDA64
-:10D0D00004ECFFEE9C6A05E191C0BC7B16C0FC67C6
-:10D0E000FFC6968CF9D97DF87B912C87FF5E909CCA
-:10D0F000DFEC241ECF352D57E8BB6E1EBF353D97A4
-:10D10000EB01916E27C59917E730113FCB9267E786
-:10D11000227DBE159689F4B79EDB039BF1BDCA6ED6
-:10D12000C1F72A514E47B9B8B7904BEB3EB2DB3945
-:10D130001D32DDF99FEDB7EBE29CFB6F77EAF2B9A8
-:10D140000D09BAFA030FB874E579812C5DF9A06373
-:10D150006E5D7E48D3305DFDEB3EF4E8F2C39B8B01
-:10D1600074F5479CF6EAF249ACF51708DF8772536D
-:10D17000091E7D14612771717CCCFE613CDD5792E4
-:10D18000FA878C7BD7043D1BF59A3E562ED7D725C0
-:10D1900032AEB7DA857ECAF4FA8D26E2D6A55CCF28
-:10D1A0007CFAB87519AFDEAE07093D47EA1321F1E5
-:10D1B000EA1E9CBF8C576FC7BB783FD448AFBF14E3
-:10D1C0007837AEA38F95DFAFABBBD74AF784E4FCCB
-:10D1D0008CF33A20E298B7DA3B7F0F6A472E971319
-:10D1E000BE4EF36ECA857A4F02BB22787618CFDD29
-:10D1F0008CBF3F50F713AB7BB9EBEAE3CD1EC8D72A
-:10D20000330BDFCDCDA1F757E95EA01CF74541DF19
-:10D210009B060A39C530DEEC681E1FC7A2AD74AF8D
-:10D22000A5EBF1385C13AC6C05BD5B25EE79DCB584
-:10D23000B6E1412C9A65ADB7F08707FC16B4A34D53
-:10D24000180B72621EE886CF2C7AC40172D1933516
-:10D2500066B28B05769DB8DDD737786FA70FE86982
-:10D2600048271310FFD0EFD0813C8EBC2597AFAF7D
-:10D2700050FDA6FDBE854DC7FF19F1FF4EE88EE8B3
-:10D2800051AEE37FEBFE85A45F239CA45ECEC4B9C0
-:10D29000D657CC4BC24FEE0B093F79FFC5758FC5F2
-:10D2A000BBD941F7688A302E4FE2EFA681DC6E1FB2
-:10D2B00087B260775E0FF95157F50AD59C68F4176D
-:10D2C000B43157B4F32A76F3FFA57B2904FFAEEE01
-:10D2D000D375C5273AF0872EEED775459FF4E71A28
-:10D2E000EED985F0091E2F25F0E1EF6BA2B884D5A9
-:10D2F00091FA7D5C3080F38753621FC3F9EDC8D388
-:10D30000F30986FE8FBA95AAE0130BDA7F6F04BF8C
-:10D31000CF5F6921B99B31EFA318A7F197F5167A72
-:10D32000E771B487917C3367A3E2DFA4047FE7ABA6
-:10D33000D86778A745FD86E4C32FD62A4EFCBD8862
-:10D34000B96BF4E50B1DFC774AE61BDFAB91FEB829
-:10D35000ABE8F5830788F3DDCDDC249789388A12A2
-:10D3600051C72897B5F9B9BF11F57295DBB128FE01
-:10D370004E9EFB2EF47785BCC302700DCFC2737C2A
-:10D3800085B9D3B8C876B87611F771DE21E23E1CB4
-:10D390003CCEA56D6F18F70F4B3F9CA87FDE7799A9
-:10D3A000CAB13EF676218FC7AF48FF9BD1BFD7E603
-:10D3B00030917FAA6D6F24C539A0DF2B1AE8E1AC4C
-:10D3C000694FFCB094E0FCB46655E73732A6DAB298
-:10D3D0007DA44F2EEFABCD1E8071FA66B7DD0DF93F
-:10D3E000FB1C87E91DAF09C20E669C6FFBEFFE8D2B
-:10D3F000E4EFEAB4F9B8BCDB56C4DF3B01FEC87009
-:10D400003FC9788EC90CA43B488B03C3693ED7EA59
-:10D41000FF9A7A258FFB7FAF8CA0F6DA9AE194EF22
-:10D42000B3E2C17BF09ED16D750B2D180AD0FC8B39
-:10D43000A585E1D0B4B9B77F7938E26D8CD2A9FF68
-:10D44000A276003F5F9A0DF716647A49EC1BC7403D
-:10D4500026F89388E75AA6D07E58AC3019DF45FCF1
-:10D460005CE62FD78B7C21CF2F59C9F3CDE27715FE
-:10D47000B6097B0BAE1B535C37DA05760A7B0CAE24
-:10D480001B535C377E47FE8579E45F9847FE8579BC
-:10D49000E45F9822FFC2EF739837394FE57EBB7186
-:10D4A00021FB03FD76E342E423F4DB85E6D16F172D
-:10D4B0005A1FFD76A1E5E8B70B2D47BF5D681EFD3D
-:10D4C00076A1F5D16F179A67C36E0AE691DF7926C8
-:10D4D000EBF25341FE1F17B2BFD16F17DA3FFAEDDF
-:10D4E00074FD69F7E8DADFC96A74EDD16F175AFF86
-:10D4F000EE1A45E7D7BB5BBC433B77431CD14F7962
-:10D500008AB711E9FEBF22BEFDBE05F545B5711112
-:10D51000D7DBC2DD1CCFF5451CEF267ECF42699DCF
-:10D5200049785E6AE5F9421EE76DA41FF48B8DB35E
-:10D5300070BF18A6E817C314FD6298A25F6C5C3A2E
-:10D54000F78B618A7E31FC8E7E314CD12F8629FA91
-:10D55000C53045BF18A6E817C314FD62D80EFD629A
-:10D5600098A25F0CBFA35F0C53F48BE1F7E3E89F35
-:10D57000B304E785F27C5F9D5E0974A8D32B9DBA46
-:10D580003CCAF3A1F5519E0F2D47793EB41CE5F935
-:10D59000D03CCAF3A1F5519E0FCDFF2DD745FB0C12
-:10D5A000E5FAD07628D787E673EB7DAFA2ED6CE283
-:10D5B000C68B47316D8E549E548065FC7DF78FA6D7
-:10D5C000A3FFB2394C498E01CE69517CD3C7415E6D
-:10D5D0001371940358AB897EAF0F95478C73083055
-:10D5E0008A5BCDFD3A91CAA3329DED71CB88F7BC21
-:10D5F000BD8C7E8F46FAD7657B3773AA98CAFAC16D
-:10D600007CE7F58CE3CB7AC43F43E68137AD31DE6E
-:10D61000276FA9231FE366B789DFCBDDB69CC75B05
-:10D620001BE92A4FC84BDB4C7B0EE37D9AD6628503
-:10D63000EE5D6798D9314B3EC2A93A1FE588C48197
-:10D6400031625DD5D7E3EF8EC9794B3B28F009BA3B
-:10D650009F38B2B5A9201AFAD17C63E8F771265831
-:10D66000B9FC80ED50AFECEF533C9B43E83B4DC819
-:10D67000E39A8F8FFFCC539378BB70DEEE99A7A20D
-:10D68000088E9356281477367227F3E03DE81C3154
-:10D69000EFFE3B032A8E57BC828F27FB2DDE984C72
-:10D6A000F7428B59F338BCD7C2062B0CF9B6841B52
-:10D6B000ACEF28AE2F03B60ADAB1BFEB7DAA5183D7
-:10D6C000630A311E9135327A5774E2E0DFEBD64BB4
-:10D6D000681F4AFDD2B996E953E81DE749BE65CBFC
-:10D6E000F1589FE8BBE7D5EE587F0B73A7B8E82841
-:10D6F000A2FBC7723EFD3C7B4C702CB21CD6640A68
-:10D700005310DFEC485C08FDC0CE9F86F8CE735BFB
-:10D71000E85DE5C966A785DEE9E8225EE7B243C6B3
-:10D72000EB18E405435C4EDDD20F93D1DEBC38D25A
-:10D73000447693C5FB22486ED03628C4D7A41C5427
-:10D740002CE2FD2EAF78B5FB7484FB1E0BF527E3AE
-:10D75000752AD2FCC926BC9FD073D3805895E4802B
-:10D76000BB07A21CE07BFEF661586F257F57F4F2E1
-:10D770008A7DFC7749857F47FECEE93C11FF559CA9
-:10D78000EB8DC67818F97B6AF29E8CFC1D5369E715
-:10D79000297E7BD06B88DFE227C4BBDF6B8AE9FE82
-:10D7A000BB31EEAA4CC87F8B5658286E6B91413E18
-:10D7B0002C13715957FB7DD39A8106F950FE4E8E7A
-:10D7C000A8C3D45E7F40BBB0BCF739CBC2F9C0ACB4
-:10D7D0003D8CFC55B3961598F0BD6AB68FD3CFAC8F
-:10D7E000655CCE99F5A287EE6F4AB9F11D21CF4C49
-:10D7F000B99244F07F4FC82FB761BC2AC0794273F9
-:10D800009888634BA474FA151EBF3AC5C1F941F359
-:10D810002BFCDD8D369F8DCB5547197F37CE409F32
-:10D8200093CD7E135E68748F04FA84FC449487A0C1
-:10D83000BF19281FC521BDA714523C649142F78827
-:10D840008CF43EC152FD2AC6DB4ED8CADC3E164AD5
-:10D85000EF40C7D89F4FA1F71834A1E74A3A36D214
-:10D86000FDEC08619F7270FB53BB9D0265557A44C5
-:10D87000FD83E9184F3C1B6D863D69191E8CDB8BBF
-:10D88000CCE1E5CF0DFC60FA0ABCFBD185DD42FDA1
-:10D890009195E0A1C97727BAB023A0FD00F9E55D15
-:10D8A000DFCBB3CE09E197CBF3C6BEEBEE1EC4F7D8
-:10D8B0001CC37DCAC5F7A5D3EF1F752517CF05B8C3
-:10D8C000E2FE981DDDFC7DA054F6FB81CC332E01D9
-:10D8D0007F5F52AE8F05301EF30E91FFF6D77FFFAC
-:10D8E000E31A07C185F26F0FFC743ABE3B57616FB4
-:10D8F0001E8F645795535D84F1D9413EA5799252AC
-:10D90000904FE505F0F7F80EC87BE006FBC4B703BF
-:10D910005DDCFF62B053CCCDE1FC9B89F7C64FDCE8
-:10D92000F7C26E3CB7E4FC4F58F4F76A65FAE5407D
-:10D93000D3BFF55E89F13EC94F93B453C83F1E353E
-:10D94000F1F7137AAAF54CD88BC8AF2CF90613EF70
-:10D950008E04F1EEB1F2B804C5196AAFD2D628FC34
-:10D96000BD822EEC3A2CABF5175BA1DDEC5A2BFDFA
-:10D970009EE353199C7E9E02FA41F96C96B5E955D7
-:10D980007B4A108E9FD4FCDCC2F958201DDF3BBAC5
-:10D99000A33ACC8D7C79799EF7EF38EF881C37F16C
-:10D9A000A377DD9CBEAEEBEE656EBCCFB8F6D09330
-:10D9B000F87EC3FF037EDA89FC00800000000000CF
-:10D9C0001F8B080000000000000BED7D0B7454D588
-:10D9D000D5F0B973672693CC244C42200F489800A9
-:10D9E000911401270981800837C82358C081100588
-:10D9F0004DC28467B46023D51A2D2D03493020DA37
-:10DA000080C120F53150A5685163B56DA8D80EE2EC
-:10DA1000BB682948F5FBDB86E18D8FD608B5DAFFB8
-:10DA2000E7ABDFDEFB9C93B9F7662680DAF5757508
-:10DA3000FDE3721DCE3DE79EC73EFBBDF7B9F9F68B
-:10DA40009E1CBB7F1863D5EDF96BD33D8CADC9F738
-:10DA5000DBBC7DA0EE72DB7D2EC66E6948B67BA076
-:10DA6000AC4A63B56DD08FB1CEECD9898C7D81BFC6
-:10DA7000098C657915C6A0FF1FF2A1A988B18F6D29
-:10DA80006C2EEFD76C9B65E867A17EACB95573F43B
-:10DA900065CCCFF82FCBCA029602C606D8FD4C4BF8
-:10DAA00065AC3E8379D7E430D60F9EC715F0F6F803
-:10DAB00014E8EFB21F5592E085C0642D9CC7DFFDCE
-:10DAC00062206376C6340BB4F783D20EFDDB877811
-:10DAD000689E2C6857E1B92DEFD83C06FD2AEC6C06
-:10DAE0003EEE47AE479633C5FAD95C8785C1BA1674
-:10DAF0003BE0DF30C46475D894B4918CADD8A8B83D
-:10DB0000E3E0D12297E7FA31505FF4BA8DAD81FAA4
-:10DB1000F4148F3D03EA9DEB14F776A82FB82DDFA0
-:10DB2000EE817D57C03619AC63D19631CCD31BCA78
-:10DB3000209485DDE795E58D1BF765ED86F958485E
-:10DB4000B3FB005E8BDC9A3D6558A47D61B3A205F2
-:10DB50005DDDEBE3BD2AADBB82B14908BFCADB7214
-:10DB6000EC0B5C587FDDB66218EE8BC341BE07FD3F
-:10DB700042D86FFA40F62AC375C3BEB6E7F0F90A79
-:10DB800074E32FC0F175F343FFF93EA8977A136948
-:10DB9000BC6A37EC3B074B37AD13E04070EABC176B
-:10DBA000C6F3D03C741E0B43419B17D7638579A104
-:10DBB0007E833B68C3791634E4DB1994FE0D7C1E2A
-:10DBC0007F53B27D38D4ABAD6E7B16C22F0160910E
-:10DBD0004AEB0B6E87A35904704971E13C6CFE6CF3
-:10DBE0005777F8548BF52E6A4EB62F363CDF68C354
-:10DBF000F39807EB698B72EE77E1B917E17A4AEC9B
-:10DC00000CDFB76A762FAE47C0F7E4ADF1EB592FC2
-:10DC100078BFA5D59603F59B05FEDE85702D42B82D
-:10DC2000847215DCF7ADF15E5CE73C7733EDAF0B4A
-:10DC3000BE9B011EF07CB1DB47F005BC083080C301
-:10DC4000A216E37946D69348E32E6AA9267A5B6248
-:10DC5000F5DBDDFA756CD99BAB005CE6D5C67B15B0
-:10DC6000803F73FBB3115F4E6DBE3E9BF609EB44E4
-:10DC7000B8267A3D53D247129E101E4B7CA92AE447
-:10DC8000F42BE7DBE4B5D27C9B705F453DD1A5F674
-:10DC90006A3AD2259CEF1A4F6CBAB433180FE6B526
-:10DCA0002F5282F54A773A95F429E952D2A9A4DF96
-:10DCB000476CBE50BA12E13355BD58EDCFA2C0E952
-:10DCC000A038871BC4B9025C5F46B8CAF617043D8A
-:10DCD000570C34D23B8E87E3FE449C7BC5C450EE88
-:10DCE000ADC322FDE5BC1529FC3DC47BC4B79F082C
-:10DCF000F860FF15D4DF62E0170BBBF8C5AEC6BEF7
-:10DD0000C82F9E55BCC82F56DCBB2FEB0E80DB8A7C
-:10DD1000A79C5E84C187CB1EBF2503E0C0AC413AFF
-:10DD200037B9AEC59FE7139F58F2F9959C5F84A25F
-:10DD3000F30B579EBFDD5B14A92FBAFFA9CBFC9C48
-:10DD4000DF8490DFFCE9A9170E8F453EC28236DFE3
-:10DD5000F0C87E1634FDDE56EDD2C38FEF777DDE40
-:10DD6000D96A3CAF852EBB4785470B1BAA89FFB2FA
-:10DD700074E6CD5522E76FC68BEA0645A3F7EA465F
-:10DD800005D5AF914F2FDC300BDE8D9C1B4CCCD8D2
-:10DD900028D827E3F095EBFFA3587F87E06F37087B
-:10DDA000FCBEA1A6C49E918AFBAD2E04CEC8E68916
-:10DDB000E7F316199F779D9BBB8BCFAF457A39DB75
-:10DDC000C6CFEDEC061BF19FB3BB12830CF6F7E157
-:10DDD0008A5FBE7D1DF4FBE0816DD94C359E1B2B07
-:10DDE000E4E786E5523837D63BEAB97DECD5F1E178
-:10DDF000A58FF2735BF8F45B7FFE9587F6CBF9DDB8
-:10DE0000BD7141E4C70BDA9EA5739CD7B4D196834C
-:10DE1000F4EACD21FCEBE2FFB5F96E06F0BDA16995
-:10DE20009B0DF9C417120E267A8052633A3A43B911
-:10DE3000A4A420FE853310FF647FE48FCFC23CB7DB
-:10DE4000DD1A9FC4AE88CC9397CFF17E616D720AC4
-:10DE5000CEB7B0B6FA3E3622220FCCFB3C1ECFE93D
-:10DE600065018C87747BBCC49BBD82F0D31255EED8
-:10DE70000EC8E7E7F82300773CE0433F67DB130871
-:10DE8000877EDF4EF022FF183C381CC47911BF7129
-:10DE9000DD76E09F0EE8377859F8135CC760C03034
-:10DEA0007C0FCBC4142A595FA86F8765174339507C
-:10DEB000E5E5E47CBE7F680F613B4B0D17E1FE2575
-:10DEC0007E9BF1D7CE1E6B1A887C2C9579EB3D1189
-:10DED0007C95E3487C95F81C6B7F575DE4FE8EE7EC
-:10DEE0007078DA13607F2997B03F40D6E294C8BEBD
-:10DEF000E4FA581EAC0BE6A9FADEF06DEB619EE386
-:10DF0000ABBDD9B5AE9EF6DB32B96F94FD9AF72959
-:10DF1000E9669183D334D04DAF30ACFB6CF3A05E97
-:10DF200028778E2B20DFE0BDE3B7C65B70FD725F04
-:10DF30003B56416758EBCE550E2A9F5C05843784CB
-:10DF4000B15DABD2A9FEF42A0F956DABF2E87975FD
-:10DF50007E0A97472C9C887A26E8039C1F84389D6C
-:10DF600074D40DA27DC9E7522FE87087135374FC57
-:10DF7000FB44AD909B2C7C2FD237AB1BC41E87A9D2
-:10DF80003A9A8F275A86217EF2F5C9F76EB3751239
-:10DF90003F648976CFE34072CEDB7E3F390DE65B8E
-:10DFA000DC9293AFC07B9575851D75D05ED990E6E8
-:10DFB00045BEB1D8E5598B72717120C78B72D1D92A
-:10DFC000927F6A0BB42F6EB8DC8BFD6F53980FE90C
-:10DFD0000BF82743B82D615D3FCD017C6DA9E06B47
-:10DFE0004B915F02BC96D4ED1BEC86F79778E3F378
-:10DFF00051BE2FDDA284E290DE2CAC4941395CEFAA
-:10E000009B827CACF341C58BFA267B08F8AB23C21C
-:10E010005F37E4F956E6E3F99F07FC83F187A20C2A
-:10E0200056715F6D1AEE83813EF238C375FB48AFBF
-:10E03000FF7F428FE968399AE819C6E18DFA3AF311
-:10E040006B16E4BB2B845C1B60EF3C7A37EA3389A8
-:10E0500016EF76CE2F7FE7C17DBEA1B2389237A2F0
-:10E06000BFE0A7037E50EC40FEB62271601AE9556E
-:10E070005B54E28F127F6AC49A176F2BEB8B78B3D5
-:10E0800018DA51DE6DC587C042D7B65CDD17F16A7C
-:10E09000D1C6C90F04408E650B389EB08667E1F982
-:10E0A0009CD99696B21AF5C2E5F59731685FB4ED42
-:10E0B000EE6C2CCF6C8B9F8BFC7E927BD6A464D8AD
-:10E0C000EF928792F3559DDCF8A9A0C79B975F9DBF
-:10E0D00086F6C0B27FEE7BC43D08E6075823DC3FDE
-:10E0E0006D730603D065D9AAF66C1568ECF338FF9A
-:10E0F0000E84E7B72C7BAE1B83FC5F09EEC8A0FE45
-:10E100009E3477147A97E529C0770FE0F3F21FBCAD
-:10E1100047E3FCC5B27FE63C787FD9F2E792709C7A
-:10E120006F6D3E34CA0DCFD70CF6FF0CC7FF40D938
-:10E13000B6C38D8269CBB61128B79F1376D4F41479
-:10E14000DF75F310EE6FA804F758F3D5B42B045F16
-:10E1500059AF0CF6227DD61F627637966E46FAF2DC
-:10E160001995D5A13E20F51AF9FCD57CAE0F9DE995
-:10E17000D59C8D7871D38ED66C942BEF27F27AC50F
-:10E180008EEBDF443EE57F2C8EEBED56467AF2C2F5
-:10E1900000D7BB590DD06B4664FE03F94E82F34D98
-:10E1A0005B0A0DF210F4129AE77D2B2BC5750CA8B3
-:10E1B000EFCC47FDEB8FD6D0623CD73F825E1BC8C9
-:10E1C000C173E27CEC8FCDEA147C1E0042427DE4F8
-:10E1D0008FCDCF250E7645F4B8C4916D21E473CB75
-:10E1E0009F4F2E50394A117EDDE296FCC935A55F5E
-:10E1F0002AE9636EC4D315BB5F99C2781D04616CB4
-:10E2000078DE2CF4B0AEFAF3CF925DB76C17D72757
-:10E2100096B53DFB6A268C734BBBD027849EB25CBF
-:10E22000D0F32DCF73B82C7FFEA87DA1DE1EC94B85
-:10E2300059DB0F34C173F9B6B99B518FC2731BCB35
-:10E240005842DBE7735783EA9CE07573FE6DED245B
-:10E25000FD707DDE41B2CB973788F1F20EAE1D48DE
-:10E26000FB9DD55BAF0FFD2DDF467095EF033CE8BE
-:10E27000BDCFE2934620FF0B2D4F6842B9AEDDE2E1
-:10E28000B26259BFDC4572FEA15A4B9E15E0AB2924
-:10E29000095ED4E3EA1CBCFF1D0949DBB1DC93C075
-:10E2A000EB9FC567939CFACCE27B7609F4BB433DB8
-:10E2B00010CF06E19177EEB3403DA38FDF5900F315
-:10E2C000A731A01E15E54748C1F68F5F3C5D88EB7E
-:10E2D000183F207C8EC1D26C4ADCBC49A82215882C
-:10E2E0007D0E0B1722BEF77989F3EB876DAC09E53C
-:10E2F0001DB3FAD86C781E42FE85E7FF0F4B10F96C
-:10E30000F11E25F463BDFE555AC0F1D617E76A52D7
-:10E31000609D6539FEFEB88E6B15DB70545D9847C5
-:10E32000CDC5F13FB6F176A9C74E144C384BD86332
-:10E33000F6CC7417EEAF5EC04BD1345607EB5833B2
-:10E34000ECA585882FF7743A581CCC3FB13381F483
-:10E35000DAACCC52926FF5022E8A2715650E7B69D6
-:10E3600098251007EBBD873982D89F394CFAAF2525
-:10E370005EC3F7943DAFFD03F97D3FF5937DBDA0EE
-:10E380007FBF3B146F3DF4A93A7BEAE1DF31B49FD4
-:10E3900083F908BFB97DFCA30A50CF3D5B7AD40F47
-:10E3A000E77D8FBBCDE11DC6C7D3EF63CF9DFF488F
-:10E3B0004AB144D6F771E7A9A77E39124B07C9A124
-:10E3C000897B549223E6F57C9CEEB1D239753A42B2
-:10E3D00016ECEFB2041505FBEF7B0FD737D1E10A3E
-:10E3E000A9A8C73B6C1FE9E50C3B90957CEA72122B
-:10E3F0002DEC0B5016FAD6F3F31BDFCB685FDE581B
-:10E40000C0EDA41B0B38DF95F09570631E8DE9E518
-:10E41000CCAF5D3B2A992542C7DF16CFCF7E3E9019
-:10E42000F48BB37B40CF88A277CAF210EA19A857C1
-:10E430000CD416161445E46CB994BA420EAB62DCE7
-:10E440007201AF729785C3678E093E026FCC786107
-:10E450003E77799EECAE03AFF4CAA1731CFE43462F
-:10E46000E7770BAEA3E31FFB1B81DC58A6AA1DF5C3
-:10E47000E7FC3B9E5F287E08EA159B2DA457A0DE93
-:10E48000877AA2E41F7EE40357D073AE07E631E239
-:10E490001B556A82777D14BE21F9853F01CA11C8D8
-:10E4A000379A891FDCA176BE6251227C624069786E
-:10E4B00038CAE10E30FDB13D6C69A3E7CF170C24DB
-:10E4C0007CE9CF0E64E073B0578A500F541D3F7E35
-:10E4D000F804889496759C3EEA6DC10797207F28C2
-:10E4E000777951AFFB386809D8609D2DC99C6FB40E
-:10E4F000DC9449F2FC6326F8C85C3BF1912B2D9625
-:10E5000000D95BF332C9DEEAEA9FEB09A2FCF9C548
-:10E510003FD5CBB660FB2C07C9DD1694C7506FB949
-:10E520007738B5BF20F9D24D9C2FB5CCD23212B07E
-:10E530007D565F0BCED792EA7F1AE936530D3E1116
-:10E540008FFAE4B712D8E3F83C47CB4079FB80E27E
-:10E550009BB718DF1FCED71D9E97F0F40E7E3C218F
-:10E56000F42775D4256E5FAF934FED4338BF1C1071
-:10E5700038FA20C22B3091E5A13EDF81F87945E4DD
-:10E58000BCC02A67752991734B359D9BC4D7800DFC
-:10E59000CE2F959FDF1A25F6F9A58AF353EA00BF1F
-:10E5A00089FFF3F3B943E5FC9DFD1A1448284FF4A5
-:10E5B000F1EF473CAFBF15CE850462F87684D7C330
-:10E5C00077266AB88F0E0BAB698B42B7EF1608BF80
-:10E5D000134A63A087F9821EE64BBC5D69C2DB70FB
-:10E5E000FFE4534E81B7F0FECF9DBEFFC279FFA27C
-:10E5F0001C1A850FF7FFB73A37DA3CC7849C78C1FD
-:10E60000E13F4A7CC13AD1A0AFEECF3F9D85728AEF
-:10E610009DDFD71FE5EEAE54DF093CBFF8C19D7604
-:10E62000F447746474DA709F1DF33EC842BD687E7F
-:10E63000DD6B445F17BBCE35CE11361C3FB934DFDE
-:10E640001686F7D34AF35F41FC393823CE131745BA
-:10E650000FD93B637416EABF87A68DCE427E77083A
-:10E660000EF000DA11566F22F241D65E497C6CB68C
-:10E6700098F35069217F2EF866E479598FFCF243B4
-:10E68000E09721D053DF07BB0CCBD3609785807F09
-:10E690009E04BB0CCBE36097E1F3A36097617964C0
-:10E6A00095979E1F2A1DD41E467DB959213B68A10E
-:10E6B000D56B8FA60F2FDBA5B290E457F0FFCD8F5F
-:10E6C000390DF59A877A1BEA4B5A40737044EA8BEE
-:10E6D000360C32D4A5FEB8A0E172C373FFCA424320
-:10E6E000FD3F16DE4D1CDEE827FF778237FE360041
-:10E6F0001CCAF01F80FF878AA6DA508E5B1D2CE0B3
-:10E70000047E928C7406EBB7CE51B85E04BF66A04F
-:10E71000BFD9F80FA02BAB8BB737CC5382C88F5023
-:10E7200017427B02E01A72027D95B92F3B89FCE803
-:10E730007AE45C2ADAF3412A6F6421A2CB4A16A656
-:10E74000FA7CD6996D87F21635B416FD76AF39FC92
-:10E75000558540C77F9FF6FB0E0589D15B3D04E9D7
-:10E760009BB952C8CE8C754EC021B97E8A5D47894F
-:10E770007DC16F0EF27D78EFA073C4EDB7C3397C15
-:10E780005C1D1E85F32F73F81F4DB5D07CCB0A910D
-:10E790001FD9FC437AC3F3B78A466721FF60BE3EA8
-:10E7A00006FB28D67C1B71B30087EA52809382F166
-:10E7B000370E9713E51C2E7B37C6D9D18F71629D1A
-:10E7C0008DFC94ADCEEC6CC4DB138D53B311EF56BE
-:10E7D0006F1C928DF83EBB69EAFBC8B727ABD3AB81
-:10E7E000F0FD63CD1CEF19BB95F4ADDBC5D91DF36E
-:10E7F000306F08DACBA7257A03B01F7F202789D690
-:10E80000CB34573EF45B28F6BDB079E9741C4FEE6B
-:10E810007FC18638C3F95F5B6CAC97337B04CF72E2
-:10E82000F09CED91763C7FB5A297BF07FBB9EE4F08
-:10E83000DBDE7C5937DE038589A9A8AFB0D16CF443
-:10E84000176AE4FD5870FD6C55F0CD9773237095F1
-:10E85000F8746BA1EF513C1F784C7136A0259203E0
-:10E86000B774F9B3F62421FC363A7F7DDF9508971B
-:10E8700077B87FA3D55945FCE3C369004758FFDE4D
-:10E8800069D76785757C41BE1F46FA067A3DFCD480
-:10E89000F5C447F695A7511CE6E0F3DCAF7C44D005
-:10E8A000FDC139D757DE0EF2F1E02E95F4BB83EDB2
-:10E8B000E75E41FFCCC136C52B406ED18F7BB07D6A
-:10E8C000D0BD23A1FD539F8DDAF7EE7A8ED669DE97
-:10E8D000F7FB62FED3380FF11537CD775CF097A3C5
-:10E8E000C85F86E03AF2A83C88FC05DAE7EC06FE51
-:10E8F00082E36FE1F32FB6FA88BF30FF5CC3FEBA44
-:10E90000ECE1C754C379D73CE434F115239F59B4E3
-:10E91000A19FA1BEA06190A1EE5F69E42F65A585CE
-:10E9200086F6C3368EA7070FABE4676301ED405E42
-:10E930005F1D7E9672FC5C5D1E47F472781AE733A9
-:10E94000B3E7001DA07ECF3C45684B7ED85ED6075E
-:10E95000CF856DB01D433DDA0DFFA1BC36C3B19C20
-:10E96000598F8575F8BBEC79E8AF5BDF6C6CD7E14C
-:10E97000B3195F3F427C7546F0F553763EDB3E901F
-:10E98000B71FE81BE17BF8D3F317C9B724FE02DFFA
-:10E99000AA42BE067CE533E463DF2DC87931ACE8DA
-:10E9A000F8CA45F2B18DCE7F921C6C75FE93F0F8DB
-:10E9B00050B9C0E3F22184C707670CC92279169CBD
-:10E9C0004BF4305FD847076DBE44F48F1E5ED93BD1
-:10E9D00009DB8F369411DD497A32CF7744E09FEC22
-:10E9E00037DFDA69F3469187FE9546FC613BE71213
-:10E9F000BEDF6EC2B358E39BFBCB79E69BE2BCE67D
-:10EA000079868C14FA665BE545CD8764D8F53EE9D6
-:10EA1000B50911BC54910F7C9618267B9CD349B93B
-:10EA200080DB91D2D189A447CC39472513F4DCD5BA
-:10EA30003EE7DC5BA391DE4A6D82DE6BE8FD32D1FE
-:10EA40006E5EC769A1379C14FCE3B8A06BD9AE6EAB
-:10EA50006BEC7B03E2FD4AD58BFCEAF0F442C2F397
-:10EA600033C1729AFFC81C95FC4CD3460EB801FD09
-:10EA70004C723D72BEB219E712D18FF629C00BFD60
-:10EA80006265366F9F68FA85191EB1C695F8B3772F
-:10EA9000DA90C3B8CF43C847B1D56F84D3217C1F68
-:10EAA000DA676F5329CE6686D3BE6943882F1DD996
-:10EAB00029F827C015F5EF9A878CE7BAA4C569E253
-:10EAC00037BD0DEDB3CBB95E26F9B55CDFA19583FB
-:10EAD000FA30D7C59FB71CE762F1E566F13E8ACDF3
-:10EAE0002F48FEA618C6030BD134DF4053FB50530A
-:10EAF0007B81B17E91787C54E08F943F47E3BD9554
-:10EB0000D1E27747AE89ABD1E7256C1AC9FD369BB8
-:10EB1000468A78F725CAED7B471AF9E085DE977CAF
-:10EB20006F61A1AF6524D269A88CE2D817CBE774D6
-:10EB300072FEA191B8DEB062C7F7A55E5523F4CF8F
-:10EB400056E77DAF22DEFD45D8037B67C4111EFE6C
-:10EB5000F529AE77FDF5E7A7499FDAB7FB8EA4B09C
-:10EB60000E6F9609BC39DD3E2409F1F0585B7D92A9
-:10EB70009EBE65FB19783E7664445EC75AF7979649
-:10EB8000D7CF0A7B602797D737599BA3DA03FF6A51
-:10EB9000393D595D497A88595E9FF67892DC041FA9
-:10EBA000417742AEC8B8CF5F6D9E24F4171E0B723A
-:10EBB000B922F9FA41131C4E201CE222F224161C41
-:10EBC0008F8BF7651DEC511BCE5FE6F0BE928AFE7F
-:10EBD000970D8A17E35E989E520CE77C604EFE8F7D
-:10EBE000D16F25FBCF2F52492EC8793EDAACB4A1A4
-:10EBF000DFEFB595FBB2BF07FDAB773989AFCAFE32
-:10EC00008BA61BED2CB33CFAA8F193B746C3BC65A9
-:10EC1000CDAAD701EF954D2FE9C3F56AB7118F043F
-:10EC20005D9ADF5F6AAD8D7A9E66BE57367D35E9A7
-:10EC3000EB87C47A0FED1D63F324767FAFCCCAE176
-:10EC4000B014F4CDD530EFD2864F48FE2C9DAE7A6D
-:10EC5000512D79ADA97E26E2FF519FCD82F471A49A
-:10EC6000ADF74C8453608EEACD85FEFB9B06111DEB
-:10EC70001C6BBABA2FCED74BC0EB747B9C05FD4FF3
-:10EC8000A77D3616227B3944E7F9514319D9C7A726
-:10EC9000114E78FE5637D149BF22EEC73A0AE370CB
-:10ECA000FBD9C3F4F1C02341B53418852FF513F314
-:10ECB0001D3FFF43C2AB5783FB08EF8EB6F1798E41
-:10ECC000AF7427619CEBB70D85248F8F4D87F1A121
-:10ECD000DCBB7BE97D98AF777A834AF2E374FBF57E
-:10ECE00033B17E688394BB5C1E558BF957EF1E3D94
-:10ECF000A318DA3FFAB98C6B72BA5E20DAAF9E7550
-:10ED0000F8BE62BD3CDB35D7B0FEC3C1E3646F9D86
-:10ED10006E80B7018ED53306D9D11E5EB4CB786E26
-:10ED2000E51B8C74083F577EDF489ECBA206D06758
-:10ED300081651D9D5E4676F4EC406F93BD6DB4E336
-:10ED4000CADBB8BDB7E0E1B2A210D269E0131B9EE6
-:10ED50005375739C619ED92B8D76DA02935D66B6EE
-:10ED6000DBCCF245C263B9ACB755D23ACC7A4B375B
-:10ED70007963ABAD8A961F5155C4F5B16AA0CB74C7
-:10ED8000F42B33EF0CB4BB8E017CD7C378D576F768
-:10ED9000DF73414F3EA2B2F1E44CF30658B1F41BCD
-:10EDA000E8E65BD0A09AFC1346F882BE7E0AF5F92D
-:10EDB000A6DE420E0740AE24A29CD1FC4528272E99
-:10EDC000D61F70D1FA7695D0B7AB0CFAF641ECA20B
-:10EDD0007B7F6FF9F5E4773A3CE37AD2BF0F77F99E
-:10EDE0009D7C06BF9384EFE1E965067D52F7BC1771
-:10EDF000EB813FC6D21F8F0AFE7A44F89DD60A39AE
-:10EE0000D320E4CCE1E9C22E4C65442F56ABC62E8C
-:10EE1000862F5D481F5BD0D0CF745E4639E32CF15E
-:10EE2000B716015EC4A50F353CB7B90B8C7463C22D
-:10EE3000CF7E8CFBC1EF46DB1EE05E5FCEF347F179
-:10EE400039E6B148BC64D01FE573F986A1C1F5BCB1
-:10EE50003DA01660DA1B43158DFA5B795D53783D52
-:10EE6000E012EDAAC85FB341FD688E772EEA519893
-:10EE70009FE34CE1ED8822FD009F935222F88FFE24
-:10EE8000F9781E220F24C17BFDE7E4BC8CF48D7958
-:10EE90003B9741FD5745398437E9E89A2FA0F14364
-:10EEA000989F13AE9F40745CE648E2717690B33D44
-:10EEB000E3DF6A6EDF94F6A6C9FA5BF97A62E2B321
-:10EEC000E877097AD56B442FCC42FE938DCE11366C
-:10EED000C4DFD92E5F16C201F0BDF276B4D35FB4A1
-:10EEE00093BCDC5BCEFDAA07A78D7EF836783EE2A8
-:10EEF000191791F1C1C580E724173A13F5787B649F
-:10EF0000E5710BE6D3FCA19D79311FF1C8AE8A579C
-:10EF1000DE8471F6AD5C786F11D2D17ECEC7CDFEA6
-:10EF2000D89267C6913CBB6E864A79DA874A55C645
-:10EF3000F97C82C1AE88F86955C28F4FF758A91D78
-:10EF4000F3AAF2308F0AFD95986F552ACE45E81541
-:10EF50006DE21C9F10FEDA1D826E5A04DD6C127485
-:10EF6000B3CEECAF7D88D3CDA1763004404EFE6E9B
-:10EF7000FAC289E487DEC2289E9C334D5D3F12F6BB
-:10EF800077799CD786F02B999ECFE13947B1601CE9
-:10EF9000A6AC34DF86F47E796F8FCD477AD62CAA63
-:10EFA0004F9A934376FBDE95658964BF277AB390C9
-:10EFB0002E074F8F0B5992D00E2C243E71E5198BE2
-:10EFC000815EF2430906BA1BFA588AA17DC8964CA5
-:10EFD00043BD8F6FA0A17FEF52233D260C2E30C979
-:10EFE00025AEE749384F56C791DFEA48445E52BB29
-:10EFF000B4EFA4FF4DF6076819F85A93D0074740BD
-:10F000001DF3E2D6CDA97760FEC3A76D562F1FBFB3
-:10F0100082E4BD23E77907D2098648314FAA49CA5D
-:10F020001FE18F671A33AD6B03C378E9915246F83D
-:10F03000143F9829182F6811E77DBF9817F86A893F
-:10F040008DFC6EFC1C7B4FF7513FE633DAA9E94893
-:10F0500067058827FCFD27C4FB3B04BE1C29FDF186
-:10F060009A04C487B98CFCF793D5656B302E78640D
-:10F070003A233A690BBD9480EBC77130CFEF57B19B
-:10F08000C699F3DC1F6FC1F5ECB4D338658F815C92
-:10F09000043C197AEDD10FDE46F06D71EF8B67DD20
-:10F0A000F5E9118F695E044EDE1916B25119D2903E
-:10F0B000FFE49D39A0615C6FE85F777EF034C3792F
-:10F0C000B95C6812F86DE6AF3F7DFC170BD663B9EB
-:10F0D000636BC17B507E63CD839975503EB1E65B17
-:10F0E0005B6FF344FC9F3B662EDDDE02F521DFFC07
-:10F0F000FE93CF235ECDFCFEFF791ED73BF31F7F2F
-:10F1000076C1FA2FAB4F6448DF727DE679D259930E
-:10F1100082F14DE4A3C497AD01AA57078C7A7759C1
-:10F12000A9D3807FD8DF0AF02BABFB29C589D3C5D3
-:10F13000FB8766DCADA830EF7BD59CAF1C5CD5D9D6
-:10F1400032C946FD43D81FF824E55DF6EB0F6C0588
-:10F15000DFB707148C6F8382E4C5B86D06B4233F14
-:10F16000671E0FE93BD9127F055FC1EB0A8CFC7B60
-:10F1700056C2B33C115744FE8BFCBE6ED440E2CB6A
-:10F18000FD5C4CC3F32D7D618382F966EFFA3D5E31
-:10F19000D20B56B1CD93C0EE1DAAF2FC89BCD2773A
-:10F1A0006FC07381AD5AFD059171778ABCA6D217E5
-:10F1B0005C947FFDEE4ED736F2EB1F9869D1EB835E
-:10F1C000137FFAD1CF7E8BF8551D4FF865D65B0EB5
-:10F1D0000AFAE8AADB3C0FDF86FAFE8B0E6E27697F
-:10F1E0009E2CB2BBBD9E2CCCC3E9EAF77D191FF360
-:10F1F000FE19F9F9EC0A27C50D649C482DFDA411F0
-:10F20000E9717E716D11EAE399780EBD23F1E8F79B
-:10F210006EB253DE404049A0FCF25871E79DA372E4
-:10F2200044FCA5F60A5A07AB1D8DE5B9B9F50FDB0D
-:10F230003DB1E5558338D758ED363BF3478B0FEF9B
-:10F240001CC5F5D07A3C079BEE1C5C7FB801E3BC83
-:10F25000B1CE81598305942FE9700CC67C8E34F1B0
-:10F26000B8D5F983B7505E751CE6F22AADEEB355FA
-:10F27000487FD20F5195CEBAE2601ABC6713EFA552
-:10F2800009FD1B6918F5EF2A11FFE9A86414FF496D
-:10F29000AB3BFDDF089F8D62FCAA77F8F8766B68C0
-:10F2A0002FE24B95CB4372A7A34F9217EF27B1F3F1
-:10F2B0003CCF2493717C4C33EBF7A809E9D69D969B
-:10F2C00050F13B541FE68E672127E28FE2A079338D
-:10F2D00057C6517EAAD4AFD2EAEEBE551D61184F73
-:10F2E00041BDFADD0A6E3FA399DB356E8E41AF2238
-:10F2F0003DCBBC0EF95E878DB5A33DA9D3B3480FB6
-:10F3000063FA790619EAC22F66ACDBD2ED063EF14C
-:10F31000EEF9B25EB55C0E785247717F1CC243EACB
-:10F3200063526FEB36AEA0779D7E19407E21F321AC
-:10F33000BAF4A41A9D1D35B0FB7B32EF4C9E83843A
-:10F3400067ACF79D25DAB951941711A271FC6218C8
-:10F350008BD3954DF035F14B605B3C2F5EE8A1A05F
-:10F36000451AF211A45E29F97387E0BBE19C30F9DC
-:10F370000165BE777F78271BDE8F1F9DDC952F8F61
-:10F380007AD091551F533CBD0AF550983FBCE643D7
-:10F39000C37D92A69292F8D1E46F33E63DE8E2A8ED
-:10F3A000B45EBFE09B935517E59F74B0042FF2AF96
-:10F3B0008E80D0C7FEE4247D4CF20B337F98E1357C
-:10F3C000F2FF6B8B8DFC7F96D6DB144732FAB3CA03
-:10F3D0007DA6F8F63BD30C7C53F29F3B542F6DC2B5
-:10F3E0000A821EE334FB05BF7C5BE88176564BCF77
-:10F3F0001D98F73908F97F1B952E7680CA24D649C7
-:10F40000A59BB9294F268579A94C653E2AFBB25A9E
-:10F410002AD319CF8BCA646D54F66707A8CC669DB2
-:10F42000547A98DB82E540E6A57230F351E9636EC9
-:10F430008A7BBF9318CE3A04F09B7E3D233F3C630A
-:10F440003FB9518373EA2897754020A4ABC94C207B
-:10F45000DFE3376A589F26EB3B78BD84F72FFDE545
-:10F460004F7F141846FC46B43FC1DBBBEA3B6F2C10
-:10F47000213AB5507D0EF687FA8323B569A3015F63
-:10F480002B4733E2A3E70BB56FEAEB0F156A33F4B2
-:10F49000F5978BB46BF5F58F0AB459883FB29E5936
-:10F4A000A895E9EB371769E5BC3FF71FBD63D34863
-:10F4B000DFC50529A338BEE1CFA9FA2B090F7729AB
-:10F4C000563CD738416F763C4715E9C8EB88C3D224
-:10F4D000C7F377C2F1AEB0D3D283FD63A2A330F2FB
-:10F4E00027C0C3E18AFF665C8F999F280191079826
-:10F4F0006A8C8300BE93FF2CBC92DBE98C456F972E
-:10F50000F35E08CF99A6F3DB0E8C8C1B6B1F66FC99
-:10F510003D20F4BC8342CF7B47F899BBF61DB6264D
-:10F520009F7244E838B67D6865A7F4FCB2DBBE3F45
-:10F53000AAB4015D87EBE2DC28EF3AE2D9DB68A7E9
-:10F54000050EAB0CF58C4B5D6F69E1940708EEACD2
-:10F55000BF9BE20A725EC1673AF09FA0E75CDE4B98
-:10F56000DA975E078737B73B92C5BAEA27A55C935F
-:10F5700047F137AED70FB31D983515D699B681FB35
-:10F58000479390BE3114F6CC9FDC18176B9E6C61CC
-:10F59000C8A71A05FF34FBDF364E5AE1D6FBA71B7E
-:10F5A00093820AC6233343F1DC0F91CA82F12847C4
-:10F5B0004BBDA594071350DDA558AF6033F3A0BE33
-:10F5C000A045F594C2BCFB5A9E5B817ED84515765A
-:10F5D0008A4BD8B42914BF96F9182902CF1BD6C577
-:10F5E000794308C73E2EF2CF0E6B2C28457BB7DE41
-:10F5F000959282B89852B184FC87F52EEFEB784F44
-:10F6000023E0B6509E21736B8E32D057B6DD662D47
-:10F61000453E9EF5ECC82455B7EEE30D67E331CFC8
-:10F62000FD51B785DA1F5D39D1B1C485F711C15ECF
-:10F6300080729FFB9886FAFB56E89306E3DD5773CA
-:10F64000ACF9B21ECE31A9D46EC05BA7D7588F33A8
-:10F65000F91F6D26BDE0F06891F7318A8DC273BE47
-:10F66000E2C9F364FFCE7779C83F3EB149A17C97E8
-:10F67000F05E6F36EA9BC7EF1D42FEF0862655F816
-:10F68000A3BDE48F0E67B16CBCB753DDAC90BEAACE
-:10F69000367CB21ADF1B90E7C9C07106783B33DCB9
-:10F6A0003AFA7BF4FBDF8D4779D78017CF088F18A4
-:10F6B0008D23ED55793FBCDA7DB692FCBBCDBFF70B
-:10F6C00021FC93350BD1CC115B301DCF7F7DC96CF4
-:10F6D000A24BBC6F857A4C377DF47358A7EE9E41E0
-:10F6E00063EAC0049C3782BF1AF9CD4F3417927E6B
-:10F6F000B4BD6922E5F59BC7B967156B43BDB5710C
-:10F7000095A32D9AFE7B4FB62F1BEF619FDC58B25D
-:10F7100096C1F99FDC7B533ADE5B5FDC1CC7E23DA0
-:10F72000DDFB9FD8389AE65B8CF7A171DEE659764F
-:10F73000942B535B4AEC08B77B56CD7D563FCFC721
-:10F74000257E6731D09FB3F959C213170B0510AE50
-:10F75000BFB94ACB46FDE2442E8B9A97D9A798C7EA
-:10F76000177F7B958FEE999CCC8ADE2FA398C71FBD
-:10F77000EF2BF6487FF1DB4B53C91E7423BD1E6F80
-:10F780002A4C42BCB5611C1DE4A2ADFDFC2AC4FF9D
-:10F7900073150BDF5B0AED8DD3AE3B83E515F65A8F
-:10F7A000D29BD91F54A207D00BE9BED7DFE638DCC5
-:10F7B000F5BABC40D41F35835FC3C7D0FEB035A9AE
-:10F7C000213BF077DB9E53A48723BE6A3AFCA5DF7A
-:10F7D00028A1CF8B7C8FF451747F8E7E8DD75C17E0
-:10F7E0000C318CA32C74443BC7D8F3EBC645FD7693
-:10F7F00012D3E275F383540C915FDBCFE7EBEA277A
-:10F80000DAC10CD5687D422F37B7CBF50FD962A48A
-:10F81000CF6FE2F91445F4F358EBFD46D0F85E4D96
-:10F8200031137916330DF432546D5B3106CE8DBD34
-:10F83000CBF93FD875CC17255E15E1B3B0F6BE0203
-:10F840007E00CFB5A9B3C93E89B50E7BF080963353
-:10F850002262BF7D23DDB82ED9AF46E05D5C908586
-:10F860006C495886E85E461CBC8FF2FBD38AEFB821
-:10F87000AF894217B234F32DFC79F0BB11F2AC4CD6
-:10F880007C02D160B0D4472CFC7D4DC7E7123773A2
-:10F89000FDF7C41685F4DFF51B795EC4A741A89374
-:10F8A00072C1CF09558B2F84B2E3D2DD1F5CF242C7
-:10F8B000D37D433D06B82D62BA78D29927EF7A1BE3
-:10F8C000DB4F3F7D970F977B77EAA224CEB78E2E32
-:10F8D000C0794E5E6E277F0CFE1C123FA0E3D26003
-:10F8E0009C010FD7EF7E72CB02943BBB1D5E4CAFE9
-:10F8F0005BBCC5D81E97AEDB17E3F81530C0293CBA
-:10F900007016D0D191EFFF84EE792720FF447A5C06
-:10F910001947F7BBCC70FE6074D7F742983E0EC70C
-:10F92000C4BD0E4957C736D49F54619CB52BED1EFC
-:10F93000FA2E82C9FE3AE299A5A5EBE2BDF695FC46
-:10F94000BE25D3DB890323FB97E31E092C74785C67
-:10F95000DDC7EB867731C65B58A2ED2A06845D567B
-:10F96000E27B1ACBE31B16D2BEEBDA571E7913FAF1
-:10F970003425F87F867CF3D88641A314BCF762F562
-:10F98000D0FDBF86064B3CF2FDE6366BFC6084770B
-:10F990008385E47C735B6AC260944B2E0BC549512E
-:10F9A000AEA83AFFFE49C12723F2C397A4D77F121E
-:10F9B000043E9ECC13FACF24AEFF28CFEC21BDA38A
-:10F9C000A191C7A9A4BEE116F8E316F1C858FA0F31
-:10F9D000321E5C7762D12237F2B5C624FE1D8D45FA
-:10F9E00093BC01BC9779B58B91DC1880972350CFDD
-:10F9F00072B1E05498477573FDC6DFCC489F4971DA
-:10FA0000B9BC08EAB4966080D6AD713A73C07F087D
-:10FA1000CF843C8DE1F856935E6137E90DAAA9DEEB
-:10FA2000512CF250841EC184FE2DBFDB90786FCF25
-:10FA3000793DD2AFDB2CFC13A03F05E8FE47310B2C
-:10FA400022DE324DF3A4F68DD801E877C4F6F462D5
-:10FA5000B6AD5E177F52B457C96F20FD92D2FF201A
-:10FA6000FD1C238AC15E4BD2F9237E0DA6A54AF167
-:10FA7000B0CF104F72801D903D398C29FC9AC597EC
-:10FA8000D4D3EB2E2EEEF3A397F83D9F064B82774F
-:10FA90007B4EF77E19E3B8DF2C611FEC0DF5DAEB36
-:10FAA0001D749F66B2BA8BEECFB78EB4F03C65760C
-:10FAB000C08DFA40F218CE776F2FF1B9C7202377A7
-:10FAC000F972106F001E011BDEC3137EDBACDB0777
-:10FAD00026A03EFC5EC6A98DA897071A2DC46F24E8
-:10FAE0001C73565B36211AEAE273216B4124CEB6B1
-:10FAF000DE773680F77ECF5FC9EF1125CC3AB1179C
-:10FB0000FDA0EB065BC8CF7E77A246713BA01F87A6
-:10FB1000CAE375AF63BCADC9939282DFCF793A99DE
-:10FB2000B733718E0F24F6DDA6CF17E9BC92EFFB39
-:10FB30000125BABEB2F74ABECF8EDD00C85EE4D75B
-:10FB4000E2F678607F85E6D2D591F6E0FD1F06B833
-:10FB50003D3D6AF7FE8AC060B29344FBF90AB2E702
-:10FB6000D1C708ED1B776FAE40FBFC919CE8F3DE3C
-:10FB70003E8ECBEB47DEF00F407D36BC1BF0A75727
-:10FB8000B4F30D314B318D9B8D71A9F09D7173A331
-:10FB90007D8FE6CD719C9FB4425B5CAF881EDB5AC3
-:10FBA00061D65383C4AFCED51C7B85D2AE817F1482
-:10FBB000013D24B3E8FCF2C2FAAA371DF5CEFA3BA8
-:10FBC00095B5C83FEA415FC5B8609ADB4EFA6A4313
-:10FBD000F2774BF05CCED53037DE5BDD0E6A1FF27C
-:10FBE0002FF4ABE27DD4A9759CCFF8DDDCCF0A768B
-:10FBF0009CEF6AC4C70C2BE1A3D45FAD159CFF5CDE
-:10FC00001EC7F38B3B925DE4374DAEE3F9C4CE00E3
-:10FC1000E8B3B8BF493C1F5883FF900F49FDD63564
-:10FC2000CC6AC80BB69BF286ADA63CE16F8F31DA89
-:10FC3000338945237BD4AB7E0DF62FAE730FF01FB7
-:10FC40002C43600763F912D8ED58BE0C763BC60D05
-:10FC50005E5D9547E5EBABBCF4FCCD55C5544EC895
-:10FC60000E535C91FCC8E4BF612185FC7812BF5E35
-:10FC7000EE3F11F1BD84B76FFFD5CC4703FDA13D29
-:10FC800055F40FE45422FE75D5D9B595D8BF2A9DF9
-:10FC9000D79D636754223E4E9AACAD1B0378D2C702
-:10FCA000E2AB6EC4BE77C579A3D9F77DC7CAFB5E48
-:10FCB000D1ED77869F3A30FA735A894FC4F0E73C0A
-:10FCC000A0F075EC7D61F343E887EA35CBEA433C6D
-:10FCD000CE1E68F4F37F3E86D3C5D4B19C2EB3DF2D
-:10FCE00004FAE801EE923E62B5D7EF061488425757
-:10FCF000B26C4D64E3E99E75A57D6EB47CA66D8201
-:10FD00006FC61CDFC53C715744E8ADDE65A6B73051
-:10FD1000C577CFD57D672FCACBAF4E6F8CECC37044
-:10FD2000A546F23A0CF486FC5CADE1F4A65AF93D26
-:10FD3000CBAAFDDC3FB21DE90BCED98FF406FF9CA8
-:10FD40001AE0F53413BDD59BE9CD65A4B730D21BBD
-:10FD50008C971CE0FA85B3A2ED6BA5B73F7F457A7F
-:10FD6000FBCD5561CA6BE8C8A9CD40F8B48AEFDA7B
-:10FD70005D2A1DDE35D6CEE5C1708DFC020D388EB4
-:10FD80008BF4F90DF8BD94A9FD575B53007ED35356
-:10FD9000F3E97B023963FB0A7A38E0427FCD024DFA
-:10FDA000FB94E8EBBA33744FB18F85D36FDFB1AFFB
-:10FDB000913CC86A3C386B2AD2DD9D2AC949F3BE02
-:10FDC0006E1A2FE25B0A9F174E2E431FD77308BA95
-:10FDD000F4DC59AF38501FAF66DEDC1CFA3E0C7DF8
-:10FDE000B7E6870D7F73E3B8378D4FA1757956BF9E
-:10FDF00093ECE7FEB574B4DFE86A7241777A845F0A
-:10FE00009BADAF819E93C7F6E09FBD10FFB84FE852
-:10FE10000F78F4A837F8C53D4C19178949CF263F0C
-:10FE20006E4CFFE1700E1FF3FB67855CAD17FE5F44
-:10FE3000B3BE27F73FA4C43F0CF7A7B85EE57EE04A
-:10FE40003DCC83EB9471B3AE3C23A91F0658B01E82
-:10FE5000F56D2BA8327DB9BA81E375E51F093DF137
-:10FE6000C512FF681C771BF3EC45F9E6F2F27C053E
-:10FE70006789564CF0FC927AE086124D1BDB035EDC
-:10FE8000BD38459B34B628763B3B0FA38C8AC4B55E
-:10FE90004A6659395FA853041F70ADB543BD351983
-:10FEA000F89907F576BE6F37F00D0FD919463B620A
-:10FEB0000A3A23916F201F21E06AD3312F32498CF7
-:10FEC0001F91D7E157502F0D036C3741535280CB10
-:10FED000EBFAFD9CAFD881AF505CBA98DB09F29E7B
-:10FEE0008F739897EC2F55EBD97EB09AECFB256376
-:10FEF000051F296023116ED916CFFD63E079E183D8
-:10FF0000930F8D81C7450F2FEE8DE274F4B6C63284
-:10FF1000FC6ED74D8F9FDC867ED231FF15C7C4F7AC
-:10FF2000D128CFE05F2867E85CB6ED79B72260455D
-:10FF30007E151D8F0BAFE2782CE3AC3DE07123E121
-:10FF4000B188735E021EBB2E80C7CD884F51F078FA
-:10FF5000E357C4E307715C0D0F01E34653B41FF58B
-:10FF600084B75B276B8FF6D4AE8B1FF0FC21564312
-:10FF7000F6B38C5F9AD7D388F235B707BFD4BAED02
-:10FF8000F168CFD6D76C7F03BFDF585FC7EDEC8E2B
-:10FF900044AF03F38D03BF57E9BB54B1DE47BB3B0E
-:10FFA00000CC72E8553C0F7ADF9D71A109304EA656
-:10FFB0008BCBDB4C97C630EFDBEA0EDBFC89A8AFBE
-:10FFC000F918DA19F6540B0BE8FC3157D80E905C8F
-:10FFD000EE00398EF401F4C9E92D998F23E5F384FD
-:10FFE0003BEFC7480EBBAA13E4A08E4EDED85D4C93
-:10FFF0007EB8C4A2E757E07B6AA5DD83F83DE173D4
-:020000023000CC
-:10000000909BBA794A4013D1D7AF766418C699EC61
-:10001000CE31B44F4DFF86A1FD1AC0173BC5B1F9D3
-:100020003D3FA9D74CF3E41BFA258B38C737F3C6FD
-:1000300018C6B3AAE7378D46FA177AC438F80FE91D
-:100040005F35E90B667DC2AC3F9C1C6BBCBF32C206
-:100050002AF2D0AC3C3FA29539E8FB12C007E9FB7D
-:100060000555913C01A29311F6F0F67BD0AF32CF4B
-:10007000E10DC0B386DDD7A4578F8CF8CF5AEBB80B
-:10008000DFAFBEDDB10DE961ABA04B495FC3128F9D
-:10009000CD6324D7ED0CE5B1995E65BE93F41748A6
-:1000A0007F8252C3FD0CADE37378DE91E03FAD1566
-:1000B000DCFEFD91128A570671BAF4A444BE339750
-:1000C000CE94C0344EDF5A8A2855918F2AF35E7140
-:1000D0001CB4B3D3F97CEC759E37B9FA7BF8BE9BA0
-:1000E00005FA0B7F46564AC44F81F909CBF87B814C
-:1000F00069E2BD0122DFB2175F7F68B2986F049496
-:100100006AAD26FCD37E2AE3301E0EE540C59B80F7
-:10011000FE8F41AA8F022D4922BE9E29E2E94E257B
-:10012000C499C797E42357001BC5BC0496C2BF13EC
-:1001300032F1A72EA6127DD8B7A33CBAFBA8F77759
-:1001400098AADB90F8DDB726C0F3A6DFAB5EF49388
-:10015000DE9D15780FE9DA0AC81020BF96AF1ACFD6
-:100160004D9DE3704F85F7D4C0B6D518DFBDC21ED4
-:10017000DC4BE7B9268EE83D0CEF213E6C4D043A8E
-:10018000457C454FD7A8483E908C6384C7781D288E
-:1001900047C3D88FFB9B0DFECF28F926E42FB58AE5
-:1001A0007A836B3BE9EF6B53EDF8E54CCCEFC9AECE
-:1001B00043BCEC93C0EFD3321E371880FF18A4E382
-:1001C0005BEEE87E4DD0D7080EE1D54BD37BD2BB9A
-:1001D00062C6515C96903DE9E2E3288D375F170CCB
-:1001E000E9D629F7BDD6B55D59C02E657E668CA3CC
-:1001F000D4302D7E4494384A38A8E03A07D4F038F9
-:10020000CB00E1AFFFB2711475FC978BA3C8FDCE94
-:1002100010FF9E0E882DEE0D533C81CECB12599FC0
-:100220000E7E8F113F22DC102802F56B45FDAD5D7F
-:10023000073F7A12FEB97FE74BBBB0947ADC2CD132
-:100240003E73C8677B30776BD6BA15228E658C3FBC
-:10025000CC00AB4EEFE7C7FBFFFAFA2CD37A265A55
-:100260008D7182492E63FF29A9C6F6D2FE71DDCEBB
-:100270000DFDF2B45FA5FB7EEF76DEC7F877A374C1
-:10028000E7A05EB8EEC0BC398CFB78BAE3893E0EBD
-:10029000E07BD1CA524622BE58482FDD1A58BAB95F
-:1002A0001CE8672DC851CE8B3D06FA8BC43D4A35FC
-:1002B000C427E9EF8F454FC75C03C9FF3FA06E6FAE
-:1002C000DBA4DEAC2B0ED094E0FFC5958037035C39
-:1002D0006715D44306D4BD4CEDD7CD2BEA118F72F0
-:1002E000EBF6B54DD27D0F30D7EAB3A0FD9C5BF79E
-:1002F0002A3D8FA9CF77E72394B7962BF042E605E6
-:100300006EC5BC40807B6E8DF8CE6F4BCFF96F52BF
-:100310001E36E8F2FB2899C1A330FDF852EE75F3C2
-:10032000A733EEF795F375E5059AE6ED927F6E2E0D
-:10033000FF9C25FE0E845FD7BD0C718F03F61D3523
-:100340000FF4E49522DE143B8F8DDB9D735E7F0FEF
-:10035000C7BF64BB33C6B813B2C395D1EE47FD4DDA
-:10036000F8AD3AE2C359E837E8B045D7EB3F9E34E1
-:10037000E51F57F660C761DE2CC232D63ABF6CDE8D
-:100380006CF6180E2F196F95F9B3322FF642F9B3A8
-:100390005FD50F3F44F8033AAF64DCCF6F8A4398D0
-:1003A000D79B33AE2BFEE019D743FC41F67F2FC31A
-:1003B0001ED52F5E3F5EE049F7FB47941F0AEB4DC9
-:1003C000D5DB41F23D99976F1E0FECA2C2713A7FC7
-:1003D000A07F752EF9FB74F696CC8725FA68157EFA
-:1003E000882E3A30EB85221E62D60B657C44A9E04C
-:1003F000FE09A08F89E3FA70BD0BF3D2A59D27F308
-:100400004965DE28E685523CEA4BEA555FBB3DB5BF
-:100410007A32E575D5BB27BEFE55ECA9E5E38DF62E
-:1004200094DFC5FD0E7EB4A78677B7A79A4AFC373E
-:10043000E13999EDAA233FF890F263C10EBD99F01E
-:10044000EAABF209937FCA3186E3B794D3D29FB661
-:1004500077B0C5E0779DA2AEDC4BF9E235DCDF92E8
-:10046000A9B5919D6677D93DE86FB14EE274641BE2
-:10047000C6821A8FF3927F45E695A5B8B83D65F61A
-:10048000CB483B312CEDC400FFAE4AC77E1EB7758A
-:10049000A2BF053B9672B926FD2DB654E16F31E53A
-:1004A000633B4DFE15B3BFA5659CB0BB84BFE51192
-:1004B000C5730F92FA735B26FF1641F1F387163B63
-:1004C000D1D4FF65B0F19BC2DFF2A00BD6B7FB3DE4
-:1004D000A3BFC51CFF8A12F722E7D59BE3B653DC06
-:1004E0004DC257D2ADF46765D6F1EF024C51772972
-:1004F000C85F5A5D1CBE2AFAB35223FE2CE5998FC1
-:10050000BAFC52981FD73D4E5EFB06AED30A0C676D
-:100510007D34FF9680AB391E9554C7FDE35F973F4E
-:100520002B34CEE8CF2A78B0F07EFC3EF1C887CBE2
-:100530000E61396ADB777ADF0065F1E3F79761F9DD
-:10054000F737C239A8779AFD58CFE0C78CFB74877C
-:10055000AF198E124FFD35124F5D76A2DB0A0E47A2
-:10056000339CD2348EA7B980A7A02274E15F4732B2
-:10057000A7CFCC49DED7D1BF3660989545C3636B12
-:100580001DBF0F2DE1B855C031A56609F909CD7819
-:100590003AA0E5D2F0F38C097E3FDB52780FC2ED32
-:1005A000F987CA7E8BE52F82DF7122DCDA1FBBFF61
-:1005B0009B027E19F45D5C13FC26C580DF042FB717
-:1005C000AF274FF4FF1DF9F335C021D01FB2BDA9ED
-:1005D000C0618C0319F969DAD7E49F0A77F153F601
-:1005E00076EE25F0D32D26FF545A80D34D5AE028BD
-:1005F000D16726D0673CFAAB6AB81E09623FE8545F
-:10060000D0E6E6FC55CA35643916103E5BDD3CEE9B
-:100610001CC54F19A2EFF69AF8303A70F4780772B9
-:1006200035FBAA3E1179B7B586C7D15E9BE4F3E0EE
-:1006300073195773966839577D35FFE337AED2F992
-:100640001F014F69FF2AE03B7EA7FC6A902768FFE5
-:100650005B6BC236942B5575B72A7E285F1CCBCFB7
-:100660003F2DDDCF30CEDADD5F174E44BD7DC2E0D9
-:100670002E7C28BE4A870F57DC79EE7EF473C5C204
-:1006800087CC18F94A17C6878906F9DADA850FB5D3
-:10069000EB2E4BBD787C68477CE8A3C30741FF691C
-:1006A00035E107917EAD021FAC6EE063000F15F1DE
-:1006B000605824EE29E9212CF20FCCF0090706C579
-:1006C000C84358A114F7B0BE8BCE3F10F1D07A11B9
-:1006D0000FF5D7F17CD98E3BE3A618F30FBCB4EE2F
-:1006E000A9AE5A459FC71F254FB616CF4FC63965CD
-:1006F0005C73F244DF0AC49F0979FC9CC3B1E34CEC
-:1007000021BCDF0AE8E736E1F9F708CFE5FD03A1F0
-:10071000C7BD36495B89E38EB00729CF19F4BDD533
-:1007200058DFBAFB49FEDD5CE1879479795FD96FC8
-:1007300096640FE27D49E9376B4DB46FC7F3AE663F
-:10074000E1C9F4BD5E8C53A0DFE9DE38CA6B5CA85A
-:1007500080E10DEF7F7BA27F33D11FF3513EAE7F4F
-:100760008EC38D7A7E43F29474E41B556B5592EBE5
-:10077000B1EC1B496F55C06F88DEEA38BF4903FCF6
-:10078000227C0B28C46F3281DF70FEA331D4EBAC26
-:100790004877AEEEFCA6B507F85F24DF790AE11CC6
-:1007A00085EF3C83CF757CA70DEB5F16EE7957196B
-:1007B000F90DC60368FF485FFAFD9BF5D9AE7D1BB6
-:1007C000E94BD2DD7F009DFD19E11A85CE8E209E7A
-:1007D0007D053A3B1383CEDE37D1D95FFF4DE9CC9F
-:1007E00032BEE8C274B659E095CCDF967AC550B5F2
-:1007F000ED6C2ECEFFBF9CBFFD1D915F77A1FC6D00
-:10080000FC5D8CFFD49CCFFDFFFDA9FFB1FE54FF22
-:10081000F83E5FDD9FFAEB2B3DA4E79AFDAA0F8E11
-:10082000D66E1EDF831F4EF269ABE4D3C08F91F703
-:1008300056013F43FE9C56D1F9975F727BD3EBF490
-:1008400090BFE10E1C2F53F06B335F06BDB36EFCFF
-:10085000D7E1978CE16FF857F90D8788BCD20BDD93
-:10086000B71F32CE23FCAED1EFDDD70BFBBE1EC6C9
-:10087000C07B7A5BEFB4071B60C1FF1CCBCF674422
-:10088000CD75D72091FDEE267B42B807BB49FE3DD2
-:1008900088E655FE174EE4EAF7C7A2CAADAEFD9949
-:1008A000F464BDDDE4B904BBE9FF8E37EAC9D61AAA
-:1008B0006EE75A41DE515C5F2B0E21BFCE0C286DD6
-:1008C000981AEC4FAD55500EA6D5F8281FFE52E3EE
-:1008D000FA663C8A15E7FFBAE3FAE6BC817F9738EF
-:1008E000FFB1F1D1E3FCD2FF6A8ECB8FB037979284
-:1008F0007CADB4E05FB2600DBB3FD87E0F9EF73C8D
-:1009000007DDD330E703C48ADB8F48B1879D0363DB
-:10091000C7EFA5BFE0115BED1B68873FB2DA42E786
-:100920006BCE1B1896C8F3C75BC7AF7A98F27FA44B
-:100930003E5C21F84C9D6247FCF7570489CFF8B51F
-:100940009DAB319E9CE6626DA867B58FE7F4A2A6C9
-:100950006BC467AC157EC22B199FA8CAE6F7E6E206
-:10096000057EA9836BDFC2F1930FA85E8C6FDF8BCE
-:100970005D816724A2AC443D628C85F2225A945A70
-:10098000F27B342B1EFA3B1EC9C3DCA41F3D9DEC39
-:10099000FDC35CCA0FE57F6F64DFB4EFA6E3FAEE38
-:1009A0005EBD3A1DF5C08C093C1F71D3B453950848
-:1009B000675B1EE87F0A9586BF4B2BCB8F26F038EE
-:1009C00009F005CA4784756FA1F8FB603BF9D9545B
-:1009D000ED81EF201F502F9B4278DDACB8E72DC092
-:1009E000F3CAB5931ED3903B6AEE22D8D7BA3EFE27
-:1009F000A61C3CD7E4C1B4CF86E4BE49A88FAECBD9
-:100A00001A48FA6793524BED812C0BBDA78AF8FC6C
-:100A1000BADCEFBEBE18FD59D9FCFE674BEEA9D774
-:100A2000B15FCB18FEC76CCCEB55DDC67B52F8E14D
-:100A300023E4DF6A7F0BDD2F54455C5C35C59537B9
-:100A4000C87D8AFB2BF1826F55E5AE994BDF4F488D
-:100A5000B5BB11C91A13C3E5586FBCD3C6304EC716
-:100A6000ACCD063DAD7E95310E617519D7D3D475E9
-:100A70003FE1D5F9C8671A15510FFC82D7B19D9295
-:100A8000FEDAE623BE34C6F3FA35BF79723EC511ED
-:100A9000C5FA6C727D7DF8DF5BF97430A3FB6D5590
-:100AA000B670D4EF0B5F685DDDC7DDA48971D9FF37
-:100AB000E6B84DB93C4E641E57F6339F9B6E1EA69A
-:100AC0005CD23CA7CA09FF0EAB0CF98C793EF3FB54
-:100AD000F2BDAA3EB349DEFDABFAC782EBF2095D77
-:100AE0007FDF8575C52DC43D3B8F2E3E563F651477
-:100AF000DD8B6D556A896E02C996A8F9BFB1E947C9
-:100B0000373E0F8E10BFB5728833B52E9EF2382453
-:100B10003DC93C0F6BBA859E33311EF0E157491F2A
-:100B2000D2BACE8BB9FB46C6552BECD4DF7C8FD81E
-:100B30004CA7323F84DECB89B45BC5BCE6FC109782
-:100B4000C6BFB7D25AF900F9F32F354FE438D22790
-:100B5000C18D915DD8F05FCD942FC5DAF9F3867C15
-:100B6000377DE770BDEC97C828BF499E83539C032F
-:100B7000137691CCBB89969783F65CBA84B9870DBE
-:100B8000C67D36CAF73D3E0DF9E53D578CC8C7EF27
-:100B9000773EB873D313680F6DD9B5E67D2CE38724
-:100BA0008DA0EFA726782D5EBC9FE5BAB1BD1D399B
-:100BB000E4DA618B9BE938F5E74AF75315CD0DFD73
-:100BC0001D2ED776E4BFCCA1D077AFD41FA605D118
-:100BD0006E4D5F64C48356C5DB17FF3E6660A3425B
-:100BE0007A177E6F40DF6EF718EBC7262842BF34B6
-:100BF000DA31CD31EE750DD5B8DEAA9AEEB56EB20A
-:100C000079E8FBB99BD6A9A40F6C1271A5F1DADDC6
-:100C1000F357036DDFDEC8FF9E706B893D88F75385
-:100C20005B13DDD7CDC5BA907F32BEDDFC8DCB82A4
-:100C3000FABFFB9439C14378B8B1A46F06E371F0F1
-:100C40000CDFF0D878F165CBFF0132DEFE59008071
-:100C5000000000001F8B080000000000000BC55BB7
-:100C60000F701CE5757F7BBBB777924EA7BDD3C9CC
-:100C70009C8C6C56B6146490E5B56C9953B0A3BDCA
-:100C8000D3BF9371E9C5FC3333B67BC6C6214D266D
-:100C9000114E494C42AA333A59F21F84AC24953381
-:100CA0006D9AB30999CC8401259DB6860073024ADA
-:100CB000288144492990690684096E483313A7C1E5
-:100CC00089D2A1A5EFBD6F5777BB3A59B6E34ECF96
-:100CD000237FF7ED7E7FDFBFEFF7DEFB6E8DDAFF60
-:100CE00072DB7A007855361ED6B104154C3FF0E71A
-:100CF0000319FFD3F06F09007D857A2AC57B052093
-:100D0000FF810470F57115F2767BFCFB6E4718A02D
-:100D10008D6A63905A8DC5E48D1ED800E0B7DA5C09
-:100D2000234FB6AEA0F95E93E1617ED20FA94AECE3
-:100D30004B9F8E42393480135C2DFA284B6855F84E
-:100D400059017030B2F54734BCBBBD5DAAB969B377
-:100D5000BE85E681FEC966805551E7FAEC76A73A72
-:100D600070F13500BE1CE4BD412AF326B450396D44
-:100D70004A589EDBFE196DB3BEF03C3E281AB79E62
-:100D8000C603DEB75C4C3F7CEE853413EFFE8A96DB
-:100D9000DB01F73D74830AB25482CE8BD455253FD4
-:100DA00025E13AC7EFBDFA468800640EC9D088E352
-:100DB00078A345EDF02FF5D47A9809887564F87911
-:100DC000D2243E053BBCBC5FFAF89730FF0088DFB9
-:100DD000FA8177641CEF4B49553F8CEBFD526AEF6B
-:100DE000576EC17AF625D990F83DFE87FCBBC79AAD
-:100DF00003C626581EAAFCA2FFFE53F7BDF922F136
-:100E000028A9BE457403AD882E2BB830FD1B0AF30C
-:100E10003D183B3DB212E9901D293DFE1DD5FAA7B4
-:100E2000885E369D171AD77E2FEF9F9AEC5A57A8E7
-:100E30008F94A77798C887D180014074D8FF1CBFD2
-:100E400087F52897B50BF31329CAF47993BE62BBD3
-:100E5000AF759A7B4CACCBA770E96B00DEAED46F5C
-:100E6000DC8AAFBA236FED20FAEF097834E2A3DD14
-:100E70007FF0A817F2012204CE8B72B70566766C5C
-:100E8000C576D0E0653997236BF9F9EECA94E2C1D3
-:100E9000F2F3E60A9617BB7F1F7C59D987CFD77824
-:100EA000B557494EB211895684CF9180B8F4CD0A16
-:100EB00098412C7BF5B8BF1EC74D3E491301748481
-:100EC000C623E0016879E2785DBA99B6614E3721B0
-:100ED0007F4216BBAEF54DA73A71BCC19765E37E64
-:100EE000AC87027BB700CA91F4182E969E8720E744
-:100EF00043BE2B819E77E9F9A6B3005D45F2D4315C
-:100F0000EB87AEA6423D8E2317D73BFDB58EF6DDAF
-:100F10005ABDE3BD0CA691473AF5465739DA55B6A6
-:100F2000ADD768BD7DFA5AC7F31B9ADA1DFDA14BF8
-:100F3000393D83F58DF88FF82E83A8F37B5C77A07D
-:100F400019EB45FD1528AAE3FBBF352B2367AEC57A
-:100F5000CA75701DE911F2E5E411B23FDBFC06F140
-:100F600065D00BA7A42A20D5CF402B11DBD4234872
-:100F70003FC992D757CC7A960B29F0FC1F580E9F89
-:100F80009CF148C4D727A0F53036FA1B4D9FF2607C
-:100F9000932B6948EC1F4541D7914F0D385E592B73
-:100FA0003F3757623D0A52A60FEBCBB05D54882203
-:100FB000BC40EDFC70E00BA21D2CA3761A64EAB0D5
-:100FC000AE19504E7CADC3713E19E67E993EABDF43
-:100FD00055A25FA62A2CC66FA179D15C76637902EF
-:100FE0000CF0C9448714C04AB222FD5C5E45ABC216
-:100FF000E70F81D14AF5469861BB84EC97A87E053E
-:101000004C6AC2C8E785DD9E514267FCC2EE97D2AA
-:101010009782DE2870C6E607CDDB61FE80F4EFD64E
-:10102000DBDBAAD28185FB29FB9F75E8AD1AD79936
-:10103000CECAFE5ED61365FFF3FCFEEA78EA551AC7
-:101040008F48EF6F9D4FEF16350F64BFB27130328E
-:101050003844F6F1CDD15DC8DFCCE37EA3112E1F5D
-:101060003F2E960F39D0CA89AE72FFA5F2013FB864
-:10107000AFC029FF89C32C8C269F937F045FFEE7B6
-:1010800052F8E2E607DC570DD0BEB81DFD6B295FB4
-:1010900026AD647A98D1D602FDB19E5965D12B6CEC
-:1010A000F14316655EB69E2BE185F942E355870B49
-:1010B000FC598C2FD114BE6F2DF047EE379978F67E
-:1010C000B9EC83B312952B2483F9B5524E79A85EFF
-:1010D00021E52DD093633B1D048DF9B314FAB98C2F
-:1010E000786776117FB2FB71229447781F4F59C2FF
-:1010F00049D6B9980D24FCF5645F9B14C383F5E6CB
-:101100004A4F2A8774BC52813CEDAF56810CD9738B
-:1011100044063C7EF6713CADF09CC9E231EDA17E07
-:10112000F7FA7359A9307F8B65B77F54F94D6DA6D7
-:10113000B940E7D364BFD6087A78D8FE4CE6A97FD9
-:101140003409C6A03EDF9E61BB8C6CD9292A77D2B8
-:101150008B76A65B26887569E4FB7F209C41E3299A
-:1011600058AF88A77BE3354C770884D92ECD5478C7
-:10117000A0142E300957ECB2E6D9F6117D790AD7C2
-:10118000B96BC4F7168D07599F1317B8FBEB1214F0
-:10119000F7B7FBCDC995BBFF25EA01ECAFB9201C21
-:1011A000107F6C6315D179419C497A525DDC4FF018
-:1011B000498DA41977A8A42FD58B8FE375E1177BF0
-:1011C0001C2F0A2E8DE3B5F08B7D4EED85B35E6549
-:1011D000A5B54EA4D76EB03F11A6E74E8B7E7F46D5
-:1011E000E75590E8A9AB44A43D9052496E3F861064
-:1011F0009A70FC8A437B828C17A04B23FA48F9EB48
-:10120000E50FAEBD083A5A74DA997FD7AB935DDA31
-:101210005F096FDBEF5714DEFF76FB4D8CDBD101EE
-:101220006820FE5658EBAB38F5FE0019F5FB2BFE97
-:10123000F2E50E5CFAD0BFC8865C4FEF11CFE23802
-:101240006520CEEF0AD2535C77C59367FE9BDADB4D
-:10125000EFC17A4F2343D1B89E8AA38C672B82AA11
-:10126000CE38DB2567368E86F7050E0E58D42B1A3E
-:101270005722BC6CFB3D3CAE347FDED5163EC757D3
-:10128000F10F2E00CFBB713ACCE173F13E105085C7
-:101290009E1888738BE9B8809ED9EBB6FBD5A8A9B8
-:1012A0007AA3B9447F8B0FCD685708EF5D5107B91A
-:1012B00003B8DE91917DF10AAC1FAB01DD87AF86EB
-:1012C0007B3E2B11DE4844842885620217D21434F9
-:1012D000BFD79A2FF40BFD7013BEDF5B173070651C
-:1012E00070C5AF4C2D8EE3DC59E7374C7C9005F18F
-:1012F0003E13F3087F3203AF101EDD63F1C7FBA47A
-:10130000C099CC1BD4C399B8C0577B4E7D720BF1EA
-:1013100077347CB391C7767BD03E55131E1BF332D6
-:101320009E435CE7C0FDBE58110EC4BF3B8F7B1DC2
-:1013300075AF0B27BE19471C48CCB470E02FE320D3
-:10134000E6C582CE93CB350F04226C4F572BD31EAC
-:10135000ADC4396BF3C3C6DF4FD5083A7BDF1374D6
-:101360004187791F3DF7BD27FC3134E081B62574F4
-:10137000FA0BFAF9DA903EF4F43D711E604F5EB755
-:1013800089FF68DD6E3CEC73E161F77A6D3EC80958
-:101390000B276F800D441FC4E78C13ECFDB8F7F1E9
-:1013A00024FAE75D28144F0FF8B9CC0F685C3E3380
-:1013B00010E5F2B9011DBA10803D3FD0C4E50B0322
-:1013C000063F7F7120C6A54D87F9F44129C4FD5E13
-:1013D00065AD59699E4ED139BAB4CBC3AA70EC3E03
-:1013E0000FD3ED1CCA27295F10BD2005977855D271
-:1013F0009333692F96FF738525AFD7FACE4EF9B098
-:10140000FD682D18F763FF2B627B59CE369DF514CE
-:10141000F404C8CF2977C409E250EDA877FAAF7475
-:10142000B4EFD6563ADE87E3336CA77AA3D73ADA1D
-:10143000D97CFE3AF959B8BE635DA735A26B9FBE51
-:10144000CED14EB90FF9DF42FECFF58E7141DE628B
-:10145000909D0E6F77CA61D0C557F5AEF3FB41364C
-:101460009FCD84530F16E2AF5B5E6DBA86E7E82A24
-:10147000FCCA2CF99548D7B026E86AEF77D4DAAFE2
-:101480003DAF1213FBBBDCFE6590FCCBFA52FEE5D0
-:10149000CF2D3A2FE25F269DFEA59BAE8BF9977F5D
-:1014A0009E70FA97174ACF9DCB45DC2DFC92CC7EDF
-:1014B0008B9CECE773B07A5A367AC9245AB8AC924E
-:1014C0006C00B6DBD9A6E608671E8399289DE70F56
-:1014D0004A485594B7EA66A396ECCCA321E3D56DB0
-:1014E000841BFB3CC649ECF26CFCD628E18EA103C0
-:1014F00027A27858C103090FCF3B163FC3F10B4514
-:10150000078E5F6069E64AE013BBFD3D435E3E0F18
-:101510001EDCA1E6246CFF60A576EB36AA5BF32007
-:10152000414C7A3FD1F6A11CF929A309DD8A336524
-:10153000A2E4AF7C69C7865A3EAC14ACAFA6E606FF
-:10154000EBC9E1322D487E74768747A37DC9EBFF56
-:10155000EA33241F0F48FD871AC87FABF1009D1F97
-:10156000D9D086DA5DD84EDE893086EA3B36BC4E6D
-:10157000367BA2463FD440FD430D4CBFA18DB7FA48
-:10158000699ED1D0923E8A8F8C767B984732E18CCF
-:10159000208FD3743EBF47D68ACE77E0B805AF53CD
-:1015A0008E78F22A9D57843F82F3E37B87432A3962
-:1015B00005F08F895B4E641AF831DBAF2B2C3F604E
-:1015C000E78E84C9F68AF004D267A777A6A6D4B9B5
-:1015D00070D08A77CE9D3B51E77A4ACCC3B8401190
-:1015E00033F247B7E3B4F8C9DED893A373741C523F
-:1015F00049B29F998087E31D0BED5F0938E7B3C7B8
-:10160000E7F1648AA395996545FBD7ACF8EFCB0960
-:1016100089F1EA0F89EF6D62199125857529490FC6
-:10162000F7B3FD5794DB6D93240F16BDD1AF78BE91
-:10163000F8BC7D2D21E2B2AFCFC911365D52B48E18
-:101640008DAA359EC1718A35AEF8B59B3F171BBF79
-:10165000FEA5B59FD7B6DF745E3F7955CED9CFD7FB
-:101660000962FF56BCDB6BF1FF1A79721FC9E3FFF9
-:1016700077BCDBD77979E3DD6F937D229C8776FE9B
-:1016800061FC9EFD698EF5054E9D7D9BF57AD51218
-:101690000BBF40B4C1C68F2BA874E90F017DE4DFF6
-:1016A000F85AC4A5581FB7EA99D5625C28D6CB155D
-:1016B000E4178838CAB2CE95C2DF227B42CC558C63
-:1016C000E544D780F29D8C86FB280F1C831096BEC4
-:1016D000C8AE0C951DCBF5D118AE6B7C9587CFAB02
-:1016E000F1CAF489215AFFAA4049BD68EE14F66F89
-:1016F00084E495FD24303DA46F92AD1C90F6209FAC
-:101700002640F0D9EC0CF17A146D2C7607CA4DCC3A
-:101710009207DC0FF7778FFF611ABFCD31FE374894
-:101720004EB3D6E034CE2E1C27DE29D97A95A1F708
-:101730007E6B3EBF3E16235C90E8D4C47B65AD4112
-:10174000FA301E2A3D5FC29A0F2814B3A1808FAED3
-:10175000D82EC601BFE8FFA07476DBE9F5CC57D6DA
-:10176000275A07BDAF309CF6C13D7E5993D3BF5178
-:10177000EB9CED5373FB70FA450F48A5D77BB7D5AB
-:10178000BE63B99033928FFB4BC8875BDF558A7B72
-:10179000E2B869E207DB0F617702CA7482FC9D4000
-:1017A0003318834CE029DE6FEAA9865333EBC9CEA8
-:1017B000070DF283143F9ACAD6829FE8DEF7627E55
-:1017C0009EA240C6DB3ADFDFC371CDAA5671CE645C
-:1017D0008AC6FB8C252772B13F584FEE887E23EDD9
-:1017E00073EC90CCF1A5B17B7DDB4A9DD3F726CE7F
-:1017F0009FD7399E423F829CD4C78E1EDA8DF5DF7B
-:101800006A1ECDC76DF492791DCDAACFE57552172A
-:1018100096D719EB0AF7355C4C5E678171E7CEE32A
-:10182000F9799DE39D48A76301915F99CBEBDC1C9F
-:10183000B9A0780E58E772D8B2CB957D961FB15FEC
-:10184000623FE299B67F3FB286E4ACCDCB720047EF
-:1018500027A0584FB66CD7BF5A4DE7CCEB3E681463
-:1018600076CDA4F16CBFD8A69F6A8D9FF8F64B0A7F
-:10187000B51FAFF56CE0F120EFF344793DAA55CAEE
-:1018800054AE51F372158D1B06439C0F79899EC788
-:101890009158C5FEC1E8EC4F3AAB284E1200834C7C
-:1018A000D0685C3B50455F280B4478A75ECF91BD64
-:1018B000EDF45738ECFF689F2AEC6B23FA4BA43FFA
-:1018C00053FA57F760FBE1FD658C9B1EA8F308FDFA
-:1018D000CA4839A99EF0B5D3EF199F5C21F0D851C1
-:1018E000AFD188ED1F9914ED77C737E464C6DD4E9C
-:1018F000BFA84F77FA45BB6B5B5F25BC08435E8E84
-:10190000C76B16AEBDA1C9E92755D6F7BF403865EC
-:10191000E790C0C307A3E125BBD1FEADEDD21D7991
-:10192000B25D437772DE684805CEA78EEE50593F10
-:1019300046BD6F1DDFCDB8B19CE938B143AD4D1741
-:10194000E9CBC7BA7C3CCEC40E813F105EA6274BC4
-:10195000BCFF589765A714E073DC96973FF9B8A0D1
-:1019600073B00E723AE1B8BE7D79F22BC7EB704FBF
-:10197000F87E28DAD03745F3BF2203EDD32D87F761
-:1019800090135CB40F5FCCE3A093D797EAA7F1E183
-:1019900006D0C9AE7525B14E7180ED2A507CC017B6
-:1019A000FD0BDE6F18EB6558F727C7320AD6FD0D21
-:1019B000E975848B9FBDF7B6917884CE3BA1DFBEDD
-:1019C000ED7B533751FBF55E28A3F5812E45697DEC
-:1019D0001909449EDFA90F07B3FFD4457C3A684834
-:1019E000CCA29D7D5BEFA2F59C8B94336E1AF3A67F
-:1019F00076B13DBAC5AF65F80C9C613FC2FB051FCF
-:101A000090DC4DDCFB4E0DE1EFABBA56B0BE95E974
-:101A10004EFFDA0F637C6E6F34A7B753BF8D3195DD
-:101A2000321EF04CFB19E6DB449BCFF0E13A26DA9C
-:101A300025A6F3EFDABC399AE769755AA6799FFEB5
-:101A40001DCE5D5F4ABF4BEB95AD47EEF6A3B1AD42
-:101A50007E928B83307D33D127332BE254EE76DFB9
-:101A6000B0E4E060F6962685E3592AE7DB95B38675
-:101A70005985A3876653DFA2D8EB2B9D0AB7BBA776
-:101A8000D6939170BCE13E95F568B8323D42F23C88
-:101A90008C72CF7E5204EBA467B511E370D17CE366
-:101AA000EDB736913D7BB9AD8CF1FD6BCFD6DE91B4
-:101AB000C12113F2AFFEEE31F2ABEA54E6E7B0B764
-:101AC000FF75F283326D65BCDEE796A9E0277B10D7
-:101AD000B9E321F2B3E191ED502CAF1349A1A71363
-:101AE0007542EFA5C7B6B31F302EC94C67B3E6A445
-:101AF0004478CC97B4E34E22CE14B7CCD9C4F6EFD9
-:101B0000721C6A699F88A3C69356BC490E64582EFE
-:101B1000AF2B7B88F4DF54BC0EFF78D359A7BFBC32
-:101B2000D4E52FBBE3515BBBAC78841577B2E532CB
-:101B300068B5998859767ABD2F27E4B0BF566B9E59
-:101B4000AFDF3FB4F0F3F4801F2502E027031AD77C
-:101B500083E66F0E54139F06A2FCFC4F379E908ABB
-:101B6000FB8DAEBFC5AFB33D9989D2B86E3BE2964F
-:101B70008B373ACB1DE789BDCECAF60410EE3D7710
-:101B8000962D326C0ACC74F2D908D38162BC9FA71F
-:101B900075FA284E26D6F91CADD3477132B1BE175F
-:101BA00006742E5F1C68E2F23B5D20F201B67DB840
-:101BB0000AED03D2A1AB4ED4C91E10FFC3913B382E
-:101BC0004EE68B2A1AE9BBBF6E2C2F15D98789CA1E
-:101BD000FE9FDE4976BF26C0F2E8DED7B1AE397C83
-:101BE000E8D8D7CEF67D6C77CEE13C447FB433772E
-:101BF000B11D42BBC0F36E576FE775986897D82E3A
-:101C0000F47FF536B60B5E203977DB817046E877D6
-:101C10005A17F13BFB9ED09C5DC0797238CF336878
-:101C2000D7A93E8C7680E6196E7FEB1334EFEFFE7A
-:101C3000500E34C4C48E57D92EBC7C0EA0FA32DAB2
-:101C4000055B0FD73DF71F27324A293E6FBDED9444
-:101C5000A0870682AEDB5225FCC48BE5339817863D
-:101C60006372CACCED22EFA8321D16CC3B663C064F
-:101C70008505062795A4957704CA3BDAF9C7A2BC67
-:101C800063B933EFA8E6B28C6F7256DEF1D6CD227F
-:101C9000EFA896CF040AEBB0F38D43F4A8B6909F5B
-:101CA000FF87AEF4CB5D6D853CA32E893CF8D571E2
-:101CB000F387F41C22613EFFDD794A3B1F89F04E19
-:101CC0004A17E5375BF0B93F5CC87FB9F399F6BDB9
-:101CD0008C1675E6E411A4CBE0ED7EC60FF6FA068D
-:101CE0001FFFF0EBE948E13E809DEFB4F39976DE0B
-:101CF00013D7FD4EF1BAE14960BB034FF84FD0F95D
-:101D0000E65E6F453CFD4B6A3F6FDD17985FDC0276
-:101D1000D6F888BB489FDFB4E838D7BE4BF89F6B36
-:101D20005411DF86A0CAFE4EE2DB0190096757AA74
-:101D300027492F76C14C37D1773024705EF6012FBA
-:101D4000DB49E8D6997F35AAC9F7216A3E5F661C50
-:101D5000C0C7D9292D48F1A7AF759AD0DD46EB1839
-:101D6000BB792BAD03713BD9BB371ABF12E17C3F66
-:101D7000DD7BAA22FFCF584E7110BDBBF47DA58E2E
-:101D8000E567B7F2BC951E20FF2C5B66BCA013BDB7
-:101D90009F5278BC3E1CC26CE5FB4B5D6A98C61135
-:101DA0007EF260E034F3ABA3D1B796E37A95A5FD5C
-:101DB000C0A5DD820E9B712C15C7792A9EAEA57534
-:101DC00053AC34CA722CFC3BBD1B6CFB759F674344
-:101DD000210E5621A7F56EB2D78F480A9D8F3E4B34
-:101DE0006E6C3FB13B61D6770B7E9834BF7D0FC8D8
-:101DF0009EFFEA6E61175FE9323F44EDDA681E929A
-:101E00004B2D13273D6C49A33C48AC3FAE3CBC90E6
-:101E10000BB7BCDAF2369787B7E450D244BE16E56A
-:101E2000AA8DF6074FEB531E89F2EDE91347A8EF91
-:101E300025E6BB3F9D3037D1BA77C7531D54BE71DD
-:101E4000EF6DC0799D0BBCC7D1B1BC3F4A79FCE1B5
-:101E500032819B1F8D1B0E7B77B7459FBBBB055EF9
-:101E6000BA1665669AF44031AA80F5F82EC6D1B646
-:101E70007D1A1B487FEFE78D85FED90198A47CD0A1
-:101E800042EBF01EDAC771DDC1BA849FEC0FDAB7FE
-:101E90002AAA0FD799D1E275642B859C679689B8D9
-:101EA00005C5D332BEC2FBBDDD32EFA7B30EF224AF
-:101EB0003BBE80C8BBF95071753C7F7C662CCFB8A7
-:101EC0002600931462F814E90FDDFF8B186092BFAF
-:101ED000599702D26F9F56E84F79D4CEBA7EBE6F23
-:101EE000B9D03872D4EE9FE6FEE3DD1A8FAB463CE4
-:101EF0008E38C0627473D36588E8D6B830DDD40BF1
-:101F0000A69BD03B37BD0E13BD909FCF863ECBFB2B
-:101F100083F73B59CF7C1AEE13CB31CBBEC80113EC
-:101F2000D29564A352882029CEDE0F9487B6E92C7F
-:101F30006B82CEB2D6CFFD7C7506A457135DD24C12
-:101F400017371DD04E00D9897F7EFC7884F0690751
-:101F5000D6A3C27E800FCB5F5BFEA0ADA75BE0C7C0
-:101F60000111FF769E17F3ECA9553E6AC59FDDCFA0
-:101F70006FE92913B84E0707DD2B2BB7323F4E8E82
-:101F8000B4323EC0F33343F7627A6A1BCBA97EB901
-:101F9000F388EEFCA13B4FE8CE0F16E4C6F4D33A2B
-:101FA0007FAB9DCE7CB484BCD8E5114BDF8606FCAC
-:101FB00025F5EE08EA3BF16FB8DDCC50DEE860684D
-:101FC00026CA7233F52EE362E525D9207CA9288242
-:101FD000CF3DCB66988FBD311328DF746460DB770B
-:101FE0008AC7FD753CFD23B26715DAA449E30420D6
-:101FF0009FA1F36773B5D95F0A37FD9B6547BA1395
-:10200000A97F257BD5A10BFEC7E2E6AB6C172FD0CD
-:102010006E2DA44F8A4DBB8BD6A7D3429F62FB582F
-:102020009F46EBFA19678DFE58262455C091963EBF
-:102030008DB69F617DB7F5EA3D4B9F3A63422F28ED
-:102040008E40E777B0CE64BBF15F963E29A827A407
-:102050004F3E4B9F825AA13DC5C73B89CEF85CA934
-:102060009BE17EC198A57FA44F01BA3F0C8C0386EB
-:1020700051EF282EE2D6AF8E06716E6A89B4A7871B
-:10208000F0C5B2AD1C971FAEFBCF6AC62F96FC17EA
-:10209000F06E2B9FE7E7463C06E9430B01E8D6824A
-:1020A0001ED8FBDE382B431E59B36956E2F223B328
-:1020B000155C76CC967169CE5673199F0D719998FF
-:1020C000BD92CBCED95A2EBB66510FD621DF67EB1E
-:1020D000B9EC99BD96CBDED9555C2667D771BBBEEE
-:1020E000D9B55C6E9EBD9ECB1B66DBC53C4D625F69
-:1020F00025F481D26097411F8C0C54921E7CFC7594
-:10210000B6EF9ACA7794B2A10D9C27F22933AC0F8F
-:102110002763C2DEF706049FDCFAD09D48AF25BADC
-:10212000BBF5610EDF2AA011FD55B03E2EFC80F8F4
-:10213000A7BDA7E83EB21A3559CE109F7CB887F4E8
-:10214000E31271C21CCE5CAE321EB571E6E832C439
-:1021500099F5059C39DC2EFCB2EC033EF6DF764B9C
-:10216000E27ED9A713E91B7BD82F1671A2F4CD7E8E
-:102170008D707336D4130D505CEFA00C142F401CDF
-:1021800092E2764A4ADC67BD407D8EC5857ED8EDF9
-:102190005BE0B4A7FF2270CC1BF4B57D61BB10BE21
-:1021A000D473D6DB29EC8226EC42B6AE7F84F3D220
-:1021B0002EBB609FB3480F875DF85C8F854B2C3D2D
-:1021C0000FD789F3324C7601E9F3C51EDB2E38CFE9
-:1021D00059C5C621491B8758762129FA216E779C5B
-:1021E000B3C86E3F14E16294A3C19EB6F9F681CFE5
-:1021F000F3A2736EB0A1314EBF25089D8538896763
-:102200007056DF6C943877B25A2BEBC194D209C563
-:10221000F1958BD6B3907DEE987CEEB8DBD9FA368B
-:102220003CD527F6699D4353B87FB348DF7A3571B3
-:102230001EE1F9F3F59E12E74FC772339D2AB1CE26
-:10224000477B84BFF1834D16EE455C690418DF9728
-:10225000C40D8FF608BB4EBFD37802ED4F77329393
-:102260005574D6F34749CE37764DCB1446F8486CB3
-:10227000EC154A89A09E3EF6C7E8E9D1B895EFDB98
-:102280005F2D2E3B5BE562F26FE3225B0FE6EDA371
-:10229000DEDC568A1E4B7B05BE1F1CF1F4D1853F48
-:1022A0005B2EA694958C7F4AD85BD3B82CF6F6C2E9
-:1022B000F0C7149E83C4F7F3E08F374BD9DB85F06A
-:1022C000C7991E912747FCF10EF5EB6816F8636974
-:1022D0002FFCDFE08AF869A6DBA5E28A0F6CFBB170
-:1022E00000AEF0F6EAE27715DA0CDB8FE025E20AC1
-:1022F000B79D40FC50DE4BF431C4B96BFFDE842F38
-:1023000050169D5F6867AA7A055ECFD3E5B19381C9
-:102310004446623D4885E8F998B982E5E872E903E8
-:10232000E2C42B7B8BEA8BE9C505B79BDCC171400E
-:102330003B9FF9FBB2600BC547F6FB45F9B9F2E0EC
-:10234000492AC707441C7A94E27E588E7B81F307A2
-:102350004352B97152A27ECB7322DEDEBF86E29E6B
-:10236000D7F786AD7872FF75FCBB1BF8A2236FBA56
-:10237000F0BAC43D5F1AEA03BE0F5EA7711CDDA26E
-:102380004B981880F31E5EE5671C78B8EF91E377F1
-:10239000505CA64FC4C140D1EB3F4AE72FC29A58C8
-:1023A000D1B920837286E2F32374B79D41C7367199
-:1023B0000FDA5A4F7512FDF722FFA32A76D7F77E60
-:1023C000EEBC37E429CE231F31B75689CBCA77F14B
-:1023D00038B69E1C094CFAB5227B7374C079FFC9CC
-:1023E0005DCA6DAFF07DC3634D0AE72F1E581F29EC
-:1023F000233D39D42082B4E58D9E54AE843E0FF443
-:102400004A8EB876C83AE7CBBAC5BA169A6F784002
-:10241000C46FEDBA4F4F9924A7E5F56329A26B79F4
-:102420006344A2F8ABFDFEF65E61370E4B46BE0379
-:102430008979B8529C17BEBA0C78080F84F6AE237F
-:102440001AFBEBFAE14C80EE6F64E06D2CC3613552
-:102450005D6ADD83D6BA0F7B7329C2538757299CE7
-:10246000E7444C55324EF609CB4E97378EF3FAA01F
-:1024700051E17C95BBDD0EBB9D3AC6F98E438DDFE5
-:10248000D4695F87E807374B914BC9871F3A40767D
-:102490006600F9EA25794E73597ECDB798FEA32DD3
-:1024A0008A46FBE8969B0FD03CC79260105E71CBCA
-:1024B000C531D0CA687CB77C54AC7E8FE34FE54110
-:1024C000CA8C901CCEF8851D157216B0F8336A8838
-:1024D000BCCF684AE4AF6CFE15DE8BFB06E7520A00
-:1024E000FB2576FE6A0940491C67EBE590158F9F36
-:1024F000F77E799ECF9DA39BF251BA2711D4FC465B
-:1025000092C67DC4B9AE837876F2BAFA44FE62CE42
-:102510003EAF15FEE1FC758AF881F2CCBBC2AE5A23
-:102520007E42B0F93DB6ABF6BDAFDE8D425FABACDF
-:102530007BF755919429E872B7C31E48D7FC224314
-:1025400079A6076BC5DD84F04671AFB65C05234FF5
-:10255000F700FA027CBF6949CCCAD76D13F72BECA0
-:10256000FBE16A4475C41322505427DCE9AA83BCFA
-:10257000FDBCF7E0F6FFECC48BCF15F1FDA55EE7DF
-:102580003DF2C5FAFF7E20F7E27368908E19E7D717
-:10259000479B6F5F1E887169CBA52DA761DA62EB3F
-:1025A000C2FDC743A992799A6052E8C362762DE2D0
-:1025B00033DBDF41BE7BAB81F3675FD9E41CEF37D0
-:1025C00096BEFEC6D22F7539D4129E1A0B093B3027
-:1025D0005606DBBE5B426F972455B61B057D70E245
-:1025E0000A5B8EE6D363115CB1BA4BE00A2D5C4600
-:1025F000B8E898917881F281EF69AA5E2CB7EEB8BD
-:10260000BB8D2BD2493BFEA74A840BB4C00CE3ED33
-:10261000395C60E108372E28F7E6B6917E94AF5218
-:102620006D7BC576E5F3DFFFFB8732BCBF8C547C46
-:102630008E8EE66FE771C3AEB83B449CBF63798B67
-:10264000F017AE27AC4F4E2728FFB84511BF6F1BC0
-:1026500033A1F81ECEB8E7FDD83BD6F7F76D1C5274
-:102660004FEF8F4EF3EF6BE01E289EFFE04D3BF9DE
-:10267000F7148BF1DF5E17DDEB2AD69F8BD50F2386
-:1026800069E9471994917E9C83FB380F0F6349C712
-:10269000F9C41989256C12C407B7A96CB0A082547B
-:1026A000D01BE8B5F2E3E9393BA9503FC3EA564BEA
-:1026B000B72C64CA37E4F9778BB6BD39073FE379A5
-:1026C00033CF48D21CEEBA12DD7FFA3DE44A5A827B
-:1026D000E6A1D2BDFE1560F0F3064871F921E8E7E6
-:1026E000B209C6B8BC0626B96C86692E5BE02C9789
-:1026F0006B419769927560CAC05737D35CBF0E3281
-:102700005CB643BA9DEE970FD5EC5D4BE7D12D2E0D
-:102710003AD9742EA1F78C2B6D7AD8742F27E35DEC
-:10272000B3385FB321618F3B6379F61F0201819B50
-:102730006D7FDB1E67211C7CB9F09A8D33FF17CFAC
-:10274000A588169043000000000000000000000073
-:102750000000001800000000000000000000004021
-:102760000000000000000000000000280000000041
-:102770000000000000000010000000000000000049
-:102780000000002000000000000000000000001019
-:102790000000000000000000000000080000000031
-:1027A0000000000000000000000000000000000029
-:1027B0000000000000000000000000000000000019
-:1027C0000000000000000000000000000000000009
-:1027D00000000000000000000000000000000000F9
-:1027E00000000000000000000000000000000000E9
-:1027F00000000000000000000000000000000000D9
-:1028000000000000000000000000000000000000C8
-:1028100000000000000000000000000000000000B8
-:1028200000000000000000000000000000000000A8
-:102830000000000000000000000000000000000098
-:102840000000000000000000000000000000000088
-:102850000000000000000000000000000000000078
-:102860000000000000000000000000000000000068
-:102870000000000000000000000000000000000058
-:102880000000000000000000000000000000000048
-:102890000000000000000000000000000000000038
-:1028A0000000000000000000000000000000000028
-:1028B0000000000000000000000090000010000078
-:1028C0000000000800009008001000000000000256
-:1028D00000009000001000000000001000009DA803
-:1028E00000000000000000080000000000000000E0
-:1028F00000000000000000000000000000000000D8
-:10290000000000000000000000000000000091A096
-:102910000000000000000008000093C00001000457
-:1029200000000001000093C8000000000000000249
-:10293000000093D00000000000000008000093D4C5
-:102940000000000000000002000094980000000059
-:1029500000000008000093D80008000000000008F4
-:1029600000009B3800400000000000400000941868
-:102970000008000000000008000094580008000053
-:1029800000000008000094A800C8000000000098A3
-:10299000000096380098000000000028000096789B
-:1029A00000980000000000280000C0000540003032
-:1029B000000005400000CB200008000000000001DE
-:1029C0000000CB21000800000000000100002008EA
-:1029D00000100000000000100000200000000000B7
-:1029E0000000000800009D600008000000000002D8
-:1029F00000009DA000000000000000010000000099
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A80000000000000000000000000000000000046
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD00000000000000000000000000000000000F6
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B200000000000000000000000000000000000A5
-:102B30000000000000000000000000000000000095
-:102B40000000000000000000000000000000000085
-:102B50000000000000000000000000000000000075
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000000000000000000000000000000000045
-:102B900000000000000012C800800000000000805B
-:102BA0000000000100000000000000000000A00084
-:102BB000071000000000071000001EC80000000001
-:102BC000000000080000AEC000080000000000087F
-:102BD0000000AE4000080000000000080000AE80C9
-:102BE000000800000000000800002008001000009D
-:102BF000000000100000200000000000000000089D
-:102C00000000A01007100040000000400000AF408E
-:102C100000080000000000010000AF4100080000B3
-:102C20000000000100001ED00000000000000001B4
-:102C300000001ED8000000000000000200001EDAA4
-:102C40000000000000000002000012B000080000B8
-:102C5000000000080000000000000000000000006C
-:102C60000000000000000000000000000000000064
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000000000000000000044
-:102C90000000000000000000000000000000000034
-:102CA0000000000000000000000000000000000024
-:102CB0000000000000000000000000000000000014
-:102CC0000000000000000000000000000000000004
-:102CD00000000000000000000000000000000000F4
-:102CE00000000000000000000000000000000000E4
-:102CF00000000000000000000000000000000000D4
-:102D000000000000000000000000000000000000C3
-:102D100000000000000000000000000000000000B3
-:102D200000000000000000000000000000000000A3
-:102D30000000000000000000000000000000000093
-:102D40000000000000000000000000000000000083
-:102D50000000B00000180000000000180000B300E0
-:102D600000400000000000400000B30000400002EE
-:102D7000000000010000B30100400002000000005C
-:102D80000000800000400000000000400000000043
-:102D9000000000000000000000008000000800406B
-:102DA000000000040000800400080040000000044F
-:102DB0000000BB0000280000000000280000BC400C
-:102DC00000100000000000100000880000800000DB
-:102DD0000000008000008800000800800000000261
-:102DE00000008C00002000000000002000002008EF
-:102DF0000010000000000010000020000000000093
-:102E00000000000800001108000800000000000891
-:102E1000000011680008000000000008000011A870
-:102E20000008000000000008000012700008000008
-:102E30000000000100001271000800000000000105
-:102E400000008D00001000040000000400001320AA
-:102E50000030001800000010000013280030001897
-:102E60000000000200000000000000000000000060
-:102E7000000000000000000000000000000011E859
-:102E80000000000000000001000000000000000041
-:102E90000000000000000000000000000000000032
-:102EA0000000000000000000000000000000000022
-:102EB0000000000000000000000000000000000012
-:102EC0000000000000000000000000000000000002
-:102ED00000000000000000000000000000000000F2
-:102EE00000000000000000000000000000000000E2
-:102EF00000000000000000000000000000000000D2
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000000000000B1
-:102F20000000000000008308008000000000008016
-:102F30000000000100000000000000000000200868
-:102F40000010000000000010000020000000000041
-:102F50000000000800008D100008000000000008BC
-:102F600000008D7000080000000000080000845080
-:102F7000046000280000046000008EA0000800002B
-:102F80000000000100008EA1000800000000000108
-:102F900000008408000800000000000800008448C9
-:102FA000000000000000000100008DF40008000097
-:102FB0000000000200008DF6000800000000000282
-:102FC00000008E040010000000000004000000005B
-:102FD00000000000000000000000000000000000F1
-:102FE00000000000000000000000000000000000E1
-:102FF00000000000000000000000000000000000D1
-:1030000000000000000000000000000000000000C0
-:1030100000000000000000000000000000000000B0
-:1030200000000000000000000000000000000000A0
-:103030000000000000000000000000000000000090
-:103040000000000000000000000000000000000080
-:103050000000000000000000000000000000000070
-:103060000000000000000000000000000000000060
-:1030700000000000000030000040000000000008D8
-:1030800000003008004000000000002800003390DD
-:1030900001C0001000000008000032000020000005
-:1030A00000000020000037200000000000000008A1
-:1030B0000000102006200038000000080000A000DA
-:1030C000000000000000200000003EA900000000F9
-:1030D0000000000100003EC80000000000000002E7
-:1030E00000001C4000E00008000000080000000094
-:1030F0000000000000000000000040000008000088
-:103100000000000100004001000800000000000174
-:103110000000404000080004000000020000406081
-:103120000008000400000004000040000008000047
-:10313000000000040000400400080000000000043B
-:10314000000040400000000000000008000040486F
-:1031500000000000000000080000800000000000E7
-:1031600000000010000050400001000400000001B9
-:103170000000500000000000000000200000500887
-:1031800000100000000000040000500C00100000BF
-:1031900000000001000052C7000000000000000114
-:1031A000000052C6000000000000000100003000D6
-:1031B0000030001800000004000030040030001847
-:1031C0000000000400003008003000180000000279
-:1031D0000000300A00300018000000020000300C2F
-:1031E00000300018000000010000300D0030001811
-:1031F000000000010000300E003000180000000147
-:1032000000003010003000180000000400003014EE
-:103210000030001800000004000050000100008091
-:1032200000080004000050040100008000080004B1
-:103230000000000A000000000000000000005068CC
-:1032400001000080000000010000506901000080C2
-:10325000000000010000506C01000080000000022E
-:103260000000506E0100008000000002000050705D
-:103270000100008000000004000050740100008084
-:103280000000000400005066010000800000000201
-:103290000000506401000080000000010000506048
-:1032A0000100008000000002000050620100008068
-:1032B00000000002000050500100008000000004E7
-:1032C000000050540100008000000004000050582D
-:1032D00001000080000000040000505C010000803C
-:1032E000000000040000507C01000080000000018C
-:1032F0000000507D01000080000000010000401827
-:1033000000100000000000040000409000100000C9
-:1033100000000004000040980010000000000004BD
-:1033200000004110000000000000000200004112F7
-:103330000000000000000002000041140000000036
-:103340000000000200004116000000000000000222
-:103350000000604000080000000000020000604221
-:1033600000080000000000020000604400080000A7
-:103370000000000400006080000800000000000859
-:10338000000060C00040000800000008000060006D
-:1033900000080000000000020000600200080000B9
-:1033A00000000001000060040008000000000002AE
-:1033B0000000634000080000000000080000638077
-:1033C0000008000000000004000063840008000002
-:1033D00000000001000063C00008000000000002BF
-:1033E000000063C400080000000000020000640048
-:1033F0000008000000000004000070000010000041
-:103400000000000400007004001000000000000430
-:1034100000007008001000000000000400007000B0
-:103420000008000000000002000070020008000018
-:10343000000000010000700400080000000000020D
-:10344000000070400008000000000002000070440E
-:1034500000080000000000020000704600080000A4
-:10346000000000020000764800080000000000088C
-:10347000000070800008000000000002000070845E
-:10348000000800000000000200007688000800002C
-:10349000000000080000804000080000000000015B
-:1034A0000000804100080000000000010000804290
-:1034B0000008000000000001000080430008000038
-:1034C0000000000100008000000800000000000271
-:1034D00000008002000800000000000100008004DD
-:1034E0000008000000000002000080C0000800008A
-:1034F00000000002000080C200080000000000027E
-:10350000000080C40008000000000002000080806D
-:103510000008000000000001000080810008000099
-:10352000000000010000808200080000000000018F
-:10353000000080830008000000000001000080847B
-:103540000008000000000001000080850008000065
-:10355000000000010000808600080000000000015B
-:10356000000060000008000000000002000060028F
-:1035700000080000000000010000600400080000D6
-:10358000000000020000604200C0001800000002BD
-:103590000000604000C00018000000020000604C05
-:1035A00000C00018000000080000604400C00018BF
-:1035B000000000080000605700C000180000000173
-:1035C0000000605400C000180000000200006056B7
-:1035D00000C0001800000001000066400008000064
-:1035E00000000008000066800008000000000008DD
-:1035F000000066C000080000000000080000D9427A
-:1036000000180000000000020000DE400000000082
-:10361000000000000000E0000000000000000004C6
-:103620000000DD4000000000000000040000DD4458
-:1036300000000000000000040000DD480000000061
-:10364000000000040000DD4C000000000000000449
-:103650000000DD5000000000000000040000DD5408
-:1036600000000000000000040000DD580000000021
-:10367000000000040000DD40000000000000002009
-:103680000000DA0000000000000000040000DA0082
-:1036900000000000000000680000BB6000000000A7
-:1036A000000000000000D000000000000000000446
-:1036B0000000B0C000000000000000040000B0C422
-:1036C00000000000000000040000B0C8000000007E
-:1036D000000000040000B0C0000000000000001066
-:1036E0000000D6B000000000000000040000D6B4C6
-:1036F00000000000000000040000D6B80000000038
-:10370000000000040000D6BC00000000000000041F
-:103710000000D6B000000000000000100000D348F8
-:1037200000000000000000080000D3580000000066
-:1037300000000080000000100000000000000000F9
-:103740000000D35800000000000000080000000046
-:08375000060022000000000049
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex
new file mode 100644
index 000000000000..5f04df69e7c3
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex
@@ -0,0 +1,13181 @@
+:1000000000004F48000000680000070C00004FB8D7
+:1000100000001ED4000056C800000094000075A027
+:1000200000009F4C00007638000000CC00011588CD
+:100030000000DC4C00011658000000940001F2A8FA
+:10004000000040000001F340000000A4000233481B
+:100050000000F38C000233F000000FFC0003278047
+:100060000000000400033780020400480000000F75
+:1000700002040054000000450204005C0000000679
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040004000000FF02040008000000FF79
+:100170000204000C000000FF02040010000000FF59
+:10018000020400140000007F02040018000000FFB9
+:100190000204001C000000FF02040020000000FF19
+:1001A000020400240000003E0204002800000000B9
+:1001B0000204002C0000003F020400300000003F59
+:1001C000020400340000003F020400380000003F39
+:1001D0000204003C0000003F020400400000003F19
+:1001E000020400440000003F020404CC00000001AF
+:1001F00002042008000002110204200C000002008A
+:10020000020420100000020402042014000002195D
+:100210000204201C0000FFFF020420200000FFFF5A
+:10022000020420240000FFFF020420280000FFFF3A
+:1002300002042038000000200604203C0000001FBB
+:10024000020420B800000001060420BC0000005F8A
+:100250000204223807FFFFFF0204223C0000003F97
+:100260000204224007FFFFFF020422440000000FA7
+:1002700001042248000000000104224C000000009C
+:10028000010422500000000001042254000000007C
+:1002900001042258000000000104225C000000005C
+:1002A000010422600000000001042264000000003C
+:1002B00001042268000000000104226C000000001C
+:1002C00001042270000000000104227400000000FC
+:1002D00001042278000000000104227C00000000DC
+:1002E0000C042000000003E80A04200000000001C4
+:1002F0000B0420000000000A0605400000000D006D
+:100300000205004400000020020500480000003201
+:10031000020500900215002002050094021500203D
+:1003200002050098000000300205009C0810000043
+:10033000020500A000000033020500A40000003008
+:10034000020500A800000031020500AC0000000218
+:10035000020500B000000005020500B40000000620
+:10036000020500B800000002020500BC0000000207
+:10037000020500C000000000020500C400000005E6
+:10038000020500C800000002020500CC00000002C7
+:10039000020500D000000002020500D400000001A8
+:1003A00002050114000000010205011C000000010B
+:1003B0000205012000000002020502040000000105
+:1003C0000205020C0000004002050210000000407F
+:1003D0000205021C0000002002050220000000139C
+:1003E0000205022400000020060502400000000A69
+:1003F00004050280002000000205005000000007F4
+:10040000020500540000000702050058000000002B
+:100410000205005C00000008020500600000000109
+:100420000605006400000003020500D80000000675
+:1004300002050004000000010205000800000001A0
+:100440000205000C00000001020500100000000180
+:100450000205001400000001020500180000000160
+:100460000205001C00000001020500200000000140
+:100470000205002400000001020500280000000120
+:100480000205002C00000001020500300000000100
+:1004900002050034000000010205003800000001E0
+:1004A0000205003C000000010205004000000001C0
+:1004B000020500E00000000D020500E80000000059
+:1004C000020500F000000000020500F80000000036
+:1004D000020500E40000002D020500EC00000020F1
+:1004E000020500F400000020020500FC00000020CE
+:1004F000020500E00000001D020500E800000010F9
+:10050000020500F000000010020500F800000010D5
+:10051000020500E40000003D020500EC0000003090
+:10052000020500F400000030020500FC000000306D
+:10053000020500E00000004D020500E80000004058
+:10054000020500F000000040020500F80000004035
+:10055000020500E40000006D020500EC00000060F0
+:10056000020500F400000060020500FC00000060CD
+:10057000020500E00000005D020500E800000050F8
+:10058000020500F000000050020500F800000050D5
+:10059000020500E40000007D020500EC0000007090
+:1005A000020500F400000070020500FC000000706D
+:1005B0000406100002000020020600DC000000011A
+:1005C000010600D80000000004060200000302201B
+:1005D000020600DC00000000010600B80000000078
+:1005E000010600C8000000000206016C00000000C7
+:1005F000010600BC00000000010600CC0000000065
+:1006000002060170000000000718040000910000BD
+:10061000081807D800050223071C00002BF700006C
+:10062000071C80002DD10AFE071D00002F461673FF
+:10063000071D800016342245081DB13049DA022515
+:100640000118000000000000011800040000000074
+:1006500001180008000000000118000C0000000054
+:100660000118001000000000011800140000000034
+:1006700002180020000000010218002400000002FF
+:1006800002180028000000030218002C00000000DF
+:1006900002180030000000040218003400000001BD
+:1006A00002180038000000000218003C00000001A1
+:1006B000021800400000000402180044000000007E
+:1006C00002180048000000010218004C000000035E
+:1006D0000218005000000000021800540000000141
+:1006E00002180058000000040218005C000000001E
+:1006F00002180060000000010218006400000003FE
+:1007000002180068000000000218006C00000001E0
+:1007100002180070000000040218007400000000BD
+:1007200002180078000000040218007C000000039A
+:100730000618008000000002021800A400003FFF1D
+:10074000021800A8000003FF0218022400000000A5
+:1007500002180234000000000218024C00000000E1
+:10076000021802E4000000FF061810000000040058
+:10077000021B8BC000000001021B8000000000343F
+:10078000021B804000000018021B80800000000C4B
+:10079000021B80C0000000200C1B83000007A1206A
+:1007A0000A1B8300000001380B1B83000000138824
+:1007B0000A1B8340000000000C1B8340000001F472
+:1007C0000B1B834000000005021B83800007A12053
+:1007D000021B83C0000001F4021B14800000000112
+:1007E0000A1B148000000000061A1000000003B36A
+:1007F000041A1ECC00010227061A1ED000000008B1
+:10080000061A2008000000C8061A20000000000296
+:10081000041AAF4000100228061A3718000000041E
+:10082000061A371000000002061A500000000002ED
+:10083000061A500800000004061A501800000004B0
+:10084000061A502800000004061A50380000000460
+:10085000061A504800000004061A50580000000410
+:10086000061A506800000004061A507800000002C2
+:10087000041A52C000020238061A40500000000656
+:10088000041A40680002023A041A40400004023C84
+:10089000041A800000010240061A800400000003D0
+:1008A000041A801000010241061A8014000000039F
+:1008B000041A802000010242061A8024000000036E
+:1008C000041A803000010243061A8034000000033D
+:1008D000041A804000010244061A8044000000030C
+:1008E000041A805000010245061A805400000003DB
+:1008F000041A806000010246061A806400000003AA
+:10090000041A807000010247061A80740000000378
+:10091000041A808000010248061A80840000000347
+:10092000041A809000010249061A80940000000316
+:10093000041A80A00001024A061A80A400000003E5
+:10094000041A80B00001024B061A80B400000003B4
+:10095000041A80C00001024C061A80C40000000383
+:10096000041A80D00001024D061A80D40000000352
+:10097000041A80E00001024E061A80E40000000321
+:10098000041A80F00001024F061A80F400000003F0
+:10099000041A810000010250061A810400000003BD
+:1009A000041A811000010251061A8114000000038C
+:1009B000041A812000010252061A8124000000035B
+:1009C000041A813000010253061A8134000000032A
+:1009D000041A814000010254061A814400000003F9
+:1009E000041A815000010255061A815400000003C8
+:1009F000041A816000010256061A81640000000397
+:100A0000041A817000010257061A81740000000365
+:100A1000041A818000010258061A81840000000334
+:100A2000041A819000010259061A81940000000303
+:100A3000041A81A00001025A061A81A400000003D2
+:100A4000041A81B00001025B061A81B400000003A1
+:100A5000041A81C00001025C061A81C40000000370
+:100A6000041A81D00001025D061A81D4000000033F
+:100A7000041A81E00001025E061A81E4000000030E
+:100A8000041A81F00001025F061A81F400000003DD
+:100A9000041A820000010260061A820400000003AA
+:100AA000041A821000010261061A82140000000379
+:100AB000041A822000010262061A82240000000348
+:100AC000041A823000010263061A82340000000317
+:100AD000041A824000010264061A824400000003E6
+:100AE000041A825000010265061A825400000003B5
+:100AF000041A826000010266061A82640000000384
+:100B0000041A827000010267061A82740000000352
+:100B1000041A828000010268061A82840000000321
+:100B2000041A829000010269061A829400000003F0
+:100B3000041A82A00001026A061A82A400000003BF
+:100B4000041A82B00001026B061A82B4000000038E
+:100B5000041A82C00001026C061A82C4000000035D
+:100B6000041A82D00001026D061A82D4000000032C
+:100B7000041A82E00001026E061A82E400000003FB
+:100B8000041A82F00001026F061A82F400000003CA
+:100B9000041A830000010270061A83040000000397
+:100BA000041A831000010271061A83140000000366
+:100BB000041A832000010272061A83240000000335
+:100BC000041A833000010273061A83340000000304
+:100BD000041A834000010274061A834400000003D3
+:100BE000041A835000010275061A835400000003A2
+:100BF000041A836000010276061A83640000000371
+:100C0000041A837000010277061A8374000000033F
+:100C1000041A838000010278061A8384000000030E
+:100C2000041A839000010279061A839400000003DD
+:100C3000041A83A00001027A061A83A400000003AC
+:100C4000041A83B00001027B061A83B4000000037B
+:100C5000041A83C00001027C061A83C4000000034A
+:100C6000041A83D00001027D061A83D40000000319
+:100C7000041A83E00001027E061A83E400000003E8
+:100C8000041A83F00001027F061A83F400000003B7
+:100C9000041A840000010280061A84040000000384
+:100CA000041A841000010281061A84140000000353
+:100CB000041A842000010282061A84240000000322
+:100CC000041A843000010283061A843400000003F1
+:100CD000041A844000010284061A844400000003C0
+:100CE000041A845000010285061A8454000000038F
+:100CF000041A846000010286061A8464000000035E
+:100D0000041A847000010287061A8474000000032C
+:100D1000041A848000010288061A848400000003FB
+:100D2000041A849000010289061A849400000003CA
+:100D3000041A84A00001028A061A84A40000000399
+:100D4000041A84B00001028B061A84B40000000368
+:100D5000041A84C00001028C061A84C40000000337
+:100D6000041A84D00001028D061A84D40000000306
+:100D7000041A84E00001028E061A84E400000003D5
+:100D8000041A84F00001028F061A84F400000003A4
+:100D9000041A850000010290061A85040000000371
+:100DA000041A851000010291061A85140000000340
+:100DB000041A852000010292061A8524000000030F
+:100DC000041A853000010293061A853400000003DE
+:100DD000041A854000010294061A854400000003AD
+:100DE000041A855000010295061A8554000000037C
+:100DF000041A856000010296061A8564000000034B
+:100E0000041A857000010297061A85740000000319
+:100E1000041A858000010298061A858400000003E8
+:100E2000041A859000010299061A859400000003B7
+:100E3000041A85A00001029A061A85A40000000386
+:100E4000041A85B00001029B061A85B40000000355
+:100E5000041A85C00001029C061A85C40000000324
+:100E6000041A85D00001029D061A85D400000003F3
+:100E7000041A85E00001029E061A85E400000003C2
+:100E8000041A85F00001029F061A85F40000000391
+:100E9000041A8600000102A0061A8604000000035E
+:100EA000041A8610000102A1061A8614000000032D
+:100EB000041A8620000102A2061A862400000003FC
+:100EC000041A8630000102A3061A863400000003CB
+:100ED000041A8640000102A4061A8644000000039A
+:100EE000041A8650000102A5061A86540000000369
+:100EF000041A8660000102A6061A86640000000338
+:100F0000041A8670000102A7061A86740000000306
+:100F1000041A8680000102A8061A868400000003D5
+:100F2000041A8690000102A9061A869400000003A4
+:100F3000041A86A0000102AA061A86A40000000373
+:100F4000041A86B0000102AB061A86B40000000342
+:100F5000041A86C0000102AC061A86C40000000311
+:100F6000041A86D0000102AD061A86D400000003E0
+:100F7000041A86E0000102AE061A86E400000003AF
+:100F8000041A86F0000102AF061A86F4000000037E
+:100F9000041A8700000102B0061A8704000000034B
+:100FA000041A8710000102B1061A8714000000031A
+:100FB000041A8720000102B2061A872400000003E9
+:100FC000041A8730000102B3061A873400000003B8
+:100FD000041A8740000102B4061A87440000000387
+:100FE000041A8750000102B5061A87540000000356
+:100FF000041A8760000102B6061A87640000000325
+:10100000041A8770000102B7061A877400000003F3
+:10101000041A8780000102B8061A878400000003C2
+:10102000041A8790000102B9061A87940000000391
+:10103000041A87A0000102BA061A87A40000000360
+:10104000041A87B0000102BB061A87B4000000032F
+:10105000041A87C0000102BC061A87C400000003FE
+:10106000041A87D0000102BD061A87D400000003CD
+:10107000041A87E0000102BE061A87E4000000039C
+:10108000041A87F0000102BF061A87F4000000036B
+:10109000041A8800000102C0061A88040000000338
+:1010A000041A8810000102C1061A88140000000307
+:1010B000041A8820000102C2061A882400000003D6
+:1010C000041A8830000102C3061A883400000003A5
+:1010D000041A8840000102C4061A88440000000374
+:1010E000041A8850000102C5061A88540000000343
+:1010F000041A8860000102C6061A88640000000312
+:10110000041A8870000102C7061A887400000003E0
+:10111000041A8880000102C8061A888400000003AF
+:10112000041A8890000102C9061A8894000000037E
+:10113000041A88A0000102CA061A88A4000000034D
+:10114000041A88B0000102CB061A88B4000000031C
+:10115000041A88C0000102CC061A88C400000003EB
+:10116000041A88D0000102CD061A88D400000003BA
+:10117000041A88E0000102CE061A88E40000000389
+:10118000041A88F0000102CF061A88F40000000358
+:10119000041A8900000102D0061A89040000000325
+:1011A000041A8910000102D1061A891400000003F4
+:1011B000041A8920000102D2061A892400000003C3
+:1011C000041A8930000102D3061A89340000000392
+:1011D000041A8940000102D4061A89440000000361
+:1011E000041A8950000102D5061A89540000000330
+:1011F000041A8960000102D6061A896400000003FF
+:10120000041A8970000102D7061A897400000003CD
+:10121000041A8980000102D8061A8984000000039C
+:10122000041A8990000102D9061A8994000000036B
+:10123000041A89A0000102DA061A89A4000000033A
+:10124000041A89B0000102DB061A89B40000000309
+:10125000041A89C0000102DC061A89C400000003D8
+:10126000041A89D0000102DD061A89D400000003A7
+:10127000041A89E0000102DE061A89E40000000376
+:10128000041A89F0000102DF061A89F40000000345
+:10129000041A8A00000102E0061A8A040000000312
+:1012A000041A8A10000102E1061A8A1400000003E1
+:1012B000041A8A20000102E2061A8A2400000003B0
+:1012C000041A8A30000102E3061A8A34000000037F
+:1012D000041A8A40000102E4061A8A44000000034E
+:1012E000041A8A50000102E5061A8A54000000031D
+:1012F000041A8A60000102E6061A8A6400000003EC
+:10130000041A8A70000102E7061A8A7400000003BA
+:10131000041A8A80000102E8061A8A840000000389
+:10132000041A8A90000102E9061A8A940000000358
+:10133000041A8AA0000102EA061A8AA40000000327
+:10134000041A8AB0000102EB061A8AB400000003F6
+:10135000041A8AC0000102EC061A8AC400000003C5
+:10136000041A8AD0000102ED061A8AD40000000394
+:10137000041A8AE0000102EE061A8AE40000000363
+:10138000041A8AF0000102EF061A8AF40000000332
+:10139000041A8B00000102F0061A8B0400000003FF
+:1013A000041A8B10000102F1061A8B1400000003CE
+:1013B000041A8B20000102F2061A8B24000000039D
+:1013C000041A8B30000102F3061A8B34000000036C
+:1013D000041A8B40000102F4061A8B44000000033B
+:1013E000041A8B50000102F5061A8B54000000030A
+:1013F000041A8B60000102F6061A8B6400000003D9
+:10140000041A8B70000102F7061A8B7400000003A7
+:10141000041A8B80000102F8061A8B840000000376
+:10142000041A8B90000102F9061A8B940000000345
+:10143000041A8BA0000102FA061A8BA40000000314
+:10144000041A8BB0000102FB061A8BB400000003E3
+:10145000041A8BC0000102FC061A8BC400000003B2
+:10146000041A8BD0000102FD061A8BD40000000381
+:10147000041A8BE0000102FE061A8BE40000000350
+:10148000041A8BF0000102FF061A8BF4000000031F
+:10149000041A8C0000010300061A8C0400000003EB
+:1014A000041A8C1000010301061A8C1400000003BA
+:1014B000041A8C2000010302061A8C240000000389
+:1014C000041A8C3000010303061A8C340000000358
+:1014D000041A8C4000010304061A8C440000000327
+:1014E000041A8C5000010305061A8C5400000003F6
+:1014F000041A8C6000010306061A8C6400000003C5
+:10150000041A8C7000010307061A8C740000000393
+:10151000041A8C8000010308061A8C840000000362
+:10152000041A8C9000010309061A8C940000000331
+:10153000041A8CA00001030A061A8CA40000000300
+:10154000041A8CB00001030B061A8CB400000003CF
+:10155000041A8CC00001030C061A8CC4000000039E
+:10156000041A8CD00001030D061A8CD4000000036D
+:10157000041A8CE00001030E061A8CE4000000033C
+:10158000041A8CF00001030F061A8CF4000000030B
+:10159000041A8D0000010310061A8D0400000003D8
+:1015A000041A8D1000010311061A8D1400000003A7
+:1015B000041A8D2000010312061A8D240000000376
+:1015C000041A8D3000010313061A8D340000000345
+:1015D000041A8D4000010314061A8D440000000314
+:1015E000041A8D5000010315061A8D5400000003E3
+:1015F000041A8D6000010316061A8D6400000003B2
+:10160000041A8D7000010317061A8D740000000380
+:10161000041A8D8000010318061A8D84000000034F
+:10162000041A8D9000010319061A8D94000000031E
+:10163000041A8DA00001031A061A8DA400000003ED
+:10164000041A8DB00001031B061A8DB400000003BC
+:10165000041A8DC00001031C061A8DC4000000038B
+:10166000041A8DD00001031D061A8DD4000000035A
+:10167000041A8DE00001031E061A8DE40000000329
+:10168000041A8DF00001031F061A8DF400000003F8
+:10169000041A8E0000010320061A8E0400000003C5
+:1016A000041A8E1000010321061A8E140000000394
+:1016B000041A8E2000010322061A8E240000000363
+:1016C000041A8E3000010323061A8E340000000332
+:1016D000041A8E4000010324061A8E440000000301
+:1016E000041A8E5000010325061A8E5400000003D0
+:1016F000041A8E6000010326061A8E64000000039F
+:10170000041A8E7000010327061A8E74000000036D
+:10171000041A8E8000010328061A8E84000000033C
+:10172000041A8E9000010329061A8E94000000030B
+:10173000041A8EA00001032A061A8EA400000003DA
+:10174000041A8EB00001032B061A8EB400000003A9
+:10175000041A8EC00001032C061A8EC40000000378
+:10176000041A8ED00001032D061A8ED40000000347
+:10177000041A8EE00001032E061A8EE40000000316
+:10178000041A8EF00001032F061A8EF400000003E5
+:10179000041A8F0000010330061A8F0400000003B2
+:1017A000041A8F1000010331061A8F140000000381
+:1017B000041A8F2000010332061A8F240000000350
+:1017C000041A8F3000010333061A8F34000000031F
+:1017D000041A8F4000010334061A8F4400000003EE
+:1017E000041A8F5000010335061A8F5400000003BD
+:1017F000041A8F6000010336061A8F64000000038C
+:10180000041A8F7000010337061A8F74000000035A
+:10181000041A8F8000010338061A8F840000000329
+:10182000041A8F9000010339061A8F9400000003F8
+:10183000041A8FA00001033A061A8FA400000003C7
+:10184000041A8FB00001033B061A8FB40000000396
+:10185000041A8FC00001033C061A8FC40000000365
+:10186000041A8FD00001033D061A8FD40000000334
+:10187000041A8FE00001033E061A8FE400000007FF
+:10188000041A62C00020033F061AD0000000007254
+:10189000061AD24800000010061AD6B00000002038
+:1018A000061AD47000000090061AD46800000002E6
+:1018B000061AA000000001C4061A30000000001043
+:1018C000061A308000000010061A310000000010D7
+:1018D000061A318000000010061A330000000012C2
+:1018E000061A339000000070061AD4580000000257
+:1018F000061AD34800000002061AD3580000002040
+:10190000061AA710000001C4061A3040000000109B
+:10191000061A30C000000010061A31400000001006
+:10192000061A31C000000010061A334800000012E9
+:10193000061A355000000070061AD460000000023C
+:10194000061AD35000000002061AD3D80000002067
+:10195000021AAE2000000000061A5000000000022B
+:10196000061A508000000012041A40000002035FB3
+:10197000041A63C000020361061A7000000000042C
+:10198000061A320000000008021AAE24000000000F
+:10199000061A501000000002061A50C8000000127B
+:1019A000041A400800020363041A63C800020365B6
+:1019B000061A701000000004061A32200000000809
+:1019C000021AAE2800000000061A50200000000293
+:1019D000061A511000000012041A4010000203679A
+:1019E000041A63D000020369061A70200000000484
+:1019F000061A324000000008021AAE2C0000000057
+:101A0000061A503000000002061A51580000001259
+:101A1000041A40180002036B041A63D80002036D15
+:101A2000061A703000000004061A32600000000838
+:101A3000021AAE3000000000061A504000000002FA
+:101A4000061A51A000000012041A40200002036F81
+:101A5000041A63E000020371061A704000000004DB
+:101A6000061A328000000008021AAE34000000009E
+:101A7000061A505000000002061A51E80000001239
+:101A8000041A402800020373041A63E80002037575
+:101A9000061A705000000004061A32A00000000868
+:101AA000021AAE3800000000061A50600000000262
+:101AB000061A523000000012041A40300002037768
+:101AC000041A63F000020379061A70600000000433
+:101AD000061A32C000000008021AAE3C00000000E6
+:101AE000061A507000000002061A52780000001218
+:101AF000041A40380002037B041A63F80002037DD5
+:101B0000061A707000000004061A32E00000000897
+:101B10000200A468000B01C80200A294071D29114D
+:101B20000200A298000000000200A29C009C042475
+:101B30000200A2A0000000000200A2A4000002090E
+:101B40000200A270000000000200A2740000000069
+:101B50000200A270000000000200A2740000000059
+:101B60000200A270000000000200A2740000000049
+:101B70000200A270000000000200A2740000000039
+:101B8000020160A000000001020160A400000262E6
+:101B9000020160A800000002020160AC0000001811
+:101BA0000201620400000001020100B40000000113
+:101BB000020100B800000001020100DC0000000189
+:101BC0000201010000000001020101040000000107
+:101BD0000201007C003000000201008400000028A7
+:101BE0000201008C0000000002010130000000042E
+:101BF0000201025C00000001020103280000000055
+:101C0000020160580000FFFF020160700000000741
+:101C10000201608000000001020105540000003054
+:101C2000020100C400000001020100CC000000011C
+:101C3000020100F800000001020100F000000001B4
+:101C4000020100800030000002010088000000282E
+:101C500002010090000000000201013400000004B5
+:101C6000020102DC000000010201032C0000000060
+:101C70000201605C0000FFFF0201607400000007C9
+:101C800002016084000000010201056400000030D0
+:101C9000020100C800000001020100D000000001A4
+:101CA000020100FC00000001020100F4000000013C
+:101CB000020C100000000028020C20080000021195
+:101CC000020C200C00000200020C20100000020494
+:101CD000020C201C0000FFFF020C20200000FFFF70
+:101CE000020C20240000FFFF020C20280000FFFF50
+:101CF000020C203800000020020C203C00000021D3
+:101D0000020C204000000022020C204400000023AE
+:101D1000020C204800000024020C204C000000258A
+:101D2000020C205000000026020C20540000002766
+:101D3000020C205800000028020C205C0000002942
+:101D4000020C20600000002A020C20640000002B1E
+:101D5000020C20680000002C020C206C0000002DFA
+:101D6000020C20700000002E020C20740000002FD6
+:101D7000020C207800000010060C207C00000007F8
+:101D8000020C209800000011020C209C00000012A0
+:101D9000020C20A000000013060C20A40000001D6F
+:101DA000020C211800000001020C211C000000019F
+:101DB000020C212000000001060C21240000001D5F
+:101DC000020C219800000001060C219C0000000775
+:101DD000020C21B800000001020C21BC000000012F
+:101DE000020C21C000000001020C21C4000000010F
+:101DF000020C21C800000001020C21CC00000001EF
+:101E0000020C21D000000001020C21D400000001CE
+:101E1000020C21D800000001020C21DC00000001AE
+:101E2000020C21E000000001020C21E4000000018E
+:101E3000020C21E800000001020C21EC000000016E
+:101E4000020C21F000000001020C21F4000000014E
+:101E5000020C21F800000001060C21FC0000000724
+:101E6000020C221800000001060C221C00000007D2
+:101E7000020C223807FFFFFF020C223C0000003F4B
+:101E8000020C224007FFFFFF020C22440000000F5B
+:101E9000010C224800000000010C224C0000000050
+:101EA000010C225000000000010C22540000000030
+:101EB000010C225800000000010C225C0000000010
+:101EC000010C226000000000010C226400000000F0
+:101ED000010C226800000000010C226C00000000D0
+:101EE000010C227000000000010C227400000000B0
+:101EF000010C227800000000010C227C0000000090
+:101F00000C0C2000000003E80A0C20000000000177
+:101F10000B0C20000000000A020C40080000101109
+:101F2000020C400C00001000020C401000001004D5
+:101F3000020C401400001021020C401C0000FFFFA6
+:101F4000020C40200000FFFF020C40240000FFFFB5
+:101F5000020C40280000FFFF020C40380000004641
+:101F6000020C403C00000010060C40400000000243
+:101F7000020C404800000018020C404C000000F029
+:101F8000060C40500000001F020C40CC0000000175
+:101F9000060C40D00000003A020C41B800000001DD
+:101FA000060C41BC00000003020C41C80000000107
+:101FB000020C41CC00000001060C41D00000001AC8
+:101FC000020C423807FFFFFF020C423C0000003FBA
+:101FD000020C424007FFFFFF020C42440000000FCA
+:101FE000010C424800000000010C424C00000000BF
+:101FF000010C425000000000010C4254000000009F
+:10200000010C425800000000010C425C000000007E
+:10201000010C426000000000010C4264000000005E
+:10202000010C426800000000010C426C000000003E
+:10203000010C427000000000010C4274000000001E
+:10204000010C427800000000010C427C00000000FE
+:10205000010C4280000000000C0C4000000003E86E
+:102060000A0C4000000000010B0C40000000000AB8
+:10207000060D400000000A00020D0044000000327E
+:10208000020D008C02150020020D009002150020A8
+:10209000020D009408100000020D009800000033AB
+:1020A000020D009C00000002020D00A000000000D4
+:1020B000020D00A400000005020D00A800000005AC
+:1020C000060D00AC00000002020D00B4000000028A
+:1020D000020D00B800000003020D00BC0000000269
+:1020E000020D00C000000001020D00C80000000247
+:1020F000020D00CC00000002020D015C0000000196
+:10210000020D016400000001020D016800000002E0
+:10211000020D020400000001020D020C000000206C
+:10212000020D021000000040020D021400000040E9
+:10213000020D022000000003020D0224000000181E
+:10214000060D028000000012040D03000018037F3A
+:10215000060D03600000000C020D004C00000001A1
+:10216000020D005000000002020D005400000000AB
+:10217000020D005800000008060D005C000000047D
+:10218000020D00C400000004020D00040000000164
+:10219000020D000800000001020D000C000000010B
+:1021A000020D001000000001020D001400000001EB
+:1021B000020D001800000001020D001C00000001CB
+:1021C000020D002000000001020D002400000001AB
+:1021D000020D002800000001020D002C000000018B
+:1021E000020D003000000001020D0034000000016B
+:1021F000020D003800000001020D003C000000014B
+:10220000020D011400000009020D011C0000000A6B
+:10221000020D012400000000020D012C000000004E
+:10222000020D013400000000020D013C0000000B13
+:10223000020D014400000000020D011800000029F9
+:10224000020D01200000002A020D012800000020DC
+:10225000020D013000000020020D013800000020B6
+:10226000020D01400000002B020D0148000000207B
+:10227000020D011400000019020D011C0000001ADB
+:10228000020D012400000010020D012C00000010BE
+:10229000020D013400000010020D013C0000001B83
+:1022A000020D014400000010020D01180000003969
+:1022B000020D01200000003A020D0128000000304C
+:1022C000020D013000000030020D01380000003026
+:1022D000020D01400000003B020D014800000030EB
+:1022E000020D011400000049020D011C0000004A0B
+:1022F000020D012400000040020D012C00000040EE
+:10230000020D013400000040020D013C0000004BB2
+:10231000020D014400000040020D01180000006998
+:10232000020D01200000006A020D0128000000607B
+:10233000020D013000000060020D01380000006055
+:10234000020D01400000006B020D0148000000601A
+:10235000020D011400000059020D011C0000005A7A
+:10236000020D012400000050020D012C000000505D
+:10237000020D013400000050020D013C0000005B22
+:10238000020D014400000050020D01180000007908
+:10239000020D01200000007A020D012800000070EB
+:1023A000020D013000000070020D013800000070C5
+:1023B000020D01400000007B020D0148000000708A
+:1023C000060E200000000800020E004C0000003243
+:1023D000020E009402150020020E00980215002043
+:1023E000020E009C00000030020E00A00810000049
+:1023F000020E00A400000033020E00A8000000300E
+:10240000020E00AC00000031020E00B0000000021D
+:10241000020E00B400000004020E00B8000000002C
+:10242000020E00BC00000002020E00C0000000020C
+:10243000020E00C400000000020E00C800000002EE
+:10244000020E00CC00000007020E00D000000002C7
+:10245000020E00D400000002020E00D800000001AD
+:10246000020E014400000001020E014C00000001B8
+:10247000020E015000000002020E020400000001E2
+:10248000020E020C00000040020E0210000000408C
+:10249000020E021C00000004020E022000000020B8
+:1024A000020E02240000000E020E02280000001B93
+:1024B000060E030000000012040E0280001B0397AA
+:1024C000060E02EC00000005020E00540000000C95
+:1024D000020E00580000000C020E005C000000001C
+:1024E000020E006000000010020E006400000010E8
+:1024F000060E006800000003020E00DC000000036E
+:10250000020E000400000001020E0008000000019D
+:10251000020E000C00000001020E0010000000017D
+:10252000020E001400000001020E0018000000015D
+:10253000020E001C00000001020E0020000000013D
+:10254000020E002400000001020E0028000000011D
+:10255000020E002C00000001020E003000000001FD
+:10256000020E003400000001020E003800000001DD
+:10257000020E003C00000001020E004000000001BD
+:10258000020E004400000001020E01100000000FC6
+:10259000020E011800000000020E012000000000E1
+:1025A000020E012800000000020E01140000002F9E
+:1025B000020E011C00000020020E01240000000099
+:1025C000020E012C00000000020E01100000001F8E
+:1025D000020E011800000010020E01200000000091
+:1025E000020E012800000000020E01140000003F4E
+:1025F000020E011C00000030020E01240000000049
+:10260000020E012C00000000020E01100000004F1D
+:10261000020E011800000040020E01200000000020
+:10262000020E012800000000020E01140000006FDD
+:10263000020E011C00000060020E012400000000D8
+:10264000020E012C00000000020E01100000005FCD
+:10265000020E011800000050020E012000000000D0
+:10266000020E012800000000020E01140000007F8D
+:10267000020E011C00000070020E01240000000088
+:10268000020E012C000000000730040000C9000009
+:10269000083007D8000503B20734000033320000C9
+:1026A0000734800030A70CCD07350000353518F70A
+:1026B000073580002A6226450736000018D330DE31
+:1026C00008364660373403B40130000000000000D3
+:1026D000013000040000000001300008000000008C
+:1026E0000130000C0000000001300010000000006C
+:1026F0000130001400000000023000200000000142
+:102700000230002400000002023000280000000314
+:102710000230002C000000000230003000000004F5
+:1027200002300034000000010230003800000000D8
+:102730000230003C000000010230004000000004B4
+:102740000230004400000000023000480000000198
+:102750000230004C00000003023000500000000076
+:102760000230005400000001023000580000000454
+:102770000230005C00000000023000600000000138
+:102780000230006400000003023000680000000016
+:102790000230006C000000010230007000000004F4
+:1027A00002300074000000000230007800000004D5
+:1027B0000230007C000000030630008000000002B0
+:1027C000023000A400003FFF023000A8000003FF19
+:1027D0000230022400000000023002340000000039
+:1027E0000230024C00000000023002E40000FFFF53
+:1027F000063020000000080002338BC000000001FA
+:10280000023380000000001A023380400000004EB6
+:102810000233808000000010023380C000000020DE
+:102820000C3383000007A1200A3383000000013825
+:102830000B338300000013880A338340000000003C
+:102840000C338340000001F40B338340000000058B
+:10285000023383800007A120023383C0000001F40B
+:1028600002331480000000010A33148000000000CD
+:10287000063280000000010206322008000000C875
+:10288000063220000000000204328EA0001003B6C1
+:1028900006323EB00000000606323ED800000002BC
+:1028A00006323E800000000A04323EA8000203C641
+:1028B00006323E00000000200632500000000400F6
+:1028C0000632400000000004043274C0000203C855
+:1028D00006324110000000020632D0000000003035
+:1028E0000632DD40000000440632DA00000000D06D
+:1028F0000632DEA0000000020632E0000000080000
+:1029000006328450000001180632100000000188D1
+:102910000632500000000020063251000000002066
+:102920000632520000000020063253000000002052
+:10293000063254000000002006325500000000203E
+:10294000063256000000002006325700000000202A
+:102950000632580000000020063259000000002016
+:1029600006325A000000002006325B000000002002
+:1029700006325C000000002006325D0000000020EE
+:1029800006325E000000002006325F0000000020DA
+:1029900006328DF00000000204328E00000203CAED
+:1029A00006328E08000000020632DE9000000002AF
+:1029B00006321C4000000038063288B000000118C2
+:1029C00006321620000001880632508000000020E8
+:1029D00006325180000000200632528000000020A4
+:1029E0000632538000000020063254800000002090
+:1029F000063255800000002006325680000000207C
+:102A00000632578000000020063258800000002067
+:102A1000063259800000002006325A800000002053
+:102A200006325B800000002006325C80000000203F
+:102A300006325D800000002006325E80000000202B
+:102A400006325F800000002006328DF80000000290
+:102A500004328E10000203CC06328E1800000002F1
+:102A60000632DE980000000206321D200000003809
+:102A700002328D50000000000632401000000002BB
+:102A800002328D5400000000063240200000000297
+:102A900002328D5800000000063240300000000273
+:102AA00002328D5C0000000006324040000000024F
+:102AB00002328D600000000006324050000000022B
+:102AC00002328D6400000000063240600000000207
+:102AD00002328D68000000000632407000000002E3
+:102AE00002328D6C000000000632408000000002BF
+:102AF000072004000091000008200780001003CE8A
+:102B0000072400002AF300000724800015090ABDED
+:102B10000824A9F0692803D001200000000000006B
+:102B20000120000400000000012000080000000057
+:102B30000120000C00000000012000100000000037
+:102B4000012000140000000002200020000000010D
+:102B500002200024000000020220002800000003E0
+:102B60000220002C000000000220003000000004C1
+:102B700002200034000000010220003800000000A4
+:102B80000220003C00000001022000400000000480
+:102B90000220004400000000022000480000000164
+:102BA0000220004C00000003022000500000000042
+:102BB0000220005400000001022000580000000420
+:102BC0000220005C00000000022000600000000104
+:102BD00002200064000000030220006800000000E2
+:102BE0000220006C000000010220007000000004C0
+:102BF00002200074000000000220007800000004A1
+:102C00000220007C0000000306200080000000027B
+:102C1000022000A400003FFF022000A8000003FFE4
+:102C20000220022400000000022002340000000004
+:102C30000220024C00000000022002E40000FFFF1E
+:102C4000062020000000080002238BC000000001C5
+:102C500002238000000000100223804000000012C8
+:102C60000223808000000030022380C00000000E9C
+:102C70000C2383000007A1200A23830000000138F1
+:102C80000B238300000013880A2383400000000008
+:102C90000C238340000001F40B2383400000000557
+:102CA000022383800007A120022383C0000001F4D7
+:102CB00002231480000000010A2314800000000099
+:102CC000062210000000004206222008000000C872
+:102CD00006222000000000020622B000000000C60C
+:102CE0000422B318000503D20622B32C0000000B07
+:102CF0000422B358000503D70622B36C0000000B72
+:102D00000422B398000503DC0622B3AC0000000BDC
+:102D10000422B3D8000503E10622B3EC0000000B47
+:102D20000422B418000503E60622B42C0000000BB0
+:102D30000422B458000503EB0622B46C0000000B1B
+:102D40000422B498000503F00622B4AC0000000B86
+:102D50000422B4D8000503F50622B4EC0000000BF1
+:102D60000422B518000503FA0622B52C0000000B5A
+:102D70000422B558000503FF0622B56C0000000BC5
+:102D80000422B598000504040622B5AC0000000B2F
+:102D90000422B5D8000504090622B5EC0000000B9A
+:102DA0000422B6180005040E0622B62C0000000B03
+:102DB0000422B658000504130622B66C0000000B6E
+:102DC0000422B698000504180622B6AC0000000BD9
+:102DD0000422B6D80005041D0622B6EC0000000B44
+:102DE0000422B718000504220622B72C0000000BAD
+:102DF0000422B758000504270622B76C0000000B18
+:102E00000422B7980005042C0622B7AC0000000B82
+:102E10000422B7D8000504310622B7EC0000000BED
+:102E20000422B818000504360622B82C0000000B56
+:102E30000422B8580005043B0622B86C0000000BC1
+:102E40000422B898000504400622B8AC0000000B2C
+:102E50000422B8D8000504450622B8EC0000000B97
+:102E60000422B9180005044A0622B92C0000000B00
+:102E70000422B9580005044F0622B96C0000000B6B
+:102E80000422B998000504540622B9AC0000000BD6
+:102E90000422B9D8000504590622B9EC0000000B41
+:102EA0000422BA180005045E0622BA2C0000000BAA
+:102EB0000422BA58000504630622BA6C0000000B15
+:102EC0000422BA98000504680622BAAC0000000B80
+:102ED0000422BAD80005046D0622BAEC00000005F1
+:102EE0000622BB00000000530422BC4C0001047207
+:102EF0000622BC50000000030422BC5C00010473E5
+:102F00000622BC60000000030422BC6C00010474B3
+:102F10000622BC70000000030422BC7C0001047582
+:102F20000622BC80000000030422BC8C0001047651
+:102F30000622BC90000000030422BC9C0001047720
+:102F40000622BCA0000000030422BCAC00010478EF
+:102F50000622BCB0000000030422BCBC00010479BE
+:102F60000622880000000100062280000000020006
+:102F7000042212700010047A06223000000000C003
+:102F800006226700000001000622900000000400F5
+:102F900004226B080020048A022212C0FFFFFFFFF8
+:102FA000062211E800000002062212C800000009F3
+:102FB000062212EC0000000906228C000000000826
+:102FC0000222114800000000062213200000000623
+:102FD000062233000000000206226040000000309C
+:102FE00006228C20000000080222114C0000000084
+:102FF00006221338000000060622330800000002F3
+:10300000062261000000003006228C40000000080B
+:10301000022211500000000006221350000000069A
+:103020000622331000000002062261C000000030BA
+:1030300006228C60000000080222115400000000EB
+:103040000622136800000006062233180000000262
+:10305000062262800000003006228C8000000008FA
+:103060000222115800000000062213800000000612
+:1030700006223320000000020622634000000030D8
+:1030800006228CA0000000080222115C0000000053
+:1030900006221398000000060622332800000002D2
+:1030A000062264000000003006228CC000000008E8
+:1030B0000222116000000000062213B0000000068A
+:1030C0000622333000000002062264C000000030F7
+:1030D00006228CE0000000080222116400000000BB
+:1030E000062213C800000006062233380000000242
+:1030F0000622658000000030021610000000002843
+:1031000002170008000000020217002C0000000354
+:103110000217003C000000040217004800000002F3
+:103120000217004C000000900217005000000090B1
+:103130000217005400800090021700580810000089
+:10314000021700600000008A02170064000000807F
+:1031500002170068000000810217006C0000008068
+:10316000021700700000000602170078000007D068
+:103170000217007C0000076C02170038007C100466
+:10318000021700040000000F061640240000000291
+:10319000021640700000001C0216420800000001E8
+:1031A0000216421000000001021642200000000139
+:1031B0000216422800000001021642300000000101
+:1031C00002164238000000010216426000000002B0
+:1031D0000C16401C0003D0900A16401C0000009CF6
+:1031E0000B16401C000009C4021640300000000805
+:1031F000021640340000000C021640380000001097
+:1032000002164044000000200216400000000001A9
+:10321000021640D80000000102164008000000011C
+:103220000216400C000000010216401000000001D0
+:103230000216424000000000021642480000000052
+:103240000616427000000002021642500000000004
+:1032500002164258000000000616428000000002DC
+:1032600002166008000012240216600C0000121002
+:1032700002166010000012140216601C0000FFFF0E
+:10328000021660200000FFFF021660240000FFFF0E
+:10329000021660280000FFFF0216603800000020C0
+:1032A0000216603C0000002006166040000000028C
+:1032B00002166048000000230216604C0000002443
+:1032C000021660500000002502166054000000261F
+:1032D00002166058000000270216605C00000029FA
+:1032E000021660600000002A021660640000002BD5
+:1032F000021660680000002C0216606C0000002DB1
+:1033000002166070000000EC0216607400000011EC
+:1033100002166078000000120616607C0000000FA4
+:10332000021660B800000001021660BC0000000137
+:10333000061660C00000000C021660F000000001DC
+:10334000061660F400000031021661B800000001AA
+:10335000061661BC0000000D021661F000000001BD
+:10336000061661F4000000110216623807FFFFFF25
+:103370000216623C0000003F0216624007FFFFFF9A
+:10338000021662440000000F0116624800000000AF
+:103390000116624C0000000001166250000000009F
+:1033A000011662540000000001166258000000007F
+:1033B0000116625C0000000001166260000000005F
+:1033C000011662640000000001166268000000003F
+:1033D0000116626C0000000001166270000000001F
+:1033E00001166274000000000116627800000000FF
+:1033F0000116627C000000000C166000000003E86B
+:103400000A166000000000010B1660000000000AB0
+:1034100002168040000000060216804400000005ED
+:10342000021680480000000A0216804C00000005C9
+:103430000216805400000002021680CC0000000436
+:10344000021680D000000004021680D400000004A0
+:10345000021680D800000004021680DC0000000480
+:10346000021680E000000004021680E40000000460
+:10347000021680E800000004021688040000000420
+:10348000021680300000007C021680340000003DEF
+:10349000021680380000003F0216803C0000009CAD
+:1034A000021680F000000007061680F400000005F8
+:1034B0000216880C010101010216810800000000BB
+:1034C0000216810C000000040216811000000004A6
+:1034D0000216811400000002021688100801200460
+:1034E00002168118000000050216811C000000056C
+:1034F000021681200000000502168124000000054C
+:103500000216882C200810010216812800000008ED
+:103510000216812C00000006021681300000000710
+:1035200002168134000000000216883001010120DB
+:1035300006168138000000040216883401010101DA
+:1035400002168148000000000216814C00000004B1
+:10355000021681500000000402168154000000028F
+:103560000216883808012004021681580000000560
+:103570000216815C00000005021681600000000553
+:1035800002168164000000050216883C2008100124
+:1035900002168168000000080216816C0000000617
+:1035A00002168170000000070216817400000001FD
+:1035B00002168840010101200216817800000001F6
+:1035C0000216817C000000010216818000000001CB
+:1035D00002168184000000010216884401010101E5
+:1035E00002168188000000010216818C0000000490
+:1035F000021681900000000402168194000000026F
+:10360000021688480801200402168198000000056F
+:103610000216819C00000005021681A00000000532
+:10362000021681A40000000502168814200810016B
+:10363000021681A800000008021681AC00000006F6
+:10364000021681B000000007021681B400000001DC
+:103650000216881801010120021681B8000000013D
+:10366000021681BC00000001021681C000000001AA
+:10367000021681C4000000010216881C010101012C
+:10368000021681C800000001021681CC000000046F
+:10369000021681D000000004021681D4000000024E
+:1036A0000216882008012004021681D800000005B7
+:1036B000021681DC00000005021681E00000000512
+:1036C000021681E40000000502168824200810017B
+:1036D000021681E800000008021681EC00000006D6
+:1036E000021681F0000000070216E40C0000000042
+:1036F00002168828010101200616E41000000004CB
+:103700000216E000010101010216E42000000000A1
+:103710000216E424000000040216E428000000045D
+:103720000216E42C000000020216E0040801200446
+:103730000216E430000000050216E4340000000523
+:103740000216E438000000050216E43C0000000503
+:103750000216E008200810010216E44000000008EC
+:103760000216E444000000060216E44800000007C8
+:103770000216E44C000000000216E00C01010120DA
+:103780000616E450000000040216E01001010101D9
+:103790000216E460000000000216E4640000000469
+:1037A0000216E468000000040216E46C0000000247
+:1037B0000216E014080120040216E470000000055F
+:1037C0000216E474000000050216E478000000050B
+:1037D0000216E47C000000050216E0182008100123
+:1037E0000216E480000000080216E48400000006CF
+:1037F0000216E488000000070216E48C00000001B5
+:103800000216E01C010101200216E49000000001F4
+:103810000216E494000000010216E4980000000182
+:103820000216E49C000000010216E02001010101E3
+:103830000216E4A0000000010216E4A40000000447
+:103840000216E4A8000000040216E4AC0000000226
+:103850000216E024080120040216E4B0000000056E
+:103860000216E4B4000000050216E4B800000005EA
+:103870000216E4BC000000050216E0282008100132
+:103880000216E4C0000000080216E4C400000006AE
+:103890000216E4C8000000070216E4CC0000000194
+:1038A0000216E02C010101200216E4D00000000104
+:1038B0000216E4D4000000010216E4D80000000162
+:1038C0000216E4DC000000010216E03001010101F3
+:1038D0000216E4E0000000010216E4E40000000427
+:1038E0000216E4E8000000040216E4EC0000000206
+:1038F0000216E034080120040216E4F0000000057E
+:103900000216E4F4000000050216E4F800000005C9
+:103910000216E4FC000000050216E0382008100141
+:103920000216E500000000080216E504000000068B
+:103930000216E508000000070216E03C0101012024
+:1039400002168240003F003F021682440000000041
+:103950000216E524003F003F0216E52800000000A3
+:1039600002168248000000000216824C003F003F11
+:103970000216E52C000000000216E530003F003F73
+:10398000021682500100010002168254010001005B
+:103990000216E534010001000216E53801000100BD
+:1039A00006168258000000020216E53C00000000E6
+:1039B0000216E540000000000216826000C000C050
+:1039C0000216826400C000C00216E54400C000C0B8
+:1039D0000216E54800C000C0021682681E001E00E4
+:1039E0000216826C1E001E000216E54C1E001E0010
+:1039F0000216E5501E001E000216827040004000B4
+:103A000002168274400040000216E5544000400057
+:103A10000216E558400040000216827880008000BF
+:103A20000216827C800080000216E55C8000800027
+:103A30000216E560800080000216828020002000CF
+:103A400002168284200020000216E5642000200077
+:103A50000216E56820002000061682880000000299
+:103A60000216E56C000000000216E5700000000080
+:103A700002168290000000000216829400000000EE
+:103A80000216E574000000000216E5780000000050
+:103A900002168298000000000216829C00000000BE
+:103AA0000216E57C000000000216E5800000000020
+:103AB000021682A000000000021682A4000000018D
+:103AC000061682A80000000A021681F400000C0805
+:103AD000021681F800000040021681FC000001007F
+:103AE0000216820000000020021682040000001767
+:103AF00002168208000000800216820C00000200FC
+:103B000002168210000000000216821801FF01FF59
+:103B10000216821401FF01FF0216E51001FF01FFEA
+:103B20000216E50C01FF01FF0216823C00000013A3
+:103B3000021680900000013F0216806000000140E4
+:103B40000216806400000140061680680000000232
+:103B500002168070000000C0061680740000000786
+:103B60000216809C00000048021680A00000004859
+:103B7000061680A400000002021680AC0000004877
+:103B8000061680B000000007021682380000800090
+:103B900002168234000025E40216809400007FFFA4
+:103BA00002168220000F000F0216821C000F000F69
+:103BB0000216E518000F000F0216E514000F000FA3
+:103BC000021682280000000002168224FFFFFFFF79
+:103BD0000216E520000000000216E51CFFFFFFFFB3
+:103BE0000216E6BC000000000216E6C0000000025B
+:103BF0000216E6C4000000010216E6C80000000339
+:103C00000216E6CC000000040216E6D00000000612
+:103C10000216E6D4000000050216E6D800000007F0
+:103C2000021680EC000000FF0214000000000001FA
+:103C30000214000C0000000102140040000000010A
+:103C40000214004400007FFF0214000C000000007A
+:103C500002140000000000000214006C00000000CC
+:103C600002140004000000010214003000000001F2
+:103C700002140004000000000214005C00000000B8
+:103C800002140008000000010214003400000001CA
+:103C90000214000800000000021400600000000090
+:103CA00006028000000020000202005800000032DE
+:103CB000020200A003150020020200A40315002048
+:103CC000020200A801000030020200AC081000004F
+:103CD000020200B000000033020200B40000003015
+:103CE000020200B800000031020200BC0000000324
+:103CF000020200C000000006020200C4000000032F
+:103D0000020200C800000003020200CC0000000212
+:103D1000020200D000000000020200D400000002F5
+:103D2000020200DC00000000020200E000000006C9
+:103D3000020200E400000004020200E800000002A9
+:103D4000020200EC00000002020200F0000000018C
+:103D5000020200FC00000006020201200000000038
+:103D60000202013400000002020201B00000000162
+:103D70000202020C00000001020202140000000115
+:103D80000202021800000002020204040000000106
+:103D90000202040C00000040020204100000004077
+:103DA0000202041C000000040202042000000020A3
+:103DB0000202042400000002020204280000002085
+:103DC000060205000000001204020480002004AA7C
+:103DD000020200600000000F020200640000000701
+:103DE00002020068000000000202006C0000000EE9
+:103DF000020200700000000E0602007400000003C2
+:103E0000020200F4000000040202000400000001AD
+:103E100002020008000000010202000C0000000184
+:103E20000202001000000001020200140000000164
+:103E300002020018000000010202001C0000000144
+:103E40000202002000000001020200240000000124
+:103E500002020028000000010202002C0000000104
+:103E600002020030000000010202003400000001E4
+:103E700002020038000000010202003C00000001C4
+:103E800002020040000000010202004400000001A4
+:103E900002020048000000010202004C0000000184
+:103EA000020200500000000102020108000000C8E8
+:103EB0000202011800000002020201C4000000001A
+:103EC000020201CC00000000020201D40000000246
+:103ED000020201DC00000002020201E4000000FF17
+:103EE000020201EC000000FF0202010000000000DD
+:103EF0000202010C000000C80202011C00000002C6
+:103F0000020201C800000000020201D0000000000F
+:103F1000020201D800000002020201E000000002DB
+:103F2000020201E8000000FF020201F0000000FFB1
+:103F3000020201040000000002020108000000C8A3
+:103F40000202011800000002020201C40000000089
+:103F5000020201CC00000000020201D400000002B5
+:103F6000020201DC00000002020201E4000000FF86
+:103F7000020201EC000000FF02020100000000004C
+:103F80000202010C000000C80202011C0000000235
+:103F9000020201C800000000020201D0000000007F
+:103FA000020201D800000002020201E0000000024B
+:103FB000020201E8000000FF020201F0000000FF21
+:103FC000020201040000000002020108000000C813
+:103FD0000202011800000002020201C400000000F9
+:103FE000020201CC00000000020201D40000000225
+:103FF000020201DC00000002020201E4000000FFF6
+:10400000020201EC000000FF0202010000000000BB
+:104010000202010C000000C80202011C00000002A4
+:10402000020201C800000000020201D000000000EE
+:10403000020201D800000002020201E000000002BA
+:10404000020201E8000000FF020201F0000000FF90
+:10405000020201040000000002020108000000C882
+:104060000202011800000002020201C40000000068
+:10407000020201CC00000000020201D40000000294
+:10408000020201DC00000002020201E4000000FF65
+:10409000020201EC000000FF02020100000000002B
+:1040A0000202010C000000C80202011C0000000214
+:1040B000020201C800000000020201D0000000005E
+:1040C000020201D800000002020201E0000000022A
+:1040D000020201E8000000FF020201F0000000FF00
+:1040E00002020104000000000728040000A00000F4
+:1040F000082807B8000904CA072C000034DA0000B9
+:10410000072C800038F80D37072D000037B91B76D3
+:10411000072D800031782965072E00001C7A35C4F0
+:10412000082E48E036E404CC01280000000000001E
+:104130000128000400000000012800080000000021
+:104140000128000C00000000012800100000000001
+:1041500001280014000000000228002000000001D7
+:1041600002280024000000020228002800000003AA
+:104170000228002C0000000002280030000000048B
+:10418000022800340000000102280038000000006E
+:104190000228003C0000000102280040000000044A
+:1041A000022800440000000002280048000000012E
+:1041B0000228004C0000000302280050000000000C
+:1041C00002280054000000010228005800000004EA
+:1041D0000228005C000000000228006000000001CE
+:1041E00002280064000000030228006800000000AC
+:1041F0000228006C0000000102280070000000048A
+:10420000022800740000000002280078000000046A
+:104210000228007C00000003062800800000000245
+:10422000022800A400003FFF022800A8000003FFAE
+:1042300002280224000000000228023400000000CE
+:104240000228024C00000000022802E40000FFFFE8
+:104250000628200000000800022B8BC0000000018F
+:10426000022B800000000000022B8040000000189C
+:10427000022B80800000000C022B80C00000006632
+:104280000C2B83000007A1200A2B830000000138BB
+:104290000B2B8300000013880A2B834000000000D2
+:1042A0000C2B8340000001F40B2B83400000000521
+:1042B000022B83800007A120022B83C0000001F4A1
+:1042C000022B1480000000010A2B14800000000063
+:1042D000062A9AF800000004042A9B08000204CE73
+:1042E000062A9B1000000006062A90800000004865
+:1042F000062A2008000000C8062A2000000000024C
+:10430000062A91A800000086062A900000000020DE
+:10431000062A93C800000003042A93D4000104D0A5
+:10432000062A9DA800000002042A9498000404D1E3
+:10433000042A9D58000104D5062A9D5C0000001146
+:10434000042ACB20001004D6042A3000000204E620
+:10435000062A300800000100062A40400000001034
+:10436000042A4000001004E8042A8408000204F82B
+:10437000062A9DA000000002062AB000000000509E
+:10438000062ABB7000000070062AB150000000022F
+:10439000062ABB6000000004062AD00000000800C6
+:1043A000062AC00000000150062A94A8000000322E
+:1043B000062A502000000002062A503000000002A9
+:1043C000062A500000000002062A501000000002D9
+:1043D000022A520800000001042A9B28000204FA65
+:1043E000062A963800000022042A96C0000104FC28
+:1043F000062A96C400000003062A976800000022DF
+:10440000042A97F0000104FD062A97F40000000337
+:10441000062A989800000022042A9920000104FE30
+:10442000062A992400000003062A99C800000022E9
+:10443000042A9A50000104FF062A9A54000000033F
+:10444000062AB14000000002062AC54000000150C3
+:10445000062A957000000032062A5028000000024B
+:10446000062A503800000002062A50080000000208
+:10447000062A501800000002022A520C0000000117
+:10448000042A9B3000020500062A96D00000002274
+:10449000042A975800010502062A975C00000003D1
+:1044A000062A980000000022042A988800010503CB
+:1044B000062A988C00000003062A9930000000228A
+:1044C000042A99B800010504062A99BC00000003DB
+:1044D000062A9A6000000022042A9AE800010505D5
+:1044E000062A9AEC00000003062AB14800000002E8
+:1044F000022ACA8000000000042A9B38001005062A
+:10450000062A50480000000E022ACA84000000005B
+:10451000042A9B7800100516062A50800000000E21
+:10452000022ACA8800000000042A9BB80010052651
+:10453000062A50B80000000E022ACA8C00000000B3
+:10454000042A9BF800100536062A50F00000000EE1
+:10455000022ACA9000000000042A9C380010054678
+:10456000062A51280000000E022ACA94000000000A
+:10457000042A9C7800100556062A51600000000E9F
+:10458000022ACA9800000000042A9CB800100566A0
+:10459000062A51980000000E022ACA9C0000000062
+:1045A000042A9CF800100576062A51D00000000E5F
+:1045B000021010080000000102101050000000015D
+:1045C000021010000003D000021010040000003D93
+:1045D0000910180002000586091011000010078656
+:1045E0000610114000000008091011600010079625
+:1045F000061011A00000001806102400000000E0C2
+:104600000210201C00000000021020200000000109
+:10461000021020C00000000202102004000000016F
+:10462000021020080000000109103C00000507A648
+:1046300009103800000507AB09103820000507B045
+:1046400006104C000000010002104028000000107D
+:104650000210404400003FFF0210405800280000B4
+:10466000021040840084924A02104058000000006A
+:104670000210800000001080021080AC00000000DA
+:1046800002108038000000100210810000000000BD
+:10469000061081200000000202108008000002B510
+:1046A0000210801000000000061082000000004A86
+:1046B000021081080001FFFF061081400000000287
+:1046C0000210800000001A800610900000000024F4
+:1046D000061091200000004A061093700000004A66
+:1046E000061095C00000004A0210800400001080EF
+:1046F000021080B0000000010210803C0000001099
+:104700000210810400000000061081280000000251
+:104710000210800C000002B502108014000000009E
+:10472000061084000000004A0210810C0001FFFF07
+:1047300006108148000000020210800400001A8068
+:104740000610909000000024061092480000004AD5
+:10475000061094980000004A061096E80000004AEF
+:104760000210800000001080021080AC00000002E7
+:1047700002108038000000100210810000000000CC
+:10478000061081200000000202108008000002B51F
+:104790000210801000000000061082000000004A95
+:1047A000021081080001FFFF061081400000000296
+:1047B0000210800000001A80061090000000002403
+:1047C000061091200000004A061093700000004A75
+:1047D000061095C00000004A0210800400001080FE
+:1047E000021080B0000000030210803C00000010A6
+:1047F0000210810400000000061081280000000261
+:104800000210800C000002B50210801400000000AD
+:10481000061084000000004A0210810C0001FFFF16
+:1048200006108148000000020210800400001A8077
+:104830000610909000000024061092480000004AE4
+:10484000061094980000004A061096E80000004AFE
+:104850000210800000001080021080AC00000004F4
+:1048600002108038000000100210810000000000DB
+:10487000061081200000000202108008000002B52E
+:104880000210801000000000061082000000004AA4
+:10489000021081080001FFFF0610814000000002A5
+:1048A0000210800000001A80061090000000002412
+:1048B000061091200000004A061093700000004A84
+:1048C000061095C00000004A02108004000010800D
+:1048D000021080B0000000050210803C00000010B3
+:1048E0000210810400000000061081280000000270
+:1048F0000210800C000002B50210801400000000BD
+:10490000061084000000004A0210810C0001FFFF25
+:1049100006108148000000020210800400001A8086
+:104920000610909000000024061092480000004AF3
+:10493000061094980000004A061096E80000004A0D
+:104940000210800000001080021080AC0000000601
+:1049500002108038000000100210810000000000EA
+:10496000061081200000000202108008000002B53D
+:104970000210801000000000061082000000004AB3
+:10498000021081080001FFFF0610814000000002B4
+:104990000210800000001A80061090000000002421
+:1049A000061091200000004A061093700000004A93
+:1049B000061095C00000004A02108004000010801C
+:1049C000021080B0000000070210803C00000010C0
+:1049D000021081040000000006108128000000027F
+:1049E0000210800C000002B50210801400000000CC
+:1049F000061084000000004A0210810C0001FFFF35
+:104A000006108148000000020210800400001A8095
+:104A10000610909000000024061092480000004A02
+:104A2000061094980000004A061096E80000004A1C
+:104A3000021205B0000000010212049000E383405E
+:104A40000212051400003C100212066C0000000166
+:104A5000021206700000000002120494FFFFFFFF24
+:104A600002120498FFFFFFFF0212049CFFFFFFFFEA
+:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA
+:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA
+:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82
+:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
+:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
+:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
+:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
+:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
+:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
+:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
+:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
+:104B200002120504FFFFFFFF02120508FFFFFFFF4F
+:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
+:104B4000021204D4FF809000021204B4F00050005E
+:104B5000021204B8F00010000212039000000008D6
+:104B60000212039C00000008021203A000000008CB
+:104B7000021203A400000002021203BC00000004A1
+:104B8000021203C000000005021203C4000000046A
+:104B9000021203D0000000000212036C00000001AA
+:104BA000021203680000003F021201BC0000004036
+:104BB000021201C000001808021201C4000008031C
+:104BC000021201C800000803021201CC00000040DC
+:104BD000021201D000000003021201D400000803F9
+:104BE000021201D800000803021201DC00000803D1
+:104BF000021201E000010003021201E400000803B8
+:104C0000021201E800000803021201EC0000000398
+:104C1000021201F000000003021201F40000000380
+:104C2000021201F800000003021201FC0000000360
+:104C3000021202000000000302120204000000033E
+:104C400002120208000000030212020C000000031E
+:104C500002120210000000030212021400000003FE
+:104C600002120218000000030212021C00000003DE
+:104C700002120220000000030212022400000003BE
+:104C800002120228000024030212022C0000002F4E
+:104C90000212023000000009021202340000001962
+:104CA00002120238000001840212023C000001835B
+:104CB0000212024000000306021202440000001922
+:104CC00002120248000000060212024C0000030615
+:104CD00002120250000003060212025400000306F2
+:104CE0000212025800000C860212025C0000030649
+:104CF00002120260000003060212026400000006B5
+:104D000002120268000000060212026C0000000697
+:104D10000212027000000006021202740000000677
+:104D200002120278000000060212027C0000000657
+:104D30000212028000000006021202840000000637
+:104D400002120288000000060212028C0000000617
+:104D500002120290000000060212029400000006F7
+:104D600002120298000000060212029C00000006D7
+:104D7000021202A000000306021202A400000013A7
+:104D8000021202A800000006021202B00000100485
+:104D9000021202B400001004021203240010644046
+:104DA0000212032800106440021205B40000000142
+:104DB000021201B0000000010600A0000000000C7B
+:104DC0000200A050000000000200A05400000000FB
+:104DD0000200A0EC555400000200A0F055555555B6
+:104DE0000200A0F4000055550200A0F8F0000000F9
+:104DF0000200A0FC555400000200A1005555555575
+:104E00000200A104000055550200A108F0000000B6
+:104E10000200A18C555400000200A1905555555533
+:104E20000200A194000055550200A198F000000076
+:104E30000200A19C000000000200A1A000010000EF
+:104E40000200A1A4000050140200A1A8000000006C
+:104E50000200A45C00000C000200A61C000000037D
+:104E60000200A06CFF5C00000200A070FFF55FFF75
+:104E70000200A0740000FFFF0200A078F00003E031
+:104E80000200A07C000000000200A0800000A00042
+:104E90000600A084000000050200A0980FE00000BA
+:104EA0000600A09C000000070200A0B8000004005B
+:104EB0000600A0BC000000030200A0C80000100013
+:104EC0000600A0CC000000030200A0D800004000B3
+:104ED0000600A0DC000000030200A0E800010000C2
+:104EE0000600A22C000000040200A10CFF5C0000E0
+:104EF0000200A110FFF55FFF0200A1140000FFFFF8
+:104F00000200A118F00003E00200A11C0000000054
+:104F10000200A1200000A0000600A124000000055E
+:104F20000200A1380FE000000600A13C00000007CD
+:104F30000200A158000008000600A15C0000000368
+:104F40000200A168000020000600A16C0000000320
+:104F50000200A178000080000600A17C0000000390
+:104F60000200A188000200000600A23C000000042C
+:104F70000200A030000000000200A0340000000089
+:104F80000200A038000000000200A03C0000000069
+:104F90000200A040000000000200A0440000000049
+:104FA0000200A048000000000200A04C0000000029
+:104FB00000000000000000000000003000000000C1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE0000000000000300031000000000000000060
+:104FF00000000000000000000000000000000000B1
+:1050000000000000000000000000000000000000A0
+:10501000003100520000000000000000000000000D
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000052008995
+:1050400000000000000000000089008D008D00912C
+:1050500000910095009500990099009D009D00A188
+:1050600000A100A500A500A900A900AE00AE00B1F6
+:1050700000B100B4000000000000000000000000CB
+:105080000000000000000000000000000000000020
+:105090000000000000B40309030903130313031DF8
+:1050A000031D03240324032B032B03320332033990
+:1050B00003390340034003470347034E034E0355A0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:105170000355035B0000000000000000035B035CBC
+:10518000035C035D035D035E035E035F035F036017
+:1051900003600361036103620362036300000000B4
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000363036D036D037B1B
+:1051D000037B0389000000000000000000000000C5
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:105220000389038A00000000000000000000000065
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000038A03D6F8
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000003D604010000000050
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000040104330000000000000000C2
+:1052B0000433043A043A0441044104480448044FC6
+:1052C000044F04560456045D045D04640464046BD6
+:1052D000046B04A4000000000000000004A404A863
+:1052E00004A804AC04AC04B004B004B404B404B81E
+:1052F00004B804BC04BC04C004C004C404C4051342
+:105300000513052A052A05410541054305430545C1
+:1053100005450547054705490549054B054B054D1D
+:10532000054D054F054F0551055105E805E805E90F
+:1053300005E905EA05EA05EF05EF05F405F405F9C9
+:1053400005F905FE05FE0603060306080608060D18
+:10535000060D0612061206130000000000000000F1
+:10536000000000000000000000000000000000003D
+:10537000000000000000000000000000000000002D
+:1053800006130624000000000000000000000000DA
+:10539000000000000000000000000000000000000D
+:1053A0000000000000000000000000000624063994
+:1053B0000639063C063C063F0000000000000000E5
+:1053C00000000000000000000000000000000000DD
+:1053D0000000000000000000063F0675000000000D
+:1053E00000000000000000000000000000000000BD
+:1053F00000000000000000000000000000000000AD
+:1054000000000000067507780000000000000000A2
+:10541000000000000000000000000000000000008C
+:10542000000000000000000000000000000000007C
+:105430000778077F077F078307830787000000003F
+:10544000000000000000000000000000000000005C
+:10545000000000000000000000000000078707C8EF
+:10546000000000000000000007C807D107D107DADC
+:1054700007DA07E307E307EC07EC07F507F507FE94
+:1054800007FE080708070810081008670867087C67
+:10549000087C089108910894089408970897089A3E
+:1054A000089A089D089D08A008A008A308A308A6BC
+:1054B00008A608A908A908B2000000000000000022
+:1054C00000000000000000000000000000000000DC
+:1054D00000000000000000000000000000000000CC
+:1054E00008B208B800000000000000000000000042
+:1054F00000000000000000000000000000000000AC
+:1055000000000000000000000000000008B808BB18
+:10551000000000000000000000000000000000008B
+:10552000000000000000000000000000000000007B
+:10553000000000000000000008BB08C100000000DF
+:10554000000000000000000000000000000000005B
+:10555000000000000000000000000000000000004B
+:10556000000000000000000000000000000000003B
+:1055700008C108D008D008DF08DF08EE08EE08FDF3
+:1055800008FD090C090C091B091B092A092A0939FC
+:10559000093909AA00000000000000000000000016
+:1055A00000000000000000000000000000000000FB
+:1055B00000000000000000000000000009AA09BF70
+:1055C00009BF09D009D009E109E109E209E209E3CB
+:1055D00009E309E409E409E509E509E609E609E75B
+:1055E00009E709E809E809E90000000000000000F7
+:1055F00000000000000000000000000000000000AB
+:10560000000000000000000000000000000000009A
+:10561000000000000000000000000000000000008A
+:10562000000000000000000000000000000000007A
+:10563000000000000000000000000000000000006A
+:10564000000000000000000000000000000000005A
+:10565000000000000000000000000000000000004A
+:10566000000000000000000000000000000000003A
+:10567000000000000000000000000000000000002A
+:10568000000000000000000000000000000000001A
+:10569000000000000000000000000000000000000A
+:1056A00000000000000000000000000000000000FA
+:1056B00000000000000000000000000000000000EA
+:1056C000000000000000000000010000000204C013
+:1056D0000003098000040E4000051300000617C0F7
+:1056E00000071C800008214000092600000A2AC08B
+:1056F000000B2F80000C3440000D3900000E3DC01F
+:10570000000F42800010474000114C00001250C0B2
+:105710000013558000145A4000155F00001663C046
+:105720000017688000186D4000197200001A76C0DA
+:10573000001B7B80001C8040001D8500001E89C06E
+:10574000001F8E80000093400000200000004000F9
+:1057500000006000000080000000A0000000C00009
+:105760000000E000000100000001200000014000F6
+:1057700000016000000180000001A0000001C000E5
+:105780000001E000000200000002200000024000D2
+:1057900000026000000280000002A0000002C000C1
+:1057A0000002E000000300000003200000034000AE
+:1057B00000036000000380000003A0000003C0009D
+:1057C0000003E0000004000000042000000440008A
+:1057D00000046000000480000004A0000004C00079
+:1057E0000004E00000050000000520000005400066
+:1057F00000056000000580000005A0000005C00055
+:105800000005E00000060000000620000006400041
+:1058100000066000000680000006A0000006C00030
+:105820000006E0000007000000072000000740001D
+:1058300000076000000780000007A0000007C0000C
+:105840000007E000000800000008200000084000F9
+:1058500000086000000880000008A0000008C000E8
+:105860000008E000000900000009200000094000D5
+:1058700000096000000980000009A0000009C000C4
+:105880000009E000000A0000000A2000000A4000B1
+:10589000000A6000000A8000000AA000000AC000A0
+:1058A000000AE000000B0000000B2000000B40008D
+:1058B000000B6000000B8000000BA000000BC0007C
+:1058C000000BE000000C0000000C2000000C400069
+:1058D000000C6000000C8000000CA000000CC00058
+:1058E000000CE000000D0000000D2000000D400045
+:1058F000000D6000000D8000000DA000000DC00034
+:10590000000DE000000E0000000E2000000E400020
+:10591000000E6000000E8000000EA000000EC0000F
+:10592000000EE000000F0000000F2000000F4000FC
+:10593000000F6000000F8000000FA000000FC000EB
+:10594000000FE000001000000010200000104000D8
+:1059500000106000001080000010A0000010C000C7
+:105960000010E000001100000011200000114000B4
+:1059700000116000001180000011A0000011C000A3
+:105980000011E00000120000001220000012400090
+:1059900000126000001280000012A0000012C0007F
+:1059A0000012E0000013000000132000001340006C
+:1059B00000136000001380000013A0000013C0005B
+:1059C0000013E00000140000001420000014400048
+:1059D00000146000001480000014A0000014C00037
+:1059E0000014E00000150000001520000015400024
+:1059F00000156000001580000015A0000015C00013
+:105A00000015E000001600000016200000164000FF
+:105A100000166000001680000016A0000016C000EE
+:105A20000016E000001700000017200000174000DB
+:105A300000176000001780000017A0000017C000CA
+:105A40000017E000001800000018200000184000B7
+:105A500000186000001880000018A0000018C000A6
+:105A60000018E00000190000001920000019400093
+:105A700000196000001980000019A0000019C00082
+:105A80000019E000001A0000001A2000001A40006F
+:105A9000001A6000001A8000001AA000001AC0005E
+:105AA000001AE000001B0000001B2000001B40004B
+:105AB000001B6000001B8000001BA000001BC0003A
+:105AC000001BE000001C0000001C2000001C400027
+:105AD000001C6000001C8000001CA000001CC00016
+:105AE000001CE000001D0000001D2000001D400003
+:105AF000001D6000001D8000001DA000001DC000F2
+:105B0000001DE000001E0000001E2000001E4000DE
+:105B1000001E6000001E8000001EA000001EC000CD
+:105B2000001EE000001F0000001F2000001F4000BA
+:105B3000001F6000001F8000001FA000001FC000A9
+:105B4000001FE00000200000002020000020400096
+:105B500000206000002080000020A0000020C00085
+:105B60000020E00000210000002120000021400072
+:105B700000216000002180000021A0000021C00061
+:105B80000021E0000022000000222000002240004E
+:105B900000226000002280000022A0000022C0003D
+:105BA0000022E0000023000000232000002340002A
+:105BB00000236000002380000023A0000023C00019
+:105BC0000023E00000240000002420000024400006
+:105BD00000246000002480000024A0000024C000F5
+:105BE0000024E000002500000025200000254000E2
+:105BF00000256000002580000025A0000025C000D1
+:105C00000025E000002600000026200000264000BD
+:105C100000266000002680000026A0000026C000AC
+:105C20000026E00000270000002720000027400099
+:105C300000276000002780000027A0000027C00088
+:105C40000027E00000280000002820000028400075
+:105C500000286000002880000028A0000028C00064
+:105C60000028E00000290000002920000029400051
+:105C700000296000002980000029A0000029C00040
+:105C80000029E000002A0000002A2000002A40002D
+:105C9000002A6000002A8000002AA000002AC0001C
+:105CA000002AE000002B0000002B2000002B400009
+:105CB000002B6000002B8000002BA000002BC000F8
+:105CC000002BE000002C0000002C2000002C4000E5
+:105CD000002C6000002C8000002CA000002CC000D4
+:105CE000002CE000002D0000002D2000002D4000C1
+:105CF000002D6000002D8000002DA000002DC000B0
+:105D0000002DE000002E0000002E2000002E40009C
+:105D1000002E6000002E8000002EA000002EC0008B
+:105D2000002EE000002F0000002F2000002F400078
+:105D3000002F6000002F8000002FA000002FC00067
+:105D4000002FE00000300000003020000030400054
+:105D500000306000003080000030A0000030C00043
+:105D60000030E00000310000003120000031400030
+:105D700000316000003180000031A0000031C0001F
+:105D80000031E0000032000000322000003240000C
+:105D900000326000003280000032A0000032C000FB
+:105DA0000032E000003300000033200000334000E8
+:105DB00000336000003380000033A0000033C000D7
+:105DC0000033E000003400000034200000344000C4
+:105DD00000346000003480000034A0000034C000B3
+:105DE0000034E000003500000035200000354000A0
+:105DF00000356000003580000035A0000035C0008F
+:105E00000035E0000036000000362000003640007B
+:105E100000366000003680000036A0000036C0006A
+:105E20000036E00000370000003720000037400057
+:105E300000376000003780000037A0000037C00046
+:105E40000037E00000380000003820000038400033
+:105E500000386000003880000038A0000038C00022
+:105E60000038E0000039000000392000003940000F
+:105E700000396000003980000039A0000039C000FE
+:105E80000039E000003A0000003A2000003A4000EB
+:105E9000003A6000003A8000003AA000003AC000DA
+:105EA000003AE000003B0000003B2000003B4000C7
+:105EB000003B6000003B8000003BA000003BC000B6
+:105EC000003BE000003C0000003C2000003C4000A3
+:105ED000003C6000003C8000003CA000003CC00092
+:105EE000003CE000003D0000003D2000003D40007F
+:105EF000003D6000003D8000003DA000003DC0006E
+:105F0000003DE000003E0000003E2000003E40005A
+:105F1000003E6000003E8000003EA000003EC00049
+:105F2000003EE000003F0000003F2000003F400036
+:105F3000003F6000003F8000003FA000003FC00025
+:105F4000003FE000003FE00100000000000001FF12
+:105F50000000020000007FF800007FF80000014010
+:105F600000003500000000010000FF0000000000FC
+:105F70000000FF00000000000000FF000000000023
+:105F80000000FF00000000000000FF000000000013
+:105F90000000FF00000000000000FF000000000003
+:105FA0000000FF000000000000000000140AFF00D5
+:105FB00000000001000000000020100100000000AF
+:105FC0000100900000000100000090020000900419
+:105FD00000009006000090080000900A0000900C5D
+:105FE0000000900E0000901000009012000090142D
+:105FF00000009016000090180000901A0000901CFD
+:106000000000901E000090200000902200009024CC
+:1060100000009026000090280000902A0000902C9C
+:106020000000902E0000903000009032000090346C
+:1060300000009036000090380000903A0000903C3C
+:106040000000903E0000904000009042000090440C
+:1060500000009046000090480000904A0000904CDC
+:106060000000904E000090500000905200009054AC
+:1060700000009056000090580000905A0000905C7C
+:106080000000905E0000906000009062000090644C
+:1060900000009066000090680000906A0000906C1C
+:1060A0000000906E000090700000907200009074EC
+:1060B00000009076000090780000907A0000907CBC
+:1060C0000000907E0000908000009082000090848C
+:1060D00000009086000090880000908A0000908C5C
+:1060E0000000908E0000909000009092000090942C
+:1060F00000009096000090980000909A0000909CFC
+:106100000000909E000090A0000090A2000090A4CB
+:10611000000090A6000090A8000090AA000090AC9B
+:10612000000090AE000090B0000090B2000090B46B
+:10613000000090B6000090B8000090BA000090BC3B
+:10614000000090BE000090C0000090C2000090C40B
+:10615000000090C6000090C8000090CA000090CCDB
+:10616000000090CE000090D0000090D2000090D4AB
+:10617000000090D6000090D8000090DA000090DC7B
+:10618000000090DE000090E0000090E2000090E44B
+:10619000000090E6000090E8000090EA000090EC1B
+:1061A000000090EE000090F0000090F2000090F4EB
+:1061B000000090F6000090F8000090FA000090FCBB
+:1061C000000090FE00009100000091020000910488
+:1061D00000009106000091080000910A0000910C57
+:1061E0000000910E00009110000091120000911427
+:1061F00000009116000091180000911A0000911CF7
+:106200000000911E000091200000912200009124C6
+:1062100000009126000091280000912A0000912C96
+:106220000000912E00009130000091320000913466
+:1062300000009136000091380000913A0000913C36
+:106240000000913E00009140000091420000914406
+:1062500000009146000091480000914A0000914CD6
+:106260000000914E000091500000915200009154A6
+:1062700000009156000091580000915A0000915C76
+:106280000000915E00009160000091620000916446
+:1062900000009166000091680000916A0000916C16
+:1062A0000000916E000091700000917200009174E6
+:1062B00000009176000091780000917A0000917CB6
+:1062C0000000917E00009180000091820000918486
+:1062D00000009186000091880000918A0000918C56
+:1062E0000000918E00009190000091920000919426
+:1062F00000009196000091980000919A0000919CF6
+:106300000000919E000091A0000091A2000091A4C5
+:10631000000091A6000091A8000091AA000091AC95
+:10632000000091AE000091B0000091B2000091B465
+:10633000000091B6000091B8000091BA000091BC35
+:10634000000091BE000091C0000091C2000091C405
+:10635000000091C6000091C8000091CA000091CCD5
+:10636000000091CE000091D0000091D2000091D4A5
+:10637000000091D6000091D8000091DA000091DC75
+:10638000000091DE000091E0000091E2000091E445
+:10639000000091E6000091E8000091EA000091EC15
+:1063A000000091EE000091F0000091F2000091F4E5
+:1063B000000091F6000091F8000091FA000091FCB5
+:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFF0000000300BEBC2000000000B3
+:10645000000000050000000300BEBC20000000009A
+:10646000000000050000000300BEBC20000000008A
+:10647000000000050000000300BEBC20000000007A
+:10648000000000050000000300BEBC20000000006A
+:10649000000000050000000300BEBC20000000005A
+:1064A000000000050000000300BEBC20000000004A
+:1064B000000000050000000300BEBC20000000003A
+:1064C0000000000500002000000040C000006180C6
+:1064D000000082400000A3000000C3C00000E48070
+:1064E0000001054000012600000146C00001678050
+:1064F000000188400001A9000001C9C00001EA8034
+:1065000000020B4000022C0000024CC000026D8013
+:1065100000028E400002AF000002CFC00002F080F7
+:10652000000011400000800000010380000187008E
+:1065300000020A8000028E00000311800003950013
+:106540000004188000049C0000051F800005A300C3
+:10655000000626800006AA0000072D800007B10073
+:10656000000834800008B80000093B800009BF0023
+:10657000000A4280000AC600000B4980000BCD00D3
+:10658000000C5080000CD400000D578000005B0010
+:1065900000007FF800007FF8000000D50000150023
+:1065A0000000FF00000000000000FF0000000000ED
+:1065B0000000FF00000000000000FF0000000000DD
+:1065C0000000FF00000000000000FF0000000000CD
+:1065D0000000FF00000000000000FF0000000000BD
+:1065E000000019000000000000000000FFFFFFFF96
+:1065F0000000000003938700000000000393870061
+:1066000000007FF800007FF80000068E00003500D3
+:106610000000FF000FFFFFFF0000FF000FFFFFFF64
+:10662000000000FF0000FF000FFFFFFF0000FF0061
+:106630000FFFFFFF000000FF0000FF000FFFFFFF44
+:106640000000FF000FFFFFFF000000FF0000FF0041
+:106650000FFFFFFF0000FF000FFFFFFF000000FF24
+:106660000000FF000FFFFFFF0000FF000FFFFFFF14
+:10667000000000FF0000FF000FFFFFFF0000FF0011
+:106680000FFFFFFF000000FF0000FF000FFFFFFFF4
+:106690000000FF000FFFFFFF000000FF0000FF00F1
+:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4
+:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4
+:1066C000000000FF0000FF000FFFFFFF0000FF00C1
+:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4
+:1066E0000000FF000FFFFFFF000000FF0000FF00A1
+:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84
+:106700000000FF000FFFFFFF0000FF000FFFFFFF73
+:10671000000000FF0000FF000FFFFFFF0000FF0070
+:106720000FFFFFFF000000FF0000FF000FFFFFFF53
+:106730000000FF000FFFFFFF000000FF0000FF0050
+:106740000FFFFFFF0000FF000FFFFFFF000000FF33
+:106750000000FF000FFFFFFF0000FF000FFFFFFF23
+:10676000000000FF0000FF000FFFFFFF0000FF0020
+:106770000FFFFFFF000000FF0000FF000FFFFFFF03
+:106780000000FF000FFFFFFF000000FF0000FF0000
+:106790000FFFFFFF0000FF000FFFFFFF000000FFE3
+:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3
+:1067B000000000FF0000FF000FFFFFFF0000FF00D0
+:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3
+:1067D0000000FF000FFFFFFF000000FF0000FF00B0
+:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93
+:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83
+:10680000000000FF0000FF000FFFFFFF0000FF007F
+:106810000FFFFFFF000000FF0000FF000FFFFFFF62
+:106820000000FF000FFFFFFF000000FF0000FF005F
+:106830000FFFFFFF0000FF000FFFFFFF000000FF42
+:106840000000FF000FFFFFFF0000FF000FFFFFFF32
+:10685000000000FF0000FF000FFFFFFF0000FF002F
+:106860000FFFFFFF000000FF0000FF000FFFFFFF12
+:106870000000FF000FFFFFFF000000FF0000FF000F
+:106880000FFFFFFF0000FF000FFFFFFF000000FFF2
+:10689000000000FF000000FF000000FF000000FFFC
+:1068A000000000FF000000FF000000FF000000FFEC
+:1068B0000000FF00000000000000FF0000000000DA
+:1068C0000000FF00000000000000FF0000000000CA
+:1068D0000000FF00000000000000FF0000000000BA
+:1068E0000000FF00000000000000FF0000000000AA
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:106970000000100000002080000031000000418075
+:10698000000052000000628000007300000083805D
+:10699000000094000000A4800000B5000000C58045
+:1069A0000000D6000000E6800000F700000107802C
+:1069B0000001180000012880000139000001498011
+:1069C00000015A0000016A8000017B0000018B80F9
+:1069D00000019C000001AC800001BD000001CD80E1
+:1069E0000001DE000001EE800001FF0000000F80CA
+:1069F00000007FF800007FF800000344000035002D
+:106A000010000000000028AD000100010005020692
+:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41
+:106A20000000FF00000000000000FF000000000068
+:106A30000000FF00000000000000FF000000000058
+:106A40000000FF00000000000000FF000000000048
+:106A50000000FF00000000000000FF000000000038
+:106A60000000000000000001CCCC0201CCCCCCCC5A
+:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80
+:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70
+:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60
+:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F
+:106AB000000E0000011600D6002625A0002625A005
+:106AC000002625A0002625A000720000012300F367
+:106AD000002625A0002625A0002625A0002625A00A
+:106AE0000000FFFF000000000000FFFF00000000AA
+:106AF0000000FFFF000000000000FFFF000000009A
+:106B00000000FFFF000000000000FFFF0000000089
+:106B10000000FFFF000000000000FFFF0000000079
+:106B20000000FFFF000000000000FFFF0000000069
+:106B30000000FFFF000000000000FFFF0000000059
+:106B40000000FFFF000000000000FFFF0000000049
+:106B50000000FFFF000000000000FFFF0000000039
+:106B60000000FFFF000000000000FFFF0000000029
+:106B70000000FFFF000000000000FFFF0000000019
+:106B80000000FFFF000000000000FFFF0000000009
+:106B90000000FFFF000000000000FFFF00000000F9
+:106BA0000000FFFF000000000000FFFF00000000E9
+:106BB0000000FFFF000000000000FFFF00000000D9
+:106BC0000000FFFF000000000000FFFF00000000C9
+:106BD0000000FFFF000000000000FFFF00000000B9
+:106BE0000000FFFF000000000000FFFF00000000A9
+:106BF0000000FFFF000000000000FFFF0000000099
+:106C00000000FFFF000000000000FFFF0000000088
+:106C10000000FFFF000000000000FFFF0000000078
+:106C20000000FFFF000000000000FFFF0000000068
+:106C30000000FFFF000000000000FFFF0000000058
+:106C40000000FFFF000000000000FFFF0000000048
+:106C50000000FFFF000000000000FFFF0000000038
+:106C60000000FFFF000000000000FFFF0000000028
+:106C70000000FFFF000000000000FFFF0000000018
+:106C80000000FFFF000000000000FFFF0000000008
+:106C90000000FFFF000000000000FFFF00000000F8
+:106CA0000000FFFF000000000000FFFF00000000E8
+:106CB0000000FFFF000000000000FFFF00000000D8
+:106CC0000000FFFF000000000000FFFF00000000C8
+:106CD0000000FFFF000000000000FFFF00000000B8
+:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329
+:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66
+:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB
+:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44
+:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316
+:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23
+:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC
+:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC
+:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA
+:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD
+:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2
+:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5
+:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304
+:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85
+:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7
+:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45
+:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328
+:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65
+:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389
+:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43
+:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315
+:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22
+:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB
+:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB
+:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9
+:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC
+:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1
+:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4
+:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304
+:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84
+:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386
+:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44
+:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC
+:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98
+:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB
+:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76
+:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B
+:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55
+:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B
+:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33
+:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B
+:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F
+:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B
+:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7
+:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B
+:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7
+:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB
+:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77
+:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5
+:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63
+:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387
+:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41
+:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313
+:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20
+:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9
+:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9
+:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7
+:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA
+:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B
+:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5
+:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD
+:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5
+:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3
+:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42
+:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4
+:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62
+:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367
+:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40
+:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312
+:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F
+:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396
+:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C
+:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6
+:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9
+:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE
+:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1
+:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320
+:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81
+:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9
+:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75
+:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9
+:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95
+:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8
+:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73
+:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398
+:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52
+:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378
+:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30
+:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358
+:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C
+:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338
+:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4
+:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318
+:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4
+:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8
+:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74
+:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8
+:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94
+:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7
+:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72
+:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397
+:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51
+:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377
+:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F
+:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357
+:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B
+:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337
+:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3
+:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317
+:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3
+:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7
+:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73
+:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7
+:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93
+:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6
+:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71
+:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396
+:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50
+:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376
+:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E
+:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356
+:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A
+:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336
+:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2
+:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316
+:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2
+:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6
+:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72
+:1074E000000C0000000700C000028130000B815832
+:1074F0000002021000010230000F024000010330C0
+:10750000000C0000000800C000028140000B8168F0
+:10751000000202200001024000070250000202C0E7
+:10752000001000000008010000028180000B81A80B
+:107530000002026000018280000E82980008038031
+:107540000010000000010100000281100009013854
+:10755000000201C8000101E8000E01F8000002D895
+:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B
+:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B
+:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B
+:10759000CCCCCCCCCCCCCCCC040020000000000067
+:1075A0001F8B080000000000000BFB51CFC0F00350
+:1075B0008AB7B13130ECE644F0E98159181818F86F
+:1075C00099C8D7BF1168C04E20BE01C4075948D71B
+:1075D0007F551AC15E26C9C0700A8827883330B427
+:1075E0004A21C4ED651818EE01F92BA16272403DE5
+:1075F00073A4C977F3281E3CB8D014951F620CA160
+:107600005F9840E82234F950A8BCB81E842E36C5D5
+:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512
+:1076200040E5C7A2A90F81F2017EE9B234D8030078
+:1076300000000000000000001F8B08000000000098
+:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421
+:10765000278470123EEEC400C1063C4280A0A83BC5
+:10766000FC1A7DD41E1025E5A11C446B004922A6FE
+:10767000D78C96D76CC8870450E3E751BD457BA0F3
+:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242
+:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F
+:1076A00073AEB592BD77CEC9C74F47EF788D43769D
+:1076B000D6DEEB3BFF6BCEB95634D943F22E27E42E
+:1076C0001CFCD0A7291142A6F73DC92D5932C92368
+:1076D000E41B3E823F1FF923534816210D3EF6BCA2
+:1076E0003D10D905CF2D8D84A426C2F771491221F2
+:1076F000244848899A0B2D02B1870BE15977617CA8
+:10770000323E67C23387C8848C84F218FDBD20EBFB
+:10771000FB9C42FF399AA880F114F68AA8A43C96F3
+:10772000C2F6DF226446DF3C48DD57F578B86FDEED
+:10773000EEA7A26B24C5EB9E837F94E5598950E6A2
+:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7
+:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A
+:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2
+:10777000E5258436333B4BE93344CC5DA5FDDBCDB9
+:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7
+:107790004B9241C0214938E0D61C5AEC33D3F42730
+:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777
+:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF
+:1077C0006A6287CF70E7159844C821C0876A128221
+:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020
+:1077E000EB1B229E822572DFF8000723E0A02F6F9B
+:1077F00034C7496F6EBA067820BE3A387CE20AE395
+:1078000007AB0F8FF4199A1D93803568F110E02DA6
+:107810009F30F8E557B7DE2A4F2194D53A0F4EA096
+:10782000F0CBEF5EB99040F9E8152780DF9ACBA640
+:1078300056CEA5F5B2CB63AF2CA04D423143027AB0
+:10784000DD0A9D15407F5FB32A68B909FAA365CBAD
+:10785000BACAB4106EA6036E1472864ACB1EF8B56F
+:10786000280DFC482F1EA473DEFEED33C1CF436C00
+:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5
+:10788000BE46101B5FD37EB22B35075EB25CE33C75
+:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C
+:1078A000A5B29EA478CA26B16CB58CE263A14A4009
+:1078B0008EE5E4EA1290C360786926A412F89F4A24
+:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5
+:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05
+:1078E000786DE5B2E74802C7EB3C5844E76595C9B7
+:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695
+:107900000F62A833B83CA0F0514A65D31FF9ECF4DC
+:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF
+:1079200059C71378EDCF571B055E7D847EDF52B2B9
+:1079300078407DD51FAF4F92046D172A2566324DD2
+:10794000BBFFB4EB0BF7D326DFDD72541935A36A06
+:10795000E74078CB75AE57F4EB6F508C7747D0A2E9
+:10796000AAA37CD5B81E688FDE63114A776740F6FC
+:107970005078281D17A5A04C8A49EC61D64D4AA223
+:10798000657FD44C6E413A48225EC4FCBC86EC90C4
+:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483
+:1079A000182F17EC02DA2105851A2229A05B41AFB6
+:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF
+:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049
+:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8
+:1079E00028102F13761DC7D3660FD92B5D48E5C12C
+:1079F000986BC152209BE1D32C6A87C0932A9FCDFC
+:107A000063A6EA4057648FA4C23C71488A4742F596
+:107A10001DD40B4A06F623FBEA90FE9490894FF1A1
+:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83
+:107A3000748E6B15D3D80874318DC9A7EAE88479A0
+:107A4000A0EF3C129BD7B7A57C5C879AD39687762C
+:107A50005906FBAE5AA52A7F2A7CDF3661207E229A
+:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8
+:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9
+:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913
+:107A9000C7F8D26769601F8875AF0576A720DD1625
+:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F
+:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373
+:107AC000BDBB5D6F7F425E507B18E85CD041504A81
+:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2
+:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0
+:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1
+:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14
+:107B100079E9E823139E7E21F9711C415FD5F2F2C9
+:107B200001E96130FA7ACA4D5F9D577F21F475C82B
+:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9
+:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6
+:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2
+:107B6000EA74FC51D48E91407F9491588ACE53A7E9
+:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A
+:107B80006BD85E21294B477BDB6967CC57E84BDA22
+:107B90004F7309497A715F64FA504F95A884E93FA1
+:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA
+:107BB000FD359BEB5F89DA5B747DA132E7BE37E070
+:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824
+:107BD0004842A88FC4FE38037FF6EE8B395C476AB3
+:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA
+:107BF0004A49E62F20256037AF970A62A00FE83E7A
+:107C0000AF278B7E7FEF070AEA878668DD8A1658E2
+:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17
+:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C
+:107C3000E91D7F549B563C0D8653DFEEA6F090293C
+:107C40002081FF02A1FBA22F18003FF6BE174EF6BF
+:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67
+:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8
+:107C700077DBFDACBC63D3AC8D169447F2FA561596
+:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF
+:107C9000BE6EF324ABE269F8FB365976D85F4DC669
+:107CA00082F2FF43D7E1F79917BD40E1498112B352
+:107CB0000CD26B97150ABF41C7DD952500FFD7147D
+:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E
+:107CD000424B0DF4850CF528DE1E96605FC7EC3133
+:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42
+:107CF000F659519F3DD68B2717DEEE557BFC80B79A
+:107D0000EF8DF9F01713693FD642390664F3BD0DC4
+:107D100045D92B6D787CCC37A70AF0489A73D12EC1
+:107D20008992DE1F13CA62DF5C403A2BC0781C4385
+:107D3000251FA1743A2EDE53012830AAF4E7708F74
+:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9
+:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041
+:107D60003C185149D73B809FE09B549F30FB2CE14E
+:107D700003FF56A67132CDF333C073934CC71D4D2C
+:107D80009208A7C1E09A099EADD127B3515E7FCE7C
+:107D900070CDD4DE0DCF1112E397956A39F2CB5036
+:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6
+:107DB000BFDA416269F0EB379CFE210DF625B67201
+:107DC000BD6C307D1072FB89189EDD7A6101D70B86
+:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF
+:107DE000909F6192B4E8F720F707915226FF7DF447
+:107DF0003FE0B751554E7DA00D511FBC2BC55F9084
+:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C
+:107E1000A337B445133638D4CB4CDF097D962C16E6
+:107E2000FA8C20FCCEE37348920E3FE8C307362C51
+:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A
+:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C
+:107E5000307918317B52E0F34342CEE32E434ED6C5
+:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448
+:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C
+:107E8000EE2C64F0B76611A4D390B1E08402FA58E6
+:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459
+:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74
+:107EB000855C4AA1EB50371003EC09D5A4223102AE
+:107EC0004F3D0FE8453563217C765754C2F3BCD94A
+:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042
+:107EE0005EF526595624C6073936789B4AA1633F6A
+:107EF00097ADBBFCA589D62AD4EF8646C617F69F58
+:107F000077BDAC72B9E7A417412703C8BBCF441FA4
+:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE
+:107F2000F9AB9CF875973F6FBCFA014F141FE751EE
+:107F30003C017D9E379BD123B547D17E7AC0D76166
+:107F400002BC1F2836644BEA6B175672989FF92CB7
+:107F5000DD6851BBE7FE95DB4D68975F4C6580841B
+:107F6000CFB4FEA37A59C376542E542ACC6E97C050
+:107F70001E9FAF6CAB82F63B295E81DF77027F43A9
+:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200
+:107F90000246ACBE14F1EBE7FCFE912751097EC806
+:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9
+:107FB000FC0D609F8CA9D3A702D833B5DB5E275791
+:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9
+:107FD000473CCB4DA048D897542B36FA0E97317FAB
+:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E
+:107FF0003F96C753DCF55E56B8BFCE60F03244FF03
+:108000001B07EE5FC0E76C9BC2E323D40043221E34
+:1080100049ECFA5BB9F15005BCA75CB709F0B55D56
+:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88
+:10803000552647C79AFA16C0F7D866192C05F2B824
+:1080400062E0FB51CBEBF67B281EDA0B492C64E097
+:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963
+:10806000D07AF9A52469D0F6EDFB1FA8D068394273
+:108070003754600AFBCA193E7D252406A690C72204
+:1080800029997D4F424C5229EFB140951E183F036C
+:10809000F75F77E69298D7E8931B82AEEE6CBEC787
+:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F
+:1080B000630A27E14F54205E163761BCF6596CDE27
+:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB
+:1080D000CEC35A4762E3B15E8C60FC860A54F05707
+:1080E0003655337BD78D8FF524F1B832DD4EAF870F
+:1080F000906EDA3F51F8BEE0C58D60E78F835F690F
+:10810000F9974D7FDC381CBB45C40F85DDB245EDCA
+:1081100044BEB728CF815E12768CBFB813C7FDBFAF
+:108120009CDE87DABFBFC4E96F75DB356E7BA65E68
+:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B
+:108140004FA3077E03FA9AB6DF115DFCAB89465F49
+:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52
+:10816000F7608F6632BE1A2BE4D037285F0D107F80
+:10817000147CF511151287804FD40EA42F6296201F
+:108180005F097E51BA3BDACFA7F460D4CBE0B906E1
+:10819000FE2239B45C48E93D65B38784BC504B3B53
+:1081A000E313A5FE74F7A021231ECF94317F7596AB
+:1081B000D56D4293606927C6F5285DFD17D095AA55
+:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9
+:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A
+:1081E000F87D31363F579CBDFE5703C6D9FD319708
+:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B
+:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3
+:10821000BB1C70E9070F65476CA0F9F9859FFE53F9
+:10822000C60550870D010E6E385EA23AFD879F3756
+:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD
+:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C
+:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4
+:10826000AA8DDE47971E4A413BB73ECAA4870693B4
+:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580
+:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB
+:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0
+:1082A000E897F998AECE16575BCDF78137F07DE4AD
+:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA
+:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64
+:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A
+:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F
+:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10
+:10830000671E9CB19296BFCBED91F7A95C366C715C
+:10831000D035A1A406F87DA76BDAB59710689F6CDD
+:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26
+:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E
+:1083400022E40DC757A6BC2A914FF50B20205ADF17
+:108350009A43D8BEF3AD60B209E535CBA71AACFDA0
+:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A
+:10837000D6966BC5C12F24E28235A4CE1C4D7F5505
+:10838000F72DB246135BBDE810EB150F5C2FD3BC85
+:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B
+:1083A0005D49D440FF5EC083024F15F18D7E608A27
+:1083B000DF5A35D4266541BE5317EE03FD86EAA089
+:1083C000875AF805E45A09936BC112E777B77FF82B
+:1083D0004355C4E153C87F188236C07E08A514F007
+:1083E000DF94AB277BEBD3F16A605D1742298E7275
+:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E
+:108400009F8F71F5FA9106FA77551233B10F17DD88
+:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1
+:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81
+:1084300092CCFC483A2DDBD6FDA70E89E7AF185940
+:108440004B06F0DFAD8F327FF00DEDE3B398DFD058
+:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8
+:108460003D7615C07BEDBF2AC407F91B8F85490AED
+:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130
+:10848000CFC7C388AF354F7A930B69FB354FBF33E6
+:1084900085D0F99DDED4F3E268B09B1F95581E820B
+:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9
+:1084B00073F2D96015F0B7B467FFF5D86FE7528F44
+:1084C000D7B6DF2EF678906F693D66973F2225C7B5
+:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF
+:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764
+:1084F000118043ED5EC5A1076AF72829EF147C1EA1
+:108500008327C48DA41940279C5EBAD661BCA8A657
+:1085100073EB07E0C7A8DDEB946B142EB114C0F524
+:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1
+:10853000802BED77A59605FAC649DFD0FFD99CFEC2
+:10854000FD11D283F1BADACE76365ED7577E0F7A36
+:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F
+:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1
+:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190
+:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0
+:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B
+:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4
+:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B
+:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B
+:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B
+:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E
+:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782
+:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5
+:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F
+:10862000B3FAE3EF0E17FECE905BBE970F798D5D28
+:10863000231C7152F1EC8B0FC6B3E203C80B210F60
+:1086400006836FB5C4E6B5CC633EE801BE7A32D886
+:108650008BDF8580DF1F9E1947287D1CF7F45C0F98
+:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3
+:10867000F12B9A81F9992424E5F13C31F67308E451
+:10868000700DDBCB91DADDE19437D287A79AE4A2B3
+:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE
+:1086A000BCBDE1296276407224C265DDEEDF69CC93
+:1086B000BEECC3A7540EF83CB600DE67C2A758BF95
+:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0
+:1086D000F5C36F527A039EA7777A55D07BA7C1FE68
+:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615
+:1086F000F1630E87CCF461713B60E0F50D177E3FAE
+:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC
+:10871000625516D8EC139F87DA27905F46E2D6E8B9
+:10872000C2BEF99E847D04A5BF938F2A18AF69ED60
+:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D
+:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F
+:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3
+:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92
+:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46
+:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416
+:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39
+:1087A00070C0003DDAB5C91C7507D86B873D04E47D
+:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40
+:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97
+:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89
+:1087E000E52890FBCD60CF4F84F16251F07F289156
+:1087F00005952C7F50D6FD69F537EBCF138A63BE04
+:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3
+:10881000FEE8059AD817D0716D7290DAAA55E9F082
+:10882000364B637648A6EF976ACCDF93E97BC52089
+:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19
+:108840005733C9030FEFA74C331CEB05782FB2E564
+:10885000C58F26C98D90274A4221773C3AEEB3C78F
+:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F
+:10887000BF87763C899D1BC08E75C79FDD7989991E
+:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2
+:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5
+:1088A0006DC9808725DA9C7FD280BE649248F77DAF
+:1088B0000BA79BCB49F7532B619E3116BF9FED82CF
+:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B
+:1088D000DFB94BCC661081F397F7ACDD0F7C26E255
+:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9
+:1088F000B521E445103D27AD5EE89B87C5F755518E
+:10890000DC2779389F1D78F3661FC82D95242A0B24
+:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32
+:10892000E906DADB79A9D50FDC0471757D0CC62365
+:1089300094B397A0FFD0DDAF128D59980F16322A4D
+:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F
+:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0
+:10896000EC77AE8E207C7D14BE201F1164B02E9E4D
+:108970003775F7D511D433FE839E9DF0DD1F6279E4
+:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F
+:10899000EB3109E328827E5B0BEBCE03393E401EB0
+:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51
+:1089B000368FCA2A9807F6586B361179559644E7D0
+:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45
+:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F
+:1089E000E78E26759DE8CF33C93536391BF1AA08C5
+:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8
+:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD
+:108A1000ECFA483C051DB5160F1CBF53CF5E847E93
+:108A20007C51F6E949D34C537FBE8FD91F827E7D9E
+:108A3000B924097AC967241EB809E83937140B32FA
+:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A
+:108A5000CEE804B95ED071FFF95FC6E75F64615C80
+:108A60002244309E96791D65B88E559A19F6DAE043
+:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10
+:108A8000DA198715791AA27E504A1478411EE6B287
+:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C
+:108AA0000212509777E2D146554F62FD127FE27C69
+:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF
+:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB
+:108AD0008FD3992CAF28033DB5150F1C87EA688CFE
+:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8
+:108AF0006E0946F73F6802BE092B822F7E88E53B50
+:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC
+:108B10007DB49A01E4FFC1D6A72767205E873B4E4C
+:108B2000FFF5B271DBCC10EE77075BB79E62E30E08
+:108B3000751C115FEB5B9F0FC769350619A7838D05
+:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED
+:108B50007BDFEC1E9248D37F16E79F036F7A515E4E
+:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF
+:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA
+:108B8000A1553CB1D04AD62E61C239DBC83C82F136
+:108B9000674F49DE2A78DF403AE273400F97CB2CCB
+:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4
+:108BB0009E928B6F86FAFBA7BF9E68023895333A68
+:108BC0002007F31D706C358AC4B99D01F9DE53EEA0
+:108BD0008C5B109F33FF93A84B306E4EE54287D7D6
+:108BE000665752BD781FF23329B3C0DEDBFEB56B8A
+:108BF00063767EFE672DFE1D565FE46B093E4F9F38
+:108C000037D79A2BF2E6123EA50CCE29F5E6532F64
+:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B
+:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6
+:108C300058C8A7FE8987C4529017F36B250679316F
+:108C40006EFA70F7E73E07D06B8F64E0E7F7013804
+:108C500036B9979F70E1ED463FC6E7C478CF837C75
+:108C60002A1D9C4F47573BFB195BE73C9F755E8372
+:108C7000335E55681538EA9FDF56E4F83EBEE302DE
+:108C8000C7F789F74F759427252F76D4FFD29E39E1
+:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F
+:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5
+:108CB000477956F7371DF51BA87902F92C7040004B
+:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B
+:108CD0009ED48FF166968BDC9767E06EA7146BA627
+:108CE0004EF9573126CCD331CFF046E423A5386F67
+:108CF0008E81EF672C00BF132963E7B444FCDA537D
+:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7
+:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A
+:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3
+:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73
+:108D40005CE623CD0053C11715CB7B46BF80D5C44D
+:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084
+:108D60007A45494E73E421B89F54FE95F9609F1EE1
+:108D70005986F2A8775FD02B1FE333E1BB478DA163
+:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F
+:108D9000421FCF05A597D711C80BA372E9CEABAF81
+:108DA000C23818A9278EF3807955711FE83D6A975C
+:108DB0007DC567DB3F47CA997DF6F766A78660BD2C
+:108DC00036F927EC5501D7118575718CEB85650255
+:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A
+:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9
+:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D
+:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9
+:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051
+:108E20006640FE44EBFE598B305F77A1AAC3BE9625
+:108E3000D04DDC3BB6B8222171F46769B932EA45FE
+:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4
+:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2
+:108E6000F39560FC108EBFC9C7F0E886BF87986D88
+:108E7000F368BD96635FEE28468A61F97AF72E9C07
+:108E80008A744A05B5837EC53E82D2EFC340BF6275
+:108E9000FF2ECEB3DEE263790902AFC460FE881113
+:108EA0000915F7BD3909B6FFED931F8C8E723C3161
+:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09
+:108EC000C77B690CF1D5FE15956C027A2BA6EB8158
+:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36
+:108EE000E1FB40952CC9C27B529485D174F6672F63
+:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4
+:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1
+:108F10001D08CFF631F7A11D2DFC63245A3688BFFA
+:108F200087C54BFBF0BCD448513CAA574C45A75FC2
+:108F30007B31C7739D2B9F97E359E057F8ED493478
+:108F400017F95AE05B017802AE94D9D181F495C249
+:108F5000F9C60DCF53FF4DE17904D600743B96AEB0
+:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8
+:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E
+:108F80000D737AF371BDF942F9DB6D709E44CD65C6
+:108F9000FBDD7079F3AD329CC320960EFEB5B03880
+:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD
+:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B
+:108FC0003F7D1E261993DEEFEA8EC789F886C88397
+:108FD00015710084035DBF67961C47F95746CC9D09
+:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9
+:108FF0003FB6A02C5501E5823A12033D71F1F143D1
+:1090000024413BBD20C0E47E41595202BF47C149C3
+:109010009617B89DC72B0BEA93D24ADB38969FE987
+:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32
+:109030003B14BDA1A302C62D67F9E461BA5F84BCED
+:10904000B1F0116F12EDADB26E027E54AA05AC30D4
+:10905000FD7EBC914CBD713CE47DF9F079B251C705
+:10906000E781B1DAFECB69BDF5850103FA6D290A06
+:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7
+:1090800062FDB66F9B685734EF3F817EC3A0392DD8
+:10909000C6FCA8A642CA613E874CF0731035662C08
+:1090A00086EF077E83F5142DF11B0BEC93651AEE0A
+:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2
+:1090C0000BC98A4569E0BD82EB1D4A518A96D79744
+:1090D00087A495A7942CF02797914EC873F7B424D2
+:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2
+:1090F0005A8F810F5D2B67E745043E3C7E127F222D
+:1091000004F552D2AD74DC89011DC7293892C4BC64
+:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7
+:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A
+:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0
+:10914000C451605F3664C8A356748AA7114C3E812F
+:109150003F62FD78635476C8DE0F8387F2DCB30C80
+:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837
+:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE
+:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2
+:10919000174FFDE895191EDADFA9275F99A1227301
+:1091A000251D76ECBA73AFCE003BC19A434AEAE87C
+:1091B000B356D708F45BEB63EB107972DBF3B4566C
+:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736
+:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED
+:1091E0001B1088175ADE7110CF7AD38BF4F75121F8
+:1091F0002929BC10FC820AB6EB594D92904FA1A5CB
+:10920000EA803D89FFE52401BE09BEA6EF475AE387
+:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826
+:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D
+:10923000F19DE560075EA7E23C6819CF1BB9F1B369
+:109240003C58E488E3E5F0F884C06B263AD9DA4864
+:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B
+:1092600018C5F2DE46039F4F3796E0B3AB3186DF79
+:10927000F73496E353E4F5E1D65E417B3A5E017A3A
+:10928000E81AE687D30DD9847C852C95F8E0BE26B4
+:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6
+:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1
+:1092B000249047D62CE66708437FB47DEE1242DE49
+:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770
+:1092D00077FD884A1790D3BF1D958B58EEEB373D2D
+:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6
+:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4
+:1093000064815CDF3E8B183A85E35D866C79B2FA46
+:10931000EAEF683C98376F3CD74120A7EAF59D5BA0
+:109320006CFB9831165911B7D1CB5D756AE52EB437
+:109330003312F98B2763BE31F76BEF9E678EC17EC8
+:10934000B13C21F0E23C8BEB159033979D657AA8F8
+:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C
+:109360009F803C057959962073E83C4397B2F8F703
+:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81
+:10938000A24909CA3FF2C7670620EF3DE7FED42E87
+:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2
+:1093A000341FF077C1BE6398B7A4C8DD1AEC789774
+:1093B0000526CF57C19E8589607C802A6A8A6725E9
+:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD
+:1093D00012B7B21D33317D51CA0F7ED1FE82168085
+:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF
+:1093F0006DBF35BB332A6743D2D4C4968397425995
+:10940000D49FD862CD26E41AAE0F48285108FCDE5E
+:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F
+:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D
+:10943000BB60EF4E94AF054982FBFE82A49484A3E7
+:109440009D7B1A0FEACDC2B926F04245C3A428BBC2
+:109450005F484B7A62B0BD9CC4EF0F1174F17490F9
+:10946000E9C74949DADE1E9776DD273289DF57835F
+:10947000200579B98D9D0776D37929EFAF81585BA7
+:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3
+:10949000736EE10E3CCF262B7001C8BF952AFA816E
+:1094A000D7162637521B8AAC7DB630462D56D2E2EF
+:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F
+:1094C000E7A3D956369CD7ADD97BF738C8EFA92189
+:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9
+:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E
+:1094F000BA2EBA12D657B34D267221E34B73229D72
+:10950000AED971019CAC7B7EEB5BF3FD630979A462
+:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F
+:10952000803EBA833D2D405F6B67C99C9E7A5E305A
+:10953000559EFF5800E35CDE027196DDCB2AAF0436
+:10954000732B4F66FC4B0912E3DA4A76B30FECF942
+:109550003FB6C8683F838B7403857BB14A0EAAF47B
+:10956000B95DA3F8043E6B55511ED2F76D1EC44B76
+:1095700007DE3342DAD83D2DE3F77957829D5D5CF3
+:1095800067AE467B5B2F453FC038D2FB837912E73D
+:1095900011267F27EAA442A5F566050B117FC55564
+:1095A000D7AE85764A784900F83D4F495AD8FF77BB
+:1095B000991CDE2E273B7D2097234588DFED114641
+:1095C00017D63DA54817BBE53917805DD422ADDC21
+:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6
+:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE
+:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1
+:1096000046503C1CDF52DF129D857828F2D1EFC70F
+:1096100003F52D3E8A97DD1BCD02DD569EF8099598
+:10962000EA48B4F52DE66CF09FDCB7069410FDFE19
+:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3
+:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D
+:109650001E5210AFFF4EC7033941D76101DDF74CF1
+:1096600052D12E08D0B904683930B908F36DE9BA7F
+:109670004900EC86C92AEA7911C7D126C96837435F
+:109680007DA087407E11E6CF51791D87733E4A94B5
+:10969000C5751465874979980479FEBEA42FC2FB6D
+:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C
+:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76
+:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98
+:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091
+:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3
+:1096F00064FE41EFD862BC57A38150FE07BE08F15B
+:10970000FBF2B8FCF0707BC17D4E40C8134F365B56
+:10971000637DFBDC5139A1BE73704AC8F4813CD82B
+:10972000AF4FCD027B743C9753CDA9595F05BB4524
+:10973000E5F260879F9DCBEDC9269DBB08D8BF3160
+:1097400062CF4B10F2605BA30F9F0F5F3601E39770
+:109750000F5F963707E215072E7E1FF7BF6776303B
+:10976000FE3D73E805B84B899CB1A8B6311859A1E4
+:109770005F3E752FDE17F27D357E17E6CB43BE0EBA
+:109780009DD25DD9CE3CCC47395CCE0578DE808752
+:109790007D17F778A867BF847EE06D7C3DBEC43C32
+:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D
+:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6
+:1097C000623EFB8219EE3376E143F835041E44FB1A
+:1097D0007AC91CA50F4037B5671592B4E585F49D8D
+:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B
+:1097F0003E48A29DE80F353BEE712551B5C77EBEB0
+:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1
+:10981000E57DBACD1579B998A7AE9207C0AE3D15D2
+:109820007C6B06F8E36AA998005739512D3C4F7AB2
+:109830009AEF4BD47DB7E2791E313FE18F13E59A61
+:10984000BD8BD04F57BB3B84E7796A924C0EAEF389
+:109850005907BDB23DEFD64C41BEAD672FEB6F3C13
+:10986000E080D2C7877A753EAC3FD870FE4C38672F
+:109870009227D79D370EE0A3323CC07EF9C9109ED7
+:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B
+:1098900006782A8158376167164D95DA474AAFDC5A
+:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC
+:1098B0007329EA67948BCB023F437BA8C52FCACF9D
+:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8
+:1098D000A75BCB4A507F2845A400E0360F1C2D2003
+:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD
+:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5
+:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4
+:109910007A8BDABA24EF692F9E33DCE171DADBE26D
+:10992000F920E7CB36D7BD1DBE44B3099B73C19F59
+:10993000EE7B9605BFAA672739F2A4C607593C5BA0
+:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7
+:109950003C4E4E86719C71BBFEE3CCE07282F07D82
+:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED
+:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB
+:1099800060FC3905F87335A7D3923D773F076AFD30
+:10999000319FF967D837ACF2991704A70F9F7FBAA8
+:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90
+:1099B00028D7DF51A45B69E245E2597D36E8905F24
+:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA
+:1099D0007EC779B6FEE385F0BB18EF16977C3E7024
+:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A
+:1099F000E780FC545E3BF9DD047E570B496F9E22E5
+:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4
+:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76
+:109A200022D17F2ED677CF47C81F28839DA67EE2FE
+:109A300015F343F975B7ECEA2F478C3F06FB13F695
+:109A4000FAB703E35F843B25EECA4E568C66FE1DD3
+:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23
+:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3
+:109A7000443D9ED3F87680D16535B5E8B1DD8ED111
+:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D
+:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D
+:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2
+:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B
+:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF
+:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4
+:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09
+:109AF0008A60FE7A28817182FDF90BA260A77FE758
+:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD
+:109B1000F70869CFC1FE91F74BCE7E59B69F47D962
+:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607
+:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE
+:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3
+:109B500016F7D10CFB7960F1DC1F9E118575366517
+:109B60002F88023D3767CF70AC47C9B09E5561065C
+:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908
+:109B8000E9EF176B17788A2690CEBEA8759DFA1B51
+:109B9000AF6B14C7577588F90D361B8C8F824AFC42
+:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B
+:109BB000DF727865E2DF659EE44898D79146B67F0C
+:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8
+:109BD0002B3C909FE37F563BCFA70F26375A422C52
+:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21
+:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF
+:109C00007478701B8C0FAAE1929BE983C34DD05BE3
+:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3
+:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD
+:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7
+:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA
+:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD
+:109C60003C5F9363FF5E067187C5AC5DBF7972F898
+:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8
+:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB
+:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64
+:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2
+:109CB000E492DEBF977101C0738FCCF2398EC2ABD4
+:109CC0007CB89F8C60A5A555A376029ECA223CEF66
+:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977
+:109CE00096BC367879230CCF3396A7B70B73233CF9
+:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F
+:109D0000978AA8E6D8C5B67375535CDFDDEDC74604
+:109D100022F8FD351E6F777FCFE2ED972E19B83D03
+:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468
+:109D300034429FAF4B8907BF01743429C4E21E2A05
+:109D4000298478BDE8275725298DC2FD5D8F3116FE
+:109D5000FCB469FA291CA89F4C7015EB11E3002B89
+:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6
+:109D70006E65870D191DE4F0FC999975C1E446B034
+:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564
+:109D90007D53617F380C261F1670BAC955129BFC83
+:109DA000E01F5B21A5BDDFECF208FB3B251F847B98
+:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F
+:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442
+:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0
+:109DE000C4919FB4247EAB07F873C9C2451E2304F7
+:109DF000DF99BCBC86CF638F96187B51A80F4E1994
+:109E0000E510874FD7914413DCEFB0A241C238521E
+:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD
+:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41
+:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B
+:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8
+:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28
+:109E6000D2089E97FB8F762FFE7D0B412FBD72622D
+:109E7000C3478D907477AF969A0C7433B2A9EE1BDA
+:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F
+:109E90002EEA2D560D4FBAFA57573AE59898F7081B
+:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332
+:109EB00002EFBDF83E927E5FB423C2E2777B9273DD
+:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C
+:109ED000DA258A43DEAE5818749D476270FDAAD712
+:109EE0007808D671EFAE9726E3DF5174E987809248
+:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0
+:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E
+:109F10009FD7AB565D83F36F567498FFB1E523AEC0
+:109F20002A07F952E5C17B828F35DF16BEC9B67E9E
+:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9
+:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6
+:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2
+:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5
+:109F7000B9B1E4BE780BC4794F344CFB6937ADF707
+:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF
+:109F90008C234483F689FAF4FAE0FAEC2093AF6A52
+:109FA0006C1CC897EB36A4AFB709922B69BD137F21
+:109FB00055AAD3E56D7EA2333E59114FDFFE133D06
+:109FC000CCBE835E4A03E7BD59412EE7F47120A75A
+:109FD0005764986F575604EBBDD372FB7510EF3B77
+:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7
+:109FF00046029E5A251DE8E1EDECD824A0B795CD88
+:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43
+:10A010009E3F92E2A56B3989494666F9FF31E79F79
+:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0
+:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D
+:10A04000760558DE11894DB7DF2F13E0F338B17B69
+:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B
+:10A060001DE28F872B95D4E57492EFED0EE23DAFA4
+:10A070006EBEC834FE70EDC013BB8767070EB6EE28
+:10A080005856E190ECC03395F7DE59067CA4754C28
+:10A0900049277F859C7E8DFBADDCF4239EB3393E42
+:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A
+:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C
+:10A0C000E859E6FFCD34CF389FA790134079104F61
+:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738
+:10A0E000070FB1BCADF1F19573461A7DF4795D1699
+:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80
+:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8
+:10A11000C4653E8818AC4CF40570448694F373CB48
+:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75
+:10A130006EC7F15D974CB2AF6707C7FF8A25D97824
+:10A140005DCA713976C528CC2F50F0BEAED78FE4EA
+:10A150002C80F2BD876490D0E4BAFA950AACEF8106
+:10A160002C9677BE62C32B680F0E97CE57D439F565
+:10A17000FF277C1DBD7696DA5306F493090EED5940
+:10A180003EB6CF892F9A0FF279D50609E5ED962CC8
+:10A1900003DFAF524D94DBA499E947E2A3F0A02A74
+:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9
+:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010
+:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD
+:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77
+:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4
+:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5
+:10A200009B637C25EC1D77FB6BD584C36E3C94551A
+:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E
+:10A2200064FDD3E98BFF0779B222080080000000AB
+:10A230001F8B080000000000000BDD3D0B7854D59B
+:10A2400099E7CE9DB9994966924932933738930080
+:10A250000625780321449E370991A0A803040C1A0F
+:10A260007044D4282144C54ABFD2CD0D893120DAAB
+:10A27000505DB4D67587885DB6D235586AD1D2762E
+:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B
+:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD
+:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591
+:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194
+:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2
+:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D
+:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1
+:10A2F000DF9234287F097FE60EFFDEF0804CA2C596
+:10A30000B179AF867518CAC77A923502F3CDF14498
+:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F
+:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67
+:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2
+:10A3400038F37B6D844CA3130402369245C86D7CB0
+:10A35000EFAB528906E3133ADFA386F145BFC3ADE5
+:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11
+:10A37000702CECFBF09533C75E3329D62F111C9659
+:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4
+:10A3900071E0A673B85AE7873F76BA8F25FCFF971E
+:10A3A0006EACBCC34341B22965CEEC709CF90F93EF
+:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA
+:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023
+:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF
+:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57
+:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE
+:10A40000257CCF85747DC72F96559DAEE7B88DF618
+:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA
+:10A420007249AD793D4B8F249BE9D2461A7BE3EC10
+:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B
+:10A44000DFDE71EACDDB613F3B9211DED67132D3A4
+:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C
+:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38
+:10A470003DB6D22DB46A574F4A6324CE7A27A7330C
+:10A480003AF0C97AF279B43D7983E103C80DF866F0
+:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD
+:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1
+:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4
+:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC
+:10A4D000B27844F8D637C82678D62D34C3D74A9FE9
+:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA
+:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B
+:10A50000919E11F9E0AA46335D9C6E9F6F7A830895
+:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69
+:10A52000CB88EA806F1D6929799A82F2E8034B7023
+:10A530003DAF13520B729E9CBAB56451496CFC1727
+:10A54000393D7F5677EBA5202EDF505A4ABC71D695
+:10A55000F33A8793C0F7EB09E019E572F70DC033C2
+:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8
+:10A570006E643C9FF07A113E6F34B427C33E8F89DE
+:10A58000791F64F3825E33E2E3C457D45B56FE1D49
+:10A5900020FA4D48C791642FE8111F9087418F74AE
+:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64
+:10A5B000B36B0E233ECABD01849B28D72D34AFF365
+:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35
+:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4
+:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB
+:10A5F00018E137278DB53FBE7364F8CD4963EB3C56
+:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B
+:10A610008CE32FFB229F443363E5ABEB252D1287A0
+:10A62000CF36789551C17D83058E577F3116C7F798
+:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343
+:10A64000785EBB5152253A84239DC9DD6B85BCB32E
+:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2
+:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C
+:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77
+:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889
+:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E
+:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E
+:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C
+:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649
+:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3
+:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756
+:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5
+:10A70000B5352054C8B79202463BD5B7E1F356326F
+:10A7100019EC87D0260FFD7DC2C64FD6835E262456
+:10A7200082FDDF75A83722BC09B373FB7BDC3BB627
+:10A73000D076AF825C80F1893A3654629013762FDE
+:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB
+:10A75000C8E3FA1657B9BBA434B07702D7C17E0656
+:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC
+:10A770006D411C16ED15611F072F0BDE755E19C8A4
+:10A780001F87E6A24B5904CECB85948EAADC3A8C67
+:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8
+:10A7A0009B322D2FBE3829007E47795FE1011F1DA6
+:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA
+:10A7C000D071F26079C76AABC711F243986C066129
+:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703
+:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771
+:10A7F0009DDA13E91F743967139295A5F5CD5509B4
+:10A8000071677C540BE5BD0F8AF13EEED20A08F960
+:10A81000992D1C9468FDD48CA405760A2F5F91981D
+:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68
+:10A83000490BECB0EE06317FE90258DFD259A25C39
+:10A84000EE82B22F85F787F55650F955185BBF3D5C
+:10A8500087CE9F21DACF58308FF63D5CD9526DA755
+:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7
+:10A870001319F50B52287EF6124AA7B4FC64C6954C
+:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA
+:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608
+:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8
+:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594
+:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F
+:10A8D000994CEEED4D8E5FAF64307B80C20DF54933
+:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7
+:10A8F000CC88F1DBE594872B285F12275BA71867CC
+:10A9000098FEC8607287E89767803C5D0843D0ADC9
+:10A9100017A912FABBA42525321E688744ED4B40C7
+:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A
+:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11
+:10A94000290AED84F16AB2734BDB83B171E8BA3B3B
+:10A950009C534CEBB6576440FDE2D29B2719E0397B
+:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364
+:10A970000AC17EFFA945EE96F72D7610DAEECA4C95
+:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F
+:10A990004EB53464B03B031C1ED5772EBC1FDA3590
+:10A9A000F53948126DB77E4F653619412F367D3126
+:10A9B0009344A61ACAF6A80272A7E98B39F87BF568
+:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C
+:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E
+:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9
+:10A9F0009E82F54370B773B82BF1D7395FD02985A4
+:10AA0000B7CD405F4B39BD51E9877194FECB26F538
+:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953
+:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8
+:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70
+:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6
+:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E
+:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099
+:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22
+:10AA80000D3EC7627D79DF330AECB32901DF8632E0
+:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6
+:10AAA00054D74CE08B853602220CF60DF66AB9902D
+:10AAB000B764D70B5576FAFB5099CADB00E06148C2
+:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD
+:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA
+:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7
+:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859
+:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4
+:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5
+:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A
+:10AB3000D171EB9C018C93093AA923CE801BE04E86
+:10AB40008DA62F41EF2F746119FE805DF269B7C4A5
+:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A
+:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C
+:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B
+:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88
+:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB
+:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3
+:10ABB0004007BFCE286076ED15B4F202CA94CE6A83
+:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B
+:10ABD00062B2F31AE4508104766B76920A7286E2CE
+:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E
+:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1
+:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309
+:10AC10005B3A8E938FE3443AE172EF376327F68015
+:10AC20007E12F253E0819C92713C517F505A54E065
+:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE
+:10AC4000BF793EB597A6D7F6466D5E902AB72FB866
+:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51
+:10AC6000722A8C379EEE83FE7428393CA9C51DC319
+:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2
+:10AC80009091E163DF06FECD4A65ED87E93D5EAF59
+:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C
+:10ACA000AC42A37D1522408776C2EC2C19748F1F0D
+:10ACB000F519C2ABFACE8634D09B9FF52D4D239368
+:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0
+:10ACD000555E9709D8CB7738185D2AE9616F06FD74
+:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA
+:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D
+:10AD00000196018AF73432A87B0D784CABB099FCE0
+:10AD100007C71793B1FF99DB0FA509EC873293FDA5
+:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582
+:10AD30001043FB9564E00E186FE5FA7C53BC289134
+:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F
+:10AD500045DD38FF31367F6CDE14CA70B179E54CC1
+:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9
+:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E
+:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D
+:10AD9000C0FDEA035CDFA41D117663724092627A03
+:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13
+:10ADB000806178CEFCAAF6655102FA98F00FB12FA7
+:10ADC000CB6785E512909FB512194F3FD3E799F5F0
+:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD
+:10ADE000EDFCF04D1995DF62D447920C728F8DD730
+:10ADF000CCE92178E2552540E57094DB43BB7CDA51
+:10AE00005D40171DC9A993414F74248F8D405C622A
+:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7
+:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D
+:10AE3000BD41D256533EBE9FCB89261FDB4F932F79
+:10AE4000AA8CA3F3E735B17514F41E90EC0679577C
+:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26
+:10AE6000111269AB2983F69A1DCE41F27A258C0F17
+:10AE7000E7B55040507AC853D9F86E35225D3B296A
+:10AE8000B6DF2EDBA249A027BAB25254D013277DD9
+:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF
+:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D
+:10AEB000BE6E0BDD1372175F570F93BF32799E0082
+:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD
+:10AED000C822E127D0CE225D04F146701F599B267F
+:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F
+:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F
+:10AF000023117F08BD26DA3912F8D582EE536AE3A1
+:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0
+:10AF20004931F8BBFCA12320B7F27A7748001B2BEC
+:10AF30009D7564FC50CAA7FBBCF546E29549E275D5
+:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D
+:10AF5000677CC2E305B3FDA163008FE67DDB14C00F
+:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA
+:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9
+:10AF800069F79EA80DECEC8D4405FE6FEADD732891
+:10AF90008FC227BF499B260762E3E5374524584FF8
+:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4
+:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B
+:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0
+:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D
+:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0
+:10AFF0001EB58DF60D249129A8AF470987E916BA29
+:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A
+:10B01000117614CAAB430EB68F0EC2D6DB99A915B2
+:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD
+:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723
+:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5
+:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2
+:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14
+:10B070006572268AF427D66BC5E73C1FB3EF2EA274
+:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07
+:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8
+:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C
+:10B0B000DB116F623D354A681CF865CBF878CF5CD0
+:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC
+:10B0D00042F72BCA5288DBE9FF2E439CF61266A288
+:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614
+:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6
+:10B10000007F01E4532B9D523983744F7405CFB9EE
+:10B11000A89CD451AE927010FC1421873B397F1348
+:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D
+:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D
+:10B14000394C4821F86B627C2BFCFE99DBED71F0E9
+:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736
+:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5
+:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91
+:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC
+:10B190007574D93615B7303D76870FF1974A987C8C
+:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F
+:10B1B000C673099F4B857309127E5659EA89D1835C
+:10B1C00015BF81270E28015A7F492FE38318DC9889
+:10B1D000BE12744BE51CE2BD33539C5F868300575F
+:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20
+:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8
+:10B200006BF4836ECA7901BF825FA8FF68E2AB2747
+:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C
+:10B2200035EFB7201FB96B993C71F79BE52021776B
+:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60
+:10B24000769278DD37482DFF097932640FCFDF38E9
+:10B2500045ADFC720A571787016FF76B1FF3B73EB6
+:10B26000DC4511017C696F5146B2874F372E89BE8C
+:10B270002601BED770587FB8BBFAC23F409C7157B9
+:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8
+:10B290007ADAD71E42FA19F4BB54882752F1592B97
+:10B2A000517A68EBFD55EA4C382F7BEC8229203728
+:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7
+:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA
+:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225
+:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA
+:10B2F0000E2C3FF36F8FFFE22F60778452556877F3
+:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9
+:10B31000E7B982BEAD726BCF01E453412F9780DE57
+:10B320000538D533F923E8F95D7EDEB4AADADD0508
+:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF
+:10B3400063F512C6D9BA28D540BCA32B9954C0378F
+:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A
+:10B3600043FB25FB5C640BC6E520A84BFD0124755F
+:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D
+:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9
+:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897
+:10B3A00071D254BF9BD32DD39B797B171504504E7C
+:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9
+:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08
+:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A
+:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F
+:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80
+:10B40000C6E9E27A6B275B37EDEF8573543A9E7796
+:10B41000C6141CA7CF9181FD75D67FFECE3629B606
+:10B420005E4AA963416FC178656ED0337A3DE227E9
+:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6
+:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F
+:10B4500056786EE4F53FF36BF825BB324D7A2591B3
+:10B46000BDF2CC151F33FDFBB37750DE34031DC393
+:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE
+:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1
+:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB
+:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26
+:10B4B0009F72D5C338076D3684E7C19EF377B44BCE
+:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F
+:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B
+:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB
+:10B4F000C7EC5142ED51689F3E2FD2A6207D959614
+:10B50000037D3D73C52F3A418F37CF235E187FFBF4
+:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2
+:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6
+:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B
+:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A
+:10B55000217D5E12991981F8D9471C7E028E1F3B0E
+:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3
+:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142
+:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0
+:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4
+:10B5A00039FEE2D52783DEFD88E31FC508C8772E64
+:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5
+:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5
+:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6
+:10B5E0002E47295D00DCF21A43480717FB6E5021F5
+:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED
+:10B60000FA3343651087F6677BD0CEF1CB953617BA
+:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2
+:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756
+:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3
+:10B6400064F043C4B9868043A42DB9DE283F7FC28D
+:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38
+:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7
+:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5
+:10B680002E5F590A7E65739D5B057EBBEF67D22AEC
+:10B69000A467081682DF1D5E8D7820140FC00F246A
+:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4
+:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A
+:10B6C00034E61D0A3920E44BB3323001E858F04328
+:10B6D000F39C810900B7D1CA938F1D94FF817F2805
+:10B6E0001C807F04BF789E667CB2A52D5009F55B57
+:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89
+:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A
+:10B71000374F8897FF26E4B0D3CEE49B339212696B
+:10B7200037D0179CF979A6E017F3795236C48F8F7A
+:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2
+:10B74000605EBB881759C7FDD82F99E232C26F815E
+:10B750007307689F93C5F827258BF3679688CF46B4
+:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E
+:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1
+:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06
+:10B790003FF839D770FCB2714878A2292FAECBB6EA
+:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB
+:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6
+:10B7C000C451AB9CC15219E765712CCF1CF209E83A
+:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92
+:10B7E000CE2372C319A6727E639EA9FD989642531A
+:10B7F000FD391BCE33D507F529A67251D70C53FB63
+:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57
+:10B81000D2D65B0F78397FD795A67E5576AFBD948B
+:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055
+:10B83000292B8878ADB29BF3882FD8678607A4CBD5
+:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0
+:10B850001E10FD83C3E9813807D4501C3F53D0B973
+:10B86000285BCFB584FC3853FA4BB44E417F89EA4C
+:10B8700013C1ED3B9CFF055C1C4370A95747828BAD
+:10B88000E3747021142E9EAF0E17EB789B529A3101
+:10B890004FF8352818ECE38156F37D98657A1AD372
+:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED
+:10B8B000C9E1F2218509E261947CFD16C7437F222C
+:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF
+:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359
+:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836
+:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714
+:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7
+:10B910005BD7307C9172B473429971E3A5D7E8F29A
+:10B92000A8F044E482B8FA32E13872C388F9E51B22
+:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD
+:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED
+:10B95000D013399539211E5F87795EE563DB57DDAA
+:10B96000A54F4A0CAF189DC587539DF3E33C70D695
+:10B970002783CD60E82FEE9F88725D382DAEDD9075
+:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA
+:10B99000FD5636D377BF4B2067D2793D5DA703CFE5
+:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF
+:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15
+:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF
+:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774
+:10B9E00069CF66E7A1D43A27C10C34F575056CC55B
+:10B9F000621260E7BEE3BC101F12790189E9D58E9F
+:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F
+:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB
+:10BA2000D303EDAF2B98D7339007EB3B537A22F239
+:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B
+:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31
+:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787
+:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008
+:10BA700064DFDB93537BE0FBB96B6C84A4527E8163
+:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA
+:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B
+:10BAA0004339999F0B27F37361255BE98432D18A6F
+:10BAB000715F17F07D75DA0263615FEF4BEA44F066
+:10BAC0005BBCB6880ADF54122D61F9799130F86BAE
+:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA
+:10BAE000D19494C117C701FFFFD286F7A21FF7B206
+:10BAF000753EFE403E9EB350818FF26232FC4EB7DF
+:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC
+:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB
+:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E
+:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B
+:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991
+:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22
+:10BB60001B317FC661C99F71D84304CE851D43F93F
+:10BB7000330D04F367E838C6FC990FAAE2AFA39F20
+:10BB8000CB73C7172909C64DC5DF3F281C799F8E87
+:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9
+:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A
+:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC
+:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186
+:10BBD000F1A41051F7E0FD1EBB637040F06121B489
+:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF
+:10BBF00020B71669E63281F60639BC1862D8741F80
+:10BC0000C9E71563FEDFA72490E61D418E3638E5AF
+:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A
+:10BC200030C766CA631ADE9FE703F07B68B77A47BE
+:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4
+:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE
+:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A
+:10BC6000A19939D82F30C1785F60AF5D4B9942BF41
+:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945
+:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B
+:10BC90003BCF02C1E7A4726F0561726F454E21CFA1
+:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE
+:10BCB0000F831F87BB158E21125809F9DDA783E773
+:10BCC000865C6D450E9DF79A57921590FF2B9D83CC
+:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B
+:10BCE000E03CAEF8C967E837B542657915641EDAFD
+:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742
+:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25
+:10BD100029B97E8CC36B9940473F4F6274F4001D74
+:10BD20008996D7FD6222DE87BF2A37AC423B91E776
+:10BD300047B4C109909770A670A27F1C4047A783A3
+:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F
+:10BD500003EFA195FDFDF843C0539C6388F5A9B995
+:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3
+:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7
+:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3
+:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1
+:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A
+:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713
+:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B
+:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8
+:10BDE00073706526E07D1EDF771689A6C3F9E62FFE
+:10BDF00092F03C60989EE4FC41E195920BFA64E17C
+:10BE000020C635FA27C4970B29B98CEE86DA77B1AC
+:10BE10007912DD43C8CC9546750F819485311E5843
+:10BE2000E97447658A875B383E94FC9B54B00F2BBE
+:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51
+:10BE4000CF7BC73912CBED35F213E52D71F63321D7
+:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B
+:10BE6000808DDDA31EB499FCE46C72467EF27E17D1
+:10BE7000E397F73242A80F403F80DEE97CFAC252D6
+:10BE80004026D81990DF33E8494639DA9E37A3387F
+:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB
+:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57
+:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43
+:10BEC000CE59E978FF00E0373736DE10FE13E0F98F
+:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92
+:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC
+:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB
+:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD
+:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994
+:10BF2000FB3089BEF92DF40F859D91227F9932FA5D
+:10BF3000750AFFF97479D6CF803D46D7536573E310
+:10BF400079E733747FB9546E5429EC5B399F5215ED
+:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F
+:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2
+:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4
+:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17
+:10BF900025FA354C9E5AE49C906736277B6F84685F
+:10BFA00024E0CDC2381283BB2EE1FB57B345199C68
+:10BFB000145A9EC59124417FBAEFD9FC4B56857324
+:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074
+:10BFD0003B570AD9D93A222C0F91B414407B9B735A
+:10BFE0004086F945BC02579205E3887959D9C3CBFD
+:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D
+:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8
+:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10
+:10C02000A40330BCC42B41F9FB52F8E7C017479575
+:10C030006E12A4BF9FFCF9E704DF65831B6245F025
+:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055
+:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD
+:10C060007C9979FA784EA2388EA38AA17EF0466632
+:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC
+:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C
+:10C09000027DE274688857A157D6EEBD9900DE9AFA
+:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13
+:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8
+:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6
+:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF
+:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53
+:10C0F00016D852F56027E40B0D6E265EC82F194640
+:10C10000BFA7283F507A7804CA74DDEB5687FFE555
+:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C
+:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636
+:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01
+:10C14000AEA2BEA948DEE3687BC883824C04D69EBB
+:10C15000D8E2B51F07ED0370AECFF043F2147C3F79
+:10C160008970F937DDC2873363FC80F5A5BCBC8ECE
+:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA
+:10C18000FE5089F8C3F8790689FD8171AB63F3A08D
+:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD
+:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F
+:10C1B0007ED23710B50D666908B4C37865242403B0
+:10C1C0009CCBBD9BDB617D1736BC9209F475735E19
+:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3
+:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154
+:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A
+:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8
+:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8
+:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE
+:10C230009610CD01FB5AC2F957F0FF52ED56B46784
+:10C240009786CC76E9EF25866F7DB98476E215F581
+:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5
+:10C260009590E78B41BF831CAEA5FADC603737DCC5
+:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F
+:10C280008769E6F761D6ED6B736401BDF3FB30EBB4
+:10C29000F6BFD369CC0314701A7E1F6610F31F9784
+:10C2A000299103704F68D94D748FB4FDAFF8FD89A3
+:10C2B00067E1FEC494181D79AE7445597E9D867958
+:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD
+:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43
+:10C2E000706EFCCD3C663F6F97585E97BEDC89F060
+:10C2F000F6CBE488F19EBFBF2884F97433F202388C
+:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E
+:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4
+:10C320008FE6CF0C95DE3229366EDD7E96BF57172D
+:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F
+:10C34000DF3D408FC3F556B819E8CF51155A7E1D11
+:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A
+:10C3600057857B781D95A14535586FC77B8259F558
+:10C37000249A44EBCB5E527A20CFAF91742B304E8F
+:10C38000A3458FDDE47E56013EBD69A72346970491
+:10C39000F213D52210784DBB87C545500E09F964BC
+:10C3A000A56732CE2C874A85DCA5F281E5F73530CA
+:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD
+:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0
+:10C3D000E0C749F0FB64EC87652A4F8B21EF742698
+:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3
+:10C3F00056561002EF2358F143E7433A17E77D7092
+:10C40000B402E70833F9FC9FDBB449D120E08B4448
+:10C410006C14CE9D520BEA1D27E481D2EF16298CB5
+:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5
+:10C4300001DE6739FB52000F4715D509F5359030FD
+:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F
+:10C4500001BE0B02C3F085F70BB404F8D2845C2153
+:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF
+:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C
+:10C4800078B47979271DCCAF984106AEDF2D0DA782
+:10C49000938F0F6E90730CF424E8F4699EA72FFD20
+:10C4A00092E7FD967950FFC5F425A383725E9A0149
+:10C4B000F465A083D9FB5C5199EEB394F79F01F426
+:10C4C0003025A62FA33677402904BCAB5DB23CDCF7
+:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D
+:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5
+:10C4F000920410FF9516BD53EDAEB3039D543BADB2
+:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23
+:10C51000BD320AFB94E27F42FE08E78D89F07F413D
+:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF
+:10C5300086787023CB4B9EFAF2B8762867AD0DE271
+:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C
+:10C5500058B49ED6D3F29E60A81ACAEB3648284734
+:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD
+:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C
+:10C580005743795D17EBFF478F5307BFBCFC48A4A7
+:10C590001D7E9FB895AD43D87D7339BDED919EF852
+:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A
+:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4
+:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A
+:10C5D000F9544E10C43BA5D34296B7DA43A75893FB
+:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832
+:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81
+:10C6000091207E007B44FD9B203F757E510BEAD339
+:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4
+:10C620005F7E4B3EB3938EF13C7AF17B63246803CB
+:10C63000FF640F100FBE03147D19EC963DF0BE9100
+:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5
+:10C650002D761D94C05809DF55B9AC8F44D352874D
+:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4
+:10C670001DBF54888F59E351AFD4713C09B9B194AF
+:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF
+:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3
+:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F
+:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C
+:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D
+:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926
+:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246
+:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B
+:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4
+:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5
+:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF
+:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD
+:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B
+:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A
+:10C76000437873517B2A05FC7DC2ECE23C32AA3C43
+:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E
+:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055
+:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC
+:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3
+:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F
+:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8
+:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD
+:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936
+:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4
+:10C8000050595A300DDA694A2EC4679E62FAA2D98D
+:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4
+:10C820008C1318509650789FE4E7FE27F97B402739
+:10C830005DEC2BD6152858540AFD4EDE3C80726301
+:10C84000A8BC6800E542A02084F39E5C2AEA79F93E
+:10C850006E5626DCAFACE47C8271E33871E2E171A4
+:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1
+:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D
+:10C88000547D02D0C3D78DE39E1CD387FBDA523987
+:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C
+:10C8A000F866AF996F66178CEE3CC51A671F053F97
+:10C8B000CD2F18C10E7A12F4972386875B787E53AA
+:10C8C0008DDC540D71A54F5713BC677BCB0B32D257
+:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C
+:10C8E000A71030C815B8A71030F875704FC158861A
+:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104
+:10C90000582E25D7B6439C6E5D17F14602ECDE82A9
+:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD
+:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228
+:10C930008FCBA3B06D17CB536B7751F8031DEA5A19
+:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2
+:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF
+:10C96000C9E316FA17E0783D09A5813F37850C1E0B
+:10C9700082784773445261DE1B1E30CBEDA1F74C29
+:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7
+:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0
+:10C9A000C6A38752726E1AC6799E97218641FE48A9
+:10C9B0005AB6CF920CE703167824E598E9C21530F1
+:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65
+:10C9D0009D37227C336BCD74B2466E42BE1770AE6B
+:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8
+:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613
+:10CA000055BB03585DE72C8FD93165CFB7E021B016
+:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A
+:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27
+:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084
+:10CA40006CBFD43283F70BADFB057B8B18E25256DB
+:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669
+:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F
+:10CA700014378E6BF7897508B888F993488B9C0337
+:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4
+:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8
+:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB
+:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990
+:10CAC0005B9C36523EE61DADE67B30741BDA88F780
+:10CAD0008A00645970EE4420A842B65E7A6800DE8F
+:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7
+:10CAF000535FCA00D7A1783E61F78415DE4F29E85D
+:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B
+:10CB10007C5ED0133943F5BF319EEBFFA3BE775146
+:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E
+:10CB3000704DBAE838D8272E62D837EA4343598E69
+:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C
+:10CB5000DEDF7518CBD157DE7718D71F617905F660
+:10CB60001081FC5BC547EB8DFA65880E2943951B48
+:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4
+:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E
+:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16
+:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95
+:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F
+:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8
+:10CBD0000874103518A0262BFD19FCF92295609ECB
+:10CBE00006E17E4921F74BB66D6DA90717EA115D85
+:10CBF00009603C88FAF739B47E2261F58F742DC63E
+:10CC0000386BDB980979F05E95BBEBA2E3707F6F20
+:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A
+:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90
+:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B
+:10CC40007B918524AA427CA5F06E5B159C9BD9C183
+:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729
+:10CC600034347E10E0A698C6775BEACFF41EEAFE65
+:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25
+:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6
+:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF
+:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B
+:10CCB000A26A04E34248278FE8F1E9E411E2AD8279
+:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC
+:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5
+:10CCE00080155F644A94AEF591AD8519C67C54B247
+:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67
+:10CD000015F0F5E9D7C497E20B45D37C10CF240189
+:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31
+:10CD200000CEC12EF69E9AC093186F6B2B89CE331E
+:10CD3000F87F4135AA019C6BE44955907FBEA30C56
+:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B
+:10CD500054EFA3782921E4BF372F4B2BA6F53D4193
+:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8
+:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94
+:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7
+:10CD9000F97703892641FBE473581E679A667ECFB4
+:10CDA000C651619607148C7D39E5106FE1F4CEDF32
+:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1
+:10CDC0008B9198DAC67C03E5594F9B82F077707996
+:10CDD000453632BAD0E95FA0A7740B1D7954331DD4
+:10CDE00039E402CCC3157C25D623E66F1B93956CE2
+:10CDF000C775D9F13D6C87554E58D6E7866020C57A
+:10CE00009DDB4722115AEFD0197F10B91F7F774C55
+:10CE1000272433F815D6F935E553E89CBF8D7CF20D
+:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD
+:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF
+:10CE4000975356B879FAB46AA0E78BE49734C88F41
+:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E
+:10CE60005586674A2F6A942EFDEE3BDC98173CB539
+:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2
+:10CE80008209E06AE5D74470FD96806B39856BD1E5
+:10CE900099C355D1997C4E9FC5DE593C384661FFF8
+:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06
+:10CEB0006D1A9537749DB51A83B7779690E36678A7
+:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB
+:10CED000ED2420017CFF5B033BA27B9A9037830407
+:10CEE000F096A631BA1570EE9ECDE05CA871387749
+:10CEF00071B8494402385BE9D52A9FD3BE269C7796
+:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF
+:10CF10008EC1D5E11E8C829CED0ADA715F07820A10
+:10CF2000D67795B0FAFB5356E680BEEDF277E60071
+:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC
+:10CF4000D8BD831A792BBE43DA1950103F9E407C1E
+:10CF5000F995362BECC47926D9898C7078488D07E1
+:10CF6000076799629297F98D66F8A658E0EBFA9AEE
+:10CF7000F2E1B5AF291FEE216CFD778E17EF347407
+:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE
+:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1
+:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0
+:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474
+:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA
+:10CFD000B35A82F1F14D297F25F1E055D465D67F12
+:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27
+:10CFF000EFB67954F66EDBFF0164680340008000F1
+:10D00000000000001F8B080000000000000BDD7D09
+:10D010000B7854C5D9F09C3D6737BBC966B3B9924C
+:10D0200040124E42081B0861810483829E84406343
+:10D030004D71435151A88D40314248285E1A7FF509
+:10D04000C94282841834A0585A2F2C378BB56AB441
+:10D0500051A922DD2052FAD5964551F152BFF55221
+:10D060002F40258A177C3E5BFF79DF99D93DE76425
+:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B
+:10D08000EFBC332184906FE8BF04CF0412F410FC8E
+:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0
+:10D0A0005677A5E139F1F7115F22562D248390546C
+:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F
+:10D0C000B450266D4F80469590D5566F968F3E4F43
+:10D0D000A85954435C84AC6A2124388A90F6163BE4
+:10D0E000962B726CDE601A2177BE2C7BE3E82B3620
+:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A
+:10D10000479FBB9711924F88423F20D1BA5233E3D9
+:10D110002352425F98B3849049D1F9ACA9B1788386
+:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40
+:10D13000DF37F4FD6FE0E782681947583BAE13BE56
+:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F
+:10D150009A98F63E2CF61C72CE37322DE579497539
+:10D160004E5A96A71092D5FF7B5FB69047F78E4434
+:10D170008012920E653D01782A7CCCD5C9B3ECC4EF
+:10D180001985B378BECACDE01B27D1CAE4FEE3B649
+:10D19000015CE3A2758510AD1BF0915D1AB3BF2849
+:10D1A0002906082923A4B32578F03D6BF4B9730A46
+:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080
+:10D1C000B869BF442F7D5F0717A77666DFA73FA525
+:10D1D0006974BD2E4E37E477920278B5F37A8254A3
+:10D1E00037572D037CF9081941FB956BA4AE987D48
+:10D1F0004F13EF49502AE41D41DF79AC74D3760612
+:10D20000522869BBDDD8AE6620BC705C25FABEF63C
+:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7
+:10D22000E0A77ECF558B80635F1A859BCCD71B030D
+:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60
+:10D2400066D55C5E8A115291A676035FB6694EE49C
+:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2
+:10D26000C88F6D43F71D5E08709DB9FFC36D08350B
+:10D270002D5425E04BDB133DD5A12A9DBC11F88A26
+:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0
+:10D29000CE21362253BC384656D9EB9C51FCD8E0FF
+:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4
+:10D2B0001B564778D0C5DBB26FFDB904449119E91C
+:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D
+:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E
+:10D2E000D66FBA5C93791585CB9A17987C241E2645
+:10D2F000176C7686CF354463EDD98A97BE41D664E4
+:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3
+:10D310005F6F07F9A198E447BACF62D00743E6C42C
+:10D320001BE4FE9A825928CF069A67569DF1FD614B
+:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD
+:10D3400046EBAB943A3BC8915B33D74B753AFA1E28
+:10D350005254F73AD0ABA8DB3267E27B7139A53182
+:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A
+:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03
+:10D380006D716319C167C13506BCACCEA2F29A8E2D
+:10D3900007B0D77FFF29B5EE73985F14CF96287C2E
+:10D3A00080698B175B805FC5386D59F90EC0DBFA59
+:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0
+:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05
+:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D
+:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0
+:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613
+:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747
+:10D4100098FACF37B52F36B52F37D5FF8FB17F2983
+:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68
+:10D43000A1E7237CE536F2E30F722AB43C66671855
+:10D44000F02BE8F374F1B39ACAB810F093A23A50F3
+:10D4500099962F267A7A589F998FFAA38D4E0BF5BD
+:10D4600037B75F52041D5773FB70CE12031DF5E6EC
+:10D47000143AC07E24CE34944BA7A20B89A418DBA7
+:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24
+:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC
+:10D4A00085931AB1A7E9C728DF6D49238138AAEF10
+:10D4B000B6F82D58FF3C937E08EC952AC687237852
+:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD
+:10D4D00001728A96B7B56462B97AAD256B218C5713
+:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9
+:10D4F000B13B340BAD279E94497022B5174AAE2834
+:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA
+:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE
+:10D52000B86A81E275405BB177859286FDFCE03692
+:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B
+:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B
+:10D550008215C3EB7E05701ADE492C1AADAB7E55E1
+:10D5600002B9F6469E8AF276EB1F28438E800FF5AD
+:10D5700065819EFD62AD6D25CC73603C11D952FE74
+:10D58000ED4B310EDA9943F1B906F4AC2A484274F6
+:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6
+:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976
+:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E
+:10D5C000976A0D1D77082D8B7909B4760EC09F9749
+:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40
+:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C
+:10D5F000EDD3C37965FDED532AE886029D6FB27ABB
+:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD
+:10D610007F8D2DB01DF84351875EAAB3BB026B32DC
+:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E
+:10D63000707ED3E5637E99D2EF263F413B6B137139
+:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C
+:10D650001DD02959C8F4667E549EAD50E8389B61B0
+:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F
+:10D67000DFB180DD3C96042DB0BE312480A5872C1F
+:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3
+:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF
+:10D6A000E9A9715772652CFBC0966FE17E26A957D8
+:10D6B00026713F87C1D9965FD61FFE56B20CE17E18
+:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B
+:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852
+:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D
+:10D6F0003F39DF8DFDAE08764F8761C679C395400F
+:10D700000B63AB7BF700C98CD136839B413CE53F73
+:10D71000DF93AAC23CEA86C23885A17005908FB318
+:10D72000FE603003E773BE05E86204CC87D3472D63
+:10D73000D2978A7422F00DF4504BEB573430F850E6
+:10D740008310DB89E236CC7FCB2A4A27CEFE749247
+:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA
+:10D76000022EB37ABC560817F87EE75E053ED0CC91
+:10D7700040DF5E077DDE9E5B770EACB374A3AF1512
+:10D78000E8CFB92BE4877E024ECE29214DC27EDA46
+:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6
+:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6
+:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F
+:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07
+:10D7D0002541D7E27901891D67B8323FE2CF66CA99
+:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D
+:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B
+:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891
+:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B
+:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9
+:10D83000737DD7C278576CEC7EDE81EFF9AE473E40
+:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F
+:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5
+:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26
+:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338
+:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38
+:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4
+:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB
+:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D
+:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638
+:10D8D0001615E57B678B07CB8E162F8F879663B95E
+:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF
+:10D8F0004289148BAEF2FC467B7F78B311EFA9D539
+:10D9000046FF3B596F2FD37F49E5F986F644EF6810
+:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1
+:10D92000837D2BE0385D9E87F1620A4FB4AB853D65
+:10D930002BDA09A9C378AED5E467769AECD80E80C5
+:10D9400023C297C1B10BE088F02DE7F0AC667E13DF
+:10D95000F77BE285DF53B47ECE7C8C8B1094572B03
+:10D96000726CA89F3BF298BDDD8F7E3275F293F208
+:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB
+:10D98000694139B9256D8F672BD6E3BD4C9FFABB32
+:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6
+:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E
+:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE
+:10D9C00063586764FEA536368E44241827A5D866AA
+:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737
+:10D9E000939D23E214663CB96B8CFA6675117BBF7C
+:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67
+:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8
+:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA
+:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5
+:10DA30003B8207115FE47E98885B8BF114C2C6C3FA
+:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D
+:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD
+:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5
+:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE
+:10DA80001B32993DA0BC13F600934BE8E7FAD74D43
+:10DA90000C69608F1711EF76025E306B17F444F457
+:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D
+:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F
+:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843
+:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144
+:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB
+:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56
+:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7
+:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64
+:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127
+:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF
+:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5
+:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D
+:10DB6000F830E227A9DC889F44AF113F099ED126F7
+:10DB70007C18F1935EA022FCE2328D78EAC737A7C9
+:10DB8000F057D2609C187672765DA802F6B886CE01
+:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6
+:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242
+:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185
+:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE
+:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB
+:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED
+:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD
+:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8
+:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B
+:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046
+:10DC3000B8DDB1F7ED4529F42995836807D2890449
+:10DC4000B6533A8D5388929802EBD5705D56B06307
+:10DC500065586F17D6E34937964E1262FBD7DC1F23
+:10DC60003DAF200FC7731337FAAB29C48BA5E06310
+:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC
+:10DC800075666FEE009F46A3509884AC82F090EECC
+:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E
+:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38
+:10DCB00059F98B78D71628BF74E4062068A58DA87B
+:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85
+:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B
+:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE
+:10DCF000E44968778AD20CD77D1EED06989F627F33
+:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D
+:10DD100053FADF96D0BE22C50C4F4E9578F2C64519
+:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4
+:10DD3000FBFB970933C349F4FDAD07A99D0779346F
+:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D
+:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC
+:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990
+:10DD7000260C7663E22445853D8E2239580DF32525
+:10DD80004D16027C714F83713FB7B3B008E122EAB0
+:10DD9000C3F87E2E2955FA227936D48EDF58C0F387
+:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76
+:10DDB0004AD3A8DE4A82B820E5145A96760631F98D
+:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87
+:10DDD000AE81F13ACB7D0960976F3834EBA2B17414
+:10DDE000DEA1B0E205100447A5E0BA439ABC368133
+:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C
+:10DE0000CC23013F85C7D6863D7619ECDE90858C04
+:10DE1000443B973A5C93B82854215ECBF8FE965168
+:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48
+:10DE3000AD6671E71972F6F3306EA8D386F849E73C
+:10DE4000F94712A945FB39659ECE5EA6FF123B99A4
+:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9
+:10DE6000F68DEEA96671671709E2F767C8BB1C1645
+:10DE7000FABCA75A71033D2599EC73278C4749AE2C
+:10DE800067231BCF359E8D9768CA83B28B79B9E91A
+:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950
+:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3
+:10DEB000B67AD558F9139D2D2454A5CBB7700E1002
+:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953
+:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95
+:10DEE000D75FBF3ABCED518063F36D2F221D72BF27
+:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A
+:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326
+:10DF10008083C27398A265FD0CF835247B57A83026
+:10DF200088E6CC9A44D85615ADAFBD92120E950F27
+:10DF3000E9F334D95F0CF190174822C5F7064D522A
+:10DF400059FE9BF43CF0534E95847E58CE219F039E
+:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55
+:10DF60002A148C375457555C0EEDC30E317A715D0F
+:10DF7000C7F047E114ACA2FC30E2108B279492B0BA
+:10DF80003748DB877989350DF4C73C0A60985F27ED
+:10DF9000C70F8F0F949686FC00D444AF118F6E1379
+:10DFA0001ECD78758DA47804FD52448A985FC7EC25
+:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D
+:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96
+:10DFD000A1ECA1F62394895AC545A574BEA1743A53
+:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A
+:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C
+:10E00000519BE4A552D9505F9BA6887D3C3FE8D444
+:10E01000C42C0BDFE79971A746EB9D990ADFD76304
+:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550
+:10E03000F01387F5092377AEF71744DBEF28A475B3
+:10E04000DA7E80DB73B54B2DBE2D31E877D948469B
+:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440
+:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95
+:10E070005775F191C3853CAEEEAB60713612FDF978
+:10E080007A12CFB322F0BC330476C4ADAF5EE90D93
+:10E090009281E5AE355339A2A7938B051D8C2423BD
+:10E0A000D19F27530E54009D754D54801E4A391F31
+:10E0B000106EC761889FD2CF539FDEFD174D053F7D
+:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8
+:10E0D00022E83391F7434895FB7DBA2EC97FA90505
+:10E0E000ECB681ED1485BCAF83476FED8C24D00373
+:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58
+:10E10000679A0F858C5DF163FC669FA7AE11E6658B
+:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA
+:10E120003CB809C683C4BEC986CE09F17114189DD6
+:10E13000545F807CDE109A8579159DDE0983C6AF19
+:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8
+:10E15000697910F88DEAC12738DFE4943FF6DAB523
+:10E16000067E396AE297A3267E397A0A7EB9E04EA6
+:10E1700068EFC9540CF51CE0175D7D6B845F583D5A
+:10E18000CA2F47915FEE79D986F58D238F1AF865EE
+:10E190004521AD67EBF865BAECDB12C30E78E53BC1
+:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39
+:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE
+:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9
+:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53
+:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5
+:10E1F000F520D397423F97713CFE8DC731CA424C00
+:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D
+:10E2100082BE9E22912E1596BAAC76A414B59BE8C8
+:10E22000F7D06EBACFCBF266C92166EFD8E97F404E
+:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3
+:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E
+:10E25000D870A812ED90CFB36D83EE5775F2F546E6
+:10E26000ECA9525F45AC78587DA184F0BEC9A3C526
+:10E270001796813EBE0AF5AED0E766BDDC53F59237
+:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC
+:10E29000E1F501E50C3907E546442FF37A442FF305
+:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3
+:10E2B00077FA757A7B19D4B34FAD9717707970B62A
+:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07
+:10E2D000A929FC0EE54C2DC899A453CB995A90332B
+:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08
+:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC
+:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29
+:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E
+:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC
+:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3
+:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C
+:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516
+:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5
+:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18
+:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8
+:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725
+:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11
+:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40
+:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07
+:10E3D0005EA28F9D877157EBCE4791E879295C0F3C
+:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC
+:10E3F000D26E63713BF3F3FF2E90D83936A9D60164
+:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B
+:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA
+:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04
+:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81
+:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A
+:10E45000BA2362BFD0F7549D9F44EB400E113F0991
+:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD
+:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B
+:10E480009770416CFB85D671DFCD91680FACCC03E2
+:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711
+:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997
+:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C
+:10E4C00049E102965F2DE86BABEAC578726735C10A
+:10E4D000F8636768656A09AD3FD1602112AD5FFFDF
+:10E4E000328B0B6F2827013847BB219B603DE465C9
+:10E4F00074304376FE08E2E03D55D47F52216EF73A
+:10E50000E35A80EDBA8499B73928BDD4962B04FC20
+:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7
+:10E52000ABA62A64E519C4AD13E562897224E54FF0
+:10E530003519F876A078B439FE4CE417BC802F73F7
+:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60
+:10E5500034CD8278EEA9E871C12815F599594F9903
+:10E56000F958D0D340F4E7043B69A2AECECFE186A0
+:10E57000F93EB513ECA48951BAE8AD9D94142BFF74
+:10E580004A9409CD7F78457F1E2F41E9C6F1129A42
+:10E5900077E1F3BB206F00D6A778519E3E5849E53E
+:10E5A000708CF9ED6E597608E4E7AE96662C2F5024
+:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71
+:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC
+:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1
+:10E5E000241D5F474753FBE87774F83EEF43BFA114
+:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C
+:10E600003D2560686F2AA83B067CE92ADD6178EE2B
+:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3
+:10E6200049329CBBA0AFC8706E88F2F190662A5E3A
+:10E6300069FDFE441EE7E866FBE49924F283740951
+:10E64000A964601FF426B23CC8D62CF67EEB8DACD4
+:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4
+:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE
+:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB
+:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638
+:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46
+:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD
+:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199
+:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657
+:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545
+:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4
+:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757
+:10E70000F3FB0988827ED1307714AE01913F22431A
+:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0
+:10E720005F934D787ECD4CF427051E364139AEFF00
+:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A
+:10E740006FA66F15F112C7E95BBA99E5456499E8C0
+:10E7500046E45D08BA14F919225F43E46FD8785E85
+:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7
+:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660
+:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0
+:10E790005F17E556F875321DC21BAE027BB5A85C4B
+:10E7A0006B85F37C29A504CFE994964B58161D621E
+:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774
+:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3
+:10E7D000E6CDF3906772FA5E3D5966F9D155129312
+:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27
+:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72
+:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF
+:10E81000883B4585F98535E0C7153977EF817C88D8
+:10E82000272E647BB6171F62F6C28FCBAFC6FB469E
+:10E830005C5FCB188F754F49F406E0433556A6FF51
+:10E84000453E74B9D15EA835D90B179FE2FE8F14EF
+:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2
+:10E86000F78030F950CAC77496BB1D10BF2E3A64AA
+:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74
+:10E88000D0F3A82F723886B89CF81BCF93ECE172B6
+:10E89000E2752E270E839CA0E52B3C4FF210CF9300
+:10E8A000349F97D8D152FD92DEDE319745927F1684
+:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB
+:10E8C000C7B802E9676FF2DD15401CEB350BDA952E
+:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB
+:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0
+:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D
+:10E9000003E97988D78EFBFB649E93BCABCB53B9EC
+:10E91000DDD7350BE6FFE03605CFE7887113BD7410
+:10E920003E3A3A499BB22713E6DF39359809F64C4F
+:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603
+:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD
+:10E9500064B867C20CFF01ED0EC80818FCBC95B383
+:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96
+:10E970009EE6FD17099C0EB3161207FADD408F8341
+:10E98000E0D9650D21DED62EB454C73A5F5B54C47E
+:10E99000F0BDB6F453B48B4971EC7924959BE9959D
+:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483
+:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8
+:10E9C0006A074948EF28973E2BB5313BC1242FFAFF
+:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8
+:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898
+:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B
+:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D
+:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF
+:10EA20000C043F33BC167EC7F032B7FFA888C74737
+:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A
+:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6
+:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE
+:10EA6000A93980B4594F8F820819B9555A66B07FB9
+:10EA70003A24EFE167302ED4970AFDA6933A852118
+:10EA80003980EBFA93146E05857529D15641D94822
+:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C
+:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC
+:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB
+:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909
+:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4
+:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758
+:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73
+:10EB00003923A5AE11E07115516DAC647683589729
+:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1
+:10EB2000F959D7E0EB1378FF4711C175DC5EA46299
+:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E
+:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB
+:10EB500016609C4CC075603A35C6C976C121D77421
+:10EB600084DFCB7AF811A5AE04C615EBF96759E836
+:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B
+:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF
+:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6
+:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE
+:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9
+:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C
+:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C
+:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6
+:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146
+:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD
+:10EC10009619890B9347D0F28238E277D0F13224EB
+:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1
+:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845
+:10EC40005B371DBE932CE37C8E503B51A172ACE22E
+:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C
+:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228
+:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED
+:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58
+:10EC9000D13CE82F5CC7FD8537E3991FF466A18856
+:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199
+:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98
+:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1
+:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8
+:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E
+:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B
+:10ED000058E09EF36B0F9FC74070694C568842E1F4
+:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A
+:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90
+:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA
+:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C
+:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9
+:10ED6000BC9BDB418D2793893F55FF9CF17774FC59
+:10ED7000346CFF2D87DB6FF75BAA63E577358F6611
+:10ED800070199DAEF8201F684C90689B637C57F407
+:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C
+:10EDA000D1627D6F3187A3986F4F4A78910FE9B395
+:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC
+:10EDC000FC309C0BE37F7C61EC733B02CF9394653A
+:10EDD000682FBF9052F734C8B77997D10AA58F2111
+:10EDE000F38216763EC53F28BEA370964960E26066
+:10EDF00070B661BB18EFA317393F523F1CF2D4AF76
+:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796
+:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661
+:10EE20006D9FB60FD4C15599D4064D61CF6F86B290
+:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2
+:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E
+:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835
+:10EE60007E36DB799B47F3F8FE2432E94CFCF24610
+:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6
+:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E
+:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8
+:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196
+:10EEB000D345704F0C99C3EC8638387C407F8D9BCE
+:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A
+:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6
+:10EEE000E807D5305EFA43091AC0ADA3421B0FF202
+:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96
+:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742
+:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28
+:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E
+:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28
+:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF
+:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C
+:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF
+:10EF70006530632EE8DB0715A647F9FCD2FE9855ED
+:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317
+:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8
+:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE
+:10EFB000EF2EB126837D036B898577519AED20C1B1
+:10EFC000878D0F24FA21EEFAB1D45708831CB13291
+:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51
+:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC
+:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314
+:10F0000008E2B930715F999BF813E9779A760FD9C6
+:10F01000027646DA086DFC723ADEC7D6702ECA0B4D
+:10F020002ADF24AA5B73C7ACB944A17CD53894DA33
+:10F030005DB47ED14377B37A7E789185D6AF7DE893
+:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F
+:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9
+:10F060003F74E012F0FF8F2433FB8178C35702FD19
+:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28
+:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731
+:10F09000083B96D971629DE23D92197BFCB1639861
+:10F0A0001EBD661AEB7741026977B0F3757EB0C773
+:10F0B000F6EE1A8570491993C2E145C7298D8E2352
+:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9
+:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744
+:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E
+:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7
+:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB
+:10F11000403ABA2081D98BA494C28FCAB38D1C6E99
+:10F12000EBC624333F32828721128EDFCAE197CDAE
+:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565
+:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1
+:10F1500072CA78308F9411F8DE6A07B1E373B22572
+:10F16000F25E1E7DEF82697D13811F96727B98F897
+:10F17000CFC7BC86062E2D96B6876C10975EDACD6B
+:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA
+:10F19000CDD61730D02739D4973B3BB13FDD46E081
+:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B
+:10F1B0001D671B1F629E267846E06C9A9F8027F091
+:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8
+:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60
+:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064
+:10F1F000541607EFA9F583FE6BDA558171AAA54F66
+:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16
+:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5
+:10F220002820C7CC5B7F9BCB01617735727D73E46F
+:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3
+:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6
+:10F250009D46FB69F16F3664A8484FFE6116DC04D9
+:10F260000B0E83CDB0C66D56DC4F693C247BE9673D
+:10F270004813E9BB15E6677E1FE67192E2BDA95B04
+:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2
+:10F290004D3D177E00764593299FA27E003BECC52D
+:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED
+:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F
+:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F
+:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB
+:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57
+:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4
+:10F30000B41A367D27EC730B3C41CE06D829022F68
+:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A
+:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA
+:10F33000DB33C004697DF04B1BD0F747BB25BCF71E
+:10F34000DEFC7EFDE6E75D40870027F04305BE2238
+:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC
+:10F3600001476548E78F3C0D7194D7E3BC0087FAED
+:10F3700047AE75C17A3E5096317ABF6F5506DC971D
+:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2
+:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E
+:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F
+:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B
+:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6
+:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9
+:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F
+:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21
+:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F
+:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2
+:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9
+:10F43000D7678718FF34066AABB13D640D0E81F6BD
+:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75
+:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1
+:10F46000AE38C37E7D947E8CF745097E157ED6D559
+:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE
+:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61
+:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626
+:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0
+:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB
+:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9
+:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA
+:10F4E000111D3C051C057D2E7E68297E2742C782A2
+:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD
+:10F50000FE837525F563C0CE7D560E6CA1533B4E30
+:10F51000E7722B85FFF1DFE561BED12AEE071C778C
+:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2
+:10F5300060F6D2715F9F2B596737BDBD4B76819DB9
+:10F54000170E90EA58F1242AB1711E6132503BDB4C
+:10F55000173BCEE3A1C779BC73BAECCC6D8638708B
+:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC
+:10F57000FF7EF66799DDEBE9D714C89358C0404089
+:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6
+:10F5900045CE6DB8BFF039B9194B73FC6431C4590D
+:10F5A00080DEEF353DDF7511D2D762137DD5017D49
+:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC
+:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7
+:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B
+:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C
+:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3
+:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25
+:10F610003B0EE7737CF79F726F82FAD37198877500
+:10F620007C651CE645F9772706E03CDFF11C16B740
+:10F630006B7DF6CB12CCBF206D88C793C536668F25
+:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6
+:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E
+:10F660003F5D4FA38DC5338F2792398F033D2733DD
+:10F67000FFAEE999C95B215F6E694FAF0DF607A632
+:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD
+:10F690001DCA639BEEB652787F0C3622F5C3378DB8
+:10F6A000EDBE14FCF0FE706170384EE100EBA2700C
+:10F6B000A907793A103C868EB521FD7FFFE0F1095C
+:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45
+:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57
+:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD
+:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12
+:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837
+:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F
+:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3
+:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1
+:10F7400035809DF2EE5849E4EFA01F22F277E4B431
+:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2
+:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8
+:10F770005B8737783B7004A37F2667D454439CA5EE
+:10F7800075059D171DA735DDE26E55E19A764B3064
+:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04
+:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50
+:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30
+:10F7C0000298B779A6704A2D191C4E66F808B8F54C
+:10F7D0008313F747C57DFC4A5A4708F85021D49F48
+:10F7E00064EB413F14FE8E14ECD7589316793BD846
+:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB
+:10F800005F2AE0AC1B0FD76F86F399C257E0C54162
+:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA
+:10F820001DEE1717F0157033E3E17DA0519D1D1FEC
+:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3
+:10F84000E5F204B4978F49242851FFED5845462529
+:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0
+:10F860003DF237F4A05E41920DF5633985F8FE3420
+:10F870007B96E1BD0390B74DFDF66359E576DC0F4D
+:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79
+:10F8900003FD9B1F641619C699F9CEB17BAFA2E593
+:10F8A0004EEE57F74DB5623CFED89FE755021C2F30
+:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B
+:10F8C0009EC986EF36BCBDA710E2103FF256189EC7
+:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A
+:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B
+:10F8F000761BC699B87FA7A1BF37E49E0626E3848E
+:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE
+:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751
+:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF
+:10F9300039E081327ED8A21258D747999D326C4B5C
+:10F94000DF23D55D5E0276D6678156A85FF075B776
+:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E
+:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7
+:10F970009DC8DB31F371D1C48A25307E5BA6D6D514
+:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296
+:10F9900089BEDB619F5EE425C54F935972FB0FACB6
+:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E
+:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70
+:10F9C000B323774898D722BEB7A09CE5DBDF5E2241
+:10F9D000EE3771A7FF642CBC9FC8F205209606EF96
+:10F9E000D558D04E711DF6EE83FBC8EEF41C728321
+:10F9F00078E8A979C70FFB223D874353258A9721D1
+:10FA00009D15270A587F02F1CD1E4F55C258D46F5D
+:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB
+:10FA2000D14306CB2F779D9488AACB33B08E5371E8
+:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411
+:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A
+:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2
+:10FA60003CC84FC20BD19470E64F629CC33BB2A31B
+:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2
+:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D
+:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644
+:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD
+:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC
+:10FAC000CC9F38355C134E01571783EBD7542B640A
+:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86
+:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81
+:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D
+:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5
+:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82
+:10FB2000A2759013AE285C35B82BB84307673BAD80
+:10FB3000D772B8FECF23F597B5017E17DA912EAEB6
+:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E
+:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59
+:10FB600067C2DF71197BD082F1BD37297D68401FE4
+:10FB7000C1F1087731DE8929AFA6C0F98913694A36
+:10FB80000AC06771D88670FB894282707F6A4FDA3B
+:10FB9000C26915C81F2AB677F371264FD4FE518269
+:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB
+:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115
+:10FBC0000C7A62797221E663355549A8879B9A3F82
+:10FBD00043B88BF1959332517579533D104D4CD705
+:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2
+:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1
+:10FC000013F72DDB419F34903DB6E53A7948BA3F72
+:10FC100089C8FF71147777D6BC180F72B656725F19
+:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0
+:10FC30007F8EF71156CF715F02FBFD631F4D9A0354
+:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78
+:10FC5000F7CB509F316E06AB27323A4879347F8E0E
+:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E
+:10FC7000C600977EEDB284795198B841E9E79F6B51
+:10FC800086B17B710B4298A735721C8BAF67A4B00D
+:10FC90003FC92BF277D346100DF657D39E72B07B37
+:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A
+:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A
+:10FCC000F84908EB5737EFC679754C70F3FB72FBB8
+:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64
+:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3
+:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916
+:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E
+:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F
+:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922
+:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9
+:10FD400073395C9376B2FD6F735EEC5CD05700172D
+:10FD5000BECFBC74D60B53002F029F1724906ECCDD
+:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1
+:10FD70008B451702FE84E5DBC53379D1F78403EDAB
+:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781
+:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7
+:10FDA0005EB798F799D359C8763A7426E44C23A9DC
+:10FDB000F3605C96CB150167314F01AF9E01F25D98
+:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C
+:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD
+:10FDE000BA849C35AF4FC85BB14E2177C57AA75214
+:10FDF0004182F210EE7E90C07FA833D8C3157062A6
+:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3
+:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB
+:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B
+:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8
+:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740
+:10FE500078F1F97FB59463F9428B8665A8C587A5CB
+:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E
+:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1
+:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C
+:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE
+:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27
+:10FEB00073ECEC5EDB397324CC4F9C43D879055A44
+:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26
+:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1
+:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE
+:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0
+:10FF00008C9D8710F786BC6E3913BBE12B386300DC
+:10FF100079A09297FDDD9464C5ABF70744F9D771DA
+:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1
+:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58
+:10FF4000FF0B270420E00080000000001F8B08004A
+:10FF500000000000000BB55A0B74146596BED5D591
+:10FF6000AF904EE88400411E76886020AF4E271D7A
+:10FF7000C26B2812C01762A3B2038A52A0189E490E
+:10FF80000CCC8AA37BBAB11904D6B39B193DAEAE93
+:10FF9000E869705076D6738890B8194D980695C761
+:10FFA000ACA3514141B3D820F258133A121470381F
+:10FFB00087BDF7FE5574572701F4ACC9C9B9F9AB31
+:10FFC000FEFAFFFFBEEFFDAA961D70B98300505DDB
+:10FFD000B63A0F0A904E918EDA902E5BF50398FB9D
+:10FFE000E178D5393017034C95DF08A696009C3D83
+:10FFF000046E1BCE1FD3AE9EDAE1C27F2E5D9660EB
+:020000021000EC
+:1000000000C04A3BFE8FE3B2CEBA8ABEF86F51B849
+:100010001ECC740D7F2EE35FF1BE2630E7C4C6E32D
+:100020002ED4BF4BF376FA55305B009AFDB3998618
+:10003000FD8BC03C0260B7BF86C7EFF957F1788FE0
+:100040003FC0749F7F1DD3BFFAEBF8FE07FE177801
+:10005000FCA13FC4B4D5BF95AF37B89D00FD01CE1C
+:10006000B5560C54F3F06834F6E286F6C999BE141E
+:10007000A4664167D3813C48ED60C9C8403A5B62E1
+:1000800079E0F500A4330DAB787F59E63B2C0FFCEB
+:10009000F1D991DF59A0FD64F4334329C0BD20F8A4
+:1000A0009F55F6DF17A5541AA83912CAEBBECC3EED
+:1000B000B04102B81F02F9F391CEAEACB38C97E811
+:1000C000FE14E709948714F8C274391765423F9308
+:1000D000BA533C289CD0E526032C71ACB1C2700009
+:1000E00094D2B108CAD704125CCE02580C612BD04E
+:1000F000FD3F5A8E45E2E4BC14200BB2F1FC6F5870
+:1001000078BE7E1DE8F9B875E50A19CAD2496E2E87
+:1001100096DB7288F07A36F951778D83F6ABB3D2DD
+:100120003A89FB2E71BC67C5410FFBB6F2F3D7DAF3
+:1001300057D75315C07C9ABF2653A9DB85EB2EEF0A
+:10014000D3F6A06CEA411E4E73E795F5500EFF32D0
+:100150004AE8554E9962571D64A70E30A11EA3218F
+:100160003964C3751665D5A5D2BA6898A980D71722
+:10017000B7C8AC0F302BE641A8B74A4D6FED10FE63
+:100180008CF45239A1723AA0FE166D34F2B3C471E8
+:100190009CE5FE3D34F7C86F153CF39D9CDA9DDF6E
+:1001A000AA09B79CA4F5AA34B9F1753CD7AA366957
+:1001B000DB7B71F356B853324E249363C118920B14
+:1001C000F2E10E93BF1D90D9DF7AB38F337E607B4F
+:1001D0003FEF876DEFA1FD9FB984176E0078D23D88
+:1001E000ED85C0845F4E6FFD8A7DEBDDE44F6827AF
+:1001F000E447BA1ED7A20D019E7B6DB93D1440792C
+:1002000046BD4E33ED1F9542C154D2CB4570AF462B
+:10021000794F6EDE7B88FC64B2DD1126B92113EDC7
+:10022000F17A9DD42E2E4F3C1E0AA6E0FCF16D0102
+:1002300099DC76EC0135E8C0F1980F14D434C699F6
+:10024000F77C32E97DBBBF89E550EFAF671AF39FBA
+:100250009BD8CF60105ECBBE7E3F8387ED268A6B36
+:100260002BB43305D3A0CE8401ABCB314D4E413EF0
+:10027000BAC2E0A6EB45075C413A57719B22A7E260
+:10028000B9BCC7D5209D7B2DAA41B1519C0CC87D1E
+:10029000F1BACD0C611BC6115BA6099438B98E3D2D
+:1002A000170A521CD4E35A7392B0E74997EA658A59
+:1002B0005B4EABBA7513CA13DE4E726F71753FF7A2
+:1002C0003B6E13CBFDEB74DF3B6EA4E0708DF4E569
+:1002D00093FDB4BFF612D94F43B2DB86CF25C66972
+:1002E0003D2EEAEBE872D3E558EDECE2B8BF6C5571
+:1002F00017C7BDC47DAB4DA0D6A3DC3D15AEE25AF9
+:100300005CA77D35CC9B89E33A0BD2BCEEF33FF181
+:10031000947F48F632559ED0AAD0B99CA6ABDA7528
+:10032000F5AAEF78FF5EEF6BFB57B7789D0B1CB11A
+:10033000EB8E2249C479303B4FD863FABC5EBD4F87
+:10034000EC9C6DC85B932EA886BC3519236DFCFD13
+:100350000AFBA386F154E7E386F9B764AE36DCBF47
+:10036000CDB5DE70FF8E9CDF1BC677BA5F34CCBF85
+:10037000AB6C93E1FE4CE53F0CF767C8A048E8730F
+:10038000F952C8427E3607EA99CE8556A60F422713
+:1003900053152D89E80270337D187C4C977B54B936
+:1003A00008ED266AE91C407EDFF1D6DFF3C82E3A5D
+:1003B0007E35DE99E58AE5653D4FFFD47CDCC78A52
+:1003C0007AEAC11E061409BBD5E37DAFFA4988F766
+:1003D000D1228C2778CE686332C799684A9F9024CF
+:1003E000C5E2095AA489F2B1EEB77A7C299EEBFEE8
+:1003F0006805F9D107328C70758F3753CD581A784C
+:10040000E8BA3BE781FCD8FE41132C223BDB8AF49F
+:100410004DE4A3EFDC88D915C74F01F181F6367999
+:10042000CE1488E0F5194E5042387F861D322E508A
+:100430002CBCD495370B03C48C0BA828B4E71FD36E
+:1004400095429277E0E909692772B5B87423EAEF1B
+:10045000A889F981C5526804CAA3A9418CF317A6DB
+:10046000317FF74398F5F800442CC4FF3C008ED34D
+:10047000F3C1C5F42150589FB8727201C6A7850D0B
+:1004800066CF06E4B330BD7338F967FED8C3E9120E
+:100490009E0B4B3B85F82934C13AAA6F743E6A35EE
+:1004A0003E3614291574BEC2F4D60DCFE2FE9D8DE2
+:1004B00026D88CEB9C1CFBF82310978FB77ACA6F59
+:1004C000A579DB245028AF065A6CA12D59B47FE7DB
+:1004D00000CA07FABCE59E8A1945B8EEAC22607DD9
+:1004E00043EB5F80F433D329640F53FAB30CF0B9B4
+:1004F00061BEFC9EFC33C0CF15922C6F0071A18CA5
+:10050000F7E5F1236FBE317B4D1EF313A03A6EABBE
+:10051000479DC7E7B7622CA0F3BF6C0B6DE67AABC3
+:10052000669884E7AC7CC566A2FC7F18E333DC0CDC
+:10053000F0A5DFCEF47FFC4EA65FF933991EF5BB24
+:10054000987EEDCF61BAF0023280FA3B59A4541183
+:100550003FBDF1D17B9C117C4425985DEFE87EBFC7
+:1005600052F3878286E34F25931D34C96EB2D3FCC4
+:1005700046344C3CF799E63121392B5EAEEA13C480
+:100580006741D3A77F185F42CF999D12CE3FD3D446
+:100590003580FC37F17C57E4D16215F2D0CEBB2D0B
+:1005A000AD75033DBFAD71389D10E308083B247D58
+:1005B0004A3DF1B19AEDE4574522DFDF65EB2C713E
+:1005C0003A62FC01951898676AB53C3355BE944A67
+:1005D0007E3193D61D4B767DD347B45F609FF04349
+:1005E000D4EB3C5F9C3FEDD0E4A0D3FC16AB8FFC7A
+:1005F000695BCB6777DF81729831EE36AFEC8ACDDD
+:100600007F9584E025FBBEF8EFCF66F07C276D3543
+:1006100007364D75E2BCFBEDBBDE27113CE03C3AF2
+:10062000350DC7F332A53D44E7BBB2A6A5531C80E8
+:10063000103FFF50CEE43D6462D3DD33AD544F4CE8
+:1006400026A78A8BBB15768C378638DFCF30BE2540
+:1006500073B061FE6DAE6CC3FD3B72720DF7F57D3C
+:10066000A7BB8B0DF3C85FA9DE463E58EFB0450E21
+:100670008D90C80ECE7DB194F99F5342FC47517EB8
+:10068000562C1C4E95AD7FFE590A1B8DBB53C93F9E
+:1006900013EBDA652DAFEE515CBDD7B555E0EB1B22
+:1006A000967AAF677BAB07AFB7AEC538F2078A2340
+:1006B000856FDDEB0CE239B68DBD78830BF9FBB8A5
+:1006C000A8E77A37AAD5BB897674C55E2597B09F0F
+:1006D000FD32503DA4D7BD897604F094560708FA40
+:1006E00053FD7DC627226F7D437EDF2FDEBE351A88
+:1006F0002A32E499422BE617D44FE7DF64D84C172F
+:100700002EE139743D64C7EC1F1EDEF4FEA012BE5C
+:100710001EA0BAB68AF202AE9FEC91C4BACB76BDE7
+:100720003F2823761F561E35CC8727A53D86F19A94
+:100730002CE3F899C97BE29FEF2D1E556E7CD4AA5D
+:10074000629CAE7C4EE27C95785F3FCFD4DD490A57
+:10075000C54D73B38DFBA92AA7028A83AA26CC2391
+:100760003DE4753D3ECC91A1A6A73837405B77FAB2
+:10077000EE24907FC6BA87D156E83C81FF12F9E695
+:10078000705F057C71FB647944FDD79156F74F3F4C
+:10079000E0BC8E3F839B44DF9126E26E41C34993C8
+:1007A00089F25F1F612F05CE88291D69745172007F
+:1007B000D09FAA17A7044C85787F78E7677654FD09
+:1007C00028CFA017EDA8B72F4C2643FE8952CCC3E3
+:1007D000B1677BE61CCA3F77EC4E0A9B7E063F1E44
+:1007E000AA399016960BBF7F90EC46ECA300FA470F
+:1007F000F5EF40DF57A13841FCD378A967C8E1E79E
+:1008000070DDEAFD220EE06D47623F7B7F5C3F0BAF
+:100810001B85FFDAF197EA9D2A084D73106E10468A
+:10082000FF875FCEFF67781C195CE7909FDFDCDDF8
+:10083000AF75BFAF3E28FCFE6CF3F79F509C3F8B1B
+:10084000F92FDEEF75B9E9FE5EFD82CC7EA95F3F30
+:10085000D32CDF1AEA41CE65BA5F296EF6D75AA7C4
+:10086000D8B776E2F9BB29CFD5B6A086A4EEFBE8CF
+:10087000B47A9D0CAEB87DB6EDB42D0A39627C44D5
+:10088000F5FCDAF27DFAE43C415753FE853A2DFE41
+:1008900088BA06F3AA2583F2EA4CC9BD05C9C196F8
+:1008A00081E524BF8312845D1E5EE25E3B9EEF1EE7
+:1008B000B11C5D77507D06993966DAE76E4DAFF76A
+:1008C00068F8D2AC96592328DE7FD6B0E0A042511A
+:1008D000CE93CDFBFD1A025C1F1E4CF30D5D4175DE
+:1008E0006850D8F9C1B4CE76C2A30E4E4C9682128F
+:1008F000AFBF26BEFE3B68F10DAD61BE345C4A1948
+:100900002D5F4EFE09FDB21617519F0149F477EC99
+:1009100007E641CF30CEB018427B14DCB7CA1DE6E3
+:100920003A7529085C20B1BEAF9AF0AD95F24362EA
+:100930003F3AB969D721A9A0071C23C16EAF855BD7
+:1009400024F6C1BDE10F3FA6FBB678E2F0C3C47A3E
+:10095000FD4A5DAAD7555B92439BF13CEF4EFCB735
+:10096000334B71BC724BB293FAEED3AFD802149FE3
+:100970004F6FB68524BC7F3ABDB38DFA90D3DBF3BD
+:10098000DDB802549A5CFFF906E5F93F59D82E000C
+:10099000DCC23FAED8E9634728DED56E499180EAD4
+:1009A0006B55DCD77B40F9F514AE1316EF1814B273
+:1009B00049B13C43FEE1C2D2E2D4CB490A15FDA7BE
+:1009C000F7DDD397F0AB76D39BC3180F939F3CF220
+:1009D000383EB7F4B5140FD5139007ACB7459B4715
+:1009E0006DA2FAF8258BBA97F8AF78FDCE8159B48D
+:1009F000FEA7FD81F88936EF1840F551AC6EEFB9CE
+:100A0000DE3BDB9CDD17F26272D2F1C4757F5CEDD8
+:100A100023BD274B2EBE6E861A6530D945D34CA018
+:100A2000753DB2A4905F76AE4FE63A35D1EE8E7842
+:100A3000449FB24CC71FFA813D93FC47059643740F
+:100A40007DEEE60D28A71F3CE95ABEEE1C79777EA5
+:100A5000BC7DB655BD43F6B9D1C6B8487B92B16EE0
+:100A6000D0E9FF7AD2789F4AFB39030E51B5EAA24A
+:100A7000719C87FD1E3EEF09BA8A1F45BA42937FDB
+:100A8000D7685F87079F5F52FFFBB73E60B96CFC7A
+:100A9000C72F68DF7D0E81C77C20E497D80F54DA1A
+:100AA00005EE01B089CFAB5F3FF9F2E70564872718
+:100AB0001B7347921E17C8AD275E423ECFA4B41EDB
+:100AC0007902E9F67D9FB05E12CF9B88DFB44B12AE
+:100AD000F3BB8CF8C0EBF77A7D72717F7667EEE33B
+:100AE000166CC867F94D95F3FA921EA3A77BE957D8
+:100AF000B473EAEBEBE7D3D7D7E7398B85BE3ED4A7
+:100B0000F0F70E6BEB19D26FC75BB912E18357AEEA
+:100B1000A7B716A4C5D9CB2F85CBDFA7E123874C78
+:100B2000AB7F63457B6CAF7FD6A2C6C7BD9F88C72E
+:100B30005FA907157039078854C2790B9933E37898
+:100B4000A23E2667C0F104ED78129D07FD72A24611
+:100B500061899AC9783BAD873409423C0E4E76BB19
+:100B6000884E927C8C7BE87DC334A819427C98EC3B
+:100B700011C609D7103E8975CBACB4B57766E17E56
+:100B80006BFAC35AAA67D658845F04E627733FA757
+:100B9000CB49CF33E0CC33E497354E7099719DD972
+:100BA0006658674917F36E44391FDCB7E07DC25DB4
+:100BB0003F37D7F4A77D0F3B9ECB974C54E7855228
+:100BC000A867FCE2933F79FF8673BF046522D515C1
+:100BD000F7EEB573DC4FC4271682CAE34A8858CEB5
+:100BE000E1735F8DFD71CB6E88F1F5D5B81F1AA941
+:100BF0004FB83FED292F3D1F28871CCA4BE7935262
+:100C00000B889F5576411FEB93BA99E869A723405B
+:100C1000B8ECF9A46121CAA72F49EA8364CFF81C74
+:100C2000F7B18123C921CA778FC96A15E3D0695604
+:100C300090707EB4BF26970E60B9442DDAFCEF5C4D
+:100C40003C2EA9F0304E09E75D1C97C727E49D9222
+:100C50005C93E8CF2E8BF9133BCD86BC5352A8E1B1
+:100C6000397F77719D3AE982F9AA79E952B1E8773B
+:100C70004BFA996A7AAA179FD5EE07212C0B9C474D
+:100C8000D40BE3AFD89722931EABB47115E535B4FE
+:100C9000AB68AA3D2023BFE39B859D8D37877711E5
+:100CA000C5280BABA8BE68C2BCA79F03E30A64E6D5
+:100CB000B23D8CD3ED14D79A8BF3D64A35DCC7D826
+:100CC000A9AE41BA416AE573FC0A3A992A5A3E2F05
+:100CD0000737D329E0638A76CAF456A8637A3BD4EF
+:100CE000339D0EAD22FF8F0E0739AFC1934EEE0735
+:100CF0006FAB3451DD51F2EB9EFB87462D9EF42EF7
+:100D00000774BCD29F2E876980FE97DD833C86E402
+:100D1000701C499447A29F4E8488CC7E4A01229B36
+:100D2000F00317FB6B05283C9E7A9D72288BA86602
+:100D3000C66F12E551D1B35DECD4ECA2966CAD7FD9
+:100D40004C4F5DC52E1EEBFA42FFCAA43A34518FB8
+:100D5000FAF592E4F22E1786E22F761C9F63C6BC4A
+:100D600054525CBE221BC7EDC5DFCF31633E2B1949
+:100D70005FBE63388ECFECF8418C0BCB8B2D6EECC5
+:100D800062569F9F3305E7ABE49F8544D10F299EB0
+:100D9000A9A23F5EA9D531EAEADFB89DE82FEA5063
+:100DA000879BF8B463B19F847294B3C57BC761B766
+:100DB00086775B70DE718B7A90FC77B93D9CEA4256
+:100DC000F9AF5C3D752085CEA7AD62BECD26705AC9
+:100DD0009D3FBC1E48C2F1F6EDB92BA4E1D73E07FA
+:100DE000AEFF35ADAFAE1E1120FF551B25B7D06C41
+:100DF000F9C0D928C3F6560B106EAAEFF7D468F5E0
+:100E000014E747979BE3F760ADCE69DF9E9B4B7A73
+:100E1000EA2A163818646415931C8F8EF675D1FC77
+:100E2000688AB0B72ECAE5DEDEE9E012E53B9A9F9C
+:100E3000783DFA0D1E009F3797A8E7E97E75F225E9
+:100E4000CEFB678A3E5D1BC98AD9AD844A9B8BFC69
+:100E500007150859393F4C705EA95329DE2DC4751A
+:100E6000501E253E3548216ECCDCCE528AABB8AE42
+:100E7000A904F7A9B6468615E173CFDD73C42AEC41
+:100E80006E88B03B2D2EB5ECDCFFC46031F4419C84
+:100E90009F55EFBCF8C39728BFEAB30E374D8FF9C3
+:100EA000D78B2BB8DF0487218EE87E37AEC9C6F515
+:100EB000F6F8E6510B69DEC44FDBB289AF496D111C
+:100EC0007E8F166DF97CB03887DE879C977E4E3E0C
+:100ED0003EA9E58993769117E8BD30F77B8DE2BD99
+:100EE00070AD8673D6B648A100C71FD13F2FD2F888
+:100EF0005BBEBF710FE1278B363E349DED2824FA8F
+:100F00000A17FE525C587248F4CD4BB71AFB8D6A33
+:100F1000EA9B693E84AD640FCBEB13EE6FACE0BE91
+:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B
+:100F3000E4B97DD51EE261625F5C05CA8412AE7BB6
+:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A
+:100F500052DB9BE4E460B958B99FA87D7985DB49F1
+:100F600063CD6F3799A8A7C689EF7D04F1CFE97EDD
+:100F7000BC789DC47D076CECC73658F89A4D217E2D
+:100F80000B5F1BC87D08F64B5C1F6E7ACDB68EC614
+:100F9000C1DFF509C885844377DE40384C3009EB62
+:100FA0004D81E783E4611C867191474BB4B8AFD59E
+:100FB00001102E32F4F3412DFFD7A68C1C889D73AF
+:100FC0006CDEBE4186FE24A8D5DB25744EAA1BB775
+:100FD000DE20EE27093E767DFC0FC954F7369A7D58
+:100FE000C9846B9F3D309CFB98DEE4EEC53404570A
+:100FF000794FE9FD7C7AF6D5F456F28259C84BB3A5
+:10100000DBB7FD0A7C6D89E945E76FAAFC4685954B
+:10101000709187C1493849EDFE578376EA0BD703B3
+:1010200023106741D8F3D953267EEF5E0A39FF3A81
+:1010300001C7DE536677089F6FD0E222BD7F76C579
+:10104000D9994DC37F935C7DC015D74727E7A41B73
+:10105000C629EE1B0CCFF52D1B6EB88FF2DE4CEBC4
+:10106000434069CD2B8DD5BD69CA68C3734FA74E68
+:10107000DBC77EDFFA08E352FD6EF518CF2337CBCE
+:10108000140FE09CA897CAF097FC6D0C0482A48F03
+:1010900071EDC63AAA2C52C77D63D201B30107B0E5
+:1010A0005D0397DA44FE457172080C11712351DE1D
+:1010B000C6EF2F6AF7CB5CEFD50EC54235AB27796B
+:1010C000DF6490B7EE8FBADCFBFB8C721F38DB2835
+:1010D000EF41AA51DE831719E53DB4C628EF1B572F
+:1010E00019E59A1530CA317BDD38C3FC1175E586E8
+:1010F000F1CD2FDC6E983F2A74B7619CBBF53EC3DF
+:10110000FCFCFA0586FB854D4BAE4BFF45E15AC30F
+:10111000BC44FD17EFFBED55F51FC05FA17F607D5F
+:1011200094A13EC2AEFF3F3B38A6C759DD0EAE3399
+:10113000CEBE4D3ECB78C2844880ECA02C99ED64A5
+:1011400046B2883B1FEE3B7B40C1F147AE624B2667
+:10115000D5595AFDE0D3E290DECF24F68D7795493C
+:1011600009EFFB930CEFFBAFF55D9DB7356C1817DE
+:101170001D00FE6EC673C8FD2E51EF7185E1AED223
+:101180005335EF121D7B8ED376B77E55FF3E2FB1C0
+:10119000DF826507F8BDE25CFDBD0C394569777CEF
+:1011A00052EFC7F43E37B1FFD5FBDEEE7D9AA86360
+:1011B000BAF71BEE4C33D7D12AD7D57B259571CE04
+:1011C0004DA3D4C15E2F3501D8279BA84F8E04852F
+:1011D0003015A0F7D051FA9F8A90C0B3F7111E1FA7
+:1011E0004D03C6CF15A9EEBE401E1FDF192915F00D
+:1011F00011FD147BD5115ED4EB31C9B9B698F089D5
+:1012000071DF0EA37A24C72BEA3C9B8C92C2BC34BC
+:1012100070AE0274FDC7746594D71BC34B7AB39B41
+:10122000C4EF931AFC61A666A79BBF5F4AC417234D
+:101230002617D7A781DF4AFCDDCFB774B8B1B13A22
+:10124000E6EC3A0BD731A0F5F30F68F2D7718FB9FE
+:101250001A3FC770894598971F68DACB7A599AD98F
+:10126000AEE125355C8F3F34C4E1E1EFE19462B734
+:10127000C0C9741C64B0FC53EAAE6BF1BF34F3B464
+:1012800001878237FA5DD7FBF218DF62FD63EB0559
+:101290009E796CFD50C6CF63EB9F613CEA819A8FCB
+:1012A0000DFE316FD561833FCC0F1C35DC8F64742C
+:1012B0005A087F8CBC3568DAFD28BF8E465B29E969
+:1012C00003EDE011D2ABBE7E647DEE14DAF7DA7C7A
+:1012D0007ECBE768F3B7B27E753E8FF80FF138E248
+:1012E0008F247C9F26F8D4710E9D5A77438E99DE09
+:1012F000274A7DDC842BF7867FE87E662A1DCEEBAD
+:101300009C37B94E089CA8660CD57F6D930794D383
+:10131000B9DB865ACD828E14E3416576319E762BF9
+:10132000D1A8C5B18E709136497C4F3457525E9921
+:101330008FFB3E314A7D9AFCA17A496701F95F75BE
+:1013400061E44109D7EFEAAF6E20F948D85E0C4A54
+:10135000673EF8BBB353A6408184AEB2C7FBF57DB0
+:10136000D4279EEA13384315CACEC623626C15FEF5
+:10137000F8A1771FFBDF715C8CF80CFC5912F89414
+:1013800023629D89EB64F4579FA77DE97B327ABF86
+:1013900047D7C93E75BC346A11756254AB175FF606
+:1013A0008A7AF69504DA44352EE18F44395E3F336C
+:1013B00092F0F4B31B6D40F52DEEAF984A62DFAFAB
+:1013C0000C405EA88E7DDF2AFA4CCF5F6C618A5399
+:1013D0003AAEFAA6378BD7CBC8167869C63F63DC1E
+:1013E000223F8CB40E9B991277DE03C0387607E15A
+:1013F000D17138F69B5ED1AFC3C322EE75AC1FCC62
+:1014000078FBF2FDC78E50FCBAD7AB36925C1798CA
+:101410005CA5FC7D56EA2EC6CDF67A5DBC2F9E9764
+:10142000F9C538B486F4B4DC1E619CED5AB87A6F05
+:10143000FC772C6C7D3E8F71645701D98DBE2F9E39
+:1014400063AF370EFFD6CF115BE7EA7EA0E3C3FAA6
+:10145000F8E4CB4F8FD4F0FD79BE1EF2EB114D2E88
+:101460006D969EF1F88B5EF11EAF9B7E6E0620FCA2
+:10147000DFD607733FD26FBD82FF8E39C80FE31BE3
+:101480004A11E977F9DD0E37C9595F1FD751DFBC23
+:10149000CA3E5DA37DDF10FF4B6A047EAFDF8F4A3B
+:1014A00042AF81F5024F5DBEF3F091277097C5AF53
+:1014B000E717533ED09F4F9433CA77247F7F278B03
+:1014C000F75F28DFB3B47E226EFF73E51A1D2ADEB4
+:1014D000D346375D1C46DFA72DA7EFE10AC83E04BF
+:1014E000FE050D465C0BE515207CA3FB7B2DE0F78C
+:1014F00063362D9FD8F4E787980DCFD7A7F8924A87
+:10150000F1FC6F697103E7874CF43DB7169F1AB47D
+:10151000BE3B117F696815B86943A695EB68AA7F41
+:10152000E8BE5EFFACFC58E0A62BB3449D4DE7241B
+:101530003D4B87F670BD7005179730DFA31CD3AD08
+:10154000EA9052F2277505E733F946D433BD0FF917
+:10155000EBED1A8E20F2A357CB875E5A87CE95D734
+:1015600097F36489B62FF6178CDF8D0555AB1F34C2
+:10157000FC6DFD1E03FEF07FDDF5EC49303100000F
+:1015800000000000000000001F8B080000000000A9
+:10159000000BFB51CFC0F0030947B0A3F20FA0F13D
+:1015A00067B2A1F2D3B850F9875950F9FE68FAD161
+:1015B000713B13030323137E35F8B0083303830C08
+:1015C00010AB00B10E33F9E680B0BE2803438104AE
+:1015D00003033B90FE23CEC0E00E641702B11790C8
+:1015E000DF02C45381581C287E16484B8931303C99
+:1015F0001185E8B300B23F8B9167A7192F656E1E66
+:10160000C594611359543EAF1A03839B3A03439F19
+:101610000684AF8D24BF1428C6A70661EF976760C4
+:10162000D004F29564B19B7B0028AF0594DFA681BE
+:10163000DFFECD3AA87C0733547E269A7CA30B2A82
+:101640005FC30D95AFE30EA101C062BAC4D8030019
+:1016500000000000000000001F8B080000000000D8
+:10166000000BCD7D0B7C54D599F8B98F99B933997E
+:1016700099DC241398BCE02604081A7012C243C4F3
+:10168000701322468D6182687197BA23AD36A240ED
+:1016900040D6C647CDE41D5E1AC4EE22B874E213EC
+:1016A00094D6D462FFB4AB7402B8D2966A54ACB488
+:1016B000B5DD485D6BFD2BBFA0A2D4D2B2E7FBCE57
+:1016C000B9997B6F2601B4DD5FE3E3E6DC7B1EDFC7
+:1016D000F9CEF73EDF39718A0EA2CE23E40CFCD09E
+:1016E000E71B84FE64269E84741332039E03727883
+:1016F0002A3CA3FC3D7B0696F60AA4008BFD6426DB
+:10170000217984FDE43576AC16A7113296847E3AB1
+:10171000399F96076EAC217E5A7EEB8A3FC2B36337
+:101720007165F5651A21594B7A5FBD9C3E03E198BE
+:10173000102926640B1109C986FE0AA3155E42DA38
+:10174000A0B339848C8966E9D16228E8B440C8BF67
+:101750002A7C20226A322DFBF0D7C43C8C27214EF4
+:10176000122FC28AC219D7F0F6F6FAC6D307ED8C4B
+:101770003AF9F0FF3504E677B676642D1B2F4AFF61
+:101780003943F19293181FFBC9AA379509E0C7FAAC
+:101790005D1FC2FBEAFF93F1B249A95B2BA3F3AD36
+:1017A00011D518D427BD69322D076E93495CA0DF8F
+:1017B000CBBA058776F675E920A4BAD78BF815EA77
+:1017C0007C09F8AE2502CE67DC5DEFF474060839BB
+:1017D000B9D41B42FA5009C9481F3E9F6F371112F6
+:1017E0007799CA8B2B85088E17FA69216D1F5D2C9E
+:1017F000861E07786A16A5C17BA3DE37F938C3E9D0
+:10180000836832C5A3CCE943AE1175F7B42F4F1FDF
+:10181000F217A48FCCB5A676E4FCD70BF13EE3DC3F
+:10182000E9E3CB8E67ACEB70BE6A4638C6DD55E89F
+:101830002674FD1FA85E941A49526FE4752D457EEB
+:101840000FD4103D96A4DD3A584F9C67D4226FF018
+:1018500049D7471A5ADEDB2DEB258D9DB9A46714B5
+:101860007C4801EB7C8D7E9D8D92F64E062DCAAA9A
+:1018700008FDC9BCBF0E75599400DD026D537C484C
+:10188000DD257142F9830449E8710E8148CB4E553C
+:101890008FAD17A014C37531E0530A45CB788E5C29
+:1018A0008F653DC892A86086DFD9E844386460132C
+:1018B0002EEFC228DC18DC30C4990950BEDBB2FE22
+:1018C000B297C4DD54AEAE2B2C25E67530E854102B
+:1018D0000C3ABDFBDCE48A7DBCC55638CFB99D57B8
+:1018E000D6DE35DA148CD64E26EF1A78A2C87B1DC8
+:1018F0007E31AD7BA783EC152E22A435B7230A6F6A
+:101900003BE17F17237D82D0229DB9A52AD013D930
+:1019100029C800A7DB208F603AD6EB211AD2535496
+:10192000B883403DC91B463C19DF47868BD35D54C5
+:10193000EF2BA4FD5ECDBBBD9AEB3352E67867C0BA
+:1019400080BB00E79128D3797C7827FD1FA58F689D
+:1019500089107B5C18FEBD06F421954735F0DE2426
+:101960004F5C82559ED5F06F079E7B73D2744A8F71
+:10197000FD218980B86A79CEA557D1FE5FBD548814
+:10198000B9040E2FAD5FCBE13CAC67E4017DF657A7
+:10199000B9907E6B2FFF2C00E47B7CEFEB72327EE4
+:1019A000AD9DEB48C041FF5B659E1FFD6F0C8C81B8
+:1019B0007C59857464C0B5A2544238FAE70A3118DC
+:1019C000E7E06FFF70DF2514CEC36542C8A521BCD8
+:1019D0003E42C7EBD73F0E8C26278831BE4654C007
+:1019E000A77DFCA1F550424B802FEB55A7B69E8EEC
+:1019F00077AB143A047A8C8C65FAA15E9D5405EBA2
+:101A000023098C3EE60B59D8AED5DB3206D75D5A9A
+:101A10009A545ED55345A196C2F78D93468533E619
+:101A2000181C30D175E35BF9F71D34C13955F00549
+:101A3000DE4DA1BFCC22B3609D3FF22E4A8D939123
+:101A4000FB7BBF4969961D847CD6A4DD77D031FC31
+:101A5000FBAD1269E82D1EFEFE4A41E1F8883AC14D
+:101A60003E33E63D344F6F00E9FB5610BF94D46F10
+:101A7000DDE96E96CDF2C7368F21FC7EC1764A60D5
+:101A80004D345B037E8B2C14A01F99FE3333C18F22
+:101A9000B7EEAE637C6783B73DF0B781F76C7CFC33
+:101AA00091B7A503ECD55607A397B64C31D442861F
+:101AB000D38BB11E061ECF753D360A6EE40F838EA2
+:101AC000EAC5A5A3AEFBD9E8E80EA0A30BFFFE7400
+:101AD000B405E868C63F241D6DFD47A4A344F97210
+:101AE000B41716F2BEFA067EFF20C8E75FEA12CAF4
+:101AF000BD5FCE65F2FF97112617FB4964D30CD06A
+:101B00000747249453FD7AAB0FE1A52631CC03FDA2
+:101B10002E4A7FAF83BD3499CAF526059F74F679A6
+:101B20008BE8F7572FFB2C17F4D7AB746DC1FE264B
+:101B30006450D769FB5786CAD40087B29B95079B30
+:101B40004F45C13EEF1758F927CDA7F4288EB7B1FE
+:101B5000E3728ACF85F02B8563F15C418F25A18BE1
+:101B60009F094E86972A62D1AB745D7E26507A51CA
+:101B7000C2ABD1AE26244CD03F2CA47682C9BE681D
+:101B800004050672B9CA85FACFDEFF2BDC2EB4DB62
+:101B9000718BE79638405FB8C227E401FA5C1816EB
+:101BA000B00CF8574D708BBAA0831E08CF753D025C
+:101BB000FA2F2C13879A845F17EA2E8BDD7582EB40
+:101BC000318A9725CC6F51F3EAA626EA9F30F4AF0D
+:101BD0006D3E23D185310FA37CCDDC13073360DE4E
+:101BE000D54268223454D4BC1B7CE6FE530CFBC6A1
+:101BF0000778FBE5926B52191D4450AF1AF4F4D3E9
+:101C0000B7BFE180F993C51948978B6B248B3DB919
+:101C1000A82AC552BE6EEE35A3DAE12462C28389DA
+:101C2000EEFD3904E994FC37B553289D462B072374
+:101C300068B71C13B4565A4E2D6F1C0FFDDE2DA62F
+:101C4000637DA1BC71F200DA5B0B90FE53789FA913
+:101C5000CE863F14805C9D28924734B04747F70BEF
+:101C6000DA399D1B6547201215E87A6A51B5541A76
+:101C700005DF315DAC4EE6374C10D9BAB54717A930
+:101C80008500D041ABDC48AB6A40FBCFA84FE97878
+:101C9000829809E346F1FD101D77D179D1761E6651
+:101CA0008B90D40B16A59251E6D1665B7F2AFEF588
+:101CB0006472F6560E1FD9CBFA3764526A3AED3F7A
+:101CC000497DE3D9C9FB3F1512493FC0298715E477
+:101CD00087A24A62EE87E8255876F2A22B1856F2C0
+:101CE000293E5DC5224C83B4173FA2CB1AE0218A5E
+:101CF000EBBD81AE6DAE892F37FC45423FFF56B13B
+:101D0000A019E4C686BE5B8846F1E109C60896A71D
+:101D1000DEAC009E365027AB1FC6977B09C0919260
+:101D20004B7FA7E3A4A824A6D1FE64AD372ED2B280
+:101D30005C4D423AFDE453438287CA89FDC1826605
+:101D400099BE6F5B4A503E12901E26FA690BBEA6E2
+:101D50004B403F4B4808006E0B2CC37976142FEB99
+:101D6000CAA7EF4FD6C8183F20A729BC865F4FFDF2
+:101D70000C4F11D161BC0D5924E6453B5847FC3A44
+:101D800055B67EDAD642129F4EBFA7CDEC83F1A3A3
+:101D9000DF228C2F09936B32972744A6F407E33791
+:101DA000AAA1F549E84F21915BC419A67556C3E86D
+:101DB000C7DAF196EA2457027EDB4A281F24917B7A
+:101DC000778822D2412CB46861419271EE16359425
+:101DD0004F46593BE544F847AA9FA82793780674D5
+:101DE000AD0B8017120EE0FCD2C9D08F0EE50C3E71
+:101DF000DF31A401EB056777F701BF65EBBD158007
+:101E00008B6FFBAE7B15D78D3CAC821D4BA12D3C5F
+:101E100093919017A073607E1F8544F43B7C625CB5
+:101E2000D569073E777F109D5F8D605C2E159A50B7
+:101E300080D737296D6097F8494880EFBE901C35F0
+:101E4000DBF5A984962DF11472A4702661221FBFC0
+:101E5000AB7DC03A6A51C34500CC16BFFE5FE03788
+:101E60006DF445D00FFBCCED9F06837DD3E37F045B
+:101E70009E9FB9C7C5D03F0B317F4BA1FF80BC4BA4
+:101E80009D2D5BFC9B34DD5ACEB0F9610B242FCE27
+:101E900033ED6AC2FD2BBD66E298045C14A23AA041
+:101EA00097CD553201FFDFEB65F018F06548F7CCB0
+:101EB00042FD18928F011C142D08C749723A0E4B2F
+:101EC000EC2F22183FA5701DB3C175CC06D7313356
+:101ED0005C8D0A9BAFDD5E8C5692A2060ADC0B225B
+:101EE000F73FA8DD0476E349F2815E0D8413BE124C
+:101EF000F5AC5F656DBC4A3F062B54A2221DD8EDA0
+:101F000046BA4E1F59FCAFD9BCAC1101E641E1B451
+:101F10007E27B9482F5896C8505C78D96C035FDA91
+:101F2000577E43F9EF96430E02FC45F95882EF0EB7
+:101F3000FEF5161E1F5E06FE35C5DFD749D80FF029
+:101F40007D48448C437D485EF34F37C9C9E322B7CF
+:101F50004F6089CD7C4C424190E3B2B7A35FF2233E
+:101F60001A0C7A13CEE03A86989CF732BA8B12A5F7
+:101F700019F56117F33F8D78EA4DDD567FF81B5B4D
+:101F8000ADE59BC9A231102FBDF9410789D17E6F04
+:101F900031FBF7749DDE105584EF1BA4A103EC9276
+:101FA0004E07B33796A94486F8E78AFFF71F336FC9
+:101FB000A4F33909F26006D8EF147C931E591E88E9
+:101FC00039F5E2E1F36B1542B5970823CFAFD3D1D2
+:101FD0005F0BFE77749303ED4C628F83EE91300EAE
+:101FE0006A6A87F07EADCB3ABFB3CDDF3E5F421E5B
+:101FF000C0F92EDF7923DAE723CDC7B933B9BDE9BC
+:1020000095044BDCC7E06B83DEEDFC5D26692CAEEE
+:1020100043D520DA2BBF4B89B5E2FA36CC82F53DA9
+:102020005BFB8BA17DE6176F5FFE25C79F7F96F652
+:102030002B94C105B0DEEB02DD61E04F238EB5923B
+:1020400044F51CFAABE3F9D55130DD86EA05CFB192
+:102050005E2EAD279D43BDC2D1FB3BCEED92977660
+:102060003FEA043BF5C3A7DEAE053BE0D6FF94880C
+:1020700042E9E1F86E1F89A3BD1273827DB39CD241
+:102080005D0CCBF199D798EC614AD1B80EB73EE31D
+:10209000433B62F9B3AE580D6DBFFC87BF9F462826
+:1020A0001E8EB70CFE570ED0F353028BBB4607A60D
+:1020B0005D43DF2F97C9BF8493D0D18D12E3A70F63
+:1020C0007E94B204EC446167DF0DD86FEF571C2E8D
+:1020D000933E5E2239705C5A0FFD88E82E213651FE
+:1020E00060F099FD0123DEFDC12E81C1B7D71173C8
+:1020F000037C3B7B9C115A6FD5CE1348D7F39FF9D5
+:10210000AE1FF0B06AAFD54E5FB5538ABBA6E1F300
+:102110006D7882061566023E193FAFDCB302F5C644
+:10212000CADE0D27809F57ED7558E43FC54B280E3A
+:10213000787D530AD540F9074FFA358AAAF7FB1F75
+:10214000F7035E69BF373A295D2D9C6D6D07FD9FD2
+:102150004A1FDE1FF50CD16F5ED5BB8E8DB7E7EA47
+:102160003F80BC5D45989E32F8F97DF8256BB89E9E
+:10217000592759E35B27C9E199B80FB83323A9FF61
+:102180006CE81583AF6FFDEEC91D513AFE07CFFE17
+:10219000FF1D513A8FDBFEFAF18EBBE9FCC83EB75A
+:1021A0000AF26AD5536FF88909FF8F496C3FE0F84E
+:1021B000AE279FD846F9E4F8AF5C68071E7FE10FB1
+:1021C000E3343AFFE3DFFFD318B053D7BE70D958DA
+:1021D000C0C7DAE7E68F1DCD5E07BA8DB9CCEB1B21
+:1021E000C3FEB5BD026C8210F23C7FDAD6E9C01E98
+:1021F000290E21820F8FBA622E8A9F55F45D6329C2
+:10220000ACDB0AD45750BE87E27BE5EECE13D2B4E6
+:1022100064788FE6884178C6734810D6FD9A859712
+:1022200096C1D311D2804EC820EA097BBB5547E83E
+:10223000FA5E34F27A527BC209F85FB57B1D1BB798
+:1022400097AEA77FF87A7E08BF5C3C7C3D0F48D6EE
+:1022500038D34972DB77B6C1C73D19B8FE23ADE765
+:102260008AE7AE1DD5BF33E4C3D9F05C2F30B8EE9A
+:1022700097F4D725E0C7679F7E625B80AD730D45FD
+:10228000CCF1EF9E1C079BBCEF39066F003939F883
+:10229000824B05BB7AF90B6F22DF1D7FEE55A786B7
+:1022A000FBD3C42B503D799C0CFDF483DE5C29B03C
+:1022B000C2AAC77C71973FB15E2B6375D59A1FDFA9
+:1022C000BF8DEF638C1F56C6FA160B49D6CF2B175E
+:1022D00030FD14CB44BCACD0FA9DAAD7BAAEC26CC8
+:1022E00058CFB71700FD8DB49EC6FC5598FF2CD370
+:1022F000BA3EC6F878247E3DDEE39285D4E1EB7CDD
+:102300009CDB15AB62C29BC9D69D901616DF1B21C4
+:10231000EE6D3CED74E194AD7C6EB437E67F363EF5
+:102320003FFBBCCE0F6F27B9BEB6E3EF83D3C9F531
+:1023300040812C70BDD55D9D6DD2776E07D563F958
+:102340006077364473F213F076F44A28DF3FD829D9
+:10235000A1BD6F97132B47F0EB43C6387BFBA681DB
+:102360003CFB60FF8F383D327A5FB9FB6D6794EBC1
+:102370008598592F407F49D6630EEF6FD5F3C9FB7F
+:102380005BB5FB44D2FEDE97F5AF00FCEFF73B48B0
+:102390009476F17EAF94344E52283B2C7656876F5C
+:1023A000E6D154DA4EF27B3498776B8BFE6614ECF0
+:1023B00091D71C04ED4739F49E8B7E6FF57970BF81
+:1023C000A5D57F33D14CFABBCD86273918463F5A65
+:1023D0000E84CBD85E68CCE2CF3A54D1023791A3B9
+:1023E000B9B0CFF972FE1F64E817E2699A292EF49A
+:1023F0008A4CDA219EF68A2E849A4992B896ADFFCD
+:10240000F05C8968663AD3C78BE6F8A27FFF9D1817
+:10241000D768240D718837915CD2FBB8A9DF879B00
+:102420003416770D8F17CDF13F574383EEA270E43A
+:10243000AE550BC07F1B69FCBC06EBBEAF31FE1A6C
+:102440001E8F203B9F7AEA295A1E0FDF44A0C3B09B
+:102450008E709C66FBCAF3B93C7C89DBCFFB0572AE
+:1024600010ECB0EA7B2232C83B217823C64517E442
+:10247000DE282F33D1E382E0892CD0ABDFF98BB497
+:1024800024199DEEE574D5FCAD27B2A0FD36F757B3
+:102490007299331B46F87278BCEB60E6E55E88EF14
+:1024A000F5DDB2E0F0243ADF6C552210AFC92615F5
+:1024B000DE120A67CE1129E44EB20EC673078FEB07
+:1024C0003DD2A4A2FC7FAC2988E527385E7736157B
+:1024D000E1F3A9A6107EDFDD341BCBBD4DD5F87C22
+:1024E000B6298CEFFD77FDB8CF0978B997F442BCD7
+:1024F000664FD312FCFEC3A6083E1FE7F3590078CF
+:10250000F15AE68FF198BD6DF35A201E63E0D18E2B
+:10251000F779247AD085FBF9820678BF5366F2C535
+:102520008EDF71AE5E01E44BE36D04EDD71D3C6EB2
+:102530006CCCF72199D99B7B383C3F7447BE27C3AD
+:102540007E53756131DA45241C02F9BD4308A79614
+:10255000D02A2F66CE0A9AE570B62FB24736ED2BF9
+:102560008CEB62F19E6D329357E3B5137D69140FC6
+:10257000D5B98206E10463BEFB2BB45C9093FB05E6
+:1025800001D7BB3A57224526BA37FAFB0F59E4FB6D
+:102590001BC9E576828E993C48BF422E02BFF624C5
+:1025A000F18424CAEFFBB2C81E42ED8F7D40972014
+:1025B000177E9B827162C3BFD9C8D73B1D8802F2C8
+:1025C00025DEF2C540FE8CE4F774F0FA1F71B856B0
+:1025D000C8E1D765DC57E6F15712C73826A41C01BD
+:1025E0003D6E732FBDBF8A3EEF9BF3FE51880F7E79
+:1025F000F89C5B03B836951DF39BF148EAE50FCCD8
+:10260000FBF143F2E6540EC6C5FE8744DE96CD725A
+:102610002830E884F6FB046D33EC5F47DF9090FFD1
+:10262000F609B12918C79209FA05FB6E09627E877F
+:10263000D1CE17B2F277BA7B60FB2A9877BD3314FC
+:102640004DC217BF4ED12CFB46AEA0B57D1074E62F
+:102650000C56D6287D96F07987645D02386690081E
+:102660003E67110D9F598EC8E7308FE9A4370BCA1A
+:102670002D29E32E61FB077F37BC298E7F40BC19D3
+:10268000F41A9C53847090BBC4D0440DBD490B9D7B
+:102690002F74081CBF0ACAF3ECA1FDA98697F202A9
+:1026A000D80D8B93A8292807B3DD0C7F8D03273025
+:1026B000BE1B1C472C71F7F67A11F960DB5B6C5F6F
+:1026C000EF647DC1E649B47E05D1EEAFCA1F3E0F6F
+:1026D000833FB629E1D464FB53C6D3E00BA3BC7996
+:1026E000FC0D04E4D0BF8FBF01F38EB2DF726BE04C
+:1026F0007754FC6E5733C8C5F6B7597EC5514F6441
+:10270000AE634642CEB4DFD2301EFC20B72F5C0E43
+:10271000EFC3B9B1EB41DE9DAC5EEBC2A97B59DEE4
+:102720004BE33DDAE6C9DAC8EBB3A371F4FD1B63F2
+:102730005E3B605EA3EC5F18F332D6EB64F5E2C15A
+:102740009B35903385A99124ED86E4C9158B471DEF
+:102750007F07D72B74FE4BCDF439AE51C5FC16A3C1
+:10276000BD315F7B7BFB7C13FBC0E79617D4EB206E
+:102770001940EFDFFFF3B81FBC82A2312C819EA667
+:10278000FCB912E099491AB04CE4DE2CB06F0C7A17
+:10279000DED6F14416EA0539968FF95DE7385E3BDF
+:1027A00009872B80DF4262C86CAF18CFD6213A8FE1
+:1027B000635CD5C5E58098724F30199E87FACFB516
+:1027C000F2FF4642989C8F2B28E72150A8D272FE38
+:1027D0002152BA9EF6570F49A1749C0A99C543A687
+:1027E0001FD27A24165795EA7C263CF2FD0623BEBA
+:1027F000DB4EEE21AA067E45491F5437F8F480339C
+:10280000F2A003F2F0821AE67B3A021181EDC7B121
+:10281000FDA1226E975C262D55C02E692461E5022C
+:10282000E0DB23126179788CAF5DC63E18E7631751
+:10283000E763CAC1589EC4BF3FCFE96B2FD8276852
+:102840004F303ADAC3ED93AAC1C1033EDAAEA8BF56
+:10285000BB12A6F32CD82B2EB04F42F8FD7B60AFF5
+:10286000D0F281B47FBFF2028A979DBA18025CEF62
+:102870006ED2193F34D5E3F74612F5AC06B9F4B081
+:10288000A8029C9D0FB7487E5ADEA50818BF78B8ED
+:10289000A901EBFB4F7BE2E06FEE52E202D8232767
+:1028A00043241405B8A97B04F39AC4E751F14E3FC1
+:1028B0006E973F11FBE8F7F7D37A5B667B709FCC8E
+:1028C000E0AF498D83EA95C0578F1FD35603FC3381
+:1028D000D6E8507F63A800F7299EA4F88275DAB97C
+:1028E000F5A3ADFDF4BB5FEE5C0D7EF0E4BC456886
+:1028F0000FF9957FBF1DCA7EF5E97FC5A7F2A36FCB
+:1029000082BE9E1C132DFBE77EE5E777C2F7CA81E6
+:1029100050552AED67CA91FEAE2BE8B33DB456047C
+:10292000124F4DFF23EE6BEC17D4AF77435CED46AF
+:1029300027D2AB7E546F0676749459F320330F4739
+:10294000206D818C3D48F14E00EFBA0CFDBEE7C80A
+:10295000473A0BFAB3AAFCB4FCC463C77E7A05FD00
+:102960007E60EB1A948BAE8765B4C726FFC75AF218
+:102970000D939C703D2627CD2B7DCFE1627CF4F03A
+:10298000E2EE291A234FE0BF298F572928270E5B33
+:10299000F31C8C7DE11E1279CF81F4CCEC135965C8
+:1029A000FBC8B0E705FB8964BBC8F8241CF198F3A9
+:1029B0009F8B1E12C3C9E2DCA71C32CEAB2D56552D
+:1029C00004EB209FB903F7C948B7757C633C3AFE16
+:1029D00029B37C935506571EA87EBA9E7DCEDF6430
+:1029E00001FCA71A0C3D15473D75B0448C8FA7F02C
+:1029F0003DF0A01883A4CC03D54C6F6D9259BEE076
+:102A0000265E7EEC348909F9093E9ACCF9EDB1874E
+:102A10004566CFC508EA3972FA0CDA175EFE3DBD8D
+:102A2000E43505F727A2BAB762266605F21F13BD83
+:102A3000501C5D14F558E4ACD8986E59FF3C6AB14F
+:102A400058F3A90B12F52590E34714A0DF93D46F38
+:102A500005FA9DC7F789AA8C3C4CE9F47498FF7677
+:102A600043CF1A7933B63CE9C71B9679205EF8A2AA
+:102A7000413FF50D3AFA3FAA0BC733F6098B6E0BAF
+:102A800047417F3A72ADF9D315B6FCE879B6F2F951
+:102A9000C6574A9DF638EAC62948079A1FE55521C8
+:102AA000C7F3E31753773E75789C65A85F1E4720F0
+:102AB000DD7E5CBF424E40F7DD25D5835FE07FA021
+:102AC00034CD9C5F70B993D9DD077FEB2260E7EFCF
+:102AD000AA52309E69E4753AF8B8B54E0DEBED7A1E
+:102AE000F00E05DA77060ADC80AF0373967B30FFC1
+:102AF00083E7A71A72B765CEF22B6F01799829A2E6
+:102B0000EE69CF6DC9867DF907AA14CC3FF5A70CF5
+:102B1000F41EA065EF93CED023F4FBAE8AF81273B7
+:102B2000DCE60E27D35FD73BF93ED0466BFE06E5C9
+:102B300083EB9D901FE66DC07D4B51E179BC36FF64
+:102B4000DEC0877FFFF562BE8F3D0B7CE08F32FADF
+:102B50008871FAD8C1FDD38741FEBB806E98FCDF37
+:102B6000C8FD537BBF13EBC3FB9D6087DDA6964278
+:102B700028CABEBE13BAACF6447ED42AE7C6DBE947
+:102B8000BE21DB523FA7BEC0F2DD17BAC0669FC4AC
+:102B9000995E236C7D3ADDDE0920B74BA9DE6576B0
+:102BA000862A86CDFB2A36BD5EEFD09B9CE761DF8F
+:102BB000F853C20DB03E767B7A035F9FAFCAFA3AF4
+:102BC000E70CF4DF36C093DAC73C5FDD6A7F0C8325
+:102BD000935038A78E0AE783E703E7D9F6D9ECFBD1
+:102BE0006BDF94C25B5FA1CFF254960FD9EE63FE08
+:102BF0007C3BC45169F9C79C0E9F764AD8FF5E3E64
+:102C0000DFF2145A3F097F1BF1D5E721F106EA8D67
+:102C10004D9E670916107ECF49FEFD7927DBCF2E2A
+:102C20001F3FFA38FB601CFADCE8D07FE434C5F1C2
+:102C3000DA9CFA7F9ACB7127DB7F1E5A179E476971
+:102C4000D8637738F43E73FDC4D32A378D7D904C1A
+:102C5000BE9E3EC2F8EFC525CBD64DA4FCECCCF50C
+:102C6000A2FD93B9A46DB5E887FCA37E15FC814C49
+:102C7000BE8F4F1633396AECABA7D758E5AAFDBC17
+:102C8000958BE7C5BBECE76CB87CB5D3E348F2F5B0
+:102C9000774EEBBEC650FC7A04BAB2C7AF1BE15701
+:102CA0006667723B389CBA68EAC8F4F872D3E0A64B
+:102CB000831313E557E0FC4C523A60FB89FEFD7F1D
+:102CC000AC595C06FB762C9ED6DF142F7F676242E0
+:102CD0007E85E7A6BD0871CF70551ACA9BDAE0A7BA
+:102CE0009B0E527FBC4EEF2B7FC734CF7E95423B6D
+:102CF00061143ED11D9F9BF9EB4981D14F3B1FEFE2
+:102D00007E8E4FBB1DDD29465DD0EF2764401792B4
+:102D1000F8B5E679B721DE06BC406723CD3BE46217
+:102D20007CE59FDD1082389DEB8C847CE01A6FD8A7
+:102D30002D21B45BA6BBD2D8B90F6F01EEE3513F92
+:102D40007DB00FD6C1CBF2FB0DFDF8B1114FE57A86
+:102D5000EFF63456DED0C4E2C7AE0317BFA9D17672
+:102D6000BEC30EE2A6EFD751B90E71C02E6AC7C31B
+:102D7000777FD90081387A2BAD1F31F9DDADA14ABB
+:102D800015EC84B6E25245A3DFA5A9655896F34B2E
+:102D9000D54A3AE605AE6FCFCF843878A18879B5A9
+:102DA000C5B4DC4C4DBA54978AF37BB9E81D2FD8D3
+:102DB00067A9E09CCF48ACA7A32CA24B141E475098
+:102DC000AD845C8C21BDCDE98CBE7F04E2254F0A29
+:102DD00091992E3AFF97F9F9AB4E6743D11AF07BE0
+:102DE000E4A80BE2078D0ADB87007A689B9E807B54
+:102DF0001EC7AF938F3BE407F1F5FC441E88426A7F
+:102E00006BA748EA93ADCF152E26E7DA545D1D95E2
+:102E10009E54F9734BFEF45CC64FCE00A5A724F177
+:102E200047BBBC26AE709D2B3391AF441756453E31
+:102E300025CCDE33CEF7BCE3D4AF75D1797CCBCBD8
+:102E4000E5586E3AD2297D5FE9F942729FC567F66F
+:102E5000CF2D7BB50AFC927E07C68BFC13C8BF84BE
+:102E60004DF2F6900B836EF4C9ECA4F5943E629398
+:102E7000595C8200DDA450450CFB907962EC917C9A
+:102E800080B7A77A02EDAF539E482DF3443F1579E2
+:102E9000CCFEDF54E9A937FB01EFA5B0FD97B5DE05
+:102EA0008A67010FC5DE5825BACF909D39869D9F50
+:102EB000023ABE502503820872304C98DE0C294C31
+:102EC000BF56A9705E4A201172266534FD683D57D1
+:102ED000F5941C6BF1003E022CDEE5DB2A6032A08B
+:102EE000D4ABC73DB44EA977519B8BE98B2218A771
+:102EF0006FA6877869FD4FFB9C681FF6FA7264C065
+:102F0000EB3E71D97720FE34F82B17E637F6FEE555
+:102F100002CCBFEFF55DB200E476AF400E51654FD5
+:102F20002A4EE5F064439202FB7CFEF93A817D8EE5
+:102F3000C1174908F2831DC19F97BF331D279E22E9
+:102F4000CEA6EDDCA4CB4DDB853EF77C3C8FD2D505
+:102F5000B3DED22D1791445CC588A754A444B603B0
+:102F60009CED637E5D0F7CD345E194D07ED58300DC
+:102F70007769A688F14792E98D4D8478D9A14015EB
+:102F8000E48F56C825981AEB9FCFD6FBA827F238B6
+:102F9000F453A5D655417CBDEC888672764170F518
+:102FA0004128CF7C8B95DB9D8C5F205E444C72B7B3
+:102FB000E2D4389C5F2FA793B6A0DEAF0BA3F28DAF
+:102FC000EDDC81355FCE4C0790E76EA28388C34C61
+:102FD00007B3291D4C35D3812E9C0F1DDC8BCAFAFB
+:102FE0008BF08FFE66959088DB0DE783D54A7AF1EA
+:102FF000707E31E0585F961E00396AF0853AEB1E0C
+:1030000094ABAE1B9D61F0D70D3E31F8E353B7038F
+:10301000F990F2C9551EFA5CECD52E4BC627E08715
+:1030200098F9E19A11F8A6960C1E0CD046B5328993
+:10303000A65251F2F2C5EF158E33F1811D6FB573B3
+:103040000572CC22CF58D9845775E87CA374EEF86A
+:103050007F4DD6DA03263EECA07E0818CB5D628851
+:10306000805E29F52EFB14E852AEF97E10FC4187F4
+:103070002B5C8F79B3B33E48B999D2E5A763440D71
+:1030800026DFAE2D7B06F9F9680A01FB64D3CCE597
+:1030900018F7FDF496C878D013EB28FE8FA15E8E4A
+:1030A0008D15310773602CDB6FD782EC1909B2F7ED
+:1030B000847F8FF1B2CEEB0D603DBACE16F9B8DE4B
+:1030C000CDF6BBD6BB99BE59E7EC5680DF06F315AB
+:1030D000D59CEF3C4F62766C89C2F79F4EB76A1061
+:1030E0001F2951989ED9D2D48BF6C7BAA6BDF8CC69
+:1030F000A88911C8A7F2144535D8F756FE3A5F7073
+:10310000001F5FC0F667E17DB3C9FECA51181CCA33
+:103110005FA508F0A7D212D5D24D7256118548325C
+:103120003B7AA39BC55F941682DF95FD0FE17E7607
+:10313000466148B809CA2DDD2404F1F3387B1F2805
+:10314000D485AF9BFA0DD4F45AF45C2D5D82D45231
+:10315000B49EF0BC4BBBE6C1FDAFDA40E51FE569AC
+:10316000C3E9087E8E99E8C180DFD8875DCBFDEF8B
+:10317000AA0205F9AFBDD1D903AAF92A85D9459F7D
+:10318000042A473D2F00FBAFD472433F179EB00F78
+:103190001B9DCCF661A10CFBB0F0847D5878C23E3B
+:1031A0002C7C877D58287FAF49C732ECC74219F67F
+:1031B00063A393D9FE2B9461FF159E7B9BEAF1F9E3
+:1031C000E3A606FCFE7C532396E7B9987F438AA2C8
+:1031D00041B097BBEE74EA9067D3C2D7EB805E90A4
+:1031E00011A2EBEA0EB03881FBF00378DED91D1492
+:1031F000316ED7117C807C8D3EBB66F8BA20EEA183
+:103200003CE3C5A75BDE42C01EDB2144EB4988904E
+:103210005BBA4AAA646A2714065757A6D3F2AAAE25
+:10322000596D907738496B0E2D531365CD57BAFC05
+:10323000FBA6F2F8E21ED913023CCF6903790070B5
+:10324000C0A6D9BD5D73AB9A0BA9DF54400D159094
+:103250006BF9CE18D0F3D761BD2602FCCCBEBB8A79
+:10326000B40621AE315E7396021FD2FA7146FFE7B3
+:1032700056BF45D1F0BDBDDD68F5C4B273AA47A401
+:1032800051FA83EFC228FDB49356B59FC2BE0164C4
+:1032900006D8476EB6CFDBE560FCDFE566CFB7DD6D
+:1032A0008C7F7FE8AEAC74D367A59BF177973B5CCE
+:1032B0000DE74D06A78A18DFE975D02EE0F04163CF
+:1032C000FEEB702EE88E9FC904F60F1EE27430717B
+:1032D000BC8FE9E9BB15D4D3978FFF6E5B3A2D4FB6
+:1032E0007C341402BDBB81843C4027D18D22E6A1F1
+:1032F0003C5D3621BD8E56BF70C673E9A07F3E553A
+:1033000098FC89717FA3B9FDE6F11097FAF4552670
+:10331000FF7672B9D3E3E86FC0F59CE1457B853A4F
+:103320000C688F340765CC1F12B3D8D3E950FF095E
+:10333000EA39A9C28F52789C7F99A560FCE3948BEF
+:10334000DF6FD18F768AD31D51D3E8FBEEA888FCBE
+:10335000DEAA7A6260576FF096E2B9D268B18CE764
+:103360004B3614B3F8698AEFBA18D827F7F7B9992A
+:103370007CF02A983F1A2BDE73A832004F51057E4D
+:103380008FE98BAA11EFAAA8621E2AFD0DBFD707ED
+:10339000F03CCA06C2D7A55EC4F374ED633EFFF9E4
+:1033A00045909773931AE2770E609E379A5C22ECF1
+:1033B000070DEE4F0178BE6ADC5730D09242EBB772
+:1033C0002D5343B00ED3D4CA6AC82368572BD1CF2C
+:1033D00049995AA5DC887268E83C06DE8BD1562CE8
+:1033E000631E117C07BE246DE4209C87CFE1B22CC4
+:1033F00025AD5400FBAABD06C37C705EC19257DEAA
+:10340000967E259E43926AD311CE76A22B503F5AC8
+:1034100023A3FECBF12A71B037728C782E1CB13009
+:10342000C51B326EB39ED3C8AA972DE7C2C746AC60
+:10343000E54C1E3FC8B49DE7F85831F6C7AC78B2EA
+:10344000CF3723F0481AC09B010779B5E1F3D912B1
+:1034500028AD8379E6A81E843BA8B65480FC1A4B9D
+:103460001A9A81EECE1B5E1B9CD38ADBFA61DDA724
+:103470006932D1E8F81791C116E87703A7F3AE7C5B
+:10348000AB3E7E48910C7EBC10F8717CA348A2A68E
+:10349000F1210E19358D37A12BDD529ED89D6DA9D6
+:1034A0003F796B81E5FB94D80596EF17EE2CB59428
+:1034B000A7F6CEB1D4BF686FA5A55C12BFD2527F6C
+:1034C000FAA14596F28CFE7FB2D49F757499E5FB04
+:1034D000C503CB2DDF2F796F8DA57CE9E05D96FAD2
+:1034E00086BD6ED78B13B9DD72BE76BA0BEE89B08E
+:1034F000C465AD7E80DD8E57FEDAAAB5805CF33BF5
+:1035000091BE65D0E3B4BCE64EE64729E5210DE463
+:103510004A0E97A3D93EBDD40DFBA97E05F581ECDB
+:1035200065F564EF02B43FC66DA5F2683A589B6436
+:10353000E87B0AC8E5A66879A129DEE456BBF16CF0
+:103540005685BF1AF7378CF6B2AA93880FC6D3D820
+:10355000F96AEAA5423DB746DB9BE6B54F14F10890
+:10356000F420F5F71E31F97B23F977767FEE5CFDC9
+:10357000B77122F1E0B90221DC00CFE286572B219E
+:103580001D98FA75D701FD6E7286EB7B68BF9B0AAA
+:103590003C6C1F94FB755DF9BDC81783F932EA17BF
+:1035A000226BC5E6785C33D74329CAD3E85752BCAF
+:1035B000A3BC35F0BE411888B582DCB9D383F27064
+:1035C000DC7FBB5E03FE520A941C85BE0F1D70EAB1
+:1035D000B0BFB485E3B5402DA984905261B06E3F71
+:1035E0003C2769D4CEA0CFA2A2CDFBE179BB9BE55D
+:1035F000035F10FA7E25C812A59CD97FF23467AC10
+:1036000085F623A9148E247E85F194FC5BD9FE45B2
+:10361000A1FC2ED01B58F567E8142AD215CCF77000
+:10362000031D08F844FA7107BCA837DC70B815CA46
+:10363000B21083FD3FB04F611FAE227D2BAEBB6148
+:10364000B7823D1B617E6E33D057A0C6BADE29CA51
+:10365000F7104F6D028B7B77A569872BE9B85D99D1
+:1036600005E9106385B8489D49DEACE7FAF49F3D53
+:1036700022CF7363F2E6CFD0E78C84BD43E97FAB02
+:103680003801E0EB2620B7DCF77413A077B74A5770
+:1036900013EDFAA816467DCAECDDDB394C55054B17
+:1036A000707FFFE34029DAB7EEC67D49F1E71E904F
+:1036B000883E7D64BCFA276D437D4F0A9C1AD8155D
+:1036C0008D9A53EF49220FA6703F64DD38E33C2BFF
+:1036D000CBEFE9E2F830E2A14371461E4F33E28CB2
+:1036E000463FB767968E1DCD1E7753FF32628277B5
+:1036F0001D1D07F0D27EBAAE1AF12013761EF72FE9
+:10370000C53DEB719F95F9495338BE4B387EC7399B
+:1037100009FA09F3216E92015EED55D5C097469CDA
+:10372000E537606CD17AA12891585CCD61E82DF124
+:10373000CC4508B3E634F2C3D0E4657A8DFEDB07EE
+:10374000E7C6267459CF654EECB696276FB596A797
+:10375000C4AC656A351F01BB006C348C5BECB47E75
+:10376000AF33F603AAD83932858E7C86E95FCBBDAC
+:103770003884EB7F238F2DAF375E01E23577AD556F
+:10378000AF66733D9F6DD39FA53E09E30915870280
+:1037900007C17E34E23E473D9A259FCC88DFD8E5BD
+:1037A000B9E7ADCD847E41BF3CE262710C880F7FEA
+:1037B00096C7E325B93C5E328EC74BF258BCC42194
+:1037C00069AF2C1530FFF3B81B8D97868B589C86FC
+:1037D0009DE7FAA85A7E51D0D87811D378DF2C8A89
+:1037E0005ECED010CB827A46DCC4880BB87D7A25B9
+:1037F000F0EF86D06B0D07289D54FECA45A09FCBE5
+:10380000A4C3879A40BEE5C998B7ADCEBAED3B1EBA
+:103810008843C2775AAECCD7C6221FFCD481F1812F
+:103820004E4ED7C6394423CE92E2617691CB63D80F
+:1038300047510FCFCBF780BD7BE14E2AA32DFA8EE7
+:10384000C5F38CB8DDD45EEBF75E2264A8B0EFBFA1
+:10385000242632FB4AF75698F21A2FE0EB366D69B0
+:10386000FC81A5B4BC9BC44AE1BEB9124E1FA18322
+:10387000D6F3AF638880E79FC61C9142315A7FDA46
+:10388000F3D6EFC5B6F3B117D8CFCBDAF6857C12F5
+:103890003971231D6FA3D620801CDDB894DAF2B4F1
+:1038A0005CE8E1FB4593C824A0C3CB246F280EF845
+:1038B0007D43C2FD2DD7DB93DFBC11F4FAAB2CEFB7
+:1038C000489DA06D8638B2FA7309F5949A424A4A27
+:1038D000BC897DA47F3B1322B02F62C4B59EA2EBAE
+:1038E0000A7A6537F5CB0B1DE067AB58EEA57E393C
+:1038F000949FA57E393CF750BF1CDEFF90FAE5503F
+:10390000DE4BFD7278FE98FAE5F0FE79EA9743798E
+:10391000ADB7A212E262FDB43ED08BA7648F3281B4
+:10392000C2DBA93854A00FBB1CAAA8B85D594C49EA
+:10393000EA2B9D4FE3FE45E5652C4FBA72FDD3B8E7
+:103940007F618EAF99E38F89F8DA8060C4D720E475
+:10395000F93BBECF3014678BB038DBD9FBD18D7EFD
+:1039600030AE39AC1F1EDFFCF0CE5F3FD14A3FAD19
+:1039700098F14097A700CE6D34F0789E9117A35927
+:10398000F2EE57EC69C6BC1867D6910658D73D656C
+:103990005ECC17713A222AC85BBB3F67F871767B11
+:1039A000DA78DAF59B8FDB1546DC749383609E74BE
+:1039B00054A0F604D8174DB1F2771C23C7535FF714
+:1039C000F0F34336B930743E80C77D5C60CDD27968
+:1039D0003A058E0F9EB78EA2B180C5F5CC71554FBA
+:1039E000610C0FA57BBC3ADA7502B5F7D0FE532304
+:1039F0004188A375C0798024F38B7998FE6BCE72D1
+:103A0000A2BDD191C5F240AA72434168DF9A353315
+:103A1000683E1F609C5F38E89BA90C98FA5BE32B1B
+:103A20001855FF49545F6BA3E86BC9C5CEEFB4EEE0
+:103A3000BF588173195DDE65FDE047770503187F88
+:103A4000EFCB9A49064CFD4BC1D9787E43F2327BCD
+:103A5000580A2A680FCB30FFE2447DA3DE3D1E46A4
+:103A600027949D31BEE8F676633D971CC67B235CA8
+:103A7000015099F4A9B2FD384FA1481493BC30C647
+:103A8000FD570F93975DC51115E22C5D4159837366
+:103A9000205D5A29E2B995E3B935CFB0274268C70E
+:103AA000ECE17836FA69E57180D67A27DA73E1C6F7
+:103AB00034B52A03F37577C1BE5697B745817D4962
+:103AC0006756D9A8FDFE84CBEB91FB2D1953351D0C
+:103AD000FBDD03FD3A7DCB54E8D731C2B9A3C31C4B
+:103AE000CE2F6AB7DAF7F128B441733E8AFDE9E3D5
+:103AF000F6A7BDDD8AE20127ACFBBAC7ACE7941D8F
+:103B0000849DDB5AB97735F2F926B91FEDA84DA788
+:103B100085A4E7BF325204CE6F43FEBDC50ECAE195
+:103B2000FC94C3BF03A981BE28895BED96E987ACED
+:103B3000E519FDD6F2ACA3763B487F03ECA0C55C4B
+:103B4000EEF55379CF92610665C047381AAB00B8DD
+:103B5000EB486F33E44938789C7C31D77F0BB97ED2
+:103B600074A7B0786F4EBDC7E27F127ECF5F2EEF95
+:103B70003FAFEAE0EA3610B261C3AED2D06FCDBB40
+:103B8000E2D90A149736FBAA4EB79EE35F68B39F4B
+:103B9000EC765685DC83F9B8D9B6B886B19F0BF3BD
+:103BA00084FB0CECE39FEFB8467F908705F2CDB81D
+:103BB000E705EF15A6EDF3E4B810A278CA6E60E74A
+:103BC0007072D612BD27091DCF49617C310C6FD1AF
+:103BD0007988B7F9FC5DB697DDCF955D25C5343A98
+:103BE0007E767D2FDA038B6EA3F3413BFC0CE6C19E
+:103BF00018F5D3D37AF13CD2B61A81E7E712B46B49
+:103C00008C75DEE665E707EB2E156222B46F28C0DF
+:103C1000F111AE82C4FA523C1D637862F986D75422
+:103C20005BCF39D6D9EC17831E16DADEFFD6C3F682
+:103C3000C50D3EF8F0E2A393C651385608DDD529EC
+:103C400013CE5D5F9AF8C37106F8107E1FC3525FF2
+:103C5000308F57F9818AE73DD206B6134A92B529CB
+:103C6000245A3517E4CFE085022D5F9BF2BDF6AEF6
+:103C70004BE1F8F6E0D360E4B95C3FB8AC3A2F51C1
+:103C8000F6787E82E5001F07B616D97A9BEE7DA1F5
+:103C9000A8DBCEF3E337E864B304B9B5A2BA39942C
+:103CA0009F68970EED8451DA85C96639493BAFD1DB
+:103CB0008EA2AB03EE75E2F3F2F0EF2287C73CBEB3
+:103CC0000C7853352F9E635C20AB9097F165E1181B
+:103CD00073B67947C866C784E1ED28D8CD06FC6283
+:103CE00072F863F0DD3CBE6314F8FFD6F8385B7FF2
+:103CF0004EFEFDBCE1A3D55BC68C3C5F80CB81F75B
+:103D00000D695ED1D4CFFD7D7FC2B8B87C3D09413D
+:103D1000C84B76E82AECE715AB0FA27F2FA755A971
+:103D20006007ACA365B003D6F57663FCBBB8F08141
+:103D30002E20FAE2B887803C984AD4B4DDB4DFA9DB
+:103D4000AA0C27AB887CE94111E2E9E46A82792375
+:103D5000A97D1E763F50FE9C47C1DF4A4B53703F02
+:103D600023256DE6A3CCE865716603FE948A23954E
+:103D7000107F97EB484800B88418A900269B427032
+:103D80007FC3A3EFF9269C032032D34F78470EE878
+:103D9000551E6F1FCB48867439D53ACC5FF9998C84
+:103DA00071ACB170051825CAE2E2F4CD004F718400
+:103DB000762000FC2C5E36352286E2B4FFD213ACAE
+:103DC0001DF9053B3F427D9325CF79137835E4CA31
+:103DD000581E870F2EB5C6A9C9209D336D5FFA8B7B
+:103DE000458F439C62CC30F9CDFC760F8733F504C8
+:103DF0000943FF811AABDEF0F0FC6D8FEDFE988B6E
+:103E00007C0EEBBDCF76FFE1DE30EA011709294ECB
+:103E1000B42F96A2DD60F825DBA022D8E37984DDFB
+:103E2000B76B6F3F93B52741E6A7B83C44514AE9C9
+:103E3000F7E51E1DF30D5DB44CF12838899245DF7E
+:103E4000678B2CDED22C1019CA89F1E29867E052F8
+:103E5000AE6A03FB65BF321DEF4533FCEA5635847D
+:103E60007910A4A8D262371BF95E6B4A0AC6C2F762
+:103E7000D43143712715E8724D6621DAD1FE8C8169
+:103E80007F0639FB598A6F81027215F230E6C0B5A0
+:103E9000B4AE8E2895BBAE53394433D9672EB901E1
+:103EA000E36CAE53E32CEFE34DD673D4BA57AC8238
+:103EB00071B2BD1A3BBF43D436685741ACE7A55D2C
+:103EC000A7B22CF67AA2FF5CCBFB38B56BCCF7FB24
+:103ED0008CDC7F0AD18ACCFD4F18A1FF49B6FED5F4
+:103EE000A4FD27FACDB0F4DB2EB3F86B34E0497AA9
+:103EF000DF64A9B772BC77C6C8FB03255E16D7EC92
+:103F00000C36E0FE4025A18C4FE965DEE963123BEB
+:103F1000C74BD07E23B9D6FD814A4EC722A50C3CA3
+:103F200017205BEF2D2E27F67B8CAD76D111086E16
+:103F3000517A177D65FDB84FF0272F9EF31BC96E90
+:103F4000EE6F22189F2E4F19B81DF6C1AFF48E7375
+:103F5000B607319F19FDF925DEE90BF8BD9F2CAF9F
+:103F60003920225EC29563F19C96D14FD8492682B2
+:103F70005C0C8B2C0F027FE8F8FD99D98FAC4F8237
+:103F80003FFB39F73A5D282F34CDAB1FF20ACDE362
+:103F9000CDCFE9914CF308BBC80C1C8FDBBB43E3CE
+:103FA0008DF962E3BDCAE359C678750BACF3AB7308
+:103FB000AA38BF3ACEC7C678AFC2FC92E0F7ACE3EE
+:103FC000F1BCC9A1F12EB7CEAFCEA5E2FCEAF83D17
+:103FD000BB43E38DF962E319719D4E674303D0E162
+:103FE00048F11D23AE734DE72E4B5C874477CDAF70
+:103FF000282464B3C0E4C7F68DF33AC0FFFBB8666B
+:104000004D11EA156E5FE37DAA541F2F9419BCB5BC
+:10401000B9DE58B3098FDBA81CD127C3390985C085
+:1040200081323837A1E3398A203E1FA1F6BA8EF9D2
+:104030002545F8FD89A610967736CDC6A7D14FD174
+:104040006C76EFD794B94252BBFD752FB3DB37675F
+:10405000A9D77F1DF45B8587E5FBCEBE84E8263BB0
+:104060009A1AD6FBDDB03F741D29011D39692B83D7
+:104070003B50352606EBEF2939D8DF047150D9A122
+:1040800061BEAB96FCEF18BCEC65FEBCCBC5DA9309
+:104090004BD8FDA7B55C3F11A906F38F6A17A6613F
+:1040A0003EC2A2C5BA4FA5785B2C086F14727D077B
+:1040B000E79EAEE54B6DF71702A079E87A05742903
+:1040C00006F7C35D9B7B788940FB0DFBAE413F2328
+:1040D0004C1BA6D37EAEE5FAB6E26D17817804B923
+:1040E000CC89F26BF162AB5FB0D91D57C1CED95C00
+:1040F0001220CDB4DDA21AEB77978BF155D876FF5D
+:104100004BED59EE8331F26DEDF8B1C74D0F79F9F2
+:1041100079251E1F3D498AEFC7335F3C2FD7DEDE6E
+:1041200088833679997CEB7432F9309C0F183CEF18
+:104130007139B8ADE928C6D10CF8B2E59800F23E65
+:10414000A7FEA825EF9D22168D6A639F8048BB4B72
+:10415000500FDBE6B34DD89D35DA7D50D9447E77DC
+:10416000A088FFDD0261F8BCFFE0B5C6854F92B9BB
+:10417000AF149264FCC3E2C1B587A450B396C08B60
+:104180008187FF6B3EDA0278A7CF57E67F52C6FCE5
+:10419000C05CCBDF0730CE6F5D335496896CA2E7ED
+:1041A00085CB9D3AF357078B812E8F5C9A12627FE5
+:1041B000E782DB41F15F8960077DF9FEF53C4B5EEC
+:1041C00033EF77A4F5B2E7539ACE1B27EE3F80FC7E
+:1041D00097E65010ED814C91003F65433E9E9F7DD8
+:1041E0003F66B55B2DF978AD7DBB04881B6E87FCFF
+:1041F00044D339BB9CFA5EA11DECBBE6188B43C4CB
+:10420000693D0A776E7D5C682B4EE47DD9E57AEED8
+:104210006DD67CC1F6B98BD5DD1AE4D55476C3C50D
+:104220005FEBB6B23897517F28DEC5CF9F3A48037F
+:1042300081F3179297C59B83FC5E8EB3E5EF7E26D4
+:1042400046D5FC7CC8DB8D291574FE0F65442A7C9D
+:10425000B4DFAE4069430FD0A71CC23CEFA58D77F9
+:1042600087214EA866248F832FE5F6418D8FC5D315
+:10427000DE72C4F3206EFE8B8CCA1ADF8C24F51B11
+:10428000EFC5FECA47B86FFE261FA3CFED62727955
+:1042900070031FE72B2B44BC47C84D7C783ED55D8F
+:1042A000D83D1BF0B17DE5B650B27396D3D5C85753
+:1042B0007DA638ABBB90DD034048EFC530CF757F9E
+:1042C0007EB8F7193AEFF43F7B51CEA64BAC5F5363
+:1042D000FB9BCCF331DAEFFBD32FF1FCFC3E7EAF3E
+:1042E0003A89165C0E71F64D4619B600A09C3654FC
+:1042F000BE1CFCCA44F9C70BE0EF266D021AA5C428
+:10430000F7DEA6C3A887370984EBE95F2CC0FEF867
+:104310003DEE2FF2EFE5577EF0E8FDA00F663AD1B3
+:10432000DFDCC4ED1D03BEF77DEC9CC2FB1C5F23EC
+:10433000E1B393E3DB0BF80C9C173E3B93E1634145
+:1043400040EF023CBB21138482E0FEB3B216F2AD13
+:104350001F6A22E1AFD3396C0FEDD905678A68FB7C
+:10436000FB93ADC70F33F46E1FC2730CE7E72BF45A
+:10437000860015EB6611EC27091C5B475BD7A96922
+:104380004CCEC11D63F04CE7F6A5E4EA0F42FE8275
+:104390005AF66FB7AB54CE74E4F72F4916277EC296
+:1043A000CFECFEB411E2E22F70FC55A5877702DC5A
+:1043B0006DEA03E8EF39051286FAEB660F10C1D4F7
+:1043C000EE2D3F5B0F0A772FC0EDBC98DD4FEDA3BC
+:1043D000788704395F19837F9D768440FEBB2F78F0
+:1043E00004F35A7D6503C8EF280AB3195D813FA81D
+:1043F00070FBED854D6F2F00BA48970C3ABCBD138A
+:10440000E84C4A9491EE7AD259FB63F7DDDE09FE5F
+:10441000E20E276D037230DB89F68D7D7E8738BC16
+:1044200082AA1F80F90DC3A76BE051B86F60D34417
+:10443000764F4BB9D8BFE46B4097577AD13EA3EF84
+:104440009798CFDB9FE4F83AE963F6D5A63F29F8C1
+:10445000DDBE1E23D1EB6FBF38BDFE76047AFD9D15
+:104460008D5E3F21C9E9F57F46A0D777E1BD1D2FBD
+:10447000F6B244F4ADB0AF2C7FBE6027F4275F35B1
+:1044800077EB33F4297DBE318AAB19122CE79913EF
+:10449000F23EF209F46FDC2B60FC7DA2BB7C23F4BE
+:1044A0003B6BE6569063E7D0EF19C087BDDF5FF046
+:1044B0007ECBAFF44692DD93B0CBCFF2E37FE067E3
+:1044C000F546E29B5FF9597ECA487C13F70FF14D20
+:1044D000AA3FF3EC7C33C8EBD37518EB9F712E7CAD
+:1044E000F3203EDD858C6F70FE7386F30D2111E4A1
+:1044F000938E7CC61745FE159DD15C131F917BAD35
+:104500007C44EEB5F0D1A7FE7B918FECEDFD23DC72
+:104510000778D110FF87A7C13CF40BD536763E69EA
+:1045200000CFE1F690C13E17E609B3BC5C4F34AA58
+:1045300033F3A09FC0BDB3B378FB1DE0A3811F344C
+:1045400093C7B3E47EB2C8379C9F7D65F132F3FD1B
+:104550002E2FF3F6AED47039E0BD870C4C01FB6C06
+:10456000A4759ACFEB9F4ED7E7FB93D0F9D9F450BF
+:10457000BD9FE9A17ADE4FFA9F9506B04FEDFC5E34
+:10458000BEF2C77F7C62947E6EE2EBFF55DECF17F2
+:10459000E0FFAFFA93F02FE5FF1B601D4CFC5F2698
+:1045A0001424E5FF9BFC49E407E5FF9BFD7F5B7E50
+:1045B0005FE34FC2975701BF659E1DDFCF717C3F00
+:1045C000F725F1BD85E37B83FF0BCBDB0DC9F04500
+:1045D000F1BDF11CF1BD65047C3FE8C7F57F16E134
+:1045E000F7695E8C9777CD227BA09F24703C6CEEA0
+:1045F00047D1583F94A73E1128DD977FDE154A76B4
+:10460000FF116DF768B276F3FDAA917CBE1AFC87A4
+:10461000ED5779715F81EAC72793F1C797A0831F90
+:10462000F893C8FD7291C921C77D1777421CEF4BE3
+:10463000F4FF9364FDDFC9E5FAD9EC82D7385DD089
+:1046400079FF977FC670F9D7C3CF270B6AE4177E2F
+:104650008CDB0F5C01F26AC75DE902C4BB72F5B87E
+:10466000007E025EEA43E1980B97F8CC48B4DB2168
+:10467000C705B83F6747832AC07929537F6FFA334C
+:1046800047EECF0E0785EFD77E9477FA6FE0399F1C
+:10469000CFEF7CEDA47DE9FAEFFD4C6EFF0F3CF50A
+:1046A000C956B96DCC430C77B33CDBD9C9FF7EE565
+:1046B000019FCCF558F8B859FEBF3B4457ACBFF347
+:1046C000D53F14BECF387C7FC27E6DF0D9F17236F3
+:1046D0003827819E67FD49A999C3F594BD3FC3CF93
+:1046E00036D609AEC530C77DD4D421FD9D0AFD79EB
+:1046F000DB453C4755CBE549EDEC346EB7AB1EE8E6
+:104700007F3B8FC36FBFED810AD857EFB9472D01AB
+:104710001464D733BDA7DD360EE3ABD9BC5F3BFCD9
+:1047200043ED9DBD53E0EF42D071C7C1B8F3E692AF
+:1047300038F88DA9603760BC42C5BF5F9CEEEA0EB9
+:10474000427C769DD0BD6419E8D52BBCEC5C4C70E6
+:10475000F159EEC56CB1D02D09969DA57E33D65783
+:1047600053BAF1FE9473AEEFEA4E6A67CD4B150D66
+:104770007F62CEA8780D0630EE65E077F8386CFDE4
+:104780002AC20D02E0DB5726A8907AE7A37402F64E
+:104790009258D88F79535797317A21D42F19FDFE2B
+:1047A000950E03AEABFF167019F5461E8FD7B39D5D
+:1047B000B718FA3B635E26C7B0222D7F742823E921
+:1047C000BE82F1EC6C5275B80AF92355C37B193BD4
+:1047D00087F2BE43C145BEBF7FBDC4BC626CDFC9AA
+:1047E000567FE8FE91A082F61FFEFD0E131D75A4F4
+:1047F00032BF554A0BDF9D8AF23784F73FD2F2B7BA
+:10480000B0ACD0B20FCB4DB03E441D2A37E3F720F9
+:10481000AB4F54F59CF04EDB75613B79A89FF5D802
+:10482000AF7768DC8D580E0C95EFC3FAB9ACFEB9C2
+:104830008E33ECFE957E09E7FF89ACA7C2BEE97511
+:104840008D5FC3F8D2F58DB7E0B3AB49AD80389D2D
+:10485000710FC975D77F4D057FFAFA9BB6E0BEBED2
+:10486000D1FF42F03B80FF35B91AEC2567BE187EB8
+:10487000CC9BE0BF041C6D58AE95D97DFE0B679FA5
+:10488000D8D4668ADF29F077D121BF4633DD834152
+:1048900012F2F04941DF9D7A1EF43C7C9E841CA4F8
+:1048A000F4FB89B73016457AAE5493F18D31DF9120
+:1048B000FA37E63B92BC31F066BC5F57C8FF8EAE5C
+:1048C0002D7EE99E5885F93F0B050EA78FDF0BC99A
+:1048D000EBD5D2719E2D46BAD0806E6BB97F67D76B
+:1048E0000FC6B84F0A91D7013F1027BEA774387E74
+:1048F000CF156F46FF63235102F772798A09EE8B59
+:10490000057CC6BE3A936B0F7A8D7214934BC285A9
+:10491000DD28E7DC9A21F7989E54537A75B184FA22
+:1049200041A97FBD3C3805F2402341F8133EB4FC59
+:1049300012DCCF9C2EB132217F7DE920DA3FEA05DF
+:104940007093A3227FFED2A13CC28E2E62DCE6F3DE
+:1049500097209ED733542671385FD0E3192AEB4A4B
+:1049600090960B86CA5128EFE076DFE9D4CF5F6AD4
+:10497000437D16FE0CF8C790AB155CAEFEADE4E9C6
+:10498000FF02CED174B20080000000001F8B08002F
+:1049900000000000000BE57D0B7854D5B5F03E73A8
+:1049A000E695642699BC27BC721240A23C9C040286
+:1049B00041B14E78355E790CF51524C824E1119E7D
+:1049C00001A432ADB60C24202868AC2FEA833B2822
+:1049D000F66AAFF682C55BFE16F907410B2D62AC95
+:1049E000A8F840C3A3151F2511B44CAD2D77ADB564
+:1049F000F7CE9C733203C1B6FFDFFFFBC3D72EF7A0
+:104A000039FBECC75A6BAFB5F65A6BEF612CCC583B
+:104A10002E639BB566CFE8618C85BD565F7F8DB1F7
+:104A2000750CFE0A183B877F5733D6D76367AC9C5B
+:104A3000B1473283291EA83FE98E0EAB13EA398BAA
+:104A400072DC41176385DE2FC295F07DE128C63404
+:104A5000FCB65F166323A15DEF32C59E037010F3B1
+:104A6000288CDEADF240FD1C3763AD009935C2D80D
+:104A700020C61E70C9328C0760A024C2DAE079AA71
+:104A8000C6DF5BB00CCF55075BBC15CA6925CC1FD0
+:104A900081B2C7C1660400F6F258681E033DAA80C1
+:104AA0000A8D37C3DBCC34A8EFACB2F82300331047
+:104AB000BAE2F362AC99EA0DF4580932818FF13908
+:104AC000C1011E286F66AC6A2B8E8B450325308F83
+:104AD000D44B73B2EE825265897519832EFF7D0522
+:104AE0000BCCB43136D413B0637D57694E6A701065
+:104AF00095875079B525CC002F95CC1D518AE27849
+:104B00008191A706DCF171C4C7C3FB7F6B453030D0
+:104B1000D6D6F5BD84374E5503FA79485889788042
+:104B20007E4F55FFFE219CCE4267879D15033DFBBE
+:104B3000DD17602ACE47A3F7CEED53A23DE1FDA2DB
+:104B40001D4B188E77555AFA28A4A3B9DFB7BE7E3D
+:104B5000D81380F7297F7604B626E86F0EE219C6CF
+:104B60007B6845357D07CD6BD63CC666E0548A1917
+:104B700011B4CD899029E71C34BD43FDE0FD2D8C97
+:104B800033C3F581DA890CF05A57AD32B508BFEB63
+:104B9000ACCFCE41F996B6DA096C081442B613F8D8
+:104BA000DC09FFCE41BB419639DE038F6BC3FC3974
+:104BB000D587FFCD62BEF1B9F05DFD5AD3F3F7AFF3
+:104BC000F998A5E37BEB89B69278FB3755D706C6F3
+:104BD0008A7A67E8FF23849FEB35E647BA5DEF4B9F
+:104BE0008B84618A3704A606C696C4DB7BFBAFEADA
+:104BF0000CC48B191FDB05DF1D5A11088CEDDF1566
+:104C00001F7501C5EED12E8C97EEE2A1D65A3A3E21
+:104C100057EB8A07F3FC01631B10CFB300CF771566
+:104C200025C707D4237ABC3D15EAC154C6AB136C23
+:104C300016C043FD14853914C26F3AEB8BF5FC1393
+:104C4000C6E9C66BC6A3195FF52F325F14DAAD7FD4
+:104C5000D0ED030E67BF93F88902D286833CE155FD
+:104C6000F5F33C86E3F7C03F9CE7772A4A5FCE81A5
+:104C700071049B151FE3F33DA69F5F1D0B64441554
+:104C80009AF7B124743FA69FA7797CE6F1A7A0B05C
+:104C900002F9177ABFE89EBDBA7ACC1A1D1418CC57
+:104CA000D8331E77CE1FD2A03C84F9CEC1BAFA9277
+:104CB0008DCA188AEFFBE5D0FA36F3C5D915DA3D6F
+:104CC0007B6DFA75CEF96C46684A67BFD8BEC28262
+:104CD0009D650FE0393055DD7003FCF75BFBB25783
+:104CE000E3B3A55E553B918DF882F912BDFC8C496A
+:104CF000FE6208C3BB55C0DF14E6D45CD0CED5201D
+:104D0000A4CEC15C26F95334976E1EA75B942A94F7
+:104D1000A340BC8CEB07C7E76B1EF752AF9DFA03AD
+:104D20007EFC42CF8F66BCBC55DD3703E5C88138B9
+:104D30005E865C0C5E46E3620639E2C9665105E8B0
+:104D4000DCA138234FC0986A42B707C60E45BCB0F5
+:104D5000B01D44E7514F11D593F3B631F9B798A17F
+:104D60003CADB1B320CEEB7D1BABDEE64218ED5D72
+:104D7000A6935B27B22B8FA25C96E59AD00FA97DF4
+:104D80006044E243C9CFB7385D5195F3E1679D7C3C
+:104D900043F2ACC6F387814427760EE6A9662CD091
+:104DA00070DE6A5AFA1096C1D85AAC02F354330333
+:104DB0007F443DA9A6F58920FFA54E7D722DA7E36E
+:104DC000FD5537EAE89832EBE7616A5CCB32E03FA9
+:104DD0004DD0AF52D02FA5C469A61FC3751A2E613E
+:104DE00091A7148102289FEEE78FE0BA4DA63724E1
+:104DF0003D534AAC5FB5E9F99AB5103F4A3AB2BDA6
+:104E0000C33A70BD06BD567617BD2F21FC043D1276
+:104E10003F1D36D4273342B6D3FA76820533232B8F
+:104E2000F1BB750E1F3EABB36879580FF0E4413DFE
+:104E3000CE4A7C3E5C3F2C0CDF497E42BCA231A1B5
+:104E40006BBF0DE6505086ED81F4C4EFD6EAFA2927
+:104E5000EEDA6FE7BA32B76BFA4E55C17E203BC22D
+:104E6000E7F3E9E4779F4C6E3F9CF60EDB6A294E30
+:104E70008EBF3A67B6DF9A1D2F1F2B70564712E878
+:104E800001D99ED4E7596AD06BC1B9B127F7ED1D9E
+:104E9000857AD87319483276F7EAC7F7EDEBCD90EB
+:104EA0004518EB81D51FDFE77791DDC1CBC898307E
+:104EB000FECDA99D65BFD30BE5E2CE7218CB9BA0BA
+:104EC0003B7605C8EBFB1EDFD70CDF9F3DE220FDE4
+:104ED00075BA2A35828B273B34861D87715BC1CC1E
+:104EE000C90056031046E80CF5A4F92856C01CE08A
+:104EF0003B5BF32988EFC9991AF183556351370C4D
+:104F00002EDBEA53105F3FB2B30621372E9DA2B3CA
+:104F10005F266772BB43F6E370B2704A59BC5DC648
+:104F20007C2B518F582730D22BB0CEC96E93EB5BC0
+:104F3000B6332D93EBCFCEF579E1F53C2D33C17A25
+:104F40003E6059FCE10FD09EFD8DCA9E82A94CF7B0
+:104F50007E8F9EDF18AA2738353497E0AC4C6EBFA1
+:104F6000FC9E056765026CAD7E63FA72E0DFC6EDFC
+:104F70000E1FAAE585B77D7C4FB9867802BAE37724
+:104F8000B3EA1F2C87F7F6FE16B267D7F666D5C8C8
+:104F90004FF6950AD947EB347BD576800F6454DE03
+:104FA0008FEDC9713D903196CAAC4AB3209F2F75E1
+:104FB000723E3F7BE44E6F1DDA952E17AD17FBCA8C
+:104FC000A27B2D5066FB61DC0CE507233B4375702B
+:104FD000B83A93DBA9AB05BE7F20F8CC1943227306
+:104FE000BE5E0CFD3BAD618676B63366A5E7760501
+:104FF000C697804F657BCE182CD2A1D89FF97B3BFA
+:105000003DC779E1F76A3633D83DF7E0F7B908E5EF
+:1050100038D2F838B2CDEDA4F3E762FD99C771D26A
+:1050200033E647889F0732FCF767921DDE664379B7
+:105030007E8BEB37879521DD91C76D0ACAE3495F07
+:105040002BD142C05F4AA51A5955847ACD337118C5
+:10505000F001ABB4F9109FADFD72DCC5BAFE9F1232
+:10506000F47FDDEA71E33803E3C0AE26FE66B9D70C
+:10507000633BE3EA8773F90706974ECFBEAE6D59DF
+:105080005B8CF2376CA3FDD20C673882E3D3D96D09
+:10509000CA392E9735EBF0B8FD3763ACEA4F49EFCC
+:1050A0006ADFC136642FD97F529687A10CDF7D203D
+:1050B0008A1F8E3D73034EA38D79ECC57A7B1077E2
+:1050C0004BC3D1BEE17F334246BBCF6C17D655945C
+:1050D000BE026400BC44AA86219F5D6A213EEBAEFD
+:1050E000BDCCD87D9CCEE39A3CB8AF7A04E504EE03
+:1050F00007C71E1F4B72034C2B6C77F258D51385D4
+:10510000DAEB4316E687811FF4AB1105E676B0A40F
+:105110006DFFD588B70A9B467AAB846DB82E07DF42
+:105120000FF5209E03C20E81FA5CBF799D91FEF0BF
+:10513000ACD57FDC55AFE3BB8315C72FC5FD0AC8CF
+:10514000BD8644FCC4D84AE2EBBDDF4FA5763E7C69
+:1051500040893860FCE3D4AF5F1D81F6EC0F6C3EF4
+:105160008746D3B2205D27F898D8B8FA5DE3747605
+:10517000C07116184E7665E9914A07DAAFAB155A39
+:10518000A712FF3342467B33B818EC32ADAB7D0A31
+:105190008DD9919FBB6B9F9AEDABB399C2AE2A6339
+:1051A000657ABB2A999E92769595F9FF467287B5E6
+:1051B0005951EF4E820789E4C04D195CEE8E533F82
+:1051C00023FA9CAE5035C4D7C1D0272EDC8F1FFCEC
+:1051D0005AE5FB607FAEC18ECBC9E27E814D763051
+:1051E000C8E0BB4D3D9C9195D0D4EEEF5F96DF4675
+:1051F000F4D11E1E8574FC8D8DE470B2F1BA432A81
+:10520000EB078C3931A41094F42B0CA530AB4E3F36
+:1052100014B2C4E3EF9FC5C79F7B07B368D06F6626
+:1052200098F913ED8F653DD8178FB732AA1FCD843B
+:10523000F12DEA6721FE94FBE3145BD8DF13E66FE0
+:10524000DBB9248CFBE442181F8E4383F1A1BE2CF2
+:105250000AA551B938944DB06F289360BF504F7A6A
+:10526000DF3FD497E025A1227A3E203490CA25A1C1
+:10527000A1042F0D9512BC2C7425C181A037B1DE7D
+:10528000A05025C1C1A16BE9F990D075042F0F4D35
+:1052900021E80B4DA3F7A5A17A8265A15A7A3E3485
+:1052A000349FCAC342B752B93CB484E0F0D0ED0495
+:1052B00047849A0856845652BD91A1BBA97C45E803
+:1052C0007E825786EE23382AF428BD97764BAA585B
+:1052D0008F776B333DE8EF000ED7908F93ADBB997E
+:1052E000595C2F1DC8F44FC82A8FD7B35B408FBBC2
+:1052F000BAD60B6671BD9189744DD0DE3441AF537F
+:10530000BE630F0D6071BAADF39EDF9FC14A12EF0D
+:1053100037E2F281CFEFDA2C2EBF36595BFD2AF24D
+:10532000EF62E60BC3A389C35E5750BE6CD6AC5583
+:1053300089ECBB07B26CF4DD2399C1F95900D38A1B
+:105340004EEC45793239EC797534F2CBA09CDF8C88
+:1053500086F60A9B2DB4DDD7986737FAD7B4B18C9F
+:10536000E4A2F42B815D67D0A7EB055E18DBBAAF32
+:1053700098D653BF32AE7FDAAEC1F565FF7E31ED10
+:10538000DF37D9A38A15ED9BA5A0C374F6FFA63518
+:10539000753FC1F7F1F6EC34CEC2B5EC2534B18BD4
+:1053A0005AB4D12900FB6EF4BF94029FF48F0447D6
+:1053B000A74279C0D3E197105EBA35323A0DE0C00A
+:1053C0001DD19750DC0C8EB68D7641F9F27D6C0FB5
+:1053D0002EFFD2566D8C1BCA430FFBF7001BB0F299
+:1053E000B6E098740DC713694A87F16CFA000C3D5A
+:1053F00028577CD6A2C276284E7FB0E3D07E937425
+:10540000710F6B1D9B0DFFD96B99A754C5EFAD6D47
+:10541000299983BAD26733CE1BE7097AE4299857D2
+:105420002F7F54F1E8F864479622E9F018F29BF4D4
+:105430004B6E6ECE22BFE4E6544F2576D9318E797D
+:105440009ED0908FAD8427FBEA62F2C749BE03FC71
+:105450001AECD9F582EF3675DABB89F1BB43C8BFC8
+:105460007F15FC7E5BF07332FC3A9157465E781DE7
+:10547000EF17EB12D6F1CBC8DFC9EA9D12F837E37C
+:1054800079B385ED035D05FD029FF275C5D08FF6FA
+:10549000B1E0EF0BE1F5F8BF18DF462F8057A6E526
+:1054A000909C047EBD14FD63C9E48D5DEC67CCEF78
+:1054B000635DE51CF7DB7A40CEF54D2EE7F666F12D
+:1054C000E749E597903376937FC796CDFB1BEA09B2
+:1054D000A8D989FCD4DE1C839F7A82EAA94479C3C7
+:1054E0000630B2A3D30645C2B84F290C6B652A56C5
+:1054F00043A18C78EC5142FE8722B033AC407F68E8
+:105500002A8AD0A9792C75E87F97EBCD53EBD5AFDC
+:1055100037A9EFE3EB51F245D6E6BBB85F529B02E9
+:10552000F6CB5831EE783BDC0FB2E67B3D36DFA59B
+:1055300093839BBD5E2ACBFAC9F8B72E5BF06FF35D
+:105540002AC2A7735462BBE15BD9AAE0DB0E3FF22B
+:1055500079F85BCC83F64C66F331924F99209F1417
+:10556000924FBCFF5EA1D49F84A17C55769EF00330
+:1055700078526F74FFDFE3E72CB4A9703D8DF2EC35
+:1055800056314E037A48C3753A0AC63E0CF1652778
+:10559000BA6B8CD3511BC52268F702DEA2B86F0F1D
+:1055A0005BDCE467B2DB5BFCB89E993D93E63FD4DD
+:1055B000139C907D9E75E149D34A91A8D3EFFFD902
+:1055C000352EE0BF35459E542CDF0CE5F515D06F28
+:1055D000561B13E575AE91DFDCEF313DFBB9FDCD18
+:1055E000D0DFAE2CFF341C0FF0F57484FE011E2BAF
+:1055F000F9ABBDDDB307E4FA8CAF274FA95C4FB51B
+:1056000083481ECEC176657BC9EC9BA26C2EE74217
+:105610000226B36F24DF5FB47D23C63B3BFBFCEB6C
+:10562000FFAD7DF76FDCC274FEC61E0FB55A35F4B0
+:1056300067703F8DC5D94AEDB985BFD18FFE46E071
+:1056400003673F5EC6BF44FEE2E4788CD078A49F37
+:1056500051FA13D3055F31AB12413D9E5EE1B1D6E5
+:10566000517B6DEC3BD0DE83024F725DA3DC7A7E12
+:1056700010CAA52C2BEED7D19FE4CE8AB78FE58C2C
+:10568000B2B87C62621F77AB1873CB2A5F06BA9CF4
+:10569000C307B91FA5E5877C5D4EECC522AB504E14
+:1056A000F899E681FA294CFEF90DFEE4095F29CC50
+:1056B0000FE33FF0954A50E9C7A26ED8EF4DF429A9
+:1056C00051DC07DA2DCE08EAD2CA1E4E86F14D7B98
+:1056D000BA2582F111FB3185E6692F4B8BA0F01BB7
+:1056E000DBA32203E398670EEC710513D0FFA660DD
+:1056F000ADC1FF65C66367BDE92F7B108F8F5E204C
+:105700004EBB37BB334EBB0BF974D2CC8E66BB1687
+:105710008FD3CAF8638177FBBA4A54590BB87DDA44
+:10572000834556EAED2A5D1C741FB6F3683C0EDA19
+:105730007A893E0EDAD86327DABB3FEE8C83067F88
+:1057400085FAC49FBDB514F9F751DFF667EE457CC5
+:105750003A44BC62E81197867EFAF23DB9389F5709
+:105760004DE39750FAF1CCFBE0C3D9C6F8C219DF7C
+:10577000751951E2ADEC84EB5BFA17E57E18FD87F5
+:105780009E84EBD0886FD97F8DC2F7B5CCA670F917
+:1057900027F428C8974F480E4418E94DBF437902B3
+:1057A000F5CD19DF501FC53D93C81B391EC063FFDF
+:1057B00044F15FE82F619CD59AC3F5588D8DFB4D60
+:1057C0009525E58B715C356E97E2D0F9FB3B84BE85
+:1057D00033C785D48CAFCB83C2EF9D68FEE6F84E0D
+:1057E00087D017882FBD9FFC42F83A6C6BA1F8E177
+:1057F000E1592A5B09ED9C098EC86709BE97F05DE7
+:10580000E49BFE0073787F9DF44C122F3ABCA2817A
+:10581000E2CCE6785AE7FBDA946AD4DFD588475DB4
+:10582000BFE5395CCF4F129039829A07DEDBEB1E61
+:10583000F4308C7FF5FFA23CEC46BF58C70B18BF75
+:10584000603F7093BFA2BAF6CBF2958375F8AC6057
+:105850003C3EBBE7C71E0D9E57F76FCE0DBB92E3D4
+:105860007112B60578BA1B1F8C247F8C2F87FB37EB
+:10587000BBE58F6183785C88ED49A1F869CA9BAA72
+:105880000FED06EC97EB01EE4F5E26E226E6385E62
+:1058900075689141BEA4C51416D1C52FD2AC5BC9A1
+:1058A0003F9B16B3D273F37ACBCA81F53630BEDE96
+:1058B00024FE93D153E2DFFC7CB0C0FBE1DAB91ADD
+:1058C000FA0DEDA989EDE066514F96CDF908C9E2D0
+:1058D000EEB5627D9C098ECC477F55B53DDCBF3B64
+:1058E000EB5CE2E742790E37E7F0FD907BEA1B22A2
+:1058F0008EA736636B52AFA659CF1F8FF59BE2B1CF
+:1059000069C3BAC4F3FE29F1D81F9AE8D7DD78EC51
+:1059100078B11E2F94877293DD68F748789DA0E3D5
+:1059200099600A0B837CBCB552A53814F007E9C70F
+:10593000C30F2A646F466B1DA497EB6B53C83F5B84
+:105940005FAAD2FBFA0D2AE9CF28C88705201F5E7F
+:105950001572C2EC9FAD648A217E3E69588AA13CD3
+:1059600075D6FDAFAE40FF72854DC3FE0E6ADCDF1B
+:105970001CF6AB64BF421BBE28FAA71FB8CA87FA41
+:105980004CF2C341BF4AEB2D7C48F561B7ADC21F55
+:105990007D706D6904F35498128FD36B7DB1FD7ADD
+:1059A0008A03BFE3DD4871CE94BF3E1C08D0FE31B0
+:1059B000A89592DEE4F1D314B14EC7F4A8B811F55E
+:1059C000F887EB6D0CFD461FDE7186D673DB8AC54A
+:1059D000941721FDCBD23F6CF6339BFDCB5DFCCA07
+:1059E000267F72B27C86977212C7EBA5BC4AC61F8F
+:1059F00020B6F67F133926E5C7BB629E637A6CDC5E
+:105A0000B012F0903653253C48BE7CE7EB3B1F4775
+:105A1000399C02FCB18A213EFFE365DC87B0B94ABC
+:105A2000423F72AA94EB983F5112A7CBD4E0DCCE50
+:105A3000322EFF690D4B0C791F66BD925CAE9D5FE7
+:105A40006EADCFE1FE0AB3DE31AF877FB4DEA9AE23
+:105A50007DB004BFAFAE9D1541B8AE87B301E5AFD1
+:105A6000593E98F5C47526391BD70F2A8B0CD58F54
+:105A70005BA37A713D61A7F7675378BE43C8C9E15C
+:105A8000F2D4F427109E4DE1F90E61340AD14EFD97
+:105A9000202DD244FBF2C523904F42CCD716C679B5
+:105AA0007A53C98FD0D28BD753AF49E576F9DE4A06
+:105AB0009AAF2A0DF3E64A5A374D622E3FCE0EF6C4
+:105AC000C885F134F92D29185F18E3B6EE47D74B96
+:105AD000CB680B73B038BEE27921CCA3C0F7F44E8B
+:105AE000C1FD67A9D3DE97ECD4E25CE4CB1FC2FE14
+:105AF00010F8FEC00175FB6698EA01DFD08C447691
+:105B0000BA84E638F291EFBEDD07D7EDEF59703079
+:105B1000B6D75A5DBF01E3C38D3B548A2F4DBFED0D
+:105B20009D4BC8EE36C529D5746709FA539A94542B
+:105B30001FCA1389C7DD6E3BC999A62369B49F6844
+:105B40003AAA88B29BE4A1C4FB5EA857300C7395B7
+:105B5000DC243725FE615E57217E241D2A59F4C0BE
+:105B6000A8A2BF6B5E55E79F572F0FC90FE43335CF
+:105B70003E0FD56DA5F9B5B3541F8E2F24FC43EC11
+:105B8000FD34DAFF493A370A7E94745E24E8DCBEBD
+:105B9000F3CB7BAE84FA2DFE2C8A3AA8BD19E1A185
+:105BA000FD7D37F189C4839C37F0C574FDBCF7ECEB
+:105BB0001C7A3888DFA7A7521C5FDADD32EFC03CC1
+:105BC000FF1AB17F6FC8553AED5EF45FBC9A3DBADB
+:105BD00021B73C417D61EF02BEE763BF951EF645EC
+:105BE00084C5F779C9F21B96E72A179BDFB05CDF03
+:105BF0007F677EC337A7E7AA8BA167A3D5B556C930
+:105C000088E35BEE9B69496B5DD7BF79FD497A28D4
+:105C10003B77FF19E3F866B9B05C5DCC14E867CD5B
+:105C200060BE2ED91D4CA3FC20D37AB990BC01FADA
+:105C30003F8E74482677BA4BFFA7BBD2FFE9F3D15A
+:105C40007F4376E0A7F81EBBEA5946FBC267B18CDA
+:105C5000F2C45E4CFD11DF766432CA6793F931728B
+:105C60003C324FE65798B49AABCBC329F129A82709
+:105C7000BAC11FBFFA07F3C72BE7E78F28ADD3855B
+:105C800082FE0B655EC6F6F3E76574837E6F26A21F
+:105C9000DF72D5D7112CEA3EFDDABAD2AFEDFCF4B3
+:105CA0000B1E277D62675F90FD5E51EB457E19EA12
+:105CB000F14FC6B8F9AE9542EE1401FDE0FDCB39C7
+:105CC0002AC9B51FB1CB486E7FCB62A1F1B683BCA8
+:105CD0007E42E9D63CCF90DE61616B16B4BBFC3AE4
+:105CE00046F13DAFB652C172BE067A5AEBFE7CFF5A
+:105CF000D675BE7FBB80BC52F272893F97217F3A36
+:105D0000358FF57CF2CA9D67B413BAC18FEEBCDC47
+:105D10007F283F7AF32E42AF7603FFC5D85E323933
+:105D2000D1DD3C5058A7AC6756D7FE19F3515CAD96
+:105D300032DDC9F5F63645E8F1D22095DD4E121672
+:105D40007B859E3FBD9DBF574727B62B07E6651154
+:105D5000FE176E5D12B01AF249C2F4FC5EFF694F85
+:105D60003F15F3B45D349FEC89DC0F29E72FF3B4C2
+:105D7000D3C57CB27BF379671FE179ED125FE962ED
+:105D8000BF91516135EC2324DE96AB0105FDE89906
+:105D9000390CD324609F3048413F57A6DF585FE25B
+:105DA0003B97ADFF5CC594AF2AE3FB5CDCCF0CC135
+:105DB000F7BAE709F6AF409F12CC1FBB314FEC4F4B
+:105DC000ECCC8BFA88A935E7E523DDFE647A5E37F3
+:105DD000F627F57932DE6ED47B5B5358423FC3E73A
+:105DE000623D80BD42FE6655E8B9B16D4594EFB2A3
+:105DF000D4AD91FF41557DCE09455DBFCFF4C3F2CF
+:105E0000D6E123BB2A9569BA79E706B20CE5FCEA2C
+:105E10001E86FA05C162C3FB9E0D9719DEF75E5C14
+:105E200066281786AE30D42F02C4EACB7DD7FE9BFE
+:105E3000A17EFF96EF18CA0336DE6CA87F69A4CE58
+:105E4000F07EE0D3F30CEF076F5D6A285FBEE3FBE3
+:105E500086FA4DC28F6CC6CBF63C6E173559B91C0D
+:105E60005AE92A23FF6693CBE8DFBC47D4ABCC18B2
+:105E700055827EF5A663A52588EFBDE957909F3D25
+:105E8000195F98E55A32796A7EFE9CA0F7A997ECD3
+:105E900016E4EB457B60DD5E0E65D7BB6B704EEBA9
+:105EA00006F1F8AC8DF17C2119AF91DF77C66BACB0
+:105EB0003EEEAF4D77B1BB12F0C53D795A427FAA95
+:105EC000E4A3647893FC7821BCBD20EAFDBD787B17
+:105ED0005FE1F9AE7A7DB02DC1B84E897505FAE65D
+:105EE000B53C6E0F0D4B254BDE43EBF162F5811C8B
+:105EF00007E8837751BF98F3744F55BF31FB610DAD
+:105F0000EBCFE6F52DBE12A44B327FFAA9BC2EFED4
+:105F1000F406EE4F4F35E0ED7DB9DE4D7EBDA6F4C3
+:105F2000AFC89FDE64F79574C79FFE3E7C8BFDBDB6
+:105F30008074CED5D157F8E393EDA3428CEDC7F32F
+:105F400010CC65D5F4FBA664FB6329CF617F5C822E
+:105F500071DA16DC7F2909F5A035BF9CF6CFA40FB6
+:105F60005A400F3AC84FC0F66B505E3EC6C2EED2E2
+:105F7000E2F396F6BC83F99C7695E89A9A8F78F9C5
+:105F8000215B96A2FE43F699B9F917A1E7D985E3FB
+:105F90007D64A74D84F9AFD2EDAF257ECCF13D896C
+:105FA0009F893E1EBF5B0DFA11E37BBB73B99E5EFA
+:105FB0000DFB6FC4A3273BE0ED83F63C3C7F02C999
+:105FC000913B9CD68FC4AB39CED75DB933229FF3BA
+:105FD000A3CE8E1B919FC03F133FAFC2E7BF54ECCF
+:105FE0009FC7A983B6A21FF374CC4E785319CFBBB9
+:105FF0006CDC676311A223CF5F9674B4C5D6B4A2DC
+:106000007EB63173BEB29681F3B7EDE3E7C4580EA6
+:106010007F1F66CE9568F7645418F557A6DFA8BFB2
+:10602000B2ABB24CFACCA8BFF2AB8DFAAB2068D4BD
+:106030005F3D1BCA4CFACCA8BF0A43A34DFACCA8BB
+:10604000BFFAAEFD8E499F19F5D7808D46FD756963
+:10605000C4A8BF063EBDD4A4CF8CFAEBF21DAB0C96
+:10606000EF4BA37719DE0FDDF72343B9BCF51143DE
+:10607000FD39FB7F4E793D230E3F61A837B2EDA776
+:10608000867A80F056CCFF9E492461ECCA93CF1BE0
+:10609000DECF14F6DA551DBF34B4C35A781E771814
+:1060A000FE21BD3E62413B1A2956D6F14A4FA0EB74
+:1060B000A288E28B42B5B93BB60DC7717CFAC135F7
+:1060C000FBB09D391B8DF9DF7323C672232BCE40A5
+:1060D000B9D0087C11013E998F79E13AF9369F2DAC
+:1060E00016E702BBC76773F65FC7289F34EC6FC51E
+:1060F000BC77394FC96F7EC16F727C72BEF3C1FE2F
+:106100008B6AF179FAE11FDF6FB6D9916F67EF50B3
+:10611000D8234AD7F934ECBC6F4DCF04F332CFC348
+:106120006C87FE24DF183F19A7BA285E70FA90EA40
+:10613000E3FE46E33A5CBA9FC709963EA790BFCEFE
+:106140008C0F699F26C38B1AE6FB86C61C1689E84E
+:10615000D69F26F0E1F01AD7DF69FC0F1CCF636AE7
+:1061600004F38D52B45433BF0D8FB2AE784E2B3141
+:10617000AE53339EDDBE1E09F94A837F388ED9E2C5
+:10618000FCA199AFCC785FB4E33E3BCAC38BC5FB9F
+:106190009BF989E312A0ED86D913E4D749BCC2BEAE
+:1061A000FD3DD423C9F6B31FE55FF47EF6A3FC7F63
+:1061B000EC7EF6F4F9F45C3BFADBC0BE34FBD9CCE0
+:1061C0007A58D9B9E7CF4A3AF9B5DB1CB8EE823E26
+:1061D00027CF8331E9C99212839EECDCF71E536806
+:1061E000DFBB2DC3AF78613CAF64F82D08A766F81C
+:1061F00055AF6EBE4D80173AF7037A6A5B023BF1EA
+:106200006AAFB48F02E437595DC9EB9BEB0DF0F236
+:106210007342BB73877BC9FE3C5AEA25FBD33DFC26
+:10622000BCF6E7BD224E7437C621FBC7F383368820
+:10623000780D2C3B3FD26DB52DE0D5E70FA77A3313
+:10624000499FA68F7CBE15F3A89B3C168FA221E424
+:10625000F9DCCD2E6BD516F15D8EE13B3E4E15F18E
+:106260000D78B5BAAC5FE9F9F66A2FE3E7AF92CCE7
+:10627000F36A2F8F13DB587003DA43323E6C3B56C0
+:10628000E94479D7C4FC1E2E277D1E7DFE878DF143
+:1062900078F068111F96CF55CF37CBC3FA6D46F013
+:1062A0005BDE047958CB32FC57237D43D6B003ED37
+:1062B000CE9033F1BE789C57C4EDC47CC10025BE9E
+:1062C000A271A8171FFF017B3380FD2E57C39427AF
+:1062D000D9E41E5E127475DFCF35CDDBC53E9AE67C
+:1062E0003D8F7D04F6E9643C47E6CFE861A56D8704
+:1062F000D55782F85E8BFF3D92FCB475889F2E794E
+:10630000AFE21C2EECE3CE9BC72BDBD995E59FEBD0
+:10631000E5F986F3B13DFF004FB3AA6B27FD02ED0F
+:10632000483F4737FC56DFF326F05B2D577D27515A
+:10633000BF77178FCDDE2EFEC266EF79FC85678FA3
+:106340000CC8C078B6F47799EBC97391B2BC36D358
+:10635000D8FF9A325EBE57D0EF77E27E8A27C538E3
+:106360009CA6F3A2CE098CEEE990E74C653B4F7AF0
+:10637000DD54FF8EECD14FE278D71429B40F5D9332
+:10638000A918F6A3B7782B9F447A3C2EFA7B52F0DB
+:10639000EFE662EECF31E761CE11F5E7784713C43F
+:1063A00073AD28C7ECAA9A108F4F7BF9F8274343A7
+:1063B000941F27FC6EF50F2A62FF64BC1701D6F903
+:1063C0005B69207F8EAFB7D1B9D759AA6B0DF26345
+:1063D000B27B0E6A070528FFE9EF3D3F86F84CCBFC
+:1063E000EAAA57A3DE4E7BC67791E7C87ECDF1D3EC
+:1063F000BD787F5B2AE7D30EB78BFCE6E67A4705CC
+:10640000FDD70BBF06CA75D42F592A5B9C48CF1CF9
+:106410001572F59B9F6BE6F77964BB5CF49DF95CA4
+:10642000739BBD6D753E8EF72AC587E717F26B3CEF
+:10643000BBF373F01CA3463EBE35452CBD02DF976F
+:106440005AE87DE6F59E3536CCFBD61866EE331B52
+:10645000F4E3867E520A781C677DF8BADDF9502F86
+:1064600043EB60C583E8BCF7782FAEDB6A9E3F6FD5
+:106470009EDF57021FAED5B0BF407C6889F3D0BF06
+:1064800012780079F367A447A5C6B6F373593C0F99
+:1064900016D992F2157D3C5F3B0DF39DFA7279831C
+:1064A000EFBFCE1A730EBF93EB4B15F8369FE74E36
+:1064B00029B8B8F3DC936B128FB75F01E787C31974
+:1064C000818C02E877F2A895DC1FF6F5B973EA70C3
+:1064D000348EF93A81EF19FA2B5272B81C4ED1342E
+:1064E00092CBCCA3509EAB53F3356039C57585472D
+:1064F000453BD9C1E3926CA685E1FD2A63443BFE8E
+:106500006AA6FCA184FB65B99CB5B23F48FE57055D
+:106510007286A39EE57F603FAD4F83F98C711DA00D
+:10652000F8644ABFC59578AEE1E519BC8D1F2539E1
+:106530003720CFBB779EEB0F470E18CEF5DB1E3D05
+:106540006038D7CF1E3DF0F79CEBAF2C78F4C03FFE
+:10655000F35CBF946787D5E0E1DB01FF370053852B
+:10656000CA105A590DD1DB4B78BB5EE039FC15E0FF
+:10657000D919C7F30D3BF713FE0EDB60DCD0BF6DFE
+:106580003447B5EDFB199126928B11EAF74667CB9C
+:1065900038DC77B6DB3B8660BFED2FBEDD3B0CF20F
+:1065A000E4C80FCEB819F0DF87D60E373E3F79C763
+:1065B0001B6EC4D7913B54B2D7E85CB42E1FA95EC2
+:1065C000F0D54B05819B91AF66ACF8EB70BD3DCE2D
+:1065D00042B9A47FE746544ABD92F26FFED3698266
+:1065E000E97879E1D66C4359EAE5858EC4E7D41F92
+:1065F00011EB62EEB39BED3D35EC3FB800FB3F295C
+:10660000F21B4E6E77D33E4C8EA7EED9523BEE3B3B
+:106610003FDCE96051F203B7DA18F9B3FC13943C9C
+:10662000BCC788FF99C7F9CAAE346A6FD6832AF906
+:106630009D6AA1AF10E035B8732EDF079BE631EB02
+:1066400088361EE5D5AC750A0B6BBCFE1D787F46FF
+:10665000E84E8AC398E769D62F7392DC9F3367E7C9
+:10666000DDF4FD4CE6BF1BEDD9592DE6F7D77C8450
+:106670004C3EE702F19C7B0B84DE19CE469CEB4B33
+:10668000F1A38CC1DA85F5CEC9157C917EB2C249E1
+:10669000F0B3151E823717703E9EBF63F72B3D691E
+:1066A00099B70E47BDF4D6BEFAB49BB5B8DD3D7CB4
+:1066B000F3AD7B1EA5AAC6FCCC1A81F711222F735D
+:1066C0008E38F7507EF8FC799935888F215DC72B7D
+:1066D000EDEC1A93DF57DADD667C9CDE37260DF988
+:1066E000E3F902B1CF1D017851FF7EBC24FB6EA1FE
+:1066F000CAEF4D333F97EBE866C1D733B74C59D358
+:1067000003FA6F7AF1A33E6DC4A7DC7F512EF055DA
+:10671000EE5AD38AF32F6726BF61981D623A7E0630
+:106720007E5251EF98F956F2133BC4BF770ABF4629
+:1067300027BFEEDC40F8957C85271D2C68C381E5DA
+:1067400062A9B8F03D57B35A8CE553B6B63E284F10
+:10675000E698FC0DA794C4FBB7BD05C51C0F9A7F36
+:106760003CE65FCC628135DC3FCFEFC739696D799C
+:10677000E5765CE75BF83A5BF88BE7FE1BE5D7BC98
+:10678000FF7A301DE5D7C7D6963CEC6FC153ABD32B
+:10679000FD28C7ACE174FCFEE3889AF01C71510F30
+:1067A00045E6EBBB304F6D11B11AFC6F667812CA2B
+:1067B000CF3F3D65F3A01FB6F16947D401F858B447
+:1067C0009DE311CA4779F94EC257E30EE3BA9CF72D
+:1067D0001F0FE669E40F08F714F8EB89227CD11645
+:1067E0001BE5B52E3AA4FAB09B46D641F3337F8F12
+:1067F000E38801DD1AB7AAB5F68CAEEFC112B2E399
+:106800007A6BDCCEE9D9B89DD3ABD164873608B9B1
+:106810006DE6FFCC1E46BE07FC905F4DE6DBB2087E
+:1068200097DF4DCF3C3CE4288CEFB32DBF4D57068E
+:10683000C5F99F615628E0EDF4D6FA19F6F3DCD7D6
+:10684000734AAC934EBD20F490B60306960FC59DD7
+:106850001C2EB045D3AF04BC2CD86CF385E1F1827B
+:10686000E754BF0BEDA8771C74FFC4FCE75E7EEB1A
+:106870000A18DFFC6DB69C097C1A2E94DF925E8D9F
+:10688000C8E76571FACCFBF9CB76CCD3C4E7776463
+:10689000C5E9347FDB6E3BE67D9AF13966EB6E3BF2
+:1068A0005F6F267A6D3D3A1EF576D33367EDC80FDC
+:1068B0001FEF52587E51D7EF1B36BF9C8E7206F1E8
+:1068C00084FA45D2AD938E5DE8179DF4CB6154CF29
+:1068D00083719E0BD1F1733C83504EFCFEB35FC2BB
+:1068E000381ADE75F8100F0D3FBB351DE7F39175B3
+:1068F00031E7FBC757E7A1DE6EB085F33C04F9F33F
+:10690000864DDF257E9CF3FA77F97D4ECC5F80EBD8
+:1069100019E65B80F39CF5D80D34CFD92C48FCD810
+:10692000F038BFDFF04B2BAB4AB41F784CAC9B8FD9
+:106930009E70D0E6E1233BE3F785FC4E15F7612D11
+:10694000217BE5BB62CE20A1A9FCA553D0AB878CEF
+:10695000FB73F9D6286A356EB993E4DB27BDFDF9E0
+:10696000B8FE010F46FFECEBE3F2855CA47B5DE82B
+:106970003BE0BF31F81CEBB7DAFC29430CDF89FCA4
+:106980005BDEFF32D13F8C3B15FD7C1FE519F7B96B
+:1069900012FEB687F4ABB156A6E7B3647260CB3A89
+:1069A000E2AF2F0E7139B32832A58ADEB7DAA2F929
+:1069B000F83EB2FB7A85E404D82189D6F9169B58B3
+:1069C000E7C6F7304EABA2C7EF2E7E7E4FF2CBEC80
+:1069D00007A0BE6E5DC7F9C71E7F5E145FAF327F32
+:1069E000638EC99E93D02C271E32C909F93D7B2C9A
+:1069F00037E1F988B87C0813FE16D8223F7904D70E
+:106A0000F53B0E3A17B9E0391BDDEFF3E9B37BDE56
+:106A1000BA19F8FFD3AD723D1BE5AF793D373C7F26
+:106A2000034BB49E3FCD09B084EB199E275CCF3950
+:106A3000FCBCC1FF29F93B2789FCDDDD43D8633A63
+:106A4000BBE34A287EF2D3F985B43F33E157E2D560
+:106A50002C4FABD158C8ED2A4FE1EF10D3E153E2F0
+:106A600051F2E9BCFF5C48FD74F2B3E457C9CF9D15
+:106A7000FC6A9EB7119FE6F7CDB877CA8DD3DFB613
+:106A80000AF6E518AF7D51A5FCBC76AD233D0BFAA7
+:106A90005D2DF27BDA3DA29CC9CB1DB9F635284F9E
+:106AA000E4F38E149EEFD01EE848CFD4ED078EEEAF
+:106AB00054D3F13C405B24715E06656CE4E2E9D698
+:106AC00064EF57D27A684FE5FEBEF654EEE71BA797
+:106AD000BAFA84707FD7C2E34B3357DE948EFBFB48
+:106AE000F69D7D2757E37E60BFCA738EC27E6B0121
+:106AF000E0B79E4F9D9D64E18746A1FDBE73FE04F5
+:106B00006C67E67A235E66BBB6D8B19D2FD91D04AB
+:106B1000673F608BF309FC6F1EE66B219F3F667A2F
+:106B2000BEF35AE2AB7926BE0A225F25384FE2EA6D
+:106B300029F8AA9495F2FDB6888F09B9374E1D340D
+:106B4000B91AF329F7F1F31EA777AA6C0DCEF759FE
+:106B5000112F0BE712BF2E02FED6FB4D3F43BE1B8B
+:106B6000905CCF7FF6C291E1B7439505FFFDDE90C3
+:106B700047017EF6DFEF5CF22B2CFFE2ED3EEFB13A
+:106B8000AEF5C7ECFAF32D94D7B9CB41F79AB6EF2F
+:106B9000FA759FDBB1FC4B07DD2FDABE8AEFB3C37A
+:106BA000BBDCA4FFDB7B737BB1E9C5B343DA487F71
+:106BB000F17B8347F4E4E73E4EEFFCCB070AE6F3B4
+:106BC000ED8459A17C14FBB7C65FA6D03EBDFDC5C0
+:106BD000B386FDE9DF3B9F45E2DC55BB9B55E339BE
+:106BE000E9F64C7E4EB5F157239FC473970BB7EF70
+:106BF000B6D7C3FB31FFFBAF43500EB53FCFED0E11
+:106C0000B08737311F63A31FBD67830DE8770A6D17
+:106C1000445833EF3D7A7062785022BC703CB40324
+:106C20001E705E809706949FC9F031B5273F7FFCA8
+:106C3000AF878FCF6FC1FE17EC1C41F70CC7F1A2D5
+:106C4000F8F97337E57BC0FCF9F35D6787A01D7524
+:106C5000A1F92EFFFF6CBE0FFECBCE97F37BEF9E0C
+:106C60005C1F99F9BE2B5FFFE2362AFFCCEDA3F142
+:106C70007673BDBFF02FBBDEFF39F47EE35F76BED7
+:106C800017A2F77E416FB707E332ED2FFEB50FBBBA
+:106C900088799FFE7F74DE9D768FC5E71C06E37BB7
+:106CA00097456EA85492E78F16F632EE33E43DDC3A
+:106CB000937266931D31C9CFFD314DAC6C1F9EB3ED
+:106CC0000BFB558A5F50F20EE0A1F5FAD208E58978
+:106CD00059C3FD1FC2BCB11B17FAF87D65C6FDD7AD
+:106CE000A4BCAA2AB4E70EAE847141BD836E8BA703
+:106CF00009A630D9AF92FD0790ECBE37475F4B79BC
+:106D000028932B8CFB909B4DFB899BAA8DEF6F6486
+:106D10004FE462BEDF8D0D36CA4FBAC154FFAF3D9E
+:106D20003D44D79BD8E2D5DC9F7371789A2CF0D480
+:106D3000150FE7C75B173C89FD26E50E695DF1E697
+:106D400008F2FDA7035E087B4BE4E52DED163E99A6
+:106D5000D8973A44D712BF0E3FBF7754D72EE1459C
+:106D6000E2FD62F12DE964C6BBC4AFC49B990EC5B8
+:106D700078DE53679FC7A1F15E6D26ECC6499D760C
+:106D8000A38BF0F8DA167E5EE2B58AFAF5A5587E96
+:106D900096DF07FFE5A8A1CC09F33D68633B282EE9
+:106DA000E4F76B9EE1F1FC19A5E2D7149FC0FC4506
+:106DB000FD7E15F317F5F3C2FC457D19F317F5F5C4
+:106DC000317F51FF1EF317F5EF317F515FC6FC4550
+:106DD0007D7DCC5FD497317F515F1FF317F565CC74
+:106DE0005FD4D7C7FC45FD7BCC5FD4BFC7FC457DD6
+:106DF00019F317F5F5317F51FF1EF317F5EF317FCA
+:106E0000515FC6FC457D7DCC5BD4BFC7BC45FD7BD7
+:106E1000CC53D497313F515FFFEAD84B867225FBA4
+:106E2000ADA1FE18E71B86F238CF7B86FADFF61E8F
+:106E300037BCBF46FBD4F05ED2FFDA923386E71848
+:106E4000FB080FC77D0CFF9BE8FB8BA11D2B0B5094
+:106E50009CD4CE161374A2BF17602ADB4AD005CB90
+:106E60001CE18901C1677A21BF6E0AAF41E63A3859
+:106E7000F26C1F94FFAF8DBA8EFB25447C6132FE0D
+:106E8000A7064C9CF6752FDCE7CAF8697A4C65D1E9
+:106E9000A1C0873185A02796C6A2D9C087B1148228
+:106EA00059B16C7A9E1DCB249813EB49CF736305BF
+:106EB00004F3627D09E6C78A087A63030916C42EC3
+:106EC00025D8233694BEEB192B25D82B76253DEFFC
+:106ED0001D1B49B04F6C0C3D2F8C5512D462D7123C
+:106EE0002C8A5D43B038761DD5EB1B9B42B05F6C9E
+:106EF0001A3DEF1F9B4AF092583DC101B15A8225BD
+:106F0000B1F9042F8DCD257859EC56FA6E606C09D5
+:106F1000C141B1DBE9F9E0D8F7080E893511BC3C75
+:106F2000B692A02F7637D52B8DAD235816BB9F9EDA
+:106F30000F8DDD477058EC517A5E1EFB31C1E1B117
+:106F400027098E886D265811FB4F822363CF10BC12
+:106F500022F673FAEECAD83682A362BFA2E757C5FB
+:106F6000FE17C16FC5F6D0F3AB63BB09FA63BFA5CB
+:106F7000E795B1FD0447C7DEA0E76362AF131C1BB2
+:106F80007B8F9E8F8BBD43707CEC38C16FC78E1298
+:106F9000AC8A7D4AF09AD8C704FF2D7686BEBB36F0
+:106FA000F639C109B1BFD0F389B13F13ECDCFF8FD3
+:106FB0004AFABB029673B87F766575EBBEB2FBD218
+:106FC000D2492E4EBA83CBC587D34EED253939D25F
+:106FD000A13948F86D34C4BBE8472460DFB77BE4CF
+:106FE00047BDD0DE595379FCFD5B519F2D7130A117
+:106FF000CF4C72F76B97F07732CC479C2EF8FAB5EE
+:107000008A3DB96847AD296B5B807E930D456D3530
+:1070100008F37A73BFAC5BC09CDE3C5FE12F03B822
+:10702000FEAD59D29FFFBE404EF7E6775D2FFE9D25
+:10703000ACFF751F0FD717AE8E3E745EAF9BED741D
+:10704000B7DE85F2B062BD8297F5CE3DDFF9C16E45
+:10705000B733B477827CAE6FD0CEA8EEB4F3A1A0E4
+:10706000FB63BD037E1C3FB3FA87E0FBD1AB0A5440
+:10707000FC5D95DAF58A07F9A5BEB9743CD2B58CEA
+:10708000F9C92F393D493ED96C41D7BAC53686FE7C
+:10709000C93A8D917FB86E3BCF43467FEA44E09773
+:1070A00006C12F0BD77D4E7EA786C57378DE53842D
+:1070B000FBA7E4EFD8CC6FD9FC0ABAF5BE64072869
+:1070C0003F7EFED346FF55A3F04F2DDC6A7ABEF813
+:1070D000DB09FD9E66BFD48CDEC22FE5E3794F4C01
+:1070E000ED45F3FE12E68DF924C1DBDC4ED41B80A6
+:1070F0000F8AC3483C48BFA7C407EB7AEE82F25719
+:107100004FEFEB4F7972A7352D1FEB05D3F9EF59F0
+:1071100029D6E0087C0E78A47C968E9569940F752C
+:1071200014F4808689579EE008BC3FAEEDDDDE4C4E
+:10713000DC5F698C4738D7539E782D8C01F3526AF7
+:107140009FCAA6739BD0DE901DE8D77CCA46F9483B
+:1071500061B6D4CB2ABAC62B02AB6DC417753B32CD
+:10716000797E5AD87F08CF1548BA1C6DEE3B1EF3C6
+:107170009AEAD6169592BB6E878DEC43199795F4D3
+:10718000EA9ABFCDF3051A59640DA62E01BD4E240F
+:10719000A457CB6EA22BD0ED4412BA9D381FDD1E32
+:1071A00032D10DFDD437E1CB3BB2693DD7AC8AF685
+:1071B0005FACE34FB3FF9FCDBC82EE3D91F9CF555D
+:1071C0003DE4EF8CF9F290BE67D69713DDCCF4AABC
+:1071D000FA5B3DD185BDEBA67B87A7F76533BE0380
+:1071E000CF6708BFE7F4A66BC8FEFEAFDE7C5FF09A
+:1071F000DA0ACCFD64ECF5154EE607E3FB8D151EAF
+:107200002ABFB9C24BE5B7576804DF595142F08431
+:107210009DE715C9F5058C40F97D2FF4E671A91796
+:107220007ACBB8F0322FFAB9ABFEF64639E619E55B
+:1072300086DF9B34EE2AB2DB0DF922D5D71BF34152
+:10724000DA6C22DF6C9DE2C3FB64EA02571AEAB3F0
+:1072500092A1F132EA1F91BF52B73693EEB19B3A39
+:1072600021DB50FFC6B53D0DE5577B6B34BE29557C
+:107270007D0DCF6FAE196828D78ADF8F605A05ADB4
+:107280001B19FF02CDCDE9E2E175BF583C227F39E1
+:10729000F4FFC5011BBD37D3E3843D4CFBF9F0136C
+:1072A0000E1FC6F74EE2F937289F7C53A5FCA29328
+:1072B0003616F680883FA9B06684CCCAD7D59787A2
+:1072C000F9BAAAFA9BCA701FCF7EEAA0F860FD4601
+:1072D0008585F16E860EC03CF4BBEC1907CD7BE6CC
+:1072E000469505E97C95B615E3E4CB9E1AE0C3F814
+:1072F000E8F4BED1DE78DEB0E385141F9EFBAA6FF2
+:10730000E3DF9F84FD7926E6472965148FF8E3C4FF
+:1073100096D916CCB7530FE4E27AFDE3F3FC77CDB0
+:10732000E62E7973B807F03CEF95AD6F55403F27D7
+:107330005A54EAF7D3A71D9B555AF7FE7CBCDF369B
+:107340003EEF08F929C6F708FC09E5FB27B32343FC
+:1073500048FEDCC1FDE35DF103F3457A23BFEAE4B7
+:10736000595CBFF1F81B08A1029413F5361FC565DF
+:107370004FACB751BC10F401E51B9C68C9B670391D
+:10738000F43CF15D9D55B3EBFBAD5BAFFAF9EF63F8
+:1073900068761C2FBB4F0DB21158E6F911E1B54AC2
+:1073A00090C77F8CF4BD75C9083A176DCEE392F093
+:1073B00014ACA9A02EAE34EF451EFF65C3DAACFABB
+:1073C0003C77E99F61C10AC37D460B8A1FBE6714E3
+:1073D000C0D37E7EF5E2975BDC24273FB3BC347CD0
+:1073E00039C04F2786FF6005BABCAE068BFB60DE56
+:1073F0009065FD2685E22AC7EFC1B8FF27CFD97C6B
+:10740000B40C45DED8BC9FCEA5F854727B81797947
+:10741000FC3A9AA778F1766246F922D3D856E15F12
+:1074200088F03C031C04E0C7B380C7C58E97BBEF50
+:10743000C2F3C3F5A6F3C6C7C5398BF23E8A415FD6
+:107440002F13E57A0B5F9F6C17BF8752FE5E9C94EB
+:10745000E352DE4A793DAE4F317D27E52C635B492F
+:10746000BECC16F7252F78DAC1CF1769CC83789C6C
+:10747000CBC9C456F5D1E8BB79F6E71E42B69EC328
+:107480005A49EF7D628BCC6E2DC2EF373767D1F74B
+:10749000365F04D77144FE1E9D95E4C81CC6C7B96B
+:1074A000B045894475FE0EF9FB240CF5844EEE744C
+:1074B000D10B267D304BE8BF59CC946FD462D453A6
+:1074C000813437CD6B5E8BC8C3EE1C97CACE61BCCE
+:1074D0002B187965128D5BF145128C630EEB88E2F7
+:1074E000BDC80B9FE5E798CCE332CFA3BBE39CED8F
+:1074F0009B3216EF57EEECD7346E896F8607AB746C
+:107500007490789F1DE6F89CBD53217AFD5ED85B90
+:10751000F27CA099FE73586012CAB9390FC03EB30D
+:1075200028CE0F920FE66E8BD079C04F594BBA0B15
+:10753000D6C3828DDB6E1C09DFCF79EC753BF27B05
+:107540004D56B4BF25137FAA67F4BD55BD13E87D22
+:10755000939EFF47E18909BF157D077899B545A539
+:107560003C0A5D3D914710267C3584F9EF09361CB5
+:10757000527D4DF0B4017FE6A8ECE2C72BF1F6CFC7
+:107580001EB7D9AED9D6E7FC768D59DE74B16B4CF7
+:10759000FA14CF73A0FEECC8E5F9E95F58FD19595C
+:1075A00024A74D7238B78CEE63957278B6D083B24B
+:1075B0009F59A8FFA0FC878D3F4F477FC6EF1FF85C
+:1075C000791EE56BA0BE1914D737B7D5F3FE6EFB55
+:1075D000450AE54BFD7162EB10B4076B1EFF75BAEF
+:1075E000FEBED79305C1D7FAE078857E5CA86EEE23
+:1075F00083BF6B28E5EC05F76DC9E6E9BEC03CDD4D
+:10760000C679D6E13C75E754EAC53C8FADE5F33B5E
+:10761000BE9ECF776697798629AE72DB930E5F9810
+:10762000EC8E28E9F593DB5486FBAC4EBBC36407B4
+:107630007CC95A36213E162E7DFB032BF0C5DC4B50
+:10764000003FC00735F73948EFCF7D81C7533F5121
+:107650002AF329A0BF379AFE3D783E0FEC05B437D8
+:10766000E2E3E8B403CE221E3BED806EE26F91F0C0
+:107670006B2DDAF96BFA1D2DC5CFF33117C97B6D70
+:107680007698EEB5D15006F073FE4EA4532FF37DDD
+:107690005CDC3FFBA7FE9FDFB294F8BFE312FD392D
+:1076A000B6C6D4A80DF3903BB62964272D5C569935
+:1076B0005EC9F07C1BF7ABE51472BB56F1FB29BF2A
+:1076C000C601744D85FEF20B35FE5CF3F07CF3C70A
+:1076D00018DDA323C76B7E8EFE7627EA439785F4D9
+:1076E000A179FEE30BB9DE5CA85AC8BE5E60E776FE
+:1076F00076BBB8BFA29F1847BF426E6F5F56C8FDEA
+:107700000AED685762BCFB2A07FD8E116363C9EF5F
+:107710006E659CFFAC126F1EEBA9CEF54DF673475C
+:107720002FC4D32DAC957E177152C5140DCF337C69
+:1077300090E7A47BA2E02F80ED4C13ED1CB4F1F395
+:107740000B1F601F30AF69C23FFD015E8F0AFD7FD6
+:10775000506027BB36FCA283EC863B53B9FF90E513
+:107760006458713DDC2CE4D4F4510E3FCAF569A392
+:10777000EE0C2084F6C20CF055E3EC585D0AFDAC2B
+:10778000B4707DBF328B71BF40735B39E2EF7230F2
+:1077900093317F1F66BFFD5CF6F9F8C8787E620101
+:1077A000FA19AE609CC12A08BF86F2023B7F5F5384
+:1077B000F893C90FF462EC779835857A0671847C6A
+:1077C000519B41FBDFC978BE200BA195F8ED3B56DC
+:1077D00016B670B8D645F72A790DBF0B7B43058BDB
+:1077E00066C0FCA2FB8DE73B6E8A5AA203305E6442
+:1077F0008DEE46FC599C9ACD03FD04AA9432C4FB3D
+:107800008255DD1B6F63E1361AEF02BCCF0BC7F95F
+:107810003D85F285A6C1A2473EBDC5CAF6AA659CB4
+:107820007EC8878D595A98EA2DE17C2ECF9548BAAB
+:107830009442F37AFC4E13E38376D6A6E3F7F6C4BC
+:107840007E95DB0BE5BE8FDB6BF3C5BA9D2FF9EEA2
+:1078500059E37A7D1CD70DF02DDAB248F76902267C
+:10786000E3FB4744FB8F08BE5F5328E37FDDEB6FEC
+:10787000A1834569DE2F3A888EB2DFC9026E2CE4FF
+:10788000F9D3721C927F67B3C594CF335BF8692C30
+:107890002049283FB8E549EE1732E51D81A144F99A
+:1078A0006DF3B6989FEBFC3CAA412E91DF54B17763
+:1078B000CCC4F129DF4AF121BF4FB36F25FF80B956
+:1078C0009E0D7F3F15E36E6BC1AE5244BC0CCA8E59
+:1078D000F50AFDEEC5B45E1D83519F83B41E4FE7CC
+:1078E0004285BD3D5BD0D721EEB79A8DF615C6D542
+:1078F000D0BE427C6DE476A555D8C375EB8DF6C637
+:10790000B4669DDDC981E17E0087294FDD26EC8EBE
+:107910000FED1D8351EE9BEF0BF8D0C2E711CE6344
+:10792000FC5ECD1CFEDE2AEC4BC9573F2DB419E29C
+:107930006DF2DC690DCA2B7E6F83294FCB45F7C7EB
+:10794000D428FCFE4EE9877C5FC0D36087D27D39A6
+:1079500047D2280E6EF64FB657BAC3169D9F727A5D
+:10796000C66D93103F35E9762BC2F73BEF156BA33D
+:10797000FE8F788AC9FE5953397423E6271D2BFCE4
+:107980007CB2B3374553C479A83FBD86F9F4D77F9D
+:107990000DF3A1F2D9C97ED847B5BFDC718B134472
+:1079A00077ECDFCF4EB6829E6F7FB0631396532382
+:1079B0002C6005FDD8BEA1A30FDEB99CAAD902F4A4
+:1079C0007EA56CCF16C0F6DA7FCCCB1F15DA027815
+:1079D0009F6E8D38B754738542F2D721D697F43312
+:1079E000D5585EE27034FF5D940BD5CBD6028EC2C3
+:1079F00072BC0FF504FDFE429F62BFA310EAA5F51D
+:107A0000099E46386F8A12B6E379FF43914B845E34
+:107A10004BF83B218E42EE6FCD2B0AD0F7D28F0E62
+:107A2000EDFCE59BB4B3458CEB7F0053DFF7AB0077
+:107A3000800000001F8B080000000000000BE57DA7
+:107A400009785445B670DDBEBD656FB260622076C0
+:107A50001212020668208100419B84252C810E2889
+:107A60004689DA2C02622091D131333A7F77D844AB
+:107A70007434A84F19079D169161E6A92FA32C41D4
+:107A8000B60EA0823ADA282A3AC04445058D4E4403
+:107A90007813FF87FA9F73AA2ADD75495866E6BDF9
+:107AA000EF7DDF1F3EBECAB955B7EEA9B39F537530
+:107AB0006FAA6ECF49F0E6331693E1353B53185B5E
+:107AC00050A1F9AD0318638702B99E38C62633E684
+:107AD0006E8C65EC27FCB93ADCDAAE303106E36F28
+:107AE000CFF4D8AE2864AC2A3C4FDC3F32CF21C360
+:107AF0003C376970EF30F8CF5C4EBCFF866C771F67
+:107B000027F4DFF67F9817E761A34798D810C67E61
+:107B10006667F4F35DEDD65C7B01B4CFD99258264D
+:107B20008C7B615BC65C9887D5C1E4698C7DD5FC94
+:107B3000A1D509F32C6AD7993B89B19A768DDA459C
+:107B40009B9AAD63615C0DB4A511F8550B7C196B64
+:107B5000314F8D0B5FEFEF047C0BF1FA6AC2FBB67D
+:107B6000174E9ABD30EE3653E3E74F24C3E5E19A52
+:107B7000EB59E7B9EBECEEE4EB3CC6585963FEB9C0
+:107B8000FD054E8DFA7F9DE31E8CF44B8139F03953
+:107B9000BA89AFD738FE57028FAA6876B307FA675B
+:107BA0000F89B33B81DE8587BC4BE3008FB96B3314
+:107BB00007E93047FF8C929148373667B842AFB239
+:107BC000CB190BE1FACC6DDD19B4DFED284C6080E8
+:107BD000575562E80E3610C8E6CC69B08F646CE287
+:107BE000E330E672BAC5CDE0DE329B848B3DA38BD9
+:107BF00001FE51277846A0B0C10FF3EC477C609E90
+:107C00001B87F68B66FD817A993126470263237BB9
+:107C1000CEACC375DD3874E458BC3ECA16973B93AE
+:107C2000E8CB483E46F6F44C433C713C837578AD56
+:107C3000C194EB601DDED775971FD6E1ED1FE30DF4
+:107C40007442B70A41D73AA783E8B1DF04780E0A35
+:107C5000E3219FCF98E38E10CC777C49DAC0553072
+:107C6000DFDA9EA3EE427CE4F3D7F6F4CE897C3EC5
+:107C70002CB73F5EBF583C660A3CEE42BE41EB2942
+:107C8000063913B4FE09FE4F1D1DA3C0D74C4A622E
+:107C9000EEBC303CFD9A7405AEACCA56C6DF30E788
+:107CA0004AA5BFDC162AA88D0DCBB7111FD932E625
+:107CB000277C6AE236C63340F1E88E33EFCF003DD1
+:107CC000F9DB7ADDA501AEB7EE7CF6FD1130EA14E2
+:107CD0002C3809E876CA0D00ACF7D4263DE0CF4435
+:107CE000F9709BCBBB33361FA782F10B0FBC641D11
+:107CF00005BFCEAF9D3709F9786BC0F2494B049EA2
+:107D000067D8592BCB027DD8A85EAF610F7CABF74B
+:107D1000472868F5F483791A0DFDB5E3BE60F138A4
+:107D2000CEFC498B5C273CBFEE48E683FB22D6BDE8
+:107D3000C61997FCF995F0CB2036E8271D9FD7FA96
+:107D40002AAC90953635139F961ED05D28A24B7BAA
+:107D50006A4C83758EDB640B44816A7DBDED63AB39
+:107D600013E8F5779FF3C17D16D4FF7AC692F0BE73
+:107D70008FAD2D70BDC8E9243A2DDAF1AD9501DF44
+:107D8000C7EDB89DF47A2CD8B104909F5033EBB76F
+:107D900009E6F767C6B99E85F96F5B399EB1C18C5C
+:107DA00025B4CFA0B6BA613CCDB7B07D1AC18BDA8D
+:107DB0006308DE1F1D1ACB008FFD5BBAB1A580C71B
+:107DC000DB7A30F7B7388F2D8EEC4479FA8D4B7013
+:107DD000DDFBA3FDF93F83E795FFC7B832A4EBA213
+:107DE0004D9A1BE5AC5C67FBB544C4378AE62BD7DC
+:107DF000DF29B81DAE4F2C8DF39B12A89F31E8D719
+:107E000087C4AD6200EB56B0179DC8E73E615F2C9A
+:107E10002D1CEF31ED15349FEC7FDD9945FD12B639
+:107E2000A4AC37CF8A0DAFC7D2A2513BA1FD4A6A9D
+:107E30006B3655989DF09CD7F39E49463AC1F85849
+:107E40006FA776796802EBC47E75D87F618F67A0D3
+:107E50003D86799BB3DC2DA88793EF6931DBD19EFA
+:107E6000C6DA1DCF821C4C2E1AE89C1BB12E7DCF8A
+:107E7000F5CC0972644B6EB3B861FE19D046DAEFE7
+:107E80009BBBF0379F0B3D65AC9EEC85F44BACC7BC
+:107E90003D0CF1BEC9C1F1967AF5AE182FEF0F690E
+:107EA0005C3FFC9B6D8167E1F78FB2BCED68474298
+:107EB000A358E58B644F43191571FF3AFC81BF76D7
+:107EC000E47FBCB98525C2FD3F74E0CFF5FA42F8E6
+:107ED0007F25FCC4DB3AAB43B978FBEAAB436EC009
+:107EE000ABF9EEC183D13FC8E7C5675AF9BC8EB67E
+:107EF000B328AF35BB629CAB607DE5C01B84DB76ED
+:107F0000DA02EB32E93AD392B1B5ADD3A0BF26BEC7
+:107F10002D17FD4FE9EEA820CA6DF3EE2833FA9134
+:107F20003D39DEF8CC14BCDE7BB406F2EDDE613305
+:107F3000A31C2439DD0978BD2B7C2F64C7A43E1A0D
+:107F4000E5CCBB92EB9F57E8E14C21B7B3841ECE42
+:107F500034BB12EE02BC6F7E536768C767DDA3F5C2
+:107F6000DB5480362DCE9513A18752DF2C289783C2
+:107F7000513EB95C56B77713FA9D29E6E57A500E63
+:107F80000E1AE9537E65B700EAF7A2F6241A27F520
+:107F900055EA696AB6F7AA4CE043F952D06F788E79
+:107FA00077495A01EA4B584EAC0E94279093D4B9B6
+:107FB0001172B0B4F97B33CA89A5582339B1415B3A
+:107FC0001A21479E8E38C531B63BE0317959A669F2
+:107FD000150BF79766CA78E5E2E4DD95C9E56B56BF
+:107FE0006C30C704F3596AA35C4B00AF53C94EB25F
+:107FF000638BEF030048B0D8E229C53863F16F34D2
+:1080000017DA5F8C3FD0FE0C395C6BF546E0777D6C
+:108010007B7FE6043A4D6BEF456DFF0C6F05F27FF9
+:1080200066FB7441C7FED432679189819FB9C3CE84
+:10803000FDCCE9DA7B6FC2E79D0ED85CF83CB0D08E
+:108040009CDF02DF42B7EBB2BB10BF372DEC6918E3
+:108050007F22CAABA35E9EE8C91C8F008AB3D700FB
+:108060009F61DE1316E677003FE700EC45B81B730F
+:10807000771B847A07EB8CF02B67CC0D192C1BF83F
+:10808000BBF88363663085B7E686FA07E1B955A386
+:10809000B8FF6F5D6F21FF5FDDFCCE1013F47F9999
+:1080A000E9BE8C81ED1D7BB9F7365CCF82A98117C3
+:1080B0002C00DFF6EB97E28739C3F46C340773CCFE
+:1080C000707F23D0D10F78353EA0970578DC13530D
+:1080D000D1EFC272BDA03D9BE823FD8DB4DF5B7D77
+:1080E000A9B088B01DBF901F92F2BD50E8C142D424
+:1080F0000316E96F2A3CA3500EF334570E8BF43766
+:108100005C1FA49D067927BD29CFEEE95ACAC27625
+:10811000DBE88FF6EA8D8F0C87F5FAB2BC4FA2DC54
+:1081200097FCFB7FBDF4117455BFF887D1C8A751E8
+:10813000576A4CD72EC64E7E6F213B794F05233BA5
+:10814000096DA49DB47411A7AFBB44B96F10720F31
+:10815000F12DC58D68C723E7FB28AB6413F2795B6B
+:10816000A6C6E7FB17E16DB4EFDB3AF0BE38FBFEC5
+:10817000FBCC8BB3EF6FA27D2F3CD79E33980FEDD6
+:10818000F9DF76F609A0BD3FC6C0FEA37FDB11E391
+:108190007C56D87BF207D10981F3D9FB5FE7CC7E0F
+:1081A000B30B7BFF67E4FF3F6BEFA57C19F5C1A81C
+:1081B0000746B99F783FC45FC8A7AD1A43FB1A8E24
+:1081C000B718C9F1FE2C2EC7526F22E22FF2F3A08E
+:1081D0000F819CCC73F5F2BBDA0F0A9C986F16C422
+:1081E0000D645A58DEA5BE487937FA913959DE1F19
+:1081F000C90F083DA97ED1E807BA92A76D16CC5FDA
+:108200002DD5DF723F006DA41FE82ADED1B32E2DDD
+:10821000DEF9F622E5A97B168F17FE1BE5A97B5632
+:1082200061A7F27459D63F113F9C878FE467A49CE5
+:108230004D7C83CB07CBE6F13EC80BE1BDDFDA33E3
+:10824000B03413ED1EB787137F62B548CF9B453D11
+:1082500041CAEBA86CEF88AC083E637C8F71FBC50C
+:10826000C68533926B991BAEDF0C6DA4DDB021FF88
+:108270003A89EFDD599766EFFA0BB9B8109F2BB228
+:10828000FEE5716155677C656EEEFFC37CB14D43C1
+:10829000B9F92E6866A85F5DF1D5B286D35DC2CB11
+:1082A0008366E95F93D0BF82BCDC98F54FD89FF21C
+:1082B000D2C6D37608FDEECE1A5E611E06797A111B
+:1082C00013F58F11ABDD66B42FF0EB709A91EA23B2
+:1082D0006FEB122E3E381AF098F84847BF1FFBC7C5
+:1082E000142774D453309590E37F9935ECE00384E0
+:1082F0007703E7A3B7C5ECE9170117001C170117AF
+:1083000019E0B57C3CFA1107CD13E0F61EE6D7065E
+:10831000212CE7137AC0DAC676C3787193E6C07A67
+:10832000C80DC57FB3227FCA4B5B5E4D87F53E9873
+:10833000555A110B21C00D680701DFA7B226AEF612
+:108340009BC5FDDDA93E463FB646CDAD039FAA8B3A
+:10835000B44056E6B9747C2A4BF567F86356EF676C
+:10836000D6824BBB1FF948F767D1FD41DB253CFFA7
+:10837000BA62E60E7462279F9376F22CC0727EA0DA
+:10838000DDB4469E871BC76F12E34326D34206F433
+:10839000DA9175F36AAC978D615C3E7665DD54E1E8
+:1083A000CFE7E8BA0DEB3D1FBEEB3A59AF53BD3FE7
+:1083B000783E7A6D3CE77E211FF3557949307BF694
+:1083C0007D077824246B0E8C6B1779A21EC0F8BD34
+:1083D000BC54CAF7AD15EE62585F1453EA7F61F9D9
+:1083E0005E50311AD6B788C9FEEAD5E8973CA68E0A
+:1083F000F15CDE77681DF7E781FC50290EEE3F9CAB
+:1084000075DB6AA40FF083FA09369F47DE1B0D70F7
+:10841000B1413F847C937EA2DD06FAE4746237CEDC
+:1084200008BE7DADB14AB47BA1121EEF85B2789B28
+:1084300092CDEB243F083A5AB2791B8A8EA0438F23
+:10844000309FE127887944C4BA894ED7278B75FBC2
+:1084500057554CEA05F727B27E1AC849C2332B5646
+:108460002FEB19BEBFDB33AB484E3AE6F3AF3C8887
+:1084700074BC5ED029E599FB0E0A39D250EF1692F2
+:1084800040801C6CD2FC3AAC7321CA4127EBFCEB58
+:10849000B972E437DCEFB69CE7FECFCEBDDF6DB836
+:1084A0009F59922FE57EC1A749063E9619F838DA02
+:1084B00000574938A0D83369E76635AD5EDE3D190F
+:1084C000EB8D1ABA09B4D7566D20637DB31FAD8802
+:1084D0001D86F2EAB4A483CDEF9FFDD8413BC8725C
+:1084E00005DA3392DFC7C97E4F437D27784D857B00
+:1084F00000CA4FEDF254185F90FD9BD576D0AF1BAC
+:1085000096ADB6604C5394FDDBD56698F7FA82FFC2
+:108510007815E7336B4F1E9C94791E796D30AC63F0
+:10852000AD01F61BC63F7A01FBBECC70FF3D86FE57
+:10853000070CF01A03BC52BD7FE61C8DF46426F0D4
+:108540000F097721BD999CDD111776F8332D96E23E
+:108550002445EE272EE57065F6BF57AC8C8D809FC5
+:1085600079AE22528E2D8CFFCC48667EF41F962E5B
+:10857000ECD9D86CB5DED5B19E3CA3BFE3FD7FC579
+:108580005FD3689F45F1CB7B75156ED6A5BEBD7CCC
+:10859000F08E58BC28E16D1558BFE872DFC3BFB537
+:1085A00002F73D263E24FBB756B823D629C78FFDD8
+:1085B000E1271D9FB7E8992D15EBA1BFAA24988349
+:1085C000F5FAAA44DE829FD1D18FD5887AC7D89D8B
+:1085D000BA07FD4C55743067717EC43A59632EAEAC
+:1085E000B3F96E9DF8E35FCAF39159CC65C57A453E
+:1085F000734242DD0618BFF76EBD0EFDDAB1BAA4B4
+:10860000EE984FECCEE6F9DEDE842BBADF02707313
+:10861000CCCD56ACD736DF3B86DA3DBA7B451BC89E
+:10862000F103D9AF56C4F6C1FE04A2CFCA679A2B94
+:10863000EAC15EDD9FEDA4FBBD898EEE4D18AFAEA5
+:10864000B230AC5733E67A8AE4E6D7B681AB008F16
+:1086500099F557D2FED1AC7FAB189B06E3662DB7D8
+:10866000D0BE02FCF447BCBDABC658B17FCE32D100
+:10867000FAC751BBFBC797DEE80FE3DBEED35DEB38
+:1086800060F0AEF6ACF85980D7A751DC0E7FD2DA95
+:108690002B1EF1ECD5CBFB7836CA6B7C5CB486CE56
+:1086A000C3E18C9F0AF366E6B8D7E075397EF78F91
+:1086B0003AED836D6F9DD51DF9B74EC8CDAEF65915
+:1086C000DD6745F8FBB95F9B89CEBBADCE3B30BEC5
+:1086D000DC1DDD53C3BA0CD03909EBB673447C0DF5
+:1086E000F252F752277EFFA16C9DE872DC56C73E1E
+:1086F00005216EBE3FA518F194F7C9FD374B0FE772
+:10870000A0C838FA775794BC909D122967470E622B
+:108710007C4F7134C0DBB23F5CED07BFC2F642FC58
+:108720008F7824BBC7A25CB17B92F83E686A636E07
+:10873000643D221CA72E11F6808F3BEA8FA3BCF567
+:10874000E8735101CC678EFAFF1217597F977A327E
+:108750002F3ECE8FCEF88BB83833D2F598D9F7F9B3
+:108760002F70DFF0490BD9D1B94FA6DCD386F600C4
+:10877000F889F520E373937A59689EAEF707BF54E2
+:10878000F5C47FF2BC7AF26EF6C98AF5F95DEBC9E1
+:108790003C11B78F7DD2E241399F571867C67DBA29
+:1087A00092275F7916E571DEED51836C80F8BC2766
+:1087B0006DC4DF96B838BF03F711E3E3CCDDA03D0D
+:1087C00021EC574B7D14E5297A772BD93D7D45A1C6
+:1087D00013E953AA33B31DFC8A1EEF727A38BC0C1E
+:1087E000EB86CBE38A9CC85F472FAE0F1DFD099532
+:1087F00013B4FEE17DB393758F3C361457CD02D38D
+:108800008766FEF3FB6835CC9380F5C7FFAE7D34F9
+:10881000AD575CF2E7908A87F7D1F213AE43F1AB24
+:10882000D3096F7D495400E9A967703F318E69B45F
+:108830008FC61CB0FE7EE17D34FD9783893EC77DE7
+:108840002057BD812EF1761AAFFF520FD8E0B9A59F
+:1088500049BCDEAA3F56C1705F0DE8EA77003C2EA6
+:10886000B996F6D77E25ECCC4C8D791A49FF5D1967
+:108870009827CF7D328AF838EFA95BDFFF4D01F2F0
+:10888000AD3C39529F7A08F983F9983D313CCF17B6
+:10889000F5BFCA407C4A7F07F925E69DBAF7B1EBE0
+:1088A000C96EC6D07E1B73B4FC7A28CA4B7DCC40FF
+:1088B000AC93CF7B322D232B3F7CFFBC2577E7F297
+:1088C000FB216F8D47BB1545EBA9DE6423799979B0
+:1088D0009FEE263FD9D34A7EF29365510457F7287D
+:1088E000227D9B69E2FB6F1013A6927DE72467D57A
+:1088F000B1CCFD522CDAFB07423AE78F5FF0CD8A0C
+:10890000FC19DA2B899E7F33D218FCD77542DE66BC
+:108910009AB81CB15D1AED373156EB443B5065D225
+:10892000C8DE19F5B2AC178F5F6766B86EC2FB166A
+:108930003E68732DC9E438E8121FC89B169A42732B
+:10894000711F926DB1517DA306D61115CFCF3DBCDD
+:1089500008F8D79899D98AF52927B76B129F1A6713
+:10896000C5389457E83F6C86FE8571DC2E2FECC627
+:10897000EB3E2CCE1E7836F279887336BFCF198F36
+:10898000FA368CE405F5DF04FD7F63BCBF34BEC856
+:10899000D9924FFBF72BB15E82F8F4E91FF15C80AE
+:1089A000D3FAA33CDE6ECE8A433E244DAFC4E73DEE
+:1089B000AF937D02A57AB008E3C0E7F5C198CFCEAA
+:1089C000BC6FEFD83508FF69A0035198F9C2BBE42A
+:1089D000A76E1372D682F13FFA2D80FF046D6D2FC2
+:1089E0006E1FBC3AAFE7D4F6E2755E4957D9BFF0C7
+:1089F0003E0BF163E1722E0F0BEB3FA07917C6859A
+:108A0000BA233F166EB60C41B9FE85C07B567DCFAA
+:108A1000E2C3201FB32C090E0D2E55FBCBAD08571A
+:108A2000376804CBE72DBCEFBDEEA67C3E1FB63603
+:108A30002147E1795332D0AF7DF55C52C6CC08BEF8
+:108A40007FB56C6B3CEE6B7F1A15CC71603DE6F622
+:108A500028D73AD253CE8FAF96E5ACC37ACD1C4718
+:108A6000280EF7C3E7DC919D88FEEE982368C5FECB
+:108A7000638D992684DD0E4731C26EF30082BF12EA
+:108A8000E754E807F8B448E37253FDDC5E6B163C2C
+:108A9000EF29419FAF9F7F3717EB060B3342B9E8B1
+:108AA0008741AE72D3912F7FD4285E58F49CEE8E0E
+:108AB000EA1F96AB452857A0FF0B845C2DDAB4F56E
+:108AC0002ED4D345284F83CE954BC82FF7D1F51719
+:108AD0009F1ECBF8FDFB50EEA4DF07789905EB6BEA
+:108AE0005601C37310FE1DD23F85FA47F37E7F3EC9
+:108AF000F913D662C5B8B846E7F102703615E389B6
+:108B00009A268BBF25C23E2EC2FEFC707F57721381
+:108B1000EC25F6CBEA6DE4978242FF5AEEDB1C8F20
+:108B200072F1F5F37B5F1D8E79D68B9A03EDFE39DA
+:108B30007A28E85683748AA775527C548374890F07
+:108B4000D3A943DF845CD4304E0749971AB3A0936E
+:108B5000EC17F7370B39AC6682AE9B7A737D17FA48
+:108B60000D12437E44AECF9BA89E1F3825E4FE6DB8
+:108B7000B1CE6A901B573EC997DB3A44E4FFD0F56B
+:108B8000F59F9EA6FA91E4A7C43B3A873F1FECB439
+:108B9000BB5B6298CF2D2636BFB37AF56742AE2C09
+:108BA000B1DCAE7C5C9F7E531DD06FC173BA8B88E5
+:108BB00087B957C4736DA696388A4F7FA93B705DFD
+:108BC000A5FF5E3101D72DE5CEB2513337E13E210D
+:108BD000EB46F497F8955EE699D08DCB5D10F19158
+:108BE000787EAC05895FFE3F690E1EEFB658B18EE8
+:108BF00028F5D488EF2981AF1EAF0DD706203E2E71
+:108C000027EA37033F48F8C41EBE9B9EE73F7A77AA
+:108C100066FFF0738EF9E3CC38EE18E37640CAE5D0
+:108C2000C7A22EF1F1F2AD140FCBE7D873B85C45B3
+:108C30003CC75B977CEE733AE2BC1C8E97D48BFDED
+:108C4000895CFE4B977D40E3A49DC51FACC7497A64
+:108C50004ABA45E8A5421FA95F529F245FFF51BD54
+:108C600062F7A450DC7AAF5837E948F7B05F40F9B3
+:108C7000447F67B3F27370117E93E29A713DBEB583
+:108C80007A3BB92EE964BC1ECEAB1C1948FF71B10A
+:108C9000A9B45FCE96A5EEEB15119F7D8A752FB412
+:108CA000A77FD003644F196865843F97715BFDED22
+:108CB000E31CA350BE9ED3E8DC91F4DFF0F34087C1
+:108CC0009CC27CF30B6ECFC57862794E16F767C9EC
+:108CD000EE93787FF589D0D87867387F19793AA8EC
+:108CE00027607D7053A6923F54B7EE233D5FC84284
+:108CF0002B30DF9D79DFBBE54391FF7FB0D0F98555
+:108D0000390D99E4FF4EAE9F3D1853DB99CB7308A4
+:108D1000BEF5D95B387C1F8FEB662E2FDC80F5F912
+:108D20004FA3DC6351CEDB566B0ECCBF463C5B7869
+:108D3000CF0DD03F22EE8A6E88EFD1F59F960FC7F8
+:108D40003CA24E27BD71AF7F643AF6BB9B74172ED1
+:108D5000710E73DC7303CAB93981F44E9E6B5C6A81
+:108D6000E1F2E6CDE176A33287DB8D4A21BFA54B48
+:108D700097E6E2B982B6A7C14FE1FEBAD5D918C4C9
+:108D80003C70E765AE75F09C1A485B53419E4E6897
+:108D90003C1E9F6F657694AF0396D09D88FF813B04
+:108DA000E306D62302FAD921A81F6E9177411E450A
+:108DB000CF95F492CFBF59E8819C47DEB71FE32AD5
+:108DC000F42302DF93CBFE301DE385931B7312590E
+:108DD00004DD4FE2BA80DEB7827D7CB1937CB03A8D
+:108DE00047D6B902FC39A28E78C0D2D003F77321DE
+:108DF000AE3F1E199F7FF174941DE512E27AF5BA19
+:108E000085FB1588E795EBA03F0ADC91EFE9550952
+:108E1000DE4EEC916C8DF1BE2F27B6D3785FEA9FC2
+:108E2000F17E19DF77D45D7A5DDAB9AE561F300670
+:108E3000146228066780EFE8981F5EC2F397731BE1
+:108E40006C0E1BD0F738EA17EE0B6ED679BC68E7CC
+:108E5000FA767CE7C000D615E61E61AE20C0730F1F
+:108E6000E92E278CDFB7FA5E3ADF71CB5A8D5DA60B
+:108E700045E45D8FAE9E8EEA76CAE55D9106E34FCE
+:108E80006DE4E751A03BD6906FBD9AE6EC3ADFFA6D
+:108E900057E559B2FE64A4FF7FE4887CCBC55C2A09
+:108EA000FD79DEBE1BC4A868D0B9F46FF57929AF8F
+:108EB000FAC6379FDA618D4F97A6C33AFEA67DFCAE
+:108EC000E008D4A3B804AA9FB4FA6A6973F09BA619
+:108ED000C16727039DB6C72638D07E7CE3ABA3EBE2
+:108EE0001D7223E474E4A6663D9DD1F81D2360FC49
+:108EF000AED804DCEEE8641F8EF3D978FEE667B7DF
+:108F00000FBD0CAFCBF57EF90BCE6F89FF971B67BA
+:108F1000C763BCDAFCDBA41DC390CF31090E1485F6
+:108F200079E21CCEE76BB83D3A614FD88075D41317
+:108F30006BA775C7FCF0164B9BD505F3BA7656C4E4
+:108F4000637DE433734BBC035B181F443CCC011DB1
+:108F5000EDE0F03246FB83C38366E6CCA4AD7B92A2
+:108F60009F61ADE600E6CD5FE1BE21FAF1B3D17CB1
+:108F7000FF5EEC07DEB28DD7D93AEA2AA2BE3042B4
+:108F8000AC37363751EE03D1F5D2227EFD8BB52FAB
+:108F90004DC6F94EAEB73810DF6FD65B68FE059050
+:108FA000DF9B401E4F6CE4E70516EC803C3913ED67
+:108FB0008846F2BB00E4D78EF277BBC56D4D3857BB
+:108FC0002E4B37F2FC7A41A346F9B694CF05EEC09A
+:108FD00058A2BB90533BFCFB095C4737D6B802E96B
+:108FE000D195BCFEA3F5003DB7F37A80511E24DD78
+:108FF000A45C84E594917C4AFE27360E1C954E377E
+:10900000F8899EFE129687F1C2522BCBC3F3507E95
+:1090100053B40BF5FEEF51F1FDB10E5567E7ED5D71
+:10902000D1F1EBB0FD7B544600F1FEBBC9F10AE67D
+:1090300059BFCCCD24B9BD4B775A34F8755A72CB91
+:10904000687203A526B709FDE0521BD911A31D7252
+:10905000E672FFB32D97D1FDC5B9FC9CB885D552FA
+:109060007C215B88077A62FC52119378068F92F715
+:10907000CB4D996606B9AE1891786736449E85B98E
+:10908000E9D370FFB76270E2E62C80876E48E3FD9B
+:1090900003120B2D00D76B3DA68D86FE6B72DD573C
+:1090A000E6463C47CE0BD7FBE3F59234EFC0DC1429
+:1090B000F473B12BD10FFC4D6B5B64D2C3E30F6A29
+:1090C000ECD8762D0CB7585806C6DBC5887F4AD732
+:1090D000EDD25CF770FE5CF5FA2C0839B02E31CB7E
+:1090E000FFDA618DEC19F3D8819F5384FCCDB2C7B0
+:1090F00006C9CEADB4B476C84716DAA90433F27DFA
+:10910000B260FB1473B019EFEFC396393EB753A8A2
+:10911000B8F6A7A4AEED3F282AFB5CCE07EBFB9B7D
+:1091200005D60B7CD5DCC06B50310D885C05F64E46
+:10913000DBF1DAF738EF523F6B89223E5439F07C8D
+:10914000B7C6BCA69FA05D18037231005B900718DC
+:10915000B778F3D7FB502D6E957196B788E2C53B73
+:109160001C7C3DCC3B9CE4F54E21AF5FF82075079D
+:10917000F99C120AC5E351D8D6C9C15CB40F65BACF
+:109180007736F2E18BB54B7B2C06F9F9FA459B6BF0
+:10919000128C3F1178291EFD6AB588F7D9593D78A0
+:1091A00035F4EFCFECB36E55847C55E772BFDF9A90
+:1091B00019CCB81BED4C26CF57D9D9BD1977C3F8B8
+:1091C000B2ACF185AB880AEE45B911FB9393CD9D06
+:1091D0009FDFA8E8C1E323B69EFB639B99F9E312E6
+:1091E000A965F140A7F1804B119E4B0558A7FDFCE6
+:1091F000003D1FC7C5635CE39C9DCAF77B9807EDE4
+:1092000096E4AFE4DB39FC049431AE37D99905D745
+:10921000DB87AD75A0FE4BBE7E21F4F10B3BD7C3BF
+:10922000317A2CD9A9C59B795D6FB1C6EDEDE29D70
+:109230001AAF6F9EE36F37AF409B3C7FED6CB26718
+:10924000D28E39E11FCAD702872721E8FC07FCEE3E
+:10925000DAD28BB2674FE68AF70406B281287F170D
+:109260008A97A41D03F6ACBF247E21C960DDF304F8
+:109270008E63F42AA719E9926277A13D5FFC6436F8
+:10928000F94976620D8B1CC7D62691FCAEC8D489ED
+:10929000AFE54DE9CC09976E6DD2E89CECA4A6240D
+:1092A00082E3DBD3082EFFFD6525B8EE8E7DD0DF8F
+:1092B000F726F8E486370ABCBC4E63C7F93D4CE29A
+:1092C00091DF88FEE7542CE00174F6C4AEA4BAA383
+:1092D0008775E443DA4F1AC22035A8776E8B9FF367
+:1092E000C75E4FFA2FD6B558E8D5E203DC5F2F1ED4
+:1092F000C5F70BCDFE3E09C87FCB7E9D0500BEF6AF
+:10930000805E1884A14B853DB7A59A9833826F5132
+:10931000CE68E68CE00FF3BB43986F550A79B937F6
+:109320008ADBFD98BC44655C65EC5C929F50C6D8B6
+:10933000FDB8DE38D7E5CABCCCCBE3632957D345AB
+:10934000DD7C326B5B867EF2DA4AE88F98CF52FC86
+:109350002DF90D4BB11A57035D8E9F4F9EBE90FEA7
+:10936000B10FEB43F264A00FE807F9FB5387F8FB5A
+:109370002710953C5E0CF0F4FD161680FEE5822E5B
+:1093800018B762FE73CA1D477A23E52E847E0FEC60
+:109390005C42914AB76E6E956E49652A7D523C2AB1
+:1093A0003D2EABCC52FAD3BC7D95FEF4F98314B8B4
+:1093B00067ED7065FC1575250A9CE99FA08CCF5E52
+:1093C000395581731A6E50C6F75E334BE9EF135867
+:1093D000A0F45FB971B102F76BFCA5327E40D312E5
+:1093E000A57F607095D23F78FFC30A5C187A421956
+:1093F0003FF4F03AA57F58CB1F95FE11275E54E04D
+:10940000916D2F2BE3AF6EDFA3C0A3D81BCAF85218
+:10941000FBBB0A3CC6F11765FCB8D44F95FEF1CEF4
+:10942000AF94FE8979DF29F07211E794BBFE4BB946
+:109430002FC496E5A01C3B7B788B7A53DDE784191B
+:10944000F5EFF08D1A4BC2FC67FF3407E9FD25E606
+:1094500081EEDEAA1C9F61B137E179F60BD9C50C0C
+:10946000114F8CD127D17B55A71A79BDC3E8D76599
+:109470003C97006ED91CF1DC6E6E3B24F46138A978
+:10948000CCA1C0299E5465FC65954EA53FCD9BA7F8
+:10949000F4A7CF772970CFDA2265FC15756E05CE5B
+:1094A000F49729E3B3577A1438A7A15219DF7B8DBB
+:1094B00057E9EF1398AFF45FB9B15681FB35D62960
+:1094C000E30734F995FE81C1954AFFE0FD0D0A5C82
+:1094D000185AA38C1F7A38A0F40F6BD9A8F48F38D0
+:1094E000D1A8C023DB9A94F157B7071578143BA095
+:1094F0008C2FB51F54E0318E0F95F1E3523F56FA91
+:10950000C73B4F2AFDD55FB982B42FB59DBFEF2A67
+:10951000E3B98979DF2AE32CC910EF63FD9B45BBD2
+:10952000F0BC7F5771BE8C03CB5DDF2BCFFDBB89B9
+:10953000C7E7BFEFCDDF4FBB4BE771E252BF87CE2E
+:10954000E725E28157D09304BF46F287295615D507
+:10955000239369DF825CA613CFBB411C0440A22980
+:109560003313F39098701CDBE3A7C1171FC76E86F7
+:109570001C07F138DEDBFBC7DE8598B7FD692CE6FA
+:1095800039B732FF0AC403FC6E02EE63BD15A5D6DF
+:10959000A3643BDE0E748C78DE81A8861E83CEA386
+:1095A000BFE3EDAD34BE635E51AFD2607D8B23E689
+:1095B0007F10F22F33E869830FF40C12ED877D0ED4
+:1095C000821FF5A512FC98CF49ED1A5F1EB54FF822
+:1095D0005CD4BFD65744F0533E37C1015F19B5EB99
+:1095E0007C1EBABEDE5749F0069F97DA8DBEF9D4CD
+:1095F000FED1574BFDCFF9EA087EC1E7A7B6D1B738
+:1096000092AEBFE86B2078936F0DC15B7C016A9BC3
+:109610007C1BA97DD9D748FD3B7C4D04EFF20509A1
+:109620000EFAF613BCC71722789FEF30C1AFFA5A73
+:10963000A8DDEF3B41EDEBBE36EA7FD3D74E70ABF2
+:10964000D84FF8A4B7A6BCAF2761C646933CC8F86C
+:109650007732E63D281C45966F94BCC7907F18F979
+:10966000F1A5788EA504C25F8C7F2ECF5DB7342222
+:109670002FF8463CEFDE68E68F027DA837F1BA404E
+:109680007D22A3F7C39888CFE709B964C93C2E9F10
+:109690002BF09A27F4A010E5338FE4F3CD4BC9B338
+:1096A00064BE1D93E1FD91E4B3A7C94F758758FED1
+:1096B0001E7EFF0CAF9607FDA76A6F79959EE77037
+:1096C000E5E243CA6DC194EBB09E7440A73A6C5773
+:1096D000CFAB11EF4974D9BFEB640FF447653FEA94
+:1096E00054AF7FCB125789F596A43C5E874DCA33A1
+:1096F00029EDD60C4F621EEEDBE7D46EF899167E8C
+:10970000FF7F0AA6E6A0E715CC69A173B8CCFD0AD5
+:10971000BE7A732D047C085FC7FCD48EECE94DC77C
+:10972000F55C0F0906C2DEE1B68CCED663C42747CE
+:10973000E09323F090EDA10C4F2FC4E7788E5BC12E
+:1097400027EA0AA73857DFF614E2F59F3BBFFD5C16
+:10975000CB0ED35BD637568C12E7B46ED7E43E38C7
+:109760008F13ED4CC689D45F7527AFF7487F79A476
+:10977000A3E5F6F054AD85EC669516EDC278FB5482
+:10978000ED9D0370BFF046C8F770FF54DAD12A8010
+:109790004D0057317EEEA2EA481CC999D1BEC27D68
+:1097A0000CF7FBAA2004C0FCF16C06AFA7BCE5F9DE
+:1097B000D682F3B2E4367A6F15E4660CAE7FC13020
+:1097C0009DBEDFF0962990ABE9242F560DF09F97B0
+:1097D0000CF2D249BC20E56291782F475E07799B55
+:1097E00082FCF966DBD03CDAA7D935CC89F45C6A17
+:1097F000E2EFD5F95FD7F9B90C2CE5E3B99184FC18
+:10980000A7E9FD020C2E907FC3E2E8FD82669DD59C
+:10981000FDA9137B5A2BF8F856AAA52C40F3AAFBF6
+:109820008AB7E6F1FACFAD795C2FCBF71CE889EF68
+:109830000D2EDA6FA1BC8815B4E47B3A3957555325
+:1098400077FFCF7B45C8794DD3C7FC3C166BC98FDA
+:109850003C87B552CC2BE54BB7C6799F8E8DC4AFF4
+:1098600043CE6B849C7F8E71FF649B33E13AB8B525
+:1098700005481384D6FB3B079DE793E7FAE6300FD4
+:10988000B5F380DD28D71EFF6A7AAF7E016BA4EBAB
+:109890008B8A6667205CC3DA46A7C27CD7AEAC7FF2
+:1098A0002515B09BD6B07A0CD6B9A70666BE826DD8
+:1098B000C57AED73BF93F4C48FCF6FD16A975F0EF3
+:1098C000CFBBE1B951CBB18E3C59E77C606F703EA4
+:1098D000803CB9F5C473D7077A71AFD00BC25FEA89
+:1098E00045D512E6D692C3EF8174E849D16D7F4D1C
+:1098F000C73D16731B9D43A9D9654BC4FAC902C65F
+:10990000FD76B80EC4FDB5D4832F2D9CEF5F3EAF1E
+:10991000D17B365F6A8CBEE7D055DC20E34FD03F69
+:10992000AE77C762B8FCEBA2AE97E14D1D941DF671
+:10993000CF5F9A0243E2B3C97F3F83EBB194781FB4
+:109940001888E7F55ED05C4B01972FBB0532F839DC
+:10995000810E3FC07E8A09D7091FB4F0BA9D31DE5F
+:1099600095EBE80A4F9B95F9713F4B2B7AF57B8C71
+:1099700043CEC5D79B3A04E8B214598475C9128FF7
+:10998000B3333C9689E7EFFF81E7E3FE9E8CCE057B
+:1099900019E9A939F873BAAAAFDAA2393ED24F4908
+:1099A0003CCFC58BF3EBADBC4C5E6714F831E6C819
+:1099B00073C0F3CDE66817EA6B85D9FB67D473599A
+:1099C0007F9379F1FECC2FC81FB0B34B7BF0F3C768
+:1099D000C1AEFC706B473E9E15F693B28EC58A3BB6
+:1099E000AF477AEC0EB25F53998BFC451F7644D299
+:1099F0008BEA583AEE10529DD74BEBB0A1BD86369C
+:109A00000AEB28E42F0324AF318817AD2B841511FE
+:109A1000B63A269EE830FC30233B3D1CD700EBDDF8
+:109A2000F9310BE079AAE633D34BE3A07FE7D766A1
+:109A3000CA831E8F79211DBF23B1F3E4FBE958EFE0
+:109A4000A93FB385E021AD634FF2FAD9911938DF10
+:109A5000F6D356A78DE280DB890EB24EB99D311741
+:109A6000EE83167D184BEF19171E6A8C21BA89BA3E
+:109A70005AB15877F1695E0FD985C030C803DAACA6
+:109A80002C18112F5B1C2A5CC422E04C7C24C011D2
+:109A9000758E4BCD1FED7D445D6D281B1A595763A4
+:109AA000ED899DBE4F65DC472CD038DE9FE679BA44
+:109AB000F5A13ADB549DD3FB471DE975756C200D6C
+:109AC000E3DBE65B37A461BCFB78CC8F44C7277E21
+:109AD000B0A6215D1B46FD27F99106B83784F9AF82
+:109AE0003910C5A8FEB590EA6B570B3FFBC4D94FA0
+:109AF000582AD0B3A18891FF64C20FCBFE86B3A7CA
+:109B0000E6233FCF14DB9D681772453DB4FEAAFFE4
+:109B10009BDA12418F9D10570781C1DB21AE0E42A7
+:109B2000ECBF0DE26A84F1BD536C37435C8D6D0070
+:109B3000E26A6C9F82B81AC7615C8DED131057639F
+:109B4000BB06E26A6C1F83B81AC73D0A7135B60FAF
+:109B5000435C8DD71BCECE2A257C0E337ABF7E493F
+:109B60004CBC09ED2BE01F8D75A1B7DD83A2911EC2
+:109B7000579D3629FC2D6E8D56E0E1C713C3FC4579
+:109B8000FE1FB95CE91F72284BE9CFF4F755E02BB3
+:109B9000EA062930D68722EF4F9F5FA2C069DE090F
+:109BA000CAF8CB2AA72A708AE706657C52D92CA569
+:109BB000FFA178031F03D526958FFCFB0A678A63F4
+:109BC000E97C655772FAB0E08B841FF9855ED9593C
+:109BD000DD766E1FB95FCFF381CB056E8BFA384906
+:109BE0003EF71D1DFA87DC02E487896F9BBADB62B2
+:109BF0007A015F721F31313C5748270E003F87B80A
+:109C0000EF9192533128977BCBAD51C89FDDEE92F7
+:109C1000688497945BD322E5A821D33B88DE53F078
+:109C2000F2F5C9FB1F2A997ADE7DF48751FE7A9FEF
+:109C3000A77FC2822CD48773E8C8E6D37E6D988E46
+:109C400053E9FB4ECC3B5FC1DFA8170C37E9D3F0DB
+:109C5000B976959EEEACFB900E4F3C6AA673581DEC
+:109C6000F389FBE57C63F4B3312DF9E7E2BFDBCD8B
+:109C7000C743FC1B8574816729F825BA9CA3903ED5
+:109C8000BF11FAF66F42DF1E177CC53C1661E6E095
+:109C9000F749BE35CC7F787C2EEA4D11C76BDD3598
+:109CA0000F6B686E9298ABDE1141D747051E4F8946
+:109CB00075ADC579014EB9C6AD21FD32EA3C1AEA4F
+:109CC000DB15F7B410FC84D0EF1EB56D74BDE71D35
+:109CD000416A2F9F1FA2FE31FA73B48E0E3AB85418
+:109CE0003A1AF91410EB91F386EF7FF100CADB19F1
+:109CF00037C73FDE1FEB467F11EF77B878EB14AD27
+:109D0000CB85763FDEEF16706D3EC2DBC4BAE2FD56
+:109D10007E8203625D0DF3930F6C70869FC79C3546
+:109D2000A6487FD3953C6D15F4DF2CE864BC6F9B8F
+:109D3000A576B0A313BD92ADF4A745474C06BB135F
+:109D4000ADE8FD01FC85FB8177C80FF83DBAD8BFAF
+:109D5000223A4EEBC897AA489E56C7DCF406E6DBCB
+:109D6000D71CD219F7B7935F417BF9EE781BF9D373
+:109D7000E6F1E37A46CA5D9358C75641F7617EF72C
+:109D8000D13B60FC448F8DEAF14399BBE79D30DF06
+:109D90008449BA2B08F31DEAF0279E187EDE81FB6A
+:109DA00093A9620D7B264DBB1F9FFFEE21B00BCE0A
+:109DB000309EB27F73D9B489FD908F21CEC7AEE8B3
+:109DC000F39AE0D72B02AFBD825FCD42BE770B7F07
+:109DD000B253F893EDE84F6CC8E722B11EEE4F3650
+:109DE0000B7F12427F02ED5BC29FBC89FE04DA82C8
+:109DF000F1D9A3C96EDA35E14F2041A1F3048B9468
+:109E00007549BCCA7AE80ABFC626C728FC1A1D9B3A
+:109E1000A4F49798D315D87D364B81AF3ADDD7E0BF
+:109E2000A754BF32FCF870839F2A51E0218726286F
+:109E3000F757B8A729FD538A6628FDE5AED94A3FF2
+:109E400013FB6185FC775618BD56A73C57EC3BC900
+:109E500078EADD329DF66D86BDA7BB22F5B690751A
+:109E6000EC9399709F0CC217A759CE97A5F4531C79
+:109E700075C8E249C7F37BF5152087D0161F8238D5
+:109E80008D8A8F20D710F7167AC6511C08F1D26040
+:109E9000E2431BDF6F92FB56C30CFB4F13F2D5FD61
+:109EA000A9C20BEC4F8DE8DB455CD62BE9A2E23270
+:109EB000D02F8ABF1E8FB9692FCACDB60F214EC5CC
+:109EC00038F7C39F53FC25E3B6AD9FFD9CE2DBADA5
+:109ED0001DFAE255F4A550E8ED9643594D2DA06FBB
+:109EE0009B5335972035E94B91D497166137CB6A50
+:109EF000E8FA1071DF568B2706E3BFCD8797887984
+:109F000023EC08C5EB117604F34896A8F6A7A687BC
+:109F1000FBB338B322C733D6D730DF20033CDC3065
+:109F2000BEC4004F308C9F6A806F308C9FA5F43781
+:109F3000C1BACF176F6F16F6418E2B347B7457273B
+:109F4000F676C821D5BE324F8D72EEA1F9E85CB22B
+:109F50009B5B8EAC10749CAFF0678F7CCE21A0739E
+:109F6000FEB9F79798FD31FD410E4A0E9B5DF5CE87
+:109F700030FF249F18E6C311F395DA7545FF9A0E5A
+:109F800073FE76B5CE5DC23EEF107EE66543FCA65D
+:109F9000FF70FADD29203F5B5A4C945F6D393435F0
+:109FA00009E7DB7D760EE1DB74D844EF91ADFFE38A
+:109FB000A46BF17D45899FC4A7F0BD2531B8CF7A48
+:109FC000A6C544F6AFD0E24972744277A37C7535DA
+:109FD000AF945B08A092902EBBC10FD1B961614FC5
+:109FE000255DF61C7D8CE8BEEDF0E224A4FBD5EDEA
+:109FF00026852E23DBD4787DC48944051EFA318F53
+:10A0000007C1EF2AF4BD10DE46BDC09D1115BE5C30
+:10A010001D7F91F1C076C1A76D824FDBA35C959D3A
+:10A02000ED6B6C3B669D1FF95D854FFBF2BAD1A7C6
+:10A030007D79FD6D33F011EDEC99E326B2B3231C6D
+:10A040008D7A6D27FC286E3519FC841A375C6ABE40
+:10A050007AACAFD8EF34D8C5AEEE9776B1447E3F38
+:10A0600025744DA7E763C37C10E72A0DF49471F4BF
+:10A0700085F926CFA31BF8D7C5FDE179FCC67CFA8C
+:10A08000BFFA62FDA5A582FCCDEA98B7843D7F8B1F
+:10A09000ECF93BDF0B7BFE7D778A930E8EBFAC27FE
+:10A0A000EAD1C10E3BCEE222EDB83C0F196A7D2702
+:10A0B0002632CEF70879DCE97E77E200E4672FFDEF
+:10A0C0007F34DE794BC43B6F62BCD31BF78178BC15
+:10A0D00073C03D9BC73BA91A7D2F6649CC55666F5F
+:10A0E0002772FABF3DCE9952A4C639E52E35CE91DE
+:10A0F000FB07BB1D1A9DC39A98A7C63DBBF117ACC1
+:10A1000033D9B500BEC7B5DD3DEDBC763828F4FBCC
+:10A1100080E0CF6BC20EBF22F2861D487FE24B99D2
+:10A12000E00BAF57149F76C5BA9CC89FF93C2FCB64
+:10A13000ABA17C7AA4F4EFBE5A1A7FF0CCACD3F872
+:10A140007EFF6E470CD55976233EB0848316EF69A7
+:10A15000FC7EC56EB7E65CD2495E3FA24DB50332C8
+:10A160004E9072B9BBF51392CB5DEDE7F7A7D27EA7
+:10A17000C971AFB1974A913E57B5328679C385EC24
+:10A180008FD12F5EE839C6F123CC8D7A677EC7F870
+:10A190001C4F7B50C7F3CF3BDB4249B85DE7091E3C
+:10A1A000D0F13DF0E2B620E1BBCFAD39F44C1A5707
+:10A1B0008AE7A25F3BFBCE44BCBEEBB4D964A37D6F
+:10A1C0002607E96DB1D0CF37CF9A625D445F9DF627
+:10A1D00039826D9FDC8FFAEAB7EBF4BEC8EEB38329
+:10A1E0009223E9B6EA4A9DECC9F6D13613D697B761
+:10A1F0009F368BF3D6418A1F76B467C562BBDD0DEF
+:10A20000FA43F62244F47FEC4A07DDB713E6E3761F
+:10A21000C249784839089E369575F6BD9DC7AEE4AB
+:10A22000EFD18F38FBD718A4CFABA7F7C4A0BDDA06
+:10A23000D5C69F33E29E9618CC33DF6837C5F1BA96
+:10A24000CAE064BCDE3CE6DED841B8AE3613DFBF00
+:10A2500011718D7CDEEED1F3A89EBFBB8DE761BB93
+:10A260004FF3FAD1F6003FB7C6841D93E3B79F9E24
+:10A270003AB11FD60F02161A3F820556C4C3B8570B
+:10A2800052B65E49E76BFCD52CD2EE953AD438A78E
+:10A29000A4CDE09FBCD5A407920F07BF9D7A4D05C2
+:10A2A0009DAFE77672BC59B52FBB4E2F499E8ACF22
+:10A2B0008FE5CF67017EBFCCCFF0C71CF1DD95FAEB
+:10A2C00031D74D2BC7F936F373662362557B767011
+:10A2D000D4ECDF2EC4F3FF9B62C8CF6EC7F5E3FC5E
+:10A2E0008718D5CF76973D521A8F75EB56E6E271F7
+:10A2F0009C6AD74BCF6CDA1B0FE3DF59AF117DC7D8
+:10A30000E5A9EBDDE9CEFE35E6C1675A397D653D4D
+:10A3100049EAE59ED6C41BC93E8D86BB818EEF946B
+:10A32000BD4475EC5B03EA3C4337C628782F6C4983
+:10A3300034E46F6A7D1CE24D591F882D1F12CEDF59
+:10A340000ADB797D7DE80F53070701DFE2D1FCFCD2
+:10A35000BCB12E3EDE6C53E32C435DBCD0581737A6
+:10A36000FA73118F0D11FB1AE7C43FC2CFC97AC32C
+:10A37000364B7086E712E2876166485DE85CAF376E
+:10A38000A900E8FFB2882F87591B7E9606AAB2550E
+:10A39000F78F6011710173F859F290707E3BFCB831
+:10A3A0009A0F141D51E512F2C7CF319F5C897B9A39
+:10A3B000A4077E7E2EE222E38CD531FD9B5A80AF2E
+:10A3C000430F31B1DFF17FF6A25C357D26F73320F4
+:10A3D000F4E88EFBF38CE2EDE6CFAC24775BC6703D
+:10A3E0003F25E314B94F730D6B5956AAE1B96CFBC5
+:10A3F000F216A0E7A68373D317C1FCEF7D44DB9D63
+:10A400006C4BA1FC3E7D83925F0E9575A823267F41
+:10A410005201C6EB3645AF657FD3912531F87D916A
+:10A42000332113C969F38756867F1FA069878DF68C
+:10A43000739A0E5B69BF65DB0EAE27B2EE2CE3FCB0
+:10A44000D7853DDF2FE2DE5745DCB24FC42D7B447C
+:10A45000DC121471CB2E11B7EC1071CBCBC26F6E26
+:10A460003A22F4EF9E9800FF8E2DAFCB4A3C6FEE60
+:10A47000DD72D40C0BAEF968C89A20437FAEEAC9EE
+:10A4800078A7AA27E35255FB31C691AE8C2FB5674A
+:10A490002BFDA3D8954AFFD5ED830CF9C870433E38
+:10A4A0005262884726AA7A792822DFA5FC5ACD77FE
+:10A4B000AF8DCC7733914F3C0FDCD6F230F171DBAE
+:10A4C000F1AC84C8B8EC65A137DB8E73FFFCF28970
+:10A4D00053719DC56D27043FBE14FC6815718A2712
+:10A4E000CD7D7D7E0AE615A7AC78EEA32B7996F795
+:10A4F000CBFB4E043E8D8FF47F9F51D21886BFDE7A
+:10A50000F2975CAA9F5CA47E2C8DE3E7DC366BD1CE
+:10A51000F4FEFD85DE6BA9CBCF12E7926A07F07DD2
+:10A52000D1DAA1D86EB078D2F1FDA7CD9A6706DA5C
+:10A5300071FF6FAC9DFE3D095FBE3CD7C49AD03F12
+:10A54000F023C9F0F39C6646F98A12E0D3CCEB43C2
+:10A55000FAD8315F87417AAC87E1BA36595813FA95
+:10A5600079E6664E4777C655089E73AA9F77398E5F
+:10A57000D7427CFF18DC2B7DEF038F66E177B7B005
+:10A58000C57D329B9DBF7760C9F7DE9F5FC8BF67FF
+:10A590009B3008E72DC9E6FBA841B2DF33C4BCA657
+:10A5A000981D3DC99F7665570D792EAB56DF473113
+:10A5B000CA4B93B0B32F677A6674F61D8C67F3F9B4
+:10A5C000B9906D5F4CD6F1B905F67837FF2EA45BD4
+:10A5D000C7F7C05EFE7242CCCC4EE42CD87FE6B307
+:10A5E000F911725010AAD5C5DFA930A9F52D531065
+:10A5F000F97D26D64A7A3D1C179C78EE7C234EA81E
+:10A6000071DEB01635FF0FEFEF376878DEAC439E92
+:10A610009021C8FF83FC7B1A179227E3BEFD07F940
+:10A62000F2BCA4F72F788E584F88A5F3359B0EDA2D
+:10A63000D7611C69ACF7BDFD1EB7E346FC9BDF9BF1
+:10A640009E8EF1D7E691D7A5A31E6F41034FDFF38E
+:10A650005934DD1D09E3FA63D1DE33FE9D2D7FF50C
+:10A66000743C2FB365BC8417F2F1A3F8F8F79F7B15
+:10A67000EB31FC1ED8961B453F7B808F97B0BF66A1
+:10A68000FA28ECB79808AE781EC6437F7B5FF707C1
+:10A69000246FF9EEC328A71B5077001ED5D7FD11F4
+:10A6A0005EFF00650CAEBFDDC77D24128EEFE33E7A
+:10A6B00016096FEEF02F6DB191FBC7520EDF3E3CD5
+:10A6C00055F81DCEF72932AF29BEB83AFF9F859CB9
+:10A6D000BE21ECD501E13F5E13FEE315F41F940F9C
+:10A6E00073FFD12CF68D770BFFB153E4BDE1BCCBEA
+:10A6F00023E28B4A910FF33CAC606429CF7B1DB2FF
+:10A70000CE9F61EE2C1F9A5CA0C68993F255BF3292
+:10A71000A1579222A7653DD20D7972B6214F56FD01
+:10A720004A8979B0214F1E6EC893D5BCB7B87582DF
+:10A73000214F9EAA8CFF20DF29F6916E30E4CBB327
+:10A740009471613EAAFB36617ECDEE948F5B8A6781
+:10A75000DFFFBF8B8F9DEFD7FCFFC7C77F501F6305
+:10A760004DCAFE8DB17D53F8FFD785DFD82FE2802B
+:10A7700057459D639F88E7F6201F7B635CE7127156
+:10A780001D3FC721EB202F8B3A549338C7B145ECBE
+:10A79000BB6D1275A8A5C5DFF1731C6799E0E35B7B
+:10A7A0009DF2B1DCA5C67913F3543E8E772619E2EB
+:10A7B0003E35CE1BE350E3BC52BBCAC7516CB0213F
+:10A7C000EE53F938B2ADC410F74D30F829F51C0737
+:10A7D000C405ABFA15E27B09EA798EC2907A9EC372
+:10A7E000E8DFE5FB8A326EE888137CEA3EF326F464
+:10A7F000A1B85F9466E5DFDB307B2FC7B843D2EBAF
+:10A80000B7FDB83FDFF2979B889E85E8CF3BF1DF2D
+:10A810001BFAF1B868433F5E97C0F723A30761793D
+:10A82000D3CFE39F84490E7EAE8A85F0FB53E78940
+:10A830009B36F44B09C74B66472DC33842B799FC8A
+:10A84000F8FD5DA6DBE9DCDDDB5DC451C7FA65CA56
+:10A85000EF9F6A38EF5FC4BC5AF16B14579DEAE76B
+:10A860006EA4F94B5D6D5817DFFCA1D5558FF21C16
+:10A87000C5BF83628CB75EEF97CBFF7E8FA01F9E14
+:10A88000FFFF39FA4BFC502CF9DF16D57F6220010F
+:10A89000F36C88E6F09BFD3E9E8EDF1794FEFAFD7A
+:10A8A000E74F913FCD8DBD7C36E6CBDA1A7F22DFB4
+:10A8B000AF0C927E19E3B62EE35F439C7624CFFD66
+:10A8C00006AEEB1BE19773F1935283BABE7F43B49C
+:10A8D000E736FE3D18B78ECF957492FDFB04DF5F1F
+:10A8E00017F375D045CA157E9F2631E23D5803FE09
+:10A8F000925E2B0EEE0DE111C64B5D8F5C4727F289
+:10A90000E3B940DCFD4D67F2C326B9C47BBA9DC7ED
+:10A910007D16114746F27F38AD2B20D7CFC60CC22B
+:10A92000F75FE47BEBDC1ECA7766121D0D8E4CD000
+:10A93000A39B0EE974CE81897D7073073F8B35F43C
+:10A9400033E6B11A4B8AA8BB1AF7138DF503E3B9A6
+:10A95000B2E2D6CB15F8AAD3EAB932F7D9BEE7F5F9
+:10A960002BA3634718FC52A9C16F4D34F8B5690693
+:10A97000BFA7D6C5CDCC2CBF3324F6EB35277E7FC1
+:10A98000C7CC2914D92FBE03C4E9BDAC0BFD95E794
+:10A99000674FF57312DD3BF4632D7372FEF995F783
+:10A9A0004CF4582FF1F9A121D28FB928EFB50687C1
+:10A9B000D1F73CAD2EF5EF33047CF68F46E7E07B14
+:10A9C000368CDAA77C8E8F46D3FB38A9D43EE17350
+:10A9D000D2F535BE3C6A1FF3B9E8FAA3BE226A1F5E
+:10A9E000F6B9A96DF09551FB80CF43E356F92A09DA
+:10A9F0005EE9F3529B05E10DFEBD812C3F7301C65C
+:10AA00002C7B253C2F82CE997EC023828E57D43951
+:10AA100014B8676DAA323E7DBE53E94FF3E629FDB7
+:10AA20009755BA1438C553A48C4F2A732B703777B7
+:10AA300099323ECEE551E098BC4A657C94D3ABF4A4
+:10AA4000EFB96A7842CB79F4B9C1E73E8A7458E528
+:10AA5000F31CE5742A3BCAE95349ED2DFDBB117F78
+:10AA60001DE64637FA6D47BE83E1F976AB9DBFF729
+:10AA7000DDCDECD0BA45CCDFCD0DF329F8C27C4A50
+:10AA80003E17E0E789F33C4755BC2B95FB4007C9CF
+:10AA90004FCA38668CDE230EF3B1FB2D8E3F0F06B6
+:10AAA0003CEE1BA3337C6FE5E0E8695417C12D4CE5
+:10AAB000D6891DFD4CC4A731FDED942F4E7954A3CA
+:10AAC000FC0E56528E75C4B987B25D917F0F4AB69F
+:10AAD0006FFF8A7F6F2866CF3627D6C5A614CF4C66
+:10AAE0008A8AC8FFA604BF1F9D46F30D1C12057875
+:10AAF0004C5933D33A3B3FBC3E396EEEA36A3C1A05
+:10AB000096FF805DC4E3B44E699F5639D6D1F555A2
+:10AB100079E7DFB73929D6F58588D73E13F1DAA76B
+:10AB200022EEFE58C4DDC744DC7D44C4DD1F89B875
+:10AB3000FBB088BBDF17F1DA2111AFBD23E2EE15C0
+:10AB400022EE5E95B78EFEAED5998D1AD3CF73BE29
+:10AB500074C17A759DF3D7AAFB86731F55E3EE394E
+:10AB60000FA8F1DAAC656ADC7D739D1AAFDD58ABD6
+:10AB7000C66B33E6ABF6F17A6FA9025F57A9D6E54B
+:10AB8000AEF5A8FB86924FD3CA543B694B55E3B54B
+:10AB9000AED6BB35385EC7BF4382CCFC34C21F463D
+:10ABA0007C0F5E39EF58E07097E27E4D21F32CC5A3
+:10ABB000FD9C91A6D0BBB8DFC4DED7E93B904D78B1
+:10ABC000C730D0D73343264D7146F81DBF4AD7AAA8
+:10ABD000236A7DE4863BD438B8A25ACD67AC656A57
+:10ABE0001CECEEA1EEC74E33F81D26FCA195FFCE5E
+:10ABF000467BCEEF874C31D5F4BED2A5FA232B335A
+:10AC00009E1FE3FE889E9BA5F4933F320FE0E7244E
+:10AC10008688F714EAA386BE89FB777B3EE4EF17AC
+:10AC200000D943BDE0FEAB18A7B7D53E8EBE1FB717
+:10AC3000D3C2DF1BD89D16EB5A025D579DE5EF0787
+:10AC4000B076339D1FF3E27B235938AF7A7EAC3068
+:10AC50006456CE97590DFD97A14F3C2F3EFC1CDD4D
+:10AC6000FF1C3EE21CC7003680CE47B474FEBE41D6
+:10AC7000471C679053697F0A823C3E2AE8323EAA0D
+:10AC8000A2EF8C99DF67F49EBDCDD476E2197C3FAC
+:10AC9000EA735E871DC5D4BCED9A496ADE36C6717B
+:10ACA000FEBC6DBC5395D78979AA1D2877A976E09B
+:10ACB0009CB8A6859F43EC2AAEF10CC892EFE91030
+:10ACC0007DA272F6C5F07D4C2E3F23C43A1FB27AA6
+:10ACD000E8FD95653D19F16984839F57ACC77D1BDD
+:10ACE0003CFFF71E7FEFC5CC3C4903B03D3E569C70
+:10ACF0005F9CE4A2F95A39BF8AE0DF4F59E79E4FC3
+:10AD0000B485CCCA7737CC2C82BFD03F07E5AB30B7
+:10AD10002C47FF7BF012E728A59CC5265E60FFCE7E
+:10AD2000AFC481B21D1572EBB88E571C7C1FF59510
+:10AD3000506D08BF13F95D2AAF53DCDB63AA997F1E
+:10AD4000B7C51D3B06F83256ACBF48EC936DF1B168
+:10AD500010C6739B7C766AE5FEE78AD4C549E8375E
+:10AD6000B76478D3F15CE096946ECB18D8E9CD96B1
+:10AD70006E3D3A7B8FA0D93294FCEC96E63433C614
+:10AD8000A1A3CC0E33DE37AAC72C1DEBB1E3F07DB7
+:10AD900093648419EDD36DF20543A3E95CA897CEC3
+:10ADA00011C13A4A318E1DED98497FEFB1F93DFC52
+:10ADB0009B4A181F77ABC2FBF6A5F0F3D736073FC7
+:10ADC000DF3A36791EF1ABC0C5BFDF57D023D615A9
+:10ADD000C0E952F9777CE6C33FCE17EE2740EF95E6
+:10ADE000EFFB0C651130F2CB00AF31F2C7702E7162
+:10ADF000C561717EAEA5F37D9BBF8AB8628BA83B0F
+:10AE00001C1171C54722AE3828E28A15863AD0BB9C
+:10AE100022AED827EA40AF8A7ADE7E51CF7B5DC46E
+:10AE200015F2FCB5948BD495CC694B60ECAD999C34
+:10AE3000CE692BB54019ACA3740E8753EBF8FEE82E
+:10AE400015DE064F4901F65B5CE3601DA9950D63B5
+:10AE5000701D69556DF49E52A5D7EA746BF87ED2C9
+:10AE600013F45E947C2FEC164E1A76D39CB1647F5B
+:10AE70006FF18A73C77A6B21C9D7A316FA4E92FC79
+:10AE80007E5CE51CF57B4AB30CF4BDC9005B356EF6
+:10AE9000475E93741FCC0647D23D4D8C8DBA459CBE
+:10AEA000E7C597AE3AD1973582EE922ECD574D88B1
+:10AEB000E3EBE0FBA13631CFA1E21BE2709EF77A13
+:10AEC000F0F9A60A7D30CEB74ACE27DEA78916FC58
+:10AED0007FA8EFF9CF9DBEED63CA39D3B7057F3A9E
+:10AEE000E62DB9DF82DFD3AE0CDED713F525FC5E8D
+:10AEF0008D3B8EBFBF32E9CF99C0A755E23D0469B3
+:10AF000057AF13FA6B7CDE7BBEF3BFBFF35EC90C99
+:10AF10000B7E0FFDDAE02FF8DF0336D7A6469EF74B
+:10AF20007D0FF1035B79EFB53FA3BF2319CAE0F2B0
+:10AF300060BBC6E6C4EF0C5ED1C3BD1CE998DAC3A2
+:10AF40003546D447C99FD9043EA698B55A0A8E1FE4
+:10AF5000AE91DED65F3581CEFF5D770D3F27F1FFE5
+:10AF60000010785941008000000000001F8B08008D
+:10AF700000000000000BED7D0B5854D7B9E8DA3320
+:10AF80007B1EC0A0838A1912B003A819531F230F78
+:10AF9000051C70A39812436410548C8803A2D0D669
+:10AFA0001892A6B7F4D4731804110951D3A63DDA48
+:10AFB000F818CDA3BDB9DE9698DCA64D73CE21C698
+:10AFC000A4696F12B1471BED6D0DBE92F46BBF1EED
+:10AFD0006DD236A7ED77BCFFFFAFB566F6DE0C6825
+:10AFE00052D3263D852FD9AEBDDEFF63FDCFB5B967
+:10AFF00072057EE633E6606A78C8C7F0C77245819D
+:10B00000FF4798579D83EFF18DA19E5DC9C4FFB79F
+:10B01000B26032BC0F7EEA176C266335ACD53F00B8
+:10B02000EF7BF3B454F774A8AEB35D187232E683C5
+:10B03000DF2B59D047CC239F354CA57A39DE920AB5
+:10B04000682FC767349FA17E6B0FF33AC642E14F6A
+:10B05000B0BA89D05FD46D55234E9CAF37F839A76D
+:10B06000E6622C2BDDD2E080F554666C5ECD264086
+:10B07000832A877B0AF60F2CFA796E1E3C7DEBBD86
+:10B08000B83D6CD70CED4E4DEBCEF04E8FAD6BEB6B
+:10B090003656128279B666FC0FCFFA646CF7BBF6AF
+:10B0A00010B6B3B1DA7E18BF77C12FD3335DB1F6D6
+:10B0B0008766954EF3E7C380E5A98CA53136D51E8A
+:10B0C000CAF24F1FBE5FC6C28C41938E9244C660C7
+:10B0D0001DE71B948803D655DB07F01B83F5975AB1
+:10B0E000F07D439FC3DB8B0B649AEB0ED8E77ABEEF
+:10B0F0004DD630A52B7F009EEBFB9A2BA8FD2EDBB7
+:10B10000398497137E11BE19ADEAB928BCB03DD37E
+:10B1100095711E53D98E73C07A17F89327BCF949DD
+:10B12000F8772ECBBD62E5F847F8D68AB6090DD57B
+:10B130006319E2D303C02C1CBEAF95EF59D9C07878
+:10B140004604C3F263EF4F37652786B01FD28D5395
+:10B15000D0D52CF8BF9779ED7310FF9CAE6A045DD3
+:10B1600079197B9EE82A6C0B47D709FB62F7D962F5
+:10B17000749765188FE17A97EBCBD45F3B3919D67A
+:10B18000BF9AD15C6C75A085C3EB3E4E8F4E78297B
+:10B19000C689D11B8C1334D11FE16BA258278CB305
+:10B1A000ACACECFFFC1060F6E8CEAC3B104FCBFE35
+:10B1B000D1CAAC305F3534C37275AD12894079792C
+:10B1C000E056E287E5FAF1E17D4D8DED821E3F6F9D
+:10B1D0006CCAA671D694F371D826DDFCB4BE9D046A
+:10B1E000CF20635BDC3A7A7B33934D6600C7E77709
+:10B1F00037EFC3FE171F7430A423867DE720DE39A6
+:10B200005C4F02ED22FDBFB54D891C84755FD8ED02
+:10B21000A075BEB94E8930C43F733F3E00EFBBFD01
+:10B22000294497171342FBBE08F58D5B93FC61D848
+:10B230006FCFB8D68D4198F7624AA81EC769DCFA6D
+:10B24000494B18DAF724869D59386EA3D57F10A68E
+:10B2500058A9024CC7C113FE7D133C1B7A74F883B6
+:10B26000FF8EF9151A7F898585FA5DC3E9C7319B81
+:10B27000D723C01DBAF52FC9B2D07A4F3DE4A0F54F
+:10B2800026CCF6123C1A0A12B484318847A6A93992
+:10B29000B09E746D12AEF38202FC09F4767E9912B0
+:10B2A00046F83095E3C57ED38D07909F1E15FBBCF5
+:10B2B000F0C0DC4948CFE75378FD394F6204F77599
+:10B2C000CECBCB618F2BF218F2861AF22D4FE6FB14
+:10B2D00050800E1AC5BA1ABD162D01F0DBF8D08ABF
+:10B2E000CF229E1B3D7DF7E0F36472385981FE6FDB
+:10B2F000EDB6328437C2C39983F545CD586F86CBFE
+:10B30000257F16ED07E1371EE0F6E6AECEE410EC41
+:10B3100083B959C83E310687869DCF7C419949FC47
+:10B320001CE6FCCEF94461BAF318E877A5D71E2EC7
+:10B330008771D8D1C944B72BDD9C6EED855B52B3C4
+:10B34000783357943EBC54EEC3F3BD51941B906EBA
+:10B3500001AE2B915F66223CC6CD1980F7B54D46F4
+:10B36000BADD3261F303D5B0CF7505366685FA755F
+:10B370001ED5C037556D463E827D1BCA636633DAE3
+:10B3800077CF38419FDD9C3E81D2270567C4E862B4
+:10B3900097DF42ED7075B651E06F86EBC70D0EE793
+:10B3A000905E41DE9CCFF0EE2B24B900F4C3D7C5EC
+:10B3B000AC3A7E68E87110DD33200F8413D0A7BD4E
+:10B3C0006A468C5E247C1A7675103D3608BA6BECA2
+:10B3D00003FA19A3A32313BC70CFAA9C273B46678B
+:10B3E000541F87CEBEE767C44792FF1A58B09E59D4
+:10B3F00087F3B57C129E8B109F9FA90DA7E3286150
+:10B40000EABFA3A4682CD1BBC007173DF4E344BC3A
+:10B41000254BFC84D9093CCF5DA2D2DDA69C2E032E
+:10B42000796315E7AC5D1B8C0CC0FB94362BBD47D4
+:10B43000F9A2427B9C9621C29F9BFBEDA9504E1026
+:10B440006597C0ABD5EA4A43782533A3DE338E999E
+:10B45000E4899FE355CAD99D369686E7718238DF25
+:10B460009B17652BD86EA7A2907E602F33D281D513
+:10B470002407BCB32DE2BC0BCB738FE4ADDDC9F761
+:10B480009B906621BEF86D3A085425060FBBD8FF85
+:10B49000B8016FFF00D4D77B9CFE0894C73337C92F
+:10B4A0008752986940376F4D45121BD0E179917BE7
+:10B4B000BCA1FC29CF4D86F6B779B30DF5B7FB3E9D
+:10B4C00069A8BFC39F6B28DB994EAEE33A8738DC8F
+:10B4D000ED02CEBA7A299707118FD5621F3BEC2176
+:10B4E0004F10CEE16ACF7A92CF1D259FF10CC13E5D
+:10B4F0001C1ECE7F76D42761DC84294D6ED2238436
+:10B500007C2E805FC443270E9216A333BB09CE6600
+:10B51000FE33EB930DB385DE730BBB85F41ED7B8FA
+:10B52000B8FA8D597F031961417A4D14F85A647540
+:10B5300091DCD85A03FA9C82FAE552AE2FF9EE2636
+:10B54000BC06453B16B690DEBA5CEC5FEA5FAFB571
+:10B5500033367033C06301D7B396175CAA41FA340F
+:10B56000CFDF2BDAC97262C1014D8B234FDB057D22
+:10B57000250578FD722753510EC9FAB090B7CB85D7
+:10B58000DC5E027C8C745B894F9DDEDA27C6E98B1A
+:10B59000D22B1BCCD1F3E9214545382488E2011692
+:10B5A000EA9B9D8A700E5323AB2BC888BFFF04D043
+:10B5B0009D437A0CFD94CE6EDAFB79A05F474DB2C5
+:10B5C0001F6D0B87D6F0D857017E8935497E8B37A2
+:10B5D00046EF64774079828FD37B6DBAD34FD561C4
+:10B5E000EDC4E43931BDAC46E877A9AC95F8609874
+:10B5F0001DE3E47439B21DC3CF1F399F439CFFCCB8
+:10B60000BAC94F7417E4E7BE057E91EE96D51AE9E4
+:10B610006A4568743AFB96A4B3B96C2ED159680395
+:10B62000D18543B4D93109E885C389E82351C2578C
+:10B63000E8DB36950DA880A763887F58A4CBC69217
+:10B64000719F83DA0BC417833E66D3D3413060D534
+:10B65000223A3C0E16B24437C897411BCB7810DA19
+:10B660008DD1562C76C3FE064B1DC90D74A8460C11
+:10B670007AFB3118F7AC8B8DA8EF9BF9612AFC039C
+:10B68000E5C0D68C373DB89EAD3646E73D0B5FAA88
+:10B69000D5A0BC5D96D92F6A4B61DCED09B2FCEEFA
+:10B6A0002EAC7F3C91972F3FF9A75D241F805E1140
+:10B6B0001F49021F49527F9FAE832BE0C13921876A
+:10B6C000CE19A709DE66BD5ECA09F3396C9EF74D37
+:10B6D000139E46DAF7B0F50269DE323A5FFCC76CBA
+:10B6E0009297AD06BE183ECE00E9EFABC4BE2D4921
+:10B6F000CF6584E2D89151F86FB0FD4A6F2F009C5E
+:10B70000BFABA0DEAB41EF398C8B0E18472978E92F
+:10B710003F51FE2BBBC2E3108E56688072DEC642DC
+:10B72000B41EC9AF0948075684FB00D583FC1D52DF
+:10B73000B271903A37C24581F6571029D77A4E96A2
+:10B7400073B9B6529C7F9538258C57D9C34AD13EE0
+:10B750004F58B7F6E03694739A03350A787FA914E8
+:10B76000D707F59A839E9734C41BD0B341EE3C5F54
+:10B77000F287B71F817EDD8356BF03C6ED0E3CCB3B
+:10B7800050EF7E673AF3E3A6BBB021ACAF3EE45E78
+:10B7900064F722DF0C9CEA9AC2D8D9763658661B29
+:10B7A000BEDEC12309762F6C36144E99F9348CD342
+:10B7B00053E070A33EF7C626AB1DF134B8B9218C17
+:10B7C000C0389D16EE57E07D8F1A6268DFDB377553
+:10B7D0002E42BE3B6D0BFBC7C1B36773F82EB4435B
+:10B7E000346F457926ACFF608F5A1E89733E6FC84F
+:10B7F0005188DF5E7BFED3B4FF6369767F028C3BAA
+:10B8000084FE0DC0DF31DBCE0C3F8EDBF1950C1CCE
+:10B81000FFD8BAADFE23B0AE631D0EB4A4D8B1DD1F
+:10B82000CE5A1CF75871B367BD6E7CE74DF6567C57
+:10B830003F78A3DD9E4DFBB99CECC1FD6CCA1D8F0A
+:10B84000B4D99D669FB416EBD73733DCAFDDB3D3E5
+:10B8500086FB73AA6C179E2F9FF05C7A752EDA4BCD
+:10B860005ECB9C4F41FBCFFB43B7E6001E57B69D16
+:10B870005D8472C95E96B2059FDD629DF2BC92F84E
+:10B880001D4A6B74E239D6DDB496FB613C9606C264
+:10B89000639A2588E75177609D73EA74FEBE79CC80
+:10B8A00070B874A3DF6516AE73BD67FD0C6CF7BB93
+:10B8B000F610B41B2A76D4C68363630E9763CECE8C
+:10B8C000E6AC365877F76EA71BE1D3AD847635002A
+:10B8D0005CC3992EFF63DEE1FDBE25FA49FA003C08
+:10B8E000111F6E387CC3EEB08AFA2AC723C0C5691F
+:10B8F000D3C9CD43B34A9B111E51789BE74DEB262C
+:10B9000079D1AD70BEFED6E159BBC3509EE90FDDC3
+:10B910008DFD8EF500AFCDA27D4E427D7F24FE19B8
+:10B9200012F5DD1DB0EF38FC3FD46465378FE5CFED
+:10B930001BE03975B3759212073E43C56BB3D04F08
+:10B94000750CEA2D30CED06E277FC2FB2CA4AF1130
+:10B95000E873560E97F7BE99C12D39687F4DF7935E
+:10B960009FEFE5D9C1AD39A407B47AB0FC31A0DFAF
+:10B970007D1F11FA65EC46A4D7E9BBC3609232F78C
+:10B980003883DE3AD2F91964432A9EC71D257F68A1
+:10B99000417BA07786DDEBD0F905A51EBDC4C7E5C8
+:10B9A0005B70CA853C38B959F5F4F564DF80BE4C4C
+:10B9B000FE4137FCC6F30F06D11FA893874B4C6599
+:10B9C000A99FBE94037211CF7DA127A77B7706178D
+:10B9D000A0FDF18AD51F01B86560072857552811C9
+:10B9E000D4D73B4A9E203D9E093D6E8958E74FDBE8
+:10B9F0009DAC6C0A8BDA732BC5FBA496B38FA27D2A
+:10BA00009D84FE4FF4D7B638BCE47F41E4C3FCD537
+:10BA1000627FD2AE233D12F6B3B245F841D9835CC2
+:10BA2000DE5803F9480FB00F835D1264263BA4C9AA
+:10BA300066B0E75699F407B3DD506DD21B76A0EEE1
+:10BA4000847AA1DAEF447A7A777ACEB12C2F5587AF
+:10BA500007A47E0FED420527B60CE9CE9F1342FEE8
+:10BA6000FCB85D3B8DF2684BF011E710FAADD5885C
+:10BA700013E5496FF9E79291EE7AEBACE5486F83F5
+:10BA8000EDE5D4EEB5F6203DAF08B951E1D77E4FD4
+:10BA90007C29F4B3EAF2D2D35D3ABC5669B79DEE85
+:10BAA000D2ADBFB2A0CA5096F4556965ADFD71CE56
+:10BAB0009759B9D2EFA231833E6A3DE40FC5392FC1
+:10BAC000E43391A9EFEAE1989C2BE846E853F74F5D
+:10BAD0005F3076347D46EE53C247EE5FD68FB4DEDC
+:10BAE000DFE55C9FF566BFCFF59AD719C5D308EDA2
+:10BAF0002BF1108373E077873B56A25CA8F0877226
+:10BB000073010FD565CA96F140273F16FECA1F077D
+:10BB100092236158CF8B3EEEFF4C6CE17665625903
+:10BB2000D5223C9FDE2FBEEF2C50883F6B024A444B
+:10BB3000837FDE2AECD59FFA18C51F805F5F4D8694
+:10BB4000F2EBC536EE47665AC51D7362766A621D12
+:10BB50008F4FECB033FF00F69BE6F26F86F7CB25F4
+:10BB6000FFD51AE310353536C33953698A3B249A19
+:10BB7000CE99A512EE7300EED931B88F647F8C4454
+:10BB8000274CBD94877E31337C369AE063B6772AA2
+:10BB90009F33F1C735DA3D077BF25E9C807A469988
+:10BBA000E29F82F8C32AE897A83D49E1905EC94721
+:10BBB000C2DE93F1AA1D4BABC9DE7B0DF581B1143A
+:10BBC0006F9A84FE6A39BEB4F366FAB5FB725347C6
+:10BBD0005EC709D16F6B557C3DE104EA09B3F8F308
+:10BBE00006784E5DBA30239E9E70A250E809508FB1
+:10BBF000FAC189DDE5FC5968D4135879EE55E0D2D5
+:10BC000041FB4D989237361EDF1D9B157A30570742
+:10BC1000F7245F2B2BD3C17DFD6CEDCBB8DF2AE180
+:10BC20008790F3817C3FAAD7C3CCF33D95E316F60A
+:10BC3000C6789217F27935FCA9EE56867476BF4D18
+:10BC4000AB457DCFEC4F3A9CCBF5C49E2CAD05EBBC
+:10BC5000992BE72AE376487FB56FF6441E7E20BF16
+:10BC60008FC91E94F6D301ACCC8FD985AA9BDB85F6
+:10BC700089E9978EBAA1AA3937F40CC2A3F85224E5
+:10BC80006C01BE735428A43F39D219E93DD76C87A3
+:10BC90005D63BB1E646AA0E7AD8DDC1F5F3A5BA5E8
+:10BCA0007262C87A90CE05931F2751BB4C76D8128A
+:10BCB000D00384DF86F4A953429F0AB256B2F75CE0
+:10BCC000B68813FD1566BF4D6DBA65602AC8F5DAF2
+:10BCD000824B35DE99D4DFE0F7A9F5661D4D15F5E9
+:10BCE0006E782E09723FD072F403E1F835919E2CE4
+:10BCF0008CC3F955BFC6B89D87FAC58AB55F98F160
+:10BD000035EFF5F30349FF92D417A53E03F2A5677B
+:10BD10003CE265A1E225DBDFE42732FB85A45FC6B8
+:10BD2000EC3F32FB8BDECBCD247C48FD4BFA7F7E93
+:10BD30009F6BD4C3FE0BD803DBF516C2910AFCDD62
+:10BD40006B63193BA773FF0EEA4BC74A7FE046FDC2
+:10BD5000E2BF4CFDAEF57CEB8673E83C9EAB2F2436
+:10BD6000D850DF0E7A42E44F5CA218F9242D4FF828
+:10BD70001BF35C7C1E1147EE6E6F93FDC3286F8230
+:10BD8000E9F64882121B8715E45F133F8D9DADA530
+:10BD9000E6E5933D72431ED2B31FEC9119688F08FC
+:10BDA000BE2F48A5FD302D959DD7C78DC5BAA3EBF5
+:10BDB0007082DD32E3FDCF3F218F19E6B91ADC76C0
+:10BDC000941439EDE88F001C5B395DB9A3FEFB2CA0
+:10BDD000F4EB6CF0EAF58A7A8C5BE4A2DEC9E31A34
+:10BDE000F2BDCE7FAE22FD26A687B4609C73F5CE51
+:10BDF000BC689C8CE2A751FFBB8F51BC488EA3321C
+:10BE00004F07F101F2AA5C8F358E9F5EACB749F007
+:10BE10000100DCE9009259BBD3CA785E02E713192E
+:10BE20008F500B83E599B0DFB5DB148A1BB370ED3F
+:10BE300051D4EFD7897ABBF0BF99E348EB441C8615
+:10BE40005937909ED6F49031BED6D8672C9BF572A8
+:10BE5000E9EF576191B8EE7F403C713844ACA3C321
+:10BE6000E100EDF36F140E920E2B723FEBC1BC9606
+:10BE7000EE84D0AE068C6BEF75923F846C48E497ED
+:10BE800001F885FD6CDB53F008EE675B9E95E0D70B
+:10BE9000ADF03C97A3695F730EE9E86D9BE0F35B3F
+:10BEA000F2BCDCEF82E7128844963E81F848E6B5A2
+:10BEB0001C4BE37AA53DC0F5C643938F2CE5715723
+:10BEC0009EDFE20BC4F25B4A013E33047C7C539A52
+:10BED000FC03F09C116826784C7FDA68AFDEEE3305
+:10BEE000EA953EB3BD6A2AEFCD8B9FD7128BB3097B
+:10BEF000BFBB58BF99AFBED9CEE32D4F80DD8ACFEF
+:10BF000043ED6E7A7EABDD43CFFE762FE96987DBAA
+:10BF10007DF49470BFDF16ACC7B896F4434AFFF8BF
+:10BF2000F7F3B8FDC6027C1D95622F8BACE9C908FA
+:10BF3000E7E301AE178E74BE54971BFDA0CB82C6FB
+:10BF4000F8DE8A5A637CEFEE99DA73785E26CDF4D8
+:10BF5000D842BA78D43AB1FF1D5FE3F12639FEF139
+:10BF60007FE47897E58B62FFAF0ABA483A9266F3AE
+:10BF700002B2AA1EAABA15FDF6CC9D734DFAE0498D
+:10BF8000C197499BDD36F40B550DACB4E338EB7625
+:10BF9000C138AE6B1F676BC6C40C637CE1EE3BB16E
+:10BFA000FFF1687C61E39DA5507F5CC417DE7EBA1B
+:10BFB000F5EB6117D2ABF673941FD63CED0CC2E3E0
+:10BFC0006D719E437908DFCB32FCBC9C3271543FCB
+:10BFD000FEDB79F9C3FDF8D6854A6BBCBC96CB79FC
+:10BFE000513FDAAF496E39A37EB44BBCCCE5919A90
+:10BFF000CFE7EFFC296BC1713A9F652D87E3E8F32A
+:10C000007FCC53E478EFE591FD2FE560F00FF1C6AA
+:10C01000B33AAA2621BC2FDA785E8C793C35DF2E24
+:10C02000C7B3E463FFF4E8FAD47CDD783B00068311
+:10C030008827D59D4C714D7617C53F251D25D5BB4D
+:10C04000EFC0BC05302C199E2F49DF71DF91877E30
+:10C050009C9F64FB1F6323E3F51782BEDE12FC7511
+:10C0600011F90BF8E8BCE0AFB3C85FF03C23F8EB84
+:10C0700067ED7E2AFFB4BD80CAA7DA352AFFA4BDCA
+:10C080009C9E27DA83F4FEC7EDB554EE6E0FD1F314
+:10C0900078D923B7E2B9F3DB6F2A248F475ACF67E9
+:10C0A0001EB51AF8A7654F9281DFD63F34DE506E79
+:10C0B000EA33C6CF1BBBB20DE5356DC6F8F9EA56BB
+:10C0C00063FC7C55CB3CC37C2B430B4DFC7CBB8978
+:10C0D000DFAB0D652D9FEB89D5E5AB0CFD1C9E46B6
+:10C0E00043BBA4A52C140FFFE5F99C3E8F94148D3F
+:10C0F0001D1AC5CF616FBBFDE7A89F44CB6A88A11D
+:10C100003E6F6F5B42EFEF4FE0E79DB95F7D3E3FD3
+:10C11000EFBACB9A820B18EA458BAD7ABDE7D3B361
+:10C12000424BF375F6A0DDC3EDB17726D7583D40FD
+:10C13000474BCB2EBF7803D051689091DDA381BAD5
+:10C14000E7013DB8A0F5C1853740B9267C8FC17E97
+:10C150002C6A79F205605F16283BDE3901FAFB672D
+:10C1600087EA71FC12CFA517B0FF828AD92A92F50F
+:10C17000FD298CF4D18B19F6C8C138F4706FBE62FA
+:10C18000885FBDDF73DA1CA7CFF2B152F42367F9E1
+:10C190002E95A25C83B286F1AF43B342F7229FC1D2
+:10C1A0007B0DE5E4FD33D667E1793252DCE86B02C2
+:10C1B0005FD29F20D7B5A384AFE7B8882F0C99E250
+:10C1C0000B3A7FC23FE58FE24FB828FA0D7D35BEAE
+:10C1D0003FE1A2883B5C947187AF55C78D3B5C5CA7
+:10C1E00024FC09508F7E848BBB6BF973D1E87107F7
+:10C1F000B93F388F1EA2F3271A77107ABEF09B1F23
+:10C200009BA5FD33D6AF9FADEDC2E76F6668BB114E
+:10C21000CFC775F14FF7445DFCB3EC0786F8E753E1
+:10C2200039A103F93C6ECDD0AEEA0CB3A1846C8C7D
+:10C23000C70637C6A3E3FF9D2FF5EB813F2B3EAB2F
+:10C240008BA35AAE7C925D731CE09ADB15F0BC1494
+:10C25000B37E9384101917D3FB9EC80B1D417875CC
+:10C26000A57CC7CBF3AF2CB1F30385DF08FA907937
+:10C270003E391ECA2B945B278063F09CD99E72A91D
+:10C280000EED94410137F3F3DFF3DD029EEE0988F2
+:10C29000DF27F2823F267C3FDDEFA5BC36F1FE5A58
+:10C2A000D7F1B83DF873D463BB1BADDE835C6F2759
+:10C2B000BFC5CD819448AF2E1EFC6B3C2FF3D1FF40
+:10C2C0003834D90EF8EE0CBDE0C27CF037F6A898F1
+:10C2D00011C3BE911CB621FE6B7DFC7C5BE0097D29
+:10C2E0006268143E077A186FF1D03A2C96023E2B02
+:10C2F0007F86157C9ADB0FEE7937D50BE37D632FB4
+:10C300008F7FDDBCB7C9D9A81B3F6B0E3F77BA91B1
+:10C3100066F2303EA9443051BD3670F9D5B9185F88
+:10C32000F15AC8CFF1C6A6DF9E5C817E47CD4A7E1A
+:10C33000C73736BD43E5535E4B2EA2EF0DCF6F4E90
+:10C3400062FB9BFF71DD446EB77078ACD994FB78CB
+:10C350006F26C5C59439008753DA3BC9D9D363F139
+:10C36000B3350A0BC6D363D2E670BC2DD65AEFC4E0
+:10C37000752D0E3918E6399F6AD8FA732C7FA354AD
+:10C38000F15AD1AEF7F1796AF7A8944F0BF0D98042
+:10C39000E557FC490CE75D107A52C5F6BF9BA1B08A
+:10C3A0001B94EB0857ED9D54E4C33790FEE2ACFFBD
+:10C3B000D7F2DC147C345505BECF41F81F75E9FD7A
+:10C3C00094929EBE94A765CF21BF5FA825487AEEC0
+:10C3D000D2ABE8A79B799EF6372FA9187B487CB48F
+:10C3E000F546F42F0D5BE708EBCB9BC3E5E46F0448
+:10C3F0005FDCBC577DF536A4E74D36CA43B8252F20
+:10C400003807F115B5B7AEF3B921F3D7060BF87DB0
+:10C410000450A7691E58AF4F8575242889FE30E760
+:10C420002BF2CF39C5F907EDB4B1D06E0DEB1F403B
+:10C430003F1F53B59D56F41F16DAC83E5EB1DA961B
+:10C440008C7889C5CBFC067BC3FC3C8FF131CAD309
+:10C4500070D27310EC6C8C97E00F68E250A90ABDA3
+:10C460007FC6C31AFCF37191577A6FC16D0F8703B2
+:10C4700060675878795DC16D376D862D9D9FD47A40
+:10C480007219ECABF741C5DFE1C5E7815D8D78BF7F
+:10C49000A24DF19743D3FA8169F518626CEE719061
+:10C4A0008E7F6EDB176E457A7DC7C3DC48CF2BD2FB
+:10C4B000383DAF3DC12216287FAAEF418A7B064F47
+:10C4C000A894B726E3B267D2785CF6CBED03B46EDE
+:10C4D000B46B17CDE12636FE8CF3C33AD08F5AA643
+:10C4E00052BC743C7377E3F992A86596727DDA6D5D
+:10C4F000A7384F05635F473F4F1BB79B0B455EA4B3
+:10C500008C63B10BDCBE6D815F9427E3CB8DF6713C
+:10C51000BEC9FE95F2CD1C6F01FA0FE3FB8E3946C2
+:10C52000FB7824BFBD7C3E0D7A04EEEF3B228EFBF0
+:10C530005DD0D7319EF92CE8EBF87C0EF4757CFFCA
+:10C54000AFA0AFE37300F4757C1E017D1D9F4741D2
+:10C550005FC7E74BA0AFE3F365D0D7B1DF8F405F94
+:10C56000C7E72BA0AFE3FBA78BF9F9D73DC51ED9D1
+:10C570000CEBEDB6B19F215D854B455C58C4C9B647
+:10C58000A54CA5F3DDF927A072D0A70695D06710BA
+:10C590001FE10C27B51B4CBEF4C7FFC0F2B64CB26E
+:10C5A0004398EAFDEE10F4EBFA62A6BF178A3D76D7
+:10C5B00046F2FEEC71E656409F796B993213FDA866
+:10C5C000E7EF50FAB13C788742FAC45464BD9CD876
+:10C5D000395AF4AEF7209E679DC94CD0E3237BB552
+:10C5E00074E88F6B237A1D5B8F76E97C872CBBEA1E
+:10C5F00035A0CFC63645D8A9EE7D48BFDB14D93F5C
+:10C600006D2FB6EF92FD45F98445F6FFCC1EB4B709
+:10C610004F46E76B5885E39DCC92F54D75583E1B10
+:10C62000CDAB2B5E8DED07A3E3E7EEC5F2F90C3938
+:10C63000FEFA5554B6C9F2E3D4FE7C2A6F7F4B71E3
+:10C64000EA7EB49BAFF7789D217EFEC139A6E9E36F
+:10C65000399B8AACE67C70F2BBC938BF25C935E589
+:10C660005AFCA5BA383FF94B613E1BF2D9E74B5350
+:10C6700026A1DC3D9BE18F6BA72C2C1AC17FAA2938
+:10C680003CDFDECD42981F9F28DE27F6F13C7ABBC7
+:10C690004F1D96477F2DFE4499F720FD89B54DA388
+:10C6A000FB136B4B8DFEC435A27E247FE21A933FB1
+:10C6B00071E526531C22F4FEFC89756CC086761841
+:10C6C000D314E2A33A77FF8B13D1DEBFE0257F229C
+:10C6D000F3BE4CFE56797F02FF6F9983F7CD78F950
+:10C6E000ADBB140FDA15BD772913F179E62EE546B7
+:10C6F000E4AF0B77296EE4B7CB73F93D98FCB7FD37
+:10C700002F7BF1BCF558FC1C1CC17FC15045B029E2
+:10C71000C5DB0BE39CBD4B1987FD57DF9769477A53
+:10C7200000BD53D023DB83FC624D520CE5BC499223
+:10C730001EF73E8CFC317FBCE497657B905F4BED30
+:10C74000B27F3B95578614D1FEDE3DDA64E0AF053B
+:10C75000B2FD843AAC5F962DC7DB4FE3CF4F92E535
+:10C76000AF12FFF544C7FB5F34DFEB2821A9FC00C3
+:10C770008D575A25E5D9742A77D7C9F15BF7625EE0
+:10C78000EC2A8BEC7F1BF1FF5A26CAA8BFC37EFFA1
+:10C790009F381FD6CDFDE32AE4A73BA3F57F7C1885
+:10C7A000F9AD4E949B9F79620FD6FFCDEFEF2F3CF2
+:10C7B0009FB9BC9A0D2EBA212FC617E673A5AE906D
+:10C7C000EB9D052D4FA2F86275AD07ACC88FB1B8CF
+:10C7D0005A5A4D10E9DB69A5FCB9A087DD1A2F9FD5
+:10C7E000FF0F73F9F9F485B92E83BC1E39BE167F8D
+:10C7F0009C86423E4ECF0216D7CE3D346BC1E6B981
+:10C80000F931BD0155443B3C4BE06981E77B334244
+:10C810003D588FB20BFD30D2AFBD44E41377947C0A
+:10C820003DB800EF2F15DAFCC21D3EA88FF7AAE233
+:10C830009EEBAA053CCF2BD4EB207BADA647E49121
+:10C84000585D148F506FB21FA0B89988A78630EF3B
+:10C85000388BF2BA46BDDFA19AE2A89D62BFA5B3AC
+:10C86000DFA538F5DA5778BEB08C63D78B75AD4548
+:10C87000B90CEB6E6C522216E8D7888207E3BA3EF9
+:10C8800016F166C6E2CA2BCBD4013BDE0B13F7339D
+:10C8900098D087A3F1F01A6F3FE6C7A85A825FC30A
+:10C8A00079D84090F2E2305E94C9A2F1672947AA94
+:10C8B0009A6FB80BE3D43AB94571EA44364C6E909E
+:10C8C0005C88E63589387A343F47C801199F6E1075
+:10C8D000FB5A1E9503154B50CF4DBC5FC4A945FCB8
+:10C8E00059C6A9AB4CF7DA1A030BC7903FD7AFFA7A
+:10C8F00029AD26DD789F29D18487A945FC5EA58CCA
+:10C9000053BF32D7186FBEDFC648EEF66419E9AEE2
+:10C91000A488DB3D9F2C927EC8C48104D4BF999328
+:10C92000EC905EF4E78CE5F6085DE632F975D4B676
+:10C9300055E47FC47A05E850F1BDF49F2897B15CB7
+:10C9400004ED55BCDF82F87059C81E95FE1F545384
+:10C9500016E5901FE8DC5CCC0369ABA771E47DF6BB
+:10C96000C713E3F3C7AFE74A3DA1DF86ED56795E13
+:10C970003A85F3FDD97E20618745F5182FCF7F4991
+:10C980009DEB9571091BBFEFC76C4B6790BFE4BD72
+:10C99000B9E41FEBF7E23AE4B9B4EC7B4FD1397656
+:10C9A000ED7170DEAFA1F0DF5685278C1CC7981A99
+:10C9B000E078F2CD0C3A3064CE26C8B883E6C49055
+:10C9C0007854CEE2460A0C72B6AEE5BF819C8DE982
+:10C9D000FDDE3A1CEFE3B67EA0A70584D772EE7F9A
+:10C9E000FBB8ADFF07F9DA4AA4C30F7B9EEFE5075A
+:10C9F0009B719EAD8A56EBA27B31CCAF8C1E2FDC97
+:10CA000088EDCDF1C2ABF931FEEEB718DD6FB1ABF9
+:10CA1000E0A3E9B7F832C00ECF6BE0A743C44F01E3
+:10CA2000CE4F7FEBE71FECF747B8DFAD4A7F24D14D
+:10CA30007AFDFD064FE4855EC7F1A7A63B1B509F1C
+:10CA40008179BCC87F517F08AEBBC0E00FD9D3F25B
+:10CA500021F843609F6F115ECB385EFF06F0A6148D
+:10CA6000E27E34AE47FC0DD2654621E2B09FEFEF87
+:10CA7000AF30FF0C9AFF10A797287C849EA4834FA9
+:10CA80005DCB5F073EA5B4BEEFF2F57D0CF0B98239
+:10CA9000E8D5CFD77B35FB7BC35CAEB742BF7AEA24
+:10CAA00097C7E960A3D0ABC12E5F78833766978FB5
+:10CAB0009DAD3516F2F87353A121CF545B87E55134
+:10CAC000ECE64F17A68E6A37DF8DF51F17BB798FFF
+:10CAD000805B2C6E13A17B7120C129BE5C2FDAF61E
+:10CAE000B6552F9E867935007F2C3B703F56DD7EF4
+:10CAF00032546E6F9BEEABC9EF1DC87DA9D6BAB19B
+:10CB000003DE183C5F1BD36AC7FB50CD5A4A37DEA1
+:10CB1000BB5DD87599F206ED9AC38B76E1273CDEB2
+:10CB20006E8CCB566B7CFFF61637DDEF93F7DDE4AA
+:10CB30003D94E681692FD9F1DE1CD82F69307E65DE
+:10CB400099ED9C7EDF0ED3BD14D5546EFB59E6F6ED
+:10CB5000A3BAF6DF284C36E437837E534EDFE9E88C
+:10CB600052DC22CF97F2329AC5181D25772E46FF48
+:10CB700025E8715E84C3C29D0F0E623CCDDE65A5C3
+:10CB8000D8F9EFDBBDDB8F024B25ECB592BFE1B7E7
+:10CB90006D0AFFDE47058FE3AF15717C66F23348FF
+:10CBA0007FB88463C2033CFFC35E70B68CEE37D699
+:10CBB000AD1BCCE7B443FE0695AF8CC9EF6F5409AB
+:10CBC000BAAA0F5CEEC27ECB3D1643FE90D91FA1E0
+:10CBD00032739E3CCFE354359EC7A9FA789E7C22DF
+:10CBE000D3E87B1D895BAA099F551ACFE304254929
+:10CBF0007C778BE3A532700FE5F998FD088E02A3D0
+:10CC00001FC24C97667C9C36E1E33195DF4FEA3ECC
+:10CC100061F587E175F7434D3DE83F0F3F64213FE4
+:10CC2000C605991F028B447FFE0A16852FE9CBDDCE
+:10CC3000AD3C5F40E265C54E9E3742AD0C7EFB7455
+:10CC4000A6FF8EC70AE157B893F5D37D87D56CC888
+:10CC5000867CB0065DE956F4C778E9B99685B730A9
+:10CC6000825FA82713E67BAC75BC1FFDDA0337DAB9
+:10CC700052DEF4713B229EFE1A8BD7AAEC4D9D9F8B
+:10CC8000FFEF7EADF7EBD7B286E97EA9C71E99A26A
+:10CC90005CDDAFF5238C4BE8FC5A17768AEF6D8884
+:10CCA000FB1683B6D6493B5DD8CE4BE7E5983D2BC6
+:10CCB00016231D1CDBFB03B7B8FFBA69E2E8DF856A
+:10CCC000C8298A934F7A7C2EE379209943748FFA8E
+:10CCD0008CCD98971BF51305ECC22F139A57941A15
+:10CCE000D38F993B9AC7595C44FE237E5F5BFA99C8
+:10CCF0009A73430BF07DF125410F154A4481FD568F
+:10CD0000BA9417156F6C7E66CEA3FF7B3C8CCB0963
+:10CD1000840FE63325F0BCDAC14C567B380E7E26F4
+:10CD20001773393A383B3EFE643DE827F716A57283
+:10CD3000FB690CF72BFCCA3EBA5FE18BF1E846E2D7
+:10CD4000F7D07CED4B1CEFBC9C9413EAC0F69DA180
+:10CD500020E5EBBCD567F57620FC075A5F2B80F207
+:10CD6000927FB2BA311EFE61C7F952E7665E539CEC
+:10CD7000EFB280EF99685EF7A67AD4077BA57D268F
+:10CD8000F4C755E3746538928B4EF0F6DF7B76EE90
+:10CD9000BEB03AB2BE79F773757BF1FEADD437A160
+:10CDA000BC1ACBB23F0B574C2A057D766D8B8C2776
+:10CDB00056EC43FD363A5F78F93EB4872ED88CE3C3
+:10CDC0004B7DF5FF3EBB681F8E1794F38717ED432D
+:10CDD000FDF7ACA93D7D9F12C67BFDD9526ADFC825
+:10CDE000E4F8A5B4DFA85F31BC7135F63F6997E57B
+:10CDF000CF523EC1F64C3EDEB1E736EE45BFD147DD
+:10CE00006D3D1FF6F8EFB7FD487AFF191BCF1F0CD9
+:10CE1000839EF65826A651F65B39F369762BD07FB0
+:10CE200091A6D079F45BF48343FFA0CB22E8EE1FF8
+:10CE3000F6A24EBFAA44EEF320E5818C44771B0294
+:10CE4000CF3C6CF4173FB3CAB06EB6B11EFBCB75C6
+:10CE50009FC0F6B0EE551B3FEDC175AE92FE8D70D2
+:10CE6000E75EDC5F778AEC376DDF68F38602DBF71D
+:10CE7000E2BCABA2F37C85FAAF4A94E37DDD98BFB8
+:10CE800012DE4FFE8FD8BAD61BE0F9FC73FB099E69
+:10CE90004177640B9E0F410FA3F3F8CE960ECAEFB5
+:10CEA0008EF2117B2083F8C8132DEF35F2D17DB4BB
+:10CEB000EEEBBD2E384FD3E7E1F9E7E376E2F5DF9D
+:10CEC000379C93B8EF3E2E87241DD5B9653F803F30
+:10CED000C893B55E39EEDDF52DD3AFC7BCDCDE0DF2
+:10CEE000FE8A917E2BF90938C9C43FD7365EA7EB7D
+:10CEF0005ECAA36806B91E2F1F7BE35C45FA336F39
+:10CF000025781648FB9949BD63F13C9D5F8E79A356
+:10CF10007A47C53C32408C7A4737E659CDA27C2E01
+:10CF2000929B1AD4787479403717F3F85AA7C893AC
+:10CF3000CCDBCCD6EBEDEDFF399FAFE71BF3B9DCD3
+:10CF400094DFB73DBF41A13CB1CEBEEC3178DFEDFF
+:10CF50005CBA773BCAB5C14C0B7DA7E08CF8BEE646
+:10CF6000E0171D19F7C1FB53194E3FCAAB53293BBC
+:10CF7000E93B6AE7FC56419FDF7903F959E7570C13
+:10CF8000A35C917EC396EF77911FF0B4979773FFE0
+:10CF9000ED9937F01C633EF3FDCE00E931F65BE11D
+:10CFA00018C1BEE2FB9C45A2BE6ADB535FADC63131
+:10CFB00084FE22E5A7F9BE27FED8F4FA578F95EB39
+:10CFC0005F1EDECEC3863AAE58705C5E768EF05D34
+:10CFD000D85A797FD9A44F5599EE2733F11D54A91A
+:10CFE0008F174D68F4A31D57B4C1A81F9DEB79A1FD
+:10CFF000AF00ED5ABFD58DC7E4ED3E63BDD4C31677
+:10D00000F73C42F628E885867964FEEDEDACBF8BEF
+:10D01000EE857B5F3E6A9D18B35B3ADD55A4A7346D
+:10D02000FBA004FB39F9A5D2E47CD40FFAACF84597
+:10D03000589E7BAFDB07B4B35926D039ED57147D2A
+:10D040005ED0E6FDC6BC205E8EF9E3DBF61BF2E89F
+:10D05000C277AFC172D4CFC956EE473E8AFAC5D85F
+:10D0600052AA3FAF0A3F186BD88FE759CCAF779AD7
+:10D07000F83AEA27634BF6233D05A3E7DF0ECAFB28
+:10D080005BEE16EB613F23F9D1A97179F2DCF7135E
+:10D09000CEE0F781DE6F7BE0CF67893F83FCBC3356
+:10D0A000D7179D88748E117A1DE68B9BF93C39C089
+:10D0B000F3EFCAB4D95DA95EEEBF72007EB4D5D6D7
+:10D0C000D5E83788E5AB14D277D2D68E905F725B05
+:10D0D00080F3EF2BF346CF53592BF254461AA7A9EE
+:10D0E00084E7030C2AEE1A2E97AD0CE572E983D97A
+:10D0F0002E8C4DC976A525FC1C786F86761ACF1B21
+:10D10000B33FED02FAD388CFB8DF63A9A01D75271E
+:10D11000FF5EBDFC9EC9F914977F33BC5FDA27FC24
+:10D1200015E57F9EFFEC57F38CDF151D29FF2120AD
+:10D13000D69F57727DF21F1E4FD43484D710B4454A
+:10D14000FFE0B07C0891E720F32012033CEF4EE6AD
+:10D150004374865B097ED7FD9E8B38FF814EC706E0
+:10D16000904E6BB91C917476749E97D3DFDB7EA2D0
+:10D170003F4977D03E358072A486B72F7A9B7FF7E0
+:10D1800042EA17C9CF0DEDED984C72E8A6805E0E0D
+:10D19000B9A2F722330271E4D0F185DA27023AFB13
+:10D1A00008FA670752E3F69F1288633FFB66067D25
+:10D1B000346EF43EA7360DCBFFDDF320589F39EFD8
+:10D1C000849F17E6BC13A90F36FDEB2F5663DEC90B
+:10D1D00095055A15C713876F54AF1CE27A4E4C9FC2
+:10D1E000F4733BECFAEB8B8D34BFC8A7F910C6DFA4
+:10D1F000A81F5FEA4FF0FE9E802E8FE7A366BFC197
+:10D20000FAB6047471930FD0FF01DA9F88D7FC053A
+:10D21000D6FB30AD57E8FD1F41787E3B90FA915E1A
+:10D22000DF0BB4BE0A713ECF63F2DC7E89DE0FA352
+:10D23000836BA6FFD702BAB8B96EDCE3FAF946B23F
+:10D24000CFA1DD4FA87FC530FE39AD1F7794FE67B3
+:10D25000689E68BB68FFB37AFABC0E7CFE4B3D7ECD
+:10D260003F8473E4F7B4DFC97CFC378BA270FC0306
+:10D27000CD2BDEFFDD4F76553AF71623BC5A393DEC
+:10D280005D837E3DB598FB6743DC3F1B96709F2610
+:10D29000DE0FE17DD2A5F3385DDD92179C5E9C1F09
+:10D2A000B36FA3F6087B781FAE376A8FE040D30DCB
+:10D2B000727E9FDEDE58F82F07F7E17AAD0B79FB1F
+:10D2C0008262F71A94B3E632E82345B49F585EE6CB
+:10D2D0003C2C5F6D5C8CFFE33ACDF17F5DFDA2627B
+:10D2E00063FE02E9AFA0B7391D80E3D7EBAC131A98
+:10D2F000A15C59CCF557D03FE2DEEBAE2C8EFA1193
+:10D300002A8B75F918278256BA1F18D553C209649B
+:10D310004FC5F4A843FB8CF736BE4DE51281DFC63E
+:10D32000E2C3F5629D77D23E26887D5CBD7D88DABA
+:10D330007B78FB38F54DB4CE74BE4EE67AF9825553
+:10D34000170F434EB3609C17FF05E74CA96D593189
+:10D350007E23EA488FE2B542B9718FC4EFF7F7191F
+:10D36000ED43CE7F2B05BD6F2E3E528FF85BF9AE9D
+:10D370005CAF8DECC5BC681ED311E29FD3C21FE128
+:10D380002E81F6E9B4BE365ABF97AFEF4318BF8B74
+:10D39000C6671C3EB52C6C9B384A9E459FC03FF427
+:10D3A000BB9FFA39F9BA6A430AE9EBC126E068C0C3
+:10D3B00073FD0916D7CFF49562BBECFF15EAEF12A7
+:10D3C00076AC3FFE7DD9DDB1B8C96E6AEFE6F359A0
+:10D3D00041FE23DE02A1E30BF13B10B5E27BE3B596
+:10D3E000652A7D6FA1B6E0D252E107A1F8A68C8331
+:10D3F000973E3099E29B896509DC5E741AFF8E4581
+:10D4000070AD83BE2727BF5B2BF332AA98F1FB7266
+:10D4100071E25B067F8BF48B44BF27674D27FBD6F9
+:10D42000BE5FFCFD27D3F7E312DB18F9B71C5DFCE8
+:10D430001EB8394ED5B0A9F5B542CCFB506D149746
+:10D4400035C733CD7F0F63BE93696372281FE5F93B
+:10D45000E2D4581ECA5B7BB25DC88766FBF9AD910A
+:10D46000ECE73D46FB7950DACFDAF5B19F4F141B5C
+:10D47000EF0FECCF0DFE84F0AC6A74BE1D29295A63
+:10D480008A7E8477441EC5D987262C417F54B88F65
+:10D49000DF573827E2FC32DE7FB690B9DCF8DCE2F9
+:10D4A00020789E5D9712C123784C5773057E5750A4
+:10D4B000DAD10879F47F558A7D9AEDEDC402C0E790
+:10D4C0002C6233B2B3CFBADD1417A8EC11DF97107A
+:10D4D000F902D2CEAE14F7F8D796F17BD5E8B14376
+:10D4E0007A90DF0FAC1476B8B4C7077EC8147D1EDF
+:10D4F000C052E627FAAD01C2C0E772F13DC55A3706
+:10D50000DB828BFACD8CD01FE99CDAC3E9846D579E
+:10D51000E9EF5C9DED7B90CED591EE313884BF81F3
+:10D52000E4D8C40FC5CE7795E8CE8F6B386FC6515F
+:10D530007B95F37117DEFF4D8D7D5742DE9BDF9E9D
+:10D54000C2FD283797703F93F929BF1BF17EE5078D
+:10D55000C8CFAC128447CC9ECF2EB936F9398DFA9C
+:10D5600089EF56A4611C889F4BD34BB85EE01DC366
+:10D5700083B83DF6D1F300724B4689E7B2ABE711B1
+:10D58000CCC3F9CCFD2F0B7DA43937A495F0783F9F
+:10D59000D1AD39DE2FDB9D44FF549CF3F673255C3F
+:10D5A0007E9702895A7286DFE77FBD5D3B833ADE54
+:10D5B000C9F6727A9E52C3C998BFF59AB8CF0F8A3E
+:10D5C00016E533C9BC28396E6D5DE9990BBAF3AC29
+:10D5D00072D1A39467D6E93BF8B202EB3C27F2BDC7
+:10D5E0000693BD74CE858FF3EF4B2DAFB9EDCC050F
+:10D5F000DDF9615E2FE6458581D5379470BFE60B76
+:10D60000A58E81F979F8BD26CE874D7D67E93E4C20
+:10D610007D5B030BCDA0BC2915F17B6A1EFFFE428A
+:10D620006581958575EB1A3B5B5B57C2FD3ECD442A
+:10D63000A7B1BCC0167C5F6AD3C6E0DF9F94FE49E9
+:10D64000192F282DF915C5DD065318CD1FF4B00884
+:10D65000C6DD176AF7D88730EEE2F1927FA4A1C445
+:10D660004BEB6CEC3940EB490C5CA6F594AA00EF4F
+:10D6700071C3E12DF9A25BC05BB76F82F748FC5B19
+:10D68000B9484D46F8BE86F882763D826F8EA997DE
+:10D690005CEE38788FF62B2835C0DBE12937E0AD1A
+:10D6A00053FBDC18DC8FC473A3A87BABC7FA2AE258
+:10D6B000F15DC023233CC6CF83388EF8BA99B17F81
+:10D6C0002FE1DF9993F8AAEFE2DFBDAEEF2AA5EFD5
+:10D6D000C5D517DC664FA33880D28FF725D796358E
+:10D6E00030D4F7ED5A0A7DDF4EE26F6919E04FB78B
+:10D6F0005EE0C77D253ABDF303F8D71F27BC0B3D7D
+:10D70000F8C3F6FFC37C4F97C4D1CBFF52F187E13A
+:10D71000DFF3E1E7EECF84DC303FE5B93B627E33F7
+:10D720005BB2A6E503AC43F20DF26D8782F9938AF2
+:10D730000DE92C88FC8BF7D70A7EB105E3A1CD1E3D
+:10D74000D68F67E16EE423809BBD3CD38EFCD3B8BB
+:10D750002793E802ED7F82A738A75F8E9DD367E904
+:10D760007D0BA78BBF76DC07D6F30EADA74EDC2F63
+:10D77000F888C5A56E2A0F3AE6A37F563B40F2E52E
+:10D78000E83CB7944F19FCBB4DEF2F0E5AA4F1BCE7
+:10D7900031190F8D13FFF42A1F20FE698EAB8E14F2
+:10D7A0000F8D13FF34E8EB23C53F99294E6A8E7F16
+:10D7B0002EEEC9A6F8F3629F85BE532DF57E19F7AC
+:10D7C0007CA5E72995BE8B345D612999C3E3A33B12
+:10D7D000857F8CA156A7DBFFA90CFEFDEBDE34276D
+:10D7E000FDDD55FCC17C2C094F900F4E07CCDBB5FD
+:10D7F00088E76556651E36C3D52EEC926B82AB8CDE
+:10D80000AFDB7B94C866240D0F8BE6FFD97578B625
+:10D81000FBBE437864EA800BBFC7DDE81F4FF964A5
+:10D82000663C14F5F0BF4B59E49E437F9752E2BF2C
+:10D83000C8333C6F5095EB8B9337F817C7A777B376
+:10D84000336B147CCA38F64878BC252FB811F946DA
+:10D850007EBF49BE3F95C1E17B7E1A137FFFD4880E
+:10D860004F80BF46F7FA7DECC06665383D14897C71
+:10D87000CC225FF81ECA834FACF060DC2C0ADFF4C8
+:10D88000EF127C3B5BBDDBD13E3A5E66A37C9538F4
+:10D89000F4407FDFF66AF4300CEF7D1F0C7FAB0A9B
+:10D8A0001F5B9819873E3E305EAF824FBBF5504FED
+:10D8B00081371E9FBED0477CEAB7BA11AF129F12C4
+:10D8C000BFC3F1C9F50B89EF53F9DA37E7E7EBF19D
+:10D8D000AC3D81788EF16F98DB312CFE776F0E8B2B
+:10D8E0007C1618E749ECF7D4FCE8384FE1B8D59F2F
+:10D8F00088FFF74E0E9772B95BC7FA5F9C8876DF98
+:10D900000526F235FD2F7BD14FD3961D375FF3E40B
+:10D91000FD0AFF3B3D1E76C022CE578BCEDE3D8BEF
+:10D92000799B60DF9EC6BC4D78FE707E26EDB717F2
+:10D93000F337C7823E2EF23BEB706C9C07F4598C98
+:10D94000CB3335C4F05EFA207E9F65167E9FA5839B
+:10D95000E46E2C0FE31D531E062F5705A4BC714522
+:10D9600028EF261AFFF4840CF14F363362947705C2
+:10D970002143FC53E4E948F9B6595B100A1BE29FC6
+:10D98000E534FE993AD97E47A474BA3EFE591DD1BA
+:10D99000F4F1CDF01D54AE8B968354967EE8C70605
+:10D9A0001E08A11FDA3733F44BC493BC370F02486B
+:10D9B000C3BF436775B90FA21D0EF601D3F247D658
+:10D9C000AB3F2ACFFF0F526BA57D00800000000007
+:10D9D0001F8B080000000000000BE53C0D7454D5BF
+:10D9E00099F7CD7BF39364422621E200415F02E880
+:10D9F000D442187E020109BCF94932B62003048DD5
+:10DA000005E903722C746D1B6CA9B4AB9B81C4989F
+:10DA10000485D0B2DB9F6DB72342CFB1DAB371EB8F
+:10DA2000A944A41DA4555A2AC6363962976AA0296A
+:10DA3000075ADBA295D5EEE929FB7DDFBD77E6CD60
+:10DA4000CB84A0D03DF674389E97FBEE77EFFDBEF9
+:10DA5000EF7EFFF73E972F54185BC0E0E74D1A1A90
+:10DA6000630361F87302B6FDA651C6D8AAC9B25DB8
+:10DA70009934A631B6B840B6AB4D6321631D2E264E
+:10DA8000C6B30403F8579893DADB8DB09998C2585F
+:10DA900068B92AE06334FF6B6B24FCAE6408E65B74
+:10DAA000ED10EDC4CAA4E165EC634CB697527B4D12
+:10DAB000BA1DA7F69D8CAFBF3FF5B09980F1DF99F5
+:10DAC000139F605C03EFA23D7A7CFADF1FFEA7156F
+:10DAD00089CF6413FB3FE8F802BF6346154ECFF9C8
+:10DAE000FD7780EF5A928F031CDF0F207EF7103FE7
+:10DAF0009FE0F87D00F069237C7A009FC2BFFD7A29
+:10DB00002F5419BB71BDBF011DDFA47D9FC6E9B8AD
+:10DB10000CF84789EE20DF077BFF84908F31EC9F64
+:10DB2000C3E77BD529E428D164A2DC9F725AF60DA5
+:10DB3000DA0BFAE57A5BF49066C57F0BE9C9EA1265
+:10DB40003EFE77A97BCD4459A60D3F03F75D8EFFBE
+:10DB50003DF6678DFF3C8DEF72A6E1693D97E85772
+:10DB60000E6F237C33F42608BECF06DF28E82B3A5D
+:10DB7000DC914C58F8C1120F127FD27629F130D9BE
+:10DB8000A501976CEF20BDD959CEE71F7FF8E1249E
+:10DB9000E20FFC3B46FC9EC2F9F78FCE8F3F184246
+:10DBA0005E029C1F520EBF33C7F823CAD9070D5F10
+:10DBB000D83F35744D46FEFF1FD62BA6F5843EBDDB
+:10DBC000D7F1697D147E9F2D49F3776208DE8F0FB0
+:10DBD000EBD45FBDF1C9C8B5F0E79AE6475413E747
+:10DBE000051856CA587C9025B7C39A37B3A4CAC043
+:10DBF00087C58326F34DB3E835FB0AE1E1F23A44E9
+:10DC0000FB5B64FF562F92727D2289F145066FEF10
+:10DC10003ADCA734DEEC9B59782F3CEC7D44D01DD8
+:10DC20000C59F4E46ACFEF0F035F2CF150BA2DF8D2
+:10DC3000B3FAD35F9B847C585D21E7FD7612E779C8
+:10DC4000B558CEFB24ADBB3ABDCE0F783B5FC2FFCB
+:10DC500094E033780D985978257E417197C4EBB1E3
+:10DC6000C303B45F2E5FF2817173E0D9A40413B0D3
+:10DC70001F1FDBB84D35AD7681F5E821F06F77B029
+:10DC8000749BE42A63077A68DDAB8DD7E690E08F5A
+:10DC9000D0D3349E832C986056FC0EF0FDB9CAEBAD
+:10DCA0005BECC23D28B7579FEF29E7B516BE4B3D49
+:10DCB00058E34BEBB7C13CC0775DCEF36373A3F77A
+:10DCC000CAD705397FD86A4FAE9C8EBE5AA2E30DE3
+:10DCD000BE2F19FBF392996D7F2E1BBF4742167F13
+:10DCE000FE9EC787B2F5CC627F1E47BA5BBD252E6C
+:10DCF00094EF757E662401BF8BF85B9C798E0F2BA9
+:10DD0000649FD2FA59CDC7AFDCC59A7BA60D87BFF9
+:10DD100036EC20B8D667D8C61E982FE43ADF14B781
+:10DD2000C0A542BCFF5048A127D07788F8BF95E333
+:10DD3000772CA4D37A21A6310374AA61E5A4329486
+:10DD400083D65FF2F9983FC8561466E63B2BE693FC
+:10DD5000EB1C5E5ED868A5E327629D63214E07FA3F
+:10DD60007FE2E77D9C0EB5E86E3FCEAF16C8FCF2B1
+:10DD700077C4D776A76827DE22BF3690B6437F24C4
+:10DD8000795FE59672F90EE9BF8CD7DF0AFD6F3235
+:10DD9000B110F167CC31CB3AEE0F6407471B37283F
+:10DDA000FD459BD8AF447ABF4E21DEA38D57234A51
+:10DDB00033F1C9C3520AF80FD5EBDBDB05A4042A03
+:10DDC0008D7338FEE84CE3B797330FF0E93CEDCBA9
+:10DDD000E7B2F3114BFFDBA1AC7CE0FCDD719C07EB
+:10DDE0005676C3BEBDB2462D5D0F7CFB2BEE4F15A4
+:10DDF000E507B15CF2F5D7CCBEFC359415CF470AE8
+:10DE0000AB408FD8784770AA3E7C9C37AC4839131A
+:10DE1000FBA43D8274B4A7F58DB77716F3FEBCE77B
+:10DE20009CEB843E1584719DA7047F99AF14D76342
+:10DE3000D38EA6D4B9E05F59FA6738A0BD1EFF8221
+:10DE4000F50722A79C28076B3B14239943EE87E92B
+:10DE5000498798FFA1F4FE8D0F5F43F39A6CAEF0F3
+:10DE60001FF01BF8C4369AB7B14921FDB3EBCBE4E0
+:10DE700030E7DFE4709A4F93097F43C8EF9CF85472
+:10DE80006C032873CFCACCBF56E01D72C60F5D0B62
+:10DE900072D0DEA6E8688FD66D5DD7510E6DA639BB
+:10DEA0008353E17103720AC6B5FB2BBC68075E148D
+:10DEB000EBE17C2ED847F425FE1282631A3CE7C6BC
+:10DEC000361FC1E1EF4E37AB909EEAF8EE0892B5EF
+:10DED000A0F1C923F8BC15CC34C629DB167D3D1E44
+:10DEE00086FDEB9BEF0CA2A84174D63705F06A10B3
+:10DEF000786946FD393606B228170BA6E6A05FF70B
+:10DF000006B7C3FB86A64F2C61950013770E0D7ADA
+:10DF10009018935DACC079B5A1C100E7D945B07147
+:10DF2000CBB73A336DC40DFB3D99FE95D773FBB467
+:10DF30003A0CFCB4C8DD0F057D3F14FCDC0538F459
+:10DF40004DA3090A19EA0DDBE840FEAD1373F5B5E0
+:10DF5000ADFCC88700BF0B0116C4B61BE95333F4F0
+:10DF60009D9AA471FA98E15D3A0ED615FB7ABC052C
+:10DF70006CDD8D306D1BD009F468EA9AA294458E51
+:10DF80008F8F315910E3B640E20106721231773BB0
+:10DF900007018FEB9BDEDC8871DF5AD3ADD7038A94
+:10DFA000776CF4D5625CBBD2147C59E23C8D747BF7
+:10DFB000E01FF2C5953AF76317F279A1C2C6C3FC18
+:10DFC000CBA2BC5FF2C5CDB4D356BE68B6F6D6932D
+:10DFD000E53B7F6481FF4CB8B0F4CC87E18FD96C0E
+:10DFE000F645A0130CC852C4E74287E253CB09CCD4
+:10DFF000C1804E9787EFE3FE8ECD2FA29EAEF56BCC
+:10E0000041878EF831E25FA358E39D167DE78F20AC
+:10E01000568D6CDDDD8D727747BFCADC00D7BE66DA
+:10E020003FCE843F0FCEA709B970147CA34F0338AD
+:10E03000ED8B2AC3F5241F81DFBEB9F0FEF4008CFE
+:10E0400007D03BAA814FB0EEAD865BD7012E7FE1B2
+:10E050009B6DC8A77CD69C1A0BEDDBFC0E96F26478
+:10E06000E802BA13822F8E8B0AADA56B725D4756FC
+:10E070003FF125FF0B11C6D076278CBE2900B75C77
+:10E08000CA6D07DFCFE506DF0FB9AF2CCAE555EE45
+:10E090004BBE4D5EDDD5CE8C7CE69057FB3E246DAD
+:10E0A000FBB05FE37A72AA5FA5F8E8D49ED25BABBF
+:10E0B000811F893D0ED263C8D30E2845F0474A61BF
+:10E0C0001AF0FF76812FFD006E7F7371B2AB3CB307
+:10E0D0001FB7079EFFB352C938D4B88C3D6298C4AD
+:10E0E00042FB36D1BAFDAB8912D4D38FB11E27EAD9
+:10E0F000F59D6CD089F2FF714C0555B48F4117BE68
+:10E100006FF4F85CC8C7FD7B9E2B443B929AE02CD1
+:10E110003E13205561563B697F2227CE48BA01380D
+:10E1200025EDA7C7F4935DF6C293ECB4C1B05D5C76
+:10E130001BF59839FCC8E1D9E60B6807655BF33538
+:10E1400033C4E35BB3E33F217B29C6EB95C64FB1F4
+:10E15000FDBD59C6317C7E1BE33DF00FE7C3F7518F
+:10E160005EF2EE74E338DA35BB1D3B8D764CCFC8DA
+:10E17000C30A9B3C483B7602ED1874AD407D05BE5A
+:10E18000B1D895D9B153520E6E6237217F809E5F10
+:10E19000931FD1801EE0CB6BB8EF331856DF52AC23
+:10E1A00084C8D47D809F22F0C3F70AD87765EB0B33
+:10E1B0007F56C6F0F6028053C4BE621A598B7EE3C6
+:10E1C0003F821ECF64B417E609A4DBCE1770CC4E95
+:10E1D000CACBFCCF9F40B971143C3BC9CCE107D3FB
+:10E1E000FB7AB7F38D345DA84710C9231D0A331D90
+:10E1F00017911E1F2031FE5272912039685FAA10BC
+:10E200007DEDE5AC11ED791B76CD07795FAAF4A021
+:10E21000BC3F1E29E1F1D2141E17761527FD415E81
+:10E220006721781608B295D333F33E1E5109FEA636
+:10E230003946013A2E88FB285E92F1AA84F345788C
+:10E240005C3936C2E38C4065BC841C5D6990F80E75
+:10E2500071D4586A7B5349C7385117E13FDD618952
+:10E260002306262619C621F946EEB8E1BA48DAAFE8
+:10E270005F17413AF648BF6E5C8FEDC5637D0D6850
+:10E28000E75C80F7DEF28CBFFEFED2FB5558967D30
+:10E2900038524EF85537ED6E1D07FB1D0A4DF662DC
+:10E2A000D894AA49FA318EE81A0F7CC8A12F5B23B3
+:10E2B000DC0FCEB94EC0097E49BFEF81F0DB09EB20
+:10E2C000609AEFC038A08CC70177462A689C8C07FB
+:10E2D000003EE102B8D00D26CDD33E35F77A770A5D
+:10E2E0007E66FC6DB008ED3563CDE42FE2C29FBCC5
+:10E2F000D262BC36044239D012A327D8FFBE2818F8
+:10E30000B8135AA23098837FCB6AF779D06FB706DB
+:10E31000D67B0631FE3322346FE39AD06B43167BF3
+:10E32000DB55C626611C705BC32DAF0D59F4ADAF34
+:10E3300090E38B7E26E1CECCBB0AE504F03D127261
+:10E34000A7160343F3FD2CE956E8E9D4510F223A0E
+:10E35000F5C78D75CCC47CBCFA9446F5AF62968641
+:10E36000DF065B13093027E215F727198ECB8736B6
+:10E37000C2C717BE49F0CBAA5596B0E009F6672D83
+:10E38000C9812D5EDA850206F3B6CF5792DB61DED6
+:10E3900006FF5DE47FB62DCAA7F7B06ED20DEF6F12
+:10E3A0009DDA447E4BC657EDD16890FCD315C65319
+:10E3B0008767C7EF41BC5CFEB45DFD1CC97FC6AE7C
+:10E3C0006E8970BBFA797C2FEDC7DE23AF90FD809C
+:10E3D0001C84F8DC05FCFEAF1CFBB84DE84157314E
+:10E3E00097437BFFD784BCBE3B3DDE8AF31BE0D363
+:10E3F000FCB3DE7FBCD92EE34DC1C72BE50FF0E3A4
+:10E40000DF2216BB0CFCF84AA46A381FE0D786F658
+:10E410004295D6E2094543F9CF13CD479899C47187
+:10E420001ED64C40AA37CED0DF0D9F27C570DC6AC0
+:10E4300041DF7BB5C7FF09E10DB76BC61311CA0BEE
+:10E44000B93C4BBB0C7AC9FDEFFBB4DBFD0EB0A7AA
+:10E45000804F07BE9A9FE93F24F6B9B7CA3C84EBC8
+:10E46000DE50E65987FC7F5031FC5E15EB9E66233B
+:10E47000DA11A6CFCA1A377C9D6D34CF4085B91109
+:10E48000F59AE92B4681DF2ED6D5B9BFD0391DB01C
+:10E49000EE57F32767DAA3D1F5FD88F173C4BBD536
+:10E4A0008CFF0AF5EEA580434F28F4243DECAACE5C
+:10E4B0004B2AD02E9865BECAF711EC284CDD157892
+:10E4C0008BE2A2654B148AD396792083CB6127CF48
+:10E4D000087FB34CE7FDECA4E1B7D63B8AA38EECF2
+:10E4E000BC1744C2B0D62FA28EF5589797FE0CEBFE
+:10E4F00026B9F4EDBCD027D5FD6619DAD5979CB9BD
+:10E50000EDF65B1117C12951519710FE6F959BE7EE
+:10E5100057EC67809FC5BFF65685FF47D8AF84622A
+:10E52000F18B0313CF93BDA31ECBFB65A2EEC4FA00
+:10E53000B3E79174964459D6BA20AF8E28AF63A83A
+:10E54000514BFF2A95F1BA475F36BF001F4F94E247
+:10E550003F3634023EFB72E273221B9F9228DF9704
+:10E56000DE2AA304E703FF3C16D7EF0883FCE5E0AF
+:10E57000EF1333C2D762BFC6121D15E5978C5BAF90
+:10E580004338D9B6C4AD7A34DBBE9647B97DAD8881
+:10E59000927DCDBD6EA5E0DB95DA87F7ABF73B6CDE
+:10E5A000FA2E9F5D834F1554021E6E77E2B3A4AF1F
+:10E5B000D32E4FBF3F7E5DDF44A4F390904FB4ED68
+:10E5C000186F183A8F473E1DE5721CBA214970CF6B
+:10E5D0008C107FA4E1803158971B290E99FF3EE3F0
+:10E5E00090AE850305384FEBDB7B0B308F7F6628C1
+:10E5F0009C330E3954D64D78DAE390DE11E290BBAD
+:10E60000A23C5E3DF21B17C5153567B99FAF39DBDC
+:10E61000ADEA209F7747B9DD9E3FD4A79A202735E2
+:10E620001887C03CBD220E41F86D20BA91B7BB558A
+:10E63000C46BFED93E1A57036D8C43E68F108700DA
+:10E64000162ACADD819AAE5FE0BED9E97DA1D2DC8F
+:10E6500012B5E45BD5837D744E22C77505B6179855
+:10E66000B4CFD972737836B7BF99715CDEED702381
+:10E67000C957ADEA0D607DA093E507910FEFE48DDA
+:10E68000A964453CAFC1B8B8134181EECE9305C92A
+:10E6900004E6D51EDE7F6FFE98BDF894F6C723F41E
+:10E6A000E29DBCEB92220F328A60FCBDAA915A0C0B
+:10E6B000FEA073CA977C9C9ECDA4475B046FC2BB2F
+:10E6C00035CAA76FF6F37D90F1D78BAB148A0F6133
+:10E6D0009A254B017E9E98DF3587E78775AA97E0DC
+:10E6E0007604781C7973E23CD52FE60FBA741DDAF4
+:10E6F000F306EFE2F9A2FAECD1028CF73FAC311548
+:10E70000DEAF6A8BB7927C9E74513DC3807FA89F19
+:10E7100055FD3DC4B7822157569D231F2C59CA125F
+:10E72000B7B86C6DA6AE29CA6587E4D35E87783228
+:10E730002AF2CF4A36E322F0E502BBAF0369734FFA
+:10E740000D1F79940D1F2FEB0B9B66184FA37C4C6C
+:10E75000710E7EF769E057EF1B2EAA5BF4EED9F33A
+:10E76000D14AA02FD1AD515D57E6334059C972CC83
+:10E7700067910754973EBE1EE5F260A16C8341038A
+:10E78000BC0FA6CFEB37AD372CED63D1074EA3DF1F
+:10E790003B788D843FC7C7CB7662703DDED7383873
+:10E7A0009EB72F44D54713B4BF831AE5D15B7FEDE5
+:10E7B000CD651F8FD772FD92ED5BAB3773791D6509
+:10E7C0001CD8F557ADFA21C7E52D35774C077E1CCF
+:10E7D0001C72D0F910E459298C0F36CD305F47F800
+:10E7E000074F70BE1E7CE31E1FEE937BECE0E772CA
+:10E7F000D9F9DF0B7F94CEF36672FB016E4E43BFF7
+:10E80000B56BD133C72A619DE3F3A7CE528104E0F3
+:10E810008507E36539DE5D5B91A587B756BFACAE72
+:10E8200047FBF3C6E9865CFA5E1535FF944D0F3F52
+:10E83000176DEDD688FF25CFD7EFC57B3FA99AEEA0
+:10E840003E0DF6B7F7F70E86794AEF7491878F84FD
+:10E850005710F02AB92CBCF6CCCB216F8097ABF6C1
+:10E860009AE178BD54CB883F2F541A9EDAAAE178FA
+:10E870003251C75C20EC7DDEB92F51DDB177D0413C
+:10E88000C5930B437B55143D59FFEE3A518111104E
+:10E890005BBCE4948A2265DEA766E9DDBC13F95906
+:10E8A000ED3B9BC766B5576F9C98D143F86F457495
+:10E8B0007256DBEDBF29AB1D62B3B3DA0D4B6ECEE2
+:10E8C0009AAFD617C96AD7FB3F9A057F8BBE32AB8A
+:10E8D000FDD1C0EA2CF8A5C10D59FD35BEDD0F6094
+:10E8E000F9283E6DA63696913CCE44BE16F41B2404
+:10E8F0008F0F9EB8C7877291AA894F42791B28EC67
+:10E900002BC3FAF58BCEDCF9DA7DB5AAF4DF65E826
+:10E91000EF0DC6F335091FAA18CCAACB6FA8E5FEE8
+:10E92000796DAD92B34E60F7C7D20F4BBF6C5FDF0E
+:10E93000EE77EDFE76D987F67A78BD9FFBFD5542DE
+:10E940000E5A033FF762BEFE6203AF237495C5A95A
+:10E950006E3020FCF39155B74FC273B5FC8039D6A9
+:10E960005D9EF1D7914092FD1AEB3CBE249B3C1D6D
+:10E97000FB936CC374AA4B6B9169FCFD0DE2FD5DCA
+:10E98000F8043F5D67E19BDDFF863C337F5CC4326A
+:10E99000F14AC3BB46B408F0FB48D3935A293C2341
+:10E9A000DEC39AD50E1DAFF96DE9087EFA93B53630
+:10E9B0007DC271BD432B2EE9075E6FE175F7EFB79E
+:10E9C00078580AE83BD9E2A3E72F5BFCF4FEE51692
+:10E9D0009D9EED2D017AA65A82D4FF8B966A7AFE0F
+:10E9E000A8C5A0E7F32D317A1E6D8913DC4F5B1AA1
+:10E9F000E9F9B31693DEEF147AFA41C1C708C8BA31
+:10EA000042FC884321BE36E055DD05670DD56AE737
+:10EA100081AFFF9A8BAFEFD79FA46A7A26A29C8121
+:10EA2000BFCAA94F3DB532AE4FEF37E125E361CC08
+:10EA30005F504E649D0EF07B0CF173637DAEE4CAB3
+:10EA4000F13BA870BC0E16F3FA0DCEB3BC10EDF975
+:10EA5000D7E361B2E7D7CC247BEE675AB63D2F1FD0
+:10EA600066CFD791DEB1A35827C5FA229D53D8EAC5
+:10EA70002045753A8D93759045EFF23AC868F403D6
+:10EA8000DD47D16E49BB7DB974DBE93D3CDB7809DC
+:10EA9000E791FE7998FF30EF26FF512D7496696F4C
+:10EAA000539C5820E8D9757A4511DA173722C8F3F4
+:10EAB000748355E33E33791F60EFC6B2E1F3BE5E67
+:10EAC000D343FE7C473ACE7993E298E1FE2B9B0F2D
+:10EAD000180B59FD3BF0E15CB65FE47CA8559F1D27
+:10EAE000DC0EFEF9E020E375B239FCBC4EFAC183BE
+:10EAF00067791DE382A624196C5D983577CF83E78B
+:10EB000081FB59691CCF9B263982FB01B4E0B95EB9
+:10EB1000DD0370A141736C1EF457A7F2685C78C9DD
+:10EB2000CC24B61BE26F927D0A6BD97E1223D4B43B
+:10EB3000DFA1225889AD3D2103AFE2FE5664DA30F1
+:10EB4000EF27669B5A1DD0B5E27C33D3617E7719DF
+:10EB500073D2FD90E1FEFD6EC55267D358B003E954
+:10EB6000D0BEB0839FEBD9E44DF249D6DB641EFEE4
+:10EB700008337C7539E2873671EE623F6F796BBA84
+:10EB8000E94778C5F73C9DB7B08D8CDF8F70407E2C
+:10EB900082FC1BE34AEE2F1F2E77DF9B75CBA43A36
+:10EBA000AA532494AB93B7772B94B78BBC89E99F76
+:10EBB0007158F3189937D9F3A387849DDD897616A8
+:10EBC0009E0F3919E55BED4A7E70AF92C997C06F11
+:10EBD000CE40BA16D589F317D63C8F9FD3DD9F95CB
+:10EBE0002F8D88B7C84B9CE97D2FF39D29C8ECBBBE
+:10EBF000D7D5EDC77B8E9D33BFD1B81EF936D34331
+:10EC0000E79C4C4BE96877ECF4305F8295CECDEC15
+:10EC1000B7CAB433589FED806006CF7B1FC62F0163
+:10EC200060BEC2A0232BEE29AACE8EDB6EAF9376F8
+:10EC3000F6EAD0810240E7DB124F1617E7993CFE57
+:10EC4000F488F76D3AB7170CED9DE57CBDCD6B7878
+:10EC50007C96FD7F10F7C73D323E6A799B0FEBE053
+:10EC6000DD5E07E97787AE759643BBC3ABF1F84627
+:10EC700077C4729D43EDAA5304DD1C2F9FC04B0D3A
+:10EC8000ADA03868A4F5BA84BCC876FE34D3207D24
+:10EC9000D48371CC935BBDA50AD64765FFA63A45E0
+:10ECA000C84B37F1A153C455F9819E9403E56CFC20
+:10ECB0005DB3916D1E8893CEC07BCFB41E8AABBC72
+:10ECC000135C662EBCBF2CE6EB74066394F7173A10
+:10ECD00018E6FD9DE5B9FDE83FD7F138B3559F151E
+:10ECE00047F804F065AA321CEE53420E1E70821CD7
+:10ECF000C2FA9D536FA37B629D9318D9EF8AFAE9FC
+:10ED00008F6EF3E69043FD33B47F4E1F93E7EF59C8
+:10ED1000F7255AF586C675B0AEF6320BA2CDB0EB2C
+:10ED20009B73FC8AC67578DFA23A3F88F0B5EACFBC
+:10ED300012C8C7F620A37A8756DCE441BC1F2CD347
+:10ED4000E87E449AAF33CCC7D07E8C26DF767C60D9
+:10ED50003D92BB91F6D78E1F85F2B32E015F6C36C4
+:10ED6000C673CCF7CBB45E65CB977314F91A8D9E3E
+:10ED70002CFF5A96F1AF3FA9DBBC01EFA93DCC783F
+:10ED8000FFB1BA30E5FBF6F6D5D2F356ADBB11F7BD
+:10ED9000A5758A8BE4CF3EBEB39CE3D5F57C8D5838
+:10EDA000D7A7A0FCEFAC2EC943FBEE45436DE16B4A
+:10EDB000AAD23C5567F1DFC5D1661EB7D731925F45
+:10EDC000AF1EF74D01B9F0F6AB2053C077C75FDE39
+:10EDD0003DA5BF7F3EB26E83E4964C3B975BF61732
+:10EDE000E04B9110EB31ECA13E7E5F640BC1497E9C
+:10EDF000EDBAFE0FC1D425F8366661767DEABDD640
+:10EE00009F94FAC252E2731ECB433E5F60F729E43F
+:10EE1000BFA306E99D2F6D57F9BD9552D90472B075
+:10EE20004D22A764EA520CCF3D50BF4C46F10D4134
+:10EE30008E13475E44B78FC64D14D34CC00B352A92
+:10EE4000CA3FB7BB17D81B7C7D1886F756948483BE
+:10EE5000FCECF528D70057CECC3F9FCA719F679234
+:10EE6000AFE9C90DF09C582FEA69829ED1F821F1D3
+:10EE7000FE5BC9AD8C0FEC755459677D1AEBACCABB
+:10EE8000E87554A69D27BEC9F8D75E5705BF5680C2
+:10EE90007C7FE7068D7511DF79BC90C9F34D8FF546
+:10EEA000FE9DF497EDBE1559F5F97923D0FBD428D2
+:10EEB0007EB1AB1FEC26C6D1FEED549F3F7072FDB4
+:10EEC00051CCE32FF85D3AB3D8FFF6C2ECF3033927
+:10EED000EFF67A51871F5FC770BCD66732BCB7E7C1
+:10EEE000F207C92FB42AB9CF1DBAEA1DE2BCD1E698
+:10EEF000276CE733FF9DE74DBA2A58DA7FA8C23E58
+:10EF00004BFFCA34F0A2E3ACE3B91D95FC3820E214
+:10EF1000D1AEE736D13D03E6B7D47D2B72AC6F8F0F
+:10EF20001B0D43F7CDCDC4B1CA208F5FE5FAED22AA
+:10EF3000EF6E3DC9F7235FDC37B2D30BF1EF17EB70
+:10EF400081DE8280C356DFCAB637F678D8ED618994
+:10EF50007C8BFD8378B8A59EE284EC7876428CF1B8
+:10EF60007B41C526C3FA4FC46FAA58AF99DBDFAC0B
+:10EF700032A07BDEC94BEF47633D8F17DA03EBE32B
+:10EF80009837C9FAF3AE451F21FB0A7EB4BBDE6297
+:10EF900077E57D87F75A8F92F23A57EC637A7DFBDB
+:10EFA000BD94855BF8B9D1C97B8EA13C1E00794424
+:10EFB0003FDF5E98D8311DE3939755B65F1F5EBF64
+:10EFC000B2D325EB506363FCDE8ACBDF7E64B1C332
+:10EFD000C29FC1665527FE180CCF8934714E64AFAD
+:10EFE0003BB9DD4633FAEF548DD168AD3B4BBE35AE
+:10EFF0000A797EBDA699CEB19E1EE1DC58C2E1E73A
+:10F00000659887CB3A56D90CF359E4EFDCD86615EE
+:10F01000CD48757C33DDBF2CF81746F923CB5792CA
+:10F02000FB61A9E7163D43F9E59FFC8CEA6C2ECC09
+:10F030002F4B319FE4F9A5CC5BA59DA8559FE8A86F
+:10F04000C07B1DFD1ADDD32B786E9307E3DE50FFE6
+:10F0500006CAF10C655501EEA3BCB724F1BCD2FC85
+:10F06000B40AF353CBF94AC66EC47E8572D0D5126A
+:10F07000FF5514E4A3B7C5A0767B4B233DABB4A4E6
+:10F0800081F4540528E3630B86A0DF8247555F2C8B
+:10F09000ABDD5569FE86EB553CEBBDDB0FF359E468
+:10F0A00002F2E3730837F724E7A76B8942F711965A
+:10F0B0000DB207B86EFFC3D8A182D8D5B143BED870
+:10F0C00025ED103F67750D8A73569BBE3D5EAF936D
+:10F0D0001EA4F50ECF5BC9CF25683C9D19CE077ADB
+:10F0E000C67C92DBADCCBD0EFA9E3124BEB3BEF120
+:10F0F00068CD3E8C67DB5F95FDCBF719967E9688D1
+:10F100003661EDEF3026C71067761E2D6DA2EFB089
+:10F11000C5773491C6E2B20196B9EF68E7D74331BB
+:10F1200047D67D9A10E3F534D9BF3926F24320073C
+:10F13000EB76F2BE443EDE97C811BFFF9398EF5EB8
+:10F14000E453157E1FC2EF2B2CB67D1F62C42EFD2B
+:10F150007D4842F48FF63DC81D319E5F98623DFCAC
+:10F16000FE3F86F8C6F97718EBC57E2DE84FB68EC0
+:10F17000C120D1CF72CE138F713FFF428CDF7771E8
+:10F18000F90D0DF705E65B4172D0C8EF67CAFE05C1
+:10F1900067D3FDB7D17A0DBC7FC15993EA48F2BB62
+:10F1A000BC78ECC67DDBB4CCBD9C76AC4778F1FB7B
+:10F1B000147EDFE9DF059DF6A7FC3EE5369FB8DF4C
+:10F1C000C326EFC3DA66ABC1BFC7BC2576D35042B6
+:10F1D000A3F5EFA2F5C5F738D5825E78BF89DEDBEF
+:10F1E000FEBF024DB1B27DE23B9E4F115DCD1CEFE3
+:10F1F000F4FF2721319BE44BC257C7663509F8CF8E
+:10F2000012FC460E9F431E843C56119E9731DFFD33
+:10F2100084DF1A8EDF87627AD6F75F526E016E3B0B
+:10F22000C189EF83FAE31B3C68CFD3DFFD27A6ED4E
+:10F2300033A65C169F76D03CA65C8FF3497573BDF0
+:10F2400090F22FE5E1BB621F66C61429575FA6F155
+:10F250004D578DFE6F123F6DDF238D4647A032BEA6
+:10F260008FF0F0A7EF23EF8FE5D6CFF7848FFC7EEA
+:10F27000CCAE17CF0AFA61DDEFD13A6541BA9704F7
+:10F28000EB3E7535D685797F407CF0A4E7FD21B54E
+:10F29000AF705E56567A59F74AFE0FED913B6F609C
+:10F2A00046000000000000001F8B08000000000066
+:10F2B000000B93E46660F8510FC181486C62F11A4B
+:10F2C0007606866816068699AC0C0C15402CC74944
+:10F2D0009AFEE540FD8B80782E10CF00E2C940DC1D
+:10F2E00007C49D40DC02C49240F34480981F88B953
+:10F2F000809815881980F8370703C3370E8439378B
+:10F3000080620F48B41B84AD7810EC3340FF6F046B
+:10F31000E2AB6484C3281E1E389D9F81A15A00C1A0
+:10F3200017104495CFE047B0B94429B34B1AA81F32
+:10F3300000656D40B4800300000000000000000084
+:10F340001F8B080000000000000BE57D0B7854D5F2
+:10F35000B5F03A8F79666672124298842027103091
+:10F36000680A4380088AF51022624BED48A9622F93
+:10F37000B5038D80104854ACDC4ABF0C4C8020286B
+:10F38000415141910E0816156D44AC58D13B20B542
+:10F39000B4B56D6CB9D55AED0DB5AD2F0C8852FDD5
+:10F3A000FBEBE5EEB5F63E9973CECC24E0EBB7F778
+:10F3B0000F9FEEECB35F6BAFD75E7BEDB577DCB242
+:10F3C0000B0A07029CC49F0B006E7103C098743A2D
+:10F3D000F2C66FCC7F6834FBFDFFBA23DBF5743DCA
+:10F3E000331D0812D50330008A012EF0B25F59BDDB
+:10F3F000893F3FF2A7114500FB40010FFB945227C4
+:10F40000F6F91AEB67DF8710C172F9E781B2CE0017
+:10F41000B68B53BB2F036F972AD7CBB42ACC808CE3
+:10F42000DF0D2FFDCEFA19BCA989B53FF14180DA75
+:10F430003BE13053F850869468737210F6ABBED738
+:10F440005929F2E5C00607016F1D404D1ADE03AFD2
+:10F45000BC46F0EE5719BC7A96F1BD0CFEA234FC06
+:10F46000FBE01BF950C5E1376AD2F09F2E3C34FF18
+:10F47000BE002B9BF5272B5C003737C39315430049
+:10F4800056377B29BFBC59A37CA2394CF9952A6B0E
+:10F49000C2F0B0721B24E3AC7D6834AB6FF6C7FEDC
+:10F4A0000B54796D7977116BEF4DE7D540D896F70E
+:10F4B00096E9B63C03E75098CDFB2C319FE5CD0C87
+:10F4C000071E1CDF0BC69958FE6DC28B4FE02D1135
+:10F4D0001C7AF9208697D6E715466900976E4C4747
+:10F4E000F82A026E3DC958E3ACC0EC29309C8D1B54
+:10F4F0008A01B07A89DB016E65700F0B4C7A03428A
+:10F5000000F7B1FE5B59FF4AA8F5450F2B5F55EE9A
+:10F51000D615C4CB0EF52F9D6C0C2FFB87783B7353
+:10F5200003CFA7E7C5F296790E034B396BFFCB8269
+:10F530003B5E94181C890AB7EE91D2E374D3A59769
+:10F54000FE87B4D9F3CEFE2B74A316F9D4EC77085A
+:10F55000449769812F6EBF6731DCF6294CF76B8EBB
+:10F56000D36BBF8CFC51D676C80648A6CA33C7A950
+:10F57000D02393E3ACBC62830AC972FEBD88C94341
+:10F5800005FF155696D5FA635599F080759C41692B
+:10F59000BA54E8EE9932E38B8A8ACBE64B8C6FA0A3
+:10F5A000CD42E7419C41515ED6366BC48F37375709
+:10F5B00052BAAD596B27F9F94899DE5E9529877FD4
+:10F5C000453DC5DADDE202E2C3F876486E97B0BF8A
+:10F5D000E8F4992CBF666471F54D3AE6A7CBA817FD
+:10F5E0004CFE5E23E9C4DF71C6DFA8FF9CF271B355
+:10F5F000CBF80AF6B76AA42C2D433C57707EAF7047
+:10F60000A5BC83B1DFB64123E3D84FE4779D58AF63
+:10F6100062C8505D61E30EABE0FCFFCB31777851FF
+:10F620000F76CF7F71717BC528807C071F68A7C8C4
+:10F6300007DAF89EF9C01CE7D39687CF8EBFDA7A37
+:10F64000E4AF35915BDF40BDB1AD82EB0D275C25AA
+:10F650000353E1682093DF2A2A189F219D223DF35E
+:10F660009933BDBD3909AF321EBAAD394C7CB7AE46
+:10F6700059A774B5E04317F25409CB0B3E84A2D1CD
+:10F6800094CFB95EC1525A8FFA4E4B428CC1791B4E
+:10F69000F2E7B9F87DB96194B1E695661E5232D3AE
+:10F6A000FDEBB0BC94F20694217F9AE58FC40DD691
+:10F6B000BE50D49F243D124F3024DDE6E3F9C952F9
+:10F6C00097112FB3B65F6D18E3D3F5593E555B61C3
+:10F6D000ED8FF55F6585E719AA6FF6572F1D36E2A6
+:10F6E0002CBFCEC7FB6B955EFC5CFABF496A0BE38F
+:10F6F00042B3CAD1CF4D663EDE661855E971CA974E
+:10F700003E6CC4ADE5F0B0ADBC66695B3CCEF07656
+:10F710002744074B8CBE2553A26160F4F7459371D3
+:10F720005C6AD3F0717CA7E77707C1EBAFE0E555E2
+:10F73000D2EF8D84853E13A4DFC4117ED3BE510465
+:10F74000BFCA3F2FBBEE39C6AF4ABE3B4276461119
+:10F75000CB8C63E34D8B81CEE090C331407DA084A0
+:10F76000D5BF5BE5C0E43F06E75882B32E3A3D07BC
+:10F770009C712B9C261CBDC16DC2919B4FF9F84E0C
+:10F780007EAABD64EC6FC73316F775B82268E7F53B
+:10F79000413C313D001FDE66B8D8F73E5319EE7587
+:10F7A000A2DB74189CD96FD19452485AD6F14F9B62
+:10F7B000AE83313F86F0F61D694C9ABE2C3FD38A4A
+:10F7C000C7B1A29E93FFCCF9B933E6F75DDBFC40ED
+:10F7D0006D0B4783BDCF6F9D2F323D1AC8ACF74BE1
+:10F7E00089DBD1B593C67E1DF878E061FAAB00C71E
+:10F7F000AB4E8F57F015361E76A626B38E5758C7D8
+:10F80000C6F37E76F874CAA309AF2F03DEDB6CF073
+:10F81000DEE462729B85FE9F35BCA72A7F7EA67FB1
+:10F8200049FE2A7B96BF4FBBBF02FC95F1D3BB2A92
+:10F83000A42E60F85A74A1371997D27AEEF3C657FE
+:10F840001F2C62F45BF4EB51872F9031C3F8FA4B15
+:10F85000E9F1174A3AC19D8BBF73CD072069EBE7E9
+:10F86000FFD57C72E1F5B3D643A7AA5F97FDC14FE0
+:10F87000FBBBE5159044795A7EF042DA672E7F6E25
+:10F88000623F60FDB85ACF06834DAA40D819CBD14C
+:10F89000CEC0FEEB4ECDCEB8A919DA5B98D1F558A3
+:10F8A000284A76D17209A8FD1A66B72599FD32FA61
+:10F8B000F96DDE9901B2AB285DEE02B263463F7F7F
+:10F8C000409BC8A6E01F523812797FB9CFFC7E68F2
+:10F8D00032DAB9AB2BD877C61ACB83BC3FF63D8A58
+:10F8E000F5F386F0EFB9E0CAAB64F058F0EE732799
+:10F8F00063D9F4E3976599F0B351D85D37A3DDC5BB
+:10F9000014B2CFDF1643BBDA5FECD6B74A99EDA647
+:10F91000CBDCEE5F3FE427717469AC42FB8DCD7F99
+:10F92000FFA5F7416715AE836D868CED23DC35B0FE
+:10F93000D1B1DE07D086A375332C4D646BA6DF9161
+:10F94000BFD9AC1FD727A0BD16AAE4E513969D3FEB
+:10F9500021612D87111370DD35CBAF5C3686CA4B24
+:10F96000BCD117C7B3F14B98FE4C303C95A86D52F3
+:10F9700013D1333BBFACBFCA3B3DC960587FE91DC3
+:10F98000E55765C113A322D1D9CC97D6DBE56BA38C
+:10F99000C0DBCD028F6194718B5EF3F1AADD7ACD6D
+:10F9A0007726D76BFECAB6A588E7D27A88A09DBD18
+:10F9B0009EE12F6619DF5769D76F25AA7D5E9FD517
+:10F9C0007CEE04E30AB96FEEFE9DF27527C4666211
+:10F9D000FD12B18EFB2B9352ACAAF7F93BE79B6B60
+:10F9E000DE5F15F864E32CCC36CEE7859792001BDA
+:10F9F00067F4A73F8EBFDEAE274F15EFD0B0CDC066
+:10FA00007D359A9AB86FF6415D2445FBB91BC90F45
+:10FA100077BD801D621B35B46B120059F5995AE110
+:10FA20004EFBD3F07FCA8CFC6C7431D3C52FBF530F
+:10FA300070C0523F29078BFE9EC77E3907CE39A979
+:10FA4000A4DB83F0F7A9261C8142DBBCDE6F3E56A7
+:10FA50007000FD72DAD47CE861BCED4C8FA6987C16
+:10FA6000DDDBEC851493AF2DCD1AE57FC8E40DD313
+:10FA70007B98FC617A37DB2F62F9C6E608E5EF6C0C
+:10FA80001E4BE9EDCD067DBFAD7932E5D73547296F
+:10FA9000BFB6793AE5BBF1F9211BAF46F02B9BC706
+:10FAA000908A645C463FED6888303061257EB7C03F
+:10FAB0007FB33CE16919FD9ED37DE4DF0808FF8632
+:10FAC0009FD17730B63BA4C076C83DAF04CE8BC182
+:10FAD000F11545E6FE53B592E4C56FCACB7A20BF57
+:10FAE0008A2FC2D62DA672D582BA42E4775F847F70
+:10FAF0000F54AA4974C1048160C40D7C727B39958E
+:10FB0000A77CC3A90B15FB1B21F8A3352053BD35DA
+:10FB10003B787F4E3E1951BD4B6614036F50E5F59F
+:10FB2000927CBDAC1A752B7D6FD5641A77CD06DE3D
+:10FB3000DE57C9F8C6C2B7616510CD6367E8406992
+:10FB4000391BEFC7C1FD8306B3741DDBDAE0FA751C
+:10FB5000EF9AAD85332D7E24AFC2EDF360DDD6A9DB
+:10FB600015AC1E1BD6C0719535FEE4D672A28782F5
+:10FB7000F09DE5E3F007BD7CDE4A0324715D32CBE6
+:10FB8000CF2EE03004B58811ADB27C178A27A827A4
+:10FB900097F9B15D2B44B6EAE9F24AB39D616F571C
+:10FBA00069B68BB7EFA7764B583B48970F2B10F0F1
+:10FBB000C0485BBB61269CB04CA676717BBBA1A202
+:10FBC0009D39FF61DB3A24AB9C0DDDD02971B9B1C1
+:10FBD000D32517FF8C0021B7FBE3D249C4473BCFA5
+:10FBE0004B92B7F52423D5D93BEC723D2CE990F329
+:10FBF0000D6E9B1F3D8AB2CBE8B156D06B53537646
+:10FC00007AAD558F1D44FB44D9A1DAF069D269ADB4
+:10FC100057D0B1C94E47934E6B3541C7A8838E026A
+:10FC2000EF6B4D7ACDC84EAFB539E8B5D6A457CCF9
+:10FC3000DECEA4D7DA1CF45A6BD26B5A767A39E945
+:10FC4000316C5B8CD69D34DD2294FFACE8E1D40BA3
+:10FC5000CFC93A7D97D71BDA04D40FF52ADF275591
+:10FC6000A600F7035056D88BDD1A17F64913E0BAF1
+:10FC7000700BFE6AB1CBEF75F3FC9589C313D00E00
+:10FC80000F75DBE1FB27A03F6C9328BF2E7182CA62
+:10FC90001F97A33185FA4BF2F11DF8F24493B0811E
+:10FCA0008154AE6A175730BE285F2347E21639F0F9
+:10FCB00080892710E737A7C6FF005CFF2078270759
+:10FCC0009F129CD72B84CF24CD3B034EB6BFDCC004
+:10FCD000F635A582BF4B9B189CF0E9C309F57CBDA6
+:10FCE000E85E9F859DE482ECFD54AC916D7A765080
+:10FCF0008BDF96D79714DAF2672C2AB5F15559C3E2
+:10FD0000205BBEB4FE2C5B3E3CA3DA962F9E76AE03
+:10FD1000ADBFA229B5B6F20C7E11F96DCA4B4B6D81
+:10FD2000FC121F5A8BFBB64DA27C4762682DEEDB9E
+:10FD30007A2BFFFA55AAE165F8578BDCB4FE300A3E
+:10FD4000127E4C7CE56B1077A3BC16059217B1723E
+:10FD5000BF66C4C91FA019807684ACC528EF0ADB32
+:10FD6000D7A7AFA1A1C4F8F4EBEB54E8A57FE3E378
+:10FD7000F4DFDBBC9CFC62AEEF4A115F4FD7B1ED04
+:10FD80009284E7224C3FE23AEE62668E2F847C2119
+:10FD9000F887F133EA154D9584FC9E9E9C0D6CB559
+:10FDA000EB9B01717BBEFF62FB7C4E95BF3F2FF941
+:10FDB000ED0D7F6B2112574E017F115512E7D5A72C
+:10FDC00027FFE11976FC144F733BE4C4A1CF3F67D2
+:10FDD000FCB598EB0568B5B8FE065AB80FE5DE35F8
+:10FDE000FBB55816FC99FCB2AEAEDA6FB543206293
+:10FDF00099D7A0F4389457B2E5BF687C929C40F63E
+:10FE0000F15C36FF72B46372CC5FD07BEDF8FDBE5F
+:10FE10007FA5F9A7E9FC83D36A1FEE86B74CA3FD43
+:10FE20009A9977ECCB32DBC7B9BE89F964AB9E6493
+:10FE30003F952AE3B310F82388E7F77DA1E190CF3F
+:10FE4000F6875E9E7ED6FBB67BEBF87E26FE725E64
+:10FE50007208E253C471DCF2F2979244F7F132DC9B
+:10FE600081E5553295DFE00F6D45B8BEA9C46E50EF
+:10FE7000FB22BC6724F1BC18D44E6DEA972CF31416
+:10FE8000769139FF5CF6D1B296EBECEB194CABB541
+:10FE9000F2E39D2D2BA99CD91D2D2AD1EB8B621F3E
+:10FEA000E58473A3FA05B68FCCF30167FB7F15FBDE
+:10FEB000E8A0DAB0CC6E1FEDE17410E5CFB5ECA987
+:10FEC0003D9572D33EF207DC621FEFB05F2A997D49
+:10FED00084E7470161BF5426C95EF15526B9FD523A
+:10FEE00069DA33F6F5EA1A3440C7A4EDA31EFA37EF
+:10FEF0003E4EFFBDCD2BD7FAEE0B98F6511BB78FB8
+:10FF000018EE31CE44A9E47E0EC5B1BE8F76E55819
+:10FF1000DFFFD7D847D9E5B737FCAD85366E1FF57B
+:10FF200082BF69B9F0F72F6E1FED50E1FF33FB2858
+:10FF3000179FFCEFB68FD274FE74EC1CA75D63DADA
+:10FF4000119FB57D63DA27CC8EA954516E999D859A
+:10FF500076CCFB72BBF70E369F1B944E2F2E8AB7C2
+:10FF60000A795DAC46D7B968FDEE247FFF06D4E779
+:10FF70007D859EC5F601119FA74600ED9DC56A6C63
+:10FF800083CB720EA1043AB558E08B870766E7D998
+:10FF9000E72FF062E261B7AB40D0BBE99C289FD766
+:10FFA000A38407E8E4768CDAE9C5F449B1BEDD9BA9
+:10FFB000810F20BB5119AB27511FB0F64FBAFADAA7
+:10FFC000F0E2B5E185AD437C3C50A236BB91A7FE83
+:10FFD000D19A84FE7296ED40FEA5F3721DFDC26DAE
+:10FFE000938732F8FBC4565C83F198C1972F7E0348
+:10FFF000E31AFB74CEA4F8C696AAEA83B5AC5E7E7B
+:020000022000DC
+:1000000044BB74928EEB2A905F71157646EB2624E2
+:100010002604C4394E29C06F969F10EBA60176BB0B
+:100020005CD655D39F3428B7BCB01FE9A427B37D55
+:100030002EF97059E59AE4F3DA53934FA1F7E3EC04
+:100040001FEA8B02473FF9867D5D088225CFCA3FB4
+:10005000107CCC2C94CF653C0D6EF5EA8C3F5C1582
+:10006000B286F191F9A01520FFF9EB5448A1FFA544
+:10007000E8581C5DB0BDD1A505FDE87C3F0A975A44
+:10008000F613413797D7F0AC96F215ACDF13A3798E
+:10009000FC7D1F8DFD579D399FD542BEBAF3555B40
+:1000A000E9DC34C1F86910DFDFD03D825515BB347F
+:1000B000AB9E1EE1966CF7082CFB365DAD11F63455
+:1000C000C38F52211B68077C52FE503E267FE44DB1
+:1000D000B1DB09A74BAFF1E25EC5A9F2C7271DCF7F
+:1000E000A46BA65C2D1574ADF7A2DDBF223CB5C78D
+:1000F00073D44CBADE4A74F5578091CCD2FF04B762
+:1001000094357ED6B93F72DAEB4ABF9AE95B7AA2A0
+:100110005B91D3AEE5FDFA162BFA5F5179A91AADC2
+:10012000035ED1DF2AFDD638EACF13A813193E9417
+:10013000B6912971FE18D9CEAB50FC874F37489F36
+:10014000D279774D1A3E77997DBFA616F9ED76E103
+:10015000F4B86485DFB7D84D7078713CD4D31AD029
+:10016000B9A71AE0FEBD8CFDA3C36E5859569D3544
+:10017000CE40FDB4F6ABD3ECF09E72BB80AAFFDD9F
+:100180006C93454FA7DBA9F0778B3DB506F9DD42AF
+:10019000FF152ED823B1753811BE0C623ACB6351CE
+:1001A00009402BA6E3900FABB97DB743A2F36012D1
+:1001B000691DFFE3E74457B875EA47F6C6084F4A9A
+:1001C000C000AAAF9FDA39D2FB0378DCD220096CD9
+:1001D000F51F74BBA95C8528609CE2FBAF5C14A68C
+:1001E0007E0DF6A9260D87B3DF2BDCB107DDD84ED7
+:1001F000E3F060035AC7C772BF40D8CBDBBD3F7383
+:100200002AC571E5826F43333F5FEFCE8BB82C6810
+:100210003DB5B8AEF7D9981D55C4FF7EDCD7421B5B
+:10022000B787060A9A6D595248DFB7B4F42CE777BE
+:100230000939DF8CF69187EE55D8E47E9B8837DB51
+:100240002E81ED9EC5100F8FCF7A4BC8FD166FDC47
+:1002500047F7159E59E51B8AF12E8794888FE1A1F7
+:10026000E22AA330D6031E86B4D9E5ED74E33B5EE3
+:1002700076678FEFC8D5DE8CEBF8A47821DBAC1461
+:10028000F1303B41FB96D405249F25826F4AD8FE6E
+:1002900005F5D0C0382475ACFBE149B0F207FBD9B5
+:1002A0008F7E8AD27A3616D22B26D3B974E9EDEE38
+:1002B000A44CF2AEDD84EDC387141E6B0846606665
+:1002C0000DB12AB50F2BCF4D40511B2CEC33586389
+:1002D000BF7751B6C47E5FAAD4714F228CF65D08F9
+:1002E000FDAE967AE59F9C1E210FA3C7D99F3F3D87
+:1002F000B6A9865FB3B4AF9020DA9EA5BF0A0FB748
+:100300003B2AD6ADE77160F50178D5B25FDC2E19D6
+:1003100085B8186C6EDBBA14CFD9E2F51019C2F0AB
+:10032000DDBF01642B1F8FF2E4513F2E30E26732B4
+:10033000BC2DFFF6659D4F215DC7834D8F65D11F95
+:10034000A33C4C5E5C455C7F6C6B9BCAD30F155A1B
+:100350003FC24B20B98C8158178B2D7521FDE702C8
+:10036000C5A187EB9BF6617C754903447018C6579D
+:10037000C45FE1E99034885FE05098F1C7003E1512
+:1003800018807C81EBCF224E5F932F4A1BECF76DD8
+:10039000C2F5F67CB1B0FB8B9DF7B71CFD94E8FC71
+:1003A0001E94BE4406BCF707D3ECF76DC2D079FFAC
+:1003B0008F10BE0381480AF935EE18C7D1BF0AB1C4
+:1003C000CB3C0C9F8F7D7FCA2FCF64F57FB8A4B63E
+:1003D0000FE2658B379A4FF78A5AB3C79D65F0AB2A
+:1003E0006977E4A89FD6A3715B5CB3335D31A4F851
+:1003F000BA590C8E55410348AFC5AF20FDAE08F980
+:100400007DA6E4322FC6932E0F54537CD83ECCB336
+:10041000747978683F6BBC9822E277CD7C42E853D0
+:10042000E778D77BB81EFD3B18D7231E467A62615A
+:100430009CB72B5CFCE84C9DCE0B8D649676733C90
+:100440007E6E5FEAEA3FADF8670BB8467208705AF5
+:10045000FE85599E582BF267BC966D2790FF074189
+:100460003281F46F6A137EF7EE7A378B7A71BC773C
+:10047000D95D2FD606D67D27AB772BCE87D5336CAB
+:10048000F5A219F5EE14F5C036AE9131EE26133E05
+:10049000B0F617C9E86F8BE88FECC1EE7A7A467F29
+:1004A000F789FE0C5B3D2DA3DE83267CB671C13E31
+:1004B0006E77F959EE6482F4368FA7DF3F6412F14C
+:1004C000CB81219326CF62E35CF70B97D01157D2F3
+:1004D000BA6DF2D53E51AF05F9AA8AE2F05A1BF087
+:1004E0001EB0B8279C084CF5C62CDFBBF92A305546
+:1004F000CBFE7D96ADBEDAEA0363147DA7FA2D1F0D
+:10050000293CBE395E5087FEB89545B28877FE5BC0
+:10051000C250991EEBABDAF2AD615E3EDCFBB74434
+:100520001CEF14897B304C573E596591EFEEF13F3B
+:100530002FF8C579461AFE77134685157E9E37E15A
+:1005400037F3DE125E5EDDFAEE44BC5865DE03185A
+:10055000DCDAA785FC175FD8F9492DF6F9F17C7A2A
+:100560007E3C6FCE6F74AB54F7AF35BFFC163BFFCC
+:10057000F17C7A7E3C6FCEAFA635FFB4E6E7AC8760
+:10058000F79550CFAF1A725F18D79D55B890B27ECD
+:10059000C7B6BE9058CAF237F535ED6D9DF4FB48ED
+:1005A00030CEF28EE9BDDDAF30F8AD2FC6ADF2F33F
+:1005B0006018E216E7C16D61F473BEE6D1441C1DFC
+:1005C0008753F1DAF30331DF379D67BFFC13D7613F
+:1005D0000C53E4FB49879EEF655D5B5EC2D79315C4
+:1005E000C1886C5DD7CC38E867FAD690FE49685C64
+:1005F000FFECEB2BF451115BD7B83F8FEABB84BE05
+:10060000BAB599BF17D026EEC3268AAA093F6DE670
+:100610007DD8F8249B7EDB3F61D241F45F1D3FC44F
+:10062000DF8978C2CBD7BDE5CDD0CEDF3DF0D2BDDE
+:10063000EEA759BF3156612FB3F730FD29B3F7301C
+:10064000DDD31CA6F427CD3AA5BBD8B8983EDC1C58
+:1006500081181B7F67F3584AEF14FBABDB85DFF78C
+:10066000CB4532F92DB634334BD985FE5F2FA5F734
+:10067000346B6BD421E8FF0D53FEB834758E97F6BA
+:10068000AF9D897C06E763BFABA07BE2E38B545A46
+:100690007F414D29F9A3D3DF4DBC1E976A1BB0DD06
+:1006A000B96199D7F32613A1ECF5AEC17A63C32AD9
+:1006B000C10381B8122ACA5AEF7BC85F3501D19FA6
+:1006C000164B04B3F77723F6571D10FD15E9894043
+:1006D000F6FEE2D8DF708DE301C29DCBF2B2D75BAC
+:1006E0008EF5AA3431DFB2949C977DDC9BB05E61BD
+:1006F000611BDDDFB96006903DEA2AD2B790CF4298
+:10070000D44BF68D82CCF8BCB04F5B13D63B3F1672
+:1007100081416C7C3D140199F1B32BC0CAABF02E22
+:1007200039EB87A5E74D63E5AC5E12CBBF6429C703
+:10073000F62C1D375DB4CFB7979BE3B95AA1FBFEEA
+:10074000345E1A77B5D8F3053297CF075AAFA8436E
+:10075000B92F10E74FBFC63C1BD7B5044C7DC4EB87
+:10076000FB79F95366FD102F7F45E40B0BF9BC7D37
+:1007700093BC142F7CCFF5434B6655A5E73BE07B3C
+:1007800095C36659E677CFF7CE2D991548CF67C048
+:100790000DE387CDEA61DFD367B2DCFD2609EAAD60
+:1007A00082B62AD29F233D51B20F47F6AB31509EFD
+:1007B00095351CAEB7BDE52DCB54822B4EF73405D5
+:1007C0005C772FB0C3D57FA11DAEBB17DAE1EADF9E
+:1007D000D8335C4F78B95ECB051F1BDFB08EBFF9F5
+:1007E000DFEDE39FF17DFBF89BBF6F1FFF8C1B3F8D
+:1007F000F1F8292B5D365D631FBFEC5AFBF89BAE09
+:10080000B58F5F76DD271BFFD3B2C7CFF7C6FEE9F2
+:1008100015F6AE62B53B9B6236FB94D53B29EAF1F7
+:1008200073F46E7B3C66B34F593DD527EC5D5BBDE1
+:1008300068463D9F4FD8BBB6718D8C7143A2BF9463
+:100840006CED2F92D15F1F518FEEADA4EDF18CFEB8
+:10085000C2625CC3564FCBA837C084CF362ED8C7F0
+:100860000511077603C6814942DE59FDC533D83EDE
+:10087000BB1CF7A15109F7FB5A1F1879807D87C16E
+:10088000FCDDA382498B07E27A2E4D5A7C26AE7F8F
+:10089000AD0560DBB74DF2713FC2189F42A99607C4
+:1008A0004DE4BFF336955C6AB9F7BA59D4EB2E0F15
+:1008B00034957CC3527E9168DF2AEE0DD6F97E4BCB
+:1008C000F688D69FD5CFE237BBD8EC4F944351A4DE
+:1008D000C36070DF79C5D43156FDBCD9E7A2F96B8E
+:1008E00003C5B865D9E16A2DE7E3DE83E306F0BB13
+:1008F000697F349510BE359E9ADF6F0FCE96FE8AC3
+:1009000058DDE6A575DD2DD6F50277D38FCA191C03
+:10091000890132E0FD8695653DFB735A9AEDE70B40
+:10092000AA163570DF573A57AB46F1C8D5EEAEC9B7
+:10093000F2E46CE70FF5623E2D736BDBF0BE0E1C2C
+:10094000B0FB71198383F53EF215EE58BD2F9B1F46
+:10095000B7C56BB36F0A8A7BBEFF65DE93EA9E075D
+:10096000EB281BDD56FBC4F9C821AFCDDE2A289445
+:1009700069DF79A28A9F1B40BC84FC84DD782DADA1
+:10098000F55AC75FE518CF07530D5C077099427998
+:100990007157F07755FC456D5AB98EFE830E3A0FAC
+:1009A0000471DFCDECB7253C95F6E327C43D5835FF
+:1009B000DC3681FB1D057C9AD055629CD20D2AA4A1
+:1009C000FAB0B15DB1D5BE3156BAC5E95ED0FBAE65
+:1009D000E4C5F4DE5339A3BF9439FF3B7CDC5F7C74
+:1009E000973EF5B7E559E87B373A8B2DFD967EE0CB
+:1009F00086D4A8DCF5D3F5385CDD7C1B66FC8AF276
+:100A0000AF0BBE751B3FF4658BB730F58338079F7E
+:100A10003516C48F7EF99FD83CAE3EE8E2EF2E88B3
+:100A2000FB36E6F9D0D5C26F3A4BF85DEB211AC21E
+:100A3000C2B741A67B496FC3EF42A32CF47FD2E734
+:100A4000E670B5BAC8DF659EFB5ED5E6B2F9C3E6CF
+:100A50006CB0E767C3D462D45BB3D7BBC8BF76B50D
+:100A6000C34FFBA098EF1C685A8176BC796F7B96C8
+:100A7000062ABECBB3E0F17B6AF07ED47E1FBFBFF7
+:100A8000F726E31BDD226FF3024937DE037875F7A3
+:100A9000A8CBCE036C9F5C518AFAB600B2BEFBF6BF
+:100AA000DD563B7CBDC1EF841760598F70A83BA415
+:100AB000ACFEAD0E9F794ECCE9952BCEC38CBB38E6
+:100AC0002EF8A8DB0FF3E73CE187E1F117BDB57F16
+:100AD000BF97F60BBC9D6E949F46B569B224A7CF15
+:100AE000A73CAE98D19FCDD3B56742AA3FD8EAB50F
+:100AF000F65CEFD824207DD914453E32EB2D045608
+:100B00000FE572EFA5715BBD0A566F70EE7A5D421C
+:100B1000AFFE7CE7BD6EF447BEFDC0E14B502EE753
+:100B20003FA980978DDBB5330829DAC726DDB89F4A
+:100B30009BB75BC97A9E4B1103ACFFF93F0ED27A8B
+:100B4000396F97273985B59FF793578703C343D7E5
+:100B5000B263CFF6C775F701899FABC63B87E3BA8F
+:100B6000364F85EF44B3F4D7D7CFF9F0C81379D314
+:100B700091CED28E7D5752BFED97BB3C167D11F0C2
+:100B8000BBCC7ADC1F77BF941C92459F98E76047E7
+:100B9000EE97387C7B5C491FC2B7638B3BC6E0682D
+:100BA000DCF10EF1D5C41F3F14423C34EE516C7E93
+:100BB000E2C61D4ACA339CD2C31EBA8F6A04A41A65
+:100BC000C427D78F0B772F20FFF9C2F6D5EF282146
+:100BD0006C6FE76F8697480AF1FA82129982F9479B
+:100BE0007F14D219AADEECD81E42BCB27E67BAF3DB
+:100BF000F11CD8EEF7C6FE3F28CCEC0FE0981BF9AD
+:100C0000ABB17D151F6FF7D75E43FDD2E890A337D8
+:100C1000F19792CC7397F3FD8E73B01D7D4EC9BED4
+:100C20009CFFD089CD7136EE915D6F6D8E33F81BD0
+:100C3000FEFBDDCD37A21DF4B44F433DD0F8C07F9D
+:100C400086C0B26E5EEEE7F2D875FF8FEEBB8BC941
+:100C500047D71F3DB47E743DF5DA193A9B77D72309
+:100C6000FFA75867F5173D7521F90B163D36B15FA3
+:100C70004FEB27F26BD2FA2E99B87FAEEF61E3F417
+:100C800063D9BD2275D0E799DD0AF8189C6FBFE8DB
+:100C9000A17B528DECDBE26AA4D702D2CB985FC273
+:100CA000F0BC70E7CA7794E1D9F01DEF2FE3A503FC
+:100CB000606218467A7FE3EBE78FC6D445E72B8D59
+:100CC000708CF4AAB35DE32146D711B9E978023EEE
+:100CD0007463DC4AE3CE557CDC7646C750261DDFC4
+:100CE000C65FC665D2F17B0E3A9E80861FE2F92070
+:100CF000ECEE93F55CD83C3F5BF0D8377BB4B74C57
+:100D0000BDD01B9EE74A1CAE5ABFB1C28FF2B5EBF5
+:100D1000C1FBEE2AE2749EC210D3F5D08933F052A3
+:100D2000F7EBAE6357A27E3CF69447C3F57EDE53E5
+:100D30002F90BC753DF6BC5B27FB1B0212B337BA84
+:100D4000A0FBA703ED8F8512CF346E0BA63CA13418
+:100D5000BD16262F9DAC87E8FB61FA9EE472B03089
+:100D6000B96F9A94857E4FFBF97D6E48F625BC2CB1
+:100D7000D8F627379D835BE82A8D457A1E9E84DF4F
+:100D800073D1D39CBF86F33FC742D76D5C7E73C9D6
+:100D900069D7168F8A710D4E3A77B9F83EA131297D
+:100DA000BD908DEEE63A78BAE7AA4F38E55BCCBB4A
+:100DB00037F9EE7D3EA787AF1D7EDDC63726DE8E76
+:100DC0007C985DEF1FF24B028EA6C9A58333D741F5
+:100DD00015A2F1FEE569788FD0DB642C7D40A1F788
+:100DE0004E57B43F43FADBA92716E6B0B3FF26F40B
+:100DF000D3C23DFB86A33E3BB2FF09E2C7853B0F52
+:100E0000BB717FF3EC8E47DD9D5569FEC775C1FA56
+:100E1000BEC59187F70D27FD8DFD67A1CF71D17FED
+:100E2000E35E7BFF8D3BDFB1F53F3FDEEE26FF6AE1
+:100E30002FE3BCA91A97E37CDFEC7001BE9BF4663C
+:100E4000BB32399B1DF4825817BBE36A82352FA24F
+:100E50007F522974EBA8FF5A961A2FE0BB89F1E75D
+:100E60005DFCDD4AD578D1C3E43351E0D671DFDBD8
+:100E700012BC0C748B1E6F73E0532BD226E07E40A5
+:100E8000AB8B8EB6EEBF4CF80B0CD906FFA2E0E49C
+:100E90007EF8DE15EEE3747C27568D70FF7568D200
+:100EA00064BAF7A8C99A2FEBBACDFB43BF1DF2BFB6
+:100EB0004B9341B7F0D7C889979D8D2E3B1574DBB6
+:100EC0007E605D1D3F0F36E7BF6E006CC2C723D644
+:100ED000493CDE3F7E318F3334ED3B70DCFF72DA0C
+:100EE0007B60183AEA2352473A1FDFB0DC734EC7E3
+:100EF000F1822E533C738436012AC42808C38B71B7
+:100F0000B68371DFD54E6980A9374CC7E70DE2FC87
+:100F10000DC7287FEBE4BF50DC63515E74645E5FF5
+:100F2000CC178A771452B4CF13CF06809C5756D271
+:100F3000933E803AF588D59FE4814DB49F4177E692
+:100F4000C93E69BC98F17666BFEB7CE3255C8F7087
+:100F50009EFDF19D367CE4A8989F1FF0791B94EFCD
+:100F60006BE61DE3604DAD462CC1249A31C935189E
+:100F7000CFF7DB249C5F29B4535A061D94167A35AB
+:100F80004925F85E267F970C7F8193790EF84EC134
+:100F90008E77DADF3728FA4B3146C784D8E76C2DD5
+:100FA000B0C7237D3B8FEB996BF26433FE3966DD6E
+:100FB000B725A08170E02BE2CF9375CB415EECAA00
+:100FC0003C0B9F29810E1E5FE6D82F5FA82CA1F352
+:100FD000FD95E19EE3BA968BF8F05CE56D7DBD333F
+:100FE000B700C1CFFD609297C7791BA06B567EC436
+:100FF000589E1A6BDCA4617B4FC7857CA8209EE3BA
+:1010000094FA50AE589A877CC5E8B05AF061103A0D
+:101010004527C7C8FFB1D91D4B201FF6AB88493CF7
+:1010200098282A71BF9AA158F940CE9B51D253DC1F
+:10103000164C637C62899BD92AE8A2AAA0FAAB115C
+:101040009E4D82FE4EFEB4C7C19A765D40E43C22BE
+:101050001EEF67A37F47EF8CA945018A7F098C6E3D
+:10106000B906DF6F55A14943BD1A30E35BC47D0F5C
+:10107000735FED7CF7C5E3888F7589FD7B46BCB84F
+:10108000588FE97E5C16BBD9B91E3F98973DCE09B3
+:10109000C6668F4B34EDB48FCBFFE6FEB3C1DBF1F8
+:1010A0002C01A11914D7A90ABFC584691AF9DB8FCD
+:1010B000EE94F87B1B0E7E3ABA2B7F387F6C47A3E9
+:1010C000F7CBF3C47769E7BE7D685FB584C0282895
+:1010D00024FDA72B0CFF2BA4915E89A50B76BFF3F3
+:1010E0009B27D18FBF57017CD7ED289B6307CE5339
+:1010F000350A906879B0C646E78F3BAFCC734C2E6B
+:101100007FD76AA6FC05A8DDF19D12DD1753E0EC40
+:101110003BF1BDABC6832E48B2F2E3C0FB3DBE89B6
+:10112000DB0D737EF1680D9304D820E0C1F5CBBAD6
+:10113000CEF499EC07DDC22761735D881B1DF8DED4
+:1011400073BDC04FDF68A1AD9E39BFB7664D3E4845
+:10115000FE9F187FFFB9DFF4525BFF20FC233AFBB0
+:10116000877C99E16790636EA075259A9F223B88E2
+:10117000EDA771FF91942208B7D39FB2708F44EB13
+:10118000D9D56C3DC3F7D8AE4E3AF6A38E782A1364
+:10119000FF4EBE9503C28E0C4020079E23A9D1743A
+:1011A0003E4B7277ED2F14B2C7AE7D484A523C7564
+:1011B000E799F9407857C82FF51A34DDC1569834AD
+:1011C0007F3BF0E709DBF1EED3ED78CFABB4E3374B
+:1011D00018B1E3D189E7FCB1836CF5E72B0D6E62A2
+:1011E0003E81EF4AF60FF1CDF424CD63219B474AAF
+:1011F000CFC4E7DCBDEB56A0BFA4573C3AF07796CE
+:10120000037F2760EF3E5E0A516FB125FE534D917B
+:101210005C39E5D0C45399D63181BE4582E4A70E2E
+:101220008B4EA47ADEAED4DBCE85AA3A427268C673
+:1012300029E775AFABAFC249965E77E981C3B320AA
+:10124000B7DCB5377B23F52E3C1F8748FD103C2FBC
+:10125000D728DD84F547F4B4DE1A349E0B221AA693
+:10126000B7887393A355FC5DA4F6D47BC568FFDDF6
+:10127000527DEC12B4FB1BAF8228EAFF6490AFBF33
+:10128000BB455A17E471D637456530D05FB0574932
+:101290004AE887D28C5F5C8076DB5E974EEB9F7668
+:1012A000EC37FF46E5A3343CC72891DB46E2B8ACF7
+:1012B0003EF9FB8FEE7D35F45D8B7DD4B5E7B661ED
+:1012C000B83E6D94616EB67D407D808FDF55F99795
+:1012D0006264CB05DE63B42F5FD969F7B3B9777366
+:1012E0003FDCC23D97923D7A60367F8FF3B123FC9D
+:1012F0005EEA2465C657BFC4F2E3FE53BC6304C66E
+:101300009499C53C9403E999F0313C333CAE17F114
+:101310009B8D7F95297E73DCF920A1BC8EFB23D0A9
+:101320003DD4D14DB369BD7A3234E920A6757B2511
+:10133000F21F351EE1EBDB980EBB9FE89C3AA61727
+:1013400058FF357BB97FABA6939F0F9CF3A2BDDE00
+:10135000B84E7BFEBC5EF8775940AC5B21283E9DC1
+:10136000F8DCBD2E6355809FA7D1BDB2889A7DFF62
+:10137000D519E47618C307CDFFE831882C63F3381C
+:101380005A5F3A01EF291D7D8F9F371CFD50999CB4
+:101390006D7FB539C0F965A39B9F1F6F9C1D482EBB
+:1013A00065F3D83F7BDE40DC57FDE3DF6303B59E8A
+:1013B000EC12A622645A138D7C188BF2D1C2EFBBBB
+:1013C000415B49B6F7934DB930E5C4948F92D9FE8D
+:1013D0005836BFE8A020DFFFD5CEAE94307EBBEB01
+:1013E0006989CE98BA9631B87AC0631C96F5477869
+:1013F0001AF7BC4B7E0AEFDEECFEEEA703219A7FC4
+:10140000D7B2F8D2F318BEBEC7843B8EF2E06E2B83
+:10141000CFD67F1CD693FF6A7B80F3739797EFC379
+:10142000416D2B991A44399978F10A06E75D4CFE13
+:1014300070FDDEE88A10DCF10540EFFF81B85F58EF
+:1014400076096CB9C9B25F3B18987008E97D28C06D
+:10145000E38FFAC42212C21DF9E8FD10F67FF403EF
+:101460000FD1AF54F88BCC764703E21C2E68FC8674
+:10147000F8656E1129C5482C14A91F0530620FC3E9
+:10148000B7457FA7E916A7710A634C0732780A03AC
+:10149000323F0F63FB34DC7F3482F913A7FD8A29C6
+:1014A0007F78E94DB5C4DD4B7BA55490E9CFD1DE03
+:1014B000400AFD328573657C8387D9A35EDE5F8732
+:1014C000DD6E450D8CFA177500509EEF8F4C7D6CCC
+:1014D000EAF19602AEFF5AD6A9A41F37A99D3EF4A1
+:1014E0004B971B7AADCAC62D54758AB7183097CB67
+:1014F0007BDEE07B0ABAEDA2F3001EF948C9EA1FC1
+:10150000393368E22BF60FC4D7F083C7F6A37915F9
+:10151000F1411FA4F72461F78C7B5BBC8B28EE198B
+:101520003476DF23B0EBA38D3E61C740DBEFF1DC07
+:10153000FE89BFAA747FA05BFFCC9E44EB2928558F
+:10154000CF207F9DF72BB13D10FA87EDF6082FE7EE
+:101550003C174B201C4E7D3316985E927AD73B4E3B
+:101560003A3323BC3B5FC69032EA2093334B7BA7D0
+:101570009EEA1714EBACD05327607CBF0BF5343FC9
+:10158000552F8E3CE3B1F08FA9A7D2FC9424BC3A2E
+:10159000C791C0DB9DD706A37E794E413FCAD109D2
+:1015A000FCEFFCA4841C15BC97BC18F961FDDE8B14
+:1015B0007CC8F7BB0E4EF4A2585D1BE6F7CED47D77
+:1015C000D3E220D8C77AAEEC02AF1EA8447CC88410
+:1015D00007456379CBF8C7DB2471EF52CF9F96E5BF
+:1015E0007D6C33BD36CCEF95ED3A38289FEF4753ED
+:1015F00044F76EBE17FE0B532E4C7E77F2B7290FC1
+:1016000009D64AB6D8118AD42EF68F763F4242D8F0
+:101610001109F3FD997809D9878B847D98080C5DB1
+:101620008D7FE6A02555ABE1B9C7A2E0208AAF5E69
+:10163000D497E3CF890F336DFC80D98B9638F84669
+:10164000F518F9C71A3F70DBBE9BF8CD851713BF9D
+:10165000E7227EA58F8FDF73829CCE4E3C7FD2F92E
+:10166000975D3B36EB7DBE7F95F99F07B1273BC960
+:101670001FCBEF9398FC66EA8F9AEB5A13797A5A4C
+:101680005F98F7414CBD63EA97731ADA9EC9CBA203
+:101690003F9C7A23E2D2BEBB86E12FF2B300BD7736
+:1016A000E2D423EFE12F25E477BB3BC8E07DE4D90A
+:1016B0003765F49B3CF6533677561ED957C7FD82E3
+:1016C0001DA776DE65DAADA6BDEAAC67DAABE6BA91
+:1016D000639E37FD3A187B00C797F630790A617C24
+:1016E0002CDF271F0CC41EC2EF790C663FC60256C2
+:1016F000A6CAF97ED62EAFB9E433CF217FED299566
+:10170000D6BF385BFF8648997098E3D707C5BB0200
+:101710008CEBD0AE29AB013ED842FE6E40D970882A
+:10172000E1FA8CD74B719EBF1276D97362BD31D36B
+:101730008381E80184DFA542DC53FDF1E136FD8BB6
+:10174000BF0E1AFBB13FEF6483E6D15F8308DAFB7B
+:10175000FDD57629C2E0286CD0A56E678FB9AEB3EF
+:10176000FEFA4FD1E9DD8FFE78A700EBA37D9485CB
+:101770003E7F0EF2B8A605DECE67D1846F9CD234D0
+:1017800039D4C3F97AFA3D8488F073D9E3408E3EA8
+:10179000F5C2003CFF7CE507EF06F15CEBBFD463CC
+:1017A0004184F3F525BF0FE27D885796F0FDC7957C
+:1017B0000E3BE784C0DFB450F44890A5DF69FEA873
+:1017C000C6F60EC9627E3E737552C14D6937BFCFF2
+:1017D000DF9147BE3D33BFA0BD8F2D6FF2E9020FF1
+:1017E0008FDB72CEBF2AC4E368AEDEB9C5DD5FC74A
+:1017F000F163FF8DE3BF2EECB8D77707C9FF61C255
+:10180000336BE74837E2E1BFF67AC4B97F878BE3F1
+:10181000DF9882E77331410A279CCF3E9D47FD5DEB
+:1018200075BB4276C74C36D662C6DFB1BD57D33ED4
+:10183000DC398FAB5ED127F563F4BB6A9544F62A99
+:10184000D65FC2F821B678259DE339E73933EE88B3
+:101850001F11768533CE64CE5E7EFE5E0FFAEAF10E
+:10186000E559E24EF65E4CE76E737AD9F7948784B9
+:101870003D5103E760DCFC09A85A5BA5F7BEEF7990
+:10188000BD192888ECCD662FA5479A359E0AFD39EB
+:101890007FCFBE6789CFD48E1A94FB5D075FCDFBE7
+:1018A000969ED6E35FDEF2EE3377B3FC28E07E1E31
+:1018B000D3DF3E43E0FD02A1CFE7087B61D4073DC3
+:1018C000EBF319888FE199F09A7A7C06FEBD410B03
+:1018D0001E4CBDEEC4C7F18383F3903FEA42CEF3C2
+:1018E000E64F86975CED1628D9E3194D393A12E494
+:1018F0007C5DBFEDD215A56CFCC453AF9DD1C9F57D
+:10190000C421D413269F0234B9518E9DFC68F2493C
+:1019100037DFEDBD99F064F20793ABB038E70CE325
+:10192000FED0C97FBDC53775B93ACF40BDE0E4B33D
+:101930002EC7BD6833BD2CC4FDEFF5BA3109F7AB36
+:101940006CB959C1CF03B93E7A5D6D7BF64694D729
+:101950006D5C5E163CFED04F500FCDFBF1ED21D4F7
+:10196000436FA86DC5385EC3F6E5213C577F5D8D9A
+:1019700087B0FD1B49256BFCE3CE9064BEA7618B4D
+:101980009380D6F82528C7FFD8EED2F01CAC71871B
+:10199000879FBBEFE67863797EDEBE3B7B9CC4BC51
+:1019A0001FDD5EACF3B85B7BBCC43617F92FD0BF2C
+:1019B00086C3E43A2FEE3E7F6EEFF93CBD71B788E7
+:1019C000B3D97D71D67809332EC1C9C79B1CFCCB16
+:1019D000F0437EBF38838BDCEDE29C3C71FF9DC3FE
+:1019E0000F33F88E6CFB5548AAB2FAE3F979FCF193
+:1019F000F6EFFED02BE7E6DF2EC1EF697B229935AB
+:101A00007EA2C1950AE1BEAA618B8BF6810D0F29DA
+:101A1000F45E1DFCD143EBF9FC877EF68773197CDD
+:101A2000F31F71154DE1D3A03809935EDD712C824F
+:101A30003EF31EFD193F5FD6453C8BA0D3FC47F615
+:101A4000B9312EC789CF89EDFBDC9D8E3808A257AE
+:101A5000FBE149749FF0FEF7DDB8CEBEF1B404FDA2
+:101A6000CA33DBCFDDF2B310EA0BC413C50108BAE9
+:101A7000E58E5B4A5DF2D3D1548FFC76BDD17109FE
+:101A8000CAE218E2F7877FCAE098FB9287E2A7E6EE
+:101A90003E7C1DC519BDA63671BEBF677931AEBF8C
+:101AA000735DF1628D52FE7DEEE6EB891FE73C7FB0
+:101AB0007DB1B88F54C2FD3DF1129CE7559BBE49E4
+:101AC000F39C0D31E2C7B9F72851F4B39C5061F291
+:101AD0002359E466683E979BD7B67AF0311D784D5E
+:101AE000F839E3BF53C4DF8B749E57F177634E8898
+:101AF000FDF73F43DDE78D5EEB7EAC71DBCA0EA4E4
+:101B0000D39B038C7E1AC513A87181377A7F5D79C8
+:101B1000FEC27E42BFD17B37A61D3411BF63FD0ECE
+:101B200017BD7B6369677BB76691189FC1ED9746C8
+:101B3000B0B438BB1FF49BF9921907CFE36F4C3E4A
+:101B4000CBA507B6F17896F70E713D83713954DE57
+:101B5000E14AF5B3C5E3786CEFA2A4E34C5C42CE56
+:101B6000EDE50C4E8A97E9C6EFD312FD3D08935F71
+:101B700066AFF7D8E3F3BAF9C7F96E8F3D7E668E8C
+:101B8000C32E33D38CF53FDF715EB7E9D4E2671A19
+:101B90005C498A7F6AF8A387F6270D0FB9A2889758
+:101BA000B7763EF3876F31BE7FABDD9463BBDE75E6
+:101BB000CAF1DC5D63209B1CBF158840563966DF87
+:101BC000B3CA71207DAEA1C367AF77E7E4D0BB5F36
+:101BD00075E093D90DF91847FCE603F30792BFC2ED
+:101BE000815F53DF3AF5E8AB219DF09C19EFC7D731
+:101BF000FD743C26C7A3C99FF31E5C40E374F3B198
+:101C0000C9A7261FE7881B73E2D3599E8FBEB33145
+:101C1000997E91782D54E2DF694AB881BFF726FB9F
+:101C200023C8BFBD9D77FE36BFDC7CFF6D04DF1788
+:101C3000F2F3CE4840C3BF5881F7E5946CE7EC91CE
+:101C4000897256FBFF07F9DC4E42B72CA68FE7736B
+:101C5000FCB52851E1C86BA77B0C74B68A7016845A
+:101C600048CE5C224E85F54CF7D12379F2BB3AEB96
+:101C7000E3AEB5072E52D13F3B4ABE6E30CBEF5A92
+:101C8000FBE2452AA377E43CF9D1412CBF7BED1F51
+:101C900079F90879948BB1EA8EF84B17D5B1FC42EB
+:101CA00031EF85A69FA4658CCD4FA2CA87EFC0F304
+:101CB0001CF5A7FCEF11AD6672EFAD4E9F33E779CF
+:101CC00020EE63F93C374B597E45F9EF57E026F299
+:101CD00057FED8867CC257AD8E783EA279297E67A2
+:101CE000D11317521CE9E3F9DC1F7DF6A3E7D1DF1E
+:101CF00075FC0CE1B83FBF6F6E385A5CBC9F23BBCC
+:101D0000CE9E88783E7B20FAD4D2F4A85675FAEE9F
+:101D100063688F73BB3F8CF75B12056EEAE771C196
+:101D200067A79A9A712F4A1EE70B255F6E7A84A5E2
+:101D30004F0B7EF88F7CCD5C8768DF7DF4A97E5BDE
+:101D4000F9BB31C7CE407A2BCAF13FA3BD79ECDB9A
+:101D500079F4F7475EF273BCBDE4E778BB3C7F8D56
+:101D6000EB2CF6BDDA7BC675C8F42F493BAFC774C0
+:101D70008B16FB25A707A4B0DF6F5DA9F07E034D8E
+:101D8000417C374E32B81D2E31669AC1F0913040F9
+:101D9000770F4611B6C77F284AF5B1148D1FB48D51
+:101DA0000F656CDD64727EF9384E2F865B5A475F93
+:101DB00018CBF3267CD39383129D3AC1F327846713
+:101DC000A4273900F753DF626615E77BFBBEBECB65
+:101DD000CFCF37BBB0FDF074FC40E3DF64DACF3621
+:101DE000E21C58FED12320FE5E217F5FC7F47B8C6E
+:101DF000FBF5B5E4FF1EBD673E8F3311FE2EF33CAD
+:101E0000BFE6003F9F73FAB7CE8335A44FC739F4BE
+:101E1000E8797BBE4AFAB5B7F3B97F987AB5144A28
+:101E20004FF37CEEA3FC53389FFB1F7622B26E006B
+:101E3000800000001F8B080000000000000BB55A56
+:101E4000097454559AFE5FBDDA92AA54AA2A45082D
+:101E500004E34B0224210B45122004D42220D0316C
+:101E60004A801681F64881B298AD98B4DB699D43EB
+:101E70008520D2DAA319756CCE69BAE785D611250B
+:101E8000E92924D1E05432C52204254E9045A01DF5
+:101E90003BED7423DA64313D824BF761FEFFDEFBDC
+:101EA000A82541E93E67C8E1DCBAEFDD77DF7FBFF7
+:101EB000FFFBB77BDFBA4409600CD03F1D2403D47D
+:101EC0009BF19702307C3C2311F200F47A00D9098F
+:101ED00060546428C1F62AFDBB0DA06D338E338596
+:101EE000FB6F252A6C9EFC53F6FBC1462DAC868207
+:101EF0008879ED7CDEDB652B4031CE7F1154533A7F
+:101F0000C0B4BEEC9FCFC1BEA1DB002ABD979EA08E
+:101F1000FB6775AA1F459B71ECD74521BCB435CE34
+:101F2000560053F195293A50CC6C5EB88AFFE39481
+:101F30007850B2C37D4BB633AA2FC7DB764122FE61
+:101F4000F07B7A53508E227E0B12DCE3A3E679DB22
+:101F5000B6A89BE42EB2AFAF20B9134B32A2E681F4
+:101F6000E3FA4FFAB09F8D7F573300A643656208AE
+:101F7000E52F844A8F84F2BA3F027708E59F718A81
+:101F80008FD39E7387FCB217712CF928FA7A2944F3
+:101F9000F4719EC73EFAC27138429EE9F604D70535
+:101FA0000BFE180FE3AFCAA3E2E80E114EA7643789
+:101FB000AA01EA8FE12017B69F810A88DB342848FE
+:101FC0000486AB0C2AF6DF04EF0B73B0BDB279C800
+:101FD000717852184F87271ACFA445D1788EA98CD3
+:101FE000C673EC8A68DCC679A3714ADD3825EAFE3F
+:101FF0004D9B0AA3FA373F561A353EDD5F16D5CF03
+:10200000DC5E1E357E52D3D2A87ED68E5551E37348
+:10201000D4B551F7737757DD90FEF303F551E362C2
+:10202000F53FB5E32751F396CAF7CA9011E6811F31
+:10203000FF880785A462D23FEA210423F53FD3E558
+:1020400027C6FFCDFA7F98F49F1BA17FF9DE44AF2E
+:10205000356C6FB1ADA6D79FD05AC7905E714E1444
+:10206000EE0AE919AF0D1AACDB256C1DC89D7BF19A
+:10207000FA63667EFD5181CF95B83495D6EF081E80
+:10208000FD5AC216D5C2ECD0FFB1456D44DE3C2AE4
+:102090002B0DC4AB17E54A09509E54549D2E13795D
+:1020A000A4838D01E4F7B33ADDEACA08F99EB3735D
+:1020B000BFF29C5DC7DA5F18D156F1BDA916F09B3F
+:1020C0000BD973B436FAE7015CB72D8981822F2CC6
+:1020D000DF3E7F0EDE77F4652B0E0033F56F01389F
+:1020E0001FCFE53D1FCFE55C65521AFBC87FC8EAEC
+:1020F0002492A7D9EEDD69C7F79C979E30E09BC17B
+:10210000E0F21BC8EE52CDE0B7E1FB1A0DB0BA12F7
+:10211000FB0E7049F5D826C24E3BE18B62285791E1
+:102120001487AA7213FBF0FAFB24D138B231B70E30
+:102130006600ACD4FCE1C61CE60F87718DBDA450CF
+:10214000BD9208D80E3F90C9AE9FBB0FAD10EDE910
+:102150009C91E3A1E17051F8C9CF379B597B69B3DA
+:102160003DCA6F6E6C7E2141C179CE65C3A2400429
+:102170007E5D84DF746A6586DF80FAC7648267707B
+:10218000DDB79349689FD4BBCD8A439EDAF10F95A2
+:10219000807A30B62DF1A34E60A55161E3B5797C0C
+:1021A000C1B940381063E9FA3D1FC22692EF9E6F15
+:1021B000B18D785F8FDDC0DED743EFC376393676D9
+:1021C000C46D39EAC541EDD1390BC82EF07A48C249
+:1021D000FEE26E30903D2CF1A61B489E93E03EDD62
+:1021E0008EF29CB52BECF91F42A581E43A735F6D2A
+:1021F000028DBB369F360F0AEBC078F2A1C36F4841
+:1022000046BF35748BE4DEA5B0F799E97AE5BDA940
+:102210004F5A95F0FBCE80B7FF34EA7B29B8D9BC82
+:10222000DAFC6879517EF18D8DD5BF4BCA207FA82D
+:102230000333F9C34E13F3878355575A5FC2FBAB81
+:1022400053FB6E32E273E7ABBE9D4CB8ACDC21832E
+:1022500082FAFF24C1FB07FBF4301EE71EF873026D
+:10226000DD5F65525F7909ED00F698DCAF003DB7A0
+:10227000873DA78D1BB0CFFD8C78072508D4ACEB2C
+:10228000DBA786FFBCD773C612CF347E3D28F85536
+:10229000FF5AD658E2537DC2357EF1FE2B996389F1
+:1022A0005F3324CECBD879BB905F4A16AE1B79A59D
+:1022B00020AFBABE2A4B223FB1EFB8B388E4D48333
+:1022C000F76AE4BAF6BDBF2A97EEC359D70DC94BDA
+:1022D000B6E94739EF012E678FB08F15C1A422D21E
+:1022E0003BDA9DC581E356FDC76BFDBF257C3AF700
+:1022F000BCF2388D29BE313C34FFB4379EC7231061
+:1023000071CE2D70C13897AD47510721DE4DF9C20E
+:10231000F5FCD65EF20BC8AB2B3A747C99E4AF2A7D
+:1023200081FC8205DC0AB5E865DE9B8D7A6C3CA0F9
+:1023300083A7B16B23A7A6F99F12ECCB3AEE7FB02F
+:102340006F4EC13822FCD324C7BF2EDACAECC76354
+:102350005D3383B9442657F1E1AA0A7A2FF4A21F0C
+:1023600047592BF18FE2C16CD874280EE59CB1035C
+:10237000F3031C37F32CBFAFF9F55921DD1A6322A3
+:102380008DFBD917B28D208A8E03B30F977F4AF346
+:10239000CE8688E746890FB31C7F5F7C98EFE0FE0E
+:1023A0002190CDFD7B2014AFFAD3D9B44595F9C85F
+:1023B00017278F1F2D8839D9B1511AC836A31F5E30
+:1023C000E468DEBE7D02D26122C785FA8DF45B2906
+:1023D000623CBE96371E9EC2FC21FC05A522BCECC9
+:1023E00042E618798AD1EE78307647E59DA123DF61
+:1023F000D8FA701DAD4EE5BF485F4398D7905F880F
+:10240000D3F7191DA3ACEF4DF2AFC8FFE71C3A2676
+:10241000AFB943F2A8F87EB3E20109D71067B74F0E
+:1024200093A5F0F832078F4BB547CEA719515FFD42
+:10243000BAE3B63C9CBFA6FD0D1B2E1F7E6CF3AE0F
+:1024400073E03CD5E73E9841A10B199E5699403860
+:102450006524923DE5EBC1AF2F1C29876F072E063F
+:10246000295FB72389B5391D125B9F2FC4D739D097
+:10247000D1E88CF41BD79EFBCFCEF1A4B73D6360AF
+:1024800005F9E3FC60D106E231C962405DBCFE554E
+:102490002E9BEF09473ACFAFF5A0A7EB00AA6E2914
+:1024A0000EDA63C0E770DE81AF64364E9B37BF63E0
+:1024B000AE6C471EE5859A0E525E18173429A4E7C4
+:1024C000B89781E3128C637ED1D7B510287F1D7435
+:1024D000805BC2FBADF1431F132F863A4DCA2E8994
+:1024E000F06B0227CEDF6AE4F133070DE10D6BF8E4
+:1024F000BAF6BEB8E0CF81FC15F2C3A3D27D7D133E
+:10250000DC628DC43D81C9FF4B07E7576B7C486790
+:1025100025BF8F9CDCC5E40ACB09ECBD9A9C39AC85
+:102520000E68350E5D78DCC5E4B2131F7280CB09EE
+:10253000C12CE5157ADEEE61EB88B32B6EBF345209
+:102540002E5F01E6C56877CF6E816B764E76EF8B96
+:102550000FF7CD6813AD1920FCC229968784FBE8DC
+:10256000B04AC2CFBFF1CF67B66F9DC3EA23BF8C1D
+:102570007CB0609BE0A47572FBC2B2C933A690E345
+:10258000E0469C2C667EFFDA78E4BB95FA563ECE98
+:102590009D68B7944BCC6E80ECA64EF89987A4D07A
+:1025A00085DB50B55F860E1628284BCDD1B7196F45
+:1025B000AB75C197F2F17E59BC3748FEF7AD8F7409
+:1025C00060C3F57FFE5A9C5A817864EF6F4EF658CF
+:1025D00047CEF7D4D92DCFA792BEF74B0A228D79DB
+:1025E000E1501AC95717FCD4E8C17661C7EF8D14C2
+:1025F0009F5639BD47C80E4A3A1AE6117EB3A0A9C4
+:10260000D16E657ED14B3C0DA470FF317C6AF2AE79
+:102610008608BC2F3978DE0243DE9BC96E82C23E3B
+:10262000BB28FFC1B65DE461ED0756662AF9E1E714
+:10263000FC70301570CE2D70389570D6AE0FAAFA9A
+:1026400045C4A7DC33E6D59E08BE5D10F67E41BCCE
+:10265000EF1F9DDE8F0887EA039F186DB82EDF1FDE
+:102660000269149F0298A7D9BFC32FFA62ECC6A7CC
+:102670001F32D278DF45607E04F5BA3511F5B4E734
+:102680004CC7943556263F24E2BADBCF9998DF6CCD
+:102690004FE7F6D770FA7201F9ADCB9DD537135ECF
+:1026A000EF3B0C1ACFCBE2C99EF602F3639A3DE6EC
+:1026B000913DA2E879C4F362EAE7B0F95A8DBDE52D
+:1026C000CCFEDA7540F6873C67BC479EDB29FFC825
+:1026D000B323EFD9F359CC9E5B7B31E061DF8F7E72
+:1026E0007C12EB972DA37E6BEF7C3BB3671D425BA7
+:1026F0004876193AC8E609604C23D549501999A77C
+:1027000096396C4C5ECD3F563AB8FF0F642B896EFC
+:102710005C8F4596A3EC20225EF2BE88A72B9F37E4
+:10272000FCF4C509644D222E88BCAC4BE4C1E02DFD
+:1027300062FEFEC72296D5BF53BAB805D75BDF232A
+:1027400073FF2F787250E4C98737A7B03EC50B05D9
+:10275000F5341D5B0FFAD3199E4DF3D0C6A064511A
+:10276000D3216A4B2B03F3107198B3A2F790819B8E
+:10277000732EF1AFEDE00F72F5C4F77326884311A5
+:10278000DBBE19FAF875C4E1912EC47F94B884CBEE
+:1027900061FC4304181FAFC79B41A9EFAED96E4C33
+:1027A000F99F1FFB037D1CDA0F1103F1C87B7ECC60
+:1027B0004FFD2850BBD333D58938FE36C93BD58968
+:1027C000380E9EF826997C7AFBA94F6CE4EFDB8CDF
+:1027D0009E5CE2595B06D60BA3F0738293F3A7D8F5
+:1027E000149DA76BED5227E7FF643F3C43FCA96BA8
+:1027F00093ED2AEABBBF4DF618318FBAE0F126EB14
+:1028000011D28BE05F3E9BE2BBA87FD771D8611DE0
+:10281000E52F1867D6BF6888AA4B6BC4BE4616F46E
+:102820006D4B459C7C2F4BACAEDD18938FD450FE86
+:102830005240F545B391D653F572CC3C94C714D0B1
+:10284000B8EFAE73973AC53E472664521E833C628A
+:10285000F5F4D069D9BD8B62A01EBA4DC8DF3D3AF0
+:102860008E13FA4D668F5A3E637279E691DDCFD3AF
+:10287000E28AA85B875A2595D9CF6EF4F3D82FBD8D
+:10288000A83403C7E154CA0C5A0FE765A99E8F2FDD
+:102890000DA633FB2BF1603D8FEB5E8FF5BC4AEB51
+:1028A000D6F23CD5C0D68FE197E579B3406DB4E15F
+:1028B000B80DBB25B6EF53BDDB1095E7F9043E35E7
+:1028C0003B4E1CA172B23610735FE0E38BC1E70D83
+:1028D000FA316B244E8F3A45BE97066991F91E7402
+:1028E0003B47AD0B347CB43CFB4F069E5F7C20E63F
+:1028F000D7C6FD8B93D7E7751E60FB4735AAACAAF8
+:102900003C1FB4AE41BEDC2FF872BFE08B0FF8B8AD
+:10291000DADD921AA278F533AE7733FE112EEB0290
+:102920006B16A42A23795525F0D8D86260F92FC0F8
+:102930002623D9E7C69D31E3042E5531B8D479A5B5
+:1029400018F9783EFEB7CA576DE0FB35D5C82FBFE2
+:10295000F2FF276FACFEFE5DD3DF149812A5BF45D2
+:102960004937A4BFD83C79EF9129167A7EB83B83CA
+:10297000ED4368BC899D6781C8B317EEE0F9687FB5
+:10298000C73C4B3ED553C7F56E09E729EAF95F5BB3
+:102990003EE251D82943054E31182C7AC68FEBDC24
+:1029A000D73D719982F1A1B047CFE24B514FA14A77
+:1029B000754D614FA1253381194F12D50B380F8BFF
+:1029C000CF83C7279ECC233FDB3DBF98606F385E27
+:1029D00068A13C621FF07D0DA9A738A92F22DE74E3
+:1029E0003BF9BEC6B694FF7996F2FC857B0D6ECAA4
+:1029F00047161A86DE9FEDA2F7EBDD0DD8AFE95939
+:102A0000BB258EF4FE9AE4A674FC486FBDEB47A488
+:102A1000DFA0C16E62F23E7C90EEFB5B24F7241CCB
+:102A2000EFEBBC3DB715FB85CD456E82597B5FA1B1
+:102A30004379A182F2C5711656C72FBCC9C0E2EE18
+:102A4000A5F1965F53BE54E5695E40FEF8D2DBFB0C
+:102A50008CE40F065B2548C1851C4939F41B3FAE49
+:102A6000F3D29B278C9494CF6B3B61ECFB8E7CA2C2
+:102A70005F9521C4EAF72623D541B5CD5ABFCF488B
+:102A80007AAA14F955DDCBBF67FD2AAA13F07D554C
+:102A90003B6555C19F873ADF3212DE752D128C4D92
+:102AA0008FB8FFB2C4EE6BBC5F0B9C076B857FAA2F
+:102AB00016FB90D5B40F89D7613BF7371AEF1FD8B3
+:102AC000BDE40885EF754DD17EE841C1F30D549703
+:102AD000B2FADB6B24BD6ED811334EF0FCC1EFE1CE
+:102AE000B93549F8F31CC8219E5F9ECBE3C9E513B5
+:102AF000F1963C5CD7E563B21BE03BF9CEE2EF71A7
+:102B0000912F0C87742C9E69E3063AFECCE28DEF80
+:102B1000F8B091F2DB05C12F983E2A8207E613DE5A
+:102B20007782B786F0BB3368B193FD57F4717F505D
+:102B30001E34A9B40F7E2704B6929E07BB5EDDEA61
+:102B400024DEFC1BE70D087FB741E0BA41E0BA0183
+:102B50001D7E12BAD8AABC032F61BA0FE5C0FD5082
+:102B60007940F8A19DD13863E4B98FF4551734C189
+:102B7000D378FF0EE18FEE68E1FE28364ED6897DD0
+:102B800080C171B98BD97E2BD6BB94C7D5B444E331
+:102B90005F27F605EA62E2F0CD497CDFEEFBEAFF53
+:102BA000583DCD8DD153C510E74F39C53D5C7F777A
+:102BB000684B1EEDDB6978C5EAA95BC94C1CAD9E6C
+:102BC000D5DAF745DEAFF517237129DF0CD89BACBA
+:102BD0009175FCAB493CFE54CD92FDA4E76BF5CE5C
+:102BE000C443058A2E5CEF609DB332690CAF7BA6AF
+:102BF000E1D44727C8E07285EB9DA7525EA828A4C0
+:102C00007CA585FB9181129C2F91F27960FECBD738
+:102C10006252A94EF1217F589D43BCC1B63228DDD6
+:102C20004EBCC1FA611DCDBF84B68E1187251D3CF7
+:102C3000EF5932FF0BC6B76313F97A87F5CAD8D1BB
+:102C4000EA09AD8EA8FB8AE7A9DAF53AB47B1A5FE8
+:102C50001794585DDC76F0EBB474F49F839D57D2E3
+:102C6000D660FBA258BF96A70E619E9A21F214CAA5
+:102C70009FD77395C1064C871F431EAE17710EA4D4
+:102C8000ADCC4EEA28D925BEB54B7C1F673F5E9878
+:102C900089FEF7837896C70C9CE1E743F4FC139810
+:102CA000470DAC0D1C76E2F8CBAD128B7FEB31C734
+:102CB000BDB570A4BDD70A5E36C01651976D656D5F
+:102CC00079F6DE4F1E277FD46256C8BF0E74341AC1
+:102CD000D9FEB21AF17CC6C87CA856F0B7F67BF6CE
+:102CE000B55E4D127152F012D7C1F2DBC163B2DD95
+:102CF0002431FC7E353E122791FFB41D8C637A1E71
+:102D00003C615529CFFF5CF0EF92D8776F2891197D
+:102D10002EBA59BCCDED7A2B83F44A7AF0D23E4AD2
+:102D2000D75B533C6C9F4F65F654BD5BA6C3BEB0EA
+:102D3000FC010BDB0BD5FA1ABE3E812FCA35D9E850
+:102D40000ACBD5AEEFB3B947B11B493AC8F4A69345
+:102D5000A2EB5CDF7EB9528DB0275CCF6AF26FFBCD
+:102D6000053F403F944C7EB9334961F23504B99E2A
+:102D7000759DBCC5F72FE7FB3606F6FE11F7CBFCB9
+:102D80003574FF72BA05184FBEF25750FF910C9977
+:102D9000F9A9473EA8CA8288F783C4EB719F6128CE
+:102DA00099D5C327744C3EDF89E1E48956F283CD7F
+:102DB000F3ED79E4DFB87F389261D948FCF6D37B34
+:102DC000C786E75998C4E33CD07A53289B7991CFC2
+:102DD0002BD6BB0596321CB6089E75897C14EBA6D3
+:102DE00033648FB175D3F5F2DD88FA8D3D7F79AE0E
+:102DF00072F247C883C2637A3FD5EBFBCE723FD1F4
+:102E0000D0B9E1775407FBCE9B80FCC4235D1BB295
+:102E1000280E83D73B95F2BBCB5D0F4E65FB97D257
+:102E20001626979FE44BA1BCE97432E543B59DA7F4
+:102E300093595C6F9FFE02E5499817DD41D7315FDA
+:102E400061FC2BEC2966FCDB77BC3829930407B7BF
+:102E500085E6AD3DA6AF247C6A8F15BF5741F94B7F
+:102E60004F19CB93B4BCA888EA71CA938E4D8CCA13
+:102E700093FA057E8307E2D8FE8704199C3F303120
+:102E80008A3F356DEFB07CA2A643F644F2E8DA73D0
+:102E90002E3DE38DC1A5B0F91A029287F1632F6F21
+:102EA0006B3AF6B1F5551B024CDF0D2D067EBF9532
+:102EB000B7004DEC793F38FD84C77B7409F5506E3F
+:102EC0005427D0FEFABBE9BCBE88D5C77617DF4FC2
+:102ED00078F79CF766E2CBBB73BD59F651E2861FCB
+:102EE000CA78DD2D09BCDB0C2CAF8C1DB7CDC5F726
+:102EF0007B6C491075DEA8B5F52ECE9F7223DFA737
+:102F00008ABD7FAB8BD7CDF8EF191DF2E26485C186
+:102F1000FEB4A827C6A1BFBD4BF8DB65771A58DE03
+:102F200071529C33DDA5F9DD121EBFB5FDFE253BB8
+:102F3000E1492CFFE14BC863E7604B3CD17EEF6E6B
+:102F4000915F2D5B14735DE453777F4F3E35C3254E
+:102F5000FCE16498CCEB06AB85F645BFEC36D86552
+:102F600026B73AB1327FE43A357F73449C0F75A39C
+:102F70001FA4B621E743B64FF5EE8173BF71303F12
+:102F80001A07197CDF91EDD7D75E67BFBEE19A9D26
+:102F9000FE308A779A9EFA29CFCF1BA9A7A502EF08
+:102FA0005AF325233BB7844DDB7572F89CD264F04D
+:102FB0007A52711D868EB9213ABF6CC831B17CA995
+:102FC000FF7649257F8F72A69922FC7DFF389E7F70
+:102FD0003DB25C62FBC207723E6471BC36D46B24A6
+:102FE0005E4D6E5BF324B35F3F9CA27A49D3E762E8
+:102FF000338F9FD7F4A8AD976E2AB43EA79FFB6589
+:10300000176B693CC5CBBB447C5C5C12ADBF2CE844
+:103010005D40FB23F77824962F5D4FEF4B574C7B99
+:1030200087DCDF8DEAFF9F5CDE875D64EFBDC3CB8D
+:10303000697FF7DD9C4FD328BED65D87CF7E81AFF9
+:10304000CFC2CFC57C167E1EE6CE521AFB101FBD26
+:10305000C3BBD945FB4FBABFD8A600CDD3F7AB7AD7
+:1030600089F4030CFFEBD9D13631EF36979DDB8B1A
+:103070008B9F0FC5519FECD9A04E203F0179377629
+:10308000CED7B0FF6801E969E0C0B10263843E2F8A
+:10309000D5A33FA0F8D2792859B146F24D27F8A61A
+:1030A00067AD242D1571339A7F97887FA4FFBD8764
+:1030B000EEA2BAB0BF6D994B5222E26AFB49DBA483
+:1030C0008879FB83321B8FF5D8E4BB1322E57C9211
+:1030D000C9D91FE0F301F44D5E961F79BF919F1B84
+:1030E00099FB188F9FCADEC4CEDD351EEB81F3B885
+:1030F000AE6309B03825D61D30E20FAA33BA4C2A88
+:103100009D53D07EBB23C24E8E0A9C67627140FCE9
+:103110009C057E99E69D8933DE4B7D3D84E84C6EAF
+:103120003684647EDE3D0188D73304AF67EA430707
+:10313000A402368E9D4B95422F1B772B0CB1D603E4
+:10314000763DB565E0666D89397407B993BC4080FA
+:103150007D97144AD63B2E98D951298CA6BFF0FAF8
+:10316000F57041E3290EC6A487EDE3C78E1B1676E2
+:10317000EFA6DA82F4DC0F6C1FEE16E893E925B3B4
+:10318000F5B088BE27BB450FE6789477EF611DB395
+:10319000E7AE3E45257FE64E12CF7D86CF617FA606
+:1031A00087DB2D8520FA6E455B6F2C0EA5381FED51
+:1031B0000BCED463E5CB700CB1F7DD4682E3BAE702
+:1031C00082A2A7FE1F5DE9623F85D769F3449DA6F1
+:1031D00033FB191E7F12F191CE736C384F69930443
+:1031E00067E97C2693AF579BBF14B3C1C4421ACF83
+:1031F000E31B6D859F75F2731E1B3B9F9B6F27BC66
+:10320000A450B2EEAAE5C6711D4C0626B7EDFEA18C
+:1032100081C78BC3E75DEEE0D1B3F45D8EE4F1B01E
+:10322000EF7ADC666B88F27364C7A5C8BCFBAA6B37
+:10323000ED5FC9DE25C5CEF0022F28947F8C0D7F6F
+:10324000EF025793C2DFD3108C1793C3E7FBDAF773
+:1032500035BBD5A58A0EF5B2C26576935E0ACD69F7
+:1032600045540F36DBBD7F75B1EF6C5A26B1C9F4FA
+:10327000EAF4CA8430DF2DE02921BCB5737D49E82A
+:10328000EF7AE7F664ABC4730BBA7DFA2EE819B493
+:1032900017B373B4EF8FF8793E5AA142DF1DC11303
+:1032A000F314FA2E609BC3EC7E5AA2141FD7670951
+:1032B000AFAFD1CCBF276834F3EF0260EB74B67FB9
+:1032C000F690388F68B4EAB2A9DE6A84783795F44C
+:1032D0009ABC0F25703E3EF4DF16763E1A2BF7D7C8
+:1032E000F1DE9C31D3C3F23F2ABBCF62EE1385E7F8
+:1032F0001C0D4F5D18CF156A46639FC2F09B46CFE9
+:103300004F33A937D1BEC82A13FF7E49C30D15CA52
+:10331000486D17FAD0F0B393BE691D1ED4B7C69797
+:103320008C307ECFC473DC0CF4E544267B56217FC1
+:103330001D8BCBFF01AF6B7F8EF0290000000000DA
+:1033400000000000000000001F8B080000000000CB
+:10335000000BFBCACFC0F0A31E8143D1F8E8389D13
+:103360000F534C941182D7B3E0D78B0D5B3122D829
+:10337000FEDC0C0CCA9C0C0C2A40DC07C4FD40FC93
+:103380001E880DB818180C81380DC84E07627B20B6
+:1033900076E386E869666760E806E2C9403C9B9D83
+:1033A00074FB39241918A6C822F84F806C4505D241
+:1033B000CD19C54313F31BA1F235B451F9C1BAC0FD
+:1033C000F481A446539B34F34F01F59E36C22DAFD2
+:1033D0006E8ECA97B344E52F3343E55F7487D00000
+:1033E00093DDE134B803000000000000000000009D
+:1033F0001F8B080000000000000BC57D0D7C54C52C
+:10340000B5F8DCBB77EF7E6F361F840D24E1260410
+:103410001230C125060C56DA4D0405451A502BA86A
+:103420004F970009C857502A69C57F2E49080102E5
+:103430002C186B50C4E553ACD006053F5EAD5D1053
+:103440002DFA7C362A2AEDB318104129D014A56C28
+:10345000DFD3F29F73666EF6DECD6EC0E7FBBF7FF3
+:10346000FAABC3DC993B77E67CCF39676665D14C14
+:10347000D206107209FE7E44C81813216444B42495
+:1034800015AA404612F2532BC13FAD5F6CD9584785
+:1034900048D842486426211D4EDA51AAB192425AB8
+:1034A000DE7EB348D2094982F715429A849A4303D3
+:1034B0004B0851B344B29D3E5A9E393929E04C3CE9
+:1034C000EE2E3EEEAFEAAC58B6D779B07CBECE8BCE
+:1034D000E5DE3A8584F30979B1AE00CB97EB7CF851
+:1034E000FC5FEB4AB17CB5CE8FE56B75E3B00CD7D2
+:1034F000556079A06E0A9607EB02F8DE9B75B3B0B3
+:103500003C545783CFDFAEABC5F29D3A159FBF5BEE
+:10351000D78C65475D10CBF7EBDAB03C5C17C27E09
+:103520001FD5EDC4F2485D3B3EFF53DDCB587E52C4
+:1035300017C6F24E924C481F42EEB8E382751A5DF0
+:103540006FFE538BDE1F9F46C8DA11A20FC095FF96
+:10355000D4096FA030BAEEB5DF9AA6B4C781CB4FBD
+:103560008880E3AC75116C5FBBFF8F44292264CD6A
+:10357000884EAF4AEBE3F977866C3F6C9D5618EDA9
+:10358000173BCEE7C4C4C631D376DA6FF006D65FF8
+:103590006B1F0FDF19116DDFD1F6BE75BA53DFCE89
+:1035A000DE7F66E3FB56C0DFEA8844C28877951069
+:1035B0005ADA95AEB63E14CFB6231662C9A1F857B3
+:1035C000DA49271D67CDA85F84C5125837EDA6C01C
+:1035D0003A3F20028583EA22480F0A8C716DF43B42
+:1035E000D71211E791FFD461F69DDB2F60F9DA3F26
+:1035F0006442E87B6BEE10420E3AFE9AD1E7BD7E44
+:10360000A037F55913D01B92AB02FFE9F456D0B1A5
+:10361000D78EFEC8AB5238ADFEF68329D381FE8625
+:10362000131F7C6FF5FE578802ED455D08BF06BE8F
+:10363000EED553A70DF01426A64B4A49442CA5CB32
+:1036400075127F280E7CFF058040E163F284704D87
+:1036500076DA2F1E1EFE85C8D86FB5ABE243808B8D
+:103660007A87D9B79DCEFB065F989C7446E70DF527
+:10367000CF68DDF97598985C30EF2FBD26BA7E478C
+:10368000A97C8D8DCEC6D9D57504DE775E5FE587C2
+:10369000B5AF19DEE9ADA2FDAD051DB85EE223BEF2
+:1036A00041745C7B814AA617021C4C88D7D8F94C20
+:1036B0000778F7013CFDDD0B38D1E8F0C3DB3FB004
+:1036C00056EAFA3FA3D187C0E88BB484AD935CD1AE
+:1036D000F6A7B4761BA31F6235B66F88A1639299D3
+:1036E000A0DD4C018DF81243DB0584BB757251CF10
+:1036F00079B784DF423E70FAC2D6409C75513EB124
+:1037000082DC492A117D00AF35A329BF1446D77941
+:1037100039BE6BE670595D32D905E35F4E6E15B563
+:103720008B245CC06526FDFFD52FDBE9CCA3F5E13A
+:10373000E11443FD9A43FD0CFD4774E41ADAAF3DF2
+:1037400032D4D03EAAB3D850FFC117D719FA8FEEA2
+:103750002A37D47F14B9D9D0BF8CDC66A8DF60BD0E
+:10376000DBD07FAC67BAA1FD26EF1C43FB78E541B7
+:1037700043FD9682870DFD6FF53518DA7F5CBACA76
+:10378000D03EC9FFA8A17EDBB8270DFDEFA8D86AFF
+:1037900068BF73CA7386F6A981170CF579F6C05114
+:1037A000C0CFDDB37E6378EF5F6A5E37D43F2464B9
+:1037B0005C3CFC1281C9194A419E9357F1FE54C4E6
+:1037C0007980E6808EFB303A2DD89C404EF2F66729
+:1037D000B7BD6F9D6990936646C719AC7D67E8FDDC
+:1037E000F8EF67713E211DD6C92E7D3B9BD755FF53
+:1037F000A0F215DA25F53BC95797C787FD35B94AB9
+:10380000E99B90EB287CD5FEAA8ADFA3E351796976
+:10381000624B26B584C929421EC4E79ADE27992443
+:103820006CA2E336B83237AF0498D0B1A534A817EC
+:103830006E81BAA8F849671CB89A3CB2014FB1F042
+:1038400025CE144ACCBDC95915E1A78E2505127C99
+:103850005FB0FB96D2F54A24D04FA0CF2F8A012F1C
+:103860004C7EB149FD7D2027DA7FE968FA4FE87F79
+:103870004C08D5637F05E1D85044FCA037D40C39FF
+:10388000B43D07E1690179A2BD471F289D6CBEEADE
+:10389000A581863A9BEF65EBDFE41BEBDAB83F3797
+:1038A000C293C219EAF7F14A8F75FBE428DD9AA0AA
+:1038B0001FAB2BA2402EA11C34B66BDFB968730F6F
+:1038C0002349148F56562EB6BBB74079D1961D2288
+:1038D0006E420AC54039C04D2D67F0518F3A420DF6
+:1038E000385ECDB5154500DFF8F60221F58C3F3E78
+:1038F000192FEAD791086F0D60B7E5EBE820D38761
+:10390000729CAE1AF55B6CFF3B05998DEFA4A8A2E3
+:10391000E35B08A3B12453E04E6104ACB68248389F
+:103920004F1FA9407C8D2360975A3578066762DD6A
+:10393000C9EDCCFDAE91470214CFABFDB20FC6AAC4
+:1039400014148E079F17F480A554242B696DB5F2CB
+:10395000BE15F8A33947CE00B96E916A8887D62D77
+:1039600079940FE2E89105DD72E211722576712CEF
+:103970009E0AE8EB6C1E04E1A8CD3F98D561CD0509
+:10398000BA1C4DED623AD5B5D7F7AE5F9671F8AE79
+:1039900002BB98966B94C94904F9964C05FA6ECE11
+:1039A0004917914F399CBAE192F39115F874057F4C
+:1039B0007FB5EF7DB4D357687A3C068ECDC38F2395
+:1039C0007CA6094C1FAF2AB24F09C581CB34C18DEB
+:1039D000EDCDC05369685F31FE8AA117DAE2ADA46C
+:1039E000ED56C553BC928E3FA6489A0A74E12A252B
+:1039F0008A05F9D7EFCCA0DFB7F3DE92221AE4876D
+:103A00002B8DD1ADF51321A4D0FE4E2FFB9EC549C1
+:103A1000427E7C7FA1012FF6D2C004328CDA49FFAE
+:103A200030E17B748ECC8E383C1EF9D1EC61EB24F6
+:103A3000050C4F1EFABF4BB9743C4536E88DA565A1
+:103A4000B22F4CBFB3D8ED447A32EBF14ABFEBF85A
+:103A5000F6850A187F79E603F6A574FC8B654DCBD5
+:103A6000812D4D9F8CFF12F8CE14DB3F6BF21F06A9
+:103A7000C6E103AD7474BA49381506B8A7573A7051
+:103A80007FB2F9ED83BA79BE2AB8D250BE5E4BAE92
+:103A900045B97099F72FD685DE3E3808E1215E09D9
+:103AA0003D2F8BE1EBA61C4D6FA9DE493ABBEC82A2
+:103AB000C0F41A51CB10CE12E7E7A6D1A40BECD676
+:103AC0003539B2524FBB48A572184807FEBAE8F71D
+:103AD000C1362320AF95A60EF6FCA706B9B9A2EF12
+:103AE000445FB817B8497931FAE632EBAF05F8E927
+:103AF000FA9F00F839A2F0B3908AA430D04B709CA2
+:103B0000611FBBBCEC21254CFFB9BCDF2FFCC78873
+:103B10000E8E3FA27CA8E30F4B6688E8BFAFC9C5F5
+:103B2000DB447F17C86193EC4339457265DC8FC471
+:103B3000CEAF4064F2260A67AB4474FC4126841081
+:103B4000EEF4AFC29ACEE147FF6CDE37FF01F0A37F
+:103B50003A3AEC1886CF1BA5623A9F34A23AAEA639
+:103B6000EF4B44827A9698837C4BDBC7C829C0BF51
+:103B700037FA400E36F17D1FF16CF6EAEDF22C912A
+:103B8000E135DA1EF2DE616867F64E9366D77BB6E2
+:103B90001AE8A2FBFD641277FFD14764767696E8B7
+:103BA000E1F4B315F76F2BD22644000DB68C1B7DC4
+:103BB00095C0AF1E8270D0F484A617A8BEC812FBB1
+:103BC00044C793F32A8880ED46FD9B505EC7E85DAD
+:103BD0005B81510E10BD3D930BFFCDF420BD90587D
+:103BE0007DCFCB8A9BAF88AF7AE84B127FBF384935
+:103BF000647298A869B87E8DAF08B727CC1A5D109B
+:103C000046AF6EFE5D19E63310F01CC2C11D745B39
+:103C1000057517A9C1FA85D2E230C0C922753613DD
+:103C2000AE1FD59C38FB28EE8749B48EB5A3E3EBD5
+:103C30008732D18DF834396B4800E9F81EB403059A
+:103C400035402EA13D18E47AD5E7053C2EAFAB25D3
+:103C50009FD1C5D80F8CC7FDB994E9F7C3FEDE0428
+:103C6000449041FFEF2C61A5E453F4F4D98D47B2A1
+:103C700014C73353B0C03ACD4EEB34D00366A767B8
+:103C800012960543670A5026DD582B225BC5A727ED
+:103C90006D3C4A57B344182F2D80FC2C792AB02450
+:103CA000CE34B45F697FA522EE3C381DF07E09E971
+:103CB000AE9B6E343828328C174B4F361FDD308860
+:103CC00058ED80F9A6F3F9A6DFD3B41040EC24AA8E
+:103CD000753085517AE734D47B4EAE7F1A0B8A9BC0
+:103CE000CB693F772149BE9196B6BC2E9C3FEE6BC7
+:103CF000FBC178772F2D43FF07C17A637D4519DB20
+:103D00001FF863EC565191343ACBEDD5DE112E59A4
+:103D10007ABE9F68FDB1FA949007AECCBE9AC2F805
+:103D200051A5FF037EF4101D7FD271DCD71BF581F6
+:103D300033E63BBF025822BC17FEAF7C2F89D45B11
+:103D4000154A0A6645F484289E286A92611F65F325
+:103D5000D3FD1DB4A775FA45E5F27869847D6C2121
+:103D6000A3173DFDBFCEE56BDF7B171D5B46C7BDCF
+:103D7000E073FAA0573A15A7A9C53DD7B33246EE6E
+:103D8000AC2C588F74D140E92817F6070522EAA514
+:103D900066658B47EF57F95C93433DE88328D2482B
+:103DA000BE9FA4F03129A2DFE6FEFEF4116B3F5D59
+:103DB000297DD8A718F1F15DF175FE3BD2C7F7FD5B
+:103DC0009E86D744F28CE215EDF1CBF99F7AE2B5ED
+:103DD0001EE5AE4D89EFAFBCD88D4FB56769F0A732
+:103DE0001AFD02D6BB9BDAE2D92D5A69BD2776FFB0
+:103DF000CFC6B5D59A941360DF4A1EC33E6885B21C
+:103E00005E057BFE02D8E5601F06CBD03F4CF298E2
+:103E1000BF160610815F147F88ED6F4244AF07E53F
+:103E20004CA3DFCD946637EAEF29AAA09FBFAD5619
+:103E3000C67958E17B69E8CF0DC1774D1E12B6B93E
+:103E4000A3F40A9F62FE8087AF880E347A05339808
+:103E5000D1ABF1BDE599C5241EFE7A7CEF76E37CFB
+:103E600013CAA5D8F79C92725267A7247E4F2227C7
+:103E700075F64EB916F7E178A276DECB42129507B9
+:103E8000DE9F9000856F133465807C22A8CF9ABC9A
+:103E9000C52817C84E2166DFAE30FA5152B0BF6850
+:103EA000657A53AB279E0FFB6E348EA4E0BE36516D
+:103EB000FF86BAD2C724AA8C1CB5AFB74A148F8D1F
+:103EC0004BFD532A707F7BA8551A14ED37CFA4ED14
+:103ED000DBA9FA1C19A56789D07E0837915CBA0660
+:103EE0001E7A883212A0C9E99B74603B7DCAF148F2
+:103EF00084EEFD0C1DB20DD689FE8923D80F06BABB
+:103F000084FEA64E56A72F427D95D9EFC779494129
+:103F1000EB03145EAB6CBCAEF07A32AF7B783D87BE
+:103F2000D7C97AAC3B645A07FE35073D58B7F37AD8
+:103F30000EAFA7F07A32AFE7F2BAB01EEBAB643641
+:103F4000DE4A29C4C6B7F3BAC2EB29BCEEE1F55C80
+:103F50005E275BD8F72DAC6E3787D8F80E5ECFE1C1
+:103F6000F5545E4FE6F581BC2E6CC17A42799947D3
+:103F7000E16F900F1DD13A2A110ED7EE7A674C3BB4
+:103F8000A3975481703B2C940176D3FED9BFC8000F
+:103F90007FE88663D77A613FD670AB464F3E949FE9
+:103FA00024F3169463197CAC86195BD00FD1304B87
+:103FB000C6FD27E1FE99687BF12185B65F08883E42
+:103FC000A09B2792E3FBC97E51C7E295ADDC4E5E14
+:103FD000C7E3956B215E09FE161EAF5C05F14A0B27
+:103FE000D0A90FEBCB215E990FFB6B16AF6C8078DD
+:103FF00025AD3F07F14A5A3E0BF14A5A3EC3E395BD
+:10400000DB79BC722BC42B69B919E295B47C9AC7D1
+:104010002B9FE2F1CA2779BCB26D46F15B7930FF84
+:10402000B96CFE89F0D1778A517EF6A930C62D523F
+:10403000C6A418DA3DD71BE316EE925C43DD59683F
+:104040008C5BD8F38A0DE35933AF33B4CB69E58683
+:10405000BAE434C62D0A774D36D4876EBBCB502FC9
+:10406000D85869187F70EBFD86F6BC96070CEDB941
+:104070008D3F37D49525F586FE4F9A7291BEB217C3
+:10408000AD34F4CB9CBBDED06F9EDD7FDA04F26EE4
+:1040900042DA15C937F2B59AAE9797B1FAC1944D85
+:1040A000FC7ED4734C1FA18F16FC6A59CC7F65FD32
+:1040B000E4A643B07FB1E4313D15EBAF8A1D4F76E6
+:1040C000EE38A2D2EF94B90F793B75FC48BCBAF731
+:1040D000E85293242627573EC2F6E72D8FC4DFA768
+:1040E000A326A0EB68F9363E1FB82493418F68FBE6
+:1040F0009A964704ECFF7DC7D7DA63C78D7E8FD2CF
+:10410000DE48FD7E38C4E7437584CE5E3077264FA7
+:1041100027A8E7D97ED9C4FD3B65134B8F35527E66
+:1041200059E6213E0BAD2F7396FB995D42AD73C0EE
+:10413000C5925B715FAFF5D7E6D5E89CCCE40BD1B7
+:10414000F92D514ED90D7E856569BDDB6F72C48432
+:10415000FE3F53442061AA9764A9625C0E9D8F7C48
+:10416000D8E45B4A503FC5F50F10B29EC59DBD46D1
+:10417000BF69E38C18F9C7F332CC7CFE0D69E5F812
+:10418000BCD1D3FBBC2C302F980F9F9739E2C0D203
+:1041900014B1E17C474552B15E1A49C6F2DA487F54
+:1041A0002C474632B01C11198865492407CB6B2275
+:1041B00057E17BC59121580E8F5C83CF7D91E158EB
+:1041C0005E1DF9013E1F1619856551E4067C5E18D7
+:1041D00029C3F2AAC82DF87C68643C964322B7E153
+:1041E000F382C8242CF323776339383215CB4191FD
+:1041F000E958E645A66139303207DFCB8DCCC632AF
+:1042000027F2203E57220BB11C107918CBECC8CFF7
+:10421000B0CC8A34609919598A65FFC82A7CAF5F8F
+:10422000640596199147F1B937B20ECBF4C8062C44
+:1042300093235BB1DD13D98C6552E4397CEE8E3C5F
+:104240008BA52BF2023E7746F660E988FC069FDBE1
+:1042500023AF60698BBC8ECFAD91FD585E0E4F973A
+:10426000B3834B4F18E3CF233F31CAF192C3C6F853
+:1042700073F13B4639EE3B688C3F0F7BD5187F2EA0
+:10428000DC6B8C3F0FDD6594E305DB8C727CF0C644
+:10429000BB0CFDF35A2B0DEDB92DF71BE574A351A3
+:1042A0008E672FF9B9A17FE6A27A437BBFB92B0DA8
+:1042B000EDDE1946F99D4E9E30ECD33C63B618F501
+:1042C000DAF5BF34EEDB4A9E8FD9D78450BED80BC7
+:1042D000FFD5F09E35EF408C5C56997C8AF1B70390
+:1042E0004820BEB998D87DB0AF89C5670A9707A99D
+:1042F000C077B44CE37CD707F88E9629B7CCF5028B
+:104300003DA44E2C9D0676CCC5638202BE3261620E
+:104310006D3EC47B52FA138CFB1275C80D7E5A6F2A
+:10432000CAE075FA44807A1661FE06B2B41CFC6CD1
+:104330004D39ACFE56E39272C88B6932F376B5B153
+:104340001CDFB7B1FA91C619F5D09E92E4EBE7A352
+:10435000EF6D35C797D79F4A2CBED75FF2FF41A2BA
+:10436000EBFF6B59E743E097FB776BE003893E9FD8
+:104370006B0D0C80D0DA5973E019501DB982FF30F3
+:10438000F42B12FC1F4A28B78D7ED609A038E9F31A
+:104390001CC9FF4768D7D6DFE4EA7D1EEF72BDD4A3
+:1043A000944C709FA93E26F3BC1282FA52F36B3DE7
+:1043B000EE70A3BC5FFE98BC05E252E6CCF4E9E0E7
+:1043C0004F833F83FE686D5A087E762BE8A18120DB
+:1043D000E5DBB174920E2CDDA40B4B0F64120C8C38
+:1043E000AEBB7BBD596CBD140E5F4BB88FA8C1FE30
+:1043F000F58E89A5B01E0A870B1C0E7F97FA2486BE
+:1044000003FDABF08E642E51B4277609067F6692C9
+:104410002940CC3C8E0ACE998C193EDC8FFD49F2A6
+:10442000203D6AF0A37F8B524646F301E87B56732A
+:104430009F9EE369E320C0E0FB5C1F6AF45C9B4045
+:104440003F697E6EA2DEFA9DE24DBF97C5B8DF31AF
+:10445000493E8CD7C6BE27398DF2CFEC0C601E8446
+:104460002CC58FEBCA161EAFDA38F18AE2DB3BB8F7
+:104470009D4F1A6FBDA2FE5BB475534A80FE591A58
+:10448000D76FBC15E96E107F3F0BEC3A4A4FAFFF78
+:10449000B9BABE05E80F62D2F1FC07AD22DA835942
+:1044A0000BA9E0C989C23BB390DA83C3A2DFCD5C1C
+:1044B00064F4BF8465165F21AD57067F2DAF338B43
+:1044C00012FCBFA6F49C07D93691AD87C751A50D44
+:1044D00015CD362A7F0639593DB3B5F7F9101EB709
+:1044E000C8E47495E9E47E979DC6717B7CD7F4CED1
+:1044F000F078795E09BFF31DE38033CDF1E3A814B2
+:104500005F88EF81DA3C6AE91F9DD7603E7F6D3C92
+:104510002D1EA8D5293EAD607737B554A29DD5E4B0
+:1045200065FA9B7C43471F892C4FE2EDCB421CFE72
+:104530009BF87E32A49663FE23D965A45365A964D3
+:104540000FA0FD26A640B9B991F5CB59966607385C
+:10455000357A5252A0DC542BD6DB28DD34AAC40FA6
+:10456000CBCAFED9091B6B3F9E0C654E5BD75BF92E
+:10457000147F391ED127D1F964A8E7DFBA09CA161A
+:10458000BF3507FC704B24CC23CC6E23F602DA2F08
+:104590007B2EC17E0444209DCF931A1ED556611CEC
+:1045A000FD67664BD7521BBE47FC8374FD3670F027
+:1045B000E5353E50066C9AD7E2993C0EE2F385C48D
+:1045C000378844FB3DCEC773403B8C3386E5316A68
+:1045D000EDEB78BBA5F6BC9A0F654BE7BA9BA05FE5
+:1045E000AB719CB5BCDF20ADBDC4D8BE5A23AB2592
+:1045F000CF87611C534BD77B37C17CDA58BF6EB96C
+:10460000C5FBAFE2FD63E5C560788FFB2BF5F35C7E
+:1046100011835F4D7E84C03F900FF865FE018B755E
+:10462000EB53E08FD4FA2D17D8FE4889C9337DC5E6
+:10463000CCE46197CCFCB61A3D25A26F3257B71F68
+:1046400080B8E50CBBB17E4F8A611F48C6F433B613
+:104650005F9F6B6C2F196AAC17161BEB79D719EAA1
+:1046600017BBFD2F411BE68573FFCB60FE8D0D6DE3
+:1046700095988712F5FBF9EDFA7D4A26EFB7ADA6BE
+:1046800018F9A7C1C9F987FB691CBCBDA9B0D2AE96
+:104690008FBF6BFCD30C7E100BF85958DEF68EB62C
+:1046A000DEE1B589E37B23CFAF7982E3A98DE3E92E
+:1046B00017DC8F13E47E9C353CEFBC85E79DAFE4AF
+:1046C0007E9C469E77FE02F7E3ECE17E9C6DDC8FDC
+:1046D000F36BEEC7D9CDF3CE9FE37E9C15C3BBA68B
+:1046E00082FFEC59EECF7986FB73C670F9BD62ACE0
+:1046F000AF1FF8F7B68E8DBF7F1EC3E9E2C7E0C8D3
+:10470000EC037ADB536F06BAF4B13CEB9C5A8F682A
+:1047100029013B97D165CE2C8F2897809DCBEA93BA
+:10472000B8BE05BD827933993C6F26936A9D74EEBD
+:10473000FF85AEAA4AC01FDF778A6738B842DD32EC
+:10474000D7A30AF1EAE3067DD58000712DC9E44FB5
+:104750009247C0F86C5EF9C1AE0390A7E8EBE82879
+:1047600007740E3BD45E0FFD0A0B83109120E6B454
+:104770009008726945990FFD6F4F7F68F26D813126
+:10478000D388812EE81C519FE5F1FD2CB9DE481736
+:1047900096C826B49B9B6A587E06ED1377FFAE95AC
+:1047A000C97EA3FD90546AF483350527F7EA97F68E
+:1047B000BD6A7C7FD85EE3FEABA9D09827125B165A
+:1047C000EE1263FC5C31EF3B7BFF7E7E6422AE37F2
+:1047D000119DDF66AA2C97757912CEC80F711F1133
+:1047E0006B0F4A60E70DC4BC1A3FD8BF529EC70F7B
+:1047F000FE12294FE1A58F3FF7F37A05D6A9DDF820
+:1048000063189FE2C560379A480063222B8610BE6A
+:104810001FF967BD9F2AFF157710DC4F789AEC3798
+:10482000A84083FE99881F99E32755AE7906FC1F9F
+:104830004FAF1609E07F6B4BEFFCDB239FC2E9C74C
+:104840003852D6224F31E8BD44EFB52E12C7C58B82
+:104850008FCDE774BD6CD1640FEA8D8397CD179827
+:104860000FEBD7F205FADCCEF305CE8C37F8955373
+:10487000AB7AC7E3062EBFB47A06896FBFEEE1FCC0
+:104880004E9C2CDF44A3FBD461BD8FDF7D6E2724BB
+:10489000920EE00B2980F2B3CFED01CC8B27145F91
+:1048A0007A3E69FA76FADBC087EA3A96A748FB892E
+:1048B0007A3B4C9B4786275C2640FFFDA3307F63F5
+:1048C000B0332042DCBA693FE1DF69477BDC31A3CA
+:1048D000C6CFFC65ED04FCF68E1A9F0ADF077C61EB
+:1048E0001E5246777FD40FAB8222A67E349430BB13
+:1048F0005793FF1A9D34788B0F417CFD4289847158
+:104900006F6A5F5DBAA4ED67E87F06B7313A68EA7F
+:1049100043F0DC8D54A086811E897F1CC20DC81F08
+:10492000FE9A5C3FF1E3B99422A6FF4D70DE03FAD4
+:10493000491D7ECC830E787C90BF98D5360CF94CFF
+:10494000F2D40880DF87C4C06E3D5F999C2CFFAB1A
+:1049500029C1B982162E67FB25C0EB87BC3D55EEF9
+:10496000180F72F8E9C728FDC7C9CBF903D70B4F59
+:10497000B54EFE438112E55FADFD4F60A4E9E695BB
+:104980001591597E61DB77DB078C35139E7F647C44
+:10499000CF2C5518F6615966E3F7E434A33FF2CA09
+:1049A000E729A15C2285371BF09CDAAF77F9A9F1E2
+:1049B000FFC5AC18BB23AF00E9396A7794233D6C7F
+:1049C000F412462F9C9E343DE2EAF4ABE2C09EF422
+:1049D000B13178C00676B246671667C80F7E038786
+:1049E000378CE9823A7AF82BD04356DB4884B7AB50
+:1049F00044C5E7FBB8FECBADED2AF3C7598766DFA8
+:104A0000C1BECB5B0C5F88D9FF908A20D8D559599D
+:104A100010C303B5CCFC0B999997DB6F5D59FC5A19
+:104A20008B2767D33FD8FFBCA2E1FD8B18BF9587CA
+:104A3000AA785D3CB5EF17D30531A7271E62DF6B5F
+:104A4000F4947BE2C96FC91448B7E8F01FBB8F8F9D
+:104A5000DD6F13BE7F94BBAB8B500E5B268CC3F80F
+:104A600048F7BE7BE3445CB785E34F6ED1E2FBB110
+:104A7000FBCAB9BEDEFDAADF6F5FE9B318F34BAF27
+:104A8000383FF73BFA25B672BB35767F113B8ED89F
+:104A90001610E39DDBC86F33C23DAFC568FF0CE362
+:104AA000FC9DA31AFDC8036AFBC5F777F27CB5CA63
+:104AB000520D4FCA9DFF41E977F62133E6E16BFBCA
+:104AC00060CDEF349BE7AD55F23CB619A4C20D8D15
+:104AD000678988E777CE92F7DDD7E8F8A6CAC2CE15
+:104AE000D19166F371387FA1E567CD0CB2BA369FDC
+:104AF000EA3663BD8A4C4E07BF6B55AB99403ED634
+:104B00006C221DEFD4E64FE9F8271696875A4D6AB6
+:104B10009A40BE2DE379AF951E22A5A61032EFA5CF
+:104B2000A746C2799E7916267F4F53F82B3A7D7D92
+:104B3000BF3324037F7FB6F79A9FFC80C0FBA1A6FA
+:104B40007EA03F93E39F8398DE6C9CDFE5E61F3BEE
+:104B50005FED9C46A279483B85B8F93F0F6BFEAFED
+:104B60002B3C47B215826223129F23B9DCFB3B2DFD
+:104B70008C7EFEBBEFEFFE9EEF3F7F99F9CFB376C1
+:104B8000DD8879DE6935152057B57C96F924E00774
+:104B900057BAE9D5496A7F45D7CF7B85FD32693F52
+:104BA000D315F4CBEB7DBC739CCF7FBF6BAB0CFC00
+:104BB0007BF697C726823F70CE6F4CC44AE9E0DC93
+:104BC0002E173F2F169241EFDDBFD7E40F613D3C1A
+:104BD000F2365DBE206616D2F1E7FCDA85FEC4FB34
+:104BE0009FB78426D0F7EF7FF1B36184C2E15C7D8B
+:104BF000D79BFDC10EFAA5C0F2AFD4CE61B7D1E705
+:104C0000F74BE4BE8A387AAB83F3C199571C5380C3
+:104C1000CE849DFBEFC571DBEF345B74718DDF5B80
+:104C2000CC087FDA8F9DC77A56080D12D8FCF4F9AC
+:104C3000E25ADEDB99670536BF97CD211BCC6FE7C3
+:104C4000663940FB2DD8F937A4EB1B7EBDDB0D7018
+:104C500058F0B2C9207F16EC34852DC3B03C6641B4
+:104C6000FFBDDF298C047812D457F3F7CE9B00F4F4
+:104C700030BF7DD5DF4C6E78DFC85F142E78EE63D1
+:104C8000CEC726DF04A8BFF08C1BECD9D31DDBDD1B
+:104C900000573AEE3499D2D50FBFD6F12161E347E0
+:104CA000527A8E071E1BA0AF05ED2BD8F7F6DE7AE1
+:104CB0000AE4DB82183E3E0DFFC8E8A93F2216A396
+:104CC0005FF202796724D81D64676ADCFCE26EFD3E
+:104CD000C1F97ACEEE0B9BE03CF199E7FFB209EC0B
+:104CE000FBB9FFFC6AD3C3E01778CDE60179B4E0E5
+:104CF000971FBA890EFEA95666CF9F7BF6991D4F66
+:104D0000503E39F7470BDA3BE77E7B2A5BA1EB3F4E
+:104D1000B7E71FE970EE76D16FC7F605782CDA7722
+:104D200043DFDEF61B40B7218B1EBF21C4AFF2323A
+:104D3000FD4E5F020758581983A7D7F7BE9E0DF3A3
+:104D40003C7BC482E76F16D067B5C580B779A81FD2
+:104D5000A0BE84C27BFEAEE57F330D8B0777B5BF67
+:104D600008678548B83FF102DE6FFBF1E81228CDF5
+:104D70003E05C6235D28DF63DF5B7098E2F7EAC477
+:104D8000F8BC40BE9101FE0B76AD60DF6DA7F874F4
+:104D9000F7C4E759F8C7A89EF82CB6C6E273EED35D
+:104DA0004F40E3DED4B879241A3EE7EDBBA357BBEE
+:104DB00041930F9783F32C9E37F54F8BBFDC0A7C12
+:104DC000F6BC43F5323C8726D0B673BB2F64134A3A
+:104DD000275F98BBEE0539D9F55B8B670B7D7EFFAE
+:104DE0006F3F46BE3BB7EF3D5961E74F9C02B52B85
+:104DF000CE91EEBF0EB033E6F3D8DA826DAEB0C519
+:104E00001DC5D7FCD0A4718A1B9F1FC3E721C60F05
+:104E1000F343FB6F17E2E06F893597E9A7501F84D2
+:104E2000CB3CD221C3F97C3D5E8552C0E7B11B81EA
+:104E3000FE12E1535BBF07D67FAD0EAFDB181FC775
+:104E4000F69F4FF915E4700FFC86848FA13CB7D90B
+:104E500022417EE4391E6F8CC57B14FEFCFCE47796
+:104E6000B4171FB226884370385C8EDF2FB7BEEFB1
+:104E70000ABF195605C78D85E3996FE2EB83F55C90
+:104E80007ECC2735E3FAE9F499C54CF5590ED87B69
+:104E9000156A7F213ADFA67613CAF9333B4D21D03C
+:104EA00017B1F2627E827D72C8CAEC97F92FEF1FAC
+:104EB0000672EDCC8157385D32BA9FBFEB98AC7269
+:104EC000FD10D2EB870471CA5FF2F116BC1A7FBCE9
+:104ED00005BBFE1677BCD392FF4E98FFE90E335107
+:104EE000E910A7DB4D71FD49AD56B331CFD635F290
+:104EF00048127DCFE4B62BB0EE867AFFC72AD825BC
+:104F0000EF9BD1CF4224DF17163C6F6D575652B836
+:104F100035B8ABD0AFA28DD7180327C95BA10A253E
+:104F200070FEABA284D9D46CDE5ABBD9231AE64DED
+:104F3000F56E26E8A5A3C34F99619D9FC6D88F9FA4
+:104F40004AA4A92F1DEF5355F02D55E2ED178DE31F
+:104F500007969888A2D78796AEA3301FF23B1B0115
+:104F60003FB2E9359B0AF264C1265B08E29BAFEFD2
+:104F7000BBB803E076EE690B8F77B23CDB6ABE5FAD
+:104F80003BB5EFE2A6FFA2EDA7E065FAFDEA4DB45E
+:104F90003FD8EDBB1C98F4FCD7E79386112AA7AB4A
+:104FA0007FF7F044902FD5B0C7A2FDAB7FDD37D49B
+:104FB00040C73BD987D54FEECE0A015EE6BEF0DB97
+:104FC000F9A04FE6FCCA4180245FDFF7F1BD503FF6
+:104FD000F73B17E67B9DFBDDA91F021F507B5BD1D2
+:104FE000EBF5D9FAF3DE74DC395067EDC2255D1EAE
+:104FF000C11C2829BDCF7939C90FFB715D3F7C6F7A
+:1050000081A5EB21744011B59F887BA2703FE0C35E
+:10501000393B8DDFFBAB95D9530BE4AE2AD63FD895
+:105020008FF16B07BEF78D46A7BC3DF67DADFF7FC8
+:105030005A7363C661EFCFB7909A78F46FB1B171CC
+:10504000E7ECFC36DF381EA3D79EDF61CF7F2AB0A6
+:10505000FC7CB2C786E77FE7CAE1C129945F5F9411
+:10506000C92CE0DBB9EEF0E064FABDDF707939D726
+:105070004EEBF4793F3E0FE80F7562EDFC15E077DB
+:10508000DE4B3602F43EEF772EF42BCF7BF1E2C9F4
+:1050900027E9F333FB1C98C73AEF778B11DFF32C2A
+:1050A000E17BC18FD3B5C782FEB1337BDECA067BFD
+:1050B000E48C399C9DD28B9F685EBB853B2F8CEB2B
+:1050C000A0FB82821A27F839595E4E2D61F70ED463
+:1050D00042E207D0F12736160FE1F1A907B8BFE881
+:1050E000FC0C2509E77FFD2DEC398F5F3F70ABD2BB
+:1050F0003759370FC89B23D7D07D895C930F72D661
+:1051000014B98528B42E450662A9F533C1FD0DE01A
+:105110000F4D2368BF9BD37CA49A968B534800CF36
+:10512000FF386FEEE6B33F50143FB041E90BE3F9AF
+:105130006C4CBECCB3FB47DB306FC478EF82BA8FC8
+:10514000ADEB22BF4F2176BE17CDAA05E479346EB0
+:10515000C7F2066B25E563F0FF92435C2EF5583FDE
+:10516000E3B3F39E14E4336D1DABEA3C284F56D4F1
+:1051700079B15C5E574014CC77F661DDC4E16129FA
+:105180005409F8578107E1CFE2ACF0C37D16302611
+:10519000C4534DCE00D297C55B83BE022B8F8B9A32
+:1051A0009C2AA976429E078393C959817092795DA2
+:1051B0006A9B8070A5EFE3F3B1F6C00CDB08C83F33
+:1051C0001E6A9053725AB1A1DE036E1A5DECFEDFC7
+:1051D000861F4178ADA8B36209F9E20037C8178786
+:1051E000FAFF07F8B530F85D47141DFF40FEB662C0
+:1051F000E0A704F0DB40E19716E5AB5838D4F23C69
+:105200001D8D9F12F12FE4DB4310667D5D1B96DA46
+:10521000F394047AFDAC8DD923B524B014E3A11E18
+:10522000E68721692AC9D4F99F8857C5732078DE9B
+:1052300014DA336F41FFA5865F93473A69947FCABA
+:10524000C7B09EC56F9B459057A6DAADE4335D1C91
+:10525000DF34A1C2A6209C7D02C4351AB87E5DD67B
+:105260008D4F237FACAA53B05CCDF9642DE79375C5
+:1052700080775A6FF0B1FC9F967104F5E763B4CE66
+:10528000F6FB61A2F78B27FBDAC3668A7F94490A93
+:1052900096EC1E8E2396D020FA9EA390603C23F9B4
+:1052A000C8CF42B856D28EE7AD93B57B605ECD4D88
+:1052B0009E8A712062667A8A98581934C33E2A16EB
+:1052C000BE0DBE0378BF44A2F9941D9D2DC0F72EDC
+:1052D0004E65B1B3B47BDA8FC07D10CE16073BA705
+:1052E000E8AB19908DF2D582F4EAF405846A1D1EAC
+:1052F000D313D87F4BECE3FF03E8F113C84BA4F8BA
+:105300005DDF3610F35A5699DBBD200F57F1F31AC3
+:10531000CA140A05DDFD626F7039E92E31CA014DEC
+:105320002E7BAE2F36D0B3267753C618E95E93BBDB
+:10533000BFEE96BB156741EEA64636225FC6F24128
+:1053400083595685ABF13E1AE67F3A26B0FB327A96
+:10535000CA038CBF9FEFCCD902E7B135FE895DBF90
+:10536000D43C1EBFD36D0F26C87FECCFEF6568A677
+:10537000F446F2215F414144ACA174066590D21914
+:10538000E3A7522C353AAE274C86A87B45364FEE24
+:10539000AFD5CEE2D45B8BFD80C765ED8C87B2ECD8
+:1053A0008CCF96A589A0BB8844F7934EFA48DA3F84
+:1053B000CA0AF6A56466F1FC2E97D80EF1DC65CE1C
+:1053C000C956C82B15924B907EFEEEAA1CD05B7C72
+:1053D00007EE5F03FAF3387DE438EDB78CDFEB645A
+:1053E000F21413D897EE7676603E94D32E1AE249E3
+:1053F000F3EC815CBBAE5E045FE77887617727B82A
+:105400001F6A185F0FC954499E4E4E74DF97A4A8B7
+:10541000A440272FEA07DD88F731F5941309E4E16A
+:10542000F6FF1979D83020847835C7CA9F343FDE1B
+:1054300001454B15AE56A0D6F9B2BB87239DDE6061
+:10544000877D88734BB71DF4A3DC9EF38C957F5149
+:10545000BDA6A01F8CEAB5C74B419E26D46B35F77D
+:10546000211DB7F457808EF7AF79F869A87FB6C6CB
+:1054700082F7BE5445561085CEB73A320ACB596DE5
+:105480008F6259D9B6993211214B5757AF990AFDFE
+:105490003798D0FF733274CDB95A5A3FD96241FB65
+:1054A000FDE4C6070780FD77B2C5A198C0DEDF38EE
+:1054B000C2D8DECCEE7F39D9660E9918FD5E324136
+:1054C0003C8270F90E5E20DD7C49898276FCF99879
+:1054D000784BE55A8B5F7027867F655B7C7B12CFAC
+:1054E0006F63726E4D3EC8D7B2A33F1B00F4A1C9D3
+:1054F00099C52954EE01FC8E5A48BCB8C058FBD857
+:105500000580A7B176FF6286AF2BBB37EB3391DA0C
+:10551000DD88A7807B92C1EFCBFCAA9F71BB9C5812
+:1055200013B4BBF9FB9EF8EDF35AFEF2E62304F246
+:10553000548D7E6D13F8AB05D88F4F62790F5A1CCE
+:10554000A8275D337BBAC582726506F74769741E6A
+:10555000A5B3809B9FDB33D0E1ECC83A947BC2AA11
+:10556000A2C74751F87D45E90FE8435835BA2FC027
+:1055700077E9CA1FACBD878EFFF53B267C3E2B62C8
+:10558000C3FE5F3EE27BFC1ED82FFCBB19F349BE75
+:105590003E3416E3C95F9A8D7E8C32079397AF71C4
+:1055A000FEAF8AAC32D8E755CDD365F0835645D6E9
+:1055B000E0F32A0822619EFC5D6F9449105F2298F7
+:1055C000E7F29AFDCEB1F5A84F8BD18F56BDDA1216
+:1055D00037CFFF35BB629057D59D2D382EA1F65998
+:1055E0005A3A1F4F2777AA23A9C81FC4A312C8FF7E
+:1055F000AEE2F2A77B7E1BCD06F9F3A52DBE9FE69A
+:105600005D3B5B6755E407C8773DD7F7437C5EA5F4
+:105610007DB793F169743D8F8F8AB79EE83AAEC724
+:10562000FE5F26C7FFFE050EDF9375B3889FCAAFE6
+:105630004A0BEDE784EF3FD8540AFBFC8DC9298261
+:105640006E5DD56D73885FB7AEEA8DD364FDFD9452
+:10565000513C2C32E0E1C2CA05888725F68A63A056
+:10566000072A578D1E16C07DFE0A84F367665F36D3
+:10567000C8E3536D0FBAE3E5175F88C54F1BC70F2B
+:10568000B5BB4B74F8D1F012FBFEC93F57FFFD11BB
+:1056900090531B5C06B9125BF6C05B4E7CB825715B
+:1056A000FA3C49F57700E1A6BC7804E87AB503F343
+:1056B000E412C3EF2A12E80D7E09EC676A67591DF0
+:1056C00023E0BB04E150DDC6E8E072708B7E97D327
+:1056D0004159FCF58C766874504B54CAB0C7E5CB81
+:1056E000D1C1C344B5F6B28E6E3A687BA32C2F4A63
+:1056F00007A31DC1B1F5B4DF1760FFE4F7C4FF7164
+:1057000059755F07F6CE4A13C6BD8EDBD5F4BB587C
+:105710007D38C8E7E3EEE0C4EB4AA2F5D9DB07B970
+:10572000F5F73A9E6AA6708803BFD18E04F493A75A
+:1057300092C291FFEFE8E73373FC3CD1B1F6B2328D
+:10574000C02709C6F7276BA526BF4D49CEEE7D2F92
+:10575000E8D1E3CEDCBF8768EB1A7BE056076D6FBC
+:105760004C7E08F5FCF1E302EAE1A57F5E9C0F7236
+:10577000B887FD5B1779E2C420F45B3E79C28CF6F2
+:10578000148E4BA8FD037A00CFD7E03EA03FFA5914
+:1057900012C5731F84CB7F4744E3BA5AFC76595D28
+:1057A000C7A3303EB1AAC4A39DD757A064F6D87F43
+:1057B000C23C74FE79D91CF0C0B92159201540F7BC
+:1057C0006629D00CF986666FDA705507E7850E9664
+:1057D00097633B78B03987BE6F9BF9070FF8F92CB8
+:1057E000F43B505A33A5F37A7FB939AD9DDD7794F8
+:1057F000A77B9E0BE7A269DDE077A0F3ED65DFFCF8
+:105800001BA1FB9E35BCDF78AA76D117808ED2CD46
+:105810001FB5FC15A991B5276BCD8DAC9DFB51171C
+:1058200054323FE9EBD392107EDABAA6BEBA1CEF2F
+:105830005B9BFA6A069E739AEACCFF1CE0F91BC8D0
+:10584000FB01BA4F66FA39962E1EE5F2E7EECDA2BD
+:105850006AA6E31D34771D70005FFC54C07DF55DC2
+:105860001F1E3403C9FFE9F07133DC97701FA4EAEF
+:10587000D0F54C238ACC8CE810BE3F9DB4BB58BDFC
+:10588000BD0FDC7F1A1D8F6E9961BC852CFE7CD705
+:105890008787C7821AA5E32D83F2BE77880CE34F72
+:1058A000DBAB34B163517CBC57E9786274BC6EF8F1
+:1058B00049568447143E568497061FB85E04DBA3FE
+:1058C000F0457B45836F03C08DC26F6AD2949BC93C
+:1058D000B0C4FC32D539F873765E8CCD2716BE5F26
+:1058E0004313E5B7A71CFE3DC07F8D0EFFF3C03FFD
+:1058F00073AD5DD9522E9E077B119ECF370506A44E
+:105900000FC47362F97D200FAD237E9C37964F8FB5
+:1059100002BF5C0D25E50B98073FB7722F5FE7EBE1
+:105920003F3BE5C2F328FB3ECE86729EA973F59DF0
+:10593000C06FFF6642FBF3FCDEFC5EF3EB8E72BFD2
+:10594000CBBB0E7E9E88AFF33E6ECFDDB7D7118204
+:105950007B10EFAB3575EFAF80AEEFAB65F9274449
+:10596000EA1876BBC19E6CE4F1909EE3C07E21767E
+:105970001C6D9D07B2FB5D05FBCBA747C8B88FD850
+:10598000FFCEF93F56D3BA3DCB8AFB84D5C99C7E66
+:10599000CBD8BEF5E964BFA308FC5F2B537C2A5D1E
+:1059A000E7CA3748BB48E17460C843A1F212B81790
+:1059B0005A44DFD9DAC8D66039BC57C8EE9DF170B9
+:1059C000BB746DC7F136A0C753472C1877F8D2C502
+:1059D000CE13AE345764831DFFF96639EEFD679F21
+:1059E000BA249CEF66A153003A9F4E825690177BD3
+:1059F0003B26F785F9B87DC403E47F6AA34964F7C1
+:105A0000A369FE96B0C4FCFDAAC4EA7E5E7A6CFA75
+:105A1000FBC6568C1B83791E335ADEC3BC5A7709EA
+:105A2000F3DBC5CE23C9C9E6EBEA48C17C52D718DF
+:105A300011F3B15DBE2E01DE1BD0512EE3FB41A15F
+:105A4000D7F7072CF18C07B8C2FB20E7075CE1FB16
+:105A50001627CBD35AC7F7D99BCDBEA631749CCDA0
+:105A6000AB9305C087D64F7132B9726A8CE6470A8C
+:105A7000A21F293BCF63837B2CB2FDC8DCC4551227
+:105A8000C4FBBEB7403FE66745386C1EF26218E2C1
+:105A9000D82BC1BF027836337A5AB95A40BF2A850B
+:105AA0005F3FD0139F3F66B905D631A059F0C0DEE5
+:105AB0009D9671E73DC5656574DEF238EE0BC14D0C
+:105AC0000BE3666FFC00E7E54AB0DE7A17BB27FF01
+:105AD000F3CBD0C7570E766F62766D07BF1F2F8C42
+:105AE000F7E005B57BBEFC25EC7E13C9AFE8F36398
+:105AF000A2FCB394D321F1439CADB2540E811F415B
+:105B00006CDE3C05D63D3D682137D1F5B5081D7EDC
+:105B1000E0177584C8EF53F21F0538AD59D717F356
+:105B2000F0968BFE6CD0C3EAFF91314E77C07F7E3A
+:105B300003DC1FBFA95446BE380070A7F5A797E441
+:105B40006E8638A5ABB6BC6D3A1D2FE49151B234C8
+:105B50009490B7F3214EB944F408B47FB042CBDF40
+:105B6000F6E0799EE1A6AFC617401C2F43449FD2B2
+:105B70002981DDDBB06C49B907F0BACC9326E8F790
+:105B80002F77723A389A5271A793C2C7FBC87A0F1F
+:105B900035E3287FA65E057E44B55956B6B3782115
+:105BA000DEF790CAF192DA2186ABDC5877CE4A81D3
+:105BB000FB7499BFF4D19B03CCCF09B1D191E8E735
+:105BC000E47F5EC46B1AAFAD1C6AC74A6B7D15F6E5
+:105BD0008771D2E938A9256278241D774BB27F13EB
+:105BE000FAEDC65A114E44EA6C033885C6F6C3BCBA
+:105BF000F0F5A306BF07E758520F754D063D1ACAC8
+:105C0000B2FF6933C8A965B2027C9EBAE4E43D786C
+:105C1000F99BEF170F4299DAF8D1C320A7933BFF06
+:105C20005687CFC7C906FF62EA275F7E0BEDA9152D
+:105C3000B2C14FF94D4AC5CF012E9B0A8341BC1713
+:105C400013309A1E5DC7EEA51DE3E0BEE3539344F7
+:105C5000DF16DE8EEB6AF5845632B895805ED0E0B2
+:105C6000B65C54DAC3B0AE8956A48F3CD281F22A16
+:105C700003A2D903A37849FD64C542C8D7889DCF44
+:105C80001AA7D07DFF06DC1308B882FC1839630C14
+:105C90009E43DC53DCE1057B7E7582FB73DE75B1D0
+:105CA000F72D22F3B3C6B6BFED62F40022B1AD18F2
+:105CB0004B7F11944EA226419969C5FBE6F688CA2E
+:105CC0007F209DAF3729801FE86FA6F8DBFFF669BC
+:105CD000F42FEE0F7E80E5B3AE02FC1E6D0FA7D34E
+:105CE000F7D794B0FB8ED778188D5437337951EDB0
+:105CF000EDB442DCA4BA9078B6707A53353883BFDD
+:105D00008CEBABCADB195CD30A09C67DC11704F75B
+:105D10004DA5433F0ABFB4E6A50B118FA4431D4810
+:105D2000FBAD8171013F8D2CAF9F904E2BF26FD058
+:105D300084714FCAEFEF825FABB2A52FC6FDE1F8C9
+:105D4000308C97C2BF9BC2C7DB4CC701FFE1A9667D
+:105D500013D982F2AD03EF675796505A46FAEC2AF0
+:105D600083F39A4A89C7B352A3034D8E51D6984103
+:105D7000F505C06D86AA2E04FA3B6EF5BC0DF370D6
+:105D8000B45A1458FF8CD6971683FDE2F07636830A
+:105D90007CA82E65F34D69A1CFD1CE51DE85FED50D
+:105DA0002D16857D8FC3AF84D31987C34C3EEF99E1
+:105DB0001BD9BCED59A120D067F5120A57680B30EA
+:105DC000BA0797E82511F9EA10ACDFA5A6E3B87D7C
+:105DD000A6C4F0450CFD69EBAAE4EBAA5CC2D6456B
+:105DE000383FD1698561DCCA12B6CE1984BD2FC295
+:105DF000733AFE4CBE9E4AF5452C67365B0CE36F4A
+:105E00002AD8D601F3C92994153C3742D87D87D9C1
+:105E10007C5DD98DEC7BD9852F22BC48AD6EBEE868
+:105E200057D5D5295F9D7A8B3216B573856C2B12A9
+:105E3000D3F19FC918CFC96B35AEEBD48AFCAD70D6
+:105E40001EFCB3C7648C7BEF117D4707E07E545680
+:105E500098FCF17D3001E4F4CC461FC8F1DD650CFF
+:105E6000FEA76E2521A08741872A5200DE830E05FA
+:105E7000785983F1740A10A15BEED1F9D12D53B397
+:105E800000F23232F0B95920074AD9399F2CFDBCB3
+:105E9000E9FC529BD3CB211F2AAD34A55CC6AB5D78
+:105EA00063DA0F3D315984F6834F3C08DFC920BACD
+:105EB000F5D076D93D909D6B39485BA15FEDC94720
+:105EC000001F2DFC1EF24130B3142C0F42994AF9E9
+:105ED0007B550ACC53226374F7586E7F6C249E0363
+:105EE000C794A7622CC324CE3D97BAFE43787F5552
+:105EF00088D3CFE5560CFBF3ED8FDD3804F6F16B5C
+:105F0000C04E4C8273BC9EAF204F47F58908F735D1
+:105F1000E6B0B590D69753BB11EC97B5051F89C075
+:105F2000776BF6121FD0476AC53F2D7A3CDEE462DC
+:105F3000BFCF23C96415F0FF812127C7019E42FB13
+:105F4000A9DD49FB97FFDEF98403ECA13FB23C9841
+:105F5000CD6FD5A0FE7E285B8E7B1F2FB98C9D1840
+:105F6000DB3F65D064F4E70D685D370EEEF7AC1EDD
+:105F700027F96EA2BDD35ACBCAC08E512A2875F517
+:105F8000A5F3DE387C2930A13281C5CB9471ECB900
+:105F9000328695ABEA0E3D0AFBF6E04EC99647E71E
+:105FA0003B7405BB576C55E1796B80DAA52565CF4D
+:105FB0005B6FA5CF4F94502D489F9FB8FEBC0DE25C
+:105FC0003B4F9794A7023CF7361BED3A02975DD101
+:105FD000FD509125E877D179B57C48109E264BB8C5
+:105FE000AD92D64D2F39C1C2E9B1CF59D1B2790A9C
+:105FF000D0E98C0219DDF6B1EBFD88EB93E9B55DD4
+:10600000E3E07EFD1C9530FF7EF07114CA33B9C801
+:10601000C8513B50E8B85AD9FE2428F9DF04B91C0E
+:106020002C0CC8F08A26CF5A0655EE0079F6676E1A
+:10603000D7919A5978BE0CF9DF04F6505759BC7DB8
+:106040005389D38EFD4F6DBCED63F053CFA865F639
+:10605000FE808D5F09880F6AF765D0F10794E055DF
+:106060008364C692A0B508F09327124581F9B41352
+:10607000D82704A9FED1C3411BF7BFFBFE429705F9
+:10608000F9B0046C67DD7A9C7C3DD93EBA9E387AC3
+:10609000BA987FF7A74F7DB57F14C07F09DB220D2B
+:1060A000081E13ACBA790C50AF6C1ED7C07860BF15
+:1060B000BAD8F9535749279E938A95EF60CE03DFEC
+:1060C0006E729C1BCEF6F74679DAA3CEE92AF679F2
+:1060D000768CBC2AB2B4DF8CF8DDCDEEBD868C5850
+:1060E000681788A8B07B3F43DAFDD435D06FA8CBC2
+:1060F000E9013A6819F25131C06735B717661612CF
+:10610000DCAFCECCEC407B617A23B717245F130859
+:1061100059C7C664B252673FA0A9045BE8466E2F18
+:1061200068FA9FEBED6A6F4733EA55B00F747AB5A2
+:1061300052657A758097E9F5EA66FA1D8513F3488A
+:10614000BD5DC2F4B8D2CAED07AE8753F977D39AD2
+:1061500099BE4A053BC20D69102AEA658C61A547C4
+:10616000ED963E854C5FA6B6EC41BDD60E87B64790
+:1061700080DC60FA32EBBDC32A80C94B1FB75139AE
+:10618000FD246FF77AA87D9612B5CF968B3CDE443E
+:10619000987D8839FF749E8F427F9DDDB88DCF6FCB
+:1061A000CFC1945B40BE6E0FE6E2F9728D6FD1FBFA
+:1061B00049EBD9252C7F25BB96C5C95DBEAA1D26F6
+:1061C0005D1C62968BDD3B344BA3ABDAB017C60D7A
+:1061D000C2FB28C7D9FD3F2BE0BE1EA017BEBFBA29
+:1061E000CEC9FD1A9C7E12E9134D0EB988DF5D48B9
+:1061F000E17B22B403E5B54AF74BB0B613C1867E06
+:10620000F703BF072795C0FCD78CFA3BE67F0C4805
+:10621000B05FFC54DB677E47B9EE1A7798ED433BDD
+:10622000C4B8E77B32DDCCFFD02E1107C0D3166493
+:10623000F7C8D94AE5B8FD93DCCCCE3ECDE1B666D1
+:10624000D40E3CA799503F4B4435C5D1A79ABE6D9B
+:10625000013C5F47FBBBDE6E52719F1EAA30A17CE2
+:1062600025B8EF0C924EDC47AA0532FA0D5BCC4103
+:106270002BE0636D09C7ABC7BA19CEFB7E67BC5074
+:1062800078009E57F8C5909003780E798A985F073A
+:10629000EF413845F7EFFA78C510B7C8E1A4E00F31
+:1062A000F30D6866F4B566948CF358393C7DB329D8
+:1062B000472F7F052E3FD939B195A3DE44FABAD2D4
+:1062C000F955D53EF7D4095D3CF1E486677201CEFD
+:1062D000BA7B307A3D4F5155FBB7D66D71E204DD84
+:1062E000EDB08F72C23E30749721AEC9F13BC62D1E
+:1062F0001AFC6E205FCDB8B908F503FFD2EED121AC
+:1063000037BC4796B0B8ED6C1EB73DBDED363C5777
+:106310005E44C9CA1C07EF5FD619CFDF7FB9FD996C
+:106320007ECCAF1132E409CFDEF1CA50437CD84FA6
+:1063300094B491EC1E63D4D36FFA548B297A0F81F5
+:10634000763FD695DEB79542CD30DC77910A2CD3D7
+:10635000490D965E12C4B21F6967E766619F3B10E4
+:10636000F44217960AF1884427F773890FEB79A452
+:10637000024B09F0961A8D4B483BAD98BF01F10BCB
+:10638000E0FB44E7CE7CEECA856EE4EF9AABD9EF32
+:1063900018B178C564B7FF0137E2218CF27B3A1758
+:1063A000E5877E35B41DCE1F3DB09A9D7BD1E43B81
+:1063B000EE6FE8779E4B61FA405D2FA01CAB774CE7
+:1063C000FC21C2B3C57C461F6F20566B1EFC3E8865
+:1063D00036EE74EE6798CEF520B8BBD9F9411F9E12
+:1063E0004F9A0EFE065D3BE96E67F7D968E3888E2B
+:1063F000EB07F716EFD3BD8FF9D19531FB80CBEAD0
+:10640000EF98FA8CD8F7BFA1134A8FFAE39EFBA14D
+:10641000928DF4CAF537252805DF6BB61CC3FD58ED
+:1064200070AC5F0F9767391F687A65464CBE476C42
+:106430003943E2FC11330ED580C970AE17EF96D008
+:10644000F1B7763FA9F6BB5AB3FD013983BDE60526
+:106450003C7AF8BC83646379062DBF80BACEBF7FD7
+:106460003829F0925BB71FF1F86B44FDBD377339E3
+:106470003F8E35B594819C3B15203ED847CC2635C0
+:10648000EE1F803FFFB009E55C7F3A6FB918EF1D42
+:1064900053C514ACABF07B2F67EBD839A193FC7ECE
+:1064A0009A1DFC7E9ABFF07B858BDA164F043A3832
+:1064B000CDEFA529D8BBA202FC3E45ED8E69A0F721
+:1064C0008BDA4757437BD14E0BFB1D1F2E27B47928
+:1064D000C1B96C3BFD4E26FD9E3505E40941BD7BEF
+:1064E000B6C51E82DFFF39DB6E62F7AA168A789F77
+:1064F00003DC8B66E2F34B4A81EFFDD7BD608F9CD6
+:10650000E6F2E48C3B99E14B5205350DD252880FEF
+:10651000EC9A758EF9780EB2CA19DAF1441AE4874A
+:106520005B7DF5F4FBFBF7BC940DCF1F77CCC7F276
+:106530002F1B3ECE06B97576DFC7723CBA9D278504
+:1065400065F04FCDD92B88103F296B9F26437CA443
+:106550006AD77EF42BCFF304B07D6EDB1EAC8FD9EF
+:10656000F51EC64F06262938AFB31901F4F3E6B578
+:1065700059C2F07B1CBB7383F7C78DDB27313DB35A
+:10658000CEF11A8EFFB8E3B537112E1B2C78FE63BF
+:10659000FF86DFE3B867F6BDC4E74B305FF0ACAD14
+:1065A000FDE8CF417FEDE1E731AD1D6EBD3F584ABB
+:1065B000120CF2F5AC8BC7BD322FD38FE70B1267ED
+:1065C000879BC9A50E37C4CDAADA191CFE620ECB73
+:1065D0006047CE691714F83DBDB25D9BF13CE09C6D
+:1065E000BD563C2F3107E00170A3F042B8B4EDC7AF
+:1065F000F9E7025CFAC03A3EC07CFCBCBD142EC375
+:10660000A2EB9EE30C20BF6AEBA57060EBDE7D3948
+:106610003C058C786A7B4F06BFCCDCBD02C26FEEB6
+:106620002E368FAABD6C5E63764D43FC9FD947140E
+:10663000F0B79CDCF3F16958CFD97D56BCCF579B9E
+:1066400017A553E22E06FE61744AF632B9AAD9DDC7
+:10665000F342E9F8BB03DDEDBBD8EF9202C86C94BE
+:106660005E8BF64EC2B86009102FF0BFA77D28FBE5
+:106670007DC16036C075F7E87036CCFB8CF6FB4800
+:1066800052301BF0E273074A9274F8F8F2D84BA824
+:10669000170BC49A4F1F013E7E5E44BB68F127EB87
+:1066A0000CF7ADDC003F483502E0F6AE1BE1D67DCD
+:1066B0008F4B90E54B9100F26315E7C7B39BE9BEA2
+:1066C00093AEFFCBB617B0FD6C8631BFEA2F6DAF2E
+:1066D000A700DC2AF9790C12BA0DE511854BB33508
+:1066E0008E9EEF3ED71662E715CF09FC5ECDA7342C
+:1066F000B8D5C8930D713E260F3337E61CC47D46CE
+:1067000028FE39C7583B29F6BED444F900C7B93C26
+:106710003BC1EF3FD0F4EE6477605A529FC4E7BDAF
+:106720002B57CDCB067857C2D948BC0775FF4DE033
+:10673000AFC07343EC9ED430C0E7A4760F2A79E94A
+:1067400026C8333D99CCEAB5491DCBC1AE3DA9DD84
+:10675000ABAABEC1DECF61EDADD04EFBFFCA5D512D
+:1067600093C4EC7B81FDBE8F39197EA741D31B8971
+:10677000E160FC9D8667E85A012E74BC9FE37812A5
+:106780001DAFE8FB8FA7C9E9EF3D8EF57F761C4D65
+:106790007F017F42EA23F1F986FE4FC0EFBFFB3E47
+:1067A00009CE34F0D5C50D039B208E7681DF23639F
+:1067B00069594A409FCF6C5D17F7F7DFBAEB3C2F62
+:1067C000471E48F94DC7D78792985D7E88CB69F8F8
+:1067D00083F89676CF24FCB5A463EA12EE9FF3F912
+:1067E0003DE6052488F6E950D28E6521E9C072188D
+:1067F000E9C212C3CC03C155EA33F1FB6847C2E2D8
+:10680000E75A034FDB44CC3B7803E410DC4B2B9876
+:10681000C09E9C7F1DCCFFED240F8757D8F07B2BAB
+:1068200044FF7B180AD88313BCBDD983C4239DE9D8
+:10683000CE7BC9C57B6DDF4BC2F525FA1DB5853111
+:10684000F7DEB073E11A1CE69176CC237963E3039B
+:106850006F0FA1F0BF7F970BEDE4C11B1B17823CAC
+:10686000BF9F74A4C339E1C1FC1E11D266FCFDA612
+:10687000216D16E3EF08C7FC5ECF1CB88704CFEF8D
+:10688000199F6BE770F11EC838F918B1E778FF9AC5
+:1068900014FFDE175218FFF75062CFF1EE6A17317E
+:1068A0003FEA01C8BBD2ED2F866CABB118E94BF9BA
+:1068B000B73CB3AE2EF8983FC265F76F177A7EE704
+:1068C000FF020F2194E60080000000001F8B0800EB
+:1068D00000000000000BDD7D0B7854D5B5F03E3391
+:1068E000679E99849964924CDE131E2128E004432C
+:1068F0008C68EB49881811EDF0A845DBE20404022E
+:10690000249940D1E22D2D131220206AD08840090D
+:106910000EF828D64727BDA888813B20225AED0DC6
+:10692000D5B6D45A3A20554484F145B9BDF57AD745
+:106930005A7BEFCC83A460AFDFBDFFF7A79F3DEC90
+:10694000B3DF6BAFF75AFBCCE50E85B14CC69E5654
+:1069500094DBBC2319FB12FFAE893D6FB1EB181B12
+:10696000CBE0AF8D4D2C67ACB541B5AF81526BD04C
+:10697000AAE99DF0B4EB824A316379A9D5E6F950D2
+:10698000660E9D7D989BB109FAAB0FBAA1BDB151BE
+:10699000BDDC04E5FDDBE6F71AB0BF4B6526983297
+:1069A000CF01E34299E5E882C3A0DC66FFA5631648
+:1069B000CC5F6283F7304E819D05DD30EEDEAD7732
+:1069C000EAB0DCDACC5836CEA3F87ADDD44F658F46
+:1069D000E1B29836A92C8BB122FC27CCA3B2B51F0B
+:1069E000EBD318AB693C6E89D8E07DA46E121BCD49
+:1069F0005895BD98F6A9BE73FD0758DEB2E498C35A
+:106A000007F3BDBA75E56F26C0788620AC0B8628E3
+:106A1000FDA2F5ED09305F74AB916D633138142E32
+:106A2000558F45CC3421FB12FECB5F9C5836322863
+:106A3000978A7231AE23AE1ECA978BF9199BCEC2CC
+:106A400059582FD6EBD418837532BBCDF9DEA58CFF
+:106A50005D6357D8978363E5B1A2BCDDD0516D85E6
+:106A6000756EFF93E26981EA7D5BE714E1FECEBEBD
+:106A7000E02BB2C33E9698D346B341E79F9FC1EE49
+:106A800016E717B0E85CF80C5B982BD67EC4A3CD54
+:106A9000261F8CD3B68C798E0F63CC1CDC6FBD1493
+:106AA000CFF1A0C10345B64261D34350AFDA981687
+:106AB00082792E17F892FC5CB1CCFDABA186D8BCD4
+:106AC0002BBE983A1DCF379A6AD5B629E7AF4BF659
+:106AD00053EDEE009EAF219F7952603E83B337D7CE
+:106AE0000EFD2E7DDEE8B101C826FC62E4A008CCD4
+:106AF0007BE94BB730772A8717AE575D62F41CCF1E
+:106B000060CCB4C4E9512FC77636C2C74F6CC6A05B
+:106B100009E1BFE4EE0EAC6FDD5AE172C7E1F5CAE0
+:106B200065768F0AEBDCBCCCEC5161832BC5FE9201
+:106B3000D757E0D07983D0CFA8633EAC5F04E7801D
+:106B4000705C644FA1E74251EE52035370FD5D80CB
+:106B50003F2D88AF8B39FE2ECA310711CF17BD3AB2
+:106B6000249BF54357F2F9F832976728AC63F3E2B8
+:106B7000992E065DAB16EEB75C07FB5F946AB623F1
+:106B80003EEAD34A1EBA1AF1FD350343BA6A4DAD47
+:106B900070CF8A1B4F9F56E94278E875815C666723
+:106BA0006C957D46AD9A83F812D8C43C8CDDD771C4
+:106BB0002D2FA7067215A87FA8E37A5ECE0C6C5223
+:106BC000A0FEE18E1B79B92090AB83F2CF3A26F379
+:106BD000F2B0C0262CFFA2E3DBBC3C0AD690CBD897
+:106BE000F31DB7D40660FE568367BA07E67D06D666
+:106BF0003F12D61F12CF17ECFC5C65FD2FF13DC094
+:106C00007B877826D73F27FAED1CA07E97A8EF193F
+:106C100060FC3DA25F7880FEFB44BFFD03F43F2093
+:106C2000FA1D1CA0FE3551FFFA00E3FF5AF4EB1DDC
+:106C3000A0FF6F44BFB706E8FF3BD1EFF000F56F50
+:106C40008BFA7792C63F22DA47C4FBFCD4F6B7032F
+:106C50008077F9C0B7F0AF34B53D1DF16E7373396D
+:106C6000E17FEB58C0F391317CCF579817CBA31D30
+:106C70002A8D371AF9313CDF14E3572D1C7A1FE2B5
+:106C8000DDA237F41EC4C356C573D807E30716EA5E
+:106C90003CC87717BDAAE778BE500DB238FA7E33EC
+:106CA00069FD5BC4FADAC47A7F651F4C7453B4C4BF
+:106CB000E59924F925D2BD3DB16C067AD260FE3645
+:106CC00027972FA50BABCDC3517E807C41BEB9C2A7
+:106CD000660C9B60FE157695EADB9CD576AC0FD8EA
+:106CE00055923F2B9CD5E659C8576DC0EC2A603EA3
+:106CF0003B1FBBCDAED606917F386AA87EC22F2639
+:106D0000D9918FB6B1A8A30AF7B714E40AF4DFDB70
+:106D10005C4DEF8B1C9F39903F1F4AE7FBDA9F7A4F
+:106D2000C0520CEDD43B74242F4AEC2AC9B1C14B9C
+:106D300075413734D96F5FA4C3F2236D5C5EC15FC8
+:106D40006A19CC3F944FCFB6DF59F15A29CAB37BA9
+:106D5000548FDBCDDFA971F26028CAAB349C373D7C
+:106D6000415E7595330DC70DB8CCC1C760DCA12A53
+:106D70007365A4C7E05EE4D073F9A29FE441B9361D
+:106D8000A423513E15B7C7C92786F232513E25CB01
+:106D9000AB8266E08F71FD4D2E7B42D9E24825F92A
+:106DA000043CC6F3254CBDA87BD1755616E3D7C964
+:106DB000F2A855C807C9775BBFB83C413E48BE9CA6
+:106DC0002C1F2ECC5FDFBC7E38E121702BF785F9BC
+:106DD000EC9B8807807F069F42F283A93E9737F598
+:106DE000C2F03218BC76BBEDC2703364BE457A8502
+:106DF000C1A7D2F8E7C9950BC055B6339A1FE93A37
+:106E00000E72EDB3777E58CA806456026CE8FC338C
+:106E100075C1C760DFF94B9EECC2F1F30E58DB1071
+:106E2000CE46D7ACAE36DC4FC7438C013EE9CD1C15
+:106E30009F8C39D576ECAFEA3457FA10283FF1BB76
+:106E40005B15C0277D46B387C1B91D7CE6B5F41B31
+:106E5000107E6F1888CE4D3AAF9D0DA1E510BEADE6
+:106E60002AB06E5D4378EC33239CF2B79B490EB099
+:106E7000C0A3AB3540EA56380E360EEBA7AFD6604E
+:106E8000DFDB95BEF2F5580E058DBC3DB068FCBF4A
+:106E90006E9D22EA99A6BA48EF14F5BFACADB91AB7
+:106EA000DAABF64B55903B8BD63DDB6E28C07A9D16
+:106EB000ECAFB14AD82FCE27CA2A9CCF93FB457D91
+:106EC000E0A5F61A20A26EA39C9F05B07DB74EC721
+:106ED000CB819E761CFFE96AD13FF0F86A2D9FD6E0
+:106EE0007383DE0145C72BEDB62B63EB5D97FE4642
+:106EF0007B0BECEF2377240DB6C11AB71ECF42F9F6
+:106F0000BC6A7AB317E18688EF05993848EF263CCA
+:106F1000ED3BB71D930379507BE6C0DFD246429527
+:106F20005F1F399002F06BDCD96C36407F93C11B38
+:106F3000C82B8EF56BDC5147FA8CBFA78C9EFDF4F5
+:106F40003BA80EFEA7FA998D1731DF47E1DF343DEC
+:106F500005558DFAE6769B9EDA337EFEFDEF4FF601
+:106F6000FFE8A9DFDC8CF39D7647B22642EB556142
+:106F7000804B3FFD64FBA69D93E9793845BBCF016B
+:106F8000EFE702EF227EA5367BB07DC8DC61F7001B
+:106F9000A02D860E2FCA0D007D5057197BDEEF18ED
+:106FA0004AED93DF27D357C8CC3226211F6F5049B3
+:106FB0004E85CC8194D1505E0B76480B2C6979D9E3
+:106FC000EFC68CC4F2B3368676496BC37ED748A42D
+:106FD0002B8F91A1BEBBF6CA500ED2795BA371FA7A
+:106FE000A388BFE145AED971FAD6BA7403AD63F593
+:106FF000CB407797C1D3107228D87F18C80D05F9F8
+:10700000A2CF8C768E25279D058AB19D6D2DD2E766
+:107010006A83AFB61ADBE5E848BE58864DABAD864D
+:1070200075B832758A9ED65173780ECA37BB112552
+:10703000283B923E7327C2E949D5D38C74F8A4CD7E
+:10704000660F4005F0480DF99F3ACC19C4B249CFFC
+:107050009A518EE795813C8FD3638F08FE79C46186
+:10706000247EB7D6129A5C05E35817E9EC01986FB5
+:1070700075E3FADE0930CF4F1B9F3BD402EFD76494
+:10708000A90CD76173AA6123C81FC38DB04658F7F6
+:10709000D32D5E3BF2D768A6CAB641BD75A891B99B
+:1070A000E3F8956D2494E3F8648653D52CD0FFEF74
+:1070B000E9BE7F77C0BC97BFF19619FBBBC6EA74E7
+:1070C000483621959F735A79E238F6AB13C749AF1A
+:1070D00049AC774E4AACCF9A9658EFFA5E6239F7D0
+:1070E000F6C4F274896FC0736C208FADBC8A5923CB
+:1070F0001F2F43790BF0F903C2DF5AA2F3207C2C37
+:107100008D8F9E9803F579C84FD01E1ACD48EEEEAC
+:107110002BFC1737EA05A6F466B763E4F9F0C82B31
+:1071200030DF80E7651BAADA19B4B7BDF3C11738A1
+:10713000BE8DC5B52B46F8685147262FBB603DA9CB
+:10714000F80F37C2BBF9CF3F46B97848EF4178E72F
+:1071500035AA34FF3DD3DC413DD7275CA8CFA489B5
+:10716000F669E6B5BD7AE0E769EFAC5E88766F3226
+:107170005CB358B3827409F8C1EDED3A46F26395F9
+:107180008ED523DEA08D80E3917A04FC626A86911D
+:10719000E0644A5784DDA8EAB03E4BE84FC69CDB6A
+:1071A0002D48C72B0E70FC5F61E4E3F48DE7A64920
+:1071B00011E519F2C98C745DC238EBEDA28D286718
+:1071C0003A78B97B7FFA0D4897EBA7A58F413C3100
+:1071D000A1DD05E30DCA376B23607F96578D01054E
+:1071E000061DA4B2FD0638CB6E2BBBCD0BEBD878B9
+:1071F000D01AD0C37BCBECFBEDA8A7958B75772F6E
+:10720000F7BC897C205AA7121C2D991DF63123F951
+:107210001E02B03E4407948B55C33A49CFB3547510
+:10722000907CB7947574209C364ED291BE917EBBF3
+:107230008EF0D952103A3414FD04B375761C2F1D0C
+:1072400004BF11067920BFC38B7E130630D755705B
+:1072500054C1716987304F8680ABD3B9E3870A8CFC
+:107260009381E38DE6ED114E0E01A7ABD3DD0477DC
+:10727000A718376328B41FCDC769AB888D23CF719A
+:10728000632D0BE2FAE4BC729CBEF199A6205F3537
+:10729000FC0AE006E7A4149A69712BE633B28FBBAF
+:1072A000977B9BB7125DDBC8CF91EBCCAF463CCA56
+:1072B0003DB8698A6E34F6B3D23C86D92C88789C66
+:1072C000AB32F337D351BFF1121C93E935677FC757
+:1072D00054D453E5B924D36F8ECADAF5E9E7D371F4
+:1072E0008ED3595D32BA1F7A4EA2979C83D13B1040
+:1072F000E993E97A4BCAE932840B8B6FAFBF7059BF
+:10730000AF0F1D423F0FCB063901A02F4C9A8FB112
+:10731000FF326159613AF7974390EF3B84FF06E4EF
+:1073200015106BF718FB781BD2E94246F855FDFCA7
+:10733000DA5B7F05E39D1D66B4A35C2938D8D18B49
+:10734000F291EDF40DC773D8ACFA1E4E81FACD87D9
+:10735000B319F2EDD5166E8FA902CF93E5CB3A4162
+:10736000376E9473AE7FFE29F5C3D0D0AC4BED40A1
+:107370007BEBEEAF7DD59CF9BFA867B1A749CFCA1B
+:10738000DFDFDB62C3F9D71D6C37037C2D6FF0F6AE
+:107390001D500EA808BF06F267ED2B98437052DF10
+:1073A0003631C4D3517A2D8865F6470B43FEBBFDB9
+:1073B000D9EFD5BB91FF644D74231FDA26E83D2831
+:1073C000ECB3E4FDAB46CD87FA44F2FB4DE93A71EC
+:1073D0009EDE1375708EA31E31B2355059AA9BD90B
+:1073E0008EF65D7435F05FA89DA97737DD1D67DFE8
+:1073F000DE6BAD0AA5A35DB2CCCC7CA030E79F5379
+:10740000980F88B3C0F99B2AE43F852CACA09C2D33
+:107410006C068517F16AB195F9E2F03DFF9C4AEDE3
+:10742000EFB56AA1F4B1FCBD19F88081FF933D99D5
+:10743000EE65754ECEA3507F313C653D8A7C833925
+:107440006BB43E7B6430E22FC87D986FB7D8B7012C
+:1074500060681803FFD97461D3E8F3DBEF1370524F
+:10746000CDB630F24BD5F6FA61E22F76F5547C3B7F
+:10747000B4BB89893530F2CB225CA8FC033B95F381
+:1074800080FF9AC690DE1F40FB3B90C6ED11A669B7
+:107490006E6716D20B2320E79B59BB19DA11B6038E
+:1074A000BDE5B05E0BE9CDFB991BE9013D6CEFA595
+:1074B00010CB6208D7CD8CD5C6D3817C4ABF84BAA5
+:1074C000444FF6D4A52F59683D866616B4A03E8475
+:1074D0006B0378AB8B59502D8EF905473BDCD4CF2D
+:1074E000C89A499F7DFA8B23B9C8A7AD07401FBB37
+:1074F0000CCF59477CCA6A4DA43FC65A084E5181E9
+:107500001F5DCBEC74CE7DF69BEF2D71CE91169462
+:1075100017858BD313CE57B6CB3F97C77C97C78FB2
+:107520001BA471F387EE57D02F937FAE90EABB96E2
+:10753000B92F30FEE001C6CF213C1A78FC7CAAEFBF
+:107540000ABFE5B80940B139BADFE175C7F4EB64A9
+:1075500038E72F4EE4CB97ED4C2C4BB8580C9A7370
+:1075600032C0DC7287CEB315C6BBE27062BBDAE212
+:10757000DF92FD1B6B1F764EC5F6609F6F85B75778
+:107580009D486CEFAD7AD981741C6BCFD777CDB99C
+:10759000C476C9E793BC5E5857E6B7E3D635DE6CD0
+:1075A0004AA89F5E77DEBA32BF13B7AEEB5C89EDB7
+:1075B0007D2DFDAFEB8652D33F5C976CF7ADCA8B48
+:1075C0006B97BC8FA9B5A601E0CEDB7F67FAC58DAE
+:1075D000FBDDFA7FDCEEB625C9F30408DF17E9B45A
+:1075E000F119503F135FA1BE68B392DE7B9E9D25CB
+:1075F000E4D344543CA09F274D9B88FD6A25DD09B8
+:107600003FC3C1672EC946BE9E27FCE84CF815BA99
+:107610001B5CE457F089F6204FDA905F746F877E29
+:10762000697C5DF1FA534603B72BEC2C4AF42CF538
+:10763000A5746657B83DCEF59D81E6491EFF1E54E0
+:107640000061BDB3968C67EF021D3E67B457A96811
+:107650009F6D51481F9855A3E953013FC6B52BE4D0
+:10766000579A75D79B0FA03FE6CAE3EE9D11783F6E
+:107670002BE8F0E0B44DBD4CC33841B67E61D98FE4
+:10768000E1F9E03E4671342C2F447CB3696EB43787
+:10769000EA704530CE294373991DF9E6F76D1AF269
+:1076A000CDBA69DA1F68BF7F07AD04DACDE65B6744
+:1076B000CF774E3662BCA3EE7BEE4AD47BEA42160D
+:1076C0008D9E66A65A611F75A08FE133DBC8540BEF
+:1076D0003EADCC8CCF8AE55CFF4AABF41AEB60FE82
+:1076E000BA9E9F7D8EFDE6AAE1BD5C9F0CD2BEEBEB
+:1076F0007A5EFD0FD4D7666B5E23F28B4BB71BB956
+:107700004E2AF0615428B18CFC20BE5C164E2C5FD2
+:107710007E30B1FC710687EF38E1C7DAB7DB447C15
+:107720007BC18756D23F7781C0433B39F0B489E4AF
+:10773000C7F805363AAF0F4F5AB7A25F6FEFDB5667
+:107740006A3FFF490B6FAF0B3D83E5C03329646788
+:107750002FC80855A4C3BA5FFC424FF0C66D19701C
+:10776000FC67466C5D83F597872A302EF6DC258C06
+:10777000F562BD1A1C8DFB7CEEBFB8DF3AFA842996
+:10778000B80DC6FDF0859F3DF3239CF789BC7405B9
+:10779000CEE72A940BD06EDC23662BDA1BE33E7C0B
+:1077A0006A08F28D05DB4D09FB7B264311FA833B0A
+:1077B0000DF16E20BFE3B1D53FA3FEA5270E13DE6A
+:1077C000ED32047418C70BACE678B6CBC2FDA4BB8F
+:1077D0002C85413CA7DD199CAEAED26DFB6913EA46
+:1077E000976F703D64A0F14B5DB3BA6AFAF133F65E
+:1077F000D5C3BCC570CE673EB0DE86FEB8E11B12B5
+:10780000CF694430B1FC7206D71366B2B8F7C5B879
+:107810009EC12B5DB89EAD8CD6537AE29D5B8B5199
+:107820001F37713D2479DE5F6770F9F9F39FC33824
+:107830009CCFE8B91E0E1003BA5E20E8E14585EB47
+:10784000C1F0B7380FF07F012A108363EF1724AD22
+:10785000438EDF22E0F4A9396D1BCA73A791E3FDC3
+:10786000C965071FC038A66CF7DE324DAB89F32B14
+:10787000CFD9B0F0400E9C7F437726D999F27DC3D3
+:10788000132F657D17DE9FDAAE7A50F56DB8E5F1FE
+:107890007BC761BB27F4215C27D66B30FEA9D0CB18
+:1078A00069D86ECE66C718F497C8FE73375CABD53F
+:1078B000C4F1D3AF4A4F92FE1B847DFC7C65EF84FC
+:1078C0003C80F7820D8A079B2D087D7BEA8DA8EB13
+:1078D0006CD67B30BE51A132AF7E0C99EED3F0D97D
+:1078E000D0FDEC815CA8F7EF1E5B81FB5AA3F3DEB1
+:1078F000300AE9658B81FC60C9E7637472FC85FE20
+:10790000611DF45F73B3AD1EE32230EE7E2CEF2BCE
+:10791000DDA6473F7EDA09E06FFCFD611DF0CC1368
+:107920003D2B4683CD02786C6B47FAD8858E0B9C35
+:10793000E7693DC90916E6FB1827FCCF0BFED469A1
+:1079400054E179E2C4F2B42A4E7F744EC8D49DB09B
+:10795000BFFA474611BDCEDD90485FB29D5CEFBCDB
+:1079600060627D325E9438A5BF8295C6E35772BBD4
+:107970008C490123D263C312E0E77174D370BCC396
+:10798000887A57F23CA8413279AE7AC24BE6A6FD1E
+:107990005AF87E41E535C37E4FE2BFB8DF5C41BB9C
+:1079A0007EBE425B640B2E61356E80E78229AC1689
+:1079B0009F921F9EAA0C8DC6F6BB0C91C77F4A7C76
+:1079C0003095F8C1297B380DFD4AB9C2AF77CA1D81
+:1079D0004E433E7746C4EDB01ECBF37B401E005DA8
+:1079E0007FF89191E4424BE8A5343CAF53CF5874F3
+:1079F0003A38970FBB33AAD11F742AF4AB34DCD7C3
+:107A0000C9504635FAF506E213C9FC4DEA0347F1C1
+:107A10009F5782DEE3D4263811BE1864C8017993DB
+:107A2000D15CD6DC0FDDCB7E4E637319E66944BFB3
+:107A30006FF3209F9DEA74D3FB3A858F877F18DF11
+:107A4000FBE460C6363CFF837B4B06A19EF00973C6
+:107A50000F42BEBD20CB7B33CEE7AAEEA5B8BE6BEE
+:107A600022F3B4429F77F59E3BED00B7DB19C82D9A
+:107A70007C96FB8CE46F69CBA475CD525958053CBC
+:107A80009D8572753495498F99B55909B6C23A6E7C
+:107A90005F9BB8CF399DA6D8F9C27FF31830442434
+:107AA000A0CD71ED60FC79283F017EF3CD2C9C02C6
+:107AB000E3CE7F34B1DF0216A6F5343CF5A5A93F2D
+:107AC000387E2EE0B8204BF33BA1AC4C31D3BA7ECC
+:107AD000F0B442F2CD29FC8CD1070705311EB64027
+:107AE000C8EBD9A6BDB41EFF5D75DAED8037679689
+:107AF000CCD26ECFE0292364976D50080F17D4B015
+:107B00007001AC6F418F121E85FAC45BFC9CE4B817
+:107B10006C0B6F77ABD07766035C507F18F79412CD
+:107B20004805FE39DB0CA61CF211B13FAC1F04E581
+:107B30007AD641FB6A64115AC75A3C47EECFA3F587
+:107B40007FFE163FBF71F55BF5B8A8837B2B28FE3F
+:107B5000F729F3D039825EC22CE9E7E309C25D8BD5
+:107B60008353FDE6C4327B34AE3C18E10AE5387835
+:107B700037EDF8D2A4F503E707FBE44970C4E451FC
+:107B8000EC3CBDF788388707BF3D2707F9C07DA8C3
+:107B9000BFE68A012A916F32E9D7089B617CEBE549
+:107BA0002CC1CF01FA15959F704E9BB8219FB1F55E
+:107BB000061FC50B66E9BD0730B49592ED7B1AF13F
+:107BC00076964E2B54891F682564EF2EE1E7F1D09D
+:107BD00098E611CDFDD8B972FDEB95505887FCE0C1
+:107BE00005AE1FA496470DBE383A7B45F0B941FB60
+:107BF0002207F2105F9E55C82FBF51616D0AC0D990
+:107C000005C782F260A372F400CA8F8DD7BB592BCF
+:107C1000D497EF98BCF065B295AD94D7D3B8A34A8A
+:107C2000DF68A3FD737D35A579AB0EEAB36F2B1D1D
+:107C3000837402FBBE6D0ABC7F5DD06D8E8DE383C5
+:107C40006B79A07811FA65F77917BE8CF43DCA4AB2
+:107C5000FEAF6C80556A3A3DDB510F75B11605DBFE
+:107C6000ADCC5478DE411D9BFECB918435EAA074E7
+:107C7000FE3C0C4F45656DE8CFCD5641AFE5EFDBDF
+:107C8000709E07D3F8BA3275FADB26A35E3D86975D
+:107C9000D3972ADA3642FE75B4AE6C13ABC57DE3DA
+:107CA0007BD4C361195A37D507094ED9E39BCB70F2
+:107CB0001DD943F8D3690CE7E338AFF7E1894F8763
+:107CC000FC7AB190BB8BB75667237F7DFD945945F5
+:107CD0003EFABA4BEA8F611BEA8F6C68296F2FE47A
+:107CE000DBE2B2F1D988F7CEC2C476670CDAA0CB5A
+:107CF000514E1CD253BCE7339B36C801EDAE32B2B5
+:107D00007EF3ECBE10E7EA3FA7B0609CDFC03FFD0A
+:107D10002CE9E7FE736AC2FB53CBCC2C18E737681B
+:107D2000A8DF3701DB35B2DE95888F8DA114168C64
+:107D3000A38FABACFDCF2BE9C27F4ECF02FDCE6B44
+:107D40004C7C7F2E830532FA6B9795F81EF6915086
+:107D5000DEF9D7BE7DE07B561949433FEA2494877C
+:107D6000503E13D4050CC0875E37703977DA1E4950
+:107D70009083A7DD112E07D14F64E37AFA643C6744
+:107D8000359A362535368FACC7FEE971FB3D3DDDB2
+:107D9000C8C2743E515A07C22F309CB14D3D1F1BC3
+:107DA000313FA6A1672FC14FE24D3C1C03F171A7E3
+:107DB000D6DEB00E784665E64FD78C1C0128B84F4A
+:107DC000F287AE35E8E7CCD2EB12F8454A791FFFCF
+:107DD0002076F52046C188DF6C59837ED25899B74A
+:107DE0008FF57F78620D8C573E92F7AFCE0CBEB602
+:107DF0009C92443A38FF55A385DED4B8B239A96CB9
+:107E000083F2A8B8B23DA9DE9954EF4A2AE7F3F607
+:107E1000A752C3857A0F6337663E3A5105BE792A69
+:107E2000273C03F3C6D6B63E3EB106F859633997F0
+:107E3000CF4D3D8A877C7F027E4D1EAE37DA3C11E6
+:107E400023E6ABA594F71E40FED2B053B12B400FF2
+:107E5000B6507798CAD8CF1DD72FA450BF86D0511F
+:107E6000EA37E0F8A53AA2F735A5C778BBD0FBA45E
+:107E700007AC6A5B48F179197FD6339F96A7C4E2B5
+:107E8000CF92CF9ECED15E223EBB5BB1237DF6E189
+:107E9000298E1BE7F791EDFF38AAE7B7A866A42C57
+:107EA000FEB805F5D93F35BE3F16F5BB3F0A79B29E
+:107EB0005E098EC0793731DF089497DF6F1CB657A3
+:107EC00007ED8E18225D18635B9BD93311F3E88EA2
+:107ED000A4460A300FEFDE070F103C8F6446BA103D
+:107EE0009EC71F7C85D717440A30EFEEFECC4F7833
+:107EF0007958A40BCBBB1EFC132F8F8A14E8A1FF6B
+:107F0000E0C0918935D0FF317BFF74DD9AC9F57BE4
+:107F1000B9BE2B866A3FC9447BB581CBA12EB089FF
+:107F2000CCC03767CC3FF9F463008719FF9242FC5D
+:107F3000ECB153532772FD3CE0552BD07FCBFF486B
+:107F40004E12BF57C96ECE41D9981E3B8FD4C25E28
+:107F500037C9914B9ABB51DFC89E3192E4488D538B
+:107F6000FB0BCE2B9FF7E7C113DAFF25D3CEF9B772
+:107F70005E47F1ECEC1FA5927E769F85EF07E886C1
+:107F8000CED726CE6383D8CF864C6E57363AAFA570
+:107F9000716E15FA74E7EAE0131680FFDB324F6664
+:107FA0001DD7CFBFBB15F80AF0F14E879683FCE4CE
+:107FB000BB22EF4DF20F7C9F1E6797749641D91636
+:107FC000B33F3B276B3956273EB37418B791FCA8D3
+:107FD000B398F7937229BB95CF9B7DDF886DB88FDF
+:107FE0001495FB9F664F2FD9D6427AC1145A2FD3CE
+:107FF000B41C05C63B3E6FB00EFD52F27CA60FD5F9
+:108000007E89F0B955F8F5E539C9F3FC8BD8F72C22
+:108010003DE815B0CF77B37C341EE819A385FF8BFC
+:10802000F48CBFE019C7C197A991B1F8FEFF2338BE
+:10803000FDFEEB8053E312E017BA8BE017027EEBF4
+:1080400095B0219BF30BB2A7F13DCA9D5F3A7D1F0E
+:1080500066C6E5C7CCF85123E995725D293F7CBE21
+:10806000F63BEC7C3A4BD6FB3EC7F38AD34F3DD26E
+:108070008F29E639F2B699E216478C21E29B47C078
+:108080001E6A41FE22E2EE15FFB2E075B407E5B8C4
+:10809000DFCDD2737FB03C77C5DB3DA718F35058D6
+:1080A000C08CFB986CA4739772B7D3C1F34A3AEFB4
+:1080B000CAA3BC92332CC2C81F5AC9883F021E50A3
+:1080C0007DF4962CA27F681FB060FB7997507BC02F
+:1080D0008B00F1875BAC64BF74629C1AEB6F290D57
+:1080E000621E0CDACD846FF374346F3FF8C2FDCD9D
+:1080F000C3799E85C49BAC56EED761AA367A729C32
+:108100009CBF228B9F734A79E4D9DFA35EBBD64222
+:108110007A2DCA588A097564D33870FEEE2CEE1792
+:10812000203CBBFDDE5491CFE6A940B8AE4AE578CD
+:10813000B9D9C2E3559B418F26BE28F057E6D3F943
+:1081400084BE17A9D7A5A1BE303AABCFDFA0A1FD51
+:108150004FFE72A89F19518EA2DD3633A00F9BD01F
+:108160000E6BBF568BC4D931F887F1BEDB045F6557
+:108170001B18F90F6FC37E6938BE350DE39BB761DD
+:108180007FF4D72EBD36218EA76571FA96EB4BE6AC
+:10819000FB5A96F04B763CA4C5CF23C74F1E0FEC7D
+:1081A000D12A840FC0393C08CFB7454FE797BCCEE2
+:1081B000C806EEF78E6C2822BC93E30DB4CE3FEBDD
+:1081C000A377282007E78CE776BAB47F660B3B9A43
+:1081D0002D4DB4EFD0CFD257D69F5F4EB617313E5C
+:1081E0009FD89EEB2D2923A346A25BB792B07E09B0
+:1081F000AF81E030F72BC24DCABD872C4007E9683C
+:10820000862B84BF1BEE4A2139E6340647205E2DBB
+:10821000CA7253BB4D9827437295DBCD9FBE2EFD8E
+:108220001E89F6B2DF1ADD82F0F25B19D1D3E9DDE7
+:10823000A9443F6C686406E6999DD9656288BF4D84
+:108240004AA404F9D66945ABA3762D296EA423E987
+:108250005778F739EE57F02324617DFEC07F529E98
+:10826000937F67A21D7D1AFEAB07BC3FAD8B54E028
+:1082700078921F801EAD917E54CFE33F4D3A164059
+:108280003BEB2ADDCC799CCE73D9367A7FB464512E
+:108290009C9E0EEDF62BE91C7D906E1A041C9B74BF
+:1082A000C7A85D03E62B213CD1DE423F1956C6F933
+:1082B000759BD67E48F9524D3B12CFBB21860FCA23
+:1082C000970AF68BC30FA2E780E0078CFB3B6A7826
+:1082D000FC3A5594536A7B297FCA2FFC1F99FB22D5
+:1082E0001390AFA49687D84C78FA4F707D635CCF1B
+:1082F000D697D0AE76D4F6162019F8859F509EB743
+:108300005CE7953DEBC8DF21F59438BB73C494045A
+:10831000BFC372EA87762CCE17C1573988065CBE78
+:10832000AD17F22D050D6294831DC3490EA29C4228
+:10833000FE24ED60E457C82752B2ABF720BD3E9251
+:108340005DFD02E76B8067A8D7A35175E5C0FE3DD0
+:10835000091FD90EEDE17FE4BF7B55E0ADF4ABD34F
+:108360008ACA31DF3A53FAEB28AEB748716723DE89
+:10837000BEA7F7915F6E2E0B909F681EFAC3E0D9DF
+:1083800020E87D8EF02FCD117E25F4F7C6C71FD1D2
+:10839000EF1A5F9ECF7A39DFD86E8AE5E5A01FA875
+:1083A00086855361BC46F453E13394D8AF8945A91F
+:1083B0009F7FE797A684F86627DFF76DE2FC1D35FF
+:1083C000413DF2898D16EE9F92FC63DC52EEC71A96
+:1083D00034462B5E8178FEAA81FC1B7F11E7D6E72D
+:1083E0002FCDAA7E290BE064D5F37B6CD11526E254
+:1083F0009BC7411E770BBFCA14B44397310DF3DE00
+:10840000996A2F8CB753E573CD2E4B3DE2CF67426F
+:108410009EC9F7DBB30CB41EF237115F4E21B90BC6
+:10842000EC6334E257C5602917D968F4731D1576DB
+:1084300073D3CD361F8E17D1717EA3647339A564B3
+:10844000F3BC3E59EEB3F304FEC8B821FA7DE2FD59
+:10845000EEE6BEF6EB843EC968BFEBE789BCF03EB2
+:108460003CD6115F4A19E925FE7B95AE9AF852F485
+:10847000039B1BE152FB61C33CDCC727D3AD74FFF8
+:10848000EF76E10776653B687CE9F7BD503CAD7659
+:10849000CD08E297B27D1E1A2863CFF71FEF127C3A
+:1084A0006C17E3EB0D9CB0F23C15950590AFED0A0F
+:1084B0008D08E27AEB84FF01F51BE4AFD167F9394F
+:1084C0003295EB43BB7A460511DF8F1A7C1B67A3FD
+:1084D0003FA7DB407E39A6069F781CC7D993E3C12E
+:1084E000BCA1D3BAE8965F43BB5D277E9E8771A28D
+:1084F0005DC25FDF600C9790DE2CF2241BD2C22598
+:10850000E8077A519C578315CAF03EC3E22BCF1E71
+:108510001B8BA7613F7C7F2CC8F5F2638CE3416025
+:108520002D8F97027C7366E37A5767533C0ECF0515
+:10853000CFE1DDDDA3685FEB0DA2FD0B0AB557A609
+:1085400094CE20B9B0C69481F03FE335529EAFFF80
+:108550003EAE37CED2B9B72C415EB92785F637BBD0
+:10856000F310C549FCF7CEA5FB93FEF94B6F62FFF4
+:10857000207E807225DEEF7D9A450BC91EAE1F1C42
+:108580000AC33A4EF78CF0F0F01FBF8FD324F249A4
+:108590008F1B9886EB8EEE3604FBBB2738D0F8E4B1
+:1085A00040ACE0F28DFCE3F1711A920789719B0BEC
+:1085B000954F1B222577C1FC6B337C73B2E3F445E6
+:1085C000FF9E1CE277EFDEF3D742D22B3A789CE194
+:1085D000B8419B8174E2A8091B67C6E9613FC916CF
+:1085E000F68749E88FC007E3E95ED6575427D2994A
+:1085F0007CFE389BEB21A922AFE0FC7A99B736D5F7
+:1086000084F293BB96705C37BD2F12F1BA7127A22A
+:108610007B313FAB215446F1C0A2A561A24B8077CC
+:1086200018F5FFE31B53393F816DE238732A19E9CE
+:10863000AF73F43C4F628E09F4612EC7A9FD7B1B1A
+:10864000B3090E15CBB91E187D5621BE28E39675C9
+:108650008CF77FBEED68400FEDEBB62B65C05A5925
+:108660005D5B15E551CCDF5C4CE73F4EF0DF5926F2
+:10867000AD6423E2DBF33CEE05F391DEDD80B9620D
+:1086800063882F19511ED66F5718DE3796FB4F8E11
+:1086900013B260629C665C88F36F941B2C4E5F93F0
+:1086A0007208E5054BD22313F12220E257FC7C7EB1
+:1086B0002EE02AF93F41EC1FC841D0A79F44FCA9F6
+:1086C000A8E6F417ED5608CE8DAC99C795841CEA40
+:1086D0005B8F9063EFE9B9DC9C635A47CF305E1E35
+:1086E0001B8B7230C2E520C835E48B03E14578006E
+:1086F000BC90F8B017F701E3359C60E16FC07C0DCA
+:108700004B59B871347FA68E26B9CCE5B399CB67A7
+:108710007C5A2F424E27CBE764799C2C87510CA1C1
+:10872000BC957810EFA7477D64DCD2A09EFB61F377
+:10873000ED981F28CFA5D1A91DCE1B1BD3B7FC8751
+:10874000CD66F76558F6B2C136F42F55DD5E00FBF5
+:10875000F7ABFC9E720AC0692BBCEF12FAF9E40277
+:10876000BE7F97C80332A85E5666C373EA257B3A7C
+:108770009AC928AF5BC2B72B15FA8DC17E5CFEF596
+:10878000F537B3366B5CFFEA5D16922F675F48A53D
+:10879000FB684CF5153960BCAC3F829E0EE5D3BB3F
+:1087A0005249BE9F16FCDE29FD166C259DD76778C1
+:1087B000CE998875D579E8FF65CAC43C46F7B4B947
+:1087C000DED8E818C86F2FEA8B7B6FE6786622390F
+:1087D0007BD611B913CBB01ECA333E25CEDDBF63A5
+:1087E0007CD98F303FC06BF370A8FACA506F30E964
+:1087F00017DF6CD6E37DFDA5D1BB601F8D0536CAA2
+:108800005FAE297AE777B740F9831D06BAE738EFFC
+:10881000B1A983C2D84DD55CFDC9E7794143C2FDFA
+:10882000B905DB13CB8DA1C4B23FE9BEFC9277B68C
+:10883000BEB63FAE3ED395EAA4F377330FE65F337F
+:10884000FDF706F9FAE197F2F9D765C1D7F60FA35C
+:10885000FCB57C17CFCB31A25E3313F1A19F7E6FA5
+:108860000ABDC6646A3E8179F0A6174D74AFFE4416
+:10887000B66F18F66FD2450FE0799A8A4E8D463959
+:10888000585DF4778AA79DFD31F3207CCE5AAA4823
+:10889000BF39BBD1E246FBACB3D04678D0B947096B
+:1088A0002A5C7F9F34B602E3A7B407E6DF70FD07BA
+:1088B000FCD20633F37BF860BDB890CF68644FBD3F
+:1088C00037D96A5F0EFDEA377079DBC07AD3900F33
+:1088D000CC7771FEE3D73F6534C33F8BDBB4112DFA
+:1088E000B0DE055E2BDDD751BF50E99EFA2A1C325F
+:1088F0004EFFAF72093FA93962ACC2F9FFBEB8168C
+:108900005D63D2CF6532F834BC1766D85916CE8372
+:10891000577397BC44764E5F1C7A37E75B73EFDA88
+:108920004BEF9529B5B4DFF760BF089797369A6883
+:10893000BFEF15D8C8CE7CAF8BDBBF73EDC6A09957
+:10894000F48D7319789FF6BD2E03DD633F1F1ED78C
+:10895000D1BDD6F737BF427EB8F7199F37B0434F26
+:10896000FACAFBF6684518E1E86E4E437DB77EC350
+:108970003CBA173BB74BEF457E36B7EB8E5F5F894E
+:10898000FEA329B796E396AE712CCE72DB62F55248
+:108990004F55D32B1F473ABCE68BF1BDD7A0BED4B1
+:1089A000057452CCF3EE514FDFDF751DE9A5732737
+:1089B0005B1DB82FF7E6C726A0FC787F722EDDE39B
+:1089C0009DFBB4C2F0D30D731D4BB2F0FD5C45F5B9
+:1089D000F6874FCCC5FD6D5545364F18FBFD564FFC
+:1089E0007802747533CACFC62E03E9BDFBA7BCFD60
+:1089F000BB5B9C31BA52A66CB8691CB6FF9981DA90
+:108A0000F7E93B9B6F94F8C2C215685771B825D33C
+:108A100099A9686909AE2B99DEE62E6F2EE1F1ABBC
+:108A2000AF46776C33BFD7DBE652D897BAAF4477FF
+:108A300077BBC65E3CDDB1FCF4047BEA7CFE16200D
+:108A40003C95FE7FB387698FD928DEAB29C07F773D
+:108A5000B8F8BDF51D2E7EBF4DFD8F45DBDF00F85C
+:108A600054BA7C5DB88E22A695A1DC7447EDD5780A
+:108A700017C926F439B6D924ED00D2EFD767B2C7AB
+:108A8000D7C4F91F422E6E27011F781CC739FD87F6
+:108A9000BF1FC0736A2A3C351AFDBEFE739F51BCCE
+:108AA000D0D6C3E3CD364F94E2F006A797F050F24C
+:108AB00077BF87CB9FF3E0E5E2F73BFCCE288DF351
+:108AC000560EE7CF9D22BEB2698995FCA99B9C41B9
+:108AD0000BF72F0418CAA749957A1E2713FAD68DCB
+:108AE000C21F692E7F89617C8C5DCDF3C2DE287F39
+:108AF00049CD80F2AF2BAFF5D07DBEF247DA07E368
+:108B0000BEAF3688FA21F4BD8D7FD7AAA87E914BDF
+:108B1000EF46FA9E54CEF322597D1AF94DDE287F96
+:108B2000D7797BDCFABDCCECB601DE4C01628DCF8F
+:108B3000C3BBE96A8BDB16873F9F7428B55CEF7572
+:108B40000F9A368AFB45481E9727C26391CB48F39C
+:108B50003E925D7508E17CCD37F9799C7CDA14444E
+:108B60003E7852DC8F49865FC425F0471D9110B7CF
+:108B7000771A438528273F5412FBCD6FD753DC7CEF
+:108B80005EBBC28230DFC9279E2F447EFEC163CF09
+:108B900017CE8C5B4F723FF93C29E7137EC1643FCF
+:108BA000EF40FE5DD9EECC06E6330F89B53F53FFAB
+:108BB00037F2EFCEEC11FE614D1BEA447B48B44F17
+:108BC0001E2F3397F36B65A7427E0FE9DF3C76F0EB
+:108BD000118CA4F49D9FA5A758179FCF289FE3C48D
+:108BE000B94DC57383AD58DA7979A0F31A881E7F21
+:108BF00021E4903CB763ED4306211C8D4D3695F181
+:108C00007B6AA5A8AF7731AB07E9E9AF22AFD56999
+:108C10008527E869C65C970DF999FC2EC00FAD69F0
+:108C2000DBF0F95791F7EAB4C213C629C82DA5F1B4
+:108C3000FEAAF3925DF7437D07DD5F74093AC966CA
+:108C40006145C14F1D2C784EA1BCAFF6447867B585
+:108C5000723912AD3392FC9270BF6AE69D64BFF622
+:108C6000735E1B108F722BF9BBC939C5C2DF11A10E
+:108C70003882A592D9D1BE6FBD3240EB90E7E5E7CF
+:108C8000CD99D2A390FE8CF92F29E9142F0D8827B6
+:108C9000B3A5B3BEF8418AB0775952BC201BF46E1D
+:108CA0006C27D70965CAA3B9CF11EA28E1F156D2DA
+:108CB0004B715C7C3F73A44AFE766C671C7361FC4D
+:108CC000EBC35391973849BEAFB7F61B9F9884F713
+:108CD00083F01C403EA25EC83C8684FB419B419FC2
+:108CE000463B4DC67FF5BA50998BEC93DE08FA4FA0
+:108CF0008C156637CADB147DA814CF2F391E0CEDF6
+:108D00008A791E42BE03E58CBCFFD3B464BC17E372
+:108D100054A07F04CC787E93F9F935DD5545EF9565
+:108D200029A52D885FFEA58CBE5330BEA79BF2A45B
+:108D3000FCB55C1FF3EF3C6A6480BF33853F870955
+:108D4000FF739638D76342FF8EC5BB225B30EFBB03
+:108D5000735E3EDDF74DCE2BF9AAF1CE33A900901C
+:108D6000CBE2E25883CC5CCE88F397F42DE35AA98A
+:108D700023BDC5A889FF2E3BFA2BEBD8AF90371245
+:108D80003878CF3FCE1B997613E68D9851CB17F5E7
+:108D9000B80C90A37DF7F92C6E8A7BF5D5E3771894
+:108DA000CC3B15717F8FDD74ED50CA3715E5D7D6F2
+:108DB00062DEF87D1696305FFCFAD4A4F10D30BE69
+:108DC000CD2DDA074EDE70AD4AF15F513F712DE6D1
+:108DD000C9DC67481C8F5050DE3F34C7E6BB7DF3CB
+:108DE000867BD6E6C7E439C8F78D396363727DD5D3
+:108DF000DB933A2E73237D7D4AF9BB523EFB9D3CAB
+:108E00008F24998F3D9AA348BD78028ADC55D317E9
+:108E1000D2770BFAE2BF3D751AEAC332FEEB5FEA86
+:108E2000A53C5ED007B6E7903E70EABDBD0CF5CE1E
+:108E3000936417F8CFA9DC4F047A057E87C6DC530C
+:108E400045FE504C4F1D1677FEF3859C421D1EE9D2
+:108E5000C1BFF93B8FE9B13E57EBCEC98CD987C969
+:108E6000EB7D2D87E7B9FB4BAB37223F608F2AF4B0
+:108E70001DA835A59F90DED1F4C2B563E3F3D0E71A
+:108E8000ED7C90E7316F37F4BBFFD772F877629AC9
+:108E90005E7896FC9D2783FCFA4CBD1A5C8D7A683F
+:108EA0007DBD0E352F561EACBB85F481E9B00FD8C1
+:108EB000572887C3C7BF7D6A00F3E2FDF09F02AF6A
+:108EC0003679E7905DB069BAD986711C7FE9CC85A7
+:108ED00084FF76AB86FB4F5E672CCE6CA5FBCB6B1D
+:108EE000761A6A518FAA00BDE95F61BD05E9136B6F
+:108EF0003DC097F2F4DD653FB061DCBD7FB9ECCFDA
+:108F0000E3E7D8A67803DF2A273F278BCFE329DAC8
+:108F1000C9F5B3A339C604BFFAD11C95E07975A091
+:108F2000773CE2DC1E3592827AB29F691FA3FDCBAB
+:108F3000BC3637F977198FB33B97B9C9BF6B764603
+:108F4000EEBE8CF42895E2CCD2BE38FD02F78B4DF4
+:108F5000CDF59D46FCA8D0471EF816C2ED6E55F81B
+:108F600089399F299C6A1B837E2C8B33F240AD9BF1
+:108F7000F26FC82F31E81B6D740E7B9CCC8EF019FC
+:108F80001FA85395383923F9C6F8BEFB3B4EF29F14
+:108F90005673B6C686C169BD6726146DFB3223A61B
+:108FA000271CFCFB34155F4AFD4167F6919D533346
+:108FB0001DEC46C4BB95D1033AF4D73B7B497F6C8B
+:108FC0000C29344F63E92F293F6E81C8C3EACB8750
+:108FD0005223941F66CE4D117EA6368E97AC97EC29
+:108FE00062F614873FC84DCA1B8BE9F12DD44E8E13
+:108FF0006714718646E1C70140517D46AE22C65DC9
+:109000009E189F10F332D55D11EF77583F19240950
+:10901000ADCB9D86EBBDD7EACDCF85F6C7EA75040B
+:10902000A263ED29F45DAAF54AAF86FEC84019CFC8
+:10903000A74DC6A33231EFA07DD109284FA22F0C36
+:10904000944FCBF367378EBD84F2D0CB777E3C0153
+:10905000F183D532A2C7A69D17974F5B81E731F602
+:10906000FFA17C5A8FA26D83E775B98EC47C5A0F1D
+:109070003F2F19D74CCEA33D9D135679BE5B64CBD1
+:109080006368B7EF34519EC8A49DAF1C46BFE62469
+:10909000330B519C37497F38E29CEACD8579CE7CF1
+:1090A000F4DE96150CF3B09FF3F07B9989FAC0407B
+:1090B000F600C53AE2ECC699126FBE267B40F26B11
+:1090C000BFB0AF3E54A2F796E0FE76EBEDFDDDA318
+:1090D000F1E7CAF8D80079203DFDE781C87B66B585
+:1090E00091E284B8D55D7D74F0D5E2604B5176F69F
+:1090F000130753455E97AA70D6C11C3CEF47C6C103
+:10910000D4EE1114DF32C5E26061D64F1C4C1571EC
+:10911000A55506AD8EFC34BB4D6E6E477B897FB581
+:1091200075677A90BFF9E79F7C063F05A03A26B89D
+:10913000506F6813F06FB8F838D883B9FDC4C1B662
+:109140000ABDEDDD525DD80870DDCA38FF0DF4C8E8
+:1091500078988EECDAE83D05B46E658A99D6FDEE16
+:109160001ED336F44FCD9271AE3DDCBF364BC4B347
+:10917000DE9D5242FEA781E03CAB3D315EF0330103
+:10918000E7B3962AF2D3DF79FF64F2CFCF41FFFE37
+:1091900090D87D0926FC7CEE767E9FDEBD5DA1EF3A
+:1091A00099229AE84827B5D3774D17001BDD84AC88
+:1091B0003700587305BC56740AEA43EE362883D24A
+:1091C000AFAE56032E68B7F5700AF9155739DD2290
+:1091D0006F8DC79D036B95E0303E2E7DC72CD0A6CA
+:1091E000D3709C5772B93FEACFB9C67EBF23D16610
+:1091F00010F163315F0B837387A74EE1CF55E23BDC
+:1092000079C9F090E3B5199ACDE8DF8B16F0EFA19C
+:109210009C356AD3C9EF9C5E42DF3D6A4B6D6EAFF1
+:10922000E5F544B3672D512FD57F43E50A2973A790
+:10923000E37A77E772FD2619CEB33B12CBC9719F53
+:10924000E47B5AB3986F78CE90F3EF31ED16FCF6CD
+:10925000EC9A62712E1E8AA3B419DCBF29A6F829E4
+:10926000FFAE514B3E879BAE803F073B6AE8FB74E5
+:10927000402F5C8F637CFD83BFE154905EDA1C1C41
+:109280006FFFA7EB4E5EEFFBB9251CBE0E4EAF6D18
+:10929000AB952087175FF7C5FA490C795F2F5F7C84
+:1092A00057F13C1E2EA67EC41F02F71888EE765991
+:1092B000F8FD4BC9AF28B107ED4F61EF0E42651ABB
+:1092C000E3A12756D2F78936D50F4EC378E9F8A91E
+:1092D00036DA47D31E7EBFB77169A410F1BAA93A36
+:1092E00052D2DC0F5C710255F2576837D3C9F87758
+:1092F0006EDA13E37FC971DDB5195A415E26DA4B88
+:10930000EF76BF82E7DD6D21F9DAB434FA38FA0F6F
+:109310007C19BEA1587FEAAEB727286EEA46FAFC50
+:1093200099DDC3E95EE2CCB6C47B5E6C6D625C9194
+:10933000B5A7F3FB6C9D89EFF13E5342BFF3E28C7E
+:109340005CBF596FF48D40FDF39A6FF23C8A8FE653
+:10935000E9189EEB47167EFE817B5205BFF694C44A
+:10936000CB83AA01CF17DA8DC4783ECF1F95ED1BB2
+:10937000F17CE15C1BC4F97EF4EC152578BEA7BA3C
+:10938000AF28C1F35D6FE8D0903E52B27DD7629CAA
+:10939000EDF8B55ED20F65BEECC5E2DDB4BCAFD76B
+:1093A0003FF755E5719D9CFF2BCA63FC8BF79BEC47
+:1093B000F9BB3E6021F9C2EFB5C6FC7727E9FB5E39
+:1093C00067CEE914E4C7038DF789B0975C66164051
+:1093D0003DACA23A42FD2AFEA663A80F4A3D387969
+:1093E000FD8BC5B9AEC8D30EA35D28FDBDF5626C7B
+:1093F00073F053AE6F3FAA903FD7EC0EA48D23FBC2
+:109400006AF6E57AE22FFF4AF725588F62473B65F7
+:10941000DEA32D547F7AE72CAAD799C361B4C71A6B
+:10942000A11ECBABAE4ECC7F36EEE0F12069FFC281
+:109430003ADEC275A438A346C4CF26D4AF61894DA5
+:109440002AF77B37399927C0501F4EB417655C77D0
+:1094500093977F3F66538F42DF91CA32FA8AF3F1C6
+:109460005C93E2BBF7E769DD887732CEBE204BEB39
+:10947000CCE3F9678508A79FE2A2A01C31C87B5BFB
+:1094800089F70F0FEEBD99F4A1CF997750FFF968D6
+:10949000C184F8FB1C714F748EB8278A7C3A9CC437
+:1094A000A7E3CB0D71F968E1FEF20AE2F2D1E2FB2B
+:1094B000C5E7A38513F819A7FF6CFD228A7BFB0182
+:1094C000CF978C89E16103137F1BA2EFD2FD97ED4B
+:1094D00026F2AB35887C547FFD31B257FC789F86ED
+:1094E000D3A3C6EF61737DA801EC40CACB0D25E67E
+:1094F000AD1EFC9AE953B61BC87FFE66123DCA7DBD
+:10950000C97D34F4289C7E92D6996CFF26FBC1A5B8
+:10951000FD7AB17CE9FDAF591E7E55BEF4D9D7C4A2
+:1095200097CE8B270C8DA679BE8678C207EE8E2C3F
+:109530007429CAFCE1F6DD3C7F7882DEA6F1F8A54D
+:109540009EE73724C771DD13284E29E3C6E6E7F40A
+:10955000C1E5C5D4DE83795F8DBB5329DFA0DE5D15
+:109560004F7A7772FC723EEB9E8047F1397B9DEE1D
+:109570006FFD4FF306F2F3C57789DDACF82BE60DEE
+:109580000CC9FF0AF1CB976C9F66F8E2F0A57A242C
+:1095900028F02307CEEB2ACBE7F89722F24BCC6AD0
+:1095A0008039E2FA0FD4EFCA7CAE1FBF24F291EEED
+:1095B0004B4DA17BFF2E23BFAFE0D2F1BC2996EB30
+:1095C000BD2A3F13E5013FCF875FF80EC3FB670F4E
+:1095D0001B42740F3FD068F3A01C937E2739FE8393
+:1095E000397C3F174B47DEFCFF5DFE71AB9CEF62A1
+:1095F000E36F1B000671F4954C0F03F51B88BF2C1D
+:10960000C8F7CEC9277B5C1B4D718B8BE44B29E5DA
+:10961000C0B7514EEF30B9D17E403F0AC9C7B53906
+:10962000D2FEE6DF25B8AF80E4D747166E4FC8FB01
+:109630003F72FF3F1910DEFF9C9EF76E96378078D1
+:109640007EBC4AA3FB03AB52B97C893EC1F387922F
+:10965000EFC124CB15798F43CE777FFEFF2D5F7D41
+:1096600058C2E77FC85741CE92FD32609CF6BCFEDF
+:109670000191C7D9AB897C19BA0F21D7E5EFE579FC
+:1096800077BF10EB93EFD70939F059BE1642BC3AB9
+:10969000F507B319E3A0E5E59C7F36796D144768BB
+:1096A0000AF1FC9AA6A58CEC7E79DFB5D2E5DB85C4
+:1096B000FD56BD6DA3EF9E36EDDCDA3E98F20F7CD1
+:1096C000A4DF9DFE037F7F22DBB707DBF9974612FD
+:1096D000E215155F7EBAB2B69CD64B76BBD39478B2
+:1096E0008F2892CFF386E4F34F7DF005FB04FA9DBB
+:1096F000AAE779DE7EA766AFA2BC03EE0F4F71F733
+:10970000921FA8690709094649A758FFA37CC29B75
+:10971000A61D5565F4FD8190A58CBE5FF347FEBD87
+:10972000A75377E506F5DC7FFE5B5C6F6A79F07A1C
+:10973000D4338B601E54494F755F5F46FEC124BA17
+:1097400093F4D6777FF4BBE660AB12A3C7F5062E81
+:1097500027A57C7B39DFCDFDD54E913FD83399CD00
+:10976000B6C5CA3667625EE58ABC6B5FC6F5BC9C4F
+:10977000CFE30532CE5E6C06EB73F0F978582CE23D
+:10978000EC93457E040B98637911832F1C6797EB4C
+:10979000936519674F39277E5FC06E24BC486DE71B
+:1097A0007C83015EA09E7D75B4773CDEDB1ADA19FE
+:1097B000BE1AE13508C14F79AA91BB2FC3F845867F
+:1097C0007A35C62FB62C19B30FE3AAEAEADE6FE0AA
+:1097D000D1B83BECD5686256BABCBA02E22FCDA52F
+:1097E00088FFD5BF35F07CC6D52924EF3B0B1B285D
+:1097F0009FF1F4DBA6847B3AC9CF005BEE42BFD178
+:10980000E0F637297E90BA43E9374FB5AAC046FB48
+:10981000C4F6E8874A6DEF0D54A25FE51E857F3BD5
+:109820001256AFB8D0FE5775A877CCDAC9EF7DCF06
+:10983000EA70549B899F2A3CFE72B593F8A4BAFA49
+:10984000061DDA696A0BA3EFB45516703FF6B04EE9
+:10985000BB0ECFFDDFBED0F71B571B5E10CB8F4377
+:1098600070359AA2075CC5B178A0CC8B1BE8FBE7EA
+:10987000521E25EBB3E7E9B1421EF5E9F349783C06
+:10988000503F89DF129FFFCDC0480FFB37C54CF713
+:10989000C1245EB7C93CFF2FB85FB748E4DB1C5B4F
+:1098A000F39FA3F97D77194F09F23C294364651EA4
+:1098B000C12BF2CD00EE7B8743D73492FC614D344F
+:1098C000CE6AFE7DB5A2F621CB2BCBF169670A2CBF
+:1098D000E1D8AE0545489701C08361FDE081B180C4
+:1098E000DF575157A7D0B9A9EBE8CBD24C7564D15B
+:1098F000B9A90FF2F361057C3F329E2BFD969FE5DF
+:10990000FB6E463CECBBBFB5C4CAEF6F89FBC1A977
+:109910004BDE7E1AEF456D11FEE37D7B2EA5DF85C4
+:1099200038BB5A55504F3DEBA8A3DF41AA2BE0FAB4
+:1099300052AADACBECB678FCDC4779B58377F3FC36
+:109940004055DC7F56573BB7223C6B9C3ECA1FFEFE
+:10995000465B987E3A618FFD38C5E9402FA27BAE09
+:10996000275F50A45E94200FA5DD966C8FDD51F02B
+:10997000BFAB2705E47C5FD5CE6289F6665F7B6965
+:109980003F26DB1349FD07D27F981648C8937940DC
+:109990009CBB94EFB98237CAFC99BEFBCE2C68C140
+:1099A000FB12239028C7C6F28898C82FDAA0583D2A
+:1099B000A82F0D9447D497E7C39A2FE3FEC8E62B50
+:1099C000F029F390649E9105F34D32CECF37B1600C
+:1099D000BE4906FE7E06BF372DF3455A0D6ECA3FBF
+:1099E00009FC98511C5199524BFEBA74AF91F0EF9B
+:1099F0000C0B6EC4EFC707A6D9E87E38DE2742BC41
+:109A00008F2A2E1A777CAD26DBEBB07DDF7708EB53
+:109A100018D5A70FD572500FB3403D7E1FB9EFBECA
+:109A2000F46CFEBDF6E47C1399F724E3C0B9C39F40
+:109A300053D02F8A6E7FCA3FF881E857CCC7E9FC24
+:109A4000BE9BF846562BCF6B8A5EC9ECE897AF9663
+:109A5000FCC79C78AEEB155F31D2E77A2BFF5E40F6
+:109A600017F3B4EBA17C77C160EED761EEBD3A622B
+:109A7000D81DF47B0F9B9CDA6B0599317C92EB62CD
+:109A80001BF8BECFE0FD302536DF99797F2B44FDF2
+:109A9000AABAC7C4F13269FE4D7DDF6B095A509EE8
+:109AA000FCB980F1EF8C26E9BBF2F96789FF822FC0
+:109AB000CBF907DA9FC4CF0BE9F112FF06C2B7401A
+:109AC000B538A72329A47F487CDBB76C3B7D877022
+:109AD000FFB2103DCF5894901EEFD55AA233903369
+:109AE0001EDFF25F37E1F73CCEA4460BF17B20D1BD
+:109AF00087F55E2A67468F6099155DC1CBC3A25B6F
+:109B0000F0FB20590FBFF82D2AE379E63276AE201C
+:109B1000F4AD808DBECBB5B217E55679521E4BD24F
+:109B2000770C52C4EF0765DB8CA44F668BB81EAB75
+:109B3000117A3D46A0A0DC9A5346713C1B73EFE8B6
+:109B4000C5FA7C13FFDE0103FCC7FA61C53C1F8226
+:109B5000F17DB37CE19F669100FD1E60B183FAF751
+:109B6000F1F11D26119FE2F31F7A96C711655E2F52
+:109B700063F602D4876C6E965096DF0161AABD0031
+:109B8000EFFDB74ABF9F28BF98E2CB2D8CD3970E2D
+:109B90005DFBC391F4BB24CFFD6828F2CDEB8C892B
+:109BA000DF7596CF3F14717BE58CF87EE11D29BEF1
+:109BB000218599F8BB243326E0A768A76754191DAF
+:109BC000A4BF3DA1473E9529F0C3318DAFCF51E3EE
+:109BD00055F0F740E4F703337D2AF90998AF538F26
+:109BE0007235F3B897F2051BCCD142FCDD9637CC29
+:109BF000BECB70FCB37547EFA47861EEA12398DF6C
+:109C000071C8D0313E0DE548B1F89E040664A17CD0
+:109C100020AF88ECC13EFE304CA178E6A469FCDEA2
+:109C2000EB441652F19C27D8F93DAC09E5C59E5688
+:109C3000986F92C80F9970D89B86FC6DC277222AC4
+:109C4000FFDE45548DCFC7904FE632B8E3E9E17AA5
+:109C5000775C99E1778E13CB377A12CBDFAAFC625F
+:109C6000787C7994A24DC47DBEA888EF46007FE140
+:109C7000FBE279873F17F6DCA52E662E427F8553DF
+:109C800009A0BD70E9F3B9146779BE9251396BBB75
+:109C9000799B397EFFEB743C0E2DFCE0F2778DB0A2
+:109CA0000EE5ED737FC8227865D980DF3A89FB1015
+:109CB000BEED1374BB4FD069459ED98AFC7F9FC10E
+:109CC000BD99F03CD5EC463FD5DE54237D37B675C3
+:109CD00021FF5D0425CDCC8C30AE7E262F433BF694
+:109CE0004DA8D75798299F649FC8D36EFDB14A7E6F
+:109CF0002EACC7EFF9EAEFB5927FBB26ADF47B58E7
+:109D0000AF4F33D23D89BDA9153E311F7DCFFED166
+:109D10005473187F5F21F9FB9D87705D083758D712
+:109D2000637C1D448FFA0A23E9E1F2DE3A8C43F1A9
+:109D3000377DAE99E6DBE7B0EF45BC6BFD80343D87
+:109D4000A8AF7463FE97C4EF9AB44AFABD12A0BEDE
+:109D5000A1F1DF67D76779DCFCBE2DFF1D8ED2BE77
+:109D6000DFE58069A11DFE861123BAE5F1BC020979
+:109D700077A66AD83E87C932BF6F96D557AE52E9EB
+:109D8000BB418A2CB750F921512FBF37FA4EA19B06
+:109D9000DF4BEE79E53F106F87A6015CE09C3C2924
+:109DA000FDDF777AB290F3F7F3CFAFC2857E7F0500
+:109DB000F73932B6FF7D0E8FCB1B57EEE75C8288FA
+:109DC0006FC9E7B2CFE271A39FEDC2E371B8CA7D5C
+:109DD000E873393CFBF691D1FF3EDE11FB0889FBAD
+:109DE000D9C9F5070B755FF73EFBC5BF7F7A9F5951
+:109DF00089FBFC1AD71951BE8675EA0B617DB6D86E
+:109E0000FAE867C72A906F72FC9B28F29B59696237
+:109E10005E12ABF498B9BE989887749DB2B90DE5FF
+:109E2000EB4322CEFD8AA0AB03293F198AFAD62B39
+:109E3000334AF613BF1DD4D286C425F9B3E4FF67B5
+:109E4000738E566019E44014E5D59D830FCDC0C1D3
+:109E5000F73B1E1A8AF20AF8E6C78599E7AF53D294
+:109E60006FDF7A817E918E24FD26AF5FD211BB29F0
+:109E700044099D5D2C4C4F17E3F9F3A097D0F7D11F
+:109E800099BB20B63F20F209E666BE8F9600ADFB77
+:109E90003AC7039437682DF6198B605DD32FFB9872
+:109EA000BEA3C45C75C3518EC07A4D4563FFEFD627
+:109EB0000BFC2907DF4B3D3F59AFBF501EB95C6714
+:109EC000323F94EB51A66C273DDE0F7A3CCF3357DF
+:109ED00088DFFBEB759C0FEF5448AF6F023983723C
+:109EE0004A7ECFF79A126B1B7E2F729781FB53032A
+:109EF000CF9ADC89DF574ACE3717F6C45226ED05D4
+:109F0000FE1D89463BFF7E9290339D770C96DF576E
+:109F1000E2F210E454C2F795EADC89DF571AC05E1A
+:109F200000BB80F433364827EC022EA73BAF74DB2E
+:109F3000038CFCCFFCF7256F310A7D10609115FB77
+:109F4000FE1BD801F45DBB1B8A8AC5F7B582FCF7FE
+:109F50003C84FE9FEC8F4EC9F6DD8478327BA4569C
+:109F6000883F2D33CBC8FDCD806F9B7B19A64D3626
+:109F70003F8ADF47BD9E35BFA51B42F8360DDB4F3C
+:109F8000BFF463FEDDD418BE7DBB2893CB2514320D
+:109F900017A2E3234EDF0C1CA7D311FA237E3F7DCB
+:109FA000538F89E02DF35293E93B6E3DC70D7C3D05
+:109FB0004EBD9ED63387F03F693D1783F7F1789504
+:109FC000CD387E0F84FF78FF23754C0CFF4729BEE8
+:109FD0003B70DE3E3A58C9EDAEF3D6ADB7D179DF6E
+:109FE0007C0B8FCBF953A49DAC4DCAC9423F249F33
+:109FF000FFE6D51C2F6EAEE37944937B1A290EC77A
+:10A000006A785CCD03FFA3DF8711FC6D9AB3CC8027
+:10A01000A8F739FB9E01FD9CD32625C6DFA69BAF82
+:10A02000A378DFCDD30C09BF8F29E1305DFCFEF6AC
+:10A03000F4A4DFC54C864B72DCAE8F1F88FDE6E1D1
+:10A04000EFC5C0339FF17B3739E277CC3614F5C5C5
+:10A05000F7867FC5F8DEC31C8F2E2EBEB7DF10A596
+:10A06000EF3BBC9C3977F342A09BE13F1D49DF7B6E
+:10A07000BF366BDEA3EBA0FCB34D9750F9E5ACEF18
+:10A080002E3E84F55B4AA85CA3FB7806D24169C5E5
+:10A090002D13F1FBF8FB2D7C1C97D5D789BF9BE2D4
+:10A0A0001A3D780CE60FD718A3D4EE86CB1A2FC72B
+:10A0B0007CA81A2B2FBF5EF6FB31541E2CCA635EA0
+:10A0C000BC04CBFB958F67F4171FBCB45409E3EFB6
+:10A0D000A3D5A4F3F693C63C918BFEA29A6A5EBE0A
+:10A0E000D453B57A08D6EB3E99D19F3EF286B0871D
+:10A0F000A47EED15F4FEBC76B40DEF117A6D8A07DF
+:10A10000EF8B782B8FF2EFAA99795E89572B53F159
+:10A11000BB9BD51AF7F38EB7B5E4205FBCC9672C9B
+:10A12000477FBEDD56DC867AF1A0CAAAB178DEE3AD
+:10A13000CD8CF009E8EA10D1D5151F17A62132DB26
+:10A1400012E94AE2ED64494F35897403FCE0F7FCFB
+:10A150001C13E901C67D87F8C75589F2AA8FDF274E
+:10A16000D16D323E0EA817B0443E18C3D390128F63
+:10A170009F5D48AF9C7E3FC2751875BD6E7C5FA425
+:10A18000782EA1449B01F40BB93E745BB231E7AF6A
+:10A190000BFF54A98FF315D8ED59382FAF877E1ACE
+:10A1A000FE989D5C17CCFF05C167255F4F97D22CA9
+:10A1B0007E1F85DB61D2DFD124F6FBDF798429C3E2
+:10A1C00000800000000000001F8B0800000000005D
+:10A1D000000BE53D097894D5B5F79F7FB6249364CD
+:10A1E000929090100893044280244CC222CAE2B09C
+:10A1F00004A32C0E9B8022FE095BC84202E833B602
+:10A20000D80C844D8B6DA8A8A8A80302A2450C0AFF
+:10A21000881AE8B088585163D5D6A5D244ADEC1061
+:10A2200083B6D8FAEA3BE7DC7B33F3FF498AF4BD17
+:10A23000F77D7DDF83DACBFDEF7ECEB9E79C7BCE69
+:10A24000B977D83ECBB9C64C467F7E48636C503850
+:10A25000F385E53196C8DC6B54153E76CAEDE3CD47
+:10A26000C6D2AE315FF5650C3FFD703D63172D8E94
+:10A27000354A346315E15139AC1F6353ECDE076C8A
+:10A2800026C6A6C6CCB630E8671AF3ED894967EC56
+:10A2900085082DDA3510DA997CFB1B15C6E6328F5E
+:10A2A00095C1F76CC5E3C4EF8C056050C616E23F5C
+:10A2B0005DC17EBB415F0CE6B1D0EE08A839F06FFE
+:10A2C0000FEBD129813145D4638679437D0F8B858E
+:10A2D000F2FA37BE53B0FEAA3A05C7E9CA1A92305D
+:10A2E0004D6295946F5D97613D3591B856C69A73EE
+:10A2F0006DFECD388819FE1BC0D8F1C20CFFFD4A97
+:10A30000705EC7159669867A3E25DCBD3595B1BF6E
+:10A3100086C1FAE17B2701872145FF318145B59D43
+:10A320006F959DD7BB3B3C6A33A6D76784AF30455A
+:10A3300063FB143FD6EF140E694E70FE7F3531CDAE
+:10A340000EF3BD5B8575A8B88EE6656618EF0956F5
+:10A350004BF9492E5834C0AF73EB7A7C0AE2C96AD4
+:10A3600052EEF03A604DF8E7FA603AC905008D27E1
+:10A3700070292C21086FE652981DF245222FE1DD4D
+:10A38000C9EAEA8AFD18E15C64B735117CD7E47B41
+:10A390001AEDC1EFACF6114F683F1DD55300AEC9A1
+:10A3A000B16DE10FF3A7F98DAF1AE5FD320EC717B6
+:10A3B000F8B82792F031FE9E11F45D9994A934C249
+:10A3C000BC4615B8288D1DF09E9965135EA6D7650D
+:10A3D00005F1F475BC368BE8CBDC387022E0F6ED85
+:10A3E00081CFE46A507EC2C48AB19E113E25089F87
+:10A3F000816DE1D34A7F06387434FFD722BC6538BB
+:10A40000EE79A5611016C677710AB86BA9889F18F6
+:10A4100067EA881884FBF7302ED0FD142C023C3FED
+:10A4200096A0DD89EDA6316FBE19D61B5BA059340D
+:10A43000070D67C2F92C76F2F9E4AB0EA2CB961D9C
+:10A440008ADF06F5467B7A3F3214F215C72CCC0F13
+:10A45000E52D8CD36DCB46D5EF037A99FFE64B8380
+:10A460006087B12F049DF6DA60622E890FF8AFB7CE
+:10A470003F9CB93283F9BEDB6375F9ECBA2EBAFAA8
+:10A48000FDF6A5E9CA73037D74E5FD8FE5E9F203E6
+:10A490001BAED3D5BFE6A391BAFCB58D37E9EA0F61
+:10A4A000393549971FD67CABAE7E4D18EC9F7E08A0
+:10A4B0006E4F4326C0658EC0D3F5978B74EDCE46A4
+:10A4C0008D3986FB6ACEDAF9E3705F8D60A5BA7EBE
+:10A4D00058ADE573A4CB4AF88BF89CC7BCD101807A
+:10A4E000573E6B3E9A0CF05BE857DC08B7F91B78D7
+:10A4F0003DD96EC1BE45236330F5EBBF9732733053
+:10A500000FFD54FD71D36F8F84948F76169A90FE51
+:10A51000EA5C919D906ED835EC9A1FD476F1EB0EE3
+:10A5200020FE3E50DD36F8B4F84D95F6C1E2E71551
+:10A530003F837E3358CF68CC571C53991FF07F92CE
+:10A54000553E3C14D2BF56FB7F7BA467103EB644F9
+:10A550003D9EC35C7A3C4764EAF11CE9D6E3397A54
+:10A56000B01ECF311E3D9EE30AF4788EF7EAF1DC8F
+:10A5700079BA1ECF499A1ECFC9C57A3C77ABD4E3CE
+:10A58000B97B951E9FA9BE123DFE0CF897FC377D46
+:10A59000CD625DBD563AF0168FC3B467ED4F74FDC2
+:10A5A00096AA6556660AD2830FFE223DF462CC1D40
+:10A5B00000382F043C045C6DE9A0B87EDDAAE47F7E
+:10A5C000810E9A11FF1121F85767466BEDF06B99D8
+:10A5D0004ABC82BCFC8B0BF84878AAF61DA6D37B3C
+:10A5E0007D9D6206BEC1BC85BDBC9141BE6794A77E
+:10A5F000528EA23C320F0ACAA38EF85A1B393A4136
+:10A60000CA9F0EE4A8AB5B900F02403E665CCE335F
+:10A61000B6D684F39821E8FA5038A7CB4B58742D5E
+:10A62000D4833A83615E1FE3BC619C8FC3FB1EC170
+:10A630007D7A2BABB360FF335903A5B35833A51A0A
+:10A640007392DE50C4DC94CE615E4ADFB66BC9A95A
+:10A65000C037CBEC8D8350EFF84BE17B27149CCCBB
+:10A66000F1389C6C877095FCFA7DFC27D4F3A67AB0
+:10A67000D353213FDAEEBAF321F87408E504F2DF90
+:10A680007171345F66F6664FCA6EAF9FE524375E20
+:10A6900053340DF9AE2FC9EEDE0A6BEB9BCCEC49BF
+:10A6A00028E712FD6993003F79A97AF9D247D0C40F
+:10A6B000F35DEA16A39EC4983F16E5C3D58E3B3CD6
+:10A6C000D5732DAE5FD6BFD27AADD6BA4538CFE6B8
+:10A6D00072877B33D0E707021F4FDF620BA851411F
+:10A6E0003AFA2862D6D178C0DB5D11DA0DD8FFF4D2
+:10A6F0006937AEC2BC7228CEB518E677B110E0CD8E
+:10A70000E13F96C35FEB9E004B3CDF4DEB158DF0B8
+:10A71000F772F8C33FB2BDEDCE9FCF6794C2C77F3B
+:10A720002D429B82FD1C3235A4B8111EE68641A441
+:10A73000773AE2A99FF3560E978EE03032A2DB4CB7
+:10A740005CD71C9BCDAD429F23158ED72FE3EE988F
+:10A750005501FF9C6BF2260454DDBC8B10DF65CEE7
+:10A76000C2EE494037E72D62DEF67801775716EEE4
+:10A77000AB8EE65D83FDA31E78AFE2473D90FE40C1
+:10A78000FE655F8CFF7EC8DB4C973E988CFA4BB61B
+:10A79000C9BD198A368643D740EFEF0A783F6181F9
+:10A7A0007C2C7D5F83DF13C379FBC4874DFE1A6861
+:10A7B000EF1DF90AE1E9E9850E5A4F2173597193AA
+:10A7C000CD16FAF39F47FC7D7F23E0C397AAFD14C3
+:10A7D000D771479C29E5039A87D617F51D36F4C72C
+:10A7E000D1BFDCA7939C7C097305DC26330FEDBB3E
+:10A7F000A94CB3E0B8BFBB60F520FFFC9DE027A0EB
+:10A80000DFD3F719CC4FE96D2C40F56F678D947F3E
+:10A810002F22A75B15CC6FE223BD7A227F0D81FB2F
+:10A820003A82BB5DBBA313A797939D11EEEBE37F29
+:10A8300014FD4E14F402FBF551A417D8AF0372D3E4
+:10A8400042F6CD684E2FCCECECF9CFF64D430B978A
+:10A8500017C0181D49B0FE1B040A6FF094929C406B
+:10A860003DAB13C0BFC1A5929E5530A2C98CF3DF8A
+:10A87000F635E7636F2C63913E287F6384CA105FCF
+:10A8800013368C398DED8EB340A701503FFFB27661
+:10A89000241AD63F01F83B706456D015E444885C16
+:10A8A000BA2971DD68D4236EEAA1FF3E96D5AA08C5
+:10A8B000BF71597AB93201E58AAC07E31D4438C447
+:10A8C000B6952FF5A942BEF4617DAE46BE2C367911
+:10A8D0000E131F013A43BA2F32334F7BFBCDD54BBA
+:10A8E000917C8CF4969BC5D82DE32E592FC27AFF0C
+:10A8F0009EAABD83FD2C1EFFE759C88FE11CF5768B
+:10A900007F94A3EFA8EC7E28FFBC1A200EC2F5CBE3
+:10A910006A3BF38082F355B593F2A7AA13293D53FE
+:10A92000EDA2F45C7526955FA876533E2DCDFB070E
+:10A93000ECB768CDD766D4A3568749FCF1792C11C2
+:10A94000F4BB3A8C9FA396442EF9A810C65D420230
+:10A9500010E4755DED18044BC9BEBAA398C277D553
+:10A9600081E5EB1437CAA7B947B455483EF38F3792
+:10A970004E40B633F0C32F13106EE59715A6C1569F
+:10A98000BABFA7E72B1CFF64F5609AD7E96A0FCD21
+:10A99000CB53DF74340EDA9FAD2EA0FC9034EF3928
+:10A9A000ACE7615F5BB1FDF81D4DE66428CFF72889
+:10A9B0001EDCDFC33DCCEF07FC6DB07079B101E464
+:10A9C00005D2CF88EC494FDCC9909F6B7FC1FD3128
+:10A9D0003576767E1CD2D5E04233D69BF63DE85CD8
+:10A9E000A941FABED23E397F4021F89C3F1043F086
+:10A9F00090702A17F83ABFB7EFCD43A0DF03A04706
+:10AA0000AA30BF96CB269A5FCB47E17E54128CEDDD
+:10AA100017EF49EFCC1CB84E686CC37CDFCE0CF04E
+:10AA200010617FFA093C979D7DFEEE44C4CBD9D8D6
+:10AA3000BABF7C827CEF33CEF740E3FDEA31E48B92
+:10AA40005D13DDF743EE8205CE6974AEA98C40B983
+:10AA5000B8D0CA349ED7FA62FE6C38A3F3EBA09D3F
+:10AA6000C923713FE178AE5E41BE96A9B85815D0B2
+:10AA70007DC6CE47D27E0AF3DE5E37F793C7203D10
+:10AA8000EF37F92C20B7CEB3BA0BAF225FDEE270FE
+:10AA90006F6558DF1C8EF57F6EE1F3F26D8573BB39
+:10AAA0000BFBF3131D43B915CBCB5E7CB40BCEFF70
+:10AAB00035D44B20FFDABA08E277AF59DC27AAB0C9
+:10AAC000DD13BCBF677E71CFE7FB307DA03CEF1E7E
+:10AAD00048FBA7C5523F737EB5A00FB607B9CF920A
+:10AAE000803FFEFA6525100670CB5E7F7079128C70
+:10AAF000D76F6393A90BA4B95B941A4CFB762B38E0
+:10AB000086F2F6DA3417E1ABFF8E5415F5C93E5DD7
+:10AB1000FC9F5C4FFA805E4FC85AFFF5C82E2CA8E8
+:10AB20002FF451EACE2C037A58DDEDF779FC9C58CE
+:10AB30004BF3D8533FF9FDDB18AE0334119C77A1DA
+:10AB400095EC14B85C0BE4CFEF4EDF84F68CBD2699
+:10AB5000DF26925F455C5F39EFF53D8A74560EF54E
+:10AB60007D902FCFF5455D07E5E59FF5700345B175
+:10AB70006E4FDE5080F058B8FBA1315DA0DEF9A128
+:10AB8000CC0DA860C57B2E8DC176AC1BE8D6D8CF86
+:10AB9000EE9A845BA1DDCFB3460E44BAF2AA7534B7
+:10ABA0000EABE0E33C22E41E6B04E024081104F544
+:10ABB0007E0E9FF17B6C7DCCC16416C44F45FDB207
+:10ABC00054B4B70CD0EC6E15F74DAA2FA9D211943E
+:10ABD000A320FF6E4B837A4956D1AF73728AF72A4E
+:10ABE000E49F55C833D9DF2356E60B8BE57AB38251
+:10ABF000F2D9CAE5F656E02F557941B90DE396E250
+:10AC0000B856A12F278390CE8579263F62F3936EA5
+:10AC1000F023C737DAD1A4DE323DAE667F23DA7B7C
+:10AC200022B4BB711C69376366B70BF5A215119E80
+:10AC3000AA34D2BB9A53700D205797A6417F0B556B
+:10AC4000D0C3D243F430FB8F93AB2F447896637F0D
+:10AC50003FB6BE91EF2EF9D6C472810E963C64A326
+:10AC6000736A8DB037D408FB564DE4203BF20B7667
+:10AC7000C4547614E4ED30DE436BBF4B22F3889F5F
+:10AC8000D430D62EDC0E001FD080EF04406E68C09A
+:10AC90000F865F6E5639DD371C8E1E80FC9679223A
+:10ACA0005D680730312D449E1AFB01BC6DC6758E60
+:10ACB00060114C0B919B1E1663C5FDCB1CB1FFD2DE
+:10ACC000FA870AFCC9750C15F6BCA12D1F4520DFBB
+:10ACD0005CF26D1EF1CF8ED6B75FACEF37B83E4851
+:10ACE000937A79F7E03C877DE334E33A879927A6A6
+:10ACF000A09E03F37F0DF13CFC1B937EFEDF87EBF0
+:10AD0000F23F761D7729CC67C2FDF9B5D58FFBB32D
+:10AD10001EE81BF773FD822C3FF281BDB01FEC785B
+:10AD2000AE9964253DB75ED849EBE39D645F7ACD6B
+:10AD3000C2F3BE19A27D182339523FA30BB5EF62AF
+:10AD4000AB7C2B1BFBAF8920FE596FF1AF49C3FED3
+:10AD5000EF8D73FB005F2ACA8FFE70DE10FCBBC64E
+:10AD600012B84DC5FEBEB6321C6F7D4C20B902EA4A
+:10AD7000AF5FD085EA7F04AA14DAEF86984C774C4F
+:10AD80007460B9272916F27BFFA192DC589F0B79DA
+:10AD900007F171B207AE9FE8490AEF84698289E63C
+:10ADA000A3B24AFA9ECADB7D62E1F56E15F8FB5844
+:10ADB000E007F639F1016D428419E9D8945EF46D2B
+:10ADC0001AE1DD93A4C07C1E9BD393211FBDB5E483
+:10ADD000C654A29BDA47889F4D173890FD6103FB4C
+:10ADE00020D4A3F99F1973B786213EA71687917DBA
+:10ADF000F4A3E2E5912E683F55530336B41B4FC9C7
+:10AE0000F7849EC74DE91E1AB7BCAE77FA97217436
+:10AE10005D6403BE01FDFF225CFB9EF6EDBE5C2A75
+:10AE2000DF07CACD0FB0AF3E9FD37327D935E6C831
+:10AE300073646036E2F540B39DE1F9A4237AA8413A
+:10AE40003C40BFDD855C277A45FC4F0FE7E71C33AC
+:10AE5000D00BE46BEA7AD339E7290BF32888AF3DAE
+:10AE600036C27FC124BB87EC8FD3C337D9A0FC0E79
+:10AE7000C1CF6AA687D3F79AFD917E9342E727CA8E
+:10AE8000FB7659A85D99D5FFEC36E8A7EC406F92A8
+:10AE9000377BAD62DC57237879942775E5002CEF7A
+:10AEA0004C74F09AC5154DE56FAA8CCAC3031931CD
+:10AEB00000C7B830AD5BFA40A43BC0B303FBE5DF8D
+:10AEC0004F08FA3A01DD22FE7C9591D42F6D7DC8A2
+:10AED0006B35DD36233E352B2F673F51A9FC84D3DC
+:10AEE000933417F2272A93695ED2CE74C26B25BAC7
+:10AEF0003F51A690BEF4C72A35600DB5E34FDA7E08
+:10AF00005F06B4FBE28085EC78337F597A1CBFCFB3
+:10AF10005C5E4EF6C899254BC94F7061E9178336C0
+:10AF2000C07A1A977F9AA285D8A5679641AB90FD03
+:10AF30007C43BA67503AE06776BA762DAEAF22AB63
+:10AF4000711EEAD717AC0D4FE27921A3933614BFD7
+:10AF50005F7CE5E436AE773767A09C5868E67422DC
+:10AF6000E56D85A0C34BE9DA48AC0F709B8572256F
+:10AF700022AB81F3BFA53F8EFF9FA9DFBA57817136
+:10AF80004AC3EB1752AAFA73B09FB34A204A492723
+:10AF9000386AB8AFCE390351087FCDC4F5BCD2EDC5
+:10AFA000FA75E11F7302DACD18D9C14BEB544F1873
+:10AFB000EE03E6B7E2FC4B9935583F35882FE8871A
+:10AFC000F0C51C7F9CF553C043C9B3BDF3F07C5161
+:10AFD0001AB3EF1743A81EB493FB456D9B97EB691B
+:10AFE0003B1FBEBE73621F9C832F16A4971D36792C
+:10AFF000CEA7F12FBCD299C64F10FBE48222E8F510
+:10B00000D9304E576E5817CEF3054E570F4B3EF9B9
+:10B010002CEFA734CE6742BE545AED24BA927C0975
+:10B02000E642FBEBECCE646A27F918F33246F5777B
+:10B03000266DE6FA9B38EFE284A17EC9AFF9389815
+:10B04000477E7EE6B964392EE9DB46796C5CF7EA27
+:10B05000746E9F0239DDF99F9D173313673F31A747
+:10B060007FC87A22AD822FB8132766A37FC1AAEBCF
+:10B07000F742A4F50E8F03FD0CFAEFB2BF07D3F928
+:10B0800079B2BB01CF5DD4E68336DC874F33921BA8
+:10B09000C6793C26DA3DF75C2B5E55614F672E4939
+:10B0A0004F2EAECF13FE3EB64AFCDD990CFCB81411
+:10B0B00061951684E3DE5C2D19E5C605E11FDA1BF8
+:10B0C00003F92CD4A7385E645EE2C34897CB3F9E59
+:10B0D000978CFEA837D2B99FCD08EF6500572CAFEB
+:10B0E000B1C0F9260BCFB9C71EFCB267703D5F55E2
+:10B0F0007B3C7342F2F336E4DA713FCEDF986B2F7C
+:10B100000AC147CDF6FEC75C00F773DBCD6E64EF76
+:10B110003566FF2F504FAFD9AED6211D41B91DE185
+:10B120007DCE71E81DAC376F634C1EEAE1B2FDFCC9
+:10B130000DF99E392178E8BB5D8F97EC3A7DBEDF33
+:10B140003E7DFE3DD441E3AFBE5D6E409FEF7F4C40
+:10B150009F67CD80BD41A80F70BCBD3CD87DCC059C
+:10B1600078EBEE57DDF8A9BB63D2E4F1A8476C5445
+:10B17000DD3DA1BCFB52EF58D42B4E6D9CEB46B489
+:10B1800017ABBE853F059C167F3AE618CAD5B3AC0F
+:10B19000EEF7E3012FF3EAD759CD2E5CB79EDEF729
+:10B1A0009A04FD3EC7ED770BFCFAF2B67C6199B4C8
+:10B1B0007B6486D297910E60DC5B3C30A1B2AAF72B
+:10B1C0001F44BE503C0E081FE8ECDABA7556D4FF97
+:10B1D000AE3C8E8FEB970E8F0BE1513898975D57F1
+:10B1E000358A7D01FB8EAD7D6F0CCEBBF0E70AE9A1
+:10B1F0001F852FF53A82F4D5B46BC64D94DE5240CC
+:10B20000EB9776C2F9F54A2012F2CEC1AE7D8DD011
+:10B210006EAE9FDB3B8A56D882FC90A19FCC308FCC
+:10B22000F521E530FFF9FB0E7EA740FFC51BF5EDCC
+:10B2300016009F46F953B2E5075BE877791EBDAE6D
+:10B240007E938AEB9E2BE62FE527F30D273FC575EE
+:10B25000BC09FB12FF0FE44E698216DF233E28472C
+:10B26000AF5BCFDB03DB2DC475973BAC2E5C77B9AE
+:10B270009D0522603EC722AD1E277CBFB42192EC03
+:10B2800074F36CA0AFE651CA308E011831F9CBBE11
+:10B290007A5725BDA73C8EE3BDFC2985CE69E568BC
+:10B2A0005CC5FCD33CBF8005683D482F9ED075FA35
+:10B2B000F57956CBCF7765E6C041844B096BE4E75F
+:10B2C00033C0A727C4DF5D06EBFC2816F537437BA8
+:10B2D000E6D6C88FE7E0FA58C5BE1F6CA1E5F29C20
+:10B2E00029CFC1D27EFC5486371CC7B108BD79FD79
+:10B2F0007D9E0C9CEF4A8B2703E1E05B1746E7FD40
+:10B300005B3771F9B53E06F4D84EA43F933E7EAB51
+:10B31000C2F5733683F3C321A61703286F9A1F8AD9
+:10B32000716F76517D9263EB1FE8CDF5FF7FA8A486
+:10B330000F35AFE37111EB7339FCD63F90CDF57F3C
+:10B3400029F7E219F5D756DFF664A01D823DC8E75C
+:10B35000F5092E2944BF8EE8AC4D467CCBF549BD9E
+:10B360009C15FF387FC65611A7D1BC2ECC8FFE8C02
+:10B370002F15EF5153887E3BA707971383467AB664
+:10B38000897AE4F798639A78FFF530AF390F9B5CC0
+:10B39000687F6B85B7C79381F2F3CB756179486796
+:10B3A0008346727BD4895CCEF72306308F1FD2721E
+:10B3B000D16F790F932E4D0C07FA837EBECCE7F642
+:10B3C000F0C8015EB2036E7571BE6F5CC73DA29F8F
+:10B3D0003956EF6F87B5331F0917369AEB1D5F2E6D
+:10B3E0005236F37901BE213FE85761643FFC52C8F1
+:10B3F00025095FA01B8A7B907C2BA6955EFCCF86DF
+:10B4000001BDACB3703A90E7B6107A11F8EF46F888
+:10B41000BD55E0973D1026E8C5C4FE8670CC777216
+:10B420007AB8CAF317E07B5D8F816DCF6112DFCCF4
+:10B43000EC1FF8CFFC2EE52F3FBFD7077A46C90B8C
+:10B440000F4531A877DA5C9BE086F6655B57467955
+:10B45000203D65F6453961FCD37EB5C0DF0EBCDF0B
+:10B460004578F3739C4309F1939E79EEE713709D41
+:10B470007FD96A71224BA8D86EA3F3D8C2DD0B48DE
+:10B480005F877C13CFAFFE1AFDA615FBF4F6F99289
+:10B49000671E4A7011BC7DC9A6444C03C90CD285F5
+:10B4A0005B2CAD7E641806F4EFE655383F637B9C59
+:10B4B000C765C077459D5A688D6E5B5E21F84BC5A8
+:10B4C000EE9F7F8D76C38ADD379E447E5F61F00BF1
+:10B4D000140BFF88D12FF09B1E7ABF33C087E20C7C
+:10B4E0007C30AF9E442EDCAE5CF3EC23394DA83F9C
+:10B4F0006C792B4AC90AFA07A4DFA4A56EF653AFEC
+:10B50000BA3ADE9717847D388837CEBF5CFB140CBF
+:10B510005682833F4FCB2C81A82178DEDB6421FD4E
+:10B52000B7ECF9A7B73D8674F6B18DE47BE9F3AFCC
+:10B53000FFFE3AD49F77593A8DE3CB7028217139B9
+:10B54000152E6E8F93F82979E975AB2B9B7F5F1AC7
+:10B550001BC453E9AE83568C0F32C27354DD416B6A
+:10B56000A3A31D7CD5358D213BD4B37FB5E2FE3836
+:10B570007D40619D53DBB62FDEF47A14EA6708271D
+:10B58000944F126FAD7834D487FE27BC3A80EA39E5
+:10B59000F19C72253C3ED58371BEF272248B817979
+:10B5A000147F62F38F43FCEE5C1285EB3969AEE4E5
+:10B5B00074FFC4CA04D4F78A2DBE0427A5FC7BF10E
+:10B5C0009377113DCE572A139C5944EF4926D22533
+:10B5D0007C49B8CEB91BA7D23AE7318DE8B1F8095A
+:10B5E000D5EB87F45B332BD8D5CEBE19DB93F3A90B
+:10B5F000939B01B9B0CE93223ECBF73B559CA3174A
+:10B60000913CBF4BAC99B1C594FF56E873DD7AB657
+:10B61000FABFEDA1E7D08A2DAB1B104F67BA793A7C
+:10B62000E33C010E3E0137E507E8577D2FBF33C7E6
+:10B63000137361FC02B503B93A0ABF63FD068B07B9
+:10B64000EDEC21EDC439918F7FA7181FE61D8EE721
+:10B65000E09309EDC77FFDA4A7E40BAC2134FEAB5A
+:10B66000433EB0E53EA2AF6F3EE07C66A17F620143
+:10B67000953758029DB1DC7F708A427CC2C602EDCC
+:10B68000EDF32D16B1CFF5E5304FB3120ADF035CB1
+:10B690003F95F4320FF4B240889E10A41F6BF03B2C
+:10B6A000ADFF57623D8DE4CF937EC0F9823F18D73E
+:10B6B0006FE417F93D0D714AA23DDBD8BEFF29C8E2
+:10B6C000277C346E19C877D447CA3EB6911E51F60E
+:10B6D000BCC58B703ABBE3F0EF6FC5F36D9DDCD753
+:10B6E0007A3E6CDCD7C52F0E6C775F9F5D9BDBFECF
+:10B6F000BE86EFEDEEEBB50AF1BBFF2E1F06C94784
+:10B7000076892BEDDFF91DF0E14A035CBF6559D165
+:10B7100043B0D059D89DF06480AF84AB91AF5A91BB
+:10B7200049B6C35719867484C053C251D22B631AC9
+:10B730008DD34AD7926E255DB7D2AD71DD7A781A76
+:10B74000CBF310F7301FEF2B16D217CAEA797C2201
+:10B75000B4A378BA0AB4CF53EDDAA3C99D42F37EFD
+:10B7600043BECE50DF63C87B0DF53543BE5257BF95
+:10B770006CDF612B3F3F0474F56C5563E93CD25696
+:10B78000CFF073BFD3EEAFAD3EA48FAECD56E493F2
+:10B7900096E5CC1709ED9BF7ABA4F75C743547A190
+:10B7A000DEB2328CEB75179D221FC3F3CDF1D65557
+:10B7B000C827E5F7E6306E87B9E86D8E8A0939CF7C
+:10B7C00037D5AB5168FF6DF4B382F6E35B6A683F2F
+:10B7D00035B28ECAB97E77319CDB1B2E86737B43D4
+:10B7E000BEEA48A9423B6C2D8F239CB36C5A14C50A
+:10B7F00061D4A7DF3C1DBECF7D93C20C308ECE8CB2
+:10B80000F10FB3392AD929E6A378C2D9F53C0E62E3
+:10B81000CE5A3D9EE739B650BCDCB76C29A5F3D6AD
+:10B82000EBE3174AD85AA2B3E28D86EFF563699F1E
+:10B830009418F68926ECC3C67DF2A1DC27B92C57F3
+:10B84000172729F879BE9A75F374C0C7C5632AB360
+:10B8500041BEA55E65AB06F0B858F43FE18104F740
+:10B86000DF42D8AFA83749789DC37DD4AB63FDE5EF
+:10B87000DC9ECF06FD14E966EFA7398F437A6EEFA1
+:10B88000C719AF61FEE53FA47CCADAD61F75E0BBDD
+:10B8900059C8A72F1EB031A4F78B07DE48417BE4BF
+:10B8A000C5576D74CEBEB8DCC6EDDC0722FD28623C
+:10B8B0002E76E37A71CDFEBFE634925C5EC1E5621E
+:10B8C0008695F0DC52FFF713684F6FA9875521DF8B
+:10B8D0003F1041FBA9E2D530B2335FDCFFD741A175
+:10B8E000F6B9FFEE7AA4FFFD62249BFE22D2710C12
+:10B8F0003F1754BC76EDD3E85F2EDF7DD03A1BCAEC
+:10B9000047FDE63F7390AF5E7C91EB53172C8D4F54
+:10B91000A28D3322E3D2AF2C4968E783CEBA30B68A
+:10B9200025A3FF645F567B70E170B80870C0750195
+:10B930005C8A511E74048FB47F5B787C3D8BF3B7B7
+:10B940006B18FAA38370513CFC7BA4DFAED0FAF9EC
+:10B95000F7037FCD41FE73A5F57A70BD03FFFFAC01
+:10B9600077D6BFED7A39BD7F85F235BE2DDDB7A51F
+:10B97000EB97FF83F23B23DD34DF1FB9DF7FF6FF58
+:10B980008CBE37FEDBAEF74AF87E53E03BD289FE31
+:10B99000CC8BFBFF33855DC5BA5FFB3FBA6EA9C791
+:10B9A0008F54DDC772A1FE5BACEE03772A6923EDED
+:10B9B000EA21A7321479BEA3F3D328C6E5F4287B85
+:10B9C00029E99FA3BA3E40FA720DCB23FF85AFABA6
+:10B9D0004A7E1D0A020138BC91984BF7AC9839D0C9
+:10B9E0007509E447269753BC98F15C392A7C7C01A1
+:10B9F000EAA78797C1BCA09FC3912627FAA84777DB
+:10BA00005503B61C4A9B303D9A3296E2FE473BF402
+:10BA1000E7ABB18673D28D2E7D79017BB113FAED40
+:10BA20000AB22C74BF620CD60F39571ECD70D23AB1
+:10BA30006F64B52B9C8EAB8753622F7ECE6C0B87C9
+:10BA40007F0EB7367012E768B3A86F849BD9717FF9
+:10BA500003B633333817F3F5D2795A9E8BAF044FC0
+:10BA600026CEDB6631B484AFB92BF7CF86F44B70AA
+:10BA70009170BF5A784B3C19E12EE12BE166C4C3AB
+:10BA8000D90C26CEB71CFE5DCDB966DC77C3845ECB
+:10BA90003FDA1CC3F35D1B542FED473FE16DD437F4
+:10BAA0006E33EAF5231C3114476ABCBF5034386644
+:10BAB0009002EB4D36339F0DCEA1E87B23BBEB7D8F
+:10BAC00066FFF2541C87DB77BB99B9FD1A76B72F56
+:10BAD0003C8FEA7BAC902F7C703EF340FDC264E665
+:10BAE00056787D161D4BE1714CC5383148B15D610A
+:10BAF00034EFB7B033F32FE7F824BCA0D907ED1B20
+:10BB0000D0AFC714CBDB47E5517B9F89B7F79821AE
+:10BB1000ED9ECEE3149A5772BB7CE1EA6E19C83FE2
+:10BB2000C68DD4DB996B7B717FA44CBFEFC5F7BB8F
+:10BB30006A7227D27D8A15BDE97CA4867BCBF7A0EB
+:10BB40009D7E278FD3295C75FBF88138BF9D716E70
+:10BB50009CDE9909BB06F1FA33EEFA10BE6BDBC32B
+:10BB6000E8BB2B531BDB0BE30114D7AC3DF0A16802
+:10BB7000EA616B220CA1D54D3C8F76C209BE5DEF08
+:10BB8000A07F72C21495EA4F603C0E93AD88A03836
+:10BB9000CCF1BEAFCD89D0DF78387460795398335B
+:10BBA0006511CCBF50D887A7897863359C692F3A37
+:10BBB000705EDD32D2E0FB78D67E7CF243627FA9F4
+:10BBC00023958DE867EA3E8ADBEF657DEC07FB7D18
+:10BBD000BC17B747158954E601AE547FCE1A5B53A4
+:10BBE0003A9E7FD65802BD20FDB0F7C879BDA07C33
+:10BBF0005C1A1BB301E17E8FCA36D37C9B0BC9AFA5
+:10BC00001099E9423C6840D2E45FA94D75A15DAC52
+:10BC100069445D00FD094D8FA6BA6B5C84658A0797
+:10BC200092E7ADA611811E68C76FCEE57E8913CE5F
+:10BC3000C6483C2FCE76D8F9FD4911573457DCA3BE
+:10BC4000E95ED3F8C035780E7D48257FCDDC87F8D6
+:10BC5000FDB03F3BEC7E05CF6DEBF93E656BF571BA
+:10BC600044CCE9263BD0ECDA11563C6FCE7178AC6F
+:10BC7000B84E7FA6B602D725EF23F641244097851C
+:10BC8000B58514AFA246C1BEC37D627645E139D801
+:10BC900018875421E28E64FE17E1DA03D85F51B4AD
+:10BCA0006B27D2CBE755E9641F3D2EE86E1CC655C5
+:10BCB000A23FC3DC9884F3198EDF11AEB1CE0C071E
+:10BCC000D17318433834599C1948DF4D2BC34CE8C5
+:10BCD000971BB79CD335EC33BB19DADF6766E1E815
+:10BCE00067B84DB49FB9CCECDD04F9AE76668E8CA6
+:10BCF00045BACA25BA4EECA315E17C4EDDCB06232E
+:10BD00003DCC5EBB8EFC31922E98B961741C8C7355
+:10BD10006A6B6A1EF2CD563EDD67E4965EA1F43092
+:10BD200045213A80F4603AD1C3A46791EEC78D0CE7
+:10BD3000F4589C85E7D132E641F99EC8DCA827B4C7
+:10BD4000B066F257B638AC2EB47F497E22F986BC75
+:10BD50002F2BE9601BC87BB385B1EDD5764A9FAB2D
+:10BD60007632734FC6765427527E67B58BD2BAEAC5
+:10BD70004CFAFE62B59BF2BBAB07537E6FB587F200
+:10BD8000FBAA0B287DB5DA4BDF255F02B8101F92A6
+:10BD90007C45F2A3D90E6B13FA2F255F32D2CD2C3E
+:10BDA00000EFF03C6A4F7C4FF23B5C87292FC88F35
+:10BDB000247ED314AF2F3115F958E30CC47FBE7A1B
+:10BDC000EEF997F15C5EEC70D3399D71BED702F449
+:10BDD0008A7049B1B27D6897AD59E4695A9D1A8459
+:10BDE000FF6DC50A3387D0D5ED9561CC1C2237EEA7
+:10BDF000A88AD1E56756BDFF7A67DC0FF1DA67885C
+:10BE000097133FFBEA893FC0F7A77E76A627E21B80
+:10BE1000E6B1F5111C776978EB3C6231BFC2427E16
+:10BE2000AEEEC27ED25DD84FF04FE87DE6A77EF63B
+:10BE300037DAE74D553617EAC59F20BE00BE7F149E
+:10BE4000F82AAAB2111C0B577EF1FCCBB8DF975A27
+:10BE500089DF15AD10FBD1700FFAF324467609D0B7
+:10BE6000AA299EFDF37BAD8108E8FF7385EF63058A
+:10BE7000948399187FB8E68D8F900F2855C7C8FF17
+:10BE8000AEE1BD3D9C9FCF724E77AFBAEA28D56335
+:10BE90008D5D63D0CF23EF25470CF0585DB07EA4B5
+:10BEA0006DC45F51E62196847E965AC589AADF1C2F
+:10BEB000F17DCE1A85FC9A18C73305EF9167AAB4B5
+:10BEC000AF46F432135E9FC2187CD2EF6A494E49E6
+:10BED000BA9DB316DAE1FEA8CDB5CE0BE1C745E2B7
+:10BEE000FBEC4C13A5F27B02F60BFD7559933B1D41
+:10BEF000F58A2E589E8569DE74846F17C718B312B1
+:10BF00004207CE4CB398071FFF29442EFCEFFECC0E
+:10BF100034EBDC2CBA0F48724C8E539499B70AE379
+:10BF20004B8BD68E402ECC6A2CEEC44E502FA9B52A
+:10BF30001F711FDBCEE3A8CB3A9023D2AE760AFF67
+:10BF4000792DAD9BECBE253B7FBD13EF17947C6A2A
+:10BF500023FC96F413715B59FE4193C900A9B7679E
+:10BF60008FFEF56751E4A7D8CDE33B21E576D6A552
+:10BF7000C5DC2EEB86FDD58EBFE8C8CE4FA3DAB563
+:10BF800063EF567F941DBB42F93E0AF508B99EFC4B
+:10BF9000FDDF26D03C94CBE427AAD8BF32A1BD3820
+:10BFA0002FA31DBBD5DE2DEC7A154B0BDAB5771B15
+:10BFB000ED77E3330DFE0333A37B66D27EC7D4ACAB
+:10BFC00068F4037C2BEE9F7474CE91F6EF8A0DD04B
+:10BFD000491CEC57B32B1AFD5B173BD0AF1FCAE4CB
+:10BFE000F2FFBCB0975FDCA1D2B9E7E28E48DA5726
+:10BFF0000B773C7814FD8E0BB728348D72D640F049
+:10C0000003B8327BA85CC338B6B8B6F36EF1F78CD0
+:10C0100046B952FAEBC84AA4B705758A672BCCA774
+:10C02000C5EE8A8E0F99CFA24CBE6F4A6D758308FC
+:10C03000DE62FEF3335D4457B2DE82FA07C9BE0CFE
+:10C04000F52E905EF44204E3F7539ADFC1799EDD4A
+:10C05000D8DF8DFEC20575BB16925EB123C289760C
+:10C060008533226E59F673AF18EFDE4CAEE79D159F
+:10C07000FEA3B33BF93B00384FDC6767146E87962D
+:10C08000ED6AC4BEA8C9E47A5606C2203E587F4174
+:10C090005D53540FA87F72DFFB943E20C659E068C1
+:10C0A000C841797C727704F9BF4EEE7E7CCC6B3050
+:10C0B000DEF9BA119D705FC8FE1FCFB4707C6C545E
+:10C0C0000B105ECCCFE366CA11BEFD43E719B7C9BA
+:10C0D000971ABAFF78FCD0D9DD2F4599B282F82C97
+:10C0E000B757DA934CB88F167991BEA39178A07F99
+:10C0F000EBEE893E946115F5B90CE99AF65F12D51D
+:10C100005F630AA967B3B829CED4B2AFD0C3EF99A1
+:10C11000887B51228E3F5FCD22BFE2AC7EAE69B7F5
+:10C12000219F7CCB42F858DCDB350DF9D3A5069571
+:10C13000E13C17A7B200EA274BEE89DC84724CCEB3
+:10C140007B567FCE0FCAD628CC03EB2BF3AB4C83A8
+:10C15000B40BE0DF87F494D83810E3249B52B95E27
+:10C1600021E3471F2B3679AC20075FCF8C157C5617
+:10C170007B742EFACF2665D279EE8495F954B42BD0
+:10C18000BDC8E34BCBD2785CF363221EBE2C369045
+:10C190001107FD9D13F82D9B14C8C0B88BB21793DF
+:10C1A00028EEE29C95FB3DF13BFA59CBF2A0BD8312
+:10C1B000DED9D064FB98107A2A2B72BBB09E1AEBA2
+:10C1C00076E53A70BECE0BA4E7EE8964A8E79A5EE6
+:10C1D0008EE47153CF846DB685E0EDE34CAE47CB72
+:10C1E000F73BD8AD3CCEE8610B8F4B7D786B92DF8F
+:10C1F0001F02AF872DDA0C8403AE03F5FB05D6DAF8
+:10C200000CD47FE57C1744D5D23CCF097A5F105E11
+:10C21000CBE3B9C57D60AC8FF9261187DEFCAC8D10
+:10C22000E280CE2435ECC5F1CF3CDB9BE1FA9B529A
+:10C23000FDF3F65139E89780CF92E76C015CCFE9C6
+:10C2400067B93DFAB485EB6BA72726BA10BF0593F3
+:10C2500036CC227BCD169B8276BED30AB32662F9FA
+:10C26000D6788A3F2FA9AEA2F8ED12601B787F081E
+:10C27000D202BC07747A6B6F8A373B8DEF3628F495
+:10C280007D0D7ED758EDAC9F203CB6F3F3D599E7F2
+:10C29000FEDE3B34DE5BA6255BF4F175924E64F95D
+:10C2A000DF047FFB9BD8E7FFC8E4F688F288BA87F3
+:10C2B000D3689D1CEE8027FE8E0D6B8C7C7C00C6A7
+:10C2C00053F454908F3CC602198FA3DD613B3F7F2E
+:10C2D0009DD961A1B8F59297233D14C7B6FA1A13F8
+:10C2E000C553A85C4F2F3101F820557EB69DE2CB97
+:10C2F0003A3D17966723FD9CD139B779AB2AC661C1
+:10C300000CEF539EDEC6E38EC7A12E49E5D9547EBD
+:10C310005AE44FEFCD26BD0FFAF7E0FDAA929FFC3D
+:10C3200094C37172F171AE77D989DF96B5FA7986C7
+:10C3300046A31C2C5F3D241AEF2BB27755867A8BCF
+:10C34000114E97CCEECEC867C7F7E6FCAC74EF137E
+:10C35000E49F2A15F7084A9F53B81F1AF621DEE713
+:10C360002C5D35E411A2CF772CAC27ACE75CDD83E4
+:10C3700051A1F8B8A637E773ADF5AD6EAA5F0AF51F
+:10C38000B19FD2556F45D17CB659285EC588C71F6D
+:10C39000DDFE39F547B56FA58F3A6E6769B37ED676
+:10C3A000F01F9F42FFDFEC0873FBE86B1DDD833B52
+:10C3B0006BA99B87EB3FFB7C18F1ADB3319C3F9C95
+:10C3C000047EEAEB85F318FB4B8AEFFADD64BABF13
+:10C3D00037DFAFEF578E3BB437E7E3E571EE688C9C
+:10C3E000172C7F97F341C0CBCDD4FE5D0BB537AE94
+:10C3F0002359B46BDD9FCF47103D9CEDC2F172769F
+:10C40000672F924F4D319CCE61BE2978DFEFECF360
+:10C41000BD72E91E1D2A3D400F25E2FC7B36A62E8B
+:10C42000C51952DE6411E7B800D444BAC136C0DF82
+:10C430004BAAB8BE556A5F4BF12518AF3B288FD287
+:10C44000802DB66DDC2DD02B9D2F1FEC2DEC983858
+:10C450005E828813273DA8CE8A7C5B13FA62D90ED0
+:10C4600063DC2E2F5F2CDBC36C3BC93861A4439F78
+:10C4700042712AA52B162DA0F8FBCA75B7E13E9391
+:10C48000F32F35B3023CA735292ACDA3298CDD3102
+:10C4900009F5CAD07142F4B97B83E3306702E9B190
+:10C4A000A4F42FEBEDA2EF98AFC57BAD2B94B53480
+:10C4B0004EAA3CEFF27549380138AC1827D83442FF
+:10C4C0009477B06E394FE3BA5BF5AEDE9CEF37A5DB
+:10C4D000BA7E3914F1FCB64AF77F2F7DDF3F3AB6BA
+:10C4E0001D3D2D28E7ADC1785998FFE6DE8CFA99FD
+:10C4F000D79BF3B5528CC78579666CD4C78B676EB2
+:10C50000D1E7FBECD0E7B376EBF339F5FABCFB8867
+:10C510003E7FBF1817CFE178DF18CFE198E239DC12
+:10C5200065E3E770CCE3391C533C87E3773C8763D2
+:10C530001ECFE198C77338E625BCF13C8E793C8F5D
+:10C5400063F9FBBD39DF2E13F1968807A477F64A0D
+:10C5500098EE3ED2C5FDFC7E09D001DF3733ACB486
+:10C560006F1EC31A741EE176A72E93ED2E8C1F5EEC
+:10C570001BA7EDEF1D8FF7501A562521DECC8D1429
+:10C58000C75AF12A8F632DCB0B73A0FDA371E5C9A8
+:10C5900055181EAAC56987B0FE454BF336846F79DE
+:10C5A000D561BAAFDFB8CCF5EEF51C7F648761C505
+:10C5B000B1A44715A29C8BED188FC67872B6561F92
+:10C5C0003F6E8C2737C6911BE940EA7F4F599A93FB
+:10C5D00090AF7FF1AC7D2DCEFF8B30711F66BADD41
+:10C5E000100FE0207EB2F8016533CAEB2F7A733D5D
+:10C5F000AAE518E8EBEDC85999CEBEDC9FF4F2D657
+:10C60000FC5AC544F1E99A87E4D01231A714A5B9C0
+:10C610006935F2B90526929B97405F237DF003951B
+:10C62000F4077C572B743DF8AE56287DE1BB5AFACF
+:10C63000FB125D74F5F15D2DFD7D893EFAF8FC2954
+:10C64000CB0EE2B97FF2DAFEBA7A73BC430C7014F7
+:10C65000F316FAEC1C901F1ED42F976E4841FC2E47
+:10C6600059D0D2B41AF0BB644F981BCB8BF1FF802A
+:10C670002F16439F78EFB278B7B8BF5CA597C3B3C6
+:10C68000851C2A36339F33364887C54EE68981F6A6
+:10C690000BFA34E4E0FB590BDE7C7F90330DCF19AD
+:10C6A000233A233F4AB17828AEB66C57CF9865D06D
+:10C6B000EF373DB4D83E80972F6B0FFF6226CAC379
+:10C6C0005DFCFCF7C5DA97A228BE4CD05B8AC51981
+:10C6D0008E78DF54CBE3EBD07EA6C606E962536DBD
+:10C6E0005C780F4770BD413AF89EF004F8E1769E01
+:10C6F000E243E41769A913EB1DA1F850CF96EB9321
+:10C70000EF6EB115BC9F3B45FE4B71DE90EB3CD705
+:10C71000FB608E0BEF7554EF4B51919F9B766CC372
+:10C7200073C83F6C5A769F788C07EDF9077C87AD0C
+:10C73000E443BE9E3FAF1F15752DEA9FCF5BDCE340
+:10C7400020BFBAF6692B9E2B4ACC7E2BC5673EBB19
+:10C75000C98AF1CA376CDF44DFE76D2FA478CCF9C2
+:10C76000AC92CEA3A7E43B09021EC523958D4E983B
+:10C77000F7837D389F2D0EE7FE3DD08F5EC7774A49
+:10C780002E6D577231CE678A7797B510BE8FE9C389
+:10C79000F98C719FB41C9F9C1F4FF0E0F7403E64E2
+:10C7A00070BA4F6FBB2F265F4EA57D31E5725F3AA1
+:10C7B000A74D0DF4E6E7E12CC379F8B8CAED79F599
+:10C7C0007C1F145B039D26E33E3960213DB7DCCC22
+:10C7D000DF792A877F5F07A977A8AAA3D78AD11113
+:10C7E0003A7A9ECE6275F7696EC1A09290FC947100
+:10C7F000E9BAFAD3A6F435D07F5EB09CF8C875BA12
+:10C800007B7FE54B7D2E85F4CC91FAEF8CC71732F8
+:10C810007693AE7D399B14AC87F4BD45E1E79EDD90
+:10C82000319BD10E586CE2E7A7E91AFFBE701FFFDB
+:10C83000CEA633DD3EEC9EEEFE03978B16F21B4830
+:10C840007BFB74FC773BF0672CBCF51E3BDEE347BB
+:10C85000FB84EE7EB7F017E2BC110FE5C29E549E3A
+:10C86000C9ED49E5BE062BBE9300F037C7C5523D62
+:10C870007B1CC655D62A646FC47429C559EAE3B433
+:10C88000B03F8C7F5C784C2DC47D622C2FC6778A9C
+:10C8900010BFAFF2B8D48568178A6AFB3EDA42B49B
+:10C8A00013A17DCBF01EDA877D5CC26FE75FD505F3
+:10C8B000E1384EC9A57B9B3B0E5A313E6FCA949816
+:10C8C0005CDC3F463A93FC1DF635C515B61C3F4C63
+:10C8D00074D6526C263ABE123C167AB89DD5487F63
+:10C8E000F3588315EFA7CCDBADB8F15C8AF5102EB9
+:10C8F0005D902E0D70898B6D0B0F09A756B819CA64
+:10C90000E7330EAFF9FB143FF2C7367012F033CEA7
+:10C91000BF23F8C975CDD3B431C827E4FAE6E33AAA
+:10C92000701C58078E23FD166CB071BFA693FD6A6C
+:10C93000A197C7D91AE963D2656E97B9E5B299D2C2
+:10C9400029E3F4FB13DBE13E997A3981CAAF967E85
+:10C9500016C23C512E5C2DDDC8F5487E1CDC27FC40
+:10C960005EC295DE3932DA279BFA88FB1003D94084
+:10C970005D7CB3E0B7C6F6C6F866A91F18E54E6140
+:10C98000A489E22D5B1C69A47748FEAB09B9A2AD6E
+:10C99000FC96EA69508FCFC6A393439AB0132E8EAC
+:10C9A0004CA377245296C52520BE0AC39C14D75F9A
+:10C9B000B84CA538EA42A8E70AD15B56AD484F41CA
+:10C9C00039F2F97DBD9EF4813EFFF93D9D1206C30B
+:10C9D000385FACB474B2BB82F53E5F999F82F11DA3
+:10C9E0005FACB34DF7B703AF88BEE23ED3CF3E2274
+:10C9F0003977DE743C6A3AB42F5BB9270AAF0F94DB
+:10CA0000AEE4F2FDE11E5A78DF8128E7376D73222C
+:10CA1000FC9C9B72D04E9C8436DFF8A05E51B232F3
+:10CA2000BF33EA1D65FF38FCA413EF852FB324A0A4
+:10CA30005E7AFA0390930AC939D2274E854117E4EA
+:10CA4000878BA4F7CF4E29CC83FEA873A6837F598A
+:10CA50008DE7C5DCBA8C8082CE532DA92FDA5557CD
+:10CA60003E4DFA4CC9FDCB32F01D426D59CFE8F670
+:10CA7000EC2932DD26E439EAF598A25E8FF135A87B
+:10CA8000D7631EF57A4C51AFC7EF151BF47A619A44
+:10CA9000F06F49BB73F79AE65CF4FBF946B2CC4AF7
+:10CAA00092C30E7A17788912EE46FEB4047528CC2C
+:10CAB0007F16417607F6C18D3A3CCB7783E5BBC044
+:10CAC000C39A41570BD927D75FB6B3D07BBA235847
+:10CAD0008C2E3FCA9EA4AB9FEF4CD595DF90D85BC0
+:10CAE000577EA32B57971F9B79ADAEFE78F7085D55
+:10CAF000FEE6C137EAEA4FF44CD4E52717CCD0D58F
+:10CB00009FEA2DD4954F9BBE40573E435BA4CBDF9D
+:10CB1000567C8FAEFEED95CB74E5F29DE47A3C8FAA
+:10CB2000D9F0FD173BA5F2BDE4BB5546EFB10D1D95
+:10CB300065E276461B97474BDEEEE908A583D97D73
+:10CB4000B91E7430CB330BE955BE8729DFB95CD4ED
+:10CB500097E3359905147E1E6E48423A36D63396D1
+:10CB60000F8D3874C905B8FCA4EFDB53CDC02F86F8
+:10CB70005E73A87F3AE4D3B2E26EA1FC90432FA586
+:10CB800039F15C3AE31633F0ABA1FD0E5DC2F2DD84
+:10CB900059893C3F99916A3268C7BEA9182F3BF466
+:10CBA000FAB4B56E6E4769F7BEBB4C111E784F1CC8
+:10CBB000E1816900E818D34340C7981E013A9E639B
+:10CBC00061EC28D031A6C7E07C8ADF7F0BE7534CAD
+:10CBD0008FC3F914D377E05C8A69039C4B31FD5D08
+:10CBE000F5744A3FA8D6A8DDEFAB8B29FDA8BA9211
+:10CBF000BE7F525D45E91FAB7DF4FD81BE8A90E3A7
+:10CC000001DD7BA31DBD2B2AFD9CD2AF5953C91A50
+:10CC100023906F349A63BEB207FD951DDB09CCECFF
+:10CC2000AB107D2D5BF16CE84BE37775121F17DFBE
+:10CC30005DA9DA1388E70F5327F7ECAFA21CAB7C92
+:10CC40001D436D3E34B5FF7EE422411FEBB33C9B98
+:10CC5000B1DD303BBF9F3CCCCEEF1F0F3337D4202C
+:10CC60007DD57CC75C18FF733092BFFB51739FD991
+:10CC70008F7650E532DFE7C33B31CAD77CD748F720
+:10CC8000958739DD8928AF64BED5EF8F7F42E27C7E
+:10CC9000A41F5EC6F78CBEDC300AF585E10EAB0B37
+:10CCA000F94868DC00FADB0F467E25E7C3703CE9F3
+:10CCB000DFDFF21D0B9872827EFC61F68654B41B96
+:10CCC0000CBFD3EE0E8D5B92FE7AE572A38A765589
+:10CCD000199F24C791F38D34437F79C1F8A361CEA6
+:10CCE000BA5CF477D4943BA8BFCEF0DD9A47F53C0C
+:10CCF0002AB5ABCB45BBDCF03207C5C1CA3881CE03
+:10CD000062DD508FD639FAB2467112C3459C04F6E3
+:10CD100063E7E53EEC6778A74012C6810DAFE4EF0C
+:10CD2000903DA1F0F7E865DC02D68F08D9B7384FFF
+:10CD3000ECB7C7DF60BEA847793C04DFC9F25CE707
+:10CD40001279E977B48F24FBD628C16B1E4ED5BE6D
+:10CD5000403AF2DA9C9F45D0FE4EEF8676D3894268
+:10CD6000AFFF27F4720ADBFDF7E9C5C3F1DD95914A
+:10CD7000BDCD4837122F12CF1DD191C47B489C19CD
+:10CD8000E1B9356E4CF463A4AF8EE84AD2D3303BA0
+:10CD9000C73BE215E3D4241D2997F9BB6EC3CBEC46
+:10CDA00024EF241D19E9A02D1D71BAACB9CB4EFD9D
+:10CDB000B5A5A320FE111EFF3A1D35AAE8BFBA5A39
+:10CDC000FAB9A3998D8986A26969DA22C46FE165EF
+:10CDD000D751CCCF6623C62049C9720DCB07B62DDB
+:10CDE000D7BE69B64487D0D9304167AB3BA82FEB9B
+:10CDF000C9772F64FFCF7430FE5B426F782B4CC62F
+:10CE0000A9781CB9838271A34BF2397D15A4AAA419
+:10CE1000778CCAE2EF9F3307D7B35DF017F9F14D76
+:10CE20004C3B129D8AEF947AE97DD2319D0CEF93B1
+:10CE30000AFDBCC0E0E7BF29EB06D2CF6FBAC23B08
+:10CE4000D7E3B3847E9DCA52AFF21DD2295964D76D
+:10CE5000FEB1EF90F2F76B478BFD9E2CE829DDA524
+:10CE6000B2A1B1F89EBB6646E17204DFAFCDC177D7
+:10CE70005E7D94BF91F9291DCB02A4478C074184A4
+:10CE8000F99B19A37BFB872326CCC43B87A3FA8F8E
+:10CE9000EA81DF43DED95B90154FEFECFDC919F253
+:10CEA000CEDEA1D12EBABF7AC89E4E7A28EE574B5D
+:10CEB00088BDF44D90CF3D607D87417E63FA3AC8CE
+:10CEC000EF1E2047DF00F98DF99B3297316C37C692
+:10CED000A58F7B92EDC73A47C141AD63F88DCD79FF
+:10CEE000A52BC2F7AD985EA3912EDE8AB96634AE4B
+:10CEF000F7AD98CE269EDAAC9466BFDCA33D3D59D3
+:10CF0000EE87E07863683C237C253C8D7094F0FDCF
+:10CF100017E0F9607BF05C84E708B4DFDADF8F4A62
+:10CF20004C43FF26E7B3E51129E23DD2B773D43471
+:10CF30008CF71D42F31C5E752D33A3BFDDCEE1746B
+:10CF4000B29AF910BEA7710968F036D8F79879A49B
+:10CF500029340EFA659BB615E9EEE44695EEEB9F93
+:10CF60007F318CEC76A7FCDC2EB9D8A43D87E56533
+:10CF7000AA6BAD1BF5CDB754FE8EE8F78753264557
+:10CF80005E05BD6EE1EF1C94D9C7B48B4F79BEAC82
+:10CF90004CF310BF6086DFA3E86AE3EF41C877294E
+:10CFA0003BD2B7E4EFB874B5717E2DF1BBD12AF452
+:10CFB00000E86710F0D9E45F86D379EBB104CF21A4
+:10CFC0005C1F9C63E8FDA996AE91249F0E89B8B8BA
+:10CFD000E181BEF4DE5A81F8DD8137C47BEE8744FF
+:10CFE000BCDC910CED6D6CFF86EB5057B43F5CCF11
+:10CFF000B81FE846077F3FFF6ACFE71F6689F8A1A1
+:10D000001C967355BF9310AFD27D8AE12C83FCF040
+:10D01000A370BEC8E7DE9C6D463919F23B09B4AE79
+:10D02000FF6BBF93C058B38AEB4A762AECB1D4ABFE
+:10D03000FFDD04559CABE4EF2714F0A236BF9BF054
+:10D040007854018FCB77CC6BF7771392C5BBD6CCD6
+:10D05000C5E586FCDD84FC44BD1C19E51C71C44992
+:10D06000A9DECE937C85F8B1F86C213FAE16FFE5C2
+:10D070008CF0DF1A67DA89C73F0DD7FAFC12EDF39F
+:10D08000A33A59DC7E575B3AF877FB5D948EF064E7
+:10D09000FCBD14239E8CBF9F92AC9699E91D4881DC
+:10D0A000A7E9F017F174BDF87D8BD1F8FB16EC7F82
+:10D0B0000E6FE30C78FB96AD1D88EF965E2CE47C3A
+:10D0C000BD23B91F9EEA99940DFC6396B01F49FBDE
+:10D0D000888CCB35FE7E92B403C8785DDF488E6FB6
+:10D0E000DF8908F25FDDAD3646A29C3961E2BF9769
+:10D0F0009411AF69D8FF1D59950AC223917977CD54
+:10D1000083F9CFFA8D2D05F3B3BAF3F7225916FF41
+:10D11000BD2039BF59C93C9EAB385BF06F378FDFFC
+:10D120002ACDE676B248B793E2CC0BB398889F65D8
+:10D1300029B3B2913E8F87F542FA5BCFED818DF82E
+:10D140005E65A7E07B95A8A7A35EDC4DE8A5351F2B
+:10D15000DBED9C0E994EFEF7F6DB7571CE7DB73B8D
+:10D1600075F9ECBA445DFD7EFB5CBAF2DC40A6AE1C
+:10D17000BCFF31B72E3FB061B0AEFE351F7974F9F8
+:10D180006B1B0B74F5879CF2EAF2C9ACF95184EF82
+:10D19000E6EC34C25B7745D8495C1C1FB3EE4EA069
+:10D1A000FB4AF2FC21E3DE3541CFC6734D772BD726
+:10D1B000EB6B92183FB7DAC5F994E9CF379A885BE1
+:10D1C000977A3DF3E9E3D665BC7AEB39489C73E482
+:10D1D0007922245EDD83F397F1EAAD7817EF871AA1
+:10D1E000E9F5856CE15733ACA3BB95DFAFABB9C7AD
+:10D1F0004AF784E4FC8CF33A2EE298B7DADB7F0F2F
+:10D200006A7F36B7AB44F6F0EE417A7D12D815C18D
+:10D21000B3CD78EE46FCFD819A7BADEEE5AE2B8F6B
+:10D2200037AB1F5FCF4C7C37378BDE5FA57B8172BE
+:10D23000DCB7057DEFE9A7B4BBBE59D13C3E8E45B6
+:10D240005BE95E4BC7E371B8265AD90A7AB74ADC64
+:10D25000F3B87D6DDD035834D35A6BE10F0FF82D11
+:10D2600068471B3712F4C45CC0C3334B1E72805E28
+:10D27000F4649599EC621F3C7FEE16D0305BEFEDC5
+:10D280007487731AD2C938C43FF47B533F1E9FFE84
+:10D290006D365F5FBEFA7DEB7D0B9B8EFF33E2FF49
+:10D2A000EDD01DD1A35CC7FFD6FD0B49BF4638C9E1
+:10D2B00073391372AD879897849FDC17127EF2FE44
+:10D2C0008B6B91C5BBD941F7680A302E4FE2EFF660
+:10D2D0007E9C2E7BE57078603DE4471DD5CB57B32F
+:10D2E000A2D15FD0C25CD1CE2BD8CDFF97EEA510D6
+:10D2F000FC3BBA4FD7119F68C31F3AB85FD7117D67
+:10D30000D29FABB86717C22778BC94C087BF878904
+:10D31000E2125647EAF7F1B41C2E17FE2EE5850FF0
+:10D32000CEE77A3EC1D0FF51B352157C625EEBEF7F
+:10D330008DE0F7B92B2DA47733E67D18E334FEBCDE
+:10D34000DE42EF3C0EF730D26F8A362AFE4D4AF0AD
+:10D3500077BE0A7D86775AD4EF493FFC76ADE2C4AA
+:10D36000DF8B98BD465F3EDFC17FA764AEF1BD1A7B
+:10D37000E98FBBC2B9BE2047E8E56EE626BD4CC4C6
+:10D3800051148B3A46BDACC5CFFD8D782E57B91DD3
+:10D390008BE2EFA4DC77A1BF2BE41D16806B78260F
+:10D3A000CAF115E676E3225BE1DA41DCC73987880A
+:10D3B000FB70F0389796DD61DC3F2CFD70A2FE39E2
+:10D3C000DF252AC7FAD8DBF95C1EBF22FD6F46FFB6
+:10D3D0005E8BC344FEA996DD9114E7807EAF68A002
+:10D3E0008733A65D09835383F3D31A559DDFC8980D
+:10D3F0006ACBF6D079F2E11EDAE21C8C6F37BBED16
+:10D400006EC8DFE73844EF788D137630E37C5B7FBE
+:10D41000F76F287F57A7C5C7F5DD9602FEDE09F036
+:10D420004786FB49C6734C64A0DD415A18B896E69E
+:10D4300073B5FEAFC99773B9FFF7F2106AAFADB914
+:10D4400096F2DD573CB008EF194DAD996FC1508091
+:10D45000C64797E68743D3C66EFEE5E188B7114A13
+:10D46000BBFE8B0773B85C6934DC5B90A9DA8FEF85
+:10D470001B573FC9CF453CD73285F6C36285C9F8F3
+:10D480002EE2E7327FA956E4F3797EC94A9E6F14F3
+:10D49000BFABB04DD85B70DD98E2BAD12EB043D8A7
+:10D4A0006370DD98E2BAF13BF22FCC23FFC23CF26D
+:10D4B0002FCC23FFC214F9177E2F62DE945C95FBFC
+:10D4C000ED4687EC0FF4DB8D0ED18FD06F179A47A6
+:10D4D000BF5D687DF4DB8596A3DF2EB41CFD76A1CD
+:10D4E00079F4DB85D647BF5D689E0DBE3198477ED7
+:10D4F000E799A8CB4F06FD7F74C8FE46BF5D68FF65
+:10D50000E8B7D3F5A72DD2B5BF8D55E9DAA3DF2E45
+:10D51000B4FE1D558ACEAF7787788776F68638A217
+:10D520001F5FAAB701E9FE4F11FFB8CB82E745B5EF
+:10D530007E013FB785BB399E6B0B38DE4DFC9E8567
+:10D54000D23C83F0BCD4CAF3F93CCEDB483FE817A9
+:10D550001B6DE17E314CD12F8629FAC53045BFD8ED
+:10D56000E89EDC2F8629FAC5F03BFAC53045BF1886
+:10D57000A6E817C314FD6298A25F0C53F48B613BBD
+:10D58000F48B618A7E31FC8E7E314CD12F86DF4F49
+:10D59000A07FCE129C17EAF33D74E74AA043DDB9A1
+:10D5A000D2A9CBA33E1F5A1FF5F9D072D4E743CBC3
+:10D5B000519F0FCDA33E1F5A1FF5F9D07C748E8B5F
+:10D5C000F621EAF5A1ED50AF0FCD67D7FA5E47DB44
+:10D5D000D9F88D178E60DA18A93CA900CB8879613B
+:10D5E000C534F45F3686292931C0392DCAFDD346AA
+:10D5F0002701998838CA1CD66CA2DFEBC3C323C6A7
+:10D60000390418C5AD667F9744E569F2FE1DFE0139
+:10D61000BCE7EE66F47B34D2BF2EDBBB9953C55416
+:10D62000D60FE6DBAF671C5FD623FE19320FBC694D
+:10D630008DF13EB94B1D791837BB4DFC5EEEB6E55A
+:10D640003CDEDA4857F9425FDA66DA7508EFD33420
+:10D65000172A74EF3AC3CC8E59F2104E9579A84729
+:10D6600064F78B11EBAABC0E7F774CCE5BDA41815D
+:10D670004FD0FDC4A1CD0DA3A2A11FCD37827E1F27
+:10D68000679C95EB0FD80ECF957D7D8A6773087DDB
+:10D690005F23F471CDC7C77FE6A909BC5D386FF77A
+:10D6A000CC535104C7092B148A3B1BBA8379F01E53
+:10D6B000B447CCBBEF8E808AE315AEE0E3C97E0BA6
+:10D6C00037A6D0BDD042D6381AEFB5B0010A43BE56
+:10D6D0002DE106EB3B82EBCB80AD8276EC1F7B9F8E
+:10D6E0006AD880987C8C4764F58CDE151D3FE03D40
+:10D6F000DD7A09ED83A85F926BBD7C0ABDE33CC176
+:10D70000B76C39826FBC6FD1EBF1587F0B73A7BA3E
+:10D710004814D1FD63399F3E9E5D26108B2C8B35BE
+:10D7200098C214C4373B1C17423FB0F3A720BE7306
+:10D73000DD167A5779A2D969A1773A3A88D7B9E440
+:10D7400090F13A067DC1109753B3F4A314B4372F68
+:10D750008E3491DD64F19E08D21BB40D0AF135A917
+:10D7600007158A78BF4B2B5E8F9F8670DF65A1FE01
+:10D7700064BC4E79BA3FC584F713BA6CCA8955495F
+:10D780000F58D20FF500DF4BB70CC67A2BF9BBA2AE
+:10D790009756ECE1BF4B2AFC3BF2774EE788F8AF97
+:10D7A000C26C6F34C6C3C8DF5393F764E4EF984A82
+:10D7B0003B4FE1DBFD8F227E0B9F10EF7EAF29A454
+:10D7C000FBEFC6B8AB52A1FF2D5861A1B8AD05065D
+:10D7D000FDB054C4655DE9F74DD7F633E887F277BD
+:10D7E00072441DA676FD3DDA85E5BDCF9916CE07BC
+:10D7F00066EE62E4AF9AB96C9409DFAB667B38FDE4
+:10D80000CC5CC6F59C99AF78E8FEA6D41BDF15FA70
+:10D81000CCA4CBC904FFF785FE3215E35501CEE356
+:10D820001AC3441C5B12A5D32EF3F8D5490ECE0FB4
+:10D830001AF7F377375A7C36AE571D61FCDD380393
+:10D840007D4E34FB4D78A1D13D14E813F2E3511F16
+:10D8500082FEA6A37E1487F49E9A4FF190050ADDFE
+:10D860002332D2FB384BE5EB186F3B6E2B73FB5822
+:10D8700028BD031D637F3E85DE63D0C43957D2B116
+:10D8800091EE674508FB9483DB9F5AED14A8ABD259
+:10D8900023EA7F9A86F1C4B3D066D88596E1C1B8F1
+:10D8A000BDC82C5E7EB4DF9FA6ADC0BB1F1DD82DAA
+:10D8B000D49F58091E9A7C77A2033B02DA0F905F2F
+:10D8C000DE7E67AEB528845F3E9C3BF22BF7C0201E
+:10D8D000BE8B0CF72917DFD7937EFFA823BD7836C0
+:10D8E000C015F7C7ACE8C6BB8052D99FFB31CFE863
+:10D8F000C1F8FB92727D2C80F198B78A7C6C9DED0B
+:10D90000A3350E820BE59BFA9D9F867134E5F6C622
+:10D9100031487615599505189F1DE4539A273915F6
+:10D92000F9546E007F8FEFB8944306FB44AC9BD74D
+:10D9300037DA29666771FECDC47BE39FDFF7F24ECD
+:10D94000945B72FE9F5BF4F76A651AEE16F2A3FA17
+:10D950007FE65E89F13EC9AF92B5BFF783FE1F3601
+:10D96000F1F713BAA8B54CD88BC8AF2CF90613EF52
+:10D970008E04F1EEA1F78DFF0B290E70D50080000B
+:10D98000000000001F8B080000000000000BED7D70
+:10D990000B7854D5B5F03E73E69564122621210F1D
+:10D9A00048980402A94698BC20BC0F9147B068076C
+:10D9B00092286812268447B068236A0D2D2D139291
+:10D9C0006040F0068D82D4C780CA45A51A955B4198
+:10D9D000693B48B56A513148F5D6DE303C7DB535F6
+:10D9E000E2F5AAFFE76DEF5A6BEF9D99733213F0E2
+:10D9F000D1FFEF7FBF8E9FDF669FBDCF7EACBDDEC8
+:10DA00006BED93960D8A735D36635E87F5849200A5
+:10DA100065BB12B08D618CF9666AC13C46BFBFE53B
+:10DA2000307678B48BB114A8E4F5DEF3703263B5C8
+:10DA30006BAD6C233C7A6014D318D41FF891D5EFEA
+:10DA40008371AAAD475EB04399E4E6FDDF69BAC3CE
+:10DA5000C24C384A20D705FDAE6E8C716F84F6BB80
+:10DA60000B3C896E688FCB775BBD0EC6CEBA19F5BD
+:10DA70009F91E249C6E7D76D3A78FF5BF0E8070768
+:10DA8000B2ADDE7CC6EAF615AC4F73E17BDE74778F
+:10DA900009D41D4EAB07DEBBBE35D1EA82B2369546
+:10DAA0003576E5E33CBD59F3E361CDF89BC658817B
+:10DAB0005B610CFA7F50C0A8FCC8C216F07E1D96B0
+:10DAC00079BA7E266A671D5B35FB108003DF3ACB8F
+:10DAD00034339FA990B1E1562FD360FD2DE9CC8D51
+:10DAE000F01A0ACF6D85BC3D2629043F23DCAC8C9F
+:10DAF0006926681F0AA5B53004C74C6857E1B925E7
+:10DB0000EFE442968370638B703F723DB25C2CD61B
+:10DB1000CF16D84D0CD6B5D40EFF862166AAF9B320
+:10DB2000528B195BB54571DAE0D11287EBAA095027
+:10DB30005FF29285AD83FADC2497351DEABD70BE95
+:10DB40003BA1BEF8A602AB0BF65D8D6701EB58B2A8
+:10DB50006D02730D86D20F6551FF796579CD9643BD
+:10DB600099FB5D787C9AD503F05AE2D4AC49F9A1CF
+:10DB7000F6FA0E45F33BFAD7E7BB55DA67351C29B1
+:10DB8000C2AFE6A66CEB6207D65FB2ACCAC77DB97E
+:10DB9000685FF23DE817C07E7373D88B0CD70DFB1E
+:10DBA000DA99CDE72B0C1B7F318E1F363FF45FE4F3
+:10DBB000C17DB9E369BE3A27EC3B1B4B27AD13E0AF
+:10DBC0004070EADD0CE3B9681E3A8FFA80DFE2C6E6
+:10DBD000F598615EA85FEDF45B709EC5AD055606D5
+:10DBE000A577139FC7DB9E68BD04EA7566A735134A
+:10DBF000E789055824D3FAFC3BE16896005C921C47
+:10DC0000380F5B34DFD11F3E7562BD4B3A12AD4B0E
+:10DC100075CFB758F03C16C27ABA229CFBED78EE6D
+:10DC200029B89EE95686EF9B35AB1BD723E07BE6F0
+:10DC300086988D6C10BCDFB9D5920DF59F22FEA69B
+:10DC4000E07B1CBFE6E6047215DCF70D316E5CE785
+:10DC5000426707EDAF0FBE77013CE0F952A787E0BE
+:10DC60000B78E1630087259DFAF30CAD87C37749F4
+:10DC7000671DD1DB32B3D7EA0C5FC7B683B90AC0E0
+:10DC80006521D0B702F0674E6F16E2CBD9BBAECAA2
+:10DC9000A27DC23A11AEF16ED7ACB462C213C263B8
+:10DCA000892FB5459C7EE57CBBDC669A6F97D8577B
+:10DCB00074BAD45E4C43BA84F35DE78A4E97560635
+:10DCC000E3C1BCD6258ABF45E94FA7923E255D4AF0
+:10DCD0003A95F47BBFC5134853427CA676106B7C03
+:10DCE0002A029CCE0A3E72B5385780EB6F10AEB256
+:10DCF000FD7571AED5397A7AC7F170DCE7647B596E
+:10DD000020F786FC507F396F75127F0FF11EF1ED01
+:10DD100039011FECBF8AFA0B78097E51DFC72FF655
+:10DD2000B40D417EF1A4E2467EB16AF3A1CC5B0062
+:10DD30006EAB7E1E879C977DB8F2E1EBD3010ECCD3
+:10DD4000ECA77393EB5AFA7901F189659F4FE2FCD6
+:10DD50002210995FB8F2BC87916FCBFA923B7F3E5D
+:10DD6000CACBF94D00F9CD1F7FFEDCB189C84798B9
+:10DD7000DFE2B924B49FC5ED6F58EA1CE1F0E3FC83
+:10DD80006E63DEB93A3CAF7A87D5A5C2A3FAD63A1C
+:10DD9000E2BF2C8DB97395D0F91BF1A2AE55D1E835
+:10DDA000BDA6717EF55BE4D3F59BE6319453F2DCBE
+:10DDB0006062C6C6C13E1987AF5CFF4762FDE704DB
+:10DDC0007FBB5AE0F7D50DD3ADE9C9B8DFBA22E081
+:10DDD0008C6CA178BE7089FE79DFB939FBF8FC7ACA
+:10DDE000A497735DFCDCCE6DB210FF39B727DECF90
+:10DDF000607F1FAE7AE6B52BA1DF0777EFC862AA76
+:10DE0000FEDC58113F372C97C3B9B1C111CF4D2D4E
+:10DE100008E3C3CB1FE0E756FFF8ABFFF1AC8BF68E
+:10DE2000CBF9DD669B1FF9F1E2AE27E91C17B66F4F
+:10DE3000B16443BFC105D93A3E5EDF58E06400DFFC
+:10DE4000ABDB7758904F0C2EE07034D203941A0B52
+:10DE5000A333944B4A12E25F301DF14FF647FEF8B0
+:10DE600024CC73D30D31096C6C689EC9059CCEEA35
+:10DE70001B139370BEFAC6BADBD998903C30EEF310
+:10DE8000540CA797C5301ED2EDA9E9EEAC55849F7E
+:10DE9000A68872B7A8809FE3CF00DC31800F43E3F0
+:10DEA000BA1E41380CFD41AC1BF9C7C891413FCEA9
+:10DEB0008BF88DEBB602FFB443BF912B831FE33A7F
+:10DEC000460286E17B58C62751C986407D272CBB78
+:10DED00014CA1C95970B0B389E407B00DB5972B01F
+:10DEE00004F72FF1DB88BF56F6507B0EF2B164E6E3
+:10DEF0006E7185F0558E23F155E273B4FDCD2BE0A4
+:10DF00007CE57CFB3B95CDE1698D85FD257D85FD1F
+:10DF100001B2962685F625D7C7F2605DA83FFEF8C8
+:10DF2000921D1B619E53CDEEAC46C740FBED9C3964
+:10DF300024C27E8DFB9474B3C4CE691AE866501077
+:10DF4000D67DAE63C420943BA714906FF0DEA91B6E
+:10DF5000624CB87EB9AF5D6BA133AC75F75A3B9597
+:10DF60008FAE05C21BCDD89EB569547F7CAD8BCAE0
+:10DF7000AEB579F4FCE68224BE0F168C473D13F44F
+:10DF800001CE0F029C4E7A9A46D0BEE473A917F4D4
+:10DF90003883F14961FCFB74A3909B2CB819E99B71
+:10DFA000358D600FC3543D1DA7E24DF9889F7C7DE0
+:10DFB000F2BD9B2CBDC40F59BCD5F530905CDC4D37
+:10DFC0006FCC4C85F99676661728F05E4D53514F0D
+:10DFD00013B4D7B4A6BA916F2C75B8D6A35C5CEA1B
+:10DFE000CB76A35C8CEB2C38BB0DDA97B65EECC617
+:10DFF000FE3729CC83F405FC9321DC96B1BE9F66E5
+:10E0000007BEB65CF0B5E5C82F015ECB9A0E8D74E5
+:10E01000C2FBCBDC310528DF976FE376C25C136B64
+:10E0200057500EB77866211FEBBD4771A3BEC9EEEE
+:10E0300005FE6A0FF1577F9EA7A300E5D297807F68
+:10E0400030FE45288355DC579786FB60A08F3CCC7B
+:10E0500070DD1ED2EB07097CE9E93C11EFCAE7F05D
+:10E06000467D9D793513F2DD5542AE0DB7F69EB86B
+:10E0700015F59978937B27E797AFBB709F2FABCCB3
+:10E0800046F246F417FC74F84F4BEDC8DF56C5E76F
+:10E09000A4925EB54D25FE28F1A741AC79E98E8AA0
+:10E0A0002188374BA11DE5DD767C082C747DE7A522
+:10E0B0004310AF966C9979B70FE4589680E3697373
+:10E0C000701E9ECF7B3B52939A512FBCAE6514833A
+:10E0D000F6253B6ECDC2F2BD1D310B90DFCF70CE69
+:10E0E0009B9108FB5D766F62811A26377E2DE8F1E1
+:10E0F000DAEB2E4D457B60E55F0FDDEF1C01F3038E
+:10E10000AC11EE9F76C5F97DD065E5DA7D592AD050
+:10E11000D85F6DDE67916F7FDF74E0CA09C8FF15B5
+:10E12000FFAE74EAEF4A7546A0F73EF90AF8EE0230
+:10E130007CBEEEA76FD3387F361DBE6221BCBFF216
+:10E14000BAA713709CEFDF75749C139EDF3DD2FB62
+:10E15000229ED707CA8E5D4E144CDB768C41B9FDEA
+:10E160005B6147CD4DF25CB910E1FEB24A708F366B
+:10E170005FC33E85E02BEB35FE41A4CF7A03CCEAAA
+:10E18000C4D2C9485F7E4F654DA80F48BD463EFFCB
+:10E190008380CB7B833AB2102F56ECDA9A8572E5F6
+:10E1A000FD785EAFDE75D52BC8A7BC0FD9B8DE6E83
+:10E1B00066A427D7FBB8DECD1A805ED343F39F2E2B
+:10E1C00088A3F5AFD856A4938780A1F4FC7D332BA8
+:10E1D000C7750C6FE92D40FDEB1D7360299EEB3B6D
+:10E1E000A0D7A27DFB6B21CFDEE95067E1731F1042
+:10E1F00012EA23EF743C1D3FD211D2E3E28BBB0243
+:10E20000C8E7AEDB9B58A8729422FCBADE29F993CA
+:10E2100063D6D064D2C79C88A7ABF6BF308BF13AE7
+:10E2200008C2E8F0BC56E8617DF5BD4F925DB7725B
+:10E230000FD72756763DF962068C73FD3EA14F0835
+:10E240003DE53A41CFD7EFE570B96EEF096B7DB888
+:10E250003D9297B47E286882B6C2410BEE72A1BD92
+:10E260000D8B9808F8DD655AD80C4C3CCBEDE47A60
+:10E27000A5B997F4C38D79DD64975FD72AC6CBEB38
+:10E280005E9F43FB9D37385C1FB2175A08AEF27D84
+:10E290008007BDF7594CC218E47F81EB62DB51AEB9
+:10E2A0006BD73BCC58B65CE720397F6FA329CF0CE6
+:10E2B000F0D5945837EA714D76DEFF96D8849D5894
+:10E2C0001E88E5F5CF62B2484E7D66F23CB90CFA85
+:10E2D000DDA21E896123F0C87B0F99A03E2AC53BB1
+:10E2E000BC10E64F65403D2ACA8F8082ED1FFDF2CB
+:10E2F000DD225CC7D4E1C14F182CCDA2242E9C0195
+:10E300007832BAD0C9F97B7EB008F13DE579CEAF5D
+:10E31000EFB3B0769477CCEC61F3E17900F9179E16
+:10E32000FF17263FF2E3034AE0C170FDABBA90EB62
+:10E330000F1E9BA35D81752ECFF6BA711DDF532C86
+:10E3400097A0EAC25C6A2E8EFF9185B74B3DB64C12
+:10E3500030E14C618F5933D21CB8BF16012F45D321
+:10E360005813AC635DFEF3F5882FB7F5DA990DE627
+:10E370002FEB8D25BD3633A39CE45B8B808BE24A6B
+:10E380004699C39ECF37F96CB0DEDB98DD8FFD99DF
+:10E39000DDA0FF9A62347C4F39F0DB2F90DF0F5500
+:10E3A0003F3E3408FA0FBD4571B7409FDA7367EFFF
+:10E3B0007B9DA1FDEC2F40F82D4DF15E5608E7D96D
+:10E3C00073AEFC8417CEFB366797DD9DCFC70BDF9E
+:10E3D000C781D55F24249942EBFBA8F7ECCF9F2996
+:10E3E000C6D24E72A8EC80CAFD4D86F57C94E6320A
+:10E3F000D339F5DA0326ECEF30F91505FB1F7A1B4C
+:10E40000D75766770454D4E3ED963F85CB1976242D
+:10E4100033F1ECC5245AD8DF405918D2C2CF6FEA85
+:10E4200020BD7DF98342AE3FFE409C9384AF841BA8
+:10E4300073692C5CCEFCCAB1AB86FBB1381DFF40C2
+:10E440003C3FF7790EE917E70E809E1141EF94E506
+:10E4500051D433407F08E468B7149684E46C9594F3
+:10E46000BA420EAB62DC2A01AF2A8789C3A7D20069
+:10E470001F813746BC309EBB3C4FF6A3232F0CCAEE
+:10E48000A673BCE45F189DDF3A5C47CF1787DB803B
+:10E49000DC5886AA9DF066FF239E5F206634EA154D
+:10E4A000779948AF40BD0FF544C93FBCC807C6D2F5
+:10E4B00073AE07E631E21BB56A2CF9198D7C43F285
+:10E4C0000B6F2C9463906F74103FB845ED7DC1A421
+:10E4D00084F8C4F0F2E02528877BC0F4C7F6A0A931
+:10E4E0008B9EBF549843F8328C1D49C7E760AF94A8
+:10E4F000A01EA8DA1FBCEF348894CE0D9C3E5A2C87
+:10E50000FE7B96217FA872B851AFFBC86FF25960AD
+:10E510009D9D899C6F74AEC82079FE11137C648127
+:10E5200095F8C82493C947F6D6C20CB2B7FAFAE7F1
+:10E53000BAC8BFFA8BBFAAA3B661FB3C3BC9DD4E8C
+:10E5400094C750EFDC7C09B53F27F9D20ACE973A41
+:10E55000E769E9B1D83E6F8809E7DB9EEC7D1ECF05
+:10E560003D43F53F1283FAE4F763D9C3F0BC335B54
+:10E570004B47797BB7E259B814DFBF84AF3BB83063
+:10E58000F6F15DFC7802E84FEA698ADFB9314C3E6A
+:10E590001D1ECDF9FA70DF897B105EBE329687FAB8
+:10E5A0007C0FE2E7D8D0798155CE9A9242E7966CFB
+:10E5B000383789AF3E0B9C5F323FBF754AF4F34B4F
+:10E5C00016E7A734017E13FFE7E7738BCAF93BFB1D
+:10E5D0001518E0507E9CE20DE27E5B6E8073218117
+:10E5E00018BC19E175DFEA780DF7D163620D5D1192
+:10E5F000E8F643C11F184A63A08745821E1649BC2E
+:10E600005D63C0DBE0B0C4B371026FE1FDE7E23CE3
+:10E610007FC679FFAC1C1D870F0FFFB7BA20D23C15
+:10E62000FF25F8CF41BBF7D34292AF653A7DF57035
+:10E63000C1BB9928A7D8978786A1DC7D2AD9F33951
+:10E640008E1B33B297FCE63DE9BD16DC67CFC20FE7
+:10E6500032512F5AD4F45BA2AF0B5DE7BAB85A0B14
+:10E660008E9358996D0942995A99FD02E2CFB139BA
+:10E6700036972D821E7270CEE84CD47FBBAB4667B6
+:10E6800022DFEB86033C82EB33BBE291FFB17D35A9
+:10E69000C4C7AA041FEBAE1CC19F0BBE19F67C7346
+:10E6A00031EAB50E933B5C5F3096EF03DF0C00DF81
+:10E6B0007C17EC332CCF807D1600FDF514D86758FD
+:10E6C0003F01F61996C7C13EC3B27BAD9BDA5B2A08
+:10E6D00047EC0BC2397FDAAED0F8E8BF8DA4175FE4
+:10E6E000FB90CA02123EF07FC3BD712C9017AA2F77
+:10E6F000EB1CACAB2FD93454575FDC3A4257977AB6
+:10E70000A477CDC5BA712BCA8B74FDD6C58DB1E087
+:10E71000B926961770B8971710DCBB2F8F02F7CB6E
+:10E72000C713DC8FCE199F89F03C8A7047FBCDEC74
+:10E730008EC77390709F2FE63C5A5EC49F0BB887BC
+:10E740009E570C28A73E4478DB10EE762ADF4578EA
+:10E7500013DC39BC4F21BC6D08F73C2A8F23BC4722
+:10E76000E3B800EFE2F3C37BE51E5507876B1FD2CA
+:10E77000C3BBE1DEC106F80FD5C171C9A611BABA93
+:10E7800084F7E2563DBCBD6B8A0CFD18DB0470A813
+:10E79000C07F001D1C2D994D7129B39DF9E280AFFA
+:10E7A0002422BDC1FACD950AD78FE0D70174381F56
+:10E7B000FF01F46576F0F6D6858A1FF912EA4468FF
+:10E7C00057005C0371406715CE5167902F5D851C23
+:10E7D0004C45BBDE4FE5352C40F459C382545FC431
+:10E7E0007AB3AC505EAF06D6A3FFEE55BBF7C62298
+:10E7F000A0FBFF9AF3468F8244E9AE1B8D74CE1CBA
+:10E8000049646F463B27E0945C1FC7AEE3C4BEE09B
+:10E810005789FC1FDEEB8E1B73F3CD700E1FD505E1
+:10E82000C7E1FC2BEDDE07924D345F7311F2258BAF
+:10E8300077F46078FE6AC9F84CA47FE649D1D949DB
+:10E84000D1E6DB829B0538D495039C148CC371B848
+:10E850009CAEE27039B8C566457FC6E90D16F25721
+:10E860006E8DCBCA42BC3DDD363B0BF1AE79CBE8B9
+:10E870002CC4F7F9EDB3DF47FE3D539D5B8BEF9F53
+:10E88000ECE078CFD80DA477DD2CCEEEA48BB903C5
+:10E89000D05E3527DEED83FD787DD909B45EA639DB
+:10E8A0000AA05FBDD8777DC7F2B9389EDCFFE24D84
+:10E8B00036DDF97FAF545FAF62D6109E65E3395BFA
+:10E8C00043ED78FE6AF520EF007674D31F77BCF233
+:10E8D0009BB0F11E2B8A4F46BECAC6B3F17F53438D
+:10E8E000EF4783EB676BFDAFFC26370457894FEB8F
+:10E8F0008B3C7B111FE031C5DB8096481E5CDFE757
+:10E90000D73A9080F0DB12F7ABDB27215CDEE47EA8
+:10E910008EAD71B5C43F3E44BE9D8D7CFAAACC60DD
+:10E92000185F90EF07053F3DF6F3AB888F1CAA4AAE
+:10E93000A5784CF75EEE5F3E2EE8BEBBF2AA9A9B2E
+:10E94000817F76EF5149CFEBDEF7C90BE8A7E9EEFF
+:10E9500052DC02E4A6F071BBF7013F477EEBB150F9
+:10E96000FBC13D4FD33ABF2D7E5EB95FF0F36D7CA6
+:10E97000FEA5660FF117E65DA0DBDFDF8BAF9F8F93
+:10E980009F1FB3703CED3EA692BF8DF9B42379432F
+:10E99000C2F0B39CE36773958D71F9CAF9CCFC4A58
+:10E9A000A003D4F399AB046DCA0FF755A490BCDC57
+:10E9B000643989FAB413FE43B96D846315339F0C2F
+:10E9C00086E1EFCABDD03F6C7DF3B13D0C9F8DF861
+:10E9D000AA1403BE5E1CC2D74FD99759D61CDE7E3F
+:10E9E000644888EFE12F9CBF48BE25F117F8562DEB
+:10E9F000F235E02B8E62C0DB1F1666FF32A884F171
+:10EA0000950BE4635BE2FE4A72706BDC5F098F8FEB
+:10EA100056093C063D039F775FCEF50DE65F40F457
+:10EA2000B048EA11164F3CFA498FAD199C80ED278A
+:10EA30005A2B88EE243D19E73B2EF04FF65B64EE2F
+:10EA4000B5B823C843EF1A3DFEB0DD0B08DF6F36C3
+:10EA5000E059B4F18DFDE53C8B0CF15EE33C938B0A
+:10EA600085DED9557341F32119F6BD4FFA6D6C0857
+:10EA70002F55E4039FC50749FF5AA0D3CB8E978F2C
+:10EA800027BDEC68E52711F5B3E3959FBC3A1EE975
+:10EA9000ADDC22E8BD81DEAF10EDC675BC2BF4867F
+:10EAA00033827F9C12742DDBD51D6D43AE46BC5F57
+:10EAB000A3BA915F1D9B5B4478FE9EBF8AE63F5ED2
+:10EAC000A992BFA976EF77AE467F935C8F9CAFE2A9
+:10EAD000F24FE2D19FF629C00BFD631516774A2449
+:10EAE000FDC2088F68E34AFC017DF618EEF328F2B8
+:10EAF000516CF5EAE17414DF87F6F93B548AB719D3
+:10EB0000E17468CE68E24BC7770BFE0970453DBCE7
+:10EB1000E15EFDB92EEB8C33F09BC1BAF6F9555C82
+:10EB20002F93FC5AAEEFE89A1129CC71E1E72DC77B
+:10EB3000B9507CB956BC8F62F36F247F9374E38124
+:10EB4000A568982FC7D07E91A1BD505FBF403C3EC5
+:10EB500021F047CA9F1331EE9A4871BCE397D91A46
+:10EB6000C2F313FEB598FB87FFB558C4BDBFA2DC46
+:10EB7000DE69E083E77B5FF2BDA622CF23C8EF58B2
+:10EB8000A082E2D917CAE7C2E4FC93C548E741C5B1
+:10EB90008AEF4BBDEADA722E17B6C63D4E791A7F60
+:10EBA0006EE67AD1C1661BE1E15F2EE7ED7FF9B732
+:10EBB00077499F3AB47F6B42B89C9778F9FEBED9EB
+:10EBC00009E8173E5DF96042B81D20DB3FA87CF0E4
+:10EBD000F68944DFAA7BA073F9BAF64077A5B0079F
+:10EBE00084BEF07D73D7FF157BC06807CC54EF4D12
+:10EBF00040FE67B407DE7769094E828FA03B21573C
+:10EC0000AE15F0F98B454BA038DDEE222E570CF8EF
+:10EC100029E17056C26153C580787346C805595FB3
+:10EC20006A66040FAF9D91BECC3A1537C6BF304D12
+:10EC3000A514CEE54865C183E8BF92FD7F54C2F3B9
+:10EC4000A9E43CC7EE53BAD0BFF2DBD68A9A9B3117
+:10EC5000DF616E1CF155D97F996F60F9756C73E2B5
+:10EC600015388F779BEAC6475EDF8994F0F54B3DF8
+:10EC7000CDF8DE0A73C705D9D15EDF8E04B46F8389
+:10EC8000629DC1833156577CFFF7305E83FB5F3155
+:10EC9000577537C3FA576CE2EBAAF2A9EE1CA8FF2E
+:10ECA000B6E3C12B900E4E35594CDC3E70EAF0FCB9
+:10ECB0007047D16BD8FF7439972B272A2F4DC03C52
+:10ECC00038DF368B3BD7D57FBED108478CF3ECB30A
+:10ECD00099D07FFA7E938505C87FE1217BF9D8A67C
+:10ECE0001154BE8FF0E3F6359D7F5109F7739DEA0D
+:10ECF000A81FC2E9C945EB90F87262B75AEE8FC0FF
+:10ED0000AF8AC47C67BE7C82F0EDC5DD15248F4FD1
+:10ED100055F279CEAC7127203C7FB749253A3EEDBC
+:10ED2000E3E31FDC7F6BC244D8C7FB957C5FEFEF4A
+:10ED3000BBE5B509B0CF60A594C75C4EC9FC9EE0A9
+:10ED4000A61114EFFD732BB7BF25BDCB78F8A5AB8B
+:10ED50008F25D0FB52CEED59A05B7FF7EE53648731
+:10ED6000BDBF0966E372CE5180F986FC75B66CAE04
+:10ED7000FE7CE757C6E9EA8BDAF5F2AC793FE75754
+:10ED8000463D77E926D083D12F65B0F3EA9B8B12FD
+:10ED90004A917E510FC63C93872B5E48C57D74D542
+:10EDA00050BF4A1137ABEFB4E9F84155ABDEAE5B6B
+:10EDB0006CB0E3FAD975067924E1745D14F924F591
+:10EDC000B96E61AF1CB7786A22E553AC2EE17ADBED
+:10EDD00022A0DF348C1331AD6A9280F746848FB560
+:10EDE000F7D35CD0A7BB55F714D4ABFBD181410F4F
+:10EDF000AC28D7C397B97DAC54FA235CA4DF9F45F8
+:10EE0000FDBF7DB090DB3E9043F12897B41F97A0E3
+:10EE10005CBA50FFC105EBE7B5423FAFD5E9E7DD8E
+:10EE2000D825ECFD835557919FEAD8E55791BE7ED2
+:10EE3000ACCF4FE5D1F9A9A45E776C6E854EFF0C7F
+:10EE40007B3E880DC04FA3E99B27901F139FE6725E
+:10EE500069BDB0235B851D796CAEB0239319D19148
+:10EE6000D9ACB148FCECABEA6F8B5BF572C9BB4621
+:10EE70006F3F3E33DDFB5409E0872DED22DD738BC0
+:10EE8000B350EF3F34E0E750C6FDE7B7A22F00E0F4
+:10EE9000DE52C5F34EF139E6BF48B9C4A03FF28B4C
+:10EEA000AA4D17F937F2769F5A88E9720C553AEA5B
+:10EEB0006FE6754DE1759F43B4AB22EFCD02F513BC
+:10EEC000D9EE05A877615E4F5C126F4714190A7876
+:10EED0009D9014927FE8D78FE1A1755F02BC37AC9B
+:10EEE00032FB3748D798EF330AEAC74AB2096FD2E4
+:10EEF000D0A55F48E30730AF27D8328DFCCD15F69B
+:10EF0000041E9F073B7A60FC6BE6F650F9609A6C32
+:10EF10009899AF272A3E8B7EE7C3E7303DEC24D19A
+:10EF20000B3391BF654BDC180BE2EF7C872713E1B5
+:10EF300000F84EF2B5FB9756E2C307ABB81FB67B9D
+:10EF4000CEF8FB6E82E7639E70902FBD7BA9F483A1
+:10EF5000F7C687E3EDF135A74CC8977FBF8FB9316E
+:10EF60008FF1F89EEA175E81710EADA9DF5C8274A5
+:10EF7000745825BBC1E8BF9DFEC464B2BFAEBC5C83
+:10EF8000A5FCEEA3E52A43B9767453ACCE0E09F97D
+:10EF90007555C28F4F0F98A91D4D9D3CCCBF42FFA8
+:10EFA00026E66995F3737956F0B32E718E8F083D7E
+:10EFB0006697A09B4E41377708BAD960F4EFDECB55
+:10EFC000E9E6E83E301C40AEBF3EB7BE8CFCD6DB67
+:10EFD00018C5A1B3E7A81B8B617F17DBDC1684DFA4
+:10EFE000F4B9051C9E958A09E33715E50516A4F7C3
+:10EFF0008B07BB2CC8472BCAE7517D466536D9F92C
+:10F0000007D7807C447B3FDE9D89743972AE2D60CA
+:10F010004A40BBB188F8C4A4F74C3A7A2908C4EA3C
+:10F02000E8EEA2879274EDA3B765E8EA299E1C5D1D
+:10F03000FFC1E57A7A8C1D59A8E7BB8CEB8512CE0F
+:10F0400033D5C9E4E73A1E92A3D42EF511E9AF9364
+:10F05000FD015A3ABED62EE4C818A8633EDD86CA22
+:10F06000163BE64D7CDA6576F3F1AB493FB067EFCE
+:10F07000B5239D606815F3ABDAA5FE29FCF74C6358
+:10F0800086756D6218673D5ECE089F62463205F553
+:10F09000AF4E71DE778A7981AF4EB7909F8E9FE336
+:10F0A000E0B91EEAC73C7AFB200DE9AC10F184BF41
+:10F0B000FF88787F97C097E3E50FAE8B457C58C0FB
+:10F0C00048DF98A9AE5C87F1C4E37319D14957E0D2
+:10F0D000F9585C3F8E83F981CF461BA7F2E977AEE2
+:10F0E000C7F5ECB6D238150FB1A98827177DEFC444
+:10F0F00007AF21F8B6390FC5B0FE7278CC439A1B22
+:10F100008193F71E0B58A80C68C87FF2DE3BA26102
+:10F110003CF0A2BFECFEE07186F372B9D02EF0DBBA
+:10F12000C85F1F7BF8178B513E3FB66B7BE1DB500E
+:10F130007E67DD3D194D503EB2EEFBDB6F7285FC04
+:10F14000A5BBAE58BEB313EAA3BFFB9347F7225E3D
+:10F150005DF1933FECC5F55EF1C57F3860FDA35AC4
+:10F16000E219D2B75C9F719E34D6AE605C14F92868
+:10F17000F165B38FEA753EBDFD6394FBD8DF0CF0FB
+:10F18000AB687A8CE2CB69E2FDA397DFAAA830EFE7
+:10F19000DB759CAF74AFEDED9C61A1FE01EC0F7CC3
+:10F1A00092F235870E03B682EF5B7D0AC6C54141F8
+:10F1B0007263BC371DDA919F33978BF4AB2C89BFF8
+:10F1C00082AFE0350746FE4033E1599E884722FF73
+:10F1D000457E7FE7381E071FEA601A9E6FF9739B12
+:10F1E00014CC537BCBEB72935EB096DD3503ECE42D
+:10F1F0008B549E779157FED6D5782EB055B3B73045
+:10F2000034EE6EA1D7953FE7A0BCEDB7763B769084
+:10F210009E7FE40A53B87E58F6D89F9EFA1DE257A7
+:10F220005D0CE197516FE916F4D157B7B8EEBB0901
+:10F23000E0E3FBA59DDB559A2B93EC74B72B13F3FE
+:10F2400077FAFAFD44C6D3DCFF81FC7C7E751CC5D1
+:10F2500019645C492DFFB80DE97151696309EAEF42
+:10F2600019780E834371ECB7575829DFC0A7C452F1
+:10F270005E7AB478F5A171D9229EDC3896D6C11A8F
+:10F28000C763F9C98296FBACAEE8F2AA559C6BB491
+:10F29000768B957923C5950F8DE3FE90163C074B31
+:10F2A000D839387E7F35C687A39D0333FB0B29CF22
+:10F2B000D26E1F897920A9E2F1D6B89FBE8AF2AA40
+:10F2C000E7189757A94D9FAD45FA937E8BDA34D650
+:10F2D0001737D3E03D8B782F55C459908651FFAE38
+:10F2E00015F1A29E1A46F1A2D4A677FF1BE1B34501
+:10F2F0008C5FFB261FDF6A0E1C447CA975B848EEA4
+:10F30000F4A424B8F15E13FB92E7A764308E8F72E9
+:10F310007C26C6C795B3B075A7C656BF4ED7A7A65D
+:10F32000B2401CE28F62A77933D6D828AF55EA578E
+:10F33000A94DB7DEA08ED18DA7A05EFD5635B7B71B
+:10F34000D1ECEC1B375BA757919E655C877CAFC700
+:10F35000C2F6A1FD1BA667911EC6C2E719A1AB0BA1
+:10F360003F9ABE6E49B3EAF8C45B5F560C6AE4721A
+:10F37000C0953C8EFBEF101E521F937A5BBF710548
+:10F38000BD87E9973EE417328FA24F4F6A08B39BBF
+:10F3900072FABF27F3D5E4394878467BFF99E95ADA
+:10F3A000C278D2B302348E570C638A7364117C0D19
+:10F3B000FC12D816CFA7177A286891BA3C06A9572D
+:10F3C0004AFEDC23F86E303B487E4399273E0CDE34
+:10F3D000C9423D687C22D183D44F8FAFFD88E2EFD4
+:10F3E000B5A887C2FCC1751FEAEEA114974D1F395D
+:10F3F0009EFC73FA7C89B0B82BADD72BF8E64CD5C0
+:10F4000041792B3D2CD68DFCABC727F4B13FC6917B
+:10F410003E26F985913F5CEED6F3FFEF95EAF9FFC2
+:10F420003C6DB0C12ED4C7A9AA3C8678F89B7374F2
+:10F430007C53F29F5BD0CDA7A27BC943719DC38251
+:10F440005FBE26F4402B6BA4E776CC171D81FCBF72
+:10F450008B4A073B426502EBA5D2C99C945F93C4DB
+:10F46000DC5426330F9543582395698CE75365B0D8
+:10F470002E2A87B1235466B15E2A5DCC69C23287D9
+:10F48000B9A91CC93C547A9893E2E46FC607338F3C
+:10F4900002FCE65EC5C86FCF7C7BAFD1E09C7AAA48
+:10F4A000441D1108E96A26E3C8E77B8AB7CF91F5C6
+:10F4B000A7AFD1B07D3AEF5F3F7EFFCF7C0EE23742
+:10F4C000A2FD17BCBDAFFE6FD74CC7F72D26AAFF14
+:10F4D00040F47FBC585B82F8DA349ED17927166BF2
+:10F4E000CBC2EB4F16690DE1F5E325DAB5E17556B0
+:10F4F000A4AD44FC91F5B145DAF5E1F5B612AD9154
+:10F50000D779BEE99B168DF45DF8ED56C6717CC3C4
+:10F51000DF20D5DB4474B34731E3B9DA04BD59F1D8
+:10F520001C55A423B7DD86A587E7FD04631CC138FD
+:10F53000D300F68F818E82C89F000F2F51BC6D348F
+:10F540008F819F283E913F98AC8F9B00BE935F3583
+:10F55000B886DBE98C456E97F39E0FCF9916E6E7E8
+:10F56000CD098D1B6D1F46FC3D22F4BC6EA1E7BD8D
+:10F5700029E2C87DFB0E9A13CFDA43741CDD3E34BA
+:10F58000B3B3E1FCB2DFBEFF546301BA0E36D99CBF
+:10F5900028EF7A62D86B68A7F98EA90CF58CAFBA00
+:10F5A000DE9AA2594F72BE38CC49F903725EC16728
+:10F5B0007AF09FA0E75C3C48DA976E3B8737B73B11
+:10F5C00012C5BA5A66245D9647FE7CAED7E75B8EBD
+:10F5D000CC9B0DEB4CDDC4FDAA0948DF183A7BE259
+:10F5E0008F4E8CA375CC3431E4536DD2CF6BF0C702
+:10F5F0006D99B1CA19EE0F6E4BF02B18BFCC08C431
+:10F60000703F4432F3C7A01C2D779753DE8C4F75A3
+:10F610009663BD9A5D9107F5C59DAAAB1CE63DD4E6
+:10F62000F9F42AF4032EA9B6521CC3A2CD7A9FFB8B
+:10F63000FF78FE4692C0F3D60D367700E198E220BF
+:10F64000BF6D7E5B6139DABB2D8EA424C4C5A4EAEC
+:10F6500065E4376C71B85FC2FB1D3EA789F2139950
+:10F6600053B35780BEB2E3267339F2F1CC278B1324
+:10F67000D4B0759F6A3D17837190079C266A7F609E
+:10F680004D997D9903EF3182BD00E521E7490DF5E4
+:10F69000F7EDD007FD8DB7379CEC1835C0392694AF
+:10F6A0005B75781BE7D6D76D067FA3C5A017F48ED0
+:10F6B000177922E3D8383CE7B18F7E49F6EF2287ED
+:10F6C0008BFCEA65ED0AE5C7040FBAB350DF3CB521
+:10F6D0007934E5BBB4B6EBFDD1C14C9685F77DEA34
+:10F6E0003A14D257D5D68F9BF1BDE179AE741C6721
+:10F6F000B8BB37DD19467F0FFCE4873128EF5AF19C
+:10F70000C21AE111E3712161AFCA7BE575CE733591
+:10F71000A8F72FE978C383F04FD44C4433C72DFEAC
+:10F72000343CFF8DD3E7135DE23D2DD463FAE9A3AA
+:10F730009FC33AC3EE27B425E7C4E2BC21FCD5122F
+:10F7400070BFA73B8A483FDAD95E46F7018CE3DCFD
+:10F75000B69675A1DEDAB6D6DE1549FFBD2DCB9380
+:10F7600085F7B7CF6C99BE9EC1F99F39B8220DEFCE
+:10F77000BB2FEDB0B11857FFFEA7B78CA7F996E2E3
+:10F780003D6A9CB7639E15E5C6ECCEE95684DB6DF9
+:10F790006B173C193ECFCFCABCA34A81FEE23A9E0A
+:10F7A000243C71B0800FE1FAEB295A16EA17A773CF
+:10F7B00059C47C4E77A942FCFC77533C743FE54C1E
+:10F7C00066E47EC5A55C3F7FA4D445FDEBCCECB5DB
+:10F7D000E5C9640F3A915E4FB51751FCCE8271773F
+:10F7E000908B967D5FAE45FCFFA4BAFEEDE5D0DEC2
+:10F7F00036E7CAF7B01C6B6D24BD99FD5E257A0013
+:10F80000BD90EE89FD67A5DDD912964788FAA3A6BB
+:10F81000F36B7818DA1F9676356005FE6E397096B0
+:10F82000F470C4572D0C7FE9374EE8F3223F246D66
+:10F830001CDDBBA35FDB6557FA03509E6CAFB74777
+:10F840003AC7E8F3878D8BFAED0CA6C584CD0F522D
+:10F8500031407E6D2F9FAFAF9F68073354A3F509EA
+:10F86000BDDCD82ED73F7A9B9E3E9789F391FA79DB
+:10F87000B4F57EC7AF7FAF058313949771858E5E15
+:10F880002E52BB56615C85BDC5F93FD875CC13219E
+:10F89000CE15E2B3B0F621027E00CFF5C9F3C93E22
+:10F8A00089B60EABFF88963D2664BF7D274DBF2EDF
+:10F8B000D9AFA594C7C16D7E16B0246019A0FB1CFA
+:10F8C00036781FE5F7A7D5373A2F8B4017B234F2B9
+:10F8D0002DFCB9C2E23F463E81683052EA2326FE43
+:10F8E000BE16C6E7E2EFE2FAEFE96D0AE9BF1BB721
+:10F8F000F03C8A4FFD5027E5829F13AA167F13CA5A
+:10F900008E23ECDEE1B2E7DA6FBFC8A583DB128A93
+:10F910006789F6F71EFDD16BD8FEEEE33FF2E07289
+:10F920006F4D5E92C0F9D689C538CF998BADE48F03
+:10F93000C19F5DE207745CEEB7E9F070E3FE47B784
+:10F940002D46B9B3DFEEC674BCA5DBF4EDB6B4B09A
+:10F950007D318E5F3E1D9C8239F3808E8EFFE45F89
+:10F96000E97E782CF24FA4C73536BA17D68F0E4AE7
+:10F97000FBBE334278BB381487A2FB2092AE4E6E9A
+:10F980006A39A3C238EBD7585DF43D0583FD75DCB9
+:10F99000354F4B0B8B0F5BD7F07B9A2CDC4ECC0991
+:10F9A000ED5F8E7BDC576F7739FA8FD70FEFA28C24
+:10F9B00037A84CFB2DF2C5B432CFCBA5148FAEA720
+:10F9C0007D37ED5B73FC15E8737BACF7D5D2125C29
+:10F9D000FF88710ADE9731BBE8DE606BAB2906F960
+:10F9E0007E4797396624C2BBD54472BEA32B3976B5
+:10F9F00024CA258789E2A72857D430FF3E9BC0F947
+:10FA000064487E7812C2F59F58818F67F284FE3376
+:10FA100083EB3FCA130748EF686DE3712AA96F387B
+:10FA200005FE385B791C329AFE838C07D71D5FB2C6
+:10FA3000C4897CAD2D817F7F63C90CB70FEF735EE6
+:10FA4000EA60243786E3A50AD4B31CCC3F1BE651F9
+:10FA50009D5CBFF17630D267921C0E37823AB5D3E7
+:10FA6000EFA3756B9CCEECF01FC233364F6338BEEC
+:10FA7000D9A057580D7A836AA87F51AAD72398D066
+:10FA8000BF653C387EF3C07940D2AFDB21FC13A0C8
+:10FA90003FF9E8DE4829F323DE324D73250F09D9FB
+:10FAA00001E877C4F6B452B6A3252CFEA4682F92C1
+:10FAB000DF40FA25A5FF41FA39C69482BD9610E6CB
+:10FAC0008FF81598962AC5C39226009E64033B20A2
+:10FAD0007B329F29FC7AC6D7D4D39B2E2CEEF3B36E
+:10FAE000E7F9FDA05653AC7B6776FF7EC593397D61
+:10FAF000C61EC21C4998E52A3BDDC399A9EEA17B2D
+:10FB0000F75B8B4D3CAF991D71A23E903F81CB932B
+:10FB1000EC32CFC5B81FE6F06423DE003C7C16BC97
+:10FB2000BF27FCB69937E7C4A23EFC76FAD92DA8C8
+:10FB300097FBDA4CC46F241CB39B4D77201A86C503
+:10FB4000E702E6C2509C6DA3E79C0FEF0BA74EE6C1
+:10FB50007ED7D879A70FA21F74C34813F9D96F8D28
+:10FB6000D7286E07F4635779BCEE258CB7B5BB92E6
+:10FB700092F0BB3B8F27F27626CEF1EEF8213BC206
+:10FB8000F34BE2C4BEEF5622EB2B7F9CC4E54BCF78
+:10FB90007E00E420F26B097BFC0FD59A23BC0E702B
+:10FBA00083F7FFC5C7EDE97913FE50ED33939D242C
+:10FBB000ECF9981AB2D7D1C708ED7B263C58ED83F3
+:10FBC000FAFDD991E7ED98CCE7BDFF65EF70D467FA
+:10FBD00083FB017F06453ADF003395D2B859189769
+:10FBE0000AAEB62D88F41D9B33629F5BA1CD3628EB
+:10FBF000A4C76EAD36EAA97EE2579F349C7C81D2C1
+:10FC0000B4817F94003D24B2C8FCF2FCFAAA3B0DFB
+:10FC1000F5CE96D5CA7AE41F2DA0AF625C30D569C7
+:10FC2000257DB535F187D3F15C3E69604EBCEFBAF6
+:10FC300013D43EE45FE857C57BACB39B389FF13AE1
+:10FC4000B99F15EC38CFA5888FE966C247A9BF9A3E
+:10FC5000AB39FFB9D8C6F3917B121DE4374D6CE286
+:10FC6000F9C7713ED067717F3378FEB006FF211F60
+:10FC700092FAAD23DFACCB23B61AF28CCD86BCE270
+:10FC80008D13F47C28BEA47840BDEA5760FFE23AA9
+:10FC90000F00FFC13200763096CF83DD8EE56FC056
+:10FCA0006EC7B8C18B6BF3A87C69AD9B9EBFB2B623
+:10FCB00094CA6959418A2B921F999C8F2CA0901F3E
+:10FCC0004FE2D71BC3CA10DFA7F3F65F4EAC7EC06E
+:10FCD000370CDA9365FFB1847F7D755F750DF6AFE4
+:10FCE0004DE3F551CF5E5D83FE9FDE99DA4313004D
+:10FCF000EF524C9EBA36ECFB239B3B927D5F30511A
+:10FD0000DE138B6CBF33FC4482DE9FF314F1892831
+:10FD1000FE9CBB15BE8E3F4E7AF05EA48B41F3CCA9
+:10FD20001EC4E3AC1CBD9F7FF044CE77168B32EB34
+:10FD300015A08F01E02EE9235A7BCB7E4081087409
+:10FD400025CBADF16C2ADDCFAEB12E8894E774409F
+:10FD5000D055D4F11DCC651B1BA2B7168791DE824E
+:10FD600014DFFDA4E9C683282FBF39BD31B20F834C
+:10FD7000351AC9EB20D01BF273B581D39B6AE6F725
+:10FD8000336B0F73FFC84EA42FCC87437A837FCE8B
+:10FD9000F6F17AAA81DE5A8CF4E6D0D35B10E90D35
+:10FDA000C64BF471FD22AEBAEB5BA5B7CFBF21BD48
+:10FDB000FD7A4A90F21A7AB21BD3113E5BC5F7F076
+:10FDC000BE2A1DDE35D1CABFCF7189467E81561C41
+:10FDD000C741FAFC26FCCECAEC61CDE62480DFDC0C
+:10FDE000E402FA0EC1E48943043D1C71A0BF266100
+:10FDF000BAE69C88F475E57B74BF31C5C4E9B7E009
+:10FE0000D937491E64B675CF9B8D74B75A253969A9
+:10FE1000DC57EB548E6F2D0A9F174E2E3D3CAE37AC
+:10FE200042D0A56B758B62477DBC8EB973B3E9BBBD
+:10FE300032F4BD9B7F69FD4F278EDB3A3589D6E5CD
+:10FE40006A7E33D1CBFD6B6968BFD195E6C2FEF403
+:10FE500008BF2ECB101D3DE74F1CC03F7B3EFEF17F
+:10FE6000C80445F209CA03F68AFB9B322E12959EFE
+:10FE70000D7EDCA8FEC34B387C8CEFC74FE1F3B698
+:10FE800008FFAF51DF93FB3F3ADD3B1BF7A7385E1E
+:10FE9000E47EE003CC85EB9471B3BE3C23A91FFA4A
+:10FEA00098BF05F56D33A83243B8BA81E3F5E51F75
+:10FEB000093D714599773E8EBB83B90EA27C73B81C
+:10FEC00079BEC233D3B50A82E7D7D4034BCBB46B28
+:10FED00006C2AB15B3B54503B5B32F619471A1B894
+:10FEE000D6F47966CE179A14C1071CEBAD50DF9A91
+:10FEF00008FCCC857A3BDFB713F8868BEC0CBD1D74
+:10FF0000310B9D91C837908F1070B5B998579920D3
+:10FF1000C60FC9EBE00BA8970601B6774053828F56
+:10FF2000CBEB96C39CAF5881AF505CBA94DB09F21F
+:10FF30005E505CBE9BEC2F551BD87E301BECFBE665
+:10FF40008922EFBD901523DCB24CAE3B27C0F3A253
+:10FF50007B661E9D008F4BEE5B3A18C5E9F81D6D60
+:10FF600015F8BDAF150F9FD9817ED209FF6E63E2F0
+:10FF7000BB6A9467F0779433742E07269FE1FA6387
+:10FF800076643CBE620A977F32CE3A001EFB098F30
+:10FF9000459CF32BE0B1E33C78FC58143CDEF30DB8
+:10FFA000F178EF44D8D7357808304ECC6CED17583F
+:10FFB0008F86B7B36669CF0ED41E163FE0F943AC07
+:10FFC00081EC6719BF34AEA70DE56BEE007EA90D7D
+:10FFD0003B63D09E6D69D8F9327EF7B1A589DBD934
+:10FFE0003DF16E7B29DA376FA8F43DAB68EFA3DDF6
+:10FFF000ED036639730ACF8F3EB4DA169806E364D0
+:020000023000CC
+:1000000038B8BCCD70680CF3C5CDCEA0C51B8FFA37
+:100010009A87A19D614D36315F983F66ACE508C96E
+:10002000E51E90E3481F409F9CDE12F938523E4F78
+:100030005B7D274672D8945E90836174F2F2FE5223
+:10004000F2C3C597EC5D85EFA9355617E2F7B4CF3B
+:10005000416E86CD331D3491F0FAA5F674DD383348
+:100060009DD9BAF6D969DFD1B55F06F862A53836F1
+:10007000BF1728F59A39AE025DBF4411E7F86EDE6E
+:1000800004DD7866F5CB3BC623FD0B3D6232FC8771
+:10009000F4AF1AF405A33E61D41FD824FD3DD53139
+:1000A00066918766E6F9115B999DBE4B017C90BE17
+:1000B0007B501BCA13203A19630DEEBC0DFD2A0BB1
+:1000C000ED6E1F3C6BDD7F595A5D71C87FB6B589F7
+:1000D000FBFD5AF6D977203D6C177429E92B3FFEBA
+:1000E000E4424672DDCA501E1BE955E63B497F815A
+:1000F000F427280DDCCFF0D4D46CA207C97FB65604
+:1001000073FBF7674A204619C1E9D29514FA3E5DA0
+:100110001A537C73387D6B49A254453EAACC7BC5EB
+:1001200071D0CE4EE3F3B19778DE64F38FF17D2783
+:10013000F30D13FE8CCCA4909F02F31356F2F77CC0
+:1001400073C47BC345BEE520BEFEC04C31DF18281A
+:10015000D5464DF8A7BD54DA301E0E658EE28E45A9
+:10016000FFC708D543819604115FCF10F1F43825FD
+:10017000C099C7D7E42363818D625E024BE2DF172B
+:10018000297BCCC154A20FEB4E9447B79E70BF8E13
+:10019000A9BAADF13F7C751A3C6F7F4375A39FF4FC
+:1001A000D64CDFDB48D76640061FF9B53C75786E44
+:1001B0006AA5DD391BDE537D3B9A31BE3BD6EA3F53
+:1001C00048E7B9CE46F41E84F7101FB6C7039D2238
+:1001D000BEA2A76B5C281F48C6318213DC7694A3AD
+:1001E00041ECC7FDCD3AFF67847C13F2979A45BD79
+:1001F000D5B193F4F7F5C956FCE226E6F76435214C
+:100200005EA6C4F2FBB78CC70D86E33FC2F2EDAD2C
+:10021000CEC87E4DD0D7080EC1E6E56903E95D5131
+:10022000E3280E53C09A70E17194B66BAFF407C225
+:10023000D629F7BDDEB15359CCBECAFC4C1F476965
+:10024000605ACC98087194A05FC1750E6FE07196EA
+:10025000E1C25FFF75E3285953BF5E1C45EEF7729C
+:10026000F1EFB980D8E29E31C513E8BC4CA1F58509
+:10027000C1EF21E247841B0245A0FE3D517F754F2F
+:10028000F79F1E857F1EDEFDFC1E2CA51E374FB47A
+:100290005F31FAB30398BB356FC32A11C7D2C71FAA
+:1002A0002E07AB2EDCCF8FDF0B08AFCF33ACA7CC44
+:1002B000AC8F13CC70E8FBCF4AD6B7970FB3F53BA2
+:1002C00037F4CBD37E95FEFBBD35EE76C6BF371532
+:1002D000760EEAF9EB76CC9BC3B88FAB3F9E84C712
+:1002E000013CBF34B3A462C41713E9A5DB7DCBEF97
+:1002F000AA02FA590F7294F362978EFE42718F72BE
+:100300000DF149FAFBA3D1D349470EF9FF87371DF9
+:10031000EC9A3198F5C5016E8FF5BE3109BF17E42F
+:1003200038A7A01E32BCE937D47EE5C29201F1287D
+:10033000B7E950D78CB0EF08E69A3D26B49F739B7F
+:100340005EA4E751F5F9FE7C84F2D672055EC8BC66
+:10035000C0ED98170870CF6D10DF07EE1C38FF4D09
+:10036000CAC3D6B0FC3E4A6670292C7C7C29F7FAB9
+:10037000F9D319F7FBCAF9FAF2020DF3F6C93F27D0
+:10038000977FCF4CF77E312925EC5E86B8C701FBFD
+:100390008E9807CA268B7BB1D1F3D8B8DD59F9D234
+:1003A000DB38FE57B63BA38C3B2D2B18F19ED4A017
+:1003B00089C28F1C13CC44BF418F25B25EFFB39915
+:1003C000B392270F60A761DE2CC232DA3ABF6EDE2D
+:1003D000EC04116F92F156993F2BF362CF973FFBDC
+:1003E0004DFDF065C21F10379951698C4318D73BFA
+:1003F00059F8C7B3CB3C9326D37DAEC8F107D9FFDC
+:10040000ED746B44BFF8FD53059EF4BF7F44F9A122
+:10041000B0DEE4703B48BE27F3F28DE3815D74C526
+:10042000E4307FA0B73997FC7D61F696CC8725FA3A
+:10043000D82AFC107D7460D40B453CC4A817CAF8B8
+:100440008852CDFD13401F350807D4BB302F5DDA2D
+:1004500079329F54E68D625E28C5A3BEA65EF5ADD7
+:10046000DB53CD3329AFABC559F6D237B1A7DAA7E5
+:10047000F27BC2D29EF23AB8DFC18BF6D425FDEDF5
+:10048000A9E2326F2BC2CB68571DFFE987941F0B7F
+:100490007668DBE46F834F18FC53232670FC96725A
+:1004A0005AFAD30E8E34E9FCAEB3D43507295FBCBB
+:1004B00081FB5B32B42EB2D3AC0EAB0BFD2DE61933
+:1004C0009C8E2CF9CCAFF1382FF957645E599263AA
+:1004D00059C4FBA6D24E0C4A3BD1C7EFA7F61CE687
+:1004E00071DB38F4B760C7722ED7A4BFC5922CFC5D
+:1004F0002D867CEC38837FC5E86F7962B2DEDF72CF
+:10050000BFE2BA0D49FDE96D337F87A0F8B77B974D
+:10051000C6A1A9FF8CBFEDBBC2DF728F03D6B7FFA8
+:100520006DBDBFC518FF8A10F722E7D599034F901C
+:10053000DF44C257D2ADF4676534F1EF37CD52F7DF
+:1005400028C85FB63A387C55F4672587FC59CA132A
+:100550007FEAF34BD17DDC7E71F2C697719D6660B8
+:10056000381B23F9B7045C8DF1A88426710FF85B62
+:10057000F267BD63806FE13D4577E2778D8BEFAB2E
+:10058000388AE5B81D370EBE1ACAD287EFACC0F262
+:10059000BF5E0E66A3DE69F463BD821F414EE90FA4
+:1005A0005F231C259E7A1B249E3AAC44B7D51C8E33
+:1005B0004638A56A1C4F73014F4145E8C3BF9E44AE
+:1005C0004E9F1933DC2FA17F6D78BE9945C26373AE
+:1005D00013FF5E9684E37601C7A48665E42734E2C0
+:1005E000E9F0CEAF869FEA14E11710F07B6A5BD189
+:1005F0006D08B7BDF756FC0ECB5FF86F8C43B8EDB6
+:100600007BE8CEEF0AF8A5D3F7740DF05B14057EF6
+:10061000D3DCDCBEFEB8CC9B3805E4C265C021D07B
+:100620001FB2B3BDD0AE8F03E9F969EAB7E49F0A00
+:10063000F6F153F65AEE57E0A74F1BFC53A93E4E76
+:1006400037A9BE13449F19409F31E8AF6AE07A246E
+:10065000887D7F9C823637E7AF52AE21CB3181F067
+:10066000D9EEE471E7087ECA007DEFD7C087D1815B
+:10067000138E772057274C4909C9BBED0D3C8E7668
+:10068000E34CCF2484AB8CAB3D335D9B3C85EE2F9C
+:100690007C6DFFE30C9C47FA1F014F69FF2AE03B8A
+:1006A0007EDFFC52902768FF9B1B8216942BB54D72
+:1006B00037285E28DF9EC8CF3F35CDCB30CEDADF7E
+:1006C0005F178C47BD7DDAC83E7CA808C787B1ABF1
+:1006D0003FB913FD5CD1F021234ABED2F9F1A14C00
+:1006E000275FB7F6E143E38651C9178E0F478DF8B0
+:1006F00020E83FB521780FD2AF59E083D9097C0CAF
+:10070000E0A1221EE487E29E921E8222FFC0089F83
+:10071000A06F44943C84554AE900EBBBE0FC031114
+:100720000F6D11F1506F13CF97ED596D9BA5CF3F12
+:1007300070D3BA673B1A95F03CFE0879B2B7E1F97D
+:10074000C938A78C6B7E5CE6D98CCFA7E5F1730E18
+:10075000468F3305F07E2BA09FD380E777139ECB87
+:10076000FB07428FBB71A6B6159F8FB1FA29CF192F
+:10077000F4BD7BB1BE7DFFA3FC7BBBC20F29F3F2AE
+:10078000BEB1DF2CC1EAC7FB92D26FB635DEBA1319
+:10079000CFBB8E0567D2777E314E817EA7CD36CA1C
+:1007A0006BAC57C0F046BE78A9B76B0AE94D1ECABC
+:1007B000C7F556DA9DA8E7B726CE4A43BE51BB5EC1
+:1007C00025B91ECDBE91F4560BFC86E8AD89F39B8E
+:1007D00054C02FC2379F42FC2603F80DE73F1A434F
+:1007E000BDCE8C74E7E8CF6FB60E00FF0BE43B2F55
+:1007F000E17946E03BAFE03EC3F8CEEFA67C83B89C
+:10080000C7A553188FE788FD633C80F68FF415BEAB
+:100810007FA33EDBB76F3D7D49BAFB5F40679F23F7
+:100820005C23D0D9FFF98674A64E8D4C67E6A97A71
+:100830003A8B99FA8F496799534BCE4F675D02AF58
+:1008400064FEB6D42B2E52BBCEE5E2FCFF8FF3B78D
+:100850006F9FC4FDA9E7CBDFC6DF85F84F8DF9DCBC
+:10086000FFF4A7FEAFF5A7FE78EAB7E04FFDF74922
+:100870002ED2DB8C7ED5BDE3B5B6A903C495259FEA
+:10088000364B3E0DFC18796F2DF033E4CFA9D5BD62
+:100890007F7E86DB9BEE3817F91BEEC0F566087E7F
+:1008A0006DE4CBA077DE39F5EFE86FF87BF90DCB7F
+:1008B000265FD87DFBB2C92EE1778D7CEFBE45D88F
+:1008C000F72D3006DED3DBBEDAEA6F8505A78BF3A2
+:1008D00019D370E5654864AFAFB0C60607B09BE4B6
+:1008E000DF91E858EB7DEE746EF8FE5844B9D5B749
+:1008F0003F839E1C6E37B9BE82DD94324DEF873246
+:1009000037703BD70CF28EE2FA5A6900F975864FC0
+:10091000E9C2D4606F72A3827230B5C143F9F05F4F
+:1009200035AE6FC4A36871FE6F3BAE6FCC1BF8474A
+:1009300089F3FFF754FD772D659C5FFA5F8D71F9A0
+:1009400031D68E7292AF3526FC0B18AC75FF073B83
+:100950006FC3F35E68A77B1AC67C806871FB314960
+:10096000D6605C4EF4F8BDF417DC6F697C19EDF0CD
+:10097000FB9B4D74BEC6BC81FC789E3FFED4AF3657
+:10098000DD47F93F521FAE167CA649B1D2771DABA9
+:10099000FDC467BCDAEE668C27A73A5817EA5947B8
+:1009A000A7727A51D334E233E66A2FE1958C4FD4A3
+:1009B00066F17B733102BFD4918DAFE2F889475461
+:1009C00037C6B7376357E019F1282B518F9860A2CB
+:1009D000BC884EA591FC1E1D8A8BFEFE4762BE930D
+:1009E000F4A3C713DDBF5F80EB4FE17FA7E4D09C8A
+:1009F0006569C807D73737A7E1FDC4E2693C1FF135
+:100A00008E39676B288E9E07FA9F42A5EEEFD9CAF2
+:100A100072A7A688BFB7E4A77C4458F7367A6FA4BC
+:100A200095FC6CAA76F78DC807D451B308AF3B1478
+:100A3000E7C2C5785EB956D2635A73C72D5802FB18
+:100A4000DA90E229CFC6734D1C49FB6C4D1C928095
+:100A5000FAE886F41C9ABF5DF19667E37BE926A26B
+:100A60006B55C4E737E42E7B09FF0E484B8689E1BE
+:100A7000BD83CEDCB3EDD8AF7302FF2338C6F5AA31
+:100A80004EFD3D29FCF011F26F358DC7C55511178C
+:100A9000570D71E5324D917F6783E20E31826FD53C
+:100AA000E6AE5B40DF4F70589D88642DF1C12AC2CD
+:100AB0008FD51686713A66EED0E969B7ADD57FFF5E
+:100AC000C591AF5F4F7BDFFD846C2FF219FA1BB02D
+:100AD000942F9EE845FC407ECB93FEE2783D46D4C1
+:100AE0000316AF2FC2F9FCB3FC67F9CFF29FE5FF05
+:100AF000EFE5FF00834DEAE8008000000000000001
+:100B00001F8B080000000000000BC55B0D741CD596
+:100B100075BEB3333BBB2BADA459FDD82B90CDC8CC
+:100B200096880C421E0BCB488D8D66A595B4322E4F
+:100B3000D938FC98C476D6D8B8E43427559D26B168
+:100B4000135AADAD95254BB62C09829C43CFE9DAFB
+:100B500024396DF00125E9690C01CE1A1C420834D4
+:100B60000A10427A92208CE39496E698828968690A
+:100B7000E9BDF7CD6877462BFFC53D1187F3FC66CD
+:100B8000DEDCF7DEFD7BDFBDF72D0078600180EC59
+:100B900007001D6073912709E500676B200DD5D80C
+:100BA000F74E576841800FE9AF35DB0EF702647CE2
+:100BB000D97EB05E05B30EF8EF43D1B8E88E9B1630
+:100BC0005DF863D21DAC5537A48373E9DAE3DA4CE0
+:100BD00009A029EF3C205DD43CA77FA6E3F8E4CF31
+:100BE00064A8D5E7CEE7FEDEFE6E73D1FA12A8FF49
+:100BF000FF1B3F1F5F979A1E800AD18755B86F6A07
+:100C00009788AE8E7C5040F0A1AF73553A83FF9C1D
+:100C1000901283D5B4BF90C7F806CCE583DDCADA5D
+:100C20001CF965E9CB827CB94D1F9720EF0C9881A8
+:100C3000627A85DF21EF355CF6872812A5DCC3CF09
+:100C4000C1A2170678E6435CDFD1ACBC405B90A53F
+:100C50002B6F5479FC72B5E785A695F8EC15D9F899
+:100C6000869EA5CBEBA9069E00ECEFAAB3EF156B11
+:100C7000DE8F1C5221638FC7FF8F9921E6D3C4A654
+:100C8000FB2181FCFDF9C64F9424F2E881DD2E4B57
+:100C90003BBF7F036902F30DD2DFC07FA77E312AFD
+:100CA000F1E4C7C4F3D40A2D3D84CF87A4F4D03532
+:100CB00034EE2EC15F5B0E85961CF02F5C837CF4B6
+:100CC0005A72F2BAF7857FCA02E693C59C1C392C8A
+:100CD000611A35B4EF3E9B9E6E6400F934BCBC6172
+:100CE000C5904EFB1FFD876FE13A0E1DDDF3E6B7A1
+:100CF000F075A0BE61A419D75360780C99F4F9532C
+:100D0000C78EA1B860A0FE0BA34476DBA8646AF886
+:100D1000DEAF058FC8B447BF64123DE5E042DE4F49
+:100D2000789B530F2624634125ED6F4C02924BA113
+:100D3000E17CEFD373F683FF1F2239B37EE63C4795
+:100D4000BE21F7364CD6CFE5FB2B963E2B383E69BD
+:100D5000D345BE8C7BF59B89CFE3FB644822C9F168
+:100D60005D68145700FC5BE6BE4FEF46DBFE42BFFA
+:100D700097E5301151D3128E9F28D26EDB40FD0AC9
+:100D80008F7184998AFFE3BE46975DCDFBB2E76B16
+:100D90006AD579BEB1C8824AB2471C5719BF6EAE38
+:100DA000FEB9D77FB1FA77B7596AE9FB28107D9869
+:100DB000BCD943F6E4B7C65C234F362EA1F97E2E8C
+:100DC00083D09B1E8817CDE54F3FF9838F64F54490
+:100DD000B5F4686FF9FA9F10F9F9F4594D4F99D5A8
+:100DE0000D340FF410DF97859DEBB3C77DCE92973E
+:100DF0002F0D196F31B519131AA89D32256CCF6EBE
+:100E0000FCBCB6569F7F1E1FE4D0AD267AC0FBF611
+:100E100042829945723573E4BAA7B0E10E924BFF56
+:100E20004D2AB0FEB9F97C9EBEAA648E4BC5A40FB4
+:100E30001F61FD48A27ED4221D6FD8A987F12756D5
+:100E4000C27450C829C9CF6326C96959AB77D67F08
+:100E5000FA73FC25E8BB7F2323BD7B63AA3E84EBAA
+:100E6000BC37BEFDABB7929D3F2F1B12BFD7D91F1A
+:100E70007EC19A034627581F4AAC7367E7B17B5E71
+:100E80007B8E6414535F27BE911DCFF245F867D364
+:100E9000BF2A3BDFC1E693834B910FA9C1FCF4EF5E
+:100EA0002CD33F47FCB3F93C1FDD59FFBDF3F86479
+:100EB000F4FA6C7FA4201188A01C4682063A017ABD
+:100EC0007F82DFC34AD4CBCAF9E5891C65FEBC46E4
+:100ED000FFC471DD51538B605F3E864B5F8E7EB1E8
+:100EE00048BF793DBEEA287F7D13F17F5BD0A3C95F
+:100EF00039F6D5B7DF0B99203102E745BD5B07D343
+:100F00009BD6E338A8F1B29ECBE52BF8F9D6A2B870
+:100F1000E2C1F6EAC8129ECFFEBE1BEE5376E0F3A6
+:100F2000E55EED15D29354B9442BC2E7C8405CFA94
+:100F30005A05CC626CBBF4889FCEB5D8E33411401F
+:100F40006B68BC9CCEA586C70E5525C8AE93E654EB
+:100F50001DCA276489EB5ADF54BC1DE9F5BD201B6F
+:100F60007BB01F0A6E5F07A847D22341F6137DE8C6
+:100F7000E77D287725D8F9263D5F7306209AA34F91
+:100F8000AD337E88E6F8BD0852CEEDB7FB2B1DE3EE
+:100F90003BB46AC77B194C23837CEA0A2F738C2BE2
+:100FA0006A5AA9D17ABBF5158EE737D5B538BE8711
+:100FB000A872721AFBABF13F92BB0CA2CFEFAB0948
+:100FC00027603FE77B0572FAF87E6DA4A8FC341D0C
+:100FD0004A37C00D6447289723C3E47F36F8F9DC0D
+:100FE000EAF3C231A904C8F493D048CC36F9BC97CF
+:100FF0002C7D4D46AA594E52F099F7590F1F9FF676
+:1010000010CE82C7A091FCEBDF6AFA710F0EB99285
+:1010100048E2F76154741DE584AE3A1968E4E7E6E6
+:10102000D2523AE7A46437F617E1B8B05045789643
+:10103000C6F961F757C4385844E3344856615F3302
+:10104000A080E45A85743E5BCADF25BBADEFAE12CB
+:10105000DF254B4A05FD86463E47331DD81E060355
+:101060007CEC7FE2089AC88BF4707B15AD0A9F3F39
+:10107000084623F56B619AFD148A5FA2FE4298D45C
+:101080008493CF08BF3DAD844EFB85DFCF672F59DA
+:10109000BB51E0B42D0F1C7C55ABF925B2BFDBEE84
+:1010A000683A27EE50763EEDB0DBEF4474711EEEE9
+:1010B000EC623B51763EC3EF5F8AC4F7901D12EBA2
+:1010C000FD8D73F9DDA06680FC572A02461249A403
+:1010D0001E5D1BDE82F24D3EEA376AE1F2C9E36231
+:1010E000E59006AD80F82AF75CAA1C80CFF9E031C4
+:1010F000FFE121564693CFC93F402EDFBA14B9B85D
+:10110000E501F79401B49CDF8F3E206502D252E6E0
+:1011100087196ECCF21FFBC96516BF4A2D79C8A28C
+:10112000CDC8D673A5747EB910BDB2D2AC7CCE2723
+:1011300097701CDF3766E523F798CC3CFB9CF6C123
+:1011400019C6B74B2483E5B5548E7BA85F28652C60
+:10115000D093E673BD183496CF15D0C36DB9777AA6
+:101160000BE3E19D3811E1D90FF094CD89C752C14D
+:10117000367F35F9D73AC5F060BFBEC8134F231F7D
+:10118000AF542043FBAB542049FE1C9101D34F3D8B
+:101190008AA7159E33293CA63DF4DD2E7F3A2565AE
+:1011A000E76FB0FCF64F8ABEA94DD767F97C92FC79
+:1011B000D772C10F0FFB9FC90C7D1F8E81D1A7CFA6
+:1011C000F567382E295B7E8ADACDF4A285F9962C54
+:1011D000C6BE34F8C3F70967103D05FBDF8B24DE7C
+:1011E00021BD219C1E2C65BF345D48C07A2E2E3057
+:1011F00009576CB1E6D970A3BE388EEBDC32E87BC0
+:101200009DE841CAE7C405EEEF750972BFB7BF9B01
+:10121000D52BF7F7976807B0B3E2827040E491D519
+:1012200025D37970FB2CCE243B29CBFD4EC8492D0C
+:101230004F30EE50C95ECACE4FC7EBC22F361D2FBE
+:101240002A2ED1F15AF8C53EA7B6C319AFB2D45A67
+:1012500027F26B2BD87FE5CCCFCD16FF3E4DE7555F
+:1012600031F1130315DCF73688ABA4B77F86109AEB
+:1012700070FC927DDB8A192F405423FE48998FCA57
+:101280001F5E7B117CB4F8B439F3A65727BFB4B303
+:1012900008DEC88DDFACF7EF6CFC8488D3FDFE1A46
+:1012A0007F4E7C5878EC835E72EA7B0AFFE68556B7
+:1012B0005C7AFF4BB22157D37B819B0320CEEF4258
+:1012C000B2535C77E1E3A7FF87C617BA7035518642
+:1012D0001CBA9EC2FD8C670B8B559D71B64BCF6CB3
+:1012E0001C0D1F081C1CB4B897435722BC6CC73D8B
+:1012F0004C579A3BEF75163EC757910F2F00CFBB47
+:10130000713ACCE273F13E1854859D609C9971C48A
+:10131000C17A5E3BB3D76D7F57A1C6AB8DFA3CDF78
+:101320005B72A8A7401CFDC2C22A48EFC6F50E0E8C
+:10133000EE8814627FAC02748C3061A0F38B12E1F2
+:101340008DB672A14AA166810B690AB0E378FC0BE5
+:10135000FDAB3E5487EFB757050D5C192C7C0B7124
+:1013600032D2B9ABCA6F98F82005E27DB2D923E238
+:10137000C924BC4C78749B251FEFE30267B26CD084
+:101380000EF7B7097CB5EDD867D7917C474A6F3126
+:1013900032386E1BFAA732C263A35EC67388EB1C99
+:1013A000B8DFD79C8303F1FFBB0E791D7DAF0B2700
+:1013B0000EB7210E44FDB671E0FD6DC07646EBA27E
+:1013C000F3E472CD03C172F6A7D729539E7CF93797
+:1013D0005B1E36FE7EA242F0D9FBAEE00B06CC3B94
+:1013E000E8B9EF5D118FA1030F362DA0D35FF0CFC9
+:1013F000D784FCA1A7EF8AF300BFE4759BF81FAD6B
+:10140000DB8D877D2E3CEC5EAF2D87476CFEAC827A
+:1014100055C41FC4E78C13ECFDB8F7F138C6E7518B
+:10142000548A277BFDDC667A356E9FEA0D737BA2BA
+:1014300057872802B0677AEBB87DB6D7E0E7CFF5DB
+:1014400036736BF3612E7F445EF32A6BCD4AFD54F5
+:101450009CCED12BA21E3685B17B3CCCB7B3A89FC6
+:10146000647CC506E5DE707CCC93A690DE8E7F168C
+:101470005AFA7AADEFCC711F8E1FA904630F7EBF9D
+:10148000B0793BEBD99A339EAC9D00C539058E3CB3
+:101490004104CA1CFD76FF958EF11DDA52C7FBD2BE
+:1014A000C834FBA9AEF0B58E71B69CFF8EE22C5C01
+:1014B000DF58F4A4467CEDD6AF778C53EE41F93774
+:1014C00050FCF351075D90D719E4A74B373AF5B0BC
+:1014D000D82557F5EE73C741B69CDF6A73C643F350
+:1014E000C9D7ADAF365F4B67F92AE2CA14C595C8B4
+:1014F000D7524DF0D5DEEF88B55F7B5EA559ECEF96
+:1015000072C797C5145F56E78B2F4F597C3E4F7CAF
+:101510001973C6976EBE9E2FBE5CD0EEF42B17CA11
+:10152000CFCD8B45DEADF47999E31639D6C3E760AC
+:10153000D9946C74914BB4705911F9001CB7B94926
+:101540004D13CE1C83E9309DE70725E42AEA5B5959
+:10155000BD51497EE6E190F1CA06C28DDD220FF849
+:1015600074E4B630E18EFEDD87C37858414BBB870B
+:10157000FDDD68E434E72F141D387F81AD99CE83FB
+:101580004FECF176BEF1E026352DE1F88356BEF141
+:1015900060F76CBE91EB1B134D22DFF827EDBA9577
+:1015A000FF4B86295EB977D3AA4A3EAC14EC5F475D
+:1015B000C30DB693A180564C71746A9347A37DC93D
+:1015C0002BEFFF3CE9C701A9675F0DC56F151ECE64
+:1015D000BBA642AB2AB7E0387933C218EA6F5AF596
+:1015E0002AF9EC890A7D5F0D7D1FAA61FEF5AFBE69
+:1015F000CD4FF38C841674537E64A4C3C332920916
+:101600006714339DBA73C53DEE3A804C1E97E2B71E
+:10161000724F46A5F38AF0474EDEDF96FF5048E54D
+:10162000FCECD6F6870E276BF831FBAF85765D664E
+:10163000531BE799CF129E90E6AFCBECB5F29DB36A
+:10164000E74ED8B99E3CF3302EB0EB12F4A7DB790D
+:101650005AFC4BDDDC99A673741CE231F29FC9E0A1
+:10166000B9EB204AF0DC7590F9EA1EBBDA451EF5AD
+:10167000CB2477915F74D44B94985517B1E2D783FC
+:10168000940F277D70D549EC75F459F452B37AE480
+:10169000AA9BAC562D7A06E4CB5FFFA1F593FBDB4A
+:1016A00045BDE662EB26DF6D07B15E2BDFEDB5E4ED
+:1016B0007F8D3CB983F4F18F9DEFFE6EFBE5CD7716
+:1016C000CFAD13A5D95EE0D89937D8AE972DB0F03D
+:1016D000CBB9EB404304F4517EE32B109752FDC38A
+:1016E000EA27AF1374DD75A1809547F951FB5211BC
+:1016F0006F913F21E12AC662E26B50F97652C37DB9
+:101700001404C72084ADAF7C4B92DAD6C53AD78794
+:10171000C69779F8BC1A2F4A1CEEA7F52F0BE6B531
+:101720008B572DFF3768D56F48813D646F926D1CD4
+:1017300090F0A09C2640C8F9ADF6108F57B4D1E6C2
+:101740003B516F4E913E54F07EF2D67F4EB78BFAEE
+:101750004F0EFDAF939EA62CE244670BD2F90F4BC0
+:101760001F810E8E0514EC88F9FCFA6833E182DFE4
+:10177000B56BE2BDB2C2207B180FE59FEF77D67E36
+:10178000805231ABB2F868E1464107FCE2FB83D2FC
+:10179000990D2757B25CD99E681DF4DE5DFF72D3A8
+:1017A0000FD439E31BB5CA39FE83D97D38E3A203D0
+:1017B000F3D4C7164585BEB62E167A46FAB1278FE2
+:1017C0007EB8ED5DA5BC27C553D190359FF03B4158
+:1017D00065AA8DE29D603D185C53548EF37EE34F05
+:1017E000D41C9B5E497EBED8A03848F1A3AB6CCC1C
+:1017F000C689EE7D9F2FCE5314487A1BE7C67B48DF
+:10180000D72C6914E74C3287DE5551A127726E3C04
+:10181000584DE1887E33D7F1A80E48FD5DBE0DF925
+:10182000CEE9DA76EFAC9FCC57D73914C73882822D
+:10183000D447F6EFDB8AFD77348FE6E3317ADEBA00
+:101840008E66F567EB3AF10BABEB8C464BBB6B2E20
+:10185000A6AE330FDDD9F3786E5D271AC57D8E05F0
+:10186000457D65B6AE734BF905E573C03A974B2DD0
+:10187000BF5CD46DC5113B258E239E6AFAEDF072D4
+:10188000D2B3262FEB01EC9F805C3B59B751FF5A36
+:10189000199D33AFFAA056F83593E8D971B1CD3F11
+:1018A000D5A2DFF6D0F30A8D1FAFF4AC627A90F1C7
+:1018B00079B8D89D54AD56A676B99A914B886E29C1
+:1018C0005875F48C44CF23C8ACDCF86064E6C5F6E8
+:1018D00012CA9304C120173412D17697D03FA80AB8
+:1018E0004478A75A4F93BF6DF7173AFCFF48B72AC1
+:1018F000FC6BADB82F337E5CFFDA361C3FB033C0D3
+:10190000B8E9409547D85752E27A7287E68C7BC691
+:101910002797083CB6DF6BD03D91A39362FCD6C8F5
+:10192000AAB4CCB8DB191775EBCEB8686B65E32B9E
+:101930008417A1DFCBF978CDC2B537D539E3A4A29E
+:10194000EA9E6709A76CEE1778786FB874C156F4F1
+:101950007FBF8AEA8E38714BFF5D5C37EA5781EBB7
+:10196000A9239B54B68F11EFEB87B6326E2C603EE5
+:101970004E6C522B1339F652D6E1B3EE4508FC817A
+:10198000F0323199E77D5987F03BA8D87C8EDBFA9D
+:10199000F2A79F117C2EAE82B44E38AE7B4786E212
+:1019A000CAF12ADC13BEEF0FD7741FA7F95F968127
+:1019B000F6E9D6C3EA8E5AB6D3D9F3B4D9E3E093A5
+:1019C000D717EF21FA7013E8E4D7A231EC531E6069
+:1019D000A30A941FF085FF8AF75B8AFD00F6FDB12C
+:1019E000D1A4827D7F4DE27AC2C54FEFBA7D3052DD
+:1019F0004EE79DB06FDFC6EDF14FD0F8955E08D091
+:101A0000FA4097C2B4BEA4B8CFE0B687BDA91F44C0
+:101A1000494E7B0D8945B4B97BFDDD7C6FA9BC8047
+:101A200071D3A837BE85FDD1AD7E2DC967E034C71F
+:101A300011DEAFF880F46E62D76F2A087FFF382A74
+:101A4000EA9A01DD195FFB6194CFEDD5E6D446FA41
+:101A50006E75B34A150F78AAE534CB6DA2C967F845
+:101A6000701D132D12F3F9BD266F9AE679529D92DF
+:101A700069DE27DFC3B9ABF3D9777EBBB2EDC83DD2
+:101A80007EA479BD9FF4622F4CDD42FC49CE883C98
+:101A9000957B5CBC439C577B53B7D6299CCF52B9EE
+:101AA000DEAE9C31CC12A41E9A89FF3DE55E9351B7
+:101AB00045C449959EA484F406BAC5BD8C81A2C4D0
+:101AC00020E9F300EA3DC749E5E23ED27865B93145
+:101AD0009433DF78CB6D75E4CF5E680A30BEEF3BA0
+:101AE000F1177712BE6F93DFFAEE23145755A92C26
+:101AF000CF016FCFAB1407259B02BCDE138B54F0D4
+:101B0000933F28BFF3418AB3E1E846C8D5D7899807
+:101B1000B0D3892A61F7D2231B390E189764E6B334
+:101B2000597144223CE68BD9792791678A58EE6C2B
+:101B300062E377380F7545B7C8A3466256BE490EB3
+:101B400026592F6F083C48F66F2A5E477CBCE68C0E
+:101B5000335EBEC2152FBBF351FF1BB5F21156DE2B
+:101B6000C9D6CB626BCC44B3E5A757FAD2420F7B00
+:101B70002AB5FAB9F6FDCF167E9EEAF5F33DB21707
+:101B80007B35EE179B6FEF2E433A2FF786F9F9C797
+:101B9000561F9672BF1B5979AB5F677F321D26BAFD
+:101BA0006E3FE2D68BA16881E33CB1D759D4D226EF
+:101BB000EEDF9D618F0C6B82D3ED7C36C254301703
+:101BC000EF677AC53DB7A7AC759EA075FA284F267A
+:101BD000D6F76CAFCEED73BD75DC6EEA00510FB079
+:101BE000FDC355E81F900FD12AD1277F40F22F2D3A
+:101BF000BF93F364BEB0A291BDFBAB4633528E7F60
+:101C00009828EAF9C55DE4F72B82AC8FEE7DADE94B
+:101C1000F0E4DDD7E6961DEC77CEE23CC47FF433EA
+:101C200077B31F42BFC0F36E54EFE07598E897D8C2
+:101C30002FF47CED76F60B5E203D77FB81D2A4B0CD
+:101C4000EF842EF277F63DA159BF80F3A4719EA7D1
+:101C5000D0AF537F00FD00CD33D0F2FA9FD3BCEF5D
+:101C6000BD5FC0F7A22636BDC27EE185B3E8B32FC3
+:101C7000A35FB0EDF0B5139123B9F17C56CEEB6FB5
+:101C80003F26F8A181E0EB86789E38F162E50CE60C
+:101C900085E198B4327D87A83BAACC8779EB8E4941
+:101CA0008F416981BE492566D51D81EA8E76FD3159
+:101CB000A7EE58E0AC3BAAE914E39BB45577BC6DA2
+:101CC000ADA83BAA05D3C1EC3AEC7A633F3DAACC60
+:101CD000D6E7EFEC48ECEA68CAD6197549D4C15F7B
+:101CE0008A985FA6E7505ECAE7BFBB4E69D723114B
+:101CF000DE49899CFA66033EF79766EB5FEE7AA6AB
+:101D00007D2FA3419D3E328C7CE9BBC3CFF8C15EE1
+:101D10005FDFA37FF26AA23C7B1FC0AE77DAF54C8F
+:101D2000BBEE89EB1ECB5D373C0EEC77E031FF61FB
+:101D30003ADFDCEBFD5E24717F47459E755F607D79
+:101D4000711D58F41177913DBF66F1D11EF7906572
+:101D50008FCB5591DF866295E39DB687822013CEA7
+:101D60002E528F905D6C81E90EE26F5F48E0BCD42B
+:101D7000012FFBC9A31D3ACBAF4235F93E44C597AD
+:101D800003C66E24933AAE1553FEA93B6A1EEDE0DE
+:101D9000758CDEB29ED681B89DFCDDAF6BBF5ACE8E
+:101DA000F57EBAF75442F19FB198F220CF77E4BFA5
+:101DB000AFD4BAF8CC7A9EB7C803149FA502C6B3B5
+:101DC0007CAFF80985E9752309B391EF2F45D5520A
+:101DD000A223EEA7F6054FB2BC5A6B7D2B38AF5746
+:101DE000943F0E7CA643C4AD6B91968A743ED39605
+:101DF000F801AD9B72A561D66311DF3D4F7E52F8AD
+:101E0000AF7B3CABB279B01239F13C8D87A39242E3
+:101E1000E7A3CFD21B3B4E7CBBCD7C81E48EF2305E
+:101E2000697EFB1E903DFF4B961C921DE68B34EEA7
+:101E3000756B9E062D19213B6C48A03E486C3FAE49
+:101E40003ABCD00BB7BEDAFA365B87B7F450D2444F
+:101E5000BD16F5EA755EEF93FA718F44F5F6C4E1AD
+:101E600061FAF612EBDD57B69B6FD2BA4BDAE2FF9E
+:101E70004E747FBDEB76BE177CA1F7385A17F784F6
+:101E8000A98E3F1010B8F9E188E1F0778B3A857C94
+:101E900016750ABC742DEACC14DF2F35F8DE37C076
+:101EA000DD8CA36DFF34DA9BF8FEA9DAECF7A95EAE
+:101EB00098A47AD07CEBF0EEDBC179DDBEAA363F88
+:101EC000F91FF46F25D41FA832C3B9EB4815093D9B
+:101ED0004F2E12790BCAA72573EE939776CABC9F33
+:101EE000F62AC890EEF882A2EEE643C3D5F1FCF1E3
+:101EF00099CD7CBF189F4F528AE18A4E5DC4E5E5BB
+:101F00000698146F56C581ECDBA765BFA73A6A7BBC
+:101F1000550FDFB79C8F8E1CB6BF4FF0F737766A30
+:101F20004C572DF738F200E7E39B9B2FFDC4B7DA3F
+:101F3000F9F9A65E30DF84DDB9F9B5CAE2D7D3A1DD
+:101F40002FF2FEE08376B6339F86FBC47675A7F04A
+:101F50002F72D0844411F9A8382248CAB3F700D5AB
+:101F6000A16D3ECB9AE0B3ACF5F077BE2A0312D751
+:101F7000115F12CC17371FD04F00F9891F3D7AA887
+:101F80009CF0692BF6C3C27F800FDB073A845C6C40
+:101F90003B5D073F0D8AFCB7F3BC70FB53BB7DD89C
+:101FA000CA3FBB9F4B5D01E13F7470F0BDC8FAFDB5
+:101FB000C291C146C607787E26E95E4C67656D0111
+:101FC000F52F771DD15D3F74D709DDF5C1ACDE98E3
+:101FD0007E5AE73BDAC9E4C7F3E88BDD0E5BF6D641
+:101FE000DFEBCF6B77C368EF24BF8116334975A34E
+:101FF000BDA1E930EBCDF13719172BCFCB06E14B63
+:10200000451172EE5C34CD72EC6A3681EA4DC3BD87
+:102010001BBE9D4BF781B6C4573A514F0AB5499341
+:10202000E8042193A4F3676D99D9930F370D587E77
+:10203000E4EDB6F86EFA8EAEAD93FC4F45CC3DD4D0
+:10204000BF50BF359F3D2936EF2EDA9E4E0A7B6A80
+:10205000DEC1F63452D5C3386BE4A73221A92C8EE9
+:10206000B4EC69A4E534DBBB6D5769DBFF340BBB13
+:10207000A03C029DDFC55526FB8D6F5AF6A4A09D9E
+:10208000903DF92C7B2AD6B2E3293FDE4E7CC6E791
+:102090004AD5347F57DC6CD91FD95390EE0F03E338
+:1020A0008001B43BCA8BB8EDABB5469C9B8FB7257E
+:1020B0001EEE247CB1683DE7E507AAFEB38CF18BE8
+:1020C000A5FF59BCDBC8E7F9D9418F41F6D04000E4
+:1020D000BA316B07F6BE57CFC89041D1AC9991B8D1
+:1020E000BD71A690DBD69900B7E64C19B79199104F
+:1020F000B76D335772DB3E53C96D7406EDE07AB4A9
+:1021000087996A6E3B67AEE5B66B6619B7B199EB16
+:10211000795CF7CC0A6ED7CE7C94DB9B665AC43CC4
+:1021200075625F79EC81CA6097C11E8C2414911D81
+:102130007CE655F6EF9ACA779452A1555C27F229AE
+:10214000D36C0F479A85BFEF0A0A39B9EDE1EDB6B6
+:10215000C4AFF2D9C32CBE554023FEAB60FDB9F02D
+:1021600003E29FDFD0F736EE55C326EB19E293D397
+:1021700024CF4BC509B33873B1CA78D4C699238B21
+:102180001067566771E6408B88CB52077C1CBF6D89
+:1021900095C4FDB22BDB13FFC5F609224F94B8C5D9
+:1021A000AF116E4E853AC341CAEBED9581F20588B9
+:1021B000433EE0752A71719FF502EDF95444F87DB4
+:1021C0007B7C039CF4F45C048EF935FDB3657EBF23
+:1021D000507AA9E7ACB75DF8054DF8855455CF2086
+:1021E000D7A55D7EC13E67911F0EBFB0B4CBF20B89
+:1021F000969D975689F3B294FC02F2675997ED17B2
+:102200009CE7AC62E390988D432CBF1013DF216EE6
+:10221000779CB3286E3FE4E062D4A3E55D79700853
+:102220009FE739E75C5F4D6D847E4B103A03115296
+:10223000CFE2197DAD91E7DC49698D6C07C79576D2
+:10224000C8CDAF5CB49D85EC73C7E473C73DCEB613
+:10225000B781E3DD629FD639741CF76FE6D85B97D0
+:1022600026CE233C7F6EA27DBAEDAD75B19988E78D
+:1022700059E727BB04DEFFF11A0BF722AE34828C3C
+:10228000EFF3E2864F92FC9AC4EF341E43FFD31162
+:102290004BA6149DEDFC9334EFEAE8944C79A01B17
+:1022A0009B475FA69208DAE9A7BA9A2EDD4E9BDB20
+:1022B000AC7ADFCE3271D9D96ACFA7FF362EB2ED14
+:1022C000C03DEEE16A73433E7E3C63F1A36FD0D321
+:1022D0004D17FE6CBD38AE2C65FC93C7DF9AC66502
+:1022E000F1B717863F8EE33948723F07FE18CE27B5
+:1022F000FFF9F0C778D72CFE182339B5D60BFCF1BF
+:102300004C179C33BEB9645C1139C97CBB545CF179
+:1023100050D7B971C5B7BB84DF54B469F61FC597F0
+:10232000882BDC7E02F1C33F317F0C71EEDABF37C0
+:10233000E10B9439E717FA99EFD338C20D7479ECB1
+:1023400048B02D29B11DC49FA0E7A3E612D6A3CBA8
+:10235000650F88137FD895D33F9F5D5CF0B8C94D5A
+:102360009C07B4EB99BF0F1437507E64A75FB45F2E
+:102370002A283E42ED58AFC843EFB7F27E635EE0D5
+:10238000FA41BF54601C91E8BBC569916FEF594E8B
+:1023900079CFDF76D9BF97ECB9817F77037FEDA83E
+:1023A0009BCEBF2E71CF97487DC8F7C1AB34CEA36B
+:1023B0005B7CA174109DD343CBFC8C03873A8E1EAB
+:1023C000BA93F2321D220F860A51FD713A7F11D65F
+:1023D00034E79C0B3228A7293F3F4877DB19746C00
+:1023E00010F7A035F1BE348AF17B6EDDCEB8DBD1BB
+:1023F000072B5F6AFF3EB070CD7ADB4E988E6D275B
+:102400008545939A96E36F067B9DBFFF76B772ED85
+:102410007D71BA9B3C5AEFE1FAC5BE1A2540F5948E
+:102420007D7522CB3E5CE389E5AB8F5F1B931C7906
+:102430006DBBBE5D1011EB9A6FBE01D77A7C7ADC62
+:10244000243D1DD6D371FE1D725DB994CCC93B7B72
+:10245000AD79862423D38ACC1C2A12E785AF2A09BA
+:102460001EC203A1EDD7138FFD553D703A48F737D3
+:1024700092F006B6A1523591CEE38796C7841F1A13
+:10248000F24EC6588ED77938DF8B982A6F9E6C61D2
+:102490004CF8E9E19A23BCBE24F285EA55EE7101BD
+:1024A0006B5C813ACAF58E7DB5DFD4695FFBE807C6
+:1024B0003757A07CBBFFFBC1DD41D2DFBB394F33B7
+:1024C00046F91AF4A705D71C8BB521DDFD372A1A6A
+:1024D000EDA343AEDA4DEB1A8D82C17500975E9481
+:1024E000AC51025C2F353D7C07D4AD2705C554198E
+:1024F000213D9CF20BFD107A16B4F4E68021EA3EF1
+:1025000007A2A27E65CB2FE77D80EAD267A30AC728
+:102510002576FD8A6A3DF970DC7ECB2EFB2DBB440F
+:102520009CCA7587D9F78B337CEEEC6FC984E99C24
+:1025300029D2FC468CE81E75AE6B6FD39403971CB2
+:1025400058F1A2DFBA8CEF5A9FD02FE5A95FB03FB8
+:102550002D52A6F8BC2A5A7D8AFDE97DD67ABA9A10
+:1025600081F759BCD2F2DB713322E8FDA5C30F48D5
+:10257000D7BC6A7AE95CB855DC49F0368BBA5D8124
+:102580000A4606F97CA022C8F79ACA565A75BA7547
+:10259000E25E857D2FBC22EEBC1716829CDF0954BB
+:1025A0008B7B59B97D90379EF3FEDBCE5F1E7EEEAE
+:1025B000440EBD2FC59CF7C7CFF7FDEF7BD3CF9D52
+:1025C00040FD1A35CE6D87B6BCEEED6D667ED9FA4C
+:1025D00068EB6788B6D838FFF763A178DEFACC31AC
+:1025E000CB0ECEE7CFCA7CF11EC245F7AD893BF0DA
+:1025F000D103967D3E1013F94F75F119CEAB1DB482
+:10260000EE5F1D0CC086EFE499371353797C56FFBB
+:102610009D38C2D69FB97C380F8E5813B5E2104F43
+:1026200080CEF151A3ED59AA47BEABA93AE4F80117
+:10263000779EDDC61105DD76BEEF3DC65125C12969
+:10264000A1B72B9D71871B070C2BE90D64E7C375A0
+:10265000AAED9FD88F5CFD6CE1D7938C939252EEDC
+:10266000B9B93F7307D30DB9F2EC50EEFCDDCAFEE9
+:1026700018F07A42FA9929BA671E8A29E2DED6A8AA
+:1026800009B9F76EC63CBF9C3965FDFB031B77B0EB
+:102690003EEF9FE2DFD3C0172077FEBD1FDBCCBF2C
+:1026A0002F399FDC67FD7A5875E4DF2ED62EFE2584
+:1026B00066D5B7031020BB380BF770DD1D46638E5F
+:1026C000F3882B100BF8C8167FB84D6595757449C3
+:1026D000597B817651D73F9B98F58B0A7D67589F30
+:1026E00055D2AD0A8AC721C3BF53B4EF959E855F0B
+:1026F000F2BCC9A7246916675D89E13EFDFE712918
+:10270000A99CE6A1D6BDFE2560F0F31A88737B353F
+:10271000F4705B07A3DC5E0393DCD6C314B70D70C3
+:1027200086DB15A0CB34C9F560CAC0573513DCBFB2
+:102730000192DCB640E2FD53B8FEFE8AED2B385E16
+:10274000B4FD87C5279BCF79EC9D71A4CD0F9BEF7E
+:10275000FF48CEFA02EC3915127EB87D6586F53C4D
+:10276000181438D98EAF6D3AF3E1DECB85CF6C5CAF
+:10277000F97FE7ADB141E048000000000000000033
+:1027800000000018000000000000000000000040F1
+:102790000000000000000000000000280000000011
+:1027A0000000000000000010000000000000000019
+:1027B00000000020000000000000000000000010E9
+:1027C0000000000000000000000000080000000001
+:1027D00000000000000000000000000000000000F9
+:1027E00000000000000000000000000000000000E9
+:1027F00000000000000000000000000000000000D9
+:1028000000000000000000000000000000000000C8
+:1028100000000000000000000000000000000000B8
+:1028200000000000000000000000000000000000A8
+:102830000000000000000000000000000000000098
+:102840000000000000000000000000000000000088
+:102850000000000000000000000000000000000078
+:102860000000000000000000000000000000000068
+:102870000000000000000000000000000000000058
+:102880000000000000000000000000000000000048
+:102890000000000000000000000000000000000038
+:1028A0000000000000000000000000000000000028
+:1028B0000000000000000000000000000000000018
+:1028C0000000000000000000000000000000000008
+:1028D00000000000000000000000000000000000F8
+:1028E0000000000000000000000090000010000048
+:1028F0000000000800009008001000000000000226
+:1029000000009000001000000000001000009DA8D2
+:10291000000000000000000880000000000000002F
+:102920000000000080000000000000000000000027
+:10293000800000000000000000000000000091A0E6
+:102940000000000000000008000093C00001000427
+:1029500000000001000093C8000000000000000219
+:10296000000093D00000000000000008000093D495
+:102970000000000000000002000094980000000029
+:1029800000000008000093D80008000000000008C4
+:1029900000009B3800400000000000400000941838
+:1029A0000008000000000008000094580008000023
+:1029B00000000008000094A800C800000000009873
+:1029C000000096380098000000000028000096786B
+:1029D00000980000000000280000C0000540003002
+:1029E000000005400000CB200008000000000001AE
+:1029F0000000CB21000800000000000100002008BA
+:102A00000010000000000010000020000000000086
+:102A10000000000800009D600008000000000002A7
+:102A200000009DA000000000000000010000000068
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50008000000000000000000000008000000076
+:102A600000000000000000008000000000000000E6
+:102A700000000000800000000000000000000000D6
+:102A80008000000000000000000000008000000046
+:102A900000000000000000008000000000000000B6
+:102AA00000000000800000000000000000000000A6
+:102AB0008000000000000000000000008000000016
+:102AC0000000000000000000800000000000000086
+:102AD0000000000080000000000000000000000076
+:102AE0008000000000000000000000000000000066
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B20000000000000000000800000000000000025
+:102B30000000000080000000000000000000000015
+:102B40008000000000000000000000000000000005
+:102B500000000000000000008000000000000000F5
+:102B600000000000800000000000000000000000E5
+:102B700080000000000000000000000000000000D5
+:102B80000000000000000000000000000000000045
+:102B90000000000000000000000000000000000035
+:102BA0000000000000000000000000000000000025
+:102BB0000000000000000000000000000000000015
+:102BC00000000000000012C800800000000000802B
+:102BD0000000000100000000000000000000A00054
+:102BE000071000000000071000001EC800000000D1
+:102BF000000000080000AEC000080000000000084F
+:102C00000000AE4000080000000000080000AE8098
+:102C1000000800000000000800002008001000006C
+:102C2000000000100000200000000000000000086C
+:102C30000000A01007100040000000400000AF405E
+:102C400000080000000000010000AF410008000083
+:102C50000000000100001ED0000000000000000184
+:102C600000001ED8000000000000000200001EDA74
+:102C70000000000000000002000012B00008000088
+:102C800000000008800000000000000000000000BC
+:102C90008000000000000000000000008000000034
+:102CA00000000000000000008000000000000000A4
+:102CB0000000000080000000000000000000000094
+:102CC0008000000000000000000000008000000004
+:102CD0000000000000000000800000000000000074
+:102CE0000000000080000000000000000000000064
+:102CF00000000000000000000000000000000000D4
+:102D000000000000000000000000000000000000C3
+:102D100000000000000000000000000000000000B3
+:102D20000000000000000000000000008000000023
+:102D30000000000000000000800000000000000013
+:102D40000000000000000000000000000000000083
+:102D50008000000000000000000000008000000073
+:102D600000000000000000008000000000000000E3
+:102D700000000000800000000000000000000000D3
+:102D80000000B00000180000000000180000B300B0
+:102D900000400000000000400000B30000400002BE
+:102DA000000000010000B30100400002000000002C
+:102DB0000000800000400000000000408000000093
+:102DC000000000000000000000008000000800403B
+:102DD000000000040000800400080040000000041F
+:102DE0000000BB0000280000000000280000BC40DC
+:102DF00000100000000000100000880000800000AB
+:102E00000000008000008800000800800000000230
+:102E100000008C00002000000000002000002008BE
+:102E20000010000000000010000020000000000062
+:102E30000000000800001108000800000000000861
+:102E4000000011680008000000000008000011A840
+:102E500000080000000000080000127000080000D8
+:102E600000000001000012710008000000000001D5
+:102E700000008D000010000400000004000013207A
+:102E80000030001800000010000013280030001867
+:102E900000000002800000000000000000000000B0
+:102EA000800000000000000000000000000011E8A9
+:102EB0000000000000000001800000000000000091
+:102EC0000000000080000000000000000000000082
+:102ED00080000000000000000000000080000000F2
+:102EE0000000000000000000800000000000000062
+:102EF0000000000080000000000000000000000052
+:102F000000000000000000000000000000000000C1
+:102F100000000000000000000000000000000000B1
+:102F200000000000000000000000000000000000A1
+:102F30008000000000000000000000008000000091
+:102F40000000000000000000000000000000000081
+:102F500000000000000083080080000000000080E6
+:102F60000000000100000000000000000000200838
+:102F70000010000000000010000020000000000011
+:102F80000000000800008D1000080000000000088C
+:102F900000008D7000080000000000080000845050
+:102FA000046000280000046000008EA000080000FB
+:102FB0000000000100008EA10008000000000001D8
+:102FC0000000840800080000000000080000844899
+:102FD000000000000000000100008DF40008000067
+:102FE0000000000200008DF6000800000000000252
+:102FF00000008E04001000000000000480000000AB
+:103000000000000000000000800000000000000040
+:103010000000000080000000000000000000000030
+:1030200000000000000000000000000000000000A0
+:103030000000000000000000000000000000000090
+:103040000000000000000000000000000000000080
+:103050008000000000000000000000008000000070
+:103060000000000000000000000000000000000060
+:1030700000000000800000000000000000000000D0
+:103080008000000000000000000000008000000040
+:1030900000000000000000008000000000000000B0
+:1030A00000000000000030000040000000000008A8
+:1030B00000003008004000000000002800003390AD
+:1030C00001C00010000000080000320000200000D5
+:1030D0000000002000003720000000000000000871
+:1030E0000000102006200038000000080000A000AA
+:1030F000000000000000200000003EA900000000C9
+:103100000000000100003EC80000000000000002B6
+:1031100000001C4000E000080000000880000000E3
+:103120000000000000000000000040000008000057
+:103130000000000100004001000800000000000144
+:103140000000404000080004000000020000406051
+:103150000008000400000004000040000008000017
+:10316000000000040000400400080000000000040B
+:10317000000040400000000000000008000040483F
+:1031800000000000000000080000800000000000B7
+:103190000000001000005040000100040000000189
+:1031A0000000500000000000000000200000500857
+:1031B00000100000000000040000500C001000008F
+:1031C00000000001000052C70000000000000001E4
+:1031D000000052C6000000000000000100003000A6
+:1031E0000030001800000004000030040030001817
+:1031F0000000000400003008003000180000000249
+:103200000000300A00300018000000020000300CFE
+:1032100000300018000000010000300D00300018E0
+:10322000000000010000300E003000180000000116
+:1032300000003010003000180000000400003014BE
+:103240000030001800000004000050000100008061
+:103250000008000400005004010000800008000481
+:103260000000000A0000000000000000000050689C
+:103270000100008000000001000050690100008092
+:10328000000000010000506C0100008000000002FE
+:103290000000506E0100008000000002000050702D
+:1032A0000100008000000004000050740100008054
+:1032B00000000004000050660100008000000002D1
+:1032C0000000506401000080000000010000506018
+:1032D0000100008000000002000050620100008038
+:1032E00000000002000050500100008000000004B7
+:1032F00000005054010000800000000400005058FD
+:1033000001000080000000040000505C010000800B
+:10331000000000040000507C01000080000000015B
+:103320000000507D010000800000000100004018F6
+:103330000010000000000004000040900010000099
+:10334000000000040000409800100000000000048D
+:1033500000004110000000000000000200004112C7
+:103360000000000000000002000041140000000006
+:1033700000000002000041160000000000000002F2
+:1033800000006040000800000000000200006042F1
+:103390000008000000000002000060440008000077
+:1033A0000000000400006080000800000000000829
+:1033B000000060C00040000800000008000060003D
+:1033C0000008000000000002000060020008000089
+:1033D000000000010000600400080000000000027E
+:1033E0000000634000080000000000080000638047
+:1033F00000080000000000040000638400080000D2
+:1034000000000001000063C000080000000000028E
+:10341000000063C400080000000000020000640017
+:103420000008000000000004000070000010000010
+:103430000000000400007004001000000000000400
+:103440000000700800100000000000040000700080
+:1034500000080000000000020000700200080000E8
+:1034600000000001000070040008000000000002DD
+:1034700000007040000800000000000200007044DE
+:103480000008000000000002000070460008000074
+:10349000000000020000764800080000000000085C
+:1034A000000070800008000000000002000070842E
+:1034B00000080000000000020000768800080000FC
+:1034C000000000080000804000080000000000012B
+:1034D0000000804100080000000000010000804260
+:1034E0000008000000000001000080430008000008
+:1034F0000000000100008000000800000000000241
+:1035000000008002000800000000000100008004AC
+:103510000008000000000002000080C00008000059
+:1035200000000002000080C200080000000000024D
+:10353000000080C40008000000000002000080803D
+:103540000008000000000001000080810008000069
+:10355000000000010000808200080000000000015F
+:10356000000080830008000000000001000080844B
+:103570000008000000000001000080850008000035
+:10358000000000010000808600080000000000012B
+:10359000000060000008000000000002000060025F
+:1035A00000080000000000010000600400080000A6
+:1035B000000000020000604200C00018000000028D
+:1035C0000000604000C00018000000020000604CD5
+:1035D00000C00018000000080000604400C000188F
+:1035E000000000080000605700C000180000000143
+:1035F0000000605400C00018000000020000605687
+:1036000000C0001800000001000066400008000033
+:1036100000000008000066800008000000000008AC
+:10362000000066C000080000000000080000D94249
+:1036300000180000000000020000DE400000000052
+:10364000000000000000E000000000000000000496
+:103650000000DD4000000000000000040000DD4428
+:1036600000000000000000040000DD480000000031
+:10367000000000040000DD4C000000000000000419
+:103680000000DD5000000000000000040000DD54D8
+:1036900000000000000000040000DD5800000000F1
+:1036A000000000040000DD400000000000000020D9
+:1036B0000000DA0000000000000000040000DA0052
+:1036C00000000000000000680000BB600000000077
+:1036D000000000000000D000000000000000000416
+:1036E0000000B0C000000000000000040000B0C4F2
+:1036F00000000000000000040000B0C8000000004E
+:10370000000000040000B0C0000000000000001035
+:103710000000D6B000000000000000040000D6B495
+:1037200000000000000000040000D6B80000000007
+:10373000000000040000D6BC0000000000000004EF
+:103740000000D6B000000000000000100000D348C8
+:1037500000000000000000080000D3580000000036
+:1037600000000080000000100000000000000000C9
+:103770000000D35800000000000000080000000016
+:08378000060205000000000034
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex
deleted file mode 100644
index 78b41615e7d9..000000000000
--- a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex
+++ /dev/null
@@ -1,15442 +0,0 @@
-:10000000000052D8000000680000070C00005348B0
-:100010000000318000005A58000000B000008BE062
-:100020000000C14C00008C98000000D800014DE891
-:100030000000F16400014EC800000074000240306E
-:1000400000005250000240A8000000B800029300D7
-:1000500000012110000293C000000FFC0003B4D87F
-:10006000000000040003C4D8020400480000000F90
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040258000000360204025C000000365F
-:10017000020402600810000002040264081000007B
-:1001800002040004000000FF02040008000000FF59
-:100190000204000C000000FF02040010000000FF39
-:1001A000020400140000007F02040018000000FF99
-:1001B0000204001C000000FF02040020000000FFF9
-:1001C000020400240000003E020400280000000099
-:1001D0000204002C0000003F020400300000003F39
-:1001E000020400340000003F020400380000003F19
-:1001F0000204003C0000003F020400400000003FF9
-:10020000020400440000003F020404CC000000018E
-:1002100002042008000002110204200C0000020069
-:10022000020420100000020402042014000002193D
-:100230000204201C0000FFFF020420200000FFFF3A
-:10024000020420240000FFFF020420280000FFFF1A
-:1002500002042038000000200604203C0000000FAB
-:1002600002042078000000210604207C0000000F1A
-:10027000020420B800000001060420BC0000000FAA
-:10028000020420F800000001060420FC0000003FEA
-:10029000020421F800000001060421FC0000000F08
-:1002A0000204223807FFFFFF0204223C0000007F07
-:1002B0000204224007FFFFFF020422440000003F27
-:1002C00001042248000000000104224C000000004C
-:1002D000010422500000000001042254000000002C
-:1002E00001042258000000000104225C000000000C
-:1002F00001042260000000000104226400000000EC
-:1003000001042268000000000104226C00000000CB
-:1003100001042270000000000104227400000000AB
-:1003200001042278000000000104227C000000008B
-:10033000020422C00000FFFF020422C40000FFFFED
-:10034000020422C80000FFFF020422CC0000FFFFCD
-:100350000C042000000003E80A0420000000000153
-:100360000B042000000000030605400000000D0003
-:100370000205004400000020020500480000003291
-:1003800002050090021500200205009402150020CD
-:1003900002050098000000300205009C08100000D3
-:1003A000020500A000000036020500A40000003095
-:1003B000020500A800000031020500B000000004A2
-:1003C000020500B400000005020500C000000000A6
-:1003D000020500C400000004020500D40000000172
-:1003E00002050114000000010205011C00000001CB
-:1003F00002050120000000020205020400000001C5
-:100400000205020C0000004002050210000000403E
-:100410000205021C00000020020502200000001C52
-:100420000205022400000020060502400000000A28
-:1004300004050280002000000205005000000007B3
-:1004400002050054000000070205005800000000EB
-:100450000205005C000000080205006000000001C9
-:100460000605006400000003020500D80000000635
-:100470000205000400000001020500080000000160
-:100480000205000C00000001020500100000000140
-:100490000205001400000001020500180000000120
-:1004A0000205001C00000001020500200000000100
-:1004B00002050024000000010205002800000001E0
-:1004C0000205002C000000010205003000000001C0
-:1004D00002050034000000010205003800000001A0
-:1004E0000205003C00000001020500400000000180
-:1004F000020500E00000000D020500E80000000019
-:10050000020500F000000000020500F800000000F5
-:10051000020500E40000002D020500EC00000020B0
-:10052000020500F400000020020500FC000000208D
-:10053000020500E00000001D020500E800000010B8
-:10054000020500F000000010020500F80000001095
-:10055000020500E40000003D020500EC0000003050
-:10056000020500F400000030020500FC000000302D
-:10057000020500E00000004D020500E80000004018
-:10058000020500F000000040020500F800000040F5
-:10059000020500E40000006D020500EC00000060B0
-:1005A000020500F400000060020500FC000000608D
-:1005B000020500E00000005D020500E800000050B8
-:1005C000020500F000000050020500F80000005095
-:1005D000020500E40000007D020500EC0000007050
-:1005E000020500F400000070020500FC000000702D
-:1005F0000406100002000020020600DC00000001DA
-:100600000406020000030220020600DC00000000D5
-:100610000718040000AC0000081807D800050223E2
-:10062000071C000029B30000071C8000312E0A6D52
-:10063000071D000034A816B9071D80002E6C23E4A6
-:10064000071E0000034B2F80081E07F03F02022503
-:100650000118000000000000011800040000000064
-:1006600001180008000000000118000C0000000044
-:100670000118001000000000011800140000000024
-:1006800002180020000000010218002400000002EF
-:1006900002180028000000030218002C00000000CF
-:1006A00002180030000000040218003400000001AD
-:1006B00002180038000000000218003C0000000191
-:1006C000021800400000000402180044000000006E
-:1006D00002180048000000010218004C000000034E
-:1006E0000218005000000000021800540000000131
-:1006F00002180058000000040218005C000000000E
-:1007000002180060000000010218006400000003ED
-:1007100002180068000000000218006C00000001D0
-:1007200002180070000000040218007400000000AD
-:1007300002180078000000040218007C000000038A
-:100740000618008000000002021800A400007FFFCD
-:10075000021800A8000003FF021802240000000095
-:1007600002180234000000000218024C00000000D1
-:10077000021802E4000000FF061810000000040048
-:10078000021B8BC000000001021B8000000000342F
-:10079000021B804000000018021B80800000000C3B
-:1007A000021B80C0000000200C1B83000008647046
-:1007B0000A1B8300000001570B1B83000000055F2C
-:1007C0000A1B8340000000000C1B8340000002262F
-:1007D0000B1B834000000001021B83800008647033
-:1007E000021B83C000000226021B148000000001CF
-:1007F0000A1B148000000000021B9440000000014E
-:10080000061B944800000002061A1000000002B304
-:10081000041A1ACC00010227061A1AD00000000898
-:10082000061A2008000000C8061A20000000000276
-:10083000041A1BF800900228061A3718000000045A
-:10084000061A371000000002061A500000000002CD
-:10085000061A500800000004061A50180000000490
-:10086000061A502800000004061A50380000000440
-:10087000061A504800000004061A505800000004F0
-:10088000061A506800000004061A507800000002A2
-:10089000041A52C0000202B8061A405000000006B6
-:1008A000041A4068000202BA041A4040000402BC64
-:1008B000041A8000000102C0061A80040000000330
-:1008C000041A8010000102C1061A801400000003FF
-:1008D000041A8020000102C2061A802400000003CE
-:1008E000041A8030000102C3061A8034000000039D
-:1008F000041A8040000102C4061A8044000000036C
-:10090000041A8050000102C5061A8054000000033A
-:10091000041A8060000102C6061A80640000000309
-:10092000041A8070000102C7061A807400000003D8
-:10093000041A8080000102C8061A808400000003A7
-:10094000041A8090000102C9061A80940000000376
-:10095000041A80A0000102CA061A80A40000000345
-:10096000041A80B0000102CB061A80B40000000314
-:10097000041A80C0000102CC061A80C400000003E3
-:10098000041A80D0000102CD061A80D400000003B2
-:10099000041A80E0000102CE061A80E40000000381
-:1009A000041A80F0000102CF061A80F40000000350
-:1009B000041A8100000102D0061A8104000000031D
-:1009C000041A8110000102D1061A811400000003EC
-:1009D000041A8120000102D2061A812400000003BB
-:1009E000041A8130000102D3061A8134000000038A
-:1009F000041A8140000102D4061A81440000000359
-:100A0000041A8150000102D5061A81540000000327
-:100A1000041A8160000102D6061A816400000003F6
-:100A2000041A8170000102D7061A817400000003C5
-:100A3000041A8180000102D8061A81840000000394
-:100A4000041A8190000102D9061A81940000000363
-:100A5000041A81A0000102DA061A81A40000000332
-:100A6000041A81B0000102DB061A81B40000000301
-:100A7000041A81C0000102DC061A81C400000003D0
-:100A8000041A81D0000102DD061A81D4000000039F
-:100A9000041A81E0000102DE061A81E4000000036E
-:100AA000041A81F0000102DF061A81F4000000033D
-:100AB000041A8200000102E0061A8204000000030A
-:100AC000041A8210000102E1061A821400000003D9
-:100AD000041A8220000102E2061A822400000003A8
-:100AE000041A8230000102E3061A82340000000377
-:100AF000041A8240000102E4061A82440000000346
-:100B0000041A8250000102E5061A82540000000314
-:100B1000041A8260000102E6061A826400000003E3
-:100B2000041A8270000102E7061A827400000003B2
-:100B3000041A8280000102E8061A82840000000381
-:100B4000041A8290000102E9061A82940000000350
-:100B5000041A82A0000102EA061A82A4000000031F
-:100B6000041A82B0000102EB061A82B400000003EE
-:100B7000041A82C0000102EC061A82C400000003BD
-:100B8000041A82D0000102ED061A82D4000000038C
-:100B9000041A82E0000102EE061A82E4000000035B
-:100BA000041A82F0000102EF061A82F4000000032A
-:100BB000041A8300000102F0061A830400000003F7
-:100BC000041A8310000102F1061A831400000003C6
-:100BD000041A8320000102F2061A83240000000395
-:100BE000041A8330000102F3061A83340000000364
-:100BF000041A8340000102F4061A83440000000333
-:100C0000041A8350000102F5061A83540000000301
-:100C1000041A8360000102F6061A836400000003D0
-:100C2000041A8370000102F7061A8374000000039F
-:100C3000041A8380000102F8061A8384000000036E
-:100C4000041A8390000102F9061A8394000000033D
-:100C5000041A83A0000102FA061A83A4000000030C
-:100C6000041A83B0000102FB061A83B400000003DB
-:100C7000041A83C0000102FC061A83C400000003AA
-:100C8000041A83D0000102FD061A83D40000000379
-:100C9000041A83E0000102FE061A83E40000000348
-:100CA000041A83F0000102FF061A83F40000000317
-:100CB000041A840000010300061A840400000003E3
-:100CC000041A841000010301061A841400000003B2
-:100CD000041A842000010302061A84240000000381
-:100CE000041A843000010303061A84340000000350
-:100CF000041A844000010304061A8444000000031F
-:100D0000041A845000010305061A845400000003ED
-:100D1000041A846000010306061A846400000003BC
-:100D2000041A847000010307061A8474000000038B
-:100D3000041A848000010308061A8484000000035A
-:100D4000041A849000010309061A84940000000329
-:100D5000041A84A00001030A061A84A400000003F8
-:100D6000041A84B00001030B061A84B400000003C7
-:100D7000041A84C00001030C061A84C40000000396
-:100D8000041A84D00001030D061A84D40000000365
-:100D9000041A84E00001030E061A84E40000000334
-:100DA000041A84F00001030F061A84F40000000303
-:100DB000041A850000010310061A850400000003D0
-:100DC000041A851000010311061A8514000000039F
-:100DD000041A852000010312061A8524000000036E
-:100DE000041A853000010313061A8534000000033D
-:100DF000041A854000010314061A8544000000030C
-:100E0000041A855000010315061A855400000003DA
-:100E1000041A856000010316061A856400000003A9
-:100E2000041A857000010317061A85740000000378
-:100E3000041A858000010318061A85840000000347
-:100E4000041A859000010319061A85940000000316
-:100E5000041A85A00001031A061A85A400000003E5
-:100E6000041A85B00001031B061A85B400000003B4
-:100E7000041A85C00001031C061A85C40000000383
-:100E8000041A85D00001031D061A85D40000000352
-:100E9000041A85E00001031E061A85E40000000321
-:100EA000041A85F00001031F061A85F400000003F0
-:100EB000041A860000010320061A860400000003BD
-:100EC000041A861000010321061A8614000000038C
-:100ED000041A862000010322061A8624000000035B
-:100EE000041A863000010323061A8634000000032A
-:100EF000041A864000010324061A864400000003F9
-:100F0000041A865000010325061A865400000003C7
-:100F1000041A866000010326061A86640000000396
-:100F2000041A867000010327061A86740000000365
-:100F3000041A868000010328061A86840000000334
-:100F4000041A869000010329061A86940000000303
-:100F5000041A86A00001032A061A86A400000003D2
-:100F6000041A86B00001032B061A86B400000003A1
-:100F7000041A86C00001032C061A86C40000000370
-:100F8000041A86D00001032D061A86D4000000033F
-:100F9000041A86E00001032E061A86E4000000030E
-:100FA000041A86F00001032F061A86F400000003DD
-:100FB000041A870000010330061A870400000003AA
-:100FC000041A871000010331061A87140000000379
-:100FD000041A872000010332061A87240000000348
-:100FE000041A873000010333061A87340000000317
-:100FF000041A874000010334061A874400000003E6
-:10100000041A875000010335061A875400000003B4
-:10101000041A876000010336061A87640000000383
-:10102000041A877000010337061A87740000000352
-:10103000041A878000010338061A87840000000321
-:10104000041A879000010339061A879400000003F0
-:10105000041A87A00001033A061A87A400000003BF
-:10106000041A87B00001033B061A87B4000000038E
-:10107000041A87C00001033C061A87C4000000035D
-:10108000041A87D00001033D061A87D4000000032C
-:10109000041A87E00001033E061A87E400000003FB
-:1010A000041A87F00001033F061A87F400000003CA
-:1010B000041A880000010340061A88040000000397
-:1010C000041A881000010341061A88140000000366
-:1010D000041A882000010342061A88240000000335
-:1010E000041A883000010343061A88340000000304
-:1010F000041A884000010344061A884400000003D3
-:10110000041A885000010345061A885400000003A1
-:10111000041A886000010346061A88640000000370
-:10112000041A887000010347061A8874000000033F
-:10113000041A888000010348061A8884000000030E
-:10114000041A889000010349061A889400000003DD
-:10115000041A88A00001034A061A88A400000003AC
-:10116000041A88B00001034B061A88B4000000037B
-:10117000041A88C00001034C061A88C4000000034A
-:10118000041A88D00001034D061A88D40000000319
-:10119000041A88E00001034E061A88E400000003E8
-:1011A000041A88F00001034F061A88F400000003B7
-:1011B000041A890000010350061A89040000000384
-:1011C000041A891000010351061A89140000000353
-:1011D000041A892000010352061A89240000000322
-:1011E000041A893000010353061A893400000003F1
-:1011F000041A894000010354061A894400000003C0
-:10120000041A895000010355061A8954000000038E
-:10121000041A896000010356061A8964000000035D
-:10122000041A897000010357061A8974000000032C
-:10123000041A898000010358061A898400000003FB
-:10124000041A899000010359061A899400000003CA
-:10125000041A89A00001035A061A89A40000000399
-:10126000041A89B00001035B061A89B40000000368
-:10127000041A89C00001035C061A89C40000000337
-:10128000041A89D00001035D061A89D40000000306
-:10129000041A89E00001035E061A89E400000003D5
-:1012A000041A89F00001035F061A89F400000003A4
-:1012B000041A8A0000010360061A8A040000000371
-:1012C000041A8A1000010361061A8A140000000340
-:1012D000041A8A2000010362061A8A24000000030F
-:1012E000041A8A3000010363061A8A3400000003DE
-:1012F000041A8A4000010364061A8A4400000003AD
-:10130000041A8A5000010365061A8A54000000037B
-:10131000041A8A6000010366061A8A64000000034A
-:10132000041A8A7000010367061A8A740000000319
-:10133000041A8A8000010368061A8A8400000003E8
-:10134000041A8A9000010369061A8A9400000003B7
-:10135000041A8AA00001036A061A8AA40000000386
-:10136000041A8AB00001036B061A8AB40000000355
-:10137000041A8AC00001036C061A8AC40000000324
-:10138000041A8AD00001036D061A8AD400000003F3
-:10139000041A8AE00001036E061A8AE400000003C2
-:1013A000041A8AF00001036F061A8AF40000000391
-:1013B000041A8B0000010370061A8B04000000035E
-:1013C000041A8B1000010371061A8B14000000032D
-:1013D000041A8B2000010372061A8B2400000003FC
-:1013E000041A8B3000010373061A8B3400000003CB
-:1013F000041A8B4000010374061A8B44000000039A
-:10140000041A8B5000010375061A8B540000000368
-:10141000041A8B6000010376061A8B640000000337
-:10142000041A8B7000010377061A8B740000000306
-:10143000041A8B8000010378061A8B8400000003D5
-:10144000041A8B9000010379061A8B9400000003A4
-:10145000041A8BA00001037A061A8BA40000000373
-:10146000041A8BB00001037B061A8BB40000000342
-:10147000041A8BC00001037C061A8BC40000000311
-:10148000041A8BD00001037D061A8BD400000003E0
-:10149000041A8BE00001037E061A8BE400000003AF
-:1014A000041A8BF00001037F061A8BF4000000037E
-:1014B000041A8C0000010380061A8C04000000034B
-:1014C000041A8C1000010381061A8C14000000031A
-:1014D000041A8C2000010382061A8C2400000003E9
-:1014E000041A8C3000010383061A8C3400000003B8
-:1014F000041A8C4000010384061A8C440000000387
-:10150000041A8C5000010385061A8C540000000355
-:10151000041A8C6000010386061A8C640000000324
-:10152000041A8C7000010387061A8C7400000003F3
-:10153000041A8C8000010388061A8C8400000003C2
-:10154000041A8C9000010389061A8C940000000391
-:10155000041A8CA00001038A061A8CA40000000360
-:10156000041A8CB00001038B061A8CB4000000032F
-:10157000041A8CC00001038C061A8CC400000003FE
-:10158000041A8CD00001038D061A8CD400000003CD
-:10159000041A8CE00001038E061A8CE4000000039C
-:1015A000041A8CF00001038F061A8CF4000000036B
-:1015B000041A8D0000010390061A8D040000000338
-:1015C000041A8D1000010391061A8D140000000307
-:1015D000041A8D2000010392061A8D2400000003D6
-:1015E000041A8D3000010393061A8D3400000003A5
-:1015F000041A8D4000010394061A8D440000000374
-:10160000041A8D5000010395061A8D540000000342
-:10161000041A8D6000010396061A8D640000000311
-:10162000041A8D7000010397061A8D7400000003E0
-:10163000041A8D8000010398061A8D8400000003AF
-:10164000041A8D9000010399061A8D94000000037E
-:10165000041A8DA00001039A061A8DA4000000034D
-:10166000041A8DB00001039B061A8DB4000000031C
-:10167000041A8DC00001039C061A8DC400000003EB
-:10168000041A8DD00001039D061A8DD400000003BA
-:10169000041A8DE00001039E061A8DE40000000389
-:1016A000041A8DF00001039F061A8DF40000000358
-:1016B000041A8E00000103A0061A8E040000000325
-:1016C000041A8E10000103A1061A8E1400000003F4
-:1016D000041A8E20000103A2061A8E2400000003C3
-:1016E000041A8E30000103A3061A8E340000000392
-:1016F000041A8E40000103A4061A8E440000000361
-:10170000041A8E50000103A5061A8E54000000032F
-:10171000041A8E60000103A6061A8E6400000003FE
-:10172000041A8E70000103A7061A8E7400000003CD
-:10173000041A8E80000103A8061A8E84000000039C
-:10174000041A8E90000103A9061A8E94000000036B
-:10175000041A8EA0000103AA061A8EA4000000033A
-:10176000041A8EB0000103AB061A8EB40000000309
-:10177000041A8EC0000103AC061A8EC400000003D8
-:10178000041A8ED0000103AD061A8ED400000003A7
-:10179000041A8EE0000103AE061A8EE40000000376
-:1017A000041A8EF0000103AF061A8EF40000000345
-:1017B000041A8F00000103B0061A8F040000000312
-:1017C000041A8F10000103B1061A8F1400000003E1
-:1017D000041A8F20000103B2061A8F2400000003B0
-:1017E000041A8F30000103B3061A8F34000000037F
-:1017F000041A8F40000103B4061A8F44000000034E
-:10180000041A8F50000103B5061A8F54000000031C
-:10181000041A8F60000103B6061A8F6400000003EB
-:10182000041A8F70000103B7061A8F7400000003BA
-:10183000041A8F80000103B8061A8F840000000389
-:10184000041A8F90000103B9061A8F940000000358
-:10185000041A8FA0000103BA061A8FA40000000327
-:10186000041A8FB0000103BB061A8FB400000003F6
-:10187000041A8FC0000103BC061A8FC400000003C5
-:10188000041A8FD0000103BD061A8FD40000000394
-:10189000041A8FE0000103BE061A8FE4000000075F
-:1018A000041A62C0002003BF061A1AF000000042AA
-:1018B000061AAF0000000008061AE000000005400C
-:1018C000061AD00000000072061AD248000000106C
-:1018D000061AD6B000000020061AD470000000904E
-:1018E000061AD46800000002061AA000000001C415
-:1018F000061A300000000010061A308000000010A8
-:10190000061A310000000010061A31800000001095
-:10191000061A330000000012061A3390000000700F
-:10192000061AD45800000002061AD348000000022C
-:10193000061AD35800000020061AA710000001C4A0
-:10194000061A304000000010061A30C000000010D7
-:10195000061A314000000010061A31C000000010C5
-:10196000061A334800000012061A355000000070B5
-:10197000061AD46000000002061AD35000000002CC
-:10198000061AD3D800000020021AAE200000000082
-:10199000061A500000000002061A508000000012D3
-:1019A000041A4000000203DF041A63C0000203E1CE
-:1019B000061A700000000004061A32000000000839
-:1019C000021AAE2400000000061A501000000002A7
-:1019D000061A50C800000012041A4008000203E36F
-:1019E000041A63C8000203E5061A70100000000420
-:1019F000061A322000000008021AAE28000000007B
-:101A0000061A502000000002061A511000000012B1
-:101A1000041A4010000203E7041A63D0000203E92D
-:101A2000061A702000000004061A32400000000868
-:101A3000021AAE2C00000000061A5030000000020E
-:101A4000061A515800000012041A4018000203EB55
-:101A5000041A63D8000203ED061A70300000000477
-:101A6000061A326000000008021AAE3000000000C2
-:101A7000061A504000000002061A51A00000001291
-:101A8000041A4020000203EF041A63E0000203F18D
-:101A9000061A704000000004061A32800000000898
-:101AA000021AAE3400000000061A50500000000276
-:101AB000061A51E800000012041A4028000203F33D
-:101AC000041A63E8000203F5061A705000000004CF
-:101AD000061A32A000000008021AAE38000000000A
-:101AE000061A506000000002061A52300000001270
-:101AF000041A4030000203F7041A63F0000203F9ED
-:101B0000061A706000000004061A32C000000008C7
-:101B1000021AAE3C00000000061A507000000002DD
-:101B2000061A527800000012041A4038000203FB23
-:101B3000041A63F8000203FD061A70700000000426
-:101B4000061A32E0000000080200A2A40000020908
-:101B50000200A270000000000200A2740000000059
-:101B60000200A270000000000200A2740000000049
-:101B70000200A270000000000200A2740000000039
-:101B80000200A270000000000200A2740000000029
-:101B9000020100B400000001020100B800000001D1
-:101BA000020100CC00000001020100D00000000191
-:101BB000020100DC00000001020101000000000140
-:101BC00002010104000000010201007C003000005D
-:101BD00002010084000000280201008C00000000C7
-:101BE00002010130000000040201025C000000015B
-:101BF0000201032800000000020160580000FFFFFE
-:101C0000020160700000000702010554000000306E
-:101C1000020100C400000001020100F80000000100
-:101C2000020100F00000000102010080003000000D
-:101C3000020100880000002802010090000000005E
-:101C40000201013400000004020102DC0000000176
-:101C50000201032C000000000201605C0000FFFF95
-:101C600002016074000000070201056400000030FA
-:101C7000020100C800000001020100FC0000000198
-:101C8000020100F400000001020C10000000002816
-:101C9000020C200800000211020C200C00000200BF
-:101CA000020C201000000204020C201C0000FFFFA8
-:101CB000020C20200000FFFF020C20240000FFFF88
-:101CC000020C20280000FFFF020C2038000000005A
-:101CD000020C203C00000037020C204000000021D4
-:101CE000020C204400000020060C20480000001DCB
-:101CF000020C20BC00000001060C20C00000003FC8
-:101D0000020C21BC00000001020C21C000000001F7
-:101D1000020C21C400000001060C21C80000001CB8
-:101D2000020C223807FFFFFF020C223C0000007F5C
-:101D3000020C224007FFFFFF020C22440000003F7C
-:101D4000010C224800000000010C224C00000000A1
-:101D5000010C225000000000010C22540000000081
-:101D6000010C225800000000010C225C0000000061
-:101D7000010C226000000000010C22640000000041
-:101D8000010C226800000000010C226C0000000021
-:101D9000010C227000000000010C22740000000001
-:101DA000010C227800000000010C227C00000000E1
-:101DB000020C22D80000FFFF020C22DC0000FFFF13
-:101DC000020C22E00000FFFF020C22E40000FFFFF3
-:101DD0000C0C2000000003E80A0C200000000001A9
-:101DE0000B0C200000000003020C40080000101142
-:101DF000020C400C00001000020C40100000100407
-:101E0000020C401400001021020C401C0000FFFFD7
-:101E1000020C40200000FFFF020C40240000FFFFE6
-:101E2000020C40280000FFFF020C40380000004672
-:101E3000020C403C0000000C060C40400000000278
-:101E4000020C404800000018020C404C000000F05A
-:101E5000060C40500000001F020C40CC00000001A6
-:101E6000060C40D00000003A020C41B8000000010E
-:101E7000060C41BC00000003020C41C80000000138
-:101E8000020C41CC00000001060C41D00000001AF9
-:101E9000020C423807FFFFFF020C423C0000007FAB
-:101EA000020C424007FFFFFF020C42440000003FCB
-:101EB000010C424800000000010C424C00000000F0
-:101EC000010C425000000000010C425400000000D0
-:101ED000010C425800000000010C425C00000000B0
-:101EE000010C426000000000010C42640000000090
-:101EF000010C426800000000010C426C0000000070
-:101F0000010C427000000000010C4274000000004F
-:101F1000010C427800000000010C427C000000002F
-:101F2000010C428000000000020C42D80000FFFFBC
-:101F3000020C42DC0000FFFF020C42E00000FFFF49
-:101F4000020C42E40000FFFF0C0C4000000003E81C
-:101F50000A0C4000000000010B0C400000000003D0
-:101F6000060D400000000A00020D0044000000328F
-:101F7000020D008C02150020020D009002150020B9
-:101F8000020D009408100000020D009800000036B9
-:101F9000020D00A000000000020D00A400000004DB
-:101FA000020D00A800000004060D00AC00000002B5
-:101FB000020D00B800000002020D00C00000000188
-:101FC000020D00C800000002020D00CC000000025B
-:101FD000020D015C00000001020D0164000000011F
-:101FE000020D016800000002020D02040000000161
-:101FF000020D020C00000020020D02100000004043
-:10200000020D021400000040020D02200000000337
-:10201000020D022400000018060D028000000012CC
-:10202000040D0300001803FF060D03600000000C00
-:10203000020D004C00000001020D005000000002E3
-:10204000020D005400000000020D005800000008BE
-:10205000060D005C00000004020D00C40000000436
-:10206000020D000400000001020D00080000000144
-:10207000020D000C00000001020D00100000000124
-:10208000020D001400000001020D00180000000104
-:10209000020D001C00000001020D002000000001E4
-:1020A000020D002400000001020D002800000001C4
-:1020B000020D002C00000001020D003000000001A4
-:1020C000020D003400000001020D00380000000184
-:1020D000020D003C00000001020D01140000000987
-:1020E000020D011C0000000A020D01240000000086
-:1020F000020D012C00000000020D01340000000060
-:10210000020D013C0000000B020D01440000000024
-:10211000020D011800000029020D01200000002A14
-:10212000020D012800000020020D013000000020F7
-:10213000020D013800000020020D01400000002BBC
-:10214000020D014800000020020D011400000019DA
-:10215000020D011C0000001A020D012400000010F5
-:10216000020D012C00000010020D013400000010CF
-:10217000020D013C0000001B020D01440000001094
-:10218000020D011800000039020D01200000003A84
-:10219000020D012800000030020D01300000003067
-:1021A000020D013800000030020D01400000003B2C
-:1021B000020D014800000030020D0114000000492A
-:1021C000020D011C0000004A020D01240000004025
-:1021D000020D012C00000040020D013400000040FF
-:1021E000020D013C0000004B020D014400000040C4
-:1021F000020D011800000069020D01200000006AB4
-:10220000020D012800000060020D01300000006096
-:10221000020D013800000060020D01400000006B5B
-:10222000020D014800000060020D01140000005979
-:10223000020D011C0000005A020D01240000005094
-:10224000020D012C00000050020D0134000000506E
-:10225000020D013C0000005B020D01440000005033
-:10226000020D011800000079020D01200000007A23
-:10227000020D012800000070020D01300000007006
-:10228000020D013800000070020D01400000007BCB
-:10229000020D014800000070060E2000000008003A
-:1022A000020E004C00000032020E009402150020C5
-:1022B000020E009802150020020E009C0000003063
-:1022C000020E00A008100000020E00A4000000365C
-:1022D000020E00A800000030020E00AC0000003129
-:1022E000020E00B400000003020E00B8000000005F
-:1022F000020E00C400000000020E00CC0000000628
-:10230000020E00D800000001020E0144000000018E
-:10231000020E014C00000001020E015000000002FC
-:10232000020E020400000001020E020C0000004038
-:10233000020E021000000040020E021C0000000409
-:10234000020E022000000020020E02240000000EF7
-:10235000020E02280000001B060E030000000012FF
-:10236000040E0280001B0417060E02EC000000059C
-:10237000020E00540000000C020E00580000000C79
-:10238000020E005C00000000020E00600000001061
-:10239000020E006400000010060E0068000000033A
-:1023A000020E00DC00000003020E00040000000129
-:1023B000020E000800000001020E000C00000001E7
-:1023C000020E001000000001020E001400000001C7
-:1023D000020E001800000001020E001C00000001A7
-:1023E000020E002000000001020E00240000000187
-:1023F000020E002800000001020E002C0000000167
-:10240000020E003000000001020E00340000000146
-:10241000020E003800000001020E003C0000000126
-:10242000020E004000000001020E00440000000106
-:10243000020E01100000000F020E01180000000043
-:10244000020E012000000000020E01280000000022
-:10245000020E01140000002F020E011C00000020DB
-:10246000020E012400000020020E012C00000020BA
-:10247000020E01100000001F020E011800000010E3
-:10248000020E012000000010020E012800000010C2
-:10249000020E01140000003F020E011C000000307B
-:1024A000020E012400000030020E012C000000305A
-:1024B000020E01100000004F020E01180000004043
-:1024C000020E012000000040020E01280000004022
-:1024D000020E01140000006F020E011C00000060DB
-:1024E000020E012400000060020E012C00000060BA
-:1024F000020E01100000005F020E011800000050E3
-:10250000020E012000000050020E012800000050C1
-:10251000020E01140000007F020E011C000000707A
-:10252000020E012400000070020E012C0000007059
-:102530000730040000D60000083007D80005043238
-:10254000073400003222000007348000312C0C894F
-:102550000735000038DD18D5073580002F16270D08
-:1025600007360000261532D30836711031DE0434E8
-:1025700001300000000000000130000400000000F5
-:1025800001300008000000000130000C00000000D5
-:1025900001300010000000000130001400000000B5
-:1025A0000230002000000001023000240000000280
-:1025B00002300028000000030230002C0000000060
-:1025C000023000300000000402300034000000013E
-:1025D00002300038000000000230003C0000000122
-:1025E00002300040000000040230004400000000FF
-:1025F00002300048000000010230004C00000003DF
-:1026000002300050000000000230005400000001C1
-:1026100002300058000000040230005C000000009E
-:10262000023000600000000102300064000000037E
-:1026300002300068000000000230006C0000000161
-:10264000023000700000000402300074000000003E
-:1026500002300078000000040230007C000000031B
-:102660000630008000000002023000A400007FFF5E
-:10267000023000A8000003FF023002240000000026
-:1026800002300234000000000230024C0000000062
-:10269000023002E40000FFFF0630200000000800C6
-:1026A00002338BC000000001023380000000001ADA
-:1026B000023380400000004E023380800000001092
-:1026C000023380C0000000200C33830000086470D7
-:1026D0000A338300000001570B3383000000055FBD
-:1026E0000A338340000000000C33834000000226C0
-:1026F0000B338340000000010233838000086470C4
-:10270000023383C00000022602331480000000015F
-:102710000A3314800000000006328000000001022D
-:1027200006322008000000C8063220000000000227
-:1027300004328520008F04360632875C00000009D1
-:1027400006323EB00000000606323ED00000000215
-:1027500006323E800000000A04323EA8000204C592
-:1027600006323E0000000020063250000000094002
-:102770000632400000000004043294C0000204C786
-:1027800006324110000000020632D0000000007046
-:102790000632DB00000000D40632DEA0000000029A
-:1027A0000632E00000000800063324000000011893
-:1027B00006321000000001880632500000000020A0
-:1027C00006325100000000200632520000000020B6
-:1027D00006325300000000200632540000000020A2
-:1027E000063255000000002006325600000000208E
-:1027F000063257000000002006325800000000207A
-:10280000063259000000002006325A000000002065
-:1028100006325B000000002006325C000000002051
-:1028200006325D000000002006325E00000000203D
-:1028300006325F0000000020063284F00000000233
-:1028400004328500000204C9063285080000000237
-:102850000632DE90000000020633286000000118F6
-:102860000632162000000188063250800000002049
-:102870000632518000000020063252800000002005
-:1028800006325380000000200632548000000020F1
-:1028900006325580000000200632568000000020DD
-:1028A00006325780000000200632588000000020C9
-:1028B000063259800000002006325A8000000020B5
-:1028C00006325B800000002006325C8000000020A1
-:1028D00006325D800000002006325E80000000208D
-:1028E00006325F8000000020063284F800000002FB
-:1028F00004328510000204CB063285180000000265
-:102900000632DE980000000202328450000000000F
-:102910000632401000000002023284540000000021
-:1029200006324020000000020232845800000000FD
-:1029300006324030000000020232845C00000000D9
-:1029400006324040000000020232846000000000B5
-:102950000632405000000002023284640000000091
-:10296000063240600000000202328468000000006D
-:1029700006324070000000020232846C0000000049
-:1029800006324080000000020720040000730000AF
-:1029900008200780001004CD072400002AD500007D
-:1029A0000724800027740AB60824D36063FA04CF92
-:1029B00001200000000000000120000400000000D1
-:1029C00001200008000000000120000C00000000B1
-:1029D0000120001000000000012000140000000091
-:1029E000022000200000000102200024000000025C
-:1029F00002200028000000030220002C000000003C
-:102A00000220003000000004022000340000000119
-:102A100002200038000000000220003C00000001FD
-:102A200002200040000000040220004400000000DA
-:102A300002200048000000010220004C00000003BA
-:102A4000022000500000000002200054000000019D
-:102A500002200058000000040220005C000000007A
-:102A6000022000600000000102200064000000035A
-:102A700002200068000000000220006C000000013D
-:102A8000022000700000000402200074000000001A
-:102A900002200078000000040220007C00000003F7
-:102AA0000620008000000002022000A400007FFF3A
-:102AB000022000A8000003FF022002240000000002
-:102AC00002200234000000000220024C000000003E
-:102AD000022002E40000FFFF0620200000000800A2
-:102AE00002238BC0000000010223800000000010C0
-:102AF000022380400000001202238080000000308A
-:102B0000022380C00000000E0C23830000086470C4
-:102B10000A238300000001570B2383000000055F98
-:102B20000A238340000000000C238340000002269B
-:102B30000B2383400000000102238380000864709F
-:102B4000022383C00000022602231480000000013B
-:102B50000A2314800000000006221000000000423A
-:102B600006222008000000C8062220000000000203
-:102B70000622B000000003300622F40000000053DB
-:102B80000422F54C000104D10622F5500000000398
-:102B90000422F55C000104D20622F5600000000367
-:102BA0000422F56C000104D30622F5700000000336
-:102BB0000422F57C000104D40622F5800000000305
-:102BC0000422F58C000104D50622F59000000003D4
-:102BD0000422F59C000104D60622F5A000000003A3
-:102BE0000422F5AC000104D70622F5B00000000372
-:102BF0000422F5BC000104D80622F5C000000046FE
-:102C00000622E2000000044004221240009004D991
-:102C100006223000000000C006226700000001000C
-:102C2000062290000000040004226B0800200569C1
-:102C3000062211F000000006042212080006058991
-:102C4000062212200000000206224000000005C0FB
-:102C50000622C000000000060422C0180006058FEE
-:102C60000622C0300000000A0422C0580006059564
-:102C70000622C0700000000A0422C0980006059BCE
-:102C80000622C0B00000000A0422C0D8000605A138
-:102C90000622C0F00000000A0422C118000605A7A1
-:102CA0000622C1300000000A0422C158000605AD0A
-:102CB0000622C1700000000A0422C198000605B374
-:102CC0000622C1B00000000A0422C1D8000605B9DE
-:102CD0000622C1F00000000A0422C218000605BF47
-:102CE0000622C2300000000A0422C258000605C5B0
-:102CF0000622C2700000000A0422C298000605CB1A
-:102D00000622C2B00000000A0422C2D8000605D183
-:102D10000622C2F00000000A0422C318000605D7EC
-:102D20000622C3300000000A0422C358000605DD55
-:102D30000622C3700000000A0422C398000605E3BF
-:102D40000622C3B00000000A0422C3D8000605E929
-:102D50000622C3F00000000A0422C418000605EF92
-:102D60000622C4300000000A0422C458000605F5FB
-:102D70000622C4700000000A0422C498000605FB65
-:102D80000622C4B00000000A0422C4D800060601CE
-:102D90000622C4F00000000A0422C5180006060737
-:102DA0000622C5300000000A0422C5580006060DA0
-:102DB0000622C5700000000A0422C598000606130A
-:102DC0000622C5B00000000A0422C5D80006061974
-:102DD0000622C5F00000000A0422C6180006061FDD
-:102DE0000622C6300000000A0422C6580006062546
-:102DF0000622C6700000000A0422C6980006062BB0
-:102E00000622C6B00000000A0422C6D80006063119
-:102E10000622C6F00000000A0422C7180006063782
-:102E20000622C7300000000A0422C7580006063DEB
-:102E30000622C7700000000A0422C7980006064355
-:102E40000622C7B00000000A0422C7D800060649BF
-:102E50000622C7F00000000A0422C8180006064F28
-:102E60000622C8300000000A0422C8580006065591
-:102E70000622C8700000000A0422C8980006065BFB
-:102E80000622C8B00000000A0422C8D80006066165
-:102E90000622C8F00000000A0422C91800060667CE
-:102EA0000622C9300000000A0422C9580006066D37
-:102EB0000622C9700000000A0422C99800060673A1
-:102EC0000622C9B00000000A0422C9D8000606790B
-:102ED0000622C9F00000000A0422CA180006067F74
-:102EE0000622CA300000000A0422CA5800060685DD
-:102EF0000622CA700000000A0422CA980006068B47
-:102F00000622CAB00000000A0422CAD800060691B0
-:102F10000622CAF00000000A0422CB180006069719
-:102F20000622CB300000000A0422CB580006069D82
-:102F30000622CB700000000A0422CB98000606A3EC
-:102F40000622CBB00000000A0422CBD8000606A956
-:102F50000622CBF00000000A0422CC18000606AFBF
-:102F60000622CC300000000A0422CC58000606B528
-:102F70000622CC700000000A0422CC98000606BB92
-:102F80000622CCB00000000A0422CCD8000606C1FC
-:102F90000622CCF00000000A0422CD18000606C765
-:102FA0000622CD300000000A0422CD58000606CDCE
-:102FB0000622CD700000000A0422CD98000606D338
-:102FC0000622CDB00000000A0422CDD8000606D9A2
-:102FD0000622CDF00000000A0422CE18000606DF0B
-:102FE0000622CE300000000A0422CE58000606E574
-:102FF0000622CE700000000A0422CE98000606EBDE
-:103000000622CEB00000000A0422CED8000606F147
-:103010000622CEF00000000A0422CF18000606F7B0
-:103020000622CF300000000A0422CF58000606FD19
-:103030000622CF700000000A0422CF980006070382
-:103040000622CFB00000000A0422CFD800060709EC
-:103050000622CFF00000000A0422D0180006070F55
-:103060000622D0300000000A0422D05800060715BE
-:103070000622D0700000000A0422D0980006071B28
-:103080000622D0B00000000A0422D0D80006072192
-:103090000622D0F00000000A0422D11800060727FB
-:1030A0000622D1300000000A0422D1580006072D64
-:1030B0000622D1700000000A0422D19800060733CE
-:1030C0000622D1B00000000A0422D1D80006073938
-:1030D0000622D1F00000000A0422D2180006073FA1
-:1030E0000622D2300000000A0422D258000607450A
-:1030F0000622D2700000000A0422D2980006074B74
-:103100000622D2B00000000A0422D2D800060751DD
-:103110000622D2F00000000A0422D3180006075746
-:103120000622D3300000000A0422D3580006075DAF
-:103130000622D3700000000A0422D3980006076319
-:103140000622D3B00000000A0422D3D80006076983
-:103150000622D3F00000000A0422D4180006076FEC
-:103160000622D4300000000A0422D4580006077555
-:103170000622D4700000000A0422D4980006077BBF
-:103180000622D4B00000000A0422D4D80006078129
-:103190000622D4F00000000A0422D5180006078792
-:1031A0000622D5300000000A0422D5580006078DFB
-:1031B0000622D5700000000A0422D5980006079365
-:1031C0000622D5B00000000A0422D5D800060799CF
-:1031D0000622D5F00000000A0422D6180006079F38
-:1031E0000622D6300000000A0422D658000607A5A1
-:1031F0000622D6700000000A0422D698000607AB0B
-:103200000622D6B00000000A0422D6D8000607B174
-:103210000622D6F00000000A0422D718000607B7DD
-:103220000622D7300000000A0422D758000607BD46
-:103230000622D7700000000A0422D798000607C3B0
-:103240000622D7B00000000A0422D7D8000607C91A
-:103250000622D7F00000000A0422D818000607CF83
-:103260000622D8300000000A0422D858000607D5EC
-:103270000622D8700000000A0422D898000607DB56
-:103280000622D8B00000000A0422D8D8000607E1C0
-:103290000622D8F00000000A0422D918000607E729
-:1032A0000622D9300000000A0422D958000607ED92
-:1032B0000622D9700000000A0422D998000607F3FC
-:1032C0000622D9B00000000A0422D9D8000607F966
-:1032D0000622D9F00000000A0422DA18000607FFCF
-:1032E0000622DA300000000A0422DA580006080537
-:1032F0000622DA700000000A0422DA980006080BA1
-:103300000622DAB00000000A0422DAD8000608110A
-:103310000622DAF00000000A0422DB180006081773
-:103320000622DB300000000A0422DB580006081DDC
-:103330000622DB700000000A0422DB980006082346
-:103340000622DBB00000000A0422DBD800060829B0
-:103350000622DBF00000000A0422DC180006082F19
-:103360000622DC300000000A0422DC580006083582
-:103370000622DC700000000A0422DC980006083BEC
-:103380000622DCB00000000A0422DCD80006084156
-:103390000622DCF00000000A0422DD1800060847BF
-:1033A0000622DD300000000A0422DD580006084D28
-:1033B0000622DD700000000A0422DD980006085392
-:1033C0000622DDB00000000A0422DDD800060859FC
-:1033D0000622DDF00000000A0422DE180006085F65
-:1033E0000622DE300000000A0422DE5800060865CE
-:1033F0000622DE700000000A0422DE980006086B38
-:103400000622DEB00000000A0422DED800060871A1
-:103410000622DEF00000000A0422DF18000608770A
-:103420000622DF300000000A0422DF580006087D73
-:103430000622DF700000000A0422DF9800060883DD
-:103440000622DFB00000000A0422DFD80006088947
-:103450000622DFF00000000A0422E0180006088FB0
-:103460000622E0300000000A0422E0580006089519
-:103470000622E0700000000A0422E0980006089B83
-:103480000622E0B00000000A0422E0D8000608A1ED
-:103490000622E0F00000000A0422E118000608A756
-:1034A0000622E1300000000A0422E158000608ADBF
-:1034B0000622E1700000000A0422E198000608B329
-:1034C0000622E1B00000000A0422E1D8000608B993
-:1034D0000622E1F000000004062215380000000278
-:1034E000062211E8000000020622F3000000000896
-:1034F00002221148000000000622590000000006C8
-:103500000622330000000002062260400000003066
-:103510000622F320000000080222114C00000000E7
-:103520000622591800000006062233080000000297
-:1035300006226100000000300622F340000000086F
-:10354000022211500000000006225930000000063F
-:103550000622331000000002062261C00000003085
-:103560000622F3600000000802221154000000004F
-:103570000622594800000006062233180000000207
-:1035800006226280000000300622F380000000085E
-:1035900002221158000000000622596000000006B7
-:1035A00006223320000000020622634000000030A3
-:1035B0000622F3A0000000080222115C00000000B7
-:1035C0000622597800000006062233280000000277
-:1035D00006226400000000300622F3C0000000084C
-:1035E000022211600000000006225990000000062F
-:1035F0000622333000000002062264C000000030C2
-:103600000622F3E00000000802221164000000001E
-:10361000062259A8000000060622333800000002E6
-:10362000062265800000003002161000000000280D
-:1036300002170008000000020217002C000000031F
-:103640000217003C000000040217004400000000C4
-:1036500002170048000000020217004C0000009012
-:1036600002170050000000900217005400800090E4
-:103670000217005808100000021700700000000632
-:1036800002170078000009FF0217007C0000076C99
-:10369000021701C4081000000217034400000001D3
-:1036A000021704000000008A0217040400000080D2
-:1036B00002170408000000810217040C00000080BB
-:1036C000021704100000008A021704140000008092
-:1036D00002170418000000810217041C000000807B
-:1036E000021704300000008A021704340000008032
-:1036F00002170438000000810217043C000000801B
-:10370000021704400000008A0217044400000080F1
-:1037100002170448000000810217044C00000080DA
-:10372000021704800000008A021704840000008051
-:1037300002170488000000810217048C000000803A
-:1037400002170038007C1004021700040000000F6C
-:10375000021701EC00000002021701F40000000251
-:10376000021701EC00000002021701F40000000241
-:10377000021701EC00000002021701F40000000231
-:10378000021701EC00000002021701F40000000221
-:10379000021701EC00000002021701F40000000211
-:1037A000021701EC00000002021701F40000000201
-:1037B000021701EC00000002021701F400000002F1
-:1037C000021701EC00000002021701F400000002E1
-:1037D0000616402400000002021640700000001C83
-:1037E000021642080000000102164210000000010B
-:1037F00002164220000000010216422800000001CB
-:10380000021642300000000102164238000000019A
-:1038100002164260000000020C16401C0003D0900B
-:103820000A16401C0000009C0B16401C0000027190
-:103830000216403000000028021640340000002C20
-:1038400002164038000000300216404400000020FC
-:103850000216400000000001021640D800000001DE
-:1038600002164008000000010216400C0000000192
-:103870000216401000000001021642400000000045
-:1038800002164248000000000616427000000002C6
-:1038900002164250000000000216425800000000CC
-:1038A0000616428000000002021660080000121492
-:1038B0000216600C000012000216601000001204D4
-:1038C0000216601C0000FFFF021660200000FFFFD0
-:1038D000021660240000FFFF021660280000FFFFB0
-:1038E00002166038000000200216603C0000001044
-:1038F0000616604000000002021660480000002327
-:103900000216604C000000240216605000000025E2
-:1039100002166054000000260216605800000027BE
-:103920000216605C000000110216606000000000DA
-:10393000021660640000002B021660680000002C74
-:103940000216606C0000002D02166070000000EC92
-:103950000216607400000000021660780000002962
-:103960000216607C0000002A021660800000002F12
-:10397000061660840000000D021660B80000000109
-:10398000061660BC00000008021660DC00000001A2
-:10399000061660E000000004021660F0000000015E
-:1039A000061660F40000000302166100000000012A
-:1039B000061661040000002D021661B80000000127
-:1039C000061661BC00000008021661DC0000000160
-:1039D000061661E000000004021661F0000000011C
-:1039E000061661F4000000030216620000000001E8
-:1039F000061662040000000D0216623807FFFFFF82
-:103A00000216623C0000007F0216624007FFFFFFC3
-:103A1000021662440000003F0116624800000000E8
-:103A20000116624C00000000011662500000000008
-:103A300001166254000000000116625800000000E8
-:103A40000116625C000000000116626000000000C8
-:103A500001166264000000000116626800000000A8
-:103A60000116626C00000000011662700000000088
-:103A70000116627400000000011662780000000068
-:103A80000116627C00000000011662D400000000F4
-:103A9000021662D80000FFFF021662DC0000FFFF82
-:103AA000021662E00000FFFF021662E40000FFFF62
-:103AB0000C166000000003E80A1660000000000118
-:103AC0000B16600000000003021680400000000694
-:103AD0000216804400000005021680480000000A1B
-:103AE0000216804C000000050216805400000002FF
-:103AF000021680CC00000004021680D000000004F2
-:103B0000021680D400000004021680D800000004D1
-:103B1000021680DC00000004021680E000000004B1
-:103B2000021680E400000004021680E80000000491
-:103B30000216880400000006021680300000007C97
-:103B4000021680340000003D021680380000003F5D
-:103B50000216803C0000009C0216E6E800006000AF
-:103B60000216E6EC000060000216E6F000006000BD
-:103B70000216E6F40000600002168234000025E41C
-:103B8000021682380000800002168094000025E3AF
-:103B9000021681F400000C08021681F800000040B3
-:103BA000021681FC000001000216820000000020C5
-:103BB000021682040000001702168208000000802E
-:103BC0000216820C000002000216821000000000A3
-:103BD0000216823C0000001302168220008F008F24
-:103BE0000216821C008F008F021680F00000000772
-:103BF0000216821801FF01FF0216821401FF01FF65
-:103C0000061680F4000000020216811C0000000568
-:103C10000216812000000005021681240000000524
-:103C200002168128000000080216812C0000000600
-:103C300002168130000000070616813400000004DF
-:103C4000021680FC000000000616814400000002FD
-:103C50000216814C00000004021681500000000191
-:103C6000021681540000000202168158000000056F
-:103C70000216815C0000000502168160000000054C
-:103C80000216816400000005021681680000000829
-:103C900002168100000000000216816C0000000680
-:103CA00002168170000000070616817400000006ED
-:103CB0000216818C000000040216819000000001B1
-:103CC0000216810400000000021681940000000228
-:103CD00002168198000000050216819C0000000574
-:103CE000021681A000000005021681A40000000554
-:103CF000021681A800000008021681AC0000000630
-:103D0000021681B000000007061681B40000000210
-:103D10000216810800000000061681BC00000004A5
-:103D2000021681CC00000004021681D000000001C0
-:103D3000021681D400000002021681D8000000059E
-:103D4000021681DC00000005021681E0000000057B
-:103D50000216810C00000004021681E40000000538
-:103D6000021681E800000008021681EC000000063F
-:103D7000021681F000000007021681100000000109
-:103D800002168114000000020216811800000005CE
-:103D90000216809C0000004C021680A00000004C1F
-:103DA000061680C400000002021680A40000000075
-:103DB000021680A800000000021680AC0000004C33
-:103DC000061680B0000000050216E6F800000204A6
-:103DD00002168240003F003F02168244003F003F2F
-:103DE00006168290000000040216824800800080BF
-:103DF0000216824C008000800216825001000100F1
-:103E000002168254010001000616825800000002CA
-:103E100002168260004000400216826400400040AA
-:103E2000021682681E001E000216826C1E001E0012
-:103E3000021682704000400002168274400040006A
-:103E400002168278800080000216827C800080004A
-:103E500002168280200020000216828420002000AA
-:103E60000616828800000002021680900000004BB7
-:103E700002168060000001400216806400000140CC
-:103E8000061680880000000202168068000000000C
-:103E90000216806C0000000002168070000000C056
-:103EA00006168074000000050216880C010101014D
-:103EB000021688100101200402168814200810013F
-:103EC00002168818010101200216881C0101010157
-:103ED00002168820010120040216882420081001FF
-:103EE00002168828010101200216882C20081001E2
-:103EF00002168830010101200216883401010101F7
-:103F000002168838010120040216883C200810019E
-:103F100002168840010101200216884401010101B6
-:103F200002168848010120040216E6BC00000000C9
-:103F30000216E6C0000000020216E6C400000004FB
-:103F40000216E6C8000000060216E7940000000111
-:103F5000021680EC000000FF0214000000000001C7
-:103F60000215C024000000000215C0EC0000000192
-:103F70000215C0F0000000010615C100000000029B
-:103F800002140004000000010214000800000001F7
-:103F90000214000C000000010214003000000001B7
-:103FA000021400340000000102140040000000016F
-:103FB000021400440000FFFF061400040000000388
-:103FC0000214000000000000060280000000200033
-:103FD0000202005800000032020200A00315002077
-:103FE000020200A403150020020200A80100003014
-:103FF000020200AC08100000020200B0000000360F
-:10400000020200B400000030020200B800000031DB
-:10401000020200BC00000002020200C00000000515
-:10402000020200C400000002020200C800000002F8
-:10403000020200D000000007020200DC00000000C5
-:10404000020200E000000005020200E4000000039C
-:10405000020200F000000001020200FC0000000665
-:1040600002020120000000000202013400000002F0
-:10407000020201B0000000010202020C0000000177
-:1040800002020214000000010202021800000002F5
-:1040900002020404000000010202040C00000040BF
-:1040A00002020410000000400202041C0000000490
-:1040B000020204200000002002020424000000028A
-:1040C0000202042800000020060205000000001281
-:1040D00004020480002008BF020200600000000FFC
-:1040E00002020064000000070202006800000000F5
-:1040F0000202006C0000000E020200700000000EC0
-:104100000602007400000003020200F40000000434
-:104110000202000400000001020200080000000189
-:104120000202000C00000001020200100000000169
-:104130000202001400000001020200180000000149
-:104140000202001C00000001020200200000000129
-:104150000202002400000001020200280000000109
-:104160000202002C000000010202003000000001E9
-:1041700002020034000000010202003800000001C9
-:104180000202003C000000010202004000000001A9
-:104190000202004400000001020200480000000189
-:1041A0000202004C00000001020200500000000169
-:1041B00002020108000000C802020118000000020B
-:1041C000020201C400000000020201CC0000000055
-:1041D000020201D400000002020201DC0000000221
-:1041E000020201E4000000FF020201EC000000FFF7
-:1041F00002020100000000000202010C000000C8E1
-:104200000202011C00000002020201C800000000BE
-:10421000020201D000000000020201D800000002EA
-:10422000020201E000000002020201E8000000FFBB
-:10423000020201F0000000FF020201040000002061
-:1042400002020108000000C802020118000000027A
-:10425000020201C400000000020201CC00000000C4
-:10426000020201D400000002020201DC0000000290
-:10427000020201E4000000FF020201EC000000FF66
-:1042800002020100000000100202010C000000C840
-:104290000202011C00000002020201C8000000002E
-:1042A000020201D000000000020201D8000000025A
-:1042B000020201E000000002020201E8000000FF2B
-:1042C000020201F0000000FF0202010400000030C1
-:1042D00002020108000000C80202011800000002EA
-:1042E000020201C400000000020201CC0000000034
-:1042F000020201D400000002020201DC0000000200
-:10430000020201E4000000FF020201EC000000FFD5
-:1043100002020100000000400202010C000000C87F
-:104320000202011C00000002020201C8000000009D
-:10433000020201D000000000020201D800000002C9
-:10434000020201E000000002020201E8000000FF9A
-:10435000020201F0000000FF020201040000006000
-:1043600002020108000000C8020201180000000259
-:10437000020201C400000000020201CC00000000A3
-:10438000020201D400000002020201DC000000026F
-:10439000020201E4000000FF020201EC000000FF45
-:1043A00002020100000000500202010C000000C8DF
-:1043B0000202011C00000002020201C8000000000D
-:1043C000020201D000000000020201D80000000239
-:1043D000020201E000000002020201E8000000FF0A
-:1043E000020201F0000000FF020201040000007060
-:1043F0000728040000B50000082807B8000908DFF6
-:10440000072C000028C30000072C800036720A31F8
-:10441000072D000035B617CE072D80003B00253C48
-:10442000072E0000366D33FD072E80001AA8419933
-:10443000082EBF20281C08E1012800000000000011
-:10444000012800040000000001280008000000000E
-:104450000128000C000000000128001000000000EE
-:1044600001280014000000000228002000000001C4
-:104470000228002400000002022800280000000397
-:104480000228002C00000000022800300000000478
-:10449000022800340000000102280038000000005B
-:1044A0000228003C00000001022800400000000437
-:1044B000022800440000000002280048000000011B
-:1044C0000228004C000000030228005000000000F9
-:1044D00002280054000000010228005800000004D7
-:1044E0000228005C000000000228006000000001BB
-:1044F0000228006400000003022800680000000099
-:104500000228006C00000001022800700000000476
-:104510000228007400000000022800780000000457
-:104520000228007C00000003062800800000000232
-:10453000022800A400007FFF022800A8000003FF5B
-:1045400002280224000000000228023400000000BB
-:104550000228024C00000000022802E40000FFFFD5
-:104560000628200000000800022B8BC0000000017C
-:10457000022B800000000000022B80400000001889
-:10458000022B80800000000C022B80C0000000661F
-:104590000C2B8300000864700A2B83000000015775
-:1045A0000B2B83000000055F0A2B834000000000F6
-:1045B0000C2B8340000002260B2B834000000001DF
-:1045C000022B838000086470022B83C00000022647
-:1045D000022B1480000000010A2B14800000000050
-:1045E000022B944000000001062B944800000002BA
-:1045F000062A9A7000000004042A9A80000408E346
-:10460000062A9A9000000002042A9A98000208E7FD
-:10461000062A900000000048062A2008000000C872
-:10462000062A200000000002062A912800000086C9
-:10463000062AC00000000120062A9348000000035B
-:10464000042A9354000108E9062A9FB000000002E2
-:10465000042A9418000208EA042A9CD0000108ECFD
-:10466000062A9CD400000011042A9D20008F08ED2A
-:10467000062A9F5C00000005042A30000002097C25
-:10468000062A300800000100062A40400000001001
-:10469000042A40000010097E042A84080002098EC2
-:1046A000042ACF4000040990042ACF600002099434
-:1046B000062A9FA000000004062A600000000540B2
-:1046C000062A9D1800000002062AB00000000050D3
-:1046D000062ABB7000000070062ABB6800000002BA
-:1046E000062AB94800000004062AD000000008008D
-:1046F000062AC48000000150062A942000000032DF
-:10470000062A502000000002062A50300000000255
-:10471000062A500000000002062A50100000000285
-:10472000022A520800000001042A9AA000020996F9
-:10473000062A95B000000022042A96380001099844
-:10474000062A963C00000003062A96E0000000229C
-:10475000042A976800010999062A976C0000000353
-:10476000062A981000000022042A98980001099A4D
-:10477000062A989C00000003062A994000000022A7
-:10478000042A99C80001099B062A99CC000000035D
-:10479000062ABB5800000002062AC9C000000150CA
-:1047A000062A94E800000032062A50280000000281
-:1047B000062A503800000002062A500800000002B5
-:1047C000062A501800000002022A520C00000001C4
-:1047D000042A9AA80002099C062A96480000002292
-:1047E000042A96D00001099E062A96D400000003F0
-:1047F000062A977800000022042A98000001099FE9
-:10480000062A980400000003062A98A80000002247
-:10481000042A9930000109A0062A993400000003F7
-:10482000062A99D800000022042A9A60000109A1F2
-:10483000062A9A6400000003062ABB6000000002FA
-:10484000022ACF0000000000042A9AB0001009A23A
-:10485000062A50480000000E022ACF040000000083
-:10486000042A9AF0001009B2062A50800000000EB7
-:10487000022ACF0800000000042A9B30001009C261
-:10488000062A50B80000000E022ACF0C00000000DB
-:10489000042A9B70001009D2062A50F00000000E76
-:1048A000022ACF1000000000042A9BB0001009E289
-:1048B000062A51280000000E022ACF140000000032
-:1048C000042A9BF0001009F2062A51600000000E35
-:1048D000022ACF1800000000042A9C3000100A02AF
-:1048E000062A51980000000E022ACF1C000000008A
-:1048F000042A9C7000100A12062A51D00000000EF3
-:104900000210100800000001021010500000000109
-:10491000021010000003D000021010040000003D3F
-:104920000910180002000A220910110000100C22C0
-:1049300006101140000000080910116000100C3230
-:10494000061011A00000001806102400000000E06E
-:104950000210201C000000000210202000000001B6
-:10496000021020C00000000202102004000000011C
-:104970000210200800000001021030D800000001E1
-:1049800009103C0000050C420910380000050C47D6
-:104990000910392000050C4C09103B0000050C5192
-:1049A00006104C000000010002104028000000101A
-:1049B0000210404400003FFF021040580028000051
-:1049C000021040840084924A021040580000000007
-:1049D00002104138000000010210413800000001BF
-:1049E00002104138000000010210413800000001AF
-:1049F000021041380000000102104138000000019F
-:104A0000021041380000000102104138000000018E
-:104A10000212049001F680400212051400003C10BE
-:104A200002120494FFFFFFFF02120498FFFFFFFF32
-:104A30000212049CFFFFFFFF021204A0FFFFFFFF12
-:104A4000021204A4FFFFFFFF021204A8FFFFFFFFF2
-:104A5000021204ACFFFFFFFF021204B0FFFFFFFFD2
-:104A6000021204B8FFFFFFFF021204BCFFFFFFFFAA
-:104A7000021204C0FFFFFFFF021204C4FFFFFFFF8A
-:104A8000021204C8FFFFFFFF021204CCFFFFFFFF6A
-:104A9000021204D0FFFFFFFF021204D8FFFFFFFF46
-:104AA000021204DCFFFFFFFF021204E0FFFFFFFF22
-:104AB000021204E4FFFFFFFF021204E8FFFFFFFF02
-:104AC000021204ECFFFFFFFF021204F0FFFFFFFFE2
-:104AD000021204F4FFFFFFFF021204F8FFFFFFFFC2
-:104AE000021204FCFFFFFFFF02120500FFFFFFFFA1
-:104AF00002120504FFFFFFFF02120508FFFFFFFF80
-:104B00000212050CFFFFFFFF02120510FFFFFFFF5F
-:104B1000021204D4F800C000021204B4F0005000E5
-:104B200002120390000000080212039C000000081B
-:104B3000021203A000000008021203A400000002F9
-:104B4000021203BC00000004021203C000000005B2
-:104B5000021203C400000004021203D0000000008F
-:104B60000212036C00000001021201BC00000040B0
-:104B7000021201C000001808021201C4000008035C
-:104B8000021201C800000803021201CC000000401C
-:104B9000021201D000000003021201D40000080339
-:104BA000021201D800000803021201DC0000080311
-:104BB000021201E000010003021201E400000803F8
-:104BC000021201E800000803021201EC00000003D9
-:104BD000021201F000000003021201F400000003C1
-:104BE000021201F800000003021201FC00000003A1
-:104BF000021202000000000302120204000000037F
-:104C000002120208000000030212020C000000035E
-:104C1000021202100000000302120214000000033E
-:104C200002120218000000030212021C000000031E
-:104C300002120220000000030212022400000003FE
-:104C400002120228000024030212022C0000002F8E
-:104C500002120230000000090212023400000019A2
-:104C600002120238000001840212023C000001839B
-:104C70000212024000000306021202440000001962
-:104C800002120248000000060212024C0000030655
-:104C90000212025000000306021202540000030632
-:104CA0000212025800000C860212025C0000030689
-:104CB00002120260000003060212026400000006F5
-:104CC00002120268000000060212026C00000006D8
-:104CD00002120270000000060212027400000006B8
-:104CE00002120278000000060212027C0000000698
-:104CF0000212028000000006021202840000000678
-:104D000002120288000000060212028C0000000657
-:104D10000212029000000006021202940000000637
-:104D200002120298000000060212029C0000000617
-:104D3000021202A000000306021202A400000013E7
-:104D4000021202A800000006021202B000001004C5
-:104D5000021202B400001004021203240010644086
-:104D60000212032800106440021205B40000000182
-:104D7000021205F800000040021205FC00000019B4
-:104D800002120600000000010212066C0000000181
-:104D9000021201B000000001021207D80000000357
-:104DA000021207D800000003021207D80000000317
-:104DB000021207D800000003021207D80000000307
-:104DC000021207D800000003021207D800000003F7
-:104DD000021207D8000000030600A0000000000C2B
-:104DE0000200A050000000000200A05400000000DB
-:104DF0000200A0EC555400000200A0F05555555596
-:104E00000200A0F4000055550200A0F8F0000000D8
-:104E10000200A0FC555400000200A1005555555554
-:104E20000200A104000055550200A108F000000096
-:104E30000200A19C000000000200A1A000010000EF
-:104E40000200A1A4000050140200A1A8000000006C
-:104E50000200A6A8000000000200A6AC00000000AE
-:104E60000200A6D0000000000200A45C00000C00BC
-:104E70000200A61C000000030200A070FFF55FFF07
-:104E80000200A0740000FFFF0200A078F00003E021
-:104E90000200A07C000000000200A0800000A00032
-:104EA0000600A084000000050200A0980FE00000AA
-:104EB0000600A09C000000070200A0B8000004004B
-:104EC0000600A0BC000000030200A0C80000100003
-:104ED0000600A0CC000000030200A0D800004000A3
-:104EE0000600A0DC000000030200A0E800010000B2
-:104EF0000600A22C000000040200A688000000FCAE
-:104F00000600A68C000000070200A6F400000000C6
-:104F10000200A10CFF5C00000200A110FFF55FFF82
-:104F20000200A1140000FFFF0200A118F00003E03E
-:104F30000200A11C000000000200A1200000A0004F
-:104F40000600A124000000050200A1380FE00000C7
-:104F50000600A13C000000070200A1580000080064
-:104F60000600A15C000000030200A1680000200010
-:104F70000600A16C000000030200A1780000800080
-:104F80000600A17C000000030200A18800020000CE
-:104F90000600A23C000000040200A6B0000000FCD5
-:104FA0000600A6B4000000070200A6F800000000FA
-:104FB0000200A030000000000200A0340000000049
-:104FC0000200A038000000000200A03C0000000029
-:104FD0000200A040000000000200A0440000000009
-:104FE0000200A048000000000200A04C00000000E9
-:104FF000020090C40000E000020090CC0000F3002A
-:10500000020090D400000003020091A00000000103
-:105010000600917000000003020090EC00006000A8
-:10502000020090F400007300020090FC00000003F6
-:10503000020091A800000001060091880000000312
-:10504000020091000000400002009108000053009F
-:105050000200911000000004020091AC0000000169
-:1050600006009194000000020200919C00000001E3
-:10507000020090D800006000020090E00000730081
-:10508000020090E800000003020091A4000000016B
-:105090000200917C000000010200918000000001EC
-:1050A000020091840000000002009128000003002B
-:1050B0000200916C0003F0080200912C0000030034
-:1050C0000200913000000300020091340000030050
-:1050D00002009138000003000200913C0000030030
-:1050E00002009140000003000200942C0000000127
-:1050F000020094300000000102009434000000011E
-:105100000200942C00000001020094300000000115
-:1051100002009434000000010200942C0000000101
-:1051200002009430000000010200943400000001ED
-:105130000200942C000000010200943000000001E5
-:1051400002009434000000010200942C00000001D1
-:1051500002009430000000010200943400000001BD
-:105160000200942C000000010200943000000001B5
-:1051700002009434000000010200942C00000001A1
-:10518000020094300000000102009434000000018D
-:105190000200942C00000001020094300000000185
-:1051A00002009434000000010213003C000061A8DA
-:1051B00006130108000000030213010400000000B0
-:1051C0000213013400000000061301080000000370
-:1051D000021301040000000002130134000000006B
-:1051E0000613010800000003021301040000000080
-:1051F0000213013400000000061301080000000340
-:10520000021301040000000002130134000000003A
-:10521000061301080000000302130104000000004F
-:10522000021301340000000006130108000000030F
-:10523000021301040000000002130134000000000A
-:10524000061301080000000302130104000000001F
-:1052500002130134000000000613010800000003DF
-:1052600002130104000000000213013400000000DA
-:10527000021100B8000000010216E6E8000020005C
-:105280000216E6EC000020000216E6F0000065556C
-:105290000216E6F400006555021681500000000079
-:1052A00002168174000000010216817800000001DE
-:1052B0000216817C000000010216818000000001BE
-:1052C000021681840000000102168188000000019E
-:1052D000021681B400000001021681B8000000012E
-:1052E000021681BC00000001021681C0000000010E
-:1052F000021681C400000001021681C800000001EE
-:1053000002168110000000000216824000BF00BF9C
-:1053100006168244000000020216824C00BF00BF45
-:105320000216E6C4000000010216E6C800000003F1
-:105330000216E79400000000042ACF40000A0C5631
-:105340000000000000000000000000340000000029
-:10535000000000000000000000000000000000004D
-:10536000000000000000000000000000000000003D
-:1053700000000000003400350000000000000000C4
-:10538000000000000000000000000000000000001D
-:10539000000000000000000000000000000000000D
-:1053A0000035006000000000000000000000000068
-:1053B00000000000000000000000000000000000ED
-:1053C00000000000000000000000000000600091EC
-:1053D0000000000000000000009100950095009979
-:1053E0000099009D009D00A100A100A500A500A9B5
-:1053F00000A900AD00AD00B100B100B50000000093
-:10540000000000000000000000000000000000009C
-:10541000000000000000000000000000000000008C
-:105420000000000000B503100310031A031A032440
-:105430000324032B032B03320332033903390340C4
-:10544000034003470347034E034E03550355035CD4
-:10545000000000000000000000000000000000004C
-:10546000000000000000000000000000000000003C
-:10547000000000000000000000000000000000002C
-:10548000000000000000000000000000000000001C
-:10549000000000000000000000000000000000000C
-:1054A00000000000000000000000000000000000FC
-:1054B00000000000000000000000000000000000EC
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00000000000000000000000000000000000BC
-:1054F00000000000000000000000000000000000AC
-:10550000035C035D0000000000000000035D035E1B
-:10551000035E035F035F0360036003610361036273
-:105520000362036303630364036403650000000014
-:10553000000000000000000000000000000000006B
-:10554000000000000000000000000000000000005B
-:1055500000000000000000000365036C036C03788A
-:105560000378038400000000000000000000000039
-:10557000000000000000000000000000000000002B
-:10558000000000000000000000000000000000001B
-:10559000000000000000000000000000000000000B
-:1055A00000000000000000000000000000000000FB
-:1055B00003840385000000000000000000000000DC
-:1055C00000000000000000000000000000000000DB
-:1055D000000000000000000000000000038503B090
-:1055E00000000000000000000000000000000000BB
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000003B003DF0000000005
-:10561000000000000000000000000000000000008A
-:10562000000000000000000000000000000000007A
-:105630000000000003DF040E000000000000000076
-:10564000040E04150415041C041C04230423042A5A
-:10565000042A0431043104380438043F043F04466A
-:105660000446047900000000000000000479047D75
-:10567000047D048104810485048504890489048DE2
-:10568000048D04910491049504950499049904E807
-:1056900004E804FE04FE0514051405160516051895
-:1056A0000518051A051A051C051C051E051E0520F2
-:1056B000052005220522052405240690000000008F
-:1056C00000000000069006950695069A069A069F29
-:1056D000069F06A406A406A906A906AE06AE06B352
-:1056E00006B306B806B806B90000000000000000C6
-:1056F00000000000000000000000000000000000AA
-:105700000000000000000000000000000000000099
-:1057100006B906DD000000000000000006DD06DF1F
-:1057200006DF06E106E106E306E306E506E506E731
-:1057300006E706E906E906EB06EB06ED06ED0702CD
-:105740000702070507050708000000000000000029
-:105750000000000000000000000000000000000049
-:1057600000000000000000000708074C00000000D7
-:105770000000000000000000000000000000000029
-:105780000000000000000000000000000000000019
-:1057900000000000074C07DE0000000000000000D1
-:1057A00000000000000000000000000000000000F9
-:1057B00000000000000000000000000000000000E9
-:1057C00007DE07EC00000000000000000000000001
-:1057D00000000000000000000000000000000000C9
-:1057E00000000000000000000000000007EC082995
-:1057F0000000000000000000082908320832083BC1
-:10580000083B08440844084D084D08560856085FF0
-:10581000085F086808680871087108D108D108E6AF
-:1058200008E608FB08FB08FE08FE09010901090457
-:10583000090409070907090A090A090D090D0910D0
-:10584000091009130913091C0000000000000000E2
-:105850000000000000000000000000000000000048
-:105860000000000000000000000000000000000038
-:10587000091C0922000000000000000000000000D8
-:105880000000000000000000000000000000000018
-:1058900000000000000000000000000009220927AD
-:1058A00000000000000000000000000000000000F8
-:1058B00000000000000000000000000000000000E8
-:1058C00000000000000000000927092D0000000072
-:1058D00000000000092D092E092E092F092F09307B
-:1058E00009300931093109320932093309330934E0
-:1058F000093409350000000000000000000000002D
-:105900000000000000000000000000000000000097
-:105910000000000000000000000000000000000087
-:10592000093509A6000000000000000009A609A72B
-:1059300009A709A809A809A909A909AA09AA09ABD7
-:1059400009AB09AC09AC09AD09AD09AE09AE09C294
-:1059500009C209D509D509E909E909EA09EA09EB02
-:1059600009EB09EC09EC09ED09ED09EE09EE09EF87
-:1059700009EF09F009F009F109F10A10000000002F
-:10598000000000000A100A130A130A160A160A1960
-:105990000A190A1C0A1C0A1F0A1F0A220A220A25BF
-:1059A0000A250A280A280A29000000000000000031
-:1059B0000A290A2C0A2C0A2F0A2F0A320A320A351F
-:1059C0000A350A380A380A3B0A3B0A3E0A3E0A41AF
-:1059D0000A410A4200000000000000000000000030
-:1059E00000000000000000000000000000000000B7
-:1059F0000000000000000000000000000A420A5AF7
-:105A00000000000000000000000000000000000096
-:105A10000000000000000000000000000000000086
-:105A200000000000000000000A5A0A5B00000000AD
-:105A30000000000000000000000000000000000066
-:105A40000000000000000000000000000000000056
-:105A5000000000000000000000010000000207003C
-:105A600000030E000004150000051C0000062300C2
-:105A700000072A000008310000093800000A3F0032
-:105A8000000B4600000C4D00000D5400000E5B00A2
-:105A9000000F620000106900001170000012770012
-:105AA00000137E000014850000158C000016930082
-:105AB00000179A000018A1000019A800001AAF00F2
-:105AC000001BB600001CBD00001DC400001ECB0062
-:105AD000001FD2000000D90000002000000040009C
-:105AE00000006000000080000000A0000000C00076
-:105AF0000000E00000010000000120000001400063
-:105B000000016000000180000001A0000001C00051
-:105B10000001E0000002000000022000000240003E
-:105B200000026000000280000002A0000002C0002D
-:105B30000002E0000003000000032000000340001A
-:105B400000036000000380000003A0000003C00009
-:105B50000003E000000400000004200000044000F6
-:105B600000046000000480000004A0000004C000E5
-:105B70000004E000000500000005200000054000D2
-:105B800000056000000580000005A0000005C000C1
-:105B90000005E000000600000006200000064000AE
-:105BA00000066000000680000006A0000006C0009D
-:105BB0000006E0000007000000072000000740008A
-:105BC00000076000000780000007A0000007C00079
-:105BD0000007E00000080000000820000008400066
-:105BE00000086000000880000008A0000008C00055
-:105BF0000008E00000090000000920000009400042
-:105C000000096000000980000009A0000009C00030
-:105C10000009E000000A0000000A2000000A40001D
-:105C2000000A6000000A8000000AA000000AC0000C
-:105C3000000AE000000B0000000B2000000B4000F9
-:105C4000000B6000000B8000000BA000000BC000E8
-:105C5000000BE000000C0000000C2000000C4000D5
-:105C6000000C6000000C8000000CA000000CC000C4
-:105C7000000CE000000D0000000D2000000D4000B1
-:105C8000000D6000000D8000000DA000000DC000A0
-:105C9000000DE000000E0000000E2000000E40008D
-:105CA000000E6000000E8000000EA000000EC0007C
-:105CB000000EE000000F0000000F2000000F400069
-:105CC000000F6000000F8000000FA000000FC00058
-:105CD000000FE00000100000001020000010400045
-:105CE00000106000001080000010A0000010C00034
-:105CF0000010E00000110000001120000011400021
-:105D000000116000001180000011A0000011C0000F
-:105D10000011E000001200000012200000124000FC
-:105D200000126000001280000012A0000012C000EB
-:105D30000012E000001300000013200000134000D8
-:105D400000136000001380000013A0000013C000C7
-:105D50000013E000001400000014200000144000B4
-:105D600000146000001480000014A0000014C000A3
-:105D70000014E00000150000001520000015400090
-:105D800000156000001580000015A0000015C0007F
-:105D90000015E0000016000000162000001640006C
-:105DA00000166000001680000016A0000016C0005B
-:105DB0000016E00000170000001720000017400048
-:105DC00000176000001780000017A0000017C00037
-:105DD0000017E00000180000001820000018400024
-:105DE00000186000001880000018A0000018C00013
-:105DF0000018E00000190000001920000019400000
-:105E000000196000001980000019A0000019C000EE
-:105E10000019E000001A0000001A2000001A4000DB
-:105E2000001A6000001A8000001AA000001AC000CA
-:105E3000001AE000001B0000001B2000001B4000B7
-:105E4000001B6000001B8000001BA000001BC000A6
-:105E5000001BE000001C0000001C2000001C400093
-:105E6000001C6000001C8000001CA000001CC00082
-:105E7000001CE000001D0000001D2000001D40006F
-:105E8000001D6000001D8000001DA000001DC0005E
-:105E9000001DE000001E0000001E2000001E40004B
-:105EA000001E6000001E8000001EA000001EC0003A
-:105EB000001EE000001F0000001F2000001F400027
-:105EC000001F6000001F8000001FA000001FC00016
-:105ED000001FE00000200000002020000020400003
-:105EE00000206000002080000020A0000020C000F2
-:105EF0000020E000002100000021200000214000DF
-:105F000000216000002180000021A0000021C000CD
-:105F10000021E000002200000022200000224000BA
-:105F200000226000002280000022A0000022C000A9
-:105F30000022E00000230000002320000023400096
-:105F400000236000002380000023A0000023C00085
-:105F50000023E00000240000002420000024400072
-:105F600000246000002480000024A0000024C00061
-:105F70000024E0000025000000252000002540004E
-:105F800000256000002580000025A0000025C0003D
-:105F90000025E0000026000000262000002640002A
-:105FA00000266000002680000026A0000026C00019
-:105FB0000026E00000270000002720000027400006
-:105FC00000276000002780000027A0000027C000F5
-:105FD0000027E000002800000028200000284000E2
-:105FE00000286000002880000028A0000028C000D1
-:105FF0000028E000002900000029200000294000BE
-:1060000000296000002980000029A0000029C000AC
-:106010000029E000002A0000002A2000002A400099
-:10602000002A6000002A8000002AA000002AC00088
-:10603000002AE000002B0000002B2000002B400075
-:10604000002B6000002B8000002BA000002BC00064
-:10605000002BE000002C0000002C2000002C400051
-:10606000002C6000002C8000002CA000002CC00040
-:10607000002CE000002D0000002D2000002D40002D
-:10608000002D6000002D8000002DA000002DC0001C
-:10609000002DE000002E0000002E2000002E400009
-:1060A000002E6000002E8000002EA000002EC000F8
-:1060B000002EE000002F0000002F2000002F4000E5
-:1060C000002F6000002F8000002FA000002FC000D4
-:1060D000002FE000003000000030200000304000C1
-:1060E00000306000003080000030A0000030C000B0
-:1060F0000030E0000031000000312000003140009D
-:1061000000316000003180000031A0000031C0008B
-:106110000031E00000320000003220000032400078
-:1061200000326000003280000032A0000032C00067
-:106130000032E00000330000003320000033400054
-:1061400000336000003380000033A0000033C00043
-:106150000033E00000340000003420000034400030
-:1061600000346000003480000034A0000034C0001F
-:106170000034E0000035000000352000003540000C
-:1061800000356000003580000035A0000035C000FB
-:106190000035E000003600000036200000364000E8
-:1061A00000366000003680000036A0000036C000D7
-:1061B0000036E000003700000037200000374000C4
-:1061C00000376000003780000037A0000037C000B3
-:1061D0000037E000003800000038200000384000A0
-:1061E00000386000003880000038A0000038C0008F
-:1061F0000038E0000039000000392000003940007C
-:1062000000396000003980000039A0000039C0006A
-:106210000039E000003A0000003A2000003A400057
-:10622000003A6000003A8000003AA000003AC00046
-:10623000003AE000003B0000003B2000003B400033
-:10624000003B6000003B8000003BA000003BC00022
-:10625000003BE000003C0000003C2000003C40000F
-:10626000003C6000003C8000003CA000003CC000FE
-:10627000003CE000003D0000003D2000003D4000EB
-:10628000003D6000003D8000003DA000003DC000DA
-:10629000003DE000003E0000003E2000003E4000C7
-:1062A000003E6000003E8000003EA000003EC000B6
-:1062B000003EE000003F0000003F2000003F4000A3
-:1062C000003F6000003F8000003FA000003FC00092
-:1062D000003FE000003FE00100000000000001FF7F
-:1062E0000000020000007FF800007FF800000A9420
-:1062F00000001500000000010000FF000000000089
-:106300000000FF00000000000000FF00000000008F
-:106310000000FF00000000000000FF00000000007F
-:106320000000FF00000000000000FF00000000006F
-:106330000000FF00000000000000FF00000000005F
-:106340000000FF00000000000000FF00000000004F
-:106350000000FF00000000000000FF00000000003F
-:106360000000FF00000000000000FF00000000002F
-:106370000000FF00000000000000FF00000000001F
-:106380000000FF00000000000000FF00000000000F
-:106390000000FF00000000000000FF0000000000FF
-:1063A0000000FF00000000000000FF0000000000EF
-:1063B0000000FF00000000000000FF0000000000DF
-:1063C0000000FF00000000000000FF0000000000CF
-:1063D0000000FF00000000000000FF0000000000BF
-:1063E0000000FF00000000000000FF0000000000AF
-:1063F0000000FF00000000000000FF00000000009F
-:106400000000FF00000000000000FF00000000008E
-:106410000000FF00000000000000FF00000000007E
-:106420000000FF00000000000000FF00000000006E
-:106430000000FF00000000000000FF00000000005E
-:106440000000FF00000000000000FF00000000004E
-:106450000000FF00000000000000FF00000000003E
-:106460000000FF00000000000000FF00000000002E
-:106470000000FF00000000000000FF00000000001E
-:106480000000FF00000000000000FF00000000000E
-:106490000000FF00000000000000FF0000000000FE
-:1064A0000000FF00000000000000FF0000000000EE
-:1064B0000000FF00000000000000FF0000000000DE
-:1064C0000000FF00000000000000FF0000000000CE
-:1064D0000000FF00000000000000FF0000000000BE
-:1064E0000000FF00000000000000FF0000000000AE
-:1064F0000000FF00000000000000FF00000000009E
-:106500000000FF00000000000000FF00000000008D
-:106510000000FF00000000000000FF00000000007D
-:106520000000FF00000000000000FF00000000006D
-:106530000000FF000000000000000000140AFF003F
-:106540000000000100000000002010010000000019
-:106550000100900000000100000090020000900483
-:1065600000009006000090080000900A0000900CC7
-:106570000000900E00009010000090120000901497
-:1065800000009016000090180000901A0000901C67
-:106590000000901E00009020000090220000902437
-:1065A00000009026000090280000902A0000902C07
-:1065B0000000902E000090300000903200009034D7
-:1065C00000009036000090380000903A0000903CA7
-:1065D0000000903E00009040000090420000904477
-:1065E00000009046000090480000904A0000904C47
-:1065F0000000904E00009050000090520000905417
-:1066000000009056000090580000905A0000905CE6
-:106610000000905E000090600000906200009064B6
-:1066200000009066000090680000906A0000906C86
-:106630000000906E00009070000090720000907456
-:1066400000009076000090780000907A0000907C26
-:106650000000907E000090800000908200009084F6
-:1066600000009086000090880000908A0000908CC6
-:106670000000908E00009090000090920000909496
-:1066800000009096000090980000909A0000909C66
-:106690000000909E000090A0000090A2000090A436
-:1066A000000090A6000090A8000090AA000090AC06
-:1066B000000090AE000090B0000090B2000090B4D6
-:1066C000000090B6000090B8000090BA000090BCA6
-:1066D000000090BE000090C0000090C2000090C476
-:1066E000000090C6000090C8000090CA000090CC46
-:1066F000000090CE000090D0000090D2000090D416
-:10670000000090D6000090D8000090DA000090DCE5
-:10671000000090DE000090E0000090E2000090E4B5
-:10672000000090E6000090E8000090EA000090EC85
-:10673000000090EE000090F0000090F2000090F455
-:10674000000090F6000090F8000090FA000090FC25
-:10675000000090FE000091000000910200009104F2
-:1067600000009106000091080000910A0000910CC1
-:106770000000910E00009110000091120000911491
-:1067800000009116000091180000911A0000911C61
-:106790000000911E00009120000091220000912431
-:1067A00000009126000091280000912A0000912C01
-:1067B0000000912E000091300000913200009134D1
-:1067C00000009136000091380000913A0000913CA1
-:1067D0000000913E00009140000091420000914471
-:1067E00000009146000091480000914A0000914C41
-:1067F0000000914E00009150000091520000915411
-:1068000000009156000091580000915A0000915CE0
-:106810000000915E000091600000916200009164B0
-:1068200000009166000091680000916A0000916C80
-:106830000000916E00009170000091720000917450
-:1068400000009176000091780000917A0000917C20
-:106850000000917E000091800000918200009184F0
-:1068600000009186000091880000918A0000918CC0
-:106870000000918E00009190000091920000919490
-:1068800000009196000091980000919A0000919C60
-:106890000000919E000091A0000091A2000091A430
-:1068A000000091A6000091A8000091AA000091AC00
-:1068B000000091AE000091B0000091B2000091B4D0
-:1068C000000091B6000091B8000091BA000091BCA0
-:1068D000000091BE000091C0000091C2000091C470
-:1068E000000091C6000091C8000091CA000091CC40
-:1068F000000091CE000091D0000091D2000091D410
-:10690000000091D6000091D8000091DA000091DCDF
-:10691000000091DE000091E0000091E2000091E4AF
-:10692000000091E6000091E8000091EA000091EC7F
-:10693000000091EE000091F0000091F2000091F44F
-:10694000000091F6000091F8000091FA000091FC1F
-:10695000000091FEFFFFFFFFFFFFFFFFFFFFFFFFB4
-:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
-:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
-:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
-:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
-:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
-:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
-:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
-:1069D000FFFFFFFF0000000300BEBC20000000001E
-:1069E000000000050000000300BEBC200000000005
-:1069F000000000050000000300BEBC2000000000F5
-:106A0000000000050000000300BEBC2000000000E4
-:106A1000000000050000000300BEBC2000000000D4
-:106A2000000000050000000300BEBC2000000000C4
-:106A3000000000050000000300BEBC2000000000B4
-:106A4000000000050000000300BEBC2000000000A4
-:106A50000000000500002000000040C00000618030
-:106A6000000082400000A3000000C3C00000E480DA
-:106A70000001054000012600000146C000016780BA
-:106A8000000188400001A9000001C9C00001EA809E
-:106A900000020B4000022C0000024CC000026D807E
-:106AA00000028E400002AF000002CFC00002F08062
-:106AB00000001140000080000001038000018700F9
-:106AC00000020A8000028E0000031180000395007E
-:106AD0000004188000049C0000051F800005A3002E
-:106AE000000626800006AA0000072D800007B100DE
-:106AF000000834800008B80000093B800009BF008E
-:106B0000000A4280000AC600000B4980000BCD003D
-:106B1000000C5080000CD400000D578000005B007A
-:106B200000007FF800007FF80000022A0000350016
-:106B30000000FF00000000000000FF000000000057
-:106B40000000FF00000000000000FF000000000047
-:106B50000000FF00000000000000FF000000000037
-:106B60000000FF00000000000000FF000000000027
-:106B70000000FF00000000000000FF000000000017
-:106B80000000FF00000000000000FF000000000007
-:106B90000000FF00000000000000FF0000000000F7
-:106BA0000000FF00000000000000FF0000000000E7
-:106BB0000000FF00000000000000FF0000000000D7
-:106BC0000000FF00000000000000FF0000000000C7
-:106BD0000000FF00000000000000FF0000000000B7
-:106BE0000000FF00000000000000FF0000000000A7
-:106BF0000000FF00000000000000FF000000000097
-:106C00000000FF00000000000000FF000000000086
-:106C10000000FF00000000000000FF000000000076
-:106C20000000FF00000000000000FF000000000066
-:106C30000000FF00000000000000FF000000000056
-:106C40000000FF00000000000000FF000000000046
-:106C50000000FF00000000000000FF000000000036
-:106C60000000FF00000000000000FF000000000026
-:106C70000000FF00000000000000FF000000000016
-:106C80000000FF00000000000000FF000000000006
-:106C90000000FF00000000000000FF0000000000F6
-:106CA0000000FF00000000000000FF0000000000E6
-:106CB0000000FF00000000000000FF0000000000D6
-:106CC0000000FF00000000000000FF0000000000C6
-:106CD0000000FF00000000000000FF0000000000B6
-:106CE0000000FF00000000000000FF0000000000A6
-:106CF0000000FF00000000000000FF000000000096
-:106D00000000FF00000000000000FF000000000085
-:106D10000000FF00000000000000FF000000000075
-:106D20000000FF00000000000000FF000000000065
-:106D30000000FF00000000000000FF000000000055
-:106D40000000FF00000000000000FF000000000045
-:106D50000000FF00000000000000FF000000000035
-:106D60000000FF00000000000000FF00000019000C
-:106D70000000000000000000FFFFFFFF0000000017
-:106D800003938700000000000393870000007FF852
-:106D900000007FF800000BA700003500000000FF96
-:106DA000000000FF000000FF000000FF000000FFE7
-:106DB000000000FF000000FF000000FF0000FF00D7
-:106DC000000000000000FF00000000000000FF00C5
-:106DD000000000000000FF00000000000000FF00B5
-:106DE000000000000000FF00000000000000FF00A5
-:106DF000000000000000FF00000000000000FF0095
-:106E0000000000000000FF00000000000000FF0084
-:106E1000000000000000FF00000000000000FF0074
-:106E2000000000000000FF00000000000000FF0064
-:106E3000000000000000FF00000000000000FF0054
-:106E4000000000000000FF00000000000000FF0044
-:106E5000000000000000FF00000000000000FF0034
-:106E6000000000000000FF00000000000000FF0024
-:106E7000000000000000FF00000000000000FF0014
-:106E8000000000000000FF00000000000000FF0004
-:106E9000000000000000FF00000000000000FF00F4
-:106EA000000000000000FF00000000000000FF00E4
-:106EB000000000000000FF00000000000000FF00D4
-:106EC000000000000000FF00000000000000FF00C4
-:106ED000000000000000FF00000000000000FF00B4
-:106EE000000000000000FF00000000000000FF00A4
-:106EF000000000000000FF00000000000000FF0094
-:106F0000000000000000FF00000000000000FF0083
-:106F1000000000000000FF00000000000000FF0073
-:106F2000000000000000FF00000000000000FF0063
-:106F3000000000000000FF00000000000000FF0053
-:106F4000000000000000FF00000000000000FF0043
-:106F5000000000000000FF00000000000000FF0033
-:106F6000000000000000FF00000000000000FF0023
-:106F7000000000000000FF00000000000000FF0013
-:106F8000000000000000FF00000000000000FF0003
-:106F9000000000000000FF00000000000000FF00F3
-:106FA000000000000000FF00000000000000FF00E3
-:106FB000000000000000FF00000000000000FF00D3
-:106FC000000000000000FF00000000000000FF00C3
-:106FD000000000000000FF00000000000000FF00B3
-:106FE000000000000000FF00000000000000FF00A3
-:106FF000000000000000FF0000000000FFFFFFFF96
-:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
-:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
-:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
-:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
-:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
-:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
-:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
-:10707000FFFFFFFFFFFFFFFFFFFFFFFF000000001C
-:10708000000028AD000029180000291900000005A3
-:10709000000000070000FF000FFFFFFF0000FF00DF
-:1070A0000FFFFFFF000000FF0000FF000000FF00D7
-:1070B0000FFFFFFF0000FF000FFFFFFF000000FFBA
-:1070C0000000FF000000FF000FFFFFFF0000FF00B7
-:1070D0000FFFFFFF000000FF0000FF000000FF00A7
-:1070E0000FFFFFFF0000FF000FFFFFFF000000FF8A
-:1070F0000000FF000000FF000FFFFFFF0000FF0087
-:107100000FFFFFFF000000FF0000FF000000FF0076
-:107110000FFFFFFF0000FF000FFFFFFF000000FF59
-:107120000000FF000000FF000FFFFFFF0000FF0056
-:107130000FFFFFFF000000FF0000FF000000FF0046
-:107140000FFFFFFF0000FF000FFFFFFF000000FF29
-:107150000000FF000000FF000FFFFFFF0000FF0026
-:107160000FFFFFFF000000FF0000FF000000FF0016
-:107170000FFFFFFF0000FF000FFFFFFF000000FFF9
-:107180000000FF000000FF000FFFFFFF0000FF00F6
-:107190000FFFFFFF000000FF0000FF000000FF00E6
-:1071A0000FFFFFFF0000FF000FFFFFFF000000FFC9
-:1071B0000000FF000000FF000FFFFFFF0000FF00C6
-:1071C0000FFFFFFF000000FF0000FF000000FF00B6
-:1071D0000FFFFFFF0000FF000FFFFFFF000000FF99
-:1071E0000000FF000000FF000FFFFFFF0000FF0096
-:1071F0000FFFFFFF000000FF0000FF000000FF0086
-:107200000FFFFFFF0000FF000FFFFFFF000000FF68
-:107210000000FF000000FF000FFFFFFF0000FF0065
-:107220000FFFFFFF000000FF0000FF000000FF0055
-:107230000FFFFFFF0000FF000FFFFFFF000000FF38
-:107240000000FF000000FF000FFFFFFF0000FF0035
-:107250000FFFFFFF000000FF0000FF000000FF0025
-:107260000FFFFFFF0000FF000FFFFFFF000000FF08
-:107270000000FF000000FF000FFFFFFF0000FF0005
-:107280000FFFFFFF000000FF0000FF000000FF00F5
-:107290000FFFFFFF0000FF000FFFFFFF000000FFD8
-:1072A0000000FF000000FF000FFFFFFF0000FF00D5
-:1072B0000FFFFFFF000000FF0000FF000000FF00C5
-:1072C0000FFFFFFF0000FF000FFFFFFF000000FFA8
-:1072D0000000FF000000FF000FFFFFFF0000FF00A5
-:1072E0000FFFFFFF000000FF0000FF000000FF0095
-:1072F0000FFFFFFF0000FF000FFFFFFF000000FF78
-:107300000000FF000000FF000FFFFFFF0000FF0074
-:107310000FFFFFFF000000FF0000FF000000FF0064
-:107320000FFFFFFF0000FF000FFFFFFF000000FF47
-:107330000000FF000000FF000FFFFFFF0000FF0044
-:107340000FFFFFFF000000FF0000FF000000FF0034
-:107350000FFFFFFF0000FF000FFFFFFF000000FF17
-:107360000000FF000000FF000FFFFFFF0000FF0014
-:107370000FFFFFFF000000FF0000FF000000FF0004
-:107380000FFFFFFF0000FF000FFFFFFF000000FFE7
-:107390000000FF000000FF000FFFFFFF0000FF00E4
-:1073A0000FFFFFFF000000FF0000FF000000FF00D4
-:1073B0000FFFFFFF0000FF000FFFFFFF000000FFB7
-:1073C0000000FF000000FF000FFFFFFF0000FF00B4
-:1073D0000FFFFFFF000000FF0000FF000000FF00A4
-:1073E0000FFFFFFF0000FF000FFFFFFF000000FF87
-:1073F0000000FF000000FF000FFFFFFF0000FF0084
-:107400000FFFFFFF000000FF0000FF000000FF0073
-:107410000FFFFFFF0000FF000FFFFFFF000000FF56
-:107420000000FF000000FF000FFFFFFF0000FF0053
-:107430000FFFFFFF000000FF0000FF000000FF0043
-:107440000FFFFFFF0000FF000FFFFFFF000000FF26
-:107450000000FF000000FF000FFFFFFF0000FF0023
-:107460000FFFFFFF000000FF0000FF000000FF0013
-:107470000FFFFFFF0000FF000FFFFFFF000000FFF6
-:107480000000FF000000FF000FFFFFFF0000FF00F3
-:107490000FFFFFFF000000FF0000FF000000FF00E3
-:1074A0000FFFFFFF0000FF000FFFFFFF000000FFC6
-:1074B0000000FF000000FF000FFFFFFF0000FF00C3
-:1074C0000FFFFFFF000000FF0000FF000000FF00B3
-:1074D0000FFFFFFF0000FF000FFFFFFF000000FF96
-:1074E0000000FF000000FF000FFFFFFF0000FF0093
-:1074F0000FFFFFFF000000FF0000FF000000FF0083
-:107500000FFFFFFF0000FF000FFFFFFF000000FF65
-:107510000000FF000000FF000FFFFFFF0000FF0062
-:107520000FFFFFFF000000FF0000FF000000FF0052
-:107530000FFFFFFF0000FF000FFFFFFF000000FF35
-:107540000000FF000000FF000FFFFFFF0000FF0032
-:107550000FFFFFFF000000FF0000FF000000FF0022
-:107560000FFFFFFF0000FF000FFFFFFF000000FF05
-:107570000000FF000000FF000FFFFFFF0000FF0002
-:107580000FFFFFFF000000FF0000FF000000FF00F2
-:107590000FFFFFFF0000FF000FFFFFFF000000FFD5
-:1075A0000000FF000000FF000FFFFFFF0000FF00D2
-:1075B0000FFFFFFF000000FF0000FF000000FF00C2
-:1075C0000FFFFFFF0000FF000FFFFFFF000000FFA5
-:1075D0000000FF000000FF000FFFFFFF0000FF00A2
-:1075E0000FFFFFFF000000FF0000FF000000FF0092
-:1075F0000FFFFFFF0000FF000FFFFFFF000000FF75
-:107600000000FF000000FF000FFFFFFF0000FF0071
-:107610000FFFFFFF000000FF0000FF000000FF0061
-:107620000FFFFFFF0000FF000FFFFFFF000000FF44
-:107630000000FF000000FF000FFFFFFF0000FF0041
-:107640000FFFFFFF000000FF0000FF000000FF0031
-:107650000FFFFFFF0000FF000FFFFFFF000000FF14
-:107660000000FF000000FF000FFFFFFF0000FF0011
-:107670000FFFFFFF000000FF0000FF000000FF0001
-:107680000FFFFFFF0000FF000FFFFFFF000000FFE4
-:107690000000FF000000FF000FFFFFFF0000FF00E1
-:1076A0000FFFFFFF000000FF0000FF000000FF00D1
-:1076B0000FFFFFFF0000FF000FFFFFFF000000FFB4
-:1076C0000000FF000000FF000FFFFFFF0000FF00B1
-:1076D0000FFFFFFF000000FF0000FF000000FF00A1
-:1076E0000FFFFFFF0000FF000FFFFFFF000000FF84
-:1076F0000000FF000000FF000FFFFFFF0000FF0081
-:107700000FFFFFFF000000FF0000FF000000FF0070
-:107710000FFFFFFF0000FF000FFFFFFF000000FF53
-:107720000000FF000000FF000FFFFFFF0000FF0050
-:107730000FFFFFFF000000FF0000FF000000FF0040
-:107740000FFFFFFF0000FF000FFFFFFF000000FF23
-:107750000000FF000000FF000FFFFFFF0000FF0020
-:107760000FFFFFFF000000FF0000FF000000FF0010
-:107770000FFFFFFF0000FF000FFFFFFF000000FFF3
-:107780000000FF000000FF000FFFFFFF0000FF00F0
-:107790000FFFFFFF000000FF0000FF000000FF00E0
-:1077A0000FFFFFFF0000FF000FFFFFFF000000FFC3
-:1077B0000000FF000000FF000FFFFFFF0000FF00C0
-:1077C0000FFFFFFF000000FF0000FF000000FF00B0
-:1077D0000FFFFFFF0000FF000FFFFFFF000000FF93
-:1077E0000000FF000000FF000FFFFFFF0000FF0090
-:1077F0000FFFFFFF000000FF0000FF000000FF0080
-:107800000FFFFFFF0000FF000FFFFFFF000000FF62
-:107810000000FF000000FF000FFFFFFF0000FF005F
-:107820000FFFFFFF000000FF0000FF000000FF004F
-:107830000FFFFFFF0000FF000FFFFFFF000000FF32
-:107840000000FF000000FF000FFFFFFF0000FF002F
-:107850000FFFFFFF000000FF0000FF000000FF001F
-:107860000FFFFFFF0000FF000FFFFFFF000000FF02
-:107870000000FF000000FF000FFFFFFF0000FF00FF
-:107880000FFFFFFF000000FF0000FF000000FF00EF
-:107890000FFFFFFF0000FF000FFFFFFF000000FFD2
-:1078A0000000FF000000FF000FFFFFFF0000FF00CF
-:1078B0000FFFFFFF000000FF0000FF000000FF00BF
-:1078C0000FFFFFFF0000FF000FFFFFFF000000FFA2
-:1078D0000000FF000000FF000FFFFFFF0000FF009F
-:1078E0000FFFFFFF000000FF0000FF000000FF008F
-:1078F0000FFFFFFF0000FF000FFFFFFF000000FF72
-:107900000000FF000000FF000FFFFFFF0000FF006E
-:107910000FFFFFFF000000FF0000FF000000FF005E
-:107920000FFFFFFF0000FF000FFFFFFF000000FF41
-:107930000000FF000000FF000FFFFFFF0000FF003E
-:107940000FFFFFFF000000FF0000FF000000FF002E
-:107950000FFFFFFF0000FF000FFFFFFF000000FF11
-:107960000000FF000000FF000FFFFFFF0000FF000E
-:107970000FFFFFFF000000FF0000FF000000FF00FE
-:107980000FFFFFFF0000FF000FFFFFFF000000FFE1
-:107990000000FF000000FF000FFFFFFF0000FF00DE
-:1079A0000FFFFFFF000000FF0000FF000000FF00CE
-:1079B0000FFFFFFF0000FF000FFFFFFF000000FFB1
-:1079C0000000FF000000FF000FFFFFFF0000FF00AE
-:1079D0000FFFFFFF000000FF0000FF000000FF009E
-:1079E0000FFFFFFF0000FF000FFFFFFF000000FF81
-:1079F0000000FF000000FF000FFFFFFF0000FF007E
-:107A00000FFFFFFF000000FF0000FF000000FF006D
-:107A10000FFFFFFF0000FF000FFFFFFF000000FF50
-:107A20000000FF000000FF000FFFFFFF0000FF004D
-:107A30000FFFFFFF000000FF0000FF000000FF003D
-:107A40000FFFFFFF0000FF000FFFFFFF000000FF20
-:107A50000000FF000000FF000FFFFFFF0000FF001D
-:107A60000FFFFFFF000000FF0000FF000000FF000D
-:107A70000FFFFFFF0000FF000FFFFFFF000000FFF0
-:107A80000000FF000000FF000FFFFFFF0000FF00ED
-:107A90000FFFFFFF000000FF0000FF000000FF00DD
-:107AA0000FFFFFFF0000FF000FFFFFFF000000FFC0
-:107AB0000000FF000000FF000FFFFFFF0000FF00BD
-:107AC0000FFFFFFF000000FF0000FF000000FF00AD
-:107AD0000FFFFFFF0000FF000FFFFFFF000000FF90
-:107AE0000000FF000000FF000FFFFFFF0000FF008D
-:107AF0000FFFFFFF000000FF0000FF000000FF007D
-:107B00000FFFFFFF0000FF000FFFFFFF000000FF5F
-:107B10000000FF000000FF000FFFFFFF0000FF005C
-:107B20000FFFFFFF000000FF0000FF000000FF004C
-:107B30000FFFFFFF0000FF000FFFFFFF000000FF2F
-:107B40000000FF000000FF000FFFFFFF0000FF002C
-:107B50000FFFFFFF000000FF0000FF000000FF001C
-:107B60000FFFFFFF0000FF000FFFFFFF000000FFFF
-:107B70000000FF000000FF000FFFFFFF0000FF00FC
-:107B80000FFFFFFF000000FF0000FF000000FF00EC
-:107B90000FFFFFFF0000FF000FFFFFFF000000FFCF
-:107BA0000000FF000000FF000FFFFFFF0000FF00CC
-:107BB0000FFFFFFF000000FF0000FF000000FF00BC
-:107BC0000FFFFFFF0000FF000FFFFFFF000000FF9F
-:107BD0000000FF000000FF000FFFFFFF0000FF009C
-:107BE0000FFFFFFF000000FF0000FF000000FF008C
-:107BF0000FFFFFFF0000FF000FFFFFFF000000FF6F
-:107C00000000FF000000FF000FFFFFFF0000FF006B
-:107C10000FFFFFFF000000FF0000FF000000FF005B
-:107C20000FFFFFFF0000FF000FFFFFFF000000FF3E
-:107C30000000FF000000FF000FFFFFFF0000FF003B
-:107C40000FFFFFFF000000FF0000FF000000FF002B
-:107C50000FFFFFFF0000FF000FFFFFFF000000FF0E
-:107C60000000FF000000FF000FFFFFFF0000FF000B
-:107C70000FFFFFFF000000FF0000FF000000FF00FB
-:107C80000FFFFFFF0000FF000FFFFFFF000000FFDE
-:107C90000000FF000000FF000FFFFFFF0000FF00DB
-:107CA0000FFFFFFF000000FF0000FF000000FF00CB
-:107CB0000FFFFFFF0000FF000FFFFFFF000000FFAE
-:107CC0000000FF000000FF000FFFFFFF0000FF00AB
-:107CD0000FFFFFFF000000FF0000FF000000FF009B
-:107CE0000FFFFFFF0000FF000FFFFFFF000000FF7E
-:107CF0000000FF000000FF000FFFFFFF0000FF007B
-:107D00000FFFFFFF000000FF0000FF000000FF006A
-:107D10000FFFFFFF0000FF000FFFFFFF000000FF4D
-:107D20000000FF000000FF000FFFFFFF0000FF004A
-:107D30000FFFFFFF000000FF0000FF000000FF003A
-:107D40000FFFFFFF0000FF000FFFFFFF000000FF1D
-:107D50000000FF0000001000000020800000310043
-:107D600000004180000052000000628000007300AB
-:107D700000008380000094000000A4800000B50093
-:107D80000000C5800000D6000000E6800000F7007B
-:107D9000000107800001180000012880000139005F
-:107DA0000001498000015A0000016A8000017B0047
-:107DB00000018B8000019C000001AC800001BD002F
-:107DC0000001CD800001DE000001EE800001FF0017
-:107DD00000000F8000007FF800007FF8000005F928
-:107DE0000000350010000000000028AD0000291838
-:107DF0000000291900000005000000060001000134
-:107E000000220006CCCCCCC97058103C0000FF000A
-:107E1000000000000000FF00000000000000FF0064
-:107E2000000000000000FF00000000000000FF0054
-:107E3000000000000000FF00000000000000FF0044
-:107E4000000000000000FF00000000000000FF0034
-:107E5000000000000000FF00000000000000FF0024
-:107E6000000000000000FF00000000000000FF0014
-:107E7000000000000000FF00000000000000FF0004
-:107E8000000000000000FF00000000000000FF00F4
-:107E9000000000000000FF00000000000000FF00E4
-:107EA000000000000000FF00000000000000FF00D4
-:107EB000000000000000FF00000000000000FF00C4
-:107EC000000000000000FF00000000000000FF00B4
-:107ED000000000000000FF00000000000000FF00A4
-:107EE000000000000000FF00000000000000FF0094
-:107EF000000000000000FF00000000000000FF0084
-:107F0000000000000000FF00000000000000FF0073
-:107F1000000000000000FF00000000000000FF0063
-:107F2000000000000000FF00000000000000FF0053
-:107F3000000000000000FF00000000000000FF0043
-:107F4000000000000000FF00000000000000FF0033
-:107F5000000000000000FF00000000000000FF0023
-:107F6000000000000000FF00000000000000FF0013
-:107F7000000000000000FF00000000000000FF0003
-:107F8000000000000000FF00000000000000FF00F3
-:107F9000000000000000FF00000000000000FF00E3
-:107FA000000000000000FF00000000000000FF00D3
-:107FB000000000000000FF00000000000000FF00C3
-:107FC000000000000000FF00000000000000FF00B3
-:107FD000000000000000FF00000000000000FF00A3
-:107FE000000000000000FF00000000000000FF0093
-:107FF000000000000000FF00000000000000FF0083
-:10800000000000000000FF00000000000000FF0072
-:10801000000000000000FF00000000000000FF0062
-:10802000000000000000FF00000000000000FF0052
-:10803000000000000000FF00000000000000FF0042
-:10804000000000000000FF00000000000000000130
-:10805000CCCC0201CCCCCCCCCCCC0201CCCCCCCC8A
-:10806000CCCC0201CCCCCCCCCCCC0201CCCCCCCC7A
-:10807000CCCC0201CCCCCCCCCCCC0201CCCCCCCC6A
-:10808000CCCC0201CCCCCCCCCCCC0201CCCCCCCC5A
-:1080900000000000FFFFFFFF03030303134202027F
-:1080A0005050502070608050020002000604060408
-:1080B000000E0000011600D6002625A0002625A0EF
-:1080C000002625A0002625A000720000012300F351
-:1080D000002625A0002625A0002625A0002625A0F4
-:1080E0000000FFFF000000000000FFFF0000000094
-:1080F0000000FFFF000000000000FFFF0000000084
-:108100000000FFFF000000000000FFFF0000000073
-:108110000000FFFF000000000000FFFF0000000063
-:108120000000FFFF000000000000FFFF0000000053
-:108130000000FFFF000000000000FFFF0000000043
-:108140000000FFFF000000000000FFFF0000000033
-:108150000000FFFF000000000000FFFF0000000023
-:108160000000FFFF000000000000FFFF0000000013
-:108170000000FFFF000000000000FFFF0000000003
-:108180000000FFFF000000000000FFFF00000000F3
-:108190000000FFFF000000000000FFFF00000000E3
-:1081A0000000FFFF000000000000FFFF00000000D3
-:1081B0000000FFFF000000000000FFFF00000000C3
-:1081C0000000FFFF000000000000FFFF00000000B3
-:1081D0000000FFFF000000000000FFFF00000000A3
-:1081E0000000FFFF000000000000FFFF0000000093
-:1081F0000000FFFF000000000000FFFF0000000083
-:108200000000FFFF000000000000FFFF0000000072
-:108210000000FFFF000000000000FFFF0000000062
-:108220000000FFFF000000000000FFFF0000000052
-:108230000000FFFF000000000000FFFF0000000042
-:108240000000FFFF000000000000FFFF0000000032
-:108250000000FFFF000000000000FFFF0000000022
-:108260000000FFFF000000000000FFFF0000000012
-:108270000000FFFF000000000000FFFF0000000002
-:108280000000FFFF000000000000FFFF00000000F2
-:108290000000FFFF000000000000FFFF00000000E2
-:1082A0000000FFFF000000000000FFFF00000000D2
-:1082B0000000FFFF000000000000FFFF00000000C2
-:1082C0000000FFFF000000000000FFFF00000000B2
-:1082D0000000FFFF000000000000FFFF00000000A2
-:1082E000FFFFFFF3318FFFFF0C30C30CC30C30C313
-:1082F000CF3CF300F3CF3CF30000CF3CCDCDCDCD50
-:10830000FFFFFFF130EFFFFF0C30C30CC30C30C395
-:10831000CF3CF300F3CF3CF30001CF3CCDCDCDCD2E
-:10832000FFFFFFF6305FFFFF0C30C30CC30C30C300
-:10833000CF3CF300F3CF3CF30002CF3CCDCDCDCD0D
-:10834000FFFFF4061CBFFFFF0C30C305C30C30C396
-:10835000CF300014F3CF3CF30004CF3CCDCDCDCDD6
-:10836000FFFFFFF2304FFFFF0C30C30CC30C30C3D4
-:10837000CF3CF300F3CF3CF30008CF3CCDCDCDCDC7
-:10838000FFFFFFFA302FFFFF0C30C30CC30C30C3CC
-:10839000CF3CF300F3CF3CF30010CF3CCDCDCDCD9F
-:1083A000FFFFFFF731EFFFFF0C30C30CC30C30C3EE
-:1083B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6F
-:1083C000FFFFFFF5302FFFFF0C30C30CC30C30C391
-:1083D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2F
-:1083E000FFFFFFF3318FFFFF0C30C30CC30C30C312
-:1083F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4F
-:10840000FFFFFFF1310FFFFF0C30C30CC30C30C373
-:10841000CF3CF300F3CF3CF30001CF3CCDCDCDCD2D
-:10842000FFFFFFF6305FFFFF0C30C30CC30C30C3FF
-:10843000CF3CF300F3CF3CF30002CF3CCDCDCDCD0C
-:10844000FFFFF4061CBFFFFF0C30C305C30C30C395
-:10845000CF300014F3CF3CF30004CF3CCDCDCDCDD5
-:10846000FFFFFFF2304FFFFF0C30C30CC30C30C3D3
-:10847000CF3CF300F3CF3CF30008CF3CCDCDCDCDC6
-:10848000FFFFFFFA302FFFFF0C30C30CC30C30C3CB
-:10849000CF3CF300F3CF3CF30010CF3CCDCDCDCD9E
-:1084A000FFFFFFF730EFFFFF0C30C30CC30C30C3EE
-:1084B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6E
-:1084C000FFFFFFF5304FFFFF0C30C30CC30C30C370
-:1084D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2E
-:1084E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C6
-:1084F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD82
-:10850000FFFFFFFF30CFFFFF0C30C30CC30C30C3A5
-:10851000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD60
-:10852000FFFFFFFF30CFFFFF0C30C30CC30C30C385
-:10853000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3F
-:10854000FFFFFFFF30CFFFFF0C30C30CC30C30C365
-:10855000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1D
-:10856000FFFFFFFF30CFFFFF0C30C30CC30C30C345
-:10857000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF9
-:10858000FFFFFFFF30CFFFFF0C30C30CC30C30C325
-:10859000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDD1
-:1085A000FFFFFFFF30CFFFFF0C30C30CC30C30C305
-:1085B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDA1
-:1085C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E5
-:1085D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD61
-:1085E000FFFFFFF3320FFFFF0C30C30CC30C30C38F
-:1085F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4D
-:10860000FFFFFFF1310FFFFF0C30C30CC30C30C371
-:10861000CF3CF300F3CF3CF30001CF3CCDCDCDCD2B
-:10862000FFFFFFF6305FFFFF0C30C30CC30C30C3FD
-:10863000CF3CF300F3CF3CF30002CF3CCDCDCDCD0A
-:10864000FFFFF4061CBFFFFF0C30C305C30C30C393
-:10865000CF300014F3CF3CF30004CF3CCDCDCDCDD3
-:10866000FFFFFFF2304FFFFF0C30C30CC30C30C3D1
-:10867000CF3CF300F3CF3CF30008CF3CCDCDCDCDC4
-:10868000FFFFFF8A042FFFFF0C30C30CC30C30C365
-:10869000CF3CC000F3CF3CF30010CF3CCDCDCDCDCF
-:1086A000FFFFFF9705CFFFFF0C30C30CC30C30C397
-:1086B000CF3CC000F3CF3CF30020CF3CCDCDCDCD9F
-:1086C000FFFFFFF5310FFFFF0C30C30CC30C30C3AD
-:1086D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2C
-:1086E000FFFFFFF3320FFFFF0C30C30CC30C30C38E
-:1086F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4C
-:10870000FFFFFFF1302FFFFF0C30C30CC30C30C351
-:10871000CF3CF300F3CF3CF30001CF3CCDCDCDCD2A
-:10872000FFFFFFF6305FFFFF0C30C30CC30C30C3FC
-:10873000CF3CF300F3CF3CF30002CF3CCDCDCDCD09
-:10874000FFFFFF061CBFFFFF0C30C30CC30C30C380
-:10875000CF3CC014F3CF3CF30004CF3CCDCDCDCD06
-:10876000FFFFFFF2304FFFFF0C30C30CC30C30C3D0
-:10877000CF3CF300F3CF3CF30008CF3CCDCDCDCDC3
-:10878000FFFFFFFA302FFFFF0C30C30CC30C30C3C8
-:10879000CF3CF300F3CF3CF30010CF3CCDCDCDCD9B
-:1087A000FFFFFFF731CFFFFF0C30C30CC30C30C30A
-:1087B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6B
-:1087C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E3
-:1087D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5F
-:1087E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C3
-:1087F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7F
-:10880000FFFFFFFF30CFFFFF0C30C30CC30C30C3A2
-:10881000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5D
-:10882000FFFFFFFF30CFFFFF0C30C30CC30C30C382
-:10883000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3C
-:10884000FFFFFFFF30CFFFFF0C30C30CC30C30C362
-:10885000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1A
-:10886000FFFFFFFF30CFFFFF0C30C30CC30C30C342
-:10887000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF6
-:10888000FFFFFFFF30CFFFFF0C30C30CC30C30C322
-:10889000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCE
-:1088A000FFFFFFFF30CFFFFF0C30C30CC30C30C302
-:1088B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9E
-:1088C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E2
-:1088D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5E
-:1088E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C2
-:1088F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7E
-:10890000FFFFFFFF30CFFFFF0C30C30CC30C30C3A1
-:10891000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5C
-:10892000FFFFFFFF30CFFFFF0C30C30CC30C30C381
-:10893000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3B
-:10894000FFFFFFFF30CFFFFF0C30C30CC30C30C361
-:10895000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD19
-:10896000FFFFFFFF30CFFFFF0C30C30CC30C30C341
-:10897000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF5
-:10898000FFFFFFFF30CFFFFF0C30C30CC30C30C321
-:10899000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCD
-:1089A000FFFFFFFF30CFFFFF0C30C30CC30C30C301
-:1089B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9D
-:1089C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E1
-:1089D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5D
-:1089E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C1
-:1089F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7D
-:108A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3A0
-:108A1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5B
-:108A2000FFFFFFFF30CFFFFF0C30C30CC30C30C380
-:108A3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3A
-:108A4000FFFFFFFF30CFFFFF0C30C30CC30C30C360
-:108A5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD18
-:108A6000FFFFFFFF30CFFFFF0C30C30CC30C30C340
-:108A7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF4
-:108A8000FFFFFFFF30CFFFFF0C30C30CC30C30C320
-:108A9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCC
-:108AA000FFFFFFFF30CFFFFF0C30C30CC30C30C300
-:108AB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9C
-:108AC000FFFFFFFF30CFFFFF0C30C30CC30C30C3E0
-:108AD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5C
-:108AE000000C0000000700C000028130000B81581C
-:108AF0000002021000010230000F024000010330AA
-:108B0000000C0000000800C000028140000B8168DA
-:108B1000000202200001024000070250000202C0D1
-:108B2000001000000008010000028180000B81A8F5
-:108B30000002026000018280000E8298000803801B
-:108B4000001000000001010000028110000901383E
-:108B5000000201C8000101E8000E01F8000002D87F
-:108B6000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45
-:108B700000002000CCCCCCCCCCCCCCCCCCCCCCCC45
-:108B8000CCCCCCCC00002000CCCCCCCCCCCCCCCC35
-:108B9000CCCCCCCCCCCCCCCC04002000CCCCCCCC21
-:108BA000CCCCCCCCCCCCCCCCCCCCCCCC41002000D4
-:108BB00003030303034202025050502070608050B0
-:108BC0001313131313421212505050207060805030
-:108BD000030102000000000000000000000000008F
-:108BE0001F8B080000000000000BFB51CFC0F003FA
-:108BF0008AF7093230288920F8C4E0427606864D8B
-:108C00001C0C0C5BB849D307C32C0C0C0CDA4CE4DD
-:108C1000E905E1DBBC0C0CCF8098810F555C80131B
-:108C200042FF075A20C80AB4830DBBFEE56A08B6A6
-:108C3000A70A0343011033283130E8AB22C445D4DE
-:108C400019182602F99150B1AB403A4C8D7C378F00
-:108C5000E2C1834F1AA3F2971A426807A8F8293491
-:108C6000F96550F9621D087DDA18BBB9253AC4D9F7
-:108C7000BFCB1A953FCD1ABFFA93F6A8FC7568EAE8
-:108C80001741F900B9FAD21DD80300000000000016
-:108C900000000000000000001F8B08000000000022
-:108CA000000BED7D7F7C14D5B5F8999DD9D9D9CD30
-:108CB000EE6608096C20E024861AFAA25D20609016
-:108CC000A843401ABF8FDA15A9A62DED77B5D4E2D7
-:108CD0000F60EBF3097DCF36931092101017B1D5CA
-:108CE00056AB2B0F2DF56B25B5D4D2FAA38B581E9E
-:108CF000B6EFF3BE4869EBD7621B7FE18F228D5A36
-:108D000084B658BFF79C7B273B33D94D36407FFC58
-:108D1000F1C207863B73EEBDE79E73EEB9E79C7B1D
-:108D2000EE8D0A35F0A133003EC09F0B016E0F019E
-:108D30004045EE695C7F7E4F7F03C05188A47BCBAA
-:108D400001D62860022B5B072399FB25C09F3A853B
-:108D50009557C91F8EF75603DC51F2957B117EB5EE
-:108D6000A540803D7BDB00B267B1EFA1E816280586
-:108D70002881D476FCCE7E12F7B3F68E05276720C5
-:108D80009AEBBF027C0033F173957EA884E0E00388
-:108D900099FD73303917C601C860FFAC863ED68E88
-:108DA0007240CE60BFB2BC50FF554DAE1DEF53D6E2
-:108DB00055C86AA23DFC475E529A0C17865F7DB08B
-:108DC0007AFBD37539F8B320527EE89FD87F1450D0
-:108DD000081F7903201D8E86212357176EE7589BA5
-:108DE000B1FD693FD2F133A589B30BC3D974EA69E8
-:108DF000D3E8D9D5A6433600C05036FBEAD9330CA8
-:108E0000E696FAA1F5E68144F4D20C8BF0E90CFB6E
-:108E10003225D588751280D1D78FF491F0FD22CDFF
-:108E2000CC53DF7E4239A38F3D5E46C720F0F680EB
-:108E30008DEF7ED65E10FBCF43AFCBB07F2627C130
-:108E4000DAA1FD5B0D27DF7F682AC0BE30D2DB448C
-:108E50001CC0A7A7202EF8FD51699876049F1583A2
-:108E6000B73312DD4BEA7CB97ED9DFA01172C94954
-:108E70002056E6961BAF5C229D2A905F86F4F29402
-:108E80005CBB2AF22D0FBDAE11F41A989B684D30D1
-:108E90007AAC6D03EB25473D390666260F9D568952
-:108EA0007A767F4A3983CBD33E40BB983F960BBE40
-:108EB00058FCBE7C92F8ADFF1BE1B749C83B409A15
-:108EC0009E03739384A7B7BD7CF38B4DE2C17248B8
-:108ED000C9583E94EF7288DFCF1E7E8DCF33FBFBE7
-:108EE000C3E0A77676A2C661FDAC11F80DCCE5FA19
-:108EF0006FED3435B345227DE4C2F321D45FAC9EDF
-:108F000024097A687D80F257725C01188BF8999079
-:108F10008800ACAB6DD686D33FA02B7FEAB7E5AE19
-:108F200066A8DC7D9875837885C2F9E9F4F0A01E07
-:108F30005D62BDC4DAD182ECFD99D86E79AC6A1657
-:108F4000E0E8E8C72FBE83E4933FC0797B82C1CDC0
-:108F5000127A56A6F6498F401590BE97053CF5C388
-:108F6000E0036C58E674F6C4F775A21F6968BBDEAF
-:108F70007AC7A08CD347E063EB75191EA77606F17C
-:108F80005112442FEF7B3F7BAF874FFDFDA996FD2C
-:108F90004681FED212C9D348F57F23E465887C164A
-:108FA000E0EB7E31CF14E833E1CC9C1CD9F275B2F2
-:108FB0007274CA72C2BAA7F5A2809C5890A279C3F3
-:108FC000C0ACDE69A397973C729275C22F94C6F02D
-:108FD0007128719217868F4272AB737C2AA69753C1
-:108FE0007B12CEF1B3B00551463AB0F15E65D7873A
-:108FF00038CDD710DA398EFA6C7084AF244B42EF3B
-:1090000073B89BC43C3FBFB98AE30FA27D0FBEACCF
-:109010003DCDD99E0C551E39E7786F94B87E63F02C
-:1090200059A2A7B77F45227C6548583E566F8BE80A
-:10903000DFABBFECE70ED1DE06095AFBC27C3E2D4A
-:1090400072AC87CD92D0131A9F675EFDE447B99A40
-:1090500071F27255AC5E5F28E55F77985514BB34AA
-:109060005278DD29F5D9EB413626F8362ABE9F29FC
-:1090700095B9F85E2CBE579D24BE1387E25B949C85
-:109080004D957CA35A276F3A49FC821EFC4E975C93
-:10909000CF1072562CFEF63C182DFEF250FA163503
-:1090A0008F668F12BF2D2749DF0A9F6D2709FC0AA3
-:1090B000CCDBF305BF2DE0F2A1303B1CFD9C62F13F
-:1090C0007B7464FC00CE637FAD172D53217B0D6054
-:1090D00002C0D3ED2F5A9692C3CF04AED747DBFF21
-:1090E0009E91F927FA7FC3326B73FD1F687FC3D54A
-:1090F000BFC2E40785ADD87E7F51ECB8E16DD7B82B
-:109100005F96DE76F57BB2747FB5E8FEFFE81AF76E
-:10911000BBD21FDDE30EB3719F597CBF7F38497905
-:10912000AC16F3A559D25DEB4021FB7D86E0EBDD6B
-:1091300036BC8D6F01F8A902AFCE22E1278AF63F37
-:1091400055247C9F68BF0FE12B46863F53C0A78AFA
-:1091500084977C7C1E165A3FE74A36FDC0E57FACFB
-:10916000D1781CC45CA340F082A17113AB39F5AD7A
-:109170007EC67BAB23A0AF29A7B809C545560324FB
-:10918000306E7217241B7D187FD9F9E57B11EE1D17
-:1091900045D37B75E013927D0F1E8C6CE9ADCEF547
-:1091A000B74A4EB64A284B6BA2FAFD145F49B54A3E
-:1091B000EC596185758CDB1CAB49B45F598EE3308B
-:1091C000748BB5F3FCB2CB7661F9364DD265266A65
-:1091D0005FBD60EAA6CB0D06F7FEAEE7CE40B869EC
-:1091E000E36A3A485FC6259487B171D594CF61CFC1
-:1091F000C58BB97E07E10FB738CACC0EF864EB27F0
-:109200005CDF3F9D74973FD1F289DC7AC2FE5E91AC
-:10921000707FCF8D07B8DF3187EBED6335A9DF7243
-:10922000BC3E546DF1F8028DB7D48AD2F836BCFF3B
-:10923000452A6F68AFD73BD8B83F75CD510BC717DC
-:109240009680C6178DBF97C532B0F1AA8D00B75E64
-:10925000F04CCF2C28EC7F459B16BBF084B87B9C50
-:10926000ADD7E7C75BD5DF9DF00AB3978EED0A9ABD
-:10927000884F74AF9C0956235F07B293B07FAB341D
-:10928000C9F93300B5C8575307E463B399CCC8ECA8
-:109290007D3AA6C5032866D0AF21DD372168257B3E
-:1092A000DFF88E96ACC7F6DFA3F675F1FDD6C69A49
-:1092B000F1181F79BC6DF54485CDF71FB55913150D
-:1092C00066B4EF6CEBA1E7A36D697ABFA3ED4E7AAC
-:1092D000DAE3434D62D8E393B11FB303E5ED989F02
-:1092E00099460CAF8DE7FBC8BFDD20F44897782A7C
-:1092F0004A562EC5EF7198D60B88D7FE79584E374F
-:10930000C0346459BAE929B9948DE3864A988E6DC0
-:10931000EF7AE157FC7B154C0F30F97ACA6CA679CD
-:10932000706BA32F13A8A6E7C5D8DFADA60F98C909
-:10933000039138C3CB41D740CC5DD621B926D2406A
-:10934000FDC77B0DAC7FC36E2CDF3093194A40ED17
-:10935000CB11A223C4B1BF99074CD2E381261FC50C
-:10936000E9D24DBE20D271A47ED248D761E25573B6
-:109370005E77C3CFEE779799C6FBCDA07C70FA3E9F
-:10938000EC637A62F70BE37D5639E141E3674F1EE8
-:10939000478CF9326894DE26E86CD3FD5884EB9D47
-:1093A0008DCC3FC47860217C369E776D6CB8788216
-:1093B000DAD8958073F0994E60BC556DCC88671FE4
-:1093C000BDF7C23F8F46D1CC5CB92B367DCC95F52D
-:1093D000397CBCF0136495E4FF5805FFDE157B4A29
-:1093E000BF32EC6C4FF27ED73E5FEFFCEEA7FE8EF5
-:1093F00055DADFF76B57D6E7A93F897DCFC397A52D
-:1094000032D7C34FBF1068FE1ACAA7A0EFEE175E8F
-:10941000DB7B26D2FB800C280FE97DCD240F287F33
-:10942000A8479E62F2D0CFDA1BDBB2E137CEF91C3F
-:1094300089BBCBE946864003E71B76F55F821F3F79
-:1094400015F1DABD225EBBA72D46CFA7DB0C7A3E15
-:10945000D55647DFB36D712A3FD9D648E5C7DB4CF7
-:109460002AFFA8AD85CA3BDB12547EB4AD959E3B66
-:10947000DA92F4BCAD6D193DD34D7C9E6F684B51B3
-:10948000B9AB6D35D5B3C7FF31A6359CF2F7CF75B3
-:10949000EEF2C5C659B9F9CEFE7E34E62E5FA47F42
-:1094A000D4559EA7B9CB73E10BAEF62E3C7EB5AB7F
-:1094B0007CFE40970B7ECEEBEEF2ECFE075CF0E715
-:1094C0003EE72ECFDCB7C7551EDBE22E47E2875CB6
-:1094D000ED0562EEF256543E5C7F917C74C56AC61F
-:1094E000E495BFC1EFD3839F737D978B949FAB7A35
-:1094F000AA517E5A7C71CB40F9E1F294467D260D4B
-:1095000095139B6F23C9978DC7DF5AAEFE479E8682
-:1095100097A7A2E5A141895B30541EBC7CF7CAC75E
-:10952000103D23E4E57FE4E01F430E607E19EBA4C9
-:10953000F0BA9AC7EE23BB35B015C8EEF3A30D5DA4
-:10954000E95887276793F9F6C1AEF5CD7D4466EDFE
-:1095500004CAA10BF749034A01FF56AC73018D7F82
-:109560000FD6A67D284F1130A6CBD30096FFE096EC
-:109570000957B1F6F709B8AEFBC1923E02306E82D0
-:109580009A44FF2652EBF673F6CA3CEE613FB77D74
-:109590003FD29AA1987F830BEFA1E3E6FB38F2C498
-:1095A00059ADBF66F340DE326BDB5AF60CD5264D63
-:1095B000D9C0FAE544B7A52183E0CCC68CE563AFFA
-:1095C0008255CC6E639FE5B0096887CDF699CFCA06
-:1095D00033C93EDA8F4FDBEED9269E8F8B7978998F
-:1095E000CFFC25D287C1FD6A3838BBDF11F90549A8
-:1095F0004BE271ABF8FD0C457F79DC653FD9E35355
-:10960000948499C8C3AF23B2D8E7D1E3AD3C3EA25E
-:1096100002EA8742F0AFCBEEFD31FB59CAFC0219DA
-:10962000F188F17D2838719971E9D943F150954459
-:1096300012FBC17DEC2DAC9FCE31971B49473F9269
-:1096400022F08999848FAA737C54256E26F2C8D1A2
-:109650009F043E763BF67E9A141B80FE700EBFB5CB
-:10966000C144EB95E8B78E51894E9D11B7FD354B3E
-:10967000E17276967876FAF3DB87001DDC4F1ED711
-:10968000A861FB6B1A9B35B4AF0D886BE87F7786BA
-:1096900017950E676F6F68E3FBE3BDA80F03B84F24
-:1096A000AE8B7DF2183D3BC38FB4E0BC3B5ACFE894
-:1096B000505DB89D48DCBDDF5B5217F2ECEF6608E9
-:1096C000CFA051E6D9079EE0AAE71FA7F8ECFD6EF0
-:1096D0009046C6BF4BE06FC3752B294DCF4BA78C6F
-:1096E000CBEE0EC4DCF8FEF5E8C7EB97F8FBF47C94
-:1096F000789D2EBA15DA9FB59FEA583595E1719697
-:1097000098731E2C11F2A58ED55218C702ADD0F752
-:1097100010AF1F4E50DC4B0B270CA8C9EDD36A3895
-:109720001F1C74BA51D47B41B1F74B5331F4AB25B4
-:1097300023D58AF2A455B179240DAD673F3F27EABE
-:1097400077BFFF2FCFD13CA9D0689E48069B4779B1
-:10975000FA511473A5827151D94C29B86FF3173996
-:10976000996FBEAC10F3595B9830B41ADADAE3792A
-:10977000201E3C36287C1EBF21E0C14A513CAB581C
-:10978000FCFFBD48FCED7E18FEDD02FF1E7C16C20C
-:10979000BF4BE05306463BC5380DAE67012E359CE6
-:1097A000F918AF89FECB849E02F822F1CDFEFE921D
-:1097B000E04BB1E3F96A91E3792DC78FFB900F6C11
-:1097C0003C5B86E34746E0F19AC2D7192D9130629F
-:1097D00035B4D4E795AB1F0B7ABD6BCB95F5C5516E
-:1097E000C9D5C3A2FE48E3F8718E2F3F12E3786C0F
-:1097F00038BEFC50F0252DC3EC5730FE78A65877C4
-:1098000060918B2FC745BBE980CD971B5C7C3932BB
-:109810004ABEEC2D723CC773E33920E4EC17C3F168
-:10982000C501FFBC18FFAFC5F829AE7EBCF39A0E88
-:109830002B4CEBF26F9599B9FE185CBF6897E06E00
-:1098400054CEEDB0EA09EE157C2FB5F07590C1BD90
-:10985000EA84034874A0FDB616F74ACF03F896725F
-:1098600073B368FF77546FE160FB879DF53628F38B
-:109870006C3C06F07DFBBCBFD8706F3BE18E775E21
-:109880006FC31DA5F6128378BCE71CD78F3B9710DA
-:10989000DC907CA45871F6AABF3C49797D651049DB
-:1098A00063DCB14B49519C193721303EB92A10A7CE
-:1098B000149691E2D4158B793D5DD128CE1A80148F
-:1098C000DC89F1B97285F64D3EAE24753FDA11524E
-:1098D000D2A24D57D097B463FB630DCA0BB3F1D935
-:1098E00054F2D91E6A87E183EDDE5112DD8572756F
-:1098F000DB24D540B9DA35E9268AA76F6AE779858E
-:109900009B2E56298EB8F98508ADBF6B95F82711A7
-:10991000DE325503E3C5AB427F796E292BF7B7974B
-:10992000EAD205340EC2DBF241624D83234F91E14E
-:109930001D88539E1DC5E136B5F0FD1EF65389F511
-:1099400057CD3328CE68A01E63DFBB1B55B25F37EF
-:1099500055D5CCC5FE36376A646F6C5E58D34E71F0
-:10996000BCC610C531CBC28684F1F7E8B92A33C032
-:1099700059B9DC68477B33322B0418772AABE2FDF8
-:1099800045CE028A43F9219DA865CF688F0AD9B1D7
-:10999000D8DEA2ECE7D09E690CE832C6FD2D737FBD
-:1099A000FD384A85E33FF27F01E2E39F2803D2DDE1
-:1099B000E66F343D587FD8FCC668A648B86C717015
-:1099C000911E05B2338A804B17099729122ECBE1DD
-:1099D0000270E9B0797E10E7F9851AFBC3F31B1D0D
-:1099E000F986D5DC7E77DA2D7ECFF7D1E68B2EF7A0
-:1099F00047CA695E9E0BE7F27CD1E1EBDB79A223DB
-:109A00008D17C097C3531E197EADB0FB0A7DF78F2B
-:109A1000BB2986FAACBBE2DFC4F366FEAC14EF2BC5
-:109A200057C7CC303EC5F7CA9B5BCD3CFD7DC3CF4D
-:109A3000F5701D2486E54399C0FF10C31DF37EEA2F
-:109A400014061F290CAF96FB86CDBFD414AB99E644
-:109A5000ED421FCDDB002A039C37557C1EFB219570
-:109A6000A8253D63462B1DF3C7DFB487E6CF7F579C
-:109A7000CA2035127FE24847AF9C78E522008E72FB
-:109A8000F5A9CBC9237E91577C9AE5C4DF2317350E
-:109A90007FFCE922E13245C2658B83537BA4A2F4AB
-:109AA0008A9A2E122E53245C96C3AD9DADF2F5DC3E
-:109AB0003AD6817900FEF3345779ED7921F7F739F9
-:109AC0006157B96BA6BBBE3ACB5DBF6B96BBBE7A86
-:109AD0002EAF1F567DF3709FBFD879F2EA49CE931F
-:109AE0003A6D78F848E308F34AD38358BF4C3120E5
-:109AF0005B4EEB5546AC5B79F7C96B543EFFA7F85C
-:109B0000F9BEFD26450FA21FF98F3E4E45E5F8DA56
-:109B1000E31D095F5BFFBE260B7BAB403E38C4F8FC
-:109B2000B9083F84E268E718F3B5E6DF303AFA9FF8
-:109B3000E1F9F0DE765F54930DAAC32F66F619247F
-:109B40001D71988B2B149E87C3F880F6900A891696
-:109B50008C3BAFA9F2913DA284475837AA1C7A2BBF
-:109B60004FBE5E2E2E05269EB3A04F06C0DCD779D1
-:109B7000BFA13810DE11E82767BA1453E8CE0418E5
-:109B80000386C493C1789E0040938EFAAC3C78BAA9
-:109B9000DB5D42ED4AE626F8A06414ED2AFD944709
-:109BA00073DADB1D01DF20DC4DED322FA9FC83B120
-:109BB000B976FDB114BDC4FC59D9914787E7252872
-:109BC0000FC517CF52DEC38428F9656BCB6F70E5E4
-:109BD000897F45AD71C58754BDEB8B12EEE3565DB1
-:109BE0006FF60F23E71D4C5D517CA46AA9D95F571E
-:109BF000186E307F1FF340F3CC832E359941FBDD87
-:109C00009A1CE6FEBC92A27863B75436BDB7210712
-:109C1000A754314DCBF00AC74D0BFDBDEEB1BE3898
-:109C2000DAA90A6CD8279DC3EAC90BE3CEF8A5F7D9
-:109C3000A954296F3AC77387EAB6A7D68C20EF23B9
-:109C4000DA3D6A3C992F2EFAA0CAFD637F28FFF700
-:109C50005742CDDF522B86D2ED47485FF46FC740A5
-:109C60000FC6DBED3C5AA56ACF734887B5150B626A
-:109C7000C38D9739508707F9C258BC2F64EE5067DF
-:109C80000E8BC74E75661EFE858B8B7F03F3D374D8
-:109C9000062A8BF339681F494CDE4383F218874E3E
-:109CA000D457CCFFE8657C0BD5C7612B2BC7E66981
-:109CB0000985D94BB7346C018C5BFB99FD44FE8957
-:109CC000DCC4EDA73A6E0F99EC0F8E23DA34BC5D3D
-:109CD0002D7BCA0754B73DB4A66D2738F3DFBCE728
-:109CE0002DECE7D650F3F3F9E9519C3FBC99C90B31
-:109CF00033EE60539B46CF5BDB747ADED216A3E76C
-:109D0000FA3683F2F33BDBEAA8FC55AC3A1BCF45AD
-:109D1000A57AAA19FD7A625B9F5BCA5E6D46DA522C
-:109D20009C20330FEDE45E2C53BE1F7303B13C89BE
-:109D30007F7FAF2B3D0FE30DBD411B7EED3CD35527
-:109D4000BE73CD5C8417718648F77DF3D0DFDF3CAE
-:109D5000C9CE4333B54F38D6BD9A003FAF42BE2B74
-:109D6000D5EF5883FD0715BBFC3D6A3F570613F13D
-:109D7000096ABCFCD1C00EC2875400EBEFE381EF4F
-:109D80005379F3141EEF87C58B46A0238FEFAF5195
-:109D90000D1EEF5A5C46FB472A939B1AF66AF3188E
-:109DA000817791ED8092E4EB9D38DF5778DE8CB0BF
-:109DB000AE093C469E0F26C5D1ED736BCA2FF2AF9C
-:109DC000D3A7BBDFCDFED1D1456B4A9AD87CB4A5D1
-:109DD0002F8BACFEB19A9C13C07DA4F9FB6859513E
-:109DE00063596E3714D9FFB8809D079924BFC9A65F
-:109DF000B7A273FB6385879FFE72BE6F1714E7538C
-:109E00008AC5FB73AAE847B4030F4DAF1CCECE2A18
-:109E10005FE843636C506F94CD0FB9CA7A539908C9
-:109E2000DAF072B46182AB1CAEAF7195FDFA875D5A
-:109E3000F54F965FADC25EB4E13FE61957B3779C2C
-:109E400045B6FB6269E25F0233314E05752946D79C
-:109E50003B3EF300D13F34385F17749A4D942F2E58
-:109E6000FC8A0B7959B7BF9FD76956B1B2617F9F02
-:109E7000C9BF9BF6F7E9BC6CD9DF3FC2E1D15F6691
-:109E8000E58EEEA99D167E870E8ADF42550A1639A9
-:109E9000F44B787C7317E2377E492666B1F7BDEF45
-:109EA000CB5C6E211D73C2DDA5713FE02753BE164A
-:109EB000C3B8E5BAA90FC480F49E94775FF0D900C7
-:109EC000CF1BAB0C256E4739667A6D00F3050F3D4D
-:109ED000201B7C5D525EC275D167F17C7D15E2FB73
-:109EE0004CB48FEA78DC3A24BE131FAB73F0837C4A
-:109EF000F5943FA2F1F5FDF79864C9C6F3ED52F36E
-:109F00003EEA1732520B9BF755160CE0F92410F677
-:109F1000DF445E15CA13198AF74D62F4C47DF6C991
-:109F20008B07DAFD8CD6C612DD8753A46669DC0781
-:109F3000A4076C7B72ACF4017B7E17F9857AF9CBB0
-:109F400029C0757CEDD4075A912E81EC97C06074BE
-:109F5000FBD749293018BDDF0E70BC024BD2407AC6
-:109F6000BB364D74F6D26BDD20DD332EBAFF4CD4F8
-:109F70008F2579BD413885C19D3D14AE37989EAB84
-:109F8000A21D3785D3D1DBCFD100DF1FF1E261B74E
-:109F9000EB85DF1410FBDB5A86F6397E32F5A61806
-:109FA000C6B7BBA730FED717E6FFA600CFBB324E21
-:109FB0007C99F46FEFA4DB685F735DED16B22B8FB5
-:109FC000327B02F3367BABF3D7EF6EE3793217C205
-:109FD000DD2D358C3FDD07648AD77AE1BE1370DB57
-:109FE000CD5A95DB2F64F2F74A60E6C8F22747B6F0
-:109FF000F279394AB953698AE2BC1BDF89FCF58BD7
-:10A000003273E63A851D40EB6CE5D23438F31E8F8F
-:10A01000097E3D2DF474B08ACB47AFDF929CFC8B58
-:10A02000B1F7731DF50AF1AD903CFC58CC877795DC
-:10A03000782B19014A4ACFE7572BB17FFEF97CC72D
-:10A0400079B04E25A3E9887FDD6D92D3BEFD869958
-:10A050008C6A0E7F3614BBE4E7F3D10F52E279FD30
-:10A06000F5FF659A65DA4CB4B360462D9E5B50AC43
-:10A0700000C2AD57B22DE45FD4FA286EBEAEEA86B8
-:10A08000BDD538EE7A5F1CC1D6543DD582F6C5BA2F
-:10A09000DA4774A4DB2BFAA22A6C27105367D48EFC
-:10A0A000A5FCEF048E3B5CCFDA75F0DBEE3723E4E2
-:10A0B000FC5EDDAC417C993E3853FB1BE883772185
-:10A0C0001EE3C616A3739E7570289D79BE4077D592
-:10A0D000103ACF71D23980749E81EDC6F3C6311823
-:10A0E0009D2F74D119189DCFCED1B9B78AD3B9BBE2
-:10A0F0006E4B4F8D93CE754FEDAD36B07F4EE7076B
-:10A10000357E7E37847476E0E9A57358B2D79FBA5E
-:10A110004EB43FBD72CFE87E29E263BFF769FBC84A
-:10A12000EE0C8F4F7C82F8C0FC6594833BA482EBDD
-:10A13000D227116EA475697D80EF57DEA57139674E
-:10A14000ED5F89FD42B968DF5E6FC57A7899B66BBD
-:10A150001EAE870CEE6AC2434F913F3C0867C1B008
-:10A16000EB28ABB79CDA0F7BDA376154EB316BE746
-:10A17000266A47F3F46FC029ADF3ACDD761A97E297
-:10A1800069F734DB13AC9F8D9AF0375D74F82BDBE5
-:10A1900031B1A4471E94B44BEFD9F250B9D40D5746
-:10A1A000785D4BF3756DA85D4372FB6CF7DEDDE8FF
-:10A1B0009FBDA29BFF07F935DA7960DB8195A1E4A9
-:10A1C000A3482F6607521EA9F58D92CC1A5657F94F
-:10A1D000201DE5FBF0EEF568BC6D0FD5F27520385B
-:10A1E000CA75E98026F204C7301D55CA9EFE446B2D
-:10A1F000BE78C33302CE6B37FF56CC2705121467E7
-:10A20000EB8C5DBEB39FF1CE6C49433E3DBF3494B1
-:10A210007C16E9A3EA29939657112729D46E79C2AF
-:10A22000DAB5B781F4EE803C465418C74D6B8CCB41
-:10A230004519DD0E6914528B639CAD62B13517F57B
-:10A2400058159317841FD7BA4F4AE6DB2717F41E19
-:10A250008B48E4F15FC67D6A5692F2E216368CE0D6
-:10A26000DFF0FC3C663FFC0EC775484D5F32C541D0
-:10A27000779B4F5F9312975E84FAF47CCEA7D251FE
-:10A28000F2E9CFC2AE8685E534F80B4F5C48E77F34
-:10A2900082115F02E3F1417F5A2F73C8D1381F2426
-:10A2A000FB46817F130CECFE00FDBFB08FFCDEDEB1
-:10A2B000F055DFC6FB792C5D8D4F3172FDF6B2F59E
-:10A2C000BECCB1FE78E35683FEB4802FDC2F879B93
-:10A2D000629D4BFBFEB9FB85DC79084CB0EA307F10
-:10A2E0006895CCE3E877947C85F211565B013D508C
-:10A2F0004EEB18D97FEB445E5BB7C86B5B2BF2DA91
-:10A30000FCD6AAED08BF192081F1C9F6F353B4EFCA
-:10A310001F5534BD834E0CA5CEC575225A6ECFCFC6
-:10A32000C7E7A37D3558B6EEEE6C66E38DC6ECF25A
-:10A33000ED347F3BDBB9BEF94CF057F351DF18E247
-:10A340003CD6E6C645A5304C5C325CEFCEA30BD5BF
-:10A35000865C65ADAACC5556CB270CBB7FB10FE30D
-:10A360004515389E7E88239E05F286A70665829352
-:10A37000E5690359CC3B98A3C6B71878CEDA9DCFD0
-:10A38000D913E4F6E08F30303413DD2C21178D7CA7
-:10A390007FB564764D1FEE07C1182E17982FE894ED
-:10A3A000874272F1F7A68FAFE4700CF32F6EE98845
-:10A3B00002E6BBDC32FB97F1AC817AB53F86791AB5
-:10A3C0006B9826E960DF37CEFEA5912FAEDCAF2576
-:10A3D0009705917EE104D95F9186243DFFDEE31A63
-:10A3E000899F7705F93A3755F053417E36E4F8B93D
-:10A3F000AE91F1B32137CFD72969AD187E7E0CFB22
-:10A400009F897AE8F7E4B7AD6FF4B5A01E32A08F4C
-:10A41000F27037D6FB7CD8FEDF8B2E365EE1D94C4E
-:10A420003F129FB2095C1736C6151FEA917F383973
-:10A43000FC4B3FBD2F420E7F984F0E97D9F250B282
-:10A44000AF355FFEDDD4A0E4E2D706E417A74B0BDF
-:10A45000A78BEFEF4297C1F5424BAE40B959165367
-:10A46000C9EF56CA7ABA68DF88AD7BB86F749D6C45
-:10A470001AB8EF04FFE1E7F735E1BAED585FDE0FF8
-:10A4800006793BF2860594FFC186867E192B7F688C
-:10A49000D87DD18C7FC0798F89373FE350D0BDEF15
-:10A4A000F44ED5A252E457A1F6DE6CDBABE3395B88
-:10A4B0003B4FC3FBFD3A1952F9CE2FFAD120263A71
-:10A4C000F4A944879BD95A3B0DE9F1A1F9783EB331
-:10A4D000BBAA631CD931E27CC375DB9ED115079EF4
-:10A4E000D7296CF99B3E743C367DAFC365B2CC5125
-:10A4F0003FB3D755DF5B6FB03D519FD96DC1107B26
-:10A500009A4A6A2FEE3BDBE738D46D73B3B46C160E
-:10A51000C09BF1F194F02EF63CC73B5BD774A1BF12
-:10A520008DF6D7794C4E5EFBAE1CEF605F97DD7DFC
-:10A53000D67C3CE77A08B8BCD8FC7963EB9A71F911
-:10A54000E4A2107F2E0EFD75E46B7AC8235F7D9721
-:10A550009566E1F4CB57A2907C09FA1CEEE3F480F7
-:10A560003BC7E6E553A1F10CF2C9AE27E4CC5BBFD3
-:10A57000503D26578B433351AEB2D139C5C895C033
-:10A58000D7E6DFA9E23B925C69AB6503CF75552B3B
-:10A5900009D29B3DE51D96B8F791F23EE5F4347E75
-:10A5A000BFCC607E3B64D19ED0CA4DB2A343E2FED5
-:10A5B0009E40AD5B6F2A31F7F989586B226BB78BE0
-:10A5C000F14B6DB54AFD0EEE2387211B8C6299EF8E
-:10A5D00097A2FA43BF22007751DC93D5CB1BF7B487
-:10A5E0009F8AC85BC39C5EBAB70D3E3D429E8BBB43
-:10A5F0009FD8E2E1F36CBCF010568C430EBA17AE54
-:10A60000A7C021879F739BB877D4A6BFB9ED4ACA6C
-:10A610002F0F822F4EFE41EC260BFDBE2E319F7B6D
-:10A62000F0399BCEF3EAE4AF197CBFC592AEA638F1
-:10A63000837DFECCEECF3E7766C38DC4FF55389F39
-:10A64000F2CCEF3D21EE8F1DFB4AEAF7E887587FF9
-:10A650000203EFC97CACED38ED575F907D43C6F83F
-:10A66000FE33A1710477C140BF3CCF312F2F10E7DB
-:10A670003900FAE47CE7BDFC56E0299487270F7384
-:10A680007FECC9C3EF901DFEE41F7C1994BB278F9C
-:10A690000F9FFFF098F08B6CB8C7FEC0EDB3C79466
-:10A6A000BE927CF65DAEFF0CF7070FBBE515943E3E
-:10A6B00019E5E5D897F7C9181F78AC4D935E66FA8F
-:10A6C000E77C31CE0B0EF7CBE8378D34AEEF79F85F
-:10A6D0006B8F737B13B747B737BD13C2F8FFF6C74D
-:10A6E000F9788F8A73B285F07DAA8DE7796C7F3C0B
-:10A6F0003F3D9ACFE7FE71B3DF28CF6BD77ACE5BB1
-:10A70000CDD364F739AFD38CDFEE266E77ED56E20A
-:10A71000E193C1C77E5FD2149770BD2B85CCDE0F4D
-:10A72000551339F73BE322A507BFDE7E35E6B75E5A
-:10A730001936A51896EF9226B3B23E41067F0CF368
-:10A7400037DEC9BEC0F05FDB5A42F91B9D0DE5ED57
-:10A75000786E73ECF2DA5DB88FDC8B1115CA5BB8DA
-:10A760006B2DE62174E27F5939B03E7D119D930037
-:10A77000AE0F98456B28E3C4FE469E790EB9FC0ED9
-:10A78000E98340AE5E217AA99E7C90002C1A5E4F30
-:10A790002DE57ACD627F3EA07352EEFCDC312DAA0E
-:10A7A0008B7EA59EF6CF2EE1F23862FEF829F65395
-:10A7B000065B3483D15FADF3E9198487F818CC0FB9
-:10A7C0002C59C80C203C1F10D377F98C91E9BE1688
-:10A7D000A085C7B7FBC039BF9A4BB87D3FE1DADB34
-:10A7E00025F4238EC699144CC3F2F178BE79714BCF
-:10A7F0009BFB3E915B1A1E21BDD809991E5C4FAC94
-:10A80000061FAD67BD75FB7567FD2B4B24911F6659
-:10A81000F31F0C6516DDEB484138A5CE6706A3276C
-:10A82000CF7FC543D791F81F59EAA6FB68F9B21C40
-:10A83000F93F7364FE9F6A3F36DF86CE8F76C1B7DD
-:10A840001B35A0FD9DE1F5FA50BE6DA175AEA42E9D
-:10A850007F5EEE0D2576DCD672E95D0D521077E451
-:10A860007FC9E367B5DE0785FB95CBDDE31B8C3342
-:10A870001A9689FB7FE35919CF7733998E6701CFF9
-:10A88000F198807610337FC85F933DFEDA6D428E7B
-:10A89000343840F5D92CB0745A37785E9A9D877257
-:10A8A000911C8E637CA2470FD3BD48A81F799E0ED2
-:10A8B000CFE72FE528313B600026B37AA14A192C57
-:10A8C0008CEB35097C25267798C77FF08D83E88F40
-:10A8D000841BDCF968CAC192177DE7A09DE6390F99
-:10A8E0007270F972F25F3C7C1E6D7EFFC325229F61
-:10A8F000AD04C2641789FA85F2F46CBBDEA6AF71B1
-:10A90000224279395D0725A247C5E4C47DE87FC1AD
-:10A910002F65E0F99760E23DC6AB7E3693BE0FDD52
-:10A92000374854235FDE3858A27754179317994855
-:10A93000B633F8EA8301F29FAA416FD6B0BF7E8991
-:10A94000F8288DD3282F6BD54FFDF70586C9CBB2DC
-:10A95000F71707CB4A9AF689D7D54ED79CFB979520
-:10A96000A1E4CF4B1CFB9741B19F3874DFFD769279
-:10A97000F3D1EE6F945F76379DEB2F1F0F62FFFDD3
-:10A98000D30BD04E595701AEBCBC7595BCFCEAFA4E
-:10A99000290B701F679DC8BBD337BC73513BE9DBE4
-:10A9A00004C5F95633C1437AC25EBFB84FD2187F8F
-:10A9B000E9307AC34B870DCA3ECA8BFF6678FFC564
-:10A9C00067219FE23E8ABB7DF346BEAF6AC3BDA24C
-:10A9D00037FFA184E6ABDE89FBD0139320F234DD90
-:10A9E000FB1F1370F560E39CC418E467F43863310F
-:10A9F00074A0F8542FE9ABC4F5786DF92363F8F926
-:10AA0000FEF9FA21B2CF65DA872E84AFD71E2F3434
-:10AA10005E7B5FDD5BFFF608BF4FD5BBFFE58DFBBF
-:10AA2000DC87F465703DB8EFF411F6F467F2C6AD5B
-:10AA30005E2DE1F1E84E6341E2F3382EC59CFD2A1C
-:10AA4000A347A63C4A7EA2FFB2FA2BF08A3E1BDE49
-:10AA5000CE5B5384DFE62F4FD1BAA668A656C7C691
-:10AA6000A11D90716681966E277D65DFFF80645D14
-:10AA70007C361F2F8E2B00DCFEC5F3091F38C60D58
-:10AA80003147BC0BF58AF0D34E03BFA787670EE5AD
-:10AA9000EFDC1E9E771E5BC6CF334D54F2F37BFC7A
-:10AAA00012DDC7F7B94E2F9F0BD52FB4BF79FB2D01
-:10AAB000EA02B453A6E8ABF64E62787759A549DCB2
-:10AAC0007739E64FD13D39BDFFEA832D80E31F7E04
-:10AAD0009DEBF4AC738A9EA0FBF4AA52FA749CE638
-:10AAE00085EA7D2DC5FD1CEFFBCF87F97AB329558B
-:10AAF000B609F319CCA753BBFCE857C6B8DF6CFB0B
-:10AB0000D94B43C9CF871DFA68CC7C2E3F5392574F
-:10AB1000D0FC3F5631FC3D0BEB3D789740FEFB5D92
-:10AB20006F8B707CA618AB78BB93868FBBDAF4383A
-:10AB3000DE238BDF8B00E487F8990027187DEF3543
-:10AB4000B87C2806FC14E56CB2E503C3C0EF03ED46
-:10AB5000A877BFE68365F9F0688BF0F935D964A66C
-:10AB6000A7A887F6693A62D0FC1CBF84D3695D351B
-:10AB7000C4C3ECD519D81EEB7FCF1495E492F9BE6F
-:10AB8000742F526035D0BA1DA8838C81FB0ABBBEDE
-:10AB900094457EA9F5100FB27ABBA774D17D2BDD49
-:10ABA0000698786F92FF6636B1F07BAD2F6362BE78
-:10ABB0008975157D5FABF37BFCD6D63603D9B131F1
-:10ABC0005ED60C7EDE65DD5485F0B0EF1F27BB93AB
-:10ABD000AD0FFEFA812C5E5967C0326AC73F9BF306
-:10ABE000B5EACE263A8FB66ECC0374DFBFB51CF83B
-:10ABF0007EA6BDEFAC30B962EF3B97E979E327EF72
-:10AC00008592DF72CA83A2EF2379289407D71DE6C5
-:10AC1000F4BC4DE8B763FE2CDD6FD8BBD647F7B662
-:10AC200078E13F2BE87F77E7A28FD3F5D4629DB11F
-:10AC3000BF1F2A315CF765541D57693C0BE49B41EB
-:10AC40006778DFC3EC24BAE7052F063D931AB8A452
-:10AC5000D2716EE59E781FD945AA6D17D5737BC654
-:10AC60003EDFC8E890FD26FBAE639E3FF303C7B707
-:10AC7000E6B78FBC7E5921FBA8A7C4FC19D2AB4B09
-:10AC8000E4ED7F7DE9227E6F6581BCFD3BC5F8EF79
-:10AC900094ACEA2ED48F93F83D335EB843C25E6421
-:10ACA000F620C9CD3A8BDFC7B58EB93E8FB272CFD1
-:10ACB0008DFC3EBF1ECBC7CF7FD602C54962375D34
-:10ACC000A5E59BAFB61DBD5EDCAF5568DE95A899C6
-:10ACD00064BE75E99F227C5F6D6CA3417E1B51723F
-:10ACE0001C2E279CEEF4C4785E1D5FB7CF007D2E2E
-:10ACF000E6316E5E58534DF77CB275036DE27BAA68
-:10AD000033D9F9289712F4DD8F95948CB59495CFAB
-:10AD1000888F337A1DE7BAF5AA07B278EEFDF627D9
-:10AD200003106864E5F99EDF67E3E40F2AC83AF789
-:10AD3000EF532934BE629FB7327ABDE488370324CB
-:10AD40005B703E85D87A8AF326D894C9D2EFD3B007
-:10AD50008280E3E8D15819F9D21902BC6F36541F2A
-:10AD60000F63DC36D43FB7859EF5895E949FE8EC8F
-:10AD7000AD7ABE73312D916A97DC87EBDCF99A418D
-:10AD800071EE2858A552BE5A30A9E6BDDFF85089A9
-:10AD9000C2ED68D625CEAB1E6B783D7BAA72F1BAA8
-:10ADA0005867F49C7F4C72C14325EC59B5E00DD92E
-:10ADB00071DF66C4EB5F78F9E8299F2A1F7B3D7C31
-:10ADC0000C36713E02E323BF07C4EAA17317860F56
-:10ADD0009CE72EC6476A5CFC508E2B748EF6CEB96B
-:10ADE000F9EFE31C1FE179DD3D25894B2294570BD8
-:10ADF00012E5F70ABD7091BC81EE3162D2C1EF8FCE
-:10AE000067FDDD9F473F8E8F70FF756BC8BC3C525E
-:10AE100051785C8F4985F0E0F50F093FBF783DCB55
-:10AE2000C737C57C2D4871CF2F0DBFEEDBEBF3315B
-:10AE300036B67D686F2B29D23B4ABF019D389F6390
-:10AE4000BE0CAEABDDB145A417EEB1988C4824978B
-:10AE50005086FEADD01350DF1FC4F88B5FCCAB7BA8
-:10AE600056FBE8BED8508542F7D7066E4EB2B510F5
-:10AE7000CF350E6431965F75E702C293AD53372329
-:10AE80009DA3B1BE76D447FEF20CED0BDFADE821F9
-:10AE90005CFF8FA191C8ECB3EF86B777519EBF9945
-:10AEA000C8E29597E81639EFEFCF58EEFED800DAF2
-:10AEB00051EF7436E9646F9F71733F38E72BEB777E
-:10AEC0003DF265625D66AE64E4D647AF3D51C88E23
-:10AED00060EBA8F0CBE675A15F46262C2B3F147ED5
-:10AEE000A40BFDB07B75F3AB11F283F2FB0F4C2E7C
-:10AEF000BE7E3272F1AC98A7B65C0CC647441CF516
-:10AF0000AA46103FC615BF66785FB3D70F38FE0B51
-:10AF10004FDCBBE79B8C1EB23817C734F99E27D88D
-:10AF2000F7A5A696C0F23507CF5631CEFACB093237
-:10AF30009E0146398BA29CBD053E8AFFBC05FBA342
-:10AF4000331CF83C21E60973805EEA77C4173F9F03
-:10AF5000E6655BDF7DE14E77F96A58340EE387578B
-:10AF6000DFEE878C84BF57CAED177F27C2F3C5BFBA
-:10AF700000A92EA4F35A71EFE9F21F9CADA27D74D3
-:10AF8000CD0CBD1AF72F6D3C7E22D6B337991C1B12
-:10AF90000EFBF5DA7046C57CA79777CCB87C0E60BF
-:10AFA0003B99AE09B85E8D81BCEBF4E77ADC788E14
-:10AFB000340E2FDEF679A1427828DBA4BC71AE9F57
-:10AFC0000B7BDAE6E3A9DEBFFE7684EB03FBF7D367
-:10AFD000D97962A7DAEE7BC2AEF6B6BB5CC30BA42E
-:10AFE00001562AE916A926B76F15F4A7CC8968DFA0
-:10AFF000ED9C9BC5DC73075C4F91702DBE61E046F4
-:10B000001ACFAAD03D518C07F5337F3FDF3D3A95EB
-:10B01000A164245A31F43E1D10BF0FE8D06FEC7BC1
-:10B02000EA0716601C2F00CC6FA7A7427240F11DE3
-:10B0300009EDD17416FD80A0A1B8E4A304F74398EC
-:10B040005DBB52D88F2575EEEFDE78CF19512E07F4
-:10B050004DD04FF67D540B6771BD854677FED21DEE
-:10B06000259F253B72C53E3F1D015801C6AD4D0DC4
-:10B07000340F29CE75E3BA33699FF7C60A83EEF918
-:10B0800055206E525D8FDCAD3C2E41C6E1FFAF54C2
-:10B0900006549C6F2BD9FAE17C7F434C365EC9F392
-:10B0A000FB99ECA79F69F5701DD2C1C7CFC5EAAC6B
-:10B0B000EC18E73B69A985EFAB19A58B87F1CB6F3E
-:10B0C00088A9D4CF55EBA694F2B88F5B6F1E11EB15
-:10B0D000D47F3EF41F2AAEBF6F3DF8E2254887EBD0
-:10B0E0001E934163FD1E792802595ABF322AAE5F72
-:10B0F000D7EE90F3DA5598A9447925DB797CF2DA1A
-:10B1000047029985ACFEB58FBE7C0E30FC8E740C68
-:10B11000EC9988F3E0411E3704ABFF9CCBD8FB6B66
-:10B1200015F8DFF9ECA62BA2DC0F38FCC312BA7FAE
-:10B1300054DAB6EBB3D46EDF15FE80637FED92A8D0
-:10B14000DF86E371CE6F4B992979F6DFECB8FAE12F
-:10B150006F4B1CBF9D7EBA8FF5DA6DF7A94986C784
-:10B16000CA6D6F933E99B7FD3B51A4C3CA9DEE7D56
-:10B17000B6EBB6BFDF857924D7C930B010E5593EAC
-:10B1800041E5A3A6362093DEE7E7A557104B18DC70
-:10B19000F75E5BF06BF6FDCD980C41A67ADFDCF72D
-:10B1A000AAFA189693E1147AB02B77BAF5DECA6D35
-:10B1B0002F535E83EE8381AA39B8BFEF966B2F3C85
-:10B1C0009B3F2ADA212BFBD6BD2D33BDB172C75B65
-:10B1D000CFA3FE58E9D19F6FE27F2A87C6A1DBA2E9
-:10B1E0009E7B66B61597FF70DD778EDE63B17E0FAE
-:10B1F0003FF2BB7B304FFEFABFBC7BCFBFA3BDF09D
-:10B20000645047FDBFF2C15F44C1218F5F8F727BE5
-:10B21000EBC824B02A19DC91FF17C8E0FD57479E00
-:10B22000786D329E733BF2DD3F8E3318FC8D4F5CA0
-:10B2300044F7EBDFF8FD79E387B3C7515E330127AD
-:10B240005E197E5E6CA7C48D97C7C5D3C38FC3DF5D
-:10B250003DA6A25DFB9E0403B8CEADE87B5F457FB3
-:10B26000648F0903489FDD3B5EDEF36FACFC16E3A1
-:10B270004F200F7FD8F827FA68FD666A923D57EC99
-:10B28000787901E2BB1206683D1DC2CF038C9F0D89
-:10B29000397E7ABF1F85132AC663573EC4F8770EDE
-:10B2A000F291F1EF9CA1FC7B0BFF337B28FF7E101A
-:10B2B00075E7091D85EBEFADC48DDA1D63F3E6314B
-:10B2C000E4F61186BFCFC4D60723D17799C4F1EA3B
-:10B2D0008C9AFF19C579F548C9207F17227FBF7363
-:10B2E00074323A39AFFB073E8B74187822A0E3EF33
-:10B2F0008FB8F6895FD13C3BF2FD675583F66D2030
-:10B300002ACD626518FCD90FACBC82C7B661F9D6EC
-:10B310003F2F789ED55F8EBF204327BE51790F9B6C
-:10B3200077C487CCA52D06AE9B990A1AF78A0C9F85
-:10B330000F2B32BB16E3BD125EBA4BA5F6BD9E398C
-:10B340007EE27D4F2B76BCB800E5AE103FEDF1EB11
-:10B3500038FE73D9F7ADEEF9EA855FC1E627AD5344
-:10B360005EFE6676FD373E8FDC1750F07CC51171AE
-:10B37000DEDBCBF71CFDC5F9F751EE33FDD93BBF42
-:10B38000ED7D2641A7C2F2C1E7F948E31B2DFDDEA2
-:10B39000881ADCEFF6D0F1F089FCFA7F7C295FB7E0
-:10B3A0005740BA054D67AFBDA240D29A589DC3F72A
-:10B3B00030DA170CDFC30FCA14F7E9EADB4D7ADC89
-:10B3C000AB2F561488BFD6D9FDEDDC750EEAB5C398
-:10B3D0004FFD90E473C5432FAAE877ECD9F63DB54D
-:10B3E000BF3E371F707DC838E87DF8E15DE7707DAE
-:10B3F000903FAE3553B4BFF27177FB2B1F7ADBD58C
-:10B40000FE75561FD90B23F5F3A6625E81E37D73AB
-:10B410009F9FEE137CB34FCE1BE79E50EA77D9C1B6
-:10B420005DCF2EF8359E676DD81FA27B1477749878
-:10B43000E36F41FB6DBF5FEC1F9ABF43BB74C7B3A3
-:10B440002103EDB41DFB2FA77C1EBBBD1F78E8793F
-:10B45000EE016B5E84B5776E7FA201F345BC7AA3E3
-:10B46000F120F3F71C7270E3B32DE351EFA37F6C6F
-:10B47000A0E3ADC4E91C951C5D4079E2B2EED38334
-:10B4800079D76FDE9E3F9CA0FD1C3F134CE7BDECBF
-:10B49000179EF8BFE4BF77C5F3C7FBEF2AB5F7BD2A
-:10B4A000F9EF77B2DF6F90B8DC58CFF07D8E42F3C2
-:10B4B0006B5B5B2C5ECB4879575B631CF77396978D
-:10B4C000F2F8C7D4572C1F9E0D99DD6F4CC7F14F72
-:10B4D000843EC0F3FA3BDA74821FE4FF4266519760
-:10B4E000E37DF3104738EC17FDB5D1F67B73A17EF1
-:10B4F000EBFB882EC5F4AB9D44BFEB4BF979E953C8
-:10B50000E9377C127406DC1D2A62BCDE3C296FFF21
-:10B51000EA349EF7E5ED6F4929B733EDFD039A7ADA
-:10B52000C3C4D5FCA29DCF941A2E7902254BF74FA8
-:10B53000E7F22A32527703EECB0D9E174E688EF358
-:10B54000C2EC3B9D175E63F23C56568FE6418F88F6
-:10B550004FE03EE5550E7C9F15FA2350958AA1FDDC
-:10B56000D58DFB0D79F4D8F342CEBB23CD943FB2F9
-:10B570004B9F5EDA3FCCBAA1ACBE6B86F35CB1A246
-:10B580006725D7FEB0F932DD8355A8BE77DFD0C678
-:10B59000BF7BD797A006F35CCB13D09107CF3E219A
-:10B5A000C708578D70B124B43BE0D4181FA75DEED7
-:10B5B0007E9FDF73FBFCAD07BB515F16A2D30EC1AC
-:10B5C000CF6731116426B96F1AE663F6447CA4276D
-:10B5D0007B82F9EFA3FF45CE2EA0FA2A9E5FA478C6
-:10B5E000EB3EF21B8D132F9878BFD1ADF52AED0BF2
-:10B5F000459AF653F9A8E923EBBF107DECFB08064A
-:10B60000CB05E24F8D3AE7EF6EF311CA6FBDE16CE7
-:10B61000D5182E9F22B47A5A1CCFB36BABE7C43136
-:10B620003F2254C77F9FC2C6F3793C6D6301F998EE
-:10B63000A573F958FF453B2E992539D938CD17C444
-:10B64000E7FF075094EC5E00800000001F8B0800AD
-:10B6500000000000000BED7D0B5C14D7B9F899DDFC
-:10B66000D9D92730C002CBF21A10140D268B226ACA
-:10B6700035664134F8885915A326185763521201CC
-:10B6800037D636B4B5611010C447486349DADA7664
-:10B69000A5D892366D31A58D491F77D5E8B58FDBDA
-:10B6A000A2318937571B34DE5C494D2F7DA4F5DE6E
-:10B6B0006BEBFF7CDF996167965D3069DA5FEFFFC6
-:10B6C00077C92F999C39E77CE73BDFF9DEE7CCD9D6
-:10B6D000A3DE6909830E426EC0DF1DA39FE6862F9D
-:10B6E0004EAF981E2EB7E5C473FE224276E63C4E5E
-:10B6F00006E9D37CBD91F8687F334FBC7DF499E8AF
-:10B700002547139CB4EC9D986BCEA54F0749379401
-:10B71000D07E6513B91DB9A3E11FCDFA84EB12EDFC
-:10B7200097E625E9F06C2B13D20D1A7C3A3F1320D3
-:10B730003E3A4E6B99B016F034873E49A4384DBD61
-:10B74000682064067D5FDDE9F5D276F42FDD47EBF6
-:10B75000094FD25768DB71644D5FD1E8F1F78B1C5C
-:10B76000212984EC56EAF7CD7EFB990728FEA257E3
-:10B770002A365230FB8E0E91BCA9B41C1AF27230DC
-:10B780002F27996625A3E140BB5CDA2EDEE5271B57
-:10B7900000CFCC41E2A7E3C7170E1298BF4D22920B
-:10B7A000414238887FC2AC6122D3760973075DF2CB
-:10B7B000540D9C3F1BA3E27923C18078DA1A4A3CDE
-:10B7C000F9C984581AE679F2E9BAC4F10344A470BD
-:10B7D000E22446FFC87E6F2530FAA874E92C9B98B6
-:10B7E000E08F065F5DDFC653A9BC49532EEB5C03B7
-:10B7F000F43739FD32CC3F7E16A38B5A1F2F0D1222
-:10B800002F1D379EB0799212E23D441F712532817F
-:10B8100071E8905EED7C362AF4DE28B2F9C09F37DD
-:10B8200015DB11425FC579170E196F85324F2E1542
-:10B83000B2FA1BB90417F49245291B479763CD67E9
-:10B84000BCE7AE46422E69E66BC9A4F357E1D27F4E
-:10B850003B4D241DE8FB41E926B806911FD4F701B2
-:10B8600065FE26E720D26714FD8A18FDEC458C7E24
-:10B87000F608FAED52FAEFFA07A3DF089D38C31A6B
-:10B88000E0C3483AAAEDE78DE02DE393F623E423E5
-:10B89000505E5609F2DB6965E5FDE25D9572119334
-:10B8A000AB71E485103721A59D37DAA0BD5B14117B
-:10B8B000AE7913D5070E4DD9AFEA0736AE23D7536D
-:10B8C00049283F935C03394449DA3E5776C17A757B
-:10B8D000A0A484E1BF2A4EC0F66D9260E06EA3CFB3
-:10B8E000530BD20885DB6CE9B4C07CDB4D9D08A707
-:10B8F00039CB207647D16FC794F91A1BECD37BA6BE
-:10B90000C7A6A35120FE6872FFA6D2BFF9E8E74F91
-:10B9100019297FF092205929BE20F46FA9EB9B478B
-:10B92000FB93BE81DC5C18271EC7712878390A0C8E
-:10B93000A429777C3CBFA5F015DF601D134F1EF0D6
-:10B940008CA267543C5B004F676C3CED59E5C8A77F
-:10B950007C8303C7F99128A17E729802968D747E2C
-:10B960008EA604A9893E77F181F66A780E98884CF4
-:10B970009B9888F75439C59B9F3A8D100AA7F5E22A
-:10B980004CCB04E0FD864EE2D3E8F94D36FF05913D
-:10B99000C2E3453FF1533C7947C00B68F42A7CA0D1
-:10B9A000AE1B294C2264361DCFCF4F077D6AF70BA3
-:10B9B000F854E1A87C623779895804700CDE207D48
-:10B9C0005A00D8EC70BB8F2432BA35CF0DF908D8A5
-:10B9D000B9629E809D6B33794F6DA0E50E3A9F6EE4
-:10B9E000FA6C51F846EDE74E4C647CA88C6F2355F9
-:10B9F0000921806D7CCEE51FC31EDB806EB47DC344
-:10BA0000F9DCEFBCACD295FEFB3F629CF3ED5B90A2
-:10BA100077D3419EDF2345AB0D86D870FED4287DB9
-:10BA2000E7658DBE6A20CC7E1022A52D9F1ABBDF54
-:10BA3000EE46323DBF205CDEC3072C409F36C7D6A2
-:10BA400053B9749EB2C7E02990004C898E4E914F35
-:10BA5000429A70DD4DC403CC4B9A33CB4F954BB01B
-:10BA6000BE2B5C8F43B5D1C1535B4B4C1349D008FF
-:10BA700074919C3AB9DC64637C13B9CED6113A1E3A
-:10BA800018938E56454E22E9989FF8BF938E2265F3
-:10BA900027E4D7B8150921E8779CFA49747C92A964
-:10BAA000973FB59FCAEF91F3AFF85F3EFF483E194D
-:10BAB000DD5E56ED267F9436CDF093600787659F57
-:10BAC0002515BB5218543E2DA126304D59D57DE980
-:10BAD0002708D8E716F16D0BAA2ECF8DE4B1E0F35D
-:10BAE000E46D959EC6F0785AFA18C0EE9C32050FA8
-:10BAF00071613AC589F7BB8E920F4EA7B6CCE7C5E8
-:10BB00000D1AFB71592CDF9E48E9B213FCDA28723A
-:10BB1000B03EB15C4EA4780986E8FA7C3FE835F483
-:10BB20001B457E011DE78E613D9D6E57E8342FED6C
-:10BB3000ED4FC334A996E40955C8E53E4F05D0AD95
-:10BB4000628D0FD8820819D76FF1233F54884017B0
-:10BB50004E9E64B861BF79FAC5A2978323BE687808
-:10BB60007F455CF1259897A388D24DE37F50411023
-:10BB7000DFB66BD6C5E11C87AFD8BA1DBF90669003
-:10BB800069D336972108F18C8904DA81EEE4AC910F
-:10BB9000809F961A4AC77AB32B2F08F62E35642554
-:10BBA0005E8C13C4A095B6EF5A7B8F07F5D3B539D9
-:10BBB0002444F906751965323ED31B027F9A17A5F6
-:10BBC00032A304E33C6681F8A6CDB52281307F9B89
-:10BBD00044D35F7589FE17615DF96BF3109EC1E276
-:10BBE000453FF166E7F3F4CA78027E80F53C1734EE
-:10BBF000535C9E5C39AF7D90CEC742E23ACDF4D91A
-:10BC0000CCCB21B063F279AB04F4DE5A20DF69A01B
-:10BC1000CFB25F590B79FABE9DB379800EED0574F2
-:10BC2000C9299C3F7DDE1E24B4BC73E5B2E10480CB
-:10BC3000D36394A07EFF8DC06DE04F59AE3F81F17C
-:10BC4000A145890F091F9809EB67FD807A6237DFEC
-:10BC500089FCBF2B7F9A45EB8FA7DBFCE7812E6A1F
-:10BC6000D9EAA2FA6D3AF2D3A541CA4F0699233711
-:10BC7000287F5A1CDB5C2724982F7DAFF2476EB8D3
-:10BC80005D586EF56527A535F89994C316815FD97F
-:10BC900006FA06FD562273504E67F5BF7DF2EE455B
-:10BCA000E087B659D5FAE58BBCDAB2FC3FA7B0BF46
-:10BCB000E2F7162525ED82F6CE0C1260F4F19155CF
-:10BCC0001A7F464AE2510E7B12BD7F4C9C319A2F5F
-:10BCD000DBF3195F1EBFD05699077C4AF9D22C01BD
-:10BCE0001FEED2C5C9EA53E5C3B67CC667B1E86E9C
-:10BCF000BA564C421A3FD0E4EC447EB4387DE84753
-:10BD000047B6BF2B99E90B95FF2D2E82F26091FC6F
-:10BD10009F7F10E5C3E101F133E7070847F9C42429
-:10BD2000B27878BC79C4C24FE5FFB6FC3C19F8F58F
-:10BD30003D913A1263B4375D2BC1F9D4257A7392E1
-:10BD400034F1873387D23DCA7CBE98C4E6D3EAABD0
-:10BD5000F63D48E17A6B2419E5C6453C1D609728FD
-:10BD6000FB83DF49FDCD5B9252B4740A307954E015
-:10BD7000CB5CE0A809E4DC49FBD1B72DE487322C89
-:10BD8000BDC919D4C9F7BE647F4992867F7991C530
-:10BD9000870B8C0E03F900F47982C665A14984EC07
-:10BDA0006D14F1B9A7D185CFF646099F1D8D5E129E
-:10BDB00032D3F0875C3BF700F8D90E1BE2371E5FE9
-:10BDC000B4367AB07F4BE32C068753F9BC7017F07A
-:10BDD000B5CDA0CAC9AD584E30AAF525BB30BEE3DB
-:10BDE00058FDD6A4DB514EE87C50EFB58F33AE3111
-:10BDF000588AEBF7FEE12BFA5BA1DF13B77FA23283
-:10BE00000FF8EF7523D1E63146F14B888D77B3F00B
-:10BE1000DB330DA84F9FB87DE7A95CF05B5FA3F013
-:10BE2000C7E2C74E063F263C15DFA3BB105F335D5C
-:10BE30006F2B85671699BE8F250F91F3A54F82F260
-:10BE4000E124A8A79F38BA961C07F9A4C35A4590C5
-:10BE5000539F17F25D420BA5B107ECAD2FF455B01F
-:10BE6000B734D03944CB822237D4ECCBC7291CC19C
-:10BE70006B211DB4DFD1DBEF21D0AFED650BC589A0
-:10BE8000DA87E43CE4776B411569A6ED76565A896A
-:10BE900091BE4F98B78600BC9DBFB022FCDC539387
-:10BEA000515E77894C8EC6D5432E030969EDB8C51E
-:10BEB000162EE781BEDC447C5351AEBF90A4D18FD7
-:10BEC000D44E7E19CA02A990090776F8210FF343D0
-:10BED000587D4FA2EF206BEFC3FE61BF304044900E
-:10BEE000D7B3C66007C49BC65A74FA161A0F580611
-:10BEF00051AEBDCBD24B09713014C82E4F886403AC
-:10BF00005DD28DD417A32F3C020951BBD149FF014B
-:10BF1000FCF8F343E7C9AD84A4AD1174F3E0CFDBC3
-:10BF20002F1A6E05FC587BD50EF1E7EBEAA03D4FCA
-:10BF300034EDC13E19AB13C68A6722FDF81F2529CF
-:10BF40007EBC9D6481DD6B693C42DE3285E1F0118F
-:10BF50007925F5A9FAF39B930D7AFF4762FCFD1250
-:10BF60008DD3811F5B5F3592EE28FCFD87A45C9D1D
-:10BF7000BF9BEE3784E747FF7DF982B9BC4BC79F73
-:10BF800063AF7F468DBE7F56C0A6A3634E4392AE7D
-:10BF90009C2BBB75ED27B4E7E9EA0B3AA7E8EA2743
-:10BFA0003D334D579E1CFC88AEFD2DBDE5BAF2D445
-:10BFB000BEC5BAF6B71D59A12B1787EED5B59F7E22
-:10BFC0006AA3AE7EC6C023BAFA99E7B6EACAB30737
-:10BFD0003FA56BEFF28BC78E807C527E34527AED98
-:10BFE0004A979F01FB39D84CFDB879CC3F067B4B73
-:10BFF0003289E21F53C3940A7CC5FE5AC00E809E4C
-:10C00000DFF3E9D067D04E1A3C20BF7CFE42EF46FA
-:10C01000E8D7221A884BA347A48504DE97EF49C4CA
-:10C02000F7DE9226940F819A0D6B3CD86DFD7A1045
-:10C03000E376D207F8BDCEF0E34539AA7E1232F599
-:10C04000FC6F26F725F8C6F0FB4C92BEFDFBE5FF22
-:10C05000AC64CAFFE0706451FE378EDF5FE5FB47DA
-:10C060000CDE09C92C5F5E71D6A98B7B90AE237163
-:10C070008F85B4803895550F679C60CD95F8C66C58
-:10C08000B871CBCDC73791F2459F94E6749D5C4C57
-:10C090005FABFEFD687B385DE79F453E9BE31F413C
-:10C0A0007D47F5E2EDC93ABDE8F32643DCC77B5195
-:10C0B0002FAAEF737BA7A05E6E17999FD22651B966
-:10C0C0001C835E917AF9F34912D39F31F4B340F5A2
-:10C0D0002C18DC9D2BEF6F07BA79B711B44BD4063F
-:10C0E000A19E8D844FFDAA7B006FC1C5FC29351E22
-:10C0F00052E32D0BD51F105F592482F432537AD9A5
-:10C10000D13F7A0CFD4B3A0F09FC23B393FA9F60A1
-:10C11000EFA9FFC9FCCD0FD7BFCC56E63D4217C5EE
-:10C120005EF6D8BCB5C929B1E1FF20C67ED4CB49A3
-:10C130006ADCFDBF93FFE6264B887F241FAA7C663E
-:10C1400006A6A3E3BD27B175A7D38AE7D4FD0B09E3
-:10C15000FEE3477E3931EB8C3C1FD6CDEFF09AA938
-:10C160005DDD376B05F61326F004F44CDCE086A5A4
-:10C1700060274909D31332FD07F8CD56A4D71B9683
-:10C18000083B2A803D8E1F6D7755FDA0C6E7E3E989
-:10C19000976755FD3293CCD4EA975871B8AA5F548B
-:10C1A0003ADC71BD5144BFE33AAD57FD090AC7946B
-:10C1B000C5FB20CF2C7888F76014F9FB27C52EEF3C
-:10C1C0003D66C5F8DBB146C038CBED0995019FBA95
-:10C1D00003C403F4993518227E0AFF0527E34FB7FD
-:10C1E00027C881FFEABE1CE400CF2E13CB0BB9B7E2
-:10C1F00005396DDEE8DF93593EFB4F171EF3C0BAD9
-:10C2000097E738504E3FF620417B3DE0DAD859069B
-:10C21000E3CE221E334E97276E289F3307519F7817
-:10C2200006BD024BC1C97174E82B8D64DA261ABFB2
-:10C23000BFD368C1E7D546119FF3730E1CBD83C2FF
-:10C24000DD9A6BC37C416B9E0DC769CB16900FFFC7
-:10C2500098F5480EF805BF697461FBF6C703859031
-:10C260004F683BC6F68332BCD3711F14A9E6027C2B
-:10C27000426C7F870FB860DF37E3F84FB05D9BC932
-:10C28000FFAF1B283EF25AC17348627480F9B6585A
-:10C29000D9FCCDF680279196CD13C8FAE5D1E451AB
-:10C2A000A107E524A3900A7940C6A7C22CA909F2E8
-:10C2B00021542BF451F488A935C8C1BE077958948C
-:10C2C000202F9469091EA5311FC9AC113DCD04DA98
-:10C2D000136FD0115E0F9395F80E3BA05D887B9491
-:10C2E0008EDBEF64FB13EE736C7D7E7FFECEA35975
-:10C2F00024B61CEF69AC3C53A1C9BB3A48F4FDDF3E
-:10C300007373CAFF027A087D045CD79963DAC19B14
-:10C3100085EB75323D75FCC2A434F08B1BF8E8FE4A
-:10C32000A45154D7494A8378796B819496E8D0C256
-:10C3300061FAC278EC455C2F7B5110CF17347FEF48
-:10C34000F5FA4F53FAFE8E7684BCD4CB173E8A7131
-:10C35000E2BB49D213105FC93F351258CF77BF3FB8
-:10C36000F32449183DEEAF1B4F25F19ABCD1BBDF3A
-:10C370003E5D6AA2F0DF7DFE74298FCA26A8D353E2
-:10C3800075375E29853C95D0F07BF7658AAF5C4EAA
-:10C390000A0350A68E32C69B72DD92D01874EB4A07
-:10C3A0007DE851C80B069B1D2247FDB2A7ED7F110A
-:10C3B00080EF1A007FFADC6219DEC9D125FEEFAEEC
-:10C3C000B71757D078722B27CB0E0EE8269B217E0D
-:10C3D00020E7CD1EE09BAD05CC2E6E7D580CCAA08B
-:10C3E000AF42012FA6852CAFB82F537D6BFD79107E
-:10C3F000F6FA490BE79B1F0779BAA904F97ACED55B
-:10C40000400EEC1F2712210FF8D06430229CE10B64
-:10C41000F66037EAD9C04CD0374D171E9B04EBF5B8
-:10C42000FB64762E40CDAFA51A024F56E7427ECD73
-:10C4300083F9B5DD7C1FEE93C59AAFDDC5F60FF825
-:10C44000F944898F7FDB119A1BE60755BE22FBED6D
-:10C450006F249E7CCA5F2F355A3C30EE671B457CAB
-:10C460001E6974E1F38946099FDF6F2CC4767B1B3C
-:10C470003D58DEDD380BCBAD26B2DEA7E1B34F3839
-:10C48000D93C5627947DC2499FFD14EE65DAAE97DC
-:10C49000F687E79CB341631CA5C79C2B542F4A50D9
-:10C4A000DFEEB94CE17D91C283E7E87A4B31BC2FD6
-:10C4B0000DF685044ABFD222F6BEB7B157E977041C
-:10C4C000E1D27AA47FE955566FAF6570EC57D4F688
-:10C4D00085C5CA38C5D09E8E5BACF48B848BEF29A2
-:10C4E000DCE268F844B6A7DEBC91942AFB1410D7AE
-:10C4F00099FA38F067648E840EC17EC6F9A7CBC066
-:10C500002EEC29267906DAC894D2CF41B9B78188B2
-:10C51000C644420AD3A7759401FF98BCF85EDECBEF
-:10C52000070FE5A21D42B8AA1DCAA80D79817FE2B6
-:10C530003D24CF584CD741BA84F686D035B6CFA12A
-:10C540004353F1B9A4B1B337E87FE0BC01AE0BEDC2
-:10C550009F5EABAF1FAF3DB52711F5D1F9EE833E1E
-:10C56000BFD8A83FE7D15547B538D51B5D8A1F76A0
-:10C5700000EA61BDEA4A133642F9D187D2416E7FA3
-:10C580004F5C1CECBB8FF48BF0DB0E349E4AAD2865
-:10C590006078037D32B78907B5FE6CA64CF9552348
-:10C5A000077B037C6537E611FCE92B34F14FABC9FF
-:10C5B0009F4E8597FCF6A9D717817E00BB0C7AFAAF
-:10C5C0002357981D1FB1DF57997E54FD064159AF7F
-:10C5D000CF95FC2E04722F833D02FBE4F19372DAB7
-:10C5E0003F658681033B448AF5EF9D02C3CBED0A8C
-:10C5F00072504E76FA5E06F9E1939E21C0477FE8BD
-:10C60000374BC06F7B8FAD2D04FF790B8997ACF44E
-:10C61000BDFB871705C0A3D5302810AACF86F66FBB
-:10C620005BCC537FA75550F4243838741D5B5315E9
-:10C63000BD20FFB1A302FC0D837F08B67AD5F65D5D
-:10C6400036FFA350A67F5E0BB5DFFBADAA9E0D742F
-:10C6500078298FED37B1F2D0FE2D1D329669FB623D
-:10C66000566E4987FD296FBA81D22BBEA9AEE3541D
-:10C670001694D5F6751D72265D4BC59E12873F1721
-:10C68000F4DE4859A4E5384D9967656261CFBDC7AE
-:10C69000FE4B807DD3D6D4E1931940CF1F737DA08C
-:10C6A0005FEB8E3F7B14CAF53544823C9CFBC8414E
-:10C6B0005C87678D6543CE1490E353223AE4F0A77C
-:10C6C000AE0BF54727BB08E68D852017CC033FADA1
-:10C6D000A8D3807EDA76EA5B1703BDDB53619DE762
-:10C6E000A4323F637290C2D1C8C1649E86EFD3C0AA
-:10C6F0005C998607B57115F118005F2439FEE7DCF7
-:10C70000E210C5A777966C9B42C7DBBC81F7344922
-:10C71000607F824DE08F91231CDA89DC53E93BBEB8
-:10C7200041CB57FB92BB21AE30ED607CB039B72FC7
-:10C73000751A7DB65A997EDD9CA89413F5E516C549
-:10C740006F7425CA8949F47DFD9127B3658AC7D0E6
-:10C75000A199182FD6ABF8C87B1783BD1C3A3A3B7A
-:10C76000610E9D6FDDCF59FEB2AEBF7831CCBF6E8A
-:10C770008F8140BC56DF4FF9492B1F540EBD93E803
-:10C780003CBC9D5378CA1F8B52739758E9FA3E9B65
-:10C79000E715815E1BBAA6ECB6D020E859419C0C87
-:10C7A000F2B2A1CBB31BF869F38C4BC88F96CF794B
-:10C7B0007E569944E3AF7B2B17835A4B3530B9A48F
-:10C7C0000C877ACE98B80DE9FF9F6564D89C88E401
-:10C7D000C4FDCC1CF83F8ADF24D15B0EEDC5A53427
-:10C7E000F4013E157CC7C00F91CB2D980F2D1797E4
-:10C7F000627DF61A62E8A0F81C9492929A68576BD0
-:10C80000BED7007E4A9ECF86794E635CC50E909B54
-:10C8100043675939BC4EBFC275B21506FB2C14CE06
-:10C8200044072F42CC916AF45A60DDA82C0F1C2AD1
-:10C8300001792168BFE5CF16615EA72B9ED43C4FDE
-:10C84000E9D463D8D8F113DAAE27C949C0AF6CE593
-:10C85000B8F52BF07DF994AD146E8FB27EC6448F7F
-:10C8600008EBD593A82FEFE7363E0C72B4E5732F93
-:10C870002C86F9A59ABD9DC914BFFACFBDD0E19A07
-:10C880008D74CEB350BAD4A7BCD061A174EF69F255
-:10C89000BA454D79D29FA9B6C679BC8072CA277EA7
-:10C8A000F61190635AFF530BE5DF6793547F80D5F1
-:10C8B000E7E7A9651ABF521D6F6C1A29CB16AAFFAC
-:10C8C000F335ED2BA8DC7EEDCB46A2C20FD1B26DC5
-:10C8D000769FC566C479101BF8335379F4676C8969
-:10C8E0006C5D6D93F3D04FEAB1327A0D6719B07E6B
-:10C8F000A1F13911F200E6C9BCC18CF173C0672AFD
-:10C90000817D579EB0BCEE01EF6409D2A36C1F90ED
-:10C91000EB5C8E71A0B550B3EF47205ED5EF13F2FC
-:10C9200011E502F360BA81DA61E7F9E55C36855713
-:10C930009BA2C4854E920E79D7400AD3338FF9E477
-:10C940003B4D12F0D8203B9F4A7CD3E099B62E3F56
-:10C950006DAC7385A3F7FF43E897ED711814BA49DE
-:10C96000BB43D4476D763C2F821EA1667EC701F083
-:10C97000279D3CF24D01C83F2D6F4B64F9F6DCDE7C
-:10C98000C54FCF02FFF0748101E49F173D229CA7A1
-:10C990002B8B2B4900BF8D1FE1D357507E8D4767EE
-:10C9A000DF0DF19E00F24BDF1EB0B273A0C3E9A40D
-:10C9B0000FF2BFBCCB4BB4FB81AAFCEE6CB4E073AE
-:10C9C0006FC98A6FC03EC1D7DB09EE07082E1F96DC
-:10C9D000A516C2815C1C2FBD17C7FD2AEF4B580757
-:10C9E000FAF62CF3EB815D309F117A8A837CC67B4B
-:10C9F000165F02CC7B5FA2DE9EDE96CAE2613985BD
-:10CA0000E9CF3625DF295CBB05F337AD26551F5925
-:10CA100096807F2AF07E3C2F6BF66FF382BEB210B9
-:10CA2000591635F9704BA63EAF255CBB15E1C829F8
-:10CA30006C9CC873050E4E854FD7610C7F597D469F
-:10CA40009E4368203ED44764809D6FD8B66B7E5A63
-:10CA50009206CE36CE9B268EC11F5BAE194950730F
-:10CA60001E650B3F2CC07CB65C13F03D710DC637C4
-:10CA7000C1FE0B65B80E58C717BF8B76C9463A433F
-:10CA80007060CA0CF908CDF94FE2E28747F83F2FF2
-:10CA90002C1FB87FCE45910F495F8EDC370F808DFC
-:10CAA000A57EC50EFB6F0498E7BBF3C930F89384ED
-:10CAB0000C2E04F9AD9B6FC37CF416D269B1401EF5
-:10CAC00085EF14B579E1BAFE8BF1708E8E2EA90434
-:10CAD000FECD961F96E9F251EA3930B55C7F6403CA
-:10CAE000E609B7F45C15A694201A03261A8FD559C7
-:10CAF0003A4F99F3C2EDAD26BF9C01FCFFC347BD81
-:10CB000019F4D5D7004F383FD5306126C47F7F1048
-:10CB10006BD2814E765EB11F6B2C683F5AAC345E8F
-:10CB2000033EBD3009ED29ADE6C13EABE32F56E231
-:10CB3000E221F02F6640D73EF4D35B6DBE2B609FA1
-:10CB400080B179EAEFB426A97CB3AD03E4A74B0822
-:10CB5000EB45F09FBA6CAC6CEFDAD6D1C2EC30F397
-:10CB60006F9CDC6EF06F5A157F6968FF75F48FBAA1
-:10CB7000844EE6FF7DDF2C019E5D369F07E2417902
-:10CB8000C76409EC49459A03E7617AC1DC0DFA30C4
-:10CB9000D9E9BF047E0B7132FFE8DD94F3D9200F91
-:10CBA00051E00C733703C7A587639DCBC67F9733CE
-:10CBB000FA769484DBD1FE21DCFFBFCF82791EB5EB
-:10CBC000FD01935EAED5675E2AA327E813906BF54F
-:10CBD000BDE0DF84F26B2601945FB34BBF2FA4CA84
-:10CBE000B3706DB22E4FF9B514B63FA5EA01E15A04
-:10CBF00011D6CB0A9FEE84FDF231C7498A31CE743B
-:10CC0000D413B1C72955F40851F2BB3C9E2753E514
-:10CC100024B6BED0E76B23F59FFA54F5DF17143E18
-:10CC20003E6DF5CF4BA5E33C12EC5B68C3DEFE5BCB
-:10CC3000617DFEA4F06561EF93C780FD2E8BDE4F12
-:10CC4000A5CC807353DE6FA4A4BC7FB9D990CAE68B
-:10CC5000335A8FB1FCC3B68725B4CF5FE53D364F5D
-:10CC6000143D5673CDAED35F19296C9C1A5E463DB8
-:10CC700056732D1EEB3F387C2B094E1F0BBE03EB6A
-:10CC800047E0F731F8C74B7FDA350BE01F3619CC98
-:10CC90009A786EDBE105699097DC66A57AD9A19355
-:10CCA0005B2FC82D9F4B46E22090F37D23F5F37751
-:10CCB000837FF3AC56CE6781FF15EECFD375DEA729
-:10CCC000C83D9197446F6F8F683FE25F5561FB48A5
-:10CCD0007C543D0265F0B7F83F9B55FC500F3D6911
-:10CCE0008880A7FA637235C2DB3C83F919969407F2
-:10CCF0007F26E703FF05CB200E1A7E9848DD6434BB
-:10CD0000DD2D0A1FD65C9BA05BD730BD27EADEFF76
-:10CD100047A38B0435F2F651FFB6856897619D00F5
-:10CD20000E917762BF031924A891BBFFC3E383E28E
-:10CD30003127061EF3FECE78E4EAE4328C47BEEEDD
-:10CD4000FD07C5C368B9E6BEAC299B4492A12D1767
-:10CD5000872C1997357ECBF453A2AE3C63C0A56BEC
-:10CD60003FF39CA4AB9F3D58A8AB9F73C5A32BDF9B
-:10CD70003E3C4BD7FE8E6B5E5DB98C2CD2B59F6F5F
-:10CD800059AE2B2F10D7EADA4F54F2E477BA36E8CF
-:10CD9000DA2D921ED6B5131A92BF03FECB1DD7EF24
-:10CDA000B0407CB1D361A8847D879DBCDF921445DF
-:10CDB0003FDEA6C01DB177AE54ECBF400CB4803E40
-:10CDC0005C4043E166EAAFA555FB5AC0EE578A2C9A
-:10CDD0008FA8E6CFC9F59515F0FEEE4544EC480C5A
-:10CDE00097EFFC14215036677AF1FC9AB5C880E7BA
-:10CDF000037617AD1873FF619FE2BFEF89B0F7EAC2
-:10CE000033C1C8CE4946BE2F48637EC29377EC2318
-:10CE1000B04F607104F17B9EA39377BAA0FCF41D20
-:10CE2000DF76419CD13EF9132EE09FB6ACAFE9CE40
-:10CE3000DFD9F2097EDF110977BF0237FFDA631607
-:10CE4000B09FBB33193D23DBA9E7D0775B58DEFCED
-:10CE50006F35CFF234263F1FF63C2F2870775B8268
-:10CE600098FFEF28FCDBE05F3D82FFE384E1FB38C5
-:10CE70009E376ECF1224AD9D559FF07D28CCA72DF7
-:10CE800077A70BEC6E7BEE2774FEBF399FEDAB45A9
-:10CE9000F6E35C6CDD768B7FDBF93CF657CF67679A
-:10CEA000D4FD754B8C7915A8F3720591CFFE56F31E
-:10CEB000FAEC883CFD7DE6F5A2325E7C1AF34F77F2
-:10CEC0004B4C8E128CBE5FE6E5C696BF8459FAF3D2
-:10CED00048711E7D1C9097EF1BF39CD139853EB1A4
-:10CEE000E4758D494E013C5E6B64E769CF021DE934
-:10CEF000F39C7F42397C97F01A9CCBE2A0FF8EB85E
-:10CF0000B1D661ADDFA8C3733CFD30258D9DA75C14
-:10CF1000BD46DF6F95CFAE3F17A59C27A0747A0260
-:10CF2000F2CB2ADD46ADF38744A758FC76B374EA0A
-:10CF3000287C7F741A8FBFE3D398FD1A8F4E2A1F67
-:10CF4000C582F3FF2B1F95037D6E828F54FEF95B24
-:10CF5000D3E71F8D7FAAFF8F3E63D2E7B19BA48FDB
-:10CF6000AA877A055213ED1C48934B40399DC4059E
-:10CF7000CE2C8238FB2E239E773873A0A78EE469CF
-:10CF8000DB317B7AA6F2AB7578EEAEC68EE7BDDEFE
-:10CF90003078FEA504F2528F1831EF1609FF8C424B
-:10CFA000BF4DAE44E5BC8E9402F47EA366E598F3D3
-:10CFB00023959A79E1BE9A2D5C3652B84442FACA5A
-:10CFC00094BE90173853393D2E9A5D53D72FD6789B
-:10CFD00037BB7E6FD434BFAFF51B6F7E2B5D7937C7
-:10CFE000A51FE1C43ACB4BB17301BD8F33FFBDD751
-:10CFF00040D793C2BF0FF2DCB3210E2098FF5BBD78
-:10D0000026ED20E0FB2F2E76FEA25F90EAF01E9028
-:10D01000954B77C3B988B3AB1239486DA8787C4576
-:10D0200059D7D2EAE8FEE7734A7DB83F472645590B
-:10D03000E72F2AFECFAA6A0EFD08C27BB3B4F77CA5
-:10D04000FC73447D64FFEFBBE2B1FE6C8CF3975F31
-:10D0500057FAAFAE1ABB3FA94D510E618853B5DFE9
-:10D060009F8FF095220F8B5DFE3E176DFF1AE7FF35
-:10D07000D2C7818F263B90EF094F7261FF7F040E6C
-:10D08000EFC5731B97EB18DD23E16AE0BD3416BCD6
-:10D0900058F455E7A58E57427C18DF914A223E315D
-:10D0A0001BC737C279B6BBE793008ECF4B884FF2D0
-:10D0B0009B34AECB0DF3C7798358871FCE2870FA07
-:10D0C000FF7BFE1280D37FC620EEC88D8D772CBDEE
-:10D0D000F0A6C23F4EA37F079C2F20EBB9A8F27D9C
-:10D0E000CE65C576BB5CCC3F24BC3F0BC699B8DF90
-:10D0F0006F9228DC7B94F36784F8B3966BC6DFA548
-:10D10000CC3BB29FD3C8F6C9C9EB4C0FF5763F9222
-:10D11000154D8E5E51FCE65DAE42DD39DF2ADFA3A0
-:10D1200026D003554B979B2407D44B8CEF143C7AA5
-:10D13000057F56B1234CA798FA47A14FFF397F339B
-:10D140009CFB59DFC0E139E3A2ED8CFFD66F3F6A4B
-:10D15000A8A3CF838A1C2E57E450ED6F4F6772D37C
-:10D16000DB6DCB06FC7BB5E730281EF73F43307FF5
-:10D170006748FFE21E99276490234ABEEFC65DB060
-:10D18000EF30A8EC8FE5D0FA26C0B782E1BB7EFB7A
-:10D19000728CF72756B278BF5F20781EE8CDDBE3AC
-:10D1A000823B0086C57BF4315ABEF4E704D2E10924
-:10D1B000F3C75342682AF0474AB3EFE3BE28EBEDCA
-:10D1C00056F0FD8383EDE7C5A28BAACFD5762B78E9
-:10D1D000C914ADFDCA4ABD5E53F14F3687DE2551F5
-:10D1E000F2EA23FC181CDBEEBDAAE8E95722E2A60E
-:10D1F000AA73D1E397D274C6C7BDC1F2CD78BE5928
-:10D20000364B789658C1C729AF467ADE5842442833
-:10D21000DF6D96BE0CF8DD53658CD0C34184B37EC0
-:10D22000A95D37AFA7BA7F3A15BE43CACB67FAF7F5
-:10D23000BD42079E0B7F880404D85FAA26F23C9467
-:10D240004B229980BFCF2AF453F13B4BBC71334042
-:10D250005F3444B79FBE742627677DF357A1DD6D09
-:10D2600031E2B9848B55C9CB200F2EFB4C1E38E61A
-:10D2700074B16565DC839A7555ED9EEADF9CF3CF4A
-:10D280001FD37EADF2E9D7AB57E8C47D40B99C040B
-:10D290000E513E9BF4A5CB7B67D2F299A001EF190A
-:10D2A000C23F2C67A8E7E0099F4AD75DA91A320C54
-:10D2B000627BF90B6C5EEBAA830B606BECBE673A8A
-:10D2C000F7CDA4E587D2993FB0C33EEF7690D75F04
-:10D2D000358C632F23F869E27E9BAE5C7A8E08D092
-:10D2E000DFBF2DBA7DF88F0CBB72AEC8930DEBB0CB
-:10D2F0006E7BF476F64C07DB27FC8BB1265AFCBD1F
-:10D300003B83C9C9FA1A2EAA3EDF9D11C7EA6BA357
-:10D31000C3BFDBADE22166C3BAAC8F81EF1237B376
-:10D32000676FB5AE5E07FAE08A41AFA7E7BA195F4B
-:10D33000B8DD6CFF7BA8FBA5D654E0879D9C08E771
-:10D34000C92E257A2603FF6D68B988F17EA2D2DE48
-:10D3500098E6DB974EDBDF7BEEF913D0BEBF9A7801
-:10D360003829B61DE84A57ED80FA1DB46A0F3BAD67
-:10D37000608FE07F619F15B6FA139260DDE547F09C
-:10D380007C4CB74D64DF3D796668FDEB1E45CF0CE4
-:10D39000F5BCBFF5BEAF46EF1745FA7F4382B4B781
-:10D3A000848E3B44F9AD89CE875C7FEA56ADBD5192
-:10D3B000E521D6B837EB070EF5BC3F3F70BC799E30
-:10D3C0004ACFBD293FF0BDCAA7F6954830CFCE5B06
-:10D3D000A3E95B552FBFA1E8C5487E19D1378A3E26
-:10D3E000B9121C1BAF8F3EA3C7675D408F8F2A1FEA
-:10D3F0005782CD36B8478B8E3E15D659F54B49C569
-:10D400008C9BBA1F24169E57143C7FD560E451EFC5
-:10D41000F57098A7FE55C353F1D1FCFCC8F90F195C
-:10D42000283F007F7C9947FD5350B3E158AA14E68A
-:10D43000C7F714F87F2D1FAAFA55B52791FDFF51A4
-:10D44000F94EB567E3F19D33461E7277BA05FB6F5F
-:10D45000E04501F69176A74BAC4CC4852EF05F6792
-:10D46000B1F3EFD4EE65C33D1243DD36FCFE4BEE67
-:10D4700030070BE83A5EE99E3359BB8ED3DC8A5EF7
-:10D48000AD4DDC095BD7570C9E4569B07E2BD87D2E
-:10D490001E67CF252D4CA3FD9F1A30C08D5864DD2B
-:10D4A000B60D4698DF6DEE446697B79F46BFEFFD19
-:10D4B000F2F5FA80DE9E3F9DAE9E3F657EF8DDD49C
-:10D4C0002F80F384B1E890E3B660FBFB6A0EA33EC5
-:10D4D0007D603B87FA54724BF8FE013E887A99B41E
-:10D4E00030FF9958283DA85EBA0893007A7C8E6375
-:10D4F000E7BC799FA0BD6FE3C13DAB17C0F9CB4836
-:10D50000F9F88EA2C73FEF3628FADCBFC88DF1A12B
-:10D510008F0378973EC9F05DBFFD513CA7FC7ABAF6
-:10D52000E25F2BF2F9BAB24EEAFC9295F99DB70D83
-:10D530006F037B41E5C680E74C5E33225E435FFBB1
-:10D540006600DA89531C18EFA31F4BCBBDCBE282D8
-:10D550004D9ABC9DEAD7E479983C54F15E9D5FF802
-:10D56000903B57E7A747FA1BFF670FD8B3C3FDF7F8
-:10D57000B5075DEE0FC71E04D219BF47DA85113912
-:10D58000DEC9E4F8E2B9DF2D8072A41C7F5D91FF53
-:10D59000BF567EAF74DF8B7C2D2F2662812E3ECA54
-:10D5A0000A421C3CC2FFE1388983736E4F75FF6CE1
-:10D5B0002AE4BB2EEE5DBD2EDAF87B33989FB531A1
-:10D5C0005E32E07D90AF313E8BD41391FD46E42274
-:10D5D000469EB16AC56C8C0FCFAE98930DDFBF45E8
-:10D5E000C607A3DA73DE9455101F3729F1F13E7395
-:10D5F0004D77147C93143F352F7FF804D0FBBD5A30
-:10D600000EBF1F863FAD9F7EEF39CF8F06A5D1F8A5
-:10D610008E94D5F8643B1B2F729CCBEE88F844A601
-:10D62000F109A5F36095311ECEB3AAF1C9A0FCE1C2
-:10D63000C6276F92E17F9909EBDC131D2F3E43E172
-:10D640006BC1BF6F36C56368B1D12383BC18683F17
-:10D650004D5C12D9EF9AC2876F6E7F9FFAE89C3EAD
-:10D66000AF1C4BDE46F0FA2BE5AD5718CE02B97F62
-:10D67000F3E0F50B8FC17C0EDAF0BEB1483807330A
-:10D680008C4A7C60433950ED6FBFD059FF12EDF7E3
-:10D69000E65D6ECF0EA2910B42E582BE3FFF172AD8
-:10D6A000171ED46F28C7BDDDF69A6871CA0F143EE5
-:10D6B0008BCCDB88DDDF08405CEC251E9336EFF475
-:10D6C000BAB2EEAF2A7A292F83D9CF7BAA960B90D4
-:10D6D0002F7A70245F4430B810A7641E84F8F215C6
-:10D6E000E57B0179631CCA5D241EB729741D2F7F59
-:10D6F000B0A65A1FD7DF53A5D71F6F07F346EC48D4
-:10D70000C118FB522AFFC61AEF66ED476FF0FDED18
-:10D710000B8C37BFBA8CDC9BDA17584502B7639E77
-:10D7200083AE0F3CAB4860EA4B149FB79F59897991
-:10D73000F45709A9443FFEFAC7A66AFD927B95F506
-:10D740007EAFEA637701BBBC2E04A646B33F917956
-:10D750009A5783D1CF67F814BDFABAFA5DC53DC6B2
-:10D76000A8EBBB5959DFD7ABC7969BC8BC4DD55268
-:10D77000FDBC3F95212A709A6D7E1657B371BFC0CC
-:10D78000C605BBA5F54B3FF521C9EB20E4EF619C35
-:10D79000ED84403EA55790A768CF5FC565323AE457
-:10D7A000158EBD1FF58A4257B55DA49FF513B7A42A
-:10D7B0003B3754B5548FD76746FC4111F320436083
-:10D7C0002F9D617B79B7D9F330F001714858FFBCC8
-:10D7D000B2DEF7D6FCD604F3A7FAB315F2A1F2191C
-:10D7E0008308FAB3F45CD0A4A5CB6B3719DFBFA6CE
-:10D7F000F80BE3E9D1BCC261D46FEF051DF89DC4FD
-:10D800009B9FF993291ADCAA6B19BAF3C4EB7DD15B
-:10D81000F32AB60CB6DF158BCEB60C49E7A7AEBF20
-:10D82000968DE78363F9FF9FCD6071D07D35075BEF
-:10D83000B5FEFF530A9C07547DC633BF3F56FEF525
-:10D84000A71937977F55EDB3DA2E72FDD567A4BDC2
-:10D850001C54E439B2DDBF65DC1CDF8DF83131F8D2
-:10D860002ED6B86AFCA1E67DF38A68FF28FB32A3B6
-:10D87000C651DA458EF3AF197AFE1E1547C4C8DBD0
-:10D880005933991CFB63E4EDAC9971587F8630BB2A
-:10D890002807ED68C7AEF43CB00FDCBD87167DFCF1
-:10D8A0002498B78F2AF99AEA9AD327204E55E38A0B
-:10D8B000B03FEE6F867DB2A11D1CFA1B91E344FAC6
-:10D8C000E51F853D269047257F5068F4629E9A7C2F
-:10D8D0009A9DF37736AC46FF52CD4FF70ABE1D71C5
-:10D8E000F4FDC4EDBFDD06F6558DE32F993C0FB373
-:10D8F0003C33F377CF773BF07BD7DA1179F760BE13
-:10D900007144FE95FCE378EB31A26F62ACC778FA04
-:10D9100026565E447D8EECB308E28C97E17C2A1794
-:10D92000EF817B99979B09E67D962FE130CE5C6E67
-:10D93000F6E27ED6E9330603947317E7EE067F63BB
-:10D94000C552A3D74A51F83700359BAAF257AA0B04
-:10D9500000CE5374C210C7F6BF21BE07CF5717C4FD
-:10D9600049E0FF9F9E27353969F9F4624EDC41FB9F
-:10D97000BDBCF401E3545A7E8586CF70EF8CBD8127
-:10D9800028DF7FDCB26C7E3E21DF00B89AEF3F5E7D
-:10D99000216AFD3DFB2A281F4D49E937382849BF38
-:10D9A00075E09E7D160ABFB5C9E782EFF2EECFBCE7
-:10D9B000751F7C0F999AEA1DB883FA519D999E654F
-:10D9C000F09D5EFF175478C5FBE03BBC1F18FCB907
-:10D9D0001CAD7F2173D1321EF62326A8F0ABB17E99
-:10D9E000D5C2750FF6D3FA0B07EA97C119F6D26ABA
-:10D9F000A5BFFCB165F3794AEFB96AFB8678283B8D
-:10DA0000ED24BCCF348B1053F83B3F3CF7DE3F7224
-:10DA10008E7CFBB20ADAF7D5B2C07CF89ED3F3A5B0
-:10DA20001DFB8AAC84CCAC2C13BD743EA5595F5849
-:10DA300066877521941F69FD47B20E2C83F9388DD6
-:10DA40000605FE9710BFD26A790AD47372705F65BB
-:10DA5000227C97307812D8724B43A72555F77D4228
-:10DA6000C00BAE8970A42C9481E828FBDA99A1A997
-:10DA7000ECBB3BA55CC8F2142365172BF7EF88FEBF
-:10DA80007DC57F6531FDD56F8B5EDF91A9DFDF4EF0
-:10DA90003847BCCF4591FF8F29797F559E4E403E38
-:10DAA000C48957CC059A601FD6C2F08CB58FDBAE07
-:10DAB000E897FCA604BC976869C08EF7E84CF03084
-:10DAC0007D43A5885F09FADF68403C538C1CDE6B00
-:10DAD000926A23FEC3F49992CCEE39594AE517EEC7
-:10DAE0001F5930C1D783E77CD3D28B9BE19C5DD398
-:10DAF0002F79F0C3D4FEA3F1141F053C538C2B8A5D
-:10DB00001F2DD2D0AF88E14DD75DE9E7FDE61D209E
-:10DB1000170353F2C0AFBE3D536FEF4A07CA4DB073
-:10DB20003FF9AB2C250F26B1FE29F3995E197E54DF
-:10DB3000B9B7C2E229D6E5F5153ACF6F5BFA34B42E
-:10DB4000AB1D3011388FB8ED7099EE7EF5C8672D9A
-:10DB50009C7BD7D8ED5A3E84E7CD6BE1DCFB74802B
-:10DB6000F77301CE39021C880FE0FB0EF09B529A2E
-:10DB7000A3AFB79A57AEBD9648E4E9DAF78C5E6179
-:10DB8000F84EAC1F6F5E6178FAEFF946C353BEEBF7
-:10DB900053E9CE2B7417A2E3F933952F29BDB5BFF6
-:10DBA000AB52554D94F313EC1EDFF3CB8ABAB5F7A5
-:10DBB0001610B2839DEBE0E93A823F3960C3FB80E7
-:10DBC0004B79AA1F9D002F4994B9D17CA1AE6B7FE0
-:10DBD0005200EF231ABE8B13BBA3F8D967143E2E55
-:10DBE0005DCAF836ADDA6FDCA0E17795FFC3F007C8
-:10DBF0003EA3CAC73A94DBBD0C3FF037800F3DA16E
-:10DC0000A9DA73202AFE659904E74FD791D1FF2E38
-:10DC100047B09B0BD36D34FD33C659CF6CAC2F1D71
-:10DC2000382600BFD5C690D3B359F1386EDAB95053
-:10DC30003C9C0F58A0F07F7FDF74EB1C908BA506F7
-:10DC4000C2496CDEE06796CE55F5E73BBF28A7F6E4
-:10DC5000206DA44CF5AB04EB30A26F43164BB8FD1E
-:10DC6000C9AC7796B5803E36B3EFBCA9FF68219A60
-:10DC7000EF11B92C96BF9DE58FBE6FFD4616F34799
-:10DC8000547A7FBE613E798BCEEFAE4C66BF670D96
-:10DC9000CA785F922AD7917A29278BAD634616E31B
-:10DCA000B3BFBD5EE2C6D14BCB15BDC4EA89D35725
-:10DCB0000BF5A906E5FB0491ADFBC69F4C2F803CFC
-:10DCC000DC56975182EF1D56729EAC6FD171AA2C13
-:10DCD000526B9C14E68F2A62911C406F3A027CFFC3
-:10DCE000BA62A915CBF0077EC7EF3A39C67F444A1E
-:10DCF000A81AC3AF55F1D9EA1270BC8DBB0A12FC49
-:10DD00005A3C79DF7398DFB32B785A22EC15AF2F8A
-:10DD1000A7A686EA0C464DBD83D9AF1697774E1657
-:10DD20002D9F56F242A43659E717AD52E42ED22F5A
-:10DD3000FAAD8B287A6205C68F69347E847B02D265
-:10DD4000FA7C781E0C2E322AC0EF76D97DC6970E4B
-:10DD500093B91027A9707C59453AFD5EBD1A364D1E
-:10DD6000A8705AE67B2F6BF4D929E53E7ACA0F33A7
-:10DD7000405E9767117D3FA32F13BE2F2769660F63
-:10DD8000E89B1382EF00AEAF4812617D17181F3D6C
-:10DD9000807C612489CD784EEA20F6AFAC1E2E41FE
-:10DDA0003FF5BA310476E797D9E998CF49B133BE48
-:10DDB0003D610D603F9E4849A84714BDF7CBECC9B3
-:10DDC000780F86AA3FC3DFB5A87058FD096E792683
-:10DDD000DC0B7B2265527133A7F777C0FF09FB4B41
-:10DDE000DFDF77673EF8377D218A33D52A2F2E7BF8
-:10DDF0008CB6DF9C25317ECDF5F5C3B82712890896
-:10DE0000F8CF1AF43F07E5452E3BDEDBA6AE47AA66
-:10DE100081FD1E4CAAF27B2B2027F0B4653339EB31
-:10DE2000529E83D96C3D53E3A3FF7ECCB0D26EBF2C
-:10DE30008DD1B9A34C7F7F92FADCA9C8719DA5B39F
-:10DE4000123EA9D77CEF89DF87F384FA551C7C4FFB
-:10DE500042F03DB56748AFF96DD5F8FB61EF0DAC09
-:10DE6000C27B5C477ED703EEABA2EB1E222B9F004A
-:10DE7000BA0BAF1AF16EBD56133B772724FA45F85B
-:10DE80001E29D91E3DDEFD96824FB291DDCFAD7EBB
-:10DE9000C76052BEEBFF8AE28FC5BBAAD83D45944E
-:10DEA0008612A55F0219C6EF74D5758C3C976B522C
-:10DEB000BEE77FFFFE43710CFFA144E73FA8E346A6
-:10DEC000FA1117E0FE6D4DBE7B9DEBEC02A2697F5F
-:10DED0003F196C0578F76FCBD0E52562F91FC715A0
-:10DEE0007D0BFE821C152F41F7FE028D0365EDF8B8
-:10DEF00057D8F8E171ED44D68CDB96E57D390BFD02
-:10DF0000D4B922DE234C7D76380F4BED0EB3D77398
-:10DF1000D9FD84D42E5582FE56E322907B3101E454
-:10DF2000BAECE759291A3BA9F48BD447772AFAE8C7
-:10DF30004EC5DE249C53FD469BC47161BB33DA6E33
-:10DF4000718A1F1DA91F23ED82DEAFA67C2B6BFDFE
-:10DF50008051F292F541FDCB0931F863E2DFC5BF94
-:10DF60002C9DEBC7F892547204F6416656E8ED3DDD
-:10DF70009FEDC079F1D9769DBD5F51AD6F6751DAE4
-:10DF8000599476E3D1536B8F3823E83D06AF9E63F7
-:10DF9000FC90FBCE19BC4FA9229BF943B7E4781340
-:10DFA000B269FB837F9EDF0BBF3B31DCC4936E27DE
-:10DFB000F4F3F60E3A615E1611E2D4B2B515850798
-:10DFC00069BDE9E7260FC4CBE448F4F8DED1C07997
-:10DFD000375196CA54F460AD93CDABD61912F229DD
-:10DFE0001EEE5A864F66DF518ED7E8BDCC1AD66E2C
-:10DFF00062B649677FA628E5C26C252E21C126F8A6
-:10E00000FD93CC1A2F0FF6CEDDC711E59E4DBC1F38
-:10E01000D5ED61F01D9E20F7405178DEED86E54597
-:10E02000602FDA53ED1EB0175B72FC9E6C90D7F335
-:10E03000A110906DE6F9011EFCBE5D39DE62A0877D
-:10E040003A3FC928BA617FDC7E9EE1D719C1FF84BF
-:10E05000EC56D6A59BE1E7F015033EA9F112DE4789
-:10E0600044FFF2C0AEA62629762395F8E1DE2062B1
-:10E07000A1EDC00FB2D176DAEF3789AF04F609828D
-:10E080002953A7819D5B60F31CB3807D9D963B0D5A
-:10E09000EE177AE940F47CFA32C5AE50FC1769F10C
-:10E0A0008F251F23F7AB2BED4C31E26895EFED95F3
-:10E0B000D1FD556A09985FBFD6792FCCA7B6452008
-:10E0C000708F844AF75D39BE6AC0C7DD77900379E7
-:10E0D00075F795215FB9659E805FD162CB0EC2BD99
-:10E0E000B12D491F4903FAC7C2BBB6C1E8DDA495EB
-:10E0F000E71601D7E360C4F93535CEF87836F3B3C7
-:10E100004339BE5A58E7FA234FE239C1877B2E0ABA
-:10E1100063DDEF73B374E36A58FC52BB86DD9B5139
-:10E12000B696473EDCDC22E0BDACB5CF1D0EE17EED
-:10E13000F17682FBA0B57D874FC2BDAC19B5DE1963
-:10E14000DADF21C8A865F7C7A5521E192842BD29E4
-:10E1500080DD76F72DAF45BE168948908FFCE877B5
-:10E16000655A983FAAD2F7A410CA7E99B63B692097
-:10E170009E665A7FD52417C24F345DCDB579E01E17
-:10E18000867F3EFCBAF469A033E4C55CB01EFE276E
-:10E19000811E1D4DEC3C79C702EAF7D0760BEC648A
-:10E1A0002B9417343B08C8C7CDD26166045FCCDC22
-:10E1B000CEE4E4B8A25FE81FDEABF4CD6C16D7A4C2
-:10E1C0001AFCD5E8BFD279B4CD46BC701EB66C6FD0
-:10E1D00010F02262128EEBAE0D71DAEF50D4679818
-:10E1E000AFBC5FCB4E793F78F6E13EE36645CF9416
-:10E1F000ADEDE1DED2F0C1F7B2D97EA9FBB9831C47
-:10E20000C487B4BE698113DB637ED0FD1C8B9B3653
-:10E21000D3FA07757A6503CEA7DDC6FC47AA577EF9
-:10E2200008FC7EC2F0E871D82F39318DE07DB377DC
-:10E230009D0F9D44F5ACE07B4260EBC9533A34D16D
-:10E24000F2A96CE6DF9D14FC9B60DD4FBAD977DE46
-:10E25000ED861D78EFA92AF791727A4AE173F79A51
-:10E260001ECE50847940F42755FCD476B7E494FF51
-:10E270003C1BE9308074A85BC3B37C8382CF02C1AE
-:10E28000970F71DA1B0ABC63ABBF6D7C86E25757F0
-:10E29000C4213FEF7FE134F2655D27C77E27A8F3F5
-:10E2A000B4B04A135F757DEF34DA9525FD6CFFA598
-:10E2B000AEFF30FF8003ECCD31E4CF3ACA7FD612F7
-:10E2C000583709E97CD514CA067B19C99FF64AA6B6
-:10E2D0001721E75AC0EE83C3FDDFE05A0BFAFDAA0F
-:10E2E000FEB5652BBF5BE9F0E7827E7D5729ABF079
-:10E2F000C3F1AAD503FC9DFBCEB46370BF5B9D87C1
-:10E30000F3C079E4E1117BC2F4B544D915F4B50A40
-:10E310003F927EAE1C66CFA2D891FF8A6647543BDF
-:10E320009BFBE572FCDD3775FD7885EE23F63D87B6
-:10E33000ED4B597278051FAF0BF2D81295E78E128C
-:10E34000B8DFCF57043FA1D69262F7407EE79F1314
-:10E350005F933668E87552A0F24ECB27F36C880FB6
-:10E36000950B6B8E66FD6A8BD8EF4AEDFFEE72A4BB
-:10E370006B2DAC1DA56BAD7FD326A4B38B888740D6
-:10E38000BFF899FEAA5D730FBB075CB57FCF7348DA
-:10E39000FF5AD981F75A2FE95B8EFC499C564F01F1
-:10E3A000877A0DD7599533DB085DD9FD4334AE6FBD
-:10E3B000827C891AD7C757FBE43869B49C262B7135
-:10E3C000FD0C25AE37CDB27CA871FDE6869F61FCC1
-:10E3D000F388EB27F854E584C68D3A799AA1ACB35B
-:10E3E0003B87D9D3B9394C2E3797F421FF6FBE1C28
-:10E3F00040F97154323DE238AFD77F6A1E8C903DB0
-:10E400008C0FED7D0B611F62C1573811F4402CBC9D
-:10E410003FCA057E01E755C861768EE28EEBBF8C60
-:10E42000D7DE47BA3487F1F7D55E230901BDF980FD
-:10E430003096FF1B0B5E56A862F6BFD3F5FB756FD7
-:10E44000029E0BBAFADCCA4F4259EE49C0732459F6
-:10E45000A12AE48BABCED91EE0036733A3D3D5BE8C
-:10E46000F9C83FEFA44906B82FACA9EFA979F0FB92
-:10E47000D01B15BCDEF9AEB101E8B0E3EBDF9907C4
-:10E48000F74B6E0E72C9F0BDD9D5DEAFFC05EC5E60
-:10E490004DCF163CF7D5FCCD7F42BFDB103CC8DE2C
-:10E4A000F72688D06EE8AB4FCE03FA36F73563FD1A
-:10E4B0003B5F3D88E5635FFF8EF19992301FBFF3AC
-:10E4C000DD833FFE6F28FBE2F1BB9C5AFFFEC7A134
-:10E4D0004CAAE2D97757FE9705EDEF75751D3E8A78
-:10E4E00072A8F2C5923E4EB93F4CC0731E2AFF5E21
-:10E4F0002A2F2A05B9831B768DF368B923AE265AD5
-:10E500001E71A732DF5AE04518770D1704396817D6
-:10E51000E45ED4E7625F36E8737B5148807B5756F0
-:10E52000571F9EC77E76B009EB575AD879B1A954C8
-:10E530005EE01E290AADE706F56B56B63FBC0EE05D
-:10E540001D3012D1981EC6B75E90303EAA5FC179C9
-:10E55000A884118E6C3B9102FB5F0D4439D7C5DA5C
-:10E56000B5D3F0D29284768858E9B3745BF43CE872
-:10E57000BE1C87229F4C5EDDFDCB33417F10A7D9A7
-:10E5800053901B8697752ED001D7F9BB6B0616C228
-:10E590003C16176E980EF37042BE0FEC8BEC40F8F1
-:10E5A00075909FA4F21454E42655F4E17D2316AF30
-:10E5B0002F057E834D32FB703F4F5AEF3335819EDE
-:10E5C000E187B357A1213CA4CB7B7599FCE93300CB
-:10E5D0005EBB629F7A18FEB43FC293E67B9DD09FDC
-:10E5E000C24778966A2F8FBFF16661EBF09F3FBA02
-:10E5F000F3903E5F1E1C05BFC401F6455E83EB260B
-:10E600000938DF77A029D25BBE559BC78ECCF78037
-:10E610003E83FDDE504ED90F7266849F6A1E28929B
-:10E62000CE7F817AD01F92179FA437F9A67E0F5014
-:10E63000D5DBF57B14BBFB838BA877EAFD3CB3BB32
-:10E64000FECB68777FDDE8256F51C7B2EBC58BC87D
-:10E65000DF0F1C6176B7FE48B100FCACDE8B5C5F5F
-:10E660007E15EDAF6C24C8D7F542DF4917C0EF2007
-:10E6700089D4B327F5F3062782FEFBCD8BD635D0A0
-:10E68000FF84C180FC76A2FB9683CD9C163F1607C3
-:10E6900070354194C77AC52F285BBBE94988C7EA22
-:10E6A0006A08C685F5FD8A7CD1780CE85B7FE43486
-:10E6B000F28FEAF7E67E7905F25B22E537FC9D846E
-:10E6C0008A01C48FFE790AE833B182DD8FBBB8B00E
-:10E6D000B814F8EDD8EA1FEF04BB5D5F414480DF5A
-:10E6E00095E57D11EF017E91C37B29BB4C9DE5F043
-:10E6F0009D64D7024904F9A8F7578DD8273C5FEDF0
-:10E70000AFEA47F971AEF380FFD0D1E447BFBA2337
-:10E71000DD8E7E41D78B4D683FEB259B077EBF6426
-:10E72000C9116E2BF6971D84E1CFA19FBF24380736
-:10E73000CF6DA9F458523198CDF405C3FB37A681AB
-:10E74000FB61DEBFF99E19EEFE1EE1BFC48AC00167
-:10E75000B8AF768938CD03F76B26F1037EF077A842
-:10E7600009F634C1FEB0C967F640DCBD97C37DA889
-:10E77000FF076B233BDE0080000000001F8B0800BA
-:10E7800000000000000BDD7D0B7854D5D5E83E730A
-:10E79000CE3C924C26274F1208F14C123040124EBC
-:10E7A00020BC114F88416CA90ECA2354C4E11D201E
-:10E7B000242362C55F6F33381023BFD71BAB156AA4
-:10E7C000A91DF0516A45A38D354AE01F10107BD575
-:10E7D000466B11FDD18E4A798964E451E957AA77D5
-:10E7E000ADB5CF49E64C263C5A7B3FBF1F3FD9EC25
-:10E7F000B3DF6BAFF75E7B4FEA64A6058B192B780E
-:10E8000040D0824EC6EC8AC05826A6163DB5313699
-:10E8100082C19F669ECAFE524F09635F3468ECB3A3
-:10E82000018CFE28598C2DA37F30B67C41C8A640B0
-:10E830007FB5CFF2FE32EC5AD9ED907E837FAE8663
-:10E840007C25BBD503E599A270EB544A2D941AE5BB
-:10E85000465AACCFC3FDF8BC87AA3218FB5E0D53F5
-:10E86000136088BE45F01DF2CCC78203DC90AFF187
-:10E87000E42A589EB15815219F99CE7E88E591D5FE
-:10E8800036B659E8D9AF8AEB1A81F53CE502D4CB0C
-:10E89000EC93AC067028B1C29280EDCA0475B382C5
-:10E8A000F91B9F64E590CFCC51B11FC6823A1C3C46
-:10E8B000E516A877342B595D87DF837F906E047847
-:10E8C0008C5764A3BC0CDB292EC6D69575B7AB2A32
-:10E8D000F0507F557D12D400CC734AB3BF94E573DA
-:10E8E00038789CDD7008AE4EAC0E46C16324C20180
-:10E8F000DA0707B1EA966284BFA716FBC9B2A8E996
-:10E90000EB5221EFF497DE948CE304085E57E03C71
-:10E9100020AD82F5F9B0DF02CF4A824766B21A0F06
-:10E920001EA12B383C76CD7C4EDC00F5EA8A85A012
-:10E930001DE6F7C8B6A965B8CEBA694E9541BECEF8
-:10E940002BCDC37199DFC19E823CF32E78A80AF2C9
-:10E9500075351E759D42EB5E80E5B91909EA3A28C6
-:10E960007FF41541C37C9DDF194C80FCF7DB383EFA
-:10E97000D4B5BD20CD873409F1CE89EDFCA5534B2C
-:10E98000BAE7C3D86A9A4FDDC41379BBA1BD5F64EF
-:10E99000AA3801F2B6F04015D65F37213C10E17578
-:10E9A000F295846A6CBFC762F1E3387B360FD914E5
-:10E9B000107AF673D2EA69C5F59F84F5FBA1FCF5E0
-:10E9C00057DE0FDE0DF935800A6236ECD16AA502FA
-:10E9D000CBD7553119F7C5D8AFBD367F11E2D5DE9B
-:10E9E000FC44C20F9CA707E07C1CFF99C358FD158F
-:10E9F0009E250ACED3126A94B0DD9674C6C640FE38
-:10EA0000D5FB077A9D3DE10CED695F1C1223FC7577
-:10EA10000493828128BC7238184B1E46A9DF09690D
-:10EA2000D22A0E9FD87EEE519C547FB923BC177614
-:10EA30008ED5AF6A7664011E2D4854E87B82D5A737
-:10EA4000F583F9D8DA2A42FDA03C2B0DFEC27DDB0E
-:10EA50009C14C47DCBCA62DE17E3F45BA7D39BB1E1
-:10EA60002FCD698CF032CBC5EBFF4CA79B07F47A16
-:10EA70009BF5348A2ECC78EFF4BA914F6425326F2F
-:10EA80004B9CF18CF6303F2A37E6C51CD04F06B6BA
-:10EA9000532C84DF317417CC2C1986745795A8EE4B
-:10EAA00072203D0D730F0BB0EE710031DD53937B7F
-:10EAB000E201AE03E907D78574D65BBDE69D9C3FB6
-:10EAC000C5E2E5B33A9D2C425C87793F27003DC6FD
-:10EAD000DD67DE4F93C56D7914E6FB9FFBC5E066ED
-:10EAE00077CF7A46FA6003D0A09DB1FC8DB3523C3B
-:10EAF00025BDD7DB89F5AE84711B1C54DFA92AAB79
-:10EB000025E87FA2C35D26321C4F9988E3F9613C5A
-:10EB1000DCE7E409EC4B11E053DAD65C74AF1BF18F
-:10EB2000BCA51AD7355192A532E40B1E0B0B1571FB
-:10EB3000FEFD0DFCDFA73A91851CDDF91C6F9A29BB
-:10EB4000DFAFA6AFA97E7F5FBEA9FC8A55834DE5E6
-:10EB50006EFF3053BEA069ACA9FE80E689A6FC9585
-:10EB60001BBE67AA3F2878A3293F64CB0F4DF54B06
-:10EB70005AE699CA53BE2ED8F533C4735C7F1C3E47
-:10EB800067A4C71537EDCF444934F537B4CDBC7E03
-:10EB900089852D48EF29138E0E8B47CF465ACAA47C
-:10EBA0003361A31DF20187627914E6E17A5F0CAE4E
-:10EBB0008BB3EF063E1BF994D1E67D30F8C4C5F067
-:10EBC0002BDF7B617C31F0AAB7F294AFC5B87499A2
-:10EBD000E8E67429310FE3EBAF562FB47E6BECFA05
-:10EBE000994278FFAFAE3FDF3BA82D0CFD9CAD16E0
-:10EBF00048BEBC8745637AF6F751CC3A67AC4C21E6
-:10EC00007D86796E8A5BBF7B1EF7D23C6EB1335F27
-:10EC10003C384C7273B93BCFCDE9FD62F4F9893EC3
-:10EC20008F3F1BF4B9C64DF4C8DE138303A0AB7944
-:10EC30004DC2CE3E8017695EA72AAA909742AC2C9F
-:10EC40004ACE3FA2D3F7A3D81ED20D0D32F5F3580A
-:10EC50004336A51B1B14FAFE784311A5C10695BEC9
-:10EC60006F6E184DE993A08F61FA74C3644AB7348C
-:10EC700078A8DE330DD5943EDBE0A5EFC6FEDCA21E
-:10EC8000EF0FF3A4933C8B5DCF9C9566FA30F6852D
-:10EC900089C5D47E0ED0997801BED6A3BD383BE598
-:10ECA0004278B4EAA0FBF9DD517830DD9D9C7178A3
-:10ECB00008FC63141BF58D78F1F65F3528CFEFB6AD
-:10ECC0005E9C2E0C7C61E73F1B10AFDE2D49503659
-:10ECD00016F893FB97CD7E67EFF0E9C6A3187CF595
-:10ECE00000BEC2D75294ED39581EEE1B3DCE9FF4A4
-:10ECF0007D36F2D3A6717C8DEDF7419D0EA7237E64
-:10ED000042F98C187AFD422FFFC2CDF5F4FDBDF01B
-:10ED10008B46B745979F7CDFA7033EA2FCBC3769B3
-:10ED2000CE55DE38E3FEDDAD98E873C634F33EEE33
-:10ED3000B772FEB6FF4F6270759CFDBF587B633D96
-:10ED4000B1EDFEA0AFE773C4C911FF73E86DFFAC6E
-:10ED500064D2E7F75BBDFD33A3F667FFACA4EA78A6
-:10ED6000FB7EC66DE57456243394EF2C8D69A8079D
-:10ED7000C192FC36D4E558A17C18E9048C21A48BFF
-:10ED8000DEF15262870D7A12119E09A48F9F9D9623
-:10ED90004CFBCFBCB2C6A2FA67924C7AE9733F0033
-:10EDA0005D01C793603CD043996AE9DEBF7CFC3BC0
-:10EDB000B19B5F8BBDD3DBC5F0C0E02333908F5C8C
-:10EDC000405EF76C77797CE4E37F131F31E8989D10
-:10EDD0009F3FC093DCB37C3AF291BE8C3DECDE4F9A
-:10EDE0007CE49F869341B7EF73BA8DE527BDB66B80
-:10EDF000CBB888FCD3F9B9E46B0A035EDC2926376B
-:10EE0000AF8326F749BE5F62DEEF97D85390DA579B
-:10EE10009DEE7B6838755B2451BDC164DFD925DF69
-:10EE2000AFC2640FDA65ACB73EE9C7CF637E157039
-:10EE30004C3BA45F25E40519D80243F2397F121D2B
-:10EE4000E7FA1E8A9A9F5566FDA2F3652147BF43E4
-:10EE500051FB367C9F6CCA8FE8C836D51F75403190
-:10EE6000958F091799CAC71D554DF9AB22A34DF5CA
-:10EE7000AF3EA799F215EC3A53FD4AC75453BE4A28
-:10EE80009E65AA7F6DF65C53F975CA1253F9D84294
-:10EE90004F493EEA0F36679390C2D812B7569A0F81
-:10EEA00070484CACF3CD453B69B54B6613B076303A
-:10EEB00088706BB439E475C0A73E15B43C0678FA87
-:10EEC000B005ACEE02A82F8619A6072D6A19A6F97F
-:10EED000DA162FD269E9A04405F1217120631D28BB
-:10EEE000A7243581013FB12585DF2D44BADE06FB1D
-:10EEF00007A8559A0A8A3EDA013F480BA2FD9B9368
-:10EF0000E8ADC479ADB334BB56E33E5B98E729ACBA
-:10EF1000CFD4FB47437AF87A8B05F7B7B5C3F9C06E
-:10EF200058C80F85EE19A59FFDE4FBB8DF1DA28A26
-:10EF30006E9F87A7BC3809BFAFBC8E896259EF7836
-:10EF4000F6F98FB83D15FB7D7D3ED7AF322BB99DCD
-:10EF5000195B7E875EFEB92D7EF9C27C2E2F2AEFCB
-:10EF60009BB21ED767EDB032F45BACCCD4FAB00BD9
-:10EF7000E9ABE70A587078545EF230D989DF07D2DE
-:10EF8000F7CAFB66B3B093F7837EAC95095A1FF4BA
-:10EF90003B7C3E31FE3C96EBF3B49E4BEAA55F17FB
-:10EFA0007DFF3CFFC2EBB49E4B60C1F478ED9DF455
-:10EFB0003D3310BF7DA301A7B4F8E5F7EA70B29E18
-:10EFC000CB61FEF4E8769CEF748F934BE5D673A982
-:10EFD000CC1F771D19F49D656BD988373B81CE9185
-:10EFE0005F54A466D91890F81C16D9A301FCA7A2F7
-:10EFF000490078CA1C6A19F22926592361832E40D8
-:10F000007ECC65D2A7682F580019BF81A9DDBACA86
-:10F01000FA69388A8EA66AE63CC3FA51F2E630F6FF
-:10F020000DF34E1C5C9482F87E8A2929721CFC32F6
-:10F03000D2D90ED12345ADE7602F7AD2EF75381DB6
-:10F04000CC890FC7DFE6733D6AE46C16575FFB7D22
-:10F05000BE8BEB81456A9F0BC90D84AF373DBADF8C
-:10F06000D87DC8A0F24B8533E005C9F5C80F9C4197
-:10F07000F2537EEBF036F0A79F092F0E1728FC7B8A
-:10F08000D7BCF3A83C2FD7F3663EC9156520CAC587
-:10F09000569D7E5B252D699813F918AB8907FF8C67
-:10F0A000025D4F8D59772BD3B2E7A25F43B2AA4FCF
-:10F0B00031E487CCF7421CF8C7AEDBA1CF1BDA578F
-:10F0C00087B03D73A99CCF318F230BF47CFC172CA8
-:10F0D000A1C2FF8E15FB9FED73A9EB40053AA9CBAA
-:10F0E000ABB92C6C453EDC037ECE0C2BFA6D63E194
-:10F0F000E861CA1CA1E0E2F0B438E4ACADB0BE39BE
-:10F100007E1743FFCCADB399AB04E6E1FD41DADBFA
-:10F110001AD49977FDE0D235980E19DF2852AB6BDF
-:10F1200048DF13FCFDC46F865CBABED7E8F2162137
-:10F130005D1C129445B47E01D68F72A6EFF18173E7
-:10F14000A3E0B7B87FC5DE02F47B5999968E7EE2C4
-:10F15000ED76F257B10D8CF4CFFA1D8336A19CE900
-:10F160002CF0EEC67AA3AED1FDB65A64E08DC997F5
-:10F170000F27F86345FAB8189CCEE7733A3FE88A40
-:10F180008F2FE5057C9F2E954E320A381C22008772
-:10F19000CDE5DF3E9D00FC4C7C63B78E7F466AC0A8
-:10F1A0006DD464B35F77B7BE8EDD059C7F7416782F
-:10F1B00008CE9DFDBF3C9C8072DF06EB8F83EFD7AE
-:10F1C0005DE6FA7BA3936F8B1F1F4C8C3FCF39DF1B
-:10F1D0009179BE6ECCB334FE3C6FBFCC79C2FE2CAD
-:10F1E00072147CFBF3EC2CD05E2F403994167F9E7A
-:10F1F0003FB9CC7902935B14827A3380FF61BD6F93
-:10F200007BBECC3FB70AE5CF4D5EEEF72F014E8BAC
-:10F210007C08A6F2E437C351AF55D76E40BEB3C2E7
-:10F22000A5FA65E223AF237E031F641ACC67DA6474
-:10F2300081FC489D23BE5C2421BE67B1502AF2ABFD
-:10F240001D76F263C7AEFF67BA9C003AF925C28902
-:10F250004D890C447E7270607C3EF1CBD8FA4D1122
-:10F26000924BEB2AE2EBA5BFD2E975B9A37972966E
-:10F2700025FA5C0516282297F569FD50CE96CB6BD2
-:10F28000909FD8401E215C6DFD06F7C1FD80BC47F4
-:10F2900080B422FBCD03828BE07DA20B7EF9DDE3FF
-:10F2A0001C6FD827175A7BE7E7CBC41747FAE2ACA5
-:10F2B000E7578AF7D582287B71D99637E4C268BFB1
-:10F2C000380B5B18098E08F9AFBBFC057DD865F9D2
-:10F2D0000B0622AE64A27CF0907C40B9817673E389
-:10F2E000AB63CA707341EF6022F2D3E4449217819A
-:10F2F000BE638B9428781EECD21BC45EF4499BE954
-:10F30000FB470D0E3025BBF3B71C7DAF0AF5F8396E
-:10F310002CBC16EBCF599984478F5DEBECEAEF9C40
-:10F3200060D26BBBFB97E87B85C31912C188A970BB
-:10F33000FE3EEE7EFC4AD13EC1F5FDB8BFF629A6E1
-:10F34000B1F0F3DF373E95FC0708BFAB7BEE7B6F78
-:10F35000FB7C5AD14E607FADFD65C39FA3D2395C63
-:10F36000A2712E2CC9871DDDF0BED47D7910FF015E
-:10F37000767D52A1760EFBD758AD0FE733DBA0EFB9
-:10F3800018FD868D4E233F64A3AB63EDCE283ABCB7
-:10F39000D512C9E4723BBC169D4B7FDE9E40FCA398
-:10F3A00073FBEBFDBD748E66E81D49E23749973E5D
-:10F3B0003FC3AF604D8CAF471BE717BBACC585A4FF
-:10F3C00097E0F9EE68C80BCA02B4272599A90198FD
-:10F3D0006FC5B5804DD0DF4431B73D0CEB38CB4E17
-:10F3E000A45D85E0D3FDAA2BDF199180F39C2859F9
-:10F3F0008F47F3A758FF4F5EA1D9FF738ACD4E09FF
-:10F40000215C8AB87FA4F4956B52D00FFAF09489EE
-:10F410007D30DDD9D0244BD66E3F50ECFC2B7AB139
-:10F42000478714727CEF48D48614C2FA2A7A59BFEF
-:10F43000AAD73B94A8A98599DDFD61FD7871106F6D
-:10F440005CA9F37B1DAE37F9E792BE6571005F459D
-:10F45000FE097AAB28A37FB0D04AF4AE3145CE2264
-:10F460007F21DF7FE0EB12E4AFD2F342D307016CE0
-:10F47000B7F176179D7F33AFC2503E0060E83CA0E5
-:10F4800051F091BFC181F11E90AE13D40D22A4A200
-:10F490002592CEE922C8E3199857C2FCEB42388086
-:10F4A000F1016B1C3FFE25FABFB580C41226405EF9
-:10F4B00062E45FF41F4CA6F3389A19CCC36ECC4BB0
-:10F4C000CF27EBF9CEE993260F80F4CEC4C75D8831
-:10F4D000A76101F828F4F355E28F434437BE44D5C1
-:10F4E000DA17FD4A1F535E5891A80AD9E8777215BA
-:10F4F000A19EBA8A25AA7618477396F8715C9BC2BA
-:10F50000C80F9FC85A681D4EE7177E048ACC640155
-:10F51000F33989DEF98564A7303A1F3FFC71F26642
-:10F520005C7F827C2A74377C4A671AD54B8F918F17
-:10F5300099CE9502C56D78A418B9E81510FE7DAA7C
-:10F5400063BF9BE5A5831D94111F859027FB1BE0DE
-:10F550004F1D08B7F26EB87548DC9E33E0E69FE8B1
-:10F56000FB15C2D57FAF5D0E64F4EE6703008D42DC
-:10F570007DBC435EB415EB83C1C42CD85F365F9F5E
-:10F58000BFC6CEF741F26EC5F61F5AB365B4770C0D
-:10F590003C6B1EA8FB217AF1733C58C8F1B02EEDEC
-:10F5A000701DCA3906835AF2C05E4A3E3A12F90605
-:10F5B000C8CB26949709568DE06DC8CDE5ADB7311F
-:10F5C000A4ABBAB6B90CE9F543C13B6037D9238C7B
-:10F5D000ECB19993FD7B2C0AFAB0A6AD75427AB8CE
-:10F5E000309F9F67EC99B487D890E82CC176655717
-:10F5F0007BAA3261DC400953EF857A8104EFD6970C
-:10F60000705DEF882AFAB9EA5755B2CF86EBC80485
-:10F61000DF37CD48277F694665A411E30422F7331D
-:10F6200019E37A7AD0C77958DF48C69EA0B1A09F67
-:10F63000057208F12707F04D90BBCB9FC4F2029EE4
-:10F64000BF1AF2F57C4B59417BC50D23B85F8CA1E5
-:10F650005FACBE5D207F5BC1B4E1A4D71462794684
-:10F660007479EAB267215F587D958AE4A458BCBFDB
-:10F67000B803CBDF66B40EA6F3EF5131F43BAE9B7B
-:10F680006EA8BCAC2BEFABC4F9EEB98D91FD5AAFAF
-:10F69000CB5B13BDE162A14C1B89F8D7D50FC37EAC
-:10F6A0002AF5FC3849A67E727D4CE70B9E8D3FA55E
-:10F6B000F3018B8A7EC946A199E0C3FC3ED2F730A4
-:10F6C0005E06E9256FF6CE5D561C2C83D39DBA8F5E
-:10F6D000D35D39F38808AF91F2FD011C7FE66C37EA
-:10F6E000F199314719C185280FF257A50AB44FB9CE
-:10F6F000030A68DFC73BD42611F04814CB0A126016
-:10F70000BCEAD9029D4B4CAF760405F8E774A00F14
-:10F710008A8392BCEE1980EF33BD023FEF85FCEC8B
-:10F72000283F3C68C3745E36C3CE7C2FC4C1E7DC7F
-:10F73000019C0F1BEDEBD7D84C7E9DEC014E2AFFB0
-:10F74000BA70D261E2138CC7B3E4247A8E217F674A
-:10F750005233F1A9C316D0BF51FF651AE9DB37E96F
-:10F76000F46EF08BE9DAED64074FF798F5E80F7166
-:10F770004F900E6609A4E7CEACBEB09E7DAE50D0D1
-:10F78000CFF172E5C349DDDF15A6903D7D23EA394F
-:10F79000A5F07132E82151FAFDEC3BCFA752FD3EB6
-:10F7A0004F2FFFE60A40851ACE5FEA019EC82F2B35
-:10F7B0006649442F756B6C14F755DFB6DA9A85F8F5
-:10F7C0007C0F5339BE7ED2D80FE6D9AF561B212A03
-:10F7D000DDF0E9571B1490AEB390E710FC2336F42C
-:10F7E000C7CDB0A9B5B8AE19694CF6A7025ECEBABE
-:10F7F0006E23F6BFC6C16411E46DDFF677828857C9
-:10F80000C0CA55C449C01C8A67CB9593E85CA1C99E
-:10F81000328CE2B59A5CC96A747CD4BAD5DD78873B
-:10F82000715A8A9D0D93F5FD8D6727150CE0FCEA52
-:10F83000518191BCF0CF72109C330B789C52668A38
-:10F840006A0BA422BFE17CEA5181C7D73D6AF5E685
-:10F850000CC7383C502BF9FEF076B1749F99AEF787
-:10F8600093A4080120C669ED65E516849B3359C54C
-:10F87000B844A3DFCA44CD8A7CAB72B0302240F0DA
-:10F88000DC242D40FD34C1CCF7AD56BE2FEC23CE89
-:10F89000F763E520C801E2FBE8AF0F9493FC1A3F41
-:10F8A0006004C903EA6795E490ED2AEB21CF323C6E
-:10F8B0002C19FD5BC30064A8AF77647BA662DC9E55
-:10F8C000FF4D89FC69E5D5EACD0BA3F6F5E7037595
-:10F8D000BD7D62640EC541DDA3F6C338A83515DDD4
-:10F8E000798C77AC61CD36C4F79A18F9B8D4B99B46
-:10F8F000F4C8A54F5ABBF197617CA85A80FCA3F6C7
-:10F90000D91EFE20E253DDFC2CC6BE64F26BB89E0D
-:10F9100011C08F910F6985C922F995D96C2E47D9ED
-:10F92000D302FAC544D7AA26947B9D4272B358DE0F
-:10F93000CD2747E8FB759FE479ED6E5C37E84B4FC8
-:10F94000C9ACA71C603ED25F2680DC443D5A689F4C
-:10F9500029E2B81B1743DF788E2F852B317FE762B2
-:10F960007E3ECAFCB7D1F9D738BF5D46FAFF2A31CF
-:10F970006F8D3EAECF0ACCFA987C0FF5C7605F5012
-:10F980006F11901F4279DFC9D014E8605CFB11EA67
-:10F990006F633AA78B583D66B7C519B45890EFFA14
-:10F9A00049EE24B06036C24F2BE47CB6FC00E7B3CE
-:10F9B0002FFB4183165195F5DD34C54D7A20958F87
-:10F9C0008D308A9BD9CEBC75BABEE31F908951A2F7
-:10F9D0003ECEC7757DC1D0E3AA62F6F15AE7231285
-:10F9E000F2AD6BB37BEC9788FD4F6602E98BD729AC
-:10F9F00017E65B9AC19798992FB9D979DA3F76FFC4
-:10FA0000DE3BD04F1088D1830297A907A5BBBD1B51
-:10FA1000911E62F5A1DEE2289FD2F9FBA5C65182B4
-:10FA2000063107E5D758C3CE8AC19FBABDC7E73CA8
-:10FA3000C0BAF1AE0B9FFD9B6EC675803C97D1EEB0
-:10FA400013FE6B3DD1F51AA8278E47681E0CFC1CCF
-:10FA5000F2210BF3619C02F3CAA7114F0DB90B9C65
-:10FA600088F0A47121C7BB5112CFE782228B78198D
-:10FA7000181DABAF7BDDE887D6CA4B282ED690C7C2
-:10FA8000C32D1AE1C908A6A6633D034F46867939FE
-:10FA9000E0C76EC48F7193015FF231BE76543FD4DC
-:10FAA000BB2A9842F8511123D72A9DD324A4F34AA4
-:10FAB00047ECFE6B16ECF71A1D3FAAE47F0E3FAE33
-:10FAC00040FC30E416E8C9F7C5D817F7C5D8179732
-:10FAD000801F615CDFA5E2C7B101971767DB69BDD5
-:10FAE000E7637F39D9B33E31AF277E08ED772E7AB1
-:10FAF00000E93D90CC70DF5F48902B9D30CFFA1A23
-:10FB00001E6F3EFCADC200E6B396BB492F7C21556B
-:10FB10007D8DCA7DBCBCBC431393215FB012CA214A
-:10FB2000FF82DB5389F9FA55500EF547BCE70D60AB
-:10FB3000BEF01E5E5E76AFEFB56494F37EDEFED55A
-:10FB4000638DA20BCA838D7AFB8AE64ACCD737F144
-:10FB5000F6230F0403981FF4001FDFD03BAFD6F944
-:10FB6000E70BC2A9D7EEC2FE807F6E06FE39EE8497
-:10FB700056F61CE417C8160BE2EDC288DF8AF8704F
-:10FB8000D8523B12F187CDF366239ED9D16E15BBB7
-:10FB9000F997059D3AD06E826425BDEF0DC12761AE
-:10FBA000BDC94812286747AB0EE4EF1887BC19E4BB
-:10FBB000CD005D1E1971BB787F606AD47E0D18C8B8
-:10FBC000E5BC512F2B8DE3057B8CE38511571C5A27
-:10FBD000CF04F4B7E0DAC80FD123CED847F23BD830
-:10FBE000BF6418E2EDB5185F0CE5D78EE5F1C56589
-:10FBF000DF9C9E14CF2E2AD6C73DAADF8730BED702
-:10FC000004DD16A49F171079FA62FFFDFF88FAD26F
-:10FC10000B38D65802A99F8DC67DE4F9B103731E37
-:10FC20006E02BC586CF14988472C4F5071FED77753
-:10FC3000F8AEA1F5D43276434E9C75E8F27E51C001
-:10FC4000B699C78770FE335DDFB763F2EC3D7791FD
-:10FC5000FDEC52AD30CEC4F10388EEA7550B06DDA6
-:10FC6000570E443D184F30C89FEDA538F7252C6836
-:10FC7000C34196C4D0FD32E7998F512E2DDB62A689
-:10FC8000EBE52C64E3FEE6C8E31F40FF351B9265FD
-:10FC9000943FCB5BCCF56A36BC754028EDC9076A4A
-:10FCA0000C3E1034F3015038381F583F98CEBF56E1
-:10FCB000648BCAA174F47FF848DE27302EEFEF93EF
-:10FCC000D430D15FBB9DDB51BA7E7EA7C8F5F3046B
-:10FCD000E6509C45C8872D7A9C2ACF1BE3B398F841
-:10FCE0009653CDB711BF31E260008024EF4FF9AFDA
-:10FCF00095A3FD6C5D7C3E86DECBDAFB84F09E81B5
-:10FD0000E16701FD80EC2BB60038DD38E243B46FCB
-:10FD1000C252F87F0CAECB46EB5A9F9447FC7D1540
-:10FD20001084BD0CED62A924847D0EE6F4E4403A13
-:10FD300042FE3ED96C6F2530AEC70FEFE07E9C11BE
-:10FD4000DD72BF01F7D7CE540797FBCD0CE9AB5757
-:10FD50007BC5B932AEBD42120AFA9F3199F3F58BD9
-:10FD6000D92BBDD9235DFB99007A1BA4D3BC09CF45
-:10FD7000E3BAAF3E9F921C2F8E6A5A85E841BB6C56
-:10FD80009A55CB4C8B1727897A7666547DAF93FAB8
-:10FD900093BCE9CF63DC12F41B42FEDFF1A62D6EAB
-:10FDA0003CB2A4F72F5935395EFFD7A2532ACADFD8
-:10FDB0002E79B3A8DF6F415F7971601C7DC5B62BCA
-:10FDC000E69C92F90746C7133CA3FB0347166A6DEE
-:10FDD000D8FE60421EF13BA50CECA97E94A7FE0E56
-:10FDE000DE762DC5479C61DA45E323D644F9CF0F73
-:10FDF000A6C63F17795DE773368C7983716F57B468
-:10FE00007D8857476DFCDCE568A29EBAF8B9D51F1E
-:10FE1000BBEAF3F498C1272DBCFC689AF9BCC6A8CC
-:10FE2000F7B9EE873AD4E0F0AC89F2BF2AEBED3EA9
-:10FE300094D39905FAFD8D958CECE7CE5752374552
-:10FE4000EFEBD98115B62B33B19E66CB4138BEC2DC
-:10FE5000E55F9D14B6E1FE3E7285F7139C779DC267
-:10FE6000B417B11F256CBBA904ED061E17D269E5B6
-:10FE7000766067024F8D799D1D38D576259E23DDEE
-:10FE80001626BED8959F1A26BE7776A087C6ED9C0B
-:10FE90006E94EBF9FFCDF30A93559C6F8543B71F22
-:10FEA0008AE435E47705BD0FFD36B1E7078C8DE7B1
-:10FEB000FAB11EE7A9E5FE83CEF17AF3F35B1C1DD0
-:10FEC0007B7E0EDFE7E8FE606FDB977BEE56087FF8
-:10FED0000EE3B87383098CE2BDFF45BF7E67FF0E5A
-:10FEE0005ACFBA8A48DE63E5142F407EB5E5EDAF00
-:10FEF000135F5F6ED07DAB99EED3AEBCB473B5D853
-:10FF0000F3966F81CEAEB8320E9DFD0EE535E0570B
-:10FF1000953885F8DAA95681FC210AEB684438AF98
-:10FF200010F8BEAC78637EA50DF30B994C7CBE3502
-:10FF3000969F7903A8272C6B6224EFCA58410AC206
-:10FF4000BB7E9F883E04BA67A344F149BC67A344C3
-:10FF5000D9C578CF263A8FF76CA2EBE33D9BE872C8
-:10FF6000BC67135D8EF76CA2F378CF26BA3EDEB382
-:10FF700089CEE33D9BE8FA78CF263A8FF76CA2EB67
-:10FF80001F61BE47C70B08D7091B10AEADABED32E2
-:10FF9000C295F9B5778BB3489C11FEE17D9CE87E54
-:10FFA00096B926D996031CF6668B4C188DF76B967E
-:10FFB0009AFA5D26D6929F00D40E92233EF88FE0E7
-:10FFC0002916939D7CB64D80BD037D68438CFED081
-:10FFD000FE5023EADB4B82E6EFCB5894DFDDDDF306
-:10FFE0001CE8D62BF573A0BEAC2FE27395E85471D4
-:10FFF0009F4FBD27AA76A6BB00709FB7727F64197A
-:020000021000EC
-:10000000BB72FD78DA472B0B2A783CC2CB4F6D14BC
-:10001000837E77F7F9D0A97DBF3DEC857A8B734459
-:1000200019E9CE9E6DDEEF04C5BCDF4945E6FD4E05
-:1000300056CDFB9D32DABCDFB1704ED5CCFBCFC4C0
-:100040002904E765FDC0BC83F1D3279BF1C180EF94
-:1000500068F88FE3AB42F05D04F07D4CC073B507E8
-:10006000F6F6537AC2B9AEED211BEAAF970BE7075C
-:1000700010CE49DD703ECBC6573A09B86C9A63641E
-:10008000B7BE54BECF474102C7E4DC4AFD3E2F3F16
-:10009000DFD1E10AFA0BD90B51E7504DA248FACC57
-:1000A00063C857B58C64E203EA8624DAAF610EDEDA
-:1000B000DF42E625FEB43046AF59EC7CC4867A4D6B
-:1000C000EC3A7136E877A969E77A4DEC7A7BF8A3C8
-:1000D0008AE4503FCEB75B1E537199ED069FF6A29E
-:1000E0001F238375D8508FE98D0F7E2F5B7B1EF900
-:1000F00011703186F0E0A600FD89AB4FD6771573FD
-:10010000FFBCDDC7FDFCCC9F4AF318C5F83CA851E5
-:1001100094BF7F941424BF432EE3FE25C31E8B851A
-:1001200027CB15D6BC0BFD8AAF311D8EAA2858BA35
-:10013000FDF760056AA85F8F3CC3F5A7D18E968056
-:10014000A4F4B4CF0F17E8E7DC921EF77991734857
-:100150009C3FFA396ED2E3EEAE6A1FB507F35DE756
-:10016000923BDEE887FB357EC75BE998BE2B284FC4
-:10017000DD0DE3DF2870BC88B52B03DBC729B8FF92
-:10018000570B1EF2574C62BE5C6E8F0449CE4C700A
-:100190007849AFB538342B9D47E9FE4BC6C2935022
-:1001A0004F5FAADA681E6BE44F27A13F6619D3FDA3
-:1001B000316DE6FDEB610FC5D841B5B0FFD86FAC2E
-:1001C000DD13078F62E201CCF2FE87453A3C198FBE
-:1001D000575118BFF75DA3FB916A1C1B5DFC1C0EF9
-:1001E000E45C2EEB61374908F831745EF135E25B6F
-:1001F000561AD80374DEAFD8E2C5EB313983CED5B9
-:10020000E73BA7115F9EDFD4C3AF4378BDB0F922AF
-:10021000EBD2F58411F80DC6FDF3950AF7A3244E31
-:10022000D9A7617179475EB43E5B6FE3F772992F8E
-:10023000DD745F21BF88EBB9E5BADE54E3D0E15449
-:10024000E46F44FDB84B6FEA612FFE73F7638C785F
-:100250001780D78022FD7C677546F7F98EB18E2F07
-:1002600046743C1D027889C9D738903F2EEEEF1DA9
-:100270005204EDFA1F081F46BA614E85F4F5936DDE
-:10028000C7F68BF9DDEB023C7B741CAEA34D94F9F1
-:100290007D797FE338E8B7B38CE35DEFF6AFDF98A5
-:1002A000D7E878F332E2EBABC4E2947094DEEED49C
-:1002B000E17774B06702B62BFF63AE0BE76BCD6FCF
-:1002C000D9DB17F5E23BB85E0CFB4A7E10D1CA04BD
-:1002D000D44BABC4F3B763FE543693D1FECC48F293
-:1002E0008B2ED4F3E632F21331D5A722AA88FD8BE8
-:1002F000C94ECEBA03EC27E8F7A395F353F15E7F1E
-:1003000056F282D40227C637C15407405EB078F84F
-:10031000BDEC173FFE8F722C9F4D7EE95BECFC9C81
-:10032000D9FDA3BF2F233A604A9A7D0C8EE7A577AB
-:100330000522A922CDAF62D699E1A85FF53DEF1C59
-:1003400086FA590E9EF302488B74FAB8BA3232DC40
-:10035000E7EC865346417CFB254587C7C1C49333F0
-:10036000F03CC4B87FB13EE96D3A0F3FA99F9FE4CE
-:100370006B935310CF0F0E34CEB54299E8B2AA4B0F
-:10038000D05266E23CDF11199E9B9C91B594542893
-:100390003FC9F8FD0A7F8795CE8956DE5FD927CD04
-:1003A000D97BBCFE7F1471FBA636262EAA560AD92D
-:1003B000F03CABF65F8C8B6A058B3BDE7998B1FE27
-:1003C000BA54894943211598E742F5B67D2DC68573
-:1003D000E3A622CB05EF6D6CD0D767DCCBA8C37B3F
-:1003E00019F069E52B157DD805ECD0BA73E34CF70D
-:1003F0001FD05EC3F5D59D9B40DF2BEF3B6143FCD7
-:10040000C67EF00904E35E466F704E29E2F6461D93
-:10041000DE67488FFEAEF0EF5DFD6750F9333ADCE2
-:100420009ED96799BC39CE3CF7E870199C2991BFD9
-:10043000604888699BE28C6BD433DE35E86D5EAD35
-:1004400013C37370DE18171C6FBC97F57AC67C5BFC
-:10045000D3C28B3CFC9C7520BE5BD095972379372B
-:1004600046F1D3B3BA7FA0F57BE13C7A27E33A6E3D
-:10047000C7F6B6CF53FB7B93903F8C944277ECC981
-:1004800020B38BA11FADCFEC9005E5A44157BDED86
-:1004900077379C45D3FD979E70B65179D7BD33A66B
-:1004A000B9842C94438CF481F57F2CB5D960FC631E
-:1004B000161641BE5325E64E7A15F3603F205D1EA9
-:1004C00023D901E90691EE311D7BB2C08676D9A20F
-:1004D0000A1611816F1D7B37AF11E32E95B9A04924
-:1004E0008E0375678DF9FCB186697B93A1DDFC03F2
-:1004F0009E9410E4173C609663C7DE7DD086F6803C
-:1005000030CFE9C3B82298E7A45721BFB0CD46F752
-:10051000B2163D12DB9F590FCED2E56DAC3E7CB2D8
-:1005200048B73B46B29128675E6D68E3EFE6E8F7AF
-:100530001041FFD3E2E189A1073F9938F1AF4504AB
-:10054000AF1611F9D238297EFD5B8B39DDAD78EA23
-:10055000B4CDA5F44E67C7819F14C2F8271A644A28
-:100560005D83346110F49F37C86B1B04ED45259201
-:10057000F705F939F93928E01BE5EBF17E1ACADBFA
-:100580006AAE27D8C5DB6A481FEDC7E400E92F3EF5
-:100590001FF9D32DA09FA462FCC6EDA28BFC0DFC1D
-:1005A000DDA0317F59908AEBCDF8CDCC1710AE7815
-:1005B000C781E1FB2B155A19F2F775539D74DEBF05
-:1005C000C9E2A77E3050EB3E8067F09931BBD07D09
-:1005D0005ED8F2D044B4FBE4F69D21B4579A2C5F68
-:1005E000EEC5B884A6094C0D10B483344E7DFBD4FF
-:1005F00017B07DDE34A78AF74AD7B9B53239AA7F5A
-:1006000085453E463DF364AD85FCA6A7DA9EA0F382
-:100610002AB0EF22A87C9FAACD27BF9911F7436784
-:100620007F71FC862740BEB1A87BDCCB5B3759507D
-:100630001F1F821B15155765CCABF6DE50D6CD2893
-:10064000777F2D911CCDF8AFEB287EC02D2902C2FB
-:10065000F36641E6FAA8AE27CF62C69FE63DA89FA3
-:10066000CE433D19F0F0332148F19A16D6FE12B66A
-:10067000AFCEE6FA20535A46A0FF3A5CABBF4BB46C
-:10068000CC9A8AFA8D714ED01B3EF4E6E7819E1615
-:100690007D08E39E1418F99BEA2D913C9CDF716B59
-:1006A0007CF93A7D10C7BFBA81BE20C9F334263F1A
-:1006B00085F32AF4BA912EEB2CCA0AF27BBDE7A18E
-:1006C000F8904E414E33BDEF2237FF0EF5EE7A8B98
-:1006D000CCED9B035A199EC7744E2DA6F75E4E5A59
-:1006E000C379C44780EF615C56DDA017A649F8DEE8
-:1006F0004E5FD0BB20FFF3413B783E3FBCC802F9C0
-:100700005DBF7E7F9A0470AD1B1C3E8CF937077D60
-:10071000CAF3C3C28B707F8E0C8AF03C1A60806073
-:1007200067067D35CD0FEB3AAEFB3F991A9E83F3FA
-:10073000AC7BF54A4BB47F313C88F3CDE309BCDE9A
-:100740007137BBF546D43F8AC2741FC6A8B77B90E9
-:1007500011B7C9F17FC9B68410C6091BED5876FCE4
-:10076000FEEFD1DB2DD1DFC902FAFB2DD6DB9DAD2B
-:10077000A4D13E1F051E85707965109DF7CC1B9492
-:10078000A6BF7314CE4B2BEE39DE5294F32807AC80
-:10079000E67B6FF70FE27C9B15F3FEEBFACAA9B874
-:1007A0001F5969DCCE800D49BD8FDE2FD8A4EB55D3
-:1007B0007C7F3244B92C2093DC198E76F3EEF3B9AA
-:1007C00065643757C6C78B4775BC5812E0E344725F
-:1007D000147933DD37671AC6A3EC6E4BA07518F594
-:1007E0008F0CE2FA4578502AC78BAE7DE823D038CB
-:1007F000011D2EB900EF926EFC31DA5F6CDD5BFEFD
-:100800004DEBEEB14FE57C7EC67A187B88EF2BCCA2
-:100810002F15F4FCE3ABF576A38D7928440F4BB686
-:10082000DDB581F33F258DEC76F6133E5F87316EA3
-:10083000319D4F2ED7F560D1FFB60DED8DE54D1DE5
-:10084000F4EEDAF216FECE5637DD692BA3E92CA3BF
-:1008500080AF3343D43202448FB03EA2474D8F372E
-:1008600030E34F17BC63E9B8477F4A9AB93F85FA2E
-:10087000EB6D1F3EF8B6F721101F9E5DFC25067E2E
-:100880005DF4E8D6DB15039E95F7A4C737BBF62FBA
-:10089000868EDDFFE478FABD93E577E9F1AA8A193F
-:1008A0008F97B7BA2DF38ABBEBDFDFF290273A9E22
-:1008B000D6DE3AD78FF2AFBEBD82E26A97BFBCF5F3
-:1008C000777E68BFF4F99FBA3098FA98D49C857AFD
-:1008D00071ED536B5D1A9EB3487E17F2CD63417183
-:1008E00072BC7BABEA60415F1FD7C7EAF09FD0FFC5
-:1008F000F167FEDEF81F30FFBF0AA05F21BF6DFD6C
-:100900005B23DA6F7B354704E5F651293C09E5E8BE
-:1009100092B94EDF6A15E306CDFAD4D25FFD344BAF
-:10092000A1E06E7F3F0BE953A17ED8AEEE49AB8AC2
-:10093000F67BDD7BA20AC3B07A1669C4F9C5B6AFEF
-:100940006FF9CC867095411FCC1DD7B31C3809E1D7
-:100950007D7DEB7F7E29BA303DF6212BC5FEA2FCC2
-:100960001100F79A5EF432F760DD4FA9DF0B30E03B
-:10097000C38299A4DF047EBDBEF41398D78927FFF4
-:10098000AF4B288E9697F712BC4EB5CCFFE5AB4A1D
-:10099000EF72F524EA07F69E7A80D2267025BB9D79
-:1009A000A7B5D6900BFD02B59BACAA1F3ED76E7DB6
-:1009B000E2693C57611FD8553C7AACDD7ADA86EFA4
-:1009C0009ED50A5A44203D8BB98491DDFBB46CEB73
-:1009D0005FB8BF2A476453609F96FEF62CAFAFB155
-:1009E0004802D45FF6C227E4DFAAF53A7D8E38FBD1
-:1009F00054D9B2D31676C6D9A7964F26A11E14F89D
-:100A0000F557B40FC77608AC8FBB67FB9A4D7FB123
-:100A100021DD9C800D494FE5F042FBB4BE459C6B47
-:100A20004B89B76FA1EB51FF8372F2835C6CFF843B
-:100A3000C18CD3C5CB5B9F437BA0E643BB3A05C7C4
-:100A40007DEE761743FE2AF938BEFF626D9606E307
-:100A5000D658FD5932A5FC7BCDE377101E2E7EE7DC
-:100A60008E2CD2EB989663194DEBCDC1752EDC38E8
-:100A70009DD6B98879090F6B7EC1FD196725363976
-:100A8000DE3DE32D8339DFB2B3DB4A913ECE424FE8
-:100A9000E8873962633C9EF75DFEFE989DDD981203
-:100AA000FDBEDCDD83391FF1B3E0C7F8EE643DD84D
-:100AB000C5C817C477CE4EC27E56BA259F5DA6F52F
-:100AC000FB757809DFF0780E4532E24EF361BFDE48
-:100AD000A9EA8376B09D9DB2DD528EE7BB4C41FF03
-:100AE0006F543B82DB91CDF64401ECFC2359F1EFCE
-:100AF00011BEDF45F7EC5D16854FF55B8E103E317C
-:100B0000B0BB52B279FE31A443B08B52006E67DEA7
-:100B1000FBCCD617FD1D19163600E7DBF117CA33DB
-:100B20003553C1FA46FFF56D76D37B24F54FFE258C
-:100B3000869EED31EF9CF8089EF52C45417DF388AB
-:100B40002D32691B8E03E362BCE6A247ECA677C296
-:100B5000BAF1C5D6FDDDDD4D9F867DB558A7FFD81E
-:100B6000F5C7F2832762F801DB987949EF3ED55A41
-:100B7000834F237C6A815EFD44AF9CFE40478F0C0F
-:100B8000007AF8FCD9D7F6FF10FD742DD68C2934E5
-:100B90009A99CFD6BC08F48BFE348077828A7CF693
-:100BA0002B1BEABDD9956007C3BC3F77AA7829AD56
-:100BB00027DDC2F7B874EB6474AEF5FF8BBF2EEE81
-:100BC00085BFBE35D87CEFEA2C2B4EC13B0CC79FAE
-:100BD000597605F91562E06BD8BBB17C73F160857D
-:100BE000E01CCB37E1CF7E1605C7A5BFF982F0F632
-:100BF000AF39FC1CACEEC9BF91FC02B046EC80B72B
-:100C000075C12F29BF16E517E5774EC3F3EA9EEBB2
-:100C100036C333B6FC219D1F75DD73BB97F931EEEA
-:100C20002EB25DA4F7173A612E8DA89F3FEBA673F5
-:100C3000C2B5BABEDF29475CA89FAF4D35F2EC566E
-:100C40007C07A6D35F2AFBB17D821E7FE089B85264
-:100C5000A3F4A44FDA4517EA75E1209B1CFF3DC0C1
-:100C600000CD23CC7A2B5FCDEF6B89E79F0BEB7622
-:100C7000BD1DC60BAFFEEA393C373F2439E8DC72B4
-:100C8000C1EA992EBAFFD75EF07F102F16BE017011
-:100C9000447AF26BB61C80F37C0E02303FFC741E6B
-:100CA0002C2697EFDD06F5160180F19C24D69FB225
-:100CB00094795242EE9E7E1390833694FF8B411EB0
-:100CC00091DF7BA3B97C69FBE784674B63F0CC8B36
-:100CD0007896D313CFFA0ED1E9B68C95E9E7BA64CA
-:100CE000CF77EE13E93CFF948391BE81E7BCB063FC
-:100CF000EC54BB48FB73EA592148F186FE4CFE6E6A
-:100D00002BE03BEA59061EC6DAF7B1E989973E1A8D
-:100D100089F7C46A7FF7DFA53F87F4C4EF3E18B8B0
-:100D20000DF32FBF9FF7DFAC67FDCA1D7F233BA6E6
-:100D300073879DFCA19D3B5ECF43B9DCF9AA5D455D
-:100D4000FCEDBCD7CEE31A7624D3FB659DFDB9DF5D
-:100D50002EB0FDABD230C9AD357C1F87D868BF4FF0
-:100D6000B5FF9DE4C8A976BB82EBA8DF9144FEB134
-:100D7000FA571382E81FE8DCFED5C8E877AEFED547
-:100D8000F5D4E9F7693A935935C6CD74A6F238CB54
-:100D9000FA6D639E588DF648EB4E1BFAFF2BFFEB66
-:100DA0001FA5C8973A5FDC6943BE0576E9E30CF0FE
-:100DB000C3F39B9FFED49A83F7C518D9DB277EB374
-:100DC0007F3ABE8BD5132E1C0E9D00075C17C0A565
-:100DD00006F5B2DEE0B1F83B0B8F2FC99EA86D1F60
-:100DE0004574D40D1741E3DF93830E01D7FF8A0BBF
-:100DF000FD469DF920FF555CF757A5A83F5D6CDDCA
-:100E00008DFF53D66D6197B5EEA786F0F7C8BF7B0F
-:100E1000EBE6F83F64089757B174D013CF5FFE112B
-:100E2000E59F4B5669BE9748FF7BBEB3EBBFE47DA1
-:100E30002F45BFEDE5EEFBA1EFECBA2FB6EF6FE863
-:100E4000FB9E2CE3FDBACEEDFFC8A3F55EE2BAC56A
-:100E5000E2EF2A9D5F78DD5DFA91E871E0D35A0FE9
-:100E6000B0508702E9DA5EF414B5D86C8F88BABE48
-:100E7000B1960DD336A15D057A06DA016B3378BEE3
-:100E800009F40791EE0F52B00A6BCA55F97BB6927E
-:100E90008FC990B7BE3F9FE259D6667D8FE597E335
-:100EA0007905F7630456ABDE9DD03E906A51022A65
-:100EB0003E53B5C2BB09CAE5BEA28CF6CD5AE54683
-:100EC00047F43B1692D366B2539C31F64662A1CDED
-:100ED000649724B05D32FAE1135489E2FFEC2CAA46
-:100EE0003DD47715F373EB4416F4CBCECB87D32DDB
-:100EF000C5BADFECF2E1E4A07B95B20E27A669B893
-:100F00006EBB22911E2631B01FF93AB8DD0970542C
-:100F1000A2E0C8743B54D2412E29C3088E604028F9
-:100F20001347235C7D04C7408E28135CBBFBA3756D
-:100F3000C7EEC35A6522CBD7F57141FDF6E13CBC43
-:100F400098FF1E432C9C8DB4C05BB11AF5DF95ABA6
-:100F5000F939D78BBFFF1EE55BADA00FC37CC6A7D9
-:100F6000781715A3DFD1A30948A72BA7F27705CBE4
-:100F7000F11E58069AFA3C0E37C391CB24F25782E1
-:100F80009D41FE4A99A1FD274E642DE40FF448319E
-:100F900071BD32C53D056EE3714FAC8829FC9D16CD
-:100FA00073FC8F7F222BC2B8862AB1B619E7758AE7
-:100FB000253763DCA5CD1ACA23FF707F9085E86FC3
-:100FC000A9F8EB462C77835ECFF03E9914FA18E32C
-:100FD0001BEE145318C55545E05314DCAE3EE760D4
-:100FE00052149C2B58AA297FA2FFE156B413F2FD9C
-:100FF000761983C72A1D39A6F62772CED17801BB90
-:101000004346FBA84A769BDA8BAE7D1FA35DF37641
-:101010009A85EC826BB30799DA5FFFE9898D737566
-:101020009CC575DCF011BFA70AF6D6E36F42BB770B
-:101030001E610CFDC6D72965A6766DBA7F2552655F
-:10104000A5F766BE5F34C6346E5B7817C1A53693CC
-:1010500009781E5C6B0192807A3F502B4CF56E181C
-:101060007D9DA9DFA9DA5453BE76D55F9994CED879
-:10107000B855E719BE1B58166A31B51FBEAFCD541F
-:10108000DFF52698429096BDA704301D7590DF23AA
-:101090001D0EFB81E71B6DE1792AC6EB94E005D0BC
-:1010A000723C16F0546218F2C8A3BED730BD58FC8B
-:1010B00032D3DF634DD4CF5FD759822D73DD18FF54
-:1010C000D3FCE04E81E221B7158F40377473650A77
-:1010D000541F7BAEE5354C5B3BC6378D2DA76B436C
-:1010E0001D247F9D163A17A812DB4B05B27F92860E
-:1010F000DBA3CE5D7A7BA7F3EEB28AB7900ED664FF
-:101100006BCD3B91EF4FFC688E98DFB31E93A548E3
-:10111000349EDF5DE6F933C69D197152899522FF31
-:101120001D8A6B799C4CA3454DD09917E907F22491
-:101130002BC5F1CF2DE1726064C7E6166739DA9DE1
-:101140000E05F73531DD7CCF7BFE687E6FEF8B625D
-:10115000DD3F2FC999B79460FB64DE1E7D7C38DECD
-:10116000140BE9533BAF3A42767AE20D96FE2041EA
-:10117000996BB46A41BB7BE4BE3FD17B04AD53F2B3
-:10118000D7EF82FAADFBFEC40428EFF340D95E2B03
-:10119000D2D9688B8CC7F5ADA3279E2EC4F229EF58
-:1011A000524CA3310FD739812951710F734B141A47
-:1011B000DF2585E91D22D73989CA5DB3554B1EF657
-:1011C000B7CF4ABF5BB3E22AAEEFAD1894B815F1C2
-:1011D000D47540E37150454E6500D143389BF88289
-:1011E00014CEBE2599C753291778CFFFF89611A9B9
-:1011F00028B7D22BD454F47BA66F15BBEE99E17CB3
-:101200001FC4BFF020DDBF76FF3550BE0563D57823
-:10121000790878105B67D3CB9105413E5DD0CBFD5B
-:101220006B675CE3A477174DF587E677D5D71CD9B4
-:10123000DDFDF7D9BA76FF9A6284F7280BC69124B0
-:10124000FE5F2BBD2BB0629093F4871540BF4CE836
-:101250007D1DAE73491781A78BCA0F094ACC3BB9D4
-:10126000A112CCE7E57AF34A005FAF389F42F7FE60
-:10127000CF342590BCBBE2FC0DF42E67AB4DCBBB4D
-:101280008BFC3509145F36F5B6CF37AC423ABEFE5B
-:101290007811C62418EF54D6CB7F25FA37E2EABA84
-:1012A000E087F80A78FEA0A53B8FFCC0D50D4F0D56
-:1012B000DFE35A17055FFC6D97A93A3C676E5D3F07
-:1012C00003E1A32C989C8D74789A39298EEFB4FC95
-:1012D000F40C9CEFE92D560A9A6DD5F9A3BF487F0F
-:1012E0007F20239C8DF7F04BDEB150FCD141C0072D
-:1012F0000DF0A120F44E5A09B6CB90D2309EE1F405
-:10130000F8F7E99D84D3F7300A265E1AB611BC5A65
-:1013100033165456A07C3BA0A4A1BFC1806F8BDEC6
-:10132000CFBA326D6209C947FD7E8836F6B2DE9BC0
-:10133000DC79D557740EB0C60D7A7D2A86189F6B5E
-:10134000C4F72457B8AD248756A4FE755206E27B35
-:10135000852382EF3ED4AF3A43F0856EDCD1F7BEF1
-:10136000A4732253A2E2B5FA0CE5FB2F491AEDBF94
-:1013700074CE46E5B5AB4E139F36DA9FD0CF53F10E
-:101380001D46BC1F54FBB548F74481FF3509C330E7
-:10139000DD655B117D8ED3F265175F1F6AC1F79F14
-:1013A000DE4D44BFE454419E8EF3FB6DE99919185C
-:1013B0001F3035419E8EF105FFABF4239EEF2F4F7A
-:1013C000C77882755BAF9E89F1065373E49F5A40DC
-:1013D0005E6D7B6ED64C2A77CB7FC2FC132577F2ED
-:1013E000F264BEEF752537CDC4F8822A91D3C1A926
-:1013F000A6A4A0FD0274B078D53616FD6E6D8F726E
-:10140000FD77A35835E7735FDCDF8FDEE964851D68
-:10141000141FB6BA44D0E3D08CF35426E3796A465D
-:1014200001D3D0BF9CF17202FFFDA1431D7908BF1B
-:10143000231B6FFF11FA4F970B8CDECBAF65CA48A9
-:10144000A4AB7996F0C798FE66B8B789E34707C59D
-:10145000B72E5EB583E6F789AAC729CB9162CF3F45
-:10146000F52E04F41FF75D08735CF1A7166520F6EE
-:101470002BE970992776CCB1F179FDBC04CF87D2E6
-:1014800076525CB324776479B9DE5444F6527622FE
-:10149000BD0BDDD8F7C3D278BF77D0D200F21D489C
-:1014A000EEC586364AEB87325A4F1F296C53A19FEF
-:1014B000BA035CCE8CECF8D4161DBFF88A2EA75266
-:1014C000F4DFB58A8DBF7D459743C6F9F6F2BEA11C
-:1014D0005CD4078D7DEDDE9750AEBE2F0CE79B915F
-:1014E000FEDAB3F8BE09C6B5DE83E7172F2784D02E
-:1014F0004FDD3B9E18FBC068BCD644CE37222F255B
-:10150000909E14BB8E3F76C957BE9E233A9EF4B67A
-:101510008E23B88ECC7FDF3A8E207FCFECB91E832E
-:10152000BE8DEF067DF76CCFE77FF978C7EFB15D31
-:101530000CEF0CFE53C7BC45FC7E34E73706BC8D70
-:10154000791A706BED25FE565AF58A693D52C744EB
-:10155000347298AD349FF3B796EB18EE87B4AA9D1A
-:10156000EAF5B61E31F90C9DDB2C55980FF5DCD849
-:1015700075D5B2166AD7735D11E2C7CB15CE8F7BD6
-:10158000C6ED47883FD7813D86FAB7B1EE2E3E0DB6
-:10159000EB47FABE0A180EF14DBC3B28A03DE135E1
-:1015A000E9C315784322FA9CCA719B295F25DF6540
-:1015B000AA7F6DF66A53F975CAFDA6F2EF173D646E
-:1015C000CAFF40FD598C3EBF29469FFFB5A97C7CD0
-:1015D000B883F4EDB71B26533CFA84A311D2BB4366
-:1015E0000D32E577356453BABB4121FADFDB504455
-:1015F000E9BE0695BEFFBE6134A56F3668947634A9
-:1016000078288DE51BE51DE172F4E78FCE48A1F344
-:10161000A707867AA795E2D1C27B9162C4BFB107C2
-:101620005A5E43515010FCF263AC775AB651FCE15C
-:101630009A9D63FE703BE4D3DF1459827221BD484A
-:10164000645A14FEB8A684199E77BB187F0F2BB678
-:10165000FEAC521E4756CDC2FCFD805574E2CDAAA9
-:101660001DF21E2D83C44604EDF46AE6233DD4B278
-:101670008ABF4B53CD54568EF6AB97F91EA0F82374
-:10168000F37B021E6DEADADF42F90CBC670AED7FDC
-:10169000E86CA17BE42FEE4BBBA60CBECFF208F4A6
-:1016A0007B1E0776DC778783EC5DE3BEE98796CB0C
-:1016B000D127669572FAEA14D40E9CAF3F95BF57B6
-:1016C00014DBAE545FE7F58108E91F11D03F30BE4F
-:1016D000CCA0CBA9F2217DFD8A25650CD2C76ABAC0
-:1016E000CF50DBA1A80180F798439C2E46005DE017
-:1016F000BE8D3DCAE96024D001C941DD1E34E80039
-:10170000ECA7D7B0FDA9834C453BA271C27F8A6884
-:101710006F8D39130C607AF5F9C8CE6FA07C5C0729
-:10172000FF7DA48BD98F865EDADE504D78B4A3C1DD
-:101730004B69A8A146C74F1FE57737ACA2FCDE0670
-:101740003FA5FB1A9A74FC6CA6F2371B3650FEEDCF
-:1017500086A08EA75BE87B1F5D9EF94B653D2EA999
-:1017600042B72B78EAD1565BE95E3F7C427E528DD0
-:101770007345FCA81182C8BF1BD3FC56CC3726E2A8
-:101780001EE0ACFD54FF66270BA11CA8CDDEC6F5FC
-:10179000B0183CA9C8B889F0649A1EB77A20ADF198
-:1017A0000E1BE0C3899687ADE6F7452F0F2F963ABB
-:1017B000D7D03DBE58BEB804DF9F107BF243C6545D
-:1017C000B5BC9CDFE7C2B8BC4BE5F7B2A543BF1F71
-:1017D000C6EFBBD4E53A29AEF6DF2767645DCEB02D
-:1017E000B958BFCBDE4E3C3807DFC3EB0197187BFF
-:1017F000FBCF57F2F686BD0D7A26F9A13A8322D99E
-:101800005F35EE6617D9DBA3232EDCCF25DB4546FB
-:10181000FAA2C4CF771763470AC6F184F68F23393B
-:10182000B3722FF2A5A5FAF96EEC396D1D9EEF0A81
-:10183000F1E01DA638FA65FAF96EECBAEBC61FA105
-:10184000F3DDBA8BDC23FD53A9391E23F6BE6E6F80
-:10185000F882F103D1EFB79E3CDF4076DAC7A57777
-:10186000AEF78FFFF7EDDFC232CFE7A53C6E9AEE01
-:10187000C919FBD9A8FFFE66E34407DD5BE81C211C
-:10188000D37B379D027F6FA7F36F4C5DADE07B3A52
-:10189000F26E940B57AB36E2ABA3C3FC7D80F178BC
-:1018A0000F31CEFB00571D0A0692B1DD413FF99F73
-:1018B000C6BCE70DE03DDB516F6A229257D96E8FAF
-:1018C000887860C827435E75D3957E4F0E63300AD3
-:1018D0002E9DFE9405A3B351BFEBB25B9D93E85DD3
-:1018E000A2D32146D1A3861F6CF8414DC47B0823A7
-:1018F0000E7903286F1B753B73D409BF9802DFAFC5
-:101900003AE3233B680CD8A9F8FB31786F5A8B82F5
-:10191000AFE1C732F89CC1D78C7B7AB2CDBB05FD55
-:10192000CDECD5047AEF2576DE7943B95F68717F17
-:101930004FDE50E47BFABDBC2AF1FCCE6FD02EE81E
-:10194000E0F101579CEF7C1AED9E952F25D1BDB497
-:101950008BDA07F2E9B8FAA991D65BF8B9C9B04AAF
-:101960006538DA9BA8B7A21D6AD8A5B1F50BCB26BE
-:10197000960DCDC4798DEFD010BF65CB05F1BB7E40
-:10198000D59717B40B8DF1EBB78F90E7459D1FD41A
-:101990000F35CE57FEB977A7AF8A549BE4D8775D51
-:1019A000EF033A2C47FC429B15E5D40F7107601DED
-:1019B00037B310E92BB7E8BF5B712BA8E0D1F76212
-:1019C000E7338DF8C31ED5BB08F765218BCCC17CEE
-:1019D000BD10A9DD0620FC62C238D9ADF494D797BA
-:1019E0002B9F13F57BAFB170BF6B28D7670CFEDF61
-:1019F000EBFEC4F0FFCE3299EE3D77BE34CE82E7E7
-:101A0000369D6F89F45EEA3A0BE72BFE6136F529C5
-:101A100015DF1F997D8DE10FC0F8B258BEB2C5A287
-:101A2000FEE17628F7BF9DCEE2D195915E8FFA2830
-:101A3000E061CAECB094EFA4F7D3D721BCBADEEFD3
-:101A400040BE7205C0FF137E3EC79608E4F76C6B7C
-:101A5000E5F99285A934BF4BDD0FE839A914D6B159
-:101A6000B0551A86743A342D928FF45532E6833489
-:101A7000C189BFC3CAEF4501F89A585AF73CDFD273
-:101A8000E1F997A1DAE338BFA1691DEB1E463DF1EC
-:101A9000250B43FFDF9131772D6251F2F56B75E233
-:101AA00013C82F9E17F4F7E5B6F3DF21801659D13E
-:101AB0007EAA3D6AE5AFB15E0BEA5748579E57E8EC
-:101AC000FEFD5499C3925D93A9FFFE63242FDEEFC0
-:101AD0000119E75043513E703F22BD07F6BCEE6747
-:101AE000DC39F4C3996B90918722F9388F2309FC74
-:101AF000FEF3D7AAF7555A07FA6B711DBFE076FEC1
-:101B000091541FDDFFF800F82C9EFBFE778383D2F3
-:101B10008FC0CEC1F4CF60E760FA09D839987E064D
-:101B2000760EA60BCF41A7B08F15AAF6C6D00BAC88
-:101B3000A3773EC1D7D1D9CBEF2AEDD2E15FDA7AD4
-:101B4000E8DE24C4833691E29A4B5E9248CF3CD9BA
-:101B50003ECAF43BA24077FB711EA56D7FFC09DEF7
-:101B60008F2E6D956441C1FBD4A7B3286E30667E7D
-:101B700008073C27886CB7F1DF3FD2E7FB7C6AC7D8
-:101B80003A6CFFFC4BF938433C7FE178B8DD1EF737
-:101B9000F7818D38B99FE972FB067BA43CFADC30F3
-:101BA00036AE8CFCB963109F0BFF80E3F8F7896CAD
-:101BB00000E1A5D94F91AC723964A425DB6D145FA7
-:101BC000FCFCF6FD377E1FFABB7EEC75A67775FF31
-:101BD000819B9B8978FDB7C71ECEA0FA320E358B4C
-:101BE0006DAA92A1DECD8E9D7B70E9B7C89F54A5EA
-:101BF00042FED66C612FA67315F7A43405E71BA42B
-:101C000071E61755EC45D49AA24EB5F1771C453CC8
-:101C10006BECE28F958E247A0CFAFF01C9CDB6AA3F
-:101C200000800000000000001F8B08000000000082
-:101C3000000BED7D7B7C54D5B5F09A39F34A329395
-:101C40004CC2041220709200060830249390902019
-:101C50002721D088944E225A54D4915A44E53122F7
-:101C6000AD694B9B13122084A04191624518285AFC
-:101C7000EDF5ABA9052FF6AA77824AD55A1B149F1A
-:101C8000A576A4D66AAB9282D87A6BCB5D6BED73E6
-:101C900032732693F010BE8F3FBEF0D39D7DF63E8B
-:101CA000FBB1DE8F7D7600004EE27F33DD83001CCA
-:101CB000C03F54FF4AD630808268FD1239DFD07EA3
-:101CC00069C178433B4008A004608EB7D8D06F52FA
-:101CD000464F5ED00930E1A9CFEEA8F4E0031384AB
-:101CE00047633961EFA76FDF82E5DCA957FA241952
-:101CF000E043E8B862BC09E083B2F55BEEA6972D3D
-:101D00008A2D7B30C08DF43BB67F04E1D72BB05DCC
-:101D100072AD3C701BBE77739604921760F136EB80
-:101D20009148CC3A96813F2D8CFD6EDE6D7C0E1075
-:101D3000B1857D00B7049CC13637C09247B0DD61E4
-:101D400068E77197EEB3B9A97D1958A2EDB9000DF6
-:101D500087731F7D3666BC4919DD77DD8DE34D7ACB
-:101D60007C9EBB19D7F768F9E74365DC67A1D7E527
-:101D7000793F053B4C812927252C25A719B0DF8900
-:101D8000E7A59084EB9A297D911A29C4E73599003B
-:101D9000D9F89E49FE6D05B6AB2F48F0008EF3F7DB
-:101DA00046F9D167AD343E5CE7C77E27E9673ACD97
-:101DB000BA9AE1AB976F35E2AF1701FCAED1C1E53E
-:101DC000EF1BDD5CFEA1318BCB771B652EFFD85856
-:101DD000C0E5DC5720D089E3FDE91F930106D13827
-:101DE0002A4066B49C64F39A87E23A7A7E23857629
-:101DF000E17E8F574E49035AE717387FA98607249B
-:101E0000813ADC0394E37F37EC7C2EDBC7CF551798
-:101E10004EB5EC1F122838EE0D5E9358E792AEE7F0
-:101E2000B23DD17658F9AEA13FAC321D30D45B72D1
-:101E30008DF5F6AA03B1EFEB70882F6FDC76AB2D32
-:101E4000E0C272B3490939FBB6EBEB99B93F4931AE
-:101E5000E1789627ED213BEE6F995B0105FB5B0076
-:101E600094CEC2BEEF0134F17B574A10EC4C30EEF9
-:101E7000721A17E136677F12486731EE5B481BB470
-:101E80001EF53FEDA107F0BDB7D214F0C7CCF35D4E
-:101E90006DDD1FA7777CFF33ECF7F113404FB00ED9
-:101EA000F3693D13F7FCD96CC67252B2A09389EE68
-:101EB000883903CBA38BFFB9E5750F93A9DF743184
-:101EC000B6E7F5BCEE4094AFEE9CB9D581787BDBEC
-:101ED0006C06180A02F165D81FC7A0FA06EFCCF904
-:101EE0002DF8FBA5FB93C2E6B3D8CF06E4452A271D
-:101EF000550B7EBF96E846CCA300F2C3F235A0CFC7
-:101F0000AB907CA0FD53FD99CEDA3737D31AA0678A
-:101F10000BC9878F00C26DBC7E253596FF973FF5B4
-:101F20002DE6CF25D9C8F748EAB04DF0AF03FF9DA5
-:101F3000CC237E0DCD72E27A6F0A23FFC3F9E7FF4F
-:101F400087BDCE289F5F9490CF5FB914EBCB9F9055
-:101F5000BC766C3EF6E468C14F1ADFEB7CDE4B4F7B
-:101F60005B25E64BBDFEC993526D2801BC376974F1
-:101F700091AFF4D4D37C2B9EB2401BAE6FC5B48B13
-:101F800086C48EDF875E5B259063C67FF469FB6243
-:101F9000E217197A06D721FF4C7AEA444655A12860
-:101FA0009B681CE8D0E44DCF08FF0494D726FFEFD0
-:101FB000BF87F301E2F101844F75D6FC1C9ABFDEA6
-:101FC000094ADB6406CB3C07CA89CB0488E0B2B27D
-:101FD000AB7300E1B90DD12521DDCD53EA5EBB1A0B
-:101FE000F178B939F05592F36F79F379FC2B5C2BCA
-:101FF000AD606672CD31E178F3E7D98B693F739BB1
-:10200000055DBF96DEF3113D7F6D5A8AA919DF7B0E
-:10201000CD042D9011DDC76B567F4E90E9A7C6FD0C
-:102020003EE2C7A48C934EA6F42F2F8892DFD7F1FF
-:102030002845E5DF4CC9A9D23CC7DC66A67B4B76B8
-:10204000BB8DD67513840E2838EF326FD846F2EF69
-:1020500016705BA8C4A2A7973E88FE2AFFD9751206
-:10206000DF5FD62D854CD8BFB3B1132C88DFC71ADC
-:10207000F77139F28B912DC3101E2B27DBBC6DA499
-:10208000B734FA32AB263899405FF5A54F4BB41DF3
-:10209000D75DE57086A5547A6CFD28761D3FC85142
-:1020A000FEE945B8AAEB2AD3DF4715CDB43032BAE2
-:1020B000CF49360027C9F9075258CE7FF874A9993D
-:1020C000F0F4E18BD69089EADB2F7AE3361FD781D3
-:1020D000E4CD87195EB38DDA33F2422AB6DF6806A3
-:1020E00095E432EC1272EB9969B7BF43726CE50369
-:1020F0002E93DD24E858461340FAC9C677EEC57121
-:102100006E4266B57BA37A63C9F49F6C7904E9607B
-:1021100089B9E38E4A7C7602C213DD08CFBF9A3AB2
-:10212000C790DEFEF3FDF6B099DEFBF1D85D128EAE
-:10213000FF5C6A207B32E9A92C65482E3E5FFC4A91
-:1021400026B4E1FB337EF2AF97496FDEF46826F3E5
-:10215000974EF733890F713D47910F693DC79ECC6C
-:1021600067BE8BE25FC06129CA034038AEDFBDC9DC
-:102170004FF8BC2159667AB440501946F8DE773DD5
-:102180000490AE8A24934274DEB31EE165EA4B4F9D
-:10219000DEC9667E6F8919F52BD161402E26781C29
-:1021A00035C9451A5F00ADE7C8D36377B5E1FBB524
-:1021B0005AFF28DD1D5EF65F4477DBEC5E3B2EE1C7
-:1021C000A324A3DED7CBCAC9E9DCFF46C7A7602991
-:1021D0008E3E5FD6F0B9B15E080AC98DA266B9F825
-:1021E000562C6FD3E03E63AC7F3AC1F1E6CE4D8F03
-:1021F000BF24D3BCDBBEFD36CDFBBC93E785970483
-:10220000FC8E9A847EE9D5AF8EBFF1F8003B797ED3
-:10221000FDF99FEF7F636200C7FFF3DEF16300E922
-:102220006EA1D4FDFE7D88AF4F5CDDEF7C0FCBC788
-:102230009E7F6530C12F7EBD4B1A8E8325460E7D55
-:102240006432F17E97D03EF0F97F14FB2F9F5CC281
-:102250006CAA10DC16B64DD845F260A654984676A6
-:10226000D3D10F8DEB8B5FA73EBEBE3E7D7CBDDF25
-:1022700042823FEE63F22437971FDBBA3F21FC7E98
-:10228000FCF87813B262F47946F7C4F4C2289EFCD5
-:102290004A9395FA5D41A21E5131DF21F03A7FB198
-:1022A00029D49CCBFDB8FD6A7C4E78AFF234737DA7
-:1022B0009E13F519F65F92F55FBC2E12740ED46B67
-:1022C0009783FE53B7E617D8EFCD15A92C17E6DF95
-:1022D000D861253BB7579EA96F9B4F8E3F73798678
-:1022E000D093DD83817998F427E0E62C589FA6D51A
-:1022F0004D65BF6BFE05C9E7DB52BD129A8CB05825
-:102300008630F1F5310811BCD79A826CEF39480F4D
-:1023100060D966F26659B094CC3D8380E70909BB69
-:102320000A0216AAFFCA1469067C6F8DA73A8BE8C9
-:10233000FF4D70FAC92EBA3C7DED0492A3D5EE395B
-:10234000F3E979BD9AEA6EC3FDB658E50D8564FFE1
-:102350005C2E79C9EED5E1A2EB8FF916AF95E03B83
-:1023600038287B55A4DFE297148789E1EF5069DCB8
-:10237000372CC14C5AD75BCECD134C66B2D342AE8C
-:1023800009B8D9B75FF969C96FF0FDDF81328DEC0B
-:102390008179BF72B01CBF1E64E6F76F80C272FC09
-:1023A0009B10E0FA8D10B17E8AEFFDA1FC7F1ED854
-:1023B0000FD17DFD61EA677BC9AE9F2F7566E6622E
-:1023C000BB5A0D05A4677EE9F8C18E08AE4369B615
-:1023D0004012DA57BF243A25FBFDB02BF400F6BBC0
-:1023E0003D797B6A17D62326617FA9D5C147A9BF4E
-:1023F0006A067F3396D9C9815F101FFE30458CD3A2
-:102400006071B8493E928145E3BCFF8E8BE99DF433
-:10241000EEF558AF406C11BC8E660A7A53FF062C5D
-:10242000778F5ABDDD0A8D7B42F63E40AFCE30F34A
-:10243000FB7052E67554C4E917DF7833BF0FFF9481
-:10244000F9FD693D16837EF14D32071FC3FD4DFF37
-:10245000876540BD737991905FBE41E660227BF055
-:102460002F1A7F2184245A4FF33E53A88D8950D8C8
-:1024700007153A3D42642DD15B254090E81EF6A138
-:102480001ED3E7C9E3FD7FA2FA880EB19DEDC1CE50
-:1024900067484EDA83824FB03E83F6E3088297ECBA
-:1024A0003554C860C17A12BE28E4AE1BC88E6DAB2D
-:1024B000824EAA4F838844F89E4E9046FC5781CCAA
-:1024C000743B0314AEEB74FC1550B9BC04425C5E63
-:1024D0000A61A1EF416EF939CEFFD50F40EC675C80
-:1024E00098E91D1D1937DB8197DC6826BBC3F7F51A
-:1024F000C4FE426A910E174488E7F4E1320B025998
-:10250000627E010F3B3DF745E1E188834712C1C37D
-:102510001B8507CE21E0D107BE023ED314840FCA2B
-:10252000A78BA147A27914CDBEA9062F9735E0E766
-:102530007200B83CDBE4E90B97B248C012284C00AB
-:102540009F1989E966884657BF2E022E75F933BB5D
-:102550004866B8E97208F9338BECD178F9A43FF7F3
-:10256000A5541F97911E7C45E9575A509FF98AAB95
-:102570006FCBC7FA8CC76451AFA8FE451ED667164D
-:10258000E589FAA4EA622BC2ABC9947F650DCA99AA
-:10259000FC80690BF1E5CA26B4AB715F81A43B8274
-:1025A00044C7A60C709BB07FA0A9C45B84F500D281
-:1025B0002520DCEC526E13C1D9FE3DF036E32A52E1
-:1025C000D302138B70FD850BBAD70A7C560F998FF7
-:1025D000FD3FEAB6B2DDB2CE160C129E90DDDD4DA7
-:1025E000E5D1FD7DF4D8F716D3F3C786829BF40BB3
-:1025F00078E462BFABEF7ACC0EE0FA52941B14FF82
-:10260000C0F92A69BE00AA2799D6F5732944F05F5C
-:10261000D93493FD81DF16F8A717C58E8FFB90265E
-:10262000D3BC42CF8127B798E03679AC7F368D7323
-:10263000D485F2358DDA051EFA2B571629B5346E7E
-:10264000FC7373CA17D72EC37996238D909CBEA6B0
-:1026500028F0351A77B93932A2189FAD4E79C7C61E
-:1026600074A1207D927C207EA5FD2E467A24BADEC0
-:102670002FF81539C0DD6BBF227E3DFE9E6B17F92A
-:10268000848893F07FA5F383CFA0594DE35FCDE31A
-:102690004B3D8B882E3F497FD5F627E6CBE182EE76
-:1026A00034B9B5FCE9CF997F9E324350D2FC6388A0
-:1026B000E1BBE54F2759C83F5CFE1708A5E0FB15B5
-:1026C0004F3EDC4CFE4E39FAFFE4272FDDF373E674
-:1026D000B727495F22E896FFF753CFDC477C7A693A
-:1026E00012C7A1A6BD7A389FECA0E98723CD883612
-:1026F00038FAD41BC304FDEB7EC9DF4D67A3C7675F
-:102700004AABEE207CAF40FCDB71BE15A6A0A85BF7
-:102710001D6E95E59EF093176BFBF818BAB72C6009
-:10272000B9A21E28A7FD6449C0F23124FC0919FF93
-:1027300011FFDF7238B496D609D21736923727D0F8
-:102740002FA67DDDF250BCDFD173A09CFC6EF28B16
-:10275000719F4B3B8DEDCB63F543023FF98E222DEC
-:102760001E960339B4AF5FA23FF4C7D134EF823471
-:10277000B20FA7525C2181BCD4FDE3DDC9D55B8AD1
-:10278000D85EEE94881F2A2C89FB5F57A8C5793440
-:10279000FB7FC5FD12FB712BEE1F348EFD648D5F38
-:1027A00021EC65FE7D94F40AD199FC021A19643F6C
-:1027B0008A35C3B6414C7337B59AD88FB14BB77AC7
-:1027C00049EF4F7A70C8CDDF65BA49754316D5A772
-:1027D000CC7FC8C3F655908435FA556C673E9ADEB7
-:1027E0009347F33F9A2E838AF33527F5E4919C555E
-:1027F0009F727849EFC6AFFB454DEEE587276F8D99
-:1028000078049E89CF739F2FDF4A783E867C4EF8EE
-:102810005BE11A33049C64375C9C15C1B259B3D395
-:10282000731F1A97568F70F1D17A63ECEAAE835713
-:10283000A490BDBCD7E24F7163BF6387F20C7E509A
-:102840007C591246E4140FD0FEC69CFC4002B8EB43
-:10285000A56FAB85E1A5D3ED2F1B15F8A395F0511E
-:1028600029F6A1DADD761FD15F6806F9932BBE0940
-:10287000EE36ECBDE2851F373BA8BE1E989A8FD17D
-:10288000FFA8FF07E610D9E33F4C99786725D6F7F4
-:102890007C68117E8AAABC521863C7DAB3CC201BAD
-:1028A000E8B55B5A4AF298E81EE935494E06398682
-:1028B0001E530A320C759777A8E1FDB4B23C437BF6
-:1028C000BA32CED05E0A0D9100AEA7244B7287704B
-:1028D000C5836A8B0CED76A4EB30ADF3536147955D
-:1028E000E13FA16F836C0F5544007E847430F52363
-:1028F000A39D5516E9607F33E990C51007B09F226C
-:102900000EF53F3A7F0D87E1C45F48FF5E9263C7D3
-:102910000E89B893ACC173458ED0CF2B5E90D80E84
-:102920005CF1A199F5C431F0F6E287E4A3CE77F12A
-:1029300070CFF41BE13C64BE11AED901235C872D3E
-:1029400036C235276884EBC806235C7355231CF315
-:102950005BA71AFA8FEEA836D42FDA3ADBD07F6C59
-:10296000A8DE501FFFD05586FE133A171ADA27ED5E
-:10297000BBD9D01E4F5793C32B0CEDF6D4D799AECD
-:102980000E205D99501F143FFFDD38BAB030DC4B8C
-:10299000863BBDA118FCABF88FF05FA1E525A680B2
-:1029A000DA4CFC78AEF03FB518F13F3E8A7F5DAE61
-:1029B000F6C7A73A7E0769FA1AF93342783F569666
-:1029C000C2F4F2F2F3C70E2940F84F8522DCEFDCA7
-:1029D000E9228E22C9C156A2936E707590FDB9CEC0
-:1029E0001264FF4545B3F00152CA71FEE6D7CAD062
-:1029F000DF8C59679D92049698FD4E0E771AEAC5B2
-:102A0000CFEF33F42FE90E1BEA930F8144FAAAE8C3
-:102A10004DEF335496BCA770F8ABF483E033549673
-:102A20007F1ABC9DF46FBC9F7B99DA24A5E1A2A616
-:102A3000FEA3F319346BD03F1BA192DF1BB935D530
-:102A40006B1A8AF0487EA799FC6F403BDA8ACA0865
-:102A5000BA7F43C884050EF1FEDF932E5E43FD4D21
-:102A6000E89F13DE112E0564EF3540B297E0427601
-:102A70000BF961305BD8F36B4D2ADBA349688F9269
-:102A80003DD25CE5677B79160487D3F32B4059432D
-:102A90007C2799D17EC5E7C72F0AAC2C2E118B2538
-:102AA000FAB9FDB8CCFEF774F2A719980A90DE3B8C
-:102AB0004ABFD3FA207CA5427110D265B8FECD6D15
-:102AC0004F5EA952DCC903EE08AE3B204006EDC5BF
-:102AD000811F14A31C3E6272AF2DC6775F9EFAD78A
-:102AE00011648F34150BBBCF2E21A49006862C5079
-:102AF000809EFF2047595D9C198DB3F4473F7A3C77
-:102B0000538F6FEE690C7369717B25A2BBF8B863B4
-:102B1000C4ECAE994CFA6F8589FDCEBFD2E2CA797A
-:102B20009E5496F30EE8B6A7F392D9FFBF46C39B17
-:102B3000D9D1BDE67BF8DEB541616F2D3479D95F1F
-:102B4000BF25EB238EA3D82513F8C81F4A2BDC25FD
-:102B5000E22F7ABC6498742676D6A9F67B4BD6878A
-:102B60008678153C3228617C3D3ABECAF08DD9E7A3
-:102B7000F6AD1EA1D7C8CF3FB23EA71A5213CDF370
-:102B800009C7AFAE091E34F0C5750D6F19F8E07AAC
-:102B9000F55D437BC4D363A57865E4F1EC59145F1C
-:102BA000FF78AFBD94F080F87FBA38265E17593FA2
-:102BB000BE06269ECE7EFFCAEB38DCD8CD78D5F790
-:102BC000FB4EE39B5C8F3446B88CDFAF1E1FD14BAE
-:102BD0001487AD64CFDC2EA1BC207F97E485274607
-:102BE0005E001490FD7FBB34CE4BF46EDB1FFC09FE
-:102BF000B5F734D9DDBB7C1C1FE1B84903D205D938
-:102C00000DE014EF2FB439D80EBDDE27FCE9C35513
-:102C10009F5D4BF66B2EA47A5106127FFC9EE22636
-:102C20000B4C69ACFFD7661FE0FA7BEB41E48D16D5
-:102C300087EF277F75796AAAB08B15EC8FF5A319FA
-:102C400066AEFFFAA2C0FBCC8F8561CE6F2C1F222F
-:102C5000E279E0898C203EBC4DF67F58CC7EBC3BAF
-:102C600040ED8B33D0DF46FAFDC0AC4E34E1FBA320
-:102C7000F7645C6541BC7F90AC7E42164D8E2FF5AB
-:102C80002AF2333FB009FE9DB0E7EFCCAFEF9924B5
-:102C9000F6CFD5274C1CAF0167C456877ED8E69186
-:102CA0008113347F8715ED49A7785E3F211A973D40
-:102CB0006AC592F83F49945F148B3CE4BF8A85FD56
-:102CC000AB97430866F87C8256CE94DAC750FCED89
-:102CD000D8363B90DCC2F915F2B7D4A7441C7F70FC
-:102CE000867F0908BCB8D7E17A3DF9F271E23F8FDF
-:102CF000847E2DEEC3EDCBE571F5782E39B0A9D8E1
-:102D00007EE471FB4EC25FEF7A0F8978D8C7EBC7BC
-:102D100073BC5BA713B7862FB80140B40FDB49ED36
-:102D20004B5F38F20EC5E7FEA338E0F1E1F80BCDBA
-:102D30007229C9C9A5A95D1CA71BE393F93D5C2FA6
-:102D4000EF17E5560BFAE2B0D411E1B8DEA9E2F7CD
-:102D5000FDEDFFE36F766F29E478B53C91E48A3EA0
-:102D60002FAE638C2F26CEAEAF233ACEC0FCA3C7C6
-:102D7000A1F5FA9FEF5F3746CB235CE74FA097A7FB
-:102D8000E9746C4D1CF79FEF13F88DC74FD145C107
-:102D900010C7F3DCE06EC6FA6C0D4E1F5F89FBE1D5
-:102DA00078883299F0BBB4DEE92538EBE30FCE80AA
-:102DB000C0CF079867C6587F0DEDFFE6A0C813E89F
-:102DC000ED487F22CEB93E85E975E9D36FBDF33D6D
-:102DD0009CE5A69F4C2826FDA1BF1F0F6784EF1816
-:102DE0005ACF4249E4CF10BE75347E7C7EE06CE160
-:102DF0007A34A79BF5C2D19DDF09D1FA8E6683DBB9
-:102E000084FCB8F4C95FBD699A4874E20C4B58C29F
-:102E10001E63FC2B5E4FB9217035C9113BCA11B23C
-:102E20006FECFA7BC32D86F766672937FA585F2B5C
-:102E30001B481ED955E1AFE507AAB8BED22AFCB59A
-:102E40003DDD6699F87B8F0542A4C7571ECC50C95B
-:102E50007E5C8976077B3A05415E2F24A31F949EF2
-:102E6000C06E307965AA57A6056E277849DF98713C
-:102E7000DF23B9517F54D797259ABE570AAF6BA667
-:102E8000F17D5A3C10ED4C8E77964340B323B43815
-:102E9000DCFA031C87D0E5B60DE63B28FEB32E73A3
-:102EA000A183FC431987E5F89AA73E0D06B023D706
-:102EB00034A2A4BD285AB7F6E3C7EBE703788D83A5
-:102EC00069BB40C21ADABF7A20D24276CADC177BCD
-:102ED0009EC5B26DC28391D5D4F6C54989EC4887A9
-:102EE0006607703198D629DEB30D5F7BAB09F567B5
-:102EF000B2D7024762F4A00339FF4881362FD903C5
-:102F000059BDEDBF25BCF5B78FF3556E40F81C19C0
-:102F10003D40BBCDBB3811BFC7C32B49C36F52E186
-:102F2000AC0FC9E04D82987DB3DD135397A2F02218
-:102F3000D54DF8B746DB959309F297675A12DE8FA5
-:102F40005863EBE183EF19EC8110AFDF6AF183176F
-:102F5000F767F360BBE11C86AAC5C191804B357A47
-:102F6000603638F5BEC82EFFBFB52F1AD73FF8829E
-:102F70005E9F7A81AF2F7C81E317EA2E6CF829756A
-:102F80001736FCD40B7C7DE10B1CBF507F61AF4F2B
-:102F9000A9BFB0F1AB5EE0EB0B5FE0F885CB2E6C28
-:102FA000F829975DD8F0532FF0F5852F6CFCAA6CAB
-:102FB000073A2B81CFCDA6B7984374CE46AA0973A2
-:102FC000DE384F058E47A7AE07CE57ECF20A3F4AD0
-:102FD0008FD38FA52164F45BACEE6CF2AB77B5DCDC
-:102FE000557D038E73220B174FF9FC9CD7151A677A
-:102FF000E74CE0FC85B3E5FDC314FFCA85B0379C00
-:103000004B713509C23176E935C11408C7F813751B
-:10301000CA2043BDA47BA8A1FF8D5BF30DEDDFECBF
-:10302000186F68FF466BB1A17EBD5A61E86F87DCFF
-:10303000B602CABBB658BC9407B3D0DECAFBC20DF9
-:1030400076DBF83D05FF911F938B9E50EFB8B88F4C
-:1030500074D56618D719D77EAA7C407C3EA1A654A9
-:10306000CB27F47EBF20DE07B72761DC53CF27E8EC
-:10307000F81C6349627C6D5245BE69DD4CE147CE68
-:1030800068719B286FA9E36F3CE83F6E33F99B0F93
-:10309000350A7F5287437A48AD667F74B7A08FB1F7
-:1030A00035E6109DC39D293993699C1092B41BDBB2
-:1030B0004335F59CD7D4E9607CCDA239145F6DCA45
-:1030C000199C4DF184DC1A81F7E5FB8CF8A6B42D30
-:1030D0006D29FD90C4EB4C6FCA28A2BC5D1FF83F60
-:1030E00022E0A99F334F8F83EFD89011FEF1F8397A
-:1030F00053F8AFFC92F0B7D5CA5D69140F5541A6DD
-:10310000F8CB733963CC0C87562FE3A116BB113C67
-:10311000735B81F33AF174D7DE08E19A183ECDF57E
-:10312000861582EF4CA9B09AF909DF1D027C1A942A
-:10313000F3EC3B5B459E16CB641A1FF6C943099F0F
-:1031400021B59ED7BD6BBD2D99CEED7DD664063AD7
-:1031500017BF2B571E4AF9AF5D4F98E6C79E034233
-:10316000ECDBCD59BC0FBBB98C4B8B2815AD048B58
-:10317000680F4B541FB1CA1C874F55A2F6F4DAE40E
-:10318000B8E78A89FA6F28CD63BF344DC930E0CBE8
-:103190005A66E46B04E32B85280747D2EF32D195BA
-:1031A000A093D06B526835C7517A4C8B896EB4733B
-:1031B00015E96BEA81F24E4D39DF9ECF72AAC9C67E
-:1031C000708755822EF4FC9FB555D0613CFDB8BC8C
-:1031D00046FAB14AC34D228F25F8445FC74E459B3E
-:1031E000375B0295E59B6D28F181356E3C3B0949C3
-:1031F000922B1EC17F4EA8077ACF5966E77C3548CF
-:103200008719FFD629008362CE23C4AFF794EBFC65
-:1032100092747EF01CC9999D35E2BCEABA35E27C15
-:10322000E389E7859E98D1EA36B3BC0199E50BD2D4
-:10323000C1DCEC52717E88E0D9AEC91B3BD4A551EC
-:10324000BB4EE7B3A4E155B1748E72E44517C9B320
-:10325000172C1CCF5C6795AB6FA0F672BB7B35C398
-:10326000B3B088D6ED6B41B943F1C26E01275D5E04
-:10327000C4C3AD0862EAB9443A89E1D89F3EE893F5
-:10328000FFD7E1588A70CC3F7338DABC42DFA6978B
-:10329000097DFB5CCEB7F955F721717E265D0106ED
-:1032A000DA7155C07596F45198E4CB2605E50BB656
-:1032B000D76AEDEE32214F7438E78925F6CA934D6F
-:1032C0000B2083F8DE4D7076125CDF67FDDC512247
-:1032D000E00C10E13C67AA22F8649D15BC148FED48
-:1032E00028777A292E98A768F06DD5E065025322D9
-:1032F000F8CA71F04D8DAB9F297CC74CD1E03B18CB
-:103300004ACF06BE9B525205BF8D12F0B13A237CC4
-:103310007EB935D7E25D8D74D8958BF0C6F6D6D7D9
-:1033200004BC7FA8F55F3301B8DE9AB9368BE1950E
-:10333000BB288BE478ABB543A57C552BD11F9FF3FD
-:1033400014E7BF5C1A5DCF44FE5E88EFAF45F944D9
-:10335000F9C6D4B28083C66B2DB480C4FBDFE64DC2
-:10336000B47F87CF669083C3161BE19A1207C7A468
-:103370002FC9FF7553BE1CFFDF49BF62BF75A39104
-:10338000E538DF1872109C6C657F71101DB595EDE6
-:10339000E2BA0CA1D63CDCFF1D4E6167B595D50F96
-:1033A000780E6A972617428D0E2EB737BA51330121
-:1033B000DCD598C5F58E4699CBF6C6022EDB1ABD34
-:1033C0005CB6369671B9A651E1FE527951157F0F60
-:1033D00036876915DC8E4FC061EE3B5F7EAB518F47
-:1033E000E5AAC906B88F6C30EAAB41B5467D95AE0B
-:1033F000E419DA5DDE7186F694822243BD704AA03C
-:10340000794A099D8B9A6A78CFE6A936F4D3CFD151
-:10341000B59589EFA174B8E97AC9A9F1F73A6B2497
-:103420008BE2D8CE32C19FEB35F8B56AF04B5680AF
-:10343000CFC5D80E49DE1010DFAF65FABE03713874
-:1034400004E1D295738542F6419B2CEC742B887372
-:10345000BDB62CBFFA0D7C9E847A8BF2B6B6F929E4
-:103460002C0FEEF038BD748EB6AD6C859BD7E3158E
-:10347000E765DCF82F519C3FFEFC8C6394F1DC8DFA
-:10348000F514E7171F9C12FF3DAF46A7951909E5F4
-:10349000471FF9DA9B5FD96FC8AFB46BF9157B3F53
-:1034A0007248D74F7ADDA9E55760B82F61FFA81D94
-:1034B00025F2071B292E1F937F705526FE7EF3B938
-:1034C0002912AFF3E01499DF7359BA81E474AACFDB
-:1034D00018B7772967363FFEF83C8349FE02CBA533
-:1034E0001B92030789EE9447847D92345CE86D1B40
-:1034F000282ACB2510F90EEE6FA252E4737AE50B61
-:10350000898618BA73F6F16745DE833EA320FAB1C7
-:1035100044DF3F27FEEB99962D8D03E77F5AFAC9CA
-:10352000FF7C3E45FF3E0C7A3CA500BA6B8EF0FB5B
-:10353000BC1FF885095E2DA64DB57964E7F92C5EB0
-:10354000C4005479E57D948F5CA3A4B25E5FE395DB
-:103550003B890F8F2B4E2FE16363610D59F090343F
-:10356000FA59D63F2D74BC26060F7ADE0914A5BB86
-:10357000468733E9DB82DAEE9A18BA583F610BE7E7
-:10358000EDDABEFA20E7F3DAE6FE94F3796BB3677F
-:1035900015505E38C93BEB43CEA3424C5E8AF447DC
-:1035A00081317F77F2A4A8331C28FEA0E5F9C0631F
-:1035B000CCE359647F743D70EEF104C385FE018B4A
-:1035C000C2DF13F4A56FC1D77ABFFEF940D5BF2B78
-:1035D0005D4DE77F5B3D428EB682F7CD00D55F92B1
-:1035E000BCAA4CCF8BDEA4F3A46B875B182F6BB304
-:1035F000EA5B85FD2EFCA556CF6A961BF1FA9ACEA2
-:1036000063C6CA6B3A8F192BCF5BE5FA01F5717669
-:10361000C01CA7EF8DEFE7048D7A477F2F29EBD2EF
-:10362000576B62CE43ADB7F81D242FD678EE320526
-:1036300062E8F9474A606E5949B46ECD9ACBEFD92A
-:10364000737C09D7355B51EACB3279FF03DA019BF2
-:1036500035B9B845D32FA7DAE756ADFF8FB4FEDBF7
-:10366000489F5F14C5CF98516393583E5F22E43161
-:10367000C13C76DEC2B2C0E2D87D10D3F4C205E907
-:10368000744CE1B824B2379A2F294A223CDD3D67B9
-:10369000E0F5E87973BD9F9E278DCF9FDB3C6603E5
-:1036A000FC7795897322CFBA1655FF08417377AD21
-:1036B000A0A7E64B845E1EF388D8475F3A34AEF786
-:1036C000EEDA81ED9FF8FE1439ECA513AE67C4D590
-:1036D00087C6F5CF8B6B1F17D75E14579F1AD7BFBE
-:1036E0003AAE3E3BAE7F7D5CFDAAB8FE0BE3DA6FDF
-:1036F0008E6B5F1157FFAE119FBEABD212C1311E50
-:103700007F7ABFD3C5DF6F7D553F23FA1E03054C7B
-:103710002F3ABD9D2E1EA276AE97E9CC56366E1F6F
-:103720009D8FBB0BED2BB287EEAEAD760BFB22B0BF
-:103730007AAF461FA41F2C5F15F374E59426B13FA2
-:10374000ECF418E4C8A9F06D820C63BB12637FE649
-:103750009D7B7C9F9A3E439A7E1C78DD3A1F174ED4
-:10376000F1BF43708790F02F75BB76A72AF867A743
-:10377000BAB07A33C9DB56B3882F6BF79D64D0405B
-:103780001C070F684A3862227CB712FEEDE4070876
-:1037900079B25193271BC83FC0E749A3825B29AE8A
-:1037A0009B7C888FDFC07A5FD1DF16127ECA4B7791
-:1037B000D2F7611B26943DFC63ACBBFE2141B818D7
-:1037C000EDF3896D0AD92C1D4A46129D174A3139ED
-:1037D0003AC93F5C53DCE11F85FD36EEFFB0F319BB
-:1037E000C4B39C65F326615DB6F49888DEA0D0CBA7
-:1037F000DF9DE13A55F2FDAC953D8D89CE956E9CED
-:10380000ED369173985E2B9B557A6F4AC0548EF0BB
-:103810001BD90A663A479CA186F9AC4D75B9CCF222
-:1038200065D713C850BCDF9E6C82D767EB6DFBA9D0
-:10383000DA3F3E40D2E2736755EAE3A409D2A01F03
-:103840008EC3C816ADAE6EDB46F78F3825511FFF0D
-:10385000C48E05AB0BA3F5EC27760CA77A7BF10899
-:1038600013C9D3744F6AC27B60A6970BF9B96BFD7D
-:10387000A2918101E84B267F6D0896855A4934351F
-:1038800005CB515A296BCFB3447D0AC10DE12937CD
-:1038900068ED1E519EEB79E2C757CADDBA9D38D458
-:1038A000CFCE3F143A071BECC5E9E599FDDB8B68E9
-:1038B0001E739C7687551E4AE70477ACB701DDEF8F
-:1038C000B02307C477C66B6C7C2E142CEEA157B8BE
-:1038D000A2EB0EAD19CCE7CF432630C46F2DE5C265
-:1038E0006E3D5E6ED2EC9E2FC2F49DDE0E2D8FB328
-:1038F00003226E8AD747F1FCF0022506CF0F957F91
-:10390000BA8DE8B32B6751F5167C6F538B99E3257D
-:103910009B5AF298CE691CB28F4EAC7AC54CC1A5A9
-:1039200042E834939D3F8EBEACCEA72B8E025C76D0
-:103930006AF2F967C49F38F16850F8F908E861E065
-:10394000BC511AB89EE0924FA24D22FE91CD0E9C22
-:1039500067D993E95589F4F62DE5BDF6F8624BA9D0
-:10396000E65FC80CDF5BCA13D8E374029FE38D8A5D
-:103970007F29B53BF71D0C0FC3EADE378CF449787D
-:10398000AB8FD133AB35FA747BFD0AE1707669E019
-:10399000DBF4FEB2AD7F3B40E6A8ACBACDF4FEFD51
-:1039A0001ADE178583B3689809DE7035F51FDFB01E
-:1039B000733FC5D10A82B7560FC1F58D51EAAA3DB2
-:1039C00044434AA091C619D51DA97261DDB9F560BD
-:1039D000389BD73391C7CBD3D783F450C774E41641
-:1039E000F17B0DBF847F3A97BC689B800FB667F36D
-:1039F000FE2CEEECD8F5EF9C8974E1EC4B170DDA58
-:103A0000BE3647E10856A35FB339111C753AD5E1BC
-:103A100071ED233D6B2897B920D4FD1CC941FF5699
-:103A2000F74C2ADDA581FBE87D5F87BF99F37C7B9E
-:103A3000BAE9BAA15EF838956E4A1B613F653BE171
-:103A40007DC7AA23D51C97D907C2DF89D3877A6996
-:103A500055E2F30BE23E9C49FB8C7632D2ABB2C509
-:103A6000134BAF66CE5785347D126A45FAA5F956D9
-:103A700009FA0DA92BDC89E8EC414DAFECD6E856EC
-:103A80007F3EAA9F73954F97EBDF9343966484E73D
-:103A9000D303F17D1A78991F900FF653BF0CE20300
-:103AA000AC8F5C25333DE87CB06CDFDF0E0C637FB0
-:103AB000522EA2FBD9F4795FD2E645FA7C91DE5F03
-:103AC000B6B5E700F98A235709FA7C95EE06CB8C48
-:103AD000D219FA8FBFA17E3AFDC4EFE3D71A5DB8C1
-:103AE0004BFDAF121E176D0DF278C83FAF31FF6C62
-:103AF000ED0E2731CB29D5B49F1D1DE0A6FDD8BF03
-:103B00005FD44572E1448389E17A5D61788D19CB98
-:103B10006B468195AE13AACB42B2C9A33CAD31EF3F
-:103B200037BAC3883FA49F3FD23C259E804D04AD49
-:103B3000833696A7FDD04554EFA93AFC57C5C9DD99
-:103B40004F0694BBA739EE774B954F699CD35EC760
-:103B500069F6D3E34D7DE3A6E39289AFDB5AEBF53B
-:103B600038552DDDB7B38BE2A608D735AD03DBABF7
-:103B7000218D7EB76BF47B971637EDD0ECA23B4ED0
-:103B8000376EBAFE5815FBBFAB80E340AB53269AA5
-:103B900012D14DAE6AE4CF910DC9717152A3FF9A53
-:103BA000AE18E3A6F49DE799C44DE3E3A58553025F
-:103BB000E3A796F48D9B42E45D839DB9A655C805A5
-:103BC0001D7E636A6EE2F8E72E8F3914FB7D845EFA
-:103BD000B66B70D3EDC936821BC3B3408B3F7B35C8
-:103BE000789669F0ABE5FA18B2E23C1C471579F714
-:103BF000B177CD5F4870CC02CE1234E53C9895E8A1
-:103C00007C3D64C5D8D148FFEBD66B79B42CE0EF8E
-:103C1000439FCB79BD369FF29A59668ECFEEF2EC78
-:103C20002FF831D79399EFACA07614E07C63DE9B3C
-:103C3000AFD27CBBCAEC6E711F07A4521E48CF4B9B
-:103C4000E8F99CB64C91CF711568F99CB8F9ED7004
-:103C50007D7507CD5F20FC977EE9D9A7E523B43CAD
-:103C60005046A1315FE188CB57C4E72BD7AD5FB891
-:103C70007F9788B3B09C1E73C3D864BFABEF3CEE94
-:103C800039463F6EDD58DD9F7AD091089EA93546B2
-:103C9000BA6CD3F0DE9C29F211A71A1F2A930DFEED
-:103CA000555BC1E9C513F47EE48FBA13F48FF7476F
-:103CB000CFC6CF75F3F8C63872023F77C354115799
-:103CC0006179B26EBDD87F6F5C4DF3AFF47346FA85
-:103CD0003856CD9FE37A6E545EE9F9B0516E1BFB06
-:103CE0006BA3B47BA19AEF4D09ADCEA5FCDADC1E27
-:103CF000CA478EDA2D71DE7D94D33F94E2AA5DF738
-:103D0000CCE2FC78767260C7D498EFE076BBBE9DBB
-:103D1000C579032DEECFF7E3A0FE533715772B645B
-:103D2000F78E05BE4F27392E2F107F0F4E9FFBD8E1
-:103D30002A841ECBBA1A12DE6FF2BBA9426F46E587
-:103D4000AE3F59F8F1B3194E0F74D4270BB9ABE855
-:103D5000F501FDE073256F1FE87885BFEB39E103BE
-:103D60004DDEFE0C2E4479FBBBB2C05B09E5ADA570
-:103D700087E5ED235394B709CFD7D3851E8487EB0E
-:103D800012DFC3E3AAB850F1F098C043A18E873B7D
-:103D90002091FF7801E021B922111ED0BF2278A91D
-:103DA0003E25A52293E2A68A93FAF5E2E3EB89F990
-:103DB000A2E23CE36393868F3BB5FCED460D1F1BEF
-:103DC000081F76CA570A7CACEB838F23021F653A23
-:103DD0003E9E3E2B7C64D46418DADD95467CA4FAC2
-:103DE000F20C7567A1111FC9A38A0CE35D5F218BDB
-:103DF000FB90864F35F4EB8B0FA35F10A0F706F016
-:103E0000B38607BAABE81BABA1F33BBB483667F9F7
-:103E10003BAAA8D4F7B92DCEAFD3CBEB35FC65CDFB
-:103E2000488CDFAF69EDFF2E57E656C4F2E7571214
-:103E3000F3E7E59A1C0D9429F30CF47369E2FE573D
-:103E40006BE37F7D8A72556C7FFCD92CC5D8E5FD6C
-:103E5000EDFB8664E57A7A2F6B86CCF1D4DD4DA933
-:103E60009C3FDB9D24F2656A93D3703FDD48FA0DD9
-:103E7000EB59DFF8A24BA57376741F105A583B6FAD
-:103E80001D9CB70E9B76668C594D70FC56453EAF17
-:103E90002B7F89FF6DCAF328EA51933887B480EFEE
-:103EA0003532850799E83E2C70679C561E09E599C6
-:103EB000B8BF6D2488EF8521C87A50F2433A7D9FC0
-:103EC0006C01BFC89B537FF11D216F3E05C25C771B
-:103ED0004184EB699ABFB7AE2297C74D07D92480BA
-:103EE000E435911CD5F9D4E10932FD7B1ADCA6D565
-:103EF000E4D3599057C91F740EE7EF76A11A54CA3C
-:103F00006B99C0C1F6A669F381CF395FA77F67F8C7
-:103F1000C220F19DE169EEEF74FBB5D0FD7B9EE818
-:103F2000FD7B2D9A3DA0DFBFA75607F93B7275B503
-:103F3000DDDDECE9FB1DF9E6A9819D44877F4F1A81
-:103F40001112C9E6E0947AD7391DFFFF9CE7F19F73
-:103F500038CFE33F47FCD0DFF81BE8D772CAEFF950
-:103F60005FA07ECDAE52B63BF5321E6FB3D1FFA738
-:103F7000F54A8E5787BE37286ACF390F9BD82F6AEC
-:103F80003689F367EABB26B6BBA050D08153868240
-:103F9000DC49D1719CDEE048117F127198A6DFDF09
-:103FA0007E11D9DF3F4C991B49C3F15E3E28EC3F9F
-:103FB000CB8CC836BAC779489ACDBB0BF9EE0E6DDB
-:103FC000BDF6F22977DE86BFD64F376BE71CBC976C
-:103FD00014F1B9A53911B21F5DA516997206CEB8B4
-:103FE000FC66BBA583CF19B7EFBEAB6A1CD039E521
-:103FF000E7DD2DD6BEFB746AF9CDB1526239F89770
-:104000006949422EF98CF7061FABD0CE41A5422A52
-:10401000D991967F2B6989CE05E8A53E7F892752E5
-:1040200043DF5947E8B236C47349595D52B287CF6E
-:104030004774137CABBD6107D9BF0F2F0CDE14FB97
-:10404000DD797B19B8C88ECF9D2ECEC3DEA3482E56
-:10405000BA47E3BE8885EF17BF6FC963EB53B0BEA5
-:10406000EFB0D94DF068F7BFEB4CC6FAC3382EC994
-:10407000BB97778B7B26D505101A8DF06B27EF1237
-:10408000EB7B15E073C0EC90956A57F221FCDFB929
-:104090003853C01B8275743FE7A6948BF9DECA9C27
-:1040A00079222E3C4B3ADC45EFDF576667FCE56B27
-:1040B000E7754C6A1DDF5B99B9C0785EE7BE95DD98
-:1040C0002AE1D75D6E77D33958909CAE89F8BEEB64
-:1040D0002766905835F6F0E4B324A75897579CA369
-:1040E0007B580EAB74AF7126BED7E4E6DB110DE74B
-:1040F00082F66E15FE69DA64A717291DD71B776E45
-:10410000485F5707AE8BEE37768DE2B844C63CE386
-:10411000FAD2E2FC06675CDD5BD97B5FCF18C2F7A1
-:1041200071FFB78B5FE556AF9CC8FF6C6F84EE9A4A
-:1041300098F309CE7EE281975F2CE8DA96FDAC8396
-:10414000EC94E3FED73D848397FE75E03D3A2BF770
-:10415000D2BF5FDCB31CE1F39BCFDFDCFD28EDAF0A
-:1041600061C32B44AFBA3FC66730713DCFD5D91874
-:104170006EFE5AED3CA7AFEB59AB8FDB39CFB47174
-:104180007F12B78FAD845012B68FB528D9DF24BA0D
-:10419000EB96BC4D320D22CE23EAF8DF78ADDF047A
-:1041A00013088F7E89EEBD9829BDA4B8F0FD7B96DB
-:1041B000804CF8B72DE9E4F3EABE95E2BCBA4FA90A
-:1041C0004BE2F3A6F3CC7C4EA4A9EE8A4B46637D6A
-:1041D000CF25E21EAADA95CA953CBF22E825ADBBE1
-:1041E000D4BC92E8325BDCCBA49F372D811EFECE7F
-:1041F00063ACB7B3CB46F266010298D6D7AEE14BBB
-:104200008B1B94F8BA55B2275D5E231E33E2F0167D
-:104210008FD79B743C8E85B18447193A92491FDE33
-:104220000FD049F707DCB3F2B12BE95CDB71358DB8
-:10423000E1D51F3FBF83F6AA7211DDB7E2E0B21BE2
-:10424000ED552AF7A0BD4AA52B5875F54A5CF7E352
-:104250006FBCFCFCD771BAB94ADDA57C544BCB7F4F
-:10426000012C1A518D70BD96B857D4B72BA300FE00
-:10427000E0930CF58D1E4BF4DE7FFCD595ADFD1D56
-:1042800000F5C4764A40B66759B47C9BA8CF253F59
-:1042900024A67DEF1C63FF8AFD31E357E27A97DAAB
-:1042A000B87D63E5A2EDEAA868FBC7D3B03E1CE089
-:1042B000A0663F5EF380D9BF2B817C7BA952D87169
-:1042C000967F834A72ED5319D8BF97CC0ACB77C833
-:1042D000B3C889EECF03407918EB97CB46F95AAAB9
-:1042E000F185C55F055A9E0CBED0E30FF8F3F8EFD9
-:1042F000E6F2BD4B6BF22D7CCF10EA03EF40793B29
-:104300008BC7F297D8FBB97EAAD3C168184DF37F4B
-:104310000A95BFAD623E88B99F01D73DA3E399617D
-:10432000CB711EDFE1648EA74AAECD29344F4B63BB
-:104330002BCBF31F29813D9531718A96F445C52415
-:104340005FF4F332D1FB8DAE309FC9FDF65D75078A
-:1043500080F4C2A7485AF601E8B0A571DFEBB48E2D
-:10436000B58D9D5C3ADD0A0B1BBB25C8719FD94AF0
-:10437000E0C5CA12BA570FDB63F8C4EAC6F70C7E71
-:1043800087F1DE4DD91D7112DCEF29FBA393E66F97
-:104390003F24F8FA9E43F57C8EA1DDFB4A12F1CD55
-:1043A00071BAE0F14BF0894F39C8326CEF1BA9D7D5
-:1043B00010FD3CDE9CC676C5CB2BEFBE8AF8E7BA73
-:1043C000EF5FCEF0EEE51BF5DE11D585317CA3DE87
-:1043D000CB74DDCB375ABD7FBEF944F0452FDF8863
-:1043E000BAAF100CF597E718FBF7F20D8D8F7CF143
-:1043F00070959DDB3F7DF25E03DFFCE1A97B8D7C48
-:10440000F32DE49B0472BF789A46DFE7986FFE3184
-:104410004DE3C7F3C437E9D3B473B55F9E6F864DE0
-:104420002B391F7CF3B8E96CF866585FBE993CEDF8
-:104430002CF8A6DD1DE67375EDF3CC09FF0E487769
-:10444000A5C0FB8C0581EA0EB26B14714FDF4C697D
-:104450004EB6CF437C26D15DD1A83F853E7FF99AE9
-:10446000DEEF33583FFB353C6E2684929DB454D02A
-:10447000CDAB8D22EE3B5372CE5C4A7A97BE23A021
-:104480002BE3E698B8DF65A8F765B20BA1D3948952
-:10449000F3DC83EABD43A62D07EB46F3F861B6CF04
-:1044A000F2B53C80532A14DF3329E2EF5BE8DFC525
-:1044B000CC9B63BC4776C829EC261C2085FC18776A
-:1044C00099F87B2757EAF4D3AB7FD10EC1F5750F6E
-:1044D000B7319DDCA35C36609CA8CFF96A5F306180
-:1044E0007EF2C0349320464559342D93E4CBF664D4
-:1044F0003A2FF1B8047C4E6741F0E75712DFB95408
-:10450000216FDA57FD89D292B067E6D78D7A5A8D3E
-:1045100018F5B41A31EA69ADDEAFBC81F78D7A5A6D
-:10452000ABF7EA69ADDEABA7B57A54DE440C7A7A14
-:10453000F55391ED6A4CFBCB54AF3CB59EEE9A76A9
-:104540007EF4F490F3ACA7779C3B79F3F0F99137C4
-:10455000AF9F95BCC9E92B6FFEFB6CE48D6B5B973D
-:104560004AE99945FDF0C137353D73A042F9158DF3
-:104570000F65A717AF89A7AFAEBA456BE9EFC77C48
-:10458000EA15FE5F7FEFBB1A7EF17A4B8C1FAE7F80
-:1045900097E06A789C9FDFB8ED20C7634FB95EBA99
-:1045A0000834B3AF5E45BBC8C1F4EB35734EFC6C49
-:1045B000D7D13E4FF05BD9B4C5CC4F7FD7E28FF156
-:1045C000F66F579DCDCCF3950939DD9F3DD4DFBC07
-:1045D000DD95B2E1FB0C7DFE78FA45FAFC37C9297E
-:1045E000A4470BDDFF7DBC1BF8EF51FDE7B12DBFEC
-:1045F00056E40B4A2F7A283470A6745AACE133C1C2
-:10460000BE732E2E399FFB3E67FC597C36FBEE9A1B
-:10461000067A5C3B7EDF95E777DFE7CC7FA8BFF8C3
-:104620002CE4D24B95BDFBE6EF5232B47DDFF3AF05
-:104630002BDEA5B8C63DFFBEEAE714D7B8EBF38280
-:104640009D14D7D0EF8F4B83E88FAC7F1F8970719B
-:10465000F9C5772519F362BE2F02F6EFA3DF9F900D
-:10466000BDE1EB6DFF7F727F1CD9274712C4197B18
-:10467000DB6DC6B89E5E4EA53FAA85F4D56EDAC442
-:10468000F1887BD0AF6A42BC75CD13F18876B45304
-:1046900058EECC2B1AD03EDAD3A870DCA9BDD1CF0E
-:1046A000E59D8DB55CEE79755905C95DDFAB4B585D
-:1046B000EFF9BCFEAB7F8C407257BDE7A4E7777A79
-:1046C00074FB44D82F6964BF60BDE3E9B61DB1FE39
-:1046D000CD90E939AC0FF4785547568CDD23C7F8F7
-:1046E00051582772E9F5A3A83E2AD6AEC9613F6AA0
-:1046F0002FD93558BFFFE91C835DA3CFB3D10C8BF5
-:10470000C9AED9B8DB5C9BC8AEA9A84CEC47619D8B
-:10471000F3200E9783BFFF97B4BFF315E59781EDA4
-:104720009AB4E9E7D78FFAE5C5E726FED0CBC79A5A
-:104730003DF323457956932B5F527E6C3153FCF841
-:104740004CE5C758921F8506F9F1F6D9C88F8A4AF9
-:10475000B7212EFAB2AC0E9A4876FA6E3334C99A63
-:10476000FEF5907E05FEFB77DFAA92D8CFB9C70B86
-:10477000FC77FC66490B5E207AD8BBC4CCDFBBDF7C
-:10478000A7887322F7CF13E7AA7EBCB2A89E3E2764
-:10479000DA9472ED86248A6B575A80FACD922A39C0
-:1047A000CE7D5FADB073729C9D97D0FE5FAEB200C0
-:1047B000D1D5A9E2DC146EE778B57E9E4ADAC67ED2
-:1047C00087EBEB16379D5B8D8F5F3BCBFECCDFCD50
-:1047D00083F4127FDF7DAAF8F599C6ADEDD37BFF98
-:1047E000CEC0D9C6AD991F2FBF38E75AFE0E218E15
-:1047F0003E9FB958E64A7F7A2C9E9FBBEA66A54544
-:10480000063817E524FB29E6BE58A725CC7454A129
-:10481000D9514EB29F8AA374D155573AE0FDB329BE
-:104820000D4FBC1E9B174AB174F278290D4FF2F35D
-:10483000CD747E81F665F1B25C7DB81AE57382F1C4
-:104840009E6C0C1E22B8FCB2B1E110C5A9A759BAE2
-:1048500025FABBADFB1A55AE3FDED8CAE59EC60EA3
-:10486000EEB7B9712B97773586F8F99D8D0F717D6D
-:10487000436327D71FCE13F34CB584789C693D382A
-:104880007E0C3F547C80F3C4E0B93CA21ADAA7BC8A
-:10489000D96A682FE9EE30D433FD5B0DFD07D5866C
-:1048A0000CED072A025F9D9E49E71A1E32F473162B
-:1048B000761AEAA7EB2F9CEB7EAB53522DFF447E7A
-:1048C0001D11407A423A4B6F9055CE9B2F167C3982
-:1048D000A4C11BA6FA76978DF95BA74B3EBB6C1261
-:1048E000EB37C5DC47DBE5B2B1BC68CE14F194E62A
-:1048F000EF88FAF66C715E724C8DC88F340F17E733
-:1049000030F53CFC7697C89B9DF0897B3446144675
-:10491000F8928C11DADF7D73568AFC991BDC9C9F20
-:104920006F6E04ED3BC508E73B32C0EC15F7A82BD2
-:1049300032FFDD240B849A70BEE642B77A23C99910
-:1049400060AAD7ECE53F211B32531E91C4132761A7
-:104950003A35BDA3E5E593FE087CEEA0173E9F889F
-:10496000EF121A7AF87EA6210D3D9C8FDBFE7D7139
-:104970008F4D3C5CBBBEFF19DFABB4E33B9F6513BF
-:1049800053EFE83DB7D363F82E6DFBE254BE6F6181
-:1049900047431E9FA3D8B1587C772C83D8EFF625C8
-:1049A000363E87B1A3C16C263979628925A4C33B01
-:1049B000A49F5BA1FF158041BEE8DF73DEA59DEFDC
-:1049C000E9D0BEBFBA433B6FD5AE9D976DD3CE5BEA
-:1049D000B56AE765D7D2F91E3BE919859FEF68589C
-:1049E00021CEF70C07ED7CCF270C670BC299E2387C
-:1049F0003BACB0CF3409E80F1732FCE2BF971D542F
-:104A00009B1C77CECA78EE2A2DEE5E2197D778EEE2
-:104A10002AA5605CDC392BE3B92B7B96F1DC95D5BC
-:104A20005D6D3C271A4BA70854D3AA2D4D4407BDF2
-:104A30007FCF911E0EE6BF17C7FB53280F85FBCA19
-:104A4000AA15743948FBFE259DCE85E493FC0F33EF
-:104A5000BC5D44AFF9746E44E57A92F6FD9B7EBE70
-:104A6000A43F3A3ADBFBFEA5D589EFFBD7CF1FBCAD
-:104A7000A1D94F0BA62BAF4F2F89CEA74E57DE8C57
-:104A8000ADEB657FF2E0FF9789CBFF0532DED6778D
-:104A900000800000000000001F8B080000000000E4
-:104AA000000BB555CF6B134114FE36BB69923669C6
-:104AB0001649B5211536C668031122A6A59588D3D7
-:104AC0001A24875AA2F4E0C1430E39F9E3EE6D537C
-:104AD000158A92D218C173840A160AEDA17F40AAE2
-:104AE000C1736AAB281609B5F42CA87829C437B36A
-:104AF000D9264D36B5170792973733EFCDFBBEF762
-:104B000023CF41CB0F4462EC9AAC0123895AC549AB
-:104B10003214072B4581E92A4937ED2F1A526532A5
-:104B200029808BD98434F574AAA62864A7B6D9A5A0
-:104B30000FECECE2DE18B71BE05211F2DCAE13F022
-:104B4000016B49A9F42C08CC6DD0791CF83D269551
-:104B500010E4C1EDD7EBA3C21490F917EBF79F0453
-:104B600066F84F7AAF7FDC379021FF0B3A503ECF8B
-:104B7000EFDCF172DD9D284C6A144764AB0A85FCBA
-:104B80008D54A19E00C7F78381F6674F5F97157A12
-:104B900077691E3845FB73F65AF22EDD5B1B77A84A
-:104BA0008F62DCCF94FD019D4F0764C85C4FDB77BB
-:104BB0006A142A2448F533C44F4231745A75FADC1A
-:104BC000448B4E714F737DB8A97BF743132AC5F50B
-:104BD000703BB852196EDA852814BE7F89797C7BC8
-:104BE0007DB41141A42E3771D4F9BADA29FFE8DA7D
-:104BF0004AC5CE71C2C6F98A6FD94A417AA7FF6306
-:104C0000B197E393AB69B946F64812EA71C2B99518
-:104C1000F6E2087FDF387F0E605B770A59D55521B1
-:104C2000D7F44121F7744DC85D7D58C81D3D2664F9
-:104C30004D1F1312C8897C3A2488F7DEE8A9CD6499
-:104C4000B8FB7B1129778BE71DAF14BCE6791E8A70
-:104C50000BBB8E7B25F2D3C217D1258AA1E279390D
-:104C6000C1ED5FA46C70907D31A1F9D3D14EFBE210
-:104C70008D492F2CF64D99D76F6F3EB1773F77F75F
-:104C800020B36A61FFB851C74041C41148D8C0EB96
-:104C9000D7EF844BA5FBF97597A8EB50CC597271EF
-:104CA0007C7937BE9B38A87E16EE1704FEA54545D5
-:104CB000A59A3AF0EB89513C2D7515606F0779DEA6
-:104CC000F257CA836992C58BEF3F9F25BBDC868C68
-:104CD000303AE37ACA241197892BA0AC4AAA45DE60
-:104CE000BBE1BAD7B0C790CF980B6DFCB7DF37F3F5
-:104CF000CE112AA38D16A595EDCD2C30DA67CB9277
-:104D0000E0C13504D1DF3D60658EF718F101978968
-:104D1000E7F24826E76EC6D32D4F661C7D8DFAF369
-:104D200067355786E7E11F75E8B61BF92A646DA958
-:104D300092451CCB8D3957601F9CBC1F11B58EC38B
-:104D4000136BAF53239E7985FCF3BC31F26FC1F72F
-:104D500057CEB751CF5F646A81E2944DE33DE421C1
-:104D60006E183DE59940291714751E2BD3F92FD6DF
-:104D70001313EEDBE643C7FBACA58ECE74CE9D7558
-:104D8000E636E64D18613E6F7E0ECD78CB16F96D96
-:104D9000F689C1A339773A79D40C9C590327A2D656
-:104DA000FDDCCCD76C63A823231FAE9B4F47D54DAA
-:104DB00037FEDBEB603E9BF696E9FF01EF5C9276F7
-:104DC00081F371B8FFBAF1D6CED3DE7FE6A9FDBC80
-:104DD0006ACE9563E23CEE3D53FF0BC81D4E69F071
-:104DE00007000000000000001F8B0800000000000A
-:104DF000000BFB51CFC0F0030977F3A0F2BFA3F182
-:104E000057F1A3F2CBB851F99E68FC2634FDE7D1E7
-:104E1000E4591820B4033BAA38B15888838141165D
-:104E200088353850C5F3A1E656012DE805E265AC9A
-:104E300084CD7A27C5C0F05F9681E12890AE06E266
-:104E40004B4036931C0303AF34038307104703F131
-:104E50003B190686A940FA25106F9086E8E3048A7C
-:104E60009D9421CFFD6D42E4E91BC5D4C1B7955097
-:104E7000F993B51918AEE93030A8E941F8E791E4A3
-:104E80009D806253B421EC70550686BDBA0C0C8728
-:104E900095B09B1B0194DF07948FD0C36FBF831124
-:104EA0002A7F8B352AFF8B212AFF9A272ABFC11B15
-:104EB000955FE103A10157D509D0D8030000000098
-:104EC00000000000000000001F8B08000000000030
-:104ED000000BCD7D0B7815D5B5F09AC79933E799BE
-:104EE0004972028710601283440D3884F0147512E1
-:104EF00082C6368503A2E6B7B61EA955449023D2D2
-:104F00009AF6573379125E6D406FE5F779A0DA5261
-:104F1000AB357AB1F5B66A9340BD784B21526B6DD3
-:104F20004BDBA05EB55EB5D18ADA5E947FAFB56724
-:104F30009299C34988B5FD6CBCBD9B3DB367EFB585
-:104F4000D75E6BEDF5DAFB285002FA2480E3F877A0
-:104F50002EC0E92200CC1C2AA373A04CAE04D8209A
-:104F6000048D70312B3F94EABBC2EC1D58F1A55360
-:104F700087BEBB04046AFFB3E2F6783F7BDF31F9FA
-:104F80005B712867ED2708D4DE69E79457820450E7
-:104F90000050DAB95C4DB07E368C6B56B17D87BE61
-:104FA000AD1ED878474B159070BCE2ECDFB73702E6
-:104FB000744F01381736AB2531567F4E323642B624
-:104FC000718A691CA7EE8F8BD05D06F4779CFD6F0C
-:104FD000C3CD4948B071DB267FAB1EE156BAAF01A5
-:104FE0003D02F0957149D0D9F3E920D2BC9439162D
-:104FF00098ACAEEA56DC9A7AE2381D889772ECB526
-:1050000033BE3432F47C898317868F0CBC00CC030A
-:10501000D0A0A2DBC27A00E8FBCC7E4D7B7C2D3E8B
-:10502000BAF14F9C3F1F7F1AE88407503BE389C8C1
-:10503000103C1B7C03DD12C3B7550CC6FDAC490EFA
-:105040001BA7CAD54FE67883F3943B3DEB3F15E1B0
-:105050002CA07908B2ABBF4C7866D9ED66B19963E4
-:10506000E9CC2B673E1FE764FD7F06515C80ED3B7A
-:10507000E356C4458FB2E5C17BD06EAF99DE76C3EF
-:10508000E12784F89989F8B1E2488F0E1D4B61BD84
-:10509000A996CDA7C082012997C8C6843100F9F826
-:1050A0002FF689ACE95548AF634CD696BD1F1BB3AC
-:1050B0009A24F67CDCFCB420B332027769AF84001A
-:1050C000A1293D4E1F599CEEBB6674F433BA3D0ACC
-:1050D00091CE8DAC6C9159BF88B7C391F4FD0CA4EF
-:1050E000A6B353F7F6B37AC492A1B992C6253EBCD3
-:1050F000513ADDD8C8487AA34DFF1D8D2A95ED8D14
-:105100001A74FB015A1BE354DE1EBAE5BBD87F8339
-:10511000E5D7FCAC94BB6E7818EB2D00091C2F1260
-:10512000E3FD83AC6AF76B580713F11E29E5E5B37D
-:10513000881706E7B71826112F3FB6F1A44337F1B9
-:105140006B8BB13407B2E0D32943655E3E0BE84177
-:10515000F6E550DD1FCFF3D47D5AA1A73D4011E104
-:105160008DEA4C54AC10B83C8AC87D60209C0C5F22
-:1051700059E5822D572469FA40379B5F78B662EC77
-:10518000649F6E11BCFC354EE0F4512EA854C660ED
-:1051900060CF71C48B21A637B2B182D34BBABA6348
-:1051A00038A6624C66EB18F4A5B5BC2CFC0595F24C
-:1051B0001BFD0EDC259F3E7E24A92795C832EEBB41
-:1051C000F6FA9D7BECA08AFCAF4E1713E97284D7E8
-:1051D0004AB0C9C3665D1671DE9F1EDC23AFD711CE
-:1051E0009B9FDB41A5F632AE57E5D07A75186CBDB2
-:1051F000907F2AF97A75C8963A9AF57A00C0839713
-:10520000D0205EBA385ECA3F65BCB4F4D627B2CCB3
-:10521000A3DD5E4F190CA38CF0A0E808E7E6264E4C
-:10522000B716A3DB6CF277383C483987E3C9F21331
-:10523000F17EB1C0C75960F38983A70D86589B0ED4
-:10524000239E3A6B516E6D2E1545944B9F169E1CF6
-:10525000B8360EC295E670957DBA7049A1EEFA6C2B
-:10526000FCD89EC18F9B106E4E77B59CEEC44F95B7
-:10527000EE1CB802C80F7C9D137C9DE57F89756E7E
-:105280001F5CE7245FE7F8A7B3CECE7E0EAA518F4E
-:10529000EBB642637CC8E0B856B2942B707F0D0920
-:1052A00070BFC1E800E11FC7F4CC70F3F3BA0E7011
-:1052B0009B10E0FA8674594ED205EF0A99E92C1535
-:1052C000F87CF3A9C911E60169DF40BF0327E3DFDA
-:1052D00086C34DEBF7BAE0BC5988C408CED9301B61
-:1052E000E17C27BC34A71B86EFEFF546B549F601F4
-:1052F000BCDF68ADDFEB3BF1FDB512A4B2E99777F7
-:10530000DA7201D42E85E67F13E3C1E98887536BF7
-:1053100020CAD623DC3C06E70161F6722EEB675704
-:10532000A04976E177B8F90CE2D5F98EA93BFEBC2D
-:1053300013BF1FEEBBBF09C97B0586DFB698588334
-:1053400070A9A590C635F0EF5AD25D08C3C3DB162D
-:10535000FBC7C03BECBAD9EDDE0937B733D30B5AE4
-:105360007CC63E9DD1496B816834C3101C0EBD388C
-:10537000EBE2E071B4EBF2C741FADA7C1E909E09D1
-:10538000BA34FD93D3D53EA4AB33FEF974F5CABF4E
-:105390002E5DBD2E14FCEBD295D220E92F333BA31A
-:1053A0005836B99CD4965BB4FE3836934B52E7F42A
-:1053B0006E94971067F6191F064456573493EBBD49
-:1053C0006000EAAF6AA9574EFA8ABC72325E6F7605
-:1053D0003BFD6ED4715C85C645F308C795C3D01DEF
-:1053E00088625DA17E909C8F9FC2F00477D696F074
-:1053F000EF0CFC6EB8F9C8F81D1B0FD58FE3C5F88C
-:10540000DDE7731259ECDEA1F97BC7892F4BE42449
-:1054100022A36F0F61597FC585F7E1BF93E115079F
-:105420002F8CFECBD04F5230847F73D7F5E4BF086A
-:105430008068905D57D46EE1DBF5F8FFE6E2BECF01
-:10544000F97A7D518586FA16B0FD069F5BC2570139
-:10545000EB7F1374E25B673C299C00A21BBBDDC998
-:10546000D6FF46E4A72CFC7D99C8F58DF76F49FD62
-:1054700019ED416BA3A0DFCFF07AA0F1037889F199
-:10548000E5F2EED314F47B5C2E8EA176CBE7172BDE
-:105490000B5CFD2C076E1702F4CB4B22EE719BB810
-:1054A0001EDA25F5E2BC5F9C23A571FF7B71CE5F00
-:1054B000483F7FD194D288E4173B2ECC1949EE1C8B
-:1054C00068E4F6ACD3EE8029D1FE7E40EE0F67D3C0
-:1054D000E387C64FD3F88BE748DE7D5AEE9771FD20
-:1054E000DFBF197CA83F1F685485972633E317E771
-:1054F000C9E868F99C6205FD0E279BD705B61FCC4D
-:10550000C1AF33CFD6B048F36C0D5793DFAA557BAC
-:1055100087ECC7A3EC39CA83E1E075FC56ADDAD25B
-:10552000ACF850225CDF527CC9ECF6A63D5FA79E2A
-:10553000E9CFFAA4F0B565C0D71EE67A56BB9CCC7D
-:105540006E4F65C0A3C4448F9C885DD625E03E376E
-:10555000168C67A614131A0FA1FF64822D7BC61E3A
-:10556000FE4DD3D50CDE0357844D218EF5DF091394
-:10557000199C5AA1043E56FFB7656B7B7E8FFEBD1A
-:10558000FA10481A836BD96D4D8C5C61FCCDF7091C
-:1055900058DE8A76210A5EEBCB4DE8B76AC54EE746
-:1055A00001DC257EBE0AFD6A327039C0A49C2E8FB4
-:1055B000417F0C9033663879C0FE84E3FEA1EF860C
-:1055C000C353C4964F344F924F4B47964FEB78FFDF
-:1055D00016FB0FE5CBF8A1F1E8FB712B14CF3A8E47
-:1055E000CD78DF6BD3A11F96FC53C729848A00EACC
-:1055F00023913A514B637BE8CA45BF536C950CDD50
-:105600008C6E0A2B3B059F7E72BC333957CBFDC491
-:10561000A6E0E6AB5FDB7268E2D79F1304F4F31AEF
-:105620004C859F8EF586E9D9F8E1DF901EFDAEFA34
-:10563000B26A01DBB5327A2A4539B64C243BF7D63B
-:10564000BAA5B9EEEFDF131DFBD8597FD0E5595845
-:10565000E7EB2FD7896660DADFBFFEF2C75CFF8217
-:10566000758A872F3EEEBA88686B149C7CFD3FE9F3
-:1056700038CEBA9DC81F4DF6BA9506509E6CABCD7C
-:105680002EBF865FB70A01F7B7581D98E92CDFF9DE
-:1056900025C123679D528514186C9DA5E724D24F20
-:1056A000A4B1B3EA77C0F0E34A3125C35EB3FBB3DC
-:1056B000CC3DA56CFD3F07CE5F9F8C72A62E2EC100
-:1056C00046669F41A5EF65B73F84ADF0509DE1FE72
-:1056D000CDAFEDD97B37FA97E6FAC95F9AF9BE0EDE
-:1056E000EB2E7AA891B8FFB4F7B15F9F2AB0710E84
-:1056F0001A7EDDCF1EED17FA5E213F6F9544FB2F1A
-:10570000C2A7CEC2EF81949183A664D6B0F67D95F0
-:1057100002ED9B7E78F68BFF97BE0F517CA36FFE48
-:105720004BDF388B7DFFB9B37DC8391C13F83D932F
-:1057300095807ACCB1FE6F9CC5DAEF3F3B7F44FD8C
-:10574000AA0EE7EBA293C54F78EB9722BDB1F5E81F
-:10575000FDFDAB7577B2F10E424EC28FE51C0EDF38
-:1057600041840FE9BEFFB7AFA01E78C014C8FF7414
-:1057700070CE2F63687F579902E9878BE60B697FAC
-:1057800096792E9A7FFDA489ACBF8411D202ECFDDC
-:10579000FEAAB7379FC5E05DFC1FD2162CDF7A5CEE
-:1057A0002A48960F0FAFF37CB1E97D3EA80743D29C
-:1057B00042BC83C6E310BE981177D3EBA0DE22274C
-:1057C000CC6CFEB59512F7370A9A41FA9C1C56002C
-:1057D000E7315CFB2B87A1DF1C18E896100E47DF32
-:1057E0003E76A1BE64EA897028722289E3489A0253
-:1057F0003B71DFCEBD5877CFFF66079EB849F028D2
-:105800001A8747910D339B7FE9AB363C4E3F009D95
-:105810005417E203D01F1E82AF2D90A8473F8595F5
-:10582000CBFD85AD11AFFFEF519B8EBF6D97AD3EA8
-:10583000C81A470168A6FEABC7CC51B1FF96395CC8
-:10584000EFD0C1207F782BB31361043D6EB3AD77E9
-:105850006CC478861FE31A9A1DD788737D24FC28B0
-:10586000F9C58E968B64C70CD74FC4F0EA43A132BA
-:10587000AFDDE2E82B013D2FC3EFE3F5F3F8C6C837
-:10588000A2A34721BD9E0CFE41BDCE6EB75E4EA9C0
-:105890005A563CA547D4DFFE79F8E3DF877C5D5A92
-:1058A00036B8FE517873E82AB37F255F49A5294EA3
-:1058B0009788BBE9FFD7365D29F96A0AFD9FA00EDC
-:1058C000F73EC8BF0FB3F718BF082774D42B25E0E5
-:1058D000712015F9C0859F3FDBF45F2F8B363FA603
-:1058E00028EE29E829F2D3A9458C7F8413BF73CA17
-:1058F0003FD8E3AEFFF08617883F0A54E20F4167B6
-:10590000FC93651C4B325F9758FB5592F93F58FA50
-:105910003E9292D9F8E44F128FE7AA75095D2DA146
-:105920003822D91F9970F8653EFE950EFC568AE222
-:1059300092A385FFBD51C2EF8CC3E017E59904BF68
-:1059400084E570F00B363C79A037C928D7742E5FF8
-:105950000196E86EBD64B9DD6F9E2D9F00AE8FBBD2
-:10596000F5C02FD8FD8C763E9A3CBAF92C1F9A4F81
-:10597000913D9F0923CD67BCCCD763B9CCF73BB52C
-:1059800026A1C7D9BAE40E4357F364BEDED70DAEE5
-:10599000CBF51F8BAE4E1BE53C9C71D83C66CA9C78
-:1059A000AE668D348F4A1B9E4E09E6BE8C7AF12975
-:1059B0008E7F67A9675D6EB0C7EFF43BEBB2D6B3DD
-:1059C0002ED7D8F818ED7C168C723E370CADCB6212
-:1059D0007B5D1223CDC7D5FE227BFE17DBEDC9EE22
-:1059E000B8419ED28C768625252E95670E8DC7DA16
-:1059F0007D5E2E186AF7E796779BAC30B5BB9CDAD4
-:105A0000D5F2FD8FB54BBAFB032BD28CFE8036B49A
-:105A100015981D53D23AB7DAEEFF2AFAAE6EB0FFF0
-:105A2000ABDDFDFB5BA1D9EEFF5A7CDEB4E023A722
-:105A3000DD2A2FBCA73BED52D84EA81984E37A7714
-:105A4000BB797221CDEB8438C328FD3FBE58B20329
-:105A5000E3FA7910E9C4BC8E7639752FC6FD2D4B5B
-:105A600086FB317FC06F08E8538BCE497D17DBE59D
-:105A70005A7E8DF23FAA530F63DD1221D15249F9AC
-:105A800003941FD020AB9ADFC07C0B03B6B3BA16C9
-:105A900093D39897D326242DDC177F2E2537CB243C
-:105AA0005FB5CB9AB0FF7C9DEBE9D04FFB9603D757
-:105AB000D6D01729DF2197C185FEA7B60CB86E0F87
-:105AC0004DECC1FDF6D60285F464666095A17CB903
-:105AD000510A1AD85F4FC15709DE6D4D3C9F61DBFB
-:105AE000E7BE4AF0DE2600C5696FF3F17C86AD3E65
-:105AF000556BD6B0BFE8B82F53FE438EE6AFB4E186
-:105B000040F83E5B42F0E5835675A540E2AB07EDF9
-:105B1000DBB6390AE9CBDB621555D4DF1C95F4D42A
-:105B2000DB12154DA477CC09924F3E3F6C90DD1AE5
-:105B30009DAD8085F598D1847A66645610735E2099
-:105B4000BF083099002253208D751F747696B232AB
-:105B5000DAC1EC927CEC6F295C8976EF1C8677B415
-:105B6000232CF310DA2561B0FFA4FD26CEDB375ECF
-:105B700002C9185ADF68E7E0F723DA5DD1F428DBC1
-:105B8000758FAE5DA483D9FD3346D1AE7394EDD24B
-:105B9000A36CD7CDDB9DD4DF61707B4F65FFA1DDAA
-:105BA00016C8B067516FF7C4F332DE67C6DF32CB79
-:105BB000CCF8C76BB237AE76B2EF9DB8C7C9E68BEB
-:105BC0004E894138A593B777F4CDE1DE2B8517C711
-:105BD0004DF67DDBB84BE324D7C65DC6CB09F6F3A3
-:105BE00009F576FD52BB7E59BD9945BE17F8F83EC2
-:105BF0005486FE9011D6211FB8FEF80A83FDB880A6
-:105C0000C94A23FB4F32F5DE4C79A7CA5635F2EB71
-:105C1000B604CFEFF02333221F1601F9357D90EA49
-:105C20002C4539016674E19821FEF1994F9BC8CF4C
-:105C300007C64920CCA1F531C87F9E41279974E160
-:105C4000CFF0E77C523A99EAF3C6C9FE5174A274C8
-:105C500048A3E21FA57394EDD2A36CD73DBA76FE9C
-:105C60000E6174ED3A47D92E3DCA76DDBC5DFB5C12
-:105C700085EFE7F058B359CAE09EA77AEAEDF382C0
-:105C8000DEF767853DF5F53315DAFF9DBA7F96EAB5
-:105C9000A9AF6772DEF37E7698EAEBDB7E5ACDB66B
-:105CA000B251F3C97FFF9D7C52A69EC42F3D47CCC5
-:105CB000B0DB32F84AD503F87DBEAC03E64BE5C74E
-:105CC000F83EC5CAAC7EB9BB6DFE4FCB1A95DB64FE
-:105CD0003D80F6E3BFFA3C1B7D1C5E67BE2783D781
-:105CE00091BFAF4AB6BE355C9E470DCFC3942148E5
-:105CF0007998A53566B5C9E492FC0C8F7B65F67B77
-:105D000099927CD8E7B2F7652DC9E379767F1714AD
-:105D1000C8A497C84CAEA1DEA340A2B698E28622E2
-:105D2000F9FBE4F049F68D2297DC2A19016E3B6FEE
-:105D3000955EE90055AFF1718306907C8D403F1967
-:105D4000D339A8F59C827A9A2E007D6F08DC7F3EBD
-:105D50005F4379160BFCA3FBBD8CFA15CCAD703CF0
-:105D6000F431FA95FBC9DFF90FEFF724F006309F05
-:105D7000F70C0A21C4DCF9BCBE788A1EC2B1E3C7A5
-:105D8000A559C03FA1BF24C5D365D1207F281446A3
-:105D9000C92E6B8BAD55DDEBFA575F89378EA6B5F3
-:105DA0005F2F445959B4CAEC1F81CE3FC42018FA62
-:105DB000478AAE34FB47D84F07E397189FCFC207F7
-:105DC000ED4A328DFABB3531CCED7939457EC6F5D9
-:105DD000425EC5C64A17FD1629DD0857D8302DB4D6
-:105DE000F7D6E78B06EAA9326CEE13A6B1EFA43A18
-:105DF0002399458F18FA5E7EDD3D9F3CC5BB4FB6AB
-:105E00009C84DE9DF8E470EF7D8A91CCE60F9DAC1A
-:105E100070BBD617CCFEFEEB62758932F344BCE151
-:105E20007680DFADCF850EE14C4E3E94DF50F4F42A
-:105E30000B8887B682F3E223CD17346F9EE555A217
-:105E400079A65230221C33B2C131DAFC0F8014B370
-:105E5000D186E225A81F096330AFC3F933A015ED41
-:105E60000B667F60DC23586EC07DAC1E5FA026648D
-:105E7000A62F6DA9DC09E8AFF631FD89EC13693E68
-:105E8000D79FCAB83E64B2FF701ED1F923EBD5523A
-:105E9000467DB1E2D59B5B1A1F078CC73BF03B7E6A
-:105EA000BCCC79CD13AB2F520AB2E16374F6F0ADDE
-:105EB0008C5E9872075B1B552ABFD9A851B9A531D2
-:105EC0004EE5A64646ECE81F6D2CA3FABFE1A7738A
-:105ED00091CF531DC50C7F1DF1FB5EB812D02E056E
-:105EE000DB4FF08505A82F6FC43AE901CC0CC4FA4A
-:105EF00004FEFE7A65D102B4F337069CF6D50B504A
-:105F0000AF1EAA5FD45285EF6D3F43877239B5BF8C
-:105F10007502D8E7184CF522D7BE77B7E2A379E02F
-:105F2000DEC2BF3FB705FB0BC84E3D45F00CD63176
-:105F3000E08A7595D77BDBAFA7FE4904B0F1FEABD5
-:105F40007DED02F42FDC3A99FBF961D9D293E0910F
-:105F5000FBF53FC2A02FD2E5B23CCA5F5118DD94D9
-:105F6000B047B7E6DA708FB21F90937CBF7B2EFBF1
-:105F70007E39C43727D9D76C384ECE0FA6ED874867
-:105F80008285E3FE8AF3C53F7BDC5B7D1F0F2FEA32
-:105F9000FCA489DD476BBBBA71A9E729C91F22DDC3
-:105FA000E7D4F4D1B6A2C4BBB9DE30CAF1B72A9A9D
-:105FB0001D8F4A92DDE4E0DBD13FFE94B19EBE9896
-:105FC00049F9478130E7C3D1C2FD071F3FC7E3F45A
-:105FD000030F568C1B49CF8AD589A88C0DCA8DBC5E
-:105FE0009AA0A7AECDCF43236DB01EAD2CF4D4C381
-:105FF000E5259EBA4F3BDDF3FDDFBB5EBFB4F54543
-:10600000A7FDBE8CFA9399F31C65BF4EBDA77F8197
-:1060100058C6D6E1F9F912C5439F9FFFD26D3318D8
-:106020003D3E6FE2EEC9ECDAFA161FC633FA980A63
-:106030005289FB7052B2FDEA3001F1F92BFC171BBB
-:10604000EF97F6FEF7AC7DEE876DBC13F09CD4B3F2
-:106050000BDF2FC2F57BD607B65CEA24B97070B0AF
-:10606000CEE5C2C100AF9FE9DFDE8272A04FE075CE
-:10607000D1BF7D01F73B6E6E3F9FE92F8BF19F6C87
-:10608000FC65F305339D657F0BFB15271F32EC671D
-:1060900078326B4C5F01E6BDE9407AAB1F12A49FDA
-:1060A00035805525A2DEC3E88FE2DDB236211B7DA7
-:1060B0001C6CE4F9027EB890F4FE65F3A7FBD0A84F
-:1060C000F727DE96D14FBA3821F8C0D69B35177C1A
-:1060D000A2299848DF89F9FE9DA83F2764461259F6
-:1060E000F691C5A6DFB35F196C2C84BF4FB0F914CD
-:1060F000B409EEB893E1E7764FBC7464BBC181DBB1
-:10610000A95F38FFEDBDF9E86FAC158CC9D8ADAA11
-:106110004DF862C4DD6FC8891347B0DFE7EBBFC439
-:10612000FD1A8C2ED0AFFACC91AB7D149F5D96EF0B
-:10613000E1BF6575DEFCB6A535214FFDE2F923E729
-:10614000D741D29F21D72CFBFCA548F278E361818F
-:10615000E443CEC48134E667C2F312703DD0F1C38C
-:10616000CE233F6C74FC808EF9A2F0C79076BF4BB3
-:106170008EB666E021B37CC2CFF55B39AF96E2DC28
-:10618000EF1F1174F4A70A790D5370BEB26236E3A3
-:10619000B8ADC5621AE3DF37966C5371BD37947E94
-:1061A0003C7DD017E3717FDDD22A90FD87FB2E6DF9
-:1061B000F2BCB6CCE7D7FA79DCA1CD5AAA9522D3A6
-:1061C000ECD5AA70FE8122C87ABE94D1FFB57EF2CA
-:1061D000BB5BC0E3EC09D2AF4BD5E5947F2B178EA8
-:1061E0001CB7CDC49B6CC70333DB3D68D363E99C0C
-:1061F0009DD4EFFBA78DDCAF83970F0C11FA102E07
-:10620000A657607B15D87C18FE3795F1FCDBD6F2DB
-:106210004709CF9259457AAD4F4B99D86E53F972D1
-:10622000A2CB36D6269F0D9D5BD345E733377DC87D
-:10623000E3140FFAF7B6A05EB1A9E71AC07CCA60F2
-:106240003C0D283F364DBD4A453C6CDAC1788BF495
-:10625000992E72CE856CBF78488334B3A840D6BBE4
-:10626000BA512EC8B56098EC556FBC1A70DD365522
-:1062700072D6CC4FA79A3004B4297EC8C4F8446BB8
-:106280003D50BE4BB0CCAC2D46F8C789240E7448A7
-:106290007660BDB54EA6F9B46B1C2F68871D77F2EA
-:1062A000BD302FA694DB61A5E8EF67E32837F3F94B
-:1062B000EBDB4BC96FB42957A9473967DAF611D31D
-:1062C000532CF4F3B7366859D77DB3987CC0EF925E
-:1062D000EFB296A0FCA64CFCBCEF83CFE0BC5BA762
-:1062E0008BB0338BDEF1233FB74BD2C6D2C52559D5
-:1062F000C679C2AF7BF611FD0385E01DAEFD503BB4
-:1063000099FCFB68805CC0E65150CBFDA690717E85
-:10631000350649B273C782D584FCE89C5B1D5F9348
-:10632000F84D9295526419E5D50D778ED5C9E75C85
-:106330003E07EC3FFD92DFB1F95EB3CF0788B7733C
-:106340008FDDFB34E64D39F606DB979E7E92BDBFAE
-:1063500092A96558BFE6F05405F3809E2F9430470C
-:1063600006F9278A74F826889487F6261C8ACE7048
-:10637000D1F9FFD8FB0E4A5694232DB97C5E72B832
-:10638000BD4F8AE27ACB56BF93C747F60FCF6787D8
-:10639000307BAE52165213C9BF0E9E37E4E4497EDD
-:1063A000B9D39B4774F5766FFD2A583A06F9E6AAE9
-:1063B000DB7C9066FD5EE3CEFF62E3FFD2CFF58328
-:1063C000AB21D58EFBCF7A5BFF5BFDA3A90AD2F58B
-:1063D0003533B4623C7FE1CCE32FF6BABFCEF8543C
-:1063E00077F1FFCA589AF29233E7F7E6EE05DD49F6
-:1063F000567F499753DCDEF6CE73BDAF6F11E67D55
-:10640000595B7C8EDEE0C9775CB9ABCAC4BC31860F
-:106410003D3DDFFB3DC1FFA50EEF7C4F868FCCF9E4
-:106420003BFAE070F3517665D72382AA376FAA450D
-:10643000E57147B34586C039279E8BB6AA5374AE23
-:10644000D96AF66B2D318A53521CB081110EC6F9F0
-:1064500066A83ACF730F4C4C039D3F48CDC673E1FD
-:106460009FB4DF392AE7C37F74BF670FD3EF6AB5E4
-:106470005F41FE5C2377D60A2543E702023ECB1C30
-:10648000CFF0ED7F7C49F778F0B4EB1865BB7D78F1
-:10649000F47914ED6AC511FA7BCBDEB7FEF3C16F58
-:1064A0002BB87FBFF9C0914528E7AEFD89042A6B60
-:1064B000F7D68311E8A67D27ADA03C5EB95BA2F5B7
-:1064C00007B97BD6859E3CFB169AFFB50F47687FC0
-:1064D00058F9A83F5DC7BE5FF9C397A601E3DBB7D4
-:1064E0009A079E1E8FF87B40E0F90C56FFB40BD93B
-:1064F000F395325C9E2D1F21A972BE7AE33F42F5CF
-:10650000B8BF0BBB7ABE48FD765DE2F3BBE4EF2576
-:10651000AACF6947FAA3F53D213D59E0F065CBCFFD
-:106520007BE37B3CFEB4F2715F1AF31557EEDAA100
-:106530002459BB35BBDE26FA5EF0F04351C4C39A42
-:10654000C7BD7ADAB50F7FD83EAF92CE390DD4A150
-:10655000FC938E51FDA8A90E70CD9FFB67AE238ED4
-:1065600065EDFEFDD5F37EC7DEBF1E9720C044CA91
-:10657000EB7DFFADFC04EBC9708A8932D6BFEF45D5
-:10658000371FAED9F5129D37D24418283A0BCF41A8
-:1065900064BCCF680F30A0A03C5CD3B5E16D94978C
-:1065A0006B76BFF95BA4BB3520BFE8E6E7D7F11FE8
-:1065B000E34E8C6B75A85E3FCE51D83F0BED16D8DD
-:1065C000959FD55E74E25A0E7F5FFBD0D17B508FD2
-:1065D00078E3D1FFB907EF6558F5D15FEEC1FC56FE
-:1065E000782AA0A1DC5AF3C0AFA2E0C2FFB76DF9D0
-:1065F000F0D6F7BEFB9D3B181EDEFA8D9FB0F6D697
-:1066000093AF4EC4FB39DE7AE4AF6350FF58F7E432
-:10661000C2B14867EB1E5B3076A4F39F48B769BFF1
-:106620007B7DD3FC5E83C705DC04D9866B9719EBB1
-:1066300002FB0714D47BDF136060632E7BDEF5A1C1
-:1066400082FACBD3260C209EF6EC7EE9E9AFB3FAB2
-:106650009B6C9DFC59D689CD7FBC48FB1B631F56A4
-:106660005EB7FBC2C5675762E933B0FB353040FB0C
-:10667000C609EBFB1C5BDFCAA1F5CD7C7F148E291C
-:1066800088FF350FB2F59C86EBCAD673DA89EBF931
-:1066900026FE63EE89EBD9AB7AFDAF4761D5BD77B6
-:1066A000E0CBDDF959ED5B673D573F76D1887AB98C
-:1066B000231F4E86673AD7CBE0FA866A1E520B90AC
-:1066C0002EBEFF9D3B627C9DEB1862DE7AE8E844BB
-:1066D0003CB4F19A6FE08B88878127FD1AEA512B31
-:1066E0009FFC35F1DD5B8F3D4BE779D85F5460FB54
-:1066F000DD5B30F8770858FD3A815756EB03E7FD2C
-:1067000096F5BB9A756119B47EE7FDB612D74F1D99
-:10671000A0F5482FA9D551FEA60B68DED7A5397F75
-:106720005C97EE59867EED4CBC87034E5EE1D0BA95
-:1067300062BCF9BADD47CE43FA1B6E3D9DF96B385A
-:10674000FFD9ECFD7D5EFE1D965FEDF57D6BC7FB11
-:106750000AEA57DD3F513491D9ED6FF9069442DCD6
-:106760006F1E91343C679CB9EE43F86FCE7ADE38E9
-:10677000B3CCA40F25903D8EEDE0E964FC7EF2F9E8
-:106780007D3CFCBD6BEF9799787CE358F6FDA02427
-:10679000C0EDB9EBA0B31655CCCCFDCC07296B7C72
-:1067A000F110BCED5D12C9F9377649148FCB9417FF
-:1067B000D70D639F19CE388FF74C43B9F646EF7F5C
-:1067C000D874C9E9FEBA078F2896BD3FA45DF85D6D
-:1067D000339CDFDBEE6FCD13D9FB5BF3E0DB59FBC2
-:1067E0007B5D362F41F85FEFF3517ED2EB5D525661
-:1067F0003BB734E0F3E85DED91592FE460DC201AFB
-:10680000A4FCAB9666F3D7E82FB50EF96C3F80F188
-:106810001AE65DB5448274BEBD257A15DD93E4F4B5
-:10682000D79A8127399E20FB498E252A792C2CED79
-:10683000896FF91841B8E106D92A42BDFF40F1AB92
-:1068400032F68B7E15DD65D71F94A10DFD2A074D0D
-:10685000C168822CFE8D8CFE13F325D0DD7EC2EE46
-:1068600071E2BBEC7BFF73521A51DB00A96E3A1F39
-:1068700050045DF767E9EFAE469DECE7E2C4E5E45E
-:10688000FFF1A75226EA6B45EBB412511F7EDC09DB
-:10689000296F1CBB9051FEBB38CE3E1FE983B0EB85
-:1068A00081071E18C3B714D4CB9FC692C9BF7357B4
-:1068B000E84558BFCB9E37E3013ABF38C14AC828E4
-:1068C000E784D812F2832D4C25E4E5AEF55C18136D
-:1068D0000A713F4D0F73FFD30F037CFF6C6ABA98A8
-:1068E000F2D9EFBC5924BABE33707E11F2D9DEDC86
-:1068F000D961CC57EC593D6BFF1406E7F8B004683A
-:1069000072EE098FEC4FBAC7F62FECB4EF1DBACF79
-:10691000CE33FF8E8DB75D8D65543ED068D0FB07BA
-:106920001BE750BDABB196CA471B13F43CFAF560A8
-:1069300012E97377633D3D1F0F6F0BB8FE3F6C4C40
-:1069400052FDDB815C827FD24D2026D9F385888F72
-:10695000F0D0BC1D78D2B6DDFDC30D4FB5A21F62CD
-:10696000108F19F83E17FA0415FD573141C775BF4E
-:1069700031C0E549267E27FA07048CCF35DCC4F305
-:1069800022EE11BCE71EBE65CBFF476D3E7D3B9AF4
-:106990007C30C0E07CA7765919E943A09523DDDC63
-:1069A00023240E1AC58467CFF9939579C947032E1E
-:1069B000BA99D8C1EDFADB035C3EE9EB40447A9B1F
-:1069C00090021DE9CD99776F955E8472B15710687A
-:1069D000BD91DECA5CF4E6F4776780EBC110CFBEF0
-:1069E0008F0FD12FE7FFF8BCB2AD358897B522F9EC
-:1069F0002D5BF095EBBBBFDAF364768B68213DAF7E
-:106A000010C99F3BE9F0116122834FD7BE1F403F61
-:106A1000747C22D8FEA6AE00D2D79D2BB87FF1EEB3
-:106A2000C3FC3CD3D175254BA6B0F68B187E30281D
-:106A3000957741698E3B7EEA9C63B85B4DE46823A1
-:106A4000F8B732F3DF6E9F74CB07396C9CF1874344
-:106A50003AFAD7B74E7AAA4761F5C27E81FC4985DA
-:106A6000E1D4145CCFAA3F7C6F5CBF6B1DEE589DD8
-:106A70009A847A63FBA41F08C80785C77E2AE03E74
-:106A800032494BBE1228C0FC70FB7CB09C9A8D76BC
-:106A9000C1A57989D770DD1245E9FF83F474B47616
-:106AA000DD7F62FF4E3CB2A141CF9DE2920F99E79C
-:106AB0002AEE4A8DECCF74E67F17CE7F8476CEFC2B
-:106AC0009DF53B5A1B5B857231139F99FDE65DB0C6
-:106AD0006CC4F1EFB2EF0F63F357822EFA2C4AF534
-:106AE000CBF89DF3FD70F1D7CCF90EFA894619AFBA
-:106AF000EDF2413ED2C523FF3BF1DF0F02924E4241
-:106B000042FF544F20190F16E0BD7129AA33E948FE
-:106B100079ED67E472FEBD63CC77C611DFC9E96227
-:106B2000CAFF18E5786D904854E13E678846B67D07
-:106B3000A03CC8E5E77C48917F540CDD3472BCBFB3
-:106B4000C81BEFDF0C3409B0BA553BFE01B286FE1C
-:106B5000B07D5081FEC7BC2087BF4AE6F6E58C7D3C
-:106B6000FA0E89FBADA4251117FE6CBF9D8F77CD62
-:106B7000E0BE09341DCF7F4DEF115CFCFA7E287911
-:106B800036E24989EB744ED6174B925F72A1141608
-:106B9000C99FDBC9E57F0324D4D3785C0670DE3A55
-:106BA000C445DCEFEF5AC7CF8DEB5A88E0BE2BA669
-:106BB00053BDC1D6531EB1F5FA876CB9FF7D5BEEAC
-:106BC0007FCF96FBA55DA9056106D7776DF97FBFDD
-:106BD0002DFF77A2FC67E569F7F5C3F72A491E1B6D
-:106BE000985FF08D6DF16644C13D8D26BD7FA27129
-:106BF00005957B7EFF7C7588C177DF73DC1F7CDFAA
-:106C0000E1319FC1F859DA140D81B5BFCBCA131F0A
-:106C100067F51DEBC49D28577EDC98A2EF76A8DDB2
-:106C200012EA314799B56C2119BC66B68458FBC885
-:106C3000BB035A2D2B77B41E0AE0BCF33E2702DEBD
-:106C4000D3E7F051F40F5FED8EA21C9B290691ADA6
-:106C5000F20ABAD553D04E5F27523FDFFCD565EA22
-:106C600002C07B1B5E84D5ECFB095784293FA2E858
-:106C7000FA97CDD5ACDD9697C394AF5DB1AFBFFBAE
-:106C800021F67ED68A08D5CBBBFACD2DAC5EFA06AE
-:106C9000AF4FB0BCFC71FAAE7EF321F67D712A4A8B
-:106CA000EF67EEEE6BC2F9FA2ABDE7AF72FED031A4
-:106CB0006E0B836F22187B826C3D1E1352BD01F454
-:106CC0005B2CE1E73C0AD2C92ADC3AC66EEFEAA1A6
-:106CD000D07F0754235EE3BF7D217E0D2BB7E147B4
-:106CE0008C2E66EFE5F8B8BBF5C50BCE67EDF6ACBC
-:106CF0005B4BE715FCEBD6717D88E10DE5FF84AFBA
-:106D0000EC15AE76C989A25639ABFF6E5BD04FFC4D
-:106D1000D1B66E59620A07776F18F5BE52EEB72CDE
-:106D20006EABF1E439397192BF09C96D41D23F7937
-:106D3000BC44D652F47C06E37DF4B3C28D22D797CF
-:106D4000127D01B73F46FF0ABF9F2D138E9D4199CB
-:106D50009F77B46A5EDBCFE6B765A62207108E295F
-:106D6000F6FD2C763CD269CFC6DFE9966FB2C6E15C
-:106D70009AC00C2505E15ED537EE21D6CF072967ED
-:106D80003F3383B89FFD68AB48FBDFE64A7E2E7039
-:106D90008FF14E37DE73E1F0559B21121F6FEB83AD
-:106DA000349EB3D85659927B1AD2510C77719AAF50
-:106DB0008A782EED93C1CECFE945FFB81FFDE38C55
-:106DC0009E4A0F878E88E407F4E683175B5E7A108D
-:106DD0001BBCE7F02630E5C79DBFCC2C9F213AA312
-:106DE0007DB6A617EF51388AF728A007C532A355FC
-:106DF00063C874E2CA917493847EF8D28C73077767
-:106E0000D8FC7E8F7DAE108E5D0F28BFEEB0F38B69
-:106E1000EE5825067586979F598768FF9CD0D05DF0
-:106E2000458199C33C8FC2C9B7F6DFA435E33E5B09
-:106E30009CF2E60D5566E45D977EC2BCEBC341AFA4
-:106E40007FAAF7C74103EFC34B3F2719A8D77EE3BB
-:106E5000EB33480E5A2BB9FE925E917707C697F234
-:106E60000530F0B9D3AF63C7BE13CC23BE49CF659D
-:106E7000EF7398FC88745DB002D70B72B4E6189E6D
-:106E80008FBE117E80FDAFE0EB5F550474BF4E51A5
-:106E90000C28CECFCA8DA7227FAF1331360EC76D17
-:106EA000790F6ADF33F83CF73322DD9F53DC6A9DAC
-:106EB00086F3EC9D575888F4B139CCCFC1B4083C67
-:106EC0009FCB2AE0FCB023D24DF9A15B6A4568C68E
-:106ED0007563B833B09FE5C19D94D782F0CE24BAD4
-:106EE00023FD0B6315C88FD61541BEFF1CB34E435F
-:106EF000FF7234D4DFB587F5135EAF183B512E56C1
-:106F000079EFA99B1CE2FA5E20C4F73FC62F8110DF
-:106F1000C6F93703E531B2B9107F33BEB280F60748
-:106F20008DEC2B27CE1FEDBD402C9ECACB1217FF38
-:106F3000EEB4E56DDACE5FB8C7DE471CBDE30E7B6D
-:106F40001FD96CEF1FC5E6E26605E976054C473CA4
-:106F500095AEEA129667E1FF533ABC7235935F260D
-:106F600065F24BCA7B6E75FC8A12CFFB8871BAE75B
-:106F70003D856470DDD93E8E785E1F289750FF9B5B
-:106F80000109D32D5786D303F282E634C4DF68F5B6
-:106F900092682891423D34530F3FCB5E972F0412E5
-:106FA00073B1BFE8BC7ACAE75915489C45FDCB6967
-:106FB00001E5E97CFC2E96155E4A061B05BC351FD3
-:106FC000075E900D3ADF75A3E4DC67EB3DDF051942
-:106FD000F7D766DE4F7BCEFFDE44F7D3B6094CE130
-:106FE000C37A8E7D3FAD9FDF4FDB16E1F6579B8F57
-:106FF000E7AD5D67E3E1F210BFEF75954DA7E7845C
-:10700000B2DF7FE4F8BF52281BB0DDD8ECF78EA1C9
-:107010006685FD9D333EFBFB5448E1DF4F1A799CAA
-:10702000B5380EEB6766D05C1D2A18C2D38C90B9B8
-:10703000C65DBF2164E715C909D22F4D99EF877A44
-:10704000D05CE76EE794791754D2F9BEA3F6F93E07
-:10705000F6DD7681F02A69A3C1BB6307B409FA564D
-:107060009283BF62FA5F96F5783F18B5C49CA1B8C9
-:1070700094A327ED0A71BB97D1DB06A20F266110FE
-:10708000EE30E85BF15E88F1780FB78EF6E7E17BD2
-:10709000BE8DF2F6ECBE5AD4A356FF58A2FBED4EBD
-:1070A000C0D72A4677AEBC14E779E107E3C91E9E34
-:1070B00020256F0FB9F6E9C215030AD23BC25FC3A0
-:1070C000E1E7F9D442FA346E1700C573DAAE897B72
-:1070D000F20B33ED923CBCF780E48A42FA5D265C09
-:1070E0008E5DE1D433CF271CB0E908FFF431784F2F
-:1070F0003870A5563625E4AF9990A47236E854321C
-:10710000FBA50BD793F19F8E703687269E85F3F8EB
-:1071100027E2EDA950C1BF1EDE1C3A2E4E9E3B4811
-:10712000C7D9EEBFBE3D142579DB7038B2D34FFB13
-:10713000C9D788AE2546D7A8F73A79330D60E7D589
-:1071400087A10BFD94C5C9463A277A94D131F62B15
-:1071500069FC5CAB0C5A02E337528CF3874F2ED399
-:10716000440DE3B3961FF51EAB040C94B5E8977479
-:10717000C35B194EBEEAA6BF1B0F6F2579FB854086
-:10718000F275C4EF8DA5961F353B971C7EC32D87E6
-:107190000508EBC87FE71CE3FB65555297911E1667
-:1071A000304E47BC2F8424D5CF078BCA0B204DE52A
-:1071B00067F18A23D2E3EC730CDD9788EE730C83BE
-:1071C000E7E12A9DBC0E1EAF2AB0E9106C7BF56783
-:1071D000F54B9B16B2F1D9E29B1897FA563DCFEBCF
-:1071E000F1CF96E93C6B41FF1575182F82655C0F56
-:1071F00073F221F2EABC7ADA09F75D1DFED361FC75
-:107200002EF3DC9CA3AF65EE5B4E99A9AFE58587B5
-:10721000892F0CB3EF64C6171AF09FDC8EB5EDEB27
-:10722000448EFBDEF8CCF240E340EB5E57DEF941E2
-:10723000BCEF28EB3EC0E3BED1DE3FD52DABA4FBB7
-:10724000E50C4C9DEC6BEC3EE7E5C943F670627EC5
-:10725000EECFD02F9DA8C9AD407B7251FCBDD6BDED
-:10726000F9004BCC9E735E76CDB34F63D066D113DD
-:1072700006C7337D7F73EFBF6FE0B903F44FD8E3E8
-:1072800045EC38D97AD1F213BFDA7EB8778BB8BD26
-:10729000EED8F9D9E6DB4AF8EA0F233D0C37DF2FA9
-:1072A00085F97E3AA6DEA0FBF25BECFBF25B2638AA
-:1072B000795C8686FAE45561EE8F5D1F2EA5386BEA
-:1072C0004BCF5CF22B17ECF7915F7DCCB2A460B989
-:1072D000F645CCBF473FEC37997EA753BE7D19D505
-:1072E0007BAB66A9682FDC10A9A0B8EDC646C39396
-:1072F00037E2942DECFBA4CBCFD792A8D630EEDBAF
-:107300005A57A1A2DD217DAE92EAF269159DD58C76
-:107310009FBFB079DA7905189F28E7F7935DCEEA29
-:107320004DA500D561BECF1E305E0E239EAAC3BA06
-:10733000433FB48EBE6549D3877221AE5563CE8C70
-:10734000F31C6CFA62CF49BF7E43495E13C67EECE4
-:107350007BB2D62BA9B2B5E5784E9E091CF417ABCB
-:10736000DC5F8874D03A6308EEB5367EE7D9E33245
-:1073700081243EE25A3F25CED76FBD082BB2ADCF58
-:107380004D61AEDFB46AA636221D69F2DF3CF78795
-:1073900056C678BE7E8CD1918B9F4FA477CE4F95E9
-:1073A000E1442BCECFAA86B214CD3F4CF287BE93D8
-:1073B00086EEB18C87CD0E6CF78B5C3B4FBA88E7BD
-:1073C00043B3E7ED3924FF5224DF1D7D70BDCCF5BA
-:1073D000B9D1EA837917AC237DF01DC65A649F7D2D
-:1073E0006E1DC9ED753E5543FBB477BE4C71ADE8DB
-:1073F0002970B9DB6E91225C1F9422DCFF8DBF9354
-:10740000909EC2F51E3CE7110D4137EE0303137841
-:107410009EE97AD8517B0AC1375973EF675513B883
-:107420009F614B757085DBDF303797C7CDF6E65629
-:10743000FD29CCCAF270BA1A59F30C0DFA31AF0615
-:10744000AAF97932A1889F27F381A1727EADD1F08C
-:10745000DE500192741E6DD8F503EFFDA20FC8E94E
-:10746000E620E22DC6EF59896C1728794FEA32BB26
-:10747000F14C4F73EED21F8709DF0903F9BB675642
-:1074800090ECBDF77A14B23FDFBB067ED785755FFF
-:107490000E586CA99E12C5DF3DCCE63BC0987527FF
-:1074A000E68169FCFDF4CD02F9B39EFA5B703CD233
-:1074B000BB1105117FCF6211D32778B22084304EE3
-:1074C0001B5D00DDE7E2F73D61C29F2FFEF3735EB7
-:1074D0009E41FB4F489C83E7B7C43B71FE8FC6219A
-:1074E0000FBF9FF1D76A094A86F4A1AD5AF210C2C4
-:1074F0003B1BAC153DECFB2D0AE7AF2D794A1AE397
-:1075000095150522E921E00BA527B3F78BF6BD5CA5
-:1075100083F99D8BE64CC796383EADF7242D79183C
-:10752000E9AF465B5293CBDA573EA793FC3D2F7EE3
-:10753000FD5EACCF3ACCEB3E3FD7E3518F719F134A
-:1075400058F4C1449AD7AB61AECFB6C6CD3E5318FE
-:1075500091AF32EEE5F59E3370E8806DEB3AE6A729
-:10756000D3BF75A28BA44F1CF23FC11CC33E8FE258
-:10757000D083297C1C7AD88D3C89F217F3CE6243E4
-:107580007967EB6DFD6DB4796799FC9477814CEB6D
-:10759000F00ED3B7300FFD443EB99EEEFFCCE4278A
-:1075A00007CE8D95793194C30EDF68B36F22B9ECA5
-:1075B000BF42A1FB4C1D3E72F86756CE201F7D13C3
-:1075C000E5C5B2B0BE90A76A98E0E6930B4FC257EC
-:1075D0008B60606F8CD517C960E530117460EE6BFD
-:1075E000A5135D7C9289CF45F30578D1230779DD1A
-:1075F000856F6DF01EE02C76F270EB7248D6DB6280
-:107600002E3E6DB7CF99758806E07ED49CBBDC8892
-:10761000CCC47B277357213F6C121229E487C8EC36
-:1076200037425731BCBF37866991E83FD4973F4C0A
-:10763000FCFE4288ECB22DB356527CEABD6B9293AD
-:10764000707FD9C0F0FE22EDE7E9B122E5DCF68FCC
-:10765000E5F9137A9C97C9387F0EF6FBB45D37EDD8
-:1076600076FDD48EADAF476EEE8B723ED817E5FB3C
-:10767000D406A553457A1828563577DEF2B9F6FDBB
-:10768000C2D746ECFC97632D3AC629AE8D08F67931
-:10769000BB2ED25736343E4E657E5D1A304F2E5883
-:1076A00066E9A857A81F2D10709F85D379DC1D9F10
-:1076B00037B9F4B58B6CB9ADE2BD406CDE6AB3A5E9
-:1076C000BBEF9D554521EB7D41FF15E5FE5FB519EB
-:1076D000E8BDDAFBFF283F21BFD410BE8CF5E64E93
-:1076E000FADD9840377F1E2B35852B5DFDC6EABA43
-:1076F0003CFBA32AF6CB640F358066A17127F7D730
-:10770000A0DFAD6369B013F39633E908FF5E74D16F
-:1077100083FAD185A417C121AE97D694A844BF6D32
-:107720000DCA0EF4EBBD1BABA63CF5161B6F99F30F
-:10773000C1F83AD3F4C84F66F9799CDD9AC2E3ECFC
-:1077400058C7383B961867C712E3ECF81EE3EC58AD
-:10775000FF41A349758CB7631DE3ED58C7383BD68D
-:1077600031BE8EE5E38D2BA8C4F809BE7FA2B1819E
-:10777000EAE7DA7213CAF8EF7C757C4D31313FEAE3
-:1077800027F6FAEC3197AEF825FA01216AE07E1D62
-:10779000D8DFFCC27FD975BAFF3A5E928F7E4988E6
-:1077A0008980F184F6F836A6630ECD2F20DF0A3AE1
-:1077B000C5D5AD1598D7B83372E03C99E90FA5F15E
-:1077C000EBABF3587D57E4B976CC233D556FAADF78
-:1077D000E1AAEB918A958F6843F549E53BE4207B6C
-:1077E000FFD096E7DB510E04625CEFFB51E437E714
-:1077F000353192E82E618A0DCAB162258D748C678D
-:10780000395F9C8CF3E07ACB67A1258E797C9374E9
-:10781000A502F98FB5EFE6743FBAF63F89E8F43C6C
-:10782000F3BB91DA8995A36A47E770876B87EF8589
-:1078300011FA698316AD8FC1BEC9C7F757AB80FB7C
-:107840007F3B7C9CEF3B02BC9C98E3E42F54DF120F
-:1078500065E52D51BEBE1D017E0FC1C054917E8FC6
-:10786000071A84CF633F5F2D040DF31F2BA696E408
-:10787000A3FE7FC8A687C993227CDFFEBF2AEDDB6B
-:10788000E74F7AA8358FD5277FDB30701FDE04469F
-:1078900010EF71B5368B944FF4FDCA53F296B0E6F3
-:1078A00067CC7C2C0FF5DE0A5BEEA46DFBA4A9ED82
-:1078B000AA49681FBCF72C977B47EC7176F8FA52FF
-:1078C000B49E33C3749E02A093F492A6B84CC10C2C
-:1078D000711C2F159F7629DD93D9A6D0BD4CCA8780
-:1078E000B355F2A77EE0B7EF25EE237D450924B519
-:1078F0005CF6BCD312C9FFD0A205296EB3295C4146
-:10790000BFCB6095CB140FDB54CEE33AA1C8C5744E
-:107910004EEB9B3D016ADF1656291F385DBE7B5F2B
-:10792000750C4B51C37D3F6D2EA5FB2A2D4DD428E0
-:10793000AF98FD8BDEAF8A919F6713D8EBB28AC7F1
-:10794000217C63F753BDE5228DFA073B7F9F542FBF
-:10795000117F2722D1E3BD7F76E0E767A21F642570
-:107960003F9F324D5BDAF3247BDF6AAA8912C60F90
-:107970006DDA3BBD21AC5F06142F0D4D7DB919E3C7
-:10798000A9AD576A06CFC7E2E721C0BEEFB8B57C04
-:1079900059CFEFB1FFFA104C36B07D8D8AFC0AAD9D
-:1079A000F034DE4F5564EB33A1DC0A01F5B1B63A91
-:1079B000BA8693C1E73D47D09AF71915E9465A941C
-:1079C00047E3B481A9627BAB4EA67DB128AC76A318
-:1079D000DFA0C8F63B38F2203FE53A4FC0FE57B86B
-:1079E0004AF69C37187BA5B75E9071DFEE9936FD9D
-:1079F00064E22D739EF9B14773119EFC557432E217
-:107A000004F86F8D552CC1798DD37A851D9564D27C
-:107A100068BA86A986A926773EC62785775A796BE4
-:107A20001FD2C3345D069DE1E54C1868C6FE37D908
-:107A3000F4DF51ECDD9F0FD9760DE3D3ABA3980FA4
-:107A4000D52082E5EA1FE31D960B9E533AF23CF5E2
-:107A5000C99D859EF653B69778DE9F963EDDF3FE70
-:107A60008C5D159EFAD4AE799EF6673E5EEDA94F09
-:107A7000EFFE8CA7FD8C7D4B3DF5997D977ADACF93
-:107A80007E61B9E7FDDCFE959EF767BDB6D6533F34
-:107A90007BE0EB9EF68E5E9FB96F5E11FDFBF47985
-:107AA000FCDD1FF7B9E24C7BE1847B743E6AD13187
-:107AB000FE07517E6FAE8CFB3BABAFFD1AB7BBD45C
-:107AC000730C1DE5CD25365DAECC33AF43F95A15A9
-:107AD00055699F90C3BC9D1C3E8FF49189DB999C96
-:107AE0009A41F6D8E0FB10CAEB46EB9C5297BF2AAE
-:107AF000A07502E68155456BE9FE40E77B593301ED
-:107B0000F3E32EC12486023C766A51BB80CEBE7759
-:107B1000CD8BD97F7495C400B30F51AF1FB4FFE470
-:107B20001C8AFB32FB8FEC4323C8ED413826D17B06
-:107B3000E39B02607C9AD977641F3E1A66F6E17473
-:107B4000B4C7FA37A11C1AF8854C7144F647F65FA2
-:107B500025B3FF36E6BAFDE0FDC558A6412B247FCC
-:107B6000B8D22D8E2D267BF036A4E72FAC7B760580
-:107B7000F63BB592DFB3D731A62E8E7A72477117D6
-:107B8000F1C940B1CCF7213951E6F6EFFDD45EEFF3
-:107B900090FA7DB243D93A905C76D66193D09FC675
-:107BA000FB0CADAF05C9DF3DF18FFE43C86F6A899D
-:107BB0003A1EF3008D3D8A89E3DD6AE3B9449B5E9A
-:107BC0008D3FF3581A5FD28BE5A93AD347585956DF
-:107BD000B6B517CB47A22534DEE9C623D52863D432
-:107BE00073B8DF5A9EA6A49B05F4373338B2D81D6C
-:107BF00083FE89E8767E8EBF547E05E90FB5FEE3ED
-:107C00006C0A55792AC58D0348170295444F0139EE
-:107C100044FB4B000FA3627D8E90C65017EAAF98CD
-:107C2000175A95B79DE8C0D16B51DF4D72FBF8A78D
-:107C300088D7589D77FD43EA0F084FADF6EFBC7526
-:107C4000E4EAFBABD9B81D052579E8B3457FCA1234
-:107C500097FCD963EFBBF7E6881EF9331B731466F4
-:107C60000EE9458C1FB68BA720BC098AAF07F64BDF
-:107C700064CF076EEAA4DF570D68960EA4FF5B3A47
-:107C8000F65B53524FFEBFBFC42A480F0E343C95DB
-:107C9000156F817E09CC19C3E3337AEA1DA40FC0A6
-:107CA00098A08EFB6C432C68EEC8621F7C29C2FD35
-:107CB000671B263AFECC049D7B6D437F5B18B7366D
-:107CC000557C84F573C32F0A76BAEF87B8A180FB81
-:107CD00027871B3FC0ECCCA40BBE0DAC5F94E36DBB
-:107CE000C796D4D2FDAAB8CD54E2B9D0F21DE4A70C
-:107CF000B7EDA52FD978BD36C2F1385181053B507B
-:107D00009EE431FD88A1B4CAF6AB38FE97780E8F99
-:107D1000EB1B1648DC2FE773F62DF138DE4BA383FF
-:107D2000AECCB2AF00211598EF6BECFF7AF07CE09F
-:107D3000291DAE7D0E703FF0D6A76CF7D64F4B7B5A
-:107D4000EB4C8B7E1EF5806500DCAFB1CBFB3E0CAF
-:107D5000A60FE32885CE7DFA097E5E506510207D52
-:107D60009777A57BEE66F34B38F75E66DC9F3F7531
-:107D7000779AF497C54C7FC1F799F7BA171E5EBD85
-:107D80001AF585C28C7DB4C22791BF01FD4486CB14
-:107D90004F3449D33D7695E3EFC994EBC1C35B8182
-:107DA000BD217B3DE9C7FB51B572F42BB417DDF261
-:107DB000C7239543FE957639F5EA11F25F32FD2B24
-:107DC000C6FD1FE897BEE1175FF9F311979FF2ED2B
-:107DD00068721AFA336E9FC4BF77EE4F75CEF5BD49
-:107DE000532BFF4CD0391C49171C379659E7737534
-:107DF000254DF76738FE15C78F70699E790BF2DD48
-:107E000026E3506A0FEBB7FA377EC07E164AFBF7BF
-:107E100035A2BC9B2053BE88367BD5BD41F467E2BA
-:107E20007B56AF2ED6C7127F3CE3237FC27A9BEFEF
-:107E30009DF3A98E3FE6B3B61D707E8EA3475941D0
-:107E4000FB5C4610F5E43376B135F4EC87DC1FE8D3
-:107E5000F8FDA67679DF9F8E47BDC9EFB983F29B07
-:107E60008CB93CBF694C7DBA17D7F94C7B9D316EFC
-:107E700055356B287E3AF6B2742FEAA1D3EC3CA5B7
-:107E8000F2677E463FE50B5211E5279D3E9EDF4B94
-:107E900064EC953DE742C68040793E639E938C3406
-:107EA000EB67DA13DEF7E5E0AA17237CDE7A665C7F
-:107EB0008AA95B6F5F21E0EFA2A60494679B2F6302
-:107EC0003602ABAFC8B1F38B4E8553916E174A6142
-:107ED00003EFD15BFB2B89F214FD47A6FC1AE3A349
-:107EE000F02CCFABD44EE1F156EDE792C1242068DF
-:107EF00021983E3D3C14C7FAD67103EFD41FF48F8E
-:107F00003DC0D61DF7A10799DD5FEA433B5EA37A2A
-:107F100017B3FBB1FE28B3FBB1DCCDEC7E7CFE4396
-:107F200066F763FD7166F763F96366F7E3F3279815
-:107F3000DD8FF5BDB955E48FEFC3FB8DA6E0EFDA19
-:107F4000EEA6BCC6F5AA4F43FAC99467555537A8A3
-:107F5000CB187E378617521CA57A21CFAB6FCF592D
-:107F600048F6F4A09F2EC3CF39E4B7EB171CBF1D12
-:107F70001E718EDBF6ECA0FF3369D0FD0527EFC73D
-:107F800074FA21FFE909FDD87ED437BFF6DBEFB4E0
-:107F9000B057AB676EEB0896E0B99E147F6FE7159C
-:107FA00066FE9ED6EADD4D94E7A78C7B2E85EBBA64
-:107FB000BB324CFA06FEDE12CAED4C3BD1B10F3398
-:107FC000F571A7CCDC0F33F36022B65E72B2BC8CC5
-:107FD0002DBE14C5ADAD26265F70BF684C9FF3B2B1
-:107FE000EF44BF6DA1969771BE99E75DF9F7F17CFB
-:107FF000BC0E486AEEF93BE71FC8E62BE1FE43B72B
-:10800000DF36589AA6FB19826193F44581E991A461
-:10801000576A498A03B60FF3BBD9AFDA72A269DC9B
-:10802000C5B4DFB73FE3237DABC6CE7F6B19A75244
-:10803000BD65DCAC389D3389CC52FBB3F4B336520A
-:1080400032E2FE2AB1FD5F1F61FF97FCFCDC574B5B
-:10805000EF5C15CF47758497F7A1DDDE118F91FF97
-:10806000BF67DC2CCF3DE4527C0EDD572185B99EE5
-:108070002DC555D2B3659C7FF9507BA7DD9E1CBEF4
-:108080008F3036273F6620DC49EDFC72C2447F8B7F
-:108090003FC6F38CFD1A8F17064B4550B39CC7782B
-:1080A0002287DFE3D5519ED4D0AFD31197E95C4747
-:1080B000875E315CBC95F4A2FFCD113CF4DB62FB22
-:1080C0001D5A5628A417261A72B59A7C3A97308002
-:1080D0007CDE116E5631FEAA8CAB1CB15F45E3FD10
-:1080E000FE7FA3B2F95D0080000000001F8B080036
-:1080F00000000000000BCD7D0D6014D5B5F09D9DF6
-:10810000D99F24BBC924BB9BECE68F09241A34E019
-:1081100026240134E224048A167111D0D052D98069
-:10812000282A48405B57ABCD8604842035F853A9F4
-:1081300058BAB160ED57ADD1D296D7222F28F2FCB4
-:10814000414DD52A58D400D66A6B6D0469A9FA3E10
-:10815000BE73CE9D497626B34950FBBE872DC39D85
-:10816000B93FE79E7BFEEFB9774F9D823F1730D630
-:10817000BA27456595F05CEA88A71431168E966794
-:10818000D74F60EC1B59E1CF32FC8C393C8BE49823
-:108190009B313B636A173C4F69EDF4A75716188370
-:1081A0007AA2FCF329EF7A077FD79F62FA661681DD
-:1081B000F6AC587AAFD7C5984D61C2291B94995B2C
-:1081C0007EEF6C467F4E89F8774F20EC49DE8FC7F3
-:1081D000F58B29EF4E18DC6E7959AF4354185BBF0D
-:1081E000AD23CCA0FCA900852A843BA6E6C1BCAE89
-:1081F000DFB99245CA18DB28F5B8648063E3E7C2AB
-:10820000C270D9E0FE17E37CAAB057298670C21F5E
-:10821000DBA973E06F85298E6AC6F2F0CD687CF227
-:10822000EF30CA9E53D07F7937944B3578E0FF13F7
-:108230009E3596AB7A8CE589078C65C642F6F03898
-:10824000C65E6B864ECF646CCEA10F0EB174C6E6CF
-:10825000C642CF3CE9632C577585E33263F358E897
-:1082600099B7A09CD790C6BA4330B88D2DC57581FB
-:1082700069BE510CF035308295E52D4D65CC35D079
-:10828000FF7C3993D6A9A1B771261BCFD8F76F69A8
-:10829000650CFA89D509F1ED00FFECFA6DB3C7C0A2
-:1082A000F3FE4A5BC143D828627F17E7E782CE4ED0
-:1082B000C17C336D2B478D86FAE1A969422BD4FB33
-:1082C000FEB967AD2F8672CFF49210E21DF0F56E05
-:1082D000FF7C00FFF3C2BCBD3EFECB95C7E68E819E
-:1082E000E796CA2766E3734E627DE86FD6A4CE1682
-:1082F00007F477C932A502FB0BD71BDBE7D518CBF8
-:1083000000399F0FFCCB9B3518DEE1E0318FAFF7D2
-:10831000777FB342F8679F033D003EC3F809DA87D1
-:10832000A53E290478CEAD11D438D04D9E2AA89D03
-:1083300016FCD0AEF18319FF622C83219FD5CD139B
-:10834000E3ED5025D76527FCE7CE14E20A8C9FBBEE
-:10835000B4AFFB14942F73D9E3227CCFCAEC12F094
-:10836000FBFDCB18EB2822F0D26B13D6F77ED71A81
-:108370007B217C9F1714990DE880D58CA1F1088E84
-:10838000D1848F231C1F2EC247DEB2D0333F82F12F
-:108390002F9FE49445A87F7903FFAEC3B751023AFB
-:1083A00083EF1B81CE624467D29144FCCC39B47C0C
-:1083B00039D2E31CD3FB62A88BF3FDDBE403671423
-:1083C000025CCB858E1969004A8ABD89315C68C020
-:1083D00020D2B5CE8F3A9E96EF68217E4CE033FBDB
-:1083E00029E467FC7736A186F8EC29D72F65941B22
-:1083F000BB337BB73020E1AD328BD5E733F69FA995
-:108400007D670B50DE2E5FB66EDDF9F03DA5EFE720
-:10841000AC9C31A7F39B336624945353AFA6B24F61
-:108420001B07A610E3EBDD3F2ED1C75F650EDF060D
-:10843000956D12A12CD9E44DA1A2817659D84E1880
-:10844000A25D986D922CDAB9F57680A7B5B07EA9B9
-:10845000DABC52B5EF360D9EC4F125C49BACB8050D
-:10846000580F69BA2423BD7C5938B2879B77846D35
-:10847000B28F19DC0EC06ED1E1B759C31FC7EF89A7
-:10848000E3DB8780FFABC6C770FD39B4EFA70D1FD4
-:10849000545F9D9D7CBE08971DF595A2B86D09FDA2
-:1084A000DCB9E75F2F9C03C42BCD67A114E843B26E
-:1084B000AB7208E8BC4CBEC7859D4B99F57204F8B9
-:1084C000613D945578BFBEABC3A5C0FBB2E2BBD63D
-:1084D00021D19775A7329407E3989CF908F43B4E95
-:1084E000965837AEDAF97B6D69506617B35009F4C8
-:1084F0009BB12795E44966D1B93F1160DCCC4C971C
-:108500008AEDD332AB7FC2883E982225E023ADF6B8
-:10851000B5BA34846B360B212B4A429CD522938DFD
-:10852000051E8272E6B46DAC1ECA157FF32822F2D6
-:10853000B4C4F55D3BB6473DDDC6F6A17E096AF2DF
-:10854000679D43DE44FAE35A89A1FE481B778F807A
-:10855000F0DC0F5D89C097656559B3EBA15CB6DFB0
-:108560001652149C4F875088F30988A4B7747CEA8C
-:1085700072A4E2E36ECEF463597C3BC0DF668F7772
-:10858000A3BC8A4DBE5CDE0EF0E45E9920AFF1AF75
-:108590003EC001C2FBE2A5DBDB8B90BEA57713FBDF
-:1085A000CBF838DE8DF28CD53684B1BD6FA66490E1
-:1085B000FFA99A3C4B35E981E62C3BC9335D1F305E
-:1085C00055526498B7A0CD9B7D2F4CFAC0C9422E5E
-:1085D00007D92B0BC80E1158AF702A0DE68F151155
-:1085E000EE023E8F41EDAB797B1608B9D0CE71A675
-:1085F0003635617DF898D502C815AE4D55513F0B03
-:108600000EE60A56C0BC6D2CD20574D2223009CBBE
-:1086100003E375331CCFE94A6B43BBEB2957AB0D22
-:10862000F1D7FA2CE80F98C7ED76D6807641AB1CCF
-:10863000726541FBA866BFAD2A1F9D83E50CA0EDC6
-:108640001EB41BA4B08C74B9CA5F9CC3E07DBAB7DA
-:10865000F79B2867BF96F9AB19AE0290A37550E758
-:108660005C90FB9B1E5B17AB81F14EE63125C1CEC2
-:10867000734A4D0CED29E7C942C3FBEE6698D199C8
-:108680000365D56DABC771AECD5408AFB54C6EC3A5
-:1086900076B5800C25615D9C27834C9960D57FBEA3
-:1086A000E17D37D8498A7324FDA731A534B1FF3164
-:1086B00049FA3FC3D4BF6CD9FF40BF5E43BF6B24B0
-:1086C000467674CCE7A67537DB05AB33EB5664A270
-:1086D0003DEA644D5D1676674BA68DE0BE3DD0D475
-:1086E000A342FB3A068C0F7472C1E7474446F60C6E
-:1086F000AC14D00BCB97FAFAE97834D6E3F46B8B51
-:10870000090CE5D20592DDC0275398B16CB68B4AAF
-:1087100060AD715C9BA7B207E967953F55715AC080
-:10872000AF3F7B9AD994E212986F6A7829033EBED4
-:108730003F739F6B4D00CAE99C4E1ECEFCE30CF4C8
-:10874000177A044E7F6B7C36C24BB82EA7534CE889
-:1087500037EC60252817C348DF6E0E0F8EDFE3CF9E
-:108760007FB0DD627C10BB06FB61B62A4C294E98B7
-:10877000578F6607F78F3735AF13F9A07F3C27ABCC
-:10878000A2F144C07FE278D95F6CBCDFE3FCCA068B
-:10879000C69B3DDD38BFD90E99E6375BE35F7DBCF4
-:1087A000DFE3FC8ABEC07838BFC4F1BE669CDF6CD4
-:1087B000A74CF39B2D72FAEA1F2FFB8B8DD7D35C4E
-:1087C0004A76F0ED0E904F4027A9E53B5C6360DCF4
-:1087D000DB5D76595006DAD5D6DEE09A8BBAD73D06
-:1087E00075BA1FC6A99B069573B197A9D36B8B1950
-:1087F000DB2470BAF8EBA63FAF43BA383E73552975
-:10880000E913CDBEBE04AB823EBE44E2F0CECA77D1
-:10881000C75B12F0783FC81115E07800F85D057E5F
-:10882000DC0A7C89E57873809E0F82BD8ECF6D0057
-:108830002F7E7FA83944E5879B27D153EFA7741279
-:10884000B7DBC7D658DBED676471BF6F53509E7FAF
-:1088500025EAB5DAD410EA4536E93CA626DAD5ACE5
-:10886000E9A914F8BEF132568EBAF18CCD1C6E5FB8
-:108870007D36D9EDA9E57B7B9AA17CBB6457502F4F
-:10888000DFAEB019567E7311EA992AB457797B7618
-:108890001EF7C37CE1DEBDA8F7E6A09D0E78F5CFFC
-:1088A000EDDD8BFEDFA56097935E6687F7BE05DF83
-:1088B0005F03FFAF1DCBA29BC9509E35C74FE3C3DB
-:1088C0009FF4DA6CB4DFF99FBB671E23BF229CC202
-:1088D000F5828FCD7E660FC21B722871EA8FDD1B79
-:1088E000463E50ED4A3B8982B01DF5B41FF5347CFD
-:1088F000AF3DEC6436846F9A83E4DADCB946BF613D
-:10890000534AB78CF6CFA6721F6B81FE2F9D69FC70
-:10891000EE74727E0B9BFC8659A6324848EE778B2C
-:108920000B32D0DEBF1D5F4D1E8CB7E8A196DBF782
-:1089300026D0695E96C747718033D81928CF4EB0CC
-:10894000B23BEBF1637E16192BE6F6FF6C8EDDBEB3
-:108950001750FF32CABD2AA46F2E3706F307876768
-:10896000B256EFFEE69E29EF960CC0972BC505D4B4
-:1089700003794BE17DC27C255F5C407F87898F94C2
-:10898000A37F639EC7FDC2234166319EFECC65D2A4
-:108990007B88175C4A94E7E6F94E1E34DF9A978B82
-:1089A00099153F299BD09E9BF5AC186A5106F0A102
-:1089B000CFFF7F9AAF8E6A7A86A93ED60DF4F23247
-:1089C000D07B3BF76318DAA93ABD4205B29F2EB9B6
-:1089D00004BE235DA86A01E2F3E5D17DDBAEC27679
-:1089E000203B5AD1DFD5EDA0EE8336B483BE68BFFD
-:1089F000975CEB207B8BB17AF9BDD281FE92AD0FF3
-:108A0000F6FB5E82FEECB713F14FB526FA10C69660
-:108A10005080EC819BC13E467F3F5AFF8194CEBF80
-:108A20001F49B053F1CF9184FE5AF7FC4C5000AE71
-:108A3000CEE6AE29EFDA13E4C552D9B606EDB99603
-:108A4000B84071886EA807F6C0E8A58AAD0DF07F22
-:108A500025F683F46992EBA3DBA09F443BA566AEA9
-:108A6000FC08D0435B595D47089EEB37F378995E6D
-:108A7000BF3F6EE68B917F6E674D4C00381D29DF3E
-:108A8000FB712FCC476D9558CA1428DBB9BDC3DEE6
-:108A9000F2905C10DD4D3FC5EF8118C82D9C775DCD
-:108AA000D363588ED958B8159EF7A5F1F651C9254C
-:108AB0003B431827699B81D3CF0C46EECD02FCAD1A
-:108AC000C94E2539E878DBF320CA294766C552B478
-:108AD0007B1644BF1BC678A4EC650BC316F4B540E7
-:108AE000B31FE2593CEE72C8DE5D900970D706EB09
-:108AF000E2D8EFA0FAD1EF517F53446B3B6CA7D67D
-:108B0000CF169BB55C785CFB7EF9F2273E7808E6D1
-:108B10009356EC0E21B9AD3F87ED106C83EBEFF26D
-:108B200047BA12E1482996258A83B2AEC968CFAD0B
-:108B3000FFEC81AEC700E5599FB949CE66899EB862
-:108B4000506468BF33AB6A70FBDDFF7A3D80EBB3E6
-:108B50003B85917E65EC850BD19FDCD85F6631014A
-:108B6000E39C995A39F6F085AAA1BCF8C25A2C2385
-:108B7000ED02514EBEFBDBEB63D85EE06516FB0EEB
-:108B8000AF6FE7F573B4EF532EFAF02777A23EA844
-:108B900076901FBA51B38374F8CEF38A443FE779D5
-:108BA00087C6E3414D2EB8468EC7835678DC1D54E8
-:108BB000DFC4F729AC4B403A4EF9CC7523B6FF61C0
-:108BC000330B5F09B06F5176FCEC4E85DA1FB6C2ED
-:108BD000E35941F508B6772D3FF2933B010E8F0E16
-:108BE000C74476631238FE32D47AEEC8E6726E9EBF
-:108BF0008FEB8D2CCDDE74387A02B3E12957FEE07D
-:108C00000619E4CDDAA2AE06ABF8F309AF8DDA654A
-:108C10002689B7677839DE76E5843F4538DAE42778
-:108C20005C387EAAC0C2587FC3A45E2624F47BB6FB
-:108C30008FAF03C06DF342BBD4C94C453AF3304FFC
-:108C40009C019D792A39FC1B02AF3105DA794AE192
-:108C5000E9C6F7BDC4FFE87270A106820ECA0E8D88
-:108C60003E32EE6EBF10E9214BD4E92DAF1DE9C5B0
-:108C700061D3EBE75D84E5CE2C5E2EF7E5B5C7F258
-:108C800041CF38A00DCA855C07D93BE6F9E568F00D
-:108C9000B6FB55BFD76F814F672FADD3C6718E50CE
-:108CA0000CD6758AADA761317EBBC84DF61ABC6F74
-:108CB0008827CC7FBA4687D3BDDCDEDAF82F57434E
-:108CC000DC623D92D1E978EF69D3E978AF359D9EBA
-:108CD00083F84FA0D34F98359D565BB5073A9D68F2
-:108CE000850F735964EAE6460050FA74FAC377A216
-:108CF000B6FA7ACDE6C7E039E533B7E4853AE2194A
-:108D00008CEC449B8BCBF701B91F9986FD4B7213FA
-:108D1000BD17DD61DAAF79318BF73FA8DF89D59BCD
-:108D2000516E8DA0DF30CEDBDCEF282F8777CA4570
-:108D3000EE48DC02EF27BD12F74B7D7CFC64FC5251
-:108D4000EAE37E73527ED1E93F271C413886E397E0
-:108D50000B06F865E9C8F86507F14B5A19E797B4AF
-:108D600024FCC2624EE28FB545BC7CF3DD3EE28757
-:108D70007EFE899518F9275662E09F69F794507D29
-:108D800073FB749CB7055E625E7D1EE1669C877A0C
-:108D9000B6DC2692BDD1CB504E75B2BE3D4EE4C37B
-:108DA0001A21B41DDECE8AF5D4BB14FCDEC3668363
-:108DB000FDB14EA3FBAD080FFA43D55A3C4BEA6117
-:108DC000977A06F3B1A7B2BB349280FF020D8F975A
-:108DD000F9C277E2F89DAC772CDAA5C9D6E91E0D69
-:108DE000DE1B03EA3D56743E9CDED9897AC78F4F5D
-:108DF0000E77D667AE269403663E9F72FD6F3F786E
-:108E000068887E7EA5C1F1A8F63C0DBE7FD46BA517
-:108E1000A783EA2F4C7C5F298CB6E4FB5F59B5072A
-:108E2000BEFFB5153EBE049F3F65C5E70F7879FFCD
-:108E3000C3E159F2713C4BBE2F87E723DA3ABD7983
-:108E4000FA787E33099EFFE8F58F08CF4792C8D79E
-:108E5000A35E82C316C37D01E477F4DFD74D8CF5A2
-:108E6000E17EA8051C7F4DECC7A5F07EC0B4FF4491
-:108E7000003A9FF2E9BA50C4822FA1DDB144F8F55F
-:108E800076F77865CD8F5056A25DBDE5EB6EDA4F73
-:108E9000003DF80FEF572BE76D3E0B793CC5C6E55B
-:108EA000D065771F5E8F719A2FD17FBA55FFCF693A
-:108EB000F4359CFE2F4AD0FFD88F59DE75321E4FF5
-:108EC00069F747F27D84AFDE0B513E6DBD254B4007
-:108ED000BF2E5FED16D0FEF76BFA65A397FB337AD2
-:108EE000BBAD52B72061FD2659880986FECE18AA6F
-:108EF0003F331C00DF5884EF329F7A163EEFF1F6C5
-:108F0000DB7BA7650F5507D40A6C0F72BA12C757DF
-:108F1000CF34CA697D1EB67017EB45FD02EE77DCD3
-:108F200082AEFC9ABE847ECEA77E34795FE5D3E91B
-:108F30008AF777BAFA06E09BAEC137039F66F8CC92
-:108F400078190ECE9B104EDEDFA5897026EB4FF709
-:108F5000AFF575227D9A10D75938A0AFAFC0FE5C2F
-:108F60006B6C31E61BE05F5D5F83644AC5FEB7381A
-:108F7000781C75CBB2BB6A31DFA0F356B91C519295
-:108F8000BB94EB39655921C555AFD1FA35C3DFDF45
-:108F9000DED1357642198DBB1CC7BDA08675A3DC1A
-:108FA000C8403B81E20FB284F1852C674700E3B2F1
-:108FB000EB858E8645A8472F7493BE6581B996F1DF
-:108FC00029FDA9C79FF479B340E530F55BA8BE9CA5
-:108FD000D6D18476D288EB3B3B2CEDAAEF6B76158D
-:108FE000CC6FFD90780DF828BEA5E377F0387CFDB6
-:108FF0006AC34D02E23BB50C8604964C0D77D066F1
-:10900000ABAD38CE7AD17E2A057AA1FE5EB38CFB59
-:109010000DF4B75687EB01A4C72F0B975E2FF97895
-:10902000BC1EEE9F51BCC3CDE5167D80F2B167BD7D
-:1090300096FB07FAF3F666599540FF1C93950C8C46
-:1090400017DEAEE941C642814B3DFFFE7A03F3884D
-:10905000F378A7A97E9471BA670117D97718864F5C
-:10906000A49B577DDC1F6DCF0E3FCBE56328847436
-:109070000DE5E711FFCC05650F95F75359EE2FBFAE
-:1090800044F503BC3E93E511E119DAFD81DA49FDAF
-:10909000FDBC41FDBAFBC73D48DF7DFDE53FD2F792
-:1090A0007C5E7FA4E324AC2B9F7F8F48F3FF445268
-:1090B00033707FF4B2E8628A13CD8F5E43CF75CDF3
-:1090C000722DC6E35E6AEE6B6B83E765F317CB68C0
-:1090D000F7CF5F7237EDDFEBFD5F827E05F2BB22DB
-:1090E000CD20BBA8C816DEE61EE0B70138DAB43CD6
-:1090F000B3DE7AA42397CAFADACBA1FDA48FDBDA18
-:109100000C794E1D943F93A2489F26C6D57539F819
-:10911000A143FD94E63F723A36CD97B1BD30FE27AC
-:10912000EEE2788CE8BA4EB6E2177DDEC9FAD7E7F0
-:109130009D4CCEE8F8D3DFAF2FAE9079FE4FDC80A8
-:109140009794927ACAF7B944D0E0F4B8347EE3F544
-:1091500066C1384F94117D2848BFB3343FCEAC1759
-:10916000F4713F74448AFCD80EDEDC5A6181DF1151
-:10917000E2ED40F3D270BD1DE571570AEDDF339982
-:10918000E2FC7ABD8624F33FDFCFF50873AA349F53
-:109190000DB765C4D1EED8D0F82B19832B69E33E07
-:1091A000A98AE153E83BB108E5CB6D1ECAC76868E0
-:1091B0003C51D592D0FFC2A7FFC385F1DE8671ABCB
-:1091C000FD187759C8A44F12F31DCCE33644AF27DE
-:1091D000BA8DB5080D56FED61BD99CAF17628A8C86
-:1091E00048FD1D49DC476E542A1C189F688C19F7EE
-:1091F0007340433A903E16AF33BF4FD8CF11B17F83
-:1092000046F38EE1661EEABD3536A2B72D8037F4EF
-:10921000030B415DE2F38DEC2C8D1F7B089FFF6EED
-:1092200078DEC896F9BE9B8BC5D2B206E82627D257
-:10923000C1503F792A05DADFF479F4FC882ED25345
-:10924000F7B8F532E82DC07FB84CB3738AF9771BB5
-:1092500096D1FF49EBD96B033E5E73EF531705C6FA
-:10926000427F6591804DA6F2F3921FED2F5E66B1AD
-:10927000A79EDF4BF6AC7C961002FE6FDBFDFCB3C5
-:1092800005E4CF6BF6D8EEE7C91ED3CB8C753398C7
-:109290004F676A7F597505A03CBABF1CC3F256CD13
-:1092A0008E5F73EFEEE7DBC83E09C7FC097AB29622
-:1092B000F1F8F257AD1F3B035776603E51ACD846EC
-:1092C000FE5EAA891F1FF13BA85E514EE42EE2C745
-:1092D0005BFB248C373882AFF9500E8C2A3EA68E69
-:1092E00006FA1F55C3D36458291FB7B37815D90D93
-:1092F0009DDABAC0FF56A3DE1B589F1ED3FAF0F5C5
-:109300000857F6D0FA78CA7A68BD6C58A6B81FDF3D
-:109310008FBFB892DB1BB293EF2B6CF7737ED8E153
-:10932000E7FEED0E3FF74F338AEFA2F84ECA0C1B53
-:10933000D5CFD09E6639BEC32F69F29CE3637730E8
-:10934000D2E54FB05BE17DB8B412E59B2F0BF75926
-:109350006B8BA51B919E7FACF9A7B04E77D23A15C7
-:10936000F952237CDD7EE3F75BAC5BE9C8D6EDF513
-:10937000E608C9AB64EB76D97C316C15777B5EC3AC
-:10938000C3470D7FFA014E67B9ABCF81FB30EB8B42
-:109390003719F2AA5D3B6677632EB49E57BD3A2D0E
-:1093A000BD06E5B679DCD73FFF2F1FE277E6BF9C0D
-:1093B00096F2F1634D3EBED6DC40ED608115299BEF
-:1093C000E400E3792FFD7962C229274DEF75CC4384
-:1093D000BB82589FB1B9E1C3B45FBD282032DC1F06
-:1093E0005FC88C79652CAAE705F33CD8D725704D6A
-:1093F0000185AFC78410608A354AB375B962C80F5A
-:109400009B3777F63EDC875FACEDC3837C317C5FB6
-:1094100062CA1BBBBCA1315CAF7D3F4E7FC7094F09
-:1094200073156E37CE75BB49BFCE0BCF0FD727EC68
-:10943000C7BDF1DFA2651EFAF9D93A5EC2E1FA9220
-:10944000C1785914161CB2323C7ECCF8A89538BEAF
-:109450001A357C99F163C6C3E2B9B369FDCDF37FD8
-:10946000DD1526FCBC0EF8C17C61333E188B5C8C8C
-:1094700074FBC67C91A17D3C5D9C69C73C81C5B3F2
-:109480000586F9454B58289DE707ABB3A625C06B69
-:10949000C6A3195F8B9F64A16EE877F1BD1E5ABF0A
-:1094A0005734FC88DD7FA77985615EED7C5E477867
-:1094B000FEAA4CF3BA542D7FC607DF236D206D152D
-:1094C0002B3DC2E7B308E6D32E0FD62727584D13FE
-:1094D000D2C91253DE82193E33FC33510E4E1EBCEC
-:1094E0008F5F91ADEDE38F67216D1F3F838E3584D4
-:1094F000FC43E62D0CF039A7AF85D1D9FDE361BF60
-:10950000028BF49765C0EFCCE7BC1BE7C1BF5705E2
-:109510004405F30467CF1FB306E71F66E18CEE2214
-:10952000B4F7FBEC28472E6560C642BB0B6092A8DF
-:109530006FC3F52954D6FB3DD6F1B19DF47884353F
-:109540006DA7FD772563EEB8E4F26555C041E39958
-:10955000ED9499E52519282FCCF8D0F1340FF1922C
-:109560004678197F3A7879017515FAB318478375EB
-:10957000ECBB86B107CB07F68F59BECAEDC96C4666
-:10958000FBFFD764676A764713C51D16687AE190BA
-:109590009D353CEEE6FBC81509F2F11BC1DA6BB252
-:1095A00013EC547D1FD9CD7A097F57B8DCDDE27802
-:1095B000A2BB0FFBE983E4979EAF19A17C4D3163F9
-:1095C000994271B1B4F4F12C03EC62C6E70D7ECC84
-:1095D0008DD97E7C5F18472360E6733F59374F195A
-:1095E00058B7F5576EEF40799CB2E49731EA5CE1E9
-:1095F000F91C69DABAD56AEBD66F4797C2FB04FC4F
-:109600001EEBD0ECB0522D8E8F7FA07CAC588D0F0E
-:10961000E5BFEAEB98520AFE87218FB083F0ADAF29
-:109620002738117DC89791804439C336E622FF3828
-:109630007233CFC758C894AD981FB4306A3F96D8DC
-:109640004F2428111C91F5295ADC2444FD2C0AF2E0
-:109650007E5829F7F3FAE93E06ED13F21F6D2E301E
-:1096600025B17D260BA1FF04FD65A3BE67EB12C6E5
-:10967000193D78DC64FD99DB89DAFEADE80C8542A2
-:1096800009727ABB663F1F0B5476D94627C7DF2283
-:1096900097579512F2628F045D0D567131BD3F5D93
-:1096A0007FF7DB89ECEA1712ED44B7A3F18567CFAA
-:1096B0004FB01359E30BB8EFFF45EDC497B21B5FF2
-:1096C0006883F9FDF3ADAF51FEF8B12610988047DD
-:1096D0006F742A3BEA45F92093FE2A6C008F0A93A7
-:1096E000BF25652CD27B4A344F9512F265DFC856F0
-:1096F000087E6FB14AFB65D0B40B5D71AF141210D8
-:109700006F7769713320DCB1B33D89EDF8BCF5F1B9
-:109710009C2E99E070E8E3B1500BE5D7CF64A447E5
-:10972000F43C109DAFF57E8E661BE37523E0E7A346
-:10973000D9FEC1FC2C8A4DEFDC8672E20591FCB0AB
-:109740006F056EA6F7E678C0DFB2B97D582046FEF9
-:1097500086FDF434BCFAAD9BA0DD8A1DCE10AAE1D3
-:10976000E5DFF9E0FB550AE289AFFFFC258BEFADA1
-:10977000C279954832ED6F14F0388CA34520FF353F
-:10978000A5C811DE01CFC3BEDADC9C04B80EFBEA2B
-:10979000A93C7A0687EB18F4D9AE60BB4D0DE42FD7
-:1097A0007AF8BEF73145C960245718D913A2933F00
-:1097B000DD393C2EECCEE1F13C2987E3DB7552A08C
-:1097C0004542BA6EC27D0B294679D0AE9312BD7761
-:1097D0000882A5BDA6F7E73A09C219F195666EEFB2
-:1097E000A0F7381F6C2F7A99C1BEF1E7703BD9DF23
-:1097F0000F471A87C36BEE279DBFD7F8CF0CC78AD8
-:10980000ECA941C4CB619F9A9BC3E3285C0EBB9F2C
-:109810003F208C1F893CE6F9FA17072517C5F56E1E
-:1098200013E225209FDA4B8FAD21B955E46AC2734C
-:109830005209F693C0CFDDF0731503F669DFB43932
-:109840009518BD66CAFDA1C1F6D63B9527E6CDC1E8
-:1098500082767EE20A5DF6C6A00CF6DCDB5AB151D8
-:1098600019BD1643FD97D470FB6C31DA6721925B0A
-:1098700006BBCB6C9FB941DFCF01BA58129064A4EC
-:109880000BB39DD65E398FEC9A76B06B305F7BB0B0
-:109890009DC6E5CD1D511B53A1DE4B3522F9192F75
-:1098A00095F63E7701EA8B497685F44569DF1D73AD
-:1098B000E8FB041AC7ADF977509F9F7708A5C54B01
-:1098C000E0DDCB3547DD8B13D6FBA54947C7A25F4B
-:1098D000B035497E851EA7D97B0BCFFF7AE71E21C5
-:1098E000EE44BCDD2ADAB0DF85E51ECA5B9D26BAF0
-:1098F000699CC51BC5B89370A8A64FCB1EB01B9919
-:109900005893FD2AE2E14E3BC3F3830537F61AEC88
-:10991000DC8551A33D176902FB47397D3BD06CFFC5
-:1099200099ED98E5399AFD52C12AD07E79A9792717
-:109930003B5A3260C7CC4AB2FFADDB31E7DAEABE50
-:10994000ADD133ED1FCC92ACF7F72FD6FC5316E216
-:10995000FEE034F1435AAF63214941FCB96F7E9E6A
-:10996000CE75B8FF5B0C5B8D77478E43DF8F237915
-:10997000BBB5228DF2AEF7DC72564E2FAD97725FFB
-:109980000DAEFFF3769283C9F45B4A5464C530315F
-:109990004F54A0A7BE9EA3A2292C513F8C4A92A748
-:1099A000F0A31C3E0FFFADCC867E76668CA9567E5A
-:1099B000A95E0FFCD1E918A386FADD9900DFF5C591
-:1099C000368AFBEB7E698A9D9FF7B5EF5A1943FFF4
-:1099D0007414C0877028001FCAE1A2681A9547470F
-:1099E000BDF41C13CDA46771348FBE9744C7D0F368
-:1099F0008C6811BD3F337A36954BA313E839365A3C
-:109A00004ECFB3A2E7D1F36CD05B58AF2C5A4BCFFB
-:109A100071D1AFD3FBF1D139F43C273A9B9EA1E839
-:109A200037E97B7974313D2BA28DF47E42F43A2ADA
-:109A300057466FA0725574253DABA3DFA5E7C468F8
-:109A40002B3D27455BA8DEE4E8062A9F1BBD9B9EB5
-:109A5000E74537D1B326BA85BEEBFC9CA6D9D32FF8
-:109A600006B6C9946FCFBACB503E26E3C3439A3CA7
-:109A7000AECB51F722FDE9F5F66BE70ECCF50EE41F
-:109A80000C9D77F3AAB65E1F858EFC008FD3EAEBA0
-:109A9000B63E30741C8195F986D9B7E2F37B3A471C
-:109AA000E1F42B7590BDB1B589513E98A7B24740FE
-:109AB00079D319906658D1913BC0F3C08A7222477E
-:109AC000517FB883EFEEC5FDA84B623DBEA9482F7C
-:109AD000215FEA54E86F549B8DDC6B85C902969533
-:109AE0007A2677B381780ED85706BD260574FBAD6C
-:109AF00067E60484E7ACE20AB25FB5FDE4FDB78C2B
-:109B000066E8776C75740B12CACB558C25DAE15B6D
-:109B1000D72E7A28F19C8614E0FC396A1D7B0AE373
-:109B200064451D4A1D9E271CB3597D0A533C4BE2D8
-:109B300091BA54289FF970EC297C8EED8AD7A5C183
-:109B4000F3EC9DDD4FA1F819D7DD5BE786F239CF45
-:109B5000B2A731FC54DEA34CF54079C201F569DCB3
-:109B600026A9EA8D4C4D57109E786B3AC0B3F56D1F
-:109B700030B4A03CE9C30E11DC9281F507BBEDF1D6
-:109B800084754929EE5145F867FE8D7239CAD9AD01
-:109B9000526F4A66D9E0F5E9C479E33C41AF6CD72E
-:109BA000F6D1E584F50805043D1EE80B24C4033B0B
-:109BB000DB5EA1786067AA5C8BA1AEBE694C7E506B
-:109BC000413AE67E42EA9AD1A49F74BA03FC1AECA9
-:109BD0004929C0E96E6BBFBD698DDF10E2B7EA7F2E
-:109BE0000F7EFF3347935F49F0FB22CE23383C1FA3
-:109BF000D706385F021F9F1FA84A5EEF2A0DFF6637
-:109C00003C6F95E4B3085F6E668B950FAC5BA34623
-:109C1000DFC3E1F59BFFCBE876526068BCB24A2F08
-:109C20008F336BF969C9E4CDFE24E7449A0283E4DB
-:109C30001C8F97CA20E7C6249773358161E4579239
-:109C40007C87DB027ABE43F8BB8111C4F5EFB0C953
-:109C5000B598EF121BCFC84F00FBB20DF37746C586
-:109C6000940ADAC642A18C78AC389BFCF422B03757
-:109C7000A40A86A98EDDF8BCB832D3B6A80CF31AB4
-:109C8000347E931B0389FCA6EBFB017ED4E922AB57
-:109C900093CE5900BD623EE12E0D4F03FDF078C416
-:109CA000DA9B733BDB13E46067288FCA7AFD64F4A8
-:109CB000FBA6F61DE405EDF75F5C639D6FF2EB809C
-:109CC000A8D9397D2AD2796C0A93E9BC73DB119249
-:109CD0004F99209F84221E1EC2F1F3A3A90F619CFD
-:109CE000F657816C4D9ECBA99779FEFFD1733BF857
-:109CF000EAC44F35F21E3C57310AF4908272B20624
-:109D000060AF443DE7A07557185F47A586C5BB0502
-:109D1000C25B37FACD311B3F9FB1DFD1A592DE7117
-:109D200064CA987FB2CB1FD91BF027E70B394D29A6
-:109D3000C745FDC3E66B67BA83989723A762F915F9
-:109D400028DF3109F3847A9956BEC33DF98BC71FCA
-:109D5000FE10B8663FEE535507D457919E81AEFF73
-:109D60008070A967CA12C58747B8FFA4F3E7003F10
-:109D7000C9E53A3F3596913C7C2790B04F9ECCBECA
-:109D8000F9A1263FFB0243DB373ADD9FB67DA3C135
-:109D9000FBF630FC3FF3B957376F6303F13F4FEEEB
-:109DA000EB3D9282F6F654767402C6BD7A38DD3306
-:109DB0001EE75331FE07749052E932C56D85195A7A
-:109DC000DC65C878AD1E4FD6E37D7A5C2F5DA32B92
-:109DD000BC3000F578FA24595A44FDF5B24BA13F46
-:109DE0004F90E349E76B945BB83FEF5A93258D2E74
-:109DF0001BE8172425C9A9CE0626B767F2FDD70CA4
-:109E0000902F1DAB19F979B19744EAFFB86AFBC0EE
-:109E100009F58E570202512EA84C91B3B573084430
-:109E2000E432D1AB93B12EF4B7D9F7422E07C6B9BD
-:109E30003F15980A70EFFF54A4A784116E687471DF
-:109E4000A83C848D6B336A42B81F281E8532C059E6
-:109E50009F519381E5FDFB27849845FCEEF248A3D2
-:109E600021BE64C6537FBD6FADA17C852DC3EC7F41
-:109E70004E0A3A74BBB32288F6CE957D6D0E6560AE
-:109E8000FF53DFD70B163F7121DEB3135CC6EDCF56
-:109E90005C166F49B49B12F6176BB09F2D03FB8BBA
-:109EA0003D6724EE2FAEC8BD158FEEFFB07F7F312A
-:109EB000720ED657BD5DE5489F7A3EEC7E07DF0700
-:109EC00060135EF02916F4B1A0FC193FD1A3E64F50
-:109ED0000CFAAEC5CDCC7EF0ACA0318E7F3C3427E1
-:109EE000A31B3F2689E3EBF13CDD0FC6789D6CC9CF
-:109EF0007746FCEBE32F10B81FCBEC02C93B5D6F3C
-:109F0000823C8904FDD48CE2D1AA53A07CADE3A1AC
-:109F1000C50AF94549E44BFFBE01EB2EB1DA675D96
-:109F2000A0E59D98DFDF1CE4FA79819DC72985951E
-:109F30004B2238EE82A04B7026D8495705B9FED285
-:109F4000F75F1CB927AB10CF0E4744B19AB7791F02
-:109F5000E5AA20EB3FEF16B2D07BC9F074C0DE411A
-:109F6000FB72079688745EF7786422DDFB904C2EB6
-:109F7000BC89F453C25838978F37B08ED678D3F354
-:109F800064CCFB55FDDF1B53E8FC8D395FE6510DBA
-:109F90006FFB34BCFCBBF365F669F87B518BCFE8F3
-:109FA000F1AC8B93C8FB736D750F131D0D139739AF
-:109FB00043CFF7D1F0C39E1E4BF7726CE8B1C75385
-:109FC0000484C746FB970D7F1043687FE9EDDC26CC
-:109FD00079A1E7EFE8E5B493028B27EC23A4495D70
-:109FE00014274D3B29D17B33FFDD6EE23F7D5D922F
-:109FF000ADB3BE2EE6F79DDABA1C68FC8F009E77E3
-:10A00000D990C22CF3893E0B1AE3EFE63C8064FB47
-:10A01000DC07B576C7239373502E3738622523E1CA
-:10A020007B1D3FAF7FFE1B17F2D98693CE1956EBEF
-:10A03000F14A90FB2DA04FD725EE837AE6BFDA8652
-:10A04000BDA649C67D505D9FEAFBA06995E67D34BB
-:10A05000EB7DD00DCC5A3E26DB071DB4FFA9E9DB12
-:10A0600013C124FB9F65439F67DFADD1F370791F58
-:10A07000973BF87959F3FB17FAD7617DC10F80AF91
-:10A080006E6874D2EE5377A393F87071630AC56556
-:10A090001797F378EFE27B056DBFCE18877D11E44B
-:10A0A000C5323C5FAFE99DA32C5C8DF6E8AC4AC19C
-:10A0B000B04F1EAE493194E72FB9FB45BC37E1A53F
-:10A0C000497685E2CFD0570CED821A9EA7C894BE80
-:10A0D0003B30CEADC79FF5F57FA9E628DD8316039B
-:10A0E0003BBF2484F16791F8EBA5D726F07BE98488
-:10A0F00081FD7005EC840DE78EA17C8F8365DFA068
-:10A1000038EF068C8BC34C377CFE9B194447A094D8
-:10A1100063C8AFE3B3E2281F178FABC846BA7C7A97
-:10A12000FCA71E8C8BBE73EB713FAE536F7313E5B0
-:10A130001D98D7DD1C6736C7974F379E3C31B73F18
-:10A140004F80E8E145533C59975766F991104FBE4F
-:10A15000207704F1645D6EE97242975F07CBDADF26
-:10A160007A10FE7930E22498DED4E6DDCF971A5DCE
-:10A170001ED4F9F07327D9234F8FFF2DE55BE9F546
-:10A180009A8399C487DF288BDB697F16F3144A070B
-:10A19000D6657EE49AFE3276FBCDA52B0DF4D12F49
-:10A1A000A786956343CB293197C72792E56BEA7C55
-:10A1B0003058FF94909D9AF67B7BDC55F4C5F550A2
-:10A1C00043E3AF146C07CFCDD47EBC2312B7D04F7E
-:10A1D0006678D24E8A2C3E21F1BDC2DFF7EB010733
-:10A1E0007D8FD529AB57FBB83DDD4AFC1973D2FEF4
-:10A1F000B94F6DCE85FA3EBF1A437A78C8A7B6E448
-:10A2000026C8D3563BDF8F146D2CF2B8055E9ECC6A
-:10A21000D5F4320B07B0BF35B5C6F35CFA737B2EAD
-:10A22000DFDFDBE3AF0EA07DDD7AB83C80FCB3D787
-:10A23000534DF676B275BB53E727945F2503FEC4F2
-:10A24000466DBD814555DCC75D630F0712E38DEB9D
-:10A2500072791E47FAE4277AD06E6E956D9427D8EE
-:10A260002AF3FCEB36B734639BD6CE676827E9E761
-:10A27000A8E8BE0CC96DCCAF7E52B37792CDF3C9BE
-:10A280005C9B76BF68F73D35C2805EB11FA975D172
-:10A29000FD0F4C95797E53C8904F6DD7F44B9D2997
-:10A2A0005F4394BF98DF16F44776E55AF86D7B7CE0
-:10A2B000EA93B8DE5129E644FA88BAACF9FE696D32
-:10A2C0005DBFA7CDD77CAFAA68BAF74134DDFB10DC
-:10A2D000AB6BFA692FD2DB6AA7DCEAA37B1EE8DE50
-:10A2E00087285EB904CF7FA6F07C16F0FF26F2F334
-:10A2F00006A15E94AF2CE0A2785447BEAAE643596B
-:10A30000F4D81E5C0DFDB5AA752A1E5DE970DB3A16
-:10A31000719F2F33183988F398EA9148EF745C9451
-:10A320004A7A08BEA77039C264A19AFC41BA3405C2
-:10A330007D703C5F660F38289ED51A61BDCE31FC1A
-:10A34000FC3FF653CBBAF7D714A1BDEDAA443CEDC0
-:10A350000F4DC88858C809FD69DEFF7FEBDB6F141D
-:10A3600062BB0231F221E2BDA761F146DCD75FB1E9
-:10A37000530CE13EC2B7BE73F00C7EDEC8B8CF7C92
-:10A380005FDA945ED46751B783EAEDF15477209E8B
-:10A390005A054F07FABBAD8757FE18F1D8DAC2E36A
-:10A3A000DC663CEFF57C87EED7380ECB89F5CDF730
-:10A3B0006BB08E957C9D9C2EDAB784F9B2BC2ABE18
-:10A3C0008E141F3CE4A17BA08EEF7FDA8DF07D8997
-:10A3D00079A7E5F9879A77BE4CF68B463F4C0AAFD2
-:10A3E000C379DD247A3ADA7D784F1AAC37C2BDCB17
-:10A3F0004EFEFE7D69E9B4AE51800FD755F4D4AB63
-:10A40000E892FD7DA748EB1C959A685E2C26B1ED7D
-:10A41000F87ED789EF9F8774A066D1AE9658D04456
-:10A4200078F93BE065B5055E807E8A10DEA777DDB2
-:10A4300040FD74385C325A36AD9E6A3AAF3CD2FB6E
-:10A4400045CAF2389F24DC2F52965765515FF3B30B
-:10A45000D0DFC6716B65F6499C0DE03D59FECA79A7
-:10A460005AFFFDFD0C9FBF725EE2F8FAB85F625DB5
-:10A47000A79FCEBAB6BAFEEF74B4B354313D94522E
-:10A4800008655C27C43FAE13AE9716B72115A4200C
-:10A490001DC8DD79480737A487903E87931B12E3D8
-:10A4A000EB6E97809EC1AE73CA91037476518BF7A1
-:10A4B000E8F2C4CC67AD2EA3BC6AD5EFE53B3432DD
-:10A4C0007905F47215E2C12CB7464A272BF304F341
-:10A4D0003D342BF3FCC9E9C41E0CDF80EB8878CA3D
-:10A4E000ABA078C5B7B1FEFEFDE20EC7681C8FC7F2
-:10A4F000CDFA824C7E30212F4B87A70D37BB799C3C
-:10A500009AE21F5203639807E72D0D0972D988E874
-:10A51000A82D11BEAF808EEE1C8A8EDCAC87CE6B70
-:10A520002CD7F373760C9D9FF365F50FAC6727E28C
-:10A53000B7D5F31DA2CFB57697CCEF513BBD757D56
-:10A5400064F0BA3E32F4BA461EC3EF6A5E35DD638C
-:10A55000C4263592DDB4CBAFBE8179A44C0A19E490
-:10A56000E220FED1E4F64D672A94AFBABB4593735F
-:10A570002D4E19EDF1677C373C86F5EF624A18E302
-:10A58000A1536CAB084F7F87F93D1822B95A8AFB5B
-:10A590003E51961AD2F4E8538887194A8B9005EFFA
-:10A5A0007D0B141B5D43AA6C62B6B291E3E1C5C199
-:10A5B00072F0C561E4608F46CF37223DEBE7ED9343
-:10A5C000C9C143A72F070F7DC572F0CF79A7A1D7C7
-:10A5D000BF0279F3098E6796376E8D9FAF08B11071
-:10A5E000C6CB479ACF06F6A682FC559BEE22FA69A7
-:10A5F0007D5CA07C29B0C32354F6B848D8ECF5386C
-:10A6000078FEEF0EFE5DACE37836E3E9F3BC2C9EFA
-:10A6100077D3B5322C19F2A462C40F77AAC7E462CB
-:10A6200011F3FB6B889EBD9A3DA3E7F5A76BF2BFC4
-:10A630005FCFCFB4D178DE022EDFBD60EFA05DC466
-:10A64000A45E867EFC4D793C7F1FF881E81B46099D
-:10A65000233F644C924C795A9C5FFC12B777327D51
-:10A660004C205D837962F0FE04D813783F41A66ADE
-:10A670006C7753EA1502EAADDE46779340E7F4C300
-:10A680007B7E04E52CCCF702BEF1CE30D6F7B38446
-:10A69000B2857F1EAB63A598B75896AFF9E90E1641
-:10A6A00020FDA8F9E9FA7D81E2F0795F95F9238828
-:10A6B0002F9E9BAFE79918F571570AB38CAFFD57E2
-:10A6C0003E975BF5BDB5756857AFF230B2AB56A19A
-:10A6D000EEC472A683EEB509EDA97459DD5791A9B0
-:10A6E000DA0CF7F37A67A41AEEBDF587B30CE59C94
-:10A6F000865C43FD6064B4E17BDED2B30CDF0B9A71
-:10A700002A0CE551D1730DF58B00C189E531EB2E93
-:10A7100032D42FE9B8D4503E73F3370CF5C7C617BF
-:10A7200019BE9FFDF0B586EFE3BA5619CAE7ECBC37
-:10A73000C550BF9559DFDFB9219FCB29E0779263E0
-:10A740002DEEBA06FA1D0DD96188F32FD1EAEDC9B5
-:10A75000AC2EC57848EB91F252F287D3CF1DD21FB1
-:10A7600036CBC564F2D8FCBE4D1BEFA3A7DEAB5EB3
-:10A7700086748E421EE4D247EE37D7E29CD697F11C
-:10A78000BC04FD7731CCF7F2F7EF534A2ACD67418D
-:10A790009683599D0F5892AF58EE2FB4092117EEAA
-:10A7A0001525C39B4E8FC3E1ED0EADDE97C5DB21B2
-:10A7B000C11807427DF2B8055C7BF3FBEF3B7828BC
-:10A7C0009FEBABCA54F230F83D0EA7AB4F74384044
-:10A7D0009F3C9EEF1F9C1FFE51C3AB57DDA760FD42
-:10A7E000AB787D5BA814D725D9BED2DE7CF3BE52F0
-:10A7F000D55294730B3CA942E27DCDBFD4EAE9F176
-:10A80000ECD6F44F695FA9D5112A1DC9BED22FF12C
-:10A81000CE8D2AC4BFC2C7D3D7D5AE06644BFFCEF8
-:10A820006CC7B0E7F01E8C985BA2BC61B37F17D5F4
-:10A83000E4B6EECF497B6BC9DF6F758FA6BC8F5630
-:10A840007515E9CB8E247E2EE8CB3FE657613CE0C0
-:10A8500046833F37100F50693C684B76536B82FF3D
-:10A860008FEBA0DEC7EFD5FE0AFCE00FF34FC34E1F
-:10A870005018F7838F338EA7E3AA8DEC84E360270B
-:10A88000A0FC5D2331DAF78E550A8A955FDCB15A58
-:10A89000B30F5773BC99F7BBCD76C6C5A19584B7E6
-:10A8A00035404FAE4A8CC771FB778D9DDFBF297B4A
-:10A8B000C301D4B77D7E077B10A0DDEBE7F1391D26
-:10A8C0002F5F541E65160CB293330B86B093A78985
-:10A8D000655D786FEBB1933C2EA2E051441FDE43DF
-:10A8E000CED76FD57373622B504F15494D98BF2E3D
-:10A8F000322503F1B2E25991C5059463C6FC7C3B55
-:10A900006BFA01C6E3988FBF8F31570BDA49199361
-:10A910008C7A2C5335EA31EF8C2C935E33EAB19C60
-:10A9200006A31E0B468C7A2C6F698549AF19F5D8A2
-:10A93000A8689D49AF19F5D89875979AF49A518FE0
-:10A940009DB9D9A8C7C6C68D7AECEC875799F49AF9
-:10A95000518F9DB373B5E17B7977BBE1FB8467EFE2
-:10A960003294AB7AEE37D49F78E041C3F7C9BDFF8C
-:10A97000C7F01D10FD0A9E67C07B687111CF7BFF79
-:10A9800009E377A63A301FFF3A3C9F09EB787EDF58
-:10A990006F0DFDB10E7E6E2106FFE17AFD9945E84F
-:10A9A0001E009063FBF2A0DDF57121D4CD503F3D38
-:10A9B000FE1EEEDB5C1310C98F5B81C156A4874776
-:10A9C0003C71A487AB371BCF3F5C13379663403F86
-:10A9D0000AC615807E90BEAE33FD6E04D883446FE8
-:10A9E000D7295213DA9566FAFAB34E5F31F5153C62
-:10A9F000CFA1CF579F9F5D3F7FAAD19FAAD11F13A1
-:10AA00007711DCD7E589F4FB3BFA7C55F88F7FFFA3
-:10AA1000D081F338B153605EDCDF67B17D7916F326
-:10AA2000B97EE72607F2A7795EE6790CB2530B8C64
-:10AA3000FB8AD3447788F8EE3591F4114D01F9EC97
-:10AA4000517E5E6FD573229D8B413E447F418C3594
-:10AA5000105E56005EF0DE70DD6E3DA6B53BF68002
-:10AA600048E79B87E34745C3873360E4C71425D590
-:10AA7000444F46FCA6951AF9F3BAB72F74A0FCDA36
-:10AA800007F8162631E60919F9F53A7119EDF3E9D7
-:10AA90007856E03F1C57025317E77D3DCCBB5B194E
-:10AAA0008CDFA5BB36ADCDB3A09BE1F0FB48817137
-:10AAB0009F4EDF9FAB05EC382CF24A75FCEDF2ABF4
-:10AAC0004FA07C4CE60FEF2E30EEAB8FC01FDE9D0B
-:10AAD000286FBF027FF8B98221F55CDF2CF4A79CB8
-:10AAE0002C3DD46E11F79398DC8DF15A7B138FFBBC
-:10AAF0000DC4EFBEF238CF3B08A724733D9922E97D
-:10AB0000719ED08108DA27196785302F6AA4718E6B
-:10AB1000BF140C8A73FCA560E838C71B780E50CDB3
-:10AB2000C8ADB7213349A152BADF1941E079481FB6
-:10AB3000E3BA0CCAD72DCED2F28F9521F38F2FD640
-:10AB4000F677AB03EA498403FAFB149FFDF7B1558E
-:10AB5000FAA99FF461FA89D5717B2D66F374B472FA
-:10AB60007B8DF699BE8238467A21FAA56E8EFF5605
-:10AB7000078FDB9E6E9C2D583808EFC1C221F0FE76
-:10AB8000CFB772F8B9D5105807E5C9E95B3F87A977
-:10AB900097D7671AFDE5B5151CAE126DFC6F66738D
-:10ABA0007F607221E73F3DEF12F316532AA03C93DA
-:10ABB0009F53D2CFB5EAFD4C2EF450FD4F02759352
-:10ABC0000BFD9837CBEFDF599B69BC87E76F05B565
-:10ABD00093715E13B4FE2717329ECF3C9AC365CEA5
-:10ABE0003BFD8756FF1F0575F4C473B4E8973844DE
-:10ABF000D1129F530A799C40BFF766BA7E7EEE5E03
-:10AC00007EBECE7CEF02F0C9EBF8FB5047EFB0936D
-:10AC1000BF07FA88CECF2DC9E3E710CDF729444A04
-:10AC2000E57D285E4FB032CB7B7906E5391CBA99B9
-:10AC3000F2EF5E9ACC6421387CDEC36585C6FB11D9
-:10AC4000BEC039BA2B0A4790F7B0503B47D79BCAD2
-:10AC5000F5585FD0157FD0C2DF8D6AEB7487E6D7D9
-:10AC6000E2FE34EE93E3FDDE56FBE5D1424E3F2398
-:10AC70003D577D97231241BE359FAB4E769EBAD786
-:10AC8000D1BB2607E11DCB4268BFE72C90F7E4401B
-:10AC9000BDD47A85CE3FAE2D62E993F07BB92D8489
-:10ACA000E73A32E7CA6BEDC8A7C52C4B80726F6CD0
-:10ACB0000E8D7F4703934580ABB390EFA32FBCF578
-:10ACC000631ACF5F035353E8DCF974F4CF620D8C41
-:10ACD000EE2D34CFF32E8D5F5C6BF83D3919C5D660
-:10ACE00079F87769F408726B13F2456D31DBC1CFE7
-:10ACF000CFF2730A782D3DE56F8652695FF01258E6
-:10AD000037BE7FDE43EB776360EA7DB89E3ABF399A
-:10AD1000B43C05F379F2CEC2D33B4F9EBAC01ADEE3
-:10AD2000DF69EBDDE80FFF14E14D2DEDE0BF5FFAC9
-:10AD3000F9A95362B5F6D38E0AB68F4450FFA580A9
-:10AD4000FE13F0A9C8748E96B9043A0FEB529A8894
-:10AD5000AE522685BCF8BB68EC4A1BC37B5CA66A76
-:10AD6000EDD50626E0EF49502E20C969D3EF4BA858
-:10AD7000A1B616683F0DF7CD4298F71D5A8AFDD54A
-:10AD8000BB53658C6FA61437D5E27A3DB390F7714B
-:10AD90005792F312FA39FB81FBA796BDBCB726E1A7
-:10ADA0005E81B557BD6CBC7FEAAA97BFCCFD530747
-:10ADB000B75EF5F2FFC4BD02BA7C03356447BBFE43
-:10ADC00080C8EFD1FBFB9397DB711DD6D6B22EC4A2
-:10ADD0007BEC53C0B36B00CFF6BAF0335BD02E5987
-:10ADE000951EE2BF2712FB16C2F9761A93B1BD9EDB
-:10ADF0006F28B052D2D7731B04B21F98D4773D96F8
-:10AE0000E7EF4A93D17FF8FB936F14C4803EDFBA1B
-:10AE1000EDB807F353DF91FA3C08D7FBB7BEEA4120
-:10AE2000FCBD75AB48792874EE3B214FEC738DBEA9
-:10AE3000168C0A1F47FA5AD8FCDFD589F6198BFA07
-:10AE400049DF5F13078813EDDE87D30CBF2BBABC35
-:10AE5000CB6B28EB7A7EB9D3FADC7CE5282E97AE53
-:10AE600079A4D391A7E0F811FB2898E7FBDA39A081
-:10AE7000F77778C88ED7E159F448B903EDE17776D2
-:10AE8000395937C5057BECCCCDF507E65D44F8D0E4
-:10AE900083E0DCB73BCF817CB644607D4E626EB60A
-:10AEA0000FF1FD27CDFF33CF63C95BB203D77749DD
-:10AEB0002DEBC373678B6E14D6DE04F51745DCE407
-:10AEC000F79BE769D63757E37D3682D53D704DFB5A
-:10AED0007E07FD5C09FDA0FDB9A4C3F8FDD8B3371A
-:10AEE000ECDB02E3EED8E9207BF1EA61E2FD6347A7
-:10AEF000697AA99A4D3C3586F45FC63825B9DDA13B
-:10AF0000EBA3F79B1925A9FC057FDF179E1F36CB06
-:10AF1000F43C5EA8D07A5CB773CF3EFA6D61A9A706
-:10AF20001AE5DDCCE716A77D830DE4155577DEF035
-:10AF3000F41662053D5FB59BE27B13B5FB5FAED6B1
-:10AF4000CE7F541D30E7ABEE79E67768B7C1FC4F92
-:10AF5000E7DE9E0523BCB7E7D8B353D3E87C808EE9
-:10AF600097898017F1CBE32559BBE5497EB745E7C3
-:10AF7000A7E39ADEBD72DBECB5B9307EEB937F2E92
-:10AF8000C4F8718C71FAAE7A80FFFE4F953B9BE856
-:10AF9000CD85F41944BC9AEE7988B1D759027D5F0A
-:10AFA000BD2B8DE82400F6907312BEE1F45A85F7AC
-:10AFB00076227DBFC6DBBB34FF36B2EB365EFF7751
-:10AFC0000ED91920BE0CD8E8D91DB04DB2B867CB48
-:10AFD0007CBF5887B1FC91BDB710E5CAD5263FF4B8
-:10AFE00023C13A3FED8A51A3497E5DA9A8D3310F11
-:10AFF00060090BAFE5F15B7E6FCFFB52C7BEEF225E
-:10B00000BF6F13580CF0B4FC378FFE1AE5D8B58F1C
-:10B01000DD9B8E72EC03A9231BC75BB67D4D3ADE28
-:10B020002FF3BE144BC7F61FC4B93C1BA42F47090E
-:10B03000DABE949A2E804CBE9E480DFE7F65DFDA04
-:10B040005B609C7F009E91EFAFDFF12F2AEF535D95
-:10B050007D2C80FDF64E4738AE697437B584D0BF7D
-:10B0600034F2E7B53FBD375BA13C8F589E86BF3CAD
-:10B070006C77FD363BE5F9A21F8FC3AC607D343F92
-:10B0800073FB155D471D28AF651BEBCB3F6FF0775A
-:10B09000B0901CC86F2B766CF8584CC7E7076FE26E
-:10B0A000EF41AD30D9A74B35F96DA6FF9F9BE81E48
-:10B0B000F043F18518C0C57F8E89CBF1D69FDD376F
-:10B0C000FE30C0F7E1B617D2F1F72674FAD7EF7960
-:10B0D0003ED6B578A163887B843ED2F8A45F3F68F2
-:10B0E000FA49D90980E54071177F2EB377A79F07EA
-:10B0F000F35DD6690F21CD2F7B5454DD68571D7445
-:10B10000923DB2ECD1E344B7CB04B54F203DC7D25A
-:10B11000518EEBEB75DDA37F9A8E72FABAA0C866EA
-:10B12000022B5EFBCB13BC3ED0790AD4BFEEF1C339
-:10B13000D3BF8B6590272E8BF59ADAB5C7D1EBB6C6
-:10B1400058AFAEC3D3313EDFFAB37FD27A7CB05B67
-:10B1500060394583DB2FEDFC13C5C13E8485F16664
-:10B16000727CA1BE59D125363A32ACD6AF7BD66FB0
-:10B170002BE93BE5850FB78E1B4631AE1F7FF3E809
-:10B180002F7E0B702C7DD3199A89E3FEE28674061C
-:10B1900074F067A989D3FD8FD664A3FE5E6A8F65BC
-:10B1A000CBF4E4EF976EFD36D1E3D5BFFF76B6B6AC
-:10B1B000DF10B4913C8805719E4B1E9847F3BC8A02
-:10B1C00045881E97FE88DFB37802FC6C2B3FA152A6
-:10B1D000E172CBC9568EBFC5877213EF6C01381C64
-:10B1E0008CDFD7F50ACF7F77B24B3312ED5C87C285
-:10B1F000EDB9188BBF8D76E70A50CB28D7C4DF9FF7
-:10B20000988EFDDC58243539293E6A7D7FCDFF03B9
-:10B2100074C90FBA00800000000000001F8B0800F6
-:10B2200000000000000BE57D0B7854C5F5F8DCBD8F
-:10B23000FB0A792D79404220DCBC1309718104128C
-:10B2400040DD10C020AF0D444589B0040C0112123E
-:10B250009116ACFE9A1B0208946A50AA54D02E088C
-:10B260008ACF0604C18AB01145A8FD300AB5F8A2FC
-:10B270008B206F6441A8EBBF54FEE79CB9377BEF8E
-:10B28000261168FD7D5FFFDF3FFDEA70EECC9D3B40
-:10B2900073DE7366E66C0D83BF64C68A3E1ED6D528
-:10B2A0009BCD98855D34DF97CBD825C6A467EC8C01
-:10B2B000D530A3ECB532FABB9AC4D88975964EC284
-:10B2C000CD507661954DD0FE2AFEDD1628A74A02A4
-:10B2D0006379D4FC13D69FB1D9F82F09FAD97862D3
-:10B2E000F86AE897C5892C328EC3CFC430662B0F1D
-:10B2F000AB8DCC87EF1D3C6AEE06F5728C81A5D92B
-:10B30000A0BEE51B82993D56C2F66AFF35DB2DCC07
-:10B31000A38E07FE5FB3FE1B33C37E0CCCD77D50DC
-:10B32000DB7AC66A737E1583F38894964179C2EC02
-:10B330001BFE367E07BEBB01BE53B112DA676AFA46
-:10B34000DB72EA739683EDCD81E749F8DF057C5E19
-:10B350006259A42B8CB1E9304D56D076FEF3BFACC8
-:10B360007FF43D4D7F395278CCF150F8C70036E07C
-:10B37000AA18789FAD89652CBEEDFBDFD7C98FBEBB
-:10B3800067C2B765C6A04995C9FD02E2A9EA338B39
-:10B390005D063C56BD76D96C009809CC97D699B11C
-:10B3A00033AFEEFEF45E98CF992653CC28FAAA2349
-:10B3B00042E812C07BE5E66F86AF86F626C07B08C2
-:10B3C000D073F696EFCD06681F57C47C1618FF9908
-:10B3D000182763BD116FA6AFBD1ABC15C1736F18D6
-:10B3E0008D23C11087A5278141393B86D93DF0FEC9
-:10B3F000EC83A25D427C31DF625B58DBF76B9A8E97
-:10B4000006D1455FCF98CFECC4EF6EF9CD05314240
-:10B410008B77E3D75E0DDE553C07E3F59E20BC5EDF
-:10B4200066D991F01976FAE5593D5DD96DF1ABE237
-:10B43000F5DB3A864CDEFAFC624F89F02C6D870F03
-:10B440007585BA1D4AC9D8A74C83C799AF9C23FEFE
-:10B45000FD47BCC844E09BD9EB7F588C7C0568F560
-:10B4600059807F67BB2F10BCC861F531829B4B852B
-:10B470009CF6E6ADC767707D77446A5E80FEA605E0
-:10B480004C0E877E7DEF88EE7530B4F3922F220A42
-:10B49000E6B728844D764279DEA6C09D55984D9E2C
-:10B4A00002E33C2FE7D8647C2F844D6802FA9C7736
-:10B4B000FA223A8705E67D64871821417BAF9B1508
-:10B4C0003785B5E543C61AE8FB5ED6517D3D8D73E1
-:10B4D0009878E5752F7CEFA26C6416F89EB7FEFB9A
-:10B4E000D7BD501E335A6D88A769F5774730037C66
-:10B4F0007F47CAD809D0EEFE7D803F9A9EC31C0FBD
-:10B50000F89DCAA7CE4E32F9A9C1303F313C77CF62
-:10B51000DBF07E052056047E9DB65C8F9F99CC198A
-:10B52000E94942B93505F884FEEB367BE0BDE9AE6A
-:10B53000B0DA65F0DDCA35FAFA993BCE107FCD0C52
-:10B54000E22F17F2577C5BFEDAA0F2571FD607F9FD
-:10B550006B981866407E3EBF57745BE09D8B0B4D29
-:10B560006C31C0175F15DC0CFAB9B8031A21BC9D09
-:10B57000C34C8E25BE55F95CC5DB59E4BF8CB6F8CB
-:10B580006CADDFFA55FF87A149D59B5FE4AC86F22D
-:10B59000EC9B9FA5BF8DF0B6BF257EC1DAB62FDA32
-:10B5A000F9C3241AD74E0BC3719DDFF941E2C308DA
-:10B5B000FFC96247BE3DBFC0E260A8EF7686BBD33D
-:10B5C000B0BE07F003D0BDE19DEF7350DF33B690FE
-:10B5D000E8D82299A9BCB8E39F87059CC70E8B8445
-:10B5E000F3A8D9094880F76BFE14E266F8FE3BDF4A
-:10B5F000F77785FD7CF3996D662EE2CF7036613367
-:10B60000F26F67E6C0F9D4BC5DF07C3D7CBF7A4B3D
-:10B61000B3792AD417EDFA570EEAA3F39B9BCDA872
-:10B62000AFBE35799F63C01F5F48131B4D80E76F26
-:10B63000C3A1B36E8CCD4D5AED94C3DAC30BC7C30F
-:10B6400079C003CE0BF052E9CEEE181F17FF6BF155
-:10B650007161127EBF6AC700262669F12238F8F3AD
-:10B6600070B755A0F9F3E73BBFCF6161D79EAF2D0F
-:10B67000C94CF2FEFFCB7C7392FE5BE9CBF9FD4D2A
-:10B6800089DBA560BE6FCBD7DB7E49F0EBE1761A94
-:10B69000EF75CAFB98FFDAF9FFEFD0BBEABF76BEC1
-:10B6A000D7A2F73E85DEE1360BEAAD77FE95C86E90
-:10B6B00060DEBFF97F74DEADFE8FC16ECD85F17D9A
-:10B6C000CEDC77160AE495B4EB8F6C4F12A83D538D
-:10B6D000D61D6314BFA2817D3D740A7C57067F028C
-:10B6E000FDFD86B0AF8D07016E013F01FD0B86CEDB
-:10B6F00009E0A1A5B48F7B19DA6D632DB3016CFA53
-:10B70000742AC113CA7F30E642FB3BC1CFC3F6FBAC
-:10B71000EBBDD3EAA17E7F6783D400F058C7F8B4AD
-:10B720002D00DBBA89365CC73438FA5925CDF8C606
-:10B73000E6EBD723F706AD2BEE9EA0AFBF8BAD8B0C
-:10B7400035427F77559A981BA6746750FBA7926C79
-:10B7500034CFBB59ED225BD88DE3E978125F9F357A
-:10B76000B0BE7B25C48B43B46F606DF1C6106F888B
-:10B7700097B87E6C991DBFE2351E04D8A2F857F029
-:10B7800047F278678CF505C49385CD61BF84FE2EA2
-:10B790004BC65A6C6F61B06EE4E316AE0A6DF106EB
-:10B7A0007F92B13FB9E24482B18E0719E2199FF747
-:10B7B0008CD3BD4FF30EC6F38DE37541DA5388D7B2
-:10B7C000D270BB1BF9C2F17CAC11BED700781684D5
-:10B7D000003E553C05E3FD6DE40D8D5FAE96D9CC82
-:10B7E0003709FDCE0816615F06FD4758BB33239F1E
-:10B7F00087CF128F858DE17A4D1CC29A96C17A8DC2
-:10B80000E51BCFB6CE2B99EA3D0FC37B0D0FC0FBD6
-:10B8100088D7EE4C7212FF97D98EF7C2659E8B5D6A
-:10B820000D0DF89F1FE583FF994425F1ED47EBB916
-:10B83000BF7979F01B8BFB80283198B3DC1FFD5C4E
-:10B84000E54FF696E17B2233D871FDCB1C0EC9D6AD
-:10B850001FFB65B4AE89CC37E8D6BF9D1D9D7478BB
-:10B860008B2E8ED2C1B1CE6EBAF65D2724EBEAE301
-:10B870005D37E9EA132AFBEAE01EB50375ED7BCEDE
-:10B880001FA28393E43B74ED53968CD3C1698DF76B
-:10B89000EADA67AC2AD7D567B967EAEA7B6D9CA379
-:10B8A000837B37FD4AD7FEE6ED0B74F57D3CCB7408
-:10B8B000F5FDF63EA183F35A9ED1B51F70689DAE8B
-:10B8C000BEC0FBB2AE7ED0C9CD3AF816DF9F74ED94
-:10B8D0006FF3BFAB830BD987BAF645D6033A789896
-:10B8E000ED0B5DFBDBE38E06C53B6CF283B9A8C6AE
-:10B8F000809F40CE46486774ED618556867C6352D2
-:10B90000F86164E677BAFAD1F67FEAFA33B35A20DF
-:10B9100002B25523959D58139561AC85CA877ABBB1
-:10B920004626A33C3C272F46A6DA5FF07D22DA911B
-:10B930008F063F2823DF5D8E6336B10F8C87F98C2D
-:10B94000C8D786D02BDD5D9AB851845F649E7EC0D7
-:10B95000877E814A9B3F9479A2810FFD215446F94D
-:10B96000A3E979B4BF339531FE047A1EEB8FA7B2F9
-:10B970008B3F85CAAEFE242AE3FCBDA88CF7675135
-:10B98000D9CDDF8FDE4BF0F7A1B2BB7F103DEFE1E9
-:10B990002FA032D15F44CF7BFA0BA994FC23A94C92
-:10B9A000F28FA032D93F9EDAA5F84BA84CF54FA4F0
-:10B9B000E769FE7BA84CF74FA532C33F85CA4CFF11
-:10B9C0002C2AB3FC33A8BCC9FF20BDD7CBFF009500
-:10B9D000D9FE87E9796FFF4354E6F81BA8BCD95F0D
-:10B9E0004FA5DDFF1B6AD7C7BF94CABEFE27E97902
-:10B9F0003FFF0A2A73FDABE9799EFFF754F6F73F44
-:10BA00004FE500FF5A2AF3FDAF5059E07F89CA8104
-:10BA1000FE37E8BD41FE4D540EF6BF4DCF6FF1BF6E
-:10BA200045E5ADFEDDF4FC367F33950EFF87F4BCB3
-:10BA3000D0BF8FCA21FE03F4BCC8FF319543FD5F20
-:10BA4000D0F361FECFA81CEE3F4AE5EDFE2354166D
-:10BA5000FBCF5039C27F8ACA3BFCDFD17B23FD1765
-:10BA6000A81CE5FF273D1FEDFF81CAD678C26053B1
-:10BA7000905E6CD57F86AB50B2B0A876E36DADEF2B
-:10BA80002BFA7845E8730CE31E636A055AA73F1D3D
-:10BA9000FAED7BA4270B2C12C28BB0693CFF8EAD54
-:10BAA0000B63F7E13F24C69A0B2CB47EDFFF3FFC0B
-:10BAB000BDC58547BF7C10EDE3031686F63158FF00
-:10BAC000AADFFD287F772CFA618BFB7AAB30FEF280
-:10BAD000DB246F1996DB92B93FF27A32B7B75B93EA
-:10BAE0000D543EDEDB4665D903699114A78AB9BEC1
-:10BAF000795D56ECBEDAFEF7A90A1CE64B247B7191
-:10BB00009DFD5C6FBB45D65FFF01E33A8E06230BBC
-:10BB1000B9156023B7F7F297E1EE0D30257948EDBE
-:10BB20008B18E79117586C0D3188E75FFF11DBCF59
-:10BB300067CC6981F29964D77ED40BDF8724BAC1C0
-:10BB400038C25FED8071E13F6BFF9FFF2FF77FFCF5
-:10BB5000A7FAFFBBC247B7A7384F27A35F6074E4BB
-:10BB6000201D862C881763E0FD29CB051BF2D1D45C
-:10BB7000857D86237FF4650E8A93DE17CD263BDB19
-:10BB8000F1CBA2520C8A7F2199EF86F19C63CC8382
-:10BB9000FE44B9C4882FCB77086E99E2D08E88D145
-:10BBA00060BF2B15BE2D5F526F9E07EDAAE379BCD7
-:10BBB0008CB979BCCC0AFF43399AD5B8760F851B6E
-:10BBC000C52B141FBB8C7E2FB0CEAC8D6DE3B1F3B3
-:10BBD00030CEBCDD6C43BB51DD1414CF0D8A9B0508
-:10BBE000C7CB4253C263505E999DD9799C3BACE26E
-:10BBF0006FF83D16218931D7C68B1A9F9598D415B9
-:10BC0000F1384CCC8EC475CCC5BD69910C4B49EA5A
-:10BC10008AED5C408B162805A36B003E077CCA4862
-:10BC2000575F7DA87B1D8CEB08D813A91F0AB76B43
-:10BC30008019E3919FF760CB04A21AF96135EB45B7
-:10BC4000F2EBBD0BFEB918E3D833928CB40E988298
-:10BC500031771CDF5B9DDDB240FD12DE7DAF091444
-:10BC60007795D99C388CEB6AF643C8AF752E8A1D40
-:10BC7000938F745AD2B9AF0569253B3E4DEDA2A111
-:10BC8000CFC206C26B795C34A7CF7613F9B5409F5B
-:10BC90007AA4CF0CB7E99816CF97D91533EEC7948D
-:10BCA0002FB940F49A19A097AE5D756333D115E8AA
-:10BCB000A47B5E537B428DA31FFB297A15A628F136
-:10BCC0004D855E183FBF1B2B1F8926FD50B6C093C4
-:10BCD00056ABE1D3E07D89D46903239D200FC5DDF8
-:10BCE000383D98D1DE05E9F9DDF23CA257309D8A56
-:10BCF0007F9C4AF4609F87B30D309EFB52D8E4715D
-:10BD0000F07CB2127FBDAF614431C6CBEF49E1FA9E
-:10BD1000F223587F3A60FDF9719D953940351FA88F
-:10BD2000B311FCD7BA3882FF562751F9595D2695D1
-:10BD3000C7CCACB249235FC000661CDF6445AE26A9
-:10BD4000A7A8FB5273E330EE5EFCE3813C03AA50EC
-:10BD5000B9A964D82DB8BE002468F033A134947C0E
-:10BD60006915F69A6CC3E3507F2C15EC1B90AECE90
-:10BD700041BAF62CB35F0046FB65E4FC047CB10ECF
-:10BD8000F9EF9E51D1BAF6772D49D0C1F352241A5A
-:10BD90005F49718AEEF9BD65BD74F0143FACE7E10F
-:10BDA00053A952B14186FE2FFDC544FC7CA97640C3
-:10BDB000D7791C26BE0BC6FF31B34C7104799DC5E3
-:10BDC0008EFAEF6408E7EF937F15DD0DB4EE952949
-:10BDD000EE72D96A93709DF2CBA97222D6FF32140B
-:10BDE0005CF23E882F9161FC80BD6C21FD39759518
-:10BDF000C06494111FA3F5F2DC972C34CF69AB44D7
-:10BE0000E6EA477C9288EDE7C64AD4DF7D295213E3
-:10BE1000F2B36F83C5BE0E6AA77A95F785BEB40FDD
-:10BE2000523DE76F878D280FE92D3918DF2F4BF230
-:10BE3000C4A21E3CBBDE44FB5ED5E2DA8A3020D1D0
-:10BE4000ACDFBE11512091F8117E4F7F1CBB16E76D
-:10BE50001F98AF9BE222DE9ECE6753009FA72BDC8C
-:10BE600039B44E7E84C7E3DBE285919E920D11D2F8
-:10BE7000069CEF54D7005BB6D61EF27DBFA9267B89
-:10BE8000177B36727F6E3CEA8163CB4DC518770114
-:10BE9000BD3F06F174AC31DAB08C16559B89BFCA30
-:10BEA0008D9259FBDDF2E5A283DA837E2F417BBDC3
-:10BEB0004274B101083752FFF212C185FB4EA92C22
-:10BEC000BF2BF2ED830F0CE88AF398D4C13EE3B7A1
-:10BED00020332ECD3ED6CC7744A71BBF97EB3596AB
-:10BEE000F6D68E9FC781525D4BBACF413A6D0AB1EB
-:10BEF0002F9350AFA644E23AF5D441B01BF08D1910
-:10BF00000DCD3912B05ED583DB880E95639AD23D94
-:10BF1000F0BCC5EAFA00F17832BEE9A9411827DA87
-:10BF2000F17CA28C76703EDF5F9BF9F28C9E5A7F8B
-:10BF3000BEAD3FC1E20CF95878BA08801797C486A5
-:10BF4000237E27B226257EE1A6F149A874011FB6FB
-:10BF50002ABEFF36D5609F742017D11F6E43BAA842
-:10BF6000FD1D35F138D7E72982CE0EC7A672F99E9E
-:10BF70006AE072C7760AC4A740B04F5335F6B2865E
-:10BF80002D277B19972032DCB73B9512A5E8056E6B
-:10BF9000FF66A1FDC37D619B40F251B5D1E27603FE
-:10BFA0007FA5A472F99C697EEDA9BED83CA9D68C68
-:10BFB000DF99B14560CF40D3D32677450BEE4BD9FF
-:10BFC000D62E8CA2F74C7637F2A9A2DFADA0105086
-:10BFD0002F4CC77F427DF54AC1ED217E71921D9A9B
-:10BFE0008671135CFFA39ED7E89136FA3D48AFDF18
-:10BFF000CFF4F68835EAED8B3334DC8AE39CB992D2
-:10C00000FBB581F188EC2AE0AAC2E5DE3386C62BB7
-:10C01000505C24F8FBD3717C385E189FC77EE3E345
-:10C02000A9B07339AD6A14DCEE76C6A7E23572307A
-:10C0300093D03ECF5A2FB8911F87C53C40F89D0939
-:10C04000F88D46BCCACE88BB01AE004672537C85D3
-:10C05000E3BF660DC73FD0F913ADDDFD26C66746C9
-:10C06000BC7E03F653C6FDC0DAEF89EE7B80BE28A6
-:10C07000BF3336B9CDB811798635468421DFAFFAA2
-:10C08000780F2E0BBE59F946175CBF964579D20C36
-:10C09000A0B7A2E5A8278A6F09F05FB0BD6E6397CD
-:10C0A00083F0233327D9A13678B22E6FC17DEF36C6
-:10C0B000F453E262F7E3BF003FF7AF171D2139BA2F
-:10C0C00076CA790499F8BF52F6919F5009F36CB083
-:10C0D000E1537938E2E57E3B23BD7BA3E30D1E27C8
-:10C0E00013CB883F31AE877EC8BF3BDE60FFA32401
-:10C0F000F5A7FD8F603D12EC7F7C69721816A0DFFA
-:10C10000F731DF17BF64F4F440F9BD14936C871660
-:10C11000013D1ADBB72BEA79558F5628764BEDF7A0
-:10C120007EB457001F5FF54604D25DA5FF74B413BB
-:10C13000D9013BF1CBA9D03F7CEF97DB42A8FF733D
-:10C14000A3C14E419F65CF7E10C134FA6F414F5756
-:10C15000752AEA13D5AE896B136DC05FAABEBCD633
-:10C16000BAABC3798505CD2B5C3FAF729C57BF40FE
-:10C170007F5395797DBD84CFE7E8723EBF696DE658
-:10C18000C5EDFE2F9FB7D865F20B3CB12887273746
-:10C1900089AC81E8CBFD86CB56E0A73E18BF594E4F
-:10C1A00076FD542C9330AED3A1FD5E6121BF60C6F5
-:10C1B00056BEDF7A5A28EC4A1BFFEF79221E42B99D
-:10C1C000DE2C32B44381F1B4DAED95A9B11ABB7D0E
-:10C1D0009D78C3382BDAB3D9803AE4FBD93BBA3225
-:10C1E0003CE7B2BC903589B40FEF253D062C44F1F5
-:10C1F00069F0C375F1060BB35BAD48A70EE2AFFF64
-:10C2000048BB30690EE1C3978EF857BF5FD3C9634F
-:10C21000EA8A7ECD2681FC9AEAB98511850CBFC3D6
-:10C22000E3669B53B99DDAAAE839C1514B7131F0ED
-:10C23000696C8FE3B8D6F0F8307B9735217E11A674
-:10C24000F8B181CF43906CACAC2F8FCB5BD1AE8576
-:10C2500019C8AE05E3E16BE53BD5A281FCDF2A33CB
-:10C26000F783CF0BFCFCC7BB8A7D7C3795FBC31FD4
-:10C27000A4F238C479F403A1DFF3B758DCF502BAAD
-:10C28000AD465A271B075BDCE8CF18AD611E3107AE
-:10C29000D16BFCB6559E015F93588B09E93926FF97
-:10C2A000818D389FC3DD984DEC4CD54EDC479848C6
-:10C2B0009A81B1FDA62FDFC778A40C6D45582B4C91
-:10C2C000CC3FD103DBAF4118E67F38A4E97D8CB3C6
-:10C2D0001C4E3232DC1790DFB190FD370DF1F6A025
-:10C2E000386527C61AFA603C66F722E4A33D71D18F
-:10C2F0009936683FD9D8C92E72FD33F4028EB752F1
-:10C30000E0FB370BBD79489F9BD942DB712B6D2D2C
-:10C310006CB91AFD53FC6364C7553E8031550D81DD
-:10C320007F0C649CB1F2099F3A18F04AF0F7A973A8
-:10C33000C7ADEC8E9B26526FA47355B2CF88FB29F4
-:10C340003E81F9D6011EEECCF7191D482F076B1A56
-:10C350000BFCEBD9C704FC0E8A007EF76E4FF2305F
-:10C36000C403CB945824D48F354A04772F6651A246
-:10C37000B26F8071AC438304A283C12A9970DECE70
-:10C3800062A12FEE8B562DB8BE71866CF8F5B8956C
-:10C3900083013618F87AF621BE9E9D281F19467E25
-:10C3A000D26026201FD6443599681D0DF282E3EF36
-:10C3B00003DD68F137D1E8E5E3AB84F115A05CA4B7
-:10C3C000121FDF5B2B903F59636E3FAE119BA6EEB1
-:10C3D000CBD9246C3F0BFE857C3D6BC7B634FCDEAD
-:10C3E0007281F3C12C95CF5ED5CBE58034467CDAE3
-:10C3F000115FE72AFDE7A619F839AED6EF3591DDD2
-:10C400009DB5E38343B8AEECA8FF6A0BF3105EDE84
-:10C41000B150FC4030F852892E8848A0C344F4271C
-:10C42000C145EC9BC6FD44953F2BD0FF48C192C748
-:10C43000450CA03CD11E56363E6F46A4059F3F02D8
-:10C44000C787CE01CD5C1FFC5C135711757A87E25C
-:10C450009E82D9370DC723DC1A62477D3CD1DC446C
-:10C46000EBF2E076A646EE679996703F8BF6D50024
-:10C47000B62CE77EE6C4EEBEDE8CF49C6DB890C4AC
-:10C480005AFDE20AFE69785EA5F38B2D1847C0B805
-:10C49000D72AEE0F1A15FFB57CB9DE5F98B850E3C6
-:10C4A0002F52B7BE6A1CAFE991508ABB58D09FD0BB
-:10C4B000F8017F3794C8A887E564239DBF34B16035
-:10C4C0007FC2C9783C933F372A7EE2D034936EDF37
-:10C4D0004D1EC232110F65A8875250D53897603C67
-:10C4E000EF220B6FC4B8D930F1118AFF95D5F373E1
-:10C4F00069C1F1BF8BB5EF3F8BEDB11E9FCFEBF460
-:10C500006322EE6FC2B2D429DC0AF2DDE9F06517CE
-:10C51000CA07282A13CA7BC8FE6F10160C914CC894
-:10C52000C7EF7B9EC5FE65B3D5867AEBE9D008EAF6
-:10C5300067FE7C81E2C30B6D5CDEBEFA327C1DEAD5
-:10C540002935DEBBB8B0DF2A3CB7F4EBB45DE3AC11
-:10C550003D503D303AB70486F11307CCA7F40AC822
-:10C560000DC1EF8F7344029FBFEF9B64053CADDCB0
-:10C57000F0FE3823F0E3F9DFF99E43F8850DFB392F
-:10C58000FC5B5F6208C26907C619418ECED7ABFD5E
-:10C590001D18E7C07DF7DF73B801EA6580CB50BF97
-:10C5A000E1BC070AB4EEDF8076293610EF2933BCF0
-:10C5B000CBCB21CC83F6F35AEDFE98E6DC80F65A1D
-:10C5C0000C3F168EFEC5960C07C19B539C8FA5A1F0
-:10C5D0001F74D0DD2516E35806D68274013BE66849
-:10C5E0006F5F7A432A97DF4DE9BC3F155FD0CFD309
-:10C5F00069B137DECF6D6DFB71FF3BE3E99401FD5F
-:10C60000E4E9FA79E9DFE9A72AA81FD56F030758FB
-:10C61000423D7526D3F11ECE73D6AF1D43B6A0FEA4
-:10C62000D92F129F7E57BB2D1DEDFE77AF5AA2D199
-:10C63000FECD7AFDADC40A8C23287ED199E6CFCCFD
-:10C6400012BC3FDB2F3207E8E91ABF40E5EC2DCDE5
-:10C65000E6E1D978AEB6D95CA4195795324EE074AC
-:10C66000E3388D1FB32F4D8D3FAFA0F1CE7AFD94EF
-:10C6700011E939CBD0741CCF1FB3813CEE153CBF00
-:10C68000CDCA7B87F1BC413B71808FD2B8DF11D717
-:10C69000CBB11FE7B709F539F28B819F0F096EDF28
-:10C6A000359DF757D689EBF9BC83F68A03B4EECBF8
-:10C6B000318850F63F546B2E87E70752861C4A6B31
-:10C6C000370EE9E371C81D3C0E5916D532178C1987
-:10C6D0008B4ABFF804CADBC8A755F900D103FD5245
-:10C6E0006C51E190F14307F33817C29737189EC495
-:10C6F00073847B3BB5FCE200DA87A5E16C1DC8D9E9
-:10C700007D03C21337C338A6CA9102D84E566809B2
-:10C710004F9F02ED4E241746A5F3F327E41F9E48D2
-:10C72000769EC3F17993420DE08C309799C7B35C44
-:10C730007F16299EE5CA0975B9DBC1D719059F5136
-:10C74000E9DC3FDB6B8071F6C571F0F3BDF097B8A3
-:10C7500019E34D0B7A0AC877EAF76F4F29EC9C9ED4
-:10C7600017F8FEED29CE1FD362B5ED2319B6BFDE53
-:10C7700071FC53B1A79DD339BD9C8381BF347A7FAF
-:10C78000DCD0501D5C3A2A9A39B4F1CDD2041D3C5C
-:10C79000A12C45D7FEDE69BD74F5A32D2DB9B537A3
-:10C7A000E0EF8B119991B4FECFE3EB90AF765CFE96
-:10C7B0007422FAB1EB45BB00F39AF1CE864F0751D4
-:10C7C000EF12C5B94EEF15C91E817B6BD6EE9F9C4B
-:10C7D000632D74EED8D87921D9BF5971FC7CF70C40
-:10C7E000B77EFF438DCBB7B76F82F6AC0ACFC5B427
-:10C7F000B76F1288C7FFE4FE49BF74653DDC97F54B
-:10C80000E5EBE1B37B60A6AC687B33D1AB619F689D
-:10C8100047566DE8213001C679FB168B3B04C67D77
-:10C82000EEAD236649B37F52E30703108DEF1D3150
-:10C83000E379AA03695C6FCFDE71C1CC902F763C9F
-:10C840004072DDD2EC8A8945FB05FEEAD65CE4AF96
-:10C85000A65CB47F7B0D3627EE87CD5A3282E2CCC0
-:10C8600091FE895456358EA07EABFDE3099EED0FF7
-:10C8700025F823B165CBC7D8CFD39136B4E7D546D9
-:10C88000F955A44BB514DA0FF7AB666FF9F8D2AFD0
-:10C89000D08EDAF8BD8ED1E227B9583FBAA7CDD0F5
-:10C8A000D019C71B42FDB40CF92217ED5231AE0B63
-:10C8B000E079D5E60217CA7D6143B80DE55EC4F3A1
-:10C8C00064EDF0E9E474AE5F4C5E3EDE61FE12EAB8
-:10C8D000AF757D9F9E4CF3576153EC7A23EA0F7539
-:10C8E0001E2630F858DEE1EF4565CD9612239E8B6B
-:10C8F000FF73E6F3318827681F8665EAD041A46795
-:10C90000BEAB1D10C9DAD15B6A6951F4F044D4C3DF
-:10C91000D05F69A6E3572897631EF11AADA847C3F5
-:10C92000AC36DCFF1893DF47AAD0CC477CF71E5CFF
-:10C930004980AFE233A11F30114AADDE9EDC817D1C
-:10C9400091D30D8A5F54CFCF75AAFA7DE5130CD72A
-:10C950006193F859AD56B9AA56DAABEFB708DC1FA8
-:10C9600090B7F2B87E75A6EB491C6F4B219BB0992E
-:10C97000F4694B6249F8CF37FE08630BD139C22600
-:10C9800019705F41AD5FD53A0F2EDFD79AC722A548
-:10C99000FD47229B8F7CF1D16DB7B538A0DFE687CC
-:10C9A000FBF5133576EAA5747EAE99D97C57485FBE
-:10C9B000EC0C95500F8CC6BD87DC80DF8FE72131F2
-:10C9C000AE51B3D3B20ECF83D544C03A1FBE3FAAF7
-:10C9D00097EB25C447F3AE824B788FC6810B33901B
-:10C9E00073C78E0197F09CBDC30ADAC68E7E90E3B2
-:10C9F00065D2FF1D8CF75AFA2C75E8AC18F427BEE7
-:10CA00008321A1BD05BB9F7B90C34EC4976B099743
-:10CA10003F9722875314FE2D57E4708A91CBE1E4AF
-:10CA20009591368C77963F22F4C6F3724C0AB7A3E1
-:10CA30000A30215FF643FEE47C59E5EFACC87392FF
-:10CA4000D20FE7FF60F99CED8FA676AA9CBE9CE909
-:10CA50003AC4ED5C4BEE7C18D71D20D7A8F75C0BD1
-:10CA6000E273514E027C62B6213F019FC45568F8C3
-:10CA7000A0A1F90723F28969B0407C6281B248C362
-:10CA800047CE56FFC436BC0BFA550B930CCB58A0BF
-:10CA9000FEAB74D54FB93E7EFFB3D2BE3C0CFC0852
-:10CAA0008AFF44308CAF5D8C91284E3A67290C1276
-:10CAB0005030C7E449C338CC9C0742280E5671B0A9
-:10CAC0007671B8D4965EF7F873687F79BC3F95CAE3
-:10CAD0000329AE33888F29FEBB143CE65CD7FE5C8D
-:10CAE0009E83C7DD4C6E8B7D6D12C6DD5C22EDC76B
-:10CAF000F560B627C94EA9FB713CEE86F13C8CEF80
-:10CB000005EFAF611C0ED7D39618836E9FB04D3CD6
-:10CB1000AE50BF9F56D5FC497F03D49F4E72505CE8
-:10CB2000CEDBD365CC8079CC1CE77EDDA4DD6753FA
-:10CB3000F0D864F4A4A11D6DAAE5F8695A2E16D3A5
-:10CB40007E1363A1259AF3BAD7E2E399FE14C28F4C
-:10CB50006A5F54BDBDAD8E0E7DB6EAEF6BD99D6A9E
-:10CB600085DFAB91DFED6DED8CCAAFC1FCACEA6740
-:10CB700053EC41D24377C02BE83FA8FABAB868D04B
-:10CB800060B4F3835E4AD9F227987F74A62B3703EB
-:10CB9000F8E7B6577AE4AE06F80EA3DB680BBB1EC7
-:10CBA0007DF88389F4E123258CF421945A7D68EA89
-:10CBB000C00F2FC8B8317D9EA1B4073F96FB87A058
-:10CBC000AFB5FD55670E1985E32FC9E076F2E71A78
-:10CBD00077477ABC244395CFEBD3E3B72AEDAFA5D3
-:10CBE000C7A765703D1EACB7411B93DE3EFF4E16D6
-:10CBF000C5C90E33D0F368CF76844A1B9234E7DC84
-:10CC00003B45BAB57A3DAED7D469C8EFD7A1D7EFC7
-:10CC100047FCFDBB7A7D78C926F2ABE0CF39F656EA
-:10CC2000587FFC06D677087F04EBBBA4B6F2102C25
-:10CC300007C17C0FEB912D1FC3F8F63ED593E20E92
-:10CC40002007C4F7D5C0F72807AABCCCDED227122C
-:10CC5000F70DD85F4486FA3F580E8A8B5E31629C8E
-:10CC60000AF538E26B37C83CEA99603BE1CF70AD1A
-:10CC7000C4F9ABF2A0CAC1B5F9E82D13AE4B4D55BE
-:10CC800017B89E8752ABE73BF2677E7F83FCFF6855
-:10CC9000C6F5F901AF66F07B103F23FFBC9A717DAA
-:10CCA0007EC16B19FF915FF036F10FEA4F5CBF8DCB
-:10CCB000FCD01E398FF30F9D4B047EC8C5B8F3DE40
-:10CCC000FE3DEC18A7197995FBF5A0D3C9AF0FF677
-:10CCD000AB272AFA6FB212273890E96CC9E0F24A02
-:10CCE0007E7B614A681FB457D7EBEF4D8CA965185E
-:10CCF000679A0CA5564F58906EEDF8EB7FCDB83182
-:10CD0000FBBDFB3AE97B3CE33FF6F37CD7A30F5234
-:10CD10001DD6F188CFEF3C468678BAD67AC0B48A61
-:10CD2000E3598517798CAADD8C46BB09FC71E13F7C
-:10CD3000E18FD1454D97AC40D7C84C6329C603EF6E
-:10CD4000C2B31614CF30AD74A4A2BE61EABE00C552
-:10CD50003B3E1255D87C70288C63E4932CB06F0056
-:10CD6000F5C30647B6C6470416681F91291E5C4ED8
-:10CD7000E3E6E75598CB6BE4FB640A9C0B70B806BE
-:10CD8000CE0F82D7F0F611462FB369FB51F4CF18BE
-:10CD90001BDF1708ECE7F9867746FF6F8B60C3FD52
-:10CDA000857B079F37633C677491774F02B44BCA0A
-:10CDB0000C2F0D03137FEF1681C6DB6763CC4A3956
-:10CDC000958E6C39F0BC61553EDF37B134350F7745
-:10CDD000B4C3877D32F5760AFF8C5D283E467F9688
-:10CDE00026819973793FC949D7F73ED28FDE4FA686
-:10CDF000F73D9698EB7FFFEEC1CCE16E878F6ECB4F
-:10CE000054F421C685D5FE8126E39B04477B719BA4
-:10CE1000DB95F62D064335033C8DDD98B912E35EB4
-:10CE2000C318E78B928D19A532E73FE6089AEF4FBA
-:10CE30008D372F53BF3EC33F49FFBEE7A7F035A84C
-:10CE40000DBE14FA57EAF924D2E87CEF3B18476488
-:10CE50008C60433F75B63364398B44BA2B7C2DF715
-:10CE60002D750C86F985305D1CAF95AFE57EA5C8A4
-:10CE7000D7B399DA3E6F25D2DF69686DCFF97C8729
-:10CE8000D0FA7EA691E127E8FD591B7357629C1CDE
-:10CE9000E841F5041B7F82CF9B82E0C14172C1381B
-:10CEA0004C72897A19F093D6CEFEED1205BFE704D5
-:10CEB0007EBEA96508F7E75A9279F96226F7DF1E68
-:10CEC00057F0F8B452B674D2E0A17B80CEF0E7C13F
-:10CED000F58066DE84A77B629479CBE34B47C1BCC7
-:10CEE0005AA2586F01F864EDC6B12B176AF8E4F93D
-:10CEF0008DE34B110FADFDC92507118FF728787A07
-:10CF000071E3B883C84778E404E5AD3A9FEFBF5AB0
-:10CF1000B67CDCAEBCCD69CB3F32E657A82646C214
-:10CF2000F704872997F793DC0E7EE6B77DDF11F4CF
-:10CF30003E33C5DCC8FB0A7D4605D1AF38887E4349
-:10CF400083E0323D1CF083A167F09FCAB7AF58D48D
-:10CF500005E3671B05BA6305FAD92CC0F31D99F7E1
-:10CF60009586C5239F4AA60468EBC99C7CD09A0588
-:10CF7000F288FA8BF4AF8BF4F578947382A7943A25
-:10CF80006E46BEA95D1407EDF76496AFC47BAFF79C
-:10CF90002E5C6142A4FF3973DA4A23F47B4FEE1F03
-:10CFA000F7607F46A1E2E028E127F8B431681E6B04
-:10CFB000826039A8FDCA6BE8F38541EF3F1254BF88
-:10CFC0003C085E15042FD1BF3F651ADFBF9C02F4F9
-:10CFD00043C45D4B5EBC99ADEB8656FB25A03DFB83
-:10CFE00050CFEF231B387C6AE383A54BC23470E635
-:10CFF0002F4AB5FC6B52ECC5C418A7A33DFE3DD427
-:10D0000011FF6406DB3559772EF130633AFBBB5BC9
-:10D01000D4C3CDA22A5F0B0ECECDD6EC07CAF5A5A0
-:10D02000184FE978BF422EC5FD8A918FABEDEB4AD0
-:10D030001D9AF9A9ED87FFEBAA88DFBB9A5957BA69
-:10D040009EF6FF94FDBB285EDE76E56A04D2653865
-:10D050009E1FC5FA4E9EB439D99AF9B1A6749C5F49
-:10D06000F3C3FCBEA1DC00F400392F6776DAFF6E53
-:10D070008E8C9CFF02B4DFFDB0381FEDD7E1F9D1F3
-:10D0800074DE686C16F7B77747F6EC723FC0CDA137
-:10D0900093CD18576D7E741895EF8A8EC53E407EED
-:10D0A000F7ACC74AC3B2B03E92F012F7D2D2D27AEE
-:10D0B0009083842C89DE7745D9BA6C473F7499896F
-:10D0C000E1FE1363F6E7884F7E6B213F754A7D2FA3
-:10D0D000DAEF29FF5DC9F0786857BEC844F17FF8E0
-:10D0E000A3FB18AE65C3CC583F6DA152CAB753B964
-:10D0F000EBC7373ECCA17D1D91CEEDECF4471D076B
-:10D1000049665FCBBDE9BEC25125BFCA962C5746C2
-:10D11000168CE3EBB3A9942F85D9A48871E8B7DD09
-:10D12000E4C8CC8A0DB4DBF5A348FB556F9F2DEF07
-:10D1300082FB7B7DB338BFECF4977729D7D8F58A8B
-:10D140007346C2F32EB33417F5C6AE4E3D0499E4D0
-:10D15000B6291AE3ACD314BF19F864FE1BEDF061D5
-:10D16000CF2C91F072CC321FCFC2B2E6DFC40EC614
-:10D1700071A9EFE51D743560BE185377A9AFD63F8E
-:10D180002E481B722B8E37C05FEB499F937F0CF0AC
-:10D1900088ACB52B65B01F6C37F8F5388E18C770A2
-:10D1A000E427F53C1E8B6B4AD7C615027EE8024584
-:10D1B000FE79BBAFF070307CFFAB5743E8DCD7574C
-:10D1C000F217E15AFF58958FE911FF73B885D6C55C
-:10D1D000919290087C63AC3BFE10BC57F1AC89F493
-:10D1E00066C5B3B18FF8B01EE8895B86C1DF7D3EAE
-:10D1F0008B9F07E8583E36970EEDAE958F4DA538BC
-:10D20000DF8EE4636AD6A60EE4A3AE0BF2D1F0671C
-:10D210004D74BEBAAC53ED5D18472C33DCCC1A60AC
-:10D220007C439EFD4517DC6799FEAC85E8EA0D0F4F
-:10D230003FCEE7D53309E7D56A7FB2B8BEF2D6173D
-:10D2400090BD100DE09D81FE16179B683D22763142
-:10D2500093DE1323ECBCBE134B5A0076795178BE93
-:10D2600084F4752BF200F512F25951E4843BF05C22
-:10D27000CBE1F929B40F762A97EF83CD78E8F90846
-:10D28000F43FBF9ACBCF77CFC47C3BB8CEFD37F706
-:10D29000BD6A947C3BFF5BFB5E4F6429F7865AF7BF
-:10D2A000BDF839D0DDF3FBE572BC30C982784AECB9
-:10D2B0004378B9DDCAA410C08B18C5D251FFA8FBB2
-:10D2C0005EE2AFB87E120D02ADD38FD5C994BFA078
-:10D2D00028C2CA9FFF8ADFDB139F2A61B40F16534F
-:10D2E0004BFB60E188578CDF0ACC89F27334C49E13
-:10D2F000F84036F25F08D173FA73333EFD7D2ED2CB
-:10D300006D748C2E9EA0F09FFAFE89FA5B687C27D4
-:10D310000466437B5FF4878CA1489F66D1F5D43DBA
-:10D32000A4374369FF9CD9BCBF1D00F0F47A58674D
-:10D3300033E49BF8C4E4EC403FD3173C9C8EF42EBE
-:10D34000FA438807CFDF4C5B18B20ACF6154EDE097
-:10D35000F7BCA72CFD8ECEE3B224632DC639BF5E89
-:10D3600018C2CFA96F1940FC33C5C0CFB9B0443340
-:10D37000C597AAC214B87B3EC19AFB4B66A4877AB4
-:10D38000FF660FEA15F8FE71151FE837A2DE55CFCC
-:10D39000D1B35A09E5BFCC20B47BCEEB6F59DC3F4B
-:10D3A0009D9268A7F3A2D58F59EC0B92389DC5FECC
-:10D3B000F85D46EBA26A836FF82AECD7C0A4AD36BD
-:10D3C0005C3FB454E07A9B6DC9A03C04354666349A
-:10D3D00047C17389EB33753C3552C9EDC44F46766E
-:10D3E000C81885786CF9B405F96341B8847191EA7D
-:10D3F000CE7617F51B6EB5713BA17C17C79E827C5C
-:10D40000E03747211F7C2A182C3CFF80C300F5E73A
-:10D4100019AF6FFDCEC2A5D9346FABCD30241EF944
-:10D42000EEC2F055F0DEED4C4A8EC77B624BA3EFA7
-:10D430009A80F5AF89A49740981ECB477FEF35B10E
-:10D440001FAE53A72CDD4DF39BB5A90FDE20605313
-:10D450005E3F40F66996C25F5EE5DC5A39C09B10BC
-:10D460008F8A5E7089AC96E2610A1E5BF1ABD4577D
-:10D470002F35113DAA175988CED5F57FA37EABC3B2
-:10D480005BBA203DAAB79A287F87F5263E8FF2FA2D
-:10D490001E830FC1B8CB4D9136011E55C9A3CD08CF
-:10D4A00057350A04ABDFAB5EFAD72E866CDE1F96CB
-:10D4B0001603DF670DF41B9B88F6ECCCABD18953C8
-:10D4C00034743FB3705B04EE3B1F0DF1A4E1395F90
-:10D4D000DF0321763C57A8C6D3CE2C4CE3F7816CF2
-:10D4E0002DE1B85F3D6D6E4A14DAB9C3368F19EB82
-:10D4F0000F3725E19139E6B0D90623EC30DE4CF048
-:10D5000019E51C09FD61FE4081F34DD5ABBBCDC9CA
-:10D51000F0BDDE3771FC9C7BEDE89E81880FE02337
-:10D520001BEA9FC49674B4C3D58696F404A4CFCBEB
-:10D5300002F90BB03E7560FE91D9C8577D411F2A94
-:10D540007C357BCBB679289FD56F9E1A8E783D3778
-:10D550009A99313E56ADCC1FD68FEF19A17DF5E6D5
-:10D56000B5C3197FFF3DE43BD5DE03BCD004F05EBC
-:10D570003387736EE2FA79AFD94B79EFF6DEC518CF
-:10D58000ED9F19D9506C0794E7F7004451B99F56A5
-:10D590001B378EE7DD93B5E7E766637D76A0BE2394
-:10D5A000BE197B9341A1B385ECD258C40BC0DEA554
-:10D5B0005B23902FCEBDB67BCF40948BCD828D69FF
-:10D5C000E54195C3441FAF07FC3D81F8DB7C613822
-:10D5D000E6A19879365C421AAA7852E54DC54B0D02
-:10D5E000E37850F1526354F0A4D43B153C54311FFE
-:10D5F000F5C7CEF6963660FF6FFE40FB6DE7A630AE
-:10D60000819F13E679D1D4F9B9A2F4FBFBF5377108
-:10D61000BE9FA4CCB3CAC6ED62550C93EAFB109F23
-:10D6200039CC6A7E4968726ED311DDF8572972D001
-:10D630004A6F9C078CD36BE0F70483F5D75C85AF0A
-:10D640008ED44FF4A05E9929433FB9280FB649B84C
-:10D65000CFC95E1715FD0D3653F3DDA2578E101F8F
-:10D6600082EE92A260CD62DA08E340FFEB6C0F8A93
-:10D67000171675F5D2BC378CB23103E89323823785
-:10D680007C3BDA838744D253EA381DF287440F4744
-:10D6900013974FE4178C0FB6EA85A0F1D62BE3B5AC
-:10D6A00018EC5E3C17CC1608747F4D5C702EFC1095
-:10D6B000B77714490CF47FCB7BB81FE9B814210964
-:10D6C00054633762BBD9972292D17E1F51E20E4735
-:10D6D000166D8B28D7D0E1A98EBEB3788084F42F45
-:10D6E0000A3BF430CAD1634ABBBD66FBD0F9A80F30
-:10D6F0002E4748785E6A6F949C8D7ED45E035BC231
-:10D70000A2381F1ABB04F007F242F8837AE9495B9A
-:10D71000402ED57103DD3C483768EFE07264A77D89
-:10D720008CD9317C5FF4DAF2D4CF4BFAA95E90D673
-:10D73000E506DAA9F7F21E55E64D32D225600F90C4
-:10D740003FD1DE59943C46C179506FEFDE3911F17B
-:10D7500057136635E0122EB83E180EACA76A8DE856
-:10D76000E7B385717BB4F7D28E86C874FFCC172FD0
-:10D77000B275408FFA073EE0E77977F07B5BAA9DB0
-:10D7800086BFE5ADFC07EF55E65E188EFAF5C502DB
-:10D790000BDD6BEADC2B99BE739A35990BD1FE9F9A
-:10D7A0006C191E2105D627B75CF28891E42F24E975
-:10D7B000D6075567DF2379AE662D741F7BCAD20367
-:10D7C000A30720BD5F32D1F981698D4964E74EAD71
-:10D7D0009FDA0FE73B65511AC13336DCCFE1A53C38
-:10D7E000FFE19445792FA0FF7534C4311CF9D9B7F6
-:10D7F00042B0E1FA6AD086BC47EE85FA41E13D3B92
-:10D80000E3B8BF5A7F7434D2FDABF922E927C7FAD7
-:10D8100027EFC27AC776116F8CC17AC6F608E63553
-:10D8200065C6481BFA05EAF9C20613D7B76715BDE6
-:10D83000704CD113C714FE2B6A6848477FC9B716CE
-:10D84000EC11EE7B9B7D1574BE5BB0D9D701BF9CFC
-:10D8500014648299CD965C5F80F759D6507E9CF314
-:10D8600069161BFAC9F759981DFDDAFB76F5E88BA6
-:10D870004B0587B2AE1A1DCDBFABE24BFDFE19E5DD
-:10D88000BB4C5C5E41FB0ED15232EAB7BDCAB9F166
-:10D89000A3CA784F2D7CE92EF40B4E6D4C8B621A87
-:10D8A000BC9F52F234CD003DB8B99DF59EFF2635A0
-:10D8B000EEE0A6EF542AF1C07DA6C6EE98F733F845
-:10D8C0007ED789B52156CCCF1B7CCFEB8489DB8FEB
-:10D8D00036F7BDB6EBE1E03CB7C1E3695DCF04DFED
-:10D8E000FFEF15D6AE1FAFCA59F0FB6DEE93A75EE2
-:10D8F000DFF92ACC4B86F7BD77DFC4E8BDA1A1FFD5
-:10D900007A03F57545A3C586F7EF8F8548B41E9257
-:10D91000F398B401ED8C558AC4F5FCB17DFDE8FCAB
-:10D920005FC5978CE4AA628BE8C654C5EFADC87892
-:10D930007C30C0F76F31D9F1FD532B57DCC5C54C96
-:10D940009F67219F71F99C0EEB248F2DB02E0A5EEC
-:10D950002FCD5CB589EE11FE5CEB25358E148CEF76
-:10D96000825EFA7C0BC1F7E77601DBE4F76D8BEFA3
-:10D97000B3752E5A177D5B57496541D3DAA2040966
-:10D98000EF531C796C10CA4D7824C543CED6D5D23E
-:10D9900026DEB7DBFB5DC1FBA16F8745DA505F7CFC
-:10D9A0005B375FB95CA0F089C297B76C6916131832
-:10D9B000B5DF3108DAEF0C8BA4BB2EA98EFC48B47E
-:10D9C000F32A5D83EF37ABF33BFD10A7AB3ADED311
-:10D9D0001BA746A0DFD9BC3A7A4701F4278746DA6D
-:10D9E000D0DF9EAE9C7F39BE8AEB9B93D6C817468C
-:10D9F000E1F99935E3BBE0BAEE7E93CF6C877EED1B
-:10DA0000EF9444E07AFF1BA33702EF1B7F03ED3D49
-:10DA100068278C6E11F5DCC06246FB78033D462614
-:10DA200025D19639F145C159A31BE97AC67369F727
-:10DA300055E4A3B3068A770166765F85F6F6F09E15
-:10DA40001427BCFF2DBEDE64FFEAC4EB83EE2D3E3F
-:10DA5000D18BEBA5136BDE1843EBF3F5261B8EF38E
-:10DA6000DBF57FED82E77066327EBEFEE44681E63E
-:10DA70003113F8312409F5038F83CE04BD6F15DA15
-:10DA8000F261D1C67AE2C399C08716F4D31C3C1F59
-:10DA9000F34CCCC72CB136F93F3A2B7C370BF80E40
-:10DAA000EFEFFEDC793F96F50A3EB7CAF950A5BB09
-:10DAB0008A1795FE013E64BAFC82514D7D0A1358C7
-:10DAC000401FA8F73B98D1BB1CEF69CC13C31B3197
-:10DAD0005FD57E63ED1F286F8B6C641BC89EB34CB3
-:10DAE000CC97374FBCC98EF1C006736D6B5E17AC17
-:10DAF0000FCEEB2286F1F74B303F31CC372C3B89F0
-:10DB0000BE37CE661F86E836C578292E2016191C2A
-:10DB1000742FAFC142EBE6603DF48A42DF3BD07721
-:10DB200040BFA7173FAFADDEFB534B30343D90DF16
-:10DB30004B42A32E4BD064FB2B9FDF89FBB4258384
-:10DB4000A27E9102DF6FEE75E44EBCB751D22F6A10
-:10DB50006B32C0BB5FF93BAFBF392ACF847E80F008
-:10DB6000F59D43D16FECE578B397E63B6ABFF0FCD7
-:10DB70002D7CFE79A2EB9D5E7CDFB402E97D5E88A0
-:10DB8000E0F9DE527D140755DFFB586087DF16028F
-:10DB9000B0D7C41231AFC1DE5E5C9F7654C6643B21
-:10DBA000F6F0EFEB9F2385BEC375A6B2FF63B04AC4
-:10DBB00066F4FF9C76B39DE757644E2BF8556315CA
-:10DBC000FE2DB75E194AF6B796D92D98C06489FE26
-:10DBD0003E5656E0DEDE9A1BB9B7C7649E87AF415A
-:10DBE000C9C3D7D13D4A61C7073FA07F197C7FAA2F
-:10DBF000DF5F5ADE443E19037C85F622B785C36396
-:10DC0000153EA9DE369AF23DCFF9D8E4463F61864B
-:10DC1000E28FA5BA3A3109DA5D06F945BD70768C16
-:10DC2000271DF5C7893AD6989A86F12A970FE9B247
-:10DC300037E903CA8B76624D4304FA3DE7603D3114
-:10DC40000ABAA852FC7B7645F4DC867E7052D6BABE
-:10DC5000651A7EFBA117B7FF67933C89B8BE919305
-:10DC60002C3C5FE395DD94E7B93879441EC691F604
-:10DC7000D76D6747D302EF75741F65A06108CBD6D7
-:10DC8000EC4B8E31B67F4EE3A49A4F733DB7DF164F
-:10DC90006323E5D10252D6D613ECA4B8521CF22865
-:10DCA000C687A507095E3C83D9E81E6B609F8EEE90
-:10DCB00083AAF477D8AF0EC5766380FEA86F0C56A2
-:10DCC0009F116167313F9F920584437DA2D27F9867
-:10DCD000F8C863488739CA3DAE39422D874D563A58
-:10DCE000E71AAC1F31AE59467A53DE5380FE18E86E
-:10DCF00049CAABA0E84509FE477991F2D79AA9D95C
-:10DD0000B5F322ED29F80FF4634EB63E8FB84A27DB
-:10DD1000D5BFEA884EAA9E047AF5BF117AA979CABE
-:10DD2000E63CCBE39D739E9D1AD797F0061287FEC3
-:10DD300050DC1F29AE325D99035B134D7C6C1AE2F7
-:10DD40009450DF8EDE9EC024783463BB40E75B478F
-:10DD50006D8F2638C21FCFF32A29F67EF48B5D879C
-:10DD6000607CF2D40B5FCCC5BCF7A37EC3287E6C6D
-:10DD7000080DA37C13E210258F8318F63EDE63BDE9
-:10DD800028196BD15E39599BFC0106A2FF5E7E4EBD
-:10DD900016567932A713BFF737671FB7F3730AF91F
-:10DDA000BEE0457C03DA5F2C15294FD3D3A139E4BB
-:10DDB000BF35DC69A2FB114C767C82EBAA090A3FD5
-:10DDC00058E26061A9A1578804F2AAA1CFA3218FCC
-:10DDD000BDEF82FEBDB0EE12BA811F9B19A5AB3715
-:10DDE000CA21DF60FE58539C6873C3F8C3EDDD742D
-:10DDF000FD39C52A13C653988BFBD12A7F31F1AC6C
-:10DE000091EECD0FE6F92BEE9CA0BF27691A7C613D
-:10DE100028D99BC17AFFDB798DBC4DF3557ECA6250
-:10DE2000594A5E7AB2FF170FF2FB211273AE52E528
-:10DE300005F53F78374F237EEEDA6B626E89F0F797
-:10DE40001AD65F942D368C07B4FAE1A9F05E0C1A4D
-:10DE5000492BF139E605D5CE13F3826AF182794177
-:10DE6000B530E605D5B6C7BCA0DA7ACC0BAAADC7EB
-:10DE7000BCA05A18F3826ADB635E502D8C7941B5E1
-:10DE8000ED312FA816C6BCA0DAF69817545B8F792F
-:10DE900041B5F59817540B635E506D7BCC0BAAAD62
-:10DEA000C7BCA0DA7ACC0BAA85312FA8B63DE6050F
-:10DEB000D5D6635E506D3DE605D5C2981754DB1E7E
-:10DEC000F3826A61CC0BAA6D8F7941B530E605D536
-:10DED000B6C7BCA0DA7ACC03AAADC7BC9F5A18F368
-:10DEE0007E6ADBB7B0856968C7DE4A72EDCD8EC544
-:10DEF0007DA793C4CF87EE037E4639DC3BDE46F92F
-:10DF00000B6F709DD892ADAC5B14FEBDCCC226E108
-:10DF100039F48EDE57F9F3257C278FECC112E25FCE
-:10DF200016DE88FEDCA34607DD87929BF8FD44667B
-:10DF3000E47EC03C51F17F94BC10F34489FC00CCDA
-:10DF40001D6CD48CA7B3C3CA8C1A3C4417DB747005
-:10DF5000AC334ED7BEEB0449571FEFCAD4D5275474
-:10DF6000DA75708FDA7C5DFB9EF31D3A38492ED648
-:10DF7000B54F59E2D4C1698D1374ED3356B974F5B8
-:10DF800059EE4A5D7DAF8DB53AB877D37C5DFB9B8A
-:10DF9000B7CBBAFA3E9E25BAFA7E7B1B75705ECB74
-:10DFA0002A5DFB0187DCBAFA02EF465DFDA0934DC6
-:10DFB0003AF816DF765DFBDBFC1E1D5CC8F6E9DA7D
-:10DFC00017593FD6C1C36C9FE9DADF1E7744573F2C
-:10DFD000423AA5ABAF3AC3FD7BD600EB038C538628
-:10DFE000F1FC1AB33DAC09FD8B91991774ED4D31DD
-:10DFF000B05E00FEA9067D887EDFF79D12291F33E3
-:10E00000AB8DB0E3BD6F7948ED1FB4F7BC47DB7F44
-:10E01000D07DFFE9D0084F08AD2FAC646F6FE9CD1C
-:10E02000EF9BB5E61351EFB3331F8B8BA190900F8D
-:10E03000FD23017F6109E00807CF0B0D7E10F94F2A
-:10E0400036F08BD0DF6C5D17199292D02E8706FCCC
-:10E05000E2EE5735795EAEE5178FC46FE7519E5EED
-:10E06000476F2867366D1A8EEBAC194C5E8CFB89B6
-:10E070006A9EC5FD21FAF8965A8EB0027E35DFDB26
-:10E0800017D2D8BDEF4FC8FB08EB596ADFDAAF12E1
-:10E09000FF1260B27334FD3F06EB3F23C875631D6A
-:10E0A000C81FF8434FD4D9085E591747F05375126B
-:10E0B00095ABEA32A97CA6CE4EF56BEAF2097EAEAC
-:10E0C000CE41B0BBAE98CA75754E7ABEBE6E02C167
-:10E0D0002FD4B9A8DC585749E5CB75B554FF6ADD94
-:10E0E0007C825FAF93A96CAA5B42CF37D73512BC55
-:10E0F000A56E15C16FD6B9A9DC5EB791CA3FD535FB
-:10E1000051FD0EF0DF10DE59E721D853B797E077C5
-:10E11000EB5A087EAFEE10C17BEABC54EEAD3B4932
-:10E12000E59FEB7C54FF973A3FC167957D8879BDA9
-:10E1300005DD7D3C1536B263DCDFC3BC1598872155
-:10E14000DFF4ED4FE5C70DA6C369A57FD310709727
-:10E15000308EDC2D7D5D83665DD1D09BC72DEB0DB0
-:10E160003C7F4B7D37666B20BFDDC1F8392DEEB7A4
-:10E170004FC77F49F034A66E0FAE372A6A799EF2F8
-:10E180003CE4C74CE2C7BFDCD03A4D59176C4E7126
-:10E190003E81FCC8C2DC9F26E506EED11F4871FD1A
-:10E1A0000E9F5FACBD7F0FB69E6EB3A7E347465B85
-:10E1B0003CB198FFCBB74FB4AF933AFE5E8D72FF80
-:10E1C000A1C3FA9DA7BAA3BD2AFE51A4B8FE7E53EF
-:10E1D000F804DCE77F51C1C78BBD0DBAF2EE54E7FE
-:10E1E0000BBD717F3FADF6850785C0FDFDB1B8C49D
-:10E1F00007F92E6112E5C119CF1CEFA30B7E27385A
-:10E200008208DFCD642A4F24BBFE88F3B9071620AD
-:10E2100008BB065A12DB9B4FF078DE52C6F39632EB
-:10E220000EB59C93EADC8EFD1D4B73E8C6F3A292FB
-:10E230005F680CF33D87E3FAC73B178E0B29017C1F
-:10E24000B7C653582DE5C928633C9EF228E6C58819
-:10E2500009E4C550D70F65FBF8EF1CD11FDACF7961
-:10E2600049B4BE0DCE9BB1B87037CF8301EB31BC42
-:10E27000FF5BF6C02F48FFE2EF41E1BDDD799D0E67
-:10E28000539E19EF0CE0D504CAABC1F3DEB8008190
-:10E2900009945783EA859BE0FFF1382E6BA691C65F
-:10E2A000D789F29D3C1DBA9FF2D2604CC1D219F3BE
-:10E2B0001E27D13CF73B2F70BF3BC647F75337A70C
-:10E2C000B8BEEACDE3E44FF5C33811F2137EC7E6DA
-:10E2D000A6F36BC04F660150343D06F8A91D7F437D
-:10E2E000E59BD9CA3D1CF539F0E309C4F7B76F0DBA
-:10E2F000C844BEA9D9592021BE1B0CFC3E9DFC6719
-:10E30000655F50F93D0431327B2DDD3B40671CE9F0
-:10E310005B104EF70E9A45367F533BFAD59AC3E908
-:10E32000BC3F8EE7936C08DA9F147238DD05A5DDDB
-:10E33000E877F7511EB2D97B79BC9AE57AB39DEDA7
-:10E340009CCBAA99FF9BA75235F3A8D97E849FE75F
-:10E3500062DE6CED392E49E957E53FD11CEE5A1BC0
-:10E36000A61D5FAB1C5872F2480E8EE3BDEE31164F
-:10E3700029F26E817E1FEC5BCC2FE3FA838DCE03F6
-:10E38000AAE702A7312795D3C17222DF3BE51574B6
-:10E390007F7E266BA2E7B3F3A726225CC37C43E310
-:10E3A000707DB4A4FE7D0C078D6F5C312C1EE635AC
-:10E3B000CE3DE57D2C4BD60BC76589E4280EBFEF1B
-:10E3C000156A177583EFDDFB6AE1228C5B8F1139CB
-:10E3D0001DD8879C0E65C0CF6254DBF981DCF4CC7C
-:10E3E0008925B9A1F1AB7253B68039F0FC817A3F2F
-:10E3F000A4558EF267FD3D01F770C09F447EADD9F4
-:10E400006989A2F529E699417DA5C8CF2223F72F76
-:10E41000654C6D4AFA93FB1B268792CF8B717F6404
-:10E4200096CCD763A74D5CDE4E7F15EE46FE9ED799
-:10E43000E9F544920F932A1F3F4EA2F33D0CFC8F47
-:10E440005BDBFA1FAD7966BA33F23758A22BAE6F99
-:10E450004AC09E9F36B8FB47F0BCFC0EC4D79E381E
-:10E46000BE7E9E857968B0BEB353C278E9E9582B69
-:10E47000DD170ACE73C6989DE66752E607239B8098
-:10E48000FEB44589AB3504CDF7FB90449AAF54C830
-:10E490009A183A16469B3C15E5FE416E27E675FA3A
-:10E4A000B50BBFEF0D61366110CD87E2B1B2813996
-:10E4B0001B787C96E637DF68B5E1B99CC55344AF5D
-:10E4C000407602C689F1BC18AB9DE75555F36F073E
-:10E4D0008FD7A11F9F3591E1FC1C22F3850CE2E34D
-:10E4E000C5F1C9400FA20FC05334E3837EDD94FF12
-:10E4F0002754B2A11FB6F75F0FF2F8723DF71F6104
-:10E50000FC1B893EF130FE846B8FDF842C0AE39F75
-:10E5100093C3F55403EE208A68673B93FE2D09717F
-:10E520003E807C98EA5AD67D0EC6350A2C768CDF62
-:10E53000B12B0DDD514F853189F26A8D71F0BC5AD6
-:10E54000D0DD42E48712CC5B67233FE0AC360F1B83
-:10E550000B8AAF015928BE3A0EE36BFC2ED17B1813
-:10E560009F1DAF9C6FCE625FAAF8A3F89A88E3A3C1
-:10E5700078B58BC66941CA421982711EA2839BE697
-:10E5800011CA3C4A3CBB85FC83150A1F0E3AC4F9EC
-:10E59000705018D7773B8F30379EFB6AFEE1AEA2F2
-:10E5A00070842F18494F019E281FE0DB7FE571A979
-:10E5B0009DE78E27E03E4CFD0F7B12D04FDC697249
-:10E5C000893530EE9D0516DB027B20AEB1E3501895
-:10E5D0008FEB2871BE5B9479EE602D0D35509F1F37
-:10E5E0002F328C03E61DF484A23C0F54E2B2C1FA30
-:10E5F00070F025B3EE772D4C363D9CCF34701286EB
-:10E60000C8827EFFF306D7B9AFE574F0BB9F2763DE
-:10E61000AE6B3F147FCB87CE27E438DFCC21BB36EF
-:10E620004E54F02E20BE400F34239D9FA936D3EFC9
-:10E630001A34579BE3BD9AF135CEF847029D73FE1D
-:10E64000D73FC86EEDCA53F3E33485E073B31C4E75
-:10E6500071B767AE1828EEB6BAF26B5A9F34E6333C
-:10E66000FA1DB1C62BE5E4075C2E66B889C4EA6FD3
-:10E67000FD3F95083F7E8B95BE173CFE6DE0CF7B3E
-:10E6800080505BC19FC7D20DFEBC2703FDF4382A22
-:10E69000D7803F8FE533E0CF63FD2AF0E7117E0A94
-:10E6A000FC792C57823F8FCF9F007F1EE177C09F60
-:10E6B00047F86DF0E7117E0BFC792C1BAF7C5248BC
-:10E6C000E39ACBE8DEFE82D088A5E8677493C3C9DD
-:10E6D000DFF8C8D1B793576367F3BF34E8E8DCFFCE
-:10E6E0006027DDEF9D24C95141BF47D32DE8F76A6C
-:10E6F000F4BF6F9350A9FF7D9B7857DFA0DFC3194C
-:10E7000018F47B3943827E4F47FFFB36B75E1AA76A
-:10E71000AB1F7C56FFFB36038F95EBE0C7957C99CA
-:10E720002A1DD3A5D742902F56578E8B64EDF8172C
-:10E730006A89EB2B8F667FF5C987C409EDC59123E4
-:10E740006FE6F6FEDDAF2CFBD6033E77B14827C659
-:10E75000DD77390CA4979E59154671588B77E029BF
-:10E76000E49F5D0E2621FF3C736548271C4F2190D6
-:10E77000119F275472BDD0ED6689F839A1D227E2E6
-:10E780007DD1DBAEF8ECC88F4F46F0DFD9827EDD5D
-:10E790000BA0BF7747F7CFC238CE3361C0CF286F09
-:10E7A0001E5F682AC091570D0CF523D84ACAF32F73
-:10E7B000FF3E4C398F7A95EEC345A24E07BDB4ABF0
-:10E7C000927F3FDD7B2554EB0F3DFEE3B5F0C28821
-:10E7D000AF3AACBF6366328E378077508D50A6B3A8
-:10E7E0004AF618E2A38ACB4F63A581E4E932C81345
-:10E7F000E207664D74617838215EFB3DAB9E0E5595
-:10E80000C94B719ECFAC34D26ED930F1D57D37C3B0
-:10E810002BAB0F8AB4CD2ED97CA1EDF977EAB8578E
-:10E820003BF8FCA2ECCC80762E0AF0E9A6FD6C7BCE
-:10E83000BDF6F7AC7EAFC8E7EFF0FBF0DED30A3FE2
-:10E84000AC54E47398B866443A8E239FEB6BA0A750
-:10E8500080F7B12E4F63F43BA2BF2B4DEED45E9EEA
-:10E86000EF95CA389E53E6B54691FB67B05FBCC7CB
-:10E870002E9615623FAB9D8CF4F86AC7D7F518B792
-:10E88000BB5CCAFBEDF9885740FC76AFF509D87F31
-:10E890008FB91E2ADDCA38BB55B650BDDA9F6477E2
-:10E8A000737EAFFA9AED85F9E2215B91ECC559CA06
-:10E8B0008FBADA68646887519F217CD96AC43312A1
-:10E8C000ACDB8C630CEF33378619699F62F5ECD3B0
-:10E8D00004AFB0713842AECDC6F3176F29F38990FB
-:10E8E0006582DD41F3499726476A7FCFF55A7AF072
-:10E8F0002D93CB7011C631E06F22FD7E4747EFA903
-:10E9000076F65AFAEA4FF88F78B20B0FDD8CEB6788
-:10E91000D94976415DB76D1DC5D76D2B42277D88DE
-:10E92000EBFE52858F9E0E1DF33ED61F18C17F074A
-:10E93000A779C4ED3DB47A72BB32EE6D0ADE0B8E60
-:10E9400039BE9A0BEF8F745A189EFB18293B7AFC3C
-:10E9500002E15122E5351FC01A1BF05CC5C13C55D0
-:10E960002E9CA1287FEF8E9ACA0EE1778AB99DDF8F
-:10E970005A3C9E9E4BCC39B237BCFF498B91FC1A56
-:10E9800078FE9372B94F19CF070A1EDF57E8B05BC4
-:10E99000A14333DA132877A13D217B6157EC05B7FA
-:10E9A00027DBD09E64201DB83D69417B9281FB6FBF
-:10E9B00013A8DD5FD09E40993BA288F6232F232326
-:10E9C000913D99CD16035C08E317DBA1D71DA9A2E1
-:10E9D0008E3EC5DD4375F4191E13AD83878625E889
-:10E9E000E021C6141DECB87253903DE81B640FF48F
-:10E9F000F624FFCB21BAF6FD0FDEA1AB2F718CD729
-:10EA0000D58FCD9FA8AB1F6D9FAAAB9759635104BB
-:10EA1000CC37EF4B467E685EA73522ADAB957D3493
-:10EA2000D5DF027A923F56F05791E456C5471E6BE8
-:10EA3000DDCF33D07E9ECC243CDF495B96C9BA7AC9
-:10EA4000F2A30E9A9C09780EB1BE04F80FCF231ED4
-:10EA5000AC18C5683F1EF818E42ACF79E24BCA3BD0
-:10EA60002A96F5237FE99251B7AF5610B43F36206E
-:10EA70005BBF7F96778DFD33EFCDCAFE431BBFACE6
-:10EA8000FDDF450AF6CB40AE441CF7D3A1937623B5
-:10EA9000DF7CF819B757CD9F3DD51D9F7F824DA1D3
-:10EAA0009F7DBD9FEE8E7CBFAF553E5CA15ABF6B74
-:10EAB0006B26FF1D9A370F266FC7F546AE4920FD1E
-:10EAC0009F9BF5249D47BC7CD040BFD3995E5C13CF
-:10EAD0008A78D97A685D98FE1E95464F909FAED190
-:10EAE0001322FAF751FA7A6342004EE6C4C1F6FFE8
-:10EAF0001710600A2E008000000000001F8B080025
-:10EB000000000000000BED7D0B7C14D5BDF0D99DFD
-:10EB10007D259BC08604DD400293F030228F0D7965
-:10EB20006D42122621D0A03C36801004E384A0D090
-:10EB3000566DEA137B6933493089014B546AC1FA37
-:10EB400058B1DAC7E7FD9A5A0950B15D9E55A1B296
-:10EB500048B051515779685BDA0F155AEFFDF17DD6
-:10EB60007EFFFFFF9C4976864D88BD7DD97B939FB4
-:10EB70004ECECC9933E7FCDFAF73608CB1CF24F875
-:10EB80001F9BC0422E463FBC3DD5D42E62A1ACE8AF
-:10EB900076B9A97DB5A9FF0253FB3A53FF1586E765
-:10EBA000AF642D1CAA26C0DFF833FDE2EBB606C623
-:10EBB0004257F4F5CBB30524DFC48BFBE5775BFB51
-:10EBC000C685FF768F5B653D9FC25857B714746644
-:10EBD000C075EC2AA6E5C238DDD620B3D0D5CAE090
-:10EBE000F92B3DBCED64C10D53E1F9B66E9BAF5DF1
-:10EBF00066EC45FCAE93B1F1811B860612192BB170
-:10EC000085637EB7F49CF1BBAFF42C18CA62F4D3D1
-:10EC1000AFBF10E3BED0E0A275ED6CF0505B7F2E6D
-:10EC2000FDDF7347E7E3BCB3241FDC86F997273386
-:10EC300058F72F2FAC74E3B8305FC6463036A33395
-:10EC4000ADBA712C63320B2658A1FFB62C89B5C31F
-:10EC50003A738FF1EFE7DA95644F0CB8326635C23C
-:10EC6000FFA2F1E007E174C11AC4F1F68C5BF2D0A7
-:10EC70005418FF60B7C4703E0E75B53B3009DA3DDD
-:10EC80007C5EFAB8D33FB5F6E119FE2B3E136F80D8
-:10EC90004BD1C96186E7B9572E1C8AEF3BE4F9C90D
-:10ECA00008DF4BCD93B178131D0D33B54718FA8F9C
-:10ECB00097016F93FAC7C37681876D8807B86E8F07
-:10ECC000F3550762E06DDB78E7EA60D43A1B7C40DD
-:10ECD0002C7978B5D235F74AC91702F89CEFB6FA05
-:10ECE0001078059E7AA93E06DCFDC78D7492DF1D63
-:10ECF0006F800793960FC8076B8E37B6EE8BEAFFCF
-:10ED00000D5F62CA6937FC51C00A68FD9778FFCF72
-:10ED10000D5AEB3E3BD031634A27AC93552E64AC81
-:10ED2000B0FFFE8C35D1FA7438B2CA64C65207837C
-:10ED3000A70E7AEF227CF5F37EDF381A63C3019EBB
-:10ED4000005E9C57EBE4C0C33E1C275225E1F71F31
-:10ED500070DF2A45607DDF75DFBA17E9F3D07B0EDF
-:10ED600019F97AF77B5D6978FF60F6F634A4FB83C6
-:10ED7000F04E18DACC065883B643BBDE8DF4F54A64
-:10ED8000F76DC43F32AB3F3889CB015F3B74DB9EEC
-:10ED9000C5E9B0BF79BD24E4CF01C1AFFB04BFEE2C
-:10EDA00069F0523BD420D3F5170D59747F57838FE8
-:10EDB000DA3F6FF0537B478342EDAE864ABA1E6955
-:10EDC00008D0FDC30DD5D4FE75834AD76D59B7570A
-:10EDD000A03C3A9F0600807535B9E7D962E173B669
-:10EDE0002C19E8E64B5EB781AE667A920DED19AE4E
-:10EDF0009186FE656C8CE1F9F44F27189E979C9DD7
-:10EE00006A684FFBB0C8D0BF30526E6817F45C6DB3
-:10EE1000E8BFA062A1E179A07899717E5202C997FA
-:10EE20009D6719C9E579B97586E73BF10F94C31F52
-:10EE3000B2A09681705938A03CD5E5F45E819FDD83
-:10EE4000023FBF14F8E942F8139F571AE09D7FBCB8
-:10EE5000F39A29C0AFBF6A584DCF1D5943CF49F02F
-:10EE6000DDED67E365947BFB1BEAA9DFC1B71F24D7
-:10EE7000BAD929E671D0CECE4929D8B6C84D968BDD
-:10EE8000E793D763E4F3F1953790BCDCD9DDE44632
-:10EE90003ADB115930287DA7F7FBD5B90533902E01
-:10EEA000FCDDA0A3322EADF7747D75A9F1F57EA827
-:10EEB0004F63E909F3B857475489C13AB6F7D43FCD
-:10EEC0009488EDD0972519DAF93DEA0CC4D7AE2C19
-:10EED0008B47B250BF190ACEFBE46DD7E0FD1DC7CA
-:10EEE0006D569CF72190FFB88E9DA06F9DA87FCF97
-:10EEF0006D754F06F8BFD8F3E03593A19F76C6E64F
-:10EF00001BC72E9EC7A86C89E4C2B6894EAB650AA2
-:10EF10005C8FDB5808E5974D25787645B6D215F518
-:10EF20001FBF5F4FF8BA32DB43EF6D3FF95C32B67B
-:10EF3000ADAC9EE4C08BC7AD95C118EBBD12BF034D
-:10EF4000B223EF4283DB03FD0F1C5FE146B9B2A39E
-:10EF5000878F9FB75673239C0E46B626E0FD9D59BA
-:10EF60003FA371774FE276C5CEE356A2E79D13AF7C
-:10EF7000D8E0CBA575FA1076703F01DBDB7A6CD454
-:10EF80009699CAC2292877A460BB05D7B382BD066B
-:10EF9000CFCFFBA420F27D1ED31CC0A26CDBFF6B85
-:10EFA000599CCDC1CF6C9731760B7F994D3B6BD47B
-:10EFB000B3453D463DE2885C383A1FC6EB3AC3E5AF
-:10EFC000DB8C4F8D7AF7E01B999B028897337C3E50
-:10EFD0003B8E2F58548572E77989DA8D93563DFA26
-:10EFE000757CBECDED73C2F7BE9CFB644B327F7D5A
-:10EFF000C85C9847B19853DE19E33C0E5E59C73E92
-:10F00000C6759EB4D13AB61DE7F6D5F92CBEAE9DB5
-:10F01000BE3AF66DE42F617FCD78FBFBD74C4A41B9
-:10F02000BAB0925DF182EF67C939289F3C9281EEB8
-:10F03000004E4437E7BB198D031245BA15C629F0B7
-:10F040003B3DED1EE4C70EA29F836FDB7C4DF8585D
-:10F050003AB4F736E89F375262B8A22F074DF2F262
-:10F06000876E43FB16D9282F9DAC6A40BB61DA59E5
-:10F070008751BE7EEA308C57C0A29E133EA39E6786
-:10F08000FC0576895D5D8676090B2F1A94BE66AC09
-:10F090009EE4C50EC67CED404085574A0AC1EFB8D4
-:10F0A0008BE057F0DDAA698CF4B43A0DF981883110
-:10F0B0004A2F5FD24EF1682C255F7C0AE980D94E39
-:10F0C00047A07F1B10C967A8BB851E378FDB9FBE7B
-:10F0D0007FC03D84E47D718585F8E7BBEE5749BF6D
-:10F0E000779DE2FA1D7F224077D7E21FA8EF4F39C4
-:10F0F000881E5E986D2139A2DB0B0B996247BE9981
-:10F10000E73F67BB1FE836E0AA99740B5C5F78A302
-:10F110006B24F2EF0B6817907CE8207E7668895AA2
-:10F12000328CB3ABC7497CB813F8CA85DFDDE52460
-:10F13000FA043E5D8F76C2AE30E7A3AEB3566EE7FB
-:10F14000ED72139FECFE8383E6DDB5D6CDFD8B33E8
-:10F150000E05EDF09D6B13E9FDF17262C88676FC39
-:10F160001A3E7E8FC0EBEB02AF07859E7A19F594AD
-:10F1700013F5904CD7FDC28ED88B768413F5995F2A
-:10F18000E833AEC79E3FFBDC5B48FFE777C591BD28
-:10F19000399E6575E2BC762538689E66382F558D98
-:10F1A000F4BFA4DA682FCC9968A4FFABC78E34B43F
-:10F1B0002BD3C618DE9F957295E17945428EE17991
-:10F1C000B96D9AA1AD5C30DA0BF3FDD718E9498926
-:10F1D000B21732F1FF467FF1DA687F11E5C8D90531
-:10F1E00064AFEDEC117AF964E65075E2C5FCB3F357
-:10F1F00024D79FDB8F7F9CA8C6B01F3E14FD7E27BF
-:10F20000F07146E0E3B7A39493D94097E74F7EECC3
-:10F2100000A5D12F1DEBEFEBEF7D183C31245AAF49
-:10F22000A74B32D1B7DEFE43D75BE3F1F960F902B9
-:10F23000F4585B04F07CB794D8D10EAFB4DAEA9FEF
-:10F24000C0B6A6D9D8D3B9048E2C1B3D9FE0437B12
-:10F25000A539B1FE07F87C5BA3D3B33505F9E85BAC
-:10F260003FC1F61A6005275CFF1C372AC880D51CF1
-:10F2700053B9DFF28C3D30D2877AD31258760BF433
-:10F28000D7B6387C4FCB17CF2761AA4567F61DA8A4
-:10F290008724C1F7FF695113A6C27DE5590BF163BD
-:10F2A0001C38A2380F270B8490FED96A6519F20723
-:10F2B000B302FFC0F51B39EA30ECCF14267B601C8B
-:10F2C0001215F03D4BF8C07F58605E7656AFE138BE
-:10F2D000CED52061809F1FC85653A9BF6D018DFFF9
-:10F2E000FC5CC6DA492106A89D7B17F3B427C1FC54
-:10F2F000986AFD18DACBC0CFC7EF5BDD37931E7A73
-:10F30000EBB7D6A014C35EEA85F3CDF633119DCEDC
-:10F3100032FBEEEF1078ED1274B12323B02C965F20
-:10F320003815E182F6C5BBF324A4AF5CD71005ED18
-:10F330000A58A05405F27DC7FB57BB6B63BC37333B
-:10F34000B776EAD428BAC80D774AB509080A4DC27B
-:10F35000756D83BF715D3FEFB68610BFE7131C2448
-:10F36000B7FB5B4761C4A8870B7A8C7E3763CB3DC4
-:10F37000A7AF427877583EBB2A9ABE94F5D1F4F5F0
-:10F38000FCC5F44570BEFB6816C1B5D9C2E94B0394
-:10F39000FAC2E75A793DD197666581E65CA2377A71
-:10F3A0007F8DCDE57182845C353593E8A62B71CED7
-:10F3B0005B2199BE376601F97135C28FAB2139FFE8
-:10F3C000F23190F331ECE8DDC7168F8C00FCB68D7E
-:10F3D0005B3212F9BC0B15C0089C7EFE52B42F7B29
-:10F3E000DB802EB20367320C55C1F3DCA50AF69F11
-:10F3F000ADB7F378FF32DEFFA6A99BB668F8FC7ABA
-:10F40000F19C2DE4FDF5B656B0B40CFBDBADD47E1B
-:10F410005BF47FC8A7AC42BC3D90ADACC66B361A5E
-:10F420002B703D3D45F90AD2E9AAA98CD67BD714A9
-:10F43000E5E6E8F6CF262BB746B7B7F5FAA71DC223
-:10F440003FBD85ECD2977B16905E9259E01AD43B73
-:10F450002F87791C6ADBD881FD9F5F097B7EBFF017
-:10F460007FF6A23C223F88FB3FBF147AE545A157B7
-:10F470005E107A65A7D02BDB857FAAFB47AFA27F02
-:10F480000AD743C23F7D05FD25E8973BEE04D91519
-:10F49000E73F65C4BC4DEE5F48B1E46A659AD17E32
-:10F4A0009B9562B4B72A128CFAA6DC66D437CA855B
-:10F4B0004C43BBF4DC0443BBF88CD13F2D3A596478
-:10F4C00068FB8F971BDAF9DD579BF4CF42C3F355E6
-:10F4D0005365C2E35C9FD14FBD26ABCED0AF0F6F5B
-:10F4E00001613F3C968076DCB6B175026FDC5ED080
-:10F4F000F1D6F54F83B7BDE49F9D3FCB445CE171EE
-:10F500002996FFF9AF8FB74BF05B02B7F32EC56FAB
-:10F5100007847ED827F4C31EA1FF43C28EFB8588D3
-:10F5200007ED42BC511C88C7837620DEA2E211CFD2
-:10F5300023DE9CFDE3AD79EC439CDF4EEA78BB35DE
-:10F5400026DEBEE435DA77333D46FB6E86CB88B7E0
-:10F5500032668C074DFFD488B792B3C678D0B40F0B
-:10F560008D782B8C18E341053D46FB2E2F6C8C07C4
-:10F5700099F10676404ACE20F0067E924274EB1353
-:10F580007A3FB890F451CB5CAE1F810FC9FE7EE686
-:10F590004EB003B2FBE0F1BCC97F7ABE1FFD3D3E19
-:10F5A00087DB355D6FD5105CF3507FC7E8972DFA88
-:10F5B00065E778E8EAB4312D7E2A4D73DF08988F2D
-:10F5C0006D2CB77B6C891B18D98B406ED6FC3E3BEB
-:10F5D000494A08301C1FECA5EC9CBCBE716D9E7A9C
-:10F5E00086F253723EB81CD7C524AB8FF4AEC93E29
-:10F5F00062AB3DCA6D78FFB621BE7680C54D3949F4
-:10F60000340F2FEBB4A39DF18D1CA508C795667030
-:10F61000786C4B071F1EE0B12D8EB73580D7D3D045
-:10F6200096862E27F87501BCA46C1C3F85DD05F37A
-:10F630005A98E3E07058CA843E7DDAA80FD1608002
-:10F64000F633F1BC7D6DCE334BB5B43EFD5BF3B309
-:10F65000AE2D1A8C333E61441D9B0CE36ED686A101
-:10F660009D3911E687F2D1EADE951E4B4FF467878C
-:10F6700069939545481F7709FD3A1E20629BDAFF82
-:10F68000FBCFC407BE8AF8CD457844C5BDE6E67019
-:10F69000FB6C218E9347F6A5126D5FB2F0426AB7FC
-:10F6A0006473FA7A6AC302A2B70480979484F3E77A
-:10F6B000F05B7607A7AFCFBB0E7DFE03D04920DA03
-:10F6C0009E8EA293BB62D1099BE3F392BFDE9F3D66
-:10F6D000A7F1F9360BFB51B7939D69BADD1C147085
-:10F6E00060A1A26174653301AEC33C8CE234351E67
-:10F6F0006B3008208B4B9A6A21B95361619E0C1CB8
-:10F700005D611C8F73E468F9638E0FFA8FC79BE409
-:10F71000BB31EE547C6684A15D7A2ED3E4274E3053
-:10F72000F99139263F739A493FCD30F4AF4CBBC6AF
-:10F73000E4C72E34F9B946796363364DE0CB4A719C
-:10F740000BCD22DBF2F13E23FC443D27BFB317CEA5
-:10F750008F2AD5C4AFC2AF31F3EB37726482B3C521
-:10F76000C3FD1A9D1FF4F775F839BC1AE17563BE25
-:10F77000AE9F7CA4775CA12F338CABBA7C3C4FA3AB
-:10F78000F7DFDAE07AAB621C63DF6F606F5500F27F
-:10F79000820D1EBA3EDEE0A5EBA30D325D1F69C8E7
-:10F7A000A27E9B1B7CD47EB8C14FD74D0D0ADD7F56
-:10F7B000B0A192DA1D0D016A6F68A8A66B7B834A1F
-:10F7C000F7C7DA540DE32063DB984F83A58CEB80F9
-:10F7D000EF45C16D4C1BCC230AEE199AC7D01EBD54
-:10F7E000C66BE89F5E2F1B9E8F5C9D65789EAAFA74
-:10F7F0000CEDCBABFD86FEC3038AA19D5C5969E885
-:10F800009FA4040CED445FB5A1BF3B4B353CDF53D7
-:10F810005A343432001F773484C20887F686305D4C
-:10F820003734BC44D796869E30C2E90CCA5FC0A369
-:10F83000C7D649F2C333D1C3304FE17201BE008F46
-:10F8400049368F25296AFC2405C6CB8A9E1F8C6702
-:10F85000F0CF82442FEEACB0E1BED3DB63786FA66D
-:10F8600094508EF98923C512C5BD8E142727A2FD99
-:10F87000B2DEEE999B0BF3387C4CF26DC5F5E20BD2
-:10F8800031E4E529616FBA27BB482ECCDF64D92A61
-:10F89000115DF3F76FEA1E13337E74F89BAC1AD731
-:10F8A000E5DEB35346BA985F5C9B1C17E5AFCD0FFE
-:10F8B000FD47452A8D979D1F07F4327F73ADA36ED8
-:10F8C00062DFBAF47E376D32DA977D741F74E13AE5
-:10F8D000C66BDF74A17C6B4FDB4AEDF6AC81F32481
-:10F8E000BF13EBF950D8CFA7851D7652D861EF0B27
-:10F8F0003B2C22ECB07784FD7C5CD8CF6F0A3BAC0C
-:10F9000047D861AF0B3BAC5BD861AF093BAC3DEB7B
-:10F91000B959240F9FB53029869FAA5FBFFA43A328
-:10F920001DF6E5A0D10E5BB5D96887DDD861B4C3FB
-:10F93000EADA8C79B95AED2AC3F31BD618E36CD7EF
-:10F94000D71BE5E1B2D5330CEDA5AA31CEB6A4DACA
-:10F950006887E9F8B93660948B0B2B8D76587FEB6E
-:10F960007D21349BF23F88C413517AAF378F8B7A55
-:10F9700005E825F702E8158A83079A317FB203BBB1
-:10F9800080FE2DB1868F4E41F9F9BAC430EEB4E74E
-:10F990007CFE9CF9F2C5DFC9D78C74B3FCB831BECC
-:10F9A00071DD1D46B856DD6CF44B1C9546B82A69CE
-:10F9B00046BF64A159CF048C700529CD902ECDFA95
-:10F9C000C6EABE5946F9FD79F58E83815EE16D8305
-:10F9D000DE71E09D4CC373D23B6DB93C5E970FF373
-:10F9E0004063A131AEE010E693F6BC61A3FA109833
-:10F9F000E06B6341FF94E2DF00BF17EDAA560FF4FE
-:10FA0000FACB42A7A7094C56269DD9FB35E8EF1043
-:10FA1000F910F6A9ED248EAFC22FE22B9F413B4A8D
-:10FA2000CFE585F9F3A8F91A9E7F0F7136E07C9433
-:10FA3000D7C6E6FF3DE7939882F6109BC2A6509D7D
-:10FA40004164D8A0E2ABE6FBB9216E07E5A6713BA5
-:10FA5000C89FBE40127927E6C1B695B9289E398A5B
-:10FA6000059FC63867FC21F73C6836E390A9E85744
-:10FA700019F97FD19C81F3F25FF21AF97FB63CC687
-:10FA8000E40F19F97FAECFC8FF4E66B25F224C4635
-:10FA90007B927060353C2738BD26E8A8F1BD96659D
-:10FAA00094874DE771379D7EA6097C31D6B9B7168C
-:10FAB000F3CDE057A2BFE1645AF214AC2B0AD72B66
-:10FAC0007ADE8DF026ADF5915D7A86E3C70FBF88AB
-:10FAD0003F3F8BC217E2EFB8117F4ED3F3D3829E24
-:10FAE0002E9E17A7A37FDCBC4C749530EC12F9B79F
-:10FAF000D874551656A44498DF7E8F85F2A9FBC3AF
-:10FB0000F5E132687FE2E5F542AD690B6C345FA642
-:10FB10000C9909789825D6EB1779ADAE064676C7CD
-:10FB2000F30D2EBA32562FA13C6AF1DE968CFAB153
-:10FB30006B943A12EBD2BA8627ADC3FCFC367B52EB
-:10FB40005AAC7A96DDF602D2A75DBB536D32BC5F2C
-:10FB500066F3D8F0BDB2B41512FA7B5FEA616417A0
-:10FB600094A5F1BA8CE71B4247F8F754AABF8175F8
-:10FB7000CC40FBB4C2533B233105E3B3608BC9686F
-:10FB8000E72691FFBA6FB893F0E6F4ACAAC0FCF197
-:10FB9000ABA912B3F8013F3EE60BA11E484BF0059E
-:10FBA0007138AFFD7D84F36AF8FD2CB34F2F009FB1
-:10FBB000BF1F8D8F0216D5A6BC82B13D224FD43F08
-:10FBC00009FCC84CA53A8B961E9E1F6291D8799667
-:10FBD0007785DDA0C7F78F0BBBE14D11773B22EC9A
-:10FBE000861661378484DD7054D80DFB84DD704047
-:10FBF000D80D2F09BBE11561371C127643AFBFC08A
-:10FC0000EAC99EAE65AE08C6D95F05FF1CE58877D8
-:10FC1000A5255809EB98A17604CAA1ED5C6727F9E0
-:10FC2000393A4D6BC4F8B8B35A9B89EBF02E3FBB01
-:10FC30001AFBA7A6396405FA3796B6A746789E61DF
-:10FC4000C85CE08F95825E96AAB30E207FE870674D
-:10FC5000D2A379946FEAE0F076C12FC23B55857646
-:10FC6000941CA935C17529B6A3E48603E910E058B0
-:10FC70009927F82187E570786B7108EFB85A016F02
-:10FC80006F4A4CFED82CE0ADC36377E957AC1A74C9
-:10FC90003D9AC6EB258E167FC5FA2AACAF5B91283C
-:10FCA0006FDA9DC6C75B20E8DF3C9E9E47DD583E6D
-:10FCB000709CEEB0E8D7DB6E63B27368D438E5FFB2
-:10FCC0006697E1FD25A17BD2911F360ED1F3C33E8D
-:10FCD000B2AB674AC5BFCE80798645DDA32E271714
-:10FCE00033011BD3F78E8A75F6379FA3E5D7D86506
-:10FCF000187751E81E86DF73DAEABDD1F5A4DD621C
-:10FD00007EAD55B733E4C7F028C03BFAEF01A78CAE
-:10FD1000F6F6E834DFBD88776F9A6ABF13EECF033B
-:10FD200039287B705A1DBB53B01FBCF30843FA98A7
-:10FD3000D089FC7634DD45F2A6BFF95CA43F828C05
-:10FD4000EC90FEF407D031D941CE391F1C477F76A5
-:10FD500021ABF785E0BD70AE6F38F22FABB6935E86
-:10FD6000CE82DFE87C9A7E5D68D2DB6EBF7D40F993
-:10FD70003BFA42431BF2CD51C137AD3696887539F7
-:10FD8000E139B7BB103EF3D333F7207E58992B32BD
-:10FD90000EE0D05A7CE7F508AFD639AB3C16A4ABE1
-:10FDA0009231F43C5CE63A8D9538BF29BB3B5D8EC1
-:10FDB0008277EB7DAC544578A7DFE5BD09D69599F0
-:10FDC000F6A7067532F4B3737FA7A7FCF76919513C
-:10FDD000FD27E595FD200FF9B97238F1C378879AB0
-:10FDE00019AB1E58A7F3C6D278E2F3F76B799D02E0
-:10FDF000DCBF770DCC47C5BA155F1FFFDE28E829A9
-:10FE00006EDC39E273F53EA78C7E069396B7AC8123
-:10FE10007635DA4968376DE27CABF3717ABD515EB5
-:10FE2000AA26BEAD36F1B5CEC7BB75B9D9C7C7894D
-:10FE300088D7B85ACE4FFDF1F1D24FC1BEA142A032
-:10FE4000A0C1AF7B63E59878AEBFA2ECDA2924931A
-:10FE500064473E568132B26BE3C57320C9DD389FDB
-:10FE6000F03D3973115F5A23D8FF38B735F63E7A23
-:10FE7000CBC475B2217E587FFC5A291BF329ACDE16
-:10FE8000DE6717671ABE4775028BA3DB48AF9AF28D
-:10FE90001BB41F308C891FFDF37B47F637C3F7DA9D
-:10FEA0004724B34684E71D9CFE5CF010C703353D34
-:10FEB000C48FCFBF352E1B53F72C9A5E61FC88C6CA
-:10FEC0009FBFB36678369999A25D73CF98A9D8AED3
-:10FED0000AD84F46CB55566123FC5FBBD6B215E31B
-:10FEE0007EE3A58FCEEE85FEF157397CCD30FEB591
-:10FEF0000FACB0235C1669EAFE3AB8BF08E822E806
-:10FF0000A37518F8E4A8CD63C7718E56585807B486
-:10FF1000E31719BF53B3D6C847663BE458A23ACAA1
-:10FF20000AEF7F6071B2AD70DDBD65D5E338DEA943
-:10FF3000079C544FC870AC7CD4034CC42595C7EFC4
-:10FF400081E72B363B19C603960A3B3F313F83C6F8
-:10FF5000B5BA97D3FBB5ED89E40F9FDE72F964C49F
-:10FF60007FDBB0FA5B03C037A792D41AC4EB8AD602
-:10FF7000ABAC1A3C6F8BEF9889FD3FB032CFD66C9B
-:10FF800068CB0FDA713E3D6017609C559F676D5BD3
-:10FF9000147EE1BFEA7C1E779F67656A670C7BA6CB
-:10FFA00023DFA2C7573567D4FC1FCA97E9FEBCCC34
-:10FFB000612D0FE17700FB1E9F800BAE7B268F87A4
-:10FFC000B6A5F96A8643FBA485799A52F0AABC8348
-:10FFD000FCA9DDEF644F13FA19F5778C1CF1647BF3
-:10FFE00094DF3F497CF744127FFEBE373E88EB7CAE
-:10FFF0005FE66DCD9B10247AB6A9598B13F97A2C44
-:020000022000DC
-:1000000097E1AE073EBF6389B22393F0C1E4E76096
-:100010005E2B367D97F0BB0DE083FCD9E3915B76D8
-:10002000C33C4E83F2D6F0B9F7919908CFDBA70213
-:10003000A1A65E0CA77BF287F13CF4E6E644D2F77A
-:100040001EA63A2EEB83476DC7F6BB2D9349CF6BA7
-:100050005C7E70FEB3B028F90EF89D57F81DFB0AC0
-:100060005C6F1CEB40BC58F7AD73E13C97D6DA29C6
-:100070002E94C00295284F6B3759A80D3F1B505F37
-:10008000AC10FCD5260F3B5087F0403B9CFCBC4796
-:10009000F7635D40AD905FD52B8D747AA3D766A0D2
-:1000A000E3AA3546BA86751ADA9BF379FEA5C77FAF
-:1000B0002A05F5731B2C1BE1F2418B25B895E46BE7
-:1000C0006054745D9D9C6FD5EB56647B14FC5700A7
-:1000D000FDAD40BDE1621DE5A9B8EE71B390DE1D36
-:1000E000C7E2699E66F8FEB3C3E144BA5C331CE61E
-:1000F0007302E818EB7EDEDFD24CF60BFE4806BE3C
-:10010000F6B4207DDF04B37CC443F4E9C0FC914E17
-:100110002F3A7C6A37671CC07EDEFF932883D3C4E6
-:100120006ABD45AB30AFD34B4726F8E09A6DFA77FE
-:10013000C6F4D1193D8F4167E5D097E345237EA9E9
-:10014000ADE8CDE78D1AA86E99F05D049FEB9ABCDF
-:100150004C2B16EF03DD6F2C7D85E8E0130F0B4A67
-:10016000DC9F7D1DE57EA2989BC69410CAD721A274
-:100170005E14F512FAC9C962BD496B2C6F56E430A2
-:10018000366C8DF46605DC4CAA0887504F38BD42AA
-:10019000EFEE2AF8C9F8CBFAF4D890F839BE10ADD2
-:1001A000C6934AFB12EC9E54B47F1EB058AA315E2F
-:1001B0003F8419EDAA64133C58AEED64B43D1E2F84
-:1001C000E4FDAA99632CE4E7541AFD529BC92EFA68
-:1001D00011D2F5F0BEF5CBF827C0B105FC3694532B
-:1001E000C3421D1D489F3560B70669FD3ECAE7380A
-:1001F000407F3C62E98B5BFDA3E21617C5BF44DC80
-:10020000A2BFF8971E0758C86FB18D0ED58BF9BEE7
-:1002100085DE9BE6A01DDA58FA152FF94BDED36474
-:10022000973A845D1A376EA587E7CD38FFE87100ED
-:10023000335D99E34966FE33DBA5BFCD17F6D304E2
-:1002400036E1F3C405F4F87D6B16F77B5AB35634E8
-:1002500061DDDA79E1F778342BE171F1220BE151BC
-:10026000B7D716FBCF2E42FE7B55F81797F27BDAF5
-:100270004D7E48BCFF494589A13FED055C3EBA8BE8
-:10028000F9F3C52E667345E50D1C055CFF2E063D92
-:10029000E88225CE633CBF319F19F35249621CFDB1
-:1002A0000A3FE1A9F9863AC1A4027E9FF2A04E91CD
-:1002B0000775893AC1B2EC737B3FC3FB0AAFFF7588
-:1002C0002AB58FDD8976DFA2449F95E8577DFA3BFA
-:1002D000E81F2F7293BC4DC992A9DEB53ACDE52334
-:1002E000DAD794D7D12F5BC488B701D40AC9DB25EC
-:1002F0005817E119C0DF710D1C2F4BD0FD9D624EC8
-:1003000057BD71A50097DF56F8457ABAB6DA482F7F
-:100310004BD481E927BB40F8D162DFD6F8C885DD30
-:100320009F115D70FEDD388AE7A1CFCF813E98B77F
-:10033000EDC71ED7FDDB043BF8450968BFEE257A03
-:100340000F67317B34BE03C592A1AE215CC8E23D8C
-:1003500043713641C257D8CED21F80FE87CB3E6054
-:1003600077C0A712BE33CC82F57BFD7DD74CD7F783
-:100370008DBB89E2FCDF9E0D2082F9DE878965AAAC
-:1003800023F8E9329CC7B7B14D75753F5A8675752C
-:10039000DF8ED3DBCF7F4F89AA2BF87AC1AEEFA1D6
-:1003A0005C575DA05F613CB7CCA88E8AB14E92C706
-:1003B00012C6FD501E4F8C8227F90946F89AED7639
-:1003C00009F13719E9D1C8E7E6EFAE32E1A5BF750B
-:1003D0009BDF839FEA09467AFF5AC10075B1E6F7B1
-:1003E00013B04E22F1F3D71780E0A43CB4C4AC3E66
-:1003F000F48F5939A3EF593C9C8E50A2A0DEB3D79D
-:100400000FF111DCA01D877A20E8D6E3A734E93884
-:10041000A40309F38621D2DF309588650CF6D7EB6B
-:100420000C54F6997BF0720EE42F8D2357F23CF2B8
-:100430001B0A8BE0F7C63FB239908FFEF931D0AB83
-:1004400032EAEDAF682E689F5BCB280FE0F6A8D4A8
-:10045000864F459A61BE5E95B76B0046A8879D5E44
-:10046000639DEBEED247CA1CF0BCA582C7550F377F
-:1004700084DE588779DAE222928FEBB063D47CC3B2
-:100480007BE21C187751B5AFBBD04E7E77ADE4C090
-:100490006BB8A956C345BF91AA755A648C33A80C92
-:1004A000FD7AC7DAE69948BF6FD835DF30B8BE8726
-:1004B000715818BFAD49BB05FD1C459E539901728B
-:1004C000616B9B8DF613BD57FEFB34398AEF7E5B63
-:1004D000C0FD845777C77D1BE1D06A7145E2F06AA1
-:1004E00057B7DE9782DF73F81A618A6F343E948EB5
-:1004F000DF69BDB1D5B7079F373A7187296BDDE258
-:10050000AAC6715BD36FF2DE1435AE6BA4A31EEFE7
-:100510008747B450FE59ADF439E292705D1F257AD9
-:10052000E1FDB6B539C9488B2DA98E5175D8EFA616
-:100530003FFFBA00F12E5BF391F51CDE0E3BAE7B64
-:10054000B457D5300F7E214FDD87F4BA74CD7B339D
-:10055000A93EAE22E95EBC8EBEF0B53684FF1B22FA
-:10056000FE12495D4179D99695752E9CEFFCD4CC4D
-:10057000A6E8F84B4BF18DAEF1F05EA6D75ABB6AF8
-:10058000C8C5F4D182F19629382F58CF24ECF7A7AB
-:100590000615FA45D21DD5B1F663BD2BE0E76A5EBC
-:1005A00095897190962D2E4CC3B0168BBA19E39C89
-:1005B0005A4642CC7AF5097EFE5E8DEA99E99009A9
-:1005C0003FC46FBFDDFEFAF7B4B1684772FCB96C87
-:1005D000CC658FD27793F2CA4E1644F9CD177D378A
-:1005E000B585E47F8B85F3EF04FF1FBF87754FCF81
-:1005F000E605CE20FC5ADBD4CD082FA6B9D890D280
-:10060000FEF924721F1BC540FEB6343AAB63D59B7E
-:1006100045564AF3904F8083DE1B322A4ADE37D597
-:1006200065623C24D2780571776FFF2DAE77100F8D
-:10063000912D5949A8FF22E92B3233916E055D9A1D
-:10064000C7FFF7026E3FFE242760F5A35E9EC8F346
-:100650009BB30B02366AB30E2FDAB55F00BA1DE901
-:100660001FFE0FA55BD273EF6EFF1DD115F30C2E8D
-:10067000EF1810F2B6B1F43F29BEBBBE90E74DF4BF
-:1006800078A06EE7C68DFB7E08FDF140A19ED72ABB
-:10069000BEF7768C1FE979D3393C1EE881DF58F12B
-:1006A000C080291E18DF4F5C7F865FE83D61CFA6C2
-:1006B000C91D817294BB87241FFA0F98AEC079566A
-:1006C000052CC110E51FE25D34EF1211D714FED6E0
-:1006D0005231EF371B5C0CF3461B1DCA7E9C7FBB5F
-:1006E000C8FB5EB7FA817BD1EFC6B835CE7F1EE37B
-:1006F000761C2B8EF351BC05892095F5FA670BF01B
-:100700001EFAADD29CBC68BD083320BB653E33DA0F
-:10071000730B98C9CF5AC9ED30DDCF5A66B213CCEE
-:1007200076FE22D3F3BE7C0078174037E7FC391BF6
-:10073000B1B4ABC6BFEFDE480CB9734CE4E98E36FA
-:10074000286FA21EBA77D1CF5C48A7EB6D9D2ED43F
-:1007500027EBE7DC9E88F4B77EB9447C79A4A192AC
-:10076000FA1D6E08D0F55BFEA4DE785648CF33C084
-:100770003C5EC953EE423AD7EDB14573CADE5C1711
-:1007800085E70515B30DED4071D59BEBA2E3903ADB
-:10079000DD49AC3E561CED593FB7DB6D4097545FC9
-:1007A000283DEB1BA8EE06E8E85C349CD6FB8DE701
-:1007B00010BCEA9F3174203B465FAF0E271D0EFA36
-:1007C000F3FEE679A79FCBADBF749EC1CF394FF33F
-:1007D000FCF479F7D73F2071BD70A7BF6C39EE17D5
-:1007E00079254FED4479BAA832693FC61A8EDA38B6
-:1007F0001F1D5512695FFBFE89566ABBB378BED5D3
-:100800008C5777652DC9B54BE137BED8C2E3CCE034
-:100810003F29F0E72CB1BFBE7D2223FE6C2CFDF1F9
-:100820004B987FFE4D999D0939336F6E94BFB4D1BB
-:10083000D119BA338A4F81DFEE45BE75EB798780D7
-:10084000317F08FE8E217F6896336E53DEE1B00E55
-:10085000F77C80FB983EB8F7EFD7C4A60F407C1E0C
-:10086000E2DD0CA75B4DF031E72702BBAA8CCF0776
-:10087000E9D76C6DCBDD8F79350DECCB7100A7D747
-:10088000F011BC17AFFC94D220AE42CE37E3236701
-:1008900036A09EEC069580FA66E382DB3763FB3C6C
-:1008A000D80188DFFEF980FB6FCFE6291FFB63D4F8
-:1008B0000DE8D76EB417A6605E30B6BDD0BD72C667
-:1008C000DC98F6C282BACC3C9C5795D15EE8DE52E9
-:1008D000F9580EDE477B017EBA0BEB0CF602ABCC6F
-:1008E000B9047CB8FC8D1B971BB33E6F7E9E3AB457
-:1008F000306A3DEEAC7A165DC7F8C77CC55308EF89
-:1009000057F59E43C2BF07F6D83E7B8CBA45FD7BA8
-:1009100053FC7C3FBF7E8EC860CF13D1EBA7D7DBE3
-:10092000956AB4FBF4B897DE6F4A218F73B4652AD9
-:10093000ABF1394B987A89711BF5384756F665A2A9
-:100940005E5866BDFED17F5A647A1EC3FF639897D6
-:100950008C4F3BBBCF035D4EFAD55C8443C9D9A015
-:1009600086F910E71C0BD94FCE344676CE60FDAD2C
-:10097000C1F66B6BE2F2A775058F979765DBA81D33
-:10098000AF4A5B51FE4CBF30D4827223A04A4FE283
-:100990007CE3958F3E7C0AF535D801188709B07A3B
-:1009A000DA5F9D600F507CA27D0E8C9C8D71982625
-:1009B0007B26C5D3337E9AE8C5AF05DB305EEEF407
-:1009C000F17D50D57EED5E3C2F637EC9380B83E709
-:1009D000F3025CEF2FC6F80D8EBBE8EC6E8CFF5C6B
-:1009E000EBE7F20BFD38F4B396D4DD3DE961F92F66
-:1009F00089DB04DB9273299E2453FCC0141F7216FA
-:100A0000CFA2F8905E271128E6E7F7B0B4043A7F4A
-:100A1000C21CDF31C773CCF11E737CA7BE90EB7193
-:100A2000DDBEFA5AA1D1BEBA0BF71E0C47790B2ACC
-:100A30000AF8BADDCED23B2646C75FAC0CE32F776F
-:100A4000159AE28C83945B61902B2770217B5FB6B3
-:100A5000A3BFBB5CA9A5F89E99EE1F10F2ABB930FD
-:100A6000C150D7116E5823DE8FD310CFCBC73A8237
-:100A700071197DE30C963FB6E42BF717723F6323A1
-:100A80005E994FA57D04B30B3C06BA65F5C3D989C1
-:100A9000E8BCAEE9BBFA7CF4F13FEF3C3608780FD6
-:100AA000964F369616B91CF0FD4F00C7BC3E1A0C87
-:100AB000ECA8F8B41E3FD7DFABC1BC410EDA9316E9
-:100AC000CA1FE8F7A3E2D836A4DBF8345509C4906E
-:100AD00097E1C2DEB829E531F5EF308B4A72A14EBD
-:100AE000E46BF4F16CCCDB487C80B4ADCF4B8A1165
-:100AF00037673E97134866C50689613C2881291DE2
-:100B0000187F76B4D9A9CDB4EA0363A3EA871CC5DC
-:100B1000B30E609C4DE70B73DEC621A5CDC261EB21
-:100B20003A8CF92B737ECA6C57EBF1751B7C04E78A
-:100B3000F507C4075F6F501ADC7A9FA4F57C41D794
-:100B4000ABD3D59C9CAF7AB1FEA4254EDD5C0BF3F4
-:100B5000D21E7351FCC28D73439884E017E5E463A1
-:100B6000FEA750FE5E28E4E7D1B458783DCABED453
-:100B70003FA544EF5BB850C8EDE1A70A651E27B159
-:100B8000B110EE93621353882FF4FA93C3A9DCBE1D
-:100B90009C5F7263E87668FF2F51277955C9D37A35
-:100BA000BE7F48593EA3D20F6E0FF27AB4C357F6F8
-:100BB0009EA7B207FD4EBD5EF7AA4EA39F794D9644
-:100BC000DDD0BEC8CF34B5938ACC7564AA8BEAC891
-:100BD00052451D9998BF994F7ED8C0F31A3F16F51C
-:100BE000FECF8AFDB2FF5BD4ED758AFDB2CF89FDE1
-:100BF000B23ADCD7DB558A4F9F9A0D365D765F5C43
-:100C00007063E937BCC8C7938B2C7A7E660FEAA95C
-:100C1000BEFD15039F0BB6B0D29837BB3660CC9B98
-:100C20002DA936E6CDFE94A34C29C27CCBE4D54D4C
-:100C3000783E41D52689CE27D8F8F0271F3E85F685
-:100C400062313F7FC7FC9D2362FF85BE7F43BF5F4C
-:100C500056C4E9C3BD27D58E75F8559BAA66613C7D
-:100C60009D79A60ECA7E9B8D317858B7BBC963C7E4
-:100C70007320AA424B1D38CE8D9B619C84C18F731B
-:100C8000DFB8CB286EDD1BF7D7AEBC1EDF3FA2C797
-:100C9000FD59D6F565F0FC8888FB2FFBF984C7D099
-:100CA0003F7AAA50A94278FC5BA1B200AFCBC47CCA
-:100CB000A0BD28BA0D3F2F2519CF9D585634407C32
-:100CC0005D9A6189E93FAE2CE27216F4516D118E86
-:100CD000EBEA8D7BD5E178CCD541FBEBEE2EE2F251
-:100CE000A9F94DB61AC769FE395BFD5C0CBBFBD692
-:100CF000228B3EDE57693CAFAEDF02B7F0F18DE3E9
-:100D000049CEAA5108E753585F1663BCBB8B1CFA47
-:100D10007877D2FB69BDF3BB3B7A7E7DFB663C896D
-:100D2000C8B4EE1AD5DA03F4C31E96A82EDDDDE5AD
-:100D3000995B88ED5963A88EE548C5C0E76BFEBD99
-:100D4000F6D11CA9F8D9BFE43E9AE78A3206B58FDE
-:100D5000C6BD80A9B1F0FE7341977B8A73864606B3
-:100D6000C09363CDC130DA19BD6D9BCA30EFE7582F
-:100D7000F32ADD5F1F17A889B5CF392CE8B4A56227
-:100D800065005344ADE9B30CE736FC3E57DD57141C
-:100D9000E52F3BBCDC5FFA64ECB9BDA89A16545849
-:100DA0006C9614B2B77D16306D73D756495E993183
-:100DB0007FFD03332E87E78BD2C0BF8B5A77D1EAF2
-:100DC0009FEE057665C515479A53A0DFCE7C358C1E
-:100DD000E3977AE57DD85E14C8A67AF7F5498CECDE
-:100DE000BC53E31CE48F98E77D42CC1BE47293ED87
-:100DF00073C8E516939C6C4D1FDF84F31F5FCE22F2
-:100E0000286133BD67CB301F38294F3D817C96E97F
-:100E1000658A7332DD5758543EC73CAE6B1AD7B75C
-:100E2000E32369F7637CF9B0EEEF977E6E7FFF6C8A
-:100E3000D100FEFE29911F68FD8E33665EE4D4CAA0
-:100E400085B1F3030FD7AD40BE3FF51DA3BF7F6A49
-:100E50004B750DEEEF3B25F203A766D60D981FD01C
-:100E6000D70972C8310DE5506F7E40D8ED22CE3DD6
-:100E70003F4F89C3E7E0CFC74FCBA37DE86EBC32BD
-:100E8000CD733DED4366B1F7C7B2473D0AFA39FA73
-:100E90007EF6297E3505C7D1F7C98E47D1368CF647
-:100EA00075DF1A8B9E478BF9FDE579D3DEBCA695DD
-:100EB000F64F0F326E3FD87EB2BF93D7E3D8789DFE
-:100EC000615C6AB917F355E727BA48BFB7E1FFA2DB
-:100ED000F46A7A919A376D78F438A6F354E5C17DB7
-:100EE000375EF89BA8AF506F75335689F2E6DB4941
-:100EF000F514F79821E066BECE9A26F0CA3C290880
-:100F0000CFF4A2C04CC2E3F39D329DFB2AEEB3ACFA
-:100F1000C1F99FCF38026FD3BEFA7249E675798C5A
-:100F2000F8E28A2C0FE969DDFEAA9DC6E5A6934585
-:100F3000C63A609DCDCADE841CE8F7EEA3B66C7C91
-:100F4000ED0789CC8EF30E64819C8375947BD5D19B
-:100F500003C9473C89C88AFB1E58C862F5D2359937
-:100F60005F350BDEBF881F1F3D371CEDF11F3CC6F0
-:100F7000F355573CB6D2B5226AFC87A709B999C682
-:100F8000E75FA358827206CEE72CE5A5AA64AB4FB3
-:100F90006198473E7F6C09C609C17E1B47ED4FA88B
-:100FA0001D96AD3998E77ED7FBF131EC7FC5376FE1
-:100FB000BC8CE85FC0E386B539CF909D9FA7DE81EA
-:100FC000F80F177F92386622D9F19B91FE6FB0B06F
-:100FD000402C3B6683C0DBD54AFD754867572B4ED6
-:100FE00086FBD5C2654E82FB0F4A2C32DA95F3910F
-:100FF000E6319EF3A88DE2CD008F9BF1F9219F9BF6
-:10100000CE892E577E6AC3F69F2659D8E503E8E3BA
-:10101000CF0DD7E24F86233FBE8BF41763FEB56238
-:10102000FE3A3F01DCCB695E0AAF1FE98FAEFE5886
-:10103000A87C17E1D496A9AEA6F3103D0B06751E49
-:10104000E2FC1F06A976CFF9FDFA112C46FDD76107
-:10105000C127E6FB3F9CC6FD821BA7F17ACB2B1E66
-:101060003B776836F2F55ABB07F1FA5461E0C7D313
-:10107000A2FDAEBFB21C99292D27FC85E7C0DCF983
-:1010800041A089D89E37D646F8D3CAC5F91E773114
-:101090004F7312BD456DD75A0BF1993BA1A31A8D21
-:1010A000665B61FDB16BF1BD3289F6F347ED7319F3
-:1010B000B08E2C22F2592DB8EF0C6CF9F03A493F62
-:1010C0006F8B5940B6852B6CC2BEFFE031652CF0AA
-:1010D000BDA8CF3CFEA2F571AC6B3966E5EDF08B97
-:1010E000D6514D400791517C1EED0F587C8D325EDC
-:1010F0009FDC8C7906758DC55709ED9AD03D5E0C45
-:1011000071AD58E764E82ABC77EF15642F7EE2657D
-:1011100074AEEC9254CE37756116B466F4F9B7EF3D
-:10112000A4B3A09E3FC5FD737EA1671EC4FD6B30B6
-:10113000EF2F6DF8BA7637BC1700BF17E36AC37C90
-:101140003CBF191FB6F9820CFD5D5E1FD9D26861E4
-:101150000FE238D28666F4CF9D22FF11AFD492FF02
-:10116000380CE853C68879C466D8BFA63295E837EC
-:10117000B91238231BAF46FF38F712FBD8965C3FF5
-:101180003C09F9E5DC34A35FDC5F7C5DBFE2393705
-:10119000889F2E916FDD01763BAEF7E760B7E37570
-:1011A00017D8ED781FCFA5C62BEE63C3EB1EB0DBBF
-:1011B000F18AFBD8F08AFBD8F08AFBD8F03DDCC777
-:1011C0008657DCC746FB0E4BB4D050844F593CC306
-:1011D000FC508B9DD39996EEA03AF75009A37C7EE4
-:1011E00038DDB1B509E375168E272D893F0F27AA83
-:1011F0005FA176C64499D7C5B351B87F709D65A2EB
-:101200008CF6539B43A63AFC534D36DA9F7062AE80
-:10121000E56DCCBB308BD527817DF3CBCF6E25F828
-:10122000D72ACC8AF2A109CF0B4579FC2113E71705
-:1012300084253C57AE3991097ABC2EA880CC7E1FFC
-:10124000BF45F47A4045BF78BA536FEF55F179ED59
-:101250001A8BE8FFAB20D26FABDE5F3BF404FAAF32
-:10126000EB4CED6EABFEFE686A1FEBFDDEC81A05A7
-:10127000E93D537F9E7A03B62371FAFB7FBC01FBE5
-:10128000135CA8EEEDD413389F13E97A7FB986DAA0
-:10129000BD7573D7ABD8FFC470DE7FCB9E834F6222
-:1012A0009DC95F7BBC6655A338BEB688B1A7932E97
-:1012B000A6AF77A74BC678A86231C443F5F8BBD573
-:1012C000BDFC72DA7FD6E424B91849F7D5A0DEEE6A
-:1012D0002F2E1A15AFA7B8E88FA6EBF5CCA6F827E6
-:1012E00070168E5B8DF1401F7D558DDE9FC62CF5EF
-:1012F00021AC530F9C4994D18E74A445C5EF840C46
-:1013000018285ED85CCFE38361D54EE777E875FD9A
-:101310008E6251D72FE2857A5D83A3F86143DEC0E8
-:101320001C2F64D2CD948F0EAC34C603E7AB9F2F35
-:101330005EB89C85EC9723FD2B16AA8B58EE91DFA7
-:10134000B90CED6836819FCB28BF14ECADEB9769E3
-:101350001819CF9BAA16EDF65BDE7B1BFB079BE201
-:1013600064DC84BFECE6B2772E23D32D81617C6BE5
-:1013700059093F9731EF43DF4B32CA53AFD5C7CD41
-:10138000B4C03751FE06562651DEE4FA3B2CF4DD9C
-:101390005ACDCD104E60570A7AEF7A1CE94B725B3A
-:1013A0000CEDDC513ABD5DFB38D2FFF464BD1DFF8E
-:1013B00004F25B99437F3F8FDA4B558B789EF5841F
-:1013C00002AAE458B94EDF2FD7E0F36BC7F48E477B
-:1013D000F43DDDADB7AFB9019FB7F58E5747DFFBE1
-:1013E0000D9E6844ED194F203F9755097DA5BDF727
-:1013F000388EDFB25C1F7F7C10EB509759F5F759A0
-:1014000010C7AF63BD6D05F5E25B82FFBB8B3B6B25
-:10141000305E755DEFF34E5AEF72D17EBD587D029E
-:10142000F9E95F7E7D7FE7EF99DBD7B3F0CCCB7333
-:10143000FBF8C22CAF7E55CAE5887FF54F91CCD919
-:10144000F2FA27E95C378C07F07C56EAA200D2B7A3
-:101450004BF20167B08037302B565DFCCA123ECE8E
-:10146000E962635EACC594170B88FC547FE31C2AC9
-:10147000E5719DB6F2D87EECA4BCF28F8A319EC095
-:10148000CE4A389E470550823DDB98A3FE19EF03F4
-:10149000EB56903DC7980FEF835FACA19D390FC00D
-:1014A0008979D8C6D247284E7FA2D06E380744CF5C
-:1014B000736E7428241FDFC3BA0E908FCBCA959920
-:1014C00058CF78E308896DA57AB204CA37D8463A6E
-:1014D0009E24B92EF29EFA391CF32EB12FC2BC2FD6
-:1014E000E58F62BD9F14B7DB513E6B4C9B59914B0E
-:1014F000F23A8CF5C756F706CA033B4BED9447D03A
-:10150000F3CF75E2DC6F3DEF3BFDC250AEDFB3F4CD
-:10151000B8EEC0F9DFBA35BB03641F7448CC9A71CA
-:10152000713EB836A0A5DF85F66F4522ED17A85E9F
-:10153000F1328D7F6414A3F87BFCA27ADA1F640376
-:10154000FB50C17A17912FD6F7798FBEF035DA3775
-:10155000AAEAF5E7D29C2128279DADE067D1801C3F
-:101560002E7ABEB8CA24EF6B8BF939730CECF87184
-:1015700049F89D81F73DDF3F9D9FEF77B283D7F319
-:10158000179418F3C7EBED3CCED79669A4ABEF4F99
-:10159000E7FEEA83D3453CB1F4C7D508974F98D509
-:1015A000877931F6283F0F0E632CB4DFCA7C0E73A7
-:1015B000D662B2EB1E1D0D4B045BDBB6E62D8A2B0B
-:1015C0005A36F3F73E9CCCEAD16FB1D9781B2E1A6C
-:1015D000E6FFA7F8D53925583FB6E61DEADFACF19E
-:1015E000FAEFFEE237D525BABEE7F19B65DE033D93
-:1015F000B8AFECBF1CC731ED7B0DC8BCBE645DB19C
-:10160000ACDB17741E2110AE1DEDC5F4A2C00A9C00
-:10161000379BD829E33C7479132AFD6A0DCA1BA6AF
-:10162000C4CE4BEB7CDF62CA4B07BCFCFD43BFB8AA
-:10163000AB06FF3D88FEF2109BCA7AF306B795E031
-:10164000BC52F4BC81723BB6FBF4282CC86FD0A30B
-:1016500037ACFE6FA0477BED76ED580DCAD52FDA7B
-:10166000FC81AEFE9DE8AA92C7CFBE68F32F9AA672
-:10167000ECC3F9FFADBF73D5B4C06BF89DFB2C4A2A
-:1016800075024FEEF92CC63C5F4FC90079BE4BC5C1
-:101690001FFE27DE3070BCC15AFACF196FB0E39E2F
-:1016A000AA3CE2A3CB4A918F8A391FFDABCB3D58B0
-:1016B0006F6E29F14367307ECC5FDFDF4F2F52CB57
-:1016C0004B490FAAD63D403FF795B9B83D13E2F01C
-:1016D000ED8B67C0FCFD8678C613ABFF06F10C5896
-:1016E000EF02C26F85F8FE171F7F37137C156E4F10
-:1016F000FC0BD2671BADAF93AFEF1FF0FDCD442FB6
-:10170000CF727AE9830FB793A2E073C3EA7F0C7CB0
-:101710009E25F8ECE0F3FB02E0730FC1D3C7E77B33
-:1017200029FFFAAD629E0F81F75EA675E6723A78E0
-:101730005BD8D7E077CFB85CEEF3BBB7E42BBF2E16
-:10174000E579E4C3A586FA4F258CED01FCE2EED2E3
-:10175000D87EF19B38DF2F9A5FEC2EE170EBCBBB8C
-:1017600004F979B7ACFAEA2BE13BEF00BC31DED6E5
-:10177000BE4622FBE27C1AA3F300747BE34412AF63
-:10178000DFBB787F584508E7ED2CE4E78CE8E703FA
-:10179000D8A4E54343F2C5707D7588ECC07D482B25
-:1017A000144B0B9E133843FB88F69F391427FD3BDF
-:1017B0005BA3BD3EFB1DE847839FFB25ACBF5CEDF3
-:1017C000A1FD27FA3E337DFFC78A50EA01DC77DBB3
-:1017D0000EF4900ADF995F61DC0F62B6376CA6B633
-:1017E000F9DF314D9E6E3C8F0AE04FF6CFF9365E41
-:1017F0001FD76E637BB0FE43DD2005C164624F6B73
-:10180000163A877325C0C90AED191D19544FEE48C1
-:10181000E3E79DE9FFCE29D041079DE7744C62784C
-:101820009F897D65FAF9DE7173F9B97A11583F9E87
-:10183000DFA39F335125E8448767DCFDC90497F394
-:1018400000178671663FB747E7ADE1F9E096E537E7
-:1018500086918D6A8A3F5A17AB2E65B1D7784EBAFA
-:10186000399E613E67DCC60243F1FC8AF9C5651A00
-:10187000DAAB4E51AF19CF143AD722A23DC5CFB53E
-:10188000A8B01BCE11317F37DE44A74E53DCC14CCC
-:10189000A766BCCC32E1E5691B3FC7B1A55BF26925
-:1018A00070BB65D3CA36DCA7AF6DB2F2BA79A6D0E9
-:1018B000B94F2D60F1D27E74982CC6EB970878EA68
-:1018C00078C183BCEE49413921F6A55BEBEFC5FD3C
-:1018D000A54BC5BEF4EB5827ED33B89E45ECE80C9C
-:1018E000DC80217209E3DDB2833B071E86F3A8ABDF
-:1018F000E6E76458710D9827D864257E6DF1EEA156
-:101900007FEF2B34C29E743A8BFB13B1ECD9DEB857
-:101910000240E274541CFF7FE257FFB5F8555E09A0
-:101920003F8FAA252EE429CCE0E74DE03E87BC128C
-:10193000599C37218FEA003E397CDF071ACA617D46
-:10194000BF03FCACBDCC788EC2E6E903F87FC525A9
-:101950008C7F2723928E7595EF8873FBCCF8FD253D
-:101960003A0E5C0F3D399DF2EF60FFE6A2DCE3F634
-:10197000EFEC82C053D3A91E9DEF7BD6E34827FD31
-:10198000EA0FF17E09FEBB39B9B43F2788FB77E641
-:101990002758F65BE4BEEF33731DFB7FD3BCD5ED58
-:1019A000C51C1EE1385EDF1ACE60D5CFC5C0C74367
-:1019B000E55C1F86B363E34B7F0E76C6EB882FF49E
-:1019C000878670A238E330C6078E0F441F3A1E93F5
-:1019D000672AEF10DEF57AF002F524B69BD5C0DB5E
-:1019E000747EDB06496E44FD1A925FC5FDF5F3BEB9
-:1019F0002579108E7FEB3CDCBAE28C41E5E1962143
-:101A00009DE5F52FBFFED2EBFF0742E7FBCB008041
-:101A1000000000001F8B080000000000000BED7D9F
-:101A20000B7855D595F03EF79CFBC8931B08F42224
-:101A3000014F0268D4602FEF04089E9B9B272470FF
-:101A400041C0280F4F08626CD1466514289D9C90B8
-:101A5000104244C119ABAD75F4120CFE7FC7AFA69E
-:101A6000FDAD15E9E38268A9851A6DA8B1551A90F4
-:101A70005AFA8F9DC10A63EBE8386BADBDCFBDE765
-:101A8000DCDCCBCBD8A1DF4CF8F4649FFD5A7BEDB6
-:101A9000B5D65EAF7D72D4C9189B01FF1993EBB424
-:101AA00002C63AB07C19C31F8D4179E9504B390702
-:101AB0009AF6F2F65768FF1636C63156CF447FD1F4
-:101AC000FE37126F7F34302C6CA4337693A887B224
-:101AD0008E65B33F634A6E4081FE0D9259DEA9299F
-:101AE000D6F932776A30DF09A77DFC6562BC42ED2A
-:101AF000131A3F149DFF93B006E5FE38F897335E46
-:101B00002ED5FE42EDEB9859FF171DD77B5C32CBEB
-:101B1000E375EC7FC46596C7D6E1FC0FE4F2F1678C
-:101B2000978C0F1B97203C9FF7F817DAFEED592A88
-:101B300063C3011F0DDF0D7E017E5DD6B853D6A1B4
-:101B4000DF5167E86D960D64F6A0A476419F42D6FA
-:101B50002D3399C076C95360084D621D30D7AA1243
-:101B6000F8DF54C063BA83CF63F8C31AD0D9D2D98F
-:101B7000269DD68671DE6474F79B7D773C8EEB8E56
-:101B8000C26DDCB1C206B731BE4E9B15833BB81F98
-:101B9000DAC3784BEFB8CD87702ECD33D73783E6D5
-:101BA00069CB32FBF59F75DE57F79512BE9746E776
-:101BB000A9A2F64B53CDF1168471DE183E97D07E64
-:101BC000C4E01A6DC3A7BF6409E133E40D6F1E01C1
-:101BD000F809F998DF007CDED4D02CEB05163E32F4
-:101BE000822AF1912F5A0EDBF9A880F868B0E11A29
-:101BF0003D23B455837D62F9DD6A68C2E7B1EE88A2
-:101C0000F30BB8EE6D12ADDBA4A3655E0BBD7B607C
-:101C1000DDAA59BEB2AE217D30E6ED29A379DF03FE
-:101C20007CB3183F3163649D967EE1E3B5A4E7B9C8
-:101C300070BF566A921686FE9FE2CF75B1E7DBB39E
-:101C400024E217C0E7FF237C16023E33F03D233E1B
-:101C5000786672E8071AD4335577EC07B85C9A8730
-:101C600075000EAAA687F6507BB6C387F8070068F2
-:101C70009CB6D798827C06BCE577CC84B293D576A7
-:101C8000170C9CF7E11207B56F61ACB21BE09AB27A
-:101C900029B43A6469E72DE370658AE7918CFEE523
-:101CA000C361FE77A06A138CDFB20D98179EC71A26
-:101CB000A4B0044D8EE578E715427D4FAEC3BF0951
-:101CC000A6EF59EF1EBD16CA7DB9E97E84AE2F6B13
-:101CD000478617E639E697059DDE761CF9FA4846F1
-:101CE000949F0C3C5F7A245EFE9556D489FCF4A642
-:101CF000CACBDF2AFDF271A300E98D79D908C003B0
-:101D0000F6005E75A4CDF2B8010E57398813ECEBDE
-:101D100065BA0BEADD580F4B5CB079D7D7AFA7D1C6
-:101D20006B5F1E378DB15AFC5DC5FE8AD1EFA1797C
-:101D3000954F257A32E7B4D8B8AED696975A108F19
-:101D40003E9995206FF9787B1FEB6FFED481E343BA
-:101D5000399F2109EEFB14F65C1265FCF914969884
-:101D6000CE4295B908573EF377C07C0B74E789687B
-:101D70003D7F6C53A60938111E79636521FC9ADA00
-:101D8000606F37371FCA9E58794E6B7D0903BCCEF2
-:101D9000D1A0DB44C60EB5D647EA619E43856EAF3F
-:101DA000049876E528B6F67359772BE29DA9070FBC
-:101DB000C880971562BE16EF82B7719C95F95002E4
-:101DC000F88F7C359031351BF94DF63B441B8789E4
-:101DD0000F46ED9C8E6C92D37EDCEF9617CC7D9BEC
-:101DE000DE897C20A749B672C065D64FE8443E3CE8
-:101DF0001295ABE3566279F158936F323A91AFAED8
-:101E00004B33CBAE95C847EF284E4127C33B914E8D
-:101E1000DACDF18CED245FDE6066BD83EA4351F9D3
-:101E200057BE13CB4BBC021EE31F481EB668FC3CDA
-:101E3000B96A5FA4DFB888F6C09F570690DF425C9E
-:101E4000DEC5D7CFE80DB76422BD007EC6AB03F96F
-:101E50006D4340263E0A69EFCBC837A58D8033D845
-:101E6000BF60ADD43B15695C61A391EFDB9A60ED77
-:101E7000E3A1FC62914BCD40B91E2AD712C88D1F39
-:101E80000438FFCE08A467BF8BB89BCC2623DDB5F2
-:101E900035AD13FD530CDCDFFA71AE704A6EF27192
-:101EA0005E0D3A48CEF448DE45FC7C96199ECF8103
-:101EB00007C7A617B158BBA783FC5C6E9EAC550440
-:101EC00060DE79207E19EC61F3EC47432530CF8941
-:101ED00022A7DF8DEB30B4D791CF160A1ADAEED2F3
-:101EE000D87A941B456EEF2694DD72C14BEBA0AC03
-:101EF0008C027EC57225A76F1DFE7D9A87E32A316D
-:101F0000FA073816ACB3F383C22CF40DF53705325B
-:101F1000B2DFBD060A57B3AB71FDF739432B508EC4
-:101F2000B5E785EEB0CAB3A7825C8E85C57AF7CFD8
-:101F3000FE762DE2E703E6F0A3FCD89D1A2279F69F
-:101F4000BB4CC63A27E23E32D53B02F99AAF43CAB0
-:101F50005FC2B0FD6397C31246021CEB7ED3533AB7
-:101F600019DE7F83F73B792D6B64F85EE1657818A5
-:101F7000C6446C7794DADD1BC8A379D9E37E8F075A
-:101F8000691F9AE37EA7B36E273E1D693F1CAD27EC
-:101F900090D3E693AD71BE17C503F2129C84B86E60
-:101FA00089E98E4F71FD42FE039D6EC4FD01A94F6C
-:101FB000E7C88C93A76CF43629A0121CF17407FDB6
-:101FC0005AA8DF22B31F73EA167D7D43E09170F3B8
-:101FD000383A8FB652BB74388FB26DE7D17D810429
-:101FE000E7D19555DAFDFC3D2F43FF0793F4FFC77A
-:101FF00044FDA1FDC3F4DEA313BEAAA66B8F6079D6
-:10200000CA18539E4043109CD70D33CBA93737E4F1
-:1020100058E5CFD427505EDCA84BA23EFF09E4EF81
-:102020002325A6BCF9D90AAC8FCA23B6F809945F58
-:102030005179C4E6DE8CF551F9C3EA1F47F91595CD
-:102040003F2CF804CA8FC002598C77EC711CBF6D0D
-:102050009939FE15E100EA250EB33F0BE3F8C9F408
-:10206000C8DE59DD2BF09CBB295ADFFDB866B133C1
-:102070007E354B7F02CF45B66D387BC7E483BC818C
-:10208000FC6ECA01937E4CFDF0D517C3BA01ED1664
-:10209000566A11EBBE44F5CC7EAEF7C4F4CBDF73C9
-:1020A000FD7BF0F5C7D768FE024E6F9FC3F86F5BEC
-:1020B000C737F52978DF4FF427DE5F6AF61CC07753
-:1020C0009AE09BC2E1BB88FE1FD3BAFDFC9CFA2BB1
-:1020D000C09B5A62B1032E417C8EB9C4E19B5482ED
-:1020E000FB5DCDF7FB698D99727C2AC13D800ECED8
-:1020F0009BFE8B69DC52BE6ECBB89A75BE64F63A15
-:10210000B42BB3B78BF24F25C125C63D4BFF1A7BCD
-:10211000BB68FF5089853E0781CF6FB2EEEFE720A5
-:102120004756D3F8E3F8F8D7C7F0789BF5FDFFFAE8
-:10213000CDCE49E7DB899E1A393D9D87BEFD75C42A
-:10214000EF56A95BCF243F9161E2FD1B380EBCEF37
-:1021500077C1FB88D88F5D45A16FE17B2CFA2659AA
-:10216000EC1363E14E842F669FC04005D6F3FE86D4
-:102170009DD6F3FE7B2537ED34804EE4206FFFD4EF
-:10218000FE97EB70FDF165D04BFE2FED7F36E82515
-:1021900013482FF936CE7FAE7101FE6EC2C3F39C99
-:1021A0006E12D43F4BE33ECDEBDB5D5C8F7D63D99C
-:1021B00007A4C76977AA0ED4E3CC73FD27255C9FDB
-:1021C000057DA432917FE127C29F06E3FE84E6ED00
-:1021D000E6F8EF0DC919A86F46F51616213B28A69B
-:1021E00057AD223A8AE955B75279B6D8E7D74BBEF0
-:1021F0005427E07D85E341ACE7DCED7B080E1F6FE3
-:102200009FA0BE97C6CBE170B2F48327D06E257A2B
-:10221000E53FE31C505E89BFA900BF73717136E8CA
-:102220002DFB5B255586725DBBB9CF77135FC4F478
-:1022300036CE87370ABAFF53C906DAC71B4F9BFC55
-:10224000BF97DA4F89DAA91B08FE37857FE26BC199
-:102250000D267C27093E95C3F7398C7F9AF0C33849
-:102260007E6A99E144BD0CEDCA2E36707F3F167E22
-:102270001CE8F71FD4CFC3E1AAD525D2DF43AB8E2C
-:102280003991DE57F4B284FE2739E832FBCB41D2D4
-:10229000CB857DEBE77EA1F8F629C1283DA5507BD3
-:1022A0002F9FEFAB45A1B420BC9FA5BF161CC1F763
-:1022B000C983FA68A8540A77E4A27D935E560AE5BA
-:1022C000050ED64F761F639BD1EFEBFEA1C23AFC01
-:1022D000D45A552C7E1DE0D25FA11DB9586CFA026C
-:1022E00016F5AF38D05F63F1DF901DE80EDE9BFF7F
-:1022F000904A7E97975AD04FE693C9AE08DCBF2A22
-:10230000520FE5D442B7D78DF3C83964E7BAEE036C
-:10231000FB1365D4226E5F3AE01FEAD1A9EB18D90E
-:102320006FF30C29ACC23C6ECDEE7FD1379E6A2193
-:10233000FB6E15F36A59F02CB4D7BBE2ECD7E6C9B3
-:10234000BA1FF174BCBDDE81F80854713BEC78FB18
-:10235000D874E4BF783BFA78723BDA40BBB92766A1
-:10236000473BD70EA21D1D0CDAEDE8D145A132DCAA
-:102370004FA66824DFF6CF9EB190EC6543666E6889
-:10238000DFFF909289FE3E639BE24777C331A7B699
-:1023900082FC07604FCB63689B18FAB7E60BF8FB2B
-:1023A0008B4E9522FCDADD63FC48EFFDCD6EC273E7
-:1023B000FF2D59E134182FD3F8B03505EA5F0E8FA1
-:1023C00042275BD4BE8EB7C3C17C32906EFAD96807
-:1023D000D681FBA078D97A7C3666FA0D7FCCDE9E5A
-:1023E0009FEF3570BCFA701AC37D8FFC8C49EFE605
-:1023F000330A39201D2F60AA130BD733CD89F85F1C
-:10240000CC742ADF00FC268DC5F9F20DA203E03B57
-:10241000F4DF6D98ACDF46F8788CD3077B40D98920
-:10242000F18AFE6D0F66209FED4EB5FB1BCCE75A7F
-:10243000E16FF0A09D3F6150EDFCF5048F9013E734
-:1024400021579AF87E727E3D8DF6EF703A271B90E9
-:10245000CF7B841FF8812CEE3F7928C8E54AFC1316
-:10246000183E1BFB5FE83901E7E5F6A0DD8EDF8152
-:10247000E5F3382F1F2639F32C5F675B9099F2E75D
-:102480009B41AE07A899E44F01513C8DEF2FFE7C94
-:1024900024E94FE0F8DAD312ED578ACA480EB95949
-:1024A00028C289C910EB611B47D8FBED3E5BBF9B7F
-:1024B000037CFE1385FA3FE3FCC5A78042A19DBBC8
-:1024C0005A0A4BD06E7EBAF492A4C6DA1D413F542C
-:1024D00002397A54C85168167180BEB23D13F600B5
-:1024E000FDDB8A7F08CAEB379AB4A3A8C31D69AA8B
-:1024F000A4679FD248F2A3AF5D0E37C33CBF6862AA
-:102500003DA5E3078E5BBB2C70F484451ECD2F7B6D
-:10251000D2034291B5E4771E94D05FAFB955E4DFA2
-:102520009E0CEF0385C8AFAFC9AC0BE05DB2A8EA63
-:10253000E8098B7C881F17E66306B0EC1B41EEC7E9
-:102540007C31E08E5C07F0ACDA268571BC55DB8E01
-:1025500039D15FB9625D1DD3619F5C85C714DCCF43
-:10256000F28097D639BF50668605AE6F4ED37A8219
-:10257000DCBFF33AEDAF3FAA47FD12CB01A796E9C6
-:102580002D88F921CDB8C0D3C15DA48FF664319AEE
-:102590003FE463848FA096EBEAC7388BCF4B7ED3A2
-:1025A000434195E6AD6BDD49F0A4CE7A9FE001DDB5
-:1025B00039E2183A10DF261FBC26F0DE26F09E0C0A
-:1025C000CF7F0A727F9E599E5FA664209E5F5754FC
-:1025D0008A7324E3EF85A5F6FD71FB2A6DE516ED00
-:1025E0006E07D2D3F15639EC96E87918F7ED34EC52
-:1025F0001BFAE9CD717A3258ADF57C36F76756A9EA
-:102600004C7099FBB3C2E0FBB3C208105E569456FF
-:10261000B946F2B85A37D036AB2FAC6388179776E5
-:102620004C4139966CBF80DFDCA516FDF122FCE73A
-:10263000434A2D7AEDE7EDDF87F946D37C717AF6D0
-:102640005F2BBE60D2532FCAD582985C2D2BE5E755
-:1026500041FCD394AB167D92FC9A163856365C0436
-:102660001C269F209F3643D3E00EC9897C12427EF0
-:102670009D80FAD91F367F211BF98675A7C0308E41
-:1026800052CE37AE59592EA48BBAF6F7153CAF008F
-:102690009F15844F2187279632F31C9A4374D1C02B
-:1026A000E9E2BF3BAE03F02C23389771382FB5B861
-:1026B000D3ED35A146842FA4815C4A477FBC57ECFB
-:1026C0003F1BCDFDDE1716DF3CD67A37433D70C188
-:1026D0001F3354D4036F2AEAD272D584F14D55B218
-:1026E000C537EB4B488FD1182B19C9CE19DF8C8F0A
-:1026F0009F0E8C771A142F35F5EEF878677C5C9373
-:1027000025897F0E8C77BE588D7AE61CBFEC55D597
-:10271000583CD335EBDDB7D8B503E39D9FC07A04B1
-:102720003EB39965BD7DA3D5EE08C0D731D2E3EFA6
-:10273000E4CD993C2D864738073C6E98A7B50CE050
-:10274000477D39B793E2C6163CBA080F1788478A07
-:102750006F235E5AA5F026DC07A5D140795EC7BC81
-:10276000EAA3DED87E46C7CBBF47F341FD57EBD384
-:10277000990310B239FB2E5607E5D443294C063D88
-:10278000F6907A17EDF7A1F732548CF7BA7D967D63
-:1027900010B8544CF8E48176D25F611F3D7989F618
-:1027A00051ED2CC573F67CF76F5751E808CA150F29
-:1027B0009CD7CAA4D8FBBED11C9FEF5CC5C29DD2DA
-:1027C000C07D047C6B6477E6B39D846FD6C8D03F30
-:1027D000D02A31F551FF40BA70A46D341C682FAE79
-:1027E0004C273BAAA5B191F0FD1AE0DBF072FEC2C6
-:1027F00038D559F8CBA40B268D387FBA88DF778C73
-:10280000E3AFCBBEA4F735097FEEBAA07D9D3B5365
-:102810001B5236DCBACF5A56D9542BDF1A222FC599
-:10282000A07D341631D69535508FBA4CE4A5C078CA
-:1028300023B1FFA83226FC80DA282C5F7F396B4C4D
-:1028400094F7E2ACE076CC3250C1C9AF62A4B2AE2C
-:10285000296865ED787B04EE9771958A65A61E0C54
-:10286000235DD589F51FD9B2B30FDBCF074C621EAC
-:1028700004BE7558F0E32FCBA5718BD61C3BAC5230
-:10288000B5F7288EE702E18F76EA327C89E382BED3
-:102890008AF175A6E86C21C8FBE56BA5B771DC5A17
-:1028A000238DA15D1BCBAB782A2EAF8297E7E788FB
-:1028B0007AE3FB74FEC4E298FBE2CEB7373A6D715F
-:1028C0004CE3D84A7B1C93E7DB98E7D99197FE65E8
-:1028D000A5A158E398EFD3F8479799F315EEB2C73F
-:1028E000313FA1F14D3F35631F765AE3946049D1E2
-:1028F000F96AFA91FF5C36BD9EFB4DF585B83F72D3
-:10290000506A44FD080E184D227F8DB713ED69D033
-:10291000FFAFC7FABFF575821E727B9925FEF1B72E
-:1029200006FF31D3BF6F1C5AA9155CFAF002BEBF77
-:1029300045F8AEE4F8FE1B80F7BB6509E20097108E
-:102940007C2F117CD138C47F3B3C6F9459ECCFCFA6
-:102950007BBE1933B51338DFE7B08E536596FC8321
-:10296000F368FFEFD45EC44BE3EB6F2FF7723F9633
-:102970008813BF198DE365D6C7C5F528EE158B23DF
-:102980005E3E3630CE0AFFE5BBB0BD19479C5D9E6A
-:102990005B4F79D149E2981AD62BD6FE2AF5EF88FB
-:1029A0009BCF25EA17955F536FD8F07335B5EF8944
-:1029B0006B5F2BD6B7B27CD22EC3820FB038A97D05
-:1029C000542EB1E9F5F6B8E3D47A6BDC714DF9F425
-:1029D0005D66FCBF1CF1336E403EC4FF487C04CAF8
-:1029E00085BD29E2E5261D8E9EA195944FBDF4E09C
-:1029F00085FD5B526EA1FFBFC27CABCA2D79171754
-:102A0000DA3FCA8FE2DC37F32700BF77E03A6EAFD8
-:102A10005009FFF1F912A69D18EA676427CE646198
-:102A200019E31221BFCED00F1AE56B43AB277F5DB0
-:102A3000F47E44E52EFBFD88E65DA85FC4CEEFE79B
-:102A4000EAED790EE536B8B7BFFC9CB9EE96724B4D
-:102A50003EC3608FBFA6C28E976859E067E91DDF4D
-:102A60001C6DBF7F11DA45718CE8FD8B9B68DE58C9
-:102A70007EC7ADBBECF91D6BA91CDBAFA6B8FDFA98
-:102A80009A0DAE8FCB9B082E97C87B73AD9292DCCC
-:102A9000AFB891E48219D785B24D2E50F97380EB0F
-:102AA000804947824FA3700EC8CFABDB857EA6C19D
-:102AB0009EDF22175E42BA187CBCF3FB1D26DE9314
-:102AC000DDEFB85135CB5FA96F28F8ECF362FE5FFC
-:102AD00079C2FCA38B5D07BF2FE28ABF2FC2D6D776
-:102AE000DBE5CF79C3773AB1FC39BFFE9F24973F2E
-:102AF000FF89F2A725DDE1423CEB3EA68513D8C74E
-:102B0000B757F0B854943FC57D94EBB727B6A7BF2D
-:102B10005CC1FDD7A6BF3BE03AB5CA1A071D26EA3D
-:102B2000BD15D1BC016F058EBB8EC33706E521C62E
-:102B30007B98C234E0A945D78FCE41F85A7ECDC7E5
-:102B4000633EB0933362E3CD14E399F3EC5B9051B1
-:102B50006BCD6BC811F38CA9904CFFF4980AC4E7B5
-:102B600046BE0E79C81ABAE715B5AB8D87487EB553
-:102B7000394D3BFBB15D24CFA272E89B44178BDD3E
-:102B800026FD877759FDC6653FDDC5CF5528621CF8
-:102B90002FD6EF1BF564E79DA3DF6413CFAD62BFB3
-:102BA0008CE87E4D41B8CFD5DF624747A4EC981D35
-:102BB000FDCC646D16E219ECE9E2F31907F014A4F8
-:102BC0007D596BB7472CF51515B6BCA4536B30AEC9
-:102BD000992C2F6961C5D9F39216C6E86161854DBC
-:102BE000AF0F664C453FC94847C27B14BAD8D75887
-:102BF0007ED77768BFDA4CBE13E507B278FDF29F47
-:102C00003E532FE0BFB9C212BF30E32DACE06004E9
-:102C1000FD3C96FC22CD61F5FB048F3971BC15ADEE
-:102C2000D2F9F14BBB187F5B741F6FAFE0FE681DDC
-:102C3000FD8E378A498EDCDA4CE3D6AEE2F7C2E28B
-:102C4000F9E65EE1A7BA3746C7F7D2385A34DF66ED
-:102C50003DE20D5306DC9362E39BF77B02CED08FFF
-:102C600030AED366482ACA577D5D1DC51559256308
-:102C7000E3619F0223F3B6A1E830E7BBBC92EF17F4
-:102C8000FC5A8AED7C20218D9198275E4771E76977
-:102C90001ACF5B995EDD2C0F5729AFA503E72F5A9A
-:102CA000B4B305977DC3B2EFCA89F2597A309F0554
-:102CB0006132D8EBE346007F0BF8F05EC85A98E724
-:102CC000CD683E4B75D93DD67C96D067CB6731FD3C
-:102CD0007F4B4B00AF16FACBAAE478CDAAE4788DEF
-:102CE000C58119C56FAF60B573AEC2BC14BCB70562
-:102CF000AF7B0C7ECFED4C0E0B63FCBF79762AF9CF
-:102D0000F1FAB318C5556143326BA6611E09FF493C
-:102D1000195FCA30CFC50DEBC275605C3672250CE9
-:102D20002F2F1B124940CFBFC8D4993F1DFDFEC6AF
-:102D300066067413D41FA4F8DCE5ABDE6FC07957C8
-:102D4000E86E1549E0C6066F19E571ADF13BEF81FC
-:102D5000F7F37D32D3D09F5DED3CCEE3341EC2D37A
-:102D6000FC525E36F1E266CA712B5E94B8F2BAB7D5
-:102D70009AB71CB0B477455232302EF85285C80746
-:102D800012F78A989C4E7470C6E708631CAA4761C4
-:102D9000FB158C63E832C515BB5AEF3C8C7CBBC27B
-:102DA000A7F81DB0CEE03A89F2BF6EF4723C7DD830
-:102DB000646C39003A6CCAC83C8AC39CF17AC81B5F
-:102DC000DFB6AC8BFCF6402F3D0AB43FB69EE7174A
-:102DD00099F94F0B04BD98784CA9FB80F07206E37B
-:102DE000E18897C22CCA839A07F850BD14E76F4553
-:102DF0003CA5B2C6C830186789CFC122163F34AC93
-:102E0000DF9647066353DE99426F6CF5849FD4F5D5
-:102E1000419E8F26576BE89F3F53C8F715CA7EA483
-:102E20007756CAE9D4C47F6A1C9DBAE3F2C3E2E9CB
-:102E3000341EFFA711EF96FB5C5D0AF34790DE7A24
-:102E400065D22FA279570F3928EF8AB130DD63EAB6
-:102E50006243FD1D28372312C5096E107833F1CE69
-:102E600058E3E695E8E76ECCF4A3FF9F391A376381
-:102E70007ED48DE134CABFBB8975531ED472B49021
-:102E800061DE9B99D785E595CC4F4F8915D0FD9292
-:102E900025BA447CA1B348CD5580BFC865CE2C6B04
-:102EA0005E55D2BC2658F9BB9678C4D04A212F3D36
-:102EB000BA8FE779EAE2DE8F46F9415965A51E3DF2
-:102EC000C1B931BB481F5969C9BB50BC8D8CE2D315
-:102ED00045A151955363FD9F9AACE554C2F85F2C10
-:102EE000D446E37337EA79701E040F8E7F12CF83C6
-:102EF000E6C99A8AEDE3E5D5B1E4F9771AF2751FD0
-:102F0000CA2BCA232C203E1CACFCBBC99503F2EF94
-:102F1000A6565AF2EF8E3AF9BD32CA459EC906DE70
-:102F20004F5B7703D59BF7D3E2EFA5B1C7781916AE
-:102F30006474801C6F311A69DD26DEE3F1C3C4BD01
-:102F4000B4A5BE97FBA46B07216FCD0BCADDC8B338
-:102F5000D187C1EF2FD7DCD987F13A83299447D89D
-:102F600096CBEF2FCFC385E23AC6717D9055F1F332
-:102F70006A4B56A3CF0FF55B9C3C1F86E5EBECFA42
-:102F8000099671AB64332EB402F1097A1FE94BA69E
-:102F9000BE6AB6AB17E7C26A712E3C3339740BE1D7
-:102FA0003F96DFBD1AE988A547C20E336EC77F285A
-:102FB0000E64EA0F474635523E8D3BC97DEF3B2BF1
-:102FC000A3E7F99D34FE43E679AEDD85E35F37CCB8
-:102FD000BB08F9CC159459279E63F36F27B9FB1CE6
-:102FE000E68D824E335D6F0E8E80FD6EAA14F1A6C3
-:102FF000862C4417EBD1783E69A4B8D187E7DD96DB
-:103000009189EF7DBF2AD63965CC2919C7DD028A9F
-:10301000CEA689883F83F2D88CC5204BA00CE6FE53
-:10302000018CCB78500F28C27391B7F736401BD86C
-:10303000876EA12F04AE00FA41FD6BBC3D1FC97C19
-:103040009AEDE2F3AD409467E0BAE3F3DCCC7CABFD
-:103050003EC5C8F027807F7ED95A0FE56BE5ACF4FA
-:10306000E039D9A60569BCF8BCB72D396C34C21556
-:103070009FD766E64D99F952E6B8FFA7D29ED7E6EC
-:10308000F6F1730B9E9427F39D4A957F9742B3E721
-:10309000B799F935D89EF26B7218CFAFF13532EC93
-:1030A000E78632B60F89FCB3F8BC2A9043DFC57DB2
-:1030B000BF50BDA92DA6376DAE1B44BDE93CE4EF62
-:1030C000CF10DE04F2F7E7C41F31F97B08E91BE4F7
-:1030D000EF617C9AF2E5CF959B48BE6C91387D6E8E
-:1030E00081FDF85E8279FA049F6CC94A4C57A704A7
-:1030F0001D374F0EFD1AE7D5B2F9BD8F4B058F80F6
-:103100008F3F5AE537E0E35F13E1017E5A519E5845
-:10311000F24FFF9DD69324FF34BEFFC5DE1F5640FD
-:103120009EF0EF4B685215D989AAB0F751A8602BD1
-:10313000F31E6E9C1C17F5E792E3BD0E90AF000FD7
-:10314000EA0A56B93FAC8AEFEB3533F56155442FA7
-:10315000FC1EF0D600BF07CC221AE9034732F45A0E
-:10316000E45F963FE91CE746B3C8B3D51B4224FF92
-:10317000179EA3FD266A7FCD4C55F8C187D27AB63B
-:103180004ADA3752E558F95CEB4BABD2F2ABD0EFF1
-:10319000A187E83B0A5BF21DAA014BBB6FBA7E2DEB
-:1031A000BEDF92BF89F6AF03084E02793ACF71EACB
-:1031B000FE3C89F2849F9786C0D303965C02BA9E38
-:1031C00029F0033A08D5B3B7349FD5FFB1BA2AEA3C
-:1031D0006F11F6EFB79FB4E6092CFED9D3AB0CCB39
-:1031E000F9867E94EF25A08BB22ACE3FB2FB4EDB50
-:1031F000F919DFAEA28ADF0F595225E206E23C5CE4
-:10320000ECE6F6153B04F059CEDB6B6696CCC5F5C3
-:10321000039A0CC9724E9AE722D558DEBB7DFC5E3C
-:103220000AEBB58F63AEF35641A7E6BC40AF3770EB
-:103230007AD56AF169D62F9619F783F4D8F105F09B
-:103240002CE774C64E2481E7C984F0F4D9E1B9357E
-:103250004AB7DAADB83E38AF1B70DCF612A0BB043B
-:10326000F89D30B5640DD62BCC68CFCB3DAB3CBDC3
-:10327000BB2AB13CFDBB2ABB3E7B4F1597A7F75637
-:10328000911C493CEF2681B741FBAEC079EA6DF74E
-:10329000E1AF09F8A6A3FFD9B46B81D5DC6EE36E6C
-:1032A000E2CF8249E7E02FCECF378F69243BFB473F
-:1032B000423FF99193299877033CE64F940FF462CB
-:1032C00095A98F8447215E5E48A28F44DB25C9BB48
-:1032D000BF92ED48BB18BDA463D69134D24B4E7754
-:1032E000A6E1F9FFC28992847AC98F72768C4AA4CA
-:1032F00097EC49A297EC15FAEB8BBF73919E517C2A
-:1033000092EB25C52777C8A85FECABE272BBE84417
-:103310008FAC03DCC5A897C0387B845E82ED492F53
-:1033200039BD4346B88A4EF650BF6228A35E529418
-:10333000442F012864C4C3F3C51DBFC4FD8B5F6F58
-:10334000F514FD152BDD16F6F790FFC7ECD791BFEE
-:10335000294DA7FDB6D3CFEC22D596375FD8CFE95C
-:103360003DBE5D323A2B93ABDBFB615D5B59C60E14
-:10337000CAD7541A9FC0B2612894C7851FDE40BACD
-:10338000B9773EC09085ED1A9FEAC7F3C5707BF10F
-:10339000BB071FA6AEE076D05AE675CE8CC9235A7D
-:1033A0003A80669488F15C1E6F0BD8798FA4651201
-:1033B0001ED7794D7FCF8ECA3CE87FEF95E3E85E5C
-:1033C00050C98330109467F6CA546FFA870E8F6421
-:1033D00094BF0FFC3BAF06C69F2EC687F34EBB1BA8
-:1033E000DA2F2E747BD1EE2E97D3A9FD7DF9BCFD8B
-:1033F0004CE35403968BFA5D2ADE3F63F246F90EE6
-:10340000F4EBA25E02EDEFFB61A8CC03F5A9470047
-:10341000121CEF2D17F93734F887FC3BB5B79BF03A
-:103420009976C265F37BA482848B58F417575C9914
-:10343000C9CB8624924FE633DE4F913247F829AE4E
-:10344000655FFC14F4AD336C633BAED13DBEE4C5A7
-:103450005D6C607FD30FF12F53B42173601FC739A8
-:1034600075B26BF65402AE619FF63CF4D0DC6B1182
-:10347000EF3B14F2FB1EDD9046FBB4F7416527FAE3
-:103480009B8E029F72FFEEFA5B905EF76630334EC2
-:103490001441BFDDDEE87DE7E1B76896F2D8572634
-:1034A000FE0ECFC3BDC3CDF60FF3FE66D9D8760BA3
-:1034B000E675EC1DC9CB35AF3CD365101DF72B6409
-:1034C00077AF7B273D91FCCC9FCBF9CE2CCF2BBC8B
-:1034D00093D3F139FA81BC9F382741BF941A6E7F8C
-:1034E000ED5D06204D443CE9D3E6009FECE9BBAB23
-:1034F0007D024C3565D6861E92A3C3FAD72692FB71
-:103500006573F8F914290E933D06363EB787997214
-:1035100000F35BE7317512DAFDDB67BFF0F36B6137
-:103520009E5F148D9F2427E06B7D4E5EDCBA5E9318
-:1035300057A25C7AEFF8A24472606B953ED7BE1E2C
-:103540001E3F6DD9A110FEBF3CF7F49398F71E29DA
-:10355000DE41FEBD3D7F74B04D406F7B2670FD1F88
-:103560006FF0C9D98302DF43D313D01DC077732214
-:10357000F8AE9ACB689CEA295A1DD6C7C3ABA21FE6
-:103580001CE00535CB8F7224E50FFFD083FECE3DC6
-:10359000FD0E72BA9C39D129230976F4E595A2DA99
-:1035A0007A5DF5311949AAD8FBE0660C0DEB1B6575
-:1035B0001BFF4DEF4BB59597370EB39597368C8A19
-:1035C000F123C37B42636D65B7EF6A5B39C026DBCD
-:1035D000CA8BAA67DAC62BF3066DE50ADF5C5BFBD4
-:1035E0002AF57A5B796EFE525BFB1A7FBDAD3E54C5
-:1035F0003051C12B7E40975B115F69BD1AF1F9967E
-:10360000BEBBBC481791E210D9DB47327A72D09F1B
-:103610007D38C977E77E394716E73BA8462827E17A
-:103620003CDF94156B1FC8EBB7F9EB5F98C3F5D47B
-:10363000EFCF89F7D727BB27C7CFE7F3BD1F177F8A
-:103640000ECFBFEA2E924B1D8BE430DEB76AC97FE6
-:103650003DBD1FD7B388FB193A72609DE994AF4115
-:10366000FCF5E2E21B4663DC2D355F1F86F2DF3C92
-:10367000BF83F961F60ED4A77AC36C2CDE3F837248
-:10368000BDB887162CE0EFAF10EF57E313CEED7205
-:103690000BBEE2CFE38067E24B6036B0D97FF6D253
-:1036A000F7FD1615707F50E9E97029DEB79EABED86
-:1036B0003BC0AF5573F9F38BE2FF9F9DE4DCDE372F
-:1036C00067AA9D7F901FF69C587856F9FFDB26EE7F
-:1036D0007F7FAEC9C322B0BEB79ABCF4FC75938F8E
-:1036E000DEBFD6A4D2B3AD299F9E91263FD5FFB2AF
-:1036F000A9909E079A347ABEDC5449CF834D216A43
-:10370000F74A532D3D0F35E9F4FE777318D1C7A55D
-:10371000028F966FFA15422F3A24C2EB224CE59D98
-:10372000715293ADF21DF0FA5E22BC5EEC391229A3
-:10373000EE1E15E2E756423EF2CC35EF8D713D7933
-:103740009E4E323F0A9F0BFD77D931FF9D1B559A44
-:10375000A104A73477F8E0C1B957F871F666B1DA79
-:10376000EF717BAA55A2F3C63B91CBF347432524C7
-:10377000CF874F4C2CCF7307C8F33A3AB7D841F4F0
-:10378000AB62DA110AE3069C7F6A42BF883124F7F4
-:10379000AC78A078A68907CB7EE5CDBD88FD8A5F91
-:1037A000FFEC22ED2AC427DE53710E1D788E5CD10A
-:1037B000FFB186BEA9E70B38BCDB8F2F1C82FA8ACB
-:1037C0001B9D52A4AF80E25688FBCD843EF2685721
-:1037D000C3AC81E3FCB6B89BCEF5FBA27ACE3F9199
-:1037E0009E13DF0E7E0E101EF0DCB2E021811C283D
-:1037F00049B4FE32F987FD9BA0FFDE7E467E33157D
-:10380000756A80FF05857FC761EF4907E1F98C473D
-:1038100022F9E85E7FB7077DDFCF7F8DB7336A245B
-:10382000BADF90B67F8F8A7A6AA05F1F86DF232B6C
-:103830008C5439F1FBA125B326FA532C7450A2D82D
-:10384000CF49D454A3E70E39C586C6952F8BB597BB
-:1038500071FFF362E55CBA97BD1CD7B5F0542353F2
-:103860000B84FF35319ED64816BF9BC2FCEDD37347
-:1038700049EF3C7019C675C6B3307D1F02CC8390EA
-:10388000C59F20A787E8DE9E69A77F2469B7E17CF2
-:1038900003C66FD0282EC71C0E8ACB6D98ACDF896B
-:1038A0007432206EE37DF92F129C69ED0E1641FDF6
-:1038B000C2C87411FEE2F7EB8B8555F7E03CBECF32
-:1038C0006CD7EF90ACDF11B842BD8EECA933604FDE
-:1038D000E13D951685DF9F32DECA087711902C1FD7
-:1038E000F5B67BE5ABFDB8FF8FA4FD3DD947EBC036
-:1038F000DE42FB6B9B90C30FA01C86E73627B7B751
-:10390000DA9ADDDECE6CB4B7320D071C5C1FA68CD4
-:10391000093358E723426EB9D9F221A10967815FC3
-:10392000D827CEE8BEE778C9DE10E57497EEF81325
-:10393000DA7547E430FADDB64E7CAC7625E26FA24C
-:1039400087C7459588BA001534AFC1B22DF7FB651E
-:10395000A6BC8B7EDA76506630FE7BBFB89F9BE1BB
-:1039600077D8F49D2185767DED3B8304B70B251137
-:10397000DAADD9AE30E6E9A828B700EE769F83F835
-:10398000AB55E5F2A1355DF37813ECEF16C4B73B08
-:10399000F9FC726EAB17FDDE3BD21DC4BFEDAAB2BF
-:1039A0003517CAEDE90AFFEEABEAA84C94C7F2CE90
-:1039B0005C9EC7024D52284F2AB090F49D64F37468
-:1039C000887D37CBA905BA467CA6FA43B89E96F403
-:1039D0006C09F7C5ACFFF15C497C6F81FB95B70AB8
-:1039E000FD2935BF3B827E9DB691AB2723BA3CA013
-:1039F0000FBD0BEF3D05DDA43FA55FE6D213C1FB74
-:103A00007B31DE56A7BF12F1B935C3C10CC0DFD67A
-:103A1000DC2471AFB95C8F6C51278588BE011FE330
-:103A2000A581EDF68B7DDEECDCE1C3FB6C5BC72F83
-:103A3000A17CB1ADA3B97CFE4A755F577301F2CD8D
-:103A400057D89F906FB215DA3795F93D78CEB57992
-:103A5000152FFA05A664DFE30958E45C3C9F38475C
-:103A60002EACADA37C82543F22BD4C3E44DF1B698B
-:103A7000F383DCCDC57CA646AFF53B02A0777F84FF
-:103A8000F2E35C74AA32DD83F885F1898E92ED5FF2
-:103A90003C3CE92899269DA57D965E9BE83B16F95E
-:103AA000D50E1BDD38CF4137E782DF762EE6C4CE58
-:103AB00045DF21DF6A8C77DCCF78FD65D5EF75A116
-:103AC0005D1F5FFEACFCD9A2EC20B9DD32CE45F41F
-:103AD00014DF7F6B2E87E7E8CF7F4FF3A1FB01F761
-:103AE0002DCBC3FD4D0F140E4D492497CBA6E8FEF8
-:103AF0006A8B9E9355DA4DE76D4A3523BA4C57438E
-:103B0000DE71304E7AAF0C340AF8767CFCE763EA5B
-:103B1000C5E351D9D1C842305E66AF4CF4893F1F2E
-:103B2000831C1C22E4E096CBFF95615EC9F6B18A46
-:103B30009FE7B3BCE73FDB799239CBEE4FBA507FBA
-:103B4000D1FC6A91DF90C252783E51758942793C2E
-:103B50000E7ECE6AF0DF08212224B1FF2378C89FB1
-:103B6000CE49C6FD64D9CB18C9CD685E0B7E9706D9
-:103B7000C7D119E92378B116DB5DB686EB5B39ACAA
-:103B80005FC278E0E598DD2323BD73F97986E538D7
-:103B900028AF07A6C1BC14C970D0B9F8F0E547A595
-:103BA00000BC7DA068F544C447FC3A1A06ACE3ECBF
-:103BB0007830E11C6C3A35CFEF160F3F8F3538B8AF
-:103BC0005350598EF37F96C91BF9796CB8BD785E56
-:103BD000B7288DCF60197A87C85F1AE7FFFC308558
-:103BE000FB47A57B98572A22FF673EEED33A96EA19
-:103BF00047FFE41045F7607DDA3885FE5E03E8DDB7
-:103C0000D331DE12B3CBD5749E47B78EF20D7F82CF
-:103C1000E71AB4DBFFF1D9E5D1B3E738D73A7AC771
-:103C2000A5937FDD539F86F6F873BEBC4368DF9C87
-:103C3000F1F03C30B3DDFEB8EFA2B40939F76AB554
-:103C4000F0A3A77C2863FFEB7CAA82F976259E89E6
-:103C500024DF5BA4C4F18237847CBB427D95D3D939
-:103C60001AF37B666B48FEFF2643D06F83BE94FC3D
-:103C7000CA42DF639AA67AA7C5F43CF3BCF4295E76
-:103C8000E3761C47E4610D58E7FEDB187EA785F953
-:103C90002CFED93C9C7F4834FF8EF8394EBF4B86B2
-:103CA000CF0E611FB7F84A287FE30CCAAC04F113AA
-:103CB000F3097AEA4F514E4DEDB1CB97B47CBB7C02
-:103CC000697734523E987135F362BE08ABF6FBACAF
-:103CD0007A32E8AB87AAC93EB5EB9D6B6A18FFFE46
-:103CE0007696AAA09F26E809308C4B28393AC3FD66
-:103CF00070F9FC67DD8FAE6AAEA7B4E5AF0CA15DCD
-:103D0000B37DF697082F532A797EAAD90ECECBA37E
-:103D1000D516FBC6E5E3FAFA797F67C9EBB8A0EFE1
-:103D20002C75CCBA857F67C9B792BEB3F41CD02579
-:103D3000F2CBFE0C3D0DF5AF0BFDCED22D35E23BA7
-:103D40003E293C1F45E9E3F107A54FA7BC1297EFB9
-:103D500014C56FAE137928F1FE22B7BB91E26D91C5
-:103D6000E2C6A5567FB189BF2E41D7BF2DD6295FA8
-:103D700028D9DF8930DB21C6705D6EE10FDD52BCD2
-:103D800081F0BFB0328BFC518AF047B94EE9941FE5
-:103D90001C9EA267D658F0EFCE31E8BC4BFB7BC629
-:103DA000EFC17FC4EFC1A76D622578EFBDE4E349A1
-:103DB00014A72A89A4109FCD3EEDA7EF5897C94FAD
-:103DC000B7E741FDFE5E85F2F2F6CF4ECDC673ED4C
-:103DD000835EAEDFA6EDBFEAD017A15CDC5B8F3E51
-:103DE00001903B00CBD081EB987DDAF199ECCCA926
-:103DF00068675AE225E6B83F683A48F4F16C530F19
-:103E00003DF73445E8D9D1D447CF42450BE27A0A91
-:103E10007B2876C9669C807A0B1C856F417F0B3DA1
-:103E200078A7E8D36B88FF7A6CEDD2F2FB6CEDC01B
-:103E3000CE9D89F8557C1C9FAE6AFE7738E6F7B1B7
-:103E4000CD92FA3F4A5E2D473C0C82BC5A597356BC
-:103E500079C5E3A9257DE27B63A6DC12FCF8976AAD
-:103E6000957F37C9E44B115735CFE976FC15CED392
-:103E700096CC2F71F966E66F887B8CE6F7EAD7D788
-:103E80009CDC8DDFBD6B7BD3ACFF78B766A967C6C2
-:103E9000BFADC6FB28FBD0B8053DF4B7353F5E8DFE
-:103EA000FE8625B5598A06F00531009B15BB476390
-:103EB000E63BC6E3ED780DB7878EE479C90FDF06E0
-:103EC0007BD29900CF2FD708BB4DB5FF3D90D424AE
-:103ED000F7872262DC43026FED2E9EA790EC9EC80E
-:103EE000D745FB64F7447E5523E2F5E7B817F21D8A
-:103EF000D1EEFB38EF70CAAFFC27E423F3EF75FC7B
-:103F000040C013FD3B1D3E96709C2E217747CFE3AA
-:103F1000F9C92E9F46DF4583F19EA2F1C4DF5530DB
-:103F2000EB679C8CD6FF33D547FF7E824E7E22F313
-:103F30009E5ED7E1D776372BB1BC9CB6E8F71679F1
-:103F40009ED3FB02FEF8A7794F25F65DA9C3BB35CA
-:103F5000CB77A51E3FDCFBAEF8EED55EA25F713FCE
-:103F6000675B0C0F3FA6F771DF19D853F3F26EF1C0
-:103F70007DC5FD047763DCF7BBD8D1DDD6EF266CB9
-:103F80003BFCD66AD1FE20B517DFFB4A4017826E94
-:103F9000FB77E3BDD1F318EF75824F7CAF6B630DF8
-:103FA000E7A364F40CEDFBA87DF43BC6F51E3C577B
-:103FB00062DF317E83F0731EF83A46E3E8E6BC4CDC
-:103FC000E443717E31F3C94CBA90E7713ADD5C236A
-:103FD00099F796FE407858356878F880E089BB9F5D
-:103FE00074AE753C3339F411F5F345F394FF83CA8D
-:103FF0009F111EF35E593C7F0C9D2799F9D129F33F
-:10400000709E9CE8F73C53E725961317342F8C9B42
-:104010004DE3C6BE133A7CDE20AC87A9E7975FF27A
-:104020005FBC10FE351071000000000000000000B1
-:104030001F8B080000000000000B0B146060F8519B
-:104040008FC0DC687C5AE3BF4C0C0CFACC0C0C978C
-:10405000D81818DC38191844F8C833E7329ABE87E4
-:1040600040B366F130302C636560D809C4865CD8F3
-:10407000F5D90922D8C7817E5F05C497E91C06A33C
-:1040800078F0E03A11068629A208BE8118AA7CBD04
-:104090000882AD2745995D2E40FD00C5F694E2806B
-:1040A00003000000000000001F8B0800000000005B
-:1040B000000BD57D0D7854D5B5E83A3367CE9CF921
-:1040C0004B4E92012721E0991031D840074C145AE9
-:1040D0005A27116D14D4887FD17A7B07DB228ACAD4
-:1040E000D47A956BB199FC4F4280008A142D8C3F95
-:1040F00054B0FA9A2A5AACB577A2146DF55DD15A2C
-:10410000ABBDB42F566BAB551B5B29F415E5EDB574
-:10411000F63E99734E66328348DB173FBFCD3EFBB8
-:104120006FEDF5B7D75E7BED3D0A5441D569008749
-:10413000F18FA5F7F900A03E93CEFAC605CB1EACD1
-:1041400063FFF6B923DB5832EBE97995B1DA4CFD20
-:104150007A90002600343E7DF91F81D5FB2F70EA4E
-:104160006EF6E9C9C0882FC2F209C909D8CE0D0D73
-:1041700065E70459F94147A48FE5D3871C7E60FDAC
-:10418000CC04278DA383E66F9EC1BECB171483A9F1
-:104190007F7BFAF94D32A4CB009EBA05E46656AF98
-:1041A0002B70EAE5C37E80E75BD37F7DE304806804
-:1041B0007ABAACB37E76B73E43F91FB7EEFDEB1B80
-:1041C0002E801894D0388DF3DE9717B3764FB9A0B0
-:1041D0006590B56B8C4AAEC5A6F162623E4F7944DC
-:1041E000B9D620672D0FB072F6BD31787ED6F218A1
-:1041F0009B11D52B11FD1C1C76623D1D467C34CFD6
-:10420000438BB2CEF338D1CEC8D70DF3F93EF9EBDC
-:10421000030B900E69286E76637AA86A1FE27B48CA
-:1042200095740833FC0E9F4DF84D237E5917075E99
-:10423000E3F87EEA4347A48DE1BB51D5FC11960714
-:1042400099D1839537FA214A70C92C65702C10706A
-:104250005F2AD24598125D74A2CB90CAE8E2CF0FD4
-:10426000EF699B1482D798E710CEB38076065DD9AC
-:10427000577F7380B583EC7C30163F6CBC938F1CEA
-:104280004E03AFCDF386FEFA860AF47798FD7F865B
-:10429000F6D3BFBE5193C99F7670AF25CF381AD4DD
-:1042A0005318BCF84F1D53F98361A33CCCCB719CD0
-:1042B00064ABFE4135E3BF8156F8A09AF1DF9A5610
-:1042C00095F2FDAD1AE5FB5A43944FCAAC09A363BE
-:1042D000B21F5209D6BE24CAEA9BC62B9EC3DA99E6
-:1042E000E00B44344BDE5713B2D4F7E8BAA53CA92F
-:1042F0005FEF4831BAF7D63A524E09E16032722286
-:10430000C2A152CAC07D39C4E653CD9BC06A97FE94
-:10431000CB2A84E70527B4B37C911E755CC1F253A8
-:10432000424E4845D8F8452300ACBFE42D00EB5978
-:104330007FFDB34E715CC1F27D73DD9A530348B1CA
-:10434000FE936ED6CF4769BD03FB99A144B01F18F9
-:10435000907F8B7852D97F87AB00A6EACA6B8E22FA
-:104360008070827D37CFCF9D08A15C17CFB17E9F33
-:10437000AA2FB91658FDA960FA1ECED0D318D7C8F7
-:10438000DBC7B38F73FC0A5BFFB67EA7E8C30D5A89
-:104390006DA6DFE361A44DF3FF2BF71B6D94904EE8
-:1043A00011D053B38E1DDCFE157F2979E3E40C9EFA
-:1043B000FB5D5C0FDAE56D181CA43F409E005106C2
-:1043C00097AE3B527DAC9FBEB083F847EF8214EAB4
-:1043D000ADD593F7C631DF1756F476960FD7EC6953
-:1043E000916602AC9AAC11DFF53DE186F6088723B1
-:1043F000C8F8748AC1A71F0D3754211F4A1059CF1E
-:10440000CAC3FA9B6D585F7BD9ABBBE68C9D1FACD2
-:10441000E0F3A73C9BFF08FEA37E6CBF3FAB57A217
-:10442000CDC8B70948B9193CBDD5ED4D0936CE9672
-:10443000840C283F7DB70CBE82784E9EC0E1B5CF7C
-:104440007B8AAE2C46BE06F3F86CBC29D5172FC369
-:1044500079D9E130F4C59DAD1A4419BD36B7D6906F
-:104460005C6E69D506514F6CFED09915BF0B24AE1A
-:104470009FEF70353B12B8CE4E77A4B649D85F6C2B
-:10448000F3550CDED5F51367E33A70FD748EEF0F2C
-:10449000FA05BEA5D4A540F5159DEADBE47F8B1C8B
-:1044A0006D47795E1D2A8304C3EB14D7DEA6A99855
-:1044B0005F51352B8178AFBBFB35EC6FCAF4693A9D
-:1044C000E2636ACD9BFB502E377F9422B99D5AC37D
-:1044D000E49ACD73CA8A8983D58C4F2AF5D4D7A89C
-:1044E0007E8DA2A7A40C5F4E86483BD2EBF8161F28
-:1044F000A4B5FCFC39393E3E7F1E3B3DF08F91ABAD
-:104500004936B9BA23875C2D941CC42FA37255C3B6
-:10451000E48AE175C74956B9DA3C39F55631CACF54
-:104520000CCEA7763E0FD7BCD98074ED67F2531A34
-:1045300002A8700FFC5942399CC5EA4B542E7D9954
-:10454000E5FFF40BAF0E284FB59CAEF9E4CAE0E7E7
-:104550004C6A1D774B9DA3B19981FAB3AB36BEED82
-:10456000C6F16A151DE5AC4FDEF467C4B35EAFE873
-:1045700009C9244FB55C9EA6D431F9C92257F9C6A2
-:104580004FB6A6E0752647EB5A43245F6B5B7592E6
-:10459000AF5542CED660D5B92C2FE40CE6CCA67C24
-:1045A0002EFB13A08DE44ED5F702DAC1EB58DF5095
-:1045B00081DFD3D1E83C80D23A230F69075BDBD798
-:1045C0008E9643142A09DF009F41F0FE9888B2F6C8
-:1045D0005A1DCF3FDEF6C7440713C2751E5EFF09A2
-:1045E000A9A62131CFDC7E0FF56FD467F97463B5CE
-:1045F000A93FECDF028FA301EB1BFDBDDA56D19082
-:1046000060E3AF1579A5BD84E78F71FF4CDF841897
-:10461000D3439FAD9FD592E827F16C34EACF8C73DA
-:10462000BBF456346129FF4314F164947FB7EDD98C
-:104630004482D57F1F9ABF25313A4C9F1FAB605BE8
-:1046400018F036ED0534A5D6D9F09D99DF0B34BFAF
-:10465000400DCFDFDDF66114F16D943F2A05DA10CD
-:10466000DFC837FE89CCAEC27FB23157FDE4474B7D
-:104670009FC37FCF29052867E3E803CCD264B3AF9B
-:104680004E01EE3B7C35F29BA3FC0719BE63F03D67
-:1046900028B174FABCD865B81466812F6186CF182A
-:1046A0003F1FBC061CB9F9938F6FE7A3C633E73CE5
-:1046B0003F8FC99B77AF2BC2C480CD4393701D2819
-:1046C00045A0985E2BF9E8E721DC8A81CCF478607C
-:1046D0006CBFA5F32B206592FB4F9A9EDFC23CC7AF
-:1046E000DB4B66BAB2FCCB663C3E88F5EAC7F29D6E
-:1046F000313F8F989F67CCFCEE69C1F9E5C29B7D85
-:104700007E6B3D032DCD59F6119F7788FDEEE7E7CF
-:104710009C87FDB3F100F597471F213B5EC3F1D89D
-:1047200056B3F8A39FB720DFE71A4F9BC7C6AB3934
-:1047300076F8CCC7C701A6BF888FEB181FD7E6E66F
-:1047400063BB3C1BF3F68A797B73CC9BAD9421DC75
-:104750008FFDFF3AEFBFC87C5E37B03E127C5E5CD7
-:104760003EFE49F3FACB736512AEEF088F93F373F5
-:10477000281B7FBD2EE9967DAE9DAF73CDEB9FC507
-:10478000A763E7353E9E8FB51E2A54BFB6BFEC2502
-:104790003CF6D5B27D02EE0B9E3983FC157DCF9D94
-:1047A0007E1CFA1FBCC94F41B40C601AF6CFEC89CD
-:1047B0003EB42FB0FF4D7505D917FDAD30D8790245
-:1047C000C023450C0F7E9A27B5DFCCECCF14537075
-:1047D000752FEC5617637EE9432AFA95FA84BD5883
-:1047E000F7C2BDEBCE64F8F4CF289DE564ACD0E70A
-:1047F00031BEEFFCE934B4E36BD977C45B80F7C713
-:10480000BEBF80F50333F8F75C70F994540CEDFBF0
-:104810004084C165E207A3FC6107B74B77A09D7593
-:1048200022C2A993BDE5F30EC690BEDECD8A7E7787
-:1048300096FDD2FF16FA74FB8C3D092FC285F61A3D
-:104840009BF7937775575CCDDAF9EE04D2E7BE9A01
-:1048500054C2C150E7AB03DA0DEE7099E85E4970BF
-:1048600009BA2E924E67EBA4CF96DF3C5AFF8B64B9
-:10487000B74CAAE5E58FB6FF4743876C2A4F5CD952
-:1048800010ADCC943FDF7E6D03AEBBD3D5D8AFE681
-:10489000B1F1A733BDD7C1F03A5D1E70C4899EC186
-:1048A000ACFCB27D9BDA92627D6CBF6B63D557B373
-:1048B000AC238C8A4467237FD2BD56BEDE21F0B77D
-:1048C00059E0B39FA117EBFB6A07DA119F27DD0BB5
-:1048D000116738B7BECB49C73BADFA6EBA6C9DD7EE
-:1048E000B19ACFFBA0F1FDB6E89FADEB2F3AF87C73
-:1048F0001C284727311A384B8E7E3E69C413B723D4
-:104900007E93ADFF7FD47CA7FBD938C14F7E1C9F1F
-:104910006D9C5CFDDAF555A2112419F7FD151041C7
-:10492000784AE6C769FFE2F4EF0D25989E95B561D8
-:104930004A5DC1915082D97F4A482FC7D45D192959
-:10494000C7EFAB3F740A79EA6943BDBA6634DFDB6F
-:10495000867A742DE6497E5651F9FAD1FC6ACA6FFF
-:1049600098CCE5EB78E76D43A887AB503931B85662
-:104970000FBDDAF2650657D96E7F044D8D327F0484
-:10498000500F1BE56B86DE0AA968C7EDF68387F139
-:1049900043A9160573FBB5437F0BE19EC52FCAFDE6
-:1049A000C1664BF9FAA1E9E521D43FA2DC1B8A518B
-:1049B000F986A1B9E53AEA93DD7E0DBFFB2AE3341F
-:1049C000EEE94F5F43FC925CE820BD6EE031B970C8
-:1049D00036F9952F9762D39D8C1E0D4FF7AB68FF6C
-:1049E0002777D792BEA7358BFC49F2FF457E245D21
-:1049F0004AEB985F7BF353825ECE0C3DFAF1BC82AA
-:104A0000FCC0FC9C2229CE29128DE934F9678A3832
-:104A10009D184767FCCFD4FE998CBF9AF27B2DF985
-:104A200080968AE23E5E0E32FDC0DAFBA28928D271
-:104A30005DA9E479A73F9246FD71C75510F1EB4897
-:104A4000F72860FDB57379DE156CA6F6BDF53CAFB1
-:104A5000846209CC2767F1BCBB329EC6FCAAE93C44
-:104A60007F874167D861E503F813D1BD7734EF69DB
-:104A7000C7F2A4C137E06BC7F2559FE37AB6426E26
-:104A80007812F17FC7D063AF2E61FD17233FB0FED0
-:104A90008B97462C74D9AC5BE9B259E7749955CC25
-:104AA0003081749075A2C7ACE3AF776878DEF129E6
-:104AB000EE176B7CFA471EB4F7EEA8994DE55364E8
-:104AC000A7F00F707FF836E10FA862D285FB9F6DCB
-:104AD000C21FF0E46DD38AB1DD939B7F48F4FE3CA6
-:104AE0002A11D66E550D3FBF7990ADD3E8C7FF6E42
-:104AF000AB4AFEBA5DACBF18D3DB8FB6AA943ED4E6
-:104B0000AA418CF5FB3DA6C7313FC0CAD36E3A0F10
-:104B10008034FBFED84E47538AF5BBA9959966AC05
-:104B20009F8DAD2AA5B7B66A7F91597FEB5B439401
-:104B3000BFD2B1688593FC1A030B66B2793DF2626D
-:104B400035F9F7E63EE868C6F6A00D5C706E5DE6E6
-:104B5000BB819F2B1D8DB720BFFE60A7DC847A062A
-:104B6000E4F8B333B2D76BC77AA73E283753BD609A
-:104B7000FCE7E704B3D6EBC17A0FEFE270831A7952
-:104B8000B6367B7FFD08EFC9DF77F0FE42919F2F9D
-:104B9000CCDEDF3AAC37B84BE6FDF999CACE5E6F92
-:104BA000238E1BF9BE80AF12CA16661FF70EEC4F9C
-:104BB0002DE5F6CA9C28905F6CD235FA5D92896F1C
-:104BC0006EBF765072303AAB65A938D63B657E4AE7
-:104BD000AA62E97157A72407D3779396B272068F1A
-:104BE00007FB61E9EC39BCFC762C0F98CAB13D4B50
-:104BF0003F3D8F95B3F4B865D67263BC495F815170
-:104C0000BF103A5B27C5C0B05F283FCDC1F38F3BD3
-:104C10007FDB80FA699AC2EBFF19F3AC9F492DD66E
-:104C2000F6D3BC3CFF5BA37E116FEF90795E6566A7
-:104C30002CEDD336AB29B4BB6E3DBF3B74853F33FF
-:104C4000DFE0A264CD15A6F9DDBA6873E88ADACC94
-:104C50007C8217DC5983F95CEB8A477740D4B40E29
-:104C60004D1BA8257BF75F5DBF5C645A37705DA95B
-:104C7000C07581E1A782310A9633BC25B8BDCAF15F
-:104C8000B6FE2C2BDE4ACFB6E26DFDD956BC952E72
-:104C9000181F6F3F13E3E7C21F1B3F6A1EFFB68B4F
-:104CA000ACE34FB8D83AFE6D175BC79F70C9518F00
-:104CB0009F36F3CD8673ACE3979D6B1D7FC3B9D64A
-:104CC000F1CBCE3BBAF10DFAF40E7DCBBAAED735AF
-:104CD00083997EC9A1DE90655D8FF075DD285F3513
-:104CE000F45808D7770FAEEFE89FA9E1EBFBACD7FC
-:104CF000DF0FA1DF7EEDE7F6846298B2BA7B6B33FB
-:104D0000EBC6939FBBD1713FEBF7EBD31D74FE3322
-:104D1000F4B94755D4FFAB6A6693BE4F8AF3DCBE45
-:104D2000D6F4FE6B5C997905921E889AFCF7A3F67F
-:104D300012FCAE01F93059E310F652797B94D9A2F6
-:104D4000EA74D992EFADE5E5377796B727D0972289
-:104D50000F96E33AE4AB810F6A4D7832FA37C637E3
-:104D6000E0C93D3EDF1767C69F6A1B7FAA657C23AB
-:104D7000EF99C1CB13727523C27387D827DF20FF49
-:104D80008EF4CBB1836F467BB4DA0C1FCF67E0E3C0
-:104D90007903BE6FCA331B13D5FF48F84EB5E1EF58
-:104DA000541BFE4EB5E06F853CE788F067AFD76FC8
-:104DB000E3CF6510BD499E807204646FC6654D9C4B
-:104DC00007F1FEEA64215F383EFAF2AF55522784BC
-:104DD00079F922B6AE5D2E8B7D98A8DF64CB1BF6E9
-:104DE0002B2E4787C98F97DD7E5580EB6DB6AD8B37
-:104DF0006C23BD1E2179CAEC3BB81F43969BA3CD03
-:104E000059F4C146999F0F4B5AA405E194FD0AF944
-:104E10001373D51F9025615F272CE73BC530927631
-:104E2000221C21A0F8243874817EFE8CB170287277
-:104E3000730CC7716A0AA05EEB2CB95837C731ED05
-:104E400030E00945091E45E3F02872249ACD0F7C15
-:104E5000B7CCFD16463F0C42D17E84CE050CF8BA85
-:104E60003CCD2D8BD19E2F51084F9D01EBB9DE6FAC
-:104E7000C4BC9E1769A7884BB28F07188D81F14B70
-:104E800013E7901DDA31A75145BED421A2A29FACF1
-:104E9000D39F3D9EC848FBD1EE3C11F95E25FB3304
-:104EA000C9EC52CC7733BB14D34EFF434DB8EEEC74
-:104EB000473ECEE2A719D5731107A44DFB6D5F8D58
-:104EC00017D2E6FDA8D8AF7AF452CB7777A8C2D232
-:104ED000CE3551267BBED3EF48E13E3F1FFCDD02BD
-:104EE0007EA35E8F1C57B502F6CBEE9015DE63876E
-:104EF0003FDEDEE71AD4B2C1F549E1CDE02B7BFFFE
-:104F00004A991227FB596E0E99F9DFE9E27CAA94BF
-:104F1000A971B29BD55CE55EDEDECFCAD12EF63735
-:104F2000EB78FEC2449EE2C4549403137E26897635
-:104F30009D2E711E0D713A3792F4780BF2915AC979
-:104F4000E4471ADBCE48BDA27DCF875F7F85E4634F
-:104F5000824AF221E923E497B78FF3801C9DE8622F
-:104F6000E926397A1CA6AE8F9CB16C7232C1C5E5B8
-:104F7000586D6ED6557E249E15FE9345BF0306FCE4
-:104F80008938F99B0B85BFAA40F84FCEC03FD35557
-:104F90004FF07F1AD35CF0CF10F094416408F7ED26
-:104FA000C8A0D82FC0F9BAD91FBE46F45B26E003CB
-:104FB000F81AD1CD28EF157828743EF30A9CCF9AC1
-:104FC000CC7C9AC47CCE1A6F3E5F10F359E3E2EBBF
-:104FD00095DAD4AC87185F95E6A0CB12D1FFE651E5
-:104FE000BA7CED88F8EAA202E7B124338FC582AF1C
-:104FF000AE186F1E3101CF8013E6BE11443349ACA9
-:1050000037B0C84297AD065FB9F9BA0170BD852EB9
-:10501000B7897E0A9DCFF202E7B335339F6F08BA96
-:10502000AC1C6F3EA6FA6DA27EBB902BB25BB6BAEB
-:105030009E6847FBE301B9B9DB559F198FD5EB316A
-:10504000D79BD4D567D45B85DFA585A3F5FAC5F8D2
-:10505000C22EBA87F6635D686330FBE6DCAEE71B01
-:10506000D11E67EDD653FFCD7CDD64ED3698FB3F56
-:10507000B96B63BBA8773BD66B3BFD23A3FF4DE623
-:10508000FEB7BAD2061C77121C4DA3FD7DDB5C6F08
-:10509000896BB09D9F13566A6FFA4C764DA834CF3A
-:1050A000B90CD7BBAE602C398CFE4A080CA0DDD100
-:1050B0002DC7B70E233F30236F1BFB7E933B2A493E
-:1050C0006CFDD4A2F1FBB05E69C2AD39916E8DF179
-:1050D000EF613EE180668C8BBCDDF7CDAD985F2142
-:1050E000AB9A3B82F6964E47436B8232C5C97549EF
-:1050F000B104AE8B07E4D82E17D93DAC4B36CE4D5C
-:10510000653AC5FB94CC0789DB1D1CAE75BE2F2507
-:10511000110E37830BE383BB6C70B1F1685FDE3B2C
-:1051200081C7DB800C3532F6E7F446B0BFA1093702
-:1051300012BCC936B786ED9327DC48F0B2B2668A56
-:10514000CF73C509DE1E97AA613CDEEDBEEB36616A
-:10515000FCD68A4431D5273870FE53AB087E0FC485
-:10516000D38BC3A8BE06A2786ED3B550A1B8E464B1
-:10517000703DED6FFB16AAE4DFEFAB599FC076FBE5
-:10518000177A29BECEE31F008C032A5BA000C6C39A
-:105190007A82036467969EEDE5F94AA0714A3FCB97
-:1051A000E3655D30AC55B1B42CC9E38EFB6A1625BE
-:1051B00016A31D3387C7A34222FA22C6B79580F8EB
-:1051C00073560E61FFAE494E704632F42D1B186DBA
-:1051D0005F1CCB222FA3F55205D64B1756AF3429AF
-:1051E00017566FA0C07AA902EBA5793D379C5F9C4A
-:1051F000ED9C7594EFE72B647F18F16D45CCF21FA1
-:10520000B54FC2DC6E37DB2B2E5032F60AF299F323
-:10521000F271E158B1AF2DB8DB64DF04954090F630
-:105220001BA7C2A9249779DA1F684D0477BBF2CF78
-:1052300017252C6DF293E7ABBFAA95FB697395FB1D
-:10524000665E1C227D36E332915ECED359EC7B2D17
-:10525000A62D227F99C85FDE12CD325E83C2F57023
-:105260000D348F4B078F80FF4D3CAB674D6A645602
-:105270003F4B9C8E91FA6B1D36BBD1AAEF5439D1AE
-:1052800048E71C353C2ED78DC288721301D22F2ED1
-:10529000486B55B8178568D1E28919F9718526924E
-:1052A000FCFC77B913A439449F08E2D1CE2776BE1F
-:1052B000F0DBF8E268F9E4D263C427BEA4B320F9B6
-:1052C000F10D14582F5560BD7461F5FC49A9B07AF1
-:1052D0000305D64B15582FCDEBAD3A4711FED60539
-:1052E0001DE887F19DAB5AF2ABCEF55ACBCFF35BFD
-:1052F000F2FD6759DBFBCFB6B6EF3FDBDADEBF80EE
-:10530000B77FB8FBA2D3D1CF53A89CFCEE63CA49A8
-:105310008D3A7EFDD28579E44A4DD07ED223EB9042
-:105320000EE2FAC5D62989D2682A8B7DF75321FF70
-:10533000CFB9B81F272927685FFBAF3ECFEF2ADC24
-:105340006F64CC371FBC86FEFDBD53D85B76FB6B0C
-:10535000D4AF73E8F0E153508F00064B83A6B3A996
-:10536000A11F17BC110C15F1540FD0F9B4BDFF5E8D
-:1053700023BE0612A14526389E7373BFCA4FC2DDF5
-:10538000213AAF3D616308F7E9BD93A5AC7E968FE6
-:10539000147E2E5815F3919DD1A3ABA40F7B27F358
-:1053A0007B4CBDAE01F21FF786ADED55613F7CA48D
-:1053B000F0F17A6F8903DAFF5D276C6CC171DDE96A
-:1053C000FF049DC1FD1F93E3A0E3F86EBE0F70477D
-:1053D0001380EB82AA27E8FCDD0E4FD2884B868132
-:1053E000D022D3BC2F32E6C5E653C8BC5E57141A90
-:1053F0004F8B72FCE5C257FA08F1B5D4ADF07B6271
-:10540000210FE16BFF3CBE7E20219D8C8EE452D4A7
-:10541000292F99F9CDBE1E037805BF1DA6BC2E5FAE
-:105420003A2E3FAD12E7A7BDE88761EBB47EE76592
-:10543000E3F2738F58CFDDF045EAD7ADC7A3A8EFED
-:105440007CB569403BDE53ADCD767270A23051F031
-:105450001FC1DD197504291E25B299B1BC6F426FB9
-:10546000242DE51E47AD55AC727384EB5A9DDBBA13
-:10547000AEED877E72C6AE76C0D26CF7018C754DEC
-:105480000F5E3AEEFC57D9E6EFA88D0B3FE54A1EBA
-:1054900057C5742BDECB84502FD9EB3E89CD3752C4
-:1054A000F83C5F75733DA687C687636D2BF7A3AD88
-:1054B00016F4CB556F353AA031BED7BDAD03F76BAF
-:1054C00025F3B97C8CCA833C60E1DB830AF777F46F
-:1054D0007AF4368A730973BFC9987E057FDBE52DA0
-:1054E00099E39E8D21CF7F5374AE9FD401F247186C
-:1054F00072A7EBFF49FAAF7772BB8AFA21A9AF27EF
-:10550000FFF1FE6A05303ECBAE278CB44FE0E134AC
-:10551000E857F11E53DF4B4EBA176BAFE7C1CD9A78
-:10552000C9DFE7ABB1EAE57C7A66B39BE3E5E3EA82
-:10553000991F0ABA66D133B42E2FEDE97C0AE9D35C
-:105540002BE20C4B9B12B0D834DFB542CFFDBB5BD6
-:10555000AC17951C8E5E97D660A65309FBDE60D60D
-:10556000A739E8938BEE976190E0840C1CF6F9ED77
-:10557000107828C5F16BF3E3612C1D381F74BBB3A1
-:10558000F3C127359F2E81AF7C7CBC55CC67ABC067
-:10559000AB31AF7C7262F4FF30E2AB1EEBDBD603C3
-:1055A0003961A1BFD3C05B93AD9E6AAD67E047761A
-:1055B000733BC6583FF2F5FF6B85C363EF3F971C03
-:1055C000FE66540E13E4AF35C671C3E3E457D8CF7B
-:1055D000F474DF2C80623F48E837706A3CEE291093
-:1055E0006C06F3798F5D7F197A31973EB2EF67F2DF
-:1055F000D55782CAB8F69361EF948A7B5FAA881365
-:105600005E2F653FFFF9BBA01B53F405C5FB61F896
-:1056100008E2039A21B58DE244A3436D2C3F31A2E9
-:10562000E87DE81791CF18BA8BE527FCC80D7D11EE
-:1056300074C5CC1F1A62FCB62AAA366379851A1E75
-:10564000BD1F39700AFABBB83D06CE95AFE0FDE04C
-:105650008997C8807875C35C8ADFDEBF02EF8E8DC4
-:105660008567A20C30A994A5C26F40E78AB8D5BC63
-:10567000D08A4F5868CAB3FDE304D5B6BF2B70DE9D
-:10568000767872B5CB0B4F667FFA068EEF86F1D730
-:10569000B5239DDFA8BD5BE0BC686D36D50B1F74DC
-:1056A000828EF7DE0F4A941E7FD047E994831E4A0C
-:1056B000271F2C039D11ADF26009A5930E4EA2EF9A
-:1056C0001507CB292D3F3895D2D0C130A525073FEE
-:1056D00045A976703AA5EB841C161F3C99F250330D
-:1056E0009BC62F3A388BF281839FA5D47F702E2FD3
-:1056F00017E7ACEB6E8901FAB1155C87987C749D55
-:10570000B184D625FBBC6E55F9BAD22DE2D6BB6D5D
-:105710007AFB6151FEA048D709B900390E667F7A3D
-:105720004AE57A615D558CECF26E633D2C5F6259FF
-:105730000FEDF5BB73DCAF7CCC804BC003358BF237
-:10574000D0879FCBBA8331BA4F001023BD0472CCEF
-:10575000A277BB0DF8051E73F727F078C6A3C4C760
-:105760001E85C72D7BBE7067CBBDA877CEBC71E907
-:105770006E267723EED8CD2AF2FB17AE26A6BBE322
-:10578000BA9B43741FF18C8D74EF09CD72BC4FD15D
-:1057900073E6CAF8BDC4758C2E33A85D9B6A3A1FA8
-:1057A000ED5D7273CB77587F7AA7037413BF4E59A0
-:1057B000E905DDACBF0E959563FBCA1B4A2DDF2BB7
-:1057C000AEA9B0B4831AEE470F7DA5CA524F9B7F96
-:1057D00092A55ED1BCD9D676E2FCDC5FF7194B3BD3
-:1057E000B7DFC02B3F5F64F4B7AC1F3D52763A7E03
-:1057F0005D758CCB3797AAC22EF21746B75CFD1B9E
-:10580000F3CDAB978279E741F6EED7D573E7E3396D
-:10581000865B8BD1FD9523AF7F6CE751683DBBBEA6
-:105820002A427D5586FA44A2D48FFAAA0CF58887BD
-:1058300052A3DE6AC36E29504E56A3BEF19BF44DAF
-:105840003D93FB2CFC50EC195FDFCC14E535225D59
-:105850002DF8CACE37938C72D437B5F9F5CD24DB49
-:10586000B876B8EA3C421FFD93F54DEFEC8DB12FB1
-:10587000B39CE7D43B5BEE6169CFAC1B29CFF485C9
-:10588000DBC3CA7B4E5919BFC7A447E0D0CF395FED
-:105890000A7E289E63D51F46FF81884D8F18F2F03F
-:1058A00031E55AF270B9CD459FDF1FA55C1BFD7F26
-:1058B000D2722DF5AE3A22B91E5BFFD8CEA3D07AB4
-:1058C0008946489F86FB9269DE5407FAE31C031160
-:1058D0007EDF3346F13CBD3F75D17902AB41FBE23F
-:1058E0007A357A0EF24FBDDA7C1EA6D787F5E370C3
-:1058F0009D66F9F36DF90B3C132CF98B6CF94B6C2D
-:10590000F52FB5957FD15C9ED4F5E3D08F917CC601
-:1059100045E78649DDD194F53D0581A767D5E62F9A
-:1059200063FB1353271D877461F9AF527F1EDE1F7F
-:10593000CB5F49E365F257D9CA97D9CAAFB5E597A6
-:10594000DBEA7FCD9CEFFD68EAEDB8DE277EE682DC
-:105950006D59FC4BAF083DD273C2CDB1762E97374F
-:10596000935C4E5B19BF02882F00E176FA6DFB3F16
-:10597000C667667E7956E89B9F4CBE91F64D3D6C9E
-:10598000FF44F18DE8DFCB829FDF78C4FB5CFA55E2
-:10599000742F22597E3DF9397A2ADB297E61BFAE08
-:1059A000D0B96D329CBD7D6F2BF773F454663F5FA9
-:1059B000F88D276C89D7826AEE17443138ECC077AE
-:1059C00086B87EEF0A77937E55D25771FF46798C61
-:1059D000FC1BDB3C7CFD52FC71F22BB82BE359F72E
-:1059E000F53DA3F8B0FA3B7F22F06AEC234DF82096
-:1059F00039ECF2FC6937FA37929EEC72B6538CEFB1
-:105A00000A1536FED8F9F3F1EFC6CB2E28AFB67DD6
-:105A10006DD2C5E3E71393B91F4066E398FD0AF61C
-:105A2000F146E769DB67DF25F83CE9E1F1F7467FFE
-:105A30007678EE17F3B9DFA359E6256B7C9C7CFDE5
-:105A4000FF182F71A11F40B3FB21AC7AAE55D4775C
-:105A500005ADF572E127318A1F1EA765F06F3E7E06
-:105A600037C67916E1A2F385ECFB70FDD01C8AEBFA
-:105A7000D80F81813EDC37CBDA2BE817BE896D93D6
-:105A8000D09FDD2127C8BF90D041E3EFECF07389B0
-:105A90009B9C274550DFA922DE0230DE22688A5710
-:105AA000147ECEDB7DDFBC0FCB5724DC1ABE7BF22D
-:105AB00077CF543E9F432B28CEA297EDD471DC03C1
-:105AC0009E29297C4FC759DC4FF6BCD3392B9E2D1C
-:105AD000FED4EDE5727CDAA1B5A467BB997EC3F371
-:105AE000A56E39A696D6A2EB3A41F2DAAB8F1FD754
-:105AF000688F8F7469F6B8442BBE225E4EDFA458BF
-:105B00007F939E488B252ED0EBA1F2BF7BACF0F5A6
-:105B1000E8FCBE900E718A334D563A1C88B7630577
-:105B20009F31AE12E6F78F8210A338163524D3B812
-:105B30000E1FC76FAE714197DF31BF2B73ACF039C9
-:105B4000BAFEC6383FC9E0257ED2E7AB8DDB31FF18
-:105B50005327ADA7F6717EEF8D7DC66BD29BB21633
-:105B6000033A8717FD9D3581C77FCB95FC7EBA022E
-:105B7000CD4D6136FF8E4AFEFEA2ECCF132F516948
-:105B8000F757E43AAFE3E72554C444B4E10F7C5C33
-:105B9000AF882308C030059116A34A9F8A7104BAC2
-:105BA000C4EFF747241E6F3E8FE2CB839E4FBADFD0
-:105BB000CBA95F29BA0E0EFB8EA05F7998FC5C9F83
-:105BC00078BF79E0F5C09DD42F86AC1E2ECBF48B28
-:105BD000FA979C4A870E1FC6F334714605861D2E20
-:105BE0003BF87D2BA828A278C4AEE0F5AA99AE9D1B
-:105BF000DE2ACBFAAA68DD5FC3779494CA6BA2C38E
-:105C0000E3F06552C89152F995E870017E4C994DC8
-:105C10003F9B3FB45B89A5DAD05E9CE2E771AC7232
-:105C20009CCE477AA4D2D97D7526FEAD54D2089772
-:105C30003F124D609C634F992382F15932F4EFA5D6
-:105C400077D39C0B23E3C9AB5C29BF6D9ECFB7BD57
-:105C50008120C129FC871D79F8BD4BE8EB5CE52E5E
-:105C60002512CBA68707BD621DF3662F3FE06B7C34
-:105C7000D09B65DD490BFCF6943055FA69CE3EC8E1
-:105C80000772E59E57100F5D13CE1C5F3F6956FDEE
-:105C9000F4BA2FFA43EFF870FCD85B9F857EFE6064
-:105CA00061FB038803DEA775BEE414E7BBD122695C
-:105CB000229EDA1A7F11E864E5AE396E0DFDC9DE69
-:105CC000DA08DCCBF2A1D3D566790EBD1B47E7AC71
-:105CD000AE7227505C9E731E8F1BAAE17ED628FBF6
-:105CE0008FE2CBE68D1F4FE6B4E57F65A773EB2E01
-:105CF0007A3FC280DF885FB7CFEB07BEC6E1ECF822
-:105D0000286C1FB481F10BB8F15D3195D2B5AD1A95
-:105D1000A5AB5B4394AE6A65CC4EEB7F0DE56FC3DC
-:105D2000A673312E249E0CE37E2474EF2B78257409
-:105D300003E296EE19DD7306DA597D98E7F7421310
-:105D400012E627F3F2437D1BCEC0FD609FC7A89FDC
-:105D5000E4F547F37774A15DD827E26BCB56DD7B82
-:105D600006DAAD1B261BFEAFA87A91C9FEAAF1B9CF
-:105D7000B89F266CB4EFEAC27DAC4736F28F9E61C5
-:105D8000CD4314E1F1A83C7F8EEF07040FA9003644
-:105D9000DE45BE5D94DF7082D8975FB8280F1EB9CC
-:105DA0001FA3D7AB733BE842FEEE8AC2F8A68A7DFA
-:105DB000DA20DECD2DB41FDCFFD07AF752F6F532B3
-:105DC000233779D6B50B0B7BFF85A183EC0BD4C3AE
-:105DD000F8FEA2FC0B2E17C77ADC0DAE23C38B3A5C
-:105DE0002F16C5EE8B9A06D348EA9F78630D3ED6F0
-:105DF0004FF1FCBDB4AC28A134B71B0A1CBFD2279D
-:105E0000EE9BB179E3BA63E0DBB03F6E407A4EC8F7
-:105E1000F4E70A46E9DCCD23DE1B2E14EEABBC9A78
-:105E2000A51F786076F978E76DC1850E0C421AD50A
-:105E30001BA5F3BD96BC36AF540475F07C515D854F
-:105E400025EFAFADB2E45DDA4996F61F975E5FF2DB
-:105E50006A16FEBEC036AF26FB3C0BECD7B3C2A918
-:105E6000BFC1EC84B06CD8A5EBE9DEF27EC431EAA8
-:105E7000C98159748F17AA8D7B0A40712C1E3D4A27
-:105E80007CEA65FA9AECE34AABBD2A07ADF66AA84C
-:105E9000259136FAC5F86DCF0A85C61D5DAFFC9019
-:105EA000F6E0DD73A19769DF3E1555DE379E09F3F5
-:105EB0007611F3FD7C7B2A8B7333BA9B1FCE7FAEAA
-:105EC0006A1F2774E1F8716CF6FAE097F5374D72A6
-:105ED00098BB9D0C6F9ADEDDD886B49F90C17F740D
-:105EE000FB62F27FB881D9D30CCF1DA18B21C6E60E
-:105EF000D98D5518FD9298323EEF0ECDD6284E5FC3
-:105F0000E77475A85C4E6EF2E916BBCCE9E77262E5
-:105F1000D4CB47FF9B9C10CFB6AEBDEAE3FBE503B5
-:105F2000DF8CFF09F799891741C7F3DFC1D683F4E6
-:105F30000E665DFA2C27FA4FF6F92652BDBADD51EE
-:105F4000E7E9A67EEA80BF07CEFE9C66BFAAE127EE
-:105F500086432AC50DEF4CF3B8E19DE93F3F751824
-:105F6000F3CF38E8DDD19D7BC7B7B306859D65D4F7
-:105F70001B7C86EF5B0765F0958E67EF88FB71B33E
-:105F8000D2B6B844199C48FF03B7E84EB47B065B11
-:105F90005509D7FFD9629E75E9A813D7B17CF3DA0A
-:105FA00063A3AF314FBC9F88F3ECF4F3FB829D1ADF
-:105FB0009B2FF1357F4F3B17BCA3FB7F2D3B3E94BE
-:105FC000007FB74371C5B46CF3CE778FF168E1EB16
-:105FD000B2C1D7EDE7FB73C37F900F1E25E8B0E891
-:105FE000096F9D26E182128081A6696142E38BB828
-:105FF0001F2255C1583DB06FAEB404E3C617FBA3D2
-:106000005208F39F95A63038B50A27DBE3307BA909
-:10601000F6C5F4AF713E2D3EBA97D151FB01C517BD
-:10602000947C556EC375AA173B27BBA8BABB81C128
-:10603000D781FF642ABCBCBFFC4CB43B64E07A80CF
-:1060400049982E4F44BB11F031979CFA80FD498747
-:10605000DD9976B9F064B73FDDB0687CFD24CEF9F8
-:1060600013EC3FD42F25B6F6C551AB7D1BB0DDA791
-:10607000380DF5777D01F7328E721C0DD6AB187A8C
-:10608000E0AA766829AC0F5A09DE07F2CE9701E341
-:106090001BB5E048C2A1E7C77B275BC2B85CA52C53
-:1060A000E73017FAB9FF2774451DC5E1EC8F302E94
-:1060B0009885F957B2EEE3ECF72D56D5DE4D7AB25E
-:1060C00083F113C69B246A1DB47FECAD7E4833CBAD
-:1060D000D3D7C53819FA832E1BFB64BCBF5AED8891
-:1060E0007A667E7CFADBF71BF9E8EF5B688DFB399B
-:1060F00052BAB4FA41C4B18C4FFFA31DC7A0DB58FC
-:10610000F9681374FB0AE993EED091DD935955BBFE
-:106110009EE8E6ADCE1EEFDEE997AC7A56A42ADB08
-:106120005F464CFB4BE771A7B4DC05E3D0654C7CC4
-:1061300015EFC7E9E77EB4D592378243ADCEE1577C
-:106140009E1630E018E6717C73F784F0DCB8BFFE71
-:10615000CD109E6FACF930FBF9E382008F0FD7A30F
-:10616000AF92FDBFA69EFB03F10FF5CE4DFC9F50F5
-:1061700095786B13BE6BB67A9FCF62FF18EB42AE79
-:106180007929154BE9BDC403AF49F4BEBA54B1E255
-:1061900044846B68EE127A87A4BBEE493A7FE98F9C
-:1061A0008C4F1723BEB45BDC571F1D3FC779E1DF5F
-:1061B000045DAA12CBC89E5C53FE228DB3BA6EFC5E
-:1061C000719236FADB53D50131F213DBCE73F70946
-:1061D000B9DDE717E712AEE6F3A686318E2A4EFE4A
-:1061E000B10935D121D4FB170662AFF859F99AB934
-:1061F0004BCA691FA15BD7C15B73CC2714E0FD1AA2
-:1062000076D281AAF8FFB9A50E7FAF62DAAC848995
-:106210001EFD39E2DA6B03C6B99787F639DD780FD0
-:1062200080C1D75F5E18FE0D3A9F06CFA9F8CE7ADF
-:10623000778EF85E23B5AFEFF9F06EC7C31AD7308B
-:10624000C53FAD91B2CF674180E37BCD2D697E9E86
-:1062500036F74D3A4FF3A75FA5B889FFA8DF4BE7A4
-:10626000697A809FFF04FCC3144F5A3487BF0F988C
-:106270004B8E527E5E5FD6ACF5401EB69E0FF98DFA
-:10628000F39EF1FB33E00475989FF38C954B5A7F96
-:10629000EEEBDFB687DE5181349D2774FFC2496F74
-:1062A000C11A7818235749FE3B316B241EB7BC2016
-:1062B000D0DA8DFE9135C6F9DA2CBE4F92EBD2744E
-:1062C000BEE60DE8167BC71F31DE492C6C9E45B833
-:1062D00016D573B580EB2AFAE111BECE5917933F5C
-:1062E00037175D6FF2C5EA03F5667F3EDF67FDABEA
-:1062F000F1E1DFFCBA252EDDCE8F6EF8B723DAC7C9
-:10630000E5F22B1F10F269BCA36BB45F1C50B2E323
-:10631000F7D797E4C3EFE2C0846CF83DCB4BFB8822
-:1063200075E39FEF6CB2E9EF4D469C8D78D797F5FA
-:10633000577E7E167BC258570F048CF77C9ABD3867
-:106340004E55A2D68B78DA965C44F96DB78E4F4FD6
-:1063500063FC2D42AF6F15EF9018E55B055FA66CEF
-:10636000FAF66521D75B857C6D53A35E8C5F82A7AF
-:10637000CEF24E67F80B33BE4057E2F15D2325E3C2
-:106380008DAFAFB4DAFD477ABF652060F5D7167AD6
-:106390006FF368F1921271352F07D224F7CE743162
-:1063A000C9537829903C85632369DC37550D3852F1
-:1063B0003AC5AF347BA733928696CA3AC5B2897B79
-:1063C000B0278AF51D9C2B1DB87F09897BE48C853D
-:1063D0002FA338983BADBF07B24D8D342A78AEDC81
-:1063E00049118E104E9A7EAF8240B2FE1E4868DF81
-:1063F0005BF47B2A2130D50B1F3DDEFF2BF0F1EE45
-:10640000CB1E353FCA231EB33E3E5E82E66C7AFF4A
-:1064100017C21E3BFE969D12C9E5357E78DDE4A7C6
-:106420004949232588DF2D2BDB25C467A2132227AA
-:1064300064D1636F047C865ED88DEF2EB82A397DD7
-:10644000BBFEEDE2E12798CADAB2A211B2ED3F98A5
-:106450005E782340EB13D70B5B572EE2E92127F13F
-:1064600049751252F83B2AF307626D2EA4FB52FEC7
-:106470002E75A8333E84F9F03510D159FF55E8D474
-:1064800067E356B7402A4A7C042F8726E2EFDDF007
-:10649000BFC9C38B87BECDEAEF99E3D6F07755E04D
-:1064A000062BBF545C63FD7D95EA4E2BBF4CB4F1C7
-:1064B0008BBD7D581F390BE19D9A7400EEEB82175E
-:1064C000DAFA83E11DF7E17C76FB2369066F75BF7D
-:1064D000B5DCDEBF0C317711A3CB23371FEAAD61EA
-:1064E000F5EF4E3696215EB6A9C0EF5B342B74BF34
-:1064F00035D73BC463F8D6B0FB0B7CB7D858F77AD6
-:10650000F649FCDD8B29DA6B61F46BBECC7FC72EBC
-:10651000F38EC567E81D8BE320C6ED478852DA2964
-:10652000EC53EDF4CA30FA3F93BFF669782F4B2B4A
-:10653000B3FACFE4D2267A1F6CD4EE2E6576372BD1
-:106540004F9658EDCBD38B389FCE2EE2F6A1E6E3E3
-:10655000FD801A2F37BFABB4B148B296FBE3E51705
-:1065600098CAE71789F767C5BBE30D450B7A502F2B
-:10657000699358FD2CFC79A618D7288760642FBE34
-:106580000772FBA58BEACDFB8B8D45FC5C473B5E20
-:106590008C5B991DAE64988F7B9B18776391F10E8D
-:1065A0005C9CBF03A7F1D4F87E5B6089F406FB7C9A
-:1065B000C0058D18A7D231C141EF43DE34D1880721
-:1065C0001B5F4F187418C5B7C6E3902A96F27B97E5
-:1065D000B9DA6D6EE2FE41FBF7989847E7D2C681C3
-:1065E0006A36FFE86E203E710721EBF90F93EF58F2
-:1065F0005136BBAAB389F671074AB2FF4EA1917614
-:10660000D8D67D59F813C7D41374D25F0A118B778B
-:1066100086B87FEE4089234AF7026B81DE3B3B5010
-:10662000CEFD75F6F6BDB6713CB0288AEB349EB34C
-:10663000623CA3520D293CC8F10607B4B08EF101AB
-:106640007BC94FA303C3272BEF8E00D9779D216E03
-:10665000C7C8A1810607AE1FD0A499EDB10AF17B8E
-:106660008B1E7FACA3C812479220FD7BC095223DB4
-:10667000D21176C0DD59FC886B8AB89DBB595FF496
-:106680007C380BFD3614E916FBB9E220B7BF73D591
-:10669000CFD4E3708DF263284EE73EA0737EBC300A
-:1066A00010BDBD689C382EC3EF78C51CA17041BFDA
-:1066B000E47FD83CAE7AC64531E9A71DDABAE7DBFC
-:1066C0000C4F4E714ECD56E53D4FB0F2AFE0BD27B9
-:1066D00096BF6ADF0C650A2B7FB9C2898B30FB6BD2
-:1066E0002EC271DF054713CAD3BBF062D1C926BAE7
-:1066F0003D5224ECD0A48BF4A6E18FFBEA80CBA220
-:1067000057AFDC64CD2F814513D14FB1E45617D973
-:106710002657D9D6FB6D62FE5742BC1BD7CF2E1130
-:106720003F7EED0F66282837579DAC859DA6FB560A
-:106730004F087ABCCDF84737C9D9D5FE9482FBB84B
-:10674000D7779E7CF16701FB497557E0FA59923D76
-:10675000FEEFCB492B9CF9E66187DB38BFCB058781
-:10676000BC5D8AA6B2C8D9B34556BF5087CADF47B9
-:106770008A76C8E0F93CC6DF01C94F625F80DEF36C
-:106780004E34C6299E2ED1EED63A82145F477174DC
-:106790002B18C1F03DA23F08FE33E2E900E2A7E278
-:1067A0003EED5A7558417FF47239DE843FA5669CF0
-:1067B000C3B85DB1E82406BF6B57437A1258EA2587
-:1067C0000BACF78C545550BD26C738FDBD27F4E4FB
-:1067D000D30FDCA3E0FAF3EEFDAF9D8B72B8EC7142
-:1067E00027E095BCF71E08409AF60F2905E5FBEA5D
-:1067F0009DCEAC7E36F2D4323C2EFB5E80F4E2D5E8
-:106800000FB9530B59FBAB1F7D7D2630797AAF7DD5
-:1068100064CF24C4DFFD123F1F4C0CCFC4F5E96ADE
-:1068200019FE3DDB3B64BE62CE5FEF3CE66B41FA96
-:1068300049DB87BE44FD0E5EE232BFC7EE28E6EBC1
-:106840000FABC7E3257748A913B2E80F633FF4CE37
-:106850000E89C3B7CB95C250E0ABB7DFA5C4181CF7
-:10686000CBB7BF4FFC72FAF71E2C423C2CDFE5B4CD
-:10687000EC2F977DEFC3EECF303A2F73C2C842940E
-:1068800063E721CAEF8FAA234E926B1E9F721DA948
-:106890000056EFE1DF9FF93FACFCED901330B4F50B
-:1068A000EDBDBF531EC77CCC1FC75F1459BECBCAFA
-:1068B000D7CBB7BFAE205C9A03462A3F8BE79C56E6
-:1068C0003BC95E1F6044413DB57CB0F77D27E3B70F
-:1068D000E53BDFFD15F2DD729B7CBC8DFF281F6B55
-:1068E0009F9F5C6CB3CFB797151487B2ECC1FD5B6B
-:1068F000D01FF1CE437FDC82F767AFF9E82F5BBE94
-:1069000081F1603FF66828DFCBEFFF451198F4FE78
-:1069100039C55CCEDEDB71DF7736B3F9BFF7AA9BF2
-:10692000B0F5DE13BF9F82FE9FF7BEFFB789E80F69
-:10693000BAE189338E43FEBAE111FE7B36B9E040FD
-:106940007E4D997F6F519C13E9BBC81803F891489D
-:106950006DF480811105D7B3BF4A30D257C2BE0F44
-:106960007EA8A07DB6270A23889FA776BEBEE766CD
-:10697000967F97D1C79D853E6CFE931CA49F99D8A6
-:10698000B0F4BA9D179CF7B93A4C5D11EC7E398C86
-:1069900090DE1C43D797185DEB3274B597EF8743B1
-:1069A0000A9E1B2C7F80D17126D293D171E6583A72
-:1069B000BE8BFF983B968ED714DBDF6FB866EB6615
-:1069C0002CDC5996D5DE35F659D73E72D1B8F69300
-:1069D000A117F2E179A9F093CC298EAE2C46397C2F
-:1069E000E8BBDFD91CE4745EC810F3DE83FBA7E0CC
-:1069F000A31C7F708D7C09F130F2845BC3F5FDEA46
-:106A0000277E49F2F6DE232F283AC5B54091740A55
-:106A1000CBC3E8DF8BC0F2D7493C73EDBD7F3FF3BA
-:106A200057ACFDB5F853AA1AD18FF27B98FC113DF3
-:106A300052E737E9A877531368DED7A5B85C5C97AF
-:106A40001ABA10E3F9EC787F44E817335DF17DA9B9
-:106A5000EB76BE7626F25F2E7A1AF3D770FEA7B2D7
-:106A6000F27BAD729B534E057DDFBBEB8082F6411E
-:106A7000FA714573307BF83DD78842EBE3F79DDA36
-:106A8000B6C858BA67F02FE28E8E701F3E586CF36E
-:106A90007F08FCE493F3FCF33A32BC6D29D62DFC5D
-:106AA00063E0EF9D43D9F5FFB3C5DCDEBE0EE24DDA
-:106AB0001553C7AE5F323427268533F0BE8371632A
-:106AC0000CDE77EE77D23B7DDD834F911EB7EB8BEB
-:106AD000EB72D8D1FB8CF1760DCD44BDF6CE938F01
-:106AE000115F5EF7C06B0AEE57F66C7F5819AECD9A
-:106AF000C801AE0FE6DF297BE77F0DCD44FDB53C35
-:106B000047FCDF5BA2FFE53FB2F6BFFC81F72DFD3E
-:106B10002F4B0C2AF43BAF79C6795B8E5E82F37DF6
-:106B20007BAF0B703FFCF6A0B3299B9DF3DF627D2A
-:106B300034F0D41D38E595623CF72AE5EF3276B69D
-:106B4000457F89BF379C78C125F6B7D157D09EE9DC
-:106B50002851E81E4267E062F2D71BFD0DD8F0A96C
-:106B600005B506DC0768F39BEBCCFB2A03FE92A875
-:106B7000C302FFFF03C228CF4D00800000000000C9
-:106B80001F8B080000000000000BD57C0B7C54D547
-:106B9000B5F73A73CE3C42269393D7E4693C4978E3
-:106BA0004AC02109101ED58120A6986A50AA5CEB24
-:106BB000D50121444832292A5AEB779990885EF012
-:106BC000B3B1D28296B60317AA95C40E1034B6811B
-:106BD0000E606950B4019F7851A3D68A15C8180574
-:106BE0006DAFD6BBD6DAE730332783D0EFFEBEEFEA
-:106BF000F7FBC2CFDF769FB3CF3E7BAFF55FCFBD54
-:106C0000CEDC91529DAD3901DA560268A30040F105
-:106C1000E4D4A600C8AED9D59089AD6A519324803A
-:106C2000AFE9EFF2680B100498086075D6820F9FE9
-:106C3000B7AA16D01CC07F5F03CFD3DE8FCFDF256E
-:106C4000A7B4AFA179ACCDBFA43EB428B0B58287BC
-:106C50008D562AE8FE259E354500EB93FFED71BA6F
-:106C60007F77C0AEDAB16D4D59F11BEAFF4A825A07
-:106C700019C7B5D2F3D806AC0E75AB8AD7D3607EF0
-:106C8000C8195D4FBE2AF17AC6E33AA8C53F1F4C2A
-:106C9000C2F78A25412B34008E80A4CC60805AE351
-:106CA000B97F577D25EAC4685F76F681AF14E00AA4
-:106CB000D969A1FDDF9F6309DA8BA8BD36154A8724
-:106CC000D2C168EF5B590BE151E7BEDF9EE558B0DA
-:106CD0000978DD010BCE1B901CC1ADB4102F68AA42
-:106CE0001B786DA0E17F484347CCBA718097F6A12D
-:106CF000E8F7ADB82DBA698700B749C4076C93218E
-:106D00000C500270A55A0C90059002FDFA2411A8AF
-:106D10001D07302FC5E7A57D660FF749342E0BBC44
-:106D2000DC5640AD44F72DC937E5FABE617F304FE0
-:106D300039D13F5AE72FBEE25756417F450165588A
-:106D400019AD63A3FA97B1380FDDCFA051015EC72B
-:106D500084AAEBC7B6111C68F131747E78D6CC0CCE
-:106D6000C28D31AED551785442BA78E52435A91098
-:106D7000FB0A5286F87D2C85E9F4A3E93833DEFF5F
-:106D8000F1B194CD32F2E36149E0294078225C41CF
-:106D9000F3E3840F17E2670D3D37B3F9378C170B18
-:106DA000D4B656E8947413FDC41FE28DF174B7E2B3
-:106DB00050ED1EA2AD5753681E1B04D748B45E1F8A
-:106DC000D3D301EDDC0E8310B74EE8E37605D1791D
-:106DD00022F1C1C3FD54E86F1F8ECFD5A8B50D2A8F
-:106DE000EEE7C7D5E912EDCF09AA4EDF825C9FF32B
-:106DF0001BE83B0BE9EB88D2D74EF44C1E4A4F07F9
-:106E0000A84C87340F78D64CE079218CFB78780633
-:106E1000046506910A2AE2255BDF6786CE67C20F0A
-:106E2000ED2F6BBED89FF97D39D0CEE3F220C46D33
-:106E300001F4719BEE502585D7734CE7EF7BF0751D
-:106E400072743D466B2704E3FCA70B70FE22A6B6C6
-:106E50004B72D3FE8DBF5AC6E11F2AF679AB709CE8
-:106E6000E2737AEDB895FF5D31934008D68B15201B
-:106E7000BE3AFB17D4800B877B6C101E4DB307788E
-:106E80007D49A345DFD02F766454D8583F3E673DF7
-:106E9000F6D1317ACE0A31E3681DF24DA944F78765
-:106EA000E8C294A174BFFB584BE67331F36E5153A3
-:106EB00032699F3019267F2D479F87CA7480DCA1D5
-:106EC000CF7FBE3290F99C354A8736C7BF312EBD81
-:106ED00008E0A4CBB04F38CE8CE21871C97A2EB03E
-:106EE000CAAEB666320E19A7772381ECD87E9E54BF
-:106EF00018E4FD43F3E46B510F5B1C5E49C2EB0DDC
-:106F0000AA2B48F469748666B39E30E98D19F3D4D0
-:106F1000701E8E1B68060FD175FDCE6B8E135D073C
-:106F2000DCA0D9D3042EBC93484F187A043419F945
-:106F3000BB5A9AE090B06DECFAE4A5DFE1F8A41E2C
-:106F40001964BC3F807BEEA37D2BDE346262323C51
-:106F50001827DFAD0E213FC63ECDF2FACFEE133932
-:106F6000CFF3331F64D2BF0FFE3B3D3F0829ED3402
-:106F70007E8382AFA6F97BADC1AD4887E50765C6C4
-:106F8000DBF24E2908C467454BA5FE5D2FC820F0F3
-:106F9000077CFFAE5F96301E6518FBA3E9F8BC7F47
-:106FA000A3D5831A13D2BCF1F62AA37A1868313814
-:106FB0008080F7480ED26B914EAFF5C90F6DA2F5E8
-:106FC0006C6811F629AB363D6EFCE74957DBEA7079
-:106FD0007E2D17D7359570D3337235F697E5CBAA4A
-:106FE0008C2A227B7E5EBC7D6CB7BE47F2A7E13F58
-:106FF000C2B7A1BFEA487F911E92EF65FB771AE9FD
-:107000002593BC80B07F4DA8AFC238DF920DE279E6
-:1070100063BEFA9E8757E7637B5B30FEFA3250A26D
-:107020007DB6B3AED1A407EE86611EBB3414FF4A11
-:107030001AE29F40E204A7E083D343FA65F015D932
-:107040006317A4607925BA931E91FB47AD9F8EF319
-:10705000F97BAD10D4885FE2FEE0463918288ACA71
-:10706000C760EF4EA6C7925CA407E2D39E134FFF02
-:10707000242D9EFEC9A3D3BF911F291E133DE51ADF
-:10708000A63FD21B68FED4CAE2F8E7757A8FC67FA6
-:1070900082DE5E5E675DB7048F4944E7070FE46BED
-:1070A00043E9DAD4FDB08DE4FF7C7435D3715C9A8A
-:1070B000AE47743A9E869EBD3A2A6B1D6E5625BC1D
-:1070C0000F456D9F41382D40B9259C98E5DAA09F6A
-:1070D0003553F5DA70DC45340EF797E7080961F4AB
-:1070E00080F232E165A1D0BBADAA97ED91A16F937B
-:1070F000CFEAEDF7E16B6C33E7563C4038BA5D4AB6
-:107100006967BFCA24B76BC7AD60FD55B00AF531DA
-:10711000DBD5783F2DB4D2E15984EB796A25781616
-:107120008D00D8B152E5D6ECBF19F2BE11FD37BBC8
-:10713000B0CF3CAF82F85DA392FEF1A8B4CE876CCD
-:10714000C0723A500AC1CDF8FE50F83337F9A30F98
-:107150009545AEAE457FC4BF186A43D86E4DB7B0F3
-:107160007E7D365DF877D5E9366ED7D45AC08BEF81
-:1071700039D52307255CDF29D57BF072D23B3D56FC
-:107180008DFD2B35F2D2F7F87EB9BA06E9996B6915
-:107190009F40EFC5F1D5419C77A0E77DD7AD317613
-:1071A000F954F72363C80F7AD402F5A104FE5063A3
-:1071B0009A78FFA9D1EFB971DBD0E888D800F174D3
-:1071C0007F7F732DF95B77256B7CDFD635239CCFD2
-:1071D000F899CBFEF17375C3186FBB4E4090E46E07
-:1071E000B67CD355E3B03FE555C56367A1F25EBDFC
-:1071F00060120F61BEAFFBB27C03D1CF8FF45CC5D0
-:1072000017DB5F267E3DFB670548EE2A9A9F7EDFEF
-:1072100087FB3C908368A80498E40D958771D4ACF3
-:107220009EB41924DFFE63C0F23AB14F89C32DC862
-:107230000DFBF349AFBC21DCC3C96F98EE43402678
-:10724000FF7F4A7FFCF569E7C1FB5A03EF2E7013FD
-:10725000DE1F5BD90DEF935DD4ED671E6E30113DDF
-:107260000D7C3F933CF39134F6274026DC7A94C49E
-:10727000E3FF9C2E310ED67D294B84CB81087856B6
-:1072800021BD0616E5F1BE073E23870CDB2FE5EA9C
-:1072900050027FEB89341B3FFFA84DE0FED13A67D7
-:1072A000B005F7B3AF6EE9C5FDF8BE333FF05DAC96
-:1072B0007E931F8CAAC552C9FC4A25BADF3EB74D42
-:1072C000623984F65CA29B79BC212786DC18F29295
-:1072D0005B37CC174CF09ED1FAFE66D68D966C8447
-:1072E000DB3D12101F4FADC2757D83FF188055F92D
-:1072F000B41E7FF7A736B2D78E1EC91B4C30BE37DF
-:10730000CD25F0BB2AD0320DE9B562213E4B72612A
-:107310006B2F4A347F00D6E5A37308BF49D3785D4D
-:10732000A71C700BC92528EDB964B74F75577D9B15
-:10733000F4FA632887E4373C6AF5F0BA038D28B382
-:107340004416723CB15F70356C5A1313471E499B4B
-:10735000F1761AAEE3ED3495E7CDF079245AB7E72C
-:10736000ABCF5D34FFC01776E65F1EC9708CDF7649
-:10737000264DD0E78174EF1B8C97FA4C56A61E9FC2
-:10738000CBB3A81CE0D26EA4770C2EA37C0BF073B9
-:10739000E9BE00AF27BD0F03278EBFBC1AF9CB7E15
-:1073A0005D394358026552543F57380AC2F9227E6C
-:1073B0000865237DD3EB7FCCFA3A09F530B9E2D0EA
-:1073C000171F17B146C6E749F6492FB4AAC2CF6ABC
-:1073D0004B137AAEED6125D88AEFDDA8F4278DC076
-:1073E000B6C8ABCD5434D2F7A53C6FCE1DC0F26DFC
-:1073F000710425D243C9253F4F3BEB774D03D8FE9F
-:1074000095CCF437F3695CBA4117DF574497F1BD67
-:10741000917DE4BE79922083F83A5B76F2BEA79C18
-:1074200014FAC7AC6FE4F02F1F257D33A0C74F09B6
-:10743000F4CDAD645F0D7D0372E97EC2CFB417F465
-:107440003053D733187D301D261FF2B53A13E89715
-:107450004AA84D45129F57BF98F988CEFED97E01A4
-:1074600012A3BC17E528E679B33EBA283D5E1F9DFE
-:1074700086E9D9576851BC94DDEDD96F8FC187A1DA
-:1074800087A27809B29C98DF2381E36C5F2D21FDF0
-:1074900071484E25BD3303F98EF33FAFCB49DA6710
-:1074A000C16F13FFD7F55C9944B8DED15BE520B11D
-:1074B000599E236B7F46FF59D93B2F003A5C48DF2A
-:1074C00019EFB58243738E267A58980EB28AFD98CA
-:1074D000F70FB64BD5A4179169A9F3C69D5B1F2C76
-:1074E000CFB1F17B76F416A7128E9C80F12DF2AF0E
-:1074F000A247623FC18C6B338E5BF105168E1B6B0E
-:10750000D99F90A5909E77888F4B8B0253D84EDDE4
-:10751000817138F9AD83BD68B7B0DD81769EFC948A
-:1075200056E76CDEB7B15F637D77A4CCCC86D2A181
-:10753000FB375AFF1732043362FA4AC44638F67FE3
-:10754000618BBB6ED0F35C7430E83995E829FD9F00
-:10755000D3F35BE91AE3C14CD7FFE9FE0B96574220
-:10756000A2BCC0FF2FFB9F06BEDFF58B78EBB51CDE
-:1075700077549F142CAF9697201D26913FEE89EAF1
-:107580000707FE237C8DEF6E677D5389FA86FCCC5E
-:10759000FC8610EB97C939225E32EB8D4B7BE03ACB
-:1075A000D28F53C2E8975E80FEF88CFE2797F3389F
-:1075B000C174CA43FD71FEB20EBC345E838C1A7C6A
-:1075C000CFF83EC543760FFA3212E605CC76C3F00B
-:1075D0004B0D7FD43CCEF0470D7BD2A4D3E170BAE3
-:1075E0002F44EF07550D90BCA15C851EF330EC35A0
-:1075F000F2178EA4D5EEE4FBA343018E038A41A5C6
-:10760000BC0ECA2BFB61150E67581E3F543E934DAE
-:10761000721842BA509E20E0B404474843D781EE26
-:107620007680FC3E7C80DF5F9F2EF2A50538869930
-:10763000D604ECFF178C071FD9DD82326C719F7F57
-:10764000D2ED4A9F3EDE6871DD07D329FFAB40C013
-:107650005EF6CFAF9796985F46F4F1FE91E67154CF
-:107660007B79FDF92A78C88FCF57429207DF9FDEDA
-:10767000A049679348869DC6F9F26B34B697F9C363
-:10768000B14FE3C9DF49C097F7D2ADBCDE4647FF33
-:10769000011BD2C15FD35CEDB244FD74BBD5E7CD15
-:1076A000A7FC51B7F0D781F27D9C3FF648B41F6527
-:1076B000A6A08F5F15F1951354D69B153A1F2B1C6E
-:1076C000359CDF219B689F3274DF92E6E5C179F338
-:1076D000400B4C89EA5523FEC16980DE63D6AB03BB
-:1076E000BB5FBF2880F2F8D6FFFA3405F0FE3B4AB4
-:1076F0002485E871FCDE9753BC488FB7EE15F1CBBB
-:10770000CD26FFC89621F8539751FB15D1F59695D4
-:107710005F4D8AD52F707716CBC56D419982E1B345
-:10772000F2B3EC8964CE3D1BFDC650465CDF90830E
-:10773000463B3427F2AB2FCB10F1D96D1D9B6C1457
-:1077400047D765F85233F0FDC775FFEF78570AE762
-:10775000038CF52CEC9860237ABFD36387302BC859
-:107760003EABE0B3F76A691225EFC59F799D07F636
-:10777000E4DB2C38DF62092222AF05077E86FD0F8D
-:10778000726458E319BA8FC56FA936CAB72F9E0124
-:107790009100CAD5C23BA4D577E1F8853E27797020
-:1077A00043F6B920101FE72FD1FD955B1FB09AE279
-:1077B000A4E603942F5B84F3503CBBB83DFEFE600F
-:1077C000EFED077E4676A0DBC67660C979E2A7F2C8
-:1077D0000C3DEF3209267F5D42FE4AE98F4AB573C0
-:1077E000EB25C35F39BE12083CF0D7950E6E4FAC47
-:1077F00054B9FD4AD7D7CBBAF71E605C2B7D93C82E
-:10780000CEEEE87D3FF9462D6A372EDBF4E9FE9F88
-:1078100061BF9CF65944FA326C253C5EAEDB8D2587
-:10782000BA1F52FE85D96EECFDC3EF28CEC6FD6FA0
-:10783000E588EBC2FC919B40F92C960E861D31D356
-:1078400063B0B724997072BD41173D1FFB3FA5CBB4
-:10785000B99E6B9411D709F487214F5FE979874569
-:107860005BE6AECEC3F7B7EEFEB0B05FE8A5D7C01B
-:107870001DC52B2A7AC6DB1280C81AC4A7AFE7073A
-:1078800007884E07086F95D4BF88EFE754217E51D3
-:107890006E97F47CF4268C67F9CAB1E4501BCEA134
-:1078A000F8D28C4333FECC783B65ED2F24FD60C6C7
-:1078B000D92909E627DA577D8638BF58A479675356
-:1078C000BC8B666DB5CAFB11FAEFB8D27EE0872497
-:1078D000B75B248E0F1B9FE97C9AF4D1D2DFFCC4E6
-:1078E00045FAE823A5DD4DEF6BD87A9FCB4B7A495B
-:1078F00009B8E8F98F82422F99DFB747A7A3712E05
-:1079000070D62E3D10597D0FD2E30CCA33C96F5388
-:10791000D7DF56DF437186D711A1B8F3B8D23F9BAA
-:10792000D671DB0267738B87E2DBF87D2F7DFC2746
-:107930006E8DF3C7817C9D7E1CAF366DB17AC238E7
-:107940006FD32BB2875EE38708EFCFFCBC3FF4BE5A
-:107950008DF4B76A8148C1B4A1F7918D36921B7F2F
-:10796000D7DA4F6417B5825F7EA273CC3943BDAEC0
-:1079700087CD387E2A23FE3C01E9C3F9D400AE8BC3
-:10798000F2471014FAB8F5D7EBC7BF8BEB3BB1E564
-:107990000597541A7BAEB08AE93618BAF5970ECB24
-:1079A000B9F17B4AC77BD46F09F2735AB7240E83AF
-:1079B0007A44DB600DBB286E6BD864F504F072432B
-:1079C000A70C0EB25F47EDEC3734747ECAF86C90AA
-:1079D000BC1169026FC325C5F811CB3A3F984DFA27
-:1079E0007659AE0C3528524B779E16E3BD1049C22E
-:1079F000F1CBB6BF3BFB87D447BC3B12F0AB2AB4FC
-:107A0000D726E4C6C4AFD0BBB3C91F6EFDF5E7CC23
-:107A10008F8FF648905D34F4F9FA4D1FD8C89E9CBC
-:107A200040C664A4097A91DDF087E405B6D444FC2D
-:107A30000B5FFDDB0ABECFF9BFF3F1F1213A6BCB4F
-:107A400062BC3FF55B5C47FD9B764F0DBDF7A9DB44
-:107A50005D8038F8506916B8FFF97D6EB2C3F5D66F
-:107A6000805BE5565CAFFFC59D8CC72587EF748BA7
-:107A7000F8C69B2BF245815CDAE7E28DDFE57DD627
-:107A8000818FF158FF73B996F234A715A8DE9E4096
-:107A90006E26654AFAF9DAF7C7DF23CE0380E2F3F0
-:107AA0000FF5BC69E088CC7E9B1DAE4D9D1B937F7E
-:107AB0004ACA14F63800C1B7E95CD58FE695CF41C4
-:107AC0000E9F9E4DF3DC51A434D33911EE3FA0D369
-:107AD0004BFA9AF302A029317E56D5E12BB2292F19
-:107AE000668741DBBF56B05FAD91DF13F31CD3ED6A
-:107AF000C3CDF661D2A5D8BA13E74D17EBFBC0BFD3
-:107B000023108327FF131F329E00ED776A8EE83F14
-:107B100046F2B8D0D99C8A74FBEC95F76D74AE151B
-:107B2000C0FD8CA0F5F67DC07DF0646934DE98DF81
-:107B3000DF6D8F9E07925C6FF9C024D7F1F7D17E7D
-:107B4000333DFD90AA51DCF6A12D329BEC7900DF8C
-:107B50004BF50575EBEC71E78D51BC98CE1775F9B7
-:107B600034F29C4B4CFE98D19AF5C284CC78BB067B
-:107B70001BB3129E2F9AE390066BF057449F86A387
-:107B8000768E5F1A3A85FCA1431D1981F2F071C708
-:107B9000FED76EC47D7C1CB266D6F0DBE2F56DFDCF
-:107BA0000E945F1C2F23BD9358DF7ECEFE94618F11
-:107BB0003E76E2C57109E416AF27945B27B03EFB21
-:107BC0007FA567979C43CF7E2F73889F908AAF8154
-:107BD000BF3EB9EC62F22FCCF435F4AB596F9ECEB8
-:107BE000D012EA4DD0EDBC41C7A5DB4E326ECFE4DA
-:107BF0008AF3A6A62D7F633B86648DD811B74DC14D
-:107C00004FB87F1FD931EEEF9D278D4FB4EF787AB3
-:107C10009AEF5F4CBC65B989DC4C74962D2E8FC8E9
-:107C2000CFA97C9EDF4A7693F4B4A602F111664296
-:107C300088FC0EA9E78F7FA3F799E38AC04C18DD73
-:107C4000CCE7BAB036B63E27A4E8F51481C4F539BE
-:107C5000ADB6E8792EDD3FD779EE715DCE3D4E951C
-:107C6000CB11AC999A9CA8AEC45365491847ACCFC8
-:107C7000147ED608DA33B67FCAD4C4B9BA5CAB274F
-:107C80001A45BC443954D67F692E3E0FB6EAF51921
-:107C900038730E9F1F245B3E4592C0CE7573E72854
-:107CA000941F2EB7DC5E82FDE7D72D9AA3207E3C81
-:107CB000D32C3B8BB17F68DD6271FF524BB915A1AC
-:107CC000FF78A06ECE2CCA1B58DEFD29ED4F59A5BA
-:107CD00000D58F94B47DC0FD3BACE2FCAAE9D95D30
-:107CE000F5F4FE26091981F46F73859AB98E210780
-:107CF000D455943CD676FAE8FEEA5C8CE7911FFBFB
-:107D0000527DDB33C9AE38C22EAD98E24AEFFAEFAE
-:107D1000E17DE588956242DCA7C8838FDD392D8738
-:107D2000F4EEFF85F7EFCD9C78EEF79FD871D57C08
-:107D30001A3F560655C6F9CA14AD8AFA768CAF2991
-:107D40006E33F850A608BA973A6D1CCFB5A5797373
-:107D5000084F7FCA34F875616DAB55F8A572B2C093
-:107D6000819C6A69DE8EED6B3AFF5FD7E9417F94B3
-:107D70001718D89DBD99EB56205248FC95E5CD9D2E
-:107D8000448F488B029B29FFBAFBF14EC2E7EB36CA
-:107D900007E78F6E487DD07A092EB9CC51783B81A8
-:107DA000FF4DA9E34E6A7F9FE57B2F53D4878569FA
-:107DB000DE1B6F96C5BCCEE614B29FE045B91279C2
-:107DC0001AF6DFC18772456BDE8772358154417CBC
-:107DD0009D93791D726A07AFE306BB58C7FC6071BB
-:107DE0006B3FAE63823D7811C557F8FE41C2C18D2D
-:107DF000E86E119E0305D04B7C7BFD964B3789FDC9
-:107E000015B0BCB2FCF3F9FB89A7683E3FCE4FE743
-:107E1000A87EA99FFB3B15871A50857E5F1093773C
-:107E20007B16DA5F2E15F9FD568A3BA6E971B191F2
-:107E30007F33EA0D26F7FAAA9CA4B0E51E99F4CA8E
-:107E400069F4D7488F99F36E534CFA775AF7C7AC59
-:107E500097CF771E9892A5FBBD799047FB08D17903
-:107E60002039BCBA9DF4D0796002F98F390FCCCAA1
-:107E7000BA80F3C03B33455CA1519D1CEE631027D3
-:107E800026BE0D1E5A0865155C8FD00C69E7B6AB8F
-:107E90005D26FD6FE07CDC2BEAADA4CFC6BD02B74A
-:107EA000D07EAFD0CF4F068F03D7034EE877707DDB
-:107EB000A0B5D71A0C4A31F528472D5C8F32089EA1
-:107EC00020D7AF04EC6A80F5E578AE3F693BAA9F06
-:107ED000F7EAF50CE58264FF743D84B9FE61AAAB54
-:107EE000525E50C1E73320550EAD7F982ADF2493B0
-:107EF0005E8143829F67EB20E45299F6753A0C400D
-:107F000021DAA45762F88DFF4DCE0CC85CFE742CAC
-:107F1000FEFA54132ECCFCFF4E966E8F75FE9FB367
-:107F20008EE42391579B00E3B98EC46AAE2379C3D4
-:107F3000C2059BD13A92F220C9DBA41691373E5F6D
-:107F40001D8FB94EC75C8793EB8BA7537EFD2571C0
-:107F5000F72F6A2E8BEB5F7CF7D4B8F1456850633E
-:107F6000FB250FCC891B3FA2FDDAB8FEA80D37C652
-:107F70008D1F135C18777FEC134B13D6BD1838197F
-:107F8000175A1E777F7DF253EF13BEDA726595FCA8
-:107F9000F94BBBEF31D5C54C675C4C35F2F03AFF7D
-:107FA0008DBA3A2A03233A4F44FE3F56447ED3BD4E
-:107FB00055923614079E7080EDF83F8B83874C38BE
-:107FC00030E4FF7CF99B75BADF2327154AE4E77894
-:107FD000D1AF4A9A4675C4E2DC1EDE12F52A9F270D
-:107FE000FD83FD224D7279E0327AAB2A911F7457DE
-:107FF00095C67ED05DC30AF752FEA0FFFB2E8F947C
-:1080000037B42ED45C079AEEF04E012EA115759070
-:108010006DA8E8B95E77A683FD8C872C965B6A63B2
-:10802000D6DF9125F44F4796B05B3FB385B6931EDC
-:10803000501CA0B6E48AE7A9F801A8B207F9E2CA81
-:1080400000511F0647D7CC9A4EF6B37FB49646F53B
-:10805000B3D8BF082F2B41B62737B62A1CE7AD4A45
-:108060007E8AED499922ECC90459D80DB423BFCDBD
-:108070009A4876ED5EABF0B30256E24FBE0302AE15
-:1080800032B6AF7C4E9C0699D2F252AA4F3D6BB7E6
-:10809000B4AF114CFB974EB3109D0617C97C1EFC64
-:1080A000122D09D73B583F86EB9C07CFD6FF69A915
-:1080B000145F0F2E7AE4E49D1551B93C6A4B1CE71E
-:1080C0009D2FEF56BFE991143A47393A1AE2EA3345
-:1080D0008E6509BFF158962CEA13821FB8894C03AC
-:1080E0008BFF6B242DDA2FF5AD76E290FB377CBF4A
-:1080F00096F862EB9A1BA0BCA691C73F1B07F6CC73
-:10810000E0FA6D235EBAE17591D7BBE1BFE2F3D629
-:1081100027B3AC7CFF24BD8FFC9A5EDF44E2DB35E5
-:1081200024109C57F64D24FFA056058DECFE7CDFF5
-:10813000823B0F617FEE8312FBFB749FC65F5B8007
-:10814000F606EFBF0C9E5777E1FAFE9E25D6330F59
-:108150006AADB4CED76E6E4C213CBD9E26C6472478
-:10816000D036C7CC778D3EDFEB372FDB45713ABD7C
-:108170008FDE4FEBA1F7CF55A198FAAF81EFE4ABBB
-:108180004543DF7B1D78AD7ABD9795EC6409043BD0
-:108190009F26BD7AD0E25903DC8633D82ED9D92E5A
-:1081A0000DB4449E5A81EB7C67E9DF764948D7B726
-:1081B00017447EF5345EFF970D3268888B4FD37D70
-:1081C000567756944E47177D9A42F4447F65EB4F9D
-:1081D00049EEB6D93D54D7F1E6D26D2363FDFA548A
-:1081E000F78C616EF2AB2A2FEC3CADEAC9298CBF4B
-:1081F000E55B05FE96FF7A5436E16C79CA59DC8955
-:10820000FED6123E279D2441C2F878CF4AF1DDC246
-:108210000EC4998638DBF385A82BDF7928BD9CD660
-:10822000A780EFE2D8FDEC7CE9C6B15CCFFB46E667
-:1082300005AD93643680FAF7065695002FEA723240
-:10824000BF27A35CF727C7D2FC37FEEED727FF93E3
-:10825000E8B27BDBD61FB28C5C181D86D6D1AADBB8
-:10826000583F197118D5BD529CB6DFC276F20AF993
-:108270005E8EC3A84E83E3AE61853C1E158E6A15E3
-:10828000FA4D7C27817E70AB87EB3D595EEF5685BA
-:10829000DF62C449B2C593A3888F0C5E98C6F317FA
-:1082A00003E5C75C145819FA0AFD08976CD1F51557
-:1082B000781D189F8ED5F559B57BC2556DE2BC2649
-:1082C000CEFFC47E554702BFB316FFB1DFB9D1D789
-:1082D0009AC47669A35C4A7E87D711263B6EF63B2B
-:1082E000A7C1839C0718E27F3EF7D70BF23FFFD56B
-:1082F0001DEF7F5EA8DDA9776BE2BC77B4D073A1D8
-:10830000F0308E73F0AF9CE46B64B6B04B7D1463B9
-:10831000519D9F746AB403E5B3C15DBEF6019449F3
-:10832000C770411FEAB7E2FF97689FEEFF9AFCC053
-:108330003E85F937F8DC25DFF81D4905CA2119FB10
-:10834000F081A95CEF3CD02BE4A3335DFBD3348AEE
-:1083500033D0CFDC8C4B4C52FA6D6909F6F334E91B
-:108360005F9207B7B0478E6E712EEAD0BC40FA25F7
-:1083700049552750606E8CAF730BFBD578E0CD422A
-:108380001BF2E7A4E5908BCE571A76ED70E176E10B
-:10839000BE0CDFFD84EF65478F4C52B9CE6D532183
-:1083A000C5DFA1F09199EC9F552369279C7B3FFE87
-:1083B0000DE5F41102346DC8E0760CE555F0923FFE
-:1083C0002CF679AABB353D517EC0FFFBB7F6D17EB6
-:1083D000B7BD98C47ECBB6AC3E9683C05C80AD483A
-:1083E000EF27BF18CBF32127781D97D46A12D9FB4A
-:1083F0005FEAFBD9A6C797A7BE90799C31EFB8EE8C
-:1084000019B28AB82A0DB7EFE33AAE1EBB46FC4D4F
-:10841000DA02823E3D495C17E6DF73A5883BD3C490
-:108420007974E7B0C8DBF49EC86EBB4675AA496A8A
-:108430003BA4E3FC9D366167C720F07738A3D78D56
-:10844000F725F5ACE78F2010175C8F97A4B4C3B75E
-:108450009CB1F44FE1F586DD02579DC3C21627D9C2
-:10846000098C9536F3BAA2EB047EAFB1CE31EC178E
-:1084700077DA227FA17C3BAE4B255C8C01B14EE8C4
-:1084800019A591BF92A48A73F52455F304A4A1EB16
-:10849000F28F87203A07F0D02A382BE75C47382C38
-:1084A000DA77A02C7416EB7E4C60F1DA5905317D39
-:1084B000526495D1E75F75D7AF6D2BA07D093BA8BE
-:1084C00028213E1F77CD0795CEBF93142FC749496A
-:1084D000F3406B417E253BBC7CDF8D73B44CE17E69
-:1084E00098D6AFD27DCACBA4AAC97370DDA95FA606
-:1084F000F2734D7D56AE3B6FF8C775A9A5B8BF1393
-:10850000967D2B3AB0FD784168249DD356A6FADEBD
-:1085100021BC3E736CE1DA7138FEAF9D564F0DE918
-:10852000A5FEC08FE9DC7EE993568DECE2FD6F0C71
-:1085300086BF26FE3E2BB15E1CB08AFBD8D75AF010
-:108540007E53CF87363AD7BAB2FB5D1BE5BFEFC982
-:10855000F61D27FB56D9DD5245749B02EDAD94E71D
-:10856000447DC8F512A11CA12F065F19B9B9258653
-:10857000CEAE6CFDDC2BE2BB98E4A64797CF3DE482
-:108580001F61BB4BF7D376EDFD97122DE6FC34004F
-:10859000FB381FB80A9EE3BA4EE3FA4050A9261CE6
-:1085A0008D7DCD718B3706678E6C5DDEF5F7FD3CFA
-:1085B000DBF70F96DBBDEFD95CB87FFF9F43856487
-:1085C000AF42E8CF7D531DA9DF242F67EB8E8E03CA
-:1085D000EB916DAF75B3FFBDED1E358DE41ED70F6A
-:1085E000A9D8DF85FE05C9D1AE2221772DAF9E190E
-:1085F0004FF9E233BB975D4CF48AB8AD06BE670E07
-:108600002339DA0EACC70C392C2539C4A597AA2218
-:10861000DF534AF826B9B3F5CD61B9DB6501923B6A
-:10862000C437E31DF1AD921F52AA22DEF9F9512C95
-:10863000C79D7D472EE17A7624EF8809D4B730BEF6
-:108640003AC37382123E5F610DEFA3E72BF0FD2D5D
-:108650005A542E2BA4F8BA9E3AB7A89335F4E3EDFA
-:108660006EA1EF43A3B5540F8E4F96E538FCC7D8E3
-:1086700049D1D7EDE80FD6FF74ED3A9487126FB960
-:108680006512F93B2FCA6C07F6E87EF2F23F4CBD4B
-:10869000A6435C67FB19D671B14FF79B9F5B99C3EB
-:1086A0007DB20B1AF26522B6DE72AAF76EAEA25444
-:1086B0005C6575FB7E6AA7D686AAE8B870FAFCBE30
-:1086C000FDE21B37EF58C25BD7BE6F8FE53AE9A3D7
-:1086D00076A0EF38BBFE1E79FB49DCFF8A3D486F70
-:1086E00048E89730DED06233FECE859301A9FFEAD9
-:1086F00069A897AF59FFF8550A1AF4260202EEBF8F
-:1087000066FDD6B5E8BAC0ABD9DE6BB291DF5FE5E6
-:10871000F8AEC946BA0D1CFEBB9BECC9AE57DE7362
-:10872000911DEEB279C712AEBA8A318E4880C7E980
-:10873000D9A26EA7E21CF526CBB3C5F9D6C800AC0A
-:1087400025BC3475C96A90ECB4B7EF6AB21B7F419F
-:1087500052525EBB6E46C045F152FDAEFD5CA76F46
-:10876000C4D38B41FF936F9A4DF43F9D23E2E3BA4C
-:1087700075D6B8F87614846D748EECF7399BC3C83F
-:10878000927A93DF715BF726FE6E64E996F8E71A3A
-:10879000C84F4108359C273E5E9EADFB29255042BF
-:1087A0007E0AE286F324915765CF66E0FAAA5EAAB4
-:1087B000AFDA6611744A76405B6A7AD45F1993EB3C
-:1087C0005D4272BE44C767A75EAF14E994F87B8A26
-:1087D000314F887879EA716D137F2715F0729D5EAD
-:1087E0003D2D00D73D5509F0FEA7E6944000F75F08
-:1087F00089EA99E4A5AE470A323DF5EF5E14FC27FD
-:10880000F2451B65FECE6FA3041945346F84E9B3AE
-:1088100054CF1F2E7B22FEFCA261C3E103E42A3564
-:10882000864CE7413A7DCCE73B3BE87F129CEFACBE
-:10883000CFD6F308855018F75D5EEF857D97F7B1C9
-:10884000FEBDEA117D7E63DC2E5D6F36E9FB6E08AE
-:10885000CA62DFC80AAA8FBE5587891F3C4CA7464B
-:10886000C409E1001E14FC36EA199742AD8DEAC82E
-:108870001ABB5A0ED0F95B9DEED79AF18404657A43
-:108880002DD1EB86EA37C6DF5FAAD365A9892E4DC5
-:108890003EC9B43EE1775FE8FA50735D4F3858DA6D
-:1088A00061E57AEED37013D75F35766DE2F5D4E9E2
-:1088B000FC1BBADE00EF6709EE87E4E942D76BE6FE
-:1088C000DF9F0C9C5F0297C4F1AF3AE382F8570236
-:1088D000EA32DADF60AF886B077B8B392F61E0C546
-:1088E000FCFC6CDD8FBE7283F0374F765725933FCB
-:1088F000307048F14888FBF2173F73D1F73765BBFA
-:1089000065A073D2819EF2B501D4973B7B875FA7A8
-:10891000A11D287B5161BB51FE625930A988FA65BF
-:10892000C9255C67A265501C80F3B01D1E3834FC5D
-:10893000E552F6D367555088DA72A82C99FC859DCC
-:1089400020F21BD28B1519FD3176E5C36C91DF58EF
-:108950009DF3FE43A4A7AEDC6EE57CF095D6C84B34
-:108960001487EDEC553C2DD86F7871E1AA24E2F71D
-:10897000AF250FB9DD07FA9667D2794D638F55B5EC
-:10898000F37AEFDC47F7031D9267048EF7EFBE62C0
-:108990006C27E58936957B88BCC6FBCAD2B447A84C
-:1089A000DE157293396EBFF2222BDBD71379C9FF24
-:1089B0005183FB5AEADD349BF4F089DFEEE4BA8A96
-:1089C000814E097224CA23EF7F8AEA7D4E3C7DD80E
-:1089D00046E7C1555D87B96EE35CF6E0641071C788
-:1089E000717BBB8DE29BC64D46BF9FBF47A9D5FD9E
-:1089F000A8A62DEF727F29C50184C78D7250C3FFD1
-:108A0000DDBFFB193E1F6EEA10751F67EF6F91F80F
-:108A1000BE81F785BADE5A061AE37D998177BD3E9D
-:108A2000CAC0FB69A8E13AAD651D0F33BE17EBF86C
-:108A300036D74D0134DB4A3385BC52BECDFCFDDF59
-:108A40006D3ABE6F3B0FBEC7E6E8F81E036308DF52
-:108A50006766887ABA33878725D3FC670E72F6F586
-:108A60009B70CE76F790EE170C862D5EDBA5D1714C
-:108A7000A7BA3FE5EF10FD87066D547732BBE713C9
-:108A8000E6474DCFDE5944EFEF80AF81E8F79D9E7A
-:108A90006495FCE09A7EA1CFE6F4D8F97CE23B1025
-:108AA0006A233E0FEC79BC2D9D70F32B811B43CFC5
-:108AB0002DD1E97A55E9F76753FCBE54B78783BDDA
-:108AC000B7CF66BD33018AC8DF9BA37FE73D27A4EC
-:108AD000EBA18DF174A7736AE25B538F9DEB4DAEF2
-:108AE000827E1BD9B3AB74FB69B69303B9C9CCE7DB
-:108AF00000DAAB1138BEA1C35447A9F4F37A06BB20
-:108B00006D7CDED564B2BF97E508BFF27CF1BD99FC
-:108B10005F0B72747BA2F3AB2622EA18E6BC227BC1
-:108B2000E8FCA137BCAA94FC05836E667EF56A2535
-:108B3000A9DFF47B092FE97EBED1BF46FFFE2DA43D
-:108B4000B63B63E3F6833916FD9C33F8D372DCE75A
-:108B50001D12F4110E31BEB9A64C4A18DFDC938306
-:108B6000FAE38F05B73E382136BEF16E1A49FEDEB4
-:108B7000FDA857CA2BB87EA78FCF0B95F61A3A07D8
-:108B8000F377583D14D7F8BB65F607FC1DF6A00532
-:108B9000E7BD927084EBAAED91AE201C61DCB09A27
-:108BA000E69F4B29651C37B71BFD117C6EEEAC4F61
-:108BB000187F07878B7D0F2A5A76A238C2881F9AA2
-:108BC000BE10FEAA71BD09F5008D6FD2BF4BEBDA66
-:108BD000F7B7C2A2143AB7FDBC7001B64FE7083B25
-:108BE0006CF8AB11F4578B757F85EA2EEA04EBA085
-:108BF000EEB97B6CA4BF0ED00F5B50FDA4EA5B4DB9
-:108C0000F1B0EA83E61F91A321B5B11C35914C1157
-:108C10000E7749227FF3AC956A43A0E5C830AE0BCE
-:108C20003CF59A388732CBFBA9857DAC2FCE2C70D2
-:108C30003613DE96956E5A9D4EF2BDE775D63763B4
-:108C40007F6B532D6A745F2DF4DD1DC7696D71FE56
-:108C5000F2A9EE561BE7A163BF1B2E1EEA1F359E2D
-:108C6000278F75D0A45770FDECEF0E1C9455CA0BDE
-:108C7000211D7F91174B2FDD1FEADA97C4F66BE0B9
-:108C8000B033487EFF5F753C9ED0F3F22D9532D312
-:108C9000C33245B463F73C534CFC257EF850DF6F7C
-:108CA000DBF3CC255ECEA307451DF113F175D88DFE
-:108CB000A1F83A6B83AE7E9DAEB8AE91F4BDB2B171
-:108CC000AE5D4ABFCB93408E24691FF3CB22C5C74C
-:108CD000B9FE67E5DAD83A52DCCF2DA4F7FED3907F
-:108CE0001725E2263BFC4E8EC6EB6BE911FCB5EC7A
-:108CF000162DBEFF7A91AFB1F2FB87DC9F1968A0F9
-:108D0000FB678A92B9BE01BE08D4507F45B1F8FD19
-:108D1000801547968E8ACDD38124E271BF35C2F586
-:108D20007EFEC3165E9FFFF0A07BB893F4E2A659C7
-:108D300054477B95AE2F0E1427D713CE03F4DEECE9
-:108D4000E83C4B72C47903D07E73A2DF571AFB5DF7
-:108D500005D7321D56E9B87A4B8F73308EFA222729
-:108D6000411C752EFFF7ECBA75FFE9CC0CEDE5EF71
-:108D7000210ECA0E2A018AD777BE911424FBDFB2D6
-:108D80007BC93B140FFBDFB403F9212BF62C19C56B
-:108D900075F83EDFA5A44FCEECB9ED52AE6394C496
-:108DA000F7A5015A5F0EF953AFBAC94F6ADCFD2A25
-:108DB000D73936EE9AF808F94FE82F5D45D7D18FAD
-:108DC00061FC95BD58C1F8DB79A822A384160E9EDC
-:108DD000649AB7F1A0C2758F8D072B5EA821BFE6FC
-:108DE000C599EC3F19FE5239C5E3E43F1D1C1EE74F
-:108DF0003FA5E60AFA0DEC4DE2FC8704C5023F30C0
-:108E00003C0E3F0D5D7F603FA301F55D2C8E8CE72E
-:108E10004A72159E6754AE8E9F90E4657C6C176D08
-:108E200043F74EDEDF326B88F9DDD26115F73B4543
-:108E30006BD44907203D40F478812E211FE6D8826B
-:108E400005146F3E5F14FFFB4446DB912BF209CF04
-:108E50001F15DF193F3FC3372AD1F7C6019829E212
-:108E60007049A77797B53AD1F7BC4FEAF3B93220EA
-:108E7000EE5CD2687F922BF4EA1C9BC85399EF2FCB
-:108E8000CC35EC0FACA5F398976BACAAF1FB2DB9E0
-:108E9000A877AF06E3CFF3EABC4C3AE7127135404E
-:108EA000FF2CD287DFA53C3FF95F95C2AE1B79FE50
-:108EB000B91BE13E91E7BFC94A7AC1A82F99EB35AA
-:108EC000FB5FB557D03CD7A27DA779AEAB8EBFFF75
-:108ED000DDF3F85D37E6EA767C248C1471853399EE
-:108EE000ECC1E95EAB2AF33E82C3137D5F68E89F65
-:108EF000032BC5F9512FEA456A5BC6BCCE79ABE7B7
-:108F0000F71E7D2A8DF56A121423892FFFF21D7733
-:108F1000A2795ACECAEBBC38FC19FC3A497140E937
-:108F2000507EDDA9D3BDD171C2C6E79BD0FC804580
-:108F30003EF777492D633E6F23793AA97FF782EB9D
-:108F40002BB4C7E8FD93B99FF0FD15332112C0FB88
-:108F50007BC7D8D9FE35CE92F8FCA0312CEC61E36A
-:108F60003C610F4776CD65BE5C8F7CF17A584DBC75
-:108F70004675B906BF2FFF726096114FD2394E0B5E
-:108F8000E19CF57426B78D5DEFB6F17925DA5DF2D7
-:108F90000BAFA98CE7DB28F0DD9785F76FA8963C2F
-:108FA000684186F0FD869BE632DFAFD3BF8F391F65
-:108FB000DFB7E7FA36E492DCF70D5E3F0E49F4FCCA
-:108FC000980F0BC9BE369D03D75B0C5C0F8F3C4DD1
-:108FD000E7659EB3E7E9FF783AF63C7DB8DBF71F1B
-:108FE000B9A4572D5FBA2E019AAFFF17CB25E21314
-:108FF000F0F3E792AB2775B97A325715F9DD4C716A
-:109000003E3456EF3F6F0D16F0F714A517760ED8C5
-:10901000F2EC1FC7939E3BB5F7E0785B0C5F4F2CDB
-:1090200047FD40F666F77EFEFE308A3B8B8E3B8521
-:109030005B49BA56B7A3F1383C413824FDBC7DFFEB
-:10904000D5143F9EECBA2E53D262ECECAE975D2362
-:1090500062E63DA9FF2E06C66D23BF9B12BBCEFB69
-:10906000C4797948CC87F23FF2BA71B1F75B753CAD
-:10907000F7339EEF1FDDCCE7F4069E151078367EA1
-:109080000FE3EC779536E0EF1E037BEC5C5F31601D
-:109090008D14A6C5C8CBC73A9D314E930B32999417
-:1090A0005CEF3A19D655F1390106EF6BA7D0E77797
-:1090B0002159D4873673DDE2F466F0106E25D8C8E6
-:1090C000FD49D5E2BC7C2AF4C9B4AECB20C2AD17B1
-:1090D0005485DA995461866DA52324933AE9ECDA34
-:1090E000974CF80ABB95B4BF3844E96922FE45F7AE
-:1090F000AFC05F0CBCE2607482127EA7EFCE137526
-:109100000E9E64218F9193E2774FBE05FDBCFE69F0
-:109110004A1FAF3745D3D2E9BC64FB73CB65AA7F46
-:10912000D9035A84E4CC93D1CCF9B7C80C086D4E5E
-:109130008BEEB792F6AB46FB53E78385F62B418760
-:10914000D87F33A4D3F9D81408F37B2EA705E37E88
-:109150006780A650DF9157A4D359C46F557AFC6637
-:109160007104B8EE27354FE03A5909CAB9159CDAAF
-:109170000E3D4CE73325629F93F13A9FE3348B75A4
-:109180009FB5D77942DF4D8510F319EA417D817F84
-:109190005C61964AF492C26E0BFD9ED885D275C072
-:1091A0000DBC7ED7AD91533FAC889E7B797AB2B926
-:1091B0001EFA41C91291695D8E02510F1D86107F02
-:1091C00097198EFFBDB392BC6B8BF268BF3EF11D49
-:1091D000AEB9AEF389E066AEBB991F40F2D03C0554
-:1091E00000C7DDD13A006B7190EF5BE99C5DE53A19
-:1091F000D3728A177F9FE52BCACBE27AD3113C99B1
-:10920000129C589B12C53BAE8C7F7F271952DA49BE
-:109210001FB5EAF5B401D5A5D73315F23E34D4F322
-:10922000FC23128AA8EBBEAB4AD49FDE356C0FD765
-:10923000F9F64BA04AF974FEBF87EB80E987E1ACF1
-:10924000F9DF70FE9FA9FFEE43B1EF8DC925BA92F9
-:10925000C7E75A8FA570FDAB32D3AB511DAFB95ED6
-:10926000BCA46DE203FD1C971AEB35D5892B1EBEFD
-:109270007F97AE5F5B1DE27780A45576559A4EDFEF
-:10928000BF2FE7DFB16A25D7A082BE7B5FCECF5369
-:109290001D33158146527DDF257A997F970AE13586
-:1092A000F83CCD9B3A92F37D89F831DDE087656823
-:1092B0009D14F2E166E2AF51776BD4DB122068DFD8
-:1092C000C95EF13B782AE2847FF70F9762275C7AC8
-:1092D000CDBFE721EA7FDB74FAE3BA9EE0BA4F879D
-:1092E000F84EDBF89ED74C3703BFFF0D047C0BCE46
-:1092F00060530000000000000000000000000000BB
-:109300001F8B080000000000000B9B29C3C0F0A3C6
-:109310001E8145A451F9E8F82C9A3C0B0303C34F76
-:10932000209EC7835F1F2E1CCD82607B8A3330183E
-:109330008932301803F14C209E05C43F80D8408C00
-:1093400081C110888B80EC6220F6016207A0DA2FC1
-:109350001C0C0C138419186603F1326154739F328C
-:109360004268252E06065320FEC784DDFEC96A0C1E
-:109370000CDB7510FC385D068635FAE4F965140FD0
-:109380003DBCCD1195BFC70A95FFDC8681C1DE09C2
-:10939000C1DF6B459AF9D540BD354EB8E58FB9A10F
-:1093A000F2F779A0F22DD1E41787416800E6955CC9
-:1093B000CAB8030000000000000000000000000028
-:1093C0001F8B080000000000000BED7D0D981C5560
-:1093D00095E8ADAEEAEAEAEEEA9E9A494FD293CC1E
-:1093E00040CDA443069884CAFF04265033C130AC54
-:1093F000A84D94ECA0A89D1F312ACB6B780A01C11F
-:10940000A9F9EF9924A4F3F342F89134D12CA0AE3A
-:109410000EC87323B2CF4E88BCE0DBA711D12F6AF0
-:10942000F01B621E4FD45D67D92F4BBB06F3EE399C
-:10943000F7D64C574DFF4D02ABDF7EAFF3E1F5544D
-:10944000DD9F73CE3DF7DC73CE3D7547264D247608
-:109450000D21E7E047CB3F780921CB264BABC3C8B2
-:1094600092A5B4FC0A31FAE8A3CBB56C8740CB05D2
-:10947000EA9847D009B9229226C443486CF431E2F5
-:10948000A1F552F532196924C4AFAFAD22EA64BF29
-:10949000EEB2AF9B90ECFCE2EFC523C3513D44FB21
-:1094A0007B6A799749FB493DDDDA65B64CBEAF83EF
-:1094B00041297E4D8462534BC840C35EE28910321D
-:1094C00044C79E4FFF53EE4B90386D27678789BE88
-:1094D00000EA55637DE5D9E39EF5F4F99097748D24
-:1094E000D2523964658314EF85CF6B8B454A8F5F09
-:1094F000323DBFA5B03FEAC95840477417F67B8696
-:10950000D20543BD5BF42C017A281D6D15D2D356CC
-:109510008C9EE72D0BE8B9E290BE289F1EA59ED138
-:10952000A3D4F7E23C9D89527A1A2F849E7B909EA9
-:10953000214ECF908B9EF7717AD6D9F4D40D223D6F
-:10954000830D941EFAC8779F45E2B4BE02F484A04E
-:109550009E939E41A0A7A5003DCA9F879E4F72790A
-:109560004B023DCBCAD393047A6A2BA0474D138D8F
-:109570003EF713C11C6D998A979FF371C1B3E9A897
-:1095800045FB1D7E5BC479A62B32BA76C164BD3122
-:109590008ED7F71A07A363205FF3F64609ED6FB87D
-:1095A00041C0FAEE7E1F2232D6AFAD377BA0FFCB93
-:1095B0009E74F63FDCC0F0B5EBFF139FC77F2222FD
-:1095C000B6AB51E3C3000FCFFB1649C038DE74546D
-:1095D00083768DACDDC0BCE55D636AA1F68C9EE14F
-:1095E000FB2D9467257B0FF2EB730D69A253D8FF17
-:1095F000648200FFE528C3C76E4FF122E44A20FBD6
-:109600002ED364F811329BCE937557D6A2E3C5D200
-:10961000B72B71CA8FE1BA5E05E84EE9BBBA406F5D
-:109620009D89C9446C04BC0AF3C1968B6BC836A5EE
-:1096300089CE67DF2BA23142A6D6B340B86A276134
-:1096400049F5906C33C1DF3902F42470FE07E6ED72
-:1096500045BA65A06B01D095243A7DFE1C971FDFAB
-:10966000B31601B952742B6A2D983A4E0AF8DF02EC
-:10967000BDA6A36BF3E8FFB93DBF745E5DF38B7CC1
-:10968000798898590BF8E277CE9B5DBEC4F97E4588
-:10969000BD85FC2D37FE54FAD9F87F4F74EC87282E
-:1096A000E9683C3489CFB077AC17E49AAE49E3203F
-:1096B000ADB2908ED39EC76FF77813744A69871C3A
-:1096C0007F8BF369D83F7E24BF3F373EDFE5F5BE91
-:1096D0004B342C6DBA161E62E394EBFFC7C0E25AFE
-:1096E000A8EF5A5792E5E0FBBDBCFE15CF3BEB154A
-:1096F000E3CFE727F86345411EEDF5083F732621C8
-:109700005C64F0A72E27E452F83FB4C9EFD78FDD91
-:10971000054BEB1791C419E8E73692B8383097AE8D
-:10972000176FE20928AF95CC7F83E7B495F6FAE589
-:109730005CEE44D4036C3CDA3DA1FD87787F92D087
-:10974000490895675F2BC98C50D4DE239ECC0A94C0
-:109750009FBB0831666979FBFA29B6AFAFD432AB4B
-:10976000613FBF4AA284D0F1AA88E68712EA6769FE
-:10977000BDF032D5A023111FF94855BC80DCF89705
-:1097800012CB5F45C76F951DEBC26F2608E8855069
-:109790009464FD614234211441FC5790150C7F5DA7
-:1097A00080FE6A24BD47A2E388318F71803EAD6A96
-:1097B000232B37E4C9A12E30F9ED89793C40D7201D
-:1097C000D5FF3EBA24C30D74BDC37A88527BA380F3
-:1097D000DC4EE8F79C48B23368BF39816497505833
-:1097E000252B13B45DDA47569EC6718971A0809C03
-:1097F000AD13D8BC0AB1F173E7D02E2099EBD02E6F
-:1098000048E33A96636913F601C50C1B3E98F6B31C
-:109810003B985E93880972521D4B67ABE0BD7E4951
-:1098200023E03B2B9624AFB5B0F2541EBE8A6A45A6
-:10983000D17E6ABC44E8CDDBC70E53F93995276F5A
-:10984000A9FB991D30D038C8F5CCA7507FDAEF3F7F
-:10985000C6F9248F5164802E5DCE340953E53A2534
-:1098600014D6131B39BDF0BB76B9535EA5995C5E67
-:10987000E9103E89A07C0D3D4532802FE5E491F54D
-:1098800014BEFCA84246A87CB590E31E909F856458
-:109890001C4B836822948B8981E55212C7F2F7ED45
-:1098A00054EE69799B49E5BD09E5FF2601F68986F5
-:1098B000C4FC307DEE8F5957C2FE42E57F1D3CA7A8
-:1098C0007222803CD598A4E07E592DB0F5BA53D2CF
-:1098D000FC506FA749503FEE11FA2CD82752DC4EAE
-:1098E0004AF989631D3FC0E94EF1B23A96206330D0
-:1098F000BF745E40AF1F6EBC15D7B14F62F0209DA4
-:109900001794BB556C1F73E3A1C0BC2C38FF79586A
-:10991000F7E79F87416159C179188279582730FD4F
-:1099200029FF9A8D5F823EDCA737F63C8EFC974F6D
-:109930004FAFBE4DFF7297DE5CC1F5DC5564FC2273
-:1099400089EA91DB7D59591210EF2F02DEFFF6B341
-:10995000E31F037AC858623EEC5314EFC704E46770
-:10996000921CA7E34BAF8819F0533CC11B944409E8
-:109970003F8568549F295C9F35C1FFD66BAF07A711
-:10998000EADF4B463F7902ED0DA22446403FAD4A47
-:109990002A20177DF56B1590A3A17A0A83DC446514
-:1099A00045B882962AE904F9B3ED8F17A21B14D0AB
-:1099B000CF723431C397B7FE574713E457B0CEB5D3
-:1099C0004454A474C899EB14A067405BABE4FB5704
-:1099D000B29A88CA54DE86A05F18C79B5404D493F9
-:1099E00064462FE5CBEAFA24F67338DA81F80C687E
-:1099F0001BB0BD4EE26837BD50BFA1B311F68B5707
-:109A00003612D063C5F8E1B6A37D6A92C879FB81AE
-:109A10004F4B12316F3E7D52320B7888D1C2FAF52E
-:109A20000497738F1EC77D85A41F34152ADF5E3E01
-:109A3000D7DE28F999B0306F3E2279FB0B9D8F411C
-:109A4000BFD15568FDD19DC2D9AF21106579E5FD23
-:109A50004EEEAB7C7ED32B526338BFA134CC6F1F4C
-:109A6000D5EFB87F9E0C650E52127A5625F7C37B50
-:109A7000AF2591DE0876D30CFBD9DDE26506C8D9A7
-:109A800003C037CAD86DDD0A9623DD1A96A9EE28E1
-:109A9000960F06BFF0C4186DB7C5F2693E5ACAE901
-:109AA000BBBF01FD51EF3A3E02FD4668FFD0AFA4B7
-:109AB00068073580D9FEE28DB1F2660FE3A3EA09AB
-:109AC00020BE8B3CCCDED68989F292D64AFBE35588
-:109AD000AD4E7B36640426E59EFE176CAE71C07EEB
-:109AE0007DB6A3BE7B5DFC80EA26C0C72BC589D1AD
-:109AF0000265617D7D5610114F515C340E768634BF
-:109B00004BC6FD7F4070EAE7473C6C5FCB7814ECB6
-:109B1000374AC65F3847F9E1D53C68DF84AB9B46DE
-:109B2000B3C09F5AD998478BB0774CAB29301E8968
-:109B300048BF1BCB5BCF4F0966A3E72F804F53E88D
-:109B4000EFE970C875CAC3F6B5B37CBD883EB30BE8
-:109B5000F449948A2141F9D01F073E78826D46333B
-:109B6000E5C340B5AC83DFD3DFE329B8BFB8F92044
-:109B700056DD12053DE8E6FBF35C8E9EE27CBFE617
-:109B8000EC07505F6CD73C9D19D41FC73B419FF732
-:109B90002FF57840CEFF62F8E7A2E3735C7ECE0A31
-:109BA000137420DFFA23CC3EDEA651F981F51C6147
-:109BB000F2A3936C27BE37285DC254BADCFC7BB796
-:109BC000E9B3F95E55ED89675A00BFF138E2D7264F
-:109BD00015C4EF3F8AEF365EEA045E598697F19727
-:109BE00081D7534262BF87C20F70797D401A5340BC
-:109BF0002F34423DD03B41B68EA6EA25C1DDCF933E
-:109C0000A02776403FB4FE0E69DCD18F5D2F047C27
-:109C100060EB22CED685F4675D17365E231C6F9D00
-:109C200064985C371796EB771B2F7B3FED0D5E4DED
-:109C300040DF54AB71B4B367A9F12CF0ABAF56D68B
-:109C4000C1FEA10E11EED7D854CFF3876AD745D104
-:109C50007E09AD43FB7BC01B477BFC58EDB7CCF5C1
-:109C600094AEBEB355C46750BB3F78F5311DF4E2E6
-:109C70003111FDB2BEB37367250BCC7310E26014D3
-:109C8000FF00E087F6B33C616C03BE7D2A557CB4CF
-:109C90009F375B4806F4A95735A3605FF72D508CBA
-:109CA0005EAC1527C0DFDEE0C75A132D53DB07D5A6
-:109CB000C13BC48593E3D09F700E6C5CBA8783BFB1
-:109CC0008EF4098EF705F128077B27610DFBA7B0FD
-:109CD000AE40D782796EEE24DF292DCD12EC9B2485
-:109CE00060C0FCC7E29DBD7F043EBD24A21E74F38C
-:109CF000E75931E113F3E25EDE4802E7CDEEEFFA19
-:109D00005A09F5A8544F323E01468DA31DD957EF8D
-:109D1000C1389AA4AEAD2A695FD757665F131EDFBC
-:109D2000B0E5A1FDD76CDC80C1F477888C11889FE9
-:109D3000541116BFA826BA40B0BD21C43128D2861E
-:109D4000719388FF9DEEF716EC5730779273C169D7
-:109D5000F42BD17EE7BE0BFD96C1D74F1EC57EA961
-:109D60007A889C9B31D9AF379AC487E4ECB973E207
-:109D700072C29AE02F81F22D790C5C9F6476D838FC
-:109D8000488B81C89D0EBFE946B1C9111F95B5C169
-:109D90003B84302DEB6F33C7F2F4837B7E6F82817F
-:109DA0009641BD4DE658057A03CCEE42F1A7413904
-:109DB00091E981FDFB2215E385444A62FC7748A8BE
-:109DC000590CF6B35D4FAA97B380976A9816E88B43
-:109DD000A1191E4334A0DF6DC7C11F20E20D46A2AA
-:109DE000441C49AA977E934FCFA745673CABAF8CE5
-:109DF000BC0F74973E87F0CA46A2903F73BFC8EC71
-:109E0000176FA0F0FBEBE58E7BC56553F9B69DF3AC
-:109E100077A89ABAD65730F1013990EA5F3C017CB5
-:109E200018A85D132D452FD1A89D93E7172D93CD2D
-:109E300021B1341E5BC5DA02F3A752E15959629C85
-:109E400009F94E120DFCC557983EA2F88685994C2B
-:109E50003FB39F01361BF1B6FAB4113A6F811683F6
-:109E60007C99C2D1D54A5C6AA5F42E3D4044785F06
-:109E700027121174ACD866A0BE6A66FE9D49FF0128
-:109E80001DE136D9B16F81FE9CD8B71A41FE9DF015
-:109E90001330CFC1BC79EE3E447E356F127FFAC8D5
-:109EA0002C1417F6CB1D7F57981F3515F163379586
-:109EB0001770C87752BF11CA1DD46F84723BF51B4F
-:109EC000A1DCDA4D859DCA537F7733C2FF0D9AAE70
-:109ED0008473B264AAB111E2A25F3EB1893EDA0D89
-:109EE00038CC866EFD1D10271F01F84A44C71200AA
-:109EF000E6E7292F89FFDE0E719711BF5DFF9FDB1B
-:109F0000B1FE042CF4425C7F24C4DA8F89C10EA810
-:109F1000BFBB81F0F8B9A9DC94E7FF9F11BD287F92
-:109F20006003B1F6BFED81FEFC920DD777401C7542
-:109F300002A67C047CFC0A8367F73774C0B906AAC2
-:109F4000003A5E53FF456CBC792C6E463EB4B60CAD
-:109F50001F7B71FC7570D806347FA8060E8F894C64
-:109F6000E5A6893EDA5DCDF1AEB01F2225D87EC7C9
-:109F7000E347C5D74D997D8DE3517E3D9868BF81FC
-:109F80001EB660DC9F14DEA7DFE971777BA7C717D9
-:109F9000A52D6142F7E1CED12C4CF52E31119668FA
-:109FA0003F55D71EC76D458E6699DD50E1F86F8825
-:109FB0001A8F7F26305E68F35BD298FDD1EE9A4F00
-:109FC0006FC4C47348BFCAD661A5782F8771F2FAEF
-:109FD000215F5B5C57687FB1CBC80D9E49BB8BFE90
-:109FE00057736DC0016B6D3593761CF063E96C0798
-:109FF000ACB6343960AF7699A3FDF9CED7E52E3AE9
-:10A00000749B7F1CAE75C195CB9FA4F3FDCE627689
-:10A01000E404CCF7E572F0D9F94E98F5EB231FAEC6
-:10A0200062760EB3673E4E781D371E469E1E16A101
-:10A030001E83758F406C3B37DB3CB5FF3EE50B184C
-:10A040008F33FB24E2BF7A6ABCCEEA4862BCCDEA19
-:10A05000F5697D118CBF61BC6D0B35E87DB4BCDD4D
-:10A060009BB855A2FC7ACB7F518684A1DFE40A8895
-:10A0700053F7B9E20A6E798A3D7A73C1F331BBECCA
-:10A08000EF6671401B96EA0B9FFB6F9164A4E3257A
-:10A090006F620BAC2349234731CE43ED6C11ED6C5D
-:10A0A00013EDC7C3D56BA260C7A44C19FD1C297D55
-:10A0B0003BAE9707DA3CB85E7A241DF1EA5FD97BA4
-:10A0C0006C2EF8A3BA87737A0CED801DABE43A5876
-:10A0D00037616A8FC27949382614DCC7B64BFCFC5D
-:10A0E0009A7CB4247DEEF9F838CF234A3708786E8D
-:10A0F00067853CC8FF94EA413DBABD4D7E1CFC9F7C
-:10A10000ED4B3D37C3FB336DB2472CA1DF06B9FDE4
-:10A11000B415E2A8B0EFA91BB09F33862753497E40
-:10A12000CEE1556B30FEDD2798CA5C3C5FF690832C
-:10A13000C8B71F60FC6FC7A20ECC1FB02416F7DA99
-:10A14000BA20D09529741E2E85F1FD8EC6F6230FF8
-:10A15000015D542F1F44BF6DFCC4C6089C5F6A8B11
-:10A160004774A0DBF4BC01E3ACF4E0FB7463F20AD7
-:10A1700003E2B66D1E87FD915EC9F8B12342908E51
-:10A18000336DA7206909F653F321387F8D2C9DB0DC
-:10A1900087EAF2ECA1706B724522EF1CC1B69F8A70
-:10A1A000ED4FA26C8C59F4BD7AD287FEAB107E9233
-:10A1B0008810A79E2DA2DF7CED82A3088B6382E12D
-:10A1C000D3216E6F9904FD3D93C5F1EB0979983E5B
-:10A1D0000FFE41C4736112E2F636B7AF34FA0FF6E0
-:10A1E0001D9FEE3C079E625F9D7CE324AC2BF164D7
-:10A1F000F0350F94AD89BF21E027BFFD4D8C1F3D89
-:10A20000D07A67A047986A879D59FA4C7A6E013DCB
-:10A210006197C1B1309EF312F1969276B87AF253FB
-:10A220003F3C9A87DFAF24971DCFED3BBB9F62F683
-:10A23000DD5BDD9B7F7894CAF8062F8B17F965F3F9
-:10A24000B7A0374EF1FD330DF93779F2B3C1CBD654
-:10A25000D11FF8FA8619067F1CFC6798DFFEF67599
-:10A2600038EFC5F0A6FAE00F4C1FD87E38B3E77779
-:10A27000B495F63B26F35CCEA21E2896E7F20129A0
-:10A28000217B97E5E927579E8BBD9E075799244A66
-:10A29000E7695B35C9C0F912B9C6241B417E056266
-:10A2A000F41AACFEF872BED5417E14794F16D6C5AD
-:10A2B000195D32E05C3235EBFDD4A12C8EAFE49217
-:10A2C0009F72F3B9C5359F0D5EE77C8A245E0586D3
-:10A2D000492CAED46D02BDA3CA06AC4FEA1FE8F903
-:10A2E000FE8F3D9F64058B8B896A86141A7788EBF5
-:10A2F000F1A4D7BCD40BFB8D377902F4B0B54A4634
-:10A30000FFD85DFFE35EE6BF0D3612C962792DA866
-:10A310000749A769C2B95F4AD0920F6B887E1CCEED
-:10A32000BF4097837FEF8BBE6EC2BA7B5424C9199E
-:10A330006DD45FF63622FF77ACBA8BD9A1EF2582B8
-:10A34000580DF52DDCDFEA4C4DB0EA26F3CD88D66A
-:10A3500013BD314F5FDFE4657A6DF2BD15BDC9F104
-:10A360009ED9EB83216EFF697DD11B4305DA571718
-:10A370003EB77E1FA7F3262FB747AC3ECC83494597
-:10A380006E3804269B74CD607A3D2D4D2D89725B0D
-:10A3900040BE6F02F9F352F9663B15936FDB5E28FE
-:10A3A00036FF6E3BC1AD7F2A3DC78DEDB9B9E438AC
-:10A3B0006EFF7D90E7BB516977F0C9C7D7F942BE00
-:10A3C0005E26EDA934870DE48B0FFC7D3817075905
-:10A3D000C8B3C776733EFA02ECBD1B0FEA676F0184
-:10A3E000B9F385991F8E8B11EC3AC970CCF7047FB5
-:10A3F000F879E8418E4F2C7D358B0B87EC7CB94A80
-:10A40000F547E93C39AA3F1E28A53F4894C5016C91
-:10A41000FAA7E2C9F814E5F33ED430EDF8C42330CE
-:10A420007E09BEED3F1FBE8DF03CBBEE811F1FE1DC
-:10A4300079094EBD7DE93A8C9F15C393CAF5A8B73B
-:10A4400080DE7E17E7E1BBDEDA0B9F07BB5E51FEC5
-:10A45000F37AFE2DA27E9AEEBB8D928576D4B0BEA5
-:10A46000CB427B0E6885FD3EBD08F3CD488CA07EB7
-:10A4700084869037E5D74DE45F801818D793EB9D1D
-:10A48000784A11E77943B4CBCADAFD82FEF66F91C0
-:10A4900071DC89B896CAF2CC6C3B149615F82D3E47
-:10A4A000F2F9638DAC1DEAFD62F44884E90938FED7
-:10A4B000017BA358BEDB24FDCE71A21F8A97D65321
-:10A4C000AEFA4495F4D70B9C234E6D2791D7F3F445
-:10A4D000DB5BB08EF3F213CC27D77761BE1FF11888
-:10A4E00010EFEC8BAE23094AE720617A2505E54A97
-:10A4F000C83F59ACE13985CEFC3F8FC2E4F125AFAE
-:10A50000EE88DF8A2AF3A7ED7AE5E6FF6EBA3F15FB
-:10A51000B28F2E97D97EF1D61792BF87BC066B44B7
-:10A52000D0C10E3EDD9D43FB6A43F65219F2D716A9
-:10A53000CA33B1DE863D8DF2EA7C7B89B0BC018AEC
-:10A54000889CBF3EED7529A77D4780EE536916179D
-:10A550003995FE57CC0B38B54F443BFA54EA832566
-:10A56000D7D369BE8FDBF54EEF134DF453524266DD
-:10A570001E6D7F5A32C305F308A8994EF2F4DC270A
-:10A58000D2A2436EDFBA3F2183FE39DDAD08BFA200
-:10A5900073752BD049F1DF906E9421FE558E2E48B5
-:10A5A00067CFDF376C3AFB55E6D7F5ABCC4FE9D731
-:10A5B000DE447ACFD0E7A5FCA614A7B35F2BAC5F2F
-:10A5C00094103BBF55BC56E1BC0917BD7EDDB94EAA
-:10A5D000DF69FC8655765E3B2CA595F3C127645A4E
-:10A5E00002D8D11AC9A6203F9FB2F165883360888E
-:10A5F000918ABA76F229E19314AF1FAC574D210A24
-:10A60000F057858B28AC513FC81B05FFC373F85525
-:10A61000BA8E86BB8218471E6CDD7418CC84E83D68
-:10A620009FC5D0D33650F6183F7D5F5F7B0B5F67C9
-:10A63000B4F3CF0C76AC8678A544E23CBEE1D125DC
-:10A64000DB5F2BB0BEF3FC65E19C6FB25D313E0574
-:10A650005CFE908FAC2DAD9F36337D66D17FA05FC1
-:10A66000A2AEF6336F71C6C1359207D3F73B65C210
-:10A67000E33537BEABE3CC2247141DCFB13C5A06BD
-:10A68000EA13AB1AF2A742098980DD3EAB39D10E3D
-:10A69000FC2FC7F761C2F2EA08394EF2D7D5DF7254
-:10A6A0003D547FE79705B0A7CF18540A1601AC2C8C
-:10A6B0002A645FD8F95A1370EBCBA80F0729D61874
-:10A6C0003768F5A0DFBBCD38A5E5AFA7EFF1712660
-:10A6D000E79FE8D2723CADC5F9970D8FE95F78FE30
-:10A6E000F32F4F73FEC39B9D76F074E7E5475C0F35
-:10A6F000959BFF0B1DC79EB7A9EB83E9C3FA3B9F50
-:10A70000C57CC5AD2DA5EDA3A9F37604F7B790419F
-:10A71000CC4C81763F9505977DCE4A8524899177EB
-:10A720000E255EBE7C1FE415151B574CB8FC0DDED4
-:10A730004FEE135412F15C442FF33DDCE81E89EE1A
-:10A7400087C12D57ED919640DE9689F95FC3DD26CE
-:10A750003E9F987F9F87E32B108FED5FEB782EBA9B
-:10A760004742BBC243CE2D21C861DD963B02F53A7C
-:10A77000F7480A3EE5F905B4EA4C6847D06E5D0437
-:10A78000C19E5A3CBFC77EA023A827912E06D38620
-:10A79000006FF59A669CEBE53BE97AD8EAE7B0CE24
-:10A7A000E16A0E6B1C6EE430D9857050A630C4E9A6
-:10A7B000BD690DE100871B395CC3E16A0E37715832
-:10A7C000D885F05699F537226558FF010EEB1CAE7F
-:10A7D000E1B0C6E1260E93036C7C1F8303DE0CEB15
-:10A7E0003FC8E1460ECFE0703587E7725838807079
-:10A7F00051BD1C3391BF93F3DFC9F84608F72FE32F
-:10A800002EB86BB27E9EFF39D0AD0BF9E78ADE22FF
-:10A8100071A7C53EA667C6DBE398BF44FD52EB5463
-:10A82000FE792475A00AC52D4DDE6EE23C3D5278BE
-:10A830005DD8EBCEBD2E2AC56FCD79E2F7A1FF2002
-:10A84000FC3EECB3D73DF3C7C7DB0DC4D3DD9FBBE4
-:10A85000DD08D52F24CFFF0F48190BBEDBA0B60FA4
-:10A86000FA355EC599E77AB7CFCBBE5BF1B13CD77D
-:10A870003E8EDF783B3B8F189817C81C10A6C61772
-:10A880003FE763FEFFF76D3C9551F48F8239BA6262
-:10A89000F3FC9DE1584799FC75E9DFF3F314DD7192
-:10A8A0008F7F8577749C805A984F774FE89B5BAC7D
-:10A8B00053B4AEE2A7CFC16FD122D1FAFC7C6AFEBD
-:10A8C0009E081E11F5CB595ACFCE2311B17F3C976C
-:10A8D00020F52CEE25F2FA384E23FB8EC15C0CFBE2
-:10A8E0000C7DDECCC711A6F6EB6E97F5D5B0F9E27C
-:10A8F000F8D8792B22791EFB99C0478A23BFDCCF79
-:10A90000213F59532FFCF985C25EBDC87869763E58
-:10A9100054AEFD135C5EA6C86791797DC467DB29E0
-:10A92000A3269C23D97264CBD7F9CAD105CB096C75
-:10A93000484B8BCB894592B86E247025174D5F5ECE
-:10A940000AC84936BF7EAD52CDCFF90D94178A8F14
-:10A950008472AB317C6A1747B03F01D6389EB7701E
-:10A9600018F840E9BD5CA9E67C60F18C009C3BE6F0
-:10A97000B5A7C421BE02758698DE67F5AE51D83AF8
-:10A980005FD551CFF027BC7F17BEB43F25BF3F91A5
-:10A99000D4BBE49CE1FDD70A9B5F5A9FC55DDCE315
-:10A9A0004B02E22B92B8E5A1ED3EC3EBBBF5975D00
-:10A9B000DECFF11BF690CD2CCF234EF2BFAB0C2A8D
-:10A9C0001EFEDD235B676EFDE405B95A72FE72550B
-:10A9D000A95EAF550AEF3B54CF37437CB6D8BE7360
-:10A9E0004299D80F9AF9BC4D6BDE7F077A68D9E49B
-:10A9F0007C568AEFE57CDCE9E27B7A2ABE15C9D970
-:10AA00009B5C4F548ADF35E789DFCB2EFCDE29B90A
-:10AA10003ECBF7A34AF1FFEBF394877F9CCADF8A12
-:10AA2000D69147991E7F3F739EF8FDD28D5F917539
-:10AA30002B2B8C5F1661F221A904E33395E2D75DDD
-:10AA40001E3FEE8FAFE9376368AFA13FBE5D59D3BC
-:10AA50006F4993F89984E9F5E98EBFA3E2F1DFDF4E
-:10AA60006F4A93E37F5179BF637C89CA0F085BA566
-:10AA7000E33E56E9B8D64D0EBABF96BAC931EEF9E3
-:10AA8000F2FDEB158FFF5107DDCFA73EEAA45B3542
-:10AA9000304FA4D271FFE13CD7FB6F38BE41457304
-:10AAA000EC03C5ECF7B3DCAEFD84A239E4B858FD85
-:10AAB00037B9BDF2BE0AEB9FE6FDCFB5F12953FFD2
-:10AAC0001E8EFF3D15D6FF1DC7676585F87C9FAFBD
-:10AAD000C362FB6780F33D083A32CFAFB9D03CA6E2
-:10AAE0004DBE84E08773CD67BBF1FBC1372545833D
-:10AAF000F377D249D01EF79F0C1DC0DC4C3BCE4CE7
-:10AB00001296C0F430C6B7BC11239AEF5FD87E9777
-:10AB100024C5CD42E76BD57EA6FF04CDE862EB5D90
-:10AB200026F03D47B1FA417FE1F84B1519CF421E9F
-:10AB30002F89F2F3A2B31FD40BC6FFA57802BFAFD3
-:10AB4000D6647200E2CED5EB1CE7F9311B9FA889D1
-:10AB5000F8C81AC347960CB350FE72839FCDABDD85
-:10AB60008FED1F0AD171C2EE7160F80DF8E35D78C8
-:10AB7000DE5F2D239FFA43CEF3F09B793F7FC5E93B
-:10AB8000EBF796CE1BEB98D9AA40FF7DAD2C6EAEAD
-:10AB90001303CF05FBD5D2F71A6CEB66E78123FCD4
-:10ABA000BBD2147C573A1FF2A4A23C3FEA19FC3EE8
-:10ABB000EF4C8BA7E4FD3821C3193F0F363BCFDDA7
-:10ABC000EC78BB5F777EEFE38B3ABFF7F1CE943C36
-:10ABD000F87D91CAF2B1CAE16FE773D9F586A4A4F2
-:10ABE000A215E453C611EFF7459DF8BE7BFC63ED5B
-:10ABF00083DE51AD105EEF14DF8AC51B26E8AD92EF
-:10AC00009319A6371CE7D4DD5CBE7C554A12F4329A
-:10AC1000D5BB45DE07587B358E790A4A34AE633C96
-:10AC20009AEF030AAC873C3E3D68AFCB80C7CE436A
-:10AC3000C6FB5E04DDC4734605D69130B5DDC4BCE9
-:10AC4000DA72FFF66ACC4FB46A155C27823E8EDF5B
-:10AC50007BB9C799EF3777F96939C36FEE86D2FBB5
-:10AC600027315168BDECF4333DAADC10D79526742A
-:10AC700055D1EE71E3F10DBEFE541B7FCBC473EED4
-:10AC80004AF17FAC42FCED7128FE5F013D4BF1FFC4
-:10AC90002A94C5F07F8AEBA31AA2F7E09EAD333D5C
-:10ACA0004BC88D7A7E7C3D1060FDD6703D4548BB1B
-:10ACB00023BFC4CBE9AA949E43B65E2B438F3D2E9F
-:10ACC000A5E7289F8FEF959A8F17383D8100DBB756
-:10ACD000947D719D2E4D7249917939C5F19819E095
-:10ACE0007125AB7D5A72F5A30AE93835392FAFF2D9
-:10ACF00079F965293A4E72B94A8B64E569D84FE70C
-:10AD0000DA790A6B1DF33287F327EDB3E7A5C33178
-:10AD10002FD5D39C97DF5648CF9CC979798BCF4BE1
-:10AD2000AE949CE5D57F9BD7FF13AF8F76E29CC096
-:10AD30001FFBE1BC6CBE3FEE09D44EEE6FB49E1813
-:10AD4000583659EFC1E163763D1FD6EB9CA8A704A6
-:10AD5000F2FA23D66BFD70AE3DC0BF0BF9FE70E872
-:10AD60003DBC5D18DBDDC0E8A1EDAAF2FBFFC6F03B
-:10AD70002B76FF33A05ECFEA3FD9F522F9F5E60442
-:10AD8000FE64D78BC27361DF447F75F9789CF2FF54
-:10AD9000733FCBCF71E5776995E531782309BCE73F
-:10ADA000A18684D290073B28B17B172C6A541F845C
-:10ADB0003C595F224B2AB0BB3C0A6BE7A3F6167CDA
-:10ADC0005F36432387FD3AB82006D907F9AD11094C
-:10ADD000FD813BFD89A5815A8627C8CBC0ABCC1E1F
-:10ADE000EB5197F2380AC36B67F06329E84FA378F9
-:10ADF00041FF0F06C387A1FEAE065907F93ADC7082
-:10AE000017DA893B7B2402EF775E2FA39DB8FBD531
-:10AE100010EEC3039281F9D59629EB6037DE1DF859
-:10AE2000D3894D141EEBA9D284AB911EC4DFF290DE
-:10AE3000781FF6CFECCE2D147FC80BC6AD0BFAED04
-:10AE4000647E0CFDD541FBBB57EB984FA313767F77
-:10AE5000D350AB8CF9483BEB9BDA61BCDDAD0ADA31
-:10AE60001DBB6F68EAC13CEDD600813C801A5517C6
-:10AE700020EF31BC422616C011BD07ECCED0F20047
-:10AE8000E446929A7A365E683EC17BFEBC241D8FF2
-:10AE9000D1329C9231BF77F70D6B593E69AB4FC3EE
-:10AEA000EFBC2CF3E5D872C25295E127FE23017C5A
-:10AEB000BC734402FCB7E7399C9E685FF21C319C6E
-:10AEC000A9B05EB6B27AA19484F74E95AD97AEB0B4
-:10AED0005EA6C27A5956AFECF93DCF9F54E83F8841
-:10AEE000C3F95DE7B760C797FA5E6EBAF9B93B037D
-:10AEF000CEEFE9CAB5B7F372CBD10B879913788A35
-:10AF0000E5EB97FD1E73E65D51F83E6DA8F65E5EBB
-:10AF1000DEC7CA3AFEBC6E4B14EF8BACE3EFEBEE30
-:10AF2000C3FB23DDFDFC0FAE8F9B49BCE43CD4701A
-:10AF3000FC5FA7B8433CBB592A930F10F1B8EC4D06
-:10AF4000A7DE5324AB03D7ED0D2C2FC707CA00D6BD
-:10AF50004D3D5BC75E928CC7309E658617CD9C5C6D
-:10AF60003FDEB61771FDFCA04E24422BCE0FFB8EA8
-:10AF7000D225276EB9F0B9CEF52F544E7EFA2EC9E0
-:10AF800089372556B47EBCE90AEB652AAC97ADAC8F
-:10AF90009E9C122AD22B72BAC27A990AEB6559BDCD
-:10AFA000819532DFD7870720BEE5BD5271C00357B8
-:10AFB000069CEFAF521DF0E032677B79B9B3FDE03C
-:10AFC00072677B79056B6F04F7BCC78A55BE4EFE6E
-:10AFD000CF79AE9366A574FD506B9975A5687E68B0
-:10AFE0005F23E904EE1DA2FB5586EF5B05E33F6B93
-:10AFF000826CFD5F1FD01CF7D3FDA5D3D91C64F86C
-:10B00000DAF496C3D7D6BFFF57E47657913CFB6A74
-:10B01000D03990774DB275D0EFE13BBE550776E55C
-:10B0200023AFADC07B3DFADE67E7CD1898F7239DCF
-:10B03000F8FECDA0C71E49CA04F2711EAD368E5D62
-:10B0400012C1EFC908D8CBD48DC2FB3E1ED92CA1AA
-:10B05000FDD1775BE97B4DBED1CDF284FE8EFBFD49
-:10B060005FE5F7713DC5EFE37AA25BC7F260773326
-:10B07000965FEA36B07CBCBB15CBFDDD26EE1B5FD0
-:10B08000ECEEC4725F771CCBBDDD5D58EEE84E6020
-:10B09000B9BD7B33FF5E2D89E570F7162C87BA2D7D
-:10B0A0002C07BA5358F675A7B19CFD3707862F5960
-:10B0B0008AF99290A156147FE37967DC61E1B301CC
-:10B0C00007DCF23567BCE1B22FCF76CAC5A34D8E3F
-:10B0D000FA97ECB9CCF13EB66DB1E37D53FF950E16
-:10B0E00058BFAFC3015FF4D9BF72B4AF4BAC75BCEE
-:10B0F0009FD5F56167FE57DB06C7FBF0D24F3B607B
-:10B10000B5E54E47FD40EC5E070CF73EE7D7BF3193
-:10B11000D8C4E2819111473D49DDE5A8F7A999E638
-:10B12000FE20C443D361B42F1F3929E03E38E32207
-:10B13000E3359027F25311E5895CCBF2DE673425C5
-:10B14000AF80FBCB88945CF1C150F97BA4ED788F84
-:10B15000186E4DC03EFBD66B820EF6AE10DE323F4F
-:10B16000DF9FB3CBCD67926414E2923CCF4C9B4DF2
-:10B170004C13FC46AA4F08DAD9C9ECFD18B7F4E025
-:10B180007753692181F74E539BD9F8EF1AE4CBBB73
-:10B19000F7DF20DAE5673482EBA0BD4369ECA7ED69
-:10B1A000B72F90F17BBE29F8BABE8B7923C8FCD7A4
-:10B1B000ADF7B378A576C4DFA82C85FB321233C077
-:10B1C00055B5DBA9D997F0DE5335662C87AB01D492
-:10B1D000E60CD9A842BD2CDEBF40EB7F1396FD44A0
-:10B1E000FD4D594BA6CFEB3627E6C2773DDB79FF05
-:10B1F000DB0FFF8C5C42F91A5A7A9CDC8AFECE5E29
-:10B20000E45FA8758CACC95BBFDBDF2EFCBDD12F22
-:10B21000832CAF667B8F85F7CC29D96FE37DA8F6A9
-:10B220003C045B8E9304F4DF368EF7036FBF9F7D83
-:10B230008FB75DF85134CAE9EA71D285F8001DB7BD
-:10B24000523DA7DE9214D6B4B0E773F3FA85F71B2C
-:10B25000E17DC212205FBD127EC9F07C13E5179D0F
-:10B260000775734628C9AF58967D1FD15C845F94DB
-:10B270003FB7A29F3BE8881BDA7CDADE739C2C6F19
-:10B2800001FB9FD59FE02BE5C3AD797C9CE0C7B265
-:10B290009F627E6BC8FA1159A2B276406F88D2B70E
-:10B2A000B100DF29FFB07F9B1FF63821CA2F869798
-:10B2B000657FDF88F775DAF91F767DF8752EE7F977
-:10B2C00087941FDEB1EA8DF03D687B4B02BF131EF1
-:10B2D000503D789FD080FA4CD6C3E519EA4992D9FF
-:10B2E000FB639E67DE2B145A7F4EFB1F32A6F3BF13
-:10B2F0000BEB57D9BD990391327610BF2F58E4F765
-:10B3000005CB52BCB391AD53A3874CC64DA78EBF9E
-:10B310000BE916A3CE7DB57F93733F8B691FC6F8EB
-:10B32000745FA403E16279F976E9CB31BB51E6F8A9
-:10B33000787341768F71CE8F789AB919585E93AB36
-:10B34000C6F2EADC1C7CBF2A5787705B6E2EC257A0
-:10B35000E51AB1BC3277393E5F99BB14E1D6DC12F5
-:10B360002C57E416E1F3E5B9AB105E965B89F0D299
-:10B37000DC6A2C97E4DAB15C9C7B2FBE5F94BB1E29
-:10B380006123F7412C2FCDDD886573EE23F87E7E97
-:10B39000EE66842FC96D44785E6E3DC2B1DC6710E5
-:10B3A0009E9BFB14964DB9FF8A6563EE0E7CAFE75A
-:10B3B0003E8FF0C5B97B10BE28D7877043AE07E13A
-:10B3C000FADC5684E7E486B19C9DDB8D655D6E27D3
-:10B3D000BE9F957B08CB99B92FE1F3EADCE3586A6D
-:10B3E000B9AFF27BA09FC2329CFB2696A1DCD3F8BA
-:10B3F0005ECD7D07E160EEDB5806722F60A9E40E9A
-:10B4000063596E9EDCDF2F8911E7BE7C0D99E190B8
-:10B410008B5539E7BE7CD57893035EF96BE7BEBCEC
-:10B42000626CB1035E76C2B92F2F39DEE178BFE8D6
-:10B4300098735FBE34EBDC97E7673EEC80E7EDDBAB
-:10B44000E0A83F37FD6907DC98BAD351FF62CBB95A
-:10B450002F376C71EECB7392230EB86EF32E47FD2F
-:10B4600059E461877F58DD75C051BFCAFC8AA37E4D
-:10B47000A8F519D7B94986E979E339C773A5F94819
-:10B48000C1F395D89EEB3D6F803ED13DFC7B7A7E2B
-:10B490004F2BBF0FCD3D9F355C0FCCC831BF28C2AD
-:10B4A000D75D2DACBBBC7C266A3F3436417E08B7E5
-:10B4B0001F6634E94F1FA5F05B4DB2D14361DB7EBF
-:10B4C000B0EB97FD7B14FC3B7D1F7CA7AFA3FD80F9
-:10B4D000F7B7DF7D4AC07B1E6AE6107EFEDFD90922
-:10B4E000FB5A0A6C69767F0EDEE7936AE0EFC9FAD1
-:10B4F000EBF07D23835FD876EF1A88A3A6BC76FB9A
-:10B50000AF5E07718B949FC12F6F5B3F08EF6BAAF3
-:10B510001275B09FEE2D726EF973957DBFAEAAE6DF
-:10B520004B6AEDE4FDD1BF8824FE37C0B729898B73
-:10B53000E12A6EB8BF1EEE67BE56327F00CF3F20B5
-:10B54000993F54715F70FA05EB20A7B516FFAEC4A2
-:10B550002B2ADA4F87703FAA79EF36FCFE3315A20B
-:10B56000F8A8C5F139A68A13FB0DB1F79B268C9379
-:10B57000A29D37D840F0BEF85475DC82FBFBACEFDF
-:10B5800029E4A00174A7591212CF3B4C5DAADB72CB
-:10B59000E1D89FE09EBF0DF47D30A1EA6087A9E469
-:10B5A00038E65584C938961AD104C73DDA36FD0D00
-:10B5B0008C7ECA9771A04B26E6A1317EDECEEFA528
-:10B5C000FE17CE9737D565C5F9F21EF13EA2D1F12F
-:10B5D000F7533B11F6C5FD5081D2F17494FA9D02E8
-:10B5E000E09988B760BFEC7E08FB7E38E9E4B7F1EC
-:10B5F000DE063B8E23896D9DB83DB730BBAF93FE11
-:10B6000003BBAF36EEB423DDDF9948AEB8CE74E3AA
-:10B61000385521771C47C573E2335D1EBC57B158BE
-:10B620003F763CE7E9AED2FEDCD7F97AFA1ABF17CB
-:10B63000E42BFC1CF7497E8EFBB7E0CFD1F2CBE0C8
-:10B64000CFD1F200F873B4CC803F47CBC7C09FCBBB
-:10B65000FB6EE4B122F7BC5C526DE72B6C41BB3D45
-:10B66000C8EFD9206414ED7409EC742A574F1FED0C
-:10B670009D19A37CA7BE06D2B7F9FA0EFC8E9F0EC9
-:10B6800061C077FEB7BFF1FACCFF1281AF6FD9F777
-:10B69000C3B43EE6494A2DEEEF48CA8C2399A81759
-:10B6A00082D41F481BC5F933ED7E1513AF6C9B7E0A
-:10B6B000BFEC3E9FC975D389F924414EB78F7C07F3
-:10B6C000C739C3FD1922D6FF2FCC8FBA4222A5BE9F
-:10B6D0000F9C32CE34E5EFE365E40FEECA44BB3392
-:10B6E000C9E663E173C7EA0ADD0B61CB61CF6B3E4C
-:10B6F0008CAB0E7D8FFD1D8AA30DF21C885F8C1E06
-:10B700007EB111BF5FE4F2D877D4997F509F244275
-:10B710007EBF0F75B338445F84F5ABAB2C6FC14D62
-:10B720008FFD5D53AA4C3EC3837CDCAF07CDFB424B
-:10B73000A80FB378EFE3C2E7948F00BE8FDEA114A9
-:10B74000E4F3D78389FE50ED543CF3DBE33D14C5AD
-:10B75000DB6F0B2D2BDEBEE519E517A474FB3DA5B1
-:10B76000DA5FF615E59132F83F5A187F6B3FB4ABBC
-:10B770008FB2BF4BD653F7FA81AD14DE7B07F38748
-:10B780008FDEBC0EFFAEC3402D9BB702FD3E510ABB
-:10B79000AF85CF757595C1EB1BA5F9DAD55586AF89
-:10B7A0007F5FAA7DCB335D27CAF0F5BBA5F9DAB57B
-:10B7B000AF0CFEFFB3707BEB62D03BF53A8BC7F565
-:10B7C0003452BE523C866CBEBAD643817E5F2E2771
-:10B7D0006F65F0FA79E979292BAFA74AF3B5ACBCCC
-:10B7E000FEE602E5F5CD227CDD0F785F80BCBE7DF4
-:10B7F00081F2EA0D5F98BC86C225F5405979AD2DDE
-:10B80000D5BE02796D2884BF8F044DB0A7CFB4B0E8
-:10B8100073AFCDED1EF6F79134A6EF8327AFC37D4E
-:10B82000B49FEE53335A61BF3EB5F7F6A593FBB311
-:10B830007BFF71F7E7DE3F6FFF973544A5F022BE2F
-:10B84000EFD9F80462EE7E4ADF2F31DD7125FE77F5
-:10B8500096ECF6B337BDD3E339F777E9281B9FD0D1
-:10B86000F157E33921BB3FB7AAD51D979CEEB8A588
-:10B87000EB476FB9307B607DD8793FD49C2DDFDCFE
-:10B880007F3AEFDEB039FC3B2F2FF910DECF446E4C
-:10B8900063F940E296A7F79F5E92774F141915F26D
-:10B8A000F37FC4DB46F79FCEA33B07711F8C1F5B62
-:10B8B000989718D3AEC4FDBDDC3EFE28DFEF1FE62F
-:10B8C000F6EC3E7E3EB1979F4FA4B93DFB003F9FF3
-:10B8D000D8C6EDD9117E3E91E2E71303FC7CE279F4
-:10B8E0007EBEF05CF73E7C7FA83B83E5B7BA9FC481
-:10B8F000F2D9EE517CFF4CF7218447BBB3CC2EBE6E
-:10B90000E756CC839DA4C3E474DC8BF7BCF4D797D3
-:10B91000B6CB1B92CE78C89CCD01D73981F39C62FF
-:10B920005697332FB2DA74C643AA5A2F73DD47EF06
-:10B930003CA708365FE9BA8FDE190F9123CE78C88D
-:10B9400015879CF19005A3CE738ACB9F749E535CA0
-:10B950009A71C643E6EF739E53CC4BDFEBA83F379B
-:10B96000D5EB8C9F58CE78C8AA71E7F9C455BF7E35
-:10B97000D819FF1973C643569C70C643961D7FC6DF
-:10B98000012F39E68C837C2098C8823E5C9475C771
-:10B990004332A84F7FA2B2F33DDBCFA6F55F0CA3E5
-:10B9A000BFA966AFA2EBBE6F33BBD7BD8F687E0D5C
-:10B9B000F5F067D16FF04EDCCF1CCFDE1F99D43F7E
-:10B9C0003BAF3DF553F06BBC21764FE5EDC27559A9
-:10B9D00092EFF778DF12F2CF23A588534F94ED5FF3
-:10B9E00062F7107AC12FD18ACBDDD47EDD7EC9B556
-:10B9F00059C893F2025E06EA1B1C27CF2F1946BFD7
-:10BA00006496444AF9A753C699A61E7AD3A58726F9
-:10BA1000FC9228BB2F4597482FE0B1F7A8A7E0BDBF
-:10BA2000BFB61EDA192DBD0EED3C979D5D95E56301
-:10BA3000EF3C5ABA9E1DBFD2F97DEC5EADF0B9F76E
-:10BA40008B619657F9C12AC2FDE6FF2F3FEFA4FC98
-:10BA50005C59F59F467E78FC72E3107CCF24BB6076
-:10BA600091C3E1AA4FAF81EF9BB610760E445E61A1
-:10BA7000F7AE961B27D6F6D1CAEEF5D398BCC65AB8
-:10BA80005761FE24DE33562A2EE1BA57CDAB5AF069
-:10BA900047F726FEFEA3BBFECF6B58FC28D6F5B1B8
-:10BAA00092F6CD41BEFF7F89EFFF31B3F4BDBB8F6E
-:10BAB00071FC5F787516DAB57B6F637A5BEAFA879B
-:10BAC000C3609F8D72F9F791CFF85B80AEDB2402E3
-:10BAD000E7C373419669FD8B55928173D02DC440A5
-:10BAE000B9A63F3C5FB6FB176F73DA5B7FB0F91402
-:10BAF0002FCD57FB9E4CF7731FF94E3BF25727C9CA
-:10BB000087ABE15AF52FC4FD149E534B10AFD41EE2
-:10BB100003ED2E99E2A11558A76E7CECF5697F4FD5
-:10BB20002A6DBADA82F673043BEE1434204FE78CA8
-:10BB3000AA96BCFF6D4ABFD35C8F5F9BB21E6FE8B5
-:10BB4000FD4964F2FE2BB285FE964FDEEF596C3D47
-:10BB5000DAF00BAF0EE1772D29D5BE1FD0BE4F8B8B
-:10BB6000948C9B6EE57C1FE6F92D5B5B3A7A5F87D0
-:10BB70007353BA5EF2DB05173C8B71C77EED19BCBF
-:10BB8000C7689BC1BED756171D55C01EE8D78EE0AB
-:10BB90007D71C1FA7427DC3718A472043AD03F6F64
-:10BBA0000F7FBF0BDFABF599149C7FA8F09ED235B9
-:10BBB000D2FCCA61F89C3B50FDE6E10EA85F3F7ADB
-:10BBC0000CDEFB3582ED2575F47807C8D966827FD7
-:10BBD0006FCBE2F72A356435CC5BB858653049D075
-:10BBE000F73ABED756537876177B6FA819F4D74823
-:10BBF0003331597B8A1F85A347359CDF996A3A8E7A
-:10BC0000FD4758FB99C6B326E0311C637FCF47ED53
-:10BC1000228F031F16A90C6FF8CE8C8DC3E988B153
-:10BC200071BC6A26DD017AA6DEC693C210378DB0DC
-:10BC30007164957D0F49C7C7FBA67C2ADB0727F4F3
-:10BC40004E5718C73B13218F97FA7B01F67A7F9CDA
-:10BC5000DBF9FBB99D2F2973BE783AEF3E867EFE55
-:10BC6000F7421B55E777987FAC62EBF1C51A9667F0
-:10BC700056EE1E49F259763EFDFF00D7C62C0E0047
-:10BC8000800000001F8B080000000000000BC53D75
-:10BC90000B7854D59967EEDC796526E126992493D3
-:10BCA000D7E426241021E0000141B19D445454D42E
-:10BCB00088B6069F43409E01026A89169B9B172403
-:10BCC00021C0A02E445E99605154D0C18252ABEE87
-:10BCD0008029C5D6B6A9F54195DA08181501532A69
-:10BCE000CAEEEABAFFFF9F7B93B9934982B5BB9B2B
-:10BCF000EFD3C3B9E7FDBFCF7FFE738631C6BECD9C
-:10BD000081FFCD8B61212BA33FCAFB1258283F2C0A
-:10BD10005F9AA6CF7B72F4F98211FA7CEE587D7F90
-:10BD2000CE4B75E55F5DCF58870332A2D7CA0A2094
-:10BD300039F2A0B52496B1BA8C1A2B83EFE7EFD174
-:10BD4000CA991DF3B9528CC09C8CB5960A81260302
-:10BD500063C115350D79858CADCC10189321754DC7
-:10BD60001FE2837ADFE2DF0FFBA6DBAB180B0D6768
-:10BD7000ACA9CA4F6963550B0B59185B953170BB61
-:10BD800000B6837ADBAAAC946EA992A8FDA62A1706
-:10BD9000E55BAA644A3754E553EAAFF2505A573587
-:10BDA00091EAADADF252DA5C3595D2BD552554FE1F
-:10BDB0007C5529E583553E4A9FAD9A47DF77555517
-:10BDC00050FEE9AA4ACAAF1E23DD5E02F0D959A58A
-:10BDD00050FE89AA064AAB2558F77828BFD2E3C29D
-:10BDE000F2DA2B596930CA3AAA2503D55B23012C14
-:10BDF0009318B3318F6006B831C8EF00B80D553CC9
-:10BE00003516C827DFC1088E432B3C356680B33416
-:10BE100085E7D7E138D0AE92312FC376B92CB02365
-:10BE20009BB19C06F69601F2AE7CA9CD98DD3BDE77
-:10BE3000F5EA7850EE12A89C05B0FCB8D97B839443
-:10BE400084FD312A1F16EA1400DDECE2B742350EFC
-:10BE50001867D41B811A23E4474E56044C630BFD2C
-:10BE600082AF00F12A14E338E75608D48F5CC80487
-:10BE700001E61774713A585D04F0095BB7EDFC36C2
-:10BE8000161AC758C38AE943D800784D29157AE9AC
-:10BE900011FE8BF786D13FFCD710120E1A619C73EE
-:10BEA000406F2CBBFF7E2EDEAFEF675430A29FD2D7
-:10BEB00081E73172A7BEFD458188F640D7C81FFDD6
-:10BEC000B51F76FE065A6F7F747CCA5C56258DEFCF
-:10BED000CD8BE77FC042898CBDED90080F09D73527
-:10BEE000BB10CEF03705D72B6630822BA03B540613
-:10BEF0007913FCAB09AA8A0592978DC65456538FC5
-:10BF000097C561EA55F325947FDDE45B83781625B8
-:10BF10001FC3F920D9205FAFBE08FE9986F9AC0691
-:10BF2000EF64C8FF08FE792963374A23A62A90FFE9
-:10BF3000CAE4132A61BC3DD942603BC07B79CE582C
-:10BF40009203B58E81F9B34EE5CF9EF549255E0388
-:10BF5000F4935E2E8D453AEAAFDDA3E5CFBF3E0CEC
-:10BF6000EA294EC19327F72DDFA5D2F1A325C214EC
-:10BF700007C22193D3B1B69EC8FAB0EE5DB86E93F6
-:10BF800093AF3BE996124A73775D632D1905EB8BEE
-:10BF90001F980EB644AC2303060A46C1FB499C1702
-:10BFA0008C93FBC67C1BF53B63E07E1B55B9773E4B
-:10BFB00020B00EC4B35841F236E9161FCB85753553
-:10BFC000A40A0107ACABE19B7B1BB2111E070492D4
-:10BFD0000B49B754305F41DF71C5DCEE6A01E9F20D
-:10BFE000C07C26C3F8165705530A30AFC96B9F01B2
-:10BFF000E7932C495750CA025EEC3F79854FC171D7
-:10C00000CD2E3FC1A521B5A7BE0DBF6F080924DF06
-:10C0100057CAC06F064A9903F9BE82513E23F561A3
-:10C020001A977D0DF39900FDE0BF01C1960CBF1773
-:10C03000E541C345CC8372C496CF8ACCD928A60EDD
-:10C040001B50AED91E609E269C6FEA130ACA23E5D8
-:10C050007246F80605C7107E30BEF526C0677ACB5B
-:10C0600068E20B5B6EC880EBBEDDECEB427C6AEBFA
-:10C0700037BB3A091E0DDF184BA3E1E537AA9CCC6C
-:10C0800044BC45C1476C3C97D75F9982D7A01CDD63
-:10C090009324B0ED86BEF52C6ABDCDCEE97F94E544
-:10C0A0005EFED4CADFC64586F173FA7933CD3BF71D
-:10C0B000963B87E07AFAA383552A7DAD1BC2F540F3
-:10C0C000EEE43BBD08EF73F05F5394792C182253D4
-:10C0D000BD9EF53B059D5CBAF0F989249F724F35F2
-:10C0E000927EFF2A7B607A6D50E7F955A6DE3E10FE
-:10C0F000725B08CFAB5C804F19ED0481C5011C5BFE
-:10C1000055FA804F84DF20E8A726C07FEB8AB3B6BC
-:10C1100002C867BC6D4432017A98A7A01EB15DC405
-:10C12000E941923BBD0CEC9098FC6EA2C78C8A4E04
-:10C1300003A680F7BCF8F1480F1374F47046D59F3E
-:10C14000F057E79AA08A3299F8BE201EBE7B77C1CD
-:10C15000249CC80F7C7C13F32A669217952C08E365
-:10C16000DADF32D2779861E8A142945382A7C903FB
-:10C1700074D05E938C7C684FE2F265DE35C524BFD7
-:10C1800000049E4D30E6E24FBB929740DEE3E27240
-:10C1900019EA5B719E628159A737061D47F48670C4
-:10C1A000FD7603F3F83DFDC3FF3BF76BF532948F4B
-:10C1B000DFBD5F10A4C968DE7138323655C175DB4A
-:10C1C000D5755BD8AF689C73380EC2DE98F13B849E
-:10C1D000AF78B1C88C51E8B5DF718C770CA83F2AD5
-:10C1E0008FCEFF637B58FDD9F1B1CE2E9804BB846E
-:10C1F0005DF22D128ED12120BFA21D40F607F20064
-:10C20000CCA3BE82E363F44B8753C3E9FFABAA79A7
-:10C210007F6C07A5B947D5FBD51F5A8AB1FDAA5F28
-:10C220000B010BB46FCF34A777C2F7E08143D93845
-:10C230002F4D3ED7B6EBF57C46053384F7FB98CA05
-:10C2400017B54EDEAFECF058A3F1FB5AB55E836331
-:10C2500060BB61A33AEEB3766F753CD175C880FCC4
-:10C2600039FA25EBED38DF2D4BAD51E1FCACDDD7D4
-:10C27000189FD4779EE1ED118F03B45F3F50FB828E
-:10C28000E7ADEFB381DB3F163FBEFFF6239EB66EF0
-:10C290001E64FE6DD1C7575AB15D86CBCC90CEAB34
-:10C2A00053BBB6AF86FC86A5668F05E8B37DC68F07
-:10C2B0005D88B7FA248EB728FDEE1A685EA35F2A60
-:10C2C0002D1D645E7B076B3F085C5F1E18AEA547A3
-:10C2D00006816BFB40ED473C5DDA32C8FCDF883EEF
-:10C2E0007F250BE54E866C263D539D0D704539AE7E
-:10C2F000C135821FA2F4FBEEC07019945EFFF63DBB
-:10C30000E9F5E381C6BF007AFD7C60B80E4AAF5FF5
-:10C31000F547AF38EFEF41AF42C2807019945E63CA
-:10C3200012BE1FBD260CD4FE02E8356DA0F95F00D9
-:10C33000BDE6441BDFC2EC5E05EDA202AEC7E71509
-:10C34000095CAF4B5CDEDB8F5E4D7AB40EF454E2D9
-:10C3500044D4D7C7362C2EECD5CF91FA27B2BF489C
-:10C36000FDB9F8EF57919D3B46D57BDA7C6272238D
-:10C37000FBB97D40FBEEBB8E2BBA58C816D7DB3E0F
-:10C380006DF6BF7A3CBD7E17DBF9F80CC6BF6222A2
-:10C39000EAD5691E84F79089669D5DF9DDC71DB8F1
-:10C3A000BEEB8EEF670FCC49007B6064AF3D905EC3
-:10C3B000F98BD61389BDFDA48B254C72A0BD778B5C
-:10C3C00017E9829533CF0E2CAEDCD37A625CAF3D99
-:10C3D00000F037DC14B66F3496075B4F84ADFBFC7E
-:10C3E0006CA6EECF14B27773A54B49BF0FA6C7B5A5
-:10C3F0007DE326F44F0D477F94A4FAA35CAA3F4A3D
-:10C4000056FD50DC3FD58CFE29F2834DE47682EA5E
-:10C410009FAA57FD532FABFEB19754FFD8FEAA0039
-:10C42000A52F54EDA4746F5590CA9FAFDA4FF960F1
-:10C430005588F2DB1E9823233E7BD7E155D7A1F91F
-:10C44000F506B6FB332BF47E90F4797A3F482AFA4E
-:10C4500023C3F229E1FE4886FE9B1C5DF9908923E7
-:10C4600074E5B19EB1BABC3DFF525D7D9B5CACCB27
-:10C470009B9DD7EAF217EF9F1EE1E7B94D573E7239
-:10C480006759841F6781AE7C78CB325D3ECFFFA0B9
-:10C49000AEFED0861A5D79B6D2A42BBFBCFB615D1F
-:10C4A000FEB24F36E9EA4FEADCAE2BBFE4C8D3BA9E
-:10C4B000F2F11DCFEBF2E30EBFA4AB7FA3DDF76B70
-:10C4C000948763420723ECF400C9D310C80ADCFF49
-:10C4D000B857485778A3E0F1BF86F07D2BD8ED45DB
-:10C4E000642F833C6B1A83ED95121BE4D37F0D34CC
-:10C4F00027E396DD676043216DD7CB1F63F977E3B0
-:10C500006BF400607D37FC215FFE97B6AFDD6953A9
-:10C510007E80E3FBB83C56A4008BD64FAD6AFFE6A5
-:10C52000EE9C3184E8532A96A2C985E366DF27E1B1
-:10C530007A4674E8E934D71BCBBC385EB9E637E3FA
-:10C5400072CFC8ABB0F4A3571F36A09FACF4D57818
-:10C550009CC73675DC06955F57229F0EC7F55E16A1
-:10C56000B2A870DB04F29919277B06925391F0FA76
-:10C57000AE72CD90A8976B208F431FA1FC2E17039E
-:10C5800003EDAF347996FBD6DD03E24783AF8647F0
-:10C59000A3245D81F2C196ABB032475F3819654E76
-:10C5A0000FFFDBEB9623D67D8EBD5CE4C5F309E679
-:10C5B000894A273DEB2DBD8BD6A1E133B2DE0E5566
-:10C5C0000E3FAEE2B54D95C342B347403BAC5595E7
-:10C5D000C7C2A3DE1A84731EECA7713F686EAE0853
-:10C5E0005901EFA60C467AD2E804388CEEED77D8E4
-:10C5F000A37ABF4B6EB35E2EE6D425E8E021AF48A8
-:10C60000FB4EFAB42FDF5D46F68D468783F11F920D
-:10C61000FCB743FF99712E8CBFDB672753FF0FAA2E
-:10C62000FC0D1CCD5385BD89F4533651252026DFE2
-:10C63000FA3EC075FE611343FFCE0FBF6E3DB415C9
-:10C64000D6619C6891D0DE014D78E815289FEDB544
-:10C6500096607EFED151663794BF930644E0C2F2E5
-:10C6600092389403A7993015FD77A7D99B71E3C23F
-:10C67000F4EEB244331FB7C174ACD38AC32B748EAB
-:10C68000758F9FE7B575CD6DD1E7E7B0E9C9228C0D
-:10C6900033E751134852189789C73A353800FECB13
-:10C6A0001225EA772EAB58897644BD89917F71D1E6
-:10C6B0008BA3CC683FCF1F27651BC7F4CEE3C144D3
-:10C6C000EE673C09F42687F98B173802662FB43BD6
-:10C6D000BE77DC8F2F63D84F60651AFA3BE3C11E2B
-:10C6E00091FBC27756837E9E83AD2372DE8CD590FC
-:10C6F000BCEF6F1EE24E833710852F1B12B95F5DB2
-:10C70000C363ADF567AD9D304F6FADC86C3F80BC66
-:10C71000C8CF9994A3B1811D28BF8B2B9EEC44BF39
-:10C72000748D45AA8574A3FD67CF61FD4A4018CA80
-:10C73000CB3D8932F7ABDADC013C7F60ACE292E9B9
-:10C74000B1DFBFDF17B0DFA47F7DBFBFEA67BE8B5D
-:10C75000AC9D66E4FF2562C55483807E453EBEC520
-:10C76000E4F3A6A33F717F51289DE9EA355C60BDE3
-:10C77000C3869C0BAA375518A0BF33AA7CFBCDAE4D
-:10C78000C7CD28CF4E3FFDE10DB82F5AF82B23B36C
-:10C7900042BD33BB625988ECBE8019EDBE057B8D6E
-:10C7A000DE00E543136E8E0DE7EB5AEA7FE173B1CD
-:10C7B000B4AF5AF0BC25300DDA2F78E1F86806F2F4
-:10C7C000E04C4DF7A17484DFD306B2A399D239FAB5
-:10C7D00066F8BE4064779744B1833F48E476C7A9C2
-:10C7E0005FDA4B91DE0C3B0FDC45FD066F3559C21D
-:10C7F000F4D8DB8926AD1EF9BD95A70C813C039FBB
-:10C80000DF4DA3C2E757CDEB3DC5FDB90BF69B024B
-:10C81000369CDFCE36B30FEA2DD9F977A2EF2B9EE7
-:10C82000DB1D877058B2DFA8936B0B9FFB66E5A5F5
-:10C8300080E78546D63D8DF4F8D7943FE7B5761B63
-:10C84000490E79E30C20B71693C8827ABFF8F8AA8C
-:10C85000F7A1FCA4CBC86C200A4E767C64FE15E6DA
-:10C860007D8E0A5049D0BF9E0F97EC3C6EC6794929
-:10C8700002EBCE0046FFC117617CC9FAD667ACDB7C
-:10C880008C727649B0F1EF46A0B7257B4FBF877415
-:10C89000B724829F4FE23F52FBEA4BB333525FBE55
-:10C8A0003101FDE66C276C8226F5AF2F35FE5EB8B0
-:10C8B000FBDC3605C63FF5FC67DB144079F97FFFEA
-:10C8C00063DB4F61FEEC559B847269C9D36FC7B1BE
-:10C8D00030F8673BF939D399A79E7C6213C0E1CC4D
-:10C8E0005F2C04B533AF7CEC96D10FBFE73F92F1DC
-:10C8F000DCE9BE57AE4C413ABB6FDF152903ED2B87
-:10C90000906E039670FC0608BFF27E182705B22FC2
-:10C91000AB69045E4EEDF9CA8CE7095F1A5837CA55
-:10C92000DFC5C16FCC78FE70C8CBBA114EAFED3DFC
-:10C930007EE841C89F063C59A2E009D69F2E905E32
-:10C9400001F68174F1DE9B6FBCBC10539347463CEB
-:10C95000B16E92F77DF0FB16E0B7B017BF91E5E737
-:10C96000D8D76684FF925D80CFD18857C0E7E8BEF4
-:10C97000F83C8DFF98D4179F5EA7DEBF7D8E95B7DC
-:10C980006EC2C2BD8984FFFEF0B968DF8F06B4B302
-:10C9900034F930189CE719F8BC1C4E6F893309E94B
-:10C9A000C2AEB8389E03D3A0ECCCEE736E0674F220
-:10C9B00089A9FB2E8443F72B1609CFC916BCF22E8A
-:10C9C000F1DD997D7F3223FEE12FCE3001F2ACE71D
-:10C9D000EF4D06F9C5DC06678B58F755EF1562CAAF
-:10C9E000BA150FE18FF287800F091F819BA6CA2815
-:10C9F0007F0349B4EEC501CE1F8B03076E318CEE69
-:10CA00000BF726A7A0E9AD1EBC1A26223E3FBC0AA2
-:10CA1000E9AF3F7C6AEB9770FD9740F9CFF5FC1BBF
-:10CA2000597F31F02BEE8FFAE03770E00F989E6956
-:10CA3000B38806B085CE9878BC4724DE7BE1CFF57D
-:10CA4000F377B58FEB9C91FB02DE5E83D360FC3EF7
-:10CA5000D8FABE2BFC963965EA37128EA7BE8EAE89
-:10CA60000F02AAFC58CC2AA6A60DEDABCF4456A2C5
-:10CA7000A467F7CE7765D04872FED44EB0C70D7D5F
-:10CA8000E5C5E27ECEE19F75723B66F1FE03A351E0
-:10CA9000AE9D3AF84B952E39DD2FDEF5A15951F5B3
-:10CAA00043205C3EF7733EBC5F9DF79297A3F7B7B8
-:10CAB00064D7DFA3F67752F4DE8AF33FD961620AC6
-:10CAC000747132689C1ACDEEDAEE34E9ECE795B178
-:10CAD000138E0C8176C6B81819D75D5BE37D57417C
-:10CAE0003BE64D139DFF33D1F38905CA6B63636445
-:10CAF000F4E7D5C6CD6172981EAF8B8093E82AA16A
-:10CB0000F355D15952C8F77401DD39B00908227CB8
-:10CB1000DEA07733502F7D30E66313AEF36F1176CE
-:10CB2000E4DF44B63205FAFB9B62F054CBD1F60742
-:10CB3000FAFE7D2B8C4C0EEB7FB1A5FB03F2C7FDFB
-:10CB4000BB8DA15D667CD5664079B2649B89F65D3C
-:10CB50004B601B8570FB78AB2DA0407EE32FAAEEC7
-:10CB600042BDF4F9360B9EBDB2D7F62DEF7A00E543
-:10CB7000D26603437FFAE7BFACFA12F5F2FC2D460A
-:10CB8000DC2AB2B9F6EE27B0FDDCE7D2592DB4FFAE
-:10CB9000CC109C809BD9AEA4D004DC8774ED4EF5FC
-:10CBA00028D4CF8B8BB1DF33CFD9A9DF33FFFE2E53
-:10CBB0008D73E6DF6349AF69F3077B5B0ED7E360F4
-:10CBC0006FCB3D7C40F41A96877116629ED7377CF6
-:10CBD000ABCA3C947F0B3105BA5FB87F8817F791D9
-:10CBE00061F5A89F2596EE9F7868FFADA409B477FC
-:10CBF0000AA5213F2EDCA91FFFBF5579B7C4DC3D34
-:10CC000087D7F7A771BEEDA076F624955ED5F2C85A
-:10CC1000F65A7D5B528EAE9ED67EB1855544E38337
-:10CC200064B5DF853BBF19AEEF4F51BF478EC3BF21
-:10CC3000DF6F600AEA67B6C746F169E5E6D0B0047F
-:10CC4000E0DB17CC6C1EF26F795C68583C8CF72BDC
-:10CC5000556E96C7401EBEA7A9F3C0FA9867D6CEF8
-:10CC60003388D7452FDAE85C65D10BEF7E89F83C35
-:10CC70008530068C9D4AEAF8F2A74007A7B61A99B4
-:10CC800002F6DA224BC8BD19F5D41E0BDB8EFCFD73
-:10CC9000EAEBA4B74E3F6F11C2E3E222D34541A0B5
-:10CCA000066BDF7528C52CBF02E6A3ACF70A6DB88A
-:10CCB0006F386C0C54C3D895A2B7E6395CDF6113AA
-:10CCC000ED33CECE66F9B8AF3CCBD23C0AE15F7E05
-:10CCD0005784F2E5BF35199AA28C6B3A0F4A7F1C34
-:10CCE000F0C1F9EB983C0EE3C08652BADC5C311C13
-:10CCF000E5AE5182C51590FF81EC7693D3C3E64231
-:10CD0000BA3C81F9107ECC716D0F7FFD1150BAECE9
-:10CD1000313905DBFD2089DBD5F393BDD726917E24
-:10CD20007448A43F543A55F6F1797E6588F154630E
-:10CD30005CCEF907EF46F82EFBD02087C79DF4C6DE
-:10CD4000837A28EEAB5294DF950B69BD248F72A5D0
-:10CD50001886703D2B0974BE7076B63C243E4C2E6E
-:10CD6000AFAE92487E3456B9285D5595CF64F26BCC
-:10CD70007B286F54D76F29509811FA419EC63F8B7C
-:10CD8000A3C48B761ECE09E3828C0E1FD111C6354B
-:10CD9000A11CB33A18ED638D0E85CD453FBF83C30B
-:10CDA000C7E82821F898D5BCD8328DE009EDE9FB19
-:10CDB00094645F4512E0D39A31422797CCCEB1BA42
-:10CDC0007C1F7869F8DFFD7F053746706AACB25288
-:10CDD000BAAA6A22C1ABBECA4BF9FF07B86DE470AC
-:10CDE000BB94C75AF4C0AD5897EF176E8F01DF3868
-:10CDF000C3F906E0887CC3623C3BA2AC3F32DD5005
-:10CE0000C528F8E6E1AA164AB5EF09FDE8ED2F932B
-:10CE1000B81D50C97CD5261C47E2FE16E65458C6FC
-:10CE2000845EFF2673294CC63CF22AE2E5480CC119
-:10CE30006ED95F6DE437364A6257B85C5B76BD9C4D
-:10CE400082F2CB58F9383B9E18E6479B566293090D
-:10CE5000AE1E3AAFAC55F5667D0FFEF47CB0BA4A13
-:10CE6000A6748DCA0FEB547E588F78C6B8130F3F47
-:10CE7000DF6C9ECA482FFE1BE4F93E3EC4C2CF9D24
-:10CE8000E23DC19009F04D3252A63444F1C0472C26
-:10CE9000813C68672F605EA48FF8230F90FF1823F2
-:10CEA00074D19F16AFC28DBD9C133F23969667E247
-:10CEB0007A871979EA37A13D1E09D75ACF412BEE5F
-:10CEC000AFFB9B4FD107F30D38DE5733084DCC79BC
-:10CED00047F008C6AB3A9AEDA457933D1559E8DFE1
-:10CEE00063472D449F0E8FCF30370C7FC9FDD87517
-:10CEF00095C9D79C40FAFB086D25C0EBC32D436D47
-:10CF000008E7D5A6A00BE5DDEA78AE3FE45280C283
-:10CF100025BDEDFEA0CAC1B8423DBF6BF2559A3C9B
-:10CF20005647BF9A5C4D98A2A7734DAEEE4FE2F6FE
-:10CF3000DAFCE4922F51AE269EDF427C1849F7B905
-:10CF4000D2A5A53E27EA01E669427B0D6D46B4E312
-:10CF50003E340438BD73FFD4D9CEECED68E7C0AEE3
-:10CF600080E48A82FC4078EA7EED5B68B75B950FCF
-:10CF700035D6E9568A73043A6214B72E1380F1FC51
-:10CF800090A9F1ED9C3F2652AAD1676672B62E5E3B
-:10CF9000D0987B48407CD5831D4171C5B0BF73E0FC
-:10CFA000F9F8814956B4F74493E730CAA9EE5821FD
-:10CFB000887AB3DE31DD8AE74A86F842C2FB97B150
-:10CFC0006559039D7B82DD427E5BC9E161C7701CB0
-:10CFD000C6C86F6B94C632DC27EE7674C4E0BEC55B
-:10CFE000912CE8ECC4F9C9BE9CE4B0FC281C5DC5DA
-:10CFF0001776BB5BED2772BCD1C9AADF324361DE75
-:10D00000B0738B4A8DBE65854D09E3EF9ABCAB5872
-:10D0100067415FBEEE576EEDF87E72AB362B40F87F
-:10D020003245CA0B27C87107A58A0028352A59AB93
-:10D030006F1F4374558C70608EED3D76C80F73A2E0
-:10D04000D0D791112914B7D9A36760D75C407A660D
-:10D05000E3446E8FA87A86EBA7B3CD76D24F67678D
-:10D0600057503CD5D9E61419E9EEC0DACB46233C3B
-:10D07000E69C6F6432CC6FEEF94994CE6B7984D222
-:10D08000B296362072C6AAD7CC5D3B03DA1D7FCCA0
-:10D09000E841BEEE0A8C3B5309F9AE660B9E11B116
-:10D0A000AE2DF766A15FBC0BC641FBAA6B4B1ED130
-:10D0B0005717C08DF20DFAFA182F6C04BC9431A6E4
-:10D0C000C619CA5EAC3FE775635B343BA96C9DC56E
-:10D0D0001BED7CA7A7BC25BADD568BFF4CC5FF55C1
-:10D0E0000C4778157DF04016AE57E3FFE509208F19
-:10D0F000105E1F5858347FFC94E42B17223EA62460
-:10D100007BEFE5784988EA5FEBA57F3EEE7101ECA5
-:10D110005BC28B2FEE269D9F95FB318FABF62FB315
-:10D12000F6531EA7B697A2972F6AFEECD043905BEA
-:10D130005550518244AFEDA745C6F7D38BF7DFA416
-:10D14000C6F9F3F9809D4A74CC001F285F66ABFED8
-:10D150001E80FB8D78AFE4F8EB4603D2472F3DF9F4
-:10D16000E2D06E31ACBEBE663794FFE330DF9FCDB8
-:10D170003FBF9EE49D61F5A88D93E0FBBDAF9B484A
-:10D18000CE57375DB6EE0EC0EF176F18293FEFBCD4
-:10D190008DEA7DFA9067E31D50AFFBF726B2C3BF5F
-:10D1A000387C25C54D7C6AD2FB092E4BE17CBC5FE7
-:10D1B000E5E739E75793FDA195CF69986596894EC4
-:10D1C000D7D2F739786883C1BECAADBF2B12F13C04
-:10D1D00087D1BD85FDC9B75C57437A6D2CD9FB73E8
-:10D1E000D7583CD1E2A8F727CB3AF933B7B399FA2D
-:10D1F0006560173993D5FEC2E4C8DCF389C4074CD7
-:10D200005218C619CF51E549CFFCB69874F2E453D1
-:10D210005B743FC8E164BE8F9A73FE32E2AFBEEB2F
-:10D22000FB017D9FA38DDBC9F9B1773D1B27455BD2
-:10D230004FEF3A2653FD4FE3A38FFFB93A7E57D500
-:10D240003CE605B95466817A0E1CFFDE95130B711E
-:10D250001DF10986B075CD6D59C8BC61EB9ABB65EF
-:10D26000A6B92CACDF5E3C2CFD5D516E2F1E3EDF5F
-:10D27000507E5D0DCAA3E492F7916FCA565F3E1AC5
-:10D28000E9716E4B23C1F9B8C9E346F9FA71CBBD18
-:10D2900071BEA8F394757A6B6E8B8A1FB0770BC33F
-:10D2A000F0A3E125B27DD75FE77EF910CA9FC7B82A
-:10D2B00071D31FBCFAE02D3B3ADC6C291ADCF299E1
-:10D2C0008FE026BF7004E97A8DDD8374DD3FFC4674
-:10D2D00032DF40F0EBC77E057B474849C27119D168
-:10D2E000E9DC164E0783C1AD775C950E8AA2AFE7E5
-:10D2F0001295DFBAAA2A99020C7BCC3C181DFC942B
-:10D3000029D601D6D14307FFA6A3834B52D6101DC1
-:10D310007C82F6CAF0BEF83F6656E22EC5739F26A1
-:10D32000239D2B1D8B51926FE3F931288F8FC5F907
-:10D330006FC0731A2D3F7F475EDCCCB0713F6E002B
-:10D34000384481DF252911FCADD14FAEC20A26FC3D
-:10D35000EFD1CF71F59C38B2DE94E4A2CB52507F6E
-:10D36000F8A3FB6BB55493D7C6218E9E7D26EACFDA
-:10D37000638E9C2F0350DA94ECBB1AFBA98BFFC978
-:10D38000DD280F8E1D3390BEADFEEBF2E1A8D72253
-:10D39000ED04D87F36E0B9E77263AC9FEC50B1A2E0
-:10D3A00095CE411591ED28C47D4AC5A61379E8377D
-:10D3B000ACA494A976E872E3080FEA6123AB781273
-:10D3C000CF49814824AC2FB20A3A3705415882F937
-:10D3D0008D767EEE5A295A254B585CC252955FEAEB
-:10D3E000AB4A1E39817E68ABC2A4F0B843C6EDAF2C
-:10D3F000FFC47986E97BB3C92779701F6A6025C8A5
-:10D400001726D1D7900DFD9B5CCE314A181E96A4ED
-:10D41000F0F3765B7B7B4336B4B7DDF37B89EE1D9F
-:10D42000C138E867B3668867C3FDD5266790EE0903
-:10D43000B1DCB0EF6057390A20AFF303C07C07B00E
-:10D440000B7F65F0B8BE447AACE6F098882082F491
-:10D450002FB387B6A15C9E28D61931EE68C63D79F8
-:10D4600094DF38EBDB619D51E861C6CBAB3AD09ECF
-:10D4700099F172EA2C3C3F98E118F611A6B05DB024
-:10D48000C640FBD70C2CD804E914EBE314D7F89A68
-:10D49000EA1F6BC77C985E6C57E90DEC9CA97B205A
-:10D4A0009D61F59B9616F4FAD322C7DDA0E2A5DDB7
-:10D4B000144C1A817400E3E03AEE7C39F02350FDFD
-:10D4C000EC8E60E0FA51809FBB58B709E1E8631227
-:10D4D0009D7B687EDD32E651F38CF6A7EF979BB615
-:10D4E000239D44F6774788F777673BF407E95D8724
-:10D4F000BB7F8D6AD91794AEB2B3B0FEF67B0ED95E
-:10D5000059DFFE22E1EC11AD46250CAE8022211C34
-:10D51000EE7DE03BA4F45A36BA7F3EEB85379F4759
-:10D52000243EBEC022E0D3408AF77994C35529DE59
-:10D530005F605A6EED768B4037EF3B7D2F221F2EBA
-:10D5400036FAB292011EA7337DC393102E1DD1CFA0
-:10D550005F23F93BB7F4F456E49BBBAA4586785E9B
-:10D56000B9EFE3ADC897A74DC047B01F78ED818FE5
-:10D5700063916E16010386CB930F2AF3C87E3ABBE4
-:10D5800077F880F1A71FA8FE923FAA7CA2ADF36EA8
-:10D59000644018EFEEBD76DACFDC5D69ECD9672127
-:10D5A000BDDF5DC9E34398D831FA169DDD59A79ECA
-:10D5B000B3F5ED07F71191FD7455F95A89EF45DF81
-:10D5C00004B4BB8F57CD6B45F91239CF3C97EF1898
-:10D5D000C2756ECB4C5DDCEDECE6F9ADE17CA8D517
-:10D5E000AFED47BEBE344C5DA7958FC7E48B8B1C57
-:10D5F00013F05E35FFB385AC1F1AC2E861B0F15875
-:10D60000EE146F8F5CA07BF702EC59FBF617594FB5
-:10D61000EBDF5579053B3E0ED7E7FDCF94F183CF85
-:10D62000DFE452E599DA4EFB6EF3F919DA85B6AF0D
-:10D6300087909DF0D230EECFF80FD52E600E582F88
-:10D6400032987FA3F7FF63BD3030C5E7D9B658A243
-:10D65000C615A5B9443ECFE0A1226B94F9F5E92F98
-:10D6600024B20BA9F7D230BE7E749391BF6B580CD5
-:10D67000ED6BCA2A6B699FDD08F203F541E47C8EED
-:10D68000356DA678689BD92FA35FB4715872760D5B
-:10D69000B403A9467E1F5B8C5F16C3BFABFE205B45
-:10D6A0008D5FC6FD6D635E1A7DD7FA6B347039AB42
-:10D6B000F14523ECFB9E27BF98C7351DE0D2F856F5
-:10D6C000606A2CB4DBBE92858C6EC60EBAD346E27D
-:10D6D0003ED75F6FA6F3BDC67C217536E4E332AD5D
-:10D6E000E41F6B8B0FCDC07B078A4124FDEA8F9727
-:10D6F000AF8945FF6E4D4A07CABF834BCDB4DED517
-:10D7000093F8BD35CBA527FC5760FFF7310FEAD55D
-:10D71000EDE77FD182F7FE9423B09F45BF21760AC3
-:10D72000F268FBD4B336DCCFA5605C1DD0D91653AC
-:10D7300090E6B5A9DA42FD6E6A339746C3DFC95455
-:10D7400091EA070C9D141F9CC8823684EBC353A733
-:10D750006FCC8576D9B94CC2FDFCEA82B3DABD72D2
-:10D76000233F8FD2FC88CCA69E6759D5732ADDFD56
-:10D77000B8CDFEBDE43FB44F0BF274AA40FEE7C83B
-:10D7800079DCEBE27E37FBE48EA9A827EC85023337
-:10D79000A07F3397D1BD66692A58E19066E7B37ED2
-:10D7A000DAF3754B5E685FC8DBA34F48BAC0F60B6F
-:10D7B0005D3CCE700DFAA1A03C60F218AE817904F8
-:10D7C000AE970C8ADC5BAFCEC5F56B2BF41F22390C
-:10D7D0001AA075B9F38321A43777B940785A33F189
-:10D7E000189D0B3C5CA8F9513D348F2DD5EF1C40A2
-:10D7F000FB6BCBFD8CECA42D2843A1DD96EB59806F
-:10D800009F27B134946F9BE69BAFA3F3FC0280BFCC
-:10D8100081D2A8F3F6A55A892EDD2B1E0EE13DFE1E
-:10D82000180FA37713208D5ABF2195C369932990B0
-:10D830008AFE91FEE8E256151FEE4AD5AE627E17CB
-:10D84000E275AD0A1F76CB58EE5F10BD72781C579B
-:10D85000AF3EE17E0C581FDDAB4DAC33933E12A6BC
-:10D860008566E0BA12F2CDECEA6CE42F0E376594CF
-:10D87000C0E3CE58A005F9B3EDA2648A275D250464
-:10D880005CE86F568ACD749E7C70A230631E94AFA4
-:10D89000AB33931F02F2C42F7E6F4E1BF29B7D723F
-:10D8A00071E93CC8AF97CC12C2B7B640B2211DD7C0
-:10D8B0007A05C900F9B525DA3D091683781B63346A
-:10D8C000DAF2A1BC3555401F2D6B351888DFEBBD52
-:10D8D000C5FEA1F0BD5E721AC2FD002FB9F8BEAA46
-:10D8E00022ABE42517F28DF761FF5099E3529C407B
-:10D8F00024467FB12C340F636EDAEA9FA0FB546B91
-:10D90000C65819DAF199F7F9E97E57EC456619F12D
-:10D91000BAFD7CE2485A5F9D59467E5E6F085C8383
-:10D920007CBF65E92105FDEAB68F1CCC08F682A311
-:10D93000F3EF55183FE62834479C633101E5B836CC
-:10D94000AEE3AD10D153A7C1F7E758F2FF1434E5A9
-:10D950003BF11E46CC0484E7DA4BDFCB9F13852EC8
-:10D96000C8653B16ED6521346134CA29AEC79828D5
-:10D97000A586E3777D66DA5FD0CFB4AD08E68FE3A6
-:10D980005576DD41F3F2BEF353B4AB1C473FFD26A1
-:10D99000FA3CDF243D127BD41E124663BA681AD9C2
-:10D9A00067E1F540EEAFCDF29E70017C775773B919
-:10D9B000DF7C0FA37729F02F3F0CBECD0520A5E912
-:10D9C0006102803CD62B90C88FBE4A90832184E7A9
-:10D9D000682BD1538A7AEF2172BDF6A38D4B31EEBD
-:10D9E000C8EED1CFF32B15BFF82726D379055AA25D
-:10D9F000CC9C3ADB86F26FCF583915F7DB0FC7475F
-:10DA0000D7F3EFA572F9B0DB10DD3EFF22D5C6FBE0
-:10DA10000759199A40A86214D707792199CE6DF851
-:10DA2000FB0A02970BEC5A467A2F6E4CA7CD1336A1
-:10DA30005E501D87FEA09F216A3B267587AA61FD67
-:10DA40006D40B578AF2D2E93C3D1A1F4C211EB4B2D
-:10DA5000EABA800FAA8717221025AACF4ACC742EC3
-:10DA600002D250F956E88543AC5A7FD344D1608541
-:10DA700079E500300C503F7EAA59778E22D5BDA3A0
-:10DA800060F94F8D4C4E98D83BFED6312C5003E3B5
-:10DA90000FF1EAE11D7BDF0BCBD12E8FA4039C415C
-:10DAA0004FBF182A3E5BDF2EF98E3E7C40F0A479F2
-:10DAB00002689ADF62DBCD0094E69DA2161F4BF24E
-:10DAC00077BCB143417F28C0AA641FCC7FC4536F89
-:10DAD000797741BED9C7F92C36FF85E54897521AA8
-:10DAE000C7D311F42D039C3733E91F18B7A3540A89
-:10DAF00032E2635B2887F47823134B104F8D15EFC8
-:10DB00000828D757EF651E8301E9FFBF2DE1F39B7E
-:10DB100091CACF69982893FC13DDFCFEE8EA02C1A4
-:10DB20008EF2F5E0D21748EF6D3D2030E4FFE2DFE2
-:10DB30001C7DCC8E74FD170BE59B5FAF20B9F113F4
-:10DB400068A744F19F0FA69723EBE72EDA6EC0F388
-:10DB500089AC79417A8F25D12F7AAE467CCCEBF017
-:10DB6000D23DF7427ECEE6981652288F5A0D6C525F
-:10DB7000D9AFA6CDBC9CDD9240FBA85196CE866B5A
-:10DB8000617E9B9F1219EA4BA325983A17FA35BE7E
-:10DB9000E8404DD0677FB4795A2815E5784C058563
-:10DBA00041F7B5E352391FBAA7C9BF1D06FDC64FDD
-:10DBB000E6B0B4F9530EA0BC449B19EF35D915AEAD
-:10DBC000E7D68A012FC679AFBDCF67C6F199BA7F74
-:10DBD000695C54F604C2F91355EFB18A79F48E8961
-:10DBE0005BE5177B252B8AB6CFDAE88AE1F12D0FAA
-:10DBF0000907903FDC5E46FA43AA0C8686AB7A1989
-:10DC0000272EAD78BE11F58BA35CA075AC153BAA91
-:10DC1000F15D89B5F731A95AEEDBDF3FDB7E79AAEA
-:10DC200085E0B1D1C574EBA0F73040BEB9E7455FE0
-:10DC3000C7BFE1B8E37BD711A3AD23BF93F2DA3CB2
-:10DC40005ABDC10B9AC706B53F7F2A7FC7C85EC0C1
-:10DC5000DFEF8894F735F60FE85D9900D8EA46BA09
-:10DC60008F16BC16F3F27302E3F7B5F4FCDD27AFB1
-:10DC7000D255E47799858D938D74C7F10C74A7DA2A
-:10DC80004FC07756140182FC2DF931FC34CF487A0D
-:10DC9000FC5F978BE1F386FE631B9841BDA72A17B3
-:10DCA000A7F6958B4C958B56A68450FEFD5FCB4511
-:10DCB000908324179B61A589B053896D6F5A8A7A26
-:10DCC0005C9387E31127976227D6EB8B0B685F4441
-:10DCD000F909A9BF6FC6F8C855827ADEA5C205DD6D
-:10DCE000500897AF5D728F9EC2EF1BF01F39F89EF0
-:10DCF0004AC2750530DEC6D29C31B8BFB0F95F2488
-:10DD0000FBC05DC0E357DC95FCFCDC9E3BE789F083
-:10DD10007B714B52B99DBE44A3BF4ABF0BC7598B01
-:10DD2000FDA27CCE3593BEDCCC825C1FAAF6E95600
-:10DD3000971A47ACD255249F44CAA771BF7716A340
-:10DD40007C4F355824DCCFA17E3E98ACD7D7482FE6
-:10DD50009ABE6EE9A889477F58B6EAEFCFB6EAE3E4
-:10DD60001C26A4717926A6723FC02AA182F69B4A7E
-:10DD7000B140FB388DFE7AF478041C23E18784BA25
-:10DD80007202C5C7503EAEA89B21FF6E03925D8F05
-:10DD90007A2C5583BB44706EBB53188BF2724F7B49
-:10DDA000990DFDEB06B7F51ADC1FAE3330BAFFB89C
-:10DDB000AEE84D8A2B69AA849E61518E7C61A6795A
-:10DDC000745F3C031FD37ED5AE583AD0AF150C6DAF
-:10DDD000A7B885A6C0A1198CDBB10CE3529AF26BEF
-:10DDE000D216A07CCF2F2944FCB6D59B296E46CAFB
-:10DDF0006751FD0827711F43F3FD6E7ACCAEED2FFE
-:10DE0000CBA3EF2B6F4CE3FBDBA008A20AE69391B8
-:10DE10002F7890FF33EACC51E751ACE2292D8DDF0A
-:10DE20000F6BAB3F44EFCC00BE026C207CC1F46BA7
-:10DE300092C3F031A91F7CB8347C881A3EE2671285
-:10DE40001F7676085CDE925E5BCBA4DB503F2A1522
-:10DE500066B2631B4D7C5FBEBD40E50BC9DA86C46C
-:10DE6000F65DE93A6E9140F7703227F2F7F5ECE58E
-:10DE7000CF535CD366D6FD3ACA3BA580DFA38F6C37
-:10DE80007F679AA0C2513678683FCDF10878A5F92E
-:10DE90006CC94B6E0BE7D38DAA1DBDD1C5F9744B70
-:10DEA000FD06E2D30B9DA726B76B553B7ABED7671D
-:10DEB0004675A0184AAE4A45FDF973FE1E15333A61
-:10DEC000C82EFF049B84F9652B337C4BD2C2FC72B5
-:10DED00092B742C07A57E2BB42D0FEE320BF07FAB6
-:10DEE00071F01745F41E978F1133CF671D066272CC
-:10DEF00090A13B20EF128354EE9A077389A7DB9120
-:10DF000094B75A412FC2844E57F1FB175DF8BEE417
-:10DF1000707C2792BF2FF999FA9EE4A89655C59B6D
-:10DF2000713C59F4A1CC3889EF4BE2FDE789EF5100
-:10DF30005CF42990B54DF1180FC3EF6F4B0F3249C8
-:10DF40009884F935C518F77CEFAB16F59E64470D3C
-:10DF5000DE7B795C60F48EC46A11F4FD502C6A306B
-:10DF60005484D1F1EECB3BE2F09CEF74F0E601FD7E
-:10DF7000C7787F10E7B143A5F7F5F6C574BF6C8E7F
-:10DF800023E4C6F607F63CF9C42618EFB37D567AAB
-:10DF9000D764A37DB11BCB3F7BEC5D37EA8BD3FB12
-:10DFA000DE35473B9F5C2406AFC27B64E5CA105652
-:10DFB00003F32F0ACE3453FCC9AE03743F6D91E4D2
-:10DFC0003363FFE52D7B283F65D79FDC587E348D7A
-:10DFD000F3C7E9549F1BFD12B92D969000FA67779D
-:10DFE0008E7F41D47376951ED7DB5FA5FE37DA5F4F
-:10DFF0003D847839FD9885FC6E071EFB0DF57B6A24
-:10E00000DF8B34DFCF76BF7B17DAD3E58C79509E78
-:10E010009FB6A97E3D6B475CF8FEF615151E5AFEAD
-:10E0200074ACBA0FCE18A49E7A1EC31C007FBA3FF0
-:10E03000D01187F70B3F33F9CC088F85080F488B39
-:10E04000000E28F717060D34CF852D6D74DF6AE1B9
-:10E050005EEE1F5C08F022B8B41CA0F9BF8F7019E7
-:10E060008FEBF8B39BDE75D86BA1FDB3B6EE850ED2
-:10E070009F1BE1A3AD17E0C0D7BDFBC2F03447C37F
-:10E0800053CB9F685EE57BF9BCCA77F179CCD90B9D
-:10E090007872209E6612FE4FED6332DE83E9DAF37A
-:10E0A000EE49B4674EEFB3CA685768F3CA00711BF4
-:10E0B0003716F988EB63B6D740FA98891D749EB37A
-:10E0C0004892247C9FA0A73C600E7079DA519C0E88
-:10E0D000E5CF3C0AF62142420A8E40FFEAE934EDE0
-:10E0E000FE4F871BFD62BB2FF7137D7E1AABC25B11
-:10E0F000EC7063FCCC8674DFE9B4B07882D31FBEC9
-:10E100003802D7BDDC58F19B4C1CE7491E1FFA555D
-:10E110004EC5DF1EA2790FD59D3746A600B7383C05
-:10E12000FFCE17988FEE25EF7D2D26FC1C5A48E771
-:10E130007EB78DF60FE83EE2697CE791E613A438DE
-:10E14000AD61DE32379EF37DCA1C3E3C97FDECE7A5
-:10E15000AF51BC4D57AAE67FEAA07AA7F6BE9680DB
-:10E1600069991A0FCF0237931C03383658C7469364
-:10E170008FEAFDA200BF3776C6000213F5C4560D24
-:10E18000CE15E6E9BA731D2E4733B664B793BF25A3
-:10E1900010FDBE59A4FCCD7D74129D2B9F63D1CF81
-:10E1A00095991A27B7DC1843F1371BED3FA3FBB74E
-:10E1B000958A45C2FB2BC754B97842BD97FF554C91
-:10E1C0009C2200DDEC4FF7E5A48FEF7B0FB76CF5D9
-:10E1D0002237C2B70CCF3D28CEA0ED7A8C27EC4A6F
-:10E1E00062AADDC942043F9356BE9197C7F3FCA4CF
-:10E1F000CDC135F81E26C297D77F829767F3F21FED
-:10E20000A9E573D24AC6A473FF0EBDAFC19829BE5B
-:10E21000CBCA55783478F4C245645D9A5D0D95E7B4
-:10E22000E1E5DC24EAEF32EA4F84FE467DFFFE00A2
-:10E23000EF8A35E15FD08FF55FD54F90F492E0C360
-:10E24000B7AEE09B87EBBFC78B99D414FFFDFBFFF4
-:10E2500067DB2F377A854F910E870844F71A5F776F
-:10E260003D367C0CEEFFCD0D4B43A836BB628BCD0B
-:10E27000A9F0FD9CCCCF4FEE79743D8B164FA2BD1B
-:10E280009BD19357CFF1CC43F5E7B3ABD3B9DE596C
-:10E290009DDEEB7FC373393CAEA28D33FC35275333
-:10E2A000280CB7D3598580F187F9ED567ACFF7223C
-:10E2B000068202E63F928504D4DFA35827E52F4665
-:10E2C000100CC5F7A8647A38731CEB768B43F1FC0D
-:10E2D00039B412EDB4F79DBEC67418EFCBC73A3E01
-:10E2E0003040F94FD27C2F75A25F289DDB570EF589
-:10E2F0007D5C0953A043C13ECD154DEEF7C05312CE
-:10E300004F859FB7DD287A1F49A7F564485DF65E03
-:10E31000386BF26081FAFE92D6FEE4534FE2563734
-:10E32000ECBD70EF80F781E754CE7FF4E7E3062879
-:10E3300057E5ECEEEAC06DE1FAFEC974AE679F4E98
-:10E34000177476218C4A76DCD33771FB69F7E5DEEA
-:10E350009AC751DEB618693FFD69CB9FE9FDC773C7
-:10E36000258CECBAFEC6FD3402EF9FEE78328D9F0D
-:10E370007704F4F1CB4FFC724478BC258059764E7B
-:10E38000E0EF7010DE0F79148B91EE39923FC6CC1E
-:10E390002A789C0ACE17D218DC8F0E453C75501A8D
-:10E3A000C7BA29959844FEE904E6A1D4C94A284D84
-:10E3B0006615066EDFF9294D63414A33D03E457F2D
-:10E3C0000FEBA654C61B9F61F11B3978623A14DF2C
-:10E3D0005D2DE1DF23E28344C4E3B828F23C222E22
-:10E3E00048DC5949F21CE382F29C7DDF53D0E4F70C
-:10E3F00086F4E2F7906EF6A77BDFC7F4F0B3BFE5D3
-:10E40000F72BD618C8BE3E6E9B66960175CF247852
-:10E41000E91D104560253B40BFCFD6FCFFF8A7C5DE
-:10E420000923309B4DA7C2E37798D5918FE7C5B3F9
-:10E43000D4AAB3D4739059AA1F248631F59E9E871F
-:10E44000EEDBCF52CF1F6645F85F98DFA2F3A3281B
-:10E45000F80F58C72CBF81CE0D66C54C7BB593F520
-:10E460004F2761FDD1BDBFB2083FD4A0FEAC88FCF0
-:10E47000ECC8F65603B326E3774E4FCFFC4026BBDD
-:10E480004EF36701C1C9D4AEC1F221F985FC577AB8
-:10E49000C3E19490C1F9C4E6BF3A2EDA3BD95A3AA7
-:10E4A0001BEC335342DFF6B0238C47BED7E4B046B3
-:10E4B000E7D9B8B1453ECA3707068A4B5DADEAFBDE
-:10E4C000A687FC0CE76D0B3D40EF54DF9FA990AF92
-:10E4D000D65A10A0FB0131F9019712657E4DF8BEA6
-:10E4E00033F05753ACFEDC64A9BAAEA519DC7F7BD0
-:10E4F000E8A2E4623CCF5E250B746F7895BC8CCEAD
-:10E500005907FB3D815AF57704B4FCCAC46D0CED84
-:10E5100036DBD7AD0CED499B18FD5ECA0C75FCF5DA
-:10E520006AFD8D89DBC84FD290C7CFF723EB1FC898
-:10E53000DBE042FBBB311BF6BB983EA450FFF579F4
-:10E540001B4AB1BD35D4A8BBCFEBCBE0F6AD752FE0
-:10E55000A74763AE399083F420FA29BE40ABD7D8E1
-:10E56000CF79D2F56AFB265380EEC934A9F6D0D212
-:10E570002DB16BC92F97B1FD08BD6F95CBE8BCD10C
-:10E58000167A8ACE11ACF9666683BC55F6337C5F89
-:10E59000C3561024FCA0B329A4A3DB98DE77368CE5
-:10E5A0007DFBAFFBD6EFC2F53566FB69FCC1D65BE0
-:10E5B000ACC2B351D5AF8D36FD39DAC20CAE57AF10
-:10E5C000CDE0F2DEFA32237932005CC8DEBB3E23B6
-:10E5D000EF06B4EFACFB0785A3AE7E362B1D128D84
-:10E5E0005F22E5BFA340887847C940F33AB7D7A078
-:10E5F000BEBBC8DFB1E8B5038266ECF7D75BCA0ED5
-:10E600005E03F359E07378317EF2C92DDBE99EFE9B
-:10E61000C2174D149F30AC732697832DFC3D46EDF9
-:10E620007DA38B5A2CBAF7A416B1B0F71A61BC853A
-:10E63000473F3DCAE89EB1FEBBF66EC06AFC10259E
-:10E640004E2DF2DD81473222DF5D56DF1D2888EE38
-:10E65000A7897C7760575020BDB10CE358691FB083
-:10E66000AD18F73D95470DE437E8CB87F2D65C53FC
-:10E6700058DEE0217A546263BC3BA2F0D37B999CC4
-:10E680005E76E3A11AD9FD3F5B1BC237BB581DC3A1
-:10E69000F3A6DAFB4409CFB56B033174BFA456125D
-:10E6A00002183792195B6C45FF238B1724BC8776C1
-:10E6B000957132DD7B32DF2F8EA3775AB72FE8C0FA
-:10E6C0007B75B52E91211F67C6F33802962AD0FBC1
-:10E6D0003475D29BF1B3701FE7E0F7F4B2241690C3
-:10E6E0000D68D779199E2FC366A52204A657A6C127
-:10E6F0001BC2F7AED8248BB483BF3373C39809E42D
-:10E7000007A6BF036D57855EC171BCD612C4FF94C6
-:10E71000FB9D640F065C467CDB947D9CC1CF05CDE0
-:10E72000B1C5A1BFE2FC66D8C9B71B508404C4C3FD
-:10E73000EB6D2BA75F0DDF4D0191E21DF2BFA9BD6F
-:10E74000ED6A68DFDD66A6FB161A9CE43A51F77E97
-:10E75000837B853E6F8E78AF426461E5903FA2CEA9
-:10E7600083B152160A8FE3757AF9A1BBE4A0F729A9
-:10E770003E02FEA4F30F35FF9E9ADF69F213DE77A7
-:10E78000FED540FED5836D73B2485EDA17B7DA71F5
-:10E790005F78849F63F6279F7766C8DA3B0936F572
-:10E7A0009D0A1BFABD22E9A9AE8A7930CED01A683B
-:10E7B0008F1989F83D6CF2605873BD2A1F45079781
-:10E7C000E31ADD44A6F511F4576FF2E4FBA17EFDD8
-:10E7D000374675DF78FA86D0640C7B90695F6DCA26
-:10E7E000601E640F93B3234D82798C7CD1ECC1DF22
-:10E7F00055B8EAB9822128E747BE3683E41BC289AF
-:10E80000DE87AF347BD04EB6543A3DE238ACE720D9
-:10E81000BA3CEB30933D2456DAFD647FB54D70C9A8
-:10E8200061726F6595E4114DF47B3794AEEC47DE71
-:10E8300067C50B25E87735ABF672B2BAAEE44C3B50
-:10E84000A5496ABE5554A6233DB702DD60DCCD81E3
-:10E85000159CBE97A55A496F2E7B7D68CA40FEC1A4
-:10E8600027AA5C9E5C00ECB61565E4B72D7AE044FF
-:10E8700023D2DDB258AB8474688C1BB67132D2FDE2
-:10E880006F4D74CFB33676823C2BAC3F63DC4417BC
-:10E89000C2C328286948CF233383378893904E9486
-:10E8A0004D789F7FDCD68D3788205F76C62A6978C1
-:10E8B0005E76D9D6CDBC3C49D96480F22BB6B6F28F
-:10E8C000F24C254D80FC755B1FE7E579CA26CCDF4D
-:10E8D000BCF5495E3E8AEBA3DBB73E7303EAA35A5D
-:10E8E00093A714FDD3CFC2FC0BF2F09D549EDEA97A
-:10E8F000C2452B7F1EBF9BF05D559E4696BFA0B6BE
-:10E90000DBDF4FF94B6AF9CBFDF4FFAADA2ED44FC7
-:10E91000FB836ABBF67EDA1F52DB1DEEA7FCB76AEB
-:10E92000F91BFDF4FF07B55D473FEDDF54DBBDD5B7
-:10E930004FFB77D47647FA297F4F2D3F1AD1FF0737
-:10E940006AFD4EF5BB3BB6E13DB4D7DC20AF509E2F
-:10E95000E4C73690BF6B5B6521D17FED78AEFF35A4
-:10E960007A77ABF702DECEE471A56F6772FB66794A
-:10E9700026B70B8A1EC85D3719E9F0F7FC9E22E81E
-:10E980008F23780F57794020FFDEB2D7F9BB32CB07
-:10E990001E1075BF1FA4B5D7E61F50E759A7A64B99
-:10E9A0003273689C6CC5E59916A61F4D923E6F05A3
-:10E9B0007EC2F8FF3A27D733F90F1437E0B9492D53
-:10E9C000E8195C5FBDC31C42FF57BD2452799DB35B
-:10E9D000D88FE7FD8A24921EAA772684F0BDE6BA76
-:10E9E000BA42DD7B9F759248EFC788F153ACB31CE8
-:10E9F0002837A649283FEB98945044E76AB04F4324
-:10EA00007D52592CA1DCC98E7726A05C9E95C5E16C
-:10EA1000DE1EDB65C37B14E24302BD15304C128958
-:10EA2000DF73EB84800CF368979691FF7547B37A98
-:10EA3000A6C8F879A226E777FEEC2AD263B5A0C76C
-:10EA400064D2636CC898E4DEFB9BE2D19166D45B30
-:10EA5000529A9199402E1FCA4CA071773CCAF55624
-:10EA60001EE82D7C67ADB590F177DE5C56F2EB9633
-:10EA700089CC9518E6C73C946954DF47E2EF50E72C
-:10EA8000E17B8861F01DEAD7EBADEC41F4565625E9
-:10EA9000C8CBB0FA1697A4CB3F97A9BEABE4611ED2
-:10EAA000B46FAE7A6E0BE993B3A84F18EA973FC4E0
-:10EAB0008C44FD027AC4C2FACA414D1E6B768B2685
-:10EAC000A76B55BD511BA1370697BBFF787D38D189
-:10EAD000A7A07B87A63FF9BB1CE304005E269F81AD
-:10EAE000F40A137D74BF7F30B8994C2512DAE383A2
-:10EAF000C1CF94F4453CCA69934FF49C88724F6A25
-:10EB000030F86AF5CCD6F4ADA8D7BE38BA3C1FFDB4
-:10EB10005E2B4D1D337721DD1A86D0FD0E59F53B56
-:10EB20006CABDACF8EE7E1EFFABCBFA56E1CDE1F3F
-:10EB3000F74AE42F492D96B19D0DF6E98964C7F196
-:10EB4000FD26937CFE0568CFBF6896F15CE0F0B3CC
-:10EB5000EAFB0D990E82E7BD7BEEA3762643858BFB
-:10EB60009FF73382F7AAB404B2CBE59D56D56E3C2D
-:10EB7000BDCE0B65B542A701F5CF5BAD817556D40F
-:10EB800027EA7E8029811B71FF130C98D5A01ABC3F
-:10EB9000E8CED81EC1A0F99FBDA22BDC0E35DD3812
-:10EBA00065329E874A2345E82FD56D5B67CAC472DC
-:10EBB000416BEFC5CB4328BEB4BC087878A65D2B6B
-:10EBC0004F593705E6B3C7CCB4FE15ACBF071F835A
-:10EBD000A4BCB40EFBDF5DACB6573E5F87BFDF055C
-:10EBE000F3B9CE087BB0E1DBD2D639527BE79BD3B9
-:10EBF0002AAFABCE052A943BE3701BB7A8ED443295
-:10EC0000EAED55A5FCFEB0F6FB59DA3DE21EBCED7F
-:10EC1000BD494157ECE787FE33AE008A96183B0F9B
-:10EC2000D9016E8BF657584D02BEDFC5DFEDD2DA43
-:10EC30002DDA3B93EC9C252F17515C70947687F16D
-:10EC4000FECC3FD1CE6ABE80F14E87DE5CBC4BC6A7
-:10EC50007B33150D0E23D567DCFF157D7D5AFBD365
-:10EC6000BBDEFC318E7746EE4CBE166AAF0A015C05
-:10EC7000A2B4D3EA6BF7AB27B9BC13DCF0FD3FDCE1
-:10EC80009C0F9958E1413F53D0EAA77B6C3693BF64
-:10EC900004F509803E80710A5A3AC99D4BF523BF9D
-:10ECA00047F257D0CA12A7A1BCBC4FA473F7A05516
-:10ECB000B18F867C33EC53AA614A3563DE198BF140
-:10ECC00002CDFB1C24D76BEF6B77E1EF2B291E33B2
-:10ECD00043BBB7F9F28E5409E65177BFB9F4E74860
-:10ECE000BFA165AE7BC2ECB09C2C1EC79D19EF2F57
-:10ECF000457EB4013FA23E6E34F9ACF86E8A922A8A
-:10ED0000505CB50DCADFA0F24CB5DC33F56ADA977A
-:10ED10000912CEAB3E77F6D462D46BAE04D207B6FE
-:10ED2000BC29A573A13C20992524AF8AACB2BB11A4
-:10ED30004ECF889E0AE4BF671C0E09E3B14056928D
-:10ED40003E10F39C149F6551EF3B658EE17ABE67E0
-:10ED50005FEE56FD026E1EDFD31CDB715311B48BC8
-:10ED600079509014E8BFF1FE0D25189FB8F5FE7795
-:10ED7000FE84F1AD4DC922BD33B0BB3AE4C57ADDA6
-:10ED800006D6B11DECC83595D33B703FBA86C93263
-:10ED9000DAEBBB0DD3FDA89FBB9344B65DE6BFEF96
-:10EDA000101EAFEA28D0C74B6594EBF36BB37C0F12
-:10EDB000BAC7633C5061118E936490657C3AB8B0D9
-:10EDC00083517C7E726EAE8471DD71851171B0935A
-:10EDD000F5FD244CD1973BA745C46DDDA22FC7DFBD
-:10EDE0004F08CFE3EF4484E74F223D523C093F7F79
-:10EDF00088E145009F2718EAE9C6AF87503C2BC23F
-:10EE000011EDF69861A207CF4532CD1D33300E8E3D
-:10EE10008D88217BE9A03B86C990B72C66244F2DB5
-:10EE200009C103B85FB5085289421A2A78E0AF5089
-:10EE30006E87FD2ACADF48F8656672FFA043FD3D74
-:10EE4000B0A018223BC2F6C010A9DA835BC7083F06
-:10EE50006C79589EC77B6F77ABE7282E2D4E8DF0CF
-:10EE60000A2B43BC4D62017C8732F3FE134A08E64D
-:10EE7000B146CEAD403B6395D049E328650E1FEE09
-:10EE8000BB9330CEDB88F1DE0AA591F8D8E3E6F635
-:10EE90009FCC66FB118FAE9902C58FD41F8AA9C380
-:10EEA000C3977AF5BD062D8E4DA3CB97DCDCFEDC37
-:10EEB000D32E085EF483DF91BB1DF1ADE55B7C4E84
-:10EEC000FA1DCECC31159D4897EC7A6E87821EA034
-:10EED0007BD95A9C981657F85196999FE767093D38
-:10EEE000F80B6971446171E0747467C4A30BBF844B
-:10EEF000E73D99634A2494338F68F72F18EF179FE3
-:10EF00002FA473836982F722D59F8E765DA23A5E25
-:10EF1000A253F4D2FBEE302701EA3FCA78FDC4DCED
-:10EF2000BDCBF1DED51E241CE49F7B389C23E93643
-:10EF3000B5DD5F320AE165007D98D1978E0DEE1642
-:10EF40003A0FAC7F902558C6F4A5EBF1466EFF74DE
-:10EF5000CF9729CE72303AFFC41DCFFDD8499B24EC
-:10EF6000B46FD3721FADA67B300F3209F55D5A7BAB
-:10EF7000C74DE8F78AE487803D6E2C8F93FB6E7E49
-:10EF800078A391F3074B11096F91F1A591F1A43981
-:10EF900059F1AA9F02F4402CDE0790AEC038C1EEB2
-:10EFA0000718BD1350FC62F36DBF83FEBECC334B1C
-:10EFB00028AFB3DEF23D6987797DF94B5F16CAE968
-:10EFC0006D62A72D3ECCEF290AFCFE59A4BCCEC928
-:10EFD000E27427A3DE70FDF36926D2F710FC7DBE34
-:10EFE000E4919284FDAEFFA335E9FFD06E61563FF8
-:10EFF000DA2DEE762D9F417658D65B3C7F893B63B8
-:10F000009D928B702B277FD1C1CC39E42F12DFE387
-:10F01000FEA251466F00F3EC7D1BC5DDEDDC77C72A
-:10F020003C8C57AB4FBE5646FD3C4EDDFF8CC9D2E3
-:10F03000F85BBF7ED1ECF521DF447E1F99A5C59515
-:10F04000947C3213F037EA7133C5DDE50B65F47B50
-:10F050009CDD8D46C26799515EBC3A6C9FD6945C2C
-:10F06000549495C47F97D8071B06F9BC81F980D9C1
-:10F07000DCCE634548AF59C066285FB2146E406667
-:10F0800055C6305F189DCAE745AADF94EC2DCAE249
-:10F09000710874EE635259FA9984123613F5327C72
-:10F0A00043BD6BDA15C3CF7B9CFAFB9146238F17C8
-:10F0B000B9415DBF09CF75C6E27B6F42C832BA6FF6
-:10F0C000FD9BD57AA2D511320E413FD91B47E8DE10
-:10F0D00065C43930EE6F292EA79C911F14E142F9C7
-:10F0E0007B25FE6E77258F07A85DC10C781650AB87
-:10F0F000DE5351EEE2BF4FCCBC5E19DF57A12DA607
-:10F100008CFF0B11FFBAAC2C01EBA7B20E8A636423
-:10F11000ED4CE6F112FA73A76DFDBC03A5F901C42D
-:10F120004A23ED5346BE66A3714D958CDE09A73781
-:10F130009B70FFBB82054443AF1FEEED4C99DA692B
-:10F14000E7B1BBBFF9200DE572BEB0DDF706D90D02
-:10F15000B1D276D48F317A3ED4EEAFD5A874B2ADA9
-:10F160004A227C6BE56EE518C5DB67B1EE6ADC67A9
-:10F17000655526E8F0DCE3973D9FCE7CE3C2FB0DAE
-:10F1800070BECE15E99D2EF9BC9BCAB755C983F454
-:10F190009FD34FFFA9444FFDF79F41E5ADA12FE25B
-:10F1A0006F00506CEB3E115F22F7DAAD917076AFD5
-:10F1B000D0CBEF8BF747C69373B8D84C5EE74D00C2
-:10F1C00037DB4382A78DE1EFDEE8EB4DCD3E17CF75
-:10F1D000CFCBB5FA21E7CD581FF6BD6D32FE8E8E2E
-:10F1E000BE7E49D147F1FCDC5DABCFE7F7C3F3FA54
-:10F1F0007A91F8899C2FCC2BE94761F3BAC26AD186
-:10F200009597CEEC33AFA45BC3E675B54B5FDF5784
-:10F210001D7D5ED7E55B069C9756EFC68917562F76
-:10F22000721D374FB5F403775EFFD6D20BEBF7F6BE
-:10F230007903D7BBBB32721C85DF53377BDF46397E
-:10F2400057C6E495F84E3873C4448D0B2E52F9E33B
-:10F25000EFE8A748C27800EF516CF779268F4B3959
-:10F26000FCEC023F9EC32CDB6796F1BC2353F55B9D
-:10F2700083E05988FCBBC72AC5633CA0C52DABFB06
-:10F28000AB8E6C8CE7DBB3F39DDB48EE31BD3DC349
-:10F2900098A708F5358830BA97F1276C97141E4760
-:10F2A000E125FBAF5EF0FC99F6553FE6FB2A2D7E8B
-:10F2B0003FDCCE62137AED2C2D7E7BBD3ACE3759E2
-:10F2C000DC1F08763EFD3E6A72AE48F1CD8F583B9A
-:10F2D000D6E3FDA3479CCE78DCCFFC469DB76637CE
-:10F2E0006AF71A5266E68E3146819796FE0F29DC40
-:10F2F000A2280080000000001F8B08000000000012
-:10F30000000BDD7D0B7814559AE8A9AEEA57D2DDE3
-:10F31000A90E9D178F509D7720840A8418909126FE
-:10F3200009195486E9A022E80C360908485E181F1E
-:10F330006165C7CA431E51C7384604046CA228BE83
-:10F34000669A59D488C16DA3C3E82E8E61D7191D62
-:10F35000C7CBB6C05506105ADD41BDABC33DFF7FDC
-:10F36000AA92EE4AB7C2E8CEDDEF663EA73875EA4C
-:10F37000BCFEF3BFFFFF9CBE2B81AC0C1411FCE361
-:10F380004A0971E6E4F476B9091957E215A7D0F7EE
-:10F39000BFCD3410328D900DF44168BD9227F877BF
-:10F3A00073F4DF2221EBCBE8F7D0308B9007C44118
-:10F3B000A740EB1F7009A2C2413B09DBED7DCD6088
-:10F3C000F0B80879E82739BDBC7BB8BCC5E7DA05D9
-:10F3D000E57106E20BD8A0137135A1EFF75A446727
-:10F3E00057092D0A83EE1A3B2DEFF9C3759C8390C4
-:10F3F000CCF1F45D0A2175AD95E4D854429E378571
-:10F400005F3D0FF3D9CCF977D37E5EE829A9166862
-:10F41000FBE52708B1D24FEBD65EF5C0F151844C25
-:10F420003F2ECE86F775DB9D324FDF370E3657C342
-:10F4300038A499C8B9322169FC6CDE4EFB49BBFB8C
-:10F44000B0DC41A7FCE080D417A2E5F02E4EEE958B
-:10F45000A07E4DC91A808FCD23D9E87A97C254F186
-:10F46000BDB3DA08EDAE32C99DB49FD346B208E011
-:10F47000781EFE660D3F97FE442A2774FE4B036BF1
-:10F4800097E2B8220559062D5B449C87451293DB11
-:10F4900068392D8158AC5308296B170FDE01E3AF93
-:10F4A000B28BBD14C68E72F1E0C3B0AEE64C91973C
-:10F4B00061703FC255EB7FB9C76B2274DC897B4C0E
-:10F4C000B433B68FE7E97F9302D1E5C97DD1E592E8
-:10F4D000607479EAEBD1E57D1283F70CCB981DC7F8
-:10F4E00029BC070E9809CC77F5A904BF99C27BBF48
-:10F4F000911058BFF2AC19F1A172B5CD03F871EAC1
-:10F5000064C22E332DBFF25E027E7FD3D356F6BD8A
-:10F5100021F04B282BBF4C24F0FDEA5181B2643A14
-:10F52000EF97BEE66FF016B16519A1FF5F16EEEA20
-:10F5300082FAA9813291BE7F7E022183502FF88BFF
-:10F54000619DCFFF95C77EC34F9AFDBDB4DF532F9A
-:10F550003EF14B80D7A927C7247374CE971A7AA798
-:10F5600076417D9B5DEAA5EF679C7A26DB17B12F7C
-:10F57000ABF798A3D6D92C71B8CE56C1D3FE28ECE0
-:10F58000CF2123E253CB727F5D90B66FE1326505E8
-:10F59000FA31513C2D82B29CE6A4F83AC3C1F0B6D0
-:10F5A000C54ACB31F65D7BD66EE1896FEA70F9E82A
-:10F5B000A627703E0527DE45BCDE6F540C0900C748
-:10F5C0004D9CBC9BCE7FBFD5514C92E099E907BCC6
-:10F5D000B95332E0FCE8BA1E6E04BC7893977B49BD
-:10F5E000FCF10AD2FFB4BD6AEA37D4D371DDC58419
-:10F5F0009CFD73C20D1E3A8FFC2DD1FB5EE88F2E51
-:10F600006F00F8507CAB2511EFDD309FACF5E94879
-:10F610002704E75370E2FDEBDC74BEA3CDA419E030
-:10F62000A21FB75B627CE4A9A7683F05D80D7F9E47
-:10F6300067FD49A9745F54BA7A89637444FF6E19EF
-:10F6400043E96D35C7F88BF67EB56E1E5AFFD3D5EC
-:10F65000FE5D26F9BE10EEBF5984FD3F79E7DC0759
-:10F660008E1B47CEE7C33B3D9EAA88F7376E597382
-:10F670003083B6ABDF9B32858F806FFD93AFA65E84
-:10F680004FDF9FDE23C8C002EB173FFEF319F0DD0A
-:10F69000937C00E60BF51EBADED381DF38E0BB1B9E
-:10F6A000B73BA7F0D270FB155BE678AA0A86E17932
-:10F6B000B174FA4239E373AB0346BF05E822F0FBAD
-:10F6C000EA3180A75B3839978E5326F878A03B7BC8
-:10F6D000A9C7A84C2764D657FF7C7034AD6F3A3069
-:10F6E000ADAC8BD67719BC57FD08E86E272FEFA677
-:10F6F000CD9E7BFBE6545FC4FEFC56C5FFAE85F590
-:10F70000D88F4271239732F58182DA4A28CF282296
-:10F710009C99F263C709E2F1DB603CF2AE2199905B
-:10F7200013FD77150B06E447D7039D9C220E19E8BD
-:10F730006EBFBDF9DF71BC678D38DEAC601207FCAF
-:10F7400077FF639CDC45001ED1F477E244BB63364F
-:10F75000A3EB1BBC28070CC445FB5BF9E824E403BE
-:10F76000DA7BFDFEADF247F7A3C78B132ADE026AF0
-:10F7700046E297FEBB51F31413D0637D2B9517110E
-:10F7800074537FBCDB446C23C72164087F09E02FDE
-:10F79000C54B22E17AADC837E81F67A1787B12FE1E
-:10F7A00095CDCA848E7F13874B23AB2704F280CF7D
-:10F7B000718258D19931CC5F49B91FF9FC69FACFF0
-:10F7C0002E19F842E008D03BC8D2DD205FC4E09992
-:10F7D0006D50AF8CF7003F1A0D484A9FE45789C817
-:10F7E0007F4F4BA1C7B1FD33936485BE3E0BF462DE
-:10F7F000C3768EE408FED41678D511A2E5537B4774
-:10F8000055F00EC0DB7F75C03A4F064655981CF187
-:10F81000F9869E6FD29921DE7C00FFA47897E4F6EA
-:10F8200024B869997452A10BF26C547349738C7D9E
-:10F83000D3DAB94CCD2512F08F9FDA64E0E3C99694
-:10F84000BA47405EC39F87BEFFF4F551BDB0FFBF0E
-:10F8500050E5EA528E8DA3F533DACDE8FDF557F287
-:10F860009242749C4F899404F2E2E96CEF38377D40
-:10F870009F5E31E8E1293CD2AF2072076D7A8C9708
-:10F880006F13E97E2C23545EC2B3D46702BE423AA2
-:10F890005370BE84C8D500CF15F328FC4B5819E42B
-:10F8A000DB2AAF49EEA272B84E60F0AEDBC3F93B83
-:10F8B000E85C96DD130D8F1B7BCCC37801FFB73D51
-:10F8C000A29E8EB34AF0AF07B935968A9C51E514D3
-:10F8D0001F1E8BFE7E3509E2BCEA9F396F8E05E75D
-:10F8E000BFA8707E3ADB7309AC8F5B60C1F9B43C92
-:10F8F000CBA17C759902A84F84D7507E4CE74BDE94
-:10F9000066FB709DAA2F35AD5DEA59469F675BEB9C
-:10F910003CCB6815921AF0919E24C49FD5558183E3
-:10F92000C85788F8EBEBD3A13FE211A1BCD9CEF4C4
-:10F930003DF2D8ABC057FE42C400E0E18C951CB646
-:10F940009FF136DF4B319C5C37B47F5E8463BD44EE
-:10F950004480E37B462FAE5B5945C4DD94AFD45B56
-:10F96000BC9AFE25FE90AEE746D28CEB5EE8CEC296
-:10F97000FD5C49BAB1DC404226C2C3FE962501BEF9
-:10F980007E4664DC5FAA27116BF248BC02F87B223A
-:10F99000E0B6727B74993C1651CE0238D37204FCE7
-:10F9A0001BF79D377B62C0FDC12179E42FAC991410
-:10F9B00089C76D38DF23EABE3C78CD8D19C047EE8C
-:10F9C000038578B4DA4139F05FFAAF19580E5A68F6
-:10F9D000FF095387CA585FD6CECA2DEE17BD5B28E4
-:10F9E000726C36FA3244BA3975BCF7A081C27561BF
-:10F9F0008EEF76D8EF3A832753407EE2C9F3D2796F
-:10FA00009056B6BF0F4D692E6C8EA17F68F3DFCC88
-:10FA1000058206E0232F32FDC25E1A3646F2FFFB56
-:10FA2000DD8C4F260D8470FFC3CF7104F4DEADDC96
-:10FA3000FD19B08F5B3324AE83AEA9745FDB6CE439
-:10FA4000379417E5D27D6DD8F7C1C131B45C3A77F0
-:10FA500010B689AEDBBBE63740CFD31298DE9CD818
-:10FA6000BCCB40FB4BBBA1604A07C5CFCD6E09E7BD
-:10FA70009330B5FB15E827BC46127B693FE9ED8A58
-:10FA8000FBE62218BFB90DF1B786E0FB946BD7B542
-:10FA9000C177778F26C93C7C47DA38F8EE410741B9
-:10FAA0007D31C5C0DF5003E529AC9CBC8EF3F42248
-:10FAB00052DF8FE3A499C95C2E99BDF71721297AEB
-:10FAC000F662BD1FD79B56D95C02FDA565B3A7CBD7
-:10FAD000E433E4D0F10E1D36FADBE97C0FA9FB7E9E
-:10FAE000CBAE8AB448FE79E8B4453050FDEC50BA4C
-:10FAF000A697066DA097DE52529906449595333726
-:10FB000009F6C795195D7FD6E8499A0A7470982757
-:10FB1000B00FFF69F324811E79A989CD5FBF7FFFF4
-:10FB2000ACEE4BD3171CF147C8A5A645E750DF6FD5
-:10FB3000FA42887A7FFA4E0B01513524BF560E5493
-:10FB4000C3770D64703DE053432091F823F0FBD25E
-:10FB500084D8E36A78DDF4054F9498E39AA2DF7FB6
-:10FB6000318A28A3627D971AFD9EAE23AADCF7F99D
-:10FB7000D03AE03D290F39BCD4DE9B07F29096CFF6
-:10FB8000FA0D8A7132A8E34C8E9D11430ED0B3A9B1
-:10FB9000DC6B867D39238550AE9D25642ED45F6A4B
-:10FBA00030DC5003FB2B841D0BECC3E368F5D03E27
-:10FBB000721FCF2C329120EE4F18E701F053F2095B
-:10FBC000D9D6FF8949027DA0FF15849F862F9170A9
-:10FBD0005422F8466AC760D040E9E3FFB8BFEA2E76
-:10FBE0002AA4A837A0D1F75FBB3D33693D6F88A237
-:10FBF000F7C4D221FA4776F3A08157F9C5F9EEAAE6
-:10FC0000999165F67D44FB9A2ACA1F4A8B587B213D
-:10FC10008B3BDC9E03AFBB999E238433017E4365FF
-:10FC20008BAE6CA3E54911655157EFD2D5A7EBCA4E
-:10FC300063D9F7A7EDC14CB04393B28C3502E57B95
-:10FC4000A733824B385ABEA7C35C5345CB0DA54C96
-:10FC5000EE36F673328A0D157E8D32D31F6D72C863
-:10FC600054570470183C08FCA1BE8F13394A0FB6D4
-:10FC7000C0DE2096A19D14D12EC061BBFAC007D86A
-:10FC80002E6EFF0506A4F3AE82A3ECBBC04728DFAF
-:10FC90003774AEF102837AC3C8F88F407C9E3194EA
-:10FCA000BE1BFB6A88CF36CC27CF64785E453E7991
-:10FCB0008013813E87F014FAB50DD385F6FD9F269B
-:10FCC000F5FF1ED487C45B3E6913E8F7FFABE1A3E1
-:10FCD00069A0DFFD4995079B397F218CBB8DF80A10
-:10FCE000419EFDB421F71503FDEE8831B40378E899
-:10FCF0008FB3C6D508947F1FB187C671545ED76491
-:10FD000015B0724A6807C0F3C9AC42561E171A678D
-:10FD1000A0E56B7AAF46781FC90DED80F2CF7A6708
-:10FD2000B1FA49A1713C6D9FAD7810FEBBC5D87486
-:10FD30003D278BF1136D7EFF36D5E3C982F5D433B1
-:10FD400039B2E4A6F71603FF5D622022A1FC76F724
-:10FD5000E963CFEEA6F0D8DD9A487A193A7A05AA77
-:10FD6000D7A631D4A7FCBE1BF973D84DF9353A811B
-:10FD70000643E03F4A9C6691BADCC3FBA28D9F36E6
-:10FD8000A1792FF49FB6A408E581C5ED790AC6D7FD
-:10FD90009E6F15B2E7535922E3DFBCC183DFDF61F9
-:10FDA000F7C3F7F759D9BA28FDE03EDBD47DB95E39
-:10FDB0005DD7F5594C1F9CE69EF354560AE823AADA
-:10FDC0005EBD31903281CEAB872301B04FDE33125E
-:10FDD000C58AFA4802EA353D3077A8BF3FC3AFD0A5
-:10FDE00071AEE78817F88BC64F7A9C9E8CE408FBAF
-:10FDF000A4A784966DC3F6684F8D2723C105CF5401
-:10FE000003E8EA1A7FEA71B3769A7C4AEB60E3A4CE
-:10FE1000DD57D80BEB491408FA4B962FCAEB6D430C
-:10FE200039BF00E74D3C9E0C8EF6777C559601E07D
-:10FE3000A8EDD767533DB7017CAEE3997DADED9B4F
-:10FE400006DFA7B2989FA08EA77A02C5BBE21C1F4F
-:10FE5000C293EA0DC528A055BDE12940DA08381340
-:10FE600021340DDEFF7F08AFED8807DF115E0DAD99
-:10FE7000948F182E808FA870DCCC058D698C8FA094
-:10FE8000FD0BEF411EAD73FB025911F4B0E48E0679
-:10FE9000D417B57925DEFEC2DC6B09D0E149A4BBDD
-:10FEA00025FF9088F6AA5E9FD3EC244DEFFC451CFD
-:10FEB000BFE3CBEAFA64CDBFAACE23B128F4ECBDF0
-:10FEC000145EC9C42E021F3D620A4D9269FB2306CF
-:10FED000DFA32FC0BC47F322E52123FABB2D9B47AC
-:10FEE000BCB16A7842C28E09AE613CD944F1C40209
-:10FEF000ED6B4C6807F738FD5B6F043CB966ACAC42
-:10FF0000482887919E95D644ACBFD4709480BF3862
-:10FF10003C5D14415FA47885F53D8BF3FC0AB3FB8F
-:10FF2000152BFA4113FCBD8077251400D0DFE209C0
-:10FF3000580F7637FA2B165BD87823F18AD9C7F990
-:10FF400084D5BB55BC5D9585789BDA4198BF41F05F
-:10FF500014D744E80B85D90C6E89A5A1E7DE013BD7
-:10FF6000E51EAB9C4B9829077E0CD29D86FD517CEB
-:10FF70003995C5FC0B8897CB7E6EDFC5F89E5C0675
-:10FF800070DE60EF266BD10F65C4F96FB706519F25
-:10FF900036582427F87B97F064731EF4D761140158
-:10FFA0004FF4F0B667C7F34B866E8DF44B2E312BB2
-:10FFB000E64CA8BFD38AFABDE69F5C92C4E84AF338
-:10FFC0004F027DC6920B9A7FF20615AF46D4777D1D
-:10FFD000995B4BFBFB0F15CFE4812F7297DAD8BAF0
-:10FFE000C1CF510BFFA2E3D6AEB37E00FECC5AC503
-:10FFF00018343B808FCCF18422EC2DB285ADC3F751
-:020000023000CC
-:10000000A6D10F706A15C8E6C7617F14B6FE96E5E3
-:10001000FE5591EBDA6662EB52FEC11EB5AE6D0E77
-:1000200016AFF8EEEBFAF3B4E8759D98A6AE8B58D0
-:1000300052693B55CEDDD06AFF802BA64F58177D05
-:100040009275745D05C3EB9A93CDF8E912958F8D87
-:1000500090BB71F7F17FC87ABB1FF2C45AAF7E9D87
-:100060004F677BAAB353906E8262E9305EFBB6D2D3
-:100070007595C2BEA6F8DB705F197E12E290818F83
-:10008000B52CA7EB82675B1AFAA59698A53EF0CF30
-:10009000928793D47512E4032D5BC7215D52BC6532
-:1000A00074FB108BEBB45899BFA0658D282B22AC44
-:1000B000FFD768CF86297F45BDA4359AAF7F3B1C0B
-:1000C000AC99B5459170B0642E2D8AB1EF8A19F1C3
-:1000D00039DEBEFF071FBE95CB8EEF2F23EBA2FDAF
-:1000E0000DE0371C2AF323CB7AFF05B51FCCD1DFF7
-:1000F0002BF1F8C14F23F1E88851C5A3B556943FC1
-:100100001A1E1DB1B3F5EAF188502D1AE8585BB7F5
-:100110001E8E4B008E31E209149F72018E4754FBF4
-:100120008CE2532EC051A3831B5A193FD0C3ED89D3
-:10013000F87CEDBBAD4387C7DF751D5A7DBC756884
-:10014000FAED166ECD56C0CF2D1944EC403D383433
-:1001500009EC2497C95F08F3DA66A2F44BFBAD55AE
-:10016000C707CD01F0FBB343CCBF79541D573FAF58
-:10017000E75539A4F77F3539C23B410F694A60F230
-:10018000F0CC013BD20DC9092D01FDFBEC7E330102
-:10019000FEDAC885F2E0BB339C67297ED7962881BA
-:1001A0005CD4FC86C79E677E438550FB17FC753E7A
-:1001B000E6F76C52FE753DECC3F96CA119ECCFA6C5
-:1001C000BE683F195D9F03D67BC64006E1FB46DE55
-:1001D000BF0A4CD6CD26A60F6C369000ECDFB05D82
-:1001E0007E340FED840C91805FA7D1F041DECD11FC
-:1001F000767CA35ADF98C9FC4C1057467F390CE532
-:100200001E0997C67B4E7D0D71B1C67D7A7A89A68F
-:10021000A7FAE132779E83FE22EADDC3F484F63842
-:10022000E06115F1E772E01F63E5C4B9837E884F92
-:1002300037A9FED394815035E80BF6D200013EDA9F
-:100240007482D92133FA77BD0A7E33E7DCC171A00D
-:100250009234A97104BDFD33BDFF7E1EFC439AFD9F
-:1002600012E18F2A5C10E5576CC776E0DF82F1421D
-:10027000F00AFCD302D37337AB7A2ED587916F2E59
-:10028000EFCE477D18F455D03B34FF18E821A08FFE
-:100290002ECCA91072E83ABFCCA9380FFC1BC6437C
-:1002A000BB1F9C2ED3BF817FA9F0D1BE033FD9379E
-:1002B000FBF3993E3543E7C7BFF98D14C4F3FD71D5
-:1002C000F4D45139437EFC34F0E3DFCC496980E754
-:1002D0001FF23EF4D7AF200AFA8157817F1CF960E4
-:1002E00010FDCB373513B90BE3E1BEF5506E58491D
-:1002F000C42EF02F57F9B01EFCCB574E67F12629BC
-:10030000027F219E1359267B68398A4F0FA2BFBAFC
-:1003100091F6B04D063F42F4F74DC45F29005EF4FC
-:100320009D3747F5D3C3E074838A2F5BADCC4F3D37
-:1003300063DD2E9E44F81992A678DC77013DBC61FE
-:10034000443FE9FF56F75783C7D3D915D61C0A8F08
-:1003500004F0FBC077779951CE1E379095802FF728
-:1003600039C90D0BC09F7527F1E418012FC4CC4883
-:100370007F97F6ECDA6F5D0978362B87F111EDFD8A
-:10038000996C2396D1EF8CFA6922C6D1295B2A0693
-:100390003C2CCBD2F462520CFEEE0F54FED4B8D0FB
-:1003A000E683FE4206C6CFE6E530BB7B5E8E09FBE8
-:1003B000D3CA43FE2215CFE838D85FC2541215C7FE
-:1003C000BB2A87C901CD5F4BD4F8CAE655094C8FCB
-:1003D0001EC27703F2B3C422AFC987FCA402F95945
-:1003E000F8CF3609E032F754FD2A58C7A78B120818
-:1003F000E41D2C53E3448D394EEC578B0BC5D0BF15
-:10040000AE0FBA86E58D869F9A9CD96F67EBBED8F2
-:10041000F8BEFE39B7AB10F9B7368F193ABD241EB6
-:100420005DDC364C1751F12D0AD744E0B3FB0DCCFF
-:10043000EEDA4F110BFD560135FE48ED649003FBDB
-:10044000F7E5A39EBD54F5A7523989F65598CA0B16
-:10045000B6DFBEADCBE1BB402EC6653F30FA9F7C18
-:100460001CE4ED01664768FBB17FFF183FD0EF8CBD
-:10047000535F6502FCF79F786A0CC4BBF7ABF1C50C
-:100480007A53300FED7D13D353EB1DC13C80DF4B0E
-:100490002ADED427D0327D9F95E2EB063EA4E50705
-:1004A000403B27AE477280BFE1986A471EA576257C
-:1004B000CC8B52CB20C43DE97E674039BC298DE905
-:1004C0007B745E8017C70E4CC2F56D36323C565EAB
-:1004D000E4D03F71D418FEB0957E7F34632A69134F
-:1004E00041DE7DF1F841E87F274FCC22E45F7C7E3E
-:1004F000AE8F7E7F96DAB9E037AB3378AB33805F6F
-:100500003CCFEC75FD3E80FC8B8CC79D21E14CF40B
-:10051000EBADCC0A00FE9CE92FC4BC22E21289425A
-:10052000CB4D2F32FB461F273E6E8CC67F7DBFB062
-:100530002EF0AF35C1BF41BE47B68FD1DFB795CFE3
-:100540001843796B293CAA245F302785B163D8CF43
-:10055000A69733901F1FBBF773DC4FD2CDE29FC726
-:100560008D9E25303F6755D0541B818FEFA8FCA38B
-:10057000CECCE435E5BFA6487EA3D59755909871BB
-:10058000FA3FA87CC13EC8E4DEC87A86E7B7924746
-:1005900079E017EFE448D8DF7835DFE056F2D92B61
-:1005A00066D04F022598CF307E5D10F9009D2FE276
-:1005B000E7F1AD49C81FC93D0C5F6F7CD88CFCE3E7
-:1005C000462A3F98BDCDF2ABC83D2C8FE2C3BBDCC1
-:1005D00088CF65EDC132A4072791412F79A1F3039C
-:1005E00085A7F54BF77025903FB6B4D38D76CA4DED
-:1005F000FBDCB8BF3354BE5E67F660BE187984C5B5
-:10060000D396FD62158ED390489C3CEA7F7E13C83A
-:10061000E5957B3802743523C0F87FBD107C05F466
-:10062000487DFE03F147C789411E91083D13E40F41
-:10063000D1D905D1FBAE5C94FCD5CB1B3E37B6FCC3
-:10064000A5F69E90CBF695C989BD1CE31BAAFC6D4F
-:1006500000F90BBA9A2AF734B9B942959B1FF24CAC
-:100660006EDF68BE1F9F19B96E1CE72688EB621CFF
-:10067000336C02FD241E5E64E432BCD2F062746E00
-:10068000345ED49F081E34A39D293F0FF1EAFA750A
-:100690002468A776DA8D4233CA87D1221131AFAEF2
-:1006A000D287F34A6BA1FA39DDE71B21063BE5E26D
-:1006B000F582117A804EFE6BF3D6F044AFFFCD5831
-:1006C000E7E7219E74328FE07BED29924009CCB799
-:1006D000C6C2F4EF1A8B2DC883BD59653C1D696FE6
-:1006E000FC58F094E5A25C1DEBFC7022B20802FD00
-:1006F0004E737B664D9836AC57269686D7DF4BFBFC
-:1007000033926203F0496D7C8B7BF692220ABF26FE
-:100710006110ED15924EC4DD74BC2B8B249C4722D6
-:10072000DD875D14AE464141F8192DA2B3CD09FB1A
-:100730003F887199700A413F9DB65F3BEC44817CD4
-:10074000C52B8B187D5F5924E293B6C738AEB180B4
-:10075000B6A7FD57ECB7225D9E7BD1EE07F94CE5BD
-:10076000CE7827AD4FFD13B55368F9CC7E3BEA290F
-:10077000675479E1D2FCB5643DEEF722156F14524F
-:100780003106EC11C25D3186CE9D687A7283335E8C
-:100790001C53AD770F2E64F86B467DE19C33741BC0
-:1007A00094E97C30B7C69BCBD6DFB4AFB2E40EE0A1
-:1007B000DF5E9BCCA0EE2B01FDC7CCDFB2D0428127
-:1007C0005DCDAF0BAF05BC1F6713CDB449D5F8F7AE
-:1007D000FFB09896FFBCCF48CC803FBBAF4A0A42DF
-:1007E00033C193EE9D34723EABFCC6A3A1083A5EC2
-:1007F000BD27BADC10882E3711E1682882FFB7BE0A
-:10080000BFEAADD722F06D6DAEDD05784024229FA2
-:10081000A7F474FCCE3E720C6421FF9324E08FCBCE
-:1008200028F9C7D22B3EBF73E55BAFD1EFACA68AE8
-:10083000B65C940B9209E8AB96EA0DB1ECD0C9B95D
-:100840004C4F339B9B4FECA2F031BF6496DB68ABFF
-:1008500079B9BE2EC0C74643F820ECAB79FCE962FB
-:10086000F067578CFF0AF302CEFD2391014EE7ACEF
-:10087000B3119FCE6DB54A60A7F664DA981FF6658E
-:10088000CECF31BB65FEB454C8FBC0B5503E165E3A
-:10089000BF15F8F474B3D82EE2722D06DC6F6ABD72
-:1008A000D1678F49590F7ED51E6A40B6C960E70DE2
-:1008B0003A80180655FED0C43F63B2D07FBA3B3DA4
-:1008C000856DF4BBD5DE0402F978C2D78217F06CCF
-:1008D00003741561F73CAEF2BF46F1EDF5307ED3FF
-:1008E00057B7CC4D310CFBF9CD46E6E737F6CD0EC8
-:1008F0008EA14D57B456A27D47F92DE38B07185FA3
-:100900005CB17636BEE716CCC5F57E48D70B70795C
-:1009100075AB19D7FBE1381BDADB1FEEE0B0BC4248
-:1009200034613E1FD54F46CD76C17BA3682623E1B7
-:10093000D1B465C3FAADB4FE77193CE128FE7FB4AB
-:10094000FDB7188FF888B0F1957D3CEA3D1F89E12D
-:10095000B220C0536A7644DA932B76F05EE0972B90
-:1009600076DCFABBE900B705D795023C66396F49DA
-:10097000956CC3F59ABE2724973F0E7439EBEBCAEA
-:10098000C159A077EDA07443E72D18880FEC8FD7DD
-:1009900076FC10F5ED1535094E589FB47D7735C8B6
-:1009A000B78F6A461B705DCF72440478385B53E1A1
-:1009B000FD0A4EF0C6C2AB65B92C9E307BBC4D061D
-:1009C0007FC38ADFF3882F94CE16421CA161871162
-:1009D000F5F9D716BCF787C5AE613AE3166C993FB7
-:1009E00003BE7FC288DF0FE953DB3F7E1FFC02F0AE
-:1009F00047253BC821849F9EEECCE3D7E5C1BCF4DC
-:100A0000F4B7A2BD398FC5F72F8E0EC9764687275A
-:100A1000299D9C37FC4D74F829E3EB174687646CDD
-:100A20007294FC1EC9F714FC4E8B8F5A64E2D96D88
-:100A3000C37C180F47F9F5983C01E13E268FD96D2C
-:100A4000C29737EF7993C26947AE4FC8A3EFC71378
-:100A50004F09C867292C56802BD6A6EA8D643BCB5C
-:100A6000F306FB02F67F730A79BC2BC23F93A6F60E
-:100A700047F9821DFA39F3C7AF0EC27E35669E2E46
-:100A800006BDBAE98BFFC4BC0A5B3FCBC7B1C961E5
-:100A9000CC3732BABC888F1ADF6F92991CD2AFABB9
-:100AA0003D8FD9AD4DAE30F6F3423EA34F2D1EB96A
-:100AB000AD3501E342DB5C7E2BF3B3507D8FF63F17
-:100AC000AF94473E6329ED2020C748398FF19C59E8
-:100AD0005FBD4520FEF5BB999532E895B6D25785A6
-:100AE00051B0CE72A35AFFAB8D59B4FEAD9973D0FD
-:100AF0003EBA399D9740AF9A579AADA0FCF4B0FC2E
-:100B0000DB595F25211DCE5F351FF54A6DBE5E6244
-:100B1000916C144F1650628DCC539E3FD32AD9222C
-:100B2000F0EBD36E6E2ED3ABA5A4AB2731BF50A094
-:100B300088C9F34838DC9C6EC2F1BFCC997D09C0EE
-:100B400077D6656C1F4E3E6BF6B7D3714F5A63DB99
-:100B500091D5790C6FB284CB912FDDF2AC19E3F310
-:100B6000A7B8D8DFDFB491C7BCA2551B39E2A7E311
-:100B70009D7CF2854CE0EB7FDEFD42666DC47CE23D
-:100B8000B5AFCB63FAC0487B3BB82CD2DE9E676220
-:100B9000710132C51CE5DF9DE750F3EC2F30DEF12B
-:100BA000A3B87EFE37C6C27CDF1CF2F3BF3E3632EE
-:100BB000DE3114B792999F5F1FAFCA29FF1775BE28
-:100BC0002CAFB95550E72B9B59DC62398B8BB71C86
-:100BD00018857837CF14FE39C6B35EE64535AEE1E9
-:100BE000B160FB74561F675DC4E3C97195A1BF096D
-:100BF000E7C3F57141BBE33BAC8FB038867E7DB572
-:100C0000FD7CCCB8DC97F92C0F20B1288C76D5D19F
-:100C1000D71F85C8FB10BE5BFBDD86C87CF8217D35
-:100C200056C5EFAB00BFE9FAAC1B59391E5EC7E3EE
-:100C300057A9798C8E35FC3EBA313B09F0ED2E4B2D
-:100C400063E820859F874F22D6D1B4ACC6FF95F7C5
-:100C5000593E2A1F61E7001DEC78DF8E764E87B182
-:100C6000F91138BFA3B40964377DEF4A68F4B7D1EE
-:100C7000B264B463DED4ED09F377815D17A20A2E66
-:100C800047CB9F271CD9057A02B12411231D47A900
-:100C900050DB9B2C6207D52F1E4A74207F695D466E
-:100CA000507EA79120C75180ECCF63F9AA29AB9F52
-:100CB000E7308F98523CE87D72766C7DF4572A5D60
-:100CC000BC0B0934F42957C6FE6E7F9EE617137CD1
-:100CD000A1083B6F03274BC877E85FDB74D0EF07B1
-:100CE00017235FA67AFC5B541E8CE17F8DFED963CF
-:100CF00077FA1E8975DE6148EE56C6B6D35F55E7B2
-:100D000057D0CDF98D0EA45FC3AE28FA55E378F61F
-:100D100054994A1888DFB2385D0ED1F2DEB780DF11
-:100D20007E74399BA3C31322A05FA4775F4E7CA37C
-:100D3000809E66A4817C6B591EED4F4BAFDD988180
-:100D40007EBDDADBE683FCDE62B46DE492E019ED91
-:100D50008FDBA2F3C77D1B5F488F4B37D3D3C1BF57
-:100D6000B16538FE87F8D3B154F4F31CAE8244C6A3
-:100D7000B5533BA4833ED083665BE45E7924FD904B
-:100D800072391DFD9CF9EABEA9F4DCA4A226D7CFD6
-:100D9000A15D3A921FAAF06C188BF0B476DF8E76C4
-:100DA000536209F36327AEAAF501FF49A4FC07ECDF
-:100DB0003893A999C3FD9FC1ECB6168E955B668BDF
-:100DC000A242BF37399A6763FD152CCFBAC5EAF343
-:100DD00045C6D32E35DC3C3B32BF5624B43DF0E152
-:100DE000456CBC7996752CBFD74775A48C61385675
-:100DF000A870CC294F60F9E6B75AD0BFB5DDDA8DBF
-:100E0000F33548CCCEAEEDB222BF1BC31760DC6415
-:100E1000C0C8F043B15B905EE58177313F6CCC2573
-:100E2000E912EF8EC09F5B58BD861744975760321A
-:100E30004907C17F472722435E4A0B271DACC07577
-:100E40008961458675AB7CB93881C9116A6EA63354
-:100E5000B8B2B8986EBF28DE30BFFA241BF31B115E
-:100E60009F847A976EBD23F1E6C502E0B70343780D
-:100E7000D357108BDFDEE7940EF646E20B91D68354
-:100E80005FF56E030977C5C21F39DACED7E7C9E926
-:100E9000EDFDC6D64AAF6A7F2816DC4F13DA1F8DE8
-:100EA0006B677B99FD51D006FEA7A6755452D136CB
-:100EB00095FD9C05FA6B5AE440FBBBA96F2FC6CF8A
-:100EC0001BE71219A651ABFA87B5751E35B2381E4D
-:100ED00095590188DFF738433BE17C5DCF2A2D8FA0
-:100EE00087E5B5287D9C9AC7A3E57D858F80FFB3F4
-:100EF0008793D00F3A744E8FEE3FCBDFB9B83C30BA
-:100F00007B91D70D96F8F4DCDE7F4B98763179B47F
-:100F10001FF5409E6CDC3C5A25780DD45B602FD4C5
-:100F20007A4003AA2F6B658F5582FC9DE17A81DAA6
-:100F30009D963E4E1DAFFA9A393978BE46EDAFFF09
-:100F4000013847779F95448D17393F41D73F989691
-:100F50003649FB7EFB02E8EFC1296A59F9FA17907E
-:100F6000377C9F31BA3F4419B53D14B4F1D29E7E0F
-:100F7000ACE79E99C37A3BD5E3FF317FDAB0FEBE82
-:100F8000E1BD79DD93E95889E267789E49D3C39B37
-:100F90005C2CAF568FE71B553ED6600955836ABD62
-:100FA00061D11A2FF43B94F7D6BFD40376B096F7ED
-:100FB000D6B4CE8BE79AA8DE7F4F3EE4D1FEF1F4A3
-:100FC00087AF10B0334FA23FA0E90B81F99DA9FD77
-:100FD000C0517CB1F4DF8FF843F618FDE0DAE97117
-:100FE0002A04F0B1E700370DF08B90E6CC6B28ECCB
-:100FF0008FE77B7A601D67E2C4C79FCD67767B531E
-:1010000041C5D63C80F5631C017DBCABE053B42BDD
-:101010001A5F9C332DF21CDEAABE07D979AE3DC6FD
-:1010200098EB7E369FC7F535BEF81CC64F4EFA3991
-:10103000A4B995827F13D89B2B571AC0B222A5FE64
-:10104000A598274B169908CCFF01D50E69DA739540
-:1010500002E7029BE87F9404C836EF8DA86F6F5BB0
-:1010600064B1411CBBA9A0760DF23B31C103A69C23
-:101070007E9E43F96F6B13308FA6ABCF3817ECA46D
-:10108000324A17FF6403BE7AD8BD0BF8E7A8297C63
-:1010900087087986B1F5EF670A991CEFE4BCCA8F1F
-:1010A0004B312E4222F399C7F731FBEBB57C5354F9
-:1010B0005CF0B57C6617CE54062B01D75E164289CC
-:1010C000600F3711CF27E0F7225E9B847121124019
-:1010D0007FA0EB4E09ED268B2B74F764A89F29A007
-:1010E000DDA4F911CEBC9886FA584981EF30E0456D
-:1010F000191F7AE0C700B7BB0535BEC4F84AE655EC
-:10110000B629605F195D4C9FB1527D06CE7B5CB6FF
-:10111000E9F8BF56026F7579518F2054C8C1B9F1F3
-:101120004A0BC7E22B3ABD99887215B4AF56FDD26F
-:10113000B974B73EB4206A769E1F05FE0C9702F084
-:101140007E9D2E6014AD9F433C9DB02F5FAAFBB7E0
-:10115000D9C4F4F5CD060BEAEB9A3E9CE81A443B61
-:10116000B121C0E1380D05BFC6F302ABD5BCF4A177
-:10117000FC702184F9F2A7F313D5F86727C34F3227
-:1011800088FE30F20CDB07AA79621EBD06772DAF10
-:101190005CEBCFA4C64B1B547F2E0518D67F9EAFA9
-:1011A000C557DBA3E3ACEAB84490CA22FD8E9B6B23
-:1011B0000819C479490E986F57AA9714D0EF8F5227
-:1011C0003C063C3BBA31D10FE7B63673831E887BB1
-:1011D00028252C9EA1C7A794024E3D1F14AEC6BC65
-:1011E000AB17E39C0FEA8B3E1F44F9C39ADFD07123
-:1011F0004A4BDF9301BFEF73AAED2F27984FAE3F05
-:101200001F34BA40C271FEDBCE07C99CA7973E735C
-:101210000A9CECFC8F763E486670D7F231F4E78288
-:10122000CE64040596C71FDAB91BE59E19EDBB977E
-:101230003E3ED809FEE2B3252619CE43A45EF77AD6
-:1012400027E6C5704233C415F5727D97BBB218E02E
-:10125000FFE035CFCB98F7AB93EBF1EC798C794687
-:10126000F87B3CEA7E7C5FF6BCB5FB7307E0CD29DA
-:101270002EFC73C847550EF031F3516F28E0E2E4BD
-:101280006D791645EA999D5ADE9633212A8FB1333E
-:101290004EDE563CFD5D889BAF7539EA619D43F992
-:1012A0005A73353D2C3A1F554CF846BB571B7F6E81
-:1012B000C81D155FBFE582D7A9DA2371D617CFFE07
-:1012C000BAD87C013D1C3AE3C8C37505F1F2053C70
-:1012D00022C4D73B21BE4E9F024714F483ED1DCAA2
-:1012E0001708A2DFF7B97CF45F99E3E60BB03C3254
-:1012F000E140BE04DF6D307A3D6097287B8D2A3F48
-:10130000F73F09FE8FCE0319E82F2305A162E07392
-:1013100082B33A1DF4A34E153FEB2F3C5F6073413F
-:101320008C7C815DFE293FCF6276F06022D5AF765E
-:1013300011266F947EE69FA4F346FF5CF8DE71A849
-:1013400077720B2CB88E632F9B7BCDA84FCB18FFE9
-:10135000AF4DE74590133D35651F821C3A46155049
-:10136000A0E3BA9BD6A11D1A6F7FEA3646C763B5C4
-:10137000F717BA4FCFA9FB7414EC7414980AFA7DCE
-:10138000576EE45EC1BC5B5D3CF805E021C8EFA38D
-:10139000E3FBE7ACB331AE7ADB2F6A309EAA9DA3A4
-:1013A000D5CECF12356E226D1490DF4B7B38BFE463
-:1013B000666462401B5D34E07D1E544C6D03D1A613
-:1013C00050AAB984BEE60C1CE89B52272DA7D17504
-:1013D0006D129474FADDAE7713D18FBAC125A9E7E7
-:1013E00021981DA5DCC3A11E47FB453B58E9A47805
-:1013F00043FB79A780F9F7CF16303D83A2881FE71A
-:10140000A33E3BD57C086DBC366208C2D3C0B1E7B1
-:101410000651981B4B4FD3FAEB34365B206E121EED
-:1014200067C0B8E439936711C6F592F308D87D9D7B
-:10143000F6E68D73593DF2D073D6B017EB7F2030AE
-:10144000859F48C930DF37D5FDD0EFEBF2EEE8B22B
-:101450003E6EAFBF17A08EF8F233B2479E937F5314
-:10146000956BE7BADCEABEC818F7EE344AFFE60629
-:1014700039B7494079DA3696C1CD308E3DB39C55A7
-:101480008B509E3AA99E89F365F3CFFA818B03FABC
-:10149000EB7432FCFAAEF3D6CFF7F3823CA63F8270
-:1014A000F24FC7EBDCC4F919BCD8BC2FD4EF9C5267
-:1014B000F8FDFA9D8F71F2E341C0339BFF61F0DFCD
-:1014C000D5B59945E067A73895FE37F1C8CFB6ADD9
-:1014D0004CC6F2D18DB9E8CF19A2DB13EBD7C07D92
-:1014E00007179A7F955FC8F0E2773A7F5A6D397790
-:1014F00018FAD1C31D104AD0E40F6D5A79555135F1
-:10150000F0C7460391D2401FD8A8CBF3D0D1739532
-:10151000E49B5608FAA269F020E353A13C01F56868
-:10152000AB0C707BD0706CEF6F015FF65A316FB00F
-:10153000715DF871F03BA64ABE998514CEA7D7BE5F
-:1015400057CD49D81DDA5B670FE4E3FD19B59DBAA5
-:101550007B09EE89CE2F211B9359FE464FF47B3831
-:101560003F1FD56E44DE09D33F379B7C856027CC77
-:10157000BA8CE5EB7DBCCA40002F3EB632FC51EE82
-:10158000B5AB7246CE8BD44F1717EAF4987BAD8873
-:101590001F75EA7925FD7E34007ED07DAB57F1E3DF
-:1015A000E3E72EC903FC38BDF7923CC08FCDC66E71
-:1015B0000FDE2390E3FB29C0F1F81CEF4103E34B5E
-:1015C000791783B7F5FA79FD9DF4ABBB0BE3C54DF5
-:1015D000A49F44C64D068CCCDFA558A3CFFB0C5C62
-:1015E000A47F34BE9FAB3027DACF55901353BFB2E0
-:1015F00058BF51BFBAF875103CEFA5C55306ECE1D2
-:101600009F3F1E01AF162BCB2B69291445A504D68D
-:10161000579B8DE7C7FE68917BB9EF759D51FEBC66
-:1016200097BFCA5EDF0DF3F030FFE3CB8274F05258
-:101630003AEECB84F91FF5EBFE7D3ECB83D1EC6710
-:10164000CD9ED38FBF57DDEF8142CF4B601FCFFAC6
-:10165000EA3CFA034EC03D39745C8BFF9FD02E23C9
-:10166000FD9C88E7CF2416CF6C7C71F9A3E03F5D29
-:10167000E557E390FB38B4BB573DF609D69FE9AB7D
-:10168000C37A5B3F17847866D35803CA6D2D8F41A8
-:10169000F3E334F5CF2680A79A1F87CEE30598475A
-:1016A000A22B6C42BE0576226DD728B0386DA38B75
-:1016B000C80AB0DABE68FF8796E7B4CD6B427ADF1E
-:1016C000D6CFF9C1AE4E35F9DC63119E63C50F1359
-:1016D00087F9C65B859ECF805F6979684F677B0E0F
-:1016E00003BDBA4C2413F3DDD5FDF00DC577D879D1
-:1016F00089BFBCCDCE4B84E2F0EBF70BB5F3120BF8
-:10170000517FFE0BF126C5CE23F7B33CF2A1BC35C9
-:10171000962F5E3F8FDAC84E56867B5F1AE0DE1743
-:1017200099C9CFA04E7E4696214F2C18C137EB8524
-:1017300041CC47D7EE7981BCB1C8EF1BE1BC45363F
-:10174000CB1F8BEA47E5A769FCCD18C789113FFD80
-:1017500049A4FD7148B3B34AB4F3316113F8695A2F
-:10176000DA5C6188071CB2ABE776D5BCD8166BF89B
-:1017700018F8315A9E4CC3732043FAFDB366D50F57
-:10178000CEF0BE9EFD9334AD3C8AF67A139CCFE733
-:1017900086E9695E5CBBEC8D1C88AB1C1AB2CB5E23
-:1017A000CF8173341A9FAD9719BFA8EFE3D879AAF8
-:1017B00040F4799A3113BE5FBEAB7D17AFFDF409DB
-:1017C000F1F8EDB7C199F1DB43F1CE21A97C528349
-:1017D000A39E1F5D2CFC86E492063F4AD7C86F7516
-:1017E000F0D3FBC334BF16E914D1EF45759200E482
-:1017F000656A7EAD0B9587F3BFE77DB95079D83028
-:10180000219E1DFEDDF6279E9CB8D87D19210F6113
-:101810007F8AE3CBC39CF27F51E7ADCF2750E7AD82
-:10182000CB2738640CCF67F75150F8B847E613C49C
-:10183000C5BF6FC927F81BD6A9CB27F8E675EAF311
-:10184000091E39F09003426E70EE0CFC0E03BB8D46
-:101850001847AFE66D1E96E7C5B3BC50E2C1FB3139
-:101860009B2C56F42FE8F3E028A75ADF0CFA6539D1
-:10187000D5FBE15CCE8E0E94CB0D193CFA1C21EF0A
-:101880004F9462E4590A3549416964BE17E4B1E3F3
-:10189000F9FE8BCCF7DA336128EFD2FD37E65D062F
-:1018A000265C40BE57712EA3BB576D9F8D8ABCBF6F
-:1018B000B2A2881AEA45F1F3ED5F56E93551CDD36E
-:1018C000B5080A89F447C56B777002B3775E358532
-:1018D000DF0D805E45BB81F865BA895AD3A5C3E7A1
-:1018E000D68FE77B5F87F9537D04F7F7CC8BEFA0AA
-:1018F000DFFE910C2242FEFB234605F75949218861
-:10190000D75A5E8236CE5AD58F7DA1FCE7C8DF5903
-:101910002EFCD7FF74BE33227F89D1E3DFC06F90E6
-:10192000FE86F88991C575B47B2BBE55CE7DDF7CD4
-:10193000469777116F5D5FE613C487F113BD1913E6
-:10194000918E3CE867BC58F997584AF52180C73E0C
-:10195000B304A46651EFA720F764687E5176DFDFF9
-:101960007DE350EFFCD8CAE6ABDDBBA1AD67CAC4CE
-:10197000EFD78E2DCEF1964EA4F33E3EDB83E77774
-:1019800037D899DE167E92E5AFEBEF91A074C3EEE7
-:10199000D550EFE1D59F87AFD6CFEFEF24BF974F5C
-:1019A000FC1F4E471729BF2F7E1DD1F6EC213BCBE4
-:1019B0000F1CB667FFDBD67551F25ACB172EAB184A
-:1019C00054FDFD1C017FBF364ED3203B6FB351DD6C
-:1019D0004FEDFDEF54FFDEA1899E4D4087A5A5C1C7
-:1019E0009D70EEA49138F01EF1C6C0ED7BDE74B19F
-:1019F00073B4582E607147E2B5E139EB1DB9BE07EB
-:101A000018FD86D6037D8E779132881B74152C20A5
-:101A10007536CC277808E860FCBAD0CE374B319FBA
-:101A2000AA19E855CB272E3BFFD9FAB9A5385FF4A0
-:101A3000FFBACCD1F76FF44D64F6A0F67C4EA50347
-:101A4000BAED19309FD32BD9B9D2269747043FB2AC
-:101A500016BF4E940631FEDFB88F194565602B42E4
-:101A6000FD1D6391BE1AF7CD2E81B82609584BF0A3
-:101A7000FEDD3FB17BAF4FAF1D8DFEC69202DF2F63
-:101A8000615DF652FFE560478FA7E340FCF3F4DEAB
-:101A9000CB4B7C31F8661A9FAC407C388D27810790
-:101AA000C461BE45EDE7C5E82F5E1F463FD6CE892F
-:101AB000128B27BB985C6FEAAF21CB6DC3659B2B64
-:101AC000FA1CD540E19C9D308F9D13595C5FCBE79C
-:101AD0007453350CFC867A7C72ABF99C356ABE3245
-:101AE000512CC379CA59DF9ECFA9CD4F2B6BF99CDE
-:101AF000895F30FB3D4B3461FE877D23E3AB641D82
-:101B0000C1B8C1CCF060651285534E4F7026C02914
-:101B100009C08EF7B186EE9E4CDFBB460933C11F6C
-:101B2000B2B375CA00E8BFC2A6C11FC09648DD6245
-:101B300005B81877E47ADF033C21427301F0A58AE7
-:101B4000DF1BD979A34D89A857F664D6E379A3336F
-:101B5000EF9963DE27A03D15D29E0E7187AC8DFFF5
-:101B60008EF17DFB3E2EE6B9B44B8B6CEA79A4F680
-:101B7000748863D8370E2AE5B4FFAC7B39A29AD1BA
-:101B8000195C3AF8870503C8D7BA3E764F5D5DB752
-:101B9000B3C282F286F96BC84C17CA1161D395069D
-:101BA000E013421BD562E93AA714B1F8746E8F684E
-:101BB0000039F5CF5FF331E348E755BC6EB0844C94
-:101BC00000AE0673F860BA7B385F473BAFA2F97B83
-:101BD00086E4CFBEA5E8EFB9F8FCECF0F598FFF786
-:101BE000752AC657E639983D4205917A4F4B74FBEA
-:101BF00011F7B4A87A8B6617EBE9409FEF9C533E30
-:101C00001AE982F2D1C036318AEFC5CC7B6E1598C5
-:101C1000DE4DD7616A8179CC4E97C13F77A179E6D5
-:101C20007A7B7A48CF51F5126DDE7F6B5EB6565FD8
-:101C30000FF9D831FC1F9A5ED3A99D67FE9ADDA3E8
-:101C4000355EB5278E76FD5731BBAF50CBFFF0E345
-:101C5000533052FE89F813BA4C013CD8E73434169D
-:101C6000617CA911FBD9C4EEDB1FBF31BBBDBC1425
-:101C70009E22E128BC8FEE5F3D1EE3B7942E726377
-:101C8000D0C5918946D6FFA644C463E17E82D98C33
-:101C9000823315F1587890E1EBBB13197E69F9672F
-:101CA0005A1CF0D0449F17CE1B0EDDAFD19AC0EE68
-:101CB000D750F3B8EDADEF3D0BF756EC54E3C0034E
-:101CC0002F4F5C80F1B94D0207F6E139E7D2F1E020
-:101CD000BFBBBE88E1B95D1824A22D925E07F01C3F
-:101CE00060D601767E4950F34D854DAE5D809F16DE
-:101CF000B70FCF3BFEA033C8633E9378FC81B91287
-:101D0000D81D6113E49F9D6C13C2ED4ED49FA2FCBD
-:101D1000647ABF171102985FD354F4F7B543EE2DE0
-:101D20008AEB9FFA4EE728C8B7F8A7BE2B5EC7F329
-:101D30004F5DFC3AF4E727987D425E66794A31D6DA
-:101D400015E5BFFCDED7A5F92DF5796723E898F9ED
-:101D50003F347B488B3F108F1295173E601483A051
-:101D6000F7409EED7332E8D54F5823F3C29E57F1EA
-:101D70007EE8FE3EE2B7C2B9FB8FE1DC30CA3B79B8
-:101D800023C4416FE7EDDD60DF7540BE3EE897009C
-:101D90005F2EE2DCC2FB76CC7B6815D8B906A2B018
-:101DA00073112DCB9B9F80F62D6D6922C05FA968B2
-:101DB000FE159E7B30106F077D7EAEFEFE84361FC3
-:101DC0002D8F3F9EFC1C91C7FF2DE71032E29C43F4
-:101DD000785BC5FB826504CF21908D9E5D30AF9E00
-:101DE000368140BC37792E2B8F172CF87B2856C8AC
-:101DF000871E85E746316F394CE109F9D756C88708
-:101E00001E05E744D87D85DC82B9887FC9143EA0D1
-:101E1000177418D9FD84CA3536C4A7CAB92C7E995F
-:101E2000EC3521FF394B64CC9F57E01E3317E05946
-:101E30003BE267D89E8AF1D7E41CA6475ABD2683A9
-:101E4000C58DF9CE88AF614ECB77667CAF67A9842C
-:101E500079E843F7152E27B83F9B72AB33E0770044
-:101E6000465F65E2205EA3C9990A153F7A76A9ED1F
-:101E70001B587BB8CF10E6475A58FBA1FB0C7FCA12
-:101E8000EA5B8510DE07447518F53E3D56DFB23833
-:101E900015E98757CFAB92EBD47C7B8EDD1FD5B293
-:101EA0007834AB77303E486E4A50E5B9DAFED664F6
-:101EB000BF1A2F6079F3AB0CEA3D00DD24329EABF4
-:101EC000D159F2B79CBBF8C570FE3CD273C7E5226E
-:101ED000E6076AF73156D84CEC3C96259AAE9E2917
-:101EE0004A66785F2E5B60DC656E4FFAA498FCD181
-:101EF000BF3492AF8CD6F8CA4D269D5D96C6E0EAF7
-:101F000008EF64E7B6CC176597C58F2B3E99111D76
-:101F100057DC93111957D4F6B762A509F94A8F53C4
-:101F20007A0DF28FB651D0C2FD76FA756F1BBAA743
-:101F3000DA6F05BD546F0F1E8A9367B46812F3E71A
-:101F4000C971FC108B26C5932F71E2B425E6FFA65C
-:101F50007833E3BF0371CEE90DC14BD39B2CFAB8A4
-:101F60008772517E9F01CBCF900F7A3A0462BD8C6D
-:101F70009675E7CA281F44BEA8B49BC50E17F0D1BA
-:101F80009F215F6CA596AB39822F5273F412E0C784
-:101F9000037716E0EFCBBC76A78CCFB3562EC04F9D
-:101FA00086677809684C4B8A0F2C847B9BCFDAC3F9
-:101FB0009970CFF3BAC96F5C8BE594F01128DF51AB
-:101FC0004C16613937BC13EE7DBEBFB8FD5AB8D789
-:101FD000F92CD0D868426E7DF6B66B9522FC3D8414
-:101FE000F583A0DF97EAF2F175F7D0C2B951584FE7
-:101FF0009ACD8471DF34F5BC2EA952FD4390E905DA
-:1020000074975182797A3622ED1B84FAB14CEED264
-:10201000FA36B8E7B423D7CDE2D084F1013256CDF9
-:10202000E3202105FC511D6E27B61FD2EFF699D58E
-:102030003C3036FEE1E7D8FD3CDA396442C47160D9
-:1020400037DA241255D6EE752682380EEE61ED5041
-:10205000F1402BF7A7F91E9A1461571E9E737B114E
-:10206000ACF3E3E7EFC8017DEA87EAEF32E9F1EA92
-:10207000C6C90CBFDB13FFBA04F8F8BBBC4306FFAC
-:10208000414B9A6F17F4B7DCD536CD49F1A74A9C7E
-:102090008DBFFF324359CC015F715ECDE6E7ACF2F4
-:1020A00072CB8B867F1726C527A09F9EF87A78D0A3
-:1020B000B7538E7B45804FBD259C29D07EFEE4F230
-:1020C0003D03FD9E5BFAC16D989737FAF011B81F7A
-:1020D000F2B0B1BBD201F8E456EF03A63B06E763CA
-:1020E0000E8E19DFABFEBE0D3B2793CBA971D860D6
-:1020F00015C8852B08C35B2843FD95EA7D67D5226B
-:10210000BB3FB3BAD48DBF57369F8405C087EA77EB
-:10211000BD0E02F471B5AF34D6FD13DA93A41BA53E
-:1021200048FAB95C8A28D3FFAE2C882EFF488E2E41
-:10213000FFB8FCEBFCA8B2E07963520AC837267FEF
-:1021400094E94CFE8824D00EF2F1A966710AC6D536
-:102150005D9C02E5892F8CC6BC2492CEF2192638EC
-:10216000B2FC0C0ED9DB615D612AE77B5DF0BB47F9
-:10217000EC1EABD4774DBBE09E042249DB810E9F61
-:10218000371660DE66AAADF69FDA509FB1935CE425
-:1021900053D276C46BBB4582DF6F78C5CEF2113A5D
-:1021A000EE3760BC8973580C1EFA1DDF2B30F96FB7
-:1021B0005F5909F57C19DD102AAB079CEC77943A3E
-:1021C000A611637B09EC9BFC2EEA45760BE6ED57E6
-:1021D000390A7E02F5BCC384F73ABC622FF3A9E347
-:1021E00011E8FF31FB4A6C0F3CDA48E977C0CAFCC2
-:1021F000EB3CB58FDBD9F8F87B69FCCD441DDF42A1
-:102200004C50AE2598873FE014D97C6F35603C0474
-:10221000EA2FC3F959B05EBB8770F8DCEB6C01EFB5
-:1022200063E7881A1F6BC3F2432A1FEC308AAF00A2
-:102230009E2A7F2604F6A3CAF105D2016F70C878E2
-:102240006F8E87E4B85209F359D0EFF9543108F989
-:10225000ECFCCD0EB49B41F3817AF02110A46BC14C
-:1022600043CA54D70C8EE7390A783C9E235ED88F38
-:102270006B8BB3901F3D6A38BC05F32B6C5EB34C7F
-:10228000C7315D47707FE5C4D8E75DF38A199D8E3D
-:10229000DCBFB274C8E3E01CE5123C3BECE5129CE9
-:1022A000DF1970CAE9DE88728C7DF103DE0CEF8BDA
-:1022B00025682886FD9025D02FBEBD3F5A6F83F537
-:1022C00048382F7EB42C811D9AE3A0FD50BE2F8F7D
-:1022D0008ABD8E6BD57504D4FBF1F4F595C586EFF8
-:1022E0007B9D3AFCFB8EEB4C8D5EE7F738CF10F709
-:1022F0003DCC93CFA4F3B30DCF8FFE13EFEBBAC257
-:102300006640FCBA42BB37A920FADC85FE9C0595E5
-:10231000C05B81CFFC50CD1FAD48FC47F4E35F4E5E
-:10232000F57C906B07137F9603F99BD5496D9D8CC7
-:10233000389A4F2F077E6CE190EF5C4982EBE1FD0C
-:10234000D9D9BE479CD9C8F75717C3B931DE979F73
-:102350004CCB1F1BBB73D6B8912FD6C37B1B092355
-:10236000DD5D01BF8F067437CFDF09653A4633DE86
-:102370009F45E910E856A3C391F3A77449BF1FD343
-:10238000ECC0734D3B48100FA6A5936E8EF95B9A77
-:10239000516E1169DCF03A29D1565B9A711DBF6DFF
-:1023A00053503EFCD0F98000E587655F1BCC6BD1B4
-:1023B000E44FF0DE7B92BE341FEC4E3ADFF6FF971F
-:1023C000F31D79DEFC9BCF51FCBDECD1C78B599C32
-:1023D00043B3475D09549FA0F39438874CA8FE3857
-:1023E000649F1A2D9897307C3E375C87E780B9242C
-:1023F0002FC833ED7CAE9EEFCEBA8CF1DD8FD7388F
-:10240000E476BCAF700FDAA54D57DBB4F3BBA87F01
-:1024100035AD34A8E77739942B8DC482F7070DFDCD
-:102420007E1CFDE352877F9F633F9CE32DFDA673D7
-:10243000BC129E1356D6B138FD907DD72032FB5585
-:10244000FB9D875BB3B4FBF8999EB2865C907D1BC5
-:10245000E37C2FEA8D24C9A0DAAF4C5FE8992E897E
-:102460000AC1F82AD3C3179BB07E73821F7F37A59A
-:102470008EEF4624F963B153BD17C16FC5DF5732E4
-:10248000C979C027B438EBC21CDFFB80BFCB8B3CC3
-:10249000991C5D4A9D89C54F291D6C1FA4ADE6920C
-:1024A000E6C7E0F7B32E27CD6F1BB2910E8E221D2B
-:1024B0004CFC84FDAED6301D1C2B86FC06C2FC01F4
-:1024C00057A871A2973E7EBC13F6FD2C47D8F9AEF3
-:1024D00002FDF92EEFA9629C5F48FD5D9D68BE1369
-:1024E000318FE346360F17CFE33C3E8B358F1174A7
-:1024F00048FC383EDDDF663C47AEC323FD7CB8FEBA
-:10250000DBF1BCFFF6EB89C84F07393E6805788ED2
-:10251000058CC88675FA0C93A7A13CF7C1FD669A95
-:102520005D3D62DEBC0DF775E1E2A13C9DF91965E8
-:10253000102762E33E94D8F820F83D9AAE37227F08
-:10254000AFE99F847ADA41C52C421224A962F93599
-:1025500032FD1FCC6B11F1CC71D27EAE126BF0BE8E
-:10256000B4ABE7E9F37294BB9A69FB6BD43C9F85EB
-:10257000571B8F46EA9B678DF718010E4A9DAD9950
-:102580009F01FD09C3EDDD23E132E2BEA64EC69FE9
-:1025900008D573A0FF8EF200F2A7787C2A6FF25064
-:1025A000BE4FFEDF98EF533C19F1E29BF37D64359B
-:1025B000DFE7356318EFE1FC4DCA8AED6BE83AF3CB
-:1025C0001F2EC2DF139D93BAEAB1FB69F9896D131F
-:1025D000B0FC9BD4EB6F390CF53BF3B05C65F86451
-:1025E00009D04341D9E22BE077585FB3B27ED213D2
-:1025F0007C3D35F4BBF4E2AC2970B14B95298CDFFE
-:102600005D39B9612AF863AA1258F950C93B53B031
-:102610009CA596A7BC3401CAAF719F2C89C517270A
-:102620001670C1422A6FAB92D9F7F3A63C391AEC67
-:10263000F8AA0A569E28CFDE940DF5864F97C4D28D
-:1026400097AE9FCCF8EAACAFCE768E72415898FD2B
-:102650003EE80B9E0FF07736BC54DEC2397C6F39F2
-:102660008BC3793D2502FCAE538587952B6D6D1983
-:10267000C007E7FB4CA51077156DEE4EF8BDC2A460
-:10268000F2D9D360DF2BA9BA0D714E4A5F37009E95
-:102690002FBAE4934C07EAA51A7D8946787EC37D5C
-:1026A0008BCBD8BE45D303ED6F15F67769B4FC1C10
-:1026B00041AF3A3CBCC23296E11D958BE6F291F4F3
-:1026C000AAE7DF647D808BA4D71D80973CD2ED5AAA
-:1026D00018DF641894E0FD784E9E207E03FD9E3541
-:1026E000BEEFC638107DC15F1A836FD03F41D3F370
-:1026F000D92C443115F397595E4FFF3BD81E8E837A
-:10270000F01938FE26189FAC67F3D901F790F060F6
-:10271000EFF91E053ED198CE7EF711E2FA40A7E907
-:102720001ABFEA8B5E6F47B97C93931F395F83852D
-:10273000C1F16A551FFB7DAB37A5844E7621693602
-:10274000C27A1F4A742810CF6DAA65F74906D27C59
-:102750000FC33EF106E540889697138F89F137CF76
-:102760007698A7B62F8DEABE345ADEC77C36F8833A
-:102770007B4E46C0A34FCF47A3D73FBC2F8319F052
-:10278000CC807B54B2619DF2463EC67A88D0BC298B
-:10279000D24FFFD0B7FAE909F3B7C866F55E94F0F7
-:1027A00092487F5C87BDF991483B999A65789FD1A3
-:1027B000A1B61C120BEF343DE910A7FAB5A8DE0B49
-:1027C000FAC0E7097F45FD84528CD798097EADF9A0
-:1027D000A8C770268B08F1EBF4DA74C4D72D542FF8
-:1027E000013FBB5211C8467FF94E9EC0FD03C37026
-:1027F000A033710FE3E7F1C9CC0E4C1B8287827CBA
-:10280000D464E062EA57C7271BD47B50D9F9D2467B
-:102810008B99E57FAABF4BA1E5B1345A8AD637E33D
-:10282000FA2C8C7E74FB3422AF459F27674943FD09
-:10283000429C4264908723F360F4768282EBF8D165
-:10284000507C8130FD67AD1DF59F1FA9F1056EC15C
-:1028500017B83FC914BFCC2E8823481CD82BC9A554
-:1028600087053269F87724E1F797C09FF57C96EFEA
-:1028700093C911F1F837A73D817921470C2C0EAA95
-:1028800087CF5743F00961BE6AA3C6AFF4EB8F331D
-:10289000FFFE34EF5F61BC8FB9C132A8D4E253545C
-:1028A000ECBBA1BFFF0B8F9234BF00800000000083
-:1028B0001F8B080000000000000BE57D097C5445DB
-:1028C000B677DDBEBD25E9249D859010960E3B129E
-:1028D000B03B21618726408651C000A2A008371076
-:1028E000D6AC82CEA0E3980E0144079D38A2328A6E
-:1028F000DA202028308D02A246A70544FC74346EED
-:10290000E3FA98C40551B61844719E6FFCCEFFD40B
-:10291000BDA46F13467CCBEF37EFFBF0375339B7CD
-:10292000EADEAA3AE7D4D9EA5475923B6B5492474F
-:1029300008F1C38F3FFE982FC495F4A7E82644639F
-:1029400037CDEECD13E26A5134D6AA08913C4EB38E
-:10295000692E21C6AAF47F038468D9A6041DF47CDD
-:102960008C3FC6225285A83C640B06095EFC8A2A6D
-:10297000002F7E480D0A825B84776D23DA071CEEF8
-:102980000095F7C7F5FFFD302A3F7DC8E675A0DF4B
-:1029900080FFADDED46F09FA25B8D75A8BF0380521
-:1029A000FFFB91FED727182B3CBD5BE1BE5B924D30
-:1029B00070BF500753FB4BF77635D5FBC29798EAAB
-:1029C000730FE598E0BC8621A6F603DF2F30C183A4
-:1029D0001B2F33B51F7A74B2091EDE7C8DA9FDC88A
-:1029E000B3B34DF5A509850797D27C0FA6AB421965
-:1029F00024C428516A6A5FAA96D98585FEA8B37D4A
-:102A0000D248EF55D17F3F7625589D61059ECFEC8A
-:102A100055444A9610F3D7CA7AE3BD05F577AFCC93
-:102A2000A47261D0FCBC54585B617A6FE9C70BDFBC
-:102A30003810D15FAFD4624B1295A3BCF1A947FA0D
-:102A400062C262E08F2AD3D51B069DDE51BD0E49BE
-:102A50000AA6F3E2ED4AF00EA2634FD1E37ED08DD9
-:102A6000E82C821ED055D6B7AC538301EAE7BBEA07
-:102A7000056F1CB0117C28776D23D17F7E8DC3AD8F
-:102A800052BD23DD4CCF188F999E71BDCDF48CF7CC
-:102A90009AE99938C84CCF24BF999E29E3CCF46CAD
-:102AA0005764A667FB69667A6668667A662E30D3D5
-:102AB000B35395999E5D969AE999155864AA8FE645
-:102AC000DF6EAB169BEAEF8F7BE188467848EDA07E
-:102AD000BA1D6E217AD4DD6CFA9E50C7DB5710BE4A
-:102AE0004A3355A1BA5BF92040FF311F882A5E5F47
-:102AF000F3880F1E203A9C11AB0F667ACEE7878AC7
-:102B0000BD77DBB13E7F2E3F2C8BE203E2BB447CE2
-:102B1000E747FC1B797E69D0F90AAB7F95B79D101A
-:102B20000F7AB5DFA19CD6EBEBCE56921BA2A8B8CC
-:102B30005751BC102ED13C13FC542112BC77A07409
-:102B40007E9C057EC13F4706FD9F5F74B712DE1471
-:102B50001D6F62AFED78A3312E9AB752FF5E16E675
-:102B6000BD8E985145FB892145D0F83A8A860CC81C
-:102B7000A70C51A5A04C17DE552AC6EDE99484791F
-:102B8000E0CF1F3399309630BDFF41898DF97759D9
-:102B90005CFF6DE0CBF76B255F9E4693C1425C23E3
-:102BA00042367CE783D8073BA1BF0242B832189572
-:102BB00075D761FC33307EAF10D789461B3E3E4B44
-:102BC000083BCA62E1E1728EF0DBF1FE5C115E89C6
-:102BD000C97C94AA6D073E2A54AD4B1AF0D1B1A11D
-:102BE00073513F2A5F4BC1A02F8857505CD07B6F39
-:102BF000E34F6AF789B76837BE33DAE9B9E15EC2F5
-:102C0000CF3E8B581022BA88F1293C6E612DEA37ED
-:102C1000B95F5BDF5946424D88E7144D03BE031987
-:102C20004EEF2620393DF4A442F3BB24D9937347D9
-:102C3000526BFB035E0BB727D60B28D4FEF15DB1B8
-:102C40008CAFBEEDD727635E3FB7DF06AFFF558C75
-:102C5000DB68FF53F3B5DBBD8B6EA47E9B1551B5CE
-:102C60008106F18E4E974C07F10F8D37534DF0D6FC
-:102C7000826E71330FB6233C2C69AF7D00BD34EDFD
-:102C8000EA5FAE04ACEC4BF12CA6F19D2A6ECCC7EA
-:102C90007809FFFF86FA3227E19FA676A293D62B0A
-:102CA000114C5124F14F7FF42B6A73FC723C077472
-:102CB000FCD7B7D78EE03BFB2C0D9DBDA0A3B52163
-:102CC0009FE9E896F33A619778B9101E0AE23ACD87
-:102CD00000FE4B1C0EAF4AF82C50E4773F4B9C355E
-:102CE000B392C63DD7529416564DE3FE06782B7329
-:102CF0001577C9C0B86DFAB89DED74BC7BB2B1AEA2
-:102D00002E34EE5A7C9FF014F8AD12DC9485E7E186
-:102D1000AD809F166EF71D3E5A7316A9979B6B9454
-:102D2000E006AA7F43C7F343366A8775E914C935BD
-:102D300034BE2B86AF588F76BFD39C3CEE4DC27B02
-:102D4000C99A2CD043B0BCCFBC4D09D6123C5B789D
-:102D500099EF4B4451E75DB00F7C5ABC8FC6F1B779
-:102D6000B87FE465597819E7BD43DFD9B3ACBDF747
-:102D70000E40C32E8EFF7B93E440FF932748BD3364
-:102D800057C7DB95A288D7E955A28A4B5AF0272A64
-:102D9000A8DD34FA0BEB93E07E18DF74C0BED67565
-:102DA0003D4334703953B89F6FA46FBD55D3FEC6F1
-:102DB0009BA8CD644B7367BB8A754AEB368BF1DFFA
-:102DC0001DE3FF76EC9B8715E0FD169263A0F79A52
-:102DD0007617C5C79314894F5AB7D9BE3C5EB7035F
-:102DE0007C9688F533A69DE43FABBBC73F5B3F2491
-:102DF000181332D284F8851485E2FED3092295E6B1
-:102E0000D9D0550D3AB2A0A76FB1EEA27936903D58
-:102E1000E1C0BCFDC51D4E51FD38D2B77748F91A47
-:102E20001F2078A25F1577301F342E5F48CF5F1BBD
-:102E300044F5D4FEE51A113F80E0977D366F2DF101
-:102E4000E1D8B3DA81442A2792DC0F53EBCBD2EFDF
-:102E50001E03FB605C47D223117AE2B2EE6698163D
-:102E60004247D0E9721DDFE3B3CD7A6722F48ED1F9
-:102E7000BE0DBD43F255057E27FB74FD7389B80472
-:102E8000FA677FF55EF129E917430F8DA61986B21F
-:102E90002FAC8762EC05D7806E447F3BD6C76C2B86
-:102EA000B507BEDD5A874911EB656FBEC274F2905B
-:102EB000E2B1D0FCDF38A406811FAB3F3C14F85BC5
-:102EC000FCBCC27CFA079F3617DF3B696B9C07BED0
-:102ED0006918969B28A8FF4FAA6920BD68FD563B3C
-:102EE000859FD6C2916A37C347ABD3B9FCAADAC370
-:102EF000E5F1EADE5C7FB2DACBF0B3BEA20AF0C342
-:102F0000EC555F5BB56CF45FC5F6D1921AAB00BDB2
-:102F100096C42F96B0CDE98610BEADD3414B1CC1EF
-:102F2000B705152FF4E2C25DC1957134AED27ABFF8
-:102F3000DD05F9D72979B40BEDEF5598EBE71DAA1C
-:102F40003A88E99E7CE793AB2688D6F9969F55840C
-:102F5000464BAE5B9EFFB798CF17D583785C5F5624
-:102F6000FB795CFEFAA68329F4BD63D5E3187EC71E
-:102F700057548B767EF135DB1113B6355961678C6A
-:102F8000F52B7ED079845F048384AFB536A957D6FC
-:102F9000925E811C18D56FF2433708C87DED4ECC88
-:102FA000736AF29CB1B057270E2A66FBF5EA1F043C
-:102FB000DBAF06FFFFD43AF288869399D4DF89808D
-:102FC000C44FCBAEB7196EB1127E68C62FEC2A2D56
-:102FD00015641FB49C7D4B3EA7766CA7EE96ED164C
-:102FE000DB64BBC5BB7F97CCCF15A55944E8BB6359
-:102FF000444741788873663EF419E1E7D8F65FA745
-:103000006B11FC752C39F4ED879093FF66F16E60BF
-:103010003ED53E7D167274B99BE5CC495BE8C8038A
-:1030200090B39D48AF727D55DC64E2B30ABBD09883
-:10303000EF84D617F0B15831ABC825FBF3F492CF2B
-:10304000C18F3D77DCDFF5379ED6FEB684E67EF88D
-:1030500000E8B0E3A3844B68BC7D541152317F215A
-:10306000C711D818CBFD943D797BB29FE0AD8A683B
-:1030700051594E04595EFCCE26A6A1DFDE8AD5BE8C
-:103080003499FCAA3B9FCEC4BC7BA9A24AA5753942
-:10309000E7AE67329FA1F71E2359A4D2F89FB379F8
-:1030A0004FEEC5771FA2F153BF8FDD599E037958AC
-:1030B000F2878597000F7F81D0223A3CF1F44EB61B
-:1030C000178827BDA349AEF55BF3E2B20C6A7FE92E
-:1030D000BA264B072A7D1B955A94A5DB76BE55432D
-:1030E000FDE5BA2D55B05FDFF279785C39A1F51BAB
-:1030F00014E8811F1EED807599BDE6EB820EE2C2D9
-:1031000076C6139DDF6F29F6B05CE0F777D74F796D
-:10311000FB5A013B862C188CB7D8EE65BD46D3B65A
-:10312000013FBBBAADC7FB7B2C01D65781D9D2CEAC
-:10313000395114F823E65F4EED030497FB1A9A6E9B
-:10314000A2FAF2A4AE2240F33F1A5C321DF5031539
-:10315000E1067E2A76DD5BD881E013C38457A1FEA9
-:1031600017EC3E5DC8FAB013D9EAF8DEAEDAB46BFC
-:10317000A00FB30BF254AA2F5243DC9FA894FD5525
-:10318000D6EF740226D427ABC46749F5A3F6677A55
-:103190005AE96369BC2BCB4ADF6B47FA14E35D9BAA
-:1031A00015C8A872B5EADF645FD169AC1BE1BEA7A0
-:1031B00018DFF99CC605FBEC62F5A5DD52B590C79A
-:1031C000932EDC81C1ADDFED64092FC43C6875B876
-:1031D00003F49D4DEE86E9DC8EE0DF73BF9A9A938F
-:1031E00007FB8AB09E2AF57B2DFA754FE90C7A5DB4
-:1031F0006CFFF7C7FD83EDB44A4B82D731A0D5CE23
-:10320000999652FB7C23D12BD85E4BCC6907FB5897
-:10321000DAC9C2EAF540EE57B7F7BB73D84E233D83
-:103220006C61FD9B9A1361379FB3DB9C17A77F43AB
-:10323000EDFD1DF0BD8B6DEFD1E312E7E4F0991CBD
-:10324000931CAE8DB70B1F3DAF5DE3E03886386051
-:10325000293B48FECA707CC2D2FABD25F139EDA1E6
-:103260001F6A8568135F2FD0FAD708B761D21B1A7F
-:10327000C98111679B558DE544C3FEC40190B7C257
-:103280001FEF41DCC022B408FD18FD1DA2D760CCA1
-:103290006F9488135A849EF58B243BD6AD70255FBE
-:1032A000E4BCC38F9AF5CFBE4723E73DACE5FD38BC
-:1032B0009860848FF6282F34AFE7F579FD19F3A2D3
-:1032C00072677ED1E5A0DFF06FDC56CC6FB8755227
-:1032D000675F571EF7243C1FF18DC53CEE1F624D02
-:1032E000F0C58EFF46851C3BF0F1D7F620D65F3D3A
-:1032F0006C059A47FDC2EC20D6FB1EBB0838E1F7EF
-:103300004CB6B31D5C1F1F88875CAD57DC21C49F82
-:103310009EB3354C977E91706FF2817F5F7F10FC7A
-:103320007F4D8B5D413CAB83431C817D25D444B1F3
-:103330002935E2FBEDDC1CE750A13772091EAC3FDA
-:103340009F6EE7E7B536C17A32303D96C7B526A9FC
-:10335000EAD57E54BFA626D34B2317EF8BE0AAAE47
-:10336000A8BF4565793ED4B261D37DF07B26A5B375
-:103370009E599314CEAC44FB85977803C40F7BFE13
-:10338000A1B2FE58E3F36724BB200749CE139DD7B3
-:103390004CF267C4A6A24CB360BE1D48CEF3F32C1A
-:1033A0006A47E58736D9EE039D6E84E90CC8DB07D2
-:1033B0004A7A08963F390577F03AA10A27F1F35483
-:1033C0004902317DEEBDE226B4D3D4A09A05BCDC1F
-:1033D00075674F82AF99ADBA11A79BBA20A649E98C
-:1033E0004FA5A6861D09F4C29563FD91FEFADA1C6D
-:1033F000FF1DA07379A84FB7CF22F878FADC1EBF63
-:10340000827CF884FC68F8DD77A4697FE0FEF7FA37
-:10341000B8DD5E326E7E849E707AFAB3BD5D62F86E
-:1034200099E139C0EF0BCD4EB6632FC40F42789DA2
-:1034300097D0F7EFB38810F8B98BAED76B110000B7
-:103440009D4331CC07E3263BFD1CAF725936C08E3D
-:103450007E84E805FD16D8ED607A91A064FADDF768
-:103460004227D64BB37439563B2D96DFABDD690B43
-:103470005A406725B87533DE7B3E86F567995DB0A7
-:10348000BF52F66C5FE6833D767FD60AF4FB82433B
-:10349000EAED044F22D7FF9F1481FAE7747D5D1691
-:1034A0001BEE994474EADA4E7B0A7823BEABE2E75E
-:1034B00076F9FC70B0603DD6A520FB266E04C1C233
-:1034C000BF1EF22A4076D026AFA41FC6A5D576DA55
-:1034D00080F16A340ED059DCACF27C0ED35AC6FCB3
-:1034E0000E5775E2712993C765CCA5FA4F17C771BE
-:1034F000DCF570D1C133B0030EA7ABBCEE4942DDA1
-:103500003990EA49E736DC4170E5C24F5E1F484F0B
-:103510002B6A3FE8BCD7D38AF719CBCAC70BE28323
-:10352000198B6E9928122EBC5E679439E053B6AEA3
-:103530006F618773276192EB4D39FE06F0C17FE41E
-:10354000686FA3ACCC267B9BF8E8A4BDE161C455B1
-:103550008E7AB4BF022FA79EF962339E0B6B734F16
-:10356000E60F676321E23265161957BA2B57FB380D
-:1035700087F56C02D3AF32E460FAC5653748B97895
-:10358000CBC5E983AFEA37ED51A89FD2D8FA0A2E0E
-:10359000D5607FE8AB634A3841E9C6F8D5B0AE8E56
-:1035A000BBC309A08F6691F65EE996E879D250D345
-:1035B00010771342FAA921FB501AD72212BD0FB877
-:1035C000F1DCDEDA3EAB958EF41DA6A3707D3CF3F4
-:1035D0003768BFB54FCE1D84F7D2A4BD770DCD3A65
-:1035E0001F7FD1B0319FF3C7A3AF93A27002D6C99A
-:1035F0003145AE93E342CAAFC096183D5E20C77115
-:10360000F299F63C8E347D1D9D54F4765B1DB21DFF
-:10361000F11EEC99D23F49BEBBCFE665BD19207DB6
-:103620000279599A22E15247BA1BF656073560894A
-:10363000055F560B5E2F34365E97C77664F2FB86C5
-:103640005C13454240AE95EEC8D820ED3ADD6FC61A
-:1036500004A8FDA227647F8021FFBF7A3C53EF5F5F
-:10366000AEA768BA46E3A15BAE8C73D5C6E7B7FFD9
-:1036700067F1CDDEE91FAD8308BACF26D775205E8E
-:10368000EA11B25BD227F5C3FE84DDF4DD93F1F6D7
-:10369000597E17F629CCCF8DEF5D9AAB70BF5DA236
-:1036A000E8DE416D7E11F6927854B09C881E477E0C
-:1036B000AEF4571F7FFC1C9D554977622483BF3CA5
-:1036C0008C3F61037D3EB01B74BC2193E47A29706A
-:1036D000D5B5158F7B7C5A26F4C849C084EF3D4987
-:1036E0000467C3DE92FAC3800D7A44F3E9B20FE6B1
-:1036F0006536D2FB7372A57F501B93D05F24A2EC7A
-:103700001C841CA821BCA29EF4E0ACA26CF8C3E30C
-:10371000EEF9CCD63A9F23D57E3FA9A073F0BCB575
-:103720003E27D6E7FC753EE7EC087AD46EC93DE447
-:1037300021BC1FDF62456452D45A83770D49C5739B
-:103740003514105CEF04BE8FBBF6BD8E76F3D62524
-:10375000E5A811F269FEDAB1FE92083AF4DD62A63C
-:103760004BBF9019BE74AF192E27DD8EF9FDDCF723
-:103770007C61339C7BC80C3F3DA859FD11FAC9659B
-:10378000093A15942DEA8F90EF4135083FA3CB2DD0
-:10379000455326107C74DD1C2FC83CFFDD65F9A065
-:1037A000DF89DDB7ED29A7F78E265BBCF0AF8E89E8
-:1037B000D05F27103DE6D5DF6DB77A305F339FEFDE
-:1037C000B1E87CFBB88C032E0C9AEBCF970F357ABF
-:1037D000DC49F48EE4AB68FA53BF57F96960654B76
-:1037E000A7DC03FB67C17862781ADFE0D0DD76E101
-:1037F000BA987E028C576B8208A7D3F89A6E8BE733
-:10380000F8CB90A5A3C5A7F4BD72AB3BFF3734CF6F
-:10381000D94EC51D70B7C6D59B766654409F6E7253
-:103820005BBCE4E308F7A0AA839903E04F8890DB30
-:103830008BB8FEAD2BE1F72FA84A60FC2C14418E0B
-:10384000CBCF5EEE68958FF4BF92D551E3591351FB
-:103850004FF358B0CEDC7ED1C61F1D91B0E1970E5C
-:10386000A95FAF62BE73F571AB8189AC9787E8F150
-:103870008ACFD094F4CD13DD8A76E4D27C87AC195C
-:1038800025EBAD4E5DCFFAD9CF2B77D93D2CCFAC00
-:103890006FAEE4FD1D5A87D00F87E2E7FD0AF2EE16
-:1038A000B453B81D3EB4D7183E9222FD42DEB7A0F5
-:1038B000F6A7D729ACD7CB53245CFEA812440CB88A
-:1038C0001C415BC08FC9386D998E0FF0893F623EF5
-:1038D000A057242CEA8CF87898FDDF8A2AE1851D10
-:1038E00020888E7E036FBC1F15B61F859E0D28A1F4
-:1038F000077CB0F7CCDFA9DCFBA323123E175F26C1
-:10390000D2D5F0F7838C47D52EFC90E3EAADB16CAD
-:10391000B7930288857EB7E9F6B558156C077DB573
-:1039200006FA8ACA15BA1D1EB85BEAAB3549FE9E77
-:103930006ED4DF9DE1051EAE5174FF16767D12EC4C
-:10394000EB7DDC6FB3E2766F48427B11884965FB03
-:103950005AFA09FF5059DF3593FDBE01F6BA2F140C
-:10396000C678D6DC9BC5F6FA7386DEBB3346DAF33F
-:10397000E7DBDD6C5F897BA4FDF8A1E0BEC555DD0A
-:10398000B593B934BF396A116F46952CF367E0BB24
-:103990002593ED16D0432CB8B87D914D56D97F3381
-:1039A000CD17F1FACF94A28396483B58D70FF9056B
-:1039B000FECD7A3B2FDA9558DE643C9458841BFE8A
-:1039C000FCA6B3AAB012BCA9CE115C46AF9474F5A4
-:1039D000F75C9C8DF7647CEAB04FCAFBB801C21F4C
-:1039E000A4D239407ED739C0622AC5181967F92C8C
-:1039F00046F2E10C5154C8FB031E29EFA3E7913AAC
-:103A000040EABD127B83793C1FEF67BA90CE732FDB
-:103A1000037F8F9176C767D72BACCF693E3DDD041E
-:103A2000E7FF2186E38B9FE9FAC8C02FF14F1EE222
-:103A30006886DC4AD2F965CDEDC1AD3184EFBB6D4E
-:103A4000C437A01BF1CDA6014C77B60BD74C4F6302
-:103A5000BA5FA3D355DC19CF741B6AB1483CDF9918
-:103A6000C178A6F6E2EF786FAC47DAF317E9871171
-:103A7000DDB307E49DEF8F19F416D660DE3FDBBFA0
-:103A8000297F7AFB9E00F1FFA23FDD9B20A8DD97F6
-:103A9000D6BA342FBD5FB66945829FCAA3D640828D
-:103AA0009BFAFF32A88E0BB681EF453ABEB17FA0DC
-:103AB000A461DF55CAF1AF1EFFF79537D338BF5564
-:103AC0004433E463C5AEEF57DE4CF33BE87736434F
-:103AD0009E1EB5361642EE2E2C7655D578B17ECD8B
-:103AE00071FC458FDD9BE6617C07322DE9BCFE331E
-:103AF000F15EC5469B177E5DC53BAAD783752F9A9D
-:103B000057627CD1EF57863EB503FF6E8B68EE3867
-:103B1000B48D7AD1C872BE72D7EFBE5613507EF9FB
-:103B200021FC8BCAA8FD8305FAFE4AF43EC2350388
-:103B3000E2538F2040AEEF5F137E388F2140E3EADF
-:103B4000C1EC22E3CEB55BEFEFDF04BB61E3AB0971
-:103B50004A76EBFE81B1EFD2129AF3C8B39E0BAF57
-:103B6000CB937ADCB8956E528E79F6D2C0DA0B041C
-:103B700018B82CB3851360EF97ADB7B11C29DBFEE5
-:103B8000E8E607C06F1F38BC3D3C804FDB210FCA01
-:103B9000147FB3C2F25D2428F9ADF42ADDFE79E189
-:103BA00083B0AF3354319EE8B5E8A933B2BD5F347A
-:103BB000C750FBD29D4D85F00FCA345795B30D7A8F
-:103BC0008D0EBD686F74B541AF505321C7A9B67E45
-:103BD000C7F4F8F20545B4CF3AFFFD05EB3FB70B4C
-:103BE000E91F34A724497C41DF5586D4627BE2F982
-:103BF000EDE9FB139F1DC0F56EF82B3F45C721C0B3
-:103C000005F37BBC4882DEFED0111C0FFAEE589201
-:103C10002088FFBFB05649BE7F68451AECBC05B688
-:103C2000409A9B4BF97CC1C337323FCE57AAD2DCB6
-:103C3000D9CCEF1996413CDF0CCC73EEBAA93CCF3E
-:103C40007942637E5CF0905A14A4F28C558CDBD9D7
-:103C5000C6BAF94C5F370E717D7FAC9333F425E81B
-:103C6000F12F74BF3EF096F4A71D627262E47ED21B
-:103C70006E5D2E0644F030F44065838DE314EA9BBC
-:103C8000670AF19D1BB2AC55C8F7A0F907747C29EF
-:103C90003F4AFFC583BC874AFC45FA74F49B63DB4B
-:103CA0003766E3FB2DF6EBA8DF6FE0277A4DEF31A7
-:103CB000DEBED8E088552EA5324DDAEFD1F348C9E3
-:103CC00033D6BF784B44F053E5962F989F44BA2AD9
-:103CD00012D3258CFD0BF76C575522E1ED9B773EF7
-:103CE000B523FE1D48B5881E186FC3E70C0B6F3B4C
-:103CF0000FDA1BDFAFDCEB10E1C875BBF1F3A87581
-:103D00006DAE17A28AF15929123DD0DF5FD89B0B07
-:103D10009F433FD4EF26EA671ED95F61937DD55C50
-:103D2000F820E4C95EBB9BE30F647F8623F8E6DCE2
-:103D3000FEA8BE2F385F9707D17888960F87A3E437
-:103D400083F1BE58D7F67E54AB5C08307DCB6C2235
-:103D5000003BA3EC0307EB8FB2ED723D0A92A73D47
-:103D6000687D1CDBB6FFAFD7C09F0DD952C773AFBC
-:103D700066F9BBE0C9CF795E7308FF315EC8DFEF3B
-:103D8000ECF07FD3478B66078DFFD86A9F1D7C7F41
-:103D9000DE3AA6E76DAEE3D50ACBB7FFAADC257CF9
-:103DA000DB616FFDD47A9D7F01B91B9367CE1B3A0F
-:103DB00023B21387A2D25DDC85F70FA2F06BE0354A
-:103DC0005A8EAE1FE09171E928394AFFFE2A22F08F
-:103DD000284423F3F1B72417B10F57B1F17BD66B09
-:103DE00084D66607F17145F06B865740AF31FCE22F
-:103DF0009588579E3F6F333EA3EB5F05EF139F15EA
-:103E00003D6363BBA0AC5EE639D27BEC7754225EA7
-:103E1000CFADEB0E66A646C2C1283814D5DE1F050D
-:103E20001745B5D7A2E02A53FBB2BDFBD9CFA2718B
-:103E30009BDA39965ECE7EC8F9764590E751B9EBAC
-:103E40006B7B00FCD1B1D90EB9685B2602F1F47E20
-:103E5000F3F32ADBBDA73CCD09B05356C4483BEE73
-:103E6000945B87930C58CC2AA6719C0AF47723AFF5
-:103E7000A03946C65B4E1535272445F8ED4DF56A49
-:103E80008287DA3706C5B8B6F3626A99CE8DE24208
-:103E9000F5D29E1BABFEB043E68B5A8583FA6BAC22
-:103EA000F96E07E2499F91FF04FBA5A4E6EA04EC42
-:103EB000BF9CAAEF76C534F881AFA89CF325027E9B
-:103EC0003BF226E648528AA32270DF309A9F1A3FBF
-:103ED000E0E073F0AF8851B0FF59B23ACABE114565
-:103EE0008961F8D36BA2F31B8276D837F349CF42AE
-:103EF0001E2D5867AE5F547F8CD7CBA2A8F5A2E9E0
-:103F000071E3E8F55269AC179FF0E9F9969CD77711
-:103F1000EA90CAFCD5B2DC2656A6CABC5AE4A3B4C1
-:103F2000D4CB7C9D96BD1216013D0F485FB706DECF
-:103F30008E633DF5BAB0DD727CF7BFE5FF06FCB3DA
-:103F4000E7A3FE0F52797CCF073D9F03FCF47B9DD6
-:103F50003F12E7B71FFDC2F733795C2F3804C675EF
-:103F6000EA85973BC3DE38F5AC83F3114E2D73B071
-:103F7000BD1E78219EE316A73A497BB8F6F9EFFA01
-:103F800037B23E5ECE747C20CF2EEDAAFA7F67FD5D
-:103F9000D852EFF0601E952FC4F1BAAA7C3686F78E
-:103FA000D54E3DFF5D7E643CEEBF3A1F631FFE545D
-:103FB000BC98F624F857B7FF2B9F1BFC680DFCE557
-:103FC0005D2FDAE720AFE4CFFFD11FF2F5D4932FB6
-:103FD000B2FC3D696B7C18B1CD4D79E1076C831162
-:103FE000D7A38F75106244BEB83690DD165E241ECE
-:103FF0004E111E302FC2CB02D8E517C2473DF0D17B
-:10400000EE5F111F5FCF94726EA0C0BE4F2B5E1487
-:10401000BF7C1ECFF12A9ABF7CFEC277FD21877E2E
-:104020006ABE1FFE7F36DFB3FFB2F395FC1EC8F3F6
-:10403000F038A3F9FE7CBE7EFA570CEF88F7F278D1
-:104040002F72BDA7E7FFABAEF7FF197AE7FFCBCE24
-:10405000F7A7E8FD8A4EEF7837F6414F3DFF1F9DE9
-:10406000C5CF98F7D4FFA5F336ECF902D57BC84746
-:10407000ED5F15A177BC596C95B4698F2CD3F3050E
-:1040800085EE4F8DC65F1EB4CF591EC27A207B02CB
-:104090007E4CAD2BE7C09B04BF4C7682CAFBB2328C
-:1040A0009EF472BA2F28E3BB5502F1AC82F7E630DA
-:1040B000FC9AEF1707905752A8CA78CCFE1AEFC6A1
-:1040C000069AC7FE248BA796E0311DE77CB693EADB
-:1040D000DD1D5437FCB3DA8EB94E4FC4F8C6B8CCE8
-:1040E0007ED6E5517ED22F3DE6FA71E2C954ECD777
-:1040F0008DCBB6099CCF2944FB08BF52CB77F33C4C
-:104100007F29EA96BB5D3F1F4FA17CE977125E785D
-:10411000DF26D051D5F3E2CC7813C05B2AF092CBE6
-:10412000F67B40780FBC49B055B7AF84BEFF58E866
-:104130008CDF0C3FDA210AC24182CF78AC55686F20
-:1041400015E40FCB79B21F1D8D37A1FBD5569D0409
-:10415000633A8E0E03CF78DE25DDF43ECF3B1ACFD7
-:104160003F1FAFFB3A2E015ED3E3BD41F045C7A729
-:10417000521167AD253C2B4A2B3E0D3C45E37D0596
-:104180008D55F297C47747ABCF8A75365CB7E7C7D2
-:10419000589324DCB1412DE2F517947CFD8DD70AAC
-:1041A0007B7E942B89F349857ECE42D5F7C39161FE
-:1041B000C7E320FF1479B95758B5703EFCE6F16E9D
-:1041C0005100BFB5408410BF55EA5FFE1EFE11CE00
-:1041D0009714F1BEE6C1F701F772BAC2F007C53A0B
-:1041E000EBF1737632E2FE51E72B260EDA390AF450
-:1041F0009ABD949E218EE5F61CC47A2CBEC7E101BF
-:10420000FD3A5A1BB89E7C2D77CD60EC5687188EF0
-:104210002D214B3F03ED5E1EC5ED9708B7928474C8
-:10422000BB9002D8E596F96AE4BC7E0BD8BE3CDEB2
-:10423000532BE32602FCD41D65577C5FB64F1F430A
-:10424000DF43BE9BD0D85E8EEDCE9120D15529E2C2
-:10425000FDF72EDD645E44F30A07FB3BC5B775EA44
-:1042600009B934BEC01CB7CE1D28F7878D3238502F
-:10427000CA11D5E24DC777662FEFC3FE971A5B547C
-:10428000BE1B78DC11C77C5EBCF2BA0979F4FDE292
-:104290001D295E0CF3AB893BF365FBE937BE4BCFC1
-:1042A000B52D31FC7CFF40AD391F79068A67E66E7B
-:1042B0007A307BEA7E7B3A75A185269D40DC71626F
-:1042C00060E7EBD8E79C78A5CAED27EAF99F627909
-:1042D0001CEF9B4F087C6D4DA7EF4D20A706F54DB9
-:1042E00031EECED7D3F88BF578F30FBABC52638595
-:1042F000F6A40BE3EAD4B32B3D9F20643E74F4BADA
-:104300001D3450B6EF32DAEB49057E9418F786017A
-:10431000ADEDF11D7C77C44019E772E8A501135E8D
-:10432000392E5EB2CAD1D42D01A52DDC8BCA5F0D0A
-:104330002E881B48F5E3BB8AC2B5F8EE4DAAD8C05B
-:10434000E36D2EE6387B7C6F0FE8A0893ACE3712FA
-:104350006B7AF07E4ED328C1FCD3747796416FCE32
-:104360004F32FCB9A651DE83C8DF6A1EE5F46EF059
-:1043700022BF2514461CE5F05AB95FD3A536DC1DD3
-:1043800072B6D927F7413E5F9AEB019FCCBD774AC1
-:1043900002E4E79C356AD8017E5F6DCE5B126E2F1A
-:1043A000E78DCFA91B6587FF5AE2F2DB312FFF2093
-:1043B000AD17E6619C8BBC0463C2B99FBAE2D7E03B
-:1043C000F7A909B49EB1FEAC9E04F8D5D1794F95FA
-:1043D0007A7E9301DF91A679F1BDD9899E1DE08F88
-:1043E0004F9676E3B86AD540297F8535DC1DF8798C
-:1043F00098D602D6E7A7F992FFC627BB7BBA987F6B
-:104400006304E6D56473F7043F37AD88B1004FE32A
-:1044100097493EBEDD2AD757D0EFB10490C7A9F324
-:10442000EF8C1A6BD17AEAA7A35358E39385786A85
-:10443000B0E6C03826046A0EC3BF9EA3EBAB39AB0F
-:10444000E5F9B12EA3255D85B5614C0A3D3FBA293A
-:104450002B0779F106DF3C35B8E01703F35AE93F43
-:10446000BEC05FD88EBE33DEE269811C2EB95279A0
-:10447000B19BE483F1E867AC5ACFEBBC85E48423BD
-:1044800009E7061B248C7C55C88DBAFBFDCE08BFFE
-:10449000DD2E7671BDBD44E6A376B1876B38FFEAA9
-:1044A0007AE15E46F066B223AC3621B6543BB97C65
-:1044B000BC9AE45D0F21B655A733BCA3DAC365A847
-:1044C000BA373F7FB2DACBF0AEEA410CEFA9F63350
-:1044D000BCB77A1C97CF5617F1F368F933C7358FFD
-:1044E000E589BB27D17AF0F97C33D343E382FC71B1
-:1044F0000AF76D38AF24A4BC4BEA2DE58FD0E55107
-:10450000D73E82CFDF54811E840FDBAA51163EEFC7
-:10451000696DCC00DF8D558F6F7F1AF18E052ECE21
-:10452000CB6A118DBC4E5A84C51B1820E58F83F8C9
-:10453000AECBADE3B222F3D4AF5DA0086B047F5DD8
-:10454000571523AC11FA69D6D224133C63E9DB2F4B
-:10455000B5A7EFF7EAAAD5802E876F3DF2D07BF49E
-:10456000FC915BBFEA21CFF5FEB03E32EED2229A3B
-:10457000256C75F27EFC233767A4A57495DF03BD17
-:1045800066E30F0FE8D3FCE56358872B54EF3282C4
-:104590003F047D089F1FEBF4295ED16DE5AFB1AEFE
-:1045A000FD4EAF42DF397C73DFC241D4FE117D3F47
-:1045B0004AAC22BC46EA9974A9BF3E81FE4A92FAEF
-:1045C000AC0072342CF5D627BF4D0BDC86FAEB130A
-:1045D000BC3801A1AD6A1F984FF06A9FDDAB22AED7
-:1045E000572F56226E4338967645C066D6638D1D8A
-:1045F00093100F663D3612FB9E41279FD3A28EB0CB
-:104600001F33BBF73E9101B954A7B8B15F83739DC7
-:10461000CE64C83785F74791077425E9CBC707AA49
-:104620004CCF23F95679DE0BC97204C7082FC76730
-:104630004A56537BC8C73A9F7D5E84FC9DAD3F9F21
-:10464000D3DBC2A5F1FC197C0FFB87AB7CD3C01F69
-:104650001D509F8D32671AC6D7C155685522F67F07
-:104660009F1A68D5FB97FD1680A8F4FE1DBDBBDA26
-:10467000E766F3F92CD65B463FB37BE7ACEC0A7DEB
-:10468000BD7A14B0236A6DDEF4546A577FEE3B6E38
-:10469000195F77CAFCECB20BE80D234E77147FCA82
-:1046A00073923CDF453B9ED88173128B3E72B0FE05
-:1046B0005A74A9D44B223B983F85039AE6B8F898E0
-:1046C000274E1CBC8DC67302E79810EFDFF5A91DBD
-:1046D000F9A1B46CAA123300AB4DC8338D8ECF1E36
-:1046E000D8F151429B71F15DEAC5C5C5951F12A075
-:1046F000178CF98C7DFE4C1AECAC4AE52CEF335547
-:104700003EBF22ADADFCB0E8B8F8B9F8B958FDB578
-:104710008A38F32D47DB8C9F47C7019B0746EF473D
-:10472000B80A2027CE1C5283D84F6F09F648146D63
-:10473000F46FC4CF2BD7D24B2958979E44EC879D5A
-:10474000BA805D9E3748DAE527F478FBA96D2AFB2D
-:104750004BA7B6C507619F566CBBE720F6292B36E1
-:104760002A6C9E978B06C617E1513823F518F2DDA7
-:1047700052605C7B1221AF8CF1953E115F05BE5AF1
-:104780001852FC9B681C2D4E4F62BB8871240D9201
-:10479000EBA2D411CA67BCEAE3760C9272D068B778
-:1047A000B0FE1E8E4B53BB936CEFFC294E709EA047
-:1047B000687E1DE33BB62ED78B7DC585A19D159CDC
-:1047C000DFB12DCE8D38C4577A9EB3F19D4E7A7FDE
-:1047D0009D0649FBED98BE7F776C873C9F8E71628A
-:1047E0003D7DA598F305BB0D92FCDF6D90B4875E0F
-:1047F000D1D7B1D17E61A829A13BB5FF62EFDB5CC7
-:10480000F6D3FB59E86AE80FBDFBC5AE38DE8FFF73
-:1048100062D7838588339F088D4A05FF1BDF1F3AC7
-:10482000C826E9B04E1D077C89A0CCB329075E736A
-:1048300023C799B23E9015B9CE64BED1B15D4F2564
-:1048400058B25BE958EEAC72E27C68E5AEEB8BC027
-:10485000C7AFD8243EEDBB260570ECB992D42DF439
-:1048600004AFB30C6EBFCA12D1CE61F3B3F0B3ED97
-:104870002DF6A3BD11875EBCDBC6E70B675EEAB908
-:10488000FA5AACC3576D4C87C57D3C57733E528373
-:10489000CAF9CB8BB34418F6C7929BE2D7633FCCDF
-:1048A00018EFCC5CB9DECB5629C24FF32A0BAA42D3
-:1048B000A3B203D13D801CA5F4C63CE44F36650588
-:1048C0006FEF99CAE77DC31B525BF34C691DF7C4B8
-:1048D000B9C89241C93CEFFBA617B2BE3B6C1701A9
-:1048E000C885C093320FA7ACABCC8F7E007C8FFE07
-:1048F00092C33D5308AFC775BA964D0EF7445E4656
-:10490000D993199C9771DC2EF74BF11CFBC56539C7
-:10491000F43EB54BD5F379F17E52041F95CDF67A6E
-:10492000D04E4DF67A7C2E8CD77D92EDD6DDF102FD
-:1049300076ABE5E9783DBF2A86F3C88DF796EA7C29
-:1049400097AAD3535C23F331EFB3C97CD5FB36650B
-:10495000F0FD1846FBFB6CDA74D84F9807ECF58530
-:10496000F6BA9ED87731C6BB30A18EC7795CE7F323
-:1049700085B175322F5C3F778CF6809BF43CF6E670
-:10498000AD0ECE5FF92AA3E15B8CF7ABAD7D900352
-:10499000037CCFDBCBF5643F123D173DEE08A3FE51
-:1049A000CBAD326EFDA52DF82DE4F0970FA5F0F9F3
-:1049B000A82FDB05F3393F40715B609F7DA9E8B00C
-:1049C000CDCD7665173BC1D43E35565890BF336E7A
-:1049D000F2DA99C86F68D9E8007B8AAF36DF9FC6E4
-:1049E0007E8DF024729ECD2155806E5F3DFEEF7D61
-:1049F00022ED17A35CB4D19C77D79425ED4AA37E12
-:104A0000ADBE2ED70E927EC7BA41524F95C785EEE6
-:104A1000EBCAF393F826FAB07F470A3E9EF327B617
-:104A2000F75020371E10C15F7D3480BD6C0FF2E659
-:104A3000CB9EDCFA3AF66BBFB28806D81FCAAD5BD4
-:104A40007E85FB3952EF4A643D24C4469EDF976E53
-:104A500079AE95162CCF7F617B092F9AB2A527E0FE
-:104A600083A473145A5F8B2C0AF7BF684F3FCEB7ED
-:104A7000237A58789F6CA7AA8F876C4AE06FB3CCD3
-:104A8000571E9F1CDC0C7BAFF9A16E02E7DDC7AAA5
-:104A9000EBFA837EA737C659C04FE5B70D4D1C0A08
-:104AA000BCBDA10AD81FA7ADDEF6917184687C4514
-:104AB000E7819FD0E55319AD3B9CFF2CDDF310DF60
-:104AC0002F520ABE045E1E57781FBB74E5D0FB99B7
-:104AD0004F5FB7891ED4EFF1D03D0991F4792FFAD9
-:104AE0003B762FB72FA5F6F2FD5713789C9B6D9C54
-:104AF000D7124DD78B7EFF71F5A2DE3F37FF10D95D
-:104B000005FDCFC7C369D1F0AB8FE8FBDF6C8B61CC
-:104B10007F903C003EC776CC169A87791FDB1EC378
-:104B2000F2EB589294135F903C0DF4C2382EFF3D87
-:104B3000F3E95B53F8BCDFFCA0F9BB46BF1FEB7287
-:104B4000BC3CC59B08BFB3FC0D290F895E57F0FB29
-:104B50006FD8F8FDE8793C87F7DA45ACD3ED71CC36
-:104B600017C73A487A1CDBD18BF55353925B30DF81
-:104B70006CB5C97A5BA833ECE063DB7BF96A23BED2
-:104B80007B2C29D4D91DF1BCC9165C3950CAD36617
-:104B9000F8C5228C583CF28B04C73F8CF74A9DAB7A
-:104BA0001B60A720BF373F87CBB023F9FC3CDDF16A
-:104BB000C9D29F1C3058DA0F9CB39AA6E793B3DD95
-:104BC00013B2438E6BBA7D58B62D3ACF57D6A7187D
-:104BD000EFD3BA4B35F28A2D186FC89ECEF106E19D
-:104BE0007992C65BBAFCFA85C81F2FADBAFB5AD8BA
-:104BF0004FA55631CE4EE36A52541E47538C98351A
-:104C0000197664643F11F65BE7C1E7E2B4C29DC662
-:104C1000762BEBB7AE83A5BE035C47DF2B5BAEAC58
-:104C2000C6F70DF9C281C2B4563C21AF15F93D4D0E
-:104C3000A3F4FA0BCCBBC926EBA3E76D8C277FB09E
-:104C400094534D599EDF0F035DFEA2F2F9AED33FA0
-:104C5000E42626B761A7B5EA7B7B6B9E2D8D1F6787
-:104C60006E595F0F96F2AE94C68771F65C67CE2BD5
-:104C7000EFBDD10C5FB2CD0C67EF32C3FDEBCDB011
-:104C8000F78019EE8B7EF3A49F8D73CBF0B351C2E6
-:104C9000CFF638A49F0D187E364AF8D9780E3F1B00
-:104CA00030FC6CC0F0B3011BF886BF0D18FE36EA6D
-:104CB0006FD0F124FCE134E46B5658649E2FD1C3CD
-:104CC000CFE798A6DB4DE7524E3D2FCFA5103F48CA
-:104CD00079BFD0C5EBE401B4180CBD24D753EAB3B7
-:104CE0008EE032C4773DDACCC158AF6BBF9E07BEB1
-:104CF000ABE8DAC879AF4D2B5EEE790FB56B54E2B5
-:104D000005EC8A8AB55FCF841D95E6D14A06D37833
-:104D10002A631B560EE4B87D98E547638DE78D91B5
-:104D2000928E1C7F2956715306D52F486E337F28EB
-:104D30003AEF5CAC36E799FF54DE79341F1876E021
-:104D400023B6E60C37FBE9C31E469C77B112EF860B
-:104D50009FFE698C5886FB8302AFC83CB5964336EC
-:104D60009937B05AD92022EC93653ABE0D78CED946
-:104D70005CB6C7CFC1AB158BB85488EE5A7313FC21
-:104D8000EBD30B2C6C779F5E5050D80EF61FF96555
-:104D90005813B89F2B72BCB89FCBC43F5B92A3CE75
-:104DA0004D7430B5C7FD5CE673139798EAA7ACCE97
-:104DB00035D597140D35D57717727C4B16CAF195FA
-:104DC000907EF0A7005EC6798B4B403BB2533A2BE6
-:104DD00081952C97D72B7C6EDCB3745521F0729C97
-:104DE000D8197104836FE6E8FA45580376F0DD9927
-:104DF0005459FFA5D270E4367AEF84AF6E33AE4ECD
-:104E000039615977DF300FF2EBD77776D33ABC416F
-:104E100009A541F4FC7E80B61D7CF399B57112EFB3
-:104E200027EE6C975C03BBF350DEEB83D0DF369547
-:104E3000F3260C7EE96C9371BAF5838866644FACF7
-:104E4000AF93F9BCEBEB5262BB47ECBF18F36C01BC
-:104E50001D04CA6569A91C17120D9807D9EDCB600E
-:104E6000B79D3E24ED76633EDD97873B2EA1FA1B6E
-:104E700076C6307E3ED3FD86E37D5EECEFC1F98DD4
-:104E8000EABD9D55D803966D9BE147B852B597B0E2
-:104E90004E16ACEFF11EEEF75AF4AE2A709EE6F312
-:104EA00035A31306D377BEDA6EF38E27F8B6BA476A
-:104EB000EDF09317598376CEC3DCBADE8EBCE45F87
-:104EC0006C59CFCFE76D29E6BCCBF9A28AFDC8A308
-:104ED000FAB92C63DE0B0A94756EE2AF5E43241FB1
-:104EE0002E8895FB79C4CF2F615EA7B7283ED88F57
-:104EF0005716EDB417D3F3C33ABF7AA64D1B0BFE7A
-:104F00006B09C9FB395A5E53E5BD6357AA322FE6D8
-:104F100002F7F94C399BC5FC7DE5D9BEEC674D0D18
-:104F2000F7917E6CB6941F2DF52AEFC7B5BCB63F3E
-:104F3000750ABE576FE3DDBB05F60679FEDF22AAD0
-:104F4000708EC033AD41F25596A882FDB7E42F6F45
-:104F50001FC4BA5B92E5F4603D140D534DFC593902
-:104F600026CEC4BFD344B2E91CCD55482A8980AFB0
-:104F70001CDFCDD4FEEA2BFB46C9839CD67A96076C
-:104F800043A2CE011698E0722A6F817C129799DEB7
-:104F90002B17935BDBC11FDE28EDD6F25D491BB0FA
-:104FA0002FBEC022FDA1699A7C5EB1573E1722F642
-:104FB000DCB9749CC7477CC0746E5BDFE743BF1CE1
-:104FC0000FECD6C0719DE60C929784D1F2DE8D76FF
-:104FD000C4D3C85C6E469CB43C4030FAF58BE65AAC
-:104FE0009C1FB14AFCBABCEEAECB325AF9A2629712
-:104FF00039DFAAE2D0DBDCCEC8678CAE273B7D650B
-:10500000078C7BBCE2E37393DB9AEC88075DA975A0
-:10501000E47B29A2EF4B2B0B35F138A7EE4D7363E0
-:10502000DFB622EA9EB485433C523FE9F17FDC3390
-:1050300024ED8406BB8CDBBAF65978FDC97B79CEAA
-:10504000F1E5028BBC2F200A2FE37DEF727F1D322A
-:10505000641E1AF0628DC04B341F014FD6083CCD40
-:1050600013124FF3489A0409EE003E8BC4CFCFC40D
-:10507000D77CFC41F5F3F72A41E4BF45E3679ED6B0
-:10508000C8F89BA7B9AA82EEF3E75371CBFB0721BF
-:105090009F7664C87B0DA3F1375F34AC84DF3B9F00
-:1050A000F4463889F9C2EE643F4DF1426F7B063514
-:1050B000DA6D529E719CB7E5B5B779DDB578695563
-:1050C000832F04D5537B97DFD3BCAC8D3CDFC967FE
-:1050D00065FCE4AAB3562EAF1C6F5E7753CFA6F1E2
-:1050E000F39F8B970AE0197C8EB85E421BF7EC2188
-:1050F000CE9770FE7C8DFD10430EB7DA75E6BCE5E9
-:105100000BD97FD171C21B87E871C23C9167CA5B22
-:10511000BE80DD119DB76CE8F11697D49363D5EC92
-:10512000373C34EFE25754F6D33DD3C659F8FCF878
-:105130002BF27E3C6DC59926F0A7166F6139B83801
-:10514000BE2BDF6BA1E971BB73F6764D4A1AE27F85
-:10515000C5316ECEC72FAE518BA0BF8AA99D27A2A5
-:10516000DDCAE5DD3A432F7C727BAF8703B45E3E38
-:10517000B929350D71FF4F57D85249729E6BF7C947
-:105180008AB19D919FF1E9DD8E69C136F0F3D010AF
-:10519000195729BFF57DD65B272CAF254CA3F7CB3C
-:1051A00056EC4E40DA7FE98AB7F3DD6452F80668C0
-:1051B000EB86E421BEB77EB31BF872AFE7FB04B603
-:1051C00093B8043E8A57AC60BA2F52E47EF50D4A7C
-:1051D000F8C8486A773CE6EE8469443F8DFE87FD57
-:1051E000C3331BE3F5F368359C37743C96EC016AD6
-:1051F0007F3446E2F3E8CE782FDF89E10D7466FF55
-:10520000AD9DDCDF29B5D45F85F14C4CD5B60FE1FF
-:105210007DDEE0E67495DBF1B975ADA647625BF122
-:105220000FA3DCACEB69D8DB28616F235F06F63691
-:1052300060D8DB28616FE379E55AB3FDF6B2BE5F53
-:1052400068C483BBD436FB60EF060A44EF2AD6B3AA
-:10525000E30BFE08BDF58AB4179628DE558D6C2F3A
-:10526000C5D7C1EFACB54A3B3BF0B13C1745FF7A1F
-:10527000433EFD5ABDC48BFDFCFBE36E7D04ED9700
-:10528000627F6800EE3D25DB2B825F479E758AC8F2
-:1052900073B7A3C8088B84473B334CEDC7BAB34CF4
-:1052A000F5BF48EF63AAFFA5C767822FEF3DD8D4AB
-:1052B0007E82779409BE62D02F4DED27F92799E0C1
-:1052C00029E3A69BDA4F2D2A36D55F3D6DA1A97E35
-:1052D000BA76BD09BE76C14DA6F6D755D598EA85F2
-:1052E000A87A0CF8F107E43D6CF5F09F1CB8FFC5F7
-:1052F000C925D5FF0979CCA348D4F3BD2B7FB9F1DB
-:1053000011C0FB90D74C2B6ED8684B555B71FC1FBE
-:10531000747BE9EA61FE6F87B03FDDC0F7682276F3
-:105320000BBE8B1BEAD1FD5FF9BCA3D5885B35644E
-:10533000F07D0951ED2FD46E58DCBED31E62B92525
-:10534000431FB8CE4AF26BD8C07DB9DD08DEFDDC64
-:10535000C7121EBAEFA9AE043F3FB4C74C862FDD7B
-:10536000771AF5970F6B92F553049B262F3FB7E200
-:105370003AE4A70C1BD975B557C645DA3CDF6E94E5
-:10538000C013CE85034F28C3C4F728F711DFA33C11
-:10539000407C5F4272ED20F13DCA43E467E2F9FFD1
-:1053A000213F13E56BE467A27C9DFC4B940DE45F09
-:1053B000A27CAB7A1A97EF546BFCDE5FAB1770F9E7
-:1053C0007E75153FFFB07A29971F5707F879CFA14F
-:1053D000328EE022BD03FD5E813C18E40B44DD4BC0
-:1053E0002AAADC7CFF41ADAEB744BD9E57B38FFC0B
-:1053F00057E0B3D19A74C4D9BABF78617FDF2A8EDF
-:1054000044D86D5758FD3943998E1DDD2CF7F5E7CB
-:105410004F7AB5814389EEEF664DE991AB42DF5596
-:10542000BD944875EF5ADABE7F326EA8E497DEC3AA
-:10543000FCC3F0DE70E761DE4FF76490B53A94612B
-:1054400005F4577264FC72B8B5A116F5B5DF0B0F01
-:10545000FCE617E3FFCAFBE0B5642EE3FCB172562D
-:10546000FA2B23F4FDFBDAEFE5FEFD088C9DEA87BD
-:10547000BB657DED5CD2743ED487F8FB2370DA59AE
-:105480009E6F33E5ED8C39DB309AEB5D760FF24D94
-:105490004738C3F27B4EE1467CF9C5F83DB2FFB117
-:1054A000B2FF8DDF87F9FBF03E91973DDCD93A9E44
-:1054B000653CBE06793F5DB66C5FABB71FA151FF7F
-:1054C00049185F951C5F31B597E367393702DF4CA8
-:1054D00082B72DEB63D3E5F9E43167F57AAF9C6FC2
-:1054E0007BAB8471A604F599299AF0537F9999C2F0
-:1054F0008BF8DB88D4860C6EAFE733C45BE5F7121C
-:10550000BDF23EAEEE7FD7E47E002100E337F2929B
-:105510008C75DB29399C013BAFD3623B7F2F53DD78
-:10552000E983BCEEE3D37E0D7EB03A2D3CBF5ABF7B
-:105530003C2FFFE6F39E4EB88F74926EAFFF13FAC6
-:10554000DF82F7873B5F90F4C7256F99ADB0328F4C
-:10555000FE37B84DFA4B7C11BF60FE447FA607E8CA
-:10556000A9D35F31F0A3D3FF1CBD9645D6EBFC71E8
-:105570003EFD4392DE3A3F8D70CABC09B407FD87F9
-:105580005B253FD4C6C87C8F17E30B1FC03D5984F1
-:105590009B22C4E7871BFC5225CF0FFF6FA5FF009E
-:1055A000ABBC47CE51E6E47BEA7E8A1F66358B4270
-:1055B000DCD379CAA7C5615D179FF51C043C478CF5
-:1055C0002A84796ED49FBD40BDF64DB30DB0F1BCB9
-:1055D0004B8E6C67D45B9D6FC541EE19DF31DA8D60
-:1055E00038AF5D8E13FA62C9D8D03AE8AF7135563C
-:1055F0008E5B9365C2F021D267329FD39FE04B8BC5
-:10560000CCFFF41E583C00F78BCAF35BC225ED6A51
-:105610000FFD07B95AF843D172F427D46D56F81D1F
-:1056200067904F4BDF294C35DBE7E3A2F6D72FCB52
-:10563000FE82EDF1CB7EE29EEBBF0DD5CFDF64891C
-:10564000ACFFE43DA35F48F97C71F78CF616F5CC0E
-:1056500007638A653E17CDDF9283B88D5F54012EB4
-:10566000145556F0C1385167957EA5FF78C500F6F0
-:10567000DA193F978B303F9F400A05CAE40A621F40
-:10568000C0FBE326CEC0FDC1A3734777C7F388FBF9
-:10569000F37EC0F82A54ED6FEE88FBF3F68D91EBA4
-:1056A0006DF154196FDAE7ECD6A61DFA0AE9DBEEC4
-:1056B0003D8017C1E54BA48FBBD3BC5F267D0CF8A2
-:1056C000B2DE35BCAF5CE831E71D19EF5FEE1E2D91
-:1056D000AC2917D67797F77FA623F0FC6A52AF3133
-:1056E000A0D7AB4903C7201EFF6A527B8B2C1D76C7
-:1056F0002EFB3DDDBDADF119EBA3B5BF42EECFB83A
-:105700002F784C3B795F70345E2F1321137EC7EBEB
-:10571000F8FD1978ED352CEF7CBCC6E1B0631EF0C6
-:10572000F9F61E236F0AF1E4EECB1B18BEC126D793
-:1057300041F9D3130A9017BDF85D99DFF125860270
-:10574000BDBB74288F7FC4D2C1C29ACBFB5101E08C
-:10575000BBCC29F17822F0627FDC6BFE528A3608DE
-:10576000FD7FB14EE5F3F6279E8CE178DCD1E05366
-:1057700009C0A7C1C765AA67B517EBF05555DEB3D9
-:10578000F4C3FECEB887F4427C4DFC3C6A585E1BE5
-:10579000FCEC227EEE773E3F8B8DF21E83326761FA
-:1057A0009B7436FC4E678E3F0E7CE816E1EBC1FF22
-:1057B0001542FA4715CED7E43D9504E3DC6BB45DA2
-:1057C000951F4BEDA9DEEE94F9C206BD331DF21E06
-:1057D000CBCC38E1461C4468B997705CBE9B7F1AFD
-:1057E000C64F7EEDB6C8BCB511E1BEBCEF3CEE9035
-:1057F000CAF9EE2FC7CA7BDF1B891E0AD9A7BFE8EB
-:105800005BE5EA4A749C99AFCD198679A93FA8E86F
-:10581000F7B51E8A48E1F879AE8BFDEC9FE9AF97AA
-:105820000ED3FDF5FEA2FF3FFD3D8576F2DEE1C51C
-:10583000AFE40631EEC535A4D552F97731F89EB8FC
-:105840005AF8E759AD726784E8C9BF97313AD5C6AF
-:1058500079E6FFDB7E4F215368BCFEFEB3BFAB3061
-:105860004E3E3AEF77153213561DD0525B7F5723C9
-:10587000FA771532F5FBAC8547EA0FE3F714460AD1
-:105880003FE7E58F4D37EB95D1EE5107DC5C9AE3AE
-:105890003D993F91CFF5F8305DAFFC14DDCB854EDF
-:1058A0007779AE137CA0FF3E4A10FC69FC3E8A412A
-:1058B00077E377526ADBC9DF49F957FB5D9468FAF1
-:1058C00044FF4E4A347DA27F37658416CB781A5D3B
-:1058D000E662BE36E8348DFE637B00E77295FF7E9C
-:1058E0007A3546ADD33362751EEE293D552CE5FA67
-:1058F00085F4FF835EFF11C88B6F114FC27917A724
-:105900008C87F86BAD226684C0FD849C2FFBEB5A1C
-:10591000790F54AD55C603024457DC8BF75DEC3F5D
-:10592000E47D8E641FD93A202E53C5EF07EC4E77E5
-:10593000AD17F44E603E59BA549E073E6CA9E3DFA2
-:10594000BB98955DA560FFF268967616FDA78BA2C1
-:105950009DF3382E5F3510F27DE69F1D9D513FB3BC
-:105960008BBC3F526437E645DA233333F53CCCE158
-:10597000FA7EBC57E661A9C3655C2DDEEBE6730DCC
-:10598000C5D942CF6F159D67F6031F7FCC767C8B00
-:1059900047DAD58D36798F65E01599CFB3AEEA2D0C
-:1059A000B6FB37915DAB4AFB66ED9D1C674810D88E
-:1059B000C77D24A63909E3EFB55698EC853E41A78B
-:1059C000292FB9EF16B709EE174A37B5BF74AFC71D
-:1059D00054EF0BF736D5E71EF29AE0BC8641A6F6E7
-:1059E00003DFF79BE0C18DE34CED871E2D32C3C36F
-:1059F000BB4A3C8127693E3397B883F21E7D192745
-:105A0000E96297F654ED4DD29F30F2D7357D1D44B3
-:105A1000E7AF77B2CAFC757B95D46B9A4BFAB7EEB9
-:105A200064E156F95C4C03C3B81B82F3C603E63C41
-:105A3000F38E4EE95F59C648FFC3AEE799C7F696A5
-:105A4000E75E8CBC72F22BFCC07777D1389D7FEF7C
-:105A500040BF4F349A9F7FA1D33D7ADC5DECF23C8E
-:105A60005DED4D76DE3FD75CF62625E1FCF1540D69
-:105A700094FCBFC9D9F6BD4F53753E7B2CB768C2A5
-:105A8000702A1F26B5C5F6D779FD791B21EF6A7FED
-:105A90006BE7BCF19FEA6FE6A5723E332C965993F3
-:105AA000B2D91FE4738046BF73F57E7F39526973A4
-:105AB0007E33139BF9DE359168F7807F35D74A86B0
-:105AC000DDB122496D03EFADE732649EFE75AB4355
-:105AD00077F6A271CEB0D7D9E48503411BF8617C7B
-:105AE00001D991B43E5EDE33FC2117D1E3E1A55626
-:105AF0008E83950D7F6666A03BECCC66E60724A2FC
-:105B0000603F11F6A79AD33AEEA611328FFC4E5C95
-:105B10002CCDE7257EE071B5E8F19116113A777E3C
-:105B200022D006BF69AE837C0EC1BD58F253A78850
-:105B30007356F03FFFA7CE4B08EC90523FB63A2188
-:105B4000CF39FE04FE8C732A9EEB6D451B5C382F0B
-:105B500022C6291178F866848C5BFC79B8A437DA00
-:105B6000411E5DA81DD97D89D85F68119E44F74FFD
-:105B7000C4D5FF27E69F69957186CE4E795EA493C2
-:105B800055637961EFADDF73771EBFEB72438F937F
-:105B900075B4CA75DFD12BD7F5F972E1007FDFAE9E
-:105BA000C97BD3A2F1CBFF22E22AC6F995D83152A4
-:105BB0008E1872E1DC39941ED20FB5E9F221D8DDDE
-:105BC000C27907B7C59BD771B32E1FEE31F445805C
-:105BD000FCF87C939C10D8D7AB5DA1B29C2039799E
-:105BE00050A37116E35E1677EBEFC3CDBD57EAB154
-:105BF00011FEA2FBB06F327B8D4DACE77D05793F86
-:105C0000EC7C3D4E5E1C88BA9F45B7C7CFAC56DCD6
-:105C1000F8DD8839ABCCF5F35D473E86FF3837FABF
-:105C20009E1A63BFEE27E2008DC3757BCD2BBC7A35
-:105C3000FEFD328CEF4C50DE7B7DEEBC921EFF6988
-:105C4000093E25E15B8488FC1D09C32E30600FF6F8
-:105C5000C922EE6121FCC6F6867E5F6E6D33BFD130
-:105C6000C0EFB93C0F7D9F8ECA652BD89F91F90D6F
-:105C7000240F785FEE38D5C30E3C1E38CDED8FEF84
-:105C80008AE1BC9213BE86FED8BF35F6E9BA6B72C4
-:105C90001FAB6557BCCC6F705924BC45DE63BFE8B1
-:105CA000EFC1FEF0631B034F99CE39688DE67DBED0
-:105CB000E852ABD9CDFEA66F80163382F8EA98D5AC
-:105CC000EBF4127CBB6B1FDFD3359EFC47C835E479
-:105CD000A5AC4895E367F915382DF15725F17705FF
-:105CE000197A909FEF0A929E88630AF26AA92C0E95
-:105CF0000FE6FE7FEE3ED894B33EB9FF7B7628BF19
-:105D0000AFAD1ACC70EF60F3A8F7A9DFAB349707FB
-:105D100071A4A9B5BF1E1B0BFAFFD1B582CB4EE60D
-:105D2000F30346D97B84A44BA3ADEDFA3F8E90EBF1
-:105D300063CF08A1DF5723F97D718DC2FB6A8BC148
-:105D4000E380EF94F7731AF0E93A1D1E2BE1252B3F
-:105D5000240CD5043B78B6FE3B699BF5F80BE68F27
-:105D600012F3475C609B1E9FC1FC5162FE780E7966
-:105D70000518F20A30E41560C82B94905778FE7924
-:105D8000D268DED7C6BEDD9888F5847DBB3111EBC5
-:105D900003FB769130F6ED22DB63DF2EB21EFB763D
-:105DA00091F5D8B78B84B16F17D91EFB7691B018D7
-:105DB000F4CB561872CD3FC9044F217F604CC47A92
-:105DC000C6BE5DE4F7B16F67FA9E76BDE9FD6BC5AF
-:105DD00052D3FBD8B78B6C3F6BA962DAD72309C8C3
-:105DE0007A7DCEDA14E6A3645FD1BC1179FCBB5690
-:105DF00037DABAB27CE038C6E2F258AFA477DD38C1
-:105E0000497F8B3C1FA134F3EF0B9CBEC52EE1B143
-:105E1000E6FC6DA3C4BED7189BDCF742897D2F94A6
-:105E2000D8F742897DAF313DE4BE174AEC7BE139BA
-:105E3000F6BD5062DF0B25F6BD5062DF0B25F6BDC7
-:105E40005062DF0BEF61DF0B25F6BDF01CFB5E2817
-:105E5000B1EF85E787691C2511720CF67A77939F5D
-:105E6000497C68F233DD2618F67A647BD8EB91F52D
-:105E7000B0D723EB61AF47C2B0D723DBC35E8F84BB
-:105E80001F1BEE613D06BB3DF23DD8ED9170BFBAE0
-:105E9000C04B88AD4D5877F200CAC678E5619C3793
-:105EA0007CEC852B6659491F36C6289D9348A6DB96
-:105EB00094A9B3C640DFEAF98FFD45B305F24783E5
-:105EC000333980CF19725E69BFEF33B8FE65E35C8A
-:105ED0001CFE11DD7DBB04FFEE8CB1DF6EBCEF2537
-:105EE000B58DD268DF0AB7DD2EBA7FA31DE7564510
-:105EF0008C03279A9137E3BBC595033F64B345E113
-:105F00003C93CDCB645E74345F7DACDB479B2D3B13
-:105F1000F7E11C4C73B1E2C5B98FEE751A9F33EBF4
-:105F2000374358545FEB7C7A3D92C079B50746C839
-:105F3000389F317E233E4AF282CF0F0E6B6E189D42
-:105F400048EDB5C028FE1D9CF176693790A5310457
-:105F5000FE64DF80E2DF10C1E7AFEBDFD302721C2B
-:105F60008F3D3251BE172BDF7BEC9104EE7FE27246
-:105F700085F3CC866D137E9C537E4F97AF7DB7859E
-:105F800055F457BC5CF6677CB7785D673BCE731BF6
-:105F9000F82A168D63709FB418A0E04E59D1D3AA89
-:105FA000B15DDA7E86DB023BE862CF410D1F9034A3
-:105FB000167988A25EF0BDA11306BC699A2FA32BA7
-:105FC0001FBF832AD837D402D75BD0EF4442400AA0
-:105FD000E2C904633E9A26AAB208BF574D2B667CDD
-:105FE000F79E2114E0BBCF8CF596547AAFAFF6A2A2
-:105FF00005F65ABFBA462E8D79788725A980C7DB6A
-:10600000DC6331FEF16315961FD1793CB00F185E49
-:106010006E637D6ED80F8BE3CFE5F9BC873C9FD3D1
-:10602000876C9CE7737AF919AE2FDE1DC3793DDAD0
-:106030005A85E59A613718793B65D7BF9B0FFC7C81
-:106040009515DC9CD48DF5BC7D24F269BAEE4CC06C
-:10605000119CE3CB775F85A37BA797EF96BF57ABE8
-:10606000EFEF18BF7B2AB2FD9C0F66D88142ADB717
-:1060700047EEE318BF9F46F293DB9DDE6B77F3EFAD
-:10608000D7E9BF776AC47D8AFF927B10782D7E485E
-:10609000FEFED9EC5577174E23789EDF19C6EF62C6
-:1060A00045E7632D8CB2037FEAF74E3D23F5F84FA9
-:1060B000ABFDC7FC72E63569FF15FF65FF5469AF9C
-:1060C000D838EF7F468D8CD7899D82EF3F9A513328
-:1060D000DA827BA467ECF67B154FAB1DF8866EB7B2
-:1060E0004C3E9BC9F87D5BB753A622FF94F03BBEA4
-:1060F0003146CF57CBE0F2EAB3321F75B24BAEF761
-:10610000C66704DBD32D0187CC23AC177A7EAB990D
-:10611000EF7C82F883E873895FD98FB4E509B07B9F
-:10612000E87BD36007A5808F8B57205F96DE66BB28
-:10613000339A8F275BC357E2FB93BD36E6AF7FC62A
-:10614000C7B897E39C5C12552FE19CBFD8287FC746
-:10615000619A26F9BBAFCEDF33E3F4F8934BC697D1
-:10616000CEC59F3048C4CCC4D659C8179E89E48593
-:106170000E3C2D3FF2F5E2B365FD3523B7CE5A0E46
-:1061800067E6027109F5663BDF5FADB99CFC3B3405
-:10619000178A13203E00F978DD0D3EFBEC08F95814
-:1061A00030AA608D3F2FE2BCE3ED320F6AF1ED3D86
-:1061B000DAB775DED628E7107EB13E662636DE8871
-:1061C000F3E64B470AFF9841F27726E5BC4418797D
-:1061D00098D7E8F0C63F37FC6D958BF1C1F00D7F85
-:1061E000DE330BF7C7953B1B0BC16E95D955E3907A
-:1061F00077DD2A87347F6616E4D0A830E4D085E2C4
-:106200000E1B474A3A44C71FE6644BF92CF4FBC205
-:106210003FB9FDE91D90E7C6F83FB9C0EF63AC1B7D
-:10622000A9EB89EAFF9E731ED1E73BDEE8A3DD35CB
-:10623000B21D7E97C7DF843CFA0E6A9D9E3F2BEF0E
-:10624000F530E81B53F71DC73B4AF4FBF0499EB0FD
-:106250003F39DBEFF4D6408EF4162B715E68A62A28
-:106260009A79DFF83CBA4B3C3E32FDEF0B918FFB45
-:10627000C86F63E5791D1D7F33EC0D2F39B35AF1DB
-:10628000F7D1D23FD8A4FC0AF7C0BEDC3555319C0B
-:10629000DF5630AAE851C8BBB86C2FDF83B1C62FD8
-:1062A000F9C9DEB568339E97AF7EF161DC9750592E
-:1062B0009FC5BF2B53BCD7B712E71C0B46694F6075
-:1062C0009EC52E37DF1B52B13C89F5D3CCF67ADC64
-:1062D0005534F33E9C81F7037A7CEA9E51F2FBA78A
-:1062E000743F03827092A9DD85E27432FF06F939AA
-:1062F000883F6AAE3D1C2770DF2CEFA9B08B776416
-:10630000FC31BDEDB841A61E6FCCF0CAF89081BF3C
-:106310003B7ACF66396733E2B9E7F0673E8F69941D
-:106320006EBFD4EFB36F50D85F2D59A3F2B9F2B15D
-:10633000EA78BEC765F1DD8A87D7D7BDDD38DF7B58
-:10634000F1ED648D7970BECC53D87E00EE5B57DCE6
-:10635000B04B66801611F19D92B58379BD9504A965
-:106360006CE35E53A3BCF6EEFD9D9EF1808C7EDE59
-:10637000BF2C71FBEDC911EB7D4E9D62BA5FC180F0
-:10638000855FC6DB66085290348E19DD3D0AF6152E
-:10639000DD7E8987EB6EC8B2E3F74866D0972D396A
-:1063A00017EEFFFF95F2FF02371C2052008000001D
-:1063B000000000001F8B080000000000000BE57DBE
-:1063C000097854E5B9F077E6CC99992433E1640172
-:1063D0009200F1241088803861A72E1C1202130845
-:1063E000305940F086308120A1456F0497D04699FE
-:1063F0009085104143890D52D461F3564B352ED709
-:1064000042C57600EB525131486B1793617169DDDB
-:106410005228B5BD0FF7FABFEFFB9D93CC39990415
-:10642000B4F6FEFD9F3F3E78F29D6F7FBF777FDF22
-:10643000EF243F9DBDCC2632D6B54D90F7A4315602
-:106440002EABB6F14EC6BEC49FE98C2D6F16D4C0DC
-:10645000D89E727E3A5BE68572B4EA626C1263651E
-:10646000B2624B4EC3A76C8B87F7CBEF3822B14497
-:10647000C6568C604CC882F6F16E9B13C75F0DE365
-:106480000B8CDD2C0773B1FEE6B10AAB8983F67580
-:10649000593606F3F9B6F0797C8D71B66BA05C665F
-:1064A000956DC3A05C12CD18B687F505B07F795005
-:1064B000B5C53B715CB6ACD0C9D71B1FB6BE326D3B
-:1064C000BDE5CD71B69586F7DB2405CA4B1853DBC5
-:1064D000C2F6A73FA7AB02ED67795D416A2BACB767
-:1064E000DCEF9271DE72AB6A73E3BA705CE8B7A45A
-:1064F000A5554A0BEB7F8D6AA17ED355859EF9E9A0
-:10650000C10C01F77B7B941BD7BB446E96109EF9A0
-:106510003A9C1FE4705829073370FC950E0E077DD6
-:10652000BCF2163E4FEFF5717897B794D914A8BF17
-:10653000C5EA4D6D85FEB7C03AFDF05CB2E3488612
-:1065400080CFCA28B700E7C1645FAAD7D5D3FF833D
-:10655000076F4AA5FDC3FA11DE2EB7322B09D6B359
-:10656000A21916A3D093E62D9DC02ADBC2E0769334
-:106570006A656C203E2DF464CDADAA6310C083F132
-:106580009FAB6C2766E03E6AAF666C23ECC3E77C8A
-:106590007E06EE53FE2E63E23458EF96B7A97E4591
-:1065A000129305A8B7B1E704ACB795431F28337F12
-:1065B000AE1ACAE4637D99CED8301C19DA3B017F4C
-:1065C000FCC98C554E5168DE252CB4840D8771B6FC
-:1065D00014C01CB0CEC17C9DA50358E53311E0D595
-:1065E000A2ADF766EDBC4B2CEC2516DF537FAF76E2
-:1065F000DE2588CF61FD713C1C778D5E9F1DCCB878
-:106600007D6C4F7B7DDE9278DE0FE901F1708D8627
-:1066100007D87E2DB5E7E55CD1B9B11EF6B376ABF0
-:1066200018B00BF8DC5B3F08CB4F0B6E84FBC76BDD
-:106630007FFAE62278FEE907BB4B717FFA3A56FEF5
-:106640002D8B290970BE7FBB8E9EE5C1694C99D008
-:106650007B9FC7A6F8BEA74E0AC39FED3F19E983EB
-:10666000F93F7EF2F50C84F31F00074480F3BFFD71
-:1066700064AFC4D27BD6BFBCF16DA9CC190E2F81FB
-:10668000E0D594D94EE7B72293F75B51F7E7323C58
-:106690000FE6B4291969BDCFBFACEE69DEBECA4DA5
-:1066A000ED7DCE5FF3F34F61B2987CF9F3D6CFD78F
-:1066B0007CEE8F48DE609280E7D36CA07FF3FE1FF4
-:1066C000D6D61DD0E8EF660D8F6FAED846FD963753
-:1066D00096ED1561DD4B74FA2D37BED7CFE7FC166A
-:1066E00089CEE7FC968C86242CB7F1F3F98ED83648
-:1066F000EE6E68F7F19AFDB725A7E3AA03A9DE6B52
-:10670000F8F9B009FC7CF0B90ACE8725443C9FA774
-:10671000C2CF67D5A3FC7C563CF9C67B3F5308FF2C
-:10672000F8FEB6DA03C87F97B73D7DEA5BF07E4995
-:10673000E336290DDAFD424DA37DE9FD575466C9C4
-:106740002C16F6D7B85B423EF00B558988E73A5CC9
-:106750009995F399472438DB38AA67427C4FFB258B
-:106760004C1D8C7C84F987B2FD89BDD7FF278D8EA7
-:10677000F2D3DDB6C1C8BFEA63D81E19D751763F40
-:106780001BD7BBBDFE3C1BC5E96239CC83F47976CF
-:10679000863B15E9A2C46231D09BFE3CADD1D790B7
-:1067A00098B625B8DE21094CAE0510FF305ACDB69B
-:1067B000C0BC3FFC9643AE75637F9F82F57607931E
-:1067C000FD00F23D16653CE1276C795332C232344C
-:1067D00009F9DE8835A13FE3FA109DA2C6F3A70BA5
-:1067E000F66D9FC1F104CA6C107F1FC4E7306B1BAC
-:1067F000F1A9E82A8E7F36F60E956DC0B7106FF5B9
-:106800007E43D80901DF27C35A70FEA6CCE5747E0B
-:10681000D2084E2F7DEDEFCB2BDCDFD9345F80E447
-:10682000441493F7C4D1FED662B97B7F994CB5402E
-:10683000FFD2EF5DB3BB09863C5BA31EB541FDD91A
-:10684000F54EEAFF4DEDD7BCCF25E565867D76D3C5
-:106850004D33F0B5347C4E48C5759E77C044507FAB
-:10686000F6F6280BC2FF6C1AD717180BB90AE15CB1
-:106870001EDB00BFDA19FBD106073D9FD800C834E4
-:106880008AB1031B92A8FCE406859E6D1B32E97D4C
-:10689000FA0C8E7F25D16A2CCAE5AE1A97BC07E1A7
-:1068A00011E474D351359CE0007A02E7C79A5ED0B8
-:1068B00021875CF1617C1AE4C7569477AC6A38DBB7
-:1068C0000F5374349F7559C6225EF2F5E9EDEF90CF
-:1068D0009AD97A6CF79010D80FE3C6DCF176EE60A7
-:1068E00094D32D695902F45B5A7581F8E152E7207F
-:1068F00085A11C77FA1AA660FD8E347923748B6902
-:10690000C9EAA882FE2BEB46B9B1FD1D82D240F345
-:10691000D6086E9C177E54C764E003F81B94573961
-:106920005F1EA1F14B0BF2CB15F7AF6F4886F269F2
-:106930000BEB120134F996825958CEDF19E7AE45B8
-:10694000795BCBF7C376011F75F4F05175AAF7FA9E
-:106950001970CEEC12E01B8C3F1AD6C644DC4F9B5C
-:106960008AEB67A077EC67B85EAF0DFBBFA0F1CBF9
-:106970008E96D32E453B9F02A41B5FD7E94D78AE80
-:106980004E8BBB4941F9AEBCA520DC5F13D91E0577
-:10699000F187D7AF75F17A786EAC87FAB5BBC500D1
-:1069A000C223572C191442FD6B87487C71E5EEA277
-:1069B00041A86FAC8432CAAF9D3815E053434B0EEB
-:1069C0006FB72DF7077EE0A7A902F3223F3A670DC4
-:1069D00015203C3EDA3D38BE06F5BD5B6B4732A85C
-:1069E0002FDFBD29159F1FED8E5A8C7C7CA65C3055
-:1069F000330EF59F5D7159A2D243671533389D7DE3
-:106A0000FBD69CC128EFD6FCCFB1476490AB2B01DD
-:106A1000476518F7625B4CC00F4DD66C38982A0258
-:106A20006A39137D2B106EDFB11C5E340DE5B0109A
-:106A3000782C99DA2B83E54874ACEB5380C70AE0D5
-:106A4000E9ADF7BE4BE37C6A393E7F09F45F73EB37
-:106A5000B3B138CE771E3C395986F759137DFF8E76
-:106A6000E3FF49D8FD980C20613B768F43F95139FB
-:106A70008371BE1AEF5DB484C3D7BD47E97BBE8A7C
-:106A80008302C1532F2F0D0CB031D44B83CC26E39E
-:106A90005366A4077F24B22A94EFBA5EA2BFAFD593
-:106AA000E0F2D180E6543CFFD58FB5A6A2FCF8A356
-:106AB0008B977DFB5E59F95D5887AFC52233C03B8C
-:106AC0009F9591DEBBC2CFF5695601CC24B967FE14
-:106AD000AD336268FDAB774C30C83D908F34CF1F2B
-:106AE000ADCC83EBB8AAB62B0BF5A7DF5B832BF1FC
-:106AF0005C7F0FFAA93F0DCF89E3DFEF9BC559F803
-:106B0000DE7F87C032042C3FEB1AE1243DCC427C6F
-:106B1000FD0529B01FDABB26B60591EFDDFA5CDC76
-:106B2000780463AE387630E2CFDA43D2AC215C9F92
-:106B30009271F635D6A02DD2B97D5BD3A3BACBCF57
-:106B40003D6D43BC5F7300F401A4CFE78400EA37D6
-:106B50006BDA9E7E3905C6BBED60D9049C476F7F1A
-:106B6000DB731C0E512C642B0AD3ABCB32E31B8698
-:106B7000008F7C72C6BBCB1E842D95E1397D0BF84E
-:106B8000D7F45FFB6A46E053A67D326B17E9E3A0BA
-:106B90005FD950FEDF5AC7C7BB35B3BD219DF6553F
-:106BA00090C0C2CEFFA91912F5D3FBC3BEA95FAD39
-:106BB000E3DE4743B05EB5D6CAA26E84B295FDE16E
-:106BC00031841F8B95F7E33EACECDCCBF0BC5B1C57
-:106BD000C09AE0B9AB72ED7F50FB1ABB2CC2B3F682
-:106BE000D6EAA742309F22322F83FEFEEC4A1ACF0C
-:106BF0006FE3F2A735E6C9876E817255B1D30DE810
-:106C00000DE55882CFE1BB2CC4E79359D7310B3C3B
-:106C10000733A02200D04769BEE3C47718E7C777DF
-:106C2000AF5302C88F61E502E2F9E72F7E3801D742
-:106C30007DE355A10B885752CD87BE9940FFEFCC1D
-:106C400090B97E32363401DB0D3CAAF135EB099266
-:106C50008F5292128FFA4A10C7C2F5FDDD4278704A
-:106C60005808EEC5797538456573FDEFEF6EDF7B2B
-:106C7000B80E5590EE0C42FB0542AC1BF77B225E32
-:106C8000CC180FF4FCB9F487341CD70F682B0EE92D
-:106C9000D163B3B5A5DB52A6EE40B8CC0080B2EB11
-:106CA000C196191BCFAC50BE8F59BAECB08EECAE6A
-:106CB000DFEDAE81B2FCFD014C0451551B95CAB20B
-:106CC000617CE1286C14F67374ECD115B8CEFBBA74
-:106CD0001C0CE1C41C463DD766490E7E0FF1B9324B
-:106CE000D6CD92500EB565213F62B739DD4DD07ECD
-:106CF000E9A550C6BFA35CFAFB71D2D347A5FBBE82
-:106D00009801FB4A11D5D33EA8BF4F0E0E7F00C796
-:106D1000AF8A71D77039C2C2D77F78FDDF6313A005
-:106D2000DFE75D23AD4F41BBCF55871B3458D6F10C
-:106D3000DD312F5D07E5EB3579625ED7E7498A15CE
-:106D4000ED8ECFBB1C41D4433E775A02028034FB08
-:106D5000F0B1770590DFD90E67508CC57ED227E160
-:106D6000F2869D1816F7C1181231EC4B80E7204DC2
-:106D70002EDD38C0683FA664733B28259BF31FAB0C
-:106D8000E226389FF75B5913E2218332CE6B75C838
-:106D90004DB0BE9F3B1F5B0A94CFCEFF2D7D00CA36
-:106DA0008DF387870F6063FBE68B27519F003D6162
-:106DB000D178352D7B528F7C5DA8C125AAF9260993
-:106DC000E1510BF06802782C745A8276D8172B3672
-:106DD000C28155759522DE304BAC1BE906CF17CF2B
-:106DE0005F112C5DECBADEE73DFD921CFC1E949712
-:106DF000C279225C4BCF7F70CD038CCEED1A5C073D
-:106E00009C63FDB5ACE7FCFED5CE8B59DD8D780ECD
-:106E1000778BAE663C875A2BD7F7FC805BFBE3A8E9
-:106E2000DB63782E77D78EA0731A540B7C02ED9417
-:106E30001A2BDB93887CA59DDAEFD7F4419659494C
-:106E40007CA6B4D62E23FCBE888EA5FE0CCE554A59
-:106E500089C467385FA92A67C457968DAD14F0DCE2
-:106E6000937006D84F8725E4C27D86A2408B84E7C5
-:106E7000FAEC74A2F321C81186F373C6FE0FAF7744
-:106E8000ED417E233A863C7C0E44116BEC8A1D0D4D
-:106E9000EB6A11581BED4BD2F8C76A27E9732D71C5
-:106EA00001E26F2D0B87BA71AF9F33ADBE229AF806
-:106EB000CB75160B95BB960C227BAC250E582B8EF2
-:106EC000B76434E90DCFFF8FC8EDB50CC6EBB3D86E
-:106ED000C81D585F9049E3BDA0F3ABAD2E1AAFA516
-:106EE000404D8EA6FA4116EC5F9EE65B87F8912234
-:106EF000F276A07850BB9D3BD5643CCF9D85366A29
-:106F0000F703C1BB64258E738D93F4C6D092E82736
-:106F10001FE3C71944FF524715DFB74E0795533893
-:106F20003FBDCA7FFA21E41FFE6C381127CA8BCF00
-:106F300096225EAB62AC1B50B8D7397FD18DE7ACDF
-:106F40000B80CB12A33BC85E573218021BCE4F6694
-:106F5000D98827C7009ED0DE2FC13927F273DE986B
-:106F600088E73C7F77F839C378FEBBE1BDB036D601
-:106F70002D4CA573CEC4F1AB58B41BEDEBEEF3FB77
-:106F800079200B9FA2C59D6407583C9FEE7B307B08
-:106F9000608F1C79F83DD81FC0A5D41E9AD48CFAF6
-:106FA000B98555B445E0038F6673FB40665D12CA30
-:106FB000D7653AFE579BF03F3434EE83180DFFA19E
-:106FC000DFE1C1DEDD780E9F0A2727E3CBE3FF2D4B
-:106FD0002E8E34FEE39A7C792BD1FB235CDF08EB09
-:106FE000D1A1EB50DF586F27FD975D3A3614E7AD1E
-:106FF0004EF3FE18C78B1AD16543FF54477297842E
-:10700000FBEB58F2A761A8672DAB7A85E8F34AD766
-:10701000B731669C847233CE932585A0FF604FD62E
-:107020002FF15CDAE7D9157B043FC891795386A12B
-:107030003E74326FCA30E497278701C9933C75BB11
-:10704000908F4A07AF71E13A4F7A265059618A56BC
-:107050002EEA97BF7E0CFC35088AC01FC15EC3E7CD
-:107060008760AF0581DFBE0FF61A3ECF82BD86EF87
-:107070004F83BD86CFCE0D6E7A7FD233FC20E2C522
-:10708000C566EE4759617547D4CBD61C105950E7F9
-:107090006FF0EFDBFB620CE58A5D0986F22D2D8037
-:1070A000418E9E72F996E186B2AE7F2EAF1B637859
-:1070B000EFAB9E60286F8C2995F09CE28AD3387CD8
-:1070C0008BD308BEA7F2FA806FDE28826FFBC25115
-:1070D000C3107EED085FD48BAD8A0BE1271D5CEAFF
-:1070E000423DA6BD78389501BE5B27E2789A1DD552
-:1070F0005EDC3F9CFF88701E85F07568F095099EE8
-:107100006735389F46388F42F866D2B31DE10CF5DB
-:10711000B5C50067C0C78B7E941E805FD62E29A29E
-:10712000FEBB4F34ECBF62578C09AE4638976F19DF
-:1071300062282FAF1B6E28EB70F6551BE15CE499BB
-:10714000606AC7D816907B45F80BE0F91B9366136D
-:107150003F3D29B0CA0478C6C99C0F5ABD02F9DF69
-:10716000F0A719E47721FE02F463752AF5585F074A
-:10717000EDBF0F6DD106463B8431B75406EF177A49
-:10718000A26494EB8B5825D1DB62D64CCF9B591B64
-:107190003D4BD8097A96324E8F9F978526E3F3F7B9
-:1071A00089BEF41CA0E7350EDFA38968BF0DF38DFF
-:1071B0004A40BEE48C27FBB4AF73424D9B697CCA46
-:1071C0003959DB17FC14E3DAA15F7BCCB83BEF54F1
-:1071D0007AE6D1C787F9DC38DFA7129FE78D4953DC
-:1071E0008621FE31EF40835DD5D77CDB347959E6CB
-:1071F000E17042DF2D96CF2D14021BA17C649BDD34
-:10720000867E86739B254D6FBF97ECDDD3A7B87F35
-:10721000E65CFDEC54C4BF9A6DA35211DFCF494A1E
-:107220007D15C0FFDC34E0E36EF2E7B8514E9CF10F
-:10723000B8A83F488CD82C38B715DAFECE286EDBBC
-:107240007A68BF3059647E68EFF3A7C5E2FAF57D2E
-:107250009BD7BD7C8BDD80170BA61ACB0B99AD0796
-:107260004FD2F0BC6D3DF5A82F8925037CFDD8DFFA
-:10727000557F58FDD64B6178F66F39AE44D46FD840
-:107280001436E54BB1A77F5FF0FD6243C55B2F4924
-:107290003DF0D5F16A528EB71CCF095EDB903F02FC
-:1072A0005C2C28974F1EE470DC1673E3D6EB000EBF
-:1072B00085EF888CC3B9D4FF7BC4E743DCBF6F9EE6
-:1072C00027A4D175A7C63FCBEADE263B6E597501D0
-:1072D000F19F4267D730F43F1DB907F80BF295795B
-:1072E0009CBF1CCB1BF5F01D306E67BEE8B6033E9D
-:1072F0001DC9BFB015CB27AB4519E7ED3C7841E37D
-:10730000E35D6F4C81F57DE69188CF741EFCE7F05C
-:10731000F3C2431A9F09707EBECAEA650D30EF2A98
-:10732000800BDAF3FF6CBE7E397EDE2E7973072286
-:10733000BC6A0437FAE16AF2ECA447B4037DD83999
-:107340003ED5DF81F2682AD8C132E29B7712DA9605
-:10735000270F0E1F88F0627EB53D73720FBEAFA877
-:107360005E958F7E76B6453A83FA373A45504E178A
-:1073700032EB9950189EFA9E937ACA84D7D633A1DD
-:1073800030BC36E3699B094F2FB24BA9B6745E7FC0
-:1073900062500FDFC39F70FE729B186C60693D786E
-:1073A000FBD7BCB74B515900BEF202E2EB5DE3D311
-:1073B0005E0C09617CE50AF918E033C9BFD6981B59
-:1073C000B97EB190CBBF230B6F3AFA3B80DFC7F396
-:1073D000385E7F9CF753E21F1F839685F87A2A3F19
-:1073E0002116F1EF745D11D1994E3FE679DA357CC3
-:1073F000D3DB155A15C91D013F8B3C467CC9786EFD
-:10740000E90094A77DAD5F1F576FA78F5B88718DD3
-:10741000B17D8FFB610EB74733F695F43B3E188282
-:107420003DF885FC8445F78C03E5233FB98961DC91
-:10743000F5643187CFC903A3881EDB8B75FDCA476E
-:10744000F5A73C6200F5D893C513DE9888F4E39560
-:10745000484EF735EF396D5F67343DA053D303F4E1
-:107460007AF1C1858B96E0B81A5F38E5E1F8FB7ECA
-:10747000CB42D23B603DE47FB2CDFC9F32F43F81F2
-:107480007DED42FED59E2F325C47615E11D9D585D8
-:10749000923230929E60DEB779BC233FB1935F0E8B
-:1074A000C623BA2A9E57C41A705FC5DCFFDB8EED77
-:1074B00061BEE20779F918B69F688013F19176E012
-:1074C00023283AA4833790DEB4B2D9784E2B1A63BE
-:1074D0004CF46EE417C50B399F6BCFCF191889DFB9
-:1074E0005DEEFCF4FE577AFE15D81FCAB8E62F49A8
-:1074F0004F89378C07169D69BE7453FD6853FD781C
-:1075000043F972F8D8A9C991761D2FA294A5DE0877
-:10751000EB6F7FD25E119EAF317726B75FE6CED498
-:10752000E2F75F51AECE9A09FC2A86F592AB7DF563
-:10753000D7F9D3A81CEFBC99385FB048C27D5D294C
-:107540003F0A93C30BA97F48B061FF6D9A9CAD6859
-:10755000E378D41A73FFCB88879F6AF6D091799C21
-:10756000DF7FA6F1FBCFFE532BFF440820DF3C76E4
-:10757000E8EE58D4DF3F3C382A16EDB1336DB5B193
-:107580005C4FF7C77E0BF0F313A0CB2698EEA3B6A3
-:107590007F8E9E5EFCB4660FFD88EBE9ABADCD91AE
-:1075A000FDD4DFB09E6ED6CF73C592A3BF83757C2A
-:1075B00018E07034EBEB1F2A4AAC4CF0E170F84C49
-:1075C0005262D1AF7726C0F97D5FF8A8C3E11CC233
-:1075D000218CDFF705C7B35A7FBD0CF621D92D45A5
-:1075E0000EF72F13D19FB0457063BC8A59199B0ABF
-:1075F000E778A2386B6F53989E11972B12BE9CAE02
-:107600003B569A8CFC070C5DF4F7BE527D2C15FDA1
-:10761000AC650762883F9AE72DCF37F2994FEA0BA6
-:10762000B27F0FFD8ADE11030E84477E1CE75F4F99
-:107630008B0111CA9DD539B1E1FBF8D02477565999
-:107640002B239E63C52EE33916E5D7D038271F14A8
-:10765000DA8401F03C324D525CBDFB1559F9FE57FE
-:107660001D10C9CFBBAAEECF6F607C7115F07B54A3
-:10767000135E69AC9D8F787DDA2B5910CF3BDB12FE
-:10768000E6237CFCC5A23B03DA1F6F1C4E787EA666
-:10769000316710CEF7CB9922C9BB0F0FDA2DC2B5D7
-:1076A000F0F44A2C487E81209DE727754524AF3EA3
-:1076B00044B8903D2B135D9C98C9E30EA7611CACA8
-:1076C000B7009DA03EDC19103D8108F47162263F91
-:1076D0008FB3971E20FC7939702C16F58AD36D7CF8
-:1076E000FCB3D5722CC6A95EAF9BE0A2F5E5C3B88A
-:1076F000A8F71EE272F4C33A8E8FB84EB20F1BB9D0
-:10770000FC3859B7E2FE69008F4FB788A4777EDA5C
-:1077100058347F1A9EF71689CA39050B29CE713263
-:10772000C0E5D1A9C0D9523CBF0FEBE0F4A15C7316
-:10773000680AC9DD4FEA25C287F203C67359B82526
-:10774000C66CAFC66681DE558EBF29F83F7516DA66
-:1077500049CB93407E02E59ECE2F92D04F59E84F01
-:10776000308C63670512E21DEA97D86EF9C3459322
-:1077700082487F7E81E4DFB2E7009F603DD2BEEBAE
-:1077800049DE9535DB0DF316561BEDA3E5267BC8C8
-:107790006C2F5D4E5E9CD6F054B73B4E4B95A59139
-:1077A000F212E45C4D2E307916C2FD0C18D64D59FC
-:1077B00000CFE74415CB17EBA2887F962D3B7F8344
-:1077C000A697DE8878C0DC7E3655B7D3C3E86C79DF
-:1077D0009D6892DB46F882FEFC01EAC78D099A1C7F
-:1077E000F51791DF6E548E1A9F8BEBB852FBFB8A14
-:1077F000F5DB524DBF2D25FDF624EAB7B09F766C20
-:1078000012D61FF45DF2EF9C9A7713D95FA7BAFDE9
-:10781000675ECD7FC6F59453F9459A7FC7AD97074C
-:10782000B07EF89CCE2FDED7CEE1ACC6274F6B7C66
-:10783000B253B3B71A347951A7C98B53F99ABD958E
-:10784000C8485E58AD2ABB123E734B4B8C493E2450
-:1078500098ECA821A6F331CA8BED5EDF6C3C077B68
-:10786000D268C37B491E6FD4CFF71D263FF24585F2
-:10787000E7156D429CC0B8C9429EA7C51C6DE44780
-:107880005EE856A87E08C60BA13D9A54984FA2E325
-:10789000A7FE5E4EE4EFF5723CECBA06DBA5B551EF
-:1078A000B9762163980F33421F07C051037AC21083
-:1078B000F467C33C4960A0617B1DDF87166FA37628
-:1078C000D9154C16A0DDEADC34C28724A6127F1934
-:1078D000B486A998F7C202CF52BBBDF7C23E00EFF3
-:1078E00043B5D3C92E2F72C4F2B837C8C7FEF1AC66
-:1078F00086C7773D09A4B70CB572D4EC136FB57683
-:1079000097C3DB303DE82EA20B66217FC4B6987189
-:1079100012E269A1D34B7E03C0EBA577A27EFFA242
-:107920008DFB0916723F707BDE9487D1DE1DF794C4
-:10793000937CCAED2B757F6517E1736775911FE521
-:10794000DEAF3D5CCE8D79EA130BE6BD751E646E2D
-:107950002C1FAB7EF6FCAF486F17C81F74B23A8776
-:10796000F365C6BC98C779D293B391CA53C130CEE0
-:10797000427A50375A711D00D726AA5FB17512EAB4
-:107980003BC745C2DF242DDF48C6734DEE2927AA29
-:107990005A991DA472523ECF13FC99A61FB469E7F1
-:1079A000F9B8E6A7784CA39B168D6EBEAFD1CD6615
-:1079B000B3DF7917A79B9156F7D618288FF4BB48E9
-:1079C000CEBC957F96D60DF42F635C372D4F6C9A05
-:1079D00008701B630F119F2E02B1B711F63323BF3E
-:1079E00086F2188B7C8CE21685C535B4BE10C6981D
-:1079F000AE43BDA94610B57AE48F631282D4BED0DF
-:107A0000C164EC5FE479FA08E6E32EF40168A03C77
-:107A1000B3B84620F894C178D0FE48F5761AEF54F2
-:107A2000055F47BB8BF73F59C6643F943398E7E83F
-:107A30001D7C9D5E8C8B9EAA7EF608C1BB98C3FB05
-:107A4000BA8F2C067ACC0A461BE87AF4BE7843FD3E
-:107A5000A81D2986F2406FBAA17D82C748EFD123C5
-:107A6000C61BEA4F7A8A2C2867753B4FF78B757ACD
-:107A7000B8DC9DF194D382F058A4F90B1061D920A1
-:107A8000B4BA18F97D1B353D91350F6798C7B1F72A
-:107A9000BB16CA13D85C5CEBC0FC878B6D563A2FC3
-:107AA0001897F8C8A9C3561AD7915627A01FF33EB6
-:107AB00080B318A6FF35EAF24D8B5FE07AAC61EB3C
-:107AC000895718668E75B76FD1F069BBB60EE0DBCB
-:107AD0003324B2C7399E24E4338B04FD071673396F
-:107AE0006DA6CB36ADFFE35AFFC7347CECF4ECDD7A
-:107AF000188D7059CC481FC915D76C8CC275E433EA
-:107B0000A2C7B6E0D1E870FDF1677D8D533C2197A7
-:107B1000C6F1733E3A7A81501B85E7BA2BF4A7373A
-:107B2000E1F9C2A70D1B6361BD4F08AC0D294AE7FF
-:107B30009FBAFE7DDD678D543F7A3C986850FFC246
-:107B4000674DBCFD64A6A0BFEB679ADC69D4E8274B
-:107B500063DF58F22F5EDC6123BBE7B1F9ABF6B40B
-:107B6000C07A47CDBDE789E7105FE6DFF3BBE79456
-:107B70001E3DBF687E7207E6F18FDCE062C81FF42D
-:107B80007933F67D924DEB96AD0CF1F4C7FB9F5F18
-:107B90008EE33DFE58B44585F17FBCC74AFCE5EA5B
-:107BA000FB1EDEB383E48D492FF618EDFCC737B713
-:107BB0003E7110DF573DFBE8B9B07C9D93F3360D65
-:107BC00043BF69FB868A9699197DF3CF221BF3A1E7
-:107BD000FFC7F3C227CFBC0EF3FFC677F5F8703BA3
-:107BE00060D42CEEFF69DF50D53213ECD4D122CF14
-:107BF000576056FF4684C7E89F0E52507F0352B02D
-:107C0000FA00969E39511615F6F79B807537F1816B
-:107C1000399B33F03CB37F9C7FF4233CE7531ABE7F
-:107C2000F7A18FE87EAAEEB2A410DCFD2F3AB87D52
-:107C3000A32AC3C83E762BC30AC3F4B9F67BF43833
-:107C40009EFB3DE4E3852531145FD6E32EA2E7CF0A
-:107C5000F5C8E7974DAD9C24D3FA8DF1FC1484DF71
-:107C6000048CF7F2B8BDDF6F65941F045B433AB92B
-:107C70005B1C4D7927EFAEBE8BE2F6FE1ABB9C91E2
-:107C8000487183A7B05C057CC73E91E2B901CA3751
-:107C90009EC5F3372E2CAE7DD8A6F40DFFBACB9C33
-:107CA0008FA49D8FF9FDCDDAB9D4E2B96418CEE581
-:107CB000A86F6284738975107EE9E722C636D2B94F
-:107CC00030873313F33F067394C2FDBC8172A8E37F
-:107CD000944872EC3725EB6AEE86F2F94B0318D222
-:107CE000851E57294DE279087424C0B724ADFF6082
-:107CF0004DEF463E867A77A91677E958CA28EEA254
-:107D00008F77B16A80CCC7BB8DF4E6D24AA07F944E
-:107D100025313F27FDA27E38CF932875762DA5BC4F
-:107D200055C1E2C6F8F960935EEF6795B4DEC1EF26
-:107D300088E4CFB7C46CA1FE83013C6216B6B211D1
-:107D400010A83D0A76305A31AF24055F28617A9633
-:107D500096B73BB8EAA75C3FCA819EC986F9842FD3
-:107D600069FDB5EF8BC807AAEC0AF23DCCD142BE43
-:107D70004DF04B433C6AA5FEF2B7998CF73998CA8F
-:107D800094C4C9DC0F86F399D70FE371BD10F433A7
-:107D9000DCAF50CDE7DF3597DF07618799126EB70B
-:107DA000B0F0F50C3794353F99B12C25D90C72EA17
-:107DB00037978A0654F6EBC733F6B728DEFEFDBECA
-:107DC000156176577A4F7B3D5F4C87734A95FDB4BA
-:107DD00010DB77BFED5EF5C02CC06727F366FF0AA6
-:107DE000E0E17B4724796789394EF0084571F874E2
-:107DF000EBB38BB9BE0BDA790DE55D83BCC3F3C37E
-:107E00007CED9180EFCC6FCC17D0E7D5E34B1D1AFA
-:107E10003F0EA58522FA058F69F4DBB9E173CA2B01
-:107E20002845FD167039B4F163C33D900105338ECA
-:107E3000E1BACDF908BA5E8A7296F0D7CFE56C87C1
-:107E40007F02F19D8BCCD54CFABF99DF5819E57FA5
-:107E5000DC2D46BB9BC86F772FE58F54F9EDB21D23
-:107E60009EF3DC467FCC82A9467950A02698E48513
-:107E7000D1DFB5D06B8C138D68594FFCEB22EA4DE6
-:107E8000C4EFF87AAC5A7E9984F74C44B4D7FDF429
-:107E90003CAEF1E737353D330AF92BBC8FC1047393
-:107EA000C047170B517900A2FC704C6D5728EF3179
-:107EB00081A9541EC87C54D6F3219359809E7A9E82
-:107EC000CB3016A2F255A80F8948520A3D87A31D50
-:107ED000321CF53C7777BC87F22773D2285E50C0FE
-:107EE000D4F7B05DFE844F49EEE5DFC4C80FCFFC88
-:107EF000F52B5428772CD4CA98098FF926B98C23EE
-:107F0000A7BF96D7E7E9E5BA152AD6CFE0EDA5D900
-:107F10004D7BFD4EE25F5AFD265EDF5D6E583103FC
-:107F2000CB9285CA715AFBC299AA6D36E62DCD66F1
-:107F30008407C11CD5317B604FB92C478D0E2FAF04
-:107F4000CB559DE1E567B3D5D8F07267B62A879720
-:107F500087E6AAF1BCCCFD4EEF48EA30B477E1E702
-:107F600047C2648E87F8F39AE44BC176EA0181E058
-:107F70006507BE8DF092981A44A60464E3C07C2283
-:107F8000E033B63BA19E8DB751DE9F25C699DA9F9F
-:107F90003FD24C5F21891D443FDD02AB2F13F76DAB
-:107FA000E67B82FF95BF633E0FD04336EAF9A16AB4
-:107FB000AE0784AAB93F40A713FDBD79BECBE13D12
-:107FC00053C3FCBCE93DE3F6B57E331E9FD0F4BD40
-:107FD000764DDF7B47F34B77EF37648DFBC0D143A2
-:107FE000DF7DF34F2BFB208C7FF6DEEFD9A51297B8
-:107FF0001F32CA8B8E28B638D2FDCABED6E7CC99BE
-:1080000055309BECDBA132C51998CEF739BFE9C0DA
-:108010005F810F8E19A0DBAF6E07C2218325CDC90A
-:108020008479B77918E9AFB5338F1622FFB95802B2
-:10803000120CD675F68E7348714C788ADB13CDC35B
-:1080400018ADD7952647A1BE54AFF14D3B8BCB1B46
-:1080500081EB1F6A25796B5E777D6C40C0B8624A00
-:10806000308AFB371259200AC649F1B83D94B7E26D
-:1080700017650F964BD8FC4C282F6F11150F8C737A
-:10808000ACA58895C3B8E55381CF51663ACFA78890
-:10809000D7F0788C9D51BE45EB4027C5ABEB368FB2
-:1080A0003AB212F966B2C832A0FDD8FAF11EF47BDA
-:1080B000D63AE3E329E6A4ADA7D6E97E15EF63F847
-:1080C000650BBF4F22AB0ECC47DF7D87D583FC7C91
-:1080D000D8D31363C530F89FAD3B1F8579EE8FCAA7
-:1080E00016AA7FB43ADB718B13EF130655CA33908F
-:1080F000CFA84E987727B4190CE3DD5F71A67924D9
-:10810000EB1B1F623D36039EC6B86D263FA8D16F9C
-:108110002999F483E6D95AFC7B329B8CE77CED13DA
-:108120009724D473973915F2A367370A949F123AAC
-:10813000E24EC5733ABB7514F9CDEB1A45CD6FED20
-:1081400026BF7568184BC57B3665CD02E9C562DD73
-:108150009F6BB0DF55994A328E73D5C4AEE4707F01
-:10816000D9A3F7DC15857CB4AEC4A2F9B9198DA3E7
-:1081700028AA230DF6FF7E9DC0F3272459C0FBCC0F
-:10818000AE07C5285C57A7C4FD144DC04FF19E6EC5
-:10819000D38CC27EE950FA1BAC33CC6EA94F4C8F06
-:1081A000C6797BF05725FFFAB9E609141FD9D39891
-:1081B0004DF920E671EEDBC0DAD03EA9DFE0A06722
-:1081C000AFFA546FAA1BFABFBF6D46030829F6FE2B
-:1081D00091D549784F6865B39D4545C0E373DBA6EB
-:1081E000D07C2BF13E33CEDB5C60433931BB6586FE
-:1081F0000DE176DF06F5E9F079EE2CF0BD8C7C2FF1
-:10820000A6F969C213270BFA119EBFB8414D45FD6F
-:10821000E25C068B982F796236D7335EBFC14BF78D
-:108220004ADE1F16B9DD3BB3B9DF792E120BCA0F38
-:108230002B7B7315C0B90CE8A9065E9D6D9C108B55
-:10824000782BB135C4A47E5352E4477BEE02EAEDAD
-:10825000C0CF1BEE59B4A31CDAD5DF3BF22D64CF9F
-:10826000D7DAB8DECC7E2D125D805E5886F4F997A1
-:1082700062875C1BC67F517F540DF9825E86FA9D32
-:10828000D428066DC0CFA5C31FFC37DA3B88B76A78
-:10829000181ED3CF64CD2ED0F235922693364E3FA2
-:1082A000F5731605820CE32E2B1C789E663DBD17D8
-:1082B0009EF45A47D8F8A8E7CE646A54D83A802585
-:1082C00004C95FEEE3F376B7D3EAADC060BE0CD36A
-:1082D000DFCDF5FA3E46ED30D2ABC3C3CF0BE0DBCA
-:1082E0006FBCEEEA80B1DF480FA3731B2DAA473F96
-:1082F0004039DB2A527EF598561EFFBF3894919F75
-:10830000A8AFF174FE8B3FD6411A1C01AE0D8985D2
-:10831000749E7DF5B3054EA869E37AECC3AB938CEC
-:10832000EBD2DB8DECDED73A16CDF5C136B4CFEC0F
-:1083300001E07BE3F0794245F99DB9FB0EB9BF7DC1
-:108340009BF9D94A5669437D4D51427BEE43BED1DC
-:10835000E222F983E83062325D5D24B983FDD430D6
-:10836000BEE77A706FD36858C7B95DDC1FDAB46DA9
-:10837000EF134FA0DCD915E3E671267E4EE3982E6D
-:10838000FF78FECF2DACE74719A48D0FED3FD2E467
-:1083900029C350D5A09E78D50707967FF604FCFA2E
-:1083A0003EAB9C8A7C4CDA5DE4B819CAE36C81244C
-:1083B000E4A7B7ECB2F7AC0BFED95B8C65699FBD47
-:1083C000175E3A747C82F19A0E3DB16339CAA943B3
-:1083D0000E37A688237EF90D74124A2F007AEABC64
-:1083E000E73FE89E7EB47C7E29E5B957DBE97E97BE
-:1083F00019BEFB6673BB9F69F736747A8A6A1EC51D
-:10840000D0BF7846B39BCE6C013B15CA0DD536055F
-:10841000BF6FD0E92E5093228C67ABB69DC67365B3
-:10842000E176627ACF3EF4F13BFDDC0FD900E30B3D
-:1084300011FC7D971BEF4F5EB5C203F87FC1EBFDCA
-:10844000B607D67F76CB0ADA6FD5C1EACE5FE1F9FF
-:108450000EF2DD86F567B60C9F2CA023D2AAD0BD04
-:10846000BFBABA67489E344F857760CF37B759A3F4
-:1084700050FFF0D759287EDBDC96183D02E594D3F7
-:108480001231CE1AF070BED9234FBCB1E1FA50D3ED
-:108490004CAE0F094F95DC9F0EF0AA3BC5F3147547
-:1084A000FD43D6F0648C5D26FE2CD7F13CB71E7DD3
-:1084B00088EBD51751AF467D6952B91C2E9FEA63F0
-:1084C000F9F730CA67BAFD781F33C7C9487E5C85A3
-:1084D0009716D06FE16481D969F8BD0C37C3FCDC15
-:1084E00078D07F14C0F8C12D5CDF89763ADD2AE2AE
-:1084F000BBCAE9CA01FF213CA3335586F3584DFAA4
-:1085000085CDA43F88A6F24E8F519F50983B16E12F
-:10851000ECDADA7F1E87EECF05BD89EE9BF919C034
-:108520001FF1D4E1A7F389054302ED0AA6AA4AE2A6
-:10853000A01EBD1FEFB571FF8A4CF122416D20BF17
-:10854000FDAE09DCBF91CC78DC2B45E5F6FCB8A983
-:108550007E2A83FD407128F673168D7C79BBD7F790
-:108560000CE24D9A1020FB2F7E2C1388ECBFA65EE8
-:10857000CEAAAE2CAEF4C3A3DCFF576B897647FAC4
-:108580009EC2A1B99C1EA38FC1DEA09D789383E2F9
-:1085900079B9E28146C4A79D132DE4D7DEC94EC840
-:1085A000C84F8E7B787ED125AFF7750FC565BD6945
-:1085B00008FF242B5854A0ECDA343FEEB03BD3A391
-:1085C00051D4BF9BFC3CC1C30FB0CB807FBBAB126F
-:1085D000E333E1FD23551B09AECA40EE27D3EF9FDD
-:1085E00027C8FC9E7F93F7BC1FEFF9FE702EBF07D4
-:1085F000145D609D930EE5ABAA4302D2DD26977B06
-:1086000031E273A3F20C9D475A9662417FD9102B39
-:108610007BD53E9EB127E3783D0A4AACFFC1D241EB
-:10862000BBC3F3491ED0F6FD0321B2BEB27C2E9728
-:10863000271D87009003D03E669AFDFD7839D9CF7B
-:10864000DD65801BF47FC0CFEDE73F7B1E2FF75B1E
-:10865000C92ED2ECF7F672B2CF315E0AF573F2D6BC
-:1086600095FBA1FC485AE47913F2397C1F794DDD62
-:108670001103F0F86B0D8F63F57DCEAA6001DE5219
-:108680003B90A5E23AEB5CB6C591BE27B3329FEFB3
-:10869000B723B18DE0C5409EC75E47F7E94DFA6A42
-:1086A00080F4E00B15E3FD536877958CE2FFC04F33
-:1086B000264DA6ABFEF4E39AC4E5A8596FD5F52B79
-:1086C0007DDEFB522B9351FF6C75A9C43F5A416F5D
-:1086D000453C2BADE67A6BA9B5EB3DBC3F94729C53
-:1086E000E7BF084F8D6DC2EF1B00BC14C4BBD94E51
-:1086F0009521BF1963F7D23DA35ACC5F977BF457FE
-:10870000260E3DE283F7D21091F4C418B98DF457C8
-:108710003693E7E5AAF01FF21B5D9F758EB51AF23E
-:1087200077EDA6FC5EC994CF9B99A7E5C369FCC60B
-:10873000356962BF7AD3CFC1DEC5751D067E83CF92
-:1087400020D8BDF83C0A76393E5F02BB1CFDDD2F08
-:108750006FC8A4E7AB1BDCF4FE571BA6D2737A6A82
-:1087600048427D9BFCCEE47C644181FC773A3E0527
-:1087700046648FC5FBC7BC7EE69C94FFF05F0FF597
-:10878000895A7BFF17849FDD65A6ACC4F6A549BC5A
-:108790007C302F7525FA775E2B56B3F300CF065A3F
-:1087A000BC65F85D07F65D3BC527CCFB3996A7CBCA
-:1087B000EBC8F63AC34F1618FD35DEBC7EFC353FDC
-:1087C00010F83A96CF5DB70FD731A0C0EA457C4D7F
-:1087D0004D37C609F6E769F107ED99FAABCA878804
-:1087E0001E04A08789FDD14390213DEC74B11B91FB
-:1087F0001E5A5747A6871BF2B95C6D75727B8FCDE9
-:10880000017A1802E512B3FD16A2FC8F0B557B8F7F
-:10881000647C23F4A026A13CAD5B0DF214C6A93BF9
-:10882000B2FA5D92A3480FD07A30D203D247183DF6
-:10883000E077585AE3347A900302C681801E82782A
-:108840005FB04EBBCF11460F02CAE16E7AA8F86640
-:10885000E9A129CF287FBF2A3DFCE28610E53174CB
-:10886000A40592110E3B25EE3FFAAA74326C8E8D50
-:10887000FB8BAE7127217FA995383F9D3DF434F9DC
-:10888000E1F21D6E11E58A47E178983B71027DFFA8
-:10889000E7CD3C1BFF5EC102750FE1FFA28FC8DF71
-:1088A0003AD0C2E9EBD86B7BCB112F87D5B717CC69
-:1088B00046BC582F92DEDB6B7FF334FC11F8FA4193
-:1088C000034A0E8FE7FD671EAF57D69FE4FC368E36
-:1088D000C919B09E24BF5CE8C1F8CCF516FABEC732
-:1088E0008082F6389493FA78CC5A998CF8852AA825
-:1088F000637C6F7A819F36699081DE7EDE1FBD5D6D
-:108900008EBE676BF4053F9477EBD3EE2D7E55FF5B
-:10891000699FFEBC6B22FB07B76872AE55E27918FF
-:10892000D05AC67BFA4F797DBFCD23FFAB490F3BB1
-:108930002C07D15FC6D6C6927F37C9CAF5AE24854B
-:10894000E78F0C617E82B31E07D3F53645E5793E8D
-:10895000B905BEB338EE6EA61CC1EF1938DD6C3117
-:10896000C5B9407FC578F576AF7A8EE6FD9AFA589C
-:108970004281FA497FF874FD22B50BC7EFAB7E4602
-:10898000C15F8E7D89718B6A9ECF6CADBE9DEE738B
-:108990008960AF5830DEE969A3EF02C9B24D51C812
-:1089A000EE52E763DE62AC069F59E227A47FB7264A
-:1089B00081FEEFEEF183EE4CE6714E113DDCA077C7
-:1089C000B61E77FB6F81796CC037FC788F3D1FF442
-:1089D0007428C7A09E8E634DE5FAB87EFF2566AC6D
-:1089E000A6A7ABC638DCE5F4F4017334B9399E4D63
-:1089F00044F8A45A94EDD3E0FD8487724FE2F14C21
-:108A00007A7865028AB329BBEB8BF0FB57ABF7BFD3
-:108A1000BF1BFD92D37E6B6748A7AD87B89EA22E81
-:108A200060742FF90AF83CD1C90DF94F97FB472024
-:108A30007F898C77AF6B78D781789768C0BBCC394A
-:108A40000323E29D1FF9F13F8077E3E718F12EDF62
-:108A5000847713E6FC6378771DAEFB138CFFC03878
-:108A6000EF2D546F98D30F1EA62E5467CCE9070F35
-:108A7000C3FCEE644F8D645551E1DF15D49F0D2882
-:108A8000E7FA89FBDB379F21B9595B95E340FDADE0
-:108A9000AEE4CC1B1847F84B955D09F713819E6730
-:108AA000D083615CE60703F6683ECF633EB6DE1E08
-:108AB0009C0EFD4A65EECF2F95DD0CF3A845679718
-:108AC000E4037EB52CC9C750BFB627597AFC12F013
-:108AD000EF5AE9843707E0DC097214CE984DBF677E
-:108AE0007B22FA9B5E3B3495FC4E3A7D74C4F17157
-:108AF0006FE802F914D67FFADF406E85E1FB0C6067
-:108B0000E0E1E51C47B2A17DAE9C66A89F9D74B5CF
-:108B1000A1DE3569DF4CC40BB14C8BEB6BF7CF7426
-:108B2000FD618C5D253C6BD5F4DB3C25CBD01FF57E
-:108B30005CE47F5694EB503F37739A613E5DBE5FB5
-:108B40000FFF21DD8A26B96D96F356939CEFACBEDC
-:108B5000108FFCBE618EF1BEDA666B289BF808E3CD
-:108B6000796A575DFA05E17FA7C2F1BB4EE2F8EEE4
-:108B70009FAA7D67C5443FE36CDC6F56BBC4417E52
-:108B8000FBDA43DF7AD717E64F622CF01ADE671C58
-:108B9000171BAFA03F7E8895DBCFB2CAEDC0B1AE48
-:108BA000EFD3F86C35979F82CCBF37B90BF8027EB4
-:108BB0003F8B1D0E913DCFBE6BA3FB4EE3E6C7116D
-:108BC000DEECACB0501ED60F856094301CE9562503
-:108BD00039C392985C47F9876FF3EF1432E6DE9C55
-:108BE0008CA6B44A79826CAAA3EB352D2F15ED948F
-:108BF000280F736F9C867C90EF337E223F3FA79BAC
-:108C000097E5EB7959B75FE3925833E6990EC1F1D6
-:108C1000A06D6215936BC94F10A4FAA11E76A2969F
-:108C2000E6E7FD0797336F2394C54A55F3DFFAB49F
-:108C3000787517C591D3057734F2EDE1A297E2C8B4
-:108C4000B14CA638730AABA4678C10E44CE36BF20A
-:108C50008F6B010018AF67B136F2E766FFD8C9D055
-:108C6000EFD6EAB2EDA1FC9890427EB94DA7F8BDCF
-:108C7000B6DAA577BD3109DA37BEC1F3F3370DF3A4
-:108C8000BF8B748D3889F742456725D50F7E5574A3
-:108C9000CF56F07D33C37BC4CB9C9600860AAEB51D
-:108CA00075FD12F3EE58BC8DA13E5207FDCBA0BE60
-:108CB00073A905793143CDB4DBFF88F53778FDAF73
-:108CC000A39EFBDF03E81E3233F90D5B7D5C5F6E14
-:108CD0004DB4119DD7966427E1780D89D174DF6C6E
-:108CE000F18D956F20FFA87D5B746F14781FF4A73A
-:108CF00013EE613CDFE64D433DD4E6B4517E87D9A7
-:108D0000EF6763DEB726C1BEEAE26E49EA4F1FEAAB
-:108D100033CE506209DA62AF3CCE507FEF4D14572C
-:108D2000D0D7A9EFB3A1E4BCB45CC1DFFEC1384326
-:108D3000B51039CE10E2DFD3C8C0FA71081FEECFEC
-:108D4000FEBA71861DF3BE5E9C41DFF73CEDF77CF9
-:108D5000406C2D5F82FCED746E969EF585C1711F8F
-:108D6000AEAF147F53F87BF49F2FD0CA6F1C68FFFF
-:108D700004FDE4C77F74F4003EA75F7AB4642DE07D
-:108D800045C154EECF7FEB7B710FF2E18C7EF97918
-:108D90006EA3BF1C7F103F691D02BFE71E5E5F60B0
-:108DA0005A57B6D5E85F9FE934B69F9568ACF70C83
-:108DB0003596F5BC15F37E37C6DC4F79679BD63107
-:108DC000FA1E110B3F0FF1F265BBD21B4FC2FDE53E
-:108DD000CC9D4674DFF90EA77BEF8B7F71915D9977
-:108DE0006491D10EBDB0B87ED3EB4A783CC0A322CB
-:108DF0001E7DF193B16FA25F9BC9BE20E6F12DCF1E
-:108E0000E1DF61EAE59FD7FCE3195547DA6686C5DD
-:108E10004F9B06F96E9A0BFA4B4649A105F5878CD4
-:108E2000AA97A87ED19249FDE291AFEA98611CFC15
-:108E30009E1DDAB7BEAA97E97D5FFA8E45F1F37CF5
-:108E4000B86ABB42FE5FD3F76E7D98CF867C3E9DAD
-:108E5000CB9B5A89CB273815265EC7485909DF971F
-:108E600045E17CFDE2547E4F820117427EA58F676B
-:108E7000968FBA1C70AA5C7FF4559BF2EF4CE36F9F
-:108E8000F7FAEE990B7425381B789E5D8ED6EE307E
-:108E9000D74BD91C26A35C867D46CCBBAC9BABD9FB
-:108EA000997DE47B31DD0E2C7EF55DE4875FD90E84
-:108EB000EC63DCE9A9A1A591EE23EDCED3F4F1A8F2
-:108EC000D030E4C31D5264BDFDF6E2593BE6F6A383
-:108ED000D7629E6A78DE44AF7D7FCD3CD5DF7AB81D
-:108EE000FF4B8F3FEAF9AACC1A188FDFCFCC74FE64
-:108EF000FA668A2BF691A7BAC9E50EA1BFAAB62CCD
-:108F00008ABEF7F875FDD56734BFFB037319F78781
-:108F10009BFCF5E6751FD1FCD797BCDE20E24B5FCA
-:108F20007E7ABDFDBBC991FD64C9F3F5FBF3DAFDA3
-:108F30001F0FD7FB54C9CD22D9057A7EA2F93DD89F
-:108F400041EDB80EBD5C569F417EB65689E32DE5D6
-:108F5000740CE9C96775A2FE477A5433D5C75670B9
-:108F60007D50D7B3642D4E60A627A08FD3441F2514
-:108F70003CEED0A3276AF4B108E803E87228E37452
-:108F80006CD1F230873A784AF7D7D5A37ADB4D1EF9
-:108F900047A4BCD3CBDA4DF5931C643739C7BF8ADD
-:108FA0007A556715BFBFD6E1EA7261DE8AFF6D911F
-:108FB000BE67DB577FDD7E12E71BEDA76525DCCEA4
-:108FC0005956A2DB4F21C9E742BF30D84FE487F59D
-:108FD000D9F307F6B6A3305F14CF09EC4C47FE3740
-:108FE000C11F4C7EA263985700EB3C32E23CF93F34
-:108FF000065771FFC7E02AEEFF4841FF471AFA37CC
-:10900000B8BD56EBE6FE0CDD7EABD3F2BC747FC878
-:10901000551A1E8CB157727F88664FD51EEF22FB02
-:10902000C9A97DCF06E3758847B66A21802E4226FE
-:109030005ECA453DD83E983E6FCA58B5D10F62CE44
-:1090400043769AFC1DE6BC816BF3353B4AF37F3CCB
-:109050002228F74D83799EDD91FB3AA2ED7FEE5AEF
-:109060001983FE8F9F06EAE76AFE8F87F0BEC5A1CF
-:1090700077B9FFA3EE10F74BFB5081B92E12FEF526
-:109080008AFB90FF6365BE9FFC1FBA3F6999533B03
-:109090007727DF2FC297BEE7E9E165F4432804CFC5
-:1090A0004F7E8971C2BA6B782EB89D6511FCF4FBB6
-:1090B000AD3AFC772619E1ADFB9FC6D803AFE1FAC4
-:1090C0003B92AD6C23CA51F1138AD7889A1FFA9B41
-:1090D000F22BDD9C6FF42B8D7F68C276FC0EEFC403
-:1090E000878B4EE273F2EE750937C373EAFEED45E6
-:1090F000F864AF7238FE751EE75B98311DCEB796E7
-:10910000E729C44F7BE0CAFD4A3A3EF6F8E378BC53
-:10911000BBB482913FAE54ADA43B8C98E78DF8A3CD
-:10912000C3A7D5849FB5C3783965666510EDDE0C9D
-:1091300080A72AF7C6D7D6E36D6B89EFADB6297E37
-:1091400082DFA51AF4D3D9357BDF8C8F197EE3FD3E
-:10915000E1CBE1638D096ECFEC98701FC2EBB95D76
-:1091600045AFE3F3F9C0BA1884D7C17DDBE7F60158
-:10917000B764431E3FC26D526F7C3C5EE06BCE878E
-:10918000F7D3DD012BF1DB0A8CD961DEDBDA286352
-:109190005C45E7933F8AFA5A7C72F379BAD7585BF9
-:1091A0007D81FC4A7555FCBB101D2EB571E4C42BA6
-:1091B000E793D7CEE3F7D8753E99A2F99952E41018
-:1091C000D1E332A047CCFF5C56CDE30A78CC310026
-:1091D0000F31890563C87FE0207ADA89F9C3D7F6B1
-:1091E000E04F27B4B30F60BDE49399BF825C7C1E4F
-:1091F000E1D5599D407ED93DDAF74555AB9BECC78B
-:10920000D9C5DE8358AFC7A5B67BD543C487BFBEDB
-:10921000BFF0487E98BFB0238E75FBD76A601F39B8
-:1092200055590CE34BA2DC2529E85FABDE2DA09C51
-:10923000583A87D349CAD04A9217BDFD6D5D396847
-:109240002F74E04DF12CC283B771DD1D557B090FE2
-:10925000AE5DCDFD241D55171222E3C1DF5C5FCF4B
-:10926000CF389EF2837579B9B31B0F02AF4DF90A5F
-:10927000F272FE3CA3BC4CD1E83EA5FAF443E89759
-:1092800016353C109DDC2F8DFC13F160701FFE47DE
-:109290001D0FEA1056801775B239AEC8EFE55EA80B
-:1092A000DE4B7FBEA5AFF55D3E2F548BAF633C9187
-:1092B000C7D7DF453CB556F17862C7FAD964275E57
-:1092C000A81664F437EFA9BE5DC0F39B5D1210428F
-:1092D000CEF0797AE5833AE60DEC891FEAF1C2E334
-:1092E00005DE687C3F1D702A291EFD7F9A1F7D6860
-:1092F00064FF1FE077FC3CD43F0FCB244F743F3A10
-:109300009374FC561370BC71B6AE6132E1B72F098D
-:10931000DB771EFA2FCA0BE8F113F23CB37FD8CFEC
-:10932000556AF473ED5C6ADB43DFD763A15C8A8F17
-:10933000601C01F9F6363BE533960B0AE5FFFDB5F7
-:10934000C03796F6C1BC9467EA2B76C8E40F734D1C
-:109350004E42FC286D10496EF7659FF4A6B3D3C446
-:109360005F5200AF347E437044391D158774271057
-:109370007F1181BFC4A01C44BA1B1BCE5F024B8867
-:10938000BF328B3B36F58AF84C0EC2B91F3E933B79
-:10939000CFC86766CDFB07E212C17CC6ED3A6DDF30
-:1093A000A87FD2BE357AEADE77099733A287EFBB72
-:1093B0005B2FD5F88C998ECCFBFA7F90AED6F54119
-:1093C000577722BCBF025DDD7319BABA17EBC3E849
-:1093D000AA96CEFF5F8FAE5AAF84AEC6CE63C6FCF0
-:1093E00063ED3BCA63BE63E1F98BFF97F38F13E72D
-:1093F00072FBDC9C7F8CF92258CE87B3A1F3D1CAD3
-:10940000F3273205EFA7D977BFB465B4C2C70BF70E
-:109410007B3293BF9399FC9B66FD2E823FD4E0FF85
-:109420003CFEC4EF8E8F865F7FFCE47F915EFBC6BF
-:109430002C81E28FF3477D7118F5FD82CD6BB53C31
-:10944000F7FEFD9FFF6C7F27FE84FB57CDFBDA14F0
-:1094500073BF068FAFE6EF64EE1AFA7E7867257366
-:1094600013DC2FE3FFEC94471AF285BD2F963FB82B
-:1094700010FD9FC7F977F8CC7E4F3D0FB8B5643922
-:10948000E9F96754875B8CE0F75C9EA0DC46FEDC64
-:10949000DE7ECFBF221DFCA37ECF657315C243B312
-:1094A000FFB318D8D5FC7EE2BE1D719502F2BB9CBD
-:1094B0001237E5DBB14BEBE8EF39882521D2034BBE
-:1094C000ABB81E38A0C0E7C2715286B27107D13E58
-:1094D000A912DC16A5375F063D33767E785EC93764
-:1094E000EC2FF867F9FB5E99FBD5EEA5BF82F09EE5
-:1094F000D4CFFD7425F430E6AD3D52E3A2EF563DE6
-:10950000A2E9D11D929A84DF397F2BEE030BF2EF93
-:10951000408B85E1BD31B35EDCF7FEB8FCEACBCF12
-:1095200024A17D34B6C73EAAEDF623B91DE17EA481
-:10953000FA0D9E43E722C049D78BB7CD37DA47A54E
-:1095400025DC9E2D2D51C98F549AE861387E8A936F
-:10955000B5A15C1493BA24D4539655F8C8BE37C746
-:10956000E1CD78628ECB9BE3F0E638FDFFAF71F979
-:10957000F5F38DDF651CA7E5A1206FC7EFE998E340
-:10958000F09BADDC4ED9A9C23BDCCC578CCB5F75D0
-:10959000E9011EE757B9BF3499713D2D259FFB4B5B
-:1095A000CD7AC723526033DADD8FD458F4EF5618E2
-:1095B000E2FA635D3C3F7ADCFC05FB293F47D70BB1
-:1095C0002B402F14482FA4EF1C9556540A1CAFAA09
-:1095D0008EE03DD36532C7ABF9F339DD5887BA4920
-:1095E0000F16AB6F67FCDE959FDE97A6F2FB60D18E
-:1095F0008867D054CCE4715FF984E8C6FB095BB19D
-:10960000E934BC0FCAB81F679A85FEBE438B5099D8
-:109610008CFCF80141A627E84A748FF0C93875D050
-:1096200012F2DF58C86F7F2CB72109D7D758B32D56
-:1096300009F336DB34BFF8B6DC0FE8FB0EE2582640
-:10964000A39E02CF887FCFF39E0582F67781DA92C0
-:10965000E8FB02AC99F44931D3C6F8DFCF71075764
-:10966000201E9D73929EF08010E0F76E5C0EBADFB4
-:10967000D67CB52DB91CD6D3E4B291165177F5AC92
-:109680001369F0BE69A01C8B7180BAB474D94F7194
-:10969000EA865791BE9BD2D219E6CF37964CA67B6D
-:1096A000748D9780B140CFDAD123DF9A04EF370B66
-:1096B00021FA0E8F7F9A85E2F02D57CF4A0EBFE731
-:1096C00028CA3653DC93EB95A262A17B73A216CF16
-:1096D000167BC5B38DF1E9AB1670BD4861CD8BE942
-:1096E0005EA5D326E37E4BAF1E4F79AF179D36CADA
-:1096F000072A9518FF8EC6D58CCE2502BF337C571E
-:109700004532AD6F3306A629FFF98155A887E31DC1
-:10971000409E9F5FC3CBDDF5DF5B85F8431FDB8198
-:10972000F2D937EF5A85F9F80AE37FF7A33693E7C2
-:109730004F96BA0A89FF964AA188DFCDBDDC7A141C
-:109740001650B5F1D8FFE6789BAFB62DC67B44978F
-:109750001BAFE75C02C4BFBFEAB87A3BF3B8E67E52
-:10976000FF5BEDFBDAA76581FEBD43467910A41AC5
-:109770006AF7C3503FB66AFCB0367B7220A8603EE1
-:10978000AF9FD3459C2562BE6CDFF411363E4FCEB1
-:10979000257E4BE3E3B75CAAF2826913F9FBC2A40E
-:1097A0001EBAE9CEBFD0C683AA97514E6CD2F90536
-:1097B000560DEA19F7372513280F16EC0B25C11D96
-:1097C00081FEB43C0D6A9F46F7647F8B79E26C346E
-:1097D000233EA2B7B76AF39AF336B66BF37ED5BCD5
-:1097E0008D73B88789246BC80EACFB6D33E52F31C0
-:1097F000FCB813FA67B364BA5F769F10A07B91FE42
-:10980000951CBEFA3944B1EE1FB27BF47C9848F93E
-:109810003268BF25E9ADC3CF219DCE7204EAED9B2E
-:10982000478DA3BF136965CD8F3F01CF1D0736FE5E
-:1098300011F33EA2478CBB7FEA44BCC76E71E3F2D2
-:109840009CFFB6E36FA80A378C5DD98CC3ACD822D5
-:10985000A8E8D7B7CBCE3D681F318740768375FB2C
-:1098600060E20B49E5C6736F15D45FE377F4FC5BE8
-:1098700005E2A3516EA35D611B6A6CBF4EA33BB3AF
-:109880007DF2801039EEFDCC022E67AC686F84E962
-:109890000DDB2485BE0BBB6DB388914CB66DBD9DB1
-:1098A000F8D9CB6F15AEC2EF76DF592F11DC5B6FA5
-:1098B000B0D1DF8B6A75C98B16635993677A9CF9AF
-:1098C000816B4606C2FFAED0D39A9C6DBEC146F2F4
-:1098D0008059BB92D02F6BBE6FDDCBBE32E1DDE590
-:1098E000F02C7741BC86DF01922BDD76FD280BBF83
-:1098F000573CCAF22F71AF786E373D7CB3F78AE7D9
-:10990000A2613EB027DFCFDA2BBF2795FC7BF5B3F2
-:109910006DF4FDB5AF6AEF6E5BBF8AE485FF76E656
-:10992000CE70F7CE0BF3BE3882F0476C14C90F2708
-:109930009AECD9FDF3A56EFEE308E3937A5ED07648
-:10994000ED9EEE766F03E5CFD479F83DDDA8E655C0
-:1099500064276F033D0CF3AA74BBF8CCD4F4C9029E
-:10996000E5FDA87EFC4EC6996C2D2F48367E4789B2
-:1099700069F97DFA7CDBA6A6D37C756887F7830737
-:10998000568F766FD7345E37BF467B3BECEF6982EC
-:10999000BD7D6E01C0FF7EA71B9D7050FF12D5B329
-:1099A00089F15774AFB2137F85761945EAC7384EEF
-:1099B0005EC6243FDA7967D80086F038E772CF4276
-:1099C000B5BB43723BC2FFFE416DB3A47D8F02E67F
-:1099D0001D4BF96D4B0B11EF4748C43FC4C42C7AA3
-:1099E0005FEEF25A2DB02EC19B6E884FE6B116EB9A
-:1099F0005AB2AB023329FE5DCE648CB794B99A2972
-:109A0000CE928B0B8489672B33C8CEF31CE6DF59CB
-:109A10009C1EF7FD449443FF0700378FAE00800083
-:109A2000000000001F8B080000000000000BAD3B91
-:109A30006B705BD599DFD5BDBA926C49BEB2652318
-:109A40001313AEED189CC43137217165089BEB47A9
-:109A5000880D29556CC749769C548140C3B4D36A9C
-:109A60005BBA4D76682DC772E2386014D3D661CBED
-:109A7000B622C0B6BB74C0A52FC8D08E1CB29467E6
-:109A8000715BDAC2B643454ABDA5D31FEE23E0EEB3
-:109A90006427FB7DDFB93796642571D28881C3B90D
-:109AA000E79CEF9CF3BD1FC78DC78E54451B00205C
-:109AB0006EFEB4BE092000E2B7DC3515695B0D30DF
-:109AC000F89A6CECE32FDA643408A084641831004F
-:109AD000A4A7D686325EEC7BA77F0D7E809B6600B6
-:109AE000DADD62ED19FC77DDAC1BDAEBE7FA2D0865
-:109AF00039BBDFE6AECC99BF5EABCE1997C134D28D
-:109B000012C086D0D29C79BE35AB353A6FA7BE3233
-:109B1000E7FBADF5CD39EBA15D3999C1FE5AFCE704
-:109B20004C0DC1137D1EAF06F036603F6BBD025970
-:109B30007D1CAF8BF882D3C5D8F9107CE88C0CB0B3
-:109B4000118CAD10A45187F138E2A5E2983B53EC9B
-:109B5000C0AE69EAC10AC4070DE9007D115CBC060C
-:109B6000FBDE6907E0BC8711865C09D0A8651C9FF5
-:109B7000263C6B13127F0798184164871493E741C2
-:109B800008B404CE5B047149C3BE2F0449EA5F05E3
-:109B9000499E8FBFE483CD004BDC62BDBF0B8C07B9
-:109BA00070BCB8212E49D82FED004346785E634A39
-:109BB000A2736AB85E5E09500969EE5775C0D42079
-:109BC000C337F7D1FACA3DA00D5512D8388FA7FA7E
-:109BD000204EE779040C70C9848F08402D800A312B
-:109BE0006EAF06BD1491088F82B18AFA759021A4D8
-:109BF00022555312F5AF80098DFA006988ACC02652
-:109C0000A304A6DD3C05CEACC37FE957A0A59DA665
-:109C10006DBAE0E4AFDC667647107FBDDBD69444D6
-:109C2000BDE75EA7EC797EA2FDFAB9FE6804915FFC
-:109C30004EDF37003450FB028F3F1589EC88E0F788
-:109C40004684EF5E75F1F86F54053E131218719C4F
-:109C50009F78F696D04E1C8F3FEB36EA80F08BF85B
-:109C600024BE08BB675E6A16EB891E41A407E1BBF0
-:109C7000B40124C2C1554407FCAE221D0E321D930F
-:109C80000C77710C8C016B5FEA57221D882E29D04E
-:109C90008A08AF72ECE2E8C03F8473C533EE4746F2
-:109CA00024C22ED2A5F6B2D0653FE1F162E9924F0F
-:109CB0000FB8B70CA0F97CFBC6998E5F91D21EA994
-:109CC00096C882F4C1FB48481FC26708043D54008F
-:109CD00083F05408FFD4F7AC067D1FF7C57CA2675C
-:109CE000BC798EFF4B90FF455FC85700E920FA8290
-:109CF0004E419217EC872213BCBE741744EEAF247A
-:109D00007A988C3C2744B975C18C446D8D6430BD04
-:109D10006AE58883FAC5525A20192949FAC00F1AF0
-:109D2000D3E74A88711B74CE4C9EC17D125E472AD0
-:109D30005E4DEDD32DB4CFE046D43028B70DBEB183
-:109D400016E6CBBB41AB43BE5BAC9AEE6AE29765CD
-:109D50008A11D7B3F1B58FE1836E1E29A671870FE3
-:109D60004656CFED9B701AA124D2EB75DFF4F12893
-:109D70007E2FAA94C165CCE1F9A453DC8F60CA8B15
-:109D8000481E847C84C27896C07CFD165204DF7A1B
-:109D90007723FE101F3B6800F1240D7F9FBF3FDC3F
-:109DA00026F4DD8391E8EB24C7A49F187F2668A4DE
-:109DB0009F3403586F3AF4F8EF64FC7E6AD8A51319
-:109DC0009F4272DC74E33E3BAD7D760EBBDE91FCC0
-:109DD00059F74CB8206DEBE71A5A1F29617E3624DB
-:109DE00070372D7CDDA5F23FEC292766BB20DFB65E
-:109DF0003CB5B624D370EE792AC94759F63A4127C3
-:109E00003588FCE4A5F11778FC42709C7B2673E44E
-:109E1000CC86E30C45188E73CF09216F64B7909EF2
-:109E200077A1DD1A417C7FD4D454C19733FF45F626
-:109E3000FCF698DF207BCE28C2797724A5D408F2DF
-:109E4000E39D1053894F25581227FAED884BC60819
-:109E50004EA939B8CBCFFE02B46B841F297DA37CF9
-:109E600066F945E0D1C2D38EF47B4EDD4778F5C16B
-:109E70006FEDF19AB9F1BFF4D5BEBE4627A5EDADA1
-:109E800027FA165BF445B51D7F05CFE93C5D02233B
-:109E90001A727FF1175E5B87E71BFA996CC8D5349D
-:109EA0004F0513E11581B0E3C524A7B5C42F13E90D
-:109EB0008F13BFED29D1E8BEF63CB0E6C5216AD2CA
-:109EC0003D8B510F105C47F17DCC9FC57E55979916
-:109ED000F951E364DFC38D7C57C1A8E65FB99A4EA0
-:109EE000937C95B7BA8D815CF8D2195A8F30A1C294
-:109EF000BA87347FFF15D477F350CB196B3FD39DCE
-:109F0000B55F5EDF19CAEA83188F67CF3754486799
-:109F1000E1F5ACBC5872669FDBEB5573E5256F9D90
-:109F20004D8F06A7E08F4008520378DEE1E1D2961C
-:109F300062EC8F064077E1D0FE1B2A2440B96ED533
-:109F4000C43C7F15A45C12EDA38FD4B3DFE865FE9B
-:109F5000F1FFDE4C7F9CF831ECD274C453E08FC625
-:109F60009489FD3B436EC3C4F1419A4FF6B50AFD97
-:109F70002C9DB7FF05F9A57758E7BD82708372F86D
-:109F8000B14DC2CF927DABF7BF82F00F5C29834CFD
-:109F90007BCB1B0DE2CF3B1480B252ECDFE764BFFA
-:109FA0000FFD3BBE8F5A95EBF7DD79C439E717C239
-:109FB0007C3FF0AE4DB97E606C13F0BE749EB2551E
-:109FC0007F3F7CE80BB2FE5CA14C39B40276D5C66B
-:109FD000BFF49497F1FA8372C42BAD8388F929EC0E
-:109FE000BB108FC4AFA8A8FD6B104F84439213DF42
-:109FF0009AEF7C9AE6BB4E21FFD27CD9DBFE29DCAE
-:10A00000CAB908F1C4FADFC9E730F11F3A77BE3F99
-:10A01000ECCA3BA733CF7F962D3A8C107E50FEA121
-:10A02000099A083FE89FB37F00DE60413BFF5C3F39
-:10A030006A0EE4A51FF6BBB94DF76BDC1EEF0F717E
-:10A040007BA25F877674AC5EE8AFE7F6C57E83BF20
-:10A05000BFDC1FE6D6C6C7B9F48DAFDCC1FEC2E1D6
-:10A060007B1D291226A5417BE95AC4C3956FC8AC54
-:10A070003EFCA07B14D4077EC48182F3AEEE505226
-:10A0800026DDC58A7FAEB0F86CB96B66D245FC5D43
-:10A0900009C63E5A08B1813B56CFC53F37CD38E699
-:10A0A000E40428DE299AB33340F14E594EBFCDBDAA
-:10A0B0002867FE7AAD3667DCA6EFD79A85DC6C0898
-:10A0C0002DCF997FB8BD35FD313CAFBFD9A5119FCC
-:10A0D00077EAD7E78CDF5A7F630E3C5B0E4AFB942E
-:10A0E0001CFEF3E7D155DD7DFE38C8A6F38F6C3A30
-:10A0F0005B72702EFAE6F3AD8DD7D2B37815716529
-:10A1000082E24A9DEEDD20ED0C129E6DBFC4848874
-:10A110008FF480D85709637CD978F9E34B3FC59712
-:10A12000D585E2CB7735E2DF0BC6971DB9F1653EE9
-:10A130005E2F145FFE691E3E4B1784CF1D8B63AFED
-:10A14000ADA178EF5599FD40B923C6F6AF6C4A36FC
-:10A150003620DC72CB1FF391CCE3BC1D6B54F62F81
-:10A160000F43264476FF0109B18AFC5FD660549202
-:10A17000BE793260566CA338BFD3611CC525CFB7FA
-:10A180007C39447EC7C1814742689420D8E5607D10
-:10A19000976C99DE4E72A5E8E8C749DC9AA902FEE1
-:10A1A000893DFFB3434E8E431ED8AEA6249CFF804C
-:10A1B0004FEBDD4A7D6B1F4408DBDBF135D7A4C8CC
-:10A1C000FF2BEFD205BF403C44F47F707B53251B2F
-:10A1D0002905FB2B68BAC1767CC46798248789DF80
-:10A1E00079218E9FEE9734BF44FEEB7687F638DEFA
-:10A1F00073BC63D55BBBB07FD0AB1A24F0894053EE
-:10A2000025F197BC03DD1EEC8F758CBDC8725CE731
-:10A21000E07E62FB35AF93FB3C5EAE75D6509CB7DB
-:10A22000BE86300DF233A7FB29AF91084C8768FD3D
-:10A23000E00D62FDB9E8236B59F61C387FC1E79544
-:10A240009738D22AC2919F9BFE3F822767DB71D647
-:10A25000E3B97EC54840A52001CCAE2BFF23BE84C8
-:10A2600054B969121DC751E6094F3BB67795503C6A
-:10A27000B5C399292F642F8650BFA6AFCDF237837F
-:10A28000B97E423E7CFE35117EF1E7105DBDC20A0B
-:10A290005DF097B8EDE6549AF006C98E1AB2CB5E1F
-:10A2A000B4CB709EF8CF9B8B071B3EC3C3FFC87B0C
-:10A2B0003CA6270B0F78AD34F93BBD5D12F3CD966C
-:10A2C000B37C001C77D8E7523A1CBCCED60FC8C767
-:10A2D0005B27883F2CBC87D064901CDAE7885AF053
-:10A2E00076CEC103AD22EB1C6B550B9EC171F1758F
-:10A2F000AA902BF885CC7EC73C3A59FE1BAFAF9E87
-:10A300001B57ACF35F7B44CDD1BF9FA1FD71DF5FD5
-:10A31000F6759F375E5E9ACA5D77B80BF8DCCB6442
-:10A32000F3F834C5B5D73A528F23A8E5D73A589EEB
-:10A330004FA15F4576ED5CF06CFAB388553077A19C
-:10A34000D38EFE59B08BF9FC5CEBD4D49459DD4824
-:10A35000FB426C02F96B6928F75CF6BCC367EFF54A
-:10A360001928A2F3A0434EF6C8954A9BA4A75D08FE
-:10A3700047C2B6FE917BB4F3DDDB0559F0119FEFC8
-:10A380004A425FC503C0F74DBC9562F98167667E9E
-:10A390004BF29D585AA18FB0BC40684913F923E293
-:10A3A0005ECE3C3A8D78049CB195C24F1DB3FAF154
-:10A3B00015022E64CB29AEF7587995AF77D5F2BD4B
-:10A3C00054D2334464C55C4C7CE155BE15D7901F14
-:10A3D0008ABC872180AD2BB8334EEDBAC5FA681818
-:10A3E000CF35B6D4C1766CCC177D6488F4D0526F6B
-:10A3F00041F9F81EE945843F4C7CCBF113980E924D
-:10A400003BC91612883A905EE3CCF9002F750544DB
-:10A410003E4B4B866F473C1EB7F802EFC3EBF3E1B0
-:10A420009F980FFF31E2D784059CE0EC44382F5B06
-:10A43000720164502AACB80FF773EBC930F90BAF57
-:10A440007469425E949506DD7F2C5078BF57ACFD51
-:10A450004C474CA27957F489F5E016EB1E9066B68E
-:10A460009E14F46479A2FD69BCD8C8D50FF9703D7B
-:10A47000F5B9FA4AADCA9DFF96C57FF9F1D0FD52F4
-:10A48000E173FEAF75DF758B81ED11F1C5BE027C06
-:10A49000912FEF2AE53F11EE7B4407C697D03B5E34
-:10A4A00065AA95E21E6F0318ECA328937CDF7DC597
-:10A4B000B7719C3C74ABC873A88AD0DB555B110C98
-:10A4C000DAE3C80FDAE3D497EF01CD15988F878BC5
-:10A4D0008DF7C8DEC4B3D69F26FE2817F78867DD40
-:10A4E00023E9D46FA37D930765203F20B9D7B5B585
-:10A4F00090DD862EE7593DE9B6F52ED20D8C6A70B7
-:10A50000E0FA236FC89C173812DECF717122A2EADD
-:10A510005235E5291E86BD38FE17D3C17EEB9E67F6
-:10A52000EEFDCDCBB8EC647B4D93E46039823B719A
-:10A53000FE498C8BC96F26F9CBC9C72062DD4D73EC
-:10A54000FB25DB6B78BF04EE279D47CF29118C5B81
-:10A550001BE7C33B6B8FF3F223231551BD1BEF7732
-:10A56000D86B703E52B6F3233DC105E5757448A61D
-:10A57000F7905EE903C683AF730CF6523E2124E2E6
-:10A580008CE36B5C82BFF64A567C06ED60EB29FCDF
-:10A590006DECD31F2A23FBF2A60BEA70BCF589579A
-:10A5A00015EA8F553A9A287EBE4ECD1CBA8EC69BB0
-:10A5B0009CAC3F5A9092E91CFE48BB1C213E8F6A1E
-:10A5C000B5B268D312B56DEEE21C7DBD5ECB8D3F9A
-:10A5D00046678FCB25C49F1A1812E279B4C5304B59
-:10A5E00048F7189941FA3EBA5E374674F28773E32A
-:10A5F00094D14E55E8D36A6177C626F587C8BF3A2D
-:10A60000B0C7C3FEE7FD550E71EF2590227EE8D45A
-:10A6100073E39AB1899A834B48CE924ECE977F735B
-:10A6200042CCDF35B0324571A966F9ABBB2A5BD9A4
-:10A630000F852131EFD6FAE579F79FD2882F927BEB
-:10A640009D40F83F5075FB30E543DF4938AF277137
-:10A65000F96EB7CE726AD36DE7D09D5C271A52614E
-:10A660001B9D7F74BBCAFC3F5AFECE913B484F975F
-:10A6700017319EC7B7AB95D12C7978AFDBC570C6C3
-:10A68000B70BFFA2DC01D18902E3EF750BBDF2E14C
-:10A69000BB81EF43F90E1D3FE94A2CED227C5401AA
-:10A6A000FC2B5D27F4EE97F8FE1D0EA8C3238E0544
-:10A6B000FBD87FCBE7B30FBAEB72CEEF0A3B72F059
-:10A6C000E87445629CE7BE1574D257ED1DD8A7F813
-:10A6D000BE4F05E23757E81EBE6729F63DD87777AB
-:10A6E00024E30AF6DD4BA2D793DFFAFCDE2DC32D5F
-:10A6F00041B25F0E8DF8CDD57757A49BE6AF768239
-:10A7000007C78740974274CEB804A4AF7588769087
-:10A71000BF3E16726894B7D998D8BC9BF6DF182C48
-:10A7200002A2F38E4E07EF77CA543969554E8E0652
-:10A73000E5BF2ABC6C77DF76C61EDA82F3DF467A85
-:10A74000C561EE5E8F76D7F03D3D7A6EFCEC8624D7
-:10A75000DBE1B5E6541FEDB336AC5245038E374FFF
-:10A760001F217F7D7C8DCB70E1B9C69B25C6F7FB91
-:10A770006B9C293C2AFC509D9269DF1FBE8FBC5107
-:10A780005D487ECF2F37F9F347C35D6EE287FD301A
-:10A79000D543F889CF8A3C54FEBC253D82FEFB118F
-:10A7A0002F84E7389EB78EE2A219942B841E988DD1
-:10A7B0007C837244DBBA15D61F9FAD74C4A92E7476
-:10A7C000A053653939E08B0E57531FF99DE3A16003
-:10A7D00094F979AC32C87268EF33D6DC5B4FFCF287
-:10A7E000DA1A0FFBED7D3FFBD5DDE4B7B7CA7FFC7E
-:10A7F000F653143F55A94CCF03CE48FA65E2EB4E11
-:10A80000E12F9EB8EA9F59EE86FA6E07C21BC46319
-:10A810006F52DD6A687533C3B7F30D6357897CD215
-:10A8200050F0D3F15DD84F87457EC12C3F2A01EB14
-:10A830006791576AB1F4D87257ECA53A5A77B722A4
-:10A84000EAC2725582F4816B91C8BF998A3327EEB0
-:10A85000BD6926370EBE322F0ECECF33817B6A49BB
-:10A8600037DAD39F775B79372BAF445760395EED8A
-:10A87000E278713C2CE2A0A43356A935CC97E31FB3
-:10A880005B7EF054BF1B3900E0A7FD1AF7FDE69F81
-:10A8900006CA10D41BFD21FEFE91B58F48D9EB46A8
-:10A8A000576F76EBAC373221829BAF2FF2F9E08EF7
-:10A8B000EE22E6038CD380E83B3A038C5F5FF3AA79
-:10A8C00034F1E9A9BF02C7A1FFD03EE5859AF9EBB3
-:10A8D000D3744E17E5BFC4394FD0395D94FF12E7EA
-:10A8E0007BB15FE7F6E5FE7A6E57F680C8F3DBFAD8
-:10A8F000E06AD40788B7F62AD127F9273B5C1ABC4F
-:10A900003D42FCE50A291AC9B7BB2A9996B2F4C19F
-:10A91000B82FF616D9E503E55EE6BFFC73057A1C91
-:10A92000D6BD62DB08EE28C225BC3FBFF77FBE5410
-:10A930004BFBBC21335F95F6F5EE66BD837AC1C350
-:10A94000FE86D087C9722FE71DC6F7D64921ECEFE6
-:10A9500018108EEE05E51EF749E1BAE3A8AFA97F0E
-:10A9600000E59CEE73A0F99D8FD33EEFFFAD882AE2
-:10A970007C48EF5FB0DCBF860148D965947B5BCE35
-:10A98000BEDFFDA4157F47B63C23EECF7A70DC37DF
-:10A9900095A4FB1FF8B90C85F076A9740573617E48
-:10A9A000484A99993C132C50373445DD7070E23B8E
-:10A9B000DC8F6F04A8C3FE579DA69BF8E0AB038E07
-:10A9C000F3D60DBF3A70FEBA61EA8B0E706973E779
-:10A9D000580419CEB352084F75C0211AC2B6A92720
-:10A9E0007A5B0FFBCBA2AEA83753CE81FA5A11F98E
-:10A9F000CF4F45CC8FF4909F1914F9AE9032912629
-:10AA0000BB1EA27AB94EEF17E25CF7D4280C5B3973
-:10AA1000FFFE83CE4C2BDF0FA750BD32BF3E2979FE
-:10AA2000BF27EAFBB5A20E69D7271BD5CCD143843B
-:10AA3000A76D6EC6C3E0B337BC49F52FBB8E1FB2FE
-:10AA4000EAC0DA6ED006C43D3EC6E77C4ED443E190
-:10AA500006BCC74ADA2453B36905D7373F41E31729
-:10AA60003AFF42EB861B2DFD86CC9D2279FE8D851B
-:10AA70004F7BDE80258FD7A9226F0D7E95F57CEB6D
-:10AA8000135E90C95FF6A947494E7642663DC9D329
-:10AA90006040F86D89C34EF6DBF6F5E8BCBE5C3568
-:10AAA000F9FD42F9BF788C01049398D4FC9447AA2D
-:10AAB000EB36F7F5F039923D5D748E6199F5DDDB8B
-:10AAC00075EBE3C41F9D5209CBA3A2998BB3F5E5A7
-:10AAD000A33D3539F9F84EF8A242EF5CD62D9EE938
-:10AAE000E2FD7D0EA0782BE1315ED409DF3F5018E6
-:10AAF0006E27A4DAF9BEBB346918EF39E83DC9F412
-:10AB00005957E75A49FAE951CBBE267C85E3BA7F0B
-:10AB1000EB11F1E7FA4DD187E9DCB7C04C1BE937FF
-:10AB2000146D23CEEF5A445EE751D29722AEB9D7C7
-:10AB3000D13497D77AC9197D94D699DF14FE842B26
-:10AB400024FC7A279869C2D7AB9BCCC7888F371271
-:10AB50009FAF6645058FAF9C7F8E27AC73F4F69848
-:10AB6000FF49F08E59FAB95133B9EEDA080E633065
-:10AB7000985557D717565797B4EF897AFA8D828F21
-:10AB8000E1B9B8E0C356D0489E90FF8ED1F9ECF7FA
-:10AB9000258DC7765773DDE512EBDBEF6F328F1330
-:10ABA000BC3F442227E81E6FEFDD020C6F81EF35BA
-:10ABB000D62DCE8422642F3DC26F7EB2C5D81AC96D
-:10ABC000CAFF9CB2F8F79445D7E5C84E53942F506E
-:10ABD0000CB6E3D740D84DFA211F7EA21F26A8EE5F
-:10ABE00073AEFD9D074FBA294F3C186E75D37BB4E9
-:10ABF00084B7B584FAA3556688F61FEAEF78F6DDC8
-:10AC00003AE223C1F7F166918FD88FFA39EE9A8331
-:10AC1000F3871E99CFD5168634E5D3FD5EE117F98B
-:10AC2000315ED4918FFCC130DB73FC3E41A9833F80
-:10AC3000933C51BC1D32C0A478321C05920BBF3628
-:10AC4000B79E4C5E5B380374AE73C191AB70BD9719
-:10AC5000D6C718DFE59B353E872BE4988BE361E18F
-:10AC6000F8DA4FF8AA3B4FDE8DF0D5706E7C9DC5AB
-:10AC7000BB2577F978F26D96F9DECF07A6F95E70FD
-:10AC8000BA8DF3227E547854CF2FDB2CF48CEC3524
-:10AC900021EAA37A5994EF970864C06898C32FFA01
-:10ACA0008A8C5F59CBF03A7FD880E80AC2478CF192
-:10ACB000997FFFC663DF6827BCBDB453E8D5758AAA
-:10ACC000A53F627817E4CF7FB2F41B5876A9D3234F
-:10ACD000ECCE46F88957E4B5059F36A23BEE2E9D93
-:10ACE000AF5FEDF6492BAF9CFFFDE79B3D220FA028
-:10ACF0004FB07E1FEC10F07D3EE1871E1D5EC5FE4D
-:10AD0000C3CD957545D9FAF172D709F3EB8217AA2D
-:10AD100003CEF18DC974FF8B7632BE493F377F1C5D
-:10AD2000B2E46DA8DF5D50EE0E2D8E840C92AB6602
-:10AD3000330E48B7FD814C88F86768F23DF693956D
-:10AD4000576583FC4D458900CDBBB93CC3F4DF108A
-:10AD50003681EA4A87FACD6F65C3FDECA668F766CF
-:10AD60007A27A44D9804C70BE938D9A35BCACC58FD
-:10AD7000A4001D3EBA59E4FF5EDD14D9B699F40E65
-:10AD8000E9CE55E86B45CC7FA4FE42F5D57C79EA47
-:10AD90007093BDB87479EA72D3FD46AB22FC4E6B5A
-:10ADA000F42732795873FEA5254FA3CDD3AC276C79
-:10ADB000B9FADCE63CBD13B4F44ED064B9F8FC66D5
-:10ADC000DDCA0347583E9C244FD97A2668EB199375
-:10ADD000E55109DAF264C91FC9137EBFCE39D346E3
-:10ADE0007ECA1088778CF9F235BE299A203A5C57D2
-:10ADF000FEE7EE6A7DEEFDA7AE0B791AADB2F8BDA7
-:10AE0000F969E6FF53C8FFF45878D05B93C3EF7637
-:10AE1000BB7656863492E2A65989DB7F982DE6767A
-:10AE2000DDAC875B73B68CDB96D900B7ADB38BB85E
-:10AE30006D9BADE4B67D16F9FE7AE4FFD96A6E6FBC
-:10AE40009E5DCEED86D9A5DC76CC5ECFF33A675712
-:10AE5000727BCBEC8DDCDE3ADB2CF6A19A5069419B
-:10AE6000FEA772D665E07F234EF5D1A1C9BBDF24D2
-:10AE7000FC383595F328894013D77B9C4A86F9FF27
-:10AE80006858D8870D5E419F7CFE7F7553F4DB8543
-:10AE9000F87FD009CF90CB95EF27A0BFF32CF1B965
-:10AEA000E47DE16F9CFF740A3F07FD8F63CCFF9741
-:10AEB00068FFCFFA9515B97EE56879AE5F39D46C35
-:10AEC000FB95AE14D5C176493ABF137B7F53F4C7C7
-:10AED0009B59FF4676D278B4C7AD913F9508DC1CEC
-:10AEE000F2627FC77E1928DF87FEC514CF43FD407D
-:10AEF0007663A1F29AB6DEF7DAF31BE1A4237611AA
-:10AF0000FEC9DBF4BFCD85E4BEDE734976D4D92615
-:10AF1000E45E13729FA88A0C53BE259127F7B61DD5
-:10AF2000453CE4C8FDFBB6DC5B725C1A14EF3E4A9C
-:10AF300049EE919EA7CFCA7DAE1D55ACF9CE0E51FC
-:10AF4000DF6A0B0ABDAA74087DA168B97614F905F9
-:10AF50007A0BF8137145F04D67DD77CFDA33B2AB7A
-:10AF6000A5C18054825B6B7FCDC489FD26955A961E
-:10AF7000EF7C394A68AB98CF2795362824FF0B968B
-:10AF8000A3806D474CB623F9F36C791A9AEC64BC34
-:10AF9000D8766512EF6D66D9930D9AC003DA93AB3C
-:10AFA0007A0BC8D3BAC5663452E09C2B7A85FFFE73
-:10AFB000CA4D11E12FA29F487E4AC259D80F58D1DD
-:10AFC0002BE856DA9154086FEB758895A11EECE8D2
-:10AFD00048B7510D03E579452FC2BBC9CC0C920C83
-:10AFE0000E7AC782747E94CF463AD7A5CA67D9260F
-:10AFF000AB2EB7A78CFD16BBBD10DFDBFE8ECDFFE1
-:10B00000F9F39EAC36B716C2CB915EE1AF1F1D7E41
-:10B010003A873F924AED2D865E50AF9AC665D1AB16
-:10B020000BF32B26D1CEB15E3DB75FB183E8B050B4
-:10B03000BFE2CEDEB37EC52EA2D3BA06E1571CE92D
-:10B0400085CBEB2FB4D8F1CAA5F90B9FEF3DBFBF5D
-:10B0500030D8ABF3B8827E35E90DBFA5372ED65F69
-:10B0600028E01F1CECE5387A46A6FA1FA2DA10F990
-:10B07000105117453D733FE10DE378F6178E7A05C1
-:10B08000BF988A6D9F220FD078D214FEC2E592033A
-:10B09000F4FB1EEA2D5FB83C2C745EDD636B8733D6
-:10B0A000E4E7802F49EFA607E9BD12C58FBFF689F7
-:10B0B000770400F594F7FF9CBCCC203B375EFC8501
-:10B0C000AFD1FC3D7105E8DDE083FD22FF374AF991
-:10B0D000BF6BB1EF8C7D9DC6F70FB8B4A308EF83AB
-:10B0E000227FDC813CF58167718ADE051DB3E4CDEA
-:10B0F00005DB4B0AF1D5DCF9C4FB5C7ABA7286FF3A
-:10B10000AEA34AE33CB98D1F350271843FB2C2C180
-:10B11000F591910F7FF3C8ED74EE0FBB0DAA3F714F
-:10B12000A115FB65CB429C47476F10C25979111995
-:10B130009469CAC70FD31BF5ACFA6B7023C6D159FB
-:10B140007146493892D3D721CAFB1E0E3A18EEA198
-:10B150007611171DF24EB8B502FAE5BEFEDC774A4D
-:10B16000F9ADBCE60D7E273856AF70DDE7FED54B56
-:10B170003A494E0E2EE14A3114D53922A902727C89
-:10B18000DA92631D740FE1D1D3D95552C8AED8ED10
-:10B1900060DE39642D6A92BE2EAA4E46888F8BEAF5
-:10B1A00082523C0B0FBFB4E08F48F1F43A7E8F26F9
-:10B1B000EC04C5BBF44E65A8FC2EAE47BA31DE9F49
-:10B1C000C6EF6EB44BBFC5B6AC428D163A2F6C11AC
-:10B1D000F99011672A42741959AA709D1279AA60D0
-:10B1E000DEEBF796BD2AAA1BE3F3419DC275A7FCCF
-:10B1F00079BFB2E7A949AE631CACFB779DE4EEE0F2
-:10B2000055C0F9EDFFFEE5AE270648BFF4231D9DAE
-:10B21000C4AF1DDC162DFB06E37DB451D1E81EEB57
-:10B22000E5B5035C27DA0806F927F97C50BC62898A
-:10B2300087F39D1D0EF6EFF2F9A20819758AFC340A
-:10B2400025C376C2092FB2DE1C3544DCA463B42AC0
-:10B25000FA825FEC7A53D0E2C7FC7B8D5A72B5DF7D
-:10B26000CAAB97587F8733D6F167AEF78E2E4EB3B1
-:10B270001DB9AF251DA2BAA13FE836285439D01C0C
-:10B28000E1FCF6E84A07FBADF3E0AE147A39FF3C87
-:10B29000CEE3EF09FDA888FC85BF4191C8EE7CC9CB
-:10B2A0003AC70653C8931616FE9BD613030D0F5FBD
-:10B2B000FE869CD2711F69D9EFE34E1C4F6E136F4F
-:10B2C0008B8B54912753CD9B07C8AEFDB8520629EE
-:10B2D0004C82F70983F36D1121DFF6BBEC8A1E3532
-:10B2E00027BE2F81AC3EBF53C9ED83DC77DEF76606
-:10B2F0007B7E7DF7EB27B2E0B56EC9ADB35D68FD2F
-:10B3000007FDBB5F3F817C32669C5FAE6CFA24FB1D
-:10B31000C342FF59FC65F31B8580F428F85CEB1FE2
-:10B320000C440BFA25FBB6083D79217DA4B9A23166
-:10B330005A7FF8A65C387759F2769705C7B558ABAF
-:10B34000E479D63BA7C31ED8FA74817B8D6C517902
-:10B35000FE1C3FDB7EC08B9796875BD123E2876024
-:10B360008D87EC30E2F345D21F7F0DAA7A367F0E2F
-:10B37000F972FD50DB0FF8E9162B0F575E21D1FA59
-:10B38000806EDBF1DC3C41BE1D2F72A6382F5DB410
-:10B3900054B5F50CEB830F7AEF79224EF2933EC849
-:10B3A000FE9E8AFC4BF5BC32328805E804A1DCBF66
-:10B3B00013D9B205183F65FAC4542BDEA32CA27032
-:10B3C0003D4449829126781B8BF8EF3FE877BA8994
-:10B3D000EC1C70509B6CFB24A471FE03B58AC1EF7A
-:10B3E00008C1D9FC2ED9DD2A3FD7516DB9B810BD9F
-:10B3F000ED73D17BB1DC77F017270F8F6DB1DE6570
-:10B400007BC023E461A36388F31D8E14BF85477955
-:10B41000579AAC9202D5FB4908703C48EF8224ABA6
-:10B420008E543B272770ABF56E73B7783FC37F5FB1
-:10B43000584B7F0F9AE1BF1BBC9A5EB7CA82AE24FD
-:10B4400027A7A0CA4175E2F871493AEB1F2DA2A7C0
-:10B450008E8683D62D8108B7F9E7BE0662FCBD1E35
-:10B4600092DC2E83096E1B608ADB4698E196D41528
-:10B470009DC73821EA1DABC090E9FB6A8870DB04E8
-:10B48000316EC390E4F6CB6D9FFCD64EA4C38FE61D
-:10B49000E145E0B5805CA711E8D9FBDB78FEC21678
-:10B4A0007D41723B14107993B6709AFD7AAF1EE11C
-:10B4B000B8CF19147C6DC3719E234FFCF7FA4FF976
-:10B4C0007F5FF2FF519E9355203F00000000000077
-:10B4D0000000000000000000000000180000000054
-:10B4E000000000000000004000000000000000001C
-:10B4F0000000002800000000000000000000001014
-:10B50000000000000000000000000020000000001B
-:10B51000000000000000001000000000000000001B
-:10B520000000000800000000000000000000000013
-:10B5300000000000000000000000003900000000D2
-:10B5400000000000000000380000000000000000C3
-:10B5500000000000000000000000000000000008E3
-:10B5600000000000000000000000000000000000DB
-:10B57000000000000000000C0000000000000000BF
-:10B580000000000E000000000000000000000004A9
-:10B590000000000000000000000000180000000093
-:10B5A000000000000000001C00000000000000007F
-:10B5B0000000001C0000000000000000000000135C
-:10B5C00000000000000000000000003A0000000041
-:10B5D000000000000000000100000000000000006A
-:10B5E0000000000200000000000000000000000158
-:10B5F000000000000000000000000010000000003B
-:10B6000000000000000000500000000000000000EA
-:10B610000000000000000000000000000000000327
-:10B620000000000000000000000000AB000000006F
-:10B630000000000000000008000000000000000002
-:10B640000000C00000100000000000080000C0085A
-:10B6500000100000000000020000C0000010000008
-:10B660000000001000009FB0000000000000000873
-:10B670000000C08000100000000000040000C0882E
-:10B6800000100000000000020000C0800010000058
-:10B6900000000010000091200000000000000008E1
-:10B6A00000009340000100040000000100009348E6
-:10B6B00000000000000000020000935000000000A5
-:10B6C0000000000800009354000000000000000289
-:10B6D00000009418000000000000000800009358CB
-:10B6E000000800000000000800009AB000400000C0
-:10B6F00000000040000093980008000000000008CF
-:10B70000000093D80008000000000008000094200A
-:10B7100000C8000000000098000095B000980000EC
-:10B7200000000028000095F00098000000000028AC
-:10B730000000C480054000300000054000009D204E
-:10B74000000800000000000100009D21000800002A
-:10B7500000000001000020080010000000000010A0
-:10B7600000002000000000000000000800009CD83D
-:10B77000000800000000000200009D18000000000A
-:10B7800000000001000000010000000000000000B7
-:10B79000000000090000000000000000000000029E
-:10B7A00000000000000000000000CF2000000000AA
-:10B7B000000000200000CF46000000000000000153
-:10B7C0000000600000200000000000200000730066
-:10B7D000000800000000000800009FA0000000001A
-:10B7E0000000000100009FA8000000000000000110
-:10B7F00000009F60000000000000001000009F6338
-:10B80000000000000000000100009F610000000037
-:10B810000000000100009F66000000000000000121
-:10B8200000009F67000000000000000000009F680B
-:10B83000000000000000000400009F6C00000000F9
-:10B8400000000004000000520000000000000000A2
-:10B8500000000003000000000000000000000003E2
-:10B8600000000000000000000000000500000000D3
-:10B8700000000000000000020000000000000000C6
-:10B8800000060000000000000000002000009F7083
-:10B89000000000000000000100009F900000000078
-:10B8A000000000080000005300000000000000003D
-:10B8B00000009F98000000000000000200009F9C14
-:10B8C000000000000000000100009F9D000000003B
-:10B8D000000000010000000900000000000000005E
-:10B8E0000000000100000000000000000000004413
-:10B8F0000000000000000000000000010000000047
-:10B9000000000000000000500000000000000000E7
-:10B91000000000890000000000000000000012C8C4
-:10B920000080000000000080000000010000000016
-:10B93000000000000000A000071000000000071039
-:10B9400000001AC800000000000000080000AEC09F
-:10B9500000080000000000080000AE4000080000E1
-:10B96000000000080000AE80000800000000000891
-:10B97000000020080010000000000010000020005F
-:10B9800000000000000000080000A01007100040A8
-:10B990000000004000001BF800080000000000014B
-:10B9A00000001BF9000800000000000100001AD090
-:10B9B000000000000000000100001AD80000000094
-:10B9C0000000000200001ADA00000000000000027F
-:10B9D0000000000000000000000000000000AF00B8
-:10B9E000000000000000002000001B78002800007C
-:10B9F000000000040000E000002000000000002023
-:10BA00000000F300000800000000000800001AF029
-:10BA1000000000000000010800001B3700000000CB
-:10BA20000000000100001B0F0000000000000001EA
-:10BA300000001B70000000000000000400001B74E8
-:10BA400000000000000000040000005000000000A2
-:10BA500000000000000000030000000000000000E3
-:10BA600000000005000000000000000000000006CB
-:10BA700000000000000000000000000700000000BF
-:10BA80000000000000001BC80000000000000001D2
-:10BA900000001BE80000000000000008000000514A
-:10BAA000000000000000000000001BD000000000AB
-:10BAB0000000000400001BD400000000000000048F
-:10BAC00000001BD8000000000000000400001BDC88
-:10BAD00000000000000000080000B0000018000096
-:10BAE000000000180000C0000040000000000040FE
-:10BAF0000000C00000400002000000010000C00182
-:10BB000000400002000000000000E20000200000F1
-:10BB1000000000200000E2040002000800200002F3
-:10BB20000000000000000000000000000000E20033
-:10BB300000080020000000040000F40000280000BD
-:10BB4000000000280000F540001000000000001078
-:10BB50000000F5C000200000000000200000F5C03B
-:10BB600000020020000000020000F300002000009E
-:10BB7000000000200000200800100000000000105D
-:10BB80000000200000000000000000080000110874
-:10BB90000008000000000008000011680008000014
-:10BBA00000000008000011A80008000000000008C4
-:10BBB00000001240000800000000000100001241D7
-:10BBC0000008000000000001000040000020000408
-:10BBD00000000010000059000030001800000010A4
-:10BBE0000000590800300018000000020000570053
-:10BBF00000080000000000010000570100080000DC
-:10BC000000000001000011E8000000000000000139
-:10BC1000000011F00000000000000001000011F819
-:10BC200000000000000000100000124400080000A6
-:10BC30000000000400004000002000000000002080
-:10BC40000000530000100000000000100000153834
-:10BC500000000000000000010000000300000000E0
-:10BC600000000000000000000000000000000000D4
-:10BC700000000001000000000000000000000004BF
-:10BC80000000000000000000000015080000000097
-:10BC9000000000010000152800000000000000085E
-:10BCA00000000050000000000000000000008308B9
-:10BCB0000080000000000080000000010000000083
-:10BCC000000000000000200800100000000000102C
-:10BCD00000002000000000000000000800008410A8
-:10BCE0000008000000000008000084700008000048
-:10BCF0000000000800060000046000280000046046
-:10BD000000008520000800000000000100008521DF
-:10BD1000000800000000000100000000000000001A
-:10BD20000000000000008408000000000000000186
-:10BD3000000084F40008000000000002000084F607
-:10BD40000008000000000002000085040010000050
-:10BD500000000004000087600000000000000020D8
-:10BD600000006000002000000000002000007300C0
-:10BD700000080000000000080000000300000000B0
-:10BD800000000000000000050000000000000000AE
-:10BD90000000000600000000000000000000000796
-:10BDA0000000000000000000000088080000000003
-:10BDB00000000001000088280000000000000008CA
-:10BDC000000000500000000000000000000088108B
-:10BDD00000000000000000040000881400000000C3
-:10BDE00000000004000088180000000000000004AB
-:10BDF0000000881C00000000000000080000300067
-:10BE00000040000000000008000030080040000072
-:10BE1000000000280000339001C00010000000085E
-:10BE20000000320000200000000000200000372049
-:10BE3000000000000000000800001020062000386C
-:10BE4000000000080000A00000000000000020002A
-:10BE500000003EA9000000000000000100003EC8F4
-:10BE600000000000000000020000000000000000D0
-:10BE7000000000000000600000200000000000083A
-:10BE80000000400000080000000000010000400128
-:10BE9000000800000000000100004040000800040D
-:10BEA00000000002000040600008000400000004E0
-:10BEB00000004000000800000000000400004004F2
-:10BEC00000080000000000040000404000000000E6
-:10BED00000000008000040480000000000000008CA
-:10BEE0000000800000000000000000100000504032
-:10BEF00000010004000000010000500000000000EC
-:10BF000000000020000050080010000000000004A5
-:10BF10000000500C0010000000000001000052C79B
-:10BF20000000000000000001000052C600000000F8
-:10BF30000000000100003000003000180000000484
-:10BF40000000300400300018000000040000300839
-:10BF500000300018000000020000300A0030001815
-:10BF6000000000020000300C00300018000000014A
-:10BF70000000300D00300018000000010000300EFD
-:10BF800000300018000000010000301000300018E0
-:10BF9000000000040000301400300018000000040D
-:10BFA0000000500001000080000800040000500460
-:10BFB00001000080000800040000000A00000000EA
-:10BFC0000000000000005068010000800000000137
-:10BFD0000000506901000080000000010000506C6A
-:10BFE00001000080000000020000506E010000808F
-:10BFF00000000002000050700100008000000004FA
-:10C000000000507401000080000000040000506631
-:10C010000100008000000002000050640100008068
-:10C0200000000001000050600100008000000002DC
-:10C03000000050620100008000000002000050502B
-:10C040000100008000000004000050540100008046
-:10C0500000000004000050580100008000000004AF
-:10C060000000505C01000080000000040000507CD3
-:10C0700001000080000000010000507D01000080F0
-:10C080000000000100004018001000000000000443
-:10C0900000004090001000000000000400004098E4
-:10C0A000001000000000000400004110000000002B
-:10C0B0000000000200004112000000000000000229
-:10C0C00000004114000000000000000200004116C2
-:10C0D00000000000000000020000604000080000B6
-:10C0E00000000002000060420008000000000002A2
-:10C0F00000006044000800000000000400006080B0
-:10C100000008000000000008000060C000400008B7
-:10C1100000000008000060000008000000000002AD
-:10C120000000600200080000000000010000600440
-:10C13000000800000000000200006340000800004A
-:10C1400000000008000063800008000000000004F8
-:10C15000000063840008000000000001000063C0CC
-:10C160000008000000000002000063C40008000096
-:10C17000000000020000640000080000000000044D
-:10C1800000007000001000000000000400007004B7
-:10C190000010000000000004000070080010000003
-:10C1A00000000004000090000008000000000002F1
-:10C1B0000000900200080000000000010000900450
-:10C1C000000800000000000200009040000800008D
-:10C1D000000000020000904400080000000000027F
-:10C1E0000000904600080000000000020000964891
-:10C1F0000008000000000008000090800008000017
-:10C20000000000020000908400080000000000020E
-:10C210000000968800080000000000080000804030
-:10C22000000800000000000100008041000800003C
-:10C230000000000100008042000800000000000132
-:10C2400000008043000800000000000100008000A2
-:10C25000000800000000000200008002000800004A
-:10C26000000000010000800400080000000000023F
-:10C27000000080C00008000000000002000080C232
-:10C280000008000000000002000080C40008000058
-:10C290000000000200008080000800000000000193
-:10C2A0000000808100080000000000010000808282
-:10C2B000000800000000000100008083000800006A
-:10C2C0000000000100008084000800000000000160
-:10C2D000000080850008000000000001000080864A
-:10C2E00000080000000000010000600000080000DD
-:10C2F00000000002000060020008000000000001D1
-:10C30000000060040008000000000002000060421D
-:10C3100000C00018000000020000604000C00018CB
-:10C32000000000020000604C00C00018000000087F
-:10C330000000604400C000180000000800006057C2
-:10C3400000C00018000000010000605400C0001888
-:10C35000000000020000605600C00018000000014C
-:10C360000000664000080000000000080000668031
-:10C370000008000000000008000066C0000800007F
-:10C38000000000080000DA4200180000000000026F
-:10C390000000DE4000000000000000000000E0009F
-:10C3A00000000000000000040000D0C000000000F9
-:10C3B000000000040000D0C40000000000000004E1
-:10C3C0000000D0C800000000000000040000D0CC35
-:10C3D00000000000000000040000D0D000000000B9
-:10C3E000000000040000D0D40000000000000004A1
-:10C3F0000000D0D800000000000000040000D0C001
-:10C4000000000000000000200000DB000000000031
-:10C41000000000040000DB000000000000000068D5
-:10C420000000B94800000000000000000000D0003B
-:10C4300000000000000000040000B0C00000000088
-:10C44000000000040000B0C4000000000000000470
-:10C450000000B0C800000000000000040000B0C0F0
-:10C4600000000000000000100000D6B00000000036
-:10C47000000000040000D6B400000000000000042A
-:10C480000000D6B800000000000000040000D6BC88
-:10C4900000000000000000040000D6B00000000012
-:10C4A000000000100000D348000000000000000859
-:10C4B0000000D358000000000000008000000010C1
-:10C4C00000000000000000000000D3580000000041
-:10C4D000000000080000000006002200000000002C
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex
new file mode 100644
index 000000000000..aef9aa622420
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex
@@ -0,0 +1,15456 @@
+:1000000000005310000000680000070C000053803F
+:100010000000318000005A90000000B000008C18F1
+:100020000000C13400008CD0000000D800014E0850
+:100030000000F1F000014EE800000074000240E012
+:100040000000525C00024158000000B8000293B862
+:100050000001213C0002947800000FFC0003B5B8B9
+:10006000000000040003C5B8020400480000000FAF
+:1000700002040054000000450204005C0000000679
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040258000000360204025C000000365F
+:10017000020402600810000002040264081000007B
+:1001800002040004000000FF02040008000000FF59
+:100190000204000C000000FF02040010000000FF39
+:1001A000020400140000007F02040018000000FF99
+:1001B0000204001C000000FF02040020000000FFF9
+:1001C000020400240000003E020400280000000099
+:1001D0000204002C0000003F020400300000003F39
+:1001E000020400340000003F020400380000003F19
+:1001F0000204003C0000003F020400400000003FF9
+:10020000020400440000003F020404CC000000018E
+:1002100002042008000002110204200C0000020069
+:10022000020420100000020402042014000002193D
+:100230000204201C0000FFFF020420200000FFFF3A
+:10024000020420240000FFFF020420280000FFFF1A
+:1002500002042038000000200604203C0000000FAB
+:1002600002042078000000210604207C0000000F1A
+:10027000020420B800000001060420BC0000000FAA
+:10028000020420F800000001060420FC0000003FEA
+:10029000020421F800000001060421FC0000000F08
+:1002A0000204223807FFFFFF0204223C0000007F07
+:1002B0000204224007FFFFFF020422440000003F27
+:1002C00001042248000000000104224C000000004C
+:1002D000010422500000000001042254000000002C
+:1002E00001042258000000000104225C000000000C
+:1002F00001042260000000000104226400000000EC
+:1003000001042268000000000104226C00000000CB
+:1003100001042270000000000104227400000000AB
+:1003200001042278000000000104227C000000008B
+:10033000020422C00000FFFF020422C40000FFFFED
+:10034000020422C80000FFFF020422CC0000FFFFCD
+:100350000C042000000003E80A0420000000000153
+:100360000B042000000000030605400000000D0003
+:100370000205004400000020020500480000003291
+:1003800002050090021500200205009402150020CD
+:1003900002050098000000300205009C08100000D3
+:1003A000020500A000000036020500A40000003095
+:1003B000020500A800000031020500B000000004A2
+:1003C000020500B400000005020500C000000000A6
+:1003D000020500C400000004020500D40000000172
+:1003E00002050114000000010205011C00000001CB
+:1003F00002050120000000020205020400000001C5
+:100400000205020C0000004002050210000000403E
+:100410000205021C00000020020502200000001C52
+:100420000205022400000020060502400000000A28
+:1004300004050280002000000205005000000007B3
+:1004400002050054000000070205005800000000EB
+:100450000205005C000000080205006000000001C9
+:100460000605006400000003020500D80000000635
+:100470000205000400000001020500080000000160
+:100480000205000C00000001020500100000000140
+:100490000205001400000001020500180000000120
+:1004A0000205001C00000001020500200000000100
+:1004B00002050024000000010205002800000001E0
+:1004C0000205002C000000010205003000000001C0
+:1004D00002050034000000010205003800000001A0
+:1004E0000205003C00000001020500400000000180
+:1004F000020500E00000000D020500E80000000019
+:10050000020500F000000000020500F800000000F5
+:10051000020500E40000002D020500EC00000020B0
+:10052000020500F400000020020500FC000000208D
+:10053000020500E00000001D020500E800000010B8
+:10054000020500F000000010020500F80000001095
+:10055000020500E40000003D020500EC0000003050
+:10056000020500F400000030020500FC000000302D
+:10057000020500E00000004D020500E80000004018
+:10058000020500F000000040020500F800000040F5
+:10059000020500E40000006D020500EC00000060B0
+:1005A000020500F400000060020500FC000000608D
+:1005B000020500E00000005D020500E800000050B8
+:1005C000020500F000000050020500F80000005095
+:1005D000020500E40000007D020500EC0000007050
+:1005E000020500F400000070020500FC000000702D
+:1005F0000406100002000020020600DC00000001DA
+:100600000406020000030220020600DC00000000D5
+:100610000718040000AD0000081807D800050223E1
+:10062000071C000029920000071C8000312A0A657F
+:10063000071D000034A316B0071D80002E7A23D9B1
+:10064000071E000003502F78081E07F03F02022506
+:10065000021800BC0000003001180000000000007B
+:10066000011800040000000001180008000000004C
+:100670000118000C0000000001180010000000002C
+:100680000118001400000000021800200000000102
+:1006900002180024000000020218002800000003D5
+:1006A0000218002C000000000218003000000004B6
+:1006B0000218003400000001021800380000000099
+:1006C0000218003C00000001021800400000000475
+:1006D0000218004400000000021800480000000159
+:1006E0000218004C00000003021800500000000037
+:1006F0000218005400000001021800580000000415
+:100700000218005C000000000218006000000001F8
+:1007100002180064000000030218006800000000D6
+:100720000218006C000000010218007000000004B4
+:100730000218007400000000021800780000000495
+:100740000218007C00000003061800800000000270
+:10075000021800A400007FFF021800A8000003FF99
+:1007600002180224000000000218023400000000F9
+:100770000218024C00000000021802E4000000FF12
+:100780000618100000000400021B8BC000000001CE
+:10079000021B800000000034021B80400000001893
+:1007A000021B80800000000C021B80C000000020A3
+:1007B0000C1B8300000864700A1B830000000157B3
+:1007C0000B1B83000000055F0A1B83400000000034
+:1007D0000C1B8340000002260B1B8340000000011D
+:1007E000021B838000086470021B83C00000022685
+:1007F000021B1480000000010A1B1480000000008E
+:10080000021B944000000001061B944800000002F7
+:10081000061A1000000002B3041A1ACC00010227C5
+:10082000061A1AD000000008061A2008000000C8A6
+:10083000061A200000000002041A1BF8009002288B
+:10084000061A371800000004061A371000000002CC
+:10085000061A500000000002061A500800000004AA
+:10086000061A501800000004061A50280000000460
+:10087000061A503800000004061A50480000000410
+:10088000061A505800000004061A506800000004C0
+:10089000061A507800000002041A52C0000202B882
+:1008A000061A405000000006041A4068000202BA0E
+:1008B000041A4040000402BC041A8000000102C077
+:1008C000061A800400000003041A8010000102C10F
+:1008D000061A801400000003041A8020000102C2DE
+:1008E000061A802400000003041A8030000102C3AD
+:1008F000061A803400000003041A8040000102C47C
+:10090000061A804400000003041A8050000102C54A
+:10091000061A805400000003041A8060000102C619
+:10092000061A806400000003041A8070000102C7E8
+:10093000061A807400000003041A8080000102C8B7
+:10094000061A808400000003041A8090000102C986
+:10095000061A809400000003041A80A0000102CA55
+:10096000061A80A400000003041A80B0000102CB24
+:10097000061A80B400000003041A80C0000102CCF3
+:10098000061A80C400000003041A80D0000102CDC2
+:10099000061A80D400000003041A80E0000102CE91
+:1009A000061A80E400000003041A80F0000102CF60
+:1009B000061A80F400000003041A8100000102D02E
+:1009C000061A810400000003041A8110000102D1FC
+:1009D000061A811400000003041A8120000102D2CB
+:1009E000061A812400000003041A8130000102D39A
+:1009F000061A813400000003041A8140000102D469
+:100A0000061A814400000003041A8150000102D537
+:100A1000061A815400000003041A8160000102D606
+:100A2000061A816400000003041A8170000102D7D5
+:100A3000061A817400000003041A8180000102D8A4
+:100A4000061A818400000003041A8190000102D973
+:100A5000061A819400000003041A81A0000102DA42
+:100A6000061A81A400000003041A81B0000102DB11
+:100A7000061A81B400000003041A81C0000102DCE0
+:100A8000061A81C400000003041A81D0000102DDAF
+:100A9000061A81D400000003041A81E0000102DE7E
+:100AA000061A81E400000003041A81F0000102DF4D
+:100AB000061A81F400000003041A8200000102E01B
+:100AC000061A820400000003041A8210000102E1E9
+:100AD000061A821400000003041A8220000102E2B8
+:100AE000061A822400000003041A8230000102E387
+:100AF000061A823400000003041A8240000102E456
+:100B0000061A824400000003041A8250000102E524
+:100B1000061A825400000003041A8260000102E6F3
+:100B2000061A826400000003041A8270000102E7C2
+:100B3000061A827400000003041A8280000102E891
+:100B4000061A828400000003041A8290000102E960
+:100B5000061A829400000003041A82A0000102EA2F
+:100B6000061A82A400000003041A82B0000102EBFE
+:100B7000061A82B400000003041A82C0000102ECCD
+:100B8000061A82C400000003041A82D0000102ED9C
+:100B9000061A82D400000003041A82E0000102EE6B
+:100BA000061A82E400000003041A82F0000102EF3A
+:100BB000061A82F400000003041A8300000102F008
+:100BC000061A830400000003041A8310000102F1D6
+:100BD000061A831400000003041A8320000102F2A5
+:100BE000061A832400000003041A8330000102F374
+:100BF000061A833400000003041A8340000102F443
+:100C0000061A834400000003041A8350000102F511
+:100C1000061A835400000003041A8360000102F6E0
+:100C2000061A836400000003041A8370000102F7AF
+:100C3000061A837400000003041A8380000102F87E
+:100C4000061A838400000003041A8390000102F94D
+:100C5000061A839400000003041A83A0000102FA1C
+:100C6000061A83A400000003041A83B0000102FBEB
+:100C7000061A83B400000003041A83C0000102FCBA
+:100C8000061A83C400000003041A83D0000102FD89
+:100C9000061A83D400000003041A83E0000102FE58
+:100CA000061A83E400000003041A83F0000102FF27
+:100CB000061A83F400000003041A840000010300F4
+:100CC000061A840400000003041A841000010301C2
+:100CD000061A841400000003041A84200001030291
+:100CE000061A842400000003041A84300001030360
+:100CF000061A843400000003041A8440000103042F
+:100D0000061A844400000003041A845000010305FD
+:100D1000061A845400000003041A846000010306CC
+:100D2000061A846400000003041A8470000103079B
+:100D3000061A847400000003041A8480000103086A
+:100D4000061A848400000003041A84900001030939
+:100D5000061A849400000003041A84A00001030A08
+:100D6000061A84A400000003041A84B00001030BD7
+:100D7000061A84B400000003041A84C00001030CA6
+:100D8000061A84C400000003041A84D00001030D75
+:100D9000061A84D400000003041A84E00001030E44
+:100DA000061A84E400000003041A84F00001030F13
+:100DB000061A84F400000003041A850000010310E1
+:100DC000061A850400000003041A851000010311AF
+:100DD000061A851400000003041A8520000103127E
+:100DE000061A852400000003041A8530000103134D
+:100DF000061A853400000003041A8540000103141C
+:100E0000061A854400000003041A855000010315EA
+:100E1000061A855400000003041A856000010316B9
+:100E2000061A856400000003041A85700001031788
+:100E3000061A857400000003041A85800001031857
+:100E4000061A858400000003041A85900001031926
+:100E5000061A859400000003041A85A00001031AF5
+:100E6000061A85A400000003041A85B00001031BC4
+:100E7000061A85B400000003041A85C00001031C93
+:100E8000061A85C400000003041A85D00001031D62
+:100E9000061A85D400000003041A85E00001031E31
+:100EA000061A85E400000003041A85F00001031F00
+:100EB000061A85F400000003041A860000010320CE
+:100EC000061A860400000003041A8610000103219C
+:100ED000061A861400000003041A8620000103226B
+:100EE000061A862400000003041A8630000103233A
+:100EF000061A863400000003041A86400001032409
+:100F0000061A864400000003041A865000010325D7
+:100F1000061A865400000003041A866000010326A6
+:100F2000061A866400000003041A86700001032775
+:100F3000061A867400000003041A86800001032844
+:100F4000061A868400000003041A86900001032913
+:100F5000061A869400000003041A86A00001032AE2
+:100F6000061A86A400000003041A86B00001032BB1
+:100F7000061A86B400000003041A86C00001032C80
+:100F8000061A86C400000003041A86D00001032D4F
+:100F9000061A86D400000003041A86E00001032E1E
+:100FA000061A86E400000003041A86F00001032FED
+:100FB000061A86F400000003041A870000010330BB
+:100FC000061A870400000003041A87100001033189
+:100FD000061A871400000003041A87200001033258
+:100FE000061A872400000003041A87300001033327
+:100FF000061A873400000003041A874000010334F6
+:10100000061A874400000003041A875000010335C4
+:10101000061A875400000003041A87600001033693
+:10102000061A876400000003041A87700001033762
+:10103000061A877400000003041A87800001033831
+:10104000061A878400000003041A87900001033900
+:10105000061A879400000003041A87A00001033ACF
+:10106000061A87A400000003041A87B00001033B9E
+:10107000061A87B400000003041A87C00001033C6D
+:10108000061A87C400000003041A87D00001033D3C
+:10109000061A87D400000003041A87E00001033E0B
+:1010A000061A87E400000003041A87F00001033FDA
+:1010B000061A87F400000003041A880000010340A8
+:1010C000061A880400000003041A88100001034176
+:1010D000061A881400000003041A88200001034245
+:1010E000061A882400000003041A88300001034314
+:1010F000061A883400000003041A884000010344E3
+:10110000061A884400000003041A885000010345B1
+:10111000061A885400000003041A88600001034680
+:10112000061A886400000003041A8870000103474F
+:10113000061A887400000003041A8880000103481E
+:10114000061A888400000003041A889000010349ED
+:10115000061A889400000003041A88A00001034ABC
+:10116000061A88A400000003041A88B00001034B8B
+:10117000061A88B400000003041A88C00001034C5A
+:10118000061A88C400000003041A88D00001034D29
+:10119000061A88D400000003041A88E00001034EF8
+:1011A000061A88E400000003041A88F00001034FC7
+:1011B000061A88F400000003041A89000001035095
+:1011C000061A890400000003041A89100001035163
+:1011D000061A891400000003041A89200001035232
+:1011E000061A892400000003041A89300001035301
+:1011F000061A893400000003041A894000010354D0
+:10120000061A894400000003041A8950000103559E
+:10121000061A895400000003041A8960000103566D
+:10122000061A896400000003041A8970000103573C
+:10123000061A897400000003041A8980000103580B
+:10124000061A898400000003041A899000010359DA
+:10125000061A899400000003041A89A00001035AA9
+:10126000061A89A400000003041A89B00001035B78
+:10127000061A89B400000003041A89C00001035C47
+:10128000061A89C400000003041A89D00001035D16
+:10129000061A89D400000003041A89E00001035EE5
+:1012A000061A89E400000003041A89F00001035FB4
+:1012B000061A89F400000003041A8A000001036082
+:1012C000061A8A0400000003041A8A100001036150
+:1012D000061A8A1400000003041A8A20000103621F
+:1012E000061A8A2400000003041A8A3000010363EE
+:1012F000061A8A3400000003041A8A4000010364BD
+:10130000061A8A4400000003041A8A50000103658B
+:10131000061A8A5400000003041A8A60000103665A
+:10132000061A8A6400000003041A8A700001036729
+:10133000061A8A7400000003041A8A8000010368F8
+:10134000061A8A8400000003041A8A9000010369C7
+:10135000061A8A9400000003041A8AA00001036A96
+:10136000061A8AA400000003041A8AB00001036B65
+:10137000061A8AB400000003041A8AC00001036C34
+:10138000061A8AC400000003041A8AD00001036D03
+:10139000061A8AD400000003041A8AE00001036ED2
+:1013A000061A8AE400000003041A8AF00001036FA1
+:1013B000061A8AF400000003041A8B00000103706F
+:1013C000061A8B0400000003041A8B10000103713D
+:1013D000061A8B1400000003041A8B20000103720C
+:1013E000061A8B2400000003041A8B3000010373DB
+:1013F000061A8B3400000003041A8B4000010374AA
+:10140000061A8B4400000003041A8B500001037578
+:10141000061A8B5400000003041A8B600001037647
+:10142000061A8B6400000003041A8B700001037716
+:10143000061A8B7400000003041A8B8000010378E5
+:10144000061A8B8400000003041A8B9000010379B4
+:10145000061A8B9400000003041A8BA00001037A83
+:10146000061A8BA400000003041A8BB00001037B52
+:10147000061A8BB400000003041A8BC00001037C21
+:10148000061A8BC400000003041A8BD00001037DF0
+:10149000061A8BD400000003041A8BE00001037EBF
+:1014A000061A8BE400000003041A8BF00001037F8E
+:1014B000061A8BF400000003041A8C00000103805C
+:1014C000061A8C0400000003041A8C10000103812A
+:1014D000061A8C1400000003041A8C2000010382F9
+:1014E000061A8C2400000003041A8C3000010383C8
+:1014F000061A8C3400000003041A8C400001038497
+:10150000061A8C4400000003041A8C500001038565
+:10151000061A8C5400000003041A8C600001038634
+:10152000061A8C6400000003041A8C700001038703
+:10153000061A8C7400000003041A8C8000010388D2
+:10154000061A8C8400000003041A8C9000010389A1
+:10155000061A8C9400000003041A8CA00001038A70
+:10156000061A8CA400000003041A8CB00001038B3F
+:10157000061A8CB400000003041A8CC00001038C0E
+:10158000061A8CC400000003041A8CD00001038DDD
+:10159000061A8CD400000003041A8CE00001038EAC
+:1015A000061A8CE400000003041A8CF00001038F7B
+:1015B000061A8CF400000003041A8D000001039049
+:1015C000061A8D0400000003041A8D100001039117
+:1015D000061A8D1400000003041A8D2000010392E6
+:1015E000061A8D2400000003041A8D3000010393B5
+:1015F000061A8D3400000003041A8D400001039484
+:10160000061A8D4400000003041A8D500001039552
+:10161000061A8D5400000003041A8D600001039621
+:10162000061A8D6400000003041A8D7000010397F0
+:10163000061A8D7400000003041A8D8000010398BF
+:10164000061A8D8400000003041A8D90000103998E
+:10165000061A8D9400000003041A8DA00001039A5D
+:10166000061A8DA400000003041A8DB00001039B2C
+:10167000061A8DB400000003041A8DC00001039CFB
+:10168000061A8DC400000003041A8DD00001039DCA
+:10169000061A8DD400000003041A8DE00001039E99
+:1016A000061A8DE400000003041A8DF00001039F68
+:1016B000061A8DF400000003041A8E00000103A036
+:1016C000061A8E0400000003041A8E10000103A104
+:1016D000061A8E1400000003041A8E20000103A2D3
+:1016E000061A8E2400000003041A8E30000103A3A2
+:1016F000061A8E3400000003041A8E40000103A471
+:10170000061A8E4400000003041A8E50000103A53F
+:10171000061A8E5400000003041A8E60000103A60E
+:10172000061A8E6400000003041A8E70000103A7DD
+:10173000061A8E7400000003041A8E80000103A8AC
+:10174000061A8E8400000003041A8E90000103A97B
+:10175000061A8E9400000003041A8EA0000103AA4A
+:10176000061A8EA400000003041A8EB0000103AB19
+:10177000061A8EB400000003041A8EC0000103ACE8
+:10178000061A8EC400000003041A8ED0000103ADB7
+:10179000061A8ED400000003041A8EE0000103AE86
+:1017A000061A8EE400000003041A8EF0000103AF55
+:1017B000061A8EF400000003041A8F00000103B023
+:1017C000061A8F0400000003041A8F10000103B1F1
+:1017D000061A8F1400000003041A8F20000103B2C0
+:1017E000061A8F2400000003041A8F30000103B38F
+:1017F000061A8F3400000003041A8F40000103B45E
+:10180000061A8F4400000003041A8F50000103B52C
+:10181000061A8F5400000003041A8F60000103B6FB
+:10182000061A8F6400000003041A8F70000103B7CA
+:10183000061A8F7400000003041A8F80000103B899
+:10184000061A8F8400000003041A8F90000103B968
+:10185000061A8F9400000003041A8FA0000103BA37
+:10186000061A8FA400000003041A8FB0000103BB06
+:10187000061A8FB400000003041A8FC0000103BCD5
+:10188000061A8FC400000003041A8FD0000103BDA4
+:10189000061A8FD400000003041A8FE0000103BE73
+:1018A000061A8FE400000007041A62C0002003BF7C
+:1018B000061A1AF000000042061AAF0000000008E5
+:1018C000061AE00000000540061AD0000000007271
+:1018D000061AD24800000010061AD6B000000020F8
+:1018E000061AD47000000090061AD46800000002A6
+:1018F000061AA000000001C4061A30000000001003
+:10190000061A308000000010061A31000000001096
+:10191000061A318000000010061A33000000001281
+:10192000061A339000000070061AD4580000000216
+:10193000061AD34800000002061AD35800000020FF
+:10194000061AA710000001C4061A3040000000105B
+:10195000061A30C000000010061A314000000010C6
+:10196000061A31C000000010061A334800000012A9
+:10197000061A355000000070061AD46000000002FC
+:10198000061AD35000000002061AD3D80000002027
+:10199000021AAE2000000000061A500000000002EB
+:1019A000061A508000000012041A4000000203DFF3
+:1019B000041A63C0000203E1061A7000000000046C
+:1019C000061A320000000008021AAE2400000000CF
+:1019D000061A501000000002061A50C8000000123B
+:1019E000041A4008000203E3041A63C8000203E576
+:1019F000061A701000000004061A322000000008C9
+:101A0000021AAE2800000000061A50200000000252
+:101A1000061A511000000012041A4010000203E7D9
+:101A2000041A63D0000203E9061A702000000004C3
+:101A3000061A324000000008021AAE2C0000000016
+:101A4000061A503000000002061A51580000001219
+:101A5000041A4018000203EB041A63D8000203EDD5
+:101A6000061A703000000004061A326000000008F8
+:101A7000021AAE3000000000061A504000000002BA
+:101A8000061A51A000000012041A4020000203EFC1
+:101A9000041A63E0000203F1061A7040000000041B
+:101AA000061A328000000008021AAE34000000005E
+:101AB000061A505000000002061A51E800000012F9
+:101AC000041A4028000203F3041A63E8000203F535
+:101AD000061A705000000004061A32A00000000828
+:101AE000021AAE3800000000061A50600000000222
+:101AF000061A523000000012041A4030000203F7A8
+:101B0000041A63F0000203F9061A70600000000472
+:101B1000061A32C000000008021AAE3C00000000A5
+:101B2000061A507000000002061A527800000012D7
+:101B3000041A4038000203FB041A63F8000203FD94
+:101B4000061A707000000004061A32E00000000857
+:101B50000200A2A4000002090200A270000000001E
+:101B60000200A274000000000200A2700000000049
+:101B70000200A274000000000200A2700000000039
+:101B80000200A274000000000200A2700000000029
+:101B90000200A27400000000020100B40000000175
+:101BA000020100B800000001020100CC00000001A9
+:101BB000020100D000000001020100DC0000000171
+:101BC0000201010000000001020101040000000107
+:101BD0000201007C003000000201008400000028A7
+:101BE0000201008C0000000002010130000000042E
+:101BF0000201025C00000001020103280000000055
+:101C0000020160580000FFFF020160700000000741
+:101C10000201055400000030020100C40000000170
+:101C2000020100F800000001020100F000000001C4
+:101C3000020100800030000002010088000000283E
+:101C400002010090000000000201013400000004C5
+:101C5000020102DC000000010201032C0000000070
+:101C60000201605C0000FFFF0201607400000007D9
+:101C70000201056400000030020100C800000001FC
+:101C8000020100FC00000001020100F4000000015C
+:101C9000020C100000000028020C200800000211B5
+:101CA000020C200C00000200020C201000000204B4
+:101CB000020C201C0000FFFF020C20200000FFFF90
+:101CC000020C20240000FFFF020C20280000FFFF70
+:101CD000020C203800000000020C203C00000037FD
+:101CE000020C204000000021020C204400000020D3
+:101CF000060C20480000001D020C20BC0000000162
+:101D0000060C20C00000003F020C21BC00000001B6
+:101D1000020C21C000000001020C21C400000001DF
+:101D2000060C21C80000001C020C223807FFFFFF30
+:101D3000020C223C0000007F020C224007FFFFFF44
+:101D4000020C22440000003F010C22480000000069
+:101D5000010C224C00000000010C22500000000089
+:101D6000010C225400000000010C22580000000069
+:101D7000010C225C00000000010C22600000000049
+:101D8000010C226400000000010C22680000000029
+:101D9000010C226C00000000010C22700000000009
+:101DA000010C227400000000010C227800000000E9
+:101DB000010C227C00000000020C22D80000FFFF72
+:101DC000020C22DC0000FFFF020C22E00000FFFFFB
+:101DD000020C22E40000FFFF0C0C2000000003E8CE
+:101DE0000A0C2000000000010B0C20000000000382
+:101DF000020C400800001011020C400C0000100002
+:101E0000020C401000001004020C401400001021CD
+:101E1000020C401C0000FFFF020C40200000FFFFEE
+:101E2000020C40240000FFFF020C40280000FFFFCE
+:101E3000020C403800000046020C403C0000000C40
+:101E4000060C404000000002020C40480000001850
+:101E5000020C404C000000F0060C40500000001F37
+:101E6000020C40CC00000001060C40D00000003AFB
+:101E7000020C41B800000001060C41BC0000000348
+:101E8000020C41C800000001020C41CC000000011E
+:101E9000060C41D00000001A020C423807FFFFFF79
+:101EA000020C423C0000007F020C424007FFFFFF93
+:101EB000020C42440000003F010C424800000000B8
+:101EC000010C424C00000000010C425000000000D8
+:101ED000010C425400000000010C425800000000B8
+:101EE000010C425C00000000010C42600000000098
+:101EF000010C426400000000010C42680000000078
+:101F0000010C426C00000000010C42700000000057
+:101F1000010C427400000000010C42780000000037
+:101F2000010C427C00000000010C42800000000017
+:101F3000020C42D80000FFFF020C42DC0000FFFF51
+:101F4000020C42E00000FFFF020C42E40000FFFF31
+:101F50000C0C4000000003E80A0C400000000001E7
+:101F60000B0C400000000003060D400000000A00BA
+:101F7000020D004400000032020D008C021500200A
+:101F8000020D009002150020020D009408100000C0
+:101F9000020D009800000036020D00A000000000B5
+:101FA000020D00A400000004020D00A800000004BF
+:101FB000060D00AC00000002020D00B80000000297
+:101FC000020D00C000000001020D00C80000000268
+:101FD000020D00CC00000002020D015C00000001B7
+:101FE000020D016400000001020D01680000000202
+:101FF000020D020400000001020D020C000000208E
+:10200000020D021000000040020D0214000000400A
+:10201000020D022000000003020D0224000000183F
+:10202000060D028000000012040D0300001803FFDB
+:10203000060D03600000000C020D004C00000001C2
+:10204000020D005000000002020D005400000000CC
+:10205000020D005800000008060D005C000000049E
+:10206000020D00C400000004020D00040000000185
+:10207000020D000800000001020D000C000000012C
+:10208000020D001000000001020D0014000000010C
+:10209000020D001800000001020D001C00000001EC
+:1020A000020D002000000001020D002400000001CC
+:1020B000020D002800000001020D002C00000001AC
+:1020C000020D003000000001020D0034000000018C
+:1020D000020D003800000001020D003C000000016C
+:1020E000020D011400000009020D011C0000000A8D
+:1020F000020D012400000000020D012C0000000070
+:10210000020D013400000000020D013C0000000B34
+:10211000020D014400000000020D0118000000291A
+:10212000020D01200000002A020D012800000020FD
+:10213000020D013000000020020D013800000020D7
+:10214000020D01400000002B020D0148000000209C
+:10215000020D011400000019020D011C0000001AFC
+:10216000020D012400000010020D012C00000010DF
+:10217000020D013400000010020D013C0000001BA4
+:10218000020D014400000010020D0118000000398A
+:10219000020D01200000003A020D0128000000306D
+:1021A000020D013000000030020D01380000003047
+:1021B000020D01400000003B020D0148000000300C
+:1021C000020D011400000049020D011C0000004A2C
+:1021D000020D012400000040020D012C000000400F
+:1021E000020D013400000040020D013C0000004BD4
+:1021F000020D014400000040020D011800000069BA
+:10220000020D01200000006A020D0128000000609C
+:10221000020D013000000060020D01380000006076
+:10222000020D01400000006B020D0148000000603B
+:10223000020D011400000059020D011C0000005A9B
+:10224000020D012400000050020D012C000000507E
+:10225000020D013400000050020D013C0000005B43
+:10226000020D014400000050020D01180000007929
+:10227000020D01200000007A020D0128000000700C
+:10228000020D013000000070020D013800000070E6
+:10229000020D01400000007B020D014800000070AB
+:1022A000060E200000000800020E004C0000003264
+:1022B000020E009402150020020E00980215002064
+:1022C000020E009C00000030020E00A0081000006A
+:1022D000020E00A400000036020E00A8000000302C
+:1022E000020E00AC00000031020E00B4000000033A
+:1022F000020E00B800000000020E00C40000000042
+:10230000020E00CC00000006020E00D80000000102
+:10231000020E014400000001020E014C0000000109
+:10232000020E015000000002020E02040000000133
+:10233000020E020C00000040020E021000000040DD
+:10234000020E021C00000004020E02200000002009
+:10235000020E02240000000E020E02280000001BE4
+:10236000060E030000000012040E0280001B04177A
+:10237000060E02EC00000005020E00540000000CE6
+:10238000020E00580000000C020E005C000000006D
+:10239000020E006000000010020E00640000001039
+:1023A000060E006800000003020E00DC00000003BF
+:1023B000020E000400000001020E000800000001EF
+:1023C000020E000C00000001020E001000000001CF
+:1023D000020E001400000001020E001800000001AF
+:1023E000020E001C00000001020E0020000000018F
+:1023F000020E002400000001020E0028000000016F
+:10240000020E002C00000001020E0030000000014E
+:10241000020E003400000001020E0038000000012E
+:10242000020E003C00000001020E0040000000010E
+:10243000020E004400000001020E01100000000F17
+:10244000020E011800000000020E01200000000032
+:10245000020E012800000000020E01140000002FEF
+:10246000020E011C00000020020E012400000020CA
+:10247000020E012C00000020020E01100000001FBF
+:10248000020E011800000010020E012000000010D2
+:10249000020E012800000010020E01140000003F8F
+:1024A000020E011C00000030020E0124000000306A
+:1024B000020E012C00000030020E01100000004F3F
+:1024C000020E011800000040020E01200000004032
+:1024D000020E012800000040020E01140000006FEF
+:1024E000020E011C00000060020E012400000060CA
+:1024F000020E012C00000060020E01100000005FBF
+:10250000020E011800000050020E012000000050D1
+:10251000020E012800000050020E01140000007F8E
+:10252000020E011C00000070020E01240000007069
+:10253000020E012C000000700730040000D60000DD
+:10254000083007D80005043207340000322A0000A2
+:102550000734800031300C8B0735000038D018D894
+:10256000073580002F82270D07360000263632EE11
+:102570000836710031E00434023000BC0000003045
+:1025800001300000000000000130000400000000E5
+:1025900001300008000000000130000C00000000C5
+:1025A00001300010000000000130001400000000A5
+:1025B0000230002000000001023000240000000270
+:1025C00002300028000000030230002C0000000050
+:1025D000023000300000000402300034000000012E
+:1025E00002300038000000000230003C0000000112
+:1025F00002300040000000040230004400000000EF
+:1026000002300048000000010230004C00000003CE
+:1026100002300050000000000230005400000001B1
+:1026200002300058000000040230005C000000008E
+:10263000023000600000000102300064000000036E
+:1026400002300068000000000230006C0000000151
+:10265000023000700000000402300074000000002E
+:1026600002300078000000040230007C000000030B
+:102670000630008000000002023000A400007FFF4E
+:10268000023000A8000003FF023002240000000016
+:1026900002300234000000000230024C0000000052
+:1026A000023002E40000FFFF0630200000000800B6
+:1026B00002338BC000000001023380000000001ACA
+:1026C000023380400000004E023380800000001082
+:1026D000023380C0000000200C33830000086470C7
+:1026E0000A338300000001570B3383000000055FAD
+:1026F0000A338340000000000C33834000000226B0
+:102700000B338340000000010233838000086470B3
+:10271000023383C00000022602331480000000014F
+:102720000A3314800000000006328000000001021D
+:1027300006322008000000C8063220000000000217
+:1027400004328520008F04360632875C00000009C1
+:1027500006323EB00000000606323ED00000000205
+:1027600006323E800000000A04323EA8000204C582
+:1027700006323E00000000200632500000000940F2
+:102780000632400000000004043294C0000204C776
+:1027900006324110000000020632D0000000007036
+:1027A0000632DB00000000D40632DEA0000000028A
+:1027B0000632E00000000800063324000000011883
+:1027C0000632100000000188063250000000002090
+:1027D00006325100000000200632520000000020A6
+:1027E0000632530000000020063254000000002092
+:1027F000063255000000002006325600000000207E
+:102800000632570000000020063258000000002069
+:10281000063259000000002006325A000000002055
+:1028200006325B000000002006325C000000002041
+:1028300006325D000000002006325E00000000202D
+:1028400006325F0000000020063284F00000000223
+:1028500004328500000204C9063285080000000227
+:102860000632DE90000000020633286000000118E6
+:102870000632162000000188063250800000002039
+:1028800006325180000000200632528000000020F5
+:1028900006325380000000200632548000000020E1
+:1028A00006325580000000200632568000000020CD
+:1028B00006325780000000200632588000000020B9
+:1028C000063259800000002006325A8000000020A5
+:1028D00006325B800000002006325C800000002091
+:1028E00006325D800000002006325E80000000207D
+:1028F00006325F8000000020063284F800000002EB
+:1029000004328510000204CB063285180000000254
+:102910000632DE98000000020232845000000000FF
+:102920000632401000000002023284540000000011
+:1029300006324020000000020232845800000000ED
+:1029400006324030000000020232845C00000000C9
+:1029500006324040000000020232846000000000A5
+:102960000632405000000002023284640000000081
+:10297000063240600000000202328468000000005D
+:1029800006324070000000020232846C0000000039
+:10299000063240800000000207200400007300009F
+:1029A00008200780001004CD072400002AF1000051
+:1029B0000724800027670ABD0824D35063FC04CF96
+:1029C000022000BC000000300120000000000000D8
+:1029D00001200004000000000120000800000000A9
+:1029E0000120000C00000000012000100000000089
+:1029F000012000140000000002200020000000015F
+:102A00000220002400000002022000280000000331
+:102A10000220002C00000000022000300000000412
+:102A200002200034000000010220003800000000F5
+:102A30000220003C000000010220004000000004D1
+:102A400002200044000000000220004800000001B5
+:102A50000220004C00000003022000500000000093
+:102A60000220005400000001022000580000000471
+:102A70000220005C00000000022000600000000155
+:102A80000220006400000003022000680000000033
+:102A90000220006C00000001022000700000000411
+:102AA00002200074000000000220007800000004F2
+:102AB0000220007C000000030620008000000002CD
+:102AC000022000A400007FFF022000A8000003FFF6
+:102AD0000220022400000000022002340000000056
+:102AE0000220024C00000000022002E40000FFFF70
+:102AF000062020000000080002238BC00000000117
+:102B00000223800000000010022380400000001219
+:102B10000223808000000030022380C00000000EED
+:102B20000C238300000864700A238300000001570F
+:102B30000B2383000000055F0A2383400000000090
+:102B40000C238340000002260B2383400000000179
+:102B50000223838000086470022383C000000226E1
+:102B600002231480000000010A23148000000000EA
+:102B7000062210000000004206222008000000C8C3
+:102B800006222000000000020622B00000000330F0
+:102B90000622F400000000530422F54C000104D189
+:102BA0000622F550000000030422F55C000104D267
+:102BB0000622F560000000030422F56C000104D336
+:102BC0000622F570000000030422F57C000104D405
+:102BD0000622F580000000030422F58C000104D5D4
+:102BE0000622F590000000030422F59C000104D6A3
+:102BF0000622F5A0000000030422F5AC000104D772
+:102C00000622F5B0000000030422F5BC000104D840
+:102C10000622F5C0000000460622E2000000044043
+:102C200004221240009004D906223000000000C0A7
+:102C30000622670000000100062290000000040048
+:102C400004226B0800200569062211F0000000062E
+:102C50000422120800060589062212200000000244
+:102C600006224000000005C00622C0000000000649
+:102C70000422C0180006058F0622C0300000000A9A
+:102C80000422C058000605950622C0700000000A04
+:102C90000422C0980006059B0622C0B00000000A6E
+:102CA0000422C0D8000605A10622C0F00000000AD8
+:102CB0000422C118000605A70622C1300000000A40
+:102CC0000422C158000605AD0622C1700000000AAA
+:102CD0000422C198000605B30622C1B00000000A14
+:102CE0000422C1D8000605B90622C1F00000000A7E
+:102CF0000422C218000605BF0622C2300000000AE6
+:102D00000422C258000605C50622C2700000000A4F
+:102D10000422C298000605CB0622C2B00000000AB9
+:102D20000422C2D8000605D10622C2F00000000A23
+:102D30000422C318000605D70622C3300000000A8B
+:102D40000422C358000605DD0622C3700000000AF5
+:102D50000422C398000605E30622C3B00000000A5F
+:102D60000422C3D8000605E90622C3F00000000AC9
+:102D70000422C418000605EF0622C4300000000A31
+:102D80000422C458000605F50622C4700000000A9B
+:102D90000422C498000605FB0622C4B00000000A05
+:102DA0000422C4D8000606010622C4F00000000A6E
+:102DB0000422C518000606070622C5300000000AD6
+:102DC0000422C5580006060D0622C5700000000A40
+:102DD0000422C598000606130622C5B00000000AAA
+:102DE0000422C5D8000606190622C5F00000000A14
+:102DF0000422C6180006061F0622C6300000000A7C
+:102E00000422C658000606250622C6700000000AE5
+:102E10000422C6980006062B0622C6B00000000A4F
+:102E20000422C6D8000606310622C6F00000000AB9
+:102E30000422C718000606370622C7300000000A21
+:102E40000422C7580006063D0622C7700000000A8B
+:102E50000422C798000606430622C7B00000000AF5
+:102E60000422C7D8000606490622C7F00000000A5F
+:102E70000422C8180006064F0622C8300000000AC7
+:102E80000422C858000606550622C8700000000A31
+:102E90000422C8980006065B0622C8B00000000A9B
+:102EA0000422C8D8000606610622C8F00000000A05
+:102EB0000422C918000606670622C9300000000A6D
+:102EC0000422C9580006066D0622C9700000000AD7
+:102ED0000422C998000606730622C9B00000000A41
+:102EE0000422C9D8000606790622C9F00000000AAB
+:102EF0000422CA180006067F0622CA300000000A13
+:102F00000422CA58000606850622CA700000000A7C
+:102F10000422CA980006068B0622CAB00000000AE6
+:102F20000422CAD8000606910622CAF00000000A50
+:102F30000422CB18000606970622CB300000000AB8
+:102F40000422CB580006069D0622CB700000000A22
+:102F50000422CB98000606A30622CBB00000000A8C
+:102F60000422CBD8000606A90622CBF00000000AF6
+:102F70000422CC18000606AF0622CC300000000A5E
+:102F80000422CC58000606B50622CC700000000AC8
+:102F90000422CC98000606BB0622CCB00000000A32
+:102FA0000422CCD8000606C10622CCF00000000A9C
+:102FB0000422CD18000606C70622CD300000000A04
+:102FC0000422CD58000606CD0622CD700000000A6E
+:102FD0000422CD98000606D30622CDB00000000AD8
+:102FE0000422CDD8000606D90622CDF00000000A42
+:102FF0000422CE18000606DF0622CE300000000AAA
+:103000000422CE58000606E50622CE700000000A13
+:103010000422CE98000606EB0622CEB00000000A7D
+:103020000422CED8000606F10622CEF00000000AE7
+:103030000422CF18000606F70622CF300000000A4F
+:103040000422CF58000606FD0622CF700000000AB9
+:103050000422CF98000607030622CFB00000000A22
+:103060000422CFD8000607090622CFF00000000A8C
+:103070000422D0180006070F0622D0300000000AF4
+:103080000422D058000607150622D0700000000A5E
+:103090000422D0980006071B0622D0B00000000AC8
+:1030A0000422D0D8000607210622D0F00000000A32
+:1030B0000422D118000607270622D1300000000A9A
+:1030C0000422D1580006072D0622D1700000000A04
+:1030D0000422D198000607330622D1B00000000A6E
+:1030E0000422D1D8000607390622D1F00000000AD8
+:1030F0000422D2180006073F0622D2300000000A40
+:103100000422D258000607450622D2700000000AA9
+:103110000422D2980006074B0622D2B00000000A13
+:103120000422D2D8000607510622D2F00000000A7D
+:103130000422D318000607570622D3300000000AE5
+:103140000422D3580006075D0622D3700000000A4F
+:103150000422D398000607630622D3B00000000AB9
+:103160000422D3D8000607690622D3F00000000A23
+:103170000422D4180006076F0622D4300000000A8B
+:103180000422D458000607750622D4700000000AF5
+:103190000422D4980006077B0622D4B00000000A5F
+:1031A0000422D4D8000607810622D4F00000000AC9
+:1031B0000422D518000607870622D5300000000A31
+:1031C0000422D5580006078D0622D5700000000A9B
+:1031D0000422D598000607930622D5B00000000A05
+:1031E0000422D5D8000607990622D5F00000000A6F
+:1031F0000422D6180006079F0622D6300000000AD7
+:103200000422D658000607A50622D6700000000A40
+:103210000422D698000607AB0622D6B00000000AAA
+:103220000422D6D8000607B10622D6F00000000A14
+:103230000422D718000607B70622D7300000000A7C
+:103240000422D758000607BD0622D7700000000AE6
+:103250000422D798000607C30622D7B00000000A50
+:103260000422D7D8000607C90622D7F00000000ABA
+:103270000422D818000607CF0622D8300000000A22
+:103280000422D858000607D50622D8700000000A8C
+:103290000422D898000607DB0622D8B00000000AF6
+:1032A0000422D8D8000607E10622D8F00000000A60
+:1032B0000422D918000607E70622D9300000000AC8
+:1032C0000422D958000607ED0622D9700000000A32
+:1032D0000422D998000607F30622D9B00000000A9C
+:1032E0000422D9D8000607F90622D9F00000000A06
+:1032F0000422DA18000607FF0622DA300000000A6E
+:103300000422DA58000608050622DA700000000AD6
+:103310000422DA980006080B0622DAB00000000A40
+:103320000422DAD8000608110622DAF00000000AAA
+:103330000422DB18000608170622DB300000000A12
+:103340000422DB580006081D0622DB700000000A7C
+:103350000422DB98000608230622DBB00000000AE6
+:103360000422DBD8000608290622DBF00000000A50
+:103370000422DC180006082F0622DC300000000AB8
+:103380000422DC58000608350622DC700000000A22
+:103390000422DC980006083B0622DCB00000000A8C
+:1033A0000422DCD8000608410622DCF00000000AF6
+:1033B0000422DD18000608470622DD300000000A5E
+:1033C0000422DD580006084D0622DD700000000AC8
+:1033D0000422DD98000608530622DDB00000000A32
+:1033E0000422DDD8000608590622DDF00000000A9C
+:1033F0000422DE180006085F0622DE300000000A04
+:103400000422DE58000608650622DE700000000A6D
+:103410000422DE980006086B0622DEB00000000AD7
+:103420000422DED8000608710622DEF00000000A41
+:103430000422DF18000608770622DF300000000AA9
+:103440000422DF580006087D0622DF700000000A13
+:103450000422DF98000608830622DFB00000000A7D
+:103460000422DFD8000608890622DFF00000000AE7
+:103470000422E0180006088F0622E0300000000A4F
+:103480000422E058000608950622E0700000000AB9
+:103490000422E0980006089B0622E0B00000000A23
+:1034A0000422E0D8000608A10622E0F00000000A8D
+:1034B0000422E118000608A70622E1300000000AF5
+:1034C0000422E158000608AD0622E1700000000A5F
+:1034D0000422E198000608B30622E1B00000000AC9
+:1034E0000422E1D8000608B90622E1F00000000439
+:1034F0000622153800000002062211E80000000232
+:103500000622F3000000000802221148000000001B
+:1035100006225900000000060622330000000002C7
+:1035200006226040000000300622F3200000000860
+:103530000222114C0000000006225918000000066B
+:10354000062233080000000206226100000000305D
+:103550000622F34000000008022211500000000083
+:103560000622593000000006062233100000000237
+:10357000062261C0000000300622F360000000084F
+:1035800002221154000000000622594800000006E3
+:10359000062233180000000206226280000000307C
+:1035A0000622F380000000080222115800000000EB
+:1035B00006225960000000060622332000000002A7
+:1035C00006226340000000300622F3A0000000083D
+:1035D0000222115C0000000006225978000000065B
+:1035E000062233280000000206226400000000309A
+:1035F0000622F3C000000008022211600000000053
+:103600000622599000000006062233300000000216
+:10361000062264C0000000300622F3E0000000082B
+:103620000222116400000000062259A800000006D2
+:1036300006223338000000020622658000000030B8
+:103640000216100000000028021700080000000207
+:103650000217002C000000030217003C00000004C9
+:10366000021700440000000002170048000000029A
+:103670000217004C0000009002170050000000905C
+:103680000217005400800090021700580810000034
+:10369000021700700000000602170078000009FF02
+:1036A0000217007C0000076C021701C4081000001C
+:1036B0000217034400000001021704000000008A02
+:1036C00002170404000000800217040800000081B3
+:1036D0000217040C00000080021704100000008A8A
+:1036E0000217041400000080021704180000008173
+:1036F0000217041C00000080021704300000008A3A
+:103700000217043400000080021704380000008112
+:103710000217043C00000080021704400000008AE9
+:1037200002170444000000800217044800000081D2
+:103730000217044C00000080021704800000008A79
+:103740000217048400000080021704880000008132
+:103750000217048C0000008002170038007C10045F
+:10376000021700040000000F021701EC0000000225
+:10377000021701F400000002021701EC0000000231
+:10378000021701F400000002021701EC0000000221
+:10379000021701F400000002021701EC0000000211
+:1037A000021701F400000002021701EC0000000201
+:1037B000021701F400000002021701EC00000002F1
+:1037C000021701F400000002021701EC00000002E1
+:1037D000021701F400000002021701EC00000002D1
+:1037E000021701F400000002061640240000000247
+:1037F000021640700000001C021642080000000182
+:1038000002164210000000010216422000000001D2
+:10381000021642280000000102164230000000019A
+:103820000216423800000001021642600000000249
+:103830000C16401C0003D0900A16401C0000009C8F
+:103840000B16401C000002710216403000000028D8
+:10385000021640340000002C0216403800000030F0
+:103860000216404400000020021640000000000143
+:10387000021640D8000000010216400800000001B6
+:103880000216400C0000000102164010000000016A
+:1038900002164240000000000216424800000000EC
+:1038A000061642700000000202164250000000009E
+:1038B0000216425800000000061642800000000276
+:1038C00002166008000012140216600C00001200BC
+:1038D00002166010000012040216601C0000FFFFB8
+:1038E000021660200000FFFF021660240000FFFFA8
+:1038F000021660280000FFFF02166038000000205A
+:103900000216603C00000010061660400000000235
+:1039100002166048000000230216604C00000024DC
+:1039200002166050000000250216605400000026B8
+:1039300002166058000000270216605C00000011AB
+:103940000216606000000000021660640000002B98
+:10395000021660680000002C0216606C0000002D4A
+:1039600002166070000000EC021660740000000097
+:1039700002166078000000290216607C0000002A10
+:10398000021660800000002F061660840000000D03
+:10399000021660B800000001061660BC00000008B6
+:1039A000021660DC00000001061660E00000000462
+:1039B000021660F000000001061660F4000000032B
+:1039C0000216610000000001061661040000002DCF
+:1039D000021661B800000001061661BC0000000874
+:1039E000021661DC00000001061661E00000000420
+:1039F000021661F000000001061661F400000003E9
+:103A00000216620000000001061662040000000DAC
+:103A10000216623807FFFFFF0216623C0000007FBB
+:103A20000216624007FFFFFF021662440000003FDB
+:103A300001166248000000000116624C0000000000
+:103A400001166250000000000116625400000000E0
+:103A500001166258000000000116625C00000000C0
+:103A600001166260000000000116626400000000A0
+:103A700001166268000000000116626C0000000080
+:103A80000116627000000000011662740000000060
+:103A900001166278000000000116627C0000000040
+:103AA000011662D400000000021662D80000FFFF79
+:103AB000021662DC0000FFFF021662E00000FFFF5A
+:103AC000021662E40000FFFF0C166000000003E82D
+:103AD0000A166000000000010B16600000000003E1
+:103AE0000216804000000006021680440000000517
+:103AF000021680480000000A0216804C00000005F3
+:103B00000216805400000002021680CC000000045F
+:103B1000021680D000000004021680D400000004C9
+:103B2000021680D800000004021680DC00000004A9
+:103B3000021680E000000004021680E40000000489
+:103B4000021680E800000004021688040000000647
+:103B5000021680300000007C021680340000003D18
+:103B6000021680380000003F0216803C0000009CD6
+:103B70000216E6E8000060000216E6EC00006000B5
+:103B80000216E6F0000060000216E6F40000600095
+:103B900002168234000025E40216823800008000FC
+:103BA00002168094000025E3021681F400000C0840
+:103BB000021681F800000040021681FC000001009E
+:103BC0000216820000000020021682040000001786
+:103BD00002168208000000800216820C000002001B
+:103BE00002168210000000000216823C0000001342
+:103BF00002168220008F008F0216821C008F008F19
+:103C0000021680F0000000070216821801FF01FF73
+:103C10000216821401FF01FF061680F40000000264
+:103C20000216811C0000000502168120000000051C
+:103C300002168124000000050216812800000008F9
+:103C40000216812C000000060216813000000007D9
+:103C50000616813400000004021680FC00000000FB
+:103C600006168144000000020216814C0000000488
+:103C7000021681500000000102168154000000026B
+:103C800002168158000000050216815C0000000544
+:103C90000216816000000005021681640000000524
+:103CA0000216816800000008021681000000000072
+:103CB0000216816C000000060216817000000007E9
+:103CC00006168174000000060216818C00000004B4
+:103CD000021681900000000102168104000000001D
+:103CE000021681940000000202168198000000056F
+:103CF0000216819C00000005021681A0000000054C
+:103D0000021681A400000005021681A80000000828
+:103D1000021681AC00000006021681B00000000708
+:103D2000061681B40000000202168108000000009F
+:103D3000061681BC00000004021681CC00000004BD
+:103D4000021681D000000001021681D4000000029A
+:103D5000021681D800000005021681DC0000000573
+:103D6000021681E0000000050216810C000000042C
+:103D7000021681E400000005021681E80000000838
+:103D8000021681EC00000006021681F00000000718
+:103D900002168110000000010216811400000002CA
+:103DA00002168118000000050216809C0000004CDD
+:103DB000021680A00000004C061680C4000000021D
+:103DC000021680A400000000021680A80000000077
+:103DD000021680AC0000004C061680B00000000502
+:103DE0000216E6F80000020402168240003F003F7F
+:103DF00002168244003F003F061682900000000435
+:103E000002168248008000800216824C00800080EA
+:103E100002168250010001000216825401000100C6
+:103E20000616825800000002021682600040004020
+:103E30000216826400400040021682681E001E00C6
+:103E40000216826C1E001E000216827040004000A6
+:103E500002168274400040000216827880008000C2
+:103E60000216827C800080000216828020002000E2
+:103E700002168284200020000616828800000002BC
+:103E8000021680900000004B021680600000014086
+:103E900002168064000001400616808800000002BF
+:103EA00002168068000000000216806C000000000E
+:103EB00002168070000000C0061680740000000525
+:103EC0000216880C0101010102168810010120046C
+:103ED000021688142008100102168818010101201A
+:103EE0000216881C0101010102168820010120042C
+:103EF00002168824200810010216882801010120DA
+:103F00000216882C200810010216883001010120B9
+:103F100002168834010101010216883801012004CB
+:103F20000216883C20081001021688400101012079
+:103F3000021688440101010102168848010120048B
+:103F40000216E6BC000000000216E6C000000002F7
+:103F50000216E6C4000000040216E6C800000006CF
+:103F60000216E79400000001021680EC000000FF3A
+:103F700002140000000000010215C024000000002F
+:103F80000215C0EC000000010215C0F000000001A5
+:103F90000615C10000000002021400040000000128
+:103FA00002140008000000010214000C00000001CF
+:103FB000021400300000000102140034000000016F
+:103FC0000214004000000001021400440000FFFF42
+:103FD00006140004000000030214000000000000AA
+:103FE000060280000000200002020058000000329B
+:103FF000020200A003150020020200A40315002005
+:10400000020200A801000030020200AC081000000B
+:10401000020200B000000036020200B400000030CE
+:10402000020200B800000031020200BC00000002E1
+:10403000020200C000000005020200C400000002ED
+:10404000020200C800000002020200D000000007C7
+:10405000020200DC00000000020200E00000000597
+:10406000020200E400000003020200F00000000170
+:10407000020200FC00000006020201200000000015
+:104080000202013400000002020201B0000000013F
+:104090000202020C000000010202021400000001F2
+:1040A00002020218000000020202040400000001E3
+:1040B0000202040C00000040020204100000004054
+:1040C0000202041C00000004020204200000002080
+:1040D0000202042400000002020204280000002062
+:1040E000060205000000001204020480002008BF40
+:1040F000020200600000000F0202006400000007DE
+:1041000002020068000000000202006C0000000EC5
+:10411000020200700000000E06020074000000039E
+:10412000020200F40000000402020004000000018A
+:1041300002020008000000010202000C0000000161
+:104140000202001000000001020200140000000141
+:1041500002020018000000010202001C0000000121
+:104160000202002000000001020200240000000101
+:1041700002020028000000010202002C00000001E1
+:1041800002020030000000010202003400000001C1
+:1041900002020038000000010202003C00000001A1
+:1041A0000202004000000001020200440000000181
+:1041B00002020048000000010202004C0000000161
+:1041C000020200500000000102020108000000C8C5
+:1041D0000202011800000002020201C400000000F7
+:1041E000020201CC00000000020201D40000000223
+:1041F000020201DC00000002020201E4000000FFF4
+:10420000020201EC000000FF0202010000000000B9
+:104210000202010C000000C80202011C00000002A2
+:10422000020201C800000000020201D000000000EC
+:10423000020201D800000002020201E000000002B8
+:10424000020201E8000000FF020201F0000000FF8E
+:10425000020201040000002002020108000000C860
+:104260000202011800000002020201C40000000066
+:10427000020201CC00000000020201D40000000292
+:10428000020201DC00000002020201E4000000FF63
+:10429000020201EC000000FF020201000000001019
+:1042A0000202010C000000C80202011C0000000212
+:1042B000020201C800000000020201D0000000005C
+:1042C000020201D800000002020201E00000000228
+:1042D000020201E8000000FF020201F0000000FFFE
+:1042E000020201040000003002020108000000C8C0
+:1042F0000202011800000002020201C400000000D6
+:10430000020201CC00000000020201D40000000201
+:10431000020201DC00000002020201E4000000FFD2
+:10432000020201EC000000FF020201000000004058
+:104330000202010C000000C80202011C0000000281
+:10434000020201C800000000020201D000000000CB
+:10435000020201D800000002020201E00000000297
+:10436000020201E8000000FF020201F0000000FF6D
+:10437000020201040000006002020108000000C8FF
+:104380000202011800000002020201C40000000045
+:10439000020201CC00000000020201D40000000271
+:1043A000020201DC00000002020201E4000000FF42
+:1043B000020201EC000000FF0202010000000050B8
+:1043C0000202010C000000C80202011C00000002F1
+:1043D000020201C800000000020201D0000000003B
+:1043E000020201D800000002020201E00000000207
+:1043F000020201E8000000FF020201F0000000FFDD
+:1044000002020104000000700728040000B500004B
+:10441000082807B8000908DF072C000028E9000079
+:10442000072C800036700A3B072D000035BE17D8D8
+:10443000072D80003B1B2548072E000035D8340F80
+:10444000072E80001B224186082EBFD0280608E1D7
+:10445000022800BC0000003001280000000000001D
+:1044600001280004000000000128000800000000EE
+:104470000128000C000000000128001000000000CE
+:1044800001280014000000000228002000000001A4
+:104490000228002400000002022800280000000377
+:1044A0000228002C00000000022800300000000458
+:1044B000022800340000000102280038000000003B
+:1044C0000228003C00000001022800400000000417
+:1044D00002280044000000000228004800000001FB
+:1044E0000228004C000000030228005000000000D9
+:1044F00002280054000000010228005800000004B7
+:104500000228005C0000000002280060000000019A
+:104510000228006400000003022800680000000078
+:104520000228006C00000001022800700000000456
+:104530000228007400000000022800780000000437
+:104540000228007C00000003062800800000000212
+:10455000022800A400007FFF022800A8000003FF3B
+:10456000022802240000000002280234000000009B
+:104570000228024C00000000022802E40000FFFFB5
+:104580000628200000000800022B8BC0000000015C
+:10459000022B800000000000022B80400000001869
+:1045A000022B80800000000C022B80C000000066FF
+:1045B0000C2B8300000864700A2B83000000015755
+:1045C0000B2B83000000055F0A2B834000000000D6
+:1045D0000C2B8340000002260B2B834000000001BF
+:1045E000022B838000086470022B83C00000022627
+:1045F000022B1480000000010A2B14800000000030
+:10460000022B944000000001062B94480000000299
+:10461000062A9A7000000004042A9A80000408E325
+:10462000062A9A9000000002042A9A98000208E7DD
+:10463000062A900000000048062A2008000000C852
+:10464000062A200000000002062A912800000086A9
+:10465000062AC00000000120062A9348000000033B
+:10466000042A9354000108E9062A9FB000000002C2
+:10467000042A9418000208EA042A9CD0000108ECDD
+:10468000062A9CD400000011042A9D20008F08ED0A
+:10469000062A9F5C00000005042A30000002097C05
+:1046A000062A300800000100062A404000000010E1
+:1046B000042A40000010097E042A84080002098EA2
+:1046C000042ACF4000040990042ACF600002099414
+:1046D000062A9FA000000004062A60000000054092
+:1046E000062A9D1800000002062AB00000000050B3
+:1046F000062ABB7000000070062ABB68000000029A
+:10470000062AB94800000004062AD000000008006C
+:10471000062AC48000000150062A942000000032BE
+:10472000062A502000000002062A50300000000235
+:10473000062A500000000002062A50100000000265
+:10474000022A520800000001042A9AA000020996D9
+:10475000062A95B000000022042A96380001099824
+:10476000062A963C00000003062A96E0000000227C
+:10477000042A976800010999062A976C0000000333
+:10478000062A981000000022042A98980001099A2D
+:10479000062A989C00000003062A99400000002287
+:1047A000042A99C80001099B062A99CC000000033D
+:1047B000062ABB5800000002062AC9C000000150AA
+:1047C000062A94E800000032062A50280000000261
+:1047D000062A503800000002062A50080000000295
+:1047E000062A501800000002022A520C00000001A4
+:1047F000042A9AA80002099C062A96480000002272
+:10480000042A96D00001099E062A96D400000003CF
+:10481000062A977800000022042A98000001099FC8
+:10482000062A980400000003062A98A80000002227
+:10483000042A9930000109A0062A993400000003D7
+:10484000062A99D800000022042A9A60000109A1D2
+:10485000062A9A6400000003062ABB6000000002DA
+:10486000022ACF0000000000042A9AB0001009A21A
+:10487000062A50480000000E022ACF040000000063
+:10488000042A9AF0001009B2062A50800000000E97
+:10489000022ACF0800000000042A9B30001009C241
+:1048A000062A50B80000000E022ACF0C00000000BB
+:1048B000042A9B70001009D2062A50F00000000E56
+:1048C000022ACF1000000000042A9BB0001009E269
+:1048D000062A51280000000E022ACF140000000012
+:1048E000042A9BF0001009F2062A51600000000E15
+:1048F000022ACF1800000000042A9C3000100A028F
+:10490000062A51980000000E022ACF1C0000000069
+:10491000042A9C7000100A12062A51D00000000ED2
+:1049200002101008000000010210105000000001E9
+:10493000021010000003D000021010040000003D1F
+:104940000910180002000A220910110000100C22A0
+:1049500006101140000000080910116000100C3210
+:10496000061011A00000001806102400000000E04E
+:104970000210201C00000000021020200000000196
+:10498000021020C0000000020210200400000001FC
+:104990000210200800000001021030D800000001C1
+:1049A00009103C0000050C420910380000050C47B6
+:1049B0000910392000050C4C09103B0000050C5172
+:1049C000021040D400000030021040D80000003037
+:1049D00006104C00000001000210402800000010EA
+:1049E0000210404400003FFF021040580028000021
+:1049F000021040840084924A0210405800000000D7
+:104A0000021041380000000102104138000000018E
+:104A1000021041380000000102104138000000017E
+:104A2000021041380000000102104138000000016E
+:104A3000021041380000000102104138000000015E
+:104A40000212049001F680400212051400003C108E
+:104A500002120494FFFFFFFF02120498FFFFFFFF02
+:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2
+:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2
+:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2
+:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A
+:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
+:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
+:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
+:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
+:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
+:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
+:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
+:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
+:104B200002120504FFFFFFFF02120508FFFFFFFF4F
+:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
+:104B4000021204D4F800C000021204B4F0005000B5
+:104B500002120390000000080212039C00000008EB
+:104B6000021203A000000008021203A400000002C9
+:104B7000021203BC00000004021203C00000000582
+:104B8000021203C400000004021203D0000000005F
+:104B90000212036C00000001021201BC0000004080
+:104BA000021201C000001808021201C4000008032C
+:104BB000021201C800000803021201CC00000040EC
+:104BC000021201D000000003021201D40000080309
+:104BD000021201D800000803021201DC00000803E1
+:104BE000021201E000010003021201E400000803C8
+:104BF000021201E800000803021201EC00000003A9
+:104C0000021201F000000003021201F40000000390
+:104C1000021201F800000003021201FC0000000370
+:104C2000021202000000000302120204000000034E
+:104C300002120208000000030212020C000000032E
+:104C4000021202100000000302120214000000030E
+:104C500002120218000000030212021C00000003EE
+:104C600002120220000000030212022400000003CE
+:104C700002120228000024030212022C0000002F5E
+:104C80000212023000000009021202340000001972
+:104C900002120238000001840212023C000001836B
+:104CA0000212024000000306021202440000001932
+:104CB00002120248000000060212024C0000030625
+:104CC0000212025000000306021202540000030602
+:104CD0000212025800000C860212025C0000030659
+:104CE00002120260000003060212026400000006C5
+:104CF00002120268000000060212026C00000006A8
+:104D00000212027000000006021202740000000687
+:104D100002120278000000060212027C0000000667
+:104D20000212028000000006021202840000000647
+:104D300002120288000000060212028C0000000627
+:104D40000212029000000006021202940000000607
+:104D500002120298000000060212029C00000006E7
+:104D6000021202A000000306021202A400000013B7
+:104D7000021202A800000006021202B00000100495
+:104D8000021202B400001004021203240010644056
+:104D90000212032800106440021205B40000000152
+:104DA000021205F800000040021205FC0000001984
+:104DB00002120600000000010212066C0000000151
+:104DC000021201B000000001021207D80000000327
+:104DD000021207D800000003021207D800000003E7
+:104DE000021207D800000003021207D800000003D7
+:104DF000021207D800000003021207D800000003C7
+:104E0000021207D8000000030600A0000000000CFA
+:104E10000200A050000000000200A05400000000AA
+:104E20000200A0EC555400000200A0F05555555565
+:104E30000200A0F4000055550200A0F8F0000000A8
+:104E40000200A0FC555400000200A1005555555524
+:104E50000200A104000055550200A108F000000066
+:104E60000200A19C000000000200A1A000010000BF
+:104E70000200A1A4000050140200A1A8000000003C
+:104E80000200A6A8000000000200A6AC000000007E
+:104E90000200A6D0000000000200A45C00000C008C
+:104EA0000200A61C000000030200A070FFF55FFFD7
+:104EB0000200A0740000FFFF0200A078F00003E0F1
+:104EC0000200A07C000000000200A0800000A00002
+:104ED0000600A084000000050200A0980FE000007A
+:104EE0000600A09C000000070200A0B8000004001B
+:104EF0000600A0BC000000030200A0C800001000D3
+:104F00000600A0CC000000030200A0D80000400072
+:104F10000600A0DC000000030200A0E80001000081
+:104F20000600A22C000000040200A688000000FC7D
+:104F30000600A68C000000070200A6F40000000096
+:104F40000200A10CFF5C00000200A110FFF55FFF52
+:104F50000200A1140000FFFF0200A118F00003E00E
+:104F60000200A11C000000000200A1200000A0001F
+:104F70000600A124000000050200A1380FE0000097
+:104F80000600A13C000000070200A1580000080034
+:104F90000600A15C000000030200A16800002000E0
+:104FA0000600A16C000000030200A1780000800050
+:104FB0000600A17C000000030200A188000200009E
+:104FC0000600A23C000000040200A6B0000000FCA5
+:104FD0000600A6B4000000070200A6F800000000CA
+:104FE0000200A030000000000200A0340000000019
+:104FF0000200A038000000000200A03C00000000F9
+:105000000200A040000000000200A04400000000D8
+:105010000200A048000000000200A04C00000000B8
+:10502000020090C40000E000020090CC0000F300F9
+:10503000020090D400000003020091A000000001D3
+:105040000600917000000003020090EC0000600078
+:10505000020090F400007300020090FC00000003C6
+:10506000020091A8000000010600918800000003E2
+:10507000020091000000400002009108000053006F
+:105080000200911000000004020091AC0000000139
+:1050900006009194000000020200919C00000001B3
+:1050A000020090D800006000020090E00000730051
+:1050B000020090E800000003020091A4000000013B
+:1050C0000200917C000000010200918000000001BC
+:1050D00002009184000000000200912800000300FB
+:1050E0000200916C0003F0080200912C0000030004
+:1050F0000200913000000300020091340000030020
+:1051000002009138000003000200913C00000300FF
+:1051100002009140000003000200942C00000001F6
+:1051200002009430000000010200943400000001ED
+:105130000200942C000000010200943000000001E5
+:1051400002009434000000010200942C00000001D1
+:1051500002009430000000010200943400000001BD
+:105160000200942C000000010200943000000001B5
+:1051700002009434000000010200942C00000001A1
+:10518000020094300000000102009434000000018D
+:105190000200942C00000001020094300000000185
+:1051A00002009434000000010200942C0000000171
+:1051B000020094300000000102009434000000015D
+:1051C0000200942C00000001020094300000000155
+:1051D0000200943400000001021300780000003047
+:1051E0000213003C000061A8061301080000000340
+:1051F000021301040000000002130134000000004B
+:10520000061301080000000302130104000000005F
+:10521000021301340000000006130108000000031F
+:10522000021301040000000002130134000000001A
+:10523000061301080000000302130104000000002F
+:1052400002130134000000000613010800000003EF
+:1052500002130104000000000213013400000000EA
+:1052600006130108000000030213010400000000FF
+:1052700002130134000000000613010800000003BF
+:1052800002130104000000000213013400000000BA
+:1052900006130108000000030213010400000000CF
+:1052A0000213013400000000021100B800000001E8
+:1052B0000216E6E8000020000216E6EC00002000DE
+:1052C0000216E6F0000065550216E6F4000065558A
+:1052D00002168150000000000216817400000001D7
+:1052E00002168178000000010216817C0000000196
+:1052F0000216818000000001021681840000000176
+:105300000216818800000001021681B4000000012D
+:10531000021681B800000001021681BC00000001E5
+:10532000021681C000000001021681C400000001C5
+:10533000021681C800000001021681100000000062
+:105340000216824000BF00BF061682440000000221
+:105350000216824C00BF00BF0216E6C40000000126
+:105360000216E6C8000000030216E79400000000E1
+:10537000042ACF40000A0C56000000000000000084
+:1053800000000034000000000000000000000000E9
+:10539000000000000000000000000000000000000D
+:1053A0000000000000000000000000000034003594
+:1053B00000000000000000000000000000000000ED
+:1053C00000000000000000000000000000000000DD
+:1053D0000000000000000000003500600000000038
+:1053E00000000000000000000000000000000000BD
+:1053F00000000000000000000000000000000000AD
+:1054000000000000006000910000000000000000AB
+:1054100000910095009500990099009D009D00A1C4
+:1054200000A100A500A500A900A900AD00AD00B134
+:1054300000B100B500000000000000000000000006
+:10544000000000000000000000000000000000005C
+:1054500000000000000000000000000000B5031183
+:105460000311031B031B03250325032C032C033308
+:105470000333033A033A0341034103480348034F0C
+:10548000034F03560356035D0000000000000000B8
+:10549000000000000000000000000000000000000C
+:1054A00000000000000000000000000000000000FC
+:1054B00000000000000000000000000000000000EC
+:1054C00000000000000000000000000000000000DC
+:1054D00000000000000000000000000000000000CC
+:1054E00000000000000000000000000000000000BC
+:1054F00000000000000000000000000000000000AC
+:10550000000000000000000000000000000000009B
+:10551000000000000000000000000000000000008B
+:10552000000000000000000000000000000000007B
+:105530000000000000000000035D035E00000000AA
+:1055400000000000035E035F035F0360036003610C
+:10555000036103620362036303630364036403651B
+:10556000036503660000000000000000000000006A
+:10557000000000000000000000000000000000002B
+:10558000000000000000000000000000000000001B
+:105590000366036D036D0379037903850000000042
+:1055A00000000000000000000000000000000000FB
+:1055B00000000000000000000000000000000000EB
+:1055C00000000000000000000000000000000000DB
+:1055D00000000000000000000000000000000000CB
+:1055E00000000000000000000385038600000000AA
+:1055F00000000000000000000000000000000000AB
+:10560000000000000000000000000000000000009A
+:1056100000000000038603B100000000000000004D
+:10562000000000000000000000000000000000007A
+:10563000000000000000000000000000000000006A
+:1056400003B103E0000000000000000000000000C3
+:10565000000000000000000000000000000000004A
+:1056600000000000000000000000000003E0040F44
+:105670000000000000000000040F04160416041DC2
+:10568000041D04240424042B042B043204320439A2
+:1056900004390440044004470447047A0000000031
+:1056A00000000000047A047E047E048204820486E2
+:1056B0000486048A048A048E048E0492049204965A
+:1056C0000496049A049A04EA04EA05000500051603
+:1056D000051605180518051A051A051C051C051ED2
+:1056E000051E052005200522052205240524052682
+:1056F00005260693000000000000000006930698AF
+:105700000698069D069D06A206A206A706A706AC59
+:1057100006AC06B106B106B606B606BB06BB06BCAD
+:105720000000000000000000000000000000000079
+:105730000000000000000000000000000000000069
+:10574000000000000000000006BC06E000000000B1
+:105750000000000006E006E206E206E406E406E6D3
+:1057600006E606E806E806EA06EA06EC06EC06EEB9
+:1057700006EE06F006F00705070507080708070B01
+:105780000000000000000000000000000000000019
+:105790000000000000000000000000000000000009
+:1057A000070B074F00000000000000000000000091
+:1057B00000000000000000000000000000000000E9
+:1057C000000000000000000000000000074F07E19B
+:1057D00000000000000000000000000000000000C9
+:1057E00000000000000000000000000000000000B9
+:1057F000000000000000000007E107EF00000000CB
+:105800000000000000000000000000000000000098
+:105810000000000000000000000000000000000088
+:105820000000000007EF082C00000000000000004E
+:10583000082C08350835083E083E08470847085038
+:1058400008500859085908620862086B086B087408
+:10585000087408D508D508EA08EA08FF08FF090215
+:1058600009020905090509080908090B090B090EB0
+:10587000090E09110911091409140917091709203A
+:105880000000000000000000000000000000000018
+:105890000000000000000000000000000000000008
+:1058A00000000000000000000920092600000000A0
+:1058B00000000000000000000000000000000000E8
+:1058C00000000000000000000000000000000000D8
+:1058D000000000000926092B000000000000000065
+:1058E00000000000000000000000000000000000B8
+:1058F00000000000000000000000000000000000A8
+:10590000092B0933000000000000000009330934AE
+:10591000093409350935093609360937093709388F
+:10592000093809390939093A093A093B00000000E8
+:105930000000000000000000000000000000000067
+:105940000000000000000000000000000000000057
+:105950000000000000000000093B09AC000000004E
+:105960000000000009AC09AD09AD09AE09AE09AFF0
+:1059700009AF09B009B009B109B109B209B209B357
+:1059800009B309B409B409C809C809DB09DB09EF7F
+:1059900009EF09F009F009F109F109F209F209F337
+:1059A00009F309F409F409F509F509F609F609F707
+:1059B00009F70A1600000000000000000A160A1984
+:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F
+:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020
+:1059E00000000000000000000A300A330A330A36C3
+:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277
+:105A00000A420A450A450A480A480A4900000000B5
+:105A10000000000000000000000000000000000086
+:105A20000000000000000000000000000000000076
+:105A3000000000000A490A610000000000000000A8
+:105A40000000000000000000000000000000000056
+:105A50000000000000000000000000000000000046
+:105A60000A610A620000000000000000000000005F
+:105A70000000000000000000000000000000000026
+:105A80000000000000000000000000000000000016
+:105A9000000100000002070000030E0000041500D2
+:105AA00000051C000006230000072A000008310042
+:105AB00000093800000A3F00000B4600000C4D00B2
+:105AC000000D5400000E5B00000F62000010690022
+:105AD000001170000012770000137E000014850092
+:105AE00000158C000016930000179A000018A10002
+:105AF0000019A800001AAF00001BB600001CBD0072
+:105B0000001DC400001ECB00001FD2000000D90001
+:105B10000000200000004000000060000000800045
+:105B20000000A0000000C0000000E0000001000034
+:105B30000001200000014000000160000001800021
+:105B40000001A0000001C0000001E0000002000010
+:105B500000022000000240000002600000028000FD
+:105B60000002A0000002C0000002E00000030000EC
+:105B700000032000000340000003600000038000D9
+:105B80000003A0000003C0000003E00000040000C8
+:105B900000042000000440000004600000048000B5
+:105BA0000004A0000004C0000004E00000050000A4
+:105BB0000005200000054000000560000005800091
+:105BC0000005A0000005C0000005E0000006000080
+:105BD000000620000006400000066000000680006D
+:105BE0000006A0000006C0000006E000000700005C
+:105BF0000007200000074000000760000007800049
+:105C00000007A0000007C0000007E0000008000037
+:105C10000008200000084000000860000008800024
+:105C20000008A0000008C0000008E0000009000013
+:105C30000009200000094000000960000009800000
+:105C40000009A0000009C0000009E000000A0000EF
+:105C5000000A2000000A4000000A6000000A8000DC
+:105C6000000AA000000AC000000AE000000B0000CB
+:105C7000000B2000000B4000000B6000000B8000B8
+:105C8000000BA000000BC000000BE000000C0000A7
+:105C9000000C2000000C4000000C6000000C800094
+:105CA000000CA000000CC000000CE000000D000083
+:105CB000000D2000000D4000000D6000000D800070
+:105CC000000DA000000DC000000DE000000E00005F
+:105CD000000E2000000E4000000E6000000E80004C
+:105CE000000EA000000EC000000EE000000F00003B
+:105CF000000F2000000F4000000F6000000F800028
+:105D0000000FA000000FC000000FE0000010000016
+:105D10000010200000104000001060000010800003
+:105D20000010A0000010C0000010E00000110000F2
+:105D300000112000001140000011600000118000DF
+:105D40000011A0000011C0000011E00000120000CE
+:105D500000122000001240000012600000128000BB
+:105D60000012A0000012C0000012E00000130000AA
+:105D70000013200000134000001360000013800097
+:105D80000013A0000013C0000013E0000014000086
+:105D90000014200000144000001460000014800073
+:105DA0000014A0000014C0000014E0000015000062
+:105DB000001520000015400000156000001580004F
+:105DC0000015A0000015C0000015E000001600003E
+:105DD000001620000016400000166000001680002B
+:105DE0000016A0000016C0000016E000001700001A
+:105DF0000017200000174000001760000017800007
+:105E00000017A0000017C0000017E00000180000F5
+:105E100000182000001840000018600000188000E2
+:105E20000018A0000018C0000018E00000190000D1
+:105E300000192000001940000019600000198000BE
+:105E40000019A0000019C0000019E000001A0000AD
+:105E5000001A2000001A4000001A6000001A80009A
+:105E6000001AA000001AC000001AE000001B000089
+:105E7000001B2000001B4000001B6000001B800076
+:105E8000001BA000001BC000001BE000001C000065
+:105E9000001C2000001C4000001C6000001C800052
+:105EA000001CA000001CC000001CE000001D000041
+:105EB000001D2000001D4000001D6000001D80002E
+:105EC000001DA000001DC000001DE000001E00001D
+:105ED000001E2000001E4000001E6000001E80000A
+:105EE000001EA000001EC000001EE000001F0000F9
+:105EF000001F2000001F4000001F6000001F8000E6
+:105F0000001FA000001FC000001FE00000200000D4
+:105F100000202000002040000020600000208000C1
+:105F20000020A0000020C0000020E00000210000B0
+:105F3000002120000021400000216000002180009D
+:105F40000021A0000021C0000021E000002200008C
+:105F50000022200000224000002260000022800079
+:105F60000022A0000022C0000022E0000023000068
+:105F70000023200000234000002360000023800055
+:105F80000023A0000023C0000023E0000024000044
+:105F90000024200000244000002460000024800031
+:105FA0000024A0000024C0000024E0000025000020
+:105FB000002520000025400000256000002580000D
+:105FC0000025A0000025C0000025E00000260000FC
+:105FD00000262000002640000026600000268000E9
+:105FE0000026A0000026C0000026E00000270000D8
+:105FF00000272000002740000027600000278000C5
+:106000000027A0000027C0000027E00000280000B3
+:1060100000282000002840000028600000288000A0
+:106020000028A0000028C0000028E000002900008F
+:10603000002920000029400000296000002980007C
+:106040000029A0000029C0000029E000002A00006B
+:10605000002A2000002A4000002A6000002A800058
+:10606000002AA000002AC000002AE000002B000047
+:10607000002B2000002B4000002B6000002B800034
+:10608000002BA000002BC000002BE000002C000023
+:10609000002C2000002C4000002C6000002C800010
+:1060A000002CA000002CC000002CE000002D0000FF
+:1060B000002D2000002D4000002D6000002D8000EC
+:1060C000002DA000002DC000002DE000002E0000DB
+:1060D000002E2000002E4000002E6000002E8000C8
+:1060E000002EA000002EC000002EE000002F0000B7
+:1060F000002F2000002F4000002F6000002F8000A4
+:10610000002FA000002FC000002FE0000030000092
+:10611000003020000030400000306000003080007F
+:106120000030A0000030C0000030E000003100006E
+:10613000003120000031400000316000003180005B
+:106140000031A0000031C0000031E000003200004A
+:106150000032200000324000003260000032800037
+:106160000032A0000032C0000032E0000033000026
+:106170000033200000334000003360000033800013
+:106180000033A0000033C0000033E0000034000002
+:1061900000342000003440000034600000348000EF
+:1061A0000034A0000034C0000034E00000350000DE
+:1061B00000352000003540000035600000358000CB
+:1061C0000035A0000035C0000035E00000360000BA
+:1061D00000362000003640000036600000368000A7
+:1061E0000036A0000036C0000036E0000037000096
+:1061F0000037200000374000003760000037800083
+:106200000037A0000037C0000037E0000038000071
+:10621000003820000038400000386000003880005E
+:106220000038A0000038C0000038E000003900004D
+:10623000003920000039400000396000003980003A
+:106240000039A0000039C0000039E000003A000029
+:10625000003A2000003A4000003A6000003A800016
+:10626000003AA000003AC000003AE000003B000005
+:10627000003B2000003B4000003B6000003B8000F2
+:10628000003BA000003BC000003BE000003C0000E1
+:10629000003C2000003C4000003C6000003C8000CE
+:1062A000003CA000003CC000003CE000003D0000BD
+:1062B000003D2000003D4000003D6000003D8000AA
+:1062C000003DA000003DC000003DE000003E000099
+:1062D000003E2000003E4000003E6000003E800086
+:1062E000003EA000003EC000003EE000003F000075
+:1062F000003F2000003F4000003F6000003F800062
+:10630000003FA000003FC000003FE000003FE00170
+:1063100000000000000001FF0000020000007FF804
+:1063200000007FF800000A90000035000000000126
+:106330000000FF00000000000000FF00000000005F
+:106340000000FF00000000000000FF00000000004F
+:106350000000FF00000000000000FF00000000003F
+:106360000000FF00000000000000FF00000000002F
+:106370000000FF00000000000000FF00000000001F
+:106380000000FF00000000000000FF00000000000F
+:106390000000FF00000000000000FF0000000000FF
+:1063A0000000FF00000000000000FF0000000000EF
+:1063B0000000FF00000000000000FF0000000000DF
+:1063C0000000FF00000000000000FF0000000000CF
+:1063D0000000FF00000000000000FF0000000000BF
+:1063E0000000FF00000000000000FF0000000000AF
+:1063F0000000FF00000000000000FF00000000009F
+:106400000000FF00000000000000FF00000000008E
+:106410000000FF00000000000000FF00000000007E
+:106420000000FF00000000000000FF00000000006E
+:106430000000FF00000000000000FF00000000005E
+:106440000000FF00000000000000FF00000000004E
+:106450000000FF00000000000000FF00000000003E
+:106460000000FF00000000000000FF00000000002E
+:106470000000FF00000000000000FF00000000001E
+:106480000000FF00000000000000FF00000000000E
+:106490000000FF00000000000000FF0000000000FE
+:1064A0000000FF00000000000000FF0000000000EE
+:1064B0000000FF00000000000000FF0000000000DE
+:1064C0000000FF00000000000000FF0000000000CE
+:1064D0000000FF00000000000000FF0000000000BE
+:1064E0000000FF00000000000000FF0000000000AE
+:1064F0000000FF00000000000000FF00000000009E
+:106500000000FF00000000000000FF00000000008D
+:106510000000FF00000000000000FF00000000007D
+:106520000000FF00000000000000FF00000000006D
+:106530000000FF00000000000000FF00000000005D
+:106540000000FF00000000000000FF00000000004D
+:106550000000FF00000000000000FF00000000003D
+:106560000000FF00000000000000FF00000000002D
+:1065700000000000140AFF000000000100000000FD
+:106580000020100100000000010090000000010048
+:1065900000009002000090040000900600009008A7
+:1065A0000000900A0000900C0000900E0000901077
+:1065B0000000901200009014000090160000901847
+:1065C0000000901A0000901C0000901E0000902017
+:1065D00000009022000090240000902600009028E7
+:1065E0000000902A0000902C0000902E00009030B7
+:1065F0000000903200009034000090360000903887
+:106600000000903A0000903C0000903E0000904056
+:106610000000904200009044000090460000904826
+:106620000000904A0000904C0000904E00009050F6
+:1066300000009052000090540000905600009058C6
+:106640000000905A0000905C0000905E0000906096
+:106650000000906200009064000090660000906866
+:106660000000906A0000906C0000906E0000907036
+:106670000000907200009074000090760000907806
+:106680000000907A0000907C0000907E00009080D6
+:1066900000009082000090840000908600009088A6
+:1066A0000000908A0000908C0000908E0000909076
+:1066B0000000909200009094000090960000909846
+:1066C0000000909A0000909C0000909E000090A016
+:1066D000000090A2000090A4000090A6000090A8E6
+:1066E000000090AA000090AC000090AE000090B0B6
+:1066F000000090B2000090B4000090B6000090B886
+:10670000000090BA000090BC000090BE000090C055
+:10671000000090C2000090C4000090C6000090C825
+:10672000000090CA000090CC000090CE000090D0F5
+:10673000000090D2000090D4000090D6000090D8C5
+:10674000000090DA000090DC000090DE000090E095
+:10675000000090E2000090E4000090E6000090E865
+:10676000000090EA000090EC000090EE000090F035
+:10677000000090F2000090F4000090F6000090F805
+:10678000000090FA000090FC000090FE00009100D4
+:1067900000009102000091040000910600009108A1
+:1067A0000000910A0000910C0000910E0000911071
+:1067B0000000911200009114000091160000911841
+:1067C0000000911A0000911C0000911E0000912011
+:1067D00000009122000091240000912600009128E1
+:1067E0000000912A0000912C0000912E00009130B1
+:1067F0000000913200009134000091360000913881
+:106800000000913A0000913C0000913E0000914050
+:106810000000914200009144000091460000914820
+:106820000000914A0000914C0000914E00009150F0
+:1068300000009152000091540000915600009158C0
+:106840000000915A0000915C0000915E0000916090
+:106850000000916200009164000091660000916860
+:106860000000916A0000916C0000916E0000917030
+:106870000000917200009174000091760000917800
+:106880000000917A0000917C0000917E00009180D0
+:1068900000009182000091840000918600009188A0
+:1068A0000000918A0000918C0000918E0000919070
+:1068B0000000919200009194000091960000919840
+:1068C0000000919A0000919C0000919E000091A010
+:1068D000000091A2000091A4000091A6000091A8E0
+:1068E000000091AA000091AC000091AE000091B0B0
+:1068F000000091B2000091B4000091B6000091B880
+:10690000000091BA000091BC000091BE000091C04F
+:10691000000091C2000091C4000091C6000091C81F
+:10692000000091CA000091CC000091CE000091D0EF
+:10693000000091D2000091D4000091D6000091D8BF
+:10694000000091DA000091DC000091DE000091E08F
+:10695000000091E2000091E4000091E6000091E85F
+:10696000000091EA000091EC000091EE000091F02F
+:10697000000091F2000091F4000091F6000091F8FF
+:10698000000091FA000091FC000091FEFFFFFFFF64
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F
+:106A100000BEBC20000000000000000500000003D4
+:106A200000BEBC20000000000000000500000003C4
+:106A300000BEBC20000000000000000500000003B4
+:106A400000BEBC20000000000000000500000003A4
+:106A500000BEBC2000000000000000050000000394
+:106A600000BEBC2000000000000000050000000384
+:106A700000BEBC2000000000000000050000000374
+:106A800000BEBC2000000000000000050000200047
+:106A9000000040C000006180000082400000A300B0
+:106AA0000000C3C00000E480000105400001260092
+:106AB000000146C000016780000188400001A90074
+:106AC0000001C9C00001EA8000020B4000022C0056
+:106AD00000024CC000026D8000028E400002AF0038
+:106AE0000002CFC00002F0800000114000008000D2
+:106AF000000103800001870000020A8000028E006E
+:106B000000031180000395000004188000049C001D
+:106B100000051F800005A300000626800006AA00CD
+:106B200000072D800007B100000834800008B8007D
+:106B300000093B800009BF00000A4280000AC6002D
+:106B4000000B4980000BCD00000C5080000CD400DD
+:106B5000000D578000005B0000007FF800007FF808
+:106B60000000022A000035000000FF0000000000C5
+:106B70000000FF00000000000000FF000000000017
+:106B80000000FF00000000000000FF000000000007
+:106B90000000FF00000000000000FF0000000000F7
+:106BA0000000FF00000000000000FF0000000000E7
+:106BB0000000FF00000000000000FF0000000000D7
+:106BC0000000FF00000000000000FF0000000000C7
+:106BD0000000FF00000000000000FF0000000000B7
+:106BE0000000FF00000000000000FF0000000000A7
+:106BF0000000FF00000000000000FF000000000097
+:106C00000000FF00000000000000FF000000000086
+:106C10000000FF00000000000000FF000000000076
+:106C20000000FF00000000000000FF000000000066
+:106C30000000FF00000000000000FF000000000056
+:106C40000000FF00000000000000FF000000000046
+:106C50000000FF00000000000000FF000000000036
+:106C60000000FF00000000000000FF000000000026
+:106C70000000FF00000000000000FF000000000016
+:106C80000000FF00000000000000FF000000000006
+:106C90000000FF00000000000000FF0000000000F6
+:106CA0000000FF00000000000000FF0000000000E6
+:106CB0000000FF00000000000000FF0000000000D6
+:106CC0000000FF00000000000000FF0000000000C6
+:106CD0000000FF00000000000000FF0000000000B6
+:106CE0000000FF00000000000000FF0000000000A6
+:106CF0000000FF00000000000000FF000000000096
+:106D00000000FF00000000000000FF000000000085
+:106D10000000FF00000000000000FF000000000075
+:106D20000000FF00000000000000FF000000000065
+:106D30000000FF00000000000000FF000000000055
+:106D40000000FF00000000000000FF000000000045
+:106D50000000FF00000000000000FF000000000035
+:106D60000000FF00000000000000FF000000000025
+:106D70000000FF00000000000000FF000000000015
+:106D80000000FF00000000000000FF000000000005
+:106D90000000FF00000000000000FF0000000000F5
+:106DA0000000FF00000019000000000000000000CB
+:106DB000FFFFFFFF000000000393870000000000BA
+:106DC0000393870000007FF800007FF800000BA30A
+:106DD00000001500000000FF000000FF000000FFA1
+:106DE000000000FF000000FF000000FF000000FFA7
+:106DF000000000FF0000FF00000000000000FF0096
+:106E0000000000000000FF00000000000000FF0084
+:106E1000000000000000FF00000000000000FF0074
+:106E2000000000000000FF00000000000000FF0064
+:106E3000000000000000FF00000000000000FF0054
+:106E4000000000000000FF00000000000000FF0044
+:106E5000000000000000FF00000000000000FF0034
+:106E6000000000000000FF00000000000000FF0024
+:106E7000000000000000FF00000000000000FF0014
+:106E8000000000000000FF00000000000000FF0004
+:106E9000000000000000FF00000000000000FF00F4
+:106EA000000000000000FF00000000000000FF00E4
+:106EB000000000000000FF00000000000000FF00D4
+:106EC000000000000000FF00000000000000FF00C4
+:106ED000000000000000FF00000000000000FF00B4
+:106EE000000000000000FF00000000000000FF00A4
+:106EF000000000000000FF00000000000000FF0094
+:106F0000000000000000FF00000000000000FF0083
+:106F1000000000000000FF00000000000000FF0073
+:106F2000000000000000FF00000000000000FF0063
+:106F3000000000000000FF00000000000000FF0053
+:106F4000000000000000FF00000000000000FF0043
+:106F5000000000000000FF00000000000000FF0033
+:106F6000000000000000FF00000000000000FF0023
+:106F7000000000000000FF00000000000000FF0013
+:106F8000000000000000FF00000000000000FF0003
+:106F9000000000000000FF00000000000000FF00F3
+:106FA000000000000000FF00000000000000FF00E3
+:106FB000000000000000FF00000000000000FF00D3
+:106FC000000000000000FF00000000000000FF00C3
+:106FD000000000000000FF00000000000000FF00B3
+:106FE000000000000000FF00000000000000FF00A3
+:106FF000000000000000FF00000000000000FF0093
+:10700000000000000000FF00000000000000FF0082
+:10701000000000000000FF00000000000000FF0072
+:10702000000000000000FF00000000000000FF0062
+:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFF00000000000028AD00002918BE
+:1070C0000000291900000005000000070000FF0073
+:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A
+:1070E0000000FF000000FF000FFFFFFF0000FF0097
+:1070F0000FFFFFFF000000FF0000FF000000FF0087
+:107100000FFFFFFF0000FF000FFFFFFF000000FF69
+:107110000000FF000000FF000FFFFFFF0000FF0066
+:107120000FFFFFFF000000FF0000FF000000FF0056
+:107130000FFFFFFF0000FF000FFFFFFF000000FF39
+:107140000000FF000000FF000FFFFFFF0000FF0036
+:107150000FFFFFFF000000FF0000FF000000FF0026
+:107160000FFFFFFF0000FF000FFFFFFF000000FF09
+:107170000000FF000000FF000FFFFFFF0000FF0006
+:107180000FFFFFFF000000FF0000FF000000FF00F6
+:107190000FFFFFFF0000FF000FFFFFFF000000FFD9
+:1071A0000000FF000000FF000FFFFFFF0000FF00D6
+:1071B0000FFFFFFF000000FF0000FF000000FF00C6
+:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9
+:1071D0000000FF000000FF000FFFFFFF0000FF00A6
+:1071E0000FFFFFFF000000FF0000FF000000FF0096
+:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79
+:107200000000FF000000FF000FFFFFFF0000FF0075
+:107210000FFFFFFF000000FF0000FF000000FF0065
+:107220000FFFFFFF0000FF000FFFFFFF000000FF48
+:107230000000FF000000FF000FFFFFFF0000FF0045
+:107240000FFFFFFF000000FF0000FF000000FF0035
+:107250000FFFFFFF0000FF000FFFFFFF000000FF18
+:107260000000FF000000FF000FFFFFFF0000FF0015
+:107270000FFFFFFF000000FF0000FF000000FF0005
+:107280000FFFFFFF0000FF000FFFFFFF000000FFE8
+:107290000000FF000000FF000FFFFFFF0000FF00E5
+:1072A0000FFFFFFF000000FF0000FF000000FF00D5
+:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8
+:1072C0000000FF000000FF000FFFFFFF0000FF00B5
+:1072D0000FFFFFFF000000FF0000FF000000FF00A5
+:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88
+:1072F0000000FF000000FF000FFFFFFF0000FF0085
+:107300000FFFFFFF000000FF0000FF000000FF0074
+:107310000FFFFFFF0000FF000FFFFFFF000000FF57
+:107320000000FF000000FF000FFFFFFF0000FF0054
+:107330000FFFFFFF000000FF0000FF000000FF0044
+:107340000FFFFFFF0000FF000FFFFFFF000000FF27
+:107350000000FF000000FF000FFFFFFF0000FF0024
+:107360000FFFFFFF000000FF0000FF000000FF0014
+:107370000FFFFFFF0000FF000FFFFFFF000000FFF7
+:107380000000FF000000FF000FFFFFFF0000FF00F4
+:107390000FFFFFFF000000FF0000FF000000FF00E4
+:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7
+:1073B0000000FF000000FF000FFFFFFF0000FF00C4
+:1073C0000FFFFFFF000000FF0000FF000000FF00B4
+:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97
+:1073E0000000FF000000FF000FFFFFFF0000FF0094
+:1073F0000FFFFFFF000000FF0000FF000000FF0084
+:107400000FFFFFFF0000FF000FFFFFFF000000FF66
+:107410000000FF000000FF000FFFFFFF0000FF0063
+:107420000FFFFFFF000000FF0000FF000000FF0053
+:107430000FFFFFFF0000FF000FFFFFFF000000FF36
+:107440000000FF000000FF000FFFFFFF0000FF0033
+:107450000FFFFFFF000000FF0000FF000000FF0023
+:107460000FFFFFFF0000FF000FFFFFFF000000FF06
+:107470000000FF000000FF000FFFFFFF0000FF0003
+:107480000FFFFFFF000000FF0000FF000000FF00F3
+:107490000FFFFFFF0000FF000FFFFFFF000000FFD6
+:1074A0000000FF000000FF000FFFFFFF0000FF00D3
+:1074B0000FFFFFFF000000FF0000FF000000FF00C3
+:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6
+:1074D0000000FF000000FF000FFFFFFF0000FF00A3
+:1074E0000FFFFFFF000000FF0000FF000000FF0093
+:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76
+:107500000000FF000000FF000FFFFFFF0000FF0072
+:107510000FFFFFFF000000FF0000FF000000FF0062
+:107520000FFFFFFF0000FF000FFFFFFF000000FF45
+:107530000000FF000000FF000FFFFFFF0000FF0042
+:107540000FFFFFFF000000FF0000FF000000FF0032
+:107550000FFFFFFF0000FF000FFFFFFF000000FF15
+:107560000000FF000000FF000FFFFFFF0000FF0012
+:107570000FFFFFFF000000FF0000FF000000FF0002
+:107580000FFFFFFF0000FF000FFFFFFF000000FFE5
+:107590000000FF000000FF000FFFFFFF0000FF00E2
+:1075A0000FFFFFFF000000FF0000FF000000FF00D2
+:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5
+:1075C0000000FF000000FF000FFFFFFF0000FF00B2
+:1075D0000FFFFFFF000000FF0000FF000000FF00A2
+:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85
+:1075F0000000FF000000FF000FFFFFFF0000FF0082
+:107600000FFFFFFF000000FF0000FF000000FF0071
+:107610000FFFFFFF0000FF000FFFFFFF000000FF54
+:107620000000FF000000FF000FFFFFFF0000FF0051
+:107630000FFFFFFF000000FF0000FF000000FF0041
+:107640000FFFFFFF0000FF000FFFFFFF000000FF24
+:107650000000FF000000FF000FFFFFFF0000FF0021
+:107660000FFFFFFF000000FF0000FF000000FF0011
+:107670000FFFFFFF0000FF000FFFFFFF000000FFF4
+:107680000000FF000000FF000FFFFFFF0000FF00F1
+:107690000FFFFFFF000000FF0000FF000000FF00E1
+:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4
+:1076B0000000FF000000FF000FFFFFFF0000FF00C1
+:1076C0000FFFFFFF000000FF0000FF000000FF00B1
+:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94
+:1076E0000000FF000000FF000FFFFFFF0000FF0091
+:1076F0000FFFFFFF000000FF0000FF000000FF0081
+:107700000FFFFFFF0000FF000FFFFFFF000000FF63
+:107710000000FF000000FF000FFFFFFF0000FF0060
+:107720000FFFFFFF000000FF0000FF000000FF0050
+:107730000FFFFFFF0000FF000FFFFFFF000000FF33
+:107740000000FF000000FF000FFFFFFF0000FF0030
+:107750000FFFFFFF000000FF0000FF000000FF0020
+:107760000FFFFFFF0000FF000FFFFFFF000000FF03
+:107770000000FF000000FF000FFFFFFF0000FF0000
+:107780000FFFFFFF000000FF0000FF000000FF00F0
+:107790000FFFFFFF0000FF000FFFFFFF000000FFD3
+:1077A0000000FF000000FF000FFFFFFF0000FF00D0
+:1077B0000FFFFFFF000000FF0000FF000000FF00C0
+:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3
+:1077D0000000FF000000FF000FFFFFFF0000FF00A0
+:1077E0000FFFFFFF000000FF0000FF000000FF0090
+:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73
+:107800000000FF000000FF000FFFFFFF0000FF006F
+:107810000FFFFFFF000000FF0000FF000000FF005F
+:107820000FFFFFFF0000FF000FFFFFFF000000FF42
+:107830000000FF000000FF000FFFFFFF0000FF003F
+:107840000FFFFFFF000000FF0000FF000000FF002F
+:107850000FFFFFFF0000FF000FFFFFFF000000FF12
+:107860000000FF000000FF000FFFFFFF0000FF000F
+:107870000FFFFFFF000000FF0000FF000000FF00FF
+:107880000FFFFFFF0000FF000FFFFFFF000000FFE2
+:107890000000FF000000FF000FFFFFFF0000FF00DF
+:1078A0000FFFFFFF000000FF0000FF000000FF00CF
+:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2
+:1078C0000000FF000000FF000FFFFFFF0000FF00AF
+:1078D0000FFFFFFF000000FF0000FF000000FF009F
+:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82
+:1078F0000000FF000000FF000FFFFFFF0000FF007F
+:107900000FFFFFFF000000FF0000FF000000FF006E
+:107910000FFFFFFF0000FF000FFFFFFF000000FF51
+:107920000000FF000000FF000FFFFFFF0000FF004E
+:107930000FFFFFFF000000FF0000FF000000FF003E
+:107940000FFFFFFF0000FF000FFFFFFF000000FF21
+:107950000000FF000000FF000FFFFFFF0000FF001E
+:107960000FFFFFFF000000FF0000FF000000FF000E
+:107970000FFFFFFF0000FF000FFFFFFF000000FFF1
+:107980000000FF000000FF000FFFFFFF0000FF00EE
+:107990000FFFFFFF000000FF0000FF000000FF00DE
+:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1
+:1079B0000000FF000000FF000FFFFFFF0000FF00BE
+:1079C0000FFFFFFF000000FF0000FF000000FF00AE
+:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91
+:1079E0000000FF000000FF000FFFFFFF0000FF008E
+:1079F0000FFFFFFF000000FF0000FF000000FF007E
+:107A00000FFFFFFF0000FF000FFFFFFF000000FF60
+:107A10000000FF000000FF000FFFFFFF0000FF005D
+:107A20000FFFFFFF000000FF0000FF000000FF004D
+:107A30000FFFFFFF0000FF000FFFFFFF000000FF30
+:107A40000000FF000000FF000FFFFFFF0000FF002D
+:107A50000FFFFFFF000000FF0000FF000000FF001D
+:107A60000FFFFFFF0000FF000FFFFFFF000000FF00
+:107A70000000FF000000FF000FFFFFFF0000FF00FD
+:107A80000FFFFFFF000000FF0000FF000000FF00ED
+:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0
+:107AA0000000FF000000FF000FFFFFFF0000FF00CD
+:107AB0000FFFFFFF000000FF0000FF000000FF00BD
+:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0
+:107AD0000000FF000000FF000FFFFFFF0000FF009D
+:107AE0000FFFFFFF000000FF0000FF000000FF008D
+:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70
+:107B00000000FF000000FF000FFFFFFF0000FF006C
+:107B10000FFFFFFF000000FF0000FF000000FF005C
+:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F
+:107B30000000FF000000FF000FFFFFFF0000FF003C
+:107B40000FFFFFFF000000FF0000FF000000FF002C
+:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F
+:107B60000000FF000000FF000FFFFFFF0000FF000C
+:107B70000FFFFFFF000000FF0000FF000000FF00FC
+:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF
+:107B90000000FF000000FF000FFFFFFF0000FF00DC
+:107BA0000FFFFFFF000000FF0000FF000000FF00CC
+:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF
+:107BC0000000FF000000FF000FFFFFFF0000FF00AC
+:107BD0000FFFFFFF000000FF0000FF000000FF009C
+:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F
+:107BF0000000FF000000FF000FFFFFFF0000FF007C
+:107C00000FFFFFFF000000FF0000FF000000FF006B
+:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E
+:107C20000000FF000000FF000FFFFFFF0000FF004B
+:107C30000FFFFFFF000000FF0000FF000000FF003B
+:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E
+:107C50000000FF000000FF000FFFFFFF0000FF001B
+:107C60000FFFFFFF000000FF0000FF000000FF000B
+:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE
+:107C80000000FF000000FF000FFFFFFF0000FF00EB
+:107C90000FFFFFFF000000FF0000FF000000FF00DB
+:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE
+:107CB0000000FF000000FF000FFFFFFF0000FF00BB
+:107CC0000FFFFFFF000000FF0000FF000000FF00AB
+:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E
+:107CE0000000FF000000FF000FFFFFFF0000FF008B
+:107CF0000FFFFFFF000000FF0000FF000000FF007B
+:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D
+:107D10000000FF000000FF000FFFFFFF0000FF005A
+:107D20000FFFFFFF000000FF0000FF000000FF004A
+:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D
+:107D40000000FF000000FF000FFFFFFF0000FF002A
+:107D50000FFFFFFF000000FF0000FF000000FF001A
+:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD
+:107D70000000FF000000FF000FFFFFFF0000FF00FA
+:107D80000FFFFFFF000000FF0000FF0000001000D9
+:107D900000002080000031000000418000005200FF
+:107DA00000006280000073000000838000009400E7
+:107DB0000000A4800000B5000000C5800000D600CF
+:107DC0000000E6800000F7000001078000011800B5
+:107DD00000012880000139000001498000015A009B
+:107DE00000016A8000017B0000018B8000019C0083
+:107DF0000001AC800001BD000001CD800001DE006B
+:107E00000001EE800001FF0000000F8000007FF8FD
+:107E100000007FF8000005F60000350010000000AB
+:107E2000000028AD000029180000291900000005F5
+:107E3000000000060001000100050206CCCCCCC900
+:107E40007058103C0000FF00000000000000FF0020
+:107E5000000000000000FF00000000000000FF0024
+:107E6000000000000000FF00000000000000FF0014
+:107E7000000000000000FF00000000000000FF0004
+:107E8000000000000000FF00000000000000FF00F4
+:107E9000000000000000FF00000000000000FF00E4
+:107EA000000000000000FF00000000000000FF00D4
+:107EB000000000000000FF00000000000000FF00C4
+:107EC000000000000000FF00000000000000FF00B4
+:107ED000000000000000FF00000000000000FF00A4
+:107EE000000000000000FF00000000000000FF0094
+:107EF000000000000000FF00000000000000FF0084
+:107F0000000000000000FF00000000000000FF0073
+:107F1000000000000000FF00000000000000FF0063
+:107F2000000000000000FF00000000000000FF0053
+:107F3000000000000000FF00000000000000FF0043
+:107F4000000000000000FF00000000000000FF0033
+:107F5000000000000000FF00000000000000FF0023
+:107F6000000000000000FF00000000000000FF0013
+:107F7000000000000000FF00000000000000FF0003
+:107F8000000000000000FF00000000000000FF00F3
+:107F9000000000000000FF00000000000000FF00E3
+:107FA000000000000000FF00000000000000FF00D3
+:107FB000000000000000FF00000000000000FF00C3
+:107FC000000000000000FF00000000000000FF00B3
+:107FD000000000000000FF00000000000000FF00A3
+:107FE000000000000000FF00000000000000FF0093
+:107FF000000000000000FF00000000000000FF0083
+:10800000000000000000FF00000000000000FF0072
+:10801000000000000000FF00000000000000FF0062
+:10802000000000000000FF00000000000000FF0052
+:10803000000000000000FF00000000000000FF0042
+:10804000000000000000FF00000000000000FF0032
+:10805000000000000000FF00000000000000FF0022
+:10806000000000000000FF00000000000000FF0012
+:10807000000000000000FF00000000000000FF0002
+:108080000000000000000001CCCC0201CCCCCCCC24
+:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A
+:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A
+:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A
+:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9
+:1080D000030303031342020250505020706080508B
+:1080E0000200020006040604000E0000011600D67D
+:1080F000002625A0002625A0002625A0002625A0D4
+:1081000000720000012300F3002625A0002625A010
+:10811000002625A0002625A00000FFFF000000008B
+:108120000000FFFF000000000000FFFF0000000053
+:108130000000FFFF000000000000FFFF0000000043
+:108140000000FFFF000000000000FFFF0000000033
+:108150000000FFFF000000000000FFFF0000000023
+:108160000000FFFF000000000000FFFF0000000013
+:108170000000FFFF000000000000FFFF0000000003
+:108180000000FFFF000000000000FFFF00000000F3
+:108190000000FFFF000000000000FFFF00000000E3
+:1081A0000000FFFF000000000000FFFF00000000D3
+:1081B0000000FFFF000000000000FFFF00000000C3
+:1081C0000000FFFF000000000000FFFF00000000B3
+:1081D0000000FFFF000000000000FFFF00000000A3
+:1081E0000000FFFF000000000000FFFF0000000093
+:1081F0000000FFFF000000000000FFFF0000000083
+:108200000000FFFF000000000000FFFF0000000072
+:108210000000FFFF000000000000FFFF0000000062
+:108220000000FFFF000000000000FFFF0000000052
+:108230000000FFFF000000000000FFFF0000000042
+:108240000000FFFF000000000000FFFF0000000032
+:108250000000FFFF000000000000FFFF0000000022
+:108260000000FFFF000000000000FFFF0000000012
+:108270000000FFFF000000000000FFFF0000000002
+:108280000000FFFF000000000000FFFF00000000F2
+:108290000000FFFF000000000000FFFF00000000E2
+:1082A0000000FFFF000000000000FFFF00000000D2
+:1082B0000000FFFF000000000000FFFF00000000C2
+:1082C0000000FFFF000000000000FFFF00000000B2
+:1082D0000000FFFF000000000000FFFF00000000A2
+:1082E0000000FFFF000000000000FFFF0000000092
+:1082F0000000FFFF000000000000FFFF0000000082
+:108300000000FFFF000000000000FFFF0000000071
+:108310000000FFFF00000000FFFFFFF3318FFFFFB1
+:108320000C30C30CC30C30C3CF3CF300F3CF3CF391
+:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3
+:108340000C30C30CC30C30C3CF3CF300F3CF3CF371
+:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D
+:108360000C30C30CC30C30C3CF3CF300F3CF3CF351
+:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB
+:108380000C30C305C30C30C3CF300014F3CF3CF323
+:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E
+:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311
+:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22
+:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1
+:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C
+:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1
+:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF
+:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0
+:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F
+:108420000C30C30CC30C30C3CF3CF300F3CF3CF390
+:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1
+:108440000C30C30CC30C30C3CF3CF300F3CF3CF370
+:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C
+:108460000C30C30CC30C30C3CF3CF300F3CF3CF350
+:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA
+:108480000C30C305C30C30C3CF300014F3CF3CF322
+:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D
+:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310
+:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21
+:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0
+:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C
+:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0
+:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE
+:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF
+:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3
+:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3
+:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03
+:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3
+:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
+:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383
+:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1
+:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363
+:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F
+:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343
+:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B
+:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323
+:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53
+:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303
+:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23
+:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2
+:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC
+:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E
+:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF
+:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E
+:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A
+:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E
+:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8
+:108680000C30C305C30C30C3CF300014F3CF3CF320
+:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B
+:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E
+:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB
+:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321
+:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5
+:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301
+:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB
+:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD
+:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB
+:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D
+:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF
+:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D
+:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59
+:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D
+:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC
+:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C
+:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A
+:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D
+:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E
+:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED
+:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58
+:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD
+:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21
+:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0
+:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
+:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0
+:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00
+:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0
+:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
+:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380
+:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE
+:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360
+:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C
+:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340
+:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78
+:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320
+:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50
+:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300
+:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20
+:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF
+:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
+:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF
+:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF
+:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F
+:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
+:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F
+:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD
+:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F
+:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B
+:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F
+:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77
+:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F
+:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
+:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF
+:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F
+:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE
+:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
+:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE
+:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE
+:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E
+:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD
+:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E
+:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC
+:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E
+:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A
+:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E
+:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76
+:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E
+:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
+:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE
+:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E
+:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD
+:108B10000040CF3CCDCDCDCD000C0000000700C003
+:108B200000028130000B8158000202100001023067
+:108B3000000F024000010330000C0000000800C0DC
+:108B400000028140000B8168000202200001024007
+:108B500000070250000202C00010000000080100DF
+:108B600000028180000B81A8000202600001828067
+:108B7000000E829800080380001000000001010030
+:108B80000002811000090138000201C8000101E85B
+:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94
+:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15
+:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005
+:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5
+:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1
+:108BE000CCCCCCCC4100200003030303034202029F
+:108BF0005050502070608050131313131342121200
+:108C000050505020706080500301020000000000AE
+:108C100000000000000000001F8B080000000000A2
+:108C2000000BFB51CFC0F0038A0F093230688A2055
+:108C3000F8C4E05C760686751C0C0C5BB849D3075B
+:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA
+:108C50008098850F559C871342FF015AC0C7CAC030
+:108C6000A0C1865DFF3A35043B408581A11C88D9AF
+:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE
+:108C8000D81D201DAB46BE9B47F1E0C1378D51F981
+:108C90005B0DA169012A7E0B4D7E1B54BE4A074223
+:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B
+:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F
+:108CC000A7D8030000000000000000000000000022
+:108CD0001F8B080000000000000BED7D7F7C14D589
+:108CE000B5F8999DD9D9D9CDEE6608096C20E02454
+:108CF000861AFB82DFE577A841878034B63CDF8A9D
+:108D00005AD3D6F6BB506C551456BF3EE1F56933C5
+:108D1000F941122262049FDAD61F2B554BFB6C8956
+:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58
+:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3
+:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7
+:108D500073EE39E79E73EE8DEAF3C3C7CE05388E06
+:108D60003FECD913028059D9A771F5BCAEBE99006A
+:108D70004721D2D35D0AD0A68009AC6C1D88A41F00
+:108D800094007F6A14565E2D7F3CDE5D097067D1CA
+:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C
+:108DA0000F453743314011A4B6E277F6937890F53A
+:108DB00037109C9C866876FC32F0D1B80015FAA179
+:108DC00022AA07C765F6CF81E47C18072083FDB38C
+:108DD000067A593FCAF3721AC795E5C5FA8B55D979
+:108DE0007EBC4F595721A389FEF01FF9B2E26438C7
+:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0
+:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A
+:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31
+:108E20009E8DA7AE668D9E1DCD3A6402000C64B384
+:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B
+:108E4000089EF6B02F5D5489502701187EFD881FBB
+:108E500009DF2FD1CC1CEDED279432FCD8F36578D7
+:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B
+:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08
+:108E80000B23BE4D84017C7A0AE282DE9F9486E940
+:108E900047D05931783F23E1BDA8C6971D97FD0DF6
+:108EA0001A21179F0462256EBEF1F225E2A90CE992
+:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9
+:108EC000F989A604C3C7DA66B05E73B4936360A67B
+:108ED00073E069B568678FA794B27A39FA076811A9
+:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28
+:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0
+:108F0000B68807CB21256DF990BF4B21FE207BF859
+:108F100035BECEECEFDF073FF5B303250E1BA74DA3
+:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5
+:108F300087517EB1769224F0A1F502F25FD1070A43
+:108F4000C05884CF844404605D7583369CFC015D09
+:108F5000F9539FCD775543F9EEE36C18842B14CE6B
+:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C
+:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC
+:108F80005CB7C758BDD942CECAD43FC911A8009218
+:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21
+:108FA000318E34B45F6FBB0128E1F811F0D8725DE7
+:108FB0008627A89F41789404E1CBFBDECFDEEBE16E
+:108FC000937F7FB265BF9167BC1E89F869A4F6AF35
+:108FD000087E19C29F79E8BA5FAC33057A4D383DF7
+:108FE000CB47367F9D281F9D349FB0E1495FE4E168
+:108FF000130B52B46E5835AB7BDAE8F925079F6442
+:109000009CF5174B63F83C9438F10B834721BED590
+:10901000393C65D34BA93F09D7F819D88328231EBB
+:10902000D87C97D9ED214EEB3584768EA33D9B1CE1
+:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006
+:1090400083E8DF032FEB4F73F627438587CF39DCA7
+:109050001B242EDF58FD0CE1D33BBE2211BC322471
+:109060002C1F6BB7598CEF955FF673BBE86FBD048F
+:109070004DBD61BE9E9638F4618324E484C6D799C1
+:10908000573EF991AF669C385F152AD7174BB9F553
+:109090000EB38A621746F2EB9D629FAD0F323141EB
+:1090A000B751D1FD74A9C445F742E15D7682F04E17
+:1090B0001C0A6F417C76A6E41B959EBCE104E10B83
+:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016
+:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B
+:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5
+:1090F00038EE730A85EFD191E103F804FB6BBD6A8A
+:10910000990AD96B0013009E6E79D5B2942C7C26F7
+:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC
+:10912000FFF996B75CE32B8C7F90D90A1DF7854237
+:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207
+:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC
+:10915000E3FEFE04F9B152AC97064977E9817CF64B
+:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8
+:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356
+:10918000D73F5DD44F15585FF2F175984F7FCE975A
+:109190006CFC816BFFD1A6713F88D9A640F09CA1E1
+:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44
+:1091B00084FC226B0012E837F92624EB7CAC1F6399
+:1091C000C74DF761BD238AA677EBC01724FB1E3C71
+:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C
+:1091E00083E45F493549EC59668575F4DB0C5425F9
+:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927
+:109200009326E9322BFFCB39736FFB0C6B35F0E102
+:10921000CE974EC37AD3C655B592BC3425C44F6998
+:109220005C35E5287B5E7C71561FE03F8B1D6566D3
+:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5
+:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4
+:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483
+:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5
+:10927000AEF4B72C65CFB004BACC9652715CA5F9A8
+:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE
+:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85
+:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035
+:1092B0004474DD3909E9621527397D40AA66CF2358
+:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604
+:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D
+:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630
+:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB
+:109300007B262ACC88DFD27C173DEDF9A12431ECF5
+:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE
+:10932000D1FE7603CA113FCAE1745B14DFD7C1B422
+:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C
+:10934000926D3437B745D93CAE2B87E9D8F7CE9725
+:109350001FE3DF2B607A8095773536905CED89FBD3
+:10936000D2814A82FF7CE4E79E461F3093078AEB56
+:10937000185C0EBC0662EEF2AE4626B066123ED215
+:1093800001293B7F852D33C4C746B32AE8DC57CF7C
+:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F
+:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C
+:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1
+:1093C000982F8DC6E716813F1BBF03112E5F3636DF
+:1093D000733F603E78367EEAAAD8707E03B5B1232B
+:1093E00081FE54B5B1270167E1332D9EBD09A79FCA
+:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0
+:109400008FB7FE785925793750C6BF77C45ED3979A
+:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98
+:109420007F3FA22D0DE7683F897DCF4197A532FF91
+:10943000FEF4CB81863B901F057E77BFFC13AD1AEF
+:10944000F1FDBC0CC8671BF73590BC453E4379B1B4
+:109450008BF1455F2DD27FFD2BCE755B5CE72E3304
+:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52
+:10947000EE157ED93DCD317A3EDD6CD07357730D3C
+:109480007DCF34C7A9FC54731D959F6836A9FCE3B2
+:10949000E6462AEF684E50F9D1E6267A6E6F4ED234
+:1094A000734BF315F464FC4BFCBCA13925FCC06B79
+:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B
+:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED
+:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B
+:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB
+:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7
+:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD
+:10951000B9BECBD47E64FE59D65589FC93F6C52DD1
+:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD
+:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3
+:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0
+:1095500001CC64C42ECFAF5773D877649F061240F6
+:10956000F69D1FED34477B75722A69E6D09F57F947
+:10957000E66F95593F8152E8C0786840C9E3E795A6
+:10958000F93E25A0F1EFC16A93ECB26230A6CB633D
+:1095900000AE796C5EF932F6FEE7421F765C089603
+:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682
+:1095B000FB18FBB9E9879126FC0EA5334798378F36
+:1095C000D7C8136737FDC660CF0B666F59CBDE86F1
+:1095D000AA9319F2019596927D9A0C19D4AF5997D6
+:1095E000B67CA518478338DA8972D884241B67AE05
+:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0
+:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110
+:10961000E905494BE2FEA9F8830C447F69DC653F0C
+:10962000D9F353948499C8616FFC4EE04BD2E34D5B
+:10963000DC0FA202CA877CF50FCAB6FFC972ED071C
+:109640008BA13F23231C311E6F82631719174E1DF8
+:109650000A87AA2492380EC6AB37B371DAC77CC624
+:10966000483AC6F948E67E2A2966123CAACEE1515C
+:1096700095B899C8C14703021EBB1F3B6E26C5FAA9
+:10968000A12F9C856F6D30D184FB256B8C4A786A45
+:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057
+:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8
+:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88
+:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A
+:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6
+:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C
+:1096F000B8364823C3DF21E0B7EB752A294DCF895F
+:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27
+:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331
+:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC
+:10973000BE8778FB7082FC5B5A38614055361EABA1
+:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8
+:109750005C92916A427ED22AD83A9286B6B39F49E9
+:10976000D1BEF3C3FFF712AD93328DD68964B075C5
+:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F
+:10978000477232D77A5921E0D116270CAD8A427838
+:109790003CDFC303C73A85EB834336FC568AFC564D
+:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D
+:1097B000DF26E02901A3857C990697B300171ACE0E
+:1097C000BC8B37C4F825424E314C11DDECEFFF2540
+:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF
+:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815
+:1097F000898411AB22559F93AF9E1070F42B228E5B
+:10980000665D3B2ABEFAD702E7F144962E8F09BA6D
+:10981000EC186E1E8F8A79F4C830F70DF4339E2E43
+:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F
+:10983000FC4ECCABD0F93C53209F1DCDD2E5393145
+:109840009FFDC3CDC751FF4551FF25519FFCE74701
+:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7
+:10986000AC776DFB2CBBDEABC80F5223D783ACDECD
+:109870006BCE7A605DD08AF6DB5A8C897E02E081FD
+:10988000F6AF3688766F52BBC583FDBF25D607B5C8
+:109890005BD73EBFD50A53BD77F07DCB828FEC7A84
+:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D
+:1098B00013CAE7A9BF217947B19282EC1F7F699251
+:1098C000F2F74A20D283FEC50E2545FE640C36A071
+:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD
+:1098E000237F6A005270177BBFA154A1F8C862257C
+:1098F00019F1A31D21252D0AAE827E590BF63FD604
+:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24
+:109910008BA23B91AF364E520DE4AB9D936E20BFB0
+:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E
+:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F
+:109940002D67E5BE96625D3A87E641705B3E48B49E
+:10995000CD74E42332B80371CAA7233FDC6D8D3C7C
+:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2
+:10997000FBDE59A792FD7A5B45D57C1C6F539D4653
+:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3
+:10999000E8678FCE519901CECAA5460BDA9B91D9C3
+:1099A0002140BF5349051F2F7206901FCA0F3D89E2
+:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0
+:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B
+:1099D0001EFF441910EF367DA33D83ED87CD638CC8
+:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493
+:1099F000582F5D60BD0CAF17800B87CDE78338CF44
+:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5
+:109A10007BBE8F362FF42ABFC80B9D0373785EE898
+:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31
+:109A3000F3F07E63FFB81B62987FD959F655F1BCED
+:109A4000913FCBC5FBF2353194779DE5E27BF98DF3
+:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5
+:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A
+:109A7000E6596A8AD540EB76B18FD66D008501AE86
+:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F
+:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9
+:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC
+:109AB0002517B47EFC3D05D64B17582F53583DB59E
+:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A
+:109AD000AB727D0E7F68C578BFFF139AABBCF613DF
+:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2
+:109AF0006C777B750E6F1FEC800518CF2F749D1C43
+:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2
+:109B10002F510CC89492BE4A0BBD95331E7E9ACA33
+:109B2000D77F959FC7CF6F53F420EE23FFD6E72949
+:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297
+:109B4000E47D438C9F7FF043288E768EB1506B78F6
+:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB
+:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C
+:109B70001E5221D158C9FA6BABF0913DA28447D057
+:109B80001B150EB995232F2FEB970213CF53D02718
+:109B90000360FE9B7CDC501C08EE08F4D166BA180A
+:109BA00053E54E07180386C493BEE212CF13ACD719
+:109BB000519E95064F75BF9751BF92791B1C2F1A66
+:109BC00045BF4A1FE5CB9CF27E478037087753BFDD
+:109BD0006C97547A7C6CB65F7F2C452F314F56764C
+:109BE000E4CBE1B908CA37F1C53394DF30214AFB31
+:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B
+:109C00005A09E3BA15579B7DC3F079331357E4F72C
+:109C1000AC586EF6D5E4AF3798A78FF99E39D64188
+:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775
+:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4
+:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82
+:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3
+:109C60007A12E1147AB26D047E1FD1EE51E3C95C21
+:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F
+:109C800035146F8F217E717F3B06BAA4FFC3D9873D
+:109C9000F2A52AF6BC8478585BB62836DC7CD90657
+:109CA000EAF0205D18897F16321F4179300C1C3F85
+:109CB000CC0507840BF37FEB0BE3C48783F65229B3
+:109CC00088FD98199518DF870457DE32737306CF25
+:109CD00043F897864DA49F6C6E01F457DB76936C26
+:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD
+:109CF00044EB87B7AB654FF939D56D0FB535EF003C
+:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3
+:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2
+:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D
+:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5
+:109D4000ED283B288FEFDE05682F770F96D93690E8
+:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9
+:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC
+:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB
+:109D80005AC04FFC477B576A6FB5617F414594E1EC
+:109D90009105EE3298084F50E3E505816DD43F8977
+:109DA0000036DEA7033FE0E34D11F96DB54B46C029
+:109DB00023F7EF5BAAC1FD5DB525143F52E3717433
+:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4
+:109DD000FFBA1941AF093846A23F4307F9D1EDF365
+:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B
+:109DF0005B7886ED09353927C0DA47CCDE4C252B58
+:109E00004717672C5ABE058E3B3660E7392669FD39
+:109E1000DB7856746E77ACF0D0D15FCAE3754171D0
+:109E2000FEA4507893AA1847F4030F37940F67AF36
+:109E300095257C68840DCA8BB18D21E19CE1E531CB
+:109E40006689AB5C5C37C1553F12AF727DF7EB1F83
+:109E5000777D3F513A5DE299C7A784DD6897CFF5DA
+:109E6000CEB3C07E0F1627560570DD34404D8AE113
+:109E7000F5CE2F3C44F80F0DAED385ED6605E58396
+:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A
+:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7
+:109EA000F96B9D67B45BF81D5AC96F0B152958E211
+:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE
+:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2
+:109ED00062E8AF5C77E64331207927E58C07FE3CEA
+:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126
+:109EF000876483EB21E535D4873E8BE7E3AB10DF46
+:109F000067A25D54C3FDD521F19DE85899AD3F4846
+:109F1000574FF9EF34AED77F87491B0CCEEF159B17
+:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2
+:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40
+:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A
+:109F500048C00DDA9163A5E3ECF93DA417CAE39B71
+:109F60005280FA7BED990F35215E02997F0283E1E1
+:109F7000ED1F27A5C040FF6F80C315B8AC07483E52
+:109F800057F7109EBDF85A3788F7B40BEF3F0970AA
+:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB
+:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4
+:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB
+:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A
+:109FD0005B19C76E22B9DB3D6923C533D7556F26A0
+:109FE0007BF228B323F0FC747765EEF69DCD3C3F01
+:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D
+:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F
+:10A01000FC27471EE0EB72947C8766213FCF50D629
+:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7
+:10A030001E70E64BBE2FF82213E0722658C1F9A31A
+:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B
+:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E
+:10A06000FBF42F173ACE7BB52B694D47F86B364A78
+:10A070004EBBF61B6632A439F627A1D805BF5C8813
+:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2
+:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D
+:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9
+:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17
+:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8
+:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2
+:10A0E0002F200FDE87788C1B590CCF39F65743F1A0
+:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9
+:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40
+:10A110007757703C77D66CEEAA72E2B966D7DE4A02
+:10A1200003C7E7787E48E3E773438867079C5E3C94
+:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A
+:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920
+:10A15000D1FEE94E29AF5EBA442B402F758A757443
+:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5
+:10A1700083F66F0B501FB27ACBA89E9EA27DF06033
+:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5
+:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F
+:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2
+:10A1B0007F663B2696F4F083D2E3927B363F942F62
+:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8
+:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E
+:10A1E0005928B94DE376209D83B0BE51946E636DBE
+:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D
+:10A2000070947A699FB0D73AC6301955CC9EFE44F7
+:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B
+:10A220005182FC6BEDB1CFECE863B4331B7B20971C
+:10A230009C4F86923FC7F9A9BA65927A15FE917C28
+:10A24000FD9626AC9D7B6792DCEDC7BC461072186C
+:10A250004D6BF4C74519DE0E69E4C288A37FADECEF
+:10A26000626B3ECAB10AC62F587F5CD33E29992B38
+:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E
+:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29
+:10A29000A638F06ED3E90E2971E179284FE7713ABB
+:10A2A000158F924E03824EB098E7A19E7BEC5C8D99
+:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7
+:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E
+:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663
+:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A
+:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C
+:10A3000056CBDC7F7E67D1D7280F618D15D003A592
+:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687
+:10A32000B7566FC5FA9B0012E8976C9997A2787F91
+:10A3300054D1F4D638C2919A837A225A6AAFCF1F89
+:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8
+:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35
+:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9
+:10A37000875C65ADA2C455564B270C1BB7F819FA7C
+:10A380008966E17CFA208E70E6C9179E12E476B6E3
+:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1
+:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E
+:10A3B000D5A2B955BD180782319C2F304FD0C90F97
+:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526
+:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB
+:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F
+:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451
+:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D
+:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF
+:10A4200019CAA1FFA67DDBCD75BE46944306F45242
+:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B
+:10A4400047A25326817A61435CF1A11CF99BE3C3C7
+:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF
+:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4
+:10A47000E3C5F757C1CBA0BED0922B916FAE88A990
+:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694
+:10A4900081F126F8969FDFC7847ADBA15FFE180C56
+:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB
+:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054
+:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51
+:10A4D000F919DEEF2B6448E53AB72885346167F651
+:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B
+:10A4F000D13A8EEC1871AE61C5966775C501E70A51
+:10A5000085A9BFE943E763E37705AAC91247FBF4CE
+:10A510005E577B6FBBC1FE447B66B7F9430C3E536D
+:10A5200049EDC578B37D7E43DD323F436A330FDCAE
+:10A530008C8E270577A1E7388E3CD0D681FB6DB491
+:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5
+:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5
+:10A56000E4A3CF79A12087E714F3D759210F7FF512
+:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29
+:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A
+:10A59000EDF3B5637C95E07C95899E5D085F097855
+:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587
+:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2
+:10A5C000B8D74AE4B54306ED8940A949767448DC1A
+:10A5D000CFA355BBE5A612739F9B8835253276BF66
+:10A5E000E8BF0CAC5169DCC1F8711832C12896790A
+:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06
+:10A60000F65311F96A98CB4BF7B2C1E747C86F719F
+:10A610008F13BB78F8FC1A6F7D082BC62107DEF379
+:10A62000B753E090639FB341DC2B6AE3DFDCB29465
+:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724
+:10A640004E7CCEC573BCD375DAAF55F0788B257DC3
+:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7
+:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81
+:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D
+:10A6800032FAF79F098DA37ECEE9EF931738D6E50E
+:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6
+:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1
+:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656
+:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961
+:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF
+:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A
+:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47
+:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D
+:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B
+:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60
+:10A73000B55B89874F049EBCEBBBAEA711DD08510A
+:10A740004836CE9708BDFB5D7E92035F6FF932E617
+:10A750006B2C0D9B12EE65A12FF3249B5789A92525
+:10A76000F0DE98E2FA1E6932E677C4781EF937AF58
+:10A770007E2DF3322BDFDC5444655D379E5B84F81D
+:10A7800028D5C99F72337A5C48407F732DE627D065
+:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4
+:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A
+:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E
+:10A7C0008372A8C49367A22F74E7A5443DFD4F454B
+:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708
+:10A7E000FAF434D607630CE60D861B9981C4E83968
+:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA
+:10A80000A7D350C4E5D584AB6E97709F7134CEB892
+:10A81000621A96DFCC997FD52EE4C76059DF45F2E6
+:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A
+:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD
+:10A840003378D65F8EFEB1E56EBC8F962ED714712D
+:10A85000793512FD4F761C9B6E43D7478BA0DB03E7
+:10A860001417EDAE195EEE0FA5DB36D277E1DADC18
+:10A87000F9BAD715492E796C3F3548419CF1892C9E
+:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9
+:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329
+:10A8A0001940FE3601ED24661E111FC99EFDDC46CF
+:10A8B000C14741789EDAB35560E9A45752A03BF2F4
+:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E
+:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F
+:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D
+:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3
+:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C
+:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9
+:10A92000E5ED741C90081F659313F7E3FE0C7E257C
+:10A9300003CFCB0413F3F656FF74167D1F1A574846
+:10A9400054225DDE3A50A4B75616922F9948B6B0FD
+:10A95000FAC68140BCD520D5E2D3908E7D12D1516C
+:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE
+:10A970000E96158BE29B5DC674CD294FCA42C95F06
+:10A980001639E3F622AEEBF5AF07C3EDB16760F41D
+:10A99000F18FD2F120E2F29F5F84F64B17AE019E59
+:10A9A0001747797A5DE5BCFC46D1944518DFE98A02
+:10A9B000F07271F8C8792D246713E4FF5BC3180E99
+:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791
+:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0
+:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750
+:10A9F000637C7A62D2CED774C74526A0D660F39B1B
+:10AA0000C408E3677838ED626845B6A9BCACB71CEA
+:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939
+:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829
+:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA
+:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF
+:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC
+:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3
+:10AA7000B9A86866D719182F7A5EC61505153D3B2B
+:10AA800025B4E7EDFB2010AD174FE5F3C579058040
+:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7
+:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768
+:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9
+:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC
+:10AAD0003D771D567112E33103FE5417CAAB0DFFCB
+:10AAE000E883CD34FFD1E937454FD03D7A15297D34
+:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42
+:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A
+:10AB10007D678CEFABED7D783294BC3CECB0CF75AB
+:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4
+:10AB30002B4F1EF31D11AE97A718AB79BF9386F765
+:10AB4000CBDA78F9A04B16BF1721134438FC8C914F
+:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3
+:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362
+:10AB70004193CDCC3AD41B93533E40FBF4F688412D
+:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7
+:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396
+:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06
+:10ABB000EBDD953758680F6CAA0013F5B8FF46B661
+:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64
+:10ABD000D6255263ADD140F6C3D1182F072AF839D4
+:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C
+:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96
+:10AC000053EB1AF310DD4B635D033CDE69C7A515FA
+:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB
+:10AC2000C0F891E44C17E613E4C0676798E3F30EAD
+:10AC300021E706FCF0298A97B4F8E83E176FFD6516
+:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45
+:10AC5000977FA3E20395E6B348BE1174A43BB39378
+:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D
+:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190
+:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A
+:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2
+:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3
+:10ACB00049FCFE196FBD83C25E64F620F1CD268B80
+:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF
+:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3
+:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F
+:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686
+:10AD0000AD805E4ABADFD858528971A15B6F540D8D
+:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7
+:10AD20009A781EBD223ECEE8769CF72EAE7894CE61
+:10AD3000C3DFFE54000275783FA9E7F7D938E9234D
+:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB
+:10AD5000308833388F220B0CBA1FD9E8253BF4A872
+:10AD60001544DD0A467D2FD72BED2178308EF7CCA8
+:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273
+:10AD8000725175A29BECF369DBF55CFAE153914AD1
+:10AD900097DF24E4895369C91B9AB89F56852939DE
+:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8
+:10ADB000F2C79B42DFE8D97D32F107C92E468F707A
+:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355
+:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C
+:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F
+:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25
+:10AE0000632CEB03F37AD933E7BDD3078B785E78F5
+:10AE10005751624984F27281EE195E27E4C679F2D5
+:10AE2000CF8298871504A6E7908F16FBE0C11C74AB
+:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5
+:10AE40007DA276FB83C20F50B81CE6F39D620ED044
+:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64
+:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4
+:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408
+:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9
+:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2
+:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6
+:10AEB000417D99562084FA7C008D4966C73D127EFB
+:10AEC000A403F35DFCB5695064DCD70338EFF737B2
+:10AED000602FD9597EA687C96E52FA5A502EB5D71F
+:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321
+:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9
+:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E
+:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2
+:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB
+:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5
+:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000
+:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975
+:10AF600014F9E71DF0917FE81DD81F9DE180676708
+:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A
+:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D
+:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056
+:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264
+:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82
+:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6
+:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD
+:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B
+:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A
+:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2
+:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5
+:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB
+:10B03000BFA84F8244AEFB77CA42C931D15943EF12
+:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121
+:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526
+:10B06000183F565CFC5184F11466F7AE12F6655138
+:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12
+:10B080008533329E6BAD73E73FDD59F44592BB2BA0
+:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C
+:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5
+:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F
+:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4
+:10B0D00019E11AC4838F9FA7D559D931CF233D5287
+:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F
+:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545
+:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783
+:10B11000E10864487FA555D45F576D9773EA77CCF3
+:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503
+:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB
+:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D
+:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D
+:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065
+:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0
+:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0
+:10B19000055BBF17453CACDAE18ED3ADD8FA610749
+:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74
+:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7
+:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0
+:10B1D00053B8C35DB5C32DF7566D799DF222741F28
+:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7
+:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165
+:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB
+:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360
+:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20
+:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC
+:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85
+:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545
+:10B26000E387B3AB905FD301275C69A2ABB143E244
+:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA
+:10B280003FEAB995BD1FAAB83FD963423FE267F7CD
+:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496
+:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF
+:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7
+:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA
+:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA
+:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3
+:10B2F0007930127EAF90385C5D51F3A728EF0F6F65
+:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC
+:10B3100017110FFD4F0674FCFD12573DF922ADB316
+:10B32000777FF89C6A505C07A2D26C5686C19FFD5D
+:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19
+:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B
+:10B35000817A335D46F35E99E6EB61657AE7C578FD
+:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF
+:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B
+:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190
+:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3
+:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61
+:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC
+:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38
+:10B3D000B55714485A132BB3F01E46FB82C17BF8B5
+:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5
+:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7
+:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341
+:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A
+:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F
+:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2
+:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839
+:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35
+:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102
+:10B470009F67FBFECF503E90DDDF631E7CCE79DE02
+:10B480005A1061FDCDE94BCC948DA172A3EE00DB87
+:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57
+:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07
+:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688
+:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B
+:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32
+:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182
+:10B4F0006F18129E2D99DB674CC7F917432FE0791F
+:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930
+:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155
+:10B520006B7B092F858CAB9DC0B8B79E8271C327FA
+:10B53000806780CD058DEBCDB3F28EAF4EE379639E
+:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9
+:10B55000A5C586EBF7958192A17BABB3791769A955
+:10B560007326C6EF06CF1B2734C77963F69DCE1B23
+:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0
+:10B5800080F705219F0215A918DA5F9D79E211AFB6
+:10B59000083EEF8C346838999DFAF4E2BE61F48677
+:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403
+:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D
+:10B5C000379B80D61C706E17EB07EB5562BD581287
+:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569
+:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD
+:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3
+:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69
+:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF
+:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D
+:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545
+:10B64000316F425B73761CCF6B876AF8EF61D8303D
+:10B650000FE26106DF863CFCF13F595ADE2D008087
+:10B66000000000001F8B080000000000000BED7DB3
+:10B670000B5C54D79DF0B93377EE3C813B30C0F082
+:10B68000BE8310D1623A28A2363E2E0F0D3E62468E
+:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD
+:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C
+:10B6B000358FF61B4C74ED635B626CE2F6D30613B8
+:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90
+:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2
+:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8
+:10B6F000840C151342F8B08DB808D95762B2433A9A
+:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907
+:10B71000553322F9CEBC442E48FBD999F73819A6E7
+:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC
+:10B730009287E6E55B7C561F4D5D24C3544ADB953A
+:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9
+:10B750003220ED2C17324C3A787ABED04402749CD9
+:10B760008E72612DC0690D7F9E480991F2274513A5
+:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977
+:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB
+:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997
+:10B7A00037FB06AF92FC69341FBE2A73302F0F9906
+:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF
+:10B7C0006112A4E327160D1398BF43229249C27E4B
+:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA
+:10B7E000FE608E09A719E649D7D1D15CEA2F48211E
+:10B7F000C4D63CDF5F40D725811F2222ED2741625E
+:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5
+:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2
+:10B82000E2092A30FFC4D90C2F5A79A2344C643A69
+:10B830006E2261F324A5443E4693845285C0387439
+:10B8400048593F9F07547A7C409D0FFCC969588F27
+:10B8500010FA29415E74D57C2BE479F256112BFF46
+:10B86000D0477041DFB2A979F3D87CBCF94C94EE93
+:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06
+:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1
+:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD
+:10B8A000FCED55DBEFFD2F86BF513C71A63540877F
+:10B8B000D178D4EA578CC2AD205DD276847C0AF26E
+:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82
+:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1
+:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6
+:10B8F000139F891CA328ED9AAB7861BDBA9153229E
+:10B90000FDFFA33809EB774A8289FB244DCF2C4CED
+:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2
+:10B92000EC8D21DF4EABF335373B671C9D111F8F2C
+:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7
+:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974
+:10B950001FF2F9609C441CC7A5C2E52A349156DF4A
+:10B96000C4701E57E98A6FB68F0B270F70C69033CD
+:10B970001A9CED00A7273E9CCE9C0AA453BED985F5
+:10B98000E30C8A125B0F4B936D239D9FAB35496A85
+:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94
+:10B9A0005450B8F969D309A1FD745C9A659B04B43D
+:10B9B000DFDC43023A391F74042F89B43F5E0C92D6
+:10B9C00020859377293280F1AC4A07DABA91A264D4
+:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B
+:10B9E000274E8B4CC462E8C7248740DF416773222F
+:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C
+:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E
+:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD
+:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42
+:10BA3000EFBCA2E115FE15133CEF38917633809FE1
+:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903
+:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7
+:10BA6000416124BF870F213EBB5DBD5DF9749E8A95
+:10BA7000DFE42FA4EB45B24B0D788A4E096965725D
+:10BA800070CCBAAE96C2B47D779189B702BD1690DC
+:10BA90009019F092ED41BED4D635E8607463F13070
+:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B
+:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2
+:10BAC000C1D499509304F8232FEF22D23400C3C875
+:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E
+:10BAE000AF68F6103F48AB660549A89BC37CC0967B
+:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11
+:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD
+:10BB1000EF68F83447C6D3E3C7047AE78C25748C02
+:10BB20008BE02941FCB47790DC089E9A6C208F3A18
+:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE
+:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA
+:10BB5000CA05536C797E48956B5480F30BE9380B1A
+:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7
+:10BB70000915C815017F15E0AD6A4D00C882085946
+:10BB80001F7C2288F45025025E3865B2E943E78DB8
+:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE
+:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F
+:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E
+:10BBC000190B69EA02BC93736602765A5A3803CBA2
+:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2
+:10BBE0007F70ED5D7ED443D76F23614A3728CB4009
+:10BBF0008E65CB61B0A779512A374B30CEA336F092
+:10BC00006F3ABD354984D9DB24961ED8E20EFE007A
+:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B
+:10BC200022013BC07E810B812E3BB0727ED77029F2
+:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B
+:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F
+:10BC5000871FF0D05548979CF6F3BBA79C2142F371
+:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E
+:10BC7000823D65FB603FFA8736D53F247CD32C5844
+:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902
+:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F
+:10BCA00086293D99148E7C48E9D3E6DAE63D25C124
+:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4
+:10BCC0006712726431D8919D206FD06E250A07EB00
+:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6
+:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1
+:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754
+:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789
+:10BD100035C8CD4E4A975609E87097C14FD6528D17
+:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4
+:10BD3000A707E9D1E609A01D1D5D7F450AB363345D
+:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3
+:10BD5000672D68221CA5138BC8FCE189E6110F3EF4
+:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75
+:10BD70002FC5F96C71CB93927578F4E451BCC798D8
+:10BD8000CF5792D97C3A027581FB69BF72BDA4205E
+:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448
+:10BDA000543D9E983DA2F5AF704D8316E0730F6D24
+:10BDB00047BFB6939714587A8B2764E0EF2FA604F9
+:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05
+:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE
+:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC
+:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B
+:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910
+:10BE1000AC959761BE8763E58F242F58AC14E37C03
+:10BE200050EE754D30AE395486EB77F3FDABF25BD7
+:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9
+:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC
+:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621
+:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324
+:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3
+:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C
+:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A
+:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070
+:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3
+:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41
+:10BED000991DFBF79D9982FCBA4B647C34A11CF23E
+:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B
+:10BEF000F9FA693D5F533DD90BFC24902A8570A067
+:10BF0000871FF0333B4451E569E05832DA81016C18
+:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC
+:10BF200046DF22F361DB30F2B5BC3CA38C10170373
+:10BF300081ECF287492EE025C34C6D31204B818482
+:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7
+:10BF5000110CF3E02F382F996E05F8587D4D0FF135
+:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6
+:10BF7000B6E30793557FD0497240EFB5B79C206F69
+:10BF80005B22FDF05171252DD5ECF9875358DC6209
+:10BF9000949E2446DF2F503F1DE8B1E31766D21B65
+:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4
+:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B
+:10BFC000063CE635271BF23E25D3507F5257BEA1D3
+:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD
+:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C
+:10BFF00049F86E43FD1967361ACA670E3D64289FDB
+:10C00000757EAB213F67F8AF0CF5BD41F1E409E067
+:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7
+:10C020009BCFEC63D0B7249BA8F631554C694057A1
+:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC
+:10C04000FEE50B16C91BA15DBB68225E9D1C911607
+:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2
+:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C
+:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2
+:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A
+:10C090006B74FF90499E9CC2FCC3AA731E83DF830E
+:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37
+:10C0B000FA3756D3879FB871FF269ABF684A714EE8
+:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60
+:10C0D00096F810CA3B2A17CB530C72315005F31354
+:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE
+:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E
+:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD
+:10C11000447510CAD9E8FEA95D7537C2E965F4A473
+:10C12000F9439ABF65A3F203FC2B9B44105F568A28
+:10C130002F27DA478FA27D49E721817D64F550FBE7
+:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6
+:10C150004FD5972187DC94921ABFFF17E3EC479DD8
+:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E
+:10C1700056203A3ADEFB125B77DA2291D3F62F246F
+:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8
+:10C190005EDD37BB06DB0993780272266178C33215
+:10C1A000D093A494C90985FE03F4E62836CA0D5B32
+:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2
+:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD
+:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6
+:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C
+:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA
+:10C200006736113FE067F670980469FF3FF4B0F5B8
+:10C21000C8F48738B0CF332F873880F3A085C58521
+:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896
+:10C23000F78A3C17F2E9671713A48F21EFC69E72A5
+:10C24000D857984BFCC03F2E0F4F32217FDE1A4249
+:10C2500079E21F51A8AF4392E944614DAFB490E930
+:10C26000F751FFFDDD161BA6D75A444C2BF38A0766
+:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A
+:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0
+:10C290005404F184CE93FF8971CD083D53AC7901EC
+:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49
+:10C2B000B404FF7103C413D70AFE6331F837E9E50C
+:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E
+:10C2D000E2FD93C8FA15B1F854C513A530B340E98F
+:10C2E0003789910611E686DA1241AFFA493F059B7C
+:10C2F000583A421CEC8790074509E245D9B6D02050
+:10C300009467D78BFE36AC4F705F415B278B9D04E3
+:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5
+:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72
+:10C330005D3CD64562EF0BFFCB6D15160FEDF77622
+:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC
+:10C350001393D3C15E6EE663DB996691AD0FC47F24
+:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A
+:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4
+:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E
+:10C390007E6C26B0CEEF7D7FD669589431F36E392E
+:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1
+:10C3B0002DE3510885101F5A79E387AF9541FC4A58
+:10C3C00068FE4DE6650AAF52418A9A204F0D68E635
+:10C3D000876E591A1E076F07D31ED802F1C2509BF1
+:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2
+:10C3F000DB4676727489B9F4779754D1FEB6728AA7
+:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B
+:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6
+:10C42000652A87ED3F0DC11900D2CE052A13207E63
+:10C43000378D20BDDF76AD290FF695DD44C8073A6C
+:10C44000B498CCD8CFC84567A817E56FD32C9043D4
+:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8
+:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90
+:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA
+:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7
+:10C4900022627AA2C58BE9F75B244C075A8A30EDF9
+:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729
+:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276
+:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5
+:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E
+:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9
+:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5
+:10C50000D27E68DEA9F643C72F61F567637F745C4E
+:10C51000CCC7E8B784C173A224163CD1F5A9956FA6
+:10C5200026548F88F0BFE0EF59240EF75138123EA1
+:10C5300006F2F882B51CF4E79E12926FA2FACD9231
+:10C540005AC041FEA966229A4BA8CACBA8D9554E1B
+:10C55000A09D8CDF95557CE8980FF513F6ABE9A705
+:10C56000E4EA30EA9D243FC937BB69CAD381A753A7
+:10C5700054DF4722E70D503EB13CAE076D2756937E
+:10C58000C8790332717DAA5FA2CA63D3DB474D210C
+:10C590003EA63FF771701EB1835F4B7DFD7E924BCF
+:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A
+:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878
+:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0
+:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498
+:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055
+:10C5F000BE06393D7784E9F751BDFE5B261F357BCA
+:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C
+:10C6100008920ADA3EB17CEBCBF09D9418BF270854
+:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2
+:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A
+:10C640001B3E4C12253BED27F3A54B02C0D1611ACE
+:10C65000168008473CCD4B786A0775089A9CA486DB
+:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD
+:10C67000AB54578ED63FE8086E813CFD936D54AFA6
+:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E
+:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA
+:10C6A000349FC86DE93E930379ADFE966E85B6BFA3
+:10C6B000EA61E700882BE803B9379A17693E41978A
+:10C6C000E7599ED858DA77F23F05D0431D6923A772
+:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1
+:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2
+:10C6F000D7724644431DFEB475A176EA142FC17863
+:10C70000B210E242F960BF15F798D07EDB4E49B017
+:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51
+:10C720007FA650BEB34E0775651919D6FB5BC46F63
+:10C73000027811E5F01FE57F2F01FDD4375B714CC6
+:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF
+:10C75000877AC2772663C73768FE5A7F4A2FF81B4D
+:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4
+:10C770005BCDBB8DF976D59EF4BA157732FDBEF947
+:10C78000C4815C3000AF1E9B857EE4660D1E720086
+:10C79000E1B93A3827E9363ADFC69FB2B866E340D6
+:10C7A000C912987FE31E13013F6EF300A5271D7F7A
+:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5
+:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C
+:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F
+:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED
+:10C7F000ACA599185F5282433967766F43FCFF6B93
+:10C800003919B1BA119DB8CF9907FF47E19B2CCADE
+:10C8100015505F5C465D22A053217012EC10A5C23A
+:10C820008671D20A711996E7AE21A66E0ACF112938
+:10C8300039B99536B517C826B053F2030E8C7F9AD6
+:10C8400013AA76803F7AEC1CCB47D6E912E2C55199
+:10C8500014EAB7D17E6E71F122F8226966D906EB2F
+:10C86000467979E85829F00BB303942F1663BCE797
+:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0
+:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3
+:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5
+:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5
+:10C8B000525FECF666209EF36DB4FC737FFD42B7C9
+:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA
+:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7
+:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5
+:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A
+:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1
+:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0
+:10C92000F81AC93161F922F3B322C407AC53781362
+:10C930009EE5214D01D0CF7C364F58BCF7B03C4529
+:10C9400082B029DB1FE47A56A07F682FD2ED071250
+:10C95000F0638DFB877C54BED03A9C61A27AD87379
+:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C
+:10C970004D6572E6D18072BB45021A1B66E75649C7
+:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F
+:10C99000B23D2E938AB749BBC305D45E763D27824C
+:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623
+:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440
+:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0
+:10C9D000E9EB4BC240378373EE043F5000FEA59F46
+:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14
+:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0
+:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1
+:10CA1000719FE10349EB40DE9E63763D900BC63982
+:10CA2000C24F7010E778DF16488279EF771BEDBFB1
+:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0
+:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D
+:10CA5000D61ADC2683BCB21145117571725BB631F2
+:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1
+:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864
+:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1
+:10CA9000431F0F5F379390EE9CCAC3FC8800F37965
+:10CAA000F8BA80DF897738B115F66528C175C33AC1
+:10CAB0003EFF5DD44B0ED213860373568853E8CEE7
+:10CAC00085122F3F324AFFF911FEC07D752E067F79
+:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035
+:10CAE0003CDFAB242360871232BC08F8B7B1D28197
+:10CAF00071EA87498FCD06062EDF23EAE3C58D0351
+:10CB000097123794E23E960476F0C32F951BE254B9
+:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B
+:10CB200014C118B2507FACD1D673C69A1FA96FB783
+:10CB300004952CA0FF975AE52CFAE95B00279CABE3
+:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76
+:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3
+:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF
+:10CB700001BF1D8EC01566B41399A7F64E47B24685
+:10CB800037CDDDA0FF0E0A11B908933DE860F9E446
+:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99
+:10CBA0006ADE43307F50E8413F41F9BE5502380FFD
+:10CBB0003A027EF007951D5324D02755E92E9C8715
+:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5
+:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62
+:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1
+:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C
+:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B
+:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E
+:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40
+:10CC3000F471C7498E33CE0C9413F1C72953E5081C
+:10CC400051E3493C9E33D3F824BEBC30C671A3E502
+:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32
+:10CC600050A87F91035B076F85F5F9A36AF716F566
+:10CC70001D3809E47745945B5353E13C957C1CD205
+:10CC80009BE59BFA3436DE5839C6E20FDB1E945022
+:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B
+:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC
+:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F
+:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262
+:10CCD00095DBEC542E1BF95606BEE57D64D40F029D
+:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF
+:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2
+:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9
+:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F
+:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8
+:10CD3000172ACF023BEB4122C139E768BC27A9740F
+:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA
+:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE
+:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36
+:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F
+:10CD8000B65DCFBCACCB5B4492A5CF97846D599771
+:10CD90007576CB8C33A2213F73C86BA83FEBBC6484
+:10CDA000289F335C6428BFED8ADF909F3732DB50C9
+:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525
+:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7
+:10CDD000867A4273CA77C07E59F0C1021BF8173BAE
+:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88
+:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034
+:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E
+:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91
+:10CE2000FF2B42206FCD96F15C9BBDD884E7067640
+:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190
+:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2
+:10CE5000CD15C27B3E8353767A21FFA505DFF6828E
+:10CE60009FD135E5112FD04F67CE570DE7F21C0546
+:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98
+:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902
+:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A
+:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C
+:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F
+:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81
+:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84
+:10CEE00079156BF3F2AAF7283EA6793DF5179E5700
+:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E
+:10CF00007DF1F92F69B6F19C5282DFE807E417043E
+:10CF1000C63D7F745EC54F3C7E5D635152018ED726
+:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D
+:10CF3000C3792D0EDAEF48186F1DD606CD063827B7
+:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9
+:10CF500052EA39038AA7FD105FD6F036669DFF4C72
+:10CF6000788A476F378AA7EEA29BC3D344F49D9A71
+:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98
+:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7
+:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2
+:10CFA00007D2E915900E27734D6717839FBDD88C64
+:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990
+:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145
+:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2
+:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6
+:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04
+:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47
+:10D01000C309768637761EA0EF7166B7F701BE6941
+:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056
+:10D03000BEE665F1F001416AC47741562EDB0DE78B
+:10D0400051CEAD727310D2D0E038A6AE67595D6C88
+:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C
+:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5
+:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D
+:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955
+:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0
+:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80
+:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741
+:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD
+:10D0D00019CE39DC59499A707C5E427852DEA4FE42
+:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20
+:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464
+:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0
+:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A
+:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9
+:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8
+:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D
+:10D1500097ADB0482E289718DDA970F409C19C122C
+:10D1600057044F71E58F8A9F81F3413CB7B1BE9957
+:10D17000C373C7C5DB19FDADDF3E686AA4E911952D
+:10D180000F57C03E93AE3F77069B5F5FAF2317E01C
+:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D
+:10D1A00010B71BE6881AE7332D87FD8661755FACE3
+:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2
+:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7
+:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2
+:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B
+:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B
+:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4
+:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E
+:10D22000B6DF3237433DA71BAAD884FA4AB14A7801
+:10D23000B65885C7A3AC467C7EB8948890BFD32AE5
+:10D240003D0DF0DD556B8E92C321EC67FD32A76179
+:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE
+:10D260009E137F80340970FEAB8E28F3912F896462
+:10D2700001FA3EA7E24F83EF1C91136682BC683629
+:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B
+:10D290001EE1526DCA72887F2B018B1F8E375D6A2B
+:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19
+:10D2B000AF5501E37AF5093DB8FFA75490A66394F2
+:10D2C000CE267FF9F2DE59347F36642A61E7DCD856
+:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF
+:10D2E000637DE56FD8BCD6D58516C296D83D877AC2
+:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5
+:10D30000C7B707A2E9E996271D867CD97922E07B79
+:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D
+:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B
+:10D3300090C5D6637D3D17539E1FC84A60E50DB169
+:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A
+:10D3500013118EB73B56AF83FDFB2B51F655452677
+:10D360008343CA64E72BAFF6BED09106F4B09313A3
+:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6
+:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8
+:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837
+:10D3A00063077D04FF0BFBAB1404252919D65D79B7
+:10D3B00008CFC5F43A44760FCA3F536F577F43A551
+:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F
+:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB
+:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887
+:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7
+:10D400005FA904F3ECB93596BCD5E4F22F55B918F1
+:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184
+:10D4200059D7648447E38F2BA13607BCAB45479F90
+:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03
+:10D4400074F2AB66338F72EF2887F1E95F353F9155
+:10D45000182B6E153DFFAB264A0F401F4FF3287F58
+:10D460000AEB379C4C9322F4F87F543CFCA974A837
+:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11
+:10D4800071E28F07326C88BF0DBC28C0FED1810CC1
+:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6
+:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C
+:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6
+:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B
+:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90
+:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7
+:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC
+:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF
+:10D510002593E1E35E3E847299B433FB99D8283EAB
+:10D52000A85CBA0493007CFC35C7CE77F30141FFB9
+:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87
+:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C
+:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58
+:10D56000C23ACD8CCC2F459DDF05C7C836D0179465
+:10D570006F4C78BEE47533C275F5ABDF6C827AE22E
+:10D580005417DEF7423B96E6FB9627845A75F13A2C
+:10D59000CDAEC9F7337EA8E565835DD890E933D871
+:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB
+:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9
+:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794
+:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B
+:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB
+:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9
+:10D600004A267C1FF2754667D17222BADD285FC4B4
+:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5
+:10D620003F18539F935357817FDCAAFAC7FBACF591
+:10D63000BD31E0F566317CE6178C9C027CBFDFC013
+:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3
+:10D65000685EF34FB6B3F1A2C779575DB751FF4487
+:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1
+:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF
+:10D68000FCAF08C17D73281C579798FD0AF08B8961
+:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53
+:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1
+:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D
+:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA
+:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A
+:10D6E0001F295FF851BE211FF7F53AEB63F9298333
+:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F
+:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD
+:10D710002140BCE8FED1781141E7429C9A7D04FC8F
+:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9
+:10D730001FACA933FAF577D51AE5C73BA1FC513DDB
+:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F
+:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353
+:10D76000D0F581B496344D7B81C2F3CEA19509608A
+:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A
+:10D78000FC7EED67EF00727943689A164BFF44C741
+:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82
+:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD
+:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90
+:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D
+:10D7D000619CED84403CA54F50A6EACF5DA5643323
+:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0
+:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC
+:10D8000015F4A527A22FEFB4FA1F043A202E09CB56
+:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA
+:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E
+:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13
+:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D
+:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC
+:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6
+:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5
+:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3
+:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7
+:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A
+:10D8B000B55EF4386F46ADCF183F224EDC2E299B63
+:10D8C000E13718276E9794CDE2766709D38B4AC863
+:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512
+:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E
+:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842
+:10D90000EF15822055E307456619E3D4E43176BE6E
+:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4
+:10D920006CFFB76DA05F353FFE2D8BFF411667661C
+:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE
+:10D94000FF6AFC71A2F518953771D6632279132FFF
+:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18
+:10D9600034AD11080F78A859CEA19F5923C84B3167
+:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293
+:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80
+:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694
+:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD
+:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986
+:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E
+:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F
+:10D9E000A335E085FB78F76597EC83FB786969F2EE
+:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33
+:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891
+:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763
+:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D
+:10DA30009FABE51F4B84BCC74922FB4CB309B144E3
+:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A
+:10DA50004D95708FB3ECCB1DFB8AA710326B59B973
+:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F
+:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D
+:10DA800028E79467F655BBE13EC2F06920CB879B3F
+:10DA90007B6C69867B098A0CA68970A23C9C85E018
+:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC
+:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB
+:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1
+:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF
+:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3
+:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7
+:10DB0000268433D5CCE17B26690E123C4ED3D41447
+:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3
+:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9
+:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4
+:10DB40005D6D277F13DE7B19189A9A0F767565B67F
+:10DB50006488CB940DD558E05CEAE51C554E48AC82
+:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE
+:10DB70009D7F65E7B22F41BD86210B817388DB8EC7
+:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674
+:10DB900073E60D70DE7D06F4F75301CE37423FE0A9
+:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A
+:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B
+:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2
+:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA
+:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3
+:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC
+:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC
+:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA
+:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4
+:10DC3000C03CFCE169FA73201AFCB753D981E7496B
+:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15
+:10DC5000998BE5654327059867431C3EFD650E3BA0
+:10DC600027927E3E9C08E703966633FD35D03FC37E
+:10DC70007E1BF0C53213E124366FB033CB34F94A42
+:10DC8000DEFB590595AFE9A3792A5F2558875179BD
+:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680
+:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872
+:10DCB000FBD6C3390906B9F5547325799BCE6F6538
+:10DCC00036D3E7B387157C2749E3EB68B95498C38B
+:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E
+:10DCE00062E5C4136880F234937A2F4164EBBEF18D
+:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9
+:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7
+:10DD10004D47807BAF35CBEC98873FB03BFEBD874E
+:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23
+:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC
+:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0
+:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0
+:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A
+:10DD700004EE7BF407F03C183C605488F775D9FB3F
+:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C
+:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE
+:10DDA0007A4A0F33815F57E710633B73201BEE9570
+:10DDB0009374AB1FE4CD29217018D757246E58DF18
+:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24
+:10DDD000BA9152B4533F308741EFFC3C3703E339EB
+:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30
+:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8
+:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090
+:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B
+:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C
+:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7
+:10DE400071D3D623CDC47E1F264DFDFD15E01348AA
+:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33
+:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75
+:10DE7000958F1B6D3DD570955E77CF13EF2DF38495
+:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5
+:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597
+:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B
+:10DEB000700745B88794E28CEDEF7E578527C5CC77
+:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA
+:10DED000721DDE58937CF02EDB08DECFD5D631FAEA
+:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60
+:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC
+:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39
+:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2
+:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2
+:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84
+:10DF40005F47F513BE5748F55235C86FCD2F02BE57
+:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5
+:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855
+:10DF70009DB17A8B53EDE868F918AD178C7635A50D
+:10DF80005B456F078CE11715AF374F1F93E2D0C782
+:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF
+:10DFA00064569551DF3B7299DFE1C8751ACEE1D610
+:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D
+:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3
+:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA
+:10DFE000A11869E549AF07DAC97DC31E98974D04AA
+:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7
+:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17
+:10E010005E0D9EB05040E1C86C60F064F70F72BCBA
+:10E020004EEE65D7B37AC5B91683FEF1439EC2772B
+:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E
+:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53
+:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D
+:10E060007379C1329877C3857018D036EBC2100F20
+:10E0700076DFFE3C79167CD7E62799C54CD81F770A
+:10E080005E60F0F544D13F21BBD575E965F0B9027A
+:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A
+:10E0A000DE482341782F88D8683DB0831CB49EFE9B
+:10E0B000DE260994C23E412875DA74D0730B1DFE2A
+:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E
+:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31
+:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1
+:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5
+:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D
+:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777
+:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971
+:10E1300035CDCF782C97E9A3D37981AD30FEE613A6
+:10E1400007F09CE083472F09E3BDEB73A378E3EA74
+:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7
+:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B
+:10E170004FC33BAD590DF24CFDEF126435B077E360
+:10E18000D212467F1F5400BD9DD9BFA201E95A2477
+:10E1900022413A0AA2DD956D63F6A886DFD34238A4
+:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B
+:10E1B000F91C7E787FE1EF8FBF213D067886B81885
+:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A
+:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4
+:10E1E000CC8AA28B59DB199FFC283751E55782EF67
+:10E1F000291DCF4D50EDA8601DDAAF741E9D731020
+:10E200002E9C87982B7F15E9564CC671331BC29CF8
+:10E21000FEFE899646E84A7E3637F566E0ECC77D15
+:10E22000C64DAA9C295F7B947B5B47072FE69A919A
+:10E230006E329F3DC2817F48CB5B177AB03EC607E6
+:10E24000339F657ED3265A7EBF41AE6CC0F97439C8
+:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE
+:10E26000C17766EFB8103E8DE25985F794C0D6931A
+:10E27000A77868A5F99FE54A38FE6921781FACFBAD
+:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A
+:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6
+:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F
+:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E
+:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8
+:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29
+:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911
+:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C
+:10E30000E8CB68FA745633B90831D742F60E1CEEE2
+:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38
+:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12
+:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD
+:10E340005222FC7660A4FF68FCE5E631F91A438F9F
+:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB
+:10E36000E27D54BFE7B1FB578979BC0A8FEC853851
+:10E37000B644F9B9BB14DEF50B144B809F54A71FAC
+:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90
+:10E39000CE77203C942F92F274EBD750CC7E67EA74
+:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A
+:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709
+:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B
+:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95
+:10E3E000D8BB43D4AF6F857889E6D727D605940488
+:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4
+:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB
+:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D
+:10E420008FF4BFE97213F28FAB9AC911D705A3FC21
+:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA
+:10E44000892007E2C1FD19AEE967705E851C67E7A8
+:10E4500028167CF0F344FD3BA435798CBEAFF599CA
+:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7
+:10E4700027BA7EFFD29784E782AE3DBBF2F3905776
+:10E480008E26E139929C702DD2C535CF1C3FD081AC
+:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E
+:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD
+:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6
+:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E
+:10E4D000DD6D0A1D61DFFB9244A877F59903F30116
+:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D
+:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237
+:10E500001A824F3E0E79529BC8EE5D055F11F4BF33
+:10E51000DF75F0F820F2A146174BFB39F5DD30012D
+:10E52000CF7968F4FB56457119F01DA550BF793EAF
+:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA
+:10E54000E142C0075D82D287F25CECCF0579EE2C08
+:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E
+:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA
+:10E57000BA1E5C07FD1D3613D19C118177B320A113
+:10E580007FB4B986F3530E231CD9762A15F6C79AA1
+:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7
+:10E5A0006C5BEC38E893792E953E19BF660EACC8CB
+:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8
+:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D
+:10E5D00040BF282EECBF11E293949FBEAACAC73455
+:10E5E0003180EF8CD8E4402AFC269B640DE0396E24
+:10E5F000697DC0D20A72861FC95D858AF09861FF65
+:10E60000F0A025983113FAEB52F5D351063F6D8FE8
+:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7
+:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49
+:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B
+:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85
+:10E65000D448AAC581A2F1CC4BB49CF65321C998E9
+:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2
+:10E670003B9B833CD3BBC1CBA877FFA545266F53FB
+:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E
+:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2
+:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4
+:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA
+:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9
+:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D
+:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893
+:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C
+:10E700005DC5DEC55D52545206F47672F50F778210
+:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0
+:10E72000EF511EB4F454C03DC9830B2511F8637337
+:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F
+:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD
+:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD
+:10E76000F839B4F397866EC3735B1A3E96560DE77D
+:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35
+:10E780007E8FD2DFFF05D640AE560080000000002D
+:10E790001F8B080000000000000BDD7D0B7854D5B6
+:10E7A000B5F03A73CE3C1226939327E1E9C90308EA
+:10E7B00098841308EF872704102BB583F2B2220E3A
+:10E7C000C823424846C48AD77E37830331526F6FCD
+:10E7D000AC2FEAA576A06AD12B106DAC51030DA821
+:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3
+:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998
+:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85
+:10E8100032802BD561BAAC03A42B6DBE3B3201D242
+:10E8200000F435986FB07B9D3A9647FE430A6DCE53
+:10E83000C5EFD3C0081501E4DF23192137408A262C
+:10E840000164516A335307C008C0BF0691AA811200
+:10E850006F31C027B5067C3800F84FCB0658CEFF85
+:10E860000058B1A8D5A1617F554F89FE329D46E978
+:10E870002D989EA3BFCB305F013778B13C4B966E8D
+:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B
+:10E890005370FEDFA9043D0987E85D88DF310F7EF4
+:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67
+:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B
+:10E8C00004D5F39649582FAB678A1EA4A1E4725B66
+:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0
+:10E8E000EA072064C2C15B66C37A47B353F4F5F408
+:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE
+:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F
+:10E91000A737044A204FC0C1EBEE8443684DF2DCB8
+:10E9200050143CC6131CB07D6830CC6D2C22F87B93
+:10E93000ABA89F6C9B9EB11E3715DC81926B526811
+:10E940009C20C36B00CD03D329B83E3FF59BEF5D00
+:10E95000C5F0C84AD113C163CF25021EBBE76C9333
+:10E960003760BDEA2229E4C4F9DDFFE28C525A6720
+:10E97000F54CB70E98AFF6290B695C08B8E031CCBE
+:10E98000836FD1BD53305F5DE9D5D76BBCEE455485
+:10E99000DE3733495F8FE50F3E2F1994AF0EB84332
+:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D
+:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35
+:10E9C000D1FF656C1F9041972762DE111EA8E3FA04
+:10E9D000AB27860712BC4E3E9F3497DABF62B30561
+:10E9E000689C57365FBA292875EDE7A4DDDB44EB58
+:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329
+:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2
+:10EA10008F23504878B5272F99F183E6E945381FB1
+:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF
+:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167
+:10EA40003DEF8B4B01C65F57A847281885572E17F7
+:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28
+:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198
+:10EA70002F59E3EF49F680D107E7E3682E6FED8366
+:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB
+:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8
+:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC
+:10EAB000EDCB253E919D0CBEC604E359ED717E5C05
+:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32
+:10EAD0002A1E4674372559DFED227A1A963B2C08F8
+:10EAE0009DE320247267A474C5035A07D10FAD8B30
+:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E
+:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C
+:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D
+:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD
+:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600
+:10EB400089C60BE078B4CF2913E15319E1E319DD4D
+:10EB50005078672EE179E35C5AD750256C2B25BE9F
+:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40
+:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E
+:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482
+:10EB90001FD03029263F68C37762EA0F0E5D1D93B0
+:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7
+:10EBB0003F253CA7F527E073561AD17279FF8636B8
+:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28
+:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39
+:10EBE000E23CCAFF2C87D627988785CF567E922293
+:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB
+:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525
+:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB
+:10EC200000EFE3D79F3A3A761FACF5E7F90637874E
+:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F
+:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB
+:10EC5000C7F54EF02782C374130E95B982DE2F4498
+:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2
+:10EC70001C1A805D2DAC9776F544BC48F7B9592F26
+:10EC80005BA8B44269949CBFDFA4EF074DFADE5045
+:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E
+:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5
+:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70
+:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598
+:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8
+:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6
+:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681
+:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B
+:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C
+:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995
+:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A
+:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D
+:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0
+:10ED600077F6983FC197605C294F8BA1CFD9336369
+:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50
+:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F
+:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE
+:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD
+:10EDB000E192020ED2E5A0403D4C7482C610D145CE
+:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA
+:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6
+:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE
+:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46
+:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F
+:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA
+:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65
+:10EE300076CD9917907F263F57FCF561C48BDBE4B4
+:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A
+:10EE500073F5E9DE878673B7850AD71BC2F69D5323
+:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9
+:10EE70008D1CD389E99749FD4380B640699EE03FE8
+:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87
+:10EE900073286ADF86EF5563F223DA7262EA8F3AEB
+:10EEA000A0C5948F0917C6948F3BAAC7E427444690
+:10EEB000C7D4BFEC8C11932F872B62EA57B866C476
+:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9
+:10EED000FD157887E7E1BA173ADCF5522ADA69B905
+:10EEE0004619E59393ABFD0BC84E5AE3516122D509
+:10EEF0000E85086E750E97BA1EF9D40792D11F10B1
+:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B
+:10EF10009A676CF1119D6E2F4CD6681F920702B450
+:10EF2000919C52F424407EE2E811F95D01EDCB6F33
+:10EF30006CF01826DB5554F4A97E736688ECDFACC0
+:10EF400064DF15348FF5B606CF1ADA671B781FCB4E
+:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2
+:10EF60003316F39F61F7329637B59DF8C995981F10
+:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712
+:10EF800078F6F10F843D15FFFD677982DF6755083C
+:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47
+:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753
+:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA
+:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3
+:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41
+:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1
+:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D
+:10F000007F2F086444B7137CA7739CBE5C6E3F934C
+:10F01000068184EBC8E4EF9063E410DEEC423A270B
+:10F020007E519E96ED0024F1F91079C540F8CF206D
+:10F030009300F1145C7A29F12950EC91B04517281E
+:10F040003F1680F201D90B3644C67338B51B56DB28
+:10F050003F0847D1D10C23360F543F4ADE7C427D16
+:10F06000E37A928714A612BE9F022D554D805F56FB
+:10F070003ACF257B95A8F51CEC464F6A33E178B072
+:10F080005762383E6FF2B191F320A1BED696E711D8
+:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE
+:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960
+:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3
+:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4
+:10F0D0008AD163989BF8185426827F9F7C534F8D6A
+:10F0E0005B771318390BC8AFA1D875E267C932F83E
+:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B
+:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922
+:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC
+:10F12000DB890F77819F3BD34E7EDB78387A419B1A
+:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD
+:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5
+:10F15000E96F185877E155434AD6527AE9F83A9957
+:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D
+:10F17000AF90E8E390A42D61384808079237BD8F1F
+:10F180000F5C1005C715FDCA7F9F9F45E7036064AC
+:10F1900090BF788793FD56B001580FADD9397813D9
+:10F1A000C9852FF27DAF51BD51934DFFAD11197837
+:10F1B00075CAC5C30BFFEC44271782976CD2FB417D
+:10F1C0004F62BC19972FF6EBABD24B66BE8043045F
+:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F
+:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837
+:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A
+:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111
+:10F21000E4C4F35CFC2D99E71B344FE2F32589E746
+:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B
+:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A
+:10F2400062BDD9C807A9DE373D5F082C984272E835
+:10F250001A9FF0FF1723C7253E845379F4DC70D240
+:10F260006FF5751B88EFACF4E80195F9C81BF982BE
+:10F270000F8281F399394D627F52FB884F97288422
+:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21
+:10F29000473A799CE004D32303899F1C1C98984F1C
+:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F
+:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888
+:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A
+:10F2D00027ED07E6BD12F981735E3F207918DE271E
+:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C
+:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F
+:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED
+:10F31000D36FD0132ECA6F509C29E865453F2FCB81
+:10F3200007921B643FD7BD30A6943617F50F20FB1C
+:10F33000209292CCF222D87B6CA11605CF0FF32D30
+:10F34000FD53EE46AF74C47C7FB7D685266567FE55
+:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A
+:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D
+:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3
+:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427
+:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9
+:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403
+:10F3B000F757DD9764D3BF88FAC4399AB701557EF1
+:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84
+:10F3D0005D517478832D9225E476781D3999FE6706
+:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F
+:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359
+:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D
+:10F41000A2821EC4F5955F8ED884FD4D92FBB68402
+:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D
+:10F4300074F2634E52ECC7A3F953BC1F684041AC51
+:10F440003FF914CC4B6D25B88C4F67B86C6F99940D
+:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1
+:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C
+:10F47000C0B4BC9BF58F32EB85938D5105599DFD32
+:10F4800051FD44F1106D832C3FAE80EB358105AC0E
+:10F490006FD95CC857897FA2FE2AABE4272CB03312
+:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4
+:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931
+:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F
+:10F4D000D237902E26DB2219822E4222AE017C0AE0
+:10F4E000E57F2B85831427B0D6F5EF3F273FB81172
+:10F4F00054206922E615603F63E0600A9FCBF1CC9F
+:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4
+:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C
+:10F5200095E9C69FACDB7B937FE93DCE4B2B937572
+:10F530002987FC4F9E42D2535743B2EEC4710C77D9
+:10F540007180C67568C0FEF86468E475B8DD9F0414
+:10F5500008282AA812DB4FC9BE65056CAF009F932F
+:10F560001F7E2F6533AD3F493DD57A077ECA0083A4
+:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405
+:10F580004904FF9E73E3BFC7CA4B171C54899F48A9
+:10F59000ADDE9C73C89FDA086E659D706B53845D09
+:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51
+:10F5B000DF86001A45FA789BBA642BD547C3096CDD
+:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831
+:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025
+:10F5E00020F4A3EAF4C3D524E70007B5F50738995A
+:10F5F000727424F10D9497F5242F93EC06C3DB92DB
+:10F600009B2B9AD600D15575F30220BEF28EE41BD7
+:10F61000F032DB23C076D99C6981576C1AF9B26647
+:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB
+:10F63000761753BBD2CBBC53B270DC6031E8776233
+:10F64000BD60926FEBB3B4AE3765FD318DE2212A18
+:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF
+:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9
+:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1
+:10F68000F247A93C5FE42FC37C8DD852C86F29FF95
+:10F69000DE0882479B0C141655D322D968FCFC99CE
+:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9
+:10F6B000049DC849B3F97E762B95BF01BC0E30F985
+:10F6C000F7A838FA1DD749375C5EDA91F757D07C36
+:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2
+:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31
+:10F6F00060F205EFC607F89CC0A6937FB24E6A6021
+:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2
+:10F7100006CB1474A7EF157457065E99E03552BDF9
+:10F720003B48E3CF9997CB7C66CC5160B830E5611C
+:10F730007E429AC4FB943F209FF165BC4BAF97116A
+:10F740008F64B9343F09C79B3B4FE2F38959735D1E
+:10F750002109FF390BE983E3A1145FEE6CC4F7398B
+:10F760003E499CFB627E5E943F1EB5613E379BED39
+:10F7700004FFD309F0397F80C077AB7DCD5A478C29
+:10F780007FE792016EE1E71830F59302E6BF22AE03
+:10F79000252BD91B117CA381F9D4611BEADFA4FFBF
+:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4
+:10F7B000BCB17AF43BB4274407D74AACE7CE997B77
+:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2
+:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72
+:10F7E0006D67D3B87ECFC7579CBB0451A152F09729
+:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5
+:10F80000695E63CF267CFE21E8025FDFAFEB83F306
+:10F81000EC53658C90B528BF4D554822BACE269E34
+:10F82000C3F08F38C82F37DBA157D1BA66A7831A28
+:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17
+:10F840002D6F8608AF9095EB849388391CD7D657D7
+:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1
+:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F
+:10F87000346480E0570F4AC0F22270AD8BE19C9552
+:10F880002FE295B2527547308DF88D66D5E338BBBF
+:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15
+:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A
+:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7
+:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1
+:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC
+:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A
+:10F8F0009E657A2185FC5CC31064A4AFB7E5786788
+:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F
+:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7
+:10F92000CE3CC53D56428383F0BD324E3E2E73BF62
+:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891
+:10F940007AAA8B3F88F954273F8BB32F417D89D604
+:10F950003302F931F121A3204566FF32CC13721432
+:10F960001E97C82F267B56D793DC6B97521AE4B2AA
+:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978
+:10F980003115BACA01F0B3FE3211E526E9D152CBE6
+:10F990001C99C6DDB814FBA6F37C255C41F9DB9607
+:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3
+:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B
+:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A
+:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84
+:10F9E00080E54E128472087E4681E0B36507049F6D
+:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913
+:10FA0000D80870FCCC0EF0559BFACE5D034650B47E
+:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31
+:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546
+:10FA3000DAF9F99661F12588E54BB97096F70FEE82
+:10FA4000DE732BF90982717A50F022F5A05EB9BEFF
+:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845
+:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756
+:10FA70004027DE75E07360D375B40E94E72AD97D14
+:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272
+:10FA90007CAB0DFC14AF003EF534E1A92577911342
+:10FAA000319ED42D1678374A11F9BEA8C8125E06C9
+:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378
+:10FAC000E13683F16404E81954CFC2939161518EF9
+:10FAD000F8F11AF19371D3105FF228CE76541FD249
+:10FAE000BBCA4163FC288F936B15EE990AD17985C7
+:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A
+:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7
+:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F
+:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367
+:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3
+:10FB4000BF2F08523E7B452EEB854FA7E92F71B999
+:10FB50005F9497B519720AE6F3576139E69FCEF5BF
+:10FB60005650BE66359663FD11FB7C41CA17FC50AA
+:10FB70009497DEE97F2985E47C40B47FE1589DECD1
+:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9
+:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441
+:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6
+:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2
+:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB
+:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2
+:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA
+:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C
+:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3
+:10FC1000426B633F449778633FCBEF50BFE2618410
+:10FC2000B797539C31965F3E56C419979E3B3D351E
+:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80
+:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687
+:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70
+:10FC60000196DAFC0AE111F497749AFF556DFEC90A
+:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30
+:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE
+:10FC9000743B8E3369FC00A6FB9973258BEEBF3352
+:10FCA00090F4603AC1607FB68FE3DD6F8290830687
+:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94
+:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E
+:10FCD0006745636CBDCA0DBF3F209574E50395165B
+:10FCE0001F08C5F2015438041F7868089F7FADCC07
+:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A
+:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6
+:10FD100069EE42E2C336335E55E4ADF1212ECEE505
+:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A
+:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A
+:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F
+:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9
+:10FD600010CE52B28B95E256EA7388A02717D111B4
+:10FD7000F1F769B1F65612083D7E789BF0E38CE806
+:10FD800094FB75B4BF4ED05D42EE3700D157B7F645
+:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0
+:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9
+:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B
+:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2
+:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5
+:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D
+:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C
+:10FE0000774E098181D171054F0F12FC6E4281F14D
+:10FE10009B81744E94D49FF99D568AF6541FCE73DD
+:10FE20007F076FBE9CE3243E03E38271126BA3FC49
+:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697
+:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88
+:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5
+:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419
+:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89
+:10FE800014BDAF670796A70CA2F8A27CC3D18BE084
+:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8
+:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E
+:10FEB0006E1776607B9248AD799D1D382365109D45
+:10FEC000CBDE1C66BED8919F1166BE7776A097C721
+:10FED0006D9F65959BF9FF10790D549DE65BEE32A1
+:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D
+:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24
+:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015
+:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D
+:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D
+:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294
+:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA
+:10FF50006BC4AF29F274E66BA79A24F68768D05673
+:10FF600047705E29897D59F9EA8D150ECA2F0695CD
+:10FF7000F97C533C3FF305494F585E0F2CEF4A2163
+:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D
+:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB
+:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51
+:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E
+:10FFC00036D1F58F80FFC1F112C175E206826BD385
+:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84
+:10FFE00089EE67B967AA6305C2614F8E0CD268BA01
+:10FFF00077B32CA6DFE57215FB0950ED6039E2C737
+:020000021000EC
+:10000000FF313CE522B6933F6F962003F175E986F8
+:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C
+:10002000F7DCAEE7404B0699F1C0BDA137E1F31410
+:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560
+:100040003FB214063D349EF7D10E218D8E4744F900
+:10005000A98D722890DB793E746AEFAF0EFBB0DE9B
+:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3
+:10007000C6EE778A1EBBDFA9A363F73B1ECE694697
+:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829
+:100090007CB0E03B1AFF27F05563F82E41F83E2C68
+:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2
+:1000B0008B85F37D7170FE1CC657B819B830D335E7
+:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E
+:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D
+:1000E000CC26A267233385F980BEA107EFD73097CE
+:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C
+:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F
+:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F
+:10012000C88F91096D0ED263BAE38333728C5F93EB
+:10013000DC402E06040F610AF05F427DB2A6A35890
+:10014000F8E79D7EE1E787401ACF6314887970A3B2
+:10015000287FFF2825C47E073429D8BF64D963F1DE
+:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A
+:10017000D37F8F56A041FAF5C8CF84FE34DAD51864
+:1001800054B4AEF6F927F9E639B762C67F5EE01CD3
+:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787
+:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469
+:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F
+:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9
+:1001D0002E1FEBB5369761E7F328D37F09109E4AAF
+:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5
+:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9
+:10020000ED9E047814170F102BEF17145AF7CA45F8
+:10021000BC8A06E2FE77A5E947AA746DF4887338B4
+:1002200094737DA18BDDA410E0C7F07985BD90EDBE
+:1002300062B407F8BC5F73248AD7033593CFD56FB8
+:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12
+:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7
+:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F
+:10027000B9B730B8509C7B97997A53A5CB8453611A
+:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92
+:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA
+:1002A0008C687BBC15E125A74C76117F5CD1CF37DC
+:1002B0008CEAF73B103E4C74036E8DF5F593CDC779
+:1002C000F6CB799DEB423C7B701CADA35956C5BD66
+:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE
+:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF
+:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A
+:100300003DAF714F6FD28B6F157A31EE2BFB41648D
+:100310003B48A4974E91CFDE42F95339A092FD9904
+:10032000D923207B48CF5B00EC2702DDAF13AAC89E
+:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198
+:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB
+:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4
+:10036000C53973EE0FFEB69CE900B474E7181ACFD6
+:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726
+:1003800059F730D2CF7AD1392F8274A8491F9755A7
+:100390004486FBDD9D70CACC4F6CBF649BF03898DF
+:1003A0007C72369D8758F7301EEAF1069F879F348E
+:1003B000CF4FF28C69A984E707075AE75AAD59E491
+:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB
+:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B
+:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE
+:1003F0009456079D6755FD9371514D6871273A0FCB
+:10040000B3D65F9DA68032145309BCE7ABF7E23F39
+:10041000E48470DC629677777FE3E7E6FAACFB1959
+:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB
+:100430002EE61E04D96BB4BEEA3313F97BC55D27E3
+:100440001C84DFD40F3D8560DDCFE80ECED985C298
+:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4
+:100460009A707B72AF6DDAE604F37CBD50D8DD4341
+:10047000B214F6175CDA0AC6A604E35AF5ACF70D17
+:10048000BA9B57D3A4F07C9A37C505271A6FA709E2
+:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C
+:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39
+:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3
+:1004C000B4DEFA4A269B5D407EB49EF35A6D242723
+:1004D0003BF84F37FBDD096739E61E4C57383BB810
+:1004E000BCE3FE19181E299BE410B03EF0D01F4B50
+:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC
+:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE
+:10051000EF20BB6C49394464E45BC7DEEA5F477196
+:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7
+:1005300029D8EEC603DED456CC2FBA27568E1D7BA3
+:10054000EBC70EB207A4856E3FC515E13CA7BE8080
+:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322
+:10056000DEC6EBC39F179AFAF048184972E685DA9F
+:1005700066F17E8E791F11F53F23119E587A7028FF
+:1005800079D2DF99EF43A34C7C699C92B8FE92220A
+:10059000B10F2B1F3BEDF068DDD3D971E42705388F
+:1005A000FE895A95D3ACC1866B30F63F60B02F659B
+:1005B00030B697B548FF4FD8CF29CE4111DF385F0D
+:1005C00043F7D448DECE157A8253BEB992F5D13EB8
+:1005D000A006597FF1FBD99F6E43FD248DE2376E53
+:1005E000913DEC6F10EF078DF968511AAD37F3BFED
+:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780
+:10060000CF70F379FF265B80FBA140ADBB109EA1AC
+:1006100027C7EC26F77941E3BD93C8EE535B76B567
+:1006200092BD526FFB740FC525D44F043DC8D00E48
+:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E
+:10064000D72855A3FAD720F21EE99927AB6CEC37CF
+:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1
+:100660009B59713F7CF697C06F7802E51B44DDE72C
+:100670005ED1B4C946FAF8A5B451517155D6BCAA99
+:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3
+:1006900003B98A26113CAF9354A18F9A7AF2B560C0
+:1006A000FD35BC42FAE942D293110F3F94421CAF90
+:1006B00069839667A9FDDC1CA10F82D63882FCD71E
+:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D
+:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530
+:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B
+:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA
+:100700007EAF7D5E8E0F6997D4F498775ED4865F56
+:1007100093DE5D6353857D73C028A5F398F6194574
+:10072000FCEECB497BB83FF311E47B149775EB13D8
+:100730004D3315845B756FD4BB30BFF9895D3315BC
+:100740007A87272FBCC486F95707FF45940F091FE6
+:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F
+:100760009127030C11EC6F4FFCEFCC00AEEBB8E916
+:10077000FF043D3C9FE659FDC2205BB47FF1C86099
+:10078000C1378F27897AC773E186AB49FF280CF3FD
+:100790007D18ABDE6B83CDFB0426FEDFF462522BAB
+:1007A000C5095BED202771FF41B3DD4DE67B59485C
+:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3
+:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0
+:1007D00023394F72C01E7BFFADC1DC2F2812FD579D
+:1007E000F756D3683FB2D3859D811B927617BF63BE
+:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15
+:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB
+:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B
+:10082000396973F47B29274DF81E199C26E0D7B14E
+:100830000F3D251E2768C2A52FC2BBB8137FACF69B
+:10084000175AF7F67FD1BABBEC5399989FB51E8023
+:100850007B051C707E69A8E71F5F63B61B6DCD43E7
+:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3
+:10087000707059E316F1F9E40A530F96036F38C804
+:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184
+:100890002A9ACE32F3C53A33652333C8F488EB6322
+:1008A0007A34CC788358FCE980773C1D77E94F4B4C
+:1008B0008FED4FE3FEBADB87B08917DFD83E041314
+:1008C000C3B383BFC4C1AF831E73CD76458867654C
+:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646
+:1008E000335E558BC5E3154DB9B685459DF5EF6E65
+:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B
+:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A
+:10091000531AB2492FAE7A6C9DC7A0731625E021F9
+:10092000BE792C244F4B747F75D41029461FABA67B
+:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201
+:10094000785737FDB58EECB73D862B4272FBA81267
+:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97
+:10096000FBE503D91A077707FAD8589F6AED43EDDC
+:10097000AA1FB5EB64BF57EF93751C066A20524758
+:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740
+:1009900072E4248CF7354D3FFA54F6507AEC1D285A
+:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F
+:1009B0002CF840288BF59BE0130F95BC8FF33AF190
+:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26
+:1009D0005AF772F524E907CEAE7A80D62C0925BBEA
+:1009E00045A455F6560FF905AA36D9F5007EAEDABC
+:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382
+:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF
+:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF
+:100A2000402409EB2F7FFA7DF66F55F9DC7E578263
+:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE
+:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F
+:100A50000EA29B13B8211969025E649FD634CA0B9B
+:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C
+:100A7000D7101074F1DCD66D640F54BEE3D4A7D345
+:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84
+:100A90001CB7D21EC8563915DF2B1FB995F170E966
+:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F
+:100AB0008DB3789D4BC0C77858F933E1CFF85C818E
+:100AC0006989EE1B6F1F22E487136E2E21FAF81C32
+:100AD0007B223FCC11078878DEB7C43B644EB83A1E
+:100AE00035FA9DB93B8708391080D07BF4FE640D40
+:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592
+:100B0000D71F30E1259D13F11C9A62C59DE6E17E59
+:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C
+:100B2000FF1BD58EE17664B33359423BFF4876E232
+:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B
+:100B400002B4BB527344FE61A243B48B52116E9F38
+:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B
+:100B6000A0676954DFEABFA6D919F32E49CDA31FA8
+:100B7000C5D1B333EEBD133FC3B3065235D2378F61
+:100B80003822535FA471705C8AD75C72BF33E6BDB4
+:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B
+:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4
+:100BB000ECA1C7093E5548AF01A657417FA8A347FE
+:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF
+:100BD0001E2D96CF563E83F44BFE348477924E7C86
+:100BE000F64B07E9BD39156807E3BC3F76EB74297E
+:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5
+:100C000076C35FF7C5C1F373284AA53B0CC79F5C49
+:100C10007E09FB15E2E06BD9BBF17CB37A88C67024
+:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206
+:100C3000973807AB7EF4AF2CBF10AC1127E26D756F
+:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B
+:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548
+:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8
+:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D
+:100C8000C1B4074AD400B54F32E30FBC114F5A9498
+:100C90009EF47E8BEC21BD2E1C826989DF050CF24F
+:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C
+:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590
+:100CC000733C7CFFAF25FF3F092F16BF8A70247A43
+:100CD0000A188E5E08E71B0508D0FC08F079B09C66
+:100CE00052B6E745ACB704014CE724F1FE9465E049
+:100CF0004D6DCDEDEA374139E820F9BF14E511FB20
+:100D0000BD37C6962F6BF998F16C591C9EF908CF28
+:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C
+:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8
+:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43
+:100D4000F84E7A968587F1F67D7C7AE2D97747D29C
+:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848
+:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6
+:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861
+:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1
+:100D900070C7972561965B6B791FA75FEAE0FD3E00
+:100DA000D5F2379623A75A9C1AADA366670FF68F24
+:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E
+:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F
+:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01
+:100DE000FE5E427CA9FD995D0EE25B68973E02883B
+:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD
+:100E00003BB3E87DACAE701170684738D0BA102E95
+:100E100095A49775078FEA6F2D3C3E657BA2AA6566
+:100E200014D351275C24437C4F09B9245AFFF31E85
+:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542
+:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F
+:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F
+:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01
+:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53
+:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E
+:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72
+:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C
+:100EB00010C21E914D7D631D0C3336915D857A06FF
+:100EC000D901EB3245BE1EF50799EF0F72B00AD477
+:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8
+:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA
+:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C
+:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F
+:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4
+:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A
+:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6
+:100F40008641EB766A0AEB610AA0FD28D621EC4EB9
+:100F500084A316054730ED50C504B9A20D6338A22D
+:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA
+:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B
+:100F8000F3D822111F100F672BCDF795AF21FD77F6
+:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8
+:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14
+:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9
+:100FC00012ED0CF657AA40F69F3C091AD91FE855B6
+:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE
+:100FE0004B6CFC4F601214525CC314B9AA81E675B5
+:100FF0000A521A28EED2616FEDCFFEE17E008F918A
+:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE
+:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC
+:10102000054A149CCB212D267FA2DFE126B213F2C4
+:10103000024E9582C72A5CBD62DA9FE87586C70BAF
+:101040003A5D2AD94753D4DC98F6B267EF7B64D770
+:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657
+:101060000526CED23ABEF7AEB8A78AF6D623AF632E
+:10107000BB37EF0720BFF1155A694CBB66D3BF12CF
+:101080009962E7F766AE2C1C13336E737837C3A5ED
+:101090002A0B243A0FAEB2214960BDEFEAE531F5E3
+:1010A000BE37FA8A987E67183362F255ABBF0025C7
+:1010B0000360DCEAB340EF0796B636C6B41FBEB78E
+:1010C00039A6BEE7753485302DDDA705291D75507D
+:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324
+:1010E00005D0323A16F0565018F2C8A3FE9728BD24
+:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965
+:1011000014FFD3F0E35D12C743EE263C1D1D69A812
+:1011100048C5EA63CF34BE446953DBF87A7AC7B373
+:101120000AA08DE5AFDBC6E70253E4961289ED9F76
+:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0
+:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0
+:101150005425128DE73F2AF51EA6384D2B4E2AB98D
+:101160004216BF4771B98893A9B3E94926F362FDD6
+:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA
+:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706
+:10119000F7459179BEA2A859D7931FBC3845B4270B
+:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94
+:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436
+:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7
+:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32
+:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4
+:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B
+:10120000478DB77282D0FF560E4EDE4A78EB3960BA
+:1012100088B8A842B73680E9239CC37C4209E75CC2
+:101220009F22E2ABB4F3BCF37F7CCB88349263198A
+:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD
+:10124000D0C13AACDF3F19E7B58562D744792BF2BC
+:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5
+:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD
+:10127000AFDFBFB688E037CA467125EB7F67E777F7
+:1012800006709DAC4FAC447A06E97CF0EC710178B5
+:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112
+:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933
+:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E
+:1012C000E3E68F37AC26BABEEA7821C52858EF5737
+:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345
+:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A
+:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D
+:10130000105D9E0637C7F59D561F9F4DF33DBDC529
+:10131000CE41B44D26BF0C149AEF11648673E85E7B
+:101320007EF19B368E473A88F860203EE4B7BE993E
+:101330005E4CED3295748A6F383DFECFFC6EC2E98B
+:101340001F0207172F0B3B185E4D998B2ACA19FFF6
+:10135000B574F23F58F06D34FB79B8D4B8B298FD4B
+:101360005CE67D1163EC45BD3FB96BC2977C2EB046
+:101370003617F5FC340A393E5347EF4BAECCB5B3C4
+:101380005C5A99F6C5D44CC2F7725784DE81A859CD
+:10139000FD19C317BBC98DBE07A69C91418B8ADF7F
+:1013A000D2868AFD571483F75F39E3E0F2AAD5A706
+:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700
+:1013C000CCF746911FD64BC328DDED5819C54FA069
+:1013D000F1D30E3E3F14F7EABEE96F25939F728664
+:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1
+:1013F000DEA06EDBFBB329BE60463F7516C517DC69
+:10140000573C790E97F7521FB0A1FC7AB964BEC859
+:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7
+:1014200075CE9C00F36337D3C1A9FA1E21E779E892
+:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120
+:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0
+:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72
+:1014600092F85DA2436DFD097E4736DEF203F2A7D6
+:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA
+:101480005F1CEEBBB798F5A9368E775DBA7A27CF89
+:10149000EF53DD8C5B562345DEAFF54E04F69FF02F
+:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC
+:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50
+:1014C000B64FE851856C3FE524F37BD175BDDF292C
+:1014D00049F43B088DB528EF91E49EA96DE674F5BB
+:1014E00050607CEBA9841D3AF6537D40C89D916DF8
+:1014F0001F38A2E319779BF04D357FEF2A3E1E7708
+:1015000037C9A5A8B88315BD5BFB927E68ED6BE774
+:10151000BEB4F635F70568BE99192F3D45EF9D50CD
+:101520009CEB0FE93CE3B9A456F25B778F27D63EDC
+:10153000887937250BBE11793689F5A6F8751C34E4
+:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C
+:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954
+:101560005F3CDE897B6D17C23B8BFF5483AF50DC41
+:101570009716FCC682B7354F0B6E4DDDC4E32AAB20
+:101580009F8F598FD236898C1E482D11EF5F298D80
+:101590005700ED87B2BA85EB75B71E39E5333EC704
+:1015A00059A6819FF4DEF875554123B7EBBAAE0812
+:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C
+:1015C0007DDC5A77079FC6F5137D4F4086C37C9319
+:1015D000EE124A645FF862F4E372BA31117D6EE58F
+:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C
+:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27
+:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE
+:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7
+:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A
+:10163000CDE9EBB506A76DB55E4EE3F946595BB84B
+:101640008CFCFBA33353F93C6AE350DFF525140708
+:10165000B92F5244F837F640E34B240AF2439FBEB9
+:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684
+:10167000EB322469E7D38B6430A2F0C7333D0C749E
+:10168000FEED01F13E567CFD8525424F9E0B61F13A
+:101690009EC06A3E0187B92EF5152393C54684EC9A
+:1016A000F6B9E0673DD4B65ABC5333177428237B90
+:1016B000D607FE7B381E29F67D01AF3163DDAFB062
+:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15
+:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611
+:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA
+:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD
+:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E
+:101710002D750CD1C71ABEDF50D5A6E94184F798C4
+:1017200043822E46205DD0BE8D3D2AE86024D20142
+:10173000CB41D33EB4E800EDA997A8FDA983A03B17
+:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C
+:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3
+:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1
+:101770007FB97635E7F7D40638DD5B5B6FE2670348
+:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0
+:1017900067089FBB4B4C39ED2A37ED0A917A8D359E
+:1017A00076BEE78F9F889FCCA5B9127E544A21E26E
+:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD
+:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE
+:1017D000F164A619C77A20BDEE5607E2C389C6FB9D
+:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F
+:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2
+:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681
+:1018100038DB7F9D9C514D39030BA87E87FD9D7C55
+:10182000703EBD8FD7052E71F6F7E141627F2DFB2B
+:101830001BF54CF64BB58764B6BF2A731B3C6C7F17
+:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21
+:101850001D6914D7D3BA7F1CCB99557B882F2D33A4
+:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30
+:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B
+:101880007B25B1BFE7137F7FB73B7CA17882E8F768
+:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F
+:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB
+:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC
+:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338
+:1018D0001DCC574787C57B01E3E95E6282F702268C
+:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25
+:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC
+:101900005E75D295796F8E6232F2BF3AFD698B4671
+:10191000E7907ED761B7BAA7F23B45A75B81A349A1
+:101920002DBFD8F083864CF712461CF20549DED64F
+:101930009976E6A813013915BF4FF8CCCF76D018A9
+:10194000B453E552718FDA8882AFE5D7B2F89CC5FF
+:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286
+:101960003FEF41436DD67BD6838612DF33EFE94DDF
+:1019700091CFEE3A4776419B8817B8E46CFBE3645D
+:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D
+:101990005A698D4D9CA30CABD08693BD497A2BD947
+:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66
+:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C
+:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81
+:1019D000A19E10991B23C7BEED7A1FD26119E11792
+:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB
+:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B
+:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5
+:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6
+:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0
+:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9
+:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E
+:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE
+:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5
+:101A7000E78595E8F3B39F9AF32FBF7632903D74D4
+:101A8000952AECCEAB5C90798678E1D9D345B390BA
+:101A9000415C45FAEC707E87FD618273C73B20C4D0
+:101AA0008F2EC17D7B5F9CF3C14D12FB4B9B9B44F2
+:101AB000BE78711AAFEBABEE23F6DCA304D7BFB848
+:101AC000491946F43D343D924774593CE6ED74099A
+:101AD000E75562DEC7C269D743D4EF5BBD6BAEE3A7
+:101AE000F3A1C6369ADFD0F4B6F5F7917EF9AC0DC6
+:101AF000C86F7864CCED4B204A2E7B4A27FD8AEADA
+:101B00006D97CC77EA7688DF33C016D9D1FEAD3F2A
+:101B1000E915CF53BD56D3CF00AB9EE77BFC3354C2
+:101B2000B1073039CBFC3DC948FF44BF2F649D67E6
+:101B30000D25580AFF23BF2BB6DDF44FBE39F483C1
+:101B400039E45F84D6481ECDE34892B847ED29F5C5
+:101B5000FD8EF8CC50F2F3D23A7E26FC0347D2FC3D
+:101B60007C8FE46DE4CF747EFC975A17A7EFA27DBB
+:101B700044E9FFA07D44E9FB681F51FA21DA47944C
+:101B80002E3E839DE2FECDD08DB799BF76B38EEE0B
+:101B9000F94BC0D4EF13FF4ED35B26FC4B9A0EDDFE
+:101BA000D983F0A059E6F8E8E26715D64F4FB68C16
+:101BB0008AF95D52A4D7C3B4BE92E63FFE84EE59C3
+:101BC000973429AAA4D1BDECD3D91C7F18373F8202
+:101BD000039D37447638C4EF2999F3DD9ED6B69E2F
+:101BE000DA6F7F368F6648E738020F773813FEDEEC
+:101BF000B0156FF7C450A17F7DCF19298B3E7F8C24
+:101C00008F4F633FF018C2E7823FD03881BD320C5E
+:101C100060BC8CF56FF4D3C53D042B2DDEE1E038BC
+:101C2000E5ED3BF65F7D25F6F77F00222F54BD00E2
+:101C3000800000001F8B080000000000000BCD7D1D
+:101C40000B7854D5B5F09A39F34A32934CC2000957
+:101C5000123809AF00018664121212E024048A8A45
+:101C60007482D482A28EB462541E23D29ADED23FF2
+:101C700027244012830605CA558401C1C7FDFCAE66
+:101C8000D102175BF44E50A9F6B73422E2A354C731
+:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF
+:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9
+:101CB0003BB3265E5E24C900A7E9670A80CBDB1729
+:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0
+:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11
+:101CE0009B968EF51B334D07A8BC49CE999E812546
+:101CF0004088DFFF515EC5810CACCDF456DB024E4F
+:101D0000800A9000F2807F4EE37F531D29008E6889
+:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27
+:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597
+:101D30001B74D23EBEBAA71CF70326080FA37DED85
+:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999
+:101D50008D1BFDA4A479E3FDF4B245B165F503B88C
+:101D6000857EC7F6E3103E5286ED926BF9813BF11A
+:101D7000BDDB322590BC00359BADEF4762D6B10488
+:101D8000FC6961EC77DB0EE37380882DEC03B83DD2
+:101D9000E00CB62000173D81ED0E433B8FBB78AFC2
+:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140
+:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A
+:101DC00093A55F0F90719FE55E97E723040D4C800C
+:101DD00009A711E42039CD80FD4EBD2485245CD7B0
+:101DE00034E99BD4483E3EAF423C67E17B26F90F85
+:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3
+:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E
+:101E10001D01F0C73A07977FAA7373F96E5D269785
+:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B
+:101E3000FCF7F1007D681C15A06FB41C67F39A07CE
+:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7
+:101E50006F70FE620D0F4802D5448CA5F8DF8FB776
+:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6
+:101E7000D724C65DD4F1629627DA0ECBDF33F48720
+:101E800015A603867A638EB1DE5A7120F67D1D0E8B
+:101E9000F1E52D9BEFB0055C58AE372921E799EDB0
+:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2
+:101EB000712BA0607F0B80D29E7FE67B00F50CE744
+:101EC000791204DB138C5B47E312BDEF4F02E93C50
+:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4
+:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA
+:101EF00033404FB00E73693D63777D6C3663392E86
+:101F000059D0C95877C49C81E5899A7F6C3CE261BD
+:101F100032F59B26637B6ED71107A2FCBEF6AB366B
+:101F200039106F6F9BCD00034020BE04FBE31854B3
+:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737
+:101F400041E445A6A34AC1EF3710DD88791440511A
+:101F5000B37415E8F32A241F68FF547FADDDFFE654
+:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0
+:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C
+:101F8000BF0EFC773A97F83534DD89EBBD358CFC14
+:101F90000F179FFF9FF13AA37C3E22219F1FBA1289
+:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537
+:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D
+:101FC00080F7368D2E86285DB369BE65CF5AA00591
+:101FD000D7B76CD288FEB1E3C7BFB7B44902396640
+:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1
+:101FF000A7322AF24559CFF868D3E44DD720FF180D
+:1020000094D726FF9F7E8EF301E27127C2A7327319
+:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD
+:102020000588E0EA92EBB201E1B919D12521DDCDB5
+:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5
+:1020400078FC6B5CCBAD606672CD36E17873E7D817
+:102050000B693FB31A045DBF9EDE759C9EBF3E298F
+:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A
+:10207000E80D37EEFE08F163524649A7537A9617EA
+:1020800044C91FE97894A2F26F9AE454699E936E52
+:1020900033D3BD25ABD546EBBA154207149C7789DF
+:1020A000376C23F9773BB82D5462D1D54D1F447F4F
+:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E
+:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C
+:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8
+:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41
+:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3
+:102100006170749FE36C004E92F33B5358CE1F7B7B
+:10211000AED84C783AF63B6BC844F52D23DEB8D3E5
+:10212000C7752079732CC36BB6517B466E48C5F6D4
+:102130005BCCA0925C86ED426E3D3FE9AE77488E67
+:102140002DDFE932D94D828E653401A447D7BEF325
+:10215000EF38CEADC8AC766F546F2C9AF2E8C62734
+:10216000900E1699DBEE29C767A7203CD68DF0FCB0
+:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D
+:102180004B38FECBA98191B41FC854FAE7E0F39A0B
+:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83
+:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59
+:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB
+:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58
+:1021D00040765381645288CEBB9A115EA633E9499A
+:1021E000196FE6F7169951BF121D06E44282C7091E
+:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC
+:10220000D63F4A774797FC86E86EB3DD6BC7251C3F
+:102210004F32EA7DBD9C393E9DF9E516C79760298E
+:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094
+:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80
+:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8
+:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9
+:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4
+:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC
+:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33
+:102290003A6E32F17E17D13EF0F96F0AFD3733BE48
+:1022A0002DA827106E0B5AC66C2779304DCA4F23C4
+:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D
+:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE
+:1022D000677B469B9015A3CF333AC7A6E747F1E447
+:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD
+:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB
+:10230000394ED467D87F51E66F785D24E81CA8D792
+:102310007E00FA4FF5AA5F61BF3797A5B25C987B44
+:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364
+:10233000849EECEE07CCC3A43F013767C1FA24ADFD
+:102340006E2AF963C3AF483EDF99EA95D064841AD8
+:1023500019C2C4D7272144F05E6D0AB2BDE7203D03
+:1023600080658BC99B69C1523277F5019E27C47085
+:102370009A06010BD57F6B8A3400BEB7CA539949C0
+:10238000F4FF2638FD6417FD207DF51892A395EE25
+:102390009973E9F96C35D5DD82FB6DB4CA77E793A3
+:1023A000FDF303C94B76AF0E175D7FCCB578AD0456
+:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86
+:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD
+:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F
+:1023E000C81E98F35B07CBF19B40667EFF11282C3B
+:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0
+:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8
+:10241000C176B512F248CFFCDAF17FB646701D4A9C
+:10242000830592D0BEFA35D129D9EF475DA19DD859
+:10243000EFAEE42DA91D588F9884FDA556069FA4E4
+:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A
+:102450004EADC5E126F94806168DF3D13B2EA67781
+:10246000D2BB3761BD0CB145F03AD157D09BFA577A
+:1024700060B97BC2EAED5468DC53B27727BD3AD528
+:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66
+:1024900043E6F72775590CFAC537CE1C7C1AF73777
+:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E
+:1024B000E0FF68FC851092683D0D7B4DA116264219
+:1024C000611F94E9F40891D5446FE50041A27BD8DF
+:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761
+:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51
+:1024F000B2D750218305EB49F8A290BB6E203BB6C2
+:10250000A502DAA93E092212E17B0A417A08F9C341
+:1025100032D3ED5450B8AED3F1F740E5F272087102
+:1025200079258485BE07B9F1299CFFAA4F40EC6745
+:102530005498E91D1D19F747686FC0E5B798C9EEB3
+:10254000F0FD30B1BF30A840870B22C473EE709904
+:102550000E814C31BF80879D9EFBA2F070C4C123C9
+:1025600089E0E18DC203E710F03803BE023E931408
+:10257000840FCAA7C9D025D13C8A66DF548297CB85
+:102580002AF073D90B5C5EA8F79C09979248C01299
+:10259000C84F009FA989E96684069F3F1600CB2F8C
+:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A
+:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C
+:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1
+:1025D000B958FF41C128511F5759684578D59B46C6
+:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8
+:1025F00081A47B8244C7A60C709BB03D505FE42D44
+:10260000C07A00E912106E7629A79EE06CFF397837
+:102610001B7015196981C905B8DEFCF99DAB053E33
+:102620002BFBCFC5FEC73BAD6CB7ACB10583842790
+:102630006477777D69747FC79FFE790D3D7F7A004F
+:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C
+:102650007283E21F38DF4C9A2F80EA49A6753D2528
+:102660008508FECBEBA7B13F7024CFFFFD82BE31C2
+:10267000E3E33EA4F134AFD073E0C92924B8958CCC
+:10268000F45F4BFD4EB850BEA651BBC0434F6563CF
+:10269000813297E68D7F6E4EF9E6862538CF52A4BB
+:1026A0001192D38B0B0237D2B84BCD914185F86C88
+:1026B00065CA3B36A60B05E993E403F12BEDB7069B
+:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA
+:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4
+:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E
+:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363
+:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D
+:10271000422805DF2FDBF77803F93BA5E8FF939FFD
+:10272000BC78D753CC6FFB485F22E896FEF7B3CF57
+:102730003F487C7A6512C7A126BD767408D94153FB
+:102740008E461A106D70E2D9372E13F4AFFB257F39
+:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972
+:10276000969982A26E75B855967BC24FAED1F6F19E
+:1027700019746E9CCF72453D504AFBC99480E56345
+:1027800048F81332FE23FEBFFD686835AD13A46F11
+:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038
+:1027A00029F9DDE417E33E17B71BDB97C6EA870478
+:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1
+:1027C000309A777E1AD9871329AE90405EEAFE715F
+:1027D00028B9F29102B697DB25E287324BE2FE0B75
+:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119
+:1027F000EC276BFC0A612FF3EF93A45788CE022FCE
+:1028000003D1C12DDA9E60731FA6B95B9B4CECC748
+:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4
+:102820004326D527CC7DCCC3F655908435FA556C1C
+:10283000673E99DE954BF33F992E838AF3352475D5
+:10284000E5929C559F757849EFC6AFFBED02E10F0D
+:102850000C098FDF14F1083C139FE7BC54BA89F0D0
+:102860007C12F99CF0B7CC35BC3F38C96E989C19E6
+:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B
+:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF
+:102890001ECE35F841F16551189153D84BFB1B33CF
+:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732
+:1028B000C00756C247B9D8876A77DB7D447FA1A994
+:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF
+:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5
+:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC
+:1028F0007BA6196403BD764A8B491E13DD23BD26D2
+:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3
+:1029100056926B684F574619DA8BA13612C0F514E0
+:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2
+:10293000FC52D85125F84FE8DB20DB4365118007B6
+:10294000900E261E37DA59259136F637930E5B0C1A
+:102950007100FB59E250C9851A7F0D8481C45F481C
+:10296000FF5E9263270F8BB893ACC17359B6D0CF7B
+:10297000CB5E96D80E5C76CCCC7AE22478BBF14361
+:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929
+:1029900001235C2FAB31C2353B6884EBE05A235CEA
+:1029A0007354231C87344D34F41FD65669A88FD82E
+:1029B0007485A1FFC8D06C437DF463D71AFA8F6980
+:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4
+:1029D000DB538F305D1D40BA32A13E287CE9DFE237
+:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD
+:1029F00099969798006A03F1E385C2FF1584FF94C6
+:102A000028FE75B9DA139FEAF81D42FA9AE565794E
+:102A100084F07EB22485E9E5E04B270F2B40F84F88
+:102A20008502DCEFAC29228E22C9C126A2934E700A
+:102A3000B591FDB9C61264FF4545B3702729E53845
+:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777
+:102A500087DB0DF5C297F61AFA1775860DF5F18723
+:102A600041227D55F0A6F7792A8B3E5438FC55FC5F
+:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F
+:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F
+:102A9000377247AAD73400E191FC4E03F9DF807604
+:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3
+:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D
+:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2
+:102AD00084F628D9230D157EB697A74370203DBFF5
+:102AE000069455C4779219ED577CFE3F23028D85DD
+:102AF0004562B1443F777D21B3FF3D85FC6906A661
+:102B000002A4F74ED0EFB43E78691EC5E34F902E75
+:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031
+:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA
+:102B300013FF3288EC917585C2EEB34B0829A4814E
+:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA
+:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B
+:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33
+:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24
+:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9
+:102B900097FDF5DB338F731CC52E99C047FE505A45
+:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3
+:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9
+:102BC00062F6B9659347E835F2F3DF6FCEAE84D491
+:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64
+:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF
+:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F
+:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5
+:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F
+:102C200011BD4471D844F6CC5D12CA0BF277495EEF
+:102C30007862E405401ED9FF7749A3BC44EFB6FD96
+:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1
+:102C50002EC86E00A7787F81CDC176E81D3EE12F9A
+:102C60001EADF8EA06B25F7320D58B32107FC27FAB
+:102C7000A2B8C97C531AEBFFD55907B8FE61338857
+:102C8000BC514DF821F25797A6A60ABB58C1FE5871
+:102C90003F9161E6FAA11181AF981FF3C39CDF5801
+:102CA000DA5FC4F3C01319447CF833D9FFB5E05799
+:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B
+:102CC000ED1A70AD05F1FE49B2FA395934637CFD55
+:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0
+:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9
+:102CF000038303561F8EDF66457BD2299ECF1E13AA
+:102D00008DCB9EB0624971D024513A7DC2EE75F9E7
+:102D1000449E532F4710CCB09CE4D3E57CEB708AE3
+:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D
+:102D3000F7CBF02F028117F71A5CAF6788FC05F11B
+:102D40009F4742BF16F721FB720CF167726053B1C7
+:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E
+:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648
+:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33
+:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1
+:102D900097F78B72AB117D7158EC88705CEF6CF11A
+:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271
+:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2
+:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB
+:102DD000AB743AB6268EFBD768F88CC74FC18860B3
+:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C
+:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029
+:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC
+:102E1000B723FD893867730AD3EBE2E7DE7AE7E789
+:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3
+:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA
+:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F
+:102E500013F2E3E27DBF7DD33496E8C41996B084C3
+:102E60005DC6F857BC9E7243E03A92237694236481
+:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2
+:102E8000EE2679645785BF362450C1F5E556E1AF8B
+:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533
+:102EA000ECC7E56877B0A79317E4F54232FA41E939
+:102EB00009EC069357E6785C5A600DC14BFAD1D401
+:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0
+:102ED0008DEFD3E281686772BCB314029A1DA1C55D
+:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0
+:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6
+:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1
+:102F100047DB0512D6D07AD5814823FEDA3AEB7723
+:102F20005D2F60D932E691C84A6AFBE6B44476A4C4
+:102F300043B303B8E847EB14EFD906AEBEC384FA37
+:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA
+:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F
+:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0
+:102F7000D16332C4EC9BED9E98BA14072F89CAEE38
+:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0
+:102F90008110AFDF6AF18317E9C9E6C176C3390C46
+:102FA00055CB7F220117C7ECEF1CF64576B955DBF0
+:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24
+:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF
+:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E
+:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063
+:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D
+:10300000A6379A4374CE46AA0A73DE3857058E4710
+:10301000A73603E72BB67B851FA5C7E947D2103239
+:10302000FA2D567716D9D1DB1BEFABFC318E732A04
+:1030300013174FF9FCEC230A8DB36D1A70FEC2D939
+:10304000F8D1518A7FE540D81BCEA1B89A04E11887
+:10305000BBF4FA600A8463FC896AA58FA15ED43947
+:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD
+:10307000D050BF492D33F4B7434E4B1EE55D1B2D99
+:103080005ECA8359686FA567C20D76D8F83D05FF03
+:10309000911F9383167DF7B8B88F74D56618D7192A
+:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5
+:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856
+:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF
+:1030D000E36FB44672FABEB7D519FDC9F446772539
+:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32
+:1030F00007E239B443D04708047D841A81F385A1DF
+:10310000AADC95D47E2A047C0A46A78FD1550B678A
+:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF
+:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72
+:10313000E79D819727049CF5F3E7E97170CFDB6188
+:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255
+:103150009B2177A4519C540599E2322F660F373397
+:103160001C9ABC8C9F19D88DF830A70938DF134FF3
+:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5
+:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1
+:10319000CB641A1FF6CA0328AE105267F3BAB737CA
+:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0
+:1031B00017DBFE8C696EECF920A40ABB3993F7612A
+:1031C0003797706911A5A2956011ED6189EA835660
+:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81
+:1031E0008A73193E694A86015FD61223BF23180FDE
+:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC
+:103200001C5FE932D510DD68E72DD257CD06CA47DD
+:10321000D567FF742ECBAF7A1BC31D5608BAD0F307
+:1032200082D6264187F1F4E3F21AE9C72A0D3489E0
+:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9
+:1032400001C467D6B8F1EC243C49DE78045F3A61EA
+:1032500036D07BCE123BE7B1413ACAF8B74E00E810
+:1032600013734E217EBD675DE777A4F30FBF239DE7
+:10327000EBF267AD57933F45E25CE429A46B8A1FEC
+:103280004DADEA04FEFE0ADC26A247A4835959C5C7
+:103290007CF4817F76911CB213BCAAD3A8DDD5A99A
+:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6
+:1032B0007989EAADCD16A0732628674C3FA2794BD9
+:1032C000EDEE952479A481E369DD853E943B1447B6
+:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6
+:1032E0003D110F47D7040D8EC508C721DF1E8E364E
+:1032F000AFD0C3E92542CEBE98FD537ED57D589C04
+:10330000AB495780E1FA852AF4F274E97898E4CB66
+:103310003A05E50BB6CFD0DADD25429EE870CED572
+:10332000E0ACCB9375F32183F8DE4DF2C44970FD18
+:1033300088F5765B9180334084F39FA98AE09335CA
+:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A
+:103350008397094C04DF78BA9421A68EEB4B8DAB92
+:103360007F5BF8964ED0F4643F283E1FF8AE4B4981
+:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D
+:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC
+:1033900018E07A53DFD5990CAF9C859944CF4DD670
+:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6
+:1033B000BD00DF5F8DF289F290A92501078DD794BA
+:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8
+:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05
+:1033E00076FA15FBAD1906D0C979C89083E0642B35
+:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3
+:103400003B85FDD5D23ABBD7F351214D2E6CA97324
+:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C
+:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05
+:1034300027ADCDA860395C051CCF5E99F239E7DF76
+:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5
+:1034500055BA62D457748E29B6DDE51D65684FC92B
+:103460002B30D493E48986FE5326047E3981E48090
+:10347000A7324E0F223F8E899EB36B6915DF4BE951
+:10348000F0D3F59353E3F33556EF00CA3B395B05B0
+:103490009F366B765E13C111CB6405F8DC8CEDB002
+:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A
+:1034B000D7286427B4C8C28EB78238F76BCBF4879D
+:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3
+:1034D000F4D239DB96D6656E5E8F579CA771E3BF39
+:1034E000447980F8F3358EA1C67339D6B39C6FFC4E
+:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC
+:103500007429F22FF778043CED3DC8A3D6387BD957
+:10351000A9E55F60A02F61FFA83D25F20BAD717199
+:103520007BF4C312E66FDE9A2071FF3F4F9085BF98
+:10353000660903C96B9717DF8FF53B14F17DE8B976
+:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1
+:10355000083B254916DFA1D84051583E81C887D085
+:10356000591FD237A95ABEA75BCE908888A13BE7E6
+:1035700019FEAEC88BD06716443F96E8FB17C4BF50
+:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6
+:10359000D1BF1F832E4F3180EEBA23FC5C2589E119
+:1035A000172678359AD6CDC8C5E7A95E8B173100A6
+:1035B0001525F25E3A5FB14A4965FDBEAA446E2701
+:1035C000FEF942717A091FADF955ACAC93867DC8FE
+:1035D000A2B7B1C4C676BA8E87246D5E444F679594
+:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F
+:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0
+:10360000C9BDA492E9C7F82097861F660DD2237919
+:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1
+:10362000CF6791FD86F92F349E60A0D0436051F89A
+:103630007B8333E95BF0B5DEAF673E50F5EF4E5765
+:10364000D2F9E0268F90A34DE07D3340F55724AFAB
+:103650002AD3F38237E9BCE9EA8116C6CBEACCD992
+:103660004DC28E177E53936725E76DE3F5369DD7E0
+:103670008C95DB745E3356BE37C9B37BD5CB59010D
+:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB
+:10369000AB8A392FD56CF13B485EACF2DC678AD53A
+:1036A000730F2881052531E793AC99B3F83D7BB6BC
+:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4
+:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A
+:1036D000EB23A2F8193EF4F26496CFEB441C8379F5
+:1036E00020665EA524B082D615C5AB390A17A4D3CF
+:1036F000E1F957B0DDD1B06E7632E169E7FADED795
+:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48
+:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD
+:103720004EE891E14F887D9C4987C6F5EE6CEBDD54
+:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0
+:10374000DCB8F65171ED0571F58971FD2BE3EA578F
+:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D
+:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34
+:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B
+:1037800073C543D4DEF5339DD94A46B17CDF81F65B
+:1037900015D9433BDB2ADDE27C4760E56E8D3E4870
+:1037A0003F58368879D0CE4AE6F89CD36390236799
+:1037B000C3B709328CEDB17668EE85C7F7D9E93326
+:1037C000A4D917BDAF5BE7E32913FC27490E414895
+:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3
+:1037E0009359C49FB5FB50E86E1D11270F684A38E6
+:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1
+:10380000094943839B28EE9B7C988FE740B3AFE048
+:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA
+:10382000C35877FD5D827021DAE9635B14B259DA1F
+:10383000948C243A4F946272B4939FB8AAB0CD3F4F
+:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758
+:10385000D9D265227A837C2F7F9786EB54C9C6B272
+:103860009677D5253A77BAF60AB7898CB0F419B2AB
+:1038700099CE11F79910E85B8AF018DC046605EB25
+:10388000196A98CFE25C532A0BFFEA196428DE6FAD
+:103890005716C1EBAB66DB7EAAF68C0F90B438DD11
+:1038A0007995FA38698234E887E38EB245ABAB8FFD
+:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5
+:1038C00098671E1FB812DB5B0B0799489EA67B52B8
+:1038D00013DE137375A9909FDB9B170E4EE48FE9DF
+:1038E000A53C13383021E76B25D1D4042C876AA579
+:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0
+:103900009EF8F1E794BA753B7B809F8D6CC877F683
+:1039100033D88B5797F6622FA279CCF1DAAD56796E
+:10392000009D23DCDA6C03BAFF616B3688EF905799
+:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67
+:10394000D14DC80486386EA6065FFB4493768EF28E
+:103950009B307DC7B755CBF36C8588DB9D1F8BE70C
+:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57
+:103970002B37E27BEB1ACD1C3759D798CB744EE32B
+:10398000907D746AC52133D9ADF9D06E263B7F1482
+:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A
+:1039A00061A0F0F341D0C5C0F9B438F01382CB1058
+:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF
+:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD
+:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8
+:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7
+:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2
+:103A0000207354565533BDFF14E11D9F2F0C07A79B
+:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C
+:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418
+:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3
+:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895
+:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6
+:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3
+:103A70006035FA358F2582A34EA73A3C6E78A26B4B
+:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED
+:103A900038F024BDEF6BF337701E7057275D47D4A5
+:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12
+:103AB0005772BC782F88B8589C3ED44BAB129F6786
+:103AC00010F7E58CDB6BB493915E958D9E587A353B
+:103AD00073BE33A4E9935013D22FCDB742D06F48B1
+:103AE0005DE64E44678F687A658746B7FAF3A13D75
+:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C
+:103B0000C0CBFC807C7084FA65101F607DF00A37A2
+:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188
+:103B2000F7D745343C227DBE43EF2FD9D475807C36
+:103B3000C5C12B047D7E4C77871545E90CFDC7F781
+:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9
+:103B5000B829C8E321FF1C2BE5713AC349CC724A4E
+:103B600025ED676B1BB8693FF65F1474905C3855A0
+:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F
+:103B8000AA33916C72298F6BCCFF0D6B33E20FE976
+:103B9000E76F344F91276013C1EBA08DE5690F7477
+:103BA00011D57BAA0EFF157172D73CB1177A3ED79B
+:103BB00071D7162B8E8945DF621DE7D84F8F379D51
+:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB
+:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436
+:103BE000889FAE008E03AD4C196B4A44379740FC5A
+:103BF00074CAC444F1D3C87B063B735593900B3A07
+:103C0000FC86578D4C16792948A57C891E1FD3F751
+:103C100075B7664F3669706B21B8313C05DCDA0840
+:103C20006E0C4F1D6E33843F425F8853BCD66316C3
+:103C300079B1910B3651BEE054A6C893D767DB44E7
+:103C40007B8EC82F9C411F9931F634F2C19A667160
+:103C50009F08BECF79B517B30F3886509E33D3CCAB
+:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65
+:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2
+:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B
+:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30
+:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228
+:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD
+:103CC0003523753FEA1147A2EF1852AB8CF4D8A206
+:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4
+:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86
+:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E
+:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4
+:103D10007E1CD773A2724ACF870D75DB985E876AC7
+:103D2000F74535FC7B4A68650EE5D76675513E72EE
+:103D3000E80E89F3EE439D7ECE43746C98CEF9F184
+:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D
+:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9
+:103D60006727392E1F107F3F4E7C7D4E99D0C39917
+:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136
+:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E
+:103D90007D4EF94093B3FF0997A29C3D5112389E86
+:103DA00050CE5ABA58CE8627289F919E5C4E177DDA
+:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6
+:103DC0001D0FF75C92F942C4437659223CA05F452F
+:103DD000F06AF32983A85D29510653D98D8F1F26D8
+:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF
+:103DF000C769642D4E93C7CF9B357CAC39031FEF49
+:103E00000B7C94E8F878EEBCF09151956168779757
+:103E10001BF191EACB35D49DF9467C240F2D308CD3
+:103E2000B7BC4C16F7240D9C68E877263E8CFEC084
+:103E30009DF45E2FF6E8C04067057D4B34606E7BD5
+:103E400007C9E64C7F5B0595FA3E37C7F9737AB927
+:103E50005CC35FE6D4C4F85DA0F15BC644E526030D
+:103E60003D7C2F317FD668FD979728B794C5F2F334
+:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA
+:103E800031F6784FFB0E242BCBCB78FD224FB6A317
+:103E90003E95F3663B92E476CA57ABF54EC3BD75CB
+:103EA00083E937AC67FEE89B0E95CED9D13D4168DA
+:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE
+:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266
+:103ED0007CBEEFC814EE63A27BB2C09D714EF92385
+:103EE0009467E25EB7C120BE238620EB41C90FE98B
+:103EF000F4DDB205FC225F4EFDC5F785BCF9140860
+:103F000073DD0511AEA7697EDE0365393C6E3AC8E4
+:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A
+:103F200036AD245FCE0250467EA073207FCF0B9526
+:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B
+:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508
+:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C
+:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA
+:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9
+:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA
+:103F90008F123F37B88AD9EED4CB78BC5DA12811F7
+:103FA000EA27395E1BF0619FA83DE73C6A627FA863
+:103FB000C124CE9FA9EF99D8EE827C41074E19F219
+:103FC00072C645C7717A838345DC49C45FEAFF74D2
+:103FD000D708B2BF7F99322B9286E31D7C55D87FDC
+:103FE00096A991CD74BF73FF349B773BF2DD3DDA28
+:103FF0007AEDA513EEBD137FBD798A90172E8BF74E
+:10400000F2023EB7343342F6A3ABD82253AEC01906
+:1040100097D76CB5B42553BCB275C77D15A3B0FB5B
+:1040200063752FB91B137CEFE9D4F29A23A5C472F0
+:10403000F09F939244DCCB67BC4FD85AAE9D2B497E
+:104040008554B2232DFF52D2129D07D04B7DFE2204
+:104050004FA48ABEBF8ED0256E88E7A292EAA464E0
+:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7
+:1040700035F6FBD3D61270911DEF9B22CEC36E5046
+:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B
+:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92
+:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9
+:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95
+:1040C00075725F016F0856D3BD9DEB5226F37D9646
+:1040D000D973443C78BA74B483DE7FB0C4CEF81B85
+:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07
+:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18
+:10410000F5A8192456715D3CF974C929D6E5157EC8
+:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7
+:104120001E68F726E19FA68D777A91D271BD71E75F
+:1041300085F475B5E1BAE8DE63D7508E4764CC31BB
+:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8
+:10415000FD85FFA785AF71AB574EE47FB6D64167AB
+:1041600055CCB904670F71C09AC982AE6D592F380A
+:10417000C84EF9C27FC4433878E59F073EBC97CA52
+:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83
+:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2
+:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91
+:1041B00093B87D64398492B07DA445C9BA99E8AEBC
+:1041C00053F2D6CB3488388FA8E37FED0D7E138C65
+:1041D000213CFA25BA0F639A76BE76C3229009FF76
+:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92
+:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B
+:104200004F3563B9328FE75704BDA475169B9713DA
+:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2
+:1042200077D848DECC4700D3FA5A357C69718322AF
+:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228
+:10424000C7E34818497894A12D99F4E14300ED742F
+:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3
+:10426000F91DB4579511740F8B83CB4EB457A9DC4D
+:1042700085F62A95AE60C575CB71DD7BDE38F8D248
+:104280000F71BA594AF5957444AB48CB7B81BA7427
+:104290005025AEFF06E25E51DF4289C4777D92A1D0
+:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E
+:1042B00094A108964C8B968F11F559E487C4B4EFFE
+:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9
+:1042D0005BBA45B5C4B43F87F572805735FBF1FA38
+:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC
+:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8
+:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B
+:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9
+:104320005A35C4C2F70FA13EF0F696AFB3782C9F72
+:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA
+:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89
+:104350004DE638AAE45A9FC2F731D535B13C7F40CB
+:1043600009FCB63CE67C4963FAC242922FFA3999BD
+:10437000E8BD47D798BFCDBDF71DD50780F4C297DC
+:10438000485AF65EE8B0B16EEF115AC7EABA762E17
+:104390009D6E85858DDD12E4B8CF154AE04FB43EA1
+:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254
+:1043B0003BE224B86F28F9C049F3B71E167CBDE173
+:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A
+:1043D000C0273EE5559661BBDF48BD9EE8674F4369
+:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17
+:1043F0009B6FE0E14195CE18BE818799AEBBF9462F
+:10440000ABF7CC377F67BEDADDCD37A2EECB074303
+:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9
+:104420007DD2C35BD418BE3A49F558BEF909F24DA6
+:1044300002B93F7D9246DF17986F522E32DF0C9DF6
+:10444000A4C9CFEFCE3763275D14BED9633A1FBE30
+:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902
+:104460005AE79813FE7D900F347939757EA0B28D8E
+:10447000EC1A45DCDF374D9A99E5F3109F497487B4
+:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541
+:10449000F58450B293160BBAE9AC1371DF6952F987
+:1044A000B4C5A477E93B024A3553F694EC02D4FB39
+:1044B00032D985D05EE1C179365499A04DA62D0739
+:1044C000AB87F1F861B6CF8668717FA7942FBE677E
+:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5
+:1044E000265C770AF931EE12F17750164D8AD7BF64
+:1044F0006887E0FA3A07DA984E362857F71A273ACB
+:10450000E35CB52F98302FF9D6249376CFBEF233E3
+:10451000A2B3DD6F6C49A673127B24E0F339F383F9
+:104520004FCD23BE73A942DEB4AEF833A52361D7C5
+:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21
+:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE
+:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD
+:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5
+:1045700066DFA4BE1743DE1C392F79937DA6BC39B4
+:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A
+:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C
+:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB
+:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60
+:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A
+:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95
+:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC
+:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80
+:104600001F4FBF489FE9938B981E2D742FF8179D5D
+:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3
+:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36
+:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5
+:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC
+:104650005132B47D6FF8E735EF515C63C3BFAE7D77
+:104660008AE21AF77D9DB78DE21AFABD726910FDD4
+:1046700091F5EF8F102E2EBFF89E24634ECC774518
+:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182
+:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71
+:1046A000AB691DC72336A05F558F78EB9823E211C5
+:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335
+:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41
+:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5
+:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792
+:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1
+:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA
+:1047100011EC47ED26BB06EBED934718EC1A7D9E96
+:10472000B566A821BB66ED0EF38C4476CDACF2C421
+:104730007E14D6390FE27039F8FB7F49FBFB5F51DD
+:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713
+:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C
+:104760004CF1E36F2B3F4692FCC837C88FCFCE4742
+:104770007ECC2A771BE2A20765B5CF58B2D37798D3
+:10478000A15ED6F42FD63BD1AF31219C7E5221B110
+:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB
+:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48
+:1047B000309B3E235A9772C3DD4914D72E17F70456
+:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7
+:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E
+:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682
+:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27
+:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1
+:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC
+:10482000457A3917E524FB29E61E59FD7BD659E563
+:10483000621E27D94F8551BAE8A82EEEF55EDA94AC
+:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4
+:104850009ECE2F90CCB27859AE3E5E89F239C178A7
+:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA
+:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B
+:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54
+:104890005DD7CEF5C773C53C132D211E6752178E09
+:1048A0001FC30F659FE03C31782E8DA886F6096FF7
+:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A
+:1048C0000CED6F950502538AE85CC363867ECEFCCF
+:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19
+:1048E0008302484F4867E9B5B2CA79F31AC197FD08
+:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D
+:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D
+:104910004CD4B76489F391C3AB447EA461A0B8972B
+:1049200044CFC36F7169F793F8C43D1A83F223FC37
+:10493000DDED20EDEFC139CB45FECC0D6ECECF378E
+:10494000D481F67D6284F31D1960F68AFBD5159932
+:10495000FF9E920542F5385F43BE5BBD85E44C3057
+:10496000D56BF6F29F960D99298F48E2899330ED29
+:104970009ADED1F2F2491F009F3BE886CFE7E27B47
+:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D
+:10499000130FD78E5F7CC5F72A6DFDD95759C4D444
+:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892
+:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1
+:1049C000C6E730B6D69ACD24274F2DB2305CF4F529
+:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F
+:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F
+:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE
+:104A000003C35742F8F2772A56D86B1A07F4870C7B
+:104A1000196EF1DFC7665425C79DE7319EB74AF589
+:104A20000D30D49DF9C6F356C9434719CFA90E34AA
+:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C
+:104A4000609A566CAC27FC77FF7D477AD88FFF7E43
+:104A50005C37FD86F47340129D4349637ACDAC12F6
+:104A6000F499A17D0FE3864E2E53915EA874529E59
+:104A70005DA273902AD351F4FB37A5577A3ADFBF72
+:104A80000720AD4CFCF700F473087FD1ECA8A553C8
+:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9
+:104AA00085FFADF2FF01C18CE32B00800000000008
+:104AB0001F8B080000000000000BB555CF4B1B41B9
+:104AC00014FEB2BBD144A35934B6865A481A520DCB
+:104AD000A4B06D37A225D2D5869283C8163C78E85B
+:104AE00021879CFAE358E86D635B904A24A9422F22
+:104AF00052C8C11E0A821EFC03621B7A8E680B52CA
+:104B000029C18AE7405B7A11D23793AC899BC47A7A
+:104B1000E940F2F266E6FDF8BEF7E6E50D68798158
+:104B200090A2DD137D40245A2A3848065468B930D3
+:104B3000305324E9A2FDB5AA94359114C0A9095CAB
+:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D
+:104B500031BB0126252EAF1F39000FB015B3E51666
+:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549
+:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3
+:104B8000C73D0309F29F3180FC30BBF3D0CD745791
+:104B9000343BE5A33C427B4548E42F5284DC078646
+:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95
+:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D
+:104BC000299DCF5C1121325DB71F962855D860AB67
+:104BD0005C237EA25255A755A1CF0334E894F70C6D
+:104BE000D347EABAFB243029535ECF0FFC1B8591D3
+:104BF000BA5D805261FBB7B51ECF71376D8410AAC4
+:104C000088751C15B6EE36CB3F866FA360673821DA
+:104C100030BED43D21E7A738BD5F96BB183EB1A892
+:104C20008B25B2478C508F13CE3DDD8D73FC7D6795
+:104C3000FC7502078683CBA22173B9650C72796C6F
+:104C4000F8B83C3246B83C34142E4BC61897408A0C
+:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3
+:104C60006775C78484F7ACCE432AB76BBA17253F64
+:104C70000D7C115DBC190A3D6F2799FDBB27028F82
+:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320
+:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4
+:104CA00096E711880B58A43CBC0EC529D3FDF4B679
+:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72
+:104CC000CB696A19829CD524997AEAD46F8F42F90C
+:104CD00034F45560FAE320AB677A223FA8138ED5EF
+:104CE0009B9FE786C92EB5232288E6BC5E6B369E65
+:104CF00097892B202982DC027F3B5C8F6BF618F2B0
+:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6
+:104D1000125D898C4675D2D66D9C07A70FFC7D77F6
+:104D200040CB33BC17C80FB8433CE7238994AB9EF4
+:104D30004FBB3A997974D7FACF9B2C3B12846FF909
+:104D40001F7DD8672F3A58BD9692423CD7228FF5E7
+:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D
+:104D600056F35991C83F9B4F2AF96FC1F737C67761
+:104D7000B59FF745AA6B46137CAC9FFB891B8D4200
+:104D8000F547904B116FD9A8A0E4E9FC97DAA17020
+:104D9000F796F9D0145F6DE8A36BCD73675B73551D
+:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374
+:104DB0004773EE34F358AEE24C567122DCFA3DD71D
+:104DC000EB355F1BEA488867FBE6EB797DD38E7F86
+:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66
+:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8
+:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A
+:104E000000000000000000001F8B080000000000F0
+:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161
+:104E200057F1A3F2CBB851F99E68FC2634FDE7D1C7
+:104E3000E4591820B4233BAA38B158988381410E15
+:104E400088353950C5F3A1E6D6002DE807E215AC48
+:104E500084CD7A27C5C0F05F9681E12890AE06E246
+:104E60004B4036931C0303AF34038307104703F111
+:104E70003B190686A940FA25106F9086E8E3048A5C
+:104E80009D9421CFFD6D42E4E91BC5D4C1B7955077
+:104E9000F993B51918AEE93030A8E941F8E791E483
+:104EA0009D806253B421EC70550686BDBA0C0C8708
+:104EB00095B09B1B0194DF07948FD0C36FBF831104
+:104EC0002A7FAB352AFF8B212AFFB2272ABFD61BA8
+:104ED000955FEA03A10135720CD6D80300000000EB
+:104EE00000000000000000001F8B08000000000010
+:104EF000000BCD7D0B7C15E595F899C79D3BF79987
+:104F00004972031708308941A2061C204040C44959
+:104F1000081A6C8A17A44A5DAA576A2D228F2B6241
+:104F20004D5D6B26EFF0B08DE856FE6AF5C26A97CC
+:104F30005AADD1D296B6DA26802EB61422A5D6B6B0
+:104F4000ECBF415D6D5965A35BD4B5B4EC77CE374A
+:104F500093CC5C6E1EF6F1B371BBC337F33DCE77D5
+:104F6000BE73CE775EDF7715D107FA250067F08F25
+:104F70003DCF170160E6C0335A01A57239C0262122
+:104F800068848BD8F34FD2F2CE30FB06567CE9947E
+:104F90008176578340F59F2F6A8DF7B2EFED93BE70
+:104FA0001A8732567FBC40F59D7ACEF30690000AF0
+:104FB000004A3A56AA09D6CFA6318D2AD66FD7B75E
+:104FC0002D0736DEA91205241CAF287BFBD67A807C
+:104FD000AEC90097C056B538C6CA47256333641BAF
+:104FE000A788C671CAFEB8085DA5407F67D8FF369E
+:104FF0007D290909366ECBA4AF2E47B895AE9B40EC
+:105000008F00DC3626093A7B3F0D449A9752618126
+:10501000C9CAAA6EC5AD29678FD38E7829C35E3BF6
+:10502000E24B2303EF97387861F8C8C00BC05C00EF
+:105030000DA67759580E00B5CFECD7B4C7D7E223E9
+:105040001BFFECF9F3F1A7824E7800B5239E880C84
+:10505000C0B3C9D7D725317C5B45603CC6AAE4B054
+:10506000712A5DFD648ED73F4FB9C3B3FE5310CE96
+:10507000029A8720BBFACB8467965D6F169B393EF8
+:105080009D79E5CCE3E30CD7FFE588E202ACDF11C4
+:10509000B7222E7A942D0FDE83767DCDF4D61B0CAD
+:1050A0003F21C4CF4CC48F15477A74E8580AEB0DE2
+:1050B000356C3E0516F449B94436268C02C8C77FC4
+:1050C000B126B2A65722BD8E32595DF67D74CC6AE8
+:1050D00090D8FB31F3D282CC9E1178487B23040810
+:1050E0004DC9196A6471BAEF9CD1DECBE8F614445D
+:1050F0003A36B36793CCFA45BC1D8BA41F632035A9
+:105100005C9C7AA4979523960C8DE5342EF1E1ED05
+:10511000D2F9C66646D29B6DFA6FAF57E9D95AAF3E
+:1051200041971FA0B93E4ECFFB4377FD1BF65F674B
+:10513000F9353F7BCA9DB73E85E52680048E1789E9
+:10514000F1FE4156B5C7342C8389788F94F0E74B34
+:10515000881706E7571926112F3FB0F1A44317F11E
+:105160006B93B13407B2E0D379864ABD7C16D08305
+:10517000ACE540D91FCFF3947DDA584F7D8042C211
+:105180001B9599A85825707914917BC0403819BE99
+:10519000B2CA055BAE48D2B4BE2E36BFF06CC5D8DD
+:1051A000C99ADE2D78F96B8CC0E9A34C50E91983BC
+:1051B000BE7D67102F8698DECCC60A4E2BEEEC8A99
+:1051C000E1988A3189AD63D097D6F2B2F01794CBCB
+:1051D0006FF53A70177FFCF891A4EE5422CBB87F9C
+:1051E000B0D7EF92D38755E47F759A98489721BC42
+:1051F00056824D1EB6EAB288F3FEF8E01E7ABD8EE6
+:10520000DBFCDC0A2AD59771BDCA07D6ABDD60EBA3
+:1052100085FC53CED7AB5DB6D491ACD7E3001EBCB2
+:1052200084FAF1D2C9F152F631E3A569EFF244965E
+:1052300079B4DAEB29836194121E141DE1DCDAC023
+:10524000E9D662749B4DFE0E860729E7583C5976D5
+:1052500036DEAF12F8380B6C3E71F0B4C9106BD269
+:1052600061C453470DCAADAD25A28872E9E3C2936C
+:1052700003D7E67EB8D21CAED28F172E29D4B53C08
+:105280001B3FB666F0E316849BD35D0DA73BF1632D
+:10529000A53B07AE00F2035FE7045F67F91F629D5D
+:1052A0005BFBD739C9D739FEF1ACB3B39F836A2C06
+:1052B000C7755BA5313E6470DC2C59CAF5B8BF8652
+:1052C0000478CC607480F08F617A66B8F1655D0710
+:1052D000B84F08707D435A919374C1BB4A663ACB6C
+:1052E000747CBFF5DCE410F380B4AFAFD78193F1E9
+:1052F0006FDDB186B6FD2E38BF24446204E76C989A
+:105300008D70BE1B5E9AD30583F777A25E6D907D8C
+:1053100000EFD75B6DFB7D677FBF59825436FDF28E
+:10532000415B2E80DAA9D0FCEF643C380DF1706E41
+:105330003544D97A841B47E13C20CC3ECE61FDEC5C
+:105340000A34C82EFC0E369F7EBC3AED98BAE3CFE5
+:105350003BBBFD60ED3E14928F080CBF2D31B11A9E
+:10536000E1524B208D6BE0DFB5A46B2C0C0E6F4B24
+:10537000EC6F03EFA0EB66D77B37DCD80AAC5D930C
+:10538000CF38A0333A692E108D461880C3A1176715
+:105390005D1C3C8E745D7EDB4F5F5B2F05D233411D
+:1053A00097A6FDF5747500E9EA82BF3F5DBDF18FF8
+:1053B0004B572784827F5CBA52EA24FD75666714D6
+:1053C000C9269793DA4A8BD61FC7667249EA98D6E0
+:1053D00085F212E2CC3EE3C380C8CA8A6672BD176A
+:1053E0000C40FD552DF1CA495FA1574EC6979B5DF4
+:1053F0004EBF9B751C57A171D13CC271E53074053D
+:10540000A25856A81F24E733E7303CC18335C5BCFA
+:105410009D81ED069B8F8CEDD878A87E9C29C27665
+:10542000FF9493C862F70ECCDF3B4E7C59222711C4
+:1054300019797D08CBFA1B2EBC0FDE4E86371CBCBB
+:1054400030FA2F453F49C100FECD5DB790FF2200E5
+:10545000A241765D61AB855FDBF0FFCDC17D9FF33F
+:10546000755BE1740DF52D60FB0DBEB7842F0096C2
+:105470003F1474E25B673C299C00A21BBBDE70EB0F
+:105480007F3BF25316FE5E21727DE3FDBB52FF8D22
+:10549000F6A0B559D01F63783D54FF01BCC6F87221
+:1054A00065D7790AFA3DAE134751BD95F38A940545
+:1054B000AE7E5602B70B017AE52511F7B80D5C0FE9
+:1054C000ED94F6E2BC5FAD90D2B8FFBD5AF13FA4B7
+:1054D0009FBF6A4A6944F2ABED57E60C25770ED5BB
+:1054E000737BD6A977C894687F3F24F786B3E9F128
+:1054F00003E3A769FC2B2A24EF3E2DF7CAB8FEEF81
+:105500007F097CA83F1FAA5785D72631E317E7C933
+:10551000E868654591827E87E1E6B5C8F68339F88B
+:1055200075E6D91C16699ECDE12AF25B356BEF92C8
+:10553000FD788ABD47793018BC8EDFAA595B9A1571
+:105540001F4A84EB5B8A2F99DDDEB4E7EB9433FDD1
+:10555000590E7CAD616E17B586395CAD31318DFC6D
+:10556000DF1ACF3EAEF36CB2E173EA35C7B85EDA4C
+:10557000CCE4C948E091C35E7818DA8EA0BF64BC61
+:105580002D6BF26B7B1A3E8F7676326C4A06BEE943
+:105590001126B0F2B8B8049B35366E4D557B356395
+:1055A00081BC1589171918301A3A2AD10F38F14BD6
+:1055B0001BBBBFC6E6356E8E5FC3767935A9EEE7B5
+:1055C00058BBB14CCC49ACDDE8636BD7A29CFD174E
+:1055D000B41351105B3736A01FAB1987980BF0B08E
+:1055E000B8A212FD6C3270B9C0A49E2E8F42FF0C7F
+:1055F00090736630F9C0FE8433FE817683E12D62BC
+:10560000CB2B9A37C9ABA543CBAB8DBC7F8BFD872A
+:10561000F266DCC078D47ECC2AC583C7D119DFF707
+:10562000DB74E987257FD771C6C2D200EA2791656E
+:10563000A296C6FAD0998B7EA8516B64E8C2EFE5BA
+:105640001D0D4C7C0C8B7726F76AB8DF38292C713E
+:10565000C1FB2B91FB9926DC715410D0EF6B309578
+:105660007E1A96EBA665A3D36D367DF6976B560A28
+:10567000491A2FB16812CAB55A91ECDE7F59363DEE
+:10568000D7DDFE037B9C81F5075D9E8565BEFEF23E
+:1056900032D10C4CFDCBD75FFE88EB9FBF51F1ECB4
+:1056A000A71F755D64B43D0A865FFFBF761C67DD8A
+:1056B000CEE60F2E1F27DC511D40F9775F6268B9D7
+:1056C00072F6BA2DA5751BB50CCC7416B9129004E0
+:1056D000CFBEEA3C554881C1D6593A2A917C9346BF
+:1056E000CF5ABE03061F578A2919F69BDD9F65EE28
+:1056F0002B61EBFF4970FE7A649443B52887502EE6
+:1057000095FB5E77FB4718C607CA0CF76F7F71DF02
+:105710007E9447169347E83FCDFC5E8B65173D5C52
+:105720002AF1FD77EF777E79AEC0C6396CF8753F08
+:105730007B7550E87983FCBE9512EDC7089F3A0B44
+:10574000DB032927874DC9AC66F57BCA05DA47FD1F
+:10575000F0D2B5FF4CED4314EFE899F7DA972F62DA
+:10576000ED3F79B10F39876302DBC7D93F51AF39BC
+:10577000DDFBE58B58FD8317E70FA96FD5E27C5D54
+:105780007472C5B3DEF20AA43784FF3FDEAC7D90AD
+:105790008D771872127E7C5670F80E237C48F7BD08
+:1057A000BF7E03F5C243A640FEA8C3153F8FA13DAF
+:1057B0005E690AA42F2E9E27A4FD59E6B978DE2D36
+:1057C0001327B0FE1246480BB0EF072BDFD97A1132
+:1057D00083F78AEF4B77E3F3E41EA920593638BCF0
+:1057E000CEFB2B4CEFFB7EBD189216E21D341E97AC
+:1057F000F0C58CB89B5EFBF518396166F3B7AD91C7
+:10580000B8FF51D00CD2EFE4B002388FC1EADF38D4
+:1058100008FDE6405F97847038FAF7E92B75B73CCE
+:1058200074E050E44412C791340576A29E917B95B2
+:10583000EE9E7FBDC4E34242DC2478148DC3A3C82E
+:105840008699CDDF5467C3E3F403D061B7EF83DEFD
+:10585000F0007C2D81C472F45B58B9DC7FD81CF158
+:10586000FA0377DBFD3CE6F4E783AC71158046EA8A
+:10587000BF6A54858AFD3755703D490783FCE3CDE7
+:10588000CC6E8421F4BAADB6BCD88CF10D3FC639CC
+:10589000343BCE11E7FA53F819F2939D2A13C9AE9F
+:1058A00019AC9F88E1D54742A55E3BC6D15F027A1D
+:1058B0005E861FC8EBF7F18D924547EF437A1D0EC8
+:1058C000FE7E3DCFAED726A7542D2B9ED243EA7342
+:1058D0007F3FFCF1F6215FA7960DAEBF15DE1CBA27
+:1058E000CAEC5FC95752698ADB25E21E7DC09693D8
+:1058F0004ABE9AC27D01D4C1BE0779FB30FB8EF14E
+:105900008C7042477F8A043C2EA4221FB8F0F38E8D
+:10591000DDEE1A59B4F5F914C541053D457E3BB598
+:1059200090F18F70763BE7D96BB76FFBD3ADAF10BB
+:105930007F14A8C41F82CEF827CB388D92F996C465
+:105940009EEB24F36D7CFAFE2C25B3F1C97FD9724E
+:1059500045AD4DE86A31C515C91EC9842320F37EC3
+:105960006F74E0B75214A71C29FC1F8C107E671CB3
+:1059700006BF2C1710FC3E7C0E06BF64C393077A4B
+:10598000838C724DE7F2156089EED64B6E90B9BCF0
+:10599000C8B3E513C02D71B7BD759DDDCF48E79342
+:1059A000278F6C3ECEB86C3E1364BE1E13E521D625
+:1059B00063BC0DC70D32DFEFD4EA841E67EB923B68
+:1059C000085DCDB3E148C9A2AD57DCF291E8EA82A7
+:1059D00011CE63DEC0BACCB6D7A562A879CCB2E747
+:1059E000D121C19CD7512F3EC7F1F72CF5ACCB6D1F
+:1059F000367E3AFCCEBA6CF0ACCBCDF6BC463A9FC4
+:105A000085767FC3CDE7B681755962CF67E950F3DC
+:105A100071D5BFDAAEBFDCAE4F76C76D726923DADF
+:105A2000198D5262855C30301EABF71977BD779ABD
+:105A30004E35D8F5AEC7F7420DDFFF58BD95EE7A6B
+:105A400060451BD13FD082B602B3634A9AE756D96C
+:105A5000ED5651BBDAFEFE6FB2F983DA059A854640
+:105A60002B4CF5D662BD86057F76EAADF3C27B810D
+:105A700003EF0682B7BA1F8E5BDDF5E6C9E3A8BF68
+:105A8000B3E20E23F407F962C9768CF3E741A4036D
+:105A9000F33C5AE5D42398076059323C86F9047EDA
+:105AA00043401F5BB422F56F582FD762F635AE5BCB
+:105AB00055EA292C5B22249ACA299F80F205EA64C0
+:105AC00055F31B987F61C07656D662721AEDF316B5
+:105AD0002169E1BEF83329F96599E4ABB6A201FB6F
+:105AE000CFD7B99E0EBDB46F3970DD13BA96F21FD1
+:105AF00072195CE88F6AC980EBFED0846EDC6FEFB0
+:105B00002D50484F66065629CA97DBA5A081FD7522
+:105B1000177C81E0DDD6C0F31BB67DF20B04EF7D70
+:105B20000250DCF63E1FCF6FB8C7A76A8D1AF61772
+:105B30001DF339CA87C8D1FCE5361C08DF278A095E
+:105B4000BE7CD02A6F10487C75A37DDB52A190BE2D
+:105B5000BC2D36BD92FAAB50494FBD2F31BD81F4FB
+:105B60008E8A20F9E8F3C306D9ADD1D90A58588EE8
+:105B7000190DA867466605310706F20B01930B2045
+:105B80003219D258F6414747097B46DB995D924F5F
+:105B90007613DC80766F05C33BDA11967904ED92BB
+:105BA00030D87FD24113E7ED1B2701FA3D9CF58DDC
+:105BB00076F4B71FD2EE8AA64758AF6B64F522ED94
+:105BC000CCEE9F31827A1D23AC971E61BD2E5E6F95
+:105BD000587F87C1ED3D95FD87765B20D36E0E7BA8
+:105BE000ED615FC6F7CC785CE633331E7242F6C6D1
+:105BF00043866BEFC441869B2F3A25FAE19486AF2A
+:105C0000EFE89B837D57C65E153759FB9631D7C4A5
+:105C100049AE8D59C19FE3EDF7E397DBE56BECF2FD
+:105C20008AE56616F93EDAC7E57029FA4386F23B43
+:105C300000D71FDF60B09F1130796968FF49A6DE89
+:105C40009B29EF54D9AA427EDD96E07E4D3F322358
+:105C5000F26121901FD607A98E1294136046178E09
+:105C60001AE01F9FF98289FC7C688C044205AD8F85
+:105C700041FEF40C3AC9A40B7F863FE7AFA5930B16
+:105C80007DDE78ECDF8A4E94766944FCA3748CB098
+:105C90005E7A84F5BA4656CFDF2E8CAC5EC708EB31
+:105CA000A54758AF8BD76B9DA3F0FD1CBEDB689654
+:105CB00030B8E7AA9E72EBDCA0F7FB45614FB96DE7
+:105CC000A642FBBF53F6CF523DE53626E73DDF67E0
+:105CD00087A9BCA9A5AB8A6D6523E693FFFC0BF9E8
+:105CE000A4541DC62F5D2166D86D197CA5EA016CF0
+:105CF0009F2FEB80F953F931BE4FB1A799CE82DFC8
+:105D0000476CFEDF29F3FCCD6DB21E40FBF11F7D19
+:105D10009E0D3E0EAF33DFE1E075E4EF9B92AD6F79
+:105D20000D96F751CDF3326508525E6649B5596557
+:105D300032B924BFC8E36099FD5EAB249FF6B9EC8D
+:105D400061594BF2F89EDDDFA20299F41299C93530
+:105D5000D47B1448D414511C51247F9F1C1E66DF31
+:105D60002874C9ADE221E0B6F358E9930E50F93B2F
+:105D70003E6ED00092AF11E825633A07B59E73508E
+:105D80004FD305A0F686C0FDE7F334DCF76281BF90
+:105D900075BF2BA85FC1BC07CE843E42BF722FF9EE
+:105DA0003BFFE6FD0E036F00F37B2FA01042CC9D5E
+:105DB000DFEB8BA7E8259C3E73469A05BC09FD25C1
+:105DC00029BE2E8B06F943616C94ECB296D806D5A9
+:105DD000BDAE7FF4157BFC268AD67A8B1065CFC2C8
+:105DE0003566EF10747E068331E81F29BCC1EC1DB7
+:105DF000623FED8F6762BC3E0B1FB42AC934EAEFE5
+:105E0000D68430B7E7E514F919DB84BCE99BCB5D98
+:105E1000F45BA874215C9172D3427BAF2D5F345048
+:105E20004F95616B8F3095B5936A8D64163D62A076
+:105E3000BD7CC23D9F98E2D5A79A86A1F79661F4F2
+:105E40001E9F6224B3F943272BDCAEF505B37FBF59
+:105E500043AC2A51669E8D37A6E673FB3617DA856A
+:105E60000B39F950BE43E10BAF201E5A0A2E8D0F9D
+:105E7000355FD0BC7997378AE634656838666683C3
+:105E800063A4F9205AB54174D8AF2FC5385DA39EDD
+:105E9000248CC27C0FFE7777F9CE2ECC03F15DCF38
+:105EA000E3B292B90BD04FEDE84D92193C2ED27A65
+:105EB000CEE3FA5329D7874CF61FCE233A6F68BD3D
+:105EC0005ACA282F51BCFA5053FD1EC0F8BC03BF5C
+:105ED000E3C7CB9CD75CB1EAEAECF818993D7C1F8C
+:105EE000A317988CF1281591021DF51A95BF5C1F18
+:105EF000A7F2D67A9D9ECDF5A5F4DC824DE7209FD2
+:105F0000A7DA8B18DEDAE38FC63FC7AADC87B28335
+:105F1000F6FD6B17A09EBCB9BFCCCC4006F7660C53
+:105F200078333DE256E58A0568BF6F0E80ED57581D
+:105F3000B0C0F494AF6AAAC4B2ED67D8DC7A1DD5BC
+:105F4000BF6F3CD8E7204CF553AE7DEF11C547FC41
+:105F50008D7B0B6F6F36617F01D92EC32D0BBC6516
+:105F600030119E80CACBFB940DD43F890036DE4FA2
+:105F7000955BF97893B81F1FCA960E8347EED70733
+:105F800045E7F2B32C8FF25914C340F72BDC976B23
+:105F9000C33DD27EE424DFEF8E66DF2F07F86698DC
+:105FA0007DCD8663B8F567E8B0FD1049B070DC5F61
+:105FB000F038E2DF7BDCFB7C1F0D2F4A459F85E735
+:105FC00047E629C9EF21BD47CCCEAE22568ED67604
+:105FD00059C4BE231CF75E45B3E79D24FE77F0EC61
+:105FE000E81DFFE5F3AEA32F66521E5220CCF96FD9
+:105FF000A4F0F6A27E3573A01F78A26ACC50FA5A9C
+:1060000041424425AC5F5EE4D704D118EB2FE79AF8
+:10601000799E724EC5584FFD8851ECF9EED3CEF7FC
+:106020007CFF4BD7E91719F3F889AD373AE51F67BD
+:10603000CE7384FD3AE5EEDE0562295B87976B251A
+:10604000D2EF5EAE7DEDBE19584E4814BF3DB5BCD3
+:10605000C9878C7414CCC84CF4872525DB9F6E8EC1
+:10606000477CFE02FFC9C67B09F73D269F0EDBE792
+:106070007F989C188FE79F0E5F3C7B3CAEEB611FC7
+:10608000E76FB03A483EFDDC071E79F0735BFE18FF
+:106090006DDB9BD00F7954E065A96DFB028BE28329
+:1060A0005B5B2F637ACB951C85B0B456C86A0F44EE
+:1060B000FC0AE1E3432119F1B3799AD57A4B0CF349
+:1060C000DF74207DD50F09D2CBEAC0AA1451DF615D
+:1060D000F447716EB9AF309BDEF1737B3FF7C39528
+:1060E000A4EF2FADCDF5A131EFAF99E6433FEA958F
+:1060F00035953EB0F565CD059F9810E8FCD4B25AB1
+:10610000FF4EC4EB32D9F4658B6B5D99F07BF6A939
+:10611000690C8708FF51FBDC03405FA13BDE34CDF7
+:10612000CFED9D78C9D0F68203B7535E523BED792F
+:10613000C403C3369D4701B5AFF0DA88BBDF9013C7
+:10614000178E60BF2F2FFF2CDF9F195DA05FF1C559
+:10615000E39FF7515C7659BE87FF96564B1EF813A6
+:10616000F3429EF255B557E60CA97F24FD19F2CCF7
+:10617000B2CF618A2487371F13483EE44CE84B6353
+:106180009E26BC2C01D7FF1CFFEB5CF2BF46C7F577
+:10619000E9A82FC06F43DA632EF9D96CD3E560E329
+:1061A0003FE7E77AAD9C5743F1EDF78F0B3ACE57B7
+:1061B000C8AB9B8CF39515B311C76D2E12D318F78E
+:1061C000BEBD789B8AEBBDA9E4A3E981BE188FF719
+:1061D000EB96361DD97FB07669939F23C87CBFC6E6
+:1061E000CFE32D2DD652AD049771BF5689F30F140E
+:1061F00042D673A68CFED7F8D16F1FB380C7D713D2
+:10620000A45797A82B290F571E3B74BC36136FB2A7
+:106210001D07CCACF7A44D8F25153BA9DFF7CF1B8D
+:10622000BA5F072F1F1822F4D8FA04D65781CD87FA
+:10623000E17F4B29CFC36D2E7B86F02C9995A4CF9F
+:10624000FAB49489F5B694AD24BA6C6175F2D9D0DC
+:10625000B9D59D744E73CB9F787CE2C9B6FD4DA82D
+:106260003F6CE9BE0930AF32184F03CA8F2D536E11
+:1062700054110F5B7600F4201DCB9DE4940BD9FEE6
+:10628000F0900669664941A8CC04940B791A3F53F3
+:10629000B9375E05B86E5BCAC140D6CC4FA71A307D
+:1062A000F4B325CEE3DFC152B3A608E11E23921852
+:1062B000D021D98EE5E65A99E6D1AA717CA0DD7588
+:1062C000C6C9EFC23C98126E7795A07F9FF5AF7C50
+:1062D00089CF5BDF5E427EA22DB92F9BA8EF5A9F2C
+:1062E00004631270BD96F40499D111F65FA7655D41
+:1062F000F7AD62F29B7E57FC5ED67401E934133F22
+:10630000EFFBE0729C77F334117666D137F6F879BB
+:10631000BC2E6D2CBDA238CB38CFF9754F9E80FEB8
+:106320008142700F567FA09E4C7E7D343C16B17921
+:1063300014D4707F29649C638D4192ECDBD160356D
+:10634000203F3AE757C755277E95644F29B28CF214
+:10635000E9063BCFEAE479AEACB00532E857FF86F8
+:10636000CDF7A6033E40BC5D72FA9117305FCA5765
+:10637000E1D728BF0A3A5EC0FCCD1B983A86E59B60
+:106380008E4D5130FFE7E5B112E6C620FF44910E75
+:10639000DF0691F2CFDE8623D1192E3A7FCBDE774E
+:1063A00050B2A21C69CAE5F392C3AD3D5214D75D49
+:1063B000B67A9DFC3D5298785E3B84D97B95B28F2E
+:1063C0001A48FEB5F37C21273FF2731DDEFCA1CFF6
+:1063D0006FF7966F84A5A3906F6E640A5D9AF57B44
+:1063E000933BEF8B8D7FD4CFF583CF43AA15F79FD7
+:1063F000363B3F66EDF7A62848D737CDD08AF01C4C
+:1064000086338F3FF8B91D7A82F1A9EEE2FFD5B14C
+:1064100034E52767CEEFEDDD0BBA92ACFC9A2EA7E0
+:10642000B89DED9D679BAF6731E67B5977FB6CBDEF
+:10643000C19BE7B87A57A589F9620C7B7ABEB73D54
+:10644000C1FFD976EF7C87C347E6FC1D7D70B0F9AC
+:1064500028BB84ACF97E21D59B2FD5A4F278A3D993
+:10646000244360FED9E7A3ADAA149D6FB61AFD5A66
+:10647000538CE29314FFAB638483F1BD7255A77E06
+:10648000DE0F4C48039D4348CD46FDE8AFED778EC7
+:10649000CAF9F06FDDEFFC41E05DABF62AC89FEB77
+:1064A000E58E1AA178E07C40C06799E318BEFD7BB9
+:1064B00096748D034FBDF611D63B8047A04750AF71
+:1064C000461CA2BF93F6BEF5EF4FFCAB82FBF7DB99
+:1064D0008F1F5F8C72EEE61F4AA0B27A279F88401A
+:1064E00017ED3B6905E5F2EADD12AD3FC85DB3AEDD
+:1064F000F4E4DB37D1FC6F7E2A42FBC3EA67FCE998
+:106500005AD67EF5775F9B0A8C6F4F36F6BD300EFC
+:10651000F1F7B8C0F318ACDEA957B2F7AB65B82EE7
+:106520005B1EC2F52AE7ABB7BE1F5A8EFBBBB0ABF2
+:10653000FB5AEAB7F36A9FDF257F97ABDC9E66F5CF
+:106540004CFC6E7D43484F12387CD9F2F2DEFA06DD
+:10655000F7A3ACDEE34B639EE2EA5D3B9424ABB76A
+:106560007ED73B44DF0B9E7A328A7858BFC77B1EAA
+:10657000E1E6A7FED43AB79CCE3BF5D5A2FC934EFC
+:1065800053F994A9F6F13C78EE8F59471CCBEA7D7C
+:10659000FBCD4B7FC3BE9F884B106022E544CF7F6D
+:1065A0002A3FC472329C62A28CF5EF7BD5CD87EB7B
+:1065B00077BD46E78E349129B017E179888CEF19C1
+:1065C000F5999EABA03C5CDFB9E91D9497EB77BFD2
+:1065D000FD6BA4BBF520BFEAE6E713F88F3167C770
+:1065E000B336A95E3FDD2938388B1C00BBF2B3DA25
+:1065F0008B4E3CCBE1EF9B9F3CF530EA116F3DF3B6
+:106600005F0FE3FD0C6BFEFC3F0F635E2BFC28A0CD
+:10661000A1DC5AFFF82FA2E0C2FFA3B67C38F98DA7
+:106620007FFBFA030C0F277FE527AC9D7CEECD099D
+:10663000784FC7C9A7FF7714EA1F1B9F5B381AE979
+:106640006CE377168C1EEA1C28D26DDAEF5EDF341D
+:10665000BFDF608F809B20C0B3F633635DE0609F37
+:10666000827AEF7B02F46DCE65EF3BFFA4A0FEF2D1
+:1066700082097D88A77DBB5F7BE10E567E9BAD9333
+:106680003FCB3AB1F98F13697F63ECC39EEB765F22
+:1066900079C5C5E5F8F419D8FD7AE8A37DE3ACF532
+:1066A0003DCAD6B77C607D33BF9F82D30AE27FFDAF
+:1066B000136C3DA7E2BAB2F59C7AF67ABE8DFF98CC
+:1066C00073F67AEE53BDFEB853B0E69107F0E3EEF1
+:1066D000FCACF6ADB39E6BBFF3A921F572473E0C3F
+:1066E00087673ADFCBE0FA8A6AFE5C45BE7DE69BAF
+:1066F0005F7F20C6D7B99621E6E493A726E0618D97
+:10670000DFF9FAAE453CF43DE7D7508F5AFDDC2F58
+:1067100089EF4E7EE7253AD7C3FEA202DBEF4E4259
+:10672000FFDF1160E575022FACD5FB2EFD35EB7751
+:106730002DEBC23268FD2EFD7539AE9FDA47EB9125
+:106740005E52A3A3FC4D17D0BCD7A5397FAC4B77C5
+:106750002F437F7626DE2301279F70605DD15FBACD
+:106760006EF7F14B91FE065B4F67FE1ACE7F36FB4C
+:10677000FEA8977F07E5577B7D4FEE785F41FDAA26
+:10678000EB878A26323BFFA4AF4F198BFBCDD39208
+:1067900086E78D33D77D00FF8D59CF1D673E33E9E6
+:1067A000C31FC81EBF76F0341CBF0F3FBF8F86BF0C
+:1067B00053F63E9C89C7B74E67DF0FCE09707B6EDC
+:1067C0001D74D4A08A99B99FF920658D2B1A80B7C2
+:1067D000B5532239FFD62EEEA7C99417EB06B1CFD9
+:1067E000A639E3ECE99E8A72EDADBDDFB7E992D33D
+:1067F000FDBA278E2B96BD3FA45DF85D3F88BFFB99
+:1068000022BBBFF5CF66EF6FFD13EF64EDEF846C35
+:106810005E8DF09FE8F1515ED2894E29AB9D3B29F8
+:10682000E0F3E85DAD9159AFE4B076523448795762
+:106830004D8DE62FD14F6A1DF1D97E00E377986F19
+:10684000D51409D239F7A6E88D745F92D35F730629
+:106850009EE47882EC27399628E731B0B4C78EF1F0
+:10686000318270C30DB255887AFFA1A23765ECF76B
+:1068700030EA912EBBFEB00C2DF9E5782E42301A8D
+:10688000208B7F23A3FFC43C0974B79FB06B8CF8A7
+:1068900007D6DE7F544A236AEB20D545E7020AA1DA
+:1068A000F3B12CFD3D54AF93FD5C94B88EFC3FFEDC
+:1068B00054CA447DAD70A3562CEA838F3B3EE58DD0
+:1068C0005F8F6594FF071CE7808FF441D8F5F8E3EC
+:1068D0008F8FE25B0AEAE52FE093C9BF4B56E9854B
+:1068E000587EC89E37E3013AC738DE4AC828E78495
+:1068F000D81219F58B85A984BCD2B59E0B63C258FA
+:10690000DC4FD383DC03F5BD00DF3F1B1AAEA23C96
+:10691000F607BF24125D3F18B8AC10F96C7FEEEC9F
+:1069200030FAD7BAD7CE3A3899C1392E2C019A9C71
+:10693000FBC2439FDB7CD8F62FECB4EF1F7AD4CE9A
+:106940002FFFBA8DB75DF5A5F47CBCDEA0EF4FD468
+:106950005750B9B3BE869ECFD427E87DF48E60121F
+:10696000E97377FD727A3F0EDE1170FDBF5B9FA465
+:10697000F2A3815C827FE29D2026D9FB85888FF07F
+:10698000C0BC1D78D2B6DDFDBDC08F9B912FFAF142
+:106990009881EF4BA04750D17F1513745CF7BA80F4
+:1069A000CEF35C33F03BC1DF27605CAEEE4E9E0F52
+:1069B000F1B0E03DEF70BF2DFFBF6DF3E93BD1E4D7
+:1069C0009301D6CFBB35CB4A491F02AD0CE9E66136
+:1069D0002171D828223C7BCE9DACCE4B7E3BE0F291
+:1069E0000F4F68E776FDF6802DDF368288F4363E5D
+:1069F000053AD29B33EFBD957A21CAC5BD8240EBE3
+:106A00008DF456EAA2B77EFA0DD879C9F1ECFBF8FD
+:106A100000FD72FE8FCF2DBDA71AF1B241243F4871
+:106A2000137E72B5FBD0A62366B78816D2F32A91DF
+:106A3000FCB9138F1D172630F874ED9B01BCB72BE2
+:106A40003E016C7F536700E9EBC155DCBFF8B563CD
+:106A5000FC1CD3A98DC54B26B3FA8B197E30189533
+:106A6000B7A8C4E3B774CE2F7C4D4DE46843F8B7A4
+:106A700032F3DEEE9F78D707396C9C71C7423A9E9D
+:106A800087B967E28FBA15561EDB2B903F696C38C9
+:106A90003519D7B3F2FF7F634CAF6B1D1E589B9A1D
+:106AA000887A63EBC46F09C807634FFF58C07D64E1
+:106AB000A2967C33C0D6619C6C9F139653B3D12EA3
+:106AC000B8262FF17B5CB74461FAD3484FA76A36EA
+:106AD000FE3BF6EFC421EBEAF4DCC92EF990799E77
+:106AE000E2A1D4D0FE4C67FE0FE1FC87A8E7CCDF23
+:106AF00059BF5335B135281733F199D96FDEA265E7
+:106B0000438EFF907D8F189BBF3FE8A2CFC254AF4A
+:106B10008CED9CF683C55D33E7DBEF271A619CB6ED
+:106B2000D307F948174FFF71C2B70F03924E424285
+:106B3000FFD4DE40724C7026DE1F97A232938E94F3
+:106B4000CF7E412EE7DF07467D7D0CF19D9C2EA276
+:106B5000BC8F118ED702894425EE73866864DB07EB
+:106B6000A60439DDCF8314F947C5D09D43C7F90B7F
+:106B7000BD71FEAD409300AB4BB5E31F206BE80F3A
+:106B80003B00D3D10F991FE4FC5E2973FB72C60151
+:106B90007D87C4FD56D292880B7FB6DFCEC7BB6619
+:106BA00070DF099A8EE7BEA6750B2E7E7D3F949C02
+:106BB0008FEBA6C4B93FD2174BD279CB855258245C
+:106BC0007F6E0797FF759050CFE37119C079EB1076
+:106BD0001771BF7F68233FDFAE6B2182FBA1984E08
+:106BE000E53A5B4FF9B14D47DFB7E5FEF76C7AF94F
+:106BF0000ECA7DF62CE935F7E730B8BE6DCBFFA79E
+:106C00006DF9FF942DFF671EED856F94933C363030
+:106C1000EFF9CBDBE28D38CD27EB4DAAB7B37E156C
+:106C20003DF7E58E16F7B07A8F6E1477223F3FAAB4
+:106C30008DBE1CEFBB4A9BA221B0C60F59DB164488
+:106C400019FC3B5481E2670FD7A7A8DD0E556F549E
+:106C5000319EC2AC650BC9A0AE87C21E95BFEBD3F7
+:106C60006A58BDAF75E45D8E71B87B6B646AE7F0FE
+:106C7000913E73033687689E3F886C9557D0A59EDA
+:106C80008376FA4691FAF94AE033EA02F61C3FFEAF
+:106C9000887A998E8B71DC4CB1EF0B1892711E15AE
+:106CA000BDBD16964B5E0F53BEF6AC577AE16956E2
+:106CB0002E5A15A1F278CBCB175376F75A1D0C8EAE
+:106CC000F16FF1EFD579BFB73A59FD9C0D51EAAF9D
+:106CD000EAF55E01E9D957EE3D7FB5DDF7AB7D11F1
+:106CE000367EEC604240BCED15B4059812627D9A88
+:106CF0009FBF197D00AAF07D3CBA88D6615BB08841
+:106D0000E8E76BCD47E237219E36C69AD1CCD9B79A
+:106D100071039D4FF06FDCC8F5A014F77F8FBF6D36
+:106D2000BFF079977C286C96B3FAEDB605FD3C4E22
+:106D3000B271596232076F7F18F5BD12EEAF2C6A3F
+:106D4000A9F6E43539F1910F85E4B620D94D3C4ED2
+:106D5000226B297A7FB184BA227B7DBBC8F5A4441B
+:106D60004FC0ED87D16FE3F7B365C2B13328131C71
+:106D7000CD56F52A941777CF54E400C231D9BE9F7F
+:106D8000C58E43F6EF63427267D0E3B7E7708D6755
+:106D9000A80C21DC5D3D9FEE64FD7C9072F63133E2
+:106DA000487AD23D22F1C7D6727E0E709FF16E17DF
+:106DB000DE73E1F0538B2112FF6E9385B4C0FAD9D4
+:106DC000565E9C7B1ED24F0C776F9AAF8A782E91BD
+:106DD0007D3C8703CCBDE817F7A35F9CAD77C9B1B5
+:106DE000D07191FC7FDEFCEF22CBBBFE629DF7DC15
+:106DF000DD78A6F4B8F39581114D3F9DD1FE5ABDC3
+:106E0000F73F901F968788CEC032A395A3307DD1DF
+:106E1000FE936AE9FC7349C63983076CFBFD61FB8D
+:106E20001C219CBE05506E3D609FBF7E608D18D4B6
+:106E3000195E9EB78ED0BE39BEAEAB9202339ADFDA
+:106E4000935FEDBF536BC4FDB528E5CD13AACCC845
+:106E50000B2AF92BF3AC8F05BD76EADE134103EF65
+:106E6000C34B1F950CD467BF7CC70C927FD66AAE0C
+:106E7000B7A457E53D80E75DF20530F0BDD3AF63C1
+:106E8000BFBE1BCC23BE49CF61DF73985C89742ED3
+:106E90005A85EB05395A630CCF43DF0EDFC2FE572C
+:106EA000F1F5AF2C04BA5FA7300674CE993D379F39
+:106EB0008BFCBF51C498389C41398F725CED7911BD
+:106EC000DFE75E2ED2FD3945CDD67938CFBD73C709
+:106ED0008E45FAD81AE6E75E9A841468086F01E7CF
+:106EE000871D912ECA07BDBB468446A428864B0346
+:106EF000FB5919DC49792C08EF4CA23BD2BB304638
+:106F000081FC685D1FE4FBCE69EB3CF42B4743BD7D
+:106F10009DFB583FE136C5D8C9FAD951E9BDA76EE6
+:106F20005288EF778190E0C4F70321F634B702E589
+:106F30002DB2B9107F33BEB280F6058DEC2A27BE84
+:106F40001FDDBB482C9AC29FC52EFEDD69CBD9B48C
+:106F50009DB7F0B0BD7F38FAC603B6DDB0D5DE37D9
+:106F60008ACC2B1A15A4DB55300DF154B2A6535818
+:106F700099CDBE6FF7CAD54C7E9998C92F29EF39A4
+:106F8000D571AB8A3DDF23C6F99EEF148AC17567C0
+:106F9000FB37E2B92D5026A1DE370312A65BAE0CFB
+:106FA000B6FFE707CDA9A18FA0FF44438914EA9F4C
+:106FB00099FAF745F6BA5C1B48CCC1F588CE5D4E10
+:106FC000793C6B03898BA87F392DA03C9D87ED62AE
+:106FD00059E1A5E4AF11C05BFD51E005D9A0F35C18
+:106FE000B74BCE7DB6DEF35C90717F6DE6FDB4F3FA
+:106FF000FF7827DD4FDB2230450FCB39F6FDB47E1D
+:107000007E3F6D4B84DB5D2D761ED53A1B0FD785F9
+:10701000F87DAF6B6C3A9D1FCA7EFF91E3F74AA1E2
+:107020006CC07AA3B3DF3B861A15F6377F5CF6EFA8
+:10703000A9108F3BCE9F38F4381B701CD6CFACA064
+:10704000B936E4F2AFCC0899EBDDE55B43767E918F
+:107050009C20BDD294F97E581434378666BAF06B02
+:107060003FF31695D379BE53F6793ED66EBB407882
+:1070700095B491E0DDD1FF5B04FD1E9283BF607A81
+:107080005F96F5783F18B5C49C817894A31FED0AEC
+:10709000717B92D1DB263E8F34E5418741BF07EFFC
+:1070A000811887F770EBE85738F6F0BFA2BCBDB87F
+:1070B000A706F5A7B53F90E87EBBB3F0B586D19D96
+:1070C0002B1FC5793FF6837164074F9492F7875C55
+:1070D000F6C7D8557D0AD23BC25FCDE1E7F9D3426E
+:1070E000FA3C6E0F00C5715A6E8A7BF20933ED913E
+:1070F0003CBCE780E48A427A5D265C8E3DE19433B5
+:10710000CF231CB2E908FFF451784F38706556362A
+:1071100025E4AF9990A4E76CD0E9C9EC964E9C07A2
+:10712000E33F1DE16C0C4DB808E7F177C4DB8F42FB
+:1071300033FFF1F0E6D07151F2927E3ACE76FFF550
+:10714000FDA128C9DBBA6311D2FBA37BBF48742D14
+:1071500031BA0EC406F265EAC0CEA30F4327EABDDA
+:1071600045C97A3A177A8AD131F62B69FC1CAB0CE7
+:107170005A02E336528CF3874F2ED5440DE3B29674
+:107180001FF30EAC623050D6A23FD20D6F7938F9A2
+:10719000A61B8FB71FBB87E4EDB581E4095CCFDB8D
+:1071A0004B2C3F6A762E39FC965B0E0B10D691FF66
+:1071B000E69FE6FB65655297911E16304E47BC2F41
+:1071C0008424952F038B9E8B204DCF4FE09546A4B2
+:1071D000C7D9E716BAAE16DDE716FAF3B9CB9D7C30
+:1071E0000E1EA72AB0E9106C3BF5F9E54B1B16B251
+:1071F000F1D9E29B188FFAEA729ECFE39F2DD3F963
+:10720000D582DEEB6B314E04CBB85EE6E441E4D5CB
+:107210007AF5B4B3EEB73AF6FB63D82EF39C9CA391
+:10722000AF65EE5BCE33535FCB0B673F3F39D8BEC4
+:10723000931957A8C37F72FBD5B6AB1339EE7BE326
+:10724000339F87EAFB9AF7BBF2CC0FE3FD4659F771
+:10725000011EEF8DEEFD7DEDB272BA5FCEC094C916
+:107260009EFAAEF9AF4F1AB08313F3729F477F7443
+:10727000A23A77BAC4F0BE38FE5EF3FE7C80256683
+:10728000F7FCD75DF3ECD118B459F484FEF14CDF70
+:1072900087EEFDF76D85CB97167BBC881D1F6B13A2
+:1072A0002D3FF1ABED7FFB4321B7D31DFB3EDB7CD4
+:1072B0009B095FBD61A487C1E6FBD930DF4F472D35
+:1072C00037E8BEFC26FBBEFCA6F14EFE96A1A13E11
+:1072D00079633897DF57102EA1F86A53F71CF2270D
+:1072E000171CF4913F7DD4B2A460B9F6C57BEBB90D
+:1072F000FFF52B4CBFC37C902D4CAFC3F2DECA59B7
+:107300002ADA0BB746A653BC7673BDE1C917719E46
+:10731000781F5DD2E5DF6B4A546918EF6DAE9DAE04
+:10732000A2DD217DB29CCAF279D33BAA183F7F66C9
+:10733000EBD44B0B302E51C6EF23BB8E951B4A98D6
+:107340001D1DE6FBEC21E3F530E2A92AAC3BF4433A
+:10735000EBE85B96347D2817E25A15E6CA38EFC190
+:10736000A62FF69EF4EBB795E44D6136FF43F6BDCC
+:10737000586D4AAA7443199E8B670207FDC42AF709
+:1073800013221D34CF18807B838DDFB9F6B84C20D3
+:10739000894FBBD64F89F3F56B136155B6F5B933F9
+:1073A000CCF59B66CDD486A4234DFED0737F68793F
+:1073B0008CE7E7C7181DB9F8F96C7AE7FC541E4E44
+:1073C00034870B502E42698AE61F26F943EDA481CB
+:1073D0007B2CE361B31DEBFD2CD7CE872EE479D057
+:1073E000EC7D6B0E96E514C977471F6C93B93E3759
+:1073F000527D306FD146D207DF65AC45F6D92737CD
+:1074000092DCDEE853E9FEBFBDF3648A6745CF81B5
+:10741000EBDC768B14B1EFFF8F70BF3CFE4E427AEF
+:1074200032D77BF09C47340474CEA56F3CCF2F6DD0
+:10743000831D35E7107C9334F77E56399EFB19EE99
+:10744000AE0AAE72FB1BE6E4F27C91FDB995BF4734
+:107450003A280BA7AB90352FD0A017F369A08A9FCD
+:107460001F130AF9391B1F182AE7D76A0DEF0D15EC
+:107470002049E7CF065D3FF0DE2FFAB89C6E0C2264
+:10748000DE62DCAF13D92E50D29ED46976E1D99D4D
+:10749000C6DCA53F0813BE1306F277F7AC20D97BF4
+:1074A000EF752B647FBE7713FC06FD49EFF972C0C0
+:1074B000624BF52351FCCD536CBE7D8C597762FE37
+:1074C00097C6BF4FDB2A90BFE9471F06C721BD1BE8
+:1074D0005110F1F72C16337D8227094208E3B3D10E
+:1074E00005D07509B6EF0E13FE7CF19FCE7F7D06A9
+:1074F000ED3F21B102CF6B890FE2FC9F89431EB69D
+:107500009FF1BF5512FAAF1C7DE81E2D7904E19D55
+:107510000DD6AA6ED6FE6E85F3D7DD794A1AE394AE
+:10752000D30B44D243C0174A4F62DF171F78BD1AEE
+:10753000F33B17574CC39A383EADF7442D790CE90D
+:10754000AF5A5B529DCBEA971FD549FE5E1ABF65C5
+:107550003F96671DE3659F9FEBF1A8C7B8CF072C47
+:10756000FE6002CDEBCD30D7679BE3668F290CC957
+:107570005719F7F27ACF173874C0B6751DF3D2E9F0
+:10758000DF3AD145D2270EF89FA0C2B0CF9F38F482
+:10759000600A1F851E7687F9BED086F966B1817CA8
+:1075A000B3365B7F1B69BE59263FE52D92691DDE10
+:1075B00065FA16DEE771369FDC42F77F66F29303C9
+:1075C000E7E6F2BC18CA61876FB4D977925CF65FC0
+:1075D000AFD07DA60E1F39FC332BA79F8FBE82F242
+:1075E0006259585FC853344C70F3C995C3F0D562E3
+:1075F000E8DB1F63E5C53258394C041D9AF3BB9292
+:10760000092E3EC9C4E7E27902BCEA9183BCECC210
+:10761000B7D67F0F70163B79B0753922F3730F0E12
+:107620009FE2EFB1E0F9B176D100DC8F1A73571AFF
+:1076300011364FB936770DF2C3162191427E88CCB0
+:107640007E2B7423C3FB7BA3981689FE437DE553F1
+:10765000C4EFAF84C82EBB7BD66A8A4BBD7753720A
+:1076600022EE2F9B18DE5FA5FD3C3D5AA45CDBDEBD
+:10767000D13C6F428FF36732CEDF83FD3D6D974D76
+:10768000BB5E2FD563EBEB919B07A29C0F0E44F9D9
+:107690003EB549E950911EFA8A54CD9DAF7C897D53
+:1076A000BFF0CD113BAE78BA49C7F8C4CD11DEEEBC
+:1076B000DEFA4ED25736D5EFA1677E6D1A303F2ED7
+:1076C000586AE9A857A87F5E20E03E0BE7F3783BB5
+:1076D000BE6F70E96B9FB2E5B68AF700B179AB8DEA
+:1076E00096EEBE77561585ACF703FD24CAFDBF6A3A
+:1076F00023D07775EFFFA3BC84FC1243F81C961BC4
+:107700003BE87763025DFC7DACC4146E70F51BAB87
+:10771000EDF4EC8FAAD82B933D54079A85C69DDCD7
+:107720005B8D7EB7F6A5C10ECC57CEA423FC7BD5CE
+:10773000450FEA9FAF24BD088E70BDB4BA5825FA34
+:107740006DA95376A05FEF0FB12ACA536FB2F196BD
+:10775000391F8CAB334D8FFC64969FC7D7ADC93CA6
+:10776000BE8E658CAFE313E3EBF8C4F83A7EC7F83E
+:107770003A96BF556F5219E3EC58C6383B9631BE66
+:107780008E658CABE3734FFD2A7AFEA03E45DF9FEA
+:10779000ADAFA3F225B6DC8452FE3B5FED5F544CE7
+:1077A000CC8BFAA1BD3EFBCCA5AB7E8E7E40881A69
+:1077B000B85F070E36BEF213BB4CF75FC78BF3D131
+:1077C0002F093111309ED01ADFC674CC81F905E43F
+:1077D0007B41A778BAB50AF31977460E5D2A33FDC7
+:1077E000A1247E4B551E2BEF8A1C6DC5FCD173F571
+:1077F00086E53B5C653D327DF5D3DA407962D90E92
+:1078000039C8BE3F79F7CBAD28070231AEF77D2FDF
+:10781000F2AB4B1B1849741533C506E558919246D7
+:107820003ABE01D76912CE83EB2D9F80A638E6EFD2
+:107830004DD495E9C87FAC7E17A7FB91D5FF2106F3
+:1078400061669EDD6EA87A62F988EAD1F9DBC1EA49
+:10785000E17761887E5AA049EB61B06FF1F1FDD507
+:107860002AE0FEDF761FE7FBF6007F4EC8E1F4F763
+:107870004EB4EAAE287BDE15E5EBDB1EE0F70EF436
+:107880004D11E9F778A04EF827ECE70B6341C3BC34
+:10789000C7E9538AF351FF3F62D3C3A48911BE6F76
+:1078A000FFB34AFBF665139F6CCE63E549FF6A1888
+:1078B000B80F6F012388F7B65A5B45CA23FA66F9F9
+:1078C00039794B58F50B667E270FF5DEE9B6DC49B2
+:1078D000DBF64943CB8D13D13E78EF252EF78EDBB7
+:1078E000E3ECF0F5A4683D6786E91C054007E9254F
+:1078F0000D7199F2BFC431FCA9F8B46BE85ECC16E7
+:1079000085EE6152FE345B257FEA077EFB1EE21E98
+:10791000D257944052CB65EF3B2C91FC0F4D5A301F
+:107920008DF7616D094FA7DF65B0CA648A876D293D
+:10793000E3719D50E42ABAEFEA2BDD01AADF12566B
+:10794000290F385DB6FB40550C9FA286FB7EDA5CA2
+:107950004AF7535A9AA8513E31FB177D5F13233FD4
+:107960000F9D2BC6EF6B781CC237FA20959B3EA566
+:1079700051FF60E7ED93EA25E2EF4424BABDF7CD6D
+:10798000F6FDF442F483ACE6E752A66A4BBB9F6374
+:10799000DF9B4D3551CCF8A1457B776F08CB2B8011
+:1079A000E2A4A129AF3786B0FE0D9AC1F3B0F83931
+:1079B00008B0EF376E2E5BD6FD1FD8FFF2104C32A9
+:1079C000B07EB58AFC0ACDF002DE475568EB33A1E4
+:1079D000DCE902EA632DB574ED2683CF7B7EA03906
+:1079E000EF7215E9465A9C47E3B480A9627DAB5615
+:1079F000A67DB130AC76A1DFA0D0F63B38F2203FB7
+:107A0000E53A47C0FE37768DEC396730FA066FB934
+:107A100020E37EDD0B6DFAC9C45BE63CF363CFE483
+:107A2000223CF96BE844C459F0DF1B9BBE04E735E8
+:107A300046DB2BEC28279346D3F17E714835B8F30B
+:107A400030FE5A78A79635F7203D4CD565D0195EA3
+:107A50002E84BE46EC7F8B4DFFED45DEFDF9886D33
+:107A6000D7303EFD7C7426C63344B05CFD63BCC396
+:107A700072C1734E7B9EA73CA963ACA7FEE4EDC523
+:107A80009EEFE7A5CFF77CBF60D7744F794AE75CDC
+:107A90004FFD0BF75479CAD3BA2EF7D49F7160A962
+:107AA000A73CB3E71A4FFDD9AFACF47C9FD3BBDA48
+:107AB000F3FDA2DF6DF0942FEEBBC353DFD1EB33A8
+:107AC000F7CDEBA37F993E8FBFFBE33E4F9C692F21
+:107AD0009C756FCE9F9B748CFF4194DF932BE3FECC
+:107AE000CECA1BBEC8ED2E75BEA1A3BCB9DAA6CB0B
+:107AF000D579E63A94AF955195F60939CCEBC9E1C1
+:107B00004B491F99B09DC9A919648FF57FC7387477
+:107B10007BBD35BFC4E5AF0A681D80F95F95D11AFA
+:107B2000BA2FD0692F6B26605EDCD5519DDF73C301
+:107B3000AC59BA074067ED5DF362F61F5D1DD1C712
+:107B4000EC43D4EBFBED3F3987E2BECCFE23FBD008
+:107B500008727B104E4BF4DDF88A40F7F333FB8E4E
+:107B6000ECC367C2CC3E9C86F658EF1694437D3F2B
+:107B700093298EC8FEC8FE2B67F6DFE65CB71FBCF4
+:107B8000B7089F69D0C6E2B35BE9124717913D7809
+:107B90001FD2F36736BEB40AFB9D52CEEFD56B1FE2
+:107BA000551B473DB9BDA893F8A4AF48E6FB909C90
+:107BB0002875FBF77E6CAF7748FD26D9A16C1D4870
+:107BC0002E3BEBB045E84DE3FD85D61783E4EF9EF1
+:107BD000F05BFF11E437B5581D87F97FC63EC5C479
+:107BE000F1EEB5F15CAC4DABC29F792C892FD98BEE
+:107BF000CF7375A68FB06769E93D7BF1F974949FE7
+:107C00005F3DDF78BA0A658C3A9FFBADE5A94ABAB9
+:107C100051407F3383238BDDD1EF9F886EE7F7FDE3
+:107C200094C86F20FDA1D67F864DA1324FA5B871B3
+:107C300000E942A027D153400ED1FE12C043A858FC
+:107C4000AE10D218EA42FD15F3412BF3B6131D38DE
+:107C50007A2DEABB496E1FFF18F11AABF5AE7F48CB
+:107C6000FD16E1A9D93EEFDC9EAB1FAC62E3B6176F
+:107C700014E7A1CF16FD294B5CF2679FBDEF3E9242
+:107C8000237AE4CF6CCC519839A017317ED82E9E40
+:107C900083F02628BE1E3828913D1FB8B3837E5F2F
+:107CA00035A0593A90FE6FE9D86F75F172F2FFFD79
+:107CB0004F6C3AE9C181BA1F65C55BA0570273C614
+:107CC000E0F88C9EFB00E903302AA8E33E5B170B2B
+:107CD0009A3BB2D8079F8D70FFD9A6098E3F3341DA
+:107CE000E75D5BD0DF16C6AD4D15314FE7D69F156A
+:107CF000EC74DF07716B01F74F0E367E80D999491E
+:107D0000177C9B58BF28C75B4E2FA9A1FB54719BC2
+:107D100029C7F3A0653BC84F6FDB4B9FB5F17A7362
+:107D200084E37182020B76A03CC963FA114369A512
+:107D3000ED5771FC2FF11C1ED7372C90B85FCEE7A2
+:107D4000EC5BE219BC8746075D99651FF127159822
+:107D5000EF6BECFFBAF15CE039EDAE7D0E703FF0F9
+:107D600096276FF796CF4B7BCB4C8B7E19F58065B2
+:107D700000DCAFB1CBFB3D0CA60FE328639DFBF30A
+:107D800013FC9CA0CA2040FA2EEB4C777F8DCD2FA0
+:107D9000E1DC7399715FFE94DD69D25FAEB07FCF95
+:107DA00023F31EF7B1F8FB1E53695E9E7D74BA4F34
+:107DB000227F03FA890C979F68A2A67BEC2AC7DF73
+:107DC0009329D783C7EE01F685ECF5A41FEF43D5C1
+:107DD000CAD0AFD05A78D76F8F970FF8575AE5D4DB
+:107DE0009BC7C97FC9F4AF18F77FA05FFAD69FDDA4
+:107DF000F6DFC75D7ECA77A2C9A9E8CFB87F226F38
+:107E0000EFDC97EA9CE77BB7467E5ED0391C4917CA
+:107E10001CB7975A977175253D06FD438E7FC5F1B6
+:107E2000235C9367DE857CB7C53892DAC7FAADFA72
+:107E3000951FB09F85D2C103F528EFC6CB942FA222
+:107E4000CD5EF34810FD99F89D95AB8AF4D1C41F1F
+:107E50002FFAC89FD066F3BD732ED5F1C77CC2B68A
+:107E6000032ECB71F4282B689FC708A29E7CC12EDD
+:107E7000B6869EFD90FB031DBFDF944EEFF7F3F136
+:107E80008837F93D77507E933187E7378D5A9EDEEC
+:107E90008BEB7CA1BDCE18B7AA9C35103F1DBD222F
+:107EA000BD17F5D0A9769E52D98BCFD34FF9825406
+:107EB00028217D9D8FF949AC9DB15FF69C0719057E
+:107EC00002E5F98C3A2A1969D6CFD467BDDFCBC059
+:107ED000552E42F8BCE5CCB81453B7DEB95EC0DF0E
+:107EE000454D0928CFB6AE6036022BAFCAB1F38B31
+:107EF000CE8573916E174A6103EFCDDBF00B89F2EB
+:107F00008BFDC727FF12E3A3F012CFA7D4CEE1F178
+:107F100056EDA792C12420682198362D3C10C7FA4F
+:107F2000EA1903EFD0EFF78F3DCED61DF7A12798C2
+:107F3000DD5FE2433B5EA37227B3FBB1FC0CB3FBF6
+:107F4000F1B99BD9FDF8FEBBCCEEC7F21E66F7E394
+:107F5000F307CCEEC7F7CF32BB1FCBFB732BC91F88
+:107F6000DF83F7194DC6DFB5DD4DF98C6DAA4F43A0
+:107F7000FAC994679595B7AACB187E378717521C14
+:107F8000A56A21CFA76FCD5948F674BF9F2EC3CFE6
+:107F900039E0B7EB151CBF1D1E6D8EDBF66CBFFF05
+:107FA0003369D0BD05C3F7633AFD90FFF4AC7E6C36
+:107FB0003FEADB5FFCF5D79BD8A7B533B7B5078B96
+:107FC000F13C4F8A7FB7F30A337F4F6BEDEE06CA61
+:107FD000F353C61C4DE1BAEE2E0F93BE81BFB7849A
+:107FE000723BD34E74ECC34C7DDC7966EE87997995
+:107FF00030115B2F192E2FE36E5F8AE2D656039362
+:108000002FB85FD4A7E7BFEE3BDB6F3B56CBCB3837
+:108010007FCCF3AEFC07783E5E3B2435F7FC9D73C6
+:108020000F64F31573FFA1DB6F1B2C49D3BD0CC18B
+:10803000B049FAA2C0F448D22BB524C5015B07F9B8
+:10804000DDEC376D39D130E62ADAEF5B5FF491BEB3
+:10805000556DE7BF358D51A9DC3466569CF2262359
+:10806000B3D4DE2CFD6C88140FB9BF4A6CFFD787E0
+:10807000D8FF253F3FEFD5B4778E8AE7A2DAC32B2E
+:108080007BD06E6F8FC7C8FFDF3D6696E7DE712934
+:108090005E41F7544861AE674B7195F46C19E75F28
+:1080A0003650DFA9B72F87EF238CCDC98F190877FA
+:1080B000503DBF9C30D1DFE28FF1FC62BFC6E3854B
+:1080C000C11211D42CE7309ECDE1E7ACDACB921A85
+:1080D000FA75DAE3329DE768D7A70F166F25BDE87A
+:1080E0008F3982877E9B6CBF43D32A85F4C2445D5F
+:1080F000AE569D4FE711FA90CFDBC38D2AC65F9530
+:1081000031E543F6AB68BCDFFF03837E3D1F008093
+:10811000000000001F8B080000000000000BCD7D58
+:108120000D6014D5B5F09D9DD99F24BBC924BB9B80
+:10813000ECE68F09241A34E026243168C449083C4F
+:10814000F4212E021A5A2A1B1045050968EB6AB55C
+:10815000D9908010A4067F2A4F2CDD58B0F6ABD6FC
+:1081600068E92BAF455E50E4F9839AAA55B0A8019F
+:10817000ACD53EB511A4A5EAFBF8CE397726D9993E
+:10818000CC26417DEF7BD832DC99FB73EEB9E7FF5B
+:108190009E7BF7D429F87321636D7B52545609CF27
+:1081A000A58E784A1163E1687976C324C6BE951519
+:1081B000FE22C3CF98C3B3488EB919B333A676C392
+:1081C000F394D64E7F7A658131A827CABF98F29E74
+:1081D00077E877FD29A66F661168CF8AA5F7FB5C63
+:1081E0008CD914269CB24199B9E5F7CF66F4E7948F
+:1081F000887FF706C29EE4FD785CBF9CF2DEA4A1F6
+:10820000ED9697F5394485B1F5DB3AC30CCA9F0B5F
+:1082100050A842B8636A1ECCEB869D2B59A48CB142
+:108220008D52AF4B0638367E292C0C970DED7F31E1
+:10823000CEA70A7B95620827FCB19D3A07FE5698A7
+:10824000E2A8662C0FDF8CC527FF0EA3EC3905FDD5
+:1082500097F740B9548307FE3FE93963B9AAD75865
+:108260003EF780B1CC58C81E9EC0D8EB2DD0E999FE
+:108270008CCD39F4E12196CED8DC58E8D9A77C8C96
+:10828000E5AAAE705C666C1E0B3DFB3694F31AD308
+:10829000584F0806B7B1A5B82E30CD378B01BE4672
+:1082A00046B0B2BCA5A98CB906FB9F2F67D23A3560
+:1082B000F635CD641319FBE1AD6D8C413FB17A21E8
+:1082C000BE1DE09FDDB06DF638783E50692B781802
+:1082D0001B45ECEFE1FC5CD0D929986FA66DE598C1
+:1082E000B1503F3C354D68837A3F3CEFACF5C5500B
+:1082F000EE9D5E1242BC03BEDE1B980FE07F5E98CF
+:10830000B7D7C77FA5F2D8DC71F0DC52F9E46C7CFA
+:10831000CE49AC0FFDCDAAE96A75407F972E532A4E
+:10832000B0BF7083B17D5EADB10C90F3F9C0BFBC3E
+:108330005943E11D091EF3F87A7F0FB428847FF6B4
+:1083400025D003E0338C9FA07D58EA974280E7DC7C
+:108350005A418D03DDE4A982DA65C10F1D1A3F98E9
+:10836000F12FC63218F259FD3C31DE0155725D76AF
+:10837000C27FEE4C21AEC0F8B94BFB7B4E41F97287
+:10838000973D2EC2F7ACCC6E01BF3FB08CB1CE2270
+:10839000022FBD2E617D1F70ADB117C2F7794191DB
+:1083A000D9800E58ED381A8FE0184BF838C2F1E139
+:1083B000227CE42D0B3DFB6318FF8A1AA72C42FD9B
+:1083C0002B1AF9771DBE8D12D0197CDF0874162385
+:1083D0003A938E24E267CEA1E5CB911EE798DE1793
+:1083E000435D9CEFC7930F9C5108702D173A67A40B
+:1083F000012829F666C670A1018348D73A3FEA787A
+:108400005ABEA395F83181CFECA7909FF1DFD984B4
+:108410001AE2B3A75DBF92516EECCEECDBC2808452
+:10842000B7CA2CD690CFD8BFA7F69F2D4079BB7C7A
+:10843000F9BA7517C0F794FE5FB072C69CCE6FCFC5
+:108440009891504E4DBD86CA3E6D1C98428CAFF738
+:10845000C0B8441FFF2973F836A86C930865C92675
+:108460006F0A150DB6CBC276C230EDC26C9364D1E3
+:10847000CEADB7033CAD85F54BD5E695AA7DB76982
+:10848000F0248E2F21DE64C52DC07A48D32519E94A
+:10849000E5EBC2913DD2BC236C937DDCD0760076B7
+:1084A000AB0EBFCD1AFE387E4F1CDF3E0CFCDF3416
+:1084B0003E46EACFA17D3F6DF8A0FAEAECE4F34531
+:1084C000B8ECA8AF14C56D4BE8E7AE3DFF78F11CE2
+:1084D000205E693E0BA5401F925D954340E765F223
+:1084E000BD2EEC5CCA6C9023C00FEBA1ACC2FBF5B7
+:1084F000DD9D2E05DE9715DFBD0E89BEAC2795A14B
+:108500003C98C0E4CC47A1DF09B2C47A70D52ED81C
+:108510006B4B8332BB84854AA0DF8C3DA9244F324C
+:108520008BCEFBA900E36666BA546C9F9659FD5347
+:1085300046F4C11429011F6975AFD7A7215CB3594F
+:1085400008595112E2AC0E996C3CF0109433A76DAF
+:10855000630D50AEF8D8A388C8D312D7771DD81EA4
+:10856000F5743BDB87FA25A8C99F750E7913E98F4F
+:10857000EB2486FA236DC2BD02C2F3007425025FAC
+:10858000969565CD6E8072D97E5B4851703E9D4256
+:1085900021CE272092DED2F1A9CB918A4F7B38D30E
+:1085A0008F67F1ED007FBB3DDE83F22A36F90A7951
+:1085B0003BC0937B5582BCC6BFFA010708EF4B97BF
+:1085C0006DEF2842FA96DE4BEC2FE3D3780FCA33D7
+:1085D00056D718C6F6BE999241FEA76AF22CD5A4CA
+:1085E000075AB2EC24CF747DC054499161DE8236C3
+:1085F0006FF68330E903270BB91C64AF2C203B4492
+:10860000607DC2A934983F5644B80BF83C86B4AF9D
+:10861000E6ED5920E4423BC799DADC8CF5E163567C
+:108620002B2057B82E5545FD2C38982B5801F3B602
+:10863000B14837D049ABC0242C0F8ED7C3703CA7AC
+:108640002BAD1DEDAEA75D6D36C45FDB73A03F6043
+:108650001E77D85923DA056D72C89505EDA39AFDEA
+:10866000B6AA7C6C0E963380B67BD16E90C232D2A5
+:10867000E52A7F710E83F7E9DEBE6FA39CFDA7CCD0
+:108680005FCF7015801CAD873AE781DCDFF4F8BA64
+:10869000582D8C77328F2909769E536A66684F3938
+:1086A0004F161ADEF7B4C08CCE1C2CAB6E5B038E5B
+:1086B000735DA64278AD63723BB6AB03642809EBE9
+:1086C000E23C1964CA24ABFEF30DEF7BC04E529C12
+:1086D000A3E93F8D29A589FD8F4BD2FF19A6FE6521
+:1086E000CBFE07FBF51AFA5D2331B2A3633E37AD2B
+:1086F000BBD92E589D59BF2213ED51276BEEB6B052
+:108700003B5B336D04F71D81E65E15DAD733607C81
+:10871000A0930BBF3C2232B26760A5805E58BED4E6
+:108720003F40C763B11EA75F5B4C6028972E94EC57
+:10873000063E99C28C65B35D54026B8DE3DA3C95BD
+:10874000BD483FABFCA98AD3027EFDD9DBC2A6148B
+:1087500097C07C53C34B19F0F10399FB5C6B02503B
+:108760004EE774F248E61F67A0BFD02B70FA5BE3B8
+:10877000B3115EC2F5395D6242BF61072B41B91882
+:1087800046FA76737870FC5E7FFE431D16E383D84D
+:1087900035D80FB355614A71C2BC7A353B7860BC9D
+:1087A000A9795DC80703E33959158D2702FE13C760
+:1087B000CBFE6AE3FD1EE7573638DEECE9C6F9CD9D
+:1087C00076C834BFD91AFFEAE3FD1EE757F415C691
+:1087D000C3F9258EF74FC6F9CD76CA34BFD922A783
+:1087E000AF81F1B2BFDA78BD2DA56407DFE100F9F2
+:1087F0000474925ABEC3350EC6BDC365970565B0F5
+:108800005D5DDD8DAEB9A87BDD53A7FB619CFA6988
+:108810005039177B993ABDAE98B14D02A78BFFDC5A
+:10882000F4E7754817C767AE2A257DA2D9D79762A6
+:1088300055D0C7974A1CDE59F9EE786B021E1F000F
+:1088400039A2021C0F02BFABC08F5B812FB11C6F1E
+:1088500009D0F321B0D7F1B90DE0C5EF0FB784A867
+:10886000FC484B0D3DF57E4A6BB8DD3EBED6DA6E58
+:108870003F238BFB7D9B82F2FCAB50AFD5A586508E
+:108880002FB29AF3999A6857B3E6A753E0FBC6CB89
+:108890005939EAC6333673B87D0DD964B7A796EF58
+:1088A000ED6D81F21D925D41BD7C87C26658F9CDA8
+:1088B00045A867AAD05EE5EDD9F9DC0FF385FBF694
+:1088C000A2DE9B83763AE0D53FB76F2FFA7F978180
+:1088D0005D4E7A991DDEFB367C7F1DFCBF0E2C8B16
+:1088E0006E264379D61C3F8D0F7FD2EBB2D17EE747
+:1088F0007FEE99798CFC8A700AD70B3E36FBD93D06
+:10890000086FC8A1C4A93F765F18F940B52B1D2494
+:108910000AC276D4D37ED4D3F0BDEEB093D910BEC4
+:10892000690E926B73E71AFD864D293D32DA3F9B43
+:10893000CA7DAC15FABF6CA6F1BBD3C9F92D6CF298
+:108940001B6699CA2021B9DF2D2EC8407BFF0E7C03
+:10895000357928DEA2875AEFD89B40A779591E1F88
+:10896000C501CE6067A03C3BC1CAEE6AC08FF95911
+:1089700064AC98DBFFBD2576C75E40FD2B28F7AAC7
+:1089800090BEB9DC18CA1F1C9EC95ABD075A7AA7E7
+:10899000BC5732085FAE1417500FE42D85F709F36A
+:1089A000957C7101FD1D263E5A8EFE8D791E0F08A5
+:1089B0008F0699C578FA339749EF235E7029519E47
+:1089C0009BE73B79C87C6B5F296656FCA46C427BB5
+:1089D0006ED67362A85519C4873EFFFF69BE3AAAD6
+:1089E000E919A6FA580FD0CB2B40EF1DDC8F616838
+:1089F000A7EAF40A15C87EBAF452F88E74A1AA0543
+:108A000088CF57C6F66FBB1ADB81EC68437F57B738
+:108A1000837A0EDAD00EFAAAFD5E7A9D83EC2DC61B
+:108A20001AE4F74B07FB4BB63ED8EFFB09FA73C0CD
+:108A30004EC43FD59AE843185B4301B2076E01FB71
+:108A400018FDFD68C387523AFF7E24C14EC53F47DB
+:108A500012FA6BDBF3734101B8BA5ABAA7BC674F7D
+:108A600090174B65DB1AB4E75AE302C5217AA01EC2
+:108A7000D80363972AB676C0FF55D80FD2A749AE60
+:108A80008F6D877E12ED94DAB9F2A3400FED65F594
+:108A90009D2178AEDFCCE3657AFD81B8992F46FE43
+:108AA000B99D353301E074A4FCE0277D301FB54D3E
+:108AB000622953A06CE7F60E7BDB4372417437FFEB
+:108AC0000CBF076220B770DEF5CD8F63396663E1B6
+:108AD0003678DE9FC6DB472597EC0C619CA47D06AB
+:108AE0004E3F3318B92F0BF0B7263B95E4A0E31D9A
+:108AF000CF4328A71C99154BD1EE5910FD7E18E3E2
+:108B000091B2972D0C5BD0D702CD7E8867F1B8CBA0
+:108B1000217B4F4126C05D17AC8F63BF43EA477F7F
+:108B200040FD4D11ADEDB09D5A3F5B6CD672E10931
+:108B3000EDFB15CB9FFCF061984F5AB13B84E4B636
+:108B4000FE1CB643B00DADBFCB1FE94E8423A55824
+:108B500096280ECABA27A33DB7FE8B07BB1F079402
+:108B6000677DE126399B257AE24291A1FDCEACAA30
+:108B7000A1ED77FFE38D00AECFEE1446FA95B11765
+:108B80002F427F72E34099C5048C73666AE5D8234F
+:108B900017A986F2E28BEAB08CB40B4439F99EEF48
+:108BA000AE8F617B819759EC7BBCBE9DD7CFD1BE88
+:108BB0004FB9F8A39FDE85FAA0DA417EE846CD0ED4
+:108BC000D2E13BDF2B12FD9CEF1D1E8F0735B9E074
+:108BD0001A3D1E0F5AE17177507D0BDFA7B06E0171
+:108BE000E938E50BD74DD8FE5F5A58F82A807D8BBF
+:108BF000B2E3E77729D4FEB0151ECF0AAA47B0BD6D
+:108C00006BF9919FDE0570787438CE65372581E366
+:108C10002FC3ADE78E6C2EE7E6F9B8DEC8D2EC4D77
+:108C200087A337301B9E72E58F6E9441DEAC2DEA30
+:108C30006EB48A3F9FF0DAA85D6692787B8697E3F0
+:108C40006D574EF87384A35D7ED285E3A70A2C8C02
+:108C5000F537D4F43121A1DFB37D7C1D006E9B1765
+:108C6000DAA54E662AD2998779E20CE8CC53C9E19D
+:108C7000DF10789D29D0CE530A4F37BEEF23FE4731
+:108C800097830B351074507668F491714FC745483F
+:108C90000F59A24E6F791D482F0E9B5E3FEF622C3D
+:108CA0007765F172B92FAF23960F7AC6016D502EFA
+:108CB000E43AC8DE31CF2F4783B7C3AFFABD7E0B8E
+:108CC0007C3AFB689D364E708462B0AE536CBD8DAD
+:108CD0008BF1DBC56EB2D7E07D633C61FED3353AE4
+:108CE0009CEEE5F6D6C67FB81AE316EB918C4E27BC
+:108CF0007A4F9B4E277AADE9F41CC47F029D7EC655
+:108D0000ACE9B4DAAA3DD0E9B956F8309745A66E79
+:108D10006E0200A5CFA73F72176AAB7FAEDDFC38AD
+:108D20003CA77CE196BC50473C83919D687371F9E8
+:108D30003E28F723D3B07F496EA6F7A23B4CFB3504
+:108D40002F65F1FE87F47B6EF566945BA3E8378CA4
+:108D5000F336F73BC6CBE19D72B13B12B7C0FB497E
+:108D6000AFC4FD521F1F3F19BF94FAB8DF9C945F38
+:108D700074FACF0947108E91F8E5C2417E593A3A0C
+:108D80007ED941FC9256C6F9252D09BFB09893F8BB
+:108D9000636D112FDF728F8FF861807F622546FE31
+:108DA000899518F867DABD2554DFDC3E1DE76D8133
+:108DB0009798579F47B805E7A19E2DB78B646FF42E
+:108DC0003194535DAC7F8F13F9B056086D87B7B3FC
+:108DD00062BD0D2E05BFF7B2D9607FACD3E87E2B04
+:108DE000C283FE50B516CF927AD9659EA17CECA9BC
+:108DF000EC298D24E0BF40C3E3E5BEF05D387E176B
+:108E0000EB1B8F7669B275BA5783F7A6807AAF15D8
+:108E10009D8FA47776A2DEF1E393C39DF585AB1910
+:108E2000E58099CFA7DCF0DB0F1F1EA69F5F6B705C
+:108E30003CA63D4F83EF1FF35AE9E9A0FA4B13DF3D
+:108E4000570A632DF9FED756ED81EFFFD50A1F5F54
+:108E500083CF9FB6E2F307BDBCFF91F02CF9389E9B
+:108E600025DFD7C3F3116D9DDE3A7D3CBF9504CF5E
+:108E70007FF4FA4785E72349E4EB512FC1618BE189
+:108E8000BE00F23BFAEFEBCE8DF5E37EA8051CFFAA
+:108E900099D88F4BE1FD8069FF9900743EE5F37529
+:108EA000A188055F42BB6389F0EBEDEEF5CA9A1F1E
+:108EB000A1AC44BB7ACB3FBB693F01F4E0DFBCDF30
+:108EC000AC9CB7F92CE4F1141B974397DF73783D02
+:108ED000C669BE46FFE956FD3FAFD1D748FABF2865
+:108EE00041FF633F6679D7C5783CA5C31FC9F71119
+:108EF000BEFA2E42F9B4F5D62C01FDBA7CB5474036
+:108F0000FBDFAFE9978D5EEECFE8EDB64A3D828498
+:108F1000F59B65212618FA3B63B8FECC70007CE314
+:108F200011BECB7DEA59F8BCD73B60EF9D963D540E
+:108F30001D502BB03DC8E94A1C5F3DD328A7F579E9
+:108F4000D8C2DDAC0FF50BB8DF710BBAF26BFA12B9
+:108F5000FAB980FAD1E47D954FA72BDEDFE9EA1B51
+:108F6000806FBA06DF0C7C9AE133E36524386F46E4
+:108F700038797F9725C299AC3FDDBFD6D789F46990
+:108F8000425C67E1A0BEBE12FB73ADB1C5986F90A5
+:108F90007F757D0D922915FBDFE2E071D42DCBEEBC
+:108FA000AEC37C83AEDBE4724449EE52AEE7946517
+:108FB000851457BD56EBD70CFF407B47F7F8496542
+:108FC00034EE721CF7C25AD683722303ED048A3F33
+:108FD000C812C617B29C9D018CCBAE173A1B17A1C5
+:108FE0001EBDC84DFA9605E65AC6A7F4A71E7FD245
+:108FF000E7CD029523D46FA5FA725A6733DA49A3F5
+:10900000AEEFECB4B4AB7EA8D95530BFF5C3E235B2
+:10901000E0A3F8968EDFA1E3F0F5AB0B370B88EFFA
+:10902000D4321812583235DC499BADB6E238EB43E6
+:10903000FBA914E885FA7BDD32EE37D8DF5A1DAE86
+:1090400007911EBF2E5C7ABDE4E3F17AB87F46F14A
+:109050000E37975BF401CAC79EF35AEE1FE8CF3B69
+:109060005A645502FD734C5632305E7887A6071954
+:109070000B052EF3FCF7D71B9C479CC73B4DF5A374
+:109080008CD33D0BB8C8BEC3307C22DDBCE6E3FE0A
+:10909000684776F8392E1F4321A46B28BF80F867F4
+:1090A0002E287BA8BC9FCAF240F965AA1FE0F5995B
+:1090B0002C8F0ACFD0EE0FD44E1AE8E74DEAD73DF9
+:1090C00030EE41FAEE1B28FF91BEE7F3FAA31D270D
+:1090D000615DF9FC7B459AFF67929A81FBA39747F4
+:1090E00017539C687EF45A7AAE6B91EB301EF77280
+:1090F0004B7F7B3B3C2F9FBF5846BB7FFE927B68DC
+:10910000FF5EEFFF52F42B90DF156906D94545B697
+:10911000F036F720BF0DC2D1AEE599F535201DB967
+:1091200054D6DF510EED6B3E6D6F37E4397552FE4C
+:109130004C8A227D9E1857D7E5E0C70EF573DFE90C
+:10914000D1B169BE8CED85F13F7317C76344D7F584
+:10915000B215BFE8F34ED6BF3EEF647246C79FFE1E
+:109160007E7D7185CCF37FE206BCA4943450BECFE3
+:10917000A58206A7C7A5F11BAF370BC679B28CE84D
+:109180004341FA9DA5F97166BDA08FFBB12352E45E
+:10919000F7E37E0363B75558E07794783BD0B23459
+:1091A000DC604779DC9D42FBF74CA638BF5EAF31EF
+:1091B000C9FC2FF0733DC29C2ACD67C3ED1971B471
+:1091C0003B3634FD5AC6E04ADA84CFAA62F814FA74
+:1091D0004F2C42F972BB87F2311A9B4E54B526F4DC
+:1091E000BFF0997F7361BCB771C26A3FC65D16322A
+:1091F000E9B3C47C07F3B88DD11B886E63AD42A37D
+:1092000095BFF56636E7EB85982223527F4712F724
+:10921000919B940A07C6279A62C6FD1CD0900EA4A3
+:109220008FC5EBCCEF13F67344EC9FD1BC63B899B8
+:10923000877A6F8D8DE86D0BE00DFDC0425097F879
+:109240007C333B4BE3C75EC2E77F373C6F66CB7C2A
+:10925000DFCDC562695983749313E964A89F3C9577
+:1092600002ED6FFA3C7A7E4437E9A97BDD7A19F486
+:1092700016E03F5CA6D939C5FCBB0DCBE8FFA4F5D1
+:10928000EEB5011FAFB9EFE98B03E3A1BFB248C050
+:109290002653F905C98FF6172FB3D8D32FEC257BAA
+:1092A000563E4B0801FFB7EF7EE1B902F2E7357B8E
+:1092B0006CF70B648FE965C67A18CCA72B75A0AC48
+:1092C000BA02501E3B508E6179AB66C7AFB96FF7DB
+:1092D0000BED649F8463FE043D59C7787CF99BD6EF
+:1092E0008F5D81AB3A319F28566C237F2FD5C48F79
+:1092F0008FFA1D54AF28277237C233EBB67E09E3CD
+:109300000D8EE0EB3E9403638A8FA96381FEC7D480
+:10931000F2341956CAC7ED2A5E45764397B62EF049
+:10932000BFD5A8F706D7A7D7B43E7C3DC295BDB43C
+:109330003E9EB25E5A2F1B9629EEC7F7E32FA9E493
+:10934000F686ECE4FB0ADBFD9C1F76F8B97FBBC315
+:10935000CFFDD38CE2BB29BE9332C346F533B4A70D
+:10936000598EEFF04B9A3CE7F8D81D8C74FB13EC48
+:1093700056781F2EAD44F9E6CBC27DD6BA62E926F7
+:10938000A4E79F68FE29ACD35DB44E45BED4085F08
+:10939000B7DFF8FD16EB563ABA757BA32542F22AE1
+:1093A000D9BA5D3E5F0C5BC5DD5ED0F0F049E39F4E
+:1093B0007E84D359EEEA77E03ECCFAE24D86BC6A71
+:1093C000D78ED93D980BADE755AF4E4BAF45B96D34
+:1093D0001EF78D2FFFC387F89DF90FA7A57CFC54BE
+:1093E000938FAFB734523B586045CA2639C078DEF8
+:1093F000CB409E9870CA49D37B03F3D0AE24D66786
+:109400006C6EF830ED572F0A880CF7C71732635E81
+:10941000198BEA79C13C0FF60D095C5340E11B3111
+:10942000210498624DD26C5DAE18F2C3E6CD9DBDAD
+:109430000FF7E1176BFBF0205F0CDF9798F2C6AED9
+:10944000686C0A3768DF8FD3DF71C2D35C85DB8D30
+:1094500073DD6ED2AFF3C2F3C30D09FB716FFE97DC
+:109460006899877E41B68E9770B8A164285E16858C
+:109470000587AC8C8C1F333EEA248EAF260D5F66C9
+:10948000FC98F1B078EE6C5A7FF3FCDF7085093FF1
+:109490006F007E305FD88C0FC6229720DDBE395F0B
+:1094A00064681F4F1767DA314F60F16C81617ED1BC
+:1094B00012164AE7F9C1EAAC6909F09AF168C6D711
+:1094C000E2A758A807FA5D7C9F87D6EF550D3F624B
+:1094D000CF5F695E619857079FD7119EBF2AD3BCA3
+:1094E0002E53CB9FF5C1F7483B485BC54A8FF0F937
+:1094F0002C82F974C843F5C90956DB8C74B2C49444
+:10950000B76086CF0CFF4C94839387EEE357646B70
+:10951000FBF8135948DBC7CFA0630D21FFB0790BCF
+:10952000837CCEE96B6174F6C078D8AFC022036546
+:1095300019F03BF379EFC679F0EF550151C13CC109
+:10954000D9F3C7ADC1F9875938A3A708EDFD7E3B14
+:10955000CA91CB1898B1D0EE429824EADB70430A46
+:1095600095F57E8F757E6A273D1E61CDDB69FF5DB7
+:10957000C9983B21B97C591570D078663B656679EE
+:109580004906CA0B333E743CCD43BCA4115E269EF3
+:109590000E5E5E445D85FE2CC6D1601DFBAF65ECA2
+:1095A000A1F2C1FD6396AF727B329BD1FEFFB5D9AC
+:1095B000999ADDD14C7187059A5E3864678D4FB8F2
+:1095C000F93E7245827CFC56B0EEDAEC043B55DF86
+:1095D0004776B33EC2DF952E778F3891E8EEA30130
+:1095E000FA20F9A5E76B46285F53CC58A6505C2CAF
+:1095F0002D7D22CB00BB98F179831F7353B61FDFFB
+:1096000017C6D10898F9FC4FD7CD5306D76DFD5535
+:10961000DB3B511EA72CF9558C3A57783E479AB63A
+:109620006E75DABA0DD8D1A5F03E01BFC73A353B09
+:10963000AC548BE3E31F281F2B56E3C3F9AFFA3A70
+:10964000A69482FF61C823EC247CEBEB094E443FD7
+:10965000F265242051CEB08DB9C83F8EDCC2F33103
+:109660001632652BE6072D8CDA8F25F613094A048E
+:1096700047647D8A163709513F8B82BC1F56CAFD4D
+:10968000BC01BA8F41FB84FC479B0B4C496C9FC9C2
+:1096900042E83F417FD9A8EFD9BA8471C60E1D3781
+:1096A000597FE676A2B67F2B3A43A150829CDEAE6C
+:1096B000D9CFC70295DDB6B1C9F1B7C8E555A584C4
+:1096C000BCD8234157A3555C4CEF4FD7DF0376221C
+:1096D000BBE6C5443BD1ED687AF1B90B12EC44D638
+:1096E000F422EEFB7F553BF1E5ECA617DB617E7FB4
+:1096F0007FFB9F287FFC5833084CC0A3373A951D49
+:10970000F5A27C90497F1536824785C9DF92321ECB
+:10971000E93D259AA74A09F9B26F662B04BFB758ED
+:10972000A5FD3268DA8DAEB8570A0988B7BBB5B85F
+:109730001910EEF8D99EC4767CDEFA784E974C70FC
+:1097400038F4F158A895F2EB6732D2237A1E88CE0E
+:10975000D77A3F47B38DF1BA51F0F3D16CFF507E09
+:1097600016C5E6776F4739F1A2487ED87702B7D0A1
+:109770007B733CE0E36C6E1F8E11231FA35CE86DCE
+:109780007CED3B3743BB153B9C2154C3CBBFF7E17A
+:109790000FAB14C4135FFFF94B16DF5785F32A9103
+:1097A00064DADF28E0711847AB40FE6B4A9123BCB6
+:1097B000039E877D75B93909701DF6355079EC0C1B
+:1097C0000ED731E8B343C1769B1AC95FF4F07DEF41
+:1097D000638A92C148AE30B22744277FBA73785C5F
+:1097E000D89DC3E379520EC7B7EBA4408B8474DDD8
+:1097F0008CFB16528CF2A05D27257AEF10044B7B70
+:109800004DEFCF75128433E22BCDDCDE41EF713E9C
+:10981000D85EF432837DE3CFE176B27F008E340EE2
+:1098200087D7DC4F3A7FAFF19F198E15D9538388C4
+:1098300097C33E353787C751B81C76BF70409838FC
+:109840001A79CCF3F52F094A2E8AEBDD2EC44B4052
+:109850003E75941E5B4372ABC8D58CE7A412EC270F
+:10986000819FBBE1E72A06EDD3FE69732A317ACDE9
+:1098700094074243EDAD772B4FCC9B8305EDFCC4A1
+:1098800095BAEC8D4119ECB977B4629332762D8696
+:10989000FA2FADE5F6D962B4CF4224B70C7697D94A
+:1098A0003E7383BE9F0374B12420C94817663BAD45
+:1098B000A3721ED9351D60D760BEF6503B8DCB9B81
+:1098C0003BA336A642BD976B45F2335E2EED7BFE81
+:1098D00042D417357685F44569FF9D73E8FB241A59
+:1098E000C7ADF977509F9F7708A5C54BE0DD2BB535
+:1098F00047DD8B13D6FBE59AA3E3D12FD89A24BF7B
+:10990000428FD3ECBD95E77FBD7BAF107722DE6E33
+:10991000136DD8EFC2720FE5AD4E13DD34CEE28D7C
+:1099200062DC493854D3A7650FDA8D4CACCD7E0D7F
+:10993000F170979DE1F9C1829BFA0C76EEC2A8D135
+:109940009E8B3483FDA39CBE1D68B6FFCC76CCF203
+:109950001CCD7EA9601568BFBCDCB2931D2D19B467
+:10996000636625D9FFD6ED98F36CF5DFD5E899F657
+:109970000F6649D6FBFB9768FE290B717F709AF83A
+:1099800011ADD7B190A420FEDCB7BC40E73ADCFFB4
+:109990002586ADC6BB33C7A1EFC791BCDD5A914642
+:1099A00079D77B6E3D2BA78FD64BB9BF16D7FF0556
+:1099B0003BC9C164FA2D252AB2629898272AD05350
+:1099C0005FCF31D11496A81FC624C953F8710E9FDA
+:1099D00087FF3666433F3B33C6542BBF54AF07FE69
+:1099E000E8748C5143FD9E4C80EF86621BC5FD756B
+:1099F000BF34C5CECFFBDA77AD8CA17F3A06E0430A
+:109A00003814800FE57051348DCA63A35E7A8E8B53
+:109A100066D2B3389A47DF4BA2E3E87946B488DED2
+:109A20009F193D9BCAA5D149F41C1F2DA7E759D109
+:109A3000F3E97936E82DAC5716ADA3E784E83FD3B8
+:109A4000FB89D139F43C273A9B9EA1E8B7E97B79A1
+:109A500074313D2BA24DF47E52F47A2A57466FA4FE
+:109A6000725574253DABA3DFA7E7B9D1367AD6444A
+:109A70005BA9DEE4E8062A9F17BD879EE74737D13A
+:109A8000B336BA85BEEBFC9CA6D9D32F05B6C994D4
+:109A90006FCF7ACA503E26E3C3439A3CAECF51F70C
+:109AA00022FDE9F5F66BE70ECCF50EE40C9F77F39B
+:109AB0009AB65E9F848EFC088FD3EAEBB63E307C6C
+:109AC0001C8195F946D8B7E2F37B2647E1F42B7564
+:109AD00092BDB1B599513E98A7B2574079D3159030
+:109AE0006658D1913BC0F3C08A722247517FB88338
+:109AF000EFEDC5FDA84B63BDBEA9482F215FEA5419
+:109B0000E86F4CBB8DDC6B85C90296950626F7B0D5
+:109B1000C1780ED85706BD260574FBAD77E62484C0
+:109B2000E7ACE20AB25FB5FDE4FDB78E65E8776C9D
+:109B300075F40812CACB558C25DAE15BD72E7A383A
+:109B4000F19C8614E0FC39661D7B1AE364459D4A4E
+:109B50003D9E271CB7597D1A533C4BE291FA54287D
+:109B60009FF948EC697C8EEF8ED7A7C1F3EC9D3D41
+:109B70004FA3F899D0D357EF86F239CFB16730FCB5
+:109B800054DEAB4CF54079D201F519DC26A9EA8BFD
+:109B90004C4D57109E785B3AC0B3F51D30B4A05CB5
+:109BA000F351A7086EC9E0FA83DDF644C2BAA414E3
+:109BB000F7AA22FC33FF26B91CE5EC56A92F25B3E2
+:109BC0006CE8FA74E1BC719EA057B66BFBE872C2F8
+:109BD0007A8402821E0FF40512E2815DEDAF523CE1
+:109BE000B02B55AEC35057FF34263FA4201D733F02
+:109BF0002175CD58D24F3ADD017E0DF6A414E074E4
+:109C0000B775C0DEB4C66F08F15BF5BF07BFFF9E36
+:109C1000A3C9AF24F87D09E7111C998FEB029C2F93
+:109C2000818F2F085425AF77B5867F339EB74AF2D0
+:109C300059842F37B3C5CA07D7AD49A3EF91F0FABE
+:109C4000EDFF65745B13181EAFACD2CBE3CC5A7E2C
+:109C50005A3279B33FC93991E6C01039C7E3A5320A
+:109C6000C8B971C9E55C6D6004F99524DFE1F6803F
+:109C70009EEF10FE7E601471FD3B6D721DE6BBC44D
+:109C80002632F213C0BE6CC7FC9D3131A582B6B13D
+:109C90005028231E2BCE263FBD08EC0DA98261AAB9
+:109CA000630F3E2FA9CCB42D2AC3BC068DDFE4A6DA
+:109CB0004022BFE9FA7E901F75BAC8EAA273164027
+:109CC000AF984FB84BC3D3603F3C1EB1F696DCAEA5
+:109CD0008E0439D815CAA3B25E3F19FDBEA57D0713
+:109CE0007941FBFD97D45AE79BFC6B40D4EC9C7EFA
+:109CF00015E93C3685C974DEB9FD08C9A74C904FFB
+:109D000042110F0FE1F8F9D1D487314EFBEB40B689
+:109D100026CFE5D4CB3DFFFFE8B9037C75E2A75A17
+:109D2000790F9EAB18037A484139590BB057A29E60
+:109D300073D0BA2B8CAFA352CBE23D02E1AD07FD4D
+:109D4000E6988D9FCFD8EFE85649EF383265CC3F83
+:109D5000D9E58FEC0DF893F3859CA694E3A2FE6100
+:109D6000F37533DD41CCCB9153B1FC2A94EFACC1F8
+:109D70003CA13EA695EF744FFEEAF1873F04AEDDAD
+:109D80008FFB54D501F535A467A0EB3F205CEA9921
+:109D9000B244F1E151EE3FE9FC39C84F72B9CE4F00
+:109DA0004D65240FDFC5FEF5FE92D937FFA2C9CF5E
+:109DB000FEC0F0F68D4EF7A76DDF68F0BE3302FFF0
+:109DC000CF7CFEB5CDDBD860FCCF93FB46AFA4A023
+:109DD000BD3D951D9D8471AF5E4EF78CC7F9548CC7
+:109DE000FF011DA454BA4C715B6186167719365E6B
+:109DF000ABC793F5789F1ED74BD7E80A2F0C403D91
+:109E00009E5E234B8BA8BF3E7619F4E709723CE9AE
+:109E10007C8D720BF7E75D6BB2A4B16583FD82A404
+:109E20002439D5D5C8E48E4CBEFF9A01F2A573350E
+:109E3000233F2FF6B248FD1F576D1F3AA1DEF14AAE
+:109E40004020CA05952972B6760E81885C267A75FF
+:109E500032D68DFE36FB41C8E5C038F7E702530124
+:109E6000EEFD9F8BF49430C20D8D2E099587B07155
+:109E70005D466D08F703C5A35006381B326A33B040
+:109E8000BC7FFFA410B388DF5D116932C497CC7822
+:109E90001AA8F79D3594AFB06584FDCF9AA043B75B
+:109EA0003B2B8268EF5CD5DFEE5006F73FF57DBDBA
+:109EB00060F19317E13D3BC165DCFECC65F1D64412
+:109EC000BB29617FB116FBD932B8BFD87B46E2FE11
+:109ED000E28ADCDBF0E8FEBF0CEC2F46CEC1FAAA2A
+:109EE000B7BB1CE953CF87DDEFE0FB006CD28B3EA4
+:109EF000C5823E16943FEB277AD4FC8921DFB5B8A2
+:109F000099D90F9E1534C6F18F87E664F4E0C72413
+:109F1000717C3D9EA7FBC118AF932DF9CE887F7D44
+:109F2000FC0502F763995D2079A7EB4D902791A07E
+:109F30009F9A513C5A750A94AF753CB45821BF287A
+:109F4000897C19D837603D2556FBAC0BB4BC13F3A4
+:109F5000FB5B825C3F2FB0F338A5B0724904C75D4C
+:109F6000107409CE043BE9EA20D75FFAFE8B23F791
+:109F70006415E2D9E1882856F336EFA35C1D64032B
+:109F8000E7DD42167A2F199E0ED83B695FEEC012AC
+:109F900091CEEB1E8F9C4BF73E24930B6F21FD94CB
+:109FA0003016CEE5E30DAEA335DEF43C19F37ED5D5
+:109FB000C0F7A6143A7F63CE97794CC3DB3E0D2FD2
+:109FC000FFDDF932FB34FCBDA4C567F478D6254922
+:109FD000E4FD79B6FA47888E4688CB9CA1E7FB68FA
+:109FE000F861CF8CA77B3936F4DAE32902C263A388
+:109FF000FDCBC63F8821B4BFF4766E93BCD0F37717
+:10A00000F472DA4981C513F611D2A46E8A93A69D23
+:10A0100094E8BD99FFEE30F19FBE2EC9D6595F1767
+:10A02000F3FB2E6D5D0E34FD5B00CFBB6C4861967B
+:10A03000F9445F048DF177731E40B27DEE835ABB05
+:10A04000E391C93928971B1DB192D1F0BD8E9F377E
+:10A05000BEFC8D0BF96CC349E70CABF57835C8FD38
+:10A0600016D0A7EB12F7413DF35F6BC75ED324E335
+:10A070003EA8AE4FF57DD0B44AF33E9AF53EE806D1
+:10A08000662D1F93ED830ED9FFD4F4ED896092FD08
+:10A09000CFB2E1CFB3EFD6E879A4BC8F2B1CFCBCC8
+:10A0A000ACF9FD8B03EBB0BEE047C05737363969DA
+:10A0B000F7A9A7C9497CB8B82985E2B28BCB79BC8E
+:10A0C00077F17D82B65F678CC3BE04F262199EAFE2
+:10A0D000D7F4CE5116AE467B7456A560D8270FD75D
+:10A0E000A618CAF397DCF312DE9BF0728D5DA1F81F
+:10A0F00033F41543BBA096E72932A5FF4E8C73EBD2
+:10A10000F1677DFD5FAE3D4AF7A0C5C0CE2F096166
+:10A11000FC5924FE7AF9F549FC5E3A61703F5C0116
+:10A120003B61C379E328DFE360D9B728CEBB01E305
+:10A13000E230D30D5FFE6606D11128E518F2EBC4BC
+:10A14000AC38CAC7C5132AB2912E9F99F8B907E354
+:10A15000A2EFDE76DC8FEBD4D7D24C7907E67537E9
+:10A16000C799CDF1E5D38D279F9B3B902740F4F015
+:10A1700092299EACCB2BB3FC4888275F983B8A780A
+:10A18000B22EB77439A1CBAF83651D6F3F04FF3C7E
+:10A190001871124C6F69F31EE04B8D2E0FEA7CF89C
+:10A1A000A593EC916726FE96F2ADF47A2DC14CE2B0
+:10A1B000C36F95C5EDB43F8B790AA583EB323F722F
+:10A1C000ED4019BBFDF6D29506FA18905323CAB19B
+:10A1D000E1E59498CBE313C9F235753E18AA7F4A9E
+:10A1E000C84E4DFBBD3DEE2AFAEA7AA8B1E9D70A7E
+:10A1F000B683E7666A3FD111895BE827333C69275C
+:10A2000045169F94F85EE1EF07F48083BEC7EA9598
+:10A21000D5AB7DDC9E6E23FE8C3969FFDCA7B6E4EE
+:10A22000427D9F5F8D213D3CEC535B7313E4699B42
+:10A230009DEF478A361679C2022F4FE56A7A9985D3
+:10A2400003D8DF9A3AE3792EFDB93D97EFEFEDF1B0
+:10A250005707D0BE6E3B5C1E40FED9EBA9267B3B68
+:10A26000D9BADDA5F313CAAF92417F62A3B6DEC0AF
+:10A27000A22AEEE3AEB1870389F1C675B93C8F23FC
+:10A280007DF293BD6837B7C936CA136C9379FE75F2
+:10A29000BB5B9AB14D6BE733B493F47354745F8630
+:10A2A000E436E6573FA5D93BC9E6F954AE4DBB5F4E
+:10A2B000B4E7DE5A6150AFD88FD4B9E8FE07A6CA1A
+:10A2C0003CBF2964C8A7B66BFAA5DE94AF21CA5F6C
+:10A2D000CD6F0BFA23BB722DFCB63D3EF5295CEF2A
+:10A2E000A81473227D445DD67CFF8CB6AE3FD0E6C9
+:10A2F0006BBE575534DDFB209AEE7D88D537FFAC19
+:10A300000FE96DB5536EF3D13D0F74EF4314AF5C9D
+:10A3100082E7DF53783E0BF87FE7F2F306A13E9425
+:10A32000AF2CE0A2785467BEAAE64359F4D81E5A6F
+:10A330000DFDB5A9F52A1E5DE974DBBA709F2F33B8
+:10A34000183988F398EA9148EF745E9C4A7A08BEFF
+:10A35000A77039C264A19AFC41BA34057D703C5F94
+:10A36000660F38289ED516617DCE71FCFC3FF653F2
+:10A37000C77AF6D716A1BDEDAA443CED0F4DCA88A9
+:10A3800058C809FD69DEFF7FFBBB6F1652BEAA18D5
+:10A39000F908FBEB6D5CBC11F7F557EC1443B88F73
+:10A3A000F09DEF1D3C839F3732EE33DF9F36A50FC4
+:10A3B000F559D4EDA07A7B3CD59D88A736C1D389C9
+:10A3C000FE6EDBE1953F413CB6B5F238B719CF7B65
+:10A3D0003DDFA3FB358EC372627DF3FD1AAC73259E
+:10A3E0005F27A78BF62D61BE2CAF8AAF23C5070F61
+:10A3F00079E81EA8E3FB9F71237C5F63DE697955D2
+:10A40000C3CD3B5F26FB45A31F2685D7E1BC6E1657
+:10A410003D9D1D3EBC270DD61BE1DE65277FFFFE5F
+:10A42000B4745AD728C087EB2A7A1A5474C9FEBA72
+:10A4300053A4758E4ACD342F1693D8767CBFEBC4C7
+:10A440000FCF473A50B368574B2C6826BCFC15F029
+:10A45000B2DA022F403F4579B85FB4EB46EAA7D3A2
+:10A46000E192D1B269F354D379E5D1DE2F5296C788
+:10A47000F924E17E91B2BC2A8BFA9A9F85FE368E32
+:10A480005B27B3CFE26C10EFC9F257CED7FA1FE8C3
+:10A4900067E4FC95F313C7D7C7FD1AEB3AFD74D6F2
+:10A4A000B5CDF57FA7A39DA58AE9A1944228E33AFB
+:10A4B00021FE719D70BDB4B80DA92005E940EEC91B
+:10A4C000433AB8313D84F43992DC90185F77BB048D
+:10A4D000F40C769D538E1CA0B38B5ABC479727660D
+:10A4E0003E6B7319E5559B7E2FDFA1D1C92BA09739
+:10A4F000AB71DDCC726BB474B2324F30DF43B33228
+:10A50000CF9F9C4EECC1F08D8877C4535E05C52B60
+:10A51000BE8BF5F7EF177738C6E2783C6ED61F642E
+:10A52000F2430979593A3CEDB8D9CDE3D414FF9000
+:10A530001A19C33C386F694890CB464547ED89F0FE
+:10A540007D037474D77074E466BD745E63B99E9FB6
+:10A55000B363F8FC9CAFAB7F603DBB109E36CFF77A
+:10A56000883ED7DA5D32BF47EDF4D6F5D1A1EBFADC
+:10A57000E8F0EB1A791CBFAB79D5748F11AB692267
+:10A58000BB69975F7D13F3C5981432C8C521FCA33E
+:10A59000C9ED9BCF54285F7577AB26E75A9D32DA19
+:10A5A000E3CFFA6E7C1CEBDFCD9430C643A7D856C0
+:10A5B000119EFE0AF37B284472B514F77DA22C3558
+:10A5C000A4E9D1A7110F339456210BDEFB162836D0
+:10A5D000BA8654D9C46C65A3C7C34B43E5E04B238B
+:10A5E000C8C15E8D9E6F427AD6CFDB279383874E9C
+:10A5F0005F0E1EFA86E5E09FF34E43AF7F03F2E65F
+:10A600003384DF2C6FDC1A3F5F1962218C978F3601
+:10A610009F0DEC4D05F9AB2EDD45F4D3F68440F9E2
+:10A6200052608747A8EC7191B0D9EB71F0FCDF1D47
+:10A63000FCBB58CFF16CC6D39779593CEFA67B652C
+:10A640005832E449C5881FEE528FC9C522E6F7D7B4
+:10A65000123D7B357B46CFEB4FD7E4FF809E9F6951
+:10A66000A3F1BC055CBE7BC1DE41BB88497D0CFD0E
+:10A67000F89BF378FE3EF003D1378C12467EC8A8D3
+:10A68000914C795A9C5FFC12B777327D4C205D83E8
+:10A690007962F0FE04D813783F41A66A6C7773EABA
+:10A6A0009502EAADBE2677B340E7F4C37B7E0CE5A6
+:10A6B0002CCCF702BEF1CE30D6F7B384B2857F1E24
+:10A6C000AB67A598B75896AFF9E90E1620FDA8F923
+:10A6D000E9FA7D81E2C8795F95F9A3882F9E97AF4B
+:10A6E000E79918F571770AB38CAFFD473E975B0D7C
+:10A6F0007D75F56857AFF230B2AB56A1EEC472A6C5
+:10A7000083EEB509EDA97459DD5791A9DA0CF7F379
+:10A710007A67A41AEEBDF587B30CE59CC65C43FDD1
+:10A720006064ACE17BDED2B30CDF0B9A2B0CE5311D
+:10A73000D1F30CF58B00C189E571EB2E36D42FE9EE
+:10A74000BCCC503E73F3B70CF5C7C71719BE9FFDBD
+:10A75000C87586EF13BA5719CAE7ECBCD550BF8D40
+:10A7600059DFDFB9219FCB29E0779263ADEEFA463E
+:10A77000FA1D0DD96188F32FD1EAEDC9AC2EC57849
+:10A7800048DB91F252F287D3CF1BD61F36CBC5647C
+:10A79000F2D8FCBE5D1BEF93A7DFAF5E86748E42DE
+:10A7A0001EE4D227EEB7D6E29CD697F1BC04FD7723
+:10A7B00031CCF7F20FEC534A2ACD67419683599D6D
+:10A7C0000F5892AF58EE2FB40B2117EE1525C39BEF
+:10A7D0004E8F23E1ED4EADDED7C5DB21C118074218
+:10A7E0007DF284055C7BF307EE3B78389FEBABCAC8
+:10A7F00054F230F83D0EA7AB4F7438409F3C915F48
+:10A8000035343FFC93C6D7AEBE5FC1FA57F3FAB6F4
+:10A810005029AE4BB27DA5BDF9E67DA5AAA528E7D6
+:10A8200016785285C4FB9A7FA5D5D3E3D96DE99FED
+:10A83000D3BE529B23543A9A7DA55FE19D1B558858
+:10A840007F858FA7AFAB5D0DC896FE9DD98E61CF7A
+:10A85000E33D1831B74479C366FF2EAAC96DDD9F69
+:10A8600093F6D691BFDFE61E4B791F6DEA2AD29789
+:10A870009D49FC5CD0977F447C4EF5DC64F0E70694
+:10A88000E3012A8D076DC96E6A4BF0FF715DD5FB40
+:10A89000F9BDDADF801FFC51FE69D8090AE37EF0BA
+:10A8A00071C6F1745CB5919D701CEC0494BF6B246F
+:10A8B00046FBDEB14A41B1F28B3B576BF6E16A8E43
+:10A8C00037F37EB7D9CEB824B492F0B606E8C955AE
+:10A8D00089F1386EFFAEB1F3FB37656F3880FAB699
+:10A8E000DFEF600F01B47BFD3C3EA7E3E5ABCAA3FD
+:10A8F000CC8221767266C13076F234B1AC1BEF6D3A
+:10A900003D7692C745143C8AE8C37BC8F9FAAD7A14
+:10A910007E4E6C05EAA922A919F3D745A664205EEC
+:10A92000563C27B2B88072CC989F6F67CD3FC278F3
+:10A930001CF3F1F731E66A453B29A3C6A8C7325597
+:10A94000A31EF3CEC832E935A31ECB6934EAB16049
+:10A95000C4A8C7F2965698F49A518F8D89D69BF465
+:10A960009A518F8D5B779949AF19F5D8999B8D7A5C
+:10A970006C7CDCA8C7CE7E649549AF19F5D8393B0D
+:10A98000571BBE97F77418BE4F7AEE6E43B9AAF7FD
+:10A990000143FD730F3C64F83EB9EFFF18BE03A2FC
+:10A9A0005FC5F30C780F2D2EE2F91F3C69FCCE54E5
+:10A9B00007E6E35F8FE733611D2FE8FFADA13FD6C8
+:10A9C000C9CF2DC4E03F5CAF3FB308DD0300726C1C
+:10A9D0005F1EB4BB212E847A18EAA727DEC77D9BB1
+:10A9E0006B0322F9712B30D88AF4F0A8278EF4700B
+:10A9F000CD66E3F9876BE3C6720CE847C1B802D0B5
+:10AA00000FD2D7F5A6DF8D007B90E8ED7A456A4638
+:10AA1000BBD24C5F7FD6E92BA6BE8AE739F4F9EAB0
+:10AA2000F3B3EBE74F35FA5335FA63E22E82FBFAC4
+:10AA30003C917E7F479FAF0AFFF1EF1F39701E27C1
+:10AA4000760ACC8BFBFB2CB62FCF623E37ECDCE4D6
+:10AA500040FE34CFCB3C8F21766A81715F719AE8DA
+:10AA60000E11DFBD2E923EA229209F3DC6CFEBAD39
+:10AA70007A5EA47331C887E82F88B146C2CB0AC07A
+:10AA80000BDE1BAEDBADC7B476C71E14E97CF34802
+:10AA9000FCA868F870068CFC98A2A49AE8C988DF24
+:10AAA000B452237F5EFFCE450E945FFB00DF420D64
+:10AAB000639E90915FAF1797D13E9F8E6705FEC34F
+:10AAC0007125307571DE37C0BC7B94A1F85DBA6B1F
+:10AAD000D3DA3C0BBA1909BF8F1618F7E9F4FDB9A0
+:10AAE0003AC08EC322AF54C7DF2EBFFA24CAC76450
+:10AAF000FEF0EE02E3BEFA28FCE1DD89F2F61BF07F
+:10AB0000879F2F1856CFF5CF427FCAC9D2431D1653
+:10AB1000713F89C93D18AFB537F3B8DF60FCEE1B54
+:10AB20008FF3BC5B5045F7CE919E4B91F4384FE8C4
+:10AB30004004ED938CB342981735DA38C75F0A8624
+:10AB4000C439FE52307C9CE34D3C4FA866E436D8B5
+:10AB50009099A45029DDEF8C20F03CA44F118F4335
+:10AB6000F2758BB3B4FC6365D8FCE34BB4FDDDEA4E
+:10AB7000807A12E180FE3EC7E7C07D6C957EEA27B1
+:10AB80007D847E62F5DC5E8BD93C9D6DDC5EA37DB1
+:10AB9000A66F208E915E887EA99BE3BFCDC1E3B6F0
+:10ABA000A71B670B160EC17BB07018BCFFFDED1C18
+:10ABB0007E6E3504D6417972FAD6CF61EAE5F59911
+:10ABC000467F796D0587AB441BFFDBD9DC1F985CA2
+:10ABD000C8F94FCFBBC4BCC5940A28CFE4E794F4AE
+:10ABE00073AD7A3F930B3D54FFB340FDE4423FE623
+:10ABF000CDF2FB77D6661AEFE1F9B8A06E32CE6BD4
+:10AC000092D6FFE442C6F399C772B8CC79A77FD336
+:10AC1000EAFFADA09E9E788E16FD1287285AE27339
+:10AC20004A218F13E8F7DE4CD7CFCFDDC7CFD799B6
+:10AC3000EF5D003E79037F1FEAE89D76F2F7401F43
+:10AC4000D1F9B92579FC1CA2F93E8548A9BC0FC5EC
+:10AC5000EB095666792FCF903C8743B750FEDDCB8A
+:10AC600093992C0447CE7BB8BCD0783FC257384765
+:10AC70007765E128F21E166AE7E8FA52B91EEB0F73
+:10AC8000BAE20F59F8BB516D9DEED4FC5ADC9FC659
+:10AC90007D72BCDFDB6ABF3C5AC8E967B4E7AAEF44
+:10ACA000764422C8B7E673D5C9CE53F739FAD6E44D
+:10ACB00020BCE35908EDF79C05F29E1CA897DAA08A
+:10ACC000D0F9C7B5452CBD06BF97DB4278AE2373DC
+:10ACD000AEBCD68E7C5ACCB20428F7C5E6D0F87745
+:10ACE00036325904B8BA0AF93EFAC2DB3EA5F1FC85
+:10ACF000B5303585CE9D4F47FF2CD6C8E8DE42F3F0
+:10AD00003CEFD6F8C5B586DF9393516C9D877FB72E
+:10AD1000468F20B736215FD415B31DFCFC2C3FA70E
+:10AD200080D7D253FE662895F6052F8575E3FBE79D
+:10AD3000BDB47E3705A6DE8FEBA9F39B43CB533022
+:10AD40009F27EF2A3CBDF3E4A90BACE1FD9DB6DEE5
+:10AD50004DFEF0CF10DED4D24EFEFBA55F9E3A250D
+:10AD6000566B3FEDA860FB4804F55F0AE83F019F82
+:10AD70008A4CE768994BA0F3B02EA599E82AA5263E
+:10AD8000E4C5DF456357D918DEE332556BAF363281
+:10AD9000017F4F827201494E9B7E5F420DB5B742E3
+:10ADA000FB69B86F16C2BCEFD052ECAFC19D2A63ED
+:10ADB0007C33A5B8B90ED7EBD985BC8FBB939C97D4
+:10ADC000D0CFD90FDE3FB5EC95BDB509F70AACBDC4
+:10ADD000FA15E3FD5357BFF275EE9F3AB8F5EA57FF
+:10ADE000FE27EE15D0E51BA8213BDAF507447E8F40
+:10ADF000DE5F9FBAC28EEBB0B68E7523DE639F0313
+:10AE00009E5D8378B6D7879FDD8276C9AAF410FF4E
+:10AE10003D91D87710CE77D2988CEDF57C43819513
+:10AE200092BE9EDB2890FDC0A4FE1BB03C7F579ACB
+:10AE30008CFEC35F9F7AB32006F4F9F6EDC73D9808
+:10AE40009FFAAED4EF41B83EB8ED350FE2EFEDDB3F
+:10AE500044CA43A173DF0979625F6AF4B5604CF8B4
+:10AE600038D2D7C296FFAA4EB4CF58D44FFAFEDAE2
+:10AE700038409C68F73E9266F85DD1E5DD5E435947
+:10AE8000D7F3CB9DD6E7E62BC770B974EDA35D8EE3
+:10AE90003C05C78FD8C7C03C3FD0CE017DB0C3436F
+:10AEA00076BC0ECFA247CB1D680FBFBBCBC97A289B
+:10AEB0002ED86B676EAE3F30EF22C2871E02E7BE10
+:10AEC000DD790EE4B32502EB771273B37D88EF3F93
+:10AED00069FE9F791E4BDE961DB8BE4BEA583F9E19
+:10AEE0003B5B7493B0F666A8BF28E226BFDF3C4FF9
+:10AEF000B3BEB906EFB311ACEE816BDEF73BE8E70A
+:10AF00002AE807EDCF259DC6EFC79EBB71DF161857
+:10AF100077C74E07D98BD78C10EF1F3F46D34BD541
+:10AF2000ECDC53E348FF654C5092DB1DBA3EFAA0BF
+:10AF3000855192CA5FF0F77DE1F9518B4CCFE385E3
+:10AF40000AADC7F53BF7ECA3DF16967AAB51DECD21
+:10AF50007C7E71DAB7D8605E517557DB335B88153C
+:10AF6000F47CD51E8AEFD568F7BF5CA39DFFA83A95
+:10AF700060CE57DDF3ECEFD06E83F99FCEBD3D0B75
+:10AF800046796FCFB1E7A6A6D1F9001D2FE7025E83
+:10AF9000C4AF8F9764ED9627F9DD169D9F8E6B7A6F
+:10AFA000F7AA6DB3D7E6C2F86D4FFDB910E3C7310C
+:10AFB000C6E9BBEA41FEFB3F55EE6CA23717D267EC
+:10AFC00010F16ABAE721C6DE6009F47DCDAE34A285
+:10AFD0009300D843CE1A7CC3E9B50AEFED44FA7E5C
+:10AFE0009DB77769FE6D64D7EDBCFEEF1CB23340B0
+:10AFF0007C19B0D1B32760ABB1B867CB7CBF58A781
+:10B00000B1FC89BDAF10E5CA35263FF413C13A3F04
+:10B01000EDCA3163497E5DA5A8D3310F60090BAF3E
+:10B02000E5F15B7E6FCF0752E7BEEF23BF6F13588A
+:10B030000CF0B4FC378FFD2BCAB1EB1EBF2F1DE502
+:10B04000D8875267368EB76CFB9A74BC5FE60329CB
+:10B05000968EED3F8C737936445F8E11B47D293521
+:10B060005D00997C03911AFCFFAAFEB5B7C2387F38
+:10B07000033C23DFDFB0E31F54DEA7BAFA5900FB1D
+:10B08000ED9B8E705CDBE46E6E0DA17F69E4CFEB0F
+:10B090007E765FB642791EB13C0D7F79D8EE866D23
+:10B0A00076CAF3453F1E8759C1FA697EE6F62BBA88
+:10B0B0008F3A505ECB36D69F7FFED0EF602139901D
+:10B0C000DF56ECD8F0A9988ECF0FDFC2DF835A612C
+:10B0D000B24F976AF2DB4CFFBF30D13DE087E20B05
+:10B0E00031808BFF1C1397E36D3FBF7FE26180EFE0
+:10B0F000A36D2FA6E3EF4DE8F4AFDFF37CAC7BF15B
+:10B1000042C730F7087DA2F1C9807ED0F493B21314
+:10B1100000CB81E22EFE5C66EF493F1FE6BBACCB65
+:10B120001E429A5FF698A8BAD1AE3AE8247B64D959
+:10B1300063C7896E97096ABF407A8EA5A31CD7D7CB
+:10B14000EBFAC7FE341DE5F4F54191CD0456BCEE93
+:10B150005727787DA0F314A87FFD1387A77F1FCB07
+:10B16000204F5C16EB35B57B8FA3CF6DB15EDD87CD
+:10B17000A7637CBEEDE77FA7F5F870B7C0728A863B
+:10B18000B65FDAF5278A837D040BE3CDE4F8427DD0
+:10B19000B3A25B6C726458AD5FCFACDF56D277CA96
+:10B1A0000B1F691D378C615C3FFEE6B15FFE16E048
+:10B1B00058FA96333413C7FDE58DE90CE8E0CF5219
+:10B1C00033A7FB1FAFC946FDBDD41ECB96E9C9DF2F
+:10B1D0002FDDFA5DA2C76B7EFFDD6C6DBF2168239A
+:10B1E00079100BE23C973C388FE679358B103D2E79
+:10B1F000FD31BF67F104F8D9567E42A5C2E59693AA
+:10B20000AD9C78AB0FE526DED902703818BFAFEBE6
+:10B21000559EFFEE64976524DAB90E85DB7331160F
+:10B220007F07EDCE15A09651AE89BF3F311DFBB90A
+:10B23000A9486A76527CD4FAFE9AFF075C96D1033D
+:10B2400000800000000000001F8B080000000000CC
+:10B25000000BE57D0B741445D670F5F4BC425E43DB
+:10B260001E100884CE3B488803492001D481400C3D
+:10B27000CA63025151220C014380BC445670F5DB75
+:10B28000740820B0AC06659515740704C5E706047C
+:10B290008135C2441483EEC128AC8B2F761004791B
+:10B2A000C980B08EFFB2F2DF7BAB3BE99E2402BBCC
+:10B2B0007EE7EC7FFEEC598BDB555D5D75DF75AB92
+:10B2C000EA4E1583BF04C6F23E1ED5DD9BCE98859F
+:10B2D0005D30DF9BC5D845C6A467EC8C5531A3EC27
+:10B2E000B532FABB12CFD889F5962EC28D5076634F
+:10B2F000650DD0FE0AFEDDD2564E9704C6B2A9F9FE
+:10B30000276C106395F82F09FAD974227F0DF4CBBE
+:10B310006244161EC3E167A218B395845487E7C040
+:10B32000F70E1E35F7847A39CAC0926D50DFF20DE0
+:10B33000C1CC1E2D617BB5FFAA1D16E651C703FFC8
+:10B34000AFDAF08D99613F06E6EB35B47D3D63D50C
+:10B3500019BF8EC279844BCBA13C61F6E5BF85DF76
+:10B3600081EF6E84EF94AE82F6699AFEB69EFC9CE5
+:10B3700065607B73DBF378FCEF423E2FB138DC1560
+:10B38000C2D84C9826CB6D3FFF055FD63EFAAEA6DD
+:10B39000BF0C2934EA7830FC63301B7C456C7B9F02
+:10B3A000AD8D66AC47FBF77FA8911F7DD7846FCB2F
+:10B3B0008C41937293FB05C453F96716BB0C782C30
+:10B3C0007FED92D9003013982FB92B63A75FDDF37F
+:10B3D000E93D309FD30DA6A831F4554798D0AD0D67
+:10B3E000EF655BBEC95F03ED4D80F720A067E5D632
+:10B3F0001FCC06681F93C77C1618FFE9282763FD3A
+:10B40000116FA6AFBD1ABCE5C1736F088D23D610AE
+:10B4100083A52796415919C5EC1E78BFF2A06897FD
+:10B42000105FCCB7C416D2FEFDAA86A30174D1D793
+:10B4300033E6333BF1BB5B7F7B5E0CD3E2DDF8B5DB
+:10B4400057837715CF8178BD3B00AF97587A387C0A
+:10B45000869D7A794E1F577A7BFCAA78FDAE8621AD
+:10B4600093B73EBFD047223C4B3BE043DDA1AE51FA
+:10B470002919FB9469F038FB95B3C4BFFFE821326A
+:10B4800011F8A672C38F4B90AF00AD3E0BF06FA5C5
+:10B49000FB3CC18B1D561F23B8A948C8E868DE7A5B
+:10B4A0007C06D6F742A466B7D1DFB490C9A1D0AF6D
+:10B4B000EF6DD1BD1E86764EF28545C0FC1607B1F4
+:10B4C000A94E28CFD914B8AB0AB3A9D3609CE7E43E
+:10B4D0000C9B8CEF05B1490D409F734E5F58D79080
+:10B4E000B6791F6914C32468EF75B3828690F67C21
+:10B4F000C8581D7DDFCB3AABAFA5718E122FBFEEC2
+:10B5000085EF5D908DCC02DFF3D6FEF0BA17CA63EB
+:10B5100046AB0DF134A3F6AE306680EF37268E9F32
+:10B5200004EDEEDB07F8A3E939CC3D00BFD3F9D435
+:10B53000D9B74C7E6A18CC4F0CCDDAFB16BC5F0A2B
+:10B540008815815F67ACD0E3673673867BE2516E06
+:10B550004D6D7C42FF759B3DF0DE4C5748F572F80F
+:10B560006ED95A7DFDECC6D3C45FB303F8CB85FC1E
+:10B57000D5A33D7F6D54F96B001B80FC354A0C311F
+:10B58000203F9F6B16DD1678E7C222135B02F08521
+:10B59000570537837E2E34422384777098C9D1C4EF
+:10B5A000B72A9FAB783B83FC97DA1E9FADF5DBBED5
+:10B5B0001AF43034297FF38B8C35509E79F3B39491
+:10B5C000B710DEFEB7B82F58FBF679BB7E9C42E37E
+:10B5D000DA656138AE73BBDE8F7B18E13F5BECC888
+:10B5E000B7E7165A1C0CF5DDAE507732D6F7067E5B
+:10B5F00000BAD7BDFD4306EA7BC616111D5B243396
+:10B6000095171AFF7958C079345A249C47D52E4093
+:10B6100002BC5FF5E72037C3F7DFFE61902BE497AC
+:10B620009B4FA599B9883F43D9A42DC8BF5D990305
+:10B63000E753F556EEF3B5F0FD8AAD4DE6E9509FC0
+:10B64000B7FB5F19A88FCE6D6932A3BEFACEE47D39
+:10B650008E017F7C214DAE37019EBF0B85CE7A32A5
+:10B66000362F7E8D530EE9082F1C0FE7000F382F61
+:10B67000C04B993BBD737C5CF8AFC5C7F929F8FD99
+:10B68000F2C6C14C8CD7E24570F0E7A16EAB40F337
+:10B69000E7CF77FD90C142AE3E5F5BBC99E4FDFF12
+:10B6A00097F966C4FFB7D297F3FB9B12B74B817C27
+:10B6B000DF9EAFB73F48F0EBA1761AEF35CAFBB873
+:10B6C000FFDAF9FFEFD0BBFCBF76BE57A3F73E858C
+:10B6D000DEA1360BEAADB7FF15C7AE63DEBFFD7F57
+:10B6E00074DEADFE8FC16ECD82F17DCEDC770C179E
+:10B6F000C82BE9D01FD9112F507BA6AC3BC6297EA1
+:10B70000451DFB7AE434F8AE0CFE04FAFB75215FAC
+:10B710001B0F02DC027E02FA170C9D13C0434BD1B3
+:10B7200000F772B4DBC66A6603D8F4E97482279521
+:10B73000FC68CC82F677809F87EDF7D77A67D44292
+:10B74000FDFEAE06A90EE0F18E89C95B01B6F514C7
+:10B750006DB88EA973645A25CDF8C6E7E8D723F7EC
+:10B7600004AC2BEE9AA4AFBF93AD8F36427F779691
+:10B7700099981BA6744740FBA7E26D34CFBB58F5E0
+:10B78000625BC8F5E3E9783C5F9FD5B181CD12E2F9
+:10B79000C521DA37B2F678638837C44B4C265B6E26
+:10B7A000C7AF788D0701B628FE15FC913CDE116508
+:10B7B0007D01F1646173D983D0DF25C9588DED2DEA
+:10B7C0000CD68D7CDCC215A13DDEE04F320E225737
+:10B7D0009C4830DEF100433CE3F33E31BAF769DECA
+:10B7E0008178BE7EBC2E4C7E0AF15A146A77235FA4
+:10B7F000389E8F36C2F7EA00CF82D0864F154F8130
+:10B80000787F0B7943E397AB653AF34D41BF338CB7
+:10B8100085D99743FF61D65ECCC8E7E1B3F4C0C2D7
+:10B82000C670BD268E600DCB61BDC6728C675AE7AF
+:10B830009540F59E87E1BDBAFBE17DC46B2F2639AB
+:10B8400089FF8B6DC7FBE132CFC5AE04B7F99F1FEF
+:10B85000E580FF194F25F1ED471BB8BF7969D81B6B
+:10B860004B0680283198B33C08FD5CE54FF616E3A3
+:10B870007B2233D871FDCB1C0EC93608FB65B4AEF4
+:10B8800009CF31E8D6BF5D1D5D74788B2C88D0C19F
+:10B89000D1CE9EBAF6DD2725E8EA7BB86ED0D5C7B3
+:10B8A000960DD4C1BDAB87E8DAF759304207C7CB54
+:10B8B000B7E9DA272E9DA08393EBEFD1B54F5D5DFD
+:10B8C000A2ABEFEB9EADABEFB769AE0EEEDFF06B68
+:10B8D0005DFB1B772CD4D50FF02CD7D567363FA155
+:10B8E00083B35B9ED1B51F7C68BDAE3ED7FBB2AEC5
+:10B8F0007EE8B75B74F04DBE3FEBDADFE27F4707CF
+:10B900000F671FEADAE7590FE8E051B62F74ED6FC1
+:10B910008D391A10EFB0C90F64A11A037E02391BCA
+:10B920002D9DD6B587155A31F28D49E187DBD3BEFF
+:10B93000D7D58FB5FF53D79F9955031190ADEAA97D
+:10B94000ECC21AA80C612D543ED4DF757B02CAC329
+:10B9500073F21264AAFDB93FC4A11DF968D803327D
+:10B96000F2DDA518661307C07898CF887C6D08BEF5
+:10B97000DCCBA5891B85F945E6C9043EF40B54DAF6
+:10B98000FCC1CC13097CE80FA232C21F49CF23FDB2
+:10B990005DA98CF2C7D2F3687F0F2ABBF913A9EC1B
+:10B9A000EE8FA732C6DF8FCA1EFEBE54F6F467D2F2
+:10B9B0007BB1FE0154F6F20FA5E7BDFDB954C6F9FF
+:10B9C000F3E8791FFF702A25FFED54C6FB47539912
+:10B9D000E09F48ED12FD855426F927D3F364FFDD7F
+:10B9E00054A6F8A75399EA9F46659A7F0E957DFD68
+:10B9F000B3A8BCC1FF00BDD7CF7F3F95E9FE87E963
+:10BA0000797FFF435466F8EBA8BCD15F4BA5DDFFFF
+:10BA10005B6A37C0BF8CCA81FE27E979A67F25956E
+:10BA200059FE35F43CDBFF072A07F99FA772B07F68
+:10BA30001D9539FE57A8CCF5BF44E510FF1BF4DE79
+:10BA400050FF662A87F9DFA2E737F9775279B37F8B
+:10BA50000F3DBFC5DF44A5C3FF213D1FEEDF47E516
+:10BA600008FF017A9EE7FF98CA91FE2FE8F928FFA8
+:10BA70006754E6FB8F5279ABFF089505FED3548ED1
+:10BA8000F69FA4F236FFF7F4DEEDFEF3548EF1FFDD
+:10BA9000939E8FF5FF48656B3C619829402FB6EA6D
+:10BAA0003FC3152859484487F1B6D6F7157DBC32F7
+:10BAB000F83986718F71D502ADD39F0EFEEE5DD23F
+:10BAC00093B91609E1C5D8B407FF8EAD1B63F7E241
+:10BAD0003F24C69A722DB47EDFFF3FFCBD25C38F85
+:10BAE0007EF900DAC7FB2D0CED63A0FE55BFFB51BC
+:10BAF000CE9E68F4C3960CF49663FCE577F1DE62A3
+:10BB00002CB727707FE4F5046E6FB72518A87CBCAE
+:10BB1000BF8DCAE2FB93C3294E15756DF3BAA4D845
+:10BB20007DB5FD1F921438C41747F6E21AFBB9D64B
+:10BB3000768BADBFF923C6751C7546167433C046A7
+:10BB40006EEFE52F43DD1B614AF288EA1731CE2301
+:10BB50002FB4D8EAA210CFBFF913B65FC098D302B2
+:10BB6000E53309AEFDA8177E088A73837184BFEAA6
+:10BB7000C113427FD1FE3FFF5FEEFFF8CFF5FF77A5
+:10BB8000858F6E4D749E4A40BFC0E8C8403A8C58BD
+:10BB9000D8438C82F7A7AD106CC847D3170DC847A0
+:10BBA000FE18C81C1427BD37924D7576E0974524C2
+:10BBB0001A14FF4232DF05E339CB9807FD89128959
+:10BBC000115F96340A6E99E2D08EB0B160BFCB148B
+:10BBD000BE2D595A6B9E0FED2A7AF0781973F378BF
+:10BBE0009915FE877234A77EDD5E0A378A97293E53
+:10BBF0007609FD5E609D399BDAC763E7639C7987B0
+:10BC0000D98676A3A221209E1B10370B8C9705277F
+:10BC10008646A1BC323BB3F3387748E9DFF07B2C92
+:10BC20004C12A3AE8E17353E2B31A93BE27194988E
+:10BC30001E8EEB980BCDC9E10C4B49EA8EED5C40B2
+:10BC40008B162805A36B303E077CCA48575F6DB042
+:10BC50007B3D8CEB08D813291385DB35D88CF1C8D4
+:10BC6000CF7BB3E502518DFCB0AA0D22F9F5DE853C
+:10BC7000FF5C8271EC59F1465A074CC3983B8E6FBA
+:10BC80006757B72C50BF8477DF6B02C55D653637C9
+:10BC900006E3BA9AFD10F26B9D8BA3C7E5209D9633
+:10BCA000761D68415AC98E4F93BA69E8B3A88EF0E1
+:10BCB0005A1213C9E9B3C3447E2DD0A716E933CB7A
+:10BCC0006D3AA6C5F32576D98CFB31254BCF13BD34
+:10BCD00066B7D14BD7AEA2BE89E80A74D23DAFAAEF
+:10BCE0003EA1C6D18FFD1CBD86272AF14D855E1869
+:10BCF0003FBF0B2B1F8924FD50BCD0935CADE1D31B
+:10BD0000C07D89A41943C29D200F053D393D98D1BE
+:10BD1000DE0DE9F9FD8A6CA257209D0A7E9A4EF449
+:10BD2000609F87B28D309E7B13D9D409F07CAA1214
+:10BD30007FBDB76E7401C6CBEF4EE4FAF223587F95
+:10BD40003A60FDF9718D953940351FA8B111FCD7C6
+:10BD50009A1882FF562351F9594D1A95C7CCACACAD
+:10BD600041235FC000661CDF5445AEA626AAFB52E5
+:10BD7000F36230EE5EF0D3816C03AA50B9A170D4A7
+:10BD80004DB8BE002468F033A928987C6915F69A4E
+:10BD90006CF931A83F9609F68D4857E7505D7B96C0
+:10BDA00096D906A3FD32727E02BE588FFC77F798B3
+:10BDB000485DFB3B97C6EAE0F989128DAFB0205190
+:10BDC000F7FC9EE27E3A789A1FD6F3F0A924A9C028
+:10BDD0002043FF17FF62227EBE583DB8FB7C0E1346
+:10BDE000DF05E2FF9859A63882BCDE6247FDF76D99
+:10BDF00010E7EF6FFF2ABAEB68DD2B53DCE592D535
+:10BE000026E13AE5C1E9721CD63F180C2EF900C4B0
+:10BE100097C8307EC05EB690FE9CBE5A6032CA881B
+:10BE20008FD17A79DE4B169AE78CD5227365129FF3
+:10BE3000C461FB79D112F5776FA2D480FCECDB688A
+:10BE4000B1AF87DAE95EE57D6120ED8354CCFDDB9F
+:10BE50006123CA434A4B06C6F78BE33DD1A807CFFF
+:10BE60006C30D1BE5785B8AE34044834E7776F8460
+:10BE7000E54A247E84DF531F47AFC3F9B7CDD74DC2
+:10BE800071116F1FE7B38980CF53A5EE0C5A273F7E
+:10BE9000C2E3F1EDF1C2484FC986306923CE77BACB
+:10BEA0006BB02D5D6B0FF9BEDF7493BD9B3D1DB96B
+:10BEB0003FAB07EA81632B4C05187701BD3F0EF1BC
+:10BEC00074AC3ED2B09C16555B88BF4A8C9259FB2D
+:10BED000DD9215A283DA837E2F447BBD5274B1C1FB
+:10BEE00008D753FFF252C185FB4E492CA73BF2ED18
+:10BEF00003F70FEE8EF398D2C93EE37720332ECDB1
+:10BF00003ED6ECB745A71BBF97E53516F5D78E9FF4
+:10BF1000C781925C4B7BCD453A6D0EB22F9750AFE7
+:10BF20002686E33AF5E441B01BF08D59754D1912A0
+:10BF3000B05EF903DB890E65E31A523CF0FC63AB9B
+:10BF4000EBFD4498C2B73D1A9E1A8A71A2C6E7E378
+:10BF500064B4830BF8FEDAEC9767F5D1FAF3EDFDE4
+:10BF6000091663C8C1C2D34D00BCB824968FF89D92
+:10BF7000CC1A94F8859BC627A1D2057CD8CAF9FEB5
+:10BF8000DB74837DCA812C447FA80DE9A2F677D4A7
+:10BF9000C4E35C9F270A3A3B1C9DC4E57BBA81CB76
+:10BFA0001DDB25109F02C13E4DD2D8CB2AB682ECB4
+:10BFB000654CACC870DFEE646284A217B8FD9B8349
+:10BFC000F60FF7856D02C947F9268BDB0DFC9598B6
+:10BFD000C4E573B6F9B5A70662F3F86A337E67D68F
+:10BFE00056813D034D4F99DCA52DB82F655BB728D1
+:10BFF00082DE33D9DDC8A78A7EB7824240BD3013C6
+:10C00000FF09F515AB04B787F8C549766806C64D34
+:10C0100070FD8F7A5EA347DAE9F700BD7E1FD3DBA0
+:10C020002356AFB72FCEE0502B8E73F62AEED7B63D
+:10C030008D4764570057A52EF7DE71345E81E222EA
+:10C0400081DF9F89E3C3F1C2F83CF6EB1F4FA99D46
+:10C05000CB6979BDE07677303E15AFE1C39884F6C1
+:10C0600079CE06C18DFC382AEA7EC2EF6CC06F24FF
+:10C07000E2557686DD05702930929BE22B1CFF5538
+:10C080006B39FE81CE9F68EDEE37513E33E2F51BF2
+:10C09000B09F32EE0756FF4074DF0BF445F99DB5B3
+:10C0A000D96DC68DC8D3AC3E2C04F97EF5C77B7123
+:10C0B00059F0CDAA37BAE1FAB538C2936C00BD1574
+:10C0C00029473C5170531BFF05DAEB767639003F68
+:10C0D0003273921D6A8727EB8A16DCF76E473F257D
+:10C0E0002E761FFE0BF073DF06D11194A16BA79C77
+:10C0F000479089FFCB641FF9096530CF3A1B3E9505
+:10C10000F3112FF7D919E9DDEB1D6FE03899584C81
+:10C11000FC89713DF443FEDDF106FA1F85493FEFCE
+:10C120007F04EA9140FFE34B93C3B010FDBE8FF94B
+:10C13000BEF845A3A737CAEFC5A8043BB468D3A38C
+:10C14000D103BBA39E57F568A962B7D47EEF437BAA
+:10C1500005F0F1D56F8421DD55FACF443B91DE66C1
+:10C16000271E9C0EFDC3F71EDC1E44FD9F1D0B7693
+:10C170000AFA2C7EF6FD30A6D17F0BFBB82A92502E
+:10C180009FA8764D5C176703FE52F5E5D5D65D9DF9
+:10C19000CE2B24605EA1FA7995E0BC32DBFA9BAE2F
+:10C1A000CCEBEBA57C3E4757F0F9CD68372F6EF707
+:10C1B0001F7CDE6297C92FF044A31C7EBB596475B7
+:10C1C000445FEE375CB2023F0DC0F8CD0AB2EB27F8
+:10C1D000A39984719D4EEDF74A0BF905B3B6F1FDB5
+:10C1E000D653C2F0EEB4F1FFAE27EC2194EB2D2232
+:10C1F000433BD4369E56BBBD2A295A63B7AF116F55
+:10C200001867457B5609A843BEAF6CECCEF09CCBBB
+:10C210008AE1AC41A47D782FE93160218A4F831FE8
+:10C22000AE8B375898DD6A453A75127FFD47F2F9B3
+:10C230002973091FBE14C4BFFAFDAA2E1E5377F43A
+:10C240006B360BE4D754CC1B1E369CE17778DC6C44
+:10C250004B12B753DB143D2738AA292E063E8DED2D
+:10C26000711CD75A1E1F66EFB006C42FC2143F368A
+:10C27000F07908928D150FE471792BDAB51003D996
+:10C28000B5403C7CAD7CA7423490FF5B6EE67EF00F
+:10C2900039819FFF7847B18FEF24717FF8FD241E0D
+:10C2A0008738877E20F47BEE268BBB5640B7D54877
+:10C2B000EB64E3308B1BFD19A335C42366207A8D14
+:10C2C000DFB5CA33E06B0A6B31213DC7E5DCBF093E
+:10C2D000E773B827B3895DA9DA89FB08934933303E
+:10C2E000B6DFF4E57B188F94A1AD086B85C93927BB
+:10C2F0007A63FBB508C3FC0F0735BC877196C3F1A1
+:10C300004686FB02F2DB16B2FFA611DEDE14A7ECB6
+:10C31000C258DD008CC7EC598C7CB4372632CD0670
+:10C32000EDA71ABBD845AE7F469EC7F196097CFFA4
+:10C330006691371BE973235B643B6EA5AD85AD57F2
+:10C34000227F8E7F8CECB8CA0730A6F211F08F21C5
+:10C350008C33560EE15307035E09FE2169DE8455D6
+:10C36000BD70D344EA8F742E4FF019713FC527304A
+:10C37000DF7AC0C31D393EA303E9E5600DE3817F89
+:10C380003DFB9880DF4111C0EFDEE54918857860FC
+:10C3900069120B87FAF14689E05E052C4254F60DCE
+:10C3A000308E7568A8407430582513CEDB59200CA8
+:10C3B000C47DD1F285D736CEA08DBF99B06A18C0A2
+:10C3C00006035FCF3EC4D7B393E523A3C84F1AC675
+:10C3D00004E4C3AA880613ADA3415E70FC03A01B4E
+:10C3E0002DFE261BBD7C7C6530BE5C948B24E2E375
+:10C3F0007BAA05F227ABCC1DC735A293D57D399B0F
+:10C4000084EDE7C0BF90AFE7346E4FC6EFAD103894
+:10C410001FCC51F9EC55BD5C0E4E66C4A79DF1755D
+:10C4200096D27F56B2819FE36AFD5E03D9DD398DD6
+:10C43000EF1FC2756567FD57589887F0F2B685E221
+:10C440000782C19744744144021D26A33F092EE28E
+:10C45000C064EE27AAFC598AFE4722963C2E620051
+:10C46000E589F6B0ACFE7933222DF0FC11383E742C
+:10C470000E68F686C0E79AB88AA8D33B14F714CCA6
+:10C48000BE19381EE1E6203BEAE3C9E6065A9707E3
+:10C49000B633D5733FCBB494FB59B4AF06B0650542
+:10C4A000F73327F7F2F567A4E76CF9423C6BF58B9D
+:10C4B0004BF9A7E179B9CE2FB6601C01E35EABB9A9
+:10C4C0003F6854FCD792157A7F61F2228DBF48DD18
+:10C4D000FA2A70BCA6478229EE62417F42E307FC3C
+:10C4E000DD5028A31E96138C74FED2C402FD0927CA
+:10C4F000E3F14CFEDCA8F88923934DBA7D3779042B
+:10C500004B433C14A31E4A4455E35C8AF1BC0B2CFC
+:10C51000B41EE366A3C44728FE575CCBCFA505C66F
+:10C52000FF2E54BFF72CB6C77A7C3EBFCB4F71B8F5
+:10C53000BF09CB52A77033C87797C3975C281FA059
+:10C54000A84C28EF41FBBF41583084332107BFEF8F
+:10C550007916FB97CD561BEAADA783C3A89F050BA1
+:10C56000048A0F2FB27179FBEACBD0F5A8A7D47853
+:10C57000EF92E199ABF1DCD26F92774FB0F646F5CE
+:10C58000C0E8DC1218C64F1C309FA2CB203704BF76
+:10C5900037C1110E7CFE9E6F8A15F0B46AE37B13DF
+:10C5A0008CC08FE77EEF7B0EE11736EEE7F0EF7C75
+:10C5B000714108271F986004393A57ABF6776082BB
+:10C5C00003F7DDFFC0E13AA897012E46FD86F31E72
+:10C5D00022D0BA7F23DAA5E8B6784FB1E11D5E8E8E
+:10C5E000601EB49F576BF7A764E746B4D762E8B103
+:10C5F00050F42FB6A63A08DE92E87C2C19FDA083F1
+:10C60000EE6ED118C732B016A40BD8314747FBD213
+:10C610001B93B8FC6E4EE1FDA9F8827E9E4E8EBE45
+:10C62000FE7E6E69DF8FFBDF194F9754E8275BD7DB
+:10C63000CF4BFF4E3FE501FDA87E1B38C012EAA993
+:10C64000D3698E77719E737EE318B115F5CF7E9115
+:10C65000F8F4FBEAED2968F7BF7FD51289F66FCEB3
+:10C66000EB3BE34A318EA0F845A79B3E334BF07E6F
+:10C67000A55F640ED0D3557E81CACAAD4DE6FC7469
+:10C680003C57DB64CED38CAB5C192770BA7182C681
+:10C690008FD997ACC69F57D278E7BC7ED288F49CDE
+:10C6A0006368388EE78FD9101EF70A9CDF16E5BD48
+:10C6B000C378DEA08338C047C9DCEF88E9E7D88FAC
+:10C6C000F3DB8CFA1CF9C5C0CF8704B6EF9EC2FB22
+:10C6D0002BEEC2F57CF6417BE9015AF76518442838
+:10C6E000071DAA3697C0F30389230E25771887F410
+:10C6F000F13864238F431647B4CC0363C622522E0D
+:10C700003C81F276FBD3AA7C80E8817E29B0A870B8
+:10C71000D0C491C3789C0BE14B1B0D4FE239C2E6AC
+:10C720002E2DBF3A80F66159285B0F7276EFE0D06C
+:10C73000B82D308EE972B800B6930DB784A64C833D
+:10C740007627128647A4F0F327E41F9E48709EC503
+:10C75000F179E3830DE08C309799C7B35C1F88149F
+:10C76000CF726504BBDC1DE0EBB482CF8814EE9F72
+:10C77000351B609C03711CFC7C2FFCC56DC178D3FC
+:10C78000C23E02F29DFAFD5B1387774DC96EFBFE38
+:10C79000AD89CE9F92A3B5EDC319B6BFD671FC5338
+:10C7A000B1A75D5338BD9CC380BF347A7FC2C860D7
+:10C7B0001D5C34269239B4F1CDA2581D3CA93851E4
+:10C7C000D7FE9E19FD74F5632D2D59D5D7E1EF8B5A
+:10C7D0006169E1B4FECFE6EB90AF1A2F7D3A19FD07
+:10C7E000D80DA25D8079CD7A7BE3A743A97789E252
+:10C7F0005CA79A45B247E0DE9AB5FB2767590B9DC7
+:10C800003B36765D44F66F4E0C3FDF3DCBADDFFF30
+:10C8100050E3F21DED9BA03D2BC773311DED9BB482
+:10C82000C5E37F76FF243345590F0F6403F97AF887
+:10C83000CC5E9829CBDBD144F4AADB27DA9155EB07
+:10C840007A0B4C8071DEBAD5E20E82719FDD79C41D
+:10C850002C69F64FAAFC600022F1BD23663C4F759F
+:10C860002099EBEDCAC6F366867CD1783FC9754B3B
+:10C87000932B2A1AED17F8ABDBB290BF1AB2D0FE99
+:10C88000351B6C4EDC0F9BB37434C599C3FD93A963
+:10C890002CAF1F4DFD56F827125CE90F26F823B187
+:10C8A00065EBC7D8CFD3E136B4E71546F955A44BAD
+:10C8B00085149C89FB55955B3FBEF86BB4A3367E0F
+:10C8C000AF63ACF84916D68FED6333D475C5F10666
+:10C8D000513F2D23BEC842BB5480EB02785EBE257B
+:10C8E000D785723FBC2ED486722FE279B20EF874CF
+:10C8F0006A0AD72F262F1FEF287F21F5D7BABE4F00
+:10C9000049A0F9ABB0297A8311F5873A0F13187C47
+:10C910002C6FF3F7A3B26A6BA111CFC57F90F67CA1
+:10C9200014E209DA876099347228E999EFAB078736
+:10C93000B30EF4965A5A143D3C19F530F45794E668
+:10C94000F835CAE5B847BC462BEAD110AB0DF73F26
+:10C95000C6E50C904A35F311DFB91B5712E0ABF86E
+:10C960004CE8074C8652ABB7A776625FE41483E2CB
+:10C9700017D5F2739DAA7E5FF504C375D8147E5651
+:10C98000AB55AE2A94F6EAFB2D02F707E46D3CAEF8
+:10C990005F91E67A12C7DB329C4DDA42FAB425AEDB
+:10C9A00030F4971B7F98B185E81C66930CB8AFA054
+:10C9B000D6AF6E9D0797EFABCD63B1D2FE23912D1D
+:10C9C00040BEF8E8965B5A1CD06FD3C39999A2C6B3
+:10C9D0004EBD94C2CF35339BEF32E98B5DC112EA75
+:10C9E00081B1B8F790D5E6F7E379488C6B54EDB296
+:10C9F000ACC7F3605561B0CE87EF8FE9E77A09F1F4
+:10CA0000D1B43BF722DEA371E0C20CE4DCD138F8EC
+:10CA1000229EB3775841DBD8D10F72BC4CFABF933A
+:10CA2000F15E4D9F258D9C1385FEC4F73024B4B76D
+:10CA300060F7B30E72D889F8722DE5F2E752E47010
+:10CA40009AC2BF258A1C4E3372399CBA2ADC86F101
+:10CA5000CE924784FE785E8E49A176540126E4CBBF
+:10CA60004CE44FCE97E5FEAE8A3CC72BFD70FE0F1F
+:10CA700094CF4A7F24B553E5F4E534D7216EE75AC5
+:10CA8000B216C0B86E03B946BDE75AD8230BE5A469
+:10CA90008D4FCC36E427E09398520D1FD435FD68B6
+:10CAA000443E310D13884F2C50E669F8C8D9EA9FEF
+:10CAB000D8F2BBA15FB528DEB09CB5D57F95A2FAB0
+:10CAC00029D7C6EF1F28ED4B42C08FA0F84F18C3DF
+:10CAD000F8DA852889E2A47397C1200105734D9E79
+:10CAE000648CC3CCBD3F88E260A507AB97844AED58
+:10CAF000E975B73F83F69727FA93A83C90E83A8DFB
+:10CB0000F898E6BF53C163C635EDCF653B78DCCD01
+:10CB1000E4B6D8D7C563DCCD25D27E5C6F667B9248
+:10CB2000EC94BA1FC7E36E18CFC3F85EE0FE1AC6D6
+:10CB3000E1703D6D8932E8F609DBC5E386EBF7D39A
+:10CB4000CA9B3E196480FA53F10E8ACB79FBB88CEC
+:10CB5000A9308FD913DCAF9BB4FB6C0A1E1B8C9ED3
+:10CB600064B4A30DD51C3F0D2BC402DA6F622CB840
+:10CB700050735EF76A7C3CDB9F48F851ED8BAAB797
+:10CB8000B7D7D0A1CF56FD7D35BB53A1F07B05F2C1
+:10CB9000BBBDBD9D51F935909F55FD6C8A3E487ACD
+:10CBA000E8367805FD07555F17E40D1D86767EE8AB
+:10CBB0004B895BFF0CF38F4C7365A502FFDCF24AD7
+:10CBC000EFAC3500DF66741B6D21D7A20F7F349167
+:10CBD0003E7CA490913E8452AB0F4D9DF8E1B9A9E3
+:10CBE000D7A7CF5395F6E0C772FF10F4B5B6BF8A4A
+:10CBF000B4116370FC85A9DC4EFE52E3EE4C8F1736
+:10CC0000A6AAF2796D7AFC66A5FDD5F4F88C54AE2F
+:10CC1000C703F5366863D2DBE7DEEE4B71B2C30CB7
+:10CC2000F43CDAB3C6606963BCE69C7B9770B75688
+:10CC3000AFC7F49B3E03F9FD1AF4FA7D88BF7F5716
+:10CC4000AFE7176E26BF0AFE9CE36F86F5C76F61DC
+:10CC50007D87F047B0BE8B6F2F0F817210C8F7B081
+:10CC60001ED9FA318CAFF9A93E1477003920BEAF36
+:10CC700000BE473950E5A572EB8070DC37607F114C
+:10CC800019EAFF403928C87BC588712AD4E388AFE8
+:10CC90003D20F3A86702ED843FD5B50AE7AFCA830C
+:10CCA0002A0757E7A39D265C979ACACF733D0FA525
+:10CCB00056CF77E6CFFCE13AF9FFD1D46BF3035EB0
+:10CCC0004DE5F7207E41FE7935F5DAFC82D752FF3B
+:10CCD00023BFE02DE21FD49FB87EBBFD437BF87CD1
+:10CCE000CE3F742E11F8210BE3CECD837ADB314E8B
+:10CCF00073FB15EED7834E27BF3ED0AF9EACE8BF87
+:10CD0000A94A9CE0409AB32595CB2BF9EDC3138338
+:10CD100007A0BDBA567F6F725435C338D35428B5B7
+:10CD20007AC28274EBC05FFF6BEAF5D9EF3DD7485A
+:10CD3000DFE3A9FFB19FE7BB167D90E4B04E447CD2
+:10CD40007EEF3132C4D3D5D603A6D51CCF2ABCD8AA
+:10CD50006354ED6624DA4DE08FF3FF097F8CCD6BD1
+:10CD6000B86805BA86A7198B301E78279EB5A078BB
+:10CD70008669952309F50D53F70528DEF191A8C2C0
+:10CD8000E68323611CB73FC9DAF60DA07ED4B0F06C
+:10CD9000D6F888C0DADA87A5890757D0B8F97915A7
+:10CDA000E6F21AF93E990267011CAA817302E0B506
+:10CDB000BC7D98D1CB6CDA7E14FD33CEC6F705DA94
+:10CDC000F6F37CF95DD1FFDB2AD8707FE19E61E745
+:10CDD000CC18CF199BE7DD1B0BEDE2D3428B42C091
+:10CDE000C4DFB355A0F10ED814B54A4EA2235B0E92
+:10CDF0003C6F589EC3F74D2C0D4DF98E0EF87040C8
+:10CE00009ADE4EE19FB11BC5C7E8CFD22030731622
+:10CE1000EF2721FEDADE47FAD1FB09F4BEC712750F
+:10CE2000EDEFDF358C39DC1DF0D12D698A3EC4B8B9
+:10CE3000B0DA3FD0646283E0E8286E73ABD2BEC53F
+:10CE400060A86080A7F19BD25661DC6B14E37C5133
+:10CE5000B829B548E6FCC71C01F3FDB9F166A7E99E
+:10CE6000D767F827E9DFF7FC1CBE86B6C39742FFF9
+:10CE7000323D9F841B9DEF7E0FE3088F126CE8A765
+:10CE8000563A8356B070A4BBC2D7F2C022C73098BE
+:10CE90005F10D3C5F15AF95ACE2C42BEAE646AFB7C
+:10CEA000EC55487FA7A1B53DE7F346A1F5FD342336
+:10CEB000C34FD0FB733665ADC23839D083EA09362B
+:10CEC000FE0C9F3704C0C302E4827198E412F5326D
+:10CED000E027B983FDDBA50A7ECF0AFC7C53CB0893
+:10CEE000EECFB524F0F2C534EEBF3DAEE0F169A55A
+:10CEF0006CE9A2C143AF363AC39F07D7039A7913AF
+:10CF00009EEE8E52E62D4F2C1A03F36A8960FD05C2
+:10CF1000E093759BC6AF5AA4E193E7374D2C423C92
+:10CF2000B4F627171E443CDEADE0E9C54D130E22D2
+:10CF30001FE1911394B78A1CBEFF6AD9FA7187F278
+:10CF400036B73DFFC8985FA1821809DF131CA62CD5
+:10CF5000DE4F4207F859D0FE7D47C0FBCC14753D2B
+:10CF6000EF2BF4191340BF8200FA8D0C808BF57003
+:10CF70009B1F0C3D83FF54B263E5E26E183FDB2438
+:10CF8000D01D2BD0CF66019E37A6DD5B14D203F9EE
+:10CF90005432C5425B4FDAD483D6BE208FA8BF4837
+:10CFA000FFBA485F4F443927785A91E346E49BEA39
+:10CFB000C531D07E6F5AC92ABCF77ACFA2952644D4
+:10CFC000FA0769335619A1DFBBB3FEB417FB330A66
+:10CFD000A507C7083FC3A7F501F3581B00CB01ED18
+:10CFE000575D459F2F0A78FF9180FA1501F0EA00FE
+:10CFF00078A9FEFD6933F8FEE534A01F22EE6AF23F
+:10D00000E24D6B5D37B4DA2F01EDD9877A7EBFBD73
+:10D010008EC327373D50B4344403A7FDAA48CBBF85
+:10D0200026C55E4C8E723A3AE2DF439DF14F5AA01C
+:10D030005D9375E7120F33A6B3BF7B443DDC24AA92
+:10D04000F2B5F0E0BC74CD7EA05C5B84F194CEF7C9
+:10D050002BE422DCAFB8FD71B57D4D9143333FB574
+:10D060007DFEBFAE88F8BD2B6935451B68FF4FD9E3
+:10D07000BF8BE0E52D97AF84215DF2F1FC28D677D8
+:10D08000F124CF4DD7CC8F35A4E0FC9A1EE6F70DE6
+:10D09000E53AA007C87909B3D3FE775378F8821729
+:10D0A000A0FD9E87C50568BF0E2F88A4F346E3FB4D
+:10D0B000727F7B4F789F6EF701DC143CD58C71D565
+:10D0C000A6474751F98EE858E203E4F7EAFB5851C6
+:10D0D000485FAC0F27BCC4BCB4ACA816E420B6AF04
+:10D0E00044EFBB226CDD76A01FBADCC470FF89312F
+:10D0F000FB73C427BFB3909F3AADB61FEDF794FC06
+:10D10000BE30BF07B42B596CA2F83FFCD17D0CD7C1
+:10D11000F25166AC9FB14829E55BA9DCFDD31B1F2A
+:10D1200066D0BE8E48E77676F9238E8324B3AFE5CA
+:10D13000FE745FE1A8925F656B5F576A5F18C7D79F
+:10D140006792285F0AB3496113D06FBBC191D6378C
+:10D15000BAADDDEE9F44DAAF7AEB4C4937DCDF1B2A
+:10D16000D897F3CB2E7F49B7128D5D2F3D6B243CB2
+:10D17000EF364BF3506FECEED25B90496E1B2231D1
+:10D18000CE3A43F19B814F16BCD1011FF6E92B1219
+:10D190005E8E5916E05958D6F4DBE861382EF5BD9D
+:10D1A000EC83AE3ACC1763EA250DD4FAC7B9C9238C
+:10D1B0006EC6F1B6F1D706D2E7E41F033CBAEFBA68
+:10D1C0005532D80FB607FC7A1C4794231FF9493D06
+:10D1D0008FC7621A52B47185363F74A122FFBCDD3D
+:10D1E00057783818BEFFD5AB4174EEEB2BF98B5056
+:10D1F000AD7FACCAC7CCB0FF39DC42EBE2704988E6
+:10D2000003BE31D61C7F08DE2B7DD6447AB3F4D919
+:10D21000E8477C580FF4C42DC3C0EF3EDF979F074B
+:10D22000E85C3EB6148DECA5958FCD4538DFCEE495
+:10D23000637ADFCD9DC8474D37E4A3FC674D74BECC
+:10D24000BAB84BF59D18472C36DCC8EA607C239EA3
+:10D25000FD5537DC6799F9AC85E8EA0D0D3DCEE761
+:10D26000D5271EE7D56A7FFA727DE5ADCD257B21F6
+:10D270001AC03B03FD2D2E31D17A44EC6626BD2722
+:10D2800086D9797D1716BF10ECF2E2D01C09E9EBC4
+:10D2900056E401EA25E4B3BCF049B7E1B996C30B03
+:10D2A00012691FEC6416DF079BF5D0F361E87F7EFF
+:10D2B000358F9FEF9E8DF976709DFB6FEE7B552924
+:10D2C000F976FEB7F6BD9EE8ABDC1B6ADDF7E2E758
+:10D2D00040F72CC8CCE278619205F1143780F072E7
+:10D2E000AB95494180173182A5A0FE51F7BDC45FBF
+:10D2F00073FD241A045AA71FAB91297F415E9895AC
+:10D300003FFF35BFB7273E55C8681F2CAA9AF6C104
+:10D310004211AF18BF159813E5E768903DEEFE7413
+:10D32000E4BF20A2E7CCE7667DFA872CA4DBD828EF
+:10D330005D3C41E13FF5FD13B537D1F84E08CC8691
+:10D34000F63EEF8FA923913E4DA2EBA9BB496F0694
+:10D35000D3FE39B3797F3718E099B5B0CE66C837B8
+:10D360003DE212D2DBFA99B9F0E114A477DE1F8313
+:10D370003C78FE66C6A2A0D5780EA3BC91DFF39ED2
+:10D38000B6EC7B3A8FCBE28DD518E7FC7A51103F93
+:10D39000A7BE7530F1CF34033FE7C2E2CC145F2A59
+:10D3A0000F51E05E39046BEE2F99911EEAFD9BBD93
+:10D3B000A857E0FBC7557CA0DF887A573D47CFAA26
+:10D3C0002594FF6283D0E139AFBFF5E5FEE9B438BB
+:10D3D0003B9D17AD78CC625F18CFE92C0EC2EF32BF
+:10D3E0005A1755187CF9ABB15F0393B6D970FDD0CD
+:10D3F000528AEB6DB63595F210541999D11C01CFB4
+:10D4000025AECFD4F1544985B7123F19D921630411
+:10D41000E2B1E5D316E48F85A112C6452ABADA5DDA
+:10D42000D46FA8D5C6ED84F25D1C7B22F281DF1C8F
+:10D43000817CF0A960B0F0FC030E03D49F63BCBEF6
+:10D44000F53B8B96A5D3BCAD36C3881EC877E7F3F2
+:10D4500057C37BB73229A107DE135B1679E724ACEB
+:10D460007F4D24BD04C2F4580EFA7BAF8999B84EA3
+:10D470009DB66C0FCD6FCEE6017883804D7BFD00AD
+:10D48000D9A7390A7F7995736B25006F463C2A7AB4
+:10D49000C125B26A8A8729786CC5AF525FB1CC4486
+:10D4A000F4A8586C213A57D4FE8DFAAD086DE98680
+:10D4B000F4A8D866A2FC1DD61BF83C4A6A7B0F3B39
+:10D4C00004E32E3185DB0478542E8F35235C5E2FE8
+:10D4D00010AC7EAF62D95FBB19D2797F585A0C7CF1
+:10D4E0009FB5ADDFE838B467A75F8D8C9BA6A1FB25
+:10D4F000E945DBC370DFF968902719CFF9FAEE0F21
+:10D50000B2E3B942359E767A5132BF0F646B09C5DA
+:10D51000FDEA19F31223D0CE1DB679CC587FB8217D
+:10D520001E8FCC3187CD360C6187F146824F2BE7B9
+:10D5300048E80FF3070A9C6FCA5FDD634E80EFF582
+:10D54000BF81E3E7EC6B47F70E417C001FD950FF2A
+:10D55000C4B5A4A01DAE30B4A4C4227D5E16C85FBD
+:10D5600080F5A903F38F54225F0D047DA8F055E5E3
+:10D57000D6EDF3513E2BDE3C998F783D3B969931A9
+:10D580003E56A1CC1FD68FEF1AA17DC59675F98C9A
+:10D59000BFFF2EF29D6AEF015E6402B8D9CCE18C28
+:10D5A0001BB87E6E367B29EF5DF39D8CD1FE999181
+:10D5B0008DC47640797E0F401495FB69D531137880
+:10D5C000DE3D597B7EAE12EBD3DBEA3BE39BF137CA
+:10D5D00018143A5BC82E8D47BC00EC5DB62D0CF9D3
+:10D5E000E2EC6B7BF60E41B9D822D898561E54391E
+:10D5F0008CF3F17AC0DF1388BF2DE7F3310FC5EC50
+:10D6000033A112D250C5932A6F2A5EAA18C7838A03
+:10D61000972AA38227A5DEA9E0A19CF9A83F76A6B8
+:10D62000BFB411FB7FF347DA6F3B3B8D09FC9C30A5
+:10D63000CF8BA6CECF15A1DFDFAFBD81F3FD146583
+:10D640009EE5366E17CBA398543B80F8CC6156F319
+:10D650004B4293B39B8FE8C6BF5A9183567AE33C03
+:10D66000609C5E03BF2718A8BFE6297C75A476B22C
+:10D6700007F5CA6C19FAC94279B04DC17D4EF6BAA8
+:10D68000A8E86FB0999AEFE6BD7284F81074971409
+:10D69000016B16D3261807FA5F677A53BC30AFBB0D
+:10D6A00097E6BD718C8D19409F1C11BCA13BD01E0B
+:10D6B0003C24929E52C7E9903F247A381AB87C22C3
+:10D6C000BF607CB0552F048CB75619AFC560F7E228
+:10D6D000B960B650A0FB6BE2C2B3A187B8BDA34846
+:10D6E000625BFF37BD8BFB918E8B61924035762359
+:10D6F000B6ABBC189680F6FB88127738B2787B58A8
+:10D7000089860E4F75F69D258325A47F5EC8A18767
+:10D71000518E1E53DA359BED2317A03EB81426E137
+:10D7200079A9E608391DFDA866035BCA22381F1ACD
+:10D73000BBB5E10FE485F007F5D293B636B954C70F
+:10D740000D74F320DDA0BD83CB919DF6312AA3F8A3
+:10D75000BEE8D5E529D34BFAA95690D667B5B5539F
+:10D76000EFE53DAACC9B64A45B9B3D40FE447B67F8
+:10D7700051F21805E641BDB557D738C45F5588D575
+:10D78000804BB8C0FA40B86D3D556D443F9F2D8A1F
+:10D79000D9ABBD97763448A6FB67BE1E225B0FF45B
+:10D7A000A8BDFF7D7E9EB791DFDB52ED34FCAD68F6
+:10D7B000E53F78AF2CEB7C3EEAD717732D74AFA909
+:10D7C0006BBF04FACE29D6601E8EF6FFDB96FC30C6
+:10D7D000A96D7D72D3458F184EFE42BC6E7D507E82
+:10D7E000E65D92E70AD642F7B1A72D3B307630D2FC
+:10D7F000FB25139D1F98511F4F76EEE486E999385B
+:10D80000DF698B93099EB5F13E0E2FE3F90FA72D2B
+:10D81000CE7E01FDAFA3418E7CE467DF4AC186EB7B
+:10D82000ABA11BB31FB907EA8786F6E98AE3FE6A54
+:10D83000C3D1B148F7AF1688A49F1C1B9EBC13EB45
+:10D840001D3B44BC3106EB19DB2398D79419C36DFB
+:10D85000E817A8E70BEB4C5CDF9E51F4C231454F53
+:10D860001C53F82FAFAE2E05FD25DF3AB047B8EFB9
+:10D870006DF695D2F96EC1665F0FFCF2AD2013CC48
+:10D880006CB684DA5CBCCFB296F2E39C4BB6D8D0CF
+:10D890004FBED7C2ECE8D7DEBBBBF7405C2A38945A
+:10D8A00075D5D848FE5D155FEAF74F2BDF65E28A34
+:10D8B00052DA7788941250BF352BE7C68F2AE33DA2
+:10D8C000B9E8A53BD12F38B929398269F07E52C910
+:10D8D000D3340BF4E0960ED67BFE1BD4B8839BBEEC
+:10D8E00053A6C403F799EA7B61DECFC0FB5D27D660
+:10D8F0000559313F6FE03DAF13266E3FDADDF7DAB1
+:10D90000A18703F3DC068EA7753D1378FFBF5F4840
+:10D91000877EBC2A6781EFB7BB4F9E746DE7AB3043
+:10D920002F19DEF7DE7303A3F74606FFEB0DD4D7FE
+:10D93000A5F5161BDEBF3F1624D17A48CE66D24627
+:10D94000B43356291CD7F3C7F665D2F9BFD22F19C5
+:10D95000C955E956D18DA98ADF5D99FAF83080EF73
+:10D96000DB6AB2E3FB2757ADBC938B993ECF420EE7
+:10D97000E3F23913D6491E5BDBBA2870BD347BF560
+:10D9800066BA47F84BAD97D4385220BE73FBE9F323
+:10D990002D04DE9FDB0D6C9333B03DBECFD4B86851
+:10D9A0005DF45D4D1995B90DEBF26225BC4F71E444
+:10D9B000B1A12837A1E1140F3953534D9B78DFED06
+:10D9C000C8BC8CF743DF0A09B7A1BEF8AE66817206
+:10D9D000B940E113852F6FDADA24C6326ADF3814D2
+:10D9E000DAEF0A09A7BB2E498E9C70B4F32A5D03B7
+:10D9F000EF37ABF33BF510A7AB3ADE539BA687A1FD
+:10DA0000DFD9B426B23117FA9383C36DE86FCF54D0
+:10DA1000CEBF1C5FCDF5CDB7D6F017C6E0F999B5EE
+:10DA200013BBE1BAEE3E93CF6C877EED6F1786E1B4
+:10DA30007AFF1BA3370CEF1B7F03ED3D68278C6E2D
+:10DA400011F5DC900246FB78433C4626C5D3963957
+:10DA5000F145EE19A31BE97ADA7371CF15E4A3330C
+:10DA6000068A770166F65C81F6F6D03E1427BC6F15
+:10DA7000275F6FB27F75E1F501F7169FE8C7F5D212
+:10DA800089B56F8CA3F5F906930DC7F9DD86BF76CE
+:10DA9000C37338B3193F5FFFED2681E6311BF831C0
+:10DAA000281EF5038F83CE06BD6F15DAF361DEA65F
+:10DAB0005AE2C3D9C08716F4D31C3C1FF36CCCC701
+:10DAC0002CB176F93FBA2A7C3707F80EEFEFFED279
+:10DAD000793F96F70B3CB7CAF950A5BB8A1795FE5C
+:10DAE0006D7CC874F905231A060C8F656DFA40BD6C
+:10DAF000DFC18CDE15784F63BE185A8FF9AAF61B6A
+:10DB0000ABFF48795B6423DB48F69CA561BEBCF99A
+:10DB1000E20D768C07D699AB5BF3BA607D605E1739
+:10DB20003184BF5F88F98961BE21E9F1F4BD09360E
+:10DB3000FB2844B729CA4B710131CFE0A07B79752E
+:10DB4000165A3707EAA15714FADE86BE03FA3DFDDE
+:10DB5000F8796DF5DE9F5A82A1E98DFC5E181C7183
+:10DB60004982263B5EF9FC0EDCA72D1C1AF1AB4462
+:10DB7000F87E53BF2377E0BD8DC2CC886D0900EFDE
+:10DB800079E5EFBCFEC6886C13FA01C2D7778C44E6
+:10DB9000BFB19FE3CD7E9AEFA8FDC2F39DF8FCF3E1
+:10DBA00038D7DBFDF8BE6929D2FB9C10C6F3BD2532
+:10DBB000F9280EAABEF7B1C00EBF25B4C15E138B03
+:10DBC000C3BC06CDFDB83EEDAC8C4A77ECE5DFD7A3
+:10DBD0003F470A7D8FEB4C65FFC76095CCE8FF3966
+:10DBE000ED663BCFAFC89C56F0ABC62BFC5B62BD6D
+:10DBF0003C92EC6F35B35B3081C952FD7DACBE6D9C
+:10DC0000F7F6D65ECFBD3D26F33C7C754A1EBECEF0
+:10DC1000EE510A8DEFFF88FE65E0FDA9CCBFB4BCD4
+:10DC2000897C320EF80AED45560B87C72B7C52B122
+:10DC30007D2CE57B9EFBB1C98D7EC22CC51F4B722E
+:10DC4000756112B4BB04F28B7AE1CC384F0AEA8FCB
+:10DC50001335AC3E09145681D5E543BA34C7BF4FDE
+:10DC600079D14EACAD0B43BFE72CAC27C64017E5CE
+:10DC70008A7FCF2E8B9E5BD00F8EEFBB7EB986DF67
+:10DC80007EECC7EDFF99784F1CAE6FE4780BCFD7D1
+:10DC900078790FE5792E48189D8D71A4FD353BD814
+:10DCA000D1E4B6F73ABB8F32C43082A56BF625C7F4
+:10DCB000193B3EA7F1AD9A4F7303B7DF16633DE5FD
+:10DCC000D1025256D712ECA4B8520CF228C687A53E
+:10DCD00007085E328BD9E81E6BDB3E1DDD0755E978
+:10DCE000EFB05F1989EDC601FD51DF18AC3E23C2CC
+:10DCF000CE027E3EA52F100EF5894AFF51E2238FFA
+:10DD0000211DE62AF7B8E60AD51C3659E99C6BA016
+:10DD10007EC4B86631E94D796F2EFA63A02729AF2A
+:10DD200082A21725F81FE545CA5967A66657CF8B0B
+:10DD3000B437F73FD08F19E9FA3CE22A9D54FFAA85
+:10DD4000333AA97A12E835E87AE8A5E6299BFB2C54
+:10DD50008F77CE7D767ACC40C21B481CFA43317F48
+:10DD6000A2B8CA4C650E6C6D24F1B1698453427D32
+:10DD70003B76472C93E0D1AC1D029D6F1DB32392DF
+:10DD8000E0307F0F9E5749B1F7635FEC3E02E393AB
+:10DD9000275FF8621EE6BD1FF35B46F16343700820
+:10DDA000E59B104728791CC490F7F01EEB05C95875
+:10DDB0008DF6CAC9DAE50F3010FD9BF9395958E5DF
+:10DDC000C99C4EFCDEDFDC7DDCCECF1DCEF7052FFF
+:10DDD000E01BD0FE429148799A9E0ECE20FFADEE18
+:10DDE0000E13DD8F60B2E3135C574D52F8C112037E
+:10DDF0000B4B0DBD822490570D7D1E0D7AEC3D1707
+:10DE0000F4EF857597D013FCD8B4085DBD510EFAB8
+:10DE100006F3C79A62449B1BC61F6AEFA9EBCF2982
+:10DE2000969B309EC25CDC8F56F98B89678C746F31
+:10DE30007E18CF5F71C724FD3D49D3B0F323C9DEFF
+:10DE40000CD3FBDFCEABE46D5AA0F2535FD657C9BB
+:10DE50004B4FF6FFC2417E3F4462CED5AABCA0FE26
+:10DE600007EFE669C4CF9DCD26E696087FAF61FD3A
+:10DE700005D962C37840AB1F9E04EF45A191B4124F
+:10DE80009F635E50ED3C312FA8162F9817540B63FB
+:10DE90005E506D7BCC0BAAADC7BCA0DA7ACC0BAAC6
+:10DEA00085312FA8B63DE605D5C2981754DB1EF381
+:10DEB000826A61CC0BAA6D8F7941B5F59817545BD6
+:10DEC0008F7941B530E605D5B6C7BCA0DA7ACC0B60
+:10DED000AAADC7BCA05A18F3826ADB635E506D3DE1
+:10DEE000E605D5D6635E502D8C7941B5ED312FA86E
+:10DEF00016C6BCA0DAF69817540B635E506D7BCC47
+:10DF00000BAAADC73CA0DA7ACCFBA98531EFA7B646
+:10DF10007D0B5B948C766C67BCAB393D1AF79DBE6C
+:10DF2000257E3E742FF033CA61F3441BE52FBCCE2F
+:10DF300075624BBAB26E51F8F7120B9982E7D03B7B
+:10DF40007B5FE5CF97F09D6CB2074B897F59683DA9
+:10DF5000FA738F1A1D741F4A6EE0F7139991FB0133
+:10DF6000F345C5FF51F242CC1725F2033077B0518B
+:10DF7000339EAE0E2B336AF0105960D3C1D1CE1848
+:10DF80005DFBEE93245D7D0F579AAE3EB6CCAE831B
+:10DF90007B57E7E8DAF759E0D0C1F17281AE7DE254
+:10DFA00052A70E4EAE9FA46B9FBADAA5ABEFEB2E35
+:10DFB000D3D5F7DB54AD83FB372CD0B5BF7187AC1D
+:10DFC000AB1FE059AAABCF6CAED7C1D92DAB75ED65
+:10DFD000071F72EBEA73BD9B74F543BF6DD0C13769
+:10DFE000F976E8DADFE2F7E8E0E16C9FAE7D9EF5D6
+:10DFF000631D3CCAF699AEFDAD314774F5A3A593F8
+:10E00000BAFAF2D3DCBF6775B03EC0386508CFAF4F
+:10E0100051E9610DE85FDC9E765ED7DE1405EB0505
+:10E02000E09F0AD087E8F7FDD0258EF231B3EA30C1
+:10E030003BDEFB964754FF517BCF7BACFD47DDF7C2
+:10E040009F0E0EF304D1FAC24AF6F6A6FEFCBE59A4
+:10E050006B3E11F53E3BF3B198280A09F9D03F1207
+:10E06000F01796000E73F0BCD0E00791FF6403BF79
+:10E0700008FDCDD67591213E1EED72709B5FDCEBE5
+:10E080008A26CFCBD5FCE2DBF1DBD994A7D7D11F11
+:10E09000CAD90D9BF3719D358BC94B703F51CDB3E0
+:10E0A000B83F481FDF52CBD156C0AFE67BFB82EAB8
+:10E0B0007B0DFC19791F6D3D43ED5BFB55E25F0263
+:10E0C0004C76AEA6FFC760FD6704B9AEAF01F90399
+:10E0D0007FE8891A1BC1AB6A62087EAA46A27275E4
+:10E0E0004D1A95CFD4D8A97E6D4D0EC1CFD5380825
+:10E0F00076D71450B9BEC649CF37D44C22F8851A0A
+:10E1000017959B6ACAA87CB9A69AEA5FAD5940F0F8
+:10E11000EB3532950D354BE9F9969A7A82B7D6AC44
+:10E1200026F8CD1A37953B6A3651F9E79A06AA6F59
+:10E1300004FF0DE15D351E823D35CD04BF53D34252
+:10E14000F0BB358708DE5BE3A5B2B9E65B2A3FA8E2
+:10E15000F151FD5F6AFC049F51F621E6F71774F751
+:10E16000F154D8C88E717F0FF356601E861CD3778A
+:10E170003F971F37900EA794FE4D23C05DC23872A3
+:10E18000CF94F5759A75455D7F1EB7AC35F0FC2DC3
+:10E19000B53D99AD8EFC7607E3E7B4B8DF3E13FFDB
+:10E1A00025C1D3A89ABDB8DE28ADE679CAB3911FC0
+:10E1B000D3881FFF725DEB34655DB025D1F904F2A1
+:10E1C000230B717F1A9FD5768FFE40A2EBF7F8FCE8
+:10E1D00042F57D7BB1F54C9B3D053F32D6E289C6C9
+:10E1E000FC5FBE7DA27DBDD4F9F7AA94FB0F9DD63E
+:10E1F000EF3AD90BED55C14F22C5F5F79B4227E108
+:10E200003EFF8B0A3E5EEC6FD0957725395FE88F35
+:10E21000FBFBC9D52F3C20B4DDDF1F8F4B7C90EF7B
+:10E220004226511E9C89CCF11EBAE077802388F0EB
+:10E230005D4CA6F24482EB4F389FBB610182B06B0C
+:10E240008825AEA3F9048E67A7329E9DCA38D47282
+:10E250006E927307F6772CD9A11BCF8B4A7EA171E2
+:10E26000CCF71C8EEB1F6F9F3F2E24B6E1BB359E73
+:10E27000C2AA294F4631E3F19447312F46545B5EE1
+:10E280000C75FD50BC8FFFCE11FDA1FD9C1F4FEB07
+:10E29000DBC0BC194B86EFE17930603D86F77F8BA0
+:10E2A000EFFF15E95FFC3D28BCB73BBFCB61CA332C
+:10E2B000E39D05BC1A4B793578DE1B17203096F2AA
+:10E2C0006A50BD7003FCBF078ECB9A66A4F175A19E
+:10E2D0007C274F07EFA7BC341853B074C5BCC7F1F7
+:10E2E00034CFFDCEF3DCEF8EF2D1FDD42D89AEAF6D
+:10E2F000FAF338F953991827427EC2EFD8DC747EBE
+:10E300000DF8C92C008A6646013F75E06FA87C5362
+:10E31000A9DCC3519F033F9E407C7FB773701AF204
+:10E320004DD5AE5C09F15D67E0F7E9E40F947D41FE
+:10E33000E5F710C4F0F47574EF009D71A46F6E28BA
+:10E34000DD3B6812D982CD1DE8576B06A7F3FE1896
+:10E350009E4FB22E607F52C8E07417947663DFD967
+:10E360004779C82A9B79BC9A6579D39D1D9CCBAA15
+:10E370005AF0DBA79234F3A8DA71849FE762DE7467
+:10E38000ED392E49E957E53FD11CEA5A17A21D5F26
+:10E39000AB1C5832B2490E8EE3BDEE711629FC2E2D
+:10E3A000817E1FEC3BCC2FE3FAA38DCE03AAE702BC
+:10E3B0006730279533C17222DF3BE595747F7E3647
+:10E3C0006BA0E79539D3E310AE62BE9131B83E5AE7
+:10E3D0005AFB1E868326D6AF1CD503E635C13DED1C
+:10E3E0003D2C0B3708C76589E42806BFEF15AA172F
+:10E3F000F784EFDDF3EAF0C518B71E27723AB00FC5
+:10E40000391D8A819FC588F6F303B9E993114D72CE
+:10E4100043E357E5A6782173E0F903F57E48AB1C8A
+:10E42000E5CCF97B2CEEE1803F89FC5AB5CB12415B
+:10E43000EB53CC3383FA4A919FC546EE5FCA98DA14
+:10E4400094F427F7374C0E259F17E3FEC81C99AFAD
+:10E45000C74E99B8BC9DFA2AD48DFC3DBFCBEB7159
+:10E46000241F26553E7E9A42E77B18F81F37B7F7E0
+:10E470003F5AF3CCF462E46FB03857CCC0C4367B5B
+:10E480007ECAE01E14C6F3F23B105F7B63F8FA7994
+:10E490000EE6A1C1FAAE4E09E3A5A7A2AD745F28AE
+:10E4A00030CF1963769A9F49991F8C6C12FAD31654
+:10E4B00025AE561730DF1F82E268BED270D6C0D0BC
+:10E4C000B130DAE4E928F70F703B31BFCB6F5CF86D
+:10E4D0007D6F10B30943693E148F950DCC59C7E386
+:10E4E000B334BF0546AB0DCFE52C99267A05B213A0
+:10E4F000304E8CE74559ED3CAFAA9A7F3B70BC0E7D
+:10E50000FDF8AC710CE7E710992F68281F2F8E4F8C
+:10E51000067A107D009EA6191FF4EBA6FC3FC1925F
+:10E520000DFDB0E67F3DC0E3CBB5DC7F84F16F220B
+:10E53000FAF480F1C75E7DFC26645118FFDC0CAE56
+:10E54000A7EA700751443BDB95F4EF8420E7FDC850
+:10E550008749AEE5BDE6625C23D762C7F81DBB5CA8
+:10E56000D70BF554089328AFD63807CFAB05DD2D70
+:10E57000427E28C4BC7536F203CE68F3B0B180F891
+:10E580001A9085E2AB1330BEC6EF12BD8BF1D9896C
+:10E59000CAF9E6BEEC4B157F145F13717C14AF769D
+:10E5A000D1382D4859288330CE437470D33C82999A
+:10E5B000478967B7907FB052E1C3218718D9892175
+:10E5C00021DC4EEC3AC2DC78EEABE9C73BF342A16A
+:10E5D0007ED77923E929C013E503FCF35FB95DD940
+:10E5E00075F2782CEE07D4FEB83716FDC45D269779
+:10E5F0005885EFE75A6C0BED6D718DC643213CAE2B
+:10E60000A3C4F96E52E6D9C85AEAAAA03EA787C8A1
+:10E61000300E987DD0138CF28C396A3BDA6F1C7601
+:10E62000D1ACFB5D0B934D0FE7300D1C8F21B280F9
+:10E63000DFFFBCCE75EE6B199DFCEEE799A86BFA77
+:10E64000DDCF2C651E8F6638DFCC20BB364154F001
+:10E650002E20BE400F3421BE9FA930D3EF1A34556F
+:10E66000987B7835E3AB9FF50FC2EFEE7FFD83EC2F
+:10E67000D6EE6C353F4E43103E37CBA114777BE688
+:10E68000B281E26E6BCABEA6F5497D0EA3DF11AB67
+:10E69000BF5C427EC0A502869B48ACF6E6FF53866F
+:10E6A000F0E33759E97B81E37F1BFC790F10EA2DFA
+:10E6B000F0E73DA9E0AF803F8F30DE67C5721BF801
+:10E6C000F358BAC19FC7F239F0E7B11DFAF3583ECB
+:10E6D00003FE3C96ABC19FC7F229F0E7B1DD2AF0FB
+:10E6E000E7B17C02FC797C0EE3CAA3711D62746FF2
+:10E6F0007F6170D832F433243994FC8D8F1C03BBB6
+:10E70000783576F6E68B061D9D879DD1FFBECD90B0
+:10E710006311BADF3FC9F9B2A7AE7ED0C1045D7DF7
+:10E72000BCACFF7D9B3E0B7EFEF76D62CB4604FCCE
+:10E730003ECE6D01BF9FA3FF7D9B68E73D01BFBF3C
+:10E74000A3FF7D9BC7957C992A1D53A4D782902F48
+:10E75000D6944D08671DF8176AF984420F157EF2AA
+:10E760002171524771E4F01BB9BD7FE72BCBBE0D81
+:10E7700080CFDD2CDC8971F7DD0E03E9A5675687B4
+:10E78000501CD6E21D7212F967B78349C83FCF5CAF
+:10E790001ED105C7331CC888CF63CBB87DEA79A3E7
+:10E7A00044FC1C5BE613F1BEE82D977D76E4C72799
+:10E7B000C3F8EF6C41BFEE85D0DF3B6307F5C5388A
+:10E7C000CE3321C0CF286F1E5F7012C0E1570C0CF2
+:10E7D000F523D84ACAF32FFF2144398F7A85EEC337
+:10E7E00085A34E07BDB4BB8C7F3FC57B3958EB0F6B
+:10E7F0003DFED3D5F0C288AF3AADBF6D76028EB77D
+:10E800000DEFA01AA14C6165EC31C44739979FFA0E
+:10E810003203C9D3259027C40FCC9AE8C25AF4F228
+:10E82000FE04CA87960EE509CB709ECFAC32D26E3D
+:10E83000D928F1D57D37C22B6B0E8AB4CD2ED97C69
+:10E84000C11DF977EAB8D738F8FC22ECCC80762ED7
+:10E8500002F0E9A6FD6C7BADF6F7ACFEA0C8E7EFD1
+:10E8600015F97C5AE1075C6F233C4A5C3B3A05C7CB
+:10E8700091C3F535D053C0FB58976630FA1DD1DFF0
+:10E88000172574E928CFF72A651CCF29F35A8BFD89
+:10E89000923C73B91F25160FC77ED63819E9F1359A
+:10E8A0008EAF6B316E77A988F7DBE711AF80F8ED9B
+:10E8B00055ED13B0FFDEF33C54BA9571F62C6BA105
+:10E8C0007AB53FC9EEE6FC5EFE356B86F9E2215B68
+:10E8D00091ECC519CA8FBAC668646887519F217CBC
+:10E8E000C96AC43312ACE7AC630CEF33D78718693D
+:10E8F0009F624DE5298257DA381C2657A7E3F98B2A
+:10E900009DCA7CC264996077C07C52A4A9E1DADF19
+:10E91000730D2CB72B78DEA6E063A7C965B800E3BA
+:10E9200018FC37917EBFA3B3F7543B9BF3A521405E
+:10E93000FF74D1C93FFEC69E62171EBA11D7CFB26F
+:10E9400093EC82BA6EDB3686DBD795C1533EC47535
+:10E950007F91C2474F078F7B0FEB0F8CE6BF83D3AE
+:10E9600034FAD6DE5A3DB94319F77605EFB9B2E36A
+:10E97000AB79D0BED069C191811973F4FE15F4E76B
+:10E980001C23DA3D40B783D9AA3C388351EEDE1907
+:10E99000339D1DC2FE0BF8BED3B68289F45C62CEF5
+:10E9A000DBFBC37B9FB418C99F81E73F2B8FFB150F
+:10E9B000FCFF4519C7070AFE9B153EDD8B76241523
+:10E9C000E32C6954BEA3D8118F6247762976A451EF
+:10E9D000B1233BD18EA4E2BC2651B94DB12359A33A
+:10E9E0009F243FE912E6C515D08E54B22530CE7C67
+:10E9F00018BFD8817D1B9F2306FC4E56B08E4EB7A4
+:10EA0000A745EAE0D1526CC0EF742506FC8E573F53
+:10EA10005D7D9E3533E077C086EADADFE21F11F0D4
+:10EA20003B627A3B32E4D804BD3FF3E53DBAFA419C
+:10EA3000074B74F532FE03E69B7D8CF1FCB2C1C33B
+:10EA40007E87FC927DDCA8FE3E33EDA3A9FE56A096
+:10EA5000FF93CD5AF7F10CB48F273309CF75D256F7
+:10EA60006582AE9EFCA78326672C9E3FAC2D04BE1C
+:10EA7000C37388074BC730DA8707FE0579CA769ECD
+:10EA8000F892F28D8AC599E4275D34EAF6D37203D1
+:10EA9000F6C59C23F5FB66D957D937FBFB8DCABE5B
+:10EAA000433B7F2CE29AFC31902711C7FD74F09410
+:10EAB0003D88B79D9F713BD5F4D983B1F8FC5D6C5F
+:10EAC0000AFD6CFFE641F2BBB6B7CA872B58EB6F65
+:10EAD0006DF3727BF1E6C1841DB8CEC88A16480F6B
+:10EAE000661D993B99F8F1A0817E9F33A5A02A1855
+:10EAF000F1B2EDD0C260FDFD298D7E204269F48324
+:10EB000088AC1CA1AF8FD2F06102278EB6FDFF0545
+:10EB10006B92E82C00800000000000001F8B0800B2
+:10EB200000000000000BED7D0B7814D5BDF8999D19
+:10EB30007D25BB81CD03DD401226E161541E9BF78C
+:10EB40002624611202460DB0101E414298243C5208
+:10EB5000AB3655ABD18FDE4C08841051A2B515AC45
+:10EB60008F958AEDEDE316AD045494E5E903840531
+:10EB70008346455D10D1DBD2BF28D0DA7EF4F37F27
+:10EB80007EBF7326D9193601FAB8ADBD37F9747254
+:10EB900066CE9C39E7F77E9D0321D790809DE0CF1C
+:10EBA000D722FC3FD3D02E2081F4F076A9A17D831B
+:10EBB000A1FF4C43FB2643FF3ADDF3ADA19983153A
+:10EBC00027FD1B7E265E78DDDC4C48E0AABE7E3940
+:10EBD000669FE8197361BFDC6E53DFB8F4BF1D1F79
+:10EBE0002C319D4B20A4AB5BF4DB52E9F5E812A27B
+:10EBF00066D371BA4D7E22E0D544E8F3AD3DAC6DED
+:10EC000023AA631C7DBEB9DBECE99008D9CEBF3BDB
+:10EC1000DAB770B02F869089E6D311BF2B9F37F5F6
+:10EC2000AD8FC07833079308FDB4EB4E3E6EA0D98C
+:10EC30008ED76DCD2E12B0F53D176372BA7D741E5E
+:10EC40005D219387DEA6F32F8D2774DDBB9C8B1D82
+:10EC5000302E9D2F214329163C49552D230991E83B
+:10EC6000BC4D741D9B4326D241D7997D847D3FDBEB
+:10EC700022C7BB22C09510931EFE178C477F004E03
+:10EC80004ED1DF41E1B2F38339F1E3E8F82F748B21
+:10EC900004E663551A1CBEB1B4DDC3E6A58D3BC9BD
+:10ECA0002EEAE050421C3A7C149D8ED3B5B38FD12E
+:10ECB00079D2F7ADD2F47880EFC5E64948B4818EB9
+:10ECC000E20CEDA1BAFEA3258AB7B1FDE3E1058E02
+:10ECD00087CD8007BAB017A23C55BE08F0DAFCA178
+:10ECE000B5C11F76FF3F3C142843E06AC26BF63182
+:10ECF000932740E173AEDBE401E0E5BB3AC5C6080B
+:10ED0000E3149CD0D3676E77B40E5E44AC1E900FB4
+:10ED10009A8EB6ACDA1DD6FF1E4F4CC24907FD23B2
+:10ED20008FE4E1FA2FF2FE1F9BD555BB2D948E295F
+:10ED3000C96EA2FD88AB9290C4FEFB13B29C325BFD
+:10ED40001F1C892B9E2EEE52F0D489EF5D80AF7E82
+:10ED5000DEEF1B4765F0A4E0857EABC6F97EE88157
+:10ED600071423344F8FE838EDBC4109DF7238EDBA3
+:10ED700076017DEEFF935502BEDEF1A7AE24B8BF4B
+:10ED80002F634B12D0FD3EFA4E10D667A658A36DE6
+:10ED9000ABBAC001F4F546F761E41F89046F1C9F0C
+:10EDA0000D6D93A783767B39BD723019006EAF71FC
+:10EDB0003AD9CBF97537E7D79DCD6ECEC7125E5FD6
+:10EDC000694EC7FBDB9A3DD87EB1D98BEDADCD3214
+:10EDD000B6BB9ACBF17AA8D987F70F365761FBCD2E
+:10EDE0006685D161FA1D65208FCE255100D0752D25
+:10EDF000774C3347C2E7F5929ECFAE73EBF96C3296
+:10EE00008573787B927D98812F47E89E4FFCEA1AA4
+:10EE1000DDF3A2D399BAF684CF0A74FDF343A5BA01
+:10EE2000765ECF0DBAFE33CB2A75CF7D85F3F5F331
+:10EE3000139D285FB6BB0494CBD3B2EB75CFB7C399
+:10EE40001F2087ED825F4D05B8540E284F03801FA9
+:10EE50001BC091F1F1AB1C3F7B003F36C00B83FF21
+:10EE6000CB007FDA7E09E04DAF3967955D83259051
+:10EE7000030DD8B6A60F767A28FC5F768A28FFB7EE
+:10EE80003437E27BFBCED59D1571BE0E09F0B29DE5
+:10EE9000CF679F45392B26405B90960B17CE2BA74B
+:10EEA00047CFEFA3CB17A2DCDCDE7DDC01F4F6CA92
+:10EEB0005797A6F7B47EAF92CA49401FC5DD545795
+:10EEC000A55E5CFF697AEB62E36BFD40AF46D2174B
+:10EED000C6716FF84A11095DC7CB3DEA0F62A01DEC
+:10EEE000F89628D1766E8F3209F0B63B5D708902B4
+:10EEF000F69B24C3BCCF1FBE11EEBF12329B60DE57
+:10EF0000FBCFC71158C776AA776DB4DF1B64C49ACC
+:10EF1000F114DE819E2FF7015FAA4E8B6714B97042
+:10EF20001E291922CA87CD636C26613CE83B330950
+:10EF30008C013E57109E5D5FA539E1BA395DE4F75B
+:10EF400083C8EF5767B8F0BD97CF672640DB448290
+:10EF5000280F02674DE5FE08EBBD1ABE436548CE9B
+:10EF6000F98F1C2EDA7FEFD93A07C897577AD8F86D
+:10EF700039CB420E80D3BEAF3638E1FEF6F42C1CFE
+:10EF800077C7D8A5685F6C3F6B42BADE3E669533A3
+:10EF9000331BD7E901D86D3F5BB72603E8BAC78CAE
+:10EFA0006D89282408F496CEF4ECE6B375E4307D40
+:10EFB0007ECE23FA81CE7248E7DE4170FF8A555635
+:10EFC00092C6E06FBE82905BD9CB64924B2F074A0A
+:10EFD0007BF4FAC41AAA9E3503EC08A067DA9E6A8D
+:10EFE0008ED73DDFF7EEF2849980170A6FB8F7CA23
+:10EFF000D9DBF78D05F9E367EDDF1F7DDA3A985E1F
+:10F000005BC6AE1A761BF4DBECF0D82478A2902F06
+:10F01000693BEFACD90FF6468E533F8F7D57572291
+:10F02000DC379F65F6D5B974B69EED9E7AF2007D09
+:10F03000EF656E7F4D3A36B202BEB79FDA4F60572A
+:10F04000BCE4F94D7C16C833AFA8A3370A1FA497B8
+:10F0500073DD04C7A13F83A6523814B22E940F7DEE
+:10F06000ADDFA1CFF7E5DB5CCB29AAB79FDFB9EB1A
+:10F0700076DACE4B14894857F22DBF7E7EF93F7366
+:10F08000E8DAB77EA6B74B6C44E0FADC8972A03FA1
+:10F09000FE9970DAAA7B6FAAD9A61B378F843D47E9
+:10F0A0007C5AFB9EA75EDC3ED9C2E59A669F6CB196
+:10F0B00028F37D40D7C15917D1A3CBB9FE6D447950
+:10F0C000B195104F470695EB578B32F0E1B9A37617
+:10F0D0008463DE23332610D4D7CA04E00724C63065
+:10F0E0007BC07BF422F68A4B2509B9FC5304AEE6BB
+:10F0F0009321DABF9DAAF9AF4187737D6E1CB73F9C
+:10F10000BDFFA06310CAFDC232A6171E711C403D90
+:10F11000DFF501D5F302FB4688E27D36FC017AFF7C
+:10F12000032BF67FE97A01E58866375412D94255F8
+:10F130001C99E63D6BBE9FE2CF67AF197B2BBDBE2E
+:10F14000F46ED730E0DF97C03E40F9D0E860F6417A
+:10F150008C1A4FA7B8ADC7867CB8E5B489D8C16F03
+:10F16000D866433AA57C7ADF58FA9D6D41662F74C4
+:10F170009DE6F6DE3607F2C98EDFB379742D733063
+:10F180003FE39455067B7CCBB21884F36829266054
+:10F1900086F19AD8F83D1CAF6F73BCEEE3FAEA75BE
+:10F1A000AEAF5E057B02F517B32776813D41AF3BDD
+:10F1B000B83DB11DF419BD3E7FFAB9F7812FCF6D6F
+:10F1C0008B42BB733449DF04F3DAE6B4E23C8D7062
+:10F1D0009EA7E8F9606E95DE6EA818A3B71B6E189F
+:10F1E000394CD72E4F1AA17B7F4AC2B5BAE765CEFC
+:10F1F0002CBD3C324FD0B5E5F37ABB61BAF7463D42
+:10F200003DC9617603CA3BBDDF383BDC6F4C053C32
+:10F21000313F674BCFED88C72D47D3062B6176C2B0
+:10F22000560EE72D4799FEDC1AFA32468960477C74
+:10F23000C6FBFD96E3E314C7C77FA7C82732860045
+:10F24000BF7CC9E46F3F74ACBDAFBDF799FFE3412C
+:10F25000E17A7DB828219368EDDF77BD3F1A9E5F84
+:10F260002A5F503A6D0F513CDF2DC67476D0575649
+:10F27000991B9F84B6AA9AC9C66C0447BA199F5FA6
+:10F28000E30179DC1AD3F85378BEB9C5E6DA900009
+:10F290007CF41FBF86761365051BBDFE312AC54F62
+:10F2A00028AB59334D38AF672CBE611ED09B826F9F
+:10F2B000FEADB4BFBADEEAD9285D381F67A6A0311B
+:10F2C000FB56D04322E7FB3F0B8A3393DE977F291F
+:10F2D000A09C8E9208EA051BF105807F48833C1FA5
+:10F2E000F8839828FFD0EBBD594A1CF42732915C73
+:10F2F000741C646DFA3D21B8F74F029D978534AABE
+:10F30000308EAD814A18CACF0F662889D8DF3C13EA
+:10F31000C77F7E2A2120CFE872B09D7D177175C40A
+:10F32000D2F911C5F4256DCFA7FE3E7CDFE4B80508
+:10F33000F5D4FBFF6DF28B11ECA55E38DF62391559
+:10F34000D2E82CED42FAE9E274B135D587F2D7F86C
+:10F350007E6626F307B77C344D04FACAB60F92C115
+:10F36000AEA00B146750F9BEF5F80D8EDA08EF4D1C
+:10F37000CEAECDCC1CD2D7CE0E6E126B9DE8CF8B0D
+:10F38000B0AECDF46F58D78BDDA600E0F79CD38AE2
+:10F39000F2A4BF75E487F471883CB007C2F88D9081
+:10F3A0006AD7C96B01DE9DC2D7D786D3977C5F38F9
+:10F3B0007D3D7F217D219CEF7E2B1DE1DA2A30FAF5
+:10F3C00052297DC173B5B411E94B35115F6B36D24B
+:10F3D0001BBEDF64B6BB6C54422ECD4C43BAE98AE7
+:10F3E000A9783F20E1F746CC447FAE86FB733528F1
+:10F3F000E75F3FC2E4BC715D3B8ECC1916027B62B5
+:10F40000D4DC61C0E75DA00086C2F473E7817DD9DA
+:10F41000DBA6E8423B70328190157D9E3D4F86FE13
+:10F42000D76BED1CD6BF84F55F92F9F07A159E2F4D
+:10F43000E0CF4925EBAFB5D5BC7925D0DF62C2F668
+:10F4400007BCFF431E7929D0E383197203E02F0321
+:10F450008C167AFD64BC7C33DC5F9A4970BD778D75
+:10F46000976F096FFF669C7C5B787B73AF9FDAC9EF
+:10F47000FDD45BD12E7DBD6726DAB312F1DD087AAB
+:10F48000E7F5208B476D1E39B01F7480DBF3FBB9A5
+:10F490009FFA06C8A3AB409F303F750FF7537771B3
+:10F4A000BDB283FBA9DBB95E7999FB492F713FE9B6
+:10F4B00005F053AF023BA48AC749989F9A3D6A5210
+:10F4C00019DA112ECD4F4D89E8A74EF7EAF5CD5444
+:10F4D0008F5EDFDC981E6FD02F7A7D332541AF6FB2
+:10F4E000CA9CD71AF44B96AEBF7C5EEFA7169F2D31
+:10F4F000D5F52F3CA5F7530B4ECCD4F55F9A2921B7
+:10F500001EBD476FD2F5CBEDAED3F5EBC39B0FF12C
+:10F5100064551F77821DB779643DC71BB31734BC90
+:10F52000755D046FAF72BCEDE178DBC5F1B683E3C6
+:10F530006D3BB7075EE6787B89DB032F70BC6DE11E
+:10F5400078DBCCE30B0738DEF673BCBDC1FDDDEC28
+:10F5500051BBD03F3B779A70BC3D2146C25B79924C
+:10F5600068C083C380073DDE4ACDC30C784833E0D2
+:10F57000E11A5DBBF054A6010F05BAB6F768A90100
+:10F58000FE3718EC864ADD730D6F533DF30DF455CD
+:10F59000AFEB77C9FCE66476DE5FCB6F7BB91DB756
+:10F5A0009BE36D27E00DE3441E1E8FF0F2B82FB3EE
+:10F5B000E35EE478DBCAE3425D8037B0EF38DE5AC1
+:10F5C000479E413BFEDC790D6F0722E2ED72F9EDBB
+:10F5D0003AB73E2E34D9A58F0B4DB2EBF9AD84E886
+:10F5E000EDBB895FE9F9ADE8B4DEBE9BF0999EDF23
+:10F5F000F24333756D6A0724640D013D7593EEBDCA
+:10F600009C609DAE1FF59398DFE2E17ADF5F89FA97
+:10F61000A86D2AD38F940FD1FE7EE67BD40EC8E866
+:10F6200083C7F306FFE9F97EF4F7E82C66D774BDCB
+:10F630005F8370CD01FD1DA15F06EF9791E5C2AB21
+:10F64000CD4CD4E84C9CE6EEA1743EE691CCEE3174
+:10F65000C7AC812003FC044DB97D7692E8F4111803
+:10F660009FDA4B195961F6A0D9D548C06E106D0FBD
+:10F6700055C3BA8868F2A0DE35D847A4C125DF0E8D
+:10F68000F76F1FE4E9A0B05892158BF370934D16F5
+:10F69000B033EECD920B605C711283C7E664EABBB7
+:10F6A00053786C8E626D95C26B236D8B83AB117E2C
+:10F6B0005D145E62068C9F40EEA2F3AACCB2323893
+:10F6C000CC235C9F6ED4EB43301868FB9968D69EC0
+:10F6D0009DF5CC3C35A94FFFD6FCA66BBD4AC7199A
+:10F6E000ED1C5A4FC6D171D7A97160678EA1F30383
+:10F6F000F968726C4B8E647FF76787A9E3E4594021
+:10F700001F7771FD3A9A42C49CD9FFFBCF44FBBEE0
+:10F710000DF8CD067884C5BDA66631FBAC12C6C90E
+:10F7200041FB520EB72F49B012DB6D198CBE7EB271
+:10F730006626D29B93C24B8C85F933F8CDBF93D10B
+:10F74000D7E5AE439BFF0074E20BB7A7C3E8E4AE76
+:10F750004874422A3C6EF4D7FBB3E75436DF566E4A
+:10F760003F6A76B22D49B39BFD1C0E24501087577B
+:10F770003299C235CE45305E53E332F9FD146451FF
+:10F78000B19902CA9D3281B852617499303C564891
+:10F79000E1F2C7181FF41E8D36C8F738831E1EAA63
+:10F7A0006B179F4D33F889D70CA8E7CB9C130CFA45
+:10F7B0006992AE7F79D28D063FB6D2E0E7EAF58452
+:10F7C0009998558E2F13C62D544132E7C27D82F889
+:10F7D000097B8E7E672F9C1F93AB905FB95F63E4BC
+:10F7E000D77BB32484B3E0627E8DC60FDAFB1AFCAC
+:10F7F000AC6E86D7B5B99A7EF2A0DEB105BE4520C3
+:10F80000AE4A6D68795318BD6D68B6BF5F368A9091
+:10F81000A79BC9FB651479FE66175E9F6876E3F5C2
+:10F82000B16609AF8F36A763BF75CD1E6CFFA8D92F
+:10F830008BD7879B65BCFF507339B63B9B7DD85EE9
+:10F84000D35C85D78E6605EF8F342BAA9DAE6B6493
+:10F850003BF1A87429A33AE9F7C2E036A29DCE2372
+:10F860000CEEA9AA4BD71EDEE4D6F54F6E9474CFEA
+:10F870008735A4EB9E272A1E5DFBCA2AAFAEFF1078
+:10F880009FAC6BC79797EBFAC7CA3E5D3BC653A5C3
+:10F89000EBEF485774CF7716170C0E0DC0C70F3516
+:10F8A00007820C2EC12083D36B41069F1EBC9E0293
+:10F8B000F94BF118670EA2BC88CB7651D2A1F8B2F1
+:10F8C000B3FC5ABCD923C4868D1F5F4EC74B0F9F14
+:10F8D0002F1D4FE79FF9915E623C41DD7D477A8F96
+:10F8E000EEBDC9A2B314F211870A458C7B1D2A8C88
+:10F8F0008F01FBE53E8B6B6A36A5C7834744CF0675
+:10F90000780F5E88202F8F71BDE8186747B9307D6A
+:10F9100085B04144A265EFD7758F8818F73CF87D14
+:10F920005205EB72EC7C4102BA985E581B1F15E63B
+:10F93000AF4D0FFCA9CC0DF75764E446D1D1A6B763
+:10F94000A75AEBC7F4AD4BEB57B7426F5FF6D1BD8B
+:10F95000DF0EEB18AD7EDF0EF2AD236903B63BD2AE
+:10F9600007CE93FC96DB619F713BEC248FC39CE038
+:10F9700076D871EEF784B81DF621B7C38E72FBF905
+:10F980003D6E87F570BFE76D6E3F7773FBF930B75B
+:10F99000C33AD29F9B82F2F097021123F8A9DAF5BD
+:10F9A000DB3FD3DB61DFF2EBEDB0A5EBF476D8E221
+:10F9B0004EBD1D56DFAEB7C36A55BD1DB6B0496F0B
+:10F9C000872D68D4CBC3F90D9374ED798A3ECE367A
+:10F9D000B74A6F3F6BF899EDD3CBC5CA72BDFDDC5A
+:10F9E000DF7A5F0A5C8FF91F40E2C7617AAF379F09
+:10F9F0000B7A85D245F679AA57300EEE6B85FCC995
+:10FA000056E842F56F9129F816E47DC8DB2281B8EB
+:10FA1000D3CE73B915D323D05FAEAAA79BEAA3FABE
+:10FA2000F8C64D77EAE13AE316BD5F622DD7C355BC
+:10FA30004ED2FB2595463DE3D3C355250A01BA3482
+:10FA4000EA1B93E31609E4F7E5EA1D2BA17A85B5D5
+:10FA5000757AC70A77D274CF51EFB467B3785D2E49
+:10FA60009D07180B2D5179FB3D146E3BDF35639DCF
+:10FA7000089DE0E19154FF14C3DF147E2F5B14B5A1
+:10FA800011F26C3C2F42C453BBBE43FB5B87B1BC3D
+:10FA900008F9CA7C02C657E82FE02B97D076989ECB
+:10FAA000CB09B2E761F3D53DFF31E06CC0F9C887FF
+:10FAB00047E6FE4FCE272601EC21329E8CC77A8383
+:10FAC00050DC25C5578DF7B303CC0ECA4E62769035
+:10FAD0003779A6C8F34F04421E5E13B1633C3385E9
+:10FAE000F837429C337ABF631A6DB6C29089E0271B
+:10FAF000E9F97F56C5C0F979A31F76BD34C2E0B7D6
+:10FB00005D6BF0EBF4FC6F2306FB254424B027115A
+:10FB10000726DD7384D3614E472DC7DAE6C3BA5E8C
+:10FB200048E6F9154E3F1338BE08D9B4AB963EF7F8
+:10FB3000BA4502FE868DA8F1E3A1BE28D82843DE8F
+:10FB400021CF6B7321DEC4651EB44B4F31FC78E9C5
+:10FB50002FE0CF4BC2F005F83BAAC79FCDF0FC24A5
+:10FB6000A7A70BE7C5E8E89F372F035D39E32EA968
+:10FB70008EC578BF24288B31747E7B5C02E651F7FA
+:10FB8000041B8325B47DC6CDEA865625CD34E37C9F
+:10FB9000893C6832C5C314BE5E2FCF6B753513B474
+:10FBA0003B9E6FB6E395904611E4519BFBF678D0EF
+:10FBB0008F5D29CA30A84FEB1A12BB02F2F39B2DBE
+:10FBC000B14991EA5A7658F2509F76ED48344BF499
+:10FBD000FD12B3CB0CEF9524D589E0EF5DD743D070
+:10FBE0002E28492298CF7ABE3970887D4FC13A1CA1
+:10FBF000BA8E49609F96B96A27C524407C96DA364A
+:10FC000012D8B9B1E8BFEE1E6243BCD95C4BCBBE83
+:10FC10004BD7772051248297E2C7433C01D0034958
+:10FC20004E8F1F86735B8E039C1BE8EFD7697D7A2E
+:10FC300081F2F9F1707CE491B036E615F4EDA1396A
+:10FC4000BC0E8AE347220AD659B4F5B0FA32128ABA
+:10FC50009C67F988DB0D5A7CFF28B71BDEE371B780
+:10FC600043DC6E6833C46FDEE276C36E6E37ECE55C
+:10FC700076C36BDC6E7883DB0DFBB9DDD0EB2F1028
+:10FC8000B505F28AF3883D04FEC2815A0667F70A79
+:10FC9000C15F0EF970A5D3574AEFDB5658507E0E60
+:10FCA0004F525B203E6EAB5227C33ADCD59D2D7080
+:10FCB0006D29EE4884FBF3949347C1CF067A999A55
+:10FCC000CBF99DE261AD95C179DDE218CF72A067F5
+:10FCD000654905F64B6270B3D35F8077E222550029
+:10FCE0003A702B161DBC6B0DF09D07ED30F9110D10
+:10FCF000F448E179BD06F72C92C5E0AE4601DCA3DD
+:10FD00006A39DCD31322F2C93A0E770D2E3B8A6F83
+:10FD100036A9B4EB5B49AC6EE2ADC29B4D07E8FC83
+:10FD2000BB6511F3AFDD49BC4E907FD738DE3BDCBD
+:10FD30009E5D5B3A70BCEE20EFD7DB6E27926D7054
+:10FD4000D838A5F75924FA7E55607532F0C5DA41E6
+:10FD50005A9ED883F6F564B1F0CD543ACF20AF83E4
+:10FD6000D4E4E51CC26163F8DE5B7C9DFDCDE7ADAC
+:10FD7000D21B2D121D7756E01E02DFB3991BDDE169
+:10FD8000F5A5DD7C7EAB66DC41802F8329A71BD0E7
+:10FD90008FF7D924B0BB87277956021DB89314CBAF
+:10FDA000F7E8FD69541E4A2E9856E78E04E847DFAF
+:10FDB000799400BD5CB309E8E1AD643BCA9DFEE601
+:10FDC00073811EF113B447FAD32354FEA03D64ABF4
+:10FDD000F8F428F8B595A4D113A0EF05B33D4380FE
+:10FDE0008F499505F5733AFD0DCFAB69D74A83FE70
+:10FDF00076782D03CAE1E1E79BDBC1EF780BF807CA
+:10FE0000F3A02406EA73821577D8013ED393D37604
+:10FE1000027E48893D348AC26155E1CA0500AF556A
+:10FE2000154B5D02D055D1087C1E2CB19F848A9C55
+:10FE30009E9255C95218BC57AD26C50AC03BF92E33
+:10FE4000F712BAAEB4A43F342B946F7A2CCCEF796E
+:10FE5000A7F47749A961FDC7E694FC2C07F8DACD31
+:10FE6000E87CB455498B541FACD1794B7134C665CD
+:10FE70008ED7B27A057A7F65137D55A1FAAAC3D3CE
+:10FE8000C7C78B393D458D3ADB00FD95D53609FD59
+:10FE900033B1BAAD89B6ABC05E02FBE9610BF2A526
+:10FEA000C6CFC98D7AB9A918F8B6CAC0D71A3FED1E
+:10FEB000BC908F6300AF51B58C9FB4F519D735EF67
+:10FEC0002B6AE7C41362F4EFDE5D34229AE9B130A5
+:10FED000FB763CCA26C94AD7378BD3D32C4E4F94D6
+:10FEE0002477C07C0EDE33622AE04B6DA17E00CC0D
+:10FEF0006D99A5CFFE4D837592415EBAFE594D6254
+:10FF000006F8A7E44E4B1F3DA6E9BE87F50273C273
+:10FF1000DB40AFAAFC0ED81110CE848FFEF1D8A121
+:10FF20003DADF47BDD43E3498B07C73BC1E4A384CC
+:10FF3000E31D2C140779E1F9BDA33220854FC2E9F6
+:10FF4000958E1F52D9F39A7B4664A2B9C9DB1F2D47
+:10FF50001B021564C45761E9EB0FFF2B3323FE67C7
+:10FF60002F133640FC6FB4F8C5E95DB4FFAC4A9B73
+:10FF7000A7958E3FFBC13A0BD8FD95AAB2A79EF676
+:10FF8000ABA474E177E13A747C72D84C2C30CE612A
+:10FF900059209DB43D6B969E6F6A96E9DB467BE4E3
+:10FFA000488C9262A2EF7F2AD8C8067ADDB17EE93A
+:10FFB0001330DE270FDAB0AE90C0B772410F101EBB
+:10FFC0009F949FB8873EAF5B6723901799C7EDFD5D
+:10FFD00041B9A938AEC9518DEFD776C4A05F7C7204
+:10FFE000FD95E300FFED718DB7413DF527B14A0D59
+:10FFF000E0B56ED5B526888FB447774E86FE9F9ABA
+:020000022000DC
+:10000000886B43066D4B0F59603E3DD43E8078AB04
+:1000100036CFDAF630FCC37773591C779A89289B60
+:1000200022D8350FE6F6D627A8B6B0F93F9C2BE1CB
+:10003000FD6969716D3F80EF50ECBB3C1C2EB0EE4A
+:10004000C92C2EDA9EE4A91942DB2704E25A9E004D
+:1000500057F943E04FF57E1BD988E827D8DF3A6C83
+:10006000E8531D61FEFF383EAF8F63D9F3E3EE68BE
+:100070003FACF3B8C4DAAADBE9477A362BE97362FE
+:10008000D87A842B6017049BDF9118C99A86F820D0
+:10009000D273745E750F3F82F8DD4CE103FCD9E347
+:1000A00092DA76D0799CA4CA5A85E7EE4727033CBA
+:1000B000EFC8A4849A78219CEECD8DC3F99C5CD7BF
+:1000C0001A8375262EA258AFE883476DE796BB8545
+:1000D00071A8E755263F18FF09244CBE53FC4ECBB0
+:1000E000FFA1A50ED61B453A012FA6DD2BEC30CF84
+:1000F00079B516CC8F3989AF1CE469EDC302B6E936
+:10010000CF1AD017759CBFDAA5B8BD40C7C7C11EAE
+:10011000477FEFB13D501F50CBE557D5223D9D2E77
+:10012000769B75FC32A349CF3F749DBAF6FA5C56B4
+:10013000D7D9E3FD2401F4733B5D36C0E5D336C166
+:10014000BF01E5AB2F25BCBE2E35D7A4C5E1254B9D
+:1001500018FCEB28FDD581DEB093CED24458F7A829
+:100160002940EFD623D1384F237CFFD5E1F071B27F
+:10017000543384CEE7634AC750FF737C7D2BDA2F5C
+:10018000F023EAF8DAD506F4BD84CEF25117D2A7EF
+:1001900075C6D83E7AD1E053BB2E752FF4737F1EFF
+:1001A0002351E789D4BA0B96823DD94B4706F8C054
+:1001B0009ACDDA7746F4D1193E8F406793685F6E27
+:1001C0001F23BFD496F5E6F55206AA5F467C1700BA
+:1001D0005EC7CF873C9426E7D616BF817470C645AC
+:1001E000FC22F36BDF06B91FC3E7A61239509F004C
+:1001F000CA84EA5D17DE437F399EAF37B64978AFD0
+:100200002C8B90B826F1BD327A33B62C18003D61A4
+:100210007373BDBB2DEFD7A3AF80DD0D04E3348333
+:10022000A22B3C015C8D2B11F729585C8960FF3CA7
+:1002300028085510B71F44F47655BC011E24DB7CFA
+:1002400022DC2E8FE6F27EE9E41102FA3BE57AFF2A
+:10025000D46CB08B7EDE4BD76CFD12FC49E1D846E6
+:10026000FD3790537181CE4EA0CF1A6AB7FA71FD57
+:100270001ECCEB58CB04F2A8D017BFFA67C52F2EBF
+:100280008883F1F8457F71302D1E50C96E517F472C
+:100290007143DEAFD24DFD9C416067DDEC46BFC9C6
+:1002A0007D12ED522BB74BA3462D72B1FC19E31F03
+:1002B0002D1E60A42B635CC9C87F46BBF4B7B9DCB4
+:1002C0007EBA865C7339F1012D8EBF2A9DF93DAB54
+:1002D000D2EB9643FDDA39EEF7B85413E271CE2C27
+:1002E00001F1A8D96B73BCA76701FF69F50717F384
+:1002F0007B3A0C7E48B4F729598EA03FAD792C2E5D
+:10030000E42864CFE7D889D91E963FB0E5313D3760
+:1003100087EA413B5DE234BE8F683AD1E7A7E2F855
+:1003200038DA95FE04337375F5827179EC3EE64355
+:100330006D3C1F6AE7F582251967777D0DF76556D5
+:10034000076C936B1FFF1E8543F4AC188F09E957A8
+:10035000D9F843F093673950DE26A44B58F75A95E5
+:1003600064F720EDABF2DBE097A19D29C194659481
+:10037000B77329FF065C03F83BF681E3664ECDDFD9
+:10038000296474D51B5FF231F96DA2BF404FB3AB46
+:10039000F4F4325719987E32F3787C89EFE31A1D12
+:1003A0003ABFE36BA40BC6BF6B53583EFA5C05ED36
+:1003B00003F9DB7EEC71CDBF755AA85F44F112944E
+:1003C0007721BD07D389251CDFBE425157DF10CCF2
+:1003D00027D12EEAF7042D24F941DA6F903CF70675
+:1003E00017F8BE25B6985AD41B7E9D7D7F908E7BD4
+:1003F000CCD9FF3C8C74BE7AD4128CFF3F703D0583
+:10040000199DFF6A483863FDDE73F3C16F7B00DA24
+:10041000585FF08BF9506FF74094D6EEFAB11C5646
+:100420006F70E796977FAC1652BFC64EF52D1DCF65
+:100430002111CC5311B209E5B308F14090CF63C24A
+:10044000E08B7E831EDE463B5E2C647114D1C0F7C8
+:10045000C6EFDE9CA7DF6FD7DFBA8DEFD19FAA6B07
+:10046000F4F47F7BDE00F5B2C6F79D503F1173F9BF
+:1004700075075490627E5A24260FF8CBA494E0F7B7
+:100480000417A32B9030A0072D8D833C0837DA8EFC
+:1004900002BDE0776871559C7414E05F847C620053
+:1004A000F5399D4A481801FDB5FA03857CEDB8740D
+:1004B000B947E5318E2395B3FCF2BB3209C1F7464B
+:1004C0003FBACE970BFEFA11AA6725D0E337AB10DF
+:1004D0002F3BBB8C607EC0E152B04D3F156A754129
+:1004E000DC8AB56B288C402FDBDCFAFAD71DC58F70
+:1004F0009658E9F3B632166F3DD81C787705A5B546
+:10050000B6C20294972BA063D87C833BA3AC108720
+:1005100051D4EFDAC16EFE689968856B7079AD0AC7
+:100520008B7E3751DD244810775008F8F9D665AD39
+:100530009381AFDEB5A89E3827E655314FDCBE5C0F
+:10054000BD15FC1E59AA284FA57CB4A1DD8CFB8CDF
+:100550008E95FE2E490AE3C3535C9E1ED811F5000A
+:10056000C06195600F45C1D5A26C589D00DFB37A7C
+:100570005AE814DF6DF941327C67D5E2559E9DF053
+:10058000BCC5063B50C9AAF5F62A187755F212F7F2
+:1005900092B071EDC3AC8D703F38B40DEB5A9472CC
+:1005A0008F352A16D6F5450CE467DB9765C5032D14
+:1005B000B6255A53EAA1DF923FBE990778974C9827
+:1005C000B7B5BA3B2DB0EEE16E4585FCF85F72948D
+:1005D00057F3E83CE7351D9B8C757365B12BE13A09
+:1005E000FCFC77DA01FEEFF2784C28B10EF3B56D22
+:1005F0008BEAED30DFE98969CBC3E3316D858BEDA3
+:10060000A3E97B696E53EDD24117D2471BC45FC685
+:10061000C3BCE87AC642BF3F342BB45F28D95A1511
+:10062000699FD6F13CE6EFD95B97A6415CA46DBD0E
+:100630001DD233A44D50D6417E404D7546AC631F4C
+:10064000EB65EFD528AEC95609F183FC762AAFE7F2
+:10065000C7EA48B02B19FEEC6662B784E9BFB1392E
+:10066000259FE685F9D1177C37B10DF5419BC0F880
+:1006700077ECD6CF7F0CF5C2BFCAF17D0EEFAD6A25
+:1006800057D601BC886A27838AFBE793D06A9242D7
+:10069000A83C6E6BB15545AA430B2D12A7019F5084
+:1006A0000E3A3628254C2E2FAF4F83F848A8E52A5E
+:1006B000E4EEDEFEEBED1F021E42EBD363411F862C
+:1006C00092EBD2D2806E395D1AC7DF94C7ECC95F56
+:1006D00067F92C5EB02BC7B0BC67459ECFE645BD21
+:1006E000DDE9063BF71B40B72930DF7F22DDA29E04
+:1006F0003B9E770AE98AB82E2D1FE9232133E65362
+:100700008BFF8CF1DE8EB1DAFE27161FD4ECDEA84B
+:1007100051275680DFEACBD7F25D857BC05F9FA66D
+:10072000E5532B587CD0457F23C5077D86F8E03400
+:10073000435BB337A778B97DC2EDDB24A9D3570A51
+:100740007277BFE8017F229930BD32A342F0839DCA
+:10075000DD521C6DC779E7F33827F7BFE6F179BFA3
+:10076000D76C27904F32390A57C2FCA715B0F93B16
+:100770001A32720212C87716E7260D3609E3268070
+:10078000FC44D2EBA7F96010BA9E790D4BD1DEEF95
+:10079000835F0B8BF310BD3FE12306FF6111B3C7ED
+:1007A000347F6BBEC13E30DAFBC638755F5E609346
+:1007B0001DE8E9EC98CC8369123E56035A3E80F658
+:1007C0005BE8ED5E190A933FDD5C3F1C6E96DF5BD4
+:1007D00041D7BFD2F7133BD06987D96F077DD2517C
+:1007E0007E470CD05F47B5580E7C1F6C2EC77E0726
+:1007F0009A7D786DF6327DB12F47BEDB1B1677AE42
+:100800002C2F796F4578DD837CFD7B2BC2E63FDDA5
+:100810003B43D7D6E86CBA481A3745902FBFF2321F
+:10082000FE3753BD8F7586E22F3D03D5DF507FF530
+:100830006C38FCD678F5F6EC7D634A070F64B76830
+:10084000EBD3E0A2AD5B7BDEDF3CEFFA1BE7F9D434
+:1008500065CED3383F6DDEFDF59F0EC28AF2FF5D97
+:100860005B4BAAA12E765F8EF22CC8A3CA326125FB
+:10087000E44B0FF378E2E1C218DCE7BE279DF97B79
+:10088000D10D8C6FA2CB6660DEEF72F17B9397D9AE
+:1008900095B30A05BF4CFF9CC2F7DBBF97CEF2B9F8
+:1008A0002DC53F7F13F2D0EF145958BC97C8D3A67B
+:1008B00086E5B1D65AFD01C827BDD75BA771CBCA63
+:1008C000BB683B5A932B55FABCC3AC59FAFCE17494
+:1008D000439E21DA2057821ADC7329DC47F4C1BD1C
+:1008E0003F7FA23FFA20E6D3D9A0878CF0B9CD0094
+:1008F0001FA3FF327D9B811F2ED18FD9D09EBD07B4
+:10090000F26A2AB5274701FEE0117D2F5A7E16D3E1
+:100910002051F98C1E47874EAD01BDD84D5500E8DA
+:1009200097B533EF5807ED7354EF035EFAFB8EE68D
+:10093000BFFD2A473EE38D503FD02B47C03E180FE6
+:1009400079C1C8F641F7A2495323DA0733EBD372D2
+:10095000605E33F4F641F7FAF2C7B3E03ED807F42D
+:10096000A73BBF5E671F90F2AC8BC087C9DDA85163
+:10097000D911EBF47C398A2B3F6C3D8EF446125E24
+:10098000CFF879AE1C9B4FDF9FC1E308DAF7A8FDD3
+:10099000B5DB12A17E51FB5EA697C53D49793CD3DC
+:1009A0000FFC7A313C6A75D4F759643CEF458B7B78
+:1009B00069FD3CF94CCEB6A7C90DF09C38332F32F7
+:1009C0006E8B16E748CFB882D70D4BA4D71FFAB36A
+:1009D00020E1F308FE1E81BC6474D2E9DD2EDAE565
+:1009E00013AF920370283AED57211F62AB10D05E0F
+:1009F000B22511B46B2ED5BFBAD47EED501C00FECB
+:100A0000561D8B97976498B11DAD881B402E4C3CAA
+:100A10003F5800B9E153C4A760BED1F2179FFD044F
+:100A2000F435D5FB1087F19146DC67EDB4F8303E24
+:100A3000D1514147CE8038CC724B1AC6D3539F8DCB
+:100A400071C3D7FCED102FB779D87EA82AAFBA12A0
+:100A5000CECD985E344A20F4F9341F8BDFCC81F878
+:100A60000D8C3BEBF40E88FFCCF632F9057E1BE8CB
+:100A7000CDB9F5778FFD91F4D7C46DFCEDF1D918A0
+:100A80004F92305E60880FD90AA7607C48AB53F163
+:100A9000158AB8BF9B2439F11C0A637CC718CF3173
+:100AA000C67B8CF19DEFE6B37D1A9A3DD598AF8F4A
+:100AB00017DE0D7B1072C05EA2A292F275878524AC
+:100AC0007752FA3C58F229B993CEC3F94313D48034
+:100AD000D37E7A3BEC52E55690CA958F6121BB5E7E
+:100AE000B7807F5B2DD7627CCF48F70FE5B378DD09
+:100AF0008A7CA72E1F1C6C6EE2EF47A980E7EA9163
+:100B0000567F546ADF3897CA1F8FE6CA0FE433BF97
+:100B1000A213E89C7814DC4F5091E7D2D12D691CC8
+:100B2000423E0E8BDF18BFABCD471BFF72E7713F14
+:100B300087F7A5F2C9DAE202BB957EFF0CC5B18842
+:100B4000FA921AD461F1692D7EAEBD570379832CD8
+:100B5000B02305CC1F68F7C3E2D866A0DBE82445C4
+:100B60008E74DED4A1FCDE3C15E631B5EF104141B8
+:100B7000B950CFF335DA7866E26E413E00DAD6E658
+:100B80002546889B138FDD4649A66E8D4820FEE3DF
+:100B9000247227C49FADED166C13B56A2FD8E98B6C
+:100BA000385F580BA7EC85B89AC617C6BC8D554C54
+:100BB0009A02C3D677EAF357C6FC94D19ED6E2EBED
+:100BC00066FA1198D7FFD3F04115B57869EB7D0A25
+:100BD000D7F30D5DAF46571559DF7643FD495B945A
+:100BE000B2AE96CE4B7DDC8EF10A07CC0D6012A022
+:100BF000BF20271FF7FE04E4EF5FF2D9F9376D023B
+:100C0000AB47D99DF88784F0FD0B7FE1FCFB74BEF8
+:100C1000C4E222661280FD52644C02F285567F7255
+:100C20003091D981D38B1607EEA0ED5FF07AC96BB6
+:100C30008B366AF9FE4125B9044B3F002E6BADACF3
+:100C40002EEDE0D566AC2723E2FE9D7724F4D5EDAA
+:100C50005EBB49EF57DE98AEB7078DF69FD5D08EB5
+:100C60002BE072ADB7FE44B1631D5922AF23E3F30D
+:100C700037F2C9CF9A595EE3E7BCEEFF977CFFE5F8
+:100C80007FF1FABD4D7CFFE5737CDFAC06F7FB2CF2
+:100C90000AC6A38F5D4F6DBAD8BE38E0DAE27BDDBD
+:100CA000C0C7E30B587C68B2E8DC097AAA6F9FC51D
+:100CB000C0E7845596EBF366B37DFABCD9DC2A7D98
+:100CC000DEEC0F59B2A76008ECC368580EE714CCED
+:100CD000582162BE726DDB19D4B3E70AD1DABE5077
+:100CE0003EF07D18DA3E0EED7E69013BB7C8B133A8
+:100CF000D102F5F83356C44E81F83971655E92FD24
+:100D00007603C4DC613ECB5D16380F62462011E3EA
+:100D1000A1B5ED9737CEEA5157609CBA37CE4FAEAA
+:100D20005900EF1FD2E2FC6AFA0288F31FE271FE5B
+:100D3000EA826B1F07FFE8E97C7926C06359BE5C35
+:100D4000599003F7995CA0EDD9E16DFAF35AACFE26
+:100D5000FC896A78AFBF78BA3849688C542FB2B82A
+:100D6000A037CE5507EF137B6F9C6B116B77E23E7C
+:100D7000BB26FEDDD6F748038CD3FA2269782E8293
+:100D8000DDFD9D02411BEF16982F716BFACD775B4D
+:100D9000A4F1445B6C0AF8FDC7787D9971BCA6028A
+:100DA000B61F938E7717BE9FD43BBF261C9F8FD74D
+:100DB000B77FC615034CEBA8514C3D949E489B88C9
+:100DC00075278E2ED754A84B225346601DCBA1B257
+:100DD000CA7F89FD3487CA7EF36FB99FE63705A9BC
+:100DE000480717DB4FE398499448718D97385DEEBB
+:100DF0002CCC1A1C1A004FD6A67D41B0337ADB6684
+:100E00008540DECFDA7400EFDF17E5AA89685F70EE
+:100E10003A6D2B5BE48394D0AAE42962B8FDF2BB5F
+:100E20006C654F4184FD8967469EDD05AA69669918
+:100E3000601612D0DEF608547E662F9B21BA25423A
+:100E4000BC8D0F4EBA923E9F9544FDBBB0751734D2
+:100E50003CBB8BB22B292C3BD49A40FBBD98AB1CDE
+:100E600082F18BDDD26E68CFF26560DDFB7DB1046F
+:100E7000EDBC63A3ACFE0DA917CEFB049F3795CB49
+:100E8000CBCD972197DB9AF5F9EF55C9A397C3FC12
+:100E90004797921048D834F7E912C8FF8DCD514ECC
+:100EA000005FA5B9896C1B87F7651296BF318E1B51
+:100EB0003581E9DBD1A1A4FB219E7C50F3F78B2F78
+:100EC000DBDFFF221CDEC6EB31CDDF5F19D9DF3F50
+:100ED000B6283E723EA0ADBE0EF201C756EAFDFD39
+:100EE00063EBDD35B0CFEF18F7F78F4DA6FEFE9818
+:100EF000FEF301DA3AA91CB24D00B9D39B0FE0769C
+:100F00003B8F6BFB72E468784EFD79075CEFCD9206
+:100F10009D13E0B9EA5A80FB9149E47DB2E4319730
+:100F20000C7E8EB6AF3DD3AB0C81F7B5FDB2A341BD
+:100F3000B4C5415ED4755B247A9626307EF9EBF316
+:100F4000A4BD794C13EEA3BEC438FDA5F693BC9B9B
+:100F5000583D8E99D519462596BA213F756E8C1D40
+:100F6000F57B3BFC2F4CAFA61428B91386848F6306
+:100F7000385F55BAB4EF6A75FAA0AF40BF74135228
+:100F80000EF2E681D8468C7B9471BC1AAFD74D70B7
+:100F9000713DEB4A0078A614F8A620DE9FDF24E11D
+:100FA00039B0FC7E7FF5FDC6793C63F57D80FBEBB7
+:100FB0004B4589D5E511E48BABD25DA8A735FBABDA
+:100FC0006E422A3B578184465AE93A5BE55DCE2C56
+:100FD000DAEFA3C7CC19F0DA4F638805E6ED4BA72B
+:100FE000728EAEA3D4AD0C1F483EC28944262F5C3E
+:100FF0000382C98DD778765505B87F013F3E767656
+:1010000008D8E33F7D9CE5A7AE7A7C91BD2E6CFCB1
+:10101000472670B999C4E65F230B7E2915E6731A3B
+:10102000F350332493472690373E77642EC409A9A2
+:10103000FD360ADB67B01D944C5990D7FEC8FDE51C
+:1010400011E87FD5F7175F81F4CFE1B17059D6333E
+:1010500068E7E728DF03FC070BCFC48C188376FC16
+:101060003AA0FF8502F145B213EEE778BB416EBCB2
+:1010700009E8EC06D94660DF5AB0C48670FF699172
+:101080002081DF3A1D681EE2398F9931DE4CE17113
+:101090000B3CDFEF71E0B9D1A5F2B36668FF61AC3C
+:1010A00040AE1C401F5F365C0BCF0C017EFC08E895
+:1010B0002FC2FCEB38FF6AFC44E15E8AF39259BD13
+:1010C000487F74F579BEBC0EE8B23D4D69C073111E
+:1010D0005D332FE95CC4E93FF363ED9EEDE9C6A102
+:1010E0002442FDD741CE27C6FBFF3981F9054B3895
+:1010F0007F5CF5F8D9FDD7035F2FB3B800AF4FE79A
+:10110000FB7E0178EBF5BBFECE7264B2588DF80B16
+:1011100056D0B9E3390E2406DAD3469A117F6A29EC
+:101120003FE7E32EE26A8DC5B7B06D5F26209F3999
+:101130009C9D5560349BF31B8FCC86F74A44DCD7CB
+:101140001FB6CF65C03AB210DF7FD606FBCFA82D01
+:101150001F5C216AE76E1181CAB6609999DBF79F1F
+:101160003E2ED33F9FE1F5991F14894F407DE61134
+:10117000136B1F2A125396D3EF8452D83C3A1E1495
+:101180003C2D125C9F5A07F9CBFA26C1534EDB3532
+:10119000817B7A20C4B5E4611B0157E1931F2E9D2A
+:1011A00002EB39E32678BEECDC44C6374A90F84DB2
+:1011B000A97DFEED87C9C4AFE54B611F9D97EB99F3
+:1011C00087601F1B9DF775EA77D5BB216F4AFD5ECF
+:1011D00088ABC579583E333A68F6F809F8BBAC3E9F
+:1011E000B2ED7E813C04E3886B5AC13FB7F17ADDF2
+:1011F00068B916FDC7384A9F1268D09059B78FADAD
+:101200009E2848BFF1E5943332E0AAF78FB32FB29E
+:101210009F6DEE8221B1C02FE726E8F765F4175FD6
+:10122000D7AE70DE0DE0A78BE757B752BB1DD6FBDC
+:1012300022B5DBE1BA8DDAED701FCEA9862BEC6703
+:1012400083EB4E6AB7C315F6B3C115F6B3C115F6F5
+:10125000B3C17BB09F0DAEB09F0DF71F16A981C122
+:10126000009F926802F9A1360BA33335D98AFE4656
+:10127000A08860FE3E986CDDB01CE27502C3931A34
+:10128000CB9E0763949BB19D3A86E577CD9E14D89B
+:1012900047B842182381FDD46E55B07EF9D8723319
+:1012A00081FAE5D054E103C8BB10C1E411A97DB3B4
+:1012B000FDEBDB10FE8B656282BAF4E5706E28C828
+:1012C000E3CFC806169F0B8A70BE5C6B0CE1756499
+:1012D00037F9654A7F2705ADBD57017F7422C404E5
+:1012E000907E7729F07C7193C0DBAFFAE59150D7FF
+:1012F000A03D7FF349882FAE30B4BB4DBCAD0E7F0F
+:1013000012C63BA27D4F1D5603E31D49D39E272ED7
+:1013100084F6C751DAFB9F2F84F783BDF33989E345
+:101320008592B5FE520DB67BFDE7050AB687B0FE85
+:10133000EB77EE7B0AFCE5BFF778AD8A8A717C75A6
+:1013400016211B6323F0FF44511F0F95055D3C548C
+:101350008BBF9B1CD557E2FEB3076C28173F4E2668
+:10136000E887F417170D8BD7635CF4E713FB897FCD
+:101370001285C0B855100FF4E05795F0FD69446828
+:101380002450A7EE3B1523811D694D0A8BDF71198F
+:101390003050BCB0B591C507838A85A8A97D75FD7D
+:1013A000D6425ED7CFE3855A1D83B5F047BABC81DC
+:1013B000315E48C45B301FED5BA48F074E572E2F64
+:1013C0005E584D02962B81FE65C103FE7BB54BF93D
+:1013D000F00AB4F7AF61E7334AAF61DC54DB37069C
+:1013E00077E0DCA92ABEE68E5B8F7D7005EDE75FB6
+:1013F0001E25C166FCF9B794E0FBF9748510DFAADD
+:101400002E4A4378E77CE6794D0279EA3679989955
+:10141000E6FB7E22D80B8B62316FB2E0CE8C0F617F
+:101420009CC5AA03DFA37625A7F7AE27809E4408B4
+:101430005C86B5B35334FA9BFD04D0FFC478AD1D70
+:10144000FDA45C484889557B3F07DBF314CE7F6AD7
+:10145000FA93C07F474A357A7DA3069ECF1ED13BC3
+:101460001ED2F74487D6BE71213C6FEF1DAF1EBF61
+:10147000F70E9C6C84ED494F823E2A99A1E9ABE3BB
+:101480004FC0F86DD5DAFBA3FD108F9A6FD2F887A5
+:10149000F8819F15D2DB96412FBECFF9FFC8B64D1C
+:1014A0003550D77593F65CDD84EBADE6ED77B62964
+:1014B0004F023FFDDBAFEF7FF87BC6F602129C7C4C
+:1014C00065761F5F18E5D56BC54C8E781B9E05723F
+:1014D00025D58D4FE1F96E100F60F9ACC4593E90DF
+:1014E0001776D1433983F8DC2E8C731AC7595CC444
+:1014F000ECEB4F0BF579B136435ECCC7F353FD8D62
+:10150000F3269F4F7B69643F766C4EE99785503F89
+:10151000404E8B309E8B020CCE276BC952BE82FB95
+:101520009475F1DC4D2AB23C709FFAC52AD899D344
+:101530002838210FDB52FC28C6E943F916DD792053
+:101540005A9E73AD5546F9F809AFEB985F2A4FBE26
+:1015500087B66B878A6403D6793831DF601E667D73
+:101560000AE53ACF7B6AE7714CBBC8BE08E3BE947C
+:10157000CFF97ACF147658403EAB449D5C968DF2FD
+:101580003A08F5C626C71ACC03DB8A2D9847D0F255
+:10159000CF0A3FFF5BCBFB4E3C3F98E9F7742DAE83
+:1015A0003B70FE5769DAE143FBA0532426E1C27C7D
+:1015B000F0629F9A0CF52CD3CA6270BF4055DDEBE8
+:1015C00038FEA11482E70447CF6AC4FD41666A1F52
+:1015D000CA00179E2FD6EA63869FFF0EEE1BADD77B
+:1015E000EACDC58A0360A7DA1EA17E1674E0F96011
+:1015F0002D5F3CC320EF171756A29E25D48E1F15D2
+:101600000BDF1978DFF3031359FEF84427ABE7F734
+:1016100016E9F3C0F759589CAF3D4D4F571B273281
+:101620007FF5075C9FEE2CFE7915DACFC4E481BC10
+:1016300018798C9D0B073116DC6F653C8F397D0E58
+:10164000DA758F0DA74BA4B6B6B9E97D8C2B0AEBE2
+:10165000D87B9F8D238DE0B798CDAC4D2F2AE4FF2A
+:1016600033BDCAD422A8B368FA10FBB7AAACDEBB5C
+:10167000BFF8CDBC226D9F088BDFCC77EFED817D6D
+:10168000657F731CC7B0EFD527B1FA929585929606
+:1016900047C0730929E15AC05E4C29F0D5C3BCC9C3
+:1016A000984D12CC4393373B5EF9760DC81B224709
+:1016B000CE4B6B7CDF66C84BFBDCECFD378BEFAEB3
+:1016C00081F30DFACB433C5C2268F1B53B8A605E46
+:1016D000095ADE40BE13DABD7A1416E4D5E9D18585
+:1016E0000DFF0BF4689FDDFE760D8CF74D9B3FA53B
+:1016F000ABFF42BC96B3F8D9376DFE1326C87B60AA
+:10170000FEFFE8EF8C99E07B0BBEB35A90AB9C2CAC
+:10171000B9E711F479BE778B06C8F35D2CFEF07F34
+:10172000F18681E30D62F1BF66BCC10A7BA87290AD
+:101730008FAE2C06F95CC8F8E8DF5DEED1F5E6C0A7
+:101740007A570B9BFCD123FEFEFE7E4A8132A918FC
+:10175000F5A062DA49E96775899DD9330106DFDEB4
+:101760007806CCDFAB8B673CD9F00F8867D0F55695
+:10177000227ECBF8F7BFF9F8BB15E12B337BE2DF14
+:10178000903E57E3FA36B1F5FD13BEBF1EE9E5976B
+:101790008C5E7AE1C3EDA430F82C6CF8E7C0E75713
+:1017A000089FAD6C7EDF007CEE42787AD87C2FE615
+:1017B0005F1F2D1434B9FC06BE97CDE8E043B0AFEF
+:1017C00099DF3DE94AA9CFEF7E34573E50CCEA631A
+:1017D00082C5BAFA4FF910B407F08B8FC0F3087EB8
+:1017E000F1FBC5DF40BFD859C4E0D69777F1B3739A
+:1017F0006F49D50D57D3EF7C48E10DF1B68E261118
+:10180000ED8B734904CF03D0EC8D502CABDFBB7054
+:101810003F581981FD88B67C76CE88763E8059ACDB
+:101820001E1C902E84EB81418A15EABC96C8196D66
+:10183000B0BF75D29A2F70DF9555B6E1BFAB39DCDA
+:10184000EDB1DC097E34F573AF83786A830BF7D191
+:1018500069FBCAB4FD1F4B02F3F6C23EDB0E4A0F12
+:1018600089F43BD3CB2CC7C3D76FB437CC86B6F142
+:10187000DF354D98A8AF07A4F047FBE7DC3A561FC9
+:10188000D761263BA1FEA35E15FD2DB4BD718D80F1
+:10189000E7712EA270027F7F52672AD6935B93D89E
+:1018A0007967DABF7B4AE9A0331FECBF2322C17FEF
+:1018B000C78EEF27D3CEF98E9A7A1ACFDBFA98AE7D
+:1018C0001FCEEFD1CE9998C1E9448367544B3CC2F7
+:1018D000E51C850B01B8F0FD36D39A583EB8AD7AB9
+:1018E0007110C8BBA6F08B1591EA52E6B8F5E7A5D2
+:1018F0001BE319C6F3C6CDC43718F6D54D2F2C51AE
+:10190000C15EB5F17ACD6822E3B9161FAFF9093B84
+:10191000D7A2CCA23B47C4F8DD68039DDA0C71075F
+:10192000239D1AF1729D012F1BCDEC9CC1B66ED187
+:10193000A3D2DB6D0F2F6A877DF9EAC32656374F96
+:10194000643CF7A98D5ABCB8FF9C4E16E2F573397A
+:101950003C35BC10D268017EABD6F6A19B1A57C2AB
+:101960007ED2797C1FFA4D6413EE3358001604FDC5
+:10197000EE4208918B70AE8C6465CE818BC03CEAE0
+:10198000ABD83919265803E4091E3621BFB6B977FA
+:10199000E2BFFB15186A893D99CEFC8948F66C6F49
+:1019A0005C8142E264581CFFFFE2577F5BFC2AB770
+:1019B000889D47D5161570E5A7B2F326A09E29B7D6
+:1019C00048423918B42829B8DF61FDA72AD081B66A
+:1019D000DF81FE2CBB427F6EC2FA8903F87F45454A
+:1019E00004C76B4B0D25835CFBB09FBACAEDE03892
+:1019F000303DB46122E6DFA9FD9B0D728FD9BF1582
+:101A000079BEA7F13EDFE7ACC5913EF12AFF39313F
+:101A100007F6E71094C3B60AC10FFB77A63B853DD6
+:101A200082D4F77D62AC63FF5F9AB7BA93FB6DC156
+:101A30002882E720055349D57311F0F1835216A788
+:101A40000C6644C697F69CDA19EF4CCC61FED020A8
+:101A50004614A7ACFAF8C00703D18786C7F8C9F2C5
+:101A6000471373FADA0FE4299F40BB55F17D0078E4
+:101A70003DA98A12E8151250F03CBF69FF21BA0057
+:101A80008EFFE83CDCCAC2D44BCAC355039D0D503F
+:101A90002F78B9D7FF0FF9613D6B0080000000007F
+:101AA0001F8B080000000000000BED7D0D7854D561
+:101AB00099F0B973EFFC24998409041C24C00D0229
+:101AC000461BDC81802440E0CE4C12124860F83581
+:101AD00002E285008D5DB451791458BAB921102005
+:101AE000A260BFB4B5EAA34310DCDDFAD4D475AD6F
+:101AF00088AE23A2A55DD4A8A1C6556910E4B3ADF4
+:101B0000ED870A6BEBA7F57BDFF79C3B73EF64C2B5
+:101B10009FB14B9FFDC2A337E79EBFF7BCE7FD3FD8
+:101B2000EFB939EA648C4D82FF8CC2655A01632D8E
+:101B300058BE9CE18FC6A0BCB8BFA59C0B4D3B799D
+:101B4000FBD1DAFF891A2319D399E82FDABF23F1E1
+:101B5000F6478303A28697B145A21ECA3A96CDFEE8
+:101B60008C29794105FAD749667997A658E7CBDAE7
+:101B7000A5C17C279CF6F19788F18AB42F69FC48AF
+:101B80007CFE2FA31A948F27C17F03E3E552EDCF8C
+:101B9000D47E65BCFD9F755CEF49C92C8FD2B1FF27
+:101BA0001197D9FF8A6538FF3D79BC7E6A6854D4A5
+:101BB000B804E1F9A6C7BFD0F647A7A88C0D047CEE
+:101BC000D4FD2C7C19FCBAA47E97AC43BFA3CEC82D
+:101BD0007B2C07C8EC5E49DD037D8A58BBCC6402D0
+:101BE000DB258F87213489B5C05C2B42F0BF09808B
+:101BF00047AF83CF6304A21AD0D9E2A9269DD64469
+:101C000071DEDEE8EE9DE0771FC27527E0FEEE5242
+:101C10001BDCC6A865DA9404DCE110B487F116DF9A
+:101C200072931FE15C3CC25CDF249AA739DBECD7DE
+:101C30007DD6795F7BA194F0BD383E4F25B55F9C82
+:101C40006E8E37278AF326E05A48FB91806BA80DE9
+:101C50009F81D042C267C417DD3C08F013F1B38006
+:101C600001F85C54D728EB05163E32C22AF1913FA9
+:101C70005E8EDAF9A880F8A8AFE11A3629B24D8352
+:101C80007D62F9ED6A64CC37B1EE98F3325CB7212E
+:101C9000D1BA4D3A5AE2B3D0BB07D6AD9AE52B97ED
+:101CA000D579FB62DE8E329AF723C0374BF01333BF
+:101CB000062FD3BC173E5E9377B90BE15EA5495A58
+:101CC00014DA7F853FD312CFA35324E217C0E7BFB6
+:101CD000123E8B009F99F89E111F3C5E18F9B906C1
+:101CE000F54CD51D07002E97E6612D8083AA8991BA
+:101CF0007DD49EEDF423FE01001AA7F975A6209F5E
+:101D0000016F051C93A1EC6435ED29E6FD61C84126
+:101D1000ED9B18AB6807F8C66FF4AD8A7813F5BE73
+:101D2000320E5796781EC9ECBE6120CCDF0D551BD4
+:101D300061FC260398179E1FD4495109D6FC416EB9
+:101D4000645631943BF21C818D307DC73AF7D03513
+:101D5000D0BE2BCF1B40E8BAB27766FA60FC0F0208
+:101D6000B2C0D74DEF235F1FC98CF39381FAA5430F
+:101D7000E0F7D75A711BF2D3DB2A2F3F50FAF7EF67
+:101D80001B05486FCCC706011EB007F0AA23638A63
+:101D9000C70DF3BACA419C605F1FD35D50EFC67A8E
+:101DA00058E29C1FECFEC13C95E4C6CB23AF65AC6A
+:101DB00006DFABD85F31BA3D34AFF295444FE6BC95
+:101DC0003631AEABB5E9A526809FF9651642DEF245
+:101DD000F3F67ED6DDF89503C787723E43127CE1A9
+:101DE0002B58BF24CAF8F3152CD1CB2215790857EC
+:101DF0003E0BB4C07C7374E789783D7F6C57AE1599
+:101E000070223CF2868A6278A6D7D9DBCDCC87B225
+:101E100027519ED15A1B42BCCFD0A0DB58C60EB76B
+:101E2000D6C66A01CEC3456E9F049876E52AB6F6FB
+:101E30003359FB26C43B530F1D94012F4BC57C4DDA
+:101E4000BE39EF31E8B72A1F4AB0FE23FF10CC9C01
+:101E50009083FC26071CA28DC3C407A3764E079768
+:101E6000D30109DA373D63EEDBC436E4033943B20C
+:101E700095832EB37E4C1BF2E191B85C1DB91CCB4F
+:101E80000BAE30F926B30DF96A5A8659762D473EC6
+:101E9000EA569C429E0D6C433AD96A8E67EC20F953
+:101EA000F21633EB1D541F89CBBFF25D585EE81369
+:101EB000F018DF2779D8A4717D72D50BB16EE322BB
+:101EC000DA037F5E19447E8B7079975C3FA933DA21
+:101ED00094857C07F819A5F6E4B7F54199F828A28E
+:101EE0007D2CE3FE95D603CE60FFC23552E704A4F5
+:101EF0004F850D45BE6F6E009D3E0ACA2FA6B9D410
+:101F00004C94EBBE722D05FFFE3CC8F97752D09B76
+:101F100073127157C80A91EE9A1BD69AFD0DDC5FB9
+:101F20007DA42B9A96D7FB38AF851D24673A24DF12
+:101F30007CAE9F6586FA3978EF15DE629668F758B1
+:101F400098EBE5C6426D7A10E69D05E297C11E3614
+:101F50004EBD3F1282794E143B036EE233ED0DE429
+:101F6000B3B9828676B834B60EE546B1DBB71165F3
+:101F7000B75CE05C0B656508F02B962B387DEBF0C9
+:101F8000EFAB1138AE92A07F8063CE5A3B3F28CC96
+:101F900042DF50BF28989973F25B50B89A5D8DEB81
+:101FA000BFCBE95B8A726CEB08DF2D5679F6689837
+:101FB000CBB1A858EF81A9FF5283F8F994390228D0
+:101FC0003FF6A647489E1DCB62AC0D75BEC654DFDA
+:101FD00020E46BBE0E297F21C3F60F0E87250C0669
+:101FE00038D6BED3515A08EFEFE3FD3EBC86D53359
+:101FF0007CAFF0323C0C632CB63B4AEDEE0C8EA06D
+:1020000079D943018F07691F9AE37E7B59BB139FE0
+:102010008E8C6787EA29F6C77CB2D5CE8FE27840EE
+:102020005E024D88EB9698EEF80AD72FE43FD0E990
+:1020300006DC1F90FAA447267D78CA466FE3822A01
+:10204000C1914C77D0AF89FACD37FB31A76EB1D7AC
+:10205000D7077F146D1C49FA681BB5F3823ECAB1DD
+:10206000E9A3BB8229F4D1C84AED6EFE9E97A1FF79
+:10207000BDBDF4FF5FA9FA43FB1FD27B8F4EF8AAC8
+:102080009AA8FD08CBE38799F2041A1681FC186020
+:10209000CA8FF41BEBA658E48F31E1619437D7EB7C
+:1020A00092A8CF7F98F44EC8ECFFABA57679B4E048
+:1020B00061BB3C9A7923D627E44FED4376F9137E32
+:1020C00018E545708ED06BECFD8770FCE62566FF49
+:1020D000D1D120DA250E531EB228F2A1CEE2659BA3
+:1020E0001D79E4D9F6A5A8E74CBF8919ED0F213C6D
+:1020F000A69FF1D6B3FAC3A817412EB2E3261F8CD0
+:10210000E8C9EFA61C30E9C7B40F5F7B31AA1BD02A
+:102110006E6E8516B3EE4BDCCEECE6764FC2BEFC9F
+:10212000DFDCFEEE7BFBF1759ABF80D3DB3730FE40
+:102130007BD6F14D7B0ADE7713FD89F7979A3F072F
+:10214000F09D26F8C673F82EA2FF17B4EE00D75301
+:102150007F0578D343163FE012C4E7B04B1CBE7135
+:1021600021DCEF2ABEDF8F69CC94E31308EE1E74E6
+:1021700070DEF45F42E396F2755BC6D5ACF3F5E62C
+:10218000AF43BB327BBB38FF54105C62DCB3F4AFAF
+:10219000B6B78BF78F842CF4D9077CBEC8BABFDFE3
+:1021A000801C5945E38FE4E3CF4BE0F126EBFBFFC6
+:1021B0001F373B279DEF207AAAE7F4741EF6F60F2F
+:1021C00010BFDBA4763D8BE2448689F7FB701C7858
+:1021D000DFED82F731B11F8F14471EC0F658F48F20
+:1021E000B3F827C6DC5D085FC23F81810A2CFA9EE6
+:1021F0005DB70BD763EAFB27428B761940277298AD
+:10220000B77FF4C0CBCB70FDC965B04BFE99F63FEC
+:1022100007EC92316497FC0BC275AE7101FE76C279
+:10222000C3D39C6E52D43F49E33EC6EBB7BAB81D48
+:10223000FBD6924FC98ED36E551D68C7997AFDF9AA
+:1022400010B767C11EA9887A7BDA8DCF8B781A8C7C
+:10225000FB3CCDDBCEF1DF199133D1DE4CD82D31F3
+:10226000F2831276D50AA2A3B85DC5BE4DE5A96278
+:102270009FDF087D679980F7571C0F623DE76EDF8F
+:102280004170F879FB14F59D345E2E8793790F9D8C
+:1022900040BF95E895FF8C7440799528049D0B4AC2
+:1022A00072C06E39D02AA948262BEF33F7F976E2AF
+:1022B0008BB8DD26F8F07A41C79F84D6D33E5E7F87
+:1022C000DAE4FFFDD47E7CDC4F5D4FF0BF2DE213DE
+:1022D000DF0BAF37E1FB90E053397CDFC0F8A70993
+:1022E0003F8CE3A786194EB4CBD0AFDCC37AEEEFB8
+:1022F00017228E03FDFE2FF5F370B86A7489ECF790
+:10230000C88A634EA4F7A59D4C4B451F72D865F64D
+:1023100097C364970BFF36C0E342C9EDD3C2717A0D
+:102320004AA3F63E3EDF86E2480696A7E8AF870757
+:10233000F1ADF1A03D1A2995A22D79E8DF78CB4ABD
+:10234000A13CC7C1BAC9EF636C33C67DDDCF2AACEF
+:102350002540AD55C512D7012EFD35FA910BC43E6F
+:10236000CF61F1F88A03E33596F80DF981EEF09D1F
+:10237000F9AD2AC55D286EE3F2CBE45704EF5E4168
+:10238000F191F422B7CF8DF3C8B9E4E7BA1E10F18A
+:10239000A2F9DCBF74C03FB4A3D3D732F2DF666DBD
+:1023A00097A22AD4BB357BFCA576C3A926F2EF56AB
+:1023B000309F067EA25264AF7725F9AF8D857A00F3
+:1023C000F172F2BE5A07E22358C9FDB093F75DE1FE
+:1023D00045FE4BF6A34FA21F4D52AA871F6DACC3FB
+:1023E000F89AC58F5ED3877E74386CF7A38715473C
+:1023F000CAC248E78A46F2EDC0D44973C95FDE2EEF
+:102400003337B43FDE3AFED522281BDB9500861B0E
+:102410003E706A4BB1DE007F5A1E46DBC430BE35CB
+:102420005BC07FBCF85429C2AFDD3E2C80F47EFC3B
+:102430006E37E1F9F8CAEC68068C97B5FDB34D69C3
+:10244000D0FFE5E8100CB2C5FDEB643F1CDC2703B0
+:10245000E9E6381BCA5A701F141FC37195FAAC8085
+:102460001148F8DBB3F37D068EA7473318EE7BECFB
+:10247000974C3A99CFE8C801E9780E539D5898C710
+:102480003427E27F01D3A97C1DF09B7405CE976FA2
+:10249000101D00DF61FC6E7DA17E13E1E3414E1F44
+:1024A000EC1E65179E571C37EECD443EDB9B6E8FAE
+:1024B0003798CF3522DEE0413F7F4C9FFAF9EB0899
+:1024C0001E2127CE43AE34F0FDE4FC7A1AFDDF81F5
+:1024D000A427EB90CF3B441CF89E6C1E3F690D7304
+:1024E000B992FC0486CFC1FE17AA27405FEE08DB35
+:1024F000FDF89D583E0F7DF94392334FF2753687B4
+:1025000099297F7E1CE676809A45F11410C5D7F292
+:10251000FDC59FCF25FD611C5F7B4CA2FD4A531971
+:10252000C921378BC4383119623D6CC3207BBFBDD4
+:1025300067EB776390CFFF4191FE136C57720A28C7
+:1025400014DAB9AB781C7CB6577A495213ED8E6019
+:102550001C2A55DC5FC85168167380BDB2230BF688
+:1025600000E3DB4AA01FCAEBB71AB4A368C31D6916
+:10257000A8A06797524FF2A3EB3E39DA085D5F6D72
+:10258000601DA5A37A8E5BB32478F484451ECD2EFE
+:102590007BC403429135E5B71D92305EAFB9553724
+:1025A000F4EFC88CDC83F17AE37599ED017817CEEE
+:1025B000AF3C7AC2221F92C785F998012CFB56982E
+:1025C000C7315F0CBA63D3009E1586144579B0C23B
+:1025D00038E6C478E5D2B5CB980EFBE42A3AA6E0FB
+:1025E0007E96077DB4CED94532332C70DD7FADD6D3
+:1025F00011E6F19D37687F03713BEA4D2C079D5A28
+:1026000096AF20118734CF051E0BEF267BB4239B9A
+:10261000D1FC113F8B36A2FCD296B9BAF19CC51FF2
+:10262000A1B8E9E1B04AF3AE6CDD45F0A44FF998EA
+:10263000E001DB39E6E8DF13DF261FBC2EF0DE2CDD
+:10264000F0DE1B9E3F09F3789E599E5DA664229E94
+:10265000DF50543AE7E88DBFE796DAF7C7EDAFB041
+:10266000959BB4DB1D484F275BE528EE133C5FC10B
+:102670007D3B0DFBC6F212E37464B21AAB7E36F7F3
+:10268000674AA94C7099FBB3743BDF9FA5DB838439
+:1026900097A5A595AEC1FC5CAD1D689BE945CB181F
+:1026A000E2C5A51D53508EF5B65FC06FEE528BFD8F
+:1026B0007811F1F37EA516BBF69B8EEFC37C4369C0
+:1026C000BE243BFBAF75BE60D25327CAD582845C63
+:1026D0002D2BE5FA20F969CA558B3D49714D0B1C2C
+:1026E000CBEB2E020E934F904F516E84774ACEEE75
+:1026F00002DC7FE0D731689FFD76F36539C8378CFF
+:10270000E8C151CAF9C635658E0BFDA695F77DACBB
+:10271000A0BE027C4E277C0A393CB694997A6806A2
+:10272000D1451DA78BFFEE731D806709C1B984C316
+:1027300079A99D3B7DA73A525F4AE7402097BC1894
+:102740008FF789FD674379DCFBC2CE373F68BD9DBB
+:10275000A11D38E70F992ADA818B8AF768796ACA4E
+:10276000F34D55B29D6FD68618F9158C8506B37357
+:102770009E6F269F9FF63CEF345E6ACA49D8DDC93A
+:10278000E79DC9E79AAC97F3CF9EE79D2F561503B7
+:102790009C3302B24F5513E799AE2927DF65D7F472
+:1027A0003CEFFC12D623F099C32CEBED1AAAB6C766
+:1027B00000BE96C19E401B6FCEE46B1378043DE0D3
+:1027C00071C33C9BCA007EB497F3DA7E308FD9F098
+:1027D000E8223C5C201EE97C1BF1D22A4537627F4F
+:1027E000A5DE4079BE92F9D4FB0389FD8C8F977FDB
+:1027F0008786F2F91F6ABDCC01FCBF39E736B60CFB
+:10280000DAA71F4E6332B43FACDE46FB7DF8A34C23
+:1028100015CF7BDD7ECB3E085C2A267C724F3FE9DC
+:10282000AFB08F1E64B91EFBA8B695A29E3DDFFD1A
+:102830007BA4387204F9D803FA5A199778DF3594D3
+:10284000E3B3FB2A166D937AEE23E05B23BF339F3D
+:10285000EDDA48F5F50CE3039B24C6F19D44178E91
+:102860008C0D069E6BBB967BC98F6AAAAF277CBF77
+:102870000EF8367C9CBFF09CEA2CFC65D2059306D2
+:102880009D3F5D24EFFBE1D65AB6F6D2DED75EF867
+:10289000737729DA3DE7BBAF5593B57E6513ACFB83
+:1028A000AC65970DB4F2AD21F2520CDA47633E638A
+:1028B0007BB27BDA51978BBC14186F30F61F52C66F
+:1028C000441C501B82E579C3597DAABC17E774EEFE
+:1028D000C72C01139CE22A463ADB331EBDAC9DEFA8
+:1028E0000D42BFCEB84AC532530F4591AE6AF912B8
+:1028F000D8911DBBBAB07E362CD69143AF54870514
+:102900003F81B23C1AB778F5B15754AA0ED0F82ED1
+:1029100010FEE8A72EC197944FC2A27B480EE86C28
+:102920002EC8FB1BD648EF61BB1A2383A15F9BC84F
+:10293000AB783429AF829767E78A7AE3DFDA6CE70E
+:1029400098C60B49FAEDAD36AB3FC58C63A4DF6C7E
+:10295000F685459F1D79E9F7CB0DEB39A6F1318D51
+:102960007F7489395FD16EFB39E69734BE19A7664B
+:10297000EC332A2F89973F27FD6AC691FF5436B161
+:1029800096C74DF5B9B8FF7258AA47FB08148C26B4
+:1029900051BCC6D786FE34D8FFF3B0FE6F7D9D6074
+:1029A00087DC5C6639FFF85B83FFB819DF370E2FD1
+:1029B000D70A2E7D7801DF0F10BE2B38BEFF06E050
+:1029C000FD59598A73804B08BE9708BEF839C47FF9
+:1029D0003B3C6F9559FCCF6F7ABEC993B513484FF6
+:1029E000DFC03A4E9559F20FCEA3FD7F517B715E49
+:1029F0009A5C7F73B98FC7B1C439F1DBF173BCAC9A
+:102A00005A1CAF3B71AE47E75E8973C4E157044778
+:102A10005AE11FBE1BDB9BE78853CBF36A292FBA11
+:102A200097734C0DEB156B7F95FAB724CDE712F534
+:102A3000F3CBBF556BD8F07335B5EF486A5F23D63B
+:102A4000B7BC7CDC6EC3820FF038A97D5C2EB189E7
+:102A5000B5F673C709B5D673C7D5E513779BE7FFFE
+:102A6000E5881F714EFB3F1D1FC172E16F8AF37233
+:102A7000930E874DD242E5132E3D7861FF16965B8B
+:102A8000E8FFAF30DF8A724BDEC585F68FF3A3D047
+:102A9000FB66FE04E0F7165CC7CDD355C27F72BE5D
+:102AA00084E92746BA5914FD96C92C2AE3B944246F
+:102AB000A0338C83C6F9DAD06A295E17BF1F51B1E3
+:102AC000DB7E3FA27137DA1709FDFD54AD3DCFA182
+:102AD000DC06F78E979F32D7DD546EC967E8EBF1BD
+:102AE000574FB7E3255E16F8597CCB8F87DAEF5F37
+:102AF0004476D33946FCFEC5229A3791DFF1EDDDED
+:102B0000F6FC8E35544EEC5743D27E7DCF06D71758
+:102B1000E50D04974BE4BDB95648BDDCAFB89EE463
+:102B20008279AE0B659B5CA0F23700D741938E048F
+:102B30009FC6E1EC919FB76C37C699FA7A7E8B5CA1
+:102B40007809E9A2EFF1CEEF779878EFED7EC7F53F
+:102B5000AA59FE6E6D5DC1D79F17F3FFCA53E61FDA
+:102B60005DEC3AF87D1157F27D11B6AED62E7FCED0
+:102B70001BBED3A9E5CFF9F5FFB277F9F317943F60
+:102B80004D5E07DD47D1FD2CE57D949BA7F373A92E
+:102B9000387F8AFB28F376A4F6A7FF7E3A8F5F9BE7
+:102BA000F1EEA0EBD40AEB79D70051EF9B1ECF1BBF
+:102BB000F04DC771D772F886A13CC4F31EA6300D44
+:102BC000786AFEBCA1B9085FD37FF2F1981FFCE4DC
+:102BD000CCC47893C578E63C2FCCC9ACB1E635E4DB
+:102BE0009AF34C97CCF8F4B0E988CF0D7C1D72BFF6
+:102BF000D574CF2BEE571BAD24BF9A9DA69FFDE049
+:102C00006E92677139F463A28B056E93FEA3BBAD20
+:102C100071E3B25FECE67A158A788E97E8775F2DDC
+:102C2000F979E7E85768E27993D82F23BE5FE3117B
+:102C3000EE73F5B7F8D1312927E1473F5EA84D4142
+:102C40003C833F5D723EE3009EC2B42F6BECFE8876
+:102C5000A57EFA745B5ED2A9D567CB4B9A3BFDEC9F
+:102C600079497313F43077BACDAE0F674EC038C9C7
+:102C70006047CA7B14BAD8D7447ED74F69BF9A4DF4
+:102C8000BE13E57BB279FD0DBF78BC56C07FE374FF
+:102C9000CBF98579DEC20A0EC530CE63C92FD21CAE
+:102CA000D6B84FF89813C75BBA5D4A993FD3835F94
+:102CB000B68AF1B7C7F7F1E6E93C1EAD63DCF17AFD
+:102CC00073DC6F37D2B8352BF8B8C97C73A788533B
+:102CD000DD99A0E33B691C2D9E6FB30ECB9832E0CB
+:102CE0001E9718DFBCDF1374469EC3739D66435264
+:102CF00051BEEA6B97D1B922AB606C14EC5370F003
+:102D000088ED283ACCF98657F0FD825F4BB19D1FC4
+:102D100024A43118F3C497D1B9F3B51ACF5B9958ED
+:102D2000D5280F5429AFA505F7AD78FEAE265CF681
+:102D3000754B7E26A7CA67E988E7B3B037460E020F
+:102D4000FE16F0E1BD903530CFDBF17C96AAB23BA8
+:102D5000ACF92C91AF97CF62C6FF168700AF967D76
+:102D6000CBAEE078CDAEE0784D9C03333ABF1DCDBD
+:102D70006A665C85F165BCB705AF3BC43DB733B946
+:102D80002C8AE7FF8D53D3298ED79DCDE85C15366D
+:102D900024ABFA5ACC23E13F69A34A298EEB86750E
+:102DA000E13AF05C3676250C2F2FE9174B41CFAF77
+:102DB00066E92CE0C5B8BFB19901DD84F57BE97CFB
+:102DC0006EF88A8FEB70DEA5BA5B4512B8BECE579F
+:102DD00046795CAB03CE3B300EE9979986F1EC2A3D
+:102DE000E7FBFC9CC643789A5DCACB265EDC4C7937
+:102DF000DF8A1725A9BCF6DDC62D072DED5DB1B420
+:102E00004C3C177C69BAC80712F78A98EC253A3807
+:102E1000E37744F11CAA4361071480A35697E9FCA9
+:102E20007DCFF65B5FC1FB634BFD4AC001EB0CAF8E
+:102E30009528FFEB7A1FC7D3670DC6968360C3A69C
+:102E40000D1E41E730677C1E8AC6372FD943717B40
+:102E5000A0970E05F37AD6C90CCFBDCDFCA7398259
+:102E60005E4C3CA62DFB94F07206CFC3112F45D9C2
+:102E70009407350BF0A1FAE89C7F13E2299DD5C792
+:102E800006C0BC0BFD0E16B3C4A161FDB63C3218E2
+:102E90009BF2CE147A63AB27FCA4AF0BF37C34B95E
+:102EA0002A86FB7AA688EF2B940348EFAC94D3A92B
+:102EB00089FFF4243A7527E58725D36932FE4F232D
+:102EC000DE2DF7B9F6282C10437AEB94C9BEE86ED4
+:102ED00055B228EFAAD54179578C45E91ED31ED6A5
+:102EE0003FD082723326D139C175026F26DE19AB0D
+:102EF000DFBC1CE3DCF559018CFF3347FD66CC8F4A
+:102F0000BA3E9A41F9778B583BE541DD801E32CCC1
+:102F10007B23F3B9B0BC9C05E829B102BA5FB2507B
+:102F200097882F7416ABBE0AF017BBDC996DCDAB3A
+:102F3000EA35AF09567ED2721ED1BF42C84B8FEE22
+:102F4000E7799EBAB8F7A3517E507659A9474F2129
+:102F50006FA715EB832B0626CA8AAF9ED1F9747131
+:102F60006448C58444FF470BB55C6C37AE481B8A88
+:102F7000CFBD68E7813E081F1AF508EA83C6424DB7
+:102F8000C5F6C9F2EA78EFF977B1B540775D28AFB9
+:102F9000288FB080F8B0AFF2EF0A2B7AE4DF4DA8AB
+:102FA000B0E4DF1D75F27B65948B3C99F5BC9FB650
+:102FB000F63AAA37EFA725DF4B630FF2322CC86829
+:102FC000198BF777EB69DD26DE93F1C3C4BDB4C579
+:102FD000FE97BBA46BFA206FCD07C6DDE0B3D187A7
+:102FE000C1EF2F57DFDA954379840AE51136E7F10F
+:102FF000FBCB9BB00926028DE4F6E097425F6DC9DA
+:10300000AEF707A07E8B93E7C3B07C9DCD1B9318D2
+:10301000F7CB0AD93C175A8A7400761FD94BA6BD44
+:103020006AB6AB157A6195D00B8F17465612FE1310
+:10303000F9DDABB03FF3C6A20EF3DC8EFFD03990C2
+:10304000693F1C19524FF9346E2DB5BD706B455C4C
+:103050009FDF4AE3B79AFA5CBB0DCBD306F8E623B1
+:103060009FB9C2326B433D36FB6692BB4F61DE288F
+:10307000D83413F5C6F020D8EF860A71DE54978D48
+:10308000E8621D1ACF278D95D4FB51DF6D199CFA8C
+:10309000DEF761B1CEF1C34EC938EE96658C6D1C7A
+:1030A0008BF833288FCD5800B204CAE0EE1FC473EA
+:1030B000190FDA01C5A817797B5F1DB4817D6C17E4
+:1030C000F80F8E06FA41FB6B943D1FC97C9AED9276
+:1030D000F3AD409467E2BA93F3DCCC7CAB2EC5C869
+:1030E0000CA4807F76D91A0FE56BE52EF7A09E6CB5
+:1030F000D6C2345E72DEDB965C3614E14ACE6B33A8
+:10310000F3A6CC7C2973DC7FAAB0E7B5B9FD5C6F70
+:10311000C193F2647E5AA1F2EF5268F6FC3633BFD7
+:1031200006DB537E4D2EE3F935FE7A86FDDC50C674
+:10313000F611917F969C570572E86744573DEC2342
+:1031400046764673B1C81B60DAE665681FE1F96D23
+:1031500020857D050201F5A00BF413D62BF2EA0AB7
+:103160004CE5F9BA76D4B4E2C8CB48972E7F5CCE52
+:103170001E22781372F697580F72F65756397BE66F
+:1031800090F108E66F6E91381D6E01BC3F91823E52
+:103190008E5448828F53D3CF1F04BD361646DEC2ED
+:1031A00079B41C7EBFE342EDCCE6849DC9F1D847DB
+:1031B0007626E0E377840F21A7011FBF473893F1FC
+:1031C000003F9B506E58F24C3FC57EBDE59926F7F7
+:1031D000BFD87BC212C80DFE1D09ED2F0857D5447C
+:1031E00095EB5D218F13F76D2F4E5E773A408E027F
+:1031F0003C681358DBFB2AB99C2B98ACFB2A492F5F
+:10320000F3FBBEDB82FCBE2F8B69A4F78F64EA352B
+:10321000C8A72C7FDC39E66B14F9B47A5D84E4FC32
+:10322000DC73B4DF48ED0B268BF5E6F727FDB14DD7
+:10323000D2EE4B9713E573ADCF53A98DAA447F53BC
+:103240008FD0F712B6E43B54039676CF44FD5BB8BB
+:10325000AE2DF91B69FF5A80E024909BB31CA7EEAA
+:103260001E21513EF0D3523F787AC0634B41D7457F
+:10327000023F60C5523D7B57F35BE31CB595F1B847
+:103280008A884BFCF323D67B4C732B7FB202E3F18D
+:10329000A61EC378C91329E82224C691DDB7DAF443
+:1032A0006472BBD24A7E0F645EA5381F107A6F81AC
+:1032B0009BFB51EC30C067D1AB05934315955C6E19
+:1032C0001992451F9AFA8F6A2CEFDD7E7EFF847576
+:1032D000DAC731D7B942D0A9392FD0EBFC4A1EBF8B
+:1032E000585069A95F20331EEFE8B0E30BE0594462
+:1032F000F03076A217781E49094F971D9E1571BAB6
+:10330000D556E078A09757E2736B08E82E057EC784
+:103310004C08DD84F50A33B68EC83BABDD5A8FEB23
+:1033200030CB16BBF5B64ABB3CBDBD92CBD3359571
+:10333000244752CFDB50C9E5629F7D3FE03CF9FD59
+:103340002EFC3505DFB4743F99710DB09ADB6DDC4E
+:103350004EFC5930EE1CFCC5F9F9C661F5A4E79E98
+:103360001376C8734EA6607E0DF0582055DE4FAC24
+:10337000D2B43BA243102FCFF46277C4DBF5925F47
+:103380007F25DB997131F647CB942319647F9C6EBE
+:10339000CB403DFFCC89504AFBE3B9DC9D4352D979
+:1033A0001FFB7AB13F9EAE14F6C7072EB2274A3EE6
+:1033B000E4F647C9873B65B423FEBD52A5F5149FCB
+:1033C000E8907580BB04ED0F18679FB03FB03DD902
+:1033D0001FA777CA0857F1871DD4AF04CA687F14A6
+:1033E000F7627F001432E2E1E992963771FF92D7DB
+:1033F0005B355EFF85956E8BBA3B28CE63F66BC955
+:10340000DF98A1D37EDBE9675A3197BB897E9CDECA
+:1034100093DBF546676572D5D66E58D73696B99365
+:10342000F23295FA87B16C180AE56BE10736906EB7
+:10343000EE9C0D306463BBFA47BB51BF186E1F7E14
+:10344000DFE0B3F4A5DCDF59C37CCEC90979444B76
+:1034500007D08C9018CFE5F13581BDF4A38C2CC238
+:10346000E35A9F19D7D9593102FADF79E548BAFFF3
+:1034700013BA170682F2E44E99EACD38D02B83199D
+:10348000E5E903FFCEAA86F1278AF141DF69B74358
+:10349000FB05C21E2B97BDD4FEAE7CDE7EB271AAA8
+:1034A0000ECBC5DD2E15EF993179837C0BC66FD11C
+:1034B0002E81F6773D1B29F3407DFA118004C77BEE
+:1034C000D745710C0DFE21FF4EE86C277C669C7081
+:1034D000D9E21BE920E16216FBC5955466F2927EA3
+:1034E000A9E493F9EC110F9A21E211D7B0BFFB0ABE
+:1034F000ECAD336CC3565CA37B54E8C5DDAC677F91
+:1035000033DEF0FBF19A7706ECE348A74EFECBBE24
+:103510000AC035ECD3BED6D699D720DE772A14DF81
+:103520003DBA3E83F669FFBDCA2E8C2B1D053EE5D4
+:10353000F1F3B52B915EF7679A6516C3F8DCFEF8D8
+:10354000F70A07F07A515667043E40DF78FF40D112
+:10355000DE68E5F56699DDB512F337F60FE6E51995
+:10356000337EBA07DB63C637F9D76B8F7B53C9CF7E
+:10357000513355DB3D8F5945B7723A3E473F90F77F
+:10358000D7CC18D8B35F5A35F7B3F62F0110C7223E
+:103590009EF4C21930FEBEAEDBB68E81A9C64F596D
+:1035A000DF41727440F79A54723F3483DBCBB1929F
+:1035B00028F95DE0CB73BF972907318F751653C784
+:1035C000A17FBF63EA33FF710DCCF36AF1A871727A
+:1035D0000ABEBE61C688A475BD2E2F47B9F4D1FBC3
+:1035E000F353C981E64ABDC2BE1E7E4EDAB45321F2
+:1035F000FCD7FDC7278F60FE43AC6427C5F1F6FDFD
+:10360000C1C1D06FD93786DBFF78534FCEE913F8AD
+:103610005A27A6A03B806F492AF846CF643C4F74D6
+:10362000BCB614EB93E15531DE0DF08299154039AB
+:1036300092F6DBEF77605C735FB783822B674EB4E3
+:10364000C948822D5D234AD16C9D56754C46922AFD
+:10365000F1DDBB198F80F50DB28DFF2676A5DBCA93
+:1036600037D40FB09517D70D49F023C3FB4057D877
+:10367000CA6EFFD5B6729015DACAF3AB26DBC62B3D
+:10368000F3856DE5E9FE99B6F695EA3C5B7966FE51
+:10369000625BFBEA40ADAD3E523056C1AB7C409719
+:1036A000CD88AF8C4E8DF87C4BD76D3EA48B58499E
+:1036B00084FCEA23991DB918B77EA597EFCB75CC8A
+:1036C00090857E07D308E524E8F38DD989F6C111EA
+:1036D000DDB6B8FCCF67707DFD84A0EF73DF87E3B4
+:1036E000FAF97CEFC125EBE1D957DD4672A965BE39
+:1036F0001CC57B554DF96F78F1FED82BF3793CA1B1
+:103700002517D6E9A5BC0CE2AF17175C3714CFD745
+:10371000D2F3F50128FF4DFD1DCE8FB2E3509FEE91
+:103720008BB22BF09E19946BC57DB370017F3F5A0D
+:10373000BC5F854FD0DBE5167C25EBE3A067EC4B47
+:10374000E036B0A97FF2D177FCE617F0B84FE9E98F
+:103750006829DEAB9EA9BD70905F9FE6F2E7D59227
+:10376000DFE5F4A2B7FFDDCE0FAF133FEC3B31F73F
+:10377000ACF2FF370D3CCEFE548387C5607DEF363B
+:10378000F8E8F99F0D7E7AFF7A834ACFE6867C7A45
+:10379000C61A0254FF6643113D0F3668F47CB9A186
+:1037A000829E871A22D4EE570D35F43CDCA0D3FB61
+:1037B000F76770BEBC54E0D1F2CDB842E44587440F
+:1037C000789D8F29BB933ED464AB7C07BCFE76C644
+:1037D000849E78BD583D122B691F12E17A2B251F5C
+:1037E00039679AF76EB99D3C4B27991F87CF857132
+:1037F000BA9C449CCE8D264D7F82F32F7D09E77EB7
+:1038000011C7D99FCD6A9EE0FED42689F48D6F2C16
+:1038100097E7F7474224CF078E4D2DCFF37AC8F3B1
+:1038200065A4B7D8218C9F627A110AE395387FEAA4
+:10383000B888D12FEFAC78A0734B130F96FD1A3ECA
+:1038400033051F9C0B0FC9EB9F56AC8D9E3981DF52
+:103850004771F6EFA94746777FA1616CEAE9020E4E
+:10386000EF8EF7E7F6437BC58D4129F2DFC1702B60
+:10387000C2FD66665EC19EBADC9EE3FCA6A49DF412
+:10388000FA5D713BE701B26392DBC1CF41C203EA4B
+:103890002D0B1E52C881693353D04199FC6CF746F9
+:1038A000E8BFBF9B51DC4C459B1AE07F46E1DF6BD4
+:1038B000D8FFA183F07CC623917C74AFBBDD83313C
+:1038C000EEA7BFC7DB19D512DD63C838B04F453B43
+:1038D00035D8AD0FC0EF8E15C52A9DF89DD0D09478
+:1038E000B181340B1D8414BB9E444B35AE77282820
+:1038F000D63FA97C79A2BD8CFB3F2251CEA3FBD73A
+:103900008B705D734FD533B540C459BD29F1B45A9E
+:10391000B2C4DD1416D83A318FECCE8397E3F9CDDB
+:1039200028169589AE0CF2BF4D78656F84EEE79945
+:103930007EFAE792B60AE7EB317E9D46E76FCCE16F
+:10394000A0F3B7F585FA2D33E99C3EE97CC6F7F282
+:103950009F25D0695B1D2C86F68591E522FC25EF1D
+:10396000D7B8A2CADBB1BFFF6BFBF53B25EBF70273
+:1039700046ABD3C89F3A03FE14DE476952F83D298F
+:10398000E3DDCCE81E0292E5A3DD76A77C7500F7A7
+:10399000FF4719FF48FED15A5824FA5FDB851CBE49
+:1039A00007E5303CB73BB9BFD5DCE8F6B5E5A0BFCD
+:1039B00095653840717D96362CCA609DAD33B93E11
+:1039C00077B31BFA45C69C057EE19F38E3FB9EEB6F
+:1039D000237F4394BD2EDDF109FA7547E428C6DD47
+:1039E000B68D7DB06639E26FAC879F7F2A31750E48
+:1039F0001A683E83E558EEF1CB4C398971DAAD6037
+:103A0000CCE039EFDDE21E6E66C061B377FA15D9FE
+:103A1000EDB59FF411DC2E9444E8B7E6B8A2988F78
+:103A2000A3A2DC02B8B7FA1DC45F9B542E1F3679DF
+:103A3000358F2FC5FE6E417CBB7B9F5FCEDBE4C321
+:103A4000B8F74EAF83F877ABAA6CCB83F2562F371B
+:103A50006A9B544745AAFCAEEE99DCBE8226699467
+:103A60000F159C4BF64E6FF3B4887D37CBE905BA42
+:103A7000467CA60622B89E266F8E84FB62D6EF9FF8
+:103A800029097DC5E3CADB84FD949EDF1EC3B84EC1
+:103A9000F3E05585882E0FD84327E1BDA7A09DEC04
+:103AA00027EFE52E3D15BC27C478DB9C810AC4E7CF
+:103AB000B64C0733007FDBF27A39DF12FAB2491DC8
+:103AC0001721FA067C8C927AB67B5EECF366E74EA1
+:103AD0003FDE5BDB366A21E5856D1BCAE5F3EAC391
+:103AE000BFDED388FE83FA5DF609F24D8E42FBA657
+:103AF000B28007F55CB34FF1615C607CCE1D9EA087
+:103B000045CE25F38973F0DC1ABC4F78A6283D809A
+:103B1000482F930FD377459A032077F3306FA9DEB0
+:103B200067FD5E00D8DD9F21FF9F8B4E55A67B1061
+:103B3000BF303ED1516FFB970C8F1725D3B8B3B46C
+:103B4000CFD66B527DC7645415C7AB4937CE73D0FF
+:103B5000CDB9E0B7E9C5DC845E1C5875D92A3C7F35
+:103B6000BE9BF1FACB0EFF8EFCF4E4F2D7E5CF2634
+:103B70006527C9EDA6912EA2A7E4FEDBF2383CEF43
+:103B8000CC3C29E20431E2DF6C0F8F37DD53D43FA8
+:103B90002D955C2E1BAF8FA9B2D81BD9A5EDA46FB4
+:103BA0005D558CC76BD5886F248CE3ED94814601FD
+:103BB000DF8E2FFE744CBD783C2A3BEB5904C6CBFC
+:103BC000EA94893EF1E70B9083FD841CDC32FC8F84
+:103BD0000CF347765CA10478DECA4781B3E993AC65
+:103BE00029F678D285C68BAAAA441E431A4BE379DC
+:103BF00043552185F2751C5CCF6AF0DF2021222419
+:103C0000B1FF83C451948AAF789C2C670923B919FA
+:103C1000CF5FC1EFCFE0383A237B042FD062BBCB1C
+:103C200057737B2B97754B781E381CB37864A47739
+:103C30002E3FCFB05C07E5EFC034987F22190ED23B
+:103C40008B3F1C7E540AC2DB7B8A578D457C24AF98
+:103C5000636595887BC5D771763C9870F6359D9ADB
+:103C6000FABBC9C3F5B1068A3B0D8DE5A4F8679987
+:103C7000BC81EB63C3ED437DDDA4D43F8E65E81DBD
+:103C8000A1786952FCF3B3341E1F95EE603EA998EB
+:103C9000E29FF9B84F6B597A00E393FD14DD83F589
+:103CA000192315FABB0C60774FC4F396845FAE7A84
+:103CB00079BEDC5ACA2B7C1EF51AB43BF0C5D9E597
+:103CC000D193E7D06B2D9D23BD145FF7D466A03F41
+:103CD000FE947FC461F46FCE7878BE97D9EE40D25F
+:103CE000F74F9A859C3B5C25E2E8699FC9D87F9A8B
+:103CF0005F5530AF2EE4194BF2BD494A7D5ED05975
+:103D0000C5F5C168F5354E67ABCDEF96AD26F9FF29
+:103D10004EA6A0DF3A7D31C59585BDC7344DF55D12
+:103D20009BB0F34C7DE9577CC6CD388EC8B7EAB15D
+:103D3000CE033731FC1E0BF35BE2B32370FE7EF142
+:103D40003C3BE2E724FBAE377CB608FFB8C91FA2B4
+:103D50003C8D3328B3529C9F984FB0530FA29C9A2E
+:103D6000D061972F19F976F9B2D5514F795FC6D541
+:103D7000CC877921AC2AE0B7DAC960AFFEB28ACE2F
+:103D800077ED76E74DD58C7F673B5B55304E13F66C
+:103D900004199E4B28B93AC3FD70F90367DD8FB64D
+:103DA0002AAEF79BF39747D0AFD931F53B8497F113
+:103DB000153C0FD56C07FAF29D2A8B7F63E6299C90
+:103DC000F7F7947C0ECA5F3CDF3852CB9495FC7BAE
+:103DD0004AFEE5F43DA5A73CFC7B4A0732F50CB44E
+:103DE000BF2EF47B4ACBAB39BD863CDF7E71DA084F
+:103DF0000B9EBA74CA1F71F94FD1F9CD34916F92ED
+:103E00001C2F72BBEBE9BC2D5652BFD81A2F36F1CE
+:103E1000D726F4F66F4A74CA0BEAEDEF4198ED101D
+:103E200063B82EB788876E29594FF89F5B914DF183
+:103E30002845C4A35CA774CA038E8ED733AA2DF875
+:103E400077E71AA4EF32FE91F1FBEE9FF3FBEE1938
+:103E50001B5908EFB787BE1847E754A1581AF1D984
+:103E6000D4D301FA5E7599FCD8D611507FA053A126
+:103E7000EFC81F989A9E837AEDD34E6EDF661CB80A
+:103E8000EAF0DF41B9A4B316630220770096FE3D45
+:103E9000D731F5B4E36BF99913D0CFB49C9798E37D
+:103EA000FEBCE110D1C7930D1DF4DCD710A3674B06
+:103EB00043173D8B142D8CEB29EAA0B34B36E90454
+:103EC000D45BE0287A17FA5BE8C1375E1F5F4DFCD0
+:103ED000D7616B9791DF656B077E6E11B653FC1C43
+:103EE0009F2EFCCE188C3FBB8B6D96D4FF51F26A8F
+:103EF0005175DFC8AB1BAB079E4D5EF1F3D45097F5
+:103F0000F8AE58123FFE5795CABF8F64F2A53857D6
+:103F100035F5F456FC15F46953D677B87C8BE76F0A
+:103F2000F0FB8AE677E9EF78E5E45ECCEB697E5B4F
+:103F3000D41B9FEFC5F3DCC4DFCDF8E32ABC77F2D6
+:103F4000023AB76087BEFBCAB3ABF0FB410B6BB262
+:103F5000150DE00BE3016C76E2BE8C99D7988CB717
+:103F6000DF543BCCEFD0511CBE7904FFFB06C9EDFA
+:103F70005EAC167E9B6AFFBB1FE9BDDC137AAE9A6E
+:103F8000CB8B5F0ABC6D75F13C85DEEE837CBFFA9E
+:103F9000ECF741DE14F5E7BAFFF113D1EE0931EF8A
+:103FA000B04991FB51FE987F97E349F13EFEF73807
+:103FB000FC2CE5386D42EE5E3ECB27F653A3EF9F17
+:103FC000C1788F107D88BF9F60D64FFA305EFF4F5B
+:103FD000541FFF3B093AC589CCFB786DD51D7B1B6F
+:103FE0002DDFFF6A8E7F5791E739FD51E02DF9698A
+:103FF000DE47897F3F8A1DDEAB59BE1FF540F59B2A
+:1040000027C5F7AD9EA6F58A7B38DB70BD03E9FDB9
+:104010007E7A9FF43D81A75E39B8577C47F179825B
+:10402000BB3EF93B5DEFEEB57E1F615BF53BAB44FC
+:10403000FB97683CF15DAF147421E8F6E85EBC1FA5
+:104040007A1EE3BD46E389EF72ADABE67CD41B3D3F
+:1040500043FB23046FFC7BC5B51ED42B897BFF4734
+:10406000083FE781AFA334AF6ECECBF125BB39BF9C
+:1040700098F964265DB0597C3F3656C7F3744F12E9
+:104080001C2BFA0C0FA7089EA47B48E75AC7E385B0
+:1040900091CF080E7F3C1FF94F34CED784C7BC3F69
+:1040A00096CC1FFD6649661EB46B16CE931BFF6E41
+:1040B000A77B561FCC0BE366D33889EF81F69F951B
+:1040C0005AFE5CD0B84C3DBFFC12B3FCFF0015C8D3
+:1040D0004EA0007100000000000000000000000081
+:1040E0001F8B080000000000000BF3176060F85100
+:1040F0008FC09C687C5AE3BF4C0C0CFACC0C0C971C
+:10410000D818189C39191884F8C833E7229ABE7B4E
+:1041100040B366F030302C636560D809C47A5CD84F
+:10412000F5D90822D847817E5F01C417E91C06A390
+:1041300078F0E01A11068649A208BE9E18AA7CAD46
+:104140000882AD2345995D4E40FD008850BECB806E
+:1041500003000000000000001F8B080000000000AA
+:10416000000BD57D0D7854D5B5E83A3367CEFC26E3
+:104170003949069884104F42C0A84007080A1675AE
+:1041800012C146E5B663DA6A6CA91DAC527F61B410
+:1041900056B956CC4908C92484101015A9CAE02F75
+:1041A0005A6D53456B9FE5DE09508ABDBE277AD50F
+:1041B000AAD5DE5829AD566DBC9692BE8770F75AC7
+:1041C0007B9FCC39273393A14ADB875FBBB3CFFEFC
+:1041D0005B7BFDEDB5D75E7B8FE27041F509004753
+:1041E000F1DF5900F7FB01605C3A9DF9BD2F5FFDDF
+:1041F000781DFBDBEF0E3FC89299BF985F119B962D
+:10420000AE3F0724AAD7F08BC57F0456EFDFC1A9C4
+:10421000B9D9A79D0543FE30CBEB9213B09D1BEAA5
+:104220004BFF25C8CA871DE16E964F1D760480F5A9
+:1042300033039CD80968A006A2D3D977F9CB45608F
+:10424000EADF9E9EB949865429C0AE95204759BDE4
+:10425000D505A72D1E0C00BCD092FACBFE290091EB
+:10426000D449B2C6FAD9DDB297F2FFD6B2EF2FFB2E
+:104270005D003128A6711AE67F242F61ED76B9A082
+:10428000B99FB56B8848AE25A6F162623EBBBCA261
+:104290005CAD97339617B072F6BD217841C6F2181F
+:1042A0009B11D52B16FD0C0F3AB19E06437E9AE763
+:1042B000E1A68CF39C20DA19F9BA413EDF9D6F1D0F
+:1042C0003A1FE99082A2A81BD3C3D56F22BE073C38
+:1042D0009206550CBF83E7117E53885FD6C5A1B700
+:1042E00039BE777DE208B7327C3778D44098E54113
+:1042F00066F460E50D0188105C324B191CE70BB8C1
+:104300002F166913A644178DE832E06174098C0DED
+:10431000EF599B1482D798E700CE338F76065DD98C
+:10432000D740B480B583CC7C301A3F6CBCD9C70E63
+:10433000A781D7E8FC81BFECF700FD3BCAFEB75070
+:104340007DEE2FFB6BD3F9B386F759F28CA3C173C3
+:104350002A8317FFD43095FF3C689457F1721C27CD
+:10436000D1A2FDB986F15F5F0BFCB986F15F6F8B5F
+:1043700087F23D2D2AE5BB5B42944FC8AC09A3638D
+:10438000A207923A6B5F1C61F54DE315CD65ED4CCC
+:10439000F01584554BDE5F1BB2D4F76A9AA53CA199
+:1043A0005DEF4832BA774D73249D12C2C164E44474
+:1043B00084C3432903F7D5109B4F0D6F026B5DDA61
+:1043C000AFAA119E179DD0C6F2855AC47129CB574A
+:1043D000869C900CB3F10B8700587F8995001B5881
+:1043E0007F3D334F755CCAF2DDF3DCAA530548B25A
+:1043F000FE136ED6CF9194B60AFB99AE84B11FE836
+:10440000937F8B78F2B0FF8E56034CD694B71D8500
+:1044100000553AFB6E9E9F5B0FA15C17CDB57E9F4A
+:10442000AC2DBD1658FDC960FA5E95A6A731AE91B8
+:10443000B78F671FE78415B6FE6DFD566A83F5EAF0
+:10444000B474BF27C050AB1AF867EE37D220219D55
+:10445000C2A025671E3FB8032B3E2EDE3F3B8DE7F3
+:104460001E17D78376791B0407E90F90C74184C1D3
+:10447000A5698E6437EBA7BBCA41FCA3AD8624EACD
+:10448000ADB593F6C531DF5DA5686D2C5F55BBA753
+:10449000599A01B066924A7CD7BDC30D6D610E4733
+:1044A00090F169A5C1A74706EBAB910F25086F6096
+:1044B000E555DA8156ACAFBEEAD35C7347CF0F56F1
+:1044C000F0F9539ECD7F08FF9833BADF5FCE5122BB
+:1044D00051E45B1D926E064F574D5BA3CEC6B95794
+:1044E0009701E5A77B65FF6B88E7C4140EAF7DDEFF
+:1044F000959AB204F91ACCE3B3F12A6B2EBC1AE7F1
+:104500006587C3D017DF6F51491EEF6AA9A5F4DE96
+:1045100016B51FF5C45D9F3833E2F77C89EBE7CD14
+:10452000AEA803E1D3E739920F92FE896DBE92E502
+:10453000EFF9EEF859B80E5C3FCF41FAE5CF3D1CDC
+:10454000DFF7487D1703D55734AA6F93FF7BE54803
+:10455000DBB758FD7B42A5A03379AE74ED3BF74441
+:10456000EC6F45F54C9DF577CF0D1BDEC6F695F348
+:10457000A66A4ED67EF2DC036FB2451CEE3A3218C4
+:104580008A0630CFE5BA72C5F8FE1AC62713B5BE43
+:10459000EB70FCCAB98A96AC4AF3650584699C1332
+:1045A0009AFD9052C7E6CF8A6B72F3E7F1D3037F8F
+:1045B0001FB92A47B92A4DC3BD59D82776BA2F92B9
+:1045C0001CC42F23723597CBD513A7733A1B727572
+:1045D000D7A4BE778B58BEF71B9C4FED7C5E35F79A
+:1045E000403DD2B587C94F4908A0CCAD7D2CB17CE8
+:1045F000EF122187730F484B59FB3FBDE2D300E513
+:104600006971667D9D8D9FD3A975DC7B6F70344485
+:1046100059BD5F5E3EF58F6E1C6FB1A2A19CF5CABD
+:10462000B534BEF65D45D34DF4AC5CCCE489F157AE
+:10463000E50D427E6C7235D6F8899624BCC3E468D9
+:104640007D4B08228C6EEB5A3492AFB542CED01619
+:10465000853296177206B5B3289FCDFE046825B93A
+:10466000F368298831FAAC677D43397E4F4522F3E0
+:10467000014A50579D4EE0A41C6C6D5F37520E11DD
+:10468000C6F4D02B89BCFE473DC2C653C33CFF6C69
+:10469000EB1FF5554C08D77B797E87545BAFCF373E
+:1046A000B7DF43FD1BF5593ED55063EA0FFB9F660C
+:1046B00086C7518FF58DFE5E6F2DAFD7D9F8EB44CD
+:1046C0005E692BE6F9E3DC7F8FD41F624C0F6B6CC5
+:1046D000FDF448024FFA7F442281F438774AEF46CE
+:1046E000744BF91F228827A3FC07ADFFA1EBACFE9A
+:1046F0004710BD4B627498B520560E8CEEFEC61462
+:10470000A029B5DE86EFF4FC5EA4F905A6F1FC7DD8
+:10471000AD9F4410DF46F9D352412BE21BF92630FE
+:104720001E20444202B0E9E73D573E8F7FD79600F6
+:10473000CC63E3687DA0B13E1C357109F71DA1C5AE
+:10474000F2018B3C08BE63F03D2EB174D6FCD8D785
+:104750007029CC009F6E86CF187F2C780D38B2F36D
+:10476000271FDFCE470DE7CC7D613E932FFF3E57DD
+:10477000D8ADE13C5409F5780902C5F45AF1915DD0
+:10478000442790FB436847DBFB2D59500E49D33C2F
+:104790003F6B7ADE85798EB797CD7465F957CD7802
+:1047A0007C1CEBCD19CD77C6FCBC383F403B98CD87
+:1047B000AFCE3CBF279B717ED9F0669FDF3A6F5F1B
+:1047C000733483FE3DD321F6BB67CEFD12F6CFC610
+:1047D00003D45F5E6D88F4AF8AE3B1AD66D1915DBD
+:1047E000CDB8B5CD369E3A9F8D577BFCF039161F5C
+:1047F0000798FED2583D4738371FDBE5D998B71FD9
+:10480000E72D211FF1FD807DDE008C8F0AFEFF9DCC
+:10481000F7C732A7E70DAC7F9DCF8BCBC73F685E54
+:104820001F3F5F4AF28AF038393F8732F1D73B9217
+:1048300066D9E7DAF93ADBBCFE517C3A7A5EB9F127
+:104840007CBCF550BEFAB5ED551FE1B1F732BE4F55
+:10485000E8DDBB90FC0EBDCF9F3D01E1284C9C02E2
+:104860001166FF4EC5FE597FBD867DB1A96E8CFED7
+:10487000B97D71670BF4B74F0178AA7090F6C30C3D
+:104880004E6ABF99D99F49A6E0EA5EBCC1BB848D40
+:10489000B7F98A0D5EF42BF50A7BB1EEC507D69FFA
+:1048A000C3F039E1F292994EC60ABD5EE3FBF6E72A
+:1048B000A6B2EF9B2E13DF85FF8A7D7F11EB874425
+:1048C000FD6C70952983B128C90B83CB847FA3FC31
+:1048D0004907B74B9F403BEB44DCCF703BABCCD799
+:1048E000B704E95BB859D1EE9346F7FBBF853EBDEF
+:1048F00013ED3436DFBB2EEF2847BB6AE7D653777C
+:104900000510AECB80F4F989C987065C1A8EAF4BCF
+:1049100088E7275C60D859B4CE975F66D0B5493A2E
+:10492000BB86DA093B8BE7BF3FB2AE7E9DEC968A31
+:1049300018CF3FDDF6DDFA55B2A95CFF767DA422E3
+:104940005DFE42DBB5F5B8EECEF2C4DE98CF483757
+:104950008BE9BD550C8E59B2E68C23BF6C0A66B448
+:1049600017B73DE7694E32FC6EDB3A75F2E519D6B2
+:10497000114645A2B3919FBDD72A674F20FEDC8820
+:10498000476EB7F630F462FD504C5B85F89CBD175E
+:10499000C2B81FCDA6EFB2D13174B755DFCD92ADFD
+:1049A000F33A5EF3F90854BEDF16FDB375FD250733
+:1049B0009F8F13E568B6CCE5FFD3CE278578E276E6
+:1049C000C46F32F5FFF79AEFAC001B27F8D98F13AD
+:1049D000B28D93AD5FBBBED21B4092D11F5F0E6103
+:1049E00084A778411CD08FEF0CEC0BE9CCDE93D57B
+:1049F000414A5DC1A190CEF4AE12D2CA307557843F
+:104A0000CBF03BDB1F09F9E86C25BD3A92EF6A4514
+:104A10003DBA0EF3247F6BA87CC3487E2DE56F9BC7
+:104A2000C4E5F304E7ED03A887AB51D930B8D60E3F
+:104A3000BCDE8C7E80D2DD81309A1AA58130A01E2A
+:104A400036CA7B07DE0D79D08EDB1D002FE3F7120F
+:104A50003502E6F6EB06FE1A525979409407825168
+:104A60004BF9868193CA420C453E51EE0BC5A8FC1A
+:104A7000B68179651ADA31BB032A7EF757C469DC3F
+:104A8000B37F718D83FCB18B1C49B7495F2516CD6F
+:104A900022FDBE588A9DE464F4A8FF458F07ED8788
+:104AA000C4EE6913F03BD93CE44F92FF2FEE47313F
+:104AB0007B94ECA0807AE014412F679A1E3D785ECB
+:104AC000417E607E4E9110E7147A432A85E3EB85A0
+:104AD0009C4E8CA3D3FE676ABF37EDAFA6FC3E4B5E
+:104AE000BE404D46701F2D07997E60EDFD113D8241
+:104AF00074572A78DE1908A7507F6CFA0684116C67
+:104B000099E113EBAF9BC7F21AD23F4AEDBBE6F037
+:104B1000BC128AE9984FCCE47977453C85F9352772
+:104B2000F1FC2683CEF088950FE04F44F7AE91BCA0
+:104B3000B70DCB1306DF80BF0DCBD79CC1F56CB989
+:104B40005CBF13F1BF69A0AB6C29EBBF08F981F51D
+:104B50005FB4384CF432E872A7E6A0F5D6A0CB9D3E
+:104B6000DA2C3A279859C4304113D2881E334FB8F3
+:104B7000DEA1E279C7298EE483129E4FF5780759AA
+:104B8000BD4DB5B3A8BC52760AFF00F7873F28FC9D
+:104B900001D5CCBA40BBE341B15EEFBC7D6A11B632
+:104BA000DBB9F97F11BDCF741653BB35B5FCFCE6FC
+:104BB00019B64EA39FEEE9160FA53F62FDC598BE3C
+:104BC0007EBCC543E90F5A544A1F617A1CD31E5656
+:104BD0009E42BF032B4FB17CFFA0A311E5FFF61649
+:104BE000669AB1F6B7B5783E96A7A0BF42A5FCBAC3
+:104BF0009610E5BFED685AE1E4FE14FF3436AFA726
+:104C00005EAA21FF5EF875473489F356A174515DA1
+:104C1000FABB819F6F3B1A5622BFFE7050A67140AF
+:104C20001EEC3E2573BD36AC37E37599F7171CDCD7
+:104C3000707E3063BD4EACF7D87E0E377852BE2CF6
+:104C4000FDF520BCD3DE12F085522559FA5B8FF5B5
+:104C50001EDD2FE00B24BB4FCE5CEF0E1CF7E4B73C
+:104C6000047C15C90DE7651EF7FBD89FA784DB2BD5
+:104C70009F437F461DAD035B25933C6F5CA24B0EAB
+:104C800046674FE9601CEB4DAF8B4BD56CFCE025C4
+:104C900071C9319DDB190E96F7623F2C3DA59695A3
+:104CA000B37A1BB1BCC0548EED597AD2345E1EFC6F
+:104CB000A6B57C446F378361A7A6D0D91AFA8A3586
+:104CC0003FD5C1F5E3B3CEDFD623BF4F5578F97F8B
+:104CD000631EEDAE45B6FA3E9EFFAD51BF90B7776D
+:104CE000C83CEF29E1F32EDCEC49A2DDB57E61473B
+:104CF000E8D2407ABEC5E7246A316FCC6FFD399B9C
+:104D000043979AE653FC85BB6B2F9D967D5DF16AB8
+:104D10000E8898D6DDA97DD32052FACFAF5FBE6A48
+:104D20005A37705D9920D6850973F9BAC2F0A67317
+:104D30007B95E36DDD1956BC159D69C5DBBA33ADB6
+:104D4000782B3A2B37DE7E29C6CF863F367EC43C91
+:104D5000FE8673ADE3979C671D7FC379D6F14BCE7A
+:104D6000FFD4E3A7CC7CD3576F1D5F6DB08EDFD728
+:104D7000601D5F3DFBD38D6FD0A76BE02EEBBA5E5D
+:104D8000170533FD12035D21CBBA1EE6EBBA51BE07
+:104D900066E0A7215CDFBDB8BEA37FA696AFEF3368
+:104DA000DFF928847EFB7567EC09E13E631DABBB30
+:104DB0006F5A7ADDD879C68D8E4759BFDF3989AFF2
+:104DC0003303673CED41FDBFA696AF3309719EDB0F
+:104DD000DD923A788D2B3DAF828497F67B467EC478
+:104DE0005E82DFD5231F266A1DC25E2A6B8B305B75
+:104DF000D473926CC9774DE3E537B797B5E9E84BC3
+:104E000091F5325C87FCB5F0E76919F65BC6F806E8
+:104E10003CD9C7E7FBE2F4F8936DE34FB68C6FE43F
+:104E2000BDD379B92ED734203C9BC4BEF906F9779F
+:104E3000A45F8E1F7CD3DB223566F8783E0D1FCF32
+:104E40001BF0DD2ACF68D06BFE9EF09D66C3DF6944
+:104E500036FC9D66C1DF0A79EE31E1CF5EAFC7C691
+:104E60009F5743E426791CCA1190BD199755711EAE
+:104E7000C4FBAB93857CE1F818B7B344494EA9E273
+:104E8000E54D6C5D5B2C8B7D98A8DF68CB1BF62B0A
+:104E90002E4747C90F93D97E5580EB6D6677841FE7
+:104EA00024BD1E26794AEF3BB81F4396A39168069E
+:104EB0007D7087CCCF872535DC8C70CA0185FCA836
+:104EC000D9EAF7C992B0AF75CBF94E110CA59C0881
+:104ED0004708283E090E7F59BB60FA683814391A12
+:104EE000C3719CAA02F7B171DA8B2FD4CC714C8FAD
+:104EF00018F08422048FA2727814391CC9E407BE0A
+:104F00004FE67E0BA31F06A1683F0468271AF0AD89
+:104F1000F6469B97A03D5FAC109EDA0BACE7E5BF71
+:104F200011F37A41A4ED59CEFD00A331307E69FC26
+:104F30005CB24357CD6DF0205F6A10F6A0BFBE3D56
+:104F400090399EC848ED766782D9A598EF6076299A
+:104F5000A6ED81271A71DD39887C9CE15C7B44CF0A
+:104F6000851D9032ED3FFDB53E4859FCA74982D3DF
+:104F7000AB9558BEBB43E59676AEF132D9F3ED0161
+:104F80004712438DC682BF43C06FD4EB94E31E35F6
+:104F90008FFDB23B6485F7F8E18FB7F7BBFAD54CCC
+:104FA000707D567833F8CADEBF52AAC4C92E96A3C4
+:104FB0002133FF3B5D9C4F95524F9CDBEBD9CA7D63
+:104FC000BC7D8095A35D1C886A78FEC2449EE2C4C5
+:104FD0003C280726FC4C14EDDA5DE23C1AE2E4AF13
+:104FE00095B47833F291A742A1F3017B3B23F58975
+:104FF000F69D9F7CE735928F711E920F4963F29365
+:10500000619CC7E4C878174B37C9910998BA8E38A4
+:105010006399E4649C8BCBB1271AD53C3CD4242300
+:10502000FCB345BF7D06FC7A9CCEBDF285BF3A4FEE
+:10503000F867A7E19FE19A43F07F0ED36CF04F171A
+:10504000F094427800F7EDC8A0D82FC0059AF95C1B
+:10505000AE57F45B2AE003B88EE8669477093CE427
+:105060003B9FF979CEA7373D9F46319F7373CDE7BC
+:105070000B623EBD2EBE5E791AA35A88F1554916C1
+:10508000BA2C15FD6F1EA1CB75C7C4575FCD731E1B
+:105090004BD3F35822F8EAD25CF3880978FA9C30B3
+:1050A0006F3FC6CF4C16EB0D3459E8B2C5E02B3735
+:1050B0005F3700AEB7D0E576D14FBEF3599EE77C9F
+:1050C000B6A4E7F33D41975B72CDC754BF55D46F8B
+:1050D00013724576CB16D78E36B43F1E93A31DAE02
+:1050E00039E9F158BD4E73BD89ABBB8D7A6BF0BB0E
+:1050F000B468A45E8F185FD845F7D37E6C35DA1894
+:10510000CCBEF9E2EA171AD01E67ED3650FF51BE49
+:105110006EB276B799FB9FBDFA8E3651EF4EACD783
+:105120007AF611A3FF4DE6FEB7B852061C77131CA2
+:105130008D23FDDD63AEB7D4D5DFC6CF092BD403F5
+:105140007E935D13CAEFDCC7158C2506D15F090578
+:105150007D687774C8F12D83C80FCCC87B907DBF64
+:10516000C91D9124B67EAA91F8C358AF4477AB4EBF
+:10517000A45B43FC4798D71D10C5B8C83BFDB76E6C
+:10518000C1FC0AD9A3BAC3686F697434D41B9429CB
+:105190009E67B514D3715D3C24C79E7191DDC3BA7F
+:1051A00064E3DC54AA25BB25F4DF82C4ED0E0ED7E0
+:1051B0007AFF250984C3CDE0C2F8E0D536B8D878A7
+:1051C000B42FEF1AC7E36D40865A19FB73FAC2D8A1
+:1051D000DFC0B81B09DE44AB5BC5F689293712BCBA
+:1051E000AC2C4AF179AE38C1DBE9F2A8188F77A769
+:1051F0007FD9268CB75BA117517D8203E73FB99A0F
+:10520000E0F7423CB5A40AD5575FC481F02C522880
+:105210002E3911DC40FBDBEE456C9163E376D76EF3
+:10522000D0B1DDC1453E8AAFF306FA00E3AD4ACF07
+:105230005700E380BCC13EB2334BCEF3F17C05D0C6
+:1052400038259FE7F1B22E1854AB595A9AE071C72E
+:10525000DDB54DFA12B463E6F27854D0232F617CA9
+:105260005B31887FCE8A01ECDF35D109CE709ABEE2
+:10527000A57D23ED8B6219E465A45E32CF7AA9FC8B
+:10528000EA9524E4FCEAF5E5592F9967BD14AFE7E8
+:10529000860B8A32C57B8CF0FD0285EC0F23BEADF8
+:1052A0009059FE23F64915B7DBCDF68A0B94B4BDB1
+:1052B000827CE65C9C138E156FB606779BEC9BA0F8
+:1052C0005210A4FDC669701AC9E518ED0FB5E8C102
+:1052D000DDAEB1E78B129632F9C9C7AABF06ED3D24
+:1052E00077F672FF8C0B43A4CFA67F4DA48B793A3F
+:1052F000937D9F8669B3C87F4DE4173747328C573B
+:10530000AF703D5C0BD19C74F00AF80FE0993F6BD5
+:10531000522BB3FA19CEC78D3430CD61B31BADFA21
+:10532000CE23EB0D74CE51CBE307DD288C283761FB
+:1053300020FDE282945A4DE78B91C225E3D3F2E33C
+:105340000A8D27F9F93F654E90E6127DC288473BEA
+:105350009FD8F92260E38B4FCB27171F273EF127F9
+:105360009C79C98FBF2FCF7AC93CEBA5F2AB174808
+:1053700048F9D5EBCBB35E32CF7A295E6FCDBF282B
+:10538000C2DF7AFE2AF4C3F8BFE8B1E4D77CD16764
+:105390002DFF52C092EF39D7DA3E709EB57DCF799E
+:1053A000D6F681F379FB273BBE7A36FA79F29593EC
+:1053B000DFFD8D7252EBC95DBF64D11872E5D16912
+:1053C0003FE99535480571FD62EB9444692499C124
+:1053D000BE7B4EC8FFF32EEEC749C83AED6BFFD92E
+:1053E000E7F90385FB8D8CF98E05AFA17F7FEF1464
+:1053F000F696DDFE1AF1EB1C3E7AF454D42380C1FC
+:10540000D2A06A6C6AE8C7055F184345BC357D7455
+:105410003E6DEFBF0BCFEBB8DF25D46482E33937A5
+:10542000F7ABFCBCAA2344E7B553EE08E13EBD6BE5
+:105430009294D1CF7244E1E782D5313FD9199D9A38
+:1054400087F461D7247E8FA9CBD547FEE3AE2A6BC4
+:105450007B8FB01F8E287CBCAE957140FB7FF5948E
+:105460003B9A715C77EA5F4163707F77529CE247B9
+:105470003BDC7C1FE08EE880EB8247D3E9FCDD0E4D
+:105480004FC2881B82BE509369DE4D6ECE373F6798
+:10549000F3C9675EEF280AD557231C7FD9F0B5E31F
+:1054A00018F175B99BF7AB85BC84AF837540EB09E8
+:1054B00012D2C9E84824D6F0FF06C1CC6FF6F51821
+:1054C000C027F8ED28E535F9E29CFCD425FC30EB4B
+:1054D000D00FC352EDEEAFE5E4E74EB19EBBE1EB7A
+:1054E000D4AF5B8B4750DFF96AFBE052C22F4460B8
+:1054F000BCE03B82B73DE2C0F30580F0666627FA68
+:10550000C675855339FC629E5AEB7A77ACEBD96C41
+:10551000375BCFFCE9F5EC20F49013768D03AEC831
+:1055200074FFC358CFB4E0C539E7DDD5C2FD5600DE
+:10553000B7403FCEE76527F1B3A306F4F58C5EEEE6
+:105540005A99E21CDC913E5CA4C15303296F61F6B9
+:1055500079BD2AF84E0BE51E77ADC0F71AA4D389A2
+:1055600039EC2C7434B37DD9AB9DF7AFC2FD5BF140
+:10557000022E07237C2FF759F87358E17E8D2EAF4A
+:10558000D64AF12C55DC3F62EFB75BC06997AB445C
+:1055900096FB3486DCFE55D1B81EF2F491DFC19043
+:1055A0002F4DFB57D2735D93DA3C88A784B681FCFC
+:1055B000C4076B14C07B30767D300287C0FF59D0A2
+:1055C000E3C1FB4ADD2F3BE9FEABBD9E17376526E5
+:1055D000BF9EBFD6AA7FC7D227777E4A7DF21343EC
+:1055E000EE47EB135A7F2FEF6CDF85F4E9F272FF81
+:1055F0007549A30E4B4CF3ED11E32F768B75A18209
+:10560000C3D1E552EBCD742A66DFEBCD7A330B7D47
+:10561000B2D1FD220C069C9386C33EBF87DCBC5EE4
+:10562000098E3F6D6C3C8CA603C7C32A77663EF893
+:10563000ACE6D3E6CE8F8FEF16F5EE167835E6356D
+:10564000969C18FDF70B7C152FB0E97D59B7D0DF7C
+:1056500069E0ADD156CF63AD67E04776737BC5583F
+:1056600027C6EAFF2D85F387BDFF6C72F89B1139C1
+:10567000D4C92F6B8CE3861F4448EE985EEE9E09DA
+:10568000501018247F01DBEBF378A76014CCE73AC5
+:1056900076FD65E8FF6CFAC8BE6F19ABBE12547296
+:1056A000DA49865D5322EE4D7A443CF00629F339FF
+:1056B000CFB09023A6D8F38AEBC33011DCB74114E6
+:1056C000C4FDBFC8402BCB8F0F2B5A37FA3FE48560
+:1056D000035B597EDCCFDCD01D4697CB82810186EF
+:1056E000AF35114F14CB2778AA46EE69F59D8A7E17
+:1056F0002D6E7781F396D7F01EF0F88B6440BCBA1C
+:10570000611EC5691F5CC174D8CCD1F08C9701268D
+:1057100096B054F807E8FC10B7945FB1AD8B8B4C92
+:1057200079F4037BACEB5EBEF3B6C393ADDD98F0CA
+:10573000A4F7A1FB717C37E45ED78E757E23766D6E
+:105740009EF332EEA319DFAB869DA0E1FDF66189E1
+:10575000D21386FD94560E7B299D345C0A1A235A77
+:10576000C57031A5138727D2F7F2E1324ACB8627DD
+:10577000531A1AAEA2B478F8144AD5E193285D2FD3
+:10578000E4B0687836E58DFB6F85C333295F30FC64
+:10579000794A03C3F378B9384F5DBF3206E8AF5694
+:1057A000701D62F2B17AE1525A97ECF35AEFE1EBD5
+:1057B0007087B827DC61D3DBFDA2FC510F97FBF5A6
+:1057C000422E408E83D96F7E8FA8B7BE3A46F677B9
+:1057D00087B11E962DB5AC87F6FA1D59EE273F6DA1
+:1057E000940B78A0B6690CFAF0F357773046F706B9
+:1057F0000062A497408E59F46E87017F9EF708D708
+:105800002F7C9AF8D8CB0419430BBD5FB8BBF901C4
+:10581000D43BE7DC78C56E26771FB863377970DC38
+:105820002F5C454CF7FD65378750BFAD5F7807DDCE
+:105830006F42F31BE39A3BCFB925FE00711DA3CB4A
+:10584000746A77ABC7740EDAB5F4E6E687587F5A08
+:10585000BB033413BF56DEE203CDACBF0E97966197
+:10586000FB8A1B4A2CDFCBAF29B7B433EE49842E19
+:10587000ABB6D453179C6CA957387F96B59D382783
+:105880000FD49D6E69E70E1878E5E7888CFE96F5D3
+:10589000A353CA4CC7B887EBCB6C7C73A187AF6BA3
+:1058A000E9FE73D32D5BFFF9DE0B49F347D6799000
+:1058B000BD1B4F2C5A80F6945B8DD13D9563AF7F15
+:1058C0007CE7916F3DBBBE2A447D558AFA44A234E1
+:1058D00080FAAA14F5889752A3DEB1DEB75D8BFA81
+:1058E0002660D2377398DC67E0878037B7BE3945CA
+:1058F000944FF1727DB356F0959D6F42A2DE5AD45B
+:1059000037D3C6D637216F6E7D33538CF78FD6379A
+:105910005DB3EE887D8BE5BCA7DDDD7C3F4B3B674F
+:10592000DE4879A62F642F2BEF3CF596F8FD263D37
+:105930000287FF93F3A5E087A2B956FD61F45F10DB
+:10594000B6E911431EFE46B93E22F8351B7DF67FAF
+:105950004AB93E729CE4FA88A77B019E2FE62BD7BA
+:10596000A3EB1FDF79E45B4F6F80D459B82F99EA1E
+:105970004BAE42BF9BA32FCCEFE5C5286EA7EB39FA
+:1059800097F0F370FFDF2C4FE43CE49F599EE82230
+:105990002F6B7F7D953601D76996FF227E37E5A371
+:1059A000B67C93ADFE576CF90B6DF59BCDE5094DBB
+:1059B0009B80E78B89BD2E3A1F4C688EC64CFC74C9
+:1059C000AE97F3CB5E4F3486FD9D983C7902D2852D
+:1059D000E52FA5FEBCBC3F96BFCC965F4AE3A7F37C
+:1059E00057D8CAAFB2955F63CB2F33D7EF3A32F9AE
+:1059F0004E7A7FE3972EC07B0976385F117AA273C7
+:105A0000CACDB1362E973761FBCEA9B7C42F05E2B8
+:105A10000BF2A33903B6FD1FE33333BFEC15FDFCD6
+:105A20007CD28DB46FEA64FB278A63443F5E06FC38
+:105A3000FCDA2BDEE1D2AEA4FB0F89B2EBC9CFD1E9
+:105A400059D146710A073585CE67135599DB1B7E00
+:105A5000A6CE8ACCE708BFC6205C933D0235DCFFAA
+:105A6000876270D481EF0971FDBEBAAA83F4AB924C
+:105A7000BA92FB37CA62E4DFB84FD04F09C4C9AF4E
+:105A8000E0AE8867DCD7778EE0C3EAD7DC69E04315
+:105A9000EC234DF820396CEBFA6037AEAF096F6636
+:105AA00039FBB197CB992B94DFF8A3E7CFD7872D9C
+:105AB00078A925C3BE36E1E271F2FA24EE0790D947
+:105AC0003866BF827DBC9179DAF6D9F70A3C25BCED
+:105AD0003CCEDEE8CF0ECFC3A2DEC35EEE5730E68B
+:105AE00025AB7C9CB1FA7F162F6BA11F40B5FB2123
+:105AF000AC7AEE1651DF15B4D6CB869F9523F8E12C
+:105B0000F15806FF8EC5EFC6387B112EDACF66DE60
+:105B1000876B87E752FCC64128E8EBC67DB3ACBE75
+:105B200086711C37B16D12FA4557C93AC527E81A74
+:105B3000A80FD2F9273F7FB8C9797218F59D47C4DD
+:105B40005500C655044D7189C2CF79A7FFD687B1DC
+:105B50007C85EE56F17D9361EF641EB77A7805C5BA
+:105B60005374B19D3A8E7BC85B99C4F7AC9C453D9C
+:105B700064CF3B9D33E399E24C651FE7DBB30EAF87
+:105B8000233DDBA1F17B371D72CC53320D5DD53A3D
+:105B9000C96B97963B7ED11E07E952EDF187567C83
+:105BA0004DF771FA26C4FA9BF0869BCDF149219FEF
+:105BB00097CA87BD56F83A11BE00C215A778D244DD
+:105BC00085C381783B5EF019E32A558E28E22508CB
+:105BD000318A57F184641AD7E1E7F8CD362E68F29E
+:105BE000FBE6F7638E173E47D6DF18E727197CC41C
+:105BF0004FDA024FC336CC3FE7A4F5D43ECE7E5FEA
+:105C0000EC349FC92F2CAB317A77C6E8EFDC713CBE
+:105C1000CE5BAE00F2E32B106DAC62F35F55C1DFDB
+:105C200059940363C44554D8FD15D9CEE5F8F988D5
+:105C3000719E53FF073EAE4FC40B14C020058B1658
+:105C4000A14A9F8CF1029AC4DF81084B3CAE7C3E96
+:105C5000C59107BD9F75BF8BA95F29B21E8EFA8FB4
+:105C6000A15F7990FC5C9F79BF63C0EB85BBA95FA6
+:105C70000C4D3D5A9AEE17F52F39950E1F3D8AE7C8
+:105C8000664E30FE713B5C76F07B55505E48718706
+:105C9000AB83D77BCC746DF5555BD65745EDB84ECD
+:105CA0002AC47B9FD7440673F0E56A9423F42356F5
+:105CB0005C1619ACCD5ECF805366D3CFE40FED50A8
+:105CC00062C956B4172B033C5E558ED3F948A754CE
+:105CD00032ABBBCEC4BF154A0AE12AA88BE818CF65
+:105CE000D859EA08631C960C3DFBE87D27E7A270B3
+:105CF0002E79952BE4F7CCF3D9ECB3C681AC1A839B
+:105D0000DF570B7D9DADDCA5846399F4F0E33EB1D4
+:105D10008EF932977FEC6F78D49761DDD921F454F6
+:105D2000673153A59FE3EC837C2057EC790DF1B0EC
+:105D30007ADC39B9F5936AD54FFFE58FFC04C7C902
+:105D400001C7B399E0007C4C210FBB5F5D40C18867
+:105D5000E978A020E76B8C0392C6D37928FD5B5BC2
+:105D6000775F0AED6ED7924004E9E78C6C035C47DD
+:105D70008DB82067C4F7B683E8399FC707D5723F4F
+:105D80006B84FD477164F373C78D396DF95FD9E991
+:105D9000DCF20CBD1761C06FC4A9DBE7F5A4BFE15D
+:105DA0002DDF9C4CF8C86F1FB491F10B307ED9C029
+:105DB000D6778614E86B5129DFDB12A27C4F8B4625
+:105DC000697B4B2DA56BB0E93C8CFF8827AA703FFF
+:105DD000127A207439ABB2116942712D5B17E23E21
+:105DE000B27B240FBAC4E0EEC6FBF1CC0EFDAB6F64
+:105DF000C342B443BBC5BB3BA0772C44BB2C9DBF67
+:105E00006B35DA85DD228E565D73DF42DC3F6E9C9A
+:105E100064EC93239EAF9AECAF297E17F11FEDD56A
+:105E2000A8FDAAD5D89F571679D8BED09A8708C2A0
+:105E3000E3F5F0FCB9FEA7081E52016CBC0BFC4F49
+:105E4000537EE314E17798D634061EB91FA3C3A787
+:105E5000713B685A09F929947018AF17C0C66201DE
+:105E6000779EFDE0FE87D6BB9733AF9769B919637C
+:105E70005D13708C457F860EB22F500FEB38EE2BE2
+:105E8000FCFCFC788FBBD1756C7851E60EE978F597
+:105E90006BA72F76869FB52F88F4A7AA58BE70519E
+:105EA0004A27F1CD73DC32BFB84FC6E68BF26FE004
+:105EB000D9B03BAE433A8E4BF7E70A46E8BCCD2B50
+:105EC000DE13CE17DEA53ED5D20F3CD65096EBDCC6
+:105ED000655CD481414623FAA2B4D127823578BECD
+:105EE000385262C917CD2DB7D42F08575BCA5DEA67
+:105EF000C996F2BF954E5FF7A916BE8EDAE6B5D009
+:105F0000569E6FBFDE154E0DDF83AC920D7B740382
+:105F1000DD4B3E883846FDD83793EEE9428D710F50
+:105F200001285EC5AB45883F7D10A6755AA9B0DA39
+:105F3000A972D06AA7869AF594D12FC6677B572895
+:105F400034EEC83A15E0F120C63919EDD727A3AAD7
+:105F5000FBDEDE2ADE2E6CBE7F6F4F65715E4677FC
+:105F6000EFABC63E4FB58F13FA4AEE38357B7D084E
+:105F7000C8DA0193FC656F27C301D3BB1A5B91F6A6
+:105F800073D2F88F6C5B427E0F37303B9AE17955C4
+:105F9000E84288B17976601546BF04A68CCF3B42B3
+:105FA000B3548AC3D7385D1D1E2E27DFF16B967858
+:105FB0000E6780CB89516F2CFADFE48478A6F5EC6C
+:105FC000153FDF271FBA35FE27DC5FEA2F01BDE34F
+:105FD000DADF324CEF5CD6A5CE75A2DFE435FF7870
+:105FE0009A4FDDEE88F36C533F75C0DFFB66FF9C74
+:105FF000667FAAE11F86C31E8A0BDE9EE271C1DBAB
+:1060000053FFBDEB28E6F73AE85DD1EDFB72DB57B5
+:10601000FDC2BE32EAF5EFE5FBD57E19FC25B9ECF1
+:106020001C71FF6D66CA1677288313E97F68A5E6A1
+:10603000447BA7BFC523E1BA3F4BCCB32E1571E219
+:106040007A3AD6BC76DAE86BCC13EF1FE23CDB037E
+:10605000FC3E60BBCAE64B7CCDDFCBCE06EFC8BEB4
+:106060005FCD8C0FA580BF7BA1B8626AA6798F75C2
+:106070004FD180AF03E19330E5707504391D3A428A
+:10608000B9E9B04AC067D46B0F723AB433FB201F32
+:1060900078E480151E66E34968170620D9486F9A90
+:1060A000E9F012EE8348556888879DA97B105EBC95
+:1060B0007781F67C719D7439DEFB8871FBB0A02E70
+:1060C00095DA1124F3248AF7324A0707526FB1F2A6
+:1060D0003DCD7E7AEC49BD7C7F0AFB91D521929F14
+:1060E0006E1C8CECA3C91D68EFACC63F994A9FD0CB
+:1060F000133A07ED0F19B85E6012A7C9E3857D92C8
+:1061000041DE4DE7FBD25177BA5D36BCD9ED4E3753
+:1061100034E5D657E2BC5F67FFA1BE516DF723ECB3
+:1061200076AE3D0EFE0CD4E7E3F2B887F129C7291D
+:1061300082FB3CF81E82B3D6A1E23BCC4CA517E310
+:10614000FD1F7F448614A3675160909ECE1A0BEF0B
+:106150004CFF35F2B8D17E30DF236D0A703F50B06E
+:10616000A94E92F83D020DDFDD0C36ED0D67E253CE
+:10617000833F47F28127483FAE866402E34EF446F0
+:1061800007AD6BDDB5D5C5E6FDD1750149EC430D15
+:10619000FA83269F9AA63F9B5FC43BE3EF47FF929B
+:1061A0004556BC1F2B5D5606B85E1A8BFE9F761CAB
+:1061B000836EA3E5A355D06D23E9BFAE9AFCF44AE4
+:1061C0009A6EF791BCFA6B2192CCD0AE4DD0CB7EBB
+:1061D0006FDF0371C0DFA3708A7854E784539BB7E5
+:1061E000420EBA8C8AB3E2FD3803DC9FB656F285C4
+:1061F00071A8B559FCCB350592D0FF833C9E6FDE6C
+:106200009E109E1FF7CC3910C2738EDE4F329F4313
+:106210009E5B20CE4522AFD33EA0770EF70BE23F28
+:10622000D43B37F13FA15A7F7713BE63B6F64DBF1B
+:10623000C51EEA68C9ED6F50CAAF88A19D71E86DAF
+:1062400049C3F5462A5F7122C235306F29BD3BD262
+:1062500051B793CE617AC2B9E962C4997688B8E839
+:1062600091F1B39C1B1E12F25AAD5F4DF6656FD9CA
+:106270004B34CEDABADCE3E07B59B9EE45791C1039
+:10628000237FB1ED5CF70D31DE1B01713EE18A7EAB
+:10629000697215FE2E874EFEB1F1B5D10107C35BC1
+:1062A0005341ECD500A36BEFBC1BCB100E7C27C673
+:1062B0004CF720F69F01BEF1050E8BDD74A83AFE67
+:1062C0005F2BEBF0F729A6D2BBF546BD9E2C71ECF7
+:1062D000271B74D6BCB4EFE9C0B87F065F4F597E68
+:1062E000F837E87C163CEF998CEDB3C4F91AA97D18
+:1062F000BD1F0BEF763CF4BA06290EAA57CA3C9F85
+:10630000730BB8DCF5AE4CF173B57907E85C2D90F2
+:106310007A9DE227BE3B671F9DAB5516707A601CC5
+:1063200025DA518573F97B80D9E4E85E413F59B5A0
+:10633000D60379D072EEB32520CECB82B9FB33E001
+:1063400004CF203FEF192D97B4FE3CD8F3C01E7A3E
+:1063500037055274AED0F18A13EFA68EE061945CDB
+:1063600025F8EFC2F4E2C6E3741CE7D60EF493F40A
+:106370001AE76C33F9BE49AE4BD1399BA740B3D86D
+:10638000EB81B0F12E627EF30CE05AC4FDC332AE55
+:10639000ABE88F47F8DA675E48FEB46C74FD8E3F59
+:1063A00036BB609CD9AFCFF75DFF6C7C7828A059D5
+:1063B000EC433B3FBAE11BC7B4AFCBE65F3E24E4FE
+:1063C0003388154DFBA46F162899F1FBD64563E180
+:1063D000F79B99F17BB10FE13D747BE6DF2732D269
+:1063E000BB6CFAEE2E231E057F24A48CFAABBA20D8
+:1063F000C3BC8D75F55081F17E4FCC87EB46B53E21
+:10640000DF87E33FD473A90FC77D68536E7A1AE321
+:106410006F11E78B49F1EE88519E147CB9D5A6E740
+:106420005F16727D8F90AF873C511FFD5EC5AE8BAE
+:10643000CF3B89E1AF9AF105BA14B52E28C9357E54
+:10644000956EDB971CE3BD96DE025B7C6F9EF73496
+:106450003F2D5EB622FF9C8E78F877927B67AA88E4
+:10646000E4A9FA1ACE37D5970DA5705F3B79A3231F
+:10647000A9511C4B8CF052768DAC514C9BB8F77ADD
+:10648000A258DFC1798BA312CBF1DEB88A6E17F563
+:106490006B140F73B7F5F73F1EF244DA14B47F1391
+:1064A00014E908D53DD6DFCB9808A6DFAB60E396AC
+:1064B000BDF92EFD7E4A99ED77413E2DDE77FC83B6
+:1064C000F09E94C167D6C79A04D14C7AFF3F055F0E
+:1064D0006AADBBF93B06F100BC633AE760F42B41BF
+:1064E000BB608BBEA11EF1A927203C25831EFB6D3E
+:1064F00081DFF81D9FDDF8CE82AB82DF3F5BBDE41C
+:10650000C2C11D4C656DB9A5C1721FC0A4177E5BC9
+:1065100040EB13D70B49BD89A7879DC427537A2029
+:1065200089BF83B260637CC085A27E0D7F87BA2C51
+:10653000A14B0ACB5733F395750F93AF005E7F31B4
+:106540002423C447F06A687CFAF74E2A07AF1BC0C1
+:106550007DF11EB62FC6DF51317EAFC4E097897141
+:106560002B7F4C4958F3136CFC626F5FADC17938D7
+:106570007E4D8F03705F37AED9541FFB83A1771F09
+:1065800066E34FD98D0F33B2B42F77FF32C45C85E9
+:106590000C9F4FDD1AF8652D9BE0FD3D0DA58897FA
+:1065A000873C40711107A31E7A7701A299CF9346C9
+:1065B000F1AD61F767A99FD697BC9EB1EE75BE2974
+:1065C000F1772E2AD5B7ABD0CFF92AFFDDBAF4BBCD
+:1065D00015A7D3BB15218873FB11A294B60BFE54EB
+:1065E000CFAEA8427F68E22DBF8AF7B3D452AB3F4B
+:1065F0004D2E69A4F7C046ECEE126677B3F244B1B3
+:10660000558FD61772BB355CC8EF85AA7EDE0F7832
+:10661000F432B3DEDF582859CB037AD9974DE50D14
+:10662000A27D42BC5B7E56E1799D68CFA81359FDDF
+:106630000CFCB9408C6B944330BC0FDFFFD8F48D59
+:10664000A639E6F57C63213FDF514F10E35664869F
+:106650002B51C5C7BD4D8CBBB1D0FA6E1CA83C35C3
+:10666000BEDF5170A3B49FE1FB900B1A305E65D57D
+:10667000384712DF4DBB69BC1117965B4F18741871
+:10668000C1B7CAE391CAAF50673933C8B1916E6ED2
+:10669000E47E2AFBF74BC43CDAAF68E8AB61704597
+:1066A0007673B9730721E3391093EF4B0AE7645807
+:1066B000F7DB1B691F77A838F7BA6FDFE7CAC2BFDD
+:1066C00068AFD72AE8A4BD1CA2A7B8DB43DC9F684B
+:1066D000F47FA88CFB15EDEDBA6CFD7BA1298271CE
+:1066E000C678BE8AE7AA4A0D24F1BEA92FD8A756BC
+:1066F00069181FB04FC7FD91060C8FE8670B03D9CF
+:1067000075ED21BE1F95437DF50E8C278146D56C16
+:1067100087958BDF5534F2AE40ACB590ECA1884440
+:106720007891F979FE2157F25CC4E7AA2A07647AC6
+:10673000A7BFA790DBB99BB5A617AA32D06F7DA1E2
+:1067400066B19FCB87B9FD9DAD7EBA1E876F841F52
+:10675000433ADD3F008DF3635341E4F6C24CE7B7A3
+:10676000865E117EC84BE70A850BDA45BF66F3B833
+:1067700072AF8B62D3CF3ABC650FEA5F27D3BFDD20
+:10678000F43B727D7BD00F7919DE7F62F92BDF9CA1
+:10679000AE54B2F257CB9DE2D1F968218EFB01389D
+:1067A000C85FF201BC5438DB44BF270B15BEDE24A2
+:1067B0005CA4470D7FDCE57D2E8B5EFDF6266B7EAF
+:1067C00029348D473FC5D28D2E4832FC5E69D3BB3C
+:1067D000F717F273A26F43BC03D7CFD5E2FCEFDA11
+:1067E0009F4C57506EAE9CAD56394DF7AE9E2DE482
+:1067F000F6DD7B8C8F34939C5D15482AB88F7B67C0
+:10680000FBEC0B3F0FD84FB2A31CFD69C599E30009
+:10681000BF95B0C239D63CEC701BE779D9E090B790
+:106820004919FD42CF154A167FFC2A0F7F0F29B266
+:106830004A06EF9918870774CF4F7FB380DEEFD6F3
+:106840001BE21457A7B7B9D555418AB3A378BA1537
+:106850008C60F8FED001C17F465C1D33284EC37D9D
+:10686000DAB59E4105FDCACBE57823FE749A712EF8
+:10687000E376C5221319FCAE67EA5313C1522F9178
+:1068800067BDBD52755EF51A1D39FAFB50E8C95F48
+:106890003C76BF82EBCF078FBEFD4594C3AB9F759F
+:1068A000025ECDFBF0B10248D1FE21A9A09C5FB5EC
+:1068B000DD99F11D098631EAFFEA1F15905EBCEAF9
+:1068C000097772116B7FD5D3EFCC00264F1FB60D21
+:1068D000ED9988F87B54E2E785FAE00C5C9FAE9274
+:1068E000E19B99DE1DF31671797FFFA7FE66A49FD9
+:1068F000B46DE012EAB7FF2297F95D7C28E2EB0F56
+:10690000ABC7E3261F91925332E80F633FF4FE2397
+:106910003CAEE4AA675C490C09BE6ADB5625C6E0BA
+:1069200058BEED23E297B37FF47821E261F9334E4C
+:106930008B1D71F58F3EE9389DD1F96A270C2D42E8
+:1069400039761EA6FCC18867C84972CDE35396917B
+:106950000A60F59EFCFD39BF66E5EF859C8021AE9F
+:10696000EFEDFB9DF22CE6630166B961FF56BE5E5A
+:10697000BEED1D857EC7C80143159FC7F30FAB9DB4
+:1069800064AF0F30A4A09E5ADEDFF59193F1DBF2E5
+:10699000ED1FBC817CB7DC261FEFE11F65A3EDF383
+:1069A000994536FB7C5B695EF6D1D58F1FBC17FD20
+:1069B00011EF3FF1C77BF11EED35473EBEF77B1867
+:1069C00017F66F5E15E57BF9A3AF148249FF9F5F51
+:1069D000C4D7CD0F1F79F8A1CD6CFE1FBEEE266C7B
+:1069E0007DB8E3F795E8FFF9F0C77F1D8FFEA01B88
+:1069F000762CA4DFADB9E1A9B327E45A17915F93D0
+:106A0000E6DF5714E746DA33121A93003F13A98DD5
+:106A10001ED037A4E0BAF6170986BA8BD9F7FE4F15
+:106A200014B4CFF6446008F1B36BFB3B7B6E66F9A0
+:106A30000F187DDC19E8C3E63FD141FA99890D4B67
+:106A4000976DFFF297CEA8C3D44576F8721822BD91
+:106A5000398AAE2F33BAD6A5E96A2F3F0887153C8D
+:106A60003758FE18A3E30CA427A3E38CD174FC00D1
+:106A7000FF98379A8E571559E3920EC2355B3663ED
+:106A8000E1F6D28CE7BCC63EEBDAA7BE9AD37E32E3
+:106A9000F4C25878BE42E2709D5A14B9B908E5EBC9
+:106AA000891F3CB439C8E9BC8821E6C3C70F560228
+:106AB000E3933FB8862E413C0CED70ABB8BE5FB59A
+:106AC000E357246F1F3EF5A2A2517C0B144AA7B2D4
+:106AD0003C8CFC7B09587E99C433D73EF0FFCE79BD
+:106AE00083B5BF167F3A5525FA517E0F933FA247D3
+:106AF000F282460DF56E721CCD7B5992CBC5B2E485
+:106B0000C05730AECF8EF7278B1C86FE1FA12BC639
+:106B10008D2DDBFEF639C87FD9E869CC5FC5F99FBA
+:106B2000C6CA1FB0CA6D563915F4FD70EB2105EDCC
+:106B300083D4B38AEA60F6F087AE2185D6C71F3BBF
+:106B4000D507C3A3E99EC6BF883F3AC67DF80FEDBF
+:106B5000722EF033969C8F3DAF63C3DBDD451ADFA9
+:106B60005FD9F0F7FEE1CCFAFF39A1379641BCB10D
+:106B70007CF2E8F54B86A83EB12A0DEFFB183FC624
+:106B8000E07DFF5127ED0F3BFA77911EB7EB8B6548
+:106B900059ECE8378AB83DB0EC998119A8D7DEDF07
+:106BA000F953E2CB658FBDADA0FF66CFB62795C187
+:106BB000696939C0F5C1FC3B38EFFF706006EAAF88
+:106BC000E559E2007F2FE6B3FC67D6FE973FF691CA
+:106BD000A5FFABF57E85FC64638CF39E1CB908E7CA
+:106BE000FBDE3E179E60C07BFDCEC64C76CEF362C8
+:106BF0007D34F0D45170EA6B4578EE55C2DF616C9C
+:106C00006F8DFC8A7EBFF74597D8DF465E437B6673
+:106C100055B142F711DA0B2E247FBDD15F9F0D9F36
+:106C20006A50ADC7FD80BA205A67DE5719F0174782
+:106C30001C16F86F28689CA005F8FE4C63FB8FFFBC
+:106C400001AB8A1A34008000000000001F8B08008E
+:106C500000000000000BD57C0B7C54D5B5F73A73CF
+:106C6000CE3CC24C2627AFC9D37892F09480431211
+:106C7000DEB40E0491226A505AA9F5AB03F28821C2
+:106C8000C9A4F8E25ABFCB8444F4029F8D95166ADA
+:106C9000693B70A152217690A0B10DDC012C060554
+:106CA0006F105F78B18D5A152B246314B4575BEFC6
+:106CB0005A6B9FC3CC9C4C84DEFBFBBEDFEF0BBF4B
+:106CC00076BBCFD9679FB5D7FAAFD7DEEB0C28DEFE
+:106CD000DCEA5400D93D6B366461AB5AD41409E048
+:106CE0002BFABB2AD6028400C603585DD5E0776133
+:106CF000AB5A407300FF7D45FFA7785B7BF0F97BC3
+:106D0000E5D4D6B5348FB5F157D4872605B657F2FA
+:106D1000B0914A25DDBFC2BBB61860A3F39F1FA781
+:106D2000FB2B8376D58E6D73EA3DBFA5FE0609AABF
+:106D300065EAD3F3383E6875A8DB55BC9E0E0BC2DE
+:106D400065317AF25424321BA00CE9A016FFFC3006
+:106D500001DF2B488266A8031C012959A120B5C672
+:106D6000730FAAFE62757CAC2FBBBAC18FF35E2D88
+:106D7000BB2CB4FE07732D217B31B537A641D9401A
+:106D80003E18ED03ABAA213262F0FBADD98E855BD4
+:106D900080E90E5A681D9223B49D08F181A67A807D
+:106DA00069030DFF873C74C4D18D037CB40E45BFCD
+:106DB0006FC565D14D3B04B94D213960EB84084066
+:106DC00029D2AD96B05C52A1479F240AD563006ECC
+:106DD0004CF57F93D6993BB451A2EB1EA8E6B612B0
+:106DE000FC12DDB738EBF2FC5FB33E58A09CE9190A
+:106DF000A9CB175FB1C12AF8AF28A00C29273A36D2
+:106E0000ABEF8FC679E87E268D0AB21CC6557D672A
+:106E1000740BC181888FE3F323336764126E8C7126
+:106E2000CD8EA29312F2DB27A7A82945D85790331D
+:106E3000C4A753A9CCA71F4DC399F1FE8F4FA56ED0
+:106E400095511E8F48024F41C213E10A1A1F277C39
+:106E5000B8113F6BE9B9198DBF65BC58A0BAB952DA
+:106E6000E7A487F827FE106F8CA7958A43B57B8926
+:106E7000B73E4DA1796C105A2B11BD7EE6A7035A7F
+:106E8000B91D02616E5DD0CDED5DC4E76C92839754
+:106E9000FB69D0D33A149F9BA356D7AA78FDC7B3FA
+:106EA00033245A9F0B549DBF8579D41F94BF3391CF
+:106EB000BF8E187FEDC44FE7407E3A40653EA47B0D
+:106EC000C1BB761CCF0B115CC723D321243388545C
+:106ED00050112F39FA3A33C127117D841F5A5FF6BA
+:106EE00002B13EF3FB72A195C7E54398DB42E8E6A9
+:106EF00036C3A14A0AD3734A97EF3BF09533468FC6
+:106F0000D1DA09C138FFB9429CBF98B9ED963CB4BB
+:106F10007EE3AF9A71F887CA83BE2A1CA7F85D3E4C
+:106F20003B2EE5FF54CE201082F5720548AEAE9E92
+:106F30008573C18DC3BD36888CA4D9834C5FCA4884
+:106F4000D137EC8B1D051531E8C7E7ACA73E3C45B2
+:106F5000CF59216E1CD121DF9A467C7F982E4C1E82
+:106F6000C8F795A79AB29E8B9B77AB9A9A45EB840C
+:106F70008930F12B39F63C4CCA402333F0F9CF5617
+:106F800005B39EB3C6F8D0E2F867C6A50F019CF220
+:106F90004DEC138EB36238465CB29D0BAEB6ABCDF2
+:106FA000598C43C6E94A64901DDBCF528A42BC7EAD
+:106FB000689C7823DA618BC3274978BD4E75878832
+:106FC0003FF5AEF02CB61326BB317DBE1AC9C77192
+:106FD0007D8DE025BE6EDC73C369E26B9F07347B59
+:106FE000BAC0856F02D909C38E8026A37CD748E337
+:106FF0001C12B6F5ED1FBFF47B1C9FD229838CF7C2
+:10700000FB70CDDDB46EC5974E4274C2FA04FD6EBE
+:107010007608FD31D669D6D77F749D28799E9FE585
+:107020002093FD5DFF2FF47C3FA4B6D2F84D0ABE3D
+:107030009AE6EFB286B6231F561C91196F2BDAA47D
+:1070400010909C152D8DFAF7BE2883C01FF0FD7B94
+:107050007F55CA789461F48FA6E1F381CD562F5AFB
+:107060004C48F725FAABCCD943408BC301047D2FA4
+:10707000E722BF16EBFCDAE87C780BD1B3A949F81C
+:10708000A7ECEA8C84F19FA55C6F5B8AF36B79486F
+:10709000D714C24DE7F035D85F5E20AB329A889C9A
+:1070A00005F989FEB1D5FA0EE99F86FF08DF86FD56
+:1070B0005A4AF68BEC907C3FFBBF7320FC9F02C2C8
+:1070C000FF35A0BD8AE07CCB3689E78DF96A3A1F8F
+:1070D000595380ED1DA1C4EBCB4189F5D9CFBA47F7
+:1070E000921D580943BC766920FE2DE9887F0289EC
+:1070F0000B5C420E2E2FD997FE5764AF5DB082F520
+:1071000095F84E7644EE19B1711ACE17E8B242489E
+:10711000237989FBFD9BE550B038A61FFD5D7B9868
+:107120001FCBF2901F884F7B6E22FF53B444FE3B6F
+:1071300047667CAD3C52BD267ECA7399FFC86FA0DE
+:10714000F9D32695243EAFF37B24FE13FCF6319D44
+:107150004B3B24784C223EAF3F5CA00DE46B43C711
+:107160002336D2FF8BF1D5CCC7D1E9BA1DD1F9783E
+:107170000E3A0FE8A8AC7678D894F03A14B5753A80
+:10718000E1B410F5967062D66B837FD62CD567C3B9
+:107190007197D1385C5FBE232C94D10BCA09C2CB46
+:1071A0002261779B551FFB23C3DE3A2FD8ED77E191
+:1071B0002B6CB3E6553E4438BA534A6D952B07EA1B
+:1071C000EDBA31F7B0FD2A5C8DF698FD6A629C1627
+:1071D0005EE5F02E467A9E5C05DEC5C3009E5AA58C
+:1071E000726B8EDF0C7DDF8CF19B5DF8679E5741E3
+:1071F000FCAE55C9FE7855A2F3611BB09EF69541D1
+:10720000682BBE3F1CF9D4A391BD2E8F5E5F8DF11C
+:1072100045600954539CF1AF1922AE7B466F6765F8
+:10722000D8B85D5B6D011FBEA7B7530E49485FAF6D
+:10723000EA3B7215D99D4EABC6F1951A7DE97B7C70
+:10724000BF425D8BFCCCB3B48EA3F7E2F8D9219C8E
+:10725000B7AFF35DF7ED717EB9B7E3D1511407FD18
+:10726000CC0235E124F1D0F2740BC731BD23DFF13C
+:10727000E0B2A1DE11B501E2E9C19EC66A8AA7EEBD
+:10728000746A4C97AD7D7AA480F1338FE3E3E7967F
+:107290000E61BCED3D0321D2BB59F2ADD78EC1FECC
+:1072A000E45715AF9D95CA77FDC2093C84E5BEE160
+:1072B000CB8A4DC4BF00F273355F6C3D41F27AF664
+:1072C000CF0A90DE55363EFDAE1FD7793817D13044
+:1072D0000960822F5C11C151333BD3A7937E074EC7
+:1072E00001EBEBF86E2501B720D71D2A20BBF286F3
+:1072F000080F27BE61BA0F4199E2FFC93D89D7A7A0
+:107300005E04EFFF62D80D377808EF8FADEA807723
+:10731000C92FEAFE331F17988C9F06BEF738673CCB
+:10732000922EE2769970EB55928F7F2743C4F91B1A
+:10733000BE9425C2655F14BCAB915F7D8BF379DD94
+:107340007D9F524086ED97F2EC709278EBD7E9364C
+:1073500096DFCF6C02F73F5BEA0A35E17A0E2EAD7D
+:10736000BDBC07DF77FE9FFC97AB5F1707A369B132
+:107370004C6279A511DFEF9CD722B11E426B1EF142
+:10738000CD3CDED013436F0C7DC95B3AC41F4AF27B
+:107390009EE1B43EA46FC6D291928D70BB5F029203
+:1073A00063EF6AA4EB6BE2C720AC2E207A021D9F2C
+:1073B000D8C85F3B3A255F28C9F8C3E96EE65FEF9E
+:1073C000EA60D354E4D73D8BF059D20B5B6B71B2BA
+:1073D000F983B0A1008343684BD704EE1D701BE90D
+:1073E0002528AD79E4B77B3BAABE4576FD31D44371
+:1073F0008A1B7E66F532DDC17A80EDC4160A3CB187
+:107400005F783D6C591B974776A74F3F958EF39D4C
+:107410004A5779DE4CBF5722BABD7FFBCC4DF3F7FC
+:107420007D6E67F9E5930EC7C56D9FA60BFEACC9CF
+:10743000F0BDC678A9C96263EAF5BBBD8B2B00AE6F
+:10744000EC407EC7E13226B720AF3BC31F647A32DF
+:10745000BA3171E2FCCBA751BC1CD08D334424500F
+:1074600026C4EC73A5A3305220F287700EF237A326
+:10747000E6C76CAF53D00E53280EDD8979115B64DB
+:107480007C9E749FEC42B32AE2AC967461E75A1E6C
+:107490005142CDF8DECD4A4FCA306C8B7DDA0C45B7
+:1074A000237B5FC6F3E6DE05ACDF164748223BE4EC
+:1074B0002CFD45FA85B86B2AC0EEBFC9CC7FB39CC2
+:1074C00046EB7AB126C3FF05F1756C57F420856F42
+:1074D000DE14C824B9CE925DBCEEC96785FD31DBF0
+:1074E0001B39F2AB9F91BDE9D3F3A724F6E676F200
+:1074F000AF86BD01B9EC10E167EA8B7A9AA9DB1976
+:10750000CC3E980F138FFA9B5D49ECCB24A84E43D9
+:10751000165FD4BE98E588C1FE857E2132A3A20BFA
+:10752000F528EE79B33D2AC8D0FDAF6E8FCEC1B439
+:107530009CABB5185ECA577A0FD9E3F061D8A11891
+:107540005E428C33F37B24705CE8ABA5643F8ECA4B
+:10755000696477A6A3DC71FE2E5D4FD23F0D7D8B53
+:10756000E4BFA1F39A14C2F5535D550E529B15B9B1
+:10757000B2F6678C9F9503F383A0C385EC9DF15E03
+:107580002B3834D748E28785F920ABD88F7B7F7FB3
+:10759000AB349BEC220A2D6DFE98C1EDC18A5C1BB9
+:1075A000BFE7A9AE9234C2910B30BF45F955764A78
+:1075B0001C2798716DC67133BEC0C2796335C7137D
+:1075C000B214D6F71D12F3D2E2E064F65377611ECF
+:1075D0004E716B7F17FA2D6C9F423F4F714AB36B10
+:1075E00016AFDB58AF41DF5DA93372A06CE0FA8DB6
+:1075F00036F0B90CA1CCB8BE12B5118E039FDB12C8
+:10760000AE1BFC1C8C0F063FA7103FA5FF3E3FA7FB
+:107610006608B99AF9FA3F5D7FE18A49906C5FE0AC
+:10762000FF97F54F05FFEF7B44BEF55AAE27664F37
+:107630000A57CC9697211F26503CEE8DD90707FE9E
+:10764000237C8DED68657B3309ED0DC5990575616A
+:10765000B62F137345BE64B61B5776C24D641F2701
+:1076600047302EBD04FBF129FD471EEFE3FC32033A
+:10767000E91EF7FC82E5BBF0D2580D32E7E27BC68B
+:10768000762B5EF27BD09D99745FC0EC378CB8D4BA
+:107690008847CDE38C78D4F0270D3A1FFE3DC3FF19
+:1076A00064065D57D520E91BEA55F8312FC35EA368
+:1076B00078A13BBD7A37DF1F190E721E50022AEDEA
+:1076C000EBA0BE721C56E97045E4B103F5D369D254
+:1076D000C330F285F609822E4B689834900E0CB7B1
+:1076E0008314F7E103FCFEA5BABF28C4312CB4060D
+:1076F000E0F8BF702CF8C9EF1696638BEB3CA6C779
+:10770000232F995AA4FB79E2AB5581A0BDFC1FA79A
+:1077100097482C2827FEF8FE40EB77CCF631FD0584
+:107720002A78298E2F50C29217DF9F51A74917360A
+:10773000910C3F8DF315CCD5D85F160CC53E8DA7A7
+:107740007827895C7A32ACBCCE7A47CF611BF221B4
+:1077500030B771B6DB128BD3ED56BFAF80F68F3AE0
+:1077600044BC0EB4DF379EED9244EB516608FE0434
+:1077700054915FB94065BB59A9CBB1D23197F77726
+:10778000C827DA270F5CB7A4F97870FE7CD0829303
+:107790006376D5C87F701AA0F798ED6ADFBED72F41
+:1077A0000BA23EBEF5BF3F4905BCFF27259A4AFC08
+:1077B000387DFF89541FF2E3ADFB45FEF27D537C1B
+:1077C000A4640AB92ECEACFE82F87ADBAABF4D883B
+:1077D000B72FB0329BF5E28E904CC9F005FD59BE33
+:1077E000C3C97BCF46BF3E9C99D037F4A0DE0E8D37
+:1077F000C9E2EA6999222FBA63D7161BE5D18B3308
+:10780000FDA999D83FADC77FA7DB53793FC0A067DB
+:10781000D1AE7136E2F79F3AED106103D96D157262
+:10782000F65D2F4DA0CD7BF167A6F3F0FE021BEDB8
+:107830009F2F91202AF6B5E0F0CFB1FF5EAE0C6B22
+:10784000BD03D7B1E42DD56641F92C990ED120EABC
+:10785000D5A2BBA435F7E2F8457E17457003D6B92B
+:10786000309898E72FD3E395DB1FB29AF2A4C6C3F2
+:10787000B45FB618E7A17C76496BE2FDFEAE3B0F24
+:10788000FF9CFC40878DFDC0B28BE44FE332F5785E
+:1078900065024CFCAA94E295B21F956983DB25230F
+:1078A0005E39BD0A083CF097550E6ECFAC52B9FD5B
+:1078B00042B7D7CB3B0E1C665C2BDD13C8CF3ED541
+:1078C000F5AEF3162DE637BEB9E593433FC77E0507
+:1078D000ADB398EC65C44A78BC4AF71BCBF438A426
+:1078E000E273B3DF38F087DF539E8DEBDFCE19D71D
+:1078F000A5C523B782F2693C1F0C3F62E6477F575C
+:10790000A99370323F33713FF67FCA97C19EAB9700
+:1079100011D749EC87A14F5F64087C2FDE366F4D8D
+:107920003EBEBF79DF07453DC22EBD069E185ED123
+:10793000D033DE960144D7223EFD9DFF7498F87443
+:1079400098F03689FA97F1FDDC2AC42FEAEDB2CE21
+:107950000FDF84B1AC5FB9965C6A23B9945F9A710A
+:1079600068C69F196FBDD69E22B20F669CF54A89E4
+:10797000E76446BB34539C5F2CD67CB328DF45B705
+:10798000B646E5F508FB775A693DFC43D2DB6D123C
+:10799000E787F5CFB43D4DF6A8F6B73F71933DFAB2
+:1079A0005069F5D0FBEAB63FE0F6915D52826E7AFF
+:1079B000FEC390B04BE6F775EA7C34CE052EF8A5F1
+:1079C00087A26BEE437E9C477D26FD6D68FFEB9A98
+:1079D000FB28CFF039A294779E567A66111D772C3A
+:1079E0007435367929BF4D5C77EDE33FF168BC7F94
+:1079F0001C2CD0F9C7F96AC336AB3782F336BC22E8
+:107A00007BE9350188F2FACCCF07C2EFDAC87EAB4A
+:107A10001688164E1D781FC56823BD09B4AFFB58E4
+:107A200076532BE415203EC79D33D4E876D88CE3FB
+:107A30005D99FABE888E5FE40FEFA706912EDA3FBC
+:107A40008290B0C7CDBFD938F66DA4EFCCB617DDA4
+:107A50005259FCB9C26A96477FF8F65F392C83E326
+:107A6000B757C77B2C6E09F1735A87240E833A45AA
+:107A70005B678DB8296FABDB62F506F1725D9B0C1D
+:107A80000EF25F27ED1C37D4B57DC2F8AC937C5164
+:107A9000691C2FC32DC5C511CBDBDE9B45F676795E
+:107AA0009E0C7351A56AF79C13E37D104DC1F1CB79
+:107AB00077BF3DEB87D447BC3B92C8AB2A7CC0263E
+:107AC000F4C624AFF0DBB3281E6EFECD672C8F0FFB
+:107AD000F74B90533CF0F99A2DEFD9C89F9C41C1C8
+:107AE00064A60B7E91DF0884E585B6B464F28B5CF6
+:107AF000FFBB4ABECFFB7F1793E37A3A6B1BCF786D
+:107B00007FF2774847CD9B76EF5C7AEF9377BA01A7
+:107B100071F081D22870FF8B073CE4876BAC418FFA
+:107B2000CAADB85EF3CBBB198FCB8EDFED11F98DEB
+:107B30002F4FEC1705F3689D4B367F9BD7B914FC8C
+:107B40008CC79A5FC8D5B44F734E81D9BB93E84DAB
+:107B5000659688B7ECF083B1F789F300A0FCFC03CD
+:107B60007DDF34F8B2CC719B1D6E4C9B17B7FF6460
+:107B7000CF12F62A08A13FD2B96A00DD2B9F831CE1
+:107B80003F378BE6B9AB5869A473225C7F50E79707
+:107B9000F415EF0B80A6C4C55955C7AFCEA17D31F2
+:107BA0003BF4DBFE5725C7D51AC53D71CF31DF3E0B
+:107BB000D86A1F225D89AD27F9BEE9ED5986FEC35B
+:107BC000CB1087A7C08E0F184F80FE3B2D57F41F98
+:107BD000237D5CE46A4C43BE7DFACABB363AD70AC1
+:107BE000E27A8611BDDDEF711FBCD91A8D37E60F21
+:107BF00074D863E781A4D7DBDE33E975E27DF4DF77
+:107C0000CCCF00A46994B77D608BCE227F1EC4F7D1
+:107C1000527DC1D20DF684F3C6185E4CE78BBA7E56
+:107C20001AFB9CCB4CF198D19AEDC29559897601FB
+:107C30003667273D5F34E72175D6D0AF893F75277A
+:107C4000ED9CBFD4B509FDC3803A3A0CF5E1A35DC4
+:107C5000875EBB05D7F151D89A3597DF96686F6B71
+:107C60009E42FDC5F132F23B85EDED671C4F19FEDA
+:107C7000E823175E1C93446FF17A52BD7501DBB3A4
+:107C8000FF577676D92076F6BB5903E284347C0D13
+:107C9000FCE589E597537C61E6AF615FCD76F393B0
+:107CA0004C2DA9DD04DDCF1B7CACDD7996717B3ECC
+:107CB0004F9C37356CFB2BFB31646BD48EB86D0851
+:107CC0007DCCFD07C88F71FFC07C696CB27527F24F
+:107CD000D37CFF32922DE723D1EF139F658BDB2BF3
+:107CE000F6E7543ECF6F26BF49765A5381E40833F6
+:107CF000204C7187D4F9FC5FE97DE6BC223803464D
+:107D000036F2B92EAC8BAFCF092B7A3D4530797D59
+:107D10004EB32D769E4BF7073BCF7D5FB7575E97EF
+:107D2000CAE508D62C4D4E5657E2ADB224CD237E7F
+:107D30009225CE774AB3C5BA8F650979B4C8D5FA0A
+:107D400046A3C897680F95ED5FBA9BCF83AD7A7D48
+:107D500006CE9CCBE7074ECB27C812D8BDA17A8EA2
+:107D600042FBC315963B4BB1DFB5E1F6390AE2C7DA
+:107D70003BD5B2A704FB2F6C582CFA575A2AAC08F3
+:107D8000FDC7834BE6CCA47D03CBDB3FA5F529AB38
+:107D900015A0FA91D296F7B87F97559C5F353CBBFA
+:107DA000B786DEDF20A12090FF2DEE7023D731E4CF
+:107DB00082BA9A368FB53D7EBABF260FF3799447C3
+:107DC00024CDFFDB2CF22B8E885B2BA1BCD2B7F12C
+:107DD0007B785F79D94A3921AE53EC838FDE333516
+:107DE00097ECEEFF85F7FF5B56F6E0EF3FF3D4B577
+:107DF0000B68FC68195419E72B57B42AEADB31BF2A
+:107E0000A6BCCD9043B922F85EE6B2713ED792EEA1
+:107E1000CB253C1D239C665F7ADBACD70FC94E8116
+:107E20000339CDD2B81BDB5774F9BFAAF383FE68C0
+:107E30005FA06F5FCE56AE5B816811C95796B7B62B
+:107E4000113FA24D0A6CA5FDD77D8FB7113E5FB7DC
+:107E50003978FFE8E6B4F5D62B90E47247D19D045B
+:107E6000FE37A55D7753BB2FDBDF9325E68DD0BCB6
+:107E7000B77C5F16F3BA1A53C97F820FF54AECD369
+:107E800070FC0E7ED42BA2F920EAD5383205897514
+:107E90004E663AE4B45D4CC7CD7641C78250497313
+:107EA0000FD231CE1EBA8CF22B7C7F94E4700B86FD
+:107EB0005B84E760217491DC5EBFEDCA2D627D8535
+:107EC000ACAFACFF7CFE7EE6499A2F80F3D3396AD3
+:107ED00040EAE1FE1EC5A1065561DF17C6EDBB3DB8
+:107EE0000BAD27CAC4FE7E33E51D53F5BCD8D87F41
+:107EF00033EA0D2676F9AB5C64B0E54E99ECCA39ED
+:107F00008CD7C88E99F7DD269BECEFD48E8FD82EB8
+:107F10005FEC3CD099ADDBE37CC8A77584E93C906D
+:107F2000025EDD4F7AE93C3089FEC79D0766660B2D
+:107F3000397DED79E09DBABDD1A84E0ED7D18F1312
+:107F400093DCFA8F2E82F24AAE476884F4C1FD6A50
+:107F5000BBC9FE1B381FF38A7A3BD9B331AFC06D62
+:107F6000B4DEABF5F393FED3C0F580E37A1C5C1F5F
+:107F700068EDB28642525C3DCA490BD7A3F4833701
+:107F8000C4F52B41BB1A647B3996EB4F5A4EEAE796
+:107F9000BD7A3D438560D93F5C0F61AE7F98E29E1C
+:107FA000242FACE4F31990260DAC7F9822DF2A939E
+:107FB0005D81A3429E17EA20E43299D6752E0240D5
+:107FC00029DA8457E2E48DFF9B981594B9FCE954B3
+:107FD000E2F529265C98E57F6DB61EDFE8F21FB456
+:107FE0008EE443B1AF360EC6721D89D55C47F2866A
+:107FF000850B366375241521D2B7094D62DFF8620F
+:10800000753CE63A1D731D4E9E3F914F0535572432
+:10801000DCBFACB13CA17FF9CA2909E38BD1A1C671
+:10802000F74B1F9A93307E58EB8D09FD119B6E49DB
+:10803000183F2AB428E1FEE81DB549EB5E0C9C8C84
+:1080400009AF48B8BFD1F9E4BB84AF963C59A578D5
+:10805000FECA8EFB4C7531D31817538C7D785DFEAC
+:10806000465D1D9581119FC7A3FC1F2BA6B8E9FE95
+:108070002A491B88036F24C87EFC1FC5C17A931D43
+:1080800030F4FF62FB373FD6FD849C5224519CE3C1
+:10809000C3B82A652AD5118B737B784BD4AB7C96F9
+:1080A000F2778E8B34C9ED856FD25B5589E2A07B68
+:1080B000AB348E83EE1D527480F60F7A7EE0F64A62
+:1080C000F903EB42CD75A0190EDF64E0AD11510745
+:1080D000D982869EEC7F708683E38C872D96DBAAFF
+:1080E000E3E87F225BD89F27B245BEF5735B783704
+:1080F000D901C5016A539E789E8A1F802A7B502E23
+:10810000EE4C10F561F0C6DA9985E43F7B466AE9EA
+:10811000543F8BFD6FE06525C4FEE4966685F3BC95
+:10812000D5CE27D99F942BC29F8C9385DF403FD219
+:1081300041F6F14DE97EAB88B38256924F810382BE
+:10814000EE72F6AF7C4E9C0E59D28A32AA4FBDE039
+:10815000B7B4AF104C876AA75A884FFD8B653E0FA6
+:108160007E8948427AFB6B46719D73FF85FA3F2DED
+:108170008DF2EBFEC58F9EBDBB32A697276DC9F36E
+:10818000BC8BEDBBD56C793495CE514E8E8484FA80
+:108190008C37B3457EF866B62CEA0C42EF79884DF1
+:1081A0007D4BBE184E4407A4EE352E1CF2E0A61FF0
+:1081B00054935C6CEDF382B4AF69ECE35FC8033BAE
+:1081C000A773FDB6912FDDFCBAD8D7BBF98BC47D60
+:1081D000EB8FB2C5B9C047F43E6CCBBBFCE3496E34
+:1081E000379042F0BEB27F3CC507D52A68E4F71746
+:1081F000F817DE7D14FBF3D64B1CEFD37D1A7F23DB
+:10820000CA90EE9F00EFAB7B91BECFB3053DF3A1CB
+:10821000DA4A74BEF6FDFA54C2D3EBE9627C54022A
+:108220006D6BDC7C37E8F3BDFEFDE57B294FA7F7DE
+:10823000D1FB891E7AFF3C154AA8FF1AF8CFBE5A17
+:108240003CF0BD3781CFAAD77B59C94F9642A8EDE4
+:1082500069B2AB472CDEB5C06D2493FD929DFD52F3
+:108260005F53F4C97B90CE3FD5FE75AF847CFDE3B0
+:10827000C2E8AF9FC6EBDFDD248386B8F838C32F92
+:108280007BE2EAB44F2EFE2495F889F1CAF69F925C
+:10829000DEEDB47BA9AEE3CDDA9DC3E3E3FA54CFC0
+:1082A00074073D07932EED3CADEA89C98CBF15DB01
+:1082B00005FE56FC66440EE16C45EA05DC89FEF6D7
+:1082C000523E279D2041D2FC783FE24D1BC17535BF
+:1082D000A021CEF67F2EEACAF71CCDA820FA14F012
+:1082E0005F16BF9E3D2FDD329AEB79DFC8BA243A84
+:1082F000496783687F6F665389F181AE270B3A33F4
+:108300002BF478729487E2B9DFFFE6EC7F105FF61A
+:10831000EDDCFE43D6914BE3C3C03A5A7527DB2709
+:10832000230FA3BA57CAD30E59D84F5E2DDFCF798A
+:1083300018D56970DE35A488C7A3C151ADC2BE8906
+:10834000EF24300E6EF672BD27EBEB4A55C42D4676
+:108350009E245BBCB98AF8C8E0C5A93C7F09D0FE61
+:10836000989B122BC35E611CE1962DBABD029F0340
+:10837000F3D3D1BA3D9BE5F15EDB22CE6B12E24F27
+:10838000EC57ED4A127756E33F8E3B37FB9B53D8B1
+:108390002F6D96CB28EEF03922E4C7CD71E7545803
+:1083A000CFFB0003E2CFE7FE7249F1E7F73CFF3D68
+:1083B000BFB3D4A3B1FD098F14762E1C19C2790E58
+:1083C000FE55907E0DA5BD003A07CD13AD4DEA1DBB
+:1083D000E940FDACF594AF7B681AC265A8E00FF5E3
+:1083E00051A450AA7D72E82B8A03BB15965FFF73D8
+:1083F000577CED772495A887E4EC2387A770BD739D
+:108400005F97D08FB60CEDDFA7529E8171E65624A0
+:108410003145E9B1A52759CFD3647F511FC21E91C1
+:1084200047393AC4B9A843F301D99714551D478970
+:10843000B9317EB147D8DDFAC36F16D9503E672DEA
+:1084400047DD74BE52B7F729372E179A33FD0F90C8
+:10845000FE2C3FF9F20495EBDCB61451FE1D8EBCE8
+:108460003C83E3B3D9C8DA7183AF27B0A9823E4217
+:1084700080864D99DC8EA27D15BC14888875F676B1
+:10848000346724DB1F08FCDB5B0769BD3B8FA570ED
+:10849000DCB233BB9BF520380F603BF2FB89CF4742
+:1084A000F37C0830A6E38A6A4D227FFF0B7D3D3BBB
+:1084B000F5FCB2F77399C719F38EE9982EAB88AB28
+:1084C000B248EB41AEE3EAB46B24DF946D20F8D3FD
+:1084D00099C2756181FDD788BC335D9C47B70D8912
+:1084E000FE91DE13DD67D7A84E35456D850C9CBF28
+:1084F000CD26FCEC2804FE53AED875E37D299D1BE8
+:10850000F92308C405D7E3A528ADF00D573CFF5368
+:1085100099DEFD1E11EFB40D89585CE4273057DA5F
+:10852000CA74C5E8047EAF41E7288E8BDB6CD1F7B7
+:1085300069BF1DE9520917A340D0099D23348A570A
+:10854000525471AE9EA26ADEA03490AEC05808614B
+:1085500070000FAF860B7ACE758443627D07EA42C6
+:108560005B891EC70417AF9B392DAE4F866C52EC4A
+:10857000F9139E65EB5A0A695DC20F2A4A98CFC764
+:10858000DD0B40A5F3EF14C5C77952CA7CD09A50D1
+:108590005E4E878FEF7B708EA6C9DC8F10FD2ADDC3
+:1085A000A77D9B34D53907E94EFB328D9F6BE8B62A
+:1085B00072DD79DDDF6F4A2BC3F59DB11CBC6717F7
+:1085C000B61F2D0C0FA773DA0969FEB7C81E3F73DB
+:1085D0006AD1BA3138FE2F6D56EF5CB24B3DC11FE8
+:1085E000D3B97DED13568DFCE2836FF447BE22F9BB
+:1085F0003E2BB15DECB38AFBD8D79AF07E43E707F8
+:10860000363AD7BAA6E36D1BED7FAFCCF1BF4F7AF8
+:1086100030A9A3A98AF836195A9B699F13ED21D76F
+:108620004B847385BDE87F65F8D6A6383EBB72F4EF
+:108630007DEFA8FF72D29B4E5D3FF7537C84ED5EC9
+:108640003D4EDB7BE0BBA55ADCF969100EF27EE003
+:108650006A788EEB3A8DEB7D216536E168F46B8E9E
+:10866000DB7C7138B3E5087DB7E9EFFB798EFF4B12
+:10867000D6DB03EFD8DCB8FEC09FC345E4AFC21819
+:10868000CF7D5D1D69C0A42F17EA8E4E03DB919D3F
+:10869000AF7570FCBDF33E359DF41EE98734ECEFF9
+:1086A000C5F882F4686FB1D0BBA657CF8FA5FDE2A5
+:1086B000F3FB965F4EFCEAF5580D7CCF18427AB476
+:1086C0001BD88E197A58467A28D1F77B62BFA78CBF
+:1086D000F04D7A67EB9EC37AB7D702A477886FC64E
+:1086E0003BE25BA538A44C45BCF3F323588FDBBABF
+:1086F0005FBE82EBD991BDC3C651DFC2F86A8BCC95
+:108700000949F87CA53572909EAFC4F7376931BD31
+:10871000AC9412EB7A167B449DAC611F7FA0EB6793
+:1087200078A496E6C5F14E594EC07F9C9F147DDD1E
+:108730008FDEBBF127EB36A0BE94FA2A2C1328DE7D
+:108740003926B31FD8AFC7C92BFE30E5865DE23AA4
+:10875000FBCF888E8B837ADCFCDCAA5CEE935FD047
+:10876000502EE3B1F55550BD7763156DC54D9ADDBB
+:108770007A88DA29D5E12A3A2E9CB6A0FB90F8C671
+:10878000CD379AF0D67EF05BA3B94EFAA41DE83B34
+:10879000CEF6FF8CFEF1095CFF3DFB91DF90342E9D
+:1087A00061BCA1C766FC0D86933EA9E7FAA968974C
+:1087B000AFDBF8EB6B1574E80D04045CFF9C8DDBFC
+:1087C000D605D1079EC8F15D9783F8FB22D77F5D60
+:1087D0000EF2ADEFF87F7AC89FEC7DE51D37F9E129
+:1087E000769B6F34E1AABD04F38824789C9263657C
+:1087F000FF5A3948BD49638EC8B78607611DE1A598
+:10880000A15D5643E4A77DDDD793DF781F5949FB6F
+:10881000DA4BA707DD942FD5EC3DC475FA463EBD73
+:1088200004F43FF9D659C4FF73B9223F5EBAC19A26
+:1088300090DF8E80888DCE91037E5763044552630E
+:108840008A3BEEE8D8C2DF8DD46E4B7CAE8EE2144C
+:108850008450DD45F2E3C61C7D9FA4144A294E4195
+:10886000DCF03E49F455D9BB15B8BEAA8BEAAB760D
+:108870005A049F9C0E6849CB88C52B23F27C4BC8B9
+:10888000DE2D31FC875EAF146D93F87B8A513B443B
+:10889000BE3CE5B4B685BF930AFAB84EAF86084031
+:1088A000BAA728415EFF94DC5208E2FA27A1792694
+:1088B0007D59DA2985989FFA772F0AFE13FB459B8D
+:1088C00065FECE6FB30499C5346F94F953ABEF1FB7
+:1088D0002EDF91787E51B7E9F8610A95EAC3A6F3D5
+:1088E000209D3FE6F39DA7E83F929CEFFC24478F35
+:1088F000E78AA028E1BBBCAE4BFB2EEF238A075CC6
+:1089000074F8080971F91E1D470DFABAEB42B25806
+:10891000378A82EAA36FD76112002FF3A91E714232
+:108920003880F542DE463D632D54DBA88EACBEBDDB
+:10893000E9309DBF2DD5E35A339E90A1CCAF657A27
+:10894000DD50CDE6C4FBB53A5F6A4D7C69F04B263D
+:10895000FA44DC7DA9F4A1E5FA0EE1A0769795EB47
+:10896000B9CFC1AD5C7F55DFBE85E959AACB6F2079
+:10897000BD415ECF325C0FE9D3A5D26B96DF3103E8
+:10898000E757C01509F29B9D7949F22B057539AD62
+:10899000AFBF4BE4B5FD5D25BC2F61E0C5FCFC2CF1
+:1089A0003D8EBE66938837CF765439291EE83BAAA0
+:1089B0007825C47DC5B14FDDF4FD4DF93E19E89C25
+:1089C000B4AFB3625D10EDE59EAEA13769E807CAAA
+:1089D0008F29EC372A8E9587528AA95FEE2CE53ACB
+:1089E000132D93F2009C87FD70DFD1A127CA384E6A
+:1089F0009F5949296AD3D17227C50B7B40EC6F4838
+:108A0000C72A337BE2FCCA7B3962BF614DEEBB0FE4
+:108A1000939DBA66B795F783AFB1465FA23C6C4FA2
+:108A200097E26DC27EDDB145AB5348DEBF91BC1409
+:108A3000761FEE5E9145E735F59D56D5CEF4DE7D89
+:108A400090EE077749DE61383EB0EFEAD16DB44F62
+:108A5000B4A5C24BEC35DE579EAE3D4AF5AE90E76D
+:108A6000E4BCFD9ACBACEC5FCFE43BFF752EAEAB24
+:108A7000D6B76516D9E133BFDBC375157D6D12E43A
+:108A80004AB48F7CE849AAF739F3F4711B9D075764
+:108A9000B51FE7BA8DC1FCC1D910E28EF3F6561BA3
+:108AA000E537F55B8C7E0F7F8F52ADC7510DDBDE56
+:108AB000E67E2DE50184C7CD7248C3FF3CB4EF19B3
+:108AC0003E1F6ED825EA3E2EDCDF26F17D03EF8BBC
+:108AD00074BBB51C34C6FB7203EF7A7D9481F773C7
+:108AE0003097EBB496EF7A84F1BD44C7B7B96E0AFC
+:108AF0002DB0AD2C4BE82BEDB799BFFFBB43C7F7AB
+:108B00001D17C1F7A85C1DDFA36014E1FBFC7451C5
+:108B10004F77FEF81027CD7FFE08EFBE7E1DCED921
+:108B2000EF1ED5E382FE88C567BB3236AEB7E313CE
+:108B3000FE0E3170B4DF467527B33A3F6679CCED4F
+:108B40003C3093F87D1DF8EB887FD7753A558A83C2
+:108B5000E7F6087B36A7D3CEE713D741B885E4DC28
+:108B6000B7FFF1960CC2CDAF056E0C3BB74CE7EBEF
+:108B7000B5653F9845F97BADEE0FFBBBEE9CC57626
+:108B8000671C1453BC3747FFCE7B4E58B7439B132B
+:108B9000F94EE7D424B7864E3BD79B5C0B3D36F2AB
+:108BA00067D7EAFED3EC27FBF29C2CE720FAAB61F7
+:108BB00038BE6E97A98E52E9617AFA3B6C7CDED59D
+:108BC00060F2BFD372AD09F51783E1D32CAFDB722E
+:108BD000757FA2CB6B6E54D431CC7945F6D2F94374
+:108BE00057647519C50B06DFCCF2EAD24AD3BEEE44
+:108BF000F7125ED2E37CA37F83FEFD5B586D75C5E3
+:108C0000E7EDCFE75AF473CED04F2B709D7749D064
+:108C10004D38C4FCE6867229697EB33217C73F5FC0
+:108C200078FBFA71F1F98D6FCB708AF71E44BB5255
+:108C300051C9F53BDD7C5EA8B4CEA573B0C02EABA8
+:108C400097F29A4087CCF14060973D64C179AF219B
+:108C50001C215DD59DD2D58423CC1B5A72D13ECD2B
+:108C6000A32D651C37AF03E3117C6EDECC8F197F1B
+:108C700047868A75F72B5A4EB23CC2C81F1A3E1758
+:108C8000F1AA71BD01ED008D6FD0BF4B6B3FF8D7DE
+:108C9000A2E2543AB7FDAC6821C5A9B9227F31E2FE
+:108CA000D528C6AB257ABC4275174B85E860E973B9
+:108CB000F7D9C87E1DA61FB6A0FA49D5BF86F261B6
+:108CC000D50F8D3FA240436A613D6A209D221CEE74
+:108CD00095C4FECDB356AA0D81A69787705D60EF4F
+:108CE0006BE21CCAACEFBD8BBAD95E9C5FE86A240C
+:108CF000BC2D2FDBB206230C18BDFF75B637A37F42
+:108D000067532D6A6C5D4DF4DD1DE7692D09F17225
+:108D10006F47B38DF7A1E3BF1B2E19181FD55F64F2
+:108D20001FEB79935D41FA39DEED3B22ABB42F8422
+:108D30007CFC657E3CBFF478A8FD600AFBAFBEE317
+:108D4000AE10C5FD7FD1F17846DF976F9A24333F8F
+:108D50002C93453B7AFF3325245F92871FEDFDCE90
+:108D6000FDCF5CE1E37DF490A823DE9158875D1F81
+:108D70004EACB336F81AD0F98A740DA7EF950DBA38
+:108D8000F62A3D6E6F123D92A4832C2F8B9498E7A8
+:108D9000069E95ABE3EB48713DB791DD3B69E88BEF
+:108DA00012F5901F7E2B5763DC34750AF95AF68949
+:108DB00016DFFF1DB15F63E5F70FB83F235847F794
+:108DC000CF173BB9BE013E0FCEA5FE3D25E2F7030E
+:108DD000EE79B97644FC3E1D48221F0F58A35CEF84
+:108DE00017386E61FA02C7FB3D435D6417B7CCA428
+:108DF0003ADA6B757B71B8C45943380FD27B736212
+:108E0000F32CC915E71B40EBCD8D7D5F69AC773541
+:108E1000DCC87C58ADE3EA3FF4BC1EF3A8F3B949C3
+:108E2000F2A8C1E2DF0B74EBF1D3F9E9DA89EF21A3
+:108E30000ECA8F2841CAD7F7BC911222FFDFB46F48
+:108E4000D99F281F0EBC69078A43EED9BF6C04D78F
+:108E5000E1FBFD57923D39BFFF8E2BB98E5112DFDA
+:108E6000970689BE5C8AA75EF5509C54BFEF55AE4D
+:108E700073ACDF3BFE518A9F305EBA96AE631CC373
+:108E8000F82B3F56C9F8DB73B432B3940807AF939D
+:108E9000E6AD3FA270DD63FD91CA17E7525C736CCB
+:108EA00006C74F46BC5441F938C54F478626C44FC4
+:108EB000A979827F7D075278FF438212811F189A19
+:108EC000809FBAF63F709C5187F62E1E47C673C529
+:108ED000790ACF332C4FC74F58F2313E768BB6AE5E
+:108EE000630FAF6FB935CCF26EDA6515F7DB446B03
+:108EF000D44907212348FC78912EA11CE6D842854D
+:108F0000946FBE502CF20DB33C9EC813E7852F9C86
+:108F100014DF19BF30DD3F22D9F7C6419821F27026
+:108F200049E777BB7576B2EF7977E489FD09772653
+:108F3000249C4B1AEDA379425FE6D8C43E95F9BE56
+:108F40003FCFF03FB08ECE634ECCB5AAC6EFB7E4AC
+:108F5000A1DDBD1E8C3FEFABF3B3E89C4BE4D50025
+:108F60003D33C91E7E9BF6F929FE9A24FCBAB1CF87
+:108F70003F6F333C20F6F96FB5925D30EA4BE6F96E
+:108F8000CCF157F5D534CF8DE8DF699E9B6627DE9F
+:108F9000FFF645E2AE0579BA1F1F0EC3455EE172CA
+:108FA000923F38D76555655E476868B2EF0B0DFB99
+:108FB000737895383FEA42BB486DD3A8D779DFEA8A
+:108FC0008503279F4C67BB9A0225C8E2ABBEFC9382
+:108FD00027D93C4D17F4757E02FE0C799DA53CA067
+:108FE0006CA0BCEECCB3E8DF259DB1F1F926343E90
+:108FF000649107FF2EA969D4672DA44F67F5EF5E32
+:1090000090BE227B9CDD3F9BF731DFBF6706448328
+:1090100078FFC0283BFBBFFA99129F1FD447843FBB
+:10902000AC9F2FFCE1F0F6792C97EFA05C7C5E36CC
+:1090300013AF515DAE21EFABBEEC9B69E493748E30
+:10904000D34438673B9DC56D7DFBDB2D7C5E897EFF
+:1090500097E2C21B2625CA6D04F81FC8C6FB37CF8E
+:1090600096BCE84106C8FDE65BE7B1DC6FD2BF8F76
+:10907000B998DC7F9BE7FF691EE97D77FF77C62003
+:109080008B5E18F54111F9D7864170BD55E72F0C5D
+:109090008D3E4DE765DE0BE7E97F7F3AFE3CBDC4C0
+:1090A000E3DF924776D5F2A5FB0AA0F97A7EB942B2
+:1090B000223901EBC5607AB5439F7F479E2ADE9334
+:1090C00025CE8746E9FD17ACA142FE9EA2ECD2CE8A
+:1090D000019B9E7D7E2CD9B9DE0347C6DAE2E47A95
+:1090E0006605DA07F237FB0EF1F78731DC5974DCDD
+:1090F00029DC4AD28DBA1F4DC4E119C221D9E7DD5E
+:1091000087AEA7FCF16CFB4D599216E767F79E708E
+:109110000F8B9BF7ACFEBB1898B70DFF766A3C9D92
+:109120000F309D67C3623ED4FFE1378D89BFDF6C8E
+:109130007C67C7787E7064239FD31B785640E0D944
+:10914000F83D8C0BDF55DA80BF7B0CEEB7737D45A5
+:109150009F355A941EA72F1F1A7244981566312BFB
+:10916000B9DE75226CA8E273024CDED74DA6CFEFB4
+:10917000C2B2A80F6DE4BAC5698DE025DC4AB0998A
+:10918000FB13668BF3F229D02D135DDF8428B73EE5
+:1091900050156A67508519B6931C6199C2ADB6F631
+:1091A000834EC257C4A3A4BFEF10A5A7C9E4175BA1
+:1091B000BF02EF1B78C5C1180425FD4E3F2B5FD8B9
+:1091C0007FAF53E863F4ACF8DD936F400FD33F55A6
+:1091D000E9667A53352D83CE4B763FB742A6FA9790
+:1091E000FDA04549CFBC998DBCFF169D0EE1ADE9B0
+:1091F000B1F54EA2F5AAB1FE940560A1F54AB04BB7
+:10920000ACBF1132E87C6C3244F83D5711C1B8DE76
+:10921000E9A029D4B7E517EB7C16F95B959EBF59F9
+:109220001C41AEFB49CD17B8762A2139AF92B7B6AB
+:10923000C38FD0F94CA958E744BCCEE7388D82EEF5
+:109240000BFE3A5FD8BB29106639430DA82FF28F69
+:109250002BCC54895F52C463A1DF13BB54BEF67993
+:1092600080E977DF1EEDFD6165ECDCCBDB99C3F5B2
+:10927000D0EB254B5426BA1C85A21E3A0261FE2E65
+:109280003392F87B67C5F9375E9E4F7ECF2FBEC302
+:1092900035D775EE086DE5BA9B0541640FCD5308CF
+:1092A00070DA13AB03B09684F8BE95CED955AE33C1
+:1092B000ADA07C715FB6FFF2FC6CAE371DC6932982
+:1092C000A1F1D5A931BC2365FCFB3B4E486D257B44
+:1092D000D4ACD7D30655B75ECF54C4EBD0D0CEF3C1
+:1092E0008F4828A2AEFBDE2A517F7AEF90FD5CE723
+:1092F000DB23812A15D0F9FF7EAE03A61F86B316A5
+:109300007CCDF97F96FEBB0F25FE372696EA461EDA
+:109310009F6B3E95CAF5AFCA0C9F4675BCE67AF1C5
+:10932000D296F10FF5705E6AD06BAA1357BC7CFF22
+:109330005EDDBE363BC4EF0049ABEDAA348DBE7F87
+:109340005FC1BF63D54CA141257DF7BE829FA73A7F
+:10935000662A02ED4DF3DF44FC32FF2E15C2ABFF4F
+:10936000059A376D38EFF72593C734431E968175FC
+:109370005228875B49BE46DDAD516F4B80A0753BDF
+:109380007DE277F054C409FFEE1F42C94EB8F4994C
+:109390007FCF43D4FFB6E8FC47BA7670DDA7437CA5
+:1093A000A76D7CCF6BE69B81DFFF02B9D77EA25011
+:1093B00053000000000000001F8B080000000000A8
+:1093C000000B9B22C3C0F0A31E81F9A551F9E8F858
+:1093D000049A3C0B0303C34F205ECC835F1F2E1CFB
+:1093E000CB8260BB883330E88A3230E801F1142048
+:1093F0009E0AC49F81585B8C814107887381EC3C35
+:10940000207607626BA0DA2F1C0C0CDDC20C0CD38B
+:109410008078A130AAB92F1821B41217038329101C
+:10942000333263B77FAA1A03C3011D043F5D9781DE
+:1094300061AB3E797E19C5430F6F7344E51FB5429A
+:10944000E57FB06160B07742F08F5991667E35500C
+:109450006F8D136EF9A36EA8FCBD1EA87C0B34F9AA
+:109460001D61101A00FB3B7C21B8030000000000C6
+:1094700000000000000000001F8B0800000000003A
+:10948000000BED7D7D7C1CC59560F5C7F4F47CAACE
+:10949000471ED9235B323DD2D8964186B62DDB32AA
+:1094A000B6714B06472424194CE20802B9C136AC08
+:1094B000B3E1B809770B0EC1D1E8FBC3B219192F7C
+:1094C000311C81417CC4102E281F9775127219031C
+:1094D000C9CF9BCB651D4238270739A1F8D87C6ED0
+:1094E00074EC19CF5D08DE7AAFAAA5E9D67CD986DF
+:1094F0004DFE38F9472AD5FDAAEABD57AF5EBDF744
+:10950000EA758D22BA48EC2242CEC2DF6642DE7294
+:109510001142D6CC96A976234B5A68F934317AE9B0
+:10952000A34BB46CBB40CB15FE4951D009B92C9C60
+:109530002644242436F1301129DC509D4246A28471
+:1095400078F46D55C43FDBAFB3ECED2224BBACF82F
+:109550007BE9F9E1881EA0FD3DB5B6D3A4FD0C7DE5
+:10956000A5B5D36C9E7D5F0B8352FC1A08C5A686F9
+:1095700090FEFAFB89182664908EBD8CFEA7DE93C0
+:109580002071DA4EC90E137D05C085105EFDFA0903
+:10959000F166FA7CD0453A2768A91E4D657D14EF27
+:1095A0004B9FD35649941E8F6C8ABFA5754F44CCF0
+:1095B000A4808EC841ECF734A50B867AAFE8590D2C
+:1095C000F4503A365648CFC662F43C974A013D976C
+:1095D0001DD557E6D3A3D6317AD4BA1E9CA7D31192
+:1095E0004A4FF442E8F90CD233C8E91974D0F34178
+:1095F0004ECF768B9EDA01A467A09ED2431FB9EFAF
+:109600004991388557819E00C0D9E919007A9A0B93
+:10961000D0A3FE79E8F92B2E6F49A0674D797A9295
+:10962000404F4D05F4F8D344A3CF3D4430279AE78B
+:10963000E2E5E17C5CF1F5742445FB1DFE9384F3C7
+:109640004C576464DB8A59B8498ED7F7A203914915
+:1096500090AF25F74708ED6FB85E407867BF0F10F1
+:1096600005E1B53AB31BFABFF888BDFFE17A86AFD2
+:1096700005FF7B3E8FBF2712B65BE08F0F437D78DF
+:10968000C9374802C671A5231AB48BB276FD4BD6F2
+:10969000764EFA0BB567F40CEF4DA13CABD9CF2059
+:1096A000BFFEA63E4D745AF71C4910E0BF1261F888
+:1096B00058ED295E845C0E64DF699A0C3F4216D235
+:1096C000794ADD994DD1F162E9DBD538E5C7706D96
+:1096D0008F0A740FE9073B416F9D8E29448A025E11
+:1096E00085F960C9C56632AA36D0F9EC7D59324693
+:1096F000C85CB8140857CD6C5DF68B24DB44F0EFE2
+:109700002C017A1238FFFD4BEE47BA15A06B05D03D
+:1097100095243A7DFE2D2E3FEEAFA708C895AAA747
+:1097200022A91573C71902FE3743AFE9C8B63CFA40
+:109730007F6ECD2F9D57C7FC225F1E206636057CAD
+:10974000F1D8E7CD2AFF9EF3FDB2BA14F2B7DCF8E8
+:1097500073E967E3FF1DD1B11FA2A623F1C02C3E20
+:10976000C3AEC91E906BBA268D2728C8A5749CB6B7
+:109770003C7E3BC79BA1534EDBE4F81B9C4FC39E32
+:10978000E9E7F3FB73E2F35D0EF75DA26169D17562
+:10979000E951364EB9FE7F022CAE0178C7BA92531A
+:1097A00036BEDFCDE12F7BCE0E578C3F9F9DE14F24
+:1097B0002A02F268AD47F833E713C24506FFFC6B97
+:1097C00009590EFF8736F9C3CD9377C2D27A259C0B
+:1097D000380DED6F23898BBC8D74BDB8125F847218
+:1097E000AB6CBE85FD12BFF6C6255CEE24D4036CBF
+:1097F0003CDA3DA1FD07787FB2D041089567772B11
+:10980000C98C50D4AE925ECD0A949F070931166878
+:1098100079FBFA14DBD7D76B992DB09F6F90292174
+:1098200074BC2AA279A004F82C850BAEF11B742419
+:10983000E2261FAF8A17901B4F0B4979AAE8F8ADB3
+:109840008A6D5D78CC0401BD108890AC2748F58DF9
+:10985000100823FEEBC83A86BF2E407FD5B2DE2D1E
+:10986000D371A498688CD3A7551BC9FA1D7972A827
+:109870000B4C7EBB63A208740D50FDEFA64B325813
+:109880004FD73BAC8708B5370AC8ED8C7ECF49244B
+:109890003B8FF69B13487635ADFBC9FA046D97767E
+:1098A00093F5A7705C628C1790B3ED029B5721363D
+:1098B0007DF62CDA0524F33EB40BD2B88E9558DA37
+:1098C000847D403583861BA6FDED7B995E938909D7
+:1098D00072128AA5B355F05E5F1A057C17C492E434
+:1098E000F566564EE5E1ABFA5311B49FA24B859E47
+:1098F000BC7DEC18959FA93C791BDACBEC80FEE887
+:1099000000D7339F44FD69BDFF04E79332499101BD
+:10991000BA7425D320CC95EB21A1B09ED8C9E98596
+:10992000BF2BD7DAE5559ECFE5950EE19609CAD74C
+:10993000E0532403F8524E3E7F33AD5FF2A24A4615
+:10994000A87C35931322C8CFA5641A4B8368129460
+:10995000AB8881650B8963F987362AF7B4BCCDA43F
+:10996000F2DE80F2FF51818EFFFBFAC4B2207DEE61
+:1099700089A52E87FD85CAFF76784EE5440079AA31
+:109980003649C1FD3224B0F53A266B1E801B3309DF
+:10999000EAC743426F0AF689216E270D79886D1D4B
+:1099A0001FE0740FF132144B9049985F3A2FA0D703
+:1099B0008F456FC575EC96597D80CE0BCADD26B6F6
+:1099C0008F39F150615E569CFF3C6CFFF3CFC38032
+:1099D0005053701E06611EB60B4C7F2ABF62E39780
+:1099E000A00FF7E99DDD8F22FF9553E7066FD1BFEA
+:1099F000D6A137D7713DB7814C2F96A91EB9DD9DF1
+:109A0000556401F1FE02E0FDD6CF4E7C02E82193C1
+:109A10008965B04F51BC1F16504F26C9093ABEFC8C
+:109A2000B294013F45F45DA3264AF82944A3FA4CB9
+:109A3000E5FAAC01FEB74E7BC33757FF2E9DF8AB5E
+:109A400093686F10353102FA69535205B9E8ADDBFE
+:109A5000A6821C0DD6D13AC84D445185CB68E92762
+:109A60001D207F96FD3110D931140D83DD63AC8547
+:109A70006EADF1B7441244C0E78979EEA8FDF92F25
+:109A800061FD6B898844E95332EF5381CE7E6D9B33
+:109A90009AEF7729FE4444A1723808E3C1F8AEE496
+:109AA000F1680BE84FB2BA07F4B99624AB41BE2374
+:109AB000ED88E796BAB80AEFDD9155C4AD038BE3A4
+:109AC00068570D84EDFEDC60DD1DE456844F92374F
+:109AD000FC73ED6BB73F4994BC7D02C691F2E6D9A9
+:109AE0002D27B340971429AC77FF07977F518FE359
+:109AF0007E43D29F37552AF72E2E03AE08F9997070
+:109B000069DE3C85F3F61D3A4F031EA3B3D0BAA419
+:109B10003B88BD5F4320EADACAFB9DDD6FF9BCA735
+:109B2000D70D4DE2BC07D230EFBD54EFE3BEFA6A69
+:109B300020F30425A17B53F21178EF4AC9A4278CA6
+:109B4000DD34C13E779774B101F27700F846378E65
+:109B5000D12E15CB912E0DCBA1AE08969FF77DEEA1
+:109B60008B93B4DD9E945B73831CA4EF7A16FAA3E7
+:109B70005E777C04FA0DD3FEA15F59D59ED0A0CEAE
+:109B8000F61D578C95378A8C8F55A217F16D119958
+:109B90001DAE1313E525AD95F6D3AB5AED766EC029
+:109BA000F0CEAE07FA9FAFA9DA56F7E80B6DF0CE0C
+:109BB000F5F26391E90D971C2746339485F5F85922
+:109BC000414238495A390DF687BC4041BBA05FB0CD
+:109BD000EBED8745B6DF3D26AA4867844CBF7096FB
+:109BE000F2C3A58968F704430D1359E04F8D622C29
+:109BF000A145D035A95517188F84E5DF4DE6ADF3A3
+:109C0000A7043326FE05F0690EFDDDED36B9DE272B
+:109C1000B2FDEE2C5F2F92DBEC043D13A1624850A5
+:109C20003EF447810FA26FA3D144F9D01F5274F0C4
+:109C300087FABAC582FB8E930F52D58D11D08F4E05
+:109C4000BE7F97CBD1339CEF9BDFFE30EA89FD9A34
+:109C5000D891F103DF4E74809EEF6B114590F3BFF6
+:109C600018FE39E8D833C3BF193A906F7D61663763
+:109C70008F6A547E603D8799FCE824DB81EF0D4AB2
+:109C80009730972E27FFDE6BFA2CBE5785C478A637
+:109C900019F09B8E237E1BE582F8FD6BF1DDC2CBB4
+:109CA0003F835796E165FC65E0F594901887F57D54
+:109CB00080CBEB01795205BD10B3E4C6C7D6D15CA9
+:109CC000BD24D8E49DF6F325E8E75EE887C2DF2BE4
+:109CD0004FDBFAB1E002C007B62EE26C5DC87FD65A
+:109CE0007561E135C2F1D64986C9755361B97EAF58
+:109CF000F1B2F6D31EDF1504F44DC81F47FB7B817C
+:109D00003F9E057EF5D6283AD83FD451C2FD1A9B16
+:109D1000EA797E52CDF608C0F707B6A35DDEEF8A7A
+:109D2000A39D7EBCE61BE6CD94AEDEB7AB88DBA080
+:109D3000FE80EF8AE33AE8C5E312FA6BBD6F372E77
+:109D4000481698671FC4C728FE5EC00FED6A65C637
+:109D500008077C7BFD54F1D17EDE6C2619D0A72E3E
+:109D6000BF1901BBBB77856AF420549C007F7B7CC4
+:109D70009F684D34CF6DEFF30F7C5ABA74761CFA9E
+:109D8000279C05DB97EEE1E0C7237D82ED7D413C1A
+:109D9000CAD55DB3750DFBA7755D85AE05F36CE3A4
+:109DA0002CDF292D4D32EC9BC46BC0FCC7E21D3D5E
+:109DB0007F043EFDBD847AD0C99FBF93125E69CDFA
+:109DC0006CDD154EE0BC59FD5D5D23A31E95EB488F
+:109DD000C62DC0A8F10EB06F7BEB448CAFC9FE6DF1
+:109DE0005525EDEEBACAEC6EC2E31E963CB4FD8A70
+:109DF0008DEB3598FE0E90490271952AC2E21A2128
+:109E0000A20B04DB1B421C83251B319E12F6BCDB1C
+:109E1000FDDE88FD0AE61839EB3B877E65DA6FE3E5
+:109E20007BD06F197C3DE421EC97AA87F0D979B3F8
+:109E3000FDBA22497C48DE3E7B565A4B5813FC4BF8
+:109E4000A07CCBA281EB932C0C1A4FD0A23F7C8735
+:109E5000CD9FFA88D4608B9B2ADAC0A785202DEB92
+:109E60006E3327F3F483737E3B6120F02FEB7699FA
+:109E70009315E80D30BB0BC5A5069444A61BF6EF61
+:109E8000C57E8C2312398971E141A17A15D8CF168C
+:109E90009C5CA76401AF408B99027D31384F34241C
+:109EA00003FA1D3D01FE0091AE311225E24B729D79
+:109EB000FC9B7C7AFEAD1408239E3CCED55B46DE2F
+:109EC00007BA4A9F4F288A9128E4CFA42466BF2866
+:109ED000DEC2EFAF54DAF74A6BE6F22D0DBCA3CF2A
+:109EE0000743D4E5BE8C890FC8815CF7FD93C0871A
+:109EF00081DAAD9152F4128DDA39797E91A19823ED
+:109F000052693C0E14C283F8A9F0AC2F310E9F5F4A
+:109F1000ED4A83C53B4029C2791CB7CF28DE416199
+:109F20003ED3D3F0B7BF653C0B7134D7CD7E13E67B
+:109F30004F328F1089C2FFA85622422BD4BDAF8B5F
+:109F4000389F1B0DD4574DCCBF33E93FA023B851E8
+:109F5000B1ED5BA03F67F6AD28C8BFBDFEB4648F0E
+:109F600067F6761D25BF5C328B3F7D64168A17CB62
+:109F70004AFB44617E5457C48F43545E08959783CF
+:109F8000D46FA44C2169EA3742FD00F51B09FA930E
+:109F90003A967D5D4D58EE83A6EBE1FC2C39148D8D
+:109FA00042BCF4F1C82D14E410E80E3C57F1B6435E
+:109FB000FC7CC4AAD32702D4F939CB0F7BFFD80687
+:109FC000F198110FAB1332DD66DAEA520FC4FB478A
+:109FD00002ACFD2F257F3B9C471CE2E7484436D569
+:109FE0008FE6F9FF39C98574800DC4DAFFBE1BFA0C
+:109FF000F3C8BC9EAA477C66EA948F808F4765F5BC
+:10A00000BABEC5D83FAA003A5EACEF2236DE126671
+:10A01000DF93E66D65F8D883F27F3D1CC201CDCD9C
+:10A02000D570A84C14C320B0DD1C0A71BC2BEC8782
+:10A03000C809B6DFF1B852F17553665FE378949BB7
+:10A040007F027E29C42FA81E4EC1B83F2DBC4FBF32
+:10A05000DBE31E729D1B5F94D6E9944C59FCB7520A
+:10A060004293693D604E64A3B41EBC269BC2E55B6F
+:10A07000E1B8BF93341E0F4DE0FAB7F82C6BCCEE6D
+:10A08000B8D2318FAEB089E7921E3F5B7F95E2BBBD
+:10A090001EC6C9EB873CD35E1B0F146F571317679F
+:10A0A000ED2DFADFBC0EEFACBD46FF0B99D5B67AAD
+:10A0B00055EB421B7CC068B0BD776917DBDE9FEFB4
+:10A0C0003C5DEAA0A3D1E21FAF479C74562C77B247
+:10A0D000CEF7B914B31F67EA7C3F2E577F7B99BD3B
+:10A0E000CEFA75931BAA987DC3EC987F43388C13E6
+:10A0F0000F234FFF4A00C7EABA2810CBBECD36CD9A
+:10A10000EDBF57FD1CC6E1CC5E9978AE981BA74BFE
+:10A11000B52731CE96EA716BBD618CBB619C6D0F2A
+:10A1200035E4DDB4BCCD95D80DF27BC6B33843829F
+:10A13000D06F721DC4AD7B1DF104A73CC51EBABE15
+:10A14000E07999550E75B1F89F5557EB0AE701DC98
+:10A150002DB3F3FAEFBB1277031EA01B09C66909E2
+:10A16000AE0397CEF6C763D1ADE4D7E8FFB3F331C2
+:10A1700085A44E36527AD2D45F1BD1816EB64E86FC
+:10A18000A25BD5187D3E1612B94D378DF653BA6DC8
+:10A190007E2DACA72A791ACFEDAA6285F1B95716A0
+:10A1A000F9BCDD54923EE77CDC048156DA6EAC5E8D
+:10A1B0001091FFF562E6098847D589B8AEF79BCACA
+:10A1C000A370D4BEBFA5FA7A8CA79B8A28211D59FB
+:10A1D000B5D03AECE776532F8F9F1EA8637EEBB184
+:10A1E000B6375438AF3960B4633E809CFE11B61F59
+:10A1F000E4FC4EAF9CC238F96091F3971E99F9F9CF
+:10A20000BD016F67A6E0FB20BE4F47DB9E7F00E8E5
+:10A21000A0FAF709F4CF48ED2E4A87666AAB80DFD3
+:10A2200063F5A6F86B90AB4D22CA5910E272129CEE
+:10A230008BDAFDE7B14D229EB3A635BF01F6FB696F
+:10A24000F34D821B91ACD5C2F962D5AB1B34DC2B2C
+:10A25000A9BD539B67E7576D4CAE83F9B2E8729383
+:10A260006B0BCE87B0784F02F879D72AA2833FE6EE
+:10A270005EDC91FD02EDF7CC7AB706AAE0CAC09584
+:10A28000D9EF803CD16D05FC6477D8CC82DDE4E960
+:10A29000F4119DBE0F4626D08E52231231C1AEFA64
+:10A2A000BF12CE17D51948977C68FD89CDB4BDB2D1
+:10A2B000495C80765933DB6F34FA0FF61B3566B78D
+:10A2C000AB245716FBBB77F2513C57561C76954C86
+:10A2D000F2E0C1EEDAB4EDC38D05F481554A934145
+:10A2E0003CD725D28D25ED6CFFAB9FFC8717F3F88B
+:10A2F0003E253BEC746EBF59FD14B3DFCE74EDFE0A
+:10A300008717A92C275C2C0E2A2BE66F605D4EF177
+:10A31000F3C53147DE4DC2C5D6CB19BE8E6166C1CD
+:10A32000DF06FF18F8D577D576E66711C3E6C7D004
+:10A33000F57E46CEF3B3ADFD2E6D96F62766F35A45
+:10A34000FC9E5889BC966BE584EC2A91D762ADD708
+:10A35000E14D2689D0F91D0D914C0FCCEF6693ECA1
+:10A3600004791588D1A331F869EB1C250A72781598
+:10A37000D905EB57970D3887EC6FFC1075148BE3FC
+:10A380002B87EDF2516E1EF738E67191CB6E87BBCD
+:10A3900048BC2A1B853846E47AC0637F5831603D4B
+:10A3A000BAC41B77EFD0E7CE2359C7F4862B9C2580
+:10A3B00085C6B5F879BBCB5CE68238BB629C4C8025
+:10A3C000FCB72BE8F73AE16F72F13C962891C13E59
+:10A3D0004BC13A81F5DB61B2BC31414B3E6820FA9A
+:10A3E00071DBB956EC2DCC677B4822C9791B09B9C2
+:10A3F000CE15657AA66D3BB37B3E40042904F00977
+:10A40000DCBF6A4D4DA07D9361CB2ED36E8E5C9BDD
+:10A41000A727AFE3F239FB3E11F9A8EDBD8BE11997
+:10A42000E076B3B63372ED8A02ED4385F5E407B802
+:10A430005C5FE7E2F6446A27E605F5EB37C681CFB5
+:10A440007D9B4D6317682D9011C847F1139B7D4C80
+:10A45000E5FB3AE0A7153F92B53896963D506CFE65
+:10A460009D76802B62CF3BA9F4DC3676E8FA92E346
+:10A4700038F7672BBF0D345F3E9F5C9C0FCD7CBDD2
+:10A48000CCDA4B69BEDE0DCC079214330171494919
+:10A4900020367B6B8CCB8BE465EF9D7850FFF94EBB
+:10A4A00058A752D044FF9AF85B98DD261BFAB505F1
+:10A4B000F0B7CE391FE379BCB1F48770FF1B0DB53F
+:10A4C000E3BED7A795D61FD6BEBA995CA342DCAE31
+:10A4D000BFB8FE18CDD71F4A58B4AF63EEDF53FAAA
+:10A4E000F5427CB6F814E1F1D2DEC0F648C9B8A056
+:10A4F000E37CC550CC07902FC5F9F685F3E1DB2846
+:10A50000CFABDBDBFFD2F33C0FC1AEAF5716D5D7D5
+:10A51000FFC9A64FB9BE7E0FF9FFDCBBC1FF4AE3FE
+:10A52000309E3D927E6A1E55F1720AE919D60FA639
+:10A53000301E03EB1BEC80741BE62B901841BD080A
+:10A540000D41DF797413F9E6E57126A5CEBECF483B
+:10A5500061AFAD1EE94C11C857837E816ECF1E05D9
+:10A56000C7B5F84D6D16CC27B3EC4B584EE08F14A1
+:10A57000CB4FB34A2B7E03C73867719FFAEC71E06B
+:10A58000EF693FC1FDA138FDF671221F8997D64FB3
+:10A590000E78E297F5370A9C0BCE6D279337F2F4CD
+:10A5A000DAFF71E813F3C8CD9DA847896840FCB273
+:10A5B00037B29D2428DE0384E9932128D7433EC97E
+:10A5C0002A0DFCDFEFBB74D65E67FE9DA8F238BD96
+:10A5D0005E99BF7717DD870AD93F4B15661F9FF934
+:10A5E0005CF20F9097901A1174D8DF4E75E5D07E0B
+:10A5F000DA915DAE405EDA72653EC2ED381455B652
+:10A60000E4ADCF1D849DFB5344947C3D6AAD3F2552
+:10A61000ED7E1EE89C4AB3B8C654FA9FF15C7FEA0F
+:10A62000B09401A64E0D5D5772FD9CE27ADB823B31
+:10A63000755832A1BFD490905942DB9F92CD60C132
+:10A640003C009261E7C1BC7E4B5AB2C9E599BD0995
+:10A6500005F4CCA92E55F8259D9B5B814E8AFF8E73
+:10A660007454019FAC1C5DF314FB7C5A74F643BE1A
+:10A670004274367FA73FFC26D27B9A3E974AC4930A
+:10A6800046B89EE80F17D6275E7EFEEA75650AE794
+:10A690003D38E8F535D9D7A585DF20CFA718D418E0
+:10A6A0005E831111E761B0AEB41EEBE3F360C1F558
+:10A6B00047D8796BBF1C572BC1C7A5D9F129368E56
+:10A6C000BA71A203B6F92A92E8688F227B5F8238BA
+:10A6D00002860E75F09F9E3A762BC4816FF69B42E0
+:10A6E000041E4E67BF43EB0BA8BF03F6A966668442
+:10A6F000C52D90D72911881B3F947C33FB1AF8A3F2
+:10A70000D4FF817A484F86DE077A289610605DED87
+:10A7100007E58F9D7FB0B7AD99AF3F5AFFD440FB9F
+:10A72000168843CA24CEE319A20EF97AB8F4C5E21A
+:10A730007A02B4E759F76CBBA2743AFC2237D956B7
+:10A74000DAFFDECDE053F41FE89D050E3F2BD46900
+:10A75000B7BBAB1CEFC7B8BC16F32BDFAD71E693EC
+:10A7600097543897555B442D03F0241982FD3678B1
+:10A77000A34CC08E9FAF6BDD10E22BC7F77D84E545
+:10A78000B9C11711F9EBEF4985D9B18B6E7F5C80A8
+:10A79000FDE93478D92BA19E330AC9AFD3EE1BD281
+:10A7A000A7309E38404E7434823DBF4BC4F3A4FDA5
+:10A7B0002D0743F9EDBFC7C7999D7FA2CB6BF1541D
+:10A7C00016FD79A5453461DF3ADFF977FAC9E5E688
+:10A7D000BF76B7DD2E3ED779F93120BEA6FCFC5FEF
+:10A7E000E838D6BCCD5D1F4C6F2EBAFD458CE38C8E
+:10A7F0001AA5F5CDDC797B09E72DD842CC42719CB6
+:10A8000057F83EE6CCEB53499218909FF832DB7F25
+:10A81000A4C6B591F112FA478A39FC0FDE4FEE1645
+:10A82000424EC07E2BEB65BE879B3824D37DD3B7C9
+:10A8300067C3217935E4679998E735DC65E2F399D8
+:10A84000F9778B1C5F81886BB95ED1F1FCF3908C3A
+:10A85000F68648CE421C846844B7E48E005CC7216B
+:10A8600019E3313ACF23A0A0F3A11D41BDB4129248
+:10A870003D6BF09C1EFB818E581CA693D569439CB2
+:10A88000279769225E725ABD83F2739F87D7755EE0
+:10A890000FF1BAC6EB515E2707B1EE53681DE2F225
+:10A8A000AEB486752FAF4779BD9AD743BCDEC0EBF7
+:10A8B000C241ACEF53587F237286F5EFE5759DD703
+:10A8C000AB795DE3F5065E27E36C7C37ABC37E882E
+:10A8D000751FAF47797D1EAF8778BD91D78571AC65
+:10A8E000179B3F6FCC44FECECE7F07E31B21DCDFFE
+:10A8F0008C3BEA9DB3F079FE687F972EE49F1FBAE8
+:10A900008AC49F56B9999E996E8B639E12F5175211
+:10A9100053F9E78E91C2F26EF27633E7E6610A5799
+:10A92000307EDD5D705D548ADFD6F3C4EF23FF4ACD
+:10A93000F8DDE0B6D63DF3CFA7DB0CC4D3D99FB387
+:10A940001DD85B24EF9CDE2B675210AFA13612FAA4
+:10A950003B2ED59ECF7A979B9D7376BB593E6B2F2E
+:10A96000C76FBA8D9D3FF42FF166C685B971C6BF1A
+:10A9700071B378C20F2C3CD509F47B7C39BA62D113
+:10A980000F627ED470ACBD4CFEBAFCFFF2FD656771
+:10A990001CE49FE11D1DC7EB2FCCA7BB66F4CD8D3A
+:10A9A000A9290AAB7AE873F067B470A42E3F6F9AB6
+:10A9B000BF278228A17E799BC259F92212F6CFE2E5
+:10A9C000C5752C5E2C71781C27CABE633057C13EFA
+:10A9D000439F37F17184B9FD3ADB65DDD56CBE3834
+:10A9E0003E567E8A449EC37E66F091E3C82FE7738D
+:10A9F000C843D6FC17FEFC42EB2EBDC8786976FE34
+:10AA000052AEFD17B9BCCC91CF22F3FA1FDD969D53
+:10AA10003261423E902547967C9DAF1C5DB09CC044
+:10AA200086D4525C4E522489EB46069773E5B9CB27
+:10AA30004B0139C9E6C3D7A8217E9E6FA0BC507CCC
+:10AA400064945B8DE153B32A8CFD09B0C697410F26
+:10AA5000BC0E7CA0F45EA286381F589CC20BE78C0B
+:10AA600079ED297188AF20095CEF33B8CD2A5BE717
+:10AA70009BDAEB18FE84F7EFC097F6A7E6F727916D
+:10AA80003A879C33BC3FA6B2F9A5F0F89DDF9CF154
+:10AA90006501F195483C25D2769FE2F04EFD659523
+:10AAA0007B397EC322D9CDBE938C93FCEF2A7DAA3D
+:10AAB000C8BF7B64EBCCA99F5C2057ABCF5FAE2AAD
+:10AAC000D5EB356AE17D87EAF92688F715DB774E05
+:10AAD000AA33FB41139FB7739AF7DF811E5A333BAA
+:10AAE0009F95E27B091FF75CF13D3517DF8AE4ECA7
+:10AAF0004DAE272AC56FF379E2F79203BF774BAECD
+:10AB0000DFE6FB51A5F87FEC3CE5E18773F95BD10B
+:10AB10003A12D573E3EFA7CE13BF5F38F12BB26EB5
+:10AB20001595F12B45987CC8FCFCA552FCBACAE3EC
+:10AB3000C7F3C5B6F69931B4D7D01FDFAF6EED4B72
+:10AB4000C9B3F89984E9F5731DFFDE8AC7FF509FEA
+:10AB500029CF8EFF05F543B6F165D94061AB74DCB2
+:10AB6000872B1D37F5511BDDCF0C7DD436EEF9F266
+:10AB7000FDCB158F7F938DEEE7866EB2D3ED373028
+:10AB80009FB8D271BF739EEBFD371C5F9FAAD9F6A9
+:10AB90008162F6FBDBDCAEBD45D56C725C0CFE4D14
+:10ABA0006EAF7CB042F853BCFF460B9F32F09FE182
+:10ABB000F87FA642F8DF717CD65788CF0FF83A2C81
+:10ABC000B67F7A39DF7DA023F3FC9A0BCD5BDAE503
+:10ABD0004E081E38E7FC7A177E27F8A6AC6A10EFFD
+:10ABE000241D04ED71CFAB8171965792E2FE7F2256
+:10ABF00025303D8CF12D57D8B09DC7597E972CC775
+:10AC0000CD42E76D210FD37F826674B2F5AE10C8D6
+:10AC1000432A06EFF3148EBF549169CC3F21117E75
+:10AC20008EF4F6757AC17302398E792D92A69071E1
+:10AC30003A4E5F68BB9E9FB71CB3F08998888FA27D
+:10AC4000317C14D9300BE529D77BD8BC5AFD58FE8E
+:10AC5000A1109926EC1E07865FBF27DE0979E2A9BD
+:10AC600090827CEA0BD8CFC7AFE7FDBC9FD3D7E774
+:10AC70002A9D27D63EBF15F3957A5B59BE924E0C9E
+:10AC8000CCEFECF397BED760B48BC5FF4778FED30B
+:10AC9000107C3F0ADF13C3F7A3CBA0FD57F13BBCE9
+:10ACA000D3CD62C9FB7102863DCEEE6BB27FCF631E
+:10ACB000C5E53DBAFDBB1E77C4FE5D8F6BBE8C79CA
+:10ACC0005D7D7E763E500E7F2BEFDD821B9493AA36
+:10ACD00056904F19DBB9803B62C7F7BDE31F6BEF9E
+:10ACE000734D6885F07AB7F8562CDE30436F959235
+:10ACF000CC30BD61CBCFE8E2F2E5AE5293A097A98C
+:10AD0000DE2DF2DECBDAFBE3981FA246E23AC6A3C1
+:10AD1000F93EA0C27AC8E3D3E7AD75E915AD7C630F
+:10AD2000CCEB107413CF1F555847C2DC7633F36A4F
+:10AD3000C9FD9FB644709DD4A8B84E047D1ABFEBE0
+:10AD4000728EB3CC631EF4C0F998C7BC0F4AD73BD0
+:10AD500052A2D07A19F3303DAA5E13D7D5067455A6
+:10AD6000D1EE71E2F12C5F7F7E0BFF9489F917958C
+:10AD7000E2FF7085F85BE350FC9F063D4BF1FF124C
+:10AD800094C5F07F8AEBA36AA277E39EAD333D4B77
+:10AD9000C8B57A7E7CDDEB65FD56733D45489B2D3D
+:10ADA000AFC7C5E9AA949EA3965E2B438F352EA507
+:10ADB000E7453E1FDF2B351F2F707ABC5EB66FA9AB
+:10ADC00087E33A5D9A6469917999E278CCF7F2B8B1
+:10ADD00052AAED9CE4EAC715D231353B2FAFF17989
+:10ADE000F945293A5EE5729596C8FA53B09F365AEE
+:10ADF000F90BDB6CF3B288F327EDB6E6A5DD362F51
+:10AE0000A1739C97DF5648CFA2D97939C3E725575C
+:10AE10004ACEF2E0FFC4E1DFE1F068272EF2FEB196
+:10AE20000FCECB9679E2A2B766767FA3709277CDEC
+:10AE30002CDCE7878F5B706E84EB988153BD79FDC6
+:10AE400091D4EB7D70FEDDCFBFFFF8C170E02ADE4C
+:10AE50002E88EDAE61F4D07655F9FD3F3BFCB2D5BE
+:10AE6000FF3C80EBDEF28E0517CE875BE47DC78268
+:10AE70008BC073E1F04C7FB5F9784C79FEA98FE572
+:10AE8000EB38F2BDB4CAF21D5CE104DEE7504D02BE
+:10AE90006989960332BB5F21458DEA27207FD69DC5
+:10AEA000C8920AEC2E5165EDDCD4DE82F3E3791A08
+:10AEB00039E6D1C10531C861FAFE4058467FE00E3F
+:10AEC0004FA2C55BC3F0C43C80D7983DD6ED6FE17F
+:10AED000711486D798EF1343D09F46F182FE3FEF5F
+:10AEE0000B1E03F883F50AE6F31EABBF13EDC4B1E6
+:10AEF0006E99C0FBB1AB15B413EF7B2D80FB70BF17
+:10AF00006C5C8FF90FA6A283DD7897F79D9390A7CD
+:10AF10003CD95DA50957203D887F4A24F15EEC9F0E
+:10AF2000D99D7B28FE900F8C5B17F4DBC1FC18C207
+:10AF3000F39CEFDAA263DE8C4ED8FD4D83AD0AE6BA
+:10AF4000298DD535B4C178F7B5AA6877DC774D433C
+:10AF500037E673B77A31F7ADDAAF0B90DF135CA742
+:10AF600010F810A43AAC7783DD1958EB853BBF4845
+:10AF7000751D1B2FB08CE03D7F2E928EC768191C6B
+:10AF800052F01EA7FBAED996DD09764D2BCB5FA6FE
+:10AF900084BD145B4B889FB392483F24808F6B1114
+:10AFA0003BCFB7E639989E695FF21C3198A9102E05
+:10AFB0005B195C6048C6FCE4B270E90AE13215C274
+:10AFC00065195CD9F37B9E4FA9D27F1087F338F3C4
+:10AFD000B1FDA5BF8B3BD77CDD31AF3DEFBA5C7BCC
+:10AFE0002B4FB71CBD70983983A7541EDECAB32BF4
+:10AFF000F6DE35FFCE087C97365873372FEF616544
+:10B000002D7F5EBB2782F745D6F2F7B5F7E0FD91BD
+:10B01000CE7EFE0BD7C74D245E721EAA39FE6F503E
+:10B02000DC219EDD2497C90770E6FB39F49E2AA730
+:10B03000DA71DD5EC3F28B66BE9FACE3DF8D906498
+:10B040003C86F12C33B872FEECFA716DFC3EAE1FFB
+:10B05000EBBB493A3FEC7B49879C38E5C2EDC84FD2
+:10B06000B9503979E53D9213D79054D1FA71A52B97
+:10B0700084CB540897AD0C4E19122AD22B4ABA42EF
+:10B08000B84C85705906D7BF5EE1FBFA703FC4B774
+:10B090005C97ABB67AFFE55EFBFB0D7E5B7D608D5A
+:10B0A000BDBDB2D6DE7E60ADBDBDB28EB5377C878C
+:10B0B000AE4AC52A5F27FFEB3CD749935A1A3ED0C8
+:10B0C0005A665DA99A07DA57CB3A81FB85E87E95E7
+:10B0D000E1FB56C1F8CF561F5BFF577B35DBFD7494
+:10B0E0007FE97436F918BE16BDE5F0B5F4EF3F4AB6
+:10B0F000DCEE2A92771F029D538B8F17417FC78EFC
+:10B10000BDB510ECCA675F5F87F79AF67ED0CA9B21
+:10B1100031301F523EE9FD38E8AD67E97E0BF93862
+:10B120001321E3F82560CF044402F63275A3F05EE4
+:10B130008F678FCA687FF43E57DAEF7FA68BE509E9
+:10B140003D0D7E3FD5FF47F8BD5B4FF27BB71EEF4D
+:10B15000D2B11CEF6AC2F7992E03EB0F77B562F9F3
+:10B16000509789CF1FECEAC0FAE1AE38D6EFEFEA8C
+:10B17000C4F2DEAE0496FBBB7663B9AF2B89E570F3
+:10B18000D71E2C07BB522C6FB36B887FBF96C6F2BD
+:10B19000D2EF4C8D5C0276925FC4EFC08AE1BF6251
+:10B1A000C21E77B8E4883DEEB03C638F372C3B6C11
+:10B1B0008F372C4937D8DE370E5D6C7B1F4DADB213
+:10B1C000D52FDA73B90DBE3ED96EAB2FDAFD7E1BDB
+:10B1D0007C6D629B3D1FACF3061BBCB67187ED7D99
+:10B1E000B0E5AF6D757FF31D36786FEC6E5B1DEECD
+:10B1F0007DCE87BFD6D7C0E281E1111B9CEC3F68B2
+:10B2000083DB35DF7CC4B706F2F183685F3EFBAABF
+:10B2100080F95DF3161BAF03DFC92B12CA13B99275
+:10B22000E5C3CF6B485E06F7941139B9EEBA40F921
+:10B230007BA4AD788F146C4D80BC9E795DD0C1DE4F
+:10B2400015827B964D1690C7DDA7936402E2923C6F
+:10B25000CFAC7121314DDACE4BF5091E2E926476BA
+:10B260002FC62D45FC8EEA312181F926D46636FEA3
+:10B27000B30679F4CEFD77C3CF7787F17E04B4CBE4
+:10B28000DB0EB44E0D51F8F1150ADE7733075FC7B8
+:10B29000FD76BFF5313F78DF5E16AF6C7C7E7D8337
+:10B2A0000A76784B621EB8AA337A23FB33FC4E2908
+:10B2B000A01B6BE10A80402C4D763603DC0913E2BB
+:10B2C000B614FE6BBEBCF1028F9F4879E9F3E547E7
+:10B2D000128DF0D9C4F85E162F1D1F5E2ADE4AC7F4
+:10B2E00069C82E1797A2BFF324BBD77D48176FA557
+:10B2F0007AA1E1505CDC5A806FE37F2A1C4F9DF4F9
+:10B3000049D87EBC3B83F7CB79B3DFC47B38AD79BA
+:10B31000F135EB6202FA3D9C10C15E1BDFCBBED360
+:10B320001B17A20B239CCE6E079D8017A58BDC0AF2
+:10B33000E5434971AB9F3D6F0CCCF60BEF77C2FB39
+:10B340004C4ADCE2AF887FA6179E3FCEF9772423D4
+:10B3500096E49F7EC2047EAB31CA3FBD14FFEE6708
+:10B36000FCA37CBBD53F975F33F0295D5CDB9CC7BA
+:10B370006FDE1EF8726B01BECEF089B64F60FBA87F
+:10B38000B89A8F0B7C68A074EF2CD44E88F271327F
+:10B39000F671281F6FCD8BA7C39F3F2F4FC48287A5
+:10B3A000BF8EB53C4F91D2ED9A0CED84EFAFDB9A96
+:10B3B00013780F70BF5FC4FB85FAFD5FCDE23DFDE2
+:10B3C0001A41BD29CB66CF4FC22C0EDD23145AA7DC
+:10B3D000763F01BE4CC9FF9EACCF6FE5E197B197B8
+:10B3E000F8BDC212BF575891E31D51B69E8D6E3203
+:10B3F0001B5F9D3BFE41A45B8AD8F7DFBE5DF67DF7
+:10B400002FA6DD8071ECDE7065DF0DB973CCBE5404
+:10B41000383EAE9C8FDD779CF3209E666E1E969B19
+:10B4200073212CAFC82DC2F79B72B558DF986BC43F
+:10B43000FA865C14CBCB7397E0F3F5B9E5586FCD82
+:10B44000ADC6725D6E253E5F9BDB80F535B9F55864
+:10B450006FC96DC17275AE0DCB55B90FE0FB95B9D3
+:10B46000ABB16EE4AEC37279EE5A2C9B721FC7F774
+:10B47000CB72D7637D696E27D697E46EC67A2CF7B8
+:10B4800029AC37E63E896543EEDF6319CD7D1ADFCF
+:10B49000EBB9CF62FDA2DC67B0BE38D78BF5FA5CA2
+:10B4A00037D6EB72FBB0BE28378CE5C2DC7D58D6B0
+:10B4B000E6C6F0FD82DC0358CECF3D86CF43B947C8
+:10B4C000B1D4725FE2F7453F856530F7352C03B99B
+:10B4D000AFE07B7FEEDB58F7E5BE89A537F7029634
+:10B4E0006AEE1896E5E6A9DCF74F9BC93C9B5C6CBD
+:10B4F000CA2DB4D5374CDBF7EFF5BFBAD8565F3756
+:10B50000B9CA565F73F2725BFFAB4FD8F7EF95C7BE
+:10B51000DF6FB71FB2F6FD7B59E606BBFD7078877B
+:10B52000DD7E48FFB5AD1E1DBAC36E3FA4ECFB77B0
+:10B53000FD1EFBFEBD283962B71F761FB4C12F2048
+:10B540000F3AF2C9C76DF055E6D336F840EB571DF8
+:10B55000E72B19A6FF8D6FD99EAB4DCF173C87897E
+:10B560001DBA1ABFDB3F5D27F27B86F8BDADFC7EBE
+:10B5700034E77C56733D302FC7FCA7305F7735B07A
+:10B58000EEF2F29EC0CE88E6D919F31AF4AFBC48A9
+:10B59000EB67162B4637AD5B7686055FF6772B1487
+:10B5A000633245F174BDEAC67BE78460A70971B5D3
+:10B5B000BBA604DCEFAB17119E1FD1D1C1E213C4AF
+:10B5C000BA4F07EFF719ACB7DEEF7C1FBE8FB2FAA8
+:10B5D00071FFDEAD10471D7459EFBFF43E8C7378D8
+:10B5E00058FDBFFB770DC0FBEAAA8908ECB3FB8AC4
+:10B5F0009C6FFE4FBFC2EC7DBFF923FF9AD97BA69B
+:10B600005F09275EF2D3E7B7A9898BE0CA6EB8E776
+:10B610001EEE71DE2A9B3F01B86B65F3653FEE0BB2
+:10B6200076FFE15AC87D5D83F702FE0CDE4BC1A3B5
+:10B6300098DF5FFD817BF0BEAAC100C5C75F1C9F7C
+:10B64000FFE69766F61B62ED370D184F457B7020BD
+:10B650004AF0DE8CC1503C05F7F9A5BEA792270C35
+:10B66000A03BCD9295787EE2E072DD920BDBFE444A
+:10B67000483C0B717C5FC2AF83BDE6272730FF22B9
+:10B6800048A6B1D48826D8EEDBB6E8AF67F4C3FD90
+:10B69000FF7E3C87378F4E629C3549F8FDD56FC1E0
+:10B6A00073CA9733FE35C5F97295740FD1E8F80F58
+:10B6B000537B12E87898307CF773FF5426C97823BF
+:10B6C0008FF7E4DF2321BFFA4D941B2BDE234B1BA6
+:10B6D0003BF07A177E8F4307FD07F6614DBC74BCC3
+:10B6E000C7796FC3B9C67BC20167BCC78FE7C9A75B
+:10B6F0009B4B7F0767C57DF63797BEB732C3FDBE4C
+:10B7000087F979EF43FCBCF741EEF71DE67EDFFDDC
+:10B71000E0F7E1BD5ACCEF3B007EDF32382F366DCB
+:10B72000DF978C16B9FF251A12B89CED41FBDEC7D6
+:10B73000EF2BA29E2BDAF35E6ECFF7FA7BE6C3FD0A
+:10B740000CBE10C9809FB0FBEA71FC7E969262C06D
+:10B75000FD00B7FFFA8DF9FF8ED6631162BBDFC91A
+:10B76000DBECB82FA1DC3872C6847E7DD46F481B19
+:10B77000C5F973CEFDAA19E239AF7ED93D3FD6BDDA
+:10B780006DD4034F81FCF9806E0DE4EADB38CE699D
+:10B790003E0E91361EC7FB0C2F934929399833CEA4
+:10B7A00039CADFAE80E3F7291CF2A7CBA407EFA9C3
+:10B7B000E1DF43EA7EC39B1F5FB1E4B0B799C51FC9
+:10B7C000BA5FFF18FE6EC08B355B17E6FB7FD6773E
+:10B7D0004ABD2D0C8E5A7DB8CEF7779FD43FA9CFA6
+:10B7E000C23D65C169A5E3194F5870A30C2ED06204
+:10B7F0008885EEEFFB22DF4FBEEC3353819AD9717F
+:10B80000F59E8E1B504FAC51F17CC6D9EECBBEC419
+:10B8100050202F3FC1EA3FBF3DC85789F6E952ED9E
+:10B8200017DFDDF17352BAFDE1C09AE2EDEBEEE80D
+:10B8300078B00CFE99C2E3A71EC173A608FBDDB267
+:10B84000EE5AA501FCE57D6BA8BF4CE7E1C5155B91
+:10B85000F15ED9BED02B7A2139A2FD7EA9145E9467
+:10B860002F9D65E8FA5AB9F64269BABE5D86AF27E0
+:10B87000CBF0E58552ED295F0F97C1FFBF16C63F9C
+:10B880007511E01DA863F1BAEE7ACA57F0D7D6B0A9
+:10B890003884B51E1E1F2BCAD757CAF0A59CBCFE04
+:10B8A000E202E5F58D52E35720AFFF5486AFE5E4A1
+:10B8B000F5AD62F28AE7A4E72FAF42F0C2E4D513F8
+:10B8C0002CCDD772F21A2AD5BE0279AD2D857F050F
+:10B8D000F21A2D34BE9B508508F67E333B17DBDD14
+:10B8E000C6EE237335B17DD7F7EA17D13EEAA3FB45
+:10B8F000D3BC56D8A7A7EEBFBD65765F76EE3BCE2C
+:10B90000FE9CFBE6EDFFFB49DC37037CBFB3F0F1A7
+:10B91000E8CE7E4ADF6771AEE37AE17798F27EDFA8
+:10B92000E2E2C7EDDFAD5EF878F67DDDDB42C7A76A
+:10B93000EF091D7F0B9E233E83E7884B0F5DE8B820
+:10B94000A5E19B1E727C8F7B8E76C02D41BB1DDADC
+:10B95000B0E76B8FE0FD23BC9F06D9C4DFED93C930
+:10B9600095ECBE9321962F24EDF9CA23A756E7DD67
+:10B970002B4574313F3F481A9A78E4541E1D39888C
+:10B98000F7B0F832E62DC6B4CBD19E181C2D6DC78A
+:10B990007E99EFE3CFF0F38BA7B91D7B84E72D3EB3
+:10B9A0000976EC3238C760E717E360C7629E632B05
+:10B9B000CF7334799E630796CFF1F3876F751DC6F9
+:10B9C000F747BB32587EA3EB08965FEF9AC0F75F4C
+:10B9D000ED3A8AF589AE2CB38757DE897A66960EE2
+:10B9E00067DCAA341D971DB5C741564CD8CF312E00
+:10B9F00039623FC7589EB19F632C3B6C8F832C49A3
+:10BA0000DBCF311A87ECE718BE26FB398647B7C76C
+:10BA100041DC91F73BCE41B639CE41ECE718F54910
+:10BA2000FB39C6A2DDF638486DC27E8EB1A0F36E3A
+:10BA30001B7CC8ECB17F17DF6A8F836C9AB69F5F5F
+:10BA40006CF8D583F6B8CFA43D0EB2EEA43D0EB28D
+:10BA5000E6C4576DF5D5C7EDF18F0FFB122F823E6F
+:10BA60005D9975C641264598BF9FFBD9F99FE55F53
+:10BA700053F81F80FEBC4AF2673750B97FEC28BBF1
+:10BA8000DFFD31C2CE3309F90FE82FC833FE8289BA
+:10BA9000FA47E2FA67ECCAA957C09F91F7337FE7EC
+:10BAA00076615D56CDF7775CFF28E4AF6B4973FA9A
+:10BAB0000D65FA970DF473E432FEC8DC7E99DE9AC8
+:10BAC000BDDFBC25057954F28C3FF201873F523728
+:10BAD0008CBF6335AFB43F32679C73D4436F058B23
+:10BAE000F8C31111F967F923FB5AB83F42D87752CE
+:10BAF000567F961E1A8B945E87D63D2D63DC6F9120
+:10BB0000FD85CFB1AD7C99B196CAF2BA7F1064E7DA
+:10BB100049149AFBC3FF5F3EDE4DF9B8BCAA88BF4B
+:10BB2000FA1ECB4731B873950F197406C6236F19E7
+:10BB300084EF985C50BF7CB6AEF07AF0DEDBB642A4
+:10BB40005EC81EC2CE75C8CBECBED57278C436DED8
+:10BB50005432FFC18AAFFE496379BBB1D69B306FC7
+:10BB6000F2341DA3D47DDACE3C0B299C841FDB83E9
+:10BB7000EFD80B9EF7FCB49AE593C73A3F51D26ECB
+:10BB800071FE1E58CC2C7DBFEE30C7FF85D716A0A6
+:10BB9000BDBA6F88E963B973C5F3208F8F833C1AF0
+:10BBA000184F5197035D4332DEA7E6D709C6051744
+:10BBB000FB49A63B0A7C3552708F17FDC373E5190C
+:10BBC000F91CB2DB51672C3EC54BF3B5ECEF19AC59
+:10BBD000D7312F4DD649520BE1FA216F84113F5CCA
+:10BBE000B783AD06FBDD3B8A8FA6CD6DEFC4CBB925
+:10BBF0003EE55D57603CA941B0D6A7CF803C9DD3C0
+:10BC00007E7FC97BDEE6F47B8EEBF19939EBF19A0E
+:10BC10009E9FC2B8A32C7E44F6D0BFBC734E677FF4
+:10BC2000D67AB4EA2FBC76177ED732387A07BBAF04
+:10BC3000B88EDF0B36CAF46331BCAC78D0016E1F0E
+:10BC40003E71A8BD07F8DB47D74DBE3E5AF2B71F7D
+:10BC5000F126D8B96235944F1E66DF6B2F7D6017D1
+:10BC60007FBE039F1F68DDD68EFECF21620259C1C1
+:10BC7000F5A754F67E4A43F8F0F471B81769299590
+:10BC8000378885DFBBB1C584DFA8AC0A89ED504A8F
+:10BC9000A393A877492B3197E830AE8CBF9FB33878
+:10BCA000451E057C168F2646403E499A18F0BE2A4E
+:10BCB0001CDF763585AFA282095756A7087BBF38AF
+:10BCC000A9E1FCC5461307AF06F86682BFCB45DF86
+:10BCD00063BD6EB786F93FBED1C921B8F79A8EC150
+:10BCE000DFD33A7DBF30C1DA074627D35BD02F9927
+:10BCF000799FDED202F70EB2F7F228A507DE4718C9
+:10BD00003E29327D02DECF0FB3F7CA28DB1FEFDDFD
+:10BD1000B803EFD3A3E3E37D532EFEFC31CEFF58EF
+:10BD2000E73B27601C2B1F2345E2B67BA99CEBDE7B
+:10BD3000FAFDBF5E6EC7FBD4455F3895771FC33EE3
+:10BD40007E5FB577D4BE3FFFB18AEDB3C7B89E29F9
+:10BD5000772F1B247A839CFF0B555919960080007E
+:10BD6000000000001F8B080000000000000BC53D14
+:10BD70000B7854D599E7DEB9F3CA4CC29D300993CC
+:10BD80009099DC840422043A814041512711111515
+:10BD90006D44DB066B7508C8FB11514BB4DADC90BF
+:10BDA00004921060B0AE44E43189A2A8A08382D28C
+:10BDB00096DA01B3145DBB4DAD456AD146D0A808F3
+:10BDC0003452517657D7FDFFFFDC4BE64E2689D61D
+:10BDD000ED6EBE4F0FE79EF7FF3EFFF9CF19C61875
+:10BDE000FB2A17FE5795C4A2058CFE285F99CAA2AC
+:10BDF000B698FCFC4C637930D7982F1F69CC7BC672
+:10BE00001ADBBB2F36947F7E1D631D4EC8487E1BF8
+:10BE100083543A7AB3AD6C3463B5EEE5943F7FBB9F
+:10BE20005E1E48C27C9E7CD28EE58F5555D8582127
+:10BE300063AB3C330605E1FB57F87779EFB4A19A81
+:10BE4000B1A895B135D5214A9BAA5B286D2E6222F7
+:10BE50002B666CED6831DC96C3D8EAC219D45FBD9D
+:10BE6000BBFFFEDAB0BF118C85AB6D946EAD96A9A9
+:10BE7000BFCDD51E4A6BAB154A37551750DA52ED78
+:10BE8000A77A0F554FA434541DA0745DF5342A7F52
+:10BE9000BEBA8CF2BBABCB297DB63A48DF7755CF23
+:10BEA000A7F4E9EA4A4A9FACAEA2F4896A95D2EDBA
+:10BEB000D50D94AAB2C8581AACE74A7F6619CCFFD0
+:10BEC000D12B5979A4B0F7BC5559E0F56480E578D9
+:10BED000C6925828CADC882FE84B61CCDE10623647
+:10BEE0008047E662F886F9AA10B342DE3387E7D7C7
+:10BEF000E138D0AE8AB100C28D15B0F076809B4D8E
+:10BF000009B159305EC0ABB21B92199BAE8D83DF75
+:10BF1000118E6A8ECA105F272C81EBE434EC8751B6
+:10BF200079FEFE8E8388D6311D91524C0B0F8744CB
+:10BF300009D291532A579A201D345915B1FD2A8FE1
+:10BF4000582AC078E7AAC4B009BA568AD94113E47E
+:10BF50001F2B14C34D307E73091345C46306E05193
+:10BF6000E8596FD2F9AD2C3A0EF05A3563104B00F8
+:10BF70000F3D1D3A5FECA147F82F2398D443AFF053
+:10BF8000DFEA50FFEDC7EC110DF50B77C6B52F8436
+:10BF9000F6FDD0D3C8C78CED0B362719E6B3DAD33C
+:10BFA000FFF8F9E7AFA775F645B7A72C153F43B8DB
+:10BFB000EBF9F4F397B1E860C6DE72CA84CFD46BB4
+:10BFC000EFF3040B69B82926A007298B859B04CCC5
+:10BFD00006D86C80AB19FED524F33CC2DD04486A58
+:10BFE000F223BB2A019682A93FC0C6601AA0FC2199
+:10BFF00073B0591E8FF932FE5D0E121D345F045D61
+:10C000005C8CFD6437042643FEFBF0CF4CC6AE0FBC
+:10C010005D344D85FCE7E6A05805E3AFF5727E5C24
+:10C02000E11B9B84EB7EB4B97F7EACD5F851CF9BEE
+:10C030009C0126403FB90DF258A4A3BEDA3DD8209A
+:10C040004E0B27E8F729A45F987F7DC30C391F5753
+:10C05000DD8E328B31AB9311BDC5D787F53E85F0B0
+:10C0600035BBF93AD36E2AA3346FE7245B19F0C3CA
+:10C07000E7C9FDE3AF316EFE76183292605E1F6A4B
+:10C08000F3CA7BED17241F3F1FDD3F5DE972EF7C94
+:10C0900058641D885FA98CE469DA4D419607EB5915
+:10C0A0000DFCE244B9F7E58D0D3980577583487270
+:10C0B000409F7FFCB826A5B34484F2D5071630050F
+:10C0C000C6377BCA985A88795D3E4718F6EF707676
+:10C0D0000470BD0E160A98A07F475550C5EF168F05
+:10C0E000CA90CE56675CA84FF2764D481411BEAB8D
+:10C0F000B2C4301328654EE4F76246F9E48CE702D7
+:10C100002292CD17309F09D00FFEDB84F05699881C
+:10C11000EBC8677E27CCCB56D01D10A17E1EDB1747
+:10C120004579602B61FE26E49F8C2301A45BF50E0C
+:10C13000E6CF27320F923C6252D086F22AB7650CC6
+:10C14000F1834D8908B8EE1F5882EFC5F28BC5C345
+:10C15000E5D8EA2F4D09E5EABF6A7231A90FBC396B
+:10C160005CBCFC73B3720DE91BC8B725A023B38B6D
+:10C17000CBF13679C6EF0B941EBED4CBDFC2458E11
+:10C18000EFC9E79EB7D0BCF36EFAF1205C4F5F7445
+:10C19000B04AA3AFF583B8DCCD9B7C6900E17D0E8E
+:10C1A000E6DA24F4AEBF609042F5F4BCE434CAC7CA
+:10C1B000AF3F3F89E452DEA97B381F78FBA7577D4C
+:10C1C0009E9F7B8DF6809867233D5D1F12492ED57B
+:10C1D000BA459602F9AD481F3928303BED17C17AB0
+:10C1E0006C6F9818E27B6B55A9A84279728E142661
+:10C1F000FAF37447519CD9257600E903F0ABB8D225
+:10C2000010EF13087E59C51101E9FA94A617E1AFA2
+:10C21000CE0374E6E34B46FE1EE182EF819D02975A
+:10C22000031E2E07CCCCAF5A717CD0881118CFF1E9
+:10C230008689BE331689DE0FF92459F4A3DC5C5BD2
+:10C24000BC321DF9CDE162A4BFE65FDD46F209E430
+:10C25000AA7F13C8D1A51F75A52F837C9E87CB5DB0
+:10C260001D1E498516835E18701C291C403DE9106F
+:10C27000983FE4EF1BCEDFB85F5B98D9FFA17E410A
+:10C2800061A4135F687F3B549A1FAE1BFAB5B25F7F
+:10C29000D138E7B47198E9D861846FD27724664ABF
+:10C2A000C01F7D8E63BAA55FFD50756CC1EFDB6367
+:10C2B000E8F73657B2BB6B14FCE3BBECBB5FA18263
+:10C2C000303989BECE813D81E32A367610F375CDB3
+:10C2D0006238117F7C5E3DFFF7ED80BCB59A5EAFA2
+:10C2E00079D75A4AF4395E0C5BA17E7BDAD4CCCE86
+:10C2F00018BED0E5706D31D70340DD0CF9616DCD0E
+:10C30000516581D253EF49BD9EDCBFBED8AED76B1D
+:10C31000E6F5928BFD623041FD27347E7AC611B876
+:10C32000CF35BE675C65E5B49B490E8DB73153824E
+:10C33000F53DE308D6B962F858EF3FB63DD26F3FFE
+:10C34000ED9B5D697DB7F7DD3BED2DD67FFB07FBF0
+:10C350006B9FB57CDAA601E6BF39F1FCD56DD82E0E
+:10C36000D9636148E7351996DC06C8AF196FF15BF0
+:10C37000010FEDA3A77A106F75AE234A227A827E51
+:10C380009FE86F5E0097F201D6F5EC00702D17FA6A
+:10C390005FD78BFDB507B81E1D002EBF1900AE2D4F
+:10C3A00003CCFFB789DBABD938EFE42C0BE9931A48
+:10C3B0002FC0D58DFC0070653DFCF0D8863EE1FABB
+:10C3C000FA40F436C0BADE1A002F03D1EBF101E0D7
+:10C3D0003A10BD9EFC96F47AB60FB86EC3797F0B07
+:10C3E0007AFDF25BD2AB39F5DBD16B726AFF72601A
+:10C3F000207A4DEBAFFDD7A0576FA2F95B9923A030
+:10C40000A2FD53C8F5F8FC1291F4BAB980EB5FC7EE
+:10C41000B127488FD6819E1A3C11F5F5F187961603
+:10C42000F7E8E778FD13DF5FBCFE5CFAC9E3CC8E6A
+:10C4300078D4F49E3E1FBB12DFCF8FFAB5E3BEE97E
+:10C44000B8491E16B58FE9693FF2318BC18EFBF6F4
+:10C45000E319F57B52318C8FFE0418FF8A89A857A7
+:10C4600077FA912E873FF86DC7EDBF7EC16663FFF7
+:10C47000DFD41E98950AF680A3C71EC8AD7A7EDB6E
+:10C480007B837BFAC995024C06BA91D814B2DB586B
+:10C4900003F36FC7E2AADDDBDE1BD7630F0047881B
+:10C4A000B89FD0C7313544B6BD17B38EF37398B675
+:10C4B0000FABA47D4F9E7C7112D2F1EAE6FEEDE255
+:10C4C00067343DBE53F3373D85FE264877A0BF094C
+:10C4D000D2C7D1DF04E963E86F1A81FE29EE6F6AE3
+:10C4E000427F9315ED0FEE6F5A85FE2648F7A31F86
+:10C4F0000CD25F6A7EB07DD5614A5FA8DE41E99EBD
+:10C50000EA08953F57BD8FF291EA28E59B8B7E4262
+:10C5100072A6671DDC3ECF93757F5DFFEBF8CE3EC4
+:10C52000E33E6274C4E82719B523D590BF289C69FF
+:10C53000A83FA225D7509E1F1A69281FD630D69033
+:10C5400077145C6CA86F574A8D74E5B9C6503F47A5
+:10C550009D61C86757DD6CA8EFADAC30940F9DBFEF
+:10C56000D0509E115C6EC80F29BFD750DF15586997
+:10C57000281F34B1C9507E69F70386FC251F6E322F
+:10C58000D49FD4D96628FFEED1A70CE5E33B9E33B8
+:10C59000E4C71DFEA5A1FEF71CC128CAC3A2E8413D
+:10C5A00023BFB04E11F1D79EC268FF6387FD7B2089
+:10C5B000813DF95F83F83ED6CA4691BD7B0EE459B2
+:10C5C0005311B6AF0CE1FE3A17CA9A14DC9A8705EC
+:10C5D000368CA1AF286A4F89E5876F260770A78F31
+:10C5E000F57DF0877CF95FFAFE75875DBD0CC7CFDE
+:10C5F000E3F2589555D207F1ED75BF50DE8E998361
+:10C60000B0BC4E2E9513C9851396E089583D11BFD5
+:10C61000DFCD0B24B3008ED7A0FBC5B8DC33F12AE5
+:10C620002CF7D8558705F483958F49C5F5E8FE9C0E
+:10C63000D51ABFD66B7C6A6597A8E8AF38A7EDFB23
+:10C640009869B2BF3F39150FAF6F2AD7BE488DDF4B
+:10C65000E74C8FBE8FE33748E144FA524F75799625
+:10C66000F7C66DFDE24787AF8E4793DC1140FD6A48
+:10C67000532A5985B3379C4C599C1EFED9EB1E3A60
+:10C68000D828CFCFB1C2D240EED7586FF9ADB40E93
+:10C690001D9FF1F5D655F37D5733E295CE1164CD4C
+:10C6A000DFCFF12B4E0CAC44F8A6C03E1AFD02A21F
+:10C6B0003FCA3A13CC7BD044237D25FB8D72D051E9
+:10C6C00060948392D32807CDFE4A16413F2D8CC338
+:10C6D000881E830CFDB6F81FF19F3C10DF5D121021
+:10C6E00062E87020FEC321BE1A3630BFFEA3FCDD17
+:10C6F0003E279DFABF47E36FE0689EAAEC75A49FB2
+:10C700008A891A0131E5877F81792F386C263FCFDE
+:10C71000E55F6C3BB405FDD113AD32FAA3190B1DD7
+:10C72000FA3594CF09D8CA30BFE0D8688B0FCA8FCA
+:10C7300064021178B0BC2C05E5C069264E433FDD8C
+:10C7400069F67ACAB81839B764B085FB7F1ACCC7C6
+:10C750003B6D38BC4AE753B787785E5FD7BC16633A
+:10C760007E2E9B912EC138731F34A3E4630B987403
+:10C77000BC538703D0C18F07CBB49E79AC72950CA4
+:10C78000E3D69BF9F9CC9217475B100F0BC6C9395A
+:10C79000A6A29E79DC3D98FB014F02BD29D69EEFF3
+:10C7A0000B9D610BCAE5137BC6FDE01286FD845725
+:10C7B00065A25FD305F688D21BBEB31B8CF31C6841
+:10C7C0001DF1F3666C25C1A3AF79483B844022FF7D
+:10C7D00079ED60C180C75ADBCFB675C23C03B51294
+:10C7E000B35F0679899F1FA9C792C3DB517E975615
+:10C7F0003ED1097050575AE55A48373A7EF62CD642
+:10C80000AF0284E1F9D3CEC10AF79FDA7D613C5FC4
+:10C81000007DF3DD19C9DFBEDFDDFFA47E5FC07ED2
+:10C82000D37AF7BBC4D669C173B46552E5344144C9
+:10C83000BF22AF6735070343D19FB8AF283A5431C1
+:10C84000D46BF89AF50E0BB95FABDE34B19FFECE18
+:10C8500068F2EDB73B1FB5A0DC3AFDD4BBD7E3BE11
+:10C8600068D1AF4CCC06F5CEEC4C6651B2FBC2168B
+:10C87000B45F17EE3105C2948F4EB8313996AF6B65
+:10C88000A9FF45CF26D3BE6AE173D6F07468BFF026
+:10C8900085136318C883332BBB0F0D45F83D2590D6
+:10C8A0001DCDD4CE3137C2F78512BBAD2C81DDF161
+:10C8B000678D1F4EFDC2518EF426EC38702BF51B90
+:10C8C000F9A1D91AA3C73A069B099F508FFCDBEA4E
+:10C8D0009342385FE0F3BB6174ECFC6A78BD27B922
+:10C8E0003F77E13E73D88EF3DBD16A0942BD653BE9
+:10C8F0003E21FABEE2D95D29088765FB4C06B9B630
+:10C90000E8D92F575D0C785E6462DDD3498F7F4193
+:10C91000F973015BB789E450204500B9B59444161A
+:10C92000D47BFE83A97F81F2931E13B3832838D969
+:10C93000F1BEE557980F3A2B991FFB37F2E1B21D74
+:10C94000272C382F5964DD59C0E8977D1AC397AC5E
+:10C95000777DC6BA2D286797451A3F3101BD2DDB7B
+:10C9600073FA2DA4BB6571FC7C12FF91D15B5F0A49
+:10C97000EE787DF9DA0486E7F43B601334A96F7D25
+:10C98000A9F3F7A25DE7B6AA30FEA9E73EDEAA0248
+:10C99000CA17FFF7DFB7FE14F7492FD965944BCBC1
+:10C9A0009EFA530A8B817F969B9F279D79F289C7B8
+:10C9B00037011CCEFCD94A503BF3EB0F7C0AC0FD7B
+:10C9C000CCEEFF48C7F3A5BB7E7DE510A4B3BBF654
+:10C9D0005E31A4BF7D05D26DD81A8BDF30F5AFEC88
+:10C9E0008371864076BF96C6E1E5D4EECF2D784EB2
+:10C9F000F499C0BA51FE2E8D7C6941FBEC508075D4
+:10CA0000239C5EDE73E2D0BD903F0D78B226C0134A
+:10CA1000AC7FA8487A253A14F5CBD23D377EEFD2C9
+:10CA2000624CCD7E05F1C4BA49DEF7C2EF1B80DF50
+:10CA3000E21EFCC6979F635F5810FECB76023EC78E
+:10CA4000205E019F637AE3F334FE63526F7C5ED213
+:10CA50000B9F8BB76DC2C23D8309FF7DE173C9DEB9
+:10CA6000EFF76B67E9F2612038CF17F8BCACEEC086
+:10CA7000B56EE4B3E71CAA87E3393C1DCACEEC3A95
+:10CA8000E74367C887E6EE5B110EDDBFB6CA786E76
+:10CA9000BFF0D76F12DF9DD9FB070BE21FFE528458
+:10CAA00009906717FE5E67905FCA6D70B684754F18
+:10CAB0007DAB1853D6ADFA097F943F047C48F80843
+:10CAC000DF304D41F91B4EA3752F0D73FE581A3EF2
+:10CAD000709330A637DCEBDDA276FED3835761225C
+:10CAE000E2F3DDA9487F7DE1535FBF8CEBFF2E941D
+:10CAF0003F66E4DFF8FA4B815F717FD40BBFE1033F
+:10CB0000FF8EE99956AB24802D7406ED04676FBC47
+:10CB1000F7C09FEBE76F6A1F57C7D187DE5E87D3E9
+:10CB200040FC3ED0FABE29FC96B815031DE9703CC6
+:10CB3000F545627DF088263F96B2CA6999C37AEBC3
+:10CB400033132B53870A3DF35D1531919C3FB5C3D9
+:10CB500044E733F1F262299EDB2618E74937B763D1
+:10CB600096EE3B3006E5DAA983BFD0E892D3FDD23A
+:10CB70009DEF5A544D3F8463E5731FE7C0CF6BF3BD
+:10CB80005EB63F717FCB767E92B0BF9352E087381E
+:10CB9000FF931D66A642172723A684710B5BDC66F4
+:10CBA00083DDB52A79C2D141B82F48495270DDB52D
+:10CBB0002B036FE2B9A8FABA99CEF999E4FFD00A2B
+:10CBC000E5B5C9490AFAF36A53E63225468FD7C557
+:10CBD000C149F294D1F99DE42E2BE67BBAB0E1BCB9
+:10CBE000D70C04113B6FD0BB59A897DE29FAC08C33
+:10CBF000EBFC6B9C1DF95789AD1A02FDFD5515FC28
+:10CC0000354AA2FD81B1FFE07D26A6C4F4BFD4DA87
+:10CC1000FD0ECE87FDC6CED02E33BD6417509E2CA0
+:10CC2000DB6AA6FDD732D85621DC3ED8620FAB9026
+:10CC3000DFF87CF5ADA897FEB6D5CAF05CE2E5BD9D
+:10CC40002BBAEE41B9F488C0D09FFEB75F547F86FF
+:10CC50007A79C166581DC893798EEEC7B1FDBC675D
+:10CC600087B25A68FFB11099809BD9AEB4E804DC52
+:10CC70008774EDCAF0ABD4CF8B4BB1DF33CF3AA87A
+:10CC8000DF33BF7993C639F39B64D26BFAFCC1DE04
+:10CC90005662F538D8DBCA053E207B3B260FE32CD5
+:10CCA000C23CAF2F7CA5C93C947F8B3005BA5FB4E2
+:10CCB0006F5000FDBB31F5A89F65D6EE9FF869FF68
+:10CCC000AD668AB4778A66223F2EDA611CFF3FDCAC
+:10CCD000DCAE5A66E99ECBEB873239DF76503B4BB0
+:10CCE0009A46AF5A797C7BBDBE94966BA8A7B75F76
+:10CCF0006A659589F8C0A5F5BB68C797238CFD7157
+:10CD0000BAED3D0EFF7EB7C0C87FC276DB29EE6C60
+:10CD1000B1253A3C15F8F6050B9B8FFCBB38253A3C
+:10CD2000DC05E3FD4A939B8B93200FDF33B57960DD
+:10CD30007DCC335BE719C4EB9217ED74AEB2E4859A
+:10CD4000373F437C9E421803C64EA5757CF653A020
+:10CD500083535B4C4C057B6D8935EA7B04F5D46EBF
+:10CD60002B6B43FE7EE915D25BA79FB38AFD9D53D3
+:10CD70002F890035D87AAF432D6505954E8CB709BC
+:10CD800088ADB86F386C0AD7C0D8555260E5B3B8D3
+:10CD9000BEC366DA679C9DC30A705F799665FA55D3
+:10CDA000C2BFF2A604E52B5E350B89E290CCE741C9
+:10CDB000A88F033E387F2D532095CE0FA37485A5F1
+:10CDC0007204CA5D930C8B2B243F01D9ED66B79F8B
+:10CDD000CD8374452A0B22FC98F39A0BFCF57B401B
+:10CDE000E9F2879521D86E521A972B73D20357A672
+:10CDF000917C71CAE457D2E854DDCBE7F9B990E4ED
+:10CE0000AF8179E59DBFF73684EFF2770525F6FC13
+:10CE10003C3ECEB34A52DE548A69BD248FF2E424EC
+:10CE200086703D2BF3B8BEB3739441AE18B9BCA65F
+:10CE30005A26F9D158EDA17475750153C8BFE6A7FC
+:10CE4000BC495BBFB550A53835E469FCB33ACB02A9
+:10CE500068E7E19CF2153CEE0F121D593D95E49BED
+:10CE6000B23919ED634D4E95CD83D4ECE4F03139F0
+:10CE7000CB083E162D2FB54C2778427BFA7E797A67
+:10CE80007011C2C39635D220972CEEB1867C2F78D4
+:10CE9000E9F8DFF57F053746706AACB651BABA7A61
+:10CEA00022C1ABBE3A40F9FF07B83DC0E17631C6BA
+:10CEB0005AC4C0ADD490EF136E0F03DFB863F90608
+:10CEC000E0887CC392FCDB13AC3F3E7DA81A17C7F9
+:10CED000D803D52D94EADF53FBD0DB9FA4713BA090
+:10CEE0008A056BCC74BEC5FD2DCCADB2AC093DFE40
+:10CEF0004DE651998279E455C4CBD12482DDF2B755
+:10CF0000EDE43736C95257AC5C5B7E9D3204E59741
+:10CF1000A9EA517662708C1F6D7A995D21B8FA0585
+:10CF2000F4A7D66A7AB3FE02FE8C7CB0A65AA1742E
+:10CF3000ADC60FEB357ED88078867CAD9F9F6F366F
+:10CF40004F63A417FF05F27C1F1F65B171262E7F6A
+:10CF5000246A067C938C54288D529CEF516B381FA9
+:10CF6000E3A80A19C5D1B98EDE43FE63C6221EF4BA
+:10CF7000A7B934B8B1FDB9AE99C9B43C33D73BCCED
+:10CF8000C4D39019EDF178B8D6FA0FDA707FDDD7F7
+:10CF90007C4ADE5920E0789FCF243431F72D91A3CD
+:10CFA00015B00E67B383F46ABABF321BFD7BEC98F1
+:10CFB00095E8D3E90F0AF362F097DE875D7767FAA9
+:10CFC000D57F45FAEB4459067AE88196617684F379
+:10CFD0001A73C483F26E8D8BEB0FA51CA0F0DD9E3F
+:10CFE00076AF687230A5D8C8EFBA7C95278F35D058
+:10CFF000AF2E5753A718E95C97ABCFA7717FC59C9D
+:10D00000F4B24FD2201D7C7E33F1613CDDE7C917BD
+:10D010009707DDA80798BF09ED35B419D18E7B5766
+:10D0200008737AE7FEA9B39D396D68E7C0AE80E466
+:10D030008A8AFC4078EA7EF92B68B74B930F2B6DF8
+:10D04000336CB8DE06A02386E77A403F08E07540DF
+:10D050003F9886807E387F4CA454A74F4F7A8E210C
+:10D060002ED0947748E4F1F222F99E25D8DF396179
+:10D070003CE9C0241BDA7B92D97F18E55477B218BB
+:10D0800041BD59EF9C610BA0FFC6554C78FF2CB9F0
+:10D0900022BBBF3827B05BC86F2B3BFDEC388EC37B
+:10D0A00018F96D4DF25886FBC45DCE8E24DCB7585E
+:10D0B000D345C3BCE6A407BDE931F9D138BA862F00
+:10D0C000EC7697D64FFC7817A56B7ECB2C95056236
+:10D0D000CE2DAA74FA5654362586BF57E64F6518EA
+:10D0E0007F11CFD77DCAADEDDF4E6ED56687095F64
+:10D0F000E67879E10639EEA45415659CB777CD8FB3
+:10D100008A88AE2E4DC7FDA1B3ED821D72796E02E5
+:10D11000FA3A3A7208C5675ED033B06B2E243DB33D
+:10D120007122B747343DC3F5D3D96607E9A7B37376
+:10D130002A299EEA6CF31005E9EEC0BA4BC6203CE2
+:10D14000E69E6F640ACC6FDEF94994CE6FF939A57B
+:10D15000152DAD40E48CD5AC9DB76E26B43BF1B037
+:10D1600089E283BAC2E3CE5441BEABD9CA4C304E39
+:10D17000D7E63BB3D12FDE05E3A07DD5B5399FE8D7
+:10D18000AB0BE046F906637D8C0B36015E2A18C7AF
+:10D190000BFC2F80F5E7BE626A4D642755ACB706DD
+:10D1A000129DEF5C286F496CB7D5E23F33F07F9555
+:10D1B00023105E25EFDC938DEBD5F97F452AC8233C
+:10D1C00084D73B5696C81F7F79FA9573912E2F4FBF
+:10D1D0000F2CE578494DE85FEBA17F3EEE0911EC9D
+:10D1E0005BC24B30E506839F95FB314F68F62FB34A
+:10D1F000F5519EA2B59713972F69FEF8D0FD0CEF5D
+:10D2000029549621D1EBFB691383FDB480FBDF1B0E
+:10D2100028FE599F0FD8A944C70CF081F2658EE60D
+:10D22000EF01B87FCF02DF4FBC6212903E7AE8294F
+:10D230009882768BB0E6BA95BBA0FCEF87F9FE6CBE
+:10D24000C1F90D24EF8435A3374E82EF77BE6226F5
+:10D25000395FD374C9FA5B00BF9FBE66A2FCFCF3C2
+:10D2600076AAF7D1FDFE8DB740BDEEDF99C90EFF5E
+:10D27000F4F09514FFF891D9E827983084F3F1F38E
+:10D280001A3FCF3DBF86EC0FBD7C6EC36C8B4274E2
+:10D29000BA8EBECFC5439B4C9CFFF7FFAD44C2F393
+:10D2A0001C46F7149E7FE8866B57925E1B4BF6FE7A
+:10D2B000BCB5567FA278D0E7D31583FC99D7D94C5B
+:10D2C000FD32B08BDCE95A7F317264DEF9C1C407EC
+:10D2D0004C5619C619CFD5E4C985F96D361BE4C97A
+:10D2E00047F6C47E9097D3F93E6AEEF94B88BF7A31
+:10D2F000AFEF32FA3E571FB793F363CF7A364E4AF9
+:10D30000B49E9E754CA6FA1FB9128F7F52836F5739
+:10D31000F57C1600B95461857A4E1CFFCE55138BEF
+:10D32000711DAE5421665DF35A16B140CCBAE66D5C
+:10D330009E65A988E9B7070FCB0C783899BE90F0A5
+:10D3400070677AD911E49B8A35978E417A9CD7D23F
+:10D3500048703E61F6FB50BE7ED072674AA238D854
+:10D3600093F1F869D1F003F66E710C7E74BCC4B70A
+:10D37000EF7A7BDE6718D7D4F530376EFA82572FF5
+:10D38000BCE524869B3484E3AD0BF46D90E0A6BC31
+:10D390007014E97AADC38F74DD37FC46B1607FF05D
+:10D3A000EBC37E057BE74B943B12FA68F11CB28518
+:10D3B000D3C14070EB1957A38392C4EB197B613D35
+:10D3C000554C05863D6E19880E7ECA545B3FEBB8FE
+:10D3D00040073F37D0C1D88D4DD7AE847A1FA2BD4C
+:10D3E00032A237FE8F5BD4948BF1DCA7C944E74AA5
+:10D3F000C793D4F49B79BE08E5F1F194D0F5784E4B
+:10D40000A3E7176CCF4F991533EE070D008704F093
+:10D410001B3B4431F8A12ED04F9ECA0A27FCF3E8EB
+:10D42000E78439F13DBECBD34B260C413B2594D844
+:10D430005FABA7BABC360D725ED867A2FE3CEECCDD
+:10D44000FD2C0CA5F5E9C1D221E3317EF427B7A16B
+:10D450003C387E5C207D5BF3F68A11A8D7E2ED04B0
+:10D46000D87F36E0B9E70A537288EC50A9721B9D49
+:10D4700083AA12DB5E8CFB94CA4DEFE5A3DFB08A72
+:10D4800052A6D9A12B4C23FD4DE497AD7C02CF4988
+:10D49000814864AC2FB14A3A3705415886F98D0E60
+:10D4A0007EEE5A25D9646B4C5CC2624D9ED757976D
+:10D4B000FDFC3DF443DB5426A7637B2E3725C6EDE8
+:10D4C000AFFFC479C6E87B8B3928FB711F2AB032C5
+:10D4D000E40BB314A47B4E668FBB488DC1C3C2213D
+:10D4E000DC7EB4B7B737E4407BFBEDBF93510F5AF6
+:10D4F000611CF4B3D9B2A4B3B1FE6AB33B42F7984E
+:10D50000585ECC77B0AB9C859037F80160BEFDD8F3
+:10D5100085BF12FC9ECF901E6B383C26228820FDD2
+:10D52000F39C61AD2897274A75268C3B9A797B3E00
+:10D53000E537CEFE6A7867027A98B97F7507DA33E5
+:10D5400033F767CCC6F38399CEE1EF630ADB055B63
+:10D5500012B47F5960912648A7D81EA5B8C6973542
+:10D56000FF583BE663F462BB466F60E74CDB0DE9B6
+:10D570004C5BC87C47618F3F2D7EDC0D1ADFB79B6B
+:10D58000236923910E601C5CC78FF787BF0FAA9F8A
+:10D59000DD12095F371AF0732BEB36231C834CA680
+:10D5A000730FDDAF5BC1FC5A9ED1FEF42F8BCD6DA6
+:10D5B0004827F1FDDD12E5FDFDB81DFA83F4D6C361
+:10D5C000DDFF8A6A391891A73A584C7FFBFC871C0B
+:10D5D000AC777FF170F64B36931A03574091180BD6
+:10D5E000F75EF01D547E0D1BD3379FF5C09BCF23F4
+:10D5F0001E1F9F6211F0E9234302BB906FEF1D12C3
+:10D600007806D3C5B66E9F047473C41D7C0EF34BAD
+:10D610004DC1EC7480C7696F70441AC2A523F1F93B
+:10D620006B3C7FE7959FDE827C736B8DC410CFAB24
+:10D63000F67EB005F9F2B419F808F6032FDFF341CE
+:10D6400032D2CD1260C05879F24E553ED94F67F7AD
+:10D650008CE8F7BEC93B9ABFE4558D4FF475DE8662
+:10D660000C08E3DDB6C741FB99DBAA4C17F6594815
+:10D67000EFB755F1F81026758CB9C96077D669E710
+:10D680006CBDFBC17D447C3F5DD5C16DC4F752705C
+:10D6900002DADD27AAE76F43F9123F4FC5137C7BFF
+:10D6A00008E9B75986B8DB39CD0BB6C5F2A15EBF24
+:10D6B000B60FF9BA7FB8B64E1B1F8F29DF29714EFE
+:10D6C000A07B99F4678FDADE1562E861A0F158DE7D
+:10D6D00094C005B940F7E545E64CEFDD5F7C3DBD04
+:10D6E0007F4FD515ECC4385C5FE0DC90F103CF9F31
+:10D6F000793479A6B5D3BFDB83218676A1FD8B4132
+:10D700006427EC1FCEFD0F9F6A760173C27A91C128
+:10D71000421B03FF1FEB8581E95EA67DB335615C8B
+:10D72000519A47E274133954624B30BF5EFD452570
+:10D73000F675EAED1FCEA85F749391BF6B7812ED7A
+:10D740006B2AAA6A699FDD08F203F541FC7C8E37DB
+:10D750003DA2A01EB05B420AFA451B87A7E7AC8436
+:10D760007620D5C8EF634F0A2952EC77CD1F645F4E
+:10D770001952707FDB989F49DFF5FE1A052E6775F9
+:10D78000BE68847DDF73E417F37B66605CE91BE1B0
+:10D7900069C9D0AE6D158B9A7C8C1DF4658EC27DE7
+:10D7A0006EA8DE42E77B8D0562C61CC8A7786DE4D3
+:10D7B0001F6B754567E23D5A559048BF865CCAD5D8
+:10D7C000C9E8DF5D39A403E5DFC13B2CB4DE359346
+:10D7D00044DA8F592F7E2F7405F67F17F3A35E6D01
+:10D7E0003BFF7C8B13E5F051D8CFA2DF103B0579CE
+:10D7F000D436EDAC1DF773A918570774B3D91CA123
+:10D80000796DAAB152BF9B5A2DE589F0F77E864407
+:10D81000F5C34227C5070F66113BC2F58169333650
+:10D82000E641BB9C3C26E37E7E4DE1596DBF19303D
+:10D83000F1F328DD8FC8ECDA79964D3BA7B2C5C667
+:10D84000173E12DA43FE43C7F4084FA789E47F8EE0
+:10D850009FC7520FF7E33926774C433DE1281699CD
+:10D8600080FECD3C26E0BAE4696D748F39A780F55F
+:10D87000D19EAF5B0E40FB62DE1E7D42F2D76C3F55
+:10D88000D7C3E30CD7A21F0ACAC366BF7035CC2327
+:10D890007C9D2CA84A4FBD6A0FD7AFDBA0FF28C9DB
+:10D8A000D130ADCB57108922BDF9168B84A7B513A3
+:10D8B0008FD3B9C003C5BA1FD54FF3D85C73E4004A
+:10D8C000DA5F9BEF6664276D46190AED365FC7C2C3
+:10D8D000FC3C8965A27CDBB4C0722D9DE71702FC7D
+:10D8E000054A13CEFB4719365AB7EFBE07A2784F49
+:10D8F0003FC9CFEFDF429AB07E6D8689E6BFC91C73
+:10D90000CE40FF485F743143C387AF4AB3AB58C8BA
+:10D9100083785DA7C187DD3496FB17A480121BC7EF
+:10D92000D5A34FB81F03D64771AD83EB2CA48FC48A
+:10D93000E9D199B8AED4020BBB2A07F98BC34D1DB0
+:10D940002DF2B833166E41FE6CBD289DE249578B0F
+:10D95000610FDD132FB5D079F2C189E2CCF950BE49
+:10D96000BECE427E08C813BF8402B9ADC86F8EC94F
+:10D97000A5E5F321BF41B6C808DFDA42D98E745C51
+:10D980001B106501F2EBCAF47B128CDE3128329950
+:10D99000EC0550BE2D43441F2DDB2608C4EFF58156
+:10D9A000D2D030F85E2FBB85583FC05E0DFF8BB2E2
+:10D9B000CBF67A906F020F8486291C97D20422310D
+:10D9C000FA4B66D1F91873D35AFFF851BA0F556460
+:10D9D000A3FBB3DEBB42E574DFF1228B82786D3BA3
+:10D9E0003F7814ADAFCEA2203F6F10C25723DF6F38
+:10D9F000BEE3908A7E75FBFB4E8C1D66CECE4FAA91
+:10DA0000317ECC596C893BC76222CA717D5CE71BB1
+:10DA100051A2A74E21F8C764F2FF143615B8299E0B
+:10DA20007902C273DDC56F15CC4D4017D0DE993E2B
+:10DA300016ED65313A610CCA29AEC7982467C4E275
+:10DA4000778337F3CFE867DA5A02F3C7F1AABA6EE1
+:10DA5000A179058EFC14ED2AE7B18FBE4C3CCFD7DF
+:10DA6000498F241F7344C531982E994EF6596C3D49
+:10DA700090FB8DD981BF7A00BEBB6AB8DC6FBE9DBA
+:10DA8000D1BB13F8571003DFE64290D2F4000140F7
+:10DA90001EEB15CAE4475F2D2A9128C2738C8DE8CE
+:10DAA00069080B925C8B5FAFE358E31D1877E4F0D5
+:10DAB0001BE77956C32FFE49E9745E819628B3644B
+:10DAC000CCB1A3FCDB3D56C9C0FDF603AEC47AFE63
+:10DAD0004F197C5FB44B486C9FFF2DC3CEFB075999
+:10DAE000199D40A86214D70779319DCE6DC8C96DC4
+:10DAF00015B95C60D730D27B29459D767FCC784FB5
+:10DB00006BE3D01FF433486BC7E4EE680DACBF1570
+:10DB1000A816EFB5A578391C9D6A0F1CB1BEACAD37
+:10DB20000BF8A06644310251A6FAACCC42E72220A1
+:10DB30000DD5AFC41E38246BF5374D94041BCC2B88
+:10DB4000178021407DD7348BE11C45AE3BA262F9A2
+:10DB50004F4D4C499DD833FE9622165E09E30F0ABD
+:10DB600018E19D7CD70B2BD02E8FA7039CC1857EFF
+:10DB700031547C8EB15DFA2DBDF880E049F304D0BC
+:10DB800034BFC1DA2C0094E61D921E1F4BF277BC05
+:10DB9000A943457F280624ED85F98F7CF28DC04E80
+:10DBA000C83707399F2517BCB002E9D291C9F1F4F3
+:10DBB00047F42D43FA0893FF8E713B6A95A8203EE7
+:10DBC000B64673498F3732A90CF1D458794444B919
+:10DBD000BE660FF30B02D2FF7F5B63E77753460EFF
+:10DBE000C7BBA490FC937CFCFEE89A42D181F2F57D
+:10DBF000E01D2F90DEDB724064C8FFA5BF3DF6B08C
+:10DC000003E9FACF56CA37BF524972E327D04E4DC7
+:10DC1000E03F1F482FC7D7CF5BD226E0F944F6FC80
+:10DC2000C82BC3513E8724FF55888FF91D0184936B
+:10DC300052CCCFD99CD3A3F44E88825A0D6C522576
+:10DC4000A4A5CDBC9CDD944AFBA8D1D6CE866B6042
+:10DC50007E8F3C2931D497266B24631EF46B7AD1D6
+:10DC6000899AA0D7FEE891E9D10C94E3499514066E
+:10DC7000DD6B7E6F67703EF44D575E1D0EFDBA265C
+:10DC80007358DA43430EA0BC449B19EF553854AE89
+:10DC9000E7D649E100C679AFBB2B68C1F199B67FE1
+:10DCA000695C52F138C2F984A6F758E57C7AAFC4B2
+:10DCB000A7F18BA38A9524DA673DE049E2F12DF7BD
+:10DCC0008B07903F7C0146FA43AE8A4447687A1935
+:10DCD000272EDFF75C23EA17E76291D6B14EEAA858
+:10DCE000C17725D6DDC5E41AA5777FFF68FBE51966
+:10DCF000567E2E8A384EEB5907B9E440BEF9E62726
+:10DD00005E4708C71DDFB38E247D1D059D94D7E7B0
+:10DD1000B12D10F95AF3D8A0AD634D067FA7C851B5
+:10DD2000D849EFB3C4CBFB958E77E8FD9830D8EA9D
+:10DD300026BA8F16B906F3CAB322E3F7B58CFCDD19
+:10DD40002BAFD155FC7785C58C938374C7F10C74C8
+:10DD5000A7D94FC077361401A2F215F93142FC9DC4
+:10DD60009C387AFCA7CBC5D87943FFC90D4CA0B825
+:10DD7000B8C54C29CDE82D179926176D4C8DA2FCFE
+:10DD8000FBBF968B2007492E36C34A07C34E25B9E1
+:10DD9000BDE90ED4E3BA3C1C8F38C177A254F375A9
+:10DDA000A585B42FA27CD1C3AF36D37B43A276DE48
+:10DDB000A5C105DD500897CF3D8A419F3E84FF8075
+:10DDC00075EC6E4FBDB610C6DB589E5B84FB0B7BBB
+:10DDD000E845B20F7C853C7EC557C5CFCF1D797312
+:10DDE0001F8FBD17B730C342F4B750A7BFAA900723
+:10DDF000C75987FDA27CCEB390BE7C8445B83ED483
+:10DE0000ECD3168F1647ACD1553C9FC4CBA771BF3E
+:10DE10007397A27CCF10AC32EEE7503F1F4C37EA2D
+:10DE20006BA4175D5FB774AC74A13F2C47F3F7E7A1
+:10DE3000D88C710E45995C5F7FA5F901568B95B41E
+:10DE4000DF544B45DAC7E9F477418FC7C1311E7EF5
+:10DE500048A8AB26507C0CE5534ABA19F2EF56207D
+:10DE6000D90D5066CB5034FB402638B7FE581C8B7A
+:10DE7000F272777B851DFDEB82CF7635EE0FD70BE7
+:10DE80002C8A72737DC9EB1457D254053DC3A29CF2
+:10DE900005E22CCB98DE78063EA6FDAA43B576A017
+:10DEA0005F2B126DA3B885A6F0A1998CDBB10CE3B2
+:10DEB000529A0A56662E44F95E50568CF86DADB7EC
+:10DEC00050DC8C5CC012FA11DED7F631DF548F398A
+:10DED000F4FDE5E2C4FBCA6B32F9FE362281A8826A
+:10DEE000F96415887EE4FFAC3A4BC2795CAAE1295B
+:10DEF0002D93DF0F6BAD3F9441EF63899561D61F82
+:10DF0000BE60FA2BD363F031A90F7C78747C483A59
+:10DF10003E5CB3880F3B3B442E6F49AFAD63F2CDFF
+:10DF2000A81FD54A0BD9B18D66BE2F6F2BD4F842EE
+:10DF3000B6B522B17D53BA4E5922D23D1CEF449161
+:10DF4000F6898EC5CF515CD323ACFB1594778063E3
+:10DF50001A2FBE7D79A6A8C15111FCB49FE67804A2
+:10DF6000BCD27C36E7A7B7C6F2E9039A1DFD8087CD
+:10DF7000F3E9E6FA87884FBFEE3C75B95DABD9D1BE
+:10DF80000B02410BAA0355289B9A81FAF331E6470D
+:10DF900038319393ECF20FB1498C5FF6CEACE0C20E
+:10DFA000CC98F345395049EF165E89EF0A41FB0FD3
+:10DFB00022FC3EE80791E74BE8DDAD2023665EC01A
+:10DFC0003A04627290A1DB21EF912254EE990F7313
+:10DFD00071D1ED48CADB6CA0176142A7ABF9FD8B8C
+:10DFE0002EEDBDC8C7B5F7223FC6F721211DDDB212
+:10DFF000BAF4111C4F918228334EE27B9178FF795D
+:10E00000E25B14177D0A646D930BE3617E5542F762
+:10E010004FEE65B23809F36B4B31EEF9CE97ACDABF
+:10E020003DC98E9578EFE55111D60D6DD648A0EF1C
+:10E0300087615183501943C7BB2EED48C173BED3CE
+:10E04000911BFBF51FE3FD417A2F3393E369836353
+:10E0500029DD2F9BEB8CFAB0FD81DD4F3CBE09C65C
+:10E06000FB78AF8DDE35D9E858EAC3F28F1F7ED337
+:10E0700087FAE2F4DE372D89CE27974891A9788F69
+:10E080006CB13A88AD84F99744665928FE64E7017B
+:10E09000BA9FB6440E5AB0FFC52DBB293F65E71F96
+:10E0A0007C58FE6626D713A733823EF44BE4B5585E
+:10E0B000A322E89F5DB9A18509CFD933456DDE2F35
+:10E0C00051FF1B1D2F1D42BC9C7ED84A7EB7030FFB
+:10E0D000FF96FA3DB5F7459AEFC7BBDEBC15EDE9F3
+:10E0E000C58CF9519E9FB66B7E3D5B474AECFE7630
+:10E0F0009F060F3D7F3A59DB07670D504F3B8F61FD
+:10E100004E803FDD1FE848C1FB851F9B831684C7F7
+:10E11000228407A425000794FB8B2202CD73514B68
+:10E120002BDDB75AB487FB071701BC082E2D0768F3
+:10E13000FE4732B9DC38B5F78F3E7A9F628F95F68D
+:10E14000CFFABA1739833E848FBE5E80035FF7AE85
+:10E15000AF87A7B93A9E5AFE40F35ABC87CF6BF1FE
+:10E160004E3E8FB97B004F4EC4D32CC2FFA9BD4C8D
+:10E17000C17B305DBBDF3C89F6CCE9BD3605ED0ADD
+:10E180007D5E59206E53C6221F717DCCF608A48F88
+:10E1900099D441E7394B6459C6F7092E94872D610C
+:10E1A0002E4F3B4A8742F9D30F8AF48E25932323BF
+:10E1B000D1BFFA61A67EFFA7C3877EB15D9786882F
+:10E1C0003E3F4AD6E02D75F8307E66C3D0E0879991
+:10E1D000B1F878F7C591B8EE15A6CADF7A719C2719
+:10E1E000787CE8E7B9957FBD9FE63DCC70DE189F4F
+:10E1F00002DC52F0FCBB406441BA97BCE7E5A4D80E
+:10E2000073E82F33B9BEDAE87887EE239EC6F71C91
+:10E21000693E118AD31A1EA8F0E139DF47CC19C430
+:10E2200073D98F1F7B99E26DBA3274FF5307D53BC8
+:10E23000B5E7E5544C2BB4787816BE91E418C0B11C
+:10E24000C13636917CD4EE1785F9BDB13302084C46
+:10E25000D4135B7438575A6618CE75B81CCDDA9C47
+:10E26000D34EFE9670E2FB66F1F237EFC14974AE11
+:10E270007C8E253E57665A9CDC0A5312C5DF6C74AF
+:10E28000FC8CEEDF56A95619EFAF1CD7E4E27BDA1F
+:10E290007B0B9F27A5A822D0CDF34383DEA169BDC8
+:10E2A000EFE156AC59E243F856E0B9076D6AB65D46
+:10E2B00087F1845D694C7B9F9445097E66BDFC5F58
+:10E2C00078B98BE78B873EB316ED13842FB7531FB6
+:10E2D000BD0EE31ABB7278791996437E566659E1F2
+:10E2E00050EE3711E81C89995D5D36AEC213C1A3AB
+:10E2F000072E12EBD2ED6AA83C7B2823B8427F138D
+:10E3000086D2BE1EFA1BFDEDFB03BCABB6D4FF8567
+:10E310007E6CFF5BFD44482F89417CEB0ABEF9B956
+:10E32000FE7BB494C94DAE6FDFFF3FDA7E852920B6
+:10E330007E8474384824BAD7F9BAEBE11145B8FFA6
+:10E34000B734DC1145B5D9955C6AC980EFE7147E16
+:10E350007E72FB831B0CEFA8EA69FC7BB5FA399E41
+:10E360006598F17C76D5502E8F560DEDF113E2B9FC
+:10E370001C1E57D1C619FE9AD3291486DBE9AC526C
+:10E38000C4F8C382761BBDD77B11034101F31FC5BF
+:10E39000A222EAEFD1AC93F2DF411040BE882926D9
+:10E3A000CC8F63DD3E69189E3F4757A19D76C41D03
+:10E3B000AC43BAFDECE18E770428FF4966F0979DE7
+:10E3C000E8EF1CCAED5427988548CF32A64087A2B3
+:10E3D00063BA2791DCBF004F593A157BDE76831470
+:10E3E00058C7F9224BEE72F4C05997070BB5F7974F
+:10E3F000F4F6279F7C2297DE1DEA7907BCDFFBC07D
+:10E4000073AB163CF8D8B87ECA3539BBAB267C73E3
+:10E41000ACBE6FD3E0BC7DA868B00B6154B2E39E84
+:10E42000BA81DB4FBB2E0DAC7C14E56D8B89F6D326
+:10E430001FB5FC91BF8753C6C8AEEB6BDC8FE2F013
+:10E44000FED1F62732F97947D8A0DF173CFE8B9131
+:10E45000B1F1960066C53D81BFC341783FE457AD39
+:10E4600026A4D232F2C75858258F53C1F90EC3F7EC
+:10E47000B822943A5907A529AC9B5299C9E49F4EFA
+:10E48000657E4ADDAC8CD274562970FB2E44692619
+:10E490008B509A85F629FA7B5837A50ADEF88C89C5
+:10E4A000DFC8C513D361F8DE6E19FF1E171F2421C4
+:10E4B0001EC72590E7717141D28E2A92E7181794F2
+:10E4C000EFEEFD9E822EBF370C2DFD13CABFE787EE
+:10E4D000068E20FD1C7EE6557EBF62AD40F6F50936
+:10E4E000FB748B02A87B3A3540EF80A8222BDB0E11
+:10E4F000FA7D8EEEFFC73F3D4E1881D96C3E151B4D
+:10E50000BFC36CCE023C2F9EAD559DAD9D83CCD636
+:10E51000FC20F8CE19BFA7E7A7FBF6B3B5F387D960
+:10E5200071FE1716B21AFC282AFE03D6313B24D0FE
+:10E53000B9C1ECA4E92F75B2BEE924A63FBAF757DA
+:10E5400011E7871AD09F15979F13DFDE26305B3ABD
+:10E550007EE7F4F4F4650AD975BA3F0B084EA1764C
+:10E560000DD677C92F14BA32100BA7E42CBE6FB5A5
+:10E5700087AE4A49F4EE929ECE01FBCC9CDABB3DBD
+:10E58000EC085DC8F7BA1CD6E93C0737B6C84705A2
+:10E590009684EFAEEAE91A4DDF37DD1F62386F7BF4
+:10E5A000F41E7A8FFA6EAF4ABE5A5B6198EE07246A
+:10E5B00015843D6A82F935E13BCEC05F4DC9C67313
+:10E5C00093C5599CFF1767F1F3DD4317A597E279CF
+:10E5D000F66A85BFEBBA5AE1BF47B03A6BA0F7C8FD
+:10E5E0006D867BF2AB066FA57780EC5F6C63684F3E
+:10E5F000DAA5C4F7526ED2E0BA41ABBF71F056F261
+:10E600009334E4F3F3FDF8FA07F21FA2F71F1B732C
+:10E6100060BF8BE9FD2AF55F9FFF5039B6B7451BF8
+:10E620000DF7797F94C5E59A6D0FA747539E259CFA
+:10E630008BF4208528BE40AFD7D8C779D2B42CAE92
+:10E640008F9ACC61BA27D3A4D9438BB31CEBC82FC4
+:10E6500097D57614F9F55C1EA3F3467BF4493A4747
+:10E66000B01558985DD07E0F00E33B0A23841F74D9
+:10E6700036450D741BF3EEBDA977FF755F853CB879
+:10E68000BEC69C108D3FD07A2FD5E0D9A8E9D746D9
+:10E69000BBF11C6DAE86EF2B75B8EC67244FFA8189
+:10E6A0000BD97BD336E75E8FF3B1ED1B108E86FA64
+:10E6B00039AC7C50227E8997FFCE4231EE1D2581F8
+:10E6C000E6756E8FA0BDBBC8DFB1E8B1032216ECC2
+:10E6D000F75F37571CBC1AE6B330E80C60FCE41354
+:10E6E0009BDBE89EFEA217CD149F30BC7316978368
+:10E6F0002DFC7D45FD7DA38B5AAC86F7A696B09880
+:10E70000F71761BC45C73E3AC6E89EB1F1BBFE6E45
+:10E71000C01AFC90204E2DFEDD8175597DBC3B500A
+:10E7200098D84F13FFEEC0CE88487A6339C6B1D26D
+:10E730003E606B29EE7BAA8E09E437E8CD87CA9646
+:10E740003C734C5EF0133DAAC94981ED09F8E94FCD
+:10E750005E4E0FBBF0508DECFEFBD645B330AD6383
+:10E7600078DE547B9724E3B9766D3889EE97D4CA66
+:10E770006218E346BCC9A536F43F329728E33DB49E
+:10E78000A9A6C974EFC972B7348EDE696D5BD881F2
+:10E79000F7EA6A3D12433EF6BA781C01CB10E97DD8
+:10E7A0009A3AF975D76CDCC739F93DBD6C99851576
+:10E7B00001EDBA00C3F365D8AC5446C1F4F20A8146
+:10E7C00028BE77C52659E5EDFC9D99EB8B26901F59
+:10E7D00098FE0EB44E8DFE1AC709D8CA10FF53EE2C
+:10E7E00076933D18F69818C6011ECFCA21385A9262
+:10E7F0004BA36FE3FC663AC8B71B56C554C4C32B82
+:10E80000ADAB665C05DFCD6189E21D0ABEACBDF92A
+:10E810002A68DFDD6AA1FB163A9C943AC9F07E8330
+:10E82000EF3E63DE12F75E85C462CA21FFC72CED9E
+:10E830007C9295B3686C1CAF3BC00FDD6527BD5B58
+:10E84000D709FC49E71F5AFE4F5A7E87394478DFC3
+:10E85000F1B640FED583AD73B3495E3A966E73E070
+:10E86000BEF0283FC7EC4B3E3F9AA5E8EF7CD8B5F9
+:10E87000772AECE8F78AA7A7BA6AE6C738435BB8F5
+:10E880003D6914E2F7B0997E3FA05E938F9293CBDF
+:10E89000719D6EE2D3FA38FAAB37FB0B4250BFFEE4
+:10E8A0004B93B66F3C797D7432863D28B4AF3667A2
+:10E8B000313FB287D9DD9129C33C46BD68F1E3EF12
+:10E8C000334C7DB67010CAF9512FCF24F9867042AF
+:10E8D0007C4955163FDAC9D62AB75F1A87F59C449A
+:10E8E00097679D16B287A42A4788ECAFD6091E25E4
+:10E8F000765F512DFB2533FE6E8D8DD2557DC8FB85
+:10E900006C9758867E578B662FBBBC5C9EBABC0E3C
+:10E910007EBEA8AD739BA4CE407ADE0674837137A9
+:10E9200007EEE3F4BD3CC3467A73F92BC386F4E7E4
+:10E930001F7CBCDAE3CF03C06EBDAF82FCB625F707
+:10E94000BCD78874B73CD926231D9A52866F9C8CFD
+:10E9500074FFAA99EE79D6264F5066C7F4674A9994
+:10E96000E8417898443513E979F8965DD74B939050
+:10E970004ED44D789F7F8CF75FAE9740BEEC4856E3
+:10E9800033F1BC6C82F7619E4F533709507E997703
+:10E990000BCF7BD54C11F253BDAD3C9FAF6EC2FC8B
+:10E9A000F5DEED3C3F9AEBA31F789F24795E6BF672
+:10E9B00097A37FFA19987F613EBE93CAD3720D2E3A
+:10E9C0007AF973F8DD8CEFAAF234BEFC05ADDDBE3A
+:10E9D0003ECA7FA995EFEFA3FF97B476D13EDA1F29
+:10E9E000D4DAB5F7D1FE90D6EE701FE5AF6AE5AF89
+:10E9F000F5D1FFBF6BED3AFA68FFBAD6EE8D3EDA7D
+:10EA00001FD1DA1DEDA3FC2DADFC585CFFEF68F5BE
+:10EA10003BB5EFBEE486B7D05EF381BC427952903D
+:10EA2000DC40FEAEAD55C544FFB5E3B9FED7E9DD28
+:10EA3000A7DD0BE8F0F2B8D20E2FB76F966B745EBD
+:10EA4000724FDEFAC94887BFE3F714417F1CC57BCC
+:10EA5000B8EA3D22F9F796BFC2DF95597E8F44E7A9
+:10EA60001B3A3DEAEDF5F987B579D669E9422F7F82
+:10EA70002F2347F5F8A7C7E847B36CCCDB809F305E
+:10EA8000FEBFCECDF54CC13DA50D786E520B7A067A
+:10EA9000D757EFB444D1FF552F4B545EE72E0DE10D
+:10EAA00079BF2A4BA487EADDA9517CAFB9AEAED8B5
+:10EAB000F0DE679D2CD1FB31926B8A6DB613E5C6F3
+:10EAC0007419E5671D93534BE85C0DF669A84FAACE
+:10EAD0004A65943B392E772ACAE55BB3F9BADA93D3
+:10EAE000BBEC788F42BA5FA4B70286CB12F17B5E93
+:10EAF0009D1856601EEDF272F2BF6E6FD6CE1419DD
+:10EB00003F4FD4E5FC8E9F4D253D560B7A4C213D61
+:10EB1000C60615A5F7DCDF948E8DB2A0DE92334DCC
+:10EB2000CC0C72F9803795C6DDFE20D75BF9A0B713
+:10EB3000F09DB56DC58CBFF3E6B1915FB742629EA3
+:10EB4000C1317ECC035E6EC733D3743FEEB3F3F1B5
+:10EB50003DC418F80E0B19F556CE007A2BBB0AE40B
+:10EB6000654C7DAB4736E49FF26AEFADFA991FED35
+:10EB70009BA9CF6E267D7216F50943FDF2EF49A3DE
+:10EB800050BF801EB1B2DE725097C7BADDA2CBE98A
+:10EB90005A4D6FD4C6E98D81E5EEDF5F1941F42946
+:10EBA0001ADEA1E94BFE2EC73801A04B735020BDE1
+:10EBB000C2A420DDEF1F086E6673998CF6F840F052
+:10EBC00033A77DEA42396D0E4AFEF712DC931A082C
+:10EBD000BE7A3D8B6DE816D46B9F1E5B51807EAF75
+:10EBE00055E68E593B916E854174BF43D1FC0E5B57
+:10EBF000ABF7B113F9F8FB3D7FD95C87BF8FC50236
+:10EC000032F94B324A156C67877DFA60B2E3F87EC1
+:10EC100093C9C1D042B4E75FB428782E70F819EDDB
+:10EC2000FD06AF93E079E7EEBBA89D59A8F4F0F399
+:10EC30007E46F05E9D994A76B9B2C3A6D98D1FAFC4
+:10EC40000FE441BF62A780FAE7F7D95BD7DB501F1B
+:10EC500069FB0198D9F770FF13095BB4FA78D19D6D
+:10EC6000B1DDF8E334DCFF1C903CB176A8E97B53BE
+:10EC7000B2F03C541E25417FEEAD96F5662F968B83
+:10EC80007AFB005E1E42F1A5E725C0C3D3ED5AB959
+:10EC9000EA5E3F05E6B3DBA28F0F06F5441C4FD4B6
+:10ECA000E829793DF6BFAB546F7F7A3DFE3E17CC25
+:10ECB000E75A13ECC1727D9EF5CE8C9EF97AB37D36
+:10ECC000EB6BA0BFD34A670A6EE396B4BE978E7A09
+:10ECD0007B7539BF3F8C0C80FE11FD1EF105BCED2C
+:10ECE000B9414557ECDF0EFD674A21142D33751EDF
+:10ECF0007200DC96ECABB499457CBFAB4CC5F7BB5E
+:10ED0000F4764BF6CC223B67D9FE224A13B43B8CF7
+:10ED1000F767FE817636CBD718EF74F4F5A53B156F
+:10ED2000BC3753D9E034517DC6FD5F89D7A7B73FC3
+:10ED3000BDF3F51FE0786794CEF46BA0F6EA28C027
+:10ED400025413BBDBE7EBFBAD81328F2C1F74F3173
+:10ED5000600CE59654E9C7FA115B88EEB1D9CDA1F4
+:10ED600032D42700FA30C629E869B12F8F9FA3C497
+:10ED70007D8FE7AF888D0D9E8EF2F22E89CEDD233A
+:10ED800036D53106F2CDB04FA98129AD2C3A3216D5
+:10ED9000E3059AF73A49AED7DED5EE2944BEF25BD9
+:10EDA00018DABDCD977664E03BF875775BCA1F43F0
+:10EDB000FA8D2EF7DC1E638779B3791CB7D7152A35
+:10EDC000477EB4033FA23E6E34076DF86E8A9A21E7
+:10EDD000525CB51DCA5FA372AF56EE9F7615EDCBA0
+:10EDE0004419E7559F37675A29EA354F2AFF1DC254
+:10EDF000FC29E5F3A03C2C5B6424AF45D9153723EF
+:10EE00009C9E96FC95C87F4F3B9D32C66381AC2487
+:10EE10007D20E5BB293ECBAADD77F216713D7F410F
+:10EE2000FFF9B81EABF3F138FCE6E48E1B4AA05D97
+:10EE3000D2BDA2AC42FF8D773F5486F1895BEE3E96
+:10EE4000F2078C6F6D4A97E89D815D35D100D6EB56
+:10EE50001658471BFE2E52D58C0EDC8FAE658A826B
+:10EE6000F6FA2E614608F573779AC4DAA07E529EB0
+:10EE7000315ED559688C97CA5A6CCC376607EFF665
+:10EE8000513C5071098E9326280A3E1D5CDCC12836
+:10EE90003E3F3D2F4FC6B8EE94E2B838D8C9C67E83
+:10EEA00052A718CBDDD3E3E2B66E32967B6E31E625
+:10EEB00033E718F3EFEBF4E8E1E70FFAEF3D6CB955
+:10EEC000FB71867ABAF18B4114CF8A7044BB3D69DD
+:10EED000B8E4C77311AFA56326C6C1B19149642FC9
+:10EEE0001DF4253105F2D6A58CE4A935357200F75D
+:10EEF000AB56512E534943450EBCEDC6DFEB32D124
+:10EF0000B96C3CFCBC5EEE1F7456F2DF858B485139
+:10EF1000B223ECF70C926BFCB8758CF3C32E8EC940
+:10EF2000F378EF2D3EED1CC5A3C7A9115E6165887E
+:10EF3000B7498C7E3FD27BF77B6A14E6B156C9ABEA
+:10EF4000443B63B5D849E3A815CE20EEBBD330CE01
+:10EF5000DB84F1DE2AA5F1F8D8A9D197C2E68410A6
+:10EF60008F9E5922C58FD41F4AAAC3C3977AEDBD7D
+:10EF7000063D8E4DA7CBBD3E6E7FEE6E17C500FAE7
+:10EF8000C16FC96B437CEBF996A0BB95E2FA8B2A63
+:10EF90003B912ED975DC0E053D40F7B2F538313D79
+:10EFA000AEB0339BD3F707D9A2210E9CE28862E270
+:10EFB000C0E9E8CE8447172119CF7BBC456532CA2A
+:10EFC000999FEBF72F18EF179F2FA47383E962E047
+:10EFD00022CD9F8E76DD606DBCC16E2940EFBBC334
+:10EFE0009C44A8FF20E3F507E7ED5981F7AE7623AF
+:10EFF000E120FFDCCEE11C4FB719EDA1B2D1082F03
+:10F0000001F461566F3A167C2D741E587F2F4BB554
+:10F0100016F5A6EBF1266EFF742F5028CE72203A1B
+:10F020003FE173713F76DA2619EDDBCCBC076BE864
+:10F030001ECCBD4C467D97D9DE7103FABDE2F921A5
+:10F04000EC4819CBE3E4BE991FDE64E2FCC18648BC
+:10F0500084B7F8F8D2F878526FB64B3B87023D90F0
+:10F060008CF701E42B304EB0FB1E46EF0494BED863
+:10F070007CF3BF417F9FE55B6494D7D96F049F7099
+:10F08000C0BC3EFB45301BE5F456A9D3EE8AF17BAC
+:10F090004A22BF7FD64B5E6BF4A1A0DEF0FCE3A951
+:10F0A00017E91B882B92973E4A467FD5B675BFB7A6
+:10F0B000A5FD1FDA2DAA3984768BAF5DCF67901D31
+:10F0C00096FD06CF8FDD9AB15E95106E8BC95F7489
+:10F0D000D03B97FC45D25BDC5F34DA1408639EFDBD
+:10F0E000C54E71773BF6DE321FE3D5EAD3AFA1DF21
+:10F0F0003D1993CDF79D85D93A7F1BD72F590241F2
+:10F10000E49BF8EFC3B3F5F3C4B20F6701FE463FCB
+:10F110006AA1B8BB02B1A22107F9A1D144F8AC3071
+:10F12000294BD7C4ECD3EAD34B2667A7D1BE8005C1
+:10F1300061C3A09C17581098CDE73E5E82F49A0DEB
+:10F140006C86F2255BE506647655120BC6D0A97273
+:10F150005EA2FAF5E981C9D99ADCC3731FB3C6D29E
+:10F160004FA796B159A897E11BEA5DF3CE247EDE46
+:10F17000E336DE8F349978BCC8D5DABACD78AE33B1
+:10F1800016DF7B13A3D631BDEB5FAFC149B239A304
+:10F19000A641E8277BED28DDBB8C3B07C6FD2DC5CE
+:10F1A000E52C66E40745B850FE4E99BFDB5DC5E32C
+:10F1B000016AEF63029E05D46AF754D45BF9EF0E3F
+:10F1C000B34040C1F755688BA9E0FFA2C4BF1E1B26
+:10F1D0004BC5FA19AC83E218593B5378BC84F1DC77
+:10F1E000696B1FEF40E97E00A9CA44FB94512FDBF5
+:10F1F000F9EF4355317A279CDE6CC2FDEF7D2C2C54
+:10F20000093D7EB80EAF42EDF4F3D85D5FBE43BF5B
+:10F21000C75C20B6055F23BB21596E43FD9864E4AB
+:10F2200043FDFEDAFD1A1FE2EF490763CE8F7CEA49
+:10F23000718AB7CF66DD35B8CFCAAE4A35E0F982FC
+:10F240005FF6FC50161C17DB6F98F3759E44EF7445
+:10F2500029E77D54BEB55A19A0FFDC3EFACF207ACB
+:10F26000EABBFF2C2ADF16FDD4753D80626BF77B6D
+:10F27000AE32A5C76E8D87B3EF3EA3FCFECEBEF8BF
+:10F2800078720E17BB39E0BE01E066BF5FF4B7329B
+:10F29000FCDD1B63BD6939E75CFCBC5CAF1F75DF3F
+:10F2A00088F561DFDBAAE0EFE818EB9795BCEFE2A9
+:10F2B000E7EE7A7D3EBFCBCF1BEBC5E3277EBE30AA
+:10F2C000AFB4EFC7CCEB0A9BD5505E3EABD7BCD2F8
+:10F2D0007E1833AFAB3CC6FAC19AC4F3BAB6C0DAF3
+:10F2E000EFBCF47ADF9BF8F5EAC5AFE3C669D63E1A
+:10F2F000E0CEEBFFB0FCEBF5FBA3F9FDD7BBAD2AED
+:10F300007E1C95E409C8CD0E944F154C5985EF84A9
+:10F31000336752C2B8E0C91A7F9C423F059E930EE4
+:10F320000DBC89F2F1A497C7FD1E7E666108CF610E
+:10F3300096EFB52878DEE1D5FCD620781621FFEED1
+:10F34000B6C92E8C07147D8A763FAA2307E3F97687
+:10F35000EF387233C93D66B46760BF5682FA1A440B
+:10F3600018DDCB780DDBA5C5C65104C8FEAB17FD73
+:10F370007FA47DD50FF8BE4A8FDF8FB5B3D8841E2A
+:10F380003B4B8FDFDEA08D733E9BFB03C1CE570549
+:10F39000B2F3258A6FFEB9AD6303DE3FFAB9DBED48
+:10F3A000C2FDCC416DDEBADDA8DF6B18322BAFC8D1
+:10F3B00094005E17F44852CF7D098CA374E5E5D123
+:10F3C000BB1868E78D2DC47E395CFF07CA89A75634
+:10F3D00000800000000000001F8B080000000000FB
+:10F3E000000BDD7D0B7C14D5B9F8999DD957B2BBC4
+:10F3F000990D4B1E3CC26EDE8100130831A095258D
+:10F40000448C96D20D3E0ADAE292F094BC00ADF143
+:10F41000CAAD13121110356A44A0800B8A62AF681E
+:10F42000E8450D08DE1035B5B7D886B6B6D67AF9F8
+:10F43000AFC0452A086B1FEAFD17CBFFFBBE339315
+:10F44000EC4E7655AAB7F7FEFEF187B367CECC79BE
+:10F450007CE77B7FDF3973AF893156CA989A2F8555
+:10F460007609F05B666C4D19636EF8C9B2197B447E
+:10F47000EE734B50FF88479255A8EFC9F232368998
+:10F48000B1BDAF994C7E0F638F7D3777A7E81B28FE
+:10F490006F0A7A766079A489053B1DD888BC8CC137
+:10F4A000FDBD36D9BDBE048A529FAFDA09E5DDBF86
+:10F4B000B949703196398A517BB5CDD3D989898CB8
+:10F4C000BD6889BC7A11C7B35108ED82765EEA281F
+:10F4D0009921C1FB0B4F336687476BEFBCEE9193CD
+:10F4E00043189B7C529E86F76BB7BA1511EE37F422
+:10F4F00035CDC07E581353F214C6D2C569A213DAB3
+:10F5000049BFEFA8D20A437EB4C7DB158672648771
+:10F51000A0ECF462FDF292E5C5F0BCC3EF75C07CCF
+:10F52000E7E350E9BE7B8619DFBBCEA2B4413B675F
+:10F53000CD6C4E273C7711FFA60E5CE77FD75BCEE4
+:10F5400060FCF33BEF9C4FFDCA00B24C28DB641A11
+:10F5500087CD2BA7B640393D89D9EC13182B5B2DED
+:10F56000F7DE85FD2F75CA3B01C6AE72B9F7873845
+:10F57000AFA62C5954B0F310C1416F7FA13F606119
+:10F58000D0EF98DD16688CD1DF45F837B633B63C3E
+:10F59000BE2BB65CD21D5B9EF8466CF97998231B96
+:10F5A000CAD814DBF06D2701DE3D87AC0CC7BBEC7D
+:10F5B0004C52C80AF03E60660CE7AFEEB1123E4C0A
+:10F5C0005FE6F0237E9CF920698715CA87DF49A290
+:10F5D000E76FFD173B7FDED4F91C96D5E792193E05
+:10F5E000BF6C4867592A8CFBE5CFC45B02C57C5AC7
+:10F5F000666CFFB9A21DEBB17E6267990CF75F1CC8
+:10F60000CD581FD64BA17138CF17FF2652BB91673B
+:10F61000ACA19DD0EE99FD4F3F87F03AF3CCF0546A
+:10F6200001C67CB969E7C4F558DFE2F4EE84FB5308
+:10F63000CE3C9B138C5A9765BBAD31F35CE61568E5
+:10F640009ECD927FF513B83E47CC844F2B17866A28
+:10F65000BBE1FD954296A2623B16C0D3622C2BE91A
+:10F660006EC0D7292E8EB72BED508EB3EEFAB5664D
+:10F6700093C8821307CAC7D73D4DE3293CFD36E145
+:10F68000F501B36A4A4238AE13945D30FE0376D773
+:10F69000389682D7AC10E2CD3F794D343E98D70FE3
+:10F6A0001B102FDE14959D2C717F8519BFDF5A39F1
+:10F6B000F173EAA15FDF38C6CEFF21E9163F8CA3C4
+:10F6C0006053ECBA178562CBAB113E806F352CEAE4
+:10F6D000BE0FC793BD2683E884D1780A4FBF7B93C2
+:10F6E0000FC63BCCCA9A102EC67EEFC379403B3F73
+:10F6F000FA11B45348CD881745DE9E370DD641A385
+:10F70000AB97054E47F077DB70A0B76502E72FFA9D
+:10F71000FD658671E8ED976A70F2589407C3B4FEF0
+:10F720005619D7FF83BBAB1E39691E3C9E5377FB2E
+:10F73000FD9551F7176D5ADE9B09EFD5ED1D3A4146
+:10F740008C826FDD33AFA6DD0CF7CFEE96146481AB
+:10F7500075739F7A600A3EF78CD889E3C57A3FCCEF
+:10F76000F76CE7EB2E7C6ED156F704D13BF0FEE24E
+:10F770004D57F92B0B07E079A974FA5239E773CB8F
+:10F780003ACD211BD245E75B3386239E6E12943C13
+:10F79000E8A74C0A8A4877CE52BF599DCCD8D40BE3
+:10F7A000FFD63B0CEA1B0F4D2A5B0FF5EB4D81EBAF
+:10F7B000BE8574B75D5476C16B2FFC7A455A306AAA
+:10F7C0007D7A34FC5F7F631DB5A3026EE40153EFC5
+:10F7D00029AC998EE529C54CB0023F769D66FE9016
+:10F7E00003FB636F9B52193B7DF09E719289F8D1A8
+:10F7F000CD482767984B41BA3BE06CFA15F5B7C77F
+:10F800004CFD4DED4E1190FF1E785250D63384477B
+:10F810002CFD9D3EBDDA358DD3F52D01920326E6F4
+:10F8200081F6963C3196F8807EDFB87E4B43063AEF
+:10F8300036E0C5096D5E889AD1F8657C6EC84CD5F6
+:10F8400082F458D70CF2228A6EEA4EB65B98637047
+:10F850003F8CF5E32F43FC05BC645E9AAF9DF80630
+:10F86000FC0936C0DB0FF0570E2F33E8FF5681A698
+:10F87000C6968DEECC473E274872455BE6007F6515
+:10F88000E521E2F367E1E77A05F942E731A47794ED
+:10F89000A5BB50BEC8DDE7B660BD3ACA8FFC68188C
+:10F8A00022295CD9F3C9C47FCF7AC34FD1FBCF8E55
+:10F8B0005554B87D1EE9C541EFB952A3F8534BE743
+:10F8C000ABAE3094CFEC1D5221BA106F7FE6C279F7
+:10F8D0007ED039A4C2E24ACC378C7C134646F07DF8
+:10F8E0000F7F02DE25F9FC661FC2BB0D842ECAB352
+:10F8F000214D254D71D64D7FCF63692AF122FFF846
+:10F900009E43413E9E6AAB7D1CE535FEF9E1FE1F3C
+:10F91000DF18B213D7FF614DAECE17783F7A3B4365
+:10F920007D9C9FBC71383F250CFDFC917953505E46
+:10F93000ECC90964F8E07E46459F5F0478645CCBBF
+:10F94000945678F584A87C5F86F558C0405EE2B591
+:10F95000346841BEC2DA86D278195366203C17CF8C
+:10F9600004F897F032CAB7A5018BB21EE470ADC49B
+:10F97000E15DBB5B08B5C258166C8885C7A20EEB6B
+:10F98000005EE0FFB646D5433F4BA5D01A945B23FB
+:10F9900040F318520EF8F064ECF3CB58378DABEE11
+:10F9A000D98BD67870FE8B06E73D39FE09383F616A
+:10F9B000B68DC6B3728F40F2D563E9247D22B21CA6
+:10F9C000F8318C97FD9AAFC34D9ABED478E77CFF8F
+:10F9D00002B89E6FAEF52F802A2235E4231D2984BC
+:10F9E0003FCB2A3B7B89AF30F9C73767607BCC2F91
+:10F9F0006379A393EB7BECC95791AFFC85C99D88D4
+:10FA000087539608F4FE945F8B3B01C3D94DFDEB01
+:10FA1000172038D679998C707CC71CA079AB4B998C
+:10FA2000BC0BF84A9D2DA0EB5FF2D5309F45AC8909
+:10FA3000E65DEDCBA6792E61ED54AE67610B1371D7
+:10FA40007DCB52105FFFC4145A5FD093983D753040
+:10FA50005E21FCFD51705BB235B6CC9E8C2A6723CB
+:10FA60009CA11C05FF867D17ADFE38707FB45F1E1C
+:10FA7000858AAAC746E3710BE1DF316D5D1EBD616A
+:10FA80005126F2910751211EA635508EFC177E4D4E
+:10FA9000A172B70DDA4F9AD85FA6FAB2D5BCDCB026
+:10FAA000E3C5C0A62B00DCE660A60C8B532B067AC0
+:10FAB0004D00D739B9C1154857B5267F9644FCC4C7
+:10FAC0009F1F8071B066BEBE8F4D682A6A8AA37F71
+:10FAD000E8E3DF2874769B908FECE7FA85B3346215
+:10FAE0008EE6FF1B7C5CBEA7F48469FD232F080C07
+:10FAF000F5DECDC24399B88E9B33BD422BCCA974A1
+:10FB00005FCB34E237C08BF2605DEBF7BDD73B1CB7
+:10FB1000CAA5557DB84C30EFC0F2D7919E2725710C
+:10FB2000BD39B9698709DA4BBFA570422BE0E743BD
+:10FB30003E2FF59334B1FD30B61359EE9577423B25
+:10FB400019AB55DF8A62ECBFA985F0B79AD1FDA148
+:10FB5000DF59D582CFDD378CA58AF81C6B11F0B93F
+:10FB60003543055A8F35F3D99C1FC3556232E99D41
+:10FB700023E6C842CB642C374D23FCF2CAEE9F65C6
+:10FB80006299B5A5805EFDA88B919E39D424DE5282
+:10FB90000DD74727F072EA2AC1BF9388E121825727
+:10FBA000BA955509A9FC7EA89848D8BF97EA43346E
+:10FBB000FEF4E94D25388EF41C7EF55882A65CE8EB
+:10FBC000FFC851736835CCF388862FB7EDA8488FEE
+:10FBD000E6BB47CEDA2413E8754732747DB6DB8185
+:10FBE000FAEC6D25D3D39118B373AB52705D3D59C8
+:10FBF000B1F5E7CDFE9489483F474586EBF7678727
+:10FC00003F05F5CFCB2D7CFCC6753FACAD67E3A7B8
+:10FC1000020B45C9B3C6391F939DD0F8A91473FFD1
+:10FC2000ECDD368622AE5FEE2DE99981CFD5B3BEED
+:10FC3000358887F59DC92C1445179727C5EF57A719
+:10FC400087C64F45A6C6EDD7127BFFD3214C1D12A8
+:10FC5000EFB9B4D8FB308F9872D727FDF3C0FBAC57
+:10FC60003CEC0A809D3813E52894CF874CAA793C58
+:10FC7000AAF15CFE9D93C32ED4CF415E36E1BA9CBF
+:10FC8000F386491E9E67AC0AEB2F37996EA9C6F51D
+:10FC90009522AED9CE817EF47A7C3F7A1DCFCDB14C
+:10FCA000B06E5A9F088D03E1A71630B6E5E04716FF
+:10FCB0002FEA11070F13FC747C8986A31AC56FD233
+:10FCC0005AFBBA4D4057177C9FB51783C13AB447CA
+:10FCD000E70B17DBFD2024D244530C9F482EEDE7A1
+:10FCE0001BC4A61E35893A9F79A872444C999E1F61
+:10FCF000785FA8AE04BE525ACCDFB7649B8EAE4686
+:10FD000059C6DA697C308F2C845F7FD966283BA086
+:10FD10003C36AA2C1BEA3D86FA0C4379047FFEACE4
+:10FD2000B33B0BED5777B6A55A023A3D9BD93D4FF1
+:10FD300080F286565B752594EB4BB9BC6E3828284B
+:10FD4000246E34F835285CEF7428614B6D31C2A104
+:10FD5000AF17F94A5D97200B400F8ECEBDDD54C61C
+:10FD6000F7BC51EF750AF45E5DE77BF45EC2F60BFB
+:10FD70004D44E7EB0B8FF3E73ADF27BDE0DEB6E556
+:10FD800001646CBD662FF105B0E2FCC3E1C586AE2F
+:10FD90006A16740CF0D77399FE5789BF1E1264A4BB
+:10FDA000CF7E3CC5761D0374A13FFFFBB107DF4248
+:10FDB000B523F9B68F5A2478FE3FEADF9F847AE1B3
+:10FDC000EF3539B251081561BF5B58B008E5E0F76F
+:10FDD000EAF30E9BE0B963E6F036E4BDD5D959D518
+:10FDE00012F0B563CEF04801E4FC75D945BC3C3453
+:10FDF000BC0DE1F92FD9A309BEC74686479AA0FCDE
+:10FE00009D9D37F0725E781B96D59D7EFEFCD8F0E6
+:10FE10004811DECF51A755574279971C9FAEAFCE00
+:10FE2000E67AB43EBEDF4FF45764A39E57C7E5CFD2
+:10FE3000BC5BDF998BFC769E89C90CF8F4AEB327C6
+:10FE4000F6EC0278EC6A4E663B393A0624D087D34A
+:10FE500039EA839C6827BE1EF1019F27E7515F584E
+:10FE60008072F2249B77BD6F605DF4FED34737ED5F
+:10FE7000C5F6D3E715931C117DFE67B17FFDFA76B9
+:10FE8000115CE1F967B365CEBF45939F9EBFCB1967
+:10FE9000C2E71FB4F37901FDD03A3BB475F95E3681
+:10FEA000E793DFCBE67AA4E2BB8ADABB49D7C7D7B0
+:10FEB000760E1D0DE3EA105827DA35EF98996A2778
+:10FEC0003D2689F4A10E1C3BD63F941952A19F9B5D
+:10FED000051640FEA2F3930EB73F3335CAAEE928AC
+:10FEE00081B263C08EEDA8F6672679F09A66421D4E
+:10FEF0005FE74F1D3EFE9E2E9FD25B793FE90F16B6
+:10FF0000EDC4F9244B8CE4DDC239F93B5B483F98E2
+:10FF10004DF3677E7FA600ED9D5C9A6D4238EAEB5B
+:10FF20007561A2BF99E62572BB5C5F371DBECF66C7
+:10FF300073BBB95604FD02F04EC90D527BA06F8C05
+:10FF400023C1AEE91BCF22D246C19949E14978FFCE
+:10FF5000FF43786DC7FAAF0AAFFA66E023A62FC158
+:10FF60004734386E14BACDE99C8F90DD8CF7511E62
+:10FF7000DDE10BFE383B8A1EE6DD554F7AA63EAE2C
+:10FF8000E43B5EAAFA0E433AFC80E86EDE3F25931E
+:10FF90009D6BD40375FB4AD7571F4EE0AFECD6E6F6
+:10FFA000A7E87E596D1CC9C5E13DF703BC529953C2
+:10FFB000463E7ACC121EABC0FBC74CC1275EC27155
+:10FFC0000F1365E02183DA6BCE11A93DBB8E272C80
+:10FFD000E21AED19C093758027367CBFDA42F673BA
+:10FFE000873BB47911E2C90D2314D54B7298E859B7
+:10FFF0006D4EA6FACB4DC719FA9923936519F54CA6
+:020000023000CC
+:10000000C02BAAEF989B1F52B9BF40B593FF34296C
+:10001000B413F1AE040080EDCD1D4DF568AF939F94
+:1000200063AE8DF73718AFB85D5DC078BD4FC3DBE9
+:10003000A5D984B769AD8CFB2924FFB8EA287D6176
+:100040004C0EE723C9A5E1177E8BFAE706BB92C7E2
+:10005000B80988FE0FD69E4EED01BE7C48F8C73821
+:100060005E2E78C0B983F33DA50CE17CAFB39DDD76
+:1000700049FE2B338D7FABBD9BF47093CDEB463F98
+:10008000F13C916DCCC7F65ACD32E28911DE2939A7
+:100090009CAF0DF667866F8FF667CEB3AAD62CACF1
+:1000A000BFDB4E7681EED79C97C2E94AF76B227D83
+:1000B000C6930BBA5FF3160DAF06D5AFFFAFBC1AF0
+:1000C00068EFFF6878A6F47C9A37DFC1E78DFE9170
+:1000D0001AFC05FDD6ACB2BF877ED01AD5DC6D7593
+:1000E000211FB9CA1F8EB2D3D8263E8FE09BE610DF
+:1000F000C2A959621B9FC2F551F9FC572E0C2D8DD8
+:100100009ED7160B9F97FA4FCE98796D71B1255FE8
+:10011000CFBCFE3029765EA72769F362B634784FEC
+:100120009373B7343BDF13C6C115E70557B60AE62C
+:10013000553830AFABD1961B4AEBD9148F0EAF4E6A
+:10014000B88EFF4BE6DBFE983FDE7C8DF3DC93E35D
+:10015000AFCA994474D32D970EE0757033CCAB14AD
+:10016000D77568A885D695E327632E05F9D8CA8583
+:10017000302FBCB6A4933F6B9ED5DB857E5DF6C366
+:10018000146D9E8CF8C0CACD23892E016F39DD3ED7
+:10019000C6E3412BEDDCCFB072B9ACA832CEFFC7BD
+:1001A00064074780BF925ED21CCBD7BF180EF6AC57
+:1001B0009AE26838D8B2E617C75977D54AF89C68EA
+:1001C000DDFF8F18B95DC849EC6763AB62FD14E8C9
+:1001D0006FEC2F8B83CB46BF07637FB3C63EAF2642
+:1001E000886F84BF178D47C7CC1A1EDD6927F9A316
+:1001F000E3D131279FAF118F1868D148C7FABC8D62
+:10020000709C87708C1387007CCA43381ED3EC33F4
+:10021000C0A73C84A34E07B734737E6084DB338968
+:10022000F9DA579B87018FBFEA3CF4FA44F3D0F523
+:10023000DB4DC2F2CD889F9B3299DC4A7A70782CD4
+:10024000DA491E4BA808C7B5C502F40BEDD668FD08
+:10025000932703E6F7A723DC2F7A5CEBD738AEAE03
+:100260001CDD2F1AEB376B7445B6A31ED298C4E57C
+:10027000E1B9434EA21B961B9E87FAF7F9035686F7
+:10028000FCB54108E7E373E704FF7C7AAE25D98B20
+:100290007251F7379E7891FB1B5506F62FFAF982BB
+:1002A000DC5FDAA8FE6C0DAEC3C51CA909EDCFC694
+:1002B000AE58FF1ACCCF85F33D67627DF87C83187A
+:1002C0005A8A26EB460BD707369A5827AEDF805D51
+:1002D0007E3C9FEC844C99A13FA8C1F45EFE8A2825
+:1002E0003BBE41AB6FC8E2FE298C47939F1DBBF21A
+:1002F0000D864BC386339F613CAD619F915E62E981
+:10030000A96EA02C5C14B0BDA87ADF003D913D8E93
+:100310007858C9427902FAD57839B9AA2F8471ED93
+:1003200046CDEF3AB4273C03F505676927433EDA2B
+:10033000789ADB21530EEE7815FD6DEEAABE91A8DA
+:1003400092346AF107A3FD33F9E04322FA8774FB84
+:1003500025CA1F55343BC61FB99ADE43FF16F61750
+:10036000C65BE8D796B89EBB51D373411F26BEB972
+:10037000B0BD80F461D45751EFD0FD63A887A03E93
+:100380003A27B7C2920BF3FC6B6E85903B89F74717
+:10039000763F3A5D267F0EFFD2E0A33F877EB2CF45
+:1003A0008F03707D6A8AC1FFBFE2A74309CF0F2484
+:1003B000D05387E6F6FBFFD3D1FFBF42F0A6239EC2
+:1003C0009F1283E4E75FCC54F21F2F45BF3AF1C17F
+:1003D0006EF24BDFDAC494F514470FAEC172FD1212
+:1003E00026AF47BF746590EAD12FFDCDC93C4EE5DD
+:1003F0008DC25F8C034597D96E28C7F0E93EF27332
+:1004000037400B5B14F423C43EDFC842D325C48BB2
+:10041000AE8BD698763A389C6ED1F065B39DFBB71B
+:10042000A7ACDA21B2283F43CA04BFEF1EA4879FBE
+:100430009AC9BFFA9FDAFAEAF0D89353918CEB95F8
+:10044000847E1F7CEE1E2BC9D99326B604F1E541AC
+:1004500037BB6536FAB3EE66FE5C33E2859C15ED7C
+:10046000EFD2AFEB0FD897209E4DCBE576807E3F45
+:100470009263A632F9AB493F4DA6F83BB0A571880F
+:100480008765D9BA5ECCC6A19FFC3D8D3F35DCE8BF
+:1004900008627B6113E767B372B93F6156AE85D6D8
+:1004A0004F2FF7FB8B343C837EA8BDA4892C26FEFE
+:1004B0007743FFF30F697628A3F96E5C9AC4F5E8D9
+:1004C0007E7C37113F4B2E0E5882C44F2A889F45A1
+:1004D000FEE0F0225CAACED42DC579FC714E12C389
+:1004E0007C85055A7CA929D74DEDEAF1A438FAD7C5
+:1004F000CDDD9E0179A3E3A72E670E38F9BC2F3519
+:100500002FC078AD5A5F44FC5B1FC714835E92888E
+:100510002E9AB57533C6C500AEC9C8670F98B8DD49
+:100520007500108BFC569D5ADC12EC64940307F6A0
+:1005300015909E3D5FF3A7829C24FB2A02F282AFB6
+:100540007770F3427CAE338FE2B9EF9943CF3C85AD
+:10055000F2F610B723F4F53870607808E977CA9995
+:100560000B5908FF03A77F341CE3E407B4B8649D6C
+:10057000A53B9FEC7D0BD753EB5CDDF908BF9735AE
+:10058000BCA94B8232DC1F3934F830F21F3DAF007A
+:10059000DF73D37CBC2EF4379CD0ECC8E36057E209
+:1005A000B8805AFA305E0AEB9D89E5C8BA74AEEF9E
+:1005B000C1B8102F4E1C1A4BF3DB68E678ACEE176F
+:1005C000C83F71DC1C39D50CCF1FCF9CC85A64942E
+:1005D000779F3ED58BED6F179955C6BC8D4F3EEE7C
+:1005E00082E7CF839D8B7EB35A53604626F28B17EA
+:1005F000B9BD6E5C07947FD171BC732C92457EBDF2
+:1006000025D99D883FE70E16513E12F3C84C8572DE
+:10061000E37E6EDF18E3CB27CDB1F86F6C17E7856B
+:10062000FEB546FC8DF23DFAFD38ED7D51F99C3961
+:100630009C7F27C063AA37D8931B65A736BE924913
+:10064000FCF8C4FD9FD07AB2761E373D69F6CFC361
+:10065000F1B92BBB2D3551F8F83B8D3FD75AB9BCBA
+:1006600006FE6B89E6377A7D59058B1BDF7F5BA31E
+:1006700073671F977B83EB399EDFCE9E10915FFCE3
+:100680002ED74BED8DD2F2146E677F3A6C45FDA4E8
+:10069000B384F22046ADEA263E00E325FC3CB9399E
+:1006A00085F823DBC0F175D10FADC43F1681FCE0A6
+:1006B000F636CFCB621B78FEC5A97B7C84CF65ABB9
+:1006C000BBCB881EDC4C41BDE4A5B6F75411EAE76C
+:1006D000EF164A30EF6C7E9B8FEC945BF7F9687DE8
+:1006E000A7687CBDD6EAA73C33F6388FC32D78784F
+:1006F00029F5539FCCDC22E97F210BCAE525BB05F8
+:10070000867435A593F3FF3AA9FB30EA91C6BC097C
+:10071000168A8D2FA33C62517A26CA1F66B00B62DF
+:10072000D75DBD24F96B9437E6BCF8F217EC3D4B6E
+:100730001E5F572E27F60A9C6F68F2B71EE52FEA58
+:100740006A9ADCD3E5E6624D6E9E12B9DC5E647D8A
+:1007500088AEC3F37C34CE5B311E4CF1CF8805F5F7
+:10076000934478315C1B978E1723304966E8005E0E
+:10077000D49DEEEEB5929DA9BC8871EEBA55ACDB66
+:100780000976DA22A989E4C33099C9948F373D48A4
+:10079000E34A5F09FA39ACF3228CDD4EB874BD60D0
+:1007A000901E6090FFFAB8753C31EA7F535685443D
+:1007B0008A33E533BAAF5F65D65982E3ADB671FDD2
+:1007C000BBDAE6E816D1DEAC349F8DB637AA257FBA
+:1007D000791EC9CB11EE53638845306C57F1F9ABE4
+:1007E000464F1AD02B934B236BEE87F6CC6C9C09AB
+:1007F000F9A4DEBFE89BB6B818E37A521FD92B2CB8
+:1008000083C9BBA0BFEB8B395C93611D76005CCDC7
+:10081000924AF033DB64778B1BD7BF8FE23291A112
+:100820008CFC74FA7A6D733215F31CAF2FE6F47DED
+:100830007D31F727C3FB14FF3517C2FBD07EC501FE
+:100840003BD1E5C7FB9D2194CF207746B9A13EED72
+:10085000F760A740F9DC0127E929E73479E1D1FD08
+:10086000B56C0DB5779386372AAB188EF60813AEA4
+:100870001D0E6367BA9E5CEF4E14C7D4EA7D7D37C8
+:1008800072FCB592BEF0B13BFC7D2CC37828276783
+:10089000B686578DFBA697DC85FC3BE05038D483A9
+:1008A00025A8FF58C5DB6EB401B06788AB2277225C
+:1008B000DE8F74C85678A572D4BBBF990BE53FECA8
+:1008C00033332BE2CFAEEB52BAF135C99F11183B4F
+:1008D000783C4B43E6E3E1283A5EB63BB65CDF1971
+:1008E0005B6E64D2F17014FF6F7E77E92F5E8BC26E
+:1008F000B7BBF29C9E53C90C7D6FCA45A0A79377E6
+:1009000077B113280BC5EFA6207F5C00E41F4FAF23
+:10091000F8E4EE25BF780D9E932C15AD1C9FBC16F8
+:10092000A4AF1AD01BE2D9A125797C7DADD6A6D380
+:100930003B003ED697AD4A0BBC352B2FB801DF6F7D
+:1009400030457A715DADA3CE8E437F76C5A80B94FA
+:100950004FF0F13F3305E1F4B17D1AE1D3C79BEDD0
+:100960005EB4533BB21CDC0FFB8A1012B8DD326B55
+:10097000521AE68BD05C808F45D66C463E3DD92A14
+:10098000AF9669BA3613AD37586F70EDB0A86BD01B
+:10099000AFDA0106648B82765E9F0B89E197B88E91
+:1009A00088DFE2B3161BFCF4B5F98B5AE0B9658118
+:1009B0002486797CD2675200F1EC5E6C2ACAEED9AB
+:1009C0009DC7E54FBD2D6C9906CF355EB8AD6AA8C1
+:1009D00069C0CF6F3507FDC361DCE6AE92EEE17012
+:1009E0006B71F374B2EF80DF72BE7888F3C5C577A0
+:1009F0004EA3FBC2EC2A9AEF29982FC2E5D5CD561B
+:100A00009AEFA9910EB2B74F6D13A8BC58B6501EFD
+:100A100020E82743A679F0BE59B6B2C1F068DC746D
+:100A2000EF9ACD50FFF34C910980FFEF6FFD09C5A0
+:100A300023DE67BC7F759F487ACFFB72A4AC1BE1B5
+:100A4000E96D7245DB938BB78901E4978BB7DDFEC7
+:100A5000F3C908B7D93795223CA6BA6F4BF33A06CB
+:100A6000EA757D4F4A2D7F0AE972EA67D3FBA6A299
+:100A7000DEB50DE806C62D995810ED8FD7B65D4D41
+:100A8000FAF6E2EA2437CECFBB75D70C946FEF5756
+:100A90000F33D1BCF6084C4678B89BD3F0FE6241C8
+:100AA0000AC4C3AB45793C9E306D9443417FC3E299
+:100AB000B744C217A0B31B318E50BFCD4CFAFC6BAC
+:100AC000B3DFF9CD5CCF009D09B337CD9A82CF3F1C
+:100AD0006DA6E7FBF5A9AD1FBE8B7E01FC03C98E99
+:100AE0007288E067A43BEBA855F9382E23FD2D5EF4
+:100AF000DD94CFE3FB9746876C2BD021F0E3B34026
+:100B000027174D7F171DFEF952E8908D488D91DF14
+:100B100083F99E4ACFE9F1519BC2FCBB1C940FE3C1
+:100B200017805F8FCC97884E46E65BE839E9BF5661
+:100B3000EC7E13E0F4785ED0928F7A17F397A07C66
+:100B4000F646E40A74C53A34BD916DE5F9E1685F93
+:100B5000E0FA6F1CCA9E5A1FE59FC9CCD7ECC0BCF7
+:100B6000600AB673EE77177A71BD1AB2CE8E43BDA6
+:100B7000BAF1D33F535E85E320CFC7712811CA5322
+:100B8000327B02848F3ADF6F54B81C32CEAB2D9F7C
+:100B9000DBAD8D9E08B5B3BF80D3BB1E8FDCD29C6E
+:100BA0004471A12D9E909DFB5940DF83F667968A84
+:100BB000C4676CA5AD0CE5182B17299E33F5C22F21
+:100BC00018C6BF7E7EC57405F54A47E9ABD2109CB6
+:100BD00067B959AB7F7E6D36D4FFE28AABC83E5A07
+:100BE00091217A51AF9A599AA392FCF4F3BCDDA9F2
+:100BF0001752880E672D9D457AA53EDE00B3791DFC
+:100C00008027B38158A3F39B675D61F73AA2F0EBAD
+:100C10008FED4215D7ABBD29D78FE57EA1CE622ED1
+:100C2000CFA3E1B022C342FDFF3577DA6484EFD46D
+:100C30002BF93A7CB0C71A5A0DFD7E608F6F47566C
+:100C4000E5737F6BB6740DF1A5DBF658293E7F4640
+:100C500088FFFCAD6B45CA2B5ABA566021E8EF837A
+:100C6000675ECA42BEFE875D2F65D5448D27D1FBE6
+:100C70000BF313F977BB1744DBDB332D3C2EC02677
+:100C80005863FCBB335D5A7EFE978C777C2BA19F0B
+:100C9000FFA72370BC6FF6FBF9DF18111DEFE88F7B
+:100CA0005B29DCCF6F8C57E596FFBB365E9E0FDD70
+:100CB0002C69E355AC3C6EB190C7C5571E1A4278FB
+:100CC00037D3127980E259AF88B216D7F0DBE8FD4E
+:100CD0000C5E9F605ECCEFCFF59491BF89C6237404
+:100CE00009DD4ED757981FE3710CE3FC6A0E8A7139
+:100CF000E3727F2D9079BCB3384276D5F1379EC030
+:100D0000C87B3FBEDB0FFA4CD179F4FDFAAC86DF2D
+:100D1000D7217EC3FCEC6B7939115E27E25719F9B4
+:100D20009C8E75FC3EBE362705F1ED1E5B43B81761
+:100D3000E0E71753987D1894B5F8BFFA2ECF6315E6
+:100D4000A3EC1CA4836DEF3AC9CE6935373D8EFB09
+:100D50007ED41689ED82FB9EA486500B94BD662737
+:100D6000E54DDD91346B07DA7561507005287F928F
+:100D7000746C07EA09CC96C2CCD08F5AA1BD6FB172
+:100D8000C9ADA05F3C96EC22FED2BC8091FC4E67C0
+:100D9000DD82000039989FCDFDB4CB5E1428FF188A
+:100DA000281EF53E2527BE3EBA57A38B5F61020D74
+:100DB000C6E5A7C77FEE60BEEE179382E1283BEF42
+:100DC0005E41F112DF813FCC8F34B3BEB9C497418D
+:100DD0008FFF05C883E1E28FC93F7BE2EEE0E3F1DC
+:100DE000F649E8D705D3E3DBE9AF6BE32B6C174299
+:100DF0006617D1AF69470CFD6A713C679A0212060B
+:100E0000E3B73C4E97CBF47CF94DE8B71F56CEC7FD
+:100E1000E8F28719EA1719EDD7B0E010A4A729E97D
+:100E200028DF562E8CF5A765D4ACCD24BF5ECDF758
+:100E300067A1FCDE6476AC1552F01AEB8FDB64F030
+:100E4000C77D115FC84848379333D0BFB16920FED2
+:100E500047F8D33A5F0E8902CD8245C7B5D35ABD54
+:100E6000BD41D483A6D9949DCA60FA61E54A06CEF5
+:100E7000ABBC80C34FA7E7460D35858302D9A58358
+:100E8000F9A106CFFA11044F7BFB1D64372597703B
+:100E90003F76F2D29A20F29F64E03F68C7592C4D0A
+:100EA00002ADFF146EB7AD147879E5345956E17987
+:100EB0008B4BCB97BD96E767AFB40783D1F1B4CB2B
+:100EC0004D2BA645E7E5CA0CDE473E3C87F737D3F6
+:100ED000B68AE705074147CA1C80638506C7DCF26E
+:100EE000249EA77EBB8DFC5B5BEDED345E9397DBB0
+:100EF000D935EBEDC4EF868B851437E93173FC509F
+:100F00009D36A257A5E76DCA0F1B7E598657F4453B
+:100F1000E1CF6DBC5EC70B66C82BB058BCBDE8BF47
+:100F20008381289897B252F0F656D0BCE488AAE0A4
+:100F3000BC35BE3C2E89CB11303733385C795CCC64
+:100F4000B05E8037DCAF3ED6C1FD462CE825BDCB78
+:100F500030DFC178B3BF10F96D4F3FDE7415C6E3C3
+:100F6000B70FBABDBD3BA3F18579D7A05FF53E139E
+:100F70008BAC8F873F4AAC9D6FCC9333DAFB0DCDA2
+:100F8000D3039AFDA1DA683D2D647F34DC392DC08E
+:100F9000ED8FC216F43F35AE024905EF4C3F28D81D
+:100FA000B0BDC6392EB2BF1BBBF652FCBCA18A290C
+:100FB000388C1ACD3FACCFF3B899C7F14066756253
+:100FC000FCBEC31DDE8EFBF23A96EA793C3CAF458F
+:100FD000ED12B43C1E3DEF2B720CFD9F1D8297FC61
+:100FE000A0FDFBFB60FD79FECEA5E581398B033EBC
+:100FF000B4C42FCF7BE29749932E218F563DD381E6
+:1010000079B289F3685FBF01EB6DB8165A3DA20152
+:10101000E8CB7AD96FF762FECE40BD0476A7AD4B20
+:10102000E0EFABD7DE709544FB72B4F2A147D01F5E
+:10103000FEA09DC5F4173D3EC9D03E9A960EAFFE68
+:10104000FCB6D9D8DEA313B4B2FAB787FD30BE0719
+:10105000CDB1ED11CA68EF6341EFCF3BE6998E0D3C
+:101060002306F476D0E3EF2E9834A0BFDFFBCECC7E
+:10107000F6F1D057B2FC27DA07A5EBE18D1E9E579B
+:101080006BC4F3F51A1F037B7806AAD6F7CE591E58
+:10109000C076FBF3DE0ECEF7A31DACE7BD35AE0A7E
+:1010A000D07E28D0FB1F28C03CDADF9D3D7598A17B
+:1010B0009DF901F9031A3F95B8DF19EC0701F0C556
+:1010C00076F021C21FB6DB1C42D74E875B65888F46
+:1010D0001D878449885F8C3565DD00B03F55E0DFB2
+:1010E00088F33897203EFE7C01B7DB1B0B2B36E7DD
+:1010F00023AC9F1418EAE3EB0BFF487645C3FEAB25
+:101100002645EFDF5BDAF528DF07B6DB1C77DECF9D
+:1011100017883C8F78FF0B143FF9202410CD2D91B8
+:1011200042EBD0DE5CB2C48496152B0DCDA73C59A2
+:1011300036C7C270FC8F1670B834EEBE4EC5FD8443
+:101140008DF00F48806D092C227D7BCB1C9B03E327
+:10115000D88D8535CB89DFC9497E34E58CE3ECCF6A
+:101160007FBB3389F268D67799ABD04E2A03BAF8A1
+:101170005707F2D5A3BE1DC83F874C105B65CC3323
+:101180008CAF7FBF50C4F5873621A07EBB94E2228E
+:101190002C3A9F795417B7BF7A0B2C31FEC9DE0267
+:1011A00089DEBB42ED9B8EB8F68A144E467BB89121
+:1011B000F93F42BF170B38BC1417629DE40FF4DCF3
+:1011C000ED25BBC9E609DF371EEBAF90C86ED2FD37
+:1011D00008E7F6A7933E36A530F82BC48B3231FCD6
+:1011E000C8B7116EF7495A7C89F395ACEB1C13D044
+:1011F000BE327BB83E63077D06F7895CB9EEE4CF6B
+:10120000A6236FF504488F6020E470BFF9749BC07B
+:10121000E32B06BD99C94A25BE3F43F34BE7C16A9C
+:101220009DB2116AB65D1C82FE0C8F8AF07E032689
+:101230003004EAAF62FE365C97BF6A76E4460BD7AD
+:10124000D7379A6CA4AFEBFA70B2A78FECC4FA4E02
+:1012500081FAA92FFC31ED1758A6E5A5F7E7874BD2
+:1012600061CA973F5790ACE96F6DDC1FC5FAC81F84
+:10127000C69EE5EB009A27E5D1EB70D7F3CAF5F6E9
+:101280002C5ABCB45EF3E702C0A8FEBF0A74BD705E
+:10129000B5165FD5F3FE79BF4CF29645FB1D375668
+:1012A00033D647E3F2BA70BCF7A4054C85F0FE7163
+:1012B000C063C4B3E36B9343B8DF6BA3D0E7C7B895
+:1012C000875AC2E319467C4A2FE4FDA6F4446650CF
+:1012D000DED5FE04FB8ABA62F715017F58FE3AF4A8
+:1012E000535AFA8E82F8FDA05B7BFF1A46F9E4C6DA
+:1012F0007D45230ABDFF3BF71529827F275CC71672
+:10130000BAF9BE217D5F91C2D74BCFE330EE273AC9
+:1013100097D92DF1FCFFF0F65D242FAD6417BEFCCC
+:10132000616F1BFA99CF975814DC479176D31B6DE8
+:10133000944F23484D188F34EA034FF8A65F563870
+:1013400009F7A5BDA850BEB0411F48E407A05869E1
+:10135000949FE89AC2AFD70F606FFFC485F87646B6
+:10136000883C8079ACEA21316E1EEB92C244FE00CB
+:10137000FF9C68FDB44DCFF77227C5E43FB625C882
+:10138000F74AA4F74B09F3BCAE21FDADAD3FCFAB9F
+:101390004AD7DF62F358E5A4CFB597F5FEABC2BEDE
+:1013A00098B8FC3F6B74F2C5F3D4EC9804F34B642B
+:1013B000B75D6A9E81110E6D09E4E83D85F1F7DFA6
+:1013C0000258648CCBB7615C1EAE92C054F29FEDA4
+:1013D000EDCF33E8267FF10B05E4F7B226CC33E0FE
+:1013E000F967D2A1022F3E77AF39E0477B46DD6B2C
+:1013F000D6E440E819F49BB41DCA243F1B2B0C8F84
+:1014000043FE28B96764E0B9066D1A7ED67DF93CC3
+:1014100083C791CF19F30C7684263C90CDEDE7BEBF
+:1014200064D0CB76302EA7D483DCAF09E326BF5E31
+:10143000E4FE91A4AF0AB36D348F13AF58775A49C5
+:101440000F57286FA026439451BE7454979D42F9BC
+:1014500075021457A4E3DA5B5791FD9A687D6AD749
+:10146000C6C671F5FB5F769D5E29E4FACE71B4EFD6
+:1014700049D0AAE42F5EB256384CF9BA8638723792
+:10148000F2109213B179011FDBA7513CF6FB0F5705
+:10149000531C56DFB7ABEFD7655ABCC5BB562239D4
+:1014A000E1DD2D84BC3E4E2626B2ED65139D1F0264
+:1014B000E26D0B8A4415A8E632B82D9804D453BDCA
+:1014C0006D504E8779AD93D40C786EC7DBC9E47F3D
+:1014D000BDD7E3D5F65170FB4BDD2090FE07ED92B2
+:1014E000FDACB601DE403BE1421E17F8B490FBA70D
+:1014F000014542341EEDDAA6E551E8FDB53053371B
+:101500005E4D02BFDE2B4B55F1F43BBDBD367393F0
+:101510000DE32D9191268A677E6CF1CFA178606AE8
+:101520003E437BB1CDD9B4B68AD7130FFDD81E097F
+:1015300050FD37246E28306F2A8EF7371ADD18D702
+:1015400075617B6CD918EF379E4350CB8205993972
+:1015500083F7E5FF4693871FAFF769EBA250BCBC4A
+:10156000CDECFDA50FE5E33A89E470CB080E37D347
+:10157000487ECD7657CE2139EC06FD94C6CBC79F69
+:10158000FD0D8F80F4D7E6E6F8F555C73DE81C81E0
+:10159000A27C1A6F1B1A0DD05FDB3A21C4E1C5C7CC
+:1015A000FD65FDD559455FAF9C3A21284F75239EB7
+:1015B00039423F44BF5F6D8B55467E7646D0E87F0B
+:1015C0009D48FC6CCB92542A1F5F9B477EA07EBA3D
+:1015D0003DBD66399EAFF065F3B694228E173F3756
+:1015E000F8E16ACA85A3D88E11EE8850922E7FE06A
+:1015F000D5E9D715CF40FED86062DE74D407D61A7D
+:10160000F2430CF43CD51BBCB208ED0F4B5F2FE747
+:1016100053E17C89F46FBB82707BD47462EF4F100E
+:101620005FF6DA29DFB06155E429F457BABDC1ABE2
+:10163000F0BDB377BE3343F05273A4279D3F5440AF
+:10164000E775D4B419CE41D8109B97C2D6A6F2BC88
+:101650008F8ED8FBB85F3FE6BD41F92AED9ABE1DDB
+:101660002C42FB62EA953CCFEFC3A5268678F1A118
+:101670009DE38F7ABF5393334A7EB45E5BA3D93721
+:10168000FDF871BF9DF0A356DBE7645C8F7AC40F51
+:1016900058B73A0D3F3E7CE1B27CC48FB37B2FCB71
+:1016A00047FCD8686EF7237DCDC90D2E2A82719D27
+:1016B000BC2AD06BE27C29FF52F0F676E3B8FE41FB
+:1016C000FA55475122BDC3FBDDE8784B8F99FBC922
+:1016D000547BEC3EA19E4BF4AB26F68F15E5C6FA83
+:1016E000C70A73E3EA5736FBE7EA57973E0F46FB14
+:1016F000C4F4384C8F33F2C05351F05A69E7F928DB
+:101700002B8B64592DC1F9D5E4D0BEB3DFD9949D9C
+:10171000C2D73ACF183FE02B1772D6B4E338FCDCBF
+:101720006FF98AE4EDBD1CFA7D8571BFA571DEBF3E
+:101730002DE0F933BADDADDB81C6FE0F68EBFDB3FA
+:1017400022FF21B4ABA75EB8487E84D3782E0FF475
+:101750006B0BFD2BD973ECA020D3BE352F8F8336B6
+:10176000EC5FF804FA5D9786B4F8E53E81ECF5A5E8
+:101770004F7E44F5E7BA6AA9DE7150E8C63868E3DF
+:101780000813C96D3DFF41F7FF341E2C21BF8FEEBA
+:10179000FF8171EC473F4DB2276221BE85F625BC23
+:1017A000D720F1F86E8387292AB2DAAE58BF899E16
+:1017B0001FB52560217ADF725008A13D9E6609FAA7
+:1017C00046103C47C894DFA2F18DB78BFC17905FA1
+:1017D000E9F96B7B72FCEF14F1BCB72CCA93D7D636
+:1017E00023D81F17E2FB2CFEF26BBECF229C805F3A
+:1017F000FF67919E677B23E9CF7F618194F8F9E7CA
+:10180000219E7FDE9FEFC6F3CCEB6632B6DECDCBFA
+:1018100078CE4C3D9E33A370F9D96D909FD165CCA5
+:101820002FEB8EE29B75521FE5B1EBE7CA60BE5904
+:10183000F4F30DB84F2387E79DC5B4A3F1D37471BA
+:1018400005C57FE2C45DBF1B6D7F1CD1EDAC127D71
+:101850005F4DC482FE9D952D9E08C6118E38B5FD44
+:10186000BE5A3EED4A7BE404FA3F563E934EFB4798
+:10187000FAF5FB3D56CD7FCEF1BE8EFF648D4B8ECB
+:10188000939DDF88FBFA85017A9A99D02EFB692E09
+:10189000C6638EF4DB656FE4E2FE1B9DCFD6299C08
+:1018A0005FD475097C1F5667EC3E9CDCD15FAFBEF0
+:1018B000A03F97E8FD8AD189ECD92F8233E7B7475B
+:1018C00012ED5FD2F8A40E47233FBA54F8E9F5FDB4
+:1018D000F003BA267E6B809FD18FA6FBC3589B4C2A
+:1018E000FE32D0493A319F53F7877D5979F89DD11F
+:1018F000FF33F2F0FBA313C9C3AFB63E89E4C4A51E
+:10190000AECB207988EB332EB13CCC2DFF776DDC4C
+:10191000C63C046DDC863C8423E6C82C7E8E05C064
+:10192000C737380F2121FE7D411EC2DF314F431ED4
+:10193000C2E7CFD39887F0F8A1C75C18AAC3FD6AA5
+:10194000E877E8D965A6F8FB0CD1E1E7F96122CF89
+:1019500027657E3A8FB3D16627FF82317F0E38D557
+:101960009A26D42FCB41EFC7FD3CDB5A492ED767CF
+:101970008AE4ABC47C41D91B273F53AA4EE9F60E3B
+:10198000CE13C3FC773A17E012F3C4F68EEECFD72E
+:10199000F4FD9DF99AFB477F893C31258FF3A757CA
+:1019A0001D7F1A127D5E66453118EAC589F3F47F02
+:1019B000A2D14DB296DF6B935416ED8F4AF4DE2F11
+:1019C00046737BE7554BE4ED4ED4ABA0198C7B6698
+:1019D00058C09A2E1DD8EF7EAA207014F394411F90
+:1019E000A1F53DB7FFB7E4EF7F3C93C99837FFB847
+:1019F00059A575568732C26B3D9F41EFE72ECDFF4B
+:101A0000FD65F9CFFBFF60B9208DF9EF910B5F1BEE
+:101A1000DF1994F7C4E9F1EFE037447FFDFCC4CC53
+:101A2000E341FA79175F28E7BE6E3E63C8D74834B2
+:101A3000AFBF1630C29FC23181EC31E417F3939FE0
+:101A4000F152E55F7229E843088F7D562F929A4D37
+:101A50003BD7826DC8D4FDA2FC7CC1074792DEF95A
+:101A6000A19D8F573FAF439FCFE5630CF8F915ED6C
+:101A7000582537F08D3130BF93D3FCB4EFF75E2794
+:101A8000D7DB22CFF0BC77E3F9134037FC3C0EEDF7
+:101A9000DC5FE33EFA6F1BC7F70F92DF0DFFDBE958
+:101AA000E812E5F7A5CF23D69E3DE2E4798503F65B
+:101AB000EC7FDBBC2E495EEB79C665157D9ABF5F76
+:101AC00060E8EFD7FB69ECE3FB741ED2D653BFFF8F
+:101AD0005BCDBFF7D618FFC388AFA5A5DDDB71BF0F
+:101AE0004A0373318CBB3774DEB1FB4D0FDF7F4B84
+:101AF000E5421EAF640107EDCF7E3C2FB8750CC9DF
+:101B0000C1F01AA4CF511E56867183F585B359AD25
+:101B100083F21042583F6A5578FB9BA59487D58481
+:101B2000F4AAE721975DFCD39AAA521A2FF97F3DB8
+:101B3000D6D8733B0E8FE1F24CBFBE3246D0E2AE38
+:101B4000FE4C1CCFD9257C3F6AA3C72FA31F598FFA
+:101B50007B277BFB286FA0611F378ACAD056C4FA47
+:101B6000BB46107D35EC9B5682F150D6692FA1F310
+:101B70007E7FCFCFD93E7BE730F2374E290CBE8433
+:101B80007CC9591ABA06EDE851D00FC64DCFEEBD4B
+:101B9000A62418876FA68BA92AC695D345D6F9889F
+:101BA0003CC0B7C07E9E4BFEE23511F2633D3D86E0
+:101BB000DF6FF470B9DE78B09A2D740C941D9ED846
+:101BC000FD573F2BBAEA691CC7D363242D2F93E737
+:101BD00081FA400D43BFA1119F7C5A1E68B596E75C
+:101BE000CC54DB407E73F617E781EAE3D3CB7A1E51
+:101BF00068F2A7DC7ECF962D9437E25CCBF92A5BA6
+:101C0000C5286E7045A46F7A0AC029B7A3FB0A8461
+:101C1000530A829DCE7F0DDF371EEE7B864857A08C
+:101C20003F647BF3841ED47FA5757DDFC025F1B6AC
+:101C3000CB15E8627C3C2F7082E480D454887CA968
+:101C4000E22D33DFA7B42E99F4CA8EAC3ADAA7742A
+:101C5000EE1D6BDC7308F4ABCA566760DC217BEDCC
+:101C6000AF282FC0B94F88BB9FADB2D8A1ED635A42
+:101C70009D81710CE7DA3EB51CDACFBE5F609A1920
+:101C80009D2964A07F5832A17CADEDE2E7DBD5B69B
+:101C9000BB2B6C246FB8BF865DE1213922ADFBA65A
+:101CA00009F984D4025A2CCCF3F2621E9FCEEB9039
+:101CB0004D28A7FEED33316E1CC9563CB0DF05C17F
+:101CC000556F8DF466F806F27CF47D2EBABFA75FDF
+:101CD000FEEC9B4FFE9E4BCFEB8EDC4C79839FA599
+:101CE000517C65A68BDB232088B4F35D62DF1F7413
+:101CF000BE8BA6B7E876B1910E8C79D2B9E5C388D0
+:101D00002E808F766E9163F85EDC7CE96689EBDD70
+:101D1000300FCB4A1CC7B40C05FD735F363FDD683E
+:101D20004FF7EB399A5EA28FFBEFCDE7D6EBEB30A6
+:101D30008F3B8EFF43D76BDAF47DD09FF1F3B7462C
+:101D400069F6C4F1F57F1DC7CF39D4F346427495C7
+:101D5000CCC03F097FC257AA8807FBDCA686628AEF
+:101D60002F35503BEBF8F9FEA3D6E6AC2E2FC5ABD2
+:101D7000CC0480F7F103CB4651FC16E8222F0E5D10
+:101D8000BC3FC6CCDB5F974C782C3DC4280B52720D
+:101D9000A7111E4B8F727C7D6F0CC72F3D6F4D8F2F
+:101DA00003BE35263817F729F69FCBD19CC4CFE563
+:101DB000D0F2BF9DCDEFECC1F32EB66B71E09E5714
+:101DC000C6CCA6F8DC3A4940FBF063F7FC51E8BF0B
+:101DD0005BA0E1B953EA63B2239A5E7B68FF60F6C9
+:101DE00021BEEF49D2F254A5759E1D889FA22F48AF
+:101DF000FB24BFD1D62D521E947CF2912A2FDA1DDE
+:101E0000110BE6AD7DD0224556BB497F8AF193196F
+:101E1000FD5E4CEAA4BC9CE6E27FAC1DB2B138A1E9
+:101E2000FEF495F65FB02FF04F7D55BC4EE49FBA9F
+:101E3000F47918F75D70FB84BDC2F39BE2CC2BC62E
+:101E40007FF9B5CF4BF75B1AF3D506D131F77FE8B1
+:101E5000F6901E7F607E35269FBCC72C77A3DE835D
+:101E6000F9B92F28A8573F6D8FCE27FB370DEFFB11
+:101E7000CFFD63213BEED73FAFED376692B216E35D
+:101E8000A07788CE76B4EF5A31CF1FF54B84AF10D0
+:101E9000B5DFE15D27E53D344B7C3F0453F97E8A95
+:101EA000950B9B9EC6F757B6A4CB087FB5A2E979E0
+:101EB000DA2F61628156B87EA27DEF421F8F9EFFAE
+:101EC0009F487E0ECAFFFF82FD0B9909F62FFC8703
+:101ED00086F7850B18ED5F606BFD3B705C1D2D1266
+:101EE000C3786F6A152F8F926CF4FD153BE6510F86
+:101EF000A1FDA694EF1C017862DEB61DF3A887E071
+:101F0000FE127ECEA130BB8AF02F15E0837A41AB62
+:101F1000999F6BA8DEE0207C9A5EC5E397A9010B30
+:101F2000F19FF34CA1BC7B15CF3FF3209EAD26FC67
+:101F30008C38D328FE9A9ACBF5487BC062B2F92838
+:101F40004F9AF03522E879D29CEF75CCF752FE7AA1
+:101F5000FF39870B19ADCFBABC1999F8DD8161D76C
+:101F600059048CD7E872A642C38F8E1DDAFBF5FCAC
+:101F70007D3C0711C7C756F2F7FBCF41FC1EAF6F80
+:101F800096C2748E10E830DA397CBC7EE5DC34A26F
+:101F90001F51DBE7CA6ED2F2F4057EEED4CAB9C394
+:101FA00078BD8BF341766B9226CFB5F76F4F0D69F5
+:101FB000F1029E6FBFD4A49D1FD0CE62E2B91A9DDC
+:101FC000A57EC17E8D8707F2EE899E5BAF9129AF1A
+:101FD000503FC7B1C261E1FBB86CB174F542712AE0
+:101FE000C7FB72C586FDDEE2F3FBC6C6F50F87E6CA
+:101FF00047F395613A5FB9D562B0CBD2395C5D9158
+:10200000ED7CBF97F592ECB2C471C5673263E38A89
+:10201000BB33A3E38AFAFA562CB1105FE9707B5FF9
+:10202000C3FCA32D005A3C17CF38EF2DFDE75B878B
+:10203000ECA8971AEDC12309F28CE68FE5768F9212
+:10204000C00F317F6C22F992204E5B62FD6F8A37A0
+:1020500073FEDB93607F5F3FBC74BDC9668C7BA859
+:1020600097E4F7E9B1FD80F8A0BF5562F62BA16CAB
+:10207000D88F067C90F8A2BADA2AB77A908FFE80C1
+:10208000F8623358AED628BE08E6E865C88F7BEE06
+:102090002EA4EFD9BC76B742D7F376A1531C8FD7C5
+:1020A000C83CD498163F77F8463CEFF9BC3392858C
+:1020B000E743DFF3FC9BDFA1F2D0C8312CB73D270B
+:1020C000CDA1725E643B9E17BDE5B935BC1E696C3F
+:1020D00018633F187BD77754077D7F614D1FEAF760
+:1020E000A5863C7EC3F9B5B8DF14E793EEB050DCAB
+:1020F000375DDBE7CB2A35FF10667A21DD65965028
+:102100009E9E8379F7F561FD082E77A1BE05CF4726
+:102110006DCDF3F13834E37C808DD0F238585845DA
+:102120007F54ABCF4DEFF7EB77FBAC5A1E18EFFFA8
+:10213000E80BFC5C1F7DFF3263F248B41B1D5E168A
+:1021400053D6CF8366923C12CF6F6DD5F0402FBF30
+:10215000941E0C8D8DB22B8F5E754731CEF3C31755
+:10216000EFCA457DEA6AED3B5046BC6A1CCFF17B65
+:1021700075F2DFE6211F7F5B7429E43F480FFE08FC
+:10218000F9C6424FCB2437E04FA53C8DBE373345CF
+:102190009D2B205F715FCFC7E7AE0C080B8B07BE8E
+:1021A00043333428919F9E053B44D4B7879E0CC887
+:1021B000089F3A5B244B82767EE309BE80E3FC787D
+:1021C000FE7BDFA7BCBC61478FE1B99247CDEDD361
+:1021D0005D884F3EED1C6126D1BE9ADEE1A3766A92
+:1021E000DFD3E1FB6BF2042D0EDB5D8972E15AC691
+:1021F000F116CB58FF4DED9CB419323F777346A9C9
+:102200008FBE8F368B4524C487196F075C0CE9E3BA
+:10221000FA6069BC732BF42BCB307BA3E9E71A6F10
+:102220005419FE7DB330B6FC2D25B6FCEDF2CF0A75
+:10223000A2CBD592FF9708CF97052E7FD4C95CFE1D
+:10224000C8AC7335CAC71F35C91328AEEE11542C5C
+:102250008F796918E525B10C9ECF30DA951DE270B3
+:10226000C8D98AF38A809CDFE9C1EF2CF1F3AFD2A1
+:10227000DEB6ECC0F31598D7BB15E9F0457321E540
+:102280006DA6396AFEB585F41927CB233EE5DD4AF4
+:1022900078EDB479F1BB0F879D3C1FA1F52113C5E3
+:1022A0009B0497CDE487E7C49D1297FFCE25D3B159
+:1022B0005E2C83050159DDE3E6DF6D6A9DC4CCAB7E
+:1022C0004B70DD94B7492F72DA28DFBFD255F85D25
+:1022D000AC175D163A0FE2B0B32CA8F5C7B0FD27D6
+:1022E0009D4BE87DE4D16630C87BECDCBF2E827D5F
+:1022F000BC9AF74FDF67135730AD7F1BB360B986C9
+:1023000051FE7E8F5BE6E3BDDD44F110ACBF92C6AB
+:1023100067A37AFDFCC281FDB2D3243AC75D605A3F
+:102320007CAC85CA8F697CB0D52C1F463C55FFC05C
+:1023300018AE47A5EB53A203D1E452E8BC1D3FCB36
+:10234000F5A431EEB380E7C534B91BF3D9C5152E1A
+:10235000B29B51F3C1FAE1F893E85AF2B332CD35AA
+:1023600043FDF98F231E8F125800D723388EEFA319
+:102370007DC2747413E55738025605FAB1DCC4689F
+:102380007D95E4F8FB64C78FE3743A78FDCA323078
+:102390008F4370957BF1DAEA2CF7E2BE9F1EB7926D
+:1023A00011882AC7599710E2CDC0BAD8BA4DE37048
+:1023B0003D142FEA175FDC1ED43B703E1A7F1DA62A
+:1023C00078D10ECD75413BC0F79521F1E7111CC7BF
+:1023D000FD8B9DDAB97AC6FA99E34C5FF73C0DF8AC
+:1023E000F715E799163BCFAF719C61E16B18A79881
+:1023F00005E3730C8C0F7ED2395FD73A4C845FD7DC
+:10240000EAE72D15C6EEBB30EEB3606CD566E4335B
+:10241000576BF9A315C9FF4C7EFC6B40CF47B9D66B
+:102420009BFC835CCCDF9C91D2D2C689A3E9EC42B1
+:10243000E4C73681F8CE3759F71ABC7F7E5AF0715F
+:10244000770EF1FDDBC60DC5F3538305A950FED011
+:10245000DC9EBBDC477CF1F67193709C11A2BB6BD8
+:10246000F17B6C487733436D58863E9AE8DC2DA0AB
+:1024700043A45B9D0E078F1FE8129E1FDEE4A2FDA2
+:1024800050DB58376D68CB60ED02F7B73491DC62F2
+:10249000DE9103F304A29D616BA279FCA44525F9AA
+:1024A00070B5FB1109CB4F2AC1F538AE39E33FA215
+:1024B000F3F259C6FC02B43B61BCF7E13CFEA7C68F
+:1024C0003B789FFAE7EFA3F847D9A3CF6B74ADDB56
+:1024D000A39E24D027609C5EC1A530D01FFBED5386
+:1024E000B38DF21206F6F5466A69FFB09012407994
+:1024F000A6EFEB35F2DDA95772BEFBE17297B29AF7
+:10250000CE39DC4D7669E3F50E7DDF2FE95F8D4B2B
+:102510004CDABE5F81E44A03B3D1B943FDDFAB833C
+:102520003F216DE0BB1E0770FF6FE9E7EDFFF5D2BD
+:10253000FE6275158FD3F7DB77F532B75FF5EF43A2
+:10254000DC9EAD9FE3CFF594E5EC4BD9B771F60572
+:1025500093DEC8524C9AFDCAF5858EC95E59651442
+:102560005FE57AF85C0BD56F4C0AD1F7566AC576F1
+:102570004292E3E3DCBADFD34EDF65B228F9C82725
+:10258000F438EB9CDCE07F225E2F2CF66709309557
+:102590005A0B8F9F021D6CED83B7AA58D393F8BDD9
+:1025A000AE6B58D3AF4D3944076710DFE78CF9881D
+:1025B0007FC76B800ECE623B36C6FD01D76A71A223
+:1025C000973F7CAA0DD7FDBCC0F8FEAE42E3FEAE3D
+:1025D000C09FC7F17896F63D9E58BE13358E936620
+:1025E0003E0E8F28D2382EC41BC7203A6421EA1F22
+:1025F000D6B789F69F1BF0C8381EE1E01DB43F6EC8
+:10260000EBCD4C1627A31CEFB3233C472046E4E058
+:102610003C83C9E327913C0FE2B968BA5D3D68DCB1
+:10262000A283D6F5C6B9FD793AB332CB304EC4FB9E
+:102630007D2CB9E151F47B34DE6C26FE5E7D702C7E
+:10264000E969BDAA55C6244856C9F36B14F80FC7EB
+:102650003587F9AF72433BD7C9D574CEDAF5338DE0
+:102660007939EA3D4DF0FE0D5A9ECF8DD79B8F47AD
+:10267000EB9BE7CD1BCC0807B5D6D1244EC1F6A401
+:1026800081F77D83E132E89CA736CE9F18E839D8E0
+:102690007E6B7927F1A7447C6AFC787E2E14B455B2
+:1026A000F077E6FB5C36FE4BE4FB4CD0CE857ACD72
+:1026B0001CA1F33B5F1FBA78EB729867C10F8BE9DF
+:1026C000FBA557A52D7DF221283FBD6534955F4FB1
+:1026D000BBF9B6A358BF3D9FCA95A68FE6213D140E
+:1026E00096CDBD16BFFBFA9A9DB7939114ECA886C0
+:1026F000E732C6654FC003612A2D117AEE9BE3EBEA
+:1027000027A23FA63289978F94FC760295B3B5F243
+:1027100084974763F935E1A379F1F8E29842A1BBC8
+:1027200008E46D652A7F7EE6846786A11D5F59C136
+:10273000CB639469EB72B0DEF4C779F1F4A505E3DD
+:10274000F97CA75E38DF36C4836161FE3DD297FC19
+:10275000EFD1F73902206F71FF7EA09CC7E102FE26
+:102760001209BF0755E1E7E5E98E964CE483B38291
+:1027700096528CBBCA0E5F1B7E1F31A57CDA245C8F
+:10278000F7E9A06E639C13E86B09C27FCE651F65F5
+:10279000B9482FD5E94B3613BD273EA7B19EAF5B95
+:1027A0002C3D407B2B906EE65C1E2B3F07D1AB018E
+:1027B0000FAFB58DE0780772D15A3E985E8DFC9BC5
+:1027C000ADE914A2E9751BE2A54874BB1AC76531CF
+:1027D000F579F1FE2841192D7F0EFD9E37BFEBA341
+:1027E0003810DC102F8FC337E04FD2F57C3E0A59EA
+:1027F0004EA3FC659ED773F0B7F43E6E071133A964
+:10280000FF8771FE6C0D1FCF363CBF44447B2FF811
+:1028100004F289860CFE9D498CEB239D66E8FCAA98
+:102820002B76BEADE5CAAD6E71F0784D360EC7EBB6
+:10283000357DECADE6C0D01218EC8DACC98CF37DC3
+:102840002CD9A5623CB7B1869F43F92FE9C1271166
+:102850001EA2493D1486F242E6E7DFAF94FCBBC6F8
+:1028600047E95F0DDABA34D8DEA57C36FCC3F351F4
+:1028700006C1A3CBC84763E73FB02E7D9978CDC48E
+:10288000F35772709ECA5A31CE7C98D4B42EDA4F68
+:10289000FFD817FAE919F7B72856ED3C95C8BC6878
+:1028A0007F5CABB3E9F1683B19CC323A07E9484B9E
+:1028B0002E8B8777BA9E7444D0FC5AA0F7A23EF0C4
+:1028C00049D2DF483F018A0998B3D0AF358BF4185D
+:1028D000C16293317E9D519341F8BA09F412F4B369
+:1028E000AB159D39E42FDF2E323CB760000E30125D
+:1028F000DF007E7E383E9B7FF7AB1F1E2AF1518B97
+:102900004988AB5F7D38DEA49D9FCAF79736D8AC67
+:102910003CFF53FB9E859EC7D2602B5ED344F3B32E
+:1029200071FA31ACD3A0BC16639E9C2D9DF40B793B
+:102930000253501E0ECE8331DA092ACDE35BFDF13E
+:1029400005C6F59F3B9DA4FF7C4B8B2F08B33FA58D
+:10295000F54905FCB27A308EE015D05E492D3D2A4E
+:10296000B1B103DF9FC4EF36A13FAB2B3BF87FC76C
+:1029700047C5E3DF9CF434E5851C33F138A8113EEC
+:102980006685C7816416A67CD5068D5FFD3F379CA2
+:10299000204A0080000000001F8B0800000000009B
+:1029A000000BE57D09785445B67FDDBEBD25E924E1
+:1029B0009D104242583AAC4102762721806C4D80EE
+:1029C000880A4C585450841B886C59059D41C73166
+:1029D0001D02880ECE84272A4F511B0444079846B7
+:1029E000D9D4C8B48088CF2D6E336E8F495C5925F9
+:1029F000864171C637FECFEFD4BDA46F13067CCBE2
+:102A0000F79FF73DF8B438B7EADEAA3AE7D4D9EA37
+:102A100054B5D8633BD19825F8CF8FDDF0FF4E49F0
+:102A20005FF61542053C02704088F642ECEE50E439
+:102A3000F052795269C847E5DF7ABB8518807A2D54
+:102A4000B3A89F1049EECC91491E027FF8F1C71F31
+:102A5000F3859882AAEE427CDA5D4BC47BD78BA2C9
+:102A600031564588E4B19A4D73093146A5FFE50911
+:102A7000D1B245093AE8F9687F8C45A4085179C874
+:102A8000160C12BCF055EA84E0858FAA4141708B88
+:102A9000F0AE6944FB80C31DA0F2A1B8FEBF1D4A81
+:102AA000E5678FDABC0EF41BF0BF9345FD96A05F7F
+:102AB000827BAFB1088F539F17FDD727182B3C5946
+:102AC000AD70DFCDC926B85FA8A3A9FDE57BBA9993
+:102AD000EA7DE1CB4CF5B987724CF080862B4CED4A
+:102AE000077E50608207375E6D6A3FE4C824133C5E
+:102AF000ACF90653FB11676799EA4B130A0F2EA630
+:102B0000F91E4C538532488891A2D4D4BE542DB3BB
+:102B10000B0BFDA3CEF66923BD57457F999EEA7442
+:102B20002BF07C668F22DA650A31778DAC37DE9B1D
+:102B300057BF6A790695F383E6E7A5C2DA0AD37B25
+:102B40008B3F99FFD68188FE7AA7145B92A8BCDAE6
+:102B50001B9FF2651C262C06FEA8325DBD61D0E9E4
+:102B60003DD5EB90A4603A2FDCAA04EF253AF6128B
+:102B70003D1F02DD88CE22E8015D657DCB5A351808
+:102B8000A07EBEAB9EF7D6011BC18772D73412FD63
+:102B9000E7D638DC2AD53BD2CCF48CF198E91997EA
+:102BA00065A667BCD74CCFC441667A26F9CDF46CD4
+:102BB00037D64CCFF645667A76986AA667BA66A687
+:102BC00067C63C333D3B5799E9D975B1999E9981C8
+:102BD00005A6FA68FEEDBE62A1A9FEA1B8BD5F6AB6
+:102BE0008487948EAADB414BAF67DD1DA6EF097584
+:102BF0009C7D19E1AB344315AABB950F02F457AE87
+:102C0000EB2A5E5F73880F1E263A9C112B0F6678A5
+:102C1000CEE7878A3DABEC589F3F951F7E0D3EE87F
+:102C2000DBCA07C47789F8CE8FF833E2FCD2A0F371
+:102C300044AB7F9597E4C806AFB61AE5D4DEDF74DF
+:102C4000B192DC1045C5BD8BE2857089E619E0A71D
+:102C50000A91E0BD17A5F3934CF00BFE38D2E97F43
+:102C60007ED1C34A785374BC892879A6D4FF29132E
+:102C7000F35E4BCCA8A2FD849002F9D54934A4435D
+:102C80003EA58B2A05659AF0AE50316E4FE756F996
+:102C900097C184B184E9FD0F4B6CCCBF4BE2FA6F56
+:102CA000015F7E502BF9F2349A0C16E20611B2E164
+:102CB0003B1FC63ED219FD1510C295C1A8ACBB0979
+:102CC000E39F8EF17B85B84934DAF0F19942D8510F
+:102CD000160B0F97B385DF8EF76F16E1E598CC1FC3
+:102CE00053B45DC04785AA754D053E3A3574819C45
+:102CF00015AFB7C3A02F8857435EBF8B7F52BBE38E
+:102D0000DEA2BDF8CE28A7E7D607083FFB2C625EFF
+:102D100088E822C6B5E3710B6B51BF49FDDAFACEE4
+:102D20001296EF2F289A067C07D29DDE8D40725AAC
+:102D3000E81985E67759B227E7DEA4D6F66F782D35
+:102D4000DC9E582FA050FBA777C432BEFA76589766
+:102D50008C79FDD47E3FF4FADFC3B88DF6179BAFB4
+:102D6000DDEE5D701BF5DBAC88AAF53488F774BA2C
+:102D70006438887F68BC196A82B716748B9B71B0FF
+:102D80003DE1A1A283F629F4D2D4EBAF5A0E58D973
+:102D9000D7CEB390C677AAB8311FE325FC7F89FE52
+:102DA000CB9C847F9ADAC9CE5AEF44304591C43F18
+:102DB000FDA35F519BE397E339A0E37F7707ED1411
+:102DC000FAD96769E8E2051DAD0DF94C47B79CD704
+:102DD00049BBC4CB85F05010D7793AF05FE27078E8
+:102DE00055C2678122BFFB79E2CC199534EE9B2D49
+:102DF00045A961D534EEFFE071BB8ABBA663DC3622
+:102E00007DDCCEF63ADE3DD95857171A772DBE4FE6
+:102E1000780AFC4A096ECCC4F3F05380770BB7FBF9
+:102E20005E1FAD398BD4CBCD354A703DD5BFA5E300
+:102E3000F9511BB5C3BA748AE41A1ADFCF862D5B29
+:102E40008776BFD69C3CEE8DC27BD9EA4CD043B08E
+:102E5000BCCFB85B09D6123C4B7899EF4B445197E5
+:102E60001DD42EC3A7A5FA681C7F8EFBFB804C0BDC
+:102E70002FE301EFD177762DE9E0BD17D0D04BE3FA
+:102E8000FF2C921CE87FD278A9776ED6F1364514D4
+:102E9000F13ABD4E5471490BFE6405B59B4AFFC221
+:102EA000FA24B81FC6370DB0AF755D4F170D5CCE55
+:102EB00010EE171BE95BEFD474B8ED766A33C9D214
+:102EC000DCC5AE629DD2BACD64FCF7F311FEBF1D26
+:102ED000F3F6610578BF93E418E8BDBAFD25F1F17A
+:102EE0004445E293D6ED00E081D66D9ECF12B17ECF
+:102EF00046B797FC6775F7FC47EB870463427AAAED
+:102F000010574A51281E3A9D2052689E0DDDD4A0CC
+:102F100023137AFA4EEB0E9A6703D9130ECCDB5FBC
+:102F2000DCF114D58F257D7BAF94AFF1018227F8BA
+:102F300055712FF341E3D2F9F4FCF541544FED5FA5
+:102F4000A911F17904BFE2B3796B890FC79CD50E43
+:102F500024523981E47E985A5F9DB66A34EC83B17D
+:102F60009D488F44E889AB7B98615A089D40A76BC8
+:102F7000747C8FCB36EB9D09D03B46FB36F40EC9F3
+:102F80005715F8BDD1A7EB9FCBC465D03FFBABF77E
+:102F900088CF48BF187A6814CD30947D613D64B500
+:102FA00017CCF631DE3C76AC8F59566A0F7CBBB538
+:102FB0008E1323D6CB4BF90AE3D7438AC742F37F5C
+:102FC000EB901A047EACFEF010E06FE18B0AF3E99F
+:102FD000233EAD02DFFBDAD638077CD330343751DD
+:102FE00050FF9F56D3407AD3FAAD760A3FAD852F76
+:102FF000ABDD0C1FA94EE3F258B587CB13D5595C56
+:10300000FF75B597E1FDBEA25FE07BB3567C63D54B
+:10301000B2D17F15DB478B6AAC02F45A14BF50C2A1
+:1030200036A71B42F8EECE072D7104DF1D54BCD02D
+:103030008BF3770497C34C2BADF7DB5D042FEA9C31
+:103040003CCA85F60F28CCF5730E551DC474BF7E9F
+:10305000EFD3EBC68BD6F9969F5584464B2E7B80DB
+:103060007F39FAFFAA7A108FEB68B59FC7E5AF6F7B
+:103070003AD88EBE77BC7A2CC3FFEE2B5A09BEF528
+:103080008B6FD88E18BFA5C90A3B638C5FF183CEC6
+:10309000C3FD2218247CADB149BDB286F40AE4C058
+:1030A000C87E931EBD5540EE6B0FA29F6B93678F3A
+:1030B00081BD3A615031DBAFD7FF20D87E35F8FFB4
+:1030C00062EBC8231ABECEA0FE4E06247E5A76BC02
+:1030D000CB708B95F04333DEBBA3B454907DD0729C
+:1030E000F61DF99CDAB19DBA53B65B6893ED16EE06
+:1030F000FC75323F57946611A1EF8E131D05E12137
+:10310000CE99F1E8E7849FE35B7F91A645F0D7F184
+:10311000E4D0B71F414EFEBBC5BB9EF954FBEC7912
+:10312000C8D1A56E96335FDB425F3E0C39DB99F464
+:103130002AD757C54D223EABB00B8DF94E687D01A5
+:103140001F8F15338B5CB23F4F6FF91CFCD86BDBC4
+:1031500043DD7EE969ED6F73E8E68F1E061DB67DDF
+:103160009C70198DB78F2A422AE62FE438021B6221
+:10317000B99FB267EE49F613FC94225A54E6F72041
+:10318000F3F3AF6D622AFACD52ACF6C5C9E457DD50
+:10319000B73B03F3EEAD8A2A95D6E5ECDF3C97F119
+:1031A0001CBDF724C92295C6FF82CDFBF51E7CF716
+:1031B000511A3FF5FBE47DE539908725FF32FF3258
+:1031C000E0E18F105A4487DFEDDECEF602F1A477FE
+:1031D00014C9B57EAB5F5A924EED2F5FDB64E948B0
+:1031E000A56F83528BB274CBF6776AA8BF5CB7A584
+:1031F0000AF6EBC73E0F8F2B27B46EBD023DF0C31E
+:10320000131DB12EB3577F53D0515CD8CEF85D97C4
+:103210000F5A8A3D2C17F8FD9DF593DFBD51C08EE6
+:10322000210B06E32DB67B59AFD1B46DC0CF8EEE26
+:10323000EBF0FE2E4B80F5556096B4734E1605FEEE
+:1032400015F32FA7F60182CB7D0D4DB7537D795233
+:103250003711A0F91F092E9A86FA818A70033F154B
+:103260003B1E28EC48F0C9A1C2AB50FFF3769E2E5E
+:10327000647DD8996C757C6F476DEA0DD087D90550
+:103280000354AA2F5243DC9FA894FD55D66F7702B2
+:1032900026D427ABC46749F523F767785AE96369F1
+:1032A000FC4DA695BED79EF429C6BB2633905EE59D
+:1032B0006AD5BF19BEA21F587EB9EF2FC677BEA030
+:1032C00071C13EBB547D69B754CDE7F1A409776065
+:1032D00070EB773B5BC2F3310F5A1DEE007D67A3A5
+:1032E000BB611AB723F8B7DCAFE6CA1900FB8AB096
+:1032F0009E22F57B2DFA754FEE027A5D6AFF0FC5AF
+:10330000FD9DEDB44A4B82D791D76AE74C6D57FBD0
+:103310006223D1EB910E5A1AFAB959B79385D5EBBE
+:1033200081DCBFA3833F3D87ED34D2C316D6BF9D5A
+:103330007322ECE673769BF3D2F4EFEF3AF8BBE33B
+:10334000FD4B6DEFD1E312E7E4F0991C931CAE8DB9
+:10335000B70B1F3DAF5DEDE038863860293B48FE76
+:10336000CA307CC2D2FABD45F1391DA01F6A8568FA
+:10337000135F7B69FD6B84DB30E90D8DE4C0F0B336
+:10338000CDAAC672A2617F621EE4ADF0C77B103782
+:10339000B0082D423F467F87E85580F98D14714271
+:1033A0008BD0B37E9164C7BA15AEE44B9C77F80915
+:1033B000B3FED9F744E4BC87B67C1007138CF0D178
+:1033C00001E585E6F5A23EAF3F605E543E9F5F3467
+:1033D0002587BE3FEC2F6E2BE637CC3AB18BAF1B67
+:1033E0008FFB068C7BF85F2CE671FF106B822F75CC
+:1033F000FCB729E4D8818FBFB107B1FEEA612BD0B9
+:103400003CEAE76707B1DE77D945C009BF67929DFF
+:10341000EDE0FAF8403CE46ABDE20E21FEF482AD34
+:10342000619AF48B847BA30FFCFBE623E0FF1B5A1D
+:10343000EC0AE2591D1DE24BD857424D141B532292
+:10344000BEDFDECD710E157A2397E0C1FAF36976FF
+:103450007E5E6B13AC2703D362795CAB93AA5EEB01
+:1034600047F5AB6B32BC3472F18108AEE886FA3BAB
+:103470005596E7432CEB373E08BF67621AEB99D5A8
+:1034800049E18C4AB49F7F993740FCB0EBEF2AEBBF
+:103490008FD53E7F7AB20B7290E43CD179F5447FB0
+:1034A0007A6C0ACA540BE6DB91E43C3FCFA4765415
+:1034B0007E6493ED3ED4E946984E87BC7DB8A4A7C0
+:1034C00080FC599753703FE8840A27F1F3B59204C2
+:1034D00062DACD0F88DBD14E53836A26F0F29BFB74
+:1034E0007A117CC32CD58D38DDB5F3629A94FE54E5
+:1034F0006A6AD891402F4C19E38FF4D7D7E5F8EFDB
+:10350000079DCB437DBA7F1EC1C7D36EEEF973C84A
+:10351000874FC98F86DFBD2C557B84D7E91E1FB727
+:10352000DB43C6CD8FD0134E4F7FB6B74B0C3F3326
+:103530003C1BF8DDDBEC643BF642FC2084D77919B8
+:103540007DFF418B08819FBBEA7ABD160100D0390F
+:1035500014C37C307692D3CFF12A97653DECE8C74F
+:10356000895ED06F819D0EA617094AA6DF837B3B3B
+:10357000B35E9AA9CBB1DAA9B1FC5EED765BD0025D
+:103580003A2BC1A736E1BD1763587F96D905FB2BAF
+:1035900065CFF7653ED865F7672E43BF7B1D526F39
+:1035A000277812B9FEDFDA09D4BFA0EBEBB2D870EE
+:1035B000AF24A253E7F65A3DE8417C57C5CFEDF260
+:1035C000F9E160C13AAC4B41F64DDC7082857F1D5C
+:1035D000E45580ECA08D5E493F8C4BABEDBC1EE307
+:1035E000D5681CA0B3B843E5F91CA6B58CF91DAE8F
+:1035F000EACCE352268D4DBF99EA3F5B18C771D7DD
+:10360000C34507CFC00E389CA6F2BA270975DF4024
+:10361000AA279DDB702FC195F33F7D73203DADA898
+:10362000FDB0CB1E4F2BDEA72F291F27880FA62FFB
+:10363000B8738248B8F07A9D5EE6804FD9BABE85ED
+:103640001DCE9D8449AE1FCBF17F8879DB73B54FCA
+:10365000C00F95D9646F131F7D6D6F780C7195CF76
+:103660003CDA9FF1FCD4735F6DC273616DEEC5FCF3
+:10367000E16C2C445CA6CC22E34A0FE56A5FE03B98
+:1036800096C604A65F65C8C1F48BCB6E9072F1CE6E
+:103690004BD307C7EA37EE52A89FD2D8FA0A2ED5E5
+:1036A000607FE8ABE34A3841E9CEF8D5B0AE4EB81A
+:1036B000C309A08F6691F65EE9E6E879D25053110E
+:1036C000771342FAA921FB101AD70212BD0FBBF1E2
+:1036D000DCDEDA3EB3958EF41DA6A3707D32E3974F
+:1036E00068FF549F9C7B09EFA5497B7E3324F37CC4
+:1036F000FC45C3C67CCE1F8FBE4E8AC2095827C761
+:1037000015B94E4E0829BF029B63F478811CC7D7B8
+:10371000CF75E071A4EAEBE86B456FF79443B623ED
+:10372000DE833D53FA7BC9770FDABCAC3703A44F75
+:10373000202F4BDB49B8D491E686BDD5510D586298
+:10374000C197D582D70B8D8DD7E5F16D19FCBE21C0
+:10375000D7449110906BA5DBD2D74BBB4EF79B3172
+:10376000016ABFE077B23FC090FFC79ECED0FB9703
+:10377000EB299AAED178C8CE9571AEDAF8FC0EFF7F
+:1037800028BE9995F6F15A88A0076D725D07E2A5EB
+:103790001E21BB256D623FEC4FD84DDFFD3ADE3E6A
+:1037A000D3EFC23E85F9B9F1BD41B9D2EFEC1A456C
+:1037B000F78E6AF34BB097C41382E544F43846E0C1
+:1037C0003DA2DBD34F9FA3B32AE94E8C64F09787C9
+:1037D000F1276CA0CF8776838EB766905C2F05AEFD
+:1037E000BAB5E271974FCB801EF91A30E17B5712C0
+:1037F000C1D9B0B7A4FE3060831ED17CBAE4C3390E
+:10380000198D904FB9D23FA88D49E82F12517609F2
+:10381000420ED4105E514F7A70665136FCE1B1F71A
+:103820007F6E6B9DCF97D57E3FA9A073F09C353EF0
+:1038300027D6E7DCB53EE7AC087AD46ECE3DE4216E
+:10384000BC9FD86C456452D45A83BFB92205CFD5EA
+:10385000504070BD13F83EE1DAF726DACD599B945B
+:10386000A346C8A7B96BC6F84B22E8D077B3992E08
+:10387000FD4266F8F23D66F8E7A4DB31BF9FFA9E91
+:103880002F6C86730F99E1DD839AD51FA19F5C96FB
+:10389000A05341D9A2FE08F91E5483F033BADE5971
+:1038A00034793CC147D6CEF682CC73DF5F920FFAF3
+:1038B0009DDC79F7AE727AEF48B2C50BFFEAB80823
+:1038C000FD713CD1634EFD2ABBD583F99AF97C97F3
+:1038D00045E7DBA7651C707ED05C7FBE7CA8D1E38A
+:1038E0004E222B92AFA2E94FFD5EE7A781952D9E58
+:1038F0007C3FEC9F79E388E1697C8343ABECC27544
+:1039000029FD0418AFD604114EA3F135DD1DCFF10A
+:10391000972B168F129FD1F7CAADEEFC5FD23C6792
+:10392000391577C0DD1A576FDA9E5E017DBAD16D09
+:10393000F1928F23DC83AA0E66E4C19F1021B71792
+:1039400071FDBB96C3EF9F5795C0F8992F821C97C6
+:103950009FB5D4D12A1FE9BF929551E3591D514F0C
+:10396000F398B7D6DC7EC1861F1D91B0E1975E51FA
+:10397000BF4EC57C6FD6C7AD0626B05EBE428F5720
+:103980007C8EA6A46FB6762FDA9D8BF6AB47CA7AEB
+:10399000AB53D7B37EF6F3CA5D760FCB33EBDBCBFD
+:1039A000797F87D621F4C3A1F8393F87BC3BED145A
+:1039B0006E870FED3586BF6C27FD42DEB7A0F6A7F8
+:1039C000D72AACD7CBDB49B8FC09258818703982D7
+:1039D000B6809F9471DA321D1FE0137FC47C40AF24
+:1039E0004858D419F1F130FBBF1555C20B3B4010BC
+:1039F0001DFD06DE783F2A6C3F023D1B50420FFB47
+:103A000060EF99BF53B9E74747247C2EBE4CA4AB67
+:103A1000E1EF07198FAA5DF821C7D5BB62D96E27E0
+:103A200005100BFD6ED3ED6BB122D81EFA6A35F48A
+:103A30001595CB743B3CB04AEAABD549FE5E6ED4DB
+:103A4000AF4AF7020F3728BA7F0BBB3E09F6F53EA7
+:103A5000EEB75971BBD727A1BD08C4A4B07D2DFD19
+:103A600084BFABACEF9AC97E5F0F7BDD170A633C66
+:103A7000AB1FC8647BFD0543EFDD1723EDF9F3EDC4
+:103A80006EB6AFC4FDD27EFC4808E9F7F6D0BE039F
+:103A9000DD67AB45BC1955B2C49F8EEF964CB25B47
+:103AA000400F31EFD2F645365A65FFCD345FC4EB97
+:103AB0003F578A0E5A22EC60679ED40FF905FE4DDF
+:103AC0007A3B2FDA9558DE663C9458841BFEFCC680
+:103AD000B3AAB012BCB1CE115C42AF9474F3F75AE2
+:103AE000988DF7647CEAB04FCAFBB83CE10F52995D
+:103AF0009427F555529EC5548AD132CEF2798CE482
+:103B0000C3E9A2A890F7073C52DE47CFA3B3FE9DBE
+:103B1000127B83793C9FEC67BA90CE732F017F8F25
+:103B20009676C7E7B728ACCF693EBDDC04E7FF4B0C
+:103B30000CC7173FD7F591815FE29F0188A31972E7
+:103B40002B49E797D5F7049F8A217CAFB211DF801C
+:103B50006EC4371BF398EE6C17AE9E96CA74BF41C5
+:103B6000A7ABB82F9EE936C4629178BE2F9DF14C69
+:103B7000EDC55FF1DE188FB4E72FD10F23BA0FC860
+:103B80001B70BE3F66D05B588303FED1FE4DF9EE3D
+:103B9000ADBB02C4FF0B7EFF4082A07647AD75A986
+:103BA0005E7ABF6CE3B2043F9547AC810437F57F82
+:103BB00034A88E0DB681EF453A3F60FF4049C5BE3F
+:103BC000AB94E3C79EFEDBF23B689CDF2AA219F2AE
+:103BD000B162C7F7CBEFA0F91DF43B9B214F8F5883
+:103BE0001B0B2177E717BBAA6ABC58BFE638FE82D9
+:103BF000271F48F530BE031996345EFF1978AF626F
+:103C000083CD0BBFAEE23DD5EBC1BA17CDCB31BEF4
+:103C1000E8F72B439FD9817FB74534771AD246BD49
+:103C20006864395FB9E3D7DFA809288F7E04FFA253
+:103C3000326AFF609EBEBF12BD8F303BCF9CC74033
+:103C4000F8E13C86008DAB27B38B8C3BD73EF5501B
+:103C5000FF26D80D1B5E4B50B25BF70F8C7D9796FD
+:103C6000D0ECC79FF75C785D7EADC78D5BE926E53C
+:103C700098670F0DAC83408081CB325B3801F67EB4
+:103C8000D93A1BCB91B2AD4F6C7A18FCF6A1C3DBCD
+:103C9000D303F8B41DF2A04CF1372B2CDF458292F0
+:103CA000DF4AAFD2AD5F143E02FB3A5D15E3885E9A
+:103CB0000B9E3D23DBFB45730CB52FDDDE5408FF67
+:103CC000A04C735539DBA0D7A8D04BF646571BF450
+:103CD0000A3515729CEAA9EF981E47F72AA243E617
+:103CE000F9EFCF5BF7855D48FFA0B95D92C417F48B
+:103CF0005D65482DB6279EDF9EBE3FE1F93CAE775D
+:103D0000C35FB9181D4701178813EC8E1749D0DB24
+:103D10001F3982E340DF6D8B1204F1FF57D62AC9A9
+:103D2000F78F2E4B859D37CF16487573299FCF7B14
+:103D3000EC36E6C7B94A55AA3B9BF93DDD3288E728
+:103D40009B8E79DEBCF65A9EE71CA1313FCE7B5498
+:103D50002D0A5279C62AC66E6F63DD9CD4E5944362
+:103D6000DCD21FEBE40C7D097AFC2BDDAF0FBC230A
+:103D7000FD6987989418B99FB457978B01113C0C33
+:103D80003D50D960E33885FAF699427CE7D64C6B12
+:103D900015F23D68FE011D5FCA8FD27FF120EFA1B1
+:103DA00012FF227D3AEAED311D1AB3F1FD16FB4DEB
+:103DB000D4EF5FE0277A4DEF31DEBE5AEF88552E03
+:103DC000A73255DAEFD1F3E8344031ECB877440448
+:103DD0003F556EFE8AF949A4A922314DC2D8BF7061
+:103DE000CF72552512DEFEF2DE6776C4BF032916B8
+:103DF000D113E36DF88261E16DEF417BE3FB957BCD
+:103E00001C221CB96E377C11B5AECDF54254313E43
+:103E10002B45A207FAFB2B7B73E10BE887FADD4801
+:103E2000FDCC21FB2B6CB2AF9A0B1F813CD9637781
+:103E300073FC81ECCF7004DF9CDB1FD5F705E7EA4C
+:103E4000F2201A0FD1F2E1AB28F960BC2FD6B6BD33
+:103E50001FD52A17022C4FCB6C22003BA3EC430743
+:103E6000EB8FB2AD723D0A92A73D697D1CDFB2FFB8
+:103E70008F37C09F0DD952C671AF66F93BEF992FAE
+:103E8000785EB309FF315EC8DFEFECF07FD346897F
+:103E90006607F68B57FAECE0FBF3D6313D6F731DE6
+:103EA000AF5458BEFD57E52EE1DB0E7BEB62EB75A0
+:103EB000EE05E46EF20073DED019919D380495EEA4
+:103EC000E2AEBC7F10855F03AFD172F4E93C4F9B3B
+:103ED0007294FEFC5144E0518846E6E36F492E623D
+:103EE0001FAE62C3F7ACD708ADCD0EE2E38AE03770
+:103EF0000C2F835E63F8A52988579E3F6F333EA33E
+:103F0000EBDF03EFD3D08B9EB3B15D50562FF31C84
+:103F1000E93DF63B2A11AFE7D67507335222E1603F
+:103F2000141C8A6AEF8F828BA2DA6B517095A97D7F
+:103F3000D99EFDEC67D1B84DED1C8BAF613FE47CA1
+:103F4000BB22C878ADDCF18D3D00FEE8D46C875C07
+:103F5000B42D1181787ABFF94595EDDE539EE604C4
+:103F6000D829CB62A41D77CAADC349062C6616D3E7
+:103F7000384E05FABB9157D01C23E32DA78A9A131C
+:103F80009222FCF6A67A35C143ED1B83626CDB7985
+:103F900031B58CD74671A17A69CF8D517FD826F380
+:103FA00045ADC241FD35D67CB70DF1A4CFC97F82A6
+:103FB000FD5252737D02F65F4ED577FFD954F881DA
+:103FC000AFAA9CF325027E3BF226664B528A23223F
+:103FD000F0E0509A9F1A9F77F005F857C428D8FF51
+:103FE0002C591965DF88A2C430FCE9D5D1F90D41FF
+:103FF0003BEC9BB9A467218FE6AD35D72FA83FCE08
+:10400000EB6541D47AD1F4B871F47A596CAC179F4E
+:10401000F0E9F9969CD777EA90CAFCD5B2D42696F7
+:10402000A7C8BC5AE4A3B4D4CB7C9D963D1216011C
+:104030003D0F485FB706DE4E603DF5BEB0DD7262F3
+:10404000E7BFE7FF12FCB3EBE3FE8F507962D7873F
+:10405000BD5E00BCFB4F5D3E16E7B71FB5F7FB1911
+:104060003CAEBD0E81719DDAFB4A17D81BA79E7727
+:10407000703EC2A9250EB6D7037BE3396E71AAB391
+:10408000B4876B5FFCAE7F23EBE3A54CC72706D854
+:10409000A55D55FF37D68F2DF50E0FE651B9378E3A
+:1040A000D755E5F331BCAF76EAC5EFF223E371FFF4
+:1040B000D5F918FBF0A7E2C5D467C0BFBAFD5FF918
+:1040C000C2E0276AE02FEF78C93E1B79257FF88F81
+:1040D000FE90AFA79E7989E5EFD7B6C6C710DBDCA7
+:1040E000B6F3C0C3B674C4F5E8631D85B87297F51E
+:1040F00046AC9FF3F122F1708AF08079115EE6C13F
+:104100002EBF103E5EFEA7C5C73733A49C1B28B048
+:10411000EFD38A17C52F9FC773BC8AE62F9FEFFD89
+:10412000AE3FE4D0C5E6FB19E6DBFEFFCE7C95FC96
+:104130007FD6F94A7EBF678087C719CDF7E7F3F5C9
+:10414000EE9F33BC2DDECBE3BDC4F59E99FF7F8B84
+:10415000BF47FCD3CEF762F47E55A777BC1BFBA00C
+:10416000A75EFC8F2EE227CC7BC6FF523E37ECF9D0
+:1041700002D57BC847ED5F13A1F7BC996C95B46974
+:104180008FFC3ADF88A7487F6A14FEE541FB9CA5B7
+:1041900021AC07B227E0C7D4BA720EBC4DF02B6435
+:1041A00027A8BC2F2BE349AFA4F98232BE5B2510B0
+:1041B000CF2AF8D36C865FF75D7900792585AA8CC4
+:1041C000C7ECAFF16E68A079EC4FB2786A091EDDDA
+:1041D00069F6E7DBA9DEDD5175C33FABED94EBF487
+:1041E000448C6FB4CBEC675D13E5275DE531D78F69
+:1041F00015CFA460BF6E6CB64DE07C4E21DA47F857
+:1042000095F3F3DD3CCFAB44DD52B7EBA7E3E939DF
+:104210003DAF92F0C2FB36814EAA9E1767C69B0047
+:10422000DE5280975CB6DF03C27BE06D82ADBA7D63
+:1042300025F4FDC74267FC26F8D10E51100E127C02
+:10424000C663AD427BAB207F58CE93FDE868BC09C6
+:10425000DDAFB6EA2418DD69541878C6F3AE69A656
+:10426000F779DED178FEE978DDD76911F09A16EF9B
+:104270000D822F3A3D9B82386B2DE159515AF169DD
+:10428000E0291AEFBFA1B14A7F5DE2BB93D567C5B4
+:104290003A1BA6DBF3A3AD4912EED4A016F1FA0B3C
+:1042A0004ABEFE8BD70A7B64A42B89F349857ECE58
+:1042B00042D5F7C39161C7E320FF1479B913ADDA92
+:1042C000ABF99C8FEF1605F05B0B4408F15BA5FE84
+:1042D00095EFE11FE17C4911EF6B1EFC00706FA7A9
+:1042E0002B0C7F50ACB59E38672723EE1F75BE623E
+:1042F000C2A0ED2341AF598BE919E2586ECF41AC12
+:10430000C7E2FB1D1ED0AF93B581EBC9D772D70CA6
+:10431000C66E7588E1D812B2F4D3D1EE9591DC7EE9
+:1043200091702B4948B70B29805D6E99AF46CEEB53
+:10433000B780ED4BE33DB5326E22C04F3D5076C3A2
+:10434000F765FBB4D1F43DE4BB098DEDE5D81E1C47
+:104350000912DD9422DE7FEFDA5DE645342F73B07B
+:10436000BF537C77E75E904BE30ACC71EBA103650A
+:104370003CC7289F1A28E5886AF1A6E13BB396F668
+:1043800061FF4B8D2D2ADF093C6E8B633E2F5E7ED5
+:10439000D3F801F4FDE26DEDBC18E6B109DBF3657D
+:1043A000FB69B7BD4FCFB5CD31FCFCF581DAF7F92C
+:1043B000C833503C3376D28359D7EEB7A751175A3A
+:1043C00068E249C41D2704B6BF897DCE0953546EE7
+:1043D0003F41CFFF144BE378DF7C7CE01B6B1A7D01
+:1043E0006F3C3935A86F8A7177B985C65FACC79BBA
+:1043F0006D03E53A546385F68C0BE3EADCAB1B3DB9
+:104400001F2F643E74F4BA1DA9B7EF3ACAEB4901F5
+:104410007E9418F7FABCD6F6F80EBE7BA58E0FF781
+:1044200040B9EF6BC084578E8B97AC7034754F409A
+:10443000690BF7A6B27A7041CA40AA1FD74D14AED5
+:10444000C1776F57C57A1E6F7331C7D9E3B33CA0EC
+:104450008326EA38DF48ACEEC9FB394D2305F34F1C
+:10446000D3AA4C83DE9C9F64F8734D23BD0791BF94
+:10447000D53CD2E95DEF457E4B288C38CAE13572D8
+:10448000BFA66B6DB807E46CB34FEE837CB138D731
+:10449000033EB9F981C909909FB357AB6107F87D15
+:1044A000A5396F49B8BD9C373EBB6EA41DFE6B8914
+:1044B000CB6FC7BCAE1AA4790742FEEBE7222FC32D
+:1044C0009870EEA7AEF875F87D6A02AD67AC3FABA9
+:1044D00027017E7574DE53A59EDF64C0CB52B5C143
+:1044E000F8DEAC44CF363E5FB9B83BC7556F1F28E6
+:1044F000E5AFB0867B003F8FD15AC0FA3C912FF9CF
+:104500006F5CB2BB978BF93746605E4D36772FF004
+:1045100073D3B2180BF0346E89E4E37BAC727D0583
+:10452000FD1E4B80DE8FD1F9777A8DB5681DF5D3EE
+:10453000C929ACF1C9C85BD3DC18C7F840CD61F814
+:10454000D7B3757D357BA53C3FD67594A4ABB0360B
+:104550008C6E47CF8F6CCCCC415EBCC137F5830BE2
+:104560008A0646D07F5C81BFB03D7D679CC5D30283
+:10457000395C324579A9BBE4836B07B23F5FCFEB6F
+:10458000BC85E4842309E7061B248C7C55C88DBABE
+:1045900087FCCE08BFDD2E7670BDBD44E6A376B5A0
+:1045A000876B38FFEA16E15E42F026B223AC362173
+:1045B00036573BB97CBA9AE45D4F21B654A731BC5B
+:1045C000ADDAC365A83A8B9F3F53ED657847F52078
+:1045D000867755FB19DE533D96CBE7AB8BF879B464
+:1045E000FC99ED9AC3F2C4DD8B683DF87CBE99E17D
+:1045F000A17141FE3885FB6EE4D30A29EF92B2A483
+:10460000FC11BA3CEAD647F0F99BDB410FC2BB6D07
+:10461000C5480B9FF7B436A683EFC6A827B6EE466B
+:10462000BC639E8BF3B25A4423AF931661F106F23A
+:10463000A4FC7110DF75BD6B6C66649EFA8DF3147B
+:10464000618DE0AF9BAA628435423FCD5C9C648261
+:10465000A72F7EF7E50EF4FD3EDDB47B41FFC37767
+:104660007DF9E89FE8F9E3771DEB29CFF5FEB02E41
+:1046700032EED2229A256C75F27EFCE377A4A7B6BF
+:10468000EB26BF077ACDC23F3CA04FF3D127B10E36
+:1046900097A9DE25047F04FA103E3FD1E953BCAC54
+:1046A000FBF25F605DFB9D5E85BE73F88EBE858309
+:1046B000A8FDE3FA7E945841788DD43369527F7D0A
+:1046C0000AFD9524F55901E46858EAAD4F7F951A23
+:1046D000B81BF5B724787102425BD1213097E09581
+:1046E0003EBB57455CAF5E2C47DC86702CED8A8064
+:1046F000CDACC71A3B25211E6C9C938ECB0B3AF98F
+:104700009C167584FD985959FB443AE4529DE2C6C3
+:104710007E0DCE753A9321DF14DE1F451ED014D2D4
+:1047200097CF0E54797D9DCAB772790D92E508AF87
+:1047300031C2CBF1999295D41EF2B1CE679F13216D
+:104740007F67E9CF676759B8349EEFD3BFD77185CC
+:104750006F2AF8A323EAB351E64CC5F83ABA0AAD7A
+:104760004AC4FE6FFD402BF7772A5FF67B0D884A1F
+:10477000EFDF9BD5CD7E73369FCF62BD65F4332BC3
+:104780002B677937E8EB9523811D516BF3A6A55074
+:10479000BB97075AF579E8E7C29D323FBBEC027A36
+:1047A000C388D31DC13FE539499EEF826DBFDB86CB
+:1047B00073120B3E76B0FE5A70B9D44B223B983F31
+:1047C00099039AE6B8F8E8DF9D3C78378DE724CE68
+:1047D0003121DEBFE3333BF24369D95425A60356AA
+:1047E0009B90671A1D9F3DB0EDE38436E3E23BD416
+:1047F0004B8B8B2B3F24402F18F319F3E29954D89D
+:104800005995CA59DE67AA7C9124751BF38E8E8B4D
+:104810009F8B9F8B95DFA88833DF79A4CDF87974BF
+:104820001CF0FB81D1FB11AE02C8893387D420F67E
+:10483000D35B823D13451BFD1BF1F3CA35F4523B9C
+:10484000AC4B4F22F6C34E5DC02E1F3E48FA2F27B9
+:10485000F578FBA92D2AFB4BA7B6C407619F566CC0
+:10486000B9FF20F6292B36286C9E978B06C617E1D8
+:10487000513823F518F2DDDAC1B8F624425E19E3A7
+:104880002BFD5D7C15F86A7E48F16FA471B4383D4C
+:1048900089ED23C6D17190E4CF5247289FF1AA8FAA
+:1048A000DB3D48CA41A3DDFCFAFB392E4DEDBE6667
+:1048B0007BE7F77182F30445F39B18DFF1B5B95E2E
+:1048C000EC2BCE0F6DAFE0FC8E2D716EC4218EE906
+:1048D00079CEC6777AE9FDF51A24ED94E3FAFEDD88
+:1048E000F16DF27C3AC689F5744C31E70B66EBEF5B
+:1048F00065EBF87A475FC746FBF9A1A6841ED4FE94
+:10490000AB3DEF72993F48AE97F9AE86FED0BB5FE4
+:10491000ED88E3FDF8AF763C528838F3C9D0C8146F
+:10492000F0FF397F6D904DD261AD3A16F812419982
+:1049300067530EBCE6468EB3DDBA4066E43A93F99F
+:1049400046C7773C9B60C96EA563B9B3CA89F3A11A
+:10495000953B6E29021F1FB4497CDA774C0CE0D8D6
+:104960007365BD4F807F799DA573FB159688760E84
+:104970009B97ED62DB9E623FDA1B71E8853B6D7CA5
+:10498000BE70C6E59EEB6FC43A7CCDC67458D8C7DE
+:10499000733DE72335A89CBFBC305384617F2CBA9C
+:1049A0003D7E1DF6C38CF1CEC895EBBD6C8522FC17
+:1049B00034AFB2A02A342A3B12DD03C8514A6B1C23
+:1049C00080FCC9A6CCE03DBD52F8BC6F787D4A6B37
+:1049D0009E29ADE35E3817593E2899E7FDE0B442C1
+:1049E000D67787ED2200B9107846E6E1947593F901
+:1049F000D10F83EFD15F72B8573B9AEF099DAE6537
+:104A000093C2BD909751F64C3AE7659CB0CBFD52EE
+:104A10003CC77E71590EBD4FED52F47C5EBC9F14B5
+:104A2000C14765B3BC1EB45393BD1E9F0BE3757F96
+:104A3000CD76EBCE7801BBD5B23B5ECFAF8AE13C01
+:104A400072E3BD9A41D22E4ED1E9296E90F9980FAA
+:104A5000DA64BEEA831BD3F97E0CA3FD83366D1A9C
+:104A6000EC27CC03F6FA7C7B5D2FECBB18E39D9F13
+:104A700050C7E33CA1F3F9FCD83A9917AE9F3B46E7
+:104A80007BC04D7A1E7BF3530ECE5F3996DEF02D40
+:104A9000C67BECA93EC88101BEE7ECE17AB21F8972
+:104AA0009E0B9E7684517FF42919B73E6A0B7E0BCC
+:104AB000397CF4D1767C3EEA68FB603EE707286EDD
+:104AC0000BECB3A38A0EDBDC6C5776B5134CED53BD
+:104AD000628505F93B6327AD9981FC86960D0EB082
+:104AE000A738B6E9A154F66B842791F36C0EA9029E
+:104AF000743BF6F4DFFA44DA2F46B9608339EFAE3F
+:104B00002953DA9546FD3A7D5DAED3D7F5C64152BD
+:104B10004F95C7851EECC6F393F826FAB07F470A77
+:104B20003E9EF327B6F65420371E16C19F7F9CC7C2
+:104B30005EB60779F365CF3CF526F66B8F594403D3
+:104B4000EC0FE5AECD3FC7FD1C29BF49643D24C431
+:104B5000069EDF51B73CD74A0B96E73FBF838417C9
+:104B60004CDEDC0BF041D2390AADAF051685FB5F98
+:104B7000B0AB1FE7DB113D2CBC4FB65DD5C743364C
+:104B800025F0B749E62B8F4B0E6E82BDD7FC6877B8
+:104B900081F3EE63D4B5FD41BFD31BE22CE0A7F255
+:104BA000BB87240E01DEDE5205EC8FD3566F87C81B
+:104BB000384234BEA2F3C0BFD5E55319AD3B9CFFCC
+:104BC0002CDDF528DF2F520ABE045E9E56781FBBEF
+:104BD00074F99087984FDFB4899ED4EF89D0FD098E
+:104BE00091F469D4E5E2B9EFD8BDDCBE94DACBF735
+:104BF0005F4BE0716EB2715E4B345D2FF9FDA7D54E
+:104C00004B7AFFDCFC436417F43F1F0FA745C3CF6B
+:104C10003FA6EFFF654B0CFB83E401F039B6E3B62A
+:104C2000D01CCCFBF8D618965FC793A49CF88AE4F6
+:104C300069A037C671CD6F994FDF99CCE7FDE606C5
+:104C4000CDDF35FAFD02721C7CD7CE9B08BFB3FCCA
+:104C50002D290F895E3FE3F7DFB2F1FBD1F338A0D6
+:104C6000BF776E9D6E8D63BE38DE51D2E3F8B6DE3F
+:104C7000AC9F9A92DC82F9E6299BACB785BAC00E4C
+:104C80003EBEB5B7AF36E2BBC793425DDC11CF9BEA
+:104C90006CC1E503A53C6D865F2CC2246AF3915F6D
+:104CA0002458CE1BEF953A5736C04E417E6F7E0E8C
+:104CB000976147F2F979BAE392A53F396CB08C0F4E
+:104CC00070CE6AAA9E4FCE764FC80E39AEE9F66115
+:104CD000D996E83C5F59DFC9789FD65D8A91576CB9
+:104CE000C17843F6348E3708CF3334DED2A5B7CC43
+:104CF00047FE7869D5AA1B613F955AC5583B8DABD5
+:104D00004951791C4D3162E624D89191FD44D86F08
+:104D1000BD079F8BD30A772ADBAD6CDCF71D2CF522
+:104D20001DE03AFA5ED9526525BE6FC8170E14A66B
+:104D3000B6E20979ADC8EF691AA9D75F60DE4D36D2
+:104D4000591F3D6F633C23064B39D594E9F9ED506B
+:104D5000D0E50D95CF779DFE213731B90D3BAD558F
+:104D6000DFDB5BF36C69FCE3605BD377DC83A5BCC2
+:104D70002BA5F1619CBDD69AF3CAB33698E1CBB6A8
+:104D800098E1EC1D66B87FBD19F61E30C3797ABF75
+:104D9000F0B3716E197E364AF8D91E87F4B301C399
+:104DA000CF46093F1BCFE16703869F0D187E366013
+:104DB00003DFF0B701C3DF46FDAF743C097F381550
+:104DC000F99A151699E74BF4F0F339A66976D3B939
+:104DD00094532FCA7329C40F52DECF77F13A791852
+:104DE0002D06432FC9F594F2BC23B884DE1BE1D114
+:104DF000E60EC67A5DF3CD1CF05D45B746CE7B6D01
+:104E00005AF64AAFFBA95DA3122F605754ACF9665E
+:104E100006ECA8248F568EF695B10DCB0772DC3EBA
+:104E2000CCF2A3B1C6F3D60849478EBF14ABB8295C
+:104E300083EAE725B7993F149D772E569AF3CC2F36
+:104E400096771ECD07861DF8B8AD39DDCD7EFAD038
+:104E5000C710E75DA8C4BBE1A77F162396E0FEA0BC
+:104E6000C0AB324FADE5904DE60DAC54D68B08FB90
+:104E7000E4D73ABE0D78F6D95CB6C7CFC12B158BF7
+:104E8000B85C881E5A7313FCEBD3F32C6C779F9E8F
+:104E90005750D81EF61FF9655813B89F2B72BCB82F
+:104EA0009F2B927F703F97F9DC4447537BDCCF65A3
+:104EB0003E377199A97EF2CA5C537D49D110537D6A
+:104EC0000F21C7B768BE1C5F09E9077F3BC04B389D
+:104ED0006F71116847764A1725B09CE5F23A85CF85
+:104EE0008D7B16AF28045E4E103B238E60F0CD6C98
+:104EF0005DBF086BC00EBE3B9322EB8F2A0D5FDEB9
+:104F00004DEF9DF4D56DC2D529272D6B1F1CEA41AD
+:104F10007EFDBA2E6E5A87B72AA154889E3579DA5B
+:104F2000AEC1ED919FD23891F713B7B74FAE81DD87
+:104F30007968C09B83D0DF1695F3260C7EE96293D7
+:104F400071BA75838866644FACAB93F9BCEBEADA4F
+:104F5000C5F688D87F31E6D9023A08944B525338C7
+:104F60002E241A300FB2DB97C06E3B7D48DAEDC6B7
+:104F70007C7A2C0D775A44F5B76E8F61FC7CAEFBC2
+:104F80000D27FABCD4DF83F31BD57BBAA8B0072C5E
+:104F90005B36C18F70A4686F82EFE7ADEBF927DC59
+:104FA000EFB5E07D55E03CCD17AB47250CA6EF1CD7
+:104FB000DB6AF38E23F8EEBA27ECF093175883766A
+:104FC000CEC37C6A9D1D79C9576E5EC7CFE76C2E34
+:104FD000E6BCCBB9A28AFDC823FAB92C63DEF30A7A
+:104FE00094B56EE22FEF15920FE7C5CAFD3CE2E7DC
+:104FF0009731AFD39B151FECC72945DBEDC5D0CF4B
+:105000003ABF7AA64E1D03FE6B09C9FB395A5E579B
+:10501000E5BD63535499177381FB7C269FCD64FED5
+:105020009E72B62FFB59D786FB483F365BCA8F96D8
+:105030007A95F7E35A5EDF9F3219DFABB7F1EEDD09
+:105040003C7B833CFF6F11553847E099DA20F92A01
+:105050005354C1FE5BF4C6BB07B1EE16653A3D582A
+:105060000F454355137F568E8E33F1EF54916C3AB2
+:1050700047731D924A22E029E3BA9BDA5F3FA56F8E
+:10508000943CC869AD67797045D439C002135C4E51
+:10509000E59D904FE26AD37BE562526B3BF8C31B00
+:1050A000A4DD5ABE23693DF6C5E759A43F345593A4
+:1050B000CF2BF6C8E742C49E3B978EF3F8880F9833
+:1050C000CE6DEBFB7CE897E381DD1B38AED39C4EC5
+:1050D000F292305A9ED568473C8DCCE566C449CBE8
+:1050E0000304A35FBF68AEC5F911ABC4AFCBEBEE51
+:1050F000B624BD952F2A7698F3AD2A0EBDCBED8C44
+:105100007CC6E87AB2D39777C4B8C7293E3E37B990
+:10511000A5C98E78D014AD13DF4B117D5F5A59A805
+:1051200089C779ED9E5437F66D2BA2EE495B7885E1
+:1051300047EA273DFE8F7B86A49DD06097715BD7A1
+:105140003E0BAF3F792FCF39BE9C6791F70544E105
+:10515000659CEF7DEEAF63BACC43035EAC117889FA
+:10516000E623E0C91A81A73942E2690E499320C1BA
+:105170001DC16791F8F989F89A8B7F50FDDC3D4A93
+:1051800010F96FD1F899A33532FEE668AEAAA0FBFC
+:10519000FCF954DCF9C141C8A76DE9F25EC368FCB3
+:1051A000CD150DCBE1F7CE25BD114E62BEB03BD97A
+:1051B0004F53BCD0DB9E418D769B94671CE76D7985
+:1051C000FD5D5E772D5E5AD5E00B41F5D4DEE5F747
+:1051D000342F6923CF77D259193FB9EEAC95CB293B
+:1051E000E3CCEBEEDAB3A9FCFCA7E2A50278069FBC
+:1051F00023AE97D0C63D7B88F3259C3F5F633FC4B9
+:1052000090C3AD769D396FF942F65F749CF0AE2B7A
+:10521000F47CC1016280296FF902764774DEB2A185
+:10522000C75B5C524F8E51B3DFF2D0BC8B5F55D958
+:105230004FF74C1D6BE1F3E3AFCAFBF1B465679A1E
+:10524000C09F5ABC85E5E0C2F86E7CAF85A6C7ED6D
+:105250008C7EBAD4B44B45FCAF38C6CDF9F8C53511
+:105260006A11F45731B5F344B45BBEB47B17E885DB
+:105270004FEFE9FD5880D6CBA7B7A7A422EEFFD900
+:10528000325B0A49CE73ED3E5D36A60BF2333E5BD0
+:10529000E5981A6C033F9B747D517ED707ACB74EDF
+:1052A0005A5E4F984AEF972DDB9980B4FFD265EF95
+:1052B000E6BBC9A4B8224FDB7805EFAFAEDBE4064E
+:1052C000BEDCEBF83E815D242EF17EF1B2654CF739
+:1052D000058ADCAFBE55097F3982DA9D8859953041
+:1052E0003513B7A10ACED338B3215E3F8F56C379A9
+:1052F000432762C91EA0F64762243E8F6C8FF7F2E7
+:105300009D18DE4017F6DFDACBFD9D524BFD751878
+:10531000CF5529DAAE2B06601CC14D692AB7E3735D
+:10532000EB5A4DCFC4B6E21FE7E6A9EB69D8DB28FC
+:10533000616F235F06F63660D8DB28616FE379E59D
+:105340001AB3FDD6A0EF171AF1E0AEB5CD3ED8BB2B
+:1053500081029155C57A765CC1BF426FBD2AED8549
+:10536000458A774523DB4BF175F03B6BADD2CE0E12
+:105370007C22CF45D19F2CC8A75FA89779B19FFF0A
+:1053800050DC5D8FA3FD62EC0FE5E1DE53B2BD2280
+:10539000F875C459A7883C773B928CB04878943311
+:1053A000DDD47E8C3BD3547F655A1F53FD551E9F21
+:1053B00009BE266BB0A9FD78EF4813FCB34157999D
+:1053C000DA4FF44F34C193C74E33B5BFB6A8D854A3
+:1053D0007FFDD4F9A6FA69DA2D26F8C679B79BDAEB
+:1053E000DF545563AA17A2EA49E0C71F90F7B0D56A
+:1053F000C37F72E0FE17279754FF7BE4318F24515F
+:10540000CFF7AEBC71DBE380F721AF9956DCD0510A
+:1054100096AAB6E2F8B62132AEA80DF5FF7805FBE4
+:10542000B90D7C8F2662B7E0BB94211EDDCF96CFED
+:105430003B598DB855433ADF9710D5FE42ED86C6ED
+:10544000ED3BED2196BBF385C76EB20E461EC4BE82
+:10545000DCEE04EF1DD2749395E4CDD021FB9EEDDC
+:1054600046F0C117FACC60F8F27DA7513FA5FE0BBC
+:10547000593F59B069D230E4DE9B02C47743477488
+:105480005BE995719136CFB71B25F08473E1C013AA
+:10549000CA30F13DCA7DC4F7280F10DF97905C3BFE
+:1054A000487C8FF210F99978FE6FE467A27C9DFC2E
+:1054B0004C946F927F89B281FC4B94EF544FE5F28C
+:1054C000BD6A8DDFFB63F53C2E3FA8AEE2E71F55BA
+:1054D0002FE6F293EA003FBF7C888C23B848EF4068
+:1054E000BF57200F06F902D1F72C57B9F9FE835A9E
+:1054F0005D6F897A3DAF661FF9AFC067A335E94B91
+:1055000067EBFEE285FD7DABF832C26E9B68F50F5E
+:1055100019C2F4EDE4E6FD21FDF90B5ECD3F84E810
+:10552000FB7EE6E49EB92AF45DD5CB8954F7BEA58F
+:10553000EDFB2753747EF10DF58FC17BC39C8779FA
+:105540003FDD934ED6EA108615D05FC991F1CB614D
+:10555000D6865AD4D77E2F3CF09B5F8AFF23EF83F9
+:10556000D792B98CF3C7CA59E9AF0CD7F7EF6BBF25
+:1055700097FBF7C33176AA1FE696F5B53793A6F3E6
+:10558000A13EC4DF1F8ED3CEF27C9B296F67F4D976
+:1055900086515CEFB27B906F3ADC1996DF730A3765
+:1055A000E2CB2FC5EF92FD8F91FD6FF83ECCDF87E8
+:1055B000F7691B8CF1B78E67098FAF41DE4F972DCE
+:1055C000DBD7EAED876BD47F12C65725C7574CED62
+:1055D000E5F859CE0DC73793E06DCBFAD834793E54
+:1055E00079F459BDDE2BE7DBC12A619C29417D4658
+:1055F0003B4DF8A9BF8C0CE145FC6D784A433AB7A6
+:10560000D7F319E2ADF27B895E791F578FBF6A72BB
+:105610003F801080F11B7949C6BAED9C1C4E879DD6
+:10562000D779A19DBF97A16EF7415EE7F8B400E876
+:1056300067755A787EB57E795EFEED173D9D711FC8
+:10564000E944DD5EFF07F45F26E9BF57D21F97BC30
+:1056500065B4C2CA1CFA6F709BF497F8227EC1FC35
+:1056600089FE4C0FD053A7BF62E047A7FF397A2DC0
+:1056700089ACD7F9E37CFA8724BD757E1AEE94795C
+:1056800013680FFA0FB34A7EA88D91F91E2FC51724
+:105690003E8C7BB208374588CF0F33F8A54A9E1F52
+:1056A000FEDF4AFF3CABBC47CE51E6E47BEA2EC6A8
+:1056B0000F339B4521EEE93CEBD35220278ACF7A6A
+:1056C0000E029E2D4616C23C37EA959CB6EBB5BF3E
+:1056D00034DB001BCFB3D06E406BBDD5F94E1CE45C
+:1056E0009EF11DA3DD95E7B5CB71425F2C1A135ACD
+:1056F0000BFD35B6C6CA716BB24C183E44FA4CE687
+:1057000073FA137CA991F99FDE030BF370BFA83CD9
+:10571000BF255CD2AEF6D05FC8D5C21F8A96A23F25
+:10572000A16EB1C2EF38837C5AFA4E618AD93E1F0E
+:105730001BB5BF7E75F6576C8F5F7D917BAE8F0C6E
+:10574000D1F7DD3345E67FF29ED1E621AC672FED40
+:105750009ED12C51CF7C30BA58E673D1FC2D3988BC
+:10576000DBF84515E0425165051F8C157556E95764
+:10577000FA4F54E4B1D7CEF8B94684F9F9785228F3
+:1057800050263F23F601BC3F6EC274DC1F3C2A77D3
+:10579000540F3C8FB83FCF36B43DDF9FF76777C4D7
+:1057A000FD79FB46CBF5B6F05A196FDAE7ECDEA6C9
+:1057B0001DFA2AE9DB1E3D8117C1E5CBA48F7BD002
+:1057C000BC5F217D0CF8EAAC1A81F70A3DE6BC23E8
+:1057D000E3FD6BDCA384B5DD85F5DD35FD9FEB04D2
+:1057E0003CBF96D47B34E8F55AD2C0D188C7BF9667
+:1057F000D4C1224B879DCB7EBB7BB4353E637DB449
+:10580000F657C8FD19F7058F6E2FEF0B8EC6EBD537
+:105810002264C2EF381DBF3F01AFDEB6F09A82C3EB
+:105820008EED81CF77771979538827F758DAC0F052
+:10583000AD36B90ECA778F2F405EF4C2F7657EC7CA
+:10584000510C057A77F1101EFFF0C583853597F767
+:10585000A302C0779953E2F164E0A5FEB8D73CDC1F
+:105860004E1B89FEBF5AABF279FB93CFC4703CEE5E
+:1058700048F0D904E0D3E0E332D5B3D28B75F89A7F
+:105880002AEF59FA617F17DC437A21BE267EBE7A61
+:10589000685BFCEC227EEE773E3F8B0DF21E83327E
+:1058A00067619B7436FCCEA41C3FCB1FB708DF0298
+:1058B000FEAF10D23FAA70BE2EEFA92418E75EA358
+:1058C000EDAAFC586A4FF576A7CC1736E89DE19013
+:1058D000F75866C40937E22042CBBD0CE3FDB4BBE8
+:1058E000BF187821BF764B64DEDAF0705FDE771E7A
+:1058F0007B48E57CF75762E5BDEF8D440F85ECD31F
+:105900002BFB56B9BA111DE7E66B65785FA83FA877
+:10591000E8F7F59E8A68C7F1F35C17FBD93FD15FC2
+:10592000BF75A8EEAFF717FDFFE1EF29B497F70EAB
+:105930002F7C353788712FAC21AD96C2BF8BC1F754
+:10594000C4D5C23FCF6C953BC3452FFEBD8C5129BA
+:1059500036CE33FFDFF67B0A1942E3F5F79FFD5D94
+:1059600085B1F2D179BFAB9091B0E28096D2FABB0B
+:105970001AD1BFAB90A1DF672D3C527F18BFA73073
+:1059800042F8392F7F4C9A59AF8C728F3CE0E6D2A7
+:105990001CEFC9B8483ED7B34375BD7231BA970BF7
+:1059A0009DEEF25C27F840FF7D9420F8D3F87D143B
+:1059B00083EEC6EFA4D4B697BF93F2CFF6BB28D13F
+:1059C000F489FE9D9468FA44FF6ECA702D96F134F6
+:1059D000AACCC57C6DD0692AFD657B00E77295FF76
+:1059E0007E7A1D8DA2D719B17200EE293D552CE5A6
+:1059F000FA85F4FF06AFFF14E4C58F8827E1BC8B5E
+:105A000053C643FCB55611335CE07E42CE97FD454C
+:105A1000ADBC07AAD62AE30101A22BEEC5FB2EF6E8
+:105A2000EFF23E47B28F6C1D1197A9E2F70376A7FC
+:105A3000BBD60B7A27309F2C5E2CCF031FB6D4F138
+:105A4000EF5DCCCCAE52B07F792C535386B547BCBA
+:105A5000B868FB1C8ECB570D847C9FF1074717D489
+:105A6000CFE82AEF8F14D98D0322ED911919322F27
+:105A70002B66982EC7BD320FCB354CFA09F15E3735
+:105A80009F6B28CE167A7EABE832A31FF8F813B6C8
+:105A9000E35B3CD2AE6EB4C97B2C03AFCA7C9EB52F
+:105AA00055EFB0DDBF91EC5A55DA376BEEE3384372
+:105AB00082C03EEEE331CD49187FEF35C2642FF44A
+:105AC000093A4D79C97D37BB4D70BF509AA9FDE5A4
+:105AD0007B3CA67A5F38CB549F7BC86B8207340C23
+:105AE00032B51FF881DF040F6E1C6B6A3FE44891EA
+:105AF000091E3DAC9B8CFB8327693E3316B983F2AC
+:105B00001E7D1927E96A97F654EDEDD29F30F2D742
+:105B1000357D1D44E7AF77B6CAFC757B95D46B9A8B
+:105B20004BFAB7EE64E156F95C4C03C3B81B82F341
+:105B3000C603E63CF34E4EE95F59464BFFC3AEE762
+:105B400099C766C9732F465E39F9157EE0BB876831
+:105B50009CC6BF77A0DF271ACDCF453ADDA3C7DDAE
+:105B6000D52ECFD3D5DE6EE7FD73CD656F5212CE45
+:105B70001FCFED0325FF6F74B67DEFD38C61328E9E
+:105B800012CA2DBA6E18B57B8CD416DB5FE7F5E729
+:105B90006D84BCABFD959DF3C62FD6DF8CCBE57C29
+:105BA000A65B2C332766B33FC8E7008D7E2BF47EBF
+:105BB000278D50DA9CDF8CC466BE774D24DA3DE039
+:105BC0005FCDB59C6177AC4852DBC07BEBB90C99DB
+:105BD000A77FD3CAD07DBD699CD3ED753679E140EE
+:105BE000D0067E18574076A40FF1D782475D448FC8
+:105BF000C7165B390E76DB8B2FCEC0D5F4E3453369
+:105C0000F3031251B09F08FB53CD691DF7B1E13288
+:105C1000EFFB415C2CCDF6CC0F3CAE163D3ED222C4
+:105C200042E7CE4F04DAE037CD7590CF21B8174A5E
+:105C30007EEA1C71CE0AFEE7FFD47909811D52EA83
+:105C4000C75627E439C78BE0CF38A7E2B9C556B4A9
+:105C5000DE85F32262AC128187FF182EE3FC878673
+:105C6000497AA31DE4D185DA91DD9788FD8516E197
+:105C700049745F24AEFE3F31FF0CAB8C337471CAA4
+:105C8000F3229DAD1ACB0B7B967ECFDD79FCAECB9C
+:105C90000D3D4ED6C92AD77D27AF5CD7E7CB85030C
+:105CA000FC7DBB26EF4D8BC62FFF8988AB18E757CD
+:105CB00062474B3962C88573E7507A4A3FD4A6CB16
+:105CC00087600F0BE71DDC1D6F5EC7DFEBF261AD78
+:105CD000A12F02E4C7E79BE484C0BE5EED3295E5E8
+:105CE00004C9C9831A8DB318F7B2B85B7F1FEEE6FB
+:105CF00007A41E1BEE2F7A10FB26B356DBC43ADE38
+:105D00005790F7C3CED5E3E4C581A8FB59747BFC5B
+:105D1000CC4AC58DDF8D98BDC25C3FD7F5E527F035
+:105D20001F6F8EBEA7C6D8AFBB481CE0E830DD4E63
+:105D3000F70AAF9E7FBF04E33B1394F75E9F3BAF30
+:105D4000A4C77F5A82CF4AF84E21227F47C2B00BA8
+:105D50000CD8837DB2887B5808BFB159D0EF4BADCA
+:105D60006DE6371AF83D97E7A1EFD351B96419FBF7
+:105D70003332BF81E401EFCB9DA07AD8812702A7FF
+:105D8000B9FD891D319C5772D2D7D01FFBB7C63ED3
+:105D90005D0F4DEE63B5EC8897F90D2E8B8437CBF4
+:105DA0007BEC17FC35D81F7E6C63E059D33907AD07
+:105DB000D1BCCF175D6A353BD9DFBC224F4B1E8E5D
+:105DC000BC74ABD7E925F81ED73EBEA76B1CF98F74
+:105DD000906BC84B599622C7CFF22B705AE2AF4A4C
+:105DE000E2EF6764E8417EBE2F487A228E29C8AB75
+:105DF000A5B2383C98FBFFA9FB6093CFFAE4FEEF15
+:105E0000D921FCBEB66230C359C1E6911F50BFD73D
+:105E1000692E0FE248D7D6FE624C2C7DBAF15F5D49
+:105E2000CBB8EC6C3E3F6094BEE1528F34DADAAE10
+:105E30005FAFCB9F3F0C17FA7D3592DF17D628BC9A
+:105E4000AFB6103C0EF83E793FA7019FAED3E131CB
+:105E5000125EB44CC2504DB08367E9BF93B6498F10
+:105E6000BF60FE28317FC405B6E8F119CC1F25E6D6
+:105E70008FE790578021AF00435E0186BC420979CD
+:105E800085E75F248DE27D6DECDB8D8E584FD8B7B2
+:105E90001B1DB13EB06F170963DF2EB23DF6ED2238
+:105EA000EBB16F17598F7DBB4818FB7691EDB16F41
+:105EB00017098B4157B5C2906BFE89267832F903DA
+:105EC000A323D633F6ED22BF8F7D3BD3F7B45B4CD3
+:105ED000EFDF28169BDEC7BE5D64FB998B15D3BE32
+:105EE0009E10CDACD767AF69C77C94E12BAA04BFE5
+:105EF000FF39EEEFB7D9BAB17CE038C6C2F258AF7D
+:105F0000A477DD58497F8B3C1FA134F3EF0B9CBE77
+:105F1000D32EE131E6FC6DA3C4BED7689BDCF7420B
+:105F2000897D2F94D8F742897DAFD13DE5BE174AD0
+:105F3000EC7BE139F6BD5062DF0B25F6BD5062DF28
+:105F40000B25F6BD5062DF0BEF61DF0B25F6BDF0D0
+:105F50001CFB5E28B1EF85E787691C2511720CF6E2
+:105F60007A0F939F497C68F233DD2618F67A647BBA
+:105F7000D8EB91F5B0D723EB61AF47C2B0D723DBA5
+:105F8000C35E8F8443C33CBCDE60B747BE07BB3DE6
+:105F900012EE57177819B1B5F16BBF3E80B2315E82
+:105FA000790CE70D43C3A7CCC47E66638CD22589E8
+:105FB00064BAAD66DACCD1B0C3F5FCC7FEA2D90293
+:105FC000F9A3C199CCE373869C57DAEFFB74AE6FEB
+:105FD00030CEC5E10FD1DDB743F0EFCE18FBEDC6F3
+:105FE000FB5E52DBFC7B517AFB56B8ED76D1FD1B94
+:105FF000ED38B72A621C38D18CBC19DF9DAE1CF875
+:10600000219B2C0AE7996C5A22F3A2A3F9EA0B5DB3
+:106010003E6DB26CDF877330CDC58A17E73E7AD408
+:10602000697CCEACDF7461517DADF3E9FD7802E7A8
+:10603000D5BEA1CB3D63FC467C94E4059F1F1CDAD2
+:10604000DC302A91DA6B8191FC3B38E3ECD26E2094
+:106050003FF40AF8937D038A7F7D049FFF69B8D4DB
+:106060006F5A408EE3C9C727C8F762E57B4F3E9E53
+:10607000C0FD4F58AA709ED9D02DC28F73CA8DFA19
+:10608000F8FB6E09ABE8AF78A9ECCFF86EF1DA2E29
+:10609000769CE736F0552C1A47E33E6991A7E04E0F
+:1060A00059D1CBAAB15DDA61BADB023BE852CF41EC
+:1060B0000DCB4B1A833C44512FF8DED0F1796F9B06
+:1060C000E6CBE8CAC7EFA00AF60DB5C02D16F43B23
+:1060D0008110D00EF16482311F4D13559984DFEB8E
+:1060E000A61633BEB3A60B05F8EE337D9D2585DEDF
+:1060F000EBABBD6481BDD6AFAE914B631EDEA14953
+:106100002AE07136F7188C7FDC1885E547741E0F7E
+:10611000EC038697DA589F1BF6C3C2F873793E7F6B
+:10612000429ECFE94336CEF339BDF40CD717EF8C3E
+:10613000E1BC1E6D8DC272CDB01B8CBC9DB25BDE0E
+:10614000CF077E8E6506372575673D9F3802F93487
+:10615000DDB627E008CE89A53BAFC3D1BDD34B77D1
+:10616000CADFABD5F7778CDF3D15D97ECE0733EC90
+:1061700040A1D6DB23F7718CDF4F23F9C9ED4EEF39
+:10618000B1BBF9F7EBF4DF3B35E23EC56FE41E042B
+:106190005E8B1F95BF7F366BC5AAC2A904CFF13BAA
+:1061A000C3F85DACE87CACF95176E0C57EEFB4CFC6
+:1061B000083DFED36AFF31BF9C795DDA7FC56FEC85
+:1061C000BF56DA2B36CEFB9F5E23E37562BBE0FB46
+:1061D0008FA6D78CB2E01EE9E93BFD5EC5D36A0706
+:1061E000BEA5DB2D93CE66307EDFD5ED946B917F1F
+:1061F0004AF81DD718A3E7ABA57379FD59998F3AD3
+:10620000C925D77BE37382EDE9968043E611D60B6F
+:106210003DBFD5CC773E41FC41F4B9CCAFEC47DA79
+:10622000F278D83DF4BDA9B083DA818F8B97215FD6
+:1062300096DE66BB339A8F2759C353F0FD495E1B28
+:10624000F3D73FE263DCCB714E2E89AA9771CE5F04
+:106250006C90BFE3305593FCDD57E7EF19717AFC82
+:10626000C925E34BE7E2011824626681AD33912F23
+:106270003C03C90B1D795A7EE4EBC567CBFAD97F85
+:10628000D83A73299C990BC425D43BEC7C7FB5E6A6
+:1062900072F2EFD05C284E80F800E4E34DB7FAECE0
+:1062A000B322E463C1C882D5FE0111E71DEF9179E5
+:1062B000500BEFE9D9A1ADF3B646399BF08BF53120
+:1062C00023B1F1369C37AF1921FCA307C9DF99E44C
+:1062D00079E1C44D167E6F52C25B47BCFFE715D90A
+:1062E0008C0F867F35E28599C8872977361682DD3F
+:1062F0002AB3ABC622EFBA550E69FE8C4CC8215F9B
+:1063000018BF1B76A1B8C3D611920ED1F187D9D987
+:10631000523E0BFDBEF04FEFD9BD0DF2DC18FFA7CA
+:1063200017F87D8C8D232CFFADE73CA2CF777CD076
+:10633000477B6804E21A167F13F2E83BAA757AFEDF
+:10634000ACBCD7C3A06F4CDD771CEF28D1EFC327BF
+:1063500079C2FEE42CBFD35B0339922596E3BCD00F
+:106360000C5534F3BEF1797497787C7CDA5FE723BF
+:106370001FF7F15FC5CAF33A3AFEA6DB1B5E7666ED
+:10638000B6E2EFE3C5FF6293F22BDC13FB723754E6
+:10639000C5707E5BC1C8A22D186F5CB697EFC1585F
+:1063A000ED97FCE4EC56F47BC8C1F2952F3D86FBDB
+:1063B000122AEB33F977658AF7F896E39C63C148B4
+:1063C0006D07DE2B76B9F9DE908AA549AC9F66741D
+:1063D000D0CFBF8B66DE8733F0FE861E9FBA7FA4C8
+:1063E000FCFE29DDCF80209C686A77A1389DCCBF58
+:1063F000417E0EE28F9A6B17C709DC77C87B2AECC7
+:10640000E23D197F4C6B3B6E90A1C71BD3BD323E62
+:1064100064E0EFDEAC592CE76C463CF71CFECCE7A1
+:10642000318DD2ED97F6C2AC5B15F6574B56AB7C6F
+:10643000AE7C8C3A8EEF7159B84AF1F0FA7AA03BF3
+:10644000E77B2FBC87AC310FCE97790A3BE4E1BEE6
+:1064500075C50DBB643A681111DF29593398D75BB4
+:106460004990CA36EE3535CA1B57EDEFFC9C0764E0
+:10647000F4F3FE6589DB6F4F8E58EFB3EB14D3FD59
+:106480000A062CF02316ED717F3D29481AC7F41E29
+:106490001E05FB8A6EBFC4C34DB766DAF17B24D3F9
+:1064A000E9CB969C0BF7FFFFBBFC7FC4BFEF53000B
+:1064B000800000001F8B080000000000000BED7D35
+:1064C0000B7854E5B5E8BF67CF2BC94CD879910458
+:1064D00048D80904C2439C109EF5C1CE0B2610601B
+:1064E00092808227840904091EF446D4126C940910
+:1064F00099C41051138D0629EA80C0A16A25564F10
+:106500008516DB017C8B8A20D6B636191E8A6D7DF6
+:10651000A470A8F67C54EF5AEBDF3B99D99904D0CC
+:10652000F6DCDEFBDDF8E1CEBFFFF7FAD77BAD7F0F
+:10653000A7289DBDCA2631D6DD2A48DBD318AB94E7
+:1065400014F3441B63DFE2CF0CC696B5088A6F7C58
+:106550006FB9289D2D75413952B1333699B10A4929
+:106560003627A7E15332C7C2FB65B71F30B178C6E3
+:10657000968F644CC882F6B10EB30DC75F05E30B6E
+:106580008CDD20F90BB0FE86F132AB8B81F6DE2C70
+:106590003383F9DC9BF83CEEA618F31550AE304A75
+:1065A000E6142897453286ED617D3EEC5FE957CCD5
+:1065B000B1361C972D2DB1F1F5C606ADAF425D6F1A
+:1065C000654B8C7945C8FB56930CE5C58C291D415C
+:1065D000FBD39E331481F6B3CC5B9CDA0EEBADF4A7
+:1065E000D8259CB7D2A8981DB82E1C17FA2D6E6B13
+:1065F00037A505F5BF423150BF198A4CCFA2747F31
+:106600008680FBBD35C281EB5D2CB598109E451A86
+:106610009C1FE6705821F93370FC15560E076DBCAF
+:10662000CA363E4FDFF5717857B6559865A8BFD189
+:10663000E84A6D87FE37C23A3DF05CBCF94086807F
+:10664000CFEA088700E7C12477AACBDEDBFF938778
+:10665000AF4FA5FDC3FA11DE76873C3309D6B3BC34
+:10666000051623D393E62DCF66D51D4170BB5E3151
+:106670003296804F033D594BBB621D0CF060FC67A6
+:10668000B8F9480EEEA37E0C631B601F6EDBCF7360
+:10669000709FD29D8C89D361BD9BDEA3FAE5494CE6
+:1066A00012A0DECC5E10B0DE5C097DA0CC3C054AB9
+:1066B00020938FF56D3A63293832B4B701FE789292
+:1066C000195B3755A67917B3C0623602C6D9540C88
+:1066D00073C03A13F93ACB07B1EA9F8581579BBA49
+:1066E000DE1BD4F32E33B097596C6FFDDDEA79973A
+:1066F000213E07F5C7F170DCD55A7DAE3FE3D6F1F8
+:10670000BDEDB579CB62793FA407C4C3D52A1E601D
+:10671000FB35D49E970B44DB8606D8CF9AFB449F6B
+:1067200045C0E7930D83B1FC9CE040B8FF79CD8B69
+:10673000EF5C07CF3F3DB2AD1CF7A7AD63C5D7599E
+:106740004C8E83F3FDFA2A7A56FAA73339BBEF3E13
+:106750000F4F75FF48991C843F0FFD74941BE6FF93
+:10676000F3B36F65209C3F021C1001CEFFF6D327C8
+:106770004D2CBD77FDCB9ADE3355D882E12510BC78
+:106780009A338FD2F92DCFE4FD967BFF5281E7C17A
+:106790006C663923ADEFF957789FE3ED6B1CD4DEBF
+:1067A0006DFB809FFF102689C9173F6FED7CF5E7D1
+:1067B000FEB8C9E54F12F07C5A42E85FBFFFC7D46C
+:1067C00075FB54FABB41C5E31BAA5AA9DFB2A68ADE
+:1067D000274558F7628D7E2B43DF6BE773769389ED
+:1067E000CEE7ECA68CC6242C77F0F3F977B163C220
+:1067F0005A68F7E7D53B6F494EC755FB525D57F0D6
+:10680000F361D9FC7CF0B912CE87C5853D9F3DC1AF
+:10681000E7B3F2097E3ECB9F7DFB0FBF9009FFF8E7
+:10682000FEEEB3F890FF2EEB78EEF80FE0FDE2A657
+:1068300056531AB4FBB59246FBD2FA2FAFCE9258FC
+:1068400034ECAF699B09F9C0AF15392C9E6B7065AC
+:1068500046CE671E37C1D9C6503D13627BDB2F661B
+:106860004A22F211E619C676C6F75DFF9F543A2A0E
+:106870004A779813917F3544B1ED12AEA3E27E368C
+:10688000A16F7BED792A82D3C5329807E9F3548E44
+:106890002315E9A2CC6008A137ED7942A5AFA1513B
+:1068A0001D8B71BD43E398540F20FE71A4926B8041
+:1068B000797FFC03AB54EFC0FE6E19EB2D562679A1
+:1068C00000E4DB0DF244C24FC6AAEF494658062643
+:1068D00023DF1BB93AF0175C1FA253C444FEB4C3B4
+:1068E000BE2D391C4FA0CC06F3F77E7CA6183B8842
+:1068F0004F45D670FC33B3F7A96C06BE8578ABF56F
+:106900001BCA8E08F83E19D682F337672EA3F333DD
+:106910008DE4F4D2DFFEBEBDC4FD9D4A73FB484E3C
+:106920004430697B0CED6F0D967BF697C91403F428
+:106930002FFFD115DB9A61C85375CA4133D49F5AD2
+:1069400067A3FEFFA8FDEAF7B9B8B222649F3D74C1
+:10695000D3027C2D0D9FD9A9B8CEB3569808EA4F23
+:10696000DD1A6140F89F4AE3FA0263017B099CCB80
+:10697000AEF5F0AB85B1DDEBADF47C6A3D20D368BC
+:10698000C69E599F44E567D7CBF4EC589F49EFD397
+:106990007338FE95452AD12897BBEBECD2768487D5
+:1069A0009FD34D67CD088203E8099C1FAB7A41A7AE
+:1069B00014B0C706F169901FF7A1BC633523D84E08
+:1069C00098A2B3E594DD301EF192AF4F6B7FBBA967
+:1069D00085ADC3768F0ABE9D306ED4EDEF1524A22F
+:1069E0009C6E4BCB12A0DF929A73C40F97D806CB44
+:1069F0000CE5B8CDDD3815EB37A7491BA05B545B20
+:106A000056670DF45FE11DEDC0F6B70B7223CD5B49
+:106A10002738705EF851AC53800FE06F505E697B91
+:106A200075A4CA2F0DC82F97DFBFAE3119CA270C26
+:106A3000AC5B04D014198A6762B9684B8CA31EE55D
+:106A40006D3DDF0FDB0A7CD4DACB470BA7B9AECEA6
+:106A50008173661700DF60FCB1B03626E27E3A141F
+:106A60005C3F03BD6327C3F5BACCD8FF972ABFECC0
+:106A70006C3B6197D5F32946BA71779FB807CFD59C
+:106A8000667034CB28DFE5776584FB1B22DB2E2381
+:106A9000FEF0FA35765E0FCF0D0D50BF669BE843D2
+:106AA000781488658303A87F6D16892FAED8563A6F
+:106AB00018F58D155046F9B505A7027C6A6CCBE335
+:106AC000ED5A0B1EF1003F4D15980BF9D16963A0EB
+:106AD00018E1F1E9B6C4D83AD4F76EAE1FC5A0BE2E
+:106AE00072DB3DA9F8FC745BC422E4E3F952717EC9
+:106AF0000CEA3F5B63B244B997CEAA72389DDD744D
+:106B0000735E22CABBD5DF1C7A5C02B9BA0270542C
+:106B10008271CF7744F93CD064F5FABDA922A096E2
+:106B200025DEBD3C07F0EBDF0DFBAF9B8E7258F00E
+:106B3000ED4AA6F672A2148E8E357D0AF058063CF8
+:106B4000BDF9EE0F699CCF0D87E72D86FEAB6F7EFA
+:106B50003E1AC7F9F7878F4D91E0FD0F26B9FF1751
+:106B60008EFF2761DB2E0940C2366F9B80F2A33A6D
+:106B70008771BE1AEBBA6E3187AF63BBDCFF7C5501
+:106B80007B0582A7565EE21B6466A897FA9959C2F4
+:106B9000A7C4480FFE54643528DF35BD447B5FAF82
+:106BA000C2E5D3412DA978FEAB76B5A7A2FCF8A328
+:106BB0009D97DD3B5E5B7127ACC3DD669018E09D61
+:106BC000DBC848EF5DEEE1FA34AB026692DC3BFFD6
+:106BD0007D3951B4FE559BB343E41EC8479AE78FF5
+:106BE00046E6C4750CAFEFCE42FDE9F746FF0A3C1E
+:106BF000D7DF837EEA49C373E2F8F7FB167126BE3E
+:106C0000F7DC2EB00C01CBCFDB47DA480F33105F37
+:106C1000FFA5C9B713DADB2775F891EFDDFC42CC8D
+:106C200044046381383E11F167CD3ED3CCA15C9F13
+:106C30009270F6D546BF39DCB9DDA4EA513DE517BF
+:106C40009E3323DEAF7E06F401A4CF17041FEA377C
+:106C5000AB3B9E7B75088C77CBDE8A6C9C476B7F49
+:106C6000CB0B1C0E112C602E0DD2AB2B32631B876D
+:106C7000028F7CF6C0474B1F862D55E039FD80B151
+:106C80007D333E70D78DC4A744FB64C66ED2C74126
+:106C9000BF32A3FCBFD9CBC7BB39F368633AEDABB6
+:106CA000388E059DFF9E1C13F5D3FAC3BEA95FBDA8
+:106CB000F5EE2702B05EA5DEC822AE85B2917DB4A6
+:106CC0000BE1C7A2A59DB80F233BFD2A3CD78A83C1
+:106CD00058333CB756AFF90F6A5F67914478D6DFF7
+:106CE0005CBB2700F3C9227331E8EFC9ADA6F13CC4
+:106CF000662E7FDAA39E7DF44628D72CB03900BDDE
+:106D0000A11C4DF0D9FF4303F1F964D67DC800CF33
+:106D10004406540400FA539AFB30E237FDC0B86BC6
+:106D20006F937DC88F81830B88E75FBE74261BD766
+:106D30007DEDF0C039C42B53DD19773ED0FFFB3910
+:106D400012D74FC607B2B15DC24195AF198F907C83
+:106D50003425C9B1A8AFF8712C5CDFDF0C8407FBC8
+:106D600005FF9338AF06A7885CAEFF19B2DC7F4001
+:106D7000FEA708A63BFCD07EBE10EDC0FD1E891507
+:106D80003326023D7F69FA280DC7F500DA8A437B76
+:106D9000F5D85C75E9E621D336235C7200A0EC6A75
+:106DA000B065C6C7322394EF65866E0BAC23B7FB84
+:106DB00077DBEAA02C3D38888920AAEA2352592E95
+:106DC0008C2F1C848DC27E0E8E3FB81CD7796FB776
+:106DD00095219C983554CF351B92FD3F427CAE8E59
+:106DE00076B02494431D59C88FD82D364733B45FED
+:106DF000722190F1BF502EFDED30E9E963D2DD5FE5
+:106E0000E17E8688CA0937D4DF2BF9473C80E3D777
+:106E10004439EAB81C61C1EBDFBFEE6FD171D0EF2E
+:106E2000CBEE51C63DD0EE4BC5EA000D9675DE396E
+:106E3000EEE5ABA07CB52A4FF4EBFA324936A2DD81
+:106E4000F165B7D58F7AC89736834F0090E6EE3F4D
+:106E5000F4A100F23BD76AF38BD1D8CFF459B0BC80
+:106E6000614752623E194722867D0BF01CACCAA5D1
+:106E70006B0785DA8F4372B91D342497F31FA3EC97
+:106E800020389FF5185933E2218332CE6BB44ACDB6
+:106E9000B0BE5FD9762D01CA6767BF4E1F8472E30B
+:106EA000ECFE1183D8F8FEF9E231D427404F583A6E
+:106EB0005149CB9DDC2B5F17AA708968B9DE84F03D
+:106EC000A8077834033C16DA0C7E0BEC8B2D088572
+:106ED00003ABE92E47BC61866807D20D9E2F9EBF8B
+:106EE0002C18BAD9557DCF7BC605C9FF23282F8121
+:106EF000F344B8969FFDE48A07189DDB15B9097421
+:106F00008E0D57B2DEF3FB573B2F667434E139AC7C
+:106F100015ED2D780EF546AEEF7900B776C650B771
+:106F20005D782E6BEB47D2390DAE073E81764A9DD8
+:106F3000916D8F47BE7294DAEF54F54196594D7CAE
+:106F4000A6BCDE2221FCBE8A8CA6FE0CCED5342443
+:106F50001C9FE17CA5A692115F593ABE5AC0734F9F
+:106F6000C219603F9D86801DF71988002D129EEB87
+:106F700072D389CE87224718C1CF19FB3FB6CEBE48
+:106F80001DF98D681DFAD8691045ACA93B7A2CAC67
+:106F9000AB4D601DB42F93CA3F56D9489F6B8BF100
+:106FA000117F6B5B38CC817BFD92A9F55591C45F55
+:106FB000AE3218A8DCBD7830D9636D31C05A71BCCF
+:106FC000C563496FF8F93722B7D73218AFCF62A33C
+:106FD00036637D71268DF74B8D5FDD67A7F1DA8A09
+:106FE00095E448AA1F6CC0FE4BD3DCB7217E0C1180
+:106FF000793B503CA8DD962D4A329EE7961233B578
+:107000007B44702D5E81E35C6123BD31B038F2D9E1
+:107010005DFC38FDE85FEAACE1FBD6E860DD54CE0C
+:107020004F877B4E3C8AFCC3930B27624379F1C5A3
+:1070300012C46B458C76000AF739E7AF7AF09C757D
+:107040000370597C6427D9EB72064360C3F9492C5D
+:1070500017F1E410C013DA7B4C70CEF1FC9C37C4FE
+:10706000E339CFDB167CCE309E672DBC17D6443B70
+:10707000846974CE99387E0D8B74A07DDD737EBFDC
+:10708000F265E1533438922C008BBDE9EE8755FA56
+:1070900025F83EF607D81FC0A5DC1298DC82FAB9A5
+:1070A00081557584E1034FE472FB4062DD2694AFA5
+:1070B0004B35FCAFD5E17F6058CC27512AFE43BF4A
+:1070C00017135DDBF01C3E178E4DC19787FF2E2EE8
+:1070D0000A37FE4F54F9F266BC6B37B61F693C386D
+:1070E000EC36D437D65948FF65170E0DC379D7A6AD
+:1070F000B99EC6FA8891DD66F44F7526779B707F3E
+:107100009D8BFF94827AD6D29AD7883E2F757D1BAD
+:10711000A22698506EC638B34C01E89FE8CC7A0599
+:10712000CFE5E85C8B6C09E3073930776A0AEA43FC
+:10713000C70AA7A620BF3C9602244FF2D461473E5F
+:107140006ADA7B851DD779CC994D6599C96AB9747E
+:1071500040FEFA67E0AF7E5004FE08F61A3ECF808C
+:10716000BDE6077EFB31D86BF83C05F61ABE3F0141
+:10717000F61A3EBBD63BE8FD31E788BD8817E75BD2
+:10718000B81F65B9D111562F5BFD8CC8FC1A7F83DF
+:107190007F37ED880A29576D8D0B29DFD8061864D3
+:1071A000ED2D576E1A1152D6F4CF65DE7121EFDD49
+:1071B000B5D921E5FF67E0DBC4E18BFEF27F25F85E
+:1071C000E2CF269077A5F80BE0F7DB9367111F3D20
+:1071D00026B0EA3878C6489CFF195D02F9DDF0A7B1
+:1071E00005E47609FE027463B4C90D58EF85F60F05
+:1071F000425BB47DD1FE60CC61AA80F70B9D111279
+:10720000CAF3EB5835D1D922D642CF1B58073DCB14
+:10721000D8117A96334E875F5604A6E0F3837877C9
+:107220005A1EAC7FB5D5FD443CDA6D29EED171C84C
+:107230008F6CB16497F6774EA8613355CFB54D5139
+:10724000F7053F0B70EDD0EF68D4843BEE907BE701
+:10725000D1C687F9AECC433E63E2F3BC3D796A0AFE
+:10726000F207E64A08B1A7FA9BAF559593154E0E63
+:1072700027F4D962F9F442C1B701CA075A2D66F45E
+:107280002F9CDE6852F5F5BBC9CE3D719CFB654E67
+:1072900037CC4A45FCAB6B1D9D8A787EDA2437D407
+:1072A00000FC4F4F07FEED203F8E03E5C349A79D2D
+:1072B000FA83A488CE82735BAEEEEFA4EC30AF838A
+:1072C000F60B9345E681F66E4F5A34AE5FDBB77E20
+:1072D000DDCB365942F060FEB4D0F24266EEC5B75F
+:1072E000343C6F736F3DEA4962D920F7007677CD61
+:1072F00047ABDE7D39085F6FC8B3C723DF6453D95E
+:10730000D46FC5DEFEFDC1F7ABF555EFBE6CEA8567
+:10731000AF865793F25CCBF19CE0B519E916E062B9
+:1073200040797C6C2F87636BD4B5F75D0570287945
+:107330005F641CCEE59EDF233EEFE37E7DFD3C01D6
+:10734000A4EBD148AF9CAE2BBCEF91FDB6B4B6D840
+:1073500084EB2BB175A7A0DFE9C05DA353F05C8E71
+:10736000CE1D9D827CE350E1E8C76E8771BB8A44E5
+:107370008705F0E940D1B9FBB07CAC569470DEAE25
+:10738000BDE754FED2FDF65458DF174E13C9A1AE27
+:10739000BDFF1C3E53B20FF80CCC7FDEC7F9CC4AC0
+:1073A000A38B35C2BC2B012E68C7FFB3F9CDC5F83E
+:1073B000CC5193AB2001E1552738D0FF56576821B7
+:1073C000FDE128D08785E353C3EDC827A781FD2BB6
+:1073D00021BEB926A34D796CEF88048417F32847A2
+:1073E00033A7F4E2FBF2DA9545E85F679B4C27513F
+:1073F000EF466708CAE712663C1908C253F70BA6A6
+:10740000DE32E1B5F1642008AFF578BA4787A7E727
+:10741000D98554733AAF3F32B897EFE14F307FB917
+:1074200045F437B2B45EBCFD6BE17BE5A824005F98
+:10743000F905E2EB0F27A6BD141082F8CA25F2B1B8
+:10744000D6A86F48EEB5477D4372EF7821977B074A
+:107450000AAF3FF83BC4FBBB38DE1F5B3895F0F248
+:107460009809E419C0EB686D7634964F6D2A253A79
+:10747000D3E8473F4F978AFF5ABBA5C66E93230CAC
+:107480007EBA6BC590F3CC7861C920F407F4B77E5F
+:107490006D5CAD9D36EE525D5C573FEE27795C4FDB
+:1074A000CCD85136E0F86000F6F6437EC2227BF17C
+:1074B00055443DE07AE601F87439397CBA8AAE2742
+:1074C0007A3CEED4E8D2CD301E7B7481E843FDB522
+:1074D000CB798EE8F43CD0298DD1CFBC9FAAF4F9AA
+:1074E000894A9FA755FAD4EAC59D0F5F77038E5B43
+:1074F0002B129F3EBA203B01E7FBE38E0C9A17D676
+:10750000034605E8212FFFBD024C34E40F76E45F0B
+:10751000C7010E6827942E2C257BBAD4E44808A70F
+:1075200027E8F7AD1FEFC05C8B81F1F188DF95DCB8
+:1075300055CA1A912F001C103F8F637BA82FD9C901
+:10754000FDC087B07D7C309C4693BE727CB7E04026
+:10755000D161DAFB773B9EC32A5F28BF58B9392A2D
+:10756000E4DC56B4C485944B0AF93E8ED78EA0FD58
+:107570005FEEF969FD2FF5FC6F52FBE39ABF253DE5
+:107580002536643C0452E87CE9BAFAB1BAFA89219A
+:10759000E58BE1E309152F34397222425E122EBECB
+:1075A000D435CF52159CA7313B9FFB5B66E773FF39
+:1075B000CBE5CAD582FCF072B5BFFE1A7F1A95E7FB
+:1075C0002ACA4739EA2F35E1BE2E951F05C9E105C4
+:1075D000D43F2098B17FAB2A67AB3A38DEB547DDA0
+:1075E000FF2AE2D5E7AA9E0E7849FCFE0B95DF7FC5
+:1075F000F19F6AF9A702E1E5A17D6BA3516F3FB34B
+:10760000777434DA61273BEAA391EFCBCC13FD0307
+:10761000C0C7CF5C203F61BA4F3B06969F7F54F9AD
+:10762000CE193C07929B129DC729557E9E40F94971
+:10763000F23E939E47517E42FD82E7543D7DB74026
+:10764000F4BFCAD812DE3FBD23945F556D8DD2C9F9
+:10765000C950B959B96968487999774448D95D1BC7
+:107660002A370BC432E2EB677C1C8EA5CEEC90F679
+:107670006764395A22F870387C6192A311CF4EFAB0
+:10768000E2A283E945E3BF477570388D7040FCF492
+:10769000960E8827A7D4FE5A19EC4213CE5B6A7562
+:1076A000BC128F7E844D8203E3540C78CE3438C7ED
+:1076B000230BB29E6C0ED233A40291F0F984F750E2
+:1076C0007932F21F30C0D0CFFB5AEDA154F4AF563F
+:1076D0003C13457A937EDECAA2503EF3594371EEC5
+:1076E000EFA15FE9FBA2CF8AF0288A21FEB5E0393D
+:1076F000D12742B9AB362F3A781F67543AD4E4CE3B
+:107700004A6375D873ACDA1A7A8EA5457534CEB152
+:1077100087850E61103C0F4C0749DAB75FA991EFDE
+:107720007FE53322F977577AFFF236C61557821E66
+:10773000886AC26B4DF5F310AF4FB84C06E2A71D37
+:1077400071F3103E9E05A22303DA1F6E1A41787E64
+:10775000B2296F30CEF772BE48747566AFC5205C33
+:10776000094F9789F9C95EF5D3797EE62D25B97160
+:1077700006E1827A905122BA78379FFB914EC03849
+:10778000586F003A417DB8CB273A7D61E8E3DD7C54
+:107790007E1EA72E3C40F8F3AAEF5034EA15273A94
+:1077A000F8F8A76AA5688C4FBDE5CDB6D3FA8A6014
+:1077B0005CD47BF75D4F72F28C97E323AE93ECC3FE
+:1077C000262E3F8E7997DF3F1DE0F1F92691F4CE0A
+:1077D000CF9B4AE74DC7F3DE64A2725EF1428A6F27
+:1077E0001CF371F972DC77AA1CCFEF8C174E1FCAFD
+:1077F00075FBA6BE3D291ECFD944F850F94CE8B917
+:107800002CDC144A5FF0139D057A5725FE26E3FF12
+:10781000949968272D4B02F909947BA2A8D484FE81
+:10782000C9124FA83CB2B06213E21DEA97D86ED9D4
+:1078300063A593FD487F1E81E4E5D217009F603D5C
+:10784000A61D5793BCAB68B184CC5B521B6A1F2D3D
+:10785000D3D9437A7BE9B2E585A9BA3C9CBC1854DC
+:10786000A0CA0526CD44B89F04C3BA390BE0F982FB
+:10787000A860F9BC3782F867C5D2B3D7A87AE9B552
+:107880008807CCE161D3343B3D88CE9679459D9EF7
+:107890001E0A5FD09F3F41FDB8294E95A39E52F22C
+:1078A000D78DCA53620A701D976A7F5FB27E5BAE46
+:1078B000EAB7E5A4DF1E5B08F202F673149B04F539
+:1078C0003FB0F07AF2EB1C9F7B3DE9B9C77BFC3AF5
+:1078D0002ED5AF730D9DDBF122C067921B0EAD3C20
+:1078E000A01EA1F18B8FD57338A5F2C9132A9FEC86
+:1078F00052EDAD46555E78557971BC48B5B7E21981
+:10790000C90BA3516197C2676E6C8BD2C987389D32
+:107910001D3554773EA1F262B7CB3DB300E0664916
+:107920001A1BF2DE244D0C2967ECD84FFEE3F3322C
+:10793000CF27BA077102E3250B797E16B37690FF45
+:1079400078A143A6FAA1182784F66852611E898699
+:107950009FDA7B299EBFD7CAB1B0EB3A6C97D6416C
+:10796000E5FA858C611ECC486D1C00471DE8094373
+:10797000D18F0DF324818186ED357C1FB6A095DA79
+:10798000E5563149807655056984E7494C21FE3238
+:1079900078355330DF85F99EA7764FDE0DFB00BCAE
+:1079A0000FD4CF20BBBCD41ACDE3DD201F07C6B354
+:1079B0003A4E3FCE38D25B8619396AF68BB76ABB2E
+:1079C0008BE16D901E7407D10533903FA2356A821A
+:1079D00009F1B4C4E622BF01E0F5923BD05FF99211
+:1079E00099FB091672FFE4D1C2A98FA1BD3B618F3B
+:1079F0008D7CC94757003E137FEFE676426DA9079D
+:107A0000E5DE074E2EE7C6EDF9CC80F96E5D7B9979
+:107A100003CB876A9F3FFB26D2CB0281EC8C63B5F8
+:107A2000799C2F33E6C2FCCD63CEBC0D549E0686F6
+:107A30007116D283B2C188EB00B83653FDF2FB2633
+:107A4000A3BE735824FC4D52F38C243CD7E4DE7261
+:107A5000BCA296D95E2A2715F1FCC05FA8FA41871F
+:107A60007A9E3F51EDA05D2ADDB4A974F3A04A3798
+:107A70001BF5FED0AD9C6E46191DF745417994C7A4
+:107A80004E72E6DDA253B46EA07F09E3B969856248
+:107A9000F32480DB384B80F8742988BD0DB09F9C9F
+:107AA000A23ACA5F2C75338A57942CA8A3F50530E7
+:107AB000B67415EA4D7582A8D6237F1C17E7A7F682
+:107AC00025562661FF52E77307300F77A11B40034D
+:107AD000E5FC057502C1A702C683F6076A1FA2F17D
+:107AE0008E57F1751CB5F3FEC72A98E481720673B0
+:107AF0001EBC9DAFD385F1D0E3B5CF1F20782FE01A
+:107B0000F0BEEA5343083D66F92343E87AEC8ED889
+:107B100090FAD19B878494135CE921EDE39CA1F456
+:107B20001E39726248FD3167A901E5ECF9055A7EFC
+:107B30000FF78B69765DCE1E9B01E171DD5C51F321
+:107B4000E31AD860B4BA18F97D9B543D91B58C60A6
+:107B500098BFF1E49D06CA0FD8B8A0DE8A790FE776
+:107B60003B8C745E302EF191E3FB8D34AE35CD2B22
+:107B7000A01FF35E80B318A4FF3569F24DF5ABE3A7
+:107B80007A8C41EB899519668CF5B46F53F1E92134
+:107B9000751DC0B7734C38AF8BE3495C113398A0A7
+:107BA0007FC2022EA7F574D9A1F6FF89DA7F978AE2
+:107BB0008F5DCE273744225C1631D2470AC4D51BCD
+:107BC00022701D458CE8B1C37F3032587FFC457F61
+:107BD000E32CC82EA0713C9C8F8E9D2FD447E0B91A
+:107BE0006E0DFCE91D78FEF2F3C60DD1B0DEA704E0
+:107BF000D68114A5F14F4DFFBEEA8B26AA1F3B117B
+:107C00004C34A8FFE517CDBCFD1426A3BFEB17AA83
+:107C1000DC6952E92763C778F22F9EDF6C26BB67C9
+:107C2000D7BC95DBDB60BDA3E7DCF5D40B882FF375
+:107C3000EEFADD0B72AF9E5F3A2FB913F3F747AD43
+:107C4000B733E40FDABC193B3ECBA5754B468678BB
+:107C5000FAF4CE9F2FC3F17EB22BD2A0C0F84F6FA3
+:107C600037127F1973EF63DB37B3BEFE985267A8F4
+:107C70009DFF938DED4FEDC5F735CF3F713A284FFE
+:107C8000E7D8DC7B52D06F7A747D555B7E46FFFC73
+:107C9000B3D4CCDC18BF73FEF2B39FBD05F3FFC6AF
+:107CA0003D6662B01D306A26F7FF1C5D5FD3960FFC
+:107CB00076EA5891E72930A36703C263EC8B8365AA
+:107CC000D4DF80148C6E80A57376844181FDFDC65F
+:107CD00067DC467C60F6C60C3CCFDCA78B0E7E8A48
+:107CE000E77C5CC5F77EF491A3EA39F5944D32C187
+:107CF000DDF39295DB378A9C42F6B1434E2909D2D7
+:107D0000E78EDEA5C5971C7F403E5E521645716525
+:107D10002DEE223AFFD2807C7EE9B4EAC912AD3F53
+:107D2000348E3F04E1978D715E1EAFF7788C8CF234
+:107D300082606B48276BC5B1946FF2E1AA1F52BCF9
+:107D4000DE53679132E2296EB007CB35C0772C93B2
+:107D5000288EEB43A1BD7826F7239C5B54FF9859EE
+:107D6000EE1FFEDE8B9C8F493D1FFDFBC533B91E08
+:107D70005A8FE79211722E07DD93C29C4BB495F097
+:107D80004B3B1731BA89CE85596D9998F791C851F7
+:107D90000AF7F336CAA1CEE3DC5FF69BB2DBEAD684
+:107DA00042F9EC85410CE9428BAB9427F1FC033A94
+:107DB00012E05B26B57FA2AA77231F43BDBB5C8D73
+:107DC000BB742E611477D1C63B5F3348E2E3DD42DA
+:107DD0007A737935D03FCA92A85F917ED13082E71D
+:107DE0004794DBBA9750BEAA607060DC3C51A7D7BD
+:107DF0007B5835AD37F17D91FCF986A84DD43F1104
+:107E0000C02366612B330181DAA36007A315F34910
+:107E100086E00B3948CF52F375136B5EE4FA511EBE
+:107E2000F44C0E994FF896D65FFFB1887CA0C6221D
+:107E300023DFC3DC2CE4DB04BF34C4A376EA2FDDEC
+:107E4000C424BCC7C11426C74FE17E309C4FBF7EFF
+:107E5000188FEB85A09FE17E855A3EFFD639FC1E28
+:107E600008DBCFE460BB8505AF67444859F59385CF
+:107E7000964D49E61039F59B0BA583AA07F0D7E884
+:107E8000FB1B64D7C07EDFAA20BB2BBDB7BD9627E6
+:107E9000A6C179488DE58410DD7FBFDD2EE5E99927
+:107EA00080CF36E6CA7D13E0E17E5F247967883AA9
+:107EB0004CF0084470F8F4E8B38BB8BE0BDA791DC7
+:107EC000E55B83BCC3F3C33CED5180EFCC139A2731
+:107ED000A0CDABC5973A557E1C480B2C718581C748
+:107EE000C1993C7FA16BFD9714EF2E47FD167039A9
+:107EF000B0E1CF21F73F4616E71C9C497EB7D03C46
+:107F0000044D2F45394BF8EBE172B6D3934D7CE726
+:107F10003CB3B790FEAFE7374646791F6BC548477D
+:107F200033F9EDEEA6BC911A8F45B2C073AE23D4DF
+:107F30001F337F5AA83C2856E274F222D4DFB5D012
+:107F4000151A271AD9B68EF8D779D49B88DFF1F5A0
+:107F500018D5BC3213DE2F11D15EF7D0F3B0CA9F13
+:107F6000DF51F5CC08E4AFF03E0A13CB011FED2C36
+:107F700040E54188F22330A55DA67CC738A650397C
+:107F800081B9A9ACE54126331F3DB5FC961416A076
+:107F9000F270D487442429999E23D00E19817A9EA9
+:107FA000A327DE4379937969142F2866CA1FB05D31
+:107FB00051F6E724F78AAE67944F0A9C64B9827938
+:107FC000250BB5322C14CB054C45CE7A5E5FA895B7
+:107FD000BDCB15E8DF99C3DB1B5FDBF8A4C746FC0C
+:107FE0004BADBF87D7F7941B97E760D964A0B2A4C5
+:107FF000B62FCE574CB3009F936731C2835FE729FA
+:1080000096E0B23B4F89082EAF2950A26625F49620
+:108010009FCF55ECC1E5AE5C655070FBA1054A0CE5
+:108020002FF33CD7F74D4A0ADABBF0B35B98C2F1A5
+:10803000107F5E35B993711CE51981E06501BEDDE5
+:108040004C7CDBC5904E816CAC9847047CC67C07A9
+:10805000D4B38966CAF73344D95207F247EAE92B09
+:1080600060627BD14F576C748FC675E9F99EE079D9
+:10807000ED6F98C703F4908B7A7E408D87046AB9C0
+:108080003F40A313EDBD7EBE8BE13D5382FCBCE9B6
+:10809000BDE3F6B77E3D1E1F51F5BDA3AABEF7BED8
+:1080A000EA97EED96FC018F389B597BEFBE79F46F4
+:1080B000F64910FFECBBDF534B4C5C7E48282F3A4F
+:1080C00023D8A270F72AFB5B5F54DE4CD72CCAA7DB
+:1080D0001826519C81697C9FF39B4EFC15F8E0B8F3
+:1080E000419AFDEAB0221C3258D2EC4C98B7D5C95F
+:1080F000487FADCF3F5882FCE77C19483058D7A95C
+:10810000DB4F23C531610FB7275A5218ADD79E26D2
+:1081100045A0BED4A0F24D0B8B291C89EB1F662411
+:1081200079AB5F7743B44FC0B8E2107F04F76FC4F8
+:10813000335F048C33C4E97052DE8A47949C582E16
+:1081400063F332A1BCAC4D949D30CEA1B65256091A
+:10815000E3564E033E4719E93C9F2256C5E371168C
+:1081600046F916ED09368A577B378E3EB002F9661E
+:10817000B2C832A0FDF886894EF47BD6DB62632953
+:10818000E6A4AEA7DEE6781DEF61782403BF4722A0
+:108190002956CC43DF76BBD189FC3CE5B949D16295
+:1081A00010FC4F79CF46607EFB139281EA9FA8CDE9
+:1081B000B5DE68C37B847E85F20CA4938A0DE6DD70
+:1081C000026D1261BCFBAB4EB68C62FDE343B4D3CF
+:1081D0001C82A7510EB3CE0F1AEAB734E9F4830715
+:1081E00066A9F1A4296C0A9EF3954F5D30A19EBB50
+:1081F000D426931F3DB749A0FC94C001472A9ED3C3
+:10820000A9FB4693DFDCDB24AA7E6B07F9AD0329CB
+:108210002C15EFD754B408A4178BDEBFD461BFE18F
+:108220009972328E337C527772B0BFEC89BB7E1864
+:10823000817CD45B6650FDDC8CC69165C59A06FBDB
+:10824000FFD82BF0FC099324E03D66FBC36204AE2B
+:10825000ABCBC4FD14CDC04FF17E6E734EC980749C
+:1082600068FA1AD61964B734C4A747E2BCBDF8ABA4
+:10827000907FFD744B36C547B637E5523E887E9CED
+:108280007BD7B30EB44F1AD65BE9D9A73ED595EA92
+:1082900080FE1FB7E6348290621F1F589584F783D3
+:1082A00056B4585844183C3EDD3A95E65B81F79841
+:1082B00071DE966233F2FD596D396684DBBDEB9554
+:1082C000E782E7692E76BF827C2FAAE539C2131BAD
+:1082D000F37B109EBFBE464945FDE274060B9B270B
+:1082E000F9EE2CAE67BC758D8BEE937C9C12BEDDD7
+:1082F000B1595CDF9F8DC43219F3D6D83B2B01CE28
+:1083000015404F75F0EA54537634E2AD89AD262618
+:10831000F59BB2520FDA73E7506F077EDE78D775A0
+:108320009B2BA15DC3DDA3DE45F67CA599EBCDECCF
+:108330000391E802F4C20AA4CFFF5A6095EA83F8D9
+:108340002FEA8F4A487E1A971BA626D16F067E6EAB
+:10835000DAFFC9DFD1DE41BC5582F0987EA6A8764F
+:10836000819AAF913485B471FA69987D9DCFCF30F1
+:10837000EEB2DC8AE7A9D7D3FBE0499F75048D8F65
+:108380007A6E3E532282D6012CC14FFE72379FB7C0
+:10839000A79D5A6F0406F36D90FEAEAFD7F6317A03
+:1083A000B38E5E9DDCAE03F80E18AF1BE30BED97AA
+:1083B000E16474CE6345E5E0272867DB45CAAB1E60
+:1083C000D7CEE3FFE78731F213F5379EC67FF1C7BB
+:1083D00038588523C0B531BE84CEB3BF7E66DF1169
+:1083E000256D42AF7D382629745D5ABB8C9E7DDD9C
+:1083F000C622B93ED881F699C5077C6F023E8F2808
+:1084000028BF33B7DD2E0DB46F3D3FC31F19D6BB58
+:10841000423D3219700DF9C3C79B05550F614923C1
+:10842000A7D0D545923FD85F09E27FC05778DE9E3E
+:108430004F20F834B79EDA7E2FF961EC0EDE8A9F6A
+:10844000D704A6C9419E07A4DD1364189A1ADC1B41
+:108450009FD2E0F8E9EE0DCF3E05AFCE3CB3E60B80
+:108460007C5A129645233CEF895F706D32B49B6055
+:10847000F625213F5DE9B3F4C13BAB862F69783F18
+:108480002FB4DE9214B47EF8D7BCEFA9CDCB504EFA
+:10849000EDB33A30351CF1CB13029F407A31D05303
+:1084A000D75DFF41F7F323A5B34B28BFBDD642F7F5
+:1084B000BAF4F07D729641CBA7A4FB1A1A3D45B4DD
+:1084C0008C66E85F3CA9DA4D2737819D0AE5C65ADC
+:1084D000B38CDF35E872142B4961C633D79A4FE06D
+:1084E000B9B2603B31BD779FDAF85D1EEE876C84D0
+:1084F000F18530FEBE8B8DF7AD4B59E904FCB21609
+:10850000BB56E1F3D4A6E5B4DF9ABDB55D6F429BDF
+:1085100086C1EE9B9D09B8EE11530474441A65BAE6
+:10852000EFE7F5FE8CE449CB347807F67C4B8731D6
+:1085300002F50F8FD740F1DB968EF8C89128A76C13
+:1085400086B071D6279C1C5EBDF2C4151DAC0F35DC
+:10855000E7737D48D853767F3AC0CB7B9CE7296A86
+:10856000FA87A4E2CD388B44FC59F2F23CB75E7D29
+:1085700088EBD5E751AF467D6972A5142C9F1AA2EE
+:10858000F977302AF31D1EBC87996763243F86E381
+:108590006505F45BD8986F561A7E27C3C1303F3704
+:1085A00016F41F19303BB18DEB3B91369B43413C98
+:1085B00056385D59E13F846764A6C2701EA34EBF62
+:1085C00030EBF40751577ED409FAC438D6A34FC80C
+:1085D000CC118D70B6DF37701E87E6CF05BD89EEF2
+:1085E000997918C01FF1D4EAA1F389064382E859AA
+:1085F00051E4F8C1BD7A3FDE67E3FE1589E24582AA
+:10860000D2487EFBADD9DCBF91CC78DC6B88C2ED63
+:10861000F909D33C5406FB81E250EC572C12F9F2D5
+:108620006E97FB39C48F34600368FFC58E67029173
+:10863000FB77D4CB59CDA5C5957E7C90FBFFBC863E
+:1086400048C7F63078FFCE1C2E97230FC1DE50BFEF
+:10865000BDDE4AF75B0AC4679A089F2619C8AFEDCA
+:108660006547248AE7AB7C36A6D8F5A693E2B2AE7E
+:1086700034847F92112C2A5076CDAA1F37E58EF4D0
+:108680004814F51F26FF9CE0E101D865C0BF6D3599
+:10869000F1B199F0FEF19A0D04573981FBC9B47B11
+:1086A000E77112BFDFDFEC3AEBC1FBBD1D73F8FDD4
+:1086B0009FC862E3EC74280FAF0D084877F7D89590
+:1086C00045A89734C93FA3F348CB920DE82F1B6A06
+:1086D00064AF5B2632F66C0CAF474189F58FD80743
+:1086E0006F0BCE27D9A1EEFB1121BCBEB2760ED7FF
+:1086F0006B3AF7012007A17DCC54FBFBA94AB2B726
+:108700007BCA0037E8FF8087DBCFDDCEA72A3D2379
+:10871000C92EE2F59EDFF2F6182F85FAA237D6545D
+:108720007AA0FDE369E1E7CD2CE2F07DFC8DEEC798
+:10873000308EF5D73A1EC7EAFF9CFDCC00BC658B96
+:108740009DA5B22B81CFAD322F0AF71D9975459C9F
+:108750008F74DA3A085E0CE479F455748F5EAFAF2B
+:108760005A918ECE49DBEBA6CA9C8F4C9E4257FB9A
+:1087700039EEE9C6BDB8DEEA4842FDB37E5577035F
+:10878000F28FFA03AB3EC47BE9E56566D25BCB8D25
+:10879000D5BF453BC87898E7BFE03726100F860065
+:1087A0003FC2FBA6B3AAF8F92D95B8BF56D8F391EE
+:1087B0002B0FFDB1C946C24B4D8F1D67513CE89749
+:1087C000DDA2E6B73371581DDEF7320E15C9EF1B77
+:1087D000550B7A2DEE2F9FE7EB2AF01FF2214DCF9C
+:1087E000B58D3786E4F59A7579BD465D1EF0D8C221
+:1087F000503E649F3C69407DEA576007E33AF703C7
+:108800001FC2A71FEC617C1E047B1D9F2F83BD8EA2
+:108810007EF057D767D2F3F5F50E7AFFE6FA69F4E2
+:108820009C911A30213E933F9AFC36CC2F905F4F9B
+:10883000C3B36D2373A1EED91C5EBF68F6C8FFF009
+:108840005C0DF5F16A7BCF3784873D65367645EE62
+:1088500078F28353F9D5C2CC15E4275AA0E4170265
+:108860009E24185C15F89D0776A785E216FAFDBCD4
+:1088700057A8E59184B7E3197EC220D48F535238AC
+:10888000B97F3FCE23025FC7DAB7D6EC40FA18545F
+:108890006C74211EA7A687C60F9E2FE47429CCE610
+:1088A000CFD437DDC307BAAFAFD1477FF5F5FB00B3
+:1088B0000506F55FEFB5B36BB1BE3E263C5D95A8EE
+:1088C00074D5EFF8366E4FB2D9406F43B1ACB70FE5
+:1088D00003945F72AE26CF4FE4F6BDE9AD3B05E9E8
+:1088E000AD2BC657877662D781559BF13B2122D2AB
+:1088F0001B9205D21BC63F347AABE1E7B114E90DF8
+:108900007E9D55FB9E2B0FE93189D397B067FF1AE7
+:10891000CAC7B88BE7D168F416A3E6CB47491D64F4
+:108920002FD28739B01FD0DE1601EFF17CF211256E
+:108930007F88450E7738BABB4C7ADBFC3DE9EDD732
+:10894000D704287FA2334D49427DC66BE27EABCB74
+:10895000A5C3ACD966FEFD8C2B7CC938CE16759CA0
+:1089600059C34E90FFAFC8EA10519E39650ED782A9
+:1089700049D9F4BDA18F0A79BF6FE62B1D445FD79B
+:108980007D4A7EDE0403A7DFF7DED8417221A5E130
+:1089900068F12CC4977522E9DBFA7DC5CD53E366F7
+:1089A000029F1734AFE4E038E221952EE575C73811
+:1089B0009F8F615206AC27C9239538312E74B5813B
+:1089C000BE2732A8F8680CCA676D3C38B824CC378B
+:1089D00041D5D73AB12F3DC24F876970083D1F2E50
+:1089E0001CC02F7B31FE51A8D2311E3DF971D57BC1
+:1089F0009297EBB7EDD78F784578BFA44F95AFF539
+:108A0000269EFF01AD25FC2EC0CB2EF79942F2FB2E
+:108A1000EAF4BFFD92DF8DFB58134D7EE52423D78A
+:108A2000F792649EB732947908CE5AFC4DD31765FD
+:108A300085E717DD50ECFE0BC2691B930FA03CB31A
+:108A400039D8228AAF813C43BCD8ED52CED2BCDFAC
+:108A5000510FCC2C56FE7B207C2ABE4EF906C7EF68
+:108A6000AF3EA7F8BF0E7D8BF45FC6FDA54BCBAA2A
+:108A700029376B08D849B8DE996A7E46FD305EAF6B
+:108A8000F957BD095AFC549987F993D12ABCC659A4
+:108A90005CAC02FA77A11CC6FB7B87037EBC176C1B
+:108AA000C17B6412FA5119F58FA9117C32F6173F78
+:108AB0007B05E345A63CFA9C0863D3B83DA0DDBF27
+:108AC00091F22FCFDF98325BF5374E6493103EA9B9
+:108AD00006F9A1E9F03EFBD18263783C931F5B115C
+:108AE00087E272EAB68652FCDED6AA9D1F6F437FEC
+:108AF000E8F4DF5A189E07E88F7E63D87CAE7F9833
+:108B00001C21BA2A29FACF4A8F11F951783CED2A53
+:108B100052F54FC4D3F8103CBD7A76783C25FDE77A
+:108B20007BE0E9CCD9A1785AA4C3D359B313BE17BB
+:108B30009ECEC775FF37C6A9609CB30B95E2D903DB
+:108B4000E065F64265E140F541F101B2FB46B169ED
+:108B5000D6E0EF1E6ACF56949703E427C46E3C49D3
+:108B6000F971F535E7284FB9CB76F26DB483FEABDA
+:108B7000C62207FBB3407F0FD1D75B40AE78C09EC3
+:108B8000FCA088E7411F5A67F1CF40BDB696DF478A
+:108B900028AFDD2660BEF790AA6AC10DFC2D5101F9
+:108BA000D311FAC728865EFF09FCBBD27484F4D9BE
+:108BB0007690C71E625FFC5E9A26FFC759AADF4007
+:108BC0003BB5FEEF46C7063C67261D407E5408F4C1
+:108BD00084F1CD6BBA41BE058DF7C6BE69E4579BE3
+:108BE000F135C8BF203F4E0E8C185CCEB32687F4FB
+:108BF0002B90D242EA67258D09A9D7E8BE33468D6E
+:108C0000AB4CDE918FF82356F03C8542392BA47D86
+:108C10007B592E7D0FE0CAE9FCFEDD9CCCE921E307
+:108C2000EBF582ABE13FA47751A707E8F504BD5E01
+:108C3000F0E3D9AA5EA0DE57D9680CE4127F623C4B
+:108C4000AF6EF8855F131DB4CB1CCFBD6567291FC0
+:108C5000A31EEC7FF4370D0DCA2F45BA98600E9015
+:108C60007F6ECB622B9DC7967D4FD1772334FF1744
+:108C7000D00DD1D1845C89F25CC7DB1FA4FE6C15DA
+:108C800097B37ABA146A5F24FD6FEB7CD81BD8EBDC
+:108C9000B9F3D2B8BCDD1F203F04BBD3CC506E7AF1
+:108CA0002503E58DFD58F0470823907E15924F2C43
+:108CB00089495ECA977C8F7F4F9131C7C66434FD66
+:108CC00015CA6B04B4EF7E43CDA345BC8D7032C78B
+:108CD0000628478DE7F41D3B899F8FCDC1CBD2D5A8
+:108CE000BCACD9DB3149AC05F36287E278D036BE43
+:108CF0008649F5E4D7F053FD30273B524FF3F3FE9E
+:108D00008995CCD50465B15A51FDCD6E35BEDE4D89
+:108D100071EF74C11189FE8D11A28BE2DED14CA2DC
+:108D2000B8F810564DCF28C1CF99C777E423570222
+:108D300000505EB09BCCF4FD8CDCA76D8CBE6FB494
+:108D4000CABC9DF2B20232F911EF39CEEFE16DB13A
+:108D5000FF90E2044D6FF3FB04F7A4783EC478E67D
+:108D6000905A81E13D56B18AC711C4D745C72CA896
+:108D7000176B5BE93B70895506F26B5D69AE3E404F
+:108D8000E770B785BE1FD705FDD1CFD56E3730A2AE
+:108D900057601E3DFE54F8E9BAC645718BAEBF0F51
+:108DA0002279C7747ECE7A37D7BFEBE3CD1CBF6C78
+:108DB00067FF807CBB313E92EEC72DBAB6FA6DE4F8
+:108DC000235BDE131D1B54FF33FAFF87E32F987FCD
+:108DD0006076A5A1DE69AE0AEFA73433D7BB93D185
+:108DE0005F7AD7CAA481F4A87EE3223683DF1C7D94
+:108DF000E9719186721E07D1D6A9EDB3D1B6465856
+:108E000026E36FDF332E52D64F5C24502D20BF1F38
+:108E10008EF513103EDC6FFD5DE322CFCCE5F2F65C
+:108E200072E322DABEE7AABF170162ABF91D14177D
+:108E3000A07333F4AE2F088E3B707DE5F89BCCDF3A
+:108E4000639C61BE5A7EFB99A39FA15FFFF0EE83F6
+:108E5000CFE073C68527CAD6005E144FB393BFF721
+:108E6000DD1FC53CCC870B8D1FCC755842FCF7F835
+:108E700083F849EB10F8BDFCE0FA62DDBA728DA10F
+:108E8000F1807C5B68FB99F1A1F5CE61A16533AB04
+:108E9000263CD5EF7743D4DD9427D7781B73F00CAD
+:108EA000F1A0F3102F5E360F3387DD97866FCC91DC
+:108EB0004674DFFE3EA77BD74BB7BFB196EC580395
+:108EC000DD9F3FB7A8E19EB764C40F33F3D0384E9F
+:108ED00005F1E8AB9F8E7F87623A92DB7323B45F24
+:108EE00096C7BF17D5279EA0FAF387D71CE8C80FEF
+:108EF0008EF70E76AF9E03FC7CB8EDAC807AC8F09E
+:108F00009A97A9FEBAC59307C4A38C9A431DF94149
+:108F1000DFF5CB30BA0CE8C7C8A87995DEF7A7F71C
+:108F200018640FCFDF2B33CB646FA9796A192ADE5F
+:108F30006494717FAB94CEE5CD1613976F1EA8167F
+:108F4000AF82FFB5E9F3DD385F3F3F8DDFEB60C0F7
+:108F500085905F69E3E9E59926076C0AD72333CA50
+:108F60001EE17245CB176CD3E7C5B91F44F808550D
+:108F70008DD46E6B9EDA6E3FD74FD96C26A15C867E
+:108F80007D86CD137D748E1A2FEA273F8D69F6E317
+:108F900082D73FC4FCBCCBB61FFB1977466A20ECD6
+:108FA0007DDB3D85DC7EEC8C08A4201FEE3485D76C
+:108FB000DF1B17CCFCE99C01F457CCAB4598F66B52
+:108FC0002F7CC7BCDA0FD57891162FD5F26B99D1CB
+:108FD0003711BFF39969FBE0068A83F693577B8FBD
+:108FE000DD11C07BEEDE8A08C776F6DDFDEB279C3F
+:108FF0009C9FEE98C3B8FF5E175FD0AFFB83393DEF
+:109000007185E373E85E58F8B842CF3E93C3FBE343
+:10901000AE98A7DDF757EF2B39B9DEA79814162EB7
+:109020000F54CB77D7BF077BE8CC9C20BF9EBB2ECD
+:1090300083FC76F5268EB71E997F4F50D31F6DA8FF
+:109040003F921ED542F5D1555C9FD4F42C498D6BCF
+:10905000E8E909E8E3AF388F60E374ABE9893DF4F0
+:10906000711DD007D0E530C6E34A06356F74989578
+:10907000A7A07F573DAAAFFDF4B5FD3BD94F753B87
+:1090800023C87EAADAFE06EA55ED35DC4FD869AF73
+:109090007E03BF7FE0794F24BDA9BFFE9A1D95389E
+:1090A0002FD48EC2B822E263A2CD27C857A01D15C7
+:1090B00030B9617DE56847D9306FD53DAC28A1AFA7
+:1090C0003DD575F79F29DF15ECCD94A27F047FD0A5
+:1090D000F9970EAA791007469E25BF8958C3ED3D22
+:1090E000B186C7438D653C6E6154B81FC50CF2084C
+:1090F0005D819A1F658B23D48FD295C2FD2889F993
+:10910000D57ED4034DD32C9242F291FB55B4BCF6DC
+:109110007116DF1B781FA33ECBC8300F1D1455B24C
+:10912000032D6A7C83957179A5F94DF479D3369D29
+:109130009F44EF47C92F0AF59B3C2EC8F74E87790D
+:109140009EDF5CF016A2ED7F6E5D11857E93177D2C
+:109150000D7354BFC9A3B89E7D1F72BF49D73E6E21
+:1091600017B95181B92A1CFEF58953911F64DDE1BD
+:10917000F5142FD3FC5089552A3CD4B80FC217E1FF
+:10918000293A393C6374F0F40ED3E2422A3C133896
+:109190007CCB8B5CE47792109E522F3C353F95F749
+:1091A00070077D5FDBB2CE227B089E9F91BD6A4235
+:1091B0007822FCBFA71FEA9622D52E55E139F1D1BE
+:1091C000EC87F03BC1931E2B3D86CF29DB6E8BBB1A
+:1091D000019ED3763E548A4FF63A8F13FC752EE7E4
+:1091E0005798D91D4C8F3715CA21DF83D7E0A9E1E5
+:1091F00061AFFF8E913FB65CE2FEFC72150F33103B
+:109200006EC1FE3C4728DCB6A8F992C6FC6A0FDAAC
+:10921000BBC37570D3F0B01EE186FC2EC62C7BC894
+:109220007F572BA03DD41F1E0E6FBB3C3C7C588744
+:10923000873FDB9C7D2FC2EB85ADA56FE1F3E7BED9
+:10924000DBA2105E7B773C34A71FB82587F07974CA
+:109250007227F485DB8962F70EE40F331C3E23F19D
+:1092600059C037B47BB7374DB486C66734FEE8B40F
+:1092700086931F17F72FADA1BCC2FAB235C41FBB2E
+:109280007AF863B71DF3102F953FE6CDE5F7FACBDB
+:109290006BBE7A6506C035AFE604D19F11E88FCE6C
+:1092A000ADF68441CDC76011202F12CB981FE3C7C4
+:1092B0004398D51725507E02F14D2FE639E3074A32
+:1092C000F57E0AE9D5BF09441C4C3024011FC7DCD8
+:1092D000A92B490EBE5934B92F9F6D2F3390FF67CC
+:1092E000BBEA1F2C5BE03A8CEDB4F8D66E97F276B1
+:1092F000D1F7F36B1F2F0AF21776C6B01EFF1A7E46
+:109300001F3CAF669B807928436A6F25F99058A669
+:1093100030940FB7CEE67462CC9768BF7DFD6DDDEB
+:1093200079682774E28DF62CC2838F110F3A6B9EF9
+:10933000243CB87215F78F74D69C8B0B8F073511B0
+:10934000DFCDCFB83D444E7A6BF8774C3AEDCAEB9F
+:1093500019978107CB543CD0E424CA1BC427635916
+:10936000E051F4630F017C88484379C9F9B108F2F0
+:109370002A0AF623F6E37FD4E8A10BD6661984F710
+:1093800084F5F900D5B4EE7365B9FEA903ACEF928C
+:10939000F300D4B864BD1A975C5AC3F3573BD77D2A
+:1093A0005580EB3D5706F601C0657B9983E1F9CD09
+:1093B00002C52A600B9EA74FDEEAB0B909BD71480D
+:1093C0002D9E7FA2D8958AEF67004E25C5625EAFBD
+:1093D0001AEF19A67E075A87FF80E7A3E6925F4E31
+:1093E00022B9A1F9D119EA8D76C46F6534D64F3010
+:1093F00057274B84DFEEF1586EDF7727E52FF4FA1D
+:1094000007793EDCF7F66F459B29BF52F36F79ED84
+:10941000DCBF55C10205685F531C01F976AB85BE00
+:10942000D75029C866F2AF95B895B9A4F7B8281FE8
+:10943000D6BDC02A911F6CD5AE64E417E58D22C954
+:10944000EBFEEC92BE7476997C46A5BBEFC067AE8E
+:109450009F7B697C6631EE2F88CFDC30F77BF099FB
+:10946000F78B42F90BEA9D75304F9E4A4F3DFB56F4
+:10947000E3F818BF8AC80AD247D5FDEAE9A88F5E8B
+:10948000FA7F1F5DDD83700D43571BF1FD65D055DD
+:10949000EB45E8EA413CCF20BA6AFF17A5ABA72FFE
+:1094A00085AE94B92C344F3A8E7FE7795C9C81E786
+:1094B00059FE1FCE931EA3DAD9FA3C69C6AAA95C4D
+:1094C000046743E7A396E74D6232C6992CDB5EDE64
+:1094D0003456E6E305FB3B99CECFC9747E4DBD7E85
+:1094E00017C60F1AE2F73CFCD4EF0E8F855F9F7E04
+:1094F000F6BF49AF7D7BA640F7C9E78DFE6A3FEA1C
+:10950000A0C51B97A9F30CECF7FC67FB39F127D832
+:10951000AFAADF5763D4DDEABD81CBF37332C7ADA9
+:10952000F47DF3F66AE640B85FCCEFD95ECBF3A6E4
+:10953000B5BC66D74B950F2F9CC4F3E9D0EFA9F7C4
+:10954000776AF9CAF5B665A4E79F54ACDC1FABF3A4
+:10955000772E8B936FA17B8C7DFD9D91F3FE01FE99
+:10956000CEDBE7C8DC4FA3F37B96CE52E2E70D904B
+:10957000CFD019E360C8EFF26C3E01E3B5EC4236A0
+:10958000F97586D802F47DADF29A1CD2034716BB5A
+:10959000D3701C637EF7E72F4EA27C03070EA5E76E
+:1095A000CBA067A6CFA33CB67F8E9FE09FE5E7FBED
+:1095B00068CEE5DD9FFF08E13D79807BF472E0B184
+:1095C0002878FF789D9DBEAFF5FC6C59CD3FE84EE5
+:1095D0006981FA77EF3A7310FD13BE3603C3FB6D52
+:1095E00097EA3F6AB8885E6CD6D9475B7AF462DF47
+:1095F0001B5383F4E286F5CE7DA7C38CA3E9C5BBDC
+:1096000074FEA3721BD78BCB6DDD26B40FCAE3BFEC
+:109610007E05F34E8D55AC03E5E210A59AF4E144C6
+:1096200089513EF1FF8FCBB37F685CFEFE79A1715B
+:10963000F9096A3E0AF278FCFE4F97E6479DC6F5A7
+:10964000868D466EAF78157817268EAE8FCB0FBFFE
+:10965000B087E2F2ED7BAD748F6FCBBE663E5E0EDF
+:109660009330CF3C99A9FA5A11F797EAF58FC74D75
+:109670008A356D12E2BB81EE13E23D41F28BECB50F
+:109680006E437FD3783BCFE7CE7D67F14ECAE7D6F6
+:10969000F443D043492F2E0BD07799CA250723BE18
+:1096A000133FCD4FF1F15A81F06BD93C4E6F4BF324
+:1096B0007DA41F0E2993047E4FCCC3EDF8541E7772
+:1096C0008E44FC82A662268FFB4A474407C69DEF64
+:1096D000C3A6D3F1FE2AE3DFAB986EA0BF43D12E21
+:1096E0007427215F6E1594647C82CE44F71E9F8D93
+:1096F0005106E3DF93AA4F31D0DF933A54D09884D8
+:10970000EB6BAA6B4D42BDF015D52FDE5AF009E583
+:109710003F98C6833E9846CFB07F77F4C1F982FA6E
+:1097200077043B92E87B08ACE543C2AB4C33E37F64
+:10973000E7C7E15F8EF474DA46FAC203828FDF1363
+:10974000B25BE93E5ECB18737225ACA7D96E266D6D
+:10975000C23B66E6913478DF9C2045631CC09B9633
+:109760002EA1FFC81BD3F83AFA419AD3D219E6FBCF
+:1097700037954DA1F879D3056030D0B37EECA8774A
+:1097800027C3FB8D4280BE1BE4996E60984FD8368C
+:10979000666672F0BD4C51D2CB4907C9055136D02F
+:1097A0003D3F518D678B7DE2D9A1F1E949EABE6564
+:1097B000D6B288EE81C69B25DC6FF998920FE99EA0
+:1097C0005BBC99F282CA4D8C7FF7630CA373D1C343
+:1097D000AF7E7D685CC1680B5DDF460C4C531EF6A6
+:1097E0009695881F0D0853CAE3BE7725F2A5869E7D
+:1097F000FA465E8EE0E5AFE7D5AD44392833FEF793
+:10980000491A3279DE65794209F1E1725320EC7729
+:109810007E2FB61E99F914753CF63F39DEC631E647
+:1098200045BEF1171FAFF75C407DFE0EE36AEDF415
+:10983000E3EAFBFD4FB5EF6F9F89F3B5BC7A46793C
+:1098400010A422AAF7D9504F36AAFCB03E778ACF8F
+:109850002F233FF070BA883184CDB3ED9F3E82C68E
+:10986000E749BDC46F697CFCF64C4DA11FF923BECE
+:109870002F49EAA59B9EFC0B753CA87A15E5C3D63B
+:10988000F942CFBAA5C1BDE3FEA62CDB8F761CD86A
+:1098900019729C230CFDA9791AD43E8DF26D283FD4
+:1098A000868D65C447B4F646755E7DDEC66E152F9F
+:1098B0002E376FE334EE6112C91AB207BDBF6DA136
+:1098C000FC25861FA342FF5C9644F7E1EED5DAD96A
+:1098D00019D971DA3944B0DE1FB4D392B482CC46C0
+:1098E000E23DC38DA327D0DFA77C74F7833FC1FC83
+:1098F0008DCDCF6CF8233E23474EB87FDA24BC478A
+:109900006F70A8B9D4643F69F934B67FDBFC35EADF
+:10991000A9FA7C95C6F12B5AE8F882CF311DFF2EAB
+:10992000B2A0A07FDF62B36DA7EFF95805B21FC4E4
+:10993000871269FD4995A1E7DE2E281FE077FF3CDD
+:10994000F709C447231CA1F9377A7BA3A9E75C4335
+:10995000ED940784F071EFD7E6733923EAEE89B608
+:109960009A64FA8E6DEB46112399AC759D85F8D9F2
+:10997000EFE72F5989DF19BF03191ED4B75F63A61C
+:10998000BF6BD56E97AE5B8465559E6971E607AE79
+:1099900018E50BFEFB47AFA29C85F95AAE31933C0C
+:1099A00060C66ECA63D7DF0FEF6367E9F0EE6278D7
+:1099B00076C3FC5835DFC04772A5C7BE1F6DE0F700
+:1099C000A0471BFE25EE41BBE787B7EFBFEF3D6821
+:1099D0008AEB25F4A55F2DFF6F4354EA62DC7FC359
+:1099E0002C337D2FEE72EDDED6752B495E786E65D9
+:1099F0008E0C47DFBC30D74B23097FC42691FC7106
+:109A0000BDF8C5EDDA5FCC33F5FC9D166B109FD425
+:109A1000F2821E52EF153FE46AA4FC19AF93DF2BCC
+:109A20008E685949F6722BE8619857A5D9C727A7C0
+:109A3000A54F1128EF47F1E0773D4EE6AA79415254
+:109A4000687E0B53F3FBB4F95AA7A5D37C5EB4C769
+:109A500007C003A353CDDFD38DD7C3AFD1EE0EB272
+:109A600097C1EEFEDB7CD8DFFD36073AE3A0FE654A
+:109A7000AA6793622FE91E6817FE0AED7E50AAD0EE
+:109A80009F48F9DF0A551CCD00800000000000004F
+:109A90001F8B080000000000000BAD3B0D7054D57B
+:109AA000B9DFFDD9BB1BB29BDC0D9BB8C1106F02A7
+:109AB000D1203F5E304913C572F303244AEDCD0F28
+:109AC00009BE01DEA26871ECD4ADB5BED03ACDC5F9
+:109AD0006C4888084BC4065F1D8D54FBDAB1D5D4A1
+:109AE000D7D7878EED5B90E7F84FDADAAA333E1BC3
+:109AF000D1F2FA3A9D37E96BB1E98C2DEFFBBE73D9
+:109B00002FD95D36809438E3E1DC73CE77CEF9FE51
+:109B10007FCEB655D53AF91180E350080AB61F85B5
+:109B2000CC35610078DF6706CC2500A7E86F1540CB
+:109B30007FD20729EC836A0260BB0E263775E07C72
+:109B400058E88327B15122CBF9FBD690ADCA4180AA
+:109B500012BB12A078667D1BEC57EFC2F1AB7C63A1
+:109B60002D500390D80ABA834BB684922AF5570336
+:109B700038801BAF351A031508B7F505DA086055AC
+:109B800078240232C0B2E70F94C5687FC7FA7975AE
+:109B90001DD054FE5BEC9FB09B717DFF1B8A791F2B
+:109BA0007FD10FC770BD1A5560182148CFAC8C4EBD
+:109BB000E279D4E089F7A000E0BA29809680587B4A
+:109BC0008AE04F07A0A57AA6DF8890D3FBCD81D28B
+:109BD0008CF9ABF58A8C71052C3325E1B9A38B3256
+:109BE000E6856A6B743A6F9BB13CE3FB0DD50D19AA
+:109BF000EBA1453D3E89FD95F8DFA94A8227FA3C55
+:109C00005E01105C82FDB4F52AA4F571FC1A3B14C8
+:109C100039B1183B9F81CF9C52882EE60620BA802E
+:109C20006C3E897829793E30998FF803CB32222512
+:109C3000880F1A3200BE6CE3E25AEC074FC884FF6B
+:109C400047F271EF52C4B33E29139D401F97F83B72
+:109C5000C0F830223BAA5A3C0FA2A02770DEA5E034
+:109C6000483AF6435148527F3E24793EFE251F6C08
+:109C700040B60888F5051D60EEC5F1FC258E24610F
+:109C8000BFA8154C05E105CD0989CEA9E37A05F9F0
+:109C9000A01452DC2F6B85897E866FDD47EB4B7BF2
+:109CA000411F2825B00E8F8F6D0487CEF33898E0C2
+:109CB00057081F36C002000DE2DC5E064611221175
+:109CC000BE0DE60AEA57C1242115A93A2651FF1212
+:109CD00018D7A90F90027B2936936AF84480A70011
+:109CE000F1A9C7AFD92DED74C2A30B4E1EBFD1DAB7
+:109CF00066237F77DF545B180BCEBE4EED7D71BCC3
+:109D0000E5EA99FEB76D83E542ED5DCBF2A2F6BEC2
+:109D1000C4E3476DFB2B36D26319C20FACF8F4F8DD
+:109D20005FA6097C2624301D9C9F78EEFAE8161C5D
+:109D3000779E0B985540F8457C125FD407A65E6964
+:109D400010EB891E11A407E1BB6809488483F9441C
+:109D500007FCAE211D76311D930CB73C0EE60E7745
+:109D60005FEA97221D882E63A0CF21BC2AF14F47BE
+:109D700007FE4338971C0A3C3E2C1176912E0B2E81
+:109D80000A5DBE752174C9A607DC3B17A0E16CFB18
+:109D90003A4CC76F49A93C69019105E983F7919055
+:109DA0003E84CF28087A680026E12917FEA99F572C
+:109DB00003C67DDC17F3899E4EC30CFF1722FF8B71
+:109DC000BE90AF30D241F4059D22242FD88FDAE324
+:109DD000BCBE682BD80F94123D2C469E0F62DCFA55
+:109DE000614AA2B65232995E0B145BA67EBE9412F3
+:109DF00048464A923E28009DE9330FE2DC467C53F8
+:109E0000874F91BE0ECA634E05B5CF36D23EFDEBED
+:109E100050C390CA0F8D34325FDE0E7A15F25DB9F1
+:109E200066B1FE2EBF52351D231D5FF7317C30AC6D
+:109E300003646FCAE5100CD7CCEC9BF099D124D207
+:109E4000EB58E8C491187E9F53AA80DF9CC1F37140
+:109E50009FB81FC1542E257910F211ADC7B384CF1E
+:109E6000D46F5155F06D701BE20FF1B19906104F90
+:109E7000D2D0BFF3F7479A85BEFBAE1DFB88F885AD
+:109E8000F413E3CF029DF4936E02EB4DD9707E4341
+:109E900076F1E490DF203E85E4A815C07DB6B8FBDE
+:109EA0006C19F27F2015A4DD33E18794A79F2B69FD
+:109EB000BD5DC8FC6C4A10A83BFF7517CAFFD05B9C
+:109EC0004CCC764EBE6D7C6665E1E492D9E76924A0
+:109ED0001F73D3D7093A6911E4A7208DBFC4E3E704
+:109EE00082E3EB3D9C21671E1C5FD46638BEDEA377
+:109EF00042DEC86E213D6F43BB358CF8FE474BD721
+:109F0000045F4EFD27D9F39BE30526D9734611CE96
+:109F1000BB25298D0D233FDE0A718DF85482850EF5
+:109F2000D16FB32399C338A572D7D602F617A045CF
+:109F300027FC48A96B95538B3F051E5D3C6D4EFD7C
+:109F40008FCF08115E43F0A1375E3933FEC78D0B0A
+:109F50008ED51AA4B483D544DF7C97BEA8899CD73C
+:109F6000F09CBE4F0A615847EECFFFC61BABF07C9A
+:109F700003BF504CA582E6696021BC3920EC783ED5
+:109F8000C9E902E297F1D41DC46FBD853ADDD79BC4
+:109F900007EE3C076216DD331FF500C195F37733FA
+:109FA0007FE6176886C2CC8F1A27FD1E01E4BB121C
+:109FB0004635FF156BA914C9577153C0DC91095F71
+:109FC0003A45EB112694B8F790CEDC7F29F5033C97
+:109FD000D478CADDCF0AA4ED97D5F745D3FA20C6C9
+:109FE0009DF4F9A606A934BC9E961757CEBC7307FC
+:109FF000835AA6BC64ADF3E8B1C427F8635E198C3C
+:10A00000EDC0F30E0D1D6C247D335A0C861F8706A0
+:10A01000377F47029CDF44BA98EC4F0B8CF925DA66
+:10A02000C718AEC6BEAF2CC8FC73C96FEDD41D08EF
+:10A03000E70BF57EDD409CCCFBBDA537E2F86D65F6
+:10A0400001D342FA26DCF94E0BFA5962FB5F915FAD
+:10A050007AAB7B5EA605CAE1BDEDC2CF52C35D3BC4
+:10A060005FC3F9FBE629A0905E53369A649F6E5554
+:10A0700001E616617FBF8FFD3EF4EFF83EFE964C81
+:10A08000BFEFB6477C197D5F969FF8F576F403899C
+:10A0900068AE1F38D00EBC2F9D67EE8ABF1F3E04EE
+:10A0A00023AC3F97AA13B29EC3AE7AF8979E0932AB
+:10A0B000FE7F528C78A575605B7762DF8F78247E97
+:10A0C00045455D508B78B2E89F06F9C93FBA8BE6EB
+:10A0D000FB4F22FFD27C25D87227D1E152174F20A7
+:10A0E000CE65E17F74EE6C7FD89FE50F679FDBA3A1
+:10A0F000C3631E7EEAA08EF083FE39FB07DEBDB28D
+:10A10000EFF3421F6A0EE4A59FF605B84DF5E9DCB2
+:10A110001EE98B727BB4CF801674AC5EEAABE6F6B8
+:10A12000E53E93BFBFDA57CFAD878FD9F44DA8581E
+:10A13000667F61DFBDF2180993BA447FE50AE2DB6E
+:10A14000B714561F3A1879EA02B643A0E2BCCB5ABC
+:10A15000D5318BEEE2C63F97B87CB6D83F75D88F25
+:10A16000EB92A560DE470BD16E6FAD99897FAE9BF8
+:10A170009267E40428DE9933636780E29DB919FD94
+:10A18000E6C0A519F357EB0B32C63DFA3ED628E4DC
+:10A19000666D7471C6FC7D2D4DA92F905FDFE0D7F1
+:10A1A000159DE29FAB33C66FA8BE36031E28EB4C4D
+:10A1B000D2D3451BD3E8C6F7CFA4ABB6EDEC719074
+:10A1C00047E7F7DA33E3A1D9E89BCDB71E5E8B4EA4
+:10A1D000E355C495098A2B0DBAF712690B82DA731D
+:10A1E000DA2FB1C00ECDECABD6637CB9ECE2C797E9
+:10A1F00005145F56E48A2F3FD2897FCF195FB66678
+:10A20000C6970559783B577CA97564EA95F3C5E76D
+:10A21000E6F2F81BB514EFBDAEB01FA8B4C6D9FE68
+:10A22000CD9D50CCB508B7D8F5C74224F3386F732D
+:10A23000ADC6FEE53E988C92DDDF2B215691FFE7FF
+:10A240002E314B49DF3C1DB64A6EA238BF4D360F4A
+:10A25000E292171BBF1925BF63D78EC7A36894600E
+:10A260005187CCFB261B4F6C22B9520DF4E3246EB0
+:10A27000ADB11CFE8937FFAB033EB6037B37696384
+:10A2800012CEDF1BD2BB3750DFDD0711C2F676B42A
+:10A29000F6F231F2FFAEEC3004BF801325FA3FB87E
+:10A2A000A9AE948D948AFDA534DD643B3E1C32AD8D
+:10A2B0005B887F7E1304073F3D20E90512D98B4D53
+:10A2C000B2FE24DE73B475C5BB5BB1BF2BA8992465
+:10A2D000F089705D29F197B219DD1EEC8FB48EBC48
+:10A2E0004CEBD52A99FB894D971F23F779B4586F0A
+:10A2F000ABA4386F7525611A94439FF4515E231106
+:10A300003E11A5F5FDD788F5B3D147D1D3EC39700F
+:10A31000FE82CFAB2C94531AC2515E38F15782A7FC
+:10A32000A4DB71D6E3997EC57058A32001D6FF7CCB
+:10A33000E1F71C9554B965111D4751E6094F9B374C
+:10A340007514523CB5D937599CCB5E0CA07E4D5D3F
+:10A3500091E66F4632FD846CF8FC5747F8C53F59CB
+:10A36000748D123774C1BFC48D6BC652843748B622
+:10A370005652DC1B147679363CA8C14C3C78F01957
+:10A380001EFE4FE9CDB3F2D2F080D74A91BF73479A
+:10A3900087C4F4FF22F141AD3806C51DDEB9D4569D
+:10A3A00099D779FA01F978C338F1878BF7289A0C95
+:10A3B0009243EF1C5F75E1DD739AAF706A49DA3939
+:10A3C000566A2E3C93E3E2AB342157F02BC57CD286
+:10A3D000C84127D77FE3F51533E3AA7BFE2B0E6830
+:10A3E00019FA7788F6C77BBCBDB1F3ACF1F2A2B124
+:10A3F000CC75DFE9003EEF958A75E404F95257C841
+:10A40000634F22A8C557C82CCF27D1FF22BB361BCC
+:10A410003C8FFE2C6225CC5D407ED9CE4807F3F9F7
+:10A420006CEBB4B109AB6219ED0BF171E4AF45D13E
+:10A43000CC7379F3BE73FA5E5F8139741E74C8C938
+:10A440001EF9C75216E9693FC291B0AD7EFC6EFDA0
+:10A450006CF7F6431A7CC4E74792D0574E18F8BE03
+:10A460008977C7587EE0D0D48724DF894525C63058
+:10A47000CB0B4417D6913F22EEE5CBA2D3709E8042
+:10A4800033B25CF8A9236EDF592AE042BA9CE2FAA3
+:10A490003C37AFF242C702C6BB467A8688AC5AE563
+:10A4A000C41741F5878E8EFC3027B80FC2D8FA2327
+:10A4B0005B1C6A57951B7BEAF15C238B64B66323B4
+:10A4C000A1D8E303A487160573CAC76BAE5E1C222E
+:10A4D000BEE5F8092C99E44EF284046232D26B9402
+:10A4E000391FE0FD8EB0C867E9C9FA9B118F6FBBB9
+:10A4F0007C81F7E1F5D9F0DF3D13FE13C4AF0917F6
+:10A5000038C1D982707EEDCA0590412971E33EDCE5
+:10A510002F6024EBC95F98ECD0C5B8BADCA4FB8FE0
+:10A520008473EF37E9EE67C97189E65DB251AC8794
+:10A530008058B7579ADA705CD093E589F6A7F17C1A
+:10A5400033533F64C3CDABCED4575A59E6FCFF75A5
+:10A55000F92F3B1E7A40CA7DCEC24E71DF55E5C051
+:10A56000F688F8E2BE1C7C912DEF1AE53F11EEDF74
+:10A57000880EBC9FD03B4175A229BF86EC3B98FD5D
+:10A580008CD8C37CDFFBF26FE43879E00691E7D02A
+:10A5900054A1B7CB362018B4C7F64F5A1CEA2B7714
+:10A5A00083EE0F9F89874F1BEF91BD71D2D6873BFA
+:10A5B00081CFA9A4C781788FA4CFB891F64DEE5270
+:10A5C00080FC80E476FF865C76BBB8C3E7E95D8EED
+:10A5D0006B55972FC0AC0019D71F784BE1BCC081D9
+:10A5E000FA9D1C17276CCD902A284FF1086CC7F1F3
+:10A5F0003F5A32FBADBD87EEFDF5ABB8EC784B654D
+:10A600009D24B31CC1AD38FF38C6C5E43793FC6543
+:10A61000E46310B181BA99FD922D95BC5F02F79366
+:10A62000CEA2E7541BE3D66567C23B6D8FB3F2231E
+:10A630000325B1DA4EBCDFBEA0A8B3285E7EA42BF2
+:10A64000725E791D0392A95ED22B1B81F1106A1BE9
+:10A6500081ED944F888A38E348AD5FF0D776C98D95
+:10A66000CFA0053C3D857FEB361A0FCF25FBF28E40
+:10A670001FAA70BCE9A9D755EA8F94CA75143F5F29
+:10A68000A54DDE7F158DD7F9587F3422255319FC4F
+:10A6900091F2CB513E8FE6B68A685312B5CD81FC5C
+:10A6A0000C7DBD5ACF8C3FF64C1F510A893F753047
+:10A6B00025C4F39E46D32A24DD634EF6D3F73DAB83
+:10A6C0000D73D8207F38334ED9D3A6097D5A21EC9B
+:10A6D000CEC861E361F2AF067BF3D8FF7CA04C16D5
+:10A6E000F75E0863C40F6D46665C33325EB96B215A
+:10A6F000C959D2C7F9F2EF8F8BF95B772C1FA3B83A
+:10A700005477FDD5ADA54DEC87C280987743F5E22F
+:10A71000ACFB4FE8C417C9ED3E20FC0F96DD3C446E
+:10A72000F9D00F12BEAB495C5EED3432E2C22D03AC
+:10A73000B7729D6840839BE8FC7B3669CCFF7B8ABF
+:10A740003F38700BE9E9E2398CE7D14D5A692C4D5D
+:10A750001EFED6E9673918DD24FC8B621962E339E5
+:10A76000C6FFD629F4D0E76E07BE4F01DA65033F76
+:10A77000196A3CE5277C9401FC335D27FAD1437CC0
+:10A78000FF5619AAF08823918DECBF65F359B0AB41
+:10A790008AE19DB68FF572061E7D7E3BCE79EE1B5B
+:10A7A000C0207DD5D28A7D8AEF376A40FCE68FDEF5
+:10A7B000CDF72CC27E1EF603AD4947C57E6061EC25
+:10A7C0006AF25B5FDCDE334479167F44D689DFFCB6
+:10A7D0001B6FB33B697E8D0FF2707C000C294AE73A
+:10A7E0007424207D6D40AC95FCF591A8AC53DE66D9
+:10A7F0005D62FD36DA7F5D640E109D37B7C9BCDF40
+:10A80000494BE3A45531391A94FF2A09B2DD7DDFA3
+:10A81000177FB807E7BF8FF47260E65E873A2BF9BF
+:10A820009E794666FC1C8024DBE195D6C446DA6737
+:10A8300065BD46150D38D270E200F9EBA3B57ED3A5
+:10A840008FE71A6D9018DF1FD7FAC6F0A8F0536D86
+:10A8500042A17D7FFA31F246452EF93DBBDC64CF43
+:10A86000DF53DF11207ED809135D841F675A66FB12
+:10A87000953DAFA14BD07F27E285F0ECE079AB2886
+:10A880002E9A42B942E8E169FBBBB760FBA54E9541
+:10A89000E77DB55476A82E34D8A6B19C0C866243C9
+:10A8A00015D4477EE7782812637E1E298DB01C7A66
+:10A8B000FB8C34745713BFBC519BC77EFB973B4F37
+:10A8C000DCEE2C44FDA1FCFE5F9FA1F8A94C637A4D
+:10A8D0000EFAECD4ABC4D76DC25F3C3AFF1E96BBF8
+:10A8E000818D3703E10D9CF83B54B71AA86960F8D5
+:10A8F0005EBE6164BEC8270D44EE7228BF91AA17E0
+:10A90000F905ABF820E7F3BCBC52A3ABC716FBE3D9
+:10A91000AF54D1BADB55511756CA12A40FFC945745
+:10A92000A2756A66BEEBBAA9CC38785E561C9C9DAF
+:10A930006782C0C4C24EB4A7BFEBCCCC2BD1155894
+:10A940008E6BFC1C2F8ED68B3828E98B97EA4BCE6A
+:10A9500094E3375D3F78A22F801C00F0F33E9DFB0F
+:10A9600005D61F76CC45506FF545F9FBE7573E2ECF
+:10A97000A5AFDB53B33E60B0DE988C12DC6C7D91EA
+:10A98000CD07BD9D7398BE18A701D177CF14307E37
+:10A99000430D2B52C4A727FF041C877EB6652208EF
+:10A9A0009567AE4FD139FD94FF12E73C4AE7F45367
+:10A9B000FE4B9CEFE53E83DB57FBAAB95DD3052236
+:10A9C000CFEFE983CB501F20DE5ACA449FE49FECAF
+:10A9D0007051E4669BF8CB1F557592EF40593225B4
+:10A9E000A5E983D150FC5DB2CB83C541E6BFEC73D2
+:10A9F0005DDE25BB762F7E13C1DD837009EF2F6EE0
+:10AA0000FFEF8716D03E6F29CC57451BBBB7B1DE91
+:10AA100041BD90C7FE86D087C9E220E71D46B757E3
+:10AA20004951EC6FDE211CDD73CA3DEE3386EB8E9F
+:10AA3000A0BEA6FE20CA39DD67B0E1833B689F8FC8
+:10AA4000FF32872A7C48EF5FB1DCBF8101C8DC8B15
+:10AA500028F79E9CBDFE8B43DF233933C0EE39249B
+:10AA6000EECF7A70343491A4FB0FFE52815C78BB38
+:10AA700050BA82757E7EC8983A75F8542447DDD066
+:10AA80001275C3FEF11F71DF59075085FD477D56D2
+:10AA900080F8E0D11DF259EB868FEE387BDD706CCB
+:10AAA000BF0C7E7DE61C97C224E7592984A73AE0B3
+:10AAB000000D617B4357EC962EF623455DD168A0CF
+:10AAC0009C03F5F539E43F1FB5ADAD3C1E2962BBD3
+:10AAD0001F55C75364D7A3542F37E8FD82C3754F62
+:10AAE000CACFD2FB85ECFBF7FB269BF87E3885EAC4
+:10AAF00095D9F54929F86351DF5F20EA905E7D72B0
+:10AB0000993679F07EC2D34D01C643FF73D7BC435B
+:10AB1000F52FAF8E1F75EBC0FA36D077887BDCDB64
+:10AB20004571D00BA21E0AD7E03D96D3269395ED32
+:10AB30004BB9BEB983EE71AEF39F6FDD709DABDF95
+:10AB400090B9C7489E7FEDE2D39BF74D92C75AF26A
+:10AB50001345DE1A0A34D6F34D4F0541217F39A43F
+:10AB60001D2439D90293AB499EFAC3C26F4BECF353
+:10AB7000B1DF36DA65F03EC59AC5EF178ABF966732
+:10AB8000EE403089C37A01E591AEE9B446BBF81CCA
+:10AB9000C9AE0E3AC790C2FAEEFDAAD5FC8EA94DF9
+:10ABA0002A64795475AB3C5D5F1EEACAFD1E695587
+:10ABB000F95407EF1F9281E2AD449EF9B241F8FECD
+:10ABC00089CA70DB40BC5782ADBA3484F7EC0F1EE3
+:10ABD00067FAACAAF22F27FD74C8B5AF8950EEB85A
+:10ABE000EE59171FFFD01EFB21D1E17A986A26FD8E
+:10ABF00086A26D3AFCAE45C46B87485F8A78F75EE3
+:10AC0000B96E26AFF5922F7688EE6B7D5FF813FE56
+:10AC1000A8F0EB3152E37CD007EDD67304771DF139
+:10AC2000790D2B2A7872790E3977CF714797F51FF6
+:10AC300004EF98BBDF32DDE2BAEB3290CDFE485A2A
+:10AC40005DDD38BFBABAA4FF58D4D3AF157C0C2F42
+:10AC500038820F9B40277942FE3B46E7F3DE972C74
+:10AC60007B7E5B05D75D2EB0BE9DDF61BD4DF04E96
+:10AC7000D9F6BBD4BEBFBD0718DE79BED758551E66
+:10AC80008FDA48A7C13CE1373FDD686EB0D3F23FB1
+:10AC900073D60B7B3267BD88C717233B4D88776F10
+:10ACA0006CC72F87FA00D12B1BFE401F8C531D68E9
+:10ACB000B6FDB55D7705284FDC5FD614A0F768892F
+:10ACC000605321F507CBAC28ED3FD0D7FADC4755D0
+:10ACD000C44782EF9DF9221F9144FDECA4E5494F42
+:10ACE00075297CAEE63248513EDD1F147E911FE38C
+:10ACF000456329F9CDF56CCFF1FB38A50EFCEB0DC2
+:10AD0000116F5B265841728340227CA18E3CBD9E10
+:10AD10004C5E73591CE85CB3C1515A703DC5A365C4
+:10AD20003AFB2157AED7196ED89267E278387F7C0C
+:10AD3000ED3B07BE8ACE812F6F9E2777D978AA5C1C
+:10AD4000AFF0F95E0CDFC3F7824F9A59CEFCA8F042
+:10AD5000A89E5FBD5EE8192568412CC4E1BF44F898
+:10AD600049D0039B2533F8455F91F1ABE8715EE76D
+:10AD70002F3321B694F0A14B848FECFB2F7BFEBBCD
+:10AD80002D84B757B608BDBA4A75F5471CEF82FC4B
+:10AD9000B9D3D56FE0DAA5B63C6177D6C1CF8222B0
+:10ADA000AF2DF87419BAE381A233F5ABD73EEDE6C7
+:10ADB00095B3BFFF6E7D9EF0878C71D6EFFDAD021F
+:10ADC0007E2824FCD083432BD87F58535A35275DE7
+:10ADD0003F5EEC3A61765DF05C75C019BEB10274FD
+:10ADE000CE3FEA7739EDC6ECFC713FF18F8FE42658
+:10ADF000C0ED19E3E576D424B99A6F398074DB1974
+:10AE00008E47897F060E6F7F87EA24EAEB8A49FE28
+:10AE1000A6AADA40F3D614C7593ED696594075A56E
+:10AE2000FBFBAC1FA6C31D6E8F6D5B4FEF84F471EF
+:10AE30008BE00421E5903DBA7EAE15B773D0E16E8C
+:10AE4000577F7CD06E7F693DF2E12AD29D2B007E38
+:10AE5000695B7752FF7CF5D599F2D41A20BD7FE16A
+:10AE6000F2D411A0FB0D96D9FC4E6BF0670A79580D
+:10AE7000A7E70DBAF23438FF1E88A5C9D5EEF559FB
+:10AE80007A27E2EA9D88C57231E2EA1955B7593E40
+:10AE90007C244F4BD2F44CC4D33316CBA31AF1E429
+:10AEA000C9953F92A720BD0F9E6A263F6500C43B0F
+:10AEB000C66CF9FA7E7BEC61A2C355C5FFD7596118
+:10AEC000CCBCFF340C214F83652EBFCF7F96F9FF9A
+:10AED00024F23F3D16EE0F5666F0BBD7AE9C5620CF
+:10AEE00085A4B86E5AE2F6B3D3F9DCAE9ACEE3D6B7
+:10AEF0009A9ECB6DE37498DBA6E94BB96D9E2EE567
+:10AF0000B6651AF9FE6AE4FFE90A6ED74C2FE676B9
+:10AF1000EDF4226E5BA7AFE6796DD3CBB9BD7EFAB7
+:10AF20005A6E6F986E10FB504DA82827FF5339EBCF
+:10AF300022F0BFE9507D74E0F0EDEF107E7CBAC6E0
+:10AF4000799444B88EEB3D3E35CEFC7FB04CE8F7AB
+:10AF5000B541419F6CFEFFA03DF632F16D36FF8397
+:10AF60004FBCDB52E9DD560DFB396F327F9FE1EFBD
+:10AF7000BEF417CA83A2FF718CE877A1F6FFB45F15
+:10AF80005992E9570E1667FA9503F33DBFD23F4633
+:10AF900075B0AD92C1EFC4F23B621FF2FE606FA1CB
+:10AFA000F1585740277F2A115E130D627FF34E053B
+:10AFB00028DF87FEC56F781EEA07B21BE72BAFBFFD
+:10AFC000B4851C78F397C17139FE29FC93F7E99F8A
+:10AFD0000D67CAFD6CEB3CB9BF1CAAF372D9D9222C
+:10AFE0005FB3907B5DC87DA2CC1EA27C4B224BEE52
+:10AFF0003D3B8A78C890FBFC6E57EE5D392E8A88FF
+:10B00000771F4524F7C857E16EC3ADFF64DA51D509
+:10B010009DEF6B15F5ADE688D0AB6AABD017AA9E55
+:10B020006947916F8ABB73F8138E2AFCE3B6AA7F37
+:10B030003B6DCFC8AE1645C252216EADFF69D2A19D
+:10B040003CD6617501CB77B61C25F415CCE787D5C6
+:10B0500066C825FFE72D4761CF8E586C47B2E77968
+:10B06000F23470B88DF1E2D995C3786F2BCD9EACD8
+:10B07000D5051ED09EACE8CE614F56955B313BC7DF
+:10B08000399BBA855FFADA75B6F017D14F243F25A0
+:10B09000E1CBED0734750BFFA7A8D5FD7D8501F148
+:10B0A000B9A8075B5B53CD54C340796EA2FDAFB323
+:10B0B00026FB4906FB8323113A3FCA6733D1E1429D
+:10B0C000E5B3BA5DF885D03B97FD16AF3D17DF7B42
+:10B0D000FE8EC7FFD9F39EAEB036E4C2CB0FBA45A1
+:10B0E0005C7370E8D90CFED8A32EB8DE3472EA5532
+:10B0F000CBBC287AF5FCFC8AC368E758AFCEEE5784
+:10B100007C25171FCCE6577CAD5BC49BE8576C27AA
+:10B110003AAD5A22FC8A1F74C3C5F5171AEE627C39
+:10B120005DA8BF30D27D767FE140B7E72FC4596F6D
+:10B13000F85DBDF169FD851CFEC1A3CCBF30A550F3
+:10B14000FD0F516D8A7C88D023A8670ED238C6F1D6
+:10B15000EC2F1C0C0A7EB15C3D734797FD04D16354
+:10B160004FBDF0172E961CA0DFF734C13D5F793834
+:10B17000DF79554FAC1C9A243F0742497A37DD4F9F
+:10B18000EF95287E7C2F24DE11E05128EFFF4FCA77
+:10B190009526D9B9D1FC6F3C46F37B1D15E8DDE05F
+:10B1A000FE3E917FDEEDE6FFF6FBE2FF328970EEB8
+:10B1B000DFE1D70FE2F89FE7143832F2D49FF3CAE9
+:10B1C000C7E85DD031570FF96153612EBE9A399FA0
+:10B1D000789F4B4F574EF1EF3ACA74CE93BBF88924
+:10B1E000683638087FE77C99EB233BDBBF7880E447
+:10B1F000C76917792E2EB4E278645E54E43BD08D93
+:10B20000A94FCB8B28A09EA07CFC10BD514FABBF9B
+:10B2100016DB1847A7C51921D3CEE81B100307F783
+:10B22000D91B91393F3FB852C44583C17840CFA163
+:10B230005F76F565BE53CA6E95454F24E92DF183BF
+:10B2400051D5A4F4E870754D1BE53113BA78B4A458
+:10B2500085653B571D3BDC23B9F97893EDB6FAB908
+:10B260008EC25C76C56B87FA449ED6EB07168E5B62
+:10B27000C49F5A8565F3EF75C211C949CB2FFFDE14
+:10B28000D5133B2533B50A91B63324EC44C0485A54
+:10B29000329E77A0F836AE47060C074ED0F78549A8
+:10B2A000F810DB488916CB5977EF11F1CC4E5F8C43
+:10B2B000F7DB59AA729D726745EEBCD75F5DBDACE6
+:10B2C000859B6CCEFF8755AE2767CF9B72F949D31C
+:10B2D000ACA8CEF1F76D06DD2B311F389739D57349
+:10B2E000E7533B82C49F36E747F6BB79126DDE36E3
+:10B2F000C6FBEE7255A73CDC6A65DD0EDAE7415409
+:10B30000BBE49F64F3817F7E4D1ED73FD7C9FC66A7
+:10B31000339B2FE8EDDB04F9696A8AFD251FBCC366
+:10B32000798BDD3547B86FC084DB17FCE2D59B22F3
+:10B330002E3F9E61275C7A2549AE72F0CFFDE51362
+:10B340006CBF1F6898D840759B602460B6E23DF6DC
+:10B350002DB739BFBDBB5666BF35DFFD3DCE83EB94
+:10B360008AC28497DDB547582F679FC777E415F6E3
+:10B370003B826A8AF317C1B28F389E7DC83DC7DA17
+:10B380007A214F05A6D0C3055D71D071DFE2B79475
+:10B390003103FBD2BC971D1FD50F6E126F8B352D5D
+:10B3A000C57E467EFD1A89CEF766A90212C1505E9F
+:10B3B000E0F7BA600BF9F6DE6597746919F17D184C
+:10B3C000D2FA15E27704E9EFA840D978D6F766BD3E
+:10B3D000EFDD7EEC681ABC9E1EF75DAF5B673BD766
+:10B3E000FA3FF76D3B761495FF83356797ABBDAE9B
+:10B3F000DEDBD357CF74F2F8CBE3B7085D71C5EC51
+:10B40000EBF787C773FA25A33D82AFCFA58F0AFC60
+:10B41000E36CE7F75E379E9187FCBAAB1FBEDE2375
+:10B42000E4482F9FE2BCE55EF79DD3DE3CD8F06C8C
+:10B430008E7B3DD6A309793ACDCF9E1FF0CE85F9FC
+:10B4400001F3BB44FC105991477E00E2F3657AE7B3
+:10B45000F6A78866409A3C0F8432FD50CF0FF86DF6
+:10B460008FF0035E2CFE98ED786130C5763C6866FF
+:10B47000E609B2EDB8E68B715CA9956A9E9EE17A09
+:10B4800057F0ED6F3CE5903E48EDE2FA513EF26F29
+:10B490009E488D3BB9E8044B32DFDD7CB107F83CB8
+:10B4A00011233ED148F6A54BE57AC87EF9BD431F6E
+:10B4B00012BA9271B05DB8C3CCB7BB27F8FD8ECB82
+:10B4C000F7E7A227FD7D52E7FE6E85DE715CFB6625
+:10B4D0007DAEB8C36BE97D55E67BF84F2717CF7B70
+:10B4E00072910779422ED6C903E40FAC93F9DD0AB5
+:10B4F0003DEF55EBDC9423D5FDE964746F7A1F248E
+:10B50000B9F5A40533F2029F17EF5E4E6E13EF6894
+:10B51000F877860BE877A193FCFBC1CBE895AB32BB
+:10B52000A3DF4E42994CF562E788249DF6932EA541
+:10B53000278FA64CEB1682CD6DF6B92F87387FAFDB
+:10B540008624B757C238B74B6082DB6530C5AD057E
+:10B55000426F994745DD6305980A7DAF019BDB3A51
+:10B5600088735B0F496EBF79ED97FE70332EF9AF8C
+:10B570001EB72E7F1A2F02AF39E43B458FFEBDFB6D
+:10B580007B787EB0C760B93B17BD07C242DF369BF0
+:10B5900013ECDF878236EB615F44F0B707C7374BA8
+:10B5A000BEF8EFF5A3B27F67F2FF2B2134C6D03F80
+:10B5B0000000000000000000000000180000000073
+:10B5C000000000000000004000000000000000003B
+:10B5D0000000002800000000000000000000001033
+:10B5E000000000000000000000000020000000003B
+:10B5F000000000000000001000000000000000003B
+:10B600000000000800000000000000000000000032
+:10B6100000000000000000000000003900000000F1
+:10B6200000000000000000380000000000000000E2
+:10B630000000000000000000000000000000000802
+:10B6400000000000000000000000000000000000FA
+:10B65000000000000000000C0000000000000000DE
+:10B660000000000E000000000000000000000004C8
+:10B6700000000000000000000000001800000000B2
+:10B68000000000000000001C00000000000000009E
+:10B690000000001C0000000000000000000000137B
+:10B6A00000000000000000000000003A0000000060
+:10B6B0000000000000000001000000000000000089
+:10B6C0000000000200000000000000000000000177
+:10B6D000000000000000000000000010000000005A
+:10B6E000000000000000005000000000000000000A
+:10B6F0000000000000000000000000000000000347
+:10B700000000000000000000000000AB000000008E
+:10B710000000000000000008000000000000000021
+:10B720000000C00000100000000000080000C00879
+:10B7300000100000000000020000C0000010000027
+:10B740000000001000009FB0000000000000000892
+:10B750000000C08000100000000000040000C0884D
+:10B7600000100000000000020000C0800010000077
+:10B770000000001000009120000000000000000800
+:10B780000000934000010004000000010000934805
+:10B7900000000000000000020000935000000000C4
+:10B7A00000000008000093540000000000000002A8
+:10B7B00000009418000000000000000800009358EA
+:10B7C000000800000000000800009AB000400000DF
+:10B7D00000000040000093980008000000000008EE
+:10B7E000000093D80008000000000008000094202A
+:10B7F00000C8000000000098000095B0009800000C
+:10B8000000000028000095F00098000000000028CB
+:10B810000000C480054000300000054000009D206D
+:10B82000000800000000000100009D210008000049
+:10B8300000000001000020080010000000000010BF
+:10B8400000002000000000000000000800009CD85C
+:10B85000000800000000000200009D180000000029
+:10B8600000000001000000010000000000000000D6
+:10B8700000000009000000000000000000000002BD
+:10B8800000000000000000000000CF2000000000C9
+:10B89000000000200000CF46000000000000000172
+:10B8A0000000600000200000000000200000730085
+:10B8B000000800000000000800009FA00000000039
+:10B8C0000000000100009FA800000000000000012F
+:10B8D00000009F60000000000000001000009F6357
+:10B8E000000000000000000100009F610000000057
+:10B8F0000000000100009F66000000000000000141
+:10B9000000009F67000000000000000000009F682A
+:10B91000000000000000000400009F6C0000000018
+:10B9200000000004000000520000000000000000C1
+:10B930000000000300000000000000000000000301
+:10B9400000000000000000000000000500000000F2
+:10B9500000000000000000020000000000000000E5
+:10B9600000060000000000000000002000009F70A2
+:10B97000000000000000000100009F900000000097
+:10B98000000000080000005300000000000000005C
+:10B9900000009F98000000000000000200009F9C33
+:10B9A000000000000000000100009F9D000000005A
+:10B9B000000000010000000900000000000000007D
+:10B9C0000000000100000000000000000000004432
+:10B9D0000000000000000000000000010000000066
+:10B9E0000000000000000050000000000000000007
+:10B9F000000000890000000000000000000012C8E4
+:10BA00000080000000000080000000010000000035
+:10BA1000000000000000A000071000000000071058
+:10BA200000001AC800000000000000080000AEC0BE
+:10BA300000080000000000080000AE400008000000
+:10BA4000000000080000AE800008000000000008B0
+:10BA5000000020080010000000000010000020007E
+:10BA600000000000000000080000A01007100040C7
+:10BA70000000004000001BF800080000000000016A
+:10BA800000001BF9000800000000000100001AD0AF
+:10BA9000000000000000000100001AD800000000B3
+:10BAA0000000000200001ADA00000000000000029E
+:10BAB0008000000000000000000000000000AF0057
+:10BAC000000000000000002000001B78002800009B
+:10BAD000000000040000E000002000000000002042
+:10BAE0000000F300000800000000000800001AF049
+:10BAF000000000000000010800001B3700000000EB
+:10BB00000000000100001B0F000000000000000109
+:10BB100000001B70000000000000000400001B7407
+:10BB200000000000000000040000005000000000C1
+:10BB30000000000000000003000000000000000002
+:10BB400000000005000000000000000000000006EA
+:10BB500000000000000000000000000700000000DE
+:10BB60000000000000001BC80000000000000001F1
+:10BB700000001BE800000000000000080000005169
+:10BB8000000000000000000000001BD000000000CA
+:10BB90000000000400001BD40000000000000004AE
+:10BBA00000001BD8000000000000000400001BDCA7
+:10BBB00000000000000000080000B00000180000B5
+:10BBC000000000180000C00000400000000000401D
+:10BBD0000000C00000400002000000010000C001A1
+:10BBE00000400002000000000000E2000020000011
+:10BBF000000000200000E204000200080020000213
+:10BC00008000000000000000000000000000E200D2
+:10BC100000080020000000040000F40000280000DC
+:10BC2000000000280000F540001000000000001097
+:10BC30000000F5C000200000000000200000F5C05A
+:10BC400000020020000000020000F30000200000BD
+:10BC5000000000200000200800100000000000107C
+:10BC60000000200000000000000000080000110893
+:10BC70000008000000000008000011680008000033
+:10BC800000000008000011A80008000000000008E3
+:10BC900000001240000800000000000100001241F6
+:10BCA0000008000000000001000040000020000427
+:10BCB00000000010000059000030001800000010C3
+:10BCC0000000590800300018000000020000570072
+:10BCD00000080000000000010000570100080000FB
+:10BCE00000000001000011E8000000000000000159
+:10BCF000000011F00000000000000001000011F839
+:10BD000000000000000000100000124400080000C5
+:10BD1000000000040000400000200000000000209F
+:10BD20000000530000100000000000100000153853
+:10BD300000000000000000010000000300000000FF
+:10BD400000000000000000000000000000000000F3
+:10BD500000000001000000000000000000000004DE
+:10BD600000000000000000000000150800000000B6
+:10BD7000000000010000152800000000000000087D
+:10BD800000000050000000000000000000008308D8
+:10BD900000800000000000800000000100000000A2
+:10BDA000000000000000200800100000000000104B
+:10BDB00000002000000000000000000800008410C7
+:10BDC0000008000000000008000084700008000067
+:10BDD0000000000800060000046000280000046065
+:10BDE00000008520000800000000000100008521FF
+:10BDF00000080000000000018000000000000000BA
+:10BE000000000000000084080000000000000001A5
+:10BE1000000084F40008000000000002000084F626
+:10BE2000000800000000000200008504001000006F
+:10BE300000000004000087600000000000000020F7
+:10BE400000006000002000000000002000007300DF
+:10BE500000080000000000080000000300000000CF
+:10BE600000000000000000050000000000000000CD
+:10BE700000000006000000000000000000000007B5
+:10BE80000000000000000000000088080000000022
+:10BE900000000001000088280000000000000008E9
+:10BEA00000000050000000000000000000008810AA
+:10BEB00000000000000000040000881400000000E2
+:10BEC00000000004000088180000000000000004CA
+:10BED0000000881C00000000000000080000300086
+:10BEE0000040000000000008000030080040000092
+:10BEF000000000280000339001C00010000000087E
+:10BF00000000320000200000000000200000372068
+:10BF1000000000000000000800001020062000388B
+:10BF2000000000080000A000000000000000200049
+:10BF300000003EA9000000000000000100003EC813
+:10BF4000000000000000000280000000000000006F
+:10BF50000000000000006000002000000000000859
+:10BF60000000400000080000000000010000400147
+:10BF7000000800000000000100004040000800042C
+:10BF800000000002000040600008000400000004FF
+:10BF90000000400000080000000000040000400411
+:10BFA0000008000000000004000040400000000005
+:10BFB00000000008000040480000000000000008E9
+:10BFC0000000800000000000000000100000504051
+:10BFD000000100040000000100005000000000000B
+:10BFE00000000020000050080010000000000004C5
+:10BFF0000000500C0010000000000001000052C7BB
+:10C000000000000000000001000052C60000000017
+:10C0100000000001000030000030001800000004A3
+:10C020000000300400300018000000040000300858
+:10C0300000300018000000020000300A0030001834
+:10C04000000000020000300C003000180000000169
+:10C050000000300D00300018000000010000300E1C
+:10C0600000300018000000010000301000300018FF
+:10C07000000000040000301400300018000000042C
+:10C08000000050000100008000080004000050047F
+:10C0900001000080000800040000000A0000000009
+:10C0A0000000000000005068010000800000000156
+:10C0B0000000506901000080000000010000506C89
+:10C0C00001000080000000020000506E01000080AE
+:10C0D0000000000200005070010000800000000419
+:10C0E0000000507401000080000000040000506651
+:10C0F0000100008000000002000050640100008088
+:10C1000000000001000050600100008000000002FB
+:10C11000000050620100008000000002000050504A
+:10C120000100008000000004000050540100008065
+:10C1300000000004000050580100008000000004CE
+:10C140000000505C01000080000000040000507CF2
+:10C1500001000080000000010000507D010000800F
+:10C160000000000100004018001000000000000462
+:10C170000000409000100000000000040000409803
+:10C18000001000000000000400004110000000004A
+:10C190000000000200004112000000000000000248
+:10C1A00000004114000000000000000200004116E1
+:10C1B00000000000000000020000604000080000D5
+:10C1C00000000002000060420008000000000002C1
+:10C1D00000006044000800000000000400006080CF
+:10C1E0000008000000000008000060C000400008D7
+:10C1F00000000008000060000008000000000002CD
+:10C20000000060020008000000000001000060045F
+:10C210000008000000000002000063400008000069
+:10C220000000000800006380000800000000000417
+:10C23000000063840008000000000001000063C0EB
+:10C240000008000000000002000063C400080000B5
+:10C25000000000020000640000080000000000046C
+:10C2600000007000001000000000000400007004D6
+:10C270000010000000000004000070080010000022
+:10C280000000000400009000000800000000000210
+:10C29000000090020008000000000001000090046F
+:10C2A00000080000000000020000904000080000AC
+:10C2B000000000020000904400080000000000029E
+:10C2C00000009046000800000000000200009648B0
+:10C2D0000008000000000008000090800008000036
+:10C2E000000000020000908400080000000000022E
+:10C2F0000000968800080000000000080000804050
+:10C30000000800000000000100008041000800005B
+:10C310000000000100008042000800000000000151
+:10C3200000008043000800000000000100008000C1
+:10C330000008000000000002000080020008000069
+:10C34000000000010000800400080000000000025E
+:10C35000000080C00008000000000002000080C251
+:10C360000008000000000002000080C40008000077
+:10C3700000000002000080800008000000000001B2
+:10C3800000008081000800000000000100008082A1
+:10C390000008000000000001000080830008000089
+:10C3A000000000010000808400080000000000017F
+:10C3B0000000808500080000000000010000808669
+:10C3C00000080000000000010000600000080000FC
+:10C3D00000000002000060020008000000000001F0
+:10C3E000000060040008000000000002000060423D
+:10C3F00000C00018000000020000604000C00018EB
+:10C40000000000020000604C00C00018000000089E
+:10C410000000604400C000180000000800006057E1
+:10C4200000C00018000000010000605400C00018A7
+:10C43000000000020000605600C00018000000016B
+:10C440000000664000080000000000080000668050
+:10C450000008000000000008000066C0000800009E
+:10C46000000000080000DA4200180000000000028E
+:10C470000000DE4000000000000000000000E000BE
+:10C4800000000000000000040000D0C00000000018
+:10C49000000000040000D0C4000000000000000400
+:10C4A0000000D0C800000000000000040000D0CC54
+:10C4B00000000000000000040000D0D000000000D8
+:10C4C000000000040000D0D40000000000000004C0
+:10C4D0000000D0D800000000000000040000D0C020
+:10C4E00000000000000000200000DB000000000051
+:10C4F000000000040000DB000000000000000068F5
+:10C500000000B94800000000000000000000D0005A
+:10C5100000000000000000040000B0C000000000A7
+:10C52000000000040000B0C400000000000000048F
+:10C530000000B0C800000000000000040000B0C00F
+:10C5400000000000000000100000D6B00000000055
+:10C55000000000040000D6B4000000000000000449
+:10C560000000D6B800000000000000040000D6BCA7
+:10C5700000000000000000040000D6B00000000031
+:10C58000000000100000D348000000000000000878
+:10C590000000D358000000000000008000000010E0
+:10C5A00000000000000000000000D3580000000060
+:10C5B0000000000800000000060205000000000066
+:00000001FF
diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig
index 7e0511476797..814ac4e213a8 100644
--- a/fs/9p/Kconfig
+++ b/fs/9p/Kconfig
@@ -9,6 +9,8 @@ config 9P_FS
If unsure, say N.
+if 9P_FS
+
config 9P_FSCACHE
bool "Enable 9P client caching support (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -20,7 +22,6 @@ config 9P_FSCACHE
config 9P_FS_POSIX_ACL
bool "9P POSIX Access Control Lists"
- depends on 9P_FS
select FS_POSIX_ACL
help
POSIX Access Control Lists (ACLs) support permissions for users and
@@ -30,3 +31,5 @@ config 9P_FS_POSIX_ACL
Linux website <http://acl.bestbits.at/>.
If you don't know what Access Control Lists are, say N
+
+endif
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index f8ba37effd1b..ab8c12780634 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_9P_FS) := 9p.o
9p-objs := \
vfs_super.o \
vfs_inode.o \
+ vfs_inode_dotl.o \
vfs_addr.o \
vfs_file.o \
vfs_dir.o \
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 12d602351dbe..e4c20d63e6d0 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -28,7 +28,7 @@ static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
{
ssize_t size;
void *value = NULL;
- struct posix_acl *acl = NULL;;
+ struct posix_acl *acl = NULL;
size = v9fs_fid_xattr_get(fid, name, NULL, 0);
if (size > 0) {
@@ -362,7 +362,7 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT;
if (!S_ISDIR(inode->i_mode)) {
- retval = -EINVAL;
+ retval = acl ? -EINVAL : 0;
goto err_out;
}
break;
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index cb6396855e2d..71d0ed3dfbbf 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -138,3 +138,39 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2000L;
}
+
+extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nameidata);
+extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
+extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
+extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);
+extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
+ void *p);
+extern struct inode *v9fs_inode(struct v9fs_session_info *v9ses,
+ struct p9_fid *fid,
+ struct super_block *sb);
+
+extern const struct inode_operations v9fs_dir_inode_operations_dotl;
+extern const struct inode_operations v9fs_file_inode_operations_dotl;
+extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
+extern struct inode *v9fs_inode_dotl(struct v9fs_session_info *v9ses,
+ struct p9_fid *fid,
+ struct super_block *sb);
+/**
+ * v9fs_inode_from_fid - Helper routine to populate an inode by
+ * issuing a attribute request
+ * @v9ses: session information
+ * @fid: fid to issue attribute request for
+ * @sb: superblock on which to create inode
+ *
+ */
+static inline struct inode *
+v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ struct super_block *sb)
+{
+ if (v9fs_proto_dotl(v9ses))
+ return v9fs_inode_dotl(v9ses, fid, sb);
+ else
+ return v9fs_inode(v9ses, fid, sb);
+}
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index cbf4e50f3933..466d2a4fc5cb 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -51,7 +51,7 @@
*
*/
-static int v9fs_dentry_delete(struct dentry *dentry)
+static int v9fs_dentry_delete(const struct dentry *dentry)
{
P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_name.name,
dentry);
@@ -68,7 +68,7 @@ static int v9fs_dentry_delete(struct dentry *dentry)
*
*/
-static int v9fs_cached_dentry_delete(struct dentry *dentry)
+static int v9fs_cached_dentry_delete(const struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_name.name,
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 34bf71b56542..3df85559e5ed 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -44,20 +44,11 @@
#include "v9fs_vfs.h"
#include "fid.h"
#include "cache.h"
-#include "xattr.h"
-#include "acl.h"
static const struct inode_operations v9fs_dir_inode_operations;
static const struct inode_operations v9fs_dir_inode_operations_dotu;
-static const struct inode_operations v9fs_dir_inode_operations_dotl;
static const struct inode_operations v9fs_file_inode_operations;
-static const struct inode_operations v9fs_file_inode_operations_dotl;
static const struct inode_operations v9fs_symlink_inode_operations;
-static const struct inode_operations v9fs_symlink_inode_operations_dotl;
-
-static int
-v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
- dev_t rdev);
/**
* unixmode2p9mode - convert unix mode bits to plan 9
@@ -237,46 +228,18 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
*
*/
-void v9fs_destroy_inode(struct inode *inode)
+static void v9fs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode));
}
-#endif
-/**
- * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
- * new file system object. This checks the S_ISGID to determine the owning
- * group of the new file system object.
- */
-
-static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
-{
- BUG_ON(dir_inode == NULL);
-
- if (dir_inode->i_mode & S_ISGID) {
- /* set_gid bit is set.*/
- return dir_inode->i_gid;
- }
- return current_fsgid();
-}
-
-/**
- * v9fs_dentry_from_dir_inode - helper function to get the dentry from
- * dir inode.
- *
- */
-
-static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
+void v9fs_destroy_inode(struct inode *inode)
{
- struct dentry *dentry;
-
- spin_lock(&dcache_lock);
- /* Directory should have only one entry. */
- BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
- dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
- spin_unlock(&dcache_lock);
- return dentry;
+ call_rcu(&inode->i_rcu, v9fs_i_callback);
}
+#endif
/**
* v9fs_get_inode - helper function to setup an inode
@@ -447,7 +410,7 @@ void v9fs_evict_inode(struct inode *inode)
#endif
}
-static struct inode *
+struct inode *
v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
@@ -482,60 +445,6 @@ error:
return ERR_PTR(err);
}
-static struct inode *
-v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
- struct super_block *sb)
-{
- struct inode *ret = NULL;
- int err;
- struct p9_stat_dotl *st;
-
- st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
- if (IS_ERR(st))
- return ERR_CAST(st);
-
- ret = v9fs_get_inode(sb, st->st_mode);
- if (IS_ERR(ret)) {
- err = PTR_ERR(ret);
- goto error;
- }
-
- v9fs_stat2inode_dotl(st, ret);
- ret->i_ino = v9fs_qid2ino(&st->qid);
-#ifdef CONFIG_9P_FSCACHE
- v9fs_vcookie_set_qid(ret, &st->qid);
- v9fs_cache_inode_get_cookie(ret);
-#endif
- err = v9fs_get_acl(ret, fid);
- if (err) {
- iput(ret);
- goto error;
- }
- kfree(st);
- return ret;
-error:
- kfree(st);
- return ERR_PTR(err);
-}
-
-/**
- * v9fs_inode_from_fid - Helper routine to populate an inode by
- * issuing a attribute request
- * @v9ses: session information
- * @fid: fid to issue attribute request for
- * @sb: superblock on which to create inode
- *
- */
-static inline struct inode *
-v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
- struct super_block *sb)
-{
- if (v9fs_proto_dotl(v9ses))
- return v9fs_inode_dotl(v9ses, fid, sb);
- else
- return v9fs_inode(v9ses, fid, sb);
-}
-
/**
* v9fs_remove - helper function to remove files and directories
* @dir: directory inode that is being deleted
@@ -628,9 +537,9 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
}
if (v9ses->cache)
- dentry->d_op = &v9fs_cached_dentry_operations;
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
else
- dentry->d_op = &v9fs_dentry_operations;
+ d_set_d_op(dentry, &v9fs_dentry_operations);
d_instantiate(dentry, inode);
err = v9fs_fid_add(dentry, fid);
@@ -650,144 +559,6 @@ error:
}
/**
- * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
- * @dir: directory inode that is being created
- * @dentry: dentry that is being deleted
- * @mode: create permissions
- * @nd: path information
- *
- */
-
-static int
-v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
- struct nameidata *nd)
-{
- int err = 0;
- char *name = NULL;
- gid_t gid;
- int flags;
- mode_t mode;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid = NULL;
- struct p9_fid *dfid, *ofid;
- struct file *filp;
- struct p9_qid qid;
- struct inode *inode;
- struct posix_acl *pacl = NULL, *dacl = NULL;
-
- v9ses = v9fs_inode2v9ses(dir);
- if (nd && nd->flags & LOOKUP_OPEN)
- flags = nd->intent.open.flags - 1;
- else {
- /*
- * create call without LOOKUP_OPEN is due
- * to mknod of regular files. So use mknod
- * operation.
- */
- return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
- }
-
- name = (char *) dentry->d_name.name;
- P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
- "mode:0x%x\n", name, flags, omode);
-
- dfid = v9fs_fid_lookup(dentry->d_parent);
- if (IS_ERR(dfid)) {
- err = PTR_ERR(dfid);
- P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
- return err;
- }
-
- /* clone a fid to use for creation */
- ofid = p9_client_walk(dfid, 0, NULL, 1);
- if (IS_ERR(ofid)) {
- err = PTR_ERR(ofid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
- return err;
- }
-
- gid = v9fs_get_fsgid_for_create(dir);
-
- mode = omode;
- /* Update mode based on ACL value */
- err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
- if (err) {
- P9_DPRINTK(P9_DEBUG_VFS,
- "Failed to get acl values in creat %d\n", err);
- goto error;
- }
- err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
- if (err < 0) {
- P9_DPRINTK(P9_DEBUG_VFS,
- "p9_client_open_dotl failed in creat %d\n",
- err);
- goto error;
- }
- /* instantiate inode and assign the unopened fid to the dentry */
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE ||
- (nd && nd->flags & LOOKUP_OPEN)) {
- fid = p9_client_walk(dfid, 1, &name, 1);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
- err);
- fid = NULL;
- goto error;
- }
-
- inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
- err);
- goto error;
- }
- dentry->d_op = &v9fs_cached_dentry_operations;
- d_instantiate(dentry, inode);
- err = v9fs_fid_add(dentry, fid);
- if (err < 0)
- goto error;
- /* The fid would get clunked via a dput */
- fid = NULL;
- } else {
- /*
- * Not in cached mode. No need to populate
- * inode with stat. We need to get an inode
- * so that we can set the acl with dentry
- */
- inode = v9fs_get_inode(dir->i_sb, mode);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- goto error;
- }
- dentry->d_op = &v9fs_dentry_operations;
- d_instantiate(dentry, inode);
- }
- /* Now set the ACL based on the default value */
- v9fs_set_create_acl(dentry, dacl, pacl);
-
- /* if we are opening a file, assign the open fid to the file */
- if (nd && nd->flags & LOOKUP_OPEN) {
- filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
- if (IS_ERR(filp)) {
- p9_client_clunk(ofid);
- return PTR_ERR(filp);
- }
- filp->private_data = ofid;
- } else
- p9_client_clunk(ofid);
-
- return 0;
-
-error:
- if (ofid)
- p9_client_clunk(ofid);
- if (fid)
- p9_client_clunk(fid);
- return err;
-}
-
-/**
* v9fs_vfs_create - VFS hook to create files
* @dir: directory inode that is being created
* @dentry: dentry that is being deleted
@@ -877,107 +648,6 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
return err;
}
-
-/**
- * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
- * @dir: inode that is being unlinked
- * @dentry: dentry that is being unlinked
- * @mode: mode for new directory
- *
- */
-
-static int v9fs_vfs_mkdir_dotl(struct inode *dir,
- struct dentry *dentry, int omode)
-{
- int err;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid = NULL, *dfid = NULL;
- gid_t gid;
- char *name;
- mode_t mode;
- struct inode *inode;
- struct p9_qid qid;
- struct dentry *dir_dentry;
- struct posix_acl *dacl = NULL, *pacl = NULL;
-
- P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
- err = 0;
- v9ses = v9fs_inode2v9ses(dir);
-
- omode |= S_IFDIR;
- if (dir->i_mode & S_ISGID)
- omode |= S_ISGID;
-
- dir_dentry = v9fs_dentry_from_dir_inode(dir);
- dfid = v9fs_fid_lookup(dir_dentry);
- if (IS_ERR(dfid)) {
- err = PTR_ERR(dfid);
- P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
- dfid = NULL;
- goto error;
- }
-
- gid = v9fs_get_fsgid_for_create(dir);
- mode = omode;
- /* Update mode based on ACL value */
- err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
- if (err) {
- P9_DPRINTK(P9_DEBUG_VFS,
- "Failed to get acl values in mkdir %d\n", err);
- goto error;
- }
- name = (char *) dentry->d_name.name;
- err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
- if (err < 0)
- goto error;
-
- /* instantiate inode and assign the unopened fid to the dentry */
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
- fid = p9_client_walk(dfid, 1, &name, 1);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
- err);
- fid = NULL;
- goto error;
- }
-
- inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
- err);
- goto error;
- }
- dentry->d_op = &v9fs_cached_dentry_operations;
- d_instantiate(dentry, inode);
- err = v9fs_fid_add(dentry, fid);
- if (err < 0)
- goto error;
- fid = NULL;
- } else {
- /*
- * Not in cached mode. No need to populate
- * inode with stat. We need to get an inode
- * so that we can set the acl with dentry
- */
- inode = v9fs_get_inode(dir->i_sb, mode);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- goto error;
- }
- dentry->d_op = &v9fs_dentry_operations;
- d_instantiate(dentry, inode);
- }
- /* Now set the ACL based on the default value */
- v9fs_set_create_acl(dentry, dacl, pacl);
-
-error:
- if (fid)
- p9_client_clunk(fid);
- return err;
-}
-
/**
* v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
* @dir: inode that is being walked from
@@ -986,8 +656,8 @@ error:
*
*/
-static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
- struct nameidata *nameidata)
+struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nameidata)
{
struct super_block *sb;
struct v9fs_session_info *v9ses;
@@ -1034,9 +704,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
inst_out:
if (v9ses->cache)
- dentry->d_op = &v9fs_cached_dentry_operations;
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
else
- dentry->d_op = &v9fs_dentry_operations;
+ d_set_d_op(dentry, &v9fs_dentry_operations);
d_add(dentry, inode);
return NULL;
@@ -1056,7 +726,7 @@ error:
*
*/
-static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
+int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
{
return v9fs_remove(i, d, 0);
}
@@ -1068,7 +738,7 @@ static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
*
*/
-static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
+int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
{
return v9fs_remove(i, d, 1);
}
@@ -1082,7 +752,7 @@ static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
*
*/
-static int
+int
v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
@@ -1189,42 +859,6 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
return 0;
}
-static int
-v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat)
-{
- int err;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid;
- struct p9_stat_dotl *st;
-
- P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
- err = -EPERM;
- v9ses = v9fs_inode2v9ses(dentry->d_inode);
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
- return simple_getattr(mnt, dentry, stat);
-
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- /* Ask for all the fields in stat structure. Server will return
- * whatever it supports
- */
-
- st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
- if (IS_ERR(st))
- return PTR_ERR(st);
-
- v9fs_stat2inode_dotl(st, dentry->d_inode);
- generic_fillattr(dentry->d_inode, stat);
- /* Change block size to what the server returned */
- stat->blksize = st->st_blksize;
-
- kfree(st);
- return 0;
-}
-
/**
* v9fs_vfs_setattr - set file metadata
* @dentry: file whose metadata to set
@@ -1284,64 +918,6 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
}
/**
- * v9fs_vfs_setattr_dotl - set file metadata
- * @dentry: file whose metadata to set
- * @iattr: metadata assignment structure
- *
- */
-
-int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
-{
- int retval;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid;
- struct p9_iattr_dotl p9attr;
-
- P9_DPRINTK(P9_DEBUG_VFS, "\n");
-
- retval = inode_change_ok(dentry->d_inode, iattr);
- if (retval)
- return retval;
-
- p9attr.valid = iattr->ia_valid;
- p9attr.mode = iattr->ia_mode;
- p9attr.uid = iattr->ia_uid;
- p9attr.gid = iattr->ia_gid;
- p9attr.size = iattr->ia_size;
- p9attr.atime_sec = iattr->ia_atime.tv_sec;
- p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
- p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
- p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
-
- retval = -EPERM;
- v9ses = v9fs_inode2v9ses(dentry->d_inode);
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- retval = p9_client_setattr(fid, &p9attr);
- if (retval < 0)
- return retval;
-
- if ((iattr->ia_valid & ATTR_SIZE) &&
- iattr->ia_size != i_size_read(dentry->d_inode)) {
- retval = vmtruncate(dentry->d_inode, iattr->ia_size);
- if (retval)
- return retval;
- }
-
- setattr_copy(dentry->d_inode, iattr);
- mark_inode_dirty(dentry->d_inode);
- if (iattr->ia_valid & ATTR_MODE) {
- /* We also want to update ACL when we update mode bits */
- retval = v9fs_acl_chmod(dentry);
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-/**
* v9fs_stat2inode - populate an inode structure with mistat info
* @stat: Plan 9 metadata (mistat) structure
* @inode: inode to populate
@@ -1419,77 +995,6 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
}
/**
- * v9fs_stat2inode_dotl - populate an inode structure with stat info
- * @stat: stat structure
- * @inode: inode to populate
- * @sb: superblock of filesystem
- *
- */
-
-void
-v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
-{
-
- if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
- inode->i_atime.tv_sec = stat->st_atime_sec;
- inode->i_atime.tv_nsec = stat->st_atime_nsec;
- inode->i_mtime.tv_sec = stat->st_mtime_sec;
- inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
- inode->i_ctime.tv_sec = stat->st_ctime_sec;
- inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
- inode->i_uid = stat->st_uid;
- inode->i_gid = stat->st_gid;
- inode->i_nlink = stat->st_nlink;
- inode->i_mode = stat->st_mode;
- inode->i_rdev = new_decode_dev(stat->st_rdev);
-
- if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
- init_special_inode(inode, inode->i_mode, inode->i_rdev);
-
- i_size_write(inode, stat->st_size);
- inode->i_blocks = stat->st_blocks;
- } else {
- if (stat->st_result_mask & P9_STATS_ATIME) {
- inode->i_atime.tv_sec = stat->st_atime_sec;
- inode->i_atime.tv_nsec = stat->st_atime_nsec;
- }
- if (stat->st_result_mask & P9_STATS_MTIME) {
- inode->i_mtime.tv_sec = stat->st_mtime_sec;
- inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
- }
- if (stat->st_result_mask & P9_STATS_CTIME) {
- inode->i_ctime.tv_sec = stat->st_ctime_sec;
- inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
- }
- if (stat->st_result_mask & P9_STATS_UID)
- inode->i_uid = stat->st_uid;
- if (stat->st_result_mask & P9_STATS_GID)
- inode->i_gid = stat->st_gid;
- if (stat->st_result_mask & P9_STATS_NLINK)
- inode->i_nlink = stat->st_nlink;
- if (stat->st_result_mask & P9_STATS_MODE) {
- inode->i_mode = stat->st_mode;
- if ((S_ISBLK(inode->i_mode)) ||
- (S_ISCHR(inode->i_mode)))
- init_special_inode(inode, inode->i_mode,
- inode->i_rdev);
- }
- if (stat->st_result_mask & P9_STATS_RDEV)
- inode->i_rdev = new_decode_dev(stat->st_rdev);
- if (stat->st_result_mask & P9_STATS_SIZE)
- i_size_write(inode, stat->st_size);
- if (stat->st_result_mask & P9_STATS_BLOCKS)
- inode->i_blocks = stat->st_blocks;
- }
- if (stat->st_result_mask & P9_STATS_GEN)
- inode->i_generation = stat->st_gen;
-
- /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
- * because the inode structure does not have fields for them.
- */
-}
-
-/**
* v9fs_qid2ino - convert qid into inode number
* @qid: qid to hash
*
@@ -1595,7 +1100,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
*
*/
-static void
+void
v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{
char *s = nd_get_link(nd);
@@ -1639,94 +1144,6 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
}
/**
- * v9fs_vfs_symlink_dotl - helper function to create symlinks
- * @dir: directory inode containing symlink
- * @dentry: dentry for symlink
- * @symname: symlink data
- *
- * See Also: 9P2000.L RFC for more information
- *
- */
-
-static int
-v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
- const char *symname)
-{
- struct v9fs_session_info *v9ses;
- struct p9_fid *dfid;
- struct p9_fid *fid = NULL;
- struct inode *inode;
- struct p9_qid qid;
- char *name;
- int err;
- gid_t gid;
-
- name = (char *) dentry->d_name.name;
- P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
- dir->i_ino, name, symname);
- v9ses = v9fs_inode2v9ses(dir);
-
- dfid = v9fs_fid_lookup(dentry->d_parent);
- if (IS_ERR(dfid)) {
- err = PTR_ERR(dfid);
- P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
- return err;
- }
-
- gid = v9fs_get_fsgid_for_create(dir);
-
- /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
- err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
-
- if (err < 0) {
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
- goto error;
- }
-
- if (v9ses->cache) {
- /* Now walk from the parent so we can get an unopened fid. */
- fid = p9_client_walk(dfid, 1, &name, 1);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
- err);
- fid = NULL;
- goto error;
- }
-
- /* instantiate inode and assign the unopened fid to dentry */
- inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
- err);
- goto error;
- }
- dentry->d_op = &v9fs_cached_dentry_operations;
- d_instantiate(dentry, inode);
- err = v9fs_fid_add(dentry, fid);
- if (err < 0)
- goto error;
- fid = NULL;
- } else {
- /* Not in cached mode. No need to populate inode with stat */
- inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- goto error;
- }
- dentry->d_op = &v9fs_dentry_operations;
- d_instantiate(dentry, inode);
- }
-
-error:
- if (fid)
- p9_client_clunk(fid);
-
- return err;
-}
-
-/**
* v9fs_vfs_symlink - helper function to create symlinks
* @dir: directory inode containing symlink
* @dentry: dentry for symlink
@@ -1785,77 +1202,6 @@ clunk_fid:
}
/**
- * v9fs_vfs_link_dotl - create a hardlink for dotl
- * @old_dentry: dentry for file to link to
- * @dir: inode destination for new link
- * @dentry: dentry for link
- *
- */
-
-static int
-v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
- struct dentry *dentry)
-{
- int err;
- struct p9_fid *dfid, *oldfid;
- char *name;
- struct v9fs_session_info *v9ses;
- struct dentry *dir_dentry;
-
- P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
- dir->i_ino, old_dentry->d_name.name,
- dentry->d_name.name);
-
- v9ses = v9fs_inode2v9ses(dir);
- dir_dentry = v9fs_dentry_from_dir_inode(dir);
- dfid = v9fs_fid_lookup(dir_dentry);
- if (IS_ERR(dfid))
- return PTR_ERR(dfid);
-
- oldfid = v9fs_fid_lookup(old_dentry);
- if (IS_ERR(oldfid))
- return PTR_ERR(oldfid);
-
- name = (char *) dentry->d_name.name;
-
- err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
-
- if (err < 0) {
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
- return err;
- }
-
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
- /* Get the latest stat info from server. */
- struct p9_fid *fid;
- struct p9_stat_dotl *st;
-
- fid = v9fs_fid_lookup(old_dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
- if (IS_ERR(st))
- return PTR_ERR(st);
-
- v9fs_stat2inode_dotl(st, old_dentry->d_inode);
-
- kfree(st);
- } else {
- /* Caching disabled. No need to get upto date stat info.
- * This dentry will be released immediately. So, just hold the
- * inode
- */
- ihold(old_dentry->d_inode);
- }
-
- dentry->d_op = old_dentry->d_op;
- d_instantiate(dentry, old_dentry->d_inode);
-
- return err;
-}
-
-/**
* v9fs_vfs_mknod - create a special file
* @dir: inode destination for new link
* @dentry: dentry for file
@@ -1900,160 +1246,6 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
return retval;
}
-/**
- * v9fs_vfs_mknod_dotl - create a special file
- * @dir: inode destination for new link
- * @dentry: dentry for file
- * @mode: mode for creation
- * @rdev: device associated with special file
- *
- */
-static int
-v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
- dev_t rdev)
-{
- int err;
- char *name;
- mode_t mode;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid = NULL, *dfid = NULL;
- struct inode *inode;
- gid_t gid;
- struct p9_qid qid;
- struct dentry *dir_dentry;
- struct posix_acl *dacl = NULL, *pacl = NULL;
-
- P9_DPRINTK(P9_DEBUG_VFS,
- " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
- dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
-
- if (!new_valid_dev(rdev))
- return -EINVAL;
-
- v9ses = v9fs_inode2v9ses(dir);
- dir_dentry = v9fs_dentry_from_dir_inode(dir);
- dfid = v9fs_fid_lookup(dir_dentry);
- if (IS_ERR(dfid)) {
- err = PTR_ERR(dfid);
- P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
- dfid = NULL;
- goto error;
- }
-
- gid = v9fs_get_fsgid_for_create(dir);
- mode = omode;
- /* Update mode based on ACL value */
- err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
- if (err) {
- P9_DPRINTK(P9_DEBUG_VFS,
- "Failed to get acl values in mknod %d\n", err);
- goto error;
- }
- name = (char *) dentry->d_name.name;
-
- err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
- if (err < 0)
- goto error;
-
- /* instantiate inode and assign the unopened fid to the dentry */
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
- fid = p9_client_walk(dfid, 1, &name, 1);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
- err);
- fid = NULL;
- goto error;
- }
-
- inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
- err);
- goto error;
- }
- dentry->d_op = &v9fs_cached_dentry_operations;
- d_instantiate(dentry, inode);
- err = v9fs_fid_add(dentry, fid);
- if (err < 0)
- goto error;
- fid = NULL;
- } else {
- /*
- * Not in cached mode. No need to populate inode with stat.
- * socket syscall returns a fd, so we need instantiate
- */
- inode = v9fs_get_inode(dir->i_sb, mode);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- goto error;
- }
- dentry->d_op = &v9fs_dentry_operations;
- d_instantiate(dentry, inode);
- }
- /* Now set the ACL based on the default value */
- v9fs_set_create_acl(dentry, dacl, pacl);
-error:
- if (fid)
- p9_client_clunk(fid);
- return err;
-}
-
-static int
-v9fs_vfs_readlink_dotl(struct dentry *dentry, char *buffer, int buflen)
-{
- int retval;
- struct p9_fid *fid;
- char *target = NULL;
-
- P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
- retval = -EPERM;
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- retval = p9_client_readlink(fid, &target);
- if (retval < 0)
- return retval;
-
- strncpy(buffer, target, buflen);
- P9_DPRINTK(P9_DEBUG_VFS, "%s -> %s\n", dentry->d_name.name, buffer);
-
- retval = strnlen(buffer, buflen);
- return retval;
-}
-
-/**
- * v9fs_vfs_follow_link_dotl - follow a symlink path
- * @dentry: dentry for symlink
- * @nd: nameidata
- *
- */
-
-static void *
-v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
-{
- int len = 0;
- char *link = __getname();
-
- P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
-
- if (!link)
- link = ERR_PTR(-ENOMEM);
- else {
- len = v9fs_vfs_readlink_dotl(dentry, link, PATH_MAX);
- if (len < 0) {
- __putname(link);
- link = ERR_PTR(len);
- } else
- link[min(len, PATH_MAX-1)] = 0;
- }
- nd_set_link(nd, link);
-
- return NULL;
-}
-
static const struct inode_operations v9fs_dir_inode_operations_dotu = {
.create = v9fs_vfs_create,
.lookup = v9fs_vfs_lookup,
@@ -2068,25 +1260,6 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
.setattr = v9fs_vfs_setattr,
};
-static const struct inode_operations v9fs_dir_inode_operations_dotl = {
- .create = v9fs_vfs_create_dotl,
- .lookup = v9fs_vfs_lookup,
- .link = v9fs_vfs_link_dotl,
- .symlink = v9fs_vfs_symlink_dotl,
- .unlink = v9fs_vfs_unlink,
- .mkdir = v9fs_vfs_mkdir_dotl,
- .rmdir = v9fs_vfs_rmdir,
- .mknod = v9fs_vfs_mknod_dotl,
- .rename = v9fs_vfs_rename,
- .getattr = v9fs_vfs_getattr_dotl,
- .setattr = v9fs_vfs_setattr_dotl,
- .setxattr = generic_setxattr,
- .getxattr = generic_getxattr,
- .removexattr = generic_removexattr,
- .listxattr = v9fs_listxattr,
- .check_acl = v9fs_check_acl,
-};
-
static const struct inode_operations v9fs_dir_inode_operations = {
.create = v9fs_vfs_create,
.lookup = v9fs_vfs_lookup,
@@ -2104,16 +1277,6 @@ static const struct inode_operations v9fs_file_inode_operations = {
.setattr = v9fs_vfs_setattr,
};
-static const struct inode_operations v9fs_file_inode_operations_dotl = {
- .getattr = v9fs_vfs_getattr_dotl,
- .setattr = v9fs_vfs_setattr_dotl,
- .setxattr = generic_setxattr,
- .getxattr = generic_getxattr,
- .removexattr = generic_removexattr,
- .listxattr = v9fs_listxattr,
- .check_acl = v9fs_check_acl,
-};
-
static const struct inode_operations v9fs_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = v9fs_vfs_follow_link,
@@ -2121,15 +1284,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = {
.getattr = v9fs_vfs_getattr,
.setattr = v9fs_vfs_setattr,
};
-
-static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
- .readlink = v9fs_vfs_readlink_dotl,
- .follow_link = v9fs_vfs_follow_link_dotl,
- .put_link = v9fs_vfs_put_link,
- .getattr = v9fs_vfs_getattr_dotl,
- .setattr = v9fs_vfs_setattr_dotl,
- .setxattr = generic_setxattr,
- .getxattr = generic_getxattr,
- .removexattr = generic_removexattr,
- .listxattr = v9fs_listxattr,
-};
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
new file mode 100644
index 000000000000..9dd534b4d9f7
--- /dev/null
+++ b/fs/9p/vfs_inode_dotl.c
@@ -0,0 +1,880 @@
+/*
+ * linux/fs/9p/vfs_inode.c
+ *
+ * This file contains vfs inode ops for the 9P2000 protocol.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can 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:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/inet.h>
+#include <linux/namei.h>
+#include <linux/idr.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/xattr.h>
+#include <linux/posix_acl.h>
+#include <net/9p/9p.h>
+#include <net/9p/client.h>
+
+#include "v9fs.h"
+#include "v9fs_vfs.h"
+#include "fid.h"
+#include "cache.h"
+#include "xattr.h"
+#include "acl.h"
+
+static int
+v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
+ dev_t rdev);
+
+/**
+ * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
+ * new file system object. This checks the S_ISGID to determine the owning
+ * group of the new file system object.
+ */
+
+static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
+{
+ BUG_ON(dir_inode == NULL);
+
+ if (dir_inode->i_mode & S_ISGID) {
+ /* set_gid bit is set.*/
+ return dir_inode->i_gid;
+ }
+ return current_fsgid();
+}
+
+/**
+ * v9fs_dentry_from_dir_inode - helper function to get the dentry from
+ * dir inode.
+ *
+ */
+
+static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
+{
+ struct dentry *dentry;
+
+ spin_lock(&inode->i_lock);
+ /* Directory should have only one entry. */
+ BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
+ dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
+ spin_unlock(&inode->i_lock);
+ return dentry;
+}
+
+struct inode *
+v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ struct super_block *sb)
+{
+ struct inode *ret = NULL;
+ int err;
+ struct p9_stat_dotl *st;
+
+ st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
+ if (IS_ERR(st))
+ return ERR_CAST(st);
+
+ ret = v9fs_get_inode(sb, st->st_mode);
+ if (IS_ERR(ret)) {
+ err = PTR_ERR(ret);
+ goto error;
+ }
+
+ v9fs_stat2inode_dotl(st, ret);
+ ret->i_ino = v9fs_qid2ino(&st->qid);
+#ifdef CONFIG_9P_FSCACHE
+ v9fs_vcookie_set_qid(ret, &st->qid);
+ v9fs_cache_inode_get_cookie(ret);
+#endif
+ err = v9fs_get_acl(ret, fid);
+ if (err) {
+ iput(ret);
+ goto error;
+ }
+ kfree(st);
+ return ret;
+error:
+ kfree(st);
+ return ERR_PTR(err);
+}
+
+/**
+ * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
+ * @dir: directory inode that is being created
+ * @dentry: dentry that is being deleted
+ * @mode: create permissions
+ * @nd: path information
+ *
+ */
+
+static int
+v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
+ struct nameidata *nd)
+{
+ int err = 0;
+ char *name = NULL;
+ gid_t gid;
+ int flags;
+ mode_t mode;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid = NULL;
+ struct p9_fid *dfid, *ofid;
+ struct file *filp;
+ struct p9_qid qid;
+ struct inode *inode;
+ struct posix_acl *pacl = NULL, *dacl = NULL;
+
+ v9ses = v9fs_inode2v9ses(dir);
+ if (nd && nd->flags & LOOKUP_OPEN)
+ flags = nd->intent.open.flags - 1;
+ else {
+ /*
+ * create call without LOOKUP_OPEN is due
+ * to mknod of regular files. So use mknod
+ * operation.
+ */
+ return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
+ }
+
+ name = (char *) dentry->d_name.name;
+ P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
+ "mode:0x%x\n", name, flags, omode);
+
+ dfid = v9fs_fid_lookup(dentry->d_parent);
+ if (IS_ERR(dfid)) {
+ err = PTR_ERR(dfid);
+ P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
+ return err;
+ }
+
+ /* clone a fid to use for creation */
+ ofid = p9_client_walk(dfid, 0, NULL, 1);
+ if (IS_ERR(ofid)) {
+ err = PTR_ERR(ofid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
+ return err;
+ }
+
+ gid = v9fs_get_fsgid_for_create(dir);
+
+ mode = omode;
+ /* Update mode based on ACL value */
+ err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_VFS,
+ "Failed to get acl values in creat %d\n", err);
+ goto error;
+ }
+ err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS,
+ "p9_client_open_dotl failed in creat %d\n",
+ err);
+ goto error;
+ }
+ /* instantiate inode and assign the unopened fid to the dentry */
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE ||
+ (nd && nd->flags & LOOKUP_OPEN)) {
+ fid = p9_client_walk(dfid, 1, &name, 1);
+ if (IS_ERR(fid)) {
+ err = PTR_ERR(fid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
+ err);
+ fid = NULL;
+ goto error;
+ }
+
+ inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
+ err);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
+ d_instantiate(dentry, inode);
+ err = v9fs_fid_add(dentry, fid);
+ if (err < 0)
+ goto error;
+ /* The fid would get clunked via a dput */
+ fid = NULL;
+ } else {
+ /*
+ * Not in cached mode. No need to populate
+ * inode with stat. We need to get an inode
+ * so that we can set the acl with dentry
+ */
+ inode = v9fs_get_inode(dir->i_sb, mode);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_dentry_operations);
+ d_instantiate(dentry, inode);
+ }
+ /* Now set the ACL based on the default value */
+ v9fs_set_create_acl(dentry, dacl, pacl);
+
+ /* if we are opening a file, assign the open fid to the file */
+ if (nd && nd->flags & LOOKUP_OPEN) {
+ filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
+ if (IS_ERR(filp)) {
+ p9_client_clunk(ofid);
+ return PTR_ERR(filp);
+ }
+ filp->private_data = ofid;
+ } else
+ p9_client_clunk(ofid);
+
+ return 0;
+
+error:
+ if (ofid)
+ p9_client_clunk(ofid);
+ if (fid)
+ p9_client_clunk(fid);
+ return err;
+}
+
+/**
+ * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
+ * @dir: inode that is being unlinked
+ * @dentry: dentry that is being unlinked
+ * @mode: mode for new directory
+ *
+ */
+
+static int v9fs_vfs_mkdir_dotl(struct inode *dir,
+ struct dentry *dentry, int omode)
+{
+ int err;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid = NULL, *dfid = NULL;
+ gid_t gid;
+ char *name;
+ mode_t mode;
+ struct inode *inode;
+ struct p9_qid qid;
+ struct dentry *dir_dentry;
+ struct posix_acl *dacl = NULL, *pacl = NULL;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
+ err = 0;
+ v9ses = v9fs_inode2v9ses(dir);
+
+ omode |= S_IFDIR;
+ if (dir->i_mode & S_ISGID)
+ omode |= S_ISGID;
+
+ dir_dentry = v9fs_dentry_from_dir_inode(dir);
+ dfid = v9fs_fid_lookup(dir_dentry);
+ if (IS_ERR(dfid)) {
+ err = PTR_ERR(dfid);
+ P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
+ dfid = NULL;
+ goto error;
+ }
+
+ gid = v9fs_get_fsgid_for_create(dir);
+ mode = omode;
+ /* Update mode based on ACL value */
+ err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_VFS,
+ "Failed to get acl values in mkdir %d\n", err);
+ goto error;
+ }
+ name = (char *) dentry->d_name.name;
+ err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
+ if (err < 0)
+ goto error;
+
+ /* instantiate inode and assign the unopened fid to the dentry */
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
+ fid = p9_client_walk(dfid, 1, &name, 1);
+ if (IS_ERR(fid)) {
+ err = PTR_ERR(fid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
+ err);
+ fid = NULL;
+ goto error;
+ }
+
+ inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
+ err);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
+ d_instantiate(dentry, inode);
+ err = v9fs_fid_add(dentry, fid);
+ if (err < 0)
+ goto error;
+ fid = NULL;
+ } else {
+ /*
+ * Not in cached mode. No need to populate
+ * inode with stat. We need to get an inode
+ * so that we can set the acl with dentry
+ */
+ inode = v9fs_get_inode(dir->i_sb, mode);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_dentry_operations);
+ d_instantiate(dentry, inode);
+ }
+ /* Now set the ACL based on the default value */
+ v9fs_set_create_acl(dentry, dacl, pacl);
+
+error:
+ if (fid)
+ p9_client_clunk(fid);
+ return err;
+}
+
+static int
+v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ int err;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid;
+ struct p9_stat_dotl *st;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
+ err = -EPERM;
+ v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
+ return simple_getattr(mnt, dentry, stat);
+
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ /* Ask for all the fields in stat structure. Server will return
+ * whatever it supports
+ */
+
+ st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
+ if (IS_ERR(st))
+ return PTR_ERR(st);
+
+ v9fs_stat2inode_dotl(st, dentry->d_inode);
+ generic_fillattr(dentry->d_inode, stat);
+ /* Change block size to what the server returned */
+ stat->blksize = st->st_blksize;
+
+ kfree(st);
+ return 0;
+}
+
+/**
+ * v9fs_vfs_setattr_dotl - set file metadata
+ * @dentry: file whose metadata to set
+ * @iattr: metadata assignment structure
+ *
+ */
+
+int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
+{
+ int retval;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid;
+ struct p9_iattr_dotl p9attr;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "\n");
+
+ retval = inode_change_ok(dentry->d_inode, iattr);
+ if (retval)
+ return retval;
+
+ p9attr.valid = iattr->ia_valid;
+ p9attr.mode = iattr->ia_mode;
+ p9attr.uid = iattr->ia_uid;
+ p9attr.gid = iattr->ia_gid;
+ p9attr.size = iattr->ia_size;
+ p9attr.atime_sec = iattr->ia_atime.tv_sec;
+ p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
+ p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
+ p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
+
+ retval = -EPERM;
+ v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ retval = p9_client_setattr(fid, &p9attr);
+ if (retval < 0)
+ return retval;
+
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(dentry->d_inode)) {
+ retval = vmtruncate(dentry->d_inode, iattr->ia_size);
+ if (retval)
+ return retval;
+ }
+
+ setattr_copy(dentry->d_inode, iattr);
+ mark_inode_dirty(dentry->d_inode);
+ if (iattr->ia_valid & ATTR_MODE) {
+ /* We also want to update ACL when we update mode bits */
+ retval = v9fs_acl_chmod(dentry);
+ if (retval < 0)
+ return retval;
+ }
+ return 0;
+}
+
+/**
+ * v9fs_stat2inode_dotl - populate an inode structure with stat info
+ * @stat: stat structure
+ * @inode: inode to populate
+ * @sb: superblock of filesystem
+ *
+ */
+
+void
+v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
+{
+
+ if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
+ inode->i_atime.tv_sec = stat->st_atime_sec;
+ inode->i_atime.tv_nsec = stat->st_atime_nsec;
+ inode->i_mtime.tv_sec = stat->st_mtime_sec;
+ inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
+ inode->i_ctime.tv_sec = stat->st_ctime_sec;
+ inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
+ inode->i_uid = stat->st_uid;
+ inode->i_gid = stat->st_gid;
+ inode->i_nlink = stat->st_nlink;
+ inode->i_mode = stat->st_mode;
+ inode->i_rdev = new_decode_dev(stat->st_rdev);
+
+ if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
+
+ i_size_write(inode, stat->st_size);
+ inode->i_blocks = stat->st_blocks;
+ } else {
+ if (stat->st_result_mask & P9_STATS_ATIME) {
+ inode->i_atime.tv_sec = stat->st_atime_sec;
+ inode->i_atime.tv_nsec = stat->st_atime_nsec;
+ }
+ if (stat->st_result_mask & P9_STATS_MTIME) {
+ inode->i_mtime.tv_sec = stat->st_mtime_sec;
+ inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
+ }
+ if (stat->st_result_mask & P9_STATS_CTIME) {
+ inode->i_ctime.tv_sec = stat->st_ctime_sec;
+ inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
+ }
+ if (stat->st_result_mask & P9_STATS_UID)
+ inode->i_uid = stat->st_uid;
+ if (stat->st_result_mask & P9_STATS_GID)
+ inode->i_gid = stat->st_gid;
+ if (stat->st_result_mask & P9_STATS_NLINK)
+ inode->i_nlink = stat->st_nlink;
+ if (stat->st_result_mask & P9_STATS_MODE) {
+ inode->i_mode = stat->st_mode;
+ if ((S_ISBLK(inode->i_mode)) ||
+ (S_ISCHR(inode->i_mode)))
+ init_special_inode(inode, inode->i_mode,
+ inode->i_rdev);
+ }
+ if (stat->st_result_mask & P9_STATS_RDEV)
+ inode->i_rdev = new_decode_dev(stat->st_rdev);
+ if (stat->st_result_mask & P9_STATS_SIZE)
+ i_size_write(inode, stat->st_size);
+ if (stat->st_result_mask & P9_STATS_BLOCKS)
+ inode->i_blocks = stat->st_blocks;
+ }
+ if (stat->st_result_mask & P9_STATS_GEN)
+ inode->i_generation = stat->st_gen;
+
+ /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
+ * because the inode structure does not have fields for them.
+ */
+}
+
+/**
+ * v9fs_vfs_symlink_dotl - helper function to create symlinks
+ * @dir: directory inode containing symlink
+ * @dentry: dentry for symlink
+ * @symname: symlink data
+ *
+ * See Also: 9P2000.L RFC for more information
+ *
+ */
+
+static int
+v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
+ const char *symname)
+{
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *dfid;
+ struct p9_fid *fid = NULL;
+ struct inode *inode;
+ struct p9_qid qid;
+ char *name;
+ int err;
+ gid_t gid;
+
+ name = (char *) dentry->d_name.name;
+ P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
+ dir->i_ino, name, symname);
+ v9ses = v9fs_inode2v9ses(dir);
+
+ dfid = v9fs_fid_lookup(dentry->d_parent);
+ if (IS_ERR(dfid)) {
+ err = PTR_ERR(dfid);
+ P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
+ return err;
+ }
+
+ gid = v9fs_get_fsgid_for_create(dir);
+
+ /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
+ err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
+
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
+ goto error;
+ }
+
+ if (v9ses->cache) {
+ /* Now walk from the parent so we can get an unopened fid. */
+ fid = p9_client_walk(dfid, 1, &name, 1);
+ if (IS_ERR(fid)) {
+ err = PTR_ERR(fid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
+ err);
+ fid = NULL;
+ goto error;
+ }
+
+ /* instantiate inode and assign the unopened fid to dentry */
+ inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
+ err);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
+ d_instantiate(dentry, inode);
+ err = v9fs_fid_add(dentry, fid);
+ if (err < 0)
+ goto error;
+ fid = NULL;
+ } else {
+ /* Not in cached mode. No need to populate inode with stat */
+ inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_dentry_operations);
+ d_instantiate(dentry, inode);
+ }
+
+error:
+ if (fid)
+ p9_client_clunk(fid);
+
+ return err;
+}
+
+/**
+ * v9fs_vfs_link_dotl - create a hardlink for dotl
+ * @old_dentry: dentry for file to link to
+ * @dir: inode destination for new link
+ * @dentry: dentry for link
+ *
+ */
+
+static int
+v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ int err;
+ struct p9_fid *dfid, *oldfid;
+ char *name;
+ struct v9fs_session_info *v9ses;
+ struct dentry *dir_dentry;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
+ dir->i_ino, old_dentry->d_name.name,
+ dentry->d_name.name);
+
+ v9ses = v9fs_inode2v9ses(dir);
+ dir_dentry = v9fs_dentry_from_dir_inode(dir);
+ dfid = v9fs_fid_lookup(dir_dentry);
+ if (IS_ERR(dfid))
+ return PTR_ERR(dfid);
+
+ oldfid = v9fs_fid_lookup(old_dentry);
+ if (IS_ERR(oldfid))
+ return PTR_ERR(oldfid);
+
+ name = (char *) dentry->d_name.name;
+
+ err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
+
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
+ return err;
+ }
+
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
+ /* Get the latest stat info from server. */
+ struct p9_fid *fid;
+ struct p9_stat_dotl *st;
+
+ fid = v9fs_fid_lookup(old_dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
+ if (IS_ERR(st))
+ return PTR_ERR(st);
+
+ v9fs_stat2inode_dotl(st, old_dentry->d_inode);
+
+ kfree(st);
+ } else {
+ /* Caching disabled. No need to get upto date stat info.
+ * This dentry will be released immediately. So, just hold the
+ * inode
+ */
+ ihold(old_dentry->d_inode);
+ }
+
+ d_set_d_op(dentry, old_dentry->d_op);
+ d_instantiate(dentry, old_dentry->d_inode);
+
+ return err;
+}
+
+/**
+ * v9fs_vfs_mknod_dotl - create a special file
+ * @dir: inode destination for new link
+ * @dentry: dentry for file
+ * @mode: mode for creation
+ * @rdev: device associated with special file
+ *
+ */
+static int
+v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
+ dev_t rdev)
+{
+ int err;
+ char *name;
+ mode_t mode;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid = NULL, *dfid = NULL;
+ struct inode *inode;
+ gid_t gid;
+ struct p9_qid qid;
+ struct dentry *dir_dentry;
+ struct posix_acl *dacl = NULL, *pacl = NULL;
+
+ P9_DPRINTK(P9_DEBUG_VFS,
+ " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
+ dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
+
+ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ v9ses = v9fs_inode2v9ses(dir);
+ dir_dentry = v9fs_dentry_from_dir_inode(dir);
+ dfid = v9fs_fid_lookup(dir_dentry);
+ if (IS_ERR(dfid)) {
+ err = PTR_ERR(dfid);
+ P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
+ dfid = NULL;
+ goto error;
+ }
+
+ gid = v9fs_get_fsgid_for_create(dir);
+ mode = omode;
+ /* Update mode based on ACL value */
+ err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_VFS,
+ "Failed to get acl values in mknod %d\n", err);
+ goto error;
+ }
+ name = (char *) dentry->d_name.name;
+
+ err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
+ if (err < 0)
+ goto error;
+
+ /* instantiate inode and assign the unopened fid to the dentry */
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
+ fid = p9_client_walk(dfid, 1, &name, 1);
+ if (IS_ERR(fid)) {
+ err = PTR_ERR(fid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
+ err);
+ fid = NULL;
+ goto error;
+ }
+
+ inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
+ err);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_cached_dentry_operations);
+ d_instantiate(dentry, inode);
+ err = v9fs_fid_add(dentry, fid);
+ if (err < 0)
+ goto error;
+ fid = NULL;
+ } else {
+ /*
+ * Not in cached mode. No need to populate inode with stat.
+ * socket syscall returns a fd, so we need instantiate
+ */
+ inode = v9fs_get_inode(dir->i_sb, mode);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ goto error;
+ }
+ d_set_d_op(dentry, &v9fs_dentry_operations);
+ d_instantiate(dentry, inode);
+ }
+ /* Now set the ACL based on the default value */
+ v9fs_set_create_acl(dentry, dacl, pacl);
+error:
+ if (fid)
+ p9_client_clunk(fid);
+ return err;
+}
+
+static int
+v9fs_vfs_readlink_dotl(struct dentry *dentry, char *buffer, int buflen)
+{
+ int retval;
+ struct p9_fid *fid;
+ char *target = NULL;
+
+ P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
+ retval = -EPERM;
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ retval = p9_client_readlink(fid, &target);
+ if (retval < 0)
+ return retval;
+
+ strncpy(buffer, target, buflen);
+ P9_DPRINTK(P9_DEBUG_VFS, "%s -> %s\n", dentry->d_name.name, buffer);
+
+ retval = strnlen(buffer, buflen);
+ return retval;
+}
+
+/**
+ * v9fs_vfs_follow_link_dotl - follow a symlink path
+ * @dentry: dentry for symlink
+ * @nd: nameidata
+ *
+ */
+
+static void *
+v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
+{
+ int len = 0;
+ char *link = __getname();
+
+ P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
+
+ if (!link)
+ link = ERR_PTR(-ENOMEM);
+ else {
+ len = v9fs_vfs_readlink_dotl(dentry, link, PATH_MAX);
+ if (len < 0) {
+ __putname(link);
+ link = ERR_PTR(len);
+ } else
+ link[min(len, PATH_MAX-1)] = 0;
+ }
+ nd_set_link(nd, link);
+
+ return NULL;
+}
+
+const struct inode_operations v9fs_dir_inode_operations_dotl = {
+ .create = v9fs_vfs_create_dotl,
+ .lookup = v9fs_vfs_lookup,
+ .link = v9fs_vfs_link_dotl,
+ .symlink = v9fs_vfs_symlink_dotl,
+ .unlink = v9fs_vfs_unlink,
+ .mkdir = v9fs_vfs_mkdir_dotl,
+ .rmdir = v9fs_vfs_rmdir,
+ .mknod = v9fs_vfs_mknod_dotl,
+ .rename = v9fs_vfs_rename,
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .removexattr = generic_removexattr,
+ .listxattr = v9fs_listxattr,
+ .check_acl = v9fs_check_acl,
+};
+
+const struct inode_operations v9fs_file_inode_operations_dotl = {
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .removexattr = generic_removexattr,
+ .listxattr = v9fs_listxattr,
+ .check_acl = v9fs_check_acl,
+};
+
+const struct inode_operations v9fs_symlink_inode_operations_dotl = {
+ .readlink = v9fs_vfs_readlink_dotl,
+ .follow_link = v9fs_vfs_follow_link_dotl,
+ .put_link = v9fs_vfs_put_link,
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .removexattr = generic_removexattr,
+ .listxattr = v9fs_listxattr,
+};
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index 43ec7df84336..d288773871b3 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -133,7 +133,7 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
"p9_client_xattrcreate failed %d\n", retval);
goto error;
}
- msize = fid->clnt->msize;;
+ msize = fid->clnt->msize;
while (value_len) {
if (value_len > (msize - P9_IOHDRSZ))
write_count = msize - P9_IOHDRSZ;
diff --git a/fs/Kconfig b/fs/Kconfig
index 771f457402d4..2bbe47fec1ec 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -188,6 +188,7 @@ source "fs/omfs/Kconfig"
source "fs/hpfs/Kconfig"
source "fs/qnx4/Kconfig"
source "fs/romfs/Kconfig"
+source "fs/pstore/Kconfig"
source "fs/sysv/Kconfig"
source "fs/ufs/Kconfig"
source "fs/exofs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index a7f7cef0c0c8..db71a5b21a4f 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -121,3 +121,4 @@ obj-$(CONFIG_BTRFS_FS) += btrfs/
obj-$(CONFIG_GFS2_FS) += gfs2/
obj-$(CONFIG_EXOFS_FS) += exofs/
obj-$(CONFIG_CEPH_FS) += ceph/
+obj-$(CONFIG_PSTORE) += pstore/
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index f4287e4de744..bf7693c384f9 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -201,7 +201,8 @@ const struct file_operations adfs_dir_operations = {
};
static int
-adfs_hash(struct dentry *parent, struct qstr *qstr)
+adfs_hash(const struct dentry *parent, const struct inode *inode,
+ struct qstr *qstr)
{
const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen;
const unsigned char *name;
@@ -237,17 +238,19 @@ adfs_hash(struct dentry *parent, struct qstr *qstr)
* requirements of the underlying filesystem.
*/
static int
-adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name)
+adfs_compare(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
int i;
- if (entry->len != name->len)
+ if (len != name->len)
return 1;
for (i = 0; i < name->len; i++) {
char a, b;
- a = entry->name[i];
+ a = str[i];
b = name->name[i];
if (a >= 'A' && a <= 'Z')
@@ -273,7 +276,7 @@ adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
struct object_info obj;
int error;
- dentry->d_op = &adfs_dentry_operations;
+ d_set_d_op(dentry, &adfs_dentry_operations);
lock_kernel();
error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
if (error == 0) {
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 959dbff2d42d..a4041b52fbca 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -240,11 +240,18 @@ static struct inode *adfs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void adfs_destroy_inode(struct inode *inode)
+static void adfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(adfs_inode_cachep, ADFS_I(inode));
}
+static void adfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, adfs_i_callback);
+}
+
static void init_once(void *foo)
{
struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
@@ -477,7 +484,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
adfs_error(sb, "get root inode failed\n");
goto error;
} else
- sb->s_root->d_op = &adfs_dentry_operations;
+ d_set_d_op(sb->s_root, &adfs_dentry_operations);
unlock_kernel();
return 0;
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index 7d0f0a30f7a3..3a4557e8325c 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -128,7 +128,7 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
void *data = dentry->d_fsdata;
struct list_head *head, *next;
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
head = &inode->i_dentry;
next = head->next;
while (next != head) {
@@ -139,7 +139,7 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
}
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
}
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 914d1c0bc07a..944a4042fb65 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -13,11 +13,19 @@
typedef int (*toupper_t)(int);
static int affs_toupper(int ch);
-static int affs_hash_dentry(struct dentry *, struct qstr *);
-static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+static int affs_hash_dentry(const struct dentry *,
+ const struct inode *, struct qstr *);
+static int affs_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
static int affs_intl_toupper(int ch);
-static int affs_intl_hash_dentry(struct dentry *, struct qstr *);
-static int affs_intl_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+static int affs_intl_hash_dentry(const struct dentry *,
+ const struct inode *, struct qstr *);
+static int affs_intl_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
const struct dentry_operations affs_dentry_operations = {
.d_hash = affs_hash_dentry,
@@ -58,13 +66,13 @@ affs_get_toupper(struct super_block *sb)
* Note: the dentry argument is the parent dentry.
*/
static inline int
-__affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper)
+__affs_hash_dentry(struct qstr *qstr, toupper_t toupper)
{
const u8 *name = qstr->name;
unsigned long hash;
int i;
- i = affs_check_name(qstr->name,qstr->len);
+ i = affs_check_name(qstr->name, qstr->len);
if (i)
return i;
@@ -78,39 +86,41 @@ __affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper)
}
static int
-affs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
+affs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
- return __affs_hash_dentry(dentry, qstr, affs_toupper);
+ return __affs_hash_dentry(qstr, affs_toupper);
}
static int
-affs_intl_hash_dentry(struct dentry *dentry, struct qstr *qstr)
+affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
- return __affs_hash_dentry(dentry, qstr, affs_intl_toupper);
+ return __affs_hash_dentry(qstr, affs_intl_toupper);
}
-static inline int
-__affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b, toupper_t toupper)
+static inline int __affs_compare_dentry(unsigned int len,
+ const char *str, const struct qstr *name, toupper_t toupper)
{
- const u8 *aname = a->name;
- const u8 *bname = b->name;
- int len;
+ const u8 *aname = str;
+ const u8 *bname = name->name;
- /* 'a' is the qstr of an already existing dentry, so the name
- * must be valid. 'b' must be validated first.
+ /*
+ * 'str' is the name of an already existing dentry, so the name
+ * must be valid. 'name' must be validated first.
*/
- if (affs_check_name(b->name,b->len))
+ if (affs_check_name(name->name, name->len))
return 1;
- /* If the names are longer than the allowed 30 chars,
+ /*
+ * If the names are longer than the allowed 30 chars,
* the excess is ignored, so their length may differ.
*/
- len = a->len;
if (len >= 30) {
- if (b->len < 30)
+ if (name->len < 30)
return 1;
len = 30;
- } else if (len != b->len)
+ } else if (len != name->len)
return 1;
for (; len > 0; len--)
@@ -121,14 +131,18 @@ __affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b, tou
}
static int
-affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+affs_compare_dentry(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return __affs_compare_dentry(dentry, a, b, affs_toupper);
+ return __affs_compare_dentry(len, str, name, affs_toupper);
}
static int
-affs_intl_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return __affs_compare_dentry(dentry, a, b, affs_intl_toupper);
+ return __affs_compare_dentry(len, str, name, affs_intl_toupper);
}
/*
@@ -226,7 +240,7 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
if (IS_ERR(inode))
return ERR_CAST(inode);
}
- dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations;
+ d_set_d_op(dentry, AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations);
d_add(dentry, inode);
return NULL;
}
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 0cf7f4384cbd..d39081bbe7ce 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -95,11 +95,18 @@ static struct inode *affs_alloc_inode(struct super_block *sb)
return &i->vfs_inode;
}
-static void affs_destroy_inode(struct inode *inode)
+static void affs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(affs_inode_cachep, AFFS_I(inode));
}
+static void affs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, affs_i_callback);
+}
+
static void init_once(void *foo)
{
struct affs_inode_info *ei = (struct affs_inode_info *) foo;
@@ -475,7 +482,7 @@ got_root:
printk(KERN_ERR "AFFS: Get root inode failed\n");
goto out_error;
}
- sb->s_root->d_op = &affs_dentry_operations;
+ d_set_d_op(sb->s_root, &affs_dentry_operations);
pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
return 0;
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 5439e1bc9a86..b8bb7e7148d0 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -23,7 +23,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
static int afs_dir_open(struct inode *inode, struct file *file);
static int afs_readdir(struct file *file, void *dirent, filldir_t filldir);
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
-static int afs_d_delete(struct dentry *dentry);
+static int afs_d_delete(const struct dentry *dentry);
static void afs_d_release(struct dentry *dentry);
static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
loff_t fpos, u64 ino, unsigned dtype);
@@ -581,7 +581,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
}
success:
- dentry->d_op = &afs_fs_dentry_operations;
+ d_set_d_op(dentry, &afs_fs_dentry_operations);
d_add(dentry, inode);
_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }",
@@ -730,7 +730,7 @@ out_bad:
* - called from dput() when d_count is going to 0.
* - return 1 to request dentry be unhashed, 0 otherwise
*/
-static int afs_d_delete(struct dentry *dentry)
+static int afs_d_delete(const struct dentry *dentry)
{
_enter("%s", dentry->d_name.name);
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 27201cffece4..f901a9d7c111 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -498,6 +498,14 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
return &vnode->vfs_inode;
}
+static void afs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct afs_vnode *vnode = AFS_FS_I(inode);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(afs_inode_cachep, vnode);
+}
+
/*
* destroy an AFS inode struct
*/
@@ -511,7 +519,7 @@ static void afs_destroy_inode(struct inode *inode)
ASSERTCMP(vnode->server, ==, NULL);
- kmem_cache_free(afs_inode_cachep, vnode);
+ call_rcu(&inode->i_rcu, afs_i_callback);
atomic_dec(&afs_count_active_inodes);
}
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 57ce55b2564c..5fd38112a6ca 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -102,7 +102,7 @@ struct file *anon_inode_getfile(const char *name,
this.name = name;
this.len = strlen(name);
this.hash = 0;
- path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
+ path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
if (!path.dentry)
goto err_module;
@@ -113,7 +113,7 @@ struct file *anon_inode_getfile(const char *name,
*/
ihold(anon_inode_inode);
- path.dentry->d_op = &anon_inodefs_dentry_operations;
+ d_set_d_op(path.dentry, &anon_inodefs_dentry_operations);
d_instantiate(path.dentry, anon_inode_inode);
error = -ENFILE;
@@ -232,7 +232,7 @@ static int __init anon_inode_init(void)
return 0;
err_mntput:
- mntput(anon_inode_mnt);
+ mntput_long(anon_inode_mnt);
err_unregister_filesystem:
unregister_filesystem(&anon_inode_fs_type);
err_exit:
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 3d283abf67d7..0fffe1c24cec 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -16,6 +16,7 @@
#include <linux/auto_fs4.h>
#include <linux/auto_dev-ioctl.h>
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/list.h>
/* This is the range of ioctl() numbers we claim as ours */
@@ -60,6 +61,8 @@ do { \
current->pid, __func__, ##args); \
} while (0)
+extern spinlock_t autofs4_lock;
+
/* Unified info structure. This is pointed to by both the dentry and
inode structures. Each file in the filesystem has an instance of this
structure. It holds a reference to the dentry, so dentries are never
@@ -254,17 +257,15 @@ static inline int simple_positive(struct dentry *dentry)
return dentry->d_inode && !d_unhashed(dentry);
}
-static inline int __simple_empty(struct dentry *dentry)
+static inline void __autofs4_add_expiring(struct dentry *dentry)
{
- struct dentry *child;
- int ret = 0;
-
- list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
- if (simple_positive(child))
- goto out;
- ret = 1;
-out:
- return ret;
+ struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+ if (ino) {
+ if (list_empty(&ino->expiring))
+ list_add(&ino->expiring, &sbi->expiring_list);
+ }
+ return;
}
static inline void autofs4_add_expiring(struct dentry *dentry)
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index a796c9417fb1..cc1d01365905 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -91,24 +91,64 @@ done:
}
/*
- * Calculate next entry in top down tree traversal.
- * From next_mnt in namespace.c - elegant.
+ * Calculate and dget next entry in top down tree traversal.
*/
-static struct dentry *next_dentry(struct dentry *p, struct dentry *root)
+static struct dentry *get_next_positive_dentry(struct dentry *prev,
+ struct dentry *root)
{
- struct list_head *next = p->d_subdirs.next;
+ struct list_head *next;
+ struct dentry *p, *ret;
+
+ if (prev == NULL)
+ return dget(prev);
+ spin_lock(&autofs4_lock);
+relock:
+ p = prev;
+ spin_lock(&p->d_lock);
+again:
+ next = p->d_subdirs.next;
if (next == &p->d_subdirs) {
while (1) {
- if (p == root)
+ struct dentry *parent;
+
+ if (p == root) {
+ spin_unlock(&p->d_lock);
+ spin_unlock(&autofs4_lock);
+ dput(prev);
return NULL;
+ }
+
+ parent = p->d_parent;
+ if (!spin_trylock(&parent->d_lock)) {
+ spin_unlock(&p->d_lock);
+ cpu_relax();
+ goto relock;
+ }
+ spin_unlock(&p->d_lock);
next = p->d_u.d_child.next;
- if (next != &p->d_parent->d_subdirs)
+ p = parent;
+ if (next != &parent->d_subdirs)
break;
- p = p->d_parent;
}
}
- return list_entry(next, struct dentry, d_u.d_child);
+ ret = list_entry(next, struct dentry, d_u.d_child);
+
+ spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
+ /* Negative dentry - try next */
+ if (!simple_positive(ret)) {
+ spin_unlock(&ret->d_lock);
+ p = ret;
+ goto again;
+ }
+ dget_dlock(ret);
+ spin_unlock(&ret->d_lock);
+ spin_unlock(&p->d_lock);
+ spin_unlock(&autofs4_lock);
+
+ dput(prev);
+
+ return ret;
}
/*
@@ -158,18 +198,11 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
if (!simple_positive(top))
return 1;
- spin_lock(&dcache_lock);
- for (p = top; p; p = next_dentry(p, top)) {
- /* Negative dentry - give up */
- if (!simple_positive(p))
- continue;
-
+ p = NULL;
+ while ((p = get_next_positive_dentry(p, top))) {
DPRINTK("dentry %p %.*s",
p, (int) p->d_name.len, p->d_name.name);
- p = dget(p);
- spin_unlock(&dcache_lock);
-
/*
* Is someone visiting anywhere in the subtree ?
* If there's no mount we need to check the usage
@@ -198,16 +231,13 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
else
ino_count++;
- if (atomic_read(&p->d_count) > ino_count) {
+ if (p->d_count > ino_count) {
top_ino->last_used = jiffies;
dput(p);
return 1;
}
}
- dput(p);
- spin_lock(&dcache_lock);
}
- spin_unlock(&dcache_lock);
/* Timeout of a tree mount is ultimately determined by its top dentry */
if (!autofs4_can_expire(top, timeout, do_now))
@@ -226,32 +256,21 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
DPRINTK("parent %p %.*s",
parent, (int)parent->d_name.len, parent->d_name.name);
- spin_lock(&dcache_lock);
- for (p = parent; p; p = next_dentry(p, parent)) {
- /* Negative dentry - give up */
- if (!simple_positive(p))
- continue;
-
+ p = NULL;
+ while ((p = get_next_positive_dentry(p, parent))) {
DPRINTK("dentry %p %.*s",
p, (int) p->d_name.len, p->d_name.name);
- p = dget(p);
- spin_unlock(&dcache_lock);
-
if (d_mountpoint(p)) {
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, p))
- goto cont;
+ continue;
/* Can we expire this guy */
if (autofs4_can_expire(p, timeout, do_now))
return p;
}
-cont:
- dput(p);
- spin_lock(&dcache_lock);
}
- spin_unlock(&dcache_lock);
return NULL;
}
@@ -276,7 +295,9 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
struct autofs_info *ino = autofs4_dentry_ino(root);
if (d_mountpoint(root)) {
ino->flags |= AUTOFS_INF_MOUNTPOINT;
- root->d_mounted--;
+ spin_lock(&root->d_lock);
+ root->d_flags &= ~DCACHE_MOUNTED;
+ spin_unlock(&root->d_lock);
}
ino->flags |= AUTOFS_INF_EXPIRING;
init_completion(&ino->expire_complete);
@@ -302,8 +323,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
{
unsigned long timeout;
struct dentry *root = sb->s_root;
+ struct dentry *dentry;
struct dentry *expired = NULL;
- struct list_head *next;
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct autofs_info *ino;
@@ -315,23 +336,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
now = jiffies;
timeout = sbi->exp_timeout;
- spin_lock(&dcache_lock);
- next = root->d_subdirs.next;
-
- /* On exit from the loop expire is set to a dgot dentry
- * to expire or it's NULL */
- while ( next != &root->d_subdirs ) {
- struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
-
- /* Negative dentry - give up */
- if (!simple_positive(dentry)) {
- next = next->next;
- continue;
- }
-
- dentry = dget(dentry);
- spin_unlock(&dcache_lock);
-
+ dentry = NULL;
+ while ((dentry = get_next_positive_dentry(dentry, root))) {
spin_lock(&sbi->fs_lock);
ino = autofs4_dentry_ino(dentry);
@@ -347,7 +353,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 2;
- if (atomic_read(&dentry->d_count) > ino_count)
+ if (dentry->d_count > ino_count)
goto next;
/* Can we umount this guy */
@@ -369,7 +375,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
if (!exp_leaves) {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
- if (atomic_read(&dentry->d_count) > ino_count)
+ if (dentry->d_count > ino_count)
goto next;
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
@@ -383,7 +389,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
} else {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
- if (atomic_read(&dentry->d_count) > ino_count)
+ if (dentry->d_count > ino_count)
goto next;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
@@ -394,11 +400,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
}
next:
spin_unlock(&sbi->fs_lock);
- dput(dentry);
- spin_lock(&dcache_lock);
- next = next->next;
}
- spin_unlock(&dcache_lock);
return NULL;
found:
@@ -408,9 +410,13 @@ found:
ino->flags |= AUTOFS_INF_EXPIRING;
init_completion(&ino->expire_complete);
spin_unlock(&sbi->fs_lock);
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
+ spin_lock(&expired->d_parent->d_lock);
+ spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
- spin_unlock(&dcache_lock);
+ spin_unlock(&expired->d_lock);
+ spin_unlock(&expired->d_parent->d_lock);
+ spin_unlock(&autofs4_lock);
return expired;
}
@@ -499,7 +505,14 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
spin_lock(&sbi->fs_lock);
if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
- sb->s_root->d_mounted++;
+ spin_lock(&sb->s_root->d_lock);
+ /*
+ * If we haven't been expired away, then reset
+ * mounted status.
+ */
+ if (mnt->mnt_parent != mnt)
+ sb->s_root->d_flags |= DCACHE_MOUNTED;
+ spin_unlock(&sb->s_root->d_lock);
ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
}
ino->flags &= ~AUTOFS_INF_EXPIRING;
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index ac87e49fa706..a7bdb9dcac84 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -309,7 +309,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
goto fail_iput;
pipe = NULL;
- root->d_op = &autofs4_sb_dentry_operations;
+ d_set_d_op(root, &autofs4_sb_dentry_operations);
root->d_fsdata = ino;
/* Can this call block? */
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index d5c1401f0031..bfe3f2eb684d 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -23,6 +23,8 @@
#include "autofs_i.h"
+DEFINE_SPINLOCK(autofs4_lock);
+
static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
static int autofs4_dir_unlink(struct inode *,struct dentry *);
static int autofs4_dir_rmdir(struct inode *,struct dentry *);
@@ -142,12 +144,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
* autofs file system so just let the libfs routines handle
* it.
*/
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
+ spin_lock(&dentry->d_lock);
if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
return -ENOENT;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
out:
return dcache_dir_open(inode, file);
@@ -252,9 +257,11 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
/* We trigger a mount for almost all flags */
lookup_type = autofs4_need_mount(nd->flags);
spin_lock(&sbi->fs_lock);
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
+ spin_lock(&dentry->d_lock);
if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);
goto follow;
}
@@ -266,7 +273,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
*/
if (ino->flags & AUTOFS_INF_PENDING ||
(!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);
status = try_to_fill_dentry(dentry, nd->flags);
@@ -275,7 +283,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
goto follow;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);
follow:
/*
@@ -346,12 +355,14 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
return 0;
/* Check for a non-mountpoint directory with no contents */
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
+ spin_lock(&dentry->d_lock);
if (S_ISDIR(dentry->d_inode->i_mode) &&
!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
DPRINTK("dentry=%p %.*s, emptydir",
dentry, dentry->d_name.len, dentry->d_name.name);
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
/* The daemon never causes a mount to trigger */
if (oz_mode)
@@ -367,7 +378,8 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
return status;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&autofs4_lock);
return 1;
}
@@ -422,7 +434,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
const unsigned char *str = name->name;
struct list_head *p, *head;
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
spin_lock(&sbi->lookup_lock);
head = &sbi->active_list;
list_for_each(p, head) {
@@ -436,7 +448,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
spin_lock(&active->d_lock);
/* Already gone? */
- if (atomic_read(&active->d_count) == 0)
+ if (active->d_count == 0)
goto next;
qstr = &active->d_name;
@@ -452,17 +464,17 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
goto next;
if (d_unhashed(active)) {
- dget(active);
+ dget_dlock(active);
spin_unlock(&active->d_lock);
spin_unlock(&sbi->lookup_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
return active;
}
next:
spin_unlock(&active->d_lock);
}
spin_unlock(&sbi->lookup_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
return NULL;
}
@@ -477,7 +489,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
const unsigned char *str = name->name;
struct list_head *p, *head;
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
spin_lock(&sbi->lookup_lock);
head = &sbi->expiring_list;
list_for_each(p, head) {
@@ -507,17 +519,17 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
goto next;
if (d_unhashed(expiring)) {
- dget(expiring);
+ dget_dlock(expiring);
spin_unlock(&expiring->d_lock);
spin_unlock(&sbi->lookup_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
return expiring;
}
next:
spin_unlock(&expiring->d_lock);
}
spin_unlock(&sbi->lookup_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
return NULL;
}
@@ -559,7 +571,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
* we check for the hashed dentry and return the newly
* hashed dentry.
*/
- dentry->d_op = &autofs4_root_dentry_operations;
+ d_set_d_op(dentry, &autofs4_root_dentry_operations);
/*
* And we need to ensure that the same dentry is used for
@@ -698,9 +710,9 @@ static int autofs4_dir_symlink(struct inode *dir,
d_add(dentry, inode);
if (dir == dir->i_sb->s_root->d_inode)
- dentry->d_op = &autofs4_root_dentry_operations;
+ d_set_d_op(dentry, &autofs4_root_dentry_operations);
else
- dentry->d_op = &autofs4_dentry_operations;
+ d_set_d_op(dentry, &autofs4_dentry_operations);
dentry->d_fsdata = ino;
ino->dentry = dget(dentry);
@@ -753,12 +765,12 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
dir->i_mtime = CURRENT_TIME;
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
autofs4_add_expiring(dentry);
spin_lock(&dentry->d_lock);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
return 0;
}
@@ -775,16 +787,20 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
if (!autofs4_oz_mode(sbi))
return -EACCES;
- spin_lock(&dcache_lock);
+ spin_lock(&autofs4_lock);
+ spin_lock(&sbi->lookup_lock);
+ spin_lock(&dentry->d_lock);
if (!list_empty(&dentry->d_subdirs)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&sbi->lookup_lock);
+ spin_unlock(&autofs4_lock);
return -ENOTEMPTY;
}
- autofs4_add_expiring(dentry);
- spin_lock(&dentry->d_lock);
+ __autofs4_add_expiring(dentry);
+ spin_unlock(&sbi->lookup_lock);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
if (atomic_dec_and_test(&ino->count)) {
p_ino = autofs4_dentry_ino(dentry->d_parent);
@@ -829,9 +845,9 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_add(dentry, inode);
if (dir == dir->i_sb->s_root->d_inode)
- dentry->d_op = &autofs4_root_dentry_operations;
+ d_set_d_op(dentry, &autofs4_root_dentry_operations);
else
- dentry->d_op = &autofs4_dentry_operations;
+ d_set_d_op(dentry, &autofs4_dentry_operations);
dentry->d_fsdata = ino;
ino->dentry = dget(dentry);
@@ -980,19 +996,11 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp,
}
}
-static DEFINE_MUTEX(autofs4_ioctl_mutex);
-
static long autofs4_root_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
{
- long ret;
struct inode *inode = filp->f_dentry->d_inode;
-
- mutex_lock(&autofs4_ioctl_mutex);
- ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
- mutex_unlock(&autofs4_ioctl_mutex);
-
- return ret;
+ return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
}
#ifdef CONFIG_COMPAT
@@ -1002,13 +1010,11 @@ static long autofs4_root_compat_ioctl(struct file *filp,
struct inode *inode = filp->f_path.dentry->d_inode;
int ret;
- mutex_lock(&autofs4_ioctl_mutex);
if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
else
ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
(unsigned long)compat_ptr(arg));
- mutex_unlock(&autofs4_ioctl_mutex);
return ret;
}
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 2341375386f8..c5f8459c905e 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -186,16 +186,26 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
{
struct dentry *root = sbi->sb->s_root;
struct dentry *tmp;
- char *buf = *name;
+ char *buf;
char *p;
- int len = 0;
+ int len;
+ unsigned seq;
- spin_lock(&dcache_lock);
+rename_retry:
+ buf = *name;
+ len = 0;
+
+ seq = read_seqbegin(&rename_lock);
+ rcu_read_lock();
+ spin_lock(&autofs4_lock);
for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
len += tmp->d_name.len + 1;
if (!len || --len > NAME_MAX) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
+ rcu_read_unlock();
+ if (read_seqretry(&rename_lock, seq))
+ goto rename_retry;
return 0;
}
@@ -208,7 +218,10 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
p -= tmp->d_name.len;
strncpy(p, tmp->d_name.name, tmp->d_name.len);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&autofs4_lock);
+ rcu_read_unlock();
+ if (read_seqretry(&rename_lock, seq))
+ goto rename_retry;
return len;
}
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index aa4e7c7ae3c6..de93581b79a2 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -284,12 +284,18 @@ befs_alloc_inode(struct super_block *sb)
return &bi->vfs_inode;
}
-static void
-befs_destroy_inode(struct inode *inode)
+static void befs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(befs_inode_cachep, BEFS_I(inode));
}
+static void befs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, befs_i_callback);
+}
+
static void init_once(void *foo)
{
struct befs_inode_info *bi = (struct befs_inode_info *) foo;
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 76db6d7d49bb..a8e37f81d097 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -248,11 +248,18 @@ static struct inode *bfs_alloc_inode(struct super_block *sb)
return &bi->vfs_inode;
}
-static void bfs_destroy_inode(struct inode *inode)
+static void bfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
}
+static void bfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, bfs_i_callback);
+}
+
static void init_once(void *foo)
{
struct bfs_inode_info *bi = foo;
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index 4d0ff5ee27b8..e49cce234c65 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -782,7 +782,12 @@ void __init bio_integrity_init(void)
{
unsigned int i;
- kintegrityd_wq = create_workqueue("kintegrityd");
+ /*
+ * kintegrityd won't block much but may burn a lot of CPU cycles.
+ * Make it highpri CPU intensive wq with max concurrency of 1.
+ */
+ kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
+ WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
if (!kintegrityd_wq)
panic("Failed to create kintegrityd\n");
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 4230252fd689..a47220cebe54 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -409,13 +409,20 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void bdev_destroy_inode(struct inode *inode)
+static void bdev_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
struct bdev_inode *bdi = BDEV_I(inode);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(bdev_cachep, bdi);
}
+static void bdev_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, bdev_i_callback);
+}
+
static void init_once(void *foo)
{
struct bdev_inode *ei = (struct bdev_inode *) foo;
@@ -425,9 +432,6 @@ static void init_once(void *foo)
mutex_init(&bdev->bd_mutex);
INIT_LIST_HEAD(&bdev->bd_inodes);
INIT_LIST_HEAD(&bdev->bd_list);
-#ifdef CONFIG_SYSFS
- INIT_LIST_HEAD(&bdev->bd_holder_list);
-#endif
inode_init_once(&ei->vfs_inode);
/* Initialize mutex for freeze. */
mutex_init(&bdev->bd_fsfreeze_mutex);
@@ -662,7 +666,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
else if (bdev->bd_contains == bdev)
return true; /* is a whole device which isn't held */
- else if (whole->bd_holder == bd_claim)
+ else if (whole->bd_holder == bd_may_claim)
return true; /* is a partition of a device that is being partitioned */
else if (whole->bd_holder != NULL)
return false; /* is a partition of a held device */
@@ -774,439 +778,87 @@ static struct block_device *bd_start_claiming(struct block_device *bdev,
}
}
-/* releases bdev_lock */
-static void __bd_abort_claiming(struct block_device *whole, void *holder)
-{
- BUG_ON(whole->bd_claiming != holder);
- whole->bd_claiming = NULL;
- wake_up_bit(&whole->bd_claiming, 0);
-
- spin_unlock(&bdev_lock);
- bdput(whole);
-}
-
-/**
- * bd_abort_claiming - abort claiming a block device
- * @whole: whole block device returned by bd_start_claiming()
- * @holder: holder trying to claim @bdev
- *
- * Abort a claiming block started by bd_start_claiming(). Note that
- * @whole is not the block device to be claimed but the whole device
- * returned by bd_start_claiming().
- *
- * CONTEXT:
- * Grabs and releases bdev_lock.
- */
-static void bd_abort_claiming(struct block_device *whole, void *holder)
-{
- spin_lock(&bdev_lock);
- __bd_abort_claiming(whole, holder); /* releases bdev_lock */
-}
-
-/* increment holders when we have a legitimate claim. requires bdev_lock */
-static void __bd_claim(struct block_device *bdev, struct block_device *whole,
- void *holder)
-{
- /* note that for a whole device bd_holders
- * will be incremented twice, and bd_holder will
- * be set to bd_claim before being set to holder
- */
- whole->bd_holders++;
- whole->bd_holder = bd_claim;
- bdev->bd_holders++;
- bdev->bd_holder = holder;
-}
-
-/**
- * bd_finish_claiming - finish claiming a block device
- * @bdev: block device of interest (passed to bd_start_claiming())
- * @whole: whole block device returned by bd_start_claiming()
- * @holder: holder trying to claim @bdev
- *
- * Finish a claiming block started by bd_start_claiming().
- *
- * CONTEXT:
- * Grabs and releases bdev_lock.
- */
-static void bd_finish_claiming(struct block_device *bdev,
- struct block_device *whole, void *holder)
-{
- spin_lock(&bdev_lock);
- BUG_ON(!bd_may_claim(bdev, whole, holder));
- __bd_claim(bdev, whole, holder);
- __bd_abort_claiming(whole, holder); /* not actually an abort */
-}
-
-/**
- * bd_claim - claim a block device
- * @bdev: block device to claim
- * @holder: holder trying to claim @bdev
- *
- * Try to claim @bdev which must have been opened successfully.
- *
- * CONTEXT:
- * Might sleep.
- *
- * RETURNS:
- * 0 if successful, -EBUSY if @bdev is already claimed.
- */
-int bd_claim(struct block_device *bdev, void *holder)
-{
- struct block_device *whole = bdev->bd_contains;
- int res;
-
- might_sleep();
-
- spin_lock(&bdev_lock);
- res = bd_prepare_to_claim(bdev, whole, holder);
- if (res == 0)
- __bd_claim(bdev, whole, holder);
- spin_unlock(&bdev_lock);
-
- return res;
-}
-EXPORT_SYMBOL(bd_claim);
-
-void bd_release(struct block_device *bdev)
-{
- spin_lock(&bdev_lock);
- if (!--bdev->bd_contains->bd_holders)
- bdev->bd_contains->bd_holder = NULL;
- if (!--bdev->bd_holders)
- bdev->bd_holder = NULL;
- spin_unlock(&bdev_lock);
-}
-
-EXPORT_SYMBOL(bd_release);
-
#ifdef CONFIG_SYSFS
-/*
- * Functions for bd_claim_by_kobject / bd_release_from_kobject
- *
- * If a kobject is passed to bd_claim_by_kobject()
- * and the kobject has a parent directory,
- * following symlinks are created:
- * o from the kobject to the claimed bdev
- * o from "holders" directory of the bdev to the parent of the kobject
- * bd_release_from_kobject() removes these symlinks.
- *
- * Example:
- * If /dev/dm-0 maps to /dev/sda, kobject corresponding to
- * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then:
- * /sys/block/dm-0/slaves/sda --> /sys/block/sda
- * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
- */
-
static int add_symlink(struct kobject *from, struct kobject *to)
{
- if (!from || !to)
- return 0;
return sysfs_create_link(from, to, kobject_name(to));
}
static void del_symlink(struct kobject *from, struct kobject *to)
{
- if (!from || !to)
- return;
sysfs_remove_link(from, kobject_name(to));
}
-/*
- * 'struct bd_holder' contains pointers to kobjects symlinked by
- * bd_claim_by_kobject.
- * It's connected to bd_holder_list which is protected by bdev->bd_sem.
- */
-struct bd_holder {
- struct list_head list; /* chain of holders of the bdev */
- int count; /* references from the holder */
- struct kobject *sdir; /* holder object, e.g. "/block/dm-0/slaves" */
- struct kobject *hdev; /* e.g. "/block/dm-0" */
- struct kobject *hdir; /* e.g. "/block/sda/holders" */
- struct kobject *sdev; /* e.g. "/block/sda" */
-};
-
-/*
- * Get references of related kobjects at once.
- * Returns 1 on success. 0 on failure.
- *
- * Should call bd_holder_release_dirs() after successful use.
- */
-static int bd_holder_grab_dirs(struct block_device *bdev,
- struct bd_holder *bo)
-{
- if (!bdev || !bo)
- return 0;
-
- bo->sdir = kobject_get(bo->sdir);
- if (!bo->sdir)
- return 0;
-
- bo->hdev = kobject_get(bo->sdir->parent);
- if (!bo->hdev)
- goto fail_put_sdir;
-
- bo->sdev = kobject_get(&part_to_dev(bdev->bd_part)->kobj);
- if (!bo->sdev)
- goto fail_put_hdev;
-
- bo->hdir = kobject_get(bdev->bd_part->holder_dir);
- if (!bo->hdir)
- goto fail_put_sdev;
-
- return 1;
-
-fail_put_sdev:
- kobject_put(bo->sdev);
-fail_put_hdev:
- kobject_put(bo->hdev);
-fail_put_sdir:
- kobject_put(bo->sdir);
-
- return 0;
-}
-
-/* Put references of related kobjects at once. */
-static void bd_holder_release_dirs(struct bd_holder *bo)
-{
- kobject_put(bo->hdir);
- kobject_put(bo->sdev);
- kobject_put(bo->hdev);
- kobject_put(bo->sdir);
-}
-
-static struct bd_holder *alloc_bd_holder(struct kobject *kobj)
-{
- struct bd_holder *bo;
-
- bo = kzalloc(sizeof(*bo), GFP_KERNEL);
- if (!bo)
- return NULL;
-
- bo->count = 1;
- bo->sdir = kobj;
-
- return bo;
-}
-
-static void free_bd_holder(struct bd_holder *bo)
-{
- kfree(bo);
-}
-
/**
- * find_bd_holder - find matching struct bd_holder from the block device
+ * bd_link_disk_holder - create symlinks between holding disk and slave bdev
+ * @bdev: the claimed slave bdev
+ * @disk: the holding disk
*
- * @bdev: struct block device to be searched
- * @bo: target struct bd_holder
+ * This functions creates the following sysfs symlinks.
*
- * Returns matching entry with @bo in @bdev->bd_holder_list.
- * If found, increment the reference count and return the pointer.
- * If not found, returns NULL.
- */
-static struct bd_holder *find_bd_holder(struct block_device *bdev,
- struct bd_holder *bo)
-{
- struct bd_holder *tmp;
-
- list_for_each_entry(tmp, &bdev->bd_holder_list, list)
- if (tmp->sdir == bo->sdir) {
- tmp->count++;
- return tmp;
- }
-
- return NULL;
-}
-
-/**
- * add_bd_holder - create sysfs symlinks for bd_claim() relationship
+ * - from "slaves" directory of the holder @disk to the claimed @bdev
+ * - from "holders" directory of the @bdev to the holder @disk
*
- * @bdev: block device to be bd_claimed
- * @bo: preallocated and initialized by alloc_bd_holder()
+ * For example, if /dev/dm-0 maps to /dev/sda and disk for dm-0 is
+ * passed to bd_link_disk_holder(), then:
*
- * Add @bo to @bdev->bd_holder_list, create symlinks.
+ * /sys/block/dm-0/slaves/sda --> /sys/block/sda
+ * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
*
- * Returns 0 if symlinks are created.
- * Returns -ve if something fails.
- */
-static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
-{
- int err;
-
- if (!bo)
- return -EINVAL;
-
- if (!bd_holder_grab_dirs(bdev, bo))
- return -EBUSY;
-
- err = add_symlink(bo->sdir, bo->sdev);
- if (err)
- return err;
-
- err = add_symlink(bo->hdir, bo->hdev);
- if (err) {
- del_symlink(bo->sdir, bo->sdev);
- return err;
- }
-
- list_add_tail(&bo->list, &bdev->bd_holder_list);
- return 0;
-}
-
-/**
- * del_bd_holder - delete sysfs symlinks for bd_claim() relationship
- *
- * @bdev: block device to be bd_claimed
- * @kobj: holder's kobject
+ * The caller must have claimed @bdev before calling this function and
+ * ensure that both @bdev and @disk are valid during the creation and
+ * lifetime of these symlinks.
*
- * If there is matching entry with @kobj in @bdev->bd_holder_list
- * and no other bd_claim() from the same kobject,
- * remove the struct bd_holder from the list, delete symlinks for it.
- *
- * Returns a pointer to the struct bd_holder when it's removed from the list
- * and ready to be freed.
- * Returns NULL if matching claim isn't found or there is other bd_claim()
- * by the same kobject.
- */
-static struct bd_holder *del_bd_holder(struct block_device *bdev,
- struct kobject *kobj)
-{
- struct bd_holder *bo;
-
- list_for_each_entry(bo, &bdev->bd_holder_list, list) {
- if (bo->sdir == kobj) {
- bo->count--;
- BUG_ON(bo->count < 0);
- if (!bo->count) {
- list_del(&bo->list);
- del_symlink(bo->sdir, bo->sdev);
- del_symlink(bo->hdir, bo->hdev);
- bd_holder_release_dirs(bo);
- return bo;
- }
- break;
- }
- }
-
- return NULL;
-}
-
-/**
- * bd_claim_by_kobject - bd_claim() with additional kobject signature
- *
- * @bdev: block device to be claimed
- * @holder: holder's signature
- * @kobj: holder's kobject
- *
- * Do bd_claim() and if it succeeds, create sysfs symlinks between
- * the bdev and the holder's kobject.
- * Use bd_release_from_kobject() when relesing the claimed bdev.
+ * CONTEXT:
+ * Might sleep.
*
- * Returns 0 on success. (same as bd_claim())
- * Returns errno on failure.
+ * RETURNS:
+ * 0 on success, -errno on failure.
*/
-static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
- struct kobject *kobj)
+int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk)
{
- int err;
- struct bd_holder *bo, *found;
-
- if (!kobj)
- return -EINVAL;
-
- bo = alloc_bd_holder(kobj);
- if (!bo)
- return -ENOMEM;
+ int ret = 0;
mutex_lock(&bdev->bd_mutex);
- err = bd_claim(bdev, holder);
- if (err)
- goto fail;
+ WARN_ON_ONCE(!bdev->bd_holder || bdev->bd_holder_disk);
- found = find_bd_holder(bdev, bo);
- if (found)
- goto fail;
+ /* FIXME: remove the following once add_disk() handles errors */
+ if (WARN_ON(!disk->slave_dir || !bdev->bd_part->holder_dir))
+ goto out_unlock;
- err = add_bd_holder(bdev, bo);
- if (err)
- bd_release(bdev);
- else
- bo = NULL;
-fail:
- mutex_unlock(&bdev->bd_mutex);
- free_bd_holder(bo);
- return err;
-}
+ ret = add_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+ if (ret)
+ goto out_unlock;
-/**
- * bd_release_from_kobject - bd_release() with additional kobject signature
- *
- * @bdev: block device to be released
- * @kobj: holder's kobject
- *
- * Do bd_release() and remove sysfs symlinks created by bd_claim_by_kobject().
- */
-static void bd_release_from_kobject(struct block_device *bdev,
- struct kobject *kobj)
-{
- if (!kobj)
- return;
+ ret = add_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
+ if (ret) {
+ del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+ goto out_unlock;
+ }
- mutex_lock(&bdev->bd_mutex);
- bd_release(bdev);
- free_bd_holder(del_bd_holder(bdev, kobj));
+ bdev->bd_holder_disk = disk;
+out_unlock:
mutex_unlock(&bdev->bd_mutex);
+ return ret;
}
+EXPORT_SYMBOL_GPL(bd_link_disk_holder);
-/**
- * bd_claim_by_disk - wrapper function for bd_claim_by_kobject()
- *
- * @bdev: block device to be claimed
- * @holder: holder's signature
- * @disk: holder's gendisk
- *
- * Call bd_claim_by_kobject() with getting @disk->slave_dir.
- */
-int bd_claim_by_disk(struct block_device *bdev, void *holder,
- struct gendisk *disk)
+static void bd_unlink_disk_holder(struct block_device *bdev)
{
- return bd_claim_by_kobject(bdev, holder, kobject_get(disk->slave_dir));
-}
-EXPORT_SYMBOL_GPL(bd_claim_by_disk);
+ struct gendisk *disk = bdev->bd_holder_disk;
-/**
- * bd_release_from_disk - wrapper function for bd_release_from_kobject()
- *
- * @bdev: block device to be claimed
- * @disk: holder's gendisk
- *
- * Call bd_release_from_kobject() and put @disk->slave_dir.
- */
-void bd_release_from_disk(struct block_device *bdev, struct gendisk *disk)
-{
- bd_release_from_kobject(bdev, disk->slave_dir);
- kobject_put(disk->slave_dir);
-}
-EXPORT_SYMBOL_GPL(bd_release_from_disk);
-#endif
+ bdev->bd_holder_disk = NULL;
+ if (!disk)
+ return;
-/*
- * Tries to open block device by device number. Use it ONLY if you
- * really do not have anything better - i.e. when you are behind a
- * truly sucky interface and all you are given is a device number. _Never_
- * to be used for internal purposes. If you ever need it - reconsider
- * your API.
- */
-struct block_device *open_by_devnum(dev_t dev, fmode_t mode)
-{
- struct block_device *bdev = bdget(dev);
- int err = -ENOMEM;
- if (bdev)
- err = blkdev_get(bdev, mode);
- return err ? ERR_PTR(err) : bdev;
+ del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+ del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
}
-
-EXPORT_SYMBOL(open_by_devnum);
+#else
+static inline void bd_unlink_disk_holder(struct block_device *bdev)
+{ }
+#endif
/**
* flush_disk - invalidates all buffer-cache entries on a disk
@@ -1302,10 +954,11 @@ int check_disk_change(struct block_device *bdev)
{
struct gendisk *disk = bdev->bd_disk;
const struct block_device_operations *bdops = disk->fops;
+ unsigned int events;
- if (!bdops->media_changed)
- return 0;
- if (!bdops->media_changed(bdev->bd_disk))
+ events = disk_clear_events(disk, DISK_EVENT_MEDIA_CHANGE |
+ DISK_EVENT_EJECT_REQUEST);
+ if (!(events & DISK_EVENT_MEDIA_CHANGE))
return 0;
flush_disk(bdev);
@@ -1468,17 +1121,171 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
return ret;
}
-int blkdev_get(struct block_device *bdev, fmode_t mode)
+/**
+ * blkdev_get - open a block device
+ * @bdev: block_device to open
+ * @mode: FMODE_* mask
+ * @holder: exclusive holder identifier
+ *
+ * Open @bdev with @mode. If @mode includes %FMODE_EXCL, @bdev is
+ * open with exclusive access. Specifying %FMODE_EXCL with %NULL
+ * @holder is invalid. Exclusive opens may nest for the same @holder.
+ *
+ * On success, the reference count of @bdev is unchanged. On failure,
+ * @bdev is put.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
{
- return __blkdev_get(bdev, mode, 0);
+ struct block_device *whole = NULL;
+ int res;
+
+ WARN_ON_ONCE((mode & FMODE_EXCL) && !holder);
+
+ if ((mode & FMODE_EXCL) && holder) {
+ whole = bd_start_claiming(bdev, holder);
+ if (IS_ERR(whole)) {
+ bdput(bdev);
+ return PTR_ERR(whole);
+ }
+ }
+
+ res = __blkdev_get(bdev, mode, 0);
+
+ /* __blkdev_get() may alter read only status, check it afterwards */
+ if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) {
+ __blkdev_put(bdev, mode, 0);
+ res = -EACCES;
+ }
+
+ if (whole) {
+ /* finish claiming */
+ mutex_lock(&bdev->bd_mutex);
+ spin_lock(&bdev_lock);
+
+ if (!res) {
+ BUG_ON(!bd_may_claim(bdev, whole, holder));
+ /*
+ * Note that for a whole device bd_holders
+ * will be incremented twice, and bd_holder
+ * will be set to bd_may_claim before being
+ * set to holder
+ */
+ whole->bd_holders++;
+ whole->bd_holder = bd_may_claim;
+ bdev->bd_holders++;
+ bdev->bd_holder = holder;
+ }
+
+ /* tell others that we're done */
+ BUG_ON(whole->bd_claiming != holder);
+ whole->bd_claiming = NULL;
+ wake_up_bit(&whole->bd_claiming, 0);
+
+ spin_unlock(&bdev_lock);
+
+ /*
+ * Block event polling for write claims. Any write
+ * holder makes the write_holder state stick until all
+ * are released. This is good enough and tracking
+ * individual writeable reference is too fragile given
+ * the way @mode is used in blkdev_get/put().
+ */
+ if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) {
+ bdev->bd_write_holder = true;
+ disk_block_events(bdev->bd_disk);
+ }
+
+ mutex_unlock(&bdev->bd_mutex);
+ bdput(whole);
+ }
+
+ return res;
}
EXPORT_SYMBOL(blkdev_get);
+/**
+ * blkdev_get_by_path - open a block device by name
+ * @path: path to the block device to open
+ * @mode: FMODE_* mask
+ * @holder: exclusive holder identifier
+ *
+ * Open the blockdevice described by the device file at @path. @mode
+ * and @holder are identical to blkdev_get().
+ *
+ * On success, the returned block_device has reference count of one.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * Pointer to block_device on success, ERR_PTR(-errno) on failure.
+ */
+struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
+ void *holder)
+{
+ struct block_device *bdev;
+ int err;
+
+ bdev = lookup_bdev(path);
+ if (IS_ERR(bdev))
+ return bdev;
+
+ err = blkdev_get(bdev, mode, holder);
+ if (err)
+ return ERR_PTR(err);
+
+ return bdev;
+}
+EXPORT_SYMBOL(blkdev_get_by_path);
+
+/**
+ * blkdev_get_by_dev - open a block device by device number
+ * @dev: device number of block device to open
+ * @mode: FMODE_* mask
+ * @holder: exclusive holder identifier
+ *
+ * Open the blockdevice described by device number @dev. @mode and
+ * @holder are identical to blkdev_get().
+ *
+ * Use it ONLY if you really do not have anything better - i.e. when
+ * you are behind a truly sucky interface and all you are given is a
+ * device number. _Never_ to be used for internal purposes. If you
+ * ever need it - reconsider your API.
+ *
+ * On success, the returned block_device has reference count of one.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * Pointer to block_device on success, ERR_PTR(-errno) on failure.
+ */
+struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder)
+{
+ struct block_device *bdev;
+ int err;
+
+ bdev = bdget(dev);
+ if (!bdev)
+ return ERR_PTR(-ENOMEM);
+
+ err = blkdev_get(bdev, mode, holder);
+ if (err)
+ return ERR_PTR(err);
+
+ return bdev;
+}
+EXPORT_SYMBOL(blkdev_get_by_dev);
+
static int blkdev_open(struct inode * inode, struct file * filp)
{
- struct block_device *whole = NULL;
struct block_device *bdev;
- int res;
/*
* Preserve backwards compatibility and allow large file access
@@ -1499,26 +1306,9 @@ static int blkdev_open(struct inode * inode, struct file * filp)
if (bdev == NULL)
return -ENOMEM;
- if (filp->f_mode & FMODE_EXCL) {
- whole = bd_start_claiming(bdev, filp);
- if (IS_ERR(whole)) {
- bdput(bdev);
- return PTR_ERR(whole);
- }
- }
-
filp->f_mapping = bdev->bd_inode->i_mapping;
- res = blkdev_get(bdev, filp->f_mode);
-
- if (whole) {
- if (res == 0)
- bd_finish_claiming(bdev, whole, filp);
- else
- bd_abort_claiming(whole, filp);
- }
-
- return res;
+ return blkdev_get(bdev, filp->f_mode, filp);
}
static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
@@ -1532,6 +1322,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
bdev->bd_part_count--;
if (!--bdev->bd_openers) {
+ WARN_ON_ONCE(bdev->bd_holders);
sync_blockdev(bdev);
kill_bdev(bdev);
}
@@ -1562,6 +1353,45 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
int blkdev_put(struct block_device *bdev, fmode_t mode)
{
+ if (mode & FMODE_EXCL) {
+ bool bdev_free;
+
+ /*
+ * Release a claim on the device. The holder fields
+ * are protected with bdev_lock. bd_mutex is to
+ * synchronize disk_holder unlinking.
+ */
+ mutex_lock(&bdev->bd_mutex);
+ spin_lock(&bdev_lock);
+
+ WARN_ON_ONCE(--bdev->bd_holders < 0);
+ WARN_ON_ONCE(--bdev->bd_contains->bd_holders < 0);
+
+ /* bd_contains might point to self, check in a separate step */
+ if ((bdev_free = !bdev->bd_holders))
+ bdev->bd_holder = NULL;
+ if (!bdev->bd_contains->bd_holders)
+ bdev->bd_contains->bd_holder = NULL;
+
+ spin_unlock(&bdev_lock);
+
+ /*
+ * If this was the last claim, remove holder link and
+ * unblock evpoll if it was a write holder.
+ */
+ if (bdev_free) {
+ bd_unlink_disk_holder(bdev);
+ if (bdev->bd_write_holder) {
+ disk_unblock_events(bdev->bd_disk);
+ bdev->bd_write_holder = false;
+ } else
+ disk_check_events(bdev->bd_disk);
+ }
+
+ mutex_unlock(&bdev->bd_mutex);
+ } else
+ disk_check_events(bdev->bd_disk);
+
return __blkdev_put(bdev, mode, 0);
}
EXPORT_SYMBOL(blkdev_put);
@@ -1569,8 +1399,7 @@ EXPORT_SYMBOL(blkdev_put);
static int blkdev_close(struct inode * inode, struct file * filp)
{
struct block_device *bdev = I_BDEV(filp->f_mapping->host);
- if (bdev->bd_holder == filp)
- bd_release(bdev);
+
return blkdev_put(bdev, filp->f_mode);
}
@@ -1715,67 +1544,6 @@ fail:
}
EXPORT_SYMBOL(lookup_bdev);
-/**
- * open_bdev_exclusive - open a block device by name and set it up for use
- *
- * @path: special file representing the block device
- * @mode: FMODE_... combination to pass be used
- * @holder: owner for exclusion
- *
- * Open the blockdevice described by the special file at @path, claim it
- * for the @holder.
- */
-struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder)
-{
- struct block_device *bdev, *whole;
- int error;
-
- bdev = lookup_bdev(path);
- if (IS_ERR(bdev))
- return bdev;
-
- whole = bd_start_claiming(bdev, holder);
- if (IS_ERR(whole)) {
- bdput(bdev);
- return whole;
- }
-
- error = blkdev_get(bdev, mode);
- if (error)
- goto out_abort_claiming;
-
- error = -EACCES;
- if ((mode & FMODE_WRITE) && bdev_read_only(bdev))
- goto out_blkdev_put;
-
- bd_finish_claiming(bdev, whole, holder);
- return bdev;
-
-out_blkdev_put:
- blkdev_put(bdev, mode);
-out_abort_claiming:
- bd_abort_claiming(whole, holder);
- return ERR_PTR(error);
-}
-
-EXPORT_SYMBOL(open_bdev_exclusive);
-
-/**
- * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive()
- *
- * @bdev: blockdevice to close
- * @mode: mode, must match that used to open.
- *
- * This is the counterpart to open_bdev_exclusive().
- */
-void close_bdev_exclusive(struct block_device *bdev, fmode_t mode)
-{
- bd_release(bdev);
- blkdev_put(bdev, mode);
-}
-
-EXPORT_SYMBOL(close_bdev_exclusive);
-
int __invalidate_device(struct block_device *bdev)
{
struct super_block *sb = get_super(bdev);
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 2222d161c7b6..c03c75317995 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -185,18 +185,23 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
return ret;
}
-int btrfs_check_acl(struct inode *inode, int mask)
+int btrfs_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
{
struct posix_acl *acl;
int error = -EAGAIN;
- acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ } else {
+ acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- if (acl) {
- error = posix_acl_permission(inode, acl, mask);
- posix_acl_release(acl);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ if (acl) {
+ error = posix_acl_permission(inode, acl, mask);
+ posix_acl_release(acl);
+ }
}
return error;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index af52f6d7a4d8..4b978b608b5c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2544,9 +2544,9 @@ int btrfs_sync_fs(struct super_block *sb, int wait);
/* acl.c */
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
-int btrfs_check_acl(struct inode *inode, int mask);
+int btrfs_check_acl_rcu(struct inode *inode, int mask, unsigned int flags);
#else
-#define btrfs_check_acl NULL
+#define btrfs_check_acl_rcu NULL
#endif
int btrfs_init_acl(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c547cca26a26..51d2e4de34eb 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -696,6 +696,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
__btree_submit_bio_done);
}
+#ifdef CONFIG_MIGRATION
static int btree_migratepage(struct address_space *mapping,
struct page *newpage, struct page *page)
{
@@ -712,12 +713,9 @@ static int btree_migratepage(struct address_space *mapping,
if (page_has_private(page) &&
!try_to_release_page(page, GFP_KERNEL))
return -EAGAIN;
-#ifdef CONFIG_MIGRATION
return migrate_page(mapping, newpage, page);
-#else
- return -ENOSYS;
-#endif
}
+#endif
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
@@ -1009,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
blocksize, generation);
- BUG_ON(!root->node);
+ if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+ free_extent_buffer(root->node);
+ return -EIO;
+ }
root->commit_root = btrfs_root_node(root);
return 0;
}
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 6f0444473594..0ccf9a8afcdf 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -110,7 +110,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
dentry = d_obtain_alias(inode);
if (!IS_ERR(dentry))
- dentry->d_op = &btrfs_dentry_operations;
+ d_set_d_op(dentry, &btrfs_dentry_operations);
return dentry;
fail:
srcu_read_unlock(&fs_info->subvol_srcu, index);
@@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
static struct dentry *btrfs_get_parent(struct dentry *child)
{
struct inode *dir = child->d_inode;
- static struct dentry *dentry;
+ struct dentry *dentry;
struct btrfs_root *root = BTRFS_I(dir)->root;
struct btrfs_path *path;
struct extent_buffer *leaf;
@@ -225,7 +225,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
key.offset = 0;
dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
if (!IS_ERR(dentry))
- dentry->d_op = &btrfs_dentry_operations;
+ d_set_d_op(dentry, &btrfs_dentry_operations);
return dentry;
fail:
btrfs_free_path(path);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index bcd59c7dfb57..227e5815d838 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -429,6 +429,7 @@ err:
static int cache_block_group(struct btrfs_block_group_cache *cache,
struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
int load_cache_only)
{
struct btrfs_fs_info *fs_info = cache->fs_info;
@@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
/*
* We can't do the read from on-disk cache during a commit since we need
- * to have the normal tree locking.
+ * to have the normal tree locking. Also if we are currently trying to
+ * allocate blocks for the tree root we can't do the fast caching since
+ * we likely hold important locks.
*/
- if (!trans->transaction->in_commit) {
+ if (!trans->transaction->in_commit &&
+ (root && root != root->fs_info->tree_root)) {
spin_lock(&cache->lock);
if (cache->cached != BTRFS_CACHE_NO) {
spin_unlock(&cache->lock);
@@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
struct btrfs_root *root = block_group->fs_info->tree_root;
struct inode *inode = NULL;
u64 alloc_hint = 0;
+ int dcs = BTRFS_DC_ERROR;
int num_pages = 0;
int retries = 0;
int ret = 0;
@@ -2795,6 +2800,8 @@ again:
spin_lock(&block_group->lock);
if (block_group->cached != BTRFS_CACHE_FINISHED) {
+ /* We're not cached, don't bother trying to write stuff out */
+ dcs = BTRFS_DC_WRITTEN;
spin_unlock(&block_group->lock);
goto out_put;
}
@@ -2821,6 +2828,8 @@ again:
ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
num_pages, num_pages,
&alloc_hint);
+ if (!ret)
+ dcs = BTRFS_DC_SETUP;
btrfs_free_reserved_data_space(inode, num_pages);
out_put:
iput(inode);
@@ -2828,10 +2837,7 @@ out_free:
btrfs_release_path(root, path);
out:
spin_lock(&block_group->lock);
- if (ret)
- block_group->disk_cache_state = BTRFS_DC_ERROR;
- else
- block_group->disk_cache_state = BTRFS_DC_SETUP;
+ block_group->disk_cache_state = dcs;
spin_unlock(&block_group->lock);
return ret;
@@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
{
- u64 num_devices = root->fs_info->fs_devices->rw_devices;
+ /*
+ * we add in the count of missing devices because we want
+ * to make sure that any RAID levels on a degraded FS
+ * continue to be honored.
+ */
+ u64 num_devices = root->fs_info->fs_devices->rw_devices +
+ root->fs_info->fs_devices->missing_devices;
if (num_devices == 1)
flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
* space back to the block group, otherwise we will leak space.
*/
if (!alloc && cache->cached == BTRFS_CACHE_NO)
- cache_block_group(cache, trans, 1);
+ cache_block_group(cache, trans, NULL, 1);
byte_in_group = bytenr - cache->key.objectid;
WARN_ON(byte_in_group > cache->key.offset);
@@ -4930,11 +4942,31 @@ search:
btrfs_get_block_group(block_group);
search_start = block_group->key.objectid;
+ /*
+ * this can happen if we end up cycling through all the
+ * raid types, but we want to make sure we only allocate
+ * for the proper type.
+ */
+ if (!block_group_bits(block_group, data)) {
+ u64 extra = BTRFS_BLOCK_GROUP_DUP |
+ BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID10;
+
+ /*
+ * if they asked for extra copies and this block group
+ * doesn't provide them, bail. This does allow us to
+ * fill raid0 from raid1.
+ */
+ if ((data & extra) && !(block_group->flags & extra))
+ goto loop;
+ }
+
have_block_group:
if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
u64 free_percent;
- ret = cache_block_group(block_group, trans, 1);
+ ret = cache_block_group(block_group, trans,
+ orig_root, 1);
if (block_group->cached == BTRFS_CACHE_FINISHED)
goto have_block_group;
@@ -4958,7 +4990,8 @@ have_block_group:
if (loop > LOOP_CACHING_NOWAIT ||
(loop > LOOP_FIND_IDEAL &&
atomic_read(&space_info->caching_threads) < 2)) {
- ret = cache_block_group(block_group, trans, 0);
+ ret = cache_block_group(block_group, trans,
+ orig_root, 0);
BUG_ON(ret);
}
found_uncached_bg = true;
@@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
u64 num_bytes = ins->offset;
block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
- cache_block_group(block_group, trans, 0);
+ cache_block_group(block_group, trans, NULL, 0);
caching_ctl = get_caching_control(block_group);
if (!caching_ctl) {
@@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
NULL, NULL);
BUG_ON(ret < 0);
if (ret > 0) {
- ret = btrfs_del_orphan_item(trans, tree_root,
- root->root_key.objectid);
- BUG_ON(ret);
+ /* if we fail to delete the orphan item this time
+ * around, it'll get picked up the next time.
+ *
+ * The most common failure here is just -ENOENT.
+ */
+ btrfs_del_orphan_item(trans, tree_root,
+ root->root_key.objectid);
}
}
@@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
- num_devices = root->fs_info->fs_devices->rw_devices;
+ /*
+ * we add in the count of missing devices because we want
+ * to make sure that any RAID levels on a degraded FS
+ * continue to be honored.
+ */
+ num_devices = root->fs_info->fs_devices->rw_devices +
+ root->fs_info->fs_devices->missing_devices;
+
if (num_devices == 1) {
stripped |= BTRFS_BLOCK_GROUP_DUP;
stripped = flags & ~stripped;
@@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
break;
if (ret != 0)
goto error;
-
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
cache = kzalloc(sizeof(*cache), GFP_NOFS);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index c1faded5fca0..66836d85763b 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
struct page **prepared_pages,
struct iov_iter *i)
{
- size_t copied;
+ size_t copied = 0;
int pg = 0;
int offset = pos & (PAGE_CACHE_SIZE - 1);
+ int total_copied = 0;
while (write_bytes > 0) {
size_t count = min_t(size_t,
PAGE_CACHE_SIZE - offset, write_bytes);
struct page *page = prepared_pages[pg];
-again:
- if (unlikely(iov_iter_fault_in_readable(i, count)))
- return -EFAULT;
-
- /* Copy data from userspace to the current page */
- copied = iov_iter_copy_from_user(page, i, offset, count);
+ /*
+ * Copy data from userspace to the current page
+ *
+ * Disable pagefault to avoid recursive lock since
+ * the pages are already locked
+ */
+ pagefault_disable();
+ copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
+ pagefault_enable();
/* Flush processor's dcache for this page */
flush_dcache_page(page);
iov_iter_advance(i, copied);
write_bytes -= copied;
+ total_copied += copied;
+ /* Return to btrfs_file_aio_write to fault page */
if (unlikely(copied == 0)) {
- count = min_t(size_t, PAGE_CACHE_SIZE - offset,
- iov_iter_single_seg_count(i));
- goto again;
+ break;
}
if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
@@ -81,7 +85,7 @@ again:
offset = 0;
}
}
- return 0;
+ return total_copied;
}
/*
@@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
unsigned long last_index;
int will_write;
int buffered = 0;
+ int copied = 0;
+ int dirty_pages = 0;
will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
(file->f_flags & O_DIRECT));
@@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
WARN_ON(num_pages > nrptrs);
memset(pages, 0, sizeof(struct page *) * nrptrs);
- ret = btrfs_delalloc_reserve_space(inode, write_bytes);
+ /*
+ * Fault pages before locking them in prepare_pages
+ * to avoid recursive lock
+ */
+ if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = btrfs_delalloc_reserve_space(inode,
+ num_pages << PAGE_CACHE_SHIFT);
if (ret)
goto out;
@@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
pos, first_index, last_index,
write_bytes);
if (ret) {
- btrfs_delalloc_release_space(inode, write_bytes);
+ btrfs_delalloc_release_space(inode,
+ num_pages << PAGE_CACHE_SHIFT);
goto out;
}
- ret = btrfs_copy_from_user(pos, num_pages,
+ copied = btrfs_copy_from_user(pos, num_pages,
write_bytes, pages, &i);
- if (ret == 0) {
+ dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
+ PAGE_CACHE_SHIFT;
+
+ if (num_pages > dirty_pages) {
+ if (copied > 0)
+ atomic_inc(
+ &BTRFS_I(inode)->outstanding_extents);
+ btrfs_delalloc_release_space(inode,
+ (num_pages - dirty_pages) <<
+ PAGE_CACHE_SHIFT);
+ }
+
+ if (copied > 0) {
dirty_and_release_pages(NULL, root, file, pages,
- num_pages, pos, write_bytes);
+ dirty_pages, pos, copied);
}
btrfs_drop_pages(pages, num_pages);
- if (ret) {
- btrfs_delalloc_release_space(inode, write_bytes);
- goto out;
- }
- if (will_write) {
- filemap_fdatawrite_range(inode->i_mapping, pos,
- pos + write_bytes - 1);
- } else {
- balance_dirty_pages_ratelimited_nr(inode->i_mapping,
- num_pages);
- if (num_pages <
- (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
- btrfs_btree_balance_dirty(root, 1);
- btrfs_throttle(root);
+ if (copied > 0) {
+ if (will_write) {
+ filemap_fdatawrite_range(inode->i_mapping, pos,
+ pos + copied - 1);
+ } else {
+ balance_dirty_pages_ratelimited_nr(
+ inode->i_mapping,
+ dirty_pages);
+ if (dirty_pages <
+ (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+ btrfs_btree_balance_dirty(root, 1);
+ btrfs_throttle(root);
+ }
}
- pos += write_bytes;
- num_written += write_bytes;
+ pos += copied;
+ num_written += copied;
cond_resched();
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 22ee0dc2e6b8..60d684266959 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
(unsigned long long)BTRFS_I(inode)->generation,
(unsigned long long)generation,
(unsigned long long)block_group->key.objectid);
- goto out;
+ goto free_cache;
}
if (!num_entries)
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,
return 0;
}
+ node = rb_first(&block_group->free_space_offset);
+ if (!node) {
+ iput(inode);
+ return 0;
+ }
+
last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
filemap_write_and_wait(inode->i_mapping);
btrfs_wait_ordered_range(inode, inode->i_size &
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root,
*/
first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
- node = rb_first(&block_group->free_space_offset);
- if (!node)
- goto out_free;
-
/*
* Lock all pages first so we can lock the extent safely.
*
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8039390bd6a6..74b451464718 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -495,7 +495,7 @@ again:
add_async_extent(async_cow, start, num_bytes,
total_compressed, pages, nr_pages_ret);
- if (start + num_bytes < end && start + num_bytes < actual_end) {
+ if (start + num_bytes < end) {
start += num_bytes;
pages = NULL;
cond_resched();
@@ -4084,7 +4084,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
int index;
int ret;
- dentry->d_op = &btrfs_dentry_operations;
+ d_set_d_op(dentry, &btrfs_dentry_operations);
if (dentry->d_name.len > BTRFS_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
@@ -4127,7 +4127,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
return inode;
}
-static int btrfs_dentry_delete(struct dentry *dentry)
+static int btrfs_dentry_delete(const struct dentry *dentry)
{
struct btrfs_root *root;
@@ -5712,9 +5712,9 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
if (err) {
printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu "
- "disk_bytenr %lu len %u err no %d\n",
- dip->inode->i_ino, bio->bi_rw, bio->bi_sector,
- bio->bi_size, err);
+ "sector %#Lx len %u err no %d\n",
+ dip->inode->i_ino, bio->bi_rw,
+ (unsigned long long)bio->bi_sector, bio->bi_size, err);
dip->errors = 1;
/*
@@ -5934,8 +5934,7 @@ free_ordered:
*/
if (write) {
struct btrfs_ordered_extent *ordered;
- ordered = btrfs_lookup_ordered_extent(inode,
- dip->logical_offset);
+ ordered = btrfs_lookup_ordered_extent(inode, file_offset);
if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
!test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
btrfs_free_reserved_extent(root, ordered->start,
@@ -6496,6 +6495,13 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
return inode;
}
+static void btrfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+}
+
void btrfs_destroy_inode(struct inode *inode)
{
struct btrfs_ordered_extent *ordered;
@@ -6565,7 +6571,7 @@ void btrfs_destroy_inode(struct inode *inode)
inode_tree_del(inode);
btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
free:
- kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+ call_rcu(&inode->i_rcu, btrfs_i_callback);
}
int btrfs_drop_inode(struct inode *inode)
@@ -7205,11 +7211,11 @@ static int btrfs_set_page_dirty(struct page *page)
return __set_page_dirty_nobuffers(page);
}
-static int btrfs_permission(struct inode *inode, int mask)
+static int btrfs_permission_rcu(struct inode *inode, int mask, unsigned int flags)
{
if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE))
return -EACCES;
- return generic_permission(inode, mask, btrfs_check_acl);
+ return generic_permission_rcu(inode, mask, flags, btrfs_check_acl_rcu);
}
static const struct inode_operations btrfs_dir_inode_operations = {
@@ -7228,11 +7234,11 @@ static const struct inode_operations btrfs_dir_inode_operations = {
.getxattr = btrfs_getxattr,
.listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr,
- .permission = btrfs_permission,
+ .permission_rcu = btrfs_permission_rcu,
};
static const struct inode_operations btrfs_dir_ro_inode_operations = {
.lookup = btrfs_lookup,
- .permission = btrfs_permission,
+ .permission_rcu = btrfs_permission_rcu,
};
static const struct file_operations btrfs_dir_file_operations = {
@@ -7301,14 +7307,14 @@ static const struct inode_operations btrfs_file_inode_operations = {
.getxattr = btrfs_getxattr,
.listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr,
- .permission = btrfs_permission,
+ .permission_rcu = btrfs_permission_rcu,
.fallocate = btrfs_fallocate,
.fiemap = btrfs_fiemap,
};
static const struct inode_operations btrfs_special_inode_operations = {
.getattr = btrfs_getattr,
.setattr = btrfs_setattr,
- .permission = btrfs_permission,
+ .permission_rcu = btrfs_permission_rcu,
.setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr,
.listxattr = btrfs_listxattr,
@@ -7319,7 +7325,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
.follow_link = page_follow_link_light,
.put_link = page_put_link,
.getattr = btrfs_getattr,
- .permission = btrfs_permission,
+ .permission_rcu = btrfs_permission_rcu,
.setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr,
.listxattr = btrfs_listxattr,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f1c9bb4079ed..f87552a1d7ea 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -947,23 +947,42 @@ out:
static noinline int btrfs_ioctl_snap_create(struct file *file,
void __user *arg, int subvol,
- int async)
+ int v2)
{
struct btrfs_ioctl_vol_args *vol_args = NULL;
- struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+ struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
char *name;
u64 fd;
- u64 transid = 0;
int ret;
- if (async) {
- async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
- if (IS_ERR(async_vol_args))
- return PTR_ERR(async_vol_args);
+ if (v2) {
+ u64 transid = 0;
+ u64 *ptr = NULL;
- name = async_vol_args->name;
- fd = async_vol_args->fd;
- async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+ vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
+ if (IS_ERR(vol_args_v2))
+ return PTR_ERR(vol_args_v2);
+
+ if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ name = vol_args_v2->name;
+ fd = vol_args_v2->fd;
+ vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
+
+ if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
+ ptr = &transid;
+
+ ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+ subvol, ptr);
+
+ if (ret == 0 && ptr &&
+ copy_to_user(arg +
+ offsetof(struct btrfs_ioctl_vol_args_v2,
+ transid), ptr, sizeof(*ptr)))
+ ret = -EFAULT;
} else {
vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
@@ -971,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
name = vol_args->name;
fd = vol_args->fd;
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
- }
-
- ret = btrfs_ioctl_snap_create_transid(file, name, fd,
- subvol, &transid);
- if (!ret && async) {
- if (copy_to_user(arg +
- offsetof(struct btrfs_ioctl_async_vol_args,
- transid), &transid, sizeof(transid)))
- return -EFAULT;
+ ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+ subvol, NULL);
}
-
+out:
kfree(vol_args);
- kfree(async_vol_args);
+ kfree(vol_args_v2);
return ret;
}
@@ -2246,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_getversion(file, argp);
case BTRFS_IOC_SNAP_CREATE:
return btrfs_ioctl_snap_create(file, argp, 0, 0);
- case BTRFS_IOC_SNAP_CREATE_ASYNC:
+ case BTRFS_IOC_SNAP_CREATE_V2:
return btrfs_ioctl_snap_create(file, argp, 0, 1);
case BTRFS_IOC_SUBVOL_CREATE:
return btrfs_ioctl_snap_create(file, argp, 1, 0);
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 17c99ebdf960..c344d12c646b 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
char name[BTRFS_PATH_NAME_MAX + 1];
};
-#define BTRFS_SNAPSHOT_NAME_MAX 4079
-struct btrfs_ioctl_async_vol_args {
+#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
+
+#define BTRFS_SUBVOL_NAME_MAX 4039
+struct btrfs_ioctl_vol_args_v2 {
__s64 fd;
__u64 transid;
- char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+ __u64 flags;
+ __u64 unused[4];
+ char name[BTRFS_SUBVOL_NAME_MAX + 1];
};
#define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
struct btrfs_ioctl_space_args)
#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
- struct btrfs_ioctl_async_vol_args)
+#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
+ struct btrfs_ioctl_vol_args_v2)
#endif
diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c
index 79cba5fbc28e..f8be250963a0 100644
--- a/fs/btrfs/orphan.c
+++ b/fs/btrfs/orphan.c
@@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans,
return -ENOMEM;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
- if (ret)
+ if (ret < 0)
goto out;
+ if (ret) {
+ ret = -ENOENT;
+ goto out;
+ }
ret = btrfs_del_item(trans, root, path);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index dbb51ea7a13c..883c6fa1367e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -685,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
mutex_unlock(&root->d_inode->i_mutex);
if (IS_ERR(new_root)) {
+ dput(root);
deactivate_locked_super(s);
error = PTR_ERR(new_root);
- dput(root);
goto error_free_subvol_name;
}
if (!new_root->d_inode) {
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index cc04dc1445d6..1718e1a5c320 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path,
device->fs_devices = fs_devices;
fs_devices->num_devices++;
- } else if (strcmp(device->name, path)) {
+ } else if (!device->name || strcmp(device->name, path)) {
name = kstrdup(path, GFP_NOFS);
if (!name)
return -ENOMEM;
kfree(device->name);
device->name = name;
+ if (device->missing) {
+ fs_devices->missing_devices--;
+ device->missing = 0;
+ }
}
if (found_transid > fs_devices->latest_trans) {
@@ -489,7 +493,7 @@ again:
continue;
if (device->bdev) {
- close_bdev_exclusive(device->bdev, device->mode);
+ blkdev_put(device->bdev, device->mode);
device->bdev = NULL;
fs_devices->open_devices--;
}
@@ -523,7 +527,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (device->bdev) {
- close_bdev_exclusive(device->bdev, device->mode);
+ blkdev_put(device->bdev, device->mode);
fs_devices->open_devices--;
}
if (device->writeable) {
@@ -580,13 +584,15 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
int seeding = 1;
int ret = 0;
+ flags |= FMODE_EXCL;
+
list_for_each_entry(device, head, dev_list) {
if (device->bdev)
continue;
if (!device->name)
continue;
- bdev = open_bdev_exclusive(device->name, flags, holder);
+ bdev = blkdev_get_by_path(device->name, flags, holder);
if (IS_ERR(bdev)) {
printk(KERN_INFO "open %s failed\n", device->name);
goto error;
@@ -638,7 +644,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
error_brelse:
brelse(bh);
error_close:
- close_bdev_exclusive(bdev, FMODE_READ);
+ blkdev_put(bdev, flags);
error:
continue;
}
@@ -684,7 +690,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
mutex_lock(&uuid_mutex);
- bdev = open_bdev_exclusive(path, flags, holder);
+ flags |= FMODE_EXCL;
+ bdev = blkdev_get_by_path(path, flags, holder);
if (IS_ERR(bdev)) {
ret = PTR_ERR(bdev);
@@ -716,7 +723,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
brelse(bh);
error_close:
- close_bdev_exclusive(bdev, flags);
+ blkdev_put(bdev, flags);
error:
mutex_unlock(&uuid_mutex);
return ret;
@@ -1179,8 +1186,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
goto out;
}
} else {
- bdev = open_bdev_exclusive(device_path, FMODE_READ,
- root->fs_info->bdev_holder);
+ bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL,
+ root->fs_info->bdev_holder);
if (IS_ERR(bdev)) {
ret = PTR_ERR(bdev);
goto out;
@@ -1236,6 +1243,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
device->fs_devices->num_devices--;
+ if (device->missing)
+ root->fs_info->fs_devices->missing_devices--;
+
next_device = list_entry(root->fs_info->fs_devices->devices.next,
struct btrfs_device, dev_list);
if (device->bdev == root->fs_info->sb->s_bdev)
@@ -1244,7 +1254,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
root->fs_info->fs_devices->latest_bdev = next_device->bdev;
if (device->bdev) {
- close_bdev_exclusive(device->bdev, device->mode);
+ blkdev_put(device->bdev, device->mode);
device->bdev = NULL;
device->fs_devices->open_devices--;
}
@@ -1287,7 +1297,7 @@ error_brelse:
brelse(bh);
error_close:
if (bdev)
- close_bdev_exclusive(bdev, FMODE_READ);
+ blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
out:
mutex_unlock(&root->fs_info->volume_mutex);
mutex_unlock(&uuid_mutex);
@@ -1439,7 +1449,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding)
return -EINVAL;
- bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder);
+ bdev = blkdev_get_by_path(device_path, FMODE_EXCL,
+ root->fs_info->bdev_holder);
if (IS_ERR(bdev))
return PTR_ERR(bdev);
@@ -1565,7 +1576,7 @@ out:
mutex_unlock(&root->fs_info->volume_mutex);
return ret;
error:
- close_bdev_exclusive(bdev, 0);
+ blkdev_put(bdev, FMODE_EXCL);
if (seeding_dev) {
mutex_unlock(&uuid_mutex);
up_write(&sb->s_umount);
@@ -3080,7 +3091,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
device->devid = devid;
device->work.func = pending_bios_fn;
device->fs_devices = fs_devices;
+ device->missing = 1;
fs_devices->num_devices++;
+ fs_devices->missing_devices++;
spin_lock_init(&device->io_lock);
INIT_LIST_HEAD(&device->dev_alloc_list);
memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3278,6 +3291,15 @@ static int read_one_dev(struct btrfs_root *root,
device = add_missing_dev(root, devid, dev_uuid);
if (!device)
return -ENOMEM;
+ } else if (!device->missing) {
+ /*
+ * this happens when a device that was properly setup
+ * in the device info lists suddenly goes bad.
+ * device->bdev is NULL, and so we have to set
+ * device->missing to one here
+ */
+ root->fs_info->fs_devices->missing_devices++;
+ device->missing = 1;
}
}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 2b638b6e4eea..1be781079450 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -44,12 +44,13 @@ struct btrfs_device {
int writeable;
int in_fs_metadata;
+ int missing;
spinlock_t io_lock;
struct block_device *bdev;
- /* the mode sent to open_bdev_exclusive */
+ /* the mode sent to blkdev_get */
fmode_t mode;
char *name;
@@ -93,6 +94,7 @@ struct btrfs_fs_devices {
u64 num_devices;
u64 open_devices;
u64 rw_devices;
+ u64 missing_devices;
u64 total_rw_bytes;
struct block_device *latest_bdev;
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile
index 9e6c4f2e8ff1..bd352125e829 100644
--- a/fs/ceph/Makefile
+++ b/fs/ceph/Makefile
@@ -2,31 +2,10 @@
# Makefile for CEPH filesystem.
#
-ifneq ($(KERNELRELEASE),)
-
obj-$(CONFIG_CEPH_FS) += ceph.o
-ceph-objs := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
+ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
export.o caps.o snap.o xattr.o \
mds_client.o mdsmap.o strings.o ceph_frag.o \
debugfs.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/debugfs.c b/fs/ceph/debugfs.c
index 7ae1b3d55b58..08f65faac112 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -60,10 +60,13 @@ static int mdsc_show(struct seq_file *s, void *p)
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
+ if (req->r_request && req->r_session)
+ seq_printf(s, "%lld\tmds%d\t", req->r_tid,
+ req->r_session->s_mds);
+ else if (!req->r_request)
seq_printf(s, "%lld\t(no request)\t", req->r_tid);
+ else
+ seq_printf(s, "%lld\t(no session)\t", req->r_tid);
seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 7d447af84ec4..46c1b89e0b15 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -40,12 +40,13 @@ int ceph_init_dentry(struct dentry *dentry)
if (dentry->d_fsdata)
return 0;
- if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
- dentry->d_op = &ceph_dentry_ops;
+ if (dentry->d_parent == NULL || /* nfs fh_to_dentry */
+ ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
+ d_set_d_op(dentry->d_op, &ceph_dentry_ops);
else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR)
- dentry->d_op = &ceph_snapdir_dentry_ops;
+ d_set_d_op(dentry->d_op, &ceph_snapdir_dentry_ops);
else
- dentry->d_op = &ceph_snap_dentry_ops;
+ d_set_d_op(dentry->d_op, &ceph_snap_dentry_ops);
di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO);
if (!di)
@@ -111,11 +112,11 @@ static int __dcache_readdir(struct file *filp,
dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,
last);
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
/* start at beginning? */
- if (filp->f_pos == 2 || (last &&
- filp->f_pos < ceph_dentry(last)->offset)) {
+ if (filp->f_pos == 2 || last == NULL ||
+ filp->f_pos < ceph_dentry(last)->offset) {
if (list_empty(&parent->d_subdirs))
goto out_unlock;
p = parent->d_subdirs.prev;
@@ -135,6 +136,7 @@ more:
fi->at_end = 1;
goto out_unlock;
}
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
if (!d_unhashed(dentry) && dentry->d_inode &&
ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
@@ -144,13 +146,15 @@ more:
dentry->d_name.len, dentry->d_name.name, di->offset,
filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
!dentry->d_inode ? " null" : "");
+ spin_unlock(&dentry->d_lock);
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);
+ dget_dlock(dentry);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&parent->d_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);
@@ -176,19 +180,19 @@ more:
filp->f_pos++;
- /* make sure a dentry wasn't dropped while we didn't have dcache_lock */
+ /* make sure a dentry wasn't dropped while we didn't have parent lock */
if (!ceph_i_test(dir, CEPH_I_COMPLETE)) {
dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
err = -EAGAIN;
goto out;
}
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
p = p->prev; /* advance to next dentry */
goto more;
out_unlock:
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
out:
if (last)
dput(last);
@@ -1215,6 +1219,26 @@ void ceph_dentry_lru_del(struct dentry *dn)
}
}
+/*
+ * Return name hash for a given dentry. This is dependent on
+ * the parent directory's hash function.
+ */
+unsigned ceph_dentry_hash(struct dentry *dn)
+{
+ struct inode *dir = dn->d_parent->d_inode;
+ struct ceph_inode_info *dci = ceph_inode(dir);
+
+ switch (dci->i_dir_layout.dl_dir_hash) {
+ case 0: /* for backward compat */
+ case CEPH_STR_HASH_LINUX:
+ return dn->d_name.hash;
+
+ default:
+ return ceph_str_hash(dci->i_dir_layout.dl_dir_hash,
+ dn->d_name.name, dn->d_name.len);
+ }
+}
+
const struct file_operations ceph_dir_fops = {
.read = ceph_read_dir,
.readdir = ceph_readdir,
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 2297d9426992..e41056174bf8 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -59,7 +59,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
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;
+ cfh->parent_name_hash = ceph_dentry_hash(parent);
*max_len = connected_handle_length;
type = 2;
} else if (*max_len >= handle_length) {
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 8d79b8912e31..7d0e4a82d898 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -282,7 +282,8 @@ int ceph_release(struct inode *inode, struct file *file)
static int striped_read(struct inode *inode,
u64 off, u64 len,
struct page **pages, int num_pages,
- int *checkeof, bool align_to_pages)
+ int *checkeof, bool align_to_pages,
+ unsigned long buf_align)
{
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
struct ceph_inode_info *ci = ceph_inode(inode);
@@ -307,7 +308,7 @@ static int striped_read(struct inode *inode,
more:
if (align_to_pages)
- page_align = (pos - io_align) & ~PAGE_MASK;
+ page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
else
page_align = pos & ~PAGE_MASK;
this_len = left;
@@ -376,16 +377,18 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
struct inode *inode = file->f_dentry->d_inode;
struct page **pages;
u64 off = *poff;
- int num_pages = calc_pages_for(off, len);
- int ret;
+ int num_pages, 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 = ceph_get_direct_page_vector(data, num_pages);
- else
+ if (file->f_flags & O_DIRECT) {
+ num_pages = calc_pages_for((unsigned long)data, len);
+ pages = ceph_get_direct_page_vector(data, num_pages, true);
+ } else {
+ num_pages = calc_pages_for(off, len);
pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
+ }
if (IS_ERR(pages))
return PTR_ERR(pages);
@@ -400,7 +403,8 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
goto done;
ret = striped_read(inode, off, len, pages, num_pages, checkeof,
- file->f_flags & O_DIRECT);
+ file->f_flags & O_DIRECT,
+ (unsigned long)data & ~PAGE_MASK);
if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
ret = ceph_copy_page_vector_to_user(pages, data, off, ret);
@@ -409,7 +413,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
done:
if (file->f_flags & O_DIRECT)
- ceph_put_page_vector(pages, num_pages);
+ ceph_put_page_vector(pages, num_pages, true);
else
ceph_release_page_vector(pages, num_pages);
dout("sync_read result %d\n", ret);
@@ -456,6 +460,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
int do_sync = 0;
int check_caps = 0;
int page_align, io_align;
+ unsigned long buf_align;
int ret;
struct timespec mtime = CURRENT_TIME;
@@ -471,6 +476,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
pos = *offset;
io_align = pos & ~PAGE_MASK;
+ buf_align = (unsigned long)data & ~PAGE_MASK;
ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
if (ret < 0)
@@ -496,12 +502,15 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
*/
more:
len = left;
- if (file->f_flags & O_DIRECT)
+ if (file->f_flags & O_DIRECT) {
/* write from beginning of first page, regardless of
io alignment */
- page_align = (pos - io_align) & ~PAGE_MASK;
- else
+ page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
+ num_pages = calc_pages_for((unsigned long)data, len);
+ } else {
page_align = pos & ~PAGE_MASK;
+ num_pages = calc_pages_for(pos, len);
+ }
req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
ceph_vino(inode), pos, &len,
CEPH_OSD_OP_WRITE, flags,
@@ -512,10 +521,8 @@ more:
if (!req)
return -ENOMEM;
- num_pages = calc_pages_for(pos, len);
-
if (file->f_flags & O_DIRECT) {
- pages = ceph_get_direct_page_vector(data, num_pages);
+ pages = ceph_get_direct_page_vector(data, num_pages, false);
if (IS_ERR(pages)) {
ret = PTR_ERR(pages);
goto out;
@@ -565,7 +572,7 @@ more:
}
if (file->f_flags & O_DIRECT)
- ceph_put_page_vector(pages, num_pages);
+ ceph_put_page_vector(pages, num_pages, false);
else if (file->f_flags & O_SYNC)
ceph_release_page_vector(pages, num_pages);
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index bf1286588f26..b0b6f9e1faad 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -297,6 +297,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
ci->i_release_count = 0;
ci->i_symlink = NULL;
+ memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout));
+
ci->i_fragtree = RB_ROOT;
mutex_init(&ci->i_fragtree_mutex);
@@ -368,6 +370,15 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
return &ci->vfs_inode;
}
+static void ceph_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ceph_inode_cachep, ci);
+}
+
void ceph_destroy_inode(struct inode *inode)
{
struct ceph_inode_info *ci = ceph_inode(inode);
@@ -407,7 +418,7 @@ void ceph_destroy_inode(struct inode *inode)
if (ci->i_xattrs.prealloc_blob)
ceph_buffer_put(ci->i_xattrs.prealloc_blob);
- kmem_cache_free(ceph_inode_cachep, ci);
+ call_rcu(&inode->i_rcu, ceph_i_callback);
}
@@ -680,6 +691,8 @@ static int fill_inode(struct inode *inode,
inode->i_op = &ceph_dir_iops;
inode->i_fop = &ceph_dir_fops;
+ ci->i_dir_layout = iinfo->dir_layout;
+
ci->i_files = le64_to_cpu(info->files);
ci->i_subdirs = le64_to_cpu(info->subdirs);
ci->i_rbytes = le64_to_cpu(info->rbytes);
@@ -841,13 +854,13 @@ static void ceph_set_dentry_offset(struct dentry *dn)
di->offset = ceph_inode(inode)->i_max_offset++;
spin_unlock(&inode->i_lock);
- spin_lock(&dcache_lock);
- spin_lock(&dn->d_lock);
+ spin_lock(&dir->d_lock);
+ spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
list_move(&dn->d_u.d_child, &dir->d_subdirs);
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);
+ spin_unlock(&dir->d_lock);
}
/*
@@ -879,8 +892,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
} 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),
+ dn, dn->d_count,
+ realdn, realdn->d_count,
realdn->d_inode, ceph_vinop(realdn->d_inode));
dput(dn);
dn = realdn;
@@ -1231,11 +1244,11 @@ retry_lookup:
goto retry_lookup;
} else {
/* reorder parent's d_subdirs */
- spin_lock(&dcache_lock);
- spin_lock(&dn->d_lock);
+ spin_lock(&parent->d_lock);
+ spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
list_move(&dn->d_u.d_child, &parent->d_subdirs);
spin_unlock(&dn->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
di = dn->d_fsdata;
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h
index a6ce54e94eb5..52e8fd74d450 100644
--- a/fs/ceph/ioctl.h
+++ b/fs/ceph/ioctl.h
@@ -4,7 +4,7 @@
#include <linux/ioctl.h>
#include <linux/types.h>
-#define CEPH_IOCTL_MAGIC 0x98
+#define CEPH_IOCTL_MAGIC 0x97
/* just use u64 to align sanely on all archs */
struct ceph_ioctl_layout {
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index 40abde93c345..476b329867d4 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -11,40 +11,68 @@
* Implement fcntl and flock locking functions.
*/
static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
- u64 pid, u64 pid_ns,
- int cmd, u64 start, u64 length, u8 wait)
+ int cmd, u8 wait, struct file_lock *fl)
{
struct inode *inode = file->f_dentry->d_inode;
struct ceph_mds_client *mdsc =
ceph_sb_to_client(inode->i_sb)->mdsc;
struct ceph_mds_request *req;
int err;
+ u64 length = 0;
req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
req->r_inode = igrab(inode);
+ /* mds requires start and length rather than start and end */
+ if (LLONG_MAX == fl->fl_end)
+ length = 0;
+ else
+ length = fl->fl_end - fl->fl_start + 1;
+
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
"length: %llu, wait: %d, type`: %d", (int)lock_type,
- (int)operation, pid, start, length, wait, cmd);
+ (int)operation, (u64)fl->fl_pid, fl->fl_start,
+ length, wait, fl->fl_type);
+
req->r_args.filelock_change.rule = lock_type;
req->r_args.filelock_change.type = cmd;
- req->r_args.filelock_change.pid = cpu_to_le64(pid);
+ req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
/* This should be adjusted, but I'm not sure if
namespaces actually get id numbers*/
req->r_args.filelock_change.pid_namespace =
- cpu_to_le64((u64)pid_ns);
- req->r_args.filelock_change.start = cpu_to_le64(start);
+ cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
+ req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
req->r_args.filelock_change.length = cpu_to_le64(length);
req->r_args.filelock_change.wait = wait;
err = ceph_mdsc_do_request(mdsc, inode, req);
+
+ if ( operation == CEPH_MDS_OP_GETFILELOCK){
+ fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
+ if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
+ fl->fl_type = F_RDLCK;
+ else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
+ fl->fl_type = F_WRLCK;
+ else
+ fl->fl_type = F_UNLCK;
+
+ fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
+ length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
+ le64_to_cpu(req->r_reply_info.filelock_reply->length);
+ if (length >= 1)
+ fl->fl_end = length -1;
+ else
+ fl->fl_end = 0;
+
+ }
ceph_mdsc_put_request(req);
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
- "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type,
- (int)operation, pid, start, length, wait, cmd, err);
+ "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
+ (int)operation, (u64)fl->fl_pid, fl->fl_start,
+ length, wait, fl->fl_type, err);
return err;
}
@@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
*/
int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
{
- u64 length;
u8 lock_cmd;
int err;
u8 wait = 0;
@@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
else
lock_cmd = CEPH_LOCK_UNLOCK;
- if (LLONG_MAX == fl->fl_end)
- length = 0;
- else
- length = fl->fl_end - fl->fl_start + 1;
-
- err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
- (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- lock_cmd, fl->fl_start,
- length, wait);
+ err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
if (!err) {
- dout("mds locked, locking locally");
- err = posix_lock_file(file, fl, NULL);
- if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
- /* undo! This should only happen if the kernel detects
- * local deadlock. */
- ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
- (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- CEPH_LOCK_UNLOCK, fl->fl_start,
- length, 0);
- dout("got %d on posix_lock_file, undid lock", err);
+ if ( op != CEPH_MDS_OP_GETFILELOCK ){
+ dout("mds locked, locking locally");
+ err = posix_lock_file(file, fl, NULL);
+ if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
+ /* undo! This should only happen if the kernel detects
+ * local deadlock. */
+ ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
+ CEPH_LOCK_UNLOCK, 0, fl);
+ dout("got %d on posix_lock_file, undid lock", err);
+ }
}
+
} else {
dout("mds returned error code %d", err);
}
@@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
{
- u64 length;
u8 lock_cmd;
int err;
u8 wait = 1;
@@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
lock_cmd = CEPH_LOCK_EXCL;
else
lock_cmd = CEPH_LOCK_UNLOCK;
- /* mds requires start and length rather than start and end */
- if (LLONG_MAX == fl->fl_end)
- length = 0;
- else
- length = fl->fl_end - fl->fl_start + 1;
err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
- file, (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- lock_cmd, fl->fl_start,
- length, wait);
+ file, lock_cmd, wait, fl);
if (!err) {
err = flock_lock_file_wait(file, fl);
if (err) {
ceph_lock_message(CEPH_LOCK_FLOCK,
CEPH_MDS_OP_SETFILELOCK,
- file, (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- CEPH_LOCK_UNLOCK, fl->fl_start,
- length, 0);
+ file, CEPH_LOCK_UNLOCK, 0, fl);
dout("got %d on flock_lock_file_wait, undid lock", err);
}
} else {
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 098b18508479..1e30d194a8e3 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -60,7 +60,8 @@ static const struct ceph_connection_operations mds_con_ops;
* parse individual inode info
*/
static int parse_reply_info_in(void **p, void *end,
- struct ceph_mds_reply_info_in *info)
+ struct ceph_mds_reply_info_in *info,
+ int features)
{
int err = -EIO;
@@ -74,6 +75,12 @@ static int parse_reply_info_in(void **p, void *end,
info->symlink = *p;
*p += info->symlink_len;
+ if (features & CEPH_FEATURE_DIRLAYOUTHASH)
+ ceph_decode_copy_safe(p, end, &info->dir_layout,
+ sizeof(info->dir_layout), bad);
+ else
+ memset(&info->dir_layout, 0, sizeof(info->dir_layout));
+
ceph_decode_32_safe(p, end, info->xattr_len, bad);
ceph_decode_need(p, end, info->xattr_len, bad);
info->xattr_data = *p;
@@ -88,12 +95,13 @@ bad:
* target inode.
*/
static int parse_reply_info_trace(void **p, void *end,
- struct ceph_mds_reply_info_parsed *info)
+ struct ceph_mds_reply_info_parsed *info,
+ int features)
{
int err;
if (info->head->is_dentry) {
- err = parse_reply_info_in(p, end, &info->diri);
+ err = parse_reply_info_in(p, end, &info->diri, features);
if (err < 0)
goto out_bad;
@@ -114,7 +122,7 @@ static int parse_reply_info_trace(void **p, void *end,
}
if (info->head->is_target) {
- err = parse_reply_info_in(p, end, &info->targeti);
+ err = parse_reply_info_in(p, end, &info->targeti, features);
if (err < 0)
goto out_bad;
}
@@ -134,7 +142,8 @@ out_bad:
* parse readdir results
*/
static int parse_reply_info_dir(void **p, void *end,
- struct ceph_mds_reply_info_parsed *info)
+ struct ceph_mds_reply_info_parsed *info,
+ int features)
{
u32 num, i = 0;
int err;
@@ -182,7 +191,7 @@ static int parse_reply_info_dir(void **p, void *end,
*p += sizeof(struct ceph_mds_reply_lease);
/* inode */
- err = parse_reply_info_in(p, end, &info->dir_in[i]);
+ err = parse_reply_info_in(p, end, &info->dir_in[i], features);
if (err < 0)
goto out_bad;
i++;
@@ -202,10 +211,45 @@ out_bad:
}
/*
+ * parse fcntl F_GETLK results
+ */
+static int parse_reply_info_filelock(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info,
+ int features)
+{
+ if (*p + sizeof(*info->filelock_reply) > end)
+ goto bad;
+
+ info->filelock_reply = *p;
+ *p += sizeof(*info->filelock_reply);
+
+ if (unlikely(*p != end))
+ goto bad;
+ return 0;
+
+bad:
+ return -EIO;
+}
+
+/*
+ * parse extra results
+ */
+static int parse_reply_info_extra(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info,
+ int features)
+{
+ if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
+ return parse_reply_info_filelock(p, end, info, features);
+ else
+ return parse_reply_info_dir(p, end, info, features);
+}
+
+/*
* parse entire mds reply
*/
static int parse_reply_info(struct ceph_msg *msg,
- struct ceph_mds_reply_info_parsed *info)
+ struct ceph_mds_reply_info_parsed *info,
+ int features)
{
void *p, *end;
u32 len;
@@ -218,15 +262,15 @@ static int parse_reply_info(struct ceph_msg *msg,
/* trace */
ceph_decode_32_safe(&p, end, len, bad);
if (len > 0) {
- err = parse_reply_info_trace(&p, p+len, info);
+ err = parse_reply_info_trace(&p, p+len, info, features);
if (err < 0)
goto out_bad;
}
- /* dir content */
+ /* extra */
ceph_decode_32_safe(&p, end, len, bad);
if (len > 0) {
- err = parse_reply_info_dir(&p, p+len, info);
+ err = parse_reply_info_extra(&p, p+len, info, features);
if (err < 0)
goto out_bad;
}
@@ -622,7 +666,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
} else {
/* dir + name */
inode = dir;
- hash = req->r_dentry->d_name.hash;
+ hash = ceph_dentry_hash(req->r_dentry);
is_hash = true;
}
}
@@ -1454,7 +1498,7 @@ retry:
*base = ceph_ino(temp->d_inode);
*plen = len;
dout("build_path on %p %d built %llx '%.*s'\n",
- dentry, atomic_read(&dentry->d_count), *base, len, path);
+ dentry, dentry->d_count, *base, len, path);
return path;
}
@@ -1661,7 +1705,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
struct ceph_msg *msg;
int flags = 0;
- req->r_mds = mds;
req->r_attempts++;
if (req->r_inode) {
struct ceph_cap *cap =
@@ -1748,6 +1791,8 @@ static int __do_request(struct ceph_mds_client *mdsc,
goto finish;
}
+ put_request_session(req);
+
mds = __choose_mds(mdsc, req);
if (mds < 0 ||
ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
@@ -1765,6 +1810,8 @@ static int __do_request(struct ceph_mds_client *mdsc,
goto finish;
}
}
+ req->r_session = get_session(session);
+
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 &&
@@ -1777,7 +1824,6 @@ static int __do_request(struct ceph_mds_client *mdsc,
}
/* 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 */
@@ -1831,7 +1877,6 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds)
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);
}
}
@@ -2024,8 +2069,11 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
goto out;
} else {
struct ceph_inode_info *ci = ceph_inode(req->r_inode);
- struct ceph_cap *cap =
- ceph_get_cap_for_mds(ci, req->r_mds);;
+ struct ceph_cap *cap = NULL;
+
+ if (req->r_session)
+ cap = ceph_get_cap_for_mds(ci,
+ req->r_session->s_mds);
dout("already using auth");
if ((!cap || cap != ci->i_auth_cap) ||
@@ -2069,12 +2117,12 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
dout("handle_reply tid %lld result %d\n", tid, result);
rinfo = &req->r_reply_info;
- err = parse_reply_info(msg, rinfo);
+ err = parse_reply_info(msg, rinfo, session->s_con.peer_features);
mutex_unlock(&mdsc->mutex);
mutex_lock(&session->s_mutex);
if (err < 0) {
- pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+ pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
ceph_msg_dump(msg);
goto out_err;
}
@@ -2094,7 +2142,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
mutex_lock(&req->r_fill_mutex);
err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
if (err == 0) {
- if (result == 0 && rinfo->dir_nr)
+ if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
+ rinfo->dir_nr)
ceph_readdir_prepopulate(req, req->r_session);
ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
}
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 9341fd4f1432..4e3a9cc0bba6 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -35,6 +35,7 @@ struct ceph_cap;
*/
struct ceph_mds_reply_info_in {
struct ceph_mds_reply_inode *in;
+ struct ceph_dir_layout dir_layout;
u32 symlink_len;
char *symlink;
u32 xattr_len;
@@ -42,26 +43,37 @@ struct ceph_mds_reply_info_in {
};
/*
- * 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).
+ * parsed info about an mds reply, including information about
+ * either: 1) the target inode and/or its parent directory and dentry,
+ * and directory contents (for readdir results), or
+ * 2) the file range lock info (for fcntl F_GETLK results).
*/
struct ceph_mds_reply_info_parsed {
struct ceph_mds_reply_head *head;
+ /* trace */
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;
+ /* extra */
+ union {
+ /* for fcntl F_GETLK results */
+ struct ceph_filelock *filelock_reply;
+
+ /* for readdir results */
+ struct {
+ 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) */
@@ -154,7 +166,6 @@ struct ceph_mds_request {
struct ceph_mds_client *r_mdsc;
int r_op; /* mds op code */
- int r_mds;
/* operation on what? */
struct inode *r_inode; /* arg1 */
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 08b460ae0539..bf6f0f34082a 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -428,7 +428,8 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
goto fail;
}
fsc->client->extra_mon_dispatch = extra_mon_dispatch;
- fsc->client->supported_features |= CEPH_FEATURE_FLOCK;
+ fsc->client->supported_features |= CEPH_FEATURE_FLOCK |
+ CEPH_FEATURE_DIRLAYOUTHASH;
fsc->client->monc.want_mdsmap = 1;
fsc->mount_options = fsopt;
@@ -443,13 +444,17 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
goto fail_client;
err = -ENOMEM;
- fsc->wb_wq = create_workqueue("ceph-writeback");
+ /*
+ * The number of concurrent works can be high but they don't need
+ * to be processed in parallel, limit concurrency.
+ */
+ fsc->wb_wq = alloc_workqueue("ceph-writeback", 0, 1);
if (fsc->wb_wq == NULL)
goto fail_bdi;
- fsc->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid");
+ fsc->pg_inv_wq = alloc_workqueue("ceph-pg-invalid", 0, 1);
if (fsc->pg_inv_wq == NULL)
goto fail_wb_wq;
- fsc->trunc_wq = create_singlethread_workqueue("ceph-trunc");
+ fsc->trunc_wq = alloc_workqueue("ceph-trunc", 0, 1);
if (fsc->trunc_wq == NULL)
goto fail_pg_inv_wq;
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 7f01728a4657..6e0826695112 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -239,6 +239,7 @@ struct ceph_inode_info {
unsigned i_ceph_flags;
unsigned long i_release_count;
+ struct ceph_dir_layout i_dir_layout;
struct ceph_file_layout i_layout;
char *i_symlink;
@@ -768,6 +769,7 @@ 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);
extern void ceph_invalidate_dentry_lease(struct dentry *dentry);
+extern unsigned ceph_dentry_hash(struct dentry *dn);
/*
* our d_ops vary depending on whether the inode is live,
diff --git a/fs/char_dev.c b/fs/char_dev.c
index e5b9df993b93..143f0207c7eb 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -59,7 +59,7 @@ static struct char_device_struct {
} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
/* index in the above */
-static inline int major_to_index(int major)
+static inline int major_to_index(unsigned major)
{
return major % CHRDEV_MAJOR_HASH_SIZE;
}
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 0ed213970ced..ee45648b0d1a 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -4,6 +4,7 @@ config CIFS
select NLS
select CRYPTO
select CRYPTO_MD5
+ select CRYPTO_HMAC
select CRYPTO_ARC4
help
This is the client VFS module for the Common Internet File System
@@ -143,6 +144,13 @@ config CIFS_FSCACHE
to be cached locally on disk through the general filesystem cache
manager. If unsure, say N.
+config CIFS_ACL
+ bool "Provide CIFS ACL support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && CIFS_XATTR
+ help
+ Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
+ is handed over to the application/caller.
+
config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index adefa60a9bdc..43b19dd39191 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
- readdir.o ioctl.o sess.o export.o cifsacl.o
+ readdir.o ioctl.o sess.o export.o
+
+cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
diff --git a/fs/cifs/README b/fs/cifs/README
index ee68d1036544..46af99ab3614 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
wsize default write size (default 57344)
maximum wsize currently allowed by CIFS is 57344 (fourteen
4096 byte pages)
+ actimeo=n attribute cache timeout in seconds (default 1 second).
+ After this timeout, the cifs client requests fresh attribute
+ information from the server. This option allows to tune the
+ attribute cache timeout to suit the workload needs. Shorter
+ timeouts mean better the cache coherency, but increased number
+ of calls to the server. Longer timeouts mean reduced number
+ of calls to the server at the expense of less stricter cache
+ coherency checks (i.e. incorrect attribute cache for a short
+ period of time).
rw mount the network share read-write (note that the
server may still consider the share read-only)
ro mount network share read-only
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 224d7bbd1fcc..e654dfd092c3 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -64,7 +64,9 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
void *buffer, uint16_t maxbuf)
{
const struct TCP_Server_Info *server = cookie_netfs_data;
- const struct sockaddr *sa = (struct sockaddr *) &server->addr.sockAddr;
+ const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
+ const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
+ const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
struct cifs_server_key *key = buffer;
uint16_t key_len = sizeof(struct cifs_server_key);
@@ -76,16 +78,16 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
*/
switch (sa->sa_family) {
case AF_INET:
- key->family = server->addr.sockAddr.sin_family;
- key->port = server->addr.sockAddr.sin_port;
- key->addr[0].ipv4_addr = server->addr.sockAddr.sin_addr;
+ key->family = sa->sa_family;
+ key->port = addr->sin_port;
+ key->addr[0].ipv4_addr = addr->sin_addr;
key_len += sizeof(key->addr[0].ipv4_addr);
break;
case AF_INET6:
- key->family = server->addr.sockAddr6.sin6_family;
- key->port = server->addr.sockAddr6.sin6_port;
- key->addr[0].ipv6_addr = server->addr.sockAddr6.sin6_addr;
+ key->family = sa->sa_family;
+ key->port = addr6->sin6_port;
+ key->addr[0].ipv6_addr = addr6->sin6_addr;
key_len += sizeof(key->addr[0].ipv6_addr);
break;
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index e9a393c9c2ca..7852cd677051 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -48,6 +48,7 @@ struct cifs_sb_info {
struct nls_table *local_nls;
unsigned int rsize;
unsigned int wsize;
+ unsigned long actimeo; /* attribute cache timeout (jiffies) */
atomic_t active;
uid_t mnt_uid;
gid_t mnt_gid;
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 87044906cd1f..4dfba8283165 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -98,6 +98,8 @@ struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
{
struct TCP_Server_Info *server = sesInfo->server;
+ struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
char *description, *dp;
size_t desc_len;
struct key *spnego_key;
@@ -127,10 +129,10 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
dp = description + strlen(description);
/* add the server address */
- if (server->addr.sockAddr.sin_family == AF_INET)
- sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
- else if (server->addr.sockAddr.sin_family == AF_INET6)
- sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr);
+ if (server->dstaddr.ss_family == AF_INET)
+ sprintf(dp, "ip4=%pI4", &sa->sin_addr);
+ else if (server->dstaddr.ss_family == AF_INET6)
+ sprintf(dp, "ip6=%pI6", &sa6->sin6_addr);
else
goto out;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c9b4792ae825..a437ec391a01 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -30,8 +30,6 @@
#include "cifs_debug.h"
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -560,7 +558,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
- return NULL;
+ return ERR_CAST(tlink);
xid = GetXid();
rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
@@ -568,7 +566,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
cifs_put_tlink(tlink);
- cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
+ cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+ if (rc)
+ return ERR_PTR(rc);
return pntsd;
}
@@ -583,7 +583,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
- return NULL;
+ return ERR_CAST(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
@@ -591,23 +591,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
&fid, &oplock, NULL, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc) {
- cERROR(1, "Unable to open file to get ACL");
- goto out;
+ if (!rc) {
+ rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
+ CIFSSMBClose(xid, tcon, fid);
}
- rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
- cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
-
- CIFSSMBClose(xid, tcon, fid);
- out:
cifs_put_tlink(tlink);
FreeXid(xid);
+
+ cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+ if (rc)
+ return ERR_PTR(rc);
return pntsd;
}
/* Retrieve an ACL from the server */
-static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
struct inode *inode, const char *path,
u32 *pacllen)
{
@@ -695,7 +694,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
}
/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
-void
+int
cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
struct inode *inode, const char *path, const __u16 *pfid)
{
@@ -711,17 +710,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
- if (pntsd)
+ if (IS_ERR(pntsd)) {
+ rc = PTR_ERR(pntsd);
+ cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+ } else {
rc = parse_sec_desc(pntsd, acllen, fattr);
- if (rc)
- cFYI(1, "parse sec desc failed rc = %d", rc);
+ kfree(pntsd);
+ if (rc)
+ cERROR(1, "parse sec desc failed rc = %d", rc);
+ }
- kfree(pntsd);
- return;
+ return rc;
}
/* Convert mode bits to an ACL so we can update the ACL on the server */
-int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
+int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
{
int rc = 0;
__u32 secdesclen = 0;
@@ -736,7 +739,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
/* Add three ACEs for owner, group, everyone getting rid of
other ACEs as chmod disables ACEs and set the security descriptor */
- if (pntsd) {
+ if (IS_ERR(pntsd)) {
+ rc = PTR_ERR(pntsd);
+ cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+ } else {
/* allocate memory for the smb header,
set security descriptor request security descriptor
parameters, and secuirty descriptor itself */
@@ -766,4 +772,3 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
return rc;
}
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 6c8096cf5155..c4ae7d036563 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -74,11 +74,7 @@ struct cifs_wksid {
char sidname[SIDNAMELENGTH];
} __attribute__((packed));
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
extern int match_sid(struct cifs_sid *);
extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
-
#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9c3789762ab7..a5db37c099da 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -334,10 +334,17 @@ cifs_alloc_inode(struct super_block *sb)
return &cifs_inode->vfs_inode;
}
+static void cifs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
+}
+
static void
cifs_destroy_inode(struct inode *inode)
{
- kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
+ call_rcu(&inode->i_rcu, cifs_i_callback);
}
static void
@@ -351,18 +358,19 @@ cifs_evict_inode(struct inode *inode)
static void
cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
{
+ struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
+
seq_printf(s, ",addr=");
- switch (server->addr.sockAddr.sin_family) {
+ switch (server->dstaddr.ss_family) {
case AF_INET:
- seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr);
+ seq_printf(s, "%pI4", &sa->sin_addr.s_addr);
break;
case AF_INET6:
- seq_printf(s, "%pI6",
- &server->addr.sockAddr6.sin6_addr.s6_addr);
- if (server->addr.sockAddr6.sin6_scope_id)
- seq_printf(s, "%%%u",
- server->addr.sockAddr6.sin6_scope_id);
+ seq_printf(s, "%pI6", &sa6->sin6_addr.s6_addr);
+ if (sa6->sin6_scope_id)
+ seq_printf(s, "%%%u", sa6->sin6_scope_id);
break;
default:
seq_printf(s, "(unknown)");
@@ -458,9 +466,13 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",acl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
seq_printf(s, ",mfsymlinks");
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
+ seq_printf(s, ",fsc");
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
+ /* convert actimeo and display it in seconds */
+ seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
return 0;
}
@@ -933,7 +945,6 @@ init_cifs(void)
GlobalCurrentXid = 0;
GlobalTotalActiveXid = 0;
GlobalMaxActiveXid = 0;
- memset(Local_System_Name, 0, 15);
spin_lock_init(&cifs_tcp_ses_lock);
spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b577bf0a1bb3..dfd2d46275ab 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -45,6 +45,16 @@
#define CIFS_MIN_RCV_POOL 4
/*
+ * default attribute cache timeout (jiffies)
+ */
+#define CIFS_DEF_ACTIMEO (1 * HZ)
+
+/*
+ * max attribute cache timeout (jiffies) - 2^30
+ */
+#define CIFS_MAX_ACTIMEO (1 << 30)
+
+/*
* MAX_REQ is the maximum number of requests that WE will send
* on one socket concurrently. It also matches the most common
* value of max multiplex returned by servers. We may
@@ -153,10 +163,7 @@ struct TCP_Server_Info {
char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
char *hostname; /* hostname portion of UNC string */
struct socket *ssocket;
- union {
- struct sockaddr_in sockAddr;
- struct sockaddr_in6 sockAddr6;
- } addr;
+ struct sockaddr_storage dstaddr;
struct sockaddr_storage srcaddr; /* locally bind to this IP */
wait_queue_head_t response_q;
wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
@@ -746,8 +753,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
/* on midQ entries */
-GLOBAL_EXTERN char Local_System_Name[15];
-
/*
* Global counters, updated atomically
*/
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7ed69b6b5fe6..e6d1481b16c1 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -54,7 +54,8 @@ do { \
__func__, curr_xid, (int)rc); \
} while (0)
extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+ struct cifsTconInfo *tcon);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern char *cifs_compose_mount_options(const char *sb_mountdata,
const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
struct TCP_Server_Info *);
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-#endif
extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -130,10 +129,12 @@ 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);
-extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
struct cifs_fattr *fattr, struct inode *inode,
const char *path, const __u16 *pfid);
-extern int mode_to_acl(struct inode *inode, const char *path, __u64);
+extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
+extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
+ const char *, u32 *);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 2f2632b6df5a..67acfb3acad2 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2478,95 +2478,6 @@ querySymLinkRetry:
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
-/* Initialize NT TRANSACT SMB into small smb request buffer.
- This assumes that all NT TRANSACTS that we init here have
- total parm and data under about 400 bytes (to fit in small cifs
- buffer size), which is the case so far, it easily fits. NB:
- Setup words themselves and ByteCount
- MaxSetupCount (size of returned setup area) and
- MaxParameterCount (returned parms size) must be set by caller */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
- const int parm_len, struct cifsTconInfo *tcon,
- void **ret_buf)
-{
- int rc;
- __u32 temp_offset;
- struct smb_com_ntransact_req *pSMB;
-
- rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
- (void **)&pSMB);
- if (rc)
- return rc;
- *ret_buf = (void *)pSMB;
- pSMB->Reserved = 0;
- pSMB->TotalParameterCount = cpu_to_le32(parm_len);
- pSMB->TotalDataCount = 0;
- pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->DataCount = pSMB->TotalDataCount;
- temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
- (setup_count * 2) - 4 /* for rfc1001 length itself */;
- pSMB->ParameterOffset = cpu_to_le32(temp_offset);
- pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
- pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
- pSMB->SubCommand = cpu_to_le16(sub_command);
- return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
- __u32 *pparmlen, __u32 *pdatalen)
-{
- char *end_of_smb;
- __u32 data_count, data_offset, parm_count, parm_offset;
- struct smb_com_ntransact_rsp *pSMBr;
-
- *pdatalen = 0;
- *pparmlen = 0;
-
- if (buf == NULL)
- return -EINVAL;
-
- pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
- /* ByteCount was converted from little endian in SendReceive */
- end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
- (char *)&pSMBr->ByteCount;
-
- data_offset = le32_to_cpu(pSMBr->DataOffset);
- data_count = le32_to_cpu(pSMBr->DataCount);
- parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
- parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
- *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
- *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
- /* should we also check that parm and data areas do not overlap? */
- if (*ppparm > end_of_smb) {
- cFYI(1, "parms start after end of smb");
- return -EINVAL;
- } else if (parm_count + *ppparm > end_of_smb) {
- cFYI(1, "parm end after end of smb");
- return -EINVAL;
- } else if (*ppdata > end_of_smb) {
- cFYI(1, "data starts after end of smb");
- return -EINVAL;
- } else if (data_count + *ppdata > end_of_smb) {
- cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
- *ppdata, data_count, (data_count + *ppdata),
- end_of_smb, pSMBr);
- return -EINVAL;
- } else if (parm_count + data_count > pSMBr->ByteCount) {
- cFYI(1, "parm count and data count larger than SMB");
- return -EINVAL;
- }
- *pdatalen = data_count;
- *pparmlen = parm_count;
- return 0;
-}
-
int
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
@@ -3056,7 +2967,97 @@ GetExtAttrOut:
#endif /* CONFIG_POSIX */
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
+/*
+ * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
+ * all NT TRANSACTS that we init here have total parm and data under about 400
+ * bytes (to fit in small cifs buffer size), which is the case so far, it
+ * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
+ * returned setup area) and MaxParameterCount (returned parms size) must be set
+ * by caller
+ */
+static int
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
+ const int parm_len, struct cifsTconInfo *tcon,
+ void **ret_buf)
+{
+ int rc;
+ __u32 temp_offset;
+ struct smb_com_ntransact_req *pSMB;
+
+ rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+ (void **)&pSMB);
+ if (rc)
+ return rc;
+ *ret_buf = (void *)pSMB;
+ pSMB->Reserved = 0;
+ pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+ MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ pSMB->DataCount = pSMB->TotalDataCount;
+ temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+ (setup_count * 2) - 4 /* for rfc1001 length itself */;
+ pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+ pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+ pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+ pSMB->SubCommand = cpu_to_le16(sub_command);
+ return 0;
+}
+
+static int
+validate_ntransact(char *buf, char **ppparm, char **ppdata,
+ __u32 *pparmlen, __u32 *pdatalen)
+{
+ char *end_of_smb;
+ __u32 data_count, data_offset, parm_count, parm_offset;
+ struct smb_com_ntransact_rsp *pSMBr;
+
+ *pdatalen = 0;
+ *pparmlen = 0;
+
+ if (buf == NULL)
+ return -EINVAL;
+
+ pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+ /* ByteCount was converted from little endian in SendReceive */
+ end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
+ (char *)&pSMBr->ByteCount;
+
+ data_offset = le32_to_cpu(pSMBr->DataOffset);
+ data_count = le32_to_cpu(pSMBr->DataCount);
+ parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+ parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+ *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+ *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+ /* should we also check that parm and data areas do not overlap? */
+ if (*ppparm > end_of_smb) {
+ cFYI(1, "parms start after end of smb");
+ return -EINVAL;
+ } else if (parm_count + *ppparm > end_of_smb) {
+ cFYI(1, "parm end after end of smb");
+ return -EINVAL;
+ } else if (*ppdata > end_of_smb) {
+ cFYI(1, "data starts after end of smb");
+ return -EINVAL;
+ } else if (data_count + *ppdata > end_of_smb) {
+ cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
+ *ppdata, data_count, (data_count + *ppdata),
+ end_of_smb, pSMBr);
+ return -EINVAL;
+ } else if (parm_count + data_count > pSMBr->ByteCount) {
+ cFYI(1, "parm count and data count larger than SMB");
+ return -EINVAL;
+ }
+ *pdatalen = data_count;
+ *pparmlen = parm_count;
+ return 0;
+}
+
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@ setCifsAclRetry:
return (rc);
}
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+#endif /* CONFIG_CIFS_ACL */
/* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 251a17c03545..41f002fb4a04 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -105,6 +105,7 @@ struct smb_vol {
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
unsigned short int port;
+ unsigned long actimeo; /* attribute cache timeout (jiffies) */
char *prepath;
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls;
@@ -114,8 +115,8 @@ struct smb_vol {
#define TLINK_ERROR_EXPIRE (1 * HZ)
#define TLINK_IDLE_EXPIRE (600 * HZ)
-static int ipv4_connect(struct TCP_Server_Info *server);
-static int ipv6_connect(struct TCP_Server_Info *server);
+static int ip_connect(struct TCP_Server_Info *server);
+static int generic_ip_connect(struct TCP_Server_Info *server);
static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
static void cifs_prune_tlinks(struct work_struct *work);
@@ -199,10 +200,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
while ((server->tcpStatus != CifsExiting) &&
(server->tcpStatus != CifsGood)) {
try_to_freeze();
- if (server->addr.sockAddr6.sin6_family == AF_INET6)
- rc = ipv6_connect(server);
- else
- rc = ipv4_connect(server);
+
+ /* we should try only the port we connected to before */
+ rc = generic_ip_connect(server);
if (rc) {
cFYI(1, "reconnect error %d", rc);
msleep(3000);
@@ -476,7 +476,7 @@ incomplete_rcv:
* initialize frame)
*/
cifs_set_port((struct sockaddr *)
- &server->addr.sockAddr, CIFS_PORT);
+ &server->dstaddr, CIFS_PORT);
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
@@ -806,23 +806,20 @@ cifs_parse_mount_options(char *options, const char *devname,
short int override_gid = -1;
bool uid_specified = false;
bool gid_specified = false;
+ char *nodename = utsname()->nodename;
separator[0] = ',';
separator[1] = 0;
- if (Local_System_Name[0] != 0)
- memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
- else {
- char *nodename = utsname()->nodename;
- int n = strnlen(nodename, 15);
- memset(vol->source_rfc1001_name, 0x20, 15);
- for (i = 0; i < n; i++) {
- /* does not have to be perfect mapping since field is
- informational, only used for servers that do not support
- port 445 and it can be overridden at mount time */
- vol->source_rfc1001_name[i] = toupper(nodename[i]);
- }
- }
+ /*
+ * does not have to be perfect mapping since field is
+ * informational, only used for servers that do not support
+ * port 445 and it can be overridden at mount time
+ */
+ memset(vol->source_rfc1001_name, 0x20, 15);
+ for (i = 0; i < strnlen(nodename, 15); i++)
+ vol->source_rfc1001_name[i] = toupper(nodename[i]);
+
vol->source_rfc1001_name[15] = 0;
/* null target name indicates to use *SMBSERVR default called name
if we end up sending RFC1001 session initialize */
@@ -840,6 +837,8 @@ cifs_parse_mount_options(char *options, const char *devname,
/* default to using server inode numbers where available */
vol->server_ino = 1;
+ vol->actimeo = CIFS_DEF_ACTIMEO;
+
if (!options)
return 1;
@@ -1214,6 +1213,16 @@ cifs_parse_mount_options(char *options, const char *devname,
printk(KERN_WARNING "CIFS: server net"
"biosname longer than 15 truncated.\n");
}
+ } else if (strnicmp(data, "actimeo", 7) == 0) {
+ if (value && *value) {
+ vol->actimeo = HZ * simple_strtoul(value,
+ &value, 0);
+ if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+ cERROR(1, "CIFS: attribute cache"
+ "timeout too large");
+ return 1;
+ }
+ }
} else if (strnicmp(data, "credentials", 4) == 0) {
/* ignore */
} else if (strnicmp(data, "version", 3) == 0) {
@@ -1352,6 +1361,11 @@ cifs_parse_mount_options(char *options, const char *devname,
"supported. Instead set "
"/proc/fs/cifs/LookupCacheEnabled to 0\n");
} else if (strnicmp(data, "fsc", 3) == 0) {
+#ifndef CONFIG_CIFS_FSCACHE
+ cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
+ "kernel config option set");
+ return 1;
+#endif
vol->fsc = true;
} else if (strnicmp(data, "mfsymlinks", 10) == 0) {
vol->mfsymlinks = true;
@@ -1439,35 +1453,71 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
}
}
+/*
+ * If no port is specified in addr structure, we try to match with 445 port
+ * and if it fails - with 139 ports. It should be called only if address
+ * families of server and addr are equal.
+ */
+static bool
+match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
+{
+ unsigned short int port, *sport;
+
+ switch (addr->sa_family) {
+ case AF_INET:
+ sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
+ port = ((struct sockaddr_in *) addr)->sin_port;
+ break;
+ case AF_INET6:
+ sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
+ port = ((struct sockaddr_in6 *) addr)->sin6_port;
+ break;
+ default:
+ WARN_ON(1);
+ return false;
+ }
+
+ if (!port) {
+ port = htons(CIFS_PORT);
+ if (port == *sport)
+ return true;
+
+ port = htons(RFC1001_PORT);
+ }
+
+ return port == *sport;
+}
static bool
match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
struct sockaddr *srcaddr)
{
- struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
-
switch (addr->sa_family) {
- case AF_INET:
- if (addr4->sin_addr.s_addr !=
- server->addr.sockAddr.sin_addr.s_addr)
- return false;
- if (addr4->sin_port &&
- addr4->sin_port != server->addr.sockAddr.sin_port)
+ case AF_INET: {
+ struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
+ struct sockaddr_in *srv_addr4 =
+ (struct sockaddr_in *)&server->dstaddr;
+
+ if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
return false;
break;
- case AF_INET6:
+ }
+ case AF_INET6: {
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
+ struct sockaddr_in6 *srv_addr6 =
+ (struct sockaddr_in6 *)&server->dstaddr;
+
if (!ipv6_addr_equal(&addr6->sin6_addr,
- &server->addr.sockAddr6.sin6_addr))
+ &srv_addr6->sin6_addr))
return false;
- if (addr6->sin6_scope_id !=
- server->addr.sockAddr6.sin6_scope_id)
- return false;
- if (addr6->sin6_port &&
- addr6->sin6_port != server->addr.sockAddr6.sin6_port)
+ if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
return false;
break;
}
+ default:
+ WARN_ON(1);
+ return false; /* don't expect to be here */
+ }
if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
return false;
@@ -1534,6 +1584,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
(struct sockaddr *)&vol->srcaddr))
continue;
+ if (!match_port(server, addr))
+ continue;
+
if (!match_security(server, vol))
continue;
@@ -1666,14 +1719,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
cFYI(1, "attempting ipv6 connect");
/* BB should we allow ipv6 on port 139? */
/* other OS never observed in Wild doing 139 with v6 */
- memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
- sizeof(struct sockaddr_in6));
- rc = ipv6_connect(tcp_ses);
- } else {
- memcpy(&tcp_ses->addr.sockAddr, sin_server,
- sizeof(struct sockaddr_in));
- rc = ipv4_connect(tcp_ses);
- }
+ memcpy(&tcp_ses->dstaddr, sin_server6,
+ sizeof(struct sockaddr_in6));
+ } else
+ memcpy(&tcp_ses->dstaddr, sin_server,
+ sizeof(struct sockaddr_in));
+
+ rc = ip_connect(tcp_ses);
if (rc < 0) {
cERROR(1, "Error connecting to socket. Aborting operation");
goto out_err_crypto_release;
@@ -1778,6 +1830,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
{
int rc = -ENOMEM, xid;
struct cifsSesInfo *ses;
+ struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
xid = GetXid();
@@ -1821,12 +1875,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
/* new SMB session uses our server ref */
ses->server = server;
- if (server->addr.sockAddr6.sin6_family == AF_INET6)
- sprintf(ses->serverName, "%pI6",
- &server->addr.sockAddr6.sin6_addr);
+ if (server->dstaddr.ss_family == AF_INET6)
+ sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
else
- sprintf(ses->serverName, "%pI4",
- &server->addr.sockAddr.sin_addr.s_addr);
+ sprintf(ses->serverName, "%pI4", &addr->sin_addr);
if (volume_info->username)
strncpy(ses->userName, volume_info->username,
@@ -2121,19 +2173,106 @@ bind_socket(struct TCP_Server_Info *server)
}
static int
-ipv4_connect(struct TCP_Server_Info *server)
+ip_rfc1001_connect(struct TCP_Server_Info *server)
+{
+ int rc = 0;
+ /*
+ * some servers require RFC1001 sessinit before sending
+ * negprot - BB check reconnection in case where second
+ * sessinit is sent but no second negprot
+ */
+ struct rfc1002_session_packet *ses_init_buf;
+ struct smb_hdr *smb_buf;
+ ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
+ GFP_KERNEL);
+ if (ses_init_buf) {
+ ses_init_buf->trailer.session_req.called_len = 32;
+
+ if (server->server_RFC1001_name &&
+ server->server_RFC1001_name[0] != 0)
+ rfc1002mangle(ses_init_buf->trailer.
+ session_req.called_name,
+ server->server_RFC1001_name,
+ RFC1001_NAME_LEN_WITH_NULL);
+ else
+ rfc1002mangle(ses_init_buf->trailer.
+ session_req.called_name,
+ DEFAULT_CIFS_CALLED_NAME,
+ RFC1001_NAME_LEN_WITH_NULL);
+
+ ses_init_buf->trailer.session_req.calling_len = 32;
+
+ /*
+ * calling name ends in null (byte 16) from old smb
+ * convention.
+ */
+ if (server->workstation_RFC1001_name &&
+ server->workstation_RFC1001_name[0] != 0)
+ rfc1002mangle(ses_init_buf->trailer.
+ session_req.calling_name,
+ server->workstation_RFC1001_name,
+ RFC1001_NAME_LEN_WITH_NULL);
+ else
+ rfc1002mangle(ses_init_buf->trailer.
+ session_req.calling_name,
+ "LINUX_CIFS_CLNT",
+ RFC1001_NAME_LEN_WITH_NULL);
+
+ ses_init_buf->trailer.session_req.scope1 = 0;
+ ses_init_buf->trailer.session_req.scope2 = 0;
+ smb_buf = (struct smb_hdr *)ses_init_buf;
+
+ /* sizeof RFC1002_SESSION_REQUEST with no scope */
+ smb_buf->smb_buf_length = 0x81000044;
+ rc = smb_send(server, smb_buf, 0x44);
+ kfree(ses_init_buf);
+ /*
+ * RFC1001 layer in at least one server
+ * requires very short break before negprot
+ * presumably because not expecting negprot
+ * to follow so fast. This is a simple
+ * solution that works without
+ * complicating the code and causes no
+ * significant slowing down on mount
+ * for everyone else
+ */
+ usleep_range(1000, 2000);
+ }
+ /*
+ * else the negprot may still work without this
+ * even though malloc failed
+ */
+
+ return rc;
+}
+
+static int
+generic_ip_connect(struct TCP_Server_Info *server)
{
int rc = 0;
- int val;
- bool connected = false;
- __be16 orig_port = 0;
+ unsigned short int sport;
+ int slen, sfamily;
struct socket *socket = server->ssocket;
+ struct sockaddr *saddr;
+
+ saddr = (struct sockaddr *) &server->dstaddr;
+
+ if (server->dstaddr.ss_family == AF_INET6) {
+ sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
+ slen = sizeof(struct sockaddr_in6);
+ sfamily = AF_INET6;
+ } else {
+ sport = ((struct sockaddr_in *) saddr)->sin_port;
+ slen = sizeof(struct sockaddr_in);
+ sfamily = AF_INET;
+ }
if (socket == NULL) {
- rc = sock_create_kern(PF_INET, SOCK_STREAM,
+ rc = sock_create_kern(sfamily, SOCK_STREAM,
IPPROTO_TCP, &socket);
if (rc < 0) {
cERROR(1, "Error %d creating socket", rc);
+ server->ssocket = NULL;
return rc;
}
@@ -2141,63 +2280,28 @@ ipv4_connect(struct TCP_Server_Info *server)
cFYI(1, "Socket created");
server->ssocket = socket;
socket->sk->sk_allocation = GFP_NOFS;
- cifs_reclassify_socket4(socket);
+ if (sfamily == AF_INET6)
+ cifs_reclassify_socket6(socket);
+ else
+ cifs_reclassify_socket4(socket);
}
rc = bind_socket(server);
if (rc < 0)
return rc;
- /* user overrode default port */
- if (server->addr.sockAddr.sin_port) {
- rc = socket->ops->connect(socket, (struct sockaddr *)
- &server->addr.sockAddr,
- sizeof(struct sockaddr_in), 0);
- if (rc >= 0)
- connected = true;
- }
-
- if (!connected) {
- /* save original port so we can retry user specified port
- later if fall back ports fail this time */
- orig_port = server->addr.sockAddr.sin_port;
-
- /* do not retry on the same port we just failed on */
- if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
- server->addr.sockAddr.sin_port = htons(CIFS_PORT);
- rc = socket->ops->connect(socket,
- (struct sockaddr *)
- &server->addr.sockAddr,
- sizeof(struct sockaddr_in), 0);
- if (rc >= 0)
- connected = true;
- }
- }
- if (!connected) {
- server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
- rc = socket->ops->connect(socket, (struct sockaddr *)
- &server->addr.sockAddr,
- sizeof(struct sockaddr_in), 0);
- if (rc >= 0)
- connected = true;
- }
-
- /* give up here - unless we want to retry on different
- protocol families some day */
- if (!connected) {
- if (orig_port)
- server->addr.sockAddr.sin_port = orig_port;
- cFYI(1, "Error %d connecting to server via ipv4", rc);
+ rc = socket->ops->connect(socket, saddr, slen, 0);
+ if (rc < 0) {
+ cFYI(1, "Error %d connecting to server", rc);
sock_release(socket);
server->ssocket = NULL;
return rc;
}
-
/*
* Eventually check for other socket options to change from
- * the default. sock_setsockopt not used because it expects
- * user space buffer
+ * the default. sock_setsockopt not used because it expects
+ * user space buffer
*/
socket->sk->sk_rcvtimeo = 7 * HZ;
socket->sk->sk_sndtimeo = 5 * HZ;
@@ -2211,7 +2315,7 @@ ipv4_connect(struct TCP_Server_Info *server)
}
if (server->tcp_nodelay) {
- val = 1;
+ int val = 1;
rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
(char *)&val, sizeof(val));
if (rc)
@@ -2222,161 +2326,39 @@ ipv4_connect(struct TCP_Server_Info *server)
socket->sk->sk_sndbuf,
socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
- /* send RFC1001 sessinit */
- if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
- /* some servers require RFC1001 sessinit before sending
- negprot - BB check reconnection in case where second
- sessinit is sent but no second negprot */
- struct rfc1002_session_packet *ses_init_buf;
- struct smb_hdr *smb_buf;
- ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
- GFP_KERNEL);
- if (ses_init_buf) {
- ses_init_buf->trailer.session_req.called_len = 32;
- if (server->server_RFC1001_name &&
- server->server_RFC1001_name[0] != 0)
- rfc1002mangle(ses_init_buf->trailer.
- session_req.called_name,
- server->server_RFC1001_name,
- RFC1001_NAME_LEN_WITH_NULL);
- else
- rfc1002mangle(ses_init_buf->trailer.
- session_req.called_name,
- DEFAULT_CIFS_CALLED_NAME,
- RFC1001_NAME_LEN_WITH_NULL);
-
- ses_init_buf->trailer.session_req.calling_len = 32;
-
- /* calling name ends in null (byte 16) from old smb
- convention. */
- if (server->workstation_RFC1001_name &&
- server->workstation_RFC1001_name[0] != 0)
- rfc1002mangle(ses_init_buf->trailer.
- session_req.calling_name,
- server->workstation_RFC1001_name,
- RFC1001_NAME_LEN_WITH_NULL);
- else
- rfc1002mangle(ses_init_buf->trailer.
- session_req.calling_name,
- "LINUX_CIFS_CLNT",
- RFC1001_NAME_LEN_WITH_NULL);
-
- ses_init_buf->trailer.session_req.scope1 = 0;
- ses_init_buf->trailer.session_req.scope2 = 0;
- smb_buf = (struct smb_hdr *)ses_init_buf;
- /* sizeof RFC1002_SESSION_REQUEST with no scope */
- smb_buf->smb_buf_length = 0x81000044;
- rc = smb_send(server, smb_buf, 0x44);
- kfree(ses_init_buf);
- msleep(1); /* RFC1001 layer in at least one server
- requires very short break before negprot
- presumably because not expecting negprot
- to follow so fast. This is a simple
- solution that works without
- complicating the code and causes no
- significant slowing down on mount
- for everyone else */
- }
- /* else the negprot may still work without this
- even though malloc failed */
-
- }
+ if (sport == htons(RFC1001_PORT))
+ rc = ip_rfc1001_connect(server);
return rc;
}
static int
-ipv6_connect(struct TCP_Server_Info *server)
+ip_connect(struct TCP_Server_Info *server)
{
- int rc = 0;
- int val;
- bool connected = false;
- __be16 orig_port = 0;
- struct socket *socket = server->ssocket;
+ unsigned short int *sport;
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
+ struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
- if (socket == NULL) {
- rc = sock_create_kern(PF_INET6, SOCK_STREAM,
- IPPROTO_TCP, &socket);
- if (rc < 0) {
- cERROR(1, "Error %d creating ipv6 socket", rc);
- socket = NULL;
- return rc;
- }
+ if (server->dstaddr.ss_family == AF_INET6)
+ sport = &addr6->sin6_port;
+ else
+ sport = &addr->sin_port;
- /* BB other socket options to set KEEPALIVE, NODELAY? */
- cFYI(1, "ipv6 Socket created");
- server->ssocket = socket;
- socket->sk->sk_allocation = GFP_NOFS;
- cifs_reclassify_socket6(socket);
- }
+ if (*sport == 0) {
+ int rc;
- rc = bind_socket(server);
- if (rc < 0)
- return rc;
+ /* try with 445 port at first */
+ *sport = htons(CIFS_PORT);
- /* user overrode default port */
- if (server->addr.sockAddr6.sin6_port) {
- rc = socket->ops->connect(socket,
- (struct sockaddr *) &server->addr.sockAddr6,
- sizeof(struct sockaddr_in6), 0);
- if (rc >= 0)
- connected = true;
- }
-
- if (!connected) {
- /* save original port so we can retry user specified port
- later if fall back ports fail this time */
-
- orig_port = server->addr.sockAddr6.sin6_port;
- /* do not retry on the same port we just failed on */
- if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
- server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
- rc = socket->ops->connect(socket, (struct sockaddr *)
- &server->addr.sockAddr6,
- sizeof(struct sockaddr_in6), 0);
- if (rc >= 0)
- connected = true;
- }
- }
- if (!connected) {
- server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
- rc = socket->ops->connect(socket, (struct sockaddr *)
- &server->addr.sockAddr6,
- sizeof(struct sockaddr_in6), 0);
+ rc = generic_ip_connect(server);
if (rc >= 0)
- connected = true;
- }
-
- /* give up here - unless we want to retry on different
- protocol families some day */
- if (!connected) {
- if (orig_port)
- server->addr.sockAddr6.sin6_port = orig_port;
- cFYI(1, "Error %d connecting to server via ipv6", rc);
- sock_release(socket);
- server->ssocket = NULL;
- return rc;
- }
-
- /*
- * Eventually check for other socket options to change from
- * the default. sock_setsockopt not used because it expects
- * user space buffer
- */
- socket->sk->sk_rcvtimeo = 7 * HZ;
- socket->sk->sk_sndtimeo = 5 * HZ;
+ return rc;
- if (server->tcp_nodelay) {
- val = 1;
- rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
- (char *)&val, sizeof(val));
- if (rc)
- cFYI(1, "set TCP_NODELAY socket option error %d", rc);
+ /* if it failed, try with 139 port */
+ *sport = htons(RFC1001_PORT);
}
- server->ssocket = socket;
-
- return rc;
+ return generic_ip_connect(server);
}
void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
@@ -2566,6 +2548,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cFYI(1, "file mode: 0x%x dir mode: 0x%x",
cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
+ cifs_sb->actimeo = pvolume_info->actimeo;
+
if (pvolume_info->noperm)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
if (pvolume_info->setuids)
@@ -2816,13 +2800,13 @@ remote_path_check:
/* check if a whole path (including prepath) is not remote */
if (!rc && cifs_sb->prepathlen && tcon) {
/* build_path_to_root works only when we have a valid tcon */
- full_path = cifs_build_path_to_root(cifs_sb);
+ full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL) {
rc = -ENOMEM;
goto mount_fail_check;
}
rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
- if (rc != -EREMOTE) {
+ if (rc != 0 && rc != -EREMOTE) {
kfree(full_path);
goto mount_fail_check;
}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 3840eddbfb7a..e3b10ca6d453 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -135,9 +135,9 @@ static void setup_cifs_dentry(struct cifsTconInfo *tcon,
struct inode *newinode)
{
if (tcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
d_instantiate(direntry, newinode);
}
@@ -421,9 +421,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
if (rc == 0)
d_instantiate(direntry, newinode);
@@ -604,9 +604,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
if ((rc == 0) && (newInode != NULL)) {
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
d_add(direntry, newInode);
if (posix_open) {
filp = lookup_instantiate_filp(nd, direntry,
@@ -634,9 +634,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
rc = 0;
direntry->d_time = jiffies;
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
d_add(direntry, NULL);
/* if it was once a directory (but how can we tell?) we could do
shrink_dcache_parent(direntry); */
@@ -656,22 +656,34 @@ lookup_out:
static int
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
{
- int isValid = 1;
-
if (direntry->d_inode) {
if (cifs_revalidate_dentry(direntry))
return 0;
- } else {
- cFYI(1, "neg dentry 0x%p name = %s",
- direntry, direntry->d_name.name);
- if (time_after(jiffies, direntry->d_time + HZ) ||
- !lookupCacheEnabled) {
- d_drop(direntry);
- isValid = 0;
- }
+ else
+ return 1;
+ }
+
+ /*
+ * This may be nfsd (or something), anyway, we can't see the
+ * intent of this. So, since this can be for creation, drop it.
+ */
+ if (!nd)
+ return 0;
+
+ /*
+ * Drop the negative dentry, in order to make sure to use the
+ * case sensitive name which is specified by user if this is
+ * for creation.
+ */
+ if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
+ if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
+ return 0;
}
- return isValid;
+ if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
+ return 0;
+
+ return 1;
}
/* static int cifs_d_delete(struct dentry *direntry)
@@ -688,9 +700,10 @@ const struct dentry_operations cifs_dentry_ops = {
/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
};
-static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
+static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *q)
{
- struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
+ struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
unsigned long hash;
int i;
@@ -703,21 +716,16 @@ static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
return 0;
}
-static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
- struct qstr *b)
+static int cifs_ci_compare(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
-
- if ((a->len == b->len) &&
- (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
- /*
- * To preserve case, don't let an existing negative dentry's
- * case take precedence. If a is not a negative dentry, this
- * should have no side effects
- */
- memcpy((void *)a->name, b->name, a->len);
+ struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
+
+ if ((name->len == len) &&
+ (nls_strnicmp(codepage, name->name, str, len) == 0))
return 0;
- }
return 1;
}
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 0eb87026cad3..548f06230a6d 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
/* Search for server name delimiter */
sep = memchr(hostname, '\\', len);
if (sep)
- len = sep - unc;
+ len = sep - hostname;
else
cFYI(1, "%s: probably server name is whole unc: %s",
__func__, unc);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 06c3e83fa387..97ddbf2fdfc3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -104,53 +104,6 @@ static inline int cifs_get_disposition(unsigned int flags)
return FILE_OPEN;
}
-static inline int cifs_open_inode_helper(struct inode *inode,
- struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
- char *full_path, int xid)
-{
- struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
- struct timespec temp;
- int rc;
-
- if (pCifsInode->clientCanCacheRead) {
- /* we have the inode open somewhere else
- no need to discard cache data */
- goto client_can_cache;
- }
-
- /* BB need same check in cifs_create too? */
- /* if not oplocked, invalidate inode pages if mtime or file
- size changed */
- temp = cifs_NTtimeToUnix(buf->LastWriteTime);
- if (timespec_equal(&inode->i_mtime, &temp) &&
- (inode->i_size ==
- (loff_t)le64_to_cpu(buf->EndOfFile))) {
- cFYI(1, "inode unchanged on server");
- } else {
- if (inode->i_mapping) {
- /* BB no need to lock inode until after invalidate
- since namei code should already have it locked? */
- rc = filemap_write_and_wait(inode->i_mapping);
- mapping_set_error(inode->i_mapping, rc);
- }
- cFYI(1, "invalidating remote inode since open detected it "
- "changed");
- invalidate_remote_inode(inode);
- }
-
-client_can_cache:
- if (pTcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
- xid);
- else
- rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
- xid, NULL);
-
- cifs_set_oplock_level(pCifsInode, oplock);
-
- return rc;
-}
-
int cifs_posix_open(char *full_path, struct inode **pinode,
struct super_block *sb, int mode, unsigned int f_flags,
__u32 *poplock, __u16 *pnetfid, int xid)
@@ -213,6 +166,76 @@ posix_open_ret:
return rc;
}
+static int
+cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
+ struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock,
+ __u16 *pnetfid, int xid)
+{
+ int rc;
+ int desiredAccess;
+ int disposition;
+ FILE_ALL_INFO *buf;
+
+ desiredAccess = cifs_convert_flags(f_flags);
+
+/*********************************************************************
+ * open flag mapping table:
+ *
+ * POSIX Flag CIFS Disposition
+ * ---------- ----------------
+ * O_CREAT FILE_OPEN_IF
+ * O_CREAT | O_EXCL FILE_CREATE
+ * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
+ * O_TRUNC FILE_OVERWRITE
+ * none of the above FILE_OPEN
+ *
+ * Note that there is not a direct match between disposition
+ * FILE_SUPERSEDE (ie create whether or not file exists although
+ * O_CREAT | O_TRUNC is similar but truncates the existing
+ * file rather than creating a new file as FILE_SUPERSEDE does
+ * (which uses the attributes / metadata passed in on open call)
+ *?
+ *? O_SYNC is a reasonable match to CIFS writethrough flag
+ *? and the read write flags match reasonably. O_LARGEFILE
+ *? is irrelevant because largefile support is always used
+ *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
+ * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
+ *********************************************************************/
+
+ disposition = cifs_get_disposition(f_flags);
+
+ /* BB pass O_SYNC flag through on file attributes .. BB */
+
+ buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (tcon->ses->capabilities & CAP_NT_SMBS)
+ rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
+ desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
+ cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+ & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ else
+ rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
+ desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
+ cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+ & CIFS_MOUNT_MAP_SPECIAL_CHR);
+
+ if (rc)
+ goto out;
+
+ if (tcon->unix_ext)
+ rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
+ xid);
+ else
+ rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
+ xid, pnetfid);
+
+out:
+ kfree(buf);
+ return rc;
+}
+
struct cifsFileInfo *
cifs_new_fileinfo(__u16 fileHandle, struct file *file,
struct tcon_link *tlink, __u32 oplock)
@@ -317,10 +340,8 @@ int cifs_open(struct inode *inode, struct file *file)
struct cifsFileInfo *pCifsFile = NULL;
struct cifsInodeInfo *pCifsInode;
char *full_path = NULL;
- int desiredAccess;
- int disposition;
+ bool posix_open_ok = false;
__u16 netfid;
- FILE_ALL_INFO *buf = NULL;
xid = GetXid();
@@ -358,17 +379,7 @@ int cifs_open(struct inode *inode, struct file *file)
file->f_flags, &oplock, &netfid, xid);
if (rc == 0) {
cFYI(1, "posix open succeeded");
-
- pCifsFile = cifs_new_fileinfo(netfid, file, tlink,
- oplock);
- if (pCifsFile == NULL) {
- CIFSSMBClose(xid, tcon, netfid);
- rc = -ENOMEM;
- }
-
- cifs_fscache_set_inode_cookie(inode, file);
-
- goto out;
+ posix_open_ok = true;
} else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
if (tcon->ses->serverNOS)
cERROR(1, "server %s of type %s returned"
@@ -385,103 +396,41 @@ int cifs_open(struct inode *inode, struct file *file)
or DFS errors */
}
- desiredAccess = cifs_convert_flags(file->f_flags);
-
-/*********************************************************************
- * open flag mapping table:
- *
- * POSIX Flag CIFS Disposition
- * ---------- ----------------
- * O_CREAT FILE_OPEN_IF
- * O_CREAT | O_EXCL FILE_CREATE
- * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
- * O_TRUNC FILE_OVERWRITE
- * none of the above FILE_OPEN
- *
- * Note that there is not a direct match between disposition
- * FILE_SUPERSEDE (ie create whether or not file exists although
- * O_CREAT | O_TRUNC is similar but truncates the existing
- * file rather than creating a new file as FILE_SUPERSEDE does
- * (which uses the attributes / metadata passed in on open call)
- *?
- *? O_SYNC is a reasonable match to CIFS writethrough flag
- *? and the read write flags match reasonably. O_LARGEFILE
- *? is irrelevant because largefile support is always used
- *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
- * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
- *********************************************************************/
-
- disposition = cifs_get_disposition(file->f_flags);
-
- /* BB pass O_SYNC flag through on file attributes .. BB */
-
- /* Also refresh inode by passing in file_info buf returned by SMBOpen
- and calling get_inode_info with returned buf (at least helps
- non-Unix server case) */
-
- /* BB we can not do this if this is the second open of a file
- and the first handle has writebehind data, we might be
- able to simply do a filemap_fdatawrite/filemap_fdatawait first */
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (!buf) {
- rc = -ENOMEM;
- goto out;
- }
-
- if (tcon->ses->capabilities & CAP_NT_SMBS)
- rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
- desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
- & CIFS_MOUNT_MAP_SPECIAL_CHR);
- else
- rc = -EIO; /* no NT SMB support fall into legacy open below */
-
- if (rc == -EIO) {
- /* Old server, try legacy style OpenX */
- rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
- desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
- & CIFS_MOUNT_MAP_SPECIAL_CHR);
- }
- if (rc) {
- cFYI(1, "cifs_open returned 0x%x", rc);
- goto out;
+ if (!posix_open_ok) {
+ rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
+ file->f_flags, &oplock, &netfid, xid);
+ if (rc)
+ goto out;
}
- rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
- if (rc != 0)
- goto out;
-
pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
if (pCifsFile == NULL) {
+ CIFSSMBClose(xid, tcon, netfid);
rc = -ENOMEM;
goto out;
}
cifs_fscache_set_inode_cookie(inode, file);
- if (oplock & CIFS_CREATE_ACTION) {
+ if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
/* time to set mode which we can not set earlier due to
problems creating new read-only files */
- if (tcon->unix_ext) {
- struct cifs_unix_set_info_args args = {
- .mode = inode->i_mode,
- .uid = NO_CHANGE_64,
- .gid = NO_CHANGE_64,
- .ctime = NO_CHANGE_64,
- .atime = NO_CHANGE_64,
- .mtime = NO_CHANGE_64,
- .device = 0,
- };
- CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- }
+ struct cifs_unix_set_info_args args = {
+ .mode = inode->i_mode,
+ .uid = NO_CHANGE_64,
+ .gid = NO_CHANGE_64,
+ .ctime = NO_CHANGE_64,
+ .atime = NO_CHANGE_64,
+ .mtime = NO_CHANGE_64,
+ .device = 0,
+ };
+ CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
}
out:
- kfree(buf);
kfree(full_path);
FreeXid(xid);
cifs_put_tlink(tlink);
@@ -1108,7 +1057,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
return total_written;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
bool fsuid_only)
{
@@ -1142,7 +1090,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
spin_unlock(&cifs_file_list_lock);
return NULL;
}
-#endif
struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
bool fsuid_only)
@@ -2271,8 +2218,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile)
void cifs_oplock_break_put(struct cifsFileInfo *cfile)
{
+ struct super_block *sb = cfile->dentry->d_sb;
+
cifsFileInfo_put(cfile);
- cifs_sb_deactive(cfile->dentry->d_sb);
+ cifs_sb_deactive(sb);
}
const struct address_space_operations cifs_addr_ops = {
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index a2ad94efcfe6..297a43d0ff7f 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -2,7 +2,7 @@
* fs/cifs/fscache.c - CIFS filesystem cache interface
*
* Copyright (c) 2010 Novell, Inc.
- * Author(s): Suresh Jayaraman (sjayaraman@suse.de>
+ * Author(s): Suresh Jayaraman <sjayaraman@suse.de>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
if (cifsi->fscache)
return;
- cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
+ cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
&cifs_fscache_inode_object_def, cifsi);
- cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
+ cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
cifsi->fscache);
+ }
}
void cifs_fscache_release_inode_cookie(struct inode *inode)
@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
{
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
cifs_fscache_disable_inode_cookie(inode);
- else {
+ else
cifs_fscache_enable_inode_cookie(inode);
- cFYI(1, "CIFS: fscache inode cookie set");
- }
}
void cifs_fscache_reset_inode_cookie(struct inode *inode)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index ef3a55bf86b6..a853a89857a5 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -686,13 +686,18 @@ int cifs_get_inode_info(struct inode **pinode,
cFYI(1, "cifs_sfu_type failed: %d", tmprc);
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- cFYI(1, "Getting mode bits from ACL");
- cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
+ rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
+ pfid);
+ if (rc) {
+ cFYI(1, "%s: Getting ACL failed with error: %d",
+ __func__, rc);
+ goto cgii_exit;
+ }
}
-#endif
+#endif /* CONFIG_CIFS_ACL */
/* fill in remaining high mode bits e.g. SUID, VTX */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -723,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
.lookup = cifs_lookup,
};
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+ struct cifsTconInfo *tcon)
{
int pplen = cifs_sb->prepathlen;
int dfsplen;
char *full_path = NULL;
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
@@ -804,14 +809,14 @@ inode_has_hashed_dentries(struct inode *inode)
{
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
return true;
}
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
return false;
}
@@ -870,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
char *full_path;
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
- full_path = cifs_build_path_to_root(cifs_sb);
+ full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL);
- if (!inode)
- return ERR_PTR(rc);
+ if (!inode) {
+ inode = ERR_PTR(rc);
+ goto out;
+ }
#ifdef CONFIG_CIFS_FSCACHE
/* populate tcon->resource_id */
@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid;
} else if (rc) {
- kfree(full_path);
- _FreeXid(xid);
iget_failed(inode);
- return ERR_PTR(rc);
+ inode = ERR_PTR(rc);
}
-
+out:
kfree(full_path);
/* can not call macro FreeXid here since in a void func
* TODO: This is no longer true
@@ -1314,9 +1319,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
to set uid/gid */
inc_nlink(inode);
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
cifs_fill_uniqueid(inode->i_sb, &fattr);
@@ -1358,9 +1363,9 @@ mkdir_get_info:
inode->i_sb, xid, NULL);
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
d_instantiate(direntry, newinode);
/* setting nlink not necessary except in cases where we
* failed to get it from the server or was set bogus */
@@ -1648,6 +1653,7 @@ static bool
cifs_inode_needs_reval(struct inode *inode)
{
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
if (cifs_i->clientCanCacheRead)
return false;
@@ -1658,19 +1664,21 @@ cifs_inode_needs_reval(struct inode *inode)
if (cifs_i->time == 0)
return true;
- /* FIXME: the actimeo should be tunable */
- if (time_after_eq(jiffies, cifs_i->time + HZ))
+ if (!time_in_range(jiffies, cifs_i->time,
+ cifs_i->time + cifs_sb->actimeo))
return true;
/* hardlinked files w/ noserverino get "special" treatment */
- if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
S_ISREG(inode->i_mode) && inode->i_nlink != 1)
return true;
return false;
}
-/* check invalid_mapping flag and zap the cache if it's set */
+/*
+ * Zap the cache. Called when invalid_mapping flag is set.
+ */
static void
cifs_invalidate_mapping(struct inode *inode)
{
@@ -2114,11 +2122,16 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
- rc = mode_to_acl(inode, full_path, mode);
- else
-#endif
+#ifdef CONFIG_CIFS_ACL
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+ rc = mode_to_cifs_acl(inode, full_path, mode);
+ if (rc) {
+ cFYI(1, "%s: Setting ACL failed with error: %d",
+ __func__, rc);
+ goto cifs_setattr_exit;
+ }
+ } else
+#endif /* CONFIG_CIFS_ACL */
if (((mode & S_IWUGO) == 0) &&
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 85cdbf831e7b..fe2f6a93c49e 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -525,9 +525,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
rc);
} else {
if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(direntry, &cifs_ci_dentry_ops);
else
- direntry->d_op = &cifs_dentry_ops;
+ d_set_d_op(direntry, &cifs_dentry_ops);
d_instantiate(direntry, newinode);
}
}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index ef7bb7b50f58..ec5b68e3b928 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
cFYI(1, "For %s", name->name);
if (parent->d_op && parent->d_op->d_hash)
- parent->d_op->d_hash(parent, name);
+ parent->d_op->d_hash(parent, parent->d_inode, name);
else
name->hash = full_name_hash(name->name, name->len);
@@ -103,9 +103,9 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
}
if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
- dentry->d_op = &cifs_ci_dentry_ops;
+ d_set_d_op(dentry, &cifs_ci_dentry_ops);
else
- dentry->d_op = &cifs_dentry_ops;
+ d_set_d_op(dentry, &cifs_dentry_ops);
alias = d_materialise_unique(dentry, inode);
if (alias != NULL) {
@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file)
char *full_path = NULL;
struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- struct tcon_link *tlink;
+ struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon;
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- if (file->private_data == NULL)
- file->private_data =
- kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
if (file->private_data == NULL) {
- rc = -ENOMEM;
- goto error_exit;
+ tlink = cifs_sb_tlink(cifs_sb);
+ if (IS_ERR(tlink))
+ return PTR_ERR(tlink);
+
+ cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
+ if (cifsFile == NULL) {
+ rc = -ENOMEM;
+ goto error_exit;
+ }
+ file->private_data = cifsFile;
+ cifsFile->tlink = cifs_get_tlink(tlink);
+ pTcon = tlink_tcon(tlink);
+ } else {
+ cifsFile = file->private_data;
+ pTcon = tlink_tcon(cifsFile->tlink);
}
- cifsFile = file->private_data;
cifsFile->invalidHandle = true;
cifsFile->srch_inf.endOfSearch = false;
- cifsFile->tlink = cifs_get_tlink(tlink);
full_path = build_path_from_dentry(file->f_path.dentry);
if (full_path == NULL) {
@@ -756,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
ino, fattr.cf_dtype);
- /*
- * we can not return filldir errors to the caller since they are
- * "normal" when the stat blocksize is too small - we return remapped
- * error instead
- *
- * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
- * case already. Why should we be clobbering other errors from it?
- */
- if (rc) {
- cFYI(1, "filldir rc = %d", rc);
- rc = -EOVERFLOW;
- }
dput(tmp_dentry);
return rc;
}
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 7b01d3f6eed6..54d9f76deff9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -431,13 +431,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
__u32 flags;
+ memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
sec_blob->MessageType = NtLmNegotiate;
/* BB is NTLMV2 session security format easier to use here? */
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM;
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -446,7 +447,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
NTLMSSP_NEGOTIATE_EXTENDED_SEC;
}
- sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+ sec_blob->NegotiateFlags = cpu_to_le32(flags);
sec_blob->WorkstationName.BufferOffset = 0;
sec_blob->WorkstationName.Length = 0;
@@ -477,7 +478,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 |
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM;
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -485,7 +486,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
- sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+ sec_blob->NegotiateFlags = cpu_to_le32(flags);
sec_blob->LmChallengeResponse.BufferOffset =
cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
@@ -544,8 +545,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
sec_blob->WorkstationName.MaximumLength = 0;
tmp += 2;
- if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
- !calc_seckey(ses)) {
+ if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
+ (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
+ && !calc_seckey(ses)) {
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
@@ -562,16 +564,6 @@ setup_ntlmv2_ret:
*buflen = tmp - pbuffer;
return rc;
}
-
-
-static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
- struct cifsSesInfo *ses)
-{
- build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
- pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
-
- return;
-}
#endif
int
@@ -828,16 +820,19 @@ ssetup_ntlmssp_authenticate:
capabilities |= CAP_EXTENDED_SECURITY;
pSMB->req.Capabilities |= cpu_to_le32(capabilities);
if (phase == NtLmNegotiate) {
- setup_ntlmssp_neg_req(pSMB, ses);
+ build_ntlmssp_negotiate_blob(
+ pSMB->req.SecurityBlob, ses);
iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
- iov[1].iov_base = &pSMB->req.SecurityBlob[0];
+ iov[1].iov_base = pSMB->req.SecurityBlob;
+ pSMB->req.SecurityBlobLength =
+ cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
} else if (phase == NtLmAuthenticate) {
/* 5 is an empirical value, large enought to
* hold authenticate message, max 10 of
* av paris, doamin,user,workstation mames,
* flags etc..
*/
- ntlmsspblob = kmalloc(
+ ntlmsspblob = kzalloc(
5*sizeof(struct _AUTHENTICATE_MESSAGE),
GFP_KERNEL);
if (!ntlmsspblob) {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index e0588cdf4cc5..59ca81b16919 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -119,7 +119,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
if (ssocket == NULL)
return -ENOTSOCK; /* BB eventually add reconnect code here */
- smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr;
+ smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
smb_msg.msg_namelen = sizeof(struct sockaddr);
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index a264b744bb41..eae2a1491608 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -30,10 +30,11 @@
#define MAX_EA_VALUE_SIZE 65535
#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
+#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
#define CIFS_XATTR_USER_PREFIX "user."
#define CIFS_XATTR_SYSTEM_PREFIX "system."
#define CIFS_XATTR_OS2_PREFIX "os2."
-#define CIFS_XATTR_SECURITY_PREFIX ".security"
+#define CIFS_XATTR_SECURITY_PREFIX "security."
#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_TRUSTED_PREFIX_LEN 8
#define XATTR_SECURITY_PREFIX_LEN 9
@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
- else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- __u16 fid;
- int oplock = 0;
- struct cifs_ntsd *pacl = NULL;
- __u32 buflen = 0;
- if (experimEnabled)
- rc = CIFSSMBOpen(xid, pTcon, full_path,
- FILE_OPEN, GENERIC_READ, 0, &fid,
- &oplock, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- /* else rc is EOPNOTSUPP from above */
-
- if (rc == 0) {
- rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
- &buflen);
- CIFSSMBClose(xid, pTcon, fid);
- }
- }
-#endif /* EXPERIMENTAL */
#else
- cFYI(1, "query POSIX ACL not supported yet");
+ cFYI(1, "Query POSIX ACL not supported yet");
#endif /* CONFIG_CIFS_POSIX */
} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
#else
- cFYI(1, "query POSIX default ACL not supported yet");
-#endif
+ cFYI(1, "Query POSIX default ACL not supported yet");
+#endif /* CONFIG_CIFS_POSIX */
+ } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
+ strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
+#ifdef CONFIG_CIFS_ACL
+ u32 acllen;
+ struct cifs_ntsd *pacl;
+
+ pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
+ full_path, &acllen);
+ if (IS_ERR(pacl)) {
+ rc = PTR_ERR(pacl);
+ cERROR(1, "%s: error %zd getting sec desc",
+ __func__, rc);
+ } else {
+ if (ea_value) {
+ if (acllen > buf_size)
+ acllen = -ERANGE;
+ else
+ memcpy(ea_value, pacl, acllen);
+ }
+ rc = acllen;
+ kfree(pacl);
+ }
+#else
+ cFYI(1, "Query CIFS ACL not supported yet");
+#endif /* CONFIG_CIFS_ACL */
} else if (strncmp(ea_name,
CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
cFYI(1, "Trusted xattr namespace not supported yet");
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 9060f08e70cf..5525e1c660fd 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -93,7 +93,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
struct list_head *child;
struct dentry *de;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
list_for_each(child, &parent->d_subdirs)
{
de = list_entry(child, struct dentry, d_u.d_child);
@@ -102,7 +102,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
continue;
coda_flag_inode(de->d_inode, flag);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
return;
}
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 5d8b35539601..aa40c811f8d2 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -47,7 +47,7 @@ static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
/* dentry ops */
static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
-static int coda_dentry_delete(struct dentry *);
+static int coda_dentry_delete(const struct dentry *);
/* support routines */
static int coda_venus_readdir(struct file *coda_file, void *buf,
@@ -125,7 +125,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc
return ERR_PTR(error);
exit:
- entry->d_op = &coda_dentry_operations;
+ d_set_d_op(entry, &coda_dentry_operations);
if (inode && (type & CODA_NOCACHE))
coda_flag_inode(inode, C_VATTR | C_PURGE);
@@ -559,7 +559,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
if (cii->c_flags & C_FLUSH)
coda_flag_inode_children(inode, C_FLUSH);
- if (atomic_read(&de->d_count) > 1)
+ if (de->d_count > 1)
/* pretend it's valid, but don't change the flags */
goto out;
@@ -577,7 +577,7 @@ out:
* This is the callback from dput() when d_count is going to 0.
* We use this to unhash dentries with bad inodes.
*/
-static int coda_dentry_delete(struct dentry * dentry)
+static int coda_dentry_delete(const struct dentry * dentry)
{
int flags;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 5ea57c8c7f97..50dc7d189f56 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -56,11 +56,18 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void coda_destroy_inode(struct inode *inode)
+static void coda_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(coda_inode_cachep, ITOC(inode));
}
+static void coda_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, coda_i_callback);
+}
+
static void init_once(void *foo)
{
struct coda_inode_info *ei = (struct coda_inode_info *) foo;
diff --git a/fs/compat.c b/fs/compat.c
index c580c322fa6b..eb1740ac8c0a 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1350,6 +1350,10 @@ static int compat_count(compat_uptr_t __user *argv, int max)
argv++;
if (i++ >= max)
return -E2BIG;
+
+ if (fatal_signal_pending(current))
+ return -ERESTARTNOHAND;
+ cond_resched();
}
}
return i;
@@ -1391,6 +1395,12 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
while (len > 0) {
int offset, bytes_to_copy;
+ if (fatal_signal_pending(current)) {
+ ret = -ERESTARTNOHAND;
+ goto out;
+ }
+ cond_resched();
+
offset = pos % PAGE_SIZE;
if (offset == 0)
offset = PAGE_SIZE;
@@ -1407,18 +1417,8 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
struct page *page;
-#ifdef CONFIG_STACK_GROWSUP
- ret = expand_stack_downwards(bprm->vma, pos);
- if (ret < 0) {
- /* We've exceed the stack rlimit. */
- ret = -E2BIG;
- goto out;
- }
-#endif
- ret = get_user_pages(current, bprm->mm, pos,
- 1, 1, 1, &page, NULL);
- if (ret <= 0) {
- /* We've exceed the stack rlimit. */
+ page = get_arg_page(bprm, pos, 1);
+ if (!page) {
ret = -E2BIG;
goto out;
}
@@ -1539,8 +1539,10 @@ int compat_do_execve(char * filename,
return retval;
out:
- if (bprm->mm)
+ if (bprm->mm) {
+ acct_arg_size(bprm, 0);
mmput(bprm->mm);
+ }
out_file:
if (bprm->file) {
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index a60579b007b0..175736c282ab 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -42,7 +42,7 @@
#include <linux/tty.h>
#include <linux/vt_kern.h>
#include <linux/fb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/netdevice.h>
#include <linux/raw.h>
#include <linux/blkdev.h>
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index da6061a6df40..026cf68553a4 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -120,7 +120,7 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
{
struct config_item * item = NULL;
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
if (!d_unhashed(dentry)) {
struct configfs_dirent * sd = dentry->d_fsdata;
if (sd->s_type & CONFIGFS_ITEM_LINK) {
@@ -129,7 +129,7 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
} else
item = config_item_get(sd->s_element);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
return item;
}
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 0b502f80c691..8cd00c35363c 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -67,7 +67,7 @@ static void configfs_d_iput(struct dentry * dentry,
* We _must_ delete our dentries on last dput, as the chain-to-parent
* behavior is required to clear the parents of default_groups.
*/
-static int configfs_d_delete(struct dentry *dentry)
+static int configfs_d_delete(const struct dentry *dentry)
{
return 1;
}
@@ -234,7 +234,7 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
sd->s_dentry = dentry;
if (dentry) {
dentry->d_fsdata = configfs_get(sd);
- dentry->d_op = &configfs_dentry_ops;
+ d_set_d_op(dentry, &configfs_dentry_ops);
}
return 0;
@@ -278,7 +278,7 @@ static int create_dir(struct config_item * k, struct dentry * p,
error = configfs_create(d, mode, init_dir);
if (!error) {
inc_nlink(p->d_inode);
- (d)->d_op = &configfs_dentry_ops;
+ d_set_d_op((d), &configfs_dentry_ops);
} else {
struct configfs_dirent *sd = d->d_fsdata;
if (sd) {
@@ -372,7 +372,7 @@ int configfs_create_link(struct configfs_symlink *sl,
if (!err) {
err = configfs_create(dentry, mode, init_symlink);
if (!err)
- dentry->d_op = &configfs_dentry_ops;
+ d_set_d_op(dentry, &configfs_dentry_ops);
else {
struct configfs_dirent *sd = dentry->d_fsdata;
if (sd) {
@@ -399,8 +399,7 @@ static void remove_dir(struct dentry * d)
if (d->d_inode)
simple_rmdir(parent->d_inode,d);
- pr_debug(" o %s removing done (%d)\n",d->d_name.name,
- atomic_read(&d->d_count));
+ pr_debug(" o %s removing done (%d)\n",d->d_name.name, d->d_count);
dput(parent);
}
@@ -448,7 +447,7 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
return error;
}
- dentry->d_op = &configfs_dentry_ops;
+ d_set_d_op(dentry, &configfs_dentry_ops);
d_rehash(dentry);
return 0;
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index 253476d78ed8..c83f4768eeaa 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -250,18 +250,14 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
struct dentry * dentry = sd->s_dentry;
if (dentry) {
- spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry) && dentry->d_inode)) {
- dget_locked(dentry);
+ dget_dlock(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
simple_unlink(parent->d_inode, dentry);
- } else {
+ } else
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
- }
}
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 23702a9d4e6d..ec6cfcd04af3 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -33,20 +33,58 @@
#include <linux/bootmem.h>
#include <linux/fs_struct.h>
#include <linux/hardirq.h>
+#include <linux/bit_spinlock.h>
+#include <linux/rculist_bl.h>
#include "internal.h"
+/*
+ * Usage:
+ * dcache->d_inode->i_lock protects:
+ * - i_dentry, d_alias, d_inode of aliases
+ * dcache_hash_bucket lock protects:
+ * - the dcache hash table
+ * s_anon bl list spinlock protects:
+ * - the s_anon list (see __d_drop)
+ * dcache_lru_lock protects:
+ * - the dcache lru lists and counters
+ * d_lock protects:
+ * - d_flags
+ * - d_name
+ * - d_lru
+ * - d_count
+ * - d_unhashed()
+ * - d_parent and d_subdirs
+ * - childrens' d_child and d_parent
+ * - d_alias, d_inode
+ *
+ * Ordering:
+ * dentry->d_inode->i_lock
+ * dentry->d_lock
+ * dcache_lru_lock
+ * dcache_hash_bucket lock
+ * s_anon lock
+ *
+ * If there is an ancestor relationship:
+ * dentry->d_parent->...->d_parent->d_lock
+ * ...
+ * dentry->d_parent->d_lock
+ * dentry->d_lock
+ *
+ * If no ancestor relationship:
+ * if (dentry1 < dentry2)
+ * dentry1->d_lock
+ * dentry2->d_lock
+ */
int sysctl_vfs_cache_pressure __read_mostly = 100;
EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);
__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
-EXPORT_SYMBOL(dcache_lock);
+EXPORT_SYMBOL(rename_lock);
static struct kmem_cache *dentry_cache __read_mostly;
-#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
-
/*
* This is the single most critical data structure when it comes
* to the dcache: the hashtable for lookups. Somebody should try
@@ -60,22 +98,51 @@ static struct kmem_cache *dentry_cache __read_mostly;
static unsigned int d_hash_mask __read_mostly;
static unsigned int d_hash_shift __read_mostly;
-static struct hlist_head *dentry_hashtable __read_mostly;
+
+struct dcache_hash_bucket {
+ struct hlist_bl_head head;
+};
+static struct dcache_hash_bucket *dentry_hashtable __read_mostly;
+
+static inline struct dcache_hash_bucket *d_hash(struct dentry *parent,
+ unsigned long hash)
+{
+ hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
+ hash = hash ^ ((hash ^ GOLDEN_RATIO_PRIME) >> D_HASHBITS);
+ return dentry_hashtable + (hash & D_HASHMASK);
+}
+
+static inline void spin_lock_bucket(struct dcache_hash_bucket *b)
+{
+ bit_spin_lock(0, (unsigned long *)&b->head.first);
+}
+
+static inline void spin_unlock_bucket(struct dcache_hash_bucket *b)
+{
+ __bit_spin_unlock(0, (unsigned long *)&b->head.first);
+}
/* Statistics gathering. */
struct dentry_stat_t dentry_stat = {
.age_limit = 45,
};
-static struct percpu_counter nr_dentry __cacheline_aligned_in_smp;
-static struct percpu_counter nr_dentry_unused __cacheline_aligned_in_smp;
+static DEFINE_PER_CPU(unsigned int, nr_dentry);
#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS)
+static int get_nr_dentry(void)
+{
+ int i;
+ int sum = 0;
+ for_each_possible_cpu(i)
+ sum += per_cpu(nr_dentry, i);
+ return sum < 0 ? 0 : sum;
+}
+
int proc_nr_dentry(ctl_table *table, int write, void __user *buffer,
size_t *lenp, loff_t *ppos)
{
- dentry_stat.nr_dentry = percpu_counter_sum_positive(&nr_dentry);
- dentry_stat.nr_unused = percpu_counter_sum_positive(&nr_dentry_unused);
+ dentry_stat.nr_dentry = get_nr_dentry();
return proc_dointvec(table, write, buffer, lenp, ppos);
}
#endif
@@ -91,35 +158,50 @@ static void __d_free(struct rcu_head *head)
}
/*
- * no dcache_lock, please.
+ * no locks, please.
*/
static void d_free(struct dentry *dentry)
{
- percpu_counter_dec(&nr_dentry);
+ BUG_ON(dentry->d_count);
+ this_cpu_dec(nr_dentry);
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
/* if dentry was never inserted into hash, immediate free is OK */
- if (hlist_unhashed(&dentry->d_hash))
+ if (hlist_bl_unhashed(&dentry->d_hash))
__d_free(&dentry->d_u.d_rcu);
else
call_rcu(&dentry->d_u.d_rcu, __d_free);
}
+/**
+ * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups
+ * After this call, in-progress rcu-walk path lookup will fail. This
+ * should be called after unhashing, and after changing d_inode (if
+ * the dentry has not already been unhashed).
+ */
+static inline void dentry_rcuwalk_barrier(struct dentry *dentry)
+{
+ assert_spin_locked(&dentry->d_lock);
+ /* Go through a barrier */
+ write_seqcount_barrier(&dentry->d_seq);
+}
+
/*
* Release the dentry's inode, using the filesystem
- * d_iput() operation if defined.
+ * d_iput() operation if defined. Dentry has no refcount
+ * and is unhashed.
*/
static void dentry_iput(struct dentry * dentry)
__releases(dentry->d_lock)
- __releases(dcache_lock)
+ __releases(dentry->d_inode->i_lock)
{
struct inode *inode = dentry->d_inode;
if (inode) {
dentry->d_inode = NULL;
list_del_init(&dentry->d_alias);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
if (!inode->i_nlink)
fsnotify_inoderemove(inode);
if (dentry->d_op && dentry->d_op->d_iput)
@@ -128,40 +210,72 @@ static void dentry_iput(struct dentry * dentry)
iput(inode);
} else {
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
}
}
/*
- * dentry_lru_(add|del|move_tail) must be called with dcache_lock held.
+ * Release the dentry's inode, using the filesystem
+ * d_iput() operation if defined. dentry remains in-use.
+ */
+static void dentry_unlink_inode(struct dentry * dentry)
+ __releases(dentry->d_lock)
+ __releases(dentry->d_inode->i_lock)
+{
+ struct inode *inode = dentry->d_inode;
+ dentry->d_inode = NULL;
+ list_del_init(&dentry->d_alias);
+ dentry_rcuwalk_barrier(dentry);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&inode->i_lock);
+ if (!inode->i_nlink)
+ fsnotify_inoderemove(inode);
+ if (dentry->d_op && dentry->d_op->d_iput)
+ dentry->d_op->d_iput(dentry, inode);
+ else
+ iput(inode);
+}
+
+/*
+ * dentry_lru_(add|del|move_tail) must be called with d_lock held.
*/
static void dentry_lru_add(struct dentry *dentry)
{
if (list_empty(&dentry->d_lru)) {
+ spin_lock(&dcache_lru_lock);
list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
dentry->d_sb->s_nr_dentry_unused++;
- percpu_counter_inc(&nr_dentry_unused);
+ dentry_stat.nr_unused++;
+ spin_unlock(&dcache_lru_lock);
}
}
+static void __dentry_lru_del(struct dentry *dentry)
+{
+ list_del_init(&dentry->d_lru);
+ dentry->d_sb->s_nr_dentry_unused--;
+ dentry_stat.nr_unused--;
+}
+
static void dentry_lru_del(struct dentry *dentry)
{
if (!list_empty(&dentry->d_lru)) {
- list_del_init(&dentry->d_lru);
- dentry->d_sb->s_nr_dentry_unused--;
- percpu_counter_dec(&nr_dentry_unused);
+ spin_lock(&dcache_lru_lock);
+ __dentry_lru_del(dentry);
+ spin_unlock(&dcache_lru_lock);
}
}
static void dentry_lru_move_tail(struct dentry *dentry)
{
+ spin_lock(&dcache_lru_lock);
if (list_empty(&dentry->d_lru)) {
list_add_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
dentry->d_sb->s_nr_dentry_unused++;
- percpu_counter_inc(&nr_dentry_unused);
+ dentry_stat.nr_unused++;
} else {
list_move_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
}
+ spin_unlock(&dcache_lru_lock);
}
/**
@@ -171,22 +285,115 @@ static void dentry_lru_move_tail(struct dentry *dentry)
* The dentry must already be unhashed and removed from the LRU.
*
* If this is the root of the dentry tree, return NULL.
+ *
+ * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by
+ * d_kill.
*/
-static struct dentry *d_kill(struct dentry *dentry)
+static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
__releases(dentry->d_lock)
- __releases(dcache_lock)
+ __releases(parent->d_lock)
+ __releases(dentry->d_inode->i_lock)
{
- struct dentry *parent;
-
+ dentry->d_parent = NULL;
list_del(&dentry->d_u.d_child);
- /*drops the locks, at that point nobody can reach this dentry */
+ if (parent)
+ spin_unlock(&parent->d_lock);
dentry_iput(dentry);
+ /*
+ * dentry_iput drops the locks, at which point nobody (except
+ * transient RCU lookups) can reach this dentry.
+ */
+ d_free(dentry);
+ return parent;
+}
+
+/**
+ * d_drop - drop a dentry
+ * @dentry: dentry to drop
+ *
+ * d_drop() unhashes the entry from the parent dentry hashes, so that it won't
+ * be found through a VFS lookup any more. Note that this is different from
+ * deleting the dentry - d_delete will try to mark the dentry negative if
+ * possible, giving a successful _negative_ lookup, while d_drop will
+ * just make the cache lookup fail.
+ *
+ * d_drop() is used mainly for stuff that wants to invalidate a dentry for some
+ * reason (NFS timeouts or autofs deletes).
+ *
+ * __d_drop requires dentry->d_lock.
+ */
+void __d_drop(struct dentry *dentry)
+{
+ if (!(dentry->d_flags & DCACHE_UNHASHED)) {
+ if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) {
+ bit_spin_lock(0,
+ (unsigned long *)&dentry->d_sb->s_anon.first);
+ dentry->d_flags |= DCACHE_UNHASHED;
+ hlist_bl_del_init(&dentry->d_hash);
+ __bit_spin_unlock(0,
+ (unsigned long *)&dentry->d_sb->s_anon.first);
+ } else {
+ struct dcache_hash_bucket *b;
+ b = d_hash(dentry->d_parent, dentry->d_name.hash);
+ spin_lock_bucket(b);
+ /*
+ * We may not actually need to put DCACHE_UNHASHED
+ * manipulations under the hash lock, but follow
+ * the principle of least surprise.
+ */
+ dentry->d_flags |= DCACHE_UNHASHED;
+ hlist_bl_del_rcu(&dentry->d_hash);
+ spin_unlock_bucket(b);
+ dentry_rcuwalk_barrier(dentry);
+ }
+ }
+}
+EXPORT_SYMBOL(__d_drop);
+
+void d_drop(struct dentry *dentry)
+{
+ spin_lock(&dentry->d_lock);
+ __d_drop(dentry);
+ spin_unlock(&dentry->d_lock);
+}
+EXPORT_SYMBOL(d_drop);
+
+/*
+ * Finish off a dentry we've decided to kill.
+ * dentry->d_lock must be held, returns with it unlocked.
+ * If ref is non-zero, then decrement the refcount too.
+ * Returns dentry requiring refcount drop, or NULL if we're done.
+ */
+static inline struct dentry *dentry_kill(struct dentry *dentry, int ref)
+ __releases(dentry->d_lock)
+{
+ struct inode *inode;
+ struct dentry *parent;
+
+ inode = dentry->d_inode;
+ if (inode && !spin_trylock(&inode->i_lock)) {
+relock:
+ spin_unlock(&dentry->d_lock);
+ cpu_relax();
+ return dentry; /* try again with same dentry */
+ }
if (IS_ROOT(dentry))
parent = NULL;
else
parent = dentry->d_parent;
- d_free(dentry);
- return parent;
+ if (parent && !spin_trylock(&parent->d_lock)) {
+ if (inode)
+ spin_unlock(&inode->i_lock);
+ goto relock;
+ }
+
+ if (ref)
+ dentry->d_count--;
+ /* if dentry was on the d_lru list delete it from there */
+ dentry_lru_del(dentry);
+ /* if it was on the hash then remove it */
+ __d_drop(dentry);
+ return d_kill(dentry, parent);
}
/*
@@ -214,34 +421,26 @@ static struct dentry *d_kill(struct dentry *dentry)
* call the dentry unlink method as well as removing it from the queues and
* releasing its resources. If the parent dentries were scheduled for release
* they too may now get deleted.
- *
- * no dcache lock, please.
*/
-
void dput(struct dentry *dentry)
{
if (!dentry)
return;
repeat:
- if (atomic_read(&dentry->d_count) == 1)
+ if (dentry->d_count == 1)
might_sleep();
- if (!atomic_dec_and_lock(&dentry->d_count, &dcache_lock))
- return;
-
spin_lock(&dentry->d_lock);
- if (atomic_read(&dentry->d_count)) {
+ BUG_ON(!dentry->d_count);
+ if (dentry->d_count > 1) {
+ dentry->d_count--;
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
return;
}
- /*
- * AV: ->d_delete() is _NOT_ allowed to block now.
- */
- if (dentry->d_op && dentry->d_op->d_delete) {
+ if (dentry->d_flags & DCACHE_OP_DELETE) {
if (dentry->d_op->d_delete(dentry))
- goto unhash_it;
+ goto kill_it;
}
/* Unreachable? Get rid of it */
@@ -252,16 +451,12 @@ repeat:
dentry->d_flags |= DCACHE_REFERENCED;
dentry_lru_add(dentry);
- spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
+ dentry->d_count--;
+ spin_unlock(&dentry->d_lock);
return;
-unhash_it:
- __d_drop(dentry);
kill_it:
- /* if dentry was on the d_lru list delete it from there */
- dentry_lru_del(dentry);
- dentry = d_kill(dentry);
+ dentry = dentry_kill(dentry, 1);
if (dentry)
goto repeat;
}
@@ -284,9 +479,9 @@ int d_invalidate(struct dentry * dentry)
/*
* If it's already been dropped, return OK.
*/
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
return 0;
}
/*
@@ -294,9 +489,9 @@ int d_invalidate(struct dentry * dentry)
* to get rid of unused child entries.
*/
if (!list_empty(&dentry->d_subdirs)) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
shrink_dcache_parent(dentry);
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
}
/*
@@ -309,35 +504,61 @@ int d_invalidate(struct dentry * dentry)
* we might still populate it if it was a
* working directory or similar).
*/
- spin_lock(&dentry->d_lock);
- if (atomic_read(&dentry->d_count) > 1) {
+ if (dentry->d_count > 1) {
if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
return -EBUSY;
}
}
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
return 0;
}
EXPORT_SYMBOL(d_invalidate);
-/* This should be called _only_ with dcache_lock held */
-static inline struct dentry * __dget_locked(struct dentry *dentry)
+/* This must be called with d_lock held */
+static inline void __dget_dlock(struct dentry *dentry)
{
- atomic_inc(&dentry->d_count);
- dentry_lru_del(dentry);
- return dentry;
+ dentry->d_count++;
}
-struct dentry * dget_locked(struct dentry *dentry)
+static inline void __dget(struct dentry *dentry)
{
- return __dget_locked(dentry);
+ spin_lock(&dentry->d_lock);
+ __dget_dlock(dentry);
+ spin_unlock(&dentry->d_lock);
}
-EXPORT_SYMBOL(dget_locked);
+
+struct dentry *dget_parent(struct dentry *dentry)
+{
+ struct dentry *ret;
+
+repeat:
+ /*
+ * Don't need rcu_dereference because we re-check it was correct under
+ * the lock.
+ */
+ rcu_read_lock();
+ ret = dentry->d_parent;
+ if (!ret) {
+ rcu_read_unlock();
+ goto out;
+ }
+ spin_lock(&ret->d_lock);
+ if (unlikely(ret != dentry->d_parent)) {
+ spin_unlock(&ret->d_lock);
+ rcu_read_unlock();
+ goto repeat;
+ }
+ rcu_read_unlock();
+ BUG_ON(!ret->d_count);
+ ret->d_count++;
+ spin_unlock(&ret->d_lock);
+out:
+ return ret;
+}
+EXPORT_SYMBOL(dget_parent);
/**
* d_find_alias - grab a hashed alias of inode
@@ -355,42 +576,56 @@ EXPORT_SYMBOL(dget_locked);
* any other hashed alias over that one unless @want_discon is set,
* in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias.
*/
-
-static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
+static struct dentry *___d_find_alias(struct inode *inode, int want_discon)
{
- struct list_head *head, *next, *tmp;
- struct dentry *alias, *discon_alias=NULL;
+ struct dentry *alias, *discon_alias;
- head = &inode->i_dentry;
- next = inode->i_dentry.next;
- while (next != head) {
- tmp = next;
- next = tmp->next;
- prefetch(next);
- alias = list_entry(tmp, struct dentry, d_alias);
+again:
+ discon_alias = NULL;
+ list_for_each_entry(alias, &inode->i_dentry, d_alias) {
+ spin_lock(&alias->d_lock);
if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
if (IS_ROOT(alias) &&
(alias->d_flags & DCACHE_DISCONNECTED))
discon_alias = alias;
- else if (!want_discon) {
- __dget_locked(alias);
+ else if (!want_discon)
+ return alias;
+ }
+ spin_unlock(&alias->d_lock);
+ }
+ if (discon_alias) {
+ alias = discon_alias;
+ spin_lock(&alias->d_lock);
+ if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
+ if (IS_ROOT(alias) &&
+ (alias->d_flags & DCACHE_DISCONNECTED))
return alias;
- }
}
+ spin_unlock(&alias->d_lock);
+ goto again;
+ }
+ return NULL;
+}
+
+static struct dentry *__d_find_alias(struct inode *inode, int want_discon)
+{
+ struct dentry *alias;
+ alias = ___d_find_alias(inode, want_discon);
+ if (alias) {
+ __dget_dlock(alias);
+ spin_unlock(&alias->d_lock);
}
- if (discon_alias)
- __dget_locked(discon_alias);
- return discon_alias;
+ return alias;
}
-struct dentry * d_find_alias(struct inode *inode)
+struct dentry *d_find_alias(struct inode *inode)
{
struct dentry *de = NULL;
if (!list_empty(&inode->i_dentry)) {
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
de = __d_find_alias(inode, 0);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
}
return de;
}
@@ -404,54 +639,61 @@ void d_prune_aliases(struct inode *inode)
{
struct dentry *dentry;
restart:
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
spin_lock(&dentry->d_lock);
- if (!atomic_read(&dentry->d_count)) {
- __dget_locked(dentry);
+ if (!dentry->d_count) {
+ __dget_dlock(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
dput(dentry);
goto restart;
}
spin_unlock(&dentry->d_lock);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(d_prune_aliases);
/*
- * Throw away a dentry - free the inode, dput the parent. This requires that
- * the LRU list has already been removed.
+ * Try to throw away a dentry - free the inode, dput the parent.
+ * Requires dentry->d_lock is held, and dentry->d_count == 0.
+ * Releases dentry->d_lock.
*
- * Try to prune ancestors as well. This is necessary to prevent
- * quadratic behavior of shrink_dcache_parent(), but is also expected
- * to be beneficial in reducing dentry cache fragmentation.
+ * This may fail if locks cannot be acquired no problem, just try again.
*/
-static void prune_one_dentry(struct dentry * dentry)
+static void try_prune_one_dentry(struct dentry *dentry)
__releases(dentry->d_lock)
- __releases(dcache_lock)
- __acquires(dcache_lock)
{
- __d_drop(dentry);
- dentry = d_kill(dentry);
+ struct dentry *parent;
+ parent = dentry_kill(dentry, 0);
/*
- * Prune ancestors. Locking is simpler than in dput(),
- * because dcache_lock needs to be taken anyway.
+ * If dentry_kill returns NULL, we have nothing more to do.
+ * if it returns the same dentry, trylocks failed. In either
+ * case, just loop again.
+ *
+ * Otherwise, we need to prune ancestors too. This is necessary
+ * to prevent quadratic behavior of shrink_dcache_parent(), but
+ * is also expected to be beneficial in reducing dentry cache
+ * fragmentation.
*/
- spin_lock(&dcache_lock);
+ if (!parent)
+ return;
+ if (parent == dentry)
+ return;
+
+ /* Prune ancestors. */
+ dentry = parent;
while (dentry) {
- if (!atomic_dec_and_lock(&dentry->d_count, &dentry->d_lock))
+ spin_lock(&dentry->d_lock);
+ if (dentry->d_count > 1) {
+ dentry->d_count--;
+ spin_unlock(&dentry->d_lock);
return;
-
- if (dentry->d_op && dentry->d_op->d_delete)
- dentry->d_op->d_delete(dentry);
- dentry_lru_del(dentry);
- __d_drop(dentry);
- dentry = d_kill(dentry);
- spin_lock(&dcache_lock);
+ }
+ dentry = dentry_kill(dentry, 1);
}
}
@@ -459,24 +701,35 @@ static void shrink_dentry_list(struct list_head *list)
{
struct dentry *dentry;
- while (!list_empty(list)) {
- dentry = list_entry(list->prev, struct dentry, d_lru);
- dentry_lru_del(dentry);
+ rcu_read_lock();
+ for (;;) {
+ dentry = list_entry_rcu(list->prev, struct dentry, d_lru);
+ if (&dentry->d_lru == list)
+ break; /* empty */
+ spin_lock(&dentry->d_lock);
+ if (dentry != list_entry(list->prev, struct dentry, d_lru)) {
+ spin_unlock(&dentry->d_lock);
+ continue;
+ }
/*
* We found an inuse dentry which was not removed from
* the LRU because of laziness during lookup. Do not free
* it - just keep it off the LRU list.
*/
- spin_lock(&dentry->d_lock);
- if (atomic_read(&dentry->d_count)) {
+ if (dentry->d_count) {
+ dentry_lru_del(dentry);
spin_unlock(&dentry->d_lock);
continue;
}
- prune_one_dentry(dentry);
- /* dentry->d_lock was dropped in prune_one_dentry() */
- cond_resched_lock(&dcache_lock);
+
+ rcu_read_unlock();
+
+ try_prune_one_dentry(dentry);
+
+ rcu_read_lock();
}
+ rcu_read_unlock();
}
/**
@@ -495,42 +748,44 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags)
LIST_HEAD(tmp);
int cnt = *count;
- spin_lock(&dcache_lock);
+relock:
+ spin_lock(&dcache_lru_lock);
while (!list_empty(&sb->s_dentry_lru)) {
dentry = list_entry(sb->s_dentry_lru.prev,
struct dentry, d_lru);
BUG_ON(dentry->d_sb != sb);
+ if (!spin_trylock(&dentry->d_lock)) {
+ spin_unlock(&dcache_lru_lock);
+ cpu_relax();
+ goto relock;
+ }
+
/*
* If we are honouring the DCACHE_REFERENCED flag and the
* dentry has this flag set, don't free it. Clear the flag
* and put it back on the LRU.
*/
- if (flags & DCACHE_REFERENCED) {
- spin_lock(&dentry->d_lock);
- if (dentry->d_flags & DCACHE_REFERENCED) {
- dentry->d_flags &= ~DCACHE_REFERENCED;
- list_move(&dentry->d_lru, &referenced);
- spin_unlock(&dentry->d_lock);
- cond_resched_lock(&dcache_lock);
- continue;
- }
+ if (flags & DCACHE_REFERENCED &&
+ dentry->d_flags & DCACHE_REFERENCED) {
+ dentry->d_flags &= ~DCACHE_REFERENCED;
+ list_move(&dentry->d_lru, &referenced);
+ spin_unlock(&dentry->d_lock);
+ } else {
+ list_move_tail(&dentry->d_lru, &tmp);
spin_unlock(&dentry->d_lock);
+ if (!--cnt)
+ break;
}
-
- list_move_tail(&dentry->d_lru, &tmp);
- if (!--cnt)
- break;
- cond_resched_lock(&dcache_lock);
+ cond_resched_lock(&dcache_lru_lock);
}
-
- *count = cnt;
- shrink_dentry_list(&tmp);
-
if (!list_empty(&referenced))
list_splice(&referenced, &sb->s_dentry_lru);
- spin_unlock(&dcache_lock);
+ spin_unlock(&dcache_lru_lock);
+ shrink_dentry_list(&tmp);
+
+ *count = cnt;
}
/**
@@ -546,13 +801,12 @@ static void prune_dcache(int count)
{
struct super_block *sb, *p = NULL;
int w_count;
- int unused = percpu_counter_sum_positive(&nr_dentry_unused);
+ int unused = dentry_stat.nr_unused;
int prune_ratio;
int pruned;
if (unused == 0 || count == 0)
return;
- spin_lock(&dcache_lock);
if (count >= unused)
prune_ratio = 1;
else
@@ -589,11 +843,9 @@ static void prune_dcache(int count)
if (down_read_trylock(&sb->s_umount)) {
if ((sb->s_root != NULL) &&
(!list_empty(&sb->s_dentry_lru))) {
- spin_unlock(&dcache_lock);
__shrink_dcache_sb(sb, &w_count,
DCACHE_REFERENCED);
pruned -= w_count;
- spin_lock(&dcache_lock);
}
up_read(&sb->s_umount);
}
@@ -609,7 +861,6 @@ static void prune_dcache(int count)
if (p)
__put_super(p);
spin_unlock(&sb_lock);
- spin_unlock(&dcache_lock);
}
/**
@@ -623,12 +874,14 @@ void shrink_dcache_sb(struct super_block *sb)
{
LIST_HEAD(tmp);
- spin_lock(&dcache_lock);
+ spin_lock(&dcache_lru_lock);
while (!list_empty(&sb->s_dentry_lru)) {
list_splice_init(&sb->s_dentry_lru, &tmp);
+ spin_unlock(&dcache_lru_lock);
shrink_dentry_list(&tmp);
+ spin_lock(&dcache_lru_lock);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dcache_lru_lock);
}
EXPORT_SYMBOL(shrink_dcache_sb);
@@ -645,10 +898,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
BUG_ON(!IS_ROOT(dentry));
/* detach this root from the system */
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
dentry_lru_del(dentry);
__d_drop(dentry);
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
for (;;) {
/* descend to the first leaf in the current subtree */
@@ -657,14 +910,16 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
/* this is a branch with children - detach all of them
* from the system in one go */
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
list_for_each_entry(loop, &dentry->d_subdirs,
d_u.d_child) {
+ spin_lock_nested(&loop->d_lock,
+ DENTRY_D_LOCK_NESTED);
dentry_lru_del(loop);
__d_drop(loop);
- cond_resched_lock(&dcache_lock);
+ spin_unlock(&loop->d_lock);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
/* move to the first child */
dentry = list_entry(dentry->d_subdirs.next,
@@ -676,7 +931,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
do {
struct inode *inode;
- if (atomic_read(&dentry->d_count) != 0) {
+ if (dentry->d_count != 0) {
printk(KERN_ERR
"BUG: Dentry %p{i=%lx,n=%s}"
" still in use (%d)"
@@ -685,20 +940,23 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
dentry->d_inode ?
dentry->d_inode->i_ino : 0UL,
dentry->d_name.name,
- atomic_read(&dentry->d_count),
+ dentry->d_count,
dentry->d_sb->s_type->name,
dentry->d_sb->s_id);
BUG();
}
- if (IS_ROOT(dentry))
+ if (IS_ROOT(dentry)) {
parent = NULL;
- else {
+ list_del(&dentry->d_u.d_child);
+ } else {
parent = dentry->d_parent;
- atomic_dec(&parent->d_count);
+ spin_lock(&parent->d_lock);
+ parent->d_count--;
+ list_del(&dentry->d_u.d_child);
+ spin_unlock(&parent->d_lock);
}
- list_del(&dentry->d_u.d_child);
detached++;
inode = dentry->d_inode;
@@ -728,8 +986,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
/*
* destroy the dentries attached to a superblock on unmounting
- * - we don't need to use dentry->d_lock, and only need dcache_lock when
- * removing the dentry from the system lists and hashes because:
+ * - we don't need to use dentry->d_lock because:
* - the superblock is detached from all mountings and open files, so the
* dentry trees will not be rearranged by the VFS
* - s_umount is write-locked, so the memory pressure shrinker will ignore
@@ -746,11 +1003,13 @@ void shrink_dcache_for_umount(struct super_block *sb)
dentry = sb->s_root;
sb->s_root = NULL;
- atomic_dec(&dentry->d_count);
+ spin_lock(&dentry->d_lock);
+ dentry->d_count--;
+ spin_unlock(&dentry->d_lock);
shrink_dcache_for_umount_subtree(dentry);
- while (!hlist_empty(&sb->s_anon)) {
- dentry = hlist_entry(sb->s_anon.first, struct dentry, d_hash);
+ while (!hlist_bl_empty(&sb->s_anon)) {
+ dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash);
shrink_dcache_for_umount_subtree(dentry);
}
}
@@ -768,15 +1027,20 @@ void shrink_dcache_for_umount(struct super_block *sb)
* Return true if the parent or its subdirectories contain
* a mount point
*/
-
int have_submounts(struct dentry *parent)
{
- struct dentry *this_parent = parent;
+ struct dentry *this_parent;
struct list_head *next;
+ unsigned seq;
+ int locked = 0;
+
+ seq = read_seqbegin(&rename_lock);
+again:
+ this_parent = parent;
- spin_lock(&dcache_lock);
if (d_mountpoint(parent))
goto positive;
+ spin_lock(&this_parent->d_lock);
repeat:
next = this_parent->d_subdirs.next;
resume:
@@ -784,27 +1048,65 @@ resume:
struct list_head *tmp = next;
struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
next = tmp->next;
+
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
/* Have we found a mount point ? */
- if (d_mountpoint(dentry))
+ if (d_mountpoint(dentry)) {
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&this_parent->d_lock);
goto positive;
+ }
if (!list_empty(&dentry->d_subdirs)) {
+ spin_unlock(&this_parent->d_lock);
+ spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
this_parent = dentry;
+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
goto repeat;
}
+ spin_unlock(&dentry->d_lock);
}
/*
* All done at this level ... ascend and resume the search.
*/
if (this_parent != parent) {
- next = this_parent->d_u.d_child.next;
- this_parent = this_parent->d_parent;
+ struct dentry *tmp;
+ struct dentry *child;
+
+ tmp = this_parent->d_parent;
+ rcu_read_lock();
+ spin_unlock(&this_parent->d_lock);
+ child = this_parent;
+ this_parent = tmp;
+ spin_lock(&this_parent->d_lock);
+ /* might go back up the wrong parent if we have had a rename
+ * or deletion */
+ if (this_parent != child->d_parent ||
+ (!locked && read_seqretry(&rename_lock, seq))) {
+ spin_unlock(&this_parent->d_lock);
+ rcu_read_unlock();
+ goto rename_retry;
+ }
+ rcu_read_unlock();
+ next = child->d_u.d_child.next;
goto resume;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&this_parent->d_lock);
+ if (!locked && read_seqretry(&rename_lock, seq))
+ goto rename_retry;
+ if (locked)
+ write_sequnlock(&rename_lock);
return 0; /* No mount points found in tree */
positive:
- spin_unlock(&dcache_lock);
+ if (!locked && read_seqretry(&rename_lock, seq))
+ goto rename_retry;
+ if (locked)
+ write_sequnlock(&rename_lock);
return 1;
+
+rename_retry:
+ locked = 1;
+ write_seqlock(&rename_lock);
+ goto again;
}
EXPORT_SYMBOL(have_submounts);
@@ -824,11 +1126,16 @@ EXPORT_SYMBOL(have_submounts);
*/
static int select_parent(struct dentry * parent)
{
- struct dentry *this_parent = parent;
+ struct dentry *this_parent;
struct list_head *next;
+ unsigned seq;
int found = 0;
+ int locked = 0;
- spin_lock(&dcache_lock);
+ seq = read_seqbegin(&rename_lock);
+again:
+ this_parent = parent;
+ spin_lock(&this_parent->d_lock);
repeat:
next = this_parent->d_subdirs.next;
resume:
@@ -837,11 +1144,13 @@ resume:
struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
next = tmp->next;
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+
/*
* move only zero ref count dentries to the end
* of the unused list for prune_dcache
*/
- if (!atomic_read(&dentry->d_count)) {
+ if (!dentry->d_count) {
dentry_lru_move_tail(dentry);
found++;
} else {
@@ -853,28 +1162,63 @@ resume:
* ensures forward progress). We'll be coming back to find
* the rest.
*/
- if (found && need_resched())
+ if (found && need_resched()) {
+ spin_unlock(&dentry->d_lock);
goto out;
+ }
/*
* Descend a level if the d_subdirs list is non-empty.
*/
if (!list_empty(&dentry->d_subdirs)) {
+ spin_unlock(&this_parent->d_lock);
+ spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
this_parent = dentry;
+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
goto repeat;
}
+
+ spin_unlock(&dentry->d_lock);
}
/*
* All done at this level ... ascend and resume the search.
*/
if (this_parent != parent) {
- next = this_parent->d_u.d_child.next;
- this_parent = this_parent->d_parent;
+ struct dentry *tmp;
+ struct dentry *child;
+
+ tmp = this_parent->d_parent;
+ rcu_read_lock();
+ spin_unlock(&this_parent->d_lock);
+ child = this_parent;
+ this_parent = tmp;
+ spin_lock(&this_parent->d_lock);
+ /* might go back up the wrong parent if we have had a rename
+ * or deletion */
+ if (this_parent != child->d_parent ||
+ (!locked && read_seqretry(&rename_lock, seq))) {
+ spin_unlock(&this_parent->d_lock);
+ rcu_read_unlock();
+ goto rename_retry;
+ }
+ rcu_read_unlock();
+ next = child->d_u.d_child.next;
goto resume;
}
out:
- spin_unlock(&dcache_lock);
+ spin_unlock(&this_parent->d_lock);
+ if (!locked && read_seqretry(&rename_lock, seq))
+ goto rename_retry;
+ if (locked)
+ write_sequnlock(&rename_lock);
return found;
+
+rename_retry:
+ if (found)
+ return found;
+ locked = 1;
+ write_seqlock(&rename_lock);
+ goto again;
}
/**
@@ -908,16 +1252,13 @@ EXPORT_SYMBOL(shrink_dcache_parent);
*/
static int shrink_dcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask)
{
- int nr_unused;
-
if (nr) {
if (!(gfp_mask & __GFP_FS))
return -1;
prune_dcache(nr);
}
- nr_unused = percpu_counter_sum_positive(&nr_dentry_unused);
- return (nr_unused / 100) * sysctl_vfs_cache_pressure;
+ return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
static struct shrinker dcache_shrinker = {
@@ -960,38 +1301,52 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
memcpy(dname, name->name, name->len);
dname[name->len] = 0;
- atomic_set(&dentry->d_count, 1);
+ dentry->d_count = 1;
dentry->d_flags = DCACHE_UNHASHED;
spin_lock_init(&dentry->d_lock);
+ seqcount_init(&dentry->d_seq);
dentry->d_inode = NULL;
dentry->d_parent = NULL;
dentry->d_sb = NULL;
dentry->d_op = NULL;
dentry->d_fsdata = NULL;
- dentry->d_mounted = 0;
- INIT_HLIST_NODE(&dentry->d_hash);
+ INIT_HLIST_BL_NODE(&dentry->d_hash);
INIT_LIST_HEAD(&dentry->d_lru);
INIT_LIST_HEAD(&dentry->d_subdirs);
INIT_LIST_HEAD(&dentry->d_alias);
+ INIT_LIST_HEAD(&dentry->d_u.d_child);
if (parent) {
- dentry->d_parent = dget(parent);
+ spin_lock(&parent->d_lock);
+ /*
+ * don't need child lock because it is not subject
+ * to concurrency here
+ */
+ __dget_dlock(parent);
+ dentry->d_parent = parent;
dentry->d_sb = parent->d_sb;
- } else {
- INIT_LIST_HEAD(&dentry->d_u.d_child);
- }
-
- spin_lock(&dcache_lock);
- if (parent)
list_add(&dentry->d_u.d_child, &parent->d_subdirs);
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
+ }
- percpu_counter_inc(&nr_dentry);
+ this_cpu_inc(nr_dentry);
return dentry;
}
EXPORT_SYMBOL(d_alloc);
+struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
+{
+ struct dentry *dentry = d_alloc(NULL, name);
+ if (dentry) {
+ dentry->d_sb = sb;
+ dentry->d_parent = dentry;
+ dentry->d_flags |= DCACHE_DISCONNECTED;
+ }
+ return dentry;
+}
+EXPORT_SYMBOL(d_alloc_pseudo);
+
struct dentry *d_alloc_name(struct dentry *parent, const char *name)
{
struct qstr q;
@@ -1003,12 +1358,39 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name)
}
EXPORT_SYMBOL(d_alloc_name);
-/* the caller must hold dcache_lock */
+void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
+{
+ BUG_ON(dentry->d_op);
+ BUG_ON(dentry->d_flags & (DCACHE_OP_HASH |
+ DCACHE_OP_COMPARE |
+ DCACHE_OP_REVALIDATE |
+ DCACHE_OP_REVALIDATE_RCU|
+ DCACHE_OP_DELETE ));
+ dentry->d_op = op;
+ if (!op)
+ return;
+ if (op->d_hash)
+ dentry->d_flags |= DCACHE_OP_HASH;
+ if (op->d_compare)
+ dentry->d_flags |= DCACHE_OP_COMPARE;
+ if (op->d_revalidate)
+ dentry->d_flags |= DCACHE_OP_REVALIDATE;
+ if (op->d_revalidate_rcu)
+ dentry->d_flags |= DCACHE_OP_REVALIDATE_RCU;
+ if (op->d_delete)
+ dentry->d_flags |= DCACHE_OP_DELETE;
+
+}
+EXPORT_SYMBOL(d_set_d_op);
+
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
{
+ spin_lock(&dentry->d_lock);
if (inode)
list_add(&dentry->d_alias, &inode->i_dentry);
dentry->d_inode = inode;
+ dentry_rcuwalk_barrier(dentry);
+ spin_unlock(&dentry->d_lock);
fsnotify_d_instantiate(dentry, inode);
}
@@ -1030,9 +1412,11 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
void d_instantiate(struct dentry *entry, struct inode * inode)
{
BUG_ON(!list_empty(&entry->d_alias));
- spin_lock(&dcache_lock);
+ if (inode)
+ spin_lock(&inode->i_lock);
__d_instantiate(entry, inode);
- spin_unlock(&dcache_lock);
+ if (inode)
+ spin_unlock(&inode->i_lock);
security_d_instantiate(entry, inode);
}
EXPORT_SYMBOL(d_instantiate);
@@ -1069,15 +1453,20 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
list_for_each_entry(alias, &inode->i_dentry, d_alias) {
struct qstr *qstr = &alias->d_name;
+ /*
+ * Don't need alias->d_lock here, because aliases with
+ * d_parent == entry->d_parent are not subject to name or
+ * parent changes, because the parent inode i_mutex is held.
+ */
if (qstr->hash != hash)
continue;
if (alias->d_parent != entry->d_parent)
continue;
if (qstr->len != len)
continue;
- if (memcmp(qstr->name, name, len))
+ if (dentry_memcmp(qstr->name, name, len))
continue;
- dget_locked(alias);
+ __dget(alias);
return alias;
}
@@ -1091,9 +1480,11 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
BUG_ON(!list_empty(&entry->d_alias));
- spin_lock(&dcache_lock);
+ if (inode)
+ spin_lock(&inode->i_lock);
result = __d_instantiate_unique(entry, inode);
- spin_unlock(&dcache_lock);
+ if (inode)
+ spin_unlock(&inode->i_lock);
if (!result) {
security_d_instantiate(entry, inode);
@@ -1134,14 +1525,6 @@ struct dentry * d_alloc_root(struct inode * root_inode)
}
EXPORT_SYMBOL(d_alloc_root);
-static inline struct hlist_head *d_hash(struct dentry *parent,
- unsigned long hash)
-{
- hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
- hash = hash ^ ((hash ^ GOLDEN_RATIO_PRIME) >> D_HASHBITS);
- return dentry_hashtable + (hash & D_HASHMASK);
-}
-
/**
* d_obtain_alias - find or allocate a dentry for a given inode
* @inode: inode to allocate the dentry for
@@ -1182,10 +1565,11 @@ struct dentry *d_obtain_alias(struct inode *inode)
}
tmp->d_parent = tmp; /* make sure dput doesn't croak */
- spin_lock(&dcache_lock);
+
+ spin_lock(&inode->i_lock);
res = __d_find_alias(inode, 0);
if (res) {
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
dput(tmp);
goto out_iput;
}
@@ -1195,12 +1579,14 @@ struct dentry *d_obtain_alias(struct inode *inode)
tmp->d_sb = inode->i_sb;
tmp->d_inode = inode;
tmp->d_flags |= DCACHE_DISCONNECTED;
- tmp->d_flags &= ~DCACHE_UNHASHED;
list_add(&tmp->d_alias, &inode->i_dentry);
- hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon);
+ bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first);
+ tmp->d_flags &= ~DCACHE_UNHASHED;
+ hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
+ __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first);
spin_unlock(&tmp->d_lock);
+ spin_unlock(&inode->i_lock);
- spin_unlock(&dcache_lock);
return tmp;
out_iput:
@@ -1230,18 +1616,18 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
struct dentry *new = NULL;
if (inode && S_ISDIR(inode->i_mode)) {
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
new = __d_find_alias(inode, 1);
if (new) {
BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
security_d_instantiate(new, inode);
d_move(new, dentry);
iput(inode);
} else {
- /* already taking dcache_lock, so d_add() by hand */
+ /* already taking inode->i_lock, so d_add() by hand */
__d_instantiate(dentry, inode);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
security_d_instantiate(dentry, inode);
d_rehash(dentry);
}
@@ -1314,10 +1700,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
* Negative dentry: instantiate it unless the inode is a directory and
* already has a dentry.
*/
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
__d_instantiate(found, inode);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
security_d_instantiate(found, inode);
return found;
}
@@ -1327,8 +1713,8 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
* reference to it, move it in place and use it.
*/
new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
- dget_locked(new);
- spin_unlock(&dcache_lock);
+ __dget(new);
+ spin_unlock(&inode->i_lock);
security_d_instantiate(found, inode);
d_move(new, found);
iput(inode);
@@ -1342,6 +1728,114 @@ err_out:
EXPORT_SYMBOL(d_add_ci);
/**
+ * __d_lookup_rcu - search for a dentry (racy, store-free)
+ * @parent: parent dentry
+ * @name: qstr of name we wish to find
+ * @seq: returns d_seq value at the point where the dentry was found
+ * @inode: returns dentry->d_inode when the inode was found valid.
+ * Returns: dentry, or NULL
+ *
+ * __d_lookup_rcu is the dcache lookup function for rcu-walk name
+ * resolution (store-free path walking) design described in
+ * Documentation/filesystems/path-lookup.txt.
+ *
+ * This is not to be used outside core vfs.
+ *
+ * __d_lookup_rcu must only be used in rcu-walk mode, ie. with vfsmount lock
+ * held, and rcu_read_lock held. The returned dentry must not be stored into
+ * without taking d_lock and checking d_seq sequence count against @seq
+ * returned here.
+ *
+ * A refcount may be taken on the found dentry with the __d_rcu_to_refcount
+ * function.
+ *
+ * Alternatively, __d_lookup_rcu may be called again to look up the child of
+ * the returned dentry, so long as its parent's seqlock is checked after the
+ * child is looked up. Thus, an interlocking stepping of sequence lock checks
+ * is formed, giving integrity down the path walk.
+ */
+struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
+ unsigned *seq, struct inode **inode)
+{
+ unsigned int len = name->len;
+ unsigned int hash = name->hash;
+ const unsigned char *str = name->name;
+ struct dcache_hash_bucket *b = d_hash(parent, hash);
+ struct hlist_bl_node *node;
+ struct dentry *dentry;
+
+ /*
+ * Note: There is significant duplication with __d_lookup_rcu which is
+ * required to prevent single threaded performance regressions
+ * especially on architectures where smp_rmb (in seqcounts) are costly.
+ * Keep the two functions in sync.
+ */
+
+ /*
+ * The hash list is protected using RCU.
+ *
+ * Carefully use d_seq when comparing a candidate dentry, to avoid
+ * races with d_move().
+ *
+ * It is possible that concurrent renames can mess up our list
+ * walk here and result in missing our dentry, resulting in the
+ * false-negative result. d_lookup() protects against concurrent
+ * renames using rename_lock seqlock.
+ *
+ * See Documentation/vfs/dcache-locking.txt for more details.
+ */
+ hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) {
+ struct inode *i;
+ const char *tname;
+ int tlen;
+
+ if (dentry->d_name.hash != hash)
+ continue;
+
+seqretry:
+ *seq = read_seqcount_begin(&dentry->d_seq);
+ if (dentry->d_parent != parent)
+ continue;
+ if (d_unhashed(dentry))
+ continue;
+ tlen = dentry->d_name.len;
+ tname = dentry->d_name.name;
+ i = dentry->d_inode;
+ prefetch(tname);
+ if (i)
+ prefetch(i);
+ /*
+ * This seqcount check is required to ensure name and
+ * len are loaded atomically, so as not to walk off the
+ * edge of memory when walking. If we could load this
+ * atomically some other way, we could drop this check.
+ */
+ if (read_seqcount_retry(&dentry->d_seq, *seq))
+ goto seqretry;
+ if (parent->d_flags & DCACHE_OP_COMPARE) {
+ if (parent->d_op->d_compare(parent, *inode,
+ dentry, i,
+ tlen, tname, name))
+ continue;
+ } else {
+ if (tlen != len)
+ continue;
+ if (dentry_memcmp(tname, str, tlen))
+ continue;
+ }
+ /*
+ * No extra seqcount check is required after the name
+ * compare. The caller must perform a seqcount check in
+ * order to do anything useful with the returned dentry
+ * anyway.
+ */
+ *inode = i;
+ return dentry;
+ }
+ return NULL;
+}
+
+/**
* d_lookup - search for a dentry
* @parent: parent dentry
* @name: qstr of name we wish to find
@@ -1352,10 +1846,10 @@ EXPORT_SYMBOL(d_add_ci);
* dentry is returned. The caller must use dput to free the entry when it has
* finished using it. %NULL is returned if the dentry does not exist.
*/
-struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
+struct dentry *d_lookup(struct dentry *parent, struct qstr *name)
{
- struct dentry * dentry = NULL;
- unsigned long seq;
+ struct dentry *dentry;
+ unsigned seq;
do {
seq = read_seqbegin(&rename_lock);
@@ -1367,7 +1861,7 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
}
EXPORT_SYMBOL(d_lookup);
-/*
+/**
* __d_lookup - search for a dentry (racy)
* @parent: parent dentry
* @name: qstr of name we wish to find
@@ -1382,17 +1876,24 @@ EXPORT_SYMBOL(d_lookup);
*
* __d_lookup callers must be commented.
*/
-struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
+struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
{
unsigned int len = name->len;
unsigned int hash = name->hash;
const unsigned char *str = name->name;
- struct hlist_head *head = d_hash(parent,hash);
+ struct dcache_hash_bucket *b = d_hash(parent, hash);
+ struct hlist_bl_node *node;
struct dentry *found = NULL;
- struct hlist_node *node;
struct dentry *dentry;
/*
+ * Note: There is significant duplication with __d_lookup_rcu which is
+ * required to prevent single threaded performance regressions
+ * especially on architectures where smp_rmb (in seqcounts) are costly.
+ * Keep the two functions in sync.
+ */
+
+ /*
* The hash list is protected using RCU.
*
* Take d_lock when comparing a candidate dentry, to avoid races
@@ -1407,25 +1908,16 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
*/
rcu_read_lock();
- hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
- struct qstr *qstr;
+ hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) {
+ const char *tname;
+ int tlen;
if (dentry->d_name.hash != hash)
continue;
- if (dentry->d_parent != parent)
- continue;
spin_lock(&dentry->d_lock);
-
- /*
- * Recheck the dentry after taking the lock - d_move may have
- * changed things. Don't bother checking the hash because
- * we're about to compare the whole name anyway.
- */
if (dentry->d_parent != parent)
goto next;
-
- /* non-existing due to RCU? */
if (d_unhashed(dentry))
goto next;
@@ -1433,18 +1925,21 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
* It is safe to compare names since d_move() cannot
* change the qstr (protected by d_lock).
*/
- qstr = &dentry->d_name;
- if (parent->d_op && parent->d_op->d_compare) {
- if (parent->d_op->d_compare(parent, qstr, name))
+ tlen = dentry->d_name.len;
+ tname = dentry->d_name.name;
+ if (parent->d_flags & DCACHE_OP_COMPARE) {
+ if (parent->d_op->d_compare(parent, parent->d_inode,
+ dentry, dentry->d_inode,
+ tlen, tname, name))
goto next;
} else {
- if (qstr->len != len)
+ if (tlen != len)
goto next;
- if (memcmp(qstr->name, str, len))
+ if (dentry_memcmp(tname, str, tlen))
goto next;
}
- atomic_inc(&dentry->d_count);
+ dentry->d_count++;
found = dentry;
spin_unlock(&dentry->d_lock);
break;
@@ -1473,8 +1968,8 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
* routine may choose to leave the hash value unchanged.
*/
name->hash = full_name_hash(name->name, name->len);
- if (dir->d_op && dir->d_op->d_hash) {
- if (dir->d_op->d_hash(dir, name) < 0)
+ if (dir->d_flags & DCACHE_OP_HASH) {
+ if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0)
goto out;
}
dentry = d_lookup(dir, name);
@@ -1483,34 +1978,32 @@ out:
}
/**
- * d_validate - verify dentry provided from insecure source
+ * d_validate - verify dentry provided from insecure source (deprecated)
* @dentry: The dentry alleged to be valid child of @dparent
* @dparent: The parent dentry (known to be valid)
*
* An insecure source has sent us a dentry, here we verify it and dget() it.
* This is used by ncpfs in its readdir implementation.
* Zero is returned in the dentry is invalid.
+ *
+ * This function is slow for big directories, and deprecated, do not use it.
*/
-int d_validate(struct dentry *dentry, struct dentry *parent)
+int d_validate(struct dentry *dentry, struct dentry *dparent)
{
- struct hlist_head *head = d_hash(parent, dentry->d_name.hash);
- struct hlist_node *node;
- struct dentry *d;
+ struct dentry *child;
- /* Check whether the ptr might be valid at all.. */
- if (!kmem_ptr_validate(dentry_cache, dentry))
- return 0;
- if (dentry->d_parent != parent)
- return 0;
-
- rcu_read_lock();
- hlist_for_each_entry_rcu(d, node, head, d_hash) {
- if (d == dentry) {
- dget(dentry);
+ spin_lock(&dparent->d_lock);
+ list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
+ if (dentry == child) {
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+ __dget_dlock(dentry);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&dparent->d_lock);
return 1;
}
}
- rcu_read_unlock();
+ spin_unlock(&dparent->d_lock);
+
return 0;
}
EXPORT_SYMBOL(d_validate);
@@ -1538,16 +2031,23 @@ EXPORT_SYMBOL(d_validate);
void d_delete(struct dentry * dentry)
{
+ struct inode *inode;
int isdir = 0;
/*
* Are we the only user?
*/
- spin_lock(&dcache_lock);
+again:
spin_lock(&dentry->d_lock);
- isdir = S_ISDIR(dentry->d_inode->i_mode);
- if (atomic_read(&dentry->d_count) == 1) {
+ inode = dentry->d_inode;
+ isdir = S_ISDIR(inode->i_mode);
+ if (dentry->d_count == 1) {
+ if (inode && !spin_trylock(&inode->i_lock)) {
+ spin_unlock(&dentry->d_lock);
+ cpu_relax();
+ goto again;
+ }
dentry->d_flags &= ~DCACHE_CANT_MOUNT;
- dentry_iput(dentry);
+ dentry_unlink_inode(dentry);
fsnotify_nameremove(dentry, isdir);
return;
}
@@ -1556,17 +2056,18 @@ void d_delete(struct dentry * dentry)
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
fsnotify_nameremove(dentry, isdir);
}
EXPORT_SYMBOL(d_delete);
-static void __d_rehash(struct dentry * entry, struct hlist_head *list)
+static void __d_rehash(struct dentry * entry, struct dcache_hash_bucket *b)
{
-
+ BUG_ON(!d_unhashed(entry));
+ spin_lock_bucket(b);
entry->d_flags &= ~DCACHE_UNHASHED;
- hlist_add_head_rcu(&entry->d_hash, list);
+ hlist_bl_add_head_rcu(&entry->d_hash, &b->head);
+ spin_unlock_bucket(b);
}
static void _d_rehash(struct dentry * entry)
@@ -1583,25 +2084,39 @@ static void _d_rehash(struct dentry * entry)
void d_rehash(struct dentry * entry)
{
- spin_lock(&dcache_lock);
spin_lock(&entry->d_lock);
_d_rehash(entry);
spin_unlock(&entry->d_lock);
- spin_unlock(&dcache_lock);
}
EXPORT_SYMBOL(d_rehash);
-/*
- * When switching names, the actual string doesn't strictly have to
- * be preserved in the target - because we're dropping the target
- * anyway. As such, we can just do a simple memcpy() to copy over
- * the new name before we switch.
+/**
+ * dentry_update_name_case - update case insensitive dentry with a new name
+ * @dentry: dentry to be updated
+ * @name: new name
*
- * Note that we have to be a lot more careful about getting the hash
- * switched - we have to switch the hash value properly even if it
- * then no longer matches the actual (corrupted) string of the target.
- * The hash value has to match the hash queue that the dentry is on..
+ * Update a case insensitive dentry with new case of name.
+ *
+ * dentry must have been returned by d_lookup with name @name. Old and new
+ * name lengths must match (ie. no d_compare which allows mismatched name
+ * lengths).
+ *
+ * Parent inode i_mutex must be held over d_lookup and into this call (to
+ * keep renames and concurrent inserts, and readdir(2) away).
*/
+void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
+{
+ BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+ BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */
+
+ spin_lock(&dentry->d_lock);
+ write_seqcount_begin(&dentry->d_seq);
+ memcpy((unsigned char *)dentry->d_name.name, name->name, name->len);
+ write_seqcount_end(&dentry->d_seq);
+ spin_unlock(&dentry->d_lock);
+}
+EXPORT_SYMBOL(dentry_update_name_case);
+
static void switch_names(struct dentry *dentry, struct dentry *target)
{
if (dname_external(target)) {
@@ -1643,54 +2158,84 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
swap(dentry->d_name.len, target->d_name.len);
}
+static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
+{
+ /*
+ * XXXX: do we really need to take target->d_lock?
+ */
+ if (IS_ROOT(dentry) || dentry->d_parent == target->d_parent)
+ spin_lock(&target->d_parent->d_lock);
+ else {
+ if (d_ancestor(dentry->d_parent, target->d_parent)) {
+ spin_lock(&dentry->d_parent->d_lock);
+ spin_lock_nested(&target->d_parent->d_lock,
+ DENTRY_D_LOCK_NESTED);
+ } else {
+ spin_lock(&target->d_parent->d_lock);
+ spin_lock_nested(&dentry->d_parent->d_lock,
+ DENTRY_D_LOCK_NESTED);
+ }
+ }
+ if (target < dentry) {
+ spin_lock_nested(&target->d_lock, 2);
+ spin_lock_nested(&dentry->d_lock, 3);
+ } else {
+ spin_lock_nested(&dentry->d_lock, 2);
+ spin_lock_nested(&target->d_lock, 3);
+ }
+}
+
+static void dentry_unlock_parents_for_move(struct dentry *dentry,
+ struct dentry *target)
+{
+ if (target->d_parent != dentry->d_parent)
+ spin_unlock(&dentry->d_parent->d_lock);
+ if (target->d_parent != target)
+ spin_unlock(&target->d_parent->d_lock);
+}
+
/*
- * We cannibalize "target" when moving dentry on top of it,
- * because it's going to be thrown away anyway. We could be more
- * polite about it, though.
- *
- * This forceful removal will result in ugly /proc output if
- * somebody holds a file open that got deleted due to a rename.
- * We could be nicer about the deleted file, and let it show
- * up under the name it had before it was deleted rather than
- * under the original name of the file that was moved on top of it.
+ * When switching names, the actual string doesn't strictly have to
+ * be preserved in the target - because we're dropping the target
+ * anyway. As such, we can just do a simple memcpy() to copy over
+ * the new name before we switch.
+ *
+ * Note that we have to be a lot more careful about getting the hash
+ * switched - we have to switch the hash value properly even if it
+ * then no longer matches the actual (corrupted) string of the target.
+ * The hash value has to match the hash queue that the dentry is on..
*/
-
/*
- * d_move_locked - move a dentry
+ * d_move - move a dentry
* @dentry: entry to move
* @target: new dentry
*
* Update the dcache to reflect the move of a file name. Negative
* dcache entries should not be moved in this way.
*/
-static void d_move_locked(struct dentry * dentry, struct dentry * target)
+void d_move(struct dentry * dentry, struct dentry * target)
{
- struct hlist_head *list;
-
if (!dentry->d_inode)
printk(KERN_WARNING "VFS: moving negative dcache entry\n");
+ BUG_ON(d_ancestor(dentry, target));
+ BUG_ON(d_ancestor(target, dentry));
+
write_seqlock(&rename_lock);
- /*
- * XXXX: do we really need to take target->d_lock?
- */
- if (target < dentry) {
- spin_lock(&target->d_lock);
- spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
- } else {
- spin_lock(&dentry->d_lock);
- spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED);
- }
- /* Move the dentry to the target hash queue, if on different bucket */
- if (d_unhashed(dentry))
- goto already_unhashed;
+ dentry_lock_for_move(dentry, target);
- hlist_del_rcu(&dentry->d_hash);
+ write_seqcount_begin(&dentry->d_seq);
+ write_seqcount_begin(&target->d_seq);
-already_unhashed:
- list = d_hash(target->d_parent, target->d_name.hash);
- __d_rehash(dentry, list);
+ /* __d_drop does write_seqcount_barrier, but they're OK to nest. */
+
+ /*
+ * Move the dentry to the target hash queue. Don't bother checking
+ * for the same hash queue because of how unlikely it is.
+ */
+ __d_drop(dentry);
+ __d_rehash(dentry, d_hash(target->d_parent, target->d_name.hash));
/* Unhash the target: dput() will then get rid of it */
__d_drop(target);
@@ -1715,27 +2260,16 @@ already_unhashed:
}
list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
+
+ write_seqcount_end(&target->d_seq);
+ write_seqcount_end(&dentry->d_seq);
+
+ dentry_unlock_parents_for_move(dentry, target);
spin_unlock(&target->d_lock);
fsnotify_d_move(dentry);
spin_unlock(&dentry->d_lock);
write_sequnlock(&rename_lock);
}
-
-/**
- * d_move - move a dentry
- * @dentry: entry to move
- * @target: new dentry
- *
- * Update the dcache to reflect the move of a file name. Negative
- * dcache entries should not be moved in this way.
- */
-
-void d_move(struct dentry * dentry, struct dentry * target)
-{
- spin_lock(&dcache_lock);
- d_move_locked(dentry, target);
- spin_unlock(&dcache_lock);
-}
EXPORT_SYMBOL(d_move);
/**
@@ -1761,13 +2295,13 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
* This helper attempts to cope with remotely renamed directories
*
* It assumes that the caller is already holding
- * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ * dentry->d_parent->d_inode->i_mutex and the inode->i_lock
*
* Note: If ever the locking in lock_rename() changes, then please
* remember to update this too...
*/
-static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
- __releases(dcache_lock)
+static struct dentry *__d_unalias(struct inode *inode,
+ struct dentry *dentry, struct dentry *alias)
{
struct mutex *m1 = NULL, *m2 = NULL;
struct dentry *ret;
@@ -1790,10 +2324,10 @@ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
goto out_err;
m2 = &alias->d_parent->d_inode->i_mutex;
out_unalias:
- d_move_locked(alias, dentry);
+ d_move(alias, dentry);
ret = alias;
out_err:
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
if (m2)
mutex_unlock(m2);
if (m1)
@@ -1804,17 +2338,23 @@ out_err:
/*
* Prepare an anonymous dentry for life in the superblock's dentry tree as a
* named dentry in place of the dentry to be replaced.
+ * returns with anon->d_lock held!
*/
static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
{
struct dentry *dparent, *aparent;
- switch_names(dentry, anon);
- swap(dentry->d_name.hash, anon->d_name.hash);
+ dentry_lock_for_move(anon, dentry);
+
+ write_seqcount_begin(&dentry->d_seq);
+ write_seqcount_begin(&anon->d_seq);
dparent = dentry->d_parent;
aparent = anon->d_parent;
+ switch_names(dentry, anon);
+ swap(dentry->d_name.hash, anon->d_name.hash);
+
dentry->d_parent = (aparent == anon) ? dentry : aparent;
list_del(&dentry->d_u.d_child);
if (!IS_ROOT(dentry))
@@ -1829,6 +2369,13 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
else
INIT_LIST_HEAD(&anon->d_u.d_child);
+ write_seqcount_end(&dentry->d_seq);
+ write_seqcount_end(&anon->d_seq);
+
+ dentry_unlock_parents_for_move(anon, dentry);
+ spin_unlock(&dentry->d_lock);
+
+ /* anon->d_lock still locked, returns locked */
anon->d_flags &= ~DCACHE_DISCONNECTED;
}
@@ -1846,31 +2393,36 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
BUG_ON(!d_unhashed(dentry));
- spin_lock(&dcache_lock);
-
if (!inode) {
actual = dentry;
__d_instantiate(dentry, NULL);
- goto found_lock;
+ d_rehash(actual);
+ goto out_nolock;
}
+ spin_lock(&inode->i_lock);
+
if (S_ISDIR(inode->i_mode)) {
struct dentry *alias;
/* Does an aliased dentry already exist? */
alias = __d_find_alias(inode, 0);
if (alias) {
+ /*
+ * XXX: after dcache_lock removal, we no longer
+ * guarantee a !d_unhashed alias here. Is that going to
+ * be a problem?
+ */
actual = alias;
/* Is this an anonymous mountpoint that we could splice
* into our tree? */
if (IS_ROOT(alias)) {
- spin_lock(&alias->d_lock);
__d_materialise_dentry(dentry, alias);
__d_drop(alias);
goto found;
}
/* Nope, but we must(!) avoid directory aliasing */
- actual = __d_unalias(dentry, alias);
+ actual = __d_unalias(inode, dentry, alias);
if (IS_ERR(actual))
dput(alias);
goto out_nolock;
@@ -1881,15 +2433,14 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
actual = __d_instantiate_unique(dentry, inode);
if (!actual)
actual = dentry;
- else if (unlikely(!d_unhashed(actual)))
- goto shouldnt_be_hashed;
+ else
+ BUG_ON(!d_unhashed(actual));
-found_lock:
spin_lock(&actual->d_lock);
found:
_d_rehash(actual);
spin_unlock(&actual->d_lock);
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
out_nolock:
if (actual == dentry) {
security_d_instantiate(dentry, inode);
@@ -1898,10 +2449,6 @@ out_nolock:
iput(inode);
return actual;
-
-shouldnt_be_hashed:
- spin_unlock(&dcache_lock);
- BUG();
}
EXPORT_SYMBOL_GPL(d_materialise_unique);
@@ -1928,7 +2475,7 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
* @buffer: pointer to the end of the buffer
* @buflen: pointer to buffer length
*
- * Caller holds the dcache_lock.
+ * Caller holds the rename_lock.
*
* If path is not reachable from the supplied root, then the value of
* root is changed (without modifying refcounts).
@@ -1956,7 +2503,9 @@ static int prepend_path(const struct path *path, struct path *root,
}
parent = dentry->d_parent;
prefetch(parent);
+ spin_lock(&dentry->d_lock);
error = prepend_name(buffer, buflen, &dentry->d_name);
+ spin_unlock(&dentry->d_lock);
if (!error)
error = prepend(buffer, buflen, "/", 1);
if (error)
@@ -2012,9 +2561,9 @@ char *__d_path(const struct path *path, struct path *root,
int error;
prepend(&res, &buflen, "\0", 1);
- spin_lock(&dcache_lock);
+ write_seqlock(&rename_lock);
error = prepend_path(path, root, &res, &buflen);
- spin_unlock(&dcache_lock);
+ write_sequnlock(&rename_lock);
if (error)
return ERR_PTR(error);
@@ -2076,12 +2625,12 @@ char *d_path(const struct path *path, char *buf, int buflen)
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
get_fs_root(current->fs, &root);
- spin_lock(&dcache_lock);
+ write_seqlock(&rename_lock);
tmp = root;
error = path_with_deleted(path, &tmp, &res, &buflen);
if (error)
res = ERR_PTR(error);
- spin_unlock(&dcache_lock);
+ write_sequnlock(&rename_lock);
path_put(&root);
return res;
}
@@ -2107,12 +2656,12 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
get_fs_root(current->fs, &root);
- spin_lock(&dcache_lock);
+ write_seqlock(&rename_lock);
tmp = root;
error = path_with_deleted(path, &tmp, &res, &buflen);
if (!error && !path_equal(&tmp, &root))
error = prepend_unreachable(&res, &buflen);
- spin_unlock(&dcache_lock);
+ write_sequnlock(&rename_lock);
path_put(&root);
if (error)
res = ERR_PTR(error);
@@ -2144,7 +2693,7 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
/*
* Write full pathname from the root of the filesystem into the buffer.
*/
-char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
+static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
{
char *end = buf + buflen;
char *retval;
@@ -2158,10 +2707,13 @@ char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
while (!IS_ROOT(dentry)) {
struct dentry *parent = dentry->d_parent;
+ int error;
prefetch(parent);
- if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
- (prepend(&end, &buflen, "/", 1) != 0))
+ spin_lock(&dentry->d_lock);
+ error = prepend_name(&end, &buflen, &dentry->d_name);
+ spin_unlock(&dentry->d_lock);
+ if (error != 0 || prepend(&end, &buflen, "/", 1) != 0)
goto Elong;
retval = end;
@@ -2171,14 +2723,25 @@ char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
Elong:
return ERR_PTR(-ENAMETOOLONG);
}
-EXPORT_SYMBOL(__dentry_path);
+
+char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
+{
+ char *retval;
+
+ write_seqlock(&rename_lock);
+ retval = __dentry_path(dentry, buf, buflen);
+ write_sequnlock(&rename_lock);
+
+ return retval;
+}
+EXPORT_SYMBOL(dentry_path_raw);
char *dentry_path(struct dentry *dentry, char *buf, int buflen)
{
char *p = NULL;
char *retval;
- spin_lock(&dcache_lock);
+ write_seqlock(&rename_lock);
if (d_unlinked(dentry)) {
p = buf + buflen;
if (prepend(&p, &buflen, "//deleted", 10) != 0)
@@ -2186,12 +2749,11 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
buflen++;
}
retval = __dentry_path(dentry, buf, buflen);
- spin_unlock(&dcache_lock);
+ write_sequnlock(&rename_lock);
if (!IS_ERR(retval) && p)
*p = '/'; /* restore '/' overriden with '\0' */
return retval;
Elong:
- spin_unlock(&dcache_lock);
return ERR_PTR(-ENAMETOOLONG);
}
@@ -2225,7 +2787,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
get_fs_root_and_pwd(current->fs, &root, &pwd);
error = -ENOENT;
- spin_lock(&dcache_lock);
+ write_seqlock(&rename_lock);
if (!d_unlinked(pwd.dentry)) {
unsigned long len;
struct path tmp = root;
@@ -2234,7 +2796,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
prepend(&cwd, &buflen, "\0", 1);
error = prepend_path(&pwd, &tmp, &cwd, &buflen);
- spin_unlock(&dcache_lock);
+ write_sequnlock(&rename_lock);
if (error)
goto out;
@@ -2253,8 +2815,9 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
if (copy_to_user(buf, cwd, len))
error = -EFAULT;
}
- } else
- spin_unlock(&dcache_lock);
+ } else {
+ write_sequnlock(&rename_lock);
+ }
out:
path_put(&pwd);
@@ -2282,25 +2845,25 @@ out:
int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
{
int result;
- unsigned long seq;
+ unsigned seq;
if (new_dentry == old_dentry)
return 1;
- /*
- * Need rcu_readlock to protect against the d_parent trashing
- * due to d_move
- */
- rcu_read_lock();
do {
/* for restarting inner loop in case of seq retry */
seq = read_seqbegin(&rename_lock);
+ /*
+ * Need rcu_readlock to protect against the d_parent trashing
+ * due to d_move
+ */
+ rcu_read_lock();
if (d_ancestor(old_dentry, new_dentry))
result = 1;
else
result = 0;
+ rcu_read_unlock();
} while (read_seqretry(&rename_lock, seq));
- rcu_read_unlock();
return result;
}
@@ -2332,10 +2895,15 @@ EXPORT_SYMBOL(path_is_under);
void d_genocide(struct dentry *root)
{
- struct dentry *this_parent = root;
+ struct dentry *this_parent;
struct list_head *next;
+ unsigned seq;
+ int locked = 0;
- spin_lock(&dcache_lock);
+ seq = read_seqbegin(&rename_lock);
+again:
+ this_parent = root;
+ spin_lock(&this_parent->d_lock);
repeat:
next = this_parent->d_subdirs.next;
resume:
@@ -2343,21 +2911,62 @@ resume:
struct list_head *tmp = next;
struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
next = tmp->next;
- if (d_unhashed(dentry)||!dentry->d_inode)
+
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+ if (d_unhashed(dentry) || !dentry->d_inode) {
+ spin_unlock(&dentry->d_lock);
continue;
+ }
if (!list_empty(&dentry->d_subdirs)) {
+ spin_unlock(&this_parent->d_lock);
+ spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
this_parent = dentry;
+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
goto repeat;
}
- atomic_dec(&dentry->d_count);
+ if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
+ dentry->d_flags |= DCACHE_GENOCIDE;
+ dentry->d_count--;
+ }
+ spin_unlock(&dentry->d_lock);
}
if (this_parent != root) {
- next = this_parent->d_u.d_child.next;
- atomic_dec(&this_parent->d_count);
- this_parent = this_parent->d_parent;
+ struct dentry *tmp;
+ struct dentry *child;
+
+ tmp = this_parent->d_parent;
+ if (!(this_parent->d_flags & DCACHE_GENOCIDE)) {
+ this_parent->d_flags |= DCACHE_GENOCIDE;
+ this_parent->d_count--;
+ }
+ rcu_read_lock();
+ spin_unlock(&this_parent->d_lock);
+ child = this_parent;
+ this_parent = tmp;
+ spin_lock(&this_parent->d_lock);
+ /* might go back up the wrong parent if we have had a rename
+ * or deletion */
+ if (this_parent != child->d_parent ||
+ (!locked && read_seqretry(&rename_lock, seq))) {
+ spin_unlock(&this_parent->d_lock);
+ rcu_read_unlock();
+ goto rename_retry;
+ }
+ rcu_read_unlock();
+ next = child->d_u.d_child.next;
goto resume;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&this_parent->d_lock);
+ if (!locked && read_seqretry(&rename_lock, seq))
+ goto rename_retry;
+ if (locked)
+ write_sequnlock(&rename_lock);
+ return;
+
+rename_retry:
+ locked = 1;
+ write_seqlock(&rename_lock);
+ goto again;
}
/**
@@ -2411,7 +3020,7 @@ static void __init dcache_init_early(void)
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
- sizeof(struct hlist_head),
+ sizeof(struct dcache_hash_bucket),
dhash_entries,
13,
HASH_EARLY,
@@ -2420,16 +3029,13 @@ static void __init dcache_init_early(void)
0);
for (loop = 0; loop < (1 << d_hash_shift); loop++)
- INIT_HLIST_HEAD(&dentry_hashtable[loop]);
+ INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head);
}
static void __init dcache_init(void)
{
int loop;
- percpu_counter_init(&nr_dentry, 0);
- percpu_counter_init(&nr_dentry_unused, 0);
-
/*
* A constructor could be added for stable state like the lists,
* but it is probably not worth it because of the cache nature
@@ -2446,7 +3052,7 @@ static void __init dcache_init(void)
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
- sizeof(struct hlist_head),
+ sizeof(struct dcache_hash_bucket),
dhash_entries,
13,
0,
@@ -2455,7 +3061,7 @@ static void __init dcache_init(void)
0);
for (loop = 0; loop < (1 << d_hash_shift); loop++)
- INIT_HLIST_HEAD(&dentry_hashtable[loop]);
+ INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head);
}
/* SLAB cache for __getname() consumers */
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 37a34c2c622a..9c64ae9e4c1a 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -63,6 +63,9 @@
#define NEEDED_RMEM (4*1024*1024)
#define CONN_HASH_SIZE 32
+/* Number of messages to send before rescheduling */
+#define MAX_SEND_MSG_COUNT 25
+
struct cbuf {
unsigned int base;
unsigned int len;
@@ -108,6 +111,7 @@ struct connection {
#define CF_INIT_PENDING 4
#define CF_IS_OTHERCON 5
#define CF_CLOSE 6
+#define CF_APP_LIMITED 7
struct list_head writequeue; /* List of outgoing writequeue_entries */
spinlock_t writequeue_lock;
int (*rx_action) (struct connection *); /* What to do when active */
@@ -295,7 +299,17 @@ static void lowcomms_write_space(struct sock *sk)
{
struct connection *con = sock2con(sk);
- if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags))
+ if (!con)
+ return;
+
+ clear_bit(SOCK_NOSPACE, &con->sock->flags);
+
+ if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) {
+ con->sock->sk->sk_write_pending--;
+ clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags);
+ }
+
+ if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
queue_work(send_workqueue, &con->swork);
}
@@ -915,6 +929,7 @@ static void tcp_connect_to_sock(struct connection *con)
struct sockaddr_storage saddr, src_addr;
int addr_len;
struct socket *sock = NULL;
+ int one = 1;
if (con->nodeid == 0) {
log_print("attempt to connect sock 0 foiled");
@@ -960,6 +975,11 @@ static void tcp_connect_to_sock(struct connection *con)
make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
log_print("connecting to %d", con->nodeid);
+
+ /* Turn off Nagle's algorithm */
+ kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one,
+ sizeof(one));
+
result =
sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len,
O_NONBLOCK);
@@ -1011,6 +1031,10 @@ static struct socket *tcp_create_listen_sock(struct connection *con,
goto create_out;
}
+ /* Turn off Nagle's algorithm */
+ kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one,
+ sizeof(one));
+
result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof(one));
@@ -1297,6 +1321,7 @@ static void send_to_sock(struct connection *con)
const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
struct writequeue_entry *e;
int len, offset;
+ int count = 0;
mutex_lock(&con->sock_mutex);
if (con->sock == NULL)
@@ -1319,14 +1344,27 @@ static void send_to_sock(struct connection *con)
ret = kernel_sendpage(con->sock, e->page, offset, len,
msg_flags);
if (ret == -EAGAIN || ret == 0) {
+ if (ret == -EAGAIN &&
+ test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) &&
+ !test_and_set_bit(CF_APP_LIMITED, &con->flags)) {
+ /* Notify TCP that we're limited by the
+ * application window size.
+ */
+ set_bit(SOCK_NOSPACE, &con->sock->flags);
+ con->sock->sk->sk_write_pending++;
+ }
cond_resched();
goto out;
}
if (ret <= 0)
goto send_error;
}
- /* Don't starve people filling buffers */
+
+ /* Don't starve people filling buffers */
+ if (++count >= MAX_SEND_MSG_COUNT) {
cond_resched();
+ count = 0;
+ }
spin_lock(&con->writequeue_lock);
e->offset += ret;
@@ -1430,20 +1468,19 @@ static void work_stop(void)
static int work_start(void)
{
- int error;
- recv_workqueue = create_workqueue("dlm_recv");
- error = IS_ERR(recv_workqueue);
- if (error) {
- log_print("can't start dlm_recv %d", error);
- return error;
+ recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM |
+ WQ_HIGHPRI | WQ_FREEZEABLE, 0);
+ if (!recv_workqueue) {
+ log_print("can't start dlm_recv");
+ return -ENOMEM;
}
- send_workqueue = create_singlethread_workqueue("dlm_send");
- error = IS_ERR(send_workqueue);
- if (error) {
- log_print("can't start dlm_send %d", error);
+ send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM |
+ WQ_HIGHPRI | WQ_FREEZEABLE, 0);
+ if (!send_workqueue) {
+ log_print("can't start dlm_send");
destroy_workqueue(recv_workqueue);
- return error;
+ return -ENOMEM;
}
return 0;
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index cbadc1bee6e7..bfd8b680e648 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -348,7 +348,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
BUG_ON(!crypt_stat || !crypt_stat->tfm
|| !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
+ ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
crypt_stat->key_size);
ecryptfs_dump_hex(crypt_stat->key,
crypt_stat->key_size);
@@ -413,10 +413,9 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
(extent_base + extent_offset));
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to "
- "derive IV for extent [0x%.16x]; "
- "rc = [%d]\n", (extent_base + extent_offset),
- rc);
+ ecryptfs_printk(KERN_ERR, "Error attempting to derive IV for "
+ "extent [0x%.16llx]; rc = [%d]\n",
+ (unsigned long long)(extent_base + extent_offset), rc);
goto out;
}
if (unlikely(ecryptfs_verbosity > 0)) {
@@ -443,9 +442,9 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
}
rc = 0;
if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
- "rc = [%d]\n", (extent_base + extent_offset),
- rc);
+ ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; "
+ "rc = [%d]\n",
+ (unsigned long long)(extent_base + extent_offset), rc);
ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
"encryption:\n");
ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
@@ -540,10 +539,9 @@ static int ecryptfs_decrypt_extent(struct page *page,
rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
(extent_base + extent_offset));
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to "
- "derive IV for extent [0x%.16x]; "
- "rc = [%d]\n", (extent_base + extent_offset),
- rc);
+ ecryptfs_printk(KERN_ERR, "Error attempting to derive IV for "
+ "extent [0x%.16llx]; rc = [%d]\n",
+ (unsigned long long)(extent_base + extent_offset), rc);
goto out;
}
if (unlikely(ecryptfs_verbosity > 0)) {
@@ -571,9 +569,9 @@ static int ecryptfs_decrypt_extent(struct page *page,
}
rc = 0;
if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
- "rc = [%d]\n", (extent_base + extent_offset),
- rc);
+ ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; "
+ "rc = [%d]\n",
+ (unsigned long long)(extent_base + extent_offset), rc);
ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
"decryption:\n");
ecryptfs_dump_hex((char *)(page_address(page)
@@ -780,7 +778,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
}
ecryptfs_printk(KERN_DEBUG,
"Initializing cipher [%s]; strlen = [%d]; "
- "key_size_bits = [%d]\n",
+ "key_size_bits = [%zd]\n",
crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
crypt_stat->key_size << 3);
if (crypt_stat->tfm) {
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index 906e803f7f79..f9a8be854f30 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -30,7 +30,7 @@
#include "ecryptfs_kernel.h"
/**
- * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
+ * ecryptfs_d_revalidate_rcu - revalidate an ecryptfs dentry
* @dentry: The ecryptfs dentry
* @nd: The associated nameidata
*
@@ -42,7 +42,7 @@
* Returns 1 if valid, 0 otherwise.
*
*/
-static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int ecryptfs_d_revalidate_rcu(struct dentry *dentry, struct nameidata *nd)
{
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
@@ -50,13 +50,18 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
struct vfsmount *vfsmount_save;
int rc = 1;
- if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
+ if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE_EITHER))
goto out;
+ if (nd->flags & LOOKUP_RCU)
+ return -ECHILD;
dentry_save = nd->path.dentry;
vfsmount_save = nd->path.mnt;
nd->path.dentry = lower_dentry;
nd->path.mnt = lower_mnt;
- rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
+ if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE)
+ rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
+ else
+ rc = lower_dentry->d_op->d_revalidate_rcu(lower_dentry, nd);
nd->path.dentry = dentry_save;
nd->path.mnt = vfsmount_save;
if (dentry->d_inode) {
@@ -91,6 +96,6 @@ static void ecryptfs_d_release(struct dentry *dentry)
}
const struct dentry_operations ecryptfs_dops = {
- .d_revalidate = ecryptfs_d_revalidate,
+ .d_revalidate_rcu = ecryptfs_d_revalidate_rcu,
.d_release = ecryptfs_d_release,
};
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 413a3c48f0bb..7d6faccbd6db 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -192,7 +192,6 @@ ecryptfs_get_key_payload_data(struct key *key)
(((struct user_key_payload*)key->payload.data)->data);
}
-#define ECRYPTFS_SUPER_MAGIC 0xf15f
#define ECRYPTFS_MAX_KEYSET_SIZE 1024
#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32
#define ECRYPTFS_MAX_NUM_ENC_KEYS 64
@@ -584,6 +583,7 @@ ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt)
#define ecryptfs_printk(type, fmt, arg...) \
__ecryptfs_printk(type "%s: " fmt, __func__, ## arg);
+__attribute__ ((format(printf, 1, 2)))
void __ecryptfs_printk(const char *fmt, ...);
extern const struct file_operations ecryptfs_main_fops;
@@ -760,8 +760,7 @@ int ecryptfs_init_kthread(void);
void ecryptfs_destroy_kthread(void);
int ecryptfs_privileged_open(struct file **lower_file,
struct dentry *lower_dentry,
- struct vfsmount *lower_mnt,
- const struct cred *cred);
+ struct vfsmount *lower_mnt);
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
int
ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 91da02987bff..81e10e6a9443 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -47,7 +47,7 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
- int rc;
+ ssize_t rc;
struct dentry *lower_dentry;
struct vfsmount *lower_vfsmount;
struct file *file = iocb->ki_filp;
@@ -191,18 +191,16 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
| ECRYPTFS_ENCRYPTED);
}
mutex_unlock(&crypt_stat->cs_mutex);
- if (!ecryptfs_inode_to_private(inode)->lower_file) {
- rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to initialize "
- "the persistent file for the dentry with name "
- "[%s]; rc = [%d]\n", __func__,
- ecryptfs_dentry->d_name.name, rc);
- goto out_free;
- }
+ rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to initialize "
+ "the persistent file for the dentry with name "
+ "[%s]; rc = [%d]\n", __func__,
+ ecryptfs_dentry->d_name.name, rc);
+ goto out_free;
}
- if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY)
- && !(file->f_flags & O_RDONLY)) {
+ if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE)
+ == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) {
rc = -EPERM;
printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
"file must hence be opened RO\n", __func__);
@@ -243,9 +241,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
}
}
mutex_unlock(&crypt_stat->cs_mutex);
- ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] "
- "size: [0x%.16x]\n", inode, inode->i_ino,
- i_size_read(inode));
+ ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = "
+ "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino,
+ (unsigned long long)i_size_read(inode));
goto out;
out_free:
kmem_cache_free(ecryptfs_file_info_cache,
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 9d1a22d62765..aeb242de74f2 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -185,15 +185,13 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
"context; rc = [%d]\n", rc);
goto out;
}
- if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) {
- rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to initialize "
- "the persistent file for the dentry with name "
- "[%s]; rc = [%d]\n", __func__,
- ecryptfs_dentry->d_name.name, rc);
- goto out;
- }
+ rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to initialize "
+ "the persistent file for the dentry with name "
+ "[%s]; rc = [%d]\n", __func__,
+ ecryptfs_dentry->d_name.name, rc);
+ goto out;
}
rc = ecryptfs_write_metadata(ecryptfs_dentry);
if (rc) {
@@ -260,7 +258,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
ecryptfs_dentry->d_parent));
lower_inode = lower_dentry->d_inode;
fsstack_copy_attr_atime(ecryptfs_dir_inode, lower_dir_dentry->d_inode);
- BUG_ON(!atomic_read(&lower_dentry->d_count));
+ BUG_ON(!lower_dentry->d_count);
ecryptfs_set_dentry_private(ecryptfs_dentry,
kmem_cache_alloc(ecryptfs_dentry_info_cache,
GFP_KERNEL));
@@ -302,15 +300,13 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
rc = -ENOMEM;
goto out;
}
- if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) {
- rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to initialize "
- "the persistent file for the dentry with name "
- "[%s]; rc = [%d]\n", __func__,
- ecryptfs_dentry->d_name.name, rc);
- goto out_free_kmem;
- }
+ rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to initialize "
+ "the persistent file for the dentry with name "
+ "[%s]; rc = [%d]\n", __func__,
+ ecryptfs_dentry->d_name.name, rc);
+ goto out_free_kmem;
}
crypt_stat = &ecryptfs_inode_to_private(
ecryptfs_dentry->d_inode)->crypt_stat;
@@ -441,7 +437,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
struct qstr lower_name;
int rc = 0;
- ecryptfs_dentry->d_op = &ecryptfs_dops;
+ d_set_d_op(ecryptfs_dentry, &ecryptfs_dops);
if ((ecryptfs_dentry->d_name.len == 1
&& !strcmp(ecryptfs_dentry->d_name.name, "."))
|| (ecryptfs_dentry->d_name.len == 2
@@ -454,7 +450,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
lower_name.hash = ecryptfs_dentry->d_name.hash;
if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) {
rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry,
- &lower_name);
+ lower_dir_dentry->d_inode, &lower_name);
if (rc < 0)
goto out_d_drop;
}
@@ -489,7 +485,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
lower_name.hash = full_name_hash(lower_name.name, lower_name.len);
if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) {
rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry,
- &lower_name);
+ lower_dir_dentry->d_inode, &lower_name);
if (rc < 0)
goto out_d_drop;
}
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index b1f6858a5223..c1436cff6f2d 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -59,7 +59,7 @@ static int process_request_key_err(long err_code)
break;
default:
ecryptfs_printk(KERN_WARNING, "Unknown error code: "
- "[0x%.16x]\n", err_code);
+ "[0x%.16lx]\n", err_code);
rc = -EINVAL;
}
return rc;
@@ -130,7 +130,7 @@ int ecryptfs_write_packet_length(char *dest, size_t size,
} else {
rc = -EINVAL;
ecryptfs_printk(KERN_WARNING,
- "Unsupported packet size: [%d]\n", size);
+ "Unsupported packet size: [%zd]\n", size);
}
return rc;
}
@@ -1672,7 +1672,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
auth_tok->session_key.decrypted_key_size);
crypt_stat->flags |= ECRYPTFS_KEY_VALID;
if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "FEK of size [%d]:\n",
+ ecryptfs_printk(KERN_DEBUG, "FEK of size [%zd]:\n",
crypt_stat->key_size);
ecryptfs_dump_hex(crypt_stat->key,
crypt_stat->key_size);
@@ -1754,7 +1754,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) {
ecryptfs_printk(KERN_ERR, "Expected "
"signature of size [%d]; "
- "read size [%d]\n",
+ "read size [%zd]\n",
ECRYPTFS_SIG_SIZE,
tag_11_contents_size);
rc = -EIO;
@@ -1787,8 +1787,8 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
goto out_wipe_list;
break;
default:
- ecryptfs_printk(KERN_DEBUG, "No packet at offset "
- "[%d] of the file header; hex value of "
+ ecryptfs_printk(KERN_DEBUG, "No packet at offset [%zd] "
+ "of the file header; hex value of "
"character is [0x%.2x]\n", i, src[i]);
next_packet_is_auth_tok_packet = 0;
}
@@ -1864,8 +1864,8 @@ found_matching_auth_tok:
"session key for authentication token with sig "
"[%.*s]; rc = [%d]. Removing auth tok "
"candidate from the list and searching for "
- "the next match.\n", candidate_auth_tok_sig,
- ECRYPTFS_SIG_SIZE_HEX, rc);
+ "the next match.\n", ECRYPTFS_SIG_SIZE_HEX,
+ candidate_auth_tok_sig, rc);
list_for_each_entry_safe(auth_tok_list_item,
auth_tok_list_item_tmp,
&auth_tok_list, list) {
@@ -2168,7 +2168,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
if (encrypted_session_key_valid) {
ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; "
"using auth_tok->session_key.encrypted_key, "
- "where key_rec->enc_key_size = [%d]\n",
+ "where key_rec->enc_key_size = [%zd]\n",
key_rec->enc_key_size);
memcpy(key_rec->enc_key,
auth_tok->session_key.encrypted_key,
@@ -2198,7 +2198,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
if (rc < 1 || rc > 2) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
"for crypt_stat session key; expected rc = 1; "
- "got rc = [%d]. key_rec->enc_key_size = [%d]\n",
+ "got rc = [%d]. key_rec->enc_key_size = [%zd]\n",
rc, key_rec->enc_key_size);
rc = -ENOMEM;
goto out;
@@ -2209,7 +2209,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
"for crypt_stat encrypted session key; "
"expected rc = 1; got rc = [%d]. "
- "key_rec->enc_key_size = [%d]\n", rc,
+ "key_rec->enc_key_size = [%zd]\n", rc,
key_rec->enc_key_size);
rc = -ENOMEM;
goto out;
@@ -2224,7 +2224,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
goto out;
}
rc = 0;
- ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
+ ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n",
crypt_stat->key_size);
rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg,
(*key_rec).enc_key_size);
@@ -2235,7 +2235,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
}
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
if (ecryptfs_verbosity > 0) {
- ecryptfs_printk(KERN_DEBUG, "EFEK of size [%d]:\n",
+ ecryptfs_printk(KERN_DEBUG, "EFEK of size [%zd]:\n",
key_rec->enc_key_size);
ecryptfs_dump_hex(key_rec->enc_key,
key_rec->enc_key_size);
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index 0851ab6980f5..c84a57be98ce 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -38,6 +38,7 @@ static struct ecryptfs_kthread_ctl {
} ecryptfs_kthread_ctl;
static struct task_struct *ecryptfs_kthread;
+static struct cred *ecryptfs_kthread_cred;
/**
* ecryptfs_threadfn
@@ -74,7 +75,8 @@ static int ecryptfs_threadfn(void *ignored)
mntget(req->lower_mnt);
(*req->lower_file) = dentry_open(
req->lower_dentry, req->lower_mnt,
- (O_RDWR | O_LARGEFILE), current_cred());
+ (O_RDWR | O_LARGEFILE),
+ ecryptfs_kthread_cred);
req->flags |= ECRYPTFS_REQ_PROCESSED;
}
wake_up(&req->wait);
@@ -99,7 +101,15 @@ int __init ecryptfs_init_kthread(void)
rc = PTR_ERR(ecryptfs_kthread);
printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]"
"\n", __func__, rc);
+ goto out;
+ }
+ ecryptfs_kthread_cred = prepare_kernel_cred(ecryptfs_kthread);
+ if (IS_ERR(ecryptfs_kthread_cred)) {
+ rc = PTR_ERR(ecryptfs_kthread_cred);
+ printk(KERN_ERR "%s: Failed to obtain the credential struct; "
+ "rc = [%d]\n", __func__, rc);
}
+out:
return rc;
}
@@ -119,6 +129,7 @@ void ecryptfs_destroy_kthread(void)
mutex_unlock(&ecryptfs_kthread_ctl.mux);
kthread_stop(ecryptfs_kthread);
wake_up(&ecryptfs_kthread_ctl.wait);
+ put_cred(ecryptfs_kthread_cred);
}
/**
@@ -133,8 +144,7 @@ void ecryptfs_destroy_kthread(void)
*/
int ecryptfs_privileged_open(struct file **lower_file,
struct dentry *lower_dentry,
- struct vfsmount *lower_mnt,
- const struct cred *cred)
+ struct vfsmount *lower_mnt)
{
struct ecryptfs_open_req *req;
int flags = O_LARGEFILE;
@@ -146,7 +156,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
dget(lower_dentry);
mntget(lower_mnt);
flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
- (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
+ (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags,
+ ecryptfs_kthread_cred);
if (!IS_ERR(*lower_file))
goto out;
if (flags & O_RDONLY) {
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index a9dbd62518e6..84c6a0ddadf1 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -36,6 +36,7 @@
#include <linux/parser.h>
#include <linux/fs_stack.h>
#include <linux/slab.h>
+#include <linux/magic.h>
#include "ecryptfs_kernel.h"
/**
@@ -116,7 +117,6 @@ void __ecryptfs_printk(const char *fmt, ...)
*/
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
{
- const struct cred *cred = current_cred();
struct ecryptfs_inode_info *inode_info =
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
int rc = 0;
@@ -129,7 +129,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
rc = ecryptfs_privileged_open(&inode_info->lower_file,
- lower_dentry, lower_mnt, cred);
+ lower_dentry, lower_mnt);
if (rc) {
printk(KERN_ERR "Error opening lower persistent file "
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "
@@ -189,7 +189,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
if (special_file(lower_inode->i_mode))
init_special_inode(inode, lower_inode->i_mode,
lower_inode->i_rdev);
- dentry->d_op = &ecryptfs_dops;
+ d_set_d_op(dentry, &ecryptfs_dops);
fsstack_copy_attr_all(inode, lower_inode);
/* This size will be overwritten for real files w/ headers and
* other metadata */
@@ -520,6 +520,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
ecryptfs_set_superblock_lower(sb, path.dentry->d_sb);
sb->s_maxbytes = path.dentry->d_sb->s_maxbytes;
sb->s_blocksize = path.dentry->d_sb->s_blocksize;
+ sb->s_magic = ECRYPTFS_SUPER_MAGIC;
ecryptfs_set_dentry_lower(sb->s_root, path.dentry);
ecryptfs_set_dentry_lower_mnt(sb->s_root, path.mnt);
rc = ecryptfs_interpose(path.dentry, sb->s_root, sb, 0);
@@ -594,7 +595,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
deactivate_locked_super(s);
goto out;
}
- s->s_root->d_op = &ecryptfs_dops;
+ d_set_d_op(s->s_root, &ecryptfs_dops);
s->s_root->d_sb = s;
s->s_root->d_parent = s->s_root;
@@ -828,9 +829,10 @@ static int __init ecryptfs_init(void)
ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is "
"larger than the host's page size, and so "
"eCryptfs cannot run on this system. The "
- "default eCryptfs extent size is [%d] bytes; "
- "the page size is [%d] bytes.\n",
- ECRYPTFS_DEFAULT_EXTENT_SIZE, PAGE_CACHE_SIZE);
+ "default eCryptfs extent size is [%u] bytes; "
+ "the page size is [%lu] bytes.\n",
+ ECRYPTFS_DEFAULT_EXTENT_SIZE,
+ (unsigned long)PAGE_CACHE_SIZE);
goto out;
}
rc = ecryptfs_init_kmem_caches();
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index b1d82756544b..cc64fca89f8d 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -65,7 +65,7 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting "
- "page (upper index [0x%.16x])\n", page->index);
+ "page (upper index [0x%.16lx])\n", page->index);
ClearPageUptodate(page);
goto out;
}
@@ -237,7 +237,7 @@ out:
ClearPageUptodate(page);
else
SetPageUptodate(page);
- ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
+ ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16lx]\n",
page->index);
unlock_page(page);
return rc;
@@ -290,6 +290,7 @@ static int ecryptfs_write_begin(struct file *file,
return -ENOMEM;
*pagep = page;
+ prev_page_end_size = ((loff_t)index << PAGE_CACHE_SHIFT);
if (!PageUptodate(page)) {
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(mapping->host)->crypt_stat;
@@ -335,18 +336,23 @@ static int ecryptfs_write_begin(struct file *file,
SetPageUptodate(page);
}
} else {
- rc = ecryptfs_decrypt_page(page);
- if (rc) {
- printk(KERN_ERR "%s: Error decrypting page "
- "at index [%ld]; rc = [%d]\n",
- __func__, page->index, rc);
- ClearPageUptodate(page);
- goto out;
+ if (prev_page_end_size
+ >= i_size_read(page->mapping->host)) {
+ zero_user(page, 0, PAGE_CACHE_SIZE);
+ } else {
+ rc = ecryptfs_decrypt_page(page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error decrypting "
+ "page at index [%ld]; "
+ "rc = [%d]\n",
+ __func__, page->index, rc);
+ ClearPageUptodate(page);
+ goto out;
+ }
}
SetPageUptodate(page);
}
}
- prev_page_end_size = ((loff_t)index << PAGE_CACHE_SHIFT);
/* If creating a page or more of holes, zero them out via truncate.
* Note, this will increase i_size. */
if (index != 0) {
@@ -488,7 +494,7 @@ static int ecryptfs_write_end(struct file *file,
} else
ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
- "(page w/ index = [0x%.16x], to = [%d])\n", index, to);
+ "(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, page, 0,
to);
@@ -503,19 +509,20 @@ static int ecryptfs_write_end(struct file *file,
rc = fill_zeros_to_end_of_page(page, to);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
- "zeros in page with index = [0x%.16x]\n", index);
+ "zeros in page with index = [0x%.16lx]\n", index);
goto out;
}
rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
- "index [0x%.16x])\n", index);
+ "index [0x%.16lx])\n", index);
goto out;
}
if (pos + copied > i_size_read(ecryptfs_inode)) {
i_size_write(ecryptfs_inode, pos + copied);
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
- "[0x%.16x]\n", i_size_read(ecryptfs_inode));
+ "[0x%.16llx]\n",
+ (unsigned long long)i_size_read(ecryptfs_inode));
}
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
if (rc)
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 2720178b7718..3042fe123a34 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -62,6 +62,16 @@ out:
return inode;
}
+static void ecryptfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct ecryptfs_inode_info *inode_info;
+ inode_info = ecryptfs_inode_to_private(inode);
+
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
+}
+
/**
* ecryptfs_destroy_inode
* @inode: The ecryptfs inode
@@ -88,7 +98,7 @@ static void ecryptfs_destroy_inode(struct inode *inode)
}
}
ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
- kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
+ call_rcu(&inode->i_rcu, ecryptfs_i_callback);
}
/**
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 5073a07652cc..0f31acb0131c 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -65,11 +65,18 @@ static struct inode *efs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void efs_destroy_inode(struct inode *inode)
+static void efs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(efs_inode_cachep, INODE_INFO(inode));
}
+static void efs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, efs_i_callback);
+}
+
static void init_once(void *foo)
{
struct efs_inode_info *ei = (struct efs_inode_info *) foo;
diff --git a/fs/exec.c b/fs/exec.c
index 99d33a1371e9..c62efcb959c7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -164,7 +164,26 @@ out:
#ifdef CONFIG_MMU
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+ struct mm_struct *mm = current->mm;
+ long diff = (long)(pages - bprm->vma_pages);
+
+ if (!mm || !diff)
+ return;
+
+ bprm->vma_pages = pages;
+
+#ifdef SPLIT_RSS_COUNTING
+ add_mm_counter(mm, MM_ANONPAGES, diff);
+#else
+ spin_lock(&mm->page_table_lock);
+ add_mm_counter(mm, MM_ANONPAGES, diff);
+ spin_unlock(&mm->page_table_lock);
+#endif
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
struct page *page;
@@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
struct rlimit *rlim;
+ acct_arg_size(bprm, size / PAGE_SIZE);
+
/*
* We've historically supported up to 32 pages (ARG_MAX)
* of argument strings even with small stacks
@@ -254,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+ err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+ if (err)
+ goto err;
+
err = insert_vm_struct(mm, vma);
if (err)
goto err;
@@ -276,7 +302,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
#else
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
struct page *page;
@@ -1003,6 +1033,7 @@ int flush_old_exec(struct linux_binprm * bprm)
/*
* Release all of the old mmap stuff
*/
+ acct_arg_size(bprm, 0);
retval = exec_mmap(bprm->mm);
if (retval)
goto out;
@@ -1426,8 +1457,10 @@ int do_execve(const char * filename,
return retval;
out:
- if (bprm->mm)
- mmput (bprm->mm);
+ if (bprm->mm) {
+ acct_arg_size(bprm, 0);
+ mmput(bprm->mm);
+ }
out_file:
if (bprm->file) {
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 79c3ae6e0456..8c6c4669b381 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -150,12 +150,19 @@ static struct inode *exofs_alloc_inode(struct super_block *sb)
return &oi->vfs_inode;
}
+static void exofs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
+}
+
/*
* Remove an inode from the cache
*/
static void exofs_destroy_inode(struct inode *inode)
{
- kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
+ call_rcu(&inode->i_rcu, exofs_i_callback);
}
/*
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 51b304056f10..4b6825740dd5 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -43,24 +43,26 @@ find_acceptable_alias(struct dentry *result,
void *context)
{
struct dentry *dentry, *toput = NULL;
+ struct inode *inode;
if (acceptable(context, result))
return result;
- spin_lock(&dcache_lock);
- list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
- dget_locked(dentry);
- spin_unlock(&dcache_lock);
+ inode = result->d_inode;
+ spin_lock(&inode->i_lock);
+ list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+ dget(dentry);
+ spin_unlock(&inode->i_lock);
if (toput)
dput(toput);
if (dentry != result && acceptable(context, dentry)) {
dput(result);
return dentry;
}
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
toput = dentry;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
if (toput)
dput(toput);
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 2bcc0431bada..43196d7a31c0 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -232,10 +232,17 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
int
-ext2_check_acl(struct inode *inode, int mask)
+ext2_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
{
- struct posix_acl *acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
+ struct posix_acl *acl;
+
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ return -EAGAIN;
+ }
+ acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl) {
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index 3ff6cbb9ac44..fb493933c60d 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -54,15 +54,15 @@ static inline int ext2_acl_count(size_t size)
#ifdef CONFIG_EXT2_FS_POSIX_ACL
/* acl.c */
-extern int ext2_check_acl (struct inode *, int);
+extern int ext2_check_acl_rcu(struct inode *, int, unsigned int);
extern int ext2_acl_chmod (struct inode *);
extern int ext2_init_acl (struct inode *, struct inode *);
#else
#include <linux/sched.h>
-#define ext2_check_acl NULL
-#define ext2_get_acl NULL
-#define ext2_set_acl NULL
+#define ext2_check_acl_rcu NULL
+#define ext2_get_acl NULL
+#define ext2_set_acl NULL
static inline int
ext2_acl_chmod (struct inode *inode)
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 49eec9456c5b..a34fc5ade9b1 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -102,6 +102,6 @@ const struct inode_operations ext2_file_inode_operations = {
.removexattr = generic_removexattr,
#endif
.setattr = ext2_setattr,
- .check_acl = ext2_check_acl,
+ .check_acl_rcu = ext2_check_acl_rcu,
.fiemap = ext2_fiemap,
};
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index f8aecd2e3297..5366e02484ce 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -417,7 +417,7 @@ const struct inode_operations ext2_dir_inode_operations = {
.removexattr = generic_removexattr,
#endif
.setattr = ext2_setattr,
- .check_acl = ext2_check_acl,
+ .check_acl_rcu = ext2_check_acl_rcu,
};
const struct inode_operations ext2_special_inode_operations = {
@@ -428,5 +428,5 @@ const struct inode_operations ext2_special_inode_operations = {
.removexattr = generic_removexattr,
#endif
.setattr = ext2_setattr,
- .check_acl = ext2_check_acl,
+ .check_acl_rcu = ext2_check_acl_rcu,
};
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index d89e0b6a2d78..e0c6380ff992 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -161,11 +161,18 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void ext2_destroy_inode(struct inode *inode)
+static void ext2_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(ext2_inode_cachep, EXT2_I(inode));
}
+static void ext2_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, ext2_i_callback);
+}
+
static void init_once(void *foo)
{
struct ext2_inode_info *ei = (struct ext2_inode_info *) foo;
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index f84700be3274..c2e4dce984d2 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -199,14 +199,6 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_get",
goto found;
entry = next;
}
- /* Check the remaining name entries */
- while (!IS_LAST_ENTRY(entry)) {
- struct ext2_xattr_entry *next =
- EXT2_XATTR_NEXT(entry);
- if ((char *)next >= end)
- goto bad_block;
- entry = next;
- }
if (ext2_xattr_cache_insert(bh))
ea_idebug(inode, "cache insert failed");
error = -ENODATA;
@@ -355,7 +347,7 @@ static void ext2_xattr_update_super_block(struct super_block *sb)
/*
* ext2_xattr_set()
*
- * Create, replace or remove an extended attribute for this inode. Buffer
+ * Create, replace or remove an extended attribute for this inode. Value
* is NULL to remove an existing extended attribute, and non-NULL to
* either replace an existing extended attribute, or create a new extended
* attribute. The flags XATTR_REPLACE and XATTR_CREATE
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 8a11fe212183..cff7c134342f 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -240,10 +240,17 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
}
int
-ext3_check_acl(struct inode *inode, int mask)
+ext3_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
{
- struct posix_acl *acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
+ struct posix_acl *acl;
+
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ return -EAGAIN;
+ }
+ acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl) {
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 597334626de9..f2536e6129c5 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -54,13 +54,13 @@ static inline int ext3_acl_count(size_t size)
#ifdef CONFIG_EXT3_FS_POSIX_ACL
/* acl.c */
-extern int ext3_check_acl (struct inode *, int);
-extern int ext3_acl_chmod (struct inode *);
-extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
+extern int ext3_check_acl_rcu(struct inode *, int, unsigned int);
+extern int ext3_acl_chmod(struct inode *);
+extern int ext3_init_acl(handle_t *, struct inode *, struct inode *);
#else /* CONFIG_EXT3_FS_POSIX_ACL */
#include <linux/sched.h>
-#define ext3_check_acl NULL
+#define ext3_check_acl_rcu NULL
static inline int
ext3_acl_chmod(struct inode *inode)
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index f55df0e61cbd..74e5ef7b70dd 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -79,7 +79,7 @@ const struct inode_operations ext3_file_inode_operations = {
.listxattr = ext3_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext3_check_acl,
+ .check_acl_rcu = ext3_check_acl_rcu,
.fiemap = ext3_fiemap,
};
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index bce9dce639b8..9b1043846ced 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2464,7 +2464,7 @@ const struct inode_operations ext3_dir_inode_operations = {
.listxattr = ext3_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext3_check_acl,
+ .check_acl_rcu = ext3_check_acl_rcu,
};
const struct inode_operations ext3_special_inode_operations = {
@@ -2475,5 +2475,5 @@ const struct inode_operations ext3_special_inode_operations = {
.listxattr = ext3_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext3_check_acl,
+ .check_acl_rcu = ext3_check_acl_rcu,
};
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index acf8695fa8f0..2e52d9d04889 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -346,7 +346,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
struct block_device *bdev;
char b[BDEVNAME_SIZE];
- bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+ bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
if (IS_ERR(bdev))
goto fail;
return bdev;
@@ -363,8 +363,7 @@ fail:
*/
static int ext3_blkdev_put(struct block_device *bdev)
{
- bd_release(bdev);
- return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
+ return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
@@ -479,6 +478,13 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
+static void ext3_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
+}
+
static void ext3_destroy_inode(struct inode *inode)
{
if (!list_empty(&(EXT3_I(inode)->i_orphan))) {
@@ -489,7 +495,7 @@ static void ext3_destroy_inode(struct inode *inode)
false);
dump_stack();
}
- kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
+ call_rcu(&inode->i_rcu, ext3_i_callback);
}
static void init_once(void *foo)
@@ -2135,13 +2141,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
if (bdev == NULL)
return NULL;
- if (bd_claim(bdev, sb)) {
- ext3_msg(sb, KERN_ERR,
- "error: failed to claim external journal device");
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
- return NULL;
- }
-
blocksize = sb->s_blocksize;
hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) {
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index e69dc6dfaa89..32e6cc23bd9a 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -925,7 +925,7 @@ ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
/*
* ext3_xattr_set_handle()
*
- * Create, replace or remove an extended attribute for this inode. Buffer
+ * Create, replace or remove an extended attribute for this inode. Value
* is NULL to remove an existing extended attribute, and non-NULL to
* either replace an existing extended attribute, or create a new extended
* attribute. The flags XATTR_REPLACE and XATTR_CREATE
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 5e2ed4504ead..ebc7127e8c9b 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -238,10 +238,17 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
}
int
-ext4_check_acl(struct inode *inode, int mask)
+ext4_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
{
- struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+ struct posix_acl *acl;
+
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ return -EAGAIN;
+ }
+ acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl) {
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 9d843d5deac4..71e8da73d0cf 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -54,13 +54,13 @@ static inline int ext4_acl_count(size_t size)
#ifdef CONFIG_EXT4_FS_POSIX_ACL
/* acl.c */
-extern int ext4_check_acl(struct inode *, int);
+extern int ext4_check_acl_rcu(struct inode *, int, unsigned int);
extern int ext4_acl_chmod(struct inode *);
extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
#else /* CONFIG_EXT4_FS_POSIX_ACL */
#include <linux/sched.h>
-#define ext4_check_acl NULL
+#define ext4_check_acl_rcu NULL
static inline int
ext4_acl_chmod(struct inode *inode)
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index ece76fb6a40c..751fb8319edc 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -60,9 +60,13 @@ static unsigned char get_dtype(struct super_block *sb, int filetype)
return (ext4_filetype_table[filetype]);
}
-
+/*
+ * Return 0 if the directory entry is OK, and 1 if there is a problem
+ *
+ * Note: this is the opposite of what ext2 and ext3 historically returned...
+ */
int __ext4_check_dir_entry(const char *function, unsigned int line,
- struct inode *dir,
+ struct inode *dir, struct file *filp,
struct ext4_dir_entry_2 *de,
struct buffer_head *bh,
unsigned int offset)
@@ -71,26 +75,37 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
const int rlen = ext4_rec_len_from_disk(de->rec_len,
dir->i_sb->s_blocksize);
- if (rlen < EXT4_DIR_REC_LEN(1))
+ if (unlikely(rlen < EXT4_DIR_REC_LEN(1)))
error_msg = "rec_len is smaller than minimal";
- else if (rlen % 4 != 0)
+ else if (unlikely(rlen % 4 != 0))
error_msg = "rec_len % 4 != 0";
- else if (rlen < EXT4_DIR_REC_LEN(de->name_len))
+ else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
error_msg = "rec_len is too small for name_len";
- else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+ else if (unlikely(((char *) de - bh->b_data) + rlen >
+ dir->i_sb->s_blocksize))
error_msg = "directory entry across blocks";
- else if (le32_to_cpu(de->inode) >
- le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))
+ else if (unlikely(le32_to_cpu(de->inode) >
+ le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
error_msg = "inode out of bounds";
+ else
+ return 0;
- if (error_msg != NULL)
+ if (filp)
+ ext4_error_file(filp, function, line, bh->b_blocknr,
+ "bad entry in directory: %s - offset=%u(%u), "
+ "inode=%u, rec_len=%d, name_len=%d",
+ error_msg, (unsigned) (offset%bh->b_size),
+ offset, le32_to_cpu(de->inode),
+ rlen, de->name_len);
+ else
ext4_error_inode(dir, function, line, bh->b_blocknr,
- "bad entry in directory: %s - "
- "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
- error_msg, (unsigned) (offset%bh->b_size), offset,
- le32_to_cpu(de->inode),
- rlen, de->name_len);
- return error_msg == NULL ? 1 : 0;
+ "bad entry in directory: %s - offset=%u(%u), "
+ "inode=%u, rec_len=%d, name_len=%d",
+ error_msg, (unsigned) (offset%bh->b_size),
+ offset, le32_to_cpu(de->inode),
+ rlen, de->name_len);
+
+ return 1;
}
static int ext4_readdir(struct file *filp,
@@ -152,8 +167,9 @@ static int ext4_readdir(struct file *filp,
*/
if (!bh) {
if (!dir_has_error) {
- EXT4_ERROR_INODE(inode, "directory "
- "contains a hole at offset %Lu",
+ EXT4_ERROR_FILE(filp, bh->b_blocknr,
+ "directory contains a "
+ "hole at offset %Lu",
(unsigned long long) filp->f_pos);
dir_has_error = 1;
}
@@ -194,8 +210,8 @@ revalidate:
while (!error && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
- if (!ext4_check_dir_entry(inode, de,
- bh, offset)) {
+ if (ext4_check_dir_entry(inode, filp, de,
+ bh, offset)) {
/*
* On error, skip the f_pos to the next block
*/
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6a5edea2d70b..2a739255ee05 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -62,8 +62,8 @@
#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \
ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a)
-#define EXT4_ERROR_FILE(file, fmt, a...) \
- ext4_error_file(__func__, __LINE__, (file), (fmt), ## a)
+#define EXT4_ERROR_FILE(file, block, fmt, a...) \
+ ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
/* data type for block offset of block group */
typedef int ext4_grpblk_t;
@@ -561,22 +561,6 @@ struct ext4_new_group_data {
#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
#endif
-
-/*
- * Mount options
- */
-struct ext4_mount_options {
- unsigned long s_mount_opt;
- uid_t s_resuid;
- gid_t s_resgid;
- unsigned long s_commit_interval;
- u32 s_min_batch_time, s_max_batch_time;
-#ifdef CONFIG_QUOTA
- int s_jquota_fmt;
- char *s_qf_names[MAXQUOTAS];
-#endif
-};
-
/* Max physical block we can addres w/o extents */
#define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF
@@ -709,6 +693,8 @@ do { \
if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \
ext4_decode_extra_time(&(inode)->xtime, \
raw_inode->xtime ## _extra); \
+ else \
+ (inode)->xtime.tv_nsec = 0; \
} while (0)
#define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode) \
@@ -719,6 +705,8 @@ do { \
if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
ext4_decode_extra_time(&(einode)->xtime, \
raw_inode->xtime ## _extra); \
+ else \
+ (einode)->xtime.tv_nsec = 0; \
} while (0)
#define i_disk_version osd1.linux1.l_i_version
@@ -910,17 +898,27 @@ struct ext4_inode_info {
#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 */
+#define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */
#define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
#define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
#define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
#define EXT4_MOUNT_DISCARD 0x40000000 /* Issue DISCARD requests */
#define EXT4_MOUNT_INIT_INODE_TABLE 0x80000000 /* Initialize uninitialized itables */
-#define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt
-#define set_opt(o, opt) o |= EXT4_MOUNT_##opt
+#define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &= \
+ ~EXT4_MOUNT_##opt
+#define set_opt(sb, opt) EXT4_SB(sb)->s_mount_opt |= \
+ EXT4_MOUNT_##opt
#define test_opt(sb, opt) (EXT4_SB(sb)->s_mount_opt & \
EXT4_MOUNT_##opt)
+#define clear_opt2(sb, opt) EXT4_SB(sb)->s_mount_opt2 &= \
+ ~EXT4_MOUNT2_##opt
+#define set_opt2(sb, opt) EXT4_SB(sb)->s_mount_opt2 |= \
+ EXT4_MOUNT2_##opt
+#define test_opt2(sb, opt) (EXT4_SB(sb)->s_mount_opt2 & \
+ EXT4_MOUNT2_##opt)
+
#define ext4_set_bit ext2_set_bit
#define ext4_set_bit_atomic ext2_set_bit_atomic
#define ext4_clear_bit ext2_clear_bit
@@ -1086,6 +1084,7 @@ struct ext4_sb_info {
struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
struct buffer_head **s_group_desc;
unsigned int s_mount_opt;
+ unsigned int s_mount_opt2;
unsigned int s_mount_flags;
ext4_fsblk_t s_sb_block;
uid_t s_resuid;
@@ -1641,10 +1640,12 @@ extern unsigned ext4_init_block_bitmap(struct super_block *sb,
/* dir.c */
extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
+ struct file *,
struct ext4_dir_entry_2 *,
struct buffer_head *, unsigned int);
-#define ext4_check_dir_entry(dir, de, bh, offset) \
- __ext4_check_dir_entry(__func__, __LINE__, (dir), (de), (bh), (offset))
+#define ext4_check_dir_entry(dir, filp, de, bh, offset) \
+ unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \
+ (de), (bh), (offset)))
extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
__u32 minor_hash,
struct ext4_dir_entry_2 *dirent);
@@ -1751,8 +1752,8 @@ extern void ext4_error_inode(struct inode *, const char *, unsigned int,
ext4_fsblk_t, const char *, ...)
__attribute__ ((format (printf, 5, 6)));
extern void ext4_error_file(struct file *, const char *, unsigned int,
- const char *, ...)
- __attribute__ ((format (printf, 4, 5)));
+ ext4_fsblk_t, const char *, ...)
+ __attribute__ ((format (printf, 5, 6)));
extern void __ext4_std_error(struct super_block *, const char *,
unsigned int, int);
extern void __ext4_abort(struct super_block *, const char *, unsigned int,
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 5a5c55ddceef..f6be0af7c0a0 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -200,7 +200,7 @@ const struct inode_operations ext4_file_inode_operations = {
.listxattr = ext4_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext4_check_acl,
+ .check_acl_rcu = ext4_check_acl_rcu,
.fallocate = ext4_fallocate,
.fiemap = ext4_fiemap,
};
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index bdbe69902207..c0fe426d444a 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -40,6 +40,7 @@
#include <linux/workqueue.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/ratelimit.h>
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -552,7 +553,7 @@ static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
}
/**
- * ext4_blks_to_allocate: Look up the block map and count the number
+ * ext4_blks_to_allocate - Look up the block map and count the number
* of direct blocks need to be allocated for the given branch.
*
* @branch: chain of indirect blocks
@@ -591,13 +592,19 @@ static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned int blks,
/**
* ext4_alloc_blocks: multiple allocate blocks needed for a branch
+ * @handle: handle for this transaction
+ * @inode: inode which needs allocated blocks
+ * @iblock: the logical block to start allocated at
+ * @goal: preferred physical block of allocation
* @indirect_blks: the number of blocks need to allocate for indirect
* blocks
- *
+ * @blks: number of desired blocks
* @new_blocks: on return it will store the new block numbers for
* the indirect blocks(if needed) and the first direct block,
- * @blks: on return it will store the total number of allocated
- * direct blocks
+ * @err: on return it will store the error code
+ *
+ * This function will return the number of blocks allocated as
+ * requested by the passed-in parameters.
*/
static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, ext4_fsblk_t goal,
@@ -711,9 +718,11 @@ failed_out:
/**
* ext4_alloc_branch - allocate and set up a chain of blocks.
+ * @handle: handle for this transaction
* @inode: owner
* @indirect_blks: number of allocated indirect blocks
* @blks: number of allocated direct blocks
+ * @goal: preferred place for allocation
* @offsets: offsets (in the blocks) to store the pointers to next.
* @branch: place to store the chain in.
*
@@ -826,6 +835,7 @@ failed:
/**
* ext4_splice_branch - splice the allocated branch onto inode.
+ * @handle: handle for this transaction
* @inode: owner
* @block: (logical) number of block we are adding
* @chain: chain of indirect blocks (with a missing link - see
@@ -2125,9 +2135,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
*/
if (unlikely(journal_data && PageChecked(page)))
err = __ext4_journalled_writepage(page, len);
- else
+ else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
err = ext4_bio_write_page(&io_submit, page,
len, mpd->wbc);
+ else
+ err = block_write_full_page(page,
+ noalloc_get_block_write, mpd->wbc);
if (!err)
mpd->pages_written++;
@@ -3717,8 +3730,7 @@ static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
retry:
io_end = ext4_init_io_end(inode, GFP_ATOMIC);
if (!io_end) {
- if (printk_ratelimit())
- printk(KERN_WARNING "%s: allocation fail\n", __func__);
+ pr_warning_ratelimited("%s: allocation fail\n", __func__);
schedule();
goto retry;
}
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 5b4d4e3a4d58..1b10681f62a4 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2608,18 +2608,12 @@ int ext4_mb_release(struct super_block *sb)
static inline int ext4_issue_discard(struct super_block *sb,
ext4_group_t block_group, ext4_grpblk_t block, int count)
{
- int ret;
ext4_fsblk_t discard_block;
discard_block = block + ext4_group_first_block_no(sb, block_group);
trace_ext4_discard_blocks(sb,
(unsigned long long) discard_block, count);
- ret = sb_issue_discard(sb, discard_block, count, GFP_NOFS, 0);
- if (ret == -EOPNOTSUPP) {
- ext4_warning(sb, "discard not supported, disabling");
- clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD);
- }
- return ret;
+ return sb_issue_discard(sb, discard_block, count, GFP_NOFS, 0);
}
/*
@@ -2631,7 +2625,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
struct super_block *sb = journal->j_private;
struct ext4_buddy e4b;
struct ext4_group_info *db;
- int err, count = 0, count2 = 0;
+ int err, ret, count = 0, count2 = 0;
struct ext4_free_data *entry;
struct list_head *l, *ltmp;
@@ -2641,9 +2635,15 @@ 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_issue_discard(sb, entry->group,
+ if (test_opt(sb, DISCARD)) {
+ ret = ext4_issue_discard(sb, entry->group,
entry->start_blk, entry->count);
+ if (unlikely(ret == -EOPNOTSUPP)) {
+ ext4_warning(sb, "discard not supported, "
+ "disabling");
+ clear_opt(sb, DISCARD);
+ }
+ }
err = ext4_mb_load_buddy(sb, entry->group, &e4b);
/* we expect to find existing buddy because it's pinned */
@@ -4626,7 +4626,11 @@ do_more:
* blocks being freed are metadata. these blocks shouldn't
* be used until this transaction is committed
*/
- new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+ new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+ if (!new_entry) {
+ err = -ENOMEM;
+ goto error_return;
+ }
new_entry->start_blk = bit;
new_entry->group = block_group;
new_entry->count = count;
@@ -4718,8 +4722,6 @@ static int ext4_trim_extent(struct super_block *sb, int start, int count,
ext4_unlock_group(sb, group);
ret = ext4_issue_discard(sb, group, start, count);
- if (ret)
- ext4_std_error(sb, ret);
ext4_lock_group(sb, group);
mb_free_blocks(NULL, e4b, start, ex.fe_len);
@@ -4815,6 +4817,7 @@ ext4_grpblk_t ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b,
int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
{
struct ext4_buddy e4b;
+ ext4_fsblk_t blocks_count = ext4_blocks_count(EXT4_SB(sb)->s_es);
ext4_group_t first_group, last_group;
ext4_group_t group, ngroups = ext4_get_groups_count(sb);
ext4_grpblk_t cnt = 0, first_block, last_block;
@@ -4826,6 +4829,9 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
minlen = range->minlen >> sb->s_blocksize_bits;
trimmed = 0;
+ if (len > blocks_count)
+ len = blocks_count - start;
+
if (unlikely(minlen > EXT4_BLOCKS_PER_GROUP(sb)))
return -EINVAL;
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 25f3a974b725..b0a126f23c20 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -496,7 +496,7 @@ int ext4_ext_migrate(struct inode *inode)
goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
- S_IFREG, 0, goal);
+ S_IFREG, NULL, goal);
if (IS_ERR(tmp_inode)) {
retval = -ENOMEM;
ext4_journal_stop(handle);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 92203b8a099f..b3c1e86ba49b 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -581,9 +581,9 @@ static int htree_dirblock_to_tree(struct file *dir_file,
dir->i_sb->s_blocksize -
EXT4_DIR_REC_LEN(0));
for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
- if (!ext4_check_dir_entry(dir, de, bh,
- (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
- +((char *)de - bh->b_data))) {
+ if (ext4_check_dir_entry(dir, NULL, de, bh,
+ (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
+ + ((char *)de - bh->b_data))) {
/* On error, skip the f_pos to the next block. */
dir_file->f_pos = (dir_file->f_pos |
(dir->i_sb->s_blocksize - 1)) + 1;
@@ -820,7 +820,7 @@ static inline int search_dirblock(struct buffer_head *bh,
if ((char *) de + namelen <= dlimit &&
ext4_match (namelen, name, de)) {
/* found a match - just to be sure, do a full check */
- if (!ext4_check_dir_entry(dir, de, bh, offset))
+ if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
return -1;
*res_dir = de;
return 1;
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
if (namelen > EXT4_NAME_LEN)
return NULL;
if ((namelen <= 2) && (name[0] == '.') &&
- (name[1] == '.' || name[1] == '0')) {
+ (name[1] == '.' || name[1] == '\0')) {
/*
* "." or ".." will only be in the first block
* NFS may look up ".."; "." should be handled by the VFS
@@ -1036,7 +1036,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
return ERR_PTR(-EIO);
}
inode = ext4_iget(dir->i_sb, ino);
- if (unlikely(IS_ERR(inode))) {
+ if (IS_ERR(inode)) {
if (PTR_ERR(inode) == -ESTALE) {
EXT4_ERROR_INODE(dir,
"deleted inode referenced: %u",
@@ -1269,7 +1269,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
de = (struct ext4_dir_entry_2 *)bh->b_data;
top = bh->b_data + blocksize - reclen;
while ((char *) de <= top) {
- if (!ext4_check_dir_entry(dir, de, bh, offset))
+ if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
return -EIO;
if (ext4_match(namelen, name, de))
return -EEXIST;
@@ -1636,7 +1636,7 @@ static int ext4_delete_entry(handle_t *handle,
pde = NULL;
de = (struct ext4_dir_entry_2 *) bh->b_data;
while (i < bh->b_size) {
- if (!ext4_check_dir_entry(dir, de, bh, i))
+ if (ext4_check_dir_entry(dir, NULL, de, bh, i))
return -EIO;
if (de == de_del) {
BUFFER_TRACE(bh, "get_write_access");
@@ -1789,7 +1789,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
handle_t *handle;
struct inode *inode;
- struct buffer_head *dir_block;
+ struct buffer_head *dir_block = NULL;
struct ext4_dir_entry_2 *de;
unsigned int blocksize = dir->i_sb->s_blocksize;
int err, retries = 0;
@@ -1822,7 +1822,9 @@ retry:
if (!dir_block)
goto out_clear_inode;
BUFFER_TRACE(dir_block, "get_write_access");
- ext4_journal_get_write_access(handle, dir_block);
+ err = ext4_journal_get_write_access(handle, dir_block);
+ if (err)
+ goto out_clear_inode;
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
@@ -1839,10 +1841,12 @@ retry:
ext4_set_de_type(dir->i_sb, de, S_IFDIR);
inode->i_nlink = 2;
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
- ext4_handle_dirty_metadata(handle, dir, dir_block);
- brelse(dir_block);
- ext4_mark_inode_dirty(handle, inode);
- err = ext4_add_entry(handle, dentry, inode);
+ err = ext4_handle_dirty_metadata(handle, dir, dir_block);
+ if (err)
+ goto out_clear_inode;
+ err = ext4_mark_inode_dirty(handle, inode);
+ if (!err)
+ err = ext4_add_entry(handle, dentry, inode);
if (err) {
out_clear_inode:
clear_nlink(inode);
@@ -1853,10 +1857,13 @@ out_clear_inode:
}
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
- ext4_mark_inode_dirty(handle, dir);
+ err = ext4_mark_inode_dirty(handle, dir);
+ if (err)
+ goto out_clear_inode;
d_instantiate(dentry, inode);
unlock_new_inode(inode);
out_stop:
+ brelse(dir_block);
ext4_journal_stop(handle);
if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
goto retry;
@@ -1919,7 +1926,7 @@ static int empty_dir(struct inode *inode)
}
de = (struct ext4_dir_entry_2 *) bh->b_data;
}
- if (!ext4_check_dir_entry(inode, de, bh, offset)) {
+ if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) {
de = (struct ext4_dir_entry_2 *)(bh->b_data +
sb->s_blocksize);
offset = (offset | (sb->s_blocksize - 1)) + 1;
@@ -2511,7 +2518,7 @@ const struct inode_operations ext4_dir_inode_operations = {
.listxattr = ext4_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext4_check_acl,
+ .check_acl_rcu = ext4_check_acl_rcu,
.fiemap = ext4_fiemap,
};
@@ -2523,5 +2530,5 @@ const struct inode_operations ext4_special_inode_operations = {
.listxattr = ext4_listxattr,
.removexattr = generic_removexattr,
#endif
- .check_acl = ext4_check_acl,
+ .check_acl_rcu = ext4_check_acl_rcu,
};
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index beacce11ac50..7270dcfca92a 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -44,7 +44,7 @@ int __init ext4_init_pageio(void)
if (io_page_cachep == NULL)
return -ENOMEM;
io_end_cachep = KMEM_CACHE(ext4_io_end, SLAB_RECLAIM_ACCOUNT);
- if (io_page_cachep == NULL) {
+ if (io_end_cachep == NULL) {
kmem_cache_destroy(io_page_cachep);
return -ENOMEM;
}
@@ -158,11 +158,8 @@ static void ext4_end_io_work(struct work_struct *work)
ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
{
- ext4_io_end_t *io = NULL;
-
- io = kmem_cache_alloc(io_end_cachep, flags);
+ ext4_io_end_t *io = kmem_cache_zalloc(io_end_cachep, flags);
if (io) {
- memset(io, 0, sizeof(*io));
atomic_inc(&EXT4_I(inode)->i_ioend_count);
io->inode = inode;
INIT_WORK(&io->work, ext4_end_io_work);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index dc963929de65..981c8477adab 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -232,6 +232,8 @@ static int setup_new_group_blocks(struct super_block *sb,
GFP_NOFS);
if (err)
goto exit_bh;
+ for (i = 0, bit = gdblocks + 1; i < reserved_gdb; i++, bit++)
+ ext4_set_bit(bit, bh->b_data);
ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap,
input->block_bitmap - start);
@@ -247,6 +249,9 @@ static int setup_new_group_blocks(struct super_block *sb,
err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS);
if (err)
goto exit_bh;
+ for (i = 0, bit = input->inode_table - start;
+ i < sbi->s_itb_per_group; i++, bit++)
+ ext4_set_bit(bit, bh->b_data);
if ((err = extend_or_restart_transaction(handle, 2, bh)))
goto exit_bh;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e32195d6aac3..a8c1bfe91f9a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -388,13 +388,14 @@ static void ext4_handle_error(struct super_block *sb)
void __ext4_error(struct super_block *sb, const char *function,
unsigned int line, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: ",
- sb->s_id, function, line, current->comm);
- vprintk(fmt, args);
- printk("\n");
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n",
+ sb->s_id, function, line, current->comm, &vaf);
va_end(args);
ext4_handle_error(sb);
@@ -405,28 +406,31 @@ void ext4_error_inode(struct inode *inode, const char *function,
const char *fmt, ...)
{
va_list args;
+ struct va_format vaf;
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
es->s_last_error_ino = cpu_to_le32(inode->i_ino);
es->s_last_error_block = cpu_to_le64(block);
save_error_info(inode->i_sb, function, line);
va_start(args, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &args;
printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
inode->i_sb->s_id, function, line, inode->i_ino);
if (block)
- printk("block %llu: ", block);
- printk("comm %s: ", current->comm);
- vprintk(fmt, args);
- printk("\n");
+ printk(KERN_CONT "block %llu: ", block);
+ printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
va_end(args);
ext4_handle_error(inode->i_sb);
}
void ext4_error_file(struct file *file, const char *function,
- unsigned int line, const char *fmt, ...)
+ unsigned int line, ext4_fsblk_t block,
+ const char *fmt, ...)
{
va_list args;
+ struct va_format vaf;
struct ext4_super_block *es;
struct inode *inode = file->f_dentry->d_inode;
char pathname[80], *path;
@@ -434,17 +438,18 @@ void ext4_error_file(struct file *file, const char *function,
es = EXT4_SB(inode->i_sb)->s_es;
es->s_last_error_ino = cpu_to_le32(inode->i_ino);
save_error_info(inode->i_sb, function, line);
- va_start(args, fmt);
path = d_path(&(file->f_path), pathname, sizeof(pathname));
- if (!path)
+ if (IS_ERR(path))
path = "(unknown)";
printk(KERN_CRIT
- "EXT4-fs error (device %s): %s:%d: inode #%lu "
- "(comm %s path %s): ",
- inode->i_sb->s_id, function, line, inode->i_ino,
- current->comm, path);
- vprintk(fmt, args);
- printk("\n");
+ "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
+ inode->i_sb->s_id, function, line, inode->i_ino);
+ if (block)
+ printk(KERN_CONT "block %llu: ", block);
+ va_start(args, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
va_end(args);
ext4_handle_error(inode->i_sb);
@@ -543,28 +548,29 @@ void __ext4_abort(struct super_block *sb, const char *function,
panic("EXT4-fs panic from previous error\n");
}
-void ext4_msg (struct super_block * sb, const char *prefix,
- const char *fmt, ...)
+void ext4_msg(struct super_block *sb, const char *prefix, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk("%sEXT4-fs (%s): ", prefix, sb->s_id);
- vprintk(fmt, args);
- printk("\n");
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ printk("%sEXT4-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
va_end(args);
}
void __ext4_warning(struct super_block *sb, const char *function,
unsigned int line, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_WARNING "EXT4-fs warning (device %s): %s:%d: ",
- sb->s_id, function, line);
- vprintk(fmt, args);
- printk("\n");
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ printk(KERN_WARNING "EXT4-fs warning (device %s): %s:%d: %pV\n",
+ sb->s_id, function, line, &vaf);
va_end(args);
}
@@ -575,21 +581,25 @@ void __ext4_grp_locked_error(const char *function, unsigned int line,
__releases(bitlock)
__acquires(bitlock)
{
+ struct va_format vaf;
va_list args;
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
es->s_last_error_ino = cpu_to_le32(ino);
es->s_last_error_block = cpu_to_le64(block);
__save_error_info(sb, function, line);
+
va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: group %u",
sb->s_id, function, line, grp);
if (ino)
- printk("inode %lu: ", ino);
+ printk(KERN_CONT "inode %lu: ", ino);
if (block)
- printk("block %llu:", (unsigned long long) block);
- vprintk(fmt, args);
- printk("\n");
+ printk(KERN_CONT "block %llu:", (unsigned long long) block);
+ printk(KERN_CONT "%pV\n", &vaf);
va_end(args);
if (test_opt(sb, ERRORS_CONT)) {
@@ -647,7 +657,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb)
struct block_device *bdev;
char b[BDEVNAME_SIZE];
- bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+ bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
if (IS_ERR(bdev))
goto fail;
return bdev;
@@ -663,8 +673,7 @@ fail:
*/
static int ext4_blkdev_put(struct block_device *bdev)
{
- bd_release(bdev);
- return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
+ return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
@@ -841,6 +850,13 @@ static int ext4_drop_inode(struct inode *inode)
return drop;
}
+static void ext4_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
+}
+
static void ext4_destroy_inode(struct inode *inode)
{
ext4_ioend_wait(inode);
@@ -853,7 +869,7 @@ static void ext4_destroy_inode(struct inode *inode)
true);
dump_stack();
}
- kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
+ call_rcu(&inode->i_rcu, ext4_i_callback);
}
static void init_once(void *foo)
@@ -1026,6 +1042,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
!(def_mount_opts & EXT4_DEFM_NODELALLOC))
seq_puts(seq, ",nodelalloc");
+ if (test_opt(sb, MBLK_IO_SUBMIT))
+ seq_puts(seq, ",mblk_io_submit");
if (sbi->s_stripe)
seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
/*
@@ -1239,8 +1257,8 @@ enum {
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
- Opt_stripe, Opt_delalloc, Opt_nodelalloc,
- Opt_block_validity, Opt_noblock_validity,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+ Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard,
@@ -1304,6 +1322,8 @@ static const match_table_t tokens = {
{Opt_resize, "resize"},
{Opt_delalloc, "delalloc"},
{Opt_nodelalloc, "nodelalloc"},
+ {Opt_mblk_io_submit, "mblk_io_submit"},
+ {Opt_nomblk_io_submit, "nomblk_io_submit"},
{Opt_block_validity, "block_validity"},
{Opt_noblock_validity, "noblock_validity"},
{Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
@@ -1382,7 +1402,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
sbi->s_qf_names[qtype] = NULL;
return 0;
}
- set_opt(sbi->s_mount_opt, QUOTA);
+ set_opt(sb, QUOTA);
return 1;
}
@@ -1437,21 +1457,21 @@ static int parse_options(char *options, struct super_block *sb,
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);
+ clear_opt(sb, 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);
+ set_opt(sb, MINIX_DF);
break;
case Opt_grpid:
ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
- set_opt(sbi->s_mount_opt, GRPID);
+ set_opt(sb, GRPID);
break;
case Opt_nogrpid:
ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
- clear_opt(sbi->s_mount_opt, GRPID);
+ clear_opt(sb, GRPID);
break;
case Opt_resuid:
@@ -1469,38 +1489,38 @@ static int parse_options(char *options, struct super_block *sb,
/* *sb_block = match_int(&args[0]); */
break;
case Opt_err_panic:
- clear_opt(sbi->s_mount_opt, ERRORS_CONT);
- clear_opt(sbi->s_mount_opt, ERRORS_RO);
- set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+ clear_opt(sb, ERRORS_CONT);
+ clear_opt(sb, ERRORS_RO);
+ set_opt(sb, ERRORS_PANIC);
break;
case Opt_err_ro:
- clear_opt(sbi->s_mount_opt, ERRORS_CONT);
- clear_opt(sbi->s_mount_opt, ERRORS_PANIC);
- set_opt(sbi->s_mount_opt, ERRORS_RO);
+ clear_opt(sb, ERRORS_CONT);
+ clear_opt(sb, ERRORS_PANIC);
+ set_opt(sb, ERRORS_RO);
break;
case Opt_err_cont:
- clear_opt(sbi->s_mount_opt, ERRORS_RO);
- clear_opt(sbi->s_mount_opt, ERRORS_PANIC);
- set_opt(sbi->s_mount_opt, ERRORS_CONT);
+ clear_opt(sb, ERRORS_RO);
+ clear_opt(sb, ERRORS_PANIC);
+ set_opt(sb, ERRORS_CONT);
break;
case Opt_nouid32:
- set_opt(sbi->s_mount_opt, NO_UID32);
+ set_opt(sb, NO_UID32);
break;
case Opt_debug:
- set_opt(sbi->s_mount_opt, DEBUG);
+ set_opt(sb, DEBUG);
break;
case Opt_oldalloc:
- set_opt(sbi->s_mount_opt, OLDALLOC);
+ set_opt(sb, OLDALLOC);
break;
case Opt_orlov:
- clear_opt(sbi->s_mount_opt, OLDALLOC);
+ clear_opt(sb, OLDALLOC);
break;
#ifdef CONFIG_EXT4_FS_XATTR
case Opt_user_xattr:
- set_opt(sbi->s_mount_opt, XATTR_USER);
+ set_opt(sb, XATTR_USER);
break;
case Opt_nouser_xattr:
- clear_opt(sbi->s_mount_opt, XATTR_USER);
+ clear_opt(sb, XATTR_USER);
break;
#else
case Opt_user_xattr:
@@ -1510,10 +1530,10 @@ static int parse_options(char *options, struct super_block *sb,
#endif
#ifdef CONFIG_EXT4_FS_POSIX_ACL
case Opt_acl:
- set_opt(sbi->s_mount_opt, POSIX_ACL);
+ set_opt(sb, POSIX_ACL);
break;
case Opt_noacl:
- clear_opt(sbi->s_mount_opt, POSIX_ACL);
+ clear_opt(sb, POSIX_ACL);
break;
#else
case Opt_acl:
@@ -1532,7 +1552,7 @@ static int parse_options(char *options, struct super_block *sb,
"Cannot specify journal on remount");
return 0;
}
- set_opt(sbi->s_mount_opt, UPDATE_JOURNAL);
+ set_opt(sb, UPDATE_JOURNAL);
break;
case Opt_journal_dev:
if (is_remount) {
@@ -1545,14 +1565,14 @@ static int parse_options(char *options, struct super_block *sb,
*journal_devnum = option;
break;
case Opt_journal_checksum:
- set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
+ set_opt(sb, JOURNAL_CHECKSUM);
break;
case Opt_journal_async_commit:
- set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
- set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
+ set_opt(sb, JOURNAL_ASYNC_COMMIT);
+ set_opt(sb, JOURNAL_CHECKSUM);
break;
case Opt_noload:
- set_opt(sbi->s_mount_opt, NOLOAD);
+ set_opt(sb, NOLOAD);
break;
case Opt_commit:
if (match_int(&args[0], &option))
@@ -1595,15 +1615,15 @@ static int parse_options(char *options, struct super_block *sb,
return 0;
}
} else {
- clear_opt(sbi->s_mount_opt, DATA_FLAGS);
+ clear_opt(sb, DATA_FLAGS);
sbi->s_mount_opt |= data_opt;
}
break;
case Opt_data_err_abort:
- set_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+ set_opt(sb, DATA_ERR_ABORT);
break;
case Opt_data_err_ignore:
- clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+ clear_opt(sb, DATA_ERR_ABORT);
break;
#ifdef CONFIG_QUOTA
case Opt_usrjquota:
@@ -1643,12 +1663,12 @@ set_qf_format:
break;
case Opt_quota:
case Opt_usrquota:
- set_opt(sbi->s_mount_opt, QUOTA);
- set_opt(sbi->s_mount_opt, USRQUOTA);
+ set_opt(sb, QUOTA);
+ set_opt(sb, USRQUOTA);
break;
case Opt_grpquota:
- set_opt(sbi->s_mount_opt, QUOTA);
- set_opt(sbi->s_mount_opt, GRPQUOTA);
+ set_opt(sb, QUOTA);
+ set_opt(sb, GRPQUOTA);
break;
case Opt_noquota:
if (sb_any_quota_loaded(sb)) {
@@ -1656,9 +1676,9 @@ set_qf_format:
"options when quota turned on");
return 0;
}
- clear_opt(sbi->s_mount_opt, QUOTA);
- clear_opt(sbi->s_mount_opt, USRQUOTA);
- clear_opt(sbi->s_mount_opt, GRPQUOTA);
+ clear_opt(sb, QUOTA);
+ clear_opt(sb, USRQUOTA);
+ clear_opt(sb, GRPQUOTA);
break;
#else
case Opt_quota:
@@ -1684,7 +1704,7 @@ set_qf_format:
sbi->s_mount_flags |= EXT4_MF_FS_ABORTED;
break;
case Opt_nobarrier:
- clear_opt(sbi->s_mount_opt, BARRIER);
+ clear_opt(sb, BARRIER);
break;
case Opt_barrier:
if (args[0].from) {
@@ -1693,9 +1713,9 @@ set_qf_format:
} else
option = 1; /* No argument, default to 1 */
if (option)
- set_opt(sbi->s_mount_opt, BARRIER);
+ set_opt(sb, BARRIER);
else
- clear_opt(sbi->s_mount_opt, BARRIER);
+ clear_opt(sb, BARRIER);
break;
case Opt_ignore:
break;
@@ -1719,11 +1739,17 @@ set_qf_format:
"Ignoring deprecated bh option");
break;
case Opt_i_version:
- set_opt(sbi->s_mount_opt, I_VERSION);
+ set_opt(sb, I_VERSION);
sb->s_flags |= MS_I_VERSION;
break;
case Opt_nodelalloc:
- clear_opt(sbi->s_mount_opt, DELALLOC);
+ clear_opt(sb, DELALLOC);
+ break;
+ case Opt_mblk_io_submit:
+ set_opt(sb, MBLK_IO_SUBMIT);
+ break;
+ case Opt_nomblk_io_submit:
+ clear_opt(sb, MBLK_IO_SUBMIT);
break;
case Opt_stripe:
if (match_int(&args[0], &option))
@@ -1733,13 +1759,13 @@ set_qf_format:
sbi->s_stripe = option;
break;
case Opt_delalloc:
- set_opt(sbi->s_mount_opt, DELALLOC);
+ set_opt(sb, DELALLOC);
break;
case Opt_block_validity:
- set_opt(sbi->s_mount_opt, BLOCK_VALIDITY);
+ set_opt(sb, BLOCK_VALIDITY);
break;
case Opt_noblock_validity:
- clear_opt(sbi->s_mount_opt, BLOCK_VALIDITY);
+ clear_opt(sb, BLOCK_VALIDITY);
break;
case Opt_inode_readahead_blks:
if (match_int(&args[0], &option))
@@ -1763,7 +1789,7 @@ set_qf_format:
option);
break;
case Opt_noauto_da_alloc:
- set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
+ set_opt(sb, NO_AUTO_DA_ALLOC);
break;
case Opt_auto_da_alloc:
if (args[0].from) {
@@ -1772,24 +1798,24 @@ set_qf_format:
} else
option = 1; /* No argument, default to 1 */
if (option)
- clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
+ clear_opt(sb, NO_AUTO_DA_ALLOC);
else
- set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
+ set_opt(sb,NO_AUTO_DA_ALLOC);
break;
case Opt_discard:
- set_opt(sbi->s_mount_opt, DISCARD);
+ set_opt(sb, DISCARD);
break;
case Opt_nodiscard:
- clear_opt(sbi->s_mount_opt, DISCARD);
+ clear_opt(sb, DISCARD);
break;
case Opt_dioread_nolock:
- set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ set_opt(sb, DIOREAD_NOLOCK);
break;
case Opt_dioread_lock:
- clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ clear_opt(sb, DIOREAD_NOLOCK);
break;
case Opt_init_inode_table:
- set_opt(sbi->s_mount_opt, INIT_INODE_TABLE);
+ set_opt(sb, INIT_INODE_TABLE);
if (args[0].from) {
if (match_int(&args[0], &option))
return 0;
@@ -1800,7 +1826,7 @@ set_qf_format:
sbi->s_li_wait_mult = option;
break;
case Opt_noinit_inode_table:
- clear_opt(sbi->s_mount_opt, INIT_INODE_TABLE);
+ clear_opt(sb, INIT_INODE_TABLE);
break;
default:
ext4_msg(sb, KERN_ERR,
@@ -1812,10 +1838,10 @@ set_qf_format:
#ifdef CONFIG_QUOTA
if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
- clear_opt(sbi->s_mount_opt, USRQUOTA);
+ clear_opt(sb, USRQUOTA);
if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
- clear_opt(sbi->s_mount_opt, GRPQUOTA);
+ clear_opt(sb, GRPQUOTA);
if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
ext4_msg(sb, KERN_ERR, "old and new quota "
@@ -1885,12 +1911,12 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
ext4_commit_super(sb, 1);
if (test_opt(sb, DEBUG))
printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, "
- "bpg=%lu, ipg=%lu, mo=%04x]\n",
+ "bpg=%lu, ipg=%lu, mo=%04x, mo2=%04x]\n",
sb->s_blocksize,
sbi->s_groups_count,
EXT4_BLOCKS_PER_GROUP(sb),
EXT4_INODES_PER_GROUP(sb),
- sbi->s_mount_opt);
+ sbi->s_mount_opt, sbi->s_mount_opt2);
return res;
}
@@ -1920,14 +1946,13 @@ static int ext4_fill_flex_info(struct super_block *sb)
size = flex_group_count * sizeof(struct flex_groups);
sbi->s_flex_groups = kzalloc(size, GFP_KERNEL);
if (sbi->s_flex_groups == NULL) {
- sbi->s_flex_groups = vmalloc(size);
- if (sbi->s_flex_groups)
- memset(sbi->s_flex_groups, 0, size);
- }
- if (sbi->s_flex_groups == NULL) {
- ext4_msg(sb, KERN_ERR, "not enough memory for "
- "%u flex groups", flex_group_count);
- goto failed;
+ sbi->s_flex_groups = vzalloc(size);
+ if (sbi->s_flex_groups == NULL) {
+ ext4_msg(sb, KERN_ERR,
+ "not enough memory for %u flex groups",
+ flex_group_count);
+ goto failed;
+ }
}
for (i = 0; i < sbi->s_groups_count; i++) {
@@ -3061,41 +3086,41 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
/* Set defaults before we parse the mount options */
def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
- set_opt(sbi->s_mount_opt, INIT_INODE_TABLE);
+ set_opt(sb, INIT_INODE_TABLE);
if (def_mount_opts & EXT4_DEFM_DEBUG)
- set_opt(sbi->s_mount_opt, DEBUG);
+ set_opt(sb, DEBUG);
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);
+ set_opt(sb, GRPID);
}
if (def_mount_opts & EXT4_DEFM_UID16)
- set_opt(sbi->s_mount_opt, NO_UID32);
+ set_opt(sb, NO_UID32);
#ifdef CONFIG_EXT4_FS_XATTR
if (def_mount_opts & EXT4_DEFM_XATTR_USER)
- set_opt(sbi->s_mount_opt, XATTR_USER);
+ set_opt(sb, XATTR_USER);
#endif
#ifdef CONFIG_EXT4_FS_POSIX_ACL
if (def_mount_opts & EXT4_DEFM_ACL)
- set_opt(sbi->s_mount_opt, POSIX_ACL);
+ set_opt(sb, POSIX_ACL);
#endif
if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
- set_opt(sbi->s_mount_opt, JOURNAL_DATA);
+ set_opt(sb, JOURNAL_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED)
- set_opt(sbi->s_mount_opt, ORDERED_DATA);
+ set_opt(sb, ORDERED_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK)
- set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
+ set_opt(sb, WRITEBACK_DATA);
if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC)
- set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+ set_opt(sb, ERRORS_PANIC);
else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE)
- set_opt(sbi->s_mount_opt, ERRORS_CONT);
+ set_opt(sb, ERRORS_CONT);
else
- set_opt(sbi->s_mount_opt, ERRORS_RO);
+ set_opt(sb, ERRORS_RO);
if (def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)
- set_opt(sbi->s_mount_opt, BLOCK_VALIDITY);
+ set_opt(sb, BLOCK_VALIDITY);
if (def_mount_opts & EXT4_DEFM_DISCARD)
- set_opt(sbi->s_mount_opt, DISCARD);
+ set_opt(sb, DISCARD);
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
@@ -3104,7 +3129,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
if ((def_mount_opts & EXT4_DEFM_NOBARRIER) == 0)
- set_opt(sbi->s_mount_opt, BARRIER);
+ set_opt(sb, BARRIER);
/*
* enable delayed allocation by default
@@ -3112,7 +3137,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
*/
if (!IS_EXT3_SB(sb) &&
((def_mount_opts & EXT4_DEFM_NODELALLOC) == 0))
- set_opt(sbi->s_mount_opt, DELALLOC);
+ set_opt(sb, DELALLOC);
if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
&journal_devnum, &journal_ioprio, NULL, 0)) {
@@ -3415,8 +3440,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"suppressed and not mounted read-only");
goto failed_mount_wq;
} else {
- clear_opt(sbi->s_mount_opt, DATA_FLAGS);
- set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
+ clear_opt(sb, DATA_FLAGS);
+ set_opt(sb, WRITEBACK_DATA);
sbi->s_journal = NULL;
needs_recovery = 0;
goto no_journal;
@@ -3454,9 +3479,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
*/
if (jbd2_journal_check_available_features
(sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE))
- set_opt(sbi->s_mount_opt, ORDERED_DATA);
+ set_opt(sb, ORDERED_DATA);
else
- set_opt(sbi->s_mount_opt, JOURNAL_DATA);
+ set_opt(sb, JOURNAL_DATA);
break;
case EXT4_MOUNT_ORDERED_DATA:
@@ -3546,18 +3571,18 @@ no_journal:
(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - "
"requested data journaling mode");
- clear_opt(sbi->s_mount_opt, DELALLOC);
+ clear_opt(sb, 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);
+ clear_opt(sb, 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);
+ clear_opt(sb, DIOREAD_NOLOCK);
}
}
@@ -3755,13 +3780,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
if (bdev == NULL)
return NULL;
- if (bd_claim(bdev, sb)) {
- ext4_msg(sb, KERN_ERR,
- "failed to claim external journal device");
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
- return NULL;
- }
-
blocksize = sb->s_blocksize;
hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) {
@@ -4156,6 +4174,22 @@ static int ext4_unfreeze(struct super_block *sb)
return 0;
}
+/*
+ * Structure to save mount options for ext4_remount's benefit
+ */
+struct ext4_mount_options {
+ unsigned long s_mount_opt;
+ unsigned long s_mount_opt2;
+ uid_t s_resuid;
+ gid_t s_resgid;
+ unsigned long s_commit_interval;
+ u32 s_min_batch_time, s_max_batch_time;
+#ifdef CONFIG_QUOTA
+ int s_jquota_fmt;
+ char *s_qf_names[MAXQUOTAS];
+#endif
+};
+
static int ext4_remount(struct super_block *sb, int *flags, char *data)
{
struct ext4_super_block *es;
@@ -4176,6 +4210,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
+ old_opts.s_mount_opt2 = sbi->s_mount_opt2;
old_opts.s_resuid = sbi->s_resuid;
old_opts.s_resgid = sbi->s_resgid;
old_opts.s_commit_interval = sbi->s_commit_interval;
@@ -4329,6 +4364,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
restore_opts:
sb->s_flags = old_sb_flags;
sbi->s_mount_opt = old_opts.s_mount_opt;
+ sbi->s_mount_opt2 = old_opts.s_mount_opt2;
sbi->s_resuid = old_opts.s_resuid;
sbi->s_resgid = old_opts.s_resgid;
sbi->s_commit_interval = old_opts.s_commit_interval;
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index fa4b899da4b3..fc32176eee39 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -427,23 +427,23 @@ cleanup:
static int
ext4_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
{
- int i_error, b_error;
+ int ret, ret2;
down_read(&EXT4_I(dentry->d_inode)->xattr_sem);
- i_error = ext4_xattr_ibody_list(dentry, buffer, buffer_size);
- if (i_error < 0) {
- b_error = 0;
- } else {
- if (buffer) {
- buffer += i_error;
- buffer_size -= i_error;
- }
- b_error = ext4_xattr_block_list(dentry, buffer, buffer_size);
- if (b_error < 0)
- i_error = 0;
+ ret = ret2 = ext4_xattr_ibody_list(dentry, buffer, buffer_size);
+ if (ret < 0)
+ goto errout;
+ if (buffer) {
+ buffer += ret;
+ buffer_size -= ret;
}
+ ret = ext4_xattr_block_list(dentry, buffer, buffer_size);
+ if (ret < 0)
+ goto errout;
+ ret += ret2;
+errout:
up_read(&EXT4_I(dentry->d_inode)->xattr_sem);
- return i_error + b_error;
+ return ret;
}
/*
@@ -947,7 +947,7 @@ ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
/*
* ext4_xattr_set_handle()
*
- * Create, replace or remove an extended attribute for this inode. Buffer
+ * Create, replace or remove an extended attribute for this inode. Value
* is NULL to remove an existing extended attribute, and non-NULL to
* either replace an existing extended attribute, or create a new extended
* attribute. The flags XATTR_REPLACE and XATTR_CREATE
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index ad6998a92c30..206351af7c58 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -514,11 +514,18 @@ static struct inode *fat_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void fat_destroy_inode(struct inode *inode)
+static void fat_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
}
+static void fat_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, fat_i_callback);
+}
+
static void init_once(void *foo)
{
struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
@@ -743,7 +750,7 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
*/
result = d_obtain_alias(inode);
if (!IS_ERR(result))
- result->d_op = sb->s_root->d_op;
+ d_set_d_op(result, sb->s_root->d_op);
return result;
}
@@ -793,7 +800,7 @@ static struct dentry *fat_get_parent(struct dentry *child)
parent = d_obtain_alias(inode);
if (!IS_ERR(parent))
- parent->d_op = sb->s_root->d_op;
+ d_set_d_op(parent, sb->s_root->d_op);
out:
unlock_super(sb);
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 3345aabd1dd7..35ffe43afa4b 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -148,7 +148,8 @@ static int msdos_find(struct inode *dir, const unsigned char *name, int len,
* that the existing dentry can be used. The msdos fs routines will
* return ENOENT or EINVAL as appropriate.
*/
-static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
+static int msdos_hash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
unsigned char msdos_name[MSDOS_NAME];
@@ -164,16 +165,18 @@ static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
* Compare two msdos names. If either of the names are invalid,
* we fall back to doing the standard name comparison.
*/
-static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int msdos_cmp(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
+ struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options;
unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];
int error;
- error = msdos_format_name(a->name, a->len, a_msdos_name, options);
+ error = msdos_format_name(name->name, name->len, a_msdos_name, options);
if (error)
goto old_compare;
- error = msdos_format_name(b->name, b->len, b_msdos_name, options);
+ error = msdos_format_name(str, len, b_msdos_name, options);
if (error)
goto old_compare;
error = memcmp(a_msdos_name, b_msdos_name, MSDOS_NAME);
@@ -182,8 +185,8 @@ out:
old_compare:
error = 1;
- if (a->len == b->len)
- error = memcmp(a->name, b->name, a->len);
+ if (name->len == len)
+ error = memcmp(name->name, str, len);
goto out;
}
@@ -224,10 +227,10 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
}
out:
unlock_super(sb);
- dentry->d_op = &msdos_dentry_operations;
+ d_set_d_op(dentry, &msdos_dentry_operations);
dentry = d_splice_alias(inode, dentry);
if (dentry)
- dentry->d_op = &msdos_dentry_operations;
+ d_set_d_op(dentry, &msdos_dentry_operations);
return dentry;
error:
@@ -670,7 +673,7 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent)
}
sb->s_flags |= MS_NOATIME;
- sb->s_root->d_op = &msdos_dentry_operations;
+ d_set_d_op(sb->s_root, &msdos_dentry_operations);
unlock_super(sb);
return 0;
}
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index b936703b8924..9419ca54dee9 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -31,7 +31,7 @@
* If it happened, the negative dentry isn't actually negative
* anymore. So, drop it.
*/
-static int vfat_revalidate_shortname(struct dentry *dentry)
+static int vfat_revalidate_rcu_shortname(struct dentry *dentry)
{
int ret = 1;
spin_lock(&dentry->d_lock);
@@ -41,15 +41,15 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
return ret;
}
-static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int vfat_revalidate_rcu(struct dentry *dentry, struct nameidata *nd)
{
/* This is not negative dentry. Always valid. */
if (dentry->d_inode)
return 1;
- return vfat_revalidate_shortname(dentry);
+ return vfat_revalidate_rcu_shortname(dentry);
}
-static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
+static int vfat_revalidate_rcu_ci(struct dentry *dentry, struct nameidata *nd)
{
/*
* This is not negative dentry. Always valid.
@@ -81,26 +81,30 @@ static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
return 0;
}
- return vfat_revalidate_shortname(dentry);
+ return vfat_revalidate_rcu_shortname(dentry);
}
/* returns the length of a struct qstr, ignoring trailing dots */
-static unsigned int vfat_striptail_len(struct qstr *qstr)
+static unsigned int __vfat_striptail_len(unsigned int len, const char *name)
{
- unsigned int len = qstr->len;
-
- while (len && qstr->name[len - 1] == '.')
+ while (len && name[len - 1] == '.')
len--;
return len;
}
+static unsigned int vfat_striptail_len(const struct qstr *qstr)
+{
+ return __vfat_striptail_len(qstr->len, qstr->name);
+}
+
/*
* Compute the hash for the vfat name corresponding to the dentry.
* Note: if the name is invalid, we leave the hash code unchanged so
* that the existing dentry can be used. The vfat fs routines will
* return ENOENT or EINVAL as appropriate.
*/
-static int vfat_hash(struct dentry *dentry, struct qstr *qstr)
+static int vfat_hash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr));
return 0;
@@ -112,9 +116,10 @@ static int vfat_hash(struct dentry *dentry, struct qstr *qstr)
* that the existing dentry can be used. The vfat fs routines will
* return ENOENT or EINVAL as appropriate.
*/
-static int vfat_hashi(struct dentry *dentry, struct qstr *qstr)
+static int vfat_hashi(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
- struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io;
+ struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
const unsigned char *name;
unsigned int len;
unsigned long hash;
@@ -133,16 +138,18 @@ static int vfat_hashi(struct dentry *dentry, struct qstr *qstr)
/*
* Case insensitive compare of two vfat names.
*/
-static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io;
+ struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io;
unsigned int alen, blen;
/* A filename cannot end in '.' or we treat it like it has none */
- alen = vfat_striptail_len(a);
- blen = vfat_striptail_len(b);
+ alen = vfat_striptail_len(name);
+ blen = __vfat_striptail_len(len, str);
if (alen == blen) {
- if (nls_strnicmp(t, a->name, b->name, alen) == 0)
+ if (nls_strnicmp(t, name->name, str, alen) == 0)
return 0;
}
return 1;
@@ -151,28 +158,30 @@ static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b)
/*
* Case sensitive compare of two vfat names.
*/
-static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int vfat_cmp(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
unsigned int alen, blen;
/* A filename cannot end in '.' or we treat it like it has none */
- alen = vfat_striptail_len(a);
- blen = vfat_striptail_len(b);
+ alen = vfat_striptail_len(name);
+ blen = __vfat_striptail_len(len, str);
if (alen == blen) {
- if (strncmp(a->name, b->name, alen) == 0)
+ if (strncmp(name->name, str, alen) == 0)
return 0;
}
return 1;
}
static const struct dentry_operations vfat_ci_dentry_ops = {
- .d_revalidate = vfat_revalidate_ci,
+ .d_revalidate = vfat_revalidate_rcu_ci,
.d_hash = vfat_hashi,
.d_compare = vfat_cmpi,
};
static const struct dentry_operations vfat_dentry_ops = {
- .d_revalidate = vfat_revalidate,
+ .d_revalidate = vfat_revalidate_rcu,
.d_hash = vfat_hash,
.d_compare = vfat_cmp,
};
@@ -757,11 +766,11 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
out:
unlock_super(sb);
- dentry->d_op = sb->s_root->d_op;
+ d_set_d_op(dentry, sb->s_root->d_op);
dentry->d_time = dentry->d_parent->d_inode->i_version;
dentry = d_splice_alias(inode, dentry);
if (dentry) {
- dentry->d_op = sb->s_root->d_op;
+ d_set_d_op(dentry, sb->s_root->d_op);
dentry->d_time = dentry->d_parent->d_inode->i_version;
}
return dentry;
@@ -1063,9 +1072,9 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent)
}
if (MSDOS_SB(sb)->options.name_check != 's')
- sb->s_root->d_op = &vfat_ci_dentry_ops;
+ d_set_d_op(sb->s_root, &vfat_ci_dentry_ops);
else
- sb->s_root->d_op = &vfat_dentry_ops;
+ d_set_d_op(sb->s_root, &vfat_dentry_ops);
unlock_super(sb);
return 0;
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 68ba492d8eef..751d6b255a12 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -115,6 +115,9 @@ int unregister_filesystem(struct file_system_type * fs)
tmp = &(*tmp)->next;
}
write_unlock(&file_systems_lock);
+
+ synchronize_rcu();
+
return -EINVAL;
}
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 8c04eac5079d..2ba6719ac612 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -337,6 +337,13 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
return ip;
}
+static void vxfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(vxfs_inode_cachep, inode->i_private);
+}
+
/**
* vxfs_evict_inode - remove inode from main memory
* @ip: inode to discard.
@@ -350,5 +357,5 @@ vxfs_evict_inode(struct inode *ip)
{
truncate_inode_pages(&ip->i_data, 0);
end_writeback(ip);
- kmem_cache_free(vxfs_inode_cachep, ip->i_private);
+ call_rcu(&ip->i_rcu, vxfs_i_callback);
}
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index ed45a9cf5f3d..68ca487bedb1 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -14,12 +14,14 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
struct path old_root;
spin_lock(&fs->lock);
+ write_seqcount_begin(&fs->seq);
old_root = fs->root;
fs->root = *path;
- path_get(path);
+ path_get_long(path);
+ write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_root.dentry)
- path_put(&old_root);
+ path_put_long(&old_root);
}
/*
@@ -31,13 +33,15 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
struct path old_pwd;
spin_lock(&fs->lock);
+ write_seqcount_begin(&fs->seq);
old_pwd = fs->pwd;
fs->pwd = *path;
- path_get(path);
+ path_get_long(path);
+ write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_pwd.dentry)
- path_put(&old_pwd);
+ path_put_long(&old_pwd);
}
void chroot_fs_refs(struct path *old_root, struct path *new_root)
@@ -52,31 +56,33 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
fs = p->fs;
if (fs) {
spin_lock(&fs->lock);
+ write_seqcount_begin(&fs->seq);
if (fs->root.dentry == old_root->dentry
&& fs->root.mnt == old_root->mnt) {
- path_get(new_root);
+ path_get_long(new_root);
fs->root = *new_root;
count++;
}
if (fs->pwd.dentry == old_root->dentry
&& fs->pwd.mnt == old_root->mnt) {
- path_get(new_root);
+ path_get_long(new_root);
fs->pwd = *new_root;
count++;
}
+ write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
}
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
while (count--)
- path_put(old_root);
+ path_put_long(old_root);
}
void free_fs_struct(struct fs_struct *fs)
{
- path_put(&fs->root);
- path_put(&fs->pwd);
+ path_put_long(&fs->root);
+ path_put_long(&fs->pwd);
kmem_cache_free(fs_cachep, fs);
}
@@ -88,8 +94,10 @@ void exit_fs(struct task_struct *tsk)
int kill;
task_lock(tsk);
spin_lock(&fs->lock);
+ write_seqcount_begin(&fs->seq);
tsk->fs = NULL;
kill = !--fs->users;
+ write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
task_unlock(tsk);
if (kill)
@@ -105,8 +113,15 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
fs->users = 1;
fs->in_exec = 0;
spin_lock_init(&fs->lock);
+ seqcount_init(&fs->seq);
fs->umask = old->umask;
- get_fs_root_and_pwd(old, &fs->root, &fs->pwd);
+
+ spin_lock(&old->lock);
+ fs->root = old->root;
+ path_get_long(&fs->root);
+ fs->pwd = old->pwd;
+ path_get_long(&fs->pwd);
+ spin_unlock(&old->lock);
}
return fs;
}
@@ -144,6 +159,7 @@ EXPORT_SYMBOL(current_umask);
struct fs_struct init_fs = {
.users = 1,
.lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
+ .seq = SEQCNT_ZERO,
.umask = 0022,
};
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 6e07696308dc..cf8d28d1fbad 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -251,6 +251,20 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
}
+void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
+ u64 nodeid, u64 nlookup)
+{
+ forget->forget_one.nodeid = nodeid;
+ forget->forget_one.nlookup = nlookup;
+
+ spin_lock(&fc->lock);
+ fc->forget_list_tail->next = forget;
+ fc->forget_list_tail = forget;
+ wake_up(&fc->waitq);
+ kill_fasync(&fc->fasync, SIGIO, POLL_IN);
+ spin_unlock(&fc->lock);
+}
+
static void flush_bg_queue(struct fuse_conn *fc)
{
while (fc->active_background < fc->max_background &&
@@ -438,12 +452,6 @@ static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
}
}
-void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
-{
- req->isreply = 0;
- fuse_request_send_nowait(fc, req);
-}
-
void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
{
req->isreply = 1;
@@ -896,9 +904,15 @@ static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
return err;
}
+static int forget_pending(struct fuse_conn *fc)
+{
+ return fc->forget_list_head.next != NULL;
+}
+
static int request_pending(struct fuse_conn *fc)
{
- return !list_empty(&fc->pending) || !list_empty(&fc->interrupts);
+ return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) ||
+ forget_pending(fc);
}
/* Wait until a request is available on the pending list */
@@ -960,6 +974,120 @@ __releases(fc->lock)
return err ? err : reqsize;
}
+static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc,
+ unsigned max,
+ unsigned *countp)
+{
+ struct fuse_forget_link *head = fc->forget_list_head.next;
+ struct fuse_forget_link **newhead = &head;
+ unsigned count;
+
+ for (count = 0; *newhead != NULL && count < max; count++)
+ newhead = &(*newhead)->next;
+
+ fc->forget_list_head.next = *newhead;
+ *newhead = NULL;
+ if (fc->forget_list_head.next == NULL)
+ fc->forget_list_tail = &fc->forget_list_head;
+
+ if (countp != NULL)
+ *countp = count;
+
+ return head;
+}
+
+static int fuse_read_single_forget(struct fuse_conn *fc,
+ struct fuse_copy_state *cs,
+ size_t nbytes)
+__releases(fc->lock)
+{
+ int err;
+ struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL);
+ struct fuse_forget_in arg = {
+ .nlookup = forget->forget_one.nlookup,
+ };
+ struct fuse_in_header ih = {
+ .opcode = FUSE_FORGET,
+ .nodeid = forget->forget_one.nodeid,
+ .unique = fuse_get_unique(fc),
+ .len = sizeof(ih) + sizeof(arg),
+ };
+
+ spin_unlock(&fc->lock);
+ kfree(forget);
+ if (nbytes < ih.len)
+ return -EINVAL;
+
+ err = fuse_copy_one(cs, &ih, sizeof(ih));
+ if (!err)
+ err = fuse_copy_one(cs, &arg, sizeof(arg));
+ fuse_copy_finish(cs);
+
+ if (err)
+ return err;
+
+ return ih.len;
+}
+
+static int fuse_read_batch_forget(struct fuse_conn *fc,
+ struct fuse_copy_state *cs, size_t nbytes)
+__releases(fc->lock)
+{
+ int err;
+ unsigned max_forgets;
+ unsigned count;
+ struct fuse_forget_link *head;
+ struct fuse_batch_forget_in arg = { .count = 0 };
+ struct fuse_in_header ih = {
+ .opcode = FUSE_BATCH_FORGET,
+ .unique = fuse_get_unique(fc),
+ .len = sizeof(ih) + sizeof(arg),
+ };
+
+ if (nbytes < ih.len) {
+ spin_unlock(&fc->lock);
+ return -EINVAL;
+ }
+
+ max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
+ head = dequeue_forget(fc, max_forgets, &count);
+ spin_unlock(&fc->lock);
+
+ arg.count = count;
+ ih.len += count * sizeof(struct fuse_forget_one);
+ err = fuse_copy_one(cs, &ih, sizeof(ih));
+ if (!err)
+ err = fuse_copy_one(cs, &arg, sizeof(arg));
+
+ while (head) {
+ struct fuse_forget_link *forget = head;
+
+ if (!err) {
+ err = fuse_copy_one(cs, &forget->forget_one,
+ sizeof(forget->forget_one));
+ }
+ head = forget->next;
+ kfree(forget);
+ }
+
+ fuse_copy_finish(cs);
+
+ if (err)
+ return err;
+
+ return ih.len;
+}
+
+static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs,
+ size_t nbytes)
+__releases(fc->lock)
+{
+ if (fc->minor < 16 || fc->forget_list_head.next->next == NULL)
+ return fuse_read_single_forget(fc, cs, nbytes);
+ else
+ return fuse_read_batch_forget(fc, cs, nbytes);
+}
+
/*
* Read a single request into the userspace filesystem's buffer. This
* function waits until a request is available, then removes it from
@@ -998,6 +1126,14 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
return fuse_read_interrupt(fc, cs, nbytes, req);
}
+ if (forget_pending(fc)) {
+ if (list_empty(&fc->pending) || fc->forget_batch-- > 0)
+ return fuse_read_forget(fc, cs, nbytes);
+
+ if (fc->forget_batch <= -8)
+ fc->forget_batch = 16;
+ }
+
req = list_entry(fc->pending.next, struct fuse_req, list);
req->state = FUSE_REQ_READING;
list_move(&req->list, &fc->io);
@@ -1090,7 +1226,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
if (!fc)
return -EPERM;
- bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL);
+ bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
if (!bufs)
return -ENOMEM;
@@ -1626,7 +1762,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
if (!fc)
return -EPERM;
- bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL);
+ bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
if (!bufs)
return -ENOMEM;
@@ -1770,6 +1906,8 @@ __acquires(fc->lock)
flush_bg_queue(fc);
end_requests(fc, &fc->pending);
end_requests(fc, &fc->processing);
+ while (forget_pending(fc))
+ kfree(dequeue_forget(fc, 1, NULL));
}
/*
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c9627c95482d..99388899f9e8 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -10,9 +10,9 @@
#include <linux/pagemap.h>
#include <linux/file.h>
-#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#if BITS_PER_LONG >= 64
static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
@@ -154,7 +154,7 @@ u64 fuse_get_attr_version(struct fuse_conn *fc)
* the lookup once more. If the lookup results in the same inode,
* then refresh the attributes, timeouts and mark the dentry valid.
*/
-static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
+static int fuse_dentry_revalidate_rcu(struct dentry *entry, struct nameidata *nd)
{
struct inode *inode = entry->d_inode;
@@ -165,10 +165,13 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
struct fuse_entry_out outarg;
struct fuse_conn *fc;
struct fuse_req *req;
- struct fuse_req *forget_req;
+ struct fuse_forget_link *forget;
struct dentry *parent;
u64 attr_version;
+ if (nd->flags & LOOKUP_RCU)
+ return -ECHILD;
+
/* For negative dentries, always do a fresh lookup */
if (!inode)
return 0;
@@ -178,8 +181,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
if (IS_ERR(req))
return 0;
- forget_req = fuse_get_req(fc);
- if (IS_ERR(forget_req)) {
+ forget = fuse_alloc_forget();
+ if (!forget) {
fuse_put_request(fc, req);
return 0;
}
@@ -199,15 +202,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
if (!err) {
struct fuse_inode *fi = get_fuse_inode(inode);
if (outarg.nodeid != get_node_id(inode)) {
- fuse_send_forget(fc, forget_req,
- outarg.nodeid, 1);
+ fuse_queue_forget(fc, forget, outarg.nodeid, 1);
return 0;
}
spin_lock(&fc->lock);
fi->nlookup++;
spin_unlock(&fc->lock);
}
- fuse_put_request(fc, forget_req);
+ kfree(forget);
if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
return 0;
@@ -225,7 +227,7 @@ static int invalid_nodeid(u64 nodeid)
}
const struct dentry_operations fuse_dentry_operations = {
- .d_revalidate = fuse_dentry_revalidate,
+ .d_revalidate_rcu = fuse_dentry_revalidate_rcu,
};
int fuse_valid_type(int m)
@@ -259,7 +261,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
{
struct fuse_conn *fc = get_fuse_conn_super(sb);
struct fuse_req *req;
- struct fuse_req *forget_req;
+ struct fuse_forget_link *forget;
u64 attr_version;
int err;
@@ -273,9 +275,9 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
if (IS_ERR(req))
goto out;
- forget_req = fuse_get_req(fc);
- err = PTR_ERR(forget_req);
- if (IS_ERR(forget_req)) {
+ forget = fuse_alloc_forget();
+ err = -ENOMEM;
+ if (!forget) {
fuse_put_request(fc, req);
goto out;
}
@@ -301,13 +303,13 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
attr_version);
err = -ENOMEM;
if (!*inode) {
- fuse_send_forget(fc, forget_req, outarg->nodeid, 1);
+ fuse_queue_forget(fc, forget, outarg->nodeid, 1);
goto out;
}
err = 0;
out_put_forget:
- fuse_put_request(fc, forget_req);
+ kfree(forget);
out:
return err;
}
@@ -347,7 +349,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
}
entry = newent ? newent : entry;
- entry->d_op = &fuse_dentry_operations;
+ d_set_d_op(entry, &fuse_dentry_operations);
if (outarg_valid)
fuse_change_entry_timeout(entry, &outarg);
else
@@ -374,7 +376,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
struct inode *inode;
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req;
- struct fuse_req *forget_req;
+ struct fuse_forget_link *forget;
struct fuse_create_in inarg;
struct fuse_open_out outopen;
struct fuse_entry_out outentry;
@@ -388,9 +390,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
if (flags & O_DIRECT)
return -EINVAL;
- forget_req = fuse_get_req(fc);
- if (IS_ERR(forget_req))
- return PTR_ERR(forget_req);
+ forget = fuse_alloc_forget();
+ if (!forget)
+ return -ENOMEM;
req = fuse_get_req(fc);
err = PTR_ERR(req);
@@ -448,10 +450,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
if (!inode) {
flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
fuse_sync_release(ff, flags);
- fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
+ fuse_queue_forget(fc, forget, outentry.nodeid, 1);
return -ENOMEM;
}
- fuse_put_request(fc, forget_req);
+ kfree(forget);
d_instantiate(entry, inode);
fuse_change_entry_timeout(entry, &outentry);
fuse_invalidate_attr(dir);
@@ -469,7 +471,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
out_put_request:
fuse_put_request(fc, req);
out_put_forget_req:
- fuse_put_request(fc, forget_req);
+ kfree(forget);
return err;
}
@@ -483,12 +485,12 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
struct fuse_entry_out outarg;
struct inode *inode;
int err;
- struct fuse_req *forget_req;
+ struct fuse_forget_link *forget;
- forget_req = fuse_get_req(fc);
- if (IS_ERR(forget_req)) {
+ forget = fuse_alloc_forget();
+ if (!forget) {
fuse_put_request(fc, req);
- return PTR_ERR(forget_req);
+ return -ENOMEM;
}
memset(&outarg, 0, sizeof(outarg));
@@ -515,10 +517,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr, entry_attr_timeout(&outarg), 0);
if (!inode) {
- fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
+ fuse_queue_forget(fc, forget, outarg.nodeid, 1);
return -ENOMEM;
}
- fuse_put_request(fc, forget_req);
+ kfree(forget);
if (S_ISDIR(inode->i_mode)) {
struct dentry *alias;
@@ -541,7 +543,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
return 0;
out_put_forget_req:
- fuse_put_request(fc, forget_req);
+ kfree(forget);
return err;
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 9242d294fe90..95da1bc1c826 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/module.h>
+#include <linux/compat.h>
static const struct file_operations fuse_direct_io_file_operations;
@@ -1628,6 +1629,94 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
}
/*
+ * CUSE servers compiled on 32bit broke on 64bit kernels because the
+ * ABI was defined to be 'struct iovec' which is different on 32bit
+ * and 64bit. Fortunately we can determine which structure the server
+ * used from the size of the reply.
+ */
+static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src,
+ size_t transferred, unsigned count,
+ bool is_compat)
+{
+#ifdef CONFIG_COMPAT
+ if (count * sizeof(struct compat_iovec) == transferred) {
+ struct compat_iovec *ciov = src;
+ unsigned i;
+
+ /*
+ * With this interface a 32bit server cannot support
+ * non-compat (i.e. ones coming from 64bit apps) ioctl
+ * requests
+ */
+ if (!is_compat)
+ return -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ dst[i].iov_base = compat_ptr(ciov[i].iov_base);
+ dst[i].iov_len = ciov[i].iov_len;
+ }
+ return 0;
+ }
+#endif
+
+ if (count * sizeof(struct iovec) != transferred)
+ return -EIO;
+
+ memcpy(dst, src, transferred);
+ return 0;
+}
+
+/* Make sure iov_length() won't overflow */
+static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+{
+ size_t n;
+ u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+ for (n = 0; n < count; n++) {
+ if (iov->iov_len > (size_t) max)
+ return -ENOMEM;
+ max -= iov->iov_len;
+ }
+ return 0;
+}
+
+static int fuse_copy_ioctl_iovec(struct fuse_conn *fc, struct iovec *dst,
+ void *src, size_t transferred, unsigned count,
+ bool is_compat)
+{
+ unsigned i;
+ struct fuse_ioctl_iovec *fiov = src;
+
+ if (fc->minor < 16) {
+ return fuse_copy_ioctl_iovec_old(dst, src, transferred,
+ count, is_compat);
+ }
+
+ if (count * sizeof(struct fuse_ioctl_iovec) != transferred)
+ return -EIO;
+
+ for (i = 0; i < count; i++) {
+ /* Did the server supply an inappropriate value? */
+ if (fiov[i].base != (unsigned long) fiov[i].base ||
+ fiov[i].len != (unsigned long) fiov[i].len)
+ return -EIO;
+
+ dst[i].iov_base = (void __user *) (unsigned long) fiov[i].base;
+ dst[i].iov_len = (size_t) fiov[i].len;
+
+#ifdef CONFIG_COMPAT
+ if (is_compat &&
+ (ptr_to_compat(dst[i].iov_base) != fiov[i].base ||
+ (compat_size_t) dst[i].iov_len != fiov[i].len))
+ return -EIO;
+#endif
+ }
+
+ return 0;
+}
+
+
+/*
* For ioctls, there is no generic way to determine how much memory
* needs to be read and/or written. Furthermore, ioctls are allowed
* to dereference the passed pointer, so the parameter requires deep
@@ -1687,18 +1776,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
struct fuse_ioctl_out outarg;
struct fuse_req *req = NULL;
struct page **pages = NULL;
- struct page *iov_page = NULL;
+ struct iovec *iov_page = NULL;
struct iovec *in_iov = NULL, *out_iov = NULL;
unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages;
size_t in_size, out_size, transferred;
int err;
+#if BITS_PER_LONG == 32
+ inarg.flags |= FUSE_IOCTL_32BIT;
+#else
+ if (flags & FUSE_IOCTL_COMPAT)
+ inarg.flags |= FUSE_IOCTL_32BIT;
+#endif
+
/* assume all the iovs returned by client always fits in a page */
- BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
+ BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
err = -ENOMEM;
pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL);
- iov_page = alloc_page(GFP_KERNEL);
+ iov_page = (struct iovec *) __get_free_page(GFP_KERNEL);
if (!pages || !iov_page)
goto out;
@@ -1707,7 +1803,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
* RETRY from server is not allowed.
*/
if (!(flags & FUSE_IOCTL_UNRESTRICTED)) {
- struct iovec *iov = page_address(iov_page);
+ struct iovec *iov = iov_page;
iov->iov_base = (void __user *)arg;
iov->iov_len = _IOC_SIZE(cmd);
@@ -1788,7 +1884,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
/* did it ask for retry? */
if (outarg.flags & FUSE_IOCTL_RETRY) {
- char *vaddr;
+ void *vaddr;
/* no retry if in restricted mode */
err = -EIO;
@@ -1808,18 +1904,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
goto out;
- err = -EIO;
- if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred)
- goto out;
-
- /* okay, copy in iovs and retry */
vaddr = kmap_atomic(pages[0], KM_USER0);
- memcpy(page_address(iov_page), vaddr, transferred);
+ err = fuse_copy_ioctl_iovec(fc, iov_page, vaddr,
+ transferred, in_iovs + out_iovs,
+ (flags & FUSE_IOCTL_COMPAT) != 0);
kunmap_atomic(vaddr, KM_USER0);
+ if (err)
+ goto out;
- in_iov = page_address(iov_page);
+ in_iov = iov_page;
out_iov = in_iov + in_iovs;
+ err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+ if (err)
+ goto out;
+
+ err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+ if (err)
+ goto out;
+
goto retry;
}
@@ -1831,8 +1934,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
out:
if (req)
fuse_put_request(fc, req);
- if (iov_page)
- __free_page(iov_page);
+ free_page((unsigned long) iov_page);
while (num_pages)
__free_page(pages[--num_pages]);
kfree(pages);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 57d4a3a0f102..ae5744a2f9e9 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -53,6 +53,12 @@ extern struct mutex fuse_mutex;
extern unsigned max_user_bgreq;
extern unsigned max_user_congthresh;
+/* One forget request */
+struct fuse_forget_link {
+ struct fuse_forget_one forget_one;
+ struct fuse_forget_link *next;
+};
+
/** FUSE inode */
struct fuse_inode {
/** Inode data */
@@ -66,7 +72,7 @@ struct fuse_inode {
u64 nlookup;
/** The request used for sending the FORGET message */
- struct fuse_req *forget_req;
+ struct fuse_forget_link *forget;
/** Time in jiffies until the file attributes are valid */
u64 i_time;
@@ -255,7 +261,6 @@ struct fuse_req {
/** Data for asynchronous requests */
union {
- struct fuse_forget_in forget_in;
struct {
struct fuse_release_in in;
struct path path;
@@ -369,6 +374,13 @@ struct fuse_conn {
/** Pending interrupts */
struct list_head interrupts;
+ /** Queue of pending forgets */
+ struct fuse_forget_link forget_list_head;
+ struct fuse_forget_link *forget_list_tail;
+
+ /** Batching of FORGET requests (positive indicates FORGET batch) */
+ int forget_batch;
+
/** Flag indicating if connection is blocked. This will be
the case before the INIT reply is received, and if there
are too many outstading backgrounds requests */
@@ -543,8 +555,10 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
/**
* Send FORGET command
*/
-void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
- u64 nodeid, u64 nlookup);
+void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
+ u64 nodeid, u64 nlookup);
+
+struct fuse_forget_link *fuse_alloc_forget(void);
/**
* Initialize READ or READDIR request
@@ -656,11 +670,6 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
/**
- * Send a request with no reply
- */
-void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
-
-/**
* Send a request in the background
*/
void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index cfce3ad86a92..f62b32cffea9 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -71,6 +71,11 @@ struct fuse_mount_data {
unsigned blksize;
};
+struct fuse_forget_link *fuse_alloc_forget()
+{
+ return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
+}
+
static struct inode *fuse_alloc_inode(struct super_block *sb)
{
struct inode *inode;
@@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
INIT_LIST_HEAD(&fi->queued_writes);
INIT_LIST_HEAD(&fi->writepages);
init_waitqueue_head(&fi->page_waitq);
- fi->forget_req = fuse_request_alloc();
- if (!fi->forget_req) {
+ fi->forget = fuse_alloc_forget();
+ if (!fi->forget) {
kmem_cache_free(fuse_inode_cachep, inode);
return NULL;
}
@@ -99,27 +104,20 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
return inode;
}
-static void fuse_destroy_inode(struct inode *inode)
+static void fuse_i_callback(struct rcu_head *head)
{
- struct fuse_inode *fi = get_fuse_inode(inode);
- BUG_ON(!list_empty(&fi->write_files));
- BUG_ON(!list_empty(&fi->queued_writes));
- if (fi->forget_req)
- fuse_request_free(fi->forget_req);
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(fuse_inode_cachep, inode);
}
-void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
- u64 nodeid, u64 nlookup)
+static void fuse_destroy_inode(struct inode *inode)
{
- struct fuse_forget_in *inarg = &req->misc.forget_in;
- inarg->nlookup = nlookup;
- req->in.h.opcode = FUSE_FORGET;
- req->in.h.nodeid = nodeid;
- req->in.numargs = 1;
- req->in.args[0].size = sizeof(struct fuse_forget_in);
- req->in.args[0].value = inarg;
- fuse_request_send_noreply(fc, req);
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ BUG_ON(!list_empty(&fi->write_files));
+ BUG_ON(!list_empty(&fi->queued_writes));
+ kfree(fi->forget);
+ call_rcu(&inode->i_rcu, fuse_i_callback);
}
static void fuse_evict_inode(struct inode *inode)
@@ -129,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode)
if (inode->i_sb->s_flags & MS_ACTIVE) {
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
- fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
- fi->forget_req = NULL;
+ fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
+ fi->forget = NULL;
}
}
@@ -534,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc)
INIT_LIST_HEAD(&fc->interrupts);
INIT_LIST_HEAD(&fc->bg_queue);
INIT_LIST_HEAD(&fc->entry);
+ fc->forget_list_tail = &fc->forget_list_head;
atomic_set(&fc->num_waiting, 0);
fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
@@ -619,7 +618,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
entry = d_obtain_alias(inode);
if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
- entry->d_op = &fuse_dentry_operations;
+ d_set_d_op(entry, &fuse_dentry_operations);
fuse_invalidate_entry_cache(entry);
}
@@ -721,7 +720,7 @@ static struct dentry *fuse_get_parent(struct dentry *child)
parent = d_obtain_alias(inode);
if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
- parent->d_op = &fuse_dentry_operations;
+ d_set_d_op(parent, &fuse_dentry_operations);
fuse_invalidate_entry_cache(parent);
}
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
index 6bc9e3a5a693..3b250e5b8be8 100644
--- a/fs/generic_acl.c
+++ b/fs/generic_acl.c
@@ -190,6 +190,26 @@ generic_acl_chmod(struct inode *inode)
}
int
+generic_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
+{
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ } else {
+ struct posix_acl *acl;
+
+ acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
+
+ if (acl) {
+ int error = posix_acl_permission(inode, acl, mask);
+ posix_acl_release(acl);
+ return error;
+ }
+ }
+ return -EAGAIN;
+}
+
+int
generic_check_acl(struct inode *inode, int mask)
{
struct posix_acl *acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 5476c066d4ee..3c4039d5eef1 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -763,7 +763,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
int metadata;
unsigned int revokes = 0;
int x;
- int error;
+ int error = 0;
if (!*top)
sm->sm_first = 0;
@@ -780,7 +780,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
if (metadata)
revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs;
- error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh);
+ if (ip != GFS2_I(sdp->sd_rindex))
+ error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh);
+ else if (!sdp->sd_rgrps)
+ error = gfs2_ri_update(ip);
+
if (error)
return error;
@@ -879,7 +883,8 @@ out_rg_gunlock:
out_rlist:
gfs2_rlist_free(&rlist);
out:
- gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
+ if (ip != GFS2_I(sdp->sd_rindex))
+ gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
return error;
}
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c
index 6798755b3858..50497f65763b 100644
--- a/fs/gfs2/dentry.c
+++ b/fs/gfs2/dentry.c
@@ -100,13 +100,14 @@ fail:
return 0;
}
-static int gfs2_dhash(struct dentry *dentry, struct qstr *str)
+static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *str)
{
str->hash = gfs2_disk_hash(str->name, str->len);
return 0;
}
-static int gfs2_dentry_delete(struct dentry *dentry)
+static int gfs2_dentry_delete(const struct dentry *dentry)
{
struct gfs2_inode *ginode;
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index 5ab3839dfcb9..97012ecff560 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -130,7 +130,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1));
if (!IS_ERR(dentry))
- dentry->d_op = &gfs2_dops;
+ d_set_d_op(dentry, &gfs2_dops);
return dentry;
}
@@ -158,7 +158,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
out_inode:
dentry = d_obtain_alias(inode);
if (!IS_ERR(dentry))
- dentry->d_op = &gfs2_dops;
+ d_set_d_op(dentry, &gfs2_dops);
return dentry;
}
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index f92c17704169..08a8beb152e6 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -541,21 +541,6 @@ out_locked:
spin_unlock(&gl->gl_spin);
}
-static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock,
- unsigned int req_state,
- unsigned int flags)
-{
- int ret = LM_OUT_ERROR;
-
- if (!sdp->sd_lockstruct.ls_ops->lm_lock)
- return req_state == LM_ST_UNLOCKED ? 0 : req_state;
-
- if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
- ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock,
- req_state, flags);
- return ret;
-}
-
/**
* do_xmote - Calls the DLM to change the state of a lock
* @gl: The lock state
@@ -575,13 +560,14 @@ __acquires(&gl->gl_spin)
lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
LM_FLAG_PRIORITY);
- BUG_ON(gl->gl_state == target);
- BUG_ON(gl->gl_state == gl->gl_target);
+ GLOCK_BUG_ON(gl, gl->gl_state == target);
+ GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target);
if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) &&
glops->go_inval) {
set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
do_error(gl, 0); /* Fail queued try locks */
}
+ gl->gl_req = target;
spin_unlock(&gl->gl_spin);
if (glops->go_xmote_th)
glops->go_xmote_th(gl);
@@ -594,15 +580,17 @@ __acquires(&gl->gl_spin)
gl->gl_state == LM_ST_DEFERRED) &&
!(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
lck_flags |= LM_FLAG_TRY_1CB;
- ret = gfs2_lm_lock(sdp, gl, target, lck_flags);
- if (!(ret & LM_OUT_ASYNC)) {
- finish_xmote(gl, ret);
+ if (sdp->sd_lockstruct.ls_ops->lm_lock) {
+ /* lock_dlm */
+ ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags);
+ GLOCK_BUG_ON(gl, ret);
+ } else { /* lock_nolock */
+ finish_xmote(gl, target);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
- } else {
- GLOCK_BUG_ON(gl, ret != LM_OUT_ASYNC);
}
+
spin_lock(&gl->gl_spin);
}
@@ -951,17 +939,22 @@ int gfs2_glock_wait(struct gfs2_holder *gh)
void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
+
if (seq) {
struct gfs2_glock_iter *gi = seq->private;
vsprintf(gi->string, fmt, args);
seq_printf(seq, gi->string);
} else {
- printk(KERN_ERR " ");
- vprintk(fmt, args);
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_ERR " %pV", &vaf);
}
+
va_end(args);
}
@@ -1361,24 +1354,28 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl)
* @gl: Pointer to the glock
* @ret: The return value from the dlm
*
+ * The gl_reply field is under the gl_spin lock so that it is ok
+ * to use a bitfield shared with other glock state fields.
*/
void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
{
struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
+ spin_lock(&gl->gl_spin);
gl->gl_reply = ret;
if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) {
- spin_lock(&gl->gl_spin);
if (gfs2_should_freeze(gl)) {
set_bit(GLF_FROZEN, &gl->gl_flags);
spin_unlock(&gl->gl_spin);
return;
}
- spin_unlock(&gl->gl_spin);
}
+
+ spin_unlock(&gl->gl_spin);
set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+ smp_wmb();
gfs2_glock_hold(gl);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
@@ -1626,18 +1623,17 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags)
static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh)
{
struct task_struct *gh_owner = NULL;
- char buffer[KSYM_SYMBOL_LEN];
char flags_buf[32];
- sprint_symbol(buffer, gh->gh_ip);
if (gh->gh_owner_pid)
gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID);
- gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %s\n",
- state2str(gh->gh_state),
- hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
- gh->gh_error,
- gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
- gh_owner ? gh_owner->comm : "(ended)", buffer);
+ gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %pS\n",
+ state2str(gh->gh_state),
+ hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
+ gh->gh_error,
+ gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
+ gh_owner ? gh_owner->comm : "(ended)",
+ (void *)gh->gh_ip);
return 0;
}
@@ -1782,12 +1778,13 @@ int __init gfs2_glock_init(void)
}
#endif
- glock_workqueue = alloc_workqueue("glock_workqueue", WQ_RESCUER |
+ glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM |
WQ_HIGHPRI | WQ_FREEZEABLE, 0);
if (IS_ERR(glock_workqueue))
return PTR_ERR(glock_workqueue);
- gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", WQ_RESCUER |
- WQ_FREEZEABLE, 0);
+ gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
+ WQ_MEM_RECLAIM | WQ_FREEZEABLE,
+ 0);
if (IS_ERR(gfs2_delete_workqueue)) {
destroy_workqueue(glock_workqueue);
return PTR_ERR(gfs2_delete_workqueue);
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index db1c26d6d220..691851ceb615 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -87,11 +87,10 @@ enum {
#define GL_ASYNC 0x00000040
#define GL_EXACT 0x00000080
#define GL_SKIP 0x00000100
-#define GL_ATIME 0x00000200
#define GL_NOCACHE 0x00000400
/*
- * lm_lock() and lm_async_cb return flags
+ * lm_async_cb return flags
*
* LM_OUT_ST_MASK
* Masks the lower two bits of lock state in the returned value.
@@ -99,15 +98,11 @@ enum {
* LM_OUT_CANCELED
* The lock request was canceled.
*
- * LM_OUT_ASYNC
- * The result of the request will be returned in an LM_CB_ASYNC callback.
- *
*/
#define LM_OUT_ST_MASK 0x00000003
#define LM_OUT_CANCELED 0x00000008
-#define LM_OUT_ASYNC 0x00000080
-#define LM_OUT_ERROR 0x00000100
+#define LM_OUT_ERROR 0x00000004
/*
* lm_recovery_done() messages
@@ -124,25 +119,12 @@ struct lm_lockops {
void (*lm_unmount) (struct gfs2_sbd *sdp);
void (*lm_withdraw) (struct gfs2_sbd *sdp);
void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl);
- unsigned int (*lm_lock) (struct gfs2_glock *gl,
- unsigned int req_state, unsigned int flags);
+ int (*lm_lock) (struct gfs2_glock *gl, unsigned int req_state,
+ unsigned int flags);
void (*lm_cancel) (struct gfs2_glock *gl);
const match_table_t *lm_tokens;
};
-#define LM_FLAG_TRY 0x00000001
-#define LM_FLAG_TRY_1CB 0x00000002
-#define LM_FLAG_NOEXP 0x00000004
-#define LM_FLAG_ANY 0x00000008
-#define LM_FLAG_PRIORITY 0x00000010
-
-#define GL_ASYNC 0x00000040
-#define GL_EXACT 0x00000080
-#define GL_SKIP 0x00000100
-#define GL_NOCACHE 0x00000400
-
-#define GLR_TRYFAILED 13
-
extern struct workqueue_struct *gfs2_delete_workqueue;
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
{
@@ -212,6 +194,8 @@ int gfs2_glock_nq_num(struct gfs2_sbd *sdp,
int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs);
void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs);
void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs);
+
+__attribute__ ((format(printf, 2, 3)))
void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...);
/**
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 0d149dcc04e5..263561bf1a50 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -325,7 +325,6 @@ static void trans_go_sync(struct gfs2_glock *gl)
if (gl->gl_state != LM_ST_UNLOCKED &&
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
- flush_workqueue(gfs2_delete_workqueue);
gfs2_meta_syncfs(sdp);
gfs2_log_shutdown(sdp);
}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 764fbb49efc8..8d3d2b4a0a7d 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -207,12 +207,14 @@ struct gfs2_glock {
spinlock_t gl_spin;
- unsigned int gl_state;
- unsigned int gl_target;
- unsigned int gl_reply;
+ /* State fields protected by gl_spin */
+ unsigned int gl_state:2, /* Current state */
+ gl_target:2, /* Target state */
+ gl_demote_state:2, /* State requested by remote node */
+ gl_req:2, /* State in last dlm request */
+ gl_reply:8; /* Last reply from the dlm */
+
unsigned int gl_hash;
- unsigned int gl_req;
- unsigned int gl_demote_state; /* state requested by remote node */
unsigned long gl_demote_time; /* time of first demote request */
struct list_head gl_holders;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index e1213f7f9217..14e682dbe8bf 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -916,17 +916,8 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
if (error)
return error;
- if ((attr->ia_valid & ATTR_SIZE) &&
- attr->ia_size != i_size_read(inode)) {
- error = vmtruncate(inode, attr->ia_size);
- if (error)
- return error;
- }
-
setattr_copy(inode, attr);
mark_inode_dirty(inode);
-
- gfs2_assert_warn(GFS2_SB(inode), !error);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 1c09425b45fd..6e493aee28f8 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -146,15 +146,13 @@ static u32 make_flags(const u32 lkid, const unsigned int gfs_flags,
return lkf;
}
-static unsigned int gdlm_lock(struct gfs2_glock *gl,
- unsigned int req_state, unsigned int flags)
+static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
+ unsigned int flags)
{
struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
- int error;
int req;
u32 lkf;
- gl->gl_req = req_state;
req = make_mode(req_state);
lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);
@@ -162,13 +160,8 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl,
* Submit the actual lock request.
*/
- error = dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
- GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
- if (error == -EAGAIN)
- return 0;
- if (error)
- return LM_OUT_ERROR;
- return LM_OUT_ASYNC;
+ return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
+ GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}
static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 3eb1393f7b81..9df007c10324 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -440,7 +440,7 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
iput(inode);
return -ENOMEM;
}
- dentry->d_op = &gfs2_dops;
+ d_set_d_op(dentry, &gfs2_dops);
*dptr = dentry;
return 0;
}
@@ -1268,7 +1268,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
{
struct block_device *bdev;
struct super_block *s;
- fmode_t mode = FMODE_READ;
+ fmode_t mode = FMODE_READ | FMODE_EXCL;
int error;
struct gfs2_args args;
struct gfs2_sbd *sdp;
@@ -1276,7 +1276,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
- bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+ bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
@@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
goto error_bdev;
if (s->s_root)
- close_bdev_exclusive(bdev, mode);
+ blkdev_put(bdev, mode);
memset(&args, 0, sizeof(args));
args.ar_quota = GFS2_QUOTA_DEFAULT;
@@ -1342,7 +1342,7 @@ error_super:
deactivate_locked_super(s);
return ERR_PTR(error);
error_bdev:
- close_bdev_exclusive(bdev, mode);
+ blkdev_put(bdev, mode);
return ERR_PTR(error);
}
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 12cbea7502c2..aa112c608295 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -106,7 +106,7 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
{
struct inode *inode = NULL;
- dentry->d_op = &gfs2_dops;
+ d_set_d_op(dentry, &gfs2_dops);
inode = gfs2_lookupi(dir, &dentry->d_name, 0);
if (inode && IS_ERR(inode))
@@ -1069,7 +1069,6 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
- struct buffer_head *dibh;
u32 ouid, ogid, nuid, ngid;
int error;
@@ -1100,25 +1099,10 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
if (error)
goto out_gunlock_q;
- error = gfs2_meta_inode_buffer(ip, &dibh);
+ error = gfs2_setattr_simple(ip, attr);
if (error)
goto out_end_trans;
- if ((attr->ia_valid & ATTR_SIZE) &&
- attr->ia_size != i_size_read(inode)) {
- int error;
-
- error = vmtruncate(inode, attr->ia_size);
- gfs2_assert_warn(sdp, !error);
- }
-
- setattr_copy(inode, attr);
- mark_inode_dirty(inode);
-
- gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
-
if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
gfs2_quota_change(ip, -blocks, ouid, ogid);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index f606baf9ba72..a689901963de 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -666,6 +666,10 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift);
qd->qd_qb.qb_limit = qp->qu_limit;
}
+ if (fdq->d_fieldmask & FS_DQ_BCOUNT) {
+ qp->qu_value = cpu_to_be64(fdq->d_bcount >> sdp->sd_fsb2bb_shift);
+ qd->qd_qb.qb_value = qp->qu_value;
+ }
}
/* Write the quota into the quota file on disk */
@@ -1509,7 +1513,7 @@ out:
}
/* GFS2 only supports a subset of the XFS fields */
-#define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD)
+#define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT)
static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
struct fs_disk_quota *fdq)
@@ -1569,9 +1573,15 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
if ((fdq->d_fieldmask & FS_DQ_BSOFT) &&
((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn)))
fdq->d_fieldmask ^= FS_DQ_BSOFT;
+
if ((fdq->d_fieldmask & FS_DQ_BHARD) &&
((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit)))
fdq->d_fieldmask ^= FS_DQ_BHARD;
+
+ if ((fdq->d_fieldmask & FS_DQ_BCOUNT) &&
+ ((fdq->d_bcount >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_value)))
+ fdq->d_fieldmask ^= FS_DQ_BCOUNT;
+
if (fdq->d_fieldmask == 0)
goto out_i;
@@ -1620,4 +1630,3 @@ const struct quotactl_ops gfs2_quotactl_ops = {
.get_dqblk = gfs2_get_dqblk,
.set_dqblk = gfs2_set_dqblk,
};
-
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 33c8407b876f..7293ea27020c 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -500,7 +500,7 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp)
for (rgrps = 0;; rgrps++) {
loff_t pos = rgrps * sizeof(struct gfs2_rindex);
- if (pos + sizeof(struct gfs2_rindex) >= i_size_read(inode))
+ if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode))
break;
error = gfs2_internal_read(ip, &ra_state, buf, &pos,
sizeof(struct gfs2_rindex));
@@ -583,7 +583,7 @@ static int read_rindex_entry(struct gfs2_inode *ip,
* Returns: 0 on successful update, error code otherwise
*/
-static int gfs2_ri_update(struct gfs2_inode *ip)
+int gfs2_ri_update(struct gfs2_inode *ip)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct inode *inode = &ip->i_inode;
@@ -614,46 +614,6 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
}
/**
- * gfs2_ri_update_special - Pull in a new resource index from the disk
- *
- * This is a special version that's safe to call from gfs2_inplace_reserve_i.
- * In this case we know that we don't have any resource groups in memory yet.
- *
- * @ip: pointer to the rindex inode
- *
- * Returns: 0 on successful update, error code otherwise
- */
-static int gfs2_ri_update_special(struct gfs2_inode *ip)
-{
- struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
- struct inode *inode = &ip->i_inode;
- struct file_ra_state ra_state;
- struct gfs2_rgrpd *rgd;
- unsigned int max_data = 0;
- int error;
-
- file_ra_state_init(&ra_state, inode->i_mapping);
- for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
- /* Ignore partials */
- if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
- i_size_read(inode))
- break;
- error = read_rindex_entry(ip, &ra_state);
- if (error) {
- clear_rgrpdi(sdp);
- return error;
- }
- }
- list_for_each_entry(rgd, &sdp->sd_rindex_list, rd_list)
- if (rgd->rd_data > max_data)
- max_data = rgd->rd_data;
- sdp->sd_max_rg_data = max_data;
-
- sdp->sd_rindex_uptodate = 1;
- return 0;
-}
-
-/**
* gfs2_rindex_hold - Grab a lock on the rindex
* @sdp: The GFS2 superblock
* @ri_gh: the glock holder
@@ -1226,16 +1186,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex,
error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
else if (!sdp->sd_rgrps) /* We may not have the rindex read
in, so: */
- error = gfs2_ri_update_special(ip);
+ error = gfs2_ri_update(ip);
if (error)
return error;
}
+try_again:
do {
error = get_local_rgrp(ip, &last_unlinked);
/* If there is no space, flushing the log may release some */
- if (error)
+ if (error) {
+ if (ip == GFS2_I(sdp->sd_rindex) &&
+ !sdp->sd_rindex_uptodate) {
+ error = gfs2_ri_update(ip);
+ if (error)
+ return error;
+ goto try_again;
+ }
gfs2_log_flush(sdp, NULL);
+ }
} while (error && tries++ < 3);
if (error) {
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 0e35c0466f9a..50c2bb04369c 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -48,6 +48,7 @@ extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex,
extern void gfs2_inplace_release(struct gfs2_inode *ip);
+extern int gfs2_ri_update(struct gfs2_inode *ip);
extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n);
extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 2b2c4997430b..16c2ecac7eb7 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1405,11 +1405,18 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
return &ip->i_inode;
}
-static void gfs2_destroy_inode(struct inode *inode)
+static void gfs2_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(gfs2_inode_cachep, inode);
}
+static void gfs2_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, gfs2_i_callback);
+}
+
const struct super_operations gfs2_super_ops = {
.alloc_inode = gfs2_alloc_inode,
.destroy_inode = gfs2_destroy_inode,
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 30b58f07c8a6..439b61c03262 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -1296,10 +1296,8 @@ fail:
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
{
- struct inode *inode = &ip->i_inode;
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_ea_location el;
- struct buffer_head *dibh;
int error;
error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el);
@@ -1321,26 +1319,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
if (error)
return error;
- error = gfs2_meta_inode_buffer(ip, &dibh);
- if (error)
- goto out_trans_end;
-
- if ((attr->ia_valid & ATTR_SIZE) &&
- attr->ia_size != i_size_read(inode)) {
- int error;
-
- error = vmtruncate(inode, attr->ia_size);
- gfs2_assert_warn(GFS2_SB(inode), !error);
- }
-
- setattr_copy(inode, attr);
- mark_inode_dirty(inode);
-
- gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
-
-out_trans_end:
+ error = gfs2_setattr_simple(ip, attr);
gfs2_trans_end(sdp);
return error;
}
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 2b3b8611b41b..ea4aefe7c652 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -25,7 +25,7 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry,
struct inode *inode = NULL;
int res;
- dentry->d_op = &hfs_dentry_operations;
+ d_set_d_op(dentry, &hfs_dentry_operations);
hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name);
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index c8cffb81e849..ad97c2d58287 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -213,10 +213,14 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
/* string.c */
extern const struct dentry_operations hfs_dentry_operations;
-extern int hfs_hash_dentry(struct dentry *, struct qstr *);
+extern int hfs_hash_dentry(const struct dentry *, const struct inode *,
+ struct qstr *);
extern int hfs_strcmp(const unsigned char *, unsigned int,
const unsigned char *, unsigned int);
-extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+extern int hfs_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
/* trans.c */
extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *);
diff --git a/fs/hfs/string.c b/fs/hfs/string.c
index 927a5af79428..495a976a3cc9 100644
--- a/fs/hfs/string.c
+++ b/fs/hfs/string.c
@@ -51,7 +51,8 @@ static unsigned char caseorder[256] = {
/*
* Hash a string to an integer in a case-independent way
*/
-int hfs_hash_dentry(struct dentry *dentry, struct qstr *this)
+int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *this)
{
const unsigned char *name = this->name;
unsigned int hash, len = this->len;
@@ -92,21 +93,21 @@ int hfs_strcmp(const unsigned char *s1, unsigned int len1,
* Test for equality of two strings in the HFS filename character ordering.
* return 1 on failure and 0 on success
*/
-int hfs_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2)
+int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
const unsigned char *n1, *n2;
- int len;
- len = s1->len;
if (len >= HFS_NAMELEN) {
- if (s2->len < HFS_NAMELEN)
+ if (name->len < HFS_NAMELEN)
return 1;
len = HFS_NAMELEN;
- } else if (len != s2->len)
+ } else if (len != name->len)
return 1;
- n1 = s1->name;
- n2 = s2->name;
+ n1 = str;
+ n2 = name->name;
while (len--) {
if (caseorder[*n1++] != caseorder[*n2++])
return 1;
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 4824c27cebb8..0bef62aa4f42 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -167,11 +167,18 @@ static struct inode *hfs_alloc_inode(struct super_block *sb)
return i ? &i->vfs_inode : NULL;
}
-static void hfs_destroy_inode(struct inode *inode)
+static void hfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(hfs_inode_cachep, HFS_I(inode));
}
+static void hfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, hfs_i_callback);
+}
+
static const struct super_operations hfs_super_operations = {
.alloc_inode = hfs_alloc_inode,
.destroy_inode = hfs_destroy_inode,
@@ -427,7 +434,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
if (!sb->s_root)
goto bail_iput;
- sb->s_root->d_op = &hfs_dentry_operations;
+ d_set_d_op(sb->s_root, &hfs_dentry_operations);
/* everything's okay */
return 0;
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c
index d182438c7ae4..5d799c13205f 100644
--- a/fs/hfsplus/bfind.c
+++ b/fs/hfsplus/bfind.c
@@ -22,7 +22,8 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
return -ENOMEM;
fd->search_key = ptr;
fd->key = ptr + tree->max_key_len + 2;
- dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0));
+ dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n",
+ tree->cnid, __builtin_return_address(0));
mutex_lock(&tree->tree_lock);
return 0;
}
@@ -31,7 +32,8 @@ void hfs_find_exit(struct hfs_find_data *fd)
{
hfs_bnode_put(fd->bnode);
kfree(fd->search_key);
- dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0));
+ dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n",
+ fd->tree->cnid, __builtin_return_address(0));
mutex_unlock(&fd->tree->tree_lock);
fd->tree = NULL;
}
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index ad57f5991eb1..1cad80c789cb 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -15,7 +15,8 @@
#define PAGE_CACHE_BITS (PAGE_CACHE_SIZE * 8)
-int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *max)
+int hfsplus_block_allocate(struct super_block *sb, u32 size,
+ u32 offset, u32 *max)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
struct page *page;
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 29da6574ba77..1c42cc5b899f 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -42,7 +42,7 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
{
__be16 data;
- // optimize later...
+ /* TODO: optimize later... */
hfs_bnode_read(node, &data, off, 2);
return be16_to_cpu(data);
}
@@ -50,7 +50,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
{
u8 data;
- // optimize later...
+ /* TODO: optimize later... */
hfs_bnode_read(node, &data, off, 1);
return data;
}
@@ -96,7 +96,7 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
{
__be16 v = cpu_to_be16(data);
- // optimize later...
+ /* TODO: optimize later... */
hfs_bnode_write(node, &v, off, 2);
}
@@ -212,7 +212,8 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
dst_page--;
}
src -= len;
- memmove(kmap(*dst_page) + src, kmap(*src_page) + src, len);
+ memmove(kmap(*dst_page) + src,
+ kmap(*src_page) + src, len);
kunmap(*src_page);
set_page_dirty(*dst_page);
kunmap(*dst_page);
@@ -250,14 +251,16 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
if (src == dst) {
l = min(len, (int)PAGE_CACHE_SIZE - src);
- memmove(kmap(*dst_page) + src, kmap(*src_page) + src, l);
+ memmove(kmap(*dst_page) + src,
+ kmap(*src_page) + src, l);
kunmap(*src_page);
set_page_dirty(*dst_page);
kunmap(*dst_page);
while ((len -= l) != 0) {
l = min(len, (int)PAGE_CACHE_SIZE);
- memmove(kmap(*++dst_page), kmap(*++src_page), l);
+ memmove(kmap(*++dst_page),
+ kmap(*++src_page), l);
kunmap(*src_page);
set_page_dirty(*dst_page);
kunmap(*dst_page);
@@ -268,7 +271,8 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
do {
src_ptr = kmap(*src_page) + src;
dst_ptr = kmap(*dst_page) + dst;
- if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) {
+ if (PAGE_CACHE_SIZE - src <
+ PAGE_CACHE_SIZE - dst) {
l = PAGE_CACHE_SIZE - src;
src = 0;
dst += l;
@@ -340,7 +344,8 @@ void hfs_bnode_unlink(struct hfs_bnode *node)
return;
tmp->next = node->next;
cnid = cpu_to_be32(tmp->next);
- hfs_bnode_write(tmp, &cnid, offsetof(struct hfs_bnode_desc, next), 4);
+ hfs_bnode_write(tmp, &cnid,
+ offsetof(struct hfs_bnode_desc, next), 4);
hfs_bnode_put(tmp);
} else if (node->type == HFS_NODE_LEAF)
tree->leaf_head = node->next;
@@ -351,15 +356,15 @@ void hfs_bnode_unlink(struct hfs_bnode *node)
return;
tmp->prev = node->prev;
cnid = cpu_to_be32(tmp->prev);
- hfs_bnode_write(tmp, &cnid, offsetof(struct hfs_bnode_desc, prev), 4);
+ hfs_bnode_write(tmp, &cnid,
+ offsetof(struct hfs_bnode_desc, prev), 4);
hfs_bnode_put(tmp);
} else if (node->type == HFS_NODE_LEAF)
tree->leaf_tail = node->prev;
- // move down?
- if (!node->prev && !node->next) {
- printk(KERN_DEBUG "hfs_btree_del_level\n");
- }
+ /* move down? */
+ if (!node->prev && !node->next)
+ dprint(DBG_BNODE_MOD, "hfs_btree_del_level\n");
if (!node->parent) {
tree->root = 0;
tree->depth = 0;
@@ -379,16 +384,16 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid)
struct hfs_bnode *node;
if (cnid >= tree->node_count) {
- printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
+ printk(KERN_ERR "hfs: request for non-existent node "
+ "%d in B*Tree\n",
+ cnid);
return NULL;
}
for (node = tree->node_hash[hfs_bnode_hash(cnid)];
- node; node = node->next_hash) {
- if (node->this == cnid) {
+ node; node = node->next_hash)
+ if (node->this == cnid)
return node;
- }
- }
return NULL;
}
@@ -402,7 +407,9 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
loff_t off;
if (cnid >= tree->node_count) {
- printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
+ printk(KERN_ERR "hfs: request for non-existent node "
+ "%d in B*Tree\n",
+ cnid);
return NULL;
}
@@ -429,7 +436,8 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
} else {
spin_unlock(&tree->hash_lock);
kfree(node);
- wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags));
+ wait_event(node2->lock_wq,
+ !test_bit(HFS_BNODE_NEW, &node2->flags));
return node2;
}
spin_unlock(&tree->hash_lock);
@@ -483,7 +491,8 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num)
if (node) {
hfs_bnode_get(node);
spin_unlock(&tree->hash_lock);
- wait_event(node->lock_wq, !test_bit(HFS_BNODE_NEW, &node->flags));
+ wait_event(node->lock_wq,
+ !test_bit(HFS_BNODE_NEW, &node->flags));
if (test_bit(HFS_BNODE_ERROR, &node->flags))
goto node_error;
return node;
@@ -497,7 +506,8 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num)
if (!test_bit(HFS_BNODE_NEW, &node->flags))
return node;
- desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + node->page_offset);
+ desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) +
+ node->page_offset);
node->prev = be32_to_cpu(desc->prev);
node->next = be32_to_cpu(desc->next);
node->num_recs = be16_to_cpu(desc->num_recs);
@@ -556,11 +566,13 @@ node_error:
void hfs_bnode_free(struct hfs_bnode *node)
{
- //int i;
+#if 0
+ int i;
- //for (i = 0; i < node->tree->pages_per_bnode; i++)
- // if (node->page[i])
- // page_cache_release(node->page[i]);
+ for (i = 0; i < node->tree->pages_per_bnode; i++)
+ if (node->page[i])
+ page_cache_release(node->page[i]);
+#endif
kfree(node);
}
@@ -607,7 +619,8 @@ void hfs_bnode_get(struct hfs_bnode *node)
if (node) {
atomic_inc(&node->refcnt);
dprint(DBG_BNODE_REFS, "get_node(%d:%d): %d\n",
- node->tree->cnid, node->this, atomic_read(&node->refcnt));
+ node->tree->cnid, node->this,
+ atomic_read(&node->refcnt));
}
}
@@ -619,7 +632,8 @@ void hfs_bnode_put(struct hfs_bnode *node)
int i;
dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n",
- node->tree->cnid, node->this, atomic_read(&node->refcnt));
+ node->tree->cnid, node->this,
+ atomic_read(&node->refcnt));
BUG_ON(!atomic_read(&node->refcnt));
if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock))
return;
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c
index 2f39d05443e1..2312de34bd42 100644
--- a/fs/hfsplus/brec.c
+++ b/fs/hfsplus/brec.c
@@ -39,7 +39,8 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec)
!(node->tree->attributes & HFS_TREE_VARIDXKEYS)) {
retval = node->tree->max_key_len + 2;
} else {
- recoff = hfs_bnode_read_u16(node, node->tree->node_size - (rec + 1) * 2);
+ recoff = hfs_bnode_read_u16(node,
+ node->tree->node_size - (rec + 1) * 2);
if (!recoff)
return 0;
@@ -84,7 +85,8 @@ again:
end_rec_off = tree->node_size - (node->num_recs + 1) * 2;
end_off = hfs_bnode_read_u16(node, end_rec_off);
end_rec_off -= 2;
- dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", rec, size, end_off, end_rec_off);
+ dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n",
+ rec, size, end_off, end_rec_off);
if (size > end_rec_off - end_off) {
if (new_node)
panic("not enough room!\n");
@@ -99,7 +101,9 @@ again:
}
node->num_recs++;
/* write new last offset */
- hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs);
+ hfs_bnode_write_u16(node,
+ offsetof(struct hfs_bnode_desc, num_recs),
+ node->num_recs);
hfs_bnode_write_u16(node, end_rec_off, end_off + size);
data_off = end_off;
data_rec_off = end_rec_off + 2;
@@ -151,7 +155,8 @@ skip:
if (tree->attributes & HFS_TREE_VARIDXKEYS)
key_len = be16_to_cpu(fd->search_key->key_len) + 2;
else {
- fd->search_key->key_len = cpu_to_be16(tree->max_key_len);
+ fd->search_key->key_len =
+ cpu_to_be16(tree->max_key_len);
key_len = tree->max_key_len + 2;
}
goto again;
@@ -180,7 +185,8 @@ again:
mark_inode_dirty(tree->inode);
}
hfs_bnode_dump(node);
- dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", fd->record, fd->keylength + fd->entrylength);
+ dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n",
+ fd->record, fd->keylength + fd->entrylength);
if (!--node->num_recs) {
hfs_bnode_unlink(node);
if (!node->parent)
@@ -194,7 +200,9 @@ again:
__hfs_brec_find(node, fd);
goto again;
}
- hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs);
+ hfs_bnode_write_u16(node,
+ offsetof(struct hfs_bnode_desc, num_recs),
+ node->num_recs);
if (rec_off == end_off)
goto skip;
@@ -364,7 +372,8 @@ again:
newkeylen = hfs_bnode_read_u16(node, 14) + 2;
else
fd->keylength = newkeylen = tree->max_key_len + 2;
- dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", rec, fd->keylength, newkeylen);
+ dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n",
+ rec, fd->keylength, newkeylen);
rec_off = tree->node_size - (rec + 2) * 2;
end_rec_off = tree->node_size - (parent->num_recs + 1) * 2;
@@ -375,7 +384,7 @@ again:
end_off = hfs_bnode_read_u16(parent, end_rec_off);
if (end_rec_off - end_off < diff) {
- printk(KERN_DEBUG "hfs: splitting index node...\n");
+ dprint(DBG_BNODE_MOD, "hfs: splitting index node.\n");
fd->bnode = parent;
new_node = hfs_bnode_split(fd);
if (IS_ERR(new_node))
@@ -383,7 +392,8 @@ again:
parent = fd->bnode;
rec = fd->record;
rec_off = tree->node_size - (rec + 2) * 2;
- end_rec_off = tree->node_size - (parent->num_recs + 1) * 2;
+ end_rec_off = tree->node_size -
+ (parent->num_recs + 1) * 2;
}
}
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index 22e4d4e32999..21023d9f8ff3 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -51,7 +51,8 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
goto free_inode;
/* Load the header */
- head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc));
+ head = (struct hfs_btree_header_rec *)(kmap(page) +
+ sizeof(struct hfs_bnode_desc));
tree->root = be32_to_cpu(head->root);
tree->leaf_count = be32_to_cpu(head->leaf_count);
tree->leaf_head = be32_to_cpu(head->leaf_head);
@@ -115,7 +116,9 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
tree->node_size_shift = ffs(size) - 1;
- tree->pages_per_bnode = (tree->node_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ tree->pages_per_bnode =
+ (tree->node_size + PAGE_CACHE_SIZE - 1) >>
+ PAGE_CACHE_SHIFT;
kunmap(page);
page_cache_release(page);
@@ -144,8 +147,10 @@ void hfs_btree_close(struct hfs_btree *tree)
while ((node = tree->node_hash[i])) {
tree->node_hash[i] = node->next_hash;
if (atomic_read(&node->refcnt))
- printk(KERN_CRIT "hfs: node %d:%d still has %d user(s)!\n",
- node->tree->cnid, node->this, atomic_read(&node->refcnt));
+ printk(KERN_CRIT "hfs: node %d:%d "
+ "still has %d user(s)!\n",
+ node->tree->cnid, node->this,
+ atomic_read(&node->refcnt));
hfs_bnode_free(node);
tree->node_hash_cnt--;
}
@@ -166,7 +171,8 @@ void hfs_btree_write(struct hfs_btree *tree)
return;
/* Load the header */
page = node->page[0];
- head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc));
+ head = (struct hfs_btree_header_rec *)(kmap(page) +
+ sizeof(struct hfs_bnode_desc));
head->root = cpu_to_be32(tree->root);
head->leaf_count = cpu_to_be32(tree->leaf_count);
@@ -272,7 +278,8 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
tree->free_nodes--;
mark_inode_dirty(tree->inode);
hfs_bnode_put(node);
- return hfs_bnode_create(tree, idx);
+ return hfs_bnode_create(tree,
+ idx);
}
}
}
@@ -287,7 +294,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
kunmap(*pagep);
nidx = node->next;
if (!nidx) {
- printk(KERN_DEBUG "hfs: create new bmap node...\n");
+ dprint(DBG_BNODE_MOD, "hfs: create new bmap node.\n");
next_node = hfs_bmap_new_bmap(node, idx);
} else
next_node = hfs_bnode_find(tree, nidx);
@@ -329,7 +336,9 @@ void hfs_bmap_free(struct hfs_bnode *node)
hfs_bnode_put(node);
if (!i) {
/* panic */;
- printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this);
+ printk(KERN_CRIT "hfs: unable to free bnode %u. "
+ "bmap not found!\n",
+ node->this);
return;
}
node = hfs_bnode_find(tree, i);
@@ -337,7 +346,9 @@ void hfs_bmap_free(struct hfs_bnode *node)
return;
if (node->type != HFS_NODE_MAP) {
/* panic */;
- printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type);
+ printk(KERN_CRIT "hfs: invalid bmap found! "
+ "(%u,%d)\n",
+ node->this, node->type);
hfs_bnode_put(node);
return;
}
@@ -350,7 +361,9 @@ void hfs_bmap_free(struct hfs_bnode *node)
m = 1 << (~nidx & 7);
byte = data[off];
if (!(byte & m)) {
- printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type);
+ printk(KERN_CRIT "hfs: trying to free free bnode "
+ "%u(%d)\n",
+ node->this, node->type);
kunmap(page);
hfs_bnode_put(node);
return;
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index 8af45fc5b051..b4ba1b319333 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -91,7 +91,8 @@ void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms)
perms->dev = 0;
}
-static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode)
+static int hfsplus_cat_build_record(hfsplus_cat_entry *entry,
+ u32 cnid, struct inode *inode)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
@@ -128,20 +129,32 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i
if (cnid == inode->i_ino) {
hfsplus_cat_set_perms(inode, &file->permissions);
if (S_ISLNK(inode->i_mode)) {
- file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE);
- file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR);
+ file->user_info.fdType =
+ cpu_to_be32(HFSP_SYMLINK_TYPE);
+ file->user_info.fdCreator =
+ cpu_to_be32(HFSP_SYMLINK_CREATOR);
} else {
- file->user_info.fdType = cpu_to_be32(sbi->type);
- file->user_info.fdCreator = cpu_to_be32(sbi->creator);
+ file->user_info.fdType =
+ cpu_to_be32(sbi->type);
+ file->user_info.fdCreator =
+ cpu_to_be32(sbi->creator);
}
- if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE)
- file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
+ if (HFSPLUS_FLG_IMMUTABLE &
+ (file->permissions.rootflags |
+ file->permissions.userflags))
+ file->flags |=
+ cpu_to_be16(HFSPLUS_FILE_LOCKED);
} else {
- file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE);
- file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR);
- file->user_info.fdFlags = cpu_to_be16(0x100);
- file->create_date = HFSPLUS_I(sbi->hidden_dir)->create_date;
- file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode)->linkid);
+ file->user_info.fdType =
+ cpu_to_be32(HFSP_HARDLINK_TYPE);
+ file->user_info.fdCreator =
+ cpu_to_be32(HFSP_HFSPLUS_CREATOR);
+ file->user_info.fdFlags =
+ cpu_to_be16(0x100);
+ file->create_date =
+ HFSPLUS_I(sbi->hidden_dir)->create_date;
+ file->permissions.dev =
+ cpu_to_be32(HFSPLUS_I(inode)->linkid);
}
return sizeof(*file);
}
@@ -182,12 +195,14 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
return -EIO;
}
- hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
- &tmp.thread.nodeName);
+ hfsplus_cat_build_key_uni(fd->search_key,
+ be32_to_cpu(tmp.thread.parentID),
+ &tmp.thread.nodeName);
return hfs_brec_find(fd);
}
-int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct inode *inode)
+int hfsplus_create_cat(u32 cnid, struct inode *dir,
+ struct qstr *str, struct inode *inode)
{
struct super_block *sb = dir->i_sb;
struct hfs_find_data fd;
@@ -195,13 +210,15 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct ino
int entry_size;
int err;
- dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", str->name, cnid, inode->i_nlink);
+ dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n",
+ str->name, cnid, inode->i_nlink);
hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL);
- entry_size = hfsplus_fill_cat_thread(sb, &entry, S_ISDIR(inode->i_mode) ?
+ entry_size = hfsplus_fill_cat_thread(sb, &entry,
+ S_ISDIR(inode->i_mode) ?
HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD,
- dir->i_ino, str);
+ dir->i_ino, str);
err = hfs_brec_find(&fd);
if (err != -ENOENT) {
if (!err)
@@ -227,7 +244,8 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct ino
dir->i_size++;
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(dir);
+ hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY);
+
hfs_find_exit(&fd);
return 0;
@@ -249,7 +267,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
int err, off;
u16 type;
- dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid);
+ dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n",
+ str ? str->name : NULL, cnid);
hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
if (!str) {
@@ -260,11 +279,15 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
if (err)
goto out;
- off = fd.entryoffset + offsetof(struct hfsplus_cat_thread, nodeName);
+ off = fd.entryoffset +
+ offsetof(struct hfsplus_cat_thread, nodeName);
fd.search_key->cat.parent = cpu_to_be32(dir->i_ino);
- hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.length, off, 2);
+ hfs_bnode_read(fd.bnode,
+ &fd.search_key->cat.name.length, off, 2);
len = be16_to_cpu(fd.search_key->cat.name.length) * 2;
- hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.unicode, off + 2, len);
+ hfs_bnode_read(fd.bnode,
+ &fd.search_key->cat.name.unicode,
+ off + 2, len);
fd.search_key->key_len = cpu_to_be16(6 + len);
} else
hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str);
@@ -281,7 +304,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_DATA);
#endif
- off = fd.entryoffset + offsetof(struct hfsplus_cat_file, rsrc_fork);
+ off = fd.entryoffset +
+ offsetof(struct hfsplus_cat_file, rsrc_fork);
hfs_bnode_read(fd.bnode, &fork, off, sizeof(fork));
hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_RSRC);
}
@@ -308,7 +332,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
dir->i_size--;
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(dir);
+ hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY);
out:
hfs_find_exit(&fd);
@@ -325,7 +349,8 @@ int hfsplus_rename_cat(u32 cnid,
int entry_size, type;
int err = 0;
- dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name,
+ dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n",
+ cnid, src_dir->i_ino, src_name->name,
dst_dir->i_ino, dst_name->name);
hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd);
dst_fd = src_fd;
@@ -353,7 +378,6 @@ int hfsplus_rename_cat(u32 cnid,
goto out;
dst_dir->i_size++;
dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(dst_dir);
/* finally remove the old entry */
hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
@@ -365,7 +389,6 @@ int hfsplus_rename_cat(u32 cnid,
goto out;
src_dir->i_size--;
src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(src_dir);
/* remove old thread entry */
hfsplus_cat_build_key(sb, src_fd.search_key, cnid, NULL);
@@ -379,7 +402,8 @@ int hfsplus_rename_cat(u32 cnid,
/* create new thread entry */
hfsplus_cat_build_key(sb, dst_fd.search_key, cnid, NULL);
- entry_size = hfsplus_fill_cat_thread(sb, &entry, type, dst_dir->i_ino, dst_name);
+ entry_size = hfsplus_fill_cat_thread(sb, &entry, type,
+ dst_dir->i_ino, dst_name);
err = hfs_brec_find(&dst_fd);
if (err != -ENOENT) {
if (!err)
@@ -387,6 +411,9 @@ int hfsplus_rename_cat(u32 cnid,
goto out;
}
err = hfs_brec_insert(&dst_fd, &entry, entry_size);
+
+ hfsplus_mark_inode_dirty(dst_dir, HFSPLUS_I_CAT_DIRTY);
+ hfsplus_mark_inode_dirty(src_dir, HFSPLUS_I_CAT_DIRTY);
out:
hfs_bnode_put(dst_fd.bnode);
hfs_find_exit(&src_fd);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 9d59c0571f59..f896dc843026 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -37,7 +37,7 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry,
sb = dir->i_sb;
- dentry->d_op = &hfsplus_dentry_operations;
+ d_set_d_op(dentry, &hfsplus_dentry_operations);
dentry->d_fsdata = NULL;
hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name);
@@ -66,11 +66,17 @@ again:
goto fail;
}
cnid = be32_to_cpu(entry.file.id);
- if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) &&
- entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR) &&
- (entry.file.create_date == HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)->create_date ||
- entry.file.create_date == HFSPLUS_I(sb->s_root->d_inode)->create_date) &&
- HFSPLUS_SB(sb)->hidden_dir) {
+ if (entry.file.user_info.fdType ==
+ cpu_to_be32(HFSP_HARDLINK_TYPE) &&
+ entry.file.user_info.fdCreator ==
+ cpu_to_be32(HFSP_HFSPLUS_CREATOR) &&
+ (entry.file.create_date ==
+ HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)->
+ create_date ||
+ entry.file.create_date ==
+ HFSPLUS_I(sb->s_root->d_inode)->
+ create_date) &&
+ HFSPLUS_SB(sb)->hidden_dir) {
struct qstr str;
char name[32];
@@ -83,11 +89,13 @@ again:
linkid = 0;
} else {
dentry->d_fsdata = (void *)(unsigned long)cnid;
- linkid = be32_to_cpu(entry.file.permissions.dev);
+ linkid =
+ be32_to_cpu(entry.file.permissions.dev);
str.len = sprintf(name, "iNode%d", linkid);
str.name = name;
hfsplus_cat_build_key(sb, fd.search_key,
- HFSPLUS_SB(sb)->hidden_dir->i_ino, &str);
+ HFSPLUS_SB(sb)->hidden_dir->i_ino,
+ &str);
goto again;
}
} else if (!dentry->d_fsdata)
@@ -139,7 +147,8 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
filp->f_pos++;
/* fall through */
case 1:
- hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ fd.entrylength);
if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) {
printk(KERN_ERR "hfs: bad catalog folder thread\n");
err = -EIO;
@@ -169,14 +178,16 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
err = -EIO;
goto out;
}
- hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ fd.entrylength);
type = be16_to_cpu(entry.type);
len = HFSPLUS_MAX_STRLEN;
err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len);
if (err)
goto out;
if (type == HFSPLUS_FOLDER) {
- if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
+ if (fd.entrylength <
+ sizeof(struct hfsplus_cat_folder)) {
printk(KERN_ERR "hfs: small dir entry\n");
err = -EIO;
goto out;
@@ -202,7 +213,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
err = -EIO;
goto out;
}
- next:
+next:
filp->f_pos++;
if (filp->f_pos >= inode->i_size)
goto out;
@@ -273,7 +284,8 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
HFSPLUS_I(inode)->linkid = id;
cnid = sbi->next_cnid++;
src_dentry->d_fsdata = (void *)(unsigned long)cnid;
- res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode);
+ res = hfsplus_create_cat(cnid, src_dir,
+ &src_dentry->d_name, inode);
if (res)
/* panic? */
goto out;
@@ -485,6 +497,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
};
const struct file_operations hfsplus_dir_operations = {
+ .fsync = hfsplus_file_fsync,
.read = generic_read_dir,
.readdir = hfsplus_readdir,
.unlocked_ioctl = hfsplus_ioctl,
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index 0c9cb1820a52..52a0bcaa7b6d 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -83,7 +83,8 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext)
return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count);
}
-static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data *fd)
+static void __hfsplus_ext_write_extent(struct inode *inode,
+ struct hfs_find_data *fd)
{
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
@@ -95,24 +96,32 @@ static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data
HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
res = hfs_brec_find(fd);
- if (hip->flags & HFSPLUS_FLG_EXT_NEW) {
+ if (hip->extent_state & HFSPLUS_EXT_NEW) {
if (res != -ENOENT)
return;
hfs_brec_insert(fd, hip->cached_extents,
sizeof(hfsplus_extent_rec));
- hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW);
+ hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
} else {
if (res)
return;
hfs_bnode_write(fd->bnode, hip->cached_extents,
fd->entryoffset, fd->entrylength);
- hip->flags &= ~HFSPLUS_FLG_EXT_DIRTY;
+ hip->extent_state &= ~HFSPLUS_EXT_DIRTY;
}
+
+ /*
+ * We can't just use hfsplus_mark_inode_dirty here, because we
+ * also get called from hfsplus_write_inode, which should not
+ * redirty the inode. Instead the callers have to be careful
+ * to explicily mark the inode dirty, too.
+ */
+ set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags);
}
static void hfsplus_ext_write_extent_locked(struct inode *inode)
{
- if (HFSPLUS_I(inode)->flags & HFSPLUS_FLG_EXT_DIRTY) {
+ if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) {
struct hfs_find_data fd;
hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd);
@@ -144,18 +153,20 @@ static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd,
return -ENOENT;
if (fd->entrylength != sizeof(hfsplus_extent_rec))
return -EIO;
- hfs_bnode_read(fd->bnode, extent, fd->entryoffset, sizeof(hfsplus_extent_rec));
+ hfs_bnode_read(fd->bnode, extent, fd->entryoffset,
+ sizeof(hfsplus_extent_rec));
return 0;
}
-static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct inode *inode, u32 block)
+static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd,
+ struct inode *inode, u32 block)
{
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
WARN_ON(!mutex_is_locked(&hip->extents_lock));
- if (hip->flags & HFSPLUS_FLG_EXT_DIRTY)
+ if (hip->extent_state & HFSPLUS_EXT_DIRTY)
__hfsplus_ext_write_extent(inode, fd);
res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino,
@@ -164,10 +175,11 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct in
HFSPLUS_TYPE_DATA);
if (!res) {
hip->cached_start = be32_to_cpu(fd->key->ext.start_block);
- hip->cached_blocks = hfsplus_ext_block_count(hip->cached_extents);
+ hip->cached_blocks =
+ hfsplus_ext_block_count(hip->cached_extents);
} else {
hip->cached_start = hip->cached_blocks = 0;
- hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW);
+ hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
}
return res;
}
@@ -197,6 +209,7 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res = -EIO;
u32 ablock, dblock, mask;
+ int was_dirty = 0;
int shift;
/* Convert inode block to disk allocation block */
@@ -223,27 +236,37 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
return -EIO;
mutex_lock(&hip->extents_lock);
+
+ /*
+ * hfsplus_ext_read_extent will write out a cached extent into
+ * the extents btree. In that case we may have to mark the inode
+ * dirty even for a pure read of an extent here.
+ */
+ was_dirty = (hip->extent_state & HFSPLUS_EXT_DIRTY);
res = hfsplus_ext_read_extent(inode, ablock);
- if (!res) {
- dblock = hfsplus_ext_find_block(hip->cached_extents,
- ablock - hip->cached_start);
- } else {
+ if (res) {
mutex_unlock(&hip->extents_lock);
return -EIO;
}
+ dblock = hfsplus_ext_find_block(hip->cached_extents,
+ ablock - hip->cached_start);
mutex_unlock(&hip->extents_lock);
done:
- dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", inode->i_ino, (long long)iblock, dblock);
+ dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n",
+ inode->i_ino, (long long)iblock, dblock);
mask = (1 << sbi->fs_shift) - 1;
- map_bh(bh_result, sb, (dblock << sbi->fs_shift) + sbi->blockoffset + (iblock & mask));
+ map_bh(bh_result, sb,
+ (dblock << sbi->fs_shift) + sbi->blockoffset +
+ (iblock & mask));
if (create) {
set_buffer_new(bh_result);
hip->phys_size += sb->s_blocksize;
hip->fs_blocks++;
inode_add_bytes(inode, sb->s_blocksize);
- mark_inode_dirty(inode);
}
+ if (create || was_dirty)
+ mark_inode_dirty(inode);
return 0;
}
@@ -326,7 +349,8 @@ found:
}
}
-int hfsplus_free_fork(struct super_block *sb, u32 cnid, struct hfsplus_fork_raw *fork, int type)
+int hfsplus_free_fork(struct super_block *sb, u32 cnid,
+ struct hfsplus_fork_raw *fork, int type)
{
struct hfs_find_data fd;
hfsplus_extent_rec ext_entry;
@@ -373,12 +397,13 @@ int hfsplus_file_extend(struct inode *inode)
u32 start, len, goal;
int res;
- if (sbi->alloc_file->i_size * 8 <
- sbi->total_blocks - sbi->free_blocks + 8) {
- // extend alloc file
- printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n",
- sbi->alloc_file->i_size * 8,
- sbi->total_blocks, sbi->free_blocks);
+ if (sbi->total_blocks - sbi->free_blocks + 8 >
+ sbi->alloc_file->i_size * 8) {
+ /* extend alloc file */
+ printk(KERN_ERR "hfs: extend alloc file! "
+ "(%llu,%u,%u)\n",
+ sbi->alloc_file->i_size * 8,
+ sbi->total_blocks, sbi->free_blocks);
return -ENOSPC;
}
@@ -429,7 +454,7 @@ int hfsplus_file_extend(struct inode *inode)
start, len);
if (!res) {
hfsplus_dump_extent(hip->cached_extents);
- hip->flags |= HFSPLUS_FLG_EXT_DIRTY;
+ hip->extent_state |= HFSPLUS_EXT_DIRTY;
hip->cached_blocks += len;
} else if (res == -ENOSPC)
goto insert_extent;
@@ -438,7 +463,7 @@ out:
mutex_unlock(&hip->extents_lock);
if (!res) {
hip->alloc_blocks += len;
- mark_inode_dirty(inode);
+ hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY);
}
return res;
@@ -450,7 +475,7 @@ insert_extent:
hip->cached_extents[0].start_block = cpu_to_be32(start);
hip->cached_extents[0].block_count = cpu_to_be32(len);
hfsplus_dump_extent(hip->cached_extents);
- hip->flags |= HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW;
+ hip->extent_state |= HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW;
hip->cached_start = hip->alloc_blocks;
hip->cached_blocks = len;
@@ -466,8 +491,9 @@ void hfsplus_file_truncate(struct inode *inode)
u32 alloc_cnt, blk_cnt, start;
int res;
- dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n",
- inode->i_ino, (long long)hip->phys_size, inode->i_size);
+ dprint(DBG_INODE, "truncate: %lu, %llu -> %llu\n",
+ inode->i_ino, (long long)hip->phys_size,
+ inode->i_size);
if (inode->i_size > hip->phys_size) {
struct address_space *mapping = inode->i_mapping;
@@ -481,7 +507,8 @@ void hfsplus_file_truncate(struct inode *inode)
&page, &fsdata);
if (res)
return;
- res = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata);
+ res = pagecache_write_end(NULL, mapping, size,
+ 0, 0, page, fsdata);
if (res < 0)
return;
mark_inode_dirty(inode);
@@ -513,12 +540,12 @@ void hfsplus_file_truncate(struct inode *inode)
alloc_cnt - start, alloc_cnt - blk_cnt);
hfsplus_dump_extent(hip->cached_extents);
if (blk_cnt > start) {
- hip->flags |= HFSPLUS_FLG_EXT_DIRTY;
+ hip->extent_state |= HFSPLUS_EXT_DIRTY;
break;
}
alloc_cnt = start;
hip->cached_start = hip->cached_blocks = 0;
- hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW);
+ hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
hfs_brec_remove(&fd);
}
hfs_find_exit(&fd);
@@ -527,7 +554,8 @@ void hfsplus_file_truncate(struct inode *inode)
hip->alloc_blocks = blk_cnt;
out:
hip->phys_size = inode->i_size;
- hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
+ hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >>
+ sb->s_blocksize_bits;
inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits);
- mark_inode_dirty(inode);
+ hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY);
}
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index cb3653efb57a..52f4a78455fe 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -23,13 +23,16 @@
#define DBG_EXTENT 0x00000020
#define DBG_BITMAP 0x00000040
-//#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
-//#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE)
-//#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT)
+#if 0
+#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
+#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE)
+#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT)
+#endif
#define DBG_MASK (0)
#define dprint(flg, fmt, args...) \
- if (flg & DBG_MASK) printk(fmt , ## args)
+ if (flg & DBG_MASK) \
+ printk(fmt , ## args)
/* Runtime config options */
#define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */
@@ -37,7 +40,8 @@
#define HFSPLUS_TYPE_DATA 0x00
#define HFSPLUS_TYPE_RSRC 0xFF
-typedef int (*btree_keycmp)(const hfsplus_btree_key *, const hfsplus_btree_key *);
+typedef int (*btree_keycmp)(const hfsplus_btree_key *,
+ const hfsplus_btree_key *);
#define NODE_HASH_SIZE 256
@@ -61,7 +65,6 @@ struct hfs_btree {
unsigned int max_key_len;
unsigned int depth;
- //unsigned int map1_size, map_size;
struct mutex tree_lock;
unsigned int pages_per_bnode;
@@ -107,8 +110,8 @@ struct hfsplus_vh;
struct hfs_btree;
struct hfsplus_sb_info {
- struct buffer_head *s_vhbh;
struct hfsplus_vh *s_vhdr;
+ struct hfsplus_vh *s_backup_vhdr;
struct hfs_btree *ext_tree;
struct hfs_btree *cat_tree;
struct hfs_btree *attr_tree;
@@ -118,7 +121,8 @@ struct hfsplus_sb_info {
/* Runtime variables */
u32 blockoffset;
- u32 sect_count;
+ sector_t part_start;
+ sector_t sect_count;
int fs_shift;
/* immutable data from the volume header */
@@ -155,6 +159,12 @@ struct hfsplus_sb_info {
#define HFSPLUS_SB_FORCE 2
#define HFSPLUS_SB_HFSX 3
#define HFSPLUS_SB_CASEFOLD 4
+#define HFSPLUS_SB_NOBARRIER 5
+
+static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
struct hfsplus_inode_info {
@@ -170,7 +180,7 @@ struct hfsplus_inode_info {
u32 cached_blocks;
hfsplus_extent_rec first_extents;
hfsplus_extent_rec cached_extents;
- unsigned long flags;
+ unsigned int extent_state;
struct mutex extents_lock;
/*
@@ -185,6 +195,11 @@ struct hfsplus_inode_info {
u32 linkid;
/*
+ * Accessed using atomic bitops.
+ */
+ unsigned long flags;
+
+ /*
* Protected by i_mutex.
*/
sector_t fs_blocks;
@@ -195,12 +210,34 @@ struct hfsplus_inode_info {
struct inode vfs_inode;
};
-#define HFSPLUS_FLG_RSRC 0x0001
-#define HFSPLUS_FLG_EXT_DIRTY 0x0002
-#define HFSPLUS_FLG_EXT_NEW 0x0004
+#define HFSPLUS_EXT_DIRTY 0x0001
+#define HFSPLUS_EXT_NEW 0x0002
+
+#define HFSPLUS_I_RSRC 0 /* represents a resource fork */
+#define HFSPLUS_I_CAT_DIRTY 1 /* has changes in the catalog tree */
+#define HFSPLUS_I_EXT_DIRTY 2 /* has changes in the extent tree */
+#define HFSPLUS_I_ALLOC_DIRTY 3 /* has changes in the allocation file */
+
+#define HFSPLUS_IS_RSRC(inode) \
+ test_bit(HFSPLUS_I_RSRC, &HFSPLUS_I(inode)->flags)
+
+static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode)
+{
+ return list_entry(inode, struct hfsplus_inode_info, vfs_inode);
+}
-#define HFSPLUS_IS_DATA(inode) (!(HFSPLUS_I(inode)->flags & HFSPLUS_FLG_RSRC))
-#define HFSPLUS_IS_RSRC(inode) (HFSPLUS_I(inode)->flags & HFSPLUS_FLG_RSRC)
+/*
+ * Mark an inode dirty, and also mark the btree in which the
+ * specific type of metadata is stored.
+ * For data or metadata that gets written back by into the catalog btree
+ * by hfsplus_write_inode a plain mark_inode_dirty call is enough.
+ */
+static inline void hfsplus_mark_inode_dirty(struct inode *inode,
+ unsigned int flag)
+{
+ set_bit(flag, &HFSPLUS_I(inode)->flags);
+ mark_inode_dirty(inode);
+}
struct hfs_find_data {
/* filled by caller */
@@ -318,9 +355,12 @@ int hfs_brec_read(struct hfs_find_data *, void *, int);
int hfs_brec_goto(struct hfs_find_data *, int);
/* catalog.c */
-int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
-int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
-void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *);
+int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *,
+ const hfsplus_btree_key *);
+int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *,
+ const hfsplus_btree_key *);
+void hfsplus_cat_build_key(struct super_block *sb,
+ hfsplus_btree_key *, u32, struct qstr *);
int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *);
int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
int hfsplus_delete_cat(u32, struct inode *, struct qstr *);
@@ -336,7 +376,8 @@ extern const struct file_operations hfsplus_dir_operations;
int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
void hfsplus_ext_write_extent(struct inode *);
int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int);
-int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int);
+int hfsplus_free_fork(struct super_block *, u32,
+ struct hfsplus_fork_raw *, int);
int hfsplus_file_extend(struct inode *);
void hfsplus_file_truncate(struct inode *);
@@ -351,6 +392,7 @@ int hfsplus_cat_read_inode(struct inode *, struct hfs_find_data *);
int hfsplus_cat_write_inode(struct inode *);
struct inode *hfsplus_new_inode(struct super_block *, int);
void hfsplus_delete_inode(struct inode *);
+int hfsplus_file_fsync(struct file *file, int datasync);
/* ioctl.c */
long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
@@ -362,6 +404,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
/* options.c */
int hfsplus_parse_options(char *, struct hfsplus_sb_info *);
+int hfsplus_parse_options_remount(char *input, int *force);
void hfsplus_fill_defaults(struct hfsplus_sb_info *);
int hfsplus_show_options(struct seq_file *, struct vfsmount *);
@@ -375,45 +418,26 @@ extern u16 hfsplus_decompose_table[];
extern u16 hfsplus_compose_table[];
/* unicode.c */
-int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
-int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
-int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *);
-int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int);
-int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str);
-int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2);
+int hfsplus_strcasecmp(const struct hfsplus_unistr *,
+ const struct hfsplus_unistr *);
+int hfsplus_strcmp(const struct hfsplus_unistr *,
+ const struct hfsplus_unistr *);
+int hfsplus_uni2asc(struct super_block *,
+ const struct hfsplus_unistr *, char *, int *);
+int hfsplus_asc2uni(struct super_block *,
+ struct hfsplus_unistr *, const char *, int);
+int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *str);
+int hfsplus_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
/* wrapper.c */
int hfsplus_read_wrapper(struct super_block *);
-
int hfs_part_find(struct super_block *, sector_t *, sector_t *);
-
-/* access macros */
-static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
-{
- return sb->s_fs_info;
-}
-
-static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode)
-{
- return list_entry(inode, struct hfsplus_inode_info, vfs_inode);
-}
-
-#define sb_bread512(sb, sec, data) ({ \
- struct buffer_head *__bh; \
- sector_t __block; \
- loff_t __start; \
- int __offset; \
- \
- __start = (loff_t)(sec) << HFSPLUS_SECTOR_SHIFT;\
- __block = __start >> (sb)->s_blocksize_bits; \
- __offset = __start & ((sb)->s_blocksize - 1); \
- __bh = sb_bread((sb), __block); \
- if (likely(__bh != NULL)) \
- data = (void *)(__bh->b_data + __offset);\
- else \
- data = NULL; \
- __bh; \
-})
+int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
+ void *data, int rw);
/* time macros */
#define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U)
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 6892899fd6fb..927cdd6d5bf5 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -36,7 +36,8 @@
#define HFSP_WRAPOFF_EMBEDSIG 0x7C
#define HFSP_WRAPOFF_EMBEDEXT 0x7E
-#define HFSP_HIDDENDIR_NAME "\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80HFS+ Private Data"
+#define HFSP_HIDDENDIR_NAME \
+ "\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80HFS+ Private Data"
#define HFSP_HARDLINK_TYPE 0x686c6e6b /* 'hlnk' */
#define HFSP_HFSPLUS_CREATOR 0x6866732b /* 'hfs+' */
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 8afd7e84f98d..a8df651747f0 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -8,6 +8,7 @@
* Inode handling routines
*/
+#include <linux/blkdev.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
@@ -77,7 +78,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask)
if (!tree)
return 0;
if (tree->node_size >= PAGE_CACHE_SIZE) {
- nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
+ nidx = page->index >>
+ (tree->node_size_shift - PAGE_CACHE_SHIFT);
spin_lock(&tree->hash_lock);
node = hfs_bnode_findhash(tree, nidx);
if (!node)
@@ -90,7 +92,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask)
}
spin_unlock(&tree->hash_lock);
} else {
- nidx = page->index << (PAGE_CACHE_SHIFT - tree->node_size_shift);
+ nidx = page->index <<
+ (PAGE_CACHE_SHIFT - tree->node_size_shift);
i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift);
spin_lock(&tree->hash_lock);
do {
@@ -166,8 +169,8 @@ const struct dentry_operations hfsplus_dentry_operations = {
.d_compare = hfsplus_compare_dentry,
};
-static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry,
- struct nameidata *nd)
+static struct dentry *hfsplus_file_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd)
{
struct hfs_find_data fd;
struct super_block *sb = dir->i_sb;
@@ -190,7 +193,9 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent
inode->i_ino = dir->i_ino;
INIT_LIST_HEAD(&hip->open_dir_list);
mutex_init(&hip->extents_lock);
- hip->flags = HFSPLUS_FLG_RSRC;
+ hip->extent_state = 0;
+ hip->flags = 0;
+ set_bit(HFSPLUS_I_RSRC, &hip->flags);
hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
err = hfsplus_find_cat(sb, dir->i_ino, &fd);
@@ -219,7 +224,8 @@ out:
return NULL;
}
-static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, int dir)
+static void hfsplus_get_perms(struct inode *inode,
+ struct hfsplus_perm *perms, int dir)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
u16 mode;
@@ -302,29 +308,41 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
return 0;
}
-static int hfsplus_file_fsync(struct file *filp, int datasync)
+int hfsplus_file_fsync(struct file *file, int datasync)
{
- struct inode *inode = filp->f_mapping->host;
- struct super_block * sb;
- int ret, err;
-
- /* sync the inode to buffers */
- ret = write_inode_now(inode, 0);
-
- /* sync the superblock to buffers */
- sb = inode->i_sb;
- if (sb->s_dirt) {
- if (!(sb->s_flags & MS_RDONLY))
- hfsplus_sync_fs(sb, 1);
- else
- sb->s_dirt = 0;
+ struct inode *inode = file->f_mapping->host;
+ struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+ struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
+ int error = 0, error2;
+
+ /*
+ * Sync inode metadata into the catalog and extent trees.
+ */
+ sync_inode_metadata(inode, 1);
+
+ /*
+ * And explicitly write out the btrees.
+ */
+ if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags))
+ error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping);
+
+ if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) {
+ error2 =
+ filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
+ if (!error)
+ error = error2;
}
- /* .. finally sync the buffers to disk */
- err = sync_blockdev(sb->s_bdev);
- if (!ret)
- ret = err;
- return ret;
+ if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) {
+ error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
+ if (!error)
+ error = error2;
+ }
+
+ if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
+ blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+
+ return error;
}
static const struct inode_operations hfsplus_file_inode_operations = {
@@ -337,7 +355,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
};
static const struct file_operations hfsplus_file_operations = {
- .llseek = generic_file_llseek,
+ .llseek = generic_file_llseek,
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = do_sync_write,
@@ -370,6 +388,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
INIT_LIST_HEAD(&hip->open_dir_list);
mutex_init(&hip->extents_lock);
atomic_set(&hip->opencnt, 0);
+ hip->extent_state = 0;
hip->flags = 0;
memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec));
memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
@@ -457,7 +476,8 @@ void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork)
}
}
-void hfsplus_inode_write_fork(struct inode *inode, struct hfsplus_fork_raw *fork)
+void hfsplus_inode_write_fork(struct inode *inode,
+ struct hfsplus_fork_raw *fork)
{
memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents,
sizeof(hfsplus_extent_rec));
@@ -499,13 +519,14 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_file));
- hfsplus_inode_read_fork(inode, HFSPLUS_IS_DATA(inode) ?
- &file->data_fork : &file->rsrc_fork);
+ hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ?
+ &file->rsrc_fork : &file->data_fork);
hfsplus_get_perms(inode, &file->permissions, 0);
inode->i_nlink = 1;
if (S_ISREG(inode->i_mode)) {
if (file->permissions.dev)
- inode->i_nlink = be32_to_cpu(file->permissions.dev);
+ inode->i_nlink =
+ be32_to_cpu(file->permissions.dev);
inode->i_op = &hfsplus_file_inode_operations;
inode->i_fop = &hfsplus_file_operations;
inode->i_mapping->a_ops = &hfsplus_aops;
@@ -578,7 +599,9 @@ int hfsplus_cat_write_inode(struct inode *inode)
sizeof(struct hfsplus_cat_file));
hfsplus_inode_write_fork(inode, &file->data_fork);
hfsplus_cat_set_perms(inode, &file->permissions);
- if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE)
+ if (HFSPLUS_FLG_IMMUTABLE &
+ (file->permissions.rootflags |
+ file->permissions.userflags))
file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
else
file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED);
@@ -588,6 +611,8 @@ int hfsplus_cat_write_inode(struct inode *inode)
hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file));
}
+
+ set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
out:
hfs_find_exit(&fd);
return 0;
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
index 40a85a3ded6e..508ce662ce12 100644
--- a/fs/hfsplus/ioctl.c
+++ b/fs/hfsplus/ioctl.c
@@ -28,7 +28,7 @@ static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
if (inode->i_flags & S_IMMUTABLE)
flags |= FS_IMMUTABLE_FL;
- if (inode->i_flags |= S_APPEND)
+ if (inode->i_flags & S_APPEND)
flags |= FS_APPEND_FL;
if (hip->userflags & HFSPLUS_FLG_NODUMP)
flags |= FS_NODUMP_FL;
@@ -147,9 +147,11 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
res = -ERANGE;
} else
res = -EOPNOTSUPP;
- if (!res)
+ if (!res) {
hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file));
+ hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY);
+ }
out:
hfs_find_exit(&fd);
return res;
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index f9ab276a4d8d..bb62a5882147 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -23,6 +23,7 @@ enum {
opt_umask, opt_uid, opt_gid,
opt_part, opt_session, opt_nls,
opt_nodecompose, opt_decompose,
+ opt_barrier, opt_nobarrier,
opt_force, opt_err
};
@@ -37,6 +38,8 @@ static const match_table_t tokens = {
{ opt_nls, "nls=%s" },
{ opt_decompose, "decompose" },
{ opt_nodecompose, "nodecompose" },
+ { opt_barrier, "barrier" },
+ { opt_nobarrier, "nobarrier" },
{ opt_force, "force" },
{ opt_err, NULL }
};
@@ -65,6 +68,32 @@ static inline int match_fourchar(substring_t *arg, u32 *result)
return 0;
}
+int hfsplus_parse_options_remount(char *input, int *force)
+{
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+
+ if (!input)
+ return 0;
+
+ while ((p = strsep(&input, ",")) != NULL) {
+ if (!*p)
+ continue;
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case opt_force:
+ *force = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 1;
+}
+
/* Parse options from mount. Returns 0 on failure */
/* input is the options passed to mount() as a string */
int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
@@ -136,7 +165,9 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
if (p)
sbi->nls = load_nls(p);
if (!sbi->nls) {
- printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p);
+ printk(KERN_ERR "hfs: unable to load "
+ "nls mapping \"%s\"\n",
+ p);
kfree(p);
return 0;
}
@@ -148,6 +179,12 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
case opt_nodecompose:
set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
break;
+ case opt_barrier:
+ clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
+ break;
+ case opt_nobarrier:
+ set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
+ break;
case opt_force:
set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
break;
@@ -177,7 +214,8 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt)
seq_printf(seq, ",creator=%.4s", (char *)&sbi->creator);
if (sbi->type != HFSPLUS_DEF_CR_TYPE)
seq_printf(seq, ",type=%.4s", (char *)&sbi->type);
- seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, sbi->uid, sbi->gid);
+ seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask,
+ sbi->uid, sbi->gid);
if (sbi->part >= 0)
seq_printf(seq, ",part=%u", sbi->part);
if (sbi->session >= 0)
@@ -186,5 +224,7 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt)
seq_printf(seq, ",nls=%s", sbi->nls->charset);
if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags))
seq_printf(seq, ",nodecompose");
+ if (test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
+ seq_printf(seq, ",nobarrier");
return 0;
}
diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c
index 208b16c645cc..d66ad113b1cc 100644
--- a/fs/hfsplus/part_tbl.c
+++ b/fs/hfsplus/part_tbl.c
@@ -2,7 +2,8 @@
* linux/fs/hfsplus/part_tbl.c
*
* Copyright (C) 1996-1997 Paul H. Hargrove
- * This file may be distributed under the terms of the GNU General Public License.
+ * This file may be distributed under the terms of
+ * the GNU General Public License.
*
* Original code to handle the new style Mac partition table based on
* a patch contributed by Holger Schemel (aeglos@valinor.owl.de).
@@ -13,6 +14,7 @@
*
*/
+#include <linux/slab.h>
#include "hfsplus_fs.h"
/* offsets to various blocks */
@@ -58,77 +60,94 @@ struct new_pmap {
*/
struct old_pmap {
__be16 pdSig; /* Signature bytes */
- struct old_pmap_entry {
+ struct old_pmap_entry {
__be32 pdStart;
__be32 pdSize;
__be32 pdFSID;
} pdEntry[42];
} __packed;
+static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
+ sector_t *part_start, sector_t *part_size)
+{
+ struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
+ int i;
+
+ for (i = 0; i < 42; i++) {
+ struct old_pmap_entry *p = &pm->pdEntry[i];
+
+ if (p->pdStart && p->pdSize &&
+ p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
+ (sbi->part < 0 || sbi->part == i)) {
+ *part_start += be32_to_cpu(p->pdStart);
+ *part_size = be32_to_cpu(p->pdSize);
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
+ sector_t *part_start, sector_t *part_size)
+{
+ struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
+ int size = be32_to_cpu(pm->pmMapBlkCnt);
+ int res;
+ int i = 0;
+
+ do {
+ if (!memcmp(pm->pmPartType, "Apple_HFS", 9) &&
+ (sbi->part < 0 || sbi->part == i)) {
+ *part_start += be32_to_cpu(pm->pmPyPartStart);
+ *part_size = be32_to_cpu(pm->pmPartBlkCnt);
+ return 0;
+ }
+
+ if (++i >= size)
+ return -ENOENT;
+
+ res = hfsplus_submit_bio(sb->s_bdev,
+ *part_start + HFS_PMAP_BLK + i,
+ pm, READ);
+ if (res)
+ return res;
+ } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
+
+ return -ENOENT;
+}
+
/*
- * hfs_part_find()
- *
- * Parse the partition map looking for the
- * start and length of the 'part'th HFS partition.
+ * Parse the partition map looking for the start and length of a
+ * HFS/HFS+ partition.
*/
int hfs_part_find(struct super_block *sb,
- sector_t *part_start, sector_t *part_size)
+ sector_t *part_start, sector_t *part_size)
{
- struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
- struct buffer_head *bh;
- __be16 *data;
- int i, size, res;
+ void *data;
+ int res;
+
+ data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- res = -ENOENT;
- bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data);
- if (!bh)
- return -EIO;
+ res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
+ data, READ);
+ if (res)
+ return res;
- switch (be16_to_cpu(*data)) {
+ switch (be16_to_cpu(*((__be16 *)data))) {
case HFS_OLD_PMAP_MAGIC:
- {
- struct old_pmap *pm;
- struct old_pmap_entry *p;
-
- pm = (struct old_pmap *)bh->b_data;
- p = pm->pdEntry;
- size = 42;
- for (i = 0; i < size; p++, i++) {
- if (p->pdStart && p->pdSize &&
- p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
- (sbi->part < 0 || sbi->part == i)) {
- *part_start += be32_to_cpu(p->pdStart);
- *part_size = be32_to_cpu(p->pdSize);
- res = 0;
- }
- }
+ res = hfs_parse_old_pmap(sb, data, part_start, part_size);
break;
- }
case HFS_NEW_PMAP_MAGIC:
- {
- struct new_pmap *pm;
-
- pm = (struct new_pmap *)bh->b_data;
- size = be32_to_cpu(pm->pmMapBlkCnt);
- for (i = 0; i < size;) {
- if (!memcmp(pm->pmPartType,"Apple_HFS", 9) &&
- (sbi->part < 0 || sbi->part == i)) {
- *part_start += be32_to_cpu(pm->pmPyPartStart);
- *part_size = be32_to_cpu(pm->pmPartBlkCnt);
- res = 0;
- break;
- }
- brelse(bh);
- bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm);
- if (!bh)
- return -EIO;
- if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC))
- break;
- }
+ res = hfs_parse_new_pmap(sb, data, part_start, part_size);
+ break;
+ default:
+ res = -ENOENT;
break;
- }
}
- brelse(bh);
+ kfree(data);
return res;
}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 52cc746d3ba3..6ee6ad20acf2 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pagemap.h>
+#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vfs.h>
@@ -66,6 +67,7 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
INIT_LIST_HEAD(&HFSPLUS_I(inode)->open_dir_list);
mutex_init(&HFSPLUS_I(inode)->extents_lock);
HFSPLUS_I(inode)->flags = 0;
+ HFSPLUS_I(inode)->extent_state = 0;
HFSPLUS_I(inode)->rsrc_inode = NULL;
atomic_set(&HFSPLUS_I(inode)->opencnt, 0);
@@ -157,45 +159,65 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
struct hfsplus_vh *vhdr = sbi->s_vhdr;
+ int write_backup = 0;
+ int error, error2;
+
+ if (!wait)
+ return 0;
dprint(DBG_SUPER, "hfsplus_write_super\n");
- mutex_lock(&sbi->vh_mutex);
- mutex_lock(&sbi->alloc_mutex);
sb->s_dirt = 0;
+ /*
+ * Explicitly write out the special metadata inodes.
+ *
+ * While these special inodes are marked as hashed and written
+ * out peridocically by the flusher threads we redirty them
+ * during writeout of normal inodes, and thus the life lock
+ * prevents us from getting the latest state to disk.
+ */
+ error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping);
+ error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
+ if (!error)
+ error = error2;
+ error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
+ if (!error)
+ error = error2;
+
+ mutex_lock(&sbi->vh_mutex);
+ mutex_lock(&sbi->alloc_mutex);
vhdr->free_blocks = cpu_to_be32(sbi->free_blocks);
vhdr->next_cnid = cpu_to_be32(sbi->next_cnid);
vhdr->folder_count = cpu_to_be32(sbi->folder_count);
vhdr->file_count = cpu_to_be32(sbi->file_count);
- mark_buffer_dirty(sbi->s_vhbh);
if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) {
- if (sbi->sect_count) {
- struct buffer_head *bh;
- u32 block, offset;
-
- block = sbi->blockoffset;
- block += (sbi->sect_count - 2) >> (sb->s_blocksize_bits - 9);
- offset = ((sbi->sect_count - 2) << 9) & (sb->s_blocksize - 1);
- printk(KERN_DEBUG "hfs: backup: %u,%u,%u,%u\n",
- sbi->blockoffset, sbi->sect_count,
- block, offset);
- bh = sb_bread(sb, block);
- if (bh) {
- vhdr = (struct hfsplus_vh *)(bh->b_data + offset);
- if (be16_to_cpu(vhdr->signature) == HFSPLUS_VOLHEAD_SIG) {
- memcpy(vhdr, sbi->s_vhdr, sizeof(*vhdr));
- mark_buffer_dirty(bh);
- brelse(bh);
- } else
- printk(KERN_WARNING "hfs: backup not found!\n");
- }
- }
+ memcpy(sbi->s_backup_vhdr, sbi->s_vhdr, sizeof(*sbi->s_vhdr));
+ write_backup = 1;
}
+
+ error2 = hfsplus_submit_bio(sb->s_bdev,
+ sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
+ sbi->s_vhdr, WRITE_SYNC);
+ if (!error)
+ error = error2;
+ if (!write_backup)
+ goto out;
+
+ error2 = hfsplus_submit_bio(sb->s_bdev,
+ sbi->part_start + sbi->sect_count - 2,
+ sbi->s_backup_vhdr, WRITE_SYNC);
+ if (!error)
+ error2 = error;
+out:
mutex_unlock(&sbi->alloc_mutex);
mutex_unlock(&sbi->vh_mutex);
- return 0;
+
+ if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
+ blkdev_issue_flush(sb->s_bdev, GFP_KERNEL, NULL);
+
+ return error;
}
static void hfsplus_write_super(struct super_block *sb)
@@ -215,23 +237,22 @@ static void hfsplus_put_super(struct super_block *sb)
if (!sb->s_fs_info)
return;
- if (sb->s_dirt)
- hfsplus_write_super(sb);
if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) {
struct hfsplus_vh *vhdr = sbi->s_vhdr;
vhdr->modify_date = hfsp_now2mt();
vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_UNMNT);
vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_INCNSTNT);
- mark_buffer_dirty(sbi->s_vhbh);
- sync_dirty_buffer(sbi->s_vhbh);
+
+ hfsplus_sync_fs(sb, 1);
}
hfs_btree_close(sbi->cat_tree);
hfs_btree_close(sbi->ext_tree);
iput(sbi->alloc_file);
iput(sbi->hidden_dir);
- brelse(sbi->s_vhbh);
+ kfree(sbi->s_vhdr);
+ kfree(sbi->s_backup_vhdr);
unload_nls(sbi->nls);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
@@ -263,26 +284,31 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
return 0;
if (!(*flags & MS_RDONLY)) {
struct hfsplus_vh *vhdr = HFSPLUS_SB(sb)->s_vhdr;
- struct hfsplus_sb_info sbi;
+ int force = 0;
- memset(&sbi, 0, sizeof(struct hfsplus_sb_info));
- sbi.nls = HFSPLUS_SB(sb)->nls;
- if (!hfsplus_parse_options(data, &sbi))
+ if (!hfsplus_parse_options_remount(data, &force))
return -EINVAL;
if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
- printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
- "running fsck.hfsplus is recommended. leaving read-only.\n");
+ printk(KERN_WARNING "hfs: filesystem was "
+ "not cleanly unmounted, "
+ "running fsck.hfsplus is recommended. "
+ "leaving read-only.\n");
sb->s_flags |= MS_RDONLY;
*flags |= MS_RDONLY;
- } else if (test_bit(HFSPLUS_SB_FORCE, &sbi.flags)) {
+ } else if (force) {
/* nothing */
- } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
- printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n");
+ } else if (vhdr->attributes &
+ cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
+ printk(KERN_WARNING "hfs: filesystem is marked locked, "
+ "leaving read-only.\n");
sb->s_flags |= MS_RDONLY;
*flags |= MS_RDONLY;
- } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
- printk(KERN_WARNING "hfs: filesystem is marked journaled, leaving read-only.\n");
+ } else if (vhdr->attributes &
+ cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
+ printk(KERN_WARNING "hfs: filesystem is "
+ "marked journaled, "
+ "leaving read-only.\n");
sb->s_flags |= MS_RDONLY;
*flags |= MS_RDONLY;
}
@@ -372,17 +398,22 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
sb->s_maxbytes = MAX_LFS_FILESIZE;
if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
- printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, "
- "running fsck.hfsplus is recommended. mounting read-only.\n");
+ printk(KERN_WARNING "hfs: Filesystem was "
+ "not cleanly unmounted, "
+ "running fsck.hfsplus is recommended. "
+ "mounting read-only.\n");
sb->s_flags |= MS_RDONLY;
} else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) {
/* nothing */
} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n");
sb->s_flags |= MS_RDONLY;
- } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && !(sb->s_flags & MS_RDONLY)) {
- printk(KERN_WARNING "hfs: write access to a journaled filesystem is not supported, "
- "use the force option at your own risk, mounting read-only.\n");
+ } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) &&
+ !(sb->s_flags & MS_RDONLY)) {
+ printk(KERN_WARNING "hfs: write access to "
+ "a journaled filesystem is not supported, "
+ "use the force option at your own risk, "
+ "mounting read-only.\n");
sb->s_flags |= MS_RDONLY;
}
@@ -419,7 +450,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
err = -ENOMEM;
goto cleanup;
}
- sb->s_root->d_op = &hfsplus_dentry_operations;
+ d_set_d_op(sb->s_root, &hfsplus_dentry_operations);
str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
str.name = HFSP_HIDDENDIR_NAME;
@@ -449,19 +480,16 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
be32_add_cpu(&vhdr->write_count, 1);
vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT);
vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT);
- mark_buffer_dirty(sbi->s_vhbh);
- sync_dirty_buffer(sbi->s_vhbh);
+ hfsplus_sync_fs(sb, 1);
if (!sbi->hidden_dir) {
- printk(KERN_DEBUG "hfs: create hidden dir...\n");
-
mutex_lock(&sbi->vh_mutex);
sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode,
&str, sbi->hidden_dir);
mutex_unlock(&sbi->vh_mutex);
- mark_inode_dirty(sbi->hidden_dir);
+ hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY);
}
out:
unload_nls(sbi->nls);
@@ -488,11 +516,19 @@ static struct inode *hfsplus_alloc_inode(struct super_block *sb)
return i ? &i->vfs_inode : NULL;
}
-static void hfsplus_destroy_inode(struct inode *inode)
+static void hfsplus_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(hfsplus_inode_cachep, HFSPLUS_I(inode));
}
+static void hfsplus_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, hfsplus_i_callback);
+}
+
#define HFSPLUS_INODE_SIZE sizeof(struct hfsplus_inode_info)
static struct dentry *hfsplus_mount(struct file_system_type *fs_type,
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index b66d67de882c..a3f0bfcc881e 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -17,14 +17,14 @@
/* Returns folded char, or 0 if ignorable */
static inline u16 case_fold(u16 c)
{
- u16 tmp;
-
- tmp = hfsplus_case_fold_table[c >> 8];
- if (tmp)
- tmp = hfsplus_case_fold_table[tmp + (c & 0xff)];
- else
- tmp = c;
- return tmp;
+ u16 tmp;
+
+ tmp = hfsplus_case_fold_table[c >> 8];
+ if (tmp)
+ tmp = hfsplus_case_fold_table[tmp + (c & 0xff)];
+ else
+ tmp = c;
+ return tmp;
}
/* Compare unicode strings, return values like normal strcmp */
@@ -118,7 +118,9 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc)
return NULL;
}
-int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, char *astr, int *len_p)
+int hfsplus_uni2asc(struct super_block *sb,
+ const struct hfsplus_unistr *ustr,
+ char *astr, int *len_p)
{
const hfsplus_unichr *ip;
struct nls_table *nls = HFSPLUS_SB(sb)->nls;
@@ -171,7 +173,8 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c
goto same;
c1 = be16_to_cpu(*ip);
if (likely(compose))
- ce1 = hfsplus_compose_lookup(hfsplus_compose_table, c1);
+ ce1 = hfsplus_compose_lookup(
+ hfsplus_compose_table, c1);
if (ce1)
break;
switch (c0) {
@@ -199,7 +202,8 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c
if (ce2) {
i = 1;
while (i < ustrlen) {
- ce1 = hfsplus_compose_lookup(ce2, be16_to_cpu(ip[i]));
+ ce1 = hfsplus_compose_lookup(ce2,
+ be16_to_cpu(ip[i]));
if (!ce1)
break;
i++;
@@ -211,7 +215,7 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c
goto done;
}
}
- same:
+same:
switch (c0) {
case 0:
cc = 0x2400;
@@ -222,7 +226,7 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c
default:
cc = c0;
}
- done:
+done:
res = nls->uni2char(cc, op, len);
if (res < 0) {
if (res == -ENAMETOOLONG)
@@ -320,7 +324,8 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
* Composed unicode characters are decomposed and case-folding is performed
* if the appropriate bits are (un)set on the superblock.
*/
-int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)
+int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *str)
{
struct super_block *sb = dentry->d_sb;
const char *astr;
@@ -363,9 +368,12 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)
* Composed unicode characters are decomposed and case-folding is performed
* if the appropriate bits are (un)set on the superblock.
*/
-int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2)
+int hfsplus_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- struct super_block *sb = dentry->d_sb;
+ struct super_block *sb = parent->d_sb;
int casefold, decompose, size;
int dsize1, dsize2, len1, len2;
const u16 *dstr1, *dstr2;
@@ -375,10 +383,10 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *
casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
- astr1 = s1->name;
- len1 = s1->len;
- astr2 = s2->name;
- len2 = s2->len;
+ astr1 = str;
+ len1 = len;
+ astr2 = name->name;
+ len2 = name->len;
dsize1 = dsize2 = 0;
dstr1 = dstr2 = NULL;
@@ -388,7 +396,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *
astr1 += size;
len1 -= size;
- if (!decompose || !(dstr1 = decompose_unichar(c, &dsize1))) {
+ if (decompose)
+ dstr1 = decompose_unichar(c, &dsize1);
+ if (!decompose || !dstr1) {
c1 = c;
dstr1 = &c1;
dsize1 = 1;
@@ -400,7 +410,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *
astr2 += size;
len2 -= size;
- if (!decompose || !(dstr2 = decompose_unichar(c, &dsize2))) {
+ if (decompose)
+ dstr2 = decompose_unichar(c, &dsize2);
+ if (!decompose || !dstr2) {
c2 = c;
dstr2 = &c2;
dsize2 = 1;
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 8972c20b3216..196231794f64 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -24,6 +24,40 @@ struct hfsplus_wd {
u16 embed_count;
};
+static void hfsplus_end_io_sync(struct bio *bio, int err)
+{
+ if (err)
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
+ complete(bio->bi_private);
+}
+
+int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
+ void *data, int rw)
+{
+ DECLARE_COMPLETION_ONSTACK(wait);
+ struct bio *bio;
+
+ bio = bio_alloc(GFP_NOIO, 1);
+ bio->bi_sector = sector;
+ bio->bi_bdev = bdev;
+ bio->bi_end_io = hfsplus_end_io_sync;
+ bio->bi_private = &wait;
+
+ /*
+ * We always submit one sector at a time, so bio_add_page must not fail.
+ */
+ if (bio_add_page(bio, virt_to_page(data), HFSPLUS_SECTOR_SIZE,
+ offset_in_page(data)) != HFSPLUS_SECTOR_SIZE)
+ BUG();
+
+ submit_bio(rw, bio);
+ wait_for_completion(&wait);
+
+ if (!bio_flagged(bio, BIO_UPTODATE))
+ return -EIO;
+ return 0;
+}
+
static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
{
u32 extent;
@@ -40,12 +74,14 @@ static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
!(attrib & HFSP_WRAP_ATTRIB_SPARED))
return 0;
- wd->ablk_size = be32_to_cpu(*(__be32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE));
+ wd->ablk_size =
+ be32_to_cpu(*(__be32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE));
if (wd->ablk_size < HFSPLUS_SECTOR_SIZE)
return 0;
if (wd->ablk_size % HFSPLUS_SECTOR_SIZE)
return 0;
- wd->ablk_start = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART));
+ wd->ablk_start =
+ be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART));
extent = get_unaligned_be32(bufptr + HFSP_WRAPOFF_EMBEDEXT);
wd->embed_start = (extent >> 16) & 0xFFFF;
@@ -68,7 +104,8 @@ static int hfsplus_get_last_session(struct super_block *sb,
if (HFSPLUS_SB(sb)->session >= 0) {
te.cdte_track = HFSPLUS_SB(sb)->session;
te.cdte_format = CDROM_LBA;
- res = ioctl_by_bdev(sb->s_bdev, CDROMREADTOCENTRY, (unsigned long)&te);
+ res = ioctl_by_bdev(sb->s_bdev,
+ CDROMREADTOCENTRY, (unsigned long)&te);
if (!res && (te.cdte_ctrl & CDROM_DATA_TRACK) == 4) {
*start = (sector_t)te.cdte_addr.lba << 2;
return 0;
@@ -77,7 +114,8 @@ static int hfsplus_get_last_session(struct super_block *sb,
return -EINVAL;
}
ms_info.addr_format = CDROM_LBA;
- res = ioctl_by_bdev(sb->s_bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
+ res = ioctl_by_bdev(sb->s_bdev, CDROMMULTISESSION,
+ (unsigned long)&ms_info);
if (!res && ms_info.xa_flag)
*start = (sector_t)ms_info.addr.lba << 2;
return 0;
@@ -88,100 +126,112 @@ static int hfsplus_get_last_session(struct super_block *sb,
int hfsplus_read_wrapper(struct super_block *sb)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
- struct buffer_head *bh;
- struct hfsplus_vh *vhdr;
struct hfsplus_wd wd;
sector_t part_start, part_size;
u32 blocksize;
+ int error = 0;
+ error = -EINVAL;
blocksize = sb_min_blocksize(sb, HFSPLUS_SECTOR_SIZE);
if (!blocksize)
- return -EINVAL;
+ goto out;
if (hfsplus_get_last_session(sb, &part_start, &part_size))
- return -EINVAL;
+ goto out;
if ((u64)part_start + part_size > 0x100000000ULL) {
pr_err("hfs: volumes larger than 2TB are not supported yet\n");
- return -EINVAL;
+ goto out;
}
- while (1) {
- bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
- if (!bh)
- return -EIO;
-
- if (vhdr->signature == cpu_to_be16(HFSP_WRAP_MAGIC)) {
- if (!hfsplus_read_mdb(vhdr, &wd))
- goto error;
- wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
- part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
- part_size = wd.embed_count * wd.ablk_size;
- brelse(bh);
- bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
- if (!bh)
- return -EIO;
- }
- if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
- break;
- if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) {
- set_bit(HFSPLUS_SB_HFSX, &sbi->flags);
- break;
- }
- brelse(bh);
- /* check for a partition block
+ error = -ENOMEM;
+ sbi->s_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
+ if (!sbi->s_vhdr)
+ goto out;
+ sbi->s_backup_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
+ if (!sbi->s_backup_vhdr)
+ goto out_free_vhdr;
+
+reread:
+ error = hfsplus_submit_bio(sb->s_bdev,
+ part_start + HFSPLUS_VOLHEAD_SECTOR,
+ sbi->s_vhdr, READ);
+ if (error)
+ goto out_free_backup_vhdr;
+
+ error = -EINVAL;
+ switch (sbi->s_vhdr->signature) {
+ case cpu_to_be16(HFSPLUS_VOLHEAD_SIGX):
+ set_bit(HFSPLUS_SB_HFSX, &sbi->flags);
+ /*FALLTHRU*/
+ case cpu_to_be16(HFSPLUS_VOLHEAD_SIG):
+ break;
+ case cpu_to_be16(HFSP_WRAP_MAGIC):
+ if (!hfsplus_read_mdb(sbi->s_vhdr, &wd))
+ goto out;
+ wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
+ part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
+ part_size = wd.embed_count * wd.ablk_size;
+ goto reread;
+ default:
+ /*
+ * Check for a partition block.
+ *
* (should do this only for cdrom/loop though)
*/
if (hfs_part_find(sb, &part_start, &part_size))
- return -EINVAL;
+ goto out;
+ goto reread;
+ }
+
+ error = hfsplus_submit_bio(sb->s_bdev,
+ part_start + part_size - 2,
+ sbi->s_backup_vhdr, READ);
+ if (error)
+ goto out_free_backup_vhdr;
+
+ error = -EINVAL;
+ if (sbi->s_backup_vhdr->signature != sbi->s_vhdr->signature) {
+ printk(KERN_WARNING
+ "hfs: invalid secondary volume header\n");
+ goto out_free_backup_vhdr;
}
- blocksize = be32_to_cpu(vhdr->blocksize);
- brelse(bh);
+ blocksize = be32_to_cpu(sbi->s_vhdr->blocksize);
- /* block size must be at least as large as a sector
- * and a multiple of 2
+ /*
+ * Block size must be at least as large as a sector and a multiple of 2.
*/
- if (blocksize < HFSPLUS_SECTOR_SIZE ||
- ((blocksize - 1) & blocksize))
- return -EINVAL;
+ if (blocksize < HFSPLUS_SECTOR_SIZE || ((blocksize - 1) & blocksize))
+ goto out_free_backup_vhdr;
sbi->alloc_blksz = blocksize;
sbi->alloc_blksz_shift = 0;
while ((blocksize >>= 1) != 0)
sbi->alloc_blksz_shift++;
blocksize = min(sbi->alloc_blksz, (u32)PAGE_SIZE);
- /* align block size to block offset */
+ /*
+ * Align block size to block offset.
+ */
while (part_start & ((blocksize >> HFSPLUS_SECTOR_SHIFT) - 1))
blocksize >>= 1;
if (sb_set_blocksize(sb, blocksize) != blocksize) {
- printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", blocksize);
- return -EINVAL;
+ printk(KERN_ERR "hfs: unable to set blocksize to %u!\n",
+ blocksize);
+ goto out_free_backup_vhdr;
}
sbi->blockoffset =
part_start >> (sb->s_blocksize_bits - HFSPLUS_SECTOR_SHIFT);
+ sbi->part_start = part_start;
sbi->sect_count = part_size;
sbi->fs_shift = sbi->alloc_blksz_shift - sb->s_blocksize_bits;
-
- bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
- if (!bh)
- return -EIO;
-
- /* should still be the same... */
- if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) {
- if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIGX))
- goto error;
- } else {
- if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
- goto error;
- }
-
- sbi->s_vhbh = bh;
- sbi->s_vhdr = vhdr;
-
return 0;
- error:
- brelse(bh);
- return -EINVAL;
+
+out_free_backup_vhdr:
+ kfree(sbi->s_backup_vhdr);
+out_free_vhdr:
+ kfree(sbi->s_vhdr);
+out:
+ return error;
}
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 2c0f148a49e6..0bc81cf256b8 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -32,7 +32,7 @@ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
-static int hostfs_d_delete(struct dentry *dentry)
+static int hostfs_d_delete(const struct dentry *dentry)
{
return 1;
}
@@ -92,12 +92,10 @@ __uml_setup("hostfs=", hostfs_args,
static char *__dentry_name(struct dentry *dentry, char *name)
{
- char *p = __dentry_path(dentry, name, PATH_MAX);
+ char *p = dentry_path_raw(dentry, name, PATH_MAX);
char *root;
size_t len;
- spin_unlock(&dcache_lock);
-
root = dentry->d_sb->s_fs_info;
len = strlen(root);
if (IS_ERR(p)) {
@@ -123,25 +121,23 @@ static char *dentry_name(struct dentry *dentry)
if (!name)
return NULL;
- spin_lock(&dcache_lock);
return __dentry_name(dentry, name); /* will unlock */
}
static char *inode_name(struct inode *ino)
{
struct dentry *dentry;
- char *name = __getname();
- if (!name)
- return NULL;
+ char *name;
- spin_lock(&dcache_lock);
- if (list_empty(&ino->i_dentry)) {
- spin_unlock(&dcache_lock);
- __putname(name);
+ dentry = d_find_alias(ino);
+ if (!dentry)
return NULL;
- }
- dentry = list_first_entry(&ino->i_dentry, struct dentry, d_alias);
- return __dentry_name(dentry, name); /* will unlock */
+
+ name = dentry_name(dentry);
+
+ dput(dentry);
+
+ return name;
}
static char *follow_link(char *link)
@@ -251,11 +247,18 @@ static void hostfs_evict_inode(struct inode *inode)
}
}
-static void hostfs_destroy_inode(struct inode *inode)
+static void hostfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kfree(HOSTFS_I(inode));
}
+static void hostfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, hostfs_i_callback);
+}
+
static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
const char *root_path = vfs->mnt_sb->s_fs_info;
@@ -609,7 +612,7 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
goto out_put;
d_add(dentry, inode);
- dentry->d_op = &hostfs_dentry_ops;
+ d_set_d_op(dentry, &hostfs_dentry_ops);
return NULL;
out_put:
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c
index 67d9d36b3d5f..32c13a94e1e9 100644
--- a/fs/hpfs/dentry.c
+++ b/fs/hpfs/dentry.c
@@ -12,7 +12,8 @@
* Note: the dentry argument is the parent dentry.
*/
-static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
+static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
unsigned long hash;
int i;
@@ -34,19 +35,25 @@ static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
return 0;
}
-static int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int hpfs_compare_dentry(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- unsigned al=a->len;
- unsigned bl=b->len;
- hpfs_adjust_length(a->name, &al);
+ unsigned al = len;
+ unsigned bl = name->len;
+
+ hpfs_adjust_length(str, &al);
/*hpfs_adjust_length(b->name, &bl);*/
- /* 'a' is the qstr of an already existing dentry, so the name
- * must be valid. 'b' must be validated first.
+
+ /*
+ * 'str' is the nane of an already existing dentry, so the name
+ * must be valid. 'name' must be validated first.
*/
- if (hpfs_chk_name(b->name, &bl))
+ if (hpfs_chk_name(name->name, &bl))
return 1;
- if (hpfs_compare_names(dentry->d_sb, a->name, al, b->name, bl, 0))
+ if (hpfs_compare_names(parent->d_sb, str, al, name->name, bl, 0))
return 1;
return 0;
}
@@ -58,5 +65,5 @@ static const struct dentry_operations hpfs_dentry_operations = {
void hpfs_set_dentry_operations(struct dentry *dentry)
{
- dentry->d_op = &hpfs_dentry_operations;
+ d_set_d_op(dentry, &hpfs_dentry_operations);
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 6c5f01597c3a..49935ba78db8 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -177,11 +177,18 @@ static struct inode *hpfs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void hpfs_destroy_inode(struct inode *inode)
+static void hpfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode));
}
+static void hpfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, hpfs_i_callback);
+}
+
static void init_once(void *foo)
{
struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index f702b5f713fc..87ed48e0343d 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -632,11 +632,18 @@ void hppfs_evict_inode(struct inode *ino)
mntput(ino->i_sb->s_fs_info);
}
-static void hppfs_destroy_inode(struct inode *inode)
+static void hppfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kfree(HPPFS_I(inode));
}
+static void hppfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, hppfs_i_callback);
+}
+
static const struct super_operations hppfs_sbops = {
.alloc_inode = hppfs_alloc_inode,
.destroy_inode = hppfs_destroy_inode,
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index a5fe68189eed..9885082b470f 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -663,11 +663,18 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
return &p->vfs_inode;
}
+static void hugetlbfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
+}
+
static void hugetlbfs_destroy_inode(struct inode *inode)
{
hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
- kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
+ call_rcu(&inode->i_rcu, hugetlbfs_i_callback);
}
static const struct address_space_operations hugetlbfs_aops = {
diff --git a/fs/inode.c b/fs/inode.c
index ae2727ab0c3a..da85e56378f3 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -102,26 +102,29 @@ static DECLARE_RWSEM(iprune_sem);
*/
struct inodes_stat_t inodes_stat;
-static struct percpu_counter nr_inodes __cacheline_aligned_in_smp;
-static struct percpu_counter nr_inodes_unused __cacheline_aligned_in_smp;
+static DEFINE_PER_CPU(unsigned int, nr_inodes);
static struct kmem_cache *inode_cachep __read_mostly;
-static inline int get_nr_inodes(void)
+static int get_nr_inodes(void)
{
- return percpu_counter_sum_positive(&nr_inodes);
+ int i;
+ int sum = 0;
+ for_each_possible_cpu(i)
+ sum += per_cpu(nr_inodes, i);
+ return sum < 0 ? 0 : sum;
}
static inline int get_nr_inodes_unused(void)
{
- return percpu_counter_sum_positive(&nr_inodes_unused);
+ return inodes_stat.nr_unused;
}
int get_nr_dirty_inodes(void)
{
+ /* not actually dirty inodes, but a wild approximation */
int nr_dirty = get_nr_inodes() - get_nr_inodes_unused();
return nr_dirty > 0 ? nr_dirty : 0;
-
}
/*
@@ -132,7 +135,6 @@ int proc_nr_inodes(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
inodes_stat.nr_inodes = get_nr_inodes();
- inodes_stat.nr_unused = get_nr_inodes_unused();
return proc_dointvec(table, write, buffer, lenp, ppos);
}
#endif
@@ -224,7 +226,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
inode->i_fsnotify_mask = 0;
#endif
- percpu_counter_inc(&nr_inodes);
+ this_cpu_inc(nr_inodes);
return 0;
out:
@@ -255,6 +257,12 @@ static struct inode *alloc_inode(struct super_block *sb)
return inode;
}
+void free_inode_nonrcu(struct inode *inode)
+{
+ kmem_cache_free(inode_cachep, inode);
+}
+EXPORT_SYMBOL(free_inode_nonrcu);
+
void __destroy_inode(struct inode *inode)
{
BUG_ON(inode_has_buffers(inode));
@@ -266,10 +274,17 @@ void __destroy_inode(struct inode *inode)
if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED)
posix_acl_release(inode->i_default_acl);
#endif
- percpu_counter_dec(&nr_inodes);
+ this_cpu_dec(nr_inodes);
}
EXPORT_SYMBOL(__destroy_inode);
+static void i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(inode_cachep, inode);
+}
+
static void destroy_inode(struct inode *inode)
{
BUG_ON(!list_empty(&inode->i_lru));
@@ -277,7 +292,7 @@ static void destroy_inode(struct inode *inode)
if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
- kmem_cache_free(inode_cachep, (inode));
+ call_rcu(&inode->i_rcu, i_callback);
}
/*
@@ -335,7 +350,7 @@ static void inode_lru_list_add(struct inode *inode)
{
if (list_empty(&inode->i_lru)) {
list_add(&inode->i_lru, &inode_lru);
- percpu_counter_inc(&nr_inodes_unused);
+ inodes_stat.nr_unused++;
}
}
@@ -343,7 +358,7 @@ static void inode_lru_list_del(struct inode *inode)
{
if (!list_empty(&inode->i_lru)) {
list_del_init(&inode->i_lru);
- percpu_counter_dec(&nr_inodes_unused);
+ inodes_stat.nr_unused--;
}
}
@@ -430,6 +445,7 @@ void end_writeback(struct inode *inode)
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
inode_sync_wait(inode);
+ /* don't need i_lock here, no concurrent mods to i_state */
inode->i_state = I_FREEING | I_CLEAR;
}
EXPORT_SYMBOL(end_writeback);
@@ -513,7 +529,7 @@ void evict_inodes(struct super_block *sb)
list_move(&inode->i_lru, &dispose);
list_del_init(&inode->i_wb_list);
if (!(inode->i_state & (I_DIRTY | I_SYNC)))
- percpu_counter_dec(&nr_inodes_unused);
+ inodes_stat.nr_unused--;
}
spin_unlock(&inode_lock);
@@ -554,7 +570,7 @@ int invalidate_inodes(struct super_block *sb)
list_move(&inode->i_lru, &dispose);
list_del_init(&inode->i_wb_list);
if (!(inode->i_state & (I_DIRTY | I_SYNC)))
- percpu_counter_dec(&nr_inodes_unused);
+ inodes_stat.nr_unused--;
}
spin_unlock(&inode_lock);
@@ -616,7 +632,7 @@ static void prune_icache(int nr_to_scan)
if (atomic_read(&inode->i_count) ||
(inode->i_state & ~I_REFERENCED)) {
list_del_init(&inode->i_lru);
- percpu_counter_dec(&nr_inodes_unused);
+ inodes_stat.nr_unused--;
continue;
}
@@ -650,7 +666,7 @@ static void prune_icache(int nr_to_scan)
*/
list_move(&inode->i_lru, &freeable);
list_del_init(&inode->i_wb_list);
- percpu_counter_dec(&nr_inodes_unused);
+ inodes_stat.nr_unused--;
}
if (current_is_kswapd())
__count_vm_events(KSWAPD_INODESTEAL, reap);
@@ -1648,8 +1664,6 @@ void __init inode_init(void)
SLAB_MEM_SPREAD),
init_once);
register_shrinker(&icache_shrinker);
- percpu_counter_init(&nr_inodes, 0);
- percpu_counter_init(&nr_inodes_unused, 0);
/* Hash may have been set up in inode_init_early */
if (!hashdist)
diff --git a/fs/internal.h b/fs/internal.h
index e43b9a4dbf4e..3a73ae2679af 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -63,6 +63,7 @@ extern int copy_mount_string(const void __user *, char **);
extern void free_vfsmnt(struct vfsmount *);
extern struct vfsmount *alloc_vfsmnt(const char *);
+extern unsigned int count_mnt_count(struct vfsmount *mnt);
extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
struct vfsmount *);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index bfdeb82a53be..844a7903c72f 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -26,16 +26,32 @@
#define BEQUIET
-static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
-static int isofs_hash(struct dentry *parent, struct qstr *qstr);
-static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_hashi(const struct dentry *parent, const struct inode *inode,
+ struct qstr *qstr);
+static int isofs_hash(const struct dentry *parent, const struct inode *inode,
+ struct qstr *qstr);
+static int isofs_dentry_cmpi(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
+static int isofs_dentry_cmp(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
#ifdef CONFIG_JOLIET
-static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
-static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
-static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode,
+ struct qstr *qstr);
+static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode,
+ struct qstr *qstr);
+static int isofs_dentry_cmpi_ms(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
+static int isofs_dentry_cmp_ms(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name);
#endif
static void isofs_put_super(struct super_block *sb)
@@ -65,11 +81,18 @@ static struct inode *isofs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void isofs_destroy_inode(struct inode *inode)
+static void isofs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
}
+static void isofs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, isofs_i_callback);
+}
+
static void init_once(void *foo)
{
struct iso_inode_info *ei = foo;
@@ -160,7 +183,7 @@ struct iso9660_options{
* Compute the hash for the isofs name corresponding to the dentry.
*/
static int
-isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
+isofs_hash_common(const struct dentry *dentry, struct qstr *qstr, int ms)
{
const char *name;
int len;
@@ -181,7 +204,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
* Compute the hash for the isofs name corresponding to the dentry.
*/
static int
-isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
+isofs_hashi_common(const struct dentry *dentry, struct qstr *qstr, int ms)
{
const char *name;
int len;
@@ -206,100 +229,94 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
}
/*
- * Case insensitive compare of two isofs names.
- */
-static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
- struct qstr *b, int ms)
-{
- int alen, blen;
-
- /* A filename cannot end in '.' or we treat it like it has none */
- alen = a->len;
- blen = b->len;
- if (ms) {
- while (alen && a->name[alen-1] == '.')
- alen--;
- while (blen && b->name[blen-1] == '.')
- blen--;
- }
- if (alen == blen) {
- if (strnicmp(a->name, b->name, alen) == 0)
- return 0;
- }
- return 1;
-}
-
-/*
- * Case sensitive compare of two isofs names.
+ * Compare of two isofs names.
*/
-static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
- struct qstr *b, int ms)
+static int isofs_dentry_cmp_common(
+ unsigned int len, const char *str,
+ const struct qstr *name, int ms, int ci)
{
int alen, blen;
/* A filename cannot end in '.' or we treat it like it has none */
- alen = a->len;
- blen = b->len;
+ alen = name->len;
+ blen = len;
if (ms) {
- while (alen && a->name[alen-1] == '.')
+ while (alen && name->name[alen-1] == '.')
alen--;
- while (blen && b->name[blen-1] == '.')
+ while (blen && str[blen-1] == '.')
blen--;
}
if (alen == blen) {
- if (strncmp(a->name, b->name, alen) == 0)
- return 0;
+ if (ci) {
+ if (strnicmp(name->name, str, alen) == 0)
+ return 0;
+ } else {
+ if (strncmp(name->name, str, alen) == 0)
+ return 0;
+ }
}
return 1;
}
static int
-isofs_hash(struct dentry *dentry, struct qstr *qstr)
+isofs_hash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
return isofs_hash_common(dentry, qstr, 0);
}
static int
-isofs_hashi(struct dentry *dentry, struct qstr *qstr)
+isofs_hashi(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
return isofs_hashi_common(dentry, qstr, 0);
}
static int
-isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return isofs_dentry_cmp_common(dentry, a, b, 0);
+ return isofs_dentry_cmp_common(len, str, name, 0, 0);
}
static int
-isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return isofs_dentry_cmpi_common(dentry, a, b, 0);
+ return isofs_dentry_cmp_common(len, str, name, 0, 1);
}
#ifdef CONFIG_JOLIET
static int
-isofs_hash_ms(struct dentry *dentry, struct qstr *qstr)
+isofs_hash_ms(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
return isofs_hash_common(dentry, qstr, 1);
}
static int
-isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
+isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
return isofs_hashi_common(dentry, qstr, 1);
}
static int
-isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return isofs_dentry_cmp_common(dentry, a, b, 1);
+ return isofs_dentry_cmp_common(len, str, name, 1, 0);
}
static int
-isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- return isofs_dentry_cmpi_common(dentry, a, b, 1);
+ return isofs_dentry_cmp_common(len, str, name, 1, 1);
}
#endif
@@ -932,7 +949,7 @@ root_found:
table += 2;
if (opt.check == 'r')
table++;
- s->s_root->d_op = &isofs_dentry_ops[table];
+ d_set_d_op(s->s_root, &isofs_dentry_ops[table]);
kfree(opt.iocharset);
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index 0d23abfd4280..679a849c3b27 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -37,7 +37,8 @@ isofs_cmp(struct dentry *dentry, const char *compare, int dlen)
qstr.name = compare;
qstr.len = dlen;
- return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr);
+ return dentry->d_op->d_compare(NULL, NULL, NULL, NULL,
+ dentry->d_name.len, dentry->d_name.name, &qstr);
}
/*
@@ -171,7 +172,7 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
struct inode *inode;
struct page *page;
- dentry->d_op = dir->i_sb->s_root->d_op;
+ d_set_d_op(dentry, dir->i_sb->s_root->d_op);
page = alloc_page(GFP_USER);
if (!page)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index f837ba953529..2447bd86f801 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -43,6 +43,7 @@
#include <linux/vmalloc.h>
#include <linux/backing-dev.h>
#include <linux/bitops.h>
+#include <linux/ratelimit.h>
#define CREATE_TRACE_POINTS
#include <trace/events/jbd2.h>
@@ -827,7 +828,7 @@ static journal_t * journal_init_common (void)
journal = kzalloc(sizeof(*journal), GFP_KERNEL);
if (!journal)
- goto fail;
+ return NULL;
init_waitqueue_head(&journal->j_wait_transaction_locked);
init_waitqueue_head(&journal->j_wait_logspace);
@@ -852,14 +853,12 @@ static journal_t * journal_init_common (void)
err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
if (err) {
kfree(journal);
- goto fail;
+ return NULL;
}
spin_lock_init(&journal->j_history_lock);
return journal;
-fail:
- return NULL;
}
/* jbd2_journal_init_dev and jbd2_journal_init_inode:
@@ -1982,7 +1981,6 @@ static void jbd2_journal_destroy_jbd2_journal_head_cache(void)
static struct journal_head *journal_alloc_journal_head(void)
{
struct journal_head *ret;
- static unsigned long last_warning;
#ifdef CONFIG_JBD2_DEBUG
atomic_inc(&nr_journal_heads);
@@ -1990,11 +1988,7 @@ static struct journal_head *journal_alloc_journal_head(void)
ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
if (!ret) {
jbd_debug(1, "out of memory for journal_head\n");
- if (time_after(jiffies, last_warning + 5*HZ)) {
- printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
- __func__);
- last_warning = jiffies;
- }
+ pr_notice_ratelimited("ENOMEM in %s, retrying.\n", __func__);
while (!ret) {
yield();
ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 2bc4d5f116f1..1cad869494f0 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -299,10 +299,10 @@ int jbd2_journal_skip_recovery(journal_t *journal)
#ifdef CONFIG_JBD2_DEBUG
int dropped = info.end_transaction -
be32_to_cpu(journal->j_superblock->s_sequence);
-#endif
jbd_debug(1,
"JBD: ignoring %d transaction%s from the journal.\n",
dropped, (dropped == 1) ? "" : "s");
+#endif
journal->j_transaction_sequence = ++info.end_transaction;
}
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 6bf0a242613e..394893242ae3 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -340,9 +340,7 @@ handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int gfp_mask)
jbd2_free_handle(handle);
current->journal_info = NULL;
handle = ERR_PTR(err);
- goto out;
}
-out:
return handle;
}
EXPORT_SYMBOL(jbd2__journal_start);
@@ -589,7 +587,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
transaction = handle->h_transaction;
journal = transaction->t_journal;
- jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy);
+ jbd_debug(5, "journal_head %p, force_copy %d\n", jh, force_copy);
JBUFFER_TRACE(jh, "entry");
repeat:
@@ -774,7 +772,7 @@ done:
J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)),
"Possible IO failure.\n");
page = jh2bh(jh)->b_page;
- offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
+ offset = offset_in_page(jh2bh(jh)->b_data);
source = kmap_atomic(page, KM_USER0);
/* Fire data frozen trigger just before we copy the data */
jbd2_buffer_frozen_trigger(jh, source + offset,
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 85c6be2db02f..3005ec4520ad 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -336,14 +336,13 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
#ifndef __ECOS
if (jffs2_blocks_use_vmalloc(c))
- c->blocks = vmalloc(size);
+ c->blocks = vzalloc(size);
else
#endif
- c->blocks = kmalloc(size, GFP_KERNEL);
+ c->blocks = kzalloc(size, GFP_KERNEL);
if (!c->blocks)
return -ENOMEM;
- memset(c->blocks, 0, size);
for (i=0; i<c->nr_blocks; i++) {
INIT_LIST_HEAD(&c->blocks[i].list);
c->blocks[i].offset = i * c->sector_size;
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index f864005de64c..0bc6a6c80a56 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -144,4 +144,4 @@ struct jffs2_sb_info {
void *os_priv;
};
-#endif /* _JFFS2_FB_SB */
+#endif /* _JFFS2_FS_SB */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index c86041b866a4..853b8e300084 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -40,11 +40,18 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb)
return &f->vfs_inode;
}
-static void jffs2_destroy_inode(struct inode *inode)
+static void jffs2_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));
}
+static void jffs2_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, jffs2_i_callback);
+}
+
static void jffs2_i_init_once(void *foo)
{
struct jffs2_inode_info *f = foo;
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 9b572ca40a49..4f9cc0482949 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -151,7 +151,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
offset, je32_to_cpu(rx.hdr_crc), crc);
xd->flags |= JFFS2_XFLAGS_INVALID;
- return EIO;
+ return -EIO;
}
totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
@@ -167,7 +167,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
je32_to_cpu(rx.xid), xd->xid,
je32_to_cpu(rx.version), xd->version);
xd->flags |= JFFS2_XFLAGS_INVALID;
- return EIO;
+ return -EIO;
}
xd->xprefix = rx.xprefix;
xd->name_len = rx.name_len;
@@ -230,7 +230,7 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum
ref_offset(xd->node), xd->data_crc, crc);
kfree(data);
xd->flags |= JFFS2_XFLAGS_INVALID;
- return EIO;
+ return -EIO;
}
xd->flags |= JFFS2_XFLAGS_HOT;
@@ -268,7 +268,7 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
if (xd->xname)
return 0;
if (xd->flags & JFFS2_XFLAGS_INVALID)
- return EIO;
+ return -EIO;
if (unlikely(is_xattr_datum_unchecked(c, xd)))
rc = do_verify_xattr_datum(c, xd);
if (!rc)
@@ -460,7 +460,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
if (crc != je32_to_cpu(rr.node_crc)) {
JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
offset, je32_to_cpu(rr.node_crc), crc);
- return EIO;
+ return -EIO;
}
if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
|| je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
@@ -470,7 +470,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
- return EIO;
+ return -EIO;
}
ref->ino = je32_to_cpu(rr.ino);
ref->xid = je32_to_cpu(rr.xid);
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index e1b8493b9aaa..278e3fb40b71 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb)
* file systems to log may have n-to-1 relationship;
*/
- bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE);
+ bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
+ log);
if (IS_ERR(bdev)) {
rc = -PTR_ERR(bdev);
goto free;
}
- if ((rc = bd_claim(bdev, log))) {
- goto close;
- }
-
log->bdev = bdev;
memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
@@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb)
* initialize log:
*/
if ((rc = lmLogInit(log)))
- goto unclaim;
+ goto close;
list_add(&log->journal_list, &jfs_external_logs);
@@ -1163,11 +1160,8 @@ journal_found:
list_del(&log->journal_list);
lbmLogShutdown(log);
- unclaim:
- bd_release(bdev);
-
close: /* close external log device */
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
free: /* free log descriptor */
mutex_unlock(&jfs_log_mutex);
@@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb)
bdev = log->bdev;
rc = lmLogShutdown(log);
- bd_release(bdev);
- blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
kfree(log);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 231ca4af9bce..a151cbdec626 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -18,6 +18,7 @@
*/
#include <linux/fs.h>
+#include <linux/namei.h>
#include <linux/ctype.h>
#include <linux/quotaops.h>
#include <linux/exportfs.h>
@@ -1465,7 +1466,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
jfs_info("jfs_lookup: name = %s", name);
if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
- dentry->d_op = &jfs_ci_dentry_operations;
+ d_set_d_op(dentry, &jfs_ci_dentry_operations);
if ((name[0] == '.') && (len == 1))
inum = dip->i_ino;
@@ -1494,7 +1495,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
dentry = d_splice_alias(ip, dentry);
if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
- dentry->d_op = &jfs_ci_dentry_operations;
+ d_set_d_op(dentry, &jfs_ci_dentry_operations);
return dentry;
}
@@ -1573,7 +1574,8 @@ const struct file_operations jfs_dir_operations = {
.llseek = generic_file_llseek,
};
-static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
+static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode,
+ struct qstr *this)
{
unsigned long hash;
int i;
@@ -1586,32 +1588,61 @@ static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
return 0;
}
-static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b)
+static int jfs_ci_compare(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
int i, result = 1;
- if (a->len != b->len)
+ if (len != name->len)
goto out;
- for (i=0; i < a->len; i++) {
- if (tolower(a->name[i]) != tolower(b->name[i]))
+ for (i=0; i < len; i++) {
+ if (tolower(str[i]) != tolower(name->name[i]))
goto out;
}
result = 0;
+out:
+ return result;
+}
+static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
/*
- * We want creates to preserve case. A negative dentry, a, that
- * has a different case than b may cause a new entry to be created
- * with the wrong case. Since we can't tell if a comes from a negative
- * dentry, we blindly replace it with b. This should be harmless if
- * a is not a negative dentry.
+ * This is not negative dentry. Always valid.
+ *
+ * Note, rename() to existing directory entry will have ->d_inode,
+ * and will use existing name which isn't specified name by user.
+ *
+ * We may be able to drop this positive dentry here. But dropping
+ * positive dentry isn't good idea. So it's unsupported like
+ * rename("filename", "FILENAME") for now.
*/
- memcpy((unsigned char *)a->name, b->name, a->len);
-out:
- return result;
+ if (dentry->d_inode)
+ return 1;
+
+ /*
+ * This may be nfsd (or something), anyway, we can't see the
+ * intent of this. So, since this can be for creation, drop it.
+ */
+ if (!nd)
+ return 0;
+
+ /*
+ * Drop the negative dentry, in order to make sure to use the
+ * case sensitive name which is specified by user if this is
+ * for creation.
+ */
+ if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
+ if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
+ return 0;
+ }
+ return 1;
}
const struct dentry_operations jfs_ci_dentry_operations =
{
.d_hash = jfs_ci_hash,
.d_compare = jfs_ci_compare,
+ .d_revalidate = jfs_ci_revalidate,
};
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 0669fc1cc3bf..3150d766e0d4 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -115,6 +115,14 @@ static struct inode *jfs_alloc_inode(struct super_block *sb)
return &jfs_inode->vfs_inode;
}
+static void jfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct jfs_inode_info *ji = JFS_IP(inode);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(jfs_inode_cachep, ji);
+}
+
static void jfs_destroy_inode(struct inode *inode)
{
struct jfs_inode_info *ji = JFS_IP(inode);
@@ -128,7 +136,7 @@ static void jfs_destroy_inode(struct inode *inode)
ji->active_ag = -1;
}
spin_unlock_irq(&ji->ag_lock);
- kmem_cache_free(jfs_inode_cachep, ji);
+ call_rcu(&inode->i_rcu, jfs_i_callback);
}
static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -517,7 +525,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
goto out_no_root;
if (sbi->mntflag & JFS_OS2)
- sb->s_root->d_op = &jfs_ci_dentry_operations;
+ d_set_d_op(sb->s_root, &jfs_ci_dentry_operations);
/* logical blocks are represented by 40 bits in pxd_t, etc. */
sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;
diff --git a/fs/libfs.c b/fs/libfs.c
index a3accdf528ad..889311e3d06b 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -16,6 +16,11 @@
#include <asm/uaccess.h>
+static inline int simple_positive(struct dentry *dentry)
+{
+ return dentry->d_inode && !d_unhashed(dentry);
+}
+
int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
@@ -37,7 +42,7 @@ int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
* Retaining negative dentries for an in-memory filesystem just wastes
* memory and lookup time: arrange for them to be deleted immediately.
*/
-static int simple_delete_dentry(struct dentry *dentry)
+static int simple_delete_dentry(const struct dentry *dentry)
{
return 1;
}
@@ -54,7 +59,7 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct na
if (dentry->d_name.len > NAME_MAX)
return ERR_PTR(-ENAMETOOLONG);
- dentry->d_op = &simple_dentry_operations;
+ d_set_d_op(dentry, &simple_dentry_operations);
d_add(dentry, NULL);
return NULL;
}
@@ -76,7 +81,8 @@ int dcache_dir_close(struct inode *inode, struct file *file)
loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
{
- mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
+ struct dentry *dentry = file->f_path.dentry;
+ mutex_lock(&dentry->d_inode->i_mutex);
switch (origin) {
case 1:
offset += file->f_pos;
@@ -84,7 +90,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
if (offset >= 0)
break;
default:
- mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
+ mutex_unlock(&dentry->d_inode->i_mutex);
return -EINVAL;
}
if (offset != file->f_pos) {
@@ -94,21 +100,24 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
struct dentry *cursor = file->private_data;
loff_t n = file->f_pos - 2;
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+ /* d_lock not required for cursor */
list_del(&cursor->d_u.d_child);
- p = file->f_path.dentry->d_subdirs.next;
- while (n && p != &file->f_path.dentry->d_subdirs) {
+ p = dentry->d_subdirs.next;
+ while (n && p != &dentry->d_subdirs) {
struct dentry *next;
next = list_entry(p, struct dentry, d_u.d_child);
- if (!d_unhashed(next) && next->d_inode)
+ spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
+ if (simple_positive(next))
n--;
+ spin_unlock(&next->d_lock);
p = p->next;
}
list_add_tail(&cursor->d_u.d_child, p);
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
}
}
- mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
+ mutex_unlock(&dentry->d_inode->i_mutex);
return offset;
}
@@ -148,29 +157,35 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
i++;
/* fallthrough */
default:
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
if (filp->f_pos == 2)
list_move(q, &dentry->d_subdirs);
for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
struct dentry *next;
next = list_entry(p, struct dentry, d_u.d_child);
- if (d_unhashed(next) || !next->d_inode)
+ spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
+ if (!simple_positive(next)) {
+ spin_unlock(&next->d_lock);
continue;
+ }
- spin_unlock(&dcache_lock);
+ spin_unlock(&next->d_lock);
+ spin_unlock(&dentry->d_lock);
if (filldir(dirent, next->d_name.name,
next->d_name.len, filp->f_pos,
next->d_inode->i_ino,
dt_type(next->d_inode)) < 0)
return 0;
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+ spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
/* next is still alive */
list_move(q, p);
+ spin_unlock(&next->d_lock);
p = q;
filp->f_pos++;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
}
return 0;
}
@@ -259,23 +274,23 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den
return 0;
}
-static inline int simple_positive(struct dentry *dentry)
-{
- return dentry->d_inode && !d_unhashed(dentry);
-}
-
int simple_empty(struct dentry *dentry)
{
struct dentry *child;
int ret = 0;
- spin_lock(&dcache_lock);
- list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
- if (simple_positive(child))
+ spin_lock(&dentry->d_lock);
+ list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
+ spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
+ if (simple_positive(child)) {
+ spin_unlock(&child->d_lock);
goto out;
+ }
+ spin_unlock(&child->d_lock);
+ }
ret = 1;
out:
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
return ret;
}
diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile
index 97f6073ab339..ca58d64374ca 100644
--- a/fs/lockd/Makefile
+++ b/fs/lockd/Makefile
@@ -4,7 +4,7 @@
obj-$(CONFIG_LOCKD) += lockd.o
-lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \
- svcproc.o svcsubs.o mon.o xdr.o grace.o
-lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o
+lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
+ svcshare.o svcproc.o svcsubs.o mon.o xdr.o grace.o
+lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
lockd-objs := $(lockd-objs-y)
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
new file mode 100644
index 000000000000..f848b52c67b1
--- /dev/null
+++ b/fs/lockd/clnt4xdr.c
@@ -0,0 +1,605 @@
+/*
+ * linux/fs/lockd/clnt4xdr.c
+ *
+ * XDR functions to encode/decode NLM version 4 RPC arguments and results.
+ *
+ * NLM client-side only.
+ *
+ * Copyright (C) 2010, Oracle. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/lockd/lockd.h>
+
+#define NLMDBG_FACILITY NLMDBG_XDR
+
+#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
+# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
+#endif
+
+#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN)
+# error "NLM host name cannot be larger than NLM's maximum string length!"
+#endif
+
+/*
+ * Declare the space requirements for NLM arguments and replies as
+ * number of 32bit-words
+ */
+#define NLM4_void_sz (0)
+#define NLM4_cookie_sz (1+(NLM_MAXCOOKIELEN>>2))
+#define NLM4_caller_sz (1+(NLMCLNT_OHSIZE>>2))
+#define NLM4_owner_sz (1+(NLMCLNT_OHSIZE>>2))
+#define NLM4_fhandle_sz (1+(NFS3_FHSIZE>>2))
+#define NLM4_lock_sz (5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz)
+#define NLM4_holder_sz (6+NLM4_owner_sz)
+
+#define NLM4_testargs_sz (NLM4_cookie_sz+1+NLM4_lock_sz)
+#define NLM4_lockargs_sz (NLM4_cookie_sz+4+NLM4_lock_sz)
+#define NLM4_cancargs_sz (NLM4_cookie_sz+2+NLM4_lock_sz)
+#define NLM4_unlockargs_sz (NLM4_cookie_sz+NLM4_lock_sz)
+
+#define NLM4_testres_sz (NLM4_cookie_sz+1+NLM4_holder_sz)
+#define NLM4_res_sz (NLM4_cookie_sz+1)
+#define NLM4_norep_sz (0)
+
+
+static s64 loff_t_to_s64(loff_t offset)
+{
+ s64 res;
+
+ if (offset >= NLM4_OFFSET_MAX)
+ res = NLM4_OFFSET_MAX;
+ else if (offset <= -NLM4_OFFSET_MAX)
+ res = -NLM4_OFFSET_MAX;
+ else
+ res = offset;
+ return res;
+}
+
+static void nlm4_compute_offsets(const struct nlm_lock *lock,
+ u64 *l_offset, u64 *l_len)
+{
+ const struct file_lock *fl = &lock->fl;
+
+ BUG_ON(fl->fl_start > NLM4_OFFSET_MAX);
+ BUG_ON(fl->fl_end > NLM4_OFFSET_MAX &&
+ fl->fl_end != OFFSET_MAX);
+
+ *l_offset = loff_t_to_s64(fl->fl_start);
+ if (fl->fl_end == OFFSET_MAX)
+ *l_len = 0;
+ else
+ *l_len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1);
+}
+
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+{
+ dprintk("lockd: %s prematurely hit the end of our receive buffer. "
+ "Remaining buffer length is %tu words.\n",
+ func, xdr->end - xdr->p);
+}
+
+
+/*
+ * Encode/decode NLMv4 basic data types
+ *
+ * Basic NLMv4 data types are defined in Appendix II, section 6.1.4
+ * of RFC 1813: "NFS Version 3 Protocol Specification" and in Chapter
+ * 10 of X/Open's "Protocols for Interworking: XNFS, Version 3W".
+ *
+ * Not all basic data types have their own encoding and decoding
+ * functions. For run-time efficiency, some data types are encoded
+ * or decoded inline.
+ */
+
+static void encode_bool(struct xdr_stream *xdr, const int value)
+{
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, 4);
+ *p = value ? xdr_one : xdr_zero;
+}
+
+static void encode_int32(struct xdr_stream *xdr, const s32 value)
+{
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, 4);
+ *p = cpu_to_be32(value);
+}
+
+/*
+ * typedef opaque netobj<MAXNETOBJ_SZ>
+ */
+static void encode_netobj(struct xdr_stream *xdr,
+ const u8 *data, const unsigned int length)
+{
+ __be32 *p;
+
+ BUG_ON(length > XDR_MAX_NETOBJ);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, data, length);
+}
+
+static int decode_netobj(struct xdr_stream *xdr,
+ struct xdr_netobj *obj)
+{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p++);
+ if (unlikely(length > XDR_MAX_NETOBJ))
+ goto out_size;
+ obj->len = length;
+ obj->data = (u8 *)p;
+ return 0;
+out_size:
+ dprintk("NFS: returned netobj was too long: %u\n", length);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * netobj cookie;
+ */
+static void encode_cookie(struct xdr_stream *xdr,
+ const struct nlm_cookie *cookie)
+{
+ BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
+ encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
+}
+
+static int decode_cookie(struct xdr_stream *xdr,
+ struct nlm_cookie *cookie)
+{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p++);
+ /* apparently HPUX can return empty cookies */
+ if (length == 0)
+ goto out_hpux;
+ if (length > NLM_MAXCOOKIELEN)
+ goto out_size;
+ p = xdr_inline_decode(xdr, length);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ cookie->len = length;
+ memcpy(cookie->data, p, length);
+ return 0;
+out_hpux:
+ cookie->len = 4;
+ memset(cookie->data, 0, 4);
+ return 0;
+out_size:
+ dprintk("NFS: returned cookie was too long: %u\n", length);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * netobj fh;
+ */
+static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
+{
+ BUG_ON(fh->size > NFS3_FHSIZE);
+ encode_netobj(xdr, (u8 *)&fh->data, fh->size);
+}
+
+/*
+ * enum nlm4_stats {
+ * NLM4_GRANTED = 0,
+ * NLM4_DENIED = 1,
+ * NLM4_DENIED_NOLOCKS = 2,
+ * NLM4_BLOCKED = 3,
+ * NLM4_DENIED_GRACE_PERIOD = 4,
+ * NLM4_DEADLCK = 5,
+ * NLM4_ROFS = 6,
+ * NLM4_STALE_FH = 7,
+ * NLM4_FBIG = 8,
+ * NLM4_FAILED = 9
+ * };
+ *
+ * struct nlm4_stat {
+ * nlm4_stats stat;
+ * };
+ *
+ * NB: we don't swap bytes for the NLM status values. The upper
+ * layers deal directly with the status value in network byte
+ * order.
+ */
+static void encode_nlm4_stat(struct xdr_stream *xdr,
+ const __be32 stat)
+{
+ __be32 *p;
+
+ BUG_ON(be32_to_cpu(stat) > NLM_FAILED);
+ p = xdr_reserve_space(xdr, 4);
+ *p = stat;
+}
+
+static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (unlikely(*p > nlm4_failed))
+ goto out_bad_xdr;
+ *stat = *p;
+ return 0;
+out_bad_xdr:
+ dprintk("%s: server returned invalid nlm4_stats value: %u\n",
+ __func__, be32_to_cpup(p));
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * struct nlm4_holder {
+ * bool exclusive;
+ * int32 svid;
+ * netobj oh;
+ * uint64 l_offset;
+ * uint64 l_len;
+ * };
+ */
+static void encode_nlm4_holder(struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ const struct nlm_lock *lock = &result->lock;
+ u64 l_offset, l_len;
+ __be32 *p;
+
+ encode_bool(xdr, lock->fl.fl_type == F_RDLCK);
+ encode_int32(xdr, lock->svid);
+ encode_netobj(xdr, lock->oh.data, lock->oh.len);
+
+ p = xdr_reserve_space(xdr, 4 + 4);
+ nlm4_compute_offsets(lock, &l_offset, &l_len);
+ p = xdr_encode_hyper(p, l_offset);
+ xdr_encode_hyper(p, l_len);
+}
+
+static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result)
+{
+ struct nlm_lock *lock = &result->lock;
+ struct file_lock *fl = &lock->fl;
+ u64 l_offset, l_len;
+ u32 exclusive;
+ int error;
+ __be32 *p;
+ s32 end;
+
+ memset(lock, 0, sizeof(*lock));
+ locks_init_lock(fl);
+
+ p = xdr_inline_decode(xdr, 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ exclusive = be32_to_cpup(p++);
+ lock->svid = be32_to_cpup(p);
+ fl->fl_pid = (pid_t)lock->svid;
+
+ error = decode_netobj(xdr, &lock->oh);
+ if (unlikely(error))
+ goto out;
+
+ p = xdr_inline_decode(xdr, 8 + 8);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+
+ fl->fl_flags = FL_POSIX;
+ fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK;
+ p = xdr_decode_hyper(p, &l_offset);
+ xdr_decode_hyper(p, &l_len);
+ end = l_offset + l_len - 1;
+
+ fl->fl_start = (loff_t)l_offset;
+ if (l_len == 0 || end < 0)
+ fl->fl_end = OFFSET_MAX;
+ else
+ fl->fl_end = (loff_t)end;
+ error = 0;
+out:
+ return error;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * string caller_name<LM_MAXSTRLEN>;
+ */
+static void encode_caller_name(struct xdr_stream *xdr, const char *name)
+{
+ /* NB: client-side does not set lock->len */
+ u32 length = strlen(name);
+ __be32 *p;
+
+ BUG_ON(length > NLM_MAXSTRLEN);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, name, length);
+}
+
+/*
+ * struct nlm4_lock {
+ * string caller_name<LM_MAXSTRLEN>;
+ * netobj fh;
+ * netobj oh;
+ * int32 svid;
+ * uint64 l_offset;
+ * uint64 l_len;
+ * };
+ */
+static void encode_nlm4_lock(struct xdr_stream *xdr,
+ const struct nlm_lock *lock)
+{
+ u64 l_offset, l_len;
+ __be32 *p;
+
+ encode_caller_name(xdr, lock->caller);
+ encode_fh(xdr, &lock->fh);
+ encode_netobj(xdr, lock->oh.data, lock->oh.len);
+
+ p = xdr_reserve_space(xdr, 4 + 8 + 8);
+ *p++ = cpu_to_be32(lock->svid);
+
+ nlm4_compute_offsets(lock, &l_offset, &l_len);
+ p = xdr_encode_hyper(p, l_offset);
+ xdr_encode_hyper(p, l_len);
+}
+
+
+/*
+ * NLMv4 XDR encode functions
+ *
+ * NLMv4 argument types are defined in Appendix II of RFC 1813:
+ * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's
+ * "Protocols for Interworking: XNFS, Version 3W".
+ */
+
+/*
+ * struct nlm4_testargs {
+ * netobj cookie;
+ * bool exclusive;
+ * struct nlm4_lock alock;
+ * };
+ */
+static void nlm4_xdr_enc_testargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm4_lock(xdr, lock);
+}
+
+/*
+ * struct nlm4_lockargs {
+ * netobj cookie;
+ * bool block;
+ * bool exclusive;
+ * struct nlm4_lock alock;
+ * bool reclaim;
+ * int state;
+ * };
+ */
+static void nlm4_xdr_enc_lockargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, args->block);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm4_lock(xdr, lock);
+ encode_bool(xdr, args->reclaim);
+ encode_int32(xdr, args->state);
+}
+
+/*
+ * struct nlm4_cancargs {
+ * netobj cookie;
+ * bool block;
+ * bool exclusive;
+ * struct nlm4_lock alock;
+ * };
+ */
+static void nlm4_xdr_enc_cancargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, args->block);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm4_lock(xdr, lock);
+}
+
+/*
+ * struct nlm4_unlockargs {
+ * netobj cookie;
+ * struct nlm4_lock alock;
+ * };
+ */
+static void nlm4_xdr_enc_unlockargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_nlm4_lock(xdr, lock);
+}
+
+/*
+ * struct nlm4_res {
+ * netobj cookie;
+ * nlm4_stat stat;
+ * };
+ */
+static void nlm4_xdr_enc_res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ encode_cookie(xdr, &result->cookie);
+ encode_nlm4_stat(xdr, result->status);
+}
+
+/*
+ * union nlm4_testrply switch (nlm4_stats stat) {
+ * case NLM4_DENIED:
+ * struct nlm4_holder holder;
+ * default:
+ * void;
+ * };
+ *
+ * struct nlm4_testres {
+ * netobj cookie;
+ * nlm4_testrply test_stat;
+ * };
+ */
+static void nlm4_xdr_enc_testres(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ encode_cookie(xdr, &result->cookie);
+ encode_nlm4_stat(xdr, result->status);
+ if (result->status == nlm_lck_denied)
+ encode_nlm4_holder(xdr, result);
+}
+
+
+/*
+ * NLMv4 XDR decode functions
+ *
+ * NLMv4 argument types are defined in Appendix II of RFC 1813:
+ * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's
+ * "Protocols for Interworking: XNFS, Version 3W".
+ */
+
+/*
+ * union nlm4_testrply switch (nlm4_stats stat) {
+ * case NLM4_DENIED:
+ * struct nlm4_holder holder;
+ * default:
+ * void;
+ * };
+ *
+ * struct nlm4_testres {
+ * netobj cookie;
+ * nlm4_testrply test_stat;
+ * };
+ */
+static int decode_nlm4_testrply(struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_nlm4_stat(xdr, &result->status);
+ if (unlikely(error))
+ goto out;
+ if (result->status == nlm_lck_denied)
+ error = decode_nlm4_holder(xdr, result);
+out:
+ return error;
+}
+
+static int nlm4_xdr_dec_testres(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_cookie(xdr, &result->cookie);
+ if (unlikely(error))
+ goto out;
+ error = decode_nlm4_testrply(xdr, result);
+out:
+ return error;
+}
+
+/*
+ * struct nlm4_res {
+ * netobj cookie;
+ * nlm4_stat stat;
+ * };
+ */
+static int nlm4_xdr_dec_res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_cookie(xdr, &result->cookie);
+ if (unlikely(error))
+ goto out;
+ error = decode_nlm4_stat(xdr, &result->status);
+out:
+ return error;
+}
+
+
+/*
+ * For NLM, a void procedure really returns nothing
+ */
+#define nlm4_xdr_dec_norep NULL
+
+#define PROC(proc, argtype, restype) \
+[NLMPROC_##proc] = { \
+ .p_proc = NLMPROC_##proc, \
+ .p_encode = (kxdreproc_t)nlm4_xdr_enc_##argtype, \
+ .p_decode = (kxdrdproc_t)nlm4_xdr_dec_##restype, \
+ .p_arglen = NLM4_##argtype##_sz, \
+ .p_replen = NLM4_##restype##_sz, \
+ .p_statidx = NLMPROC_##proc, \
+ .p_name = #proc, \
+ }
+
+static struct rpc_procinfo nlm4_procedures[] = {
+ PROC(TEST, testargs, testres),
+ PROC(LOCK, lockargs, res),
+ PROC(CANCEL, cancargs, res),
+ PROC(UNLOCK, unlockargs, res),
+ PROC(GRANTED, testargs, res),
+ PROC(TEST_MSG, testargs, norep),
+ PROC(LOCK_MSG, lockargs, norep),
+ PROC(CANCEL_MSG, cancargs, norep),
+ PROC(UNLOCK_MSG, unlockargs, norep),
+ PROC(GRANTED_MSG, testargs, norep),
+ PROC(TEST_RES, testres, norep),
+ PROC(LOCK_RES, res, norep),
+ PROC(CANCEL_RES, res, norep),
+ PROC(UNLOCK_RES, res, norep),
+ PROC(GRANTED_RES, res, norep),
+};
+
+struct rpc_version nlm_version4 = {
+ .number = 4,
+ .nrprocs = ARRAY_SIZE(nlm4_procedures),
+ .procs = nlm4_procedures,
+};
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 25509eb28fd7..8d4ea8351e3d 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(nlmclnt_init);
*/
void nlmclnt_done(struct nlm_host *host)
{
- nlm_release_host(host);
+ nlmclnt_release_host(host);
lockd_down();
}
EXPORT_SYMBOL_GPL(nlmclnt_done);
@@ -273,7 +273,7 @@ restart:
spin_unlock(&nlm_blocked_lock);
/* Release host handle after use */
- nlm_release_host(host);
+ nlmclnt_release_host(host);
lockd_down();
return 0;
}
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 332c54cf75e0..adb45ec9038c 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -58,7 +58,7 @@ static void nlm_put_lockowner(struct nlm_lockowner *lockowner)
return;
list_del(&lockowner->list);
spin_unlock(&lockowner->host->h_lock);
- nlm_release_host(lockowner->host);
+ nlmclnt_release_host(lockowner->host);
kfree(lockowner);
}
@@ -207,22 +207,22 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
printk("nlm_alloc_call: failed, waiting for memory\n");
schedule_timeout_interruptible(5*HZ);
}
- nlm_release_host(host);
+ nlmclnt_release_host(host);
return NULL;
}
-void nlm_release_call(struct nlm_rqst *call)
+void nlmclnt_release_call(struct nlm_rqst *call)
{
if (!atomic_dec_and_test(&call->a_count))
return;
- nlm_release_host(call->a_host);
+ nlmclnt_release_host(call->a_host);
nlmclnt_release_lockargs(call);
kfree(call);
}
static void nlmclnt_rpc_release(void *data)
{
- nlm_release_call(data);
+ nlmclnt_release_call(data);
}
static int nlm_wait_on_grace(wait_queue_head_t *queue)
@@ -436,7 +436,7 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl)
status = nlm_stat_to_errno(req->a_res.status);
}
out:
- nlm_release_call(req);
+ nlmclnt_release_call(req);
return status;
}
@@ -593,7 +593,7 @@ again:
out_unblock:
nlmclnt_finish_block(block);
out:
- nlm_release_call(req);
+ nlmclnt_release_call(req);
return status;
out_unlock:
/* Fatal error: ensure that we remove the lock altogether */
@@ -694,7 +694,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
/* What to do now? I'm out of my depth... */
status = -ENOLCK;
out:
- nlm_release_call(req);
+ nlmclnt_release_call(req);
return status;
}
@@ -755,7 +755,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl
NLMPROC_CANCEL, &nlmclnt_cancel_ops);
if (status == 0 && req->a_res.status == nlm_lck_denied)
status = -ENOLCK;
- nlm_release_call(req);
+ nlmclnt_release_call(req);
return status;
}
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
new file mode 100644
index 000000000000..180ac34feb9a
--- /dev/null
+++ b/fs/lockd/clntxdr.c
@@ -0,0 +1,627 @@
+/*
+ * linux/fs/lockd/clntxdr.c
+ *
+ * XDR functions to encode/decode NLM version 3 RPC arguments and results.
+ * NLM version 3 is backwards compatible with NLM versions 1 and 2.
+ *
+ * NLM client-side only.
+ *
+ * Copyright (C) 2010, Oracle. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/lockd/lockd.h>
+
+#define NLMDBG_FACILITY NLMDBG_XDR
+
+#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
+# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
+#endif
+
+/*
+ * Declare the space requirements for NLM arguments and replies as
+ * number of 32bit-words
+ */
+#define NLM_cookie_sz (1+(NLM_MAXCOOKIELEN>>2))
+#define NLM_caller_sz (1+(NLMCLNT_OHSIZE>>2))
+#define NLM_owner_sz (1+(NLMCLNT_OHSIZE>>2))
+#define NLM_fhandle_sz (1+(NFS2_FHSIZE>>2))
+#define NLM_lock_sz (3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz)
+#define NLM_holder_sz (4+NLM_owner_sz)
+
+#define NLM_testargs_sz (NLM_cookie_sz+1+NLM_lock_sz)
+#define NLM_lockargs_sz (NLM_cookie_sz+4+NLM_lock_sz)
+#define NLM_cancargs_sz (NLM_cookie_sz+2+NLM_lock_sz)
+#define NLM_unlockargs_sz (NLM_cookie_sz+NLM_lock_sz)
+
+#define NLM_testres_sz (NLM_cookie_sz+1+NLM_holder_sz)
+#define NLM_res_sz (NLM_cookie_sz+1)
+#define NLM_norep_sz (0)
+
+
+static s32 loff_t_to_s32(loff_t offset)
+{
+ s32 res;
+
+ if (offset >= NLM_OFFSET_MAX)
+ res = NLM_OFFSET_MAX;
+ else if (offset <= -NLM_OFFSET_MAX)
+ res = -NLM_OFFSET_MAX;
+ else
+ res = offset;
+ return res;
+}
+
+static void nlm_compute_offsets(const struct nlm_lock *lock,
+ u32 *l_offset, u32 *l_len)
+{
+ const struct file_lock *fl = &lock->fl;
+
+ BUG_ON(fl->fl_start > NLM_OFFSET_MAX);
+ BUG_ON(fl->fl_end > NLM_OFFSET_MAX &&
+ fl->fl_end != OFFSET_MAX);
+
+ *l_offset = loff_t_to_s32(fl->fl_start);
+ if (fl->fl_end == OFFSET_MAX)
+ *l_len = 0;
+ else
+ *l_len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1);
+}
+
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+{
+ dprintk("lockd: %s prematurely hit the end of our receive buffer. "
+ "Remaining buffer length is %tu words.\n",
+ func, xdr->end - xdr->p);
+}
+
+
+/*
+ * Encode/decode NLMv3 basic data types
+ *
+ * Basic NLMv3 data types are not defined in an IETF standards
+ * document. X/Open has a description of these data types that
+ * is useful. See Chapter 10 of "Protocols for Interworking:
+ * XNFS, Version 3W".
+ *
+ * Not all basic data types have their own encoding and decoding
+ * functions. For run-time efficiency, some data types are encoded
+ * or decoded inline.
+ */
+
+static void encode_bool(struct xdr_stream *xdr, const int value)
+{
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, 4);
+ *p = value ? xdr_one : xdr_zero;
+}
+
+static void encode_int32(struct xdr_stream *xdr, const s32 value)
+{
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, 4);
+ *p = cpu_to_be32(value);
+}
+
+/*
+ * typedef opaque netobj<MAXNETOBJ_SZ>
+ */
+static void encode_netobj(struct xdr_stream *xdr,
+ const u8 *data, const unsigned int length)
+{
+ __be32 *p;
+
+ BUG_ON(length > XDR_MAX_NETOBJ);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, data, length);
+}
+
+static int decode_netobj(struct xdr_stream *xdr,
+ struct xdr_netobj *obj)
+{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p++);
+ if (unlikely(length > XDR_MAX_NETOBJ))
+ goto out_size;
+ obj->len = length;
+ obj->data = (u8 *)p;
+ return 0;
+out_size:
+ dprintk("NFS: returned netobj was too long: %u\n", length);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * netobj cookie;
+ */
+static void encode_cookie(struct xdr_stream *xdr,
+ const struct nlm_cookie *cookie)
+{
+ BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
+ encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
+}
+
+static int decode_cookie(struct xdr_stream *xdr,
+ struct nlm_cookie *cookie)
+{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p++);
+ /* apparently HPUX can return empty cookies */
+ if (length == 0)
+ goto out_hpux;
+ if (length > NLM_MAXCOOKIELEN)
+ goto out_size;
+ p = xdr_inline_decode(xdr, length);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ cookie->len = length;
+ memcpy(cookie->data, p, length);
+ return 0;
+out_hpux:
+ cookie->len = 4;
+ memset(cookie->data, 0, 4);
+ return 0;
+out_size:
+ dprintk("NFS: returned cookie was too long: %u\n", length);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * netobj fh;
+ */
+static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
+{
+ BUG_ON(fh->size != NFS2_FHSIZE);
+ encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE);
+}
+
+/*
+ * enum nlm_stats {
+ * LCK_GRANTED = 0,
+ * LCK_DENIED = 1,
+ * LCK_DENIED_NOLOCKS = 2,
+ * LCK_BLOCKED = 3,
+ * LCK_DENIED_GRACE_PERIOD = 4
+ * };
+ *
+ *
+ * struct nlm_stat {
+ * nlm_stats stat;
+ * };
+ *
+ * NB: we don't swap bytes for the NLM status values. The upper
+ * layers deal directly with the status value in network byte
+ * order.
+ */
+
+static void encode_nlm_stat(struct xdr_stream *xdr,
+ const __be32 stat)
+{
+ __be32 *p;
+
+ BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD);
+ p = xdr_reserve_space(xdr, 4);
+ *p = stat;
+}
+
+static int decode_nlm_stat(struct xdr_stream *xdr,
+ __be32 *stat)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (unlikely(*p > nlm_lck_denied_grace_period))
+ goto out_enum;
+ *stat = *p;
+ return 0;
+out_enum:
+ dprintk("%s: server returned invalid nlm_stats value: %u\n",
+ __func__, be32_to_cpup(p));
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * struct nlm_holder {
+ * bool exclusive;
+ * int uppid;
+ * netobj oh;
+ * unsigned l_offset;
+ * unsigned l_len;
+ * };
+ */
+static void encode_nlm_holder(struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ const struct nlm_lock *lock = &result->lock;
+ u32 l_offset, l_len;
+ __be32 *p;
+
+ encode_bool(xdr, lock->fl.fl_type == F_RDLCK);
+ encode_int32(xdr, lock->svid);
+ encode_netobj(xdr, lock->oh.data, lock->oh.len);
+
+ p = xdr_reserve_space(xdr, 4 + 4);
+ nlm_compute_offsets(lock, &l_offset, &l_len);
+ *p++ = cpu_to_be32(l_offset);
+ *p = cpu_to_be32(l_len);
+}
+
+static int decode_nlm_holder(struct xdr_stream *xdr, struct nlm_res *result)
+{
+ struct nlm_lock *lock = &result->lock;
+ struct file_lock *fl = &lock->fl;
+ u32 exclusive, l_offset, l_len;
+ int error;
+ __be32 *p;
+ s32 end;
+
+ memset(lock, 0, sizeof(*lock));
+ locks_init_lock(fl);
+
+ p = xdr_inline_decode(xdr, 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ exclusive = be32_to_cpup(p++);
+ lock->svid = be32_to_cpup(p);
+ fl->fl_pid = (pid_t)lock->svid;
+
+ error = decode_netobj(xdr, &lock->oh);
+ if (unlikely(error))
+ goto out;
+
+ p = xdr_inline_decode(xdr, 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+
+ fl->fl_flags = FL_POSIX;
+ fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK;
+ l_offset = be32_to_cpup(p++);
+ l_len = be32_to_cpup(p);
+ end = l_offset + l_len - 1;
+
+ fl->fl_start = (loff_t)l_offset;
+ if (l_len == 0 || end < 0)
+ fl->fl_end = OFFSET_MAX;
+ else
+ fl->fl_end = (loff_t)end;
+ error = 0;
+out:
+ return error;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * string caller_name<LM_MAXSTRLEN>;
+ */
+static void encode_caller_name(struct xdr_stream *xdr, const char *name)
+{
+ /* NB: client-side does not set lock->len */
+ u32 length = strlen(name);
+ __be32 *p;
+
+ BUG_ON(length > NLM_MAXSTRLEN);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, name, length);
+}
+
+/*
+ * struct nlm_lock {
+ * string caller_name<LM_MAXSTRLEN>;
+ * netobj fh;
+ * netobj oh;
+ * int uppid;
+ * unsigned l_offset;
+ * unsigned l_len;
+ * };
+ */
+static void encode_nlm_lock(struct xdr_stream *xdr,
+ const struct nlm_lock *lock)
+{
+ u32 l_offset, l_len;
+ __be32 *p;
+
+ encode_caller_name(xdr, lock->caller);
+ encode_fh(xdr, &lock->fh);
+ encode_netobj(xdr, lock->oh.data, lock->oh.len);
+
+ p = xdr_reserve_space(xdr, 4 + 4 + 4);
+ *p++ = cpu_to_be32(lock->svid);
+
+ nlm_compute_offsets(lock, &l_offset, &l_len);
+ *p++ = cpu_to_be32(l_offset);
+ *p = cpu_to_be32(l_len);
+}
+
+
+/*
+ * NLMv3 XDR encode functions
+ *
+ * NLMv3 argument types are defined in Chapter 10 of The Open Group's
+ * "Protocols for Interworking: XNFS, Version 3W".
+ */
+
+/*
+ * struct nlm_testargs {
+ * netobj cookie;
+ * bool exclusive;
+ * struct nlm_lock alock;
+ * };
+ */
+static void nlm_xdr_enc_testargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm_lock(xdr, lock);
+}
+
+/*
+ * struct nlm_lockargs {
+ * netobj cookie;
+ * bool block;
+ * bool exclusive;
+ * struct nlm_lock alock;
+ * bool reclaim;
+ * int state;
+ * };
+ */
+static void nlm_xdr_enc_lockargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, args->block);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm_lock(xdr, lock);
+ encode_bool(xdr, args->reclaim);
+ encode_int32(xdr, args->state);
+}
+
+/*
+ * struct nlm_cancargs {
+ * netobj cookie;
+ * bool block;
+ * bool exclusive;
+ * struct nlm_lock alock;
+ * };
+ */
+static void nlm_xdr_enc_cancargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_bool(xdr, args->block);
+ encode_bool(xdr, lock->fl.fl_type == F_WRLCK);
+ encode_nlm_lock(xdr, lock);
+}
+
+/*
+ * struct nlm_unlockargs {
+ * netobj cookie;
+ * struct nlm_lock alock;
+ * };
+ */
+static void nlm_xdr_enc_unlockargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_args *args)
+{
+ const struct nlm_lock *lock = &args->lock;
+
+ encode_cookie(xdr, &args->cookie);
+ encode_nlm_lock(xdr, lock);
+}
+
+/*
+ * struct nlm_res {
+ * netobj cookie;
+ * nlm_stat stat;
+ * };
+ */
+static void nlm_xdr_enc_res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ encode_cookie(xdr, &result->cookie);
+ encode_nlm_stat(xdr, result->status);
+}
+
+/*
+ * union nlm_testrply switch (nlm_stats stat) {
+ * case LCK_DENIED:
+ * struct nlm_holder holder;
+ * default:
+ * void;
+ * };
+ *
+ * struct nlm_testres {
+ * netobj cookie;
+ * nlm_testrply test_stat;
+ * };
+ */
+static void encode_nlm_testrply(struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ if (result->status == nlm_lck_denied)
+ encode_nlm_holder(xdr, result);
+}
+
+static void nlm_xdr_enc_testres(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nlm_res *result)
+{
+ encode_cookie(xdr, &result->cookie);
+ encode_nlm_stat(xdr, result->status);
+ encode_nlm_testrply(xdr, result);
+}
+
+
+/*
+ * NLMv3 XDR decode functions
+ *
+ * NLMv3 result types are defined in Chapter 10 of The Open Group's
+ * "Protocols for Interworking: XNFS, Version 3W".
+ */
+
+/*
+ * union nlm_testrply switch (nlm_stats stat) {
+ * case LCK_DENIED:
+ * struct nlm_holder holder;
+ * default:
+ * void;
+ * };
+ *
+ * struct nlm_testres {
+ * netobj cookie;
+ * nlm_testrply test_stat;
+ * };
+ */
+static int decode_nlm_testrply(struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_nlm_stat(xdr, &result->status);
+ if (unlikely(error))
+ goto out;
+ if (result->status == nlm_lck_denied)
+ error = decode_nlm_holder(xdr, result);
+out:
+ return error;
+}
+
+static int nlm_xdr_dec_testres(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_cookie(xdr, &result->cookie);
+ if (unlikely(error))
+ goto out;
+ error = decode_nlm_testrply(xdr, result);
+out:
+ return error;
+}
+
+/*
+ * struct nlm_res {
+ * netobj cookie;
+ * nlm_stat stat;
+ * };
+ */
+static int nlm_xdr_dec_res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nlm_res *result)
+{
+ int error;
+
+ error = decode_cookie(xdr, &result->cookie);
+ if (unlikely(error))
+ goto out;
+ error = decode_nlm_stat(xdr, &result->status);
+out:
+ return error;
+}
+
+
+/*
+ * For NLM, a void procedure really returns nothing
+ */
+#define nlm_xdr_dec_norep NULL
+
+#define PROC(proc, argtype, restype) \
+[NLMPROC_##proc] = { \
+ .p_proc = NLMPROC_##proc, \
+ .p_encode = (kxdreproc_t)nlm_xdr_enc_##argtype, \
+ .p_decode = (kxdrdproc_t)nlm_xdr_dec_##restype, \
+ .p_arglen = NLM_##argtype##_sz, \
+ .p_replen = NLM_##restype##_sz, \
+ .p_statidx = NLMPROC_##proc, \
+ .p_name = #proc, \
+ }
+
+static struct rpc_procinfo nlm_procedures[] = {
+ PROC(TEST, testargs, testres),
+ PROC(LOCK, lockargs, res),
+ PROC(CANCEL, cancargs, res),
+ PROC(UNLOCK, unlockargs, res),
+ PROC(GRANTED, testargs, res),
+ PROC(TEST_MSG, testargs, norep),
+ PROC(LOCK_MSG, lockargs, norep),
+ PROC(CANCEL_MSG, cancargs, norep),
+ PROC(UNLOCK_MSG, unlockargs, norep),
+ PROC(GRANTED_MSG, testargs, norep),
+ PROC(TEST_RES, testres, norep),
+ PROC(LOCK_RES, res, norep),
+ PROC(CANCEL_RES, res, norep),
+ PROC(UNLOCK_RES, res, norep),
+ PROC(GRANTED_RES, res, norep),
+};
+
+static struct rpc_version nlm_version1 = {
+ .number = 1,
+ .nrprocs = ARRAY_SIZE(nlm_procedures),
+ .procs = nlm_procedures,
+};
+
+static struct rpc_version nlm_version3 = {
+ .number = 3,
+ .nrprocs = ARRAY_SIZE(nlm_procedures),
+ .procs = nlm_procedures,
+};
+
+static struct rpc_version *nlm_versions[] = {
+ [1] = &nlm_version1,
+ [3] = &nlm_version3,
+#ifdef CONFIG_LOCKD_V4
+ [4] = &nlm_version4,
+#endif
+};
+
+static struct rpc_stat nlm_rpc_stats;
+
+struct rpc_program nlm_program = {
+ .name = "lockd",
+ .number = NLM_PROGRAM,
+ .nrvers = ARRAY_SIZE(nlm_versions),
+ .version = nlm_versions,
+ .stats = &nlm_rpc_stats,
+};
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index ed0c59fe23ce..5f1bcb2f06f3 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -25,9 +25,22 @@
#define NLM_HOST_EXPIRE (300 * HZ)
#define NLM_HOST_COLLECT (120 * HZ)
-static struct hlist_head nlm_hosts[NLM_HOST_NRHASH];
+static struct hlist_head nlm_server_hosts[NLM_HOST_NRHASH];
+static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH];
+
+#define for_each_host(host, pos, chain, table) \
+ for ((chain) = (table); \
+ (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \
+ hlist_for_each_entry((host), (pos), (chain), h_hash)
+
+#define for_each_host_safe(host, pos, next, chain, table) \
+ for ((chain) = (table); \
+ (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \
+ hlist_for_each_entry_safe((host), (pos), (next), \
+ (chain), h_hash)
+
static unsigned long next_gc;
-static int nrhosts;
+static unsigned long nrhosts;
static DEFINE_MUTEX(nlm_host_mutex);
static void nlm_gc_hosts(void);
@@ -40,8 +53,6 @@ struct nlm_lookup_host_info {
const u32 version; /* NLM version to search for */
const char *hostname; /* remote's hostname */
const size_t hostname_len; /* it's length */
- const struct sockaddr *src_sap; /* our address (optional) */
- const size_t src_len; /* it's length */
const int noresvport; /* use non-priv port */
};
@@ -88,127 +99,83 @@ static unsigned int nlm_hash_address(const struct sockaddr *sap)
}
/*
- * Common host lookup routine for server & client
+ * Allocate and initialize an nlm_host. Common to both client and server.
*/
-static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
+static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
+ struct nsm_handle *nsm)
{
- struct hlist_head *chain;
- struct hlist_node *pos;
- struct nlm_host *host;
- struct nsm_handle *nsm = NULL;
-
- mutex_lock(&nlm_host_mutex);
+ struct nlm_host *host = NULL;
+ unsigned long now = jiffies;
- if (time_after_eq(jiffies, next_gc))
- nlm_gc_hosts();
-
- /* We may keep several nlm_host objects for a peer, because each
- * nlm_host is identified by
- * (address, protocol, version, server/client)
- * We could probably simplify this a little by putting all those
- * different NLM rpc_clients into one single nlm_host object.
- * This would allow us to have one nlm_host per address.
- */
- chain = &nlm_hosts[nlm_hash_address(ni->sap)];
- hlist_for_each_entry(host, pos, chain, h_hash) {
- if (!rpc_cmp_addr(nlm_addr(host), ni->sap))
- continue;
-
- /* See if we have an NSM handle for this client */
- if (!nsm)
- nsm = host->h_nsmhandle;
-
- if (host->h_proto != ni->protocol)
- continue;
- if (host->h_version != ni->version)
- continue;
- if (host->h_server != ni->server)
- continue;
- if (ni->server && ni->src_len != 0 &&
- !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap))
- continue;
-
- /* Move to head of hash chain. */
- hlist_del(&host->h_hash);
- hlist_add_head(&host->h_hash, chain);
-
- nlm_get_host(host);
- dprintk("lockd: nlm_lookup_host found host %s (%s)\n",
- host->h_name, host->h_addrbuf);
- goto out;
- }
-
- /*
- * The host wasn't in our hash table. If we don't
- * have an NSM handle for it yet, create one.
- */
- if (nsm)
+ if (nsm != NULL)
atomic_inc(&nsm->sm_count);
else {
host = NULL;
nsm = nsm_get_handle(ni->sap, ni->salen,
ni->hostname, ni->hostname_len);
- if (!nsm) {
- dprintk("lockd: nlm_lookup_host failed; "
- "no nsm handle\n");
+ if (unlikely(nsm == NULL)) {
+ dprintk("lockd: %s failed; no nsm handle\n",
+ __func__);
goto out;
}
}
- host = kzalloc(sizeof(*host), GFP_KERNEL);
- if (!host) {
+ host = kmalloc(sizeof(*host), GFP_KERNEL);
+ if (unlikely(host == NULL)) {
+ dprintk("lockd: %s failed; no memory\n", __func__);
nsm_release(nsm);
- dprintk("lockd: nlm_lookup_host failed; no memory\n");
goto out;
}
- host->h_name = nsm->sm_name;
- host->h_addrbuf = nsm->sm_addrbuf;
+
memcpy(nlm_addr(host), ni->sap, ni->salen);
- host->h_addrlen = ni->salen;
+ host->h_addrlen = ni->salen;
rpc_set_port(nlm_addr(host), 0);
- memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len);
- host->h_srcaddrlen = ni->src_len;
+ host->h_srcaddrlen = 0;
+
+ host->h_rpcclnt = NULL;
+ host->h_name = nsm->sm_name;
host->h_version = ni->version;
host->h_proto = ni->protocol;
- host->h_rpcclnt = NULL;
- mutex_init(&host->h_mutex);
- host->h_nextrebind = jiffies + NLM_HOST_REBIND;
- host->h_expires = jiffies + NLM_HOST_EXPIRE;
- atomic_set(&host->h_count, 1);
+ host->h_reclaiming = 0;
+ host->h_server = ni->server;
+ host->h_noresvport = ni->noresvport;
+ host->h_inuse = 0;
init_waitqueue_head(&host->h_gracewait);
init_rwsem(&host->h_rwsem);
- host->h_state = 0; /* pseudo NSM state */
- host->h_nsmstate = 0; /* real NSM state */
- host->h_nsmhandle = nsm;
- host->h_server = ni->server;
- host->h_noresvport = ni->noresvport;
- hlist_add_head(&host->h_hash, chain);
+ host->h_state = 0;
+ host->h_nsmstate = 0;
+ host->h_pidcount = 0;
+ atomic_set(&host->h_count, 1);
+ mutex_init(&host->h_mutex);
+ host->h_nextrebind = now + NLM_HOST_REBIND;
+ host->h_expires = now + NLM_HOST_EXPIRE;
INIT_LIST_HEAD(&host->h_lockowners);
spin_lock_init(&host->h_lock);
INIT_LIST_HEAD(&host->h_granted);
INIT_LIST_HEAD(&host->h_reclaim);
-
- nrhosts++;
-
- dprintk("lockd: nlm_lookup_host created host %s\n",
- host->h_name);
+ host->h_nsmhandle = nsm;
+ host->h_addrbuf = nsm->sm_addrbuf;
out:
- mutex_unlock(&nlm_host_mutex);
return host;
}
/*
- * Destroy a host
+ * Destroy an nlm_host and free associated resources
+ *
+ * Caller must hold nlm_host_mutex.
*/
-static void
-nlm_destroy_host(struct nlm_host *host)
+static void nlm_destroy_host_locked(struct nlm_host *host)
{
struct rpc_clnt *clnt;
+ dprintk("lockd: destroy host %s\n", host->h_name);
+
BUG_ON(!list_empty(&host->h_lockowners));
BUG_ON(atomic_read(&host->h_count));
+ hlist_del_init(&host->h_hash);
+
nsm_unmonitor(host);
nsm_release(host->h_nsmhandle);
@@ -216,6 +183,8 @@ nlm_destroy_host(struct nlm_host *host)
if (clnt != NULL)
rpc_shutdown_client(clnt);
kfree(host);
+
+ nrhosts--;
}
/**
@@ -249,12 +218,76 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
.hostname_len = strlen(hostname),
.noresvport = noresvport,
};
+ struct hlist_head *chain;
+ struct hlist_node *pos;
+ struct nlm_host *host;
+ struct nsm_handle *nsm = NULL;
dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__,
(hostname ? hostname : "<none>"), version,
(protocol == IPPROTO_UDP ? "udp" : "tcp"));
- return nlm_lookup_host(&ni);
+ mutex_lock(&nlm_host_mutex);
+
+ chain = &nlm_client_hosts[nlm_hash_address(sap)];
+ hlist_for_each_entry(host, pos, chain, h_hash) {
+ if (!rpc_cmp_addr(nlm_addr(host), sap))
+ continue;
+
+ /* Same address. Share an NSM handle if we already have one */
+ if (nsm == NULL)
+ nsm = host->h_nsmhandle;
+
+ if (host->h_proto != protocol)
+ continue;
+ if (host->h_version != version)
+ continue;
+
+ nlm_get_host(host);
+ dprintk("lockd: %s found host %s (%s)\n", __func__,
+ host->h_name, host->h_addrbuf);
+ goto out;
+ }
+
+ host = nlm_alloc_host(&ni, nsm);
+ if (unlikely(host == NULL))
+ goto out;
+
+ hlist_add_head(&host->h_hash, chain);
+ nrhosts++;
+
+ dprintk("lockd: %s created host %s (%s)\n", __func__,
+ host->h_name, host->h_addrbuf);
+
+out:
+ mutex_unlock(&nlm_host_mutex);
+ return host;
+}
+
+/**
+ * nlmclnt_release_host - release client nlm_host
+ * @host: nlm_host to release
+ *
+ */
+void nlmclnt_release_host(struct nlm_host *host)
+{
+ if (host == NULL)
+ return;
+
+ dprintk("lockd: release client host %s\n", host->h_name);
+
+ BUG_ON(atomic_read(&host->h_count) < 0);
+ BUG_ON(host->h_server);
+
+ if (atomic_dec_and_test(&host->h_count)) {
+ BUG_ON(!list_empty(&host->h_lockowners));
+ BUG_ON(!list_empty(&host->h_granted));
+ BUG_ON(!list_empty(&host->h_reclaim));
+
+ mutex_lock(&nlm_host_mutex);
+ nlm_destroy_host_locked(host);
+ mutex_unlock(&nlm_host_mutex);
+ }
}
/**
@@ -279,12 +312,18 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
const char *hostname,
const size_t hostname_len)
{
+ struct hlist_head *chain;
+ struct hlist_node *pos;
+ struct nlm_host *host = NULL;
+ struct nsm_handle *nsm = NULL;
struct sockaddr_in sin = {
.sin_family = AF_INET,
};
struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
};
+ struct sockaddr *src_sap;
+ size_t src_len = rqstp->rq_addrlen;
struct nlm_lookup_host_info ni = {
.server = 1,
.sap = svc_addr(rqstp),
@@ -293,27 +332,91 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
.version = rqstp->rq_vers,
.hostname = hostname,
.hostname_len = hostname_len,
- .src_len = rqstp->rq_addrlen,
};
dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__,
(int)hostname_len, hostname, rqstp->rq_vers,
(rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp"));
+ mutex_lock(&nlm_host_mutex);
+
switch (ni.sap->sa_family) {
case AF_INET:
sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr;
- ni.src_sap = (struct sockaddr *)&sin;
+ src_sap = (struct sockaddr *)&sin;
break;
case AF_INET6:
ipv6_addr_copy(&sin6.sin6_addr, &rqstp->rq_daddr.addr6);
- ni.src_sap = (struct sockaddr *)&sin6;
+ src_sap = (struct sockaddr *)&sin6;
break;
default:
- return NULL;
+ dprintk("lockd: %s failed; unrecognized address family\n",
+ __func__);
+ goto out;
+ }
+
+ if (time_after_eq(jiffies, next_gc))
+ nlm_gc_hosts();
+
+ chain = &nlm_server_hosts[nlm_hash_address(ni.sap)];
+ hlist_for_each_entry(host, pos, chain, h_hash) {
+ if (!rpc_cmp_addr(nlm_addr(host), ni.sap))
+ continue;
+
+ /* Same address. Share an NSM handle if we already have one */
+ if (nsm == NULL)
+ nsm = host->h_nsmhandle;
+
+ if (host->h_proto != ni.protocol)
+ continue;
+ if (host->h_version != ni.version)
+ continue;
+ if (!rpc_cmp_addr(nlm_srcaddr(host), src_sap))
+ continue;
+
+ /* Move to head of hash chain. */
+ hlist_del(&host->h_hash);
+ hlist_add_head(&host->h_hash, chain);
+
+ nlm_get_host(host);
+ dprintk("lockd: %s found host %s (%s)\n",
+ __func__, host->h_name, host->h_addrbuf);
+ goto out;
}
- return nlm_lookup_host(&ni);
+ host = nlm_alloc_host(&ni, nsm);
+ if (unlikely(host == NULL))
+ goto out;
+
+ memcpy(nlm_srcaddr(host), src_sap, src_len);
+ host->h_srcaddrlen = src_len;
+ hlist_add_head(&host->h_hash, chain);
+ nrhosts++;
+
+ dprintk("lockd: %s created host %s (%s)\n",
+ __func__, host->h_name, host->h_addrbuf);
+
+out:
+ mutex_unlock(&nlm_host_mutex);
+ return host;
+}
+
+/**
+ * nlmsvc_release_host - release server nlm_host
+ * @host: nlm_host to release
+ *
+ * Host is destroyed later in nlm_gc_host().
+ */
+void nlmsvc_release_host(struct nlm_host *host)
+{
+ if (host == NULL)
+ return;
+
+ dprintk("lockd: release server host %s\n", host->h_name);
+
+ BUG_ON(atomic_read(&host->h_count) < 0);
+ BUG_ON(!host->h_server);
+ atomic_dec(&host->h_count);
}
/*
@@ -413,20 +516,28 @@ struct nlm_host * nlm_get_host(struct nlm_host *host)
return host;
}
-/*
- * Release NLM host after use
- */
-void nlm_release_host(struct nlm_host *host)
+static struct nlm_host *next_host_state(struct hlist_head *cache,
+ struct nsm_handle *nsm,
+ const struct nlm_reboot *info)
{
- if (host != NULL) {
- dprintk("lockd: release host %s\n", host->h_name);
- BUG_ON(atomic_read(&host->h_count) < 0);
- if (atomic_dec_and_test(&host->h_count)) {
- BUG_ON(!list_empty(&host->h_lockowners));
- BUG_ON(!list_empty(&host->h_granted));
- BUG_ON(!list_empty(&host->h_reclaim));
+ struct nlm_host *host = NULL;
+ struct hlist_head *chain;
+ struct hlist_node *pos;
+
+ mutex_lock(&nlm_host_mutex);
+ for_each_host(host, pos, chain, cache) {
+ if (host->h_nsmhandle == nsm
+ && host->h_nsmstate != info->state) {
+ host->h_nsmstate = info->state;
+ host->h_state++;
+
+ nlm_get_host(host);
+ goto out;
}
}
+out:
+ mutex_unlock(&nlm_host_mutex);
+ return host;
}
/**
@@ -438,8 +549,6 @@ void nlm_release_host(struct nlm_host *host)
*/
void nlm_host_rebooted(const struct nlm_reboot *info)
{
- struct hlist_head *chain;
- struct hlist_node *pos;
struct nsm_handle *nsm;
struct nlm_host *host;
@@ -452,32 +561,15 @@ void nlm_host_rebooted(const struct nlm_reboot *info)
* lock for this.
* To avoid processing a host several times, we match the nsmstate.
*/
-again: mutex_lock(&nlm_host_mutex);
- for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
- hlist_for_each_entry(host, pos, chain, h_hash) {
- if (host->h_nsmhandle == nsm
- && host->h_nsmstate != info->state) {
- host->h_nsmstate = info->state;
- host->h_state++;
-
- nlm_get_host(host);
- mutex_unlock(&nlm_host_mutex);
-
- if (host->h_server) {
- /* We're server for this guy, just ditch
- * all the locks he held. */
- nlmsvc_free_host_resources(host);
- } else {
- /* He's the server, initiate lock recovery. */
- nlmclnt_recovery(host);
- }
-
- nlm_release_host(host);
- goto again;
- }
- }
+ while ((host = next_host_state(nlm_server_hosts, nsm, info)) != NULL) {
+ nlmsvc_free_host_resources(host);
+ nlmsvc_release_host(host);
}
- mutex_unlock(&nlm_host_mutex);
+ while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) {
+ nlmclnt_recovery(host);
+ nlmclnt_release_host(host);
+ }
+
nsm_release(nsm);
}
@@ -497,13 +589,11 @@ nlm_shutdown_hosts(void)
/* First, make all hosts eligible for gc */
dprintk("lockd: nuking all hosts...\n");
- for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
- hlist_for_each_entry(host, pos, chain, h_hash) {
- host->h_expires = jiffies - 1;
- if (host->h_rpcclnt) {
- rpc_shutdown_client(host->h_rpcclnt);
- host->h_rpcclnt = NULL;
- }
+ for_each_host(host, pos, chain, nlm_server_hosts) {
+ host->h_expires = jiffies - 1;
+ if (host->h_rpcclnt) {
+ rpc_shutdown_client(host->h_rpcclnt);
+ host->h_rpcclnt = NULL;
}
}
@@ -512,15 +602,13 @@ nlm_shutdown_hosts(void)
mutex_unlock(&nlm_host_mutex);
/* complain if any hosts are left */
- if (nrhosts) {
+ if (nrhosts != 0) {
printk(KERN_WARNING "lockd: couldn't shutdown host module!\n");
- dprintk("lockd: %d hosts left:\n", nrhosts);
- for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
- hlist_for_each_entry(host, pos, chain, h_hash) {
- dprintk(" %s (cnt %d use %d exp %ld)\n",
- host->h_name, atomic_read(&host->h_count),
- host->h_inuse, host->h_expires);
- }
+ dprintk("lockd: %lu hosts left:\n", nrhosts);
+ for_each_host(host, pos, chain, nlm_server_hosts) {
+ dprintk(" %s (cnt %d use %d exp %ld)\n",
+ host->h_name, atomic_read(&host->h_count),
+ host->h_inuse, host->h_expires);
}
}
}
@@ -538,29 +626,22 @@ nlm_gc_hosts(void)
struct nlm_host *host;
dprintk("lockd: host garbage collection\n");
- for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
- hlist_for_each_entry(host, pos, chain, h_hash)
- host->h_inuse = 0;
- }
+ for_each_host(host, pos, chain, nlm_server_hosts)
+ host->h_inuse = 0;
/* Mark all hosts that hold locks, blocks or shares */
nlmsvc_mark_resources();
- for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
- hlist_for_each_entry_safe(host, pos, next, chain, h_hash) {
- if (atomic_read(&host->h_count) || host->h_inuse
- || time_before(jiffies, host->h_expires)) {
- dprintk("nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)\n",
- host->h_name, atomic_read(&host->h_count),
- host->h_inuse, host->h_expires);
- continue;
- }
- dprintk("lockd: delete host %s\n", host->h_name);
- hlist_del_init(&host->h_hash);
-
- nlm_destroy_host(host);
- nrhosts--;
+ for_each_host_safe(host, pos, next, chain, nlm_server_hosts) {
+ if (atomic_read(&host->h_count) || host->h_inuse
+ || time_before(jiffies, host->h_expires)) {
+ dprintk("nlm_gc_hosts skipping %s "
+ "(cnt %d use %d exp %ld)\n",
+ host->h_name, atomic_read(&host->h_count),
+ host->h_inuse, host->h_expires);
+ continue;
}
+ nlm_destroy_host_locked(host);
}
next_gc = jiffies + NLM_HOST_COLLECT;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index e0c918949644..23d7451b2938 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -401,26 +401,22 @@ void nsm_release(struct nsm_handle *nsm)
* Status Monitor wire protocol.
*/
-static int encode_nsm_string(struct xdr_stream *xdr, const char *string)
+static void encode_nsm_string(struct xdr_stream *xdr, const char *string)
{
const u32 len = strlen(string);
__be32 *p;
- if (unlikely(len > SM_MAXSTRLEN))
- return -EIO;
- p = xdr_reserve_space(xdr, sizeof(u32) + len);
- if (unlikely(p == NULL))
- return -EIO;
+ BUG_ON(len > SM_MAXSTRLEN);
+ p = xdr_reserve_space(xdr, 4 + len);
xdr_encode_opaque(p, string, len);
- return 0;
}
/*
* "mon_name" specifies the host to be monitored.
*/
-static int encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp)
+static void encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp)
{
- return encode_nsm_string(xdr, argp->mon_name);
+ encode_nsm_string(xdr, argp->mon_name);
}
/*
@@ -429,35 +425,25 @@ static int encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp)
* (via the NLMPROC_SM_NOTIFY call) that the state of host "mon_name"
* has changed.
*/
-static int encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp)
+static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp)
{
- int status;
__be32 *p;
- status = encode_nsm_string(xdr, utsname()->nodename);
- if (unlikely(status != 0))
- return status;
- p = xdr_reserve_space(xdr, 3 * sizeof(u32));
- if (unlikely(p == NULL))
- return -EIO;
- *p++ = htonl(argp->prog);
- *p++ = htonl(argp->vers);
- *p++ = htonl(argp->proc);
- return 0;
+ encode_nsm_string(xdr, utsname()->nodename);
+ p = xdr_reserve_space(xdr, 4 + 4 + 4);
+ *p++ = cpu_to_be32(argp->prog);
+ *p++ = cpu_to_be32(argp->vers);
+ *p = cpu_to_be32(argp->proc);
}
/*
* The "mon_id" argument specifies the non-private arguments
* of an NSMPROC_MON or NSMPROC_UNMON call.
*/
-static int encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp)
+static void encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp)
{
- int status;
-
- status = encode_mon_name(xdr, argp);
- if (unlikely(status != 0))
- return status;
- return encode_my_id(xdr, argp);
+ encode_mon_name(xdr, argp);
+ encode_my_id(xdr, argp);
}
/*
@@ -465,68 +451,56 @@ static int encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp)
* by the NSMPROC_MON call. This information will be supplied in the
* NLMPROC_SM_NOTIFY call.
*/
-static int encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp)
+static void encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp)
{
__be32 *p;
p = xdr_reserve_space(xdr, SM_PRIV_SIZE);
- if (unlikely(p == NULL))
- return -EIO;
xdr_encode_opaque_fixed(p, argp->priv->data, SM_PRIV_SIZE);
- return 0;
}
-static int xdr_enc_mon(struct rpc_rqst *req, __be32 *p,
- const struct nsm_args *argp)
+static void nsm_xdr_enc_mon(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nsm_args *argp)
{
- struct xdr_stream xdr;
- int status;
-
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- status = encode_mon_id(&xdr, argp);
- if (unlikely(status))
- return status;
- return encode_priv(&xdr, argp);
+ encode_mon_id(xdr, argp);
+ encode_priv(xdr, argp);
}
-static int xdr_enc_unmon(struct rpc_rqst *req, __be32 *p,
- const struct nsm_args *argp)
+static void nsm_xdr_enc_unmon(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nsm_args *argp)
{
- struct xdr_stream xdr;
-
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- return encode_mon_id(&xdr, argp);
+ encode_mon_id(xdr, argp);
}
-static int xdr_dec_stat_res(struct rpc_rqst *rqstp, __be32 *p,
- struct nsm_res *resp)
+static int nsm_xdr_dec_stat_res(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nsm_res *resp)
{
- struct xdr_stream xdr;
+ __be32 *p;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- p = xdr_inline_decode(&xdr, 2 * sizeof(u32));
+ p = xdr_inline_decode(xdr, 4 + 4);
if (unlikely(p == NULL))
return -EIO;
- resp->status = ntohl(*p++);
- resp->state = ntohl(*p);
+ resp->status = be32_to_cpup(p++);
+ resp->state = be32_to_cpup(p);
- dprintk("lockd: xdr_dec_stat_res status %d state %d\n",
- resp->status, resp->state);
+ dprintk("lockd: %s status %d state %d\n",
+ __func__, resp->status, resp->state);
return 0;
}
-static int xdr_dec_stat(struct rpc_rqst *rqstp, __be32 *p,
- struct nsm_res *resp)
+static int nsm_xdr_dec_stat(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nsm_res *resp)
{
- struct xdr_stream xdr;
+ __be32 *p;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- p = xdr_inline_decode(&xdr, sizeof(u32));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- resp->state = ntohl(*p);
+ resp->state = be32_to_cpup(p);
- dprintk("lockd: xdr_dec_stat state %d\n", resp->state);
+ dprintk("lockd: %s state %d\n", __func__, resp->state);
return 0;
}
@@ -542,8 +516,8 @@ static int xdr_dec_stat(struct rpc_rqst *rqstp, __be32 *p,
static struct rpc_procinfo nsm_procedures[] = {
[NSMPROC_MON] = {
.p_proc = NSMPROC_MON,
- .p_encode = (kxdrproc_t)xdr_enc_mon,
- .p_decode = (kxdrproc_t)xdr_dec_stat_res,
+ .p_encode = (kxdreproc_t)nsm_xdr_enc_mon,
+ .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat_res,
.p_arglen = SM_mon_sz,
.p_replen = SM_monres_sz,
.p_statidx = NSMPROC_MON,
@@ -551,8 +525,8 @@ static struct rpc_procinfo nsm_procedures[] = {
},
[NSMPROC_UNMON] = {
.p_proc = NSMPROC_UNMON,
- .p_encode = (kxdrproc_t)xdr_enc_unmon,
- .p_decode = (kxdrproc_t)xdr_dec_stat,
+ .p_encode = (kxdreproc_t)nsm_xdr_enc_unmon,
+ .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat,
.p_arglen = SM_mon_id_sz,
.p_replen = SM_unmonres_sz,
.p_statidx = NSMPROC_UNMON,
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 38d261192453..9a41fdc19511 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -51,7 +51,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
return 0;
no_locks:
- nlm_release_host(host);
+ nlmsvc_release_host(host);
if (error)
return error;
return nlm_lck_denied_nolocks;
@@ -92,7 +92,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
else
dprintk("lockd: TEST4 status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rc;
}
@@ -134,7 +134,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
else
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rc;
}
@@ -164,7 +164,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = nlmsvc_cancel_blocked(file, &argp->lock);
dprintk("lockd: CANCEL status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -197,7 +197,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = nlmsvc_unlock(file, &argp->lock);
dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -229,7 +229,7 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
static void nlm4svc_callback_release(void *data)
{
- nlm_release_call(data);
+ nlmsvc_release_call(data);
}
static const struct rpc_call_ops nlm4svc_callback_ops = {
@@ -261,7 +261,7 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args
stat = func(rqstp, argp, &call->a_res);
if (stat != 0) {
- nlm_release_call(call);
+ nlmsvc_release_call(call);
return stat;
}
@@ -334,7 +334,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = nlmsvc_share_file(host, file, argp);
dprintk("lockd: SHARE status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -367,7 +367,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = nlmsvc_unshare_file(host, file, argp);
dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -399,7 +399,7 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
return rpc_success;
nlmsvc_free_host_resources(host);
- nlm_release_host(host);
+ nlmsvc_release_host(host);
return rpc_success;
}
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index ef5659b211e9..6e31695d046f 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -46,6 +46,7 @@ static void nlmsvc_remove_block(struct nlm_block *block);
static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock);
static void nlmsvc_freegrantargs(struct nlm_rqst *call);
static const struct rpc_call_ops nlmsvc_grant_ops;
+static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie);
/*
* The list of blocked locks to retry
@@ -233,7 +234,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
failed_free:
kfree(block);
failed:
- nlm_release_call(call);
+ nlmsvc_release_call(call);
return NULL;
}
@@ -266,7 +267,7 @@ static void nlmsvc_free_block(struct kref *kref)
mutex_unlock(&file->f_mutex);
nlmsvc_freegrantargs(block->b_call);
- nlm_release_call(block->b_call);
+ nlmsvc_release_call(block->b_call);
nlm_release_file(block->b_file);
kfree(block->b_fl);
kfree(block);
@@ -934,3 +935,32 @@ nlmsvc_retry_blocked(void)
return timeout;
}
+
+#ifdef RPC_DEBUG
+static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
+{
+ /*
+ * We can get away with a static buffer because we're only
+ * called with BKL held.
+ */
+ static char buf[2*NLM_MAXCOOKIELEN+1];
+ unsigned int i, len = sizeof(buf);
+ char *p = buf;
+
+ len--; /* allow for trailing \0 */
+ if (len < 3)
+ return "???";
+ for (i = 0 ; i < cookie->len ; i++) {
+ if (len < 2) {
+ strcpy(p-3, "...");
+ break;
+ }
+ sprintf(p, "%02x", cookie->data[i]);
+ p += 2;
+ len -= 2;
+ }
+ *p = '\0';
+
+ return buf;
+}
+#endif
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 0caea5310ac3..d27aab11f324 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -80,7 +80,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
return 0;
no_locks:
- nlm_release_host(host);
+ nlmsvc_release_host(host);
if (error)
return error;
return nlm_lck_denied_nolocks;
@@ -122,7 +122,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
dprintk("lockd: TEST status %d vers %d\n",
ntohl(resp->status), rqstp->rq_vers);
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rc;
}
@@ -164,7 +164,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
else
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rc;
}
@@ -194,7 +194,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock));
dprintk("lockd: CANCEL status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -227,7 +227,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = cast_status(nlmsvc_unlock(file, &argp->lock));
dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -257,9 +257,17 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
-task->tk_status);
}
+void nlmsvc_release_call(struct nlm_rqst *call)
+{
+ if (!atomic_dec_and_test(&call->a_count))
+ return;
+ nlmsvc_release_host(call->a_host);
+ kfree(call);
+}
+
static void nlmsvc_callback_release(void *data)
{
- nlm_release_call(data);
+ nlmsvc_release_call(data);
}
static const struct rpc_call_ops nlmsvc_callback_ops = {
@@ -291,7 +299,7 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args
stat = func(rqstp, argp, &call->a_res);
if (stat != 0) {
- nlm_release_call(call);
+ nlmsvc_release_call(call);
return stat;
}
@@ -366,7 +374,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = cast_status(nlmsvc_share_file(host, file, argp));
dprintk("lockd: SHARE status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -399,7 +407,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status));
- nlm_release_host(host);
+ nlmsvc_release_host(host);
nlm_release_file(file);
return rpc_success;
}
@@ -431,7 +439,7 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
return rpc_success;
nlmsvc_free_host_resources(host);
- nlm_release_host(host);
+ nlmsvc_release_host(host);
return rpc_success;
}
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index b583ab0a4cbb..964666c68a86 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -149,37 +149,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock)
}
/*
- * Encode a lock as part of an NLM call
- */
-static __be32 *
-nlm_encode_lock(__be32 *p, struct nlm_lock *lock)
-{
- struct file_lock *fl = &lock->fl;
- __s32 start, len;
-
- if (!(p = xdr_encode_string(p, lock->caller))
- || !(p = nlm_encode_fh(p, &lock->fh))
- || !(p = nlm_encode_oh(p, &lock->oh)))
- return NULL;
-
- if (fl->fl_start > NLM_OFFSET_MAX
- || (fl->fl_end > NLM_OFFSET_MAX && fl->fl_end != OFFSET_MAX))
- return NULL;
-
- start = loff_t_to_s32(fl->fl_start);
- if (fl->fl_end == OFFSET_MAX)
- len = 0;
- else
- len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1);
-
- *p++ = htonl(lock->svid);
- *p++ = htonl(start);
- *p++ = htonl(len);
-
- return p;
-}
-
-/*
* Encode result of a TEST/TEST_MSG call
*/
static __be32 *
@@ -372,259 +341,3 @@ nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
{
return xdr_ressize_check(rqstp, p);
}
-
-/*
- * Now, the client side XDR functions
- */
-#ifdef NLMCLNT_SUPPORT_SHARES
-static int
-nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr)
-{
- return 0;
-}
-#endif
-
-static int
-nlmclt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm_decode_cookie(p, &resp->cookie)))
- return -EIO;
- resp->status = *p++;
- if (resp->status == nlm_lck_denied) {
- struct file_lock *fl = &resp->lock.fl;
- u32 excl;
- s32 start, len, end;
-
- memset(&resp->lock, 0, sizeof(resp->lock));
- locks_init_lock(fl);
- excl = ntohl(*p++);
- resp->lock.svid = ntohl(*p++);
- fl->fl_pid = (pid_t)resp->lock.svid;
- if (!(p = nlm_decode_oh(p, &resp->lock.oh)))
- return -EIO;
-
- fl->fl_flags = FL_POSIX;
- fl->fl_type = excl? F_WRLCK : F_RDLCK;
- start = ntohl(*p++);
- len = ntohl(*p++);
- end = start + len - 1;
-
- fl->fl_start = s32_to_loff_t(start);
- if (len == 0 || end < 0)
- fl->fl_end = OFFSET_MAX;
- else
- fl->fl_end = s32_to_loff_t(end);
- }
- return 0;
-}
-
-
-static int
-nlmclt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = argp->block? xdr_one : xdr_zero;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm_encode_lock(p, lock)))
- return -EIO;
- *p++ = argp->reclaim? xdr_one : xdr_zero;
- *p++ = htonl(argp->state);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = argp->block? xdr_one : xdr_zero;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm_encode_cookie(p, &argp->cookie)))
- return -EIO;
- if (!(p = nlm_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm_encode_cookie(p, &resp->cookie)))
- return -EIO;
- *p++ = resp->status;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm_encode_testres(p, resp)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm_decode_cookie(p, &resp->cookie)))
- return -EIO;
- resp->status = *p++;
- return 0;
-}
-
-#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
-# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
-#endif
-
-/*
- * Buffer requirements for NLM
- */
-#define NLM_void_sz 0
-#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
-#define NLM_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
-#define NLM_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
-#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE)
-#define NLM_lock_sz 3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz
-#define NLM_holder_sz 4+NLM_owner_sz
-
-#define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz
-#define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz
-#define NLM_cancargs_sz NLM_cookie_sz+2+NLM_lock_sz
-#define NLM_unlockargs_sz NLM_cookie_sz+NLM_lock_sz
-
-#define NLM_testres_sz NLM_cookie_sz+1+NLM_holder_sz
-#define NLM_res_sz NLM_cookie_sz+1
-#define NLM_norep_sz 0
-
-/*
- * For NLM, a void procedure really returns nothing
- */
-#define nlmclt_decode_norep NULL
-
-#define PROC(proc, argtype, restype) \
-[NLMPROC_##proc] = { \
- .p_proc = NLMPROC_##proc, \
- .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \
- .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \
- .p_arglen = NLM_##argtype##_sz, \
- .p_replen = NLM_##restype##_sz, \
- .p_statidx = NLMPROC_##proc, \
- .p_name = #proc, \
- }
-
-static struct rpc_procinfo nlm_procedures[] = {
- PROC(TEST, testargs, testres),
- PROC(LOCK, lockargs, res),
- PROC(CANCEL, cancargs, res),
- PROC(UNLOCK, unlockargs, res),
- PROC(GRANTED, testargs, res),
- PROC(TEST_MSG, testargs, norep),
- PROC(LOCK_MSG, lockargs, norep),
- PROC(CANCEL_MSG, cancargs, norep),
- PROC(UNLOCK_MSG, unlockargs, norep),
- PROC(GRANTED_MSG, testargs, norep),
- PROC(TEST_RES, testres, norep),
- PROC(LOCK_RES, res, norep),
- PROC(CANCEL_RES, res, norep),
- PROC(UNLOCK_RES, res, norep),
- PROC(GRANTED_RES, res, norep),
-#ifdef NLMCLNT_SUPPORT_SHARES
- PROC(SHARE, shareargs, shareres),
- PROC(UNSHARE, shareargs, shareres),
- PROC(NM_LOCK, lockargs, res),
- PROC(FREE_ALL, notify, void),
-#endif
-};
-
-static struct rpc_version nlm_version1 = {
- .number = 1,
- .nrprocs = 16,
- .procs = nlm_procedures,
-};
-
-static struct rpc_version nlm_version3 = {
- .number = 3,
- .nrprocs = 24,
- .procs = nlm_procedures,
-};
-
-static struct rpc_version * nlm_versions[] = {
- [1] = &nlm_version1,
- [3] = &nlm_version3,
-#ifdef CONFIG_LOCKD_V4
- [4] = &nlm_version4,
-#endif
-};
-
-static struct rpc_stat nlm_stats;
-
-struct rpc_program nlm_program = {
- .name = "lockd",
- .number = NLM_PROGRAM,
- .nrvers = ARRAY_SIZE(nlm_versions),
- .version = nlm_versions,
- .stats = &nlm_stats,
-};
-
-#ifdef RPC_DEBUG
-const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
-{
- /*
- * We can get away with a static buffer because we're only
- * called with BKL held.
- */
- static char buf[2*NLM_MAXCOOKIELEN+1];
- unsigned int i, len = sizeof(buf);
- char *p = buf;
-
- len--; /* allow for trailing \0 */
- if (len < 3)
- return "???";
- for (i = 0 ; i < cookie->len ; i++) {
- if (len < 2) {
- strcpy(p-3, "...");
- break;
- }
- sprintf(p, "%02x", cookie->data[i]);
- p += 2;
- len -= 2;
- }
- *p = '\0';
-
- return buf;
-}
-#endif
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index ad9dbbc9145d..dfa4789cd460 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -93,15 +93,6 @@ nlm4_decode_fh(__be32 *p, struct nfs_fh *f)
return p + XDR_QUADLEN(f->size);
}
-static __be32 *
-nlm4_encode_fh(__be32 *p, struct nfs_fh *f)
-{
- *p++ = htonl(f->size);
- if (f->size) p[XDR_QUADLEN(f->size)-1] = 0; /* don't leak anything */
- memcpy(p, f->data, f->size);
- return p + XDR_QUADLEN(f->size);
-}
-
/*
* Encode and decode owner handle
*/
@@ -112,12 +103,6 @@ nlm4_decode_oh(__be32 *p, struct xdr_netobj *oh)
}
static __be32 *
-nlm4_encode_oh(__be32 *p, struct xdr_netobj *oh)
-{
- return xdr_encode_netobj(p, oh);
-}
-
-static __be32 *
nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
{
struct file_lock *fl = &lock->fl;
@@ -150,38 +135,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
}
/*
- * Encode a lock as part of an NLM call
- */
-static __be32 *
-nlm4_encode_lock(__be32 *p, struct nlm_lock *lock)
-{
- struct file_lock *fl = &lock->fl;
- __s64 start, len;
-
- if (!(p = xdr_encode_string(p, lock->caller))
- || !(p = nlm4_encode_fh(p, &lock->fh))
- || !(p = nlm4_encode_oh(p, &lock->oh)))
- return NULL;
-
- if (fl->fl_start > NLM4_OFFSET_MAX
- || (fl->fl_end > NLM4_OFFSET_MAX && fl->fl_end != OFFSET_MAX))
- return NULL;
-
- *p++ = htonl(lock->svid);
-
- start = loff_t_to_s64(fl->fl_start);
- if (fl->fl_end == OFFSET_MAX)
- len = 0;
- else
- len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1);
-
- p = xdr_encode_hyper(p, start);
- p = xdr_encode_hyper(p, len);
-
- return p;
-}
-
-/*
* Encode result of a TEST/TEST_MSG call
*/
static __be32 *
@@ -379,211 +332,3 @@ nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
{
return xdr_ressize_check(rqstp, p);
}
-
-/*
- * Now, the client side XDR functions
- */
-#ifdef NLMCLNT_SUPPORT_SHARES
-static int
-nlm4clt_decode_void(struct rpc_rqst *req, __be32 *p, void *ptr)
-{
- return 0;
-}
-#endif
-
-static int
-nlm4clt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm4_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm4_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
- return -EIO;
- resp->status = *p++;
- if (resp->status == nlm_lck_denied) {
- struct file_lock *fl = &resp->lock.fl;
- u32 excl;
- __u64 start, len;
- __s64 end;
-
- memset(&resp->lock, 0, sizeof(resp->lock));
- locks_init_lock(fl);
- excl = ntohl(*p++);
- resp->lock.svid = ntohl(*p++);
- fl->fl_pid = (pid_t)resp->lock.svid;
- if (!(p = nlm4_decode_oh(p, &resp->lock.oh)))
- return -EIO;
-
- fl->fl_flags = FL_POSIX;
- fl->fl_type = excl? F_WRLCK : F_RDLCK;
- p = xdr_decode_hyper(p, &start);
- p = xdr_decode_hyper(p, &len);
- end = start + len - 1;
-
- fl->fl_start = s64_to_loff_t(start);
- if (len == 0 || end < 0)
- fl->fl_end = OFFSET_MAX;
- else
- fl->fl_end = s64_to_loff_t(end);
- }
- return 0;
-}
-
-
-static int
-nlm4clt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm4_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = argp->block? xdr_one : xdr_zero;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm4_encode_lock(p, lock)))
- return -EIO;
- *p++ = argp->reclaim? xdr_one : xdr_zero;
- *p++ = htonl(argp->state);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm4_encode_cookie(p, &argp->cookie)))
- return -EIO;
- *p++ = argp->block? xdr_one : xdr_zero;
- *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero;
- if (!(p = nlm4_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
-{
- struct nlm_lock *lock = &argp->lock;
-
- if (!(p = nlm4_encode_cookie(p, &argp->cookie)))
- return -EIO;
- if (!(p = nlm4_encode_lock(p, lock)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm4_encode_cookie(p, &resp->cookie)))
- return -EIO;
- *p++ = resp->status;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm4_encode_testres(p, resp)))
- return -EIO;
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-static int
-nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
-{
- if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
- return -EIO;
- resp->status = *p++;
- return 0;
-}
-
-#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
-# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
-#endif
-
-#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN)
-# error "NLM host name cannot be larger than NLM's maximum string length!"
-#endif
-
-/*
- * Buffer requirements for NLM
- */
-#define NLM4_void_sz 0
-#define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
-#define NLM4_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
-#define NLM4_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
-#define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE)
-#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz
-#define NLM4_holder_sz 6+NLM4_owner_sz
-
-#define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz
-#define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz
-#define NLM4_cancargs_sz NLM4_cookie_sz+2+NLM4_lock_sz
-#define NLM4_unlockargs_sz NLM4_cookie_sz+NLM4_lock_sz
-
-#define NLM4_testres_sz NLM4_cookie_sz+1+NLM4_holder_sz
-#define NLM4_res_sz NLM4_cookie_sz+1
-#define NLM4_norep_sz 0
-
-/*
- * For NLM, a void procedure really returns nothing
- */
-#define nlm4clt_decode_norep NULL
-
-#define PROC(proc, argtype, restype) \
-[NLMPROC_##proc] = { \
- .p_proc = NLMPROC_##proc, \
- .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \
- .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \
- .p_arglen = NLM4_##argtype##_sz, \
- .p_replen = NLM4_##restype##_sz, \
- .p_statidx = NLMPROC_##proc, \
- .p_name = #proc, \
- }
-
-static struct rpc_procinfo nlm4_procedures[] = {
- PROC(TEST, testargs, testres),
- PROC(LOCK, lockargs, res),
- PROC(CANCEL, cancargs, res),
- PROC(UNLOCK, unlockargs, res),
- PROC(GRANTED, testargs, res),
- PROC(TEST_MSG, testargs, norep),
- PROC(LOCK_MSG, lockargs, norep),
- PROC(CANCEL_MSG, cancargs, norep),
- PROC(UNLOCK_MSG, unlockargs, norep),
- PROC(GRANTED_MSG, testargs, norep),
- PROC(TEST_RES, testres, norep),
- PROC(LOCK_RES, res, norep),
- PROC(CANCEL_RES, res, norep),
- PROC(UNLOCK_RES, res, norep),
- PROC(GRANTED_RES, res, norep),
-#ifdef NLMCLNT_SUPPORT_SHARES
- PROC(SHARE, shareargs, shareres),
- PROC(UNSHARE, shareargs, shareres),
- PROC(NM_LOCK, lockargs, res),
- PROC(FREE_ALL, notify, void),
-#endif
-};
-
-struct rpc_version nlm_version4 = {
- .number = 4,
- .nrprocs = 24,
- .procs = nlm4_procedures,
-};
diff --git a/fs/locks.c b/fs/locks.c
index 8729347bcd1a..08415b2a6d36 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1389,7 +1389,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
goto out;
if ((arg == F_WRLCK)
- && ((atomic_read(&dentry->d_count) > 1)
+ && ((dentry->d_count > 1)
|| (atomic_read(&inode->i_count) > 1)))
goto out;
}
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c
index 92ca6fbe09bd..723bc5bca09a 100644
--- a/fs/logfs/dev_bdev.c
+++ b/fs/logfs/dev_bdev.c
@@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page)
static void bdev_put_device(struct logfs_super *s)
{
- close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(s->s_bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
@@ -325,13 +325,14 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type,
{
struct block_device *bdev;
- bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type);
+ bdev = blkdev_get_by_path(devname, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
+ 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);
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
return logfs_get_sb_mtd(p, mtdnr);
}
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
index d8c71ece098f..03b8c240aeda 100644
--- a/fs/logfs/inode.c
+++ b/fs/logfs/inode.c
@@ -141,13 +141,20 @@ struct inode *logfs_safe_iget(struct super_block *sb, ino_t ino, int *is_cached)
return __logfs_iget(sb, ino);
}
+static void logfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(logfs_inode_cache, logfs_inode(inode));
+}
+
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);
+ call_rcu(&inode->i_rcu, logfs_i_callback);
}
static void logfs_destroy_inode(struct inode *inode)
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
index f46ee8b0e135..9da29706f91c 100644
--- a/fs/logfs/journal.c
+++ b/fs/logfs/journal.c
@@ -828,7 +828,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
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);
+ err = btree_insert32(head, segno, (void *)1, GFP_NOFS);
BUG_ON(err); /* mempool should prevent this */
err = logfs_erase_segment(sb, segno, 1);
BUG_ON(err); /* FIXME: remount-ro would be nicer */
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
index 6127baf0e188..ee99a9f5dfd3 100644
--- a/fs/logfs/readwrite.c
+++ b/fs/logfs/readwrite.c
@@ -1994,6 +1994,9 @@ static int do_write_inode(struct inode *inode)
/* FIXME: transaction is part of logfs_block now. Is that enough? */
err = logfs_write_buf(master_inode, page, 0);
+ if (err)
+ move_page_to_inode(inode, page);
+
logfs_put_write_page(page);
return err;
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index fb2020858a34..ae0b83f476a6 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -68,11 +68,18 @@ static struct inode *minix_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void minix_destroy_inode(struct inode *inode)
+static void minix_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(minix_inode_cachep, minix_i(inode));
}
+static void minix_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, minix_i_callback);
+}
+
static void init_once(void *foo)
{
struct minix_inode_info *ei = (struct minix_inode_info *) foo;
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index c0d35a3accef..1b9e07728a9f 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -23,7 +23,7 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st
struct inode * inode = NULL;
ino_t ino;
- dentry->d_op = dir->i_sb->s_root->d_op;
+ d_set_d_op(dentry, dir->i_sb->s_root->d_op);
if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
return ERR_PTR(-ENAMETOOLONG);
diff --git a/fs/namei.c b/fs/namei.c
index 5362af9b7372..1e2f2197d809 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -169,8 +169,8 @@ EXPORT_SYMBOL(putname);
/*
* This does basic POSIX ACL permission checking
*/
-static int acl_permission_check(struct inode *inode, int mask,
- int (*check_acl)(struct inode *inode, int mask))
+static int acl_permission_check_rcu(struct inode *inode, int mask, unsigned int flags,
+ int (*check_acl_rcu)(struct inode *inode, int mask, unsigned int flags))
{
umode_t mode = inode->i_mode;
@@ -179,8 +179,8 @@ static int acl_permission_check(struct inode *inode, int mask,
if (current_fsuid() == inode->i_uid)
mode >>= 6;
else {
- if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
- int error = check_acl(inode, mask);
+ if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl_rcu) {
+ int error = check_acl_rcu(inode, mask, flags);
if (error != -EAGAIN)
return error;
}
@@ -197,6 +197,86 @@ static int acl_permission_check(struct inode *inode, int mask,
return -EACCES;
}
+static int acl_permission_check(struct inode *inode, int mask, unsigned int flags,
+ int (*check_acl)(struct inode *inode, int mask))
+{
+ umode_t mode = inode->i_mode;
+
+ mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
+
+ if (current_fsuid() == inode->i_uid)
+ mode >>= 6;
+ else {
+ if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
+ if (flags) {
+ return -ECHILD;
+ } else {
+ int error = check_acl(inode, mask);
+ if (error != -EAGAIN)
+ return error;
+ }
+ }
+
+ if (in_group_p(inode->i_gid))
+ mode >>= 3;
+ }
+
+ /*
+ * If the DACs are ok we don't need any capability check.
+ */
+ if ((mask & ~mode) == 0)
+ return 0;
+ return -EACCES;
+}
+
+/**
+ * generic_permission_rcu - check for access rights on a Posix-like filesystem
+ * @inode: inode to check access rights for
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ * @check_acl_rcu: optional callback to check for Posix ACLs
+ * @flags IPERM_FLAG_ flags.
+ *
+ * Used to check for read/write/execute permissions on a file.
+ * We use "fsuid" for this, letting us set arbitrary permissions
+ * for filesystem access without changing the "normal" uids which
+ * are used for other things.
+ *
+ * generic_permission_rcu must be rcu-walk aware. It should return
+ * -ECHILD in case an rcu-walk request cannot be satisfied (eg.
+ * requires blocking or too much thought!). It would then be called
+ * again in ref-walk mode.
+ */
+int generic_permission_rcu(struct inode *inode, int mask, unsigned int flags,
+ int (*check_acl_rcu)(struct inode *inode, int mask, unsigned int flags))
+{
+ int ret;
+
+ /*
+ * Do the basic POSIX ACL permission checks.
+ */
+ ret = acl_permission_check_rcu(inode, mask, flags, check_acl_rcu);
+ if (ret != -EACCES)
+ return ret;
+
+ /*
+ * Read/write DACs are always overridable.
+ * Executable DACs are overridable if at least one exec bit is set.
+ */
+ if (!(mask & MAY_EXEC) || execute_ok(inode))
+ if (capable(CAP_DAC_OVERRIDE))
+ return 0;
+
+ /*
+ * Searching includes executable on directories, else just read.
+ */
+ mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
+ if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
+ if (capable(CAP_DAC_READ_SEARCH))
+ return 0;
+
+ return -EACCES;
+}
+
/**
* generic_permission - check for access rights on a Posix-like filesystem
* @inode: inode to check access rights for
@@ -216,7 +296,7 @@ int generic_permission(struct inode *inode, int mask,
/*
* Do the basic POSIX ACL permission checks.
*/
- ret = acl_permission_check(inode, mask, check_acl);
+ ret = acl_permission_check(inode, mask, 0, check_acl);
if (ret != -EACCES)
return ret;
@@ -272,8 +352,14 @@ int inode_permission(struct inode *inode, int mask)
if (inode->i_op->permission)
retval = inode->i_op->permission(inode, mask);
+ else if (inode->i_op->permission_rcu)
+ retval = inode->i_op->permission_rcu(inode, mask, 0);
+ else if (inode->i_op->check_acl_rcu)
+ retval = generic_permission_rcu(inode, mask, 0,
+ inode->i_op->check_acl_rcu);
else
- retval = generic_permission(inode, mask, inode->i_op->check_acl);
+ retval = generic_permission(inode, mask,
+ inode->i_op->check_acl);
if (retval)
return retval;
@@ -362,6 +448,18 @@ void path_get(struct path *path)
EXPORT_SYMBOL(path_get);
/**
+ * path_get_long - get a long reference to a path
+ * @path: path to get the reference to
+ *
+ * Given a path increment the reference count to the dentry and the vfsmount.
+ */
+void path_get_long(struct path *path)
+{
+ mntget_long(path->mnt);
+ dget(path->dentry);
+}
+
+/**
* path_put - put a reference to a path
* @path: path to put the reference to
*
@@ -375,6 +473,185 @@ void path_put(struct path *path)
EXPORT_SYMBOL(path_put);
/**
+ * path_put_long - put a long reference to a path
+ * @path: path to put the reference to
+ *
+ * Given a path decrement the reference count to the dentry and the vfsmount.
+ */
+void path_put_long(struct path *path)
+{
+ dput(path->dentry);
+ mntput_long(path->mnt);
+}
+
+/**
+ * nameidata_drop_rcu - drop this nameidata out of rcu-walk
+ * @nd: nameidata pathwalk data to drop
+ * @Returns: 0 on success, -ECHLID on failure
+ *
+ * Path walking has 2 modes, rcu-walk and ref-walk (see
+ * Documentation/filesystems/path-lookup.txt). __drop_rcu* functions attempt
+ * to drop out of rcu-walk mode and take normal reference counts on dentries
+ * and vfsmounts to transition to rcu-walk mode. __drop_rcu* functions take
+ * refcounts at the last known good point before rcu-walk got stuck, so
+ * ref-walk may continue from there. If this is not successful (eg. a seqcount
+ * has changed), then failure is returned and path walk restarts from the
+ * beginning in ref-walk mode.
+ *
+ * nameidata_drop_rcu attempts to drop the current nd->path and nd->root into
+ * ref-walk. Must be called from rcu-walk context.
+ */
+static int nameidata_drop_rcu(struct nameidata *nd)
+{
+ struct fs_struct *fs = current->fs;
+ struct dentry *dentry = nd->path.dentry;
+
+ BUG_ON(!(nd->flags & LOOKUP_RCU));
+ if (nd->root.mnt) {
+ spin_lock(&fs->lock);
+ if (nd->root.mnt != fs->root.mnt ||
+ nd->root.dentry != fs->root.dentry)
+ goto err_root;
+ }
+ spin_lock(&dentry->d_lock);
+ if (!__d_rcu_to_refcount(dentry, nd->seq))
+ goto err;
+ BUG_ON(nd->inode != dentry->d_inode);
+ spin_unlock(&dentry->d_lock);
+ if (nd->root.mnt) {
+ path_get(&nd->root);
+ spin_unlock(&fs->lock);
+ }
+ mntget(nd->path.mnt);
+
+ rcu_read_unlock();
+ br_read_unlock(vfsmount_lock);
+ nd->flags &= ~LOOKUP_RCU;
+ return 0;
+err:
+ spin_unlock(&dentry->d_lock);
+err_root:
+ if (nd->root.mnt)
+ spin_unlock(&fs->lock);
+ return -ECHILD;
+}
+
+/* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */
+static inline int nameidata_drop_rcu_maybe(struct nameidata *nd)
+{
+ if (nd->flags & LOOKUP_RCU)
+ return nameidata_drop_rcu(nd);
+ return 0;
+}
+
+/**
+ * nameidata_dentry_drop_rcu - drop nameidata and dentry out of rcu-walk
+ * @nd: nameidata pathwalk data to drop
+ * @dentry: dentry to drop
+ * @Returns: 0 on success, -ECHLID on failure
+ *
+ * nameidata_dentry_drop_rcu attempts to drop the current nd->path and nd->root,
+ * and dentry into ref-walk. @dentry must be a path found by a do_lookup call on
+ * @nd. Must be called from rcu-walk context.
+ */
+static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry)
+{
+ struct fs_struct *fs = current->fs;
+ struct dentry *parent = nd->path.dentry;
+
+ BUG_ON(!(nd->flags & LOOKUP_RCU));
+ if (nd->root.mnt) {
+ spin_lock(&fs->lock);
+ if (nd->root.mnt != fs->root.mnt ||
+ nd->root.dentry != fs->root.dentry)
+ goto err_root;
+ }
+ spin_lock(&parent->d_lock);
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+ if (!__d_rcu_to_refcount(dentry, nd->seq))
+ goto err;
+ /*
+ * If the sequence check on the child dentry passed, then the child has
+ * not been removed from its parent. This means the parent dentry must
+ * be valid and able to take a reference at this point.
+ */
+ BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent);
+ BUG_ON(!parent->d_count);
+ parent->d_count++;
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&parent->d_lock);
+ if (nd->root.mnt) {
+ path_get(&nd->root);
+ spin_unlock(&fs->lock);
+ }
+ mntget(nd->path.mnt);
+
+ rcu_read_unlock();
+ br_read_unlock(vfsmount_lock);
+ nd->flags &= ~LOOKUP_RCU;
+ return 0;
+err:
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&parent->d_lock);
+err_root:
+ if (nd->root.mnt)
+ spin_unlock(&fs->lock);
+ return -ECHILD;
+}
+
+/* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */
+static inline int nameidata_dentry_drop_rcu_maybe(struct nameidata *nd, struct dentry *dentry)
+{
+ if (nd->flags & LOOKUP_RCU)
+ return nameidata_dentry_drop_rcu(nd, dentry);
+ return 0;
+}
+
+/**
+ * nameidata_drop_rcu_last - drop nameidata ending path walk out of rcu-walk
+ * @nd: nameidata pathwalk data to drop
+ * @Returns: 0 on success, -ECHLID on failure
+ *
+ * nameidata_drop_rcu_last attempts to drop the current nd->path into ref-walk.
+ * nd->path should be the final element of the lookup, so nd->root is discarded.
+ * Must be called from rcu-walk context.
+ */
+static int nameidata_drop_rcu_last(struct nameidata *nd)
+{
+ struct dentry *dentry = nd->path.dentry;
+
+ BUG_ON(!(nd->flags & LOOKUP_RCU));
+ nd->flags &= ~LOOKUP_RCU;
+ nd->root.mnt = NULL;
+ spin_lock(&dentry->d_lock);
+ if (!__d_rcu_to_refcount(dentry, nd->seq))
+ goto err_unlock;
+ BUG_ON(nd->inode != dentry->d_inode);
+ spin_unlock(&dentry->d_lock);
+
+ mntget(nd->path.mnt);
+
+ rcu_read_unlock();
+ br_read_unlock(vfsmount_lock);
+
+ return 0;
+
+err_unlock:
+ spin_unlock(&dentry->d_lock);
+ rcu_read_unlock();
+ br_read_unlock(vfsmount_lock);
+ return -ECHILD;
+}
+
+/* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */
+static inline int nameidata_drop_rcu_last_maybe(struct nameidata *nd)
+{
+ if (likely(nd->flags & LOOKUP_RCU))
+ return nameidata_drop_rcu_last(nd);
+ return 0;
+}
+
+/**
* release_open_intent - free up open intent resources
* @nd: pointer to nameidata
*/
@@ -386,10 +663,30 @@ void release_open_intent(struct nameidata *nd)
fput(nd->intent.open.file);
}
+static int d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+ if (dentry->d_op->d_revalidate_rcu) {
+ int status;
+ status = dentry->d_op->d_revalidate_rcu(dentry, nd);
+ if (!status && (nd->flags & LOOKUP_RCU))
+ status = -ECHILD;
+ if (status == -ECHILD) {
+ BUG_ON(!(nd->flags & LOOKUP_RCU));
+ if (nameidata_dentry_drop_rcu(nd, dentry))
+ return status;
+ status = dentry->d_op->d_revalidate_rcu(dentry, nd);
+ }
+ return status;
+ } else
+ return dentry->d_op->d_revalidate(dentry, nd);
+}
+
static inline struct dentry *
do_revalidate(struct dentry *dentry, struct nameidata *nd)
{
- int status = dentry->d_op->d_revalidate(dentry, nd);
+ int status;
+
+ status = d_revalidate(dentry, nd);
if (unlikely(status <= 0)) {
/*
* The dentry failed validation.
@@ -410,6 +707,17 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd)
return dentry;
}
+static inline int need_reval_dot(struct dentry *dentry)
+{
+ if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE_EITHER)))
+ return 0;
+
+ if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
+ return 0;
+
+ return 1;
+}
+
/*
* force_reval_path - force revalidation of a dentry
*
@@ -433,13 +741,12 @@ force_reval_path(struct path *path, struct nameidata *nd)
/*
* only check on filesystems where it's possible for the dentry to
- * become stale. It's assumed that if this flag is set then the
- * d_revalidate op will also be defined.
+ * become stale.
*/
- if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
+ if (!need_reval_dot(dentry))
return 0;
- status = dentry->d_op->d_revalidate(dentry, nd);
+ status = d_revalidate(dentry, nd);
if (status > 0)
return 0;
@@ -459,26 +766,34 @@ force_reval_path(struct path *path, struct nameidata *nd)
* short-cut DAC fails, then call ->permission() to do more
* complete permission check.
*/
-static int exec_permission(struct inode *inode)
+static inline int exec_permission(struct inode *inode, unsigned int flags)
{
int ret;
- if (inode->i_op->permission) {
+ if (inode->i_op->permission_rcu) {
+ ret = inode->i_op->permission_rcu(inode, MAY_EXEC, flags);
+ } else if (inode->i_op->permission) {
+ if (flags)
+ return -ECHILD;
ret = inode->i_op->permission(inode, MAY_EXEC);
- if (!ret)
- goto ok;
- return ret;
+ } else if (inode->i_op->check_acl_rcu) {
+ ret = acl_permission_check_rcu(inode, MAY_EXEC, flags,
+ inode->i_op->check_acl_rcu);
+ } else {
+ ret = acl_permission_check(inode, MAY_EXEC, flags,
+ inode->i_op->check_acl);
}
- ret = acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl);
- if (!ret)
+ if (likely(!ret))
goto ok;
+ if (ret == -ECHILD)
+ return ret;
if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH))
goto ok;
return ret;
ok:
- return security_inode_permission(inode, MAY_EXEC);
+ return security_inode_exec_permission(inode, flags);
}
static __always_inline void set_root(struct nameidata *nd)
@@ -489,8 +804,23 @@ static __always_inline void set_root(struct nameidata *nd)
static int link_path_walk(const char *, struct nameidata *);
+static __always_inline void set_root_rcu(struct nameidata *nd)
+{
+ if (!nd->root.mnt) {
+ struct fs_struct *fs = current->fs;
+ unsigned seq;
+
+ do {
+ seq = read_seqcount_begin(&fs->seq);
+ nd->root = fs->root;
+ } while (read_seqcount_retry(&fs->seq, seq));
+ }
+}
+
static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
{
+ int ret;
+
if (IS_ERR(link))
goto fail;
@@ -500,8 +830,10 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
nd->path = nd->root;
path_get(&nd->root);
}
+ nd->inode = nd->path.dentry->d_inode;
- return link_path_walk(link, nd);
+ ret = link_path_walk(link, nd);
+ return ret;
fail:
path_put(&nd->path);
return PTR_ERR(link);
@@ -516,11 +848,12 @@ static void path_put_conditional(struct path *path, struct nameidata *nd)
static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
{
- dput(nd->path.dentry);
- if (nd->path.mnt != path->mnt) {
- mntput(nd->path.mnt);
- nd->path.mnt = path->mnt;
+ if (!(nd->flags & LOOKUP_RCU)) {
+ dput(nd->path.dentry);
+ if (nd->path.mnt != path->mnt)
+ mntput(nd->path.mnt);
}
+ nd->path.mnt = path->mnt;
nd->path.dentry = path->dentry;
}
@@ -535,9 +868,11 @@ __do_follow_link(struct path *path, struct nameidata *nd, void **p)
if (path->mnt != nd->path.mnt) {
path_to_nameidata(path, nd);
+ nd->inode = nd->path.dentry->d_inode;
dget(dentry);
}
mntget(path->mnt);
+
nd->last_type = LAST_BIND;
*p = dentry->d_inode->i_op->follow_link(dentry, nd);
error = PTR_ERR(*p);
@@ -591,6 +926,20 @@ loop:
return err;
}
+static int follow_up_rcu(struct path *path)
+{
+ struct vfsmount *parent;
+ struct dentry *mountpoint;
+
+ parent = path->mnt->mnt_parent;
+ if (parent == path->mnt)
+ return 0;
+ mountpoint = path->mnt->mnt_mountpoint;
+ path->dentry = mountpoint;
+ path->mnt = parent;
+ return 1;
+}
+
int follow_up(struct path *path)
{
struct vfsmount *parent;
@@ -612,9 +961,24 @@ int follow_up(struct path *path)
return 1;
}
-/* no need for dcache_lock, as serialization is taken care in
- * namespace.c
+/*
+ * serialization is taken care of in namespace.c
*/
+static void __follow_mount_rcu(struct nameidata *nd, struct path *path,
+ struct inode **inode)
+{
+ while (d_mountpoint(path->dentry)) {
+ struct vfsmount *mounted;
+ mounted = __lookup_mnt(path->mnt, path->dentry, 1);
+ if (!mounted)
+ return;
+ path->mnt = mounted;
+ path->dentry = mounted->mnt_root;
+ nd->seq = read_seqcount_begin(&path->dentry->d_seq);
+ *inode = path->dentry->d_inode;
+ }
+}
+
static int __follow_mount(struct path *path)
{
int res = 0;
@@ -645,9 +1009,6 @@ static void follow_mount(struct path *path)
}
}
-/* no need for dcache_lock, as serialization is taken care in
- * namespace.c
- */
int follow_down(struct path *path)
{
struct vfsmount *mounted;
@@ -663,7 +1024,42 @@ int follow_down(struct path *path)
return 0;
}
-static __always_inline void follow_dotdot(struct nameidata *nd)
+static int follow_dotdot_rcu(struct nameidata *nd)
+{
+ struct inode *inode = nd->inode;
+
+ set_root_rcu(nd);
+
+ while(1) {
+ if (nd->path.dentry == nd->root.dentry &&
+ nd->path.mnt == nd->root.mnt) {
+ break;
+ }
+ if (nd->path.dentry != nd->path.mnt->mnt_root) {
+ struct dentry *old = nd->path.dentry;
+ struct dentry *parent = old->d_parent;
+ unsigned seq;
+
+ seq = read_seqcount_begin(&parent->d_seq);
+ if (read_seqcount_retry(&old->d_seq, nd->seq))
+ return -ECHILD;
+ inode = parent->d_inode;
+ nd->path.dentry = parent;
+ nd->seq = seq;
+ break;
+ }
+ if (!follow_up_rcu(&nd->path))
+ break;
+ nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
+ inode = nd->path.dentry->d_inode;
+ }
+ __follow_mount_rcu(nd, &nd->path, &inode);
+ nd->inode = inode;
+
+ return 0;
+}
+
+static void follow_dotdot(struct nameidata *nd)
{
set_root(nd);
@@ -684,6 +1080,7 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
break;
}
follow_mount(&nd->path);
+ nd->inode = nd->path.dentry->d_inode;
}
/*
@@ -721,17 +1118,17 @@ static struct dentry *d_alloc_and_lookup(struct dentry *parent,
* It _is_ time-critical.
*/
static int do_lookup(struct nameidata *nd, struct qstr *name,
- struct path *path)
+ struct path *path, struct inode **inode)
{
struct vfsmount *mnt = nd->path.mnt;
- struct dentry *dentry, *parent;
+ struct dentry *dentry, *parent = nd->path.dentry;
struct inode *dir;
/*
* See if the low-level filesystem might want
* to use its own hash..
*/
- if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
- int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, name);
+ if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
+ int err = parent->d_op->d_hash(parent, nd->inode, name);
if (err < 0)
return err;
}
@@ -741,21 +1138,49 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
* of a false negative due to a concurrent rename, we're going to
* do the non-racy lookup, below.
*/
- dentry = __d_lookup(nd->path.dentry, name);
- if (!dentry)
- goto need_lookup;
+ if (nd->flags & LOOKUP_RCU) {
+ unsigned seq;
+
+ *inode = nd->inode;
+ dentry = __d_lookup_rcu(parent, name, &seq, inode);
+ if (!dentry) {
+ if (nameidata_drop_rcu(nd))
+ return -ECHILD;
+ goto need_lookup;
+ }
+ /* Memory barrier in read_seqcount_begin of child is enough */
+ if (__read_seqcount_retry(&parent->d_seq, nd->seq))
+ return -ECHILD;
+
+ nd->seq = seq;
+ if (dentry->d_flags & DCACHE_OP_REVALIDATE_EITHER) {
+ if (dentry->d_flags & DCACHE_OP_REVALIDATE) {
+ if (nameidata_dentry_drop_rcu(nd, dentry))
+ return -ECHILD;
+ }
+ goto need_revalidate;
+ }
+ path->mnt = mnt;
+ path->dentry = dentry;
+ __follow_mount_rcu(nd, path, inode);
+ } else {
+ dentry = __d_lookup(parent, name);
+ if (!dentry)
+ goto need_lookup;
found:
- if (dentry->d_op && dentry->d_op->d_revalidate)
- goto need_revalidate;
+ if (dentry->d_flags & DCACHE_OP_REVALIDATE)
+ goto need_revalidate;
done:
- path->mnt = mnt;
- path->dentry = dentry;
- __follow_mount(path);
+ path->mnt = mnt;
+ path->dentry = dentry;
+ __follow_mount(path);
+ *inode = path->dentry->d_inode;
+ }
return 0;
need_lookup:
- parent = nd->path.dentry;
dir = parent->d_inode;
+ BUG_ON(nd->inode != dir);
mutex_lock(&dir->i_mutex);
/*
@@ -785,8 +1210,11 @@ need_lookup:
need_revalidate:
dentry = do_revalidate(dentry, nd);
- if (!dentry)
+ if (!dentry) {
+ if (nameidata_drop_rcu_maybe(nd))
+ return -ECHILD;
goto need_lookup;
+ }
if (IS_ERR(dentry))
goto fail;
goto done;
@@ -817,7 +1245,6 @@ static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
static int link_path_walk(const char *name, struct nameidata *nd)
{
struct path next;
- struct inode *inode;
int err;
unsigned int lookup_flags = nd->flags;
@@ -826,18 +1253,28 @@ static int link_path_walk(const char *name, struct nameidata *nd)
if (!*name)
goto return_reval;
- inode = nd->path.dentry->d_inode;
if (nd->depth)
lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
/* At this point we know we have a real path component. */
for(;;) {
+ struct inode *inode;
unsigned long hash;
struct qstr this;
unsigned int c;
nd->flags |= LOOKUP_CONTINUE;
- err = exec_permission(inode);
+ if (nd->flags & LOOKUP_RCU) {
+ err = exec_permission(nd->inode, IPERM_FLAG_RCU);
+ if (err == -ECHILD) {
+ if (nameidata_drop_rcu(nd))
+ return -ECHILD;
+ goto exec_again;
+ }
+ } else {
+exec_again:
+ err = exec_permission(nd->inode, 0);
+ }
if (err)
break;
@@ -868,37 +1305,44 @@ static int link_path_walk(const char *name, struct nameidata *nd)
if (this.name[0] == '.') switch (this.len) {
default:
break;
- case 2:
+ case 2:
if (this.name[1] != '.')
break;
- follow_dotdot(nd);
- inode = nd->path.dentry->d_inode;
+ if (nd->flags & LOOKUP_RCU) {
+ if (follow_dotdot_rcu(nd))
+ return -ECHILD;
+ } else
+ follow_dotdot(nd);
/* fallthrough */
case 1:
continue;
}
/* This does the actual lookups.. */
- err = do_lookup(nd, &this, &next);
+ err = do_lookup(nd, &this, &next, &inode);
if (err)
break;
-
err = -ENOENT;
- inode = next.dentry->d_inode;
if (!inode)
goto out_dput;
if (inode->i_op->follow_link) {
+ /* We commonly drop rcu-walk here */
+ if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry))
+ return -ECHILD;
+ BUG_ON(inode != next.dentry->d_inode);
err = do_follow_link(&next, nd);
if (err)
goto return_err;
+ nd->inode = nd->path.dentry->d_inode;
err = -ENOENT;
- inode = nd->path.dentry->d_inode;
- if (!inode)
+ if (!nd->inode)
break;
- } else
+ } else {
path_to_nameidata(&next, nd);
+ nd->inode = inode;
+ }
err = -ENOTDIR;
- if (!inode->i_op->lookup)
+ if (!nd->inode->i_op->lookup)
break;
continue;
/* here ends the main loop */
@@ -913,32 +1357,39 @@ last_component:
if (this.name[0] == '.') switch (this.len) {
default:
break;
- case 2:
+ case 2:
if (this.name[1] != '.')
break;
- follow_dotdot(nd);
- inode = nd->path.dentry->d_inode;
+ if (nd->flags & LOOKUP_RCU) {
+ if (follow_dotdot_rcu(nd))
+ return -ECHILD;
+ } else
+ follow_dotdot(nd);
/* fallthrough */
case 1:
goto return_reval;
}
- err = do_lookup(nd, &this, &next);
+ err = do_lookup(nd, &this, &next, &inode);
if (err)
break;
- inode = next.dentry->d_inode;
if (follow_on_final(inode, lookup_flags)) {
+ if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry))
+ return -ECHILD;
+ BUG_ON(inode != next.dentry->d_inode);
err = do_follow_link(&next, nd);
if (err)
goto return_err;
- inode = nd->path.dentry->d_inode;
- } else
+ nd->inode = nd->path.dentry->d_inode;
+ } else {
path_to_nameidata(&next, nd);
+ nd->inode = inode;
+ }
err = -ENOENT;
- if (!inode)
+ if (!nd->inode)
break;
if (lookup_flags & LOOKUP_DIRECTORY) {
err = -ENOTDIR;
- if (!inode->i_op->lookup)
+ if (!nd->inode->i_op->lookup)
break;
}
goto return_base;
@@ -958,25 +1409,43 @@ return_reval:
* We bypassed the ordinary revalidation routines.
* We may need to check the cached dentry for staleness.
*/
- if (nd->path.dentry && nd->path.dentry->d_sb &&
- (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
- err = -ESTALE;
+ if (need_reval_dot(nd->path.dentry)) {
/* Note: we do not d_invalidate() */
- if (!nd->path.dentry->d_op->d_revalidate(
- nd->path.dentry, nd))
+ err = d_revalidate(nd->path.dentry, nd);
+ if (!err)
+ err = -ESTALE;
+ if (err < 0)
break;
}
return_base:
+ if (nameidata_drop_rcu_last_maybe(nd))
+ return -ECHILD;
return 0;
out_dput:
- path_put_conditional(&next, nd);
+ if (!(nd->flags & LOOKUP_RCU))
+ path_put_conditional(&next, nd);
break;
}
- path_put(&nd->path);
+ if (!(nd->flags & LOOKUP_RCU))
+ path_put(&nd->path);
return_err:
return err;
}
+static inline int path_walk_rcu(const char *name, struct nameidata *nd)
+{
+ current->total_link_count = 0;
+
+ return link_path_walk(name, nd);
+}
+
+static inline int path_walk_simple(const char *name, struct nameidata *nd)
+{
+ current->total_link_count = 0;
+
+ return link_path_walk(name, nd);
+}
+
static int path_walk(const char *name, struct nameidata *nd)
{
struct path save = nd->path;
@@ -1002,6 +1471,93 @@ static int path_walk(const char *name, struct nameidata *nd)
return result;
}
+static void path_finish_rcu(struct nameidata *nd)
+{
+ if (nd->flags & LOOKUP_RCU) {
+ /* RCU dangling. Cancel it. */
+ nd->flags &= ~LOOKUP_RCU;
+ nd->root.mnt = NULL;
+ rcu_read_unlock();
+ br_read_unlock(vfsmount_lock);
+ }
+ if (nd->file)
+ fput(nd->file);
+}
+
+static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
+{
+ int retval = 0;
+ int fput_needed;
+ struct file *file;
+
+ nd->last_type = LAST_ROOT; /* if there are only slashes... */
+ nd->flags = flags | LOOKUP_RCU;
+ nd->depth = 0;
+ nd->root.mnt = NULL;
+ nd->file = NULL;
+
+ if (*name=='/') {
+ struct fs_struct *fs = current->fs;
+ unsigned seq;
+
+ br_read_lock(vfsmount_lock);
+ rcu_read_lock();
+
+ do {
+ seq = read_seqcount_begin(&fs->seq);
+ nd->root = fs->root;
+ nd->path = nd->root;
+ nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
+ } while (read_seqcount_retry(&fs->seq, seq));
+
+ } else if (dfd == AT_FDCWD) {
+ struct fs_struct *fs = current->fs;
+ unsigned seq;
+
+ br_read_lock(vfsmount_lock);
+ rcu_read_lock();
+
+ do {
+ seq = read_seqcount_begin(&fs->seq);
+ nd->path = fs->pwd;
+ nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
+ } while (read_seqcount_retry(&fs->seq, seq));
+
+ } else {
+ struct dentry *dentry;
+
+ file = fget_light(dfd, &fput_needed);
+ retval = -EBADF;
+ if (!file)
+ goto out_fail;
+
+ dentry = file->f_path.dentry;
+
+ retval = -ENOTDIR;
+ if (!S_ISDIR(dentry->d_inode->i_mode))
+ goto fput_fail;
+
+ retval = file_permission(file, MAY_EXEC);
+ if (retval)
+ goto fput_fail;
+
+ nd->path = file->f_path;
+ if (fput_needed)
+ nd->file = file;
+
+ nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
+ br_read_lock(vfsmount_lock);
+ rcu_read_lock();
+ }
+ nd->inode = nd->path.dentry->d_inode;
+ return 0;
+
+fput_fail:
+ fput_light(file, fput_needed);
+out_fail:
+ return retval;
+}
+
static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
{
int retval = 0;
@@ -1042,6 +1598,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct namei
fput_light(file, fput_needed);
}
+ nd->inode = nd->path.dentry->d_inode;
return 0;
fput_fail:
@@ -1054,16 +1611,53 @@ out_fail:
static int do_path_lookup(int dfd, const char *name,
unsigned int flags, struct nameidata *nd)
{
- int retval = path_init(dfd, name, flags, nd);
- if (!retval)
- retval = path_walk(name, nd);
- if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
- nd->path.dentry->d_inode))
- audit_inode(name, nd->path.dentry);
+ int retval;
+
+ /*
+ * Path walking is largely split up into 2 different synchronisation
+ * schemes, rcu-walk and ref-walk (explained in
+ * Documentation/filesystems/path-lookup.txt). These share much of the
+ * path walk code, but some things particularly setup, cleanup, and
+ * following mounts are sufficiently divergent that functions are
+ * duplicated. Typically there is a function foo(), and its RCU
+ * analogue, foo_rcu().
+ *
+ * -ECHILD is the error number of choice (just to avoid clashes) that
+ * is returned if some aspect of an rcu-walk fails. Such an error must
+ * be handled by restarting a traditional ref-walk (which will always
+ * be able to complete).
+ */
+ retval = path_init_rcu(dfd, name, flags, nd);
+ if (unlikely(retval))
+ return retval;
+ retval = path_walk_rcu(name, nd);
+ path_finish_rcu(nd);
if (nd->root.mnt) {
path_put(&nd->root);
nd->root.mnt = NULL;
}
+
+ if (unlikely(retval == -ECHILD || retval == -ESTALE)) {
+ /* slower, locked walk */
+ if (retval == -ESTALE)
+ flags |= LOOKUP_REVAL;
+ retval = path_init(dfd, name, flags, nd);
+ if (unlikely(retval))
+ return retval;
+ retval = path_walk(name, nd);
+ if (nd->root.mnt) {
+ path_put(&nd->root);
+ nd->root.mnt = NULL;
+ }
+ }
+
+ if (likely(!retval)) {
+ if (unlikely(!audit_dummy_context())) {
+ if (nd->path.dentry && nd->inode)
+ audit_inode(name, nd->path.dentry);
+ }
+ }
+
return retval;
}
@@ -1106,10 +1700,11 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
path_get(&nd->path);
nd->root = nd->path;
path_get(&nd->root);
+ nd->inode = nd->path.dentry->d_inode;
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
- nd->path.dentry->d_inode))
+ nd->inode))
audit_inode(name, nd->path.dentry);
path_put(&nd->root);
@@ -1125,7 +1720,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
struct dentry *dentry;
int err;
- err = exec_permission(inode);
+ err = exec_permission(inode, 0);
if (err)
return ERR_PTR(err);
@@ -1133,8 +1728,8 @@ static struct dentry *__lookup_hash(struct qstr *name,
* See if the low-level filesystem might want
* to use its own hash..
*/
- if (base->d_op && base->d_op->d_hash) {
- err = base->d_op->d_hash(base, name);
+ if (base->d_flags & DCACHE_OP_HASH) {
+ err = base->d_op->d_hash(base, inode, name);
dentry = ERR_PTR(err);
if (err < 0)
goto out;
@@ -1147,7 +1742,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
*/
dentry = d_lookup(base, name);
- if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
+ if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE_EITHER))
dentry = do_revalidate(dentry, nd);
if (!dentry)
@@ -1490,6 +2085,7 @@ out_unlock:
mutex_unlock(&dir->d_inode->i_mutex);
dput(nd->path.dentry);
nd->path.dentry = path->dentry;
+
if (error)
return error;
/* Don't check for write permission, don't truncate */
@@ -1584,6 +2180,9 @@ exit:
return ERR_PTR(error);
}
+/*
+ * Handle O_CREAT case for do_filp_open
+ */
static struct file *do_last(struct nameidata *nd, struct path *path,
int open_flag, int acc_mode,
int mode, const char *pathname)
@@ -1597,50 +2196,25 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
follow_dotdot(nd);
dir = nd->path.dentry;
case LAST_DOT:
- if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
- if (!dir->d_op->d_revalidate(dir, nd)) {
+ if (need_reval_dot(dir)) {
+ error = d_revalidate(nd->path.dentry, nd);
+ if (!error)
error = -ESTALE;
+ if (error < 0)
goto exit;
- }
}
/* fallthrough */
case LAST_ROOT:
- if (open_flag & O_CREAT)
- goto exit;
- /* fallthrough */
+ goto exit;
case LAST_BIND:
audit_inode(pathname, dir);
goto ok;
}
/* trailing slashes? */
- if (nd->last.name[nd->last.len]) {
- if (open_flag & O_CREAT)
- goto exit;
- nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW;
- }
-
- /* 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;
- }
+ if (nd->last.name[nd->last.len])
+ goto exit;
- /* OK, it's O_CREAT */
mutex_lock(&dir->d_inode->i_mutex);
path->dentry = lookup_hash(nd);
@@ -1711,8 +2285,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
return NULL;
path_to_nameidata(path, nd);
+ nd->inode = path->dentry->d_inode;
error = -EISDIR;
- if (S_ISDIR(path->dentry->d_inode->i_mode))
+ if (S_ISDIR(nd->inode->i_mode))
goto exit;
ok:
filp = finish_open(nd, open_flag, acc_mode);
@@ -1743,11 +2318,14 @@ struct file *do_filp_open(int dfd, const char *pathname,
struct path path;
int count = 0;
int flag = open_to_namei_flags(open_flag);
- int force_reval = 0;
+ int flags;
if (!(open_flag & O_CREAT))
mode = 0;
+ /* Must never be set by userspace */
+ open_flag &= ~FMODE_NONOTIFY;
+
/*
* 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
@@ -1769,54 +2347,84 @@ struct file *do_filp_open(int dfd, const char *pathname,
if (open_flag & O_APPEND)
acc_mode |= MAY_APPEND;
- /* find the parent */
-reval:
- error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
+ flags = LOOKUP_OPEN;
+ if (open_flag & O_CREAT) {
+ flags |= LOOKUP_CREATE;
+ if (open_flag & O_EXCL)
+ flags |= LOOKUP_EXCL;
+ }
+ if (open_flag & O_DIRECTORY)
+ flags |= LOOKUP_DIRECTORY;
+ if (!(open_flag & O_NOFOLLOW))
+ flags |= LOOKUP_FOLLOW;
+
+ filp = get_empty_filp();
+ if (!filp)
+ return ERR_PTR(-ENFILE);
+
+ filp->f_flags = open_flag;
+ nd.intent.open.file = filp;
+ nd.intent.open.flags = flag;
+ nd.intent.open.create_mode = mode;
+
+ if (open_flag & O_CREAT)
+ goto creat;
+
+ /* !O_CREAT, simple open */
+ error = do_path_lookup(dfd, pathname, flags, &nd);
+ if (unlikely(error))
+ goto out_filp;
+ error = -ELOOP;
+ if (!(nd.flags & LOOKUP_FOLLOW)) {
+ if (nd.inode->i_op->follow_link)
+ goto out_path;
+ }
+ error = -ENOTDIR;
+ if (nd.flags & LOOKUP_DIRECTORY) {
+ if (!nd.inode->i_op->lookup)
+ goto out_path;
+ }
+ audit_inode(pathname, nd.path.dentry);
+ filp = finish_open(&nd, open_flag, acc_mode);
+ return filp;
+
+creat:
+ /* OK, have to create the file. Find the parent. */
+ error = path_init_rcu(dfd, pathname,
+ LOOKUP_PARENT | (flags & LOOKUP_REVAL), &nd);
if (error)
- return ERR_PTR(error);
- if (force_reval)
- nd.flags |= LOOKUP_REVAL;
+ goto out_filp;
+ error = path_walk_rcu(pathname, &nd);
+ path_finish_rcu(&nd);
+ if (unlikely(error == -ECHILD || error == -ESTALE)) {
+ /* slower, locked walk */
+ if (error == -ESTALE) {
+reval:
+ flags |= LOOKUP_REVAL;
+ }
+ error = path_init(dfd, pathname,
+ LOOKUP_PARENT | (flags & LOOKUP_REVAL), &nd);
+ if (error)
+ goto out_filp;
- current->total_link_count = 0;
- error = link_path_walk(pathname, &nd);
- if (error) {
- filp = ERR_PTR(error);
- goto out;
+ error = path_walk_simple(pathname, &nd);
}
- if (unlikely(!audit_dummy_context()) && (open_flag & O_CREAT))
+ if (unlikely(error))
+ goto out_filp;
+ if (unlikely(!audit_dummy_context()))
audit_inode(pathname, nd.path.dentry);
/*
* We have the parent and last component.
*/
-
- 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;
- if (!(open_flag & O_NOFOLLOW))
- nd.flags |= LOOKUP_FOLLOW;
+ nd.flags = flags;
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 (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode))
+ if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(nd.inode->i_mode))
goto exit_dput;
if (count++ == 32)
goto exit_dput;
@@ -1837,36 +2445,33 @@ reval:
goto exit_dput;
error = __do_follow_link(&path, &nd, &cookie);
if (unlikely(error)) {
+ if (!IS_ERR(cookie) && nd.inode->i_op->put_link)
+ nd.inode->i_op->put_link(path.dentry, &nd, cookie);
/* 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;
+ nd.path = path;
+ goto out_path;
}
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);
+ if (nd.inode->i_op->put_link)
+ nd.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;
+ if (filp == ERR_PTR(-ESTALE) && !(flags & LOOKUP_REVAL))
goto reval;
- }
return filp;
exit_dput:
path_put_conditional(&path, &nd);
+out_path:
+ path_put(&nd.path);
+out_filp:
if (!IS_ERR(nd.intent.open.file))
release_open_intent(&nd);
-exit_parent:
- path_put(&nd.path);
filp = ERR_PTR(error);
goto out;
}
@@ -2127,12 +2732,10 @@ void dentry_unhash(struct dentry *dentry)
{
dget(dentry);
shrink_dcache_parent(dentry);
- spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
- if (atomic_read(&dentry->d_count) == 2)
+ if (dentry->d_count == 2)
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
}
int vfs_rmdir(struct inode *dir, struct dentry *dentry)
@@ -2904,6 +3507,7 @@ EXPORT_SYMBOL(vfs_follow_link);
EXPORT_SYMBOL(vfs_link);
EXPORT_SYMBOL(vfs_mkdir);
EXPORT_SYMBOL(vfs_mknod);
+EXPORT_SYMBOL(generic_permission_rcu);
EXPORT_SYMBOL(generic_permission);
EXPORT_SYMBOL(vfs_readlink);
EXPORT_SYMBOL(vfs_rename);
diff --git a/fs/namespace.c b/fs/namespace.c
index 3dbfc072ec70..744fcf675e74 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -138,6 +138,64 @@ void mnt_release_group_id(struct vfsmount *mnt)
mnt->mnt_group_id = 0;
}
+/*
+ * vfsmount lock must be held for read
+ */
+static inline void add_mnt_count(struct vfsmount *mnt, int n)
+{
+#ifdef CONFIG_SMP
+ this_cpu_add(mnt->mnt_pcp->mnt_count, n);
+#else
+ preempt_disable();
+ mnt->mnt_count += n;
+ preempt_enable();
+#endif
+}
+
+static inline void set_mnt_count(struct vfsmount *mnt, int n)
+{
+#ifdef CONFIG_SMP
+ this_cpu_write(mnt->mnt_pcp->mnt_count, n);
+#else
+ mnt->mnt_count = n;
+#endif
+}
+
+/*
+ * vfsmount lock must be held for read
+ */
+static inline void inc_mnt_count(struct vfsmount *mnt)
+{
+ add_mnt_count(mnt, 1);
+}
+
+/*
+ * vfsmount lock must be held for read
+ */
+static inline void dec_mnt_count(struct vfsmount *mnt)
+{
+ add_mnt_count(mnt, -1);
+}
+
+/*
+ * vfsmount lock must be held for write
+ */
+unsigned int count_mnt_count(struct vfsmount *mnt)
+{
+#ifdef CONFIG_SMP
+ unsigned int count = atomic_read(&mnt->mnt_longrefs);
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
+ }
+
+ return count;
+#else
+ return mnt->mnt_count;
+#endif
+}
+
struct vfsmount *alloc_vfsmnt(const char *name)
{
struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
@@ -154,7 +212,17 @@ struct vfsmount *alloc_vfsmnt(const char *name)
goto out_free_id;
}
- atomic_set(&mnt->mnt_count, 1);
+#ifdef CONFIG_SMP
+ mnt->mnt_pcp = alloc_percpu(struct mnt_pcp);
+ if (!mnt->mnt_pcp)
+ goto out_free_devname;
+
+ atomic_set(&mnt->mnt_longrefs, 1);
+#else
+ mnt->mnt_count = 1;
+ mnt->mnt_writers = 0;
+#endif
+
INIT_LIST_HEAD(&mnt->mnt_hash);
INIT_LIST_HEAD(&mnt->mnt_child);
INIT_LIST_HEAD(&mnt->mnt_mounts);
@@ -166,13 +234,6 @@ struct vfsmount *alloc_vfsmnt(const char *name)
#ifdef CONFIG_FSNOTIFY
INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
#endif
-#ifdef CONFIG_SMP
- mnt->mnt_writers = alloc_percpu(int);
- if (!mnt->mnt_writers)
- goto out_free_devname;
-#else
- mnt->mnt_writers = 0;
-#endif
}
return mnt;
@@ -219,7 +280,7 @@ EXPORT_SYMBOL_GPL(__mnt_is_readonly);
static inline void inc_mnt_writers(struct vfsmount *mnt)
{
#ifdef CONFIG_SMP
- (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))++;
+ this_cpu_inc(mnt->mnt_pcp->mnt_writers);
#else
mnt->mnt_writers++;
#endif
@@ -228,7 +289,7 @@ static inline void inc_mnt_writers(struct vfsmount *mnt)
static inline void dec_mnt_writers(struct vfsmount *mnt)
{
#ifdef CONFIG_SMP
- (*per_cpu_ptr(mnt->mnt_writers, smp_processor_id()))--;
+ this_cpu_dec(mnt->mnt_pcp->mnt_writers);
#else
mnt->mnt_writers--;
#endif
@@ -241,7 +302,7 @@ static unsigned int count_mnt_writers(struct vfsmount *mnt)
int cpu;
for_each_possible_cpu(cpu) {
- count += *per_cpu_ptr(mnt->mnt_writers, cpu);
+ count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_writers;
}
return count;
@@ -418,7 +479,7 @@ void free_vfsmnt(struct vfsmount *mnt)
kfree(mnt->mnt_devname);
mnt_free_id(mnt);
#ifdef CONFIG_SMP
- free_percpu(mnt->mnt_writers);
+ free_percpu(mnt->mnt_pcp);
#endif
kmem_cache_free(mnt_cache, mnt);
}
@@ -492,6 +553,27 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
}
/*
+ * Clear dentry's mounted state if it has no remaining mounts.
+ * vfsmount_lock must be held for write.
+ */
+static void dentry_reset_mounted(struct vfsmount *mnt, struct dentry *dentry)
+{
+ unsigned u;
+
+ for (u = 0; u < HASH_SIZE; u++) {
+ struct vfsmount *p;
+
+ list_for_each_entry(p, &mount_hashtable[u], mnt_hash) {
+ if (p->mnt_mountpoint == dentry)
+ return;
+ }
+ }
+ spin_lock(&dentry->d_lock);
+ dentry->d_flags &= ~DCACHE_MOUNTED;
+ spin_unlock(&dentry->d_lock);
+}
+
+/*
* vfsmount lock must be held for write
*/
static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
@@ -502,7 +584,7 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
mnt->mnt_mountpoint = mnt->mnt_root;
list_del_init(&mnt->mnt_child);
list_del_init(&mnt->mnt_hash);
- old_path->dentry->d_mounted--;
+ dentry_reset_mounted(old_path->mnt, old_path->dentry);
}
/*
@@ -513,7 +595,9 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
{
child_mnt->mnt_parent = mntget(mnt);
child_mnt->mnt_mountpoint = dget(dentry);
- dentry->d_mounted++;
+ spin_lock(&dentry->d_lock);
+ dentry->d_flags |= DCACHE_MOUNTED;
+ spin_unlock(&dentry->d_lock);
}
/*
@@ -629,9 +713,10 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
return NULL;
}
-static inline void __mntput(struct vfsmount *mnt)
+static inline void mntfree(struct vfsmount *mnt)
{
struct super_block *sb = mnt->mnt_sb;
+
/*
* This probably indicates that somebody messed
* up a mnt_want/drop_write() pair. If this
@@ -639,8 +724,8 @@ static inline void __mntput(struct vfsmount *mnt)
* to make r/w->r/o transitions.
*/
/*
- * atomic_dec_and_lock() used to deal with ->mnt_count decrements
- * provides barriers, so count_mnt_writers() below is safe. AV
+ * The locking used to deal with mnt_count decrement provides barriers,
+ * so count_mnt_writers() below is safe.
*/
WARN_ON(count_mnt_writers(mnt));
fsnotify_vfsmount_delete(mnt);
@@ -649,28 +734,113 @@ static inline void __mntput(struct vfsmount *mnt)
deactivate_super(sb);
}
-void mntput_no_expire(struct vfsmount *mnt)
-{
-repeat:
- if (atomic_add_unless(&mnt->mnt_count, -1, 1))
- return;
+#ifdef CONFIG_SMP
+static inline void __mntput(struct vfsmount *mnt, int longrefs)
+{
+ if (!longrefs) {
+put_again:
+ br_read_lock(vfsmount_lock);
+ if (likely(atomic_read(&mnt->mnt_longrefs))) {
+ dec_mnt_count(mnt);
+ br_read_unlock(vfsmount_lock);
+ return;
+ }
+ br_read_unlock(vfsmount_lock);
+ } else {
+ BUG_ON(!atomic_read(&mnt->mnt_longrefs));
+ if (atomic_add_unless(&mnt->mnt_longrefs, -1, 1))
+ return;
+ }
+
br_write_lock(vfsmount_lock);
- if (!atomic_dec_and_test(&mnt->mnt_count)) {
+ if (!longrefs)
+ dec_mnt_count(mnt);
+ else
+ atomic_dec(&mnt->mnt_longrefs);
+ if (count_mnt_count(mnt)) {
br_write_unlock(vfsmount_lock);
return;
}
- if (likely(!mnt->mnt_pinned)) {
+ if (unlikely(mnt->mnt_pinned)) {
+ add_mnt_count(mnt, mnt->mnt_pinned + 1);
+ mnt->mnt_pinned = 0;
br_write_unlock(vfsmount_lock);
- __mntput(mnt);
+ acct_auto_close_mnt(mnt);
+ goto put_again;
+ }
+ br_write_unlock(vfsmount_lock);
+ mntfree(mnt);
+}
+#else
+static inline void __mntput(struct vfsmount *mnt, int longrefs)
+{
+put_again:
+ dec_mnt_count(mnt);
+ if (likely(count_mnt_count(mnt)))
return;
+ br_write_lock(vfsmount_lock);
+ if (unlikely(mnt->mnt_pinned)) {
+ add_mnt_count(mnt, mnt->mnt_pinned + 1);
+ mnt->mnt_pinned = 0;
+ br_write_unlock(vfsmount_lock);
+ acct_auto_close_mnt(mnt);
+ goto put_again;
}
- atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
- mnt->mnt_pinned = 0;
br_write_unlock(vfsmount_lock);
- acct_auto_close_mnt(mnt);
- goto repeat;
+ mntfree(mnt);
+}
+#endif
+
+static void mntput_no_expire(struct vfsmount *mnt)
+{
+ __mntput(mnt, 0);
+}
+
+void mntput(struct vfsmount *mnt)
+{
+ if (mnt) {
+ /* avoid cacheline pingpong, hope gcc doesn't get "smart" */
+ if (unlikely(mnt->mnt_expiry_mark))
+ mnt->mnt_expiry_mark = 0;
+ __mntput(mnt, 0);
+ }
+}
+EXPORT_SYMBOL(mntput);
+
+struct vfsmount *mntget(struct vfsmount *mnt)
+{
+ if (mnt)
+ inc_mnt_count(mnt);
+ return mnt;
}
-EXPORT_SYMBOL(mntput_no_expire);
+EXPORT_SYMBOL(mntget);
+
+void mntput_long(struct vfsmount *mnt)
+{
+#ifdef CONFIG_SMP
+ if (mnt) {
+ /* avoid cacheline pingpong, hope gcc doesn't get "smart" */
+ if (unlikely(mnt->mnt_expiry_mark))
+ mnt->mnt_expiry_mark = 0;
+ __mntput(mnt, 1);
+ }
+#else
+ mntput(mnt);
+#endif
+}
+EXPORT_SYMBOL(mntput_long);
+
+struct vfsmount *mntget_long(struct vfsmount *mnt)
+{
+#ifdef CONFIG_SMP
+ if (mnt)
+ atomic_inc(&mnt->mnt_longrefs);
+ return mnt;
+#else
+ return mntget(mnt);
+#endif
+}
+EXPORT_SYMBOL(mntget_long);
void mnt_pin(struct vfsmount *mnt)
{
@@ -678,19 +848,17 @@ void mnt_pin(struct vfsmount *mnt)
mnt->mnt_pinned++;
br_write_unlock(vfsmount_lock);
}
-
EXPORT_SYMBOL(mnt_pin);
void mnt_unpin(struct vfsmount *mnt)
{
br_write_lock(vfsmount_lock);
if (mnt->mnt_pinned) {
- atomic_inc(&mnt->mnt_count);
+ inc_mnt_count(mnt);
mnt->mnt_pinned--;
}
br_write_unlock(vfsmount_lock);
}
-
EXPORT_SYMBOL(mnt_unpin);
static inline void mangle(struct seq_file *m, const char *s)
@@ -985,12 +1153,13 @@ int may_umount_tree(struct vfsmount *mnt)
int minimum_refs = 0;
struct vfsmount *p;
- br_read_lock(vfsmount_lock);
+ /* write lock needed for count_mnt_count */
+ br_write_lock(vfsmount_lock);
for (p = mnt; p; p = next_mnt(p, mnt)) {
- actual_refs += atomic_read(&p->mnt_count);
+ actual_refs += count_mnt_count(p);
minimum_refs += 2;
}
- br_read_unlock(vfsmount_lock);
+ br_write_unlock(vfsmount_lock);
if (actual_refs > minimum_refs)
return 0;
@@ -1017,10 +1186,10 @@ int may_umount(struct vfsmount *mnt)
{
int ret = 1;
down_read(&namespace_sem);
- br_read_lock(vfsmount_lock);
+ br_write_lock(vfsmount_lock);
if (propagate_mount_busy(mnt, 2))
ret = 0;
- br_read_unlock(vfsmount_lock);
+ br_write_unlock(vfsmount_lock);
up_read(&namespace_sem);
return ret;
}
@@ -1047,7 +1216,7 @@ void release_mounts(struct list_head *head)
dput(dentry);
mntput(m);
}
- mntput(mnt);
+ mntput_long(mnt);
}
}
@@ -1073,7 +1242,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
list_del_init(&p->mnt_child);
if (p->mnt_parent != p) {
p->mnt_parent->mnt_ghosts++;
- p->mnt_mountpoint->d_mounted--;
+ dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint);
}
change_mnt_propagation(p, MS_PRIVATE);
}
@@ -1102,8 +1271,16 @@ static int do_umount(struct vfsmount *mnt, int flags)
flags & (MNT_FORCE | MNT_DETACH))
return -EINVAL;
- if (atomic_read(&mnt->mnt_count) != 2)
+ /*
+ * probably don't strictly need the lock here if we examined
+ * all race cases, but it's a slowpath.
+ */
+ br_write_lock(vfsmount_lock);
+ if (count_mnt_count(mnt) != 2) {
+ br_write_lock(vfsmount_lock);
return -EBUSY;
+ }
+ br_write_unlock(vfsmount_lock);
if (!xchg(&mnt->mnt_expiry_mark, 1))
return -EAGAIN;
@@ -1792,7 +1969,7 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path,
unlock:
up_write(&namespace_sem);
- mntput(newmnt);
+ mntput_long(newmnt);
return err;
}
@@ -2125,11 +2302,11 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
if (fs) {
if (p == fs->root.mnt) {
rootmnt = p;
- fs->root.mnt = mntget(q);
+ fs->root.mnt = mntget_long(q);
}
if (p == fs->pwd.mnt) {
pwdmnt = p;
- fs->pwd.mnt = mntget(q);
+ fs->pwd.mnt = mntget_long(q);
}
}
p = next_mnt(p, mnt_ns->root);
@@ -2138,9 +2315,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
up_write(&namespace_sem);
if (rootmnt)
- mntput(rootmnt);
+ mntput_long(rootmnt);
if (pwdmnt)
- mntput(pwdmnt);
+ mntput_long(pwdmnt);
return new_ns;
}
@@ -2327,6 +2504,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
touch_mnt_namespace(current->nsproxy->mnt_ns);
br_write_unlock(vfsmount_lock);
chroot_fs_refs(&root, &new);
+
error = 0;
path_put(&root_parent);
path_put(&parent_path);
@@ -2353,6 +2531,7 @@ static void __init init_mount_tree(void)
mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(mnt))
panic("Can't create rootfs");
+
ns = create_mnt_ns(mnt);
if (IS_ERR(ns))
panic("Can't allocate initial namespace");
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f22b12e7d337..4b9cbb28d7fa 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -74,9 +74,12 @@ const struct inode_operations ncp_dir_inode_operations =
* Dentry operations routines
*/
static int ncp_lookup_validate(struct dentry *, struct nameidata *);
-static int ncp_hash_dentry(struct dentry *, struct qstr *);
-static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
-static int ncp_delete_dentry(struct dentry *);
+static int ncp_hash_dentry(const struct dentry *, const struct inode *,
+ struct qstr *);
+static int ncp_compare_dentry(const struct dentry *, const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
+static int ncp_delete_dentry(const struct dentry *);
static const struct dentry_operations ncp_dentry_operations =
{
@@ -113,10 +116,10 @@ static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
#define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
-static inline int ncp_case_sensitive(struct dentry *dentry)
+static inline int ncp_case_sensitive(const struct inode *i)
{
#ifdef CONFIG_NCPFS_NFS_NS
- return ncp_namespace(dentry->d_inode) == NW_NS_NFS;
+ return ncp_namespace(i) == NW_NS_NFS;
#else
return 0;
#endif /* CONFIG_NCPFS_NFS_NS */
@@ -127,14 +130,16 @@ static inline int ncp_case_sensitive(struct dentry *dentry)
* is case-sensitive.
*/
static int
-ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
+ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *this)
{
- if (!ncp_case_sensitive(dentry)) {
+ if (!ncp_case_sensitive(inode)) {
+ struct super_block *sb = dentry->d_sb;
struct nls_table *t;
unsigned long hash;
int i;
- t = NCP_IO_TABLE(dentry);
+ t = NCP_IO_TABLE(sb);
hash = init_name_hash();
for (i=0; i<this->len ; i++)
hash = partial_name_hash(ncp_tolower(t, this->name[i]),
@@ -145,15 +150,17 @@ ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
}
static int
-ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- if (a->len != b->len)
+ if (len != name->len)
return 1;
- if (ncp_case_sensitive(dentry))
- return strncmp(a->name, b->name, a->len);
+ if (ncp_case_sensitive(pinode))
+ return strncmp(str, name->name, len);
- return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len);
+ return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len);
}
/*
@@ -162,7 +169,7 @@ ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
* Closing files can be safely postponed until iput() - it's done there anyway.
*/
static int
-ncp_delete_dentry(struct dentry * dentry)
+ncp_delete_dentry(const struct dentry * dentry)
{
struct inode *inode = dentry->d_inode;
@@ -384,21 +391,21 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
}
/* If a pointer is invalid, we search the dentry. */
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dent = list_entry(next, struct dentry, d_u.d_child);
if ((unsigned long)dent->d_fsdata == fpos) {
if (dent->d_inode)
- dget_locked(dent);
+ dget(dent);
else
dent = NULL;
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
goto out;
}
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
return NULL;
out:
@@ -592,7 +599,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
qname.hash = full_name_hash(qname.name, qname.len);
if (dentry->d_op && dentry->d_op->d_hash)
- if (dentry->d_op->d_hash(dentry, &qname) != 0)
+ if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0)
goto end_advance;
newdent = d_lookup(dentry, &qname);
@@ -611,35 +618,12 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
shrink_dcache_parent(newdent);
/*
- * It is not as dangerous as it looks. NetWare's OS2 namespace is
- * case preserving yet case insensitive. So we update dentry's name
- * as received from server. We found dentry via d_lookup with our
- * hash, so we know that hash does not change, and so replacing name
- * should be reasonably safe.
+ * NetWare's OS2 namespace is case preserving yet case
+ * insensitive. So we update dentry's name as received from
+ * server. Parent dir's i_mutex is locked because we're in
+ * readdir.
*/
- if (qname.len == newdent->d_name.len &&
- memcmp(newdent->d_name.name, qname.name, newdent->d_name.len)) {
- struct inode *inode = newdent->d_inode;
-
- /*
- * Inside ncpfs all uses of d_name are either for debugging,
- * or on functions which acquire inode mutex (mknod, creat,
- * lookup). So grab i_mutex here, to be sure. d_path
- * uses dcache_lock when generating path, so we should too.
- * And finally d_compare is protected by dentry's d_lock, so
- * here we go.
- */
- if (inode)
- mutex_lock(&inode->i_mutex);
- spin_lock(&dcache_lock);
- spin_lock(&newdent->d_lock);
- memcpy((char *) newdent->d_name.name, qname.name,
- newdent->d_name.len);
- spin_unlock(&newdent->d_lock);
- spin_unlock(&dcache_lock);
- if (inode)
- mutex_unlock(&inode->i_mutex);
- }
+ dentry_update_name_case(newdent, &qname);
}
if (!newdent->d_inode) {
@@ -649,7 +633,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
entry->ino = iunique(dir->i_sb, 2);
inode = ncp_iget(dir->i_sb, entry);
if (inode) {
- newdent->d_op = &ncp_dentry_operations;
+ d_set_d_op(newdent, &ncp_dentry_operations);
d_instantiate(newdent, inode);
if (!hashed)
d_rehash(newdent);
@@ -657,7 +641,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
} else {
struct inode *inode = newdent->d_inode;
- mutex_lock(&inode->i_mutex);
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
ncp_update_inode2(inode, entry);
mutex_unlock(&inode->i_mutex);
}
@@ -905,7 +889,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
if (inode) {
ncp_new_dentry(dentry);
add_entry:
- dentry->d_op = &ncp_dentry_operations;
+ d_set_d_op(dentry, &ncp_dentry_operations);
d_add(dentry, inode);
error = 0;
}
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 8fb93b604e73..0c75a5f3cafd 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -58,11 +58,18 @@ static struct inode *ncp_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void ncp_destroy_inode(struct inode *inode)
+static void ncp_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
}
+static void ncp_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, ncp_i_callback);
+}
+
static void init_once(void *foo)
{
struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
@@ -710,7 +717,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root)
goto out_no_root;
- sb->s_root->d_op = &ncp_root_dentry_operations;
+ d_set_d_op(sb->s_root, &ncp_root_dentry_operations);
return 0;
out_no_root:
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 56f5b3a0e1ee..b9c4f362a88f 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -39,6 +39,8 @@ static int ncp_file_mmap_fault(struct vm_area_struct *area,
int bufsize;
int pos; /* XXX: loff_t ? */
+ if (vmf->flags & FAULT_FLAG_MINOR)
+ return VM_FAULT_MAJOR | VM_FAULT_ERROR;
/*
* ncpfs has nothing against high pages as long
* as recvmsg and memset works on it
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 3c57eca634ce..1220df75ff22 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -135,7 +135,7 @@ int ncp__vol2io(struct ncp_server *, unsigned char *, unsigned int *,
const unsigned char *, unsigned int, int);
#define NCP_ESC ':'
-#define NCP_IO_TABLE(dentry) (NCP_SERVER((dentry)->d_inode)->nls_io)
+#define NCP_IO_TABLE(sb) (NCP_SBP(sb)->nls_io)
#define ncp_tolower(t, c) nls_tolower(t, c)
#define ncp_toupper(t, c) nls_toupper(t, c)
#define ncp_strnicmp(t, s1, s2, len) \
@@ -150,15 +150,15 @@ int ncp__io2vol(unsigned char *, unsigned int *,
int ncp__vol2io(unsigned char *, unsigned int *,
const unsigned char *, unsigned int, int);
-#define NCP_IO_TABLE(dentry) NULL
+#define NCP_IO_TABLE(sb) NULL
#define ncp_tolower(t, c) tolower(c)
#define ncp_toupper(t, c) toupper(c)
#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(m,i,n,k,U)
#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(m,i,n,k,U)
-static inline int ncp_strnicmp(struct nls_table *t, const unsigned char *s1,
- const unsigned char *s2, int len)
+static inline int ncp_strnicmp(const struct nls_table *t,
+ const unsigned char *s1, const unsigned char *s2, int len)
{
while (len--) {
if (tolower(*s1++) != tolower(*s2++))
@@ -193,7 +193,7 @@ ncp_renew_dentries(struct dentry *parent)
struct list_head *next;
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -205,7 +205,7 @@ ncp_renew_dentries(struct dentry *parent)
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
static inline void
@@ -215,7 +215,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
struct list_head *next;
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -223,7 +223,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
ncp_age_dentry(server, dentry);
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
struct ncp_cache_head {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8ea4a4180a87..fd8f380b6708 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -35,6 +35,7 @@
#include <linux/sched.h>
#include <linux/vmalloc.h>
#include <linux/kmemleak.h>
+#include <linux/xattr.h>
#include "delegation.h"
#include "iostat.h"
@@ -57,7 +58,7 @@ static int nfs_rename(struct inode *, struct dentry *,
struct inode *, struct dentry *);
static int nfs_fsync_dir(struct file *, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static int nfs_readdir_clear_array(struct page*, gfp_t);
+static void nfs_readdir_clear_array(struct page*);
const struct file_operations nfs_dir_operations = {
.llseek = nfs_llseek_dir,
@@ -83,8 +84,8 @@ const struct inode_operations nfs_dir_inode_operations = {
.setattr = nfs_setattr,
};
-const struct address_space_operations nfs_dir_addr_space_ops = {
- .releasepage = nfs_readdir_clear_array,
+const struct address_space_operations nfs_dir_aops = {
+ .freepage = nfs_readdir_clear_array,
};
#ifdef CONFIG_NFS_V3
@@ -125,9 +126,10 @@ const struct inode_operations nfs4_dir_inode_operations = {
.permission = nfs_permission,
.getattr = nfs_getattr,
.setattr = nfs_setattr,
- .getxattr = nfs4_getxattr,
- .setxattr = nfs4_setxattr,
- .listxattr = nfs4_listxattr,
+ .getxattr = generic_getxattr,
+ .setxattr = generic_setxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
};
#endif /* CONFIG_NFS_V4 */
@@ -172,12 +174,13 @@ struct nfs_cache_array {
struct nfs_cache_array_entry array[0];
};
-typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
+typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);
typedef struct {
struct file *file;
struct page *page;
unsigned long page_index;
u64 *dir_cookie;
+ u64 last_cookie;
loff_t current_index;
decode_dirent_t decode;
@@ -213,17 +216,15 @@ void nfs_readdir_release_array(struct page *page)
* we are freeing strings created by nfs_add_to_readdir_array()
*/
static
-int nfs_readdir_clear_array(struct page *page, gfp_t mask)
+void nfs_readdir_clear_array(struct page *page)
{
- struct nfs_cache_array *array = nfs_readdir_get_array(page);
+ struct nfs_cache_array *array;
int i;
- if (IS_ERR(array))
- return PTR_ERR(array);
+ array = kmap_atomic(page, KM_USER0);
for (i = 0; i < array->size; i++)
kfree(array->array[i].string.name);
- nfs_readdir_release_array(page);
- return 0;
+ kunmap_atomic(array, KM_USER0);
}
/*
@@ -272,7 +273,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
goto out;
array->last_cookie = entry->cookie;
array->size++;
- if (entry->eof == 1)
+ if (entry->eof != 0)
array->eof_index = array->size;
out:
nfs_readdir_release_array(page);
@@ -312,15 +313,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
for (i = 0; i < array->size; i++) {
if (array->array[i].cookie == *desc->dir_cookie) {
desc->cache_entry_index = i;
- status = 0;
- goto out;
+ return 0;
}
}
- if (i == array->eof_index) {
- desc->eof = 1;
+ if (array->eof_index >= 0) {
status = -EBADCOOKIE;
+ if (*desc->dir_cookie == array->last_cookie)
+ desc->eof = 1;
}
-out:
return status;
}
@@ -328,10 +328,7 @@ static
int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
{
struct nfs_cache_array *array;
- int status = -EBADCOOKIE;
-
- if (desc->dir_cookie == NULL)
- goto out;
+ int status;
array = nfs_readdir_get_array(desc->page);
if (IS_ERR(array)) {
@@ -344,6 +341,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
else
status = nfs_readdir_search_for_cookie(array, desc);
+ if (status == -EAGAIN) {
+ desc->last_cookie = array->last_cookie;
+ desc->page_index++;
+ }
nfs_readdir_release_array(desc->page);
out:
return status;
@@ -379,14 +380,14 @@ error:
return error;
}
-/* Fill in an entry based on the xdr code stored in desc->page */
-static
-int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream)
+static int xdr_decode(nfs_readdir_descriptor_t *desc,
+ struct nfs_entry *entry, struct xdr_stream *xdr)
{
- __be32 *p = desc->decode(stream, entry, NFS_SERVER(desc->file->f_path.dentry->d_inode), desc->plus);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ int error;
+ error = desc->decode(xdr, entry, desc->plus);
+ if (error)
+ return error;
entry->fattr->time_start = desc->timestamp;
entry->fattr->gencount = desc->gencount;
return 0;
@@ -395,13 +396,9 @@ int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct x
static
int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
{
- struct nfs_inode *node;
if (dentry->d_inode == NULL)
goto different;
- node = NFS_I(dentry->d_inode);
- if (node->fh.size != entry->fh->size)
- goto different;
- if (strncmp(node->fh.data, entry->fh->data, node->fh.size) != 0)
+ if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0)
goto different;
return 1;
different:
@@ -443,7 +440,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
if (dentry == NULL)
return;
- dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+ d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
if (IS_ERR(inode))
goto out;
@@ -494,7 +491,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
count++;
- if (desc->plus == 1)
+ if (desc->plus != 0)
nfs_prime_dcache(desc->file->f_path.dentry, entry);
status = nfs_readdir_add_to_array(entry, page);
@@ -502,7 +499,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
break;
} while (!entry->eof);
- if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) {
+ if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
array = nfs_readdir_get_array(page);
if (!IS_ERR(array)) {
array->eof_index = array->size;
@@ -567,10 +564,11 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
unsigned int array_size = ARRAY_SIZE(pages);
entry.prev_cookie = 0;
- entry.cookie = *desc->dir_cookie;
+ entry.cookie = desc->last_cookie;
entry.eof = 0;
entry.fh = nfs_alloc_fhandle();
entry.fattr = nfs_alloc_fattr();
+ entry.server = NFS_SERVER(inode);
if (entry.fh == NULL || entry.fattr == NULL)
goto out;
@@ -640,6 +638,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
static
void cache_page_release(nfs_readdir_descriptor_t *desc)
{
+ if (!desc->page->mapping)
+ nfs_readdir_clear_array(desc->page);
page_cache_release(desc->page);
desc->page = NULL;
}
@@ -664,9 +664,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
return PTR_ERR(desc->page);
res = nfs_readdir_search_array(desc);
- if (res == 0)
- return 0;
- cache_page_release(desc);
+ if (res != 0)
+ cache_page_release(desc);
return res;
}
@@ -676,22 +675,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
{
int res;
- if (desc->page_index == 0)
+ if (desc->page_index == 0) {
desc->current_index = 0;
- while (1) {
- res = find_cache_page(desc);
- if (res != -EAGAIN)
- break;
- desc->page_index++;
+ desc->last_cookie = 0;
}
+ do {
+ res = find_cache_page(desc);
+ } while (res == -EAGAIN);
return res;
}
-static inline unsigned int dt_type(struct inode *inode)
-{
- return (inode->i_mode >> 12) & 15;
-}
-
/*
* Once we've found the start of the dirent within a page: fill 'er up...
*/
@@ -721,13 +714,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
break;
}
file->f_pos++;
- desc->cache_entry_index = i;
if (i < (array->size-1))
*desc->dir_cookie = array->array[i+1].cookie;
else
*desc->dir_cookie = array->last_cookie;
}
- if (i == array->eof_index)
+ if (array->eof_index >= 0)
desc->eof = 1;
nfs_readdir_release_array(desc->page);
@@ -768,6 +760,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
}
desc->page_index = 0;
+ desc->last_cookie = *desc->dir_cookie;
desc->page = page;
status = nfs_readdir_xdr_to_array(desc, page, inode);
@@ -795,7 +788,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct inode *inode = dentry->d_inode;
nfs_readdir_descriptor_t my_desc,
*desc = &my_desc;
- int res = -ENOMEM;
+ int res;
dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -820,7 +813,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (res < 0)
goto out;
- while (desc->eof != 1) {
+ do {
res = readdir_search_pagecache(desc);
if (res == -EBADCOOKIE) {
@@ -848,7 +841,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
res = nfs_do_filldir(desc, dirent, filldir);
if (res < 0)
break;
- }
+ } while (!desc->eof);
out:
nfs_unblock_sillyrename(dentry);
if (res > 0)
@@ -1127,7 +1120,7 @@ out_error:
/*
* This is called from dput() when d_count is going to 0.
*/
-static int nfs_dentry_delete(struct dentry *dentry)
+static int nfs_dentry_delete(const struct dentry *dentry)
{
dfprintk(VFS, "NFS: dentry_delete(%s/%s, %x)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -1198,7 +1191,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
goto out;
- dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+ d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
/*
* If we're doing an exclusive create, optimize away the lookup
@@ -1227,7 +1220,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
goto out_unblock_sillyrename;
}
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
- res = (struct dentry *)inode;
+ res = ERR_CAST(inode);
if (IS_ERR(res))
goto out_unblock_sillyrename;
@@ -1343,7 +1336,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
res = ERR_PTR(-ENAMETOOLONG);
goto out;
}
- dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+ d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
/* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
* the dentry. */
@@ -1361,8 +1354,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
if (nd->flags & LOOKUP_CREATE) {
attr.ia_mode = nd->intent.open.create_mode;
attr.ia_valid = ATTR_MODE;
- if (!IS_POSIXACL(dir))
- attr.ia_mode &= ~current_umask();
+ attr.ia_mode &= ~current_umask();
} else {
open_flags &= ~(O_EXCL | O_CREAT);
attr.ia_valid = 0;
@@ -1728,11 +1720,9 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name);
- spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
- if (atomic_read(&dentry->d_count) > 1) {
+ if (dentry->d_count > 1) {
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
/* Start asynchronous writeout of the inode */
write_inode_now(dentry->d_inode, 0);
error = nfs_sillyrename(dir, dentry);
@@ -1743,7 +1733,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
need_rehash = 1;
}
spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
error = nfs_safe_remove(dentry);
if (!error || error == -ENOENT) {
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
@@ -1878,7 +1867,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
- atomic_read(&new_dentry->d_count));
+ new_dentry->d_count);
/*
* For non-directories, check whether the target is busy and if so,
@@ -1896,7 +1885,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rehash = new_dentry;
}
- if (atomic_read(&new_dentry->d_count) > 2) {
+ if (new_dentry->d_count > 2) {
int err;
/* copy the target dentry's name */
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 60677f9f1311..7bf029ef4084 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
{
struct inode *inode = filp->f_mapping->host;
int status = 0;
+ unsigned int saved_type = fl->fl_type;
/* Try local locking first */
posix_test_lock(filp, fl);
@@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
/* found a conflict */
goto out;
}
+ fl->fl_type = saved_type;
if (nfs_have_delegation(inode, FMODE_READ))
goto out_noconflict;
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index ac7b814ce162..5596c6a2881e 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -63,9 +63,11 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
* This again causes shrink_dcache_for_umount_subtree() to
* Oops, since the test for IS_ROOT() will fail.
*/
- spin_lock(&dcache_lock);
+ spin_lock(&sb->s_root->d_inode->i_lock);
+ spin_lock(&sb->s_root->d_lock);
list_del_init(&sb->s_root->d_alias);
- spin_unlock(&dcache_lock);
+ spin_unlock(&sb->s_root->d_lock);
+ spin_unlock(&sb->s_root->d_inode->i_lock);
}
return 0;
}
@@ -119,7 +121,7 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
security_d_instantiate(ret, inode);
if (ret->d_op == NULL)
- ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
+ d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops);
out:
nfs_free_fattr(fsinfo.fattr);
return ret;
@@ -226,7 +228,7 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
security_d_instantiate(ret, inode);
if (ret->d_op == NULL)
- ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
+ d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops);
out:
nfs_free_fattr(fattr);
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 4e2d9b6b1380..18696882f1c6 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -238,7 +238,7 @@ int nfs_map_gid_to_group(struct nfs_client *clp, __u32 gid, char *buf, size_t bu
return nfs_idmap_lookup_name(gid, "group", buf, buflen);
}
-#else /* CONFIG_NFS_USE_IDMAPPER not defined */
+#else /* CONFIG_NFS_USE_NEW_IDMAPPER not defined */
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 314f57164602..017daa3bed38 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
inode->i_fop = &nfs_dir_operations;
+ inode->i_data.a_ops = &nfs_dir_aops;
if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
/* Deal with crossing mountpoints */
@@ -1437,11 +1438,18 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
return &nfsi->vfs_inode;
}
-void nfs_destroy_inode(struct inode *inode)
+static void nfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
}
+void nfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, nfs_i_callback);
+}
+
static inline void nfs4_init_once(struct nfs_inode *nfsi)
{
#ifdef CONFIG_NFS_V4
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e6356b750b77..435eae3666bd 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -185,17 +185,20 @@ extern int __init nfs_init_directcache(void);
extern void nfs_destroy_directcache(void);
/* nfs2xdr.c */
-extern int nfs_stat_to_errno(int);
+extern int nfs_stat_to_errno(enum nfs_stat);
extern struct rpc_procinfo nfs_procedures[];
-extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
+extern int nfs2_decode_dirent(struct xdr_stream *,
+ struct nfs_entry *, int);
/* nfs3xdr.c */
extern struct rpc_procinfo nfs3_procedures[];
-extern __be32 *nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
+extern int nfs3_decode_dirent(struct xdr_stream *,
+ struct nfs_entry *, int);
/* nfs4xdr.c */
#ifdef CONFIG_NFS_V4
-extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
+extern int nfs4_decode_dirent(struct xdr_stream *,
+ struct nfs_entry *, int);
#endif
#ifdef CONFIG_NFS_V4_1
extern const u32 nfs41_maxread_overhead;
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index eceafe74f473..d4c2d6b7507e 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -236,10 +236,8 @@ void nfs_umount(const struct nfs_mount_request *info)
.authflavor = RPC_AUTH_UNIX,
.flags = RPC_CLNT_CREATE_NOPING,
};
- struct mountres result;
struct rpc_message msg = {
.rpc_argp = info->dirpath,
- .rpc_resp = &result,
};
struct rpc_clnt *clnt;
int status;
@@ -248,7 +246,7 @@ void nfs_umount(const struct nfs_mount_request *info)
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
clnt = rpc_create(&args);
- if (unlikely(IS_ERR(clnt)))
+ if (IS_ERR(clnt))
goto out_clnt_err;
dprintk("NFS: sending UMNT request for %s:%s\n",
@@ -280,29 +278,20 @@ out_call_err:
* XDR encode/decode functions for MOUNT
*/
-static int encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
+static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
{
const u32 pathname_len = strlen(pathname);
__be32 *p;
- if (unlikely(pathname_len > MNTPATHLEN))
- return -EIO;
-
- p = xdr_reserve_space(xdr, sizeof(u32) + pathname_len);
- if (unlikely(p == NULL))
- return -EIO;
+ BUG_ON(pathname_len > MNTPATHLEN);
+ p = xdr_reserve_space(xdr, 4 + pathname_len);
xdr_encode_opaque(p, pathname, pathname_len);
-
- return 0;
}
-static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p,
- const char *dirpath)
+static void mnt_xdr_enc_dirpath(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const char *dirpath)
{
- struct xdr_stream xdr;
-
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- return encode_mntdirpath(&xdr, dirpath);
+ encode_mntdirpath(xdr, dirpath);
}
/*
@@ -320,10 +309,10 @@ static int decode_status(struct xdr_stream *xdr, struct mountres *res)
u32 status;
__be32 *p;
- p = xdr_inline_decode(xdr, sizeof(status));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- status = ntohl(*p);
+ status = be32_to_cpup(p);
for (i = 0; i < ARRAY_SIZE(mnt_errtbl); i++) {
if (mnt_errtbl[i].status == status) {
@@ -351,18 +340,16 @@ static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
return 0;
}
-static int mnt_dec_mountres(struct rpc_rqst *req, __be32 *p,
- struct mountres *res)
+static int mnt_xdr_dec_mountres(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct mountres *res)
{
- struct xdr_stream xdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
-
- status = decode_status(&xdr, res);
+ status = decode_status(xdr, res);
if (unlikely(status != 0 || res->errno != 0))
return status;
- return decode_fhandle(&xdr, res);
+ return decode_fhandle(xdr, res);
}
static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
@@ -371,10 +358,10 @@ static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
u32 status;
__be32 *p;
- p = xdr_inline_decode(xdr, sizeof(status));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- status = ntohl(*p);
+ status = be32_to_cpup(p);
for (i = 0; i < ARRAY_SIZE(mnt3_errtbl); i++) {
if (mnt3_errtbl[i].status == status) {
@@ -394,11 +381,11 @@ static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res)
u32 size;
__be32 *p;
- p = xdr_inline_decode(xdr, sizeof(size));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- size = ntohl(*p++);
+ size = be32_to_cpup(p);
if (size > NFS3_FHSIZE || size == 0)
return -EIO;
@@ -421,15 +408,15 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
if (*count == 0)
return 0;
- p = xdr_inline_decode(xdr, sizeof(entries));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- entries = ntohl(*p);
+ entries = be32_to_cpup(p);
dprintk("NFS: received %u auth flavors\n", entries);
if (entries > NFS_MAX_SECFLAVORS)
entries = NFS_MAX_SECFLAVORS;
- p = xdr_inline_decode(xdr, sizeof(u32) * entries);
+ p = xdr_inline_decode(xdr, 4 * entries);
if (unlikely(p == NULL))
return -EIO;
@@ -437,7 +424,7 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
entries = *count;
for (i = 0; i < entries; i++) {
- flavors[i] = ntohl(*p++);
+ flavors[i] = be32_to_cpup(p++);
dprintk("NFS: auth flavor[%u]: %d\n", i, flavors[i]);
}
*count = i;
@@ -445,30 +432,28 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
return 0;
}
-static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p,
- struct mountres *res)
+static int mnt_xdr_dec_mountres3(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct mountres *res)
{
- struct xdr_stream xdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
-
- status = decode_fhs_status(&xdr, res);
+ status = decode_fhs_status(xdr, res);
if (unlikely(status != 0 || res->errno != 0))
return status;
- status = decode_fhandle3(&xdr, res);
+ status = decode_fhandle3(xdr, res);
if (unlikely(status != 0)) {
res->errno = -EBADHANDLE;
return 0;
}
- return decode_auth_flavors(&xdr, res);
+ return decode_auth_flavors(xdr, res);
}
static struct rpc_procinfo mnt_procedures[] = {
[MOUNTPROC_MNT] = {
.p_proc = MOUNTPROC_MNT,
- .p_encode = (kxdrproc_t)mnt_enc_dirpath,
- .p_decode = (kxdrproc_t)mnt_dec_mountres,
+ .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath,
+ .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres,
.p_arglen = MNT_enc_dirpath_sz,
.p_replen = MNT_dec_mountres_sz,
.p_statidx = MOUNTPROC_MNT,
@@ -476,7 +461,7 @@ static struct rpc_procinfo mnt_procedures[] = {
},
[MOUNTPROC_UMNT] = {
.p_proc = MOUNTPROC_UMNT,
- .p_encode = (kxdrproc_t)mnt_enc_dirpath,
+ .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath,
.p_arglen = MNT_enc_dirpath_sz,
.p_statidx = MOUNTPROC_UMNT,
.p_name = "UMOUNT",
@@ -486,8 +471,8 @@ static struct rpc_procinfo mnt_procedures[] = {
static struct rpc_procinfo mnt3_procedures[] = {
[MOUNTPROC3_MNT] = {
.p_proc = MOUNTPROC3_MNT,
- .p_encode = (kxdrproc_t)mnt_enc_dirpath,
- .p_decode = (kxdrproc_t)mnt_dec_mountres3,
+ .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath,
+ .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres3,
.p_arglen = MNT_enc_dirpath_sz,
.p_replen = MNT_dec_mountres3_sz,
.p_statidx = MOUNTPROC3_MNT,
@@ -495,7 +480,7 @@ static struct rpc_procinfo mnt3_procedures[] = {
},
[MOUNTPROC3_UMNT] = {
.p_proc = MOUNTPROC3_UMNT,
- .p_encode = (kxdrproc_t)mnt_enc_dirpath,
+ .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath,
.p_arglen = MNT_enc_dirpath_sz,
.p_statidx = MOUNTPROC3_UMNT,
.p_name = "UMOUNT",
@@ -505,13 +490,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
static struct rpc_version mnt_version1 = {
.number = 1,
- .nrprocs = 2,
+ .nrprocs = ARRAY_SIZE(mnt_procedures),
.procs = mnt_procedures,
};
static struct rpc_version mnt_version3 = {
.number = 3,
- .nrprocs = 2,
+ .nrprocs = ARRAY_SIZE(mnt3_procedures),
.procs = mnt3_procedures,
};
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index db6aa3673cf3..74aaf3963c10 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -49,12 +49,17 @@ char *nfs_path(const char *base,
const struct dentry *dentry,
char *buffer, ssize_t buflen)
{
- char *end = buffer+buflen;
+ char *end;
int namelen;
+ unsigned seq;
+rename_retry:
+ end = buffer+buflen;
*--end = '\0';
buflen--;
- spin_lock(&dcache_lock);
+
+ seq = read_seqbegin(&rename_lock);
+ rcu_read_lock();
while (!IS_ROOT(dentry) && dentry != droot) {
namelen = dentry->d_name.len;
buflen -= namelen + 1;
@@ -65,7 +70,9 @@ char *nfs_path(const char *base,
*--end = '/';
dentry = dentry->d_parent;
}
- spin_unlock(&dcache_lock);
+ rcu_read_unlock();
+ if (read_seqretry(&rename_lock, seq))
+ goto rename_retry;
if (*end != '/') {
if (--buflen < 0)
goto Elong;
@@ -82,7 +89,9 @@ char *nfs_path(const char *base,
memcpy(end, base, namelen);
return end;
Elong_unlock:
- spin_unlock(&dcache_lock);
+ rcu_read_unlock();
+ if (read_seqretry(&rename_lock, seq))
+ goto rename_retry;
Elong:
return ERR_PTR(-ENAMETOOLONG);
}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 5914a1911c95..51f1cfa04d27 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -61,584 +61,1013 @@
#define NFS_readdirres_sz (1)
#define NFS_statfsres_sz (1+NFS_info_sz)
+
/*
- * Common NFS XDR functions as inlines
+ * While encoding arguments, set up the reply buffer in advance to
+ * receive reply data directly into the page cache.
*/
-static inline __be32 *
-xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle)
+static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
+ unsigned int base, unsigned int len,
+ unsigned int bufsize)
{
- memcpy(p, fhandle->data, NFS2_FHSIZE);
- return p + XDR_QUADLEN(NFS2_FHSIZE);
+ struct rpc_auth *auth = req->rq_cred->cr_auth;
+ unsigned int replen;
+
+ replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
}
-static inline __be32 *
-xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
{
- /* NFSv2 handles have a fixed length */
- fhandle->size = NFS2_FHSIZE;
- memcpy(fhandle->data, p, NFS2_FHSIZE);
- return p + XDR_QUADLEN(NFS2_FHSIZE);
+ dprintk("NFS: %s prematurely hit the end of our receive buffer. "
+ "Remaining buffer length is %tu words.\n",
+ func, xdr->end - xdr->p);
+}
+
+
+/*
+ * Encode/decode NFSv2 basic data types
+ *
+ * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
+ * "NFS: Network File System Protocol Specification".
+ *
+ * Not all basic data types have their own encoding and decoding
+ * functions. For run-time efficiency, some data types are encoded
+ * or decoded inline.
+ */
+
+/*
+ * typedef opaque nfsdata<>;
+ */
+static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
+{
+ u32 recvd, count;
+ size_t hdrlen;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ count = be32_to_cpup(p);
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(count > recvd))
+ goto out_cheating;
+out:
+ xdr_read_pages(xdr, count);
+ result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */
+ result->count = count;
+ return count;
+out_cheating:
+ dprintk("NFS: server cheating in read result: "
+ "count %u > recvd %u\n", count, recvd);
+ count = recvd;
+ goto out;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * enum stat {
+ * NFS_OK = 0,
+ * NFSERR_PERM = 1,
+ * NFSERR_NOENT = 2,
+ * NFSERR_IO = 5,
+ * NFSERR_NXIO = 6,
+ * NFSERR_ACCES = 13,
+ * NFSERR_EXIST = 17,
+ * NFSERR_NODEV = 19,
+ * NFSERR_NOTDIR = 20,
+ * NFSERR_ISDIR = 21,
+ * NFSERR_FBIG = 27,
+ * NFSERR_NOSPC = 28,
+ * NFSERR_ROFS = 30,
+ * NFSERR_NAMETOOLONG = 63,
+ * NFSERR_NOTEMPTY = 66,
+ * NFSERR_DQUOT = 69,
+ * NFSERR_STALE = 70,
+ * NFSERR_WFLUSH = 99
+ * };
+ */
+static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *status = be32_to_cpup(p);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
-static inline __be32*
-xdr_encode_time(__be32 *p, struct timespec *timep)
+/*
+ * 2.3.2. ftype
+ *
+ * enum ftype {
+ * NFNON = 0,
+ * NFREG = 1,
+ * NFDIR = 2,
+ * NFBLK = 3,
+ * NFCHR = 4,
+ * NFLNK = 5
+ * };
+ *
+ */
+static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
{
- *p++ = htonl(timep->tv_sec);
- /* Convert nanoseconds into microseconds */
- *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
+ *type = be32_to_cpup(p++);
+ if (unlikely(*type > NF2FIFO))
+ *type = NFBAD;
return p;
}
-static inline __be32*
-xdr_encode_current_server_time(__be32 *p, struct timespec *timep)
+/*
+ * 2.3.3. fhandle
+ *
+ * typedef opaque fhandle[FHSIZE];
+ */
+static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
{
- /*
- * Passing the invalid value useconds=1000000 is a
- * Sun convention for "set to current server time".
- * It's needed to make permissions checks for the
- * "touch" program across v2 mounts to Solaris and
- * Irix boxes work correctly. See description of
- * sattr in section 6.1 of "NFS Illustrated" by
- * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
- */
- *p++ = htonl(timep->tv_sec);
- *p++ = htonl(1000000);
+ __be32 *p;
+
+ BUG_ON(fh->size != NFS2_FHSIZE);
+ p = xdr_reserve_space(xdr, NFS2_FHSIZE);
+ memcpy(p, fh->data, NFS2_FHSIZE);
+}
+
+static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS2_FHSIZE);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ fh->size = NFS2_FHSIZE;
+ memcpy(fh->data, p, NFS2_FHSIZE);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * 2.3.4. timeval
+ *
+ * struct timeval {
+ * unsigned int seconds;
+ * unsigned int useconds;
+ * };
+ */
+static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
+{
+ *p++ = cpu_to_be32(timep->tv_sec);
+ if (timep->tv_nsec != 0)
+ *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
+ else
+ *p++ = cpu_to_be32(0);
return p;
}
-static inline __be32*
-xdr_decode_time(__be32 *p, struct timespec *timep)
+/*
+ * Passing the invalid value useconds=1000000 is a Sun convention for
+ * "set to current server time". It's needed to make permissions checks
+ * for the "touch" program across v2 mounts to Solaris and Irix servers
+ * work correctly. See description of sattr in section 6.1 of "NFS
+ * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
+ */
+static __be32 *xdr_encode_current_server_time(__be32 *p,
+ const struct timespec *timep)
{
- timep->tv_sec = ntohl(*p++);
- /* Convert microseconds into nanoseconds */
- timep->tv_nsec = ntohl(*p++) * 1000;
+ *p++ = cpu_to_be32(timep->tv_sec);
+ *p++ = cpu_to_be32(1000000);
return p;
}
-static __be32 *
-xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
+static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
+{
+ timep->tv_sec = be32_to_cpup(p++);
+ timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
+ return p;
+}
+
+/*
+ * 2.3.5. fattr
+ *
+ * struct fattr {
+ * ftype type;
+ * unsigned int mode;
+ * unsigned int nlink;
+ * unsigned int uid;
+ * unsigned int gid;
+ * unsigned int size;
+ * unsigned int blocksize;
+ * unsigned int rdev;
+ * unsigned int blocks;
+ * unsigned int fsid;
+ * unsigned int fileid;
+ * timeval atime;
+ * timeval mtime;
+ * timeval ctime;
+ * };
+ *
+ */
+static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
{
u32 rdev, type;
- type = ntohl(*p++);
- fattr->mode = ntohl(*p++);
- fattr->nlink = ntohl(*p++);
- fattr->uid = ntohl(*p++);
- fattr->gid = ntohl(*p++);
- fattr->size = ntohl(*p++);
- fattr->du.nfs2.blocksize = ntohl(*p++);
- rdev = ntohl(*p++);
- fattr->du.nfs2.blocks = ntohl(*p++);
- fattr->fsid.major = ntohl(*p++);
- fattr->fsid.minor = 0;
- fattr->fileid = ntohl(*p++);
- p = xdr_decode_time(p, &fattr->atime);
- p = xdr_decode_time(p, &fattr->mtime);
- p = xdr_decode_time(p, &fattr->ctime);
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+
fattr->valid |= NFS_ATTR_FATTR_V2;
+
+ p = xdr_decode_ftype(p, &type);
+
+ fattr->mode = be32_to_cpup(p++);
+ fattr->nlink = be32_to_cpup(p++);
+ fattr->uid = be32_to_cpup(p++);
+ fattr->gid = be32_to_cpup(p++);
+ fattr->size = be32_to_cpup(p++);
+ fattr->du.nfs2.blocksize = be32_to_cpup(p++);
+
+ rdev = be32_to_cpup(p++);
fattr->rdev = new_decode_dev(rdev);
- if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
+ if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
fattr->rdev = 0;
}
+
+ fattr->du.nfs2.blocks = be32_to_cpup(p++);
+ fattr->fsid.major = be32_to_cpup(p++);
+ fattr->fsid.minor = 0;
+ fattr->fileid = be32_to_cpup(p++);
+
+ p = xdr_decode_time(p, &fattr->atime);
+ p = xdr_decode_time(p, &fattr->mtime);
+ xdr_decode_time(p, &fattr->ctime);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * 2.3.6. sattr
+ *
+ * struct sattr {
+ * unsigned int mode;
+ * unsigned int uid;
+ * unsigned int gid;
+ * unsigned int size;
+ * timeval atime;
+ * timeval mtime;
+ * };
+ */
+
+#define NFS2_SATTR_NOT_SET (0xffffffff)
+
+static __be32 *xdr_time_not_set(__be32 *p)
+{
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
return p;
}
-static inline __be32 *
-xdr_encode_sattr(__be32 *p, struct iattr *attr)
+static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
{
- const __be32 not_set = __constant_htonl(0xFFFFFFFF);
+ __be32 *p;
- *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
- *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
- *p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set;
- *p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set;
+ p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
- if (attr->ia_valid & ATTR_ATIME_SET) {
+ if (attr->ia_valid & ATTR_MODE)
+ *p++ = cpu_to_be32(attr->ia_mode);
+ else
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+ if (attr->ia_valid & ATTR_UID)
+ *p++ = cpu_to_be32(attr->ia_uid);
+ else
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+ if (attr->ia_valid & ATTR_GID)
+ *p++ = cpu_to_be32(attr->ia_gid);
+ else
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+ if (attr->ia_valid & ATTR_SIZE)
+ *p++ = cpu_to_be32((u32)attr->ia_size);
+ else
+ *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+
+ if (attr->ia_valid & ATTR_ATIME_SET)
p = xdr_encode_time(p, &attr->ia_atime);
- } else if (attr->ia_valid & ATTR_ATIME) {
+ else if (attr->ia_valid & ATTR_ATIME)
p = xdr_encode_current_server_time(p, &attr->ia_atime);
- } else {
- *p++ = not_set;
- *p++ = not_set;
- }
-
- if (attr->ia_valid & ATTR_MTIME_SET) {
- p = xdr_encode_time(p, &attr->ia_mtime);
- } else if (attr->ia_valid & ATTR_MTIME) {
- p = xdr_encode_current_server_time(p, &attr->ia_mtime);
- } else {
- *p++ = not_set;
- *p++ = not_set;
- }
- return p;
+ else
+ p = xdr_time_not_set(p);
+ if (attr->ia_valid & ATTR_MTIME_SET)
+ xdr_encode_time(p, &attr->ia_mtime);
+ else if (attr->ia_valid & ATTR_MTIME)
+ xdr_encode_current_server_time(p, &attr->ia_mtime);
+ else
+ xdr_time_not_set(p);
}
/*
- * NFS encode functions
+ * 2.3.7. filename
+ *
+ * typedef string filename<MAXNAMLEN>;
*/
+static void encode_filename(struct xdr_stream *xdr,
+ const char *name, u32 length)
+{
+ __be32 *p;
+
+ BUG_ON(length > NFS2_MAXNAMLEN);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, name, length);
+}
+
+static int decode_filename_inline(struct xdr_stream *xdr,
+ const char **name, u32 *length)
+{
+ __be32 *p;
+ u32 count;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ count = be32_to_cpup(p);
+ if (count > NFS3_MAXNAMLEN)
+ goto out_nametoolong;
+ p = xdr_inline_decode(xdr, count);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *name = (const char *)p;
+ *length = count;
+ return 0;
+out_nametoolong:
+ dprintk("NFS: returned filename too long: %u\n", count);
+ return -ENAMETOOLONG;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
/*
- * Encode file handle argument
- * GETATTR, READLINK, STATFS
+ * 2.3.8. path
+ *
+ * typedef string path<MAXPATHLEN>;
*/
-static int
-nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
+static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
{
- p = xdr_encode_fhandle(p, fh);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ __be32 *p;
+
+ BUG_ON(length > NFS2_MAXPATHLEN);
+ p = xdr_reserve_space(xdr, 4);
+ *p = cpu_to_be32(length);
+ xdr_write_pages(xdr, pages, 0, length);
+}
+
+static int decode_path(struct xdr_stream *xdr)
+{
+ u32 length, recvd;
+ size_t hdrlen;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p);
+ if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
+ goto out_size;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(length > recvd))
+ goto out_cheating;
+
+ xdr_read_pages(xdr, length);
+ xdr_terminate_string(xdr->buf, length);
return 0;
+out_size:
+ dprintk("NFS: returned pathname too long: %u\n", length);
+ return -ENAMETOOLONG;
+out_cheating:
+ dprintk("NFS: server cheating in pathname result: "
+ "length %u > received %u\n", length, recvd);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
/*
- * Encode SETATTR arguments
+ * 2.3.9. attrstat
+ *
+ * union attrstat switch (stat status) {
+ * case NFS_OK:
+ * fattr attributes;
+ * default:
+ * void;
+ * };
*/
-static int
-nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
+static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_sattr(p, args->sattr);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_fattr(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
/*
- * Encode directory ops argument
- * LOOKUP, RMDIR
+ * 2.3.10. diropargs
+ *
+ * struct diropargs {
+ * fhandle dir;
+ * filename name;
+ * };
*/
-static int
-nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
+static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
+ const char *name, u32 length)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_fhandle(xdr, fh);
+ encode_filename(xdr, name, length);
}
/*
- * Encode REMOVE argument
+ * 2.3.11. diropres
+ *
+ * union diropres switch (stat status) {
+ * case NFS_OK:
+ * struct {
+ * fhandle file;
+ * fattr attributes;
+ * } diropok;
+ * default:
+ * void;
+ * };
*/
-static int
-nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
+static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name.name, args->name.len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ int error;
+
+ error = decode_fhandle(xdr, result->fh);
+ if (unlikely(error))
+ goto out;
+ error = decode_fattr(xdr, result->fattr);
+out:
+ return error;
+}
+
+static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_diropok(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
+
/*
- * Arguments to a READ call. Since we read data directly into the page
- * cache, we also set up the reply iovec here so that iov[1] points
- * exactly to the page we want to fetch.
+ * NFSv2 XDR encode functions
+ *
+ * NFSv2 argument types are defined in section 2.2 of RFC 1094:
+ * "NFS: Network File System Protocol Specification".
*/
-static int
-nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
+
+static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_fh *fh)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
- u32 offset = (u32)args->offset;
+ encode_fhandle(xdr, fh);
+}
+
+/*
+ * 2.2.3. sattrargs
+ *
+ * struct sattrargs {
+ * fhandle file;
+ * sattr attributes;
+ * };
+ */
+static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_sattrargs *args)
+{
+ encode_fhandle(xdr, args->fh);
+ encode_sattr(xdr, args->sattr);
+}
+
+static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_diropargs *args)
+{
+ encode_diropargs(xdr, args->fh, args->name, args->len);
+}
+
+static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_readlinkargs *args)
+{
+ encode_fhandle(xdr, args->fh);
+ prepare_reply_buffer(req, args->pages, args->pgbase,
+ args->pglen, NFS_readlinkres_sz);
+}
+
+/*
+ * 2.2.7. readargs
+ *
+ * struct readargs {
+ * fhandle file;
+ * unsigned offset;
+ * unsigned count;
+ * unsigned totalcount;
+ * };
+ */
+static void encode_readargs(struct xdr_stream *xdr,
+ const struct nfs_readargs *args)
+{
+ u32 offset = args->offset;
u32 count = args->count;
+ __be32 *p;
- p = xdr_encode_fhandle(p, args->fh);
- *p++ = htonl(offset);
- *p++ = htonl(count);
- *p++ = htonl(count);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ encode_fhandle(xdr, args->fh);
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
- args->pages, args->pgbase, count);
+ p = xdr_reserve_space(xdr, 4 + 4 + 4);
+ *p++ = cpu_to_be32(offset);
+ *p++ = cpu_to_be32(count);
+ *p = cpu_to_be32(count);
+}
+
+static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_readargs *args)
+{
+ encode_readargs(xdr, args);
+ prepare_reply_buffer(req, args->pages, args->pgbase,
+ args->count, NFS_readres_sz);
req->rq_rcv_buf.flags |= XDRBUF_READ;
- return 0;
}
/*
- * Decode READ reply
+ * 2.2.9. writeargs
+ *
+ * struct writeargs {
+ * fhandle file;
+ * unsigned beginoffset;
+ * unsigned offset;
+ * unsigned totalcount;
+ * nfsdata data;
+ * };
*/
-static int
-nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
+static void encode_writeargs(struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
{
- struct kvec *iov = req->rq_rcv_buf.head;
- size_t hdrlen;
- u32 count, recvd;
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
- p = xdr_decode_fattr(p, res->fattr);
-
- count = ntohl(*p++);
- res->eof = 0;
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READ reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READ header is short. iovec will be shifted.\n");
- xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
- }
+ u32 offset = args->offset;
+ u32 count = args->count;
+ __be32 *p;
- recvd = req->rq_rcv_buf.len - hdrlen;
- if (count > recvd) {
- dprintk("NFS: server cheating in read reply: "
- "count %u > recvd %u\n", count, recvd);
- count = recvd;
- }
+ encode_fhandle(xdr, args->fh);
- dprintk("RPC: readres OK count %u\n", count);
- if (count < res->count)
- res->count = count;
+ p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
+ *p++ = cpu_to_be32(offset);
+ *p++ = cpu_to_be32(offset);
+ *p++ = cpu_to_be32(count);
- return count;
+ /* nfsdata */
+ *p = cpu_to_be32(count);
+ xdr_write_pages(xdr, args->pages, args->pgbase, count);
}
+static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
+{
+ encode_writeargs(xdr, args);
+ xdr->buf->flags |= XDRBUF_WRITE;
+}
/*
- * Write arguments. Splice the buffer to be written into the iovec.
+ * 2.2.10. createargs
+ *
+ * struct createargs {
+ * diropargs where;
+ * sattr attributes;
+ * };
*/
-static int
-nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
+static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_createargs *args)
{
- struct xdr_buf *sndbuf = &req->rq_snd_buf;
- u32 offset = (u32)args->offset;
- u32 count = args->count;
-
- p = xdr_encode_fhandle(p, args->fh);
- *p++ = htonl(offset);
- *p++ = htonl(offset);
- *p++ = htonl(count);
- *p++ = htonl(count);
- sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
+ encode_diropargs(xdr, args->fh, args->name, args->len);
+ encode_sattr(xdr, args->sattr);
+}
- /* Copy the page array */
- xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
- sndbuf->flags |= XDRBUF_WRITE;
- return 0;
+static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_removeargs *args)
+{
+ encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
}
/*
- * Encode create arguments
- * CREATE, MKDIR
+ * 2.2.12. renameargs
+ *
+ * struct renameargs {
+ * diropargs from;
+ * diropargs to;
+ * };
*/
-static int
-nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
+static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_renameargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
- p = xdr_encode_sattr(p, args->sattr);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ const struct qstr *old = args->old_name;
+ const struct qstr *new = args->new_name;
+
+ encode_diropargs(xdr, args->old_dir, old->name, old->len);
+ encode_diropargs(xdr, args->new_dir, new->name, new->len);
}
/*
- * Encode RENAME arguments
+ * 2.2.13. linkargs
+ *
+ * struct linkargs {
+ * fhandle from;
+ * diropargs to;
+ * };
*/
-static int
-nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
+static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_linkargs *args)
{
- p = xdr_encode_fhandle(p, args->old_dir);
- p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
- p = xdr_encode_fhandle(p, args->new_dir);
- p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_fhandle(xdr, args->fromfh);
+ encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
}
/*
- * Encode LINK arguments
+ * 2.2.14. symlinkargs
+ *
+ * struct symlinkargs {
+ * diropargs from;
+ * path to;
+ * sattr attributes;
+ * };
*/
-static int
-nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
+static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_symlinkargs *args)
{
- p = xdr_encode_fhandle(p, args->fromfh);
- p = xdr_encode_fhandle(p, args->tofh);
- p = xdr_encode_array(p, args->toname, args->tolen);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
+ encode_path(xdr, args->pages, args->pathlen);
+ encode_sattr(xdr, args->sattr);
}
/*
- * Encode SYMLINK arguments
+ * 2.2.17. readdirargs
+ *
+ * struct readdirargs {
+ * fhandle dir;
+ * nfscookie cookie;
+ * unsigned count;
+ * };
*/
-static int
-nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
+static void encode_readdirargs(struct xdr_stream *xdr,
+ const struct nfs_readdirargs *args)
{
- struct xdr_buf *sndbuf = &req->rq_snd_buf;
- size_t pad;
+ __be32 *p;
- p = xdr_encode_fhandle(p, args->fromfh);
- p = xdr_encode_array(p, args->fromname, args->fromlen);
- *p++ = htonl(args->pathlen);
- sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
+ encode_fhandle(xdr, args->fh);
- xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
+ p = xdr_reserve_space(xdr, 4 + 4);
+ *p++ = cpu_to_be32(args->cookie);
+ *p = cpu_to_be32(args->count);
+}
- /*
- * xdr_encode_pages may have added a few bytes to ensure the
- * pathname ends on a 4-byte boundary. Start encoding the
- * attributes after the pad bytes.
- */
- pad = sndbuf->tail->iov_len;
- if (pad > 0)
- p++;
- p = xdr_encode_sattr(p, args->sattr);
- sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
- return 0;
+static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_readdirargs *args)
+{
+ encode_readdirargs(xdr, args);
+ prepare_reply_buffer(req, args->pages, 0,
+ args->count, NFS_readdirres_sz);
}
/*
- * Encode arguments to readdir call
+ * NFSv2 XDR decode functions
+ *
+ * NFSv2 result types are defined in section 2.2 of RFC 1094:
+ * "NFS: Network File System Protocol Specification".
*/
-static int
-nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
+
+static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
+ void *__unused)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
- u32 count = args->count;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
- p = xdr_encode_fhandle(p, args->fh);
- *p++ = htonl(args->cookie);
- *p++ = htonl(count); /* see above */
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_fattr *result)
+{
+ return decode_attrstat(xdr, result);
+}
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
- return 0;
+static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_diropok *result)
+{
+ return decode_diropres(xdr, result);
}
/*
- * Decode the result of a readdir call.
- * We're not really decoding anymore, we just leave the buffer untouched
- * and only check that it is syntactically correct.
- * The real decoding happens in nfs_decode_entry below, called directly
- * from nfs_readdir for each entry.
+ * 2.2.6. readlinkres
+ *
+ * union readlinkres switch (stat status) {
+ * case NFS_OK:
+ * path data;
+ * default:
+ * void;
+ * };
*/
-static int
-nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
+static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
+ struct xdr_stream *xdr, void *__unused)
{
- struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
- struct kvec *iov = rcvbuf->head;
- struct page **page;
- size_t hdrlen;
- unsigned int pglen, recvd;
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
-
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READDIR reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
- xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
- }
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_path(xdr);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
- pglen = rcvbuf->page_len;
- recvd = rcvbuf->len - hdrlen;
- if (pglen > recvd)
- pglen = recvd;
- page = rcvbuf->pages;
- return pglen;
+/*
+ * 2.2.7. readres
+ *
+ * union readres switch (stat status) {
+ * case NFS_OK:
+ * fattr attributes;
+ * nfsdata data;
+ * default:
+ * void;
+ * };
+ */
+static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_readres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_fattr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_nfsdata(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_writeres *result)
{
- dprintk("nfs: %s: prematurely hit end of receive buffer. "
- "Remaining buffer length is %tu words.\n",
- func, xdr->end - xdr->p);
+ /* All NFSv2 writes are "file sync" writes */
+ result->verf->committed = NFS_FILE_SYNC;
+ return decode_attrstat(xdr, result->fattr);
}
-__be32 *
-nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
+/**
+ * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
+ * the local page cache.
+ * @xdr: XDR stream where entry resides
+ * @entry: buffer to fill in with entry data
+ * @plus: boolean indicating whether this should be a readdirplus entry
+ *
+ * Returns zero if successful, otherwise a negative errno value is
+ * returned.
+ *
+ * This function is not invoked during READDIR reply decoding, but
+ * rather whenever an application invokes the getdents(2) system call
+ * on a directory already in our cache.
+ *
+ * 2.2.17. entry
+ *
+ * struct entry {
+ * unsigned fileid;
+ * filename name;
+ * nfscookie cookie;
+ * entry *nextentry;
+ * };
+ */
+int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
+ int plus)
{
__be32 *p;
+ int error;
+
p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
+ if (unlikely(p == NULL))
goto out_overflow;
- if (!ntohl(*p++)) {
+ if (*p++ == xdr_zero) {
p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
+ if (unlikely(p == NULL))
goto out_overflow;
- if (!ntohl(*p++))
- return ERR_PTR(-EAGAIN);
+ if (*p++ == xdr_zero)
+ return -EAGAIN;
entry->eof = 1;
- return ERR_PTR(-EBADCOOKIE);
+ return -EBADCOOKIE;
}
- p = xdr_inline_decode(xdr, 8);
- if (unlikely(!p))
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
goto out_overflow;
+ entry->ino = be32_to_cpup(p);
- entry->ino = ntohl(*p++);
- entry->len = ntohl(*p++);
+ error = decode_filename_inline(xdr, &entry->name, &entry->len);
+ if (unlikely(error))
+ return error;
- p = xdr_inline_decode(xdr, entry->len + 4);
- if (unlikely(!p))
+ /*
+ * The type (size and byte order) of nfscookie isn't defined in
+ * RFC 1094. This implementation assumes that it's an XDR uint32.
+ */
+ entry->prev_cookie = entry->cookie;
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
goto out_overflow;
- entry->name = (const char *) p;
- p += XDR_QUADLEN(entry->len);
- entry->prev_cookie = entry->cookie;
- entry->cookie = ntohl(*p++);
+ entry->cookie = be32_to_cpup(p);
entry->d_type = DT_UNKNOWN;
- p = xdr_inline_peek(xdr, 8);
+ /* Peek at the next entry to see if we're at EOD */
+ p = xdr_inline_peek(xdr, 4 + 4);
+ entry->eof = 0;
if (p != NULL)
- entry->eof = !p[0] && p[1];
- else
- entry->eof = 0;
-
- return p;
+ entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
+ return 0;
out_overflow:
print_overflow_msg(__func__, xdr);
- return ERR_PTR(-EAGAIN);
-}
-
-/*
- * NFS XDR decode functions
- */
-/*
- * Decode simple status reply
- */
-static int
-nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
-{
- int status;
-
- if ((status = ntohl(*p++)) != 0)
- status = nfs_stat_to_errno(status);
- return status;
+ return -EAGAIN;
}
/*
- * Decode attrstat reply
- * GETATTR, SETATTR, WRITE
- */
-static int
-nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
-{
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
- xdr_decode_fattr(p, fattr);
- return 0;
-}
-
-/*
- * Decode diropres reply
- * LOOKUP, CREATE, MKDIR
+ * 2.2.17. readdirres
+ *
+ * union readdirres switch (stat status) {
+ * case NFS_OK:
+ * struct {
+ * entry *entries;
+ * bool eof;
+ * } readdirok;
+ * default:
+ * void;
+ * };
+ *
+ * Read the directory contents into the page cache, but don't
+ * touch them. The actual decoding is done by nfs2_decode_dirent()
+ * during subsequent nfs_readdir() calls.
*/
-static int
-nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
+static int decode_readdirok(struct xdr_stream *xdr)
{
- int status;
+ u32 recvd, pglen;
+ size_t hdrlen;
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
- p = xdr_decode_fhandle(p, res->fh);
- xdr_decode_fattr(p, res->fattr);
- return 0;
+ pglen = xdr->buf->page_len;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(pglen > recvd))
+ goto out_cheating;
+out:
+ xdr_read_pages(xdr, pglen);
+ return pglen;
+out_cheating:
+ dprintk("NFS: server cheating in readdir result: "
+ "pglen %u > recvd %u\n", pglen, recvd);
+ pglen = recvd;
+ goto out;
}
-/*
- * Encode READLINK args
- */
-static int
-nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
+static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
+ struct xdr_stream *xdr, void *__unused)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
-
- p = xdr_encode_fhandle(p, args->fh);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
- return 0;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_readdirok(xdr);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode READLINK reply
+ * 2.2.18. statfsres
+ *
+ * union statfsres (stat status) {
+ * case NFS_OK:
+ * struct {
+ * unsigned tsize;
+ * unsigned bsize;
+ * unsigned blocks;
+ * unsigned bfree;
+ * unsigned bavail;
+ * } info;
+ * default:
+ * void;
+ * };
*/
-static int
-nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
+static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
{
- struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
- struct kvec *iov = rcvbuf->head;
- size_t hdrlen;
- u32 len, recvd;
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
- /* Convert length of symlink */
- len = ntohl(*p++);
- if (len >= rcvbuf->page_len) {
- dprintk("nfs: server returned giant symlink!\n");
- return -ENAMETOOLONG;
- }
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READLINK reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
- xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
- }
- recvd = req->rq_rcv_buf.len - hdrlen;
- if (recvd < len) {
- dprintk("NFS: server cheating in readlink reply: "
- "count %u > recvd %u\n", len, recvd);
- return -EIO;
- }
+ __be32 *p;
- xdr_terminate_string(rcvbuf, len);
+ p = xdr_inline_decode(xdr, NFS_info_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ result->tsize = be32_to_cpup(p++);
+ result->bsize = be32_to_cpup(p++);
+ result->blocks = be32_to_cpup(p++);
+ result->bfree = be32_to_cpup(p++);
+ result->bavail = be32_to_cpup(p);
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
-/*
- * Decode WRITE reply
- */
-static int
-nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
+static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs2_fsstat *result)
{
- res->verf->committed = NFS_FILE_SYNC;
- return nfs_xdr_attrstat(req, p, res->fattr);
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_info(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
-/*
- * Decode STATFS reply
- */
-static int
-nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
-{
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
-
- res->tsize = ntohl(*p++);
- res->bsize = ntohl(*p++);
- res->blocks = ntohl(*p++);
- res->bfree = ntohl(*p++);
- res->bavail = ntohl(*p++);
- return 0;
-}
/*
* We need to translate between nfs status return values and
* the local errno values which may not be the same.
*/
-static struct {
+static const struct {
int stat;
int errno;
} nfs_errtbl[] = {
@@ -678,28 +1107,30 @@ static struct {
{ -1, -EIO }
};
-/*
- * Convert an NFS error code to a local one.
- * This one is used jointly by NFSv2 and NFSv3.
+/**
+ * nfs_stat_to_errno - convert an NFS status code to a local errno
+ * @status: NFS status code to convert
+ *
+ * Returns a local errno value, or -EIO if the NFS status code is
+ * not recognized. This function is used jointly by NFSv2 and NFSv3.
*/
-int
-nfs_stat_to_errno(int stat)
+int nfs_stat_to_errno(enum nfs_stat status)
{
int i;
for (i = 0; nfs_errtbl[i].stat != -1; i++) {
- if (nfs_errtbl[i].stat == stat)
+ if (nfs_errtbl[i].stat == (int)status)
return nfs_errtbl[i].errno;
}
- dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
+ dprintk("NFS: Unrecognized nfs status value: %u\n", status);
return nfs_errtbl[i].errno;
}
#define PROC(proc, argtype, restype, timer) \
[NFSPROC_##proc] = { \
.p_proc = NFSPROC_##proc, \
- .p_encode = (kxdrproc_t) nfs_xdr_##argtype, \
- .p_decode = (kxdrproc_t) nfs_xdr_##restype, \
+ .p_encode = (kxdreproc_t)nfs2_xdr_enc_##argtype, \
+ .p_decode = (kxdrdproc_t)nfs2_xdr_dec_##restype, \
.p_arglen = NFS_##argtype##_sz, \
.p_replen = NFS_##restype##_sz, \
.p_timer = timer, \
@@ -707,21 +1138,21 @@ nfs_stat_to_errno(int stat)
.p_name = #proc, \
}
struct rpc_procinfo nfs_procedures[] = {
- PROC(GETATTR, fhandle, attrstat, 1),
- PROC(SETATTR, sattrargs, attrstat, 0),
- PROC(LOOKUP, diropargs, diropres, 2),
- PROC(READLINK, readlinkargs, readlinkres, 3),
- PROC(READ, readargs, readres, 3),
- PROC(WRITE, writeargs, writeres, 4),
- PROC(CREATE, createargs, diropres, 0),
- PROC(REMOVE, removeargs, stat, 0),
- PROC(RENAME, renameargs, stat, 0),
- PROC(LINK, linkargs, stat, 0),
- PROC(SYMLINK, symlinkargs, stat, 0),
- PROC(MKDIR, createargs, diropres, 0),
- PROC(RMDIR, diropargs, stat, 0),
- PROC(READDIR, readdirargs, readdirres, 3),
- PROC(STATFS, fhandle, statfsres, 0),
+ PROC(GETATTR, fhandle, attrstat, 1),
+ PROC(SETATTR, sattrargs, attrstat, 0),
+ PROC(LOOKUP, diropargs, diropres, 2),
+ PROC(READLINK, readlinkargs, readlinkres, 3),
+ PROC(READ, readargs, readres, 3),
+ PROC(WRITE, writeargs, writeres, 4),
+ PROC(CREATE, createargs, diropres, 0),
+ PROC(REMOVE, removeargs, stat, 0),
+ PROC(RENAME, renameargs, stat, 0),
+ PROC(LINK, linkargs, stat, 0),
+ PROC(SYMLINK, symlinkargs, stat, 0),
+ PROC(MKDIR, createargs, diropres, 0),
+ PROC(RMDIR, diropargs, stat, 0),
+ PROC(READDIR, readdirargs, readdirres, 3),
+ PROC(STATFS, fhandle, statfsres, 0),
};
struct rpc_version nfs_version2 = {
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index f6cc60f06dac..df30a26cc4fa 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -37,18 +37,16 @@
#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
#define NFS3_fattr_sz (21)
-#define NFS3_wcc_attr_sz (6)
+#define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
+#define NFS3_wcc_attr_sz (6)
#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
-#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
-#define NFS3_fsstat_sz
-#define NFS3_fsinfo_sz
-#define NFS3_pathconf_sz
-#define NFS3_entry_sz (NFS3_filename_sz+3)
-
-#define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
+#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
#define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
-#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
+
+#define NFS3_getattrargs_sz (NFS3_fh_sz)
+#define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
+#define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
#define NFS3_accessargs_sz (NFS3_fh_sz+1)
#define NFS3_readlinkargs_sz (NFS3_fh_sz)
#define NFS3_readargs_sz (NFS3_fh_sz+3)
@@ -57,14 +55,16 @@
#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
+#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
-#define NFS3_readdirargs_sz (NFS3_fh_sz+2)
+#define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
+#define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
#define NFS3_commitargs_sz (NFS3_fh_sz+3)
-#define NFS3_attrstat_sz (1+NFS3_fattr_sz)
-#define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
-#define NFS3_removeres_sz (NFS3_wccstat_sz)
+#define NFS3_getattrres_sz (1+NFS3_fattr_sz)
+#define NFS3_setattrres_sz (1+NFS3_wcc_data_sz)
+#define NFS3_removeres_sz (NFS3_setattrres_sz)
#define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
#define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
@@ -100,1079 +100,2367 @@ static const umode_t nfs_type2fmt[] = {
[NF3FIFO] = S_IFIFO,
};
+/*
+ * While encoding arguments, set up the reply buffer in advance to
+ * receive reply data directly into the page cache.
+ */
+static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
+ unsigned int base, unsigned int len,
+ unsigned int bufsize)
+{
+ struct rpc_auth *auth = req->rq_cred->cr_auth;
+ unsigned int replen;
+
+ replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
+}
+
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
{
- dprintk("nfs: %s: prematurely hit end of receive buffer. "
+ dprintk("NFS: %s prematurely hit the end of our receive buffer. "
"Remaining buffer length is %tu words.\n",
func, xdr->end - xdr->p);
}
+
/*
- * Common NFS XDR functions as inlines
+ * Encode/decode NFSv3 basic data types
+ *
+ * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
+ * "NFS Version 3 Protocol Specification".
+ *
+ * Not all basic data types have their own encoding and decoding
+ * functions. For run-time efficiency, some data types are encoded
+ * or decoded inline.
*/
-static inline __be32 *
-xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
+
+static void encode_uint32(struct xdr_stream *xdr, u32 value)
{
- return xdr_encode_array(p, fh->data, fh->size);
+ __be32 *p = xdr_reserve_space(xdr, 4);
+ *p = cpu_to_be32(value);
}
-static inline __be32 *
-xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
+static int decode_uint32(struct xdr_stream *xdr, u32 *value)
{
- if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
- memcpy(fh->data, p, fh->size);
- return p + XDR_QUADLEN(fh->size);
- }
- return NULL;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *value = be32_to_cpup(p);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
-static inline __be32 *
-xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
+static int decode_uint64(struct xdr_stream *xdr, u64 *value)
{
__be32 *p;
+
+ p = xdr_inline_decode(xdr, 8);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ xdr_decode_hyper(p, value);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * fileid3
+ *
+ * typedef uint64 fileid3;
+ */
+static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid)
+{
+ return xdr_decode_hyper(p, fileid);
+}
+
+static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
+{
+ return decode_uint64(xdr, fileid);
+}
+
+/*
+ * filename3
+ *
+ * typedef string filename3<>;
+ */
+static void encode_filename3(struct xdr_stream *xdr,
+ const char *name, u32 length)
+{
+ __be32 *p;
+
+ BUG_ON(length > NFS3_MAXNAMLEN);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, name, length);
+}
+
+static int decode_inline_filename3(struct xdr_stream *xdr,
+ const char **name, u32 *length)
+{
+ __be32 *p;
+ u32 count;
+
p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
+ if (unlikely(p == NULL))
goto out_overflow;
- fh->size = ntohl(*p++);
+ count = be32_to_cpup(p);
+ if (count > NFS3_MAXNAMLEN)
+ goto out_nametoolong;
+ p = xdr_inline_decode(xdr, count);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *name = (const char *)p;
+ *length = count;
+ return 0;
- if (fh->size <= NFS3_FHSIZE) {
- p = xdr_inline_decode(xdr, fh->size);
- if (unlikely(!p))
- goto out_overflow;
- memcpy(fh->data, p, fh->size);
- return p + XDR_QUADLEN(fh->size);
- }
- return NULL;
+out_nametoolong:
+ dprintk("NFS: returned filename too long: %u\n", count);
+ return -ENAMETOOLONG;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+/*
+ * nfspath3
+ *
+ * typedef string nfspath3<>;
+ */
+static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
+ const u32 length)
+{
+ BUG_ON(length > NFS3_MAXPATHLEN);
+ encode_uint32(xdr, length);
+ xdr_write_pages(xdr, pages, 0, length);
+}
+
+static int decode_nfspath3(struct xdr_stream *xdr)
+{
+ u32 recvd, count;
+ size_t hdrlen;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ count = be32_to_cpup(p);
+ if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
+ goto out_nametoolong;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(count > recvd))
+ goto out_cheating;
+
+ xdr_read_pages(xdr, count);
+ xdr_terminate_string(xdr->buf, count);
+ return 0;
+
+out_nametoolong:
+ dprintk("NFS: returned pathname too long: %u\n", count);
+ return -ENAMETOOLONG;
+out_cheating:
+ dprintk("NFS: server cheating in pathname result: "
+ "count %u > recvd %u\n", count, recvd);
+ return -EIO;
out_overflow:
print_overflow_msg(__func__, xdr);
- return ERR_PTR(-EIO);
+ return -EIO;
}
/*
- * Encode/decode time.
+ * cookie3
+ *
+ * typedef uint64 cookie3
*/
-static inline __be32 *
-xdr_encode_time3(__be32 *p, struct timespec *timep)
+static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
{
- *p++ = htonl(timep->tv_sec);
- *p++ = htonl(timep->tv_nsec);
- return p;
+ return xdr_encode_hyper(p, cookie);
}
-static inline __be32 *
-xdr_decode_time3(__be32 *p, struct timespec *timep)
+static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
{
- timep->tv_sec = ntohl(*p++);
- timep->tv_nsec = ntohl(*p++);
- return p;
+ return decode_uint64(xdr, cookie);
}
-static __be32 *
-xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
+/*
+ * cookieverf3
+ *
+ * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+ */
+static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
+{
+ memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
+ return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
+}
+
+static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * createverf3
+ *
+ * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+ */
+static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
+{
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
+ memcpy(p, verifier, NFS3_CREATEVERFSIZE);
+}
+
+static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ memcpy(verifier, p, NFS3_WRITEVERFSIZE);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * size3
+ *
+ * typedef uint64 size3;
+ */
+static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
+{
+ return xdr_decode_hyper(p, size);
+}
+
+/*
+ * nfsstat3
+ *
+ * enum nfsstat3 {
+ * NFS3_OK = 0,
+ * ...
+ * }
+ */
+#define NFS3_OK NFS_OK
+
+static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *status = be32_to_cpup(p);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * ftype3
+ *
+ * enum ftype3 {
+ * NF3REG = 1,
+ * NF3DIR = 2,
+ * NF3BLK = 3,
+ * NF3CHR = 4,
+ * NF3LNK = 5,
+ * NF3SOCK = 6,
+ * NF3FIFO = 7
+ * };
+ */
+static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
+{
+ BUG_ON(type > NF3FIFO);
+ encode_uint32(xdr, type);
+}
+
+static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode)
{
- unsigned int type, major, minor;
- umode_t fmode;
+ u32 type;
- type = ntohl(*p++);
+ type = be32_to_cpup(p++);
if (type > NF3FIFO)
type = NF3NON;
- fmode = nfs_type2fmt[type];
- fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
- fattr->nlink = ntohl(*p++);
- fattr->uid = ntohl(*p++);
- fattr->gid = ntohl(*p++);
- p = xdr_decode_hyper(p, &fattr->size);
- p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
-
- /* Turn remote device info into Linux-specific dev_t */
- major = ntohl(*p++);
- minor = ntohl(*p++);
- fattr->rdev = MKDEV(major, minor);
- if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
- fattr->rdev = 0;
+ *mode = nfs_type2fmt[type];
+ return p;
+}
- p = xdr_decode_hyper(p, &fattr->fsid.major);
- fattr->fsid.minor = 0;
- p = xdr_decode_hyper(p, &fattr->fileid);
- p = xdr_decode_time3(p, &fattr->atime);
- p = xdr_decode_time3(p, &fattr->mtime);
- p = xdr_decode_time3(p, &fattr->ctime);
+/*
+ * specdata3
+ *
+ * struct specdata3 {
+ * uint32 specdata1;
+ * uint32 specdata2;
+ * };
+ */
+static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
+{
+ __be32 *p;
- /* Update the mode bits */
- fattr->valid |= NFS_ATTR_FATTR_V3;
+ p = xdr_reserve_space(xdr, 8);
+ *p++ = cpu_to_be32(MAJOR(rdev));
+ *p = cpu_to_be32(MINOR(rdev));
+}
+
+static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev)
+{
+ unsigned int major, minor;
+
+ major = be32_to_cpup(p++);
+ minor = be32_to_cpup(p++);
+ *rdev = MKDEV(major, minor);
+ if (MAJOR(*rdev) != major || MINOR(*rdev) != minor)
+ *rdev = 0;
return p;
}
-static inline __be32 *
-xdr_encode_sattr(__be32 *p, struct iattr *attr)
+/*
+ * nfs_fh3
+ *
+ * struct nfs_fh3 {
+ * opaque data<NFS3_FHSIZE>;
+ * };
+ */
+static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
+{
+ __be32 *p;
+
+ BUG_ON(fh->size > NFS3_FHSIZE);
+ p = xdr_reserve_space(xdr, 4 + fh->size);
+ xdr_encode_opaque(p, fh->data, fh->size);
+}
+
+static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p++);
+ if (unlikely(length > NFS3_FHSIZE))
+ goto out_toobig;
+ p = xdr_inline_decode(xdr, length);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ fh->size = length;
+ memcpy(fh->data, p, length);
+ return 0;
+out_toobig:
+ dprintk("NFS: file handle size (%u) too big\n", length);
+ return -E2BIG;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+static void zero_nfs_fh3(struct nfs_fh *fh)
+{
+ memset(fh, 0, sizeof(*fh));
+}
+
+/*
+ * nfstime3
+ *
+ * struct nfstime3 {
+ * uint32 seconds;
+ * uint32 nseconds;
+ * };
+ */
+static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
+{
+ *p++ = cpu_to_be32(timep->tv_sec);
+ *p++ = cpu_to_be32(timep->tv_nsec);
+ return p;
+}
+
+static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep)
+{
+ timep->tv_sec = be32_to_cpup(p++);
+ timep->tv_nsec = be32_to_cpup(p++);
+ return p;
+}
+
+/*
+ * sattr3
+ *
+ * enum time_how {
+ * DONT_CHANGE = 0,
+ * SET_TO_SERVER_TIME = 1,
+ * SET_TO_CLIENT_TIME = 2
+ * };
+ *
+ * union set_mode3 switch (bool set_it) {
+ * case TRUE:
+ * mode3 mode;
+ * default:
+ * void;
+ * };
+ *
+ * union set_uid3 switch (bool set_it) {
+ * case TRUE:
+ * uid3 uid;
+ * default:
+ * void;
+ * };
+ *
+ * union set_gid3 switch (bool set_it) {
+ * case TRUE:
+ * gid3 gid;
+ * default:
+ * void;
+ * };
+ *
+ * union set_size3 switch (bool set_it) {
+ * case TRUE:
+ * size3 size;
+ * default:
+ * void;
+ * };
+ *
+ * union set_atime switch (time_how set_it) {
+ * case SET_TO_CLIENT_TIME:
+ * nfstime3 atime;
+ * default:
+ * void;
+ * };
+ *
+ * union set_mtime switch (time_how set_it) {
+ * case SET_TO_CLIENT_TIME:
+ * nfstime3 mtime;
+ * default:
+ * void;
+ * };
+ *
+ * struct sattr3 {
+ * set_mode3 mode;
+ * set_uid3 uid;
+ * set_gid3 gid;
+ * set_size3 size;
+ * set_atime atime;
+ * set_mtime mtime;
+ * };
+ */
+static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
+{
+ u32 nbytes;
+ __be32 *p;
+
+ /*
+ * In order to make only a single xdr_reserve_space() call,
+ * pre-compute the total number of bytes to be reserved.
+ * Six boolean values, one for each set_foo field, are always
+ * present in the encoded result, so start there.
+ */
+ nbytes = 6 * 4;
+ if (attr->ia_valid & ATTR_MODE)
+ nbytes += 4;
+ if (attr->ia_valid & ATTR_UID)
+ nbytes += 4;
+ if (attr->ia_valid & ATTR_GID)
+ nbytes += 4;
+ if (attr->ia_valid & ATTR_SIZE)
+ nbytes += 8;
+ if (attr->ia_valid & ATTR_ATIME_SET)
+ nbytes += 8;
+ if (attr->ia_valid & ATTR_MTIME_SET)
+ nbytes += 8;
+ p = xdr_reserve_space(xdr, nbytes);
+
if (attr->ia_valid & ATTR_MODE) {
*p++ = xdr_one;
- *p++ = htonl(attr->ia_mode & S_IALLUGO);
- } else {
+ *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
+ } else
*p++ = xdr_zero;
- }
+
if (attr->ia_valid & ATTR_UID) {
*p++ = xdr_one;
- *p++ = htonl(attr->ia_uid);
- } else {
+ *p++ = cpu_to_be32(attr->ia_uid);
+ } else
*p++ = xdr_zero;
- }
+
if (attr->ia_valid & ATTR_GID) {
*p++ = xdr_one;
- *p++ = htonl(attr->ia_gid);
- } else {
+ *p++ = cpu_to_be32(attr->ia_gid);
+ } else
*p++ = xdr_zero;
- }
+
if (attr->ia_valid & ATTR_SIZE) {
*p++ = xdr_one;
- p = xdr_encode_hyper(p, (__u64) attr->ia_size);
- } else {
+ p = xdr_encode_hyper(p, (u64)attr->ia_size);
+ } else
*p++ = xdr_zero;
- }
+
if (attr->ia_valid & ATTR_ATIME_SET) {
*p++ = xdr_two;
- p = xdr_encode_time3(p, &attr->ia_atime);
+ p = xdr_encode_nfstime3(p, &attr->ia_atime);
} else if (attr->ia_valid & ATTR_ATIME) {
*p++ = xdr_one;
- } else {
+ } else
*p++ = xdr_zero;
- }
+
if (attr->ia_valid & ATTR_MTIME_SET) {
*p++ = xdr_two;
- p = xdr_encode_time3(p, &attr->ia_mtime);
+ xdr_encode_nfstime3(p, &attr->ia_mtime);
} else if (attr->ia_valid & ATTR_MTIME) {
- *p++ = xdr_one;
- } else {
- *p++ = xdr_zero;
- }
- return p;
+ *p = xdr_one;
+ } else
+ *p = xdr_zero;
+}
+
+/*
+ * fattr3
+ *
+ * struct fattr3 {
+ * ftype3 type;
+ * mode3 mode;
+ * uint32 nlink;
+ * uid3 uid;
+ * gid3 gid;
+ * size3 size;
+ * size3 used;
+ * specdata3 rdev;
+ * uint64 fsid;
+ * fileid3 fileid;
+ * nfstime3 atime;
+ * nfstime3 mtime;
+ * nfstime3 ctime;
+ * };
+ */
+static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+ umode_t fmode;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+
+ p = xdr_decode_ftype3(p, &fmode);
+
+ fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;
+ fattr->nlink = be32_to_cpup(p++);
+ fattr->uid = be32_to_cpup(p++);
+ fattr->gid = be32_to_cpup(p++);
+
+ p = xdr_decode_size3(p, &fattr->size);
+ p = xdr_decode_size3(p, &fattr->du.nfs3.used);
+ p = xdr_decode_specdata3(p, &fattr->rdev);
+
+ p = xdr_decode_hyper(p, &fattr->fsid.major);
+ fattr->fsid.minor = 0;
+
+ p = xdr_decode_fileid3(p, &fattr->fileid);
+ p = xdr_decode_nfstime3(p, &fattr->atime);
+ p = xdr_decode_nfstime3(p, &fattr->mtime);
+ xdr_decode_nfstime3(p, &fattr->ctime);
+
+ fattr->valid |= NFS_ATTR_FATTR_V3;
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
-static inline __be32 *
-xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
+/*
+ * post_op_attr
+ *
+ * union post_op_attr switch (bool attributes_follow) {
+ * case TRUE:
+ * fattr3 attributes;
+ * case FALSE:
+ * void;
+ * };
+ */
+static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
{
- p = xdr_decode_hyper(p, &fattr->pre_size);
- p = xdr_decode_time3(p, &fattr->pre_mtime);
- p = xdr_decode_time3(p, &fattr->pre_ctime);
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (*p != xdr_zero)
+ return decode_fattr3(xdr, fattr);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * wcc_attr
+ * struct wcc_attr {
+ * size3 size;
+ * nfstime3 mtime;
+ * nfstime3 ctime;
+ * };
+ */
+static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+
fattr->valid |= NFS_ATTR_FATTR_PRESIZE
| NFS_ATTR_FATTR_PREMTIME
| NFS_ATTR_FATTR_PRECTIME;
- return p;
-}
-static inline __be32 *
-xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
-{
- if (*p++)
- p = xdr_decode_fattr(p, fattr);
- return p;
+ p = xdr_decode_size3(p, &fattr->pre_size);
+ p = xdr_decode_nfstime3(p, &fattr->pre_mtime);
+ xdr_decode_nfstime3(p, &fattr->pre_ctime);
+
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
-static inline __be32 *
-xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+/*
+ * pre_op_attr
+ * union pre_op_attr switch (bool attributes_follow) {
+ * case TRUE:
+ * wcc_attr attributes;
+ * case FALSE:
+ * void;
+ * };
+ *
+ * wcc_data
+ *
+ * struct wcc_data {
+ * pre_op_attr before;
+ * post_op_attr after;
+ * };
+ */
+static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
{
__be32 *p;
p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
+ if (unlikely(p == NULL))
goto out_overflow;
- if (ntohl(*p++)) {
- p = xdr_inline_decode(xdr, 84);
- if (unlikely(!p))
- goto out_overflow;
- p = xdr_decode_fattr(p, fattr);
- }
- return p;
+ if (*p != xdr_zero)
+ return decode_wcc_attr(xdr, fattr);
+ return 0;
out_overflow:
print_overflow_msg(__func__, xdr);
- return ERR_PTR(-EIO);
+ return -EIO;
}
-static inline __be32 *
-xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
+static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
{
- if (*p++)
- return xdr_decode_wcc_attr(p, fattr);
- return p;
+ int error;
+
+ error = decode_pre_op_attr(xdr, fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, fattr);
+out:
+ return error;
}
+/*
+ * post_op_fh3
+ *
+ * union post_op_fh3 switch (bool handle_follows) {
+ * case TRUE:
+ * nfs_fh3 handle;
+ * case FALSE:
+ * void;
+ * };
+ */
+static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
+{
+ __be32 *p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (*p != xdr_zero)
+ return decode_nfs_fh3(xdr, fh);
+ zero_nfs_fh3(fh);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
-static inline __be32 *
-xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
+/*
+ * diropargs3
+ *
+ * struct diropargs3 {
+ * nfs_fh3 dir;
+ * filename3 name;
+ * };
+ */
+static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
+ const char *name, u32 length)
{
- p = xdr_decode_pre_op_attr(p, fattr);
- return xdr_decode_post_op_attr(p, fattr);
+ encode_nfs_fh3(xdr, fh);
+ encode_filename3(xdr, name, length);
}
+
/*
- * NFS encode functions
+ * NFSv3 XDR encode functions
+ *
+ * NFSv3 argument types are defined in section 3.3 of RFC 1813:
+ * "NFS Version 3 Protocol Specification".
*/
/*
- * Encode file handle argument
+ * 3.3.1 GETATTR3args
+ *
+ * struct GETATTR3args {
+ * nfs_fh3 object;
+ * };
*/
-static int
-nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
+static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_fh *fh)
{
- p = xdr_encode_fhandle(p, fh);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_nfs_fh3(xdr, fh);
}
/*
- * Encode SETATTR arguments
+ * 3.3.2 SETATTR3args
+ *
+ * union sattrguard3 switch (bool check) {
+ * case TRUE:
+ * nfstime3 obj_ctime;
+ * case FALSE:
+ * void;
+ * };
+ *
+ * struct SETATTR3args {
+ * nfs_fh3 object;
+ * sattr3 new_attributes;
+ * sattrguard3 guard;
+ * };
*/
-static int
-nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
-{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_sattr(p, args->sattr);
- *p++ = htonl(args->guard);
- if (args->guard)
- p = xdr_encode_time3(p, &args->guardtime);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+static void encode_sattrguard3(struct xdr_stream *xdr,
+ const struct nfs3_sattrargs *args)
+{
+ __be32 *p;
+
+ if (args->guard) {
+ p = xdr_reserve_space(xdr, 4 + 8);
+ *p++ = xdr_one;
+ xdr_encode_nfstime3(p, &args->guardtime);
+ } else {
+ p = xdr_reserve_space(xdr, 4);
+ *p = xdr_zero;
+ }
+}
+
+static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_sattrargs *args)
+{
+ encode_nfs_fh3(xdr, args->fh);
+ encode_sattr3(xdr, args->sattr);
+ encode_sattrguard3(xdr, args);
}
/*
- * Encode directory ops argument
+ * 3.3.3 LOOKUP3args
+ *
+ * struct LOOKUP3args {
+ * diropargs3 what;
+ * };
*/
-static int
-nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
+static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_diropargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_diropargs3(xdr, args->fh, args->name, args->len);
}
/*
- * Encode REMOVE argument
+ * 3.3.4 ACCESS3args
+ *
+ * struct ACCESS3args {
+ * nfs_fh3 object;
+ * uint32 access;
+ * };
*/
-static int
-nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
+static void encode_access3args(struct xdr_stream *xdr,
+ const struct nfs3_accessargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name.name, args->name.len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_nfs_fh3(xdr, args->fh);
+ encode_uint32(xdr, args->access);
+}
+
+static void nfs3_xdr_enc_access3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_accessargs *args)
+{
+ encode_access3args(xdr, args);
}
/*
- * Encode access() argument
+ * 3.3.5 READLINK3args
+ *
+ * struct READLINK3args {
+ * nfs_fh3 symlink;
+ * };
*/
-static int
-nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
+static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_readlinkargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- *p++ = htonl(args->access);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_nfs_fh3(xdr, args->fh);
+ prepare_reply_buffer(req, args->pages, args->pgbase,
+ args->pglen, NFS3_readlinkres_sz);
}
/*
- * Arguments to a READ call. Since we read data directly into the page
- * cache, we also set up the reply iovec here so that iov[1] points
- * exactly to the page we want to fetch.
+ * 3.3.6 READ3args
+ *
+ * struct READ3args {
+ * nfs_fh3 file;
+ * offset3 offset;
+ * count3 count;
+ * };
*/
-static int
-nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
+static void encode_read3args(struct xdr_stream *xdr,
+ const struct nfs_readargs *args)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
- u32 count = args->count;
+ __be32 *p;
+
+ encode_nfs_fh3(xdr, args->fh);
- p = xdr_encode_fhandle(p, args->fh);
+ p = xdr_reserve_space(xdr, 8 + 4);
p = xdr_encode_hyper(p, args->offset);
- *p++ = htonl(count);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ *p = cpu_to_be32(args->count);
+}
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
- args->pages, args->pgbase, count);
+static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_readargs *args)
+{
+ encode_read3args(xdr, args);
+ prepare_reply_buffer(req, args->pages, args->pgbase,
+ args->count, NFS3_readres_sz);
req->rq_rcv_buf.flags |= XDRBUF_READ;
- return 0;
}
/*
- * Write arguments. Splice the buffer to be written into the iovec.
+ * 3.3.7 WRITE3args
+ *
+ * enum stable_how {
+ * UNSTABLE = 0,
+ * DATA_SYNC = 1,
+ * FILE_SYNC = 2
+ * };
+ *
+ * struct WRITE3args {
+ * nfs_fh3 file;
+ * offset3 offset;
+ * count3 count;
+ * stable_how stable;
+ * opaque data<>;
+ * };
*/
-static int
-nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
+static void encode_write3args(struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
{
- struct xdr_buf *sndbuf = &req->rq_snd_buf;
- u32 count = args->count;
+ __be32 *p;
- p = xdr_encode_fhandle(p, args->fh);
+ encode_nfs_fh3(xdr, args->fh);
+
+ p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
p = xdr_encode_hyper(p, args->offset);
- *p++ = htonl(count);
- *p++ = htonl(args->stable);
- *p++ = htonl(count);
- sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
-
- /* Copy the page array */
- xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
- sndbuf->flags |= XDRBUF_WRITE;
- return 0;
+ *p++ = cpu_to_be32(args->count);
+ *p++ = cpu_to_be32(args->stable);
+ *p = cpu_to_be32(args->count);
+ xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
+}
+
+static void nfs3_xdr_enc_write3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
+{
+ encode_write3args(xdr, args);
+ xdr->buf->flags |= XDRBUF_WRITE;
}
/*
- * Encode CREATE arguments
+ * 3.3.8 CREATE3args
+ *
+ * enum createmode3 {
+ * UNCHECKED = 0,
+ * GUARDED = 1,
+ * EXCLUSIVE = 2
+ * };
+ *
+ * union createhow3 switch (createmode3 mode) {
+ * case UNCHECKED:
+ * case GUARDED:
+ * sattr3 obj_attributes;
+ * case EXCLUSIVE:
+ * createverf3 verf;
+ * };
+ *
+ * struct CREATE3args {
+ * diropargs3 where;
+ * createhow3 how;
+ * };
*/
-static int
-nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
+static void encode_createhow3(struct xdr_stream *xdr,
+ const struct nfs3_createargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
-
- *p++ = htonl(args->createmode);
- if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
- *p++ = args->verifier[0];
- *p++ = args->verifier[1];
- } else
- p = xdr_encode_sattr(p, args->sattr);
+ encode_uint32(xdr, args->createmode);
+ switch (args->createmode) {
+ case NFS3_CREATE_UNCHECKED:
+ case NFS3_CREATE_GUARDED:
+ encode_sattr3(xdr, args->sattr);
+ break;
+ case NFS3_CREATE_EXCLUSIVE:
+ encode_createverf3(xdr, args->verifier);
+ break;
+ default:
+ BUG();
+ }
+}
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+static void nfs3_xdr_enc_create3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_createargs *args)
+{
+ encode_diropargs3(xdr, args->fh, args->name, args->len);
+ encode_createhow3(xdr, args);
}
/*
- * Encode MKDIR arguments
+ * 3.3.9 MKDIR3args
+ *
+ * struct MKDIR3args {
+ * diropargs3 where;
+ * sattr3 attributes;
+ * };
*/
-static int
-nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
+static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_mkdirargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
- p = xdr_encode_sattr(p, args->sattr);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ encode_diropargs3(xdr, args->fh, args->name, args->len);
+ encode_sattr3(xdr, args->sattr);
}
/*
- * Encode SYMLINK arguments
+ * 3.3.10 SYMLINK3args
+ *
+ * struct symlinkdata3 {
+ * sattr3 symlink_attributes;
+ * nfspath3 symlink_data;
+ * };
+ *
+ * struct SYMLINK3args {
+ * diropargs3 where;
+ * symlinkdata3 symlink;
+ * };
*/
-static int
-nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
+static void encode_symlinkdata3(struct xdr_stream *xdr,
+ const struct nfs3_symlinkargs *args)
{
- p = xdr_encode_fhandle(p, args->fromfh);
- p = xdr_encode_array(p, args->fromname, args->fromlen);
- p = xdr_encode_sattr(p, args->sattr);
- *p++ = htonl(args->pathlen);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ encode_sattr3(xdr, args->sattr);
+ encode_nfspath3(xdr, args->pages, args->pathlen);
+}
- /* Copy the page */
- xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
- return 0;
+static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_symlinkargs *args)
+{
+ encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
+ encode_symlinkdata3(xdr, args);
}
/*
- * Encode MKNOD arguments
+ * 3.3.11 MKNOD3args
+ *
+ * struct devicedata3 {
+ * sattr3 dev_attributes;
+ * specdata3 spec;
+ * };
+ *
+ * union mknoddata3 switch (ftype3 type) {
+ * case NF3CHR:
+ * case NF3BLK:
+ * devicedata3 device;
+ * case NF3SOCK:
+ * case NF3FIFO:
+ * sattr3 pipe_attributes;
+ * default:
+ * void;
+ * };
+ *
+ * struct MKNOD3args {
+ * diropargs3 where;
+ * mknoddata3 what;
+ * };
*/
-static int
-nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
-{
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_array(p, args->name, args->len);
- *p++ = htonl(args->type);
- p = xdr_encode_sattr(p, args->sattr);
- if (args->type == NF3CHR || args->type == NF3BLK) {
- *p++ = htonl(MAJOR(args->rdev));
- *p++ = htonl(MINOR(args->rdev));
+static void encode_devicedata3(struct xdr_stream *xdr,
+ const struct nfs3_mknodargs *args)
+{
+ encode_sattr3(xdr, args->sattr);
+ encode_specdata3(xdr, args->rdev);
+}
+
+static void encode_mknoddata3(struct xdr_stream *xdr,
+ const struct nfs3_mknodargs *args)
+{
+ encode_ftype3(xdr, args->type);
+ switch (args->type) {
+ case NF3CHR:
+ case NF3BLK:
+ encode_devicedata3(xdr, args);
+ break;
+ case NF3SOCK:
+ case NF3FIFO:
+ encode_sattr3(xdr, args->sattr);
+ break;
+ case NF3REG:
+ case NF3DIR:
+ break;
+ default:
+ BUG();
}
+}
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_mknodargs *args)
+{
+ encode_diropargs3(xdr, args->fh, args->name, args->len);
+ encode_mknoddata3(xdr, args);
}
/*
- * Encode RENAME arguments
+ * 3.3.12 REMOVE3args
+ *
+ * struct REMOVE3args {
+ * diropargs3 object;
+ * };
*/
-static int
-nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
-{
- p = xdr_encode_fhandle(p, args->old_dir);
- p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
- p = xdr_encode_fhandle(p, args->new_dir);
- p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_removeargs *args)
+{
+ encode_diropargs3(xdr, args->fh, args->name.name, args->name.len);
}
/*
- * Encode LINK arguments
+ * 3.3.14 RENAME3args
+ *
+ * struct RENAME3args {
+ * diropargs3 from;
+ * diropargs3 to;
+ * };
*/
-static int
-nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
+static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_renameargs *args)
{
- p = xdr_encode_fhandle(p, args->fromfh);
- p = xdr_encode_fhandle(p, args->tofh);
- p = xdr_encode_array(p, args->toname, args->tolen);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ const struct qstr *old = args->old_name;
+ const struct qstr *new = args->new_name;
+
+ encode_diropargs3(xdr, args->old_dir, old->name, old->len);
+ encode_diropargs3(xdr, args->new_dir, new->name, new->len);
}
/*
- * Encode arguments to readdir call
+ * 3.3.15 LINK3args
+ *
+ * struct LINK3args {
+ * nfs_fh3 file;
+ * diropargs3 link;
+ * };
*/
-static int
-nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
+static void nfs3_xdr_enc_link3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_linkargs *args)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
- u32 count = args->count;
-
- p = xdr_encode_fhandle(p, args->fh);
- p = xdr_encode_hyper(p, args->cookie);
- *p++ = args->verf[0];
- *p++ = args->verf[1];
- if (args->plus) {
- /* readdirplus: need dircount + buffer size.
- * We just make sure we make dircount big enough */
- *p++ = htonl(count >> 3);
- }
- *p++ = htonl(count);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
- return 0;
+ encode_nfs_fh3(xdr, args->fromfh);
+ encode_diropargs3(xdr, args->tofh, args->toname, args->tolen);
}
/*
- * Decode the result of a readdir call.
- * We just check for syntactical correctness.
+ * 3.3.16 READDIR3args
+ *
+ * struct READDIR3args {
+ * nfs_fh3 dir;
+ * cookie3 cookie;
+ * cookieverf3 cookieverf;
+ * count3 count;
+ * };
*/
-static int
-nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
+static void encode_readdir3args(struct xdr_stream *xdr,
+ const struct nfs3_readdirargs *args)
{
- struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
- struct kvec *iov = rcvbuf->head;
- struct page **page;
- size_t hdrlen;
- u32 recvd, pglen;
- int status;
-
- status = ntohl(*p++);
- /* Decode post_op_attrs */
- p = xdr_decode_post_op_attr(p, res->dir_attr);
- if (status)
- return nfs_stat_to_errno(status);
- /* Decode verifier cookie */
- if (res->verf) {
- res->verf[0] = *p++;
- res->verf[1] = *p++;
- } else {
- p += 2;
- }
+ __be32 *p;
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READDIR reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
- xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
- }
+ encode_nfs_fh3(xdr, args->fh);
- pglen = rcvbuf->page_len;
- recvd = rcvbuf->len - hdrlen;
- if (pglen > recvd)
- pglen = recvd;
- page = rcvbuf->pages;
+ p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
+ p = xdr_encode_cookie3(p, args->cookie);
+ p = xdr_encode_cookieverf3(p, args->verf);
+ *p = cpu_to_be32(args->count);
+}
- return pglen;
+static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_readdirargs *args)
+{
+ encode_readdir3args(xdr, args);
+ prepare_reply_buffer(req, args->pages, 0,
+ args->count, NFS3_readdirres_sz);
}
-__be32 *
-nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
+/*
+ * 3.3.17 READDIRPLUS3args
+ *
+ * struct READDIRPLUS3args {
+ * nfs_fh3 dir;
+ * cookie3 cookie;
+ * cookieverf3 cookieverf;
+ * count3 dircount;
+ * count3 maxcount;
+ * };
+ */
+static void encode_readdirplus3args(struct xdr_stream *xdr,
+ const struct nfs3_readdirargs *args)
{
__be32 *p;
- struct nfs_entry old = *entry;
-
- p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
- goto out_overflow;
- if (!ntohl(*p++)) {
- p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
- goto out_overflow;
- if (!ntohl(*p++))
- return ERR_PTR(-EAGAIN);
- entry->eof = 1;
- return ERR_PTR(-EBADCOOKIE);
- }
-
- p = xdr_inline_decode(xdr, 12);
- if (unlikely(!p))
- goto out_overflow;
- p = xdr_decode_hyper(p, &entry->ino);
- entry->len = ntohl(*p++);
- p = xdr_inline_decode(xdr, entry->len + 8);
- if (unlikely(!p))
- goto out_overflow;
- entry->name = (const char *) p;
- p += XDR_QUADLEN(entry->len);
- entry->prev_cookie = entry->cookie;
- p = xdr_decode_hyper(p, &entry->cookie);
+ encode_nfs_fh3(xdr, args->fh);
- entry->d_type = DT_UNKNOWN;
- if (plus) {
- entry->fattr->valid = 0;
- p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
- if (IS_ERR(p))
- goto out_overflow_exit;
- entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
- /* In fact, a post_op_fh3: */
- p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
- goto out_overflow;
- if (*p++) {
- p = xdr_decode_fhandle_stream(xdr, entry->fh);
- if (IS_ERR(p))
- goto out_overflow_exit;
- /* Ugh -- server reply was truncated */
- if (p == NULL) {
- dprintk("NFS: FH truncated\n");
- *entry = old;
- return ERR_PTR(-EAGAIN);
- }
- } else
- memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
- }
+ p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
+ p = xdr_encode_cookie3(p, args->cookie);
+ p = xdr_encode_cookieverf3(p, args->verf);
- p = xdr_inline_peek(xdr, 8);
- if (p != NULL)
- entry->eof = !p[0] && p[1];
- else
- entry->eof = 0;
+ /*
+ * readdirplus: need dircount + buffer size.
+ * We just make sure we make dircount big enough
+ */
+ *p++ = cpu_to_be32(args->count >> 3);
- return p;
+ *p = cpu_to_be32(args->count);
+}
-out_overflow:
- print_overflow_msg(__func__, xdr);
-out_overflow_exit:
- return ERR_PTR(-EAGAIN);
+static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_readdirargs *args)
+{
+ encode_readdirplus3args(xdr, args);
+ prepare_reply_buffer(req, args->pages, 0,
+ args->count, NFS3_readdirres_sz);
}
/*
- * Encode COMMIT arguments
+ * 3.3.21 COMMIT3args
+ *
+ * struct COMMIT3args {
+ * nfs_fh3 file;
+ * offset3 offset;
+ * count3 count;
+ * };
*/
-static int
-nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
+static void encode_commit3args(struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
{
- p = xdr_encode_fhandle(p, args->fh);
+ __be32 *p;
+
+ encode_nfs_fh3(xdr, args->fh);
+
+ p = xdr_reserve_space(xdr, 8 + 4);
p = xdr_encode_hyper(p, args->offset);
- *p++ = htonl(args->count);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
+ *p = cpu_to_be32(args->count);
}
-#ifdef CONFIG_NFS_V3_ACL
-/*
- * Encode GETACL arguments
- */
-static int
-nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
- struct nfs3_getaclargs *args)
+static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs_writeargs *args)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
+ encode_commit3args(xdr, args);
+}
- p = xdr_encode_fhandle(p, args->fh);
- *p++ = htonl(args->mask);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+#ifdef CONFIG_NFS_V3_ACL
- if (args->mask & (NFS_ACL | NFS_DFACL)) {
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack +
- ACL3_getaclres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
- NFSACL_MAXPAGES << PAGE_SHIFT);
- }
- return 0;
+static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_getaclargs *args)
+{
+ encode_nfs_fh3(xdr, args->fh);
+ encode_uint32(xdr, args->mask);
+ if (args->mask & (NFS_ACL | NFS_DFACL))
+ prepare_reply_buffer(req, args->pages, 0,
+ NFSACL_MAXPAGES << PAGE_SHIFT,
+ ACL3_getaclres_sz);
}
-/*
- * Encode SETACL arguments
- */
-static int
-nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
- struct nfs3_setaclargs *args)
+static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs3_setaclargs *args)
{
- struct xdr_buf *buf = &req->rq_snd_buf;
unsigned int base;
- int err;
-
- p = xdr_encode_fhandle(p, NFS_FH(args->inode));
- *p++ = htonl(args->mask);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- base = req->rq_slen;
+ int error;
+ encode_nfs_fh3(xdr, NFS_FH(args->inode));
+ encode_uint32(xdr, args->mask);
if (args->npages != 0)
- xdr_encode_pages(buf, args->pages, 0, args->len);
- else
- req->rq_slen = xdr_adjust_iovec(req->rq_svec,
- p + XDR_QUADLEN(args->len));
+ xdr_write_pages(xdr, args->pages, 0, args->len);
- err = nfsacl_encode(buf, base, args->inode,
+ base = req->rq_slen;
+ error = nfsacl_encode(xdr->buf, base, args->inode,
(args->mask & NFS_ACL) ?
args->acl_access : NULL, 1, 0);
- if (err > 0)
- err = nfsacl_encode(buf, base + err, args->inode,
- (args->mask & NFS_DFACL) ?
- args->acl_default : NULL, 1,
- NFS_ACL_DEFAULT);
- return (err > 0) ? 0 : err;
+ BUG_ON(error < 0);
+ error = nfsacl_encode(xdr->buf, base + error, args->inode,
+ (args->mask & NFS_DFACL) ?
+ args->acl_default : NULL, 1,
+ NFS_ACL_DEFAULT);
+ BUG_ON(error < 0);
}
+
#endif /* CONFIG_NFS_V3_ACL */
/*
- * NFS XDR decode functions
+ * NFSv3 XDR decode functions
+ *
+ * NFSv3 result types are defined in section 3.3 of RFC 1813:
+ * "NFS Version 3 Protocol Specification".
*/
/*
- * Decode attrstat reply.
+ * 3.3.1 GETATTR3res
+ *
+ * struct GETATTR3resok {
+ * fattr3 obj_attributes;
+ * };
+ *
+ * union GETATTR3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * GETATTR3resok resok;
+ * default:
+ * void;
+ * };
*/
-static int
-nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
+static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fattr *result)
{
- int status;
-
- if ((status = ntohl(*p++)))
- return nfs_stat_to_errno(status);
- xdr_decode_fattr(p, fattr);
- return 0;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_fattr3(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode status+wcc_data reply
- * SATTR, REMOVE, RMDIR
+ * 3.3.2 SETATTR3res
+ *
+ * struct SETATTR3resok {
+ * wcc_data obj_wcc;
+ * };
+ *
+ * struct SETATTR3resfail {
+ * wcc_data obj_wcc;
+ * };
+ *
+ * union SETATTR3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * SETATTR3resok resok;
+ * default:
+ * SETATTR3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
+static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fattr *result)
{
- int status;
-
- if ((status = ntohl(*p++)))
- status = nfs_stat_to_errno(status);
- xdr_decode_wcc_data(p, fattr);
- return status;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
-static int
-nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
+/*
+ * 3.3.3 LOOKUP3res
+ *
+ * struct LOOKUP3resok {
+ * nfs_fh3 object;
+ * post_op_attr obj_attributes;
+ * post_op_attr dir_attributes;
+ * };
+ *
+ * struct LOOKUP3resfail {
+ * post_op_attr dir_attributes;
+ * };
+ *
+ * union LOOKUP3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * LOOKUP3resok resok;
+ * default:
+ * LOOKUP3resfail resfail;
+ * };
+ */
+static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs3_diropres *result)
{
- return nfs3_xdr_wccstat(req, p, res->dir_attr);
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_nfs_fh3(xdr, result->fh);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->dir_attr);
+out:
+ return error;
+out_default:
+ error = decode_post_op_attr(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ return nfs_stat_to_errno(status);
}
/*
- * Decode LOOKUP reply
+ * 3.3.4 ACCESS3res
+ *
+ * struct ACCESS3resok {
+ * post_op_attr obj_attributes;
+ * uint32 access;
+ * };
+ *
+ * struct ACCESS3resfail {
+ * post_op_attr obj_attributes;
+ * };
+ *
+ * union ACCESS3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * ACCESS3resok resok;
+ * default:
+ * ACCESS3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
+static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs3_accessres *result)
{
- int status;
-
- if ((status = ntohl(*p++))) {
- status = nfs_stat_to_errno(status);
- } else {
- if (!(p = xdr_decode_fhandle(p, res->fh)))
- return -errno_NFSERR_IO;
- p = xdr_decode_post_op_attr(p, res->fattr);
- }
- xdr_decode_post_op_attr(p, res->dir_attr);
- return status;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_uint32(xdr, &result->access);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode ACCESS reply
+ * 3.3.5 READLINK3res
+ *
+ * struct READLINK3resok {
+ * post_op_attr symlink_attributes;
+ * nfspath3 data;
+ * };
+ *
+ * struct READLINK3resfail {
+ * post_op_attr symlink_attributes;
+ * };
+ *
+ * union READLINK3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * READLINK3resok resok;
+ * default:
+ * READLINK3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
+static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fattr *result)
{
- int status = ntohl(*p++);
-
- p = xdr_decode_post_op_attr(p, res->fattr);
- if (status)
- return nfs_stat_to_errno(status);
- res->access = ntohl(*p++);
- return 0;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_nfspath3(xdr);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
-static int
-nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
+/*
+ * 3.3.6 READ3res
+ *
+ * struct READ3resok {
+ * post_op_attr file_attributes;
+ * count3 count;
+ * bool eof;
+ * opaque data<>;
+ * };
+ *
+ * struct READ3resfail {
+ * post_op_attr file_attributes;
+ * };
+ *
+ * union READ3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * READ3resok resok;
+ * default:
+ * READ3resfail resfail;
+ * };
+ */
+static int decode_read3resok(struct xdr_stream *xdr,
+ struct nfs_readres *result)
{
- struct rpc_auth *auth = req->rq_cred->cr_auth;
- unsigned int replen;
+ u32 eof, count, ocount, recvd;
+ size_t hdrlen;
+ __be32 *p;
- p = xdr_encode_fhandle(p, args->fh);
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ p = xdr_inline_decode(xdr, 4 + 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ count = be32_to_cpup(p++);
+ eof = be32_to_cpup(p++);
+ ocount = be32_to_cpup(p++);
+ if (unlikely(ocount != count))
+ goto out_mismatch;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(count > recvd))
+ goto out_cheating;
+
+out:
+ xdr_read_pages(xdr, count);
+ result->eof = eof;
+ result->count = count;
+ return count;
+out_mismatch:
+ dprintk("NFS: READ count doesn't match length of opaque: "
+ "count %u != ocount %u\n", count, ocount);
+ return -EIO;
+out_cheating:
+ dprintk("NFS: server cheating in read result: "
+ "count %u > recvd %u\n", count, recvd);
+ count = recvd;
+ eof = 0;
+ goto out;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
- /* Inline the page array */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
- return 0;
+static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_readres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_read3resok(xdr, result);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode READLINK reply
+ * 3.3.7 WRITE3res
+ *
+ * enum stable_how {
+ * UNSTABLE = 0,
+ * DATA_SYNC = 1,
+ * FILE_SYNC = 2
+ * };
+ *
+ * struct WRITE3resok {
+ * wcc_data file_wcc;
+ * count3 count;
+ * stable_how committed;
+ * writeverf3 verf;
+ * };
+ *
+ * struct WRITE3resfail {
+ * wcc_data file_wcc;
+ * };
+ *
+ * union WRITE3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * WRITE3resok resok;
+ * default:
+ * WRITE3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
+static int decode_write3resok(struct xdr_stream *xdr,
+ struct nfs_writeres *result)
{
- struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
- struct kvec *iov = rcvbuf->head;
- size_t hdrlen;
- u32 len, recvd;
- int status;
-
- status = ntohl(*p++);
- p = xdr_decode_post_op_attr(p, fattr);
-
- if (status != 0)
- return nfs_stat_to_errno(status);
-
- /* Convert length of symlink */
- len = ntohl(*p++);
- if (len >= rcvbuf->page_len) {
- dprintk("nfs: server returned giant symlink!\n");
- return -ENAMETOOLONG;
- }
+ __be32 *p;
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READLINK reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READLINK header is short. "
- "iovec will be shifted.\n");
- xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
- }
- recvd = req->rq_rcv_buf.len - hdrlen;
- if (recvd < len) {
- dprintk("NFS: server cheating in readlink reply: "
- "count %u > recvd %u\n", len, recvd);
- return -EIO;
- }
+ p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ result->count = be32_to_cpup(p++);
+ result->verf->committed = be32_to_cpup(p++);
+ if (unlikely(result->verf->committed > NFS_FILE_SYNC))
+ goto out_badvalue;
+ memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
+ return result->count;
+out_badvalue:
+ dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
- xdr_terminate_string(rcvbuf, len);
- return 0;
+static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_writeres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_write3resok(xdr, result);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode READ reply
+ * 3.3.8 CREATE3res
+ *
+ * struct CREATE3resok {
+ * post_op_fh3 obj;
+ * post_op_attr obj_attributes;
+ * wcc_data dir_wcc;
+ * };
+ *
+ * struct CREATE3resfail {
+ * wcc_data dir_wcc;
+ * };
+ *
+ * union CREATE3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * CREATE3resok resok;
+ * default:
+ * CREATE3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
+static int decode_create3resok(struct xdr_stream *xdr,
+ struct nfs3_diropres *result)
{
- struct kvec *iov = req->rq_rcv_buf.head;
- size_t hdrlen;
- u32 count, ocount, recvd;
- int status;
+ int error;
+
+ error = decode_post_op_fh3(xdr, result->fh);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ /* The server isn't required to return a file handle.
+ * If it didn't, force the client to perform a LOOKUP
+ * to determine the correct file handle and attribute
+ * values for the new object. */
+ if (result->fh->size == 0)
+ result->fattr->valid = 0;
+ error = decode_wcc_data(xdr, result->dir_attr);
+out:
+ return error;
+}
- status = ntohl(*p++);
- p = xdr_decode_post_op_attr(p, res->fattr);
+static int nfs3_xdr_dec_create3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs3_diropres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_create3resok(xdr, result);
+out:
+ return error;
+out_default:
+ error = decode_wcc_data(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ return nfs_stat_to_errno(status);
+}
- if (status != 0)
- return nfs_stat_to_errno(status);
+/*
+ * 3.3.12 REMOVE3res
+ *
+ * struct REMOVE3resok {
+ * wcc_data dir_wcc;
+ * };
+ *
+ * struct REMOVE3resfail {
+ * wcc_data dir_wcc;
+ * };
+ *
+ * union REMOVE3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * REMOVE3resok resok;
+ * default:
+ * REMOVE3resfail resfail;
+ * };
+ */
+static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_removeres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
+}
- /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
- * in that it puts the count both in the res struct and in the
- * opaque data count. */
- count = ntohl(*p++);
- res->eof = ntohl(*p++);
- ocount = ntohl(*p++);
+/*
+ * 3.3.14 RENAME3res
+ *
+ * struct RENAME3resok {
+ * wcc_data fromdir_wcc;
+ * wcc_data todir_wcc;
+ * };
+ *
+ * struct RENAME3resfail {
+ * wcc_data fromdir_wcc;
+ * wcc_data todir_wcc;
+ * };
+ *
+ * union RENAME3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * RENAME3resok resok;
+ * default:
+ * RENAME3resfail resfail;
+ * };
+ */
+static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_renameres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->old_fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->new_fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
+}
- if (ocount != count) {
- dprintk("NFS: READ count doesn't match RPC opaque count.\n");
- return -errno_NFSERR_IO;
- }
+/*
+ * 3.3.15 LINK3res
+ *
+ * struct LINK3resok {
+ * post_op_attr file_attributes;
+ * wcc_data linkdir_wcc;
+ * };
+ *
+ * struct LINK3resfail {
+ * post_op_attr file_attributes;
+ * wcc_data linkdir_wcc;
+ * };
+ *
+ * union LINK3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * LINK3resok resok;
+ * default:
+ * LINK3resfail resfail;
+ * };
+ */
+static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs3_linkres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
+}
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
- if (iov->iov_len < hdrlen) {
- dprintk("NFS: READ reply header overflowed:"
- "length %Zu > %Zu\n", hdrlen, iov->iov_len);
- return -errno_NFSERR_IO;
- } else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READ header is short. iovec will be shifted.\n");
- xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
- }
+/**
+ * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
+ * the local page cache
+ * @xdr: XDR stream where entry resides
+ * @entry: buffer to fill in with entry data
+ * @plus: boolean indicating whether this should be a readdirplus entry
+ *
+ * Returns zero if successful, otherwise a negative errno value is
+ * returned.
+ *
+ * This function is not invoked during READDIR reply decoding, but
+ * rather whenever an application invokes the getdents(2) system call
+ * on a directory already in our cache.
+ *
+ * 3.3.16 entry3
+ *
+ * struct entry3 {
+ * fileid3 fileid;
+ * filename3 name;
+ * cookie3 cookie;
+ * fhandle3 filehandle;
+ * post_op_attr3 attributes;
+ * entry3 *nextentry;
+ * };
+ *
+ * 3.3.17 entryplus3
+ * struct entryplus3 {
+ * fileid3 fileid;
+ * filename3 name;
+ * cookie3 cookie;
+ * post_op_attr name_attributes;
+ * post_op_fh3 name_handle;
+ * entryplus3 *nextentry;
+ * };
+ */
+int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
+ int plus)
+{
+ struct nfs_entry old = *entry;
+ __be32 *p;
+ int error;
- recvd = req->rq_rcv_buf.len - hdrlen;
- if (count > recvd) {
- dprintk("NFS: server cheating in read reply: "
- "count %u > recvd %u\n", count, recvd);
- count = recvd;
- res->eof = 0;
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (*p == xdr_zero) {
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (*p == xdr_zero)
+ return -EAGAIN;
+ entry->eof = 1;
+ return -EBADCOOKIE;
}
- if (count < res->count)
- res->count = count;
+ error = decode_fileid3(xdr, &entry->ino);
+ if (unlikely(error))
+ return error;
- return count;
-}
+ error = decode_inline_filename3(xdr, &entry->name, &entry->len);
+ if (unlikely(error))
+ return error;
-/*
- * Decode WRITE response
- */
-static int
-nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
-{
- int status;
+ entry->prev_cookie = entry->cookie;
+ error = decode_cookie3(xdr, &entry->cookie);
+ if (unlikely(error))
+ return error;
- status = ntohl(*p++);
- p = xdr_decode_wcc_data(p, res->fattr);
+ entry->d_type = DT_UNKNOWN;
- if (status != 0)
- return nfs_stat_to_errno(status);
+ if (plus) {
+ entry->fattr->valid = 0;
+ error = decode_post_op_attr(xdr, entry->fattr);
+ if (unlikely(error))
+ return error;
+ if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
+ entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
- res->count = ntohl(*p++);
- res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
- res->verf->verifier[0] = *p++;
- res->verf->verifier[1] = *p++;
+ /* In fact, a post_op_fh3: */
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ if (*p != xdr_zero) {
+ error = decode_nfs_fh3(xdr, entry->fh);
+ if (unlikely(error)) {
+ if (error == -E2BIG)
+ goto out_truncated;
+ return error;
+ }
+ } else
+ zero_nfs_fh3(entry->fh);
+ }
- return res->count;
-}
+ /* Peek at the next entry to see if we're at EOD */
+ p = xdr_inline_peek(xdr, 4 + 4);
+ entry->eof = 0;
+ if (p != NULL)
+ entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
+ return 0;
-/*
- * Decode a CREATE response
- */
-static int
-nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
-{
- int status;
-
- status = ntohl(*p++);
- if (status == 0) {
- if (*p++) {
- if (!(p = xdr_decode_fhandle(p, res->fh)))
- return -errno_NFSERR_IO;
- p = xdr_decode_post_op_attr(p, res->fattr);
- } else {
- memset(res->fh, 0, sizeof(*res->fh));
- /* Do decode post_op_attr but set it to NULL */
- p = xdr_decode_post_op_attr(p, res->fattr);
- res->fattr->valid = 0;
- }
- } else {
- status = nfs_stat_to_errno(status);
- }
- p = xdr_decode_wcc_data(p, res->dir_attr);
- return status;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EAGAIN;
+out_truncated:
+ dprintk("NFS: directory entry contains invalid file handle\n");
+ *entry = old;
+ return -EAGAIN;
}
/*
- * Decode RENAME reply
+ * 3.3.16 READDIR3res
+ *
+ * struct dirlist3 {
+ * entry3 *entries;
+ * bool eof;
+ * };
+ *
+ * struct READDIR3resok {
+ * post_op_attr dir_attributes;
+ * cookieverf3 cookieverf;
+ * dirlist3 reply;
+ * };
+ *
+ * struct READDIR3resfail {
+ * post_op_attr dir_attributes;
+ * };
+ *
+ * union READDIR3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * READDIR3resok resok;
+ * default:
+ * READDIR3resfail resfail;
+ * };
+ *
+ * Read the directory contents into the page cache, but otherwise
+ * don't touch them. The actual decoding is done by nfs3_decode_entry()
+ * during subsequent nfs_readdir() calls.
*/
-static int
-nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
+static int decode_dirlist3(struct xdr_stream *xdr)
{
- int status;
+ u32 recvd, pglen;
+ size_t hdrlen;
- if ((status = ntohl(*p++)) != 0)
- status = nfs_stat_to_errno(status);
- p = xdr_decode_wcc_data(p, res->old_fattr);
- p = xdr_decode_wcc_data(p, res->new_fattr);
- return status;
+ pglen = xdr->buf->page_len;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(pglen > recvd))
+ goto out_cheating;
+out:
+ xdr_read_pages(xdr, pglen);
+ return pglen;
+out_cheating:
+ dprintk("NFS: server cheating in readdir result: "
+ "pglen %u > recvd %u\n", pglen, recvd);
+ pglen = recvd;
+ goto out;
}
-/*
- * Decode LINK reply
- */
-static int
-nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
+static int decode_readdir3resok(struct xdr_stream *xdr,
+ struct nfs3_readdirres *result)
{
- int status;
+ int error;
+
+ error = decode_post_op_attr(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ /* XXX: do we need to check if result->verf != NULL ? */
+ error = decode_cookieverf3(xdr, result->verf);
+ if (unlikely(error))
+ goto out;
+ error = decode_dirlist3(xdr);
+out:
+ return error;
+}
- if ((status = ntohl(*p++)) != 0)
- status = nfs_stat_to_errno(status);
- p = xdr_decode_post_op_attr(p, res->fattr);
- p = xdr_decode_wcc_data(p, res->dir_attr);
- return status;
+static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs3_readdirres *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_readdir3resok(xdr, result);
+out:
+ return error;
+out_default:
+ error = decode_post_op_attr(xdr, result->dir_attr);
+ if (unlikely(error))
+ goto out;
+ return nfs_stat_to_errno(status);
}
/*
- * Decode FSSTAT reply
+ * 3.3.18 FSSTAT3res
+ *
+ * struct FSSTAT3resok {
+ * post_op_attr obj_attributes;
+ * size3 tbytes;
+ * size3 fbytes;
+ * size3 abytes;
+ * size3 tfiles;
+ * size3 ffiles;
+ * size3 afiles;
+ * uint32 invarsec;
+ * };
+ *
+ * struct FSSTAT3resfail {
+ * post_op_attr obj_attributes;
+ * };
+ *
+ * union FSSTAT3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * FSSTAT3resok resok;
+ * default:
+ * FSSTAT3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
+static int decode_fsstat3resok(struct xdr_stream *xdr,
+ struct nfs_fsstat *result)
{
- int status;
-
- status = ntohl(*p++);
-
- p = xdr_decode_post_op_attr(p, res->fattr);
- if (status != 0)
- return nfs_stat_to_errno(status);
-
- p = xdr_decode_hyper(p, &res->tbytes);
- p = xdr_decode_hyper(p, &res->fbytes);
- p = xdr_decode_hyper(p, &res->abytes);
- p = xdr_decode_hyper(p, &res->tfiles);
- p = xdr_decode_hyper(p, &res->ffiles);
- p = xdr_decode_hyper(p, &res->afiles);
+ __be32 *p;
+ p = xdr_inline_decode(xdr, 8 * 6 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ p = xdr_decode_size3(p, &result->tbytes);
+ p = xdr_decode_size3(p, &result->fbytes);
+ p = xdr_decode_size3(p, &result->abytes);
+ p = xdr_decode_size3(p, &result->tfiles);
+ p = xdr_decode_size3(p, &result->ffiles);
+ xdr_decode_size3(p, &result->afiles);
/* ignore invarsec */
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fsstat *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_fsstat3resok(xdr, result);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode FSINFO reply
+ * 3.3.19 FSINFO3res
+ *
+ * struct FSINFO3resok {
+ * post_op_attr obj_attributes;
+ * uint32 rtmax;
+ * uint32 rtpref;
+ * uint32 rtmult;
+ * uint32 wtmax;
+ * uint32 wtpref;
+ * uint32 wtmult;
+ * uint32 dtpref;
+ * size3 maxfilesize;
+ * nfstime3 time_delta;
+ * uint32 properties;
+ * };
+ *
+ * struct FSINFO3resfail {
+ * post_op_attr obj_attributes;
+ * };
+ *
+ * union FSINFO3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * FSINFO3resok resok;
+ * default:
+ * FSINFO3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
+static int decode_fsinfo3resok(struct xdr_stream *xdr,
+ struct nfs_fsinfo *result)
{
- int status;
-
- status = ntohl(*p++);
-
- p = xdr_decode_post_op_attr(p, res->fattr);
- if (status != 0)
- return nfs_stat_to_errno(status);
+ __be32 *p;
- res->rtmax = ntohl(*p++);
- res->rtpref = ntohl(*p++);
- res->rtmult = ntohl(*p++);
- res->wtmax = ntohl(*p++);
- res->wtpref = ntohl(*p++);
- res->wtmult = ntohl(*p++);
- res->dtpref = ntohl(*p++);
- p = xdr_decode_hyper(p, &res->maxfilesize);
- p = xdr_decode_time3(p, &res->time_delta);
+ p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ result->rtmax = be32_to_cpup(p++);
+ result->rtpref = be32_to_cpup(p++);
+ result->rtmult = be32_to_cpup(p++);
+ result->wtmax = be32_to_cpup(p++);
+ result->wtpref = be32_to_cpup(p++);
+ result->wtmult = be32_to_cpup(p++);
+ result->dtpref = be32_to_cpup(p++);
+ p = xdr_decode_size3(p, &result->maxfilesize);
+ xdr_decode_nfstime3(p, &result->time_delta);
/* ignore properties */
- res->lease_time = 0;
+ result->lease_time = 0;
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fsinfo *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_fsinfo3resok(xdr, result);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode PATHCONF reply
+ * 3.3.20 PATHCONF3res
+ *
+ * struct PATHCONF3resok {
+ * post_op_attr obj_attributes;
+ * uint32 linkmax;
+ * uint32 name_max;
+ * bool no_trunc;
+ * bool chown_restricted;
+ * bool case_insensitive;
+ * bool case_preserving;
+ * };
+ *
+ * struct PATHCONF3resfail {
+ * post_op_attr obj_attributes;
+ * };
+ *
+ * union PATHCONF3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * PATHCONF3resok resok;
+ * default:
+ * PATHCONF3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
+static int decode_pathconf3resok(struct xdr_stream *xdr,
+ struct nfs_pathconf *result)
{
- int status;
-
- status = ntohl(*p++);
-
- p = xdr_decode_post_op_attr(p, res->fattr);
- if (status != 0)
- return nfs_stat_to_errno(status);
- res->max_link = ntohl(*p++);
- res->max_namelen = ntohl(*p++);
+ __be32 *p;
+ p = xdr_inline_decode(xdr, 4 * 6);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ result->max_link = be32_to_cpup(p++);
+ result->max_namelen = be32_to_cpup(p);
/* ignore remaining fields */
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_pathconf *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_pathconf3resok(xdr, result);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
/*
- * Decode COMMIT reply
+ * 3.3.21 COMMIT3res
+ *
+ * struct COMMIT3resok {
+ * wcc_data file_wcc;
+ * writeverf3 verf;
+ * };
+ *
+ * struct COMMIT3resfail {
+ * wcc_data file_wcc;
+ * };
+ *
+ * union COMMIT3res switch (nfsstat3 status) {
+ * case NFS3_OK:
+ * COMMIT3resok resok;
+ * default:
+ * COMMIT3resfail resfail;
+ * };
*/
-static int
-nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
+static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_writeres *result)
{
- int status;
-
- status = ntohl(*p++);
- p = xdr_decode_wcc_data(p, res->fattr);
- if (status != 0)
- return nfs_stat_to_errno(status);
-
- res->verf->verifier[0] = *p++;
- res->verf->verifier[1] = *p++;
- return 0;
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ error = decode_wcc_data(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_status;
+ error = decode_writeverf3(xdr, result->verf->verifier);
+out:
+ return error;
+out_status:
+ return nfs_stat_to_errno(status);
}
#ifdef CONFIG_NFS_V3_ACL
-/*
- * Decode GETACL reply
- */
-static int
-nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
- struct nfs3_getaclres *res)
+
+static inline int decode_getacl3resok(struct xdr_stream *xdr,
+ struct nfs3_getaclres *result)
{
- struct xdr_buf *buf = &req->rq_rcv_buf;
- int status = ntohl(*p++);
struct posix_acl **acl;
unsigned int *aclcnt;
- int err, base;
-
- if (status != 0)
- return nfs_stat_to_errno(status);
- p = xdr_decode_post_op_attr(p, res->fattr);
- res->mask = ntohl(*p++);
- if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
- return -EINVAL;
- base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
-
- acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
- aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
- err = nfsacl_decode(buf, base, aclcnt, acl);
-
- acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
- aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
- if (err > 0)
- err = nfsacl_decode(buf, base + err, aclcnt, acl);
- return (err > 0) ? 0 : err;
+ size_t hdrlen;
+ int error;
+
+ error = decode_post_op_attr(xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_uint32(xdr, &result->mask);
+ if (unlikely(error))
+ goto out;
+ error = -EINVAL;
+ if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
+ goto out;
+
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+
+ acl = NULL;
+ if (result->mask & NFS_ACL)
+ acl = &result->acl_access;
+ aclcnt = NULL;
+ if (result->mask & NFS_ACLCNT)
+ aclcnt = &result->acl_access_count;
+ error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
+ if (unlikely(error <= 0))
+ goto out;
+
+ acl = NULL;
+ if (result->mask & NFS_DFACL)
+ acl = &result->acl_default;
+ aclcnt = NULL;
+ if (result->mask & NFS_DFACLCNT)
+ aclcnt = &result->acl_default_count;
+ error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
+ if (unlikely(error <= 0))
+ return error;
+ error = 0;
+out:
+ return error;
}
-/*
- * Decode setacl reply.
- */
-static int
-nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
+static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs3_getaclres *result)
{
- int status = ntohl(*p++);
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_getacl3resok(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
- if (status)
- return nfs_stat_to_errno(status);
- xdr_decode_post_op_attr(p, fattr);
- return 0;
+static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fattr *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_nfsstat3(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS3_OK)
+ goto out_default;
+ error = decode_post_op_attr(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
}
+
#endif /* CONFIG_NFS_V3_ACL */
#define PROC(proc, argtype, restype, timer) \
[NFS3PROC_##proc] = { \
.p_proc = NFS3PROC_##proc, \
- .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \
- .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
- .p_arglen = NFS3_##argtype##_sz, \
- .p_replen = NFS3_##restype##_sz, \
+ .p_encode = (kxdreproc_t)nfs3_xdr_enc_##argtype##3args, \
+ .p_decode = (kxdrdproc_t)nfs3_xdr_dec_##restype##3res, \
+ .p_arglen = NFS3_##argtype##args_sz, \
+ .p_replen = NFS3_##restype##res_sz, \
.p_timer = timer, \
.p_statidx = NFS3PROC_##proc, \
.p_name = #proc, \
}
struct rpc_procinfo nfs3_procedures[] = {
- PROC(GETATTR, fhandle, attrstat, 1),
- PROC(SETATTR, sattrargs, wccstat, 0),
- PROC(LOOKUP, diropargs, lookupres, 2),
- PROC(ACCESS, accessargs, accessres, 1),
- PROC(READLINK, readlinkargs, readlinkres, 3),
- PROC(READ, readargs, readres, 3),
- PROC(WRITE, writeargs, writeres, 4),
- PROC(CREATE, createargs, createres, 0),
- PROC(MKDIR, mkdirargs, createres, 0),
- PROC(SYMLINK, symlinkargs, createres, 0),
- PROC(MKNOD, mknodargs, createres, 0),
- PROC(REMOVE, removeargs, removeres, 0),
- PROC(RMDIR, diropargs, wccstat, 0),
- PROC(RENAME, renameargs, renameres, 0),
- PROC(LINK, linkargs, linkres, 0),
- PROC(READDIR, readdirargs, readdirres, 3),
- PROC(READDIRPLUS, readdirargs, readdirres, 3),
- PROC(FSSTAT, fhandle, fsstatres, 0),
- PROC(FSINFO, fhandle, fsinfores, 0),
- PROC(PATHCONF, fhandle, pathconfres, 0),
- PROC(COMMIT, commitargs, commitres, 5),
+ PROC(GETATTR, getattr, getattr, 1),
+ PROC(SETATTR, setattr, setattr, 0),
+ PROC(LOOKUP, lookup, lookup, 2),
+ PROC(ACCESS, access, access, 1),
+ PROC(READLINK, readlink, readlink, 3),
+ PROC(READ, read, read, 3),
+ PROC(WRITE, write, write, 4),
+ PROC(CREATE, create, create, 0),
+ PROC(MKDIR, mkdir, create, 0),
+ PROC(SYMLINK, symlink, create, 0),
+ PROC(MKNOD, mknod, create, 0),
+ PROC(REMOVE, remove, remove, 0),
+ PROC(RMDIR, lookup, setattr, 0),
+ PROC(RENAME, rename, rename, 0),
+ PROC(LINK, link, link, 0),
+ PROC(READDIR, readdir, readdir, 3),
+ PROC(READDIRPLUS, readdirplus, readdir, 3),
+ PROC(FSSTAT, getattr, fsstat, 0),
+ PROC(FSINFO, getattr, fsinfo, 0),
+ PROC(PATHCONF, getattr, pathconf, 0),
+ PROC(COMMIT, commit, commit, 5),
};
struct rpc_version nfs_version3 = {
@@ -1185,8 +2473,8 @@ struct rpc_version nfs_version3 = {
static struct rpc_procinfo nfs3_acl_procedures[] = {
[ACLPROC3_GETACL] = {
.p_proc = ACLPROC3_GETACL,
- .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
- .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
+ .p_encode = (kxdreproc_t)nfs3_xdr_enc_getacl3args,
+ .p_decode = (kxdrdproc_t)nfs3_xdr_dec_getacl3res,
.p_arglen = ACL3_getaclargs_sz,
.p_replen = ACL3_getaclres_sz,
.p_timer = 1,
@@ -1194,8 +2482,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = {
},
[ACLPROC3_SETACL] = {
.p_proc = ACLPROC3_SETACL,
- .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
- .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
+ .p_encode = (kxdreproc_t)nfs3_xdr_enc_setacl3args,
+ .p_decode = (kxdrdproc_t)nfs3_xdr_dec_setacl3res,
.p_arglen = ACL3_setaclargs_sz,
.p_replen = ACL3_setaclres_sz,
.p_timer = 0,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 9fa496387fdf..3b3829c3098f 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -227,12 +227,6 @@ struct nfs4_state_maintenance_ops {
extern const struct dentry_operations nfs4_dentry_operations;
extern const struct inode_operations nfs4_dir_inode_operations;
-/* inode.c */
-extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
-extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int);
-extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
-
-
/* nfs4proc.c */
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
@@ -246,6 +240,7 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh
extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
struct nfs4_fs_locations *fs_locations, struct page *page);
extern void nfs4_release_lockowner(const struct nfs4_lock_state *);
+extern const struct xattr_handler *nfs4_xattr_handlers[];
#if defined(CONFIG_NFS_V4_1)
static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
@@ -331,7 +326,6 @@ extern void nfs_free_seqid(struct nfs_seqid *seqid);
extern const nfs4_stateid zero_stateid;
/* nfs4xdr.c */
-extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
extern struct rpc_procinfo nfs4_procedures[];
struct nfs4_mount_data;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6a653ffd8e4e..82f3a82b7115 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -49,6 +49,7 @@
#include <linux/mount.h>
#include <linux/module.h>
#include <linux/sunrpc/bc_xprt.h>
+#include <linux/xattr.h>
#include "nfs4_fs.h"
#include "delegation.h"
@@ -1984,8 +1985,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
path_get(path);
calldata->path = *path;
- msg.rpc_argp = &calldata->arg,
- msg.rpc_resp = &calldata->res,
+ msg.rpc_argp = &calldata->arg;
+ msg.rpc_resp = &calldata->res;
task_setup_data.callback_data = calldata;
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
@@ -2486,6 +2487,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
path = &ctx->path;
fmode = ctx->mode;
}
+ sattr->ia_mode &= ~current_umask();
state = nfs4_do_open(dir, path, fmode, flags, sattr, cred);
d_drop(dentry);
if (IS_ERR(state)) {
@@ -2816,6 +2818,8 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
{
struct nfs4_exception exception = { };
int err;
+
+ sattr->ia_mode &= ~current_umask();
do {
err = nfs4_handle_exception(NFS_SERVER(dir),
_nfs4_proc_mkdir(dir, dentry, sattr),
@@ -2916,6 +2920,8 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
{
struct nfs4_exception exception = { };
int err;
+
+ sattr->ia_mode &= ~current_umask();
do {
err = nfs4_handle_exception(NFS_SERVER(dir),
_nfs4_proc_mknod(dir, dentry, sattr, rdev),
@@ -3361,6 +3367,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
ret = nfs_revalidate_inode(server, inode);
if (ret < 0)
return ret;
+ if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+ nfs_zap_acl_cache(inode);
ret = nfs4_read_cached_acl(inode, buf, buflen);
if (ret != -ENOENT)
return ret;
@@ -3389,6 +3397,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+ /*
+ * Acl update can result in inode attribute update.
+ * so mark the attribute cache invalid.
+ */
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
+ spin_unlock(&inode->i_lock);
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
return ret;
@@ -3508,7 +3523,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
if (signalled())
break;
if (loop++ & 1)
- ssleep(clp->cl_lease_time + 1);
+ ssleep(clp->cl_lease_time / HZ + 1);
else
if (++clp->cl_id_uniquifier == 0)
break;
@@ -3654,8 +3669,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
data->rpc_status = 0;
task_setup_data.callback_data = data;
- msg.rpc_argp = &data->args,
- msg.rpc_resp = &data->res,
+ msg.rpc_argp = &data->args;
+ msg.rpc_resp = &data->res;
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
return PTR_ERR(task);
@@ -3899,8 +3914,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
return ERR_PTR(-ENOMEM);
}
- msg.rpc_argp = &data->arg,
- msg.rpc_resp = &data->res,
+ msg.rpc_argp = &data->arg;
+ msg.rpc_resp = &data->res;
task_setup_data.callback_data = data;
return rpc_run_task(&task_setup_data);
}
@@ -4136,8 +4151,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
data->arg.reclaim = NFS_LOCK_RECLAIM;
task_setup_data.callback_ops = &nfs4_recover_lock_ops;
}
- msg.rpc_argp = &data->arg,
- msg.rpc_resp = &data->res,
+ msg.rpc_argp = &data->arg;
+ msg.rpc_resp = &data->res;
task_setup_data.callback_data = data;
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
@@ -4389,42 +4404,36 @@ void nfs4_release_lockowner(const struct nfs4_lock_state *lsp)
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
-int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
- size_t buflen, int flags)
+static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
+ const void *buf, size_t buflen,
+ int flags, int type)
{
- struct inode *inode = dentry->d_inode;
-
- if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
- return -EOPNOTSUPP;
+ if (strcmp(key, "") != 0)
+ return -EINVAL;
- return nfs4_proc_set_acl(inode, buf, buflen);
+ return nfs4_proc_set_acl(dentry->d_inode, buf, buflen);
}
-/* The getxattr man page suggests returning -ENODATA for unknown attributes,
- * and that's what we'll do for e.g. user attributes that haven't been set.
- * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported
- * attributes in kernel-managed attribute namespaces. */
-ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
- size_t buflen)
+static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
+ void *buf, size_t buflen, int type)
{
- struct inode *inode = dentry->d_inode;
-
- if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
- return -EOPNOTSUPP;
+ if (strcmp(key, "") != 0)
+ return -EINVAL;
- return nfs4_proc_get_acl(inode, buf, buflen);
+ return nfs4_proc_get_acl(dentry->d_inode, buf, buflen);
}
-ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
+static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
+ size_t list_len, const char *name,
+ size_t name_len, int type)
{
- size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1;
+ size_t len = sizeof(XATTR_NAME_NFSV4_ACL);
if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
return 0;
- if (buf && buflen < len)
- return -ERANGE;
- if (buf)
- memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
+
+ if (list && len <= list_len)
+ memcpy(list, XATTR_NAME_NFSV4_ACL, len);
return len;
}
@@ -5495,9 +5504,10 @@ static const struct inode_operations nfs4_file_inode_operations = {
.permission = nfs_permission,
.getattr = nfs_getattr,
.setattr = nfs_setattr,
- .getxattr = nfs4_getxattr,
- .setxattr = nfs4_setxattr,
- .listxattr = nfs4_listxattr,
+ .getxattr = generic_getxattr,
+ .setxattr = generic_setxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
};
const struct nfs_rpc_ops nfs_v4_clientops = {
@@ -5542,6 +5552,18 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.open_context = nfs4_atomic_open,
};
+static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
+ .prefix = XATTR_NAME_NFSV4_ACL,
+ .list = nfs4_xattr_list_nfs4_acl,
+ .get = nfs4_xattr_get_nfs4_acl,
+ .set = nfs4_xattr_set_nfs4_acl,
+};
+
+const struct xattr_handler *nfs4_xattr_handlers[] = {
+ &nfs4_xattr_nfs4_acl_handler,
+ NULL
+};
+
/*
* Local variables:
* c-basic-offset: 8
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 9f1826b012e6..f3f99156bfcb 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1510,7 +1510,7 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
hdr->replen += decode_restorefh_maxsz;
}
-static int
+static void
encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr)
{
__be32 *p;
@@ -1521,14 +1521,12 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
p = reserve_space(xdr, 2*4);
*p++ = cpu_to_be32(1);
*p = cpu_to_be32(FATTR4_WORD0_ACL);
- if (arg->acl_len % 4)
- return -EINVAL;
+ BUG_ON(arg->acl_len % 4);
p = reserve_space(xdr, 4);
*p = cpu_to_be32(arg->acl_len);
xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
hdr->nops++;
hdr->replen += decode_setacl_maxsz;
- return 0;
}
static void
@@ -1833,393 +1831,362 @@ static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
/*
* Encode an ACCESS request
*/
-static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args)
+static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_accessargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_access(&xdr, args->access, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_access(xdr, args->access, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode LOOKUP request
*/
-static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args)
+static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_lookup_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->dir_fh, &hdr);
- encode_lookup(&xdr, args->name, &hdr);
- encode_getfh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->dir_fh, &hdr);
+ encode_lookup(xdr, args->name, &hdr);
+ encode_getfh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode LOOKUP_ROOT request
*/
-static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args)
+static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs4_lookup_root_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putrootfh(&xdr, &hdr);
- encode_getfh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putrootfh(xdr, &hdr);
+ encode_getfh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode REMOVE request
*/
-static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
+static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs_removeargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_remove(&xdr, &args->name, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_remove(xdr, &args->name, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode RENAME request
*/
-static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs_renameargs *args)
+static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs_renameargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->old_dir, &hdr);
- encode_savefh(&xdr, &hdr);
- encode_putfh(&xdr, args->new_dir, &hdr);
- encode_rename(&xdr, args->old_name, args->new_name, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
- encode_restorefh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->old_dir, &hdr);
+ encode_savefh(xdr, &hdr);
+ encode_putfh(xdr, args->new_dir, &hdr);
+ encode_rename(xdr, args->old_name, args->new_name, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
+ encode_restorefh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode LINK request
*/
-static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args)
+static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_link_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_savefh(&xdr, &hdr);
- encode_putfh(&xdr, args->dir_fh, &hdr);
- encode_link(&xdr, args->name, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
- encode_restorefh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_savefh(xdr, &hdr);
+ encode_putfh(xdr, args->dir_fh, &hdr);
+ encode_link(xdr, args->name, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
+ encode_restorefh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode CREATE request
*/
-static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
+static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_create_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->dir_fh, &hdr);
- encode_savefh(&xdr, &hdr);
- encode_create(&xdr, args, &hdr);
- encode_getfh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
- encode_restorefh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->dir_fh, &hdr);
+ encode_savefh(xdr, &hdr);
+ encode_create(xdr, args, &hdr);
+ encode_getfh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
+ encode_restorefh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode SYMLINK request
*/
-static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
+static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_create_arg *args)
{
- return nfs4_xdr_enc_create(req, p, args);
+ nfs4_xdr_enc_create(req, xdr, args);
}
/*
* Encode GETATTR request
*/
-static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args)
+static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_getattr_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a CLOSE request
*/
-static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
+static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_closeargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_close(&xdr, args, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_close(xdr, args, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode an OPEN request
*/
-static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
+static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_openargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_savefh(&xdr, &hdr);
- encode_open(&xdr, args, &hdr);
- encode_getfh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
- encode_restorefh(&xdr, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_savefh(xdr, &hdr);
+ encode_open(xdr, args, &hdr);
+ encode_getfh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
+ encode_restorefh(xdr, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode an OPEN_CONFIRM request
*/
-static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_open_confirmargs *args)
+static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_open_confirmargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.nops = 0,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_open_confirm(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_open_confirm(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode an OPEN request with no attributes.
*/
-static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
+static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_openargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_open(&xdr, args, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_open(xdr, args, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode an OPEN_DOWNGRADE request
*/
-static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
+static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_closeargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_open_downgrade(&xdr, args, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_open_downgrade(xdr, args, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a LOCK request
*/
-static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args)
+static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_lock_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_lock(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_lock(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a LOCKT request
*/
-static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args)
+static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_lockt_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_lockt(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_lockt(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a LOCKU request
*/
-static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args)
+static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_locku_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_locku(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_locku(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
-static int nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, __be32 *p, struct nfs_release_lockowner_args *args)
+static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_release_lockowner_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = 0,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_release_lockowner(&xdr, &args->lock_owner, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_release_lockowner(xdr, &args->lock_owner, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a READLINK request
*/
-static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args)
+static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_readlink *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_readlink(&xdr, args, req, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_readlink(xdr, args, req, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->pglen);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a READDIR request
*/
-static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args)
+static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_readdir_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_readdir(&xdr, args, req, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_readdir(xdr, args, req, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->count);
@@ -2227,428 +2194,387 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
__func__, hdr.replen << 2, args->pages,
args->pgbase, args->count);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a READ request
*/
-static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
+static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_readargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_read(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_read(xdr, args, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
args->pages, args->pgbase, args->count);
req->rq_rcv_buf.flags |= XDRBUF_READ;
encode_nops(&hdr);
- return 0;
}
/*
* Encode an SETATTR request
*/
-static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args)
+static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_setattrargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_setattr(&xdr, args, args->server, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_setattr(xdr, args, args->server, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a GETACL request
*/
-static int
-nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
- struct nfs_getaclargs *args)
+static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_getaclargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
uint32_t replen;
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
- encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
+ encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
args->acl_pages, args->acl_pgbase, args->acl_len);
encode_nops(&hdr);
- return 0;
}
/*
* Encode a WRITE request
*/
-static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
+static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_writeargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_write(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_write(xdr, args, &hdr);
req->rq_snd_buf.flags |= XDRBUF_WRITE;
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a COMMIT request
*/
-static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
+static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_writeargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_commit(&xdr, args, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_commit(xdr, args, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* FSINFO request
*/
-static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args)
+static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs4_fsinfo_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_fsinfo(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_fsinfo(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a PATHCONF request
*/
-static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args)
+static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_pathconf_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_getattr_one(xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
&hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a STATFS request
*/
-static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args)
+static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfs4_statfs_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_getattr_two(xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* GETATTR_BITMAP request
*/
-static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
- struct nfs4_server_caps_arg *args)
+static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_server_caps_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fhandle, &hdr);
- encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fhandle, &hdr);
+ encode_getattr_one(xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
FATTR4_WORD0_LINK_SUPPORT|
FATTR4_WORD0_SYMLINK_SUPPORT|
FATTR4_WORD0_ACLSUPPORT, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a RENEW request
*/
-static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
+static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_client *clp)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.nops = 0,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_renew(&xdr, clp, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_renew(xdr, clp, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a SETCLIENTID request
*/
-static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid *sc)
+static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_setclientid *sc)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.nops = 0,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_setclientid(&xdr, sc, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_setclientid(xdr, sc, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a SETCLIENTID_CONFIRM request
*/
-static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg)
+static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_setclientid_res *arg)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.nops = 0,
};
const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_setclientid_confirm(&xdr, arg, &hdr);
- encode_putrootfh(&xdr, &hdr);
- encode_fsinfo(&xdr, lease_bitmap, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_setclientid_confirm(xdr, arg, &hdr);
+ encode_putrootfh(xdr, &hdr);
+ encode_fsinfo(xdr, lease_bitmap, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* DELEGRETURN request
*/
-static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args)
+static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ const struct nfs4_delegreturnargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fhandle, &hdr);
- encode_delegreturn(&xdr, args->stateid, &hdr);
- encode_getfattr(&xdr, args->bitmask, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fhandle, &hdr);
+ encode_delegreturn(xdr, args->stateid, &hdr);
+ encode_getfattr(xdr, args->bitmask, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode FS_LOCATIONS request
*/
-static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args)
+static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_fs_locations_arg *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
uint32_t replen;
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->dir_fh, &hdr);
- encode_lookup(&xdr, args->name, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->dir_fh, &hdr);
+ encode_lookup(xdr, args->name, &hdr);
replen = hdr.replen; /* get the attribute into args->page */
- encode_fs_locations(&xdr, args->bitmask, &hdr);
+ encode_fs_locations(xdr, args->bitmask, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
0, PAGE_SIZE);
encode_nops(&hdr);
- return 0;
}
#if defined(CONFIG_NFS_V4_1)
/*
* EXCHANGE_ID request
*/
-static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p,
- struct nfs41_exchange_id_args *args)
+static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs41_exchange_id_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = args->client->cl_mvops->minor_version,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_exchange_id(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_exchange_id(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a CREATE_SESSION request
*/
-static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p,
- struct nfs41_create_session_args *args)
+static void nfs4_xdr_enc_create_session(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs41_create_session_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = args->client->cl_mvops->minor_version,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_create_session(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_create_session(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a DESTROY_SESSION request
*/
-static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p,
- struct nfs4_session *session)
+static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_session *session)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = session->clp->cl_mvops->minor_version,
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_destroy_session(&xdr, session, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_destroy_session(xdr, session, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a SEQUENCE request
*/
-static int nfs4_xdr_enc_sequence(struct rpc_rqst *req, uint32_t *p,
- struct nfs4_sequence_args *args)
+static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs4_sequence_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a GET_LEASE_TIME request
*/
-static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p,
- struct nfs4_get_lease_time_args *args)
+static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_get_lease_time_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
};
const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->la_seq_args, &hdr);
- encode_putrootfh(&xdr, &hdr);
- encode_fsinfo(&xdr, lease_bitmap, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->la_seq_args, &hdr);
+ encode_putrootfh(xdr, &hdr);
+ encode_fsinfo(xdr, lease_bitmap, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* a RECLAIM_COMPLETE request
*/
-static int nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, uint32_t *p,
- struct nfs41_reclaim_complete_args *args)
+static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs41_reclaim_complete_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args)
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_reclaim_complete(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_reclaim_complete(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
/*
* Encode GETDEVICEINFO request
*/
-static int nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, uint32_t *p,
- struct nfs4_getdeviceinfo_args *args)
+static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_getdeviceinfo_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_getdeviceinfo(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_getdeviceinfo(xdr, args, &hdr);
/* set up reply kvec. Subtract notification bitmap max size (2)
* so that notification bitmap is put in xdr_buf tail */
@@ -2657,27 +2583,24 @@ static int nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, uint32_t *p,
args->pdev->pglen);
encode_nops(&hdr);
- return 0;
}
/*
* Encode LAYOUTGET request
*/
-static int nfs4_xdr_enc_layoutget(struct rpc_rqst *req, uint32_t *p,
- struct nfs4_layoutget_args *args)
+static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_layoutget_args *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, NFS_FH(args->inode), &hdr);
- encode_layoutget(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, NFS_FH(args->inode), &hdr);
+ encode_layoutget(xdr, args, &hdr);
encode_nops(&hdr);
- return 0;
}
#endif /* CONFIG_NFS_V4_1 */
@@ -4475,7 +4398,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_
goto out_overflow;
eof = be32_to_cpup(p++);
count = be32_to_cpup(p);
- hdrlen = (u8 *) p - (u8 *) iov->iov_base;
+ hdrlen = (u8 *) xdr->p - (u8 *) iov->iov_base;
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
dprintk("NFS: server cheating in read reply: "
@@ -5000,7 +4923,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr,
goto out_overflow;
len = be32_to_cpup(p);
if (len) {
- int i;
+ uint32_t i;
p = xdr_inline_decode(xdr, 4 * len);
if (unlikely(!p))
@@ -5090,26 +5013,26 @@ out_overflow:
/*
* Decode OPEN_DOWNGRADE response
*/
-static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
+static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs_closeres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_open_downgrade(&xdr, res);
+ status = decode_open_downgrade(xdr, res);
if (status != 0)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5118,26 +5041,25 @@ out:
/*
* Decode ACCESS response
*/
-static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res)
+static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_accessres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status != 0)
goto out;
- status = decode_access(&xdr, res);
+ status = decode_access(xdr, res);
if (status != 0)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5146,26 +5068,28 @@ out:
/*
* Decode LOOKUP response
*/
-static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
+static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_lookup_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_lookup(&xdr)) != 0)
+ status = decode_lookup(xdr);
+ if (status)
goto out;
- if ((status = decode_getfh(&xdr, res->fh)) != 0)
+ status = decode_getfh(xdr, res->fh);
+ if (status)
goto out;
- status = decode_getfattr(&xdr, res->fattr, res->server
+ status = decode_getfattr(xdr, res->fattr, res->server
,!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5174,23 +5098,25 @@ out:
/*
* Decode LOOKUP_ROOT response
*/
-static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
+static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs4_lookup_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putrootfh(&xdr)) != 0)
+ status = decode_putrootfh(xdr);
+ if (status)
goto out;
- if ((status = decode_getfh(&xdr, res->fh)) == 0)
- status = decode_getfattr(&xdr, res->fattr, res->server,
+ status = decode_getfh(xdr, res->fh);
+ if (status == 0)
+ status = decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5199,24 +5125,25 @@ out:
/*
* Decode REMOVE response
*/
-static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_removeres *res)
+static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_removeres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
+ status = decode_remove(xdr, &res->cinfo);
+ if (status)
goto out;
- decode_getfattr(&xdr, res->dir_attr, res->server,
+ decode_getfattr(xdr, res->dir_attr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5225,34 +5152,38 @@ out:
/*
* Decode RENAME response
*/
-static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs_renameres *res)
+static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_renameres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_savefh(&xdr)) != 0)
+ status = decode_savefh(xdr);
+ if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
+ status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo);
+ if (status)
goto out;
/* Current FH is target directory */
- if (decode_getfattr(&xdr, res->new_fattr, res->server,
+ if (decode_getfattr(xdr, res->new_fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
goto out;
- if ((status = decode_restorefh(&xdr)) != 0)
+ status = decode_restorefh(xdr);
+ if (status)
goto out;
- decode_getfattr(&xdr, res->old_fattr, res->server,
+ decode_getfattr(xdr, res->old_fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5261,37 +5192,41 @@ out:
/*
* Decode LINK response
*/
-static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link_res *res)
+static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_link_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_savefh(&xdr)) != 0)
+ status = decode_savefh(xdr);
+ if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_link(&xdr, &res->cinfo)) != 0)
+ status = decode_link(xdr, &res->cinfo);
+ if (status)
goto out;
/*
* Note order: OP_LINK leaves the directory as the current
* filehandle.
*/
- if (decode_getfattr(&xdr, res->dir_attr, res->server,
+ if (decode_getfattr(xdr, res->dir_attr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
goto out;
- if ((status = decode_restorefh(&xdr)) != 0)
+ status = decode_restorefh(xdr);
+ if (status)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5300,33 +5235,37 @@ out:
/*
* Decode CREATE response
*/
-static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
+static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_create_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_savefh(&xdr)) != 0)
+ status = decode_savefh(xdr);
+ if (status)
goto out;
- if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
+ status = decode_create(xdr, &res->dir_cinfo);
+ if (status)
goto out;
- if ((status = decode_getfh(&xdr, res->fh)) != 0)
+ status = decode_getfh(xdr, res->fh);
+ if (status)
goto out;
- if (decode_getfattr(&xdr, res->fattr, res->server,
+ if (decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
goto out;
- if ((status = decode_restorefh(&xdr)) != 0)
+ status = decode_restorefh(xdr);
+ if (status)
goto out;
- decode_getfattr(&xdr, res->dir_fattr, res->server,
+ decode_getfattr(xdr, res->dir_fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5335,31 +5274,31 @@ out:
/*
* Decode SYMLINK response
*/
-static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
+static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_create_res *res)
{
- return nfs4_xdr_dec_create(rqstp, p, res);
+ return nfs4_xdr_dec_create(rqstp, xdr, res);
}
/*
* Decode GETATTR response
*/
-static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_getattr_res *res)
+static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_getattr_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_getfattr(&xdr, res->fattr, res->server,
+ status = decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5368,46 +5307,40 @@ out:
/*
* Encode an SETACL request
*/
-static int
-nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args)
+static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr,
+ struct nfs_setaclargs *args)
{
- struct xdr_stream xdr;
struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
- int status;
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, req, &hdr);
- encode_sequence(&xdr, &args->seq_args, &hdr);
- encode_putfh(&xdr, args->fh, &hdr);
- status = encode_setacl(&xdr, args, &hdr);
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_setacl(xdr, args, &hdr);
encode_nops(&hdr);
- return status;
}
/*
* Decode SETACL response
*/
static int
-nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
struct nfs_setaclres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_setattr(&xdr);
+ status = decode_setattr(xdr);
out:
return status;
}
@@ -5416,24 +5349,22 @@ out:
* Decode GETACL response
*/
static int
-nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
+nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
struct nfs_getaclres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_getacl(&xdr, rqstp, &res->acl_len);
+ status = decode_getacl(xdr, rqstp, &res->acl_len);
out:
return status;
@@ -5442,23 +5373,22 @@ out:
/*
* Decode CLOSE response
*/
-static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
+static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_closeres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_close(&xdr, res);
+ status = decode_close(xdr, res);
if (status != 0)
goto out;
/*
@@ -5467,7 +5397,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
* an ESTALE error. Shouldn't be a problem,
* though, since fattr->valid will remain unset.
*/
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5476,36 +5406,35 @@ out:
/*
* Decode OPEN response
*/
-static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
+static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_openres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_savefh(&xdr);
+ status = decode_savefh(xdr);
if (status)
goto out;
- status = decode_open(&xdr, res);
+ status = decode_open(xdr, res);
if (status)
goto out;
- if (decode_getfh(&xdr, &res->fh) != 0)
+ if (decode_getfh(xdr, &res->fh) != 0)
goto out;
- if (decode_getfattr(&xdr, res->f_attr, res->server,
+ if (decode_getfattr(xdr, res->f_attr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
goto out;
- if (decode_restorefh(&xdr) != 0)
+ if (decode_restorefh(xdr) != 0)
goto out;
- decode_getfattr(&xdr, res->dir_attr, res->server,
+ decode_getfattr(xdr, res->dir_attr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5514,20 +5443,20 @@ out:
/*
* Decode OPEN_CONFIRM response
*/
-static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res)
+static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs_open_confirmres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_open_confirm(&xdr, res);
+ status = decode_open_confirm(xdr, res);
out:
return status;
}
@@ -5535,26 +5464,26 @@ out:
/*
* Decode OPEN response
*/
-static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
+static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs_openres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_open(&xdr, res);
+ status = decode_open(xdr, res);
if (status)
goto out;
- decode_getfattr(&xdr, res->f_attr, res->server,
+ decode_getfattr(xdr, res->f_attr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5563,26 +5492,26 @@ out:
/*
* Decode SETATTR response
*/
-static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res)
+static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs_setattrres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_setattr(&xdr);
+ status = decode_setattr(xdr);
if (status)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5591,23 +5520,22 @@ out:
/*
* Decode LOCK response
*/
-static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res)
+static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_lock_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_lock(&xdr, res);
+ status = decode_lock(xdr, res);
out:
return status;
}
@@ -5615,23 +5543,22 @@ out:
/*
* Decode LOCKT response
*/
-static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res)
+static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_lockt_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_lockt(&xdr, res);
+ status = decode_lockt(xdr, res);
out:
return status;
}
@@ -5639,61 +5566,58 @@ out:
/*
* Decode LOCKU response
*/
-static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res)
+static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_locku_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_locku(&xdr, res);
+ status = decode_locku(xdr, res);
out:
return status;
}
-static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
+static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr, void *dummy)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_release_lockowner(&xdr);
+ status = decode_release_lockowner(xdr);
return status;
}
/*
* Decode READLINK response
*/
-static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p,
+static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs4_readlink_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_readlink(&xdr, rqstp);
+ status = decode_readlink(xdr, rqstp);
out:
return status;
}
@@ -5701,23 +5625,22 @@ out:
/*
* Decode READDIR response
*/
-static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res)
+static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs4_readdir_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_readdir(&xdr, rqstp, res);
+ status = decode_readdir(xdr, rqstp, res);
out:
return status;
}
@@ -5725,23 +5648,22 @@ out:
/*
* Decode Read response
*/
-static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res)
+static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_readres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_read(&xdr, rqstp, res);
+ status = decode_read(xdr, rqstp, res);
if (!status)
status = res->count;
out:
@@ -5751,26 +5673,25 @@ out:
/*
* Decode WRITE response
*/
-static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
+static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_writeres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_write(&xdr, res);
+ status = decode_write(xdr, res);
if (status)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
if (!status)
status = res->count;
@@ -5781,26 +5702,25 @@ out:
/*
* Decode COMMIT response
*/
-static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
+static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct nfs_writeres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_commit(&xdr, res);
+ status = decode_commit(xdr, res);
if (status)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5809,85 +5729,80 @@ out:
/*
* Decode FSINFO response
*/
-static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
+static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
struct nfs4_fsinfo_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, &res->seq_res, req);
+ status = decode_sequence(xdr, &res->seq_res, req);
if (!status)
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (!status)
- status = decode_fsinfo(&xdr, res->fsinfo);
+ status = decode_fsinfo(xdr, res->fsinfo);
return status;
}
/*
* Decode PATHCONF response
*/
-static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
+static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
struct nfs4_pathconf_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, &res->seq_res, req);
+ status = decode_sequence(xdr, &res->seq_res, req);
if (!status)
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (!status)
- status = decode_pathconf(&xdr, res->pathconf);
+ status = decode_pathconf(xdr, res->pathconf);
return status;
}
/*
* Decode STATFS response
*/
-static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
+static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
struct nfs4_statfs_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, &res->seq_res, req);
+ status = decode_sequence(xdr, &res->seq_res, req);
if (!status)
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (!status)
- status = decode_statfs(&xdr, res->fsstat);
+ status = decode_statfs(xdr, res->fsstat);
return status;
}
/*
* Decode GETATTR_BITMAP response
*/
-static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res)
+static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_server_caps_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, req);
+ status = decode_sequence(xdr, &res->seq_res, req);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- status = decode_server_caps(&xdr, res);
+ status = decode_server_caps(xdr, res);
out:
return status;
}
@@ -5895,79 +5810,77 @@ out:
/*
* Decode RENEW response
*/
-static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
+static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ void *__unused)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_renew(&xdr);
+ status = decode_renew(xdr);
return status;
}
/*
* Decode SETCLIENTID response
*/
-static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
- struct nfs4_setclientid_res *res)
+static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs4_setclientid_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_setclientid(&xdr, res);
+ status = decode_setclientid(xdr, res);
return status;
}
/*
* Decode SETCLIENTID_CONFIRM response
*/
-static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
+static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs_fsinfo *fsinfo)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_setclientid_confirm(&xdr);
+ status = decode_setclientid_confirm(xdr);
if (!status)
- status = decode_putrootfh(&xdr);
+ status = decode_putrootfh(xdr);
if (!status)
- status = decode_fsinfo(&xdr, fsinfo);
+ status = decode_fsinfo(xdr, fsinfo);
return status;
}
/*
* Decode DELEGRETURN response
*/
-static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res)
+static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs4_delegreturnres *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status != 0)
goto out;
- status = decode_delegreturn(&xdr);
+ status = decode_delegreturn(xdr);
if (status != 0)
goto out;
- decode_getfattr(&xdr, res->fattr, res->server,
+ decode_getfattr(xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
return status;
@@ -5976,26 +5889,27 @@ out:
/*
* Decode FS_LOCATIONS response
*/
-static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
+static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
struct nfs4_fs_locations_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, req);
+ status = decode_sequence(xdr, &res->seq_res, req);
if (status)
goto out;
- if ((status = decode_putfh(&xdr)) != 0)
+ status = decode_putfh(xdr);
+ if (status)
goto out;
- if ((status = decode_lookup(&xdr)) != 0)
+ status = decode_lookup(xdr);
+ if (status)
goto out;
- xdr_enter_page(&xdr, PAGE_SIZE);
- status = decode_getfattr(&xdr, &res->fs_locations->fattr,
+ xdr_enter_page(xdr, PAGE_SIZE);
+ status = decode_getfattr(xdr, &res->fs_locations->fattr,
res->fs_locations->server,
!RPC_IS_ASYNC(req->rq_task));
out:
@@ -6006,129 +5920,122 @@ out:
/*
* Decode EXCHANGE_ID response
*/
-static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
void *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_exchange_id(&xdr, res);
+ status = decode_exchange_id(xdr, res);
return status;
}
/*
* Decode CREATE_SESSION response
*/
-static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs41_create_session_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_create_session(&xdr, res);
+ status = decode_create_session(xdr, res);
return status;
}
/*
* Decode DESTROY_SESSION response
*/
-static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p,
- void *dummy)
+static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ void *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_destroy_session(&xdr, dummy);
+ status = decode_destroy_session(xdr, res);
return status;
}
/*
* Decode SEQUENCE response
*/
-static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs4_sequence_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, res, rqstp);
+ status = decode_sequence(xdr, res, rqstp);
return status;
}
/*
* Decode GET_LEASE_TIME response
*/
-static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs4_get_lease_time_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, &res->lr_seq_res, rqstp);
+ status = decode_sequence(xdr, &res->lr_seq_res, rqstp);
if (!status)
- status = decode_putrootfh(&xdr);
+ status = decode_putrootfh(xdr);
if (!status)
- status = decode_fsinfo(&xdr, res->lr_fsinfo);
+ status = decode_fsinfo(xdr, res->lr_fsinfo);
return status;
}
/*
* Decode RECLAIM_COMPLETE response
*/
-static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs41_reclaim_complete_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (!status)
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (!status)
- status = decode_reclaim_complete(&xdr, (void *)NULL);
+ status = decode_reclaim_complete(xdr, (void *)NULL);
return status;
}
/*
* Decode GETDEVINFO response
*/
-static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs4_getdeviceinfo_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status != 0)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status != 0)
goto out;
- status = decode_getdeviceinfo(&xdr, res->pdev);
+ status = decode_getdeviceinfo(xdr, res->pdev);
out:
return status;
}
@@ -6136,31 +6043,44 @@ out:
/*
* Decode LAYOUTGET response
*/
-static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp, uint32_t *p,
+static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
struct nfs4_layoutget_res *res)
{
- struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_compound_hdr(&xdr, &hdr);
+ status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
- status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
if (status)
goto out;
- status = decode_putfh(&xdr);
+ status = decode_putfh(xdr);
if (status)
goto out;
- status = decode_layoutget(&xdr, rqstp, res);
+ status = decode_layoutget(xdr, rqstp, res);
out:
return status;
}
#endif /* CONFIG_NFS_V4_1 */
-__be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
- struct nfs_server *server, int plus)
+/**
+ * nfs4_decode_dirent - Decode a single NFSv4 directory entry stored in
+ * the local page cache.
+ * @xdr: XDR stream where entry resides
+ * @entry: buffer to fill in with entry data
+ * @plus: boolean indicating whether this should be a readdirplus entry
+ *
+ * Returns zero if successful, otherwise a negative errno value is
+ * returned.
+ *
+ * This function is not invoked during READDIR reply decoding, but
+ * rather whenever an application invokes the getdents(2) system call
+ * on a directory already in our cache.
+ */
+int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
+ int plus)
{
uint32_t bitmap[2] = {0};
uint32_t len;
@@ -6172,9 +6092,9 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
if (unlikely(!p))
goto out_overflow;
if (!ntohl(*p++))
- return ERR_PTR(-EAGAIN);
+ return -EAGAIN;
entry->eof = 1;
- return ERR_PTR(-EBADCOOKIE);
+ return -EBADCOOKIE;
}
p = xdr_inline_decode(xdr, 12);
@@ -6203,7 +6123,8 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
if (decode_attr_length(xdr, &len, &p) < 0)
goto out_overflow;
- if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, server, 1) < 0)
+ if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
+ entry->server, 1) < 0)
goto out_overflow;
if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
entry->ino = entry->fattr->fileid;
@@ -6221,11 +6142,11 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
else
entry->eof = 0;
- return p;
+ return 0;
out_overflow:
print_overflow_msg(__func__, xdr);
- return ERR_PTR(-EAGAIN);
+ return -EAGAIN;
}
/*
@@ -6301,8 +6222,8 @@ nfs4_stat_to_errno(int stat)
#define PROC(proc, argtype, restype) \
[NFSPROC4_CLNT_##proc] = { \
.p_proc = NFSPROC4_COMPOUND, \
- .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
- .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
+ .p_encode = (kxdreproc_t)nfs4_xdr_##argtype, \
+ .p_decode = (kxdrdproc_t)nfs4_xdr_##restype, \
.p_arglen = NFS4_##argtype##_sz, \
.p_replen = NFS4_##restype##_sz, \
.p_statidx = NFSPROC4_CLNT_##proc, \
@@ -6310,50 +6231,50 @@ nfs4_stat_to_errno(int stat)
}
struct rpc_procinfo nfs4_procedures[] = {
- PROC(READ, enc_read, dec_read),
- PROC(WRITE, enc_write, dec_write),
- PROC(COMMIT, enc_commit, dec_commit),
- PROC(OPEN, enc_open, dec_open),
- PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm),
- PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr),
- PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade),
- PROC(CLOSE, enc_close, dec_close),
- PROC(SETATTR, enc_setattr, dec_setattr),
- PROC(FSINFO, enc_fsinfo, dec_fsinfo),
- PROC(RENEW, enc_renew, dec_renew),
- PROC(SETCLIENTID, enc_setclientid, dec_setclientid),
- PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
- PROC(LOCK, enc_lock, dec_lock),
- PROC(LOCKT, enc_lockt, dec_lockt),
- PROC(LOCKU, enc_locku, dec_locku),
- PROC(ACCESS, enc_access, dec_access),
- PROC(GETATTR, enc_getattr, dec_getattr),
- PROC(LOOKUP, enc_lookup, dec_lookup),
- PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
- PROC(REMOVE, enc_remove, dec_remove),
- PROC(RENAME, enc_rename, dec_rename),
- PROC(LINK, enc_link, dec_link),
- PROC(SYMLINK, enc_symlink, dec_symlink),
- PROC(CREATE, enc_create, dec_create),
- PROC(PATHCONF, enc_pathconf, dec_pathconf),
- PROC(STATFS, enc_statfs, dec_statfs),
- PROC(READLINK, enc_readlink, dec_readlink),
- PROC(READDIR, enc_readdir, dec_readdir),
- PROC(SERVER_CAPS, enc_server_caps, dec_server_caps),
- PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn),
- PROC(GETACL, enc_getacl, dec_getacl),
- PROC(SETACL, enc_setacl, dec_setacl),
- PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
- PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
+ PROC(READ, enc_read, dec_read),
+ PROC(WRITE, enc_write, dec_write),
+ PROC(COMMIT, enc_commit, dec_commit),
+ PROC(OPEN, enc_open, dec_open),
+ PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm),
+ PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr),
+ PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade),
+ PROC(CLOSE, enc_close, dec_close),
+ PROC(SETATTR, enc_setattr, dec_setattr),
+ PROC(FSINFO, enc_fsinfo, dec_fsinfo),
+ PROC(RENEW, enc_renew, dec_renew),
+ PROC(SETCLIENTID, enc_setclientid, dec_setclientid),
+ PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
+ PROC(LOCK, enc_lock, dec_lock),
+ PROC(LOCKT, enc_lockt, dec_lockt),
+ PROC(LOCKU, enc_locku, dec_locku),
+ PROC(ACCESS, enc_access, dec_access),
+ PROC(GETATTR, enc_getattr, dec_getattr),
+ PROC(LOOKUP, enc_lookup, dec_lookup),
+ PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
+ PROC(REMOVE, enc_remove, dec_remove),
+ PROC(RENAME, enc_rename, dec_rename),
+ PROC(LINK, enc_link, dec_link),
+ PROC(SYMLINK, enc_symlink, dec_symlink),
+ PROC(CREATE, enc_create, dec_create),
+ PROC(PATHCONF, enc_pathconf, dec_pathconf),
+ PROC(STATFS, enc_statfs, dec_statfs),
+ PROC(READLINK, enc_readlink, dec_readlink),
+ PROC(READDIR, enc_readdir, dec_readdir),
+ PROC(SERVER_CAPS, enc_server_caps, dec_server_caps),
+ PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn),
+ PROC(GETACL, enc_getacl, dec_getacl),
+ PROC(SETACL, enc_setacl, dec_setacl),
+ PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
+ PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
#if defined(CONFIG_NFS_V4_1)
- PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
- PROC(CREATE_SESSION, enc_create_session, dec_create_session),
- PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
- PROC(SEQUENCE, enc_sequence, dec_sequence),
- PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
- PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete),
- PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
- PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
+ PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
+ PROC(CREATE_SESSION, enc_create_session, dec_create_session),
+ PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
+ PROC(SEQUENCE, enc_sequence, dec_sequence),
+ PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
+ PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete),
+ PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
+ PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
#endif /* CONFIG_NFS_V4_1 */
};
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 137b549e63db..e1164e3f9e69 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -26,12 +26,9 @@ static struct kmem_cache *nfs_page_cachep;
static inline struct nfs_page *
nfs_page_alloc(void)
{
- struct nfs_page *p;
- p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL);
- if (p) {
- memset(p, 0, sizeof(*p));
+ struct nfs_page *p = kmem_cache_zalloc(nfs_page_cachep, GFP_KERNEL);
+ if (p)
INIT_LIST_HEAD(&p->wb_list);
- }
return p;
}
@@ -115,7 +112,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
{
if (!nfs_lock_request_dontget(req))
return 0;
- if (req->wb_page != NULL)
+ if (test_bit(PG_MAPPED, &req->wb_flags))
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;
}
@@ -125,7 +122,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
*/
void nfs_clear_page_tag_locked(struct nfs_page *req)
{
- if (req->wb_page != NULL) {
+ if (test_bit(PG_MAPPED, &req->wb_flags)) {
struct inode *inode = req->wb_context->path.dentry->d_inode;
struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 58e7f84fc1fd..77d5e21c4ad6 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -458,7 +458,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
fattr = nfs_alloc_fattr();
status = -ENOMEM;
if (fh == NULL || fattr == NULL)
- goto out;
+ goto out_free;
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir);
@@ -471,6 +471,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
if (status == 0)
status = nfs_instantiate(dentry, fh, fattr);
+out_free:
nfs_free_fattr(fattr);
nfs_free_fhandle(fh);
out:
@@ -731,7 +732,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
.statfs = nfs_proc_statfs,
.fsinfo = nfs_proc_fsinfo,
.pathconf = nfs_proc_pathconf,
- .decode_dirent = nfs_decode_dirent,
+ .decode_dirent = nfs2_decode_dirent,
.read_setup = nfs_proc_read_setup,
.read_done = nfs_read_done,
.write_setup = nfs_proc_write_setup,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index e4b62c6f5a6e..aedcaa7f291f 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req)
(long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
req->wb_bytes,
(long long)req_offset(req));
- nfs_clear_request(req);
nfs_release_request(req);
}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 3c045044fca2..0f9ea73e7789 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -598,7 +598,9 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
if (nfss->mountd_version || showdefaults)
seq_printf(m, ",mountvers=%u", nfss->mountd_version);
- if (nfss->mountd_port || showdefaults)
+ if ((nfss->mountd_port &&
+ nfss->mountd_port != (unsigned short)NFS_UNSPEC_PORT) ||
+ showdefaults)
seq_printf(m, ",mountport=%u", nfss->mountd_port);
nfs_show_mountd_netid(m, nfss, showdefaults);
@@ -1069,12 +1071,10 @@ static int nfs_parse_mount_options(char *raw,
mnt->flags |= NFS_MOUNT_VER3;
mnt->version = 3;
break;
-#ifdef CONFIG_NFS_V4
case Opt_v4:
mnt->flags &= ~NFS_MOUNT_VER3;
mnt->version = 4;
break;
-#endif
case Opt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1286,12 +1286,10 @@ static int nfs_parse_mount_options(char *raw,
mnt->flags |= NFS_MOUNT_VER3;
mnt->version = 3;
break;
-#ifdef CONFIG_NFS_V4
case NFS4_VERSION:
mnt->flags &= ~NFS_MOUNT_VER3;
mnt->version = 4;
break;
-#endif
default:
goto out_invalid_value;
}
@@ -2498,7 +2496,13 @@ static void nfs4_clone_super(struct super_block *sb,
sb->s_maxbytes = old_sb->s_maxbytes;
sb->s_time_gran = 1;
sb->s_op = old_sb->s_op;
- nfs_initialise_sb(sb);
+ /*
+ * The VFS shouldn't apply the umask to mode bits. We will do
+ * so ourselves when necessary.
+ */
+ sb->s_flags |= MS_POSIXACL;
+ sb->s_xattr = old_sb->s_xattr;
+ nfs_initialise_sb(sb);
}
/*
@@ -2508,6 +2512,12 @@ static void nfs4_fill_super(struct super_block *sb)
{
sb->s_time_gran = 1;
sb->s_op = &nfs4_sops;
+ /*
+ * The VFS shouldn't apply the umask to mode bits. We will do
+ * so ourselves when necessary.
+ */
+ sb->s_flags |= MS_POSIXACL;
+ sb->s_xattr = nfs4_xattr_handlers;
nfs_initialise_sb(sb);
}
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 7bdec8531400..e313a51acdd1 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -429,7 +429,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return ERR_PTR(-ENOMEM);
- task_setup_data.callback_data = data,
+ task_setup_data.callback_data = data;
data->cred = rpc_lookup_cred();
if (IS_ERR(data->cred)) {
@@ -496,7 +496,7 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
- atomic_read(&dentry->d_count));
+ dentry->d_count);
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
/*
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 4c14c17a5276..10d648ea128b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
if (nfs_have_delegation(inode, FMODE_WRITE))
nfsi->change_attr++;
}
+ set_bit(PG_MAPPED, &req->wb_flags);
SetPagePrivate(req->wb_page);
set_page_private(req->wb_page, (unsigned long)req);
nfsi->npages++;
@@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
spin_lock(&inode->i_lock);
set_page_private(req->wb_page, 0);
ClearPagePrivate(req->wb_page);
+ clear_bit(PG_MAPPED, &req->wb_flags);
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
nfsi->npages--;
if (!nfsi->npages) {
@@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
iput(inode);
} else
spin_unlock(&inode->i_lock);
- nfs_clear_request(req);
nfs_release_request(req);
}
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 5b7e3021e06b..2247fc91d5e9 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -151,10 +151,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
__be32 nfserr;
u32 max_blocksize = svc_max_payload(rqstp);
- dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
+ dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n",
SVCFH_fmt(&argp->fh),
(unsigned long) argp->count,
- (unsigned long) argp->offset);
+ (unsigned long long) argp->offset);
/* Obtain buffer pointer for payload.
* 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)
@@ -191,10 +191,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
__be32 nfserr;
unsigned long cnt = argp->len;
- dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n",
+ dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n",
SVCFH_fmt(&argp->fh),
argp->len,
- (unsigned long) argp->offset,
+ (unsigned long long) argp->offset,
argp->stable? " stable" : "");
fh_copy(&resp->fh, &argp->fh);
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 2a533a0af2a9..7e84a852cdae 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp)
err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
&fhp->fh_post_attr);
fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
- if (err)
+ if (err) {
fhp->fh_post_saved = 0;
- else
+ /* Grab the ctime anyway - set_change_info might use it */
+ fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime;
+ } else
fhp->fh_post_saved = 1;
}
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 143da2eecd7b..020d443f0bca 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -50,11 +50,6 @@ enum {
NFSPROC4_CLNT_CB_SEQUENCE,
};
-enum nfs_cb_opnum4 {
- OP_CB_RECALL = 4,
- OP_CB_SEQUENCE = 11,
-};
-
#define NFS4_MAXTAGLEN 20
#define NFS4_enc_cb_null_sz 0
@@ -79,61 +74,6 @@ enum nfs_cb_opnum4 {
cb_sequence_dec_sz + \
op_dec_sz)
-/*
-* Generic encode routines from fs/nfs/nfs4xdr.c
-*/
-static inline __be32 *
-xdr_writemem(__be32 *p, const void *ptr, int nbytes)
-{
- int tmp = XDR_QUADLEN(nbytes);
- if (!tmp)
- return p;
- p[tmp-1] = 0;
- memcpy(p, ptr, nbytes);
- return p + tmp;
-}
-
-#define WRITE32(n) *p++ = htonl(n)
-#define WRITEMEM(ptr,nbytes) do { \
- p = xdr_writemem(p, ptr, nbytes); \
-} while (0)
-#define RESERVE_SPACE(nbytes) do { \
- p = xdr_reserve_space(xdr, nbytes); \
- if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \
- BUG_ON(!p); \
-} while (0)
-
-/*
- * Generic decode routines from fs/nfs/nfs4xdr.c
- */
-#define DECODE_TAIL \
- status = 0; \
-out: \
- return status; \
-xdr_error: \
- dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \
- status = -EIO; \
- goto out
-
-#define READ32(x) (x) = ntohl(*p++)
-#define READ64(x) do { \
- (x) = (u64)ntohl(*p++) << 32; \
- (x) |= ntohl(*p++); \
-} while (0)
-#define READTIME(x) do { \
- p++; \
- (x.tv_sec) = ntohl(*p++); \
- (x.tv_nsec) = ntohl(*p++); \
-} while (0)
-#define READ_BUF(nbytes) do { \
- p = xdr_inline_decode(xdr, nbytes); \
- if (!p) { \
- dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
- __func__, __LINE__); \
- return -EIO; \
- } \
-} while (0)
-
struct nfs4_cb_compound_hdr {
/* args */
u32 ident; /* minorversion 0 only */
@@ -144,295 +84,513 @@ struct nfs4_cb_compound_hdr {
int status;
};
-static struct {
-int stat;
-int errno;
-} nfs_cb_errtbl[] = {
- { NFS4_OK, 0 },
- { NFS4ERR_PERM, EPERM },
- { NFS4ERR_NOENT, ENOENT },
- { NFS4ERR_IO, EIO },
- { NFS4ERR_NXIO, ENXIO },
- { NFS4ERR_ACCESS, EACCES },
- { NFS4ERR_EXIST, EEXIST },
- { NFS4ERR_XDEV, EXDEV },
- { NFS4ERR_NOTDIR, ENOTDIR },
- { NFS4ERR_ISDIR, EISDIR },
- { NFS4ERR_INVAL, EINVAL },
- { NFS4ERR_FBIG, EFBIG },
- { NFS4ERR_NOSPC, ENOSPC },
- { NFS4ERR_ROFS, EROFS },
- { NFS4ERR_MLINK, EMLINK },
- { NFS4ERR_NAMETOOLONG, ENAMETOOLONG },
- { NFS4ERR_NOTEMPTY, ENOTEMPTY },
- { NFS4ERR_DQUOT, EDQUOT },
- { NFS4ERR_STALE, ESTALE },
- { NFS4ERR_BADHANDLE, EBADHANDLE },
- { NFS4ERR_BAD_COOKIE, EBADCOOKIE },
- { NFS4ERR_NOTSUPP, ENOTSUPP },
- { NFS4ERR_TOOSMALL, ETOOSMALL },
- { NFS4ERR_SERVERFAULT, ESERVERFAULT },
- { NFS4ERR_BADTYPE, EBADTYPE },
- { NFS4ERR_LOCKED, EAGAIN },
- { NFS4ERR_RESOURCE, EREMOTEIO },
- { NFS4ERR_SYMLINK, ELOOP },
- { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP },
- { NFS4ERR_DEADLOCK, EDEADLK },
- { -1, EIO }
-};
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+{
+ dprintk("NFS: %s prematurely hit the end of our receive buffer. "
+ "Remaining buffer length is %tu words.\n",
+ func, xdr->end - xdr->p);
+}
-static int
-nfs_cb_stat_to_errno(int stat)
+static __be32 *xdr_encode_empty_array(__be32 *p)
{
- int i;
- for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
- if (nfs_cb_errtbl[i].stat == stat)
- return nfs_cb_errtbl[i].errno;
- }
- /* If we cannot translate the error, the recovery routines should
- * handle it.
- * Note: remaining NFSv4 error codes have values > 10000, so should
- * not conflict with native Linux error codes.
- */
- return stat;
+ *p++ = xdr_zero;
+ return p;
}
/*
- * XDR encode
+ * Encode/decode NFSv4 CB basic data types
+ *
+ * Basic NFSv4 callback data types are defined in section 15 of RFC
+ * 3530: "Network File System (NFS) version 4 Protocol" and section
+ * 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version
+ * 1 Protocol"
+ */
+
+/*
+ * nfs_cb_opnum4
+ *
+ * enum nfs_cb_opnum4 {
+ * OP_CB_GETATTR = 3,
+ * ...
+ * };
*/
+enum nfs_cb_opnum4 {
+ OP_CB_GETATTR = 3,
+ OP_CB_RECALL = 4,
+ OP_CB_LAYOUTRECALL = 5,
+ OP_CB_NOTIFY = 6,
+ OP_CB_PUSH_DELEG = 7,
+ OP_CB_RECALL_ANY = 8,
+ OP_CB_RECALLABLE_OBJ_AVAIL = 9,
+ OP_CB_RECALL_SLOT = 10,
+ OP_CB_SEQUENCE = 11,
+ OP_CB_WANTS_CANCELLED = 12,
+ OP_CB_NOTIFY_LOCK = 13,
+ OP_CB_NOTIFY_DEVICEID = 14,
+ OP_CB_ILLEGAL = 10044
+};
-static void
-encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
+static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op)
{
__be32 *p;
- RESERVE_SPACE(sizeof(stateid_t));
- WRITE32(sid->si_generation);
- WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
+ p = xdr_reserve_space(xdr, 4);
+ *p = cpu_to_be32(op);
}
-static void
-encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
+/*
+ * nfs_fh4
+ *
+ * typedef opaque nfs_fh4<NFS4_FHSIZE>;
+ */
+static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh)
{
- __be32 * p;
+ u32 length = fh->fh_size;
+ __be32 *p;
- RESERVE_SPACE(16);
- WRITE32(0); /* tag length is always 0 */
- WRITE32(hdr->minorversion);
- WRITE32(hdr->ident);
- hdr->nops_p = p;
- WRITE32(hdr->nops);
+ BUG_ON(length > NFS4_FHSIZE);
+ p = xdr_reserve_space(xdr, 4 + length);
+ xdr_encode_opaque(p, &fh->fh_base, length);
}
-static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
+/*
+ * stateid4
+ *
+ * struct stateid4 {
+ * uint32_t seqid;
+ * opaque other[12];
+ * };
+ */
+static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid)
{
- *hdr->nops_p = htonl(hdr->nops);
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE);
+ *p++ = cpu_to_be32(sid->si_generation);
+ xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE);
}
-static void
-encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp,
- struct nfs4_cb_compound_hdr *hdr)
+/*
+ * sessionid4
+ *
+ * typedef opaque sessionid4[NFS4_SESSIONID_SIZE];
+ */
+static void encode_sessionid4(struct xdr_stream *xdr,
+ const struct nfsd4_session *session)
{
__be32 *p;
- int len = dp->dl_fh.fh_size;
-
- RESERVE_SPACE(4);
- WRITE32(OP_CB_RECALL);
- encode_stateid(xdr, &dp->dl_stateid);
- RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2));
- WRITE32(0); /* truncate optimization not implemented */
- WRITE32(len);
- WRITEMEM(&dp->dl_fh.fh_base, len);
- hdr->nops++;
+
+ p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN);
+ xdr_encode_opaque_fixed(p, session->se_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN);
}
-static void
-encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb,
- struct nfs4_cb_compound_hdr *hdr)
-{
- __be32 *p;
- struct nfsd4_session *ses = cb->cb_clp->cl_cb_session;
+/*
+ * nfsstat4
+ */
+static const struct {
+ int stat;
+ int errno;
+} nfs_cb_errtbl[] = {
+ { NFS4_OK, 0 },
+ { NFS4ERR_PERM, -EPERM },
+ { NFS4ERR_NOENT, -ENOENT },
+ { NFS4ERR_IO, -EIO },
+ { NFS4ERR_NXIO, -ENXIO },
+ { NFS4ERR_ACCESS, -EACCES },
+ { NFS4ERR_EXIST, -EEXIST },
+ { NFS4ERR_XDEV, -EXDEV },
+ { NFS4ERR_NOTDIR, -ENOTDIR },
+ { NFS4ERR_ISDIR, -EISDIR },
+ { NFS4ERR_INVAL, -EINVAL },
+ { NFS4ERR_FBIG, -EFBIG },
+ { NFS4ERR_NOSPC, -ENOSPC },
+ { NFS4ERR_ROFS, -EROFS },
+ { NFS4ERR_MLINK, -EMLINK },
+ { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG },
+ { NFS4ERR_NOTEMPTY, -ENOTEMPTY },
+ { NFS4ERR_DQUOT, -EDQUOT },
+ { NFS4ERR_STALE, -ESTALE },
+ { NFS4ERR_BADHANDLE, -EBADHANDLE },
+ { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFS4ERR_NOTSUPP, -ENOTSUPP },
+ { NFS4ERR_TOOSMALL, -ETOOSMALL },
+ { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
+ { NFS4ERR_BADTYPE, -EBADTYPE },
+ { NFS4ERR_LOCKED, -EAGAIN },
+ { NFS4ERR_RESOURCE, -EREMOTEIO },
+ { NFS4ERR_SYMLINK, -ELOOP },
+ { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
+ { NFS4ERR_DEADLOCK, -EDEADLK },
+ { -1, -EIO }
+};
- if (hdr->minorversion == 0)
- return;
+/*
+ * If we cannot translate the error, the recovery routines should
+ * handle it.
+ *
+ * Note: remaining NFSv4 error codes have values > 10000, so should
+ * not conflict with native Linux error codes.
+ */
+static int nfs_cb_stat_to_errno(int status)
+{
+ int i;
- RESERVE_SPACE(1 + NFS4_MAX_SESSIONID_LEN + 20);
+ for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
+ if (nfs_cb_errtbl[i].stat == status)
+ return nfs_cb_errtbl[i].errno;
+ }
- WRITE32(OP_CB_SEQUENCE);
- WRITEMEM(ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN);
- WRITE32(ses->se_cb_seq_nr);
- WRITE32(0); /* slotid, always 0 */
- WRITE32(0); /* highest slotid always 0 */
- WRITE32(0); /* cachethis always 0 */
- WRITE32(0); /* FIXME: support referring_call_lists */
- hdr->nops++;
+ dprintk("NFSD: Unrecognized NFS CB status value: %u\n", status);
+ return -status;
}
-static int
-nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p)
+static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
+ enum nfsstat4 *status)
{
- struct xdr_stream xdrs, *xdr = &xdrs;
+ __be32 *p;
+ u32 op;
- xdr_init_encode(&xdrs, &req->rq_snd_buf, p);
- RESERVE_SPACE(0);
+ p = xdr_inline_decode(xdr, 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ op = be32_to_cpup(p++);
+ if (unlikely(op != expected))
+ goto out_unexpected;
+ *status = be32_to_cpup(p);
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+out_unexpected:
+ dprintk("NFSD: Callback server returned operation %d but "
+ "we issued a request for %d\n", op, expected);
+ return -EIO;
}
-static int
-nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p,
- struct nfsd4_callback *cb)
+/*
+ * CB_COMPOUND4args
+ *
+ * struct CB_COMPOUND4args {
+ * utf8str_cs tag;
+ * uint32_t minorversion;
+ * uint32_t callback_ident;
+ * nfs_cb_argop4 argarray<>;
+ * };
+*/
+static void encode_cb_compound4args(struct xdr_stream *xdr,
+ struct nfs4_cb_compound_hdr *hdr)
{
- struct xdr_stream xdr;
- struct nfs4_delegation *args = cb->cb_op;
- struct nfs4_cb_compound_hdr hdr = {
- .ident = cb->cb_clp->cl_cb_ident,
- .minorversion = cb->cb_minorversion,
- };
+ __be32 * p;
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_cb_compound_hdr(&xdr, &hdr);
- encode_cb_sequence(&xdr, cb, &hdr);
- encode_cb_recall(&xdr, args, &hdr);
- encode_cb_nops(&hdr);
+ p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
+ p = xdr_encode_empty_array(p); /* empty tag */
+ *p++ = cpu_to_be32(hdr->minorversion);
+ *p++ = cpu_to_be32(hdr->ident);
+
+ hdr->nops_p = p;
+ *p = cpu_to_be32(hdr->nops); /* argarray element count */
+}
+
+/*
+ * Update argarray element count
+ */
+static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
+{
+ BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS);
+ *hdr->nops_p = cpu_to_be32(hdr->nops);
+}
+
+/*
+ * CB_COMPOUND4res
+ *
+ * struct CB_COMPOUND4res {
+ * nfsstat4 status;
+ * utf8str_cs tag;
+ * nfs_cb_resop4 resarray<>;
+ * };
+ */
+static int decode_cb_compound4res(struct xdr_stream *xdr,
+ struct nfs4_cb_compound_hdr *hdr)
+{
+ u32 length;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ hdr->status = be32_to_cpup(p++);
+ /* Ignore the tag */
+ length = be32_to_cpup(p++);
+ p = xdr_inline_decode(xdr, length + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ hdr->nops = be32_to_cpup(p);
return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
+/*
+ * CB_RECALL4args
+ *
+ * struct CB_RECALL4args {
+ * stateid4 stateid;
+ * bool truncate;
+ * nfs_fh4 fh;
+ * };
+ */
+static void encode_cb_recall4args(struct xdr_stream *xdr,
+ const struct nfs4_delegation *dp,
+ struct nfs4_cb_compound_hdr *hdr)
+{
+ __be32 *p;
+
+ encode_nfs_cb_opnum4(xdr, OP_CB_RECALL);
+ encode_stateid4(xdr, &dp->dl_stateid);
+
+ p = xdr_reserve_space(xdr, 4);
+ *p++ = xdr_zero; /* truncate */
-static int
-decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
- __be32 *p;
- u32 taglen;
+ encode_nfs_fh4(xdr, &dp->dl_fh);
- READ_BUF(8);
- READ32(hdr->status);
- /* We've got no use for the tag; ignore it: */
- READ32(taglen);
- READ_BUF(taglen + 4);
- p += XDR_QUADLEN(taglen);
- READ32(hdr->nops);
- return 0;
+ hdr->nops++;
}
-static int
-decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
+/*
+ * CB_SEQUENCE4args
+ *
+ * struct CB_SEQUENCE4args {
+ * sessionid4 csa_sessionid;
+ * sequenceid4 csa_sequenceid;
+ * slotid4 csa_slotid;
+ * slotid4 csa_highest_slotid;
+ * bool csa_cachethis;
+ * referring_call_list4 csa_referring_call_lists<>;
+ * };
+ */
+static void encode_cb_sequence4args(struct xdr_stream *xdr,
+ const struct nfsd4_callback *cb,
+ struct nfs4_cb_compound_hdr *hdr)
{
+ struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
__be32 *p;
- u32 op;
- int32_t nfserr;
-
- READ_BUF(8);
- READ32(op);
- if (op != expected) {
- dprintk("NFSD: decode_cb_op_hdr: Callback server returned "
- " operation %d but we issued a request for %d\n",
- op, expected);
- return -EIO;
- }
- READ32(nfserr);
- if (nfserr != NFS_OK)
- return -nfs_cb_stat_to_errno(nfserr);
- return 0;
+
+ if (hdr->minorversion == 0)
+ return;
+
+ encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE);
+ encode_sessionid4(xdr, session);
+
+ p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4);
+ *p++ = cpu_to_be32(session->se_cb_seq_nr); /* csa_sequenceid */
+ *p++ = xdr_zero; /* csa_slotid */
+ *p++ = xdr_zero; /* csa_highest_slotid */
+ *p++ = xdr_zero; /* csa_cachethis */
+ xdr_encode_empty_array(p); /* csa_referring_call_lists */
+
+ hdr->nops++;
}
/*
+ * CB_SEQUENCE4resok
+ *
+ * struct CB_SEQUENCE4resok {
+ * sessionid4 csr_sessionid;
+ * sequenceid4 csr_sequenceid;
+ * slotid4 csr_slotid;
+ * slotid4 csr_highest_slotid;
+ * slotid4 csr_target_highest_slotid;
+ * };
+ *
+ * union CB_SEQUENCE4res switch (nfsstat4 csr_status) {
+ * case NFS4_OK:
+ * CB_SEQUENCE4resok csr_resok4;
+ * default:
+ * void;
+ * };
+ *
* Our current back channel implmentation supports a single backchannel
* with a single slot.
*/
-static int
-decode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb,
- struct rpc_rqst *rqstp)
+static int decode_cb_sequence4resok(struct xdr_stream *xdr,
+ struct nfsd4_callback *cb)
{
- struct nfsd4_session *ses = cb->cb_clp->cl_cb_session;
+ struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
struct nfs4_sessionid id;
int status;
- u32 dummy;
__be32 *p;
+ u32 dummy;
- if (cb->cb_minorversion == 0)
- return 0;
-
- status = decode_cb_op_hdr(xdr, OP_CB_SEQUENCE);
- if (status)
- return status;
+ status = -ESERVERFAULT;
/*
* If the server returns different values for sessionID, slotID or
* sequence number, the server is looney tunes.
*/
- status = -ESERVERFAULT;
-
- READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
+ p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN + 4 + 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
memcpy(id.data, p, NFS4_MAX_SESSIONID_LEN);
- p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN);
- if (memcmp(id.data, ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN)) {
- dprintk("%s Invalid session id\n", __func__);
+ if (memcmp(id.data, session->se_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN) != 0) {
+ dprintk("NFS: %s Invalid session id\n", __func__);
goto out;
}
- READ32(dummy);
- if (dummy != ses->se_cb_seq_nr) {
- dprintk("%s Invalid sequence number\n", __func__);
+ p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN);
+
+ dummy = be32_to_cpup(p++);
+ if (dummy != session->se_cb_seq_nr) {
+ dprintk("NFS: %s Invalid sequence number\n", __func__);
goto out;
}
- READ32(dummy); /* slotid must be 0 */
+
+ dummy = be32_to_cpup(p++);
if (dummy != 0) {
- dprintk("%s Invalid slotid\n", __func__);
+ dprintk("NFS: %s Invalid slotid\n", __func__);
goto out;
}
- /* FIXME: process highest slotid and target highest slotid */
+
+ /*
+ * FIXME: process highest slotid and target highest slotid
+ */
status = 0;
out:
return status;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
}
+static int decode_cb_sequence4res(struct xdr_stream *xdr,
+ struct nfsd4_callback *cb)
+{
+ enum nfsstat4 nfserr;
+ int status;
+
+ if (cb->cb_minorversion == 0)
+ return 0;
+
+ status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &nfserr);
+ if (unlikely(status))
+ goto out;
+ if (unlikely(nfserr != NFS4_OK))
+ goto out_default;
+ status = decode_cb_sequence4resok(xdr, cb);
+out:
+ return status;
+out_default:
+ return nfs_cb_stat_to_errno(status);
+}
-static int
-nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p)
+/*
+ * NFSv4.0 and NFSv4.1 XDR encode functions
+ *
+ * NFSv4.0 callback argument types are defined in section 15 of RFC
+ * 3530: "Network File System (NFS) version 4 Protocol" and section 20
+ * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1
+ * Protocol".
+ */
+
+/*
+ * NB: Without this zero space reservation, callbacks over krb5p fail
+ */
+static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
+ void *__unused)
+{
+ xdr_reserve_space(xdr, 0);
+}
+
+/*
+ * 20.2. Operation 4: CB_RECALL - Recall a Delegation
+ */
+static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct nfsd4_callback *cb)
+{
+ const struct nfs4_delegation *args = cb->cb_op;
+ struct nfs4_cb_compound_hdr hdr = {
+ .ident = cb->cb_clp->cl_cb_ident,
+ .minorversion = cb->cb_minorversion,
+ };
+
+ encode_cb_compound4args(xdr, &hdr);
+ encode_cb_sequence4args(xdr, cb, &hdr);
+ encode_cb_recall4args(xdr, args, &hdr);
+ encode_cb_nops(&hdr);
+}
+
+
+/*
+ * NFSv4.0 and NFSv4.1 XDR decode functions
+ *
+ * NFSv4.0 callback result types are defined in section 15 of RFC
+ * 3530: "Network File System (NFS) version 4 Protocol" and section 20
+ * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1
+ * Protocol".
+ */
+
+static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
+ void *__unused)
{
return 0;
}
-static int
-nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p,
- struct nfsd4_callback *cb)
+/*
+ * 20.2. Operation 4: CB_RECALL - Recall a Delegation
+ */
+static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfsd4_callback *cb)
{
- struct xdr_stream xdr;
struct nfs4_cb_compound_hdr hdr;
+ enum nfsstat4 nfserr;
int status;
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- status = decode_cb_compound_hdr(&xdr, &hdr);
- if (status)
+ status = decode_cb_compound4res(xdr, &hdr);
+ if (unlikely(status))
goto out;
- if (cb) {
- status = decode_cb_sequence(&xdr, cb, rqstp);
- if (status)
+
+ if (cb != NULL) {
+ status = decode_cb_sequence4res(xdr, cb);
+ if (unlikely(status))
goto out;
}
- status = decode_cb_op_hdr(&xdr, OP_CB_RECALL);
+
+ status = decode_cb_op_status(xdr, OP_CB_RECALL, &nfserr);
+ if (unlikely(status))
+ goto out;
+ if (unlikely(nfserr != NFS4_OK))
+ goto out_default;
out:
return status;
+out_default:
+ return nfs_cb_stat_to_errno(status);
}
/*
* RPC procedure tables
*/
-#define PROC(proc, call, argtype, restype) \
-[NFSPROC4_CLNT_##proc] = { \
- .p_proc = NFSPROC4_CB_##call, \
- .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
- .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
- .p_arglen = NFS4_##argtype##_sz, \
- .p_replen = NFS4_##restype##_sz, \
- .p_statidx = NFSPROC4_CB_##call, \
- .p_name = #proc, \
-}
-
-static struct rpc_procinfo nfs4_cb_procedures[] = {
- PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null),
- PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall),
+#define PROC(proc, call, argtype, restype) \
+[NFSPROC4_CLNT_##proc] = { \
+ .p_proc = NFSPROC4_CB_##call, \
+ .p_encode = (kxdreproc_t)nfs4_xdr_enc_##argtype, \
+ .p_decode = (kxdrdproc_t)nfs4_xdr_dec_##restype, \
+ .p_arglen = NFS4_enc_##argtype##_sz, \
+ .p_replen = NFS4_dec_##restype##_sz, \
+ .p_statidx = NFSPROC4_CB_##call, \
+ .p_name = #proc, \
+}
+
+static struct rpc_procinfo nfs4_cb_procedures[] = {
+ PROC(CB_NULL, NULL, cb_null, cb_null),
+ PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall),
};
-static struct rpc_version nfs_cb_version4 = {
+static struct rpc_version nfs_cb_version4 = {
/*
* Note on the callback rpc program version number: despite language in rfc
* 5661 section 18.36.3 requiring servers to use 4 in this field, the
@@ -440,29 +598,29 @@ static struct rpc_version nfs_cb_version4 = {
* in practice that appears to be what implementations use. The section
* 18.36.3 language is expected to be fixed in an erratum.
*/
- .number = 1,
- .nrprocs = ARRAY_SIZE(nfs4_cb_procedures),
- .procs = nfs4_cb_procedures
+ .number = 1,
+ .nrprocs = ARRAY_SIZE(nfs4_cb_procedures),
+ .procs = nfs4_cb_procedures
};
-static struct rpc_version * nfs_cb_version[] = {
+static struct rpc_version *nfs_cb_version[] = {
&nfs_cb_version4,
};
static struct rpc_program cb_program;
static struct rpc_stat cb_stats = {
- .program = &cb_program
+ .program = &cb_program
};
#define NFS4_CALLBACK 0x40000000
static struct rpc_program cb_program = {
- .name = "nfs4_cb",
- .number = NFS4_CALLBACK,
- .nrvers = ARRAY_SIZE(nfs_cb_version),
- .version = nfs_cb_version,
- .stats = &cb_stats,
- .pipe_dir_name = "/nfsd4_cb",
+ .name = "nfs4_cb",
+ .number = NFS4_CALLBACK,
+ .nrvers = ARRAY_SIZE(nfs_cb_version),
+ .version = nfs_cb_version,
+ .stats = &cb_stats,
+ .pipe_dir_name = "/nfsd4_cb",
};
static int max_cb_time(void)
@@ -473,7 +631,8 @@ static int max_cb_time(void)
/* Reference counting, callback cleanup, etc., all look racy as heck.
* And why is cl_cb_set an atomic? */
-int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
+static int setup_callback_client(struct nfs4_client *clp,
+ struct nfs4_cb_conn *conn)
{
struct rpc_timeout timeparms = {
.to_initval = max_cb_time(),
@@ -748,13 +907,13 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp)
flush_workqueue(callback_wq);
}
-void nfsd4_release_cb(struct nfsd4_callback *cb)
+static void nfsd4_release_cb(struct nfsd4_callback *cb)
{
if (cb->cb_ops->rpc_release)
cb->cb_ops->rpc_release(cb);
}
-void nfsd4_process_cb_update(struct nfsd4_callback *cb)
+static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
{
struct nfs4_cb_conn conn;
struct nfs4_client *clp = cb->cb_clp;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0cdfd022bb7b..fd6694b49e1c 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -604,9 +604,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}
-static __be32
-nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- void *arg)
+static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
{
struct svc_fh tmp_fh;
__be32 ret;
@@ -615,13 +613,19 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
ret = exp_pseudoroot(rqstp, &tmp_fh);
if (ret)
return ret;
- if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) {
+ if (tmp_fh.fh_dentry == fh->fh_dentry) {
fh_put(&tmp_fh);
return nfserr_noent;
}
fh_put(&tmp_fh);
- return nfsd_lookup(rqstp, &cstate->current_fh,
- "..", 2, &cstate->current_fh);
+ return nfsd_lookup(rqstp, fh, "..", 2, fh);
+}
+
+static __be32
+nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ void *arg)
+{
+ return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
}
static __be32
@@ -769,10 +773,36 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
} else
secinfo->si_exp = exp;
dput(dentry);
+ if (cstate->minorversion)
+ /* See rfc 5661 section 2.6.3.1.1.8 */
+ fh_put(&cstate->current_fh);
return err;
}
static __be32
+nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_secinfo_no_name *sin)
+{
+ __be32 err;
+
+ switch (sin->sin_style) {
+ case NFS4_SECINFO_STYLE4_CURRENT_FH:
+ break;
+ case NFS4_SECINFO_STYLE4_PARENT:
+ err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
+ if (err)
+ return err;
+ break;
+ default:
+ return nfserr_inval;
+ }
+ exp_get(cstate->current_fh.fh_export);
+ sin->sin_exp = cstate->current_fh.fh_export;
+ fh_put(&cstate->current_fh);
+ return nfs_ok;
+}
+
+static __be32
nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_setattr *setattr)
{
@@ -1126,10 +1156,6 @@ encode_op:
nfsd4_increment_op_stats(op->opnum);
}
- if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
- dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
- status = nfserr_jukebox;
- }
resp->cstate.status = status;
fh_put(&resp->cstate.current_fh);
@@ -1320,6 +1346,10 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_flags = ALLOWED_WITHOUT_FH,
.op_name = "OP_RECLAIM_COMPLETE",
},
+ [OP_SECINFO_NO_NAME] = {
+ .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
+ .op_name = "OP_SECINFO_NO_NAME",
+ },
};
static const char *nfsd4_op_name(unsigned opnum)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 7e26caab2a26..ffb59ef6f82f 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -302,7 +302,6 @@ purge_old(struct dentry *parent, struct dentry *child)
{
int status;
- /* note: we currently use this path only for minorversion 0 */
if (nfs4_has_reclaimed_state(child->d_name.name, false))
return 0;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 116cab970e0f..b82e36862044 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -749,6 +749,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
*/
slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
+ if (numslots < 1)
+ return NULL;
new = alloc_session(slotsize, numslots);
if (!new) {
@@ -1132,45 +1134,30 @@ find_unconfirmed_client(clientid_t *clid)
return NULL;
}
-/*
- * Return 1 iff clp's clientid establishment method matches the use_exchange_id
- * parameter. Matching is based on the fact the at least one of the
- * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1
- *
- * FIXME: we need to unify the clientid namespaces for nfsv4.x
- * and correctly deal with client upgrade/downgrade in EXCHANGE_ID
- * and SET_CLIENTID{,_CONFIRM}
- */
-static inline int
-match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id)
+static bool clp_used_exchangeid(struct nfs4_client *clp)
{
- bool has_exchange_flags = (clp->cl_exchange_flags != 0);
- return use_exchange_id == has_exchange_flags;
-}
+ return clp->cl_exchange_flags != 0;
+}
static struct nfs4_client *
-find_confirmed_client_by_str(const char *dname, unsigned int hashval,
- bool use_exchange_id)
+find_confirmed_client_by_str(const char *dname, unsigned int hashval)
{
struct nfs4_client *clp;
list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
- if (same_name(clp->cl_recdir, dname) &&
- match_clientid_establishment(clp, use_exchange_id))
+ if (same_name(clp->cl_recdir, dname))
return clp;
}
return NULL;
}
static struct nfs4_client *
-find_unconfirmed_client_by_str(const char *dname, unsigned int hashval,
- bool use_exchange_id)
+find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
{
struct nfs4_client *clp;
list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
- if (same_name(clp->cl_recdir, dname) &&
- match_clientid_establishment(clp, use_exchange_id))
+ if (same_name(clp->cl_recdir, dname))
return clp;
}
return NULL;
@@ -1344,7 +1331,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
case SP4_NONE:
break;
case SP4_SSV:
- return nfserr_encr_alg_unsupp;
+ return nfserr_serverfault;
default:
BUG(); /* checked by xdr code */
case SP4_MACH_CRED:
@@ -1361,8 +1348,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
nfs4_lock_state();
status = nfs_ok;
- conf = find_confirmed_client_by_str(dname, strhashval, true);
+ conf = find_confirmed_client_by_str(dname, strhashval);
if (conf) {
+ if (!clp_used_exchangeid(conf)) {
+ status = nfserr_clid_inuse; /* XXX: ? */
+ goto out;
+ }
if (!same_verf(&verf, &conf->cl_verifier)) {
/* 18.35.4 case 8 */
if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
@@ -1403,7 +1394,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
goto out;
}
- unconf = find_unconfirmed_client_by_str(dname, strhashval, true);
+ unconf = find_unconfirmed_client_by_str(dname, strhashval);
if (unconf) {
/*
* Possible retry or client restart. Per 18.35.4 case 4,
@@ -1560,6 +1551,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
status = nfs_ok;
memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
NFS4_MAX_SESSIONID_LEN);
+ memcpy(&cr_ses->fore_channel, &new->se_fchannel,
+ sizeof(struct nfsd4_channel_attrs));
cs_slot->sl_seqid++;
cr_ses->seqid = cs_slot->sl_seqid;
@@ -1801,10 +1794,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
strhashval = clientstr_hashval(dname);
nfs4_lock_state();
- conf = find_confirmed_client_by_str(dname, strhashval, false);
+ conf = find_confirmed_client_by_str(dname, strhashval);
if (conf) {
/* RFC 3530 14.2.33 CASE 0: */
status = nfserr_clid_inuse;
+ if (clp_used_exchangeid(conf))
+ goto out;
if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
char addr_str[INET6_ADDRSTRLEN];
rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
@@ -1819,7 +1814,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
* has a description of SETCLIENTID request processing consisting
* of 5 bullet points, labeled as CASE0 - CASE4 below.
*/
- unconf = find_unconfirmed_client_by_str(dname, strhashval, false);
+ unconf = find_unconfirmed_client_by_str(dname, strhashval);
status = nfserr_resource;
if (!conf) {
/*
@@ -1964,7 +1959,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
unsigned int hash =
clientstr_hashval(unconf->cl_recdir);
conf = find_confirmed_client_by_str(unconf->cl_recdir,
- hash, false);
+ hash);
if (conf) {
nfsd4_remove_clid_dir(conf);
expire_client(conf);
@@ -2514,8 +2509,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
if (!fp->fi_fds[oflag]) {
status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
&fp->fi_fds[oflag]);
- if (status == nfserr_dropit)
- status = nfserr_jukebox;
if (status)
return status;
}
@@ -3081,9 +3074,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
if (status)
goto out;
renew_client(dp->dl_client);
- if (filpp)
+ if (filpp) {
*filpp = find_readable_file(dp->dl_file);
- BUG_ON(!*filpp);
+ BUG_ON(!*filpp);
+ }
} else { /* open or lock stateid */
stp = find_stateid(stateid, flags);
if (!stp)
@@ -4107,7 +4101,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
unsigned int strhashval = clientstr_hashval(name);
struct nfs4_client *clp;
- clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id);
+ clp = find_confirmed_client_by_str(name, strhashval);
return clp ? 1 : 0;
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index f35a94a04026..364aae7d5998 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -847,6 +847,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
}
static __be32
+nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
+ struct nfsd4_secinfo_no_name *sin)
+{
+ DECODE_HEAD;
+
+ READ_BUF(4);
+ READ32(sin->sin_style);
+ DECODE_TAIL;
+}
+
+static __be32
nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
{
__be32 status;
@@ -1005,7 +1016,7 @@ static __be32
nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
struct nfsd4_exchange_id *exid)
{
- int dummy;
+ int dummy, tmp;
DECODE_HEAD;
READ_BUF(NFS4_VERIFIER_SIZE);
@@ -1053,15 +1064,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
/* ssp_hash_algs<> */
READ_BUF(4);
- READ32(dummy);
- READ_BUF(dummy);
- p += XDR_QUADLEN(dummy);
+ READ32(tmp);
+ while (tmp--) {
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+ }
/* ssp_encr_algs<> */
READ_BUF(4);
- READ32(dummy);
- READ_BUF(dummy);
- p += XDR_QUADLEN(dummy);
+ READ32(tmp);
+ while (tmp--) {
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+ }
/* ssp_window and ssp_num_gss_handles */
READ_BUF(8);
@@ -1350,7 +1369,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
[OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
- [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
[OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
[OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -2309,8 +2328,6 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
case nfserr_resource:
nfserr = nfserr_toosmall;
goto fail;
- case nfserr_dropit:
- goto fail;
case nfserr_noent:
goto skip_entry;
default:
@@ -2826,11 +2843,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
}
static __be32
-nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
- struct nfsd4_secinfo *secinfo)
+nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
+ __be32 nfserr,struct svc_export *exp)
{
int i = 0;
- struct svc_export *exp = secinfo->si_exp;
u32 nflavs;
struct exp_flavor_info *flavs;
struct exp_flavor_info def_flavs[2];
@@ -2892,6 +2908,20 @@ out:
return nfserr;
}
+static __be32
+nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
+ struct nfsd4_secinfo *secinfo)
+{
+ return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
+}
+
+static __be32
+nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
+ struct nfsd4_secinfo_no_name *secinfo)
+{
+ return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
+}
+
/*
* The SETATTR encode routine is special -- it always encodes a bitmap,
* regardless of the error status.
@@ -3154,7 +3184,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
[OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
[OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
[OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
- [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
[OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
[OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
[OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 4514ebbee4d6..6840ec3ceecf 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -127,6 +127,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
{
+#ifdef CONFIG_NFSD_DEPRECATED
static int warned;
if (file->f_dentry->d_name.name[0] == '.' && !warned) {
printk(KERN_INFO
@@ -135,6 +136,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size
current->comm, file->f_dentry->d_name.name);
warned = 1;
}
+#endif
if (! file->private_data) {
/* An attempt to read a transaction file without writing
* causes a 0-byte write so that the file can return
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 08e17264784b..fd608a27a8d5 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -735,8 +735,9 @@ nfserrno (int errno)
{ nfserr_stale, -ESTALE },
{ nfserr_jukebox, -ETIMEDOUT },
{ nfserr_jukebox, -ERESTARTSYS },
- { nfserr_dropit, -EAGAIN },
- { nfserr_dropit, -ENOMEM },
+ { nfserr_jukebox, -EAGAIN },
+ { nfserr_jukebox, -EWOULDBLOCK },
+ { nfserr_jukebox, -ENOMEM },
{ nfserr_badname, -ESRCH },
{ nfserr_io, -ETXTBSY },
{ nfserr_notsupp, -EOPNOTSUPP },
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 2bae1d86f5f2..18743c4d8bca 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -608,7 +608,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
/* Now call the procedure handler, and encode NFS status. */
nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
nfserr = map_new_errors(rqstp->rq_vers, nfserr);
- if (nfserr == nfserr_dropit) {
+ if (nfserr == nfserr_dropit || rqstp->rq_dropme) {
dprintk("nfsd: Dropping request; may be revisited later\n");
nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
return 0;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 184938fcff04..bfbc575f0e6f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -380,8 +380,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
* we need to break all leases.
*/
host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
- if (host_err == -EWOULDBLOCK)
- host_err = -ETIMEDOUT;
if (host_err) /* ENOMEM or EWOULDBLOCK */
goto out_nfserr;
@@ -752,8 +750,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
*/
if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
- if (host_err == -EWOULDBLOCK)
- host_err = -ETIMEDOUT;
if (host_err) /* NOMEM or WOULDBLOCK */
goto out_nfserr;
@@ -845,11 +841,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
struct page *page = buf->page;
size_t size;
- int ret;
-
- ret = buf->ops->confirm(pipe, buf);
- if (unlikely(ret))
- return ret;
size = sd->len;
@@ -1756,8 +1747,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
goto out_dput_new;
if (svc_msnfs(ffhp) &&
- ((atomic_read(&odentry->d_count) > 1)
- || (atomic_read(&ndentry->d_count) > 1))) {
+ ((odentry->d_count > 1) || (ndentry->d_count > 1))) {
host_err = -EPERM;
goto out_dput_new;
}
@@ -1843,7 +1833,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (type != S_IFDIR) { /* It's UNLINK */
#ifdef MSNFS
if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (atomic_read(&rdentry->d_count) > 1)) {
+ (rdentry->d_count > 1)) {
host_err = -EPERM;
} else
#endif
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 4d476ff08ae6..799c30c3b495 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -311,6 +311,11 @@ struct nfsd4_secinfo {
struct svc_export *si_exp; /* response */
};
+struct nfsd4_secinfo_no_name {
+ u32 sin_style; /* request */
+ struct svc_export *sin_exp; /* response */
+};
+
struct nfsd4_setattr {
stateid_t sa_stateid; /* request */
u32 sa_bmval[3]; /* request */
@@ -484,18 +489,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
static inline void
set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
{
- BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
- cinfo->atomic = 1;
+ BUG_ON(!fhp->fh_pre_saved);
+ cinfo->atomic = fhp->fh_post_saved;
cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
- if (cinfo->change_supported) {
- cinfo->before_change = fhp->fh_pre_change;
- cinfo->after_change = fhp->fh_post_change;
- } else {
- cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
- cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
- cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
- cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
- }
+
+ cinfo->before_change = fhp->fh_pre_change;
+ cinfo->after_change = fhp->fh_post_change;
+ cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+ cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+ cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+ cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
}
int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 8b782b062baa..3ee67c67cc52 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -35,7 +35,20 @@
struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
{
- return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
+ return NILFS_I_NILFS(bmap->b_inode)->ns_dat;
+}
+
+static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap,
+ const char *fname, int err)
+{
+ struct inode *inode = bmap->b_inode;
+
+ if (err == -EINVAL) {
+ nilfs_error(inode->i_sb, fname,
+ "broken bmap (inode number=%lu)\n", inode->i_ino);
+ err = -EIO;
+ }
+ return err;
}
/**
@@ -66,8 +79,10 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
down_read(&bmap->b_sem);
ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
- if (ret < 0)
+ if (ret < 0) {
+ ret = nilfs_bmap_convert_error(bmap, __func__, ret);
goto out;
+ }
if (NILFS_BMAP_USE_VBN(bmap)) {
ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
&blocknr);
@@ -88,7 +103,8 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
down_read(&bmap->b_sem);
ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
up_read(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
@@ -144,7 +160,8 @@ int nilfs_bmap_insert(struct nilfs_bmap *bmap,
down_write(&bmap->b_sem);
ret = nilfs_bmap_do_insert(bmap, key, rec);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
@@ -180,9 +197,12 @@ int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key)
down_read(&bmap->b_sem);
ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
- if (!ret)
- *key = lastkey;
up_read(&bmap->b_sem);
+
+ if (ret < 0)
+ ret = nilfs_bmap_convert_error(bmap, __func__, ret);
+ else
+ *key = lastkey;
return ret;
}
@@ -210,7 +230,8 @@ int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key)
down_write(&bmap->b_sem);
ret = nilfs_bmap_do_delete(bmap, key);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key)
@@ -261,7 +282,8 @@ int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key)
down_write(&bmap->b_sem);
ret = nilfs_bmap_do_truncate(bmap, key);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
/**
@@ -300,7 +322,8 @@ int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh)
down_write(&bmap->b_sem);
ret = bmap->b_ops->bop_propagate(bmap, bh);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
/**
@@ -344,7 +367,8 @@ int nilfs_bmap_assign(struct nilfs_bmap *bmap,
down_write(&bmap->b_sem);
ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
/**
@@ -373,7 +397,8 @@ int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level)
down_write(&bmap->b_sem);
ret = bmap->b_ops->bop_mark(bmap, key, level);
up_write(&bmap->b_sem);
- return ret;
+
+ return nilfs_bmap_convert_error(bmap, __func__, ret);
}
/**
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 5115814cb745..388e9e8f5286 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -104,8 +104,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
if (pblocknr == 0) {
pblocknr = blocknr;
if (inode->i_ino != NILFS_DAT_INO) {
- struct inode *dat =
- nilfs_dat_inode(NILFS_I_NILFS(inode));
+ struct inode *dat = NILFS_I_NILFS(inode)->ns_dat;
/* blocknr is a virtual block number */
err = nilfs_dat_translate(dat, blocknr, &pblocknr);
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index cb003c8ee1f6..9d45773b79e6 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -91,7 +91,6 @@ static void nilfs_commit_chunk(struct page *page,
unsigned from, unsigned to)
{
struct inode *dir = mapping->host;
- struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb);
loff_t pos = page_offset(page) + from;
unsigned len = to - from;
unsigned nr_dirty, copied;
@@ -103,7 +102,7 @@ static void nilfs_commit_chunk(struct page *page,
i_size_write(dir, pos + copied);
if (IS_DIRSYNC(dir))
nilfs_set_transaction_flag(NILFS_TI_SYNC);
- err = nilfs_set_file_dirty(sbi, dir, nr_dirty);
+ err = nilfs_set_file_dirty(dir, nr_dirty);
WARN_ON(err); /* do not happen */
unlock_page(page);
}
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index c9a30d7ff6fc..2f560c9fb808 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -155,6 +155,7 @@ const struct inode_operations nilfs_file_inode_operations = {
.truncate = nilfs_truncate,
.setattr = nilfs_setattr,
.permission = nilfs_permission,
+ .fiemap = nilfs_fiemap,
};
/* end of file */
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index 33ad25ddd5c4..caf9a6a3fb54 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -176,7 +176,6 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
int nilfs_init_gcinode(struct inode *inode)
{
struct nilfs_inode_info *ii = NILFS_I(inode);
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
inode->i_mode = S_IFREG;
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
@@ -186,14 +185,6 @@ int nilfs_init_gcinode(struct inode *inode)
ii->i_flags = 0;
nilfs_bmap_init_gc(ii->i_bmap);
- /*
- * Add the inode to GC inode list. Garbage Collection
- * is serialized and no two processes manipulate the
- * list simultaneously.
- */
- igrab(inode);
- list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes);
-
return 0;
}
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
index 9f8a2da67f90..bfc73d3a30ed 100644
--- a/fs/nilfs2/ifile.c
+++ b/fs/nilfs2/ifile.c
@@ -149,14 +149,9 @@ int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
}
err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
- if (unlikely(err)) {
- if (err == -EINVAL)
- nilfs_error(sb, __func__, "ifile is broken");
- else
- nilfs_warning(sb, __func__,
- "unable to read inode: %lu",
- (unsigned long) ino);
- }
+ if (unlikely(err))
+ nilfs_warning(sb, __func__, "unable to read inode: %lu",
+ (unsigned long) ino);
return err;
}
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 71d4bc8464e0..3becc12add79 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -58,7 +58,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
struct nilfs_inode_info *ii = NILFS_I(inode);
__u64 blknum = 0;
int err = 0, ret;
- struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode));
+ struct inode *dat = NILFS_I_NILFS(inode)->ns_dat;
unsigned maxblocks = bh_result->b_size >> inode->i_blkbits;
down_read(&NILFS_MDT(dat)->mi_sem);
@@ -96,11 +96,6 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
inode->i_ino,
(unsigned long long)blkoff);
err = 0;
- } else if (err == -EINVAL) {
- nilfs_error(inode->i_sb, __func__,
- "broken bmap (inode=%lu)\n",
- inode->i_ino);
- err = -EIO;
}
nilfs_transaction_abort(inode->i_sb);
goto out;
@@ -109,6 +104,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
nilfs_transaction_commit(inode->i_sb); /* never fails */
/* Error handling should be detailed */
set_buffer_new(bh_result);
+ set_buffer_delay(bh_result);
map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed
to proper value */
} else if (ret == -ENOENT) {
@@ -185,10 +181,9 @@ static int nilfs_set_page_dirty(struct page *page)
if (ret) {
struct inode *inode = page->mapping->host;
- struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits);
- nilfs_set_file_dirty(sbi, inode, nr_dirty);
+ nilfs_set_file_dirty(inode, nr_dirty);
}
return ret;
}
@@ -229,7 +224,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping,
start + copied);
copied = generic_write_end(file, mapping, pos, len, copied, page,
fsdata);
- nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty);
+ nilfs_set_file_dirty(inode, nr_dirty);
err = nilfs_transaction_commit(inode->i_sb);
return err ? : copied;
}
@@ -425,13 +420,12 @@ static int __nilfs_read_inode(struct super_block *sb,
struct nilfs_root *root, unsigned long ino,
struct inode *inode)
{
- struct nilfs_sb_info *sbi = NILFS_SB(sb);
- struct inode *dat = nilfs_dat_inode(sbi->s_nilfs);
+ struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs;
struct buffer_head *bh;
struct nilfs_inode *raw_inode;
int err;
- down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh);
if (unlikely(err))
goto bad_inode;
@@ -461,7 +455,7 @@ static int __nilfs_read_inode(struct super_block *sb,
}
nilfs_ifile_unmap_inode(root->ifile, ino, bh);
brelse(bh);
- up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
nilfs_set_inode_flags(inode);
return 0;
@@ -470,7 +464,7 @@ static int __nilfs_read_inode(struct super_block *sb,
brelse(bh);
bad_inode:
- up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
return err;
}
@@ -629,7 +623,7 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii,
if (!test_bit(NILFS_I_BMAP, &ii->i_state))
return;
- repeat:
+repeat:
ret = nilfs_bmap_last_key(ii->i_bmap, &b);
if (ret == -ENOENT)
return;
@@ -646,14 +640,10 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii,
nilfs_bmap_truncate(ii->i_bmap, b) == 0))
goto repeat;
- failed:
- if (ret == -EINVAL)
- nilfs_error(ii->vfs_inode.i_sb, __func__,
- "bmap is broken (ino=%lu)", ii->vfs_inode.i_ino);
- else
- nilfs_warning(ii->vfs_inode.i_sb, __func__,
- "failed to truncate bmap (ino=%lu, err=%d)",
- ii->vfs_inode.i_ino, ret);
+failed:
+ nilfs_warning(ii->vfs_inode.i_sb, __func__,
+ "failed to truncate bmap (ino=%lu, err=%d)",
+ ii->vfs_inode.i_ino, ret);
}
void nilfs_truncate(struct inode *inode)
@@ -682,7 +672,7 @@ void nilfs_truncate(struct inode *inode)
nilfs_set_transaction_flag(NILFS_TI_SYNC);
nilfs_mark_inode_dirty(inode);
- nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
+ nilfs_set_file_dirty(inode, 0);
nilfs_transaction_commit(sb);
/* May construct a logical segment and may fail in sync mode.
But truncate has no return value. */
@@ -796,9 +786,9 @@ int nilfs_permission(struct inode *inode, int mask)
return generic_permission(inode, mask, NULL);
}
-int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
- struct buffer_head **pbh)
+int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh)
{
+ struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
struct nilfs_inode_info *ii = NILFS_I(inode);
int err;
@@ -839,9 +829,9 @@ int nilfs_inode_dirty(struct inode *inode)
return ret;
}
-int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode,
- unsigned nr_dirty)
+int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty)
{
+ struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
struct nilfs_inode_info *ii = NILFS_I(inode);
atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks);
@@ -874,11 +864,10 @@ int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode,
int nilfs_mark_inode_dirty(struct inode *inode)
{
- struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
struct buffer_head *ibh;
int err;
- err = nilfs_load_inode_block(sbi, inode, &ibh);
+ err = nilfs_load_inode_block(inode, &ibh);
if (unlikely(err)) {
nilfs_warning(inode->i_sb, __func__,
"failed to reget inode block.\n");
@@ -920,3 +909,134 @@ void nilfs_dirty_inode(struct inode *inode)
nilfs_mark_inode_dirty(inode);
nilfs_transaction_commit(inode->i_sb); /* never fails */
}
+
+int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ __u64 start, __u64 len)
+{
+ struct the_nilfs *nilfs = NILFS_I_NILFS(inode);
+ __u64 logical = 0, phys = 0, size = 0;
+ __u32 flags = 0;
+ loff_t isize;
+ sector_t blkoff, end_blkoff;
+ sector_t delalloc_blkoff;
+ unsigned long delalloc_blklen;
+ unsigned int blkbits = inode->i_blkbits;
+ int ret, n;
+
+ ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
+ if (ret)
+ return ret;
+
+ mutex_lock(&inode->i_mutex);
+
+ isize = i_size_read(inode);
+
+ blkoff = start >> blkbits;
+ end_blkoff = (start + len - 1) >> blkbits;
+
+ delalloc_blklen = nilfs_find_uncommitted_extent(inode, blkoff,
+ &delalloc_blkoff);
+
+ do {
+ __u64 blkphy;
+ unsigned int maxblocks;
+
+ if (delalloc_blklen && blkoff == delalloc_blkoff) {
+ if (size) {
+ /* End of the current extent */
+ ret = fiemap_fill_next_extent(
+ fieinfo, logical, phys, size, flags);
+ if (ret)
+ break;
+ }
+ if (blkoff > end_blkoff)
+ break;
+
+ flags = FIEMAP_EXTENT_MERGED | FIEMAP_EXTENT_DELALLOC;
+ logical = blkoff << blkbits;
+ phys = 0;
+ size = delalloc_blklen << blkbits;
+
+ blkoff = delalloc_blkoff + delalloc_blklen;
+ delalloc_blklen = nilfs_find_uncommitted_extent(
+ inode, blkoff, &delalloc_blkoff);
+ continue;
+ }
+
+ /*
+ * Limit the number of blocks that we look up so as
+ * not to get into the next delayed allocation extent.
+ */
+ maxblocks = INT_MAX;
+ if (delalloc_blklen)
+ maxblocks = min_t(sector_t, delalloc_blkoff - blkoff,
+ maxblocks);
+ blkphy = 0;
+
+ down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+ n = nilfs_bmap_lookup_contig(
+ NILFS_I(inode)->i_bmap, blkoff, &blkphy, maxblocks);
+ up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+
+ if (n < 0) {
+ int past_eof;
+
+ if (unlikely(n != -ENOENT))
+ break; /* error */
+
+ /* HOLE */
+ blkoff++;
+ past_eof = ((blkoff << blkbits) >= isize);
+
+ if (size) {
+ /* End of the current extent */
+
+ if (past_eof)
+ flags |= FIEMAP_EXTENT_LAST;
+
+ ret = fiemap_fill_next_extent(
+ fieinfo, logical, phys, size, flags);
+ if (ret)
+ break;
+ size = 0;
+ }
+ if (blkoff > end_blkoff || past_eof)
+ break;
+ } else {
+ if (size) {
+ if (phys && blkphy << blkbits == phys + size) {
+ /* The current extent goes on */
+ size += n << blkbits;
+ } else {
+ /* Terminate the current extent */
+ ret = fiemap_fill_next_extent(
+ fieinfo, logical, phys, size,
+ flags);
+ if (ret || blkoff > end_blkoff)
+ break;
+
+ /* Start another extent */
+ flags = FIEMAP_EXTENT_MERGED;
+ logical = blkoff << blkbits;
+ phys = blkphy << blkbits;
+ size = n << blkbits;
+ }
+ } else {
+ /* Start a new extent */
+ flags = FIEMAP_EXTENT_MERGED;
+ logical = blkoff << blkbits;
+ phys = blkphy << blkbits;
+ size = n << blkbits;
+ }
+ blkoff += n;
+ }
+ cond_resched();
+ } while (true);
+
+ /* If ret is 1 then we just hit the end of the extent array */
+ if (ret == 1)
+ ret = 0;
+
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+}
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index e00d9457c256..496738963fdb 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -233,7 +233,7 @@ nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
int ret;
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, size, nmembs);
+ ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
up_read(&nilfs->ns_segctor_sem);
return ret;
}
@@ -242,8 +242,7 @@ static ssize_t
nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- struct inode *dat = nilfs_dat_inode(nilfs);
- struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
+ struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
struct nilfs_bdesc *bdescs = buf;
int ret, i;
@@ -337,6 +336,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
struct nilfs_argv *argv, void *buf)
{
size_t nmembs = argv->v_nmembs;
+ struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs;
struct inode *inode;
struct nilfs_vdesc *vdesc;
struct buffer_head *bh, *n;
@@ -353,6 +353,17 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
ret = PTR_ERR(inode);
goto failed;
}
+ if (list_empty(&NILFS_I(inode)->i_dirty)) {
+ /*
+ * Add the inode to GC inode list. Garbage Collection
+ * is serialized and no two processes manipulate the
+ * list simultaneously.
+ */
+ igrab(inode);
+ list_add(&NILFS_I(inode)->i_dirty,
+ &nilfs->ns_gc_inodes);
+ }
+
do {
ret = nilfs_ioctl_move_inode_block(inode, vdesc,
&buffers);
@@ -409,7 +420,7 @@ static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
size_t nmembs = argv->v_nmembs;
int ret;
- ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
+ ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
return (ret < 0) ? ret : nmembs;
}
@@ -418,8 +429,7 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
struct nilfs_argv *argv, void *buf)
{
size_t nmembs = argv->v_nmembs;
- struct inode *dat = nilfs_dat_inode(nilfs);
- struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
+ struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
struct nilfs_bdesc *bdescs = buf;
int ret, i;
@@ -438,7 +448,7 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
/* skip dead block */
continue;
if (bdescs[i].bd_level == 0) {
- ret = nilfs_mdt_mark_block_dirty(dat,
+ ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat,
bdescs[i].bd_offset);
if (ret < 0) {
WARN_ON(ret == -ENOENT);
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 39a5b84e2c9f..6a0e2a189f60 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -237,8 +237,6 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
*
* %-ENOENT - the specified block does not exist (hole block)
*
- * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
- *
* %-EROFS - Read only filesystem (for create mode)
*/
int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
@@ -273,8 +271,6 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
* %-ENOMEM - Insufficient memory available.
*
* %-EIO - I/O error
- *
- * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
*/
int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
{
@@ -350,8 +346,6 @@ int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)
* %-EIO - I/O error
*
* %-ENOENT - the specified block does not exist (hole block)
- *
- * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
*/
int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
{
@@ -499,31 +493,29 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
struct buffer_head *bh_frozen;
struct page *page;
int blkbits = inode->i_blkbits;
- int ret = -ENOMEM;
page = grab_cache_page(&shadow->frozen_data, bh->b_page->index);
if (!page)
- return ret;
+ return -ENOMEM;
if (!page_has_buffers(page))
create_empty_buffers(page, 1 << blkbits, 0);
bh_frozen = nilfs_page_get_nth_block(page, bh_offset(bh) >> blkbits);
- if (bh_frozen) {
- if (!buffer_uptodate(bh_frozen))
- nilfs_copy_buffer(bh_frozen, bh);
- if (list_empty(&bh_frozen->b_assoc_buffers)) {
- list_add_tail(&bh_frozen->b_assoc_buffers,
- &shadow->frozen_buffers);
- set_buffer_nilfs_redirected(bh);
- } else {
- brelse(bh_frozen); /* already frozen */
- }
- ret = 0;
+
+ if (!buffer_uptodate(bh_frozen))
+ nilfs_copy_buffer(bh_frozen, bh);
+ if (list_empty(&bh_frozen->b_assoc_buffers)) {
+ list_add_tail(&bh_frozen->b_assoc_buffers,
+ &shadow->frozen_buffers);
+ set_buffer_nilfs_redirected(bh);
+ } else {
+ brelse(bh_frozen); /* already frozen */
}
+
unlock_page(page);
page_cache_release(page);
- return ret;
+ return 0;
}
struct buffer_head *
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 6e9557ecf161..98034271cd02 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -577,6 +577,7 @@ const struct inode_operations nilfs_dir_inode_operations = {
.rename = nilfs_rename,
.setattr = nilfs_setattr,
.permission = nilfs_permission,
+ .fiemap = nilfs_fiemap,
};
const struct inode_operations nilfs_special_inode_operations = {
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index f7560da5a567..04ba1102d8c7 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -190,11 +190,6 @@ static inline int nilfs_doing_construction(void)
return nilfs_test_transaction_flag(NILFS_TI_WRITER);
}
-static inline struct inode *nilfs_dat_inode(const struct the_nilfs *nilfs)
-{
- return nilfs->ns_dat;
-}
-
/*
* function prototype
*/
@@ -257,13 +252,13 @@ extern void nilfs_truncate(struct inode *);
extern void nilfs_evict_inode(struct inode *);
extern int nilfs_setattr(struct dentry *, struct iattr *);
int nilfs_permission(struct inode *inode, int mask);
-extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *,
- struct buffer_head **);
+int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh);
extern int nilfs_inode_dirty(struct inode *);
-extern int nilfs_set_file_dirty(struct nilfs_sb_info *, struct inode *,
- unsigned);
+int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty);
extern int nilfs_mark_inode_dirty(struct inode *);
extern void nilfs_dirty_inode(struct inode *);
+int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ __u64 start, __u64 len);
/* super.c */
extern struct inode *nilfs_alloc_inode(struct super_block *);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index a6c3c2e817f8..0c432416cfef 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -491,7 +491,7 @@ unsigned nilfs_page_count_clean_buffers(struct page *page,
}
return nc;
}
-
+
void nilfs_mapping_init_once(struct address_space *mapping)
{
memset(mapping, 0, sizeof(*mapping));
@@ -546,3 +546,87 @@ int __nilfs_clear_page_dirty(struct page *page)
}
return TestClearPageDirty(page);
}
+
+/**
+ * nilfs_find_uncommitted_extent - find extent of uncommitted data
+ * @inode: inode
+ * @start_blk: start block offset (in)
+ * @blkoff: start offset of the found extent (out)
+ *
+ * This function searches an extent of buffers marked "delayed" which
+ * starts from a block offset equal to or larger than @start_blk. If
+ * such an extent was found, this will store the start offset in
+ * @blkoff and return its length in blocks. Otherwise, zero is
+ * returned.
+ */
+unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
+ sector_t start_blk,
+ sector_t *blkoff)
+{
+ unsigned int i;
+ pgoff_t index;
+ unsigned int nblocks_in_page;
+ unsigned long length = 0;
+ sector_t b;
+ struct pagevec pvec;
+ struct page *page;
+
+ if (inode->i_mapping->nrpages == 0)
+ return 0;
+
+ index = start_blk >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+ nblocks_in_page = 1U << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+
+ pagevec_init(&pvec, 0);
+
+repeat:
+ pvec.nr = find_get_pages_contig(inode->i_mapping, index, PAGEVEC_SIZE,
+ pvec.pages);
+ if (pvec.nr == 0)
+ return length;
+
+ if (length > 0 && pvec.pages[0]->index > index)
+ goto out;
+
+ b = pvec.pages[0]->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+ i = 0;
+ do {
+ page = pvec.pages[i];
+
+ lock_page(page);
+ if (page_has_buffers(page)) {
+ struct buffer_head *bh, *head;
+
+ bh = head = page_buffers(page);
+ do {
+ if (b < start_blk)
+ continue;
+ if (buffer_delay(bh)) {
+ if (length == 0)
+ *blkoff = b;
+ length++;
+ } else if (length > 0) {
+ goto out_locked;
+ }
+ } while (++b, bh = bh->b_this_page, bh != head);
+ } else {
+ if (length > 0)
+ goto out_locked;
+
+ b += nblocks_in_page;
+ }
+ unlock_page(page);
+
+ } while (++i < pagevec_count(&pvec));
+
+ index = page->index + 1;
+ pagevec_release(&pvec);
+ cond_resched();
+ goto repeat;
+
+out_locked:
+ unlock_page(page);
+out:
+ pagevec_release(&pvec);
+ return length;
+}
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index fb9e8a8a2038..622df27cd891 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -66,6 +66,9 @@ void nilfs_mapping_init(struct address_space *mapping,
struct backing_dev_info *bdi,
const struct address_space_operations *aops);
unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned);
+unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
+ sector_t start_blk,
+ sector_t *blkoff);
#define NILFS_PAGE_BUG(page, m, a...) \
do { nilfs_page_bug(page); BUG(); } while (0)
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 5d2711c28da7..3dfcd3b7d389 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -535,7 +535,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
if (unlikely(err))
goto failed_page;
- err = nilfs_set_file_dirty(sbi, inode, 1);
+ err = nilfs_set_file_dirty(inode, 1);
if (unlikely(err))
goto failed_page;
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h
index 35a07157b980..7a17715f215f 100644
--- a/fs/nilfs2/sb.h
+++ b/fs/nilfs2/sb.h
@@ -27,14 +27,6 @@
#include <linux/types.h>
#include <linux/fs.h>
-/*
- * Mount options
- */
-struct nilfs_mount_options {
- unsigned long mount_opt;
- __u64 snapshot_cno;
-};
-
struct the_nilfs;
struct nilfs_sc_info;
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 687d090cea34..55ebae5c7f39 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -504,17 +504,6 @@ static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci,
return err;
}
-static int nilfs_handle_bmap_error(int err, const char *fname,
- struct inode *inode, struct super_block *sb)
-{
- if (err == -EINVAL) {
- nilfs_error(sb, fname, "broken bmap (inode=%lu)\n",
- inode->i_ino);
- err = -EIO;
- }
- return err;
-}
-
/*
* Callback functions that enumerate, mark, and collect dirty blocks
*/
@@ -524,9 +513,8 @@ static int nilfs_collect_file_data(struct nilfs_sc_info *sci,
int err;
err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
- if (unlikely(err < 0))
- return nilfs_handle_bmap_error(err, __func__, inode,
- sci->sc_super);
+ if (err < 0)
+ return err;
err = nilfs_segctor_add_file_block(sci, bh, inode,
sizeof(struct nilfs_binfo_v));
@@ -539,13 +527,7 @@ static int nilfs_collect_file_node(struct nilfs_sc_info *sci,
struct buffer_head *bh,
struct inode *inode)
{
- int err;
-
- err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
- if (unlikely(err < 0))
- return nilfs_handle_bmap_error(err, __func__, inode,
- sci->sc_super);
- return 0;
+ return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
}
static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
@@ -588,9 +570,8 @@ static int nilfs_collect_dat_data(struct nilfs_sc_info *sci,
int err;
err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
- if (unlikely(err < 0))
- return nilfs_handle_bmap_error(err, __func__, inode,
- sci->sc_super);
+ if (err < 0)
+ return err;
err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
if (!err)
@@ -776,9 +757,8 @@ static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
ret++;
if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile))
ret++;
- if (ret || nilfs_doing_gc())
- if (nilfs_mdt_fetch_dirty(nilfs_dat_inode(nilfs)))
- ret++;
+ if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
+ ret++;
return ret;
}
@@ -814,7 +794,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
nilfs_mdt_clear_dirty(sci->sc_root->ifile);
nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
nilfs_mdt_clear_dirty(nilfs->ns_sufile);
- nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs));
+ nilfs_mdt_clear_dirty(nilfs->ns_dat);
}
static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
@@ -923,7 +903,7 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
raw_sr->sr_flags = 0;
- nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr +
+ nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr +
NILFS_SR_DAT_OFFSET(isz), 1);
nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr +
NILFS_SR_CPFILE_OFFSET(isz), 1);
@@ -1179,7 +1159,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
sci->sc_stage.scnt++; /* Fall through */
case NILFS_ST_DAT:
dat_stage:
- err = nilfs_segctor_scan_file(sci, nilfs_dat_inode(nilfs),
+ err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
&nilfs_sc_dat_ops);
if (unlikely(err))
break;
@@ -1563,7 +1543,6 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
return 0;
failed_bmap:
- err = nilfs_handle_bmap_error(err, __func__, inode, sci->sc_super);
return err;
}
@@ -1783,6 +1762,7 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
if (!err) {
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
+ clear_buffer_delay(bh);
clear_buffer_nilfs_volatile(bh);
}
brelse(bh); /* for b_assoc_buffers */
@@ -1909,6 +1889,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
b_assoc_buffers) {
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
+ clear_buffer_delay(bh);
clear_buffer_nilfs_volatile(bh);
clear_buffer_nilfs_redirected(bh);
if (bh == segbuf->sb_super_root) {
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index f804d41ec9d3..b9b6963508fd 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -111,12 +111,17 @@ void nilfs_error(struct super_block *sb, const char *function,
const char *fmt, ...)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_CRIT "NILFS error (device %s): %s: ", sb->s_id, function);
- vprintk(fmt, args);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_CRIT "NILFS error (device %s): %s: %pV\n",
+ sb->s_id, function, &vaf);
+
va_end(args);
if (!(sb->s_flags & MS_RDONLY)) {
@@ -136,13 +141,17 @@ void nilfs_error(struct super_block *sb, const char *function,
void nilfs_warning(struct super_block *sb, const char *function,
const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_WARNING "NILFS warning (device %s): %s: ",
- sb->s_id, function);
- vprintk(fmt, args);
- printk("\n");
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_WARNING "NILFS warning (device %s): %s: %pV\n",
+ sb->s_id, function, &vaf);
+
va_end(args);
}
@@ -162,10 +171,13 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
return &ii->vfs_inode;
}
-void nilfs_destroy_inode(struct inode *inode)
+static void nilfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
+ INIT_LIST_HEAD(&inode->i_dentry);
+
if (mdi) {
kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
kfree(mdi);
@@ -173,6 +185,11 @@ void nilfs_destroy_inode(struct inode *inode)
kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
}
+void nilfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, nilfs_i_callback);
+}
+
static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
@@ -838,7 +855,7 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
static int nilfs_tree_was_touched(struct dentry *root_dentry)
{
- return atomic_read(&root_dentry->d_count) > 1;
+ return root_dentry->d_count > 1;
}
/**
@@ -1002,11 +1019,11 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct the_nilfs *nilfs = sbi->s_nilfs;
unsigned long old_sb_flags;
- struct nilfs_mount_options old_opts;
+ unsigned long old_mount_opt;
int err;
old_sb_flags = sb->s_flags;
- old_opts.mount_opt = sbi->s_mount_opt;
+ old_mount_opt = sbi->s_mount_opt;
if (!parse_options(data, sb, 1)) {
err = -EINVAL;
@@ -1075,7 +1092,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
restore_opts:
sb->s_flags = old_sb_flags;
- sbi->s_mount_opt = old_opts.mount_opt;
+ sbi->s_mount_opt = old_mount_opt;
return err;
}
@@ -1147,14 +1164,14 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
{
struct nilfs_super_data sd;
struct super_block *s;
- fmode_t mode = FMODE_READ;
+ fmode_t mode = FMODE_READ | FMODE_EXCL;
struct dentry *root_dentry;
int err, s_new = false;
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
- sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+ sd.bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(sd.bdev))
return ERR_CAST(sd.bdev);
@@ -1233,7 +1250,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
}
if (!s_new)
- close_bdev_exclusive(sd.bdev, mode);
+ blkdev_put(sd.bdev, mode);
return root_dentry;
@@ -1242,7 +1259,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
failed:
if (!s_new)
- close_bdev_exclusive(sd.bdev, mode);
+ blkdev_put(sd.bdev, mode);
return ERR_PTR(err);
}
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 0254be2d73c6..ad4ac607cf57 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -329,7 +329,6 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
printk(KERN_INFO "NILFS: recovery complete.\n");
skip_recovery:
- set_nilfs_loaded(nilfs);
nilfs_clear_recovery_info(&ri);
sbi->s_super->s_flags = s_flags;
return 0;
@@ -651,12 +650,11 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
{
- struct inode *dat = nilfs_dat_inode(nilfs);
unsigned long ncleansegs;
- down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
- up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
return 0;
}
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 69226e14b745..fd85e4c05c6b 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -36,8 +36,6 @@
/* the_nilfs struct */
enum {
THE_NILFS_INIT = 0, /* Information from super_block is set */
- THE_NILFS_LOADED, /* Roll-back/roll-forward has done and
- the latest checkpoint was loaded */
THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
THE_NILFS_GC_RUNNING, /* gc process is running */
THE_NILFS_SB_DIRTY, /* super block is dirty */
@@ -178,7 +176,6 @@ static inline int nilfs_##name(struct the_nilfs *nilfs) \
}
THE_NILFS_FNS(INIT, init)
-THE_NILFS_FNS(LOADED, loaded)
THE_NILFS_FNS(DISCONTINUED, discontinued)
THE_NILFS_FNS(GC_RUNNING, gc_running)
THE_NILFS_FNS(SB_DIRTY, sb_dirty)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index b04f88eed09e..f35794b97e8e 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group,
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
- wait_event(group->fanotify_data.access_waitq, event->response);
+ wait_event(group->fanotify_data.access_waitq, event->response ||
+ atomic_read(&group->fanotify_data.bypass_perm));
+
+ if (!event->response) /* bypass_perm set */
+ return 0;
/* userspace responded, convert to something usable */
spin_lock(&event->lock);
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 063224812b7e..8b61220cffc5 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
return client_fd;
}
-static ssize_t fill_event_metadata(struct fsnotify_group *group,
+static int fill_event_metadata(struct fsnotify_group *group,
struct fanotify_event_metadata *metadata,
struct fsnotify_event *event)
{
+ int ret = 0;
+
pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
group, metadata, event);
metadata->event_len = FAN_EVENT_METADATA_LEN;
+ metadata->metadata_len = FAN_EVENT_METADATA_LEN;
metadata->vers = FANOTIFY_METADATA_VERSION;
metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS;
metadata->pid = pid_vnr(event->tgid);
- metadata->fd = create_fd(group, event);
+ if (unlikely(event->mask & FAN_Q_OVERFLOW))
+ metadata->fd = FAN_NOFD;
+ else {
+ metadata->fd = create_fd(group, event);
+ if (metadata->fd < 0)
+ ret = metadata->fd;
+ }
- return metadata->fd;
+ return ret;
}
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
@@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group,
mutex_lock(&group->fanotify_data.access_mutex);
- if (group->fanotify_data.bypass_perm) {
+ if (atomic_read(&group->fanotify_data.bypass_perm)) {
mutex_unlock(&group->fanotify_data.access_mutex);
kmem_cache_free(fanotify_response_event_cache, re);
event->response = FAN_ALLOW;
@@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
- fd = fill_event_metadata(group, &fanotify_event_metadata, event);
- if (fd < 0)
- return fd;
+ ret = fill_event_metadata(group, &fanotify_event_metadata, event);
+ if (ret < 0)
+ goto out;
+ fd = fanotify_event_metadata.fd;
ret = prepare_for_access_response(group, event, fd);
if (ret)
goto out_close_fd;
ret = -EFAULT;
- if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN))
+ if (copy_to_user(buf, &fanotify_event_metadata,
+ fanotify_event_metadata.event_len))
goto out_kill_access_response;
- return FAN_EVENT_METADATA_LEN;
+ return fanotify_event_metadata.event_len;
out_kill_access_response:
remove_access_response(group, event, fd);
out_close_fd:
- sys_close(fd);
+ if (fd != FAN_NOFD)
+ sys_close(fd);
+out:
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+ if (event->mask & FAN_ALL_PERM_EVENTS) {
+ event->response = FAN_DENY;
+ wake_up(&group->fanotify_data.access_waitq);
+ }
+#endif
return ret;
}
@@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
mutex_lock(&group->fanotify_data.access_mutex);
- group->fanotify_data.bypass_perm = true;
+ atomic_inc(&group->fanotify_data.bypass_perm);
list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) {
pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group,
@@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
{
struct fsnotify_mark *fsn_mark;
__u32 added;
+ int ret = 0;
fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
if (!fsn_mark) {
- int ret;
-
if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
return -ENOSPC;
@@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
fsnotify_init_mark(fsn_mark, fanotify_free_mark);
ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0);
- if (ret) {
- fanotify_free_mark(fsn_mark);
- return ret;
- }
+ if (ret)
+ goto err;
}
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
- fsnotify_put_mark(fsn_mark);
+
if (added & ~mnt->mnt_fsnotify_mask)
fsnotify_recalc_vfsmount_mask(mnt);
-
- return 0;
+err:
+ fsnotify_put_mark(fsn_mark);
+ return ret;
}
static int fanotify_add_inode_mark(struct fsnotify_group *group,
@@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
{
struct fsnotify_mark *fsn_mark;
__u32 added;
+ int ret = 0;
pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
@@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
fsn_mark = fsnotify_find_inode_mark(group, inode);
if (!fsn_mark) {
- int ret;
-
if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
return -ENOSPC;
@@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
fsnotify_init_mark(fsn_mark, fanotify_free_mark);
ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0);
- if (ret) {
- fanotify_free_mark(fsn_mark);
- return ret;
- }
+ if (ret)
+ goto err;
}
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
- fsnotify_put_mark(fsn_mark);
+
if (added & ~inode->i_fsnotify_mask)
fsnotify_recalc_inode_mask(inode);
- return 0;
+err:
+ fsnotify_put_mark(fsn_mark);
+ return ret;
}
/* fanotify syscalls */
@@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
/* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */
group = fsnotify_alloc_group(&fanotify_fsnotify_ops);
- if (IS_ERR(group))
+ if (IS_ERR(group)) {
+ free_uid(user);
return PTR_ERR(group);
+ }
group->fanotify_data.user = user;
atomic_inc(&user->fanotify_listeners);
@@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
mutex_init(&group->fanotify_data.access_mutex);
init_waitqueue_head(&group->fanotify_data.access_waitq);
INIT_LIST_HEAD(&group->fanotify_data.access_list);
+ atomic_set(&group->fanotify_data.bypass_perm, 0);
#endif
switch (flags & FAN_ALL_CLASS_BITS) {
case FAN_CLASS_NOTIF:
@@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
if (flags & ~FAN_ALL_MARK_FLAGS)
return -EINVAL;
switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
- case FAN_MARK_ADD:
+ case FAN_MARK_ADD: /* fallthrough */
case FAN_MARK_REMOVE:
+ if (!mask)
+ return -EINVAL;
case FAN_MARK_FLUSH:
break;
default:
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 20dc218707ca..79b47cbb5cd8 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -59,7 +59,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
/* determine if the children should tell inode about their events */
watched = fsnotify_inode_watches_children(inode);
- spin_lock(&dcache_lock);
+ spin_lock(&inode->i_lock);
/* run all of the dentries associated with this inode. Since this is a
* directory, there damn well better only be one item on this list */
list_for_each_entry(alias, &inode->i_dentry, d_alias) {
@@ -68,19 +68,21 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
/* run all of the children of the original inode and fix their
* d_flags to indicate parental interest (their parent is the
* original inode) */
+ spin_lock(&alias->d_lock);
list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
if (!child->d_inode)
continue;
- spin_lock(&child->d_lock);
+ spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
if (watched)
child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
else
child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
spin_unlock(&child->d_lock);
}
+ spin_unlock(&alias->d_lock);
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
}
/* Notify this dentry's parent about a child's events. */
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 444c305a468c..4cd5d5d78f9f 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
if (ret >= 0)
return ret;
+ fsnotify_put_group(group);
atomic_dec(&user->inotify_devs);
out_free_uid:
free_uid(user);
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 93622b175fc7..a627ed82c0a3 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -332,6 +332,13 @@ struct inode *ntfs_alloc_big_inode(struct super_block *sb)
return NULL;
}
+static void ntfs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ntfs_big_inode_cache, NTFS_I(inode));
+}
+
void ntfs_destroy_big_inode(struct inode *inode)
{
ntfs_inode *ni = NTFS_I(inode);
@@ -340,7 +347,7 @@ void ntfs_destroy_big_inode(struct inode *inode)
BUG_ON(ni->page);
if (!atomic_dec_and_test(&ni->count))
BUG();
- kmem_cache_free(ntfs_big_inode_cache, NTFS_I(inode));
+ call_rcu(&inode->i_rcu, ntfs_i_callback);
}
static inline ntfs_inode *ntfs_alloc_extent_inode(void)
diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig
index 0d840669698e..ab152c00cd3a 100644
--- a/fs/ocfs2/Kconfig
+++ b/fs/ocfs2/Kconfig
@@ -51,7 +51,7 @@ config OCFS2_FS_USERSPACE_CLUSTER
config OCFS2_FS_STATS
bool "OCFS2 statistics"
- depends on OCFS2_FS
+ depends on OCFS2_FS && DEBUG_FS
default y
help
This option allows some fs statistics to be captured. Enabling
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 592fae5007d1..8ec418dd9e36 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5858,6 +5858,7 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
ocfs2_journal_dirty(handle, tl_bh);
+ osb->truncated_clusters += num_clusters;
bail:
mlog_exit(status);
return status;
@@ -5929,6 +5930,8 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
i--;
}
+ osb->truncated_clusters = 0;
+
bail:
mlog_exit(status);
return status;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f1e962cb3b73..1fbb0e20131b 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -573,11 +573,14 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
/* this io's submitter should not have unlocked this before we could */
BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
+ if (ocfs2_iocb_is_sem_locked(iocb)) {
+ up_read(&inode->i_alloc_sem);
+ ocfs2_iocb_clear_sem_locked(iocb);
+ }
+
ocfs2_iocb_clear_rw_locked(iocb);
level = ocfs2_iocb_rw_locked_level(iocb);
- if (!level)
- up_read(&inode->i_alloc_sem);
ocfs2_rw_unlock(inode, level);
if (is_async)
@@ -1627,6 +1630,43 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
return ret;
}
+/*
+ * Try to flush truncate logs if we can free enough clusters from it.
+ * As for return value, "< 0" means error, "0" no space and "1" means
+ * we have freed enough spaces and let the caller try to allocate again.
+ */
+static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb,
+ unsigned int needed)
+{
+ tid_t target;
+ int ret = 0;
+ unsigned int truncated_clusters;
+
+ mutex_lock(&osb->osb_tl_inode->i_mutex);
+ truncated_clusters = osb->truncated_clusters;
+ mutex_unlock(&osb->osb_tl_inode->i_mutex);
+
+ /*
+ * Check whether we can succeed in allocating if we free
+ * the truncate log.
+ */
+ if (truncated_clusters < needed)
+ goto out;
+
+ ret = ocfs2_flush_truncate_log(osb);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (jbd2_journal_start_commit(osb->journal->j_journal, &target)) {
+ jbd2_log_wait_commit(osb->journal->j_journal, target);
+ ret = 1;
+ }
+out:
+ return ret;
+}
+
int ocfs2_write_begin_nolock(struct file *filp,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
@@ -1634,7 +1674,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
struct buffer_head *di_bh, struct page *mmap_page)
{
int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
- unsigned int clusters_to_alloc, extents_to_split;
+ unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0;
struct ocfs2_write_ctxt *wc;
struct inode *inode = mapping->host;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -1643,7 +1683,9 @@ int ocfs2_write_begin_nolock(struct file *filp,
struct ocfs2_alloc_context *meta_ac = NULL;
handle_t *handle;
struct ocfs2_extent_tree et;
+ int try_free = 1, ret1;
+try_again:
ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh);
if (ret) {
mlog_errno(ret);
@@ -1678,6 +1720,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
mlog_errno(ret);
goto out;
} else if (ret == 1) {
+ clusters_need = wc->w_clen;
ret = ocfs2_refcount_cow(inode, filp, di_bh,
wc->w_cpos, wc->w_clen, UINT_MAX);
if (ret) {
@@ -1692,6 +1735,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
mlog_errno(ret);
goto out;
}
+ clusters_need += clusters_to_alloc;
di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
@@ -1814,6 +1858,22 @@ out:
ocfs2_free_alloc_context(data_ac);
if (meta_ac)
ocfs2_free_alloc_context(meta_ac);
+
+ if (ret == -ENOSPC && try_free) {
+ /*
+ * Try to free some truncate log so that we can have enough
+ * clusters to allocate.
+ */
+ try_free = 0;
+
+ ret1 = ocfs2_try_to_free_truncate_log(osb, clusters_need);
+ if (ret1 == 1)
+ goto try_again;
+
+ if (ret1 < 0)
+ mlog_errno(ret1);
+ }
+
return ret;
}
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 76bfdfda691a..eceb456037c1 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
else
clear_bit(1, (unsigned long *)&iocb->private);
}
+
+/*
+ * Using a named enum representing lock types in terms of #N bit stored in
+ * iocb->private, which is going to be used for communication bewteen
+ * ocfs2_dio_end_io() and ocfs2_file_aio_write/read().
+ */
+enum ocfs2_iocb_lock_bits {
+ OCFS2_IOCB_RW_LOCK = 0,
+ OCFS2_IOCB_RW_LOCK_LEVEL,
+ OCFS2_IOCB_SEM,
+ OCFS2_IOCB_NUM_LOCKS
+};
+
#define ocfs2_iocb_clear_rw_locked(iocb) \
- clear_bit(0, (unsigned long *)&iocb->private)
+ clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
#define ocfs2_iocb_rw_locked_level(iocb) \
- test_bit(1, (unsigned long *)&iocb->private)
+ test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_set_sem_locked(iocb) \
+ set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_sem_locked(iocb) \
+ clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_sem_locked(iocb) \
+ test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
#endif /* OCFS2_FILE_H */
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 52c7557f3e25..94006b635528 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -82,6 +82,7 @@ static unsigned long o2hb_failed_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)];
#define O2HB_DB_TYPE_REGION_LIVENODES 4
#define O2HB_DB_TYPE_REGION_NUMBER 5
#define O2HB_DB_TYPE_REGION_ELAPSED_TIME 6
+#define O2HB_DB_TYPE_REGION_PINNED 7
struct o2hb_debug_buf {
int db_type;
int db_size;
@@ -101,6 +102,7 @@ static struct o2hb_debug_buf *o2hb_db_failedregions;
#define O2HB_DEBUG_FAILEDREGIONS "failed_regions"
#define O2HB_DEBUG_REGION_NUMBER "num"
#define O2HB_DEBUG_REGION_ELAPSED_TIME "elapsed_time_in_ms"
+#define O2HB_DEBUG_REGION_PINNED "pinned"
static struct dentry *o2hb_debug_dir;
static struct dentry *o2hb_debug_livenodes;
@@ -132,6 +134,33 @@ char *o2hb_heartbeat_mode_desc[O2HB_HEARTBEAT_NUM_MODES] = {
unsigned int o2hb_dead_threshold = O2HB_DEFAULT_DEAD_THRESHOLD;
unsigned int o2hb_heartbeat_mode = O2HB_HEARTBEAT_LOCAL;
+/*
+ * o2hb_dependent_users tracks the number of registered callbacks that depend
+ * on heartbeat. o2net and o2dlm are two entities that register this callback.
+ * However only o2dlm depends on the heartbeat. It does not want the heartbeat
+ * to stop while a dlm domain is still active.
+ */
+unsigned int o2hb_dependent_users;
+
+/*
+ * In global heartbeat mode, all regions are pinned if there are one or more
+ * dependent users and the quorum region count is <= O2HB_PIN_CUT_OFF. All
+ * regions are unpinned if the region count exceeds the cut off or the number
+ * of dependent users falls to zero.
+ */
+#define O2HB_PIN_CUT_OFF 3
+
+/*
+ * In local heartbeat mode, we assume the dlm domain name to be the same as
+ * region uuid. This is true for domains created for the file system but not
+ * necessarily true for userdlm domains. This is a known limitation.
+ *
+ * In global heartbeat mode, we pin/unpin all o2hb regions. This solution
+ * works for both file system and userdlm domains.
+ */
+static int o2hb_region_pin(const char *region_uuid);
+static void o2hb_region_unpin(const char *region_uuid);
+
/* Only sets a new threshold if there are no active regions.
*
* No locking or otherwise interesting code is required for reading
@@ -186,7 +215,9 @@ struct o2hb_region {
struct config_item hr_item;
struct list_head hr_all_item;
- unsigned hr_unclean_stop:1;
+ unsigned hr_unclean_stop:1,
+ hr_item_pinned:1,
+ hr_item_dropped:1;
/* protected by the hr_callback_sem */
struct task_struct *hr_task;
@@ -212,9 +243,11 @@ struct o2hb_region {
struct dentry *hr_debug_livenodes;
struct dentry *hr_debug_regnum;
struct dentry *hr_debug_elapsed_time;
+ struct dentry *hr_debug_pinned;
struct o2hb_debug_buf *hr_db_livenodes;
struct o2hb_debug_buf *hr_db_regnum;
struct o2hb_debug_buf *hr_db_elapsed_time;
+ struct o2hb_debug_buf *hr_db_pinned;
/* let the person setting up hb wait for it to return until it
* has reached a 'steady' state. This will be fixed when we have
@@ -702,6 +735,14 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
config_item_name(&reg->hr_item));
set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
+
+ /*
+ * If global heartbeat active, unpin all regions if the
+ * region count > CUT_OFF
+ */
+ if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+ O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
+ o2hb_region_unpin(NULL);
}
static int o2hb_check_slot(struct o2hb_region *reg,
@@ -1042,6 +1083,9 @@ static int o2hb_thread(void *data)
set_user_nice(current, -20);
+ /* Pin node */
+ o2nm_depend_this_node();
+
while (!kthread_should_stop() && !reg->hr_unclean_stop) {
/* We track the time spent inside
* o2hb_do_disk_heartbeat so that we avoid more than
@@ -1091,6 +1135,9 @@ static int o2hb_thread(void *data)
mlog_errno(ret);
}
+ /* Unpin node */
+ o2nm_undepend_this_node();
+
mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
return 0;
@@ -1143,6 +1190,12 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
reg->hr_last_timeout_start));
goto done;
+ case O2HB_DB_TYPE_REGION_PINNED:
+ reg = (struct o2hb_region *)db->db_data;
+ out += snprintf(buf + out, PAGE_SIZE - out, "%u\n",
+ !!reg->hr_item_pinned);
+ goto done;
+
default:
goto done;
}
@@ -1316,6 +1369,8 @@ int o2hb_init(void)
memset(o2hb_quorum_region_bitmap, 0, sizeof(o2hb_quorum_region_bitmap));
memset(o2hb_failed_region_bitmap, 0, sizeof(o2hb_failed_region_bitmap));
+ o2hb_dependent_users = 0;
+
return o2hb_debug_init();
}
@@ -1385,6 +1440,7 @@ static void o2hb_region_release(struct config_item *item)
debugfs_remove(reg->hr_debug_livenodes);
debugfs_remove(reg->hr_debug_regnum);
debugfs_remove(reg->hr_debug_elapsed_time);
+ debugfs_remove(reg->hr_debug_pinned);
debugfs_remove(reg->hr_debug_dir);
spin_lock(&o2hb_live_lock);
@@ -1674,7 +1730,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
goto out;
reg->hr_bdev = I_BDEV(filp->f_mapping->host);
- ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ);
+ ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL);
if (ret) {
reg->hr_bdev = NULL;
goto out;
@@ -1949,6 +2005,18 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
goto bail;
}
+ reg->hr_debug_pinned =
+ o2hb_debug_create(O2HB_DEBUG_REGION_PINNED,
+ reg->hr_debug_dir,
+ &(reg->hr_db_pinned),
+ sizeof(*(reg->hr_db_pinned)),
+ O2HB_DB_TYPE_REGION_PINNED,
+ 0, 0, reg);
+ if (!reg->hr_debug_pinned) {
+ mlog_errno(ret);
+ goto bail;
+ }
+
ret = 0;
bail:
return ret;
@@ -1964,8 +2032,10 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
if (reg == NULL)
return ERR_PTR(-ENOMEM);
- if (strlen(name) > O2HB_MAX_REGION_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
+ if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) {
+ ret = -ENAMETOOLONG;
+ goto free;
+ }
spin_lock(&o2hb_live_lock);
reg->hr_region_num = 0;
@@ -1974,7 +2044,8 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
O2NM_MAX_REGIONS);
if (reg->hr_region_num >= O2NM_MAX_REGIONS) {
spin_unlock(&o2hb_live_lock);
- return ERR_PTR(-EFBIG);
+ ret = -EFBIG;
+ goto free;
}
set_bit(reg->hr_region_num, o2hb_region_bitmap);
}
@@ -1986,10 +2057,13 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
if (ret) {
config_item_put(&reg->hr_item);
- return ERR_PTR(ret);
+ goto free;
}
return &reg->hr_item;
+free:
+ kfree(reg);
+ return ERR_PTR(ret);
}
static void o2hb_heartbeat_group_drop_item(struct config_group *group,
@@ -1997,15 +2071,20 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
{
struct task_struct *hb_task;
struct o2hb_region *reg = to_o2hb_region(item);
+ int quorum_region = 0;
/* stop the thread when the user removes the region dir */
spin_lock(&o2hb_live_lock);
if (o2hb_global_heartbeat_active()) {
clear_bit(reg->hr_region_num, o2hb_region_bitmap);
clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
+ if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+ quorum_region = 1;
+ clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
}
hb_task = reg->hr_task;
reg->hr_task = NULL;
+ reg->hr_item_dropped = 1;
spin_unlock(&o2hb_live_lock);
if (hb_task)
@@ -2023,7 +2102,27 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
if (o2hb_global_heartbeat_active())
printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n",
config_item_name(&reg->hr_item));
+
config_item_put(item);
+
+ if (!o2hb_global_heartbeat_active() || !quorum_region)
+ return;
+
+ /*
+ * If global heartbeat active and there are dependent users,
+ * pin all regions if quorum region count <= CUT_OFF
+ */
+ spin_lock(&o2hb_live_lock);
+
+ if (!o2hb_dependent_users)
+ goto unlock;
+
+ if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+ O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF)
+ o2hb_region_pin(NULL);
+
+unlock:
+ spin_unlock(&o2hb_live_lock);
}
struct o2hb_heartbeat_group_attribute {
@@ -2209,63 +2308,138 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
}
EXPORT_SYMBOL_GPL(o2hb_setup_callback);
-static struct o2hb_region *o2hb_find_region(const char *region_uuid)
+/*
+ * In local heartbeat mode, region_uuid passed matches the dlm domain name.
+ * In global heartbeat mode, region_uuid passed is NULL.
+ *
+ * In local, we only pin the matching region. In global we pin all the active
+ * regions.
+ */
+static int o2hb_region_pin(const char *region_uuid)
{
- struct o2hb_region *p, *reg = NULL;
+ int ret = 0, found = 0;
+ struct o2hb_region *reg;
+ char *uuid;
assert_spin_locked(&o2hb_live_lock);
- list_for_each_entry(p, &o2hb_all_regions, hr_all_item) {
- if (!strcmp(region_uuid, config_item_name(&p->hr_item))) {
- reg = p;
- break;
+ list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) {
+ uuid = config_item_name(&reg->hr_item);
+
+ /* local heartbeat */
+ if (region_uuid) {
+ if (strcmp(region_uuid, uuid))
+ continue;
+ found = 1;
+ }
+
+ if (reg->hr_item_pinned || reg->hr_item_dropped)
+ goto skip_pin;
+
+ /* Ignore ENOENT only for local hb (userdlm domain) */
+ ret = o2nm_depend_item(&reg->hr_item);
+ if (!ret) {
+ mlog(ML_CLUSTER, "Pin region %s\n", uuid);
+ reg->hr_item_pinned = 1;
+ } else {
+ if (ret == -ENOENT && found)
+ ret = 0;
+ else {
+ mlog(ML_ERROR, "Pin region %s fails with %d\n",
+ uuid, ret);
+ break;
+ }
}
+skip_pin:
+ if (found)
+ break;
}
- return reg;
+ return ret;
}
-static int o2hb_region_get(const char *region_uuid)
+/*
+ * In local heartbeat mode, region_uuid passed matches the dlm domain name.
+ * In global heartbeat mode, region_uuid passed is NULL.
+ *
+ * In local, we only unpin the matching region. In global we unpin all the
+ * active regions.
+ */
+static void o2hb_region_unpin(const char *region_uuid)
{
- int ret = 0;
struct o2hb_region *reg;
+ char *uuid;
+ int found = 0;
- spin_lock(&o2hb_live_lock);
+ assert_spin_locked(&o2hb_live_lock);
- reg = o2hb_find_region(region_uuid);
- if (!reg)
- ret = -ENOENT;
- spin_unlock(&o2hb_live_lock);
+ list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) {
+ uuid = config_item_name(&reg->hr_item);
+ if (region_uuid) {
+ if (strcmp(region_uuid, uuid))
+ continue;
+ found = 1;
+ }
- if (ret)
- goto out;
+ if (reg->hr_item_pinned) {
+ mlog(ML_CLUSTER, "Unpin region %s\n", uuid);
+ o2nm_undepend_item(&reg->hr_item);
+ reg->hr_item_pinned = 0;
+ }
+ if (found)
+ break;
+ }
+}
- ret = o2nm_depend_this_node();
- if (ret)
- goto out;
+static int o2hb_region_inc_user(const char *region_uuid)
+{
+ int ret = 0;
- ret = o2nm_depend_item(&reg->hr_item);
- if (ret)
- o2nm_undepend_this_node();
+ spin_lock(&o2hb_live_lock);
-out:
+ /* local heartbeat */
+ if (!o2hb_global_heartbeat_active()) {
+ ret = o2hb_region_pin(region_uuid);
+ goto unlock;
+ }
+
+ /*
+ * if global heartbeat active and this is the first dependent user,
+ * pin all regions if quorum region count <= CUT_OFF
+ */
+ o2hb_dependent_users++;
+ if (o2hb_dependent_users > 1)
+ goto unlock;
+
+ if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+ O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF)
+ ret = o2hb_region_pin(NULL);
+
+unlock:
+ spin_unlock(&o2hb_live_lock);
return ret;
}
-static void o2hb_region_put(const char *region_uuid)
+void o2hb_region_dec_user(const char *region_uuid)
{
- struct o2hb_region *reg;
-
spin_lock(&o2hb_live_lock);
- reg = o2hb_find_region(region_uuid);
+ /* local heartbeat */
+ if (!o2hb_global_heartbeat_active()) {
+ o2hb_region_unpin(region_uuid);
+ goto unlock;
+ }
- spin_unlock(&o2hb_live_lock);
+ /*
+ * if global heartbeat active and there are no dependent users,
+ * unpin all quorum regions
+ */
+ o2hb_dependent_users--;
+ if (!o2hb_dependent_users)
+ o2hb_region_unpin(NULL);
- if (reg) {
- o2nm_undepend_item(&reg->hr_item);
- o2nm_undepend_this_node();
- }
+unlock:
+ spin_unlock(&o2hb_live_lock);
}
int o2hb_register_callback(const char *region_uuid,
@@ -2286,9 +2460,11 @@ int o2hb_register_callback(const char *region_uuid,
}
if (region_uuid) {
- ret = o2hb_region_get(region_uuid);
- if (ret)
+ ret = o2hb_region_inc_user(region_uuid);
+ if (ret) {
+ mlog_errno(ret);
goto out;
+ }
}
down_write(&o2hb_callback_sem);
@@ -2306,7 +2482,7 @@ int o2hb_register_callback(const char *region_uuid,
up_write(&o2hb_callback_sem);
ret = 0;
out:
- mlog(ML_HEARTBEAT, "returning %d on behalf of %p for funcs %p\n",
+ mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n",
ret, __builtin_return_address(0), hc);
return ret;
}
@@ -2317,7 +2493,7 @@ void o2hb_unregister_callback(const char *region_uuid,
{
BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
- mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",
+ mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n",
__builtin_return_address(0), hc);
/* XXX Can this happen _with_ a region reference? */
@@ -2325,7 +2501,7 @@ void o2hb_unregister_callback(const char *region_uuid,
return;
if (region_uuid)
- o2hb_region_put(region_uuid);
+ o2hb_region_dec_user(region_uuid);
down_write(&o2hb_callback_sem);
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index c7fba396392d..6c61771469af 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -113,10 +113,11 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
define_mask(QUOTA),
define_mask(REFCOUNT),
define_mask(BASTS),
+ define_mask(RESERVATIONS),
+ define_mask(CLUSTER),
define_mask(ERROR),
define_mask(NOTICE),
define_mask(KTHREAD),
- define_mask(RESERVATIONS),
};
static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, };
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index ea2ed9f56c94..34d6544357d9 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -81,7 +81,7 @@
#include <linux/sched.h>
/* bits that are frequently given and infrequently matched in the low word */
-/* NOTE: If you add a flag, you need to also update mlog.c! */
+/* NOTE: If you add a flag, you need to also update masklog.c! */
#define ML_ENTRY 0x0000000000000001ULL /* func call entry */
#define ML_EXIT 0x0000000000000002ULL /* func call exit */
#define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */
@@ -114,13 +114,14 @@
#define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */
#define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */
#define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */
-#define ML_BASTS 0x0000001000000000ULL /* dlmglue asts and basts */
+#define ML_BASTS 0x0000000100000000ULL /* dlmglue asts and basts */
+#define ML_RESERVATIONS 0x0000000200000000ULL /* ocfs2 alloc reservations */
+#define ML_CLUSTER 0x0000000400000000ULL /* cluster stack */
+
/* bits that are infrequently given and frequently matched in the high word */
-#define ML_ERROR 0x0000000100000000ULL /* sent to KERN_ERR */
-#define ML_NOTICE 0x0000000200000000ULL /* setn to KERN_NOTICE */
-#define ML_KTHREAD 0x0000000400000000ULL /* kernel thread activity */
-#define ML_RESERVATIONS 0x0000000800000000ULL /* ocfs2 alloc reservations */
-#define ML_CLUSTER 0x0000001000000000ULL /* cluster stack */
+#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */
+#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */
+#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */
#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
#define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT)
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c
index a3f150e52b02..61df89cedded 100644
--- a/fs/ocfs2/cluster/netdebug.c
+++ b/fs/ocfs2/cluster/netdebug.c
@@ -46,10 +46,15 @@
#define O2NET_DEBUG_DIR "o2net"
#define SC_DEBUG_NAME "sock_containers"
#define NST_DEBUG_NAME "send_tracking"
+#define STATS_DEBUG_NAME "stats"
+
+#define SHOW_SOCK_CONTAINERS 0
+#define SHOW_SOCK_STATS 1
static struct dentry *o2net_dentry;
static struct dentry *sc_dentry;
static struct dentry *nst_dentry;
+static struct dentry *stats_dentry;
static DEFINE_SPINLOCK(o2net_debug_lock);
@@ -123,10 +128,17 @@ static void *nst_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static int nst_seq_show(struct seq_file *seq, void *v)
{
struct o2net_send_tracking *nst, *dummy_nst = seq->private;
+ ktime_t now;
+ s64 sock, send, status;
spin_lock(&o2net_debug_lock);
nst = next_nst(dummy_nst);
+ now = ktime_get();
+ sock = ktime_to_us(ktime_sub(now, nst->st_sock_time));
+ send = ktime_to_us(ktime_sub(now, nst->st_send_time));
+ status = ktime_to_us(ktime_sub(now, nst->st_status_time));
+
if (nst != NULL) {
/* get_task_comm isn't exported. oh well. */
seq_printf(seq, "%p:\n"
@@ -138,20 +150,17 @@ static int nst_seq_show(struct seq_file *seq, void *v)
" message id: %d\n"
" message type: %u\n"
" message key: 0x%08x\n"
- " sock acquiry: %lu.%ld\n"
- " send start: %lu.%ld\n"
- " wait start: %lu.%ld\n",
- nst, (unsigned long)nst->st_task->pid,
+ " sock acquiry: %lld usecs ago\n"
+ " send start: %lld usecs ago\n"
+ " wait start: %lld usecs ago\n",
+ nst, (unsigned long)task_pid_nr(nst->st_task),
(unsigned long)nst->st_task->tgid,
nst->st_task->comm, nst->st_node,
nst->st_sc, nst->st_id, nst->st_msg_type,
nst->st_msg_key,
- nst->st_sock_time.tv_sec,
- (long)nst->st_sock_time.tv_usec,
- nst->st_send_time.tv_sec,
- (long)nst->st_send_time.tv_usec,
- nst->st_status_time.tv_sec,
- (long)nst->st_status_time.tv_usec);
+ (long long)sock,
+ (long long)send,
+ (long long)status);
}
spin_unlock(&o2net_debug_lock);
@@ -228,6 +237,11 @@ void o2net_debug_del_sc(struct o2net_sock_container *sc)
spin_unlock(&o2net_debug_lock);
}
+struct o2net_sock_debug {
+ int dbg_ctxt;
+ struct o2net_sock_container *dbg_sock;
+};
+
static struct o2net_sock_container
*next_sc(struct o2net_sock_container *sc_start)
{
@@ -253,7 +267,8 @@ static struct o2net_sock_container
static void *sc_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct o2net_sock_container *sc, *dummy_sc = seq->private;
+ struct o2net_sock_debug *sd = seq->private;
+ struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
spin_lock(&o2net_debug_lock);
sc = next_sc(dummy_sc);
@@ -264,7 +279,8 @@ static void *sc_seq_start(struct seq_file *seq, loff_t *pos)
static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct o2net_sock_container *sc, *dummy_sc = seq->private;
+ struct o2net_sock_debug *sd = seq->private;
+ struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
spin_lock(&o2net_debug_lock);
sc = next_sc(dummy_sc);
@@ -276,65 +292,107 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
return sc; /* unused, just needs to be null when done */
}
-#define TV_SEC_USEC(TV) TV.tv_sec, (long)TV.tv_usec
+#ifdef CONFIG_OCFS2_FS_STATS
+# define sc_send_count(_s) ((_s)->sc_send_count)
+# define sc_recv_count(_s) ((_s)->sc_recv_count)
+# define sc_tv_acquiry_total_ns(_s) (ktime_to_ns((_s)->sc_tv_acquiry_total))
+# define sc_tv_send_total_ns(_s) (ktime_to_ns((_s)->sc_tv_send_total))
+# define sc_tv_status_total_ns(_s) (ktime_to_ns((_s)->sc_tv_status_total))
+# define sc_tv_process_total_ns(_s) (ktime_to_ns((_s)->sc_tv_process_total))
+#else
+# define sc_send_count(_s) (0U)
+# define sc_recv_count(_s) (0U)
+# define sc_tv_acquiry_total_ns(_s) (0LL)
+# define sc_tv_send_total_ns(_s) (0LL)
+# define sc_tv_status_total_ns(_s) (0LL)
+# define sc_tv_process_total_ns(_s) (0LL)
+#endif
+
+/* So that debugfs.ocfs2 can determine which format is being used */
+#define O2NET_STATS_STR_VERSION 1
+static void sc_show_sock_stats(struct seq_file *seq,
+ struct o2net_sock_container *sc)
+{
+ if (!sc)
+ return;
+
+ seq_printf(seq, "%d,%u,%lu,%lld,%lld,%lld,%lu,%lld\n", O2NET_STATS_STR_VERSION,
+ sc->sc_node->nd_num, (unsigned long)sc_send_count(sc),
+ (long long)sc_tv_acquiry_total_ns(sc),
+ (long long)sc_tv_send_total_ns(sc),
+ (long long)sc_tv_status_total_ns(sc),
+ (unsigned long)sc_recv_count(sc),
+ (long long)sc_tv_process_total_ns(sc));
+}
+
+static void sc_show_sock_container(struct seq_file *seq,
+ struct o2net_sock_container *sc)
+{
+ struct inet_sock *inet = NULL;
+ __be32 saddr = 0, daddr = 0;
+ __be16 sport = 0, dport = 0;
+
+ if (!sc)
+ return;
+
+ if (sc->sc_sock) {
+ inet = inet_sk(sc->sc_sock->sk);
+ /* the stack's structs aren't sparse endian clean */
+ saddr = (__force __be32)inet->inet_saddr;
+ daddr = (__force __be32)inet->inet_daddr;
+ sport = (__force __be16)inet->inet_sport;
+ dport = (__force __be16)inet->inet_dport;
+ }
+
+ /* XXX sigh, inet-> doesn't have sparse annotation so any
+ * use of it here generates a warning with -Wbitwise */
+ seq_printf(seq, "%p:\n"
+ " krefs: %d\n"
+ " sock: %pI4:%u -> "
+ "%pI4:%u\n"
+ " remote node: %s\n"
+ " page off: %zu\n"
+ " handshake ok: %u\n"
+ " timer: %lld usecs\n"
+ " data ready: %lld usecs\n"
+ " advance start: %lld usecs\n"
+ " advance stop: %lld usecs\n"
+ " func start: %lld usecs\n"
+ " func stop: %lld usecs\n"
+ " func key: 0x%08x\n"
+ " func type: %u\n",
+ sc,
+ atomic_read(&sc->sc_kref.refcount),
+ &saddr, inet ? ntohs(sport) : 0,
+ &daddr, inet ? ntohs(dport) : 0,
+ sc->sc_node->nd_name,
+ sc->sc_page_off,
+ sc->sc_handshake_ok,
+ (long long)ktime_to_us(sc->sc_tv_timer),
+ (long long)ktime_to_us(sc->sc_tv_data_ready),
+ (long long)ktime_to_us(sc->sc_tv_advance_start),
+ (long long)ktime_to_us(sc->sc_tv_advance_stop),
+ (long long)ktime_to_us(sc->sc_tv_func_start),
+ (long long)ktime_to_us(sc->sc_tv_func_stop),
+ sc->sc_msg_key,
+ sc->sc_msg_type);
+}
static int sc_seq_show(struct seq_file *seq, void *v)
{
- struct o2net_sock_container *sc, *dummy_sc = seq->private;
+ struct o2net_sock_debug *sd = seq->private;
+ struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
spin_lock(&o2net_debug_lock);
sc = next_sc(dummy_sc);
- if (sc != NULL) {
- struct inet_sock *inet = NULL;
-
- __be32 saddr = 0, daddr = 0;
- __be16 sport = 0, dport = 0;
-
- if (sc->sc_sock) {
- inet = inet_sk(sc->sc_sock->sk);
- /* the stack's structs aren't sparse endian clean */
- saddr = (__force __be32)inet->inet_saddr;
- daddr = (__force __be32)inet->inet_daddr;
- sport = (__force __be16)inet->inet_sport;
- dport = (__force __be16)inet->inet_dport;
- }
-
- /* XXX sigh, inet-> doesn't have sparse annotation so any
- * use of it here generates a warning with -Wbitwise */
- seq_printf(seq, "%p:\n"
- " krefs: %d\n"
- " sock: %pI4:%u -> "
- "%pI4:%u\n"
- " remote node: %s\n"
- " page off: %zu\n"
- " handshake ok: %u\n"
- " timer: %lu.%ld\n"
- " data ready: %lu.%ld\n"
- " advance start: %lu.%ld\n"
- " advance stop: %lu.%ld\n"
- " func start: %lu.%ld\n"
- " func stop: %lu.%ld\n"
- " func key: %u\n"
- " func type: %u\n",
- sc,
- atomic_read(&sc->sc_kref.refcount),
- &saddr, inet ? ntohs(sport) : 0,
- &daddr, inet ? ntohs(dport) : 0,
- sc->sc_node->nd_name,
- sc->sc_page_off,
- sc->sc_handshake_ok,
- TV_SEC_USEC(sc->sc_tv_timer),
- TV_SEC_USEC(sc->sc_tv_data_ready),
- TV_SEC_USEC(sc->sc_tv_advance_start),
- TV_SEC_USEC(sc->sc_tv_advance_stop),
- TV_SEC_USEC(sc->sc_tv_func_start),
- TV_SEC_USEC(sc->sc_tv_func_stop),
- sc->sc_msg_key,
- sc->sc_msg_type);
+ if (sc) {
+ if (sd->dbg_ctxt == SHOW_SOCK_CONTAINERS)
+ sc_show_sock_container(seq, sc);
+ else
+ sc_show_sock_stats(seq, sc);
}
-
spin_unlock(&o2net_debug_lock);
return 0;
@@ -351,7 +409,7 @@ static const struct seq_operations sc_seq_ops = {
.show = sc_seq_show,
};
-static int sc_fop_open(struct inode *inode, struct file *file)
+static int sc_common_open(struct file *file, struct o2net_sock_debug *sd)
{
struct o2net_sock_container *dummy_sc;
struct seq_file *seq;
@@ -369,7 +427,8 @@ static int sc_fop_open(struct inode *inode, struct file *file)
goto out;
seq = file->private_data;
- seq->private = dummy_sc;
+ seq->private = sd;
+ sd->dbg_sock = dummy_sc;
o2net_debug_add_sc(dummy_sc);
dummy_sc = NULL;
@@ -382,12 +441,48 @@ out:
static int sc_fop_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = file->private_data;
- struct o2net_sock_container *dummy_sc = seq->private;
+ struct o2net_sock_debug *sd = seq->private;
+ struct o2net_sock_container *dummy_sc = sd->dbg_sock;
o2net_debug_del_sc(dummy_sc);
return seq_release_private(inode, file);
}
+static int stats_fop_open(struct inode *inode, struct file *file)
+{
+ struct o2net_sock_debug *sd;
+
+ sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+
+ sd->dbg_ctxt = SHOW_SOCK_STATS;
+ sd->dbg_sock = NULL;
+
+ return sc_common_open(file, sd);
+}
+
+static const struct file_operations stats_seq_fops = {
+ .open = stats_fop_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = sc_fop_release,
+};
+
+static int sc_fop_open(struct inode *inode, struct file *file)
+{
+ struct o2net_sock_debug *sd;
+
+ sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+
+ sd->dbg_ctxt = SHOW_SOCK_CONTAINERS;
+ sd->dbg_sock = NULL;
+
+ return sc_common_open(file, sd);
+}
+
static const struct file_operations sc_seq_fops = {
.open = sc_fop_open,
.read = seq_read,
@@ -419,25 +514,29 @@ int o2net_debugfs_init(void)
goto bail;
}
+ stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
+ o2net_dentry, NULL,
+ &stats_seq_fops);
+ if (!stats_dentry) {
+ mlog_errno(-ENOMEM);
+ goto bail;
+ }
+
return 0;
bail:
- if (sc_dentry)
- debugfs_remove(sc_dentry);
- if (nst_dentry)
- debugfs_remove(nst_dentry);
- if (o2net_dentry)
- debugfs_remove(o2net_dentry);
+ debugfs_remove(stats_dentry);
+ debugfs_remove(sc_dentry);
+ debugfs_remove(nst_dentry);
+ debugfs_remove(o2net_dentry);
return -ENOMEM;
}
void o2net_debugfs_exit(void)
{
- if (sc_dentry)
- debugfs_remove(sc_dentry);
- if (nst_dentry)
- debugfs_remove(nst_dentry);
- if (o2net_dentry)
- debugfs_remove(o2net_dentry);
+ debugfs_remove(stats_dentry);
+ debugfs_remove(sc_dentry);
+ debugfs_remove(nst_dentry);
+ debugfs_remove(o2net_dentry);
}
#endif /* CONFIG_DEBUG_FS */
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 9aa426e42123..bc2309554d0b 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -153,63 +153,112 @@ static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
nst->st_node = node;
}
-static void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
{
- do_gettimeofday(&nst->st_sock_time);
+ nst->st_sock_time = ktime_get();
}
-static void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
{
- do_gettimeofday(&nst->st_send_time);
+ nst->st_send_time = ktime_get();
}
-static void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
{
- do_gettimeofday(&nst->st_status_time);
+ nst->st_status_time = ktime_get();
}
-static void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
- struct o2net_sock_container *sc)
+static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
+ struct o2net_sock_container *sc)
{
nst->st_sc = sc;
}
-static void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id)
+static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst,
+ u32 msg_id)
{
nst->st_id = msg_id;
}
-#else /* CONFIG_DEBUG_FS */
-
-static inline void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
- u32 msgkey, struct task_struct *task, u8 node)
+static inline void o2net_set_sock_timer(struct o2net_sock_container *sc)
{
+ sc->sc_tv_timer = ktime_get();
}
-static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_data_ready_time(struct o2net_sock_container *sc)
{
+ sc->sc_tv_data_ready = ktime_get();
}
-static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_advance_start_time(struct o2net_sock_container *sc)
{
+ sc->sc_tv_advance_start = ktime_get();
}
-static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
+static inline void o2net_set_advance_stop_time(struct o2net_sock_container *sc)
{
+ sc->sc_tv_advance_stop = ktime_get();
}
-static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
- struct o2net_sock_container *sc)
+static inline void o2net_set_func_start_time(struct o2net_sock_container *sc)
{
+ sc->sc_tv_func_start = ktime_get();
}
-static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst,
- u32 msg_id)
+static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc)
{
+ sc->sc_tv_func_stop = ktime_get();
}
+static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc)
+{
+ return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start);
+}
+#else /* CONFIG_DEBUG_FS */
+# define o2net_init_nst(a, b, c, d, e)
+# define o2net_set_nst_sock_time(a)
+# define o2net_set_nst_send_time(a)
+# define o2net_set_nst_status_time(a)
+# define o2net_set_nst_sock_container(a, b)
+# define o2net_set_nst_msg_id(a, b)
+# define o2net_set_sock_timer(a)
+# define o2net_set_data_ready_time(a)
+# define o2net_set_advance_start_time(a)
+# define o2net_set_advance_stop_time(a)
+# define o2net_set_func_start_time(a)
+# define o2net_set_func_stop_time(a)
+# define o2net_get_func_run_time(a) (ktime_t)0
#endif /* CONFIG_DEBUG_FS */
+#ifdef CONFIG_OCFS2_FS_STATS
+static void o2net_update_send_stats(struct o2net_send_tracking *nst,
+ struct o2net_sock_container *sc)
+{
+ sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total,
+ ktime_sub(ktime_get(),
+ nst->st_status_time));
+ sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total,
+ ktime_sub(nst->st_status_time,
+ nst->st_send_time));
+ sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total,
+ ktime_sub(nst->st_send_time,
+ nst->st_sock_time));
+ sc->sc_send_count++;
+}
+
+static void o2net_update_recv_stats(struct o2net_sock_container *sc)
+{
+ sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total,
+ o2net_get_func_run_time(sc));
+ sc->sc_recv_count++;
+}
+
+#else
+
+# define o2net_update_send_stats(a, b)
+
+#endif /* CONFIG_OCFS2_FS_STATS */
+
static inline int o2net_reconnect_delay(void)
{
return o2nm_single_cluster->cl_reconnect_delay_ms;
@@ -355,6 +404,7 @@ static void sc_kref_release(struct kref *kref)
sc->sc_sock = NULL;
}
+ o2nm_undepend_item(&sc->sc_node->nd_item);
o2nm_node_put(sc->sc_node);
sc->sc_node = NULL;
@@ -376,6 +426,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
{
struct o2net_sock_container *sc, *ret = NULL;
struct page *page = NULL;
+ int status = 0;
page = alloc_page(GFP_NOFS);
sc = kzalloc(sizeof(*sc), GFP_NOFS);
@@ -386,6 +437,13 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
o2nm_node_get(node);
sc->sc_node = node;
+ /* pin the node item of the remote node */
+ status = o2nm_depend_item(&node->nd_item);
+ if (status) {
+ mlog_errno(status);
+ o2nm_node_put(node);
+ goto out;
+ }
INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed);
INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty);
INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc);
@@ -546,7 +604,7 @@ static void o2net_data_ready(struct sock *sk, int bytes)
if (sk->sk_user_data) {
struct o2net_sock_container *sc = sk->sk_user_data;
sclog(sc, "data_ready hit\n");
- do_gettimeofday(&sc->sc_tv_data_ready);
+ o2net_set_data_ready_time(sc);
o2net_sc_queue_work(sc, &sc->sc_rx_work);
ready = sc->sc_data_ready;
} else {
@@ -1070,6 +1128,8 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
o2net_set_nst_status_time(&nst);
wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw));
+ o2net_update_send_stats(&nst, sc);
+
/* Note that we avoid overwriting the callers status return
* variable if a system error was reported on the other
* side. Callers beware. */
@@ -1183,13 +1243,15 @@ static int o2net_process_message(struct o2net_sock_container *sc,
if (syserr != O2NET_ERR_NONE)
goto out_respond;
- do_gettimeofday(&sc->sc_tv_func_start);
+ o2net_set_func_start_time(sc);
sc->sc_msg_key = be32_to_cpu(hdr->key);
sc->sc_msg_type = be16_to_cpu(hdr->msg_type);
handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) +
be16_to_cpu(hdr->data_len),
nmh->nh_func_data, &ret_data);
- do_gettimeofday(&sc->sc_tv_func_stop);
+ o2net_set_func_stop_time(sc);
+
+ o2net_update_recv_stats(sc);
out_respond:
/* this destroys the hdr, so don't use it after this */
@@ -1300,7 +1362,7 @@ static int o2net_advance_rx(struct o2net_sock_container *sc)
size_t datalen;
sclog(sc, "receiving\n");
- do_gettimeofday(&sc->sc_tv_advance_start);
+ o2net_set_advance_start_time(sc);
if (unlikely(sc->sc_handshake_ok == 0)) {
if(sc->sc_page_off < sizeof(struct o2net_handshake)) {
@@ -1375,7 +1437,7 @@ static int o2net_advance_rx(struct o2net_sock_container *sc)
out:
sclog(sc, "ret = %d\n", ret);
- do_gettimeofday(&sc->sc_tv_advance_stop);
+ o2net_set_advance_stop_time(sc);
return ret;
}
@@ -1475,27 +1537,28 @@ static void o2net_idle_timer(unsigned long data)
{
struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
- struct timeval now;
- do_gettimeofday(&now);
+#ifdef CONFIG_DEBUG_FS
+ ktime_t now = ktime_get();
+#endif
printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
"seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
o2net_idle_timeout() / 1000,
o2net_idle_timeout() % 1000);
- mlog(ML_NOTICE, "here are some times that might help debug the "
- "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
- "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n",
- sc->sc_tv_timer.tv_sec, (long) sc->sc_tv_timer.tv_usec,
- now.tv_sec, (long) now.tv_usec,
- sc->sc_tv_data_ready.tv_sec, (long) sc->sc_tv_data_ready.tv_usec,
- sc->sc_tv_advance_start.tv_sec,
- (long) sc->sc_tv_advance_start.tv_usec,
- sc->sc_tv_advance_stop.tv_sec,
- (long) sc->sc_tv_advance_stop.tv_usec,
+
+#ifdef CONFIG_DEBUG_FS
+ mlog(ML_NOTICE, "Here are some times that might help debug the "
+ "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, "
+ "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n",
+ (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now),
+ (long long)ktime_to_us(sc->sc_tv_data_ready),
+ (long long)ktime_to_us(sc->sc_tv_advance_start),
+ (long long)ktime_to_us(sc->sc_tv_advance_stop),
sc->sc_msg_key, sc->sc_msg_type,
- sc->sc_tv_func_start.tv_sec, (long) sc->sc_tv_func_start.tv_usec,
- sc->sc_tv_func_stop.tv_sec, (long) sc->sc_tv_func_stop.tv_usec);
+ (long long)ktime_to_us(sc->sc_tv_func_start),
+ (long long)ktime_to_us(sc->sc_tv_func_stop));
+#endif
/*
* Initialize the nn_timeout so that the next connection attempt
@@ -1511,7 +1574,7 @@ static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc)
o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work,
msecs_to_jiffies(o2net_keepalive_delay()));
- do_gettimeofday(&sc->sc_tv_timer);
+ o2net_set_sock_timer(sc);
mod_timer(&sc->sc_idle_timeout,
jiffies + msecs_to_jiffies(o2net_idle_timeout()));
}
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h
index 15fdbdf9eb4b..4cbcb65784a3 100644
--- a/fs/ocfs2/cluster/tcp_internal.h
+++ b/fs/ocfs2/cluster/tcp_internal.h
@@ -166,18 +166,27 @@ struct o2net_sock_container {
/* original handlers for the sockets */
void (*sc_state_change)(struct sock *sk);
void (*sc_data_ready)(struct sock *sk, int bytes);
-#ifdef CONFIG_DEBUG_FS
- struct list_head sc_net_debug_item;
-#endif
- struct timeval sc_tv_timer;
- struct timeval sc_tv_data_ready;
- struct timeval sc_tv_advance_start;
- struct timeval sc_tv_advance_stop;
- struct timeval sc_tv_func_start;
- struct timeval sc_tv_func_stop;
+
u32 sc_msg_key;
u16 sc_msg_type;
+#ifdef CONFIG_DEBUG_FS
+ struct list_head sc_net_debug_item;
+ ktime_t sc_tv_timer;
+ ktime_t sc_tv_data_ready;
+ ktime_t sc_tv_advance_start;
+ ktime_t sc_tv_advance_stop;
+ ktime_t sc_tv_func_start;
+ ktime_t sc_tv_func_stop;
+#endif
+#ifdef CONFIG_OCFS2_FS_STATS
+ ktime_t sc_tv_acquiry_total;
+ ktime_t sc_tv_send_total;
+ ktime_t sc_tv_status_total;
+ u32 sc_send_count;
+ u32 sc_recv_count;
+ ktime_t sc_tv_process_total;
+#endif
struct mutex sc_send_lock;
};
@@ -220,9 +229,9 @@ struct o2net_send_tracking {
u32 st_msg_type;
u32 st_msg_key;
u8 st_node;
- struct timeval st_sock_time;
- struct timeval st_send_time;
- struct timeval st_status_time;
+ ktime_t st_sock_time;
+ ktime_t st_send_time;
+ ktime_t st_status_time;
};
#else
struct o2net_send_tracking {
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index edaded48e7e9..b4d3fe9c1c5c 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -169,23 +169,25 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
struct list_head *p;
struct dentry *dentry = NULL;
- spin_lock(&dcache_lock);
-
+ spin_lock(&inode->i_lock);
list_for_each(p, &inode->i_dentry) {
dentry = list_entry(p, struct dentry, d_alias);
+ spin_lock(&dentry->d_lock);
if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
mlog(0, "dentry found: %.*s\n",
dentry->d_name.len, dentry->d_name.name);
- dget_locked(dentry);
+ dget_dlock(dentry);
+ spin_unlock(&dentry->d_lock);
break;
}
+ spin_unlock(&dentry->d_lock);
dentry = NULL;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
return dentry;
}
@@ -476,7 +478,6 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
out:
iput(inode);
- ocfs2_dentry_attach_gen(dentry);
}
/*
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index c49f6de0e7ab..d417b3f9b0c7 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -2461,8 +2461,10 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
di->i_dx_root = cpu_to_le64(dr_blkno);
+ spin_lock(&OCFS2_I(dir)->ip_lock);
OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL;
di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+ spin_unlock(&OCFS2_I(dir)->ip_lock);
ocfs2_journal_dirty(handle, di_bh);
@@ -4466,8 +4468,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir,
goto out_commit;
}
+ spin_lock(&OCFS2_I(dir)->ip_lock);
OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL;
di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+ spin_unlock(&OCFS2_I(dir)->ip_lock);
di->i_dx_root = cpu_to_le64(0ULL);
ocfs2_journal_dirty(handle, di_bh);
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index f44999156839..3a3ed4bb794b 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -90,19 +90,29 @@ static int dlm_should_cancel_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
{
- mlog_entry_void();
+ struct dlm_lock_resource *res;
BUG_ON(!dlm);
BUG_ON(!lock);
+ res = lock->lockres;
+
assert_spin_locked(&dlm->ast_lock);
+
if (!list_empty(&lock->ast_list)) {
- mlog(ML_ERROR, "ast list not empty!! pending=%d, newlevel=%d\n",
+ mlog(ML_ERROR, "%s: res %.*s, lock %u:%llu, "
+ "AST list not empty, pending %d, newlevel %d\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
lock->ast_pending, lock->ml.type);
BUG();
}
if (lock->ast_pending)
- mlog(0, "lock has an ast getting flushed right now\n");
+ mlog(0, "%s: res %.*s, lock %u:%llu, AST getting flushed\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
/* putting lock on list, add a ref */
dlm_lock_get(lock);
@@ -110,9 +120,10 @@ void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
/* check to see if this ast obsoletes the bast */
if (dlm_should_cancel_bast(dlm, lock)) {
- struct dlm_lock_resource *res = lock->lockres;
- mlog(0, "%s: cancelling bast for %.*s\n",
- dlm->name, res->lockname.len, res->lockname.name);
+ mlog(0, "%s: res %.*s, lock %u:%llu, Cancelling BAST\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
lock->bast_pending = 0;
list_del_init(&lock->bast_list);
lock->ml.highest_blocked = LKM_IVMODE;
@@ -134,8 +145,6 @@ void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
{
- mlog_entry_void();
-
BUG_ON(!dlm);
BUG_ON(!lock);
@@ -147,15 +156,21 @@ void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
{
- mlog_entry_void();
+ struct dlm_lock_resource *res;
BUG_ON(!dlm);
BUG_ON(!lock);
+
assert_spin_locked(&dlm->ast_lock);
+ res = lock->lockres;
+
BUG_ON(!list_empty(&lock->bast_list));
if (lock->bast_pending)
- mlog(0, "lock has a bast getting flushed right now\n");
+ mlog(0, "%s: res %.*s, lock %u:%llu, BAST getting flushed\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
/* putting lock on list, add a ref */
dlm_lock_get(lock);
@@ -167,8 +182,6 @@ void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
{
- mlog_entry_void();
-
BUG_ON(!dlm);
BUG_ON(!lock);
@@ -213,7 +226,10 @@ void dlm_do_local_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
dlm_astlockfunc_t *fn;
struct dlm_lockstatus *lksb;
- mlog_entry_void();
+ mlog(0, "%s: res %.*s, lock %u:%llu, Local AST\n", dlm->name,
+ res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
lksb = lock->lksb;
fn = lock->ast;
@@ -231,7 +247,10 @@ int dlm_do_remote_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
struct dlm_lockstatus *lksb;
int lksbflags;
- mlog_entry_void();
+ mlog(0, "%s: res %.*s, lock %u:%llu, Remote AST\n", dlm->name,
+ res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
lksb = lock->lksb;
BUG_ON(lock->ml.node == dlm->node_num);
@@ -250,9 +269,14 @@ void dlm_do_local_bast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
{
dlm_bastlockfunc_t *fn = lock->bast;
- mlog_entry_void();
BUG_ON(lock->ml.node != dlm->node_num);
+ mlog(0, "%s: res %.*s, lock %u:%llu, Local BAST, blocked %d\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+ blocked_type);
+
(*fn)(lock->astdata, blocked_type);
}
@@ -332,7 +356,8 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
/* cannot get a proxy ast message if this node owns it */
BUG_ON(res->owner == dlm->node_num);
- mlog(0, "lockres %.*s\n", res->lockname.len, res->lockname.name);
+ mlog(0, "%s: res %.*s\n", dlm->name, res->lockname.len,
+ res->lockname.name);
spin_lock(&res->spinlock);
if (res->state & DLM_LOCK_RES_RECOVERING) {
@@ -382,8 +407,12 @@ do_ast:
if (past->type == DLM_AST) {
/* do not alter lock refcount. switching lists. */
list_move_tail(&lock->list, &res->granted);
- mlog(0, "ast: Adding to granted list... type=%d, "
- "convert_type=%d\n", lock->ml.type, lock->ml.convert_type);
+ mlog(0, "%s: res %.*s, lock %u:%llu, Granted type %d => %d\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(cookie)),
+ lock->ml.type, lock->ml.convert_type);
+
if (lock->ml.convert_type != LKM_IVMODE) {
lock->ml.type = lock->ml.convert_type;
lock->ml.convert_type = LKM_IVMODE;
@@ -426,9 +455,9 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
size_t veclen = 1;
int status;
- mlog_entry("res %.*s, to=%u, type=%d, blocked_type=%d\n",
- res->lockname.len, res->lockname.name, lock->ml.node,
- msg_type, blocked_type);
+ mlog(0, "%s: res %.*s, to %u, type %d, blocked_type %d\n", dlm->name,
+ res->lockname.len, res->lockname.name, lock->ml.node, msg_type,
+ blocked_type);
memset(&past, 0, sizeof(struct dlm_proxy_ast));
past.node_idx = dlm->node_num;
@@ -441,7 +470,6 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
vec[0].iov_len = sizeof(struct dlm_proxy_ast);
vec[0].iov_base = &past;
if (flags & DLM_LKSB_GET_LVB) {
- mlog(0, "returning requested LVB data\n");
be32_add_cpu(&past.flags, LKM_GET_LVB);
vec[1].iov_len = DLM_LVB_LEN;
vec[1].iov_base = lock->lksb->lvb;
@@ -451,8 +479,8 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
ret = o2net_send_message_vec(DLM_PROXY_AST_MSG, dlm->key, vec, veclen,
lock->ml.node, &status);
if (ret < 0)
- mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
- "node %u\n", ret, DLM_PROXY_AST_MSG, dlm->key,
+ mlog(ML_ERROR, "%s: res %.*s, error %d send AST to node %u\n",
+ dlm->name, res->lockname.len, res->lockname.name, ret,
lock->ml.node);
else {
if (status == DLM_RECOVERING) {
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index b36d0bf77a5a..4bdf7baee344 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -50,10 +50,10 @@
#define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l)
enum dlm_mle_type {
- DLM_MLE_BLOCK,
- DLM_MLE_MASTER,
- DLM_MLE_MIGRATION,
- DLM_MLE_NUM_TYPES
+ DLM_MLE_BLOCK = 0,
+ DLM_MLE_MASTER = 1,
+ DLM_MLE_MIGRATION = 2,
+ DLM_MLE_NUM_TYPES = 3,
};
struct dlm_master_list_entry {
@@ -82,8 +82,8 @@ struct dlm_master_list_entry {
enum dlm_ast_type {
DLM_AST = 0,
- DLM_BAST,
- DLM_ASTUNLOCK
+ DLM_BAST = 1,
+ DLM_ASTUNLOCK = 2,
};
@@ -119,9 +119,9 @@ struct dlm_recovery_ctxt
enum dlm_ctxt_state {
DLM_CTXT_NEW = 0,
- DLM_CTXT_JOINED,
- DLM_CTXT_IN_SHUTDOWN,
- DLM_CTXT_LEAVING,
+ DLM_CTXT_JOINED = 1,
+ DLM_CTXT_IN_SHUTDOWN = 2,
+ DLM_CTXT_LEAVING = 3,
};
struct dlm_ctxt
@@ -388,8 +388,8 @@ struct dlm_lock
enum dlm_lockres_list {
DLM_GRANTED_LIST = 0,
- DLM_CONVERTING_LIST,
- DLM_BLOCKED_LIST
+ DLM_CONVERTING_LIST = 1,
+ DLM_BLOCKED_LIST = 2,
};
static inline int dlm_lvb_is_empty(char *lvb)
@@ -427,27 +427,27 @@ struct dlm_node_iter
enum {
- DLM_MASTER_REQUEST_MSG = 500,
- DLM_UNUSED_MSG1, /* 501 */
- DLM_ASSERT_MASTER_MSG, /* 502 */
- DLM_CREATE_LOCK_MSG, /* 503 */
- DLM_CONVERT_LOCK_MSG, /* 504 */
- DLM_PROXY_AST_MSG, /* 505 */
- DLM_UNLOCK_LOCK_MSG, /* 506 */
- DLM_DEREF_LOCKRES_MSG, /* 507 */
- DLM_MIGRATE_REQUEST_MSG, /* 508 */
- DLM_MIG_LOCKRES_MSG, /* 509 */
- DLM_QUERY_JOIN_MSG, /* 510 */
- DLM_ASSERT_JOINED_MSG, /* 511 */
- DLM_CANCEL_JOIN_MSG, /* 512 */
- DLM_EXIT_DOMAIN_MSG, /* 513 */
- DLM_MASTER_REQUERY_MSG, /* 514 */
- DLM_LOCK_REQUEST_MSG, /* 515 */
- DLM_RECO_DATA_DONE_MSG, /* 516 */
- DLM_BEGIN_RECO_MSG, /* 517 */
- DLM_FINALIZE_RECO_MSG, /* 518 */
- DLM_QUERY_REGION, /* 519 */
- DLM_QUERY_NODEINFO, /* 520 */
+ DLM_MASTER_REQUEST_MSG = 500,
+ DLM_UNUSED_MSG1 = 501,
+ DLM_ASSERT_MASTER_MSG = 502,
+ DLM_CREATE_LOCK_MSG = 503,
+ DLM_CONVERT_LOCK_MSG = 504,
+ DLM_PROXY_AST_MSG = 505,
+ DLM_UNLOCK_LOCK_MSG = 506,
+ DLM_DEREF_LOCKRES_MSG = 507,
+ DLM_MIGRATE_REQUEST_MSG = 508,
+ DLM_MIG_LOCKRES_MSG = 509,
+ DLM_QUERY_JOIN_MSG = 510,
+ DLM_ASSERT_JOINED_MSG = 511,
+ DLM_CANCEL_JOIN_MSG = 512,
+ DLM_EXIT_DOMAIN_MSG = 513,
+ DLM_MASTER_REQUERY_MSG = 514,
+ DLM_LOCK_REQUEST_MSG = 515,
+ DLM_RECO_DATA_DONE_MSG = 516,
+ DLM_BEGIN_RECO_MSG = 517,
+ DLM_FINALIZE_RECO_MSG = 518,
+ DLM_QUERY_REGION = 519,
+ DLM_QUERY_NODEINFO = 520,
};
struct dlm_reco_node_data
@@ -460,19 +460,19 @@ struct dlm_reco_node_data
enum {
DLM_RECO_NODE_DATA_DEAD = -1,
DLM_RECO_NODE_DATA_INIT = 0,
- DLM_RECO_NODE_DATA_REQUESTING,
- DLM_RECO_NODE_DATA_REQUESTED,
- DLM_RECO_NODE_DATA_RECEIVING,
- DLM_RECO_NODE_DATA_DONE,
- DLM_RECO_NODE_DATA_FINALIZE_SENT,
+ DLM_RECO_NODE_DATA_REQUESTING = 1,
+ DLM_RECO_NODE_DATA_REQUESTED = 2,
+ DLM_RECO_NODE_DATA_RECEIVING = 3,
+ DLM_RECO_NODE_DATA_DONE = 4,
+ DLM_RECO_NODE_DATA_FINALIZE_SENT = 5,
};
enum {
DLM_MASTER_RESP_NO = 0,
- DLM_MASTER_RESP_YES,
- DLM_MASTER_RESP_MAYBE,
- DLM_MASTER_RESP_ERROR
+ DLM_MASTER_RESP_YES = 1,
+ DLM_MASTER_RESP_MAYBE = 2,
+ DLM_MASTER_RESP_ERROR = 3,
};
@@ -649,9 +649,9 @@ struct dlm_proxy_ast
#define DLM_MOD_KEY (0x666c6172)
enum dlm_query_join_response_code {
JOIN_DISALLOW = 0,
- JOIN_OK,
- JOIN_OK_NO_MAP,
- JOIN_PROTOCOL_MISMATCH,
+ JOIN_OK = 1,
+ JOIN_OK_NO_MAP = 2,
+ JOIN_PROTOCOL_MISMATCH = 3,
};
struct dlm_query_join_packet {
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 272ec8631a51..04a32be0aeb9 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -370,92 +370,46 @@ static void dlm_debug_get(struct dlm_debug_ctxt *dc)
kref_get(&dc->debug_refcnt);
}
-static struct debug_buffer *debug_buffer_allocate(void)
+static int debug_release(struct inode *inode, struct file *file)
{
- struct debug_buffer *db = NULL;
-
- db = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
- if (!db)
- goto bail;
-
- db->len = PAGE_SIZE;
- db->buf = kmalloc(db->len, GFP_KERNEL);
- if (!db->buf)
- goto bail;
-
- return db;
-bail:
- kfree(db);
- return NULL;
-}
-
-static ssize_t debug_buffer_read(struct file *file, char __user *buf,
- size_t nbytes, loff_t *ppos)
-{
- struct debug_buffer *db = file->private_data;
-
- return simple_read_from_buffer(buf, nbytes, ppos, db->buf, db->len);
-}
-
-static loff_t debug_buffer_llseek(struct file *file, loff_t off, int whence)
-{
- struct debug_buffer *db = file->private_data;
- loff_t new = -1;
-
- switch (whence) {
- case 0:
- new = off;
- break;
- case 1:
- new = file->f_pos + off;
- break;
- }
-
- if (new < 0 || new > db->len)
- return -EINVAL;
-
- return (file->f_pos = new);
+ free_page((unsigned long)file->private_data);
+ return 0;
}
-static int debug_buffer_release(struct inode *inode, struct file *file)
+static ssize_t debug_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
{
- struct debug_buffer *db = file->private_data;
-
- if (db)
- kfree(db->buf);
- kfree(db);
-
- return 0;
+ return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+ i_size_read(file->f_mapping->host));
}
/* end - util funcs */
/* begin - purge list funcs */
-static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+static int debug_purgelist_print(struct dlm_ctxt *dlm, char *buf, int len)
{
struct dlm_lock_resource *res;
int out = 0;
unsigned long total = 0;
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Dumping Purgelist for Domain: %s\n", dlm->name);
spin_lock(&dlm->spinlock);
list_for_each_entry(res, &dlm->purge_list, purge) {
++total;
- if (db->len - out < 100)
+ if (len - out < 100)
continue;
spin_lock(&res->spinlock);
out += stringify_lockname(res->lockname.name,
res->lockname.len,
- db->buf + out, db->len - out);
- out += snprintf(db->buf + out, db->len - out, "\t%ld\n",
+ buf + out, len - out);
+ out += snprintf(buf + out, len - out, "\t%ld\n",
(jiffies - res->last_used)/HZ);
spin_unlock(&res->spinlock);
}
spin_unlock(&dlm->spinlock);
- out += snprintf(db->buf + out, db->len - out,
- "Total on list: %ld\n", total);
+ out += snprintf(buf + out, len - out, "Total on list: %ld\n", total);
return out;
}
@@ -463,15 +417,15 @@ static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
static int debug_purgelist_open(struct inode *inode, struct file *file)
{
struct dlm_ctxt *dlm = inode->i_private;
- struct debug_buffer *db;
+ char *buf = NULL;
- db = debug_buffer_allocate();
- if (!db)
+ buf = (char *) get_zeroed_page(GFP_NOFS);
+ if (!buf)
goto bail;
- db->len = debug_purgelist_print(dlm, db);
+ i_size_write(inode, debug_purgelist_print(dlm, buf, PAGE_SIZE - 1));
- file->private_data = db;
+ file->private_data = buf;
return 0;
bail:
@@ -480,14 +434,14 @@ bail:
static const struct file_operations debug_purgelist_fops = {
.open = debug_purgelist_open,
- .release = debug_buffer_release,
- .read = debug_buffer_read,
- .llseek = debug_buffer_llseek,
+ .release = debug_release,
+ .read = debug_read,
+ .llseek = generic_file_llseek,
};
/* end - purge list funcs */
/* begin - debug mle funcs */
-static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+static int debug_mle_print(struct dlm_ctxt *dlm, char *buf, int len)
{
struct dlm_master_list_entry *mle;
struct hlist_head *bucket;
@@ -495,7 +449,7 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
int i, out = 0;
unsigned long total = 0, longest = 0, bucket_count = 0;
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Dumping MLEs for Domain: %s\n", dlm->name);
spin_lock(&dlm->master_lock);
@@ -506,16 +460,16 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
master_hash_node);
++total;
++bucket_count;
- if (db->len - out < 200)
+ if (len - out < 200)
continue;
- out += dump_mle(mle, db->buf + out, db->len - out);
+ out += dump_mle(mle, buf + out, len - out);
}
longest = max(longest, bucket_count);
bucket_count = 0;
}
spin_unlock(&dlm->master_lock);
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Total: %ld, Longest: %ld\n", total, longest);
return out;
}
@@ -523,15 +477,15 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
static int debug_mle_open(struct inode *inode, struct file *file)
{
struct dlm_ctxt *dlm = inode->i_private;
- struct debug_buffer *db;
+ char *buf = NULL;
- db = debug_buffer_allocate();
- if (!db)
+ buf = (char *) get_zeroed_page(GFP_NOFS);
+ if (!buf)
goto bail;
- db->len = debug_mle_print(dlm, db);
+ i_size_write(inode, debug_mle_print(dlm, buf, PAGE_SIZE - 1));
- file->private_data = db;
+ file->private_data = buf;
return 0;
bail:
@@ -540,9 +494,9 @@ bail:
static const struct file_operations debug_mle_fops = {
.open = debug_mle_open,
- .release = debug_buffer_release,
- .read = debug_buffer_read,
- .llseek = debug_buffer_llseek,
+ .release = debug_release,
+ .read = debug_read,
+ .llseek = generic_file_llseek,
};
/* end - debug mle funcs */
@@ -757,7 +711,7 @@ static const struct file_operations debug_lockres_fops = {
/* end - debug lockres funcs */
/* begin - debug state funcs */
-static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len)
{
int out = 0;
struct dlm_reco_node_data *node;
@@ -781,35 +735,35 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
}
/* Domain: xxxxxxxxxx Key: 0xdfbac769 */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Domain: %s Key: 0x%08x Protocol: %d.%d\n",
dlm->name, dlm->key, dlm->dlm_locking_proto.pv_major,
dlm->dlm_locking_proto.pv_minor);
/* Thread Pid: xxx Node: xxx State: xxxxx */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Thread Pid: %d Node: %d State: %s\n",
- dlm->dlm_thread_task->pid, dlm->node_num, state);
+ task_pid_nr(dlm->dlm_thread_task), dlm->node_num, state);
/* Number of Joins: xxx Joining Node: xxx */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Number of Joins: %d Joining Node: %d\n",
dlm->num_joins, dlm->joining_node);
/* Domain Map: xx xx xx */
- out += snprintf(db->buf + out, db->len - out, "Domain Map: ");
+ out += snprintf(buf + out, len - out, "Domain Map: ");
out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES,
- db->buf + out, db->len - out);
- out += snprintf(db->buf + out, db->len - out, "\n");
+ buf + out, len - out);
+ out += snprintf(buf + out, len - out, "\n");
/* Live Map: xx xx xx */
- out += snprintf(db->buf + out, db->len - out, "Live Map: ");
+ out += snprintf(buf + out, len - out, "Live Map: ");
out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES,
- db->buf + out, db->len - out);
- out += snprintf(db->buf + out, db->len - out, "\n");
+ buf + out, len - out);
+ out += snprintf(buf + out, len - out, "\n");
/* Lock Resources: xxx (xxx) */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Lock Resources: %d (%d)\n",
atomic_read(&dlm->res_cur_count),
atomic_read(&dlm->res_tot_count));
@@ -821,29 +775,29 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
cur_mles += atomic_read(&dlm->mle_cur_count[i]);
/* MLEs: xxx (xxx) */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"MLEs: %d (%d)\n", cur_mles, tot_mles);
/* Blocking: xxx (xxx) */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
" Blocking: %d (%d)\n",
atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]),
atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK]));
/* Mastery: xxx (xxx) */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
" Mastery: %d (%d)\n",
atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]),
atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER]));
/* Migration: xxx (xxx) */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
" Migration: %d (%d)\n",
atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]),
atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION]));
/* Lists: Dirty=Empty Purge=InUse PendingASTs=Empty ... */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Lists: Dirty=%s Purge=%s PendingASTs=%s "
"PendingBASTs=%s\n",
(list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),
@@ -852,12 +806,12 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
(list_empty(&dlm->pending_basts) ? "Empty" : "InUse"));
/* Purge Count: xxx Refs: xxx */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Purge Count: %d Refs: %d\n", dlm->purge_count,
atomic_read(&dlm->dlm_refs.refcount));
/* Dead Node: xxx */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Dead Node: %d\n", dlm->reco.dead_node);
/* What about DLM_RECO_STATE_FINALIZE? */
@@ -867,19 +821,19 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
state = "INACTIVE";
/* Recovery Pid: xxxx Master: xxx State: xxxx */
- out += snprintf(db->buf + out, db->len - out,
+ out += snprintf(buf + out, len - out,
"Recovery Pid: %d Master: %d State: %s\n",
- dlm->dlm_reco_thread_task->pid,
+ task_pid_nr(dlm->dlm_reco_thread_task),
dlm->reco.new_master, state);
/* Recovery Map: xx xx */
- out += snprintf(db->buf + out, db->len - out, "Recovery Map: ");
+ out += snprintf(buf + out, len - out, "Recovery Map: ");
out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES,
- db->buf + out, db->len - out);
- out += snprintf(db->buf + out, db->len - out, "\n");
+ buf + out, len - out);
+ out += snprintf(buf + out, len - out, "\n");
/* Recovery Node State: */
- out += snprintf(db->buf + out, db->len - out, "Recovery Node State:\n");
+ out += snprintf(buf + out, len - out, "Recovery Node State:\n");
list_for_each_entry(node, &dlm->reco.node_data, list) {
switch (node->state) {
case DLM_RECO_NODE_DATA_INIT:
@@ -907,7 +861,7 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
state = "BAD";
break;
}
- out += snprintf(db->buf + out, db->len - out, "\t%u - %s\n",
+ out += snprintf(buf + out, len - out, "\t%u - %s\n",
node->node_num, state);
}
@@ -919,15 +873,15 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
static int debug_state_open(struct inode *inode, struct file *file)
{
struct dlm_ctxt *dlm = inode->i_private;
- struct debug_buffer *db = NULL;
+ char *buf = NULL;
- db = debug_buffer_allocate();
- if (!db)
+ buf = (char *) get_zeroed_page(GFP_NOFS);
+ if (!buf)
goto bail;
- db->len = debug_state_print(dlm, db);
+ i_size_write(inode, debug_state_print(dlm, buf, PAGE_SIZE - 1));
- file->private_data = db;
+ file->private_data = buf;
return 0;
bail:
@@ -936,9 +890,9 @@ bail:
static const struct file_operations debug_state_fops = {
.open = debug_state_open,
- .release = debug_buffer_release,
- .read = debug_buffer_read,
- .llseek = debug_buffer_llseek,
+ .release = debug_release,
+ .read = debug_read,
+ .llseek = generic_file_llseek,
};
/* end - debug state funcs */
@@ -1002,14 +956,10 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
if (dc) {
- if (dc->debug_purgelist_dentry)
- debugfs_remove(dc->debug_purgelist_dentry);
- if (dc->debug_mle_dentry)
- debugfs_remove(dc->debug_mle_dentry);
- if (dc->debug_lockres_dentry)
- debugfs_remove(dc->debug_lockres_dentry);
- if (dc->debug_state_dentry)
- debugfs_remove(dc->debug_state_dentry);
+ debugfs_remove(dc->debug_purgelist_dentry);
+ debugfs_remove(dc->debug_mle_dentry);
+ debugfs_remove(dc->debug_lockres_dentry);
+ debugfs_remove(dc->debug_state_dentry);
dlm_debug_put(dc);
}
}
@@ -1040,8 +990,7 @@ bail:
void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
{
- if (dlm->dlm_debugfs_subroot)
- debugfs_remove(dlm->dlm_debugfs_subroot);
+ debugfs_remove(dlm->dlm_debugfs_subroot);
}
/* debugfs root */
@@ -1057,7 +1006,6 @@ int dlm_create_debugfs_root(void)
void dlm_destroy_debugfs_root(void)
{
- if (dlm_debugfs_root)
- debugfs_remove(dlm_debugfs_root);
+ debugfs_remove(dlm_debugfs_root);
}
#endif /* CONFIG_DEBUG_FS */
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index 8c686d22f9c7..1f27c4812d1a 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -37,11 +37,6 @@ struct dlm_debug_ctxt {
struct dentry *debug_purgelist_dentry;
};
-struct debug_buffer {
- int len;
- char *buf;
-};
-
struct debug_lockres {
int dl_len;
char *dl_buf;
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 58a93b953735..7e38a072d720 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -460,8 +460,6 @@ redo_bucket:
}
cond_resched_lock(&dlm->spinlock);
num += n;
- mlog(0, "%s: touched %d lockreses in bucket %d "
- "(tot=%d)\n", dlm->name, n, i, num);
}
spin_unlock(&dlm->spinlock);
wake_up(&dlm->dlm_thread_wq);
@@ -959,7 +957,7 @@ static int dlm_match_regions(struct dlm_ctxt *dlm,
r += O2HB_MAX_REGION_NAME_LEN;
}
- local = kmalloc(sizeof(qr->qr_regions), GFP_KERNEL);
+ local = kmalloc(sizeof(qr->qr_regions), GFP_ATOMIC);
if (!local) {
status = -ENOMEM;
goto bail;
@@ -1661,8 +1659,8 @@ bail:
static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm)
{
- o2hb_unregister_callback(NULL, &dlm->dlm_hb_up);
- o2hb_unregister_callback(NULL, &dlm->dlm_hb_down);
+ o2hb_unregister_callback(dlm->name, &dlm->dlm_hb_up);
+ o2hb_unregister_callback(dlm->name, &dlm->dlm_hb_down);
o2net_unregister_handler_list(&dlm->dlm_domain_handlers);
}
@@ -1674,13 +1672,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB,
dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI);
- status = o2hb_register_callback(NULL, &dlm->dlm_hb_down);
+ status = o2hb_register_callback(dlm->name, &dlm->dlm_hb_down);
if (status)
goto bail;
o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB,
dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI);
- status = o2hb_register_callback(NULL, &dlm->dlm_hb_up);
+ status = o2hb_register_callback(dlm->name, &dlm->dlm_hb_up);
if (status)
goto bail;
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index 69cf369961c4..7009292aac5a 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -106,6 +106,9 @@ static int dlm_can_grant_new_lock(struct dlm_lock_resource *res,
if (!dlm_lock_compatible(tmplock->ml.type, lock->ml.type))
return 0;
+ if (!dlm_lock_compatible(tmplock->ml.convert_type,
+ lock->ml.type))
+ return 0;
}
return 1;
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index f564b0e5f80d..59f0f6bdfc62 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2346,7 +2346,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
*/
static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res,
- int *numlocks)
+ int *numlocks,
+ int *hasrefs)
{
int ret;
int i;
@@ -2356,6 +2357,9 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
assert_spin_locked(&res->spinlock);
+ *numlocks = 0;
+ *hasrefs = 0;
+
ret = -EINVAL;
if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
mlog(0, "cannot migrate lockres with unknown owner!\n");
@@ -2386,7 +2390,13 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
}
*numlocks = count;
- mlog(0, "migrateable lockres having %d locks\n", *numlocks);
+
+ count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
+ if (count < O2NM_MAX_NODES)
+ *hasrefs = 1;
+
+ mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name,
+ res->lockname.len, res->lockname.name, *numlocks, *hasrefs);
leave:
return ret;
@@ -2408,7 +2418,7 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
const char *name;
unsigned int namelen;
int mle_added = 0;
- int numlocks;
+ int numlocks, hasrefs;
int wake = 0;
if (!dlm_grab(dlm))
@@ -2417,13 +2427,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
name = res->lockname.name;
namelen = res->lockname.len;
- mlog(0, "migrating %.*s to %u\n", namelen, name, target);
+ mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target);
/*
* ensure this lockres is a proper candidate for migration
*/
spin_lock(&res->spinlock);
- ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
+ ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
if (ret < 0) {
spin_unlock(&res->spinlock);
goto leave;
@@ -2431,10 +2441,8 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
spin_unlock(&res->spinlock);
/* no work to do */
- if (numlocks == 0) {
- mlog(0, "no locks were found on this lockres! done!\n");
+ if (numlocks == 0 && !hasrefs)
goto leave;
- }
/*
* preallocate up front
@@ -2459,14 +2467,14 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
* find a node to migrate the lockres to
*/
- mlog(0, "picking a migration node\n");
spin_lock(&dlm->spinlock);
/* pick a new node */
if (!test_bit(target, dlm->domain_map) ||
target >= O2NM_MAX_NODES) {
target = dlm_pick_migration_target(dlm, res);
}
- mlog(0, "node %u chosen for migration\n", target);
+ mlog(0, "%s: res %.*s, Node %u chosen for migration\n", dlm->name,
+ namelen, name, target);
if (target >= O2NM_MAX_NODES ||
!test_bit(target, dlm->domain_map)) {
@@ -2667,7 +2675,7 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
{
int ret;
int lock_dropped = 0;
- int numlocks;
+ int numlocks, hasrefs;
spin_lock(&res->spinlock);
if (res->owner != dlm->node_num) {
@@ -2681,8 +2689,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
}
/* No need to migrate a lockres having no locks */
- ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
- if (ret >= 0 && numlocks == 0) {
+ ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
+ if (ret >= 0 && numlocks == 0 && !hasrefs) {
spin_unlock(&res->spinlock);
goto leave;
}
@@ -2915,6 +2923,12 @@ static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm,
}
queue++;
}
+
+ nodenum = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
+ if (nodenum < O2NM_MAX_NODES) {
+ spin_unlock(&res->spinlock);
+ return nodenum;
+ }
spin_unlock(&res->spinlock);
mlog(0, "have not found a suitable target yet! checking domain map\n");
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 2211acf33d9b..1d6d1d22c471 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -122,15 +122,13 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res)
void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res)
{
- mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
-
assert_spin_locked(&dlm->spinlock);
assert_spin_locked(&res->spinlock);
if (__dlm_lockres_unused(res)){
if (list_empty(&res->purge)) {
- mlog(0, "putting lockres %.*s:%p onto purge list\n",
- res->lockname.len, res->lockname.name, res);
+ mlog(0, "%s: Adding res %.*s to purge list\n",
+ dlm->name, res->lockname.len, res->lockname.name);
res->last_used = jiffies;
dlm_lockres_get(res);
@@ -138,8 +136,8 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
dlm->purge_count++;
}
} else if (!list_empty(&res->purge)) {
- mlog(0, "removing lockres %.*s:%p from purge list, owner=%u\n",
- res->lockname.len, res->lockname.name, res, res->owner);
+ mlog(0, "%s: Removing res %.*s from purge list\n",
+ dlm->name, res->lockname.len, res->lockname.name);
list_del_init(&res->purge);
dlm_lockres_put(res);
@@ -150,7 +148,6 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res)
{
- mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
spin_lock(&dlm->spinlock);
spin_lock(&res->spinlock);
@@ -171,9 +168,8 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
master = (res->owner == dlm->node_num);
-
- mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len,
- res->lockname.name, master);
+ mlog(0, "%s: Purging res %.*s, master %d\n", dlm->name,
+ res->lockname.len, res->lockname.name, master);
if (!master) {
res->state |= DLM_LOCK_RES_DROPPING_REF;
@@ -189,27 +185,25 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
/* clear our bit from the master's refmap, ignore errors */
ret = dlm_drop_lockres_ref(dlm, res);
if (ret < 0) {
- mlog_errno(ret);
+ mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name,
+ res->lockname.len, res->lockname.name, ret);
if (!dlm_is_host_down(ret))
BUG();
}
- mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n",
- dlm->name, res->lockname.len, res->lockname.name, ret);
spin_lock(&dlm->spinlock);
spin_lock(&res->spinlock);
}
if (!list_empty(&res->purge)) {
- mlog(0, "removing lockres %.*s:%p from purgelist, "
- "master = %d\n", res->lockname.len, res->lockname.name,
- res, master);
+ mlog(0, "%s: Removing res %.*s from purgelist, master %d\n",
+ dlm->name, res->lockname.len, res->lockname.name, master);
list_del_init(&res->purge);
dlm_lockres_put(res);
dlm->purge_count--;
}
if (!__dlm_lockres_unused(res)) {
- mlog(ML_ERROR, "found lockres %s:%.*s: in use after deref\n",
+ mlog(ML_ERROR, "%s: res %.*s in use after deref\n",
dlm->name, res->lockname.len, res->lockname.name);
__dlm_print_one_lock_resource(res);
BUG();
@@ -266,10 +260,10 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm,
unused = __dlm_lockres_unused(lockres);
if (!unused ||
(lockres->state & DLM_LOCK_RES_MIGRATING)) {
- mlog(0, "lockres %s:%.*s: is in use or "
- "being remastered, used %d, state %d\n",
- dlm->name, lockres->lockname.len,
- lockres->lockname.name, !unused, lockres->state);
+ mlog(0, "%s: res %.*s is in use or being remastered, "
+ "used %d, state %d\n", dlm->name,
+ lockres->lockname.len, lockres->lockname.name,
+ !unused, lockres->state);
list_move_tail(&dlm->purge_list, &lockres->purge);
spin_unlock(&lockres->spinlock);
continue;
@@ -296,15 +290,12 @@ static void dlm_shuffle_lists(struct dlm_ctxt *dlm,
struct list_head *head;
int can_grant = 1;
- //mlog(0, "res->lockname.len=%d\n", res->lockname.len);
- //mlog(0, "res->lockname.name=%p\n", res->lockname.name);
- //mlog(0, "shuffle res %.*s\n", res->lockname.len,
- // res->lockname.name);
-
- /* because this function is called with the lockres
+ /*
+ * Because this function is called with the lockres
* spinlock, and because we know that it is not migrating/
* recovering/in-progress, it is fine to reserve asts and
- * basts right before queueing them all throughout */
+ * basts right before queueing them all throughout
+ */
assert_spin_locked(&dlm->ast_lock);
assert_spin_locked(&res->spinlock);
BUG_ON((res->state & (DLM_LOCK_RES_MIGRATING|
@@ -314,13 +305,13 @@ static void dlm_shuffle_lists(struct dlm_ctxt *dlm,
converting:
if (list_empty(&res->converting))
goto blocked;
- mlog(0, "res %.*s has locks on a convert queue\n", res->lockname.len,
- res->lockname.name);
+ mlog(0, "%s: res %.*s has locks on the convert queue\n", dlm->name,
+ res->lockname.len, res->lockname.name);
target = list_entry(res->converting.next, struct dlm_lock, list);
if (target->ml.convert_type == LKM_IVMODE) {
- mlog(ML_ERROR, "%.*s: converting a lock with no "
- "convert_type!\n", res->lockname.len, res->lockname.name);
+ mlog(ML_ERROR, "%s: res %.*s converting lock to invalid mode\n",
+ dlm->name, res->lockname.len, res->lockname.name);
BUG();
}
head = &res->granted;
@@ -365,9 +356,12 @@ converting:
spin_lock(&target->spinlock);
BUG_ON(target->ml.highest_blocked != LKM_IVMODE);
- mlog(0, "calling ast for converting lock: %.*s, have: %d, "
- "granting: %d, node: %u\n", res->lockname.len,
- res->lockname.name, target->ml.type,
+ mlog(0, "%s: res %.*s, AST for Converting lock %u:%llu, type "
+ "%d => %d, node %u\n", dlm->name, res->lockname.len,
+ res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(target->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(target->ml.cookie)),
+ target->ml.type,
target->ml.convert_type, target->ml.node);
target->ml.type = target->ml.convert_type;
@@ -428,11 +422,14 @@ blocked:
spin_lock(&target->spinlock);
BUG_ON(target->ml.highest_blocked != LKM_IVMODE);
- mlog(0, "calling ast for blocked lock: %.*s, granting: %d, "
- "node: %u\n", res->lockname.len, res->lockname.name,
+ mlog(0, "%s: res %.*s, AST for Blocked lock %u:%llu, type %d, "
+ "node %u\n", dlm->name, res->lockname.len,
+ res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(target->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(target->ml.cookie)),
target->ml.type, target->ml.node);
- // target->ml.type is already correct
+ /* target->ml.type is already correct */
list_move_tail(&target->list, &res->granted);
BUG_ON(!target->lksb);
@@ -453,7 +450,6 @@ leave:
/* must have NO locks when calling this with res !=NULL * */
void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
{
- mlog_entry("dlm=%p, res=%p\n", dlm, res);
if (res) {
spin_lock(&dlm->spinlock);
spin_lock(&res->spinlock);
@@ -466,8 +462,6 @@ void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
{
- mlog_entry("dlm=%p, res=%p\n", dlm, res);
-
assert_spin_locked(&dlm->spinlock);
assert_spin_locked(&res->spinlock);
@@ -484,13 +478,16 @@ void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
res->state |= DLM_LOCK_RES_DIRTY;
}
}
+
+ mlog(0, "%s: res %.*s\n", dlm->name, res->lockname.len,
+ res->lockname.name);
}
/* Launch the NM thread for the mounted volume */
int dlm_launch_thread(struct dlm_ctxt *dlm)
{
- mlog(0, "starting dlm thread...\n");
+ mlog(0, "Starting dlm_thread...\n");
dlm->dlm_thread_task = kthread_run(dlm_thread, dlm, "dlm_thread");
if (IS_ERR(dlm->dlm_thread_task)) {
@@ -505,7 +502,7 @@ int dlm_launch_thread(struct dlm_ctxt *dlm)
void dlm_complete_thread(struct dlm_ctxt *dlm)
{
if (dlm->dlm_thread_task) {
- mlog(ML_KTHREAD, "waiting for dlm thread to exit\n");
+ mlog(ML_KTHREAD, "Waiting for dlm thread to exit\n");
kthread_stop(dlm->dlm_thread_task);
dlm->dlm_thread_task = NULL;
}
@@ -536,7 +533,12 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm)
/* get an extra ref on lock */
dlm_lock_get(lock);
res = lock->lockres;
- mlog(0, "delivering an ast for this lockres\n");
+ mlog(0, "%s: res %.*s, Flush AST for lock %u:%llu, type %d, "
+ "node %u\n", dlm->name, res->lockname.len,
+ res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+ lock->ml.type, lock->ml.node);
BUG_ON(!lock->ast_pending);
@@ -557,9 +559,9 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm)
/* possible that another ast was queued while
* we were delivering the last one */
if (!list_empty(&lock->ast_list)) {
- mlog(0, "aha another ast got queued while "
- "we were finishing the last one. will "
- "keep the ast_pending flag set.\n");
+ mlog(0, "%s: res %.*s, AST queued while flushing last "
+ "one\n", dlm->name, res->lockname.len,
+ res->lockname.name);
} else
lock->ast_pending = 0;
@@ -590,8 +592,12 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm)
dlm_lock_put(lock);
spin_unlock(&dlm->ast_lock);
- mlog(0, "delivering a bast for this lockres "
- "(blocked = %d\n", hi);
+ mlog(0, "%s: res %.*s, Flush BAST for lock %u:%llu, "
+ "blocked %d, node %u\n",
+ dlm->name, res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+ hi, lock->ml.node);
if (lock->ml.node != dlm->node_num) {
ret = dlm_send_proxy_bast(dlm, res, lock, hi);
@@ -605,9 +611,9 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm)
/* possible that another bast was queued while
* we were delivering the last one */
if (!list_empty(&lock->bast_list)) {
- mlog(0, "aha another bast got queued while "
- "we were finishing the last one. will "
- "keep the bast_pending flag set.\n");
+ mlog(0, "%s: res %.*s, BAST queued while flushing last "
+ "one\n", dlm->name, res->lockname.len,
+ res->lockname.name);
} else
lock->bast_pending = 0;
@@ -675,11 +681,12 @@ static int dlm_thread(void *data)
spin_lock(&res->spinlock);
if (res->owner != dlm->node_num) {
__dlm_print_one_lock_resource(res);
- mlog(ML_ERROR, "inprog:%s, mig:%s, reco:%s, dirty:%s\n",
- res->state & DLM_LOCK_RES_IN_PROGRESS ? "yes" : "no",
- res->state & DLM_LOCK_RES_MIGRATING ? "yes" : "no",
- res->state & DLM_LOCK_RES_RECOVERING ? "yes" : "no",
- res->state & DLM_LOCK_RES_DIRTY ? "yes" : "no");
+ mlog(ML_ERROR, "%s: inprog %d, mig %d, reco %d,"
+ " dirty %d\n", dlm->name,
+ !!(res->state & DLM_LOCK_RES_IN_PROGRESS),
+ !!(res->state & DLM_LOCK_RES_MIGRATING),
+ !!(res->state & DLM_LOCK_RES_RECOVERING),
+ !!(res->state & DLM_LOCK_RES_DIRTY));
}
BUG_ON(res->owner != dlm->node_num);
@@ -693,8 +700,8 @@ static int dlm_thread(void *data)
res->state &= ~DLM_LOCK_RES_DIRTY;
spin_unlock(&res->spinlock);
spin_unlock(&dlm->ast_lock);
- mlog(0, "delaying list shuffling for in-"
- "progress lockres %.*s, state=%d\n",
+ mlog(0, "%s: res %.*s, inprogress, delay list "
+ "shuffle, state %d\n", dlm->name,
res->lockname.len, res->lockname.name,
res->state);
delay = 1;
@@ -706,10 +713,6 @@ static int dlm_thread(void *data)
* spinlock and do NOT have the dlm lock.
* safe to reserve/queue asts and run the lists. */
- mlog(0, "calling dlm_shuffle_lists with dlm=%s, "
- "res=%.*s\n", dlm->name,
- res->lockname.len, res->lockname.name);
-
/* called while holding lockres lock */
dlm_shuffle_lists(dlm, res);
res->state &= ~DLM_LOCK_RES_DIRTY;
@@ -733,7 +736,8 @@ in_progress:
/* unlikely, but we may need to give time to
* other tasks */
if (!--n) {
- mlog(0, "throttling dlm_thread\n");
+ mlog(0, "%s: Throttling dlm thread\n",
+ dlm->name);
break;
}
}
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c
index b2df490a19ed..8c5c0eddc365 100644
--- a/fs/ocfs2/dlmfs/dlmfs.c
+++ b/fs/ocfs2/dlmfs/dlmfs.c
@@ -351,11 +351,18 @@ static struct inode *dlmfs_alloc_inode(struct super_block *sb)
return &ip->ip_vfs_inode;
}
-static void dlmfs_destroy_inode(struct inode *inode)
+static void dlmfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(dlmfs_inode_cache, DLMFS_I(inode));
}
+static void dlmfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, dlmfs_i_callback);
+}
+
static void dlmfs_evict_inode(struct inode *inode)
{
int status;
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 19ad145d2af3..6adafa576065 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -138,7 +138,7 @@ check_gen:
result = d_obtain_alias(inode);
if (!IS_ERR(result))
- result->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(result, &ocfs2_dentry_ops);
else
mlog_errno(PTR_ERR(result));
@@ -176,7 +176,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
if (!IS_ERR(parent))
- parent->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(parent, &ocfs2_dentry_ops);
bail_unlock:
ocfs2_inode_unlock(dir, 0);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 77b4c04a2809..f6cba566429d 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2241,11 +2241,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
mutex_lock(&inode->i_mutex);
+ ocfs2_iocb_clear_sem_locked(iocb);
+
relock:
/* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
if (direct_io) {
down_read(&inode->i_alloc_sem);
have_alloc_sem = 1;
+ /* communicate with ocfs2_dio_end_io */
+ ocfs2_iocb_set_sem_locked(iocb);
}
/*
@@ -2382,8 +2386,10 @@ out:
ocfs2_rw_unlock(inode, rw_level);
out_sems:
- if (have_alloc_sem)
+ if (have_alloc_sem) {
up_read(&inode->i_alloc_sem);
+ ocfs2_iocb_clear_sem_locked(iocb);
+ }
mutex_unlock(&inode->i_mutex);
@@ -2527,6 +2533,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
goto bail;
}
+ ocfs2_iocb_clear_sem_locked(iocb);
+
/*
* buffered reads protect themselves in ->readpage(). O_DIRECT reads
* need locks to protect pending reads from racing with truncate.
@@ -2534,6 +2542,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
if (filp->f_flags & O_DIRECT) {
down_read(&inode->i_alloc_sem);
have_alloc_sem = 1;
+ ocfs2_iocb_set_sem_locked(iocb);
ret = ocfs2_rw_lock(inode, 0);
if (ret < 0) {
@@ -2575,8 +2584,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
}
bail:
- if (have_alloc_sem)
+ if (have_alloc_sem) {
up_read(&inode->i_alloc_sem);
+ ocfs2_iocb_clear_sem_locked(iocb);
+ }
if (rw_level != -1)
ocfs2_rw_unlock(inode, rw_level);
mlog_exit(ret);
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index ff5744e1e36f..30c523144452 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -147,7 +147,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
spin_unlock(&oi->ip_lock);
bail_add:
- dentry->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(dentry, &ocfs2_dentry_ops);
ret = d_splice_alias(inode, dentry);
if (inode) {
@@ -415,7 +415,7 @@ static int ocfs2_mknod(struct inode *dir,
mlog_errno(status);
goto leave;
}
- dentry->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(dentry, &ocfs2_dentry_ops);
status = ocfs2_add_entry(handle, dentry, inode,
OCFS2_I(inode)->ip_blkno, parent_fe_bh,
@@ -743,7 +743,7 @@ static int ocfs2_link(struct dentry *old_dentry,
}
ihold(inode);
- dentry->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(dentry, &ocfs2_dentry_ops);
d_instantiate(dentry, inode);
out_commit:
@@ -1017,8 +1017,11 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
* An error return must mean that no cluster locks
* were held on function exit.
*/
- if (oi1->ip_blkno != oi2->ip_blkno)
+ if (oi1->ip_blkno != oi2->ip_blkno) {
ocfs2_inode_unlock(inode2, 1);
+ brelse(*bh2);
+ *bh2 = NULL;
+ }
if (status != -ENOENT)
mlog_errno(status);
@@ -1794,7 +1797,7 @@ static int ocfs2_symlink(struct inode *dir,
mlog_errno(status);
goto bail;
}
- dentry->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(dentry, &ocfs2_dentry_ops);
status = ocfs2_add_entry(handle, dentry, inode,
le64_to_cpu(fe->i_blkno), parent_fe_bh,
@@ -2459,7 +2462,7 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
goto out_commit;
}
- dentry->d_op = &ocfs2_dentry_ops;
+ d_set_d_op(dentry, &ocfs2_dentry_ops);
d_instantiate(dentry, inode);
status = 0;
out_commit:
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 1efea3615589..51cd6898e7f1 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -159,9 +159,9 @@ struct ocfs2_lock_res {
char l_name[OCFS2_LOCK_ID_MAX_LEN];
unsigned int l_ro_holders;
unsigned int l_ex_holders;
- char l_level;
- char l_requested;
- char l_blocking;
+ signed char l_level;
+ signed char l_requested;
+ signed char l_blocking;
/* Data packed - type enum ocfs2_lock_type */
unsigned char l_type;
@@ -420,6 +420,11 @@ struct ocfs2_super
struct inode *osb_tl_inode;
struct buffer_head *osb_tl_bh;
struct delayed_work osb_truncate_log_wq;
+ /*
+ * How many clusters in our truncate log.
+ * It must be protected by osb_tl_inode->i_mutex.
+ */
+ unsigned int truncated_clusters;
struct ocfs2_node_map osb_recovering_orphan_dirs;
unsigned int *osb_orphan_wipes;
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index c2e4f8222e2f..bf2e7764920e 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -350,7 +350,7 @@ enum {
#define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE
NUM_SYSTEM_INODES
};
-#define NUM_GLOBAL_SYSTEM_INODES OCFS2_LAST_GLOBAL_SYSTEM_INODE
+#define NUM_GLOBAL_SYSTEM_INODES OCFS2_FIRST_LOCAL_SYSTEM_INODE
#define NUM_LOCAL_SYSTEM_INODES \
(NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE)
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index 252e7c82f929..a5ebe421195f 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -190,7 +190,7 @@ static struct ocfs2_live_connection *ocfs2_connection_find(const char *name)
return c;
}
- return c;
+ return NULL;
}
/*
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index cfeab7ce3697..17ff46fa8a10 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -569,11 +569,18 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb)
return &oi->vfs_inode;
}
-static void ocfs2_destroy_inode(struct inode *inode)
+static void ocfs2_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
}
+static void ocfs2_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, ocfs2_i_callback);
+}
+
static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
unsigned int cbits)
{
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 911e61f348fc..a2a5bff774e3 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -343,11 +343,18 @@ static struct inode *openprom_alloc_inode(struct super_block *sb)
return &oi->vfs_inode;
}
-static void openprom_destroy_inode(struct inode *inode)
+static void openprom_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(op_inode_cachep, OP_I(inode));
}
+static void openprom_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, openprom_i_callback);
+}
+
static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
{
struct inode *inode;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 0a8b0ad0c7e2..9a48d65d9855 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -237,6 +237,13 @@ ssize_t part_size_show(struct device *dev,
return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects);
}
+ssize_t part_ro_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+ return sprintf(buf, "%d\n", p->policy ? 1 : 0);
+}
+
ssize_t part_alignment_offset_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -312,6 +319,7 @@ ssize_t part_fail_store(struct device *dev,
static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
+static DEVICE_ATTR(ro, S_IRUGO, part_ro_show, NULL);
static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show,
NULL);
@@ -326,6 +334,7 @@ static struct attribute *part_attrs[] = {
&dev_attr_partition.attr,
&dev_attr_start.attr,
&dev_attr_size.attr,
+ &dev_attr_ro.attr,
&dev_attr_alignment_offset.attr,
&dev_attr_discard_alignment.attr,
&dev_attr_stat.attr,
@@ -507,65 +516,6 @@ out_put:
return ERR_PTR(err);
}
-/* Not exported, helper to add_disk(). */
-void register_disk(struct gendisk *disk)
-{
- struct device *ddev = disk_to_dev(disk);
- struct block_device *bdev;
- struct disk_part_iter piter;
- struct hd_struct *part;
- int err;
-
- ddev->parent = disk->driverfs_dev;
-
- dev_set_name(ddev, disk->disk_name);
-
- /* delay uevents, until we scanned partition table */
- dev_set_uevent_suppress(ddev, 1);
-
- if (device_add(ddev))
- return;
- if (!sysfs_deprecated) {
- err = sysfs_create_link(block_depr, &ddev->kobj,
- kobject_name(&ddev->kobj));
- if (err) {
- device_del(ddev);
- return;
- }
- }
- disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
- disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
-
- /* No minors to use for partitions */
- if (!disk_partitionable(disk))
- goto exit;
-
- /* No such device (e.g., media were just removed) */
- if (!get_capacity(disk))
- goto exit;
-
- bdev = bdget_disk(disk, 0);
- if (!bdev)
- goto exit;
-
- bdev->bd_invalidated = 1;
- err = blkdev_get(bdev, FMODE_READ);
- if (err < 0)
- goto exit;
- blkdev_put(bdev, FMODE_READ);
-
-exit:
- /* announce disk after possible partitions are created */
- dev_set_uevent_suppress(ddev, 0);
- kobject_uevent(&ddev->kobj, KOBJ_ADD);
-
- /* announce possible partitions */
- disk_part_iter_init(&piter, disk, 0);
- while ((part = disk_part_iter_next(&piter)))
- kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
- disk_part_iter_exit(&piter);
-}
-
static bool disk_unlock_native_capacity(struct gendisk *disk)
{
const struct block_device_operations *bdops = disk->fops;
@@ -728,33 +678,3 @@ fail:
}
EXPORT_SYMBOL(read_dev_sector);
-
-void del_gendisk(struct gendisk *disk)
-{
- struct disk_part_iter piter;
- struct hd_struct *part;
-
- /* invalidate stuff */
- disk_part_iter_init(&piter, disk,
- DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
- while ((part = disk_part_iter_next(&piter))) {
- invalidate_partition(disk, part->partno);
- delete_partition(disk, part->partno);
- }
- disk_part_iter_exit(&piter);
-
- invalidate_partition(disk, 0);
- blk_free_devt(disk_to_dev(disk)->devt);
- set_capacity(disk, 0);
- disk->flags &= ~GENHD_FL_UP;
- unlink_gendisk(disk);
- part_stat_set_all(&disk->part0, 0);
- disk->part0.stamp = 0;
-
- kobject_put(disk->part0.holder_dir);
- kobject_put(disk->slave_dir);
- disk->driverfs_dev = NULL;
- if (!sysfs_deprecated)
- sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
- device_del(disk_to_dev(disk));
-}
diff --git a/fs/pipe.c b/fs/pipe.c
index 04629f36e397..68f1f8e4e23b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -999,12 +999,12 @@ struct file *create_write_pipe(int flags)
goto err;
err = -ENOMEM;
- path.dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
+ path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
if (!path.dentry)
goto err_inode;
path.mnt = mntget(pipe_mnt);
- path.dentry->d_op = &pipefs_dentry_operations;
+ d_set_d_op(path.dentry, &pipefs_dentry_operations);
d_instantiate(path.dentry, inode);
err = -ENFILE;
@@ -1253,6 +1253,10 @@ out:
return ret;
}
+static const struct super_operations pipefs_ops = {
+ .destroy_inode = free_inode_nonrcu,
+};
+
/*
* pipefs should _never_ be mounted by userland - too much of security hassle,
* no real gain from having the whole whorehouse mounted. So we don't need
@@ -1262,7 +1266,7 @@ out:
static struct dentry *pipefs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
- return mount_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
+ return mount_pseudo(fs_type, "pipe:", &pipefs_ops, PIPEFS_MAGIC);
}
static struct file_system_type pipe_fs_type = {
@@ -1288,7 +1292,7 @@ static int __init init_pipe_fs(void)
static void __exit exit_pipe_fs(void)
{
unregister_filesystem(&pipe_fs_type);
- mntput(pipe_mnt);
+ mntput_long(pipe_mnt);
}
fs_initcall(init_pipe_fs);
diff --git a/fs/pnode.c b/fs/pnode.c
index 8066b8dd748f..646ab86d8ae4 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -288,7 +288,7 @@ out:
*/
static inline int do_refcount_check(struct vfsmount *mnt, int count)
{
- int mycount = atomic_read(&mnt->mnt_count) - mnt->mnt_ghosts;
+ int mycount = count_mnt_count(mnt) - mnt->mnt_ghosts;
return (mycount > count);
}
@@ -300,7 +300,7 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count)
* Check if any of these mounts that **do not have submounts**
* have more references than 'refcnt'. If so return busy.
*
- * vfsmount lock must be held for read or write
+ * vfsmount lock must be held for write
*/
int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
{
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f3d02ca461ec..85f0a80912aa 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1574,7 +1574,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
if (!tmp)
return -ENOMEM;
- pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE);
+ pathname = d_path(path, tmp, PAGE_SIZE);
len = PTR_ERR(pathname);
if (IS_ERR(pathname))
goto out;
@@ -1744,7 +1744,7 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
return 0;
}
-static int pid_delete_dentry(struct dentry * dentry)
+static int pid_delete_dentry(const struct dentry * dentry)
{
/* Is the task we represent dead?
* If so, then don't put the dentry on the lru list,
@@ -1969,7 +1969,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link;
- dentry->d_op = &tid_fd_dentry_operations;
+ d_set_d_op(dentry, &tid_fd_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (tid_fd_revalidate(dentry, NULL))
@@ -2137,7 +2137,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
ei->fd = fd;
inode->i_mode = S_IFREG | S_IRUSR;
inode->i_fop = &proc_fdinfo_file_operations;
- dentry->d_op = &tid_fd_dentry_operations;
+ d_set_d_op(dentry, &tid_fd_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (tid_fd_revalidate(dentry, NULL))
@@ -2196,7 +2196,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir,
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
- dentry->d_op = &pid_dentry_operations;
+ d_set_d_op(dentry, &pid_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
@@ -2615,7 +2615,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
- dentry->d_op = &proc_base_dentry_operations;
+ d_set_d_op(dentry, &proc_base_dentry_operations);
d_add(dentry, inode);
error = NULL;
out:
@@ -2926,7 +2926,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff,
ARRAY_SIZE(tgid_base_stuff));
- dentry->d_op = &pid_dentry_operations;
+ d_set_d_op(dentry, &pid_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
@@ -3169,7 +3169,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff,
ARRAY_SIZE(tid_base_stuff));
- dentry->d_op = &pid_dentry_operations;
+ d_set_d_op(dentry, &pid_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index dd29f0337661..f766be29d2c7 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -400,7 +400,7 @@ static const struct inode_operations proc_link_inode_operations = {
* smarter: we could keep a "volatile" flag in the
* inode to indicate which ones to keep.
*/
-static int proc_delete_dentry(struct dentry * dentry)
+static int proc_delete_dentry(const struct dentry * dentry)
{
return 1;
}
@@ -439,7 +439,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
out_unlock:
if (inode) {
- dentry->d_op = &proc_dentry_operations;
+ d_set_d_op(dentry, &proc_dentry_operations);
d_add(dentry, inode);
return NULL;
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 3ddb6068177c..6bcb926b101b 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -65,11 +65,18 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
return inode;
}
-static void proc_destroy_inode(struct inode *inode)
+static void proc_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}
+static void proc_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, proc_i_callback);
+}
+
static void init_once(void *foo)
{
struct proc_inode *ei = (struct proc_inode *) foo;
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index b652cb00906b..35efd85a4d32 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -120,7 +120,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
goto out;
err = NULL;
- dentry->d_op = &proc_sys_dentry_operations;
+ d_set_d_op(dentry, &proc_sys_dentry_operations);
d_add(dentry, inode);
out:
@@ -201,7 +201,7 @@ static int proc_sys_fill_cache(struct file *filp, void *dirent,
dput(child);
return -ENOMEM;
} else {
- child->d_op = &proc_sys_dentry_operations;
+ d_set_d_op(child, &proc_sys_dentry_operations);
d_add(child, inode);
}
} else {
@@ -392,20 +392,25 @@ static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
return !PROC_I(dentry->d_inode)->sysctl->unregistering;
}
-static int proc_sys_delete(struct dentry *dentry)
+static int proc_sys_delete(const struct dentry *dentry)
{
return !!PROC_I(dentry->d_inode)->sysctl->unregistering;
}
-static int proc_sys_compare(struct dentry *dir, struct qstr *qstr,
- struct qstr *name)
+static int proc_sys_compare(const struct dentry *parent,
+ const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- struct dentry *dentry = container_of(qstr, struct dentry, d_name);
- if (qstr->len != name->len)
+ /* Although proc doesn't have negative dentries, rcu-walk means
+ * that inode here can be NULL */
+ if (!inode)
+ return 0;
+ if (name->len != len)
return 1;
- if (memcmp(qstr->name, name->name, name->len))
+ if (memcmp(name->name, str, len))
return 1;
- return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl);
+ return !sysctl_is_seen(PROC_I(inode)->sysctl);
}
static const struct dentry_operations proc_sys_dentry_operations = {
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 2367fb3f70bc..74802bc5ded9 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -499,7 +499,7 @@ static int __init parse_crash_elf64_headers(void)
/* Do some basic Verification. */
if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
(ehdr.e_type != ET_CORE) ||
- !vmcore_elf_check_arch(&ehdr) ||
+ !vmcore_elf64_check_arch(&ehdr) ||
ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
ehdr.e_version != EV_CURRENT ||
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
new file mode 100644
index 000000000000..867d0ac026ce
--- /dev/null
+++ b/fs/pstore/Kconfig
@@ -0,0 +1,13 @@
+config PSTORE
+ bool "Persistant store support"
+ default n
+ help
+ This option enables generic access to platform level
+ persistent storage via "pstore" filesystem that can
+ be mounted as /dev/pstore. Only useful if you have
+ a platform level driver that registers with pstore to
+ provide the data, so you probably should just go say "Y"
+ (or "M") to a platform specific persistent store driver
+ (e.g. ACPI_APEI on X86) which will select this for you.
+ If you don't have a platform persistent store driver,
+ say N.
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
new file mode 100644
index 000000000000..760f4bce7d1d
--- /dev/null
+++ b/fs/pstore/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux pstorefs routines.
+#
+
+obj-y += pstore.o
+
+pstore-objs += inode.o platform.o
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
new file mode 100644
index 000000000000..0e806aafe857
--- /dev/null
+++ b/fs/pstore/inode.c
@@ -0,0 +1,280 @@
+/*
+ * Persistent Storage - ramfs parts.
+ *
+ * Copyright (C) 2010 Intel Corporation <tony.luck@intel.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
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/mount.h>
+#include <linux/ramfs.h>
+#include <linux/sched.h>
+#include <linux/magic.h>
+#include <linux/pstore.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "internal.h"
+
+#define PSTORE_NAMELEN 64
+
+struct pstore_private {
+ u64 id;
+ int (*erase)(u64);
+};
+
+#define pstore_get_inode ramfs_get_inode
+
+/*
+ * When a file is unlinked from our file system we call the
+ * platform driver to erase the record from persistent store.
+ */
+static int pstore_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct pstore_private *p = dentry->d_inode->i_private;
+
+ p->erase(p->id);
+ kfree(p);
+
+ return simple_unlink(dir, dentry);
+}
+
+static const struct inode_operations pstore_dir_inode_operations = {
+ .lookup = simple_lookup,
+ .unlink = pstore_unlink,
+};
+
+static const struct super_operations pstore_ops = {
+ .statfs = simple_statfs,
+ .drop_inode = generic_delete_inode,
+ .show_options = generic_show_options,
+};
+
+static struct super_block *pstore_sb;
+static struct vfsmount *pstore_mnt;
+
+int pstore_is_mounted(void)
+{
+ return pstore_mnt != NULL;
+}
+
+/*
+ * Set up a file structure as if we had opened this file and
+ * write our data to it.
+ */
+static int pstore_writefile(struct inode *inode, struct dentry *dentry,
+ char *data, size_t size)
+{
+ struct file f;
+ ssize_t n;
+ mm_segment_t old_fs = get_fs();
+
+ memset(&f, '0', sizeof f);
+ f.f_mapping = inode->i_mapping;
+ f.f_path.dentry = dentry;
+ f.f_path.mnt = pstore_mnt;
+ f.f_pos = 0;
+ f.f_op = inode->i_fop;
+ set_fs(KERNEL_DS);
+ n = do_sync_write(&f, data, size, &f.f_pos);
+ set_fs(old_fs);
+
+ fsnotify_modify(&f);
+
+ return n == size;
+}
+
+/*
+ * Make a regular file in the root directory of our file system.
+ * Load it up with "size" bytes of data from "buf".
+ * Set the mtime & ctime to the date that this record was originally stored.
+ */
+int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
+ char *data, size_t size,
+ struct timespec time, int (*erase)(u64))
+{
+ struct dentry *root = pstore_sb->s_root;
+ struct dentry *dentry;
+ struct inode *inode;
+ int rc;
+ char name[PSTORE_NAMELEN];
+ struct pstore_private *private;
+
+ rc = -ENOMEM;
+ inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0);
+ if (!inode)
+ goto fail;
+ inode->i_uid = inode->i_gid = 0;
+ private = kmalloc(sizeof *private, GFP_KERNEL);
+ if (!private)
+ goto fail_alloc;
+ private->id = id;
+ private->erase = erase;
+
+ switch (type) {
+ case PSTORE_TYPE_DMESG:
+ sprintf(name, "dmesg-%s-%lld", psname, id);
+ break;
+ case PSTORE_TYPE_MCE:
+ sprintf(name, "mce-%s-%lld", psname, id);
+ break;
+ case PSTORE_TYPE_UNKNOWN:
+ sprintf(name, "unknown-%s-%lld", psname, id);
+ break;
+ default:
+ sprintf(name, "type%d-%s-%lld", type, psname, id);
+ break;
+ }
+
+ mutex_lock(&root->d_inode->i_mutex);
+
+ rc = -ENOSPC;
+ dentry = d_alloc_name(root, name);
+ if (IS_ERR(dentry))
+ goto fail_lockedalloc;
+
+ d_add(dentry, inode);
+
+ mutex_unlock(&root->d_inode->i_mutex);
+
+ if (!pstore_writefile(inode, dentry, data, size))
+ goto fail_write;
+
+ inode->i_private = private;
+
+ if (time.tv_sec)
+ inode->i_mtime = inode->i_ctime = time;
+
+ return 0;
+
+fail_write:
+ kfree(private);
+ inode->i_nlink--;
+ mutex_lock(&root->d_inode->i_mutex);
+ d_delete(dentry);
+ dput(dentry);
+ mutex_unlock(&root->d_inode->i_mutex);
+ goto fail;
+
+fail_lockedalloc:
+ mutex_unlock(&root->d_inode->i_mutex);
+ kfree(private);
+fail_alloc:
+ iput(inode);
+
+fail:
+ return rc;
+}
+
+int pstore_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct inode *inode = NULL;
+ struct dentry *root;
+ int err;
+
+ save_mount_options(sb, data);
+
+ pstore_sb = sb;
+
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = PSTOREFS_MAGIC;
+ sb->s_op = &pstore_ops;
+ sb->s_time_gran = 1;
+
+ inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0);
+ if (!inode) {
+ err = -ENOMEM;
+ goto fail;
+ }
+ /* override ramfs "dir" options so we catch unlink(2) */
+ inode->i_op = &pstore_dir_inode_operations;
+
+ root = d_alloc_root(inode);
+ sb->s_root = root;
+ if (!root) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ pstore_get_records();
+
+ return 0;
+fail:
+ iput(inode);
+ return err;
+}
+
+static int pstore_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ struct dentry *root;
+
+ root = mount_nodev(fs_type, flags, data, pstore_fill_super);
+ if (IS_ERR(root))
+ return -ENOMEM;
+
+ mnt->mnt_root = root;
+ mnt->mnt_sb = root->d_sb;
+ pstore_mnt = mnt;
+
+ return 0;
+}
+
+static void pstore_kill_sb(struct super_block *sb)
+{
+ kill_litter_super(sb);
+ pstore_sb = NULL;
+ pstore_mnt = NULL;
+}
+
+static struct file_system_type pstore_fs_type = {
+ .name = "pstore",
+ .get_sb = pstore_get_sb,
+ .kill_sb = pstore_kill_sb,
+};
+
+static int __init init_pstore_fs(void)
+{
+ int ret = 0;
+ struct kobject *pstorefs_kobj;
+
+ pstorefs_kobj = kobject_create_and_add("pstore", fs_kobj);
+ if (!pstorefs_kobj)
+ return -ENOMEM;
+
+ sysfs_create_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
+
+ ret = register_filesystem(&pstore_fs_type);
+
+ if (ret) {
+ sysfs_remove_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
+ kobject_put(pstorefs_kobj);
+ }
+
+ return ret;
+}
+module_init(init_pstore_fs)
+
+MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
new file mode 100644
index 000000000000..76c26d2fab29
--- /dev/null
+++ b/fs/pstore/internal.h
@@ -0,0 +1,7 @@
+extern void pstore_get_records(void);
+extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
+ char *data, size_t size,
+ struct timespec time, int (*erase)(u64));
+extern int pstore_is_mounted(void);
+
+extern struct kobj_attribute pstore_kmsg_bytes_attr;
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
new file mode 100644
index 000000000000..705fdf8abf6e
--- /dev/null
+++ b/fs/pstore/platform.c
@@ -0,0 +1,202 @@
+/*
+ * Persistent Storage - platform driver interface parts.
+ *
+ * Copyright (C) 2010 Intel Corporation <tony.luck@intel.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
+ */
+
+#include <linux/atomic.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kmsg_dump.h>
+#include <linux/module.h>
+#include <linux/pstore.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "internal.h"
+
+/*
+ * pstore_lock just protects "psinfo" during
+ * calls to pstore_register()
+ */
+static DEFINE_SPINLOCK(pstore_lock);
+static struct pstore_info *psinfo;
+
+/* How much of the console log to snapshot. /sys/fs/pstore/kmsg_bytes */
+static unsigned long kmsg_bytes = 10240;
+
+static ssize_t b_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%lu\n", kmsg_bytes);
+}
+
+static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ return (sscanf(buf, "%lu", &kmsg_bytes) > 0) ? count : 0;
+}
+
+struct kobj_attribute pstore_kmsg_bytes_attr =
+ __ATTR(kmsg_bytes, S_IRUGO | S_IWUSR, b_show, b_store);
+
+/* Tag each group of saved records with a sequence number */
+static int oopscount;
+
+/*
+ * callback from kmsg_dump. (s2,l2) has the most recently
+ * written bytes, older bytes are in (s1,l1). Save as much
+ * as we can from the end of the buffer.
+ */
+static void pstore_dump(struct kmsg_dumper *dumper,
+ enum kmsg_dump_reason reason,
+ const char *s1, unsigned long l1,
+ const char *s2, unsigned long l2)
+{
+ unsigned long s1_start, s2_start;
+ unsigned long l1_cpy, l2_cpy;
+ unsigned long size, total = 0;
+ char *dst;
+ u64 id;
+ int hsize, part = 1;
+
+ mutex_lock(&psinfo->buf_mutex);
+ oopscount++;
+ while (total < kmsg_bytes) {
+ dst = psinfo->buf;
+ hsize = sprintf(dst, "Oops#%d Part%d\n", oopscount, part++);
+ size = psinfo->bufsize - hsize;
+ dst += hsize;
+
+ l2_cpy = min(l2, size);
+ l1_cpy = min(l1, size - l2_cpy);
+
+ if (l1_cpy + l2_cpy == 0)
+ break;
+
+ s2_start = l2 - l2_cpy;
+ s1_start = l1 - l1_cpy;
+
+ memcpy(dst, s1 + s1_start, l1_cpy);
+ memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);
+
+ id = psinfo->write(PSTORE_TYPE_DMESG, hsize + l1_cpy + l2_cpy);
+ if (pstore_is_mounted())
+ pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
+ psinfo->buf, hsize + l1_cpy + l2_cpy,
+ CURRENT_TIME, psinfo->erase);
+ l1 -= l1_cpy;
+ l2 -= l2_cpy;
+ total += l1_cpy + l2_cpy;
+ }
+ mutex_unlock(&psinfo->buf_mutex);
+}
+
+static struct kmsg_dumper pstore_dumper = {
+ .dump = pstore_dump,
+};
+
+/*
+ * platform specific persistent storage driver registers with
+ * us here. If pstore is already mounted, call the platform
+ * read function right away to populate the file system. If not
+ * then the pstore mount code will call us later to fill out
+ * the file system.
+ *
+ * Register with kmsg_dump to save last part of console log on panic.
+ */
+int pstore_register(struct pstore_info *psi)
+{
+ struct module *owner = psi->owner;
+
+ spin_lock(&pstore_lock);
+ if (psinfo) {
+ spin_unlock(&pstore_lock);
+ return -EBUSY;
+ }
+ psinfo = psi;
+ spin_unlock(&pstore_lock);
+
+ if (owner && !try_module_get(owner)) {
+ psinfo = NULL;
+ return -EINVAL;
+ }
+
+ if (pstore_is_mounted())
+ pstore_get_records();
+
+ kmsg_dump_register(&pstore_dumper);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pstore_register);
+
+/*
+ * Read all the records from the persistent store. Create and
+ * file files in our filesystem.
+ */
+void pstore_get_records(void)
+{
+ struct pstore_info *psi = psinfo;
+ size_t size;
+ u64 id;
+ enum pstore_type_id type;
+ struct timespec time;
+ int failed = 0;
+
+ if (!psi)
+ return;
+
+ mutex_lock(&psinfo->buf_mutex);
+ while ((size = psi->read(&id, &type, &time)) > 0) {
+ if (pstore_mkfile(type, psi->name, id, psi->buf, size,
+ time, psi->erase))
+ failed++;
+ }
+ mutex_unlock(&psinfo->buf_mutex);
+
+ if (failed)
+ printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
+ failed, psi->name);
+}
+
+/*
+ * Call platform driver to write a record to the
+ * persistent store.
+ */
+int pstore_write(enum pstore_type_id type, char *buf, size_t size)
+{
+ u64 id;
+
+ if (!psinfo)
+ return -ENODEV;
+
+ if (size > psinfo->bufsize)
+ return -EFBIG;
+
+ mutex_lock(&psinfo->buf_mutex);
+ memcpy(psinfo->buf, buf, size);
+ id = psinfo->write(type, size);
+ if (pstore_is_mounted())
+ pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id, psinfo->buf,
+ size, CURRENT_TIME, psinfo->erase);
+ mutex_unlock(&psinfo->buf_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pstore_write);
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index fcada42f1aa3..e63b4171d583 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -425,11 +425,18 @@ static struct inode *qnx4_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void qnx4_destroy_inode(struct inode *inode)
+static void qnx4_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
}
+static void qnx4_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, qnx4_i_callback);
+}
+
static void init_once(void *foo)
{
struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index d31bce1a9f90..3eea859e6990 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2551,8 +2551,6 @@ static int release_journal_dev(struct super_block *super,
result = 0;
if (journal->j_dev_bd != NULL) {
- if (journal->j_dev_bd->bd_dev != super->s_dev)
- bd_release(journal->j_dev_bd);
result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
journal->j_dev_bd = NULL;
}
@@ -2570,7 +2568,7 @@ static int journal_init_dev(struct super_block *super,
{
int result;
dev_t jdev;
- fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE;
+ fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
char b[BDEVNAME_SIZE];
result = 0;
@@ -2584,7 +2582,10 @@ static int journal_init_dev(struct super_block *super,
/* there is no "jdev" option and journal is on separate device */
if ((!jdev_name || !jdev_name[0])) {
- journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode);
+ if (jdev == super->s_dev)
+ blkdev_mode &= ~FMODE_EXCL;
+ journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode,
+ journal);
journal->j_dev_mode = blkdev_mode;
if (IS_ERR(journal->j_dev_bd)) {
result = PTR_ERR(journal->j_dev_bd);
@@ -2593,22 +2594,14 @@ static int journal_init_dev(struct super_block *super,
"cannot init journal device '%s': %i",
__bdevname(jdev, b), result);
return result;
- } else if (jdev != super->s_dev) {
- result = bd_claim(journal->j_dev_bd, journal);
- if (result) {
- blkdev_put(journal->j_dev_bd, blkdev_mode);
- return result;
- }
-
+ } else if (jdev != super->s_dev)
set_blocksize(journal->j_dev_bd, super->s_blocksize);
- }
return 0;
}
journal->j_dev_mode = blkdev_mode;
- journal->j_dev_bd = open_bdev_exclusive(jdev_name,
- blkdev_mode, journal);
+ journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal);
if (IS_ERR(journal->j_dev_bd)) {
result = PTR_ERR(journal->j_dev_bd);
journal->j_dev_bd = NULL;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b243117b8752..2575682a9ead 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -529,11 +529,18 @@ static struct inode *reiserfs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void reiserfs_destroy_inode(struct inode *inode)
+static void reiserfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
}
+static void reiserfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, reiserfs_i_callback);
+}
+
static void init_once(void *foo)
{
struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 5d04a7828e7a..e0f0d7ea10a1 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -990,7 +990,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
strlen(PRIVROOT_NAME));
if (!IS_ERR(dentry)) {
REISERFS_SB(s)->priv_root = dentry;
- dentry->d_op = &xattr_lookup_poison_ops;
+ d_set_d_op(dentry, &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 536d697a8a28..90d2fcb67a31 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -472,7 +472,9 @@ int reiserfs_acl_chmod(struct inode *inode)
struct reiserfs_transaction_handle th;
size_t size = reiserfs_xattr_nblocks(inode,
reiserfs_acl_size(clone->a_count));
- reiserfs_write_lock(inode->i_sb);
+ int depth;
+
+ depth = reiserfs_write_lock_once(inode->i_sb);
error = journal_begin(&th, inode->i_sb, size * 2);
if (!error) {
int error2;
@@ -482,7 +484,7 @@ int reiserfs_acl_chmod(struct inode *inode)
if (error2)
error = error2;
}
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, depth);
}
posix_acl_release(clone);
return error;
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 6647f90e55cd..2305e3121cb1 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -400,11 +400,18 @@ static struct inode *romfs_alloc_inode(struct super_block *sb)
/*
* return a spent inode to the slab cache
*/
-static void romfs_destroy_inode(struct inode *inode)
+static void romfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
}
+static void romfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, romfs_i_callback);
+}
+
/*
* get filesystem statistics
*/
diff --git a/fs/splice.c b/fs/splice.c
index ce2f02579e35..50a5d978da16 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -682,19 +682,14 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
{
struct file *file = sd->u.file;
loff_t pos = sd->pos;
- int ret, more;
-
- ret = buf->ops->confirm(pipe, buf);
- if (!ret) {
- more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
- if (file->f_op && file->f_op->sendpage)
- ret = file->f_op->sendpage(file, buf->page, buf->offset,
- sd->len, &pos, more);
- else
- ret = -EINVAL;
- }
+ int more;
- return ret;
+ if (!likely(file->f_op && file->f_op->sendpage))
+ return -EINVAL;
+
+ more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
+ return file->f_op->sendpage(file, buf->page, buf->offset,
+ sd->len, &pos, more);
}
/*
@@ -727,13 +722,6 @@ int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
void *fsdata;
int ret;
- /*
- * make sure the data in this buffer is uptodate
- */
- ret = buf->ops->confirm(pipe, buf);
- if (unlikely(ret))
- return ret;
-
offset = sd->pos & ~PAGE_CACHE_MASK;
this_len = sd->len;
@@ -805,12 +793,17 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
if (sd->len > sd->total_len)
sd->len = sd->total_len;
- ret = actor(pipe, buf, sd);
- if (ret <= 0) {
+ ret = buf->ops->confirm(pipe, buf);
+ if (unlikely(ret)) {
if (ret == -ENODATA)
ret = 0;
return ret;
}
+
+ ret = actor(pipe, buf, sd);
+ if (ret <= 0)
+ return ret;
+
buf->offset += ret;
buf->len -= ret;
@@ -1044,10 +1037,6 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
int ret;
void *data;
- ret = buf->ops->confirm(pipe, buf);
- if (ret)
- return ret;
-
data = buf->ops->map(pipe, buf, 0);
ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
buf->ops->unmap(pipe, buf, data);
@@ -1495,10 +1484,6 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
char *src;
int ret;
- ret = buf->ops->confirm(pipe, buf);
- if (unlikely(ret))
- return ret;
-
/*
* See if we can use the atomic maps, by prefaulting in the
* pages and doing an atomic copy
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 24de30ba34c1..20700b9f2b4c 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -440,11 +440,18 @@ static struct inode *squashfs_alloc_inode(struct super_block *sb)
}
-static void squashfs_destroy_inode(struct inode *inode)
+static void squashfs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
}
+static void squashfs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, squashfs_i_callback);
+}
+
static struct file_system_type squashfs_fs_type = {
.owner = THIS_MODULE,
diff --git a/fs/super.c b/fs/super.c
index ca696155cd9a..4f6a3571a634 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -30,6 +30,7 @@
#include <linux/idr.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
+#include <linux/rculist_bl.h>
#include "internal.h"
@@ -71,7 +72,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
INIT_LIST_HEAD(&s->s_files);
#endif
INIT_LIST_HEAD(&s->s_instances);
- INIT_HLIST_HEAD(&s->s_anon);
+ INIT_HLIST_BL_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes);
INIT_LIST_HEAD(&s->s_dentry_lru);
init_rwsem(&s->s_umount);
@@ -766,13 +767,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
{
struct block_device *bdev;
struct super_block *s;
- fmode_t mode = FMODE_READ;
+ fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0;
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
- bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+ bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
@@ -801,13 +802,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
/*
* s_umount nests inside bd_mutex during
- * __invalidate_device(). close_bdev_exclusive()
- * acquires bd_mutex and can't be called under
- * s_umount. Drop s_umount temporarily. This is safe
- * as we're holding an active reference.
+ * __invalidate_device(). blkdev_put() acquires
+ * bd_mutex and can't be called under s_umount. Drop
+ * s_umount temporarily. This is safe as we're
+ * holding an active reference.
*/
up_write(&s->s_umount);
- close_bdev_exclusive(bdev, mode);
+ blkdev_put(bdev, mode);
down_write(&s->s_umount);
} else {
char b[BDEVNAME_SIZE];
@@ -831,7 +832,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error_s:
error = PTR_ERR(s);
error_bdev:
- close_bdev_exclusive(bdev, mode);
+ blkdev_put(bdev, mode);
error:
return ERR_PTR(error);
}
@@ -862,7 +863,8 @@ void kill_block_super(struct super_block *sb)
bdev->bd_super = NULL;
generic_shutdown_super(sb);
sync_blockdev(bdev);
- close_bdev_exclusive(bdev, mode);
+ WARN_ON_ONCE(!(mode & FMODE_EXCL));
+ blkdev_put(bdev, mode | FMODE_EXCL);
}
EXPORT_SYMBOL(kill_block_super);
@@ -1139,7 +1141,7 @@ static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
return mnt;
err:
- mntput(mnt);
+ mntput_long(mnt);
return ERR_PTR(err);
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 7e54bac8c4b0..c3fff5788b51 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -231,18 +231,27 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
goto repeat;
}
-static int sysfs_dentry_delete(struct dentry *dentry)
+static int sysfs_dentry_delete(const struct dentry *dentry)
{
struct sysfs_dirent *sd = dentry->d_fsdata;
return !!(sd->s_flags & SYSFS_FLAG_REMOVED);
}
-static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int sysfs_dentry_revalidate_rcu(struct dentry *dentry, struct nameidata *nd)
{
struct sysfs_dirent *sd = dentry->d_fsdata;
int is_dir;
- mutex_lock(&sysfs_mutex);
+ if (nd->flags & LOOKUP_RCU) {
+ if (!mutex_trylock(&sysfs_mutex))
+ return -ECHILD;
+ /* ensure dentry still exists, now under the sysfs_mutex */
+ if (read_seqcount_retry(&dentry->d_seq, nd->seq)) {
+ mutex_unlock(&sysfs_mutex);
+ return -ECHILD;
+ }
+ } else
+ mutex_lock(&sysfs_mutex);
/* The sysfs dirent has been deleted */
if (sd->s_flags & SYSFS_FLAG_REMOVED)
@@ -272,6 +281,9 @@ out_bad:
*/
is_dir = (sysfs_type(sd) == SYSFS_DIR);
mutex_unlock(&sysfs_mutex);
+ if (nd->flags & LOOKUP_RCU)
+ return -ECHILD;
+
if (is_dir) {
/* If we have submounts we must allow the vfs caches
* to lie about the state of the filesystem to prevent
@@ -294,7 +306,7 @@ static void sysfs_dentry_iput(struct dentry *dentry, struct inode *inode)
}
static const struct dentry_operations sysfs_dentry_ops = {
- .d_revalidate = sysfs_dentry_revalidate,
+ .d_revalidate_rcu = sysfs_dentry_revalidate_rcu,
.d_delete = sysfs_dentry_delete,
.d_iput = sysfs_dentry_iput,
};
@@ -701,7 +713,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
/* instantiate and hash dentry */
ret = d_find_alias(inode);
if (!ret) {
- dentry->d_op = &sysfs_dentry_ops;
+ d_set_d_op(dentry, &sysfs_dentry_ops);
dentry->d_fsdata = sysfs_get(sd);
d_add(dentry, inode);
} else {
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index de44d067b9e6..0630eb969a28 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -333,11 +333,18 @@ static struct inode *sysv_alloc_inode(struct super_block *sb)
return &si->vfs_inode;
}
-static void sysv_destroy_inode(struct inode *inode)
+static void sysv_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(sysv_inode_cachep, SYSV_I(inode));
}
+static void sysv_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, sysv_i_callback);
+}
+
static void init_once(void *p)
{
struct sysv_inode_info *si = (struct sysv_inode_info *)p;
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 11e7f7d11cd0..b5e68da2db32 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -27,7 +27,8 @@ static int add_nondir(struct dentry *dentry, struct inode *inode)
return err;
}
-static int sysv_hash(struct dentry *dentry, struct qstr *qstr)
+static int sysv_hash(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *qstr)
{
/* Truncate the name in place, avoids having to define a compare
function. */
@@ -47,7 +48,7 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st
struct inode * inode = NULL;
ino_t ino;
- dentry->d_op = dir->i_sb->s_root->d_op;
+ d_set_d_op(dentry, dir->i_sb->s_root->d_op);
if (dentry->d_name.len > SYSV_NAMELEN)
return ERR_PTR(-ENAMETOOLONG);
ino = sysv_inode_by_name(dentry);
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 3d9c62be0c10..76712aefc4ab 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -346,7 +346,7 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
if (sbi->s_forced_ro)
sb->s_flags |= MS_RDONLY;
if (sbi->s_truncate)
- sb->s_root->d_op = &sysv_dentry_operations;
+ d_set_d_op(sb->s_root, &sysv_dentry_operations);
return 1;
}
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 91fac54c70e3..6e11c2975dcf 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -272,12 +272,20 @@ static struct inode *ubifs_alloc_inode(struct super_block *sb)
return &ui->vfs_inode;
};
+static void ubifs_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct ubifs_inode *ui = ubifs_inode(inode);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(ubifs_inode_slab, ui);
+}
+
static void ubifs_destroy_inode(struct inode *inode)
{
struct ubifs_inode *ui = ubifs_inode(inode);
kfree(ui->data);
- kmem_cache_free(ubifs_inode_slab, inode);
+ call_rcu(&inode->i_rcu, ubifs_i_callback);
}
/*
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index b608efaa4cee..306ee39ef2c3 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -157,10 +157,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
udf_debug("bit %ld already set\n", bit + i);
udf_debug("byte=%2x\n",
((char *)bh->b_data)[(bit + i) >> 3]);
- } else {
- udf_add_free_space(sb, sbi->s_partition, 1);
}
}
+ udf_add_free_space(sb, sbi->s_partition, count);
mark_buffer_dirty(bh);
if (overflow) {
block += count;
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 51552bf50225..eb8bfe2b89a5 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -30,7 +30,6 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include "udf_i.h"
@@ -190,18 +189,14 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct inode *dir = filp->f_path.dentry->d_inode;
int result;
- lock_kernel();
-
if (filp->f_pos == 0) {
if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) {
- unlock_kernel();
return 0;
}
filp->f_pos++;
}
result = do_udf_readdir(dir, filp, filldir, dirent);
- unlock_kernel();
return result;
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 66b9e7e7e4c5..89c78486cbbe 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -32,7 +32,6 @@
#include <linux/string.h> /* memset */
#include <linux/capability.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/aio.h>
@@ -114,6 +113,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
size_t count = iocb->ki_left;
struct udf_inode_info *iinfo = UDF_I(inode);
+ down_write(&iinfo->i_data_sem);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
if (file->f_flags & O_APPEND)
pos = inode->i_size;
@@ -126,6 +126,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
udf_expand_file_adinicb(inode, pos + count, &err);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
udf_debug("udf_expand_adinicb: err=%d\n", err);
+ up_write(&iinfo->i_data_sem);
return err;
}
} else {
@@ -135,6 +136,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
iinfo->i_lenAlloc = inode->i_size;
}
}
+ up_write(&iinfo->i_data_sem);
retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
if (retval > 0)
@@ -149,8 +151,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
long old_block, new_block;
int result = -EINVAL;
- lock_kernel();
-
if (file_permission(filp, MAY_READ) != 0) {
udf_debug("no permission to access inode %lu\n", inode->i_ino);
result = -EPERM;
@@ -196,7 +196,6 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
out:
- unlock_kernel();
return result;
}
@@ -204,10 +203,10 @@ static int udf_release_file(struct inode *inode, struct file *filp)
{
if (filp->f_mode & FMODE_WRITE) {
mutex_lock(&inode->i_mutex);
- lock_kernel();
+ down_write(&UDF_I(inode)->i_data_sem);
udf_discard_prealloc(inode);
udf_truncate_tail_extent(inode);
- unlock_kernel();
+ up_write(&UDF_I(inode)->i_data_sem);
mutex_unlock(&inode->i_mutex);
}
return 0;
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 75d9304d0dc3..6fb7e0adcda0 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
return NULL;
}
- mutex_lock(&sbi->s_alloc_mutex);
if (sbi->s_lvid_bh) {
- struct logicalVolIntegrityDesc *lvid =
- (struct logicalVolIntegrityDesc *)
- sbi->s_lvid_bh->b_data;
- struct logicalVolIntegrityDescImpUse *lvidiu =
- udf_sb_lvidiu(sbi);
- struct logicalVolHeaderDesc *lvhd;
- uint64_t uniqueID;
- lvhd = (struct logicalVolHeaderDesc *)
- (lvid->logicalVolContentsUse);
+ struct logicalVolIntegrityDescImpUse *lvidiu;
+
+ iinfo->i_unique = lvid_get_unique_id(sb);
+ mutex_lock(&sbi->s_alloc_mutex);
+ lvidiu = udf_sb_lvidiu(sbi);
if (S_ISDIR(mode))
le32_add_cpu(&lvidiu->numDirs, 1);
else
le32_add_cpu(&lvidiu->numFiles, 1);
- iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID);
- if (!(++uniqueID & 0x00000000FFFFFFFFUL))
- uniqueID += 16;
- lvhd->uniqueID = cpu_to_le64(uniqueID);
udf_updated_lvid(sb);
+ mutex_unlock(&sbi->s_alloc_mutex);
}
- mutex_unlock(&sbi->s_alloc_mutex);
inode_init_owner(inode, dir, mode);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index fc48f37aa2dd..c6a2e782b97b 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -31,7 +31,6 @@
#include "udfdecl.h"
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
@@ -51,6 +50,7 @@ MODULE_LICENSE("GPL");
static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
+static int udf_sync_inode(struct inode *inode);
static int udf_alloc_i_data(struct inode *inode, size_t size);
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
sector_t *, int *);
@@ -79,9 +79,7 @@ void udf_evict_inode(struct inode *inode)
want_delete = 1;
inode->i_size = 0;
udf_truncate(inode);
- lock_kernel();
udf_update_inode(inode, IS_SYNC(inode));
- unlock_kernel();
}
invalidate_inode_buffers(inode);
end_writeback(inode);
@@ -97,9 +95,7 @@ void udf_evict_inode(struct inode *inode)
kfree(iinfo->i_ext.i_data);
iinfo->i_ext.i_data = NULL;
if (want_delete) {
- lock_kernel();
udf_free_inode(inode);
- unlock_kernel();
}
}
@@ -302,10 +298,9 @@ static int udf_get_block(struct inode *inode, sector_t block,
err = -EIO;
new = 0;
bh = NULL;
-
- lock_kernel();
-
iinfo = UDF_I(inode);
+
+ down_write(&iinfo->i_data_sem);
if (block == iinfo->i_next_alloc_block + 1) {
iinfo->i_next_alloc_block++;
iinfo->i_next_alloc_goal++;
@@ -324,7 +319,7 @@ static int udf_get_block(struct inode *inode, sector_t block,
map_bh(bh_result, inode->i_sb, phys);
abort:
- unlock_kernel();
+ up_write(&iinfo->i_data_sem);
return err;
}
@@ -1022,16 +1017,16 @@ void udf_truncate(struct inode *inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
- lock_kernel();
iinfo = UDF_I(inode);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+ down_write(&iinfo->i_data_sem);
if (inode->i_sb->s_blocksize <
(udf_file_entry_alloc_offset(inode) +
inode->i_size)) {
udf_expand_file_adinicb(inode, inode->i_size, &err);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
inode->i_size = iinfo->i_lenAlloc;
- unlock_kernel();
+ up_write(&iinfo->i_data_sem);
return;
} else
udf_truncate_extents(inode);
@@ -1042,10 +1037,13 @@ void udf_truncate(struct inode *inode)
offset - udf_file_entry_alloc_offset(inode));
iinfo->i_lenAlloc = inode->i_size;
}
+ up_write(&iinfo->i_data_sem);
} else {
block_truncate_page(inode->i_mapping, inode->i_size,
udf_get_block);
+ down_write(&iinfo->i_data_sem);
udf_truncate_extents(inode);
+ up_write(&iinfo->i_data_sem);
}
inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
@@ -1053,7 +1051,6 @@ void udf_truncate(struct inode *inode)
udf_sync_inode(inode);
else
mark_inode_dirty(inode);
- unlock_kernel();
}
static void __udf_read_inode(struct inode *inode)
@@ -1202,6 +1199,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
return;
}
+ read_lock(&sbi->s_cred_lock);
inode->i_uid = le32_to_cpu(fe->uid);
if (inode->i_uid == -1 ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
@@ -1214,13 +1212,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
- inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
- if (!inode->i_nlink)
- inode->i_nlink = 1;
-
- inode->i_size = le64_to_cpu(fe->informationLength);
- iinfo->i_lenExtents = inode->i_size;
-
if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
sbi->s_fmode != UDF_INVALID_MODE)
inode->i_mode = sbi->s_fmode;
@@ -1230,6 +1221,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
else
inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~sbi->s_umask;
+ read_unlock(&sbi->s_cred_lock);
+
+ inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
+ if (!inode->i_nlink)
+ inode->i_nlink = 1;
+
+ inode->i_size = le64_to_cpu(fe->informationLength);
+ iinfo->i_lenExtents = inode->i_size;
if (iinfo->i_efe == 0) {
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
@@ -1373,16 +1372,10 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)
int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
{
- int ret;
-
- lock_kernel();
- ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
- unlock_kernel();
-
- return ret;
+ return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}
-int udf_sync_inode(struct inode *inode)
+static int udf_sync_inode(struct inode *inode)
{
return udf_update_inode(inode, 1);
}
@@ -2048,7 +2041,7 @@ long udf_block_map(struct inode *inode, sector_t block)
struct extent_position epos = {};
int ret;
- lock_kernel();
+ down_read(&UDF_I(inode)->i_data_sem);
if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30))
@@ -2056,7 +2049,7 @@ long udf_block_map(struct inode *inode, sector_t block)
else
ret = 0;
- unlock_kernel();
+ up_read(&UDF_I(inode)->i_data_sem);
brelse(epos.bh);
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 6d8dc02baebb..a2974f7563a2 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -27,7 +27,6 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/sched.h>
#include <linux/crc-itu-t.h>
@@ -263,7 +262,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
if (dentry->d_name.len > UDF_NAME_LEN - 2)
return ERR_PTR(-ENAMETOOLONG);
- lock_kernel();
#ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3)) {
@@ -275,7 +273,6 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
};
inode = udf_iget(dir->i_sb, lb);
if (!inode) {
- unlock_kernel();
return ERR_PTR(-EACCES);
}
} else
@@ -291,11 +288,9 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
loc = lelb_to_cpu(cfi.icb.extLocation);
inode = udf_iget(dir->i_sb, &loc);
if (!inode) {
- unlock_kernel();
return ERR_PTR(-EACCES);
}
}
- unlock_kernel();
return d_splice_alias(inode, dentry);
}
@@ -476,15 +471,19 @@ add:
f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
if (!fibh->ebh)
goto out_err;
+ /* Extents could have been merged, invalidate our position */
+ brelse(epos.bh);
+ epos.bh = NULL;
+ epos.block = dinfo->i_location;
+ epos.offset = udf_file_entry_alloc_offset(dir);
if (!fibh->soffset) {
- if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
- (EXT_RECORDED_ALLOCATED >> 30)) {
- block = eloc.logicalBlockNum + ((elen - 1) >>
+ /* Find the freshly allocated block */
+ while (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
+ (EXT_RECORDED_ALLOCATED >> 30))
+ ;
+ block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits);
- } else
- block++;
-
brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
@@ -562,10 +561,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
int err;
struct udf_inode_info *iinfo;
- lock_kernel();
inode = udf_new_inode(dir, mode, &err);
if (!inode) {
- unlock_kernel();
return err;
}
@@ -583,7 +580,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
inode->i_nlink--;
mark_inode_dirty(inode);
iput(inode);
- unlock_kernel();
return err;
}
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
@@ -596,7 +592,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh);
brelse(fibh.sbh);
- unlock_kernel();
d_instantiate(dentry, inode);
return 0;
@@ -614,7 +609,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
if (!old_valid_dev(rdev))
return -EINVAL;
- lock_kernel();
err = -EIO;
inode = udf_new_inode(dir, mode, &err);
if (!inode)
@@ -627,7 +621,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
inode->i_nlink--;
mark_inode_dirty(inode);
iput(inode);
- unlock_kernel();
return err;
}
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
@@ -646,7 +639,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
err = 0;
out:
- unlock_kernel();
return err;
}
@@ -659,7 +651,6 @@ 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;
- lock_kernel();
err = -EMLINK;
if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
goto out;
@@ -712,7 +703,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
err = 0;
out:
- unlock_kernel();
return err;
}
@@ -794,7 +784,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
struct kernel_lb_addr tloc;
retval = -ENOENT;
- lock_kernel();
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
if (!fi)
goto out;
@@ -826,7 +815,6 @@ end_rmdir:
brelse(fibh.sbh);
out:
- unlock_kernel();
return retval;
}
@@ -840,7 +828,6 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
struct kernel_lb_addr tloc;
retval = -ENOENT;
- lock_kernel();
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
if (!fi)
goto out;
@@ -870,7 +857,6 @@ end_unlink:
brelse(fibh.sbh);
out:
- unlock_kernel();
return retval;
}
@@ -890,21 +876,21 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
int block;
unsigned char *name = NULL;
int namelen;
- struct buffer_head *bh;
struct udf_inode_info *iinfo;
+ struct super_block *sb = dir->i_sb;
- lock_kernel();
inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err);
if (!inode)
goto out;
+ iinfo = UDF_I(inode);
+ down_write(&iinfo->i_data_sem);
name = kmalloc(UDF_NAME_LEN, GFP_NOFS);
if (!name) {
err = -ENOMEM;
goto out_no_entry;
}
- iinfo = UDF_I(inode);
inode->i_data.a_ops = &udf_symlink_aops;
inode->i_op = &udf_symlink_inode_operations;
@@ -912,7 +898,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
struct kernel_lb_addr eloc;
uint32_t bsize;
- block = udf_new_block(inode->i_sb, inode,
+ block = udf_new_block(sb, inode,
iinfo->i_location.partitionReferenceNum,
iinfo->i_location.logicalBlockNum, &err);
if (!block)
@@ -923,17 +909,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
eloc.logicalBlockNum = block;
eloc.partitionReferenceNum =
iinfo->i_location.partitionReferenceNum;
- bsize = inode->i_sb->s_blocksize;
+ bsize = sb->s_blocksize;
iinfo->i_lenExtents = bsize;
udf_add_aext(inode, &epos, &eloc, bsize, 0);
brelse(epos.bh);
- block = udf_get_pblock(inode->i_sb, block,
+ block = udf_get_pblock(sb, block,
iinfo->i_location.partitionReferenceNum,
0);
- epos.bh = udf_tgetblk(inode->i_sb, block);
+ epos.bh = udf_tgetblk(sb, block);
lock_buffer(epos.bh);
- memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
+ memset(epos.bh->b_data, 0x00, bsize);
set_buffer_uptodate(epos.bh);
unlock_buffer(epos.bh);
mark_buffer_dirty_inode(epos.bh, inode);
@@ -941,7 +927,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
} else
ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
- eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
+ eoffset = sb->s_blocksize - udf_ext0_offset(inode);
pc = (struct pathComponent *)ea;
if (*symname == '/') {
@@ -981,7 +967,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
}
if (pc->componentType == 5) {
- namelen = udf_put_filename(inode->i_sb, compstart, name,
+ namelen = udf_put_filename(sb, compstart, name,
symname - compstart);
if (!namelen)
goto out_no_entry;
@@ -1015,27 +1001,16 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
if (!fi)
goto out_no_entry;
- cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
+ cfi.icb.extLength = cpu_to_le32(sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
- bh = UDF_SB(inode->i_sb)->s_lvid_bh;
- if (bh) {
- struct logicalVolIntegrityDesc *lvid =
- (struct logicalVolIntegrityDesc *)bh->b_data;
- struct logicalVolHeaderDesc *lvhd;
- uint64_t uniqueID;
- lvhd = (struct logicalVolHeaderDesc *)
- lvid->logicalVolContentsUse;
- uniqueID = le64_to_cpu(lvhd->uniqueID);
+ if (UDF_SB(inode->i_sb)->s_lvid_bh) {
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
- cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
- if (!(++uniqueID & 0x00000000FFFFFFFFUL))
- uniqueID += 16;
- lvhd->uniqueID = cpu_to_le64(uniqueID);
- mark_buffer_dirty(bh);
+ cpu_to_le32(lvid_get_unique_id(sb));
}
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
mark_inode_dirty(dir);
+ up_write(&iinfo->i_data_sem);
if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh);
brelse(fibh.sbh);
@@ -1044,10 +1019,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
out:
kfree(name);
- unlock_kernel();
return err;
out_no_entry:
+ up_write(&iinfo->i_data_sem);
inode_dec_link_count(inode);
iput(inode);
goto out;
@@ -1060,36 +1035,20 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
struct udf_fileident_bh fibh;
struct fileIdentDesc cfi, *fi;
int err;
- struct buffer_head *bh;
- lock_kernel();
if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
- unlock_kernel();
return -EMLINK;
}
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
if (!fi) {
- unlock_kernel();
return err;
}
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location);
- bh = UDF_SB(inode->i_sb)->s_lvid_bh;
- if (bh) {
- struct logicalVolIntegrityDesc *lvid =
- (struct logicalVolIntegrityDesc *)bh->b_data;
- struct logicalVolHeaderDesc *lvhd;
- uint64_t uniqueID;
- lvhd = (struct logicalVolHeaderDesc *)
- (lvid->logicalVolContentsUse);
- uniqueID = le64_to_cpu(lvhd->uniqueID);
+ if (UDF_SB(inode->i_sb)->s_lvid_bh) {
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
- cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
- if (!(++uniqueID & 0x00000000FFFFFFFFUL))
- uniqueID += 16;
- lvhd->uniqueID = cpu_to_le64(uniqueID);
- mark_buffer_dirty(bh);
+ cpu_to_le32(lvid_get_unique_id(inode->i_sb));
}
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
@@ -1103,7 +1062,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
mark_inode_dirty(inode);
ihold(inode);
d_instantiate(dentry, inode);
- unlock_kernel();
return 0;
}
@@ -1124,7 +1082,6 @@ 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);
- lock_kernel();
ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
if (ofi) {
if (ofibh.sbh != ofibh.ebh)
@@ -1248,7 +1205,6 @@ end_rename:
brelse(nfibh.ebh);
brelse(nfibh.sbh);
}
- unlock_kernel();
return retval;
}
@@ -1261,7 +1217,6 @@ static struct dentry *udf_get_parent(struct dentry *child)
struct fileIdentDesc cfi;
struct udf_fileident_bh fibh;
- lock_kernel();
if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
goto out_unlock;
@@ -1273,11 +1228,9 @@ static struct dentry *udf_get_parent(struct dentry *child)
inode = udf_iget(child->d_inode->i_sb, &tloc);
if (!inode)
goto out_unlock;
- unlock_kernel();
return d_obtain_alias(inode);
out_unlock:
- unlock_kernel();
return ERR_PTR(-EACCES);
}
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 745eb209be0c..a71090ea0e07 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -25,6 +25,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/buffer_head.h>
+#include <linux/mutex.h>
uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
uint16_t partition, uint32_t offset)
@@ -159,7 +160,9 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
struct udf_sb_info *sbi = UDF_SB(sb);
u16 reallocationTableLen;
struct buffer_head *bh;
+ int ret = 0;
+ mutex_lock(&sbi->s_alloc_mutex);
for (i = 0; i < sbi->s_partitions; i++) {
struct udf_part_map *map = &sbi->s_partmaps[i];
if (old_block > map->s_partition_root &&
@@ -175,8 +178,10 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
break;
}
- if (!st)
- return 1;
+ if (!st) {
+ ret = 1;
+ goto out;
+ }
reallocationTableLen =
le16_to_cpu(st->reallocationTableLen);
@@ -207,14 +212,16 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
((old_block -
map->s_partition_root) &
(sdata->s_packet_len - 1));
- return 0;
+ ret = 0;
+ goto out;
} else if (origLoc == packet) {
*new_block = le32_to_cpu(
entry->mappedLocation) +
((old_block -
map->s_partition_root) &
(sdata->s_packet_len - 1));
- return 0;
+ ret = 0;
+ goto out;
} else if (origLoc > packet)
break;
}
@@ -251,20 +258,24 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
st->mapEntry[k].mappedLocation) +
((old_block - map->s_partition_root) &
(sdata->s_packet_len - 1));
- return 0;
+ ret = 0;
+ goto out;
}
- return 1;
+ ret = 1;
+ goto out;
} /* if old_block */
}
if (i == sbi->s_partitions) {
/* outside of partitions */
/* for now, fail =) */
- return 1;
+ ret = 1;
}
- return 0;
+out:
+ mutex_unlock(&sbi->s_alloc_mutex);
+ return ret;
}
static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 4a5c7c61836a..7b27b063ff6d 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -48,7 +48,6 @@
#include <linux/stat.h>
#include <linux/cdrom.h>
#include <linux/nls.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
#include <linux/vmalloc.h>
@@ -135,15 +134,23 @@ static struct inode *udf_alloc_inode(struct super_block *sb)
ei->i_next_alloc_block = 0;
ei->i_next_alloc_goal = 0;
ei->i_strat4096 = 0;
+ init_rwsem(&ei->i_data_sem);
return &ei->vfs_inode;
}
-static void udf_destroy_inode(struct inode *inode)
+static void udf_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(udf_inode_cachep, UDF_I(inode));
}
+static void udf_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, udf_i_callback);
+}
+
static void init_once(void *foo)
{
struct udf_inode_info *ei = (struct udf_inode_info *)foo;
@@ -567,13 +574,14 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
if (!udf_parse_options(options, &uopt, true))
return -EINVAL;
- lock_kernel();
+ write_lock(&sbi->s_cred_lock);
sbi->s_flags = uopt.flags;
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
sbi->s_fmode = uopt.fmode;
sbi->s_dmode = uopt.dmode;
+ write_unlock(&sbi->s_cred_lock);
if (sbi->s_lvid_bh) {
int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
@@ -590,7 +598,6 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
udf_open_lvid(sb);
out_unlock:
- unlock_kernel();
return error;
}
@@ -959,9 +966,9 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
(sizeof(struct buffer_head *) * nr_groups);
if (size <= PAGE_SIZE)
- bitmap = kmalloc(size, GFP_KERNEL);
+ bitmap = kzalloc(size, GFP_KERNEL);
else
- bitmap = vmalloc(size); /* TODO: get rid of vmalloc */
+ bitmap = vzalloc(size); /* TODO: get rid of vzalloc */
if (bitmap == NULL) {
udf_error(sb, __func__,
@@ -970,7 +977,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
return NULL;
}
- memset(bitmap, 0x00, size);
bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1);
bitmap->s_nr_groups = nr_groups;
return bitmap;
@@ -1774,6 +1780,8 @@ static void udf_open_lvid(struct super_block *sb)
if (!bh)
return;
+
+ mutex_lock(&sbi->s_alloc_mutex);
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
lvidiu = udf_sb_lvidiu(sbi);
@@ -1790,6 +1798,7 @@ static void udf_open_lvid(struct super_block *sb)
lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
mark_buffer_dirty(bh);
sbi->s_lvid_dirty = 0;
+ mutex_unlock(&sbi->s_alloc_mutex);
}
static void udf_close_lvid(struct super_block *sb)
@@ -1802,6 +1811,7 @@ static void udf_close_lvid(struct super_block *sb)
if (!bh)
return;
+ mutex_lock(&sbi->s_alloc_mutex);
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
lvidiu = udf_sb_lvidiu(sbi);
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1822,6 +1832,34 @@ static void udf_close_lvid(struct super_block *sb)
lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
mark_buffer_dirty(bh);
sbi->s_lvid_dirty = 0;
+ mutex_unlock(&sbi->s_alloc_mutex);
+}
+
+u64 lvid_get_unique_id(struct super_block *sb)
+{
+ struct buffer_head *bh;
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ struct logicalVolIntegrityDesc *lvid;
+ struct logicalVolHeaderDesc *lvhd;
+ u64 uniqueID;
+ u64 ret;
+
+ bh = sbi->s_lvid_bh;
+ if (!bh)
+ return 0;
+
+ lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
+ lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse;
+
+ mutex_lock(&sbi->s_alloc_mutex);
+ ret = uniqueID = le64_to_cpu(lvhd->uniqueID);
+ if (!(++uniqueID & 0xFFFFFFFF))
+ uniqueID += 16;
+ lvhd->uniqueID = cpu_to_le64(uniqueID);
+ mutex_unlock(&sbi->s_alloc_mutex);
+ mark_buffer_dirty(bh);
+
+ return ret;
}
static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
@@ -1879,8 +1917,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
struct kernel_lb_addr rootdir, fileset;
struct udf_sb_info *sbi;
- lock_kernel();
-
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
uopt.uid = -1;
uopt.gid = -1;
@@ -1889,10 +1925,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
uopt.dmode = UDF_INVALID_MODE;
sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
- if (!sbi) {
- unlock_kernel();
+ if (!sbi)
return -ENOMEM;
- }
sb->s_fs_info = sbi;
@@ -1929,6 +1963,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sbi->s_fmode = uopt.fmode;
sbi->s_dmode = uopt.dmode;
sbi->s_nls_map = uopt.nls_map;
+ rwlock_init(&sbi->s_cred_lock);
if (uopt.session == 0xFFFFFFFF)
sbi->s_session = udf_get_last_session(sb);
@@ -2038,7 +2073,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
goto error_out;
}
sb->s_maxbytes = MAX_LFS_FILESIZE;
- unlock_kernel();
return 0;
error_out:
@@ -2059,7 +2093,6 @@ error_out:
kfree(sbi);
sb->s_fs_info = NULL;
- unlock_kernel();
return -EINVAL;
}
@@ -2098,8 +2131,6 @@ static void udf_put_super(struct super_block *sb)
sbi = UDF_SB(sb);
- lock_kernel();
-
if (sbi->s_vat_inode)
iput(sbi->s_vat_inode);
if (sbi->s_partitions)
@@ -2115,8 +2146,6 @@ static void udf_put_super(struct super_block *sb)
kfree(sbi->s_partmaps);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
-
- unlock_kernel();
}
static int udf_sync_fs(struct super_block *sb, int wait)
@@ -2179,8 +2208,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
uint16_t ident;
struct spaceBitmapDesc *bm;
- lock_kernel();
-
loc.logicalBlockNum = bitmap->s_extPosition;
loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
bh = udf_read_ptagged(sb, &loc, 0, &ident);
@@ -2217,10 +2244,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
}
}
brelse(bh);
-
out:
- unlock_kernel();
-
return accum;
}
@@ -2233,8 +2257,7 @@ static unsigned int udf_count_free_table(struct super_block *sb,
int8_t etype;
struct extent_position epos;
- lock_kernel();
-
+ mutex_lock(&UDF_SB(sb)->s_alloc_mutex);
epos.block = UDF_I(table)->i_location;
epos.offset = sizeof(struct unallocSpaceEntry);
epos.bh = NULL;
@@ -2243,8 +2266,7 @@ static unsigned int udf_count_free_table(struct super_block *sb,
accum += (elen >> table->i_sb->s_blocksize_bits);
brelse(epos.bh);
-
- unlock_kernel();
+ mutex_unlock(&UDF_SB(sb)->s_alloc_mutex);
return accum;
}
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 16064787d2b7..b1d4488b0f14 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -27,7 +27,6 @@
#include <linux/mm.h>
#include <linux/stat.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include "udf_i.h"
@@ -78,13 +77,16 @@ static int udf_symlink_filler(struct file *file, struct page *page)
int err = -EIO;
unsigned char *p = kmap(page);
struct udf_inode_info *iinfo;
+ uint32_t pos;
- lock_kernel();
iinfo = UDF_I(inode);
+ pos = udf_block_map(inode, 0);
+
+ down_read(&iinfo->i_data_sem);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
} else {
- bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
+ bh = sb_bread(inode->i_sb, pos);
if (!bh)
goto out;
@@ -95,14 +97,14 @@ static int udf_symlink_filler(struct file *file, struct page *page)
udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
brelse(bh);
- unlock_kernel();
+ up_read(&iinfo->i_data_sem);
SetPageUptodate(page);
kunmap(page);
unlock_page(page);
return 0;
out:
- unlock_kernel();
+ up_read(&iinfo->i_data_sem);
SetPageError(page);
kunmap(page);
unlock_page(page);
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
index e58d1de41073..d1bd31ea724e 100644
--- a/fs/udf/udf_i.h
+++ b/fs/udf/udf_i.h
@@ -1,6 +1,18 @@
#ifndef _UDF_I_H
#define _UDF_I_H
+/*
+ * The i_data_sem and i_mutex serve for protection of allocation information
+ * of a regular files and symlinks. This includes all extents belonging to
+ * the file/symlink, a fact whether data are in-inode or in external data
+ * blocks, preallocation, goal block information... When extents are read,
+ * i_mutex or i_data_sem must be held (for reading is enough in case of
+ * i_data_sem). When extents are changed, i_data_sem must be held for writing
+ * and also i_mutex must be held.
+ *
+ * For directories i_mutex is used for all the necessary protection.
+ */
+
struct udf_inode_info {
struct timespec i_crtime;
/* Physical address of inode */
@@ -21,6 +33,7 @@ struct udf_inode_info {
struct long_ad *i_lad;
__u8 *i_data;
} i_ext;
+ struct rw_semaphore i_data_sem;
struct inode vfs_inode;
};
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index d113b72c2768..4858c191242b 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -2,6 +2,7 @@
#define __LINUX_UDF_SB_H
#include <linux/mutex.h>
+#include <linux/bitops.h>
/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC 0x15013346
@@ -128,6 +129,8 @@ struct udf_sb_info {
uid_t s_uid;
mode_t s_fmode;
mode_t s_dmode;
+ /* Lock protecting consistency of above permission settings */
+ rwlock_t s_cred_lock;
/* Root Info */
struct timespec s_record_time;
@@ -139,7 +142,7 @@ struct udf_sb_info {
__u16 s_udfrev;
/* Miscellaneous flags */
- __u32 s_flags;
+ unsigned long s_flags;
/* Encoding info */
struct nls_table *s_nls_map;
@@ -161,8 +164,19 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi);
int udf_compute_nr_groups(struct super_block *sb, u32 partition);
-#define UDF_QUERY_FLAG(X,Y) ( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
-#define UDF_SET_FLAG(X,Y) ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
-#define UDF_CLEAR_FLAG(X,Y) ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
+static inline int UDF_QUERY_FLAG(struct super_block *sb, int flag)
+{
+ return test_bit(flag, &UDF_SB(sb)->s_flags);
+}
+
+static inline void UDF_SET_FLAG(struct super_block *sb, int flag)
+{
+ set_bit(flag, &UDF_SB(sb)->s_flags);
+}
+
+static inline void UDF_CLEAR_FLAG(struct super_block *sb, int flag)
+{
+ clear_bit(flag, &UDF_SB(sb)->s_flags);
+}
#endif /* __LINUX_UDF_SB_H */
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 6995ab1f4305..eba48209f9f3 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -111,6 +111,8 @@ struct extent_position {
};
/* super.c */
+
+__attribute__((format(printf, 3, 4)))
extern void udf_warning(struct super_block *, const char *, const char *, ...);
static inline void udf_updated_lvid(struct super_block *sb)
{
@@ -123,6 +125,7 @@ static inline void udf_updated_lvid(struct super_block *sb)
sb->s_dirt = 1;
UDF_SB(sb)->s_lvid_dirty = 1;
}
+extern u64 lvid_get_unique_id(struct super_block *sb);
/* namei.c */
extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
@@ -133,7 +136,6 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
extern long udf_ioctl(struct file *, unsigned int, unsigned long);
/* inode.c */
extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
-extern int udf_sync_inode(struct inode *);
extern void udf_expand_file_adinicb(struct inode *, int, int *);
extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
extern struct buffer_head *udf_bread(struct inode *, int, int, int *);
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 2c47daed56da..2c61ac5d4e48 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1412,11 +1412,18 @@ static struct inode *ufs_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void ufs_destroy_inode(struct inode *inode)
+static void ufs_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(ufs_inode_cachep, UFS_I(inode));
}
+static void ufs_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, ufs_i_callback);
+}
+
static void init_once(void *foo)
{
struct ufs_inode_info *ei = (struct ufs_inode_info *) foo;
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index b2771862fd3d..70053f6fd208 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -219,7 +219,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
int
-xfs_check_acl(struct inode *inode, int mask)
+xfs_check_acl_rcu(struct inode *inode, int mask, unsigned int flags)
{
struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl;
@@ -234,6 +234,12 @@ xfs_check_acl(struct inode *inode, int mask)
if (!XFS_IFORK_Q(ip))
return -EAGAIN;
+ if (flags & IPERM_FLAG_RCU) {
+ if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
+ return -ECHILD;
+ return -EAGAIN;
+ }
+
acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl))
return PTR_ERR(acl);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 7d287afccde5..ec7bbb5645b6 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -38,15 +38,6 @@
#include <linux/pagevec.h>
#include <linux/writeback.h>
-/*
- * Types of I/O for bmap clustering and I/O completion tracking.
- */
-enum {
- IO_READ, /* mapping for a read */
- IO_DELAY, /* mapping covers delalloc region */
- IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */
- IO_NEW /* just allocated */
-};
/*
* Prime number of hash buckets since address is used as the key.
@@ -182,9 +173,6 @@ xfs_setfilesize(
xfs_inode_t *ip = XFS_I(ioend->io_inode);
xfs_fsize_t isize;
- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
- ASSERT(ioend->io_type != IO_READ);
-
if (unlikely(ioend->io_error))
return 0;
@@ -244,10 +232,8 @@ xfs_end_io(
* We might have to update the on-disk file size after extending
* writes.
*/
- if (ioend->io_type != IO_READ) {
- error = xfs_setfilesize(ioend);
- ASSERT(!error || error == EAGAIN);
- }
+ error = xfs_setfilesize(ioend);
+ ASSERT(!error || error == EAGAIN);
/*
* If we didn't complete processing of the ioend, requeue it to the
@@ -318,14 +304,63 @@ STATIC int
xfs_map_blocks(
struct inode *inode,
loff_t offset,
- ssize_t count,
struct xfs_bmbt_irec *imap,
- int flags)
+ int type,
+ int nonblocking)
{
- int nmaps = 1;
- int new = 0;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ ssize_t count = 1 << inode->i_blkbits;
+ xfs_fileoff_t offset_fsb, end_fsb;
+ int error = 0;
+ int bmapi_flags = XFS_BMAPI_ENTIRE;
+ int nimaps = 1;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -XFS_ERROR(EIO);
+
+ if (type == IO_UNWRITTEN)
+ bmapi_flags |= XFS_BMAPI_IGSTATE;
+
+ if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
+ if (nonblocking)
+ return -XFS_ERROR(EAGAIN);
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ }
+
+ ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
+ (ip->i_df.if_flags & XFS_IFEXTENTS));
+ ASSERT(offset <= mp->m_maxioffset);
+
+ if (offset + count > mp->m_maxioffset)
+ count = mp->m_maxioffset - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
+ bmapi_flags, NULL, 0, imap, &nimaps, NULL);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return -xfs_iomap(XFS_I(inode), offset, count, flags, imap, &nmaps, &new);
+ if (error)
+ return -XFS_ERROR(error);
+
+ if (type == IO_DELALLOC &&
+ (!nimaps || isnullstartblock(imap->br_startblock))) {
+ error = xfs_iomap_write_allocate(ip, offset, count, imap);
+ if (!error)
+ trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
+ return -XFS_ERROR(error);
+ }
+
+#ifdef DEBUG
+ if (type == IO_UNWRITTEN) {
+ ASSERT(nimaps);
+ ASSERT(imap->br_startblock != HOLESTARTBLOCK);
+ ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
+ }
+#endif
+ if (nimaps)
+ trace_xfs_map_blocks_found(ip, offset, count, type, imap);
+ return 0;
}
STATIC int
@@ -380,26 +415,18 @@ xfs_submit_ioend_bio(
submit_bio(wbc->sync_mode == WB_SYNC_ALL ?
WRITE_SYNC_PLUG : WRITE, bio);
- ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
- bio_put(bio);
}
STATIC struct bio *
xfs_alloc_ioend_bio(
struct buffer_head *bh)
{
- struct bio *bio;
int nvecs = bio_get_nr_vecs(bh->b_bdev);
-
- do {
- bio = bio_alloc(GFP_NOIO, nvecs);
- nvecs >>= 1;
- } while (!bio);
+ struct bio *bio = bio_alloc(GFP_NOIO, nvecs);
ASSERT(bio->bi_private == NULL);
bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
bio->bi_bdev = bh->b_bdev;
- bio_get(bio);
return bio;
}
@@ -470,9 +497,8 @@ xfs_submit_ioend(
/* Pass 1 - start writeback */
do {
next = ioend->io_list;
- for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
+ for (bh = ioend->io_buffer_head; bh; bh = bh->b_private)
xfs_start_buffer_writeback(bh);
- }
} while ((ioend = next) != NULL);
/* Pass 2 - submit I/O */
@@ -600,117 +626,13 @@ xfs_map_at_offset(
ASSERT(imap->br_startblock != HOLESTARTBLOCK);
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
- lock_buffer(bh);
xfs_map_buffer(inode, bh, imap, offset);
- bh->b_bdev = xfs_find_bdev_for_inode(inode);
set_buffer_mapped(bh);
clear_buffer_delay(bh);
clear_buffer_unwritten(bh);
}
/*
- * Look for a page at index that is suitable for clustering.
- */
-STATIC unsigned int
-xfs_probe_page(
- struct page *page,
- unsigned int pg_offset)
-{
- struct buffer_head *bh, *head;
- int ret = 0;
-
- if (PageWriteback(page))
- return 0;
- if (!PageDirty(page))
- return 0;
- if (!page->mapping)
- return 0;
- if (!page_has_buffers(page))
- return 0;
-
- bh = head = page_buffers(page);
- do {
- if (!buffer_uptodate(bh))
- break;
- if (!buffer_mapped(bh))
- break;
- ret += bh->b_size;
- if (ret >= pg_offset)
- break;
- } while ((bh = bh->b_this_page) != head);
-
- return ret;
-}
-
-STATIC size_t
-xfs_probe_cluster(
- struct inode *inode,
- struct page *startpage,
- struct buffer_head *bh,
- struct buffer_head *head)
-{
- struct pagevec pvec;
- pgoff_t tindex, tlast, tloff;
- size_t total = 0;
- int done = 0, i;
-
- /* First sum forwards in this page */
- do {
- if (!buffer_uptodate(bh) || !buffer_mapped(bh))
- return total;
- total += bh->b_size;
- } while ((bh = bh->b_this_page) != head);
-
- /* if we reached the end of the page, sum forwards in following pages */
- tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
- tindex = startpage->index + 1;
-
- /* Prune this back to avoid pathological behavior */
- tloff = min(tlast, startpage->index + 64);
-
- pagevec_init(&pvec, 0);
- while (!done && tindex <= tloff) {
- unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);
-
- if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))
- break;
-
- for (i = 0; i < pagevec_count(&pvec); i++) {
- struct page *page = pvec.pages[i];
- size_t pg_offset, pg_len = 0;
-
- if (tindex == tlast) {
- pg_offset =
- i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
- if (!pg_offset) {
- done = 1;
- break;
- }
- } else
- pg_offset = PAGE_CACHE_SIZE;
-
- if (page->index == tindex && trylock_page(page)) {
- pg_len = xfs_probe_page(page, pg_offset);
- unlock_page(page);
- }
-
- if (!pg_len) {
- done = 1;
- break;
- }
-
- total += pg_len;
- tindex++;
- }
-
- pagevec_release(&pvec);
- cond_resched();
- }
-
- return total;
-}
-
-/*
* Test if a given page is suitable for writing as part of an unwritten
* or delayed allocate extent.
*/
@@ -731,9 +653,9 @@ xfs_is_delayed_page(
if (buffer_unwritten(bh))
acceptable = (type == IO_UNWRITTEN);
else if (buffer_delay(bh))
- acceptable = (type == IO_DELAY);
+ acceptable = (type == IO_DELALLOC);
else if (buffer_dirty(bh) && buffer_mapped(bh))
- acceptable = (type == IO_NEW);
+ acceptable = (type == IO_OVERWRITE);
else
break;
} while ((bh = bh->b_this_page) != head);
@@ -758,8 +680,7 @@ xfs_convert_page(
loff_t tindex,
struct xfs_bmbt_irec *imap,
xfs_ioend_t **ioendp,
- struct writeback_control *wbc,
- int all_bh)
+ struct writeback_control *wbc)
{
struct buffer_head *bh, *head;
xfs_off_t end_offset;
@@ -814,37 +735,30 @@ xfs_convert_page(
continue;
}
- if (buffer_unwritten(bh) || buffer_delay(bh)) {
+ if (buffer_unwritten(bh) || buffer_delay(bh) ||
+ buffer_mapped(bh)) {
if (buffer_unwritten(bh))
type = IO_UNWRITTEN;
+ else if (buffer_delay(bh))
+ type = IO_DELALLOC;
else
- type = IO_DELAY;
+ type = IO_OVERWRITE;
if (!xfs_imap_valid(inode, imap, offset)) {
done = 1;
continue;
}
- ASSERT(imap->br_startblock != HOLESTARTBLOCK);
- ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
-
- xfs_map_at_offset(inode, bh, imap, offset);
+ lock_buffer(bh);
+ if (type != IO_OVERWRITE)
+ xfs_map_at_offset(inode, bh, imap, offset);
xfs_add_to_ioend(inode, bh, offset, type,
ioendp, done);
page_dirty--;
count++;
} else {
- type = IO_NEW;
- if (buffer_mapped(bh) && all_bh) {
- lock_buffer(bh);
- xfs_add_to_ioend(inode, bh, offset,
- type, ioendp, done);
- count++;
- page_dirty--;
- } else {
- done = 1;
- }
+ done = 1;
}
} while (offset += len, (bh = bh->b_this_page) != head);
@@ -876,7 +790,6 @@ xfs_cluster_write(
struct xfs_bmbt_irec *imap,
xfs_ioend_t **ioendp,
struct writeback_control *wbc,
- int all_bh,
pgoff_t tlast)
{
struct pagevec pvec;
@@ -891,7 +804,7 @@ xfs_cluster_write(
for (i = 0; i < pagevec_count(&pvec); i++) {
done = xfs_convert_page(inode, pvec.pages[i], tindex++,
- imap, ioendp, wbc, all_bh);
+ imap, ioendp, wbc);
if (done)
break;
}
@@ -934,9 +847,8 @@ xfs_aops_discard_page(
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, IO_DELAY))
+ if (!xfs_is_delayed_page(page, IO_DELALLOC))
goto out_invalidate;
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -949,58 +861,14 @@ xfs_aops_discard_page(
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;
+ xfs_fileoff_t start_fsb;
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);
-
- 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, &done);
-
- ASSERT(!flist.xbf_count && !flist.xbf_first);
+ start_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+ error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 1);
if (error) {
/* something screwed, just bail */
if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
@@ -1010,7 +878,7 @@ xfs_aops_discard_page(
break;
}
next_buffer:
- offset += len;
+ offset += 1 << inode->i_blkbits;
} while ((bh = bh->b_this_page) != head);
@@ -1047,10 +915,10 @@ xfs_vm_writepage(
unsigned int type;
__uint64_t end_offset;
pgoff_t end_index, last_index;
- ssize_t size, len;
- int flags, err, imap_valid = 0, uptodate = 1;
+ ssize_t len;
+ int err, imap_valid = 0, uptodate = 1;
int count = 0;
- int all_bh = 0;
+ int nonblocking = 0;
trace_xfs_writepage(inode, page, 0);
@@ -1101,10 +969,14 @@ xfs_vm_writepage(
bh = head = page_buffers(page);
offset = page_offset(page);
- flags = BMAPI_READ;
- type = IO_NEW;
+ type = IO_OVERWRITE;
+
+ if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking)
+ nonblocking = 1;
do {
+ int new_ioend = 0;
+
if (offset >= end_offset)
break;
if (!buffer_uptodate(bh))
@@ -1121,90 +993,54 @@ xfs_vm_writepage(
continue;
}
- if (imap_valid)
- imap_valid = xfs_imap_valid(inode, &imap, offset);
-
- if (buffer_unwritten(bh) || buffer_delay(bh)) {
- int new_ioend = 0;
-
- /*
- * Make sure we don't use a read-only iomap
- */
- if (flags == BMAPI_READ)
- imap_valid = 0;
-
- if (buffer_unwritten(bh)) {
+ if (buffer_unwritten(bh)) {
+ if (type != IO_UNWRITTEN) {
type = IO_UNWRITTEN;
- flags = BMAPI_WRITE | BMAPI_IGNSTATE;
- } else if (buffer_delay(bh)) {
- type = IO_DELAY;
- flags = BMAPI_ALLOCATE;
-
- if (wbc->sync_mode == WB_SYNC_NONE)
- flags |= BMAPI_TRYLOCK;
- }
-
- if (!imap_valid) {
- /*
- * If we didn't have a valid mapping then we
- * need to ensure that we put the new mapping
- * in a new ioend structure. This needs to be
- * done to ensure that the ioends correctly
- * reflect the block mappings at io completion
- * for unwritten extent conversion.
- */
- new_ioend = 1;
- err = xfs_map_blocks(inode, offset, len,
- &imap, flags);
- if (err)
- goto error;
- imap_valid = xfs_imap_valid(inode, &imap,
- offset);
+ imap_valid = 0;
}
- if (imap_valid) {
- xfs_map_at_offset(inode, bh, &imap, offset);
- xfs_add_to_ioend(inode, bh, offset, type,
- &ioend, new_ioend);
- count++;
+ } else if (buffer_delay(bh)) {
+ if (type != IO_DELALLOC) {
+ type = IO_DELALLOC;
+ imap_valid = 0;
}
} else if (buffer_uptodate(bh)) {
- /*
- * we got here because the buffer is already mapped.
- * That means it must already have extents allocated
- * underneath it. Map the extent by reading it.
- */
- if (!imap_valid || flags != BMAPI_READ) {
- flags = BMAPI_READ;
- size = xfs_probe_cluster(inode, page, bh, head);
- err = xfs_map_blocks(inode, offset, size,
- &imap, flags);
- if (err)
- goto error;
- imap_valid = xfs_imap_valid(inode, &imap,
- offset);
+ if (type != IO_OVERWRITE) {
+ type = IO_OVERWRITE;
+ imap_valid = 0;
+ }
+ } else {
+ if (PageUptodate(page)) {
+ ASSERT(buffer_mapped(bh));
+ imap_valid = 0;
}
+ continue;
+ }
+ if (imap_valid)
+ imap_valid = xfs_imap_valid(inode, &imap, offset);
+ if (!imap_valid) {
/*
- * We set the type to IO_NEW in case we are doing a
- * small write at EOF that is extending the file but
- * without needing an allocation. We need to update the
- * file size on I/O completion in this case so it is
- * the same case as having just allocated a new extent
- * that we are writing into for the first time.
+ * If we didn't have a valid mapping then we need to
+ * put the new mapping into a separate ioend structure.
+ * This ensures non-contiguous extents always have
+ * separate ioends, which is particularly important
+ * for unwritten extent conversion at I/O completion
+ * time.
*/
- type = IO_NEW;
- if (trylock_buffer(bh)) {
- if (imap_valid)
- all_bh = 1;
- xfs_add_to_ioend(inode, bh, offset, type,
- &ioend, !imap_valid);
- count++;
- } else {
- imap_valid = 0;
- }
- } else if (PageUptodate(page)) {
- ASSERT(buffer_mapped(bh));
- imap_valid = 0;
+ new_ioend = 1;
+ err = xfs_map_blocks(inode, offset, &imap, type,
+ nonblocking);
+ if (err)
+ goto error;
+ imap_valid = xfs_imap_valid(inode, &imap, offset);
+ }
+ if (imap_valid) {
+ lock_buffer(bh);
+ if (type != IO_OVERWRITE)
+ xfs_map_at_offset(inode, bh, &imap, offset);
+ xfs_add_to_ioend(inode, bh, offset, type, &ioend,
+ new_ioend);
+ count++;
}
if (!iohead)
@@ -1233,7 +1069,7 @@ xfs_vm_writepage(
end_index = last_index;
xfs_cluster_write(inode, page->index + 1, &imap, &ioend,
- wbc, all_bh, end_index);
+ wbc, end_index);
}
if (iohead)
@@ -1302,13 +1138,19 @@ __xfs_get_blocks(
int create,
int direct)
{
- int flags = create ? BMAPI_WRITE : BMAPI_READ;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ xfs_fileoff_t offset_fsb, end_fsb;
+ int error = 0;
+ int lockmode = 0;
struct xfs_bmbt_irec imap;
+ int nimaps = 1;
xfs_off_t offset;
ssize_t size;
- int nimap = 1;
int new = 0;
- int error;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -XFS_ERROR(EIO);
offset = (xfs_off_t)iblock << inode->i_blkbits;
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
@@ -1317,15 +1159,45 @@ __xfs_get_blocks(
if (!create && direct && offset >= i_size_read(inode))
return 0;
- if (direct && create)
- flags |= BMAPI_DIRECT;
+ if (create) {
+ lockmode = XFS_ILOCK_EXCL;
+ xfs_ilock(ip, lockmode);
+ } else {
+ lockmode = xfs_ilock_map_shared(ip);
+ }
+
+ ASSERT(offset <= mp->m_maxioffset);
+ if (offset + size > mp->m_maxioffset)
+ size = mp->m_maxioffset - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
- error = xfs_iomap(XFS_I(inode), offset, size, flags, &imap, &nimap,
- &new);
+ error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
+ XFS_BMAPI_ENTIRE, NULL, 0, &imap, &nimaps, NULL);
if (error)
- return -error;
- if (nimap == 0)
- return 0;
+ goto out_unlock;
+
+ if (create &&
+ (!nimaps ||
+ (imap.br_startblock == HOLESTARTBLOCK ||
+ imap.br_startblock == DELAYSTARTBLOCK))) {
+ if (direct) {
+ error = xfs_iomap_write_direct(ip, offset, size,
+ &imap, nimaps);
+ } else {
+ error = xfs_iomap_write_delay(ip, offset, size, &imap);
+ }
+ if (error)
+ goto out_unlock;
+
+ trace_xfs_get_blocks_alloc(ip, offset, size, 0, &imap);
+ } else if (nimaps) {
+ trace_xfs_get_blocks_found(ip, offset, size, 0, &imap);
+ } else {
+ trace_xfs_get_blocks_notfound(ip, offset, size);
+ goto out_unlock;
+ }
+ xfs_iunlock(ip, lockmode);
if (imap.br_startblock != HOLESTARTBLOCK &&
imap.br_startblock != DELAYSTARTBLOCK) {
@@ -1392,6 +1264,10 @@ __xfs_get_blocks(
}
return 0;
+
+out_unlock:
+ xfs_iunlock(ip, lockmode);
+ return -error;
}
int
@@ -1479,7 +1355,7 @@ xfs_vm_direct_IO(
ssize_t ret;
if (rw & WRITE) {
- iocb->private = xfs_alloc_ioend(inode, IO_NEW);
+ iocb->private = xfs_alloc_ioend(inode, IO_DIRECT);
ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov,
offset, nr_segs,
@@ -1505,11 +1381,42 @@ xfs_vm_write_failed(
struct inode *inode = mapping->host;
if (to > inode->i_size) {
- struct iattr ia = {
- .ia_valid = ATTR_SIZE | ATTR_FORCE,
- .ia_size = inode->i_size,
- };
- xfs_setattr(XFS_I(inode), &ia, XFS_ATTR_NOLOCK);
+ /*
+ * punch out the delalloc blocks we have already allocated. We
+ * don't call xfs_setattr() to do this as we may be in the
+ * middle of a multi-iovec write and so the vfs inode->i_size
+ * will not match the xfs ip->i_size and so it will zero too
+ * much. Hence we jus truncate the page cache to zero what is
+ * necessary and punch the delalloc blocks directly.
+ */
+ struct xfs_inode *ip = XFS_I(inode);
+ xfs_fileoff_t start_fsb;
+ xfs_fileoff_t end_fsb;
+ int error;
+
+ truncate_pagecache(inode, to, inode->i_size);
+
+ /*
+ * Check if there are any blocks that are outside of i_size
+ * that need to be trimmed back.
+ */
+ start_fsb = XFS_B_TO_FSB(ip->i_mount, inode->i_size) + 1;
+ end_fsb = XFS_B_TO_FSB(ip->i_mount, to);
+ if (end_fsb <= start_fsb)
+ return;
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
+ end_fsb - start_fsb);
+ if (error) {
+ /* something screwed, just bail */
+ if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+ "xfs_vm_write_failed: unable to clean up ino %lld",
+ ip->i_ino);
+ }
+ }
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
}
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index c5057fb6237a..71f721e1a71f 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -23,6 +23,22 @@ extern struct workqueue_struct *xfsconvertd_workqueue;
extern mempool_t *xfs_ioend_pool;
/*
+ * Types of I/O for bmap clustering and I/O completion tracking.
+ */
+enum {
+ IO_DIRECT = 0, /* special case for direct I/O ioends */
+ IO_DELALLOC, /* mapping covers delalloc region */
+ IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */
+ IO_OVERWRITE, /* mapping covers already allocated extent */
+};
+
+#define XFS_IO_TYPES \
+ { 0, "" }, \
+ { IO_DELALLOC, "delalloc" }, \
+ { IO_UNWRITTEN, "unwritten" }, \
+ { IO_OVERWRITE, "overwrite" }
+
+/*
* xfs_ioend struct manages large extent writes for XFS.
* It can manage several multi-page bio's at once.
*/
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index aa1d353def29..4c5deb6e9e31 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -488,29 +488,16 @@ found:
spin_unlock(&pag->pag_buf_lock);
xfs_perag_put(pag);
- /* Attempt to get the semaphore without sleeping,
- * if this does not work then we need to drop the
- * spinlock and do a hard attempt on the semaphore.
- */
- if (down_trylock(&bp->b_sema)) {
+ if (xfs_buf_cond_lock(bp)) {
+ /* failed, so wait for the lock if requested. */
if (!(flags & XBF_TRYLOCK)) {
- /* wait for buffer ownership */
xfs_buf_lock(bp);
XFS_STATS_INC(xb_get_locked_waited);
} else {
- /* We asked for a trylock and failed, no need
- * to look at file offset and length here, we
- * know that this buffer at least overlaps our
- * buffer and is locked, therefore our buffer
- * either does not exist, or is this buffer.
- */
xfs_buf_rele(bp);
XFS_STATS_INC(xb_busy_locked);
return NULL;
}
- } else {
- /* trylock worked */
- XB_SET_OWNER(bp);
}
if (bp->b_flags & XBF_STALE) {
@@ -876,10 +863,18 @@ xfs_buf_rele(
*/
/*
- * Locks a buffer object, if it is not already locked.
- * Note that this in no way locks the underlying pages, so it is only
- * useful for synchronizing concurrent use of buffer objects, not for
- * synchronizing independent access to the underlying pages.
+ * Locks a buffer object, if it is not already locked. Note that this in
+ * no way locks the underlying pages, so it is only useful for
+ * synchronizing concurrent use of buffer objects, not for synchronizing
+ * independent access to the underlying pages.
+ *
+ * If we come across a stale, pinned, locked buffer, we know that we are
+ * being asked to lock a buffer that has been reallocated. Because it is
+ * pinned, we know that the log has not been pushed to disk and hence it
+ * will still be locked. Rather than continuing to have trylock attempts
+ * fail until someone else pushes the log, push it ourselves before
+ * returning. This means that the xfsaild will not get stuck trying
+ * to push on stale inode buffers.
*/
int
xfs_buf_cond_lock(
@@ -890,6 +885,8 @@ xfs_buf_cond_lock(
locked = down_trylock(&bp->b_sema) == 0;
if (locked)
XB_SET_OWNER(bp);
+ else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
+ xfs_log_force(bp->b_target->bt_mount, 0);
trace_xfs_buf_cond_lock(bp, _RET_IP_);
return locked ? 0 : -EBUSY;
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 3764d74790ec..fc0114da7fdd 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -70,8 +70,16 @@ xfs_fs_encode_fh(
else
fileid_type = FILEID_INO32_GEN_PARENT;
- /* filesystem may contain 64bit inode numbers */
- if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS))
+ /*
+ * If the the filesystem may contain 64bit inode numbers, we need
+ * to use larger file handles that can represent them.
+ *
+ * While we only allocate inodes that do not fit into 32 bits any
+ * large enough filesystem may contain them, thus the slightly
+ * confusing looking conditional below.
+ */
+ if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS) ||
+ (XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES))
fileid_type |= XFS_FILEID_TYPE_64FLAG;
/*
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 94d5fd6a2973..c8751c70383f 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -643,7 +643,7 @@ xfs_vn_fiemap(
}
static const struct inode_operations xfs_inode_operations = {
- .check_acl = xfs_check_acl,
+ .check_acl_rcu = xfs_check_acl_rcu,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -670,7 +670,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
.rmdir = xfs_vn_unlink,
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
- .check_acl = xfs_check_acl,
+ .check_acl_rcu = xfs_check_acl_rcu,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -695,7 +695,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
.rmdir = xfs_vn_unlink,
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
- .check_acl = xfs_check_acl,
+ .check_acl_rcu = xfs_check_acl_rcu,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -708,7 +708,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = xfs_vn_follow_link,
.put_link = xfs_vn_put_link,
- .check_acl = xfs_check_acl,
+ .check_acl_rcu = xfs_check_acl_rcu,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 064f964d4f3c..2d2ce7f651a7 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -606,7 +606,8 @@ xfs_blkdev_get(
{
int error = 0;
- *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp);
+ *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
+ mp);
if (IS_ERR(*bdevp)) {
error = PTR_ERR(*bdevp);
printk("XFS: Invalid device [%s], error=%d\n", name, error);
@@ -620,7 +621,7 @@ xfs_blkdev_put(
struct block_device *bdev)
{
if (bdev)
- close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
}
/*
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index acef2e98c594..83e8760159ef 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -935,10 +935,10 @@ DEFINE_PAGE_EVENT(xfs_writepage);
DEFINE_PAGE_EVENT(xfs_releasepage);
DEFINE_PAGE_EVENT(xfs_invalidatepage);
-DECLARE_EVENT_CLASS(xfs_iomap_class,
+DECLARE_EVENT_CLASS(xfs_imap_class,
TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
- int flags, struct xfs_bmbt_irec *irec),
- TP_ARGS(ip, offset, count, flags, irec),
+ int type, struct xfs_bmbt_irec *irec),
+ TP_ARGS(ip, offset, count, type, irec),
TP_STRUCT__entry(
__field(dev_t, dev)
__field(xfs_ino_t, ino)
@@ -946,7 +946,7 @@ DECLARE_EVENT_CLASS(xfs_iomap_class,
__field(loff_t, new_size)
__field(loff_t, offset)
__field(size_t, count)
- __field(int, flags)
+ __field(int, type)
__field(xfs_fileoff_t, startoff)
__field(xfs_fsblock_t, startblock)
__field(xfs_filblks_t, blockcount)
@@ -958,13 +958,13 @@ DECLARE_EVENT_CLASS(xfs_iomap_class,
__entry->new_size = ip->i_new_size;
__entry->offset = offset;
__entry->count = count;
- __entry->flags = flags;
+ __entry->type = type;
__entry->startoff = irec ? irec->br_startoff : 0;
__entry->startblock = irec ? irec->br_startblock : 0;
__entry->blockcount = irec ? irec->br_blockcount : 0;
),
TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx "
- "offset 0x%llx count %zd flags %s "
+ "offset 0x%llx count %zd type %s "
"startoff 0x%llx startblock %lld blockcount 0x%llx",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
@@ -972,20 +972,21 @@ DECLARE_EVENT_CLASS(xfs_iomap_class,
__entry->new_size,
__entry->offset,
__entry->count,
- __print_flags(__entry->flags, "|", BMAPI_FLAGS),
+ __print_symbolic(__entry->type, XFS_IO_TYPES),
__entry->startoff,
(__int64_t)__entry->startblock,
__entry->blockcount)
)
#define DEFINE_IOMAP_EVENT(name) \
-DEFINE_EVENT(xfs_iomap_class, name, \
+DEFINE_EVENT(xfs_imap_class, name, \
TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \
- int flags, struct xfs_bmbt_irec *irec), \
- TP_ARGS(ip, offset, count, flags, irec))
-DEFINE_IOMAP_EVENT(xfs_iomap_enter);
-DEFINE_IOMAP_EVENT(xfs_iomap_found);
-DEFINE_IOMAP_EVENT(xfs_iomap_alloc);
+ int type, struct xfs_bmbt_irec *irec), \
+ TP_ARGS(ip, offset, count, type, irec))
+DEFINE_IOMAP_EVENT(xfs_map_blocks_found);
+DEFINE_IOMAP_EVENT(xfs_map_blocks_alloc);
+DEFINE_IOMAP_EVENT(xfs_get_blocks_found);
+DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc);
DECLARE_EVENT_CLASS(xfs_simple_io_class,
TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count),
@@ -1022,6 +1023,7 @@ DEFINE_EVENT(xfs_simple_io_class, name, \
TP_ARGS(ip, offset, count))
DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc);
DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert);
+DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound);
TRACE_EVENT(xfs_itruncate_start,
@@ -1420,6 +1422,7 @@ DEFINE_EVENT(xfs_alloc_class, name, \
TP_PROTO(struct xfs_alloc_arg *args), \
TP_ARGS(args))
DEFINE_ALLOC_EVENT(xfs_alloc_exact_done);
+DEFINE_ALLOC_EVENT(xfs_alloc_exact_notfound);
DEFINE_ALLOC_EVENT(xfs_alloc_exact_error);
DEFINE_ALLOC_EVENT(xfs_alloc_near_nominleft);
DEFINE_ALLOC_EVENT(xfs_alloc_near_first);
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 0135e2a669d7..6560d563a557 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -42,7 +42,7 @@ struct xfs_acl {
#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
#ifdef CONFIG_XFS_POSIX_ACL
-extern int xfs_check_acl(struct inode *inode, int mask);
+extern int xfs_check_acl_rcu(struct inode *inode, int mask, unsigned int flags);
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode);
@@ -52,7 +52,7 @@ extern int posix_acl_default_exists(struct inode *inode);
extern const struct xattr_handler xfs_xattr_acl_access_handler;
extern const struct xattr_handler xfs_xattr_acl_default_handler;
#else
-# define xfs_check_acl NULL
+# define xfs_check_acl_rcu NULL
# define xfs_get_acl(inode, type) NULL
# define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 0
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 112abc439ca5..fa8723f5870a 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -577,61 +577,58 @@ xfs_alloc_ag_vextent_exact(
xfs_extlen_t rlen; /* length of returned extent */
ASSERT(args->alignment == 1);
+
/*
* Allocate/initialize a cursor for the by-number freespace btree.
*/
bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
- args->agno, XFS_BTNUM_BNO);
+ args->agno, XFS_BTNUM_BNO);
+
/*
* Lookup bno and minlen in the btree (minlen is irrelevant, really).
* Look for the closest free block <= bno, it must contain bno
* if any free block does.
*/
- if ((error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i)))
+ error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i);
+ if (error)
goto error0;
- if (!i) {
- /*
- * Didn't find it, return null.
- */
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
+ if (!i)
+ goto not_found;
+
/*
* Grab the freespace record.
*/
- if ((error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i)))
+ error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i);
+ if (error)
goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
ASSERT(fbno <= args->agbno);
minend = args->agbno + args->minlen;
maxend = args->agbno + args->maxlen;
fend = fbno + flen;
+
/*
* Give up if the freespace isn't long enough for the minimum request.
*/
- if (fend < minend) {
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- args->agbno = NULLAGBLOCK;
- return 0;
- }
+ if (fend < minend)
+ goto not_found;
+
/*
* End of extent will be smaller of the freespace end and the
* maximal requested end.
- */
- end = XFS_AGBLOCK_MIN(fend, maxend);
- /*
+ *
* Fix the length according to mod and prod if given.
*/
+ end = XFS_AGBLOCK_MIN(fend, maxend);
args->len = end - args->agbno;
xfs_alloc_fix_len(args);
- if (!xfs_alloc_fix_minleft(args)) {
- xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
- return 0;
- }
+ if (!xfs_alloc_fix_minleft(args))
+ goto not_found;
+
rlen = args->len;
ASSERT(args->agbno + rlen <= fend);
end = args->agbno + rlen;
+
/*
* We are allocating agbno for rlen [agbno .. end]
* Allocate/initialize a cursor for the by-size btree.
@@ -640,16 +637,25 @@ xfs_alloc_ag_vextent_exact(
args->agno, XFS_BTNUM_CNT);
ASSERT(args->agbno + args->len <=
be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
- args->agbno, args->len, XFSA_FIXUP_BNO_OK))) {
+ error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
+ args->len, XFSA_FIXUP_BNO_OK);
+ if (error) {
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
goto error0;
}
+
xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
- trace_xfs_alloc_exact_done(args);
args->wasfromfl = 0;
+ trace_xfs_alloc_exact_done(args);
+ return 0;
+
+not_found:
+ /* Didn't find it, return null. */
+ xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
+ args->agbno = NULLAGBLOCK;
+ trace_xfs_alloc_exact_notfound(args);
return 0;
error0:
@@ -659,6 +665,95 @@ error0:
}
/*
+ * Search the btree in a given direction via the search cursor and compare
+ * the records found against the good extent we've already found.
+ */
+STATIC int
+xfs_alloc_find_best_extent(
+ struct xfs_alloc_arg *args, /* allocation argument structure */
+ struct xfs_btree_cur **gcur, /* good cursor */
+ struct xfs_btree_cur **scur, /* searching cursor */
+ xfs_agblock_t gdiff, /* difference for search comparison */
+ xfs_agblock_t *sbno, /* extent found by search */
+ xfs_extlen_t *slen,
+ xfs_extlen_t *slena, /* aligned length */
+ int dir) /* 0 = search right, 1 = search left */
+{
+ xfs_agblock_t bno;
+ xfs_agblock_t new;
+ xfs_agblock_t sdiff;
+ int error;
+ int i;
+
+ /* The good extent is perfect, no need to search. */
+ if (!gdiff)
+ goto out_use_good;
+
+ /*
+ * Look until we find a better one, run out of space or run off the end.
+ */
+ do {
+ error = xfs_alloc_get_rec(*scur, sbno, slen, &i);
+ if (error)
+ goto error0;
+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+ xfs_alloc_compute_aligned(*sbno, *slen, args->alignment,
+ args->minlen, &bno, slena);
+
+ /*
+ * The good extent is closer than this one.
+ */
+ if (!dir) {
+ if (bno >= args->agbno + gdiff)
+ goto out_use_good;
+ } else {
+ if (bno <= args->agbno - gdiff)
+ goto out_use_good;
+ }
+
+ /*
+ * Same distance, compare length and pick the best.
+ */
+ if (*slena >= args->minlen) {
+ args->len = XFS_EXTLEN_MIN(*slena, args->maxlen);
+ xfs_alloc_fix_len(args);
+
+ sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
+ args->alignment, *sbno,
+ *slen, &new);
+
+ /*
+ * Choose closer size and invalidate other cursor.
+ */
+ if (sdiff < gdiff)
+ goto out_use_search;
+ goto out_use_good;
+ }
+
+ if (!dir)
+ error = xfs_btree_increment(*scur, 0, &i);
+ else
+ error = xfs_btree_decrement(*scur, 0, &i);
+ if (error)
+ goto error0;
+ } while (i);
+
+out_use_good:
+ xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR);
+ *scur = NULL;
+ return 0;
+
+out_use_search:
+ xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR);
+ *gcur = NULL;
+ return 0;
+
+error0:
+ /* caller invalidates cursors */
+ return error;
+}
+
+/*
* Allocate a variable extent near bno in the allocation group agno.
* Extent's length (returned in len) will be between minlen and maxlen,
* and of the form k * prod + mod unless there's nothing that large.
@@ -925,203 +1020,45 @@ xfs_alloc_ag_vextent_near(
}
}
} while (bno_cur_lt || bno_cur_gt);
+
/*
* Got both cursors still active, need to find better entry.
*/
if (bno_cur_lt && bno_cur_gt) {
- /*
- * Left side is long enough, look for a right side entry.
- */
if (ltlena >= args->minlen) {
/*
- * Fix up the length.
+ * Left side is good, look for a right side entry.
*/
args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
xfs_alloc_fix_len(args);
- rlen = args->len;
- ltdiff = xfs_alloc_compute_diff(args->agbno, rlen,
+ ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
args->alignment, ltbno, ltlen, &ltnew);
+
+ error = xfs_alloc_find_best_extent(args,
+ &bno_cur_lt, &bno_cur_gt,
+ ltdiff, &gtbno, &gtlen, &gtlena,
+ 0 /* search right */);
+ } else {
+ ASSERT(gtlena >= args->minlen);
+
/*
- * Not perfect.
- */
- if (ltdiff) {
- /*
- * Look until we find a better one, run out of
- * space, or run off the end.
- */
- while (bno_cur_lt && bno_cur_gt) {
- if ((error = xfs_alloc_get_rec(
- bno_cur_gt, &gtbno,
- &gtlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_alloc_compute_aligned(gtbno, gtlen,
- args->alignment, args->minlen,
- &gtbnoa, &gtlena);
- /*
- * The left one is clearly better.
- */
- if (gtbnoa >= args->agbno + ltdiff) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- break;
- }
- /*
- * If we reach a big enough entry,
- * compare the two and pick the best.
- */
- if (gtlena >= args->minlen) {
- args->len =
- XFS_EXTLEN_MIN(gtlena,
- args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- gtdiff = xfs_alloc_compute_diff(
- args->agbno, rlen,
- args->alignment,
- gtbno, gtlen, &gtnew);
- /*
- * Right side is better.
- */
- if (gtdiff < ltdiff) {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- /*
- * Left side is better.
- */
- else {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- break;
- }
- /*
- * Fell off the right end.
- */
- if ((error = xfs_btree_increment(
- bno_cur_gt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- break;
- }
- }
- }
- /*
- * The left side is perfect, trash the right side.
- */
- else {
- xfs_btree_del_cursor(bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- }
- /*
- * It's the right side that was found first, look left.
- */
- else {
- /*
- * Fix up the length.
+ * Right side is good, look for a left side entry.
*/
args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
xfs_alloc_fix_len(args);
- rlen = args->len;
- gtdiff = xfs_alloc_compute_diff(args->agbno, rlen,
+ gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
args->alignment, gtbno, gtlen, &gtnew);
- /*
- * Right side entry isn't perfect.
- */
- if (gtdiff) {
- /*
- * Look until we find a better one, run out of
- * space, or run off the end.
- */
- while (bno_cur_lt && bno_cur_gt) {
- if ((error = xfs_alloc_get_rec(
- bno_cur_lt, &ltbno,
- &ltlen, &i)))
- goto error0;
- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
- xfs_alloc_compute_aligned(ltbno, ltlen,
- args->alignment, args->minlen,
- &ltbnoa, &ltlena);
- /*
- * The right one is clearly better.
- */
- if (ltbnoa <= args->agbno - gtdiff) {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- break;
- }
- /*
- * If we reach a big enough entry,
- * compare the two and pick the best.
- */
- if (ltlena >= args->minlen) {
- args->len = XFS_EXTLEN_MIN(
- ltlena, args->maxlen);
- xfs_alloc_fix_len(args);
- rlen = args->len;
- ltdiff = xfs_alloc_compute_diff(
- args->agbno, rlen,
- args->alignment,
- ltbno, ltlen, &ltnew);
- /*
- * Left side is better.
- */
- if (ltdiff < gtdiff) {
- xfs_btree_del_cursor(
- bno_cur_gt,
- XFS_BTREE_NOERROR);
- bno_cur_gt = NULL;
- }
- /*
- * Right side is better.
- */
- else {
- xfs_btree_del_cursor(
- bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
- break;
- }
- /*
- * Fell off the left end.
- */
- if ((error = xfs_btree_decrement(
- bno_cur_lt, 0, &i)))
- goto error0;
- if (!i) {
- xfs_btree_del_cursor(bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- break;
- }
- }
- }
- /*
- * The right side is perfect, trash the left side.
- */
- else {
- xfs_btree_del_cursor(bno_cur_lt,
- XFS_BTREE_NOERROR);
- bno_cur_lt = NULL;
- }
+
+ error = xfs_alloc_find_best_extent(args,
+ &bno_cur_gt, &bno_cur_lt,
+ gtdiff, &ltbno, &ltlen, &ltlena,
+ 1 /* search left */);
}
+
+ if (error)
+ goto error0;
}
+
/*
* If we couldn't get anything, give up.
*/
@@ -1130,6 +1067,7 @@ xfs_alloc_ag_vextent_near(
args->agbno = NULLAGBLOCK;
return 0;
}
+
/*
* At this point we have selected a freespace entry, either to the
* left or to the right. If it's on the right, copy all the
@@ -1146,6 +1084,7 @@ xfs_alloc_ag_vextent_near(
j = 1;
} else
j = 0;
+
/*
* Fix up the length and compute the useful address.
*/
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 8abd12e32e13..4111cd3966c7 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5471,8 +5471,13 @@ xfs_getbmap(
if (error)
goto out_unlock_iolock;
}
-
- ASSERT(ip->i_delayed_blks == 0);
+ /*
+ * even after flushing the inode, there can still be delalloc
+ * blocks on the inode beyond EOF due to speculative
+ * preallocation. These are not removed until the release
+ * function is called or the inode is inactivated. Hence we
+ * cannot assert here that ip->i_delayed_blks == 0.
+ */
}
lock = xfs_ilock_map_shared(ip);
@@ -6070,3 +6075,79 @@ xfs_bmap_disk_count_leaves(
*count += xfs_bmbt_disk_get_blockcount(frp);
}
}
+
+/*
+ * dead simple method of punching delalyed allocation blocks from a range in
+ * the inode. Walks a block at a time so will be slow, but is only executed in
+ * rare error cases so the overhead is not critical. This will alays punch out
+ * both the start and end blocks, even if the ranges only partially overlap
+ * them, so it is up to the caller to ensure that partial blocks are not
+ * passed in.
+ */
+int
+xfs_bmap_punch_delalloc_range(
+ struct xfs_inode *ip,
+ xfs_fileoff_t start_fsb,
+ xfs_fileoff_t length)
+{
+ xfs_fileoff_t remaining = length;
+ int error = 0;
+
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+ do {
+ int done;
+ xfs_bmbt_irec_t imap;
+ int nimaps = 1;
+ xfs_fsblock_t firstblock;
+ xfs_bmap_free_t flist;
+
+ /*
+ * 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, start_fsb, 1,
+ XFS_BMAPI_ENTIRE, NULL, 0, &imap,
+ &nimaps, NULL);
+
+ if (error) {
+ /* something screwed, just bail */
+ if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+ "Failed delalloc mapping lookup ino %lld fsb %lld.",
+ ip->i_ino, start_fsb);
+ }
+ break;
+ }
+ if (!nimaps) {
+ /* nothing there */
+ goto next_block;
+ }
+ if (imap.br_startblock != DELAYSTARTBLOCK) {
+ /* been converted, ignore */
+ goto next_block;
+ }
+ 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, start_fsb, 1, 0, 1, &firstblock,
+ &flist, &done);
+ if (error)
+ break;
+
+ ASSERT(!flist.xbf_count && !flist.xbf_first);
+next_block:
+ start_fsb++;
+ remaining--;
+ } while(remaining > 0);
+
+ return error;
+}
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 71ec9b6ecdfc..3651191daea1 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -394,6 +394,11 @@ xfs_bmap_count_blocks(
int whichfork,
int *count);
+int
+xfs_bmap_punch_delalloc_range(
+ struct xfs_inode *ip,
+ xfs_fileoff_t start_fsb,
+ xfs_fileoff_t length);
#endif /* __KERNEL__ */
#endif /* __XFS_BMAP_H__ */
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 0e2ed43f16c7..b6ecd2061e7c 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -105,17 +105,6 @@ typedef struct xfs_buf_log_item {
xfs_buf_log_format_t bli_format; /* in-log header */
} xfs_buf_log_item_t;
-/*
- * This structure is used during recovery to record the buf log
- * items which have been canceled and should not be replayed.
- */
-typedef struct xfs_buf_cancel {
- xfs_daddr_t bc_blkno;
- uint bc_len;
- int bc_refcount;
- struct xfs_buf_cancel *bc_next;
-} xfs_buf_cancel_t;
-
void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
void xfs_buf_item_relse(struct xfs_buf *);
void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 3b9582c60a22..e60490bc00a6 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -377,6 +377,19 @@ xfs_swap_extents(
ip->i_d.di_format = tip->i_d.di_format;
tip->i_d.di_format = tmp;
+ /*
+ * The extents in the source inode could still contain speculative
+ * preallocation beyond EOF (e.g. the file is open but not modified
+ * while defrag is in progress). In that case, we need to copy over the
+ * number of delalloc blocks the data fork in the source inode is
+ * tracking beyond EOF so that when the fork is truncated away when the
+ * temporary inode is unlinked we don't underrun the i_delayed_blks
+ * counter on that inode.
+ */
+ ASSERT(tip->i_delayed_blks == 0);
+ tip->i_delayed_blks = ip->i_delayed_blks;
+ ip->i_delayed_blks = 0;
+
ilf_fields = XFS_ILOG_CORE;
switch(ip->i_d.di_format) {
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index ed9990267661..c78cc6a3d87c 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -58,6 +58,7 @@ xfs_error_trap(int e)
int xfs_etest[XFS_NUM_INJECT_ERROR];
int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
+int xfs_error_test_active;
int
xfs_error_test(int error_tag, int *fsidp, char *expression,
@@ -108,6 +109,7 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
len = strlen(mp->m_fsname);
xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
strcpy(xfs_etest_fsname[i], mp->m_fsname);
+ xfs_error_test_active++;
return 0;
}
}
@@ -137,6 +139,7 @@ xfs_errortag_clearall(xfs_mount_t *mp, int loud)
xfs_etest_fsid[i] = 0LL;
kmem_free(xfs_etest_fsname[i]);
xfs_etest_fsname[i] = NULL;
+ xfs_error_test_active--;
}
}
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index c2c1a072bb82..f338847f80b8 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -127,13 +127,14 @@ extern void xfs_corruption_error(const char *tag, int level,
#define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT
#ifdef DEBUG
+extern int xfs_error_test_active;
extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
#define XFS_NUM_INJECT_ERROR 10
#define XFS_TEST_ERROR(expr, mp, tag, rf) \
- ((expr) || \
+ ((expr) || (xfs_error_test_active && \
xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
- (rf)))
+ (rf))))
extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 0cdd26932d8e..d7de5a3f7867 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -91,6 +91,17 @@ xfs_inode_alloc(
return ip;
}
+STATIC void
+xfs_inode_free_callback(
+ struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ struct xfs_inode *ip = XFS_I(inode);
+
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_zone_free(xfs_inode_zone, ip);
+}
+
void
xfs_inode_free(
struct xfs_inode *ip)
@@ -134,7 +145,7 @@ xfs_inode_free(
ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush));
- kmem_zone_free(xfs_inode_zone, ip);
+ call_rcu(&ip->i_vnode.i_rcu, xfs_inode_free_callback);
}
/*
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index c7ac020705df..7c8d30c453c3 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -657,18 +657,37 @@ xfs_inode_item_unlock(
}
/*
- * This is called to find out where the oldest active copy of the
- * inode log item in the on disk log resides now that the last log
- * write of it completed at the given lsn. Since we always re-log
- * all dirty data in an inode, the latest copy in the on disk log
- * is the only one that matters. Therefore, simply return the
- * given lsn.
+ * This is called to find out where the oldest active copy of the inode log
+ * item in the on disk log resides now that the last log write of it completed
+ * at the given lsn. Since we always re-log all dirty data in an inode, the
+ * latest copy in the on disk log is the only one that matters. Therefore,
+ * simply return the given lsn.
+ *
+ * If the inode has been marked stale because the cluster is being freed, we
+ * don't want to (re-)insert this inode into the AIL. There is a race condition
+ * where the cluster buffer may be unpinned before the inode is inserted into
+ * the AIL during transaction committed processing. If the buffer is unpinned
+ * before the inode item has been committed and inserted, then it is possible
+ * for the buffer to be written and IO completions before the inode is inserted
+ * into the AIL. In that case, we'd be inserting a clean, stale inode into the
+ * AIL which will never get removed. It will, however, get reclaimed which
+ * triggers an assert in xfs_inode_free() complaining about freein an inode
+ * still in the AIL.
+ *
+ * To avoid this, return a lower LSN than the one passed in so that the
+ * transaction committed code will not move the inode forward in the AIL but
+ * will still unpin it properly.
*/
STATIC xfs_lsn_t
xfs_inode_item_committed(
struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
+
+ if (xfs_iflags_test(ip, XFS_ISTALE))
+ return lsn - 1;
return lsn;
}
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 20576146369f..22b62a179e89 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -47,127 +47,8 @@
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
<< mp->m_writeio_log)
-#define XFS_STRAT_WRITE_IMAPS 2
#define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP
-STATIC int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
- int, struct xfs_bmbt_irec *, int *);
-STATIC int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int,
- struct xfs_bmbt_irec *, int *);
-STATIC int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
- struct xfs_bmbt_irec *, int *);
-
-int
-xfs_iomap(
- struct xfs_inode *ip,
- xfs_off_t offset,
- ssize_t count,
- int flags,
- struct xfs_bmbt_irec *imap,
- int *nimaps,
- int *new)
-{
- struct xfs_mount *mp = ip->i_mount;
- xfs_fileoff_t offset_fsb, end_fsb;
- int error = 0;
- int lockmode = 0;
- int bmapi_flags = 0;
-
- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
-
- *new = 0;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- trace_xfs_iomap_enter(ip, offset, count, flags, NULL);
-
- switch (flags & (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE)) {
- case BMAPI_READ:
- lockmode = xfs_ilock_map_shared(ip);
- bmapi_flags = XFS_BMAPI_ENTIRE;
- break;
- case BMAPI_WRITE:
- lockmode = XFS_ILOCK_EXCL;
- if (flags & BMAPI_IGNSTATE)
- bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE;
- xfs_ilock(ip, lockmode);
- break;
- case BMAPI_ALLOCATE:
- lockmode = XFS_ILOCK_SHARED;
- bmapi_flags = XFS_BMAPI_ENTIRE;
-
- /* Attempt non-blocking lock */
- if (flags & BMAPI_TRYLOCK) {
- if (!xfs_ilock_nowait(ip, lockmode))
- return XFS_ERROR(EAGAIN);
- } else {
- xfs_ilock(ip, lockmode);
- }
- break;
- default:
- BUG();
- }
-
- ASSERT(offset <= mp->m_maxioffset);
- if ((xfs_fsize_t)offset + count > mp->m_maxioffset)
- count = mp->m_maxioffset - offset;
- end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
- offset_fsb = XFS_B_TO_FSBT(mp, offset);
-
- error = xfs_bmapi(NULL, ip, offset_fsb,
- (xfs_filblks_t)(end_fsb - offset_fsb),
- bmapi_flags, NULL, 0, imap,
- nimaps, NULL);
-
- if (error)
- goto out;
-
- switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) {
- case BMAPI_WRITE:
- /* If we found an extent, return it */
- if (*nimaps &&
- (imap->br_startblock != HOLESTARTBLOCK) &&
- (imap->br_startblock != DELAYSTARTBLOCK)) {
- trace_xfs_iomap_found(ip, offset, count, flags, imap);
- break;
- }
-
- if (flags & BMAPI_DIRECT) {
- error = xfs_iomap_write_direct(ip, offset, count, flags,
- imap, nimaps);
- } else {
- error = xfs_iomap_write_delay(ip, offset, count, flags,
- imap, nimaps);
- }
- if (!error) {
- trace_xfs_iomap_alloc(ip, offset, count, flags, imap);
- }
- *new = 1;
- break;
- case BMAPI_ALLOCATE:
- /* If we found an extent, return it */
- xfs_iunlock(ip, lockmode);
- lockmode = 0;
-
- if (*nimaps && !isnullstartblock(imap->br_startblock)) {
- trace_xfs_iomap_found(ip, offset, count, flags, imap);
- break;
- }
-
- error = xfs_iomap_write_allocate(ip, offset, count,
- imap, nimaps);
- break;
- }
-
- ASSERT(*nimaps <= 1);
-
-out:
- if (lockmode)
- xfs_iunlock(ip, lockmode);
- return XFS_ERROR(error);
-}
-
STATIC int
xfs_iomap_eof_align_last_fsb(
xfs_mount_t *mp,
@@ -236,14 +117,13 @@ xfs_cmn_err_fsblock_zero(
return EFSCORRUPTED;
}
-STATIC int
+int
xfs_iomap_write_direct(
xfs_inode_t *ip,
xfs_off_t offset,
size_t count,
- int flags,
xfs_bmbt_irec_t *imap,
- int *nmaps)
+ int nmaps)
{
xfs_mount_t *mp = ip->i_mount;
xfs_fileoff_t offset_fsb;
@@ -279,7 +159,7 @@ xfs_iomap_write_direct(
if (error)
goto error_out;
} else {
- if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK))
+ if (nmaps && (imap->br_startblock == HOLESTARTBLOCK))
last_fsb = MIN(last_fsb, (xfs_fileoff_t)
imap->br_blockcount +
imap->br_startoff);
@@ -331,7 +211,7 @@ xfs_iomap_write_direct(
xfs_trans_ijoin(tp, ip);
bmapi_flag = XFS_BMAPI_WRITE;
- if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
+ if (offset < ip->i_size || extsz)
bmapi_flag |= XFS_BMAPI_PREALLOC;
/*
@@ -370,7 +250,6 @@ xfs_iomap_write_direct(
goto error_out;
}
- *nmaps = 1;
return 0;
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -379,7 +258,6 @@ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
error1: /* Just cancel transaction */
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
- *nmaps = 0; /* nothing set-up here */
error_out:
return XFS_ERROR(error);
@@ -396,7 +274,6 @@ xfs_iomap_eof_want_preallocate(
xfs_inode_t *ip,
xfs_off_t offset,
size_t count,
- int ioflag,
xfs_bmbt_irec_t *imap,
int nimaps,
int *prealloc)
@@ -435,14 +312,12 @@ xfs_iomap_eof_want_preallocate(
return 0;
}
-STATIC int
+int
xfs_iomap_write_delay(
xfs_inode_t *ip,
xfs_off_t offset,
size_t count,
- int ioflag,
- xfs_bmbt_irec_t *ret_imap,
- int *nmaps)
+ xfs_bmbt_irec_t *ret_imap)
{
xfs_mount_t *mp = ip->i_mount;
xfs_fileoff_t offset_fsb;
@@ -470,7 +345,7 @@ xfs_iomap_write_delay(
offset_fsb = XFS_B_TO_FSBT(mp, offset);
error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count,
- ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
+ imap, XFS_WRITE_IMAPS, &prealloc);
if (error)
return error;
@@ -523,8 +398,6 @@ retry:
return xfs_cmn_err_fsblock_zero(ip, &imap[0]);
*ret_imap = imap[0];
- *nmaps = 1;
-
return 0;
}
@@ -538,13 +411,12 @@ retry:
* We no longer bother to look at the incoming map - all we have to
* guarantee is that whatever we allocate fills the required range.
*/
-STATIC int
+int
xfs_iomap_write_allocate(
xfs_inode_t *ip,
xfs_off_t offset,
size_t count,
- xfs_bmbt_irec_t *imap,
- int *retmap)
+ xfs_bmbt_irec_t *imap)
{
xfs_mount_t *mp = ip->i_mount;
xfs_fileoff_t offset_fsb, last_block;
@@ -557,8 +429,6 @@ xfs_iomap_write_allocate(
int error = 0;
int nres;
- *retmap = 0;
-
/*
* Make sure that the dquots are there.
*/
@@ -680,7 +550,6 @@ xfs_iomap_write_allocate(
if ((offset_fsb >= imap->br_startoff) &&
(offset_fsb < (imap->br_startoff +
imap->br_blockcount))) {
- *retmap = 1;
XFS_STATS_INC(xs_xstrat_quick);
return 0;
}
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 7748a430f50d..80615760959a 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -18,30 +18,15 @@
#ifndef __XFS_IOMAP_H__
#define __XFS_IOMAP_H__
-/* base extent manipulation calls */
-#define BMAPI_READ (1 << 0) /* read extents */
-#define BMAPI_WRITE (1 << 1) /* create extents */
-#define BMAPI_ALLOCATE (1 << 2) /* delayed allocate to real extents */
-
-/* modifiers */
-#define BMAPI_IGNSTATE (1 << 4) /* ignore unwritten state on read */
-#define BMAPI_DIRECT (1 << 5) /* direct instead of buffered write */
-#define BMAPI_MMA (1 << 6) /* allocate for mmap write */
-#define BMAPI_TRYLOCK (1 << 7) /* non-blocking request */
-
-#define BMAPI_FLAGS \
- { BMAPI_READ, "READ" }, \
- { BMAPI_WRITE, "WRITE" }, \
- { BMAPI_ALLOCATE, "ALLOCATE" }, \
- { BMAPI_IGNSTATE, "IGNSTATE" }, \
- { BMAPI_DIRECT, "DIRECT" }, \
- { BMAPI_TRYLOCK, "TRYLOCK" }
-
struct xfs_inode;
struct xfs_bmbt_irec;
-extern int xfs_iomap(struct xfs_inode *, xfs_off_t, ssize_t, int,
- struct xfs_bmbt_irec *, int *, int *);
+extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
+ struct xfs_bmbt_irec *, int);
+extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t,
+ struct xfs_bmbt_irec *);
+extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
+ struct xfs_bmbt_irec *);
extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t);
#endif /* __XFS_IOMAP_H__*/
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index edcdfe01617f..c1ce505313e9 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -21,7 +21,6 @@
struct xfs_buf;
struct log;
struct xlog_ticket;
-struct xfs_buf_cancel;
struct xfs_mount;
/*
@@ -491,7 +490,7 @@ typedef struct log {
struct xfs_buftarg *l_targ; /* buftarg of log */
uint l_flags;
uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
- struct xfs_buf_cancel **l_buf_cancel_table;
+ struct list_head *l_buf_cancel_table;
int l_iclog_hsize; /* size of iclog header */
int l_iclog_heads; /* # of iclog header sectors */
uint l_sectBBsize; /* sector size in BBs (2^n) */
@@ -534,6 +533,9 @@ typedef struct log {
} xlog_t;
+#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \
+ ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE))
+
#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
/* common routines */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 966d3f97458c..4ab4f6ff48aa 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -53,6 +53,17 @@ STATIC void xlog_recover_check_summary(xlog_t *);
#endif
/*
+ * This structure is used during recovery to record the buf log items which
+ * have been canceled and should not be replayed.
+ */
+struct xfs_buf_cancel {
+ xfs_daddr_t bc_blkno;
+ uint bc_len;
+ int bc_refcount;
+ struct list_head bc_list;
+};
+
+/*
* Sector aligned buffer routines for buffer create/read/write/access
*/
@@ -1605,82 +1616,45 @@ xlog_recover_reorder_trans(
* record in the table to tell us how many times we expect to see this
* record during the second pass.
*/
-STATIC void
-xlog_recover_do_buffer_pass1(
- xlog_t *log,
- xfs_buf_log_format_t *buf_f)
+STATIC int
+xlog_recover_buffer_pass1(
+ struct log *log,
+ xlog_recover_item_t *item)
{
- xfs_buf_cancel_t *bcp;
- xfs_buf_cancel_t *nextp;
- xfs_buf_cancel_t *prevp;
- xfs_buf_cancel_t **bucket;
- xfs_daddr_t blkno = 0;
- uint len = 0;
- ushort flags = 0;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- len = buf_f->blf_len;
- flags = buf_f->blf_flags;
- break;
- }
+ xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
+ struct list_head *bucket;
+ struct xfs_buf_cancel *bcp;
/*
* If this isn't a cancel buffer item, then just return.
*/
- if (!(flags & XFS_BLF_CANCEL)) {
+ if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
trace_xfs_log_recover_buf_not_cancel(log, buf_f);
- return;
- }
-
- /*
- * Insert an xfs_buf_cancel record into the hash table of
- * them. If there is already an identical record, bump
- * its reference count.
- */
- bucket = &log->l_buf_cancel_table[(__uint64_t)blkno %
- XLOG_BC_TABLE_SIZE];
- /*
- * If the hash bucket is empty then just insert a new record into
- * the bucket.
- */
- if (*bucket == NULL) {
- bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t),
- KM_SLEEP);
- bcp->bc_blkno = blkno;
- bcp->bc_len = len;
- bcp->bc_refcount = 1;
- bcp->bc_next = NULL;
- *bucket = bcp;
- return;
+ return 0;
}
/*
- * The hash bucket is not empty, so search for duplicates of our
- * record. If we find one them just bump its refcount. If not
- * then add us at the end of the list.
+ * Insert an xfs_buf_cancel record into the hash table of them.
+ * If there is already an identical record, bump its reference count.
*/
- prevp = NULL;
- nextp = *bucket;
- while (nextp != NULL) {
- if (nextp->bc_blkno == blkno && nextp->bc_len == len) {
- nextp->bc_refcount++;
+ bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno);
+ list_for_each_entry(bcp, bucket, bc_list) {
+ if (bcp->bc_blkno == buf_f->blf_blkno &&
+ bcp->bc_len == buf_f->blf_len) {
+ bcp->bc_refcount++;
trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f);
- return;
+ return 0;
}
- prevp = nextp;
- nextp = nextp->bc_next;
- }
- ASSERT(prevp != NULL);
- bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t),
- KM_SLEEP);
- bcp->bc_blkno = blkno;
- bcp->bc_len = len;
+ }
+
+ bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP);
+ bcp->bc_blkno = buf_f->blf_blkno;
+ bcp->bc_len = buf_f->blf_len;
bcp->bc_refcount = 1;
- bcp->bc_next = NULL;
- prevp->bc_next = bcp;
+ list_add_tail(&bcp->bc_list, bucket);
+
trace_xfs_log_recover_buf_cancel_add(log, buf_f);
+ return 0;
}
/*
@@ -1698,14 +1672,13 @@ xlog_recover_do_buffer_pass1(
*/
STATIC int
xlog_check_buffer_cancelled(
- xlog_t *log,
+ struct log *log,
xfs_daddr_t blkno,
uint len,
ushort flags)
{
- xfs_buf_cancel_t *bcp;
- xfs_buf_cancel_t *prevp;
- xfs_buf_cancel_t **bucket;
+ struct list_head *bucket;
+ struct xfs_buf_cancel *bcp;
if (log->l_buf_cancel_table == NULL) {
/*
@@ -1716,128 +1689,70 @@ xlog_check_buffer_cancelled(
return 0;
}
- bucket = &log->l_buf_cancel_table[(__uint64_t)blkno %
- XLOG_BC_TABLE_SIZE];
- bcp = *bucket;
- if (bcp == NULL) {
- /*
- * There is no corresponding entry in the table built
- * in pass one, so this buffer has not been cancelled.
- */
- ASSERT(!(flags & XFS_BLF_CANCEL));
- return 0;
- }
-
/*
- * Search for an entry in the buffer cancel table that
- * matches our buffer.
+ * Search for an entry in the cancel table that matches our buffer.
*/
- prevp = NULL;
- while (bcp != NULL) {
- if (bcp->bc_blkno == blkno && bcp->bc_len == len) {
- /*
- * We've go a match, so return 1 so that the
- * recovery of this buffer is cancelled.
- * If this buffer is actually a buffer cancel
- * log item, then decrement the refcount on the
- * one in the table and remove it if this is the
- * last reference.
- */
- if (flags & XFS_BLF_CANCEL) {
- bcp->bc_refcount--;
- if (bcp->bc_refcount == 0) {
- if (prevp == NULL) {
- *bucket = bcp->bc_next;
- } else {
- prevp->bc_next = bcp->bc_next;
- }
- kmem_free(bcp);
- }
- }
- return 1;
- }
- prevp = bcp;
- bcp = bcp->bc_next;
+ bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno);
+ list_for_each_entry(bcp, bucket, bc_list) {
+ if (bcp->bc_blkno == blkno && bcp->bc_len == len)
+ goto found;
}
+
/*
- * We didn't find a corresponding entry in the table, so
- * return 0 so that the buffer is NOT cancelled.
+ * We didn't find a corresponding entry in the table, so return 0 so
+ * that the buffer is NOT cancelled.
*/
ASSERT(!(flags & XFS_BLF_CANCEL));
return 0;
-}
-STATIC int
-xlog_recover_do_buffer_pass2(
- xlog_t *log,
- xfs_buf_log_format_t *buf_f)
-{
- xfs_daddr_t blkno = 0;
- ushort flags = 0;
- uint len = 0;
-
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- flags = buf_f->blf_flags;
- len = buf_f->blf_len;
- break;
+found:
+ /*
+ * We've go a match, so return 1 so that the recovery of this buffer
+ * is cancelled. If this buffer is actually a buffer cancel log
+ * item, then decrement the refcount on the one in the table and
+ * remove it if this is the last reference.
+ */
+ if (flags & XFS_BLF_CANCEL) {
+ if (--bcp->bc_refcount == 0) {
+ list_del(&bcp->bc_list);
+ kmem_free(bcp);
+ }
}
-
- return xlog_check_buffer_cancelled(log, blkno, len, flags);
+ return 1;
}
/*
- * Perform recovery for a buffer full of inodes. In these buffers,
- * the only data which should be recovered is that which corresponds
- * to the di_next_unlinked pointers in the on disk inode structures.
- * The rest of the data for the inodes is always logged through the
- * inodes themselves rather than the inode buffer and is recovered
- * in xlog_recover_do_inode_trans().
+ * Perform recovery for a buffer full of inodes. In these buffers, the only
+ * data which should be recovered is that which corresponds to the
+ * di_next_unlinked pointers in the on disk inode structures. The rest of the
+ * data for the inodes is always logged through the inodes themselves rather
+ * than the inode buffer and is recovered in xlog_recover_inode_pass2().
*
- * The only time when buffers full of inodes are fully recovered is
- * when the buffer is full of newly allocated inodes. In this case
- * the buffer will not be marked as an inode buffer and so will be
- * sent to xlog_recover_do_reg_buffer() below during recovery.
+ * The only time when buffers full of inodes are fully recovered is when the
+ * buffer is full of newly allocated inodes. In this case the buffer will
+ * not be marked as an inode buffer and so will be sent to
+ * xlog_recover_do_reg_buffer() below during recovery.
*/
STATIC int
xlog_recover_do_inode_buffer(
- xfs_mount_t *mp,
+ struct xfs_mount *mp,
xlog_recover_item_t *item,
- xfs_buf_t *bp,
+ struct xfs_buf *bp,
xfs_buf_log_format_t *buf_f)
{
int i;
- int item_index;
- int bit;
- int nbits;
- int reg_buf_offset;
- int reg_buf_bytes;
+ int item_index = 0;
+ int bit = 0;
+ int nbits = 0;
+ int reg_buf_offset = 0;
+ int reg_buf_bytes = 0;
int next_unlinked_offset;
int inodes_per_buf;
xfs_agino_t *logged_nextp;
xfs_agino_t *buffer_nextp;
- unsigned int *data_map = NULL;
- unsigned int map_size = 0;
trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- data_map = buf_f->blf_data_map;
- map_size = buf_f->blf_map_size;
- break;
- }
- /*
- * Set the variables corresponding to the current region to
- * 0 so that we'll initialize them on the first pass through
- * the loop.
- */
- reg_buf_offset = 0;
- reg_buf_bytes = 0;
- bit = 0;
- nbits = 0;
- item_index = 0;
inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
for (i = 0; i < inodes_per_buf; i++) {
next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
@@ -1852,18 +1767,18 @@ xlog_recover_do_inode_buffer(
* the current di_next_unlinked field.
*/
bit += nbits;
- bit = xfs_next_bit(data_map, map_size, bit);
+ bit = xfs_next_bit(buf_f->blf_data_map,
+ buf_f->blf_map_size, bit);
/*
* If there are no more logged regions in the
* buffer, then we're done.
*/
- if (bit == -1) {
+ if (bit == -1)
return 0;
- }
- nbits = xfs_contig_bits(data_map, map_size,
- bit);
+ nbits = xfs_contig_bits(buf_f->blf_data_map,
+ buf_f->blf_map_size, bit);
ASSERT(nbits > 0);
reg_buf_offset = bit << XFS_BLF_SHIFT;
reg_buf_bytes = nbits << XFS_BLF_SHIFT;
@@ -1875,9 +1790,8 @@ xlog_recover_do_inode_buffer(
* di_next_unlinked field, then move on to the next
* di_next_unlinked field.
*/
- if (next_unlinked_offset < reg_buf_offset) {
+ if (next_unlinked_offset < reg_buf_offset)
continue;
- }
ASSERT(item->ri_buf[item_index].i_addr != NULL);
ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
@@ -1913,36 +1827,29 @@ xlog_recover_do_inode_buffer(
* given buffer. The bitmap in the buf log format structure indicates
* where to place the logged data.
*/
-/*ARGSUSED*/
STATIC void
xlog_recover_do_reg_buffer(
struct xfs_mount *mp,
xlog_recover_item_t *item,
- xfs_buf_t *bp,
+ struct xfs_buf *bp,
xfs_buf_log_format_t *buf_f)
{
int i;
int bit;
int nbits;
- unsigned int *data_map = NULL;
- unsigned int map_size = 0;
int error;
trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- data_map = buf_f->blf_data_map;
- map_size = buf_f->blf_map_size;
- break;
- }
bit = 0;
i = 1; /* 0 is the buf format structure */
while (1) {
- bit = xfs_next_bit(data_map, map_size, bit);
+ bit = xfs_next_bit(buf_f->blf_data_map,
+ buf_f->blf_map_size, bit);
if (bit == -1)
break;
- nbits = xfs_contig_bits(data_map, map_size, bit);
+ nbits = xfs_contig_bits(buf_f->blf_data_map,
+ buf_f->blf_map_size, bit);
ASSERT(nbits > 0);
ASSERT(item->ri_buf[i].i_addr != NULL);
ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
@@ -2176,77 +2083,46 @@ xlog_recover_do_dquot_buffer(
* for more details on the implementation of the table of cancel records.
*/
STATIC int
-xlog_recover_do_buffer_trans(
+xlog_recover_buffer_pass2(
xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
+ xlog_recover_item_t *item)
{
xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
- xfs_mount_t *mp;
+ xfs_mount_t *mp = log->l_mp;
xfs_buf_t *bp;
int error;
- int cancel;
- xfs_daddr_t blkno;
- int len;
- ushort flags;
uint buf_flags;
- if (pass == XLOG_RECOVER_PASS1) {
- /*
- * In this pass we're only looking for buf items
- * with the XFS_BLF_CANCEL bit set.
- */
- xlog_recover_do_buffer_pass1(log, buf_f);
+ /*
+ * In this pass we only want to recover all the buffers which have
+ * not been cancelled and are not cancellation buffers themselves.
+ */
+ if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno,
+ buf_f->blf_len, buf_f->blf_flags)) {
+ trace_xfs_log_recover_buf_cancel(log, buf_f);
return 0;
- } else {
- /*
- * In this pass we want to recover all the buffers
- * which have not been cancelled and are not
- * cancellation buffers themselves. The routine
- * we call here will tell us whether or not to
- * continue with the replay of this buffer.
- */
- cancel = xlog_recover_do_buffer_pass2(log, buf_f);
- if (cancel) {
- trace_xfs_log_recover_buf_cancel(log, buf_f);
- return 0;
- }
}
+
trace_xfs_log_recover_buf_recover(log, buf_f);
- switch (buf_f->blf_type) {
- case XFS_LI_BUF:
- blkno = buf_f->blf_blkno;
- len = buf_f->blf_len;
- flags = buf_f->blf_flags;
- break;
- default:
- xfs_fs_cmn_err(CE_ALERT, log->l_mp,
- "xfs_log_recover: unknown buffer type 0x%x, logdev %s",
- buf_f->blf_type, log->l_mp->m_logname ?
- log->l_mp->m_logname : "internal");
- XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- mp = log->l_mp;
buf_flags = XBF_LOCK;
- if (!(flags & XFS_BLF_INODE_BUF))
+ if (!(buf_f->blf_flags & XFS_BLF_INODE_BUF))
buf_flags |= XBF_MAPPED;
- bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags);
+ bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
+ buf_flags);
if (XFS_BUF_ISERROR(bp)) {
- xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp,
- bp, blkno);
+ xfs_ioerror_alert("xlog_recover_do..(read#1)", mp,
+ bp, buf_f->blf_blkno);
error = XFS_BUF_GETERROR(bp);
xfs_buf_relse(bp);
return error;
}
error = 0;
- if (flags & XFS_BLF_INODE_BUF) {
+ if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
- } else if (flags &
+ } else if (buf_f->blf_flags &
(XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
} else {
@@ -2286,16 +2162,14 @@ xlog_recover_do_buffer_trans(
}
STATIC int
-xlog_recover_do_inode_trans(
+xlog_recover_inode_pass2(
xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
+ xlog_recover_item_t *item)
{
xfs_inode_log_format_t *in_f;
- xfs_mount_t *mp;
+ xfs_mount_t *mp = log->l_mp;
xfs_buf_t *bp;
xfs_dinode_t *dip;
- xfs_ino_t ino;
int len;
xfs_caddr_t src;
xfs_caddr_t dest;
@@ -2305,10 +2179,6 @@ xlog_recover_do_inode_trans(
xfs_icdinode_t *dicp;
int need_free = 0;
- if (pass == XLOG_RECOVER_PASS1) {
- return 0;
- }
-
if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
in_f = item->ri_buf[0].i_addr;
} else {
@@ -2318,8 +2188,6 @@ xlog_recover_do_inode_trans(
if (error)
goto error;
}
- ino = in_f->ilf_ino;
- mp = log->l_mp;
/*
* Inode buffers can be freed, look out for it,
@@ -2354,8 +2222,8 @@ xlog_recover_do_inode_trans(
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
- dip, bp, ino);
- XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
+ dip, bp, in_f->ilf_ino);
+ XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)",
XFS_ERRLEVEL_LOW, mp);
error = EFSCORRUPTED;
goto error;
@@ -2365,8 +2233,8 @@ xlog_recover_do_inode_trans(
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, ino %Ld",
- item, ino);
- XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
+ item, in_f->ilf_ino);
+ XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)",
XFS_ERRLEVEL_LOW, mp);
error = EFSCORRUPTED;
goto error;
@@ -2394,12 +2262,12 @@ xlog_recover_do_inode_trans(
if (unlikely((dicp->di_mode & S_IFMT) == S_IFREG)) {
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
(dicp->di_format != XFS_DINODE_FMT_BTREE)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(3)",
+ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
- item, dip, bp, ino);
+ item, dip, bp, in_f->ilf_ino);
error = EFSCORRUPTED;
goto error;
}
@@ -2407,40 +2275,40 @@ xlog_recover_do_inode_trans(
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
(dicp->di_format != XFS_DINODE_FMT_BTREE) &&
(dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(4)",
+ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
- item, dip, bp, ino);
+ item, dip, bp, in_f->ilf_ino);
error = EFSCORRUPTED;
goto error;
}
}
if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(5)",
+ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
- item, dip, bp, ino,
+ item, dip, bp, in_f->ilf_ino,
dicp->di_nextents + dicp->di_anextents,
dicp->di_nblocks);
error = EFSCORRUPTED;
goto error;
}
if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
+ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
- item, dip, bp, ino, dicp->di_forkoff);
+ item, dip, bp, in_f->ilf_ino, dicp->di_forkoff);
error = EFSCORRUPTED;
goto error;
}
if (unlikely(item->ri_buf[1].i_len > sizeof(struct xfs_icdinode))) {
- XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
+ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
@@ -2532,7 +2400,7 @@ xlog_recover_do_inode_trans(
break;
default:
- xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
+ xlog_warn("XFS: xlog_recover_inode_pass2: Invalid flag");
ASSERT(0);
xfs_buf_relse(bp);
error = EIO;
@@ -2556,18 +2424,11 @@ error:
* of that type.
*/
STATIC int
-xlog_recover_do_quotaoff_trans(
+xlog_recover_quotaoff_pass1(
xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
+ xlog_recover_item_t *item)
{
- xfs_qoff_logformat_t *qoff_f;
-
- if (pass == XLOG_RECOVER_PASS2) {
- return (0);
- }
-
- qoff_f = item->ri_buf[0].i_addr;
+ xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr;
ASSERT(qoff_f);
/*
@@ -2588,22 +2449,17 @@ xlog_recover_do_quotaoff_trans(
* Recover a dquot record
*/
STATIC int
-xlog_recover_do_dquot_trans(
+xlog_recover_dquot_pass2(
xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
+ xlog_recover_item_t *item)
{
- xfs_mount_t *mp;
+ xfs_mount_t *mp = log->l_mp;
xfs_buf_t *bp;
struct xfs_disk_dquot *ddq, *recddq;
int error;
xfs_dq_logformat_t *dq_f;
uint type;
- if (pass == XLOG_RECOVER_PASS1) {
- return 0;
- }
- mp = log->l_mp;
/*
* Filesystems are required to send in quota flags at mount time.
@@ -2647,7 +2503,7 @@ xlog_recover_do_dquot_trans(
if ((error = xfs_qm_dqcheck(recddq,
dq_f->qlf_id,
0, XFS_QMOPT_DOWARN,
- "xlog_recover_do_dquot_trans (log copy)"))) {
+ "xlog_recover_dquot_pass2 (log copy)"))) {
return XFS_ERROR(EIO);
}
ASSERT(dq_f->qlf_len == 1);
@@ -2670,7 +2526,7 @@ xlog_recover_do_dquot_trans(
* minimal initialization then.
*/
if (xfs_qm_dqcheck(ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN,
- "xlog_recover_do_dquot_trans")) {
+ "xlog_recover_dquot_pass2")) {
xfs_buf_relse(bp);
return XFS_ERROR(EIO);
}
@@ -2693,24 +2549,18 @@ xlog_recover_do_dquot_trans(
* LSN.
*/
STATIC int
-xlog_recover_do_efi_trans(
+xlog_recover_efi_pass2(
xlog_t *log,
xlog_recover_item_t *item,
- xfs_lsn_t lsn,
- int pass)
+ xfs_lsn_t lsn)
{
int error;
- xfs_mount_t *mp;
+ xfs_mount_t *mp = log->l_mp;
xfs_efi_log_item_t *efip;
xfs_efi_log_format_t *efi_formatp;
- if (pass == XLOG_RECOVER_PASS1) {
- return 0;
- }
-
efi_formatp = item->ri_buf[0].i_addr;
- mp = log->l_mp;
efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
&(efip->efi_format)))) {
@@ -2737,11 +2587,10 @@ xlog_recover_do_efi_trans(
* efd format structure. If we find it, we remove the efi from the
* AIL and free it.
*/
-STATIC void
-xlog_recover_do_efd_trans(
+STATIC int
+xlog_recover_efd_pass2(
xlog_t *log,
- xlog_recover_item_t *item,
- int pass)
+ xlog_recover_item_t *item)
{
xfs_efd_log_format_t *efd_formatp;
xfs_efi_log_item_t *efip = NULL;
@@ -2750,10 +2599,6 @@ xlog_recover_do_efd_trans(
struct xfs_ail_cursor cur;
struct xfs_ail *ailp = log->l_ailp;
- if (pass == XLOG_RECOVER_PASS1) {
- return;
- }
-
efd_formatp = item->ri_buf[0].i_addr;
ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
@@ -2785,62 +2630,6 @@ xlog_recover_do_efd_trans(
}
xfs_trans_ail_cursor_done(ailp, &cur);
spin_unlock(&ailp->xa_lock);
-}
-
-/*
- * Perform the transaction
- *
- * If the transaction modifies a buffer or inode, do it now. Otherwise,
- * EFIs and EFDs get queued up by adding entries into the AIL for them.
- */
-STATIC int
-xlog_recover_do_trans(
- xlog_t *log,
- xlog_recover_t *trans,
- int pass)
-{
- int error = 0;
- xlog_recover_item_t *item;
-
- error = xlog_recover_reorder_trans(log, trans, pass);
- if (error)
- return error;
-
- list_for_each_entry(item, &trans->r_itemq, ri_list) {
- trace_xfs_log_recover_item_recover(log, trans, item, pass);
- switch (ITEM_TYPE(item)) {
- case XFS_LI_BUF:
- error = xlog_recover_do_buffer_trans(log, item, pass);
- break;
- case XFS_LI_INODE:
- error = xlog_recover_do_inode_trans(log, item, pass);
- break;
- case XFS_LI_EFI:
- error = xlog_recover_do_efi_trans(log, item,
- trans->r_lsn, pass);
- break;
- case XFS_LI_EFD:
- xlog_recover_do_efd_trans(log, item, pass);
- error = 0;
- break;
- case XFS_LI_DQUOT:
- error = xlog_recover_do_dquot_trans(log, item, pass);
- break;
- case XFS_LI_QUOTAOFF:
- error = xlog_recover_do_quotaoff_trans(log, item,
- pass);
- break;
- default:
- xlog_warn(
- "XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item));
- ASSERT(0);
- error = XFS_ERROR(EIO);
- break;
- }
-
- if (error)
- return error;
- }
return 0;
}
@@ -2852,7 +2641,7 @@ xlog_recover_do_trans(
*/
STATIC void
xlog_recover_free_trans(
- xlog_recover_t *trans)
+ struct xlog_recover *trans)
{
xlog_recover_item_t *item, *n;
int i;
@@ -2871,17 +2660,95 @@ xlog_recover_free_trans(
}
STATIC int
+xlog_recover_commit_pass1(
+ struct log *log,
+ struct xlog_recover *trans,
+ xlog_recover_item_t *item)
+{
+ trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1);
+
+ switch (ITEM_TYPE(item)) {
+ case XFS_LI_BUF:
+ return xlog_recover_buffer_pass1(log, item);
+ case XFS_LI_QUOTAOFF:
+ return xlog_recover_quotaoff_pass1(log, item);
+ case XFS_LI_INODE:
+ case XFS_LI_EFI:
+ case XFS_LI_EFD:
+ case XFS_LI_DQUOT:
+ /* nothing to do in pass 1 */
+ return 0;
+ default:
+ xlog_warn(
+ "XFS: invalid item type (%d) xlog_recover_commit_pass1",
+ ITEM_TYPE(item));
+ ASSERT(0);
+ return XFS_ERROR(EIO);
+ }
+}
+
+STATIC int
+xlog_recover_commit_pass2(
+ struct log *log,
+ struct xlog_recover *trans,
+ xlog_recover_item_t *item)
+{
+ trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2);
+
+ switch (ITEM_TYPE(item)) {
+ case XFS_LI_BUF:
+ return xlog_recover_buffer_pass2(log, item);
+ case XFS_LI_INODE:
+ return xlog_recover_inode_pass2(log, item);
+ case XFS_LI_EFI:
+ return xlog_recover_efi_pass2(log, item, trans->r_lsn);
+ case XFS_LI_EFD:
+ return xlog_recover_efd_pass2(log, item);
+ case XFS_LI_DQUOT:
+ return xlog_recover_dquot_pass2(log, item);
+ case XFS_LI_QUOTAOFF:
+ /* nothing to do in pass2 */
+ return 0;
+ default:
+ xlog_warn(
+ "XFS: invalid item type (%d) xlog_recover_commit_pass2",
+ ITEM_TYPE(item));
+ ASSERT(0);
+ return XFS_ERROR(EIO);
+ }
+}
+
+/*
+ * Perform the transaction.
+ *
+ * If the transaction modifies a buffer or inode, do it now. Otherwise,
+ * EFIs and EFDs get queued up by adding entries into the AIL for them.
+ */
+STATIC int
xlog_recover_commit_trans(
- xlog_t *log,
- xlog_recover_t *trans,
+ struct log *log,
+ struct xlog_recover *trans,
int pass)
{
- int error;
+ int error = 0;
+ xlog_recover_item_t *item;
hlist_del(&trans->r_list);
- if ((error = xlog_recover_do_trans(log, trans, pass)))
+
+ error = xlog_recover_reorder_trans(log, trans, pass);
+ if (error)
return error;
- xlog_recover_free_trans(trans); /* no error */
+
+ list_for_each_entry(item, &trans->r_itemq, ri_list) {
+ if (pass == XLOG_RECOVER_PASS1)
+ error = xlog_recover_commit_pass1(log, trans, item);
+ else
+ error = xlog_recover_commit_pass2(log, trans, item);
+ if (error)
+ return error;
+ }
+
+ xlog_recover_free_trans(trans);
return 0;
}
@@ -3724,7 +3591,7 @@ xlog_do_log_recovery(
xfs_daddr_t head_blk,
xfs_daddr_t tail_blk)
{
- int error;
+ int error, i;
ASSERT(head_blk != tail_blk);
@@ -3732,10 +3599,12 @@ xlog_do_log_recovery(
* First do a pass to find all of the cancelled buf log items.
* Store them in the buf_cancel_table for use in the second pass.
*/
- log->l_buf_cancel_table =
- (xfs_buf_cancel_t **)kmem_zalloc(XLOG_BC_TABLE_SIZE *
- sizeof(xfs_buf_cancel_t*),
+ log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
+ sizeof(struct list_head),
KM_SLEEP);
+ for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
+ INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
+
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
XLOG_RECOVER_PASS1);
if (error != 0) {
@@ -3754,7 +3623,7 @@ xlog_do_log_recovery(
int i;
for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
- ASSERT(log->l_buf_cancel_table[i] == NULL);
+ ASSERT(list_empty(&log->l_buf_cancel_table[i]));
}
#endif /* DEBUG */
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index d2af0a8381a6..77a59891734e 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -297,6 +297,7 @@ xfs_rename(
* it and some incremental backup programs won't work without it.
*/
xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
+ xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
/*
* Adjust the link count on src_dp. This is necessary when
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 359ef11725a6..673a3f4d1f07 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -149,8 +149,7 @@ struct acpi_device_flags {
u32 power_manageable:1;
u32 performance_manageable:1;
u32 wake_capable:1; /* Wakeup(_PRW) supported? */
- u32 force_power_state:1;
- u32 reserved:22;
+ u32 reserved:23;
};
/* File System */
@@ -328,8 +327,8 @@ void acpi_bus_data_handler(acpi_handle handle, void *context);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
-int acpi_bus_get_power(acpi_handle handle, int *state);
int acpi_bus_set_power(acpi_handle handle, int state);
+int acpi_bus_update_power(acpi_handle handle, int *state_p);
bool acpi_bus_power_manageable(acpi_handle handle);
bool acpi_bus_can_wakeup(acpi_handle handle);
#ifdef CONFIG_ACPI_PROC_EVENT
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 53b7cfd924a3..241b8a04c83c 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20101013
+#define ACPI_CA_VERSION 0x20101209
#include "actypes.h"
#include "actbl.h"
@@ -229,6 +229,10 @@ acpi_status
acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
acpi_status
+acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler,
+ void *context);
+
+acpi_status
acpi_install_fixed_event_handler(u32 acpi_event,
acpi_event_handler handler, void *context);
@@ -258,11 +262,11 @@ acpi_remove_address_space_handler(acpi_handle device,
acpi_status
acpi_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
- u32 type, acpi_event_handler address, void *context);
+ u32 type, acpi_gpe_handler address, void *context);
acpi_status
acpi_remove_gpe_handler(acpi_handle gpe_device,
- u32 gpe_number, acpi_event_handler address);
+ u32 gpe_number, acpi_gpe_handler address);
#ifdef ACPI_FUTURE_USAGE
acpi_status acpi_install_exception_handler(acpi_exception_handler handler);
@@ -292,11 +296,13 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);
-acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number);
-
acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
-acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action);
+acpi_status
+acpi_setup_gpe_for_wake(acpi_handle parent_device,
+ acpi_handle gpe_device, u32 gpe_number);
+
+acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action);
acpi_status
acpi_get_gpe_status(acpi_handle gpe_device,
@@ -315,7 +321,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
-acpi_status acpi_update_gpes(void);
+acpi_status acpi_update_all_gpes(void);
/*
* Resource interfaces
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 2b134b691e34..939a431a6ab6 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -656,33 +656,34 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_MAX 0xFF
#define ACPI_NUM_GPE 256
-/* Actions for acpi_gpe_wakeup, acpi_hw_low_set_gpe */
+/* Actions for acpi_set_gpe_wake_mask, acpi_hw_low_set_gpe */
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
-#define ACPI_GPE_COND_ENABLE 2
+#define ACPI_GPE_CONDITIONAL_ENABLE 2
/*
* GPE info flags - Per GPE
- * +-------+---+-+-+
- * | 7:4 |3:2|1|0|
- * +-------+---+-+-+
- * | | | |
- * | | | +--- Interrupt type: edge or level triggered
- * | | +----- GPE can wake the system
- * | +-------- Type of dispatch:to method, handler, or none
- * +-------------- <Reserved>
+ * +-------+-+-+---+
+ * | 7:4 |3|2|1:0|
+ * +-------+-+-+---+
+ * | | | |
+ * | | | +-- Type of dispatch:to method, handler, notify, or none
+ * | | +----- Interrupt type: edge or level triggered
+ * | +------- Is a Wake GPE
+ * +------------ <Reserved>
*/
-#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01
-#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01
-#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00
+#define ACPI_GPE_DISPATCH_NONE (u8) 0x00
+#define ACPI_GPE_DISPATCH_METHOD (u8) 0x01
+#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02
+#define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03
+#define ACPI_GPE_DISPATCH_MASK (u8) 0x03
-#define ACPI_GPE_CAN_WAKE (u8) 0x02
+#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04
+#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00
+#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x04
-#define ACPI_GPE_DISPATCH_MASK (u8) 0x0C
-#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x04
-#define ACPI_GPE_DISPATCH_METHOD (u8) 0x08
-#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00
+#define ACPI_GPE_CAN_WAKE (u8) 0x08
/*
* Flags for GPE and Lock interfaces
@@ -894,9 +895,20 @@ typedef void
/*
* Various handlers and callback procedures
*/
+typedef
+void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type,
+ acpi_handle device,
+ u32 event_number, void *context);
+
+#define ACPI_EVENT_TYPE_GPE 0
+#define ACPI_EVENT_TYPE_FIXED 1
+
typedef u32(*acpi_event_handler) (void *context);
typedef
+u32 (*acpi_gpe_handler) (acpi_handle gpe_device, u32 gpe_number, void *context);
+
+typedef
void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context);
typedef
@@ -951,6 +963,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
#define ACPI_INTERRUPT_HANDLED 0x01
+/* GPE handler return values */
+
+#define ACPI_REENABLE_GPE 0x80
+
/* Length of 32-bit EISAID values when converted back to a string */
#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */
diff --git a/include/acpi/video.h b/include/acpi/video.h
index 551793c9b6e8..0e98e679d3a7 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -1,6 +1,10 @@
#ifndef __ACPI_VIDEO_H
#define __ACPI_VIDEO_H
+#include <linux/errno.h> /* for ENODEV */
+
+struct acpi_device;
+
#define ACPI_VIDEO_DISPLAY_CRT 1
#define ACPI_VIDEO_DISPLAY_TV 2
#define ACPI_VIDEO_DISPLAY_DVI 3
@@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
#endif
#endif
-
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 3577ca11a0be..4644c9a7f724 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -211,6 +211,36 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
}
#endif
+static inline void readsl(const void __iomem *addr, void *buf, int len)
+{
+ insl((unsigned long)addr, buf, len);
+}
+
+static inline void readsw(const void __iomem *addr, void *buf, int len)
+{
+ insw((unsigned long)addr, buf, len);
+}
+
+static inline void readsb(const void __iomem *addr, void *buf, int len)
+{
+ insb((unsigned long)addr, buf, len);
+}
+
+static inline void writesl(const void __iomem *addr, const void *buf, int len)
+{
+ outsl((unsigned long)addr, buf, len);
+}
+
+static inline void writesw(const void __iomem *addr, const void *buf, int len)
+{
+ outsw((unsigned long)addr, buf, len);
+}
+
+static inline void writesb(const void __iomem *addr, const void *buf, int len)
+{
+ outsb((unsigned long)addr, buf, len);
+}
+
#ifndef CONFIG_GENERIC_IOMAP
#define ioread8(addr) readb(addr)
#define ioread16(addr) readw(addr)
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
new file mode 100644
index 000000000000..c5813c87de06
--- /dev/null
+++ b/include/crypto/if_alg.h
@@ -0,0 +1,92 @@
+/*
+ * if_alg: User-space algorithm interface
+ *
+ * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or 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 _CRYPTO_IF_ALG_H
+#define _CRYPTO_IF_ALG_H
+
+#include <linux/compiler.h>
+#include <linux/completion.h>
+#include <linux/if_alg.h>
+#include <linux/types.h>
+#include <net/sock.h>
+
+#define ALG_MAX_PAGES 16
+
+struct crypto_async_request;
+
+struct alg_sock {
+ /* struct sock must be the first member of struct alg_sock */
+ struct sock sk;
+
+ struct sock *parent;
+
+ const struct af_alg_type *type;
+ void *private;
+};
+
+struct af_alg_completion {
+ struct completion completion;
+ int err;
+};
+
+struct af_alg_control {
+ struct af_alg_iv *iv;
+ int op;
+};
+
+struct af_alg_type {
+ void *(*bind)(const char *name, u32 type, u32 mask);
+ void (*release)(void *private);
+ int (*setkey)(void *private, const u8 *key, unsigned int keylen);
+ int (*accept)(void *private, struct sock *sk);
+
+ struct proto_ops *ops;
+ struct module *owner;
+ char name[14];
+};
+
+struct af_alg_sgl {
+ struct scatterlist sg[ALG_MAX_PAGES];
+ struct page *pages[ALG_MAX_PAGES];
+};
+
+int af_alg_register_type(const struct af_alg_type *type);
+int af_alg_unregister_type(const struct af_alg_type *type);
+
+int af_alg_release(struct socket *sock);
+int af_alg_accept(struct sock *sk, struct socket *newsock);
+
+int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
+ int write);
+void af_alg_free_sg(struct af_alg_sgl *sgl);
+
+int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con);
+
+int af_alg_wait_for_completion(int err, struct af_alg_completion *completion);
+void af_alg_complete(struct crypto_async_request *req, int err);
+
+static inline struct alg_sock *alg_sk(struct sock *sk)
+{
+ return (struct alg_sock *)sk;
+}
+
+static inline void af_alg_release_parent(struct sock *sk)
+{
+ sock_put(alg_sk(sk)->parent);
+}
+
+static inline void af_alg_init_completion(struct af_alg_completion *completion)
+{
+ init_completion(&completion->completion);
+}
+
+#endif /* _CRYPTO_IF_ALG_H */
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 833d208c25d6..4fd95a323beb 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -68,6 +68,21 @@ static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
return (++sg)->length ? sg : (void *)sg_page(sg);
}
+static inline void scatterwalk_crypto_chain(struct scatterlist *head,
+ struct scatterlist *sg,
+ int chain, int num)
+{
+ if (chain) {
+ head->length += sg->length;
+ sg = scatterwalk_sg_next(sg);
+ }
+
+ if (sg)
+ scatterwalk_sg_chain(head, num, sg);
+ else
+ sg_mark_end(head);
+}
+
static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
struct scatter_walk *walk_out)
{
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 8c641bed9bbd..a2776e2807a4 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_HAS_EXECBUF2 9
#define I915_PARAM_HAS_BSD 10
#define I915_PARAM_HAS_BLT 11
+#define I915_PARAM_HAS_RELAXED_FENCING 12
+#define I915_PARAM_HAS_COHERENT_RINGS 13
typedef struct drm_i915_getparam {
int param;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 97319a8fc1e0..2296d8b1931f 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -20,15 +20,18 @@ header-y += wimax/
objhdr-y += version.h
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
- $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
+ $(srctree)/include/asm-$(SRCARCH)/a.out.h \
+ $(INSTALL_HDR_PATH)/include/asm-*/a.out.h),)
header-y += a.out.h
endif
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
+ $(srctree)/include/asm-$(SRCARCH)/kvm.h \
+ $(INSTALL_HDR_PATH)/include/asm-*/kvm.h),)
header-y += kvm.h
endif
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),)
+ $(srctree)/include/asm-$(SRCARCH)/kvm_para.h \
+ $(INSTALL_HDR_PATH)/include/asm-*/kvm_para.h),)
header-y += kvm_para.h
endif
@@ -155,6 +158,7 @@ header-y += icmpv6.h
header-y += if.h
header-y += if_addr.h
header-y += if_addrlabel.h
+header-y += if_alg.h
header-y += if_arcnet.h
header-y += if_arp.h
header-y += if_bonding.h
@@ -367,7 +371,6 @@ header-y += utime.h
header-y += utsname.h
header-y += veth.h
header-y += vhost.h
-header-y += videodev.h
header-y += videodev2.h
header-y += virtio_9p.h
header-y += virtio_balloon.h
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 050a7bccb836..67c91b4418b0 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void)
extern int acpi_blacklisted(void);
extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern int acpi_osi_setup(char *str);
+extern void acpi_osi_setup(char *str);
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index c6454cca0447..9e7f259346e1 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -18,6 +18,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/resource.h>
+#include <linux/regulator/consumer.h>
#define AMBA_NR_IRQS 2
#define AMBA_CID 0xb105f00d
@@ -28,6 +29,7 @@ struct amba_device {
struct device dev;
struct resource res;
struct clk *pclk;
+ struct regulator *vcore;
u64 dma_mask;
unsigned int periphid;
unsigned int irq[AMBA_NR_IRQS];
@@ -71,6 +73,12 @@ void amba_release_regions(struct amba_device *);
#define amba_pclk_disable(d) \
do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
+#define amba_vcore_enable(d) \
+ (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore))
+
+#define amba_vcore_disable(d) \
+ do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0)
+
/* Some drivers don't use the struct amba_device */
#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index 6021588ba0a8..5479fdc849e9 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -113,6 +113,21 @@
#define UART01x_LCRH_PEN 0x02
#define UART01x_LCRH_BRK 0x01
+#define ST_UART011_DMAWM_RX_1 (0 << 3)
+#define ST_UART011_DMAWM_RX_2 (1 << 3)
+#define ST_UART011_DMAWM_RX_4 (2 << 3)
+#define ST_UART011_DMAWM_RX_8 (3 << 3)
+#define ST_UART011_DMAWM_RX_16 (4 << 3)
+#define ST_UART011_DMAWM_RX_32 (5 << 3)
+#define ST_UART011_DMAWM_RX_48 (6 << 3)
+#define ST_UART011_DMAWM_TX_1 0
+#define ST_UART011_DMAWM_TX_2 1
+#define ST_UART011_DMAWM_TX_4 2
+#define ST_UART011_DMAWM_TX_8 3
+#define ST_UART011_DMAWM_TX_16 4
+#define ST_UART011_DMAWM_TX_32 5
+#define ST_UART011_DMAWM_TX_48 6
+
#define UART010_IIR_RTIS 0x08
#define UART010_IIR_TIS 0x04
#define UART010_IIR_RIS 0x02
@@ -180,6 +195,13 @@ struct amba_device; /* in uncompress this is included but amba/bus.h is not */
struct amba_pl010_data {
void (*set_mctrl)(struct amba_device *dev, void __iomem *base, unsigned int mctrl);
};
+
+struct dma_chan;
+struct amba_pl011_data {
+ bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+ void *dma_rx_param;
+ void *dma_tx_param;
+};
#endif
#endif
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index a8e4e832cdbb..475f8c42c0e9 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock;
#define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
- int number,unsigned long *flags); /* number == -1: pick first available */
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+ const struct atmdev_ops *ops,
+ int number, /* -1 == pick first available */
+ unsigned long *flags);
struct atm_dev *atm_dev_lookup(int number);
void atm_dev_deregister(struct atm_dev *dev);
diff --git a/include/linux/average.h b/include/linux/average.h
new file mode 100644
index 000000000000..c6028fd742c1
--- /dev/null
+++ b/include/linux/average.h
@@ -0,0 +1,30 @@
+#ifndef _LINUX_AVERAGE_H
+#define _LINUX_AVERAGE_H
+
+/* Exponentially weighted moving average (EWMA) */
+
+/* For more documentation see lib/average.c */
+
+struct ewma {
+ unsigned long internal;
+ unsigned long factor;
+ unsigned long weight;
+};
+
+extern void ewma_init(struct ewma *avg, unsigned long factor,
+ unsigned long weight);
+
+extern struct ewma *ewma_add(struct ewma *avg, unsigned long val);
+
+/**
+ * ewma_read() - Get average value
+ * @avg: Average structure
+ *
+ * Returns the average value held in @avg.
+ */
+static inline unsigned long ewma_read(const struct ewma *avg)
+{
+ return avg->internal >> avg->factor;
+}
+
+#endif /* _LINUX_AVERAGE_H */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index a065612fc928..64a7114a9394 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -29,6 +29,7 @@ struct linux_binprm{
char buf[BINPRM_BUF_SIZE];
#ifdef CONFIG_MMU
struct vm_area_struct *vma;
+ unsigned long vma_pages;
#else
# define MAX_ARG_PAGES 32
struct page *page[MAX_ARG_PAGES];
@@ -59,6 +60,10 @@ struct linux_binprm{
unsigned long loader, exec;
};
+extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages);
+extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ int write);
+
#define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
#define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index 7113a32a86ea..e612575a2596 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -1,6 +1,10 @@
#ifndef __LINUX_BIT_SPINLOCK_H
#define __LINUX_BIT_SPINLOCK_H
+#include <linux/kernel.h>
+#include <linux/preempt.h>
+#include <asm/atomic.h>
+
/*
* bit-based spin_lock()
*
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 827cc95711ef..2184c6b97aeb 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -109,6 +109,17 @@ static inline __u8 ror8(__u8 word, unsigned int shift)
return (word >> shift) | (word << (8 - shift));
}
+/**
+ * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit
+ * @value: value to sign extend
+ * @index: 0 based bit index (0<=index<32) to sign bit
+ */
+static inline __s32 sign_extend32(__u32 value, int index)
+{
+ __u8 shift = 31 - index;
+ return (__s32)(value << shift) >> shift;
+}
+
static inline unsigned fls_long(unsigned long l)
{
if (sizeof(l) == 4)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index aae86fd10c4f..6184d81c0d11 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -250,7 +250,7 @@ struct queue_limits {
unsigned char misaligned;
unsigned char discard_misaligned;
- unsigned char no_cluster;
+ unsigned char cluster;
signed char discard_zeroes_data;
};
@@ -380,7 +380,6 @@ struct request_queue
#endif
};
-#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */
#define QUEUE_FLAG_STOPPED 2 /* queue is stopped */
#define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */
@@ -403,7 +402,6 @@ struct request_queue
#define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
- (1 << QUEUE_FLAG_CLUSTER) | \
(1 << QUEUE_FLAG_STACKABLE) | \
(1 << QUEUE_FLAG_SAME_COMP) | \
(1 << QUEUE_FLAG_ADD_RANDOM))
@@ -510,6 +508,11 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define rq_data_dir(rq) ((rq)->cmd_flags & 1)
+static inline unsigned int blk_queue_cluster(struct request_queue *q)
+{
+ return q->limits.cluster;
+}
+
/*
* We regard a request as sync, if either a read or a sync write
*/
@@ -643,7 +646,6 @@ static inline void rq_flush_dcache_pages(struct request *rq)
extern int blk_register_queue(struct gendisk *disk);
extern void blk_unregister_queue(struct gendisk *disk);
-extern void register_disk(struct gendisk *dev);
extern void generic_make_request(struct bio *bio);
extern void blk_rq_init(struct request_queue *q, struct request *rq);
extern void blk_put_request(struct request *);
@@ -805,6 +807,7 @@ extern struct request_queue *blk_init_allocated_queue(struct request_queue *,
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_limits_max_hw_sectors(struct queue_limits *, unsigned int);
extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
extern void blk_queue_max_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
@@ -1252,6 +1255,9 @@ struct block_device_operations {
int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*direct_access) (struct block_device *, sector_t,
void **, unsigned long *);
+ unsigned int (*check_events) (struct gendisk *disk,
+ unsigned int clearing);
+ /* ->media_changed() is DEPRECATED, use ->check_events() instead */
int (*media_changed) (struct gendisk *);
void (*unlock_native_capacity) (struct gendisk *);
int (*revalidate_disk) (struct gendisk *);
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 266ab9291232..499dfe982a0e 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -105,6 +105,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
#define alloc_bootmem(x) \
__alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_align(x, align) \
+ __alloc_bootmem(x, align, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_nopanic(x) \
__alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_pages(x) \
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 78e904796622..35eae4b67503 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -946,6 +946,8 @@ struct cdrom_device_info {
/* device-related storage */
unsigned int options : 30; /* options flags */
unsigned mc_flags : 2; /* media change buffer flags */
+ unsigned int vfs_events; /* cached events for vfs path */
+ unsigned int ioctl_events; /* cached events for ioctl path */
int use_count; /* number of times device opened */
char name[20]; /* name of the device type */
/* per-device flags */
@@ -965,6 +967,8 @@ struct cdrom_device_ops {
int (*open) (struct cdrom_device_info *, int);
void (*release) (struct cdrom_device_info *);
int (*drive_status) (struct cdrom_device_info *, int);
+ unsigned int (*check_events) (struct cdrom_device_info *cdi,
+ unsigned int clearing, int slot);
int (*media_changed) (struct cdrom_device_info *, int);
int (*tray_move) (struct cdrom_device_info *, int);
int (*lock_door) (struct cdrom_device_info *, int);
@@ -993,6 +997,8 @@ extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode);
extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
fmode_t mode, unsigned int cmd, unsigned long arg);
+extern unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
+ unsigned int clearing);
extern int cdrom_media_changed(struct cdrom_device_info *);
extern int register_cdrom(struct cdrom_device_info *cdi);
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index c3c74aef289d..09dcc0c2ffd5 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -43,6 +43,10 @@
#define CEPH_FEATURE_NOSRCADDR (1<<1)
#define CEPH_FEATURE_MONCLOCKCHECK (1<<2)
#define CEPH_FEATURE_FLOCK (1<<3)
+#define CEPH_FEATURE_SUBSCRIBE2 (1<<4)
+#define CEPH_FEATURE_MONNAMES (1<<5)
+#define CEPH_FEATURE_RECONNECT_SEQ (1<<6)
+#define CEPH_FEATURE_DIRLAYOUTHASH (1<<7)
/*
@@ -55,10 +59,10 @@ struct ceph_file_layout {
__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 */
+ __le32 fl_cas_hash; /* UNUSED. 0 = none; 1 = sha256 */
/* pg -> disk layout */
- __le32 fl_object_stripe_unit; /* for per-object parity, if any */
+ __le32 fl_object_stripe_unit; /* UNUSED. for per-object parity, if any */
/* object -> pg layout */
__le32 fl_pg_preferred; /* preferred primary for pg (-1 for none) */
@@ -69,6 +73,12 @@ struct ceph_file_layout {
int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+struct ceph_dir_layout {
+ __u8 dl_dir_hash; /* see ceph_hash.h for ids */
+ __u8 dl_unused1;
+ __u16 dl_unused2;
+ __u32 dl_unused3;
+} __attribute__ ((packed));
/* crypto algorithms */
#define CEPH_CRYPTO_NONE 0x0
@@ -457,7 +467,7 @@ struct ceph_mds_reply_inode {
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 */
+/* followed by frag array, symlink string, dir layout, xattr blob */
/* reply_lease follows dname, and reply_inode */
struct ceph_mds_reply_lease {
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 9e76d35670d2..72c72bfccb88 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -227,8 +227,10 @@ extern int ceph_open_session(struct ceph_client *client);
extern void ceph_release_page_vector(struct page **pages, int num_pages);
extern struct page **ceph_get_direct_page_vector(const char __user *data,
- int num_pages);
-extern void ceph_put_page_vector(struct page **pages, int num_pages);
+ int num_pages,
+ bool write_page);
+extern void ceph_put_page_vector(struct page **pages, int num_pages,
+ bool dirty);
extern void ceph_release_page_vector(struct page **pages, int num_pages);
extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
extern int ceph_copy_user_to_page_vector(struct page **pages,
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index a108b425fee2..c3011beac30d 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -110,17 +110,12 @@ struct ceph_msg_pos {
/*
* 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. */
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
new file mode 100644
index 000000000000..457bcb0a310a
--- /dev/null
+++ b/include/linux/clkdev.h
@@ -0,0 +1,36 @@
+/*
+ * include/linux/clkdev.h
+ *
+ * Copyright (C) 2008 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __CLKDEV_H
+#define __CLKDEV_H
+
+#include <asm/clkdev.h>
+
+struct clk;
+struct device;
+
+struct clk_lookup {
+ struct list_head node;
+ const char *dev_id;
+ const char *con_id;
+ struct clk *clk;
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+ const char *dev_fmt, ...);
+
+void clkdev_add(struct clk_lookup *cl);
+void clkdev_drop(struct clk_lookup *cl);
+
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
+#endif
diff --git a/include/linux/cnt32_to_63.h b/include/linux/cnt32_to_63.h
index 7605fdd1eb65..e3d8bf26e5eb 100644
--- a/include/linux/cnt32_to_63.h
+++ b/include/linux/cnt32_to_63.h
@@ -61,13 +61,31 @@ union cnt32_to_63 {
*
* 2) this code must not be preempted for a duration longer than the
* 32-bit counter half period minus the longest period between two
- * calls to this code.
+ * calls to this code;
*
* Those requirements ensure proper update to the state bit in memory.
* This is usually not a problem in practice, but if it is then a kernel
* timer should be scheduled to manage for this code to be executed often
* enough.
*
+ * And finally:
+ *
+ * 3) the cnt_lo argument must be seen as a globally incrementing value,
+ * meaning that it should be a direct reference to the counter data which
+ * can be evaluated according to a specific ordering within the macro,
+ * and not the result of a previous evaluation stored in a variable.
+ *
+ * For example, this is wrong:
+ *
+ * u32 partial = get_hw_count();
+ * u64 full = cnt32_to_63(partial);
+ * return full;
+ *
+ * This is fine:
+ *
+ * u64 full = cnt32_to_63(get_hw_count());
+ * return full;
+ *
* Note that the top bit (bit 63) in the returned value should be considered
* as garbage. It is not cleared here because callers are likely to use a
* multiplier on the returned value which can get rid of the top bit
diff --git a/include/linux/cper.h b/include/linux/cper.h
index bf972f81e2a7..3104aaff5dd0 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -39,10 +39,12 @@
* Severity difinition for error_severity in struct cper_record_header
* and section_severity in struct cper_section_descriptor
*/
-#define CPER_SEV_RECOVERABLE 0x0
-#define CPER_SEV_FATAL 0x1
-#define CPER_SEV_CORRECTED 0x2
-#define CPER_SEV_INFORMATIONAL 0x3
+enum {
+ CPER_SEV_RECOVERABLE,
+ CPER_SEV_FATAL,
+ CPER_SEV_CORRECTED,
+ CPER_SEV_INFORMATIONAL,
+};
/*
* Validation bits difinition for validation_bits in struct
@@ -201,6 +203,47 @@
UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \
0xDF, 0xAA, 0x84, 0xEC)
+#define CPER_PROC_VALID_TYPE 0x0001
+#define CPER_PROC_VALID_ISA 0x0002
+#define CPER_PROC_VALID_ERROR_TYPE 0x0004
+#define CPER_PROC_VALID_OPERATION 0x0008
+#define CPER_PROC_VALID_FLAGS 0x0010
+#define CPER_PROC_VALID_LEVEL 0x0020
+#define CPER_PROC_VALID_VERSION 0x0040
+#define CPER_PROC_VALID_BRAND_INFO 0x0080
+#define CPER_PROC_VALID_ID 0x0100
+#define CPER_PROC_VALID_TARGET_ADDRESS 0x0200
+#define CPER_PROC_VALID_REQUESTOR_ID 0x0400
+#define CPER_PROC_VALID_RESPONDER_ID 0x0800
+#define CPER_PROC_VALID_IP 0x1000
+
+#define CPER_MEM_VALID_ERROR_STATUS 0x0001
+#define CPER_MEM_VALID_PHYSICAL_ADDRESS 0x0002
+#define CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK 0x0004
+#define CPER_MEM_VALID_NODE 0x0008
+#define CPER_MEM_VALID_CARD 0x0010
+#define CPER_MEM_VALID_MODULE 0x0020
+#define CPER_MEM_VALID_BANK 0x0040
+#define CPER_MEM_VALID_DEVICE 0x0080
+#define CPER_MEM_VALID_ROW 0x0100
+#define CPER_MEM_VALID_COLUMN 0x0200
+#define CPER_MEM_VALID_BIT_POSITION 0x0400
+#define CPER_MEM_VALID_REQUESTOR_ID 0x0800
+#define CPER_MEM_VALID_RESPONDER_ID 0x1000
+#define CPER_MEM_VALID_TARGET_ID 0x2000
+#define CPER_MEM_VALID_ERROR_TYPE 0x4000
+
+#define CPER_PCIE_VALID_PORT_TYPE 0x0001
+#define CPER_PCIE_VALID_VERSION 0x0002
+#define CPER_PCIE_VALID_COMMAND_STATUS 0x0004
+#define CPER_PCIE_VALID_DEVICE_ID 0x0008
+#define CPER_PCIE_VALID_SERIAL_NUMBER 0x0010
+#define CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS 0x0020
+#define CPER_PCIE_VALID_CAPABILITY 0x0040
+#define CPER_PCIE_VALID_AER_INFO 0x0080
+
+#define CPER_PCIE_SLOT_SHIFT 3
+
/*
* All tables and structs must be byte-packed to match CPER
* specification, since the tables are provided by the system BIOS
@@ -306,6 +349,41 @@ struct cper_sec_mem_err {
__u8 error_type;
};
+struct cper_sec_pcie {
+ __u64 validation_bits;
+ __u32 port_type;
+ struct {
+ __u8 minor;
+ __u8 major;
+ __u8 reserved[2];
+ } version;
+ __u16 command;
+ __u16 status;
+ __u32 reserved;
+ struct {
+ __u16 vendor_id;
+ __u16 device_id;
+ __u8 class_code[3];
+ __u8 function;
+ __u8 device;
+ __u16 segment;
+ __u8 bus;
+ __u8 secondary_bus;
+ __u16 slot;
+ __u8 reserved;
+ } device_id;
+ struct {
+ __u32 lower;
+ __u32 upper;
+ } serial_number;
+ struct {
+ __u16 secondary_status;
+ __u16 control;
+ } bridge;
+ __u8 capability[60];
+ __u8 aer_info[96];
+};
+
/* Reset to default packing */
#pragma pack()
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 4823af64e9db..5f09323ee880 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -10,11 +10,6 @@
*
* CPUs are exported via sysfs in the class/cpu/devices/
* directory.
- *
- * Per-cpu interfaces can be implemented using a struct device_interface.
- * See the following for how to do this:
- * - drivers/base/intf.c
- * - Documentation/driver-model/interface.txt
*/
#ifndef _LINUX_CPU_H_
#define _LINUX_CPU_H_
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index 0026f267da20..088cd4ace4ef 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -20,7 +20,14 @@ extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
#define vmcore_elf_check_arch_cross(x) 0
#endif
-#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
+/*
+ * Architecture code can redefine this if there are any special checks
+ * needed for 64-bit ELF vmcores. In case of 32-bit only architecture,
+ * this can be set to zero.
+ */
+#ifndef vmcore_elf64_check_arch
+#define vmcore_elf64_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
+#endif
/*
* is_kdump_kernel() checks whether this kernel is booting after a panic of
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 6a4aea30aa09..9840a01e5524 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -4,7 +4,9 @@
#include <asm/atomic.h>
#include <linux/list.h>
#include <linux/rculist.h>
+#include <linux/rculist_bl.h>
#include <linux/spinlock.h>
+#include <linux/seqlock.h>
#include <linux/cache.h>
#include <linux/rcupdate.h>
@@ -45,6 +47,25 @@ struct dentry_stat_t {
};
extern struct dentry_stat_t dentry_stat;
+/*
+ * Compare 2 name strings, return 0 if they match, otherwise non-zero.
+ * The strings are both count bytes long, and count is non-zero.
+ */
+static inline int dentry_memcmp(const unsigned char *cs,
+ const unsigned char *ct, size_t count)
+{
+ int ret;
+ do {
+ ret = (*cs != *ct);
+ if (ret)
+ break;
+ cs++;
+ ct++;
+ count--;
+ } while (count);
+ return ret;
+}
+
/* Name hashing routines. Initial hash value */
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
#define init_name_hash() 0
@@ -81,25 +102,33 @@ full_name_hash(const unsigned char *name, unsigned int len)
* large memory footprint increase).
*/
#ifdef CONFIG_64BIT
-#define DNAME_INLINE_LEN_MIN 32 /* 192 bytes */
+# define DNAME_INLINE_LEN 32 /* 192 bytes */
#else
-#define DNAME_INLINE_LEN_MIN 40 /* 128 bytes */
+# ifdef CONFIG_SMP
+# define DNAME_INLINE_LEN 36 /* 128 bytes */
+# else
+# define DNAME_INLINE_LEN 40 /* 128 bytes */
+# endif
#endif
struct dentry {
- atomic_t d_count;
+ /* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
- spinlock_t d_lock; /* per dentry lock */
- int d_mounted;
- struct inode *d_inode; /* Where the name belongs to - NULL is
- * negative */
- /*
- * The next three fields are touched by __d_lookup. Place them here
- * so they all fit in a cache line.
- */
- struct hlist_node d_hash; /* lookup hash list */
+ seqcount_t d_seq; /* per dentry seqlock */
+ struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
+ struct inode *d_inode; /* Where the name belongs to - NULL is
+ * negative */
+ unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
+
+ /* Ref lookup also touches following */
+ unsigned int d_count; /* protected by d_lock */
+ spinlock_t d_lock; /* per dentry lock */
+ const struct dentry_operations *d_op;
+ struct super_block *d_sb; /* The root of the dentry tree */
+ unsigned long d_time; /* used by d_revalidate */
+ void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
/*
@@ -111,12 +140,6 @@ struct dentry {
} d_u;
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
- unsigned long d_time; /* used by d_revalidate */
- const struct dentry_operations *d_op;
- struct super_block *d_sb; /* The root of the dentry tree */
- void *d_fsdata; /* fs-specific data */
-
- unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};
/*
@@ -133,96 +156,67 @@ enum dentry_d_lock_class
struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *);
- int (*d_hash) (struct dentry *, struct qstr *);
- int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
- int (*d_delete)(struct dentry *);
+ int (*d_revalidate_rcu)(struct dentry *, struct nameidata *);
+ int (*d_hash)(const struct dentry *, const struct inode *,
+ struct qstr *);
+ int (*d_compare)(const struct dentry *, const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
+ int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
-};
-
-/* the dentry parameter passed to d_hash and d_compare is the parent
- * directory of the entries to be compared. It is used in case these
- * functions need any directory specific information for determining
- * equivalency classes. Using the dentry itself might not work, as it
- * might be a negative dentry which has no information associated with
- * it */
+} ____cacheline_aligned;
/*
-locking rules:
- big lock dcache_lock d_lock may block
-d_revalidate: no no no yes
-d_hash no no no yes
-d_compare: no yes yes no
-d_delete: no yes no no
-d_release: no no no yes
-d_iput: no no no yes
+ * Locking rules for dentry_operations callbacks are to be found in
+ * Documentation/filesystems/Locking. Keep it updated!
+ *
+ * FUrther descriptions are found in Documentation/filesystems/vfs.txt.
+ * Keep it updated too!
*/
/* d_flags entries */
#define DCACHE_AUTOFS_PENDING 0x0001 /* autofs: "under construction" */
-#define DCACHE_NFSFS_RENAMED 0x0002 /* this dentry has been "silly
- * renamed" and has to be
- * deleted on the last dput()
- */
-#define DCACHE_DISCONNECTED 0x0004
- /* This dentry is possibly not currently connected to the dcache tree,
- * in which case its parent will either be itself, or will have this
- * flag as well. nfsd will not use a dentry with this bit set, but will
- * first endeavour to clear the bit either by discovering that it is
- * connected, or by performing lookup operations. Any filesystem which
- * supports nfsd_operations MUST have a lookup function which, if it finds
- * a directory inode with a DCACHE_DISCONNECTED dentry, will d_move
- * that dentry into place and return that dentry rather than the passed one,
- * typically using d_splice_alias.
- */
+#define DCACHE_NFSFS_RENAMED 0x0002
+ /* this dentry has been "silly renamed" and has to be deleted on the last
+ * dput() */
+
+#define DCACHE_DISCONNECTED 0x0004
+ /* This dentry is possibly not currently connected to the dcache tree, in
+ * which case its parent will either be itself, or will have this flag as
+ * well. nfsd will not use a dentry with this bit set, but will first
+ * endeavour to clear the bit either by discovering that it is connected,
+ * or by performing lookup operations. Any filesystem which supports
+ * nfsd_operations MUST have a lookup function which, if it finds a
+ * directory inode with a DCACHE_DISCONNECTED dentry, will d_move that
+ * dentry into place and return that dentry rather than the passed one,
+ * typically using d_splice_alias. */
#define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
#define DCACHE_UNHASHED 0x0010
-
-#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched by inotify */
+#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020
+ /* Parent inode is watched by inotify */
#define DCACHE_COOKIE 0x0040 /* For use by dcookie subsystem */
-
-#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 /* Parent inode is watched by some fsnotify listener */
+#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080
+ /* Parent inode is watched by some fsnotify listener */
#define DCACHE_CANT_MOUNT 0x0100
+#define DCACHE_GENOCIDE 0x0200
+#define DCACHE_MOUNTED 0x0400 /* is a mountpoint */
-extern spinlock_t dcache_lock;
-extern seqlock_t rename_lock;
+#define DCACHE_OP_HASH 0x1000
+#define DCACHE_OP_COMPARE 0x2000
+#define DCACHE_OP_REVALIDATE 0x4000
+#define DCACHE_OP_REVALIDATE_RCU 0x8000
-/**
- * d_drop - drop a dentry
- * @dentry: dentry to drop
- *
- * d_drop() unhashes the entry from the parent dentry hashes, so that it won't
- * be found through a VFS lookup any more. Note that this is different from
- * deleting the dentry - d_delete will try to mark the dentry negative if
- * possible, giving a successful _negative_ lookup, while d_drop will
- * just make the cache lookup fail.
- *
- * d_drop() is used mainly for stuff that wants to invalidate a dentry for some
- * reason (NFS timeouts or autofs deletes).
- *
- * __d_drop requires dentry->d_lock.
- */
+#define DCACHE_OP_DELETE 0x10000
-static inline void __d_drop(struct dentry *dentry)
-{
- if (!(dentry->d_flags & DCACHE_UNHASHED)) {
- dentry->d_flags |= DCACHE_UNHASHED;
- hlist_del_rcu(&dentry->d_hash);
- }
-}
+#define DCACHE_OP_REVALIDATE_EITHER \
+ (DCACHE_OP_REVALIDATE|DCACHE_OP_REVALIDATE_RCU)
-static inline void d_drop(struct dentry *dentry)
-{
- spin_lock(&dcache_lock);
- spin_lock(&dentry->d_lock);
- __d_drop(dentry);
- spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
-}
+extern seqlock_t rename_lock;
static inline int dname_external(struct dentry *dentry)
{
@@ -235,10 +229,14 @@ static inline int dname_external(struct dentry *dentry)
extern void d_instantiate(struct dentry *, struct inode *);
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
extern struct dentry * d_materialise_unique(struct dentry *, struct inode *);
+extern void __d_drop(struct dentry *dentry);
+extern void d_drop(struct dentry *dentry);
extern void d_delete(struct dentry *);
+extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op);
/* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
+extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
extern struct dentry * d_obtain_alias(struct inode *);
@@ -296,14 +294,40 @@ static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *in
return res;
}
+extern void dentry_update_name_case(struct dentry *, struct qstr *);
+
/* used for rename() and baskets */
extern void d_move(struct dentry *, struct dentry *);
extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
/* appendix may either be NULL or be used for transname suffixes */
-extern struct dentry * d_lookup(struct dentry *, struct qstr *);
-extern struct dentry * __d_lookup(struct dentry *, struct qstr *);
-extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *);
+extern struct dentry *d_lookup(struct dentry *, struct qstr *);
+extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *);
+extern struct dentry *__d_lookup(struct dentry *, struct qstr *);
+extern struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
+ unsigned *seq, struct inode **inode);
+
+/**
+ * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok
+ * @dentry: dentry to take a ref on
+ * @seq: seqcount to verify against
+ * @Returns: 0 on failure, else 1.
+ *
+ * __d_rcu_to_refcount operates on a dentry,seq pair that was returned
+ * by __d_lookup_rcu, to get a reference on an rcu-walk dentry.
+ */
+static inline int __d_rcu_to_refcount(struct dentry *dentry, unsigned seq)
+{
+ int ret = 0;
+
+ assert_spin_locked(&dentry->d_lock);
+ if (!read_seqcount_retry(&dentry->d_seq, seq)) {
+ ret = 1;
+ dentry->d_count++;
+ }
+
+ return ret;
+}
/* validate "insecure" dentry pointer */
extern int d_validate(struct dentry *, struct dentry *);
@@ -316,34 +340,37 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *__d_path(const struct path *path, struct path *root, char *, int);
extern char *d_path(const struct path *, char *, int);
extern char *d_path_with_unreachable(const struct path *, char *, int);
-extern char *__dentry_path(struct dentry *, char *, int);
+extern char *dentry_path_raw(struct dentry *, char *, int);
extern char *dentry_path(struct dentry *, char *, int);
/* Allocation counts.. */
/**
- * dget, dget_locked - get a reference to a dentry
+ * dget, dget_dlock - get a reference to a dentry
* @dentry: dentry to get a reference to
*
* Given a dentry or %NULL pointer increment the reference count
* if appropriate and return the dentry. A dentry will not be
- * destroyed when it has references. dget() should never be
- * called for dentries with zero reference counter. For these cases
- * (preferably none, functions in dcache.c are sufficient for normal
- * needs and they take necessary precautions) you should hold dcache_lock
- * and call dget_locked() instead of dget().
+ * destroyed when it has references.
*/
-
+static inline struct dentry *dget_dlock(struct dentry *dentry)
+{
+ if (dentry)
+ dentry->d_count++;
+ return dentry;
+}
+
static inline struct dentry *dget(struct dentry *dentry)
{
if (dentry) {
- BUG_ON(!atomic_read(&dentry->d_count));
- atomic_inc(&dentry->d_count);
+ spin_lock(&dentry->d_lock);
+ dget_dlock(dentry);
+ spin_unlock(&dentry->d_lock);
}
return dentry;
}
-extern struct dentry * dget_locked(struct dentry *);
+extern struct dentry *dget_parent(struct dentry *dentry);
/**
* d_unhashed - is dentry hashed
@@ -374,21 +401,11 @@ static inline void dont_mount(struct dentry *dentry)
spin_unlock(&dentry->d_lock);
}
-static inline struct dentry *dget_parent(struct dentry *dentry)
-{
- struct dentry *ret;
-
- spin_lock(&dentry->d_lock);
- ret = dget(dentry->d_parent);
- spin_unlock(&dentry->d_lock);
- return ret;
-}
-
extern void dput(struct dentry *);
static inline int d_mountpoint(struct dentry *dentry)
{
- return dentry->d_mounted;
+ return dentry->d_flags & DCACHE_MOUNTED;
}
extern struct vfsmount *lookup_mnt(struct path *);
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 8723491f7dfd..68cd248f6d3e 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -22,6 +22,89 @@
#include <linux/types.h>
+/* IEEE 802.1Qaz std supported values */
+#define IEEE_8021QAZ_MAX_TCS 8
+
+/* This structure contains the IEEE 802.1Qaz ETS managed object
+ *
+ * @willing: willing bit in ETS configuratin TLV
+ * @ets_cap: indicates supported capacity of ets feature
+ * @cbs: credit based shaper ets algorithm supported
+ * @tc_tx_bw: tc tx bandwidth indexed by traffic class
+ * @tc_rx_bw: tc rx bandwidth indexed by traffic class
+ * @tc_tsa: TSA Assignment table, indexed by traffic class
+ * @prio_tc: priority assignment table mapping 8021Qp to traffic class
+ * @tc_reco_bw: recommended tc bandwidth indexed by traffic class for TLV
+ * @tc_reco_tsa: recommended tc bandwidth indexed by traffic class for TLV
+ * @reco_prio_tc: recommended tc tx bandwidth indexed by traffic class for TLV
+ *
+ * Recommended values are used to set fields in the ETS recommendation TLV
+ * with hardware offloaded LLDP.
+ *
+ * ----
+ * TSA Assignment 8 bit identifiers
+ * 0 strict priority
+ * 1 credit-based shaper
+ * 2 enhanced transmission selection
+ * 3-254 reserved
+ * 255 vendor specific
+ */
+struct ieee_ets {
+ __u8 willing;
+ __u8 ets_cap;
+ __u8 cbs;
+ __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS];
+ __u8 tc_rx_bw[IEEE_8021QAZ_MAX_TCS];
+ __u8 tc_tsa[IEEE_8021QAZ_MAX_TCS];
+ __u8 prio_tc[IEEE_8021QAZ_MAX_TCS];
+ __u8 tc_reco_bw[IEEE_8021QAZ_MAX_TCS];
+ __u8 tc_reco_tsa[IEEE_8021QAZ_MAX_TCS];
+ __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS];
+};
+
+/* This structure contains the IEEE 802.1Qaz PFC managed object
+ *
+ * @pfc_cap: Indicates the number of traffic classes on the local device
+ * that may simultaneously have PFC enabled.
+ * @pfc_en: bitmap indicating pfc enabled traffic classes
+ * @mbc: enable macsec bypass capability
+ * @delay: the allowance made for a round-trip propagation delay of the
+ * link in bits.
+ * @requests: count of the sent pfc frames
+ * @indications: count of the received pfc frames
+ */
+struct ieee_pfc {
+ __u8 pfc_cap;
+ __u8 pfc_en;
+ __u8 mbc;
+ __u16 delay;
+ __u64 requests[IEEE_8021QAZ_MAX_TCS];
+ __u64 indications[IEEE_8021QAZ_MAX_TCS];
+};
+
+/* This structure contains the IEEE 802.1Qaz APP managed object. This
+ * object is also used for the CEE std as well. There is no difference
+ * between the objects.
+ *
+ * @selector: protocol identifier type
+ * @protocol: protocol of type indicated
+ * @priority: 3-bit unsigned integer indicating priority
+ *
+ * ----
+ * Selector field values
+ * 0 Reserved
+ * 1 Ethertype
+ * 2 Well known port number over TCP or SCTP
+ * 3 Well known port number over UDP or DCCP
+ * 4 Well known port number over TCP, SCTP, UDP, or DCCP
+ * 5-7 Reserved
+ */
+struct dcb_app {
+ __u8 selector;
+ __u32 protocol;
+ __u8 priority;
+};
+
struct dcbmsg {
__u8 dcb_family;
__u8 cmd;
@@ -50,6 +133,12 @@ struct dcbmsg {
* @DCB_CMD_SBCN: get backward congestion notification configration.
* @DCB_CMD_GAPP: get application protocol configuration
* @DCB_CMD_SAPP: set application protocol configuration
+ * @DCB_CMD_IEEE_SET: set IEEE 802.1Qaz configuration
+ * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration
+ * @DCB_CMD_GDCBX: get DCBX engine configuration
+ * @DCB_CMD_SDCBX: set DCBX engine configuration
+ * @DCB_CMD_GFEATCFG: get DCBX features flags
+ * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags
*/
enum dcbnl_commands {
DCB_CMD_UNDEFINED,
@@ -83,6 +172,15 @@ enum dcbnl_commands {
DCB_CMD_GAPP,
DCB_CMD_SAPP,
+ DCB_CMD_IEEE_SET,
+ DCB_CMD_IEEE_GET,
+
+ DCB_CMD_GDCBX,
+ DCB_CMD_SDCBX,
+
+ DCB_CMD_GFEATCFG,
+ DCB_CMD_SFEATCFG,
+
__DCB_CMD_ENUM_MAX,
DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
};
@@ -102,6 +200,9 @@ enum dcbnl_commands {
* @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED)
* @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED)
* @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED)
+ * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED)
+ * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8)
+ * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED)
*/
enum dcbnl_attrs {
DCB_ATTR_UNDEFINED,
@@ -119,10 +220,32 @@ enum dcbnl_attrs {
DCB_ATTR_BCN,
DCB_ATTR_APP,
+ /* IEEE std attributes */
+ DCB_ATTR_IEEE,
+
+ DCB_ATTR_DCBX,
+ DCB_ATTR_FEATCFG,
+
__DCB_ATTR_ENUM_MAX,
DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
};
+enum ieee_attrs {
+ DCB_ATTR_IEEE_UNSPEC,
+ DCB_ATTR_IEEE_ETS,
+ DCB_ATTR_IEEE_PFC,
+ DCB_ATTR_IEEE_APP_TABLE,
+ __DCB_ATTR_IEEE_MAX
+};
+#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
+
+enum ieee_attrs_app {
+ DCB_ATTR_IEEE_APP_UNSPEC,
+ DCB_ATTR_IEEE_APP,
+ __DCB_ATTR_IEEE_APP_MAX
+};
+#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)
+
/**
* enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
*
@@ -262,6 +385,8 @@ enum dcbnl_tc_attrs {
* @DCB_CAP_ATTR_GSP: (NLA_U8) device supports group strict priority
* @DCB_CAP_ATTR_BCN: (NLA_U8) device supports Backwards Congestion
* Notification
+ * @DCB_CAP_ATTR_DCBX: (NLA_U8) device supports DCBX engine
+ *
*/
enum dcbnl_cap_attrs {
DCB_CAP_ATTR_UNDEFINED,
@@ -273,12 +398,45 @@ enum dcbnl_cap_attrs {
DCB_CAP_ATTR_PFC_TCS,
DCB_CAP_ATTR_GSP,
DCB_CAP_ATTR_BCN,
+ DCB_CAP_ATTR_DCBX,
__DCB_CAP_ATTR_ENUM_MAX,
DCB_CAP_ATTR_MAX = __DCB_CAP_ATTR_ENUM_MAX - 1,
};
/**
+ * DCBX capability flags
+ *
+ * @DCB_CAP_DCBX_HOST: DCBX negotiation is performed by the host LLDP agent.
+ * 'set' routines are used to configure the device with
+ * the negotiated parameters
+ *
+ * @DCB_CAP_DCBX_LLD_MANAGED: DCBX negotiation is not performed in the host but
+ * by another entity
+ * 'get' routines are used to retrieve the
+ * negotiated parameters
+ * 'set' routines can be used to set the initial
+ * negotiation configuration
+ *
+ * @DCB_CAP_DCBX_VER_CEE: for a non-host DCBX engine, indicates the engine
+ * supports the CEE protocol flavor
+ *
+ * @DCB_CAP_DCBX_VER_IEEE: for a non-host DCBX engine, indicates the engine
+ * supports the IEEE protocol flavor
+ *
+ * @DCB_CAP_DCBX_STATIC: for a non-host DCBX engine, indicates the engine
+ * supports static configuration (i.e no actual
+ * negotiation is performed negotiated parameters equal
+ * the initial configuration)
+ *
+ */
+#define DCB_CAP_DCBX_HOST 0x01
+#define DCB_CAP_DCBX_LLD_MANAGED 0x02
+#define DCB_CAP_DCBX_VER_CEE 0x04
+#define DCB_CAP_DCBX_VER_IEEE 0x08
+#define DCB_CAP_DCBX_STATIC 0x10
+
+/**
* enum dcbnl_numtcs_attrs - number of traffic classes
*
* @DCB_NUMTCS_ATTR_UNDEFINED: unspecified attribute to catch errors
@@ -355,4 +513,30 @@ enum dcbnl_app_attrs {
DCB_APP_ATTR_MAX = __DCB_APP_ATTR_ENUM_MAX - 1,
};
+/**
+ * enum dcbnl_featcfg_attrs - features conifiguration flags
+ *
+ * @DCB_FEATCFG_ATTR_UNDEFINED: unspecified attribute to catch errors
+ * @DCB_FEATCFG_ATTR_ALL: (NLA_FLAG) all features configuration attributes
+ * @DCB_FEATCFG_ATTR_PG: (NLA_U8) configuration flags for priority groups
+ * @DCB_FEATCFG_ATTR_PFC: (NLA_U8) configuration flags for priority
+ * flow control
+ * @DCB_FEATCFG_ATTR_APP: (NLA_U8) configuration flags for application TLV
+ *
+ */
+#define DCB_FEATCFG_ERROR 0x01 /* error in feature resolution */
+#define DCB_FEATCFG_ENABLE 0x02 /* enable feature */
+#define DCB_FEATCFG_WILLING 0x04 /* feature is willing */
+#define DCB_FEATCFG_ADVERTISE 0x08 /* advertise feature */
+enum dcbnl_featcfg_attrs {
+ DCB_FEATCFG_ATTR_UNDEFINED,
+ DCB_FEATCFG_ATTR_ALL,
+ DCB_FEATCFG_ATTR_PG,
+ DCB_FEATCFG_ATTR_PFC,
+ DCB_FEATCFG_ATTR_APP,
+
+ __DCB_FEATCFG_ATTR_ENUM_MAX,
+ DCB_FEATCFG_ATTR_MAX = __DCB_FEATCFG_ATTR_ENUM_MAX - 1,
+};
+
#endif /* __LINUX_DCBNL_H__ */
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 749f01ccd26e..010e2d87ed75 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -197,6 +197,21 @@ enum dccp_feature_numbers {
DCCPF_MAX_CCID_SPECIFIC = 255,
};
+/* DCCP socket control message types for cmsg */
+enum dccp_cmsg_type {
+ DCCP_SCM_PRIORITY = 1,
+ DCCP_SCM_QPOLICY_MAX = 0xFFFF,
+ /* ^-- Up to here reserved exclusively for qpolicy parameters */
+ DCCP_SCM_MAX
+};
+
+/* DCCP priorities for outgoing/queued packets */
+enum dccp_packet_dequeueing_policy {
+ DCCPQ_POLICY_SIMPLE,
+ DCCPQ_POLICY_PRIO,
+ DCCPQ_POLICY_MAX
+};
+
/* DCCP socket options */
#define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */
#define DCCP_SOCKOPT_SERVICE 2
@@ -210,6 +225,8 @@ enum dccp_feature_numbers {
#define DCCP_SOCKOPT_CCID 13
#define DCCP_SOCKOPT_TX_CCID 14
#define DCCP_SOCKOPT_RX_CCID 15
+#define DCCP_SOCKOPT_QPOLICY_ID 16
+#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17
#define DCCP_SOCKOPT_CCID_RX_INFO 128
#define DCCP_SOCKOPT_CCID_TX_INFO 192
@@ -458,10 +475,13 @@ struct dccp_ackvec;
* @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
* @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection)
* @dccps_options_received - parsed set of retrieved options
+ * @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy
+ * @dccps_tx_qlen - maximum length of the TX queue
* @dccps_role - role of this sock, one of %dccp_role
* @dccps_hc_rx_insert_options - receiver wants to add options when acking
* @dccps_hc_tx_insert_options - sender wants to add options when sending
* @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3)
+ * @dccps_sync_scheduled - flag which signals "send out-of-band message soon"
* @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets
* @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing)
* @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs)
@@ -499,10 +519,13 @@ struct dccp_sock {
struct ccid *dccps_hc_rx_ccid;
struct ccid *dccps_hc_tx_ccid;
struct dccp_options_received dccps_options_received;
+ __u8 dccps_qpolicy;
+ __u32 dccps_tx_qlen;
enum dccp_role dccps_role:2;
__u8 dccps_hc_rx_insert_options:1;
__u8 dccps_hc_tx_insert_options:1;
__u8 dccps_server_timewait:1;
+ __u8 dccps_sync_scheduled:1;
struct tasklet_struct dccps_xmitlet;
struct timer_list dccps_xmit_timer;
};
diff --git a/include/linux/device.h b/include/linux/device.h
index dd4895313468..032bdb5406a2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -197,6 +197,7 @@ struct class {
struct class_attribute *class_attrs;
struct device_attribute *dev_attrs;
+ struct bin_attribute *dev_bin_attrs;
struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index 49eab360d5d4..e453e1174ae1 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -44,7 +44,7 @@
* Remove a device, destroy any tables.
*
* DM_DEV_RENAME:
- * Rename a device.
+ * Rename a device or set its uuid if none was previously supplied.
*
* DM_SUSPEND:
* This performs both suspend and resume, depending which flag is
@@ -267,9 +267,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 18
+#define DM_VERSION_MINOR 19
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2010-06-29)"
+#define DM_VERSION_EXTRA "-ioctl (2010-10-14)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
@@ -322,4 +322,10 @@ enum {
*/
#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
+/*
+ * If set, rename changes the uuid not the name. Only permitted
+ * if no uuid was previously supplied: an existing uuid cannot be changed.
+ */
+#define DM_UUID_FLAG (1 << 14) /* In */
+
#endif /* _LINUX_DM_IOCTL_H */
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 9d8688b92d8b..8cd00ad98d37 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -824,6 +824,8 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie);
#ifdef CONFIG_DMA_ENGINE
enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
void dma_issue_pending_all(void);
+struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
+void dma_release_channel(struct dma_chan *chan);
#else
static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
{
@@ -831,7 +833,14 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript
}
static inline void dma_issue_pending_all(void)
{
- do { } while (0);
+}
+static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask,
+ dma_filter_fn fn, void *fn_param)
+{
+ return NULL;
+}
+static inline void dma_release_channel(struct dma_chan *chan)
+{
}
#endif
@@ -842,8 +851,6 @@ void dma_async_device_unregister(struct dma_device *device);
void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
#define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
-struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
-void dma_release_channel(struct dma_chan *chan);
/* --- Helper iov-locking functions --- */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 6628a507fd3b..1908929204a9 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -691,7 +691,9 @@ struct ethtool_ops {
#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */
#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */
-#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
+/* Get link status for host, i.e. whether the interface *and* the
+ * physical port (if there is one) are up (ethtool_value). */
+#define ETHTOOL_GLINK 0x0000000a
#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */
#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 0f0121467fc4..6c6133f76e16 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -83,11 +83,13 @@
FAN_ALL_PERM_EVENTS |\
FAN_Q_OVERFLOW)
-#define FANOTIFY_METADATA_VERSION 2
+#define FANOTIFY_METADATA_VERSION 3
struct fanotify_event_metadata {
__u32 event_len;
- __u32 vers;
+ __u8 vers;
+ __u8 reserved;
+ __u16 metadata_len;
__aligned_u64 mask;
__s32 fd;
__s32 pid;
@@ -96,11 +98,13 @@ struct fanotify_event_metadata {
struct fanotify_response {
__s32 fd;
__u32 response;
-} __attribute__ ((packed));
+};
/* Legit userspace responses to a _PERM event */
#define FAN_ALLOW 0x01
#define FAN_DENY 0x02
+/* No fd set in event */
+#define FAN_NOFD -1
/* Helper functions to deal with fanotify_event_metadata buffers */
#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 69b43dbea6c6..45266b75409a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -91,54 +91,6 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define BPF_TAX 0x00
#define BPF_TXA 0x80
-enum {
- BPF_S_RET_K = 0,
- BPF_S_RET_A,
- BPF_S_ALU_ADD_K,
- BPF_S_ALU_ADD_X,
- BPF_S_ALU_SUB_K,
- BPF_S_ALU_SUB_X,
- BPF_S_ALU_MUL_K,
- BPF_S_ALU_MUL_X,
- BPF_S_ALU_DIV_X,
- BPF_S_ALU_AND_K,
- BPF_S_ALU_AND_X,
- BPF_S_ALU_OR_K,
- BPF_S_ALU_OR_X,
- BPF_S_ALU_LSH_K,
- BPF_S_ALU_LSH_X,
- BPF_S_ALU_RSH_K,
- BPF_S_ALU_RSH_X,
- BPF_S_ALU_NEG,
- BPF_S_LD_W_ABS,
- BPF_S_LD_H_ABS,
- BPF_S_LD_B_ABS,
- BPF_S_LD_W_LEN,
- BPF_S_LD_W_IND,
- BPF_S_LD_H_IND,
- BPF_S_LD_B_IND,
- BPF_S_LD_IMM,
- BPF_S_LDX_W_LEN,
- BPF_S_LDX_B_MSH,
- BPF_S_LDX_IMM,
- BPF_S_MISC_TAX,
- BPF_S_MISC_TXA,
- BPF_S_ALU_DIV_K,
- BPF_S_LD_MEM,
- BPF_S_LDX_MEM,
- BPF_S_ST,
- BPF_S_STX,
- BPF_S_JMP_JA,
- BPF_S_JMP_JEQ_K,
- BPF_S_JMP_JEQ_X,
- BPF_S_JMP_JGE_K,
- BPF_S_JMP_JGE_X,
- BPF_S_JMP_JGT_K,
- BPF_S_JMP_JGT_X,
- BPF_S_JMP_JSET_K,
- BPF_S_JMP_JSET_X,
-};
-
#ifndef BPF_MAXINSNS
#define BPF_MAXINSNS 4096
#endif
@@ -172,7 +124,9 @@ enum {
#define SKF_AD_MARK 20
#define SKF_AD_QUEUE 24
#define SKF_AD_HATYPE 28
-#define SKF_AD_MAX 32
+#define SKF_AD_RXHASH 32
+#define SKF_AD_CPU 36
+#define SKF_AD_MAX 40
#define SKF_NET_OFF (-0x100000)
#define SKF_LL_OFF (-0x200000)
@@ -194,8 +148,8 @@ struct sk_buff;
struct sock;
extern int sk_filter(struct sock *sk, struct sk_buff *skb);
-extern unsigned int sk_run_filter(struct sk_buff *skb,
- struct sock_filter *filter, int flen);
+extern unsigned int sk_run_filter(const struct sk_buff *skb,
+ const struct sock_filter *filter);
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, int flen);
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 1cd637ef62d2..9a3f5f9383f6 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -302,9 +302,9 @@ struct fw_packet {
struct fw_transaction {
int node_id; /* The generation is implied; it is always the current. */
int tlabel;
- int timestamp;
struct list_head link;
struct fw_card *card;
+ bool is_split_transaction;
struct timer_list split_timeout_timer;
struct fw_packet packet;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c9e06cc70dad..aa1ae4ba5b3d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -392,6 +392,7 @@ struct inodes_stat_t {
#include <linux/capability.h>
#include <linux/semaphore.h>
#include <linux/fiemap.h>
+#include <linux/rculist_bl.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
@@ -602,6 +603,7 @@ struct address_space_operations {
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, gfp_t);
+ void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*get_xip_mem)(struct address_space *, pgoff_t, int,
@@ -662,8 +664,9 @@ struct block_device {
void * bd_claiming;
void * bd_holder;
int bd_holders;
+ bool bd_write_holder;
#ifdef CONFIG_SYSFS
- struct list_head bd_holder_list;
+ struct gendisk * bd_holder_disk; /* for sysfs slave linkng */
#endif
struct block_device * bd_contains;
unsigned bd_block_size;
@@ -732,16 +735,31 @@ struct posix_acl;
#define ACL_NOT_CACHED ((void *)(-1))
struct inode {
+ /* RCU path lookup touches following: */
+ umode_t i_mode;
+ uid_t i_uid;
+ gid_t i_gid;
+ const struct inode_operations *i_op;
+ struct super_block *i_sb;
+
+ spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
+ unsigned int i_flags;
+ struct mutex i_mutex;
+
+ unsigned long i_state;
+ unsigned long dirtied_when; /* jiffies of first dirtying */
+
struct hlist_node i_hash;
struct list_head i_wb_list; /* backing dev IO list */
struct list_head i_lru; /* inode LRU list */
struct list_head i_sb_list;
- struct list_head i_dentry;
+ union {
+ struct list_head i_dentry;
+ struct rcu_head i_rcu;
+ };
unsigned long i_ino;
atomic_t i_count;
unsigned int i_nlink;
- uid_t i_uid;
- gid_t i_gid;
dev_t i_rdev;
unsigned int i_blkbits;
u64 i_version;
@@ -754,13 +772,8 @@ struct inode {
struct timespec i_ctime;
blkcnt_t i_blocks;
unsigned short i_bytes;
- umode_t i_mode;
- spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
- struct mutex i_mutex;
struct rw_semaphore i_alloc_sem;
- const struct inode_operations *i_op;
const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
- struct super_block *i_sb;
struct file_lock *i_flock;
struct address_space *i_mapping;
struct address_space i_data;
@@ -781,11 +794,6 @@ struct inode {
struct hlist_head i_fsnotify_marks;
#endif
- unsigned long i_state;
- unsigned long dirtied_when; /* jiffies of first dirtying */
-
- unsigned int i_flags;
-
#ifdef CONFIG_IMA
/* protected by i_lock */
unsigned int i_readcount; /* struct files open RO */
@@ -1371,13 +1379,13 @@ struct super_block {
const struct xattr_handler **s_xattr;
struct list_head s_inodes; /* all inodes */
- struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
+ struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
#ifdef CONFIG_SMP
struct list_head __percpu *s_files;
#else
struct list_head s_files;
#endif
- /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
+ /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */
struct list_head s_dentry_lru; /* unused dentry lru */
int s_nr_dentry_unused; /* # of dentry on lru */
@@ -1544,9 +1552,20 @@ struct file_operations {
int (*setlease)(struct file *, long, struct file_lock **);
};
+#define IPERM_FLAG_RCU 0x0001
+
struct inode_operations {
- int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
+ void * (*follow_link) (struct dentry *, struct nameidata *);
+ int (*permission) (struct inode *, int);
+ int (*permission_rcu) (struct inode *, int, unsigned int);
+ int (*check_acl)(struct inode *, int);
+ int (*check_acl_rcu)(struct inode *, int, unsigned int);
+
+ int (*readlink) (struct dentry *, char __user *,int);
+ void (*put_link) (struct dentry *, struct nameidata *, void *);
+
+ int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -1555,12 +1574,7 @@ struct inode_operations {
int (*mknod) (struct inode *,struct dentry *,int,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
- int (*readlink) (struct dentry *, char __user *,int);
- void * (*follow_link) (struct dentry *, struct nameidata *);
- void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int);
- int (*check_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1572,7 +1586,7 @@ struct inode_operations {
loff_t len);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
-};
+} ____cacheline_aligned;
struct seq_file;
@@ -2005,7 +2019,6 @@ extern struct block_device *bdgrab(struct block_device *bdev);
extern void bd_set_size(struct block_device *, loff_t size);
extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *);
-extern struct block_device *open_by_devnum(dev_t, fmode_t);
extern void invalidate_bdev(struct block_device *);
extern int sync_blockdev(struct block_device *bdev);
extern struct super_block *freeze_bdev(struct block_device *);
@@ -2036,16 +2049,20 @@ extern const struct file_operations def_fifo_fops;
extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
-extern int blkdev_get(struct block_device *, fmode_t);
-extern int blkdev_put(struct block_device *, fmode_t);
-extern int bd_claim(struct block_device *, void *);
-extern void bd_release(struct block_device *);
+extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder);
+extern struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
+ void *holder);
+extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode,
+ void *holder);
+extern int blkdev_put(struct block_device *bdev, fmode_t mode);
#ifdef CONFIG_SYSFS
-extern int bd_claim_by_disk(struct block_device *, void *, struct gendisk *);
-extern void bd_release_from_disk(struct block_device *, struct gendisk *);
+extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
#else
-#define bd_claim_by_disk(bdev, holder, disk) bd_claim(bdev, holder)
-#define bd_release_from_disk(bdev, disk) bd_release(bdev)
+static inline int bd_link_disk_holder(struct block_device *bdev,
+ struct gendisk *disk)
+{
+ return 0;
+}
#endif
#endif
@@ -2081,8 +2098,6 @@ static inline void unregister_chrdev(unsigned int major, const char *name)
extern const char *__bdevname(dev_t, char *buffer);
extern const char *bdevname(struct block_device *bdev, char *buffer);
extern struct block_device *lookup_bdev(const char *);
-extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
-extern void close_bdev_exclusive(struct block_device *, fmode_t);
extern void blkdev_show(struct seq_file *,off_t);
#else
@@ -2157,6 +2172,8 @@ extern sector_t bmap(struct inode *, sector_t);
#endif
extern int notify_change(struct dentry *, struct iattr *);
extern int inode_permission(struct inode *, int);
+extern int generic_permission_rcu(struct inode *, int, unsigned int,
+ int (*check_acl_rcu)(struct inode *, int, unsigned int));
extern int generic_permission(struct inode *, int,
int (*check_acl)(struct inode *, int));
@@ -2229,6 +2246,7 @@ extern void iget_failed(struct inode *);
extern void end_writeback(struct inode *);
extern void __destroy_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
+extern void free_inode_nonrcu(struct inode *inode);
extern int should_remove_suid(struct dentry *);
extern int file_remove_suid(struct file *);
@@ -2445,6 +2463,10 @@ static inline ino_t parent_ino(struct dentry *dentry)
{
ino_t res;
+ /*
+ * Don't strictly need d_lock here? If the parent ino could change
+ * then surely we'd have a deeper race in the caller?
+ */
spin_lock(&dentry->d_lock);
res = dentry->d_parent->d_inode->i_ino;
spin_unlock(&dentry->d_lock);
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index a42b5bf02f8b..003dc0fd7347 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -2,10 +2,13 @@
#define _LINUX_FS_STRUCT_H
#include <linux/path.h>
+#include <linux/spinlock.h>
+#include <linux/seqlock.h>
struct fs_struct {
int users;
spinlock_t lock;
+ seqcount_t seq;
int umask;
int in_exec;
struct path root, pwd;
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 5c185fa27089..2a53f10712b3 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -17,7 +17,6 @@
/*
* fsnotify_d_instantiate - instantiate a dentry for inode
- * Called with dcache_lock held.
*/
static inline void fsnotify_d_instantiate(struct dentry *dentry,
struct inode *inode)
@@ -62,7 +61,6 @@ static inline int fsnotify_perm(struct file *file, int mask)
/*
* fsnotify_d_move - dentry has been moved
- * Called with dcache_lock and dentry->d_lock held.
*/
static inline void fsnotify_d_move(struct dentry *dentry)
{
@@ -235,9 +233,6 @@ static inline void fsnotify_open(struct file *file)
if (S_ISDIR(inode->i_mode))
mask |= FS_ISDIR;
- /* FMODE_NONOTIFY must never be set from user */
- file->f_mode &= ~FMODE_NONOTIFY;
-
fsnotify_parent(path, NULL, mask);
fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
}
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 0a68f924f06f..69ad89b50489 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -166,7 +166,7 @@ struct fsnotify_group {
struct mutex access_mutex;
struct list_head access_list;
wait_queue_head_t access_waitq;
- bool bypass_perm; /* protected by access_mutex */
+ atomic_t bypass_perm;
#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
int f_flags;
unsigned int max_marks;
@@ -329,9 +329,15 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
{
struct dentry *parent;
- assert_spin_locked(&dcache_lock);
assert_spin_locked(&dentry->d_lock);
+ /*
+ * Serialisation of setting PARENT_WATCHED on the dentries is provided
+ * by d_lock. If inotify_inode_watched changes after we have taken
+ * d_lock, the following __fsnotify_update_child_dentry_flags call will
+ * find our entry, so it will spin until we complete here, and update
+ * us with the new state.
+ */
parent = dentry->d_parent;
if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
@@ -341,15 +347,12 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
/*
* fsnotify_d_instantiate - instantiate a dentry for inode
- * Called with dcache_lock held.
*/
static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
{
if (!inode)
return;
- assert_spin_locked(&dcache_lock);
-
spin_lock(&dentry->d_lock);
__fsnotify_update_dcache_flags(dentry);
spin_unlock(&dentry->d_lock);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index c3c578e09833..d464de53db43 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -41,6 +41,12 @@
* 7.15
* - add store notify
* - add retrieve notify
+ *
+ * 7.16
+ * - add BATCH_FORGET request
+ * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
+ * fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
+ * - add FUSE_IOCTL_32BIT flag
*/
#ifndef _LINUX_FUSE_H
@@ -72,7 +78,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 15
+#define FUSE_KERNEL_MINOR_VERSION 16
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -200,12 +206,14 @@ struct fuse_file_lock {
* FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
* FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
* FUSE_IOCTL_RETRY: retry with new iovecs
+ * FUSE_IOCTL_32BIT: 32bit ioctl
*
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
*/
#define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2)
+#define FUSE_IOCTL_32BIT (1 << 3)
#define FUSE_IOCTL_MAX_IOV 256
@@ -256,6 +264,7 @@ enum fuse_opcode {
FUSE_IOCTL = 39,
FUSE_POLL = 40,
FUSE_NOTIFY_REPLY = 41,
+ FUSE_BATCH_FORGET = 42,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -290,6 +299,16 @@ struct fuse_forget_in {
__u64 nlookup;
};
+struct fuse_forget_one {
+ __u64 nodeid;
+ __u64 nlookup;
+};
+
+struct fuse_batch_forget_in {
+ __u32 count;
+ __u32 dummy;
+};
+
struct fuse_getattr_in {
__u32 getattr_flags;
__u32 dummy;
@@ -510,6 +529,11 @@ struct fuse_ioctl_in {
__u32 out_size;
};
+struct fuse_ioctl_iovec {
+ __u64 base;
+ __u64 len;
+};
+
struct fuse_ioctl_out {
__s32 result;
__u32 flags;
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h
index 574bea4013b6..b57e89c24f51 100644
--- a/include/linux/generic_acl.h
+++ b/include/linux/generic_acl.h
@@ -11,5 +11,6 @@ extern const struct xattr_handler generic_acl_default_handler;
int generic_acl_init(struct inode *, struct inode *);
int generic_acl_chmod(struct inode *);
int generic_check_acl(struct inode *inode, int mask);
+int generic_check_acl_rcu(struct inode *inode, int mask, unsigned int flags);
#endif /* LINUX_GENERIC_ACL_H */
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 7a7b9c1644e4..13893aa2ac9d 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -127,6 +127,11 @@ struct hd_struct {
#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
#define GENHD_FL_NATIVE_CAPACITY 128
+enum {
+ DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
+ DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */
+};
+
#define BLK_SCSI_MAX_CMDS (256)
#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
@@ -143,6 +148,8 @@ struct disk_part_tbl {
struct hd_struct __rcu *part[];
};
+struct disk_events;
+
struct gendisk {
/* major, first_minor and minors are input parameters only,
* don't use directly. Use disk_devt() and disk_max_parts().
@@ -154,6 +161,10 @@ struct gendisk {
char disk_name[DISK_NAME_LEN]; /* name of major driver */
char *(*devnode)(struct gendisk *gd, mode_t *mode);
+
+ unsigned int events; /* supported events */
+ unsigned int async_events; /* async events, subset of all */
+
/* Array of pointers to partitions indexed by partno.
* Protected with matching bdev lock but stat and other
* non-critical accesses use RCU. Always access through
@@ -171,9 +182,8 @@ struct gendisk {
struct kobject *slave_dir;
struct timer_rand_state *random;
-
atomic_t sync_io; /* RAID */
- struct work_struct async_notify;
+ struct disk_events *ev;
#ifdef CONFIG_BLK_DEV_INTEGRITY
struct blk_integrity *integrity;
#endif
@@ -395,7 +405,6 @@ extern void part_round_stats(int cpu, struct hd_struct *part);
/* block/genhd.c */
extern void add_disk(struct gendisk *disk);
extern void del_gendisk(struct gendisk *gp);
-extern void unlink_gendisk(struct gendisk *gp);
extern struct gendisk *get_gendisk(dev_t dev, int *partno);
extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
@@ -407,6 +416,11 @@ static inline int get_disk_ro(struct gendisk *disk)
return disk->part0.policy;
}
+extern void disk_block_events(struct gendisk *disk);
+extern void disk_unblock_events(struct gendisk *disk);
+extern void disk_check_events(struct gendisk *disk);
+extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
+
/* drivers/char/random.c */
extern void add_disk_randomness(struct gendisk *disk);
extern void rand_initialize_disk(struct gendisk *disk);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index e8713d55360a..f54adfcbec9c 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -360,7 +360,7 @@ void drain_local_pages(void *dummy);
extern gfp_t gfp_allowed_mask;
-extern void set_gfp_allowed_mask(gfp_t mask);
-extern gfp_t clear_gfp_allowed_mask(gfp_t mask);
+extern void pm_restrict_gfp_mask(void);
+extern void pm_restore_gfp_mask(void);
#endif /* __LINUX_GFP_H */
diff --git a/include/linux/gpio-i2cmux.h b/include/linux/gpio-i2cmux.h
new file mode 100644
index 000000000000..4a333bb0bd0d
--- /dev/null
+++ b/include/linux/gpio-i2cmux.h
@@ -0,0 +1,38 @@
+/*
+ * gpio-i2cmux interface to platform code
+ *
+ * Peter Korsgaard <peter.korsgaard@barco.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_GPIO_I2CMUX_H
+#define _LINUX_GPIO_I2CMUX_H
+
+/* MUX has no specific idle mode */
+#define GPIO_I2CMUX_NO_IDLE ((unsigned)-1)
+
+/**
+ * struct gpio_i2cmux_platform_data - Platform-dependent data for gpio-i2cmux
+ * @parent: Parent I2C bus adapter number
+ * @base_nr: Base I2C bus number to number adapters from or zero for dynamic
+ * @values: Array of bitmasks of GPIO settings (low/high) for each
+ * position
+ * @n_values: Number of multiplexer positions (busses to instantiate)
+ * @gpios: Array of GPIO numbers used to control MUX
+ * @n_gpios: Number of GPIOs used to control MUX
+ * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
+ */
+struct gpio_i2cmux_platform_data {
+ int parent;
+ int base_nr;
+ const unsigned *values;
+ int n_values;
+ const unsigned *gpios;
+ int n_gpios;
+ unsigned idle;
+};
+
+#endif /* _LINUX_GPIO_I2CMUX_H */
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index ce73a30113b4..dd1a56fbe924 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -16,6 +16,8 @@ struct gpio_keys_button {
struct gpio_keys_platform_data {
struct gpio_keys_button *buttons;
int nbuttons;
+ unsigned int poll_interval; /* polling interval in msecs -
+ for polling driver only */
unsigned int rep:1; /* enable input subsystem auto repeat */
int (*enable)(struct device *dev);
void (*disable)(struct device *dev);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index bb0f56f5c01e..20b9801f669b 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -820,6 +820,49 @@ static inline void hid_hw_stop(struct hid_device *hdev)
hdev->ll_driver->stop(hdev);
}
+/**
+ * hid_hw_open - signal underlaying HW to start delivering events
+ *
+ * @hdev: hid device
+ *
+ * Tell underlying HW to start delivering events from the device.
+ * This function should be called sometime after successful call
+ * to hid_hiw_start().
+ */
+static inline int __must_check hid_hw_open(struct hid_device *hdev)
+{
+ return hdev->ll_driver->open(hdev);
+}
+
+/**
+ * hid_hw_close - signal underlaying HW to stop delivering events
+ *
+ * @hdev: hid device
+ *
+ * This function indicates that we are not interested in the events
+ * from this device anymore. Delivery of events may or may not stop,
+ * depending on the number of users still outstanding.
+ */
+static inline void hid_hw_close(struct hid_device *hdev)
+{
+ hdev->ll_driver->close(hdev);
+}
+
+/**
+ * hid_hw_power - requests underlying HW to go into given power mode
+ *
+ * @hdev: hid device
+ * @level: requested power level (one of %PM_HINT_* defines)
+ *
+ * This function requests underlying hardware to enter requested power
+ * mode.
+ */
+
+static inline int hid_hw_power(struct hid_device *hdev, int level)
+{
+ return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
+}
+
void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
int interrupt);
@@ -838,12 +881,32 @@ int hid_pidff_init(struct hid_device *hid);
#define hid_pidff_init NULL
#endif
-#define dbg_hid(format, arg...) if (hid_debug) \
- printk(KERN_DEBUG "%s: " format ,\
- __FILE__ , ## arg)
-#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
- __FILE__ , ## arg)
-#endif /* HID_FF */
+#define dbg_hid(format, arg...) \
+do { \
+ if (hid_debug) \
+ printk(KERN_DEBUG "%s: " format, __FILE__, ##arg); \
+} while (0)
+
+#define hid_printk(level, hid, fmt, arg...) \
+ dev_printk(level, &(hid)->dev, fmt, ##arg)
+#define hid_emerg(hid, fmt, arg...) \
+ dev_emerg(&(hid)->dev, fmt, ##arg)
+#define hid_crit(hid, fmt, arg...) \
+ dev_crit(&(hid)->dev, fmt, ##arg)
+#define hid_alert(hid, fmt, arg...) \
+ dev_alert(&(hid)->dev, fmt, ##arg)
+#define hid_err(hid, fmt, arg...) \
+ dev_err(&(hid)->dev, fmt, ##arg)
+#define hid_notice(hid, fmt, arg...) \
+ dev_notice(&(hid)->dev, fmt, ##arg)
+#define hid_warn(hid, fmt, arg...) \
+ dev_warn(&(hid)->dev, fmt, ##arg)
+#define hid_info(hid, fmt, arg...) \
+ dev_info(&(hid)->dev, fmt, ##arg)
+#define hid_dbg(hid, fmt, arg...) \
+ dev_dbg(&(hid)->dev, fmt, ##arg)
+
+#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 78ebf507ce56..7472449cbb74 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -1,9 +1,14 @@
#ifndef __I2C_OMAP_H__
#define __I2C_OMAP_H__
+#include <linux/platform_device.h>
+
struct omap_i2c_bus_platform_data {
u32 clkrate;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
+ int (*device_enable) (struct platform_device *pdev);
+ int (*device_shutdown) (struct platform_device *pdev);
+ int (*device_idle) (struct platform_device *pdev);
};
#endif
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index ed5a03cbe184..6042228954a7 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -122,6 +122,7 @@
/* U-APSD queue for WMM IEs sent by AP */
#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
+#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
/* U-APSD queues for WMM IEs sent by STA */
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0)
@@ -535,7 +536,6 @@ struct ieee80211s_hdr {
__le32 seqnum;
u8 eaddr1[6];
u8 eaddr2[6];
- u8 eaddr3[6];
} __attribute__ ((packed));
/* Mesh flags */
@@ -1223,6 +1223,9 @@ enum ieee80211_eid {
WLAN_EID_BSS_AC_ACCESS_DELAY = 68,
WLAN_EID_RRM_ENABLED_CAPABILITIES = 70,
WLAN_EID_MULTIPLE_BSSID = 71,
+ WLAN_EID_BSS_COEX_2040 = 72,
+ WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74,
+ WLAN_EID_EXT_CAPABILITY = 127,
WLAN_EID_MOBILITY_DOMAIN = 54,
WLAN_EID_FAST_BSS_TRANSITION = 55,
@@ -1287,6 +1290,31 @@ enum ieee80211_key_len {
WLAN_KEY_LEN_AES_CMAC = 16,
};
+/**
+ * enum - mesh path selection protocol identifier
+ *
+ * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
+ * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
+ * be specified in a vendor specific information element
+ */
+enum {
+ IEEE80211_PATH_PROTOCOL_HWMP = 0,
+ IEEE80211_PATH_PROTOCOL_VENDOR = 255,
+};
+
+/**
+ * enum - mesh path selection metric identifier
+ *
+ * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
+ * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
+ * specified in a vendor specific information element
+ */
+enum {
+ IEEE80211_PATH_METRIC_AIRTIME = 0,
+ IEEE80211_PATH_METRIC_VENDOR = 255,
+};
+
+
/*
* IEEE 802.11-2007 7.3.2.9 Country information element
*
diff --git a/include/linux/if_alg.h b/include/linux/if_alg.h
new file mode 100644
index 000000000000..0f9acce5b1ff
--- /dev/null
+++ b/include/linux/if_alg.h
@@ -0,0 +1,40 @@
+/*
+ * if_alg: User-space algorithm interface
+ *
+ * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#ifndef _LINUX_IF_ALG_H
+#define _LINUX_IF_ALG_H
+
+#include <linux/types.h>
+
+struct sockaddr_alg {
+ __u16 salg_family;
+ __u8 salg_type[14];
+ __u32 salg_feat;
+ __u32 salg_mask;
+ __u8 salg_name[64];
+};
+
+struct af_alg_iv {
+ __u32 ivlen;
+ __u8 iv[0];
+};
+
+/* Socket options */
+#define ALG_SET_KEY 1
+#define ALG_SET_IV 2
+#define ALG_SET_OP 3
+
+/* Operations */
+#define ALG_OP_DECRYPT 0
+#define ALG_OP_ENCRYPT 1
+
+#endif /* _LINUX_IF_ALG_H */
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 0d241a5c4909..f7e73c338c40 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -102,7 +102,9 @@ struct __fdb_entry {
#include <linux/netdevice.h>
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
-extern int (*br_should_route_hook)(struct sk_buff *skb);
+
+typedef int (*br_should_route_hook_t)(struct sk_buff *skb);
+extern br_should_route_hook_t __rcu *br_should_route_hook;
#endif
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 2fc66dd783ee..6485d2a89bec 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -80,6 +80,24 @@ struct rtnl_link_ifmap {
__u8 port;
};
+/*
+ * IFLA_AF_SPEC
+ * Contains nested attributes for address family specific attributes.
+ * Each address family may create a attribute with the address family
+ * number as type and create its own attribute structure in it.
+ *
+ * Example:
+ * [IFLA_AF_SPEC] = {
+ * [AF_INET] = {
+ * [IFLA_INET_CONF] = ...,
+ * },
+ * [AF_INET6] = {
+ * [IFLA_INET6_FLAGS] = ...,
+ * [IFLA_INET6_CONF] = ...,
+ * }
+ * }
+ */
+
enum {
IFLA_UNSPEC,
IFLA_ADDRESS,
@@ -116,6 +134,7 @@ enum {
IFLA_STATS64,
IFLA_VF_PORTS,
IFLA_PORT_SELF,
+ IFLA_AF_SPEC,
__IFLA_MAX
};
@@ -128,6 +147,14 @@ enum {
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
#endif
+enum {
+ IFLA_INET_UNSPEC,
+ IFLA_INET_CONF,
+ __IFLA_INET_MAX,
+};
+
+#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
+
/* ifi_flags.
IFF_* flags.
@@ -232,6 +259,7 @@ enum macvlan_mode {
MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
+ MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
};
/* SR-IOV virtual function management section */
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index 8a2fd66a8b5f..e28b2e4959d4 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -25,19 +25,25 @@ struct macvlan_port;
struct macvtap_queue;
/**
- * struct macvlan_rx_stats - MACVLAN percpu rx stats
+ * struct macvlan_pcpu_stats - MACVLAN percpu stats
* @rx_packets: number of received packets
* @rx_bytes: number of received bytes
* @rx_multicast: number of received multicast packets
+ * @tx_packets: number of transmitted packets
+ * @tx_bytes: number of transmitted bytes
* @syncp: synchronization point for 64bit counters
- * @rx_errors: number of errors
+ * @rx_errors: number of rx errors
+ * @tx_dropped: number of tx dropped packets
*/
-struct macvlan_rx_stats {
+struct macvlan_pcpu_stats {
u64 rx_packets;
u64 rx_bytes;
u64 rx_multicast;
+ u64 tx_packets;
+ u64 tx_bytes;
struct u64_stats_sync syncp;
- unsigned long rx_errors;
+ u32 rx_errors;
+ u32 tx_dropped;
};
/*
@@ -52,7 +58,7 @@ struct macvlan_dev {
struct hlist_node hlist;
struct macvlan_port *port;
struct net_device *lowerdev;
- struct macvlan_rx_stats __percpu *rx_stats;
+ struct macvlan_pcpu_stats __percpu *pcpu_stats;
enum macvlan_mode mode;
int (*receive)(struct sk_buff *skb);
int (*forward)(struct net_device *dev, struct sk_buff *skb);
@@ -64,18 +70,18 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
unsigned int len, bool success,
bool multicast)
{
- struct macvlan_rx_stats *rx_stats;
-
- rx_stats = this_cpu_ptr(vlan->rx_stats);
if (likely(success)) {
- u64_stats_update_begin(&rx_stats->syncp);
- rx_stats->rx_packets++;;
- rx_stats->rx_bytes += len;
+ struct macvlan_pcpu_stats *pcpu_stats;
+
+ pcpu_stats = this_cpu_ptr(vlan->pcpu_stats);
+ u64_stats_update_begin(&pcpu_stats->syncp);
+ pcpu_stats->rx_packets++;
+ pcpu_stats->rx_bytes += len;
if (multicast)
- rx_stats->rx_multicast++;
- u64_stats_update_end(&rx_stats->syncp);
+ pcpu_stats->rx_multicast++;
+ u64_stats_update_end(&pcpu_stats->syncp);
} else {
- rx_stats->rx_errors++;
+ this_cpu_inc(vlan->pcpu_stats->rx_errors);
}
}
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 93fc2449af10..74cfcff0148b 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -85,9 +85,9 @@ struct igmpv3_query {
#define IGMP_DVMRP 0x13 /* DVMRP routing */
#define IGMP_PIM 0x14 /* PIM routing */
#define IGMP_TRACE 0x15
-#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x11 */
+#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */
#define IGMP_HOST_LEAVE_MESSAGE 0x17
-#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x11 */
+#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */
#define IGMP_MTRACE_RESP 0x1e
#define IGMP_MTRACE 0x1f
@@ -167,10 +167,10 @@ struct ip_sf_socklist {
*/
struct ip_mc_socklist {
- struct ip_mc_socklist *next;
+ struct ip_mc_socklist __rcu *next_rcu;
struct ip_mreqn multi;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
- struct ip_sf_socklist *sflist;
+ struct ip_sf_socklist __rcu *sflist;
struct rcu_head rcu;
};
@@ -186,11 +186,14 @@ struct ip_sf_list {
struct ip_mc_list {
struct in_device *interface;
__be32 multiaddr;
+ unsigned int sfmode;
struct ip_sf_list *sources;
struct ip_sf_list *tomb;
- unsigned int sfmode;
unsigned long sfcount[2];
- struct ip_mc_list *next;
+ union {
+ struct ip_mc_list *next;
+ struct ip_mc_list __rcu *next_rcu;
+ };
struct timer_list timer;
int users;
atomic_t refcnt;
@@ -201,6 +204,7 @@ struct ip_mc_list {
char loaded;
unsigned char gsquery; /* check source marks? */
unsigned char crcount;
+ struct rcu_head rcu;
};
/* V3 exponential field decoding */
@@ -234,7 +238,7 @@ extern void ip_mc_unmap(struct in_device *);
extern void ip_mc_remap(struct in_device *);
extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
-extern void ip_mc_rejoin_group(struct ip_mc_list *im);
+extern void ip_mc_rejoin_groups(struct in_device *in_dev);
#endif
#endif
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index ccd5b07d678d..ae8fdc54e0c0 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -41,10 +41,12 @@ enum
__IPV4_DEVCONF_MAX
};
+#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
+
struct ipv4_devconf {
void *sysctl;
- int data[__IPV4_DEVCONF_MAX - 1];
- DECLARE_BITMAP(state, __IPV4_DEVCONF_MAX - 1);
+ int data[IPV4_DEVCONF_MAX];
+ DECLARE_BITMAP(state, IPV4_DEVCONF_MAX);
};
struct in_device {
@@ -52,9 +54,8 @@ struct in_device {
atomic_t refcnt;
int dead;
struct in_ifaddr *ifa_list; /* IP ifaddr chain */
- rwlock_t mc_list_lock;
- struct ip_mc_list *mc_list; /* IP multicast filter chain */
- int mc_count; /* Number of installed mcasts */
+ struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */
+ int mc_count; /* Number of installed mcasts */
spinlock_t mc_tomb_lock;
struct ip_mc_list *mc_tomb;
unsigned long mr_v1_seen;
@@ -91,7 +92,7 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
- bitmap_fill(in_dev->cnf.state, __IPV4_DEVCONF_MAX - 1);
+ bitmap_fill(in_dev->cnf.state, IPV4_DEVCONF_MAX);
}
#define IN_DEV_CONF_GET(in_dev, attr) \
@@ -221,7 +222,7 @@ static inline struct in_device *in_dev_get(const struct net_device *dev)
static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
{
- return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
+ return rtnl_dereference(dev->ip_ptr);
}
extern void in_dev_finish_destroy(struct in_device *idev);
diff --git a/include/linux/input.h b/include/linux/input.h
index 6ef44465db8d..c4e9d91ec979 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -47,6 +47,25 @@ struct input_id {
__u16 version;
};
+/**
+ * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
+ * @value: latest reported value for the axis.
+ * @minimum: specifies minimum value for the axis.
+ * @maximum: specifies maximum value for the axis.
+ * @fuzz: specifies fuzz value that is used to filter noise from
+ * the event stream.
+ * @flat: values that are within this value will be discarded by
+ * joydev interface and reported as 0 instead.
+ * @resolution: specifies resolution for the values reported for
+ * the axis.
+ *
+ * Note that input core does not clamp reported values to the
+ * [minimum, maximum] limits, such task is left to userspace.
+ *
+ * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
+ * units per millimeter (units/mm), resolution for rotational axes
+ * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
+ */
struct input_absinfo {
__s32 value;
__s32 minimum;
@@ -85,12 +104,15 @@ struct input_keymap_entry {
#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, struct input_keymap_entry) /* get keycode */
-#define EVIOCSKEYCODE _IOW('E', 0x04, struct input_keymap_entry) /* set keycode */
+#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
+#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
+#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
+#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
+#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
@@ -108,6 +130,18 @@ struct input_keymap_entry {
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
+#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
+#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
+
+#define INPUT_PROP_MAX 0x1f
+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
+
+/*
* Event types
*/
@@ -569,6 +603,8 @@ struct input_keymap_entry {
#define KEY_FRAMEFORWARD 0x1b5
#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
+#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
#define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1
@@ -624,6 +660,10 @@ struct input_keymap_entry {
#define KEY_CAMERA_FOCUS 0x210
#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
+#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON 0x213
+#define KEY_TOUCHPAD_OFF 0x214
+
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
@@ -733,11 +773,12 @@ struct input_keymap_entry {
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
+#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
#ifdef __KERNEL__
/* Implementation details, userspace should not care about these */
#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR
-#define ABS_MT_LAST ABS_MT_PRESSURE
+#define ABS_MT_LAST ABS_MT_DISTANCE
#endif
#define ABS_MAX 0x3f
@@ -848,6 +889,7 @@ struct input_keymap_entry {
*/
#define MT_TOOL_FINGER 0
#define MT_TOOL_PEN 1
+#define MT_TOOL_MAX 1
/*
* Values describing the status of a force-feedback effect
@@ -1083,19 +1125,12 @@ struct ff_effect {
#include <linux/mod_devicetable.h>
/**
- * struct input_mt_slot - represents the state of an input MT slot
- * @abs: holds current values of ABS_MT axes for this slot
- */
-struct input_mt_slot {
- int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
-};
-
-/**
* struct input_dev - represents an input device
* @name: name of the device
* @phys: physical path to the device in the system hierarchy
* @uniq: unique identification code for the device (if device has it)
* @id: id of the device (struct input_id)
+ * @propbit: bitmap of device properties and quirks
* @evbit: bitmap of types of events supported by the device (EV_KEY,
* EV_REL, etc.)
* @keybit: bitmap of keys/buttons this device has
@@ -1130,7 +1165,8 @@ struct input_mt_slot {
* of tracked contacts
* @mtsize: number of MT slots the device uses
* @slot: MT slot currently being transmitted
- * @absinfo: array of &struct absinfo elements holding information
+ * @trkid: stores MT tracking ID for the current contact
+ * @absinfo: array of &struct input_absinfo elements holding information
* about absolute axes (current value, min, max, flat, fuzz,
* resolution)
* @key: reflects current state of device's keys/buttons
@@ -1178,6 +1214,8 @@ struct input_dev {
const char *uniq;
struct input_id id;
+ unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
+
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
@@ -1214,6 +1252,7 @@ struct input_dev {
struct input_mt_slot *mt;
int mtsize;
int slot;
+ int trkid;
struct input_absinfo *absinfo;
@@ -1463,11 +1502,6 @@ static inline void input_mt_sync(struct input_dev *dev)
input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
}
-static inline void input_mt_slot(struct input_dev *dev, int slot)
-{
- input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
-}
-
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
/**
@@ -1580,8 +1614,5 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
int input_ff_create_memless(struct input_dev *dev, void *data,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
-void input_mt_destroy_slots(struct input_dev *dev);
-
#endif
#endif
diff --git a/include/linux/input/cma3000.h b/include/linux/input/cma3000.h
new file mode 100644
index 000000000000..cbbaac27d311
--- /dev/null
+++ b/include/linux/input/cma3000.h
@@ -0,0 +1,59 @@
+/*
+ * VTI CMA3000_Dxx Accelerometer driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ * Author: Hemanth V <hemanthv@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LINUX_CMA3000_H
+#define _LINUX_CMA3000_H
+
+#define CMAMODE_DEFAULT 0
+#define CMAMODE_MEAS100 1
+#define CMAMODE_MEAS400 2
+#define CMAMODE_MEAS40 3
+#define CMAMODE_MOTDET 4
+#define CMAMODE_FF100 5
+#define CMAMODE_FF400 6
+#define CMAMODE_POFF 7
+
+#define CMARANGE_2G 2000
+#define CMARANGE_8G 8000
+
+/**
+ * struct cma3000_i2c_platform_data - CMA3000 Platform data
+ * @fuzz_x: Noise on X Axis
+ * @fuzz_y: Noise on Y Axis
+ * @fuzz_z: Noise on Z Axis
+ * @g_range: G range in milli g i.e 2000 or 8000
+ * @mode: Operating mode
+ * @mdthr: Motion detect threshold value
+ * @mdfftmr: Motion detect and free fall time value
+ * @ffthr: Free fall threshold value
+ */
+
+struct cma3000_platform_data {
+ int fuzz_x;
+ int fuzz_y;
+ int fuzz_z;
+ int g_range;
+ uint8_t mode;
+ uint8_t mdthr;
+ uint8_t mdfftmr;
+ uint8_t ffthr;
+ unsigned long irqflags;
+};
+
+#endif
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 80352ad6581a..697474691749 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -9,7 +9,7 @@
#define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
(((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
- (val & 0xffff))
+ ((val) & 0xffff))
#define KEY_ROW(k) (((k) >> 24) & 0xff)
#define KEY_COL(k) (((k) >> 16) & 0xff)
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
new file mode 100644
index 000000000000..b3ac06a4435d
--- /dev/null
+++ b/include/linux/input/mt.h
@@ -0,0 +1,57 @@
+#ifndef _INPUT_MT_H
+#define _INPUT_MT_H
+
+/*
+ * Input Multitouch Library
+ *
+ * Copyright (c) 2010 Henrik Rydberg
+ *
+ * This program is free software; you can 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/input.h>
+
+#define TRKID_MAX 0xffff
+
+/**
+ * struct input_mt_slot - represents the state of an input MT slot
+ * @abs: holds current values of ABS_MT axes for this slot
+ */
+struct input_mt_slot {
+ int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
+};
+
+static inline void input_mt_set_value(struct input_mt_slot *slot,
+ unsigned code, int value)
+{
+ slot->abs[code - ABS_MT_FIRST] = value;
+}
+
+static inline int input_mt_get_value(const struct input_mt_slot *slot,
+ unsigned code)
+{
+ return slot->abs[code - ABS_MT_FIRST];
+}
+
+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
+void input_mt_destroy_slots(struct input_dev *dev);
+
+static inline int input_mt_new_trkid(struct input_dev *dev)
+{
+ return dev->trkid++ & TRKID_MAX;
+}
+
+static inline void input_mt_slot(struct input_dev *dev, int slot)
+{
+ input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
+}
+
+void input_mt_report_slot_state(struct input_dev *dev,
+ unsigned int tool_type, bool active);
+
+void input_mt_report_finger_count(struct input_dev *dev, int count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
+
+#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index d377ea815d45..e9bb22cba764 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -112,7 +112,6 @@ struct resource_list {
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource;
extern struct resource iomem_resource;
-extern int resource_alloc_from_bottom;
extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
extern int request_resource(struct resource *root, struct resource *new);
@@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root,
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 void arch_remove_reservations(struct resource *avail);
extern int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
resource_size_t max, resource_size_t align,
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 65aae34759de..045f2f275cd0 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -454,6 +454,44 @@ unsigned int ipmi_addr_length(int addr_type);
/* Validate that the given IPMI address is valid. */
int ipmi_validate_addr(struct ipmi_addr *addr, int len);
+/*
+ * How did the IPMI driver find out about the device?
+ */
+enum ipmi_addr_src {
+ SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
+ SI_PCI, SI_DEVICETREE, SI_DEFAULT
+};
+
+union ipmi_smi_info_union {
+ /*
+ * the acpi_info element is defined for the SI_ACPI
+ * address type
+ */
+ struct {
+ void *acpi_handle;
+ } acpi_info;
+};
+
+struct ipmi_smi_info {
+ enum ipmi_addr_src addr_src;
+
+ /*
+ * Base device for the interface. Don't forget to put this when
+ * you are done.
+ */
+ struct device *dev;
+
+ /*
+ * The addr_info provides more detailed info for some IPMI
+ * devices, depending on the addr_src. Currently only SI_ACPI
+ * info is provided.
+ */
+ union ipmi_smi_info_union addr_info;
+};
+
+/* This is to get the private info of ipmi_smi_t */
+extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data);
+
#endif /* __KERNEL__ */
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 4b48318ac542..906590aa6907 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -39,6 +39,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/ipmi.h>
/* This files describes the interface for IPMI system management interface
drivers to bind into the IPMI message handler. */
@@ -86,6 +87,13 @@ struct ipmi_smi_handlers {
int (*start_processing)(void *send_info,
ipmi_smi_t new_intf);
+ /*
+ * Get the detailed private info of the low level interface and store
+ * it into the structure of ipmi_smi_data. For example: the
+ * ACPI device handle will be returned for the pnp_acpi IPMI device.
+ */
+ int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);
+
/* Called to enqueue an SMI message to be sent. This
operation is not allowed to fail. If an error occurs, it
should report back the error in a received message. It may
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 8e429d0e0405..0c997767429a 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -364,7 +364,7 @@ struct ipv6_pinfo {
__u32 dst_cookie;
- struct ipv6_mc_socklist *ipv6_mc_list;
+ struct ipv6_mc_socklist __rcu *ipv6_mc_list;
struct ipv6_ac_socklist *ipv6_ac_list;
struct ipv6_fl_socklist *ipv6_fl_list;
diff --git a/include/linux/jhash.h b/include/linux/jhash.h
index ced1159fa4f2..47cb09edec1a 100644
--- a/include/linux/jhash.h
+++ b/include/linux/jhash.h
@@ -3,129 +3,156 @@
/* jhash.h: Jenkins hash support.
*
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
*
* http://burtleburtle.net/bob/hash/
*
* These are the credits from Bob's sources:
*
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose. It has no warranty.
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
*
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions. Routines to test the hash are included
+ * if SELF_TEST is defined. You can use this free for any purpose. It's in
+ * the public domain. It has no warranty.
+ *
+ * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
*
* I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault. -DaveM
+ * any bugs present are my fault.
+ * Jozsef
*/
+#include <linux/bitops.h>
+#include <linux/unaligned/packed_struct.h>
+
+/* Best hash sizes are of power of two */
+#define jhash_size(n) ((u32)1<<(n))
+/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */
+#define jhash_mask(n) (jhash_size(n)-1)
+
+/* __jhash_mix -- mix 3 32-bit values reversibly. */
+#define __jhash_mix(a, b, c) \
+{ \
+ a -= c; a ^= rol32(c, 4); c += b; \
+ b -= a; b ^= rol32(a, 6); a += c; \
+ c -= b; c ^= rol32(b, 8); b += a; \
+ a -= c; a ^= rol32(c, 16); c += b; \
+ b -= a; b ^= rol32(a, 19); a += c; \
+ c -= b; c ^= rol32(b, 4); b += a; \
+}
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
-{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a, b, c) \
+{ \
+ c ^= b; c -= rol32(b, 14); \
+ a ^= c; a -= rol32(c, 11); \
+ b ^= a; b -= rol32(a, 25); \
+ c ^= b; c -= rol32(b, 16); \
+ a ^= c; a -= rol32(c, 4); \
+ b ^= a; b -= rol32(a, 14); \
+ c ^= b; c -= rol32(b, 24); \
}
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO 0x9e3779b9
+/* An arbitrary initial parameter */
+#define JHASH_INITVAL 0xdeadbeef
-/* The most generic version, hashes an arbitrary sequence
- * of bytes. No alignment or length assumptions are made about
- * the input key.
+/* jhash - hash an arbitrary key
+ * @k: sequence of bytes as key
+ * @length: the length of the key
+ * @initval: the previous hash, or an arbitray value
+ *
+ * The generic version, hashes an arbitrary sequence of bytes.
+ * No alignment or length assumptions are made about the input key.
+ *
+ * Returns the hash value of the key. The result depends on endianness.
*/
static inline u32 jhash(const void *key, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a, b, c;
const u8 *k = key;
- len = length;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
-
- while (len >= 12) {
- a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
- b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
- c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
-
- __jhash_mix(a,b,c);
+ /* Set up the internal state */
+ a = b = c = JHASH_INITVAL + length + initval;
+ /* All but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += __get_unaligned_cpu32(k);
+ b += __get_unaligned_cpu32(k + 4);
+ c += __get_unaligned_cpu32(k + 8);
+ __jhash_mix(a, b, c);
+ length -= 12;
k += 12;
- len -= 12;
}
-
- c += length;
- switch (len) {
- case 11: c += ((u32)k[10]<<24);
- case 10: c += ((u32)k[9]<<16);
- case 9 : c += ((u32)k[8]<<8);
- case 8 : b += ((u32)k[7]<<24);
- case 7 : b += ((u32)k[6]<<16);
- case 6 : b += ((u32)k[5]<<8);
- case 5 : b += k[4];
- case 4 : a += ((u32)k[3]<<24);
- case 3 : a += ((u32)k[2]<<16);
- case 2 : a += ((u32)k[1]<<8);
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ /* Last block: affect all 32 bits of (c) */
+ /* All the case statements fall through */
+ switch (length) {
+ case 12: c += (u32)k[11]<<24;
+ case 11: c += (u32)k[10]<<16;
+ case 10: c += (u32)k[9]<<8;
+ case 9: c += k[8];
+ case 8: b += (u32)k[7]<<24;
+ case 7: b += (u32)k[6]<<16;
+ case 6: b += (u32)k[5]<<8;
+ case 5: b += k[4];
+ case 4: a += (u32)k[3]<<24;
+ case 3: a += (u32)k[2]<<16;
+ case 2: a += (u32)k[1]<<8;
+ case 1: a += k[0];
+ __jhash_final(a, b, c);
+ case 0: /* Nothing left to add */
+ break;
+ }
return c;
}
-/* A special optimized version that handles 1 or more of u32s.
- * The length parameter here is the number of u32s in the key.
+/* jhash2 - hash an array of u32's
+ * @k: the key which must be an array of u32's
+ * @length: the number of u32's in the key
+ * @initval: the previous hash, or an arbitray value
+ *
+ * Returns the hash value of the key.
*/
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a, b, c;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
- len = length;
+ /* Set up the internal state */
+ a = b = c = JHASH_INITVAL + (length<<2) + initval;
- while (len >= 3) {
+ /* Handle most of the key */
+ while (length > 3) {
a += k[0];
b += k[1];
c += k[2];
__jhash_mix(a, b, c);
- k += 3; len -= 3;
+ length -= 3;
+ k += 3;
}
- c += length * 4;
-
- switch (len) {
- case 2 : b += k[1];
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ /* Handle the last 3 u32's: all the case statements fall through */
+ switch (length) {
+ case 3: c += k[2];
+ case 2: b += k[1];
+ case 1: a += k[0];
+ __jhash_final(a, b, c);
+ case 0: /* Nothing left to add */
+ break;
+ }
return c;
}
-/* A special ultra-optimized versions that knows they are hashing exactly
- * 3, 2 or 1 word(s).
- *
- * NOTE: In particular the "c += length; __jhash_mix(a,b,c);" normally
- * done at the end is not done here.
- */
+/* jhash_3words - hash exactly 3, 2 or 1 word(s) */
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
+ a += JHASH_INITVAL;
+ b += JHASH_INITVAL;
c += initval;
- __jhash_mix(a, b, c);
+ __jhash_final(a, b, c);
return c;
}
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 685ea65eb803..ce0775aa64c3 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -81,16 +81,41 @@ struct kthread_work {
#define DEFINE_KTHREAD_WORK(work, fn) \
struct kthread_work work = KTHREAD_WORK_INIT(work, fn)
-static inline void init_kthread_worker(struct kthread_worker *worker)
-{
- *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker);
-}
-
-static inline void init_kthread_work(struct kthread_work *work,
- kthread_work_func_t fn)
-{
- *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn);
-}
+/*
+ * kthread_worker.lock and kthread_work.done need their own lockdep class
+ * keys if they are defined on stack with lockdep enabled. Use the
+ * following macros when defining them on stack.
+ */
+#ifdef CONFIG_LOCKDEP
+# define KTHREAD_WORKER_INIT_ONSTACK(worker) \
+ ({ init_kthread_worker(&worker); worker; })
+# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) \
+ struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker)
+# define KTHREAD_WORK_INIT_ONSTACK(work, fn) \
+ ({ init_kthread_work((&work), fn); work; })
+# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) \
+ struct kthread_work work = KTHREAD_WORK_INIT_ONSTACK(work, fn)
+#else
+# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker)
+# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) DEFINE_KTHREAD_WORK(work, fn)
+#endif
+
+extern void __init_kthread_worker(struct kthread_worker *worker,
+ const char *name, struct lock_class_key *key);
+
+#define init_kthread_worker(worker) \
+ do { \
+ static struct lock_class_key __key; \
+ __init_kthread_worker((worker), "("#worker")->lock", &__key); \
+ } while (0)
+
+#define init_kthread_work(work, fn) \
+ do { \
+ memset((work), 0, sizeof(struct kthread_work)); \
+ INIT_LIST_HEAD(&(work)->node); \
+ (work)->func = (fn); \
+ init_waitqueue_head(&(work)->done); \
+ } while (0)
int kthread_worker_fn(void *worker_ptr);
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 919ae53adc5c..ea2dc1a2e13d 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -540,6 +540,7 @@ struct kvm_ppc_pvinfo {
#endif
#define KVM_CAP_PPC_GET_PVINFO 57
#define KVM_CAP_PPC_IRQ_LEVEL 58
+#define KVM_CAP_ASYNC_PF 59
#ifdef KVM_CAP_IRQ_ROUTING
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a0557422715e..b5021db21858 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -16,6 +16,8 @@
#include <linux/mm.h>
#include <linux/preempt.h>
#include <linux/msi.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
#include <asm/signal.h>
#include <linux/kvm.h>
@@ -40,6 +42,7 @@
#define KVM_REQ_KICK 9
#define KVM_REQ_DEACTIVATE_FPU 10
#define KVM_REQ_EVENT 11
+#define KVM_REQ_APF_HALT 12
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
@@ -74,6 +77,27 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
struct kvm_io_device *dev);
+#ifdef CONFIG_KVM_ASYNC_PF
+struct kvm_async_pf {
+ struct work_struct work;
+ struct list_head link;
+ struct list_head queue;
+ struct kvm_vcpu *vcpu;
+ struct mm_struct *mm;
+ gva_t gva;
+ unsigned long addr;
+ struct kvm_arch_async_pf arch;
+ struct page *page;
+ bool done;
+};
+
+void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu);
+void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu);
+int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
+ struct kvm_arch_async_pf *arch);
+int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu);
+#endif
+
struct kvm_vcpu {
struct kvm *kvm;
#ifdef CONFIG_PREEMPT_NOTIFIERS
@@ -104,6 +128,15 @@ struct kvm_vcpu {
gpa_t mmio_phys_addr;
#endif
+#ifdef CONFIG_KVM_ASYNC_PF
+ struct {
+ u32 queued;
+ struct list_head queue;
+ struct list_head done;
+ spinlock_t lock;
+ } async_pf;
+#endif
+
struct kvm_vcpu_arch arch;
};
@@ -113,16 +146,19 @@ struct kvm_vcpu {
*/
#define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1)
+struct kvm_lpage_info {
+ unsigned long rmap_pde;
+ int write_count;
+};
+
struct kvm_memory_slot {
gfn_t base_gfn;
unsigned long npages;
unsigned long flags;
unsigned long *rmap;
unsigned long *dirty_bitmap;
- struct {
- unsigned long rmap_pde;
- int write_count;
- } *lpage_info[KVM_NR_PAGE_SIZES - 1];
+ unsigned long *dirty_bitmap_head;
+ struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
unsigned long userspace_addr;
int user_alloc;
int id;
@@ -169,6 +205,7 @@ struct kvm_irq_routing_table {};
struct kvm_memslots {
int nmemslots;
+ u64 generation;
struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
KVM_PRIVATE_MEM_SLOTS];
};
@@ -206,6 +243,10 @@ struct kvm {
struct mutex irq_lock;
#ifdef CONFIG_HAVE_KVM_IRQCHIP
+ /*
+ * Update side is protected by irq_lock and,
+ * if configured, irqfds.lock.
+ */
struct kvm_irq_routing_table __rcu *irq_routing;
struct hlist_head mask_notifier_list;
struct hlist_head irq_ack_notifier_list;
@@ -216,6 +257,7 @@ struct kvm {
unsigned long mmu_notifier_seq;
long mmu_notifier_count;
#endif
+ long tlbs_dirty;
};
/* The guest did something we don't support. */
@@ -302,7 +344,11 @@ void kvm_set_page_accessed(struct page *page);
pfn_t hva_to_pfn_atomic(struct kvm *kvm, unsigned long addr);
pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn);
+pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
+ bool write_fault, bool *writable);
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn);
+pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
+ bool *writable);
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);
@@ -321,18 +367,25 @@ int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data,
int offset, int len);
int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
unsigned long len);
+int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ void *data, unsigned long len);
+int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ gpa_t gpa);
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 mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
+ gfn_t gfn);
void kvm_vcpu_block(struct kvm_vcpu *vcpu);
void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu);
void kvm_resched(struct kvm_vcpu *vcpu);
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
+
void kvm_flush_remote_tlbs(struct kvm *kvm);
void kvm_reload_remote_mmus(struct kvm *kvm);
@@ -398,7 +451,19 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
void kvm_free_physmem(struct kvm *kvm);
-struct kvm *kvm_arch_create_vm(void);
+#ifndef __KVM_HAVE_ARCH_VM_ALLOC
+static inline struct kvm *kvm_arch_alloc_vm(void)
+{
+ return kzalloc(sizeof(struct kvm), GFP_KERNEL);
+}
+
+static inline void kvm_arch_free_vm(struct kvm *kvm)
+{
+ kfree(kvm);
+}
+#endif
+
+int kvm_arch_init_vm(struct kvm *kvm);
void kvm_arch_destroy_vm(struct kvm *kvm);
void kvm_free_all_assigned_devices(struct kvm *kvm);
void kvm_arch_sync_events(struct kvm *kvm);
@@ -414,16 +479,8 @@ struct kvm_irq_ack_notifier {
void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
};
-#define KVM_ASSIGNED_MSIX_PENDING 0x1
-struct kvm_guest_msix_entry {
- u32 vector;
- u16 entry;
- u16 flags;
-};
-
struct kvm_assigned_dev_kernel {
struct kvm_irq_ack_notifier ack_notifier;
- struct work_struct interrupt_work;
struct list_head list;
int assigned_dev_id;
int host_segnr;
@@ -434,13 +491,14 @@ struct kvm_assigned_dev_kernel {
bool host_irq_disabled;
struct msix_entry *host_msix_entries;
int guest_irq;
- struct kvm_guest_msix_entry *guest_msix_entries;
+ struct msix_entry *guest_msix_entries;
unsigned long irq_requested_type;
int irq_source_id;
int flags;
struct pci_dev *dev;
struct kvm *kvm;
- spinlock_t assigned_dev_lock;
+ spinlock_t intx_lock;
+ char irq_name[32];
};
struct kvm_irq_mask_notifier {
@@ -462,6 +520,8 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
unsigned long *deliver_bitmask);
#endif
int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level);
+int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
+ int irq_source_id, int level);
void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
void kvm_register_irq_ack_notifier(struct kvm *kvm,
struct kvm_irq_ack_notifier *kian);
@@ -603,17 +663,28 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {}
void kvm_eventfd_init(struct kvm *kvm);
int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags);
void kvm_irqfd_release(struct kvm *kvm);
+void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *);
int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
#else
static inline void kvm_eventfd_init(struct kvm *kvm) {}
+
static inline int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags)
{
return -EINVAL;
}
static inline void kvm_irqfd_release(struct kvm *kvm) {}
+
+#ifdef CONFIG_HAVE_KVM_IRQCHIP
+static inline void kvm_irq_routing_update(struct kvm *kvm,
+ struct kvm_irq_routing_table *irq_rt)
+{
+ rcu_assign_pointer(kvm->irq_routing, irq_rt);
+}
+#endif
+
static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
return -ENOSYS;
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index 7ac0d4eee430..fa7cc7244cbd 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -67,4 +67,11 @@ struct kvm_lapic_irq {
u32 dest_id;
};
+struct gfn_to_hva_cache {
+ u64 generation;
+ gpa_t gpa;
+ unsigned long hva;
+ struct kvm_memory_slot *memslot;
+};
+
#endif /* __KVM_TYPES_H__ */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d947b1231662..c9c5d7ad1a2b 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -996,8 +996,7 @@ extern int ata_sas_port_init(struct ata_port *);
extern int ata_sas_port_start(struct ata_port *ap);
extern void ata_sas_port_stop(struct ata_port *ap);
extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
-extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
- struct ata_port *ap);
+extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap);
extern int sata_scr_valid(struct ata_link *link);
extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
@@ -1040,8 +1039,7 @@ extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id);
extern void ata_qc_complete(struct ata_queued_cmd *qc);
extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active);
-extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *));
+extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd);
extern int ata_std_bios_param(struct scsi_device *sdev,
struct block_device *bdev,
sector_t capacity, int geom[]);
diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h
new file mode 100644
index 000000000000..c2034b93a4e6
--- /dev/null
+++ b/include/linux/list_bl.h
@@ -0,0 +1,141 @@
+#ifndef _LINUX_LIST_BL_H
+#define _LINUX_LIST_BL_H
+
+#include <linux/list.h>
+#include <linux/bit_spinlock.h>
+
+/*
+ * Special version of lists, where head of the list has a bit spinlock
+ * in the lowest bit. This is useful for scalable hash tables without
+ * increasing memory footprint overhead.
+ *
+ * For modification operations, the 0 bit of hlist_bl_head->first
+ * pointer must be set.
+ */
+
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#define LIST_BL_LOCKMASK 1UL
+#else
+#define LIST_BL_LOCKMASK 0UL
+#endif
+
+#ifdef CONFIG_DEBUG_LIST
+#define LIST_BL_BUG_ON(x) BUG_ON(x)
+#else
+#define LIST_BL_BUG_ON(x)
+#endif
+
+
+struct hlist_bl_head {
+ struct hlist_bl_node *first;
+};
+
+struct hlist_bl_node {
+ struct hlist_bl_node *next, **pprev;
+};
+#define INIT_HLIST_BL_HEAD(ptr) \
+ ((ptr)->first = NULL)
+
+static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h)
+{
+ h->next = NULL;
+ h->pprev = NULL;
+}
+
+#define hlist_bl_entry(ptr, type, member) container_of(ptr,type,member)
+
+static inline int hlist_bl_unhashed(const struct hlist_bl_node *h)
+{
+ return !h->pprev;
+}
+
+static inline struct hlist_bl_node *hlist_bl_first(struct hlist_bl_head *h)
+{
+ return (struct hlist_bl_node *)
+ ((unsigned long)h->first & ~LIST_BL_LOCKMASK);
+}
+
+static inline void hlist_bl_set_first(struct hlist_bl_head *h,
+ struct hlist_bl_node *n)
+{
+ LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
+ LIST_BL_BUG_ON(!bit_spin_is_locked(0, (unsigned long *)&h->first));
+ h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK);
+}
+
+static inline int hlist_bl_empty(const struct hlist_bl_head *h)
+{
+ return !((unsigned long)h->first & ~LIST_BL_LOCKMASK);
+}
+
+static inline void hlist_bl_add_head(struct hlist_bl_node *n,
+ struct hlist_bl_head *h)
+{
+ struct hlist_bl_node *first = hlist_bl_first(h);
+
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ n->pprev = &h->first;
+ hlist_bl_set_first(h, n);
+}
+
+static inline void __hlist_bl_del(struct hlist_bl_node *n)
+{
+ struct hlist_bl_node *next = n->next;
+ struct hlist_bl_node **pprev = n->pprev;
+
+ LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
+
+ /* pprev may be `first`, so be careful not to lose the lock bit */
+ *pprev = (struct hlist_bl_node *)
+ ((unsigned long)next |
+ ((unsigned long)*pprev & LIST_BL_LOCKMASK));
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_bl_del(struct hlist_bl_node *n)
+{
+ __hlist_bl_del(n);
+ n->next = LIST_POISON1;
+ n->pprev = LIST_POISON2;
+}
+
+static inline void hlist_bl_del_init(struct hlist_bl_node *n)
+{
+ if (!hlist_bl_unhashed(n)) {
+ __hlist_bl_del(n);
+ INIT_HLIST_BL_NODE(n);
+ }
+}
+
+/**
+ * hlist_bl_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ *
+ */
+#define hlist_bl_for_each_entry(tpos, pos, head, member) \
+ for (pos = hlist_bl_first(head); \
+ pos && \
+ ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_bl_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @n: another &struct hlist_node to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_bl_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = hlist_bl_first(head); \
+ pos && ({ n = pos->next; 1; }) && \
+ ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = n)
+
+#endif
diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h
index 34b2b7f33c3b..257d3779f2ab 100644
--- a/include/linux/lockd/debug.h
+++ b/include/linux/lockd/debug.h
@@ -44,14 +44,4 @@
#define NLMDBG_XDR 0x0100
#define NLMDBG_ALL 0x7fff
-
-/*
- * Support for printing NLM cookies in dprintk()
- */
-#ifdef RPC_DEBUG
-struct nlm_cookie;
-/* Call this function with the BKL held (it uses a static buffer) */
-extern const char *nlmdbg_cookie2a(const struct nlm_cookie *);
-#endif
-
#endif /* LINUX_LOCKD_DEBUG_H */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 2dee05e5119a..ff9abff55aa0 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -202,9 +202,9 @@ extern u32 nsm_local_state;
* Lockd client functions
*/
struct nlm_rqst * nlm_alloc_call(struct nlm_host *host);
-void nlm_release_call(struct nlm_rqst *);
int nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
+void nlmclnt_release_call(struct nlm_rqst *);
struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl);
void nlmclnt_finish_block(struct nlm_wait *block);
int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
@@ -223,13 +223,14 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
const u32 version,
const char *hostname,
int noresvport);
+void nlmclnt_release_host(struct nlm_host *);
struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
const char *hostname,
const size_t hostname_len);
+void nlmsvc_release_host(struct nlm_host *);
struct rpc_clnt * nlm_bind_host(struct nlm_host *);
void nlm_rebind_host(struct nlm_host *);
struct nlm_host * nlm_get_host(struct nlm_host *);
-void nlm_release_host(struct nlm_host *);
void nlm_shutdown_hosts(void);
void nlm_host_rebooted(const struct nlm_reboot *);
@@ -267,6 +268,7 @@ unsigned long nlmsvc_retry_blocked(void);
void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
nlm_host_match_fn_t match);
void nlmsvc_grant_reply(struct nlm_cookie *, __be32);
+void nlmsvc_release_call(struct nlm_rqst *);
/*
* File handling for the server personality
diff --git a/include/linux/magic.h b/include/linux/magic.h
index ff690d05f129..6cfe344f9559 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -16,6 +16,7 @@
#define TMPFS_MAGIC 0x01021994
#define HUGETLBFS_MAGIC 0x958458f6 /* some random number */
#define SQUASHFS_MAGIC 0x73717368
+#define ECRYPTFS_SUPER_MAGIC 0xf15f
#define EFS_SUPER_MAGIC 0x414A53
#define EXT2_SUPER_MAGIC 0xEF53
#define EXT3_SUPER_MAGIC 0xEF53
@@ -26,6 +27,7 @@
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
#define ANON_INODE_FS_MAGIC 0x09041934
+#define PSTOREFS_MAGIC 0x6165676C
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index c779b49a1fda..b1494aced217 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -55,6 +55,7 @@
#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */
#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */
+#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
#define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */
@@ -235,6 +236,10 @@
#define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */
#define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */
+/* AN EEE Advertisement register. */
+#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */
+#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */
+
/* LASI RX_ALARM control/status registers. */
#define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */
#define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 4307231bd22f..31c237a00c48 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -161,6 +161,9 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
extern void put_page_bootmem(struct page *page);
#endif
+void lock_memory_hotplug(void);
+void unlock_memory_hotplug(void);
+
#else /* ! CONFIG_MEMORY_HOTPLUG */
/*
* Stub functions for when hotplug is off
@@ -192,6 +195,9 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
{
}
+static inline void lock_memory_hotplug(void) {}
+static inline void unlock_memory_hotplug(void) {}
+
#endif /* ! CONFIG_MEMORY_HOTPLUG */
#ifdef CONFIG_MEMORY_HOTREMOVE
diff --git a/include/linux/mfd/tc35892.h b/include/linux/mfd/tc35892.h
deleted file mode 100644
index eff3094ca84e..000000000000
--- a/include/linux/mfd/tc35892.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License Terms: GNU General Public License, version 2
- */
-
-#ifndef __LINUX_MFD_TC35892_H
-#define __LINUX_MFD_TC35892_H
-
-#include <linux/device.h>
-
-#define TC35892_RSTCTRL_IRQRST (1 << 4)
-#define TC35892_RSTCTRL_TIMRST (1 << 3)
-#define TC35892_RSTCTRL_ROTRST (1 << 2)
-#define TC35892_RSTCTRL_KBDRST (1 << 1)
-#define TC35892_RSTCTRL_GPIRST (1 << 0)
-
-#define TC35892_IRQST 0x91
-
-#define TC35892_MANFCODE_MAGIC 0x03
-#define TC35892_MANFCODE 0x80
-#define TC35892_VERSION 0x81
-#define TC35892_IOCFG 0xA7
-
-#define TC35892_CLKMODE 0x88
-#define TC35892_CLKCFG 0x89
-#define TC35892_CLKEN 0x8A
-
-#define TC35892_RSTCTRL 0x82
-#define TC35892_EXTRSTN 0x83
-#define TC35892_RSTINTCLR 0x84
-
-#define TC35892_GPIOIS0 0xC9
-#define TC35892_GPIOIS1 0xCA
-#define TC35892_GPIOIS2 0xCB
-#define TC35892_GPIOIBE0 0xCC
-#define TC35892_GPIOIBE1 0xCD
-#define TC35892_GPIOIBE2 0xCE
-#define TC35892_GPIOIEV0 0xCF
-#define TC35892_GPIOIEV1 0xD0
-#define TC35892_GPIOIEV2 0xD1
-#define TC35892_GPIOIE0 0xD2
-#define TC35892_GPIOIE1 0xD3
-#define TC35892_GPIOIE2 0xD4
-#define TC35892_GPIORIS0 0xD6
-#define TC35892_GPIORIS1 0xD7
-#define TC35892_GPIORIS2 0xD8
-#define TC35892_GPIOMIS0 0xD9
-#define TC35892_GPIOMIS1 0xDA
-#define TC35892_GPIOMIS2 0xDB
-#define TC35892_GPIOIC0 0xDC
-#define TC35892_GPIOIC1 0xDD
-#define TC35892_GPIOIC2 0xDE
-
-#define TC35892_GPIODATA0 0xC0
-#define TC35892_GPIOMASK0 0xc1
-#define TC35892_GPIODATA1 0xC2
-#define TC35892_GPIOMASK1 0xc3
-#define TC35892_GPIODATA2 0xC4
-#define TC35892_GPIOMASK2 0xC5
-
-#define TC35892_GPIODIR0 0xC6
-#define TC35892_GPIODIR1 0xC7
-#define TC35892_GPIODIR2 0xC8
-
-#define TC35892_GPIOSYNC0 0xE6
-#define TC35892_GPIOSYNC1 0xE7
-#define TC35892_GPIOSYNC2 0xE8
-
-#define TC35892_GPIOWAKE0 0xE9
-#define TC35892_GPIOWAKE1 0xEA
-#define TC35892_GPIOWAKE2 0xEB
-
-#define TC35892_GPIOODM0 0xE0
-#define TC35892_GPIOODE0 0xE1
-#define TC35892_GPIOODM1 0xE2
-#define TC35892_GPIOODE1 0xE3
-#define TC35892_GPIOODM2 0xE4
-#define TC35892_GPIOODE2 0xE5
-
-#define TC35892_INT_GPIIRQ 0
-#define TC35892_INT_TI0IRQ 1
-#define TC35892_INT_TI1IRQ 2
-#define TC35892_INT_TI2IRQ 3
-#define TC35892_INT_ROTIRQ 5
-#define TC35892_INT_KBDIRQ 6
-#define TC35892_INT_PORIRQ 7
-
-#define TC35892_NR_INTERNAL_IRQS 8
-#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
-
-struct tc35892 {
- struct mutex lock;
- struct device *dev;
- struct i2c_client *i2c;
-
- int irq_base;
- int num_gpio;
- struct tc35892_platform_data *pdata;
-};
-
-extern int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data);
-extern int tc35892_reg_read(struct tc35892 *tc35892, u8 reg);
-extern int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length,
- u8 *values);
-extern int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length,
- const u8 *values);
-extern int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val);
-
-/**
- * struct tc35892_gpio_platform_data - TC35892 GPIO platform data
- * @gpio_base: first gpio number assigned to TC35892. A maximum of
- * %TC35892_NR_GPIOS GPIOs will be allocated.
- * @setup: callback for board-specific initialization
- * @remove: callback for board-specific teardown
- */
-struct tc35892_gpio_platform_data {
- int gpio_base;
- void (*setup)(struct tc35892 *tc35892, unsigned gpio_base);
- void (*remove)(struct tc35892 *tc35892, unsigned gpio_base);
-};
-
-/**
- * struct tc35892_platform_data - TC35892 platform data
- * @irq_base: base IRQ number. %TC35892_NR_IRQS irqs will be used.
- * @gpio: GPIO-specific platform data
- */
-struct tc35892_platform_data {
- int irq_base;
- struct tc35892_gpio_platform_data *gpio;
-};
-
-#define TC35892_NR_GPIOS 24
-#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
-
-#endif
diff --git a/include/linux/mfd/tc3589x.h b/include/linux/mfd/tc3589x.h
new file mode 100644
index 000000000000..16c76e124f9c
--- /dev/null
+++ b/include/linux/mfd/tc3589x.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License, version 2
+ */
+
+#ifndef __LINUX_MFD_TC3589x_H
+#define __LINUX_MFD_TC3589x_H
+
+#include <linux/device.h>
+
+enum tx3589x_block {
+ TC3589x_BLOCK_GPIO = 1 << 0,
+ TC3589x_BLOCK_KEYPAD = 1 << 1,
+};
+
+#define TC3589x_RSTCTRL_IRQRST (1 << 4)
+#define TC3589x_RSTCTRL_TIMRST (1 << 3)
+#define TC3589x_RSTCTRL_ROTRST (1 << 2)
+#define TC3589x_RSTCTRL_KBDRST (1 << 1)
+#define TC3589x_RSTCTRL_GPIRST (1 << 0)
+
+/* Keyboard Configuration Registers */
+#define TC3589x_KBDSETTLE_REG 0x01
+#define TC3589x_KBDBOUNCE 0x02
+#define TC3589x_KBDSIZE 0x03
+#define TC3589x_KBCFG_LSB 0x04
+#define TC3589x_KBCFG_MSB 0x05
+#define TC3589x_KBDIC 0x08
+#define TC3589x_KBDMSK 0x09
+#define TC3589x_EVTCODE_FIFO 0x10
+#define TC3589x_KBDMFS 0x8F
+
+#define TC3589x_IRQST 0x91
+
+#define TC3589x_MANFCODE_MAGIC 0x03
+#define TC3589x_MANFCODE 0x80
+#define TC3589x_VERSION 0x81
+#define TC3589x_IOCFG 0xA7
+
+#define TC3589x_CLKMODE 0x88
+#define TC3589x_CLKCFG 0x89
+#define TC3589x_CLKEN 0x8A
+
+#define TC3589x_RSTCTRL 0x82
+#define TC3589x_EXTRSTN 0x83
+#define TC3589x_RSTINTCLR 0x84
+
+/* Pull up/down configuration registers */
+#define TC3589x_IOCFG 0xA7
+#define TC3589x_IOPULLCFG0_LSB 0xAA
+#define TC3589x_IOPULLCFG0_MSB 0xAB
+#define TC3589x_IOPULLCFG1_LSB 0xAC
+#define TC3589x_IOPULLCFG1_MSB 0xAD
+#define TC3589x_IOPULLCFG2_LSB 0xAE
+
+#define TC3589x_GPIOIS0 0xC9
+#define TC3589x_GPIOIS1 0xCA
+#define TC3589x_GPIOIS2 0xCB
+#define TC3589x_GPIOIBE0 0xCC
+#define TC3589x_GPIOIBE1 0xCD
+#define TC3589x_GPIOIBE2 0xCE
+#define TC3589x_GPIOIEV0 0xCF
+#define TC3589x_GPIOIEV1 0xD0
+#define TC3589x_GPIOIEV2 0xD1
+#define TC3589x_GPIOIE0 0xD2
+#define TC3589x_GPIOIE1 0xD3
+#define TC3589x_GPIOIE2 0xD4
+#define TC3589x_GPIORIS0 0xD6
+#define TC3589x_GPIORIS1 0xD7
+#define TC3589x_GPIORIS2 0xD8
+#define TC3589x_GPIOMIS0 0xD9
+#define TC3589x_GPIOMIS1 0xDA
+#define TC3589x_GPIOMIS2 0xDB
+#define TC3589x_GPIOIC0 0xDC
+#define TC3589x_GPIOIC1 0xDD
+#define TC3589x_GPIOIC2 0xDE
+
+#define TC3589x_GPIODATA0 0xC0
+#define TC3589x_GPIOMASK0 0xc1
+#define TC3589x_GPIODATA1 0xC2
+#define TC3589x_GPIOMASK1 0xc3
+#define TC3589x_GPIODATA2 0xC4
+#define TC3589x_GPIOMASK2 0xC5
+
+#define TC3589x_GPIODIR0 0xC6
+#define TC3589x_GPIODIR1 0xC7
+#define TC3589x_GPIODIR2 0xC8
+
+#define TC3589x_GPIOSYNC0 0xE6
+#define TC3589x_GPIOSYNC1 0xE7
+#define TC3589x_GPIOSYNC2 0xE8
+
+#define TC3589x_GPIOWAKE0 0xE9
+#define TC3589x_GPIOWAKE1 0xEA
+#define TC3589x_GPIOWAKE2 0xEB
+
+#define TC3589x_GPIOODM0 0xE0
+#define TC3589x_GPIOODE0 0xE1
+#define TC3589x_GPIOODM1 0xE2
+#define TC3589x_GPIOODE1 0xE3
+#define TC3589x_GPIOODM2 0xE4
+#define TC3589x_GPIOODE2 0xE5
+
+#define TC3589x_INT_GPIIRQ 0
+#define TC3589x_INT_TI0IRQ 1
+#define TC3589x_INT_TI1IRQ 2
+#define TC3589x_INT_TI2IRQ 3
+#define TC3589x_INT_ROTIRQ 5
+#define TC3589x_INT_KBDIRQ 6
+#define TC3589x_INT_PORIRQ 7
+
+#define TC3589x_NR_INTERNAL_IRQS 8
+#define TC3589x_INT_GPIO(x) (TC3589x_NR_INTERNAL_IRQS + (x))
+
+struct tc3589x {
+ struct mutex lock;
+ struct device *dev;
+ struct i2c_client *i2c;
+
+ int irq_base;
+ int num_gpio;
+ struct tc3589x_platform_data *pdata;
+};
+
+extern int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data);
+extern int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg);
+extern int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length,
+ u8 *values);
+extern int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length,
+ const u8 *values);
+extern int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val);
+
+/*
+ * Keypad related platform specific constants
+ * These values may be modified for fine tuning
+ */
+#define TC_KPD_ROWS 0x8
+#define TC_KPD_COLUMNS 0x8
+#define TC_KPD_DEBOUNCE_PERIOD 0xA3
+#define TC_KPD_SETTLE_TIME 0xA3
+
+/**
+ * struct tc35893_platform_data - data structure for platform specific data
+ * @keymap_data: matrix scan code table for keycodes
+ * @krow: mask for available rows, value is 0xFF
+ * @kcol: mask for available columns, value is 0xFF
+ * @debounce_period: platform specific debounce time
+ * @settle_time: platform specific settle down time
+ * @irqtype: type of interrupt, falling or rising edge
+ * @enable_wakeup: specifies if keypad event can wake up system from sleep
+ * @no_autorepeat: flag for auto repetition
+ */
+struct tc3589x_keypad_platform_data {
+ const struct matrix_keymap_data *keymap_data;
+ u8 krow;
+ u8 kcol;
+ u8 debounce_period;
+ u8 settle_time;
+ unsigned long irqtype;
+ bool enable_wakeup;
+ bool no_autorepeat;
+};
+
+/**
+ * struct tc3589x_gpio_platform_data - TC3589x GPIO platform data
+ * @gpio_base: first gpio number assigned to TC3589x. A maximum of
+ * %TC3589x_NR_GPIOS GPIOs will be allocated.
+ * @setup: callback for board-specific initialization
+ * @remove: callback for board-specific teardown
+ */
+struct tc3589x_gpio_platform_data {
+ int gpio_base;
+ void (*setup)(struct tc3589x *tc3589x, unsigned gpio_base);
+ void (*remove)(struct tc3589x *tc3589x, unsigned gpio_base);
+};
+
+/**
+ * struct tc3589x_platform_data - TC3589x platform data
+ * @block: bitmask of blocks to enable (use TC3589x_BLOCK_*)
+ * @irq_base: base IRQ number. %TC3589x_NR_IRQS irqs will be used.
+ * @gpio: GPIO-specific platform data
+ * @keypad: keypad-specific platform data
+ */
+struct tc3589x_platform_data {
+ unsigned int block;
+ int irq_base;
+ struct tc3589x_gpio_platform_data *gpio;
+ const struct tc3589x_keypad_platform_data *keypad;
+};
+
+#define TC3589x_NR_GPIOS 24
+#define TC3589x_NR_IRQS TC3589x_INT_GPIO(TC3589x_NR_GPIOS)
+
+#endif
diff --git a/include/linux/mfd/wl1273-core.h b/include/linux/mfd/wl1273-core.h
new file mode 100644
index 000000000000..9787293eae5f
--- /dev/null
+++ b/include/linux/mfd/wl1273-core.h
@@ -0,0 +1,288 @@
+/*
+ * include/linux/mfd/wl1273-core.h
+ *
+ * Some definitions for the wl1273 radio receiver/transmitter chip.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef WL1273_CORE_H
+#define WL1273_CORE_H
+
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+
+#define WL1273_FM_DRIVER_NAME "wl1273-fm"
+#define RX71_FM_I2C_ADDR 0x22
+
+#define WL1273_STEREO_GET 0
+#define WL1273_RSSI_LVL_GET 1
+#define WL1273_IF_COUNT_GET 2
+#define WL1273_FLAG_GET 3
+#define WL1273_RDS_SYNC_GET 4
+#define WL1273_RDS_DATA_GET 5
+#define WL1273_FREQ_SET 10
+#define WL1273_AF_FREQ_SET 11
+#define WL1273_MOST_MODE_SET 12
+#define WL1273_MOST_BLEND_SET 13
+#define WL1273_DEMPH_MODE_SET 14
+#define WL1273_SEARCH_LVL_SET 15
+#define WL1273_BAND_SET 16
+#define WL1273_MUTE_STATUS_SET 17
+#define WL1273_RDS_PAUSE_LVL_SET 18
+#define WL1273_RDS_PAUSE_DUR_SET 19
+#define WL1273_RDS_MEM_SET 20
+#define WL1273_RDS_BLK_B_SET 21
+#define WL1273_RDS_MSK_B_SET 22
+#define WL1273_RDS_PI_MASK_SET 23
+#define WL1273_RDS_PI_SET 24
+#define WL1273_RDS_SYSTEM_SET 25
+#define WL1273_INT_MASK_SET 26
+#define WL1273_SEARCH_DIR_SET 27
+#define WL1273_VOLUME_SET 28
+#define WL1273_AUDIO_ENABLE 29
+#define WL1273_PCM_MODE_SET 30
+#define WL1273_I2S_MODE_CONFIG_SET 31
+#define WL1273_POWER_SET 32
+#define WL1273_INTX_CONFIG_SET 33
+#define WL1273_PULL_EN_SET 34
+#define WL1273_HILO_SET 35
+#define WL1273_SWITCH2FREF 36
+#define WL1273_FREQ_DRIFT_REPORT 37
+
+#define WL1273_PCE_GET 40
+#define WL1273_FIRM_VER_GET 41
+#define WL1273_ASIC_VER_GET 42
+#define WL1273_ASIC_ID_GET 43
+#define WL1273_MAN_ID_GET 44
+#define WL1273_TUNER_MODE_SET 45
+#define WL1273_STOP_SEARCH 46
+#define WL1273_RDS_CNTRL_SET 47
+
+#define WL1273_WRITE_HARDWARE_REG 100
+#define WL1273_CODE_DOWNLOAD 101
+#define WL1273_RESET 102
+
+#define WL1273_FM_POWER_MODE 254
+#define WL1273_FM_INTERRUPT 255
+
+/* Transmitter API */
+
+#define WL1273_CHANL_SET 55
+#define WL1273_SCAN_SPACING_SET 56
+#define WL1273_REF_SET 57
+#define WL1273_POWER_ENB_SET 90
+#define WL1273_POWER_ATT_SET 58
+#define WL1273_POWER_LEV_SET 59
+#define WL1273_AUDIO_DEV_SET 60
+#define WL1273_PILOT_DEV_SET 61
+#define WL1273_RDS_DEV_SET 62
+#define WL1273_PUPD_SET 91
+#define WL1273_AUDIO_IO_SET 63
+#define WL1273_PREMPH_SET 64
+#define WL1273_MONO_SET 66
+#define WL1273_MUTE 92
+#define WL1273_MPX_LMT_ENABLE 67
+#define WL1273_PI_SET 93
+#define WL1273_ECC_SET 69
+#define WL1273_PTY 70
+#define WL1273_AF 71
+#define WL1273_DISPLAY_MODE 74
+#define WL1273_RDS_REP_SET 77
+#define WL1273_RDS_CONFIG_DATA_SET 98
+#define WL1273_RDS_DATA_SET 99
+#define WL1273_RDS_DATA_ENB 94
+#define WL1273_TA_SET 78
+#define WL1273_TP_SET 79
+#define WL1273_DI_SET 80
+#define WL1273_MS_SET 81
+#define WL1273_PS_SCROLL_SPEED 82
+#define WL1273_TX_AUDIO_LEVEL_TEST 96
+#define WL1273_TX_AUDIO_LEVEL_TEST_THRESHOLD 73
+#define WL1273_TX_AUDIO_INPUT_LEVEL_RANGE_SET 54
+#define WL1273_RX_ANTENNA_SELECT 87
+#define WL1273_I2C_DEV_ADDR_SET 86
+#define WL1273_REF_ERR_CALIB_PARAM_SET 88
+#define WL1273_REF_ERR_CALIB_PERIODICITY_SET 89
+#define WL1273_SOC_INT_TRIGGER 52
+#define WL1273_SOC_AUDIO_PATH_SET 83
+#define WL1273_SOC_PCMI_OVERRIDE 84
+#define WL1273_SOC_I2S_OVERRIDE 85
+#define WL1273_RSSI_BLOCK_SCAN_FREQ_SET 95
+#define WL1273_RSSI_BLOCK_SCAN_START 97
+#define WL1273_RSSI_BLOCK_SCAN_DATA_GET 5
+#define WL1273_READ_FMANT_TUNE_VALUE 104
+
+#define WL1273_RDS_OFF 0
+#define WL1273_RDS_ON 1
+#define WL1273_RDS_RESET 2
+
+#define WL1273_AUDIO_DIGITAL 0
+#define WL1273_AUDIO_ANALOG 1
+
+#define WL1273_MODE_RX BIT(0)
+#define WL1273_MODE_TX BIT(1)
+#define WL1273_MODE_OFF BIT(2)
+#define WL1273_MODE_SUSPENDED BIT(3)
+
+#define WL1273_RADIO_CHILD BIT(0)
+#define WL1273_CODEC_CHILD BIT(1)
+
+#define WL1273_RX_MONO 1
+#define WL1273_RX_STEREO 0
+#define WL1273_TX_MONO 0
+#define WL1273_TX_STEREO 1
+
+#define WL1273_MAX_VOLUME 0xffff
+#define WL1273_DEFAULT_VOLUME 0x78b8
+
+/* I2S protocol, left channel first, data width 16 bits */
+#define WL1273_PCM_DEF_MODE 0x00
+
+/* Rx */
+#define WL1273_AUDIO_ENABLE_I2S BIT(0)
+#define WL1273_AUDIO_ENABLE_ANALOG BIT(1)
+
+/* Tx */
+#define WL1273_AUDIO_IO_SET_ANALOG 0
+#define WL1273_AUDIO_IO_SET_I2S 1
+
+#define WL1273_PUPD_SET_OFF 0x00
+#define WL1273_PUPD_SET_ON 0x01
+#define WL1273_PUPD_SET_RETENTION 0x10
+
+/* I2S mode */
+#define WL1273_IS2_WIDTH_32 0x0
+#define WL1273_IS2_WIDTH_40 0x1
+#define WL1273_IS2_WIDTH_22_23 0x2
+#define WL1273_IS2_WIDTH_23_22 0x3
+#define WL1273_IS2_WIDTH_48 0x4
+#define WL1273_IS2_WIDTH_50 0x5
+#define WL1273_IS2_WIDTH_60 0x6
+#define WL1273_IS2_WIDTH_64 0x7
+#define WL1273_IS2_WIDTH_80 0x8
+#define WL1273_IS2_WIDTH_96 0x9
+#define WL1273_IS2_WIDTH_128 0xa
+#define WL1273_IS2_WIDTH 0xf
+
+#define WL1273_IS2_FORMAT_STD (0x0 << 4)
+#define WL1273_IS2_FORMAT_LEFT (0x1 << 4)
+#define WL1273_IS2_FORMAT_RIGHT (0x2 << 4)
+#define WL1273_IS2_FORMAT_USER (0x3 << 4)
+
+#define WL1273_IS2_MASTER (0x0 << 6)
+#define WL1273_IS2_SLAVEW (0x1 << 6)
+
+#define WL1273_IS2_TRI_AFTER_SENDING (0x0 << 7)
+#define WL1273_IS2_TRI_ALWAYS_ACTIVE (0x1 << 7)
+
+#define WL1273_IS2_SDOWS_RR (0x0 << 8)
+#define WL1273_IS2_SDOWS_RF (0x1 << 8)
+#define WL1273_IS2_SDOWS_FR (0x2 << 8)
+#define WL1273_IS2_SDOWS_FF (0x3 << 8)
+
+#define WL1273_IS2_TRI_OPT (0x0 << 10)
+#define WL1273_IS2_TRI_ALWAYS (0x1 << 10)
+
+#define WL1273_IS2_RATE_48K (0x0 << 12)
+#define WL1273_IS2_RATE_44_1K (0x1 << 12)
+#define WL1273_IS2_RATE_32K (0x2 << 12)
+#define WL1273_IS2_RATE_22_05K (0x4 << 12)
+#define WL1273_IS2_RATE_16K (0x5 << 12)
+#define WL1273_IS2_RATE_12K (0x8 << 12)
+#define WL1273_IS2_RATE_11_025 (0x9 << 12)
+#define WL1273_IS2_RATE_8K (0xa << 12)
+#define WL1273_IS2_RATE (0xf << 12)
+
+#define WL1273_I2S_DEF_MODE (WL1273_IS2_WIDTH_32 | \
+ WL1273_IS2_FORMAT_STD | \
+ WL1273_IS2_MASTER | \
+ WL1273_IS2_TRI_AFTER_SENDING | \
+ WL1273_IS2_SDOWS_RR | \
+ WL1273_IS2_TRI_OPT | \
+ WL1273_IS2_RATE_48K)
+
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+
+#define WL1273_FR_EVENT BIT(0)
+#define WL1273_BL_EVENT BIT(1)
+#define WL1273_RDS_EVENT BIT(2)
+#define WL1273_BBLK_EVENT BIT(3)
+#define WL1273_LSYNC_EVENT BIT(4)
+#define WL1273_LEV_EVENT BIT(5)
+#define WL1273_IFFR_EVENT BIT(6)
+#define WL1273_PI_EVENT BIT(7)
+#define WL1273_PD_EVENT BIT(8)
+#define WL1273_STIC_EVENT BIT(9)
+#define WL1273_MAL_EVENT BIT(10)
+#define WL1273_POW_ENB_EVENT BIT(11)
+#define WL1273_SCAN_OVER_EVENT BIT(12)
+#define WL1273_ERROR_EVENT BIT(13)
+
+#define TUNER_MODE_STOP_SEARCH 0
+#define TUNER_MODE_PRESET 1
+#define TUNER_MODE_AUTO_SEEK 2
+#define TUNER_MODE_AF 3
+#define TUNER_MODE_AUTO_SEEK_PI 4
+#define TUNER_MODE_AUTO_SEEK_BULK 5
+
+#define RDS_BLOCK_SIZE 3
+
+struct wl1273_fm_platform_data {
+ int (*request_resources) (struct i2c_client *client);
+ void (*free_resources) (void);
+ void (*enable) (void);
+ void (*disable) (void);
+
+ u8 forbidden_modes;
+ unsigned int children;
+};
+
+#define WL1273_FM_CORE_CELLS 2
+
+#define WL1273_BAND_OTHER 0
+#define WL1273_BAND_JAPAN 1
+
+#define WL1273_BAND_JAPAN_LOW 76000
+#define WL1273_BAND_JAPAN_HIGH 90000
+#define WL1273_BAND_OTHER_LOW 87500
+#define WL1273_BAND_OTHER_HIGH 108000
+
+#define WL1273_BAND_TX_LOW 76000
+#define WL1273_BAND_TX_HIGH 108000
+
+struct wl1273_core {
+ struct mfd_cell cells[WL1273_FM_CORE_CELLS];
+ struct wl1273_fm_platform_data *pdata;
+
+ unsigned int mode;
+ unsigned int i2s_mode;
+ unsigned int volume;
+ unsigned int audio_mode;
+ unsigned int channel_number;
+ struct mutex lock; /* for serializing fm radio operations */
+
+ struct i2c_client *client;
+
+ int (*write)(struct wl1273_core *core, u8, u16);
+ int (*set_audio)(struct wl1273_core *core, unsigned int);
+ int (*set_volume)(struct wl1273_core *core, unsigned int);
+};
+
+#endif /* ifndef WL1273_CORE_H */
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index de79baee4925..3fd36845ca45 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -17,6 +17,11 @@
#include <linux/interrupt.h>
+enum wm8994_type {
+ WM8994 = 0,
+ WM8958 = 1,
+};
+
struct regulator_dev;
struct regulator_bulk_data;
@@ -48,6 +53,8 @@ struct wm8994 {
struct mutex io_lock;
struct mutex irq_lock;
+ enum wm8994_type type;
+
struct device *dev;
int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
int bytes, void *dest);
@@ -68,6 +75,7 @@ struct wm8994 {
u16 gpio_regs[WM8994_NUM_GPIO_REGS];
struct regulator_dev *dbvdd;
+ int num_supplies;
struct regulator_bulk_data *supplies;
};
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 5c51f367c061..9eab263658be 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -29,7 +29,9 @@ struct wm8994_ldo_pdata {
#define WM8994_CONFIGURE_GPIO 0x8000
#define WM8994_DRC_REGS 5
-#define WM8994_EQ_REGS 19
+#define WM8994_EQ_REGS 20
+#define WM8958_MBC_CUTOFF_REGS 20
+#define WM8958_MBC_COEFF_REGS 48
/**
* DRC configurations are specified with a label and a set of register
@@ -59,6 +61,18 @@ struct wm8994_retune_mobile_cfg {
u16 regs[WM8994_EQ_REGS];
};
+/**
+ * Multiband compressor configurations are specified with a label and
+ * two sets of values to write. Configurations are expected to be
+ * generated using the multiband compressor configuration panel in
+ * WISCE - see http://www.wolfsonmicro.com/wisce/
+ */
+struct wm8958_mbc_cfg {
+ const char *name;
+ u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS];
+ u16 coeff_regs[WM8958_MBC_COEFF_REGS];
+};
+
struct wm8994_pdata {
int gpio_base;
@@ -78,6 +92,9 @@ struct wm8994_pdata {
int num_retune_mobile_cfgs;
struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
+ int num_mbc_cfgs;
+ struct wm8958_mbc_cfg *mbc_cfgs;
+
/* LINEOUT can be differential or single ended */
unsigned int lineout1_diff:1;
unsigned int lineout2_diff:1;
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index 967f62f54159..be072faec6f0 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -64,12 +64,16 @@
#define WM8994_LDO_1 0x3B
#define WM8994_LDO_2 0x3C
#define WM8994_CHARGE_PUMP_1 0x4C
+#define WM8958_CHARGE_PUMP_2 0x4D
#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 WM8958_MIC_DETECT_1 0xD0
+#define WM8958_MIC_DETECT_2 0xD1
+#define WM8958_MIC_DETECT_3 0xD2
#define WM8994_CHIP_REVISION 0x100
#define WM8994_CONTROL_INTERFACE 0x101
#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110
@@ -109,6 +113,10 @@
#define WM8994_AIF2DAC_LRCLK 0x315
#define WM8994_AIF2DAC_DATA 0x316
#define WM8994_AIF2ADC_DATA 0x317
+#define WM8958_AIF3_CONTROL_1 0x320
+#define WM8958_AIF3_CONTROL_2 0x321
+#define WM8958_AIF3DAC_DATA 0x322
+#define WM8958_AIF3ADC_DATA 0x323
#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
@@ -242,6 +250,83 @@
#define WM8994_INTERRUPT_STATUS_2_MASK 0x739
#define WM8994_INTERRUPT_CONTROL 0x740
#define WM8994_IRQ_DEBOUNCE 0x748
+#define WM8958_DSP2_PROGRAM 0x900
+#define WM8958_DSP2_CONFIG 0x901
+#define WM8958_DSP2_MAGICNUM 0xA00
+#define WM8958_DSP2_RELEASEYEAR 0xA01
+#define WM8958_DSP2_RELEASEMONTHDAY 0xA02
+#define WM8958_DSP2_RELEASETIME 0xA03
+#define WM8958_DSP2_VERMAJMIN 0xA04
+#define WM8958_DSP2_VERBUILD 0xA05
+#define WM8958_DSP2_EXECCONTROL 0xA0D
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 0x2200
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_2 0x2201
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_1 0x2202
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_2 0x2203
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_1 0x2204
+#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_2 0x2205
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_1 0x2206
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_2 0x2207
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_1 0x2208
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_2 0x2209
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_1 0x220A
+#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_2 0x220B
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_1 0x220C
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_2 0x220D
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_1 0x220E
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_2 0x220F
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_1 0x2210
+#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_2 0x2211
+#define WM8958_MBC_BAND_1_LOWER_CUTOFF_1 0x2212
+#define WM8958_MBC_BAND_1_LOWER_CUTOFF_2 0x2213
+#define WM8958_MBC_BAND_1_K_1 0x2400
+#define WM8958_MBC_BAND_1_K_2 0x2401
+#define WM8958_MBC_BAND_1_N1_1 0x2402
+#define WM8958_MBC_BAND_1_N1_2 0x2403
+#define WM8958_MBC_BAND_1_N2_1 0x2404
+#define WM8958_MBC_BAND_1_N2_2 0x2405
+#define WM8958_MBC_BAND_1_N3_1 0x2406
+#define WM8958_MBC_BAND_1_N3_2 0x2407
+#define WM8958_MBC_BAND_1_N4_1 0x2408
+#define WM8958_MBC_BAND_1_N4_2 0x2409
+#define WM8958_MBC_BAND_1_N5_1 0x240A
+#define WM8958_MBC_BAND_1_N5_2 0x240B
+#define WM8958_MBC_BAND_1_X1_1 0x240C
+#define WM8958_MBC_BAND_1_X1_2 0x240D
+#define WM8958_MBC_BAND_1_X2_1 0x240E
+#define WM8958_MBC_BAND_1_X2_2 0x240F
+#define WM8958_MBC_BAND_1_X3_1 0x2410
+#define WM8958_MBC_BAND_1_X3_2 0x2411
+#define WM8958_MBC_BAND_1_ATTACK_1 0x2412
+#define WM8958_MBC_BAND_1_ATTACK_2 0x2413
+#define WM8958_MBC_BAND_1_DECAY_1 0x2414
+#define WM8958_MBC_BAND_1_DECAY_2 0x2415
+#define WM8958_MBC_BAND_2_K_1 0x2416
+#define WM8958_MBC_BAND_2_K_2 0x2417
+#define WM8958_MBC_BAND_2_N1_1 0x2418
+#define WM8958_MBC_BAND_2_N1_2 0x2419
+#define WM8958_MBC_BAND_2_N2_1 0x241A
+#define WM8958_MBC_BAND_2_N2_2 0x241B
+#define WM8958_MBC_BAND_2_N3_1 0x241C
+#define WM8958_MBC_BAND_2_N3_2 0x241D
+#define WM8958_MBC_BAND_2_N4_1 0x241E
+#define WM8958_MBC_BAND_2_N4_2 0x241F
+#define WM8958_MBC_BAND_2_N5_1 0x2420
+#define WM8958_MBC_BAND_2_N5_2 0x2421
+#define WM8958_MBC_BAND_2_X1_1 0x2422
+#define WM8958_MBC_BAND_2_X1_2 0x2423
+#define WM8958_MBC_BAND_2_X2_1 0x2424
+#define WM8958_MBC_BAND_2_X2_2 0x2425
+#define WM8958_MBC_BAND_2_X3_1 0x2426
+#define WM8958_MBC_BAND_2_X3_2 0x2427
+#define WM8958_MBC_BAND_2_ATTACK_1 0x2428
+#define WM8958_MBC_BAND_2_ATTACK_2 0x2429
+#define WM8958_MBC_BAND_2_DECAY_1 0x242A
+#define WM8958_MBC_BAND_2_DECAY_2 0x242B
+#define WM8958_MBC_B2_PG2_1 0x242C
+#define WM8958_MBC_B2_PG2_2 0x242D
+#define WM8958_MBC_B1_PG2_1 0x242E
+#define WM8958_MBC_B1_PG2_2 0x242F
#define WM8994_WRITE_SEQUENCER_0 0x3000
#define WM8994_WRITE_SEQUENCER_1 0x3001
#define WM8994_WRITE_SEQUENCER_2 0x3002
@@ -992,6 +1077,12 @@
/*
* R6 (0x06) - Power Management (6)
*/
+#define WM8958_AIF3ADC_SRC_MASK 0x0600 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF3ADC_SRC_SHIFT 9 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF3ADC_SRC_WIDTH 2 /* AIF3ADC_SRC - [10:9] */
+#define WM8958_AIF2DAC_SRC_MASK 0x0180 /* AIF2DAC_SRC - [8:7] */
+#define WM8958_AIF2DAC_SRC_SHIFT 7 /* AIF2DAC_SRC - [8:7] */
+#define WM8958_AIF2DAC_SRC_WIDTH 2 /* AIF2DAC_SRC - [8:7] */
#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */
#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
@@ -1836,6 +1927,14 @@
#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */
/*
+ * R77 (0x4D) - Charge Pump (2)
+ */
+#define WM8958_CP_DISCH 0x8000 /* CP_DISCH */
+#define WM8958_CP_DISCH_MASK 0x8000 /* CP_DISCH */
+#define WM8958_CP_DISCH_SHIFT 15 /* CP_DISCH */
+#define WM8958_CP_DISCH_WIDTH 1 /* CP_DISCH */
+
+/*
* R81 (0x51) - Class W (1)
*/
#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
@@ -1952,6 +2051,46 @@
#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
/*
+ * R208 (0xD0) - Mic Detect 1
+ */
+#define WM8958_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8958_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
+#define WM8958_MICD_DBTIME 0x0002 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
+#define WM8958_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
+#define WM8958_MICD_ENA 0x0001 /* MICD_ENA */
+#define WM8958_MICD_ENA_MASK 0x0001 /* MICD_ENA */
+#define WM8958_MICD_ENA_SHIFT 0 /* MICD_ENA */
+#define WM8958_MICD_ENA_WIDTH 1 /* MICD_ENA */
+
+/*
+ * R209 (0xD1) - Mic Detect 2
+ */
+#define WM8958_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
+#define WM8958_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
+#define WM8958_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
+
+/*
+ * R210 (0xD2) - Mic Detect 3
+ */
+#define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
+#define WM8958_MICD_VALID 0x0002 /* MICD_VALID */
+#define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */
+#define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */
+#define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */
+#define WM8958_MICD_STS 0x0001 /* MICD_STS */
+#define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */
+#define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */
+#define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */
+
+/*
* R256 (0x100) - Chip Revision
*/
#define WM8994_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
@@ -2069,6 +2208,14 @@
/*
* R520 (0x208) - Clocking (1)
*/
+#define WM8958_DSP2CLK_ENA 0x4000 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_MASK 0x4000 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_SHIFT 14 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_ENA_WIDTH 1 /* DSP2CLK_ENA */
+#define WM8958_DSP2CLK_SRC 0x1000 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_MASK 0x1000 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_SHIFT 12 /* DSP2CLK_SRC */
+#define WM8958_DSP2CLK_SRC_WIDTH 1 /* DSP2CLK_SRC */
#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */
#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
@@ -2553,6 +2700,63 @@
#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
/*
+ * R800 (0x320) - AIF3 Control (1)
+ */
+#define WM8958_AIF3_LRCLK_INV 0x0080 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_MASK 0x0080 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_SHIFT 7 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_LRCLK_INV_WIDTH 1 /* AIF3_LRCLK_INV */
+#define WM8958_AIF3_WL_MASK 0x0060 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_WL_SHIFT 5 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_WL_WIDTH 2 /* AIF3_WL - [6:5] */
+#define WM8958_AIF3_FMT_MASK 0x0018 /* AIF3_FMT - [4:3] */
+#define WM8958_AIF3_FMT_SHIFT 3 /* AIF3_FMT - [4:3] */
+#define WM8958_AIF3_FMT_WIDTH 2 /* AIF3_FMT - [4:3] */
+
+/*
+ * R801 (0x321) - AIF3 Control (2)
+ */
+#define WM8958_AIF3DAC_BOOST_MASK 0x0C00 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_BOOST_SHIFT 10 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_BOOST_WIDTH 2 /* AIF3DAC_BOOST - [11:10] */
+#define WM8958_AIF3DAC_COMP 0x0010 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_MASK 0x0010 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_SHIFT 4 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMP_WIDTH 1 /* AIF3DAC_COMP */
+#define WM8958_AIF3DAC_COMPMODE 0x0008 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_MASK 0x0008 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_SHIFT 3 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3DAC_COMPMODE_WIDTH 1 /* AIF3DAC_COMPMODE */
+#define WM8958_AIF3ADC_COMP 0x0004 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_MASK 0x0004 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_SHIFT 2 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMP_WIDTH 1 /* AIF3ADC_COMP */
+#define WM8958_AIF3ADC_COMPMODE 0x0002 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_MASK 0x0002 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_SHIFT 1 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3ADC_COMPMODE_WIDTH 1 /* AIF3ADC_COMPMODE */
+#define WM8958_AIF3_LOOPBACK 0x0001 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_MASK 0x0001 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_SHIFT 0 /* AIF3_LOOPBACK */
+#define WM8958_AIF3_LOOPBACK_WIDTH 1 /* AIF3_LOOPBACK */
+
+/*
+ * R802 (0x322) - AIF3DAC Data
+ */
+#define WM8958_AIF3DAC_DAT_INV 0x0001 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_MASK 0x0001 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_SHIFT 0 /* AIF3DAC_DAT_INV */
+#define WM8958_AIF3DAC_DAT_INV_WIDTH 1 /* AIF3DAC_DAT_INV */
+
+/*
+ * R803 (0x323) - AIF3ADC Data
+ */
+#define WM8958_AIF3ADC_DAT_INV 0x0001 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_MASK 0x0001 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_SHIFT 0 /* AIF3ADC_DAT_INV */
+#define WM8958_AIF3ADC_DAT_INV_WIDTH 1 /* AIF3ADC_DAT_INV */
+
+/*
* R1024 (0x400) - AIF1 ADC1 Left Volume
*/
#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
@@ -4289,4 +4493,102 @@
#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
+/*
+ * R2304 (0x900) - DSP2_Program
+ */
+#define WM8958_DSP2_ENA 0x0001 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_MASK 0x0001 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_SHIFT 0 /* DSP2_ENA */
+#define WM8958_DSP2_ENA_WIDTH 1 /* DSP2_ENA */
+
+/*
+ * R2305 (0x901) - DSP2_Config
+ */
+#define WM8958_MBC_SEL_MASK 0x0030 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_SEL_SHIFT 4 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_SEL_WIDTH 2 /* MBC_SEL - [5:4] */
+#define WM8958_MBC_ENA 0x0001 /* MBC_ENA */
+#define WM8958_MBC_ENA_MASK 0x0001 /* MBC_ENA */
+#define WM8958_MBC_ENA_SHIFT 0 /* MBC_ENA */
+#define WM8958_MBC_ENA_WIDTH 1 /* MBC_ENA */
+
+/*
+ * R2560 (0xA00) - DSP2_MagicNum
+ */
+#define WM8958_DSP2_MAGIC_NUM_MASK 0xFFFF /* DSP2_MAGIC_NUM - [15:0] */
+#define WM8958_DSP2_MAGIC_NUM_SHIFT 0 /* DSP2_MAGIC_NUM - [15:0] */
+#define WM8958_DSP2_MAGIC_NUM_WIDTH 16 /* DSP2_MAGIC_NUM - [15:0] */
+
+/*
+ * R2561 (0xA01) - DSP2_ReleaseYear
+ */
+#define WM8958_DSP2_RELEASE_YEAR_MASK 0xFFFF /* DSP2_RELEASE_YEAR - [15:0] */
+#define WM8958_DSP2_RELEASE_YEAR_SHIFT 0 /* DSP2_RELEASE_YEAR - [15:0] */
+#define WM8958_DSP2_RELEASE_YEAR_WIDTH 16 /* DSP2_RELEASE_YEAR - [15:0] */
+
+/*
+ * R2562 (0xA02) - DSP2_ReleaseMonthDay
+ */
+#define WM8958_DSP2_RELEASE_MONTH_MASK 0xFF00 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_MONTH_SHIFT 8 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_MONTH_WIDTH 8 /* DSP2_RELEASE_MONTH - [15:8] */
+#define WM8958_DSP2_RELEASE_DAY_MASK 0x00FF /* DSP2_RELEASE_DAY - [7:0] */
+#define WM8958_DSP2_RELEASE_DAY_SHIFT 0 /* DSP2_RELEASE_DAY - [7:0] */
+#define WM8958_DSP2_RELEASE_DAY_WIDTH 8 /* DSP2_RELEASE_DAY - [7:0] */
+
+/*
+ * R2563 (0xA03) - DSP2_ReleaseTime
+ */
+#define WM8958_DSP2_RELEASE_HOURS_MASK 0xFF00 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_HOURS_SHIFT 8 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_HOURS_WIDTH 8 /* DSP2_RELEASE_HOURS - [15:8] */
+#define WM8958_DSP2_RELEASE_MINS_MASK 0x00FF /* DSP2_RELEASE_MINS - [7:0] */
+#define WM8958_DSP2_RELEASE_MINS_SHIFT 0 /* DSP2_RELEASE_MINS - [7:0] */
+#define WM8958_DSP2_RELEASE_MINS_WIDTH 8 /* DSP2_RELEASE_MINS - [7:0] */
+
+/*
+ * R2564 (0xA04) - DSP2_VerMajMin
+ */
+#define WM8958_DSP2_MAJOR_VER_MASK 0xFF00 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MAJOR_VER_SHIFT 8 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MAJOR_VER_WIDTH 8 /* DSP2_MAJOR_VER - [15:8] */
+#define WM8958_DSP2_MINOR_VER_MASK 0x00FF /* DSP2_MINOR_VER - [7:0] */
+#define WM8958_DSP2_MINOR_VER_SHIFT 0 /* DSP2_MINOR_VER - [7:0] */
+#define WM8958_DSP2_MINOR_VER_WIDTH 8 /* DSP2_MINOR_VER - [7:0] */
+
+/*
+ * R2565 (0xA05) - DSP2_VerBuild
+ */
+#define WM8958_DSP2_BUILD_VER_MASK 0xFFFF /* DSP2_BUILD_VER - [15:0] */
+#define WM8958_DSP2_BUILD_VER_SHIFT 0 /* DSP2_BUILD_VER - [15:0] */
+#define WM8958_DSP2_BUILD_VER_WIDTH 16 /* DSP2_BUILD_VER - [15:0] */
+
+/*
+ * R2573 (0xA0D) - DSP2_ExecControl
+ */
+#define WM8958_DSP2_STOPC 0x0020 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_MASK 0x0020 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_SHIFT 5 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPC_WIDTH 1 /* DSP2_STOPC */
+#define WM8958_DSP2_STOPS 0x0010 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_MASK 0x0010 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_SHIFT 4 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPS_WIDTH 1 /* DSP2_STOPS */
+#define WM8958_DSP2_STOPI 0x0008 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_MASK 0x0008 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_SHIFT 3 /* DSP2_STOPI */
+#define WM8958_DSP2_STOPI_WIDTH 1 /* DSP2_STOPI */
+#define WM8958_DSP2_STOP 0x0004 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_MASK 0x0004 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_SHIFT 2 /* DSP2_STOP */
+#define WM8958_DSP2_STOP_WIDTH 1 /* DSP2_STOP */
+#define WM8958_DSP2_RUNR 0x0002 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_MASK 0x0002 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_SHIFT 1 /* DSP2_RUNR */
+#define WM8958_DSP2_RUNR_WIDTH 1 /* DSP2_RUNR */
+#define WM8958_DSP2_RUN 0x0001 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_MASK 0x0001 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_SHIFT 0 /* DSP2_RUN */
+#define WM8958_DSP2_RUN_WIDTH 1 /* DSP2_RUN */
+
#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 721f451c3029..e097df6c0174 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -145,6 +145,7 @@ extern pgprot_t protection_map[16];
#define FAULT_FLAG_NONLINEAR 0x02 /* Fault was via a nonlinear mapping */
#define FAULT_FLAG_MKWRITE 0x04 /* Fault was mkwrite of existing pte */
#define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */
+#define FAULT_FLAG_MINOR 0x10 /* Do only minor fault */
/*
* This interface is used by x86 PAT code to identify a pfn mapping that is
@@ -858,6 +859,9 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, int nr_pages, int write, int force,
struct page **pages, struct vm_area_struct **vmas);
+int get_user_pages_noio(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int nr_pages, int write, int force,
+ struct page **pages, struct vm_area_struct **vmas);
int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages);
struct page *get_dump_page(unsigned long addr);
@@ -1415,6 +1419,7 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address,
#define FOLL_GET 0x04 /* do get_page on page */
#define FOLL_DUMP 0x08 /* give error on hole if it would be zero */
#define FOLL_FORCE 0x10 /* get_user_pages read/write w/o permission */
+#define FOLL_MINOR 0x20 /* do only minor page faults */
typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
void *data);
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
index 5c99da1078aa..44fc5348fd5d 100644
--- a/include/linux/mmc/sh_mmcif.h
+++ b/include/linux/mmc/sh_mmcif.h
@@ -14,8 +14,9 @@
#ifndef __SH_MMCIF_H__
#define __SH_MMCIF_H__
-#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/sh_dma.h>
/*
* MMCIF : CE_CLK_CTRL [19:16]
@@ -31,13 +32,19 @@
* 1111 : Peripheral clock (sup_pclk set '1')
*/
+struct sh_mmcif_dma {
+ struct sh_dmae_slave chan_priv_tx;
+ struct sh_dmae_slave chan_priv_rx;
+};
+
struct sh_mmcif_plat_data {
void (*set_pwr)(struct platform_device *pdev, int state);
void (*down_pwr)(struct platform_device *pdev);
int (*get_cd)(struct platform_device *pdef);
- u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
- unsigned long caps;
- u32 ocr;
+ struct sh_mmcif_dma *dma;
+ u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
+ unsigned long caps;
+ u32 ocr;
};
#define MMCIF_CE_CMD_SET 0x00000000
@@ -59,6 +66,32 @@ struct sh_mmcif_plat_data {
#define MMCIF_CE_HOST_STS2 0x0000004C
#define MMCIF_CE_VERSION 0x0000007C
+/* CE_BUF_ACC */
+#define BUF_ACC_DMAWEN (1 << 25)
+#define BUF_ACC_DMAREN (1 << 24)
+#define BUF_ACC_BUSW_32 (0 << 17)
+#define BUF_ACC_BUSW_16 (1 << 17)
+#define BUF_ACC_ATYP (1 << 16)
+
+/* CE_CLK_CTRL */
+#define CLK_ENABLE (1 << 24) /* 1: output mmc clock */
+#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+#define CLKDIV_4 (1<<16) /* mmc clock frequency.
+ * n: bus clock/(2^(n+1)) */
+#define CLKDIV_256 (7<<16) /* mmc clock frequency. (see above) */
+#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */
+#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \
+ (1 << 9) | (1 << 8)) /* resp busy timeout */
+#define SRWDTO_29 ((1 << 7) | (1 << 6) | \
+ (1 << 5) | (1 << 4)) /* read/write timeout */
+#define SCCSTO_29 ((1 << 3) | (1 << 2) | \
+ (1 << 1) | (1 << 0)) /* ccs timeout */
+
+/* CE_VERSION */
+#define SOFT_RST_ON (1 << 31)
+#define SOFT_RST_OFF 0
+
static inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
{
return readl(addr + reg);
@@ -145,21 +178,20 @@ static inline int sh_mmcif_boot_do_read(void __iomem *base,
static inline void sh_mmcif_boot_init(void __iomem *base)
{
- unsigned long tmp;
-
/* reset */
- tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION);
- sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | 0x80000000);
- sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & ~0x80000000);
+ sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_ON);
+ sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_OFF);
/* byte swap */
- sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, 0x00010000);
+ sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP);
/* Set block size in MMCIF hardware */
sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS);
- /* Enable the clock, set it to Bus clock/256 (about 325Khz)*/
- sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01072fff);
+ /* Enable the clock, set it to Bus clock/256 (about 325Khz). */
+ sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
+ CLK_ENABLE | CLKDIV_256 | SRSPTO_256 |
+ SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
/* CMD0 */
sh_mmcif_boot_cmd(base, 0x00000040, 0);
@@ -184,7 +216,9 @@ static inline void sh_mmcif_boot_slurp(void __iomem *base,
unsigned long tmp;
/* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */
- sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01012fff);
+ sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
+ CLK_ENABLE | CLKDIV_4 | SRSPTO_256 |
+ SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
/* CMD9 - Get CSD */
sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000);
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 5e7a59408dd4..1869ea24a739 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/nodemask.h>
#include <linux/spinlock.h>
+#include <linux/seqlock.h>
#include <asm/atomic.h>
struct super_block;
@@ -46,12 +47,24 @@ struct mnt_namespace;
#define MNT_INTERNAL 0x4000
+struct mnt_pcp {
+ int mnt_count;
+ int mnt_writers;
+};
+
struct vfsmount {
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
+#ifdef CONFIG_SMP
+ struct mnt_pcp __percpu *mnt_pcp;
+ atomic_t mnt_longrefs;
+#else
+ int mnt_count;
+ int mnt_writers;
+#endif
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
int mnt_flags;
@@ -70,57 +83,25 @@ struct vfsmount {
struct mnt_namespace *mnt_ns; /* containing namespace */
int mnt_id; /* mount identifier */
int mnt_group_id; /* peer group identifier */
- /*
- * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
- * to let these frequently modified fields in a separate cache line
- * (so that reads of mnt_flags wont ping-pong on SMP machines)
- */
- atomic_t mnt_count;
int mnt_expiry_mark; /* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
-#ifdef CONFIG_SMP
- int __percpu *mnt_writers;
-#else
- int mnt_writers;
-#endif
};
-static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
-{
-#ifdef CONFIG_SMP
- return mnt->mnt_writers;
-#else
- return &mnt->mnt_writers;
-#endif
-}
-
-static inline struct vfsmount *mntget(struct vfsmount *mnt)
-{
- if (mnt)
- atomic_inc(&mnt->mnt_count);
- return mnt;
-}
-
struct file; /* forward dec */
extern int mnt_want_write(struct vfsmount *mnt);
extern int mnt_want_write_file(struct file *file);
extern int mnt_clone_write(struct vfsmount *mnt);
extern void mnt_drop_write(struct vfsmount *mnt);
-extern void mntput_no_expire(struct vfsmount *mnt);
+extern void mntput(struct vfsmount *mnt);
+extern struct vfsmount *mntget(struct vfsmount *mnt);
+extern void mntput_long(struct vfsmount *mnt);
+extern struct vfsmount *mntget_long(struct vfsmount *mnt);
extern void mnt_pin(struct vfsmount *mnt);
extern void mnt_unpin(struct vfsmount *mnt);
extern int __mnt_is_readonly(struct vfsmount *mnt);
-static inline void mntput(struct vfsmount *mnt)
-{
- if (mnt) {
- mnt->mnt_expiry_mark = 0;
- mntput_no_expire(mnt);
- }
-}
-
extern struct vfsmount *do_kern_mount(const char *fstype, int flags,
const char *name, void *data);
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 4dd0c2cd7659..a9baee6864af 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -527,8 +527,7 @@ struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t s
struct cfi_fixup {
uint16_t mfr;
uint16_t id;
- void (*fixup)(struct mtd_info *mtd, void* param);
- void* param;
+ void (*fixup)(struct mtd_info *mtd);
};
#define CFI_MFR_ANY 0xFFFF
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index 5d2556700ec2..6987995ad3cf 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -16,6 +16,7 @@
#ifndef __MTD_FSMC_H
#define __MTD_FSMC_H
+#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/types.h>
@@ -27,7 +28,7 @@
/*
* The placement of the Command Latch Enable (CLE) and
- * Address Latch Enable (ALE) is twised around in the
+ * Address Latch Enable (ALE) is twisted around in the
* SPEAR310 implementation.
*/
#if defined(CONFIG_MACH_SPEAR310)
@@ -62,7 +63,7 @@ struct fsmc_nor_bank_regs {
/* ctrl_tim register definitions */
-struct fsms_nand_bank_regs {
+struct fsmc_nand_bank_regs {
uint32_t pc;
uint32_t sts;
uint32_t comm;
@@ -78,7 +79,7 @@ struct fsms_nand_bank_regs {
struct fsmc_regs {
struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS];
uint8_t reserved_1[0x40 - 0x20];
- struct fsms_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
+ struct fsmc_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
uint8_t reserved_2[0xfe0 - 0xc0];
uint32_t peripid0; /* 0xfe0 */
uint32_t peripid1; /* 0xfe4 */
@@ -114,25 +115,6 @@ struct fsmc_regs {
#define FSMC_THOLD_4 (4 << 16)
#define FSMC_THIZ_1 (1 << 24)
-/* peripid2 register definitions */
-#define FSMC_REVISION_MSK (0xf)
-#define FSMC_REVISION_SHFT (0x4)
-
-#define FSMC_VER1 1
-#define FSMC_VER2 2
-#define FSMC_VER3 3
-#define FSMC_VER4 4
-#define FSMC_VER5 5
-#define FSMC_VER6 6
-#define FSMC_VER7 7
-#define FSMC_VER8 8
-
-static inline uint32_t get_fsmc_version(struct fsmc_regs *regs)
-{
- return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
- FSMC_REVISION_MSK;
-}
-
/*
* There are 13 bytes of ecc for every 512 byte block in FSMC version 8
* and it has to be read consecutively and immediately after the 512
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 63e17d01fde9..1f489b247a29 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -448,6 +448,8 @@ struct nand_buffers {
* See the defines for further explanation.
* @badblockpos: [INTERN] position of the bad block marker in the oob
* area.
+ * @badblockbits: [INTERN] number of bits to left-shift the bad block
+ * number
* @cellinfo: [INTERN] MLC/multichip data from chip ident
* @numchips: [INTERN] number of physical chips
* @chipsize: [INTERN] the size of one chip for multichip arrays
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 0c8815bfae1c..6da3fe314828 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -137,6 +137,14 @@ struct onenand_chip {
void *bbm;
void *priv;
+
+ /*
+ * Shows that the current operation is composed
+ * of sequence of commands. For example, cache program.
+ * Such command status OnGo bit is checked at the end of
+ * sequence.
+ */
+ unsigned int ongoing;
};
/*
@@ -171,6 +179,9 @@ struct onenand_chip {
#define ONENAND_IS_2PLANE(this) (0)
#endif
+#define ONENAND_IS_CACHE_PROGRAM(this) \
+ (this->options & ONENAND_HAS_CACHE_PROGRAM)
+
/* Check byte access in OneNAND */
#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
@@ -181,6 +192,7 @@ struct onenand_chip {
#define ONENAND_HAS_UNLOCK_ALL (0x0002)
#define ONENAND_HAS_2PLANE (0x0004)
#define ONENAND_HAS_4KB_PAGE (0x0008)
+#define ONENAND_HAS_CACHE_PROGRAM (0x0010)
#define ONENAND_SKIP_UNLOCK_CHECK (0x0100)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
#define ONENAND_OOBBUF_ALLOC (0x2000)
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 2b54316591d2..4a0a8ba90a72 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -89,7 +89,7 @@ static inline int mtd_has_cmdlinepart(void) { return 1; }
static inline int mtd_has_cmdlinepart(void) { return 0; }
#endif
-int mtd_is_master(struct mtd_info *mtd);
+int mtd_is_partition(struct mtd_info *mtd);
int mtd_add_partition(struct mtd_info *master, char *name,
long long offset, long long length);
int mtd_del_partition(struct mtd_info *master, int partno);
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index f363bc8fdc74..94b48bd40dd7 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -160,4 +160,8 @@ extern int mutex_trylock(struct mutex *lock);
extern void mutex_unlock(struct mutex *lock);
extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
+#ifndef CONFIG_HAVE_ARCH_MUTEX_CPU_RELAX
+#define arch_mutex_cpu_relax() cpu_relax()
+#endif
+
#endif
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 05b441d93642..18d06add0a40 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -19,7 +19,10 @@ struct nameidata {
struct path path;
struct qstr last;
struct path root;
+ struct file *file;
+ struct inode *inode; /* path.dentry.d_inode */
unsigned int flags;
+ unsigned seq;
int last_type;
unsigned depth;
char *saved_names[MAX_NESTED_LINKS + 1];
@@ -41,14 +44,15 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
* - require a directory
* - ending slashes ok even for nonexistent files
* - internal "there are more path components" flag
- * - locked when lookup done with dcache_lock held
* - dentry cache is untrusted; force a real lookup
*/
-#define LOOKUP_FOLLOW 1
-#define LOOKUP_DIRECTORY 2
-#define LOOKUP_CONTINUE 4
-#define LOOKUP_PARENT 16
-#define LOOKUP_REVAL 64
+#define LOOKUP_FOLLOW 0x0001
+#define LOOKUP_DIRECTORY 0x0002
+#define LOOKUP_CONTINUE 0x0004
+
+#define LOOKUP_PARENT 0x0010
+#define LOOKUP_REVAL 0x0020
+#define LOOKUP_RCU 0x0040
/*
* Intent data
*/
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index ef663061d5ac..1c27f201c856 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -184,13 +184,13 @@ struct ncp_entry_info {
__u8 file_handle[6];
};
-static inline struct ncp_server *NCP_SBP(struct super_block *sb)
+static inline struct ncp_server *NCP_SBP(const struct super_block *sb)
{
return sb->s_fs_info;
}
#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb)
-static inline struct ncp_inode_info *NCP_FINFO(struct inode *inode)
+static inline struct ncp_inode_info *NCP_FINFO(const struct inode *inode)
{
return container_of(inode, struct ncp_inode_info, vfs_inode);
}
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d8fd2c23a1b9..0f6b1c965815 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -493,6 +493,8 @@ static inline void napi_synchronize(const struct napi_struct *n)
enum netdev_queue_state_t {
__QUEUE_STATE_XOFF,
__QUEUE_STATE_FROZEN,
+#define QUEUE_STATE_XOFF_OR_FROZEN ((1 << __QUEUE_STATE_XOFF) | \
+ (1 << __QUEUE_STATE_FROZEN))
};
struct netdev_queue {
@@ -503,6 +505,12 @@ struct netdev_queue {
struct Qdisc *qdisc;
unsigned long state;
struct Qdisc *qdisc_sleeping;
+#ifdef CONFIG_RPS
+ struct kobject kobj;
+#endif
+#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
+ int numa_node;
+#endif
/*
* write mostly part
*/
@@ -517,6 +525,22 @@ struct netdev_queue {
u64 tx_dropped;
} ____cacheline_aligned_in_smp;
+static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
+{
+#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
+ return q->numa_node;
+#else
+ return NUMA_NO_NODE;
+#endif
+}
+
+static inline void netdev_queue_numa_node_write(struct netdev_queue *q, int node)
+{
+#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
+ q->numa_node = node;
+#endif
+}
+
#ifdef CONFIG_RPS
/*
* This structure holds an RPS map which can be of variable length. The
@@ -592,11 +616,36 @@ struct netdev_rx_queue {
struct rps_map __rcu *rps_map;
struct rps_dev_flow_table __rcu *rps_flow_table;
struct kobject kobj;
- struct netdev_rx_queue *first;
- atomic_t count;
+ struct net_device *dev;
} ____cacheline_aligned_in_smp;
#endif /* CONFIG_RPS */
+#ifdef CONFIG_XPS
+/*
+ * This structure holds an XPS map which can be of variable length. The
+ * map is an array of queues.
+ */
+struct xps_map {
+ unsigned int len;
+ unsigned int alloc_len;
+ struct rcu_head rcu;
+ u16 queues[0];
+};
+#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16)))
+#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \
+ / sizeof(u16))
+
+/*
+ * This structure holds all XPS maps for device. Maps are indexed by CPU.
+ */
+struct xps_dev_maps {
+ struct rcu_head rcu;
+ struct xps_map __rcu *cpu_map[0];
+};
+#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \
+ (nr_cpu_ids * sizeof(struct xps_map *)))
+#endif /* CONFIG_XPS */
+
/*
* This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are
@@ -683,7 +732,7 @@ struct netdev_rx_queue {
* neither operation.
*
* void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
- * If device support VLAN receive accleration
+ * If device support VLAN receive acceleration
* (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called
* when vlan groups for the device changes. Note: grp is NULL
* if no vlan's groups are being used.
@@ -951,7 +1000,7 @@ struct net_device {
#endif
void *atalk_ptr; /* AppleTalk link */
struct in_device __rcu *ip_ptr; /* IPv4 specific data */
- void *dn_ptr; /* DECnet specific data */
+ struct dn_dev __rcu *dn_ptr; /* DECnet specific data */
struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */
void *ax25_ptr; /* AX.25 specific data */
@@ -995,8 +1044,8 @@ struct net_device {
unsigned int real_num_rx_queues;
#endif
- rx_handler_func_t *rx_handler;
- void *rx_handler_data;
+ rx_handler_func_t __rcu *rx_handler;
+ void __rcu *rx_handler_data;
struct netdev_queue __rcu *ingress_queue;
@@ -1017,6 +1066,10 @@ struct net_device {
unsigned long tx_queue_len; /* Max frames per queue allowed */
spinlock_t tx_global_lock;
+#ifdef CONFIG_XPS
+ struct xps_dev_maps __rcu *xps_maps;
+#endif
+
/* These may be needed for future network-power-down code. */
/*
@@ -1307,7 +1360,8 @@ static inline struct net_device *first_net_device(struct net *net)
extern int netdev_boot_setup_check(struct net_device *dev);
extern unsigned long netdev_boot_base(const char *prefix, int unit);
-extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
+extern struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+ const char *hwaddr);
extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
extern void dev_add_pack(struct packet_type *pt);
@@ -1600,9 +1654,9 @@ static inline int netif_queue_stopped(const struct net_device *dev)
return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0));
}
-static inline int netif_tx_queue_frozen(const struct netdev_queue *dev_queue)
+static inline int netif_tx_queue_frozen_or_stopped(const struct netdev_queue *dev_queue)
{
- return test_bit(__QUEUE_STATE_FROZEN, &dev_queue->state);
+ return dev_queue->state & QUEUE_STATE_XOFF_OR_FROZEN;
}
/**
@@ -1693,6 +1747,16 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
__netif_schedule(txq->qdisc);
}
+/*
+ * Returns a Tx hash for the given packet when dev->real_num_tx_queues is used
+ * as a distribution range limit for the returned value.
+ */
+static inline u16 skb_tx_hash(const struct net_device *dev,
+ const struct sk_buff *skb)
+{
+ return __skb_tx_hash(dev, skb, dev->real_num_tx_queues);
+}
+
/**
* netif_is_multiqueue - test if device has multiple transmit queues
* @dev: network device
@@ -2239,6 +2303,8 @@ unsigned long netdev_fix_features(unsigned long features, const char *name);
void netif_stacked_transfer_operstate(const struct net_device *rootdev,
struct net_device *dev);
+int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev);
+
static inline int net_gso_ok(int features, int gso_type)
{
int feature = gso_type << NETIF_F_GSO_SHIFT;
@@ -2254,10 +2320,7 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features)
static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
{
if (skb_is_gso(skb)) {
- int features = dev->features;
-
- if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci)
- features &= dev->vlan_features;
+ int features = netif_get_vlan_features(skb, dev);
return (!skb_gso_ok(skb, features) ||
unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 03317c8d4077..1893837b3966 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -33,6 +33,8 @@
#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+#define NF_DROP_ERR(x) (((-x) << NF_VERDICT_BITS) | NF_DROP)
+
/* only for userspace compatibility */
#ifndef __KERNEL__
/* Generic cache responses from hook functions.
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 123566912d73..e2b9e63afa68 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -70,7 +70,7 @@ struct nlmsghdr {
Check NLM_F_EXCL
*/
-#define NLMSG_ALIGNTO 4
+#define NLMSG_ALIGNTO 4U
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
diff --git a/include/linux/nfs3.h b/include/linux/nfs3.h
index ac33806ec7f9..6ccfe3b641e1 100644
--- a/include/linux/nfs3.h
+++ b/include/linux/nfs3.h
@@ -11,6 +11,9 @@
#define NFS3_MAXGROUPS 16
#define NFS3_FHSIZE 64
#define NFS3_COOKIESIZE 4
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
#define NFS3_FIFO_DEV (-1)
#define NFS3MODE_FMT 0170000
#define NFS3MODE_DIR 0040000
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 4925b22219d2..26afa3021ed6 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -136,6 +136,9 @@
#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400
+#define NFS4_SECINFO_STYLE4_CURRENT_FH 0
+#define NFS4_SECINFO_STYLE4_PARENT 1
+
#define NFS4_MAX_UINT64 (~(u64)0)
/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index c66fdb7d6998..29d504d5d1c3 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations;
#endif /* CONFIG_NFS_V3 */
extern const struct file_operations nfs_file_operations;
extern const struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_dir_aops;
static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
{
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index f8b60e7f4c44..d55cee73f634 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -29,6 +29,7 @@
*/
enum {
PG_BUSY = 0,
+ PG_MAPPED,
PG_CLEAN,
PG_NEED_COMMIT,
PG_NEED_RESCHED,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 80f07198a31a..236e7e4b99a0 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -484,6 +484,7 @@ struct nfs_entry {
struct nfs_fh * fh;
struct nfs_fattr * fattr;
unsigned char d_type;
+ struct nfs_server * server;
};
/*
@@ -1089,7 +1090,7 @@ struct nfs_rpc_ops {
int (*pathconf) (struct nfs_server *, struct nfs_fh *,
struct nfs_pathconf *);
int (*set_capabilities)(struct nfs_server *, struct nfs_fh *);
- __be32 *(*decode_dirent)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int plus);
+ int (*decode_dirent)(struct xdr_stream *, struct nfs_entry *, int);
void (*read_setup) (struct nfs_read_data *, struct rpc_message *);
int (*read_done) (struct rpc_task *, struct nfs_read_data *);
void (*write_setup) (struct nfs_write_data *, struct rpc_message *);
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0edb2566c14c..2b89b712565b 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -172,10 +172,10 @@
* to the specified ISO/IEC 3166-1 alpha2 country code. The core will
* store this as a valid request and then query userspace for it.
*
- * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
* interface identified by %NL80211_ATTR_IFINDEX
*
- * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the
* interface identified by %NL80211_ATTR_IFINDEX
*
* @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
@@ -358,11 +358,16 @@
* user space application). %NL80211_ATTR_FRAME is used to specify the
* frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
* optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on
- * which channel the frame is to be transmitted or was received. This
- * channel has to be the current channel (remain-on-channel or the
- * operational channel). When called, this operation returns a cookie
- * (%NL80211_ATTR_COOKIE) that will be included with the TX status event
- * pertaining to the TX request.
+ * which channel the frame is to be transmitted or was received. If this
+ * channel is not the current channel (remain-on-channel or the
+ * operational channel) the device will switch to the given channel and
+ * transmit the frame, optionally waiting for a response for the time
+ * specified using %NL80211_ATTR_DURATION. When called, this operation
+ * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
+ * TX status event pertaining to the TX request.
+ * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
+ * command may be used with the corresponding cookie to cancel the wait
+ * time if it is known that it is no longer necessary.
* @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
* @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
* transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
@@ -389,6 +394,18 @@
*
* @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
*
+ * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial
+ * mesh config parameters may be given.
+ * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
+ * network is determined by the network interface.
+ *
+ * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
+ * notification. This event is used to indicate that an unprotected
+ * deauthentication frame was dropped when MFP is in use.
+ * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
+ * notification. This event is used to indicate that an unprotected
+ * disassociation frame was dropped when MFP is in use.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -431,8 +448,8 @@ enum nl80211_commands {
NL80211_CMD_SET_REG,
NL80211_CMD_REQ_SET_REG,
- NL80211_CMD_GET_MESH_PARAMS,
- NL80211_CMD_SET_MESH_PARAMS,
+ NL80211_CMD_GET_MESH_CONFIG,
+ NL80211_CMD_SET_MESH_CONFIG,
NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
@@ -493,6 +510,14 @@ enum nl80211_commands {
NL80211_CMD_SET_CHANNEL,
NL80211_CMD_SET_WDS_PEER,
+ NL80211_CMD_FRAME_WAIT_CANCEL,
+
+ NL80211_CMD_JOIN_MESH,
+ NL80211_CMD_LEAVE_MESH,
+
+ NL80211_CMD_UNPROT_DEAUTHENTICATE,
+ NL80211_CMD_UNPROT_DISASSOCIATE,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -513,6 +538,10 @@ enum nl80211_commands {
#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
+/* source-level API compatibility */
+#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
+#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
+
/**
* enum nl80211_attrs - nl80211 netlink attributes
*
@@ -758,6 +787,9 @@ enum nl80211_commands {
* cache, a wiphy attribute.
*
* @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32.
+ * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that
+ * specifies the maximum duration that can be requested with the
+ * remain-on-channel operation, in milliseconds, u32.
*
* @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects.
*
@@ -804,6 +836,51 @@ enum nl80211_commands {
* @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly
* means support for per-station GTKs.
*
+ * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting.
+ * This can be used to mask out antennas which are not attached or should
+ * not be used for transmitting. If an antenna is not selected in this
+ * bitmap the hardware is not allowed to transmit on this antenna.
+ *
+ * Each bit represents one antenna, starting with antenna 1 at the first
+ * bit. Depending on which antennas are selected in the bitmap, 802.11n
+ * drivers can derive which chainmasks to use (if all antennas belonging to
+ * a particular chain are disabled this chain should be disabled) and if
+ * a chain has diversity antennas wether diversity should be used or not.
+ * HT capabilities (STBC, TX Beamforming, Antenna selection) can be
+ * derived from the available chains after applying the antenna mask.
+ * Non-802.11n drivers can derive wether to use diversity or not.
+ * Drivers may reject configurations or RX/TX mask combinations they cannot
+ * support by returning -EINVAL.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving.
+ * This can be used to mask out antennas which are not attached or should
+ * not be used for receiving. If an antenna is not selected in this bitmap
+ * the hardware should not be configured to receive on this antenna.
+ * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available
+ * for configuration as TX antennas via the above parameters.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available
+ * for configuration as RX antennas via the above parameters.
+ *
+ * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
+ *
+ * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
+ * transmitted on another channel when the channel given doesn't match
+ * the current channel. If the current channel doesn't match and this
+ * flag isn't set, the frame will be rejected. This is also used as an
+ * nl80211 capability flag.
+ *
+ * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16)
+ *
+ * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ * attributes, specifying what a key should be set as default as.
+ * See &enum nl80211_key_default_types.
+ *
+ * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be
+ * changed once the mesh is active.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -858,7 +935,7 @@ enum nl80211_attrs {
NL80211_ATTR_REG_ALPHA2,
NL80211_ATTR_REG_RULES,
- NL80211_ATTR_MESH_PARAMS,
+ NL80211_ATTR_MESH_CONFIG,
NL80211_ATTR_BSS_BASIC_RATES,
@@ -973,6 +1050,24 @@ enum nl80211_attrs {
NL80211_ATTR_SUPPORT_IBSS_RSN,
+ NL80211_ATTR_WIPHY_ANTENNA_TX,
+ NL80211_ATTR_WIPHY_ANTENNA_RX,
+
+ NL80211_ATTR_MCAST_RATE,
+
+ NL80211_ATTR_OFFCHANNEL_TX_OK,
+
+ NL80211_ATTR_BSS_HT_OPMODE,
+
+ NL80211_ATTR_KEY_DEFAULT_TYPES,
+
+ NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
+
+ NL80211_ATTR_MESH_SETUP,
+
+ NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
+ NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -981,6 +1076,7 @@ enum nl80211_attrs {
/* source-level API compatibility */
#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+#define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
/*
* Allow user space programs to use #ifdef on new attributes by defining them
@@ -1139,6 +1235,7 @@ enum nl80211_rate_info {
* station)
* @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
* @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
+ * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
*/
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -1154,6 +1251,7 @@ enum nl80211_sta_info {
NL80211_STA_INFO_TX_PACKETS,
NL80211_STA_INFO_TX_RETRIES,
NL80211_STA_INFO_TX_FAILED,
+ NL80211_STA_INFO_SIGNAL_AVG,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
@@ -1307,7 +1405,11 @@ enum nl80211_bitrate_attr {
* wireless core it thinks its knows the regulatory domain we should be in.
* @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
* 802.11 country information element with regulatory information it
- * thinks we should consider.
+ * thinks we should consider. cfg80211 only processes the country
+ * code from the IE, and relies on the regulatory domain information
+ * structure pased by userspace (CRDA) from our wireless-regdb.
+ * If a channel is enabled but the country code indicates it should
+ * be disabled we disable the channel and re-enable it upon disassociation.
*/
enum nl80211_reg_initiator {
NL80211_REGDOM_SET_BY_CORE,
@@ -1476,7 +1578,8 @@ enum nl80211_mntr_flags {
/**
* enum nl80211_meshconf_params - mesh configuration parameters
*
- * Mesh configuration parameters
+ * Mesh configuration parameters. These can be changed while the mesh is
+ * active.
*
* @__NL80211_MESHCONF_INVALID: internal use
*
@@ -1525,6 +1628,9 @@ enum nl80211_mntr_flags {
*
* @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
*
+ * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
+ * source mesh point for path selection elements.
+ *
* @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
*
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1545,6 +1651,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
NL80211_MESHCONF_HWMP_ROOTMODE,
+ NL80211_MESHCONF_ELEMENT_TTL,
/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -1552,6 +1659,39 @@ enum nl80211_meshconf_params {
};
/**
+ * enum nl80211_mesh_setup_params - mesh setup parameters
+ *
+ * Mesh setup parameters. These are used to start/join a mesh and cannot be
+ * changed while the mesh is active.
+ *
+ * @__NL80211_MESH_SETUP_INVALID: Internal use
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
+ * vendor specific path selection algorithm or disable it to use the default
+ * HWMP.
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
+ * vendor specific path metric or disable it to use the default Airtime
+ * metric.
+ *
+ * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information
+ * element that vendors will use to identify the path selection methods and
+ * metrics in use.
+ *
+ * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
+ */
+enum nl80211_mesh_setup_params {
+ __NL80211_MESH_SETUP_INVALID,
+ NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
+ NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
+ NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE,
+
+ /* keep last */
+ __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
+ NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_txq_attr - TX queue parameter attributes
* @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
* @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
@@ -1709,6 +1849,23 @@ enum nl80211_wpa_versions {
};
/**
+ * enum nl80211_key_default_types - key default types
+ * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid
+ * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default
+ * unicast key
+ * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default
+ * multicast key
+ * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types
+ */
+enum nl80211_key_default_types {
+ __NL80211_KEY_DEFAULT_TYPE_INVALID,
+ NL80211_KEY_DEFAULT_TYPE_UNICAST,
+ NL80211_KEY_DEFAULT_TYPE_MULTICAST,
+
+ NUM_NL80211_KEY_DEFAULT_TYPES
+};
+
+/**
* enum nl80211_key_attributes - key attributes
* @__NL80211_KEY_INVALID: invalid
* @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
@@ -1724,6 +1881,9 @@ enum nl80211_wpa_versions {
* @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
* specified the default depends on whether a MAC address was
* given with the command using the key or not (u32)
+ * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ * attributes, specifying what a key should be set as default as.
+ * See &enum nl80211_key_default_types.
* @__NL80211_KEY_AFTER_LAST: internal
* @NL80211_KEY_MAX: highest key attribute
*/
@@ -1736,6 +1896,7 @@ enum nl80211_key_attributes {
NL80211_KEY_DEFAULT,
NL80211_KEY_DEFAULT_MGMT,
NL80211_KEY_TYPE,
+ NL80211_KEY_DEFAULT_TYPES,
/* keep last */
__NL80211_KEY_AFTER_LAST,
@@ -1786,6 +1947,8 @@ enum nl80211_ps_state {
* the minimum amount the RSSI level must change after an event before a
* new event may be issued (to reduce effects of RSSI oscillation).
* @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event
+ * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many
+ * consecutive packets were not acknowledged by the peer
* @__NL80211_ATTR_CQM_AFTER_LAST: internal
* @NL80211_ATTR_CQM_MAX: highest key attribute
*/
@@ -1794,6 +1957,7 @@ enum nl80211_attr_cqm {
NL80211_ATTR_CQM_RSSI_THOLD,
NL80211_ATTR_CQM_RSSI_HYST,
NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+ NL80211_ATTR_CQM_PKT_LOSS_EVENT,
/* keep last */
__NL80211_ATTR_CQM_AFTER_LAST,
diff --git a/include/linux/node.h b/include/linux/node.h
index 06292dac3eab..1466945cc9ef 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -10,11 +10,6 @@
*
* Nodes are exported via driverfs in the class/node/devices/
* directory.
- *
- * Per-node interfaces can be implemented using a struct device_interface.
- * See the following for how to do this:
- * - drivers/base/intf.c
- * - Documentation/driver-model/interface.txt
*/
#ifndef _LINUX_NODE_H_
#define _LINUX_NODE_H_
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 8aea06f0564c..2feda6ee6140 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -3,7 +3,7 @@
#include <linux/ioport.h>
#include <linux/of.h>
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r);
extern void __iomem *of_iomap(struct device_node *device, int index);
@@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#endif
#ifdef CONFIG_PCI
-extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
u64 *size, unsigned int *flags);
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r);
@@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
return -ENOSYS;
}
-static inline const u32 *of_get_pci_address(struct device_node *dev,
+static inline const __be32 *of_get_pci_address(struct device_node *dev,
int bar_no, u64 *size, unsigned int *flags)
{
return NULL;
diff --git a/include/linux/path.h b/include/linux/path.h
index edc98dec6266..a581e8c06533 100644
--- a/include/linux/path.h
+++ b/include/linux/path.h
@@ -10,7 +10,9 @@ struct path {
};
extern void path_get(struct path *);
+extern void path_get_long(struct path *);
extern void path_put(struct path *);
+extern void path_put_long(struct path *);
static inline int path_equal(const struct path *path1, const struct path *path2)
{
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
index 91ba0b338b47..ce6810512c66 100644
--- a/include/linux/pci-aspm.h
+++ b/include/linux/pci-aspm.h
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
+extern void pcie_clear_aspm(void);
extern void pcie_no_aspm(void);
#else
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
@@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
{
}
-
+static inline void pcie_clear_aspm(void)
+{
+}
static inline void pcie_no_aspm(void)
{
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7454408c41b6..63cbadce337e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
/* Power management related routines */
int pci_save_state(struct pci_dev *dev);
-int pci_restore_state(struct pci_dev *dev);
+void pci_restore_state(struct pci_dev *dev);
int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
@@ -1168,10 +1168,8 @@ static inline int pci_save_state(struct pci_dev *dev)
return 0;
}
-static inline int pci_restore_state(struct pci_dev *dev)
-{
- return 0;
-}
+static inline void pci_restore_state(struct pci_dev *dev)
+{ }
static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 2f17b4ccbb58..e86e3403af09 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2475,7 +2475,8 @@
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
-#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index af83076c31a6..5b7e6b1ba54f 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -309,6 +309,14 @@
#define PCI_MSIX_PBA 8
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
+/* MSI-X entry's format */
+#define PCI_MSIX_ENTRY_SIZE 16
+#define PCI_MSIX_ENTRY_LOWER_ADDR 0
+#define PCI_MSIX_ENTRY_UPPER_ADDR 4
+#define PCI_MSIX_ENTRY_DATA 8
+#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
+#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1
+
/* CompactPCI Hotswap Register */
#define PCI_CHSWP_CSR 2 /* Control and Status Register */
@@ -496,6 +504,8 @@
#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
#define PCI_EXP_RTSTA 32 /* Root Status */
+#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index de2c41758e29..4f1279e105ee 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -887,6 +887,7 @@ struct perf_cpu_context {
int exclusive;
struct list_head rotation_list;
int jiffies_interval;
+ struct pmu *active_pmu;
};
struct perf_output_handle {
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 3ec2358f8692..d19f1cca7f74 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable)
static inline bool pm_runtime_suspended(struct device *dev)
{
- return dev->power.runtime_status == RPM_SUSPENDED;
+ return dev->power.runtime_status == RPM_SUSPENDED
+ && !dev->power.disable_depth;
}
static inline void pm_runtime_mark_last_busy(struct device *dev)
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 67608161df6b..d68283a898bb 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -108,6 +108,25 @@ static inline struct posix_acl *get_cached_acl(struct inode *inode, int type)
return acl;
}
+static inline int negative_cached_acl(struct inode *inode, int type)
+{
+ struct posix_acl **p, *acl;
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ p = &inode->i_acl;
+ break;
+ case ACL_TYPE_DEFAULT:
+ p = &inode->i_default_acl;
+ break;
+ default:
+ BUG();
+ }
+ acl = ACCESS_ONCE(*p);
+ if (acl)
+ return 0;
+ return 1;
+}
+
static inline void set_cached_acl(struct inode *inode,
int type,
struct posix_acl *acl)
diff --git a/include/linux/power/gpio-charger.h b/include/linux/power/gpio-charger.h
new file mode 100644
index 000000000000..de1dfe09a03d
--- /dev/null
+++ b/include/linux/power/gpio-charger.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LINUX_POWER_GPIO_CHARGER_H__
+#define __LINUX_POWER_GPIO_CHARGER_H__
+
+#include <linux/power_supply.h>
+#include <linux/types.h>
+
+/**
+ * struct gpio_charger_platform_data - platform_data for gpio_charger devices
+ * @name: Name for the chargers power_supply device
+ * @type: Type of the charger
+ * @gpio: GPIO which is used to indicate the chargers status
+ * @gpio_active_low: Should be set to 1 if the GPIO is active low otherwise 0
+ * @supplied_to: Array of battery names to which this chargers supplies power
+ * @num_supplicants: Number of entries in the supplied_to array
+ */
+struct gpio_charger_platform_data {
+ const char *name;
+ enum power_supply_type type;
+
+ int gpio;
+ int gpio_active_low;
+
+ char **supplied_to;
+ size_t num_supplicants;
+};
+
+#endif
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
new file mode 100644
index 000000000000..41977737bb7d
--- /dev/null
+++ b/include/linux/pstore.h
@@ -0,0 +1,60 @@
+/*
+ * Persistent Storage - pstore.h
+ *
+ * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
+ *
+ * This code is the generic layer to export data records from platform
+ * level persistent storage via a file system.
+ *
+ * This program is free software; you can 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 _LINUX_PSTORE_H
+#define _LINUX_PSTORE_H
+
+/* types */
+enum pstore_type_id {
+ PSTORE_TYPE_DMESG = 0,
+ PSTORE_TYPE_MCE = 1,
+ PSTORE_TYPE_UNKNOWN = 255
+};
+
+struct pstore_info {
+ struct module *owner;
+ char *name;
+ struct mutex buf_mutex; /* serialize access to 'buf' */
+ char *buf;
+ size_t bufsize;
+ size_t (*read)(u64 *id, enum pstore_type_id *type,
+ struct timespec *time);
+ u64 (*write)(enum pstore_type_id type, size_t size);
+ int (*erase)(u64 id);
+};
+
+#ifdef CONFIG_PSTORE
+extern int pstore_register(struct pstore_info *);
+extern int pstore_write(enum pstore_type_id type, char *buf, size_t size);
+#else
+static inline int
+pstore_register(struct pstore_info *psi)
+{
+ return -ENODEV;
+}
+static inline int
+pstore_write(enum pstore_type_id type, char *buf, size_t size)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif /*_LINUX_PSTORE_H*/
diff --git a/include/linux/rculist_bl.h b/include/linux/rculist_bl.h
new file mode 100644
index 000000000000..cdfb54e73003
--- /dev/null
+++ b/include/linux/rculist_bl.h
@@ -0,0 +1,128 @@
+#ifndef _LINUX_RCULIST_BL_H
+#define _LINUX_RCULIST_BL_H
+
+/*
+ * RCU-protected bl list version. See include/linux/list_bl.h.
+ */
+#include <linux/list_bl.h>
+#include <linux/rcupdate.h>
+#include <linux/bit_spinlock.h>
+
+static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h,
+ struct hlist_bl_node *n)
+{
+ LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
+ LIST_BL_BUG_ON(!bit_spin_is_locked(0, (unsigned long *)&h->first));
+ rcu_assign_pointer(h->first,
+ (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK));
+}
+
+static inline struct hlist_bl_node *hlist_bl_first_rcu(struct hlist_bl_head *h)
+{
+ return (struct hlist_bl_node *)
+ ((unsigned long)rcu_dereference(h->first) & ~LIST_BL_LOCKMASK);
+}
+
+/**
+ * hlist_bl_del_init_rcu - deletes entry from hash list with re-initialization
+ * @n: the element to delete from the hash list.
+ *
+ * Note: hlist_bl_unhashed() on the node returns true after this. It is
+ * useful for RCU based read lockfree traversal if the writer side
+ * must know if the list entry is still hashed or already unhashed.
+ *
+ * In particular, it means that we can not poison the forward pointers
+ * that may still be used for walking the hash list and we can only
+ * zero the pprev pointer so list_unhashed() will return true after
+ * this.
+ *
+ * The caller must take whatever precautions are necessary (such as
+ * holding appropriate locks) to avoid racing with another
+ * list-mutation primitive, such as hlist_bl_add_head_rcu() or
+ * hlist_bl_del_rcu(), running on this same list. However, it is
+ * perfectly legal to run concurrently with the _rcu list-traversal
+ * primitives, such as hlist_bl_for_each_entry_rcu().
+ */
+static inline void hlist_bl_del_init_rcu(struct hlist_bl_node *n)
+{
+ if (!hlist_bl_unhashed(n)) {
+ __hlist_bl_del(n);
+ n->pprev = NULL;
+ }
+}
+
+/**
+ * hlist_bl_del_rcu - deletes entry from hash list without re-initialization
+ * @n: the element to delete from the hash list.
+ *
+ * Note: hlist_bl_unhashed() on entry does not return true after this,
+ * the entry is in an undefined state. It is useful for RCU based
+ * lockfree traversal.
+ *
+ * In particular, it means that we can not poison the forward
+ * pointers that may still be used for walking the hash list.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_bl_add_head_rcu()
+ * or hlist_bl_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_bl_for_each_entry().
+ */
+static inline void hlist_bl_del_rcu(struct hlist_bl_node *n)
+{
+ __hlist_bl_del(n);
+ n->pprev = LIST_POISON2;
+}
+
+/**
+ * hlist_bl_add_head_rcu
+ * @n: the element to add to the hash list.
+ * @h: the list to add to.
+ *
+ * Description:
+ * Adds the specified element to the specified hlist_bl,
+ * while permitting racing traversals.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_bl_add_head_rcu()
+ * or hlist_bl_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_bl_for_each_entry_rcu(), used to prevent memory-consistency
+ * problems on Alpha CPUs. Regardless of the type of CPU, the
+ * list-traversal primitive must be guarded by rcu_read_lock().
+ */
+static inline void hlist_bl_add_head_rcu(struct hlist_bl_node *n,
+ struct hlist_bl_head *h)
+{
+ struct hlist_bl_node *first;
+
+ /* don't need hlist_bl_first_rcu because we're under lock */
+ first = hlist_bl_first(h);
+
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ n->pprev = &h->first;
+
+ /* need _rcu because we can have concurrent lock free readers */
+ hlist_bl_set_first_rcu(h, n);
+}
+/**
+ * hlist_bl_for_each_entry_rcu - iterate over rcu list of given type
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_bl_node to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the hlist_bl_node within the struct.
+ *
+ */
+#define hlist_bl_for_each_entry_rcu(tpos, pos, head, member) \
+ for (pos = hlist_bl_first_rcu(head); \
+ pos && \
+ ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \
+ pos = rcu_dereference_raw(pos->next))
+
+#endif
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 08c32e4f261a..c6c608482cba 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -354,37 +354,6 @@ static inline bool rfkill_blocked(struct rfkill *rfkill)
}
#endif /* RFKILL || RFKILL_MODULE */
-
-#ifdef CONFIG_RFKILL_LEDS
-/**
- * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.
- * This function might return a NULL pointer if registering of the
- * LED trigger failed. Use this as "default_trigger" for the LED.
- */
-const char *rfkill_get_led_trigger_name(struct rfkill *rfkill);
-
-/**
- * rfkill_set_led_trigger_name -- set the LED trigger name
- * @rfkill: rfkill struct
- * @name: LED trigger name
- *
- * This function sets the LED trigger name of the radio LED
- * trigger that rfkill creates. It is optional, but if called
- * must be called before rfkill_register() to be effective.
- */
-void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name);
-#else
-static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
-{
- return NULL;
-}
-
-static inline void
-rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
-{
-}
-#endif
-
#endif /* __KERNEL__ */
#endif /* RFKILL_H */
diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h
index dbce22faa660..fbe58b7e63eb 100644
--- a/include/linux/s3c_adc_battery.h
+++ b/include/linux/s3c_adc_battery.h
@@ -14,6 +14,7 @@ struct s3c_adc_bat_pdata {
void (*disable_charger)(void);
int gpio_charge_finished;
+ int gpio_inverted;
const struct s3c_adc_bat_thresh *lut_noac;
unsigned int lut_noac_cnt;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2c79e921a68b..223874538b33 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu);
extern unsigned long this_cpu_load(void);
-extern void calc_global_load(void);
+extern void calc_global_load(unsigned long ticks);
extern unsigned long get_parent_ip(unsigned long addr);
diff --git a/include/linux/security.h b/include/linux/security.h
index fd4d55fb8845..ed95401970c7 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -457,7 +457,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* called when the actual read/write operations are performed.
* @inode contains the inode structure to check.
* @mask contains the permission mask.
- * @nd contains the nameidata (may be NULL).
* Return 0 if permission is granted.
* @inode_setattr:
* Check permission before setting file attributes. Note that the kernel
@@ -1713,6 +1712,7 @@ int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
int security_inode_readlink(struct dentry *dentry);
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
int security_inode_permission(struct inode *inode, int mask);
+int security_inode_exec_permission(struct inode *inode, unsigned int flags);
int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
int security_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2102,6 +2102,12 @@ static inline int security_inode_permission(struct inode *inode, int mask)
return 0;
}
+static inline int security_inode_exec_permission(struct inode *inode,
+ unsigned int flags)
+{
+ return 0;
+}
+
static inline int security_inode_setattr(struct dentry *dentry,
struct iattr *attr)
{
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 632205ccc25d..e98cd2e57194 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -107,7 +107,7 @@ static __always_inline int read_seqretry(const seqlock_t *sl, unsigned start)
{
smp_rmb();
- return (sl->sequence != start);
+ return unlikely(sl->sequence != start);
}
@@ -125,14 +125,25 @@ typedef struct seqcount {
#define SEQCNT_ZERO { 0 }
#define seqcount_init(x) do { *(x) = (seqcount_t) SEQCNT_ZERO; } while (0)
-/* Start of read using pointer to a sequence counter only. */
-static inline unsigned read_seqcount_begin(const seqcount_t *s)
+/**
+ * __read_seqcount_begin - begin a seq-read critical section (without barrier)
+ * @s: pointer to seqcount_t
+ * Returns: count to be passed to read_seqcount_retry
+ *
+ * __read_seqcount_begin is like read_seqcount_begin, but has no smp_rmb()
+ * barrier. Callers should ensure that smp_rmb() or equivalent ordering is
+ * provided before actually loading any of the variables that are to be
+ * protected in this critical section.
+ *
+ * Use carefully, only in critical code, and comment how the barrier is
+ * provided.
+ */
+static inline unsigned __read_seqcount_begin(const seqcount_t *s)
{
unsigned ret;
repeat:
ret = s->sequence;
- smp_rmb();
if (unlikely(ret & 1)) {
cpu_relax();
goto repeat;
@@ -140,14 +151,56 @@ repeat:
return ret;
}
-/*
- * Test if reader processed invalid data because sequence number has changed.
+/**
+ * read_seqcount_begin - begin a seq-read critical section
+ * @s: pointer to seqcount_t
+ * Returns: count to be passed to read_seqcount_retry
+ *
+ * read_seqcount_begin opens a read critical section of the given seqcount.
+ * Validity of the critical section is tested by checking read_seqcount_retry
+ * function.
+ */
+static inline unsigned read_seqcount_begin(const seqcount_t *s)
+{
+ unsigned ret = __read_seqcount_begin(s);
+ smp_rmb();
+ return ret;
+}
+
+/**
+ * __read_seqcount_retry - end a seq-read critical section (without barrier)
+ * @s: pointer to seqcount_t
+ * @start: count, from read_seqcount_begin
+ * Returns: 1 if retry is required, else 0
+ *
+ * __read_seqcount_retry is like read_seqcount_retry, but has no smp_rmb()
+ * barrier. Callers should ensure that smp_rmb() or equivalent ordering is
+ * provided before actually loading any of the variables that are to be
+ * protected in this critical section.
+ *
+ * Use carefully, only in critical code, and comment how the barrier is
+ * provided.
+ */
+static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start)
+{
+ return unlikely(s->sequence != start);
+}
+
+/**
+ * read_seqcount_retry - end a seq-read critical section
+ * @s: pointer to seqcount_t
+ * @start: count, from read_seqcount_begin
+ * Returns: 1 if retry is required, else 0
+ *
+ * read_seqcount_retry closes a read critical section of the given seqcount.
+ * If the critical section was invalid, it must be ignored (and typically
+ * retried).
*/
static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
{
smp_rmb();
- return s->sequence != start;
+ return __read_seqcount_retry(s, start);
}
@@ -167,6 +220,19 @@ static inline void write_seqcount_end(seqcount_t *s)
s->sequence++;
}
+/**
+ * write_seqcount_barrier - invalidate in-progress read-side seq operations
+ * @s: pointer to seqcount_t
+ *
+ * After write_seqcount_barrier, no read-side seq operations will complete
+ * successfully and see data older than this.
+ */
+static inline void write_seqcount_barrier(seqcount_t *s)
+{
+ smp_wmb();
+ s->sequence+=2;
+}
+
/*
* Possible sw/hw IRQ protected versions of the interfaces.
*/
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index c7a0ce11cd47..3ecb71a9e505 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -99,6 +99,13 @@
#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
+/*
+ * Access to some registers depends on register access / configuration
+ * mode.
+ */
+#define UART_LCR_CONF_MODE_A UART_LCR_DLAB /* Configutation mode A */
+#define UART_LCR_CONF_MODE_B 0xBF /* Configutation mode B */
+
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */
#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */
@@ -341,5 +348,17 @@
#define UART_OMAP_SYSS 0x16 /* System status register */
#define UART_OMAP_WER 0x17 /* Wake-up enable register */
+/*
+ * These are the definitions for the MDR1 register
+ */
+#define UART_OMAP_MDR1_16X_MODE 0x00 /* UART 16x mode */
+#define UART_OMAP_MDR1_SIR_MODE 0x01 /* SIR mode */
+#define UART_OMAP_MDR1_16X_ABAUD_MODE 0x02 /* UART 16x auto-baud */
+#define UART_OMAP_MDR1_13X_MODE 0x03 /* UART 13x mode */
+#define UART_OMAP_MDR1_MIR_MODE 0x04 /* MIR mode */
+#define UART_OMAP_MDR1_FIR_MODE 0x05 /* FIR mode */
+#define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */
+#define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */
+
#endif /* _LINUX_SERIAL_REG_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e6ba898de61c..20ec0a64cb9f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -386,9 +386,10 @@ struct sk_buff {
#else
__u8 deliver_no_wcard:1;
#endif
+ __u8 ooo_okay:1;
kmemcheck_bitfield_end(flags2);
- /* 0/14 bit hole */
+ /* 0/13 bit hole */
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
@@ -1354,6 +1355,11 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset)
}
#endif /* NET_SKBUFF_DATA_USES_OFFSET */
+static inline int skb_checksum_start_offset(const struct sk_buff *skb)
+{
+ return skb->csum_start - skb_headroom(skb);
+}
+
static inline int skb_transport_offset(const struct sk_buff *skb)
{
return skb_transport_header(skb) - skb->data;
@@ -2164,8 +2170,9 @@ static inline bool skb_rx_queue_recorded(const struct sk_buff *skb)
return skb->queue_mapping != 0;
}
-extern u16 skb_tx_hash(const struct net_device *dev,
- const struct sk_buff *skb);
+extern u16 __skb_tx_hash(const struct net_device *dev,
+ const struct sk_buff *skb,
+ unsigned int num_tx_queues);
#ifdef CONFIG_XFRM
static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 59260e21bdf5..fa9086647eb7 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -106,8 +106,6 @@ 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);
/*
* Please use this macro to create slab caches. Simply specify the
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index ebb0c80ffd6e..12b2b18e50c1 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -230,6 +230,7 @@ enum
LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
LINUX_MIB_TCPDEFERACCEPTDROP,
LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+ LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */
__LINUX_MIB_MAX
};
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 86b652fabf6e..2dccbeba1894 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -193,7 +193,8 @@ struct ucred {
#define AF_PHONET 35 /* Phonet sockets */
#define AF_IEEE802154 36 /* IEEE802154 sockets */
#define AF_CAIF 37 /* CAIF sockets */
-#define AF_MAX 38 /* For now.. */
+#define AF_ALG 38 /* Algorithm sockets */
+#define AF_MAX 39 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
@@ -234,6 +235,7 @@ struct ucred {
#define PF_PHONET AF_PHONET
#define PF_IEEE802154 AF_IEEE802154
#define PF_CAIF AF_CAIF
+#define PF_ALG AF_ALG
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */
@@ -307,6 +309,7 @@ struct ucred {
#define SOL_RDS 276
#define SOL_IUCV 277
#define SOL_CAIF 278
+#define SOL_ALG 279
/* IPX options */
#define IPX_TYPE 1
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 623b704fdc42..9659eff52ca2 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -55,6 +55,10 @@ struct ssb_sprom {
u8 tri5gl; /* 5.2GHz TX isolation */
u8 tri5g; /* 5.3GHz TX isolation */
u8 tri5gh; /* 5.8GHz TX isolation */
+ u8 txpid2g[4]; /* 2GHz TX power index */
+ u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */
+ u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */
+ u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */
u8 rxpo2g; /* 2GHz RX power offset */
u8 rxpo5g; /* 5GHz RX power offset */
u8 rssisav2g; /* 2GHz RSSI params */
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h
index 942e38736901..eba52a100533 100644
--- a/include/linux/ssb/ssb_driver_gige.h
+++ b/include/linux/ssb/ssb_driver_gige.h
@@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
return 0;
}
-extern char * nvram_get(const char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
/* Get the device MAC address */
static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
{
-#ifdef CONFIG_BCM47XX
- char *res = nvram_get("et0macaddr");
- if (res)
- memcpy(macaddr, res, 6);
-#endif
+ char buf[20];
+ if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0)
+ return;
+ nvram_parse_macaddr(buf, macaddr);
}
+#else
+static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
+{
+}
+#endif
extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
struct pci_dev *pdev);
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 11daf9c140e7..489f7b6d61c5 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -299,6 +299,46 @@
#define SSB_SPROM4_AGAIN2_SHIFT 0
#define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */
#define SSB_SPROM4_AGAIN3_SHIFT 8
+#define SSB_SPROM4_TXPID2G01 0x0062 /* TX Power Index 2GHz */
+#define SSB_SPROM4_TXPID2G0 0x00FF
+#define SSB_SPROM4_TXPID2G0_SHIFT 0
+#define SSB_SPROM4_TXPID2G1 0xFF00
+#define SSB_SPROM4_TXPID2G1_SHIFT 8
+#define SSB_SPROM4_TXPID2G23 0x0064 /* TX Power Index 2GHz */
+#define SSB_SPROM4_TXPID2G2 0x00FF
+#define SSB_SPROM4_TXPID2G2_SHIFT 0
+#define SSB_SPROM4_TXPID2G3 0xFF00
+#define SSB_SPROM4_TXPID2G3_SHIFT 8
+#define SSB_SPROM4_TXPID5G01 0x0066 /* TX Power Index 5GHz middle subband */
+#define SSB_SPROM4_TXPID5G0 0x00FF
+#define SSB_SPROM4_TXPID5G0_SHIFT 0
+#define SSB_SPROM4_TXPID5G1 0xFF00
+#define SSB_SPROM4_TXPID5G1_SHIFT 8
+#define SSB_SPROM4_TXPID5G23 0x0068 /* TX Power Index 5GHz middle subband */
+#define SSB_SPROM4_TXPID5G2 0x00FF
+#define SSB_SPROM4_TXPID5G2_SHIFT 0
+#define SSB_SPROM4_TXPID5G3 0xFF00
+#define SSB_SPROM4_TXPID5G3_SHIFT 8
+#define SSB_SPROM4_TXPID5GL01 0x006A /* TX Power Index 5GHz low subband */
+#define SSB_SPROM4_TXPID5GL0 0x00FF
+#define SSB_SPROM4_TXPID5GL0_SHIFT 0
+#define SSB_SPROM4_TXPID5GL1 0xFF00
+#define SSB_SPROM4_TXPID5GL1_SHIFT 8
+#define SSB_SPROM4_TXPID5GL23 0x006C /* TX Power Index 5GHz low subband */
+#define SSB_SPROM4_TXPID5GL2 0x00FF
+#define SSB_SPROM4_TXPID5GL2_SHIFT 0
+#define SSB_SPROM4_TXPID5GL3 0xFF00
+#define SSB_SPROM4_TXPID5GL3_SHIFT 8
+#define SSB_SPROM4_TXPID5GH01 0x006E /* TX Power Index 5GHz high subband */
+#define SSB_SPROM4_TXPID5GH0 0x00FF
+#define SSB_SPROM4_TXPID5GH0_SHIFT 0
+#define SSB_SPROM4_TXPID5GH1 0xFF00
+#define SSB_SPROM4_TXPID5GH1_SHIFT 8
+#define SSB_SPROM4_TXPID5GH23 0x0070 /* TX Power Index 5GHz high subband */
+#define SSB_SPROM4_TXPID5GH2 0x00FF
+#define SSB_SPROM4_TXPID5GH2_SHIFT 0
+#define SSB_SPROM4_TXPID5GH3 0xFF00
+#define SSB_SPROM4_TXPID5GH3_SHIFT 8
#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */
#define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
#define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index d66c61774d95..e10352915698 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -40,9 +40,9 @@ struct plat_stmmacenet_data {
int pmt;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void (*bus_setup)(void __iomem *ioaddr);
-#ifdef CONFIG_STM_DRIVERS
- struct stm_pad_config *pad_config;
-#endif
+ int (*init)(struct platform_device *pdev);
+ void (*exit)(struct platform_device *pdev);
+ void *custom_cfg;
void *bsp_priv;
};
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index b2024757edd5..8521067ed4f7 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -110,9 +110,9 @@ struct rpc_credops {
__be32 * (*crmarshal)(struct rpc_task *, __be32 *);
int (*crrefresh)(struct rpc_task *);
__be32 * (*crvalidate)(struct rpc_task *, __be32 *);
- int (*crwrap_req)(struct rpc_task *, kxdrproc_t,
+ int (*crwrap_req)(struct rpc_task *, kxdreproc_t,
void *, __be32 *, void *);
- int (*crunwrap_resp)(struct rpc_task *, kxdrproc_t,
+ int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
void *, __be32 *, void *);
};
@@ -139,8 +139,8 @@ struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *
void put_rpccred(struct rpc_cred *);
__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
-int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
-int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, __be32 *data, void *obj);
+int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj);
+int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj);
int rpcauth_refreshcred(struct rpc_task *);
void rpcauth_invalcred(struct rpc_task *);
int rpcauth_uptodatecred(struct rpc_task *);
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 6950c981882d..c2aebe8eeffd 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -255,10 +255,13 @@ static inline time_t get_expiry(char **bpp)
return rv - boot.tv_sec;
}
+#ifdef CONFIG_NFSD_DEPRECATED
static inline void sunrpc_invalidate(struct cache_head *h,
struct cache_detail *detail)
{
h->expiry_time = seconds_since_boot() - 1;
detail->nextcheck = seconds_since_boot();
}
+#endif /* CONFIG_NFSD_DEPRECATED */
+
#endif /* _LINUX_SUNRPC_CACHE_H_ */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index a5a55f284b7d..ef9476a36ff7 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -89,8 +89,8 @@ struct rpc_version {
*/
struct rpc_procinfo {
u32 p_proc; /* RPC procedure number */
- kxdrproc_t p_encode; /* XDR encode function */
- kxdrproc_t p_decode; /* XDR decode function */
+ kxdreproc_t p_encode; /* XDR encode function */
+ kxdrdproc_t p_decode; /* XDR decode function */
unsigned int p_arglen; /* argument hdr length (u32) */
unsigned int p_replen; /* reply hdr length (u32) */
unsigned int p_count; /* call count */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 5a3085b9b394..d45c482b6444 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -269,6 +269,7 @@ struct svc_rqst {
struct cache_req rq_chandle; /* handle passed to caches for
* request delaying
*/
+ bool rq_dropme;
/* Catering to nfsd */
struct auth_domain * rq_client; /* RPC peer info */
struct auth_domain * rq_gssclient; /* "gss/"-style peer info */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index aea0d438e3c7..c8f81da15c7e 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -63,7 +63,6 @@ struct svc_xprt {
#define XPT_LISTENER 11 /* listening endpoint */
#define XPT_CACHE_AUTH 12 /* cache auth info */
- struct svc_pool *xpt_pool; /* current pool iff queued */
struct svc_serv *xpt_server; /* service for transport */
atomic_t xpt_reserved; /* space on outq that is rsvd */
struct mutex xpt_mutex; /* to serialize sending data */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 498ab93a81e4..9a21e8102c42 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -33,8 +33,8 @@ struct xdr_netobj {
};
/*
- * This is the generic XDR function. rqstp is either a rpc_rqst (client
- * side) or svc_rqst pointer (server side).
+ * This is the legacy generic XDR function. rqstp is either a rpc_rqst
+ * (client side) or svc_rqst pointer (server side).
* Encode functions always assume there's enough room in the buffer.
*/
typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj);
@@ -203,6 +203,12 @@ struct xdr_stream {
struct kvec *iov; /* pointer to the current kvec */
};
+/*
+ * These are the xdr_stream style generic XDR encode and decode functions.
+ */
+typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj);
+typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj);
+
extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index 341dddb55090..2466e550a41d 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -33,7 +33,7 @@
*/
-#define TASKSTATS_VERSION 7
+#define TASKSTATS_VERSION 8
#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
* in linux/sched.h */
@@ -188,6 +188,7 @@ enum {
TASKSTATS_TYPE_STATS, /* taskstats structure */
TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */
TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */
+ TASKSTATS_TYPE_NULL, /* contains nothing */
__TASKSTATS_TYPE_MAX,
};
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 1de8b9eb841b..8651556dbd52 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -77,7 +77,7 @@ struct thermal_cooling_device {
char type[THERMAL_NAME_LENGTH];
struct device device;
void *devdata;
- struct thermal_cooling_device_ops *ops;
+ const struct thermal_cooling_device_ops *ops;
struct list_head node;
};
@@ -114,7 +114,7 @@ struct thermal_zone_device {
int last_temperature;
bool passive;
unsigned int forced_passive;
- struct thermal_zone_device_ops *ops;
+ const struct thermal_zone_device_ops *ops;
struct list_head cooling_devices;
struct idr idr;
struct mutex lock; /* protect cooling devices list */
@@ -127,13 +127,41 @@ struct thermal_zone_device {
struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */
#endif
};
+/* Adding event notification support elements */
+#define THERMAL_GENL_FAMILY_NAME "thermal_event"
+#define THERMAL_GENL_VERSION 0x01
+#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group"
+
+enum events {
+ THERMAL_AUX0,
+ THERMAL_AUX1,
+ THERMAL_CRITICAL,
+ THERMAL_DEV_FAULT,
+};
+
+struct thermal_genl_event {
+ u32 orig;
+ enum events event;
+};
+/* attributes of thermal_genl_family */
+enum {
+ THERMAL_GENL_ATTR_UNSPEC,
+ THERMAL_GENL_ATTR_EVENT,
+ __THERMAL_GENL_ATTR_MAX,
+};
+#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
+
+/* commands supported by the thermal_genl_family */
+enum {
+ THERMAL_GENL_CMD_UNSPEC,
+ THERMAL_GENL_CMD_EVENT,
+ __THERMAL_GENL_CMD_MAX,
+};
+#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
- struct
- thermal_zone_device_ops
- *, int tc1, int tc2,
- int passive_freq,
- int polling_freq);
+ const struct thermal_zone_device_ops *, int tc1, int tc2,
+ int passive_freq, int polling_freq);
void thermal_zone_device_unregister(struct thermal_zone_device *);
int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
@@ -142,9 +170,8 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
void thermal_zone_device_update(struct thermal_zone_device *);
struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
- struct
- thermal_cooling_device_ops
- *);
+ const struct thermal_cooling_device_ops *);
void thermal_cooling_device_unregister(struct thermal_cooling_device *);
+extern int generate_netlink_event(u32 orig, enum events event);
#endif /* __THERMAL_H__ */
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index d10614b29d59..1eefa3f6d1f4 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -1,6 +1,6 @@
/*
* include/linux/tipc.h: Include file for TIPC socket interface
- *
+ *
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005, Wind River Systems
* All rights reserved.
@@ -42,7 +42,7 @@
/*
* TIPC addressing primitives
*/
-
+
struct tipc_portid {
__u32 ref;
__u32 node;
@@ -89,7 +89,7 @@ static inline unsigned int tipc_node(__u32 addr)
#define TIPC_TOP_SRV 1 /* topology service name type */
#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */
-/*
+/*
* Publication scopes when binding port names and port name sequences
*/
@@ -112,7 +112,7 @@ static inline unsigned int tipc_node(__u32 addr)
#define TIPC_HIGH_IMPORTANCE 2
#define TIPC_CRITICAL_IMPORTANCE 3
-/*
+/*
* Msg rejection/connection shutdown reasons
*/
@@ -127,9 +127,9 @@ static inline unsigned int tipc_node(__u32 addr)
* TIPC topology subscription service definitions
*/
-#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
-#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
-#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */
+#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
+#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
+#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */
#if 0
/* The following filter options are not currently implemented */
#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */
@@ -137,12 +137,12 @@ static inline unsigned int tipc_node(__u32 addr)
#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */
#endif
-#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */
+#define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */
struct tipc_subscr {
struct tipc_name_seq seq; /* name sequence of interest */
__u32 timeout; /* subscription duration (in ms) */
- __u32 filter; /* bitmask of filter options */
+ __u32 filter; /* bitmask of filter options */
char usr_handle[8]; /* available for subscriber use */
};
diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h
index 9cde86c32412..7d42460a5e3c 100644
--- a/include/linux/tipc_config.h
+++ b/include/linux/tipc_config.h
@@ -1,6 +1,6 @@
/*
* include/linux/tipc_config.h: Include file for TIPC configuration interface
- *
+ *
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005-2007, Wind River Systems
* All rights reserved.
@@ -54,19 +54,19 @@
* which specify parameters or results for the operation.
*
* For many operations, the request and reply messages have a fixed number
- * of TLVs (usually zero or one); however, some reply messages may return
+ * of TLVs (usually zero or one); however, some reply messages may return
* a variable number of TLVs. A failed request is denoted by the presence
* of an "error string" TLV in the reply message instead of the TLV(s) the
* reply should contain if the request succeeds.
*/
-
-/*
+
+/*
* Public commands:
* May be issued by any process.
- * Accepted by own node, or by remote node only if remote management enabled.
+ * Accepted by own node, or by remote node only if remote management enabled.
*/
-
-#define TIPC_CMD_NOOP 0x0000 /* tx none, rx none */
+
+#define TIPC_CMD_NOOP 0x0000 /* tx none, rx none */
#define TIPC_CMD_GET_NODES 0x0001 /* tx net_addr, rx node_info(s) */
#define TIPC_CMD_GET_MEDIA_NAMES 0x0002 /* tx none, rx media_name(s) */
#define TIPC_CMD_GET_BEARER_NAMES 0x0003 /* tx none, rx bearer_name(s) */
@@ -83,21 +83,21 @@
#define TIPC_CMD_GET_LINK_PEER 0x000D /* tx link_name, rx ? */
#endif
-/*
+/*
* Protected commands:
* May only be issued by "network administration capable" process.
* Accepted by own node, or by remote node only if remote management enabled
- * and this node is zone manager.
+ * and this node is zone manager.
*/
#define TIPC_CMD_GET_REMOTE_MNG 0x4003 /* tx none, rx unsigned */
#define TIPC_CMD_GET_MAX_PORTS 0x4004 /* tx none, rx unsigned */
#define TIPC_CMD_GET_MAX_PUBL 0x4005 /* tx none, rx unsigned */
#define TIPC_CMD_GET_MAX_SUBSCR 0x4006 /* tx none, rx unsigned */
-#define TIPC_CMD_GET_MAX_ZONES 0x4007 /* tx none, rx unsigned */
-#define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* tx none, rx unsigned */
+#define TIPC_CMD_GET_MAX_ZONES 0x4007 /* obsoleted */
+#define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* obsoleted */
#define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */
-#define TIPC_CMD_GET_MAX_SLAVES 0x400A /* tx none, rx unsigned */
+#define TIPC_CMD_GET_MAX_SLAVES 0x400A /* obsoleted */
#define TIPC_CMD_GET_NETID 0x400B /* tx none, rx unsigned */
#define TIPC_CMD_ENABLE_BEARER 0x4101 /* tx bearer_config, rx none */
@@ -116,10 +116,10 @@
#define TIPC_CMD_UNBLOCK_LINK 0x4106 /* tx link_name, rx none */
#endif
-/*
+/*
* Private commands:
* May only be issued by "network administration capable" process.
- * Accepted by own node only; cannot be used on a remote node.
+ * Accepted by own node only; cannot be used on a remote node.
*/
#define TIPC_CMD_SET_NODE_ADDR 0x8001 /* tx net_addr, rx none */
@@ -130,10 +130,10 @@
#define TIPC_CMD_SET_MAX_PORTS 0x8004 /* tx unsigned, rx none */
#define TIPC_CMD_SET_MAX_PUBL 0x8005 /* tx unsigned, rx none */
#define TIPC_CMD_SET_MAX_SUBSCR 0x8006 /* tx unsigned, rx none */
-#define TIPC_CMD_SET_MAX_ZONES 0x8007 /* tx unsigned, rx none */
-#define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* tx unsigned, rx none */
+#define TIPC_CMD_SET_MAX_ZONES 0x8007 /* obsoleted */
+#define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* obsoleted */
#define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */
-#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */
+#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* obsoleted */
#define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */
/*
@@ -156,20 +156,20 @@
#define TIPC_TLV_ULTRA_STRING 5 /* char[32768] (max) */
#define TIPC_TLV_ERROR_STRING 16 /* char[128] containing "error code" */
-#define TIPC_TLV_NET_ADDR 17 /* 32-bit integer denoting <Z.C.N> */
+#define TIPC_TLV_NET_ADDR 17 /* 32-bit integer denoting <Z.C.N> */
#define TIPC_TLV_MEDIA_NAME 18 /* char[TIPC_MAX_MEDIA_NAME] */
#define TIPC_TLV_BEARER_NAME 19 /* char[TIPC_MAX_BEARER_NAME] */
#define TIPC_TLV_LINK_NAME 20 /* char[TIPC_MAX_LINK_NAME] */
#define TIPC_TLV_NODE_INFO 21 /* struct tipc_node_info */
#define TIPC_TLV_LINK_INFO 22 /* struct tipc_link_info */
-#define TIPC_TLV_BEARER_CONFIG 23 /* struct tipc_bearer_config */
-#define TIPC_TLV_LINK_CONFIG 24 /* struct tipc_link_config */
+#define TIPC_TLV_BEARER_CONFIG 23 /* struct tipc_bearer_config */
+#define TIPC_TLV_LINK_CONFIG 24 /* struct tipc_link_config */
#define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */
-#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */
+#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */
/*
* Maximum sizes of TIPC bearer-related names (including terminating NUL)
- */
+ */
#define TIPC_MAX_MEDIA_NAME 16 /* format = media */
#define TIPC_MAX_IF_NAME 16 /* format = interface */
@@ -234,7 +234,7 @@ struct tipc_name_table_query {
};
/*
- * The error string TLV is a null-terminated string describing the cause
+ * The error string TLV is a null-terminated string describing the cause
* of the request failure. To simplify error processing (and to save space)
* the first character of the string can be a special error code character
* (lying by the range 0x80 to 0xFF) which represents a pre-defined reason.
@@ -254,16 +254,11 @@ struct tipc_link_create {
struct tipc_media_addr peer_addr;
char bearer_name[TIPC_MAX_BEARER_NAME];
};
-
-struct tipc_route_info {
- __u32 dest;
- __u32 router;
-};
#endif
/*
* A TLV consists of a descriptor, followed by the TLV value.
- * TLV descriptor fields are stored in network byte order;
+ * TLV descriptor fields are stored in network byte order;
* TLV values must also be stored in network byte order (where applicable).
* TLV descriptors must be aligned to addresses which are multiple of 4,
* so up to 3 bytes of padding may exist at the end of the TLV value area.
@@ -299,7 +294,7 @@ static inline int TLV_OK(const void *tlv, __u16 space)
static inline int TLV_CHECK(const void *tlv, __u16 space, __u16 exp_type)
{
- return TLV_OK(tlv, space) &&
+ return TLV_OK(tlv, space) &&
(ntohs(((struct tlv_desc *)tlv)->tlv_type) == exp_type);
}
@@ -318,7 +313,7 @@ static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len)
}
/*
- * A TLV list descriptor simplifies processing of messages
+ * A TLV list descriptor simplifies processing of messages
* containing multiple TLVs.
*/
@@ -327,15 +322,15 @@ struct tlv_list_desc {
__u32 tlv_space; /* # bytes from curr TLV to list end */
};
-static inline void TLV_LIST_INIT(struct tlv_list_desc *list,
+static inline void TLV_LIST_INIT(struct tlv_list_desc *list,
void *data, __u32 space)
{
list->tlv_ptr = (struct tlv_desc *)data;
list->tlv_space = space;
}
-
+
static inline int TLV_LIST_EMPTY(struct tlv_list_desc *list)
-{
+{
return (list->tlv_space == 0);
}
@@ -353,7 +348,7 @@ static inline void TLV_LIST_STEP(struct tlv_list_desc *list)
{
__u16 tlv_space = TLV_ALIGN(ntohs(list->tlv_ptr->tlv_len));
- list->tlv_ptr = (struct tlv_desc *)((char *)list->tlv_ptr + tlv_space);
+ list->tlv_ptr = (struct tlv_desc *)((char *)list->tlv_ptr + tlv_space);
list->tlv_space -= tlv_space;
}
@@ -377,15 +372,14 @@ struct tipc_genlmsghdr {
#define TIPC_GENL_HDRLEN NLMSG_ALIGN(sizeof(struct tipc_genlmsghdr))
/*
- * Configuration messages exchanged via TIPC sockets use the TIPC configuration
- * message header, which is defined below. This structure is analogous
- * to the Netlink message header, but fields are stored in network byte order
- * and no padding is permitted between the header and the message data
+ * Configuration messages exchanged via TIPC sockets use the TIPC configuration
+ * message header, which is defined below. This structure is analogous
+ * to the Netlink message header, but fields are stored in network byte order
+ * and no padding is permitted between the header and the message data
* that follows.
*/
-struct tipc_cfg_msg_hdr
-{
+struct tipc_cfg_msg_hdr {
__be32 tcm_len; /* Message length (including header) */
__be16 tcm_type; /* Command type */
__be16 tcm_flags; /* Additional flags */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 032d79ff1d9d..54e4eaaa0561 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -366,6 +366,7 @@ struct tty_file_private {
#define TTY_HUPPED 18 /* Post driver->hangup() */
#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
+#define TTY_HUPPING 21 /* ->hangup() in progress */
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index 05f7fed2b173..d28c726ede4f 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -104,6 +104,7 @@ struct uinput_ff_erase {
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
+#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
index d6188e5a52df..665517c05eaf 100644
--- a/include/linux/uio_driver.h
+++ b/include/linux/uio_driver.h
@@ -3,7 +3,7 @@
*
* Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
* Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
* Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
*
* Userspace IO driver.
diff --git a/include/linux/unaligned/packed_struct.h b/include/linux/unaligned/packed_struct.h
index 2498bb9fe002..c9a6abd972a1 100644
--- a/include/linux/unaligned/packed_struct.h
+++ b/include/linux/unaligned/packed_struct.h
@@ -3,9 +3,9 @@
#include <linux/kernel.h>
-struct __una_u16 { u16 x __attribute__((packed)); };
-struct __una_u32 { u32 x __attribute__((packed)); };
-struct __una_u64 { u64 x __attribute__((packed)); };
+struct __una_u16 { u16 x; } __attribute__((packed));
+struct __una_u32 { u32 x; } __attribute__((packed));
+struct __una_u64 { u64 x; } __attribute__((packed));
static inline u16 __get_unaligned_cpu16(const void *p)
{
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 24300d8a1bc1..a28eb2592577 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -313,6 +313,10 @@ struct usb_bus {
int busnum; /* Bus number (in order of reg) */
const char *bus_name; /* stable id (PCI slot_name etc) */
u8 uses_dma; /* Does the host controller use DMA? */
+ u8 uses_pio_for_control; /*
+ * Does the host controller use PIO
+ * for control transfers?
+ */
u8 otg_port; /* 0, or number of OTG/HNP port */
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 7ae27a473818..44842c8d38c0 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -97,6 +97,12 @@ struct driver_info {
#define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */
+/*
+ * Indicates to usbnet, that USB driver accumulates multiple IP packets.
+ * Affects statistic (counters) and short packet handling.
+ */
+#define FLAG_MULTI_PACKET 0x1000
+
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
diff --git a/include/linux/video_output.h b/include/linux/video_output.h
index 2fb46bc9340d..ed5cdeb3604d 100644
--- a/include/linux/video_output.h
+++ b/include/linux/video_output.h
@@ -23,6 +23,7 @@
#ifndef _LINUX_VIDEO_OUTPUT_H
#define _LINUX_VIDEO_OUTPUT_H
#include <linux/device.h>
+#include <linux/err.h>
struct output_device;
struct output_properties {
int (*set_state)(struct output_device *);
@@ -34,9 +35,23 @@ struct output_device {
struct device dev;
};
#define to_output_device(obj) container_of(obj, struct output_device, dev)
+#if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
struct output_device *video_output_register(const char *name,
struct device *dev,
void *devdata,
struct output_properties *op);
void video_output_unregister(struct output_device *dev);
+#else
+static struct output_device *video_output_register(const char *name,
+ struct device *dev,
+ void *devdata,
+ struct output_properties *op)
+{
+ return ERR_PTR(-ENODEV);
+}
+static void video_output_unregister(struct output_device *dev)
+{
+ return;
+}
+#endif
#endif
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index a03dcf62ca9d..44b54f619ac6 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -7,8 +7,6 @@
struct vm_area_struct; /* vma defining user mapping in mm_types.h */
-extern bool vmap_lazy_unmap;
-
/* bits in flags of vmalloc's vm_struct below */
#define VM_IOREMAP 0x00000001 /* ioremap() and friends */
#define VM_ALLOC 0x00000002 /* vmalloc() */
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 4f902e1908aa..bebb8efea0a6 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,6 +24,14 @@
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
+/* The board reference clock values */
+enum {
+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
+ WL12XX_REFCLOCK_54 = 3, /* 54 MHz */
+};
+
struct wl12xx_platform_data {
void (*set_power)(bool enable);
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b971e3848493..930fdd2de79c 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -283,6 +283,7 @@ enum xfrm_attr_type_t {
XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */
XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
XFRMA_MARK, /* struct xfrm_mark */
+ XFRMA_TFCPAD, /* __u32 */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/media/bt819.h b/include/media/bt819.h
index 38f666bde77a..8025f4bc2bb6 100644
--- a/include/media/bt819.h
+++ b/include/media/bt819.h
@@ -26,7 +26,10 @@
/* v4l2_device notifications. */
/* Needed to reset the FIFO buffer when changing the input
- or the video standard. */
+ or the video standard.
+
+ Note: these ioctls that internal to the kernel and are never called
+ from userspace. */
#define BT819_FIFO_RESET_LOW _IO('b', 0)
#define BT819_FIFO_RESET_HIGH _IO('b', 1)
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index 8d08ebfe20b7..9635eebaab09 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -95,7 +95,7 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
const struct cx2341x_mpeg_params *new);
int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
struct v4l2_queryctrl *qctrl);
-const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id);
+const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id);
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
struct v4l2_ext_controls *ctrls, unsigned int cmd);
void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
deleted file mode 100644
index 528050e39ad9..000000000000
--- a/include/media/ir-common.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or 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 _IR_COMMON
-#define _IR_COMMON
-
-#include <linux/input.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <media/ir-core.h>
-
-#define RC5_START(x) (((x)>>12)&3)
-#define RC5_TOGGLE(x) (((x)>>11)&1)
-#define RC5_ADDR(x) (((x)>>6)&31)
-#define RC5_INSTR(x) ((x)&63)
-
-struct ir_input_state {
- /* configuration */
- u64 ir_type;
-
- /* key info */
- u32 ir_key; /* ir scancode */
- u32 keycode; /* linux key code */
- int keypressed; /* current state */
-};
-
-/* this was saa7134_ir and bttv_ir, moved here for
- * rc5 decoding. */
-struct card_ir {
- struct input_dev *dev;
- struct ir_input_state ir;
- char name[32];
- char phys[32];
- int users;
-
- u32 running:1;
- struct ir_dev_props props;
-
- /* Usual gpio signalling */
-
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
- u32 polling;
- u32 last_gpio;
- int shift_by;
- int start; // What should RC5_START() be
- int addr; // What RC5_ADDR() should be.
- int rc5_key_timeout;
- int rc5_remote_gap;
- struct work_struct work;
- struct timer_list timer;
-
- /* RC5 gpio */
- u32 rc5_gpio;
- struct timer_list timer_end; /* timer_end for code completion */
- struct timer_list timer_keyup; /* timer_end for key release */
- u32 last_rc5; /* last good rc5 code */
- u32 last_bit; /* last raw bit seen */
- u32 code; /* raw code under construction */
- struct timeval base_time; /* time of last seen code */
- int active; /* building raw code */
-
- /* NEC decoding */
- u32 nec_gpio;
- struct tasklet_struct tlet;
-
- /* IR core raw decoding */
- u32 raw_decode;
-};
-
-/* Routines from ir-functions.c */
-
-int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
- const u64 ir_type);
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
- u32 ir_key);
-u32 ir_extract_bits(u32 data, u32 mask);
-int ir_dump_samples(u32 *samples, int count);
-int ir_decode_biphase(u32 *samples, int count, int low, int high);
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
-u32 ir_rc5_decode(unsigned int code);
-
-void ir_rc5_timer_end(unsigned long data);
-void ir_rc5_timer_keyup(unsigned long data);
-
-#endif
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
deleted file mode 100644
index 6dc37fae6606..000000000000
--- a/include/media/ir-core.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Remote Controller core header
- *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _IR_CORE
-#define _IR_CORE
-
-#include <linux/spinlock.h>
-#include <linux/kfifo.h>
-#include <linux/time.h>
-#include <linux/timer.h>
-#include <media/rc-map.h>
-
-extern int ir_core_debug;
-#define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt , __func__, ## arg)
-
-enum rc_driver_type {
- RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
- RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */
-};
-
-/**
- * struct ir_dev_props - Allow caller drivers to set special properties
- * @driver_type: specifies if the driver or hardware have already a decoder,
- * or if it needs to use the IR raw event decoders to produce a scancode
- * @allowed_protos: bitmask with the supported IR_TYPE_* protocols
- * @scanmask: some hardware decoders are not capable of providing the full
- * scancode to the application. As this is a hardware limit, we can't do
- * anything with it. Yet, as the same keycode table can be used with other
- * devices, a mask is provided to allow its usage. Drivers should generally
- * leave this field in blank
- * @timeout: optional time after which device stops sending data
- * @min_timeout: minimum timeout supported by device
- * @max_timeout: maximum timeout supported by device
- * @rx_resolution : resolution (in ns) of input sampler
- * @tx_resolution: resolution (in ns) of output sampler
- * @priv: driver-specific data, to be used on the callbacks
- * @change_protocol: allow changing the protocol used on hardware decoders
- * @open: callback to allow drivers to enable polling/irq when IR input device
- * is opened.
- * @close: callback to allow drivers to disable polling/irq when IR input device
- * is opened.
- * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
- * @s_tx_carrier: set transmit carrier frequency
- * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
- * @s_rx_carrier: inform driver about carrier it is expected to handle
- * @tx_ir: transmit IR
- * @s_idle: optional: enable/disable hardware idle mode, upon which,
- device doesn't interrupt host until it sees IR pulses
- * @s_learning_mode: enable wide band receiver used for learning
- * @s_carrier_report: enable carrier reports
- */
-struct ir_dev_props {
- enum rc_driver_type driver_type;
- unsigned long allowed_protos;
- u32 scanmask;
-
- u32 timeout;
- u32 min_timeout;
- u32 max_timeout;
-
- u32 rx_resolution;
- u32 tx_resolution;
-
- void *priv;
- int (*change_protocol)(void *priv, u64 ir_type);
- int (*open)(void *priv);
- void (*close)(void *priv);
- int (*s_tx_mask)(void *priv, u32 mask);
- int (*s_tx_carrier)(void *priv, u32 carrier);
- int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
- int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
- int (*tx_ir)(void *priv, int *txbuf, u32 n);
- void (*s_idle)(void *priv, bool enable);
- int (*s_learning_mode)(void *priv, int enable);
- int (*s_carrier_report) (void *priv, int enable);
-};
-
-struct ir_input_dev {
- struct device dev; /* device */
- char *driver_name; /* Name of the driver module */
- struct ir_scancode_table rc_tab; /* scan/key table */
- unsigned long devno; /* device number */
- struct ir_dev_props *props; /* Device properties */
- struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */
- struct input_dev *input_dev; /* the input device associated with this device */
- bool idle;
-
- /* key info - needed by IR keycode handlers */
- spinlock_t keylock; /* protects the below members */
- bool keypressed; /* current state */
- unsigned long keyup_jiffies; /* when should the current keypress be released? */
- struct timer_list timer_keyup; /* timer for releasing a keypress */
- u32 last_keycode; /* keycode of last command */
- u32 last_scancode; /* scancode of last command */
- u8 last_toggle; /* toggle of last command */
-};
-
-enum raw_event_type {
- IR_SPACE = (1 << 0),
- IR_PULSE = (1 << 1),
- IR_START_EVENT = (1 << 2),
- IR_STOP_EVENT = (1 << 3),
-};
-
-#define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr)
-
-/* From ir-keytable.c */
-int __ir_input_register(struct input_dev *dev,
- const struct ir_scancode_table *ir_codes,
- struct ir_dev_props *props,
- const char *driver_name);
-
-static inline int ir_input_register(struct input_dev *dev,
- const char *map_name,
- struct ir_dev_props *props,
- const char *driver_name) {
- struct ir_scancode_table *ir_codes;
- struct ir_input_dev *ir_dev;
- int rc;
-
- if (!map_name)
- return -EINVAL;
-
- ir_codes = get_rc_map(map_name);
- if (!ir_codes) {
- ir_codes = get_rc_map(RC_MAP_EMPTY);
-
- if (!ir_codes)
- return -EINVAL;
- }
-
- rc = __ir_input_register(dev, ir_codes, props, driver_name);
- if (rc < 0)
- return -EINVAL;
-
- ir_dev = input_get_drvdata(dev);
-
- if (!rc && ir_dev->props && ir_dev->props->change_protocol)
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- ir_codes->ir_type);
-
- return rc;
-}
-
-void ir_input_unregister(struct input_dev *input_dev);
-
-void ir_repeat(struct input_dev *dev);
-void ir_keydown(struct input_dev *dev, int scancode, u8 toggle);
-void ir_keyup(struct ir_input_dev *ir);
-u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
-
-/* From ir-raw-event.c */
-
-struct ir_raw_event {
- union {
- u32 duration;
-
- struct {
- u32 carrier;
- u8 duty_cycle;
- };
- };
-
- unsigned pulse:1;
- unsigned reset:1;
- unsigned timeout:1;
- unsigned carrier_report:1;
-};
-
-#define DEFINE_IR_RAW_EVENT(event) \
- struct ir_raw_event event = { \
- { .duration = 0 } , \
- .pulse = 0, \
- .reset = 0, \
- .timeout = 0, \
- .carrier_report = 0 }
-
-static inline void init_ir_raw_event(struct ir_raw_event *ev)
-{
- memset(ev, 0, sizeof(*ev));
-}
-
-#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
-
-void ir_raw_event_handle(struct input_dev *input_dev);
-int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
-int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
-int ir_raw_event_store_with_filter(struct input_dev *input_dev,
- struct ir_raw_event *ev);
-void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle);
-
-static inline void ir_raw_event_reset(struct input_dev *input_dev)
-{
- DEFINE_IR_RAW_EVENT(ev);
- ev.reset = true;
-
- ir_raw_event_store(input_dev, &ev);
- ir_raw_event_handle(input_dev);
-}
-
-#endif /* _IR_CORE */
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 557c676ab7dc..768aa77925cd 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -1,7 +1,7 @@
#ifndef _IR_I2C
#define _IR_I2C
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#define DEFAULT_POLLING_INTERVAL 100 /* ms */
@@ -9,11 +9,9 @@ struct IR_i2c;
struct IR_i2c {
char *ir_codes;
-
struct i2c_client *c;
- struct input_dev *input;
- struct ir_input_state ir;
- u64 ir_type;
+ struct rc_dev *rc;
+
/* Used to avoid fast repeating */
unsigned char old;
@@ -39,13 +37,16 @@ enum ir_kbd_get_key_fn {
struct IR_i2c_init_data {
char *ir_codes;
const char *name;
- u64 type; /* IR_TYPE_RC5, etc */
+ u64 type; /* RC_TYPE_RC5, etc */
u32 polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */
+
/*
* Specify either a function pointer or a value indicating one of
* ir_kbd_i2c's internal get_key functions
*/
int (*get_key)(struct IR_i2c*, u32*, u32*);
enum ir_kbd_get_key_fn internal_get_key_func;
+
+ struct rc_dev *rc_dev;
};
#endif
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
index 54780a560d0e..630e702c9511 100644
--- a/include/media/lirc_dev.h
+++ b/include/media/lirc_dev.h
@@ -217,9 +217,9 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file);
int lirc_dev_fop_close(struct inode *inode, struct file *file);
unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait);
long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-ssize_t lirc_dev_fop_read(struct file *file, char *buffer, size_t length,
+ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length,
loff_t *ppos);
-ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, size_t length,
- loff_t *ppos);
+ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer,
+ size_t length, loff_t *ppos);
#endif
diff --git a/include/media/ovcamchip.h b/include/media/ovcamchip.h
deleted file mode 100644
index 05b9569ef1c8..000000000000
--- a/include/media/ovcamchip.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* OmniVision* camera chip driver API
- *
- * Copyright (c) 1999-2004 Mark McClelland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
- *
- * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver
- * is not sponsored or developed by them.
- */
-
-#ifndef __LINUX_OVCAMCHIP_H
-#define __LINUX_OVCAMCHIP_H
-
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-
-/* --------------------------------- */
-/* ENUMERATIONS */
-/* --------------------------------- */
-
-/* Controls */
-enum {
- OVCAMCHIP_CID_CONT, /* Contrast */
- OVCAMCHIP_CID_BRIGHT, /* Brightness */
- OVCAMCHIP_CID_SAT, /* Saturation */
- OVCAMCHIP_CID_HUE, /* Hue */
- OVCAMCHIP_CID_EXP, /* Exposure */
- OVCAMCHIP_CID_FREQ, /* Light frequency */
- OVCAMCHIP_CID_BANDFILT, /* Banding filter */
- OVCAMCHIP_CID_AUTOBRIGHT, /* Auto brightness */
- OVCAMCHIP_CID_AUTOEXP, /* Auto exposure */
- OVCAMCHIP_CID_BACKLIGHT, /* Back light compensation */
- OVCAMCHIP_CID_MIRROR, /* Mirror horizontally */
-};
-
-/* Chip types */
-#define NUM_CC_TYPES 9
-enum {
- CC_UNKNOWN,
- CC_OV76BE,
- CC_OV7610,
- CC_OV7620,
- CC_OV7620AE,
- CC_OV6620,
- CC_OV6630,
- CC_OV6630AE,
- CC_OV6630AF,
-};
-
-/* --------------------------------- */
-/* I2C ADDRESSES */
-/* --------------------------------- */
-
-#define OV7xx0_SID (0x42 >> 1)
-#define OV6xx0_SID (0xC0 >> 1)
-
-/* --------------------------------- */
-/* API */
-/* --------------------------------- */
-
-struct ovcamchip_control {
- __u32 id;
- __s32 value;
-};
-
-struct ovcamchip_window {
- int x;
- int y;
- int width;
- int height;
- int format;
- int quarter; /* Scale width and height down 2x */
-
- /* This stuff will be removed eventually */
- int clockdiv; /* Clock divisor setting */
-};
-
-/* Commands */
-#define OVCAMCHIP_CMD_Q_SUBTYPE _IOR (0x88, 0x00, int)
-#define OVCAMCHIP_CMD_INITIALIZE _IOW (0x88, 0x01, int)
-/* You must call OVCAMCHIP_CMD_INITIALIZE before any of commands below! */
-#define OVCAMCHIP_CMD_S_CTRL _IOW (0x88, 0x02, struct ovcamchip_control)
-#define OVCAMCHIP_CMD_G_CTRL _IOWR (0x88, 0x03, struct ovcamchip_control)
-#define OVCAMCHIP_CMD_S_MODE _IOW (0x88, 0x04, struct ovcamchip_window)
-#define OVCAMCHIP_MAX_CMD _IO (0x88, 0x3f)
-
-#endif
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
new file mode 100644
index 000000000000..a23c1fc685a1
--- /dev/null
+++ b/include/media/rc-core.h
@@ -0,0 +1,220 @@
+/*
+ * Remote Controller core header
+ *
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _RC_CORE
+#define _RC_CORE
+
+#include <linux/spinlock.h>
+#include <linux/kfifo.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <media/rc-map.h>
+
+extern int rc_core_debug;
+#define IR_dprintk(level, fmt, arg...) if (rc_core_debug >= level) \
+ printk(KERN_DEBUG "%s: " fmt , __func__, ## arg)
+
+enum rc_driver_type {
+ RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
+ RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */
+};
+
+/**
+ * struct rc_dev - represents a remote control device
+ * @dev: driver model's view of this device
+ * @input_name: name of the input child device
+ * @input_phys: physical path to the input child device
+ * @input_id: id of the input child device (struct input_id)
+ * @driver_name: name of the hardware driver which registered this device
+ * @map_name: name of the default keymap
+ * @rc_map: current scan/key table
+ * @devno: unique remote control device number
+ * @raw: additional data for raw pulse/space devices
+ * @input_dev: the input child device used to communicate events to userspace
+ * @driver_type: specifies if protocol decoding is done in hardware or software
+ * @idle: used to keep track of RX state
+ * @allowed_protos: bitmask with the supported RC_TYPE_* protocols
+ * @scanmask: some hardware decoders are not capable of providing the full
+ * scancode to the application. As this is a hardware limit, we can't do
+ * anything with it. Yet, as the same keycode table can be used with other
+ * devices, a mask is provided to allow its usage. Drivers should generally
+ * leave this field in blank
+ * @priv: driver-specific data
+ * @keylock: protects the remaining members of the struct
+ * @keypressed: whether a key is currently pressed
+ * @keyup_jiffies: time (in jiffies) when the current keypress should be released
+ * @timer_keyup: timer for releasing a keypress
+ * @last_keycode: keycode of last keypress
+ * @last_scancode: scancode of last keypress
+ * @last_toggle: toggle value of last command
+ * @timeout: optional time after which device stops sending data
+ * @min_timeout: minimum timeout supported by device
+ * @max_timeout: maximum timeout supported by device
+ * @rx_resolution : resolution (in ns) of input sampler
+ * @tx_resolution: resolution (in ns) of output sampler
+ * @change_protocol: allow changing the protocol used on hardware decoders
+ * @open: callback to allow drivers to enable polling/irq when IR input device
+ * is opened.
+ * @close: callback to allow drivers to disable polling/irq when IR input device
+ * is opened.
+ * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
+ * @s_tx_carrier: set transmit carrier frequency
+ * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
+ * @s_rx_carrier: inform driver about carrier it is expected to handle
+ * @tx_ir: transmit IR
+ * @s_idle: enable/disable hardware idle mode, upon which,
+ * device doesn't interrupt host until it sees IR pulses
+ * @s_learning_mode: enable wide band receiver used for learning
+ * @s_carrier_report: enable carrier reports
+ */
+struct rc_dev {
+ struct device dev;
+ const char *input_name;
+ const char *input_phys;
+ struct input_id input_id;
+ char *driver_name;
+ const char *map_name;
+ struct rc_map rc_map;
+ unsigned long devno;
+ struct ir_raw_event_ctrl *raw;
+ struct input_dev *input_dev;
+ enum rc_driver_type driver_type;
+ bool idle;
+ u64 allowed_protos;
+ u32 scanmask;
+ void *priv;
+ spinlock_t keylock;
+ bool keypressed;
+ unsigned long keyup_jiffies;
+ struct timer_list timer_keyup;
+ u32 last_keycode;
+ u32 last_scancode;
+ u8 last_toggle;
+ u32 timeout;
+ u32 min_timeout;
+ u32 max_timeout;
+ u32 rx_resolution;
+ u32 tx_resolution;
+ int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+ int (*open)(struct rc_dev *dev);
+ void (*close)(struct rc_dev *dev);
+ int (*s_tx_mask)(struct rc_dev *dev, u32 mask);
+ int (*s_tx_carrier)(struct rc_dev *dev, u32 carrier);
+ int (*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle);
+ int (*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max);
+ int (*tx_ir)(struct rc_dev *dev, int *txbuf, u32 n);
+ void (*s_idle)(struct rc_dev *dev, bool enable);
+ int (*s_learning_mode)(struct rc_dev *dev, int enable);
+ int (*s_carrier_report) (struct rc_dev *dev, int enable);
+};
+
+#define to_rc_dev(d) container_of(d, struct rc_dev, dev)
+
+/*
+ * From rc-main.c
+ * Those functions can be used on any type of Remote Controller. They
+ * basically creates an input_dev and properly reports the device as a
+ * Remote Controller, at sys/class/rc.
+ */
+
+struct rc_dev *rc_allocate_device(void);
+void rc_free_device(struct rc_dev *dev);
+int rc_register_device(struct rc_dev *dev);
+void rc_unregister_device(struct rc_dev *dev);
+
+void rc_repeat(struct rc_dev *dev);
+void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle);
+void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle);
+void rc_keyup(struct rc_dev *dev);
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
+
+/*
+ * From rc-raw.c
+ * The Raw interface is specific to InfraRed. It may be a good idea to
+ * split it later into a separate header.
+ */
+
+enum raw_event_type {
+ IR_SPACE = (1 << 0),
+ IR_PULSE = (1 << 1),
+ IR_START_EVENT = (1 << 2),
+ IR_STOP_EVENT = (1 << 3),
+};
+
+struct ir_raw_event {
+ union {
+ u32 duration;
+
+ struct {
+ u32 carrier;
+ u8 duty_cycle;
+ };
+ };
+
+ unsigned pulse:1;
+ unsigned reset:1;
+ unsigned timeout:1;
+ unsigned carrier_report:1;
+};
+
+#define DEFINE_IR_RAW_EVENT(event) \
+ struct ir_raw_event event = { \
+ { .duration = 0 } , \
+ .pulse = 0, \
+ .reset = 0, \
+ .timeout = 0, \
+ .carrier_report = 0 }
+
+static inline void init_ir_raw_event(struct ir_raw_event *ev)
+{
+ memset(ev, 0, sizeof(*ev));
+}
+
+#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
+
+void ir_raw_event_handle(struct rc_dev *dev);
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type);
+int ir_raw_event_store_with_filter(struct rc_dev *dev,
+ struct ir_raw_event *ev);
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
+
+static inline void ir_raw_event_reset(struct rc_dev *dev)
+{
+ DEFINE_IR_RAW_EVENT(ev);
+ ev.reset = true;
+
+ ir_raw_event_store(dev, &ev);
+ ir_raw_event_handle(dev);
+}
+
+/* extract mask bits out of data and pack them into the result */
+static inline u32 ir_extract_bits(u32 data, u32 mask)
+{
+ u32 vbit = 1, value = 0;
+
+ do {
+ if (mask & 1) {
+ if (data & 1)
+ value |= vbit;
+ vbit <<= 1;
+ }
+ data >>= 1;
+ } while (mask >>= 1);
+
+ return value;
+}
+
+#endif /* _RC_CORE */
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index e0f17edf38ed..ee9e2f747c76 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -11,45 +11,45 @@
#include <linux/input.h>
-#define IR_TYPE_UNKNOWN 0
-#define IR_TYPE_RC5 (1 << 0) /* Philips RC5 protocol */
-#define IR_TYPE_NEC (1 << 1)
-#define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
-#define IR_TYPE_JVC (1 << 3) /* JVC protocol */
-#define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
-#define IR_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */
-#define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */
-#define IR_TYPE_OTHER (1u << 31)
+#define RC_TYPE_UNKNOWN 0
+#define RC_TYPE_RC5 (1 << 0) /* Philips RC5 protocol */
+#define RC_TYPE_NEC (1 << 1)
+#define RC_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
+#define RC_TYPE_JVC (1 << 3) /* JVC protocol */
+#define RC_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
+#define RC_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */
+#define RC_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */
+#define RC_TYPE_OTHER (1u << 31)
-#define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \
- IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \
- IR_TYPE_RC5_SZ | IR_TYPE_OTHER)
+#define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC | RC_TYPE_RC6 | \
+ RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \
+ RC_TYPE_RC5_SZ | RC_TYPE_OTHER)
-struct ir_scancode {
+struct rc_map_table {
u32 scancode;
u32 keycode;
};
-struct ir_scancode_table {
- struct ir_scancode *scan;
+struct rc_map {
+ struct rc_map_table *scan;
unsigned int size; /* Max number of entries */
unsigned int len; /* Used number of entries */
unsigned int alloc; /* Size of *scan in bytes */
- u64 ir_type;
+ u64 rc_type;
const char *name;
spinlock_t lock;
};
-struct rc_keymap {
+struct rc_map_list {
struct list_head list;
- struct ir_scancode_table map;
+ struct rc_map map;
};
/* Routines from rc-map.c */
-int ir_register_map(struct rc_keymap *map);
-void ir_unregister_map(struct rc_keymap *map);
-struct ir_scancode_table *get_rc_map(const char *name);
+int rc_map_register(struct rc_map_list *map);
+void rc_map_unregister(struct rc_map_list *map);
+struct rc_map *rc_map_get(const char *name);
void rc_map_init(void);
/* Names of the several keytables defined in-kernel */
@@ -119,6 +119,7 @@ void rc_map_init(void);
#define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd"
#define RC_MAP_PIXELVIEW_NEW "rc-pixelview-new"
#define RC_MAP_PIXELVIEW "rc-pixelview"
+#define RC_MAP_PIXELVIEW_002T "rc-pixelview-002t"
#define RC_MAP_PIXELVIEW_MK12 "rc-pixelview-mk12"
#define RC_MAP_POWERCOLOR_REAL_ANGEL "rc-powercolor-real-angel"
#define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
@@ -137,6 +138,7 @@ void rc_map_init(void);
#define RC_MAP_TREKSTOR "rc-trekstor"
#define RC_MAP_TT_1500 "rc-tt-1500"
#define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027"
+#define RC_MAP_VIDEOMATE_M1F "rc-videomate-m1f"
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
#define RC_MAP_WINFAST "rc-winfast"
diff --git a/include/media/rds.h b/include/media/saa6588.h
index a89426667618..2c3c4420a4eb 100644
--- a/include/media/rds.h
+++ b/include/media/saa6588.h
@@ -4,9 +4,6 @@
saa6588.c and every driver (e.g. bttv-driver.c) that wants
to use the saa6588 module.
- Instead of having a separate rds.h, I'd prefer to include
- this stuff in one of the already existing files like tuner.h
-
(c) 2005 by Hans J. Koch
This program is free software; you can redistribute it and/or modify
@@ -25,10 +22,10 @@
*/
-#ifndef _RDS_H
-#define _RDS_H
+#ifndef _SAA6588_H
+#define _SAA6588_H
-struct rds_command {
+struct saa6588_command {
unsigned int block_count;
int result;
unsigned char __user *buffer;
@@ -36,9 +33,10 @@ struct rds_command {
poll_table *event_list;
};
-#define RDS_CMD_OPEN _IOW('R',1,int)
-#define RDS_CMD_CLOSE _IOW('R',2,int)
-#define RDS_CMD_READ _IOR('R',3,int)
-#define RDS_CMD_POLL _IOR('R',4,int)
+/* These ioctls are internal to the kernel */
+#define SAA6588_CMD_OPEN _IOW('R', 1, int)
+#define SAA6588_CMD_CLOSE _IOW('R', 2, int)
+#define SAA6588_CMD_READ _IOR('R', 3, int)
+#define SAA6588_CMD_POLL _IOR('R', 4, int)
#endif
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 7a9f76ecbbbd..ac7ce00f39cf 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -161,7 +161,7 @@ extern struct list_head saa7146_devices;
extern struct mutex saa7146_devices_lock;
int saa7146_register_extension(struct saa7146_extension*);
int saa7146_unregister_extension(struct saa7146_extension*);
-struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc);
+struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc);
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
diff --git a/include/media/si4713.h b/include/media/si4713.h
index 99850a54ed09..ed7353e8a982 100644
--- a/include/media/si4713.h
+++ b/include/media/si4713.h
@@ -23,8 +23,7 @@
* Platform dependent definition
*/
struct si4713_platform_data {
- /* Set power state, zero is off, non-zero is on. */
- int (*set_power)(int power);
+ int gpio_reset; /* < 0 if not used */
};
/*
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 86e3631764ef..9386db829fb7 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -97,6 +97,7 @@ struct soc_camera_host_ops {
#define SOCAM_SENSOR_INVERT_DATA (1 << 4)
struct i2c_board_info;
+struct regulator_bulk_data;
struct soc_camera_link {
/* Camera bus id, used to match a camera and a bus */
@@ -108,6 +109,10 @@ struct soc_camera_link {
const char *module_name;
void *priv;
+ /* Optional regulators that have to be managed on power on/off events */
+ struct regulator_bulk_data *regulators;
+ int num_regulators;
+
/*
* For non-I2C devices platform platform has to provide methods to
* add a device to the system and to remove
diff --git a/include/media/timb_radio.h b/include/media/timb_radio.h
index fcd32a3696ba..a59a84854dc1 100644
--- a/include/media/timb_radio.h
+++ b/include/media/timb_radio.h
@@ -24,7 +24,6 @@
struct timb_radio_platform_data {
int i2c_adapter; /* I2C adapter where the tuner and dsp are attached */
struct {
- const char *module_name;
struct i2c_board_info *info;
} tuner;
struct {
diff --git a/include/media/timb_video.h b/include/media/timb_video.h
new file mode 100644
index 000000000000..70ae43970a49
--- /dev/null
+++ b/include/media/timb_video.h
@@ -0,0 +1,33 @@
+/*
+ * timb_video.h Platform struct for the Timberdale video driver
+ * 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.
+ */
+
+#ifndef _TIMB_VIDEO_
+#define _TIMB_VIDEO_ 1
+
+#include <linux/i2c.h>
+
+struct timb_video_platform_data {
+ int dma_channel;
+ int i2c_adapter; /* The I2C adapter where the encoder is attached */
+ struct {
+ const char *module_name;
+ struct i2c_board_info *info;
+ } encoder;
+};
+
+#endif
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 51e89f2267b8..44fe44ec9ea7 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -74,6 +74,7 @@ enum {
V4L2_IDENT_SOI968 = 256,
V4L2_IDENT_OV9640 = 257,
V4L2_IDENT_OV6650 = 258,
+ V4L2_IDENT_OV2640 = 259,
/* module saa7146: reserved range 300-309 */
V4L2_IDENT_SAA7146 = 300,
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 41dd480e45f1..2d65b35cdab2 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -98,12 +98,12 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
/* Control helper functions */
int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
- const char **menu_items);
+ const char * const *menu_items);
const char *v4l2_ctrl_get_name(u32 id);
-const char **v4l2_ctrl_get_menu(u32 id);
+const char * const *v4l2_ctrl_get_menu(u32 id);
int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def);
int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu,
- struct v4l2_queryctrl *qctrl, const char **menu_items);
+ struct v4l2_queryctrl *qctrl, const char * const *menu_items);
#define V4L2_CTRL_MENU_IDS_END (0xffffffff)
int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids);
@@ -137,31 +137,27 @@ struct v4l2_subdev_ops;
/* Load an i2c module and return an initialized v4l2_subdev struct.
- Only call request_module if module_name != NULL.
The client_type argument is the name of the chip that's on the adapter. */
struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter,
- const char *module_name, const char *client_type,
+ struct i2c_adapter *adapter, const char *client_type,
int irq, void *platform_data,
u8 addr, const unsigned short *probe_addrs);
/* Load an i2c module and return an initialized v4l2_subdev struct.
- Only call request_module if module_name != NULL.
The client_type argument is the name of the chip that's on the adapter. */
static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter,
- const char *module_name, const char *client_type,
+ struct i2c_adapter *adapter, const char *client_type,
u8 addr, const unsigned short *probe_addrs)
{
- return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name,
- client_type, 0, NULL, addr, probe_addrs);
+ return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, client_type, 0, NULL,
+ addr, probe_addrs);
}
struct i2c_board_info;
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter, const char *module_name,
- struct i2c_board_info *info, const unsigned short *probe_addrs);
+ struct i2c_adapter *adapter, struct i2c_board_info *info,
+ const unsigned short *probe_addrs);
/* Initialize an v4l2_subdev with data from an i2c_client struct */
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 9b7bea928a88..d69ab4aae032 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -112,7 +112,7 @@ struct v4l2_ctrl {
u32 step;
u32 menu_skip_mask;
};
- const char **qmenu;
+ const char * const *qmenu;
unsigned long flags;
union {
s32 val;
@@ -202,7 +202,7 @@ struct v4l2_ctrl_config {
s32 def;
u32 flags;
u32 menu_skip_mask;
- const char **qmenu;
+ const char * const *qmenu;
unsigned int is_private:1;
unsigned int is_volatile:1;
};
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 6648036b728d..b16f307d471a 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -51,6 +51,8 @@ struct v4l2_device {
unsigned int notification, void *arg);
/* The control handler. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
+ /* BKL replacement mutex. Temporary solution only. */
+ struct mutex ioctl_lock;
};
/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 06daa6e8e051..67df37542c68 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -14,12 +14,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/compiler.h> /* need __user */
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-#define __MIN_V4L1
-#include <linux/videodev.h>
-#else
#include <linux/videodev2.h>
-#endif
struct v4l2_fh;
@@ -113,10 +108,6 @@ struct v4l2_ioctl_ops {
int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* buffer type is struct vidio_mbuf * */
- int (*vidiocgmbuf) (struct file *file, void *fh, struct video_mbuf *p);
-#endif
int (*vidioc_g_fbuf) (struct file *file, void *fh,
struct v4l2_framebuffer *a);
int (*vidioc_s_fbuf) (struct file *file, void *fh,
@@ -300,22 +291,15 @@ extern void v4l_printk_ioctl(unsigned int cmd);
extern const char *v4l2_field_names[];
extern const char *v4l2_type_names[];
-/* Compatibility layer interface -- v4l1-compat module */
-typedef long (*v4l2_kioctl)(struct file *file,
- unsigned int cmd, void *arg);
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-long v4l_compat_translate_ioctl(struct file *file,
- int cmd, void *arg, v4l2_kioctl driver_ioctl);
-#else
-#define v4l_compat_translate_ioctl(file, cmd, arg, ioctl) (-EINVAL)
-#endif
-
#ifdef CONFIG_COMPAT
/* 32 Bits compatibility layer for 64 bits processors */
extern long v4l2_compat_ioctl32(struct file *file, unsigned int cmd,
unsigned long arg);
#endif
+typedef long (*v4l2_kioctl)(struct file *file,
+ unsigned int cmd, void *arg);
+
/* Include support for obsoleted stuff */
extern long video_usercopy(struct file *file, unsigned int cmd,
unsigned long arg, v4l2_kioctl func);
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 1d3835fc26be..90ed895e217d 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -17,10 +17,6 @@
#define _VIDEOBUF_CORE_H
#include <linux/poll.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-#define __MIN_V4L1
-#include <linux/videodev.h>
-#endif
#include <linux/videodev2.h>
#define UNSET (-1U)
@@ -212,10 +208,6 @@ int videobuf_qbuf(struct videobuf_queue *q,
struct v4l2_buffer *b);
int videobuf_dqbuf(struct videobuf_queue *q,
struct v4l2_buffer *b, int nonblocking);
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-int videobuf_cgmbuf(struct videobuf_queue *q,
- struct video_mbuf *mbuf, int count);
-#endif
int videobuf_streamon(struct videobuf_queue *q);
int videobuf_streamoff(struct videobuf_queue *q);
diff --git a/include/media/wm8775.h b/include/media/wm8775.h
index a1c4d417dfa2..60739c5a23ae 100644
--- a/include/media/wm8775.h
+++ b/include/media/wm8775.h
@@ -32,7 +32,4 @@
#define WM8775_AIN3 4
#define WM8775_AIN4 8
-/* subdev group ID */
-#define WM8775_GID (1 << 0)
-
#endif
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index a9441249306c..23710aa6a181 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -1,8 +1,6 @@
#ifndef _ADDRCONF_H
#define _ADDRCONF_H
-#define RETRANS_TIMER HZ
-
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index d81ea7997701..0c5e72503b77 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -144,6 +144,7 @@ struct bt_skb_cb {
__u8 tx_seq;
__u8 retries;
__u8 sar;
+ unsigned short channel;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e30e00834340..29a7a8ca0438 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1,4 +1,4 @@
-/*
+/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
@@ -12,13 +12,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
@@ -489,7 +489,7 @@ struct hci_rp_read_local_name {
#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18
-#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
+#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
#define SCAN_DISABLED 0x00
#define SCAN_INQUIRY 0x01
#define SCAN_PAGE 0x02
@@ -874,7 +874,7 @@ struct hci_ev_si_security {
struct hci_command_hdr {
__le16 opcode; /* OCF & OGF */
- __u8 plen;
+ __u8 plen;
} __packed;
struct hci_event_hdr {
@@ -934,9 +934,13 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev;
+ unsigned short hci_channel;
};
#define HCI_DEV_NONE 0xffff
+#define HCI_CHANNEL_RAW 0
+#define HCI_CHANNEL_CONTROL 1
+
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebec8c9a929d..a29feb01854e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -44,15 +44,15 @@ struct inquiry_data {
};
struct inquiry_entry {
- struct inquiry_entry *next;
+ struct inquiry_entry *next;
__u32 timestamp;
struct inquiry_data data;
};
struct inquiry_cache {
- spinlock_t lock;
+ spinlock_t lock;
__u32 timestamp;
- struct inquiry_entry *list;
+ struct inquiry_entry *list;
};
struct hci_conn_hash {
@@ -129,6 +129,7 @@ struct hci_dev {
wait_queue_head_t req_wait_q;
__u32 req_status;
__u32 req_result;
+ __u16 req_last_cmd;
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
@@ -141,7 +142,7 @@ struct hci_dev {
void *driver_data;
void *core_data;
- atomic_t promisc;
+ atomic_t promisc;
struct dentry *debugfs;
@@ -150,7 +151,7 @@ struct hci_dev {
struct rfkill *rfkill;
- struct module *owner;
+ struct module *owner;
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
@@ -215,8 +216,8 @@ extern rwlock_t hci_dev_list_lock;
extern rwlock_t hci_cb_list_lock;
/* ----- Inquiry cache ----- */
-#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
-#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
+#define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */
+#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */
#define inquiry_cache_lock(c) spin_lock(&c->lock)
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
@@ -660,6 +661,11 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+/* Management interface */
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+int mgmt_index_added(u16 index);
+int mgmt_index_removed(u16 index);
+
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
@@ -668,6 +674,7 @@ struct hci_pinfo {
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
+ unsigned short channel;
};
/* HCI security filter */
@@ -687,6 +694,6 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
-void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
#endif /* __HCI_CORE_H */
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c819c8bf9b68..7ad25ca60ec0 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -1,4 +1,4 @@
-/*
+/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
@@ -14,13 +14,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
@@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk)
return sub == pi->remote_tx_win;
}
-#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
-#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
-#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)
-#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
-#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
+#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
+#define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)
+#define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE))
+#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
+#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
void l2cap_load(void);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
new file mode 100644
index 000000000000..ca29c1367ffd
--- /dev/null
+++ b/include/net/bluetooth/mgmt.h
@@ -0,0 +1,87 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+
+ Copyright (C) 2010 Nokia Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ 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 OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+struct mgmt_hdr {
+ __le16 opcode;
+ __le16 len;
+} __packed;
+#define MGMT_HDR_SIZE 4
+
+#define MGMT_OP_READ_VERSION 0x0001
+struct mgmt_rp_read_version {
+ __u8 version;
+ __le16 revision;
+} __packed;
+
+#define MGMT_OP_READ_INDEX_LIST 0x0003
+struct mgmt_rp_read_index_list {
+ __le16 num_controllers;
+ __le16 index[0];
+} __packed;
+
+#define MGMT_OP_READ_INFO 0x0004
+struct mgmt_cp_read_info {
+ __le16 index;
+} __packed;
+struct mgmt_rp_read_info {
+ __le16 index;
+ __u8 type;
+ __u8 powered;
+ __u8 discoverable;
+ __u8 pairable;
+ __u8 sec_mode;
+ bdaddr_t bdaddr;
+ __u8 dev_class[3];
+ __u8 features[8];
+ __u16 manufacturer;
+ __u8 hci_ver;
+ __u16 hci_rev;
+} __packed;
+
+#define MGMT_EV_CMD_COMPLETE 0x0001
+struct mgmt_ev_cmd_complete {
+ __le16 opcode;
+ __u8 data[0];
+} __packed;
+
+#define MGMT_EV_CMD_STATUS 0x0002
+struct mgmt_ev_cmd_status {
+ __u8 status;
+ __le16 opcode;
+} __packed;
+
+#define MGMT_EV_CONTROLLER_ERROR 0x0003
+struct mgmt_ev_controller_error {
+ __le16 index;
+ __u8 error_code;
+} __packed;
+
+#define MGMT_EV_INDEX_ADDED 0x0004
+struct mgmt_ev_index_added {
+ __le16 index;
+} __packed;
+
+#define MGMT_EV_INDEX_REMOVED 0x0005
+struct mgmt_ev_index_removed {
+ __le16 index;
+} __packed;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 71047bc0af84..6eac4a760c3b 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -1,5 +1,5 @@
-/*
- RFCOMM implementation for Linux Bluetooth stack (BlueZ).
+/*
+ RFCOMM implementation for Linux Bluetooth stack (BlueZ)
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
@@ -11,13 +11,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
@@ -105,7 +105,7 @@
struct rfcomm_hdr {
u8 addr;
u8 ctrl;
- u8 len; // Actual size can be 2 bytes
+ u8 len; /* Actual size can be 2 bytes */
} __packed;
struct rfcomm_cmd {
@@ -228,7 +228,7 @@ struct rfcomm_dlc {
/* ---- RFCOMM SEND RPN ---- */
int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
u8 bit_rate, u8 data_bits, u8 stop_bits,
- u8 parity, u8 flow_ctrl_settings,
+ u8 parity, u8 flow_ctrl_settings,
u8 xon_char, u8 xoff_char, u16 param_mask);
/* ---- RFCOMM DLCs (channels) ---- */
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index e28a2a771471..1e35c43657c8 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -1,4 +1,4 @@
-/*
+/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
@@ -12,13 +12,13 @@
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
@@ -55,11 +55,11 @@ struct sco_conninfo {
struct sco_conn {
struct hci_conn *hcon;
- bdaddr_t *dst;
- bdaddr_t *src;
-
+ bdaddr_t *dst;
+ bdaddr_t *src;
+
spinlock_t lock;
- struct sock *sk;
+ struct sock *sk;
unsigned int mtu;
};
diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h
index 9402543fc20d..e54f6396fa4c 100644
--- a/include/net/caif/cfctrl.h
+++ b/include/net/caif/cfctrl.h
@@ -51,7 +51,7 @@ struct cfctrl_rsp {
void (*restart_rsp)(void);
void (*radioset_rsp)(void);
void (*reject_rsp)(struct cflayer *layer, u8 linkid,
- struct cflayer *client_layer);;
+ struct cflayer *client_layer);
};
/* Link Setup Parameters for CAIF-Links. */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 97b8b7c9b63c..bcc9f448ec4e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -258,13 +258,9 @@ struct ieee80211_supported_band {
/**
* struct vif_params - describes virtual interface parameters
- * @mesh_id: mesh ID to use
- * @mesh_id_len: length of the mesh ID
* @use_4addr: use 4-address frames
*/
struct vif_params {
- u8 *mesh_id;
- int mesh_id_len;
int use_4addr;
};
@@ -424,6 +420,7 @@ struct station_parameters {
* @STATION_INFO_TX_RETRIES: @tx_retries filled
* @STATION_INFO_TX_FAILED: @tx_failed filled
* @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
+ * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -439,6 +436,7 @@ enum station_info_flags {
STATION_INFO_TX_RETRIES = 1<<10,
STATION_INFO_TX_FAILED = 1<<11,
STATION_INFO_RX_DROP_MISC = 1<<12,
+ STATION_INFO_SIGNAL_AVG = 1<<13,
};
/**
@@ -485,6 +483,7 @@ struct rate_info {
* @plid: mesh peer link id
* @plink_state: mesh peer link state
* @signal: signal strength of last received packet in dBm
+ * @signal_avg: signal strength average in dBm
* @txrate: current unicast bitrate to this station
* @rx_packets: packets received from this station
* @tx_packets: packets transmitted to this station
@@ -505,6 +504,7 @@ struct station_info {
u16 plid;
u8 plink_state;
s8 signal;
+ s8 signal_avg;
struct rate_info txrate;
u32 rx_packets;
u32 tx_packets;
@@ -605,6 +605,8 @@ struct mpath_info {
* (or NULL for no change)
* @basic_rates_len: number of basic rates
* @ap_isolate: do not forward packets between connected stations
+ * @ht_opmode: HT Operation mode
+ * (u16 = opmode, -1 = do not change)
*/
struct bss_parameters {
int use_cts_prot;
@@ -613,8 +615,14 @@ struct bss_parameters {
u8 *basic_rates;
u8 basic_rates_len;
int ap_isolate;
+ int ht_opmode;
};
+/*
+ * struct mesh_config - 802.11s mesh configuration
+ *
+ * These parameters can be changed while the mesh is active.
+ */
struct mesh_config {
/* Timeouts in ms */
/* Mesh plink management parameters */
@@ -624,6 +632,8 @@ struct mesh_config {
u16 dot11MeshMaxPeerLinks;
u8 dot11MeshMaxRetries;
u8 dot11MeshTTL;
+ /* ttl used in path selection information elements */
+ u8 element_ttl;
bool auto_open_plinks;
/* HWMP parameters */
u8 dot11MeshHWMPmaxPREQretries;
@@ -636,6 +646,26 @@ struct mesh_config {
};
/**
+ * struct mesh_setup - 802.11s mesh setup configuration
+ * @mesh_id: the mesh ID
+ * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
+ * @path_sel_proto: which path selection protocol to use
+ * @path_metric: which metric to use
+ * @vendor_ie: vendor information elements (optional)
+ * @vendor_ie_len: length of vendor information elements
+ *
+ * These parameters are fixed when the mesh is created.
+ */
+struct mesh_setup {
+ const u8 *mesh_id;
+ u8 mesh_id_len;
+ u8 path_sel_proto;
+ u8 path_metric;
+ const u8 *vendor_ie;
+ u8 vendor_ie_len;
+};
+
+/**
* struct ieee80211_txq_params - TX queue parameters
* @queue: TX queue identifier (NL80211_TXQ_Q_*)
* @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled
@@ -923,6 +953,7 @@ struct cfg80211_disassoc_request {
* @privacy: this is a protected network, keys will be configured
* after joining
* @basic_rates: bitmap of basic rates to use when creating the IBSS
+ * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
*/
struct cfg80211_ibss_params {
u8 *ssid;
@@ -934,6 +965,7 @@ struct cfg80211_ibss_params {
u32 basic_rates;
bool channel_fixed;
bool privacy;
+ int mcast_rate[IEEE80211_NUM_BANDS];
};
/**
@@ -1029,7 +1061,8 @@ struct cfg80211_pmksa {
*
* @add_virtual_intf: create a new virtual interface with the given name,
* must set the struct wireless_dev's iftype. Beware: You must create
- * the new netdev in the wiphy's network namespace!
+ * the new netdev in the wiphy's network namespace! Returns the netdev,
+ * or an ERR_PTR.
*
* @del_virtual_intf: remove the virtual interface determined by ifindex.
*
@@ -1071,9 +1104,9 @@ struct cfg80211_pmksa {
* @get_mpath: get a mesh path for the given parameters
* @dump_mpath: dump mesh path callback -- resume dump at index @idx
*
- * @get_mesh_params: Put the current mesh parameters into *params
+ * @get_mesh_config: Get the current mesh configuration
*
- * @set_mesh_params: Set mesh parameters.
+ * @update_mesh_config: Update mesh parameters on a running mesh.
* The mask is a bitfield which tells us which parameters to
* set, and which to leave alone.
*
@@ -1132,7 +1165,9 @@ struct cfg80211_pmksa {
* @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.
* This allows the operation to be terminated prior to timeout based on
* the duration value.
- * @mgmt_tx: Transmit a management frame
+ * @mgmt_tx: Transmit a management frame.
+ * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
+ * frame on another channel
*
* @testmode_cmd: run a test mode command
*
@@ -1150,14 +1185,23 @@ struct cfg80211_pmksa {
* @mgmt_frame_register: Notify driver that a management frame type was
* registered. Note that this callback may not sleep, and cannot run
* concurrently with itself.
+ *
+ * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.
+ * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may
+ * reject TX/RX mask combinations they cannot support by returning -EINVAL
+ * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).
+ *
+ * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
int (*resume)(struct wiphy *wiphy);
- int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params);
+ struct net_device * (*add_virtual_intf)(struct wiphy *wiphy,
+ char *name,
+ enum nl80211_iftype type,
+ u32 *flags,
+ struct vif_params *params);
int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev);
int (*change_virtual_intf)(struct wiphy *wiphy,
struct net_device *dev,
@@ -1175,7 +1219,7 @@ struct cfg80211_ops {
u8 key_index, bool pairwise, const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev,
- u8 key_index);
+ u8 key_index, bool unicast, bool multicast);
int (*set_default_mgmt_key)(struct wiphy *wiphy,
struct net_device *netdev,
u8 key_index);
@@ -1210,12 +1254,17 @@ struct cfg80211_ops {
int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
int idx, u8 *dst, u8 *next_hop,
struct mpath_info *pinfo);
- int (*get_mesh_params)(struct wiphy *wiphy,
+ int (*get_mesh_config)(struct wiphy *wiphy,
struct net_device *dev,
struct mesh_config *conf);
- int (*set_mesh_params)(struct wiphy *wiphy,
- struct net_device *dev,
- const struct mesh_config *nconf, u32 mask);
+ int (*update_mesh_config)(struct wiphy *wiphy,
+ struct net_device *dev, u32 mask,
+ const struct mesh_config *nconf);
+ int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
+ const struct mesh_config *conf,
+ const struct mesh_setup *setup);
+ int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev);
+
int (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
struct bss_parameters *params);
@@ -1289,10 +1338,13 @@ struct cfg80211_ops {
u64 cookie);
int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
- bool channel_type_valid,
+ bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, u64 *cookie);
+ int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
+ struct net_device *dev,
+ u64 cookie);
int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
bool enabled, int timeout);
@@ -1304,6 +1356,9 @@ struct cfg80211_ops {
void (*mgmt_frame_register)(struct wiphy *wiphy,
struct net_device *dev,
u16 frame_type, bool reg);
+
+ int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
+ int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
};
/*
@@ -1321,13 +1376,14 @@ struct cfg80211_ops {
* initiator is %REGDOM_SET_BY_CORE).
* @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will
* ignore regulatory domain settings until it gets its own regulatory
- * domain via its regulatory_hint(). After its gets its own regulatory
- * domain it will only allow further regulatory domain settings to
- * further enhance compliance. For example if channel 13 and 14 are
- * disabled by this regulatory domain no user regulatory domain can
- * enable these channels at a later time. This can be used for devices
- * which do not have calibration information gauranteed for frequencies
- * or settings outside of its regulatory domain.
+ * domain via its regulatory_hint() unless the regulatory hint is
+ * from a country IE. After its gets its own regulatory domain it will
+ * only allow further regulatory domain settings to further enhance
+ * compliance. For example if channel 13 and 14 are disabled by this
+ * regulatory domain no user regulatory domain can enable these channels
+ * at a later time. This can be used for devices which do not have
+ * calibration information guaranteed for frequencies or settings
+ * outside of its regulatory domain.
* @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
* that passive scan flags and beaconing flags may not be lifted by
* cfg80211 due to regulatory beacon hints. For more information on beacon
@@ -1345,6 +1401,8 @@ struct cfg80211_ops {
* control port protocol ethertype. The device also honours the
* control_port_no_encrypt flag.
* @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
+ * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
+ * unicast and multicast TX keys.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1356,6 +1414,7 @@ enum wiphy_flags {
WIPHY_FLAG_4ADDR_STATION = BIT(6),
WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
WIPHY_FLAG_IBSS_RSN = BIT(8),
+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
};
struct mac_address {
@@ -1368,7 +1427,9 @@ struct ieee80211_txrx_stypes {
/**
* struct wiphy - wireless hardware description
- * @reg_notifier: the driver's regulatory notification callback
+ * @reg_notifier: the driver's regulatory notification callback,
+ * note that if your driver uses wiphy_apply_custom_regulatory()
+ * the reg_notifier's request can be passed as NULL
* @regd: the driver's regulatory domain, if one was requested via
* the regulatory_hint() API. This can be used by the driver
* on the reg_notifier() if it chooses to ignore future
@@ -1420,6 +1481,17 @@ struct ieee80211_txrx_stypes {
* @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or
* transmitted through nl80211, points to an array indexed by interface
* type
+ *
+ * @available_antennas_tx: bitmap of antennas which are available to be
+ * configured as TX antennas. Antenna configuration commands will be
+ * rejected unless this or @available_antennas_rx is set.
+ *
+ * @available_antennas_rx: bitmap of antennas which are available to be
+ * configured as RX antennas. Antenna configuration commands will be
+ * rejected unless this or @available_antennas_tx is set.
+ *
+ * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
+ * may request, if implemented.
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1457,8 +1529,13 @@ struct wiphy {
char fw_version[ETHTOOL_BUSINFO_LEN];
u32 hw_version;
+ u16 max_remain_on_channel_duration;
+
u8 max_num_pmkids;
+ u32 available_antennas_tx;
+ u32 available_antennas_rx;
+
/* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered
@@ -1624,6 +1701,8 @@ struct cfg80211_cached_keys;
* @bssid: (private) Used by the internal configuration code
* @ssid: (private) Used by the internal configuration code
* @ssid_len: (private) Used by the internal configuration code
+ * @mesh_id_len: (private) Used by the internal configuration code
+ * @mesh_id_up_len: (private) Used by the internal configuration code
* @wext: (private) Used by the internal wireless extensions compat code
* @use_4addr: indicates 4addr mode is used on this interface, must be
* set by driver (if supported) on add_interface BEFORE registering the
@@ -1653,7 +1732,7 @@ struct wireless_dev {
/* currently used for IBSS and SME - might be rearranged later */
u8 ssid[IEEE80211_MAX_SSID_LEN];
- u8 ssid_len;
+ u8 ssid_len, mesh_id_len, mesh_id_up_len;
enum {
CFG80211_SME_IDLE,
CFG80211_SME_CONNECTING,
@@ -2297,6 +2376,32 @@ void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf,
size_t len);
/**
+ * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
+ * @dev: network device
+ * @buf: deauthentication frame (header + body)
+ * @len: length of the frame data
+ *
+ * This function is called whenever a received Deauthentication frame has been
+ * dropped in station mode because of MFP being used but the Deauthentication
+ * frame was not protected. This function may sleep.
+ */
+void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
+ size_t len);
+
+/**
+ * cfg80211_send_unprot_disassoc - notification of unprotected disassociation
+ * @dev: network device
+ * @buf: disassociation frame (header + body)
+ * @len: length of the frame data
+ *
+ * This function is called whenever a received Disassociation frame has been
+ * dropped in station mode because of MFP being used but the Disassociation
+ * frame was not protected. This function may sleep.
+ */
+void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
+ size_t len);
+
+/**
* cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
* @dev: network device
* @addr: The source MAC address of the frame
@@ -2595,6 +2700,18 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
enum nl80211_cqm_rssi_threshold_event rssi_event,
gfp_t gfp);
+/**
+ * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
+ * @dev: network device
+ * @peer: peer's MAC address
+ * @num_packets: how many packets were lost -- should be a fixed threshold
+ * but probably no less than maybe 50, or maybe a throughput dependent
+ * threshold (to account for temporary interference)
+ * @gfp: context flags
+ */
+void cfg80211_cqm_pktloss_notify(struct net_device *dev,
+ const u8 *peer, u32 num_packets, gfp_t gfp);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/net/dcbevent.h b/include/net/dcbevent.h
new file mode 100644
index 000000000000..bc1e7ef40171
--- /dev/null
+++ b/include/net/dcbevent.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Author: John Fastabend <john.r.fastabend@intel.com>
+ */
+
+#ifndef _DCB_EVENT_H
+#define _DCB_EVENT_H
+
+enum dcbevent_notif_type {
+ DCB_APP_EVENT = 1,
+};
+
+extern int register_dcbevent_notifier(struct notifier_block *nb);
+extern int unregister_dcbevent_notifier(struct notifier_block *nb);
+extern int call_dcbevent_notifiers(unsigned long val, void *v);
+
+#endif
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index b36ac7e0914d..a8e7852b10ab 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -20,11 +20,31 @@
#ifndef __NET_DCBNL_H__
#define __NET_DCBNL_H__
+#include <linux/dcbnl.h>
+
+struct dcb_app_type {
+ char name[IFNAMSIZ];
+ struct dcb_app app;
+ struct list_head list;
+};
+
+u8 dcb_setapp(struct net_device *, struct dcb_app *);
+u8 dcb_getapp(struct net_device *, struct dcb_app *);
+
/*
* Ops struct for the netlink callbacks. Used by DCB-enabled drivers through
* the netdevice struct.
*/
struct dcbnl_rtnl_ops {
+ /* IEEE 802.1Qaz std */
+ int (*ieee_getets) (struct net_device *, struct ieee_ets *);
+ int (*ieee_setets) (struct net_device *, struct ieee_ets *);
+ int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *);
+ int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
+ int (*ieee_getapp) (struct net_device *, struct dcb_app *);
+ int (*ieee_setapp) (struct net_device *, struct dcb_app *);
+
+ /* CEE std */
u8 (*getstate)(struct net_device *);
u8 (*setstate)(struct net_device *, u8);
void (*getpermhwaddr)(struct net_device *, u8 *);
@@ -50,6 +70,14 @@ struct dcbnl_rtnl_ops {
void (*setbcnrp)(struct net_device *, int, u8);
u8 (*setapp)(struct net_device *, u8, u16, u8);
u8 (*getapp)(struct net_device *, u8, u16);
+ u8 (*getfeatcfg)(struct net_device *, int, u8 *);
+ u8 (*setfeatcfg)(struct net_device *, int, u8);
+
+ /* DCBX configuration */
+ u8 (*getdcbx)(struct net_device *);
+ u8 (*setdcbx)(struct net_device *, u8);
+
+
};
#endif /* __NET_DCBNL_H__ */
diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h
index 0916bbf3bdff..b9e32db03f20 100644
--- a/include/net/dn_dev.h
+++ b/include/net/dn_dev.h
@@ -5,13 +5,14 @@
struct dn_dev;
struct dn_ifaddr {
- struct dn_ifaddr *ifa_next;
+ struct dn_ifaddr __rcu *ifa_next;
struct dn_dev *ifa_dev;
__le16 ifa_local;
__le16 ifa_address;
__u8 ifa_flags;
__u8 ifa_scope;
char ifa_label[IFNAMSIZ];
+ struct rcu_head rcu;
};
#define DN_DEV_S_RU 0 /* Run - working normally */
@@ -83,7 +84,7 @@ struct dn_dev_parms {
struct dn_dev {
- struct dn_ifaddr *ifa_list;
+ struct dn_ifaddr __rcu *ifa_list;
struct net_device *dev;
struct dn_dev_parms parms;
char use_long;
@@ -171,19 +172,27 @@ extern int unregister_dnaddr_notifier(struct notifier_block *nb);
static inline int dn_dev_islocal(struct net_device *dev, __le16 addr)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db;
struct dn_ifaddr *ifa;
+ int res = 0;
+ rcu_read_lock();
+ dn_db = rcu_dereference(dev->dn_ptr);
if (dn_db == NULL) {
printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n");
- return 0;
+ goto out;
}
- for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next)
- if ((addr ^ ifa->ifa_local) == 0)
- return 1;
-
- return 0;
+ for (ifa = rcu_dereference(dn_db->ifa_list);
+ ifa != NULL;
+ ifa = rcu_dereference(ifa->ifa_next))
+ if ((addr ^ ifa->ifa_local) == 0) {
+ res = 1;
+ break;
+ }
+out:
+ rcu_read_unlock();
+ return res;
}
#endif /* _NET_DN_DEV_H */
diff --git a/include/net/dn_route.h b/include/net/dn_route.h
index ccadab3aa3f6..9b185df265fb 100644
--- a/include/net/dn_route.h
+++ b/include/net/dn_route.h
@@ -80,6 +80,16 @@ struct dn_route {
unsigned rt_type;
};
+static inline bool dn_is_input_route(struct dn_route *rt)
+{
+ return rt->fl.iif != 0;
+}
+
+static inline bool dn_is_output_route(struct dn_route *rt)
+{
+ return rt->fl.iif == 0;
+}
+
extern void dn_route_init(void);
extern void dn_route_cleanup(void);
diff --git a/include/net/dst.h b/include/net/dst.h
index ffe9cb719c0e..93b0310317be 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -70,7 +70,7 @@ struct dst_entry {
struct dst_ops *ops;
- u32 metrics[RTAX_MAX];
+ u32 _metrics[RTAX_MAX];
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
@@ -94,19 +94,59 @@ struct dst_entry {
int __use;
unsigned long lastuse;
union {
- struct dst_entry *next;
- struct rtable __rcu *rt_next;
- struct rt6_info *rt6_next;
- struct dn_route *dn_next;
+ struct dst_entry *next;
+ struct rtable __rcu *rt_next;
+ struct rt6_info *rt6_next;
+ struct dn_route __rcu *dn_next;
};
};
#ifdef __KERNEL__
static inline u32
-dst_metric(const struct dst_entry *dst, int metric)
+dst_metric_raw(const struct dst_entry *dst, const int metric)
{
- return dst->metrics[metric-1];
+ return dst->_metrics[metric-1];
+}
+
+static inline u32
+dst_metric(const struct dst_entry *dst, const int metric)
+{
+ WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
+ metric == RTAX_ADVMSS ||
+ metric == RTAX_MTU);
+ return dst_metric_raw(dst, metric);
+}
+
+static inline u32
+dst_metric_advmss(const struct dst_entry *dst)
+{
+ u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);
+
+ if (!advmss)
+ advmss = dst->ops->default_advmss(dst);
+
+ return advmss;
+}
+
+static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
+{
+ dst->_metrics[metric-1] = val;
+}
+
+static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics)
+{
+ memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32));
+}
+
+static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
+{
+ dst_import_metrics(dest, src->_metrics);
+}
+
+static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
+{
+ return dst->_metrics;
}
static inline u32
@@ -117,11 +157,11 @@ dst_feature(const struct dst_entry *dst, u32 feature)
static inline u32 dst_mtu(const struct dst_entry *dst)
{
- u32 mtu = dst_metric(dst, RTAX_MTU);
- /*
- * Alexey put it here, so ask him about it :)
- */
- barrier();
+ u32 mtu = dst_metric_raw(dst, RTAX_MTU);
+
+ if (!mtu)
+ mtu = dst->ops->default_mtu(dst);
+
return mtu;
}
@@ -134,7 +174,7 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr
static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
unsigned long rtt)
{
- dst->metrics[metric-1] = jiffies_to_msecs(rtt);
+ dst_metric_set(dst, metric, jiffies_to_msecs(rtt));
}
static inline u32
@@ -147,7 +187,7 @@ dst_allfrag(const struct dst_entry *dst)
}
static inline int
-dst_metric_locked(struct dst_entry *dst, int metric)
+dst_metric_locked(const struct dst_entry *dst, int metric)
{
return dst_metric(dst, RTAX_LOCK) & (1<<metric);
}
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index 51665b3461b8..21a320b8708e 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -16,6 +16,8 @@ struct dst_ops {
int (*gc)(struct dst_ops *ops);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
+ unsigned int (*default_advmss)(const struct dst_entry *);
+ unsigned int (*default_mtu)(const struct dst_entry *);
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
diff --git a/include/net/flow.h b/include/net/flow.h
index 0ac3fb5e0973..240b7f356c71 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -49,7 +49,6 @@ struct flowi {
__u8 proto;
__u8 flags;
#define FLOWI_FLAG_ANYSRC 0x01
-#define FLOWI_FLAG_MATCH_ANY_IIF 0x02
union {
struct {
__be16 sport;
@@ -67,6 +66,7 @@ struct flowi {
} dnports;
__be32 spi;
+ __be32 gre_key;
struct {
__u8 type;
@@ -78,6 +78,7 @@ struct flowi {
#define fl_icmp_code uli_u.icmpt.code
#define fl_ipsec_spi uli_u.spi
#define fl_mh_type uli_u.mht.type
+#define fl_gre_key uli_u.gre_key
__u32 secid; /* used by xfrm; see secid.txt */
} __attribute__((__aligned__(BITS_PER_LONG/8)));
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index f95ff8d9aa47..04977eefb0ee 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -89,10 +89,11 @@ struct ip6_sf_socklist {
struct ipv6_mc_socklist {
struct in6_addr addr;
int ifindex;
- struct ipv6_mc_socklist *next;
+ struct ipv6_mc_socklist __rcu *next;
rwlock_t sflock;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
struct ip6_sf_socklist *sflist;
+ struct rcu_head rcu;
};
struct ip6_sf_list {
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index aae08f686633..ff013505236b 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -25,6 +25,9 @@ struct sockaddr;
extern int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb);
+extern struct dst_entry* inet6_csk_route_req(struct sock *sk,
+ const struct request_sock *req);
+
extern struct request_sock *inet6_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport,
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index e4f494b42e06..6ac4e3b5007f 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -43,7 +43,7 @@ struct inet_connection_sock_af_ops {
struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst);
- int (*remember_stamp)(struct sock *sk);
+ struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it);
u16 net_header_len;
u16 sockaddr_len;
int (*setsockopt)(struct sock *sk, int level, int optname,
@@ -132,7 +132,6 @@ struct inet_connection_sock {
#define ICSK_TIME_RETRANS 1 /* Retransmit timer */
#define ICSK_TIME_DACK 2 /* Delayed ack timer */
#define ICSK_TIME_PROBE0 3 /* Zero window probe timer */
-#define ICSK_TIME_KEEPOPEN 4 /* Keepalive timer */
static inline struct inet_connection_sock *inet_csk(const struct sock *sk)
{
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 1989cfd7405f..8181498fa96c 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -116,8 +116,9 @@ struct inet_sock {
struct ipv6_pinfo *pinet6;
#endif
/* Socket demultiplex comparisons on incoming packets. */
- __be32 inet_daddr;
- __be32 inet_rcv_saddr;
+#define inet_daddr sk.__sk_common.skc_daddr
+#define inet_rcv_saddr sk.__sk_common.skc_rcv_saddr
+
__be16 inet_dport;
__u16 inet_num;
__be32 inet_saddr;
@@ -141,7 +142,7 @@ struct inet_sock {
nodefrag:1;
int mc_index;
__be32 mc_addr;
- struct ip_mc_socklist *mc_list;
+ struct ip_mc_socklist __rcu *mc_list;
struct {
unsigned int flags;
unsigned int fragsize;
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index a066fdd50da6..17404b5388a7 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -88,12 +88,6 @@ extern void inet_twdr_hangman(unsigned long data);
extern void inet_twdr_twkill_work(struct work_struct *work);
extern void inet_twdr_twcal_tick(unsigned long data);
-#if (BITS_PER_LONG == 64)
-#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 8
-#else
-#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 4
-#endif
-
struct inet_bind_bucket;
/*
@@ -117,15 +111,15 @@ struct inet_timewait_sock {
#define tw_hash __tw_common.skc_hash
#define tw_prot __tw_common.skc_prot
#define tw_net __tw_common.skc_net
+#define tw_daddr __tw_common.skc_daddr
+#define tw_rcv_saddr __tw_common.skc_rcv_saddr
int tw_timeout;
volatile unsigned char tw_substate;
- /* 3 bits hole, try to pack */
unsigned char tw_rcv_wscale;
+
/* Socket demultiplex comparisons on incoming packets. */
- /* these five are in inet_sock */
+ /* these three are in inet_sock */
__be16 tw_sport;
- __be32 tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
- __be32 tw_rcv_saddr;
__be16 tw_dport;
__u16 tw_num;
kmemcheck_bitfield_begin(flags);
@@ -191,10 +185,10 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
return (struct inet_timewait_sock *)sk;
}
-static inline __be32 inet_rcv_saddr(const struct sock *sk)
+static inline __be32 sk_rcv_saddr(const struct sock *sk)
{
- return likely(sk->sk_state != TCP_TIME_WAIT) ?
- inet_sk(sk)->inet_rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
+/* both inet_sk() and inet_twsk() store rcv_saddr in skc_rcv_saddr */
+ return sk->__sk_common.skc_rcv_saddr;
}
extern void inet_twsk_put(struct inet_timewait_sock *tw);
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index fe239bfe5f7f..599d96e74114 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -11,12 +11,21 @@
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
+#include <net/ipv6.h>
#include <asm/atomic.h>
+struct inetpeer_addr {
+ union {
+ __be32 a4;
+ __be32 a6[4];
+ };
+ __u16 family;
+};
+
struct inet_peer {
/* group together avl_left,avl_right,v4daddr to speedup lookups */
struct inet_peer __rcu *avl_left, *avl_right;
- __be32 v4daddr; /* peer's address */
+ struct inetpeer_addr daddr;
__u32 avl_height;
struct list_head unused;
__u32 dtime; /* the time of last use of not
@@ -26,7 +35,6 @@ struct inet_peer {
* Once inet_peer is queued for deletion (refcnt == -1), following fields
* are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp
* We can share memory with rcu_head to keep inet_peer small
- * (less then 64 bytes)
*/
union {
struct {
@@ -42,7 +50,25 @@ struct inet_peer {
void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */
-struct inet_peer *inet_getpeer(__be32 daddr, int create);
+struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create);
+
+static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create)
+{
+ struct inetpeer_addr daddr;
+
+ daddr.a4 = v4daddr;
+ daddr.family = AF_INET;
+ return inet_getpeer(&daddr, create);
+}
+
+static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int create)
+{
+ struct inetpeer_addr daddr;
+
+ ipv6_addr_copy((struct in6_addr *)daddr.a6, v6daddr);
+ daddr.family = AF_INET6;
+ return inet_getpeer(&daddr, create);
+}
/* can be called from BH context or outside */
extern void inet_putpeer(struct inet_peer *p);
diff --git a/include/net/ip.h b/include/net/ip.h
index 86e2b182a0c0..67fac78a186b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -201,7 +201,6 @@ static inline int inet_is_reserved_local_port(int port)
return test_bit(port, sysctl_local_reserved_ports);
}
-extern int sysctl_ip_default_ttl;
extern int sysctl_ip_nonlocal_bind;
extern struct ctl_path net_core_path[];
@@ -428,15 +427,6 @@ extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
u32 info);
-/* sysctl helpers - any sysctl which holds a value that ends up being
- * fed into the routing cache should use these handlers.
- */
-int ipv4_doint_and_flush(ctl_table *ctl, int write,
- void __user *buffer,
- size_t *lenp, loff_t *ppos);
-int ipv4_doint_and_flush_strategy(ctl_table *table,
- void __user *oldval, size_t __user *oldlenp,
- void __user *newval, size_t newlen);
#ifdef CONFIG_PROC_FS
extern int ip_misc_proc_init(void);
#endif
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 062a823d311c..708ff7cb8806 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -21,6 +21,7 @@
#include <net/dst.h>
#include <net/flow.h>
#include <net/netlink.h>
+#include <net/inetpeer.h>
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB6_TABLE_HASHSZ 256
@@ -109,6 +110,7 @@ struct rt6_info {
u32 rt6i_metric;
struct inet6_dev *rt6i_idev;
+ struct inet_peer *rt6i_peer;
#ifdef CONFIG_XFRM
u32 rt6i_flow_cache_genid;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 278312c95f96..8552f0a2e854 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -3,7 +3,6 @@
#define IP6_RT_PRIO_USER 1024
#define IP6_RT_PRIO_ADDRCONF 256
-#define IP6_RT_PRIO_KERN 512
struct route_info {
__u8 type;
@@ -56,6 +55,18 @@ static inline unsigned int rt6_flags2srcprefs(int flags)
return (flags >> 3) & 7;
}
+extern void rt6_bind_peer(struct rt6_info *rt,
+ int create);
+
+static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt)
+{
+ if (rt->rt6i_peer)
+ return rt->rt6i_peer;
+
+ rt6_bind_peer(rt, 0);
+ return rt->rt6i_peer;
+}
+
extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct net *net,
@@ -164,5 +175,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb)
return rt->rt6i_flags & RTF_LOCAL;
}
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+
+static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
+{
+ struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
+
+ return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
+ skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
+}
+
#endif
#endif
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9fdf982d1286..479c35e160e3 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -97,6 +97,20 @@ enum ieee80211_max_queues {
};
/**
+ * enum ieee80211_ac_numbers - AC numbers as used in mac80211
+ * @IEEE80211_AC_VO: voice
+ * @IEEE80211_AC_VI: video
+ * @IEEE80211_AC_BE: best effort
+ * @IEEE80211_AC_BK: background
+ */
+enum ieee80211_ac_numbers {
+ IEEE80211_AC_VO = 0,
+ IEEE80211_AC_VI = 1,
+ IEEE80211_AC_BE = 2,
+ IEEE80211_AC_BK = 3,
+};
+
+/**
* struct ieee80211_tx_queue_params - transmit queue configuration
*
* The information provided in this structure is required for QoS
@@ -205,6 +219,7 @@ enum ieee80211_bss_change {
* @basic_rates: bitmap of basic rates, each bit stands for an
* index into the rate table configured by the driver in
* the current band.
+ * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
* @bssid: The BSSID for this BSS
* @enable_beacon: whether beaconing should be enabled or not
* @channel_type: Channel type for this BSS -- the hardware might be
@@ -244,6 +259,7 @@ struct ieee80211_bss_conf {
u16 assoc_capability;
u64 timestamp;
u32 basic_rates;
+ int mcast_rate[IEEE80211_NUM_BANDS];
u16 ht_operation_mode;
s32 cqm_rssi_thold;
u32 cqm_rssi_hyst;
@@ -1652,6 +1668,11 @@ enum ieee80211_ampdu_mlme_action {
* and IV16) for the given key from hardware.
* The callback must be atomic.
*
+ * @set_frag_threshold: Configuration of fragmentation threshold. Assign this
+ * if the device does fragmentation by itself; if this callback is
+ * implemented then the stack will not do fragmentation.
+ * The callback can sleep.
+ *
* @set_rts_threshold: Configuration of RTS threshold (if device needs it)
* The callback can sleep.
*
@@ -1724,6 +1745,13 @@ enum ieee80211_ampdu_mlme_action {
* completion of the channel switch.
*
* @napi_poll: Poll Rx queue for incoming data frames.
+ *
+ * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.
+ * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may
+ * reject TX/RX mask combinations they cannot support by returning -EINVAL
+ * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).
+ *
+ * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1765,6 +1793,7 @@ struct ieee80211_ops {
struct ieee80211_low_level_stats *stats);
void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
u32 *iv32, u16 *iv16);
+ int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
@@ -1793,6 +1822,8 @@ struct ieee80211_ops {
void (*channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_channel_switch *ch_switch);
int (*napi_poll)(struct ieee80211_hw *hw, int budget);
+ int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
+ int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
};
/**
@@ -1821,11 +1852,39 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
*/
int ieee80211_register_hw(struct ieee80211_hw *hw);
+/**
+ * struct ieee80211_tpt_blink - throughput blink description
+ * @throughput: throughput in Kbit/sec
+ * @blink_time: blink time in milliseconds
+ * (full cycle, ie. one off + one on period)
+ */
+struct ieee80211_tpt_blink {
+ int throughput;
+ int blink_time;
+};
+
+/**
+ * enum ieee80211_tpt_led_trigger_flags - throughput trigger flags
+ * @IEEE80211_TPT_LEDTRIG_FL_RADIO: enable blinking with radio
+ * @IEEE80211_TPT_LEDTRIG_FL_WORK: enable blinking when working
+ * @IEEE80211_TPT_LEDTRIG_FL_CONNECTED: enable blinking when at least one
+ * interface is connected in some way, including being an AP
+ */
+enum ieee80211_tpt_led_trigger_flags {
+ IEEE80211_TPT_LEDTRIG_FL_RADIO = BIT(0),
+ IEEE80211_TPT_LEDTRIG_FL_WORK = BIT(1),
+ IEEE80211_TPT_LEDTRIG_FL_CONNECTED = BIT(2),
+};
+
#ifdef CONFIG_MAC80211_LEDS
extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw);
extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw);
extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw);
extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw);
+extern char *__ieee80211_create_tpt_led_trigger(
+ struct ieee80211_hw *hw, unsigned int flags,
+ const struct ieee80211_tpt_blink *blink_table,
+ unsigned int blink_table_len);
#endif
/**
* ieee80211_get_tx_led_name - get name of TX LED
@@ -1904,6 +1963,30 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
}
/**
+ * ieee80211_create_tpt_led_trigger - create throughput LED trigger
+ * @hw: the hardware to create the trigger for
+ * @flags: trigger flags, see &enum ieee80211_tpt_led_trigger_flags
+ * @blink_table: the blink table -- needs to be ordered by throughput
+ * @blink_table_len: size of the blink table
+ *
+ * This function returns %NULL (in case of error, or if no LED
+ * triggers are configured) or the name of the new trigger.
+ * This function must be called before ieee80211_register_hw().
+ */
+static inline char *
+ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
+ const struct ieee80211_tpt_blink *blink_table,
+ unsigned int blink_table_len)
+{
+#ifdef CONFIG_MAC80211_LEDS
+ return __ieee80211_create_tpt_led_trigger(hw, flags, blink_table,
+ blink_table_len);
+#else
+ return NULL;
+#endif
+}
+
+/**
* ieee80211_unregister_hw - Unregister a hardware device
*
* This function instructs mac80211 to free allocated resources
@@ -2024,8 +2107,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
*
* This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls
- * to this function and ieee80211_tx_status_irqsafe() may not be mixed
- * for a single hardware.
+ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
+ * may not be mixed for a single hardware.
*
* @hw: the hardware the frame was transmitted by
* @skb: the frame that was transmitted, owned by mac80211 after this call
@@ -2034,13 +2117,33 @@ void ieee80211_tx_status(struct ieee80211_hw *hw,
struct sk_buff *skb);
/**
+ * ieee80211_tx_status_ni - transmit status callback (in process context)
+ *
+ * Like ieee80211_tx_status() but can be called in process context.
+ *
+ * Calls to this function, ieee80211_tx_status() and
+ * ieee80211_tx_status_irqsafe() may not be mixed
+ * for a single hardware.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @skb: the frame that was transmitted, owned by mac80211 after this call
+ */
+static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ local_bh_disable();
+ ieee80211_tx_status(hw, skb);
+ local_bh_enable();
+}
+
+/**
* ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback
*
* Like ieee80211_tx_status() but can be called in IRQ context
* (internally defers to a tasklet.)
*
- * Calls to this function and ieee80211_tx_status() may not be mixed for a
- * single hardware.
+ * Calls to this function, ieee80211_tx_status() and
+ * ieee80211_tx_status_ni() may not be mixed for a single hardware.
*
* @hw: the hardware the frame was transmitted by
* @skb: the frame that was transmitted, owned by mac80211 after this call
@@ -2384,6 +2487,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
* ieee80211_start_tx_ba_session - Start a tx Block Ack session.
* @sta: the station for which to start a BA session
* @tid: the TID to BA on.
+ * @timeout: session timeout value (in TUs)
*
* Return: success if addBA request was sent, failure otherwise
*
@@ -2391,7 +2495,8 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
* the need to start aggregation on a certain RA/TID, the session level
* will be managed by the mac80211.
*/
-int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid);
+int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid,
+ u16 timeout);
/**
* ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate.
@@ -2501,6 +2606,21 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
struct ieee80211_sta *pubsta, bool block);
/**
+ * ieee80211_ap_probereq_get - retrieve a Probe Request template
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ *
+ * Creates a Probe Request template which can, for example, be uploaded to
+ * hardware. The template is filled with bssid, ssid and supported rate
+ * information. This function must only be called from within the
+ * .bss_info_changed callback function and only in managed mode. The function
+ * is only useful when the interface is associated, otherwise it will return
+ * NULL.
+ */
+struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+
+/**
* ieee80211_beacon_loss - inform hardware does not receive beacons
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
@@ -2640,7 +2760,7 @@ enum rate_control_changed {
* @rate_idx_mask: user-requested rate mask (not MCS for now)
* @skb: the skb that will be transmitted, the control information in it needs
* to be filled in
- * @ap: whether this frame is sent out in AP mode
+ * @bss: whether this frame is sent out in AP or IBSS mode
*/
struct ieee80211_tx_rate_control {
struct ieee80211_hw *hw;
@@ -2651,7 +2771,7 @@ struct ieee80211_tx_rate_control {
bool rts, short_preamble;
u8 max_rate_idx;
u32 rate_idx_mask;
- bool ap;
+ bool bss;
};
struct rate_control_ops {
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 895997bc2ead..e0e594f8e9d9 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -42,9 +42,6 @@ enum {
#define ND_REACHABLE_TIME (30*HZ)
#define ND_RETRANS_TIMER HZ
-#define ND_MIN_RANDOM_FACTOR (1/2)
-#define ND_MAX_RANDOM_FACTOR (3/2)
-
#ifdef __KERNEL__
#include <linux/compiler.h>
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 6beb1ffc2b7f..4014b623880c 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -96,16 +96,16 @@ struct neighbour {
struct neigh_parms *parms;
unsigned long confirmed;
unsigned long updated;
- __u8 flags;
- __u8 nud_state;
- __u8 type;
- __u8 dead;
+ rwlock_t lock;
atomic_t refcnt;
struct sk_buff_head arp_queue;
struct timer_list timer;
unsigned long used;
atomic_t probes;
- rwlock_t lock;
+ __u8 flags;
+ __u8 nud_state;
+ __u8 type;
+ __u8 dead;
seqlock_t ha_lock;
unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
struct hh_cache *hh;
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 9801c55de5d6..373f1a900cf4 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -225,13 +225,15 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb,
u32 pid, unsigned int group, int report,
gfp_t flags);
-extern int nla_validate(struct nlattr *head, int len, int maxtype,
+extern int nla_validate(const struct nlattr *head,
+ int len, int maxtype,
const struct nla_policy *policy);
-extern int nla_parse(struct nlattr *tb[], int maxtype,
- struct nlattr *head, int len,
+extern int nla_parse(struct nlattr **tb, int maxtype,
+ const struct nlattr *head, int len,
const struct nla_policy *policy);
extern int nla_policy_len(const struct nla_policy *, int);
-extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
+extern struct nlattr * nla_find(const struct nlattr *head,
+ int len, int attrtype);
extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
size_t dstsize);
extern int nla_memcpy(void *dest, const struct nlattr *src, int count);
@@ -346,7 +348,8 @@ static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
* Returns the next netlink message in the message stream and
* decrements remaining by the size of the current message.
*/
-static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
+static inline struct nlmsghdr *
+nlmsg_next(const struct nlmsghdr *nlh, int *remaining)
{
int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
@@ -398,7 +401,8 @@ static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
* @maxtype: maximum attribute type to be expected
* @policy: validation policy
*/
-static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
+static inline int nlmsg_validate(const struct nlmsghdr *nlh,
+ int hdrlen, int maxtype,
const struct nla_policy *policy)
{
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
@@ -727,7 +731,8 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
*
* Returns the first attribute which matches the specified type.
*/
-static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
+static inline struct nlattr *
+nla_find_nested(const struct nlattr *nla, int attrtype)
{
return nla_find(nla_data(nla), nla_len(nla), attrtype);
}
@@ -1032,7 +1037,7 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
*
* Returns 0 on success or a negative error code.
*/
-static inline int nla_validate_nested(struct nlattr *start, int maxtype,
+static inline int nla_validate_nested(const struct nlattr *start, int maxtype,
const struct nla_policy *policy)
{
return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h
index 81a31c0db3e7..3419bf5cd154 100644
--- a/include/net/netns/generic.h
+++ b/include/net/netns/generic.h
@@ -30,7 +30,7 @@ struct net_generic {
void *ptr[0];
};
-static inline void *net_generic(struct net *net, int id)
+static inline void *net_generic(const struct net *net, int id)
{
struct net_generic *ng;
void *ptr;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index dd3031aed9d5..9fcc680ab6b9 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -323,7 +323,9 @@ static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
static inline int tcf_valid_offset(const struct sk_buff *skb,
const unsigned char *ptr, const int len)
{
- return unlikely((ptr + len) < skb_tail_pointer(skb) && ptr > skb->head);
+ return likely((ptr + len) <= skb_tail_pointer(skb) &&
+ ptr >= skb->head &&
+ (ptr <= (ptr + len)));
}
#ifdef CONFIG_NET_CLS_IND
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index 9e103a4e91ee..356d6e3dc20a 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -43,6 +43,12 @@ enum environment_cap {
* @intersect: indicates whether the wireless core should intersect
* the requested regulatory domain with the presently set regulatory
* domain.
+ * @processed: indicates whether or not this requests has already been
+ * processed. When the last request is processed it means that the
+ * currently regulatory domain set on cfg80211 is updated from
+ * CRDA and can be used by other regulatory requests. When a
+ * the last request is not yet processed we must yield until it
+ * is processed before processing any new requests.
* @country_ie_checksum: checksum of the last processed and accepted
* country IE
* @country_ie_env: lets us know if the AP is telling us we are outdoor,
@@ -54,6 +60,7 @@ struct regulatory_request {
enum nl80211_reg_initiator initiator;
char alpha2[2];
bool intersect;
+ bool processed;
enum environment_cap country_ie_env;
struct list_head list;
};
diff --git a/include/net/route.h b/include/net/route.h
index 7e5e73bfa4de..93e10c453f6b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -55,8 +55,6 @@ struct rtable {
/* Cache lookup keys */
struct flowi fl;
- struct in_device *idev;
-
int rt_genid;
unsigned rt_flags;
__u16 rt_type;
@@ -73,6 +71,16 @@ struct rtable {
struct inet_peer *peer; /* long-living peer info */
};
+static inline bool rt_is_input_route(struct rtable *rt)
+{
+ return rt->fl.iif != 0;
+}
+
+static inline bool rt_is_output_route(struct rtable *rt)
+{
+ return rt->fl.iif == 0;
+}
+
struct ip_rt_acct {
__u32 o_bytes;
__u32 o_packets;
@@ -106,7 +114,7 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
-extern void rt_cache_flush_batch(void);
+extern void rt_cache_flush_batch(struct net *net);
extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
@@ -161,14 +169,12 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
{
struct flowi fl = { .oif = oif,
.mark = sk->sk_mark,
- .nl_u = { .ip4_u = { .daddr = dst,
- .saddr = src,
- .tos = tos } },
+ .fl4_dst = dst,
+ .fl4_src = src,
+ .fl4_tos = tos,
.proto = protocol,
- .uli_u = { .ports =
- { .sport = sport,
- .dport = dport } } };
-
+ .fl_ip_sport = sport,
+ .fl_ip_dport = dport };
int err;
struct net *net = sock_net(sk);
@@ -225,4 +231,15 @@ static inline int inet_iif(const struct sk_buff *skb)
return skb_rtable(skb)->rt_iif;
}
+extern int sysctl_ip_default_ttl;
+
+static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
+{
+ int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
+
+ if (hoplimit == 0)
+ hoplimit = sysctl_ip_default_ttl;
+ return hoplimit;
+}
+
#endif /* _ROUTE_H */
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index e013c68bfb00..4093ca78cf60 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -83,6 +83,41 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops);
extern int rtnl_link_register(struct rtnl_link_ops *ops);
extern void rtnl_link_unregister(struct rtnl_link_ops *ops);
+/**
+ * struct rtnl_af_ops - rtnetlink address family operations
+ *
+ * @list: Used internally
+ * @family: Address family
+ * @fill_link_af: Function to fill IFLA_AF_SPEC with address family
+ * specific netlink attributes.
+ * @get_link_af_size: Function to calculate size of address family specific
+ * netlink attributes exlusive the container attribute.
+ * @validate_link_af: Validate a IFLA_AF_SPEC attribute, must check attr
+ * for invalid configuration settings.
+ * @set_link_af: Function to parse a IFLA_AF_SPEC attribute and modify
+ * net_device accordingly.
+ */
+struct rtnl_af_ops {
+ struct list_head list;
+ int family;
+
+ int (*fill_link_af)(struct sk_buff *skb,
+ const struct net_device *dev);
+ size_t (*get_link_af_size)(const struct net_device *dev);
+
+ int (*validate_link_af)(const struct net_device *dev,
+ const struct nlattr *attr);
+ int (*set_link_af)(struct net_device *dev,
+ const struct nlattr *attr);
+};
+
+extern int __rtnl_af_register(struct rtnl_af_ops *ops);
+extern void __rtnl_af_unregister(struct rtnl_af_ops *ops);
+
+extern int rtnl_af_register(struct rtnl_af_ops *ops);
+extern void rtnl_af_unregister(struct rtnl_af_ops *ops);
+
+
extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]);
extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index ea1f8a83160d..0af57ebae762 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -321,6 +321,7 @@ extern void dev_init_scheduler(struct net_device *dev);
extern void dev_shutdown(struct net_device *dev);
extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
+extern void dev_deactivate_many(struct list_head *head);
extern struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
struct Qdisc *qdisc);
extern void qdisc_reset(struct Qdisc *qdisc);
@@ -610,11 +611,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
{
struct sk_buff *n;
- if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
- !skb_shared(skb))
- n = skb_get(skb);
- else
- n = skb_clone(skb, gfp_mask);
+ n = skb_clone(skb, gfp_mask);
if (n) {
n->tc_verd = SET_TC_VERD(n->tc_verd, 0);
diff --git a/include/net/scm.h b/include/net/scm.h
index 31656506d967..745460fa2f02 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -10,11 +10,12 @@
/* Well, we should have at least one descriptor open
* to accept passed FDs 8)
*/
-#define SCM_MAX_FD 255
+#define SCM_MAX_FD 253
struct scm_fp_list {
struct list_head list;
- int count;
+ short count;
+ short max;
struct file *fp[SCM_MAX_FD];
};
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 2c55a7ea20af..c01dc99def07 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -111,9 +111,6 @@ typedef enum {
SCTP_CMD_LAST
} sctp_verb_t;
-#define SCTP_CMD_MAX (SCTP_CMD_LAST - 1)
-#define SCTP_CMD_NUM_VERBS (SCTP_CMD_MAX + 1)
-
/* How many commands can you put in an sctp_cmd_seq_t?
* This is a rather arbitrary number, ideally derived from a careful
* analysis of the state functions, but in reality just taken from
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 63908840eef0..c70d8ccc55cb 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -61,7 +61,6 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
* symbols. CIDs are dense through SCTP_CID_BASE_MAX.
*/
#define SCTP_CID_BASE_MAX SCTP_CID_SHUTDOWN_COMPLETE
-#define SCTP_CID_MAX SCTP_CID_ASCONF_ACK
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
@@ -86,9 +85,6 @@ typedef enum {
} sctp_event_t;
-#define SCTP_EVENT_T_MAX SCTP_EVENT_T_PRIMITIVE
-#define SCTP_EVENT_T_NUM (SCTP_EVENT_T_MAX + 1)
-
/* As a convenience for the state machine, we append SCTP_EVENT_* and
* SCTP_ULP_* to the list of possible chunks.
*/
@@ -162,9 +158,6 @@ SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive)
- (unsigned long)(c->chunk_hdr)\
- sizeof(sctp_data_chunk_t)))
-#define SCTP_MAX_ERROR_CAUSE SCTP_ERROR_NONEXIST_IP
-#define SCTP_NUM_ERROR_CAUSE 10
-
/* Internal error codes */
typedef enum {
@@ -266,7 +259,6 @@ enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 };
#define SCTP_TSN_MAP_INITIAL BITS_PER_LONG
#define SCTP_TSN_MAP_INCREMENT SCTP_TSN_MAP_INITIAL
#define SCTP_TSN_MAP_SIZE 4096
-#define SCTP_TSN_MAX_GAP 65535
/* We will not record more than this many duplicate TSNs between two
* SACKs. The minimum PMTU is 576. Remove all the headers and there
@@ -301,9 +293,6 @@ enum { SCTP_MAX_GABS = 16 };
#define SCTP_CLOCK_GRANULARITY 1 /* 1 jiffy */
-#define SCTP_DEF_MAX_INIT 6
-#define SCTP_DEF_MAX_SEND 10
-
#define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */
#define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */
@@ -317,9 +306,6 @@ enum { SCTP_MAX_GABS = 16 };
*/
#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
#define SCTP_HOW_MANY_SECRETS 2 /* How many secrets I keep */
-#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* How many seconds the current
- * secret will live?
- */
#define SCTP_SECRET_SIZE 32 /* Number of octets in a 256 bits. */
#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 69fef4fb79c0..cc9185ca8fd1 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -261,8 +261,6 @@ extern struct sctp_globals {
#define sctp_assoc_hashsize (sctp_globals.assoc_hashsize)
#define sctp_assoc_hashtable (sctp_globals.assoc_hashtable)
#define sctp_port_hashsize (sctp_globals.port_hashsize)
-#define sctp_port_rover (sctp_globals.port_rover)
-#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.addr_list_lock)
diff --git a/include/net/snmp.h b/include/net/snmp.h
index a0e61806d480..762e2abce889 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -60,9 +60,7 @@ struct ipstats_mib {
};
/* ICMP */
-#define ICMP_MIB_DUMMY __ICMP_MIB_MAX
-#define ICMP_MIB_MAX (__ICMP_MIB_MAX + 1)
-
+#define ICMP_MIB_MAX __ICMP_MIB_MAX
struct icmp_mib {
unsigned long mibs[ICMP_MIB_MAX];
};
diff --git a/include/net/sock.h b/include/net/sock.h
index a6338d039857..21a02f7e4f45 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -57,7 +57,7 @@
#include <linux/rculist_nulls.h>
#include <linux/poll.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <net/dst.h>
#include <net/checksum.h>
@@ -105,10 +105,8 @@ struct net;
/**
* struct sock_common - minimal network layer representation of sockets
- * @skc_node: main hash linkage for various protocol lookup tables
- * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol
- * @skc_refcnt: reference count
- * @skc_tx_queue_mapping: tx queue number for this connection
+ * @skc_daddr: Foreign IPv4 addr
+ * @skc_rcv_saddr: Bound local IPv4 addr
* @skc_hash: hash value used with various protocol lookup tables
* @skc_u16hashes: two u16 hash values used by UDP lookup tables
* @skc_family: network address family
@@ -119,20 +117,20 @@ struct net;
* @skc_portaddr_node: second hash linkage for UDP/UDP-Lite protocol
* @skc_prot: protocol handlers inside a network family
* @skc_net: reference to the network namespace of this socket
+ * @skc_node: main hash linkage for various protocol lookup tables
+ * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol
+ * @skc_tx_queue_mapping: tx queue number for this connection
+ * @skc_refcnt: reference count
*
* This is the minimal network layer representation of sockets, the header
* for struct sock and struct inet_timewait_sock.
*/
struct sock_common {
- /*
- * first fields are not copied in sock_copy()
+ /* skc_daddr and skc_rcv_saddr must be grouped :
+ * cf INET_MATCH() and INET_TW_MATCH()
*/
- union {
- struct hlist_node skc_node;
- struct hlist_nulls_node skc_nulls_node;
- };
- atomic_t skc_refcnt;
- int skc_tx_queue_mapping;
+ __be32 skc_daddr;
+ __be32 skc_rcv_saddr;
union {
unsigned int skc_hash;
@@ -150,6 +148,18 @@ struct sock_common {
#ifdef CONFIG_NET_NS
struct net *skc_net;
#endif
+ /*
+ * fields between dontcopy_begin/dontcopy_end
+ * are not copied in sock_copy()
+ */
+ int skc_dontcopy_begin[0];
+ union {
+ struct hlist_node skc_node;
+ struct hlist_nulls_node skc_nulls_node;
+ };
+ int skc_tx_queue_mapping;
+ atomic_t skc_refcnt;
+ int skc_dontcopy_end[0];
};
/**
@@ -232,7 +242,8 @@ struct sock {
#define sk_refcnt __sk_common.skc_refcnt
#define sk_tx_queue_mapping __sk_common.skc_tx_queue_mapping
-#define sk_copy_start __sk_common.skc_hash
+#define sk_dontcopy_begin __sk_common.skc_dontcopy_begin
+#define sk_dontcopy_end __sk_common.skc_dontcopy_end
#define sk_hash __sk_common.skc_hash
#define sk_family __sk_common.skc_family
#define sk_state __sk_common.skc_state
@@ -241,59 +252,67 @@ struct sock {
#define sk_bind_node __sk_common.skc_bind_node
#define sk_prot __sk_common.skc_prot
#define sk_net __sk_common.skc_net
- kmemcheck_bitfield_begin(flags);
- unsigned int sk_shutdown : 2,
- sk_no_check : 2,
- sk_userlocks : 4,
- sk_protocol : 8,
- sk_type : 16;
- kmemcheck_bitfield_end(flags);
- int sk_rcvbuf;
socket_lock_t sk_lock;
+ struct sk_buff_head sk_receive_queue;
/*
* The backlog queue is special, it is always used with
* the per-socket spinlock held and requires low latency
* access. Therefore we special case it's implementation.
+ * Note : rmem_alloc is in this structure to fill a hole
+ * on 64bit arches, not because its logically part of
+ * backlog.
*/
struct {
- struct sk_buff *head;
- struct sk_buff *tail;
- int len;
+ atomic_t rmem_alloc;
+ int len;
+ struct sk_buff *head;
+ struct sk_buff *tail;
} sk_backlog;
+#define sk_rmem_alloc sk_backlog.rmem_alloc
+ int sk_forward_alloc;
+#ifdef CONFIG_RPS
+ __u32 sk_rxhash;
+#endif
+ atomic_t sk_drops;
+ int sk_rcvbuf;
+
+ struct sk_filter __rcu *sk_filter;
struct socket_wq *sk_wq;
- struct dst_entry *sk_dst_cache;
+
+#ifdef CONFIG_NET_DMA
+ struct sk_buff_head sk_async_wait_queue;
+#endif
+
#ifdef CONFIG_XFRM
struct xfrm_policy *sk_policy[2];
#endif
+ unsigned long sk_flags;
+ struct dst_entry *sk_dst_cache;
spinlock_t sk_dst_lock;
- atomic_t sk_rmem_alloc;
atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
int sk_sndbuf;
- struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
-#ifdef CONFIG_NET_DMA
- struct sk_buff_head sk_async_wait_queue;
-#endif
+ kmemcheck_bitfield_begin(flags);
+ unsigned int sk_shutdown : 2,
+ sk_no_check : 2,
+ sk_userlocks : 4,
+ sk_protocol : 8,
+ sk_type : 16;
+ kmemcheck_bitfield_end(flags);
int sk_wmem_queued;
- int sk_forward_alloc;
gfp_t sk_allocation;
int sk_route_caps;
int sk_route_nocaps;
int sk_gso_type;
unsigned int sk_gso_max_size;
int sk_rcvlowat;
-#ifdef CONFIG_RPS
- __u32 sk_rxhash;
-#endif
- unsigned long sk_flags;
unsigned long sk_lingertime;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
- atomic_t sk_drops;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
@@ -301,7 +320,6 @@ struct sock {
const struct cred *sk_peer_cred;
long sk_rcvtimeo;
long sk_sndtimeo;
- struct sk_filter __rcu *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
ktime_t sk_stamp;
@@ -509,9 +527,6 @@ static __inline__ void sk_add_bind_node(struct sock *sk,
#define sk_nulls_for_each_from(__sk, node) \
if (__sk && ({ node = &(__sk)->sk_nulls_node; 1; })) \
hlist_nulls_for_each_entry_from(__sk, node, sk_nulls_node)
-#define sk_for_each_continue(__sk, node) \
- if (__sk && ({ node = &(__sk)->sk_node; 1; })) \
- hlist_for_each_entry_continue(__sk, node, sk_node)
#define sk_for_each_safe(__sk, node, tmp, list) \
hlist_for_each_entry_safe(__sk, node, tmp, list, sk_node)
#define sk_for_each_bound(__sk, node, list) \
@@ -754,6 +769,7 @@ struct proto {
void (*unhash)(struct sock *sk);
void (*rehash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
+ void (*clear_sk)(struct sock *sk, int size);
/* Keeping track of sockets in use */
#ifdef CONFIG_PROC_FS
@@ -852,6 +868,8 @@ static inline void __sk_prot_rehash(struct sock *sk)
sk->sk_prot->hash(sk);
}
+void sk_prot_clear_portaddr_nulls(struct sock *sk, int size);
+
/* About 10 seconds */
#define SOCK_DESTROY_TIME (10*HZ)
@@ -1155,6 +1173,8 @@ extern void sk_common_release(struct sock *sk);
/* Initialise core socket variables */
extern void sock_init_data(struct socket *sock, struct sock *sk);
+extern void sk_filter_release_rcu(struct rcu_head *rcu);
+
/**
* sk_filter_release - release a socket filter
* @fp: filter to remove
@@ -1165,7 +1185,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk);
static inline void sk_filter_release(struct sk_filter *fp)
{
if (atomic_dec_and_test(&fp->refcnt))
- kfree(fp);
+ call_rcu_bh(&fp->rcu, sk_filter_release_rcu);
}
static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index e36c874c7fb1..38509f047382 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -60,6 +60,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
*/
#define MAX_TCP_WINDOW 32767U
+/* Offer an initial receive window of 10 mss. */
+#define TCP_DEFAULT_INIT_RCVWND 10
+
/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
#define TCP_MIN_MSS 88U
@@ -100,12 +103,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a
* connection: ~180sec is RFC minimum */
-
-#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned
- * socket. 7 is ~50sec-16min.
- */
-
-
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
* state, about 60 seconds */
#define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN
@@ -312,7 +309,8 @@ extern void tcp_shutdown (struct sock *sk, int how);
extern int tcp_v4_rcv(struct sk_buff *skb);
-extern int tcp_v4_remember_stamp(struct sock *sk);
+extern struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it);
+extern void *tcp_v4_tw_get_peer(struct sock *sk);
extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t size);
@@ -1043,7 +1041,13 @@ static inline int tcp_paws_check(const struct tcp_options_received *rx_opt,
return 1;
if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS))
return 1;
-
+ /*
+ * Some OSes send SYN and SYNACK messages with tsval=0 tsecr=0,
+ * then following tcp messages have valid values. Ignore 0 value,
+ * or else 'negative' tsval might forbid us to accept their packets.
+ */
+ if (!rx_opt->ts_recent)
+ return 1;
return 0;
}
@@ -1157,8 +1161,6 @@ struct tcp_md5sig_pool {
union tcp_md5sum_block md5_blk;
};
-#define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */
-
/* - functions */
extern int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
struct sock *sk, struct request_sock *req,
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
index 97c3b14da55d..053b3cf2c66a 100644
--- a/include/net/timewait_sock.h
+++ b/include/net/timewait_sock.h
@@ -21,6 +21,7 @@ struct timewait_sock_ops {
int (*twsk_unique)(struct sock *sk,
struct sock *sktw, void *twp);
void (*twsk_destructor)(struct sock *sk);
+ void *(*twsk_getpeer)(struct sock *sk);
};
static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
@@ -39,4 +40,11 @@ static inline void twsk_destructor(struct sock *sk)
sk->sk_prot->twsk_prot->twsk_destructor(sk);
}
+static inline void *twsk_getpeer(struct sock *sk)
+{
+ if (sk->sk_prot->twsk_prot->twsk_getpeer)
+ return sk->sk_prot->twsk_prot->twsk_getpeer(sk);
+ return NULL;
+}
+
#endif /* _TIMEWAIT_SOCK_H */
diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h
deleted file mode 100644
index 1e0645e1eed2..000000000000
--- a/include/net/tipc/tipc.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * include/net/tipc/tipc.h: Main include file for TIPC users
- *
- * Copyright (c) 2003-2006, Ericsson AB
- * Copyright (c) 2005,2010 Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _NET_TIPC_H_
-#define _NET_TIPC_H_
-
-#ifdef __KERNEL__
-
-#include <linux/tipc.h>
-#include <linux/skbuff.h>
-
-/*
- * Native API
- */
-
-/*
- * TIPC operating mode routines
- */
-
-#define TIPC_NOT_RUNNING 0
-#define TIPC_NODE_MODE 1
-#define TIPC_NET_MODE 2
-
-typedef void (*tipc_mode_event)(void *usr_handle, int mode, u32 addr);
-
-int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle);
-
-void tipc_detach(unsigned int userref);
-
-/*
- * TIPC port manipulation routines
- */
-
-typedef void (*tipc_msg_err_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size,
- int reason,
- struct tipc_portid const *attmpt_destid);
-
-typedef void (*tipc_named_msg_err_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size,
- int reason,
- struct tipc_name_seq const *attmpt_dest);
-
-typedef void (*tipc_conn_shutdown_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size,
- int reason);
-
-typedef void (*tipc_msg_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size,
- unsigned int importance,
- struct tipc_portid const *origin);
-
-typedef void (*tipc_named_msg_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size,
- unsigned int importance,
- struct tipc_portid const *orig,
- struct tipc_name_seq const *dest);
-
-typedef void (*tipc_conn_msg_event) (void *usr_handle,
- u32 portref,
- struct sk_buff **buf,
- unsigned char const *data,
- unsigned int size);
-
-typedef void (*tipc_continue_event) (void *usr_handle,
- u32 portref);
-
-int tipc_createport(unsigned int tipc_user,
- void *usr_handle,
- unsigned int importance,
- tipc_msg_err_event error_cb,
- tipc_named_msg_err_event named_error_cb,
- tipc_conn_shutdown_event conn_error_cb,
- tipc_msg_event message_cb,
- tipc_named_msg_event named_message_cb,
- tipc_conn_msg_event conn_message_cb,
- tipc_continue_event continue_event_cb,
- u32 *portref);
-
-int tipc_deleteport(u32 portref);
-
-int tipc_ownidentity(u32 portref, struct tipc_portid *port);
-
-int tipc_portimportance(u32 portref, unsigned int *importance);
-int tipc_set_portimportance(u32 portref, unsigned int importance);
-
-int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
-int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
-
-int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
-int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
-
-int tipc_publish(u32 portref, unsigned int scope,
- struct tipc_name_seq const *name_seq);
-int tipc_withdraw(u32 portref, unsigned int scope,
- struct tipc_name_seq const *name_seq);
-
-int tipc_connect2port(u32 portref, struct tipc_portid const *port);
-
-int tipc_disconnect(u32 portref);
-
-int tipc_shutdown(u32 ref);
-
-/*
- * TIPC messaging routines
- */
-
-#define TIPC_PORT_IMPORTANCE 100 /* send using current port setting */
-
-
-int tipc_send(u32 portref,
- unsigned int num_sect,
- struct iovec const *msg_sect);
-
-int tipc_send2name(u32 portref,
- struct tipc_name const *name,
- u32 domain,
- unsigned int num_sect,
- struct iovec const *msg_sect);
-
-int tipc_send2port(u32 portref,
- struct tipc_portid const *dest,
- unsigned int num_sect,
- struct iovec const *msg_sect);
-
-int tipc_send_buf2port(u32 portref,
- struct tipc_portid const *dest,
- struct sk_buff *buf,
- unsigned int dsz);
-
-int tipc_multicast(u32 portref,
- struct tipc_name_seq const *seq,
- u32 domain, /* currently unused */
- unsigned int section_count,
- struct iovec const *msg);
-#endif
-
-#endif
diff --git a/include/net/tipc/tipc_bearer.h b/include/net/tipc/tipc_bearer.h
deleted file mode 100644
index ee2f304e4919..000000000000
--- a/include/net/tipc/tipc_bearer.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * include/net/tipc/tipc_bearer.h: Include file for privileged access to TIPC bearers
- *
- * Copyright (c) 2003-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _NET_TIPC_BEARER_H_
-#define _NET_TIPC_BEARER_H_
-
-#ifdef __KERNEL__
-
-#include <linux/tipc_config.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-
-/*
- * Identifiers of supported TIPC media types
- */
-
-#define TIPC_MEDIA_TYPE_ETH 1
-
-/*
- * Destination address structure used by TIPC bearers when sending messages
- *
- * IMPORTANT: The fields of this structure MUST be stored using the specified
- * byte order indicated below, as the structure is exchanged between nodes
- * as part of a link setup process.
- */
-
-struct tipc_media_addr {
- __be32 type; /* bearer type (network byte order) */
- union {
- __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */
-#if 0
- /* Prototypes for other possible bearer types */
-
- struct {
- __u16 sin_family;
- __u16 sin_port;
- struct {
- __u32 s_addr;
- } sin_addr;
- char pad[4];
- } addr_in; /* IP-based bearer */
- __u16 sock_descr; /* generic socket bearer */
-#endif
- } dev_addr;
-};
-
-/**
- * struct tipc_bearer - TIPC bearer info available to privileged users
- * @usr_handle: pointer to additional user-defined information about bearer
- * @mtu: max packet size bearer can support
- * @blocked: non-zero if bearer is blocked
- * @lock: spinlock for controlling access to bearer
- * @addr: media-specific address associated with bearer
- * @name: bearer name (format = media:interface)
- *
- * Note: TIPC initializes "name" and "lock" fields; user is responsible for
- * initialization all other fields when a bearer is enabled.
- */
-
-struct tipc_bearer {
- void *usr_handle;
- u32 mtu;
- int blocked;
- spinlock_t lock;
- struct tipc_media_addr addr;
- char name[TIPC_MAX_BEARER_NAME];
-};
-
-/*
- * TIPC routines available to supported media types
- */
-
-int tipc_register_media(u32 media_type,
- char *media_name,
- int (*enable)(struct tipc_bearer *),
- void (*disable)(struct tipc_bearer *),
- int (*send_msg)(struct sk_buff *,
- struct tipc_bearer *,
- struct tipc_media_addr *),
- char *(*addr2str)(struct tipc_media_addr *a,
- char *str_buf,
- int str_size),
- struct tipc_media_addr *bcast_addr,
- const u32 bearer_priority,
- const u32 link_tolerance, /* [ms] */
- const u32 send_window_limit);
-
-void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
-
-int tipc_block_bearer(const char *name);
-void tipc_continue(struct tipc_bearer *tb_ptr);
-
-int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority);
-int tipc_disable_bearer(const char *name);
-
-/*
- * Routines made available to TIPC by supported media types
- */
-
-int tipc_eth_media_start(void);
-void tipc_eth_media_stop(void);
-
-#endif
-
-#endif
diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h
deleted file mode 100644
index ffe50b4e7b93..000000000000
--- a/include/net/tipc/tipc_msg.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * include/net/tipc/tipc_msg.h: Include file for privileged access to TIPC message headers
- *
- * Copyright (c) 2003-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _NET_TIPC_MSG_H_
-#define _NET_TIPC_MSG_H_
-
-#ifdef __KERNEL__
-
-struct tipc_msg {
- __be32 hdr[15];
-};
-
-
-/*
- TIPC user data message header format, version 2:
-
-
- 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w0:|vers | user |hdr sz |n|d|s|-| message size |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w2:| link level ack no | broadcast/link level seq no |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w3:| previous node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w4:| originating port |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w5:| destination port |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w6:| originating node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w7:| destination node |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w8:| name type / transport sequence number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- w9:| name instance/multicast lower bound |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- wA:| multicast upper bound |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- / /
- \ options \
- / /
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-*/
-
-#define TIPC_CONN_MSG 0
-#define TIPC_MCAST_MSG 1
-#define TIPC_NAMED_MSG 2
-#define TIPC_DIRECT_MSG 3
-
-
-static inline u32 msg_word(struct tipc_msg *m, u32 pos)
-{
- return ntohl(m->hdr[pos]);
-}
-
-static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
-{
- return (msg_word(m, w) >> pos) & mask;
-}
-
-static inline u32 msg_importance(struct tipc_msg *m)
-{
- return msg_bits(m, 0, 25, 0xf);
-}
-
-static inline u32 msg_hdr_sz(struct tipc_msg *m)
-{
- return msg_bits(m, 0, 21, 0xf) << 2;
-}
-
-static inline int msg_short(struct tipc_msg *m)
-{
- return msg_hdr_sz(m) == 24;
-}
-
-static inline u32 msg_size(struct tipc_msg *m)
-{
- return msg_bits(m, 0, 0, 0x1ffff);
-}
-
-static inline u32 msg_data_sz(struct tipc_msg *m)
-{
- return msg_size(m) - msg_hdr_sz(m);
-}
-
-static inline unchar *msg_data(struct tipc_msg *m)
-{
- return ((unchar *)m) + msg_hdr_sz(m);
-}
-
-static inline u32 msg_type(struct tipc_msg *m)
-{
- return msg_bits(m, 1, 29, 0x7);
-}
-
-static inline u32 msg_named(struct tipc_msg *m)
-{
- return msg_type(m) == TIPC_NAMED_MSG;
-}
-
-static inline u32 msg_mcast(struct tipc_msg *m)
-{
- return msg_type(m) == TIPC_MCAST_MSG;
-}
-
-static inline u32 msg_connected(struct tipc_msg *m)
-{
- return msg_type(m) == TIPC_CONN_MSG;
-}
-
-static inline u32 msg_errcode(struct tipc_msg *m)
-{
- return msg_bits(m, 1, 25, 0xf);
-}
-
-static inline u32 msg_prevnode(struct tipc_msg *m)
-{
- return msg_word(m, 3);
-}
-
-static inline u32 msg_origport(struct tipc_msg *m)
-{
- return msg_word(m, 4);
-}
-
-static inline u32 msg_destport(struct tipc_msg *m)
-{
- return msg_word(m, 5);
-}
-
-static inline u32 msg_mc_netid(struct tipc_msg *m)
-{
- return msg_word(m, 5);
-}
-
-static inline u32 msg_orignode(struct tipc_msg *m)
-{
- if (likely(msg_short(m)))
- return msg_prevnode(m);
- return msg_word(m, 6);
-}
-
-static inline u32 msg_destnode(struct tipc_msg *m)
-{
- return msg_word(m, 7);
-}
-
-static inline u32 msg_nametype(struct tipc_msg *m)
-{
- return msg_word(m, 8);
-}
-
-static inline u32 msg_nameinst(struct tipc_msg *m)
-{
- return msg_word(m, 9);
-}
-
-static inline u32 msg_namelower(struct tipc_msg *m)
-{
- return msg_nameinst(m);
-}
-
-static inline u32 msg_nameupper(struct tipc_msg *m)
-{
- return msg_word(m, 10);
-}
-
-#endif
-
-#endif
diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h
deleted file mode 100644
index 1893aaf49426..000000000000
--- a/include/net/tipc/tipc_port.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports
- *
- * Copyright (c) 1994-2007, Ericsson AB
- * Copyright (c) 2005-2008, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _NET_TIPC_PORT_H_
-#define _NET_TIPC_PORT_H_
-
-#ifdef __KERNEL__
-
-#include <linux/tipc.h>
-#include <linux/skbuff.h>
-#include <net/tipc/tipc_msg.h>
-
-#define TIPC_FLOW_CONTROL_WIN 512
-
-/**
- * struct tipc_port - native TIPC port info available to privileged users
- * @usr_handle: pointer to additional user-defined information about port
- * @lock: pointer to spinlock for controlling access to port
- * @connected: non-zero if port is currently connected to a peer port
- * @conn_type: TIPC type used when connection was established
- * @conn_instance: TIPC instance used when connection was established
- * @conn_unacked: number of unacknowledged messages received from peer port
- * @published: non-zero if port has one or more associated names
- * @congested: non-zero if cannot send because of link or port congestion
- * @max_pkt: maximum packet size "hint" used when building messages sent by port
- * @ref: unique reference to port in TIPC object registry
- * @phdr: preformatted message header used when sending messages
- */
-
-struct tipc_port {
- void *usr_handle;
- spinlock_t *lock;
- int connected;
- u32 conn_type;
- u32 conn_instance;
- u32 conn_unacked;
- int published;
- u32 congested;
- u32 max_pkt;
- u32 ref;
- struct tipc_msg phdr;
-};
-
-
-struct tipc_port *tipc_createport_raw(void *usr_handle,
- u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
- void (*wakeup)(struct tipc_port *),
- const u32 importance);
-
-int tipc_reject_msg(struct sk_buff *buf, u32 err);
-
-int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
-
-void tipc_acknowledge(u32 port_ref,u32 ack);
-
-struct tipc_port *tipc_get_port(const u32 ref);
-
-/*
- * The following routines require that the port be locked on entry
- */
-
-int tipc_disconnect_port(struct tipc_port *tp_ptr);
-
-
-#endif
-
-#endif
-
diff --git a/include/net/x25.h b/include/net/x25.h
index 1479cb4a41fc..a06119a05129 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -315,6 +315,8 @@ extern struct list_head x25_route_list;
extern rwlock_t x25_route_list_lock;
extern struct list_head x25_forward_list;
extern rwlock_t x25_forward_list_lock;
+extern struct list_head x25_neigh_list;
+extern rwlock_t x25_neigh_list_lock;
extern int x25_proc_init(void);
extern void x25_proc_exit(void);
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bcfb6b24b019..b9f385da758e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -143,6 +143,7 @@ struct xfrm_state {
struct xfrm_id id;
struct xfrm_selector sel;
struct xfrm_mark mark;
+ u32 tfcpad;
u32 genid;
@@ -805,6 +806,9 @@ __be16 xfrm_flowi_sport(struct flowi *fl)
case IPPROTO_MH:
port = htons(fl->fl_mh_type);
break;
+ case IPPROTO_GRE:
+ port = htons(ntohl(fl->fl_gre_key) >> 16);
+ break;
default:
port = 0; /*XXX*/
}
@@ -826,6 +830,9 @@ __be16 xfrm_flowi_dport(struct flowi *fl)
case IPPROTO_ICMPV6:
port = htons(fl->fl_icmp_code);
break;
+ case IPPROTO_GRE:
+ port = htons(ntohl(fl->fl_gre_key) & 0xffff);
+ break;
default:
port = 0; /*XXX*/
}
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index a8631acd37c3..c3e1cbcc2ad2 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -263,6 +263,7 @@ enum iscsi_err {
ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18,
ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19,
ISCSI_ERR_TCP_CONN_CLOSE = ISCSI_ERR_BASE + 20,
+ ISCSI_ERR_SCSI_EH_SESSION_RST = ISCSI_ERR_BASE + 21,
};
/*
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 5c4c1678f7be..f53c8e31d5fb 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -221,8 +221,8 @@ struct fc_rport_priv {
* @InputRequests: Number of input requests
* @OutputRequests: Number of output requests
* @ControlRequests: Number of control requests
- * @InputMegabytes: Number of received megabytes
- * @OutputMegabytes: Number of transmitted megabytes
+ * @InputBytes: Number of received bytes
+ * @OutputBytes: Number of transmitted bytes
* @VLinkFailureCount: Number of virtual link failures
* @MissDiscAdvCount: Number of missing FIP discovery advertisement
*/
@@ -241,8 +241,8 @@ struct fcoe_dev_stats {
u64 InputRequests;
u64 OutputRequests;
u64 ControlRequests;
- u64 InputMegabytes;
- u64 OutputMegabytes;
+ u64 InputBytes;
+ u64 OutputBytes;
u64 VLinkFailureCount;
u64 MissDiscAdvCount;
};
@@ -263,7 +263,6 @@ struct fc_seq_els_data {
* struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)
* @lp: The associated local port
* @state: The state of the I/O
- * @tgt_flags: Target's flags
* @ref_cnt: Reference count
* @scsi_pkt_lock: Lock to protect the SCSI packet (must be taken before the
* host_lock if both are to be held at the same time)
@@ -298,7 +297,6 @@ struct fc_fcp_pkt {
/* Housekeeping information */
struct fc_lport *lp;
u16 state;
- u16 tgt_flags;
atomic_t ref_cnt;
spinlock_t scsi_pkt_lock;
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 06f1b5a8ed19..feb6a94c90ea 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -92,10 +92,12 @@ enum fip_state {
* @timer_work: &work_struct for doing keep-alives and resets.
* @recv_work: &work_struct for receiving FIP frames.
* @fip_recv_list: list of received FIP frames.
+ * @flogi_req: clone of FLOGI request sent
* @rnd_state: state for pseudo-random number generator.
* @port_id: proposed or selected local-port ID.
* @user_mfs: configured maximum FC frame size, including FC header.
* @flogi_oxid: exchange ID of most recent fabric login.
+ * @flogi_req_send: send of FLOGI requested
* @flogi_count: number of FLOGI attempts in AUTO mode.
* @map_dest: use the FC_MAP mode for destination MAC addresses.
* @spma: supports SPMA server-provided MACs mode
@@ -106,6 +108,7 @@ enum fip_state {
* @update_mac: LLD-supplied function to handle changes to MAC addresses.
* @get_src_addr: LLD-supplied function to supply a source MAC address.
* @ctlr_mutex: lock protecting this structure.
+ * @ctlr_lock: spinlock covering flogi_req
*
* This structure is used by all FCoE drivers. It contains information
* needed by all FCoE low-level drivers (LLDs) as well as internal state
@@ -126,12 +129,14 @@ struct fcoe_ctlr {
struct work_struct timer_work;
struct work_struct recv_work;
struct sk_buff_head fip_recv_list;
+ struct sk_buff *flogi_req;
struct rnd_state rnd_state;
u32 port_id;
u16 user_mfs;
u16 flogi_oxid;
+ u8 flogi_req_send;
u8 flogi_count;
u8 map_dest;
u8 spma;
@@ -143,6 +148,7 @@ struct fcoe_ctlr {
void (*update_mac)(struct fc_lport *, u8 *addr);
u8 * (*get_src_addr)(struct fc_lport *);
struct mutex ctlr_mutex;
+ spinlock_t ctlr_lock;
};
/**
@@ -155,6 +161,7 @@ struct fcoe_ctlr {
* @fcf_mac: Ethernet address of the FCF
* @vfid: virtual fabric ID
* @pri: selection priority, smaller values are better
+ * @flogi_sent: current FLOGI sent to this FCF
* @flags: flags received from advertisement
* @fka_period: keep-alive period, in jiffies
*
@@ -176,6 +183,7 @@ struct fcoe_fcf {
u8 fcf_mac[ETH_ALEN];
u8 pri;
+ u8 flogi_sent;
u16 flags;
u32 fka_period;
u8 fd_flags:1;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index b81d969ddc67..748382b32b52 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -89,6 +89,7 @@ enum {
ISCSI_TASK_RUNNING,
ISCSI_TASK_ABRT_TMF, /* aborted due to TMF */
ISCSI_TASK_ABRT_SESS_RECOV, /* aborted due to session recovery */
+ ISCSI_TASK_REQUEUE_SCSIQ, /* qcmd requeueing to scsi-ml */
};
struct iscsi_r2t_info {
@@ -341,7 +342,7 @@ extern int iscsi_eh_abort(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_Host *h, struct scsi_cmnd *sc);
+extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
/*
* iSCSI host helpers.
@@ -419,6 +420,7 @@ extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
extern void iscsi_requeue_task(struct iscsi_task *task);
extern void iscsi_put_task(struct iscsi_task *task);
+extern void __iscsi_put_task(struct iscsi_task *task);
extern void __iscsi_get_task(struct iscsi_task *task);
extern void iscsi_complete_scsi_task(struct iscsi_task *task,
uint32_t exp_cmdsn, uint32_t max_cmdsn);
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 90ce527ecf3d..8f6bb9c7f3eb 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -361,6 +361,8 @@ struct sas_ha_struct {
/* The class calls this to send a task for execution. */
int lldd_max_execute_num;
int lldd_queue_size;
+ int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
+ * their siblings when forming wide ports */
/* LLDD calls these to notify the class of an event. */
void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 216af8538cc9..648d23358038 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -104,6 +104,7 @@ struct scsi_cmnd;
#define UNMAP 0x42
#define READ_TOC 0x43
#define READ_HEADER 0x44
+#define GET_EVENT_STATUS_NOTIFICATION 0x4a
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
#define XDWRITEREAD_10 0x53
@@ -115,33 +116,61 @@ struct scsi_cmnd;
#define PERSISTENT_RESERVE_OUT 0x5f
#define VARIABLE_LENGTH_CMD 0x7f
#define REPORT_LUNS 0xa0
+#define SECURITY_PROTOCOL_IN 0xa2
#define MAINTENANCE_IN 0xa3
#define MAINTENANCE_OUT 0xa4
#define MOVE_MEDIUM 0xa5
#define EXCHANGE_MEDIUM 0xa6
#define READ_12 0xa8
#define WRITE_12 0xaa
+#define READ_MEDIA_SERIAL_NUMBER 0xab
#define WRITE_VERIFY_12 0xae
#define VERIFY_12 0xaf
#define SEARCH_HIGH_12 0xb0
#define SEARCH_EQUAL_12 0xb1
#define SEARCH_LOW_12 0xb2
+#define SECURITY_PROTOCOL_OUT 0xb5
#define READ_ELEMENT_STATUS 0xb8
#define SEND_VOLUME_TAG 0xb6
#define WRITE_LONG_2 0xea
+#define EXTENDED_COPY 0x83
+#define RECEIVE_COPY_RESULTS 0x84
+#define ACCESS_CONTROL_IN 0x86
+#define ACCESS_CONTROL_OUT 0x87
#define READ_16 0x88
#define WRITE_16 0x8a
+#define READ_ATTRIBUTE 0x8c
+#define WRITE_ATTRIBUTE 0x8d
#define VERIFY_16 0x8f
#define WRITE_SAME_16 0x93
#define SERVICE_ACTION_IN 0x9e
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
#define SAI_GET_LBA_STATUS 0x12
+/* values for VARIABLE_LENGTH_CMD service action codes
+ * see spc4r17 Section D.3.5, table D.7 and D.8 */
+#define VLC_SA_RECEIVE_CREDENTIAL 0x1800
/* values for maintenance in */
+#define MI_REPORT_IDENTIFYING_INFORMATION 0x05
#define MI_REPORT_TARGET_PGS 0x0a
+#define MI_REPORT_ALIASES 0x0b
+#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c
+#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d
+#define MI_REPORT_PRIORITY 0x0e
+#define MI_REPORT_TIMESTAMP 0x0f
+#define MI_MANAGEMENT_PROTOCOL_IN 0x10
/* values for maintenance out */
+#define MO_SET_IDENTIFYING_INFORMATION 0x06
#define MO_SET_TARGET_PGS 0x0a
+#define MO_CHANGE_ALIASES 0x0b
+#define MO_SET_PRIORITY 0x0e
+#define MO_SET_TIMESTAMP 0x0f
+#define MO_MANAGEMENT_PROTOCOL_OUT 0x10
/* values for variable length command */
+#define XDREAD_32 0x03
+#define XDWRITE_32 0x04
+#define XPWRITE_32 0x06
+#define XDWRITEREAD_32 0x07
#define READ_32 0x09
#define VERIFY_32 0x0a
#define WRITE_32 0x0b
diff --git a/include/sound/alc5623.h b/include/sound/alc5623.h
new file mode 100644
index 000000000000..422c97d43df3
--- /dev/null
+++ b/include/sound/alc5623.h
@@ -0,0 +1,15 @@
+#ifndef _INCLUDE_SOUND_ALC5623_H
+#define _INCLUDE_SOUND_ALC5623_H
+struct alc5623_platform_data {
+ /* configure : */
+ /* Lineout/Speaker Amps Vmid ratio control */
+ /* enable/disable adc/dac high pass filters */
+ unsigned int add_ctrl;
+ /* configure : */
+ /* output to enable when jack is low */
+ /* output to enable when jack is high */
+ /* jack detect (gpio/nc/jack detect [12] */
+ unsigned int jack_det_ctrl;
+};
+#endif
+
diff --git a/include/sound/asound.h b/include/sound/asound.h
index a1803ecea34d..5d6074faa279 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -259,6 +259,7 @@ typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
+#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */
#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */
typedef int __bitwise snd_pcm_state_t;
@@ -334,6 +335,8 @@ typedef int snd_pcm_hw_param_t;
#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
+#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */
+#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */
struct snd_interval {
unsigned int min, max;
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
index d98a78dff2db..0909a3843479 100644
--- a/include/sound/hdsp.h
+++ b/include/sound/hdsp.h
@@ -28,6 +28,7 @@ enum HDSP_IO_Type {
Multiface,
H9652,
H9632,
+ RPM,
Undefined,
};
diff --git a/include/sound/minors.h b/include/sound/minors.h
index a81798ab73ed..8f764204a856 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -31,8 +31,8 @@
/* these minors can still be used for autoloading devices (/dev/aload*) */
#define SNDRV_MINOR_CONTROL 0 /* 0 */
#define SNDRV_MINOR_GLOBAL 1 /* 1 */
-#define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32)
-#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32)
+#define SNDRV_MINOR_SEQUENCER 1 /* SNDRV_MINOR_GLOBAL + 0 * 32 */
+#define SNDRV_MINOR_TIMER 33 /* SNDRV_MINOR_GLOBAL + 1 * 32 */
#ifndef CONFIG_SND_DYNAMIC_MINORS
/* 2 - 3 (reserved) */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index dfd9b76b1853..e731f8d71934 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -297,6 +297,7 @@ struct snd_pcm_runtime {
unsigned int info;
unsigned int rate_num;
unsigned int rate_den;
+ unsigned int no_period_wakeup: 1;
/* -- SW params -- */
int tstamp_mode; /* mmap timestamp is updated */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index e7b680248006..1bafe95dcf41 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -16,8 +16,6 @@
#include <linux/list.h>
-#include <sound/soc.h>
-
struct snd_pcm_substream;
/*
@@ -205,7 +203,7 @@ struct snd_soc_dai_driver {
int (*resume)(struct snd_soc_dai *dai);
/* ops */
- struct snd_soc_dai_ops *ops;
+ const struct snd_soc_dai_ops *ops;
/* DAI capabilities */
struct snd_soc_pcm_stream capture;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8fd3b41b763f..8031769ac485 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -16,7 +16,6 @@
#include <linux/device.h>
#include <linux/types.h>
#include <sound/control.h>
-#include <sound/soc.h>
/* widget has no PM register bit */
#define SND_SOC_NOPM -1
@@ -72,6 +71,10 @@
wcontrols, wncontrols) \
{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
+ wcontrols, wncontrols) \
+{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols}
#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
wcontrols, wncontrols)\
{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
@@ -90,6 +93,9 @@
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1}
+#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
+{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .kcontrols = wcontrols, \
@@ -116,6 +122,11 @@
{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
+ wncontrols, wevent, wflags) \
+{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
+ .event = wevent, .event_flags = wflags}
#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
wncontrols, wevent, wflags) \
{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
@@ -140,6 +151,11 @@
{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \
.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
+ wevent, wflags) \
+{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \
+ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \
+ .event = wevent, .event_flags = wflags}
/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
@@ -219,13 +235,6 @@
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-#define SOC_DAPM_DOUBLE(xname, reg, shift_left, shift_right, max, invert, \
- power) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
- .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\
- ((max) << 16) | ((invert) << 24) }
#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
@@ -233,15 +242,6 @@
.tlv.p = (tlv_array), \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-#define SOC_DAPM_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, \
- power, tlv_array) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .tlv.p = (tlv_array), \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
- .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\
- ((max) << 16) | ((invert) << 24) }
#define SOC_DAPM_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_enum_double, \
@@ -297,6 +297,7 @@ enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
struct snd_soc_dapm_pin;
struct snd_soc_dapm_route;
+struct snd_soc_dapm_context;
int dapm_reg_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
@@ -324,16 +325,16 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
-int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
-int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num);
/* dapm path setup */
-int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
-void snd_soc_dapm_free(struct snd_soc_codec *codec);
-int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
+void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
/* dapm events */
@@ -343,27 +344,33 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card);
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm);
/* dapm audio pin control and status */
-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin);
-int snd_soc_dapm_sync(struct snd_soc_codec *codec);
-int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec,
+int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
+int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
+ const char *pin);
+int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin);
-int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin);
+int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
+ const char *pin);
/* dapm widget types */
enum snd_soc_dapm_type {
snd_soc_dapm_input = 0, /* input pin */
snd_soc_dapm_output, /* output pin */
snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */
+ snd_soc_dapm_virt_mux, /* virtual version of snd_soc_dapm_mux */
snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */
snd_soc_dapm_mixer, /* mixes several analog signals together */
snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */
snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */
+ snd_soc_dapm_out_drv, /* output driver */
snd_soc_dapm_adc, /* analog to digital converter */
snd_soc_dapm_dac, /* digital to analog converter */
snd_soc_dapm_micbias, /* microphone bias (power) */
@@ -425,6 +432,7 @@ struct snd_soc_dapm_widget {
char *sname; /* stream name */
struct snd_soc_codec *codec;
struct list_head list;
+ struct snd_soc_dapm_context *dapm;
/* dapm control */
short reg; /* negative reg = no direct dapm */
@@ -461,4 +469,35 @@ struct snd_soc_dapm_widget {
struct list_head power_list;
};
+struct snd_soc_dapm_update {
+ struct snd_soc_dapm_widget *widget;
+ struct snd_kcontrol *kcontrol;
+ int reg;
+ int mask;
+ int val;
+};
+
+/* DAPM context */
+struct snd_soc_dapm_context {
+ int n_widgets; /* number of widgets in this context */
+ enum snd_soc_bias_level bias_level;
+ enum snd_soc_bias_level suspend_bias_level;
+ struct delayed_work delayed_work;
+ unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
+
+ struct snd_soc_dapm_update *update;
+
+ struct device *dev; /* from parent - for debug */
+ struct snd_soc_codec *codec; /* parent codec */
+ struct snd_soc_card *card; /* parent card */
+
+ /* used during DAPM updates */
+ int dev_power;
+ struct list_head list;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_dapm;
+#endif
+};
+
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 5c3bce83f28a..74921f20a1d8 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -222,10 +222,8 @@ enum snd_soc_bias_level {
struct snd_jack;
struct snd_soc_card;
-struct snd_soc_device;
struct snd_soc_pcm_stream;
struct snd_soc_ops;
-struct snd_soc_dai_mode;
struct snd_soc_pcm_runtime;
struct snd_soc_dai;
struct snd_soc_dai_driver;
@@ -235,9 +233,10 @@ struct snd_soc_platform_driver;
struct snd_soc_codec;
struct snd_soc_codec_driver;
struct soc_enum;
-struct snd_soc_ac97_ops;
struct snd_soc_jack;
struct snd_soc_jack_pin;
+struct snd_soc_cache_ops;
+#include <sound/soc-dapm.h>
#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio;
@@ -253,17 +252,30 @@ enum snd_soc_control_type {
SND_SOC_SPI,
};
+enum snd_soc_compress_type {
+ SND_SOC_FLAT_COMPRESSION = 1,
+ SND_SOC_LZO_COMPRESSION,
+ SND_SOC_RBTREE_COMPRESSION
+};
+
int snd_soc_register_platform(struct device *dev,
struct snd_soc_platform_driver *platform_drv);
void snd_soc_unregister_platform(struct device *dev);
int snd_soc_register_codec(struct device *dev,
- struct snd_soc_codec_driver *codec_drv,
+ const struct snd_soc_codec_driver *codec_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_codec(struct device *dev);
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
int addr_bits, int data_bits,
enum snd_soc_control_type control);
+int snd_soc_cache_sync(struct snd_soc_codec *codec);
+int snd_soc_cache_init(struct snd_soc_codec *codec);
+int snd_soc_cache_exit(struct snd_soc_codec *codec);
+int snd_soc_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value);
+int snd_soc_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -420,23 +432,37 @@ struct snd_soc_ops {
int (*trigger)(struct snd_pcm_substream *, int);
};
+/* SoC cache ops */
+struct snd_soc_cache_ops {
+ const char *name;
+ enum snd_soc_compress_type id;
+ int (*init)(struct snd_soc_codec *codec);
+ int (*exit)(struct snd_soc_codec *codec);
+ int (*read)(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int *value);
+ int (*write)(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value);
+ int (*sync)(struct snd_soc_codec *codec);
+};
+
/* SoC Audio Codec device */
struct snd_soc_codec {
const char *name;
+ const char *name_prefix;
int id;
struct device *dev;
- struct snd_soc_codec_driver *driver;
+ const struct snd_soc_codec_driver *driver;
struct mutex mutex;
struct snd_soc_card *card;
struct list_head list;
struct list_head card_list;
int num_dai;
+ enum snd_soc_compress_type compress_type;
/* runtime */
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
unsigned int active;
- unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
unsigned int cache_only:1; /* Suppress writes to hardware */
unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
unsigned int suspended:1; /* Codec is in suspend PM state */
@@ -444,25 +470,25 @@ struct snd_soc_codec {
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
+ unsigned int cache_init:1; /* codec cache has been initialized */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
+ unsigned int (*read)(struct snd_soc_codec *, unsigned int);
+ int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
void *reg_cache;
+ const void *reg_def_copy;
+ const struct snd_soc_cache_ops *cache_ops;
+ struct mutex cache_rw_mutex;
/* dapm */
- u32 pop_time;
- struct list_head dapm_widgets;
- struct list_head dapm_paths;
- enum snd_soc_bias_level bias_level;
- enum snd_soc_bias_level suspend_bias_level;
- struct delayed_work delayed_work;
+ struct snd_soc_dapm_context dapm;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root;
struct dentry *debugfs_reg;
- struct dentry *debugfs_pop_time;
struct dentry *debugfs_dapm;
#endif
};
@@ -488,6 +514,7 @@ struct snd_soc_codec_driver {
short reg_cache_step;
short reg_word_size;
const void *reg_cache_default;
+ enum snd_soc_compress_type compress_type;
/* codec bias level */
int (*set_bias_level)(struct snd_soc_codec *,
@@ -554,6 +581,30 @@ struct snd_soc_dai_link {
struct snd_soc_ops *ops;
};
+struct snd_soc_codec_conf {
+ const char *dev_name;
+
+ /*
+ * optional map of kcontrol, widget and path name prefixes that are
+ * associated per device
+ */
+ const char *name_prefix;
+
+ /*
+ * set this to the desired compression type if you want to
+ * override the one supplied in codec->driver->compress_type
+ */
+ enum snd_soc_compress_type compress_type;
+};
+
+struct snd_soc_aux_dev {
+ const char *name; /* Codec name */
+ const char *codec_name; /* for multi-codec */
+
+ /* codec/machine specific init - e.g. add machine controls */
+ int (*init)(struct snd_soc_dapm_context *dapm);
+};
+
/* SoC card */
struct snd_soc_card {
const char *name;
@@ -579,6 +630,8 @@ struct snd_soc_card {
/* callbacks */
int (*set_bias_level)(struct snd_soc_card *,
enum snd_soc_bias_level level);
+ int (*set_bias_level_post)(struct snd_soc_card *,
+ enum snd_soc_bias_level level);
long pmdown_time;
@@ -588,12 +641,35 @@ struct snd_soc_card {
struct snd_soc_pcm_runtime *rtd;
int num_rtd;
+ /* optional codec specific configuration */
+ struct snd_soc_codec_conf *codec_conf;
+ int num_configs;
+
+ /*
+ * optional auxiliary devices such as amplifiers or codecs with DAI
+ * link unused
+ */
+ struct snd_soc_aux_dev *aux_dev;
+ int num_aux_devs;
+ struct snd_soc_pcm_runtime *rtd_aux;
+ int num_aux_rtd;
+
struct work_struct deferred_resume_work;
/* lists of probed devices belonging to this card */
struct list_head codec_dev_list;
struct list_head platform_dev_list;
struct list_head dai_dev_list;
+
+ struct list_head widgets;
+ struct list_head paths;
+ struct list_head dapm_list;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_card_root;
+ struct dentry *debugfs_pop_time;
+#endif
+ u32 pop_time;
};
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
@@ -639,17 +715,9 @@ struct soc_enum {
};
/* codec IO */
-static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return codec->driver->read(codec, reg);
-}
-
-static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val)
-{
- return codec->driver->write(codec, reg, val);
-}
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
+unsigned int snd_soc_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int val);
/* device driver data */
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
new file mode 100644
index 000000000000..186e84db4b54
--- /dev/null
+++ b/include/trace/events/asoc.h
@@ -0,0 +1,235 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM asoc
+
+#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ASOC_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+struct snd_soc_jack;
+struct snd_soc_codec;
+struct snd_soc_card;
+struct snd_soc_dapm_widget;
+
+/*
+ * Log register events
+ */
+DECLARE_EVENT_CLASS(snd_soc_reg,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val),
+
+ TP_STRUCT__entry(
+ __string( name, codec->name )
+ __field( int, id )
+ __field( unsigned int, reg )
+ __field( unsigned int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, codec->name);
+ __entry->id = codec->id;
+ __entry->reg = reg;
+ __entry->val = val;
+ ),
+
+ TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name),
+ (int)__entry->id, (unsigned int)__entry->reg,
+ (unsigned int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val)
+
+);
+
+DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read,
+
+ TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int val),
+
+ TP_ARGS(codec, reg, val)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_card,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val),
+
+ TP_STRUCT__entry(
+ __string( name, card->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, card->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val)
+
+);
+
+DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done,
+
+ TP_PROTO(struct snd_soc_card *card, int val),
+
+ TP_ARGS(card, val)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_dapm_basic,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card),
+
+ TP_STRUCT__entry(
+ __string( name, card->name )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, card->name);
+ ),
+
+ TP_printk("card=%s", __get_str(name))
+);
+
+DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card)
+
+);
+
+DECLARE_EVENT_CLASS(snd_soc_dapm_widget,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val),
+
+ TP_STRUCT__entry(
+ __string( name, w->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, w->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("widget=%s val=%d", __get_str(name),
+ (int)__entry->val)
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done,
+
+ TP_PROTO(struct snd_soc_dapm_widget *w, int val),
+
+ TP_ARGS(w, val)
+
+);
+
+TRACE_EVENT(snd_soc_jack_irq,
+
+ TP_PROTO(const char *name),
+
+ TP_ARGS(name),
+
+ TP_STRUCT__entry(
+ __string( name, name )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
+
+TRACE_EVENT(snd_soc_jack_report,
+
+ TP_PROTO(struct snd_soc_jack *jack, int mask, int val),
+
+ TP_ARGS(jack, mask, val),
+
+ TP_STRUCT__entry(
+ __string( name, jack->jack->name )
+ __field( int, mask )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, jack->jack->name);
+ __entry->mask = mask;
+ __entry->val = val;
+ ),
+
+ TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val,
+ (int)__entry->mask)
+);
+
+TRACE_EVENT(snd_soc_jack_notify,
+
+ TP_PROTO(struct snd_soc_jack *jack, int val),
+
+ TP_ARGS(jack, val),
+
+ TP_STRUCT__entry(
+ __string( name, jack->jack->name )
+ __field( int, val )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, jack->jack->name);
+ __entry->val = val;
+ ),
+
+ TP_printk("jack=%s %x", __get_str(name), (int)__entry->val)
+);
+
+#endif /* _TRACE_ASOC_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index d8ce278515c3..b56c65dc105d 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -486,16 +486,16 @@ TRACE_EVENT(block_split,
);
/**
- * block_remap - map request for a partition to the raw device
+ * block_bio_remap - map request for a logical device 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
+ * An operation for a logical device has been mapped to the
* raw block device.
*/
-TRACE_EVENT(block_remap,
+TRACE_EVENT(block_bio_remap,
TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
sector_t from),
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 6dd3a51ab1cb..46e3cd8e197a 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -6,6 +6,36 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvm
+#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x }
+
+#define kvm_trace_exit_reason \
+ ERSN(UNKNOWN), ERSN(EXCEPTION), ERSN(IO), ERSN(HYPERCALL), \
+ ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN), \
+ ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR), \
+ ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\
+ ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI)
+
+TRACE_EVENT(kvm_userspace_exit,
+ TP_PROTO(__u32 reason, int errno),
+ TP_ARGS(reason, errno),
+
+ TP_STRUCT__entry(
+ __field( __u32, reason )
+ __field( int, errno )
+ ),
+
+ TP_fast_assign(
+ __entry->reason = reason;
+ __entry->errno = errno;
+ ),
+
+ TP_printk("reason %s (%d)",
+ __entry->errno < 0 ?
+ (__entry->errno == -EINTR ? "restart" : "error") :
+ __print_symbolic(__entry->reason, kvm_trace_exit_reason),
+ __entry->errno < 0 ? -__entry->errno : __entry->reason)
+);
+
#if defined(__KVM_HAVE_IOAPIC)
TRACE_EVENT(kvm_set_irq,
TP_PROTO(unsigned int gsi, int level, int irq_source_id),
@@ -185,6 +215,97 @@ TRACE_EVENT(kvm_age_page,
__entry->referenced ? "YOUNG" : "OLD")
);
+#ifdef CONFIG_KVM_ASYNC_PF
+DECLARE_EVENT_CLASS(kvm_async_get_page_class,
+
+ TP_PROTO(u64 gva, u64 gfn),
+
+ TP_ARGS(gva, gfn),
+
+ TP_STRUCT__entry(
+ __field(__u64, gva)
+ __field(u64, gfn)
+ ),
+
+ TP_fast_assign(
+ __entry->gva = gva;
+ __entry->gfn = gfn;
+ ),
+
+ TP_printk("gva = %#llx, gfn = %#llx", __entry->gva, __entry->gfn)
+);
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_try_async_get_page,
+
+ TP_PROTO(u64 gva, u64 gfn),
+
+ TP_ARGS(gva, gfn)
+);
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_async_pf_doublefault,
+
+ TP_PROTO(u64 gva, u64 gfn),
+
+ TP_ARGS(gva, gfn)
+);
+
+DECLARE_EVENT_CLASS(kvm_async_pf_nopresent_ready,
+
+ TP_PROTO(u64 token, u64 gva),
+
+ TP_ARGS(token, gva),
+
+ TP_STRUCT__entry(
+ __field(__u64, token)
+ __field(__u64, gva)
+ ),
+
+ TP_fast_assign(
+ __entry->token = token;
+ __entry->gva = gva;
+ ),
+
+ TP_printk("token %#llx gva %#llx", __entry->token, __entry->gva)
+
+);
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_not_present,
+
+ TP_PROTO(u64 token, u64 gva),
+
+ TP_ARGS(token, gva)
+);
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_ready,
+
+ TP_PROTO(u64 token, u64 gva),
+
+ TP_ARGS(token, gva)
+);
+
+TRACE_EVENT(
+ kvm_async_pf_completed,
+ TP_PROTO(unsigned long address, struct page *page, u64 gva),
+ TP_ARGS(address, page, gva),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, address)
+ __field(pfn_t, pfn)
+ __field(u64, gva)
+ ),
+
+ TP_fast_assign(
+ __entry->address = address;
+ __entry->pfn = page ? page_to_pfn(page) : 0;
+ __entry->gva = gva;
+ ),
+
+ TP_printk("gva %#llx address %#lx pfn %#llx", __entry->gva,
+ __entry->address, __entry->pfn)
+);
+
+#endif
+
#endif /* _TRACE_KVM_MAIN_H */
/* This part must be outside protection */
diff --git a/include/xen/events.h b/include/xen/events.h
index 646dd17d3aa4..00f53ddcc062 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -76,7 +76,9 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
#ifdef CONFIG_PCI_MSI
/* Allocate an irq and a pirq to be used with MSIs. */
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq);
+#define XEN_ALLOC_PIRQ (1 << 0)
+#define XEN_ALLOC_IRQ (1 << 1)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_mask);
int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type);
#endif
@@ -89,4 +91,7 @@ int xen_vector_from_irq(unsigned pirq);
/* Return gsi allocated to pirq */
int xen_gsi_from_irq(unsigned pirq);
+/* Return irq from pirq */
+int xen_irq_from_pirq(unsigned pirq);
+
#endif /* _XEN_EVENTS_H */
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index e8cbf431c8cc..75271b9a8f61 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -24,8 +24,15 @@ typedef unsigned int RING_IDX;
* A ring contains as many entries as will fit, rounded down to the nearest
* power of two (so we can mask with (size-1) to loop around).
*/
-#define __RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+#define __CONST_RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
+ sizeof(((struct _s##_sring *)0)->ring[0])))
+
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
/*
* Macros to make the correct C datatypes for a new kind of ring.
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index 2b2c66c3df00..534cac89a77d 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -188,6 +188,16 @@ struct physdev_nr_pirqs {
uint32_t nr_pirqs;
};
+/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
+ * the hypercall returns a free pirq */
+#define PHYSDEVOP_get_free_pirq 23
+struct physdev_get_free_pirq {
+ /* IN */
+ int type;
+ /* OUT */
+ uint32_t pirq;
+};
+
/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 830aaec9c7d5..2b54bef33b55 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -93,7 +93,7 @@ no_match:
*
* Returns the matching dev_t on success or 0 on failure.
*/
-static dev_t __init devt_from_partuuid(char *uuid_str)
+static dev_t devt_from_partuuid(char *uuid_str)
{
dev_t res = 0;
struct device *dev = NULL;
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 035f4399edbc..14fb6d67e6a3 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -237,11 +237,18 @@ static struct inode *mqueue_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void mqueue_destroy_inode(struct inode *inode)
+static void mqueue_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode));
}
+static void mqueue_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, mqueue_i_callback);
+}
+
static void mqueue_evict_inode(struct inode *inode)
{
struct mqueue_inode_info *info;
diff --git a/kernel/Makefile b/kernel/Makefile
index 0b5ff083fa22..33e0a39cf359 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -121,7 +121,7 @@ $(obj)/configs.o: $(obj)/config_data.h
# config_data.h contains the same information as ikconfig.h but gzipped.
# Info from config_data can be extracted from /proc/config*
targets += config_data.gz
-$(obj)/config_data.gz: .config FORCE
+$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
$(call if_changed,gzip)
quiet_cmd_ikconfiggz = IKCFG $@
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 66a416b42c18..51cddc11cd85 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -763,6 +763,8 @@ EXPORT_SYMBOL_GPL(cgroup_unlock);
* -> cgroup_mkdir.
*/
+static struct dentry *cgroup_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd);
static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
static int cgroup_populate_dir(struct cgroup *cgrp);
@@ -874,25 +876,29 @@ static void cgroup_clear_directory(struct dentry *dentry)
struct list_head *node;
BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
- spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
node = dentry->d_subdirs.next;
while (node != &dentry->d_subdirs) {
struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+
+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
list_del_init(node);
if (d->d_inode) {
/* This should never be called on a cgroup
* directory with child cgroups */
BUG_ON(d->d_inode->i_mode & S_IFDIR);
- d = dget_locked(d);
- spin_unlock(&dcache_lock);
+ dget_dlock(d);
+ spin_unlock(&d->d_lock);
+ spin_unlock(&dentry->d_lock);
d_delete(d);
simple_unlink(dentry->d_inode, d);
dput(d);
- spin_lock(&dcache_lock);
- }
+ spin_lock(&dentry->d_lock);
+ } else
+ spin_unlock(&d->d_lock);
node = dentry->d_subdirs.next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
}
/*
@@ -900,11 +906,16 @@ static void cgroup_clear_directory(struct dentry *dentry)
*/
static void cgroup_d_remove_dir(struct dentry *dentry)
{
+ struct dentry *parent;
+
cgroup_clear_directory(dentry);
- spin_lock(&dcache_lock);
+ parent = dentry->d_parent;
+ spin_lock(&parent->d_lock);
+ spin_lock(&dentry->d_lock);
list_del_init(&dentry->d_u.d_child);
- spin_unlock(&dcache_lock);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&parent->d_lock);
remove_dir(dentry);
}
@@ -2180,7 +2191,7 @@ static const struct file_operations cgroup_file_operations = {
};
static const struct inode_operations cgroup_dir_inode_operations = {
- .lookup = simple_lookup,
+ .lookup = cgroup_lookup,
.mkdir = cgroup_mkdir,
.rmdir = cgroup_rmdir,
.rename = cgroup_rename,
@@ -2196,13 +2207,29 @@ static inline struct cftype *__file_cft(struct file *file)
return __d_cft(file->f_dentry);
}
-static int cgroup_create_file(struct dentry *dentry, mode_t mode,
- struct super_block *sb)
+static int cgroup_delete_dentry(const struct dentry *dentry)
+{
+ return 1;
+}
+
+static struct dentry *cgroup_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd)
{
- static const struct dentry_operations cgroup_dops = {
+ static const struct dentry_operations cgroup_dentry_operations = {
+ .d_delete = cgroup_delete_dentry,
.d_iput = cgroup_diput,
};
+ if (dentry->d_name.len > NAME_MAX)
+ return ERR_PTR(-ENAMETOOLONG);
+ d_set_d_op(dentry, &cgroup_dentry_operations);
+ d_add(dentry, NULL);
+ return NULL;
+}
+
+static int cgroup_create_file(struct dentry *dentry, mode_t mode,
+ struct super_block *sb)
+{
struct inode *inode;
if (!dentry)
@@ -2228,7 +2255,6 @@ static int cgroup_create_file(struct dentry *dentry, mode_t mode,
inode->i_size = 0;
inode->i_fop = &cgroup_file_operations;
}
- dentry->d_op = &cgroup_dops;
d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */
return 0;
@@ -3638,9 +3664,7 @@ again:
list_del(&cgrp->sibling);
cgroup_unlock_hierarchy(cgrp->root);
- spin_lock(&cgrp->dentry->d_lock);
d = dget(cgrp->dentry);
- spin_unlock(&d->d_lock);
cgroup_d_remove_dir(d);
dput(d);
diff --git a/kernel/exit.c b/kernel/exit.c
index 21aa7b3001fb..676149a4ac5f 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -914,6 +914,15 @@ NORET_TYPE void do_exit(long code)
if (unlikely(!tsk->pid))
panic("Attempted to kill the idle task!");
+ /*
+ * If do_exit is called because this processes oopsed, it's possible
+ * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
+ * continuing. Amongst other possible reasons, this is to prevent
+ * mm_release()->clear_child_tid() from writing to a user-controlled
+ * kernel address.
+ */
+ set_fs(USER_DS);
+
tracehook_report_exit(&code);
validate_creds_for_do_exit(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index 3b159c5991b7..5447dc7defa9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -273,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
setup_thread_stack(tsk, orig);
clear_user_return_notifier(tsk);
+ clear_tsk_need_resched(tsk);
stackend = end_of_stack(tsk);
*stackend = STACK_END_MAGIC; /* for overflow detection */
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 01b1d3a88983..6c8a2a9f8a7b 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -214,7 +214,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v)
static int irq_spurious_proc_open(struct inode *inode, struct file *file)
{
- return single_open(file, irq_spurious_proc_show, NULL);
+ return single_open(file, irq_spurious_proc_show, PDE(inode)->data);
}
static const struct file_operations irq_spurious_proc_fops = {
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 2dc3786349d1..ca61bbdd44b2 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -265,6 +265,17 @@ int kthreadd(void *unused)
return 0;
}
+void __init_kthread_worker(struct kthread_worker *worker,
+ const char *name,
+ struct lock_class_key *key)
+{
+ spin_lock_init(&worker->lock);
+ lockdep_set_class_and_name(&worker->lock, key, name);
+ INIT_LIST_HEAD(&worker->work_list);
+ worker->task = NULL;
+}
+EXPORT_SYMBOL_GPL(__init_kthread_worker);
+
/**
* kthread_worker_fn - kthread function to process kthread_worker
* @worker_ptr: pointer to initialized kthread_worker
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 200407c1502f..a5889fb28ecf 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -199,7 +199,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
* memory barriers as we'll eventually observe the right
* values at the cost of a few extra spins.
*/
- cpu_relax();
+ arch_mutex_cpu_relax();
}
#endif
spin_lock_mutex(&lock->wait_lock, flags);
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index eac7e3364335..2870feee81dd 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3824,6 +3824,8 @@ static void perf_event_task_event(struct perf_task_event *task_event)
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+ if (cpuctx->active_pmu != pmu)
+ goto next;
perf_event_task_ctx(&cpuctx->ctx, task_event);
ctx = task_event->task_ctx;
@@ -3959,6 +3961,8 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+ if (cpuctx->active_pmu != pmu)
+ goto next;
perf_event_comm_ctx(&cpuctx->ctx, comm_event);
ctxn = pmu->task_ctx_nr;
@@ -4144,6 +4148,8 @@ got_name:
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+ if (cpuctx->active_pmu != pmu)
+ goto next;
perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
vma->vm_flags & VM_EXEC);
@@ -4713,7 +4719,7 @@ static int perf_swevent_init(struct perf_event *event)
break;
}
- if (event_id > PERF_COUNT_SW_MAX)
+ if (event_id >= PERF_COUNT_SW_MAX)
return -ENOENT;
if (!event->parent) {
@@ -5145,20 +5151,36 @@ static void *find_pmu_context(int ctxn)
return NULL;
}
-static void free_pmu_context(void * __percpu cpu_context)
+static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
{
- struct pmu *pmu;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ struct perf_cpu_context *cpuctx;
+
+ cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
+
+ if (cpuctx->active_pmu == old_pmu)
+ cpuctx->active_pmu = pmu;
+ }
+}
+
+static void free_pmu_context(struct pmu *pmu)
+{
+ struct pmu *i;
mutex_lock(&pmus_lock);
/*
* Like a real lame refcount.
*/
- list_for_each_entry(pmu, &pmus, entry) {
- if (pmu->pmu_cpu_context == cpu_context)
+ list_for_each_entry(i, &pmus, entry) {
+ if (i->pmu_cpu_context == pmu->pmu_cpu_context) {
+ update_pmu_context(i, pmu);
goto out;
+ }
}
- free_percpu(cpu_context);
+ free_percpu(pmu->pmu_cpu_context);
out:
mutex_unlock(&pmus_lock);
}
@@ -5190,6 +5212,7 @@ int perf_pmu_register(struct pmu *pmu)
cpuctx->ctx.pmu = pmu;
cpuctx->jiffies_interval = 1;
INIT_LIST_HEAD(&cpuctx->rotation_list);
+ cpuctx->active_pmu = pmu;
}
got_cpu_context:
@@ -5241,7 +5264,7 @@ void perf_pmu_unregister(struct pmu *pmu)
synchronize_rcu();
free_percpu(pmu->pmu_disable_count);
- free_pmu_context(pmu->pmu_cpu_context);
+ free_pmu_context(pmu);
}
struct pmu *perf_init_event(struct perf_event *event)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 657272e91d0a..048d0b514831 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -327,7 +327,6 @@ 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)
@@ -339,7 +338,7 @@ int hibernation_snapshot(int platform_mode)
goto Close;
suspend_console();
- saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+ pm_restrict_gfp_mask();
error = dpm_suspend_start(PMSG_FREEZE);
if (error)
goto Recover_platform;
@@ -348,7 +347,10 @@ int hibernation_snapshot(int platform_mode)
goto Recover_platform;
error = create_image(platform_mode);
- /* Control returns here after successful restore */
+ /*
+ * Control returns here (1) after the image has been created or the
+ * image creation has failed and (2) after a successful restore.
+ */
Resume_devices:
/* We may need to release the preallocated image pages here. */
@@ -357,7 +359,10 @@ int hibernation_snapshot(int platform_mode)
dpm_resume_end(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
- set_gfp_allowed_mask(saved_mask);
+
+ if (error || !in_suspend)
+ pm_restore_gfp_mask();
+
resume_console();
Close:
platform_end(platform_mode);
@@ -452,17 +457,16 @@ 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);
+ pm_restrict_gfp_mask();
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);
+ pm_restore_gfp_mask();
resume_console();
pm_restore_console();
return error;
@@ -476,7 +480,6 @@ int hibernation_restore(int platform_mode)
int hibernation_platform_enter(void)
{
int error;
- gfp_t saved_mask;
if (!hibernation_ops)
return -ENOSYS;
@@ -492,7 +495,6 @@ 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)
@@ -536,7 +538,6 @@ 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:
@@ -646,6 +647,7 @@ int hibernate(void)
swsusp_free();
if (!error)
power_down();
+ pm_restore_gfp_mask();
} else {
pr_debug("PM: Image restored successfully.\n");
}
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 7335952ee473..ecf770509d0d 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -197,7 +197,6 @@ 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;
@@ -208,7 +207,7 @@ int suspend_devices_and_enter(suspend_state_t state)
goto Close;
}
suspend_console();
- saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+ pm_restrict_gfp_mask();
suspend_test_start();
error = dpm_suspend_start(PMSG_SUSPEND);
if (error) {
@@ -225,7 +224,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);
+ pm_restore_gfp_mask();
resume_console();
Close:
if (suspend_ops->end)
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index a0e4a86ccf94..d53e91e4bd55 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -6,6 +6,7 @@
*
* Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
* Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ * Copyright (C) 2010 Bojan Smojver <bojan@rexursive.com>
*
* This file is released under the GPLv2.
*
@@ -29,7 +30,7 @@
#include "power.h"
-#define HIBERNATE_SIG "LINHIB0001"
+#define HIBERNATE_SIG "S1SUSPEND"
/*
* The swap map is a data structure used for keeping track of each page
@@ -223,7 +224,7 @@ static int swsusp_swap_check(void)
return res;
root_swap = res;
- res = blkdev_get(hib_resume_bdev, FMODE_WRITE);
+ res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
if (res)
return res;
@@ -753,30 +754,43 @@ static int load_image_lzo(struct swap_map_handle *handle,
{
unsigned int m;
int error = 0;
+ struct bio *bio;
struct timeval start;
struct timeval stop;
unsigned nr_pages;
- size_t off, unc_len, cmp_len;
- unsigned char *unc, *cmp, *page;
+ size_t i, off, unc_len, cmp_len;
+ unsigned char *unc, *cmp, *page[LZO_CMP_PAGES];
- page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
- if (!page) {
- printk(KERN_ERR "PM: Failed to allocate LZO page\n");
- return -ENOMEM;
+ for (i = 0; i < LZO_CMP_PAGES; i++) {
+ page[i] = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
+ if (!page[i]) {
+ printk(KERN_ERR "PM: Failed to allocate LZO page\n");
+
+ while (i)
+ free_page((unsigned long)page[--i]);
+
+ return -ENOMEM;
+ }
}
unc = vmalloc(LZO_UNC_SIZE);
if (!unc) {
printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
- free_page((unsigned long)page);
+
+ for (i = 0; i < LZO_CMP_PAGES; i++)
+ free_page((unsigned long)page[i]);
+
return -ENOMEM;
}
cmp = vmalloc(LZO_CMP_SIZE);
if (!cmp) {
printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
+
vfree(unc);
- free_page((unsigned long)page);
+ for (i = 0; i < LZO_CMP_PAGES; i++)
+ free_page((unsigned long)page[i]);
+
return -ENOMEM;
}
@@ -787,6 +801,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
if (!m)
m = 1;
nr_pages = 0;
+ bio = NULL;
do_gettimeofday(&start);
error = snapshot_write_next(snapshot);
@@ -794,11 +809,11 @@ static int load_image_lzo(struct swap_map_handle *handle,
goto out_finish;
for (;;) {
- error = swap_read_page(handle, page, NULL); /* sync */
+ error = swap_read_page(handle, page[0], NULL); /* sync */
if (error)
break;
- cmp_len = *(size_t *)page;
+ cmp_len = *(size_t *)page[0];
if (unlikely(!cmp_len ||
cmp_len > lzo1x_worst_compress(LZO_UNC_SIZE))) {
printk(KERN_ERR "PM: Invalid LZO compressed length\n");
@@ -806,13 +821,20 @@ static int load_image_lzo(struct swap_map_handle *handle,
break;
}
- memcpy(cmp, page, PAGE_SIZE);
- for (off = PAGE_SIZE; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
- error = swap_read_page(handle, page, NULL); /* sync */
+ for (off = PAGE_SIZE, i = 1;
+ off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+ error = swap_read_page(handle, page[i], &bio);
if (error)
goto out_finish;
+ }
- memcpy(cmp + off, page, PAGE_SIZE);
+ error = hib_wait_on_bio_chain(&bio); /* need all data now */
+ if (error)
+ goto out_finish;
+
+ for (off = 0, i = 0;
+ off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+ memcpy(cmp + off, page[i], PAGE_SIZE);
}
unc_len = LZO_UNC_SIZE;
@@ -857,7 +879,8 @@ out_finish:
vfree(cmp);
vfree(unc);
- free_page((unsigned long)page);
+ for (i = 0; i < LZO_CMP_PAGES; i++)
+ free_page((unsigned long)page[i]);
return error;
}
@@ -907,7 +930,8 @@ int swsusp_check(void)
{
int error;
- hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
+ hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
+ FMODE_READ, NULL);
if (!IS_ERR(hib_resume_bdev)) {
set_blocksize(hib_resume_bdev, PAGE_SIZE);
clear_page(swsusp_header);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index e819e17877ca..c36c3b9e8a84 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
free_all_swap_pages(data->swap);
if (data->frozen)
thaw_processes();
- pm_notifier_call_chain(data->mode == O_WRONLY ?
+ pm_notifier_call_chain(data->mode == O_RDONLY ?
PM_POST_HIBERNATION : PM_POST_RESTORE);
atomic_inc(&snapshot_device_available);
@@ -263,6 +263,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
case SNAPSHOT_UNFREEZE:
if (!data->frozen || data->ready)
break;
+ pm_restore_gfp_mask();
thaw_processes();
usermodehelper_enable();
data->frozen = 0;
@@ -275,6 +276,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
error = -EPERM;
break;
}
+ pm_restore_gfp_mask();
error = hibernation_snapshot(data->platform_support);
if (!error)
error = put_user(in_suspend, (int __user *)arg);
diff --git a/kernel/printk.c b/kernel/printk.c
index 9a2264fc42ca..a23315dc4498 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1082,13 +1082,15 @@ void printk_tick(void)
int printk_needs_cpu(int cpu)
{
+ if (unlikely(cpu_is_offline(cpu)))
+ printk_tick();
return per_cpu(printk_pending, cpu);
}
void wake_up_klogd(void)
{
if (waitqueue_active(&log_wait))
- __raw_get_cpu_var(printk_pending) = 1;
+ this_cpu_write(printk_pending, 1);
}
/**
diff --git a/kernel/resource.c b/kernel/resource.c
index 9fad33efd0db..798e2fae2a06 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource);
static DEFINE_RWLOCK(resource_lock);
-/*
- * By default, we allocate free space bottom-up. The architecture can request
- * top-down by clearing this flag. The user can override the architecture's
- * choice with the "resource_alloc_from_bottom" kernel boot option, but that
- * should only be a debugging tool.
- */
-int resource_alloc_from_bottom = 1;
-
-static __init int setup_alloc_from_bottom(char *s)
-{
- printk(KERN_INFO
- "resource: allocating from bottom-up; please report a bug\n");
- resource_alloc_from_bottom = 1;
- return 0;
-}
-early_param("resource_alloc_from_bottom", setup_alloc_from_bottom);
-
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
{
struct resource *p = v;
@@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn)
return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
}
+void __weak arch_remove_reservations(struct resource *avail)
+{
+}
+
static resource_size_t simple_align_resource(void *data,
const struct resource *avail,
resource_size_t size,
@@ -397,74 +384,7 @@ static bool resource_contains(struct resource *res1, struct resource *res2)
}
/*
- * Find the resource before "child" in the sibling list of "root" children.
- */
-static struct resource *find_sibling_prev(struct resource *root, struct resource *child)
-{
- struct resource *this;
-
- for (this = root->child; this; this = this->sibling)
- if (this->sibling == child)
- return this;
-
- return NULL;
-}
-
-/*
* Find empty slot in the resource tree given range and alignment.
- * This version allocates from the end of the root resource first.
- */
-static int find_resource_from_top(struct resource *root, struct resource *new,
- resource_size_t size, resource_size_t min,
- resource_size_t max, resource_size_t align,
- resource_size_t (*alignf)(void *,
- const struct resource *,
- resource_size_t,
- resource_size_t),
- void *alignf_data)
-{
- struct resource *this;
- struct resource tmp, avail, alloc;
-
- tmp.start = root->end;
- tmp.end = root->end;
-
- this = find_sibling_prev(root, NULL);
- for (;;) {
- if (this) {
- if (this->end < root->end)
- tmp.start = this->end + 1;
- } else
- tmp.start = root->start;
-
- resource_clip(&tmp, min, max);
-
- /* Check for overflow after ALIGN() */
- avail = *new;
- avail.start = ALIGN(tmp.start, align);
- avail.end = tmp.end;
- if (avail.start >= tmp.start) {
- alloc.start = alignf(alignf_data, &avail, size, align);
- alloc.end = alloc.start + size - 1;
- if (resource_contains(&avail, &alloc)) {
- new->start = alloc.start;
- new->end = alloc.end;
- return 0;
- }
- }
-
- if (!this || this->start == root->start)
- break;
-
- tmp.end = this->start - 1;
- this = find_sibling_prev(root, this);
- }
- return -EBUSY;
-}
-
-/*
- * Find empty slot in the resource tree given range and alignment.
- * This version allocates from the beginning of the root resource first.
*/
static int find_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
@@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new,
struct resource *this = root->child;
struct resource tmp = *new, avail, alloc;
+ tmp.flags = new->flags;
tmp.start = root->start;
/*
- * Skip past an allocated resource that starts at 0, since the
- * assignment of this->start - 1 to tmp->end below would cause an
- * underflow.
+ * Skip past an allocated resource that starts at 0, since the assignment
+ * of this->start - 1 to tmp->end below would cause an underflow.
*/
if (this && this->start == 0) {
tmp.start = this->end + 1;
this = this->sibling;
}
- for (;;) {
+ for(;;) {
if (this)
tmp.end = this->start - 1;
else
tmp.end = root->end;
resource_clip(&tmp, min, max);
+ arch_remove_reservations(&tmp);
/* Check for overflow after ALIGN() */
avail = *new;
@@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new,
return 0;
}
}
-
if (!this)
break;
-
tmp.start = this->end + 1;
this = this->sibling;
}
@@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new,
alignf = simple_align_resource;
write_lock(&resource_lock);
- if (resource_alloc_from_bottom)
- err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
- else
- err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data);
+ err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
if (err >= 0 && __request_resource(root, new))
err = -EBUSY;
write_unlock(&resource_lock);
diff --git a/kernel/sched.c b/kernel/sched.c
index dc91a4d09ac3..fe1c6243d258 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -75,6 +75,7 @@
#include <asm/tlb.h>
#include <asm/irq_regs.h>
+#include <asm/mutex.h>
#include "sched_cpupri.h"
#include "workqueue_sched.h"
@@ -636,22 +637,18 @@ static inline struct task_group *task_group(struct task_struct *p)
#endif /* CONFIG_CGROUP_SCHED */
-static u64 irq_time_cpu(int cpu);
-static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time);
+static void update_rq_clock_task(struct rq *rq, s64 delta);
-inline void update_rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
{
- if (!rq->skip_clock_update) {
- int cpu = cpu_of(rq);
- u64 irq_time;
+ s64 delta;
- rq->clock = sched_clock_cpu(cpu);
- irq_time = irq_time_cpu(cpu);
- if (rq->clock - irq_time > rq->clock_task)
- rq->clock_task = rq->clock - irq_time;
+ if (rq->skip_clock_update)
+ return;
- sched_irq_time_avg_update(rq, irq_time);
- }
+ delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
+ rq->clock += delta;
+ update_rq_clock_task(rq, delta);
}
/*
@@ -1924,10 +1921,9 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
* They are read and saved off onto struct rq in update_rq_clock().
* This may result in other CPU reading this CPU's irq time and can
* race with irq/account_system_vtime on this CPU. We would either get old
- * or new value (or semi updated value on 32 bit) with a side effect of
- * accounting a slice of irq time to wrong task when irq is in progress
- * while we read rq->clock. That is a worthy compromise in place of having
- * locks on each irq in account_system_time.
+ * or new value with a side effect of accounting a slice of irq time to wrong
+ * task when irq is in progress while we read rq->clock. That is a worthy
+ * compromise in place of having locks on each irq in account_system_time.
*/
static DEFINE_PER_CPU(u64, cpu_hardirq_time);
static DEFINE_PER_CPU(u64, cpu_softirq_time);
@@ -1945,19 +1941,58 @@ void disable_sched_clock_irqtime(void)
sched_clock_irqtime = 0;
}
-static u64 irq_time_cpu(int cpu)
+#ifndef CONFIG_64BIT
+static DEFINE_PER_CPU(seqcount_t, irq_time_seq);
+
+static inline void irq_time_write_begin(void)
{
- if (!sched_clock_irqtime)
- return 0;
+ __this_cpu_inc(irq_time_seq.sequence);
+ smp_wmb();
+}
+
+static inline void irq_time_write_end(void)
+{
+ smp_wmb();
+ __this_cpu_inc(irq_time_seq.sequence);
+}
+
+static inline u64 irq_time_read(int cpu)
+{
+ u64 irq_time;
+ unsigned seq;
+ do {
+ seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu));
+ irq_time = per_cpu(cpu_softirq_time, cpu) +
+ per_cpu(cpu_hardirq_time, cpu);
+ } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq));
+
+ return irq_time;
+}
+#else /* CONFIG_64BIT */
+static inline void irq_time_write_begin(void)
+{
+}
+
+static inline void irq_time_write_end(void)
+{
+}
+
+static inline u64 irq_time_read(int cpu)
+{
return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu);
}
+#endif /* CONFIG_64BIT */
+/*
+ * Called before incrementing preempt_count on {soft,}irq_enter
+ * and before decrementing preempt_count on {soft,}irq_exit.
+ */
void account_system_vtime(struct task_struct *curr)
{
unsigned long flags;
+ s64 delta;
int cpu;
- u64 now, delta;
if (!sched_clock_irqtime)
return;
@@ -1965,9 +2000,10 @@ void account_system_vtime(struct task_struct *curr)
local_irq_save(flags);
cpu = smp_processor_id();
- now = sched_clock_cpu(cpu);
- delta = now - per_cpu(irq_start_time, cpu);
- per_cpu(irq_start_time, cpu) = now;
+ delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time);
+ __this_cpu_add(irq_start_time, delta);
+
+ irq_time_write_begin();
/*
* We do not account for softirq time from ksoftirqd here.
* We want to continue accounting softirq time to ksoftirqd thread
@@ -1975,33 +2011,55 @@ void account_system_vtime(struct task_struct *curr)
* that do not consume any time, but still wants to run.
*/
if (hardirq_count())
- per_cpu(cpu_hardirq_time, cpu) += delta;
+ __this_cpu_add(cpu_hardirq_time, delta);
else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD))
- per_cpu(cpu_softirq_time, cpu) += delta;
+ __this_cpu_add(cpu_softirq_time, delta);
+ irq_time_write_end();
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(account_system_vtime);
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
{
- if (sched_clock_irqtime && sched_feat(NONIRQ_POWER)) {
- u64 delta_irq = curr_irq_time - rq->prev_irq_time;
- rq->prev_irq_time = curr_irq_time;
- sched_rt_avg_update(rq, delta_irq);
- }
+ s64 irq_delta;
+
+ irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
+
+ /*
+ * Since irq_time is only updated on {soft,}irq_exit, we might run into
+ * this case when a previous update_rq_clock() happened inside a
+ * {soft,}irq region.
+ *
+ * When this happens, we stop ->clock_task and only update the
+ * prev_irq_time stamp to account for the part that fit, so that a next
+ * update will consume the rest. This ensures ->clock_task is
+ * monotonic.
+ *
+ * It does however cause some slight miss-attribution of {soft,}irq
+ * time, a more accurate solution would be to update the irq_time using
+ * the current rq->clock timestamp, except that would require using
+ * atomic ops.
+ */
+ if (irq_delta > delta)
+ irq_delta = delta;
+
+ rq->prev_irq_time += irq_delta;
+ delta -= irq_delta;
+ rq->clock_task += delta;
+
+ if (irq_delta && sched_feat(NONIRQ_POWER))
+ sched_rt_avg_update(rq, irq_delta);
}
-#else
+#else /* CONFIG_IRQ_TIME_ACCOUNTING */
-static u64 irq_time_cpu(int cpu)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
{
- return 0;
+ rq->clock_task += delta;
}
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) { }
-
-#endif
+#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
#include "sched_idletask.c"
#include "sched_fair.c"
@@ -2129,7 +2187,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
* A queue event has occurred, and we're going to schedule. In
* this case, we can save a useless back to back clock update.
*/
- if (test_tsk_need_resched(rq->curr))
+ if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr))
rq->skip_clock_update = 1;
}
@@ -3119,6 +3177,15 @@ static long calc_load_fold_active(struct rq *this_rq)
return delta;
}
+static unsigned long
+calc_load(unsigned long load, unsigned long exp, unsigned long active)
+{
+ load *= exp;
+ load += active * (FIXED_1 - exp);
+ load += 1UL << (FSHIFT - 1);
+ return load >> FSHIFT;
+}
+
#ifdef CONFIG_NO_HZ
/*
* For NO_HZ we delay the active fold to the next LOAD_FREQ update.
@@ -3148,6 +3215,128 @@ static long calc_load_fold_idle(void)
return delta;
}
+
+/**
+ * fixed_power_int - compute: x^n, in O(log n) time
+ *
+ * @x: base of the power
+ * @frac_bits: fractional bits of @x
+ * @n: power to raise @x to.
+ *
+ * By exploiting the relation between the definition of the natural power
+ * function: x^n := x*x*...*x (x multiplied by itself for n times), and
+ * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
+ * (where: n_i \elem {0, 1}, the binary vector representing n),
+ * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
+ * of course trivially computable in O(log_2 n), the length of our binary
+ * vector.
+ */
+static unsigned long
+fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
+{
+ unsigned long result = 1UL << frac_bits;
+
+ if (n) for (;;) {
+ if (n & 1) {
+ result *= x;
+ result += 1UL << (frac_bits - 1);
+ result >>= frac_bits;
+ }
+ n >>= 1;
+ if (!n)
+ break;
+ x *= x;
+ x += 1UL << (frac_bits - 1);
+ x >>= frac_bits;
+ }
+
+ return result;
+}
+
+/*
+ * a1 = a0 * e + a * (1 - e)
+ *
+ * a2 = a1 * e + a * (1 - e)
+ * = (a0 * e + a * (1 - e)) * e + a * (1 - e)
+ * = a0 * e^2 + a * (1 - e) * (1 + e)
+ *
+ * a3 = a2 * e + a * (1 - e)
+ * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
+ * = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
+ *
+ * ...
+ *
+ * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
+ * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
+ * = a0 * e^n + a * (1 - e^n)
+ *
+ * [1] application of the geometric series:
+ *
+ * n 1 - x^(n+1)
+ * S_n := \Sum x^i = -------------
+ * i=0 1 - x
+ */
+static unsigned long
+calc_load_n(unsigned long load, unsigned long exp,
+ unsigned long active, unsigned int n)
+{
+
+ return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
+}
+
+/*
+ * NO_HZ can leave us missing all per-cpu ticks calling
+ * calc_load_account_active(), but since an idle CPU folds its delta into
+ * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold
+ * in the pending idle delta if our idle period crossed a load cycle boundary.
+ *
+ * Once we've updated the global active value, we need to apply the exponential
+ * weights adjusted to the number of cycles missed.
+ */
+static void calc_global_nohz(unsigned long ticks)
+{
+ long delta, active, n;
+
+ if (time_before(jiffies, calc_load_update))
+ return;
+
+ /*
+ * If we crossed a calc_load_update boundary, make sure to fold
+ * any pending idle changes, the respective CPUs might have
+ * missed the tick driven calc_load_account_active() update
+ * due to NO_HZ.
+ */
+ delta = calc_load_fold_idle();
+ if (delta)
+ atomic_long_add(delta, &calc_load_tasks);
+
+ /*
+ * If we were idle for multiple load cycles, apply them.
+ */
+ if (ticks >= LOAD_FREQ) {
+ n = ticks / LOAD_FREQ;
+
+ active = atomic_long_read(&calc_load_tasks);
+ active = active > 0 ? active * FIXED_1 : 0;
+
+ avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+ avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+ avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+
+ calc_load_update += n * LOAD_FREQ;
+ }
+
+ /*
+ * Its possible the remainder of the above division also crosses
+ * a LOAD_FREQ period, the regular check in calc_global_load()
+ * which comes after this will take care of that.
+ *
+ * Consider us being 11 ticks before a cycle completion, and us
+ * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
+ * age us 4 cycles, and the test in calc_global_load() will
+ * pick up the final one.
+ */
+}
#else
static void calc_load_account_idle(struct rq *this_rq)
{
@@ -3157,6 +3346,10 @@ static inline long calc_load_fold_idle(void)
{
return 0;
}
+
+static void calc_global_nohz(unsigned long ticks)
+{
+}
#endif
/**
@@ -3174,24 +3367,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
loads[2] = (avenrun[2] + offset) << shift;
}
-static unsigned long
-calc_load(unsigned long load, unsigned long exp, unsigned long active)
-{
- load *= exp;
- load += active * (FIXED_1 - exp);
- return load >> FSHIFT;
-}
-
/*
* calc_load - update the avenrun load estimates 10 ticks after the
* CPUs have updated calc_load_tasks.
*/
-void calc_global_load(void)
+void calc_global_load(unsigned long ticks)
{
- unsigned long upd = calc_load_update + 10;
long active;
- if (time_before(jiffies, upd))
+ calc_global_nohz(ticks);
+
+ if (time_before(jiffies, calc_load_update + 10))
return;
active = atomic_long_read(&calc_load_tasks);
@@ -3845,7 +4031,6 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev)
{
if (prev->se.on_rq)
update_rq_clock(rq);
- rq->skip_clock_update = 0;
prev->sched_class->put_prev_task(rq, prev);
}
@@ -3903,7 +4088,6 @@ need_resched_nonpreemptible:
hrtick_clear(rq);
raw_spin_lock_irq(&rq->lock);
- clear_tsk_need_resched(prev);
switch_count = &prev->nivcsw;
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
@@ -3935,6 +4119,8 @@ need_resched_nonpreemptible:
put_prev_task(rq, prev);
next = pick_next_task(rq);
+ clear_tsk_need_resched(prev);
+ rq->skip_clock_update = 0;
if (likely(prev != next)) {
sched_info_switch(prev, next);
@@ -4029,7 +4215,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
if (task_thread_info(rq->curr) != owner || need_resched())
return 0;
- cpu_relax();
+ arch_mutex_cpu_relax();
}
return 1;
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index c8231fb15708..3308fd7f1b52 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -349,25 +349,47 @@ static int parse(struct nlattr *na, struct cpumask *mask)
return ret;
}
+#ifdef CONFIG_IA64
+#define TASKSTATS_NEEDS_PADDING 1
+#endif
+
static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
{
struct nlattr *na, *ret;
int aggr;
- /* If we don't pad, we end up with alignment on a 4 byte boundary.
- * This causes lots of runtime warnings on systems requiring 8 byte
- * alignment */
- u32 pids[2] = { pid, 0 };
- int pid_size = ALIGN(sizeof(pid), sizeof(long));
-
aggr = (type == TASKSTATS_TYPE_PID)
? TASKSTATS_TYPE_AGGR_PID
: TASKSTATS_TYPE_AGGR_TGID;
+ /*
+ * The taskstats structure is internally aligned on 8 byte
+ * boundaries but the layout of the aggregrate reply, with
+ * two NLA headers and the pid (each 4 bytes), actually
+ * force the entire structure to be unaligned. This causes
+ * the kernel to issue unaligned access warnings on some
+ * architectures like ia64. Unfortunately, some software out there
+ * doesn't properly unroll the NLA packet and assumes that the start
+ * of the taskstats structure will always be 20 bytes from the start
+ * of the netlink payload. Aligning the start of the taskstats
+ * structure breaks this software, which we don't want. So, for now
+ * the alignment only happens on architectures that require it
+ * and those users will have to update to fixed versions of those
+ * packages. Space is reserved in the packet only when needed.
+ * This ifdef should be removed in several years e.g. 2012 once
+ * we can be confident that fixed versions are installed on most
+ * systems. We add the padding before the aggregate since the
+ * aggregate is already a defined type.
+ */
+#ifdef TASKSTATS_NEEDS_PADDING
+ if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0)
+ goto err;
+#endif
na = nla_nest_start(skb, aggr);
if (!na)
goto err;
- if (nla_put(skb, type, pid_size, pids) < 0)
+
+ if (nla_put(skb, type, sizeof(pid), &pid) < 0)
goto err;
ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats));
if (!ret)
@@ -456,6 +478,18 @@ out:
return rc;
}
+static size_t taskstats_packet_size(void)
+{
+ size_t size;
+
+ size = nla_total_size(sizeof(u32)) +
+ nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+#ifdef TASKSTATS_NEEDS_PADDING
+ size += nla_total_size(0); /* Padding for alignment */
+#endif
+ return size;
+}
+
static int cmd_attr_pid(struct genl_info *info)
{
struct taskstats *stats;
@@ -464,8 +498,7 @@ static int cmd_attr_pid(struct genl_info *info)
u32 pid;
int rc;
- size = nla_total_size(sizeof(u32)) +
- nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+ size = taskstats_packet_size();
rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
if (rc < 0)
@@ -494,8 +527,7 @@ static int cmd_attr_tgid(struct genl_info *info)
u32 tgid;
int rc;
- size = nla_total_size(sizeof(u32)) +
- nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+ size = taskstats_packet_size();
rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
if (rc < 0)
@@ -570,8 +602,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
/*
* Size includes space for nested attributes
*/
- size = nla_total_size(sizeof(u32)) +
- nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+ size = taskstats_packet_size();
is_thread_group = !!taskstats_tgid_alloc(tsk);
if (is_thread_group) {
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index c18d7efa1b4b..df140cd3ea47 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -152,6 +152,7 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
*/
for (sft = 32; sft > 0; sft--) {
tmp = (u64) to << sft;
+ tmp += from / 2;
do_div(tmp, from);
if ((tmp >> sftacc) == 0)
break;
diff --git a/kernel/timer.c b/kernel/timer.c
index 68a9ae7679b7..353b9227c2ec 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1252,6 +1252,12 @@ unsigned long get_next_timer_interrupt(unsigned long now)
struct tvec_base *base = __get_cpu_var(tvec_bases);
unsigned long expires;
+ /*
+ * Pretend that there is no timer pending if the cpu is offline.
+ * Possible pending timers will be migrated later to an active cpu.
+ */
+ if (cpu_is_offline(smp_processor_id()))
+ return now + NEXT_TIMER_MAX_DELTA;
spin_lock(&base->lock);
if (time_before_eq(base->next_timer, base->timer_jiffies))
base->next_timer = __next_timer_interrupt(base);
@@ -1319,7 +1325,7 @@ void do_timer(unsigned long ticks)
{
jiffies_64 += ticks;
update_wall_time();
- calc_global_load();
+ calc_global_load(ticks);
}
#ifdef __ARCH_WANT_SYS_ALARM
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 7b8ec0281548..2b8e2ee7c0ef 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -887,7 +887,7 @@ static void blk_add_trace_split(void *ignore,
}
/**
- * blk_add_trace_remap - Add a trace for a remap operation
+ * blk_add_trace_bio_remap - Add a trace for a bio-remap operation
* @ignore: trace callback data parameter (not used)
* @q: queue the io is for
* @bio: the source bio
@@ -899,9 +899,9 @@ static void blk_add_trace_split(void *ignore,
* it spans a stripe (or similar). Add a trace for that action.
*
**/
-static void blk_add_trace_remap(void *ignore,
- struct request_queue *q, struct bio *bio,
- dev_t dev, sector_t from)
+static void blk_add_trace_bio_remap(void *ignore,
+ struct request_queue *q, struct bio *bio,
+ dev_t dev, sector_t from)
{
struct blk_trace *bt = q->blk_trace;
struct blk_io_trace_remap r;
@@ -1016,7 +1016,7 @@ static void blk_register_tracepoints(void)
WARN_ON(ret);
ret = register_trace_block_split(blk_add_trace_split, NULL);
WARN_ON(ret);
- ret = register_trace_block_remap(blk_add_trace_remap, NULL);
+ ret = register_trace_block_bio_remap(blk_add_trace_bio_remap, NULL);
WARN_ON(ret);
ret = register_trace_block_rq_remap(blk_add_trace_rq_remap, NULL);
WARN_ON(ret);
@@ -1025,7 +1025,7 @@ static void blk_register_tracepoints(void)
static void blk_unregister_tracepoints(void)
{
unregister_trace_block_rq_remap(blk_add_trace_rq_remap, NULL);
- unregister_trace_block_remap(blk_add_trace_remap, NULL);
+ unregister_trace_block_bio_remap(blk_add_trace_bio_remap, NULL);
unregister_trace_block_split(blk_add_trace_split, NULL);
unregister_trace_block_unplug_io(blk_add_trace_unplug_io, NULL);
unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer, NULL);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 9ed509a015d8..bd1c35a4fbcc 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -3853,6 +3853,13 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
/* Need to copy one event at a time */
do {
+ /* We need the size of one event, because
+ * rb_advance_reader only advances by one event,
+ * whereas rb_event_ts_length may include the size of
+ * one or two events.
+ * We have already ensured there's enough space if this
+ * is a time extend. */
+ size = rb_event_length(event);
memcpy(bpage->data + pos, rpage->data + rpos, size);
len -= size;
@@ -3867,7 +3874,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
event = rb_reader_event(cpu_buffer);
/* Always keep the time extend and data together */
size = rb_event_ts_length(event);
- } while (len > size);
+ } while (len >= size);
/* update bpage */
local_set(&bpage->commit, pos);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c380612273bf..f8cf959bad45 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2338,11 +2338,19 @@ tracing_write_stub(struct file *filp, const char __user *ubuf,
return count;
}
+static loff_t tracing_seek(struct file *file, loff_t offset, int origin)
+{
+ if (file->f_mode & FMODE_READ)
+ return seq_lseek(file, offset, origin);
+ else
+ return 0;
+}
+
static const struct file_operations tracing_fops = {
.open = tracing_open,
.read = seq_read,
.write = tracing_write_stub,
- .llseek = seq_lseek,
+ .llseek = tracing_seek,
.release = tracing_release,
};
diff --git a/kernel/user.c b/kernel/user.c
index 2c7d8d5914b1..5c598ca781df 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -158,6 +158,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
spin_lock_irq(&uidhash_lock);
up = uid_hash_find(uid, hashent);
if (up) {
+ put_user_ns(ns);
key_put(new->uid_keyring);
key_put(new->session_keyring);
kmem_cache_free(uid_cachep, new);
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 6e3c41a4024c..5b082156cd21 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -364,7 +364,8 @@ static int watchdog_nmi_enable(int cpu)
goto out_save;
}
- printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event);
+ printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n",
+ cpu, PTR_ERR(event));
return PTR_ERR(event);
/* success path */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 90db1bd1a978..e785b0f2aea5 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu)
{
struct worker *worker = kthread_data(task);
- if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+ if (!(worker->flags & WORKER_NOT_RUNNING))
atomic_inc(get_gcwq_nr_running(cpu));
}
@@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task,
struct global_cwq *gcwq = get_gcwq(cpu);
atomic_t *nr_running = get_gcwq_nr_running(cpu);
- if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+ if (worker->flags & WORKER_NOT_RUNNING)
return NULL;
/* this can only happen on the local cpu */
@@ -3692,7 +3692,8 @@ static int __init init_workqueues(void)
system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
WQ_UNBOUND_MAX_ACTIVE);
- BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+ BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
+ !system_unbound_wq);
return 0;
}
early_initcall(init_workqueues);
diff --git a/lib/Kconfig b/lib/Kconfig
index fa9bf2c06199..3116aa631af6 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -210,4 +210,7 @@ config GENERIC_ATOMIC64
config LRU_CACHE
tristate
+config AVERAGE
+ bool
+
endmenu
diff --git a/lib/Makefile b/lib/Makefile
index e6a3763b8212..76d3b8514903 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -106,6 +106,8 @@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
+obj-$(CONFIG_AVERAGE) += average.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/average.c b/lib/average.c
new file mode 100644
index 000000000000..5576c2841496
--- /dev/null
+++ b/lib/average.c
@@ -0,0 +1,61 @@
+/*
+ * lib/average.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/average.h>
+#include <linux/bug.h>
+#include <linux/log2.h>
+
+/**
+ * DOC: Exponentially Weighted Moving Average (EWMA)
+ *
+ * These are generic functions for calculating Exponentially Weighted Moving
+ * Averages (EWMA). We keep a structure with the EWMA parameters and a scaled
+ * up internal representation of the average value to prevent rounding errors.
+ * The factor for scaling up and the exponential weight (or decay rate) have to
+ * be specified thru the init fuction. The structure should not be accessed
+ * directly but only thru the helper functions.
+ */
+
+/**
+ * ewma_init() - Initialize EWMA parameters
+ * @avg: Average structure
+ * @factor: Factor to use for the scaled up internal value. The maximum value
+ * of averages can be ULONG_MAX/(factor*weight). For performance reasons
+ * factor has to be a power of 2.
+ * @weight: Exponential weight, or decay rate. This defines how fast the
+ * influence of older values decreases. For performance reasons weight has
+ * to be a power of 2.
+ *
+ * Initialize the EWMA parameters for a given struct ewma @avg.
+ */
+void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight)
+{
+ WARN_ON(!is_power_of_2(weight) || !is_power_of_2(factor));
+
+ avg->weight = ilog2(weight);
+ avg->factor = ilog2(factor);
+ avg->internal = 0;
+}
+EXPORT_SYMBOL(ewma_init);
+
+/**
+ * ewma_add() - Exponentially weighted moving average (EWMA)
+ * @avg: Average structure
+ * @val: Current value
+ *
+ * Add a sample to the average.
+ */
+struct ewma *ewma_add(struct ewma *avg, unsigned long val)
+{
+ avg->internal = avg->internal ?
+ (((avg->internal << avg->weight) - avg->internal) +
+ (val << avg->factor)) >> avg->weight :
+ (val << avg->factor);
+ return avg;
+}
+EXPORT_SYMBOL(ewma_add);
diff --git a/lib/nlattr.c b/lib/nlattr.c
index c4706eb98d3d..00e8a02681a6 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -15,7 +15,7 @@
#include <linux/types.h>
#include <net/netlink.h>
-static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
+static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
[NLA_U8] = sizeof(u8),
[NLA_U16] = sizeof(u16),
[NLA_U32] = sizeof(u32),
@@ -23,7 +23,7 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
[NLA_NESTED] = NLA_HDRLEN,
};
-static int validate_nla(struct nlattr *nla, int maxtype,
+static int validate_nla(const struct nlattr *nla, int maxtype,
const struct nla_policy *policy)
{
const struct nla_policy *pt;
@@ -115,10 +115,10 @@ static int validate_nla(struct nlattr *nla, int maxtype,
*
* Returns 0 on success or a negative error code.
*/
-int nla_validate(struct nlattr *head, int len, int maxtype,
+int nla_validate(const struct nlattr *head, int len, int maxtype,
const struct nla_policy *policy)
{
- struct nlattr *nla;
+ const struct nlattr *nla;
int rem, err;
nla_for_each_attr(nla, head, len, rem) {
@@ -173,10 +173,10 @@ nla_policy_len(const struct nla_policy *p, int n)
*
* Returns 0 on success or a negative error code.
*/
-int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
- const struct nla_policy *policy)
+int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
+ int len, const struct nla_policy *policy)
{
- struct nlattr *nla;
+ const struct nlattr *nla;
int rem, err;
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
@@ -191,7 +191,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
goto errout;
}
- tb[type] = nla;
+ tb[type] = (struct nlattr *)nla;
}
}
@@ -212,14 +212,14 @@ errout:
*
* Returns the first attribute in the stream matching the specified type.
*/
-struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
+struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
{
- struct nlattr *nla;
+ const struct nlattr *nla;
int rem;
nla_for_each_attr(nla, head, len, rem)
if (nla_type(nla) == attrtype)
- return nla;
+ return (struct nlattr *)nla;
return NULL;
}
diff --git a/mm/compaction.c b/mm/compaction.c
index 4d709ee59013..1a8894eadf72 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -279,7 +279,6 @@ static unsigned long isolate_migratepages(struct zone *zone,
/* Successfully isolated */
del_page_from_lru_list(zone, page, page_lru(page));
list_add(&page->lru, migratelist);
- mem_cgroup_del_lru(page);
cc->nr_migratepages++;
/* Avoid isolating too much */
diff --git a/mm/filemap.c b/mm/filemap.c
index ea89840fc65f..4e80ae9516c3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -102,9 +102,6 @@
* ->inode_lock (zap_pte_range->set_page_dirty)
* ->private_lock (zap_pte_range->__set_page_dirty_buffers)
*
- * ->task->proc_lock
- * ->dcache_lock (proc_pid_lookup)
- *
* (code doesn't rely on that order, so you could switch it around)
* ->tasklist_lock (memory_failure, collect_procs_ao)
* ->i_mmap_lock
@@ -143,13 +140,18 @@ void __remove_from_page_cache(struct page *page)
void remove_from_page_cache(struct page *page)
{
struct address_space *mapping = page->mapping;
+ void (*freepage)(struct page *);
BUG_ON(!PageLocked(page));
+ freepage = mapping->a_ops->freepage;
spin_lock_irq(&mapping->tree_lock);
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (freepage)
+ freepage(page);
}
EXPORT_SYMBOL(remove_from_page_cache);
@@ -1550,6 +1552,9 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
do_async_mmap_readahead(vma, ra, file, page, offset);
} else {
+ if (vmf->flags & FAULT_FLAG_MINOR)
+ return VM_FAULT_MAJOR | VM_FAULT_ERROR;
+
/* No page in the page cache at all */
do_sync_mmap_readahead(vma, ra, file, offset);
count_vm_event(PGMAJFAULT);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index c4a3558589ab..85855240933d 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2738,7 +2738,8 @@ out_page_table_lock:
unlock_page(pagecache_page);
put_page(pagecache_page);
}
- unlock_page(page);
+ if (page != pagecache_page)
+ unlock_page(page);
out_mutex:
mutex_unlock(&hugetlb_instantiation_mutex);
diff --git a/mm/ksm.c b/mm/ksm.c
index 65ab5c7067d9..43bc893470b4 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1724,8 +1724,13 @@ static int ksm_memory_callback(struct notifier_block *self,
/*
* Keep it very simple for now: just lock out ksmd and
* MADV_UNMERGEABLE while any memory is going offline.
+ * mutex_lock_nested() is necessary because lockdep was alarmed
+ * that here we take ksm_thread_mutex inside notifier chain
+ * mutex, and later take notifier chain mutex inside
+ * ksm_thread_mutex to unlock it. But that's safe because both
+ * are inside mem_hotplug_mutex.
*/
- mutex_lock(&ksm_thread_mutex);
+ mutex_lock_nested(&ksm_thread_mutex, SINGLE_DEPTH_NESTING);
break;
case MEM_OFFLINE:
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 7a22b4129211..00bb8a64d028 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1925,19 +1925,18 @@ again:
rcu_read_lock();
p = rcu_dereference(mm->owner);
- VM_BUG_ON(!p);
/*
- * because we don't have task_lock(), "p" can exit while
- * we're here. In that case, "mem" can point to root
- * cgroup but never be NULL. (and task_struct itself is freed
- * by RCU, cgroup itself is RCU safe.) Then, we have small
- * risk here to get wrong cgroup. But such kind of mis-account
- * by race always happens because we don't have cgroup_mutex().
- * It's overkill and we allow that small race, here.
+ * Because we don't have task_lock(), "p" can exit.
+ * In that case, "mem" can point to root or p can be NULL with
+ * race with swapoff. Then, we have small risk of mis-accouning.
+ * But such kind of mis-account by race always happens because
+ * we don't have cgroup_mutex(). It's overkill and we allo that
+ * small race, here.
+ * (*) swapoff at el will charge against mm-struct not against
+ * task-struct. So, mm->owner can be NULL.
*/
mem = mem_cgroup_from_task(p);
- VM_BUG_ON(!mem);
- if (mem_cgroup_is_root(mem)) {
+ if (!mem || mem_cgroup_is_root(mem)) {
rcu_read_unlock();
goto done;
}
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 124324134ff6..46ab2c044b0e 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -51,6 +51,7 @@
#include <linux/slab.h>
#include <linux/swapops.h>
#include <linux/hugetlb.h>
+#include <linux/memory_hotplug.h>
#include "internal.h"
int sysctl_memory_failure_early_kill __read_mostly = 0;
@@ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
return 1;
/*
- * The lock_system_sleep prevents a race with memory hotplug,
- * because the isolation assumes there's only a single user.
+ * The lock_memory_hotplug prevents a race with memory hotplug.
* This is a big hammer, a better would be nicer.
*/
- lock_system_sleep();
+ lock_memory_hotplug();
/*
* Isolate the page, so that it doesn't get reallocated if it
@@ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
ret = 1;
}
unset_migratetype_isolate(p);
- unlock_system_sleep();
+ unlock_memory_hotplug();
return ret;
}
diff --git a/mm/memory.c b/mm/memory.c
index 02e48aa0ed13..2c989f3e7f10 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1441,10 +1441,13 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
cond_resched();
while (!(page = follow_page(vma, start, foll_flags))) {
int ret;
+ unsigned int fault_fl =
+ ((foll_flags & FOLL_WRITE) ?
+ FAULT_FLAG_WRITE : 0) |
+ ((foll_flags & FOLL_MINOR) ?
+ FAULT_FLAG_MINOR : 0);
- ret = handle_mm_fault(mm, vma, start,
- (foll_flags & FOLL_WRITE) ?
- FAULT_FLAG_WRITE : 0);
+ ret = handle_mm_fault(mm, vma, start, fault_fl);
if (ret & VM_FAULT_ERROR) {
if (ret & VM_FAULT_OOM)
@@ -1453,6 +1456,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
(VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE|
VM_FAULT_SIGBUS))
return i ? i : -EFAULT;
+ else if (ret & VM_FAULT_MAJOR)
+ return i ? i : -EFAULT;
BUG();
}
if (ret & VM_FAULT_MAJOR)
@@ -1563,6 +1568,23 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
}
EXPORT_SYMBOL(get_user_pages);
+int get_user_pages_noio(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int nr_pages, int write, int force,
+ struct page **pages, struct vm_area_struct **vmas)
+{
+ int flags = FOLL_TOUCH | FOLL_MINOR;
+
+ if (pages)
+ flags |= FOLL_GET;
+ if (write)
+ flags |= FOLL_WRITE;
+ if (force)
+ flags |= FOLL_FORCE;
+
+ return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas);
+}
+EXPORT_SYMBOL(get_user_pages_noio);
+
/**
* get_dump_page() - pin user page in memory while writing it to core dump
* @addr: user address
@@ -2651,6 +2673,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
delayacct_set_flag(DELAYACCT_PF_SWAPIN);
page = lookup_swap_cache(entry);
if (!page) {
+ if (flags & FAULT_FLAG_MINOR)
+ return VM_FAULT_MAJOR | VM_FAULT_ERROR;
+
grab_swap_token(mm); /* Contend for token _before_ read-in */
page = swapin_readahead(entry,
GFP_HIGHUSER_MOVABLE, vma, address);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 9260314a221e..2c6523af5473 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -34,6 +34,23 @@
#include "internal.h"
+DEFINE_MUTEX(mem_hotplug_mutex);
+
+void lock_memory_hotplug(void)
+{
+ mutex_lock(&mem_hotplug_mutex);
+
+ /* for exclusive hibernation if CONFIG_HIBERNATION=y */
+ lock_system_sleep();
+}
+
+void unlock_memory_hotplug(void)
+{
+ unlock_system_sleep();
+ mutex_unlock(&mem_hotplug_mutex);
+}
+
+
/* add this memory to iomem resource */
static struct resource *register_memory_resource(u64 start, u64 size)
{
@@ -493,7 +510,7 @@ int mem_online_node(int nid)
pg_data_t *pgdat;
int ret;
- lock_system_sleep();
+ lock_memory_hotplug();
pgdat = hotadd_new_pgdat(nid, 0);
if (pgdat) {
ret = -ENOMEM;
@@ -504,7 +521,7 @@ int mem_online_node(int nid)
BUG_ON(ret);
out:
- unlock_system_sleep();
+ unlock_memory_hotplug();
return ret;
}
@@ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
struct resource *res;
int ret;
- lock_system_sleep();
+ lock_memory_hotplug();
res = register_memory_resource(start, size);
ret = -EEXIST;
@@ -563,7 +580,7 @@ error:
release_memory_resource(res);
out:
- unlock_system_sleep();
+ unlock_memory_hotplug();
return ret;
}
EXPORT_SYMBOL_GPL(add_memory);
@@ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn,
if (!test_pages_in_a_zone(start_pfn, end_pfn))
return -EINVAL;
- lock_system_sleep();
+ lock_memory_hotplug();
zone = page_zone(pfn_to_page(start_pfn));
node = zone_to_nid(zone);
@@ -880,7 +897,7 @@ repeat:
writeback_set_ratelimit();
memory_notify(MEM_OFFLINE, &arg);
- unlock_system_sleep();
+ unlock_memory_hotplug();
return 0;
failed_removal:
@@ -891,7 +908,7 @@ failed_removal:
undo_isolate_page_range(start_pfn, end_pfn);
out:
- unlock_system_sleep();
+ unlock_memory_hotplug();
return ret;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 4a57f135b76e..11ff260fb282 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1307,15 +1307,18 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
goto out;
/* Find the mm_struct */
+ rcu_read_lock();
read_lock(&tasklist_lock);
task = pid ? find_task_by_vpid(pid) : current;
if (!task) {
read_unlock(&tasklist_lock);
+ rcu_read_unlock();
err = -ESRCH;
goto out;
}
mm = get_task_mm(task);
read_unlock(&tasklist_lock);
+ rcu_read_unlock();
err = -EINVAL;
if (!mm)
diff --git a/mm/migrate.c b/mm/migrate.c
index fe5a3c6a5426..6ae8a66a7045 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -35,6 +35,8 @@
#include <linux/hugetlb.h>
#include <linux/gfp.h>
+#include <asm/tlbflush.h>
+
#include "internal.h"
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
diff --git a/mm/mmap.c b/mm/mmap.c
index b179abb1474a..50a4aa0255a0 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm,
unsigned long addr, unsigned long len,
unsigned long vm_flags, struct page **pages)
{
+ int ret;
struct vm_area_struct *vma;
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm,
vma->vm_ops = &special_mapping_vmops;
vma->vm_private_data = pages;
- if (unlikely(insert_vm_struct(mm, vma))) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
+ ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+ if (ret)
+ goto out;
+
+ ret = insert_vm_struct(mm, vma);
+ if (ret)
+ goto out;
mm->total_vm += len >> PAGE_SHIFT;
perf_event_mmap(vma);
return 0;
+
+out:
+ kmem_cache_free(vm_area_cachep, vma);
+ return ret;
}
static DEFINE_MUTEX(mm_all_locks_mutex);
diff --git a/mm/nommu.c b/mm/nommu.c
index 27a9ac588516..ef4045d010d5 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -10,7 +10,7 @@
* Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com>
* Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
* Copyright (c) 2002 Greg Ungerer <gerg@snapgear.com>
- * Copyright (c) 2007-2009 Paul Mundt <lethal@linux-sh.org>
+ * Copyright (c) 2007-2010 Paul Mundt <lethal@linux-sh.org>
*/
#include <linux/module.h>
@@ -328,6 +328,7 @@ void *vmalloc_node(unsigned long size, int node)
{
return vmalloc(size);
}
+EXPORT_SYMBOL(vmalloc_node);
/**
* vzalloc_node - allocate memory on a specific node with zero fill
@@ -440,6 +441,31 @@ void __attribute__((weak)) vmalloc_sync_all(void)
{
}
+/**
+ * alloc_vm_area - allocate a range of kernel address space
+ * @size: size of the area
+ *
+ * Returns: NULL on failure, vm_struct on success
+ *
+ * This function reserves a range of kernel address space, and
+ * allocates pagetables to map that range. No actual mappings
+ * are created. If the kernel address space is not shared
+ * between processes, it syncs the pagetable across all
+ * processes.
+ */
+struct vm_struct *alloc_vm_area(size_t size)
+{
+ BUG();
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(alloc_vm_area);
+
+void free_vm_area(struct vm_struct *area)
+{
+ BUG();
+}
+EXPORT_SYMBOL_GPL(free_vm_area);
+
int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
struct page *page)
{
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index b840afa89761..b4edfe7ce06c 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -563,7 +563,7 @@ static void balance_dirty_pages(struct address_space *mapping,
break; /* We've done our duty */
}
trace_wbc_balance_dirty_wait(&wbc, bdi);
- __set_current_state(TASK_INTERRUPTIBLE);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
io_schedule_timeout(pause);
/*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e4092704c1a9..ff7e15872398 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -104,19 +104,24 @@ gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
* 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)
+
+static gfp_t saved_gfp_mask;
+
+void pm_restore_gfp_mask(void)
{
WARN_ON(!mutex_is_locked(&pm_mutex));
- gfp_allowed_mask = mask;
+ if (saved_gfp_mask) {
+ gfp_allowed_mask = saved_gfp_mask;
+ saved_gfp_mask = 0;
+ }
}
-gfp_t clear_gfp_allowed_mask(gfp_t mask)
+void pm_restrict_gfp_mask(void)
{
- gfp_t ret = gfp_allowed_mask;
-
WARN_ON(!mutex_is_locked(&pm_mutex));
- gfp_allowed_mask &= ~mask;
- return ret;
+ WARN_ON(saved_gfp_mask);
+ saved_gfp_mask = gfp_allowed_mask;
+ gfp_allowed_mask &= ~GFP_IOFS;
}
#endif /* CONFIG_PM_SLEEP */
diff --git a/mm/percpu.c b/mm/percpu.c
index efe816856a9d..02ba91230b99 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1268,7 +1268,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
/* we're done parsing the input, undefine BUG macro and dump config */
#undef PCPU_SETUP_BUG_ON
- pcpu_dump_alloc_info(KERN_INFO, ai);
+ pcpu_dump_alloc_info(KERN_DEBUG, ai);
pcpu_nr_groups = ai->nr_groups;
pcpu_group_offsets = group_offsets;
diff --git a/mm/shmem.c b/mm/shmem.c
index 47fdeeb9d636..fa9acc97a39a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1228,6 +1228,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
swp_entry_t swap;
gfp_t gfp;
int error;
+ int flags = type ? *type : 0;
if (idx >= SHMEM_MAX_INDEX)
return -EFBIG;
@@ -1287,6 +1288,11 @@ repeat:
swappage = lookup_swap_cache(swap);
if (!swappage) {
shmem_swp_unmap(entry);
+ if (flags & FAULT_FLAG_MINOR) {
+ spin_unlock(&info->lock);
+ *type = VM_FAULT_MAJOR | VM_FAULT_ERROR;
+ goto failed;
+ }
/* here we actually do the io */
if (type && !(*type & VM_FAULT_MAJOR)) {
__count_vm_event(PGMAJFAULT);
@@ -1510,7 +1516,7 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
int error;
- int ret;
+ int ret = (int)vmf->flags;
if (((loff_t)vmf->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
return VM_FAULT_SIGBUS;
@@ -2415,13 +2421,20 @@ static struct inode *shmem_alloc_inode(struct super_block *sb)
return &p->vfs_inode;
}
+static void shmem_i_callback(struct rcu_head *head)
+{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
+}
+
static void shmem_destroy_inode(struct inode *inode)
{
if ((inode->i_mode & S_IFMT) == S_IFREG) {
/* only struct inode is valid if it's an inline symlink */
mpol_free_shared_policy(&SHMEM_I(inode)->policy);
}
- kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
+ call_rcu(&inode->i_rcu, shmem_i_callback);
}
static void init_once(void *foo)
@@ -2478,7 +2491,7 @@ static const struct inode_operations shmem_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl = generic_check_acl,
+ .check_acl_rcu = generic_check_acl_rcu,
#endif
};
@@ -2501,7 +2514,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl = generic_check_acl,
+ .check_acl_rcu = generic_check_acl_rcu,
#endif
};
@@ -2512,7 +2525,7 @@ static const struct inode_operations shmem_special_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl = generic_check_acl,
+ .check_acl_rcu = generic_check_acl_rcu,
#endif
};
diff --git a/mm/slab.c b/mm/slab.c
index b1e40dafbab3..6107f2380e08 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2781,7 +2781,7 @@ static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp,
/*
* Map pages beginning at addr to the given cache and slab. This is required
* for the slab allocator to be able to lookup the cache and slab of a
- * virtual address for kfree, ksize, kmem_ptr_validate, and slab debugging.
+ * virtual address for kfree, ksize, and slab debugging.
*/
static void slab_map_pages(struct kmem_cache *cache, struct slab *slab,
void *addr)
@@ -3660,36 +3660,6 @@ void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
EXPORT_SYMBOL(kmem_cache_alloc_notrace);
#endif
-/**
- * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
- * @cachep: the cache we're checking against
- * @ptr: pointer to validate
- *
- * This verifies that the untrusted pointer looks sane;
- * it is _not_ a guarantee that the pointer is actually
- * part of the slab cache in question, but it at least
- * validates that the pointer can be dereferenced and
- * looks half-way sane.
- *
- * Currently only used for dentry validation.
- */
-int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
-{
- unsigned long size = cachep->buffer_size;
- struct page *page;
-
- if (unlikely(!kern_ptr_validate(ptr, size)))
- goto out;
- page = virt_to_page(ptr);
- if (unlikely(!PageSlab(page)))
- goto out;
- if (unlikely(page_get_cache(page) != cachep))
- goto out;
- return 1;
-out:
- return 0;
-}
-
#ifdef CONFIG_NUMA
void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
{
diff --git a/mm/slob.c b/mm/slob.c
index 617b6d6c42c7..3588eaaef726 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -678,11 +678,6 @@ int kmem_cache_shrink(struct kmem_cache *d)
}
EXPORT_SYMBOL(kmem_cache_shrink);
-int kmem_ptr_validate(struct kmem_cache *a, const void *b)
-{
- return 0;
-}
-
static unsigned int slob_ready __read_mostly;
int slab_is_available(void)
diff --git a/mm/slub.c b/mm/slub.c
index 981fb730aa04..a2fe1727ed85 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1917,17 +1917,6 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
}
EXPORT_SYMBOL(kmem_cache_free);
-/* Figure out on which slab page the object resides */
-static struct page *get_object_page(const void *x)
-{
- struct page *page = virt_to_head_page(x);
-
- if (!PageSlab(page))
- return NULL;
-
- return page;
-}
-
/*
* Object placement in a slab is made very easy because we always start at
* offset 0. If we tune the size of the object to the alignment then we can
@@ -2386,35 +2375,6 @@ error:
}
/*
- * Check if a given pointer is valid
- */
-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)
- /* No slab or wrong slab */
- return 0;
-
- if (!check_valid_pointer(s, page, object))
- return 0;
-
- /*
- * We could also check if the object is on the slabs freelist.
- * But this would be too expensive and it seems that the main
- * purpose of kmem_ptr_valid() is to check if the object belongs
- * to a certain slab.
- */
- return 1;
-}
-EXPORT_SYMBOL(kmem_ptr_validate);
-
-/*
* Determine the size of a slab object
*/
unsigned int kmem_cache_size(struct kmem_cache *s)
@@ -3401,13 +3361,13 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
for_each_free_object(p, s, page->freelist) {
set_bit(slab_index(p, s, addr), map);
- if (!check_object(s, page, p, 0))
+ if (!check_object(s, page, p, SLUB_RED_INACTIVE))
return 0;
}
for_each_object(p, s, addr, page->objects)
if (!test_bit(slab_index(p, s, addr), map))
- if (!check_object(s, page, p, 1))
+ if (!check_object(s, page, p, SLUB_RED_ACTIVE))
return 0;
return 1;
}
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 67ddaaf98c74..b6adcfbf6f48 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1677,7 +1677,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
if (S_ISBLK(inode->i_mode)) {
struct block_device *bdev = I_BDEV(inode);
set_blocksize(bdev, p->old_block_size);
- bd_release(bdev);
+ blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
} else {
mutex_lock(&inode->i_mutex);
inode->i_flags &= ~S_SWAPFILE;
@@ -1939,7 +1939,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
error = -EINVAL;
if (S_ISBLK(inode->i_mode)) {
bdev = I_BDEV(inode);
- error = bd_claim(bdev, sys_swapon);
+ error = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL,
+ sys_swapon);
if (error < 0) {
bdev = NULL;
error = -EINVAL;
@@ -2136,7 +2137,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
bad_swap:
if (bdev) {
set_blocksize(bdev, p->old_block_size);
- bd_release(bdev);
+ blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
}
destroy_swap_extents(p);
swap_cgroup_swapoff(type);
diff --git a/mm/truncate.c b/mm/truncate.c
index ba887bff48c5..3c2d5ddfa0d4 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (mapping->a_ops->freepage)
+ mapping->a_ops->freepage(page);
+
page_cache_release(page); /* pagecache ref */
return 1;
failed:
diff --git a/mm/util.c b/mm/util.c
index 73dac81e9f78..f126975ef23e 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -186,27 +186,6 @@ 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/vmalloc.c b/mm/vmalloc.c
index a3d66b3dc5cb..eb5cc7d00c5a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -31,8 +31,6 @@
#include <asm/tlbflush.h>
#include <asm/shmparam.h>
-bool vmap_lazy_unmap __read_mostly = true;
-
/*** Page table manipulation functions ***/
static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
@@ -503,9 +501,6 @@ static unsigned long lazy_max_pages(void)
{
unsigned int log;
- if (!vmap_lazy_unmap)
- return 0;
-
log = fls(num_online_cpus());
return log * (32UL * 1024 * 1024 / PAGE_SIZE);
@@ -566,7 +561,6 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
if (va->va_end > *end)
*end = va->va_end;
nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
- unmap_vmap_area(va);
list_add_tail(&va->purge_list, &valist);
va->flags |= VM_LAZY_FREEING;
va->flags &= ~VM_LAZY_FREE;
@@ -611,10 +605,11 @@ static void purge_vmap_area_lazy(void)
}
/*
- * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
- * called for the correct range previously.
+ * Free a vmap area, caller ensuring that the area has been unmapped
+ * and flush_cache_vunmap had been called for the correct range
+ * previously.
*/
-static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+static void free_vmap_area_noflush(struct vmap_area *va)
{
va->flags |= VM_LAZY_FREE;
atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
@@ -623,6 +618,16 @@ static void free_unmap_vmap_area_noflush(struct vmap_area *va)
}
/*
+ * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
+ * called for the correct range previously.
+ */
+static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+{
+ unmap_vmap_area(va);
+ free_vmap_area_noflush(va);
+}
+
+/*
* Free and unmap a vmap area
*/
static void free_unmap_vmap_area(struct vmap_area *va)
@@ -798,7 +803,7 @@ static void free_vmap_block(struct vmap_block *vb)
spin_unlock(&vmap_block_tree_lock);
BUG_ON(tmp != vb);
- free_unmap_vmap_area_noflush(vb->va);
+ free_vmap_area_noflush(vb->va);
call_rcu(&vb->rcu_head, rcu_free_vb);
}
@@ -936,6 +941,8 @@ static void vb_free(const void *addr, unsigned long size)
rcu_read_unlock();
BUG_ON(!vb);
+ vunmap_page_range((unsigned long)addr, (unsigned long)addr + size);
+
spin_lock(&vb->lock);
BUG_ON(bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order));
@@ -988,7 +995,6 @@ void vm_unmap_aliases(void)
s = vb->va->va_start + (i << PAGE_SHIFT);
e = vb->va->va_start + (j << PAGE_SHIFT);
- vunmap_page_range(s, e);
flush = 1;
if (s < start)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d31d7ce52c0e..9ca587c69274 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page)
spin_unlock_irq(&mapping->tree_lock);
swapcache_free(swap, page);
} else {
+ void (*freepage)(struct page *);
+
+ freepage = mapping->a_ops->freepage;
+
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (freepage != NULL)
+ freepage(page);
}
return 1;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 42eac4d33216..8f62f17ee1c7 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -750,8 +750,6 @@ static const char * const vmstat_text[] = {
"nr_shmem",
"nr_dirtied",
"nr_written",
- "nr_dirty_threshold",
- "nr_dirty_background_threshold",
#ifdef CONFIG_NUMA
"numa_hit",
@@ -761,6 +759,8 @@ static const char * const vmstat_text[] = {
"numa_local",
"numa_other",
#endif
+ "nr_dirty_threshold",
+ "nr_dirty_background_threshold",
#ifdef CONFIG_VM_EVENT_COUNTERS
"pgpgin",
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 52077ca22072..6e64f7c6a2e9 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -272,13 +272,11 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id);
}
- new_dev = alloc_netdev_mq(sizeof(struct vlan_dev_info), name,
- vlan_setup, real_dev->num_tx_queues);
+ new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup);
if (new_dev == NULL)
return -ENOBUFS;
- netif_copy_real_num_queues(new_dev, real_dev);
dev_net_set(new_dev, net);
/* need 4 bytes for extra VLAN header info,
* hope the underlying device can handle it.
@@ -334,12 +332,15 @@ static void vlan_transfer_features(struct net_device *dev,
vlandev->features &= ~dev->vlan_features;
vlandev->features |= dev->features & dev->vlan_features;
vlandev->gso_max_size = dev->gso_max_size;
+
+ if (dev->features & NETIF_F_HW_VLAN_TX)
+ vlandev->hard_header_len = dev->hard_header_len;
+ else
+ vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;
+
#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.h b/net/8021q/vlan.h
index db01b3181fdc..5687c9b95f33 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -19,19 +19,25 @@ struct vlan_priority_tci_mapping {
/**
- * struct vlan_rx_stats - VLAN percpu rx stats
+ * struct vlan_pcpu_stats - VLAN percpu rx/tx stats
* @rx_packets: number of received packets
* @rx_bytes: number of received bytes
* @rx_multicast: number of received multicast packets
+ * @tx_packets: number of transmitted packets
+ * @tx_bytes: number of transmitted bytes
* @syncp: synchronization point for 64bit counters
- * @rx_errors: number of errors
+ * @rx_errors: number of rx errors
+ * @tx_dropped: number of tx drops
*/
-struct vlan_rx_stats {
+struct vlan_pcpu_stats {
u64 rx_packets;
u64 rx_bytes;
u64 rx_multicast;
+ u64 tx_packets;
+ u64 tx_bytes;
struct u64_stats_sync syncp;
- unsigned long rx_errors;
+ u32 rx_errors;
+ u32 tx_dropped;
};
/**
@@ -45,9 +51,7 @@ struct vlan_rx_stats {
* @real_dev: underlying netdevice
* @real_dev_addr: address of underlying netdevice
* @dent: proc dir entry
- * @cnt_inc_headroom_on_tx: statistic - number of skb expansions on TX
- * @cnt_encap_on_xmit: statistic - number of skb encapsulations on TX
- * @vlan_rx_stats: ptr to percpu rx stats
+ * @vlan_pcpu_stats: ptr to percpu rx stats
*/
struct vlan_dev_info {
unsigned int nr_ingress_mappings;
@@ -62,9 +66,7 @@ struct vlan_dev_info {
unsigned char real_dev_addr[ETH_ALEN];
struct proc_dir_entry *dent;
- unsigned long cnt_inc_headroom_on_tx;
- unsigned long cnt_encap_on_xmit;
- struct vlan_rx_stats __percpu *vlan_rx_stats;
+ struct vlan_pcpu_stats __percpu *vlan_pcpu_stats;
};
static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 69b2f79800a5..ce8e3ab3e7a5 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -9,7 +9,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
struct sk_buff *skb = *skbp;
u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
struct net_device *vlan_dev;
- struct vlan_rx_stats *rx_stats;
+ struct vlan_pcpu_stats *rx_stats;
vlan_dev = vlan_find_dev(skb->dev, vlan_id);
if (!vlan_dev) {
@@ -26,7 +26,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
skb->vlan_tci = 0;
- rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats);
+ rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats);
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 14e3d1fa07a0..be737539f34d 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -141,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)
{
struct vlan_hdr *vhdr;
- struct vlan_rx_stats *rx_stats;
+ struct vlan_pcpu_stats *rx_stats;
struct net_device *vlan_dev;
u16 vlan_id;
u16 vlan_tci;
@@ -177,7 +177,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
} else {
skb->dev = vlan_dev;
- rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);
+ rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats);
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
@@ -274,9 +274,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
u16 vlan_tci = 0;
int rc;
- if (WARN_ON(skb_headroom(skb) < dev->hard_header_len))
- return -ENOSPC;
-
if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) {
vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
@@ -313,8 +310,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- int i = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
unsigned int len;
int ret;
@@ -326,71 +321,31 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
*/
if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
- unsigned int orig_headroom = skb_headroom(skb);
u16 vlan_tci;
-
- vlan_dev_info(dev)->cnt_encap_on_xmit++;
-
vlan_tci = vlan_dev_info(dev)->vlan_id;
vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
- skb = __vlan_put_tag(skb, vlan_tci);
- if (!skb) {
- txq->tx_dropped++;
- return NETDEV_TX_OK;
- }
-
- if (orig_headroom < VLAN_HLEN)
- vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
+ skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
}
-
skb_set_dev(skb, vlan_dev_info(dev)->real_dev);
len = skb->len;
ret = dev_queue_xmit(skb);
if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
- txq->tx_packets++;
- txq->tx_bytes += len;
- } else
- txq->tx_dropped++;
+ struct vlan_pcpu_stats *stats;
- return ret;
-}
-
-static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- int i = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
- u16 vlan_tci;
- unsigned int len;
- int ret;
-
- vlan_tci = vlan_dev_info(dev)->vlan_id;
- vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
- skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
-
- skb->dev = vlan_dev_info(dev)->real_dev;
- len = skb->len;
- ret = dev_queue_xmit(skb);
-
- if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
- txq->tx_packets++;
- txq->tx_bytes += len;
- } else
- txq->tx_dropped++;
+ stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats);
+ u64_stats_update_begin(&stats->syncp);
+ stats->tx_packets++;
+ stats->tx_bytes += len;
+ u64_stats_update_begin(&stats->syncp);
+ } else {
+ this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped);
+ }
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,
@@ -719,8 +674,7 @@ 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,
- vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq;
+static const struct net_device_ops vlan_netdev_ops;
static int vlan_dev_init(struct net_device *dev)
{
@@ -738,6 +692,7 @@ static int vlan_dev_init(struct net_device *dev)
(1<<__LINK_STATE_PRESENT);
dev->features |= real_dev->features & real_dev->vlan_features;
+ dev->features |= NETIF_F_LLTX;
dev->gso_max_size = real_dev->gso_max_size;
/* ipv6 shared card related stuff */
@@ -755,26 +710,20 @@ 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;
- 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;
- if (real_dev->netdev_ops->ndo_select_queue)
- dev->netdev_ops = &vlan_netdev_ops_sq;
- else
- dev->netdev_ops = &vlan_netdev_ops;
}
+ dev->netdev_ops = &vlan_netdev_ops;
+
if (is_vlan_dev(real_dev))
subclass = 1;
vlan_dev_set_lockdep_class(dev, subclass);
- vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats);
- if (!vlan_dev_info(dev)->vlan_rx_stats)
+ vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats);
+ if (!vlan_dev_info(dev)->vlan_pcpu_stats)
return -ENOMEM;
return 0;
@@ -786,8 +735,8 @@ static void vlan_dev_uninit(struct net_device *dev)
struct vlan_dev_info *vlan = vlan_dev_info(dev);
int i;
- free_percpu(vlan->vlan_rx_stats);
- vlan->vlan_rx_stats = NULL;
+ free_percpu(vlan->vlan_pcpu_stats);
+ vlan->vlan_pcpu_stats = NULL;
for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
while ((pm = vlan->egress_priority_map[i]) != NULL) {
vlan->egress_priority_map[i] = pm->next;
@@ -825,33 +774,37 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev)
static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
- dev_txq_stats_fold(dev, stats);
- if (vlan_dev_info(dev)->vlan_rx_stats) {
- struct vlan_rx_stats *p, accum = {0};
+ if (vlan_dev_info(dev)->vlan_pcpu_stats) {
+ struct vlan_pcpu_stats *p;
+ u32 rx_errors = 0, tx_dropped = 0;
int i;
for_each_possible_cpu(i) {
- u64 rxpackets, rxbytes, rxmulticast;
+ u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
unsigned int start;
- p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i);
+ p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i);
do {
start = u64_stats_fetch_begin_bh(&p->syncp);
rxpackets = p->rx_packets;
rxbytes = p->rx_bytes;
rxmulticast = p->rx_multicast;
+ txpackets = p->tx_packets;
+ txbytes = p->tx_bytes;
} while (u64_stats_fetch_retry_bh(&p->syncp, start));
- accum.rx_packets += rxpackets;
- accum.rx_bytes += rxbytes;
- accum.rx_multicast += rxmulticast;
- /* rx_errors is ulong, not protected by syncp */
- accum.rx_errors += p->rx_errors;
+
+ stats->rx_packets += rxpackets;
+ stats->rx_bytes += rxbytes;
+ stats->multicast += rxmulticast;
+ stats->tx_packets += txpackets;
+ stats->tx_bytes += txbytes;
+ /* rx_errors & tx_dropped are u32 */
+ rx_errors += p->rx_errors;
+ tx_dropped += p->tx_dropped;
}
- stats->rx_packets = accum.rx_packets;
- stats->rx_bytes = accum.rx_bytes;
- stats->rx_errors = accum.rx_errors;
- stats->multicast = accum.rx_multicast;
+ stats->rx_errors = rx_errors;
+ stats->tx_dropped = tx_dropped;
}
return stats;
}
@@ -908,80 +861,6 @@ static const struct net_device_ops vlan_netdev_ops = {
#endif
};
-static const struct net_device_ops vlan_netdev_accel_ops = {
- .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_stats64 = vlan_dev_get_stats64,
-#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_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_stats64 = vlan_dev_get_stats64,
-#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_stats64 = vlan_dev_get_stats64,
-#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/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index ddc105734af7..be9a5c19a775 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -101,25 +101,6 @@ static int vlan_changelink(struct net_device *dev,
return 0;
}
-static int vlan_get_tx_queues(struct net *net,
- struct nlattr *tb[],
- unsigned int *num_tx_queues,
- unsigned int *real_num_tx_queues)
-{
- struct net_device *real_dev;
-
- if (!tb[IFLA_LINK])
- return -EINVAL;
-
- real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
- if (!real_dev)
- return -ENODEV;
-
- *num_tx_queues = real_dev->num_tx_queues;
- *real_num_tx_queues = real_dev->real_num_tx_queues;
- return 0;
-}
-
static int vlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
@@ -237,7 +218,6 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = {
.maxtype = IFLA_VLAN_MAX,
.policy = vlan_policy,
.priv_size = sizeof(struct vlan_dev_info),
- .get_tx_queues = vlan_get_tx_queues,
.setup = vlan_setup,
.validate = vlan_validate,
.newlink = vlan_newlink,
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index 80e280f56686..d1314cf18adf 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -280,7 +280,6 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *stats;
- static const char fmt[] = "%30s %12lu\n";
static const char fmt64[] = "%30s %12llu\n";
int i;
@@ -299,10 +298,6 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
seq_puts(seq, "\n");
seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets);
seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes);
- seq_printf(seq, fmt, "total headroom inc",
- dev_info->cnt_inc_headroom_on_tx);
- seq_printf(seq, fmt, "total encap on xmit",
- dev_info->cnt_encap_on_xmit);
seq_printf(seq, "Device: %s", dev_info->real_dev->name);
/* now show all PRIORITY mappings relating to this VLAN */
seq_printf(seq, "\nINGRESS priority mappings: "
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 45c15f491401..798beac7f100 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -27,31 +27,16 @@
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "protocol.h"
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef offset_of
-#define offset_of(type, memb) \
- ((unsigned long)(&((type *)0)->memb))
-#endif
-#ifndef container_of
-#define container_of(obj, type, memb) \
- ((type *)(((char *)obj) - offset_of(type, memb)))
-#endif
-
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
@@ -104,7 +89,7 @@ EXPORT_SYMBOL(p9stat_free);
static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
{
- size_t len = MIN(pdu->size - pdu->offset, size);
+ size_t len = min(pdu->size - pdu->offset, size);
memcpy(data, &pdu->sdata[pdu->offset], len);
pdu->offset += len;
return size - len;
@@ -112,7 +97,7 @@ static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
{
- size_t len = MIN(pdu->capacity - pdu->size, size);
+ size_t len = min(pdu->capacity - pdu->size, size);
memcpy(&pdu->sdata[pdu->size], data, len);
pdu->size += len;
return size - len;
@@ -121,7 +106,7 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
static size_t
pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
{
- size_t len = MIN(pdu->capacity - pdu->size, size);
+ size_t len = min(pdu->capacity - pdu->size, size);
if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
len = 0;
@@ -201,7 +186,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
if (errcode)
break;
- size = MAX(len, 0);
+ size = max_t(int16_t, len, 0);
*sptr = kmalloc(size + 1, GFP_KERNEL);
if (*sptr == NULL) {
@@ -256,8 +241,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
p9pdu_readf(pdu, proto_version, "d", count);
if (!errcode) {
*count =
- MIN(*count,
- pdu->size - pdu->offset);
+ min_t(int32_t, *count,
+ pdu->size - pdu->offset);
*data = &pdu->sdata[pdu->offset];
}
}
@@ -421,7 +406,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
const char *sptr = va_arg(ap, const char *);
int16_t len = 0;
if (sptr)
- len = MIN(strlen(sptr), USHRT_MAX);
+ len = min_t(int16_t, strlen(sptr), USHRT_MAX);
errcode = p9pdu_writef(pdu, proto_version,
"w", len);
diff --git a/net/Kconfig b/net/Kconfig
index 55fd82e9ffd9..ad0aafe903f8 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -214,12 +214,18 @@ source "net/ieee802154/Kconfig"
source "net/sched/Kconfig"
source "net/dcb/Kconfig"
source "net/dns_resolver/Kconfig"
+source "net/batman-adv/Kconfig"
config RPS
boolean
depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
default y
+config XPS
+ boolean
+ depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
+ default y
+
menu "Network testing"
config NET_PKTGEN
diff --git a/net/Makefile b/net/Makefile
index 6b7bfd7f1416..a3330ebe2c53 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -69,3 +69,4 @@ endif
obj-$(CONFIG_WIMAX) += wimax/
obj-$(CONFIG_DNS_RESOLVER) += dns_resolver/
obj-$(CONFIG_CEPH_LIB) += ceph/
+obj-$(CONFIG_BATMAN_ADV) += batman-adv/
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index 799c631f0fed..f7fa67c78766 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -143,12 +143,13 @@ static struct class atm_class = {
.dev_uevent = atm_uevent,
};
-int atm_register_sysfs(struct atm_dev *adev)
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
{
struct device *cdev = &adev->class_dev;
int i, j, err;
cdev->class = &atm_class;
+ cdev->parent = parent;
dev_set_drvdata(cdev, adev);
dev_set_name(cdev, "%s%d", adev->type, adev->number);
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index ad2b232a2055..fce2eae8d476 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -97,7 +97,7 @@ static LIST_HEAD(br2684_devs);
static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
{
- return (struct br2684_dev *)netdev_priv(net_dev);
+ return netdev_priv(net_dev);
}
static inline struct net_device *list_entry_brdev(const struct list_head *le)
diff --git a/net/atm/clip.c b/net/atm/clip.c
index ff956d1115bc..d257da50fcfb 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -502,7 +502,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
struct atmarp_entry *entry;
int error;
struct clip_vcc *clip_vcc;
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} };
+ struct flowi fl = { .fl4_dst = ip,
+ .fl4_tos = 1 };
struct rtable *rt;
if (vcc->push != clip_push) {
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 181d70c73d70..179e04bc99dd 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -816,8 +816,7 @@ static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
return -EINVAL;
vcc->proto_data = dev_lec[arg];
- return lec_mcast_make((struct lec_priv *)netdev_priv(dev_lec[arg]),
- vcc);
+ return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc);
}
/* Initialize device. */
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 74bcc662c3dd..644cdf071642 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -64,8 +64,6 @@
do { if (0) printk(KERN_CONT format, ##args); } while (0)
#endif
-#define MPOA_TAG_LEN 4
-
/* mpc_daemon -> kernel */
static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc);
static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc);
diff --git a/net/atm/resources.c b/net/atm/resources.c
index d29e58261511..23f45ce6f351 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number)
}
EXPORT_SYMBOL(atm_dev_lookup);
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
- int number, unsigned long *flags)
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+ const struct atmdev_ops *ops, int number,
+ unsigned long *flags)
{
struct atm_dev *dev, *inuse;
@@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
goto out_fail;
}
- if (atm_register_sysfs(dev) < 0) {
+ if (atm_register_sysfs(dev, parent) < 0) {
pr_err("atm_register_sysfs failed for dev %s\n", type);
atm_proc_dev_deregister(dev);
goto out_fail;
diff --git a/net/atm/resources.h b/net/atm/resources.h
index 126fb1840dfb..521431e30507 100644
--- a/net/atm/resources.h
+++ b/net/atm/resources.h
@@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev)
#endif /* CONFIG_PROC_FS */
-int atm_register_sysfs(struct atm_dev *adev);
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent);
void atm_unregister_sysfs(struct atm_dev *adev);
#endif
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
new file mode 100644
index 000000000000..6c051ad833eb
--- /dev/null
+++ b/net/batman-adv/Kconfig
@@ -0,0 +1,25 @@
+#
+# B.A.T.M.A.N meshing protocol
+#
+
+config BATMAN_ADV
+ tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
+ depends on NET
+ default n
+ ---help---
+
+ B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
+ a routing protocol for multi-hop ad-hoc mesh networks. The
+ networks may be wired or wireless. See
+ http://www.open-mesh.org/ for more information and user space
+ tools.
+
+config BATMAN_ADV_DEBUG
+ bool "B.A.T.M.A.N. debugging"
+ depends on BATMAN_ADV != n
+ ---help---
+
+ This is an option for use by developers; most people should
+ say N here. This enables compilation of support for
+ outputting debugging information to the kernel log. The
+ output is controlled via the module parameter debug.
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
new file mode 100644
index 000000000000..d936aeccd194
--- /dev/null
+++ b/net/batman-adv/Makefile
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2007-2010 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
+#
+
+obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
+batman-adv-y += aggregation.o
+batman-adv-y += bat_debugfs.o
+batman-adv-y += bat_sysfs.o
+batman-adv-y += bitarray.o
+batman-adv-y += gateway_client.o
+batman-adv-y += gateway_common.o
+batman-adv-y += hard-interface.o
+batman-adv-y += hash.o
+batman-adv-y += icmp_socket.o
+batman-adv-y += main.o
+batman-adv-y += originator.o
+batman-adv-y += ring_buffer.o
+batman-adv-y += routing.o
+batman-adv-y += send.o
+batman-adv-y += soft-interface.o
+batman-adv-y += translation-table.o
+batman-adv-y += unicast.o
+batman-adv-y += vis.o
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
new file mode 100644
index 000000000000..3850a3ecf947
--- /dev/null
+++ b/net/batman-adv/aggregation.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2007-2010 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 "aggregation.h"
+#include "send.h"
+#include "routing.h"
+
+/* calculate the size of the hna information for a given packet */
+static int hna_len(struct batman_packet *batman_packet)
+{
+ return batman_packet->num_hna * ETH_ALEN;
+}
+
+/* return true if new_packet can be aggregated with forw_packet */
+static bool can_aggregate_with(struct batman_packet *new_batman_packet,
+ int packet_len,
+ unsigned long send_time,
+ bool directlink,
+ struct batman_if *if_incoming,
+ struct forw_packet *forw_packet)
+{
+ struct batman_packet *batman_packet =
+ (struct batman_packet *)forw_packet->skb->data;
+ int aggregated_bytes = forw_packet->packet_len + packet_len;
+
+ /**
+ * we can aggregate the current packet to this aggregated packet
+ * if:
+ *
+ * - the send time is within our MAX_AGGREGATION_MS time
+ * - the resulting packet wont be bigger than
+ * MAX_AGGREGATION_BYTES
+ */
+
+ if (time_before(send_time, forw_packet->send_time) &&
+ time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
+ forw_packet->send_time) &&
+ (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
+
+ /**
+ * check aggregation compatibility
+ * -> direct link packets are broadcasted on
+ * their interface only
+ * -> aggregate packet if the current packet is
+ * a "global" packet as well as the base
+ * packet
+ */
+
+ /* packets without direct link flag and high TTL
+ * are flooded through the net */
+ if ((!directlink) &&
+ (!(batman_packet->flags & DIRECTLINK)) &&
+ (batman_packet->ttl != 1) &&
+
+ /* own packets originating non-primary
+ * interfaces leave only that interface */
+ ((!forw_packet->own) ||
+ (forw_packet->if_incoming->if_num == 0)))
+ return true;
+
+ /* if the incoming packet is sent via this one
+ * interface only - we still can aggregate */
+ if ((directlink) &&
+ (new_batman_packet->ttl == 1) &&
+ (forw_packet->if_incoming == if_incoming) &&
+
+ /* packets from direct neighbors or
+ * own secondary interface packets
+ * (= secondary interface packets in general) */
+ (batman_packet->flags & DIRECTLINK ||
+ (forw_packet->own &&
+ forw_packet->if_incoming->if_num != 0)))
+ return true;
+ }
+
+ return false;
+}
+
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+/* create a new aggregated packet and add this packet to it */
+static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
+ unsigned long send_time, bool direct_link,
+ struct batman_if *if_incoming,
+ int own_packet)
+{
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct forw_packet *forw_packet_aggr;
+ unsigned char *skb_buff;
+
+ /* own packet should always be scheduled */
+ if (!own_packet) {
+ if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "batman packet queue full\n");
+ return;
+ }
+ }
+
+ forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+ if (!forw_packet_aggr) {
+ if (!own_packet)
+ atomic_inc(&bat_priv->batman_queue_left);
+ return;
+ }
+
+ if ((atomic_read(&bat_priv->aggregated_ogms)) &&
+ (packet_len < MAX_AGGREGATION_BYTES))
+ forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
+ sizeof(struct ethhdr));
+ else
+ forw_packet_aggr->skb = dev_alloc_skb(packet_len +
+ sizeof(struct ethhdr));
+
+ if (!forw_packet_aggr->skb) {
+ if (!own_packet)
+ atomic_inc(&bat_priv->batman_queue_left);
+ kfree(forw_packet_aggr);
+ return;
+ }
+ skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
+
+ INIT_HLIST_NODE(&forw_packet_aggr->list);
+
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+ forw_packet_aggr->packet_len = packet_len;
+ memcpy(skb_buff, packet_buff, packet_len);
+
+ forw_packet_aggr->own = own_packet;
+ forw_packet_aggr->if_incoming = if_incoming;
+ forw_packet_aggr->num_packets = 0;
+ forw_packet_aggr->direct_link_flags = 0;
+ forw_packet_aggr->send_time = send_time;
+
+ /* save packet direct link flag status */
+ if (direct_link)
+ forw_packet_aggr->direct_link_flags |= 1;
+
+ /* add new packet to packet list */
+ spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ /* start timer for this packet */
+ INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
+ send_outstanding_bat_packet);
+ queue_delayed_work(bat_event_workqueue,
+ &forw_packet_aggr->delayed_work,
+ send_time - jiffies);
+}
+
+/* aggregate a new packet into the existing aggregation */
+static void aggregate(struct forw_packet *forw_packet_aggr,
+ unsigned char *packet_buff,
+ int packet_len,
+ bool direct_link)
+{
+ unsigned char *skb_buff;
+
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+ memcpy(skb_buff, packet_buff, packet_len);
+ forw_packet_aggr->packet_len += packet_len;
+ forw_packet_aggr->num_packets++;
+
+ /* save packet direct link flag status */
+ if (direct_link)
+ forw_packet_aggr->direct_link_flags |=
+ (1 << forw_packet_aggr->num_packets);
+}
+
+void add_bat_packet_to_list(struct bat_priv *bat_priv,
+ unsigned char *packet_buff, int packet_len,
+ struct batman_if *if_incoming, char own_packet,
+ unsigned long send_time)
+{
+ /**
+ * _aggr -> pointer to the packet we want to aggregate with
+ * _pos -> pointer to the position in the queue
+ */
+ struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
+ struct hlist_node *tmp_node;
+ struct batman_packet *batman_packet =
+ (struct batman_packet *)packet_buff;
+ bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
+
+ /* find position for the packet in the forward queue */
+ spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ /* own packets are not to be aggregated */
+ if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
+ hlist_for_each_entry(forw_packet_pos, tmp_node,
+ &bat_priv->forw_bat_list, list) {
+ if (can_aggregate_with(batman_packet,
+ packet_len,
+ send_time,
+ direct_link,
+ if_incoming,
+ forw_packet_pos)) {
+ forw_packet_aggr = forw_packet_pos;
+ break;
+ }
+ }
+ }
+
+ /* nothing to aggregate with - either aggregation disabled or no
+ * suitable aggregation packet found */
+ if (!forw_packet_aggr) {
+ /* the following section can run without the lock */
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ /**
+ * if we could not aggregate this packet with one of the others
+ * we hold it back for a while, so that it might be aggregated
+ * later on
+ */
+ if ((!own_packet) &&
+ (atomic_read(&bat_priv->aggregated_ogms)))
+ send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
+
+ new_aggregated_packet(packet_buff, packet_len,
+ send_time, direct_link,
+ if_incoming, own_packet);
+ } else {
+ aggregate(forw_packet_aggr,
+ packet_buff, packet_len,
+ direct_link);
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+ }
+}
+
+/* unpack the aggregated packets and process them one by one */
+void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
+ int packet_len, struct batman_if *if_incoming)
+{
+ struct batman_packet *batman_packet;
+ int buff_pos = 0;
+ unsigned char *hna_buff;
+
+ batman_packet = (struct batman_packet *)packet_buff;
+
+ do {
+ /* network to host order for our 32bit seqno, and the
+ orig_interval. */
+ batman_packet->seqno = ntohl(batman_packet->seqno);
+
+ hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
+ receive_bat_packet(ethhdr, batman_packet,
+ hna_buff, hna_len(batman_packet),
+ if_incoming);
+
+ buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
+ batman_packet = (struct batman_packet *)
+ (packet_buff + buff_pos);
+ } while (aggregated_packet(buff_pos, packet_len,
+ batman_packet->num_hna));
+}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
new file mode 100644
index 000000000000..71a91b3da913
--- /dev/null
+++ b/net/batman-adv/aggregation.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
+#define _NET_BATMAN_ADV_AGGREGATION_H_
+
+#include "main.h"
+
+/* is there another aggregated packet here? */
+static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
+{
+ int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
+
+ return (next_buff_pos <= packet_len) &&
+ (next_buff_pos <= MAX_AGGREGATION_BYTES);
+}
+
+void add_bat_packet_to_list(struct bat_priv *bat_priv,
+ unsigned char *packet_buff, int packet_len,
+ struct batman_if *if_incoming, char own_packet,
+ unsigned long send_time);
+void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
+ int packet_len, struct batman_if *if_incoming);
+
+#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c
new file mode 100644
index 000000000000..0ae81d07f102
--- /dev/null
+++ b/net/batman-adv/bat_debugfs.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 <linux/debugfs.h>
+
+#include "bat_debugfs.h"
+#include "translation-table.h"
+#include "originator.h"
+#include "hard-interface.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
+#include "soft-interface.h"
+#include "vis.h"
+#include "icmp_socket.h"
+
+static struct dentry *bat_debugfs;
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+#define LOG_BUFF_MASK (log_buff_len-1)
+#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK])
+
+static int log_buff_len = LOG_BUF_LEN;
+
+static void emit_log_char(struct debug_log *debug_log, char c)
+{
+ LOG_BUFF(debug_log->log_end) = c;
+ debug_log->log_end++;
+
+ if (debug_log->log_end - debug_log->log_start > log_buff_len)
+ debug_log->log_start = debug_log->log_end - log_buff_len;
+}
+
+static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
+{
+ int printed_len;
+ va_list args;
+ static char debug_log_buf[256];
+ char *p;
+
+ if (!debug_log)
+ return 0;
+
+ spin_lock_bh(&debug_log->lock);
+ 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(debug_log, *p);
+
+ spin_unlock_bh(&debug_log->lock);
+
+ wake_up(&debug_log->queue_wait);
+
+ return 0;
+}
+
+int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
+{
+ va_list args;
+ char tmp_log_buf[256];
+
+ va_start(args, fmt);
+ vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
+ fdebug_log(bat_priv->debug_log, "[%10u] %s",
+ (jiffies / HZ), tmp_log_buf);
+ va_end(args);
+
+ return 0;
+}
+
+static int log_open(struct inode *inode, struct file *file)
+{
+ nonseekable_open(inode, file);
+ file->private_data = inode->i_private;
+ inc_module_count();
+ return 0;
+}
+
+static int log_release(struct inode *inode, struct file *file)
+{
+ dec_module_count();
+ return 0;
+}
+
+static ssize_t log_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct bat_priv *bat_priv = file->private_data;
+ struct debug_log *debug_log = bat_priv->debug_log;
+ int error, i = 0;
+ char c;
+
+ if ((file->f_flags & O_NONBLOCK) &&
+ !(debug_log->log_end - debug_log->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(debug_log->queue_wait,
+ (debug_log->log_start - debug_log->log_end));
+
+ if (error)
+ return error;
+
+ spin_lock_bh(&debug_log->lock);
+
+ while ((!error) && (i < count) &&
+ (debug_log->log_start != debug_log->log_end)) {
+ c = LOG_BUFF(debug_log->log_start);
+
+ debug_log->log_start++;
+
+ spin_unlock_bh(&debug_log->lock);
+
+ error = __put_user(c, buf);
+
+ spin_lock_bh(&debug_log->lock);
+
+ buf++;
+ i++;
+
+ }
+
+ spin_unlock_bh(&debug_log->lock);
+
+ if (!error)
+ return i;
+
+ return error;
+}
+
+static unsigned int log_poll(struct file *file, poll_table *wait)
+{
+ struct bat_priv *bat_priv = file->private_data;
+ struct debug_log *debug_log = bat_priv->debug_log;
+
+ poll_wait(file, &debug_log->queue_wait, wait);
+
+ if (debug_log->log_end - debug_log->log_start)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+static const struct file_operations log_fops = {
+ .open = log_open,
+ .release = log_release,
+ .read = log_read,
+ .poll = log_poll,
+ .llseek = no_llseek,
+};
+
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+ struct dentry *d;
+
+ if (!bat_priv->debug_dir)
+ goto err;
+
+ bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
+ if (!bat_priv->debug_log)
+ goto err;
+
+ spin_lock_init(&bat_priv->debug_log->lock);
+ init_waitqueue_head(&bat_priv->debug_log->queue_wait);
+
+ d = debugfs_create_file("log", S_IFREG | S_IRUSR,
+ bat_priv->debug_dir, bat_priv, &log_fops);
+ if (d)
+ goto err;
+
+ return 0;
+
+err:
+ return 1;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+ kfree(bat_priv->debug_log);
+ bat_priv->debug_log = NULL;
+}
+#else /* CONFIG_BATMAN_ADV_DEBUG */
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+ bat_priv->debug_log = NULL;
+ return 0;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+ return;
+}
+#endif
+
+static int originators_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, orig_seq_print_text, net_dev);
+}
+
+static int gateways_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, gw_client_seq_print_text, net_dev);
+}
+
+static int softif_neigh_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, softif_neigh_seq_print_text, net_dev);
+}
+
+static int transtable_global_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, hna_global_seq_print_text, net_dev);
+}
+
+static int transtable_local_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, hna_local_seq_print_text, net_dev);
+}
+
+static int vis_data_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, vis_seq_print_text, net_dev);
+}
+
+struct bat_debuginfo {
+ struct attribute attr;
+ const struct file_operations fops;
+};
+
+#define BAT_DEBUGINFO(_name, _mode, _open) \
+struct bat_debuginfo bat_debuginfo_##_name = { \
+ .attr = { .name = __stringify(_name), \
+ .mode = _mode, }, \
+ .fops = { .owner = THIS_MODULE, \
+ .open = _open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+ } \
+};
+
+static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
+static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
+static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open);
+static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
+static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
+static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
+
+static struct bat_debuginfo *mesh_debuginfos[] = {
+ &bat_debuginfo_originators,
+ &bat_debuginfo_gateways,
+ &bat_debuginfo_softif_neigh,
+ &bat_debuginfo_transtable_global,
+ &bat_debuginfo_transtable_local,
+ &bat_debuginfo_vis_data,
+ NULL,
+};
+
+void debugfs_init(void)
+{
+ bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
+ if (bat_debugfs == ERR_PTR(-ENODEV))
+ bat_debugfs = NULL;
+}
+
+void debugfs_destroy(void)
+{
+ if (bat_debugfs) {
+ debugfs_remove_recursive(bat_debugfs);
+ bat_debugfs = NULL;
+ }
+}
+
+int debugfs_add_meshif(struct net_device *dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ struct bat_debuginfo **bat_debug;
+ struct dentry *file;
+
+ if (!bat_debugfs)
+ goto out;
+
+ bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs);
+ if (!bat_priv->debug_dir)
+ goto out;
+
+ bat_socket_setup(bat_priv);
+ debug_log_setup(bat_priv);
+
+ for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
+ file = debugfs_create_file(((*bat_debug)->attr).name,
+ S_IFREG | ((*bat_debug)->attr).mode,
+ bat_priv->debug_dir,
+ dev, &(*bat_debug)->fops);
+ if (!file) {
+ bat_err(dev, "Can't add debugfs file: %s/%s\n",
+ dev->name, ((*bat_debug)->attr).name);
+ goto rem_attr;
+ }
+ }
+
+ return 0;
+rem_attr:
+ debugfs_remove_recursive(bat_priv->debug_dir);
+ bat_priv->debug_dir = NULL;
+out:
+#ifdef CONFIG_DEBUG_FS
+ return -ENOMEM;
+#else
+ return 0;
+#endif /* CONFIG_DEBUG_FS */
+}
+
+void debugfs_del_meshif(struct net_device *dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+
+ debug_log_cleanup(bat_priv);
+
+ if (bat_debugfs) {
+ debugfs_remove_recursive(bat_priv->debug_dir);
+ bat_priv->debug_dir = NULL;
+ }
+}
diff --git a/net/batman-adv/bat_debugfs.h b/net/batman-adv/bat_debugfs.h
new file mode 100644
index 000000000000..72df532b7d5f
--- /dev/null
+++ b/net/batman-adv/bat_debugfs.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+
+#ifndef _NET_BATMAN_ADV_DEBUGFS_H_
+#define _NET_BATMAN_ADV_DEBUGFS_H_
+
+#define DEBUGFS_BAT_SUBDIR "batman_adv"
+
+void debugfs_init(void);
+void debugfs_destroy(void);
+int debugfs_add_meshif(struct net_device *dev);
+void debugfs_del_meshif(struct net_device *dev);
+
+#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
new file mode 100644
index 000000000000..cd7bb51825f1
--- /dev/null
+++ b/net/batman-adv/bat_sysfs.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 "bat_sysfs.h"
+#include "translation-table.h"
+#include "originator.h"
+#include "hard-interface.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
+#include "vis.h"
+
+#define to_dev(obj) container_of(obj, struct device, kobj)
+#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent))
+#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj))
+
+/* Use this, if you have customized show and store functions */
+#define BAT_ATTR(_name, _mode, _show, _store) \
+struct bat_attribute bat_attr_##_name = { \
+ .attr = {.name = __stringify(_name), \
+ .mode = _mode }, \
+ .show = _show, \
+ .store = _store, \
+};
+
+#define BAT_ATTR_STORE_BOOL(_name, _post_func) \
+ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
+ char *buff, size_t count) \
+{ \
+ struct net_device *net_dev = kobj_to_netdev(kobj); \
+ struct bat_priv *bat_priv = netdev_priv(net_dev); \
+ return __store_bool_attr(buff, count, _post_func, attr, \
+ &bat_priv->_name, net_dev); \
+}
+
+#define BAT_ATTR_SHOW_BOOL(_name) \
+ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
+ char *buff) \
+{ \
+ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \
+ return sprintf(buff, "%s\n", \
+ atomic_read(&bat_priv->_name) == 0 ? \
+ "disabled" : "enabled"); \
+} \
+
+/* Use this, if you are going to turn a [name] in bat_priv on or off */
+#define BAT_ATTR_BOOL(_name, _mode, _post_func) \
+ static BAT_ATTR_STORE_BOOL(_name, _post_func) \
+ static BAT_ATTR_SHOW_BOOL(_name) \
+ static BAT_ATTR(_name, _mode, show_##_name, store_##_name)
+
+
+#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \
+ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \
+ char *buff, size_t count) \
+{ \
+ struct net_device *net_dev = kobj_to_netdev(kobj); \
+ struct bat_priv *bat_priv = netdev_priv(net_dev); \
+ return __store_uint_attr(buff, count, _min, _max, _post_func, \
+ attr, &bat_priv->_name, net_dev); \
+}
+
+#define BAT_ATTR_SHOW_UINT(_name) \
+ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
+ char *buff) \
+{ \
+ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \
+ return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \
+} \
+
+/* Use this, if you are going to set [name] in bat_priv to unsigned integer
+ * values only */
+#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \
+ static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \
+ static BAT_ATTR_SHOW_UINT(_name) \
+ static BAT_ATTR(_name, _mode, show_##_name, store_##_name)
+
+
+static int store_bool_attr(char *buff, size_t count,
+ struct net_device *net_dev,
+ char *attr_name, atomic_t *attr)
+{
+ int enabled = -1;
+
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ if ((strncmp(buff, "1", 2) == 0) ||
+ (strncmp(buff, "enable", 7) == 0) ||
+ (strncmp(buff, "enabled", 8) == 0))
+ enabled = 1;
+
+ if ((strncmp(buff, "0", 2) == 0) ||
+ (strncmp(buff, "disable", 8) == 0) ||
+ (strncmp(buff, "disabled", 9) == 0))
+ enabled = 0;
+
+ if (enabled < 0) {
+ bat_info(net_dev,
+ "%s: Invalid parameter received: %s\n",
+ attr_name, buff);
+ return -EINVAL;
+ }
+
+ if (atomic_read(attr) == enabled)
+ return count;
+
+ bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name,
+ atomic_read(attr) == 1 ? "enabled" : "disabled",
+ enabled == 1 ? "enabled" : "disabled");
+
+ atomic_set(attr, (unsigned)enabled);
+ return count;
+}
+
+static inline ssize_t __store_bool_attr(char *buff, size_t count,
+ void (*post_func)(struct net_device *),
+ struct attribute *attr,
+ atomic_t *attr_store, struct net_device *net_dev)
+{
+ int ret;
+
+ ret = store_bool_attr(buff, count, net_dev, (char *)attr->name,
+ attr_store);
+ if (post_func && ret)
+ post_func(net_dev);
+
+ return ret;
+}
+
+static int store_uint_attr(char *buff, size_t count,
+ struct net_device *net_dev, char *attr_name,
+ unsigned int min, unsigned int max, atomic_t *attr)
+{
+ unsigned long uint_val;
+ int ret;
+
+ ret = strict_strtoul(buff, 10, &uint_val);
+ if (ret) {
+ bat_info(net_dev,
+ "%s: Invalid parameter received: %s\n",
+ attr_name, buff);
+ return -EINVAL;
+ }
+
+ if (uint_val < min) {
+ bat_info(net_dev, "%s: Value is too small: %lu min: %u\n",
+ attr_name, uint_val, min);
+ return -EINVAL;
+ }
+
+ if (uint_val > max) {
+ bat_info(net_dev, "%s: Value is too big: %lu max: %u\n",
+ attr_name, uint_val, max);
+ return -EINVAL;
+ }
+
+ if (atomic_read(attr) == uint_val)
+ return count;
+
+ bat_info(net_dev, "%s: Changing from: %i to: %lu\n",
+ attr_name, atomic_read(attr), uint_val);
+
+ atomic_set(attr, uint_val);
+ return count;
+}
+
+static inline ssize_t __store_uint_attr(char *buff, size_t count,
+ int min, int max,
+ void (*post_func)(struct net_device *),
+ struct attribute *attr,
+ atomic_t *attr_store, struct net_device *net_dev)
+{
+ int ret;
+
+ ret = store_uint_attr(buff, count, net_dev, (char *)attr->name,
+ min, max, attr_store);
+ if (post_func && ret)
+ post_func(net_dev);
+
+ return ret;
+}
+
+static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct bat_priv *bat_priv = kobj_to_batpriv(kobj);
+ int vis_mode = atomic_read(&bat_priv->vis_mode);
+
+ return sprintf(buff, "%s\n",
+ vis_mode == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server");
+}
+
+static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ unsigned long val;
+ int ret, vis_mode_tmp = -1;
+
+ ret = strict_strtoul(buff, 10, &val);
+
+ if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
+ (strncmp(buff, "client", 6) == 0) ||
+ (strncmp(buff, "off", 3) == 0))
+ vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
+
+ if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
+ (strncmp(buff, "server", 6) == 0))
+ vis_mode_tmp = VIS_TYPE_SERVER_SYNC;
+
+ if (vis_mode_tmp < 0) {
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ bat_info(net_dev,
+ "Invalid parameter for 'vis mode' setting received: "
+ "%s\n", buff);
+ return -EINVAL;
+ }
+
+ if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
+ return count;
+
+ bat_info(net_dev, "Changing vis mode from: %s to: %s\n",
+ atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
+ "client" : "server");
+
+ atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
+ return count;
+}
+
+static void post_gw_deselect(struct net_device *net_dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ gw_deselect(bat_priv);
+}
+
+static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct bat_priv *bat_priv = kobj_to_batpriv(kobj);
+ int bytes_written;
+
+ switch (atomic_read(&bat_priv->gw_mode)) {
+ case GW_MODE_CLIENT:
+ bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME);
+ break;
+ case GW_MODE_SERVER:
+ bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME);
+ break;
+ default:
+ bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME);
+ break;
+ }
+
+ return bytes_written;
+}
+
+static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ char *curr_gw_mode_str;
+ int gw_mode_tmp = -1;
+
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0)
+ gw_mode_tmp = GW_MODE_OFF;
+
+ if (strncmp(buff, GW_MODE_CLIENT_NAME,
+ strlen(GW_MODE_CLIENT_NAME)) == 0)
+ gw_mode_tmp = GW_MODE_CLIENT;
+
+ if (strncmp(buff, GW_MODE_SERVER_NAME,
+ strlen(GW_MODE_SERVER_NAME)) == 0)
+ gw_mode_tmp = GW_MODE_SERVER;
+
+ if (gw_mode_tmp < 0) {
+ bat_info(net_dev,
+ "Invalid parameter for 'gw mode' setting received: "
+ "%s\n", buff);
+ return -EINVAL;
+ }
+
+ if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp)
+ return count;
+
+ switch (atomic_read(&bat_priv->gw_mode)) {
+ case GW_MODE_CLIENT:
+ curr_gw_mode_str = GW_MODE_CLIENT_NAME;
+ break;
+ case GW_MODE_SERVER:
+ curr_gw_mode_str = GW_MODE_SERVER_NAME;
+ break;
+ default:
+ curr_gw_mode_str = GW_MODE_OFF_NAME;
+ break;
+ }
+
+ bat_info(net_dev, "Changing gw mode from: %s to: %s\n",
+ curr_gw_mode_str, buff);
+
+ gw_deselect(bat_priv);
+ atomic_set(&bat_priv->gw_mode, (unsigned)gw_mode_tmp);
+ return count;
+}
+
+static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct bat_priv *bat_priv = kobj_to_batpriv(kobj);
+ int down, up;
+ int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth);
+
+ gw_bandwidth_to_kbit(gw_bandwidth, &down, &up);
+ return sprintf(buff, "%i%s/%i%s\n",
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
+}
+
+static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ return gw_bandwidth_set(net_dev, buff, count);
+}
+
+BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
+BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
+BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
+static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
+static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
+BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
+BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
+BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
+ post_gw_deselect);
+static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
+ store_gw_bwidth);
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL);
+#endif
+
+static struct bat_attribute *mesh_attrs[] = {
+ &bat_attr_aggregated_ogms,
+ &bat_attr_bonding,
+ &bat_attr_fragmentation,
+ &bat_attr_vis_mode,
+ &bat_attr_gw_mode,
+ &bat_attr_orig_interval,
+ &bat_attr_hop_penalty,
+ &bat_attr_gw_sel_class,
+ &bat_attr_gw_bandwidth,
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+ &bat_attr_log_level,
+#endif
+ NULL,
+};
+
+int sysfs_add_meshif(struct net_device *dev)
+{
+ struct kobject *batif_kobject = &dev->dev.kobj;
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ struct bat_attribute **bat_attr;
+ int err;
+
+ bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
+ batif_kobject);
+ if (!bat_priv->mesh_obj) {
+ bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+ SYSFS_IF_MESH_SUBDIR);
+ goto out;
+ }
+
+ for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) {
+ err = sysfs_create_file(bat_priv->mesh_obj,
+ &((*bat_attr)->attr));
+ if (err) {
+ bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+ dev->name, SYSFS_IF_MESH_SUBDIR,
+ ((*bat_attr)->attr).name);
+ goto rem_attr;
+ }
+ }
+
+ return 0;
+
+rem_attr:
+ for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
+ sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
+
+ kobject_put(bat_priv->mesh_obj);
+ bat_priv->mesh_obj = NULL;
+out:
+ return -ENOMEM;
+}
+
+void sysfs_del_meshif(struct net_device *dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ struct bat_attribute **bat_attr;
+
+ for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
+ sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
+
+ kobject_put(bat_priv->mesh_obj);
+ bat_priv->mesh_obj = NULL;
+}
+
+static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+ struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+ ssize_t length;
+
+ if (!batman_if)
+ return 0;
+
+ length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ?
+ "none" : batman_if->soft_iface->name);
+
+ kref_put(&batman_if->refcount, hardif_free_ref);
+
+ return length;
+}
+
+static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+ struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+ int status_tmp = -1;
+ int ret;
+
+ if (!batman_if)
+ return count;
+
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ if (strlen(buff) >= IFNAMSIZ) {
+ pr_err("Invalid parameter for 'mesh_iface' setting received: "
+ "interface name too long '%s'\n", buff);
+ kref_put(&batman_if->refcount, hardif_free_ref);
+ return -EINVAL;
+ }
+
+ if (strncmp(buff, "none", 4) == 0)
+ status_tmp = IF_NOT_IN_USE;
+ else
+ status_tmp = IF_I_WANT_YOU;
+
+ if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) &&
+ (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) {
+ kref_put(&batman_if->refcount, hardif_free_ref);
+ return count;
+ }
+
+ if (status_tmp == IF_NOT_IN_USE) {
+ rtnl_lock();
+ hardif_disable_interface(batman_if);
+ rtnl_unlock();
+ kref_put(&batman_if->refcount, hardif_free_ref);
+ return count;
+ }
+
+ /* if the interface already is in use */
+ if (batman_if->if_status != IF_NOT_IN_USE) {
+ rtnl_lock();
+ hardif_disable_interface(batman_if);
+ rtnl_unlock();
+ }
+
+ ret = hardif_enable_interface(batman_if, buff);
+ kref_put(&batman_if->refcount, hardif_free_ref);
+
+ return ret;
+}
+
+static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct net_device *net_dev = kobj_to_netdev(kobj);
+ struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+ ssize_t length;
+
+ if (!batman_if)
+ return 0;
+
+ switch (batman_if->if_status) {
+ case IF_TO_BE_REMOVED:
+ length = sprintf(buff, "disabling\n");
+ break;
+ case IF_INACTIVE:
+ length = sprintf(buff, "inactive\n");
+ break;
+ case IF_ACTIVE:
+ length = sprintf(buff, "active\n");
+ break;
+ case IF_TO_BE_ACTIVATED:
+ length = sprintf(buff, "enabling\n");
+ break;
+ case IF_NOT_IN_USE:
+ default:
+ length = sprintf(buff, "not in use\n");
+ break;
+ }
+
+ kref_put(&batman_if->refcount, hardif_free_ref);
+
+ return length;
+}
+
+static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
+ show_mesh_iface, store_mesh_iface);
+static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
+
+static struct bat_attribute *batman_attrs[] = {
+ &bat_attr_mesh_iface,
+ &bat_attr_iface_status,
+ NULL,
+};
+
+int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
+{
+ struct kobject *hardif_kobject = &dev->dev.kobj;
+ struct bat_attribute **bat_attr;
+ int err;
+
+ *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
+ hardif_kobject);
+
+ if (!*hardif_obj) {
+ bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+ SYSFS_IF_BAT_SUBDIR);
+ goto out;
+ }
+
+ for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) {
+ err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
+ if (err) {
+ bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+ dev->name, SYSFS_IF_BAT_SUBDIR,
+ ((*bat_attr)->attr).name);
+ goto rem_attr;
+ }
+ }
+
+ return 0;
+
+rem_attr:
+ for (bat_attr = batman_attrs; *bat_attr; ++bat_attr)
+ sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
+out:
+ return -ENOMEM;
+}
+
+void sysfs_del_hardif(struct kobject **hardif_obj)
+{
+ kobject_put(*hardif_obj);
+ *hardif_obj = NULL;
+}
diff --git a/net/batman-adv/bat_sysfs.h b/net/batman-adv/bat_sysfs.h
new file mode 100644
index 000000000000..7f186c007b4f
--- /dev/null
+++ b/net/batman-adv/bat_sysfs.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+
+#ifndef _NET_BATMAN_ADV_SYSFS_H_
+#define _NET_BATMAN_ADV_SYSFS_H_
+
+#define SYSFS_IF_MESH_SUBDIR "mesh"
+#define SYSFS_IF_BAT_SUBDIR "batman_adv"
+
+struct bat_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
+ char *buf, size_t count);
+};
+
+int sysfs_add_meshif(struct net_device *dev);
+void sysfs_del_meshif(struct net_device *dev);
+int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
+void sysfs_del_hardif(struct kobject **hardif_obj);
+
+#endif /* _NET_BATMAN_ADV_SYSFS_H_ */
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c
new file mode 100644
index 000000000000..bbcd8f744cdd
--- /dev/null
+++ b/net/batman-adv/bitarray.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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 "bitarray.h"
+
+#include <linux/bitops.h>
+
+/* returns true if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno */
+uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno,
+ uint32_t curr_seqno)
+{
+ int32_t diff, word_offset, word_num;
+
+ diff = last_seqno - curr_seqno;
+ if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
+ return 0;
+ } else {
+ /* which word */
+ word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE;
+ /* which position in the selected word */
+ word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE;
+
+ if (test_bit(word_offset, &seq_bits[word_num]))
+ return 1;
+ else
+ return 0;
+ }
+}
+
+/* turn corresponding bit on, so we can remember that we got the packet */
+void bit_mark(unsigned long *seq_bits, int32_t n)
+{
+ int32_t word_offset, word_num;
+
+ /* if too old, just drop it */
+ if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE)
+ return;
+
+ /* which word */
+ word_num = n / WORD_BIT_SIZE;
+ /* which position in the selected word */
+ word_offset = n % WORD_BIT_SIZE;
+
+ set_bit(word_offset, &seq_bits[word_num]); /* turn the position on */
+}
+
+/* shift the packet array by n places. */
+static void bit_shift(unsigned long *seq_bits, int32_t n)
+{
+ int32_t word_offset, word_num;
+ int32_t i;
+
+ if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE)
+ return;
+
+ word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */
+ word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */
+
+ for (i = NUM_WORDS - 1; i > word_num; i--) {
+ /* going from old to new, so we don't overwrite the data we copy
+ * from.
+ *
+ * left is high, right is low: FEDC BA98 7654 3210
+ * ^^ ^^
+ * vvvv
+ * ^^^^ = from, vvvvv =to, we'd have word_num==1 and
+ * word_offset==WORD_BIT_SIZE/2 ????? in this example.
+ * (=24 bits)
+ *
+ * our desired output would be: 9876 5432 1000 0000
+ * */
+
+ seq_bits[i] =
+ (seq_bits[i - word_num] << word_offset) +
+ /* take the lower port from the left half, shift it left
+ * to its final position */
+ (seq_bits[i - word_num - 1] >>
+ (WORD_BIT_SIZE-word_offset));
+ /* and the upper part of the right half and shift it left to
+ * it's position */
+ /* for our example that would be: word[0] = 9800 + 0076 =
+ * 9876 */
+ }
+ /* now for our last word, i==word_num, we only have the it's "left"
+ * half. that's the 1000 word in our example.*/
+
+ seq_bits[i] = (seq_bits[i - word_num] << word_offset);
+
+ /* pad the rest with 0, if there is anything */
+ i--;
+
+ for (; i >= 0; i--)
+ seq_bits[i] = 0;
+}
+
+static void bit_reset_window(unsigned long *seq_bits)
+{
+ int i;
+ for (i = 0; i < NUM_WORDS; i++)
+ seq_bits[i] = 0;
+}
+
+
+/* receive and process one packet within the sequence number window.
+ *
+ * returns:
+ * 1 if the window was moved (either new or very old)
+ * 0 if the window was not moved/shifted.
+ */
+char bit_get_packet(void *priv, unsigned long *seq_bits,
+ int32_t seq_num_diff, int8_t set_mark)
+{
+ struct bat_priv *bat_priv = (struct bat_priv *)priv;
+
+ /* sequence number is slightly older. We already got a sequence number
+ * higher than this one, so we just mark it. */
+
+ if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) {
+ if (set_mark)
+ bit_mark(seq_bits, -seq_num_diff);
+ return 0;
+ }
+
+ /* sequence number is slightly newer, so we shift the window and
+ * set the mark if required */
+
+ if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) {
+ bit_shift(seq_bits, seq_num_diff);
+
+ if (set_mark)
+ bit_mark(seq_bits, 0);
+ return 1;
+ }
+
+ /* sequence number is much newer, probably missed a lot of packets */
+
+ if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
+ || (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "We missed a lot of packets (%i) !\n",
+ seq_num_diff - 1);
+ bit_reset_window(seq_bits);
+ if (set_mark)
+ bit_mark(seq_bits, 0);
+ return 1;
+ }
+
+ /* received a much older packet. The other host either restarted
+ * or the old packet got delayed somewhere in the network. The
+ * packet should be dropped without calling this function if the
+ * seqno window is protected. */
+
+ if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
+ || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Other host probably restarted!\n");
+
+ bit_reset_window(seq_bits);
+ if (set_mark)
+ bit_mark(seq_bits, 0);
+
+ return 1;
+ }
+
+ /* never reached */
+ return 0;
+}
+
+/* count the hamming weight, how many good packets did we receive? just count
+ * the 1's.
+ */
+int bit_packet_count(unsigned long *seq_bits)
+{
+ int i, hamming = 0;
+
+ for (i = 0; i < NUM_WORDS; i++)
+ hamming += hweight_long(seq_bits[i]);
+
+ return hamming;
+}
diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h
new file mode 100644
index 000000000000..ac54017601b1
--- /dev/null
+++ b/net/batman-adv/bitarray.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_BITARRAY_H_
+#define _NET_BATMAN_ADV_BITARRAY_H_
+
+#define WORD_BIT_SIZE (sizeof(unsigned long) * 8)
+
+/* returns true if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno */
+uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno,
+ uint32_t curr_seqno);
+
+/* turn corresponding bit on, so we can remember that we got the packet */
+void bit_mark(unsigned long *seq_bits, int32_t n);
+
+
+/* receive and process one packet, returns 1 if received seq_num is considered
+ * new, 0 if old */
+char bit_get_packet(void *priv, unsigned long *seq_bits,
+ int32_t seq_num_diff, int8_t set_mark);
+
+/* count the hamming weight, how many good packets did we receive? */
+int bit_packet_count(unsigned long *seq_bits);
+
+#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
new file mode 100644
index 000000000000..0065ffb8d96d
--- /dev/null
+++ b/net/batman-adv/gateway_client.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 "gateway_client.h"
+#include "gateway_common.h"
+#include "hard-interface.h"
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/if_vlan.h>
+
+static void gw_node_free_ref(struct kref *refcount)
+{
+ struct gw_node *gw_node;
+
+ gw_node = container_of(refcount, struct gw_node, refcount);
+ kfree(gw_node);
+}
+
+static void gw_node_free_rcu(struct rcu_head *rcu)
+{
+ struct gw_node *gw_node;
+
+ gw_node = container_of(rcu, struct gw_node, rcu);
+ kref_put(&gw_node->refcount, gw_node_free_ref);
+}
+
+void *gw_get_selected(struct bat_priv *bat_priv)
+{
+ struct gw_node *curr_gateway_tmp = bat_priv->curr_gw;
+
+ if (!curr_gateway_tmp)
+ return NULL;
+
+ return curr_gateway_tmp->orig_node;
+}
+
+void gw_deselect(struct bat_priv *bat_priv)
+{
+ struct gw_node *gw_node = bat_priv->curr_gw;
+
+ bat_priv->curr_gw = NULL;
+
+ if (gw_node)
+ kref_put(&gw_node->refcount, gw_node_free_ref);
+}
+
+static struct gw_node *gw_select(struct bat_priv *bat_priv,
+ struct gw_node *new_gw_node)
+{
+ struct gw_node *curr_gw_node = bat_priv->curr_gw;
+
+ if (new_gw_node)
+ kref_get(&new_gw_node->refcount);
+
+ bat_priv->curr_gw = new_gw_node;
+ return curr_gw_node;
+}
+
+void gw_election(struct bat_priv *bat_priv)
+{
+ struct hlist_node *node;
+ struct gw_node *gw_node, *curr_gw_tmp = NULL, *old_gw_node = NULL;
+ uint8_t max_tq = 0;
+ uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
+ int down, up;
+
+ /**
+ * The batman daemon checks here if we already passed a full originator
+ * cycle in order to make sure we don't choose the first gateway we
+ * hear about. This check is based on the daemon's uptime which we
+ * don't have.
+ **/
+ if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
+ return;
+
+ if (bat_priv->curr_gw)
+ return;
+
+ rcu_read_lock();
+ if (hlist_empty(&bat_priv->gw_list)) {
+ rcu_read_unlock();
+
+ if (bat_priv->curr_gw) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Removing selected gateway - "
+ "no gateway in range\n");
+ gw_deselect(bat_priv);
+ }
+
+ return;
+ }
+
+ hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
+ if (!gw_node->orig_node->router)
+ continue;
+
+ if (gw_node->deleted)
+ continue;
+
+ switch (atomic_read(&bat_priv->gw_sel_class)) {
+ case 1: /* fast connection */
+ gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags,
+ &down, &up);
+
+ tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
+ gw_node->orig_node->router->tq_avg *
+ down * 100 * 100) /
+ (TQ_LOCAL_WINDOW_SIZE *
+ TQ_LOCAL_WINDOW_SIZE * 64);
+
+ if ((tmp_gw_factor > max_gw_factor) ||
+ ((tmp_gw_factor == max_gw_factor) &&
+ (gw_node->orig_node->router->tq_avg > max_tq)))
+ curr_gw_tmp = gw_node;
+ break;
+
+ default: /**
+ * 2: stable connection (use best statistic)
+ * 3: fast-switch (use best statistic but change as
+ * soon as a better gateway appears)
+ * XX: late-switch (use best statistic but change as
+ * soon as a better gateway appears which has
+ * $routing_class more tq points)
+ **/
+ if (gw_node->orig_node->router->tq_avg > max_tq)
+ curr_gw_tmp = gw_node;
+ break;
+ }
+
+ if (gw_node->orig_node->router->tq_avg > max_tq)
+ max_tq = gw_node->orig_node->router->tq_avg;
+
+ if (tmp_gw_factor > max_gw_factor)
+ max_gw_factor = tmp_gw_factor;
+ }
+
+ if (bat_priv->curr_gw != curr_gw_tmp) {
+ if ((bat_priv->curr_gw) && (!curr_gw_tmp))
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Removing selected gateway - "
+ "no gateway in range\n");
+ else if ((!bat_priv->curr_gw) && (curr_gw_tmp))
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Adding route to gateway %pM "
+ "(gw_flags: %i, tq: %i)\n",
+ curr_gw_tmp->orig_node->orig,
+ curr_gw_tmp->orig_node->gw_flags,
+ curr_gw_tmp->orig_node->router->tq_avg);
+ else
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Changing route to gateway %pM "
+ "(gw_flags: %i, tq: %i)\n",
+ curr_gw_tmp->orig_node->orig,
+ curr_gw_tmp->orig_node->gw_flags,
+ curr_gw_tmp->orig_node->router->tq_avg);
+
+ old_gw_node = gw_select(bat_priv, curr_gw_tmp);
+ }
+
+ rcu_read_unlock();
+
+ /* the kfree() has to be outside of the rcu lock */
+ if (old_gw_node)
+ kref_put(&old_gw_node->refcount, gw_node_free_ref);
+}
+
+void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
+{
+ struct gw_node *curr_gateway_tmp = bat_priv->curr_gw;
+ uint8_t gw_tq_avg, orig_tq_avg;
+
+ if (!curr_gateway_tmp)
+ return;
+
+ if (!curr_gateway_tmp->orig_node)
+ goto deselect;
+
+ if (!curr_gateway_tmp->orig_node->router)
+ goto deselect;
+
+ /* this node already is the gateway */
+ if (curr_gateway_tmp->orig_node == orig_node)
+ return;
+
+ if (!orig_node->router)
+ return;
+
+ gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
+ orig_tq_avg = orig_node->router->tq_avg;
+
+ /* the TQ value has to be better */
+ if (orig_tq_avg < gw_tq_avg)
+ return;
+
+ /**
+ * if the routing class is greater than 3 the value tells us how much
+ * greater the TQ value of the new gateway must be
+ **/
+ if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
+ (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
+ return;
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Restarting gateway selection: better gateway found (tq curr: "
+ "%i, tq new: %i)\n",
+ gw_tq_avg, orig_tq_avg);
+
+deselect:
+ gw_deselect(bat_priv);
+}
+
+static void gw_node_add(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, uint8_t new_gwflags)
+{
+ struct gw_node *gw_node;
+ int down, up;
+
+ gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC);
+ if (!gw_node)
+ return;
+
+ memset(gw_node, 0, sizeof(struct gw_node));
+ INIT_HLIST_NODE(&gw_node->list);
+ gw_node->orig_node = orig_node;
+ kref_init(&gw_node->refcount);
+
+ spin_lock_bh(&bat_priv->gw_list_lock);
+ hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list);
+ spin_unlock_bh(&bat_priv->gw_list_lock);
+
+ gw_bandwidth_to_kbit(new_gwflags, &down, &up);
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
+ orig_node->orig, new_gwflags,
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
+}
+
+void gw_node_update(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, uint8_t new_gwflags)
+{
+ struct hlist_node *node;
+ struct gw_node *gw_node;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
+ if (gw_node->orig_node != orig_node)
+ continue;
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Gateway class of originator %pM changed from "
+ "%i to %i\n",
+ orig_node->orig, gw_node->orig_node->gw_flags,
+ new_gwflags);
+
+ gw_node->deleted = 0;
+
+ if (new_gwflags == 0) {
+ gw_node->deleted = jiffies;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Gateway %pM removed from gateway list\n",
+ orig_node->orig);
+
+ if (gw_node == bat_priv->curr_gw) {
+ rcu_read_unlock();
+ gw_deselect(bat_priv);
+ return;
+ }
+ }
+
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+
+ if (new_gwflags == 0)
+ return;
+
+ gw_node_add(bat_priv, orig_node, new_gwflags);
+}
+
+void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
+{
+ return gw_node_update(bat_priv, orig_node, 0);
+}
+
+void gw_node_purge(struct bat_priv *bat_priv)
+{
+ struct gw_node *gw_node;
+ struct hlist_node *node, *node_tmp;
+ unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
+
+ spin_lock_bh(&bat_priv->gw_list_lock);
+
+ hlist_for_each_entry_safe(gw_node, node, node_tmp,
+ &bat_priv->gw_list, list) {
+ if (((!gw_node->deleted) ||
+ (time_before(jiffies, gw_node->deleted + timeout))) &&
+ atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
+ continue;
+
+ if (bat_priv->curr_gw == gw_node)
+ gw_deselect(bat_priv);
+
+ hlist_del_rcu(&gw_node->list);
+ call_rcu(&gw_node->rcu, gw_node_free_rcu);
+ }
+
+
+ spin_unlock_bh(&bat_priv->gw_list_lock);
+}
+
+static int _write_buffer_text(struct bat_priv *bat_priv,
+ struct seq_file *seq, struct gw_node *gw_node)
+{
+ int down, up;
+
+ gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
+
+ return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
+ (bat_priv->curr_gw == gw_node ? "=>" : " "),
+ gw_node->orig_node->orig,
+ gw_node->orig_node->router->tq_avg,
+ gw_node->orig_node->router->addr,
+ gw_node->orig_node->router->if_incoming->net_dev->name,
+ gw_node->orig_node->gw_flags,
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
+}
+
+int gw_client_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct gw_node *gw_node;
+ struct hlist_node *node;
+ int gw_count = 0;
+
+ if (!bat_priv->primary_if) {
+
+ return seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ }
+
+ if (bat_priv->primary_if->if_status != IF_ACTIVE) {
+
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ }
+
+ seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
+ "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
+ "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
+ "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
+ bat_priv->primary_if->net_dev->name,
+ bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
+ if (gw_node->deleted)
+ continue;
+
+ if (!gw_node->orig_node->router)
+ continue;
+
+ _write_buffer_text(bat_priv, seq, gw_node);
+ gw_count++;
+ }
+ rcu_read_unlock();
+
+ if (gw_count == 0)
+ seq_printf(seq, "No gateways in range ...\n");
+
+ return 0;
+}
+
+int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ struct ethhdr *ethhdr;
+ struct iphdr *iphdr;
+ struct ipv6hdr *ipv6hdr;
+ struct udphdr *udphdr;
+ unsigned int header_len = 0;
+
+ if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
+ return 0;
+
+ /* check for ethernet header */
+ if (!pskb_may_pull(skb, header_len + ETH_HLEN))
+ return 0;
+ ethhdr = (struct ethhdr *)skb->data;
+ header_len += ETH_HLEN;
+
+ /* check for initial vlan header */
+ if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
+ if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
+ return 0;
+ ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
+ header_len += VLAN_HLEN;
+ }
+
+ /* check for ip header */
+ switch (ntohs(ethhdr->h_proto)) {
+ case ETH_P_IP:
+ if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
+ return 0;
+ iphdr = (struct iphdr *)(skb->data + header_len);
+ header_len += iphdr->ihl * 4;
+
+ /* check for udp header */
+ if (iphdr->protocol != IPPROTO_UDP)
+ return 0;
+
+ break;
+ case ETH_P_IPV6:
+ if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
+ return 0;
+ ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
+ header_len += sizeof(struct ipv6hdr);
+
+ /* check for udp header */
+ if (ipv6hdr->nexthdr != IPPROTO_UDP)
+ return 0;
+
+ break;
+ default:
+ return 0;
+ }
+
+ if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
+ return 0;
+ udphdr = (struct udphdr *)(skb->data + header_len);
+ header_len += sizeof(struct udphdr);
+
+ /* check for bootp port */
+ if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
+ (ntohs(udphdr->dest) != 67))
+ return 0;
+
+ if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
+ (ntohs(udphdr->dest) != 547))
+ return 0;
+
+ if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
+ return -1;
+
+ if (!bat_priv->curr_gw)
+ return 0;
+
+ return 1;
+}
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
new file mode 100644
index 000000000000..4585e6549844
--- /dev/null
+++ b/net/batman-adv/gateway_client.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_
+#define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_
+
+void gw_deselect(struct bat_priv *bat_priv);
+void gw_election(struct bat_priv *bat_priv);
+void *gw_get_selected(struct bat_priv *bat_priv);
+void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node);
+void gw_node_update(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, uint8_t new_gwflags);
+void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node);
+void gw_node_purge(struct bat_priv *bat_priv);
+int gw_client_seq_print_text(struct seq_file *seq, void *offset);
+int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb);
+
+#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
new file mode 100644
index 000000000000..b962982f017e
--- /dev/null
+++ b/net/batman-adv/gateway_common.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 "gateway_common.h"
+#include "gateway_client.h"
+
+/* calculates the gateway class from kbit */
+static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class)
+{
+ int mdown = 0, tdown, tup, difference;
+ uint8_t sbit, part;
+
+ *gw_srv_class = 0;
+ difference = 0x0FFFFFFF;
+
+ /* test all downspeeds */
+ for (sbit = 0; sbit < 2; sbit++) {
+ for (part = 0; part < 16; part++) {
+ tdown = 32 * (sbit + 2) * (1 << part);
+
+ if (abs(tdown - down) < difference) {
+ *gw_srv_class = (sbit << 7) + (part << 3);
+ difference = abs(tdown - down);
+ mdown = tdown;
+ }
+ }
+ }
+
+ /* test all upspeeds */
+ difference = 0x0FFFFFFF;
+
+ for (part = 0; part < 8; part++) {
+ tup = ((part + 1) * (mdown)) / 8;
+
+ if (abs(tup - up) < difference) {
+ *gw_srv_class = (*gw_srv_class & 0xF8) | part;
+ difference = abs(tup - up);
+ }
+ }
+}
+
+/* returns the up and downspeeds in kbit, calculated from the class */
+void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up)
+{
+ char sbit = (gw_srv_class & 0x80) >> 7;
+ char dpart = (gw_srv_class & 0x78) >> 3;
+ char upart = (gw_srv_class & 0x07);
+
+ if (!gw_srv_class) {
+ *down = 0;
+ *up = 0;
+ return;
+ }
+
+ *down = 32 * (sbit + 2) * (1 << dpart);
+ *up = ((upart + 1) * (*down)) / 8;
+}
+
+static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
+ long *up, long *down)
+{
+ int ret, multi = 1;
+ char *slash_ptr, *tmp_ptr;
+
+ slash_ptr = strchr(buff, '/');
+ if (slash_ptr)
+ *slash_ptr = 0;
+
+ if (strlen(buff) > 4) {
+ tmp_ptr = buff + strlen(buff) - 4;
+
+ if (strnicmp(tmp_ptr, "mbit", 4) == 0)
+ multi = 1024;
+
+ if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
+ (multi > 1))
+ *tmp_ptr = '\0';
+ }
+
+ ret = strict_strtoul(buff, 10, down);
+ if (ret) {
+ bat_err(net_dev,
+ "Download speed of gateway mode invalid: %s\n",
+ buff);
+ return false;
+ }
+
+ *down *= multi;
+
+ /* we also got some upload info */
+ if (slash_ptr) {
+ multi = 1;
+
+ if (strlen(slash_ptr + 1) > 4) {
+ tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1);
+
+ if (strnicmp(tmp_ptr, "mbit", 4) == 0)
+ multi = 1024;
+
+ if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
+ (multi > 1))
+ *tmp_ptr = '\0';
+ }
+
+ ret = strict_strtoul(slash_ptr + 1, 10, up);
+ if (ret) {
+ bat_err(net_dev,
+ "Upload speed of gateway mode invalid: "
+ "%s\n", slash_ptr + 1);
+ return false;
+ }
+
+ *up *= multi;
+ }
+
+ return true;
+}
+
+ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count)
+{
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ long gw_bandwidth_tmp = 0, up = 0, down = 0;
+ bool ret;
+
+ ret = parse_gw_bandwidth(net_dev, buff, &up, &down);
+ if (!ret)
+ goto end;
+
+ if ((!down) || (down < 256))
+ down = 2000;
+
+ if (!up)
+ up = down / 5;
+
+ kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp);
+
+ /**
+ * the gw bandwidth we guessed above might not match the given
+ * speeds, hence we need to calculate it back to show the number
+ * that is going to be propagated
+ **/
+ gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp,
+ (int *)&down, (int *)&up);
+
+ gw_deselect(bat_priv);
+ bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' "
+ "(propagating: %ld%s/%ld%s)\n",
+ atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp,
+ (down > 2048 ? down / 1024 : down),
+ (down > 2048 ? "MBit" : "KBit"),
+ (up > 2048 ? up / 1024 : up),
+ (up > 2048 ? "MBit" : "KBit"));
+
+ atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp);
+
+end:
+ return count;
+}
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
new file mode 100644
index 000000000000..5e728d0b7959
--- /dev/null
+++ b/net/batman-adv/gateway_common.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_
+#define _NET_BATMAN_ADV_GATEWAY_COMMON_H_
+
+enum gw_modes {
+ GW_MODE_OFF,
+ GW_MODE_CLIENT,
+ GW_MODE_SERVER,
+};
+
+#define GW_MODE_OFF_NAME "off"
+#define GW_MODE_CLIENT_NAME "client"
+#define GW_MODE_SERVER_NAME "server"
+
+void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up);
+ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count);
+
+#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
new file mode 100644
index 000000000000..4f95777ce080
--- /dev/null
+++ b/net/batman-adv/hard-interface.c
@@ -0,0 +1,651 @@
+/*
+ * Copyright (C) 2007-2010 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 "hard-interface.h"
+#include "soft-interface.h"
+#include "send.h"
+#include "translation-table.h"
+#include "routing.h"
+#include "bat_sysfs.h"
+#include "originator.h"
+#include "hash.h"
+
+#include <linux/if_arp.h>
+
+/* protect update critical side of if_list - but not the content */
+static DEFINE_SPINLOCK(if_list_lock);
+
+static void hardif_free_rcu(struct rcu_head *rcu)
+{
+ struct batman_if *batman_if;
+
+ batman_if = container_of(rcu, struct batman_if, rcu);
+ dev_put(batman_if->net_dev);
+ kref_put(&batman_if->refcount, hardif_free_ref);
+}
+
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->net_dev == net_dev)
+ goto out;
+ }
+
+ batman_if = NULL;
+
+out:
+ if (batman_if)
+ kref_get(&batman_if->refcount);
+
+ rcu_read_unlock();
+ return batman_if;
+}
+
+static int is_valid_iface(struct net_device *net_dev)
+{
+ if (net_dev->flags & IFF_LOOPBACK)
+ return 0;
+
+ if (net_dev->type != ARPHRD_ETHER)
+ return 0;
+
+ if (net_dev->addr_len != ETH_ALEN)
+ return 0;
+
+ /* no batman over batman */
+#ifdef HAVE_NET_DEVICE_OPS
+ if (net_dev->netdev_ops->ndo_start_xmit == interface_tx)
+ return 0;
+#else
+ if (net_dev->hard_start_xmit == interface_tx)
+ return 0;
+#endif
+
+ /* Device is being bridged */
+ /* if (net_dev->priv_flags & IFF_BRIDGE_PORT)
+ return 0; */
+
+ return 1;
+}
+
+static struct batman_if *get_active_batman_if(struct net_device *soft_iface)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
+ if (batman_if->if_status == IF_ACTIVE)
+ goto out;
+ }
+
+ batman_if = NULL;
+
+out:
+ if (batman_if)
+ kref_get(&batman_if->refcount);
+
+ rcu_read_unlock();
+ return batman_if;
+}
+
+static void update_primary_addr(struct bat_priv *bat_priv)
+{
+ struct vis_packet *vis_packet;
+
+ vis_packet = (struct vis_packet *)
+ bat_priv->my_vis_info->skb_packet->data;
+ memcpy(vis_packet->vis_orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(vis_packet->sender_orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+}
+
+static void set_primary_if(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
+{
+ struct batman_packet *batman_packet;
+ struct batman_if *old_if;
+
+ if (batman_if)
+ kref_get(&batman_if->refcount);
+
+ old_if = bat_priv->primary_if;
+ bat_priv->primary_if = batman_if;
+
+ if (old_if)
+ kref_put(&old_if->refcount, hardif_free_ref);
+
+ if (!bat_priv->primary_if)
+ return;
+
+ batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+ batman_packet->flags = PRIMARIES_FIRST_HOP;
+ batman_packet->ttl = TTL;
+
+ update_primary_addr(bat_priv);
+
+ /***
+ * hacky trick to make sure that we send the HNA information via
+ * our new primary interface
+ */
+ atomic_set(&bat_priv->hna_local_changed, 1);
+}
+
+static bool hardif_is_iface_up(struct batman_if *batman_if)
+{
+ if (batman_if->net_dev->flags & IFF_UP)
+ return true;
+
+ return false;
+}
+
+static void update_mac_addresses(struct batman_if *batman_if)
+{
+ memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
+ batman_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
+ batman_if->net_dev->dev_addr, ETH_ALEN);
+}
+
+static void check_known_mac_addr(struct net_device *net_dev)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ continue;
+
+ if (batman_if->net_dev == net_dev)
+ continue;
+
+ if (!compare_orig(batman_if->net_dev->dev_addr,
+ net_dev->dev_addr))
+ continue;
+
+ pr_warning("The newly added mac address (%pM) already exists "
+ "on: %s\n", net_dev->dev_addr,
+ batman_if->net_dev->name);
+ pr_warning("It is strongly recommended to keep mac addresses "
+ "unique to avoid problems!\n");
+ }
+ rcu_read_unlock();
+}
+
+int hardif_min_mtu(struct net_device *soft_iface)
+{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct batman_if *batman_if;
+ /* allow big frames if all devices are capable to do so
+ * (have MTU > 1500 + BAT_HEADER_LEN) */
+ int min_mtu = ETH_DATA_LEN;
+
+ if (atomic_read(&bat_priv->fragmentation))
+ goto out;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ continue;
+
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
+ min_mtu = min_t(int, batman_if->net_dev->mtu - BAT_HEADER_LEN,
+ min_mtu);
+ }
+ rcu_read_unlock();
+out:
+ return min_mtu;
+}
+
+/* adjusts the MTU if a new interface with a smaller MTU appeared. */
+void update_min_mtu(struct net_device *soft_iface)
+{
+ int min_mtu;
+
+ min_mtu = hardif_min_mtu(soft_iface);
+ if (soft_iface->mtu != min_mtu)
+ soft_iface->mtu = min_mtu;
+}
+
+static void hardif_activate_interface(struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv;
+
+ if (batman_if->if_status != IF_INACTIVE)
+ return;
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
+
+ update_mac_addresses(batman_if);
+ batman_if->if_status = IF_TO_BE_ACTIVATED;
+
+ /**
+ * the first active interface becomes our primary interface or
+ * the next active interface after the old primay interface was removed
+ */
+ if (!bat_priv->primary_if)
+ set_primary_if(bat_priv, batman_if);
+
+ bat_info(batman_if->soft_iface, "Interface activated: %s\n",
+ batman_if->net_dev->name);
+
+ update_min_mtu(batman_if->soft_iface);
+ return;
+}
+
+static void hardif_deactivate_interface(struct batman_if *batman_if)
+{
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ return;
+
+ batman_if->if_status = IF_INACTIVE;
+
+ bat_info(batman_if->soft_iface, "Interface deactivated: %s\n",
+ batman_if->net_dev->name);
+
+ update_min_mtu(batman_if->soft_iface);
+}
+
+int hardif_enable_interface(struct batman_if *batman_if, char *iface_name)
+{
+ struct bat_priv *bat_priv;
+ struct batman_packet *batman_packet;
+
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ goto out;
+
+ batman_if->soft_iface = dev_get_by_name(&init_net, iface_name);
+
+ if (!batman_if->soft_iface) {
+ batman_if->soft_iface = softif_create(iface_name);
+
+ if (!batman_if->soft_iface)
+ goto err;
+
+ /* dev_get_by_name() increases the reference counter for us */
+ dev_hold(batman_if->soft_iface);
+ }
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
+ batman_if->packet_len = BAT_PACKET_LEN;
+ batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
+
+ if (!batman_if->packet_buff) {
+ bat_err(batman_if->soft_iface, "Can't add interface packet "
+ "(%s): out of memory\n", batman_if->net_dev->name);
+ goto err;
+ }
+
+ batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+ batman_packet->packet_type = BAT_PACKET;
+ batman_packet->version = COMPAT_VERSION;
+ batman_packet->flags = 0;
+ batman_packet->ttl = 2;
+ batman_packet->tq = TQ_MAX_VALUE;
+ batman_packet->num_hna = 0;
+
+ batman_if->if_num = bat_priv->num_ifaces;
+ bat_priv->num_ifaces++;
+ batman_if->if_status = IF_INACTIVE;
+ orig_hash_add_if(batman_if, bat_priv->num_ifaces);
+
+ batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN);
+ batman_if->batman_adv_ptype.func = batman_skb_recv;
+ batman_if->batman_adv_ptype.dev = batman_if->net_dev;
+ kref_get(&batman_if->refcount);
+ dev_add_pack(&batman_if->batman_adv_ptype);
+
+ atomic_set(&batman_if->seqno, 1);
+ atomic_set(&batman_if->frag_seqno, 1);
+ bat_info(batman_if->soft_iface, "Adding interface: %s\n",
+ batman_if->net_dev->name);
+
+ if (atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu <
+ ETH_DATA_LEN + BAT_HEADER_LEN)
+ bat_info(batman_if->soft_iface,
+ "The MTU of interface %s is too small (%i) to handle "
+ "the transport of batman-adv packets. Packets going "
+ "over this interface will be fragmented on layer2 "
+ "which could impact the performance. Setting the MTU "
+ "to %zi would solve the problem.\n",
+ batman_if->net_dev->name, batman_if->net_dev->mtu,
+ ETH_DATA_LEN + BAT_HEADER_LEN);
+
+ if (!atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu <
+ ETH_DATA_LEN + BAT_HEADER_LEN)
+ bat_info(batman_if->soft_iface,
+ "The MTU of interface %s is too small (%i) to handle "
+ "the transport of batman-adv packets. If you experience"
+ " problems getting traffic through try increasing the "
+ "MTU to %zi.\n",
+ batman_if->net_dev->name, batman_if->net_dev->mtu,
+ ETH_DATA_LEN + BAT_HEADER_LEN);
+
+ if (hardif_is_iface_up(batman_if))
+ hardif_activate_interface(batman_if);
+ else
+ bat_err(batman_if->soft_iface, "Not using interface %s "
+ "(retrying later): interface not active\n",
+ batman_if->net_dev->name);
+
+ /* begin scheduling originator messages on that interface */
+ schedule_own_packet(batman_if);
+
+out:
+ return 0;
+
+err:
+ return -ENOMEM;
+}
+
+void hardif_disable_interface(struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+
+ if (batman_if->if_status == IF_ACTIVE)
+ hardif_deactivate_interface(batman_if);
+
+ if (batman_if->if_status != IF_INACTIVE)
+ return;
+
+ bat_info(batman_if->soft_iface, "Removing interface: %s\n",
+ batman_if->net_dev->name);
+ dev_remove_pack(&batman_if->batman_adv_ptype);
+ kref_put(&batman_if->refcount, hardif_free_ref);
+
+ bat_priv->num_ifaces--;
+ orig_hash_del_if(batman_if, bat_priv->num_ifaces);
+
+ if (batman_if == bat_priv->primary_if) {
+ struct batman_if *new_if;
+
+ new_if = get_active_batman_if(batman_if->soft_iface);
+ set_primary_if(bat_priv, new_if);
+
+ if (new_if)
+ kref_put(&new_if->refcount, hardif_free_ref);
+ }
+
+ kfree(batman_if->packet_buff);
+ batman_if->packet_buff = NULL;
+ batman_if->if_status = IF_NOT_IN_USE;
+
+ /* delete all references to this batman_if */
+ purge_orig_ref(bat_priv);
+ purge_outstanding_packets(bat_priv, batman_if);
+ dev_put(batman_if->soft_iface);
+
+ /* nobody uses this interface anymore */
+ if (!bat_priv->num_ifaces)
+ softif_destroy(batman_if->soft_iface);
+
+ batman_if->soft_iface = NULL;
+}
+
+static struct batman_if *hardif_add_interface(struct net_device *net_dev)
+{
+ struct batman_if *batman_if;
+ int ret;
+
+ ret = is_valid_iface(net_dev);
+ if (ret != 1)
+ goto out;
+
+ dev_hold(net_dev);
+
+ batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
+ if (!batman_if) {
+ pr_err("Can't add interface (%s): out of memory\n",
+ net_dev->name);
+ goto release_dev;
+ }
+
+ ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev);
+ if (ret)
+ goto free_if;
+
+ batman_if->if_num = -1;
+ batman_if->net_dev = net_dev;
+ batman_if->soft_iface = NULL;
+ batman_if->if_status = IF_NOT_IN_USE;
+ INIT_LIST_HEAD(&batman_if->list);
+ kref_init(&batman_if->refcount);
+
+ check_known_mac_addr(batman_if->net_dev);
+
+ spin_lock(&if_list_lock);
+ list_add_tail_rcu(&batman_if->list, &if_list);
+ spin_unlock(&if_list_lock);
+
+ /* extra reference for return */
+ kref_get(&batman_if->refcount);
+ return batman_if;
+
+free_if:
+ kfree(batman_if);
+release_dev:
+ dev_put(net_dev);
+out:
+ return NULL;
+}
+
+static void hardif_remove_interface(struct batman_if *batman_if)
+{
+ /* first deactivate interface */
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ hardif_disable_interface(batman_if);
+
+ if (batman_if->if_status != IF_NOT_IN_USE)
+ return;
+
+ batman_if->if_status = IF_TO_BE_REMOVED;
+ sysfs_del_hardif(&batman_if->hardif_obj);
+ call_rcu(&batman_if->rcu, hardif_free_rcu);
+}
+
+void hardif_remove_interfaces(void)
+{
+ struct batman_if *batman_if, *batman_if_tmp;
+ struct list_head if_queue;
+
+ INIT_LIST_HEAD(&if_queue);
+
+ spin_lock(&if_list_lock);
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
+ list_del_rcu(&batman_if->list);
+ list_add_tail(&batman_if->list, &if_queue);
+ }
+ spin_unlock(&if_list_lock);
+
+ rtnl_lock();
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
+ hardif_remove_interface(batman_if);
+ }
+ rtnl_unlock();
+}
+
+static int hard_if_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *net_dev = (struct net_device *)ptr;
+ struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+ struct bat_priv *bat_priv;
+
+ if (!batman_if && event == NETDEV_REGISTER)
+ batman_if = hardif_add_interface(net_dev);
+
+ if (!batman_if)
+ goto out;
+
+ switch (event) {
+ case NETDEV_UP:
+ hardif_activate_interface(batman_if);
+ break;
+ case NETDEV_GOING_DOWN:
+ case NETDEV_DOWN:
+ hardif_deactivate_interface(batman_if);
+ break;
+ case NETDEV_UNREGISTER:
+ spin_lock(&if_list_lock);
+ list_del_rcu(&batman_if->list);
+ spin_unlock(&if_list_lock);
+
+ hardif_remove_interface(batman_if);
+ break;
+ case NETDEV_CHANGEMTU:
+ if (batman_if->soft_iface)
+ update_min_mtu(batman_if->soft_iface);
+ break;
+ case NETDEV_CHANGEADDR:
+ if (batman_if->if_status == IF_NOT_IN_USE)
+ goto hardif_put;
+
+ check_known_mac_addr(batman_if->net_dev);
+ update_mac_addresses(batman_if);
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
+ if (batman_if == bat_priv->primary_if)
+ update_primary_addr(bat_priv);
+ break;
+ default:
+ break;
+ };
+
+hardif_put:
+ kref_put(&batman_if->refcount, hardif_free_ref);
+out:
+ return NOTIFY_DONE;
+}
+
+/* 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 bat_priv *bat_priv;
+ struct batman_packet *batman_packet;
+ struct batman_if *batman_if;
+ int ret;
+
+ batman_if = container_of(ptype, struct batman_if, batman_adv_ptype);
+ skb = skb_share_check(skb, GFP_ATOMIC);
+
+ /* skb was released by skb_share_check() */
+ if (!skb)
+ goto err_out;
+
+ /* packet should hold at least type and version */
+ if (unlikely(!pskb_may_pull(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;
+
+ if (!batman_if->soft_iface)
+ goto err_free;
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
+
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
+ goto err_free;
+
+ /* discard frames on not active interfaces */
+ if (batman_if->if_status != IF_ACTIVE)
+ goto err_free;
+
+ batman_packet = (struct batman_packet *)skb->data;
+
+ if (batman_packet->version != COMPAT_VERSION) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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, batman_if);
+ break;
+
+ /* unicast packet */
+ case BAT_UNICAST:
+ ret = recv_unicast_packet(skb, batman_if);
+ break;
+
+ /* fragmented unicast packet */
+ case BAT_UNICAST_FRAG:
+ ret = recv_ucast_frag_packet(skb, batman_if);
+ break;
+
+ /* broadcast packet */
+ case BAT_BCAST:
+ ret = recv_bcast_packet(skb, batman_if);
+ break;
+
+ /* vis packet */
+ case BAT_VIS:
+ ret = recv_vis_packet(skb, batman_if);
+ 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,
+};
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
new file mode 100644
index 000000000000..30ec3b8db459
--- /dev/null
+++ b/net/batman-adv/hard-interface.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
+#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
+
+#define IF_NOT_IN_USE 0
+#define IF_TO_BE_REMOVED 1
+#define IF_INACTIVE 2
+#define IF_ACTIVE 3
+#define IF_TO_BE_ACTIVATED 4
+#define IF_I_WANT_YOU 5
+
+extern struct notifier_block hard_if_notifier;
+
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev);
+int hardif_enable_interface(struct batman_if *batman_if, char *iface_name);
+void hardif_disable_interface(struct batman_if *batman_if);
+void hardif_remove_interfaces(void);
+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(struct net_device *soft_iface);
+void update_min_mtu(struct net_device *soft_iface);
+
+static inline void hardif_free_ref(struct kref *refcount)
+{
+ struct batman_if *batman_if;
+
+ batman_if = container_of(refcount, struct batman_if, refcount);
+ kfree(batman_if);
+}
+
+#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c
new file mode 100644
index 000000000000..26e623eb9def
--- /dev/null
+++ b/net/batman-adv/hash.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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 "hash.h"
+
+/* clears the hash */
+static void hash_init(struct hashtable_t *hash)
+{
+ int i;
+
+ for (i = 0 ; i < hash->size; i++)
+ INIT_HLIST_HEAD(&hash->table[i]);
+}
+
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash)
+{
+ kfree(hash->table);
+ kfree(hash);
+}
+
+/* allocates and clears the hash */
+struct hashtable_t *hash_new(int size)
+{
+ struct hashtable_t *hash;
+
+ hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC);
+
+ if (!hash)
+ return NULL;
+
+ hash->size = size;
+ hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC);
+
+ if (!hash->table) {
+ kfree(hash);
+ return NULL;
+ }
+
+ hash_init(hash);
+
+ return hash;
+}
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h
new file mode 100644
index 000000000000..09216ade16f1
--- /dev/null
+++ b/net/batman-adv/hash.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_HASH_H_
+#define _NET_BATMAN_ADV_HASH_H_
+
+#include <linux/list.h>
+
+/* callback to a compare function. should
+ * compare 2 element datas for their keys,
+ * return 0 if same and not 0 if not
+ * same */
+typedef int (*hashdata_compare_cb)(void *, void *);
+
+/* the hashfunction, should return an index
+ * based on the key in the data of the first
+ * argument and the size the second */
+typedef int (*hashdata_choose_cb)(void *, int);
+typedef void (*hashdata_free_cb)(void *, void *);
+
+struct element_t {
+ void *data; /* pointer to the data */
+ struct hlist_node hlist; /* bucket list pointer */
+};
+
+struct hashtable_t {
+ struct hlist_head *table; /* the hashtable itself, with the buckets */
+ int size; /* size of hashtable */
+};
+
+/* allocates and clears the hash */
+struct hashtable_t *hash_new(int size);
+
+/* remove element if you already found the element you want to delete and don't
+ * need the overhead to find it again with hash_remove(). But usually, you
+ * don't want to use this function, as it fiddles with hash-internals. */
+void *hash_remove_element(struct hashtable_t *hash, struct element_t *elem);
+
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash);
+
+/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
+ * called to remove the elements inside of the hash. if you don't remove the
+ * elements, memory might be leaked. */
+static inline void hash_delete(struct hashtable_t *hash,
+ hashdata_free_cb free_cb, void *arg)
+{
+ struct hlist_head *head;
+ struct hlist_node *walk, *safe;
+ struct element_t *bucket;
+ int i;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_safe(walk, safe, head) {
+ bucket = hlist_entry(walk, struct element_t, hlist);
+ if (free_cb)
+ free_cb(bucket->data, arg);
+
+ hlist_del(walk);
+ kfree(bucket);
+ }
+ }
+
+ hash_destroy(hash);
+}
+
+/* adds data to the hashtable. returns 0 on success, -1 on error */
+static inline int hash_add(struct hashtable_t *hash,
+ hashdata_compare_cb compare,
+ hashdata_choose_cb choose, void *data)
+{
+ int index;
+ struct hlist_head *head;
+ struct hlist_node *walk, *safe;
+ struct element_t *bucket;
+
+ if (!hash)
+ return -1;
+
+ index = choose(data, hash->size);
+ head = &hash->table[index];
+
+ hlist_for_each_safe(walk, safe, head) {
+ bucket = hlist_entry(walk, struct element_t, hlist);
+ if (compare(bucket->data, data))
+ return -1;
+ }
+
+ /* no duplicate found in list, add new element */
+ bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
+
+ if (!bucket)
+ return -1;
+
+ bucket->data = data;
+ hlist_add_head(&bucket->hlist, head);
+
+ return 0;
+}
+
+/* removes data from hash, if found. returns pointer do data on success, so you
+ * can remove the used structure yourself, or NULL on error . data could be the
+ * structure you use with just the key filled, we just need the key for
+ * comparing. */
+static inline void *hash_remove(struct hashtable_t *hash,
+ hashdata_compare_cb compare,
+ hashdata_choose_cb choose, void *data)
+{
+ size_t index;
+ struct hlist_node *walk;
+ struct element_t *bucket;
+ struct hlist_head *head;
+ void *data_save;
+
+ index = choose(data, hash->size);
+ head = &hash->table[index];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ if (compare(bucket->data, data)) {
+ data_save = bucket->data;
+ hlist_del(walk);
+ kfree(bucket);
+ return data_save;
+ }
+ }
+
+ return NULL;
+}
+
+/* finds data, based on the key in keydata. returns the found data on success,
+ * or NULL on error */
+static inline void *hash_find(struct hashtable_t *hash,
+ hashdata_compare_cb compare,
+ hashdata_choose_cb choose, void *keydata)
+{
+ int index;
+ struct hlist_head *head;
+ struct hlist_node *walk;
+ struct element_t *bucket;
+
+ if (!hash)
+ return NULL;
+
+ index = choose(keydata , hash->size);
+ head = &hash->table[index];
+
+ hlist_for_each(walk, head) {
+ bucket = hlist_entry(walk, struct element_t, hlist);
+ if (compare(bucket->data, keydata))
+ return bucket->data;
+ }
+
+ return NULL;
+}
+
+#endif /* _NET_BATMAN_ADV_HASH_H_ */
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
new file mode 100644
index 000000000000..ecf6d7ffab2e
--- /dev/null
+++ b/net/batman-adv/icmp_socket.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 <linux/debugfs.h>
+#include <linux/slab.h>
+#include "icmp_socket.h"
+#include "send.h"
+#include "types.h"
+#include "hash.h"
+#include "originator.h"
+#include "hard-interface.h"
+
+static struct socket_client *socket_client_hash[256];
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+ struct icmp_packet_rr *icmp_packet,
+ size_t icmp_len);
+
+void bat_socket_init(void)
+{
+ memset(socket_client_hash, 0, sizeof(socket_client_hash));
+}
+
+static int bat_socket_open(struct inode *inode, struct file *file)
+{
+ unsigned int i;
+ struct socket_client *socket_client;
+
+ nonseekable_open(inode, file);
+
+ socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
+
+ if (!socket_client)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) {
+ if (!socket_client_hash[i]) {
+ socket_client_hash[i] = socket_client;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(socket_client_hash)) {
+ pr_err("Error - can't add another packet client: "
+ "maximum number of clients reached\n");
+ kfree(socket_client);
+ return -EXFULL;
+ }
+
+ INIT_LIST_HEAD(&socket_client->queue_list);
+ socket_client->queue_len = 0;
+ socket_client->index = i;
+ socket_client->bat_priv = inode->i_private;
+ spin_lock_init(&socket_client->lock);
+ init_waitqueue_head(&socket_client->queue_wait);
+
+ file->private_data = socket_client;
+
+ inc_module_count();
+ return 0;
+}
+
+static int bat_socket_release(struct inode *inode, struct file *file)
+{
+ struct socket_client *socket_client = file->private_data;
+ struct socket_packet *socket_packet;
+ struct list_head *list_pos, *list_pos_tmp;
+
+ spin_lock_bh(&socket_client->lock);
+
+ /* for all packets in the queue ... */
+ list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) {
+ socket_packet = list_entry(list_pos,
+ struct socket_packet, list);
+
+ list_del(list_pos);
+ kfree(socket_packet);
+ }
+
+ socket_client_hash[socket_client->index] = NULL;
+ spin_unlock_bh(&socket_client->lock);
+
+ kfree(socket_client);
+ dec_module_count();
+
+ return 0;
+}
+
+static ssize_t bat_socket_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct socket_client *socket_client = file->private_data;
+ struct socket_packet *socket_packet;
+ size_t packet_len;
+ int error;
+
+ if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0))
+ return -EAGAIN;
+
+ if ((!buf) || (count < sizeof(struct icmp_packet)))
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, buf, count))
+ return -EFAULT;
+
+ error = wait_event_interruptible(socket_client->queue_wait,
+ socket_client->queue_len);
+
+ if (error)
+ return error;
+
+ spin_lock_bh(&socket_client->lock);
+
+ socket_packet = list_first_entry(&socket_client->queue_list,
+ struct socket_packet, list);
+ list_del(&socket_packet->list);
+ socket_client->queue_len--;
+
+ spin_unlock_bh(&socket_client->lock);
+
+ error = __copy_to_user(buf, &socket_packet->icmp_packet,
+ socket_packet->icmp_len);
+
+ packet_len = socket_packet->icmp_len;
+ kfree(socket_packet);
+
+ if (error)
+ return -EFAULT;
+
+ return packet_len;
+}
+
+static ssize_t bat_socket_write(struct file *file, const char __user *buff,
+ size_t len, loff_t *off)
+{
+ struct socket_client *socket_client = file->private_data;
+ struct bat_priv *bat_priv = socket_client->bat_priv;
+ struct sk_buff *skb;
+ struct icmp_packet_rr *icmp_packet;
+
+ struct orig_node *orig_node;
+ struct batman_if *batman_if;
+ size_t packet_len = sizeof(struct icmp_packet);
+ uint8_t dstaddr[ETH_ALEN];
+
+ if (len < sizeof(struct icmp_packet)) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Error - can't send packet from char device: "
+ "invalid packet size\n");
+ return -EINVAL;
+ }
+
+ if (!bat_priv->primary_if)
+ return -EFAULT;
+
+ if (len >= sizeof(struct icmp_packet_rr))
+ packet_len = sizeof(struct icmp_packet_rr);
+
+ skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reserve(skb, sizeof(struct ethhdr));
+ icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
+
+ if (!access_ok(VERIFY_READ, buff, packet_len)) {
+ len = -EFAULT;
+ goto free_skb;
+ }
+
+ if (__copy_from_user(icmp_packet, buff, packet_len)) {
+ len = -EFAULT;
+ goto free_skb;
+ }
+
+ if (icmp_packet->packet_type != BAT_ICMP) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Error - can't send packet from char device: "
+ "got bogus packet type (expected: BAT_ICMP)\n");
+ len = -EINVAL;
+ goto free_skb;
+ }
+
+ if (icmp_packet->msg_type != ECHO_REQUEST) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Error - can't send packet from char device: "
+ "got bogus message type (expected: ECHO_REQUEST)\n");
+ len = -EINVAL;
+ goto free_skb;
+ }
+
+ icmp_packet->uid = socket_client->index;
+
+ if (icmp_packet->version != COMPAT_VERSION) {
+ icmp_packet->msg_type = PARAMETER_PROBLEM;
+ icmp_packet->ttl = COMPAT_VERSION;
+ bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+ goto free_skb;
+ }
+
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
+ goto dst_unreach;
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ compare_orig, choose_orig,
+ icmp_packet->dst));
+
+ if (!orig_node)
+ goto unlock;
+
+ if (!orig_node->router)
+ goto unlock;
+
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ if (!batman_if)
+ goto dst_unreach;
+
+ if (batman_if->if_status != IF_ACTIVE)
+ goto dst_unreach;
+
+ memcpy(icmp_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+
+ if (packet_len == sizeof(struct icmp_packet_rr))
+ memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+
+
+ send_skb_packet(skb, batman_if, dstaddr);
+
+ goto out;
+
+unlock:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+dst_unreach:
+ icmp_packet->msg_type = DESTINATION_UNREACHABLE;
+ bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+free_skb:
+ kfree_skb(skb);
+out:
+ return len;
+}
+
+static unsigned int bat_socket_poll(struct file *file, poll_table *wait)
+{
+ struct socket_client *socket_client = file->private_data;
+
+ poll_wait(file, &socket_client->queue_wait, wait);
+
+ if (socket_client->queue_len > 0)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .open = bat_socket_open,
+ .release = bat_socket_release,
+ .read = bat_socket_read,
+ .write = bat_socket_write,
+ .poll = bat_socket_poll,
+ .llseek = no_llseek,
+};
+
+int bat_socket_setup(struct bat_priv *bat_priv)
+{
+ struct dentry *d;
+
+ if (!bat_priv->debug_dir)
+ goto err;
+
+ d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
+ bat_priv->debug_dir, bat_priv, &fops);
+ if (d)
+ goto err;
+
+ return 0;
+
+err:
+ return 1;
+}
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+ struct icmp_packet_rr *icmp_packet,
+ size_t icmp_len)
+{
+ struct socket_packet *socket_packet;
+
+ socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC);
+
+ if (!socket_packet)
+ return;
+
+ INIT_LIST_HEAD(&socket_packet->list);
+ memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len);
+ socket_packet->icmp_len = icmp_len;
+
+ spin_lock_bh(&socket_client->lock);
+
+ /* while waiting for the lock the socket_client could have been
+ * deleted */
+ if (!socket_client_hash[icmp_packet->uid]) {
+ spin_unlock_bh(&socket_client->lock);
+ kfree(socket_packet);
+ return;
+ }
+
+ list_add_tail(&socket_packet->list, &socket_client->queue_list);
+ socket_client->queue_len++;
+
+ if (socket_client->queue_len > 100) {
+ socket_packet = list_first_entry(&socket_client->queue_list,
+ struct socket_packet, list);
+
+ list_del(&socket_packet->list);
+ kfree(socket_packet);
+ socket_client->queue_len--;
+ }
+
+ spin_unlock_bh(&socket_client->lock);
+
+ wake_up(&socket_client->queue_wait);
+}
+
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+ size_t icmp_len)
+{
+ struct socket_client *hash = socket_client_hash[icmp_packet->uid];
+
+ if (hash)
+ bat_socket_add_packet(hash, icmp_packet, icmp_len);
+}
diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h
new file mode 100644
index 000000000000..bf9b348cde27
--- /dev/null
+++ b/net/batman-adv/icmp_socket.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_
+#define _NET_BATMAN_ADV_ICMP_SOCKET_H_
+
+#include "types.h"
+
+#define ICMP_SOCKET "socket"
+
+void bat_socket_init(void);
+int bat_socket_setup(struct bat_priv *bat_priv);
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+ size_t icmp_len);
+
+#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
new file mode 100644
index 000000000000..b827f6a158cb
--- /dev/null
+++ b/net/batman-adv/main.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2007-2010 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 "bat_sysfs.h"
+#include "bat_debugfs.h"
+#include "routing.h"
+#include "send.h"
+#include "originator.h"
+#include "soft-interface.h"
+#include "icmp_socket.h"
+#include "translation-table.h"
+#include "hard-interface.h"
+#include "gateway_client.h"
+#include "types.h"
+#include "vis.h"
+#include "hash.h"
+
+struct list_head if_list;
+
+unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct workqueue_struct *bat_event_workqueue;
+
+static int __init batman_init(void)
+{
+ INIT_LIST_HEAD(&if_list);
+
+ /* the name should not be longer than 10 chars - see
+ * http://lwn.net/Articles/23634/ */
+ bat_event_workqueue = create_singlethread_workqueue("bat_events");
+
+ if (!bat_event_workqueue)
+ return -ENOMEM;
+
+ bat_socket_init();
+ debugfs_init();
+
+ register_netdevice_notifier(&hard_if_notifier);
+
+ pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
+ "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
+ COMPAT_VERSION);
+
+ return 0;
+}
+
+static void __exit batman_exit(void)
+{
+ debugfs_destroy();
+ unregister_netdevice_notifier(&hard_if_notifier);
+ hardif_remove_interfaces();
+
+ flush_workqueue(bat_event_workqueue);
+ destroy_workqueue(bat_event_workqueue);
+ bat_event_workqueue = NULL;
+
+ rcu_barrier();
+}
+
+int mesh_init(struct net_device *soft_iface)
+{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+
+ spin_lock_init(&bat_priv->orig_hash_lock);
+ spin_lock_init(&bat_priv->forw_bat_list_lock);
+ spin_lock_init(&bat_priv->forw_bcast_list_lock);
+ spin_lock_init(&bat_priv->hna_lhash_lock);
+ spin_lock_init(&bat_priv->hna_ghash_lock);
+ spin_lock_init(&bat_priv->gw_list_lock);
+ spin_lock_init(&bat_priv->vis_hash_lock);
+ spin_lock_init(&bat_priv->vis_list_lock);
+ spin_lock_init(&bat_priv->softif_neigh_lock);
+
+ INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
+ INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
+ INIT_HLIST_HEAD(&bat_priv->gw_list);
+ INIT_HLIST_HEAD(&bat_priv->softif_neigh_list);
+
+ if (originator_init(bat_priv) < 1)
+ goto err;
+
+ if (hna_local_init(bat_priv) < 1)
+ goto err;
+
+ if (hna_global_init(bat_priv) < 1)
+ goto err;
+
+ hna_local_add(soft_iface, soft_iface->dev_addr);
+
+ if (vis_init(bat_priv) < 1)
+ goto err;
+
+ atomic_set(&bat_priv->mesh_state, MESH_ACTIVE);
+ goto end;
+
+err:
+ pr_err("Unable to allocate memory for mesh information structures: "
+ "out of mem ?\n");
+ mesh_free(soft_iface);
+ return -1;
+
+end:
+ return 0;
+}
+
+void mesh_free(struct net_device *soft_iface)
+{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+
+ atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING);
+
+ purge_outstanding_packets(bat_priv, NULL);
+
+ vis_quit(bat_priv);
+
+ gw_node_purge(bat_priv);
+ originator_free(bat_priv);
+
+ hna_local_free(bat_priv);
+ hna_global_free(bat_priv);
+
+ softif_neigh_purge(bat_priv);
+
+ atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
+}
+
+void inc_module_count(void)
+{
+ try_module_get(THIS_MODULE);
+}
+
+void dec_module_count(void)
+{
+ module_put(THIS_MODULE);
+}
+
+int is_my_mac(uint8_t *addr)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->if_status != IF_ACTIVE)
+ continue;
+
+ if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
+ rcu_read_unlock();
+ return 1;
+ }
+ }
+ rcu_read_unlock();
+ return 0;
+
+}
+
+module_init(batman_init);
+module_exit(batman_exit);
+
+MODULE_LICENSE("GPL");
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE);
+#ifdef REVISION_VERSION
+MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION);
+#else
+MODULE_VERSION(SOURCE_VERSION);
+#endif
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
new file mode 100644
index 000000000000..d4d9926c2201
--- /dev/null
+++ b/net/batman-adv/main.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_MAIN_H_
+#define _NET_BATMAN_ADV_MAIN_H_
+
+/* Kernel Programming */
+#define LINUX
+
+#define DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \
+ "Simon Wunderlich <siwu@hrz.tu-chemnitz.de>"
+#define DRIVER_DESC "B.A.T.M.A.N. advanced"
+#define DRIVER_DEVICE "batman-adv"
+
+#define SOURCE_VERSION "next"
+
+
+/* B.A.T.M.A.N. parameters */
+
+#define TQ_MAX_VALUE 255
+#define JITTER 20
+#define TTL 50 /* Time To Live of broadcast messages */
+
+#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no
+ * valid packet comes in -> TODO: check
+ * influence on TQ_LOCAL_WINDOW_SIZE */
+#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
+
+#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
+#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
+#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
+#define TQ_TOTAL_BIDRECT_LIMIT 1
+
+#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
+
+#define PACKBUFF_SIZE 2000
+#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
+
+#define VIS_INTERVAL 5000 /* 5 seconds */
+
+/* how much worse secondary interfaces may be to
+ * to be considered as bonding candidates */
+
+#define BONDING_TQ_THRESHOLD 50
+
+#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
+ * change the size of
+ * forw_packet->direct_link_flags */
+#define MAX_AGGREGATION_MS 100
+
+#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */
+
+#define RESET_PROTECTION_MS 30000
+#define EXPECTED_SEQNO_RANGE 65536
+/* don't reset again within 30 seconds */
+
+#define MESH_INACTIVE 0
+#define MESH_ACTIVE 1
+#define MESH_DEACTIVATING 2
+
+#define BCAST_QUEUE_LEN 256
+#define BATMAN_QUEUE_LEN 256
+
+/*
+ * Debug Messages
+ */
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
+ * kernel messages */
+
+#define DBG_BATMAN 1 /* all messages related to routing / flooding /
+ * broadcasting / etc */
+#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
+#define DBG_ALL 3
+
+#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
+
+
+/*
+ * Vis
+ */
+
+/* #define VIS_SUBCLUSTERS_DISABLED */
+
+/*
+ * Kernel headers
+ */
+
+#include <linux/mutex.h> /* mutex */
+#include <linux/module.h> /* needed by all modules */
+#include <linux/netdevice.h> /* netdevice */
+#include <linux/etherdevice.h> /* ethernet address classifaction */
+#include <linux/if_ether.h> /* ethernet header */
+#include <linux/poll.h> /* poll_table */
+#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 <linux/seq_file.h>
+#include "types.h"
+
+#ifndef REVISION_VERSION
+#define REVISION_VERSION_STR ""
+#else
+#define REVISION_VERSION_STR " "REVISION_VERSION
+#endif
+
+extern struct list_head if_list;
+
+extern unsigned char broadcast_addr[];
+extern struct workqueue_struct *bat_event_workqueue;
+
+int mesh_init(struct net_device *soft_iface);
+void mesh_free(struct net_device *soft_iface);
+void inc_module_count(void);
+void dec_module_count(void);
+int is_my_mac(uint8_t *addr);
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
+
+#define bat_dbg(type, bat_priv, fmt, arg...) \
+ do { \
+ if (atomic_read(&bat_priv->log_level) & type) \
+ debug_log(bat_priv, fmt, ## arg); \
+ } \
+ while (0)
+#else /* !CONFIG_BATMAN_ADV_DEBUG */
+static inline void bat_dbg(char type __attribute__((unused)),
+ struct bat_priv *bat_priv __attribute__((unused)),
+ char *fmt __attribute__((unused)), ...)
+{
+}
+#endif
+
+#define bat_warning(net_dev, fmt, arg...) \
+ do { \
+ struct net_device *_netdev = (net_dev); \
+ struct bat_priv *_batpriv = netdev_priv(_netdev); \
+ bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
+ pr_warning("%s: " fmt, _netdev->name, ## arg); \
+ } while (0)
+#define bat_info(net_dev, fmt, arg...) \
+ do { \
+ struct net_device *_netdev = (net_dev); \
+ struct bat_priv *_batpriv = netdev_priv(_netdev); \
+ bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
+ pr_info("%s: " fmt, _netdev->name, ## arg); \
+ } while (0)
+#define bat_err(net_dev, fmt, arg...) \
+ do { \
+ struct net_device *_netdev = (net_dev); \
+ struct bat_priv *_batpriv = netdev_priv(_netdev); \
+ bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
+ pr_err("%s: " fmt, _netdev->name, ## arg); \
+ } while (0)
+
+#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
new file mode 100644
index 000000000000..6b7fb6b7e6f9
--- /dev/null
+++ b/net/batman-adv/originator.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2009-2010 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"
+#include "gateway_client.h"
+#include "hard-interface.h"
+#include "unicast.h"
+#include "soft-interface.h"
+
+static void purge_orig(struct work_struct *work);
+
+static void start_purge_timer(struct bat_priv *bat_priv)
+{
+ INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ);
+}
+
+int originator_init(struct bat_priv *bat_priv)
+{
+ if (bat_priv->orig_hash)
+ return 1;
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ bat_priv->orig_hash = hash_new(1024);
+
+ if (!bat_priv->orig_hash)
+ goto err;
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ start_purge_timer(bat_priv);
+ return 1;
+
+err:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return 0;
+}
+
+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 bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct neigh_node *neigh_node;
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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;
+}
+
+static void free_orig_node(void *data, void *arg)
+{
+ struct list_head *list_pos, *list_pos_tmp;
+ struct neigh_node *neigh_node;
+ struct orig_node *orig_node = (struct orig_node *)data;
+ struct bat_priv *bat_priv = (struct bat_priv *)arg;
+
+ /* 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);
+ }
+
+ frag_list_free(&orig_node->frag_list);
+ hna_global_del_orig(bat_priv, orig_node, "originator timed out");
+
+ kfree(orig_node->bcast_own);
+ kfree(orig_node->bcast_own_sum);
+ kfree(orig_node);
+}
+
+void originator_free(struct bat_priv *bat_priv)
+{
+ if (!bat_priv->orig_hash)
+ return;
+
+ cancel_delayed_work_sync(&bat_priv->orig_work);
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv);
+ bat_priv->orig_hash = NULL;
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+}
+
+/* this function finds or creates an originator entry for the given
+ * address if it does not exits */
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
+{
+ struct orig_node *orig_node;
+ int size;
+ int hash_added;
+
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ compare_orig, choose_orig,
+ addr));
+
+ if (orig_node)
+ return orig_node;
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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->hna_buff = NULL;
+ orig_node->bcast_seqno_reset = jiffies - 1
+ - msecs_to_jiffies(RESET_PROTECTION_MS);
+ orig_node->batman_seqno_reset = jiffies - 1
+ - msecs_to_jiffies(RESET_PROTECTION_MS);
+
+ size = bat_priv->num_ifaces * sizeof(unsigned long) * NUM_WORDS;
+
+ orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
+ if (!orig_node->bcast_own)
+ goto free_orig_node;
+
+ size = bat_priv->num_ifaces * sizeof(uint8_t);
+ orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
+
+ INIT_LIST_HEAD(&orig_node->frag_list);
+ orig_node->last_frag_packet = 0;
+
+ if (!orig_node->bcast_own_sum)
+ goto free_bcast_own;
+
+ hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig,
+ orig_node);
+ if (hash_added < 0)
+ goto free_bcast_own_sum;
+
+ 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 bat_priv *bat_priv,
+ 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)) ||
+ (neigh_node->if_incoming->if_status == IF_INACTIVE) ||
+ (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
+
+ if (neigh_node->if_incoming->if_status ==
+ IF_TO_BE_REMOVED)
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "neighbor purge: originator %pM, "
+ "neighbor: %pM, iface: %s\n",
+ orig_node->orig, neigh_node->addr,
+ neigh_node->if_incoming->net_dev->name);
+ else
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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) ||
+ (neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
+ *best_neigh_node = neigh_node;
+ }
+ }
+ return neigh_purged;
+}
+
+static bool purge_orig_node(struct bat_priv *bat_priv,
+ struct orig_node *orig_node)
+{
+ struct neigh_node *best_neigh_node;
+
+ if (time_after(jiffies,
+ orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Originator timeout: originator %pM, last_valid %lu\n",
+ orig_node->orig, (orig_node->last_valid / HZ));
+ return true;
+ } else {
+ if (purge_orig_neighbors(bat_priv, orig_node,
+ &best_neigh_node)) {
+ update_routes(bat_priv, orig_node,
+ best_neigh_node,
+ orig_node->hna_buff,
+ orig_node->hna_buff_len);
+ /* update bonding candidates, we could have lost
+ * some candidates. */
+ update_bonding_candidates(bat_priv, orig_node);
+ }
+ }
+
+ return false;
+}
+
+static void _purge_orig(struct bat_priv *bat_priv)
+{
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk, *safe;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ int i;
+
+ if (!hash)
+ return;
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ /* for all origins... */
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) {
+ orig_node = bucket->data;
+
+ if (purge_orig_node(bat_priv, orig_node)) {
+ if (orig_node->gw_flags)
+ gw_node_delete(bat_priv, orig_node);
+ hlist_del(walk);
+ kfree(bucket);
+ free_orig_node(orig_node, bat_priv);
+ }
+
+ if (time_after(jiffies, orig_node->last_frag_packet +
+ msecs_to_jiffies(FRAG_TIMEOUT)))
+ frag_list_free(&orig_node->frag_list);
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ gw_node_purge(bat_priv);
+ gw_election(bat_priv);
+
+ softif_neigh_purge(bat_priv);
+}
+
+static void purge_orig(struct work_struct *work)
+{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, orig_work);
+
+ _purge_orig(bat_priv);
+ start_purge_timer(bat_priv);
+}
+
+void purge_orig_ref(struct bat_priv *bat_priv)
+{
+ _purge_orig(bat_priv);
+}
+
+int orig_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ struct neigh_node *neigh_node;
+ int batman_count = 0;
+ int last_seen_secs;
+ int last_seen_msecs;
+ int i;
+
+ if ((!bat_priv->primary_if) ||
+ (bat_priv->primary_if->if_status != IF_ACTIVE)) {
+ if (!bat_priv->primary_if)
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+
+ return seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ }
+
+ seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
+ SOURCE_VERSION, REVISION_VERSION_STR,
+ bat_priv->primary_if->net_dev->name,
+ bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
+ "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
+ "outgoingIF", "Potential nexthops");
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+
+ if (!orig_node->router)
+ continue;
+
+ if (orig_node->router->tq_avg == 0)
+ continue;
+
+ last_seen_secs = jiffies_to_msecs(jiffies -
+ orig_node->last_valid) / 1000;
+ last_seen_msecs = jiffies_to_msecs(jiffies -
+ orig_node->last_valid) % 1000;
+
+ neigh_node = orig_node->router;
+ seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
+ orig_node->orig, last_seen_secs,
+ last_seen_msecs, neigh_node->tq_avg,
+ neigh_node->addr,
+ neigh_node->if_incoming->net_dev->name);
+
+ list_for_each_entry(neigh_node, &orig_node->neigh_list,
+ list) {
+ seq_printf(seq, " %pM (%3i)", neigh_node->addr,
+ neigh_node->tq_avg);
+ }
+
+ seq_printf(seq, "\n");
+ batman_count++;
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ if ((batman_count == 0))
+ seq_printf(seq, "No batman nodes in range ...\n");
+
+ return 0;
+}
+
+static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
+{
+ void *data_ptr;
+
+ data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS,
+ GFP_ATOMIC);
+ if (!data_ptr) {
+ pr_err("Can't resize orig: out of memory\n");
+ return -1;
+ }
+
+ memcpy(data_ptr, orig_node->bcast_own,
+ (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS);
+ kfree(orig_node->bcast_own);
+ orig_node->bcast_own = data_ptr;
+
+ data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
+ if (!data_ptr) {
+ pr_err("Can't resize orig: out of memory\n");
+ return -1;
+ }
+
+ memcpy(data_ptr, orig_node->bcast_own_sum,
+ (max_if_num - 1) * sizeof(uint8_t));
+ kfree(orig_node->bcast_own_sum);
+ orig_node->bcast_own_sum = data_ptr;
+
+ return 0;
+}
+
+int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ int i;
+
+ /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
+ * if_num */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+
+ if (orig_node_add_if(orig_node, max_if_num) == -1)
+ goto err;
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return 0;
+
+err:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return -ENOMEM;
+}
+
+static int orig_node_del_if(struct orig_node *orig_node,
+ int max_if_num, int del_if_num)
+{
+ void *data_ptr = NULL;
+ int chunk_size;
+
+ /* last interface was removed */
+ if (max_if_num == 0)
+ goto free_bcast_own;
+
+ chunk_size = sizeof(unsigned long) * NUM_WORDS;
+ data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
+ if (!data_ptr) {
+ pr_err("Can't resize orig: out of memory\n");
+ return -1;
+ }
+
+ /* copy first part */
+ memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
+
+ /* copy second part */
+ memcpy(data_ptr + del_if_num * chunk_size,
+ orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
+ (max_if_num - del_if_num) * chunk_size);
+
+free_bcast_own:
+ kfree(orig_node->bcast_own);
+ orig_node->bcast_own = data_ptr;
+
+ if (max_if_num == 0)
+ goto free_own_sum;
+
+ data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
+ if (!data_ptr) {
+ pr_err("Can't resize orig: out of memory\n");
+ return -1;
+ }
+
+ memcpy(data_ptr, orig_node->bcast_own_sum,
+ del_if_num * sizeof(uint8_t));
+
+ memcpy(data_ptr + del_if_num * sizeof(uint8_t),
+ orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)),
+ (max_if_num - del_if_num) * sizeof(uint8_t));
+
+free_own_sum:
+ kfree(orig_node->bcast_own_sum);
+ orig_node->bcast_own_sum = data_ptr;
+
+ return 0;
+}
+
+int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct batman_if *batman_if_tmp;
+ struct orig_node *orig_node;
+ int i, ret;
+
+ /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
+ * if_num */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+
+ ret = orig_node_del_if(orig_node, max_if_num,
+ batman_if->if_num);
+
+ if (ret == -1)
+ goto err;
+ }
+ }
+
+ /* renumber remaining batman interfaces _inside_ of orig_hash_lock */
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if_tmp, &if_list, list) {
+ if (batman_if_tmp->if_status == IF_NOT_IN_USE)
+ continue;
+
+ if (batman_if == batman_if_tmp)
+ continue;
+
+ if (batman_if->soft_iface != batman_if_tmp->soft_iface)
+ continue;
+
+ if (batman_if_tmp->if_num > batman_if->if_num)
+ batman_if_tmp->if_num--;
+ }
+ rcu_read_unlock();
+
+ batman_if->if_num = -1;
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return 0;
+
+err:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return -ENOMEM;
+}
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
new file mode 100644
index 000000000000..d474ceb2a4eb
--- /dev/null
+++ b/net/batman-adv/originator.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
+#define _NET_BATMAN_ADV_ORIGINATOR_H_
+
+int originator_init(struct bat_priv *bat_priv);
+void originator_free(struct bat_priv *bat_priv);
+void purge_orig_ref(struct bat_priv *bat_priv);
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, 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);
+int orig_seq_print_text(struct seq_file *seq, void *offset);
+int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
+int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
+
+
+/* returns 1 if they are the same originator */
+static inline int compare_orig(void *data1, void *data2)
+{
+ return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
+}
+
+/* hashfunction to choose an entry in a hash table of given size */
+/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
+static inline int choose_orig(void *data, int32_t size)
+{
+ unsigned char *key = data;
+ uint32_t hash = 0;
+ size_t i;
+
+ for (i = 0; i < 6; i++) {
+ hash += key[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash % size;
+}
+
+#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
new file mode 100644
index 000000000000..b49fdf70a6d5
--- /dev/null
+++ b/net/batman-adv/packet.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_PACKET_H_
+#define _NET_BATMAN_ADV_PACKET_H_
+
+#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
+
+#define BAT_PACKET 0x01
+#define BAT_ICMP 0x02
+#define BAT_UNICAST 0x03
+#define BAT_BCAST 0x04
+#define BAT_VIS 0x05
+#define BAT_UNICAST_FRAG 0x06
+
+/* this file is included by batctl which needs these defines */
+#define COMPAT_VERSION 12
+#define DIRECTLINK 0x40
+#define VIS_SERVER 0x20
+#define PRIMARIES_FIRST_HOP 0x10
+
+/* ICMP message types */
+#define ECHO_REPLY 0
+#define DESTINATION_UNREACHABLE 3
+#define ECHO_REQUEST 8
+#define TTL_EXCEEDED 11
+#define PARAMETER_PROBLEM 12
+
+/* vis defines */
+#define VIS_TYPE_SERVER_SYNC 0
+#define VIS_TYPE_CLIENT_UPDATE 1
+
+/* fragmentation defines */
+#define UNI_FRAG_HEAD 0x01
+
+struct batman_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
+ uint8_t tq;
+ uint32_t seqno;
+ uint8_t orig[6];
+ uint8_t prev_sender[6];
+ uint8_t ttl;
+ uint8_t num_hna;
+ uint8_t gw_flags; /* flags related to gateway class */
+ uint8_t align;
+} __attribute__((packed));
+
+#define BAT_PACKET_LEN sizeof(struct batman_packet)
+
+struct icmp_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t msg_type; /* see ICMP message types above */
+ uint8_t ttl;
+ uint8_t dst[6];
+ uint8_t orig[6];
+ uint16_t seqno;
+ uint8_t uid;
+} __attribute__((packed));
+
+#define BAT_RR_LEN 16
+
+/* icmp_packet_rr must start with all fields from imcp_packet
+ * as this is assumed by code that handles ICMP packets */
+struct icmp_packet_rr {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t msg_type; /* see ICMP message types above */
+ uint8_t ttl;
+ uint8_t dst[6];
+ uint8_t orig[6];
+ uint16_t seqno;
+ uint8_t uid;
+ uint8_t rr_cur;
+ uint8_t rr[BAT_RR_LEN][ETH_ALEN];
+} __attribute__((packed));
+
+struct unicast_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t dest[6];
+ uint8_t ttl;
+} __attribute__((packed));
+
+struct unicast_frag_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t dest[6];
+ uint8_t ttl;
+ uint8_t flags;
+ uint8_t orig[6];
+ uint16_t seqno;
+} __attribute__((packed));
+
+struct bcast_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t orig[6];
+ uint8_t ttl;
+ uint32_t seqno;
+} __attribute__((packed));
+
+struct vis_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t vis_type; /* which type of vis-participant sent this? */
+ uint8_t entries; /* number of entries behind this struct */
+ uint32_t seqno; /* sequence number */
+ uint8_t ttl; /* TTL */
+ uint8_t vis_orig[6]; /* originator that informs about its
+ * neighbors */
+ uint8_t target_orig[6]; /* who should receive this packet */
+ uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
+} __attribute__((packed));
+
+#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c
new file mode 100644
index 000000000000..defd37c9be1f
--- /dev/null
+++ b/net/batman-adv/ring_buffer.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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 "ring_buffer.h"
+
+void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value)
+{
+ lq_recv[*lq_index] = value;
+ *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE;
+}
+
+uint8_t ring_buffer_avg(uint8_t lq_recv[])
+{
+ uint8_t *ptr;
+ uint16_t count = 0, i = 0, sum = 0;
+
+ ptr = lq_recv;
+
+ while (i < TQ_GLOBAL_WINDOW_SIZE) {
+ if (*ptr != 0) {
+ count++;
+ sum += *ptr;
+ }
+
+ i++;
+ ptr++;
+ }
+
+ if (count == 0)
+ return 0;
+
+ return (uint8_t)(sum / count);
+}
diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h
new file mode 100644
index 000000000000..6b0cb9aaeba5
--- /dev/null
+++ b/net/batman-adv/ring_buffer.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
+#define _NET_BATMAN_ADV_RING_BUFFER_H_
+
+void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
+uint8_t ring_buffer_avg(uint8_t lq_recv[]);
+
+#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
new file mode 100644
index 000000000000..8828eddd3f72
--- /dev/null
+++ b/net/batman-adv/routing.c
@@ -0,0 +1,1397 @@
+/*
+ * Copyright (C) 2007-2010 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 "routing.h"
+#include "send.h"
+#include "hash.h"
+#include "soft-interface.h"
+#include "hard-interface.h"
+#include "icmp_socket.h"
+#include "translation-table.h"
+#include "originator.h"
+#include "types.h"
+#include "ring_buffer.h"
+#include "vis.h"
+#include "aggregation.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
+#include "unicast.h"
+
+void slide_own_bcast_window(struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ unsigned long *word;
+ int i;
+ size_t word_index;
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+ word_index = batman_if->if_num * NUM_WORDS;
+ word = &(orig_node->bcast_own[word_index]);
+
+ bit_get_packet(bat_priv, word, 1, 0);
+ orig_node->bcast_own_sum[batman_if->if_num] =
+ bit_packet_count(word);
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+}
+
+static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ unsigned char *hna_buff, int hna_buff_len)
+{
+ 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(bat_priv, orig_node,
+ "originator changed hna");
+
+ if ((hna_buff_len > 0) && (hna_buff))
+ hna_global_add_orig(bat_priv, orig_node,
+ hna_buff, hna_buff_len);
+ }
+}
+
+static void update_route(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ struct neigh_node *neigh_node,
+ unsigned char *hna_buff, int hna_buff_len)
+{
+ /* route deleted */
+ if ((orig_node->router) && (!neigh_node)) {
+
+ bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
+ orig_node->orig);
+ hna_global_del_orig(bat_priv, orig_node,
+ "originator timed out");
+
+ /* route added */
+ } else if ((!orig_node->router) && (neigh_node)) {
+
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Adding route towards: %pM (via %pM)\n",
+ orig_node->orig, neigh_node->addr);
+ hna_global_add_orig(bat_priv, orig_node,
+ hna_buff, hna_buff_len);
+
+ /* route changed */
+ } else {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Changing route towards: %pM "
+ "(now via %pM - was via %pM)\n",
+ orig_node->orig, neigh_node->addr,
+ orig_node->router->addr);
+ }
+
+ orig_node->router = neigh_node;
+}
+
+
+void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ struct neigh_node *neigh_node, unsigned char *hna_buff,
+ int hna_buff_len)
+{
+
+ if (!orig_node)
+ return;
+
+ if (orig_node->router != neigh_node)
+ update_route(bat_priv, orig_node, neigh_node,
+ hna_buff, hna_buff_len);
+ /* may be just HNA changed */
+ else
+ update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len);
+}
+
+static int is_bidirectional_neigh(struct orig_node *orig_node,
+ struct orig_node *orig_neigh_node,
+ struct batman_packet *batman_packet,
+ struct batman_if *if_incoming)
+{
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+ unsigned char total_count;
+
+ if (orig_node == orig_neigh_node) {
+ 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))
+ neigh_node = tmp_neigh_node;
+ }
+
+ 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) {
+
+ 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)
+ 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]);
+
+ /* 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))
+ 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;
+
+ /*
+ * 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));
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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 bat_priv *bat_priv,
+ 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;
+
+ bat_dbg(DBG_BATMAN, bat_priv, "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)) {
+ neigh_node = tmp_neigh_node;
+ continue;
+ }
+
+ 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);
+ }
+
+ if (!neigh_node) {
+ struct orig_node *orig_tmp;
+
+ orig_tmp = get_orig_node(bat_priv, 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, bat_priv,
+ "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);
+ neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
+
+ if (!is_duplicate) {
+ orig_node->last_ttl = batman_packet->ttl;
+ 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);
+
+ /* if this neighbor already is our next hop there is nothing
+ * to change */
+ if (orig_node->router == neigh_node)
+ goto update_hna;
+
+ /* if this neighbor does not offer a better TQ we won't consider it */
+ if ((orig_node->router) &&
+ (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 ((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])))
+ goto update_hna;
+
+ update_routes(bat_priv, orig_node, neigh_node,
+ hna_buff, tmp_hna_buff_len);
+ goto update_gw;
+
+update_hna:
+ update_routes(bat_priv, orig_node, orig_node->router,
+ hna_buff, tmp_hna_buff_len);
+
+update_gw:
+ if (orig_node->gw_flags != batman_packet->gw_flags)
+ gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
+
+ orig_node->gw_flags = batman_packet->gw_flags;
+
+ /* restart gateway selection if fast or late switching was enabled */
+ if ((orig_node->gw_flags) &&
+ (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
+ (atomic_read(&bat_priv->gw_sel_class) > 2))
+ gw_check_election(bat_priv, orig_node);
+}
+
+/* checks whether the host restarted and is in the protection time.
+ * returns:
+ * 0 if the packet is to be accepted
+ * 1 if the packet is to be ignored.
+ */
+static int window_protected(struct bat_priv *bat_priv,
+ int32_t seq_num_diff,
+ unsigned long *last_reset)
+{
+ if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
+ || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
+ if (time_after(jiffies, *last_reset +
+ msecs_to_jiffies(RESET_PROTECTION_MS))) {
+
+ *last_reset = jiffies;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "old packet received, start protection\n");
+
+ return 0;
+ } else
+ return 1;
+ }
+ return 0;
+}
+
+/* processes a batman packet for all interfaces, adjusts the sequence number and
+ * finds out whether it is a duplicate.
+ * returns:
+ * 1 the packet is a duplicate
+ * 0 the packet has not yet been received
+ * -1 the packet is old and has been received while the seqno window
+ * was protected. Caller should drop it.
+ */
+static char count_real_packets(struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ struct batman_if *if_incoming)
+{
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct orig_node *orig_node;
+ struct neigh_node *tmp_neigh_node;
+ char is_duplicate = 0;
+ int32_t seq_diff;
+ int need_update = 0;
+ int set_mark;
+
+ orig_node = get_orig_node(bat_priv, batman_packet->orig);
+ if (!orig_node)
+ return 0;
+
+ seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
+
+ /* signalize caller that the packet is to be dropped. */
+ if (window_protected(bat_priv, seq_diff,
+ &orig_node->batman_seqno_reset))
+ return -1;
+
+ list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+ 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))
+ set_mark = 1;
+ else
+ set_mark = 0;
+
+ /* if the window moved, set the update flag. */
+ need_update |= bit_get_packet(bat_priv,
+ tmp_neigh_node->real_bits,
+ seq_diff, set_mark);
+
+ tmp_neigh_node->real_packet_count =
+ bit_packet_count(tmp_neigh_node->real_bits);
+ }
+
+ if (need_update) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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;
+}
+
+/* copy primary address for bonding */
+static void mark_bonding_address(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ struct orig_node *orig_neigh_node,
+ struct batman_packet *batman_packet)
+
+{
+ if (batman_packet->flags & PRIMARIES_FIRST_HOP)
+ memcpy(orig_neigh_node->primary_addr,
+ orig_node->orig, ETH_ALEN);
+
+ return;
+}
+
+/* mark possible bond.candidates in the neighbor list */
+void update_bonding_candidates(struct bat_priv *bat_priv,
+ struct orig_node *orig_node)
+{
+ int candidates;
+ int interference_candidate;
+ int best_tq;
+ struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
+ struct neigh_node *first_candidate, *last_candidate;
+
+ /* update the candidates for this originator */
+ if (!orig_node->router) {
+ orig_node->bond.candidates = 0;
+ return;
+ }
+
+ best_tq = orig_node->router->tq_avg;
+
+ /* update bond.candidates */
+
+ candidates = 0;
+
+ /* mark other nodes which also received "PRIMARIES FIRST HOP" packets
+ * as "bonding partner" */
+
+ /* first, zero the list */
+ list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+ tmp_neigh_node->next_bond_candidate = NULL;
+ }
+
+ first_candidate = NULL;
+ last_candidate = NULL;
+ list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+ /* only consider if it has the same primary address ... */
+ if (memcmp(orig_node->orig,
+ tmp_neigh_node->orig_node->primary_addr,
+ ETH_ALEN) != 0)
+ continue;
+
+ /* ... and is good enough to be considered */
+ if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
+ continue;
+
+ /* check if we have another candidate with the same
+ * mac address or interface. If we do, we won't
+ * select this candidate because of possible interference. */
+
+ interference_candidate = 0;
+ list_for_each_entry(tmp_neigh_node2,
+ &orig_node->neigh_list, list) {
+
+ if (tmp_neigh_node2 == tmp_neigh_node)
+ continue;
+
+ /* we only care if the other candidate is even
+ * considered as candidate. */
+ if (!tmp_neigh_node2->next_bond_candidate)
+ continue;
+
+
+ if ((tmp_neigh_node->if_incoming ==
+ tmp_neigh_node2->if_incoming)
+ || (memcmp(tmp_neigh_node->addr,
+ tmp_neigh_node2->addr, ETH_ALEN) == 0)) {
+
+ interference_candidate = 1;
+ break;
+ }
+ }
+ /* don't care further if it is an interference candidate */
+ if (interference_candidate)
+ continue;
+
+ if (!first_candidate) {
+ first_candidate = tmp_neigh_node;
+ tmp_neigh_node->next_bond_candidate = first_candidate;
+ } else
+ tmp_neigh_node->next_bond_candidate = last_candidate;
+
+ last_candidate = tmp_neigh_node;
+
+ candidates++;
+ }
+
+ if (candidates > 0) {
+ first_candidate->next_bond_candidate = last_candidate;
+ orig_node->bond.selected = first_candidate;
+ }
+
+ orig_node->bond.candidates = candidates;
+}
+
+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 bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batman_if *batman_if;
+ struct orig_node *orig_neigh_node, *orig_node;
+ char has_directlink_flag;
+ 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;
+ uint32_t if_incoming_seqno;
+
+ /* 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)
+ */
+ if (batman_packet->packet_type != BAT_PACKET)
+ return;
+
+ /* could be changed by schedule_own_packet() */
+ if_incoming_seqno = atomic_read(&if_incoming->seqno);
+
+ has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+
+ is_single_hop_neigh = (compare_orig(ethhdr->h_source,
+ batman_packet->orig) ? 1 : 0);
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Received BATMAN packet via NB: %pM, IF: %s [%pM] "
+ "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, "
+ "TTL %d, V %d, IDF %d)\n",
+ ethhdr->h_source, if_incoming->net_dev->name,
+ if_incoming->net_dev->dev_addr, batman_packet->orig,
+ batman_packet->prev_sender, batman_packet->seqno,
+ batman_packet->tq, batman_packet->ttl, batman_packet->version,
+ has_directlink_flag);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->if_status != IF_ACTIVE)
+ continue;
+
+ if (batman_if->soft_iface != if_incoming->soft_iface)
+ continue;
+
+ 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))
+ is_my_orig = 1;
+
+ if (compare_orig(batman_packet->prev_sender,
+ batman_if->net_dev->dev_addr))
+ is_my_oldorig = 1;
+
+ if (compare_orig(ethhdr->h_source, broadcast_addr))
+ is_broadcast = 1;
+ }
+ rcu_read_unlock();
+
+ if (batman_packet->version != COMPAT_VERSION) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: incompatible batman version (%i)\n",
+ batman_packet->version);
+ return;
+ }
+
+ if (is_my_addr) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: received my own broadcast (sender: %pM"
+ ")\n",
+ ethhdr->h_source);
+ return;
+ }
+
+ if (is_broadcast) {
+ bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
+ "ignoring all packets with broadcast source addr (sender: %pM"
+ ")\n", ethhdr->h_source);
+ return;
+ }
+
+ if (is_my_orig) {
+ unsigned long *word;
+ int offset;
+
+ orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
+
+ 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);
+ }
+
+ bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
+ "originator packet from myself (via neighbor)\n");
+ return;
+ }
+
+ if (is_my_oldorig) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: ignoring all rebroadcast echos (sender: "
+ "%pM)\n", ethhdr->h_source);
+ return;
+ }
+
+ orig_node = get_orig_node(bat_priv, batman_packet->orig);
+ if (!orig_node)
+ return;
+
+ is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
+
+ if (is_duplicate == -1) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: packet within seqno protection time "
+ "(sender: %pM)\n", ethhdr->h_source);
+ return;
+ }
+
+ if (batman_packet->tq == 0) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: originator packet with tq equal 0\n");
+ 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)) &&
+ !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
+ (compare_orig(orig_node->router->addr,
+ orig_node->router->orig_node->router->addr))) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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(bat_priv, ethhdr->h_source));
+ if (!orig_neigh_node)
+ 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)) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: OGM via unknown neighbor!\n");
+ return;
+ }
+
+ is_bidirectional = is_bidirectional_neigh(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(bat_priv, orig_node, ethhdr, batman_packet,
+ if_incoming, hna_buff, hna_buff_len, is_duplicate);
+
+ mark_bonding_address(bat_priv, orig_node,
+ orig_neigh_node, batman_packet);
+ update_bonding_candidates(bat_priv, orig_node);
+
+ /* 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);
+
+ bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
+ "rebroadcast neighbor packet with direct link flag\n");
+ return;
+ }
+
+ /* multihop originator */
+ if (!is_bidirectional) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: not received via bidirectional link\n");
+ return;
+ }
+
+ if (is_duplicate) {
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Drop packet: duplicate packet received\n");
+ return;
+ }
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "Forwarding packet: rebroadcast originator packet\n");
+ schedule_forward_packet(orig_node, ethhdr, batman_packet,
+ 0, hna_buff_len, if_incoming);
+}
+
+int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ struct ethhdr *ethhdr;
+
+ /* drop packet if it has not necessary minimum size */
+ if (unlikely(!pskb_may_pull(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_broadcast_ether_addr(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* packet with broadcast sender address */
+ if (is_broadcast_ether_addr(ethhdr->h_source))
+ return NET_RX_DROP;
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, 0) < 0)
+ return NET_RX_DROP;
+
+ /* keep skb linear */
+ if (skb_linearize(skb) < 0)
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ receive_aggr_bat_packet(ethhdr,
+ skb->data,
+ skb_headlen(skb),
+ batman_if);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ kfree_skb(skb);
+ return NET_RX_SUCCESS;
+}
+
+static int recv_my_icmp_packet(struct bat_priv *bat_priv,
+ struct sk_buff *skb, size_t icmp_len)
+{
+ struct orig_node *orig_node;
+ struct icmp_packet_rr *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct batman_if *batman_if;
+ int ret;
+ uint8_t dstaddr[ETH_ALEN];
+
+ icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* add data to device queue */
+ if (icmp_packet->msg_type != ECHO_REQUEST) {
+ bat_socket_receive_packet(icmp_packet, icmp_len);
+ return NET_RX_DROP;
+ }
+
+ if (!bat_priv->primary_if)
+ return NET_RX_DROP;
+
+ /* answer echo request (ping) */
+ /* get routing information */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ compare_orig, choose_orig,
+ icmp_packet->orig));
+ ret = NET_RX_DROP;
+
+ if ((orig_node) && (orig_node->router)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+ memcpy(icmp_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ icmp_packet->msg_type = ECHO_REPLY;
+ icmp_packet->ttl = TTL;
+
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
+
+ } else
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ return ret;
+}
+
+static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
+ struct sk_buff *skb, size_t icmp_len)
+{
+ struct orig_node *orig_node;
+ struct icmp_packet *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct batman_if *batman_if;
+ int ret;
+ 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) {
+ pr_debug("Warning - can't forward icmp packet from %pM to "
+ "%pM: ttl exceeded\n", icmp_packet->orig,
+ icmp_packet->dst);
+ return NET_RX_DROP;
+ }
+
+ if (!bat_priv->primary_if)
+ return NET_RX_DROP;
+
+ /* get routing information */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
+ icmp_packet->orig));
+ ret = NET_RX_DROP;
+
+ if ((orig_node) && (orig_node->router)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet *) skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+ memcpy(icmp_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ icmp_packet->msg_type = TTL_EXCEEDED;
+ icmp_packet->ttl = TTL;
+
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
+
+ } else
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ return ret;
+}
+
+
+int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct icmp_packet_rr *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct orig_node *orig_node;
+ struct batman_if *batman_if;
+ int hdr_size = sizeof(struct icmp_packet);
+ int ret;
+ uint8_t dstaddr[ETH_ALEN];
+
+ /**
+ * we truncate all incoming icmp packets if they don't match our size
+ */
+ if (skb->len >= sizeof(struct icmp_packet_rr))
+ hdr_size = sizeof(struct icmp_packet_rr);
+
+ /* drop packet if it has not necessary minimum size */
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* packet with unicast indication but broadcast recipient */
+ if (is_broadcast_ether_addr(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* packet with broadcast sender address */
+ if (is_broadcast_ether_addr(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_rr *)skb->data;
+
+ /* add record route information if not full */
+ if ((hdr_size == sizeof(struct icmp_packet_rr)) &&
+ (icmp_packet->rr_cur < BAT_RR_LEN)) {
+ memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
+ ethhdr->h_dest, ETH_ALEN);
+ icmp_packet->rr_cur++;
+ }
+
+ /* packet for me */
+ if (is_my_mac(icmp_packet->dst))
+ return recv_my_icmp_packet(bat_priv, skb, hdr_size);
+
+ /* TTL exceeded */
+ if (icmp_packet->ttl < 2)
+ return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size);
+
+ ret = NET_RX_DROP;
+
+ /* get routing information */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
+ icmp_packet->dst));
+
+ if ((orig_node) && (orig_node->router)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* decrement ttl */
+ icmp_packet->ttl--;
+
+ /* route it */
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
+
+ } else
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ return ret;
+}
+
+/* find a suitable router for this originator, and use
+ * bonding if possible. */
+struct neigh_node *find_router(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ struct batman_if *recv_if)
+{
+ struct orig_node *primary_orig_node;
+ struct orig_node *router_orig;
+ struct neigh_node *router, *first_candidate, *best_router;
+ static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+ int bonding_enabled;
+
+ if (!orig_node)
+ return NULL;
+
+ if (!orig_node->router)
+ return NULL;
+
+ /* without bonding, the first node should
+ * always choose the default router. */
+
+ bonding_enabled = atomic_read(&bat_priv->bonding);
+
+ if ((!recv_if) && (!bonding_enabled))
+ return orig_node->router;
+
+ router_orig = orig_node->router->orig_node;
+
+ /* if we have something in the primary_addr, we can search
+ * for a potential bonding candidate. */
+ if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0)
+ return orig_node->router;
+
+ /* find the orig_node which has the primary interface. might
+ * even be the same as our router_orig in many cases */
+
+ if (memcmp(router_orig->primary_addr,
+ router_orig->orig, ETH_ALEN) == 0) {
+ primary_orig_node = router_orig;
+ } else {
+ primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig,
+ choose_orig,
+ router_orig->primary_addr);
+
+ if (!primary_orig_node)
+ return orig_node->router;
+ }
+
+ /* with less than 2 candidates, we can't do any
+ * bonding and prefer the original router. */
+
+ if (primary_orig_node->bond.candidates < 2)
+ return orig_node->router;
+
+
+ /* all nodes between should choose a candidate which
+ * is is not on the interface where the packet came
+ * in. */
+ first_candidate = primary_orig_node->bond.selected;
+ router = first_candidate;
+
+ if (bonding_enabled) {
+ /* in the bonding case, send the packets in a round
+ * robin fashion over the remaining interfaces. */
+ do {
+ /* recv_if == NULL on the first node. */
+ if (router->if_incoming != recv_if)
+ break;
+
+ router = router->next_bond_candidate;
+ } while (router != first_candidate);
+
+ primary_orig_node->bond.selected = router->next_bond_candidate;
+
+ } else {
+ /* if bonding is disabled, use the best of the
+ * remaining candidates which are not using
+ * this interface. */
+ best_router = first_candidate;
+
+ do {
+ /* recv_if == NULL on the first node. */
+ if ((router->if_incoming != recv_if) &&
+ (router->tq_avg > best_router->tq_avg))
+ best_router = router;
+
+ router = router->next_bond_candidate;
+ } while (router != first_candidate);
+
+ router = best_router;
+ }
+
+ return router;
+}
+
+static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
+{
+ struct ethhdr *ethhdr;
+
+ /* drop packet if it has not necessary minimum size */
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return -1;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* packet with unicast indication but broadcast recipient */
+ if (is_broadcast_ether_addr(ethhdr->h_dest))
+ return -1;
+
+ /* packet with broadcast sender address */
+ if (is_broadcast_ether_addr(ethhdr->h_source))
+ return -1;
+
+ /* not for me */
+ if (!is_my_mac(ethhdr->h_dest))
+ return -1;
+
+ return 0;
+}
+
+int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
+ int hdr_size)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct orig_node *orig_node;
+ struct neigh_node *router;
+ struct batman_if *batman_if;
+ uint8_t dstaddr[ETH_ALEN];
+ struct unicast_packet *unicast_packet;
+ struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ int ret;
+ struct sk_buff *new_skb;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ /* TTL exceeded */
+ if (unicast_packet->ttl < 2) {
+ pr_debug("Warning - can't forward unicast packet from %pM to "
+ "%pM: ttl exceeded\n", ethhdr->h_source,
+ unicast_packet->dest);
+ return NET_RX_DROP;
+ }
+
+ /* get routing information */
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
+ unicast_packet->dest));
+
+ router = find_router(bat_priv, orig_node, recv_if);
+
+ if (!router) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return NET_RX_DROP;
+ }
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+
+ batman_if = router->if_incoming;
+ memcpy(dstaddr, router->addr, ETH_ALEN);
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ if (unicast_packet->packet_type == BAT_UNICAST &&
+ atomic_read(&bat_priv->fragmentation) &&
+ skb->len > batman_if->net_dev->mtu)
+ return frag_send_skb(skb, bat_priv, batman_if,
+ dstaddr);
+
+ if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
+ 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) {
+
+ ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
+
+ if (ret == NET_RX_DROP)
+ return NET_RX_DROP;
+
+ /* packet was buffered for late merge */
+ if (!new_skb)
+ return NET_RX_SUCCESS;
+
+ skb = new_skb;
+ unicast_packet = (struct unicast_packet *)skb->data;
+ }
+
+ /* decrement ttl */
+ unicast_packet->ttl--;
+
+ /* route it */
+ send_skb_packet(skb, batman_if, dstaddr);
+
+ return NET_RX_SUCCESS;
+}
+
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct unicast_packet *unicast_packet;
+ int hdr_size = sizeof(struct unicast_packet);
+
+ if (check_unicast_packet(skb, hdr_size) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ /* packet for me */
+ if (is_my_mac(unicast_packet->dest)) {
+ interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
+ return NET_RX_SUCCESS;
+ }
+
+ return route_unicast_packet(skb, recv_if, hdr_size);
+}
+
+int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct unicast_frag_packet *unicast_packet;
+ int hdr_size = sizeof(struct unicast_frag_packet);
+ struct sk_buff *new_skb = NULL;
+ int ret;
+
+ if (check_unicast_packet(skb, hdr_size) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_frag_packet *)skb->data;
+
+ /* packet for me */
+ if (is_my_mac(unicast_packet->dest)) {
+
+ ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
+
+ if (ret == NET_RX_DROP)
+ return NET_RX_DROP;
+
+ /* packet was buffered for late merge */
+ if (!new_skb)
+ return NET_RX_SUCCESS;
+
+ interface_rx(recv_if->soft_iface, new_skb, recv_if,
+ sizeof(struct unicast_packet));
+ return NET_RX_SUCCESS;
+ }
+
+ return route_unicast_packet(skb, recv_if, hdr_size);
+}
+
+
+int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct orig_node *orig_node;
+ struct bcast_packet *bcast_packet;
+ struct ethhdr *ethhdr;
+ int hdr_size = sizeof(struct bcast_packet);
+ int32_t seq_diff;
+
+ /* drop packet if it has not necessary minimum size */
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* packet with broadcast indication but unicast recipient */
+ if (!is_broadcast_ether_addr(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* packet with broadcast sender address */
+ if (is_broadcast_ether_addr(ethhdr->h_source))
+ return NET_RX_DROP;
+
+ /* ignore broadcasts sent by myself */
+ if (is_my_mac(ethhdr->h_source))
+ return NET_RX_DROP;
+
+ bcast_packet = (struct bcast_packet *)skb->data;
+
+ /* ignore broadcasts originated by myself */
+ if (is_my_mac(bcast_packet->orig))
+ return NET_RX_DROP;
+
+ if (bcast_packet->ttl < 2)
+ return NET_RX_DROP;
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
+ bcast_packet->orig));
+
+ if (!orig_node) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return NET_RX_DROP;
+ }
+
+ /* check whether the packet is a duplicate */
+ if (get_bit_status(orig_node->bcast_bits,
+ orig_node->last_bcast_seqno,
+ ntohl(bcast_packet->seqno))) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return NET_RX_DROP;
+ }
+
+ seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
+
+ /* check whether the packet is old and the host just restarted. */
+ if (window_protected(bat_priv, seq_diff,
+ &orig_node->bcast_seqno_reset)) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return NET_RX_DROP;
+ }
+
+ /* mark broadcast in flood history, update window position
+ * if required. */
+ if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
+ orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ /* rebroadcast packet */
+ add_bcast_packet_to_list(bat_priv, skb);
+
+ /* broadcast for me */
+ interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
+
+ return NET_RX_SUCCESS;
+}
+
+int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct vis_packet *vis_packet;
+ struct ethhdr *ethhdr;
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ int hdr_size = sizeof(struct vis_packet);
+
+ /* keep skb linear */
+ if (skb_linearize(skb) < 0)
+ return NET_RX_DROP;
+
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return NET_RX_DROP;
+
+ vis_packet = (struct vis_packet *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* not for me */
+ if (!is_my_mac(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* 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;
+
+ switch (vis_packet->vis_type) {
+ case VIS_TYPE_SERVER_SYNC:
+ receive_server_sync_packet(bat_priv, vis_packet,
+ skb_headlen(skb));
+ break;
+
+ case VIS_TYPE_CLIENT_UPDATE:
+ receive_client_update_packet(bat_priv, vis_packet,
+ skb_headlen(skb));
+ break;
+
+ default: /* ignore unknown packet */
+ break;
+ }
+
+ /* We take a copy of the data in the packet, so we should
+ always free the skbuf. */
+ return NET_RX_DROP;
+}
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
new file mode 100644
index 000000000000..f108f230bfdb
--- /dev/null
+++ b/net/batman-adv/routing.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_ROUTING_H_
+#define _NET_BATMAN_ADV_ROUTING_H_
+
+#include "types.h"
+
+void slide_own_bcast_window(struct batman_if *batman_if);
+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 bat_priv *bat_priv, struct orig_node *orig_node,
+ struct neigh_node *neigh_node, unsigned char *hna_buff,
+ int hna_buff_len);
+int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
+ int hdr_size);
+int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if);
+struct neigh_node *find_router(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, struct batman_if *recv_if);
+void update_bonding_candidates(struct bat_priv *bat_priv,
+ struct orig_node *orig_node);
+
+#endif /* _NET_BATMAN_ADV_ROUTING_H_ */
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
new file mode 100644
index 000000000000..b89b9f7709ae
--- /dev/null
+++ b/net/batman-adv/send.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2007-2010 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 "send.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 "gateway_common.h"
+#include "originator.h"
+
+static void send_outstanding_bcast_packet(struct work_struct *work);
+
+/* apply hop penalty for a normal link */
+static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv)
+{
+ int hop_penalty = atomic_read(&bat_priv->hop_penalty);
+ return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);
+}
+
+/* when do we schedule our own packet to be sent */
+static unsigned long own_send_time(struct bat_priv *bat_priv)
+{
+ return jiffies + msecs_to_jiffies(
+ atomic_read(&bat_priv->orig_interval) -
+ JITTER + (random32() % 2*JITTER));
+}
+
+/* when do we schedule a forwarded packet to be sent */
+static unsigned long forward_send_time(struct bat_priv *bat_priv)
+{
+ return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
+}
+
+/* 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;
+
+ if (batman_if->if_status != IF_ACTIVE)
+ goto send_skb_err;
+
+ if (unlikely(!batman_if->net_dev))
+ goto send_skb_err;
+
+ if (!(batman_if->net_dev->flags & IFF_UP)) {
+ pr_warning("Interface %s is not up - can't send packet via "
+ "that interface!\n", batman_if->net_dev->name);
+ goto send_skb_err;
+ }
+
+ /* push to the ethernet header. */
+ if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0)
+ goto send_skb_err;
+
+ skb_reset_mac_header(skb);
+
+ 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_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. */
+
+ return dev_queue_xmit(skb);
+send_skb_err:
+ kfree_skb(skb);
+ return NET_XMIT_DROP;
+}
+
+/* Send a packet to a given interface */
+static void send_packet_to_if(struct forw_packet *forw_packet,
+ struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ char *fwd_str;
+ uint8_t packet_num;
+ int16_t buff_pos;
+ struct batman_packet *batman_packet;
+ struct sk_buff *skb;
+
+ if (batman_if->if_status != IF_ACTIVE)
+ return;
+
+ packet_num = 0;
+ buff_pos = 0;
+ batman_packet = (struct batman_packet *)forw_packet->skb->data;
+
+ /* adjust all flags and log packets */
+ while (aggregated_packet(buff_pos,
+ forw_packet->packet_len,
+ batman_packet->num_hna)) {
+
+ /* we might have aggregated direct link packets with an
+ * ordinary base packet */
+ if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
+ (forw_packet->if_incoming == batman_if))
+ batman_packet->flags |= DIRECTLINK;
+ else
+ batman_packet->flags &= ~DIRECTLINK;
+
+ fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
+ "Sending own" :
+ "Forwarding"));
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
+ " IDF %s) on interface %s [%pM]\n",
+ fwd_str, (packet_num > 0 ? "aggregated " : ""),
+ batman_packet->orig, ntohl(batman_packet->seqno),
+ batman_packet->tq, batman_packet->ttl,
+ (batman_packet->flags & DIRECTLINK ?
+ "on" : "off"),
+ batman_if->net_dev->name, batman_if->net_dev->dev_addr);
+
+ buff_pos += sizeof(struct batman_packet) +
+ (batman_packet->num_hna * ETH_ALEN);
+ packet_num++;
+ batman_packet = (struct batman_packet *)
+ (forw_packet->skb->data + buff_pos);
+ }
+
+ /* create clone because function is called more than once */
+ skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, broadcast_addr);
+}
+
+/* send a batman packet */
+static void send_packet(struct forw_packet *forw_packet)
+{
+ struct batman_if *batman_if;
+ struct net_device *soft_iface;
+ struct bat_priv *bat_priv;
+ struct batman_packet *batman_packet =
+ (struct batman_packet *)(forw_packet->skb->data);
+ unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+
+ if (!forw_packet->if_incoming) {
+ pr_err("Error - can't forward packet: incoming iface not "
+ "specified\n");
+ return;
+ }
+
+ soft_iface = forw_packet->if_incoming->soft_iface;
+ bat_priv = netdev_priv(soft_iface);
+
+ if (forw_packet->if_incoming->if_status != IF_ACTIVE)
+ return;
+
+ /* 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 ? */
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "%s packet (originator %pM, seqno %d, TTL %d) "
+ "on interface %s [%pM]\n",
+ (forw_packet->own ? "Sending own" : "Forwarding"),
+ batman_packet->orig, ntohl(batman_packet->seqno),
+ batman_packet->ttl,
+ forw_packet->if_incoming->net_dev->name,
+ forw_packet->if_incoming->net_dev->dev_addr);
+
+ /* skb is only used once and than forw_packet is free'd */
+ send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
+ broadcast_addr);
+ forw_packet->skb = NULL;
+
+ return;
+ }
+
+ /* broadcast on every interface */
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
+ send_packet_to_if(forw_packet, batman_if);
+ }
+ rcu_read_unlock();
+}
+
+static void rebuild_batman_packet(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
+{
+ int new_len;
+ unsigned char *new_buff;
+ struct batman_packet *batman_packet;
+
+ new_len = sizeof(struct batman_packet) +
+ (bat_priv->num_local_hna * ETH_ALEN);
+ new_buff = kmalloc(new_len, GFP_ATOMIC);
+
+ /* keep old buffer if kmalloc should fail */
+ if (new_buff) {
+ memcpy(new_buff, batman_if->packet_buff,
+ sizeof(struct batman_packet));
+ batman_packet = (struct batman_packet *)new_buff;
+
+ batman_packet->num_hna = hna_local_fill_buffer(bat_priv,
+ new_buff + sizeof(struct batman_packet),
+ new_len - sizeof(struct batman_packet));
+
+ kfree(batman_if->packet_buff);
+ batman_if->packet_buff = new_buff;
+ batman_if->packet_len = new_len;
+ }
+}
+
+void schedule_own_packet(struct batman_if *batman_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
+ unsigned long send_time;
+ struct batman_packet *batman_packet;
+ int vis_server;
+
+ if ((batman_if->if_status == IF_NOT_IN_USE) ||
+ (batman_if->if_status == IF_TO_BE_REMOVED))
+ return;
+
+ vis_server = atomic_read(&bat_priv->vis_mode);
+
+ /**
+ * the interface gets activated here to avoid race conditions between
+ * the moment of activating the interface in
+ * hardif_activate_interface() where the originator mac is set and
+ * outdated packets (especially uninitialized mac addresses) in the
+ * packet queue
+ */
+ if (batman_if->if_status == IF_TO_BE_ACTIVATED)
+ batman_if->if_status = IF_ACTIVE;
+
+ /* if local hna has changed and interface is a primary interface */
+ if ((atomic_read(&bat_priv->hna_local_changed)) &&
+ (batman_if == bat_priv->primary_if))
+ rebuild_batman_packet(bat_priv, batman_if);
+
+ /**
+ * NOTE: packet_buff might just have been re-allocated in
+ * rebuild_batman_packet()
+ */
+ batman_packet = (struct batman_packet *)batman_if->packet_buff;
+
+ /* change sequence number to network order */
+ batman_packet->seqno =
+ htonl((uint32_t)atomic_read(&batman_if->seqno));
+
+ if (vis_server == VIS_TYPE_SERVER_SYNC)
+ batman_packet->flags |= VIS_SERVER;
+ else
+ batman_packet->flags &= ~VIS_SERVER;
+
+ if ((batman_if == bat_priv->primary_if) &&
+ (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
+ batman_packet->gw_flags =
+ (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
+ else
+ batman_packet->gw_flags = 0;
+
+ atomic_inc(&batman_if->seqno);
+
+ slide_own_bcast_window(batman_if);
+ send_time = own_send_time(bat_priv);
+ add_bat_packet_to_list(bat_priv,
+ batman_if->packet_buff,
+ batman_if->packet_len,
+ batman_if, 1, send_time);
+}
+
+void schedule_forward_packet(struct orig_node *orig_node,
+ struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ uint8_t directlink, int hna_buff_len,
+ struct batman_if *if_incoming)
+{
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ unsigned char in_tq, in_ttl, tq_avg = 0;
+ unsigned long send_time;
+
+ if (batman_packet->ttl <= 1) {
+ bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
+ return;
+ }
+
+ in_tq = batman_packet->tq;
+ in_ttl = batman_packet->ttl;
+
+ batman_packet->ttl--;
+ memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
+
+ /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
+ * of our best tq value */
+ if ((orig_node->router) && (orig_node->router->tq_avg != 0)) {
+
+ /* rebroadcast ogm of best ranking neighbor as is */
+ if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) {
+ batman_packet->tq = orig_node->router->tq_avg;
+
+ if (orig_node->router->last_ttl)
+ batman_packet->ttl = orig_node->router->last_ttl
+ - 1;
+ }
+
+ tq_avg = orig_node->router->tq_avg;
+ }
+
+ /* apply hop penalty */
+ batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv);
+
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "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 = htonl(batman_packet->seqno);
+
+ /* switch of primaries first hop flag when forwarding */
+ batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
+ if (directlink)
+ batman_packet->flags |= DIRECTLINK;
+ else
+ batman_packet->flags &= ~DIRECTLINK;
+
+ send_time = forward_send_time(bat_priv);
+ add_bat_packet_to_list(bat_priv,
+ (unsigned char *)batman_packet,
+ sizeof(struct batman_packet) + hna_buff_len,
+ if_incoming, 0, send_time);
+}
+
+static void forw_packet_free(struct forw_packet *forw_packet)
+{
+ if (forw_packet->skb)
+ kfree_skb(forw_packet->skb);
+ kfree(forw_packet);
+}
+
+static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
+ struct forw_packet *forw_packet,
+ unsigned long send_time)
+{
+ INIT_HLIST_NODE(&forw_packet->list);
+
+ /* add new packet to packet list */
+ spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+ hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list);
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+
+ /* start timer for this packet */
+ INIT_DELAYED_WORK(&forw_packet->delayed_work,
+ send_outstanding_bcast_packet);
+ queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work,
+ send_time);
+}
+
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+/* add a broadcast packet to the queue and setup timers. broadcast packets
+ * are sent multiple times to increase probability for beeing received.
+ *
+ * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on
+ * errors.
+ *
+ * The skb is not consumed, so the caller should make sure that the
+ * skb is freed. */
+int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ struct forw_packet *forw_packet;
+ struct bcast_packet *bcast_packet;
+
+ if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
+ bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
+ goto out;
+ }
+
+ if (!bat_priv->primary_if)
+ goto out;
+
+ forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+
+ if (!forw_packet)
+ goto out_and_inc;
+
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ goto packet_free;
+
+ /* as we have a copy now, it is safe to decrease the TTL */
+ bcast_packet = (struct bcast_packet *)skb->data;
+ bcast_packet->ttl--;
+
+ skb_reset_mac_header(skb);
+
+ forw_packet->skb = skb;
+ forw_packet->if_incoming = bat_priv->primary_if;
+
+ /* how often did we send the bcast packet ? */
+ forw_packet->num_packets = 0;
+
+ _add_bcast_packet_to_list(bat_priv, forw_packet, 1);
+ return NETDEV_TX_OK;
+
+packet_free:
+ kfree(forw_packet);
+out_and_inc:
+ atomic_inc(&bat_priv->bcast_queue_left);
+out:
+ return NETDEV_TX_BUSY;
+}
+
+static void send_outstanding_bcast_packet(struct work_struct *work)
+{
+ struct batman_if *batman_if;
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct forw_packet *forw_packet =
+ container_of(delayed_work, struct forw_packet, delayed_work);
+ struct sk_buff *skb1;
+ struct net_device *soft_iface = forw_packet->if_incoming->soft_iface;
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+
+ spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+ hlist_del(&forw_packet->list);
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+
+ if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
+ goto out;
+
+ /* rebroadcast packet */
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
+ /* send a copy of the saved skb */
+ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
+ if (skb1)
+ send_skb_packet(skb1, batman_if, broadcast_addr);
+ }
+ rcu_read_unlock();
+
+ forw_packet->num_packets++;
+
+ /* if we still have some more bcasts to send */
+ if (forw_packet->num_packets < 3) {
+ _add_bcast_packet_to_list(bat_priv, forw_packet,
+ ((5 * HZ) / 1000));
+ return;
+ }
+
+out:
+ forw_packet_free(forw_packet);
+ atomic_inc(&bat_priv->bcast_queue_left);
+}
+
+void send_outstanding_bat_packet(struct work_struct *work)
+{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct forw_packet *forw_packet =
+ container_of(delayed_work, struct forw_packet, delayed_work);
+ struct bat_priv *bat_priv;
+
+ bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
+ spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ hlist_del(&forw_packet->list);
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
+ goto out;
+
+ send_packet(forw_packet);
+
+ /**
+ * we have to have at least one packet in the queue
+ * to determine the queues wake up time unless we are
+ * shutting down
+ */
+ if (forw_packet->own)
+ schedule_own_packet(forw_packet->if_incoming);
+
+out:
+ /* don't count own packet */
+ if (!forw_packet->own)
+ atomic_inc(&bat_priv->batman_queue_left);
+
+ forw_packet_free(forw_packet);
+}
+
+void purge_outstanding_packets(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
+{
+ struct forw_packet *forw_packet;
+ struct hlist_node *tmp_node, *safe_tmp_node;
+
+ if (batman_if)
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "purge_outstanding_packets(): %s\n",
+ batman_if->net_dev->name);
+ else
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "purge_outstanding_packets()\n");
+
+ /* free bcast list */
+ spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+ &bat_priv->forw_bcast_list, list) {
+
+ /**
+ * if purge_outstanding_packets() was called with an argmument
+ * we delete only packets belonging to the given interface
+ */
+ if ((batman_if) &&
+ (forw_packet->if_incoming != batman_if))
+ continue;
+
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+
+ /**
+ * 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_bh(&bat_priv->forw_bcast_list_lock);
+ }
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+
+ /* free batman packet list */
+ spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+ &bat_priv->forw_bat_list, list) {
+
+ /**
+ * if purge_outstanding_packets() was called with an argmument
+ * we delete only packets belonging to the given interface
+ */
+ if ((batman_if) &&
+ (forw_packet->if_incoming != batman_if))
+ continue;
+
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ /**
+ * 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_bh(&bat_priv->forw_bat_list_lock);
+ }
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+}
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
new file mode 100644
index 000000000000..c4cefa8e4f85
--- /dev/null
+++ b/net/batman-adv/send.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_SEND_H_
+#define _NET_BATMAN_ADV_SEND_H_
+
+#include "types.h"
+
+int send_skb_packet(struct sk_buff *skb,
+ struct batman_if *batman_if,
+ uint8_t *dst_addr);
+void schedule_own_packet(struct batman_if *batman_if);
+void schedule_forward_packet(struct orig_node *orig_node,
+ struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ uint8_t directlink, int hna_buff_len,
+ struct batman_if *if_outgoing);
+int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
+void send_outstanding_bat_packet(struct work_struct *work);
+void purge_outstanding_packets(struct bat_priv *bat_priv,
+ struct batman_if *batman_if);
+
+#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
new file mode 100644
index 000000000000..e89ede192ed0
--- /dev/null
+++ b/net/batman-adv/soft-interface.c
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2007-2010 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 "soft-interface.h"
+#include "hard-interface.h"
+#include "routing.h"
+#include "send.h"
+#include "bat_debugfs.h"
+#include "translation-table.h"
+#include "types.h"
+#include "hash.h"
+#include "gateway_common.h"
+#include "gateway_client.h"
+#include "send.h"
+#include "bat_sysfs.h"
+#include <linux/slab.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include "unicast.h"
+#include "routing.h"
+
+
+static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static void bat_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info);
+static u32 bat_get_msglevel(struct net_device *dev);
+static void bat_set_msglevel(struct net_device *dev, u32 value);
+static u32 bat_get_link(struct net_device *dev);
+static u32 bat_get_rx_csum(struct net_device *dev);
+static int bat_set_rx_csum(struct net_device *dev, u32 data);
+
+static const struct ethtool_ops bat_ethtool_ops = {
+ .get_settings = bat_get_settings,
+ .get_drvinfo = bat_get_drvinfo,
+ .get_msglevel = bat_get_msglevel,
+ .set_msglevel = bat_set_msglevel,
+ .get_link = bat_get_link,
+ .get_rx_csum = bat_get_rx_csum,
+ .set_rx_csum = bat_set_rx_csum
+};
+
+int my_skb_head_push(struct sk_buff *skb, unsigned int len)
+{
+ int result;
+
+ /**
+ * TODO: We must check if we can release all references to non-payload
+ * data using skb_header_release in our skbs to allow skb_cow_header to
+ * work optimally. This means that those skbs are not allowed to read
+ * or write any data which is before the current position of skb->data
+ * after that call and thus allow other skbs with the same data buffer
+ * to write freely in that area.
+ */
+ result = skb_cow_head(skb, len);
+ if (result < 0)
+ return result;
+
+ skb_push(skb, len);
+ return 0;
+}
+
+static void softif_neigh_free_ref(struct kref *refcount)
+{
+ struct softif_neigh *softif_neigh;
+
+ softif_neigh = container_of(refcount, struct softif_neigh, refcount);
+ kfree(softif_neigh);
+}
+
+static void softif_neigh_free_rcu(struct rcu_head *rcu)
+{
+ struct softif_neigh *softif_neigh;
+
+ softif_neigh = container_of(rcu, struct softif_neigh, rcu);
+ kref_put(&softif_neigh->refcount, softif_neigh_free_ref);
+}
+
+void softif_neigh_purge(struct bat_priv *bat_priv)
+{
+ struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+ struct hlist_node *node, *node_tmp;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+
+ hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
+ &bat_priv->softif_neigh_list, list) {
+
+ if ((!time_after(jiffies, softif_neigh->last_seen +
+ msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
+ (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
+ continue;
+
+ hlist_del_rcu(&softif_neigh->list);
+
+ if (bat_priv->softif_neigh == softif_neigh) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Current mesh exit point '%pM' vanished "
+ "(vid: %d).\n",
+ softif_neigh->addr, softif_neigh->vid);
+ softif_neigh_tmp = bat_priv->softif_neigh;
+ bat_priv->softif_neigh = NULL;
+ kref_put(&softif_neigh_tmp->refcount,
+ softif_neigh_free_ref);
+ }
+
+ call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu);
+ }
+
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+}
+
+static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
+ uint8_t *addr, short vid)
+{
+ struct softif_neigh *softif_neigh;
+ struct hlist_node *node;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh, node,
+ &bat_priv->softif_neigh_list, list) {
+ if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0)
+ continue;
+
+ if (softif_neigh->vid != vid)
+ continue;
+
+ softif_neigh->last_seen = jiffies;
+ goto found;
+ }
+
+ softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC);
+ if (!softif_neigh)
+ goto out;
+
+ memcpy(softif_neigh->addr, addr, ETH_ALEN);
+ softif_neigh->vid = vid;
+ softif_neigh->last_seen = jiffies;
+ kref_init(&softif_neigh->refcount);
+
+ INIT_HLIST_NODE(&softif_neigh->list);
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+ hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list);
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+found:
+ kref_get(&softif_neigh->refcount);
+out:
+ rcu_read_unlock();
+ return softif_neigh;
+}
+
+int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct softif_neigh *softif_neigh;
+ struct hlist_node *node;
+ size_t buf_size, pos;
+ char *buff;
+
+ if (!bat_priv->primary_if) {
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ }
+
+ seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
+
+ buf_size = 1;
+ /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh, node,
+ &bat_priv->softif_neigh_list, list)
+ buf_size += 30;
+ rcu_read_unlock();
+
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff)
+ return -ENOMEM;
+
+ buff[0] = '\0';
+ pos = 0;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh, node,
+ &bat_priv->softif_neigh_list, list) {
+ pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n",
+ bat_priv->softif_neigh == softif_neigh
+ ? "=>" : " ", softif_neigh->addr,
+ softif_neigh->vid);
+ }
+ rcu_read_unlock();
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+ return 0;
+}
+
+static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
+ short vid)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+ struct batman_packet *batman_packet;
+ struct softif_neigh *softif_neigh, *softif_neigh_tmp;
+
+ if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
+ batman_packet = (struct batman_packet *)
+ (skb->data + ETH_HLEN + VLAN_HLEN);
+ else
+ batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
+
+ if (batman_packet->version != COMPAT_VERSION)
+ goto err;
+
+ if (batman_packet->packet_type != BAT_PACKET)
+ goto err;
+
+ if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
+ goto err;
+
+ if (is_my_mac(batman_packet->orig))
+ goto err;
+
+ softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
+
+ if (!softif_neigh)
+ goto err;
+
+ if (bat_priv->softif_neigh == softif_neigh)
+ goto out;
+
+ /* we got a neighbor but its mac is 'bigger' than ours */
+ if (memcmp(bat_priv->primary_if->net_dev->dev_addr,
+ softif_neigh->addr, ETH_ALEN) < 0)
+ goto out;
+
+ /* switch to new 'smallest neighbor' */
+ if ((bat_priv->softif_neigh) &&
+ (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr,
+ ETH_ALEN) < 0)) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Changing mesh exit point from %pM (vid: %d) "
+ "to %pM (vid: %d).\n",
+ bat_priv->softif_neigh->addr,
+ bat_priv->softif_neigh->vid,
+ softif_neigh->addr, softif_neigh->vid);
+ softif_neigh_tmp = bat_priv->softif_neigh;
+ bat_priv->softif_neigh = softif_neigh;
+ kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref);
+ /* we need to hold the additional reference */
+ goto err;
+ }
+
+ /* close own batX device and use softif_neigh as exit node */
+ if ((!bat_priv->softif_neigh) &&
+ (memcmp(softif_neigh->addr,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Setting mesh exit point to %pM (vid: %d).\n",
+ softif_neigh->addr, softif_neigh->vid);
+ bat_priv->softif_neigh = softif_neigh;
+ /* we need to hold the additional reference */
+ goto err;
+ }
+
+out:
+ kref_put(&softif_neigh->refcount, softif_neigh_free_ref);
+err:
+ kfree_skb(skb);
+ return;
+}
+
+static int interface_open(struct net_device *dev)
+{
+ netif_start_queue(dev);
+ return 0;
+}
+
+static int interface_release(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static struct net_device_stats *interface_stats(struct net_device *dev)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ return &bat_priv->stats;
+}
+
+static int interface_set_mac_addr(struct net_device *dev, void *p)
+{
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ /* only modify hna-table if it has been initialised before */
+ if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
+ hna_local_remove(bat_priv, dev->dev_addr,
+ "mac address changed");
+ hna_local_add(dev, addr->sa_data);
+ }
+
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ return 0;
+}
+
+static int interface_change_mtu(struct net_device *dev, int new_mtu)
+{
+ /* check ranges */
+ if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev)))
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
+{
+ struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct bcast_packet *bcast_packet;
+ struct vlan_ethhdr *vhdr;
+ int data_len = skb->len, ret;
+ short vid = -1;
+ bool do_bcast = false;
+
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
+ goto dropped;
+
+ soft_iface->trans_start = jiffies;
+
+ switch (ntohs(ethhdr->h_proto)) {
+ case ETH_P_8021Q:
+ vhdr = (struct vlan_ethhdr *)skb->data;
+ vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+
+ if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN)
+ break;
+
+ /* fall through */
+ case ETH_P_BATMAN:
+ softif_batman_recv(skb, soft_iface, vid);
+ goto end;
+ }
+
+ /**
+ * if we have a another chosen mesh exit node in range
+ * it will transport the packets to the mesh
+ */
+ if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid))
+ goto dropped;
+
+ /* TODO: check this for locks */
+ hna_local_add(soft_iface, ethhdr->h_source);
+
+ if (is_multicast_ether_addr(ethhdr->h_dest)) {
+ ret = gw_is_target(bat_priv, skb);
+
+ if (ret < 0)
+ goto dropped;
+
+ if (ret == 0)
+ do_bcast = true;
+ }
+
+ /* ethernet packet should be broadcasted */
+ if (do_bcast) {
+ if (!bat_priv->primary_if)
+ goto dropped;
+
+ if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
+ goto dropped;
+
+ bcast_packet = (struct bcast_packet *)skb->data;
+ bcast_packet->version = COMPAT_VERSION;
+ bcast_packet->ttl = TTL;
+
+ /* batman packet type: broadcast */
+ bcast_packet->packet_type = BAT_BCAST;
+
+ /* hw address of first interface is the orig mac because only
+ * this mac is known throughout the mesh */
+ memcpy(bcast_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+
+ /* set broadcast sequence number */
+ bcast_packet->seqno =
+ htonl(atomic_inc_return(&bat_priv->bcast_seqno));
+
+ add_bcast_packet_to_list(bat_priv, skb);
+
+ /* a copy is stored in the bcast list, therefore removing
+ * the original skb. */
+ kfree_skb(skb);
+
+ /* unicast packet */
+ } else {
+ ret = unicast_send_skb(skb, bat_priv);
+ if (ret != 0)
+ goto dropped_freed;
+ }
+
+ bat_priv->stats.tx_packets++;
+ bat_priv->stats.tx_bytes += data_len;
+ goto end;
+
+dropped:
+ kfree_skb(skb);
+dropped_freed:
+ bat_priv->stats.tx_dropped++;
+end:
+ return NETDEV_TX_OK;
+}
+
+void interface_rx(struct net_device *soft_iface,
+ struct sk_buff *skb, struct batman_if *recv_if,
+ int hdr_size)
+{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct unicast_packet *unicast_packet;
+ struct ethhdr *ethhdr;
+ struct vlan_ethhdr *vhdr;
+ short vid = -1;
+ int ret;
+
+ /* check if enough space is available for pulling, and pull */
+ if (!pskb_may_pull(skb, hdr_size))
+ goto dropped;
+
+ skb_pull_rcsum(skb, hdr_size);
+ skb_reset_mac_header(skb);
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ switch (ntohs(ethhdr->h_proto)) {
+ case ETH_P_8021Q:
+ vhdr = (struct vlan_ethhdr *)skb->data;
+ vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+
+ if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN)
+ break;
+
+ /* fall through */
+ case ETH_P_BATMAN:
+ goto dropped;
+ }
+
+ /**
+ * if we have a another chosen mesh exit node in range
+ * it will transport the packets to the non-mesh network
+ */
+ if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) {
+ skb_push(skb, hdr_size);
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ if ((unicast_packet->packet_type != BAT_UNICAST) &&
+ (unicast_packet->packet_type != BAT_UNICAST_FRAG))
+ goto dropped;
+
+ skb_reset_mac_header(skb);
+
+ memcpy(unicast_packet->dest,
+ bat_priv->softif_neigh->addr, ETH_ALEN);
+ ret = route_unicast_packet(skb, recv_if, hdr_size);
+ if (ret == NET_RX_DROP)
+ goto dropped;
+
+ goto out;
+ }
+
+ /* skb->dev & skb->pkt_type are set here */
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto dropped;
+ skb->protocol = eth_type_trans(skb, soft_iface);
+
+ /* 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;*/
+
+ bat_priv->stats.rx_packets++;
+ bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
+
+ soft_iface->last_rx = jiffies;
+
+ netif_rx(skb);
+ return;
+
+dropped:
+ kfree_skb(skb);
+out:
+ return;
+}
+
+#ifdef HAVE_NET_DEVICE_OPS
+static const struct net_device_ops bat_netdev_ops = {
+ .ndo_open = interface_open,
+ .ndo_stop = interface_release,
+ .ndo_get_stats = interface_stats,
+ .ndo_set_mac_address = interface_set_mac_addr,
+ .ndo_change_mtu = interface_change_mtu,
+ .ndo_start_xmit = interface_tx,
+ .ndo_validate_addr = eth_validate_addr
+};
+#endif
+
+static void interface_setup(struct net_device *dev)
+{
+ struct bat_priv *priv = netdev_priv(dev);
+ char dev_addr[ETH_ALEN];
+
+ ether_setup(dev);
+
+#ifdef HAVE_NET_DEVICE_OPS
+ dev->netdev_ops = &bat_netdev_ops;
+#else
+ dev->open = interface_open;
+ dev->stop = interface_release;
+ dev->get_stats = interface_stats;
+ dev->set_mac_address = interface_set_mac_addr;
+ dev->change_mtu = interface_change_mtu;
+ dev->hard_start_xmit = interface_tx;
+#endif
+ dev->destructor = free_netdev;
+
+ /**
+ * can't call min_mtu, because the needed variables
+ * have not been initialized yet
+ */
+ dev->mtu = ETH_DATA_LEN;
+ dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
+ * skbuff for our header */
+
+ /* generate random address */
+ random_ether_addr(dev_addr);
+ memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
+
+ SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
+
+ memset(priv, 0, sizeof(struct bat_priv));
+}
+
+struct net_device *softif_create(char *name)
+{
+ struct net_device *soft_iface;
+ struct bat_priv *bat_priv;
+ int ret;
+
+ soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
+ interface_setup);
+
+ if (!soft_iface) {
+ pr_err("Unable to allocate the batman interface: %s\n", name);
+ goto out;
+ }
+
+ ret = register_netdev(soft_iface);
+ if (ret < 0) {
+ pr_err("Unable to register the batman interface '%s': %i\n",
+ name, ret);
+ goto free_soft_iface;
+ }
+
+ bat_priv = netdev_priv(soft_iface);
+
+ atomic_set(&bat_priv->aggregated_ogms, 1);
+ atomic_set(&bat_priv->bonding, 0);
+ atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
+ atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
+ atomic_set(&bat_priv->gw_sel_class, 20);
+ atomic_set(&bat_priv->gw_bandwidth, 41);
+ atomic_set(&bat_priv->orig_interval, 1000);
+ atomic_set(&bat_priv->hop_penalty, 10);
+ atomic_set(&bat_priv->log_level, 0);
+ atomic_set(&bat_priv->fragmentation, 1);
+ atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
+ atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
+
+ atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
+ atomic_set(&bat_priv->bcast_seqno, 1);
+ atomic_set(&bat_priv->hna_local_changed, 0);
+
+ bat_priv->primary_if = NULL;
+ bat_priv->num_ifaces = 0;
+ bat_priv->softif_neigh = NULL;
+
+ ret = sysfs_add_meshif(soft_iface);
+ if (ret < 0)
+ goto unreg_soft_iface;
+
+ ret = debugfs_add_meshif(soft_iface);
+ if (ret < 0)
+ goto unreg_sysfs;
+
+ ret = mesh_init(soft_iface);
+ if (ret < 0)
+ goto unreg_debugfs;
+
+ return soft_iface;
+
+unreg_debugfs:
+ debugfs_del_meshif(soft_iface);
+unreg_sysfs:
+ sysfs_del_meshif(soft_iface);
+unreg_soft_iface:
+ unregister_netdev(soft_iface);
+ return NULL;
+
+free_soft_iface:
+ free_netdev(soft_iface);
+out:
+ return NULL;
+}
+
+void softif_destroy(struct net_device *soft_iface)
+{
+ debugfs_del_meshif(soft_iface);
+ sysfs_del_meshif(soft_iface);
+ mesh_free(soft_iface);
+ unregister_netdevice(soft_iface);
+}
+
+/* ethtool */
+static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = 0;
+ cmd->advertising = 0;
+ cmd->speed = SPEED_10;
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_TP;
+ cmd->phy_address = 0;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ return 0;
+}
+
+static void bat_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, "B.A.T.M.A.N. advanced");
+ strcpy(info->version, SOURCE_VERSION);
+ strcpy(info->fw_version, "N/A");
+ strcpy(info->bus_info, "batman");
+}
+
+static u32 bat_get_msglevel(struct net_device *dev)
+{
+ return -EOPNOTSUPP;
+}
+
+static void bat_set_msglevel(struct net_device *dev, u32 value)
+{
+}
+
+static u32 bat_get_link(struct net_device *dev)
+{
+ return 1;
+}
+
+static u32 bat_get_rx_csum(struct net_device *dev)
+{
+ return 0;
+}
+
+static int bat_set_rx_csum(struct net_device *dev, u32 data)
+{
+ return -EOPNOTSUPP;
+}
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
new file mode 100644
index 000000000000..02b77334d10d
--- /dev/null
+++ b/net/batman-adv/soft-interface.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+
+int my_skb_head_push(struct sk_buff *skb, unsigned int len);
+int softif_neigh_seq_print_text(struct seq_file *seq, void *offset);
+void softif_neigh_purge(struct bat_priv *bat_priv);
+int interface_tx(struct sk_buff *skb, struct net_device *soft_iface);
+void interface_rx(struct net_device *soft_iface,
+ struct sk_buff *skb, struct batman_if *recv_if,
+ int hdr_size);
+struct net_device *softif_create(char *name);
+void softif_destroy(struct net_device *soft_iface);
+
+#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
new file mode 100644
index 000000000000..a633b5a435e2
--- /dev/null
+++ b/net/batman-adv/translation-table.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2007-2010 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 "translation-table.h"
+#include "soft-interface.h"
+#include "types.h"
+#include "hash.h"
+#include "originator.h"
+
+static void hna_local_purge(struct work_struct *work);
+static void _hna_global_del_orig(struct bat_priv *bat_priv,
+ struct hna_global_entry *hna_global_entry,
+ char *message);
+
+static void hna_local_start_timer(struct bat_priv *bat_priv)
+{
+ INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ);
+}
+
+int hna_local_init(struct bat_priv *bat_priv)
+{
+ if (bat_priv->hna_local_hash)
+ return 1;
+
+ bat_priv->hna_local_hash = hash_new(1024);
+
+ if (!bat_priv->hna_local_hash)
+ return 0;
+
+ atomic_set(&bat_priv->hna_local_changed, 0);
+ hna_local_start_timer(bat_priv);
+
+ return 1;
+}
+
+void hna_local_add(struct net_device *soft_iface, uint8_t *addr)
+{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct hna_local_entry *hna_local_entry;
+ struct hna_global_entry *hna_global_entry;
+ int required_bytes;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+ hna_local_entry =
+ ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash,
+ compare_orig, choose_orig,
+ addr));
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+
+ if (hna_local_entry) {
+ hna_local_entry->last_seen = jiffies;
+ return;
+ }
+
+ /* 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. */
+ required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN;
+ required_bytes += BAT_PACKET_LEN;
+
+ if ((required_bytes > ETH_DATA_LEN) ||
+ (atomic_read(&bat_priv->aggregated_ogms) &&
+ required_bytes > MAX_AGGREGATION_BYTES) ||
+ (bat_priv->num_local_hna + 1 > 255)) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Can't add new local hna entry (%pM): "
+ "number of local hna entries exceeds packet size\n",
+ addr);
+ return;
+ }
+
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Creating new local hna entry: %pM\n", addr);
+
+ hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
+ if (!hna_local_entry)
+ return;
+
+ memcpy(hna_local_entry->addr, addr, ETH_ALEN);
+ hna_local_entry->last_seen = jiffies;
+
+ /* the batman interface mac address should never be purged */
+ if (compare_orig(addr, soft_iface->dev_addr))
+ hna_local_entry->never_purge = 1;
+ else
+ hna_local_entry->never_purge = 0;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig,
+ hna_local_entry);
+ bat_priv->num_local_hna++;
+ atomic_set(&bat_priv->hna_local_changed, 1);
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+
+ /* remove address from global hash if present */
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+
+ hna_global_entry = ((struct hna_global_entry *)
+ hash_find(bat_priv->hna_global_hash,
+ compare_orig, choose_orig, addr));
+
+ if (hna_global_entry)
+ _hna_global_del_orig(bat_priv, hna_global_entry,
+ "local hna received");
+
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+}
+
+int hna_local_fill_buffer(struct bat_priv *bat_priv,
+ unsigned char *buff, int buff_len)
+{
+ struct hashtable_t *hash = bat_priv->hna_local_hash;
+ struct hna_local_entry *hna_local_entry;
+ struct element_t *bucket;
+ int i;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ int count = 0;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+
+ if (buff_len < (count + 1) * ETH_ALEN)
+ break;
+
+ hna_local_entry = bucket->data;
+ memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr,
+ ETH_ALEN);
+
+ count++;
+ }
+ }
+
+ /* if we did not get all new local hnas see you next time ;-) */
+ if (count == bat_priv->num_local_hna)
+ atomic_set(&bat_priv->hna_local_changed, 0);
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ return count;
+}
+
+int hna_local_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hashtable_t *hash = bat_priv->hna_local_hash;
+ struct hna_local_entry *hna_local_entry;
+ int i;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ size_t buf_size, pos;
+ char *buff;
+
+ if (!bat_priv->primary_if) {
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ }
+
+ seq_printf(seq, "Locally retrieved addresses (from %s) "
+ "announced via HNA:\n",
+ net_dev->name);
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ buf_size = 1;
+ /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each(walk, head)
+ buf_size += 21;
+ }
+
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ pos = 0;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ hna_local_entry = bucket->data;
+
+ pos += snprintf(buff + pos, 22, " * %pM\n",
+ hna_local_entry->addr);
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+ return 0;
+}
+
+static void _hna_local_del(void *data, void *arg)
+{
+ struct bat_priv *bat_priv = (struct bat_priv *)arg;
+
+ kfree(data);
+ bat_priv->num_local_hna--;
+ atomic_set(&bat_priv->hna_local_changed, 1);
+}
+
+static void hna_local_del(struct bat_priv *bat_priv,
+ struct hna_local_entry *hna_local_entry,
+ char *message)
+{
+ bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
+ hna_local_entry->addr, message);
+
+ hash_remove(bat_priv->hna_local_hash, compare_orig, choose_orig,
+ hna_local_entry->addr);
+ _hna_local_del(hna_local_entry, bat_priv);
+}
+
+void hna_local_remove(struct bat_priv *bat_priv,
+ uint8_t *addr, char *message)
+{
+ struct hna_local_entry *hna_local_entry;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ hna_local_entry = (struct hna_local_entry *)
+ hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig,
+ addr);
+
+ if (hna_local_entry)
+ hna_local_del(bat_priv, hna_local_entry, message);
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+}
+
+static void hna_local_purge(struct work_struct *work)
+{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, hna_work);
+ struct hashtable_t *hash = bat_priv->hna_local_hash;
+ struct hna_local_entry *hna_local_entry;
+ int i;
+ struct hlist_node *walk, *safe;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ unsigned long timeout;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) {
+ hna_local_entry = bucket->data;
+
+ timeout = hna_local_entry->last_seen;
+ timeout += LOCAL_HNA_TIMEOUT * HZ;
+
+ if ((!hna_local_entry->never_purge) &&
+ time_after(jiffies, timeout))
+ hna_local_del(bat_priv, hna_local_entry,
+ "address timed out");
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ hna_local_start_timer(bat_priv);
+}
+
+void hna_local_free(struct bat_priv *bat_priv)
+{
+ if (!bat_priv->hna_local_hash)
+ return;
+
+ cancel_delayed_work_sync(&bat_priv->hna_work);
+ hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv);
+ bat_priv->hna_local_hash = NULL;
+}
+
+int hna_global_init(struct bat_priv *bat_priv)
+{
+ if (bat_priv->hna_global_hash)
+ return 1;
+
+ bat_priv->hna_global_hash = hash_new(1024);
+
+ if (!bat_priv->hna_global_hash)
+ return 0;
+
+ return 1;
+}
+
+void hna_global_add_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ unsigned char *hna_buff, int hna_buff_len)
+{
+ struct hna_global_entry *hna_global_entry;
+ struct hna_local_entry *hna_local_entry;
+ int hna_buff_count = 0;
+ unsigned char *hna_ptr;
+
+ while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+
+ hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
+ hna_global_entry = (struct hna_global_entry *)
+ hash_find(bat_priv->hna_global_hash, compare_orig,
+ choose_orig, hna_ptr);
+
+ if (!hna_global_entry) {
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+
+ hna_global_entry =
+ kmalloc(sizeof(struct hna_global_entry),
+ GFP_ATOMIC);
+
+ if (!hna_global_entry)
+ break;
+
+ memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
+
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Creating new global hna entry: "
+ "%pM (via %pM)\n",
+ hna_global_entry->addr, orig_node->orig);
+
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+ hash_add(bat_priv->hna_global_hash, compare_orig,
+ choose_orig, hna_global_entry);
+
+ }
+
+ hna_global_entry->orig_node = orig_node;
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+
+ /* remove address from local hash if present */
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+
+ hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
+ hna_local_entry = (struct hna_local_entry *)
+ hash_find(bat_priv->hna_local_hash, compare_orig,
+ choose_orig, hna_ptr);
+
+ if (hna_local_entry)
+ hna_local_del(bat_priv, hna_local_entry,
+ "global hna received");
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+
+ hna_buff_count++;
+ }
+
+ /* initialize, and overwrite if malloc succeeds */
+ orig_node->hna_buff = NULL;
+ orig_node->hna_buff_len = 0;
+
+ 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;
+ }
+ }
+}
+
+int hna_global_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hashtable_t *hash = bat_priv->hna_global_hash;
+ struct hna_global_entry *hna_global_entry;
+ int i;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ size_t buf_size, pos;
+ char *buff;
+
+ if (!bat_priv->primary_if) {
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ }
+
+ seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+ net_dev->name);
+
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+
+ buf_size = 1;
+ /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each(walk, head)
+ buf_size += 43;
+ }
+
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ pos = 0;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ hna_global_entry = bucket->data;
+
+ pos += snprintf(buff + pos, 44,
+ " * %pM via %pM\n",
+ hna_global_entry->addr,
+ hna_global_entry->orig_node->orig);
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+ return 0;
+}
+
+static void _hna_global_del_orig(struct bat_priv *bat_priv,
+ struct hna_global_entry *hna_global_entry,
+ char *message)
+{
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Deleting global hna entry %pM (via %pM): %s\n",
+ hna_global_entry->addr, hna_global_entry->orig_node->orig,
+ message);
+
+ hash_remove(bat_priv->hna_global_hash, compare_orig, choose_orig,
+ hna_global_entry->addr);
+ kfree(hna_global_entry);
+}
+
+void hna_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, char *message)
+{
+ struct hna_global_entry *hna_global_entry;
+ int hna_buff_count = 0;
+ unsigned char *hna_ptr;
+
+ if (orig_node->hna_buff_len == 0)
+ return;
+
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+
+ while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
+ hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
+ hna_global_entry = (struct hna_global_entry *)
+ hash_find(bat_priv->hna_global_hash, compare_orig,
+ choose_orig, hna_ptr);
+
+ if ((hna_global_entry) &&
+ (hna_global_entry->orig_node == orig_node))
+ _hna_global_del_orig(bat_priv, hna_global_entry,
+ message);
+
+ hna_buff_count++;
+ }
+
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+
+ orig_node->hna_buff_len = 0;
+ kfree(orig_node->hna_buff);
+ orig_node->hna_buff = NULL;
+}
+
+static void hna_global_del(void *data, void *arg)
+{
+ kfree(data);
+}
+
+void hna_global_free(struct bat_priv *bat_priv)
+{
+ if (!bat_priv->hna_global_hash)
+ return;
+
+ hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL);
+ bat_priv->hna_global_hash = NULL;
+}
+
+struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
+{
+ struct hna_global_entry *hna_global_entry;
+
+ spin_lock_bh(&bat_priv->hna_ghash_lock);
+ hna_global_entry = (struct hna_global_entry *)
+ hash_find(bat_priv->hna_global_hash,
+ compare_orig, choose_orig, addr);
+ spin_unlock_bh(&bat_priv->hna_ghash_lock);
+
+ if (!hna_global_entry)
+ return NULL;
+
+ return hna_global_entry->orig_node;
+}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
new file mode 100644
index 000000000000..10c4c5c319b6
--- /dev/null
+++ b/net/batman-adv/translation-table.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+
+#include "types.h"
+
+int hna_local_init(struct bat_priv *bat_priv);
+void hna_local_add(struct net_device *soft_iface, uint8_t *addr);
+void hna_local_remove(struct bat_priv *bat_priv,
+ uint8_t *addr, char *message);
+int hna_local_fill_buffer(struct bat_priv *bat_priv,
+ unsigned char *buff, int buff_len);
+int hna_local_seq_print_text(struct seq_file *seq, void *offset);
+void hna_local_free(struct bat_priv *bat_priv);
+int hna_global_init(struct bat_priv *bat_priv);
+void hna_global_add_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ unsigned char *hna_buff, int hna_buff_len);
+int hna_global_seq_print_text(struct seq_file *seq, void *offset);
+void hna_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, char *message);
+void hna_global_free(struct bat_priv *bat_priv);
+struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
+
+#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
new file mode 100644
index 000000000000..97cb23dd3e69
--- /dev/null
+++ b/net/batman-adv/types.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2007-2010 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
+ *
+ */
+
+
+
+#ifndef _NET_BATMAN_ADV_TYPES_H_
+#define _NET_BATMAN_ADV_TYPES_H_
+
+#include "packet.h"
+#include "bitarray.h"
+
+#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \
+ ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \
+ sizeof(struct unicast_packet) : \
+ sizeof(struct bcast_packet))))
+
+
+struct batman_if {
+ struct list_head list;
+ int16_t if_num;
+ char if_status;
+ struct net_device *net_dev;
+ atomic_t seqno;
+ atomic_t frag_seqno;
+ unsigned char *packet_buff;
+ int packet_len;
+ struct kobject *hardif_obj;
+ struct kref refcount;
+ struct packet_type batman_adv_ptype;
+ struct net_device *soft_iface;
+ struct rcu_head rcu;
+};
+
+/**
+ * orig_node - structure for orig_list maintaining nodes of mesh
+ * @primary_addr: hosts primary interface address
+ * @last_valid: when last packet from this node was received
+ * @bcast_seqno_reset: time when the broadcast seqno window was reset
+ * @batman_seqno_reset: time when the batman seqno window was reset
+ * @gw_flags: flags related to gateway class
+ * @flags: for now only VIS_SERVER flag
+ * @last_real_seqno: last and best known squence number
+ * @last_ttl: ttl of last received packet
+ * @last_bcast_seqno: last broadcast sequence number received by this host
+ *
+ * @candidates: how many candidates are available
+ * @selected: next bonding candidate
+ */
+struct orig_node {
+ uint8_t orig[ETH_ALEN];
+ uint8_t primary_addr[ETH_ALEN];
+ struct neigh_node *router;
+ unsigned long *bcast_own;
+ uint8_t *bcast_own_sum;
+ uint8_t tq_own;
+ int tq_asym_penalty;
+ unsigned long last_valid;
+ unsigned long bcast_seqno_reset;
+ unsigned long batman_seqno_reset;
+ uint8_t gw_flags;
+ uint8_t flags;
+ unsigned char *hna_buff;
+ int16_t hna_buff_len;
+ uint32_t last_real_seqno;
+ uint8_t last_ttl;
+ unsigned long bcast_bits[NUM_WORDS];
+ uint32_t last_bcast_seqno;
+ struct list_head neigh_list;
+ struct list_head frag_list;
+ unsigned long last_frag_packet;
+ struct {
+ uint8_t candidates;
+ struct neigh_node *selected;
+ } bond;
+};
+
+struct gw_node {
+ struct hlist_node list;
+ struct orig_node *orig_node;
+ unsigned long deleted;
+ struct kref refcount;
+ struct rcu_head rcu;
+};
+
+/**
+ * neigh_node
+ * @last_valid: when last packet via this neighbor was received
+ */
+struct neigh_node {
+ struct list_head list;
+ uint8_t addr[ETH_ALEN];
+ uint8_t real_packet_count;
+ uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE];
+ uint8_t tq_index;
+ uint8_t tq_avg;
+ uint8_t last_ttl;
+ struct neigh_node *next_bond_candidate;
+ unsigned long last_valid;
+ unsigned long real_bits[NUM_WORDS];
+ struct orig_node *orig_node;
+ struct batman_if *if_incoming;
+};
+
+
+struct bat_priv {
+ atomic_t mesh_state;
+ struct net_device_stats stats;
+ atomic_t aggregated_ogms; /* boolean */
+ atomic_t bonding; /* boolean */
+ atomic_t fragmentation; /* boolean */
+ atomic_t vis_mode; /* VIS_TYPE_* */
+ atomic_t gw_mode; /* GW_MODE_* */
+ atomic_t gw_sel_class; /* uint */
+ atomic_t gw_bandwidth; /* gw bandwidth */
+ atomic_t orig_interval; /* uint */
+ atomic_t hop_penalty; /* uint */
+ atomic_t log_level; /* uint */
+ atomic_t bcast_seqno;
+ atomic_t bcast_queue_left;
+ atomic_t batman_queue_left;
+ char num_ifaces;
+ struct hlist_head softif_neigh_list;
+ struct softif_neigh *softif_neigh;
+ struct debug_log *debug_log;
+ struct batman_if *primary_if;
+ struct kobject *mesh_obj;
+ struct dentry *debug_dir;
+ struct hlist_head forw_bat_list;
+ struct hlist_head forw_bcast_list;
+ struct hlist_head gw_list;
+ struct list_head vis_send_list;
+ struct hashtable_t *orig_hash;
+ struct hashtable_t *hna_local_hash;
+ struct hashtable_t *hna_global_hash;
+ struct hashtable_t *vis_hash;
+ spinlock_t orig_hash_lock; /* protects orig_hash */
+ spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
+ spinlock_t forw_bcast_list_lock; /* protects */
+ spinlock_t hna_lhash_lock; /* protects hna_local_hash */
+ spinlock_t hna_ghash_lock; /* protects hna_global_hash */
+ spinlock_t gw_list_lock; /* protects gw_list */
+ spinlock_t vis_hash_lock; /* protects vis_hash */
+ spinlock_t vis_list_lock; /* protects vis_info::recv_list */
+ spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */
+ int16_t num_local_hna;
+ atomic_t hna_local_changed;
+ struct delayed_work hna_work;
+ struct delayed_work orig_work;
+ struct delayed_work vis_work;
+ struct gw_node *curr_gw;
+ struct vis_info *my_vis_info;
+};
+
+struct socket_client {
+ struct list_head queue_list;
+ unsigned int queue_len;
+ unsigned char index;
+ spinlock_t lock; /* protects queue_list, queue_len, index */
+ wait_queue_head_t queue_wait;
+ struct bat_priv *bat_priv;
+};
+
+struct socket_packet {
+ struct list_head list;
+ size_t icmp_len;
+ struct icmp_packet_rr icmp_packet;
+};
+
+struct hna_local_entry {
+ uint8_t addr[ETH_ALEN];
+ unsigned long last_seen;
+ char never_purge;
+};
+
+struct hna_global_entry {
+ uint8_t addr[ETH_ALEN];
+ struct orig_node *orig_node;
+};
+
+/**
+ * forw_packet - structure for forw_list maintaining packets to be
+ * send/forwarded
+ */
+struct forw_packet {
+ struct hlist_node list;
+ unsigned long send_time;
+ uint8_t own;
+ struct sk_buff *skb;
+ uint16_t packet_len;
+ uint32_t direct_link_flags;
+ uint8_t num_packets;
+ struct delayed_work delayed_work;
+ 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;
+};
+
+struct debug_log {
+ char log_buff[LOG_BUF_LEN];
+ unsigned long log_start;
+ unsigned long log_end;
+ spinlock_t lock; /* protects log_buff, log_start and log_end */
+ wait_queue_head_t queue_wait;
+};
+
+struct frag_packet_list_entry {
+ struct list_head list;
+ uint16_t seqno;
+ struct sk_buff *skb;
+};
+
+struct vis_info {
+ unsigned long first_seen;
+ struct list_head recv_list;
+ /* list of server-neighbors we received a vis-packet
+ * from. we should not reply to them. */
+ struct list_head send_list;
+ struct kref refcount;
+ struct bat_priv *bat_priv;
+ /* this packet might be part of the vis send queue. */
+ struct sk_buff *skb_packet;
+ /* vis_info may follow here*/
+} __attribute__((packed));
+
+struct vis_info_entry {
+ uint8_t src[ETH_ALEN];
+ uint8_t dest[ETH_ALEN];
+ uint8_t quality; /* quality = 0 means HNA */
+} __attribute__((packed));
+
+struct recvlist_node {
+ struct list_head list;
+ uint8_t mac[ETH_ALEN];
+};
+
+struct softif_neigh {
+ struct hlist_node list;
+ uint8_t addr[ETH_ALEN];
+ unsigned long last_seen;
+ short vid;
+ struct kref refcount;
+ struct rcu_head rcu;
+};
+
+#endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
new file mode 100644
index 000000000000..dc2e28bed844
--- /dev/null
+++ b/net/batman-adv/unicast.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Andreas Langer
+ *
+ * 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 "unicast.h"
+#include "send.h"
+#include "soft-interface.h"
+#include "gateway_client.h"
+#include "originator.h"
+#include "hash.h"
+#include "translation-table.h"
+#include "routing.h"
+#include "hard-interface.h"
+
+
+static struct sk_buff *frag_merge_packet(struct list_head *head,
+ struct frag_packet_list_entry *tfp,
+ struct sk_buff *skb)
+{
+ struct unicast_frag_packet *up =
+ (struct unicast_frag_packet *)skb->data;
+ struct sk_buff *tmp_skb;
+ struct unicast_packet *unicast_packet;
+ int hdr_len = sizeof(struct unicast_packet),
+ uni_diff = sizeof(struct unicast_frag_packet) - hdr_len;
+
+ /* set skb to the first part and tmp_skb to the second part */
+ if (up->flags & UNI_FRAG_HEAD) {
+ tmp_skb = tfp->skb;
+ } else {
+ tmp_skb = skb;
+ skb = tfp->skb;
+ }
+
+ skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
+ if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) {
+ /* free buffered skb, skb will be freed later */
+ kfree_skb(tfp->skb);
+ return NULL;
+ }
+
+ /* move free entry to end */
+ tfp->skb = NULL;
+ tfp->seqno = 0;
+ list_move_tail(&tfp->list, head);
+
+ memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len);
+ kfree_skb(tmp_skb);
+
+ memmove(skb->data + uni_diff, skb->data, hdr_len);
+ unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff);
+ unicast_packet->packet_type = BAT_UNICAST;
+
+ return skb;
+}
+
+static void frag_create_entry(struct list_head *head, struct sk_buff *skb)
+{
+ struct frag_packet_list_entry *tfp;
+ struct unicast_frag_packet *up =
+ (struct unicast_frag_packet *)skb->data;
+
+ /* free and oldest packets stand at the end */
+ tfp = list_entry((head)->prev, typeof(*tfp), list);
+ kfree_skb(tfp->skb);
+
+ tfp->seqno = ntohs(up->seqno);
+ tfp->skb = skb;
+ list_move(&tfp->list, head);
+ return;
+}
+
+static int frag_create_buffer(struct list_head *head)
+{
+ int i;
+ struct frag_packet_list_entry *tfp;
+
+ for (i = 0; i < FRAG_BUFFER_SIZE; i++) {
+ tfp = kmalloc(sizeof(struct frag_packet_list_entry),
+ GFP_ATOMIC);
+ if (!tfp) {
+ frag_list_free(head);
+ return -ENOMEM;
+ }
+ tfp->skb = NULL;
+ tfp->seqno = 0;
+ INIT_LIST_HEAD(&tfp->list);
+ list_add(&tfp->list, head);
+ }
+
+ return 0;
+}
+
+static struct frag_packet_list_entry *frag_search_packet(struct list_head *head,
+ struct unicast_frag_packet *up)
+{
+ struct frag_packet_list_entry *tfp;
+ struct unicast_frag_packet *tmp_up = NULL;
+ uint16_t search_seqno;
+
+ if (up->flags & UNI_FRAG_HEAD)
+ search_seqno = ntohs(up->seqno)+1;
+ else
+ search_seqno = ntohs(up->seqno)-1;
+
+ list_for_each_entry(tfp, head, list) {
+
+ if (!tfp->skb)
+ continue;
+
+ if (tfp->seqno == ntohs(up->seqno))
+ goto mov_tail;
+
+ tmp_up = (struct unicast_frag_packet *)tfp->skb->data;
+
+ if (tfp->seqno == search_seqno) {
+
+ if ((tmp_up->flags & UNI_FRAG_HEAD) !=
+ (up->flags & UNI_FRAG_HEAD))
+ return tfp;
+ else
+ goto mov_tail;
+ }
+ }
+ return NULL;
+
+mov_tail:
+ list_move_tail(&tfp->list, head);
+ return NULL;
+}
+
+void frag_list_free(struct list_head *head)
+{
+ struct frag_packet_list_entry *pf, *tmp_pf;
+
+ if (!list_empty(head)) {
+
+ list_for_each_entry_safe(pf, tmp_pf, head, list) {
+ kfree_skb(pf->skb);
+ list_del(&pf->list);
+ kfree(pf);
+ }
+ }
+ return;
+}
+
+/* frag_reassemble_skb():
+ * returns NET_RX_DROP if the operation failed - skb is left intact
+ * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL)
+ * or the skb could be reassembled (skb_new will point to the new packet and
+ * skb was freed)
+ */
+int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
+ struct sk_buff **new_skb)
+{
+ struct orig_node *orig_node;
+ struct frag_packet_list_entry *tmp_frag_entry;
+ int ret = NET_RX_DROP;
+ struct unicast_frag_packet *unicast_packet =
+ (struct unicast_frag_packet *)skb->data;
+
+ *new_skb = NULL;
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
+ unicast_packet->orig));
+
+ if (!orig_node) {
+ pr_debug("couldn't find originator in orig_hash\n");
+ goto out;
+ }
+
+ orig_node->last_frag_packet = jiffies;
+
+ if (list_empty(&orig_node->frag_list) &&
+ frag_create_buffer(&orig_node->frag_list)) {
+ pr_debug("couldn't create frag buffer\n");
+ goto out;
+ }
+
+ tmp_frag_entry = frag_search_packet(&orig_node->frag_list,
+ unicast_packet);
+
+ if (!tmp_frag_entry) {
+ frag_create_entry(&orig_node->frag_list, skb);
+ ret = NET_RX_SUCCESS;
+ goto out;
+ }
+
+ *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry,
+ skb);
+ /* if not, merge failed */
+ if (*new_skb)
+ ret = NET_RX_SUCCESS;
+out:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ return ret;
+}
+
+int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
+ struct batman_if *batman_if, uint8_t dstaddr[])
+{
+ struct unicast_packet tmp_uc, *unicast_packet;
+ struct sk_buff *frag_skb;
+ struct unicast_frag_packet *frag1, *frag2;
+ int uc_hdr_len = sizeof(struct unicast_packet);
+ int ucf_hdr_len = sizeof(struct unicast_frag_packet);
+ int data_len = skb->len;
+
+ if (!bat_priv->primary_if)
+ goto dropped;
+
+ unicast_packet = (struct unicast_packet *) skb->data;
+
+ memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
+ frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
+ skb_split(skb, frag_skb, data_len / 2);
+
+ if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 ||
+ my_skb_head_push(frag_skb, ucf_hdr_len) < 0)
+ goto drop_frag;
+
+ frag1 = (struct unicast_frag_packet *)skb->data;
+ frag2 = (struct unicast_frag_packet *)frag_skb->data;
+
+ memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet));
+
+ frag1->ttl--;
+ frag1->version = COMPAT_VERSION;
+ frag1->packet_type = BAT_UNICAST_FRAG;
+
+ memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(frag2, frag1, sizeof(struct unicast_frag_packet));
+
+ frag1->flags |= UNI_FRAG_HEAD;
+ frag2->flags &= ~UNI_FRAG_HEAD;
+
+ frag1->seqno = htons((uint16_t)atomic_inc_return(
+ &batman_if->frag_seqno));
+ frag2->seqno = htons((uint16_t)atomic_inc_return(
+ &batman_if->frag_seqno));
+
+ send_skb_packet(skb, batman_if, dstaddr);
+ send_skb_packet(frag_skb, batman_if, dstaddr);
+ return NET_RX_SUCCESS;
+
+drop_frag:
+ kfree_skb(frag_skb);
+dropped:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
+{
+ struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+ struct unicast_packet *unicast_packet;
+ struct orig_node *orig_node;
+ struct batman_if *batman_if;
+ struct neigh_node *router;
+ int data_len = skb->len;
+ uint8_t dstaddr[6];
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+
+ /* get routing information */
+ if (is_multicast_ether_addr(ethhdr->h_dest))
+ orig_node = (struct orig_node *)gw_get_selected(bat_priv);
+ else
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ compare_orig,
+ choose_orig,
+ ethhdr->h_dest));
+
+ /* check for hna host */
+ if (!orig_node)
+ orig_node = transtable_search(bat_priv, ethhdr->h_dest);
+
+ router = find_router(bat_priv, orig_node, NULL);
+
+ if (!router)
+ goto unlock;
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+
+ batman_if = router->if_incoming;
+ memcpy(dstaddr, router->addr, ETH_ALEN);
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ if (batman_if->if_status != IF_ACTIVE)
+ goto dropped;
+
+ if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0)
+ goto dropped;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ unicast_packet->version = COMPAT_VERSION;
+ /* batman packet type: unicast */
+ unicast_packet->packet_type = BAT_UNICAST;
+ /* set unicast ttl */
+ unicast_packet->ttl = TTL;
+ /* copy the destination for faster routing */
+ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+
+ if (atomic_read(&bat_priv->fragmentation) &&
+ data_len + sizeof(struct unicast_packet) >
+ batman_if->net_dev->mtu) {
+ /* send frag skb decreases ttl */
+ unicast_packet->ttl++;
+ return frag_send_skb(skb, bat_priv, batman_if,
+ dstaddr);
+ }
+ send_skb_packet(skb, batman_if, dstaddr);
+ return 0;
+
+unlock:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+dropped:
+ kfree_skb(skb);
+ return 1;
+}
diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h
new file mode 100644
index 000000000000..e32b7867a9a4
--- /dev/null
+++ b/net/batman-adv/unicast.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Andreas Langer
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_UNICAST_H_
+#define _NET_BATMAN_ADV_UNICAST_H_
+
+#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */
+#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
+
+int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
+ struct sk_buff **new_skb);
+void frag_list_free(struct list_head *head);
+int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
+int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
+ struct batman_if *batman_if, uint8_t dstaddr[]);
+
+#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
new file mode 100644
index 000000000000..cd4c4231fa48
--- /dev/null
+++ b/net/batman-adv/vis.c
@@ -0,0 +1,949 @@
+/*
+ * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors:
+ *
+ * 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 "send.h"
+#include "translation-table.h"
+#include "vis.h"
+#include "soft-interface.h"
+#include "hard-interface.h"
+#include "hash.h"
+#include "originator.h"
+
+#define MAX_VIS_PACKET_SIZE 1000
+
+/* Returns the smallest signed integer in two's complement with the sizeof x */
+#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
+
+/* Checks if a sequence number x is a predecessor/successor of y.
+ * they handle overflows/underflows and can correctly check for a
+ * predecessor/successor unless the variable sequence number has grown by
+ * more then 2**(bitwidth(x)-1)-1.
+ * This means that for a uint8_t with the maximum value 255, it would think:
+ * - when adding nothing - it is neither a predecessor nor a successor
+ * - before adding more than 127 to the starting value - it is a predecessor,
+ * - when adding 128 - it is neither a predecessor nor a successor,
+ * - after adding more than 127 to the starting value - it is a successor */
+#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
+ _dummy > smallest_signed_int(_dummy); })
+#define seq_after(x, y) seq_before(y, x)
+
+static void start_vis_timer(struct bat_priv *bat_priv);
+
+/* free the info */
+static void free_info(struct kref *ref)
+{
+ struct vis_info *info = container_of(ref, struct vis_info, refcount);
+ struct bat_priv *bat_priv = info->bat_priv;
+ struct recvlist_node *entry, *tmp;
+
+ list_del_init(&info->send_list);
+ spin_lock_bh(&bat_priv->vis_list_lock);
+ list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
+
+ spin_unlock_bh(&bat_priv->vis_list_lock);
+ kfree_skb(info->skb_packet);
+}
+
+/* Compare two vis packets, used by the hashing algorithm */
+static int vis_info_cmp(void *data1, void *data2)
+{
+ struct vis_info *d1, *d2;
+ struct vis_packet *p1, *p2;
+ d1 = data1;
+ d2 = data2;
+ p1 = (struct vis_packet *)d1->skb_packet->data;
+ p2 = (struct vis_packet *)d2->skb_packet->data;
+ return compare_orig(p1->vis_orig, p2->vis_orig);
+}
+
+/* hash function to choose an entry in a hash table of given size */
+/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
+static int vis_info_choose(void *data, int size)
+{
+ struct vis_info *vis_info = data;
+ struct vis_packet *packet;
+ unsigned char *key;
+ uint32_t hash = 0;
+ size_t i;
+
+ packet = (struct vis_packet *)vis_info->skb_packet->data;
+ key = packet->vis_orig;
+ for (i = 0; i < ETH_ALEN; i++) {
+ hash += key[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash % size;
+}
+
+/* insert interface to the list of interfaces of one originator, if it
+ * does not already exist in the list */
+static void vis_data_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_ATOMIC);
+ if (!entry)
+ return;
+ memcpy(entry->addr, interface, ETH_ALEN);
+ entry->primary = primary;
+ hlist_add_head(&entry->list, if_list);
+}
+
+static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
+{
+ struct if_list_entry *entry;
+ struct hlist_node *pos;
+ size_t len = 0;
+
+ hlist_for_each_entry(entry, pos, if_list, list) {
+ if (entry->primary)
+ len += sprintf(buff + len, "PRIMARY, ");
+ else
+ len += sprintf(buff + len, "SEC %pM, ", entry->addr);
+ }
+
+ return len;
+}
+
+static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
+{
+ struct if_list_entry *entry;
+ struct hlist_node *pos;
+ size_t count = 0;
+
+ hlist_for_each_entry(entry, pos, if_list, list) {
+ if (entry->primary)
+ count += 9;
+ else
+ count += 23;
+ }
+
+ return count;
+}
+
+/* read an entry */
+static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
+ uint8_t *src, bool primary)
+{
+ /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
+ if (primary && entry->quality == 0)
+ return sprintf(buff, "HNA %pM, ", entry->dest);
+ else if (compare_orig(entry->src, src))
+ return sprintf(buff, "TQ %pM %d, ", entry->dest,
+ entry->quality);
+
+ return 0;
+}
+
+int vis_seq_print_text(struct seq_file *seq, void *offset)
+{
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct vis_info *info;
+ struct vis_packet *packet;
+ struct vis_info_entry *entries;
+ struct net_device *net_dev = (struct net_device *)seq->private;
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hashtable_t *hash = bat_priv->vis_hash;
+ HLIST_HEAD(vis_if_list);
+ struct if_list_entry *entry;
+ struct hlist_node *pos, *n;
+ int i, j;
+ int vis_server = atomic_read(&bat_priv->vis_mode);
+ size_t buff_pos, buf_size;
+ char *buff;
+ int compare;
+
+ if ((!bat_priv->primary_if) ||
+ (vis_server == VIS_TYPE_CLIENT_UPDATE))
+ return 0;
+
+ buf_size = 1;
+ /* Estimate length */
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ info = bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
+ entries = (struct vis_info_entry *)
+ ((char *)packet + sizeof(struct vis_packet));
+
+ for (j = 0; j < packet->entries; j++) {
+ if (entries[j].quality == 0)
+ continue;
+ compare =
+ compare_orig(entries[j].src, packet->vis_orig);
+ vis_data_insert_interface(entries[j].src,
+ &vis_if_list,
+ compare);
+ }
+
+ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+ buf_size += 18 + 26 * packet->entries;
+
+ /* add primary/secondary records */
+ if (compare_orig(entry->addr, packet->vis_orig))
+ buf_size +=
+ vis_data_count_prim_sec(&vis_if_list);
+
+ buf_size += 1;
+ }
+
+ hlist_for_each_entry_safe(entry, pos, n, &vis_if_list,
+ list) {
+ hlist_del(&entry->list);
+ kfree(entry);
+ }
+ }
+ }
+
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ buff_pos = 0;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ info = bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
+ entries = (struct vis_info_entry *)
+ ((char *)packet + sizeof(struct vis_packet));
+
+ for (j = 0; j < packet->entries; j++) {
+ if (entries[j].quality == 0)
+ continue;
+ compare =
+ compare_orig(entries[j].src, packet->vis_orig);
+ vis_data_insert_interface(entries[j].src,
+ &vis_if_list,
+ compare);
+ }
+
+ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+ buff_pos += sprintf(buff + buff_pos, "%pM,",
+ entry->addr);
+
+ for (i = 0; i < packet->entries; i++)
+ buff_pos += vis_data_read_entry(
+ buff + buff_pos,
+ &entries[i],
+ entry->addr,
+ entry->primary);
+
+ /* add primary/secondary records */
+ if (compare_orig(entry->addr, packet->vis_orig))
+ buff_pos +=
+ vis_data_read_prim_sec(buff + buff_pos,
+ &vis_if_list);
+
+ buff_pos += sprintf(buff + buff_pos, "\n");
+ }
+
+ hlist_for_each_entry_safe(entry, pos, n, &vis_if_list,
+ list) {
+ hlist_del(&entry->list);
+ kfree(entry);
+ }
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+
+ return 0;
+}
+
+/* add the info packet to the send list, if it was not
+ * already linked in. */
+static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info)
+{
+ if (list_empty(&info->send_list)) {
+ kref_get(&info->refcount);
+ list_add_tail(&info->send_list, &bat_priv->vis_send_list);
+ }
+}
+
+/* delete the info packet from the send list, if it was
+ * linked in. */
+static void send_list_del(struct vis_info *info)
+{
+ if (!list_empty(&info->send_list)) {
+ list_del_init(&info->send_list);
+ kref_put(&info->refcount, free_info);
+ }
+}
+
+/* tries to add one entry to the receive list. */
+static void recv_list_add(struct bat_priv *bat_priv,
+ struct list_head *recv_list, char *mac)
+{
+ struct recvlist_node *entry;
+
+ entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+ if (!entry)
+ return;
+
+ memcpy(entry->mac, mac, ETH_ALEN);
+ spin_lock_bh(&bat_priv->vis_list_lock);
+ list_add_tail(&entry->list, recv_list);
+ spin_unlock_bh(&bat_priv->vis_list_lock);
+}
+
+/* returns 1 if this mac is in the recv_list */
+static int recv_list_is_in(struct bat_priv *bat_priv,
+ struct list_head *recv_list, char *mac)
+{
+ struct recvlist_node *entry;
+
+ spin_lock_bh(&bat_priv->vis_list_lock);
+ list_for_each_entry(entry, recv_list, list) {
+ if (memcmp(entry->mac, mac, ETH_ALEN) == 0) {
+ spin_unlock_bh(&bat_priv->vis_list_lock);
+ return 1;
+ }
+ }
+ spin_unlock_bh(&bat_priv->vis_list_lock);
+ return 0;
+}
+
+/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
+ * broken.. ). vis hash must be locked outside. is_new is set when the packet
+ * is newer than old entries in the hash. */
+static struct vis_info *add_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len, int *is_new,
+ int make_broadcast)
+{
+ struct vis_info *info, *old_info;
+ struct vis_packet *search_packet, *old_packet;
+ struct vis_info search_elem;
+ struct vis_packet *packet;
+ int hash_added;
+
+ *is_new = 0;
+ /* sanity check */
+ if (!bat_priv->vis_hash)
+ return NULL;
+
+ /* see if the packet is already in vis_hash */
+ search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
+ if (!search_elem.skb_packet)
+ return NULL;
+ search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
+ sizeof(struct vis_packet));
+
+ memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
+ old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
+ &search_elem);
+ kfree_skb(search_elem.skb_packet);
+
+ if (old_info) {
+ old_packet = (struct vis_packet *)old_info->skb_packet->data;
+ if (!seq_after(ntohl(vis_packet->seqno),
+ ntohl(old_packet->seqno))) {
+ if (old_packet->seqno == vis_packet->seqno) {
+ recv_list_add(bat_priv, &old_info->recv_list,
+ vis_packet->sender_orig);
+ return old_info;
+ } else {
+ /* newer packet is already in hash. */
+ return NULL;
+ }
+ }
+ /* remove old entry */
+ hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
+ old_info);
+ send_list_del(old_info);
+ kref_put(&old_info->refcount, free_info);
+ }
+
+ info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
+ if (!info)
+ return NULL;
+
+ info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
+ vis_info_len + sizeof(struct ethhdr));
+ if (!info->skb_packet) {
+ kfree(info);
+ return NULL;
+ }
+ skb_reserve(info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(info->skb_packet,
+ sizeof(struct vis_packet) +
+ vis_info_len);
+
+ kref_init(&info->refcount);
+ INIT_LIST_HEAD(&info->send_list);
+ INIT_LIST_HEAD(&info->recv_list);
+ info->first_seen = jiffies;
+ info->bat_priv = bat_priv;
+ memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
+
+ /* initialize and add new packet. */
+ *is_new = 1;
+
+ /* Make it a broadcast packet, if required */
+ if (make_broadcast)
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
+
+ /* repair if entries is longer than packet. */
+ if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len)
+ packet->entries = vis_info_len / sizeof(struct vis_info_entry);
+
+ recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
+
+ /* try to add it */
+ hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
+ info);
+ if (hash_added < 0) {
+ /* did not work (for some reason) */
+ kref_put(&old_info->refcount, free_info);
+ info = NULL;
+ }
+
+ return info;
+}
+
+/* handle the server sync packet, forward if needed. */
+void receive_server_sync_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len)
+{
+ struct vis_info *info;
+ int is_new, make_broadcast;
+ int vis_server = atomic_read(&bat_priv->vis_mode);
+
+ make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ info = add_packet(bat_priv, vis_packet, vis_info_len,
+ &is_new, make_broadcast);
+ if (!info)
+ goto end;
+
+ /* only if we are server ourselves and packet is newer than the one in
+ * hash.*/
+ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new)
+ send_list_add(bat_priv, info);
+end:
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+}
+
+/* handle an incoming client update packet and schedule forward if needed. */
+void receive_client_update_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len)
+{
+ struct vis_info *info;
+ struct vis_packet *packet;
+ int is_new;
+ int vis_server = atomic_read(&bat_priv->vis_mode);
+ int are_target = 0;
+
+ /* clients shall not broadcast. */
+ if (is_broadcast_ether_addr(vis_packet->target_orig))
+ return;
+
+ /* Are we the target for this VIS packet? */
+ if (vis_server == VIS_TYPE_SERVER_SYNC &&
+ is_my_mac(vis_packet->target_orig))
+ are_target = 1;
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ info = add_packet(bat_priv, vis_packet, vis_info_len,
+ &is_new, are_target);
+
+ if (!info)
+ goto end;
+ /* note that outdated packets will be dropped at this point. */
+
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ /* send only if we're the target server or ... */
+ if (are_target && is_new) {
+ packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
+ send_list_add(bat_priv, info);
+
+ /* ... we're not the recipient (and thus need to forward). */
+ } else if (!is_my_mac(packet->target_orig)) {
+ send_list_add(bat_priv, info);
+ }
+
+end:
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+}
+
+/* Walk the originators and find the VIS server with the best tq. Set the packet
+ * address to its address and return the best_tq.
+ *
+ * Must be called with the originator hash locked */
+static int find_best_vis_server(struct bat_priv *bat_priv,
+ struct vis_info *info)
+{
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ struct vis_packet *packet;
+ int best_tq = -1, i;
+
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+ if ((orig_node) && (orig_node->router) &&
+ (orig_node->flags & VIS_SERVER) &&
+ (orig_node->router->tq_avg > best_tq)) {
+ best_tq = orig_node->router->tq_avg;
+ memcpy(packet->target_orig, orig_node->orig,
+ ETH_ALEN);
+ }
+ }
+ }
+
+ return best_tq;
+}
+
+/* Return true if the vis packet is full. */
+static bool vis_packet_full(struct vis_info *info)
+{
+ struct vis_packet *packet;
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
+ < packet->entries + 1)
+ return true;
+ return false;
+}
+
+/* generates a packet of own vis data,
+ * returns 0 on success, -1 if no packet could be generated */
+static int generate_vis_packet(struct bat_priv *bat_priv)
+{
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ struct neigh_node *neigh_node;
+ struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
+ struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
+ struct vis_info_entry *entry;
+ struct hna_local_entry *hna_local_entry;
+ int best_tq = -1, i;
+
+ info->first_seen = jiffies;
+ packet->vis_type = atomic_read(&bat_priv->vis_mode);
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
+ packet->ttl = TTL;
+ packet->seqno = htonl(ntohl(packet->seqno) + 1);
+ packet->entries = 0;
+ skb_trim(info->skb_packet, sizeof(struct vis_packet));
+
+ if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
+ best_tq = find_best_vis_server(bat_priv, info);
+
+ if (best_tq < 0) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+ neigh_node = orig_node->router;
+
+ if (!neigh_node)
+ continue;
+
+ if (!compare_orig(neigh_node->addr, orig_node->orig))
+ continue;
+
+ if (neigh_node->if_incoming->if_status != IF_ACTIVE)
+ continue;
+
+ if (neigh_node->tq_avg < 1)
+ continue;
+
+ /* fill one entry into buffer. */
+ entry = (struct vis_info_entry *)
+ skb_put(info->skb_packet, sizeof(*entry));
+ memcpy(entry->src,
+ neigh_node->if_incoming->net_dev->dev_addr,
+ ETH_ALEN);
+ memcpy(entry->dest, orig_node->orig, ETH_ALEN);
+ entry->quality = neigh_node->tq_avg;
+ packet->entries++;
+
+ if (vis_packet_full(info)) {
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+ return 0;
+ }
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ hash = bat_priv->hna_local_hash;
+
+ spin_lock_bh(&bat_priv->hna_lhash_lock);
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ hna_local_entry = bucket->data;
+ entry = (struct vis_info_entry *)
+ skb_put(info->skb_packet,
+ sizeof(*entry));
+ memset(entry->src, 0, ETH_ALEN);
+ memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
+ entry->quality = 0; /* 0 means HNA */
+ packet->entries++;
+
+ if (vis_packet_full(info)) {
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ return 0;
+ }
+ }
+ }
+
+ spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ return 0;
+}
+
+/* free old vis packets. Must be called with this vis_hash_lock
+ * held */
+static void purge_vis_packets(struct bat_priv *bat_priv)
+{
+ int i;
+ struct hashtable_t *hash = bat_priv->vis_hash;
+ struct hlist_node *walk, *safe;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct vis_info *info;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) {
+ info = bucket->data;
+
+ /* never purge own data. */
+ if (info == bat_priv->my_vis_info)
+ continue;
+
+ if (time_after(jiffies,
+ info->first_seen + VIS_TIMEOUT * HZ)) {
+ hlist_del(walk);
+ kfree(bucket);
+ send_list_del(info);
+ kref_put(&info->refcount, free_info);
+ }
+ }
+ }
+}
+
+static void broadcast_vis_packet(struct bat_priv *bat_priv,
+ struct vis_info *info)
+{
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *walk;
+ struct hlist_head *head;
+ struct element_t *bucket;
+ struct orig_node *orig_node;
+ struct vis_packet *packet;
+ struct sk_buff *skb;
+ struct batman_if *batman_if;
+ uint8_t dstaddr[ETH_ALEN];
+ int i;
+
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ /* send to all routers in range. */
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ hlist_for_each_entry(bucket, walk, head, hlist) {
+ orig_node = bucket->data;
+
+ /* if it's a vis server and reachable, send it. */
+ if ((!orig_node) || (!orig_node->router))
+ continue;
+ if (!(orig_node->flags & VIS_SERVER))
+ continue;
+ /* don't send it if we already received the packet from
+ * this node. */
+ if (recv_list_is_in(bat_priv, &info->recv_list,
+ orig_node->orig))
+ continue;
+
+ memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ }
+
+ }
+
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+}
+
+static void unicast_vis_packet(struct bat_priv *bat_priv,
+ struct vis_info *info)
+{
+ struct orig_node *orig_node;
+ struct sk_buff *skb;
+ struct vis_packet *packet;
+ struct batman_if *batman_if;
+ uint8_t dstaddr[ETH_ALEN];
+
+ spin_lock_bh(&bat_priv->orig_hash_lock);
+ packet = (struct vis_packet *)info->skb_packet->data;
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ compare_orig, choose_orig,
+ packet->target_orig));
+
+ if ((!orig_node) || (!orig_node->router))
+ goto out;
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->router->if_incoming;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
+
+ return;
+
+out:
+ spin_unlock_bh(&bat_priv->orig_hash_lock);
+}
+
+/* only send one vis packet. called from send_vis_packets() */
+static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
+{
+ struct vis_packet *packet;
+
+ packet = (struct vis_packet *)info->skb_packet->data;
+ if (packet->ttl < 2) {
+ pr_debug("Error - can't send vis packet: ttl exceeded\n");
+ return;
+ }
+
+ memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
+ ETH_ALEN);
+ packet->ttl--;
+
+ if (is_broadcast_ether_addr(packet->target_orig))
+ broadcast_vis_packet(bat_priv, info);
+ else
+ unicast_vis_packet(bat_priv, info);
+ packet->ttl++; /* restore TTL */
+}
+
+/* called from timer; send (and maybe generate) vis packet. */
+static void send_vis_packets(struct work_struct *work)
+{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, vis_work);
+ struct vis_info *info, *temp;
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ purge_vis_packets(bat_priv);
+
+ if (generate_vis_packet(bat_priv) == 0) {
+ /* schedule if generation was successful */
+ send_list_add(bat_priv, bat_priv->my_vis_info);
+ }
+
+ list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list,
+ send_list) {
+
+ kref_get(&info->refcount);
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+
+ if (bat_priv->primary_if)
+ send_vis_packet(bat_priv, info);
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ send_list_del(info);
+ kref_put(&info->refcount, free_info);
+ }
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+ start_vis_timer(bat_priv);
+}
+
+/* init the vis server. this may only be called when if_list is already
+ * initialized (e.g. bat0 is initialized, interfaces have been added) */
+int vis_init(struct bat_priv *bat_priv)
+{
+ struct vis_packet *packet;
+ int hash_added;
+
+ if (bat_priv->vis_hash)
+ return 1;
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+
+ bat_priv->vis_hash = hash_new(256);
+ if (!bat_priv->vis_hash) {
+ pr_err("Can't initialize vis_hash\n");
+ goto err;
+ }
+
+ bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
+ if (!bat_priv->my_vis_info) {
+ pr_err("Can't initialize vis packet\n");
+ goto err;
+ }
+
+ bat_priv->my_vis_info->skb_packet = dev_alloc_skb(
+ sizeof(struct vis_packet) +
+ MAX_VIS_PACKET_SIZE +
+ sizeof(struct ethhdr));
+ if (!bat_priv->my_vis_info->skb_packet)
+ goto free_info;
+
+ skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(
+ bat_priv->my_vis_info->skb_packet,
+ sizeof(struct vis_packet));
+
+ /* prefill the vis info */
+ bat_priv->my_vis_info->first_seen = jiffies -
+ msecs_to_jiffies(VIS_INTERVAL);
+ INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list);
+ INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list);
+ kref_init(&bat_priv->my_vis_info->refcount);
+ bat_priv->my_vis_info->bat_priv = bat_priv;
+ packet->version = COMPAT_VERSION;
+ packet->packet_type = BAT_VIS;
+ packet->ttl = TTL;
+ packet->seqno = 0;
+ packet->entries = 0;
+
+ INIT_LIST_HEAD(&bat_priv->vis_send_list);
+
+ hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
+ bat_priv->my_vis_info);
+ if (hash_added < 0) {
+ pr_err("Can't add own vis packet into hash\n");
+ /* not in hash, need to remove it manually. */
+ kref_put(&bat_priv->my_vis_info->refcount, free_info);
+ goto err;
+ }
+
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+ start_vis_timer(bat_priv);
+ return 1;
+
+free_info:
+ kfree(bat_priv->my_vis_info);
+ bat_priv->my_vis_info = NULL;
+err:
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+ vis_quit(bat_priv);
+ return 0;
+}
+
+/* Decrease the reference count on a hash item info */
+static void free_info_ref(void *data, void *arg)
+{
+ struct vis_info *info = data;
+
+ send_list_del(info);
+ kref_put(&info->refcount, free_info);
+}
+
+/* shutdown vis-server */
+void vis_quit(struct bat_priv *bat_priv)
+{
+ if (!bat_priv->vis_hash)
+ return;
+
+ cancel_delayed_work_sync(&bat_priv->vis_work);
+
+ spin_lock_bh(&bat_priv->vis_hash_lock);
+ /* properly remove, kill timers ... */
+ hash_delete(bat_priv->vis_hash, free_info_ref, NULL);
+ bat_priv->vis_hash = NULL;
+ bat_priv->my_vis_info = NULL;
+ spin_unlock_bh(&bat_priv->vis_hash_lock);
+}
+
+/* schedule packets for (re)transmission */
+static void start_vis_timer(struct bat_priv *bat_priv)
+{
+ INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work,
+ msecs_to_jiffies(VIS_INTERVAL));
+}
diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h
new file mode 100644
index 000000000000..2c3b33089a9b
--- /dev/null
+++ b/net/batman-adv/vis.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_VIS_H_
+#define _NET_BATMAN_ADV_VIS_H_
+
+#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */
+
+int vis_seq_print_text(struct seq_file *seq, void *offset);
+void receive_server_sync_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len);
+void receive_client_update_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
+ int vis_info_len);
+int vis_init(struct bat_priv *bat_priv);
+void vis_quit(struct bat_priv *bat_priv);
+
+#endif /* _NET_BATMAN_ADV_VIS_H_ */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index d1e433f7d673..250f954f0213 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/
obj-$(CONFIG_BT_HIDP) += hidp/
-bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
+bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index f10b41fb05a0..5868597534e5 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -648,6 +648,7 @@ int bnep_del_connection(struct bnep_conndel_req *req)
static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
{
+ memset(ci, 0, sizeof(*ci));
memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
strcpy(ci->device, s->dev->name);
ci->flags = s->flags;
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index ec0a1347f933..8e5f292529ac 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -78,6 +78,7 @@ static void __cmtp_unlink_session(struct cmtp_session *session)
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
{
+ memset(ci, 0, sizeof(*ci));
bacpy(&ci->bdaddr, &session->bdaddr);
ci->flags = session->flags;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0b1e460fe440..6b90a4191734 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn)
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
- if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
+ ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
+ if (ie) {
if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
cp.pscan_rep_mode = ie->data.pscan_rep_mode;
cp.pscan_mode = ie->data.pscan_mode;
@@ -368,8 +369,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
BT_DBG("%s dst %s", hdev->name, batostr(dst));
- if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
- if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
+ acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+ if (!acl) {
+ acl = hci_conn_add(hdev, ACL_LINK, dst);
+ if (!acl)
return NULL;
}
@@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (type == ACL_LINK)
return acl;
- if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
- if (!(sco = hci_conn_add(hdev, type, dst))) {
+ sco = hci_conn_hash_lookup_ba(hdev, type, dst);
+ if (!sco) {
+ sco = hci_conn_add(hdev, type, dst);
+ if (!sco) {
hci_conn_put(acl);
return NULL;
}
@@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg)
size = sizeof(req) + req.conn_num * sizeof(*ci);
- if (!(cl = kmalloc(size, GFP_KERNEL)))
+ cl = kmalloc(size, GFP_KERNEL);
+ if (!cl)
return -ENOMEM;
- if (!(hdev = hci_dev_get(req.dev_id))) {
+ hdev = hci_dev_get(req.dev_id);
+ if (!hdev) {
kfree(cl);
return -ENODEV;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bc2a052e518b..8b602d881fd7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -91,9 +91,16 @@ static void hci_notify(struct hci_dev *hdev, int event)
/* ---- HCI requests ---- */
-void hci_req_complete(struct hci_dev *hdev, int result)
+void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
{
- BT_DBG("%s result 0x%2.2x", hdev->name, result);
+ BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
+
+ /* If the request has set req_last_cmd (typical for multi-HCI
+ * command requests) check if the completed command matches
+ * this, and if not just return. Single HCI command requests
+ * typically leave req_last_cmd as 0 */
+ if (hdev->req_last_cmd && cmd != hdev->req_last_cmd)
+ return;
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
@@ -149,7 +156,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
break;
}
- hdev->req_status = hdev->req_result = 0;
+ hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0;
BT_DBG("%s end: err %d", hdev->name, err);
@@ -252,6 +259,8 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Connection accept timeout ~20 secs */
param = cpu_to_le16(0x7d00);
hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
+
+ hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT;
}
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -349,20 +358,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
{
struct inquiry_cache *cache = &hdev->inq_cache;
- struct inquiry_entry *e;
+ struct inquiry_entry *ie;
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
- if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) {
+ ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
+ if (!ie) {
/* Entry not in the cache. Add new one. */
- if (!(e = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
+ ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
+ if (!ie)
return;
- e->next = cache->list;
- cache->list = e;
+
+ ie->next = cache->list;
+ cache->list = ie;
}
- memcpy(&e->data, data, sizeof(*data));
- e->timestamp = jiffies;
+ memcpy(&ie->data, data, sizeof(*data));
+ ie->timestamp = jiffies;
cache->timestamp = jiffies;
}
@@ -422,16 +434,20 @@ int hci_inquiry(void __user *arg)
hci_dev_lock_bh(hdev);
if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
- inquiry_cache_empty(hdev) ||
- ir.flags & IREQ_CACHE_FLUSH) {
+ inquiry_cache_empty(hdev) ||
+ ir.flags & IREQ_CACHE_FLUSH) {
inquiry_cache_flush(hdev);
do_inquiry = 1;
}
hci_dev_unlock_bh(hdev);
timeo = ir.length * msecs_to_jiffies(2000);
- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
- goto done;
+
+ if (do_inquiry) {
+ err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
+ if (err < 0)
+ goto done;
+ }
/* for unlimited number of responses we will use buffer with 255 entries */
max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
@@ -439,7 +455,8 @@ int hci_inquiry(void __user *arg)
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
* copy it to the user space.
*/
- if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) {
+ buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL);
+ if (!buf) {
err = -ENOMEM;
goto done;
}
@@ -611,7 +628,8 @@ int hci_dev_close(__u16 dev)
struct hci_dev *hdev;
int err;
- if (!(hdev = hci_dev_get(dev)))
+ hdev = hci_dev_get(dev);
+ if (!hdev)
return -ENODEV;
err = hci_dev_do_close(hdev);
hci_dev_put(hdev);
@@ -623,7 +641,8 @@ int hci_dev_reset(__u16 dev)
struct hci_dev *hdev;
int ret = 0;
- if (!(hdev = hci_dev_get(dev)))
+ hdev = hci_dev_get(dev);
+ if (!hdev)
return -ENODEV;
hci_req_lock(hdev);
@@ -663,7 +682,8 @@ int hci_dev_reset_stat(__u16 dev)
struct hci_dev *hdev;
int ret = 0;
- if (!(hdev = hci_dev_get(dev)))
+ hdev = hci_dev_get(dev);
+ if (!hdev)
return -ENODEV;
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
@@ -682,7 +702,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
if (copy_from_user(&dr, arg, sizeof(dr)))
return -EFAULT;
- if (!(hdev = hci_dev_get(dr.dev_id)))
+ hdev = hci_dev_get(dr.dev_id);
+ if (!hdev)
return -ENODEV;
switch (cmd) {
@@ -763,7 +784,8 @@ int hci_get_dev_list(void __user *arg)
size = sizeof(*dl) + dev_num * sizeof(*dr);
- if (!(dl = kzalloc(size, GFP_KERNEL)))
+ dl = kzalloc(size, GFP_KERNEL);
+ if (!dl)
return -ENOMEM;
dr = dl->dev_req;
@@ -797,7 +819,8 @@ int hci_get_dev_info(void __user *arg)
if (copy_from_user(&di, arg, sizeof(di)))
return -EFAULT;
- if (!(hdev = hci_dev_get(di.dev_id)))
+ hdev = hci_dev_get(di.dev_id);
+ if (!hdev)
return -ENODEV;
strcpy(di.name, hdev->name);
@@ -905,7 +928,7 @@ int hci_register_dev(struct hci_dev *hdev)
hdev->sniff_max_interval = 800;
hdev->sniff_min_interval = 80;
- tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
+ tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
@@ -946,6 +969,7 @@ int hci_register_dev(struct hci_dev *hdev)
}
}
+ mgmt_index_added(hdev->id);
hci_notify(hdev, HCI_DEV_REG);
return id;
@@ -975,6 +999,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
for (i = 0; i < NUM_REASSEMBLY; i++)
kfree_skb(hdev->reassembly[i]);
+ mgmt_index_removed(hdev->id);
hci_notify(hdev, HCI_DEV_UNREG);
if (hdev->rfkill) {
@@ -1368,7 +1393,8 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
- if (!(list = skb_shinfo(skb)->frag_list)) {
+ list = skb_shinfo(skb)->frag_list;
+ if (!list) {
/* Non fragmented */
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
@@ -1609,7 +1635,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_enter_active_mode(conn);
/* Send to upper protocol */
- if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
+ hp = hci_proto[HCI_PROTO_L2CAP];
+ if (hp && hp->recv_acldata) {
hp->recv_acldata(conn, skb, flags);
return;
}
@@ -1644,7 +1671,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
register struct hci_proto *hp;
/* Send to upper protocol */
- if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
+ hp = hci_proto[HCI_PROTO_SCO];
+ if (hp && hp->recv_scodata) {
hp->recv_scodata(conn, skb);
return;
}
@@ -1727,7 +1755,8 @@ static void hci_cmd_task(unsigned long arg)
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
kfree_skb(hdev->sent_cmd);
- if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
+ hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
+ if (hdev->sent_cmd) {
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(skb);
hdev->cmd_last_tx = jiffies;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 84093b0000b9..38100170d380 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -39,7 +39,7 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -58,7 +58,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
hci_conn_check_pending(hdev);
}
@@ -174,7 +174,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *s
if (!status)
hdev->link_policy = get_unaligned_le16(sent);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
}
static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
@@ -183,7 +183,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_RESET, status);
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -235,7 +235,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_AUTH, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
}
static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -258,7 +258,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_ENCRYPT, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
}
static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
@@ -285,7 +285,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
set_bit(HCI_PSCAN, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
}
static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
@@ -383,7 +383,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
}
static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -536,7 +536,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
if (!rp->status)
bacpy(&hdev->bdaddr, &rp->bdaddr);
- hci_req_complete(hdev, rp->status);
+ hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
+}
+
+static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
}
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
@@ -544,7 +553,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
BT_DBG("%s status 0x%x", hdev->name, status);
if (status) {
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
} else
@@ -677,9 +686,50 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}
+static int hci_outgoing_auth_needed(struct hci_dev *hdev,
+ struct hci_conn *conn)
+{
+ if (conn->state != BT_CONFIG || !conn->out)
+ return 0;
+
+ if (conn->sec_level == BT_SECURITY_SDP)
+ return 0;
+
+ /* Only request authentication for SSP connections or non-SSP
+ * devices with sec_level HIGH */
+ if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
+ conn->sec_level != BT_SECURITY_HIGH)
+ return 0;
+
+ return 1;
+}
+
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
{
+ struct hci_cp_remote_name_req *cp;
+ struct hci_conn *conn;
+
BT_DBG("%s status 0x%x", hdev->name, status);
+
+ /* If successful wait for the name req complete event before
+ * checking for the need to do authentication */
+ if (!status)
+ return;
+
+ cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
+ if (!cp)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
+ if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ struct hci_cp_auth_requested cp;
+ cp.handle = __cpu_to_le16(conn->handle);
+ hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
+ }
+
+ hci_dev_unlock(hdev);
}
static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
@@ -830,7 +880,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
}
@@ -955,12 +1005,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_lock(hdev);
- if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
+ ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
+ if (ie)
memcpy(ie->data.dev_class, ev->dev_class, 3);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
- if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
+ conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
+ if (!conn) {
BT_ERR("No memory for new connection");
hci_dev_unlock(hdev);
return;
@@ -1090,9 +1142,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
+ struct hci_ev_remote_name *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
BT_DBG("%s", hdev->name);
hci_conn_check_pending(hdev);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ struct hci_cp_auth_requested cp;
+ cp.handle = __cpu_to_le16(conn->handle);
+ hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
+ }
+
+ hci_dev_unlock(hdev);
}
static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1162,33 +1228,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn) {
- if (!ev->status)
- memcpy(conn->features, ev->features, 8);
+ if (!conn)
+ goto unlock;
- if (conn->state == BT_CONFIG) {
- if (!ev->status && lmp_ssp_capable(hdev) &&
- lmp_ssp_capable(conn)) {
- struct hci_cp_read_remote_ext_features cp;
- cp.handle = ev->handle;
- cp.page = 0x01;
- hci_send_cmd(hdev,
- HCI_OP_READ_REMOTE_EXT_FEATURES,
- sizeof(cp), &cp);
- } else if (!ev->status && conn->out &&
- conn->sec_level == BT_SECURITY_HIGH) {
- struct hci_cp_auth_requested cp;
- cp.handle = ev->handle;
- hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
+ if (!ev->status)
+ memcpy(conn->features, ev->features, 8);
+
+ if (conn->state != BT_CONFIG)
+ goto unlock;
+
+ if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
+ struct hci_cp_read_remote_ext_features cp;
+ cp.handle = ev->handle;
+ cp.page = 0x01;
+ hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
sizeof(cp), &cp);
- } else {
- conn->state = BT_CONNECTED;
- hci_proto_connect_cfm(conn, ev->status);
- hci_conn_put(conn);
- }
- }
+ goto unlock;
+ }
+
+ if (!ev->status) {
+ struct hci_cp_remote_name_req cp;
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.bdaddr, &conn->dst);
+ cp.pscan_rep_mode = 0x02;
+ hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
+ }
+
+ if (!hci_outgoing_auth_needed(hdev, conn)) {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, ev->status);
+ hci_conn_put(conn);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1316,6 +1388,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_read_bd_addr(hdev, skb);
break;
+ case HCI_OP_WRITE_CA_TIMEOUT:
+ hci_cc_write_ca_timeout(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1449,10 +1525,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sent -= count;
if (conn->type == ACL_LINK) {
- if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+ hdev->acl_cnt += count;
+ if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
} else {
- if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+ hdev->sco_cnt += count;
+ if (hdev->sco_cnt > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
}
}
@@ -1547,7 +1625,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
if (conn && !ev->status) {
struct inquiry_entry *ie;
- if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
+ ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
+ if (ie) {
ie->data.clock_offset = ev->clock_offset;
ie->timestamp = jiffies;
}
@@ -1581,7 +1660,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
- if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
+ ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
+ if (ie) {
ie->data.pscan_rep_mode = ev->pscan_rep_mode;
ie->timestamp = jiffies;
}
@@ -1646,32 +1726,37 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn) {
- if (!ev->status && ev->page == 0x01) {
- struct inquiry_entry *ie;
+ if (!conn)
+ goto unlock;
- if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
- ie->data.ssp_mode = (ev->features[0] & 0x01);
+ if (!ev->status && ev->page == 0x01) {
+ struct inquiry_entry *ie;
- conn->ssp_mode = (ev->features[0] & 0x01);
- }
+ ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
+ if (ie)
+ ie->data.ssp_mode = (ev->features[0] & 0x01);
- if (conn->state == BT_CONFIG) {
- if (!ev->status && hdev->ssp_mode > 0 &&
- conn->ssp_mode > 0 && conn->out &&
- conn->sec_level != BT_SECURITY_SDP) {
- struct hci_cp_auth_requested cp;
- cp.handle = ev->handle;
- hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
- sizeof(cp), &cp);
- } else {
- conn->state = BT_CONNECTED;
- hci_proto_connect_cfm(conn, ev->status);
- hci_conn_put(conn);
- }
- }
+ conn->ssp_mode = (ev->features[0] & 0x01);
+ }
+
+ if (conn->state != BT_CONFIG)
+ goto unlock;
+
+ if (!ev->status) {
+ struct hci_cp_remote_name_req cp;
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.bdaddr, &conn->dst);
+ cp.pscan_rep_mode = 0x02;
+ hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
}
+ if (!hci_outgoing_auth_needed(hdev, conn)) {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, ev->status);
+ hci_conn_put(conn);
+ }
+
+unlock:
hci_dev_unlock(hdev);
}
@@ -1821,7 +1906,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_lock(hdev);
- if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
+ ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
+ if (ie)
ie->data.ssp_mode = (ev->features[0] & 0x01);
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 83acd164d39e..29827c77f6ce 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -43,12 +43,14 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+static int enable_mgmt;
+
/* ----- HCI socket interface ----- */
static inline int hci_test_bit(int nr, void *addr)
@@ -102,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (skb->sk == sk)
continue;
+ if (bt_cb(skb)->channel != hci_pi(sk)->channel)
+ continue;
+
+ if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
+ goto clone;
+
/* Apply filter */
flt = &hci_pi(sk)->filter;
@@ -125,11 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
continue;
}
- if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
+clone:
+ nskb = skb_clone(skb, GFP_ATOMIC);
+ if (!nskb)
continue;
/* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
+ if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
+ memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
@@ -352,25 +363,39 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
+ struct sockaddr_hci haddr;
struct sock *sk = sock->sk;
struct hci_dev *hdev = NULL;
- int err = 0;
+ int len, err = 0;
BT_DBG("sock %p sk %p", sock, sk);
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
+ if (!addr)
+ return -EINVAL;
+
+ memset(&haddr, 0, sizeof(haddr));
+ len = min_t(unsigned int, sizeof(haddr), addr_len);
+ memcpy(&haddr, addr, len);
+
+ if (haddr.hci_family != AF_BLUETOOTH)
+ return -EINVAL;
+
+ if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
+ return -EINVAL;
+
+ if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt)
return -EINVAL;
lock_sock(sk);
- if (hci_pi(sk)->hdev) {
+ if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
err = -EALREADY;
goto done;
}
- if (haddr->hci_dev != HCI_DEV_NONE) {
- if (!(hdev = hci_dev_get(haddr->hci_dev))) {
+ if (haddr.hci_dev != HCI_DEV_NONE) {
+ hdev = hci_dev_get(haddr.hci_dev);
+ if (!hdev) {
err = -ENODEV;
goto done;
}
@@ -378,6 +403,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
atomic_inc(&hdev->promisc);
}
+ hci_pi(sk)->channel = haddr.hci_channel;
hci_pi(sk)->hdev = hdev;
sk->sk_state = BT_BOUND;
@@ -457,7 +483,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_state == BT_CLOSED)
return 0;
- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
return err;
msg->msg_namelen = 0;
@@ -499,7 +526,19 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock(sk);
- if (!(hdev = hci_pi(sk)->hdev)) {
+ switch (hci_pi(sk)->channel) {
+ case HCI_CHANNEL_RAW:
+ break;
+ case HCI_CHANNEL_CONTROL:
+ err = mgmt_control(sk, msg, len);
+ goto done;
+ default:
+ err = -EINVAL;
+ goto done;
+ }
+
+ hdev = hci_pi(sk)->hdev;
+ if (!hdev) {
err = -EBADFD;
goto done;
}
@@ -509,7 +548,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto done;
}
- if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
+ skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
+ if (!skb)
goto done;
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
@@ -826,3 +866,6 @@ void __exit hci_sock_cleanup(void)
proto_unregister(&hci_sk_proto);
}
+
+module_param(enable_mgmt, bool, 0644);
+MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index c0ee8b3928ed..29544c21f4b5 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -107,6 +107,7 @@ static void __hidp_unlink_session(struct hidp_session *session)
static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
{
+ memset(ci, 0, sizeof(*ci));
bacpy(&ci->bdaddr, &session->bdaddr);
ci->flags = session->flags;
@@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin
ci->vendor = 0x0000;
ci->product = 0x0000;
ci->version = 0x0000;
- memset(ci->name, 0, 128);
if (session->input) {
ci->vendor = session->input->id.vendor;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index cd8f6ea03841..c791fcda7b2d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -57,7 +57,7 @@
#define VERSION "2.15"
-static int disable_ertm = 0;
+static int disable_ertm;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { 0x02, };
@@ -83,6 +83,18 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP timers ---- */
+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
+{
+ BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
+}
+
+static void l2cap_sock_clear_timer(struct sock *sk)
+{
+ BT_DBG("sock %p state %d", sk, sk->sk_state);
+ sk_stop_timer(sk, &sk->sk_timer);
+}
+
static void l2cap_sock_timeout(unsigned long arg)
{
struct sock *sk = (struct sock *) arg;
@@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg)
bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
+ /* sk is owned by user. Try again later */
+ l2cap_sock_set_timer(sk, HZ / 5);
+ bh_unlock_sock(sk);
+ sock_put(sk);
+ return;
+ }
+
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
reason = ECONNREFUSED;
else if (sk->sk_state == BT_CONNECT &&
@@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg)
sock_put(sk);
}
-static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-{
- BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
- sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
-}
-
-static void l2cap_sock_clear_timer(struct sock *sk)
-{
- BT_DBG("sock %p state %d", sk, sk->sk_state);
- sk_stop_timer(sk, &sk->sk_timer);
-}
-
/* ---- L2CAP channels ---- */
static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
{
@@ -743,11 +751,13 @@ found:
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
-static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
+static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
+ read_lock(&l2cap_sk_list.lock);
+
sk_for_each(sk, node, &l2cap_sk_list.head) {
if (state && sk->sk_state != state)
continue;
@@ -762,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
sk1 = sk;
}
}
- return node ? sk : sk1;
-}
-/* Find socket with given address (psm, src).
- * Returns locked socket */
-static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
-{
- struct sock *s;
- read_lock(&l2cap_sk_list.lock);
- s = __l2cap_get_sock_by_psm(state, psm, src);
- if (s)
- bh_lock_sock(s);
read_unlock(&l2cap_sk_list.lock);
- return s;
+
+ return node ? sk : sk1;
}
static void l2cap_sock_destruct(struct sock *sk)
@@ -2926,6 +2926,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto sendresp;
}
+ bh_lock_sock(parent);
+
/* Check if the ACL is secure enough (if not SDP) */
if (psm != cpu_to_le16(0x0001) &&
!hci_conn_check_link_mode(conn->hcon)) {
@@ -3078,6 +3080,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break;
default:
+ /* don't delete l2cap channel if sk is owned by user */
+ if (sock_owned_by_user(sk)) {
+ sk->sk_state = BT_DISCONN;
+ l2cap_sock_clear_timer(sk);
+ l2cap_sock_set_timer(sk, HZ / 5);
+ break;
+ }
+
l2cap_chan_del(sk, ECONNREFUSED);
break;
}
@@ -3114,8 +3124,14 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!sk)
return -ENOENT;
- if (sk->sk_state == BT_DISCONN)
+ if (sk->sk_state != BT_CONFIG) {
+ struct l2cap_cmd_rej rej;
+
+ rej.reason = cpu_to_le16(0x0002);
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
+ sizeof(rej), &rej);
goto unlock;
+ }
/* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req);
@@ -3283,6 +3299,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
sk->sk_shutdown = SHUTDOWN_MASK;
+ /* don't delete l2cap channel if sk is owned by user */
+ if (sock_owned_by_user(sk)) {
+ sk->sk_state = BT_DISCONN;
+ l2cap_sock_clear_timer(sk);
+ l2cap_sock_set_timer(sk, HZ / 5);
+ bh_unlock_sock(sk);
+ return 0;
+ }
+
l2cap_chan_del(sk, ECONNRESET);
bh_unlock_sock(sk);
@@ -3305,6 +3330,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
if (!sk)
return 0;
+ /* don't delete l2cap channel if sk is owned by user */
+ if (sock_owned_by_user(sk)) {
+ sk->sk_state = BT_DISCONN;
+ l2cap_sock_clear_timer(sk);
+ l2cap_sock_set_timer(sk, HZ / 5);
+ bh_unlock_sock(sk);
+ return 0;
+ }
+
l2cap_chan_del(sk, 0);
bh_unlock_sock(sk);
@@ -4134,11 +4168,10 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
__mod_retrans_timer();
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
l2cap_send_ack(pi);
- } else {
+ else
l2cap_ertm_send(sk);
- }
}
}
@@ -4430,6 +4463,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if (!sk)
goto drop;
+ bh_lock_sock(sk);
+
BT_DBG("sk %p, len %d", sk, skb->len);
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
@@ -4841,8 +4876,10 @@ static int __init l2cap_init(void)
return err;
_busy_wq = create_singlethread_workqueue("l2cap");
- if (!_busy_wq)
- goto error;
+ if (!_busy_wq) {
+ proto_unregister(&l2cap_proto);
+ return -ENOMEM;
+ }
err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
if (err < 0) {
@@ -4870,6 +4907,7 @@ static int __init l2cap_init(void)
return 0;
error:
+ destroy_workqueue(_busy_wq);
proto_unregister(&l2cap_proto);
return err;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
new file mode 100644
index 000000000000..f827fd908380
--- /dev/null
+++ b/net/bluetooth/mgmt.c
@@ -0,0 +1,308 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2010 Nokia Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ 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 OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+/* Bluetooth HCI Management interface */
+
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/mgmt.h>
+
+#define MGMT_VERSION 0
+#define MGMT_REVISION 1
+
+static int cmd_status(struct sock *sk, u16 cmd, u8 status)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_status *ev;
+
+ BT_DBG("sock %p", sk);
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
+ hdr->len = cpu_to_le16(sizeof(*ev));
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ ev->status = status;
+ put_unaligned_le16(cmd, &ev->opcode);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
+static int read_version(struct sock *sk)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_complete *ev;
+ struct mgmt_rp_read_version *rp;
+
+ BT_DBG("sock %p", sk);
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode);
+
+ rp = (void *) skb_put(skb, sizeof(*rp));
+ rp->version = MGMT_VERSION;
+ put_unaligned_le16(MGMT_REVISION, &rp->revision);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
+static int read_index_list(struct sock *sk)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_complete *ev;
+ struct mgmt_rp_read_index_list *rp;
+ struct list_head *p;
+ size_t body_len;
+ u16 count;
+ int i;
+
+ BT_DBG("sock %p", sk);
+
+ read_lock(&hci_dev_list_lock);
+
+ count = 0;
+ list_for_each(p, &hci_dev_list) {
+ count++;
+ }
+
+ body_len = sizeof(*ev) + sizeof(*rp) + (2 * count);
+ skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->len = cpu_to_le16(body_len);
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode);
+
+ rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count));
+ put_unaligned_le16(count, &rp->num_controllers);
+
+ i = 0;
+ list_for_each(p, &hci_dev_list) {
+ struct hci_dev *d = list_entry(p, struct hci_dev, list);
+ put_unaligned_le16(d->id, &rp->index[i++]);
+ BT_DBG("Added hci%u", d->id);
+ }
+
+ read_unlock(&hci_dev_list_lock);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
+static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_complete *ev;
+ struct mgmt_rp_read_info *rp;
+ struct mgmt_cp_read_info *cp;
+ struct hci_dev *hdev;
+ u16 dev_id;
+
+ BT_DBG("sock %p", sk);
+
+ if (len != 2)
+ return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode);
+
+ rp = (void *) skb_put(skb, sizeof(*rp));
+
+ cp = (void *) data;
+ dev_id = get_unaligned_le16(&cp->index);
+
+ BT_DBG("request for hci%u", dev_id);
+
+ hdev = hci_dev_get(dev_id);
+ if (!hdev) {
+ kfree_skb(skb);
+ return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
+ }
+
+ hci_dev_lock_bh(hdev);
+
+ put_unaligned_le16(hdev->id, &rp->index);
+ rp->type = hdev->dev_type;
+
+ rp->powered = test_bit(HCI_UP, &hdev->flags);
+ rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags);
+ rp->pairable = test_bit(HCI_PSCAN, &hdev->flags);
+
+ if (test_bit(HCI_AUTH, &hdev->flags))
+ rp->sec_mode = 3;
+ else if (hdev->ssp_mode > 0)
+ rp->sec_mode = 4;
+ else
+ rp->sec_mode = 2;
+
+ bacpy(&rp->bdaddr, &hdev->bdaddr);
+ memcpy(rp->features, hdev->features, 8);
+ memcpy(rp->dev_class, hdev->dev_class, 3);
+ put_unaligned_le16(hdev->manufacturer, &rp->manufacturer);
+ rp->hci_ver = hdev->hci_ver;
+ put_unaligned_le16(hdev->hci_rev, &rp->hci_rev);
+
+ hci_dev_unlock_bh(hdev);
+ hci_dev_put(hdev);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
+{
+ unsigned char *buf;
+ struct mgmt_hdr *hdr;
+ u16 opcode, len;
+ int err;
+
+ BT_DBG("got %zu bytes", msglen);
+
+ if (msglen < sizeof(*hdr))
+ return -EINVAL;
+
+ buf = kmalloc(msglen, GFP_ATOMIC);
+ if (!buf)
+ return -ENOMEM;
+
+ if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+ err = -EFAULT;
+ goto done;
+ }
+
+ hdr = (struct mgmt_hdr *) buf;
+ opcode = get_unaligned_le16(&hdr->opcode);
+ len = get_unaligned_le16(&hdr->len);
+
+ if (len != msglen - sizeof(*hdr)) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ switch (opcode) {
+ case MGMT_OP_READ_VERSION:
+ err = read_version(sk);
+ break;
+ case MGMT_OP_READ_INDEX_LIST:
+ err = read_index_list(sk);
+ break;
+ case MGMT_OP_READ_INFO:
+ err = read_controller_info(sk, buf + sizeof(*hdr), len);
+ break;
+ default:
+ BT_DBG("Unknown op %u", opcode);
+ err = cmd_status(sk, opcode, 0x01);
+ break;
+ }
+
+ if (err < 0)
+ goto done;
+
+ err = msglen;
+
+done:
+ kfree(buf);
+ return err;
+}
+
+static int mgmt_event(u16 event, void *data, u16 data_len)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+
+ skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(event);
+ hdr->len = cpu_to_le16(data_len);
+
+ memcpy(skb_put(skb, data_len), data, data_len);
+
+ hci_send_to_sock(NULL, skb);
+ kfree_skb(skb);
+
+ return 0;
+}
+
+int mgmt_index_added(u16 index)
+{
+ struct mgmt_ev_index_added ev;
+
+ put_unaligned_le16(index, &ev.index);
+
+ return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev));
+}
+
+int mgmt_index_removed(u16 index)
+{
+ struct mgmt_ev_index_added ev;
+
+ put_unaligned_le16(index, &ev.index);
+
+ return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev));
+}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index fa642aa652bd..ff8aaa736650 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -41,7 +41,7 @@
#include <linux/slab.h>
#include <net/sock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -51,10 +51,10 @@
#define VERSION "1.11"
-static int disable_cfc = 0;
+static int disable_cfc;
+static int l2cap_ertm;
static int channel_mtu = -1;
static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
-static int l2cap_ertm = 0;
static struct task_struct *rfcomm_thread;
@@ -311,6 +311,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
d->state = BT_OPEN;
d->flags = 0;
d->mscex = 0;
+ d->sec_level = BT_SECURITY_LOW;
d->mtu = RFCOMM_DEFAULT_MTU;
d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
@@ -1901,7 +1902,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
BT_DBG("%p state %ld", s, s->state);
- switch(sk->sk_state) {
+ switch (sk->sk_state) {
case BT_CONNECTED:
s->state = BT_CONNECT;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index aec505f934df..66cc1f0c3df8 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -45,7 +45,7 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
* Returns closest match.
*/
-static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
+static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
+ read_lock(&rfcomm_sk_list.lock);
+
sk_for_each(sk, node, &rfcomm_sk_list.head) {
if (state && sk->sk_state != state)
continue;
@@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
sk1 = sk;
}
}
- return node ? sk : sk1;
-}
-/* Find socket with given address (channel, src).
- * Returns locked socket */
-static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-{
- struct sock *s;
- read_lock(&rfcomm_sk_list.lock);
- s = __rfcomm_get_sock_by_channel(state, channel, src);
- if (s) bh_lock_sock(s);
read_unlock(&rfcomm_sk_list.lock);
- return s;
+
+ return node ? sk : sk1;
}
static void rfcomm_sock_destruct(struct sock *sk)
@@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
BT_DBG("sock %p, sk %p", sock, sk);
- if (!sk) return 0;
+ if (!sk)
+ return 0;
lock_sock(sk);
if (!sk->sk_shutdown) {
@@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if (!parent)
return 0;
+ bh_lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index a9b81f5dacd1..2575c2db6404 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -58,9 +58,9 @@ struct rfcomm_dev {
bdaddr_t src;
bdaddr_t dst;
- u8 channel;
+ u8 channel;
- uint modem_status;
+ uint modem_status;
struct rfcomm_dlc *dlc;
struct tty_struct *tty;
@@ -69,7 +69,7 @@ struct rfcomm_dev {
struct device *tty_dev;
- atomic_t wmem_alloc;
+ atomic_t wmem_alloc;
struct sk_buff_head pending;
};
@@ -431,7 +431,8 @@ static int rfcomm_release_dev(void __user *arg)
BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
- if (!(dev = rfcomm_dev_get(req.dev_id)))
+ dev = rfcomm_dev_get(req.dev_id);
+ if (!dev)
return -ENODEV;
if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
@@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg)
size = sizeof(*dl) + dev_num * sizeof(*di);
- if (!(dl = kmalloc(size, GFP_KERNEL)))
+ dl = kmalloc(size, GFP_KERNEL);
+ if (!dl)
return -ENOMEM;
di = dl->dev_info;
@@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg)
if (copy_from_user(&di, arg, sizeof(di)))
return -EFAULT;
- if (!(dev = rfcomm_dev_get(di.id)))
+ dev = rfcomm_dev_get(di.id);
+ if (!dev)
return -ENODEV;
di.flags = dev->flags;
@@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
return;
}
- if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) {
+ tty = dev->tty;
+ if (!tty || !skb_queue_empty(&dev->pending)) {
skb_queue_tail(&dev->pending, skb);
return;
}
@@ -796,7 +800,8 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
memcpy(skb_put(skb, size), buf + sent, size);
- if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
+ err = rfcomm_dlc_send(dlc, skb);
+ if (err < 0) {
kfree_skb(skb);
break;
}
@@ -892,7 +897,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
/* Parity on/off and when on, odd/even */
if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
- ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
+ ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
changes |= RFCOMM_RPN_PM_PARITY;
BT_DBG("Parity change detected.");
}
@@ -937,11 +942,10 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
/* POSIX does not support 1.5 stop bits and RFCOMM does not
* support 2 stop bits. So a request for 2 stop bits gets
* translated to 1.5 stop bits */
- if (new->c_cflag & CSTOPB) {
+ if (new->c_cflag & CSTOPB)
stop_bits = RFCOMM_RPN_STOP_15;
- } else {
+ else
stop_bits = RFCOMM_RPN_STOP_1;
- }
/* Handle number of data bits [5-8] */
if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index d0927d1fdada..960c6d1637da 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -44,7 +44,7 @@
#include <net/sock.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -52,7 +52,7 @@
#define VERSION "0.6"
-static int disable_esco = 0;
+static int disable_esco;
static const struct proto_ops sco_sock_ops;
@@ -138,16 +138,17 @@ static inline struct sock *sco_chan_get(struct sco_conn *conn)
static int sco_conn_del(struct hci_conn *hcon, int err)
{
- struct sco_conn *conn;
+ struct sco_conn *conn = hcon->sco_data;
struct sock *sk;
- if (!(conn = hcon->sco_data))
+ if (!conn)
return 0;
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
/* Kill socket */
- if ((sk = sco_chan_get(conn))) {
+ sk = sco_chan_get(conn);
+ if (sk) {
bh_lock_sock(sk);
sco_sock_clear_timer(sk);
sco_chan_del(sk, err);
@@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk)
BT_DBG("%s -> %s", batostr(src), batostr(dst));
- if (!(hdev = hci_get_route(dst, src)))
+ hdev = hci_get_route(dst, src);
+ if (!hdev)
return -EHOSTUNREACH;
hci_dev_lock_bh(hdev);
@@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
- if ((err = sco_connect(sk)))
+ err = sco_connect(sk);
+ if (err)
goto done;
err = bt_sock_wait_state(sk, BT_CONNECTED,
@@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err)
static void sco_conn_ready(struct sco_conn *conn)
{
- struct sock *parent, *sk;
+ struct sock *parent;
+ struct sock *sk = conn->sk;
BT_DBG("conn %p", conn);
sco_conn_lock(conn);
- if ((sk = conn->sk)) {
+ if (sk) {
sco_sock_clear_timer(sk);
bh_lock_sock(sk);
sk->sk_state = BT_CONNECTED;
@@ -882,7 +886,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
int lm = 0;
if (type != SCO_LINK && type != ESCO_LINK)
- return 0;
+ return -EINVAL;
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
@@ -908,7 +912,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
if (!status) {
struct sco_conn *conn;
@@ -927,7 +931,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
BT_DBG("hcon %p reason %d", hcon, reason);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
sco_conn_del(hcon, bt_err(reason));
diff --git a/net/bridge/br.c b/net/bridge/br.c
index c8436fa31344..84bbb82599b2 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -22,8 +22,6 @@
#include "br_private.h"
-int (*br_should_route_hook)(struct sk_buff *skb);
-
static const struct stp_proto br_stp_proto = {
.rcv = br_stp_rcv,
};
@@ -102,8 +100,6 @@ static void __exit br_deinit(void)
br_fdb_fini();
}
-EXPORT_SYMBOL(br_should_route_hook);
-
module_init(br_init)
module_exit(br_deinit)
MODULE_LICENSE("GPL");
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 17cb0b633576..556443566e9c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -141,7 +141,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
#ifdef CONFIG_BRIDGE_NETFILTER
/* remember the MTU in the rtable for PMTU */
- br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu;
+ dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
#endif
return 0;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 90512ccfd3e9..2872393b2939 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -238,15 +238,18 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
{
struct net_bridge_fdb_entry *fdb;
+ struct net_bridge_port *port;
int ret;
- if (!br_port_exists(dev))
- return 0;
-
rcu_read_lock();
- fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr);
- ret = fdb && fdb->dst->dev != dev &&
- fdb->dst->state == BR_STATE_FORWARDING;
+ port = br_port_get_rcu(dev);
+ if (!port)
+ ret = 0;
+ else {
+ fdb = __br_fdb_get(port->br, addr);
+ ret = fdb && fdb->dst->dev != dev &&
+ fdb->dst->state == BR_STATE_FORWARDING;
+ }
rcu_read_unlock();
return ret;
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index cbfe87f0f34a..2bd11ec6d166 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -223,7 +223,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
struct net_bridge_port_group *p;
struct hlist_node *rp;
- rp = rcu_dereference(br->router_list.first);
+ rp = rcu_dereference(hlist_first_rcu(&br->router_list));
p = mdst ? rcu_dereference(mdst->ports) : NULL;
while (p || rp) {
struct net_bridge_port *port, *lport, *rport;
@@ -242,7 +242,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
if ((unsigned long)lport >= (unsigned long)port)
p = rcu_dereference(p->next);
if ((unsigned long)rport >= (unsigned long)port)
- rp = rcu_dereference(rp->next);
+ rp = rcu_dereference(hlist_next_rcu(rp));
}
if (!prev)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 89ad25a76202..d9d1e2bac1d6 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -475,11 +475,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
{
struct net_bridge_port *p;
- if (!br_port_exists(dev))
- return -EINVAL;
-
- p = br_port_get(dev);
- if (p->br != br)
+ p = br_port_get_rtnl(dev);
+ if (!p || p->br != br)
return -EINVAL;
del_nbp(p);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 25207a1f182b..6f6d8e1b776f 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -21,6 +21,10 @@
/* Bridge group multicast address 802.1d (pg 51). */
const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
+/* Hook for brouter */
+br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
+EXPORT_SYMBOL(br_should_route_hook);
+
static int br_pass_frame_up(struct sk_buff *skb)
{
struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
@@ -139,7 +143,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
{
struct net_bridge_port *p;
const unsigned char *dest = eth_hdr(skb)->h_dest;
- int (*rhook)(struct sk_buff *skb);
+ br_should_route_hook_t *rhook;
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
return skb;
@@ -173,8 +177,8 @@ forward:
switch (p->state) {
case BR_STATE_FORWARDING:
rhook = rcu_dereference(br_should_route_hook);
- if (rhook != NULL) {
- if (rhook(skb))
+ if (rhook) {
+ if ((*rhook)(skb))
return skb;
dest = eth_hdr(skb)->h_dest;
}
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index eb5b256ffc88..f701a21acb34 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -33,6 +33,9 @@
#include "br_private.h"
+#define mlock_dereference(X, br) \
+ rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static inline int ipv6_is_local_multicast(const struct in6_addr *addr)
{
@@ -135,7 +138,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get(
struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
struct sk_buff *skb)
{
- struct net_bridge_mdb_htable *mdb = br->mdb;
+ struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
struct br_ip ip;
if (br->multicast_disabled)
@@ -235,7 +238,8 @@ static void br_multicast_group_expired(unsigned long data)
if (mp->ports)
goto out;
- mdb = br->mdb;
+ mdb = mlock_dereference(br->mdb, br);
+
hlist_del_rcu(&mp->hlist[mdb->ver]);
mdb->size--;
@@ -249,16 +253,20 @@ out:
static void br_multicast_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg)
{
- struct net_bridge_mdb_htable *mdb = br->mdb;
+ struct net_bridge_mdb_htable *mdb;
struct net_bridge_mdb_entry *mp;
struct net_bridge_port_group *p;
- struct net_bridge_port_group **pp;
+ struct net_bridge_port_group __rcu **pp;
+
+ mdb = mlock_dereference(br->mdb, br);
mp = br_mdb_ip_get(mdb, &pg->addr);
if (WARN_ON(!mp))
return;
- for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+ for (pp = &mp->ports;
+ (p = mlock_dereference(*pp, br)) != NULL;
+ pp = &p->next) {
if (p != pg)
continue;
@@ -294,10 +302,10 @@ out:
spin_unlock(&br->multicast_lock);
}
-static int br_mdb_rehash(struct net_bridge_mdb_htable **mdbp, int max,
+static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max,
int elasticity)
{
- struct net_bridge_mdb_htable *old = *mdbp;
+ struct net_bridge_mdb_htable *old = rcu_dereference_protected(*mdbp, 1);
struct net_bridge_mdb_htable *mdb;
int err;
@@ -437,7 +445,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
ip6h = ipv6_hdr(skb);
*(__force __be32 *)ip6h = htonl(0x60000000);
- ip6h->payload_len = 8 + sizeof(*mldq);
+ ip6h->payload_len = htons(8 + sizeof(*mldq));
ip6h->nexthdr = IPPROTO_HOPOPTS;
ip6h->hop_limit = 1;
ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0);
@@ -569,7 +577,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group(
struct net_bridge *br, struct net_bridge_port *port,
struct br_ip *group, int hash)
{
- struct net_bridge_mdb_htable *mdb = br->mdb;
+ struct net_bridge_mdb_htable *mdb;
struct net_bridge_mdb_entry *mp;
struct hlist_node *p;
unsigned count = 0;
@@ -577,6 +585,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group(
int elasticity;
int err;
+ mdb = rcu_dereference_protected(br->mdb, 1);
hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
count++;
if (unlikely(br_ip_equal(group, &mp->addr)))
@@ -642,13 +651,16 @@ static struct net_bridge_mdb_entry *br_multicast_new_group(
struct net_bridge *br, struct net_bridge_port *port,
struct br_ip *group)
{
- struct net_bridge_mdb_htable *mdb = br->mdb;
+ struct net_bridge_mdb_htable *mdb;
struct net_bridge_mdb_entry *mp;
int hash;
+ int err;
+ mdb = rcu_dereference_protected(br->mdb, 1);
if (!mdb) {
- if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0))
- return NULL;
+ err = br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0);
+ if (err)
+ return ERR_PTR(err);
goto rehash;
}
@@ -660,7 +672,7 @@ static struct net_bridge_mdb_entry *br_multicast_new_group(
case -EAGAIN:
rehash:
- mdb = br->mdb;
+ mdb = rcu_dereference_protected(br->mdb, 1);
hash = br_ip_hash(mdb, group);
break;
@@ -670,7 +682,7 @@ rehash:
mp = kzalloc(sizeof(*mp), GFP_ATOMIC);
if (unlikely(!mp))
- goto out;
+ return ERR_PTR(-ENOMEM);
mp->br = br;
mp->addr = *group;
@@ -692,7 +704,7 @@ static int br_multicast_add_group(struct net_bridge *br,
{
struct net_bridge_mdb_entry *mp;
struct net_bridge_port_group *p;
- struct net_bridge_port_group **pp;
+ struct net_bridge_port_group __rcu **pp;
unsigned long now = jiffies;
int err;
@@ -703,7 +715,7 @@ static int br_multicast_add_group(struct net_bridge *br,
mp = br_multicast_new_group(br, port, group);
err = PTR_ERR(mp);
- if (unlikely(IS_ERR(mp) || !mp))
+ if (IS_ERR(mp))
goto err;
if (!port) {
@@ -712,7 +724,9 @@ static int br_multicast_add_group(struct net_bridge *br,
goto out;
}
- for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+ for (pp = &mp->ports;
+ (p = mlock_dereference(*pp, br)) != NULL;
+ pp = &p->next) {
if (p->port == port)
goto found;
if ((unsigned long)p->port < (unsigned long)port)
@@ -1106,7 +1120,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
struct net_bridge_mdb_entry *mp;
struct igmpv3_query *ih3;
struct net_bridge_port_group *p;
- struct net_bridge_port_group **pp;
+ struct net_bridge_port_group __rcu **pp;
unsigned long max_delay;
unsigned long now = jiffies;
__be32 group;
@@ -1145,7 +1159,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
if (!group)
goto out;
- mp = br_mdb_ip4_get(br->mdb, group);
+ mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group);
if (!mp)
goto out;
@@ -1157,7 +1171,9 @@ static int br_ip4_multicast_query(struct net_bridge *br,
try_to_del_timer_sync(&mp->timer) >= 0))
mod_timer(&mp->timer, now + max_delay);
- for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+ for (pp = &mp->ports;
+ (p = mlock_dereference(*pp, br)) != NULL;
+ pp = &p->next) {
if (timer_pending(&p->timer) ?
time_after(p->timer.expires, now + max_delay) :
try_to_del_timer_sync(&p->timer) >= 0)
@@ -1178,7 +1194,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb);
struct net_bridge_mdb_entry *mp;
struct mld2_query *mld2q;
- struct net_bridge_port_group *p, **pp;
+ struct net_bridge_port_group *p;
+ struct net_bridge_port_group __rcu **pp;
unsigned long max_delay;
unsigned long now = jiffies;
struct in6_addr *group = NULL;
@@ -1214,7 +1231,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
if (!group)
goto out;
- mp = br_mdb_ip6_get(br->mdb, group);
+ mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group);
if (!mp)
goto out;
@@ -1225,7 +1242,9 @@ static int br_ip6_multicast_query(struct net_bridge *br,
try_to_del_timer_sync(&mp->timer) >= 0))
mod_timer(&mp->timer, now + max_delay);
- for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+ for (pp = &mp->ports;
+ (p = mlock_dereference(*pp, br)) != NULL;
+ pp = &p->next) {
if (timer_pending(&p->timer) ?
time_after(p->timer.expires, now + max_delay) :
try_to_del_timer_sync(&p->timer) >= 0)
@@ -1254,7 +1273,7 @@ static void br_multicast_leave_group(struct net_bridge *br,
timer_pending(&br->multicast_querier_timer))
goto out;
- mdb = br->mdb;
+ mdb = mlock_dereference(br->mdb, br);
mp = br_mdb_ip_get(mdb, group);
if (!mp)
goto out;
@@ -1277,7 +1296,9 @@ static void br_multicast_leave_group(struct net_bridge *br,
goto out;
}
- for (p = mp->ports; p; p = p->next) {
+ for (p = mlock_dereference(mp->ports, br);
+ p != NULL;
+ p = mlock_dereference(p->next, br)) {
if (p->port != port)
continue;
@@ -1430,7 +1451,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
struct net_bridge_port *port,
struct sk_buff *skb)
{
- struct sk_buff *skb2 = skb;
+ struct sk_buff *skb2;
struct ipv6hdr *ip6h;
struct icmp6hdr *icmp6h;
u8 nexthdr;
@@ -1469,15 +1490,15 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
if (!skb2)
return -ENOMEM;
+ err = -EINVAL;
+ if (!pskb_may_pull(skb2, offset + sizeof(struct icmp6hdr)))
+ goto out;
+
len -= offset - skb_network_offset(skb2);
__skb_pull(skb2, offset);
skb_reset_transport_header(skb2);
- err = -EINVAL;
- if (!pskb_may_pull(skb2, sizeof(*icmp6h)))
- goto out;
-
icmp6h = icmp6_hdr(skb2);
switch (icmp6h->icmp6_type) {
@@ -1516,7 +1537,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
switch (icmp6h->icmp6_type) {
case ICMPV6_MGM_REPORT:
{
- struct mld_msg *mld = (struct mld_msg *)icmp6h;
+ struct mld_msg *mld;
+ if (!pskb_may_pull(skb2, sizeof(*mld))) {
+ err = -EINVAL;
+ goto out;
+ }
+ mld = (struct mld_msg *)skb_transport_header(skb2);
BR_INPUT_SKB_CB(skb2)->mrouters_only = 1;
err = br_ip6_multicast_add_group(br, port, &mld->mld_mca);
break;
@@ -1529,15 +1555,18 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
break;
case ICMPV6_MGM_REDUCTION:
{
- struct mld_msg *mld = (struct mld_msg *)icmp6h;
+ struct mld_msg *mld;
+ if (!pskb_may_pull(skb2, sizeof(*mld))) {
+ err = -EINVAL;
+ goto out;
+ }
+ mld = (struct mld_msg *)skb_transport_header(skb2);
br_ip6_multicast_leave_group(br, port, &mld->mld_mca);
}
}
out:
- __skb_push(skb2, offset);
- if (skb2 != skb)
- kfree_skb(skb2);
+ kfree_skb(skb2);
return err;
}
#endif
@@ -1625,7 +1654,7 @@ void br_multicast_stop(struct net_bridge *br)
del_timer_sync(&br->multicast_query_timer);
spin_lock_bh(&br->multicast_lock);
- mdb = br->mdb;
+ mdb = mlock_dereference(br->mdb, br);
if (!mdb)
goto out;
@@ -1729,6 +1758,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
{
struct net_bridge_port *port;
int err = 0;
+ struct net_bridge_mdb_htable *mdb;
spin_lock(&br->multicast_lock);
if (br->multicast_disabled == !val)
@@ -1741,15 +1771,16 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
if (!netif_running(br->dev))
goto unlock;
- if (br->mdb) {
- if (br->mdb->old) {
+ mdb = mlock_dereference(br->mdb, br);
+ if (mdb) {
+ if (mdb->old) {
err = -EEXIST;
rollback:
br->multicast_disabled = !!val;
goto unlock;
}
- err = br_mdb_rehash(&br->mdb, br->mdb->max,
+ err = br_mdb_rehash(&br->mdb, mdb->max,
br->hash_elasticity);
if (err)
goto rollback;
@@ -1774,6 +1805,7 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val)
{
int err = -ENOENT;
u32 old;
+ struct net_bridge_mdb_htable *mdb;
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev))
@@ -1782,7 +1814,9 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val)
err = -EINVAL;
if (!is_power_of_2(val))
goto unlock;
- if (br->mdb && val < br->mdb->size)
+
+ mdb = mlock_dereference(br->mdb, br);
+ if (mdb && val < mdb->size)
goto unlock;
err = 0;
@@ -1790,8 +1824,8 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val)
old = br->hash_max;
br->hash_max = val;
- if (br->mdb) {
- if (br->mdb->old) {
+ if (mdb) {
+ if (mdb->old) {
err = -EEXIST;
rollback:
br->hash_max = old;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 865fd7634b67..4b5b66d07bba 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -124,24 +124,25 @@ void br_netfilter_rtable_init(struct net_bridge *br)
atomic_set(&rt->dst.__refcnt, 1);
rt->dst.dev = br->dev;
rt->dst.path = &rt->dst;
- rt->dst.metrics[RTAX_MTU - 1] = 1500;
+ dst_metric_set(&rt->dst, RTAX_MTU, 1500);
rt->dst.flags = DST_NOXFRM;
rt->dst.ops = &fake_dst_ops;
}
static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
{
- if (!br_port_exists(dev))
- return NULL;
- return &br_port_get_rcu(dev)->br->fake_rtable;
+ struct net_bridge_port *port;
+
+ port = br_port_get_rcu(dev);
+ return port ? &port->br->fake_rtable : NULL;
}
static inline struct net_device *bridge_parent(const struct net_device *dev)
{
- if (!br_port_exists(dev))
- return NULL;
+ struct net_bridge_port *port;
- return br_port_get_rcu(dev)->br->dev;
+ port = br_port_get_rcu(dev);
+ return port ? port->br->dev : NULL;
}
static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
@@ -412,13 +413,8 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
if (dnat_took_place(skb)) {
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .saddr = 0,
- .tos = RT_TOS(iph->tos) },
- },
- .proto = 0,
+ .fl4_dst = iph->daddr,
+ .fl4_tos = RT_TOS(iph->tos),
};
struct in_device *in_dev = __in_dev_get_rcu(dev);
@@ -566,26 +562,26 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
u32 pkt_len;
if (skb->len < sizeof(struct ipv6hdr))
- goto inhdr_error;
+ return NF_DROP;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
- goto inhdr_error;
+ return NF_DROP;
hdr = ipv6_hdr(skb);
if (hdr->version != 6)
- goto inhdr_error;
+ return NF_DROP;
pkt_len = ntohs(hdr->payload_len);
if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
- goto inhdr_error;
+ return NF_DROP;
if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
- goto inhdr_error;
+ return NF_DROP;
}
if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
- goto inhdr_error;
+ return NF_DROP;
nf_bridge_put(skb->nf_bridge);
if (!nf_bridge_alloc(skb))
@@ -598,9 +594,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
br_nf_pre_routing_finish_ipv6);
return NF_STOLEN;
-
-inhdr_error:
- return NF_DROP;
}
/* Direct IPv6 traffic to br_nf_pre_routing_ipv6.
@@ -619,11 +612,11 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
__u32 len = nf_bridge_encap_header_len(skb);
if (unlikely(!pskb_may_pull(skb, len)))
- goto out;
+ return NF_DROP;
p = br_port_get_rcu(in);
if (p == NULL)
- goto out;
+ return NF_DROP;
br = p->br;
if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
@@ -645,8 +638,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
nf_bridge_pull_encap_header_rcsum(skb);
if (br_parse_ip_options(skb))
- /* Drop invalid packet */
- goto out;
+ return NF_DROP;
nf_bridge_put(skb->nf_bridge);
if (!nf_bridge_alloc(skb))
@@ -660,9 +652,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
br_nf_pre_routing_finish);
return NF_STOLEN;
-
-out:
- return NF_DROP;
}
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 4a6a378c84e3..f8bf4c7f842c 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -119,11 +119,13 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
idx = 0;
for_each_netdev(net, dev) {
+ struct net_bridge_port *port = br_port_get_rtnl(dev);
+
/* not a bridge port */
- if (!br_port_exists(dev) || idx < cb->args[0])
+ if (!port || idx < cb->args[0])
goto skip;
- if (br_fill_ifinfo(skb, br_port_get(dev),
+ if (br_fill_ifinfo(skb, port,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWLINK,
NLM_F_MULTI) < 0)
@@ -169,9 +171,9 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (!dev)
return -ENODEV;
- if (!br_port_exists(dev))
+ p = br_port_get_rtnl(dev);
+ if (!p)
return -EINVAL;
- p = br_port_get(dev);
/* if kernel STP is running, don't allow changes */
if (p->br->stp_enabled == BR_KERNEL_STP)
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 404d4e14c6a7..7d337c9b6082 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -32,15 +32,15 @@ struct notifier_block br_device_notifier = {
static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
- struct net_bridge_port *p = br_port_get(dev);
+ struct net_bridge_port *p;
struct net_bridge *br;
int err;
/* not a port of a bridge */
- if (!br_port_exists(dev))
+ p = br_port_get_rtnl(dev);
+ if (!p)
return NOTIFY_DONE;
- p = br_port_get(dev);
br = p->br;
switch (event) {
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 75c90edaf7db..84aac7734bfc 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -72,7 +72,7 @@ struct net_bridge_fdb_entry
struct net_bridge_port_group {
struct net_bridge_port *port;
- struct net_bridge_port_group *next;
+ struct net_bridge_port_group __rcu *next;
struct hlist_node mglist;
struct rcu_head rcu;
struct timer_list timer;
@@ -86,7 +86,7 @@ struct net_bridge_mdb_entry
struct hlist_node hlist[2];
struct hlist_node mglist;
struct net_bridge *br;
- struct net_bridge_port_group *ports;
+ struct net_bridge_port_group __rcu *ports;
struct rcu_head rcu;
struct timer_list timer;
struct timer_list query_timer;
@@ -151,11 +151,20 @@ struct net_bridge_port
#endif
};
-#define br_port_get_rcu(dev) \
- ((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data))
-#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
+static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
+{
+ struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data);
+ return br_port_exists(dev) ? port : NULL;
+}
+
+static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev)
+{
+ return br_port_exists(dev) ?
+ rtnl_dereference(dev->rx_handler_data) : NULL;
+}
+
struct br_cpu_netstats {
u64 rx_packets;
u64 rx_bytes;
@@ -227,7 +236,7 @@ struct net_bridge
unsigned long multicast_startup_query_interval;
spinlock_t multicast_lock;
- struct net_bridge_mdb_htable *mdb;
+ struct net_bridge_mdb_htable __rcu *mdb;
struct hlist_head router_list;
struct hlist_head mglist;
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 35cf27087b56..289646ec9b7b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -50,6 +50,8 @@ static void br_send_bpdu(struct net_bridge_port *p,
llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
+ skb_reset_mac_header(skb);
+
NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
}
@@ -141,10 +143,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
struct net_bridge *br;
const unsigned char *buf;
- if (!br_port_exists(dev))
- goto err;
- p = br_port_get_rcu(dev);
-
if (!pskb_may_pull(skb, 4))
goto err;
@@ -153,6 +151,10 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0)
goto err;
+ p = br_port_get_rcu(dev);
+ if (!p)
+ goto err;
+
br = p->br;
spin_lock(&br->lock);
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 1d8826914cbf..79372d4a4055 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -145,7 +145,7 @@ static void br_stp_stop(struct net_bridge *br)
char *envp[] = { NULL };
if (br->stp_enabled == BR_USER_STP) {
- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
br_info(br, "userspace STP stopped, return code %d\n", r);
/* To start timers on any ports left in blocking */
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index ae3f106c3908..1bcaf36ad612 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -87,7 +87,8 @@ static int __init ebtable_broute_init(void)
if (ret < 0)
return ret;
/* see br_input.c */
- rcu_assign_pointer(br_should_route_hook, ebt_broute);
+ rcu_assign_pointer(br_should_route_hook,
+ (br_should_route_hook_t *)ebt_broute);
return 0;
}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index a1dcf83f0d58..16df0532d4b9 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -128,6 +128,7 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out)
{
const struct ethhdr *h = eth_hdr(skb);
+ const struct net_bridge_port *p;
__be16 ethproto;
int verdict, i;
@@ -148,13 +149,11 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
return 1;
/* rcu_read_lock()ed by nf_hook_slow */
- if (in && br_port_exists(in) &&
- FWINV2(ebt_dev_check(e->logical_in, br_port_get_rcu(in)->br->dev),
- EBT_ILOGICALIN))
+ if (in && (p = br_port_get_rcu(in)) != NULL &&
+ FWINV2(ebt_dev_check(e->logical_in, p->br->dev), EBT_ILOGICALIN))
return 1;
- if (out && br_port_exists(out) &&
- FWINV2(ebt_dev_check(e->logical_out, br_port_get_rcu(out)->br->dev),
- EBT_ILOGICALOUT))
+ if (out && (p = br_port_get_rcu(out)) != NULL &&
+ FWINV2(ebt_dev_check(e->logical_out, p->br->dev), EBT_ILOGICALOUT))
return 1;
if (e->bitmask & EBT_SOURCEMAC) {
@@ -1148,7 +1147,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table)
void *p;
if (input_table == NULL || (repl = input_table->table) == NULL ||
- repl->entries == 0 || repl->entries_size == 0 ||
+ repl->entries == NULL || repl->entries_size == 0 ||
repl->counters != NULL || input_table->private != NULL) {
BUGPRINT("Bad table data for ebt_register_table!!!\n");
return ERR_PTR(-EINVAL);
diff --git a/net/caif/Makefile b/net/caif/Makefile
index f87481fb0e65..9d38e406e4a4 100644
--- a/net/caif/Makefile
+++ b/net/caif/Makefile
@@ -1,8 +1,6 @@
-ifeq ($(CONFIG_CAIF_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
-caif-objs := caif_dev.o \
+caif-y := caif_dev.o \
cfcnfg.o cfmuxl.o cfctrl.o \
cffrml.o cfveil.o cfdbgl.o\
cfserl.o cfdgml.o \
@@ -13,4 +11,4 @@ obj-$(CONFIG_CAIF) += caif.o
obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
obj-$(CONFIG_CAIF) += caif_socket.o
-export-objs := caif.o
+export-y := caif.o
diff --git a/net/can/Makefile b/net/can/Makefile
index 9cd3c4b3abda..2d3894b32742 100644
--- a/net/can/Makefile
+++ b/net/can/Makefile
@@ -3,10 +3,10 @@
#
obj-$(CONFIG_CAN) += can.o
-can-objs := af_can.o proc.o
+can-y := af_can.o proc.o
obj-$(CONFIG_CAN_RAW) += can-raw.o
-can-raw-objs := raw.o
+can-raw-y := raw.o
obj-$(CONFIG_CAN_BCM) += can-bcm.o
-can-bcm-objs := bcm.o
+can-bcm-y := bcm.o
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 6faa8256e10c..9d5e8accfab1 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -125,7 +125,7 @@ struct bcm_sock {
struct list_head tx_ops;
unsigned long dropped_usr_msgs;
struct proc_dir_entry *bcm_proc_read;
- char procname [20]; /* pointer printed in ASCII with \0 */
+ char procname [32]; /* inode number in decimal with \0 */
};
static inline struct bcm_sock *bcm_sk(const struct sock *sk)
@@ -1521,7 +1521,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
if (proc_dir) {
/* unique socket address as filename */
- sprintf(bo->procname, "%p", sock);
+ sprintf(bo->procname, "%lu", sock_i_ino(sk));
bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
proc_dir,
&bcm_proc_fops, sk);
diff --git a/net/ceph/Makefile b/net/ceph/Makefile
index 5f19415ec9c0..e87ef435e11b 100644
--- a/net/ceph/Makefile
+++ b/net/ceph/Makefile
@@ -3,7 +3,7 @@
#
obj-$(CONFIG_CEPH_LIB) += libceph.o
-libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
+libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
mon_client.o \
osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
debugfs.o \
diff --git a/net/ceph/ceph_hash.c b/net/ceph/ceph_hash.c
index 815ef8826796..0a1b53bce76d 100644
--- a/net/ceph/ceph_hash.c
+++ b/net/ceph/ceph_hash.c
@@ -1,5 +1,6 @@
#include <linux/ceph/types.h>
+#include <linux/module.h>
/*
* Robert Jenkin's hash function.
@@ -104,6 +105,7 @@ unsigned ceph_str_hash(int type, const char *s, unsigned len)
return -1;
}
}
+EXPORT_SYMBOL(ceph_str_hash);
const char *ceph_str_hash_name(int type)
{
@@ -116,3 +118,4 @@ const char *ceph_str_hash_name(int type)
return "unknown";
}
}
+EXPORT_SYMBOL(ceph_str_hash_name);
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 1c7a2ec4f3cc..dff633d62e5b 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -96,12 +96,10 @@ struct workqueue_struct *ceph_msgr_wq;
int 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;
+ ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_NON_REENTRANT, 0);
+ if (!ceph_msgr_wq) {
+ pr_err("msgr_init failed to create workqueue\n");
+ return -ENOMEM;
}
return 0;
}
@@ -1922,20 +1920,6 @@ bad_tag:
/*
* 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)
{
@@ -1950,11 +1934,7 @@ static void queue_con(struct ceph_connection *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)) {
+ if (!queue_delayed_work(ceph_msgr_wq, &con->work, 0)) {
dout("queue_con %p - already queued\n", con);
con->ops->put(con);
} else {
@@ -1969,15 +1949,6 @@ 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);
mutex_lock(&con->mutex);
@@ -1996,28 +1967,13 @@ more:
try_read(con) < 0 ||
try_write(con) < 0) {
mutex_unlock(&con->mutex);
- backoff = 1;
ceph_fault(con); /* error/fault path */
goto done_unlocked;
}
done:
mutex_unlock(&con->mutex);
-
done_unlocked:
- 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);
}
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index d73f3f6efa36..71603ac3dff5 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -605,8 +605,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
goto bad;
}
err = __decode_pool(p, end, pi);
- if (err < 0)
+ if (err < 0) {
+ kfree(pi);
goto bad;
+ }
__insert_pg_pool(&map->pg_pools, pi);
}
diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c
index ac34feeb2b3a..1a040e64c69f 100644
--- a/net/ceph/pagevec.c
+++ b/net/ceph/pagevec.c
@@ -13,7 +13,7 @@
* build a vector of user pages
*/
struct page **ceph_get_direct_page_vector(const char __user *data,
- int num_pages)
+ int num_pages, bool write_page)
{
struct page **pages;
int rc;
@@ -24,24 +24,27 @@ struct page **ceph_get_direct_page_vector(const char __user *data,
down_read(&current->mm->mmap_sem);
rc = get_user_pages(current, current->mm, (unsigned long)data,
- num_pages, 0, 0, pages, NULL);
+ num_pages, write_page, 0, pages, NULL);
up_read(&current->mm->mmap_sem);
- if (rc < 0)
+ if (rc < num_pages)
goto fail;
return pages;
fail:
- kfree(pages);
+ ceph_put_page_vector(pages, rc > 0 ? rc : 0, false);
return ERR_PTR(rc);
}
EXPORT_SYMBOL(ceph_get_direct_page_vector);
-void ceph_put_page_vector(struct page **pages, int num_pages)
+void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty)
{
int i;
- for (i = 0; i < num_pages; i++)
+ for (i = 0; i < num_pages; i++) {
+ if (dirty)
+ set_page_dirty_lock(pages[i]);
put_page(pages[i]);
+ }
kfree(pages);
}
EXPORT_SYMBOL(ceph_put_page_vector);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index cd1e039c8755..18ac112ea7ae 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -177,7 +177,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
* interrupt level will suddenly eat the receive_queue.
*
* Look at current nfs client by the way...
- * However, this function was corrent in any case. 8)
+ * However, this function was correct in any case. 8)
*/
unsigned long cpu_flags;
diff --git a/net/core/dev.c b/net/core/dev.c
index 0dd54a69dace..a215269d2e35 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -743,34 +743,31 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
EXPORT_SYMBOL(dev_get_by_index);
/**
- * dev_getbyhwaddr - find a device by its hardware address
+ * dev_getbyhwaddr_rcu - find a device by its hardware address
* @net: the applicable net namespace
* @type: media type of device
* @ha: hardware address
*
* Search for an interface by MAC address. Returns NULL if the device
- * is not found or a pointer to the device. The caller must hold the
- * rtnl semaphore. The returned device has not had its ref count increased
+ * is not found or a pointer to the device. The caller must hold RCU
+ * The returned device has not had its ref count increased
* and the caller must therefore be careful about locking
*
- * BUGS:
- * If the API was consistent this would be __dev_get_by_hwaddr
*/
-struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha)
+struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+ const char *ha)
{
struct net_device *dev;
- ASSERT_RTNL();
-
- for_each_netdev(net, dev)
+ for_each_netdev_rcu(net, dev)
if (dev->type == type &&
!memcmp(dev->dev_addr, ha, dev->addr_len))
return dev;
return NULL;
}
-EXPORT_SYMBOL(dev_getbyhwaddr);
+EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
{
@@ -1225,52 +1222,90 @@ int dev_open(struct net_device *dev)
}
EXPORT_SYMBOL(dev_open);
-static int __dev_close(struct net_device *dev)
+static int __dev_close_many(struct list_head *head)
{
- const struct net_device_ops *ops = dev->netdev_ops;
+ struct net_device *dev;
ASSERT_RTNL();
might_sleep();
- /*
- * Tell people we are going down, so that they can
- * prepare to death, when device is still operating.
- */
- call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
+ list_for_each_entry(dev, head, unreg_list) {
+ /*
+ * Tell people we are going down, so that they can
+ * prepare to death, when device is still operating.
+ */
+ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
- clear_bit(__LINK_STATE_START, &dev->state);
+ clear_bit(__LINK_STATE_START, &dev->state);
- /* Synchronize to scheduled poll. We cannot touch poll list,
- * it can be even on different cpu. So just clear netif_running().
- *
- * dev->stop() will invoke napi_disable() on all of it's
- * napi_struct instances on this device.
- */
- smp_mb__after_clear_bit(); /* Commit netif_running(). */
+ /* Synchronize to scheduled poll. We cannot touch poll list, it
+ * can be even on different cpu. So just clear netif_running().
+ *
+ * dev->stop() will invoke napi_disable() on all of it's
+ * napi_struct instances on this device.
+ */
+ smp_mb__after_clear_bit(); /* Commit netif_running(). */
+ }
- dev_deactivate(dev);
+ dev_deactivate_many(head);
- /*
- * Call the device specific close. This cannot fail.
- * Only if device is UP
- *
- * We allow it to be called even after a DETACH hot-plug
- * event.
- */
- if (ops->ndo_stop)
- ops->ndo_stop(dev);
+ list_for_each_entry(dev, head, unreg_list) {
+ const struct net_device_ops *ops = dev->netdev_ops;
- /*
- * Device is now down.
- */
+ /*
+ * Call the device specific close. This cannot fail.
+ * Only if device is UP
+ *
+ * We allow it to be called even after a DETACH hot-plug
+ * event.
+ */
+ if (ops->ndo_stop)
+ ops->ndo_stop(dev);
+
+ /*
+ * Device is now down.
+ */
+
+ dev->flags &= ~IFF_UP;
+
+ /*
+ * Shutdown NET_DMA
+ */
+ net_dmaengine_put();
+ }
+
+ return 0;
+}
+
+static int __dev_close(struct net_device *dev)
+{
+ LIST_HEAD(single);
+
+ list_add(&dev->unreg_list, &single);
+ return __dev_close_many(&single);
+}
+
+int dev_close_many(struct list_head *head)
+{
+ struct net_device *dev, *tmp;
+ LIST_HEAD(tmp_list);
+
+ list_for_each_entry_safe(dev, tmp, head, unreg_list)
+ if (!(dev->flags & IFF_UP))
+ list_move(&dev->unreg_list, &tmp_list);
- dev->flags &= ~IFF_UP;
+ __dev_close_many(head);
/*
- * Shutdown NET_DMA
+ * Tell people we are down
*/
- net_dmaengine_put();
+ list_for_each_entry(dev, head, unreg_list) {
+ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
+ call_netdevice_notifiers(NETDEV_DOWN, dev);
+ }
+ /* rollback_registered_many needs the complete original list */
+ list_splice(&tmp_list, head);
return 0;
}
@@ -1285,16 +1320,10 @@ static int __dev_close(struct net_device *dev)
*/
int dev_close(struct net_device *dev)
{
- if (!(dev->flags & IFF_UP))
- return 0;
-
- __dev_close(dev);
+ LIST_HEAD(single);
- /*
- * Tell people we are down
- */
- rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
- call_netdevice_notifiers(NETDEV_DOWN, dev);
+ list_add(&dev->unreg_list, &single);
+ dev_close_many(&single);
return 0;
}
@@ -1499,6 +1528,14 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(dev_forward_skb);
+static inline int deliver_skb(struct sk_buff *skb,
+ struct packet_type *pt_prev,
+ struct net_device *orig_dev)
+{
+ atomic_inc(&skb->users);
+ return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
+}
+
/*
* Support routine. Sends outgoing frames to any network
* taps currently in use.
@@ -1507,13 +1544,8 @@ EXPORT_SYMBOL_GPL(dev_forward_skb);
static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
{
struct packet_type *ptype;
-
-#ifdef CONFIG_NET_CLS_ACT
- if (!(skb->tstamp.tv64 && (G_TC_FROM(skb->tc_verd) & AT_INGRESS)))
- net_timestamp_set(skb);
-#else
- net_timestamp_set(skb);
-#endif
+ struct sk_buff *skb2 = NULL;
+ struct packet_type *pt_prev = NULL;
rcu_read_lock();
list_for_each_entry_rcu(ptype, &ptype_all, list) {
@@ -1523,10 +1555,18 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
if ((ptype->dev == dev || !ptype->dev) &&
(ptype->af_packet_priv == NULL ||
(struct sock *)ptype->af_packet_priv != skb->sk)) {
- struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (pt_prev) {
+ deliver_skb(skb2, pt_prev, skb->dev);
+ pt_prev = ptype;
+ continue;
+ }
+
+ skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2)
break;
+ net_timestamp_set(skb2);
+
/* skb->nh should be correctly
set by sender, so that the second statement is
just protection against buggy protocols.
@@ -1545,9 +1585,11 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
skb2->transport_header = skb2->network_header;
skb2->pkt_type = PACKET_OUTGOING;
- ptype->func(skb2, skb->dev, ptype, skb->dev);
+ pt_prev = ptype;
}
}
+ if (pt_prev)
+ pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
rcu_read_unlock();
}
@@ -1557,12 +1599,19 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
*/
int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
{
+ int rc;
+
if (txq < 1 || txq > dev->num_tx_queues)
return -EINVAL;
if (dev->reg_state == NETREG_REGISTERED) {
ASSERT_RTNL();
+ rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues,
+ txq);
+ if (rc)
+ return rc;
+
if (txq < dev->real_num_tx_queues)
qdisc_reset_all_tx_gt(dev, txq);
}
@@ -1757,7 +1806,7 @@ int skb_checksum_help(struct sk_buff *skb)
goto out_set_summed;
}
- offset = skb->csum_start - skb_headroom(skb);
+ offset = skb_checksum_start_offset(skb);
BUG_ON(offset >= skb_headlen(skb));
csum = skb_checksum(skb, offset, skb->len - offset, 0);
@@ -1794,16 +1843,18 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
struct packet_type *ptype;
__be16 type = skb->protocol;
+ int vlan_depth = ETH_HLEN;
int err;
- if (type == htons(ETH_P_8021Q)) {
- struct vlan_ethhdr *veh;
+ while (type == htons(ETH_P_8021Q)) {
+ struct vlan_hdr *vh;
- if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+ if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
return ERR_PTR(-EINVAL);
- veh = (struct vlan_ethhdr *)skb->data;
- type = veh->h_vlan_encapsulated_proto;
+ vh = (struct vlan_hdr *)(skb->data + vlan_depth);
+ type = vh->h_vlan_encapsulated_proto;
+ vlan_depth += VLAN_HLEN;
}
skb_reset_mac_header(skb);
@@ -1817,8 +1868,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
dev->ethtool_ops->get_drvinfo(dev, &info);
- WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d "
- "ip_summed=%d",
+ WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n",
info.driver, dev ? dev->features : 0L,
skb->sk ? skb->sk->sk_route_caps : 0L,
skb->len, skb->data_len, skb->ip_summed);
@@ -1967,6 +2017,23 @@ static inline void skb_orphan_try(struct sk_buff *skb)
}
}
+int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev)
+{
+ __be16 protocol = skb->protocol;
+
+ if (protocol == htons(ETH_P_8021Q)) {
+ struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+ protocol = veh->h_vlan_encapsulated_proto;
+ } else if (!skb->vlan_tci)
+ return dev->features;
+
+ if (protocol != htons(ETH_P_8021Q))
+ return dev->features & dev->vlan_features;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(netif_get_vlan_features);
+
/*
* Returns true if either:
* 1. skb has frag_list and the device doesn't support FRAGLIST, or
@@ -1977,15 +2044,20 @@ static inline void skb_orphan_try(struct sk_buff *skb)
static inline int skb_needs_linearize(struct sk_buff *skb,
struct net_device *dev)
{
- int features = dev->features;
+ if (skb_is_nonlinear(skb)) {
+ int features = dev->features;
- if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb))
- features &= dev->vlan_features;
+ if (vlan_tx_tag_present(skb))
+ features &= dev->vlan_features;
- return skb_is_nonlinear(skb) &&
- ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) ||
- (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) ||
- illegal_highdma(dev, skb))));
+ return (skb_has_frag_list(skb) &&
+ !(features & NETIF_F_FRAGLIST)) ||
+ (skb_shinfo(skb)->nr_frags &&
+ (!(features & NETIF_F_SG) ||
+ illegal_highdma(dev, skb)));
+ }
+
+ return 0;
}
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
@@ -1995,9 +2067,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
int rc = NETDEV_TX_OK;
if (likely(!skb->next)) {
- if (!list_empty(&ptype_all))
- dev_queue_xmit_nit(skb, dev);
-
/*
* If device doesnt need skb->dst, release it right now while
* its hot in this cpu cache
@@ -2005,6 +2074,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
skb_dst_drop(skb);
+ if (!list_empty(&ptype_all))
+ dev_queue_xmit_nit(skb, dev);
+
skb_orphan_try(skb);
if (vlan_tx_tag_present(skb) &&
@@ -2031,8 +2103,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
* checksumming here.
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- skb_set_transport_header(skb, skb->csum_start -
- skb_headroom(skb));
+ skb_set_transport_header(skb,
+ skb_checksum_start_offset(skb));
if (!dev_can_checksum(dev, skb) &&
skb_checksum_help(skb))
goto out_kfree_skb;
@@ -2085,14 +2157,19 @@ out:
static u32 hashrnd __read_mostly;
-u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
+/*
+ * Returns a Tx hash based on the given packet descriptor a Tx queues' number
+ * to be used as a distribution range.
+ */
+u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
+ unsigned int num_tx_queues)
{
u32 hash;
if (skb_rx_queue_recorded(skb)) {
hash = skb_get_rx_queue(skb);
- while (unlikely(hash >= dev->real_num_tx_queues))
- hash -= dev->real_num_tx_queues;
+ while (unlikely(hash >= num_tx_queues))
+ hash -= num_tx_queues;
return hash;
}
@@ -2102,9 +2179,9 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
hash = (__force u16) skb->protocol ^ skb->rxhash;
hash = jhash_1word(hash, hashrnd);
- return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
+ return (u16) (((u64) hash * num_tx_queues) >> 32);
}
-EXPORT_SYMBOL(skb_tx_hash);
+EXPORT_SYMBOL(__skb_tx_hash);
static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
{
@@ -2119,26 +2196,70 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
return queue_index;
}
+static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
+{
+#ifdef CONFIG_XPS
+ struct xps_dev_maps *dev_maps;
+ struct xps_map *map;
+ int queue_index = -1;
+
+ rcu_read_lock();
+ dev_maps = rcu_dereference(dev->xps_maps);
+ if (dev_maps) {
+ map = rcu_dereference(
+ dev_maps->cpu_map[raw_smp_processor_id()]);
+ if (map) {
+ if (map->len == 1)
+ queue_index = map->queues[0];
+ else {
+ u32 hash;
+ if (skb->sk && skb->sk->sk_hash)
+ hash = skb->sk->sk_hash;
+ else
+ hash = (__force u16) skb->protocol ^
+ skb->rxhash;
+ hash = jhash_1word(hash, hashrnd);
+ queue_index = map->queues[
+ ((u64)hash * map->len) >> 32];
+ }
+ if (unlikely(queue_index >= dev->real_num_tx_queues))
+ queue_index = -1;
+ }
+ }
+ rcu_read_unlock();
+
+ return queue_index;
+#else
+ return -1;
+#endif
+}
+
static struct netdev_queue *dev_pick_tx(struct net_device *dev,
struct sk_buff *skb)
{
int queue_index;
const struct net_device_ops *ops = dev->netdev_ops;
- if (ops->ndo_select_queue) {
+ if (dev->real_num_tx_queues == 1)
+ queue_index = 0;
+ else if (ops->ndo_select_queue) {
queue_index = ops->ndo_select_queue(dev, skb);
queue_index = dev_cap_txqueue(dev, queue_index);
} else {
struct sock *sk = skb->sk;
queue_index = sk_tx_queue_get(sk);
- if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) {
- queue_index = 0;
- if (dev->real_num_tx_queues > 1)
+ if (queue_index < 0 || skb->ooo_okay ||
+ queue_index >= dev->real_num_tx_queues) {
+ int old_index = queue_index;
+
+ queue_index = get_xps_queue(dev, skb);
+ if (queue_index < 0)
queue_index = skb_tx_hash(dev, skb);
- if (sk) {
- struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1);
+ if (queue_index != old_index && sk) {
+ struct dst_entry *dst =
+ rcu_dereference_check(sk->sk_dst_cache, 1);
if (dst && skb_dst(skb) == dst)
sk_tx_queue_set(sk, queue_index);
@@ -2712,14 +2833,6 @@ static void net_tx_action(struct softirq_action *h)
}
}
-static inline int deliver_skb(struct sk_buff *skb,
- struct packet_type *pt_prev,
- struct net_device *orig_dev)
-{
- atomic_inc(&skb->users);
- return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
-}
-
#if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \
(defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE))
/* This hook is defined here for ATM LANE */
@@ -4887,10 +5000,12 @@ static void rollback_registered_many(struct list_head *head)
}
BUG_ON(dev->reg_state != NETREG_REGISTERED);
+ }
- /* If device is running, close it first. */
- dev_close(dev);
+ /* If device is running, close it first. */
+ dev_close_many(head);
+ list_for_each_entry(dev, head, unreg_list) {
/* And unlink it from device chain. */
unlist_netdevice(dev);
@@ -4967,10 +5082,13 @@ unsigned long netdev_fix_features(unsigned long features, const char *name)
}
if (features & NETIF_F_UFO) {
- if (!(features & NETIF_F_GEN_CSUM)) {
+ /* maybe split UFO into V4 and V6? */
+ if (!((features & NETIF_F_GEN_CSUM) ||
+ (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+ == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
if (name)
printk(KERN_ERR "%s: Dropping NETIF_F_UFO "
- "since no NETIF_F_HW_CSUM feature.\n",
+ "since no checksum offload features.\n",
name);
features &= ~NETIF_F_UFO;
}
@@ -5014,9 +5132,9 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
}
EXPORT_SYMBOL(netif_stacked_transfer_operstate);
+#ifdef CONFIG_RPS
static int netif_alloc_rx_queues(struct net_device *dev)
{
-#ifdef CONFIG_RPS
unsigned int i, count = dev->num_rx_queues;
struct netdev_rx_queue *rx;
@@ -5029,15 +5147,22 @@ static int netif_alloc_rx_queues(struct net_device *dev)
}
dev->_rx = rx;
- /*
- * Set a pointer to first element in the array which holds the
- * reference count.
- */
for (i = 0; i < count; i++)
- rx[i].first = rx;
-#endif
+ rx[i].dev = dev;
return 0;
}
+#endif
+
+static void netdev_init_one_queue(struct net_device *dev,
+ struct netdev_queue *queue, void *_unused)
+{
+ /* Initialize queue lock */
+ spin_lock_init(&queue->_xmit_lock);
+ netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type);
+ queue->xmit_lock_owner = -1;
+ netdev_queue_numa_node_write(queue, NUMA_NO_NODE);
+ queue->dev = dev;
+}
static int netif_alloc_netdev_queues(struct net_device *dev)
{
@@ -5053,25 +5178,11 @@ static int netif_alloc_netdev_queues(struct net_device *dev)
return -ENOMEM;
}
dev->_tx = tx;
- return 0;
-}
-static void netdev_init_one_queue(struct net_device *dev,
- struct netdev_queue *queue,
- void *_unused)
-{
- queue->dev = dev;
-
- /* Initialize queue lock */
- spin_lock_init(&queue->_xmit_lock);
- netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type);
- queue->xmit_lock_owner = -1;
-}
-
-static void netdev_init_queues(struct net_device *dev)
-{
netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
spin_lock_init(&dev->tx_global_lock);
+
+ return 0;
}
/**
@@ -5110,16 +5221,6 @@ int register_netdevice(struct net_device *dev)
dev->iflink = -1;
- ret = netif_alloc_rx_queues(dev);
- if (ret)
- goto out;
-
- ret = netif_alloc_netdev_queues(dev);
- if (ret)
- goto out;
-
- netdev_init_queues(dev);
-
/* Init, if this function is available */
if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev);
@@ -5577,10 +5678,14 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
dev->num_tx_queues = queue_count;
dev->real_num_tx_queues = queue_count;
+ if (netif_alloc_netdev_queues(dev))
+ goto free_pcpu;
#ifdef CONFIG_RPS
dev->num_rx_queues = queue_count;
dev->real_num_rx_queues = queue_count;
+ if (netif_alloc_rx_queues(dev))
+ goto free_pcpu;
#endif
dev->gso_max_size = GSO_MAX_SIZE;
@@ -5597,6 +5702,11 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
free_pcpu:
free_percpu(dev->pcpu_refcnt);
+ kfree(dev->_tx);
+#ifdef CONFIG_RPS
+ kfree(dev->_rx);
+#endif
+
free_p:
kfree(p);
return NULL;
@@ -5618,6 +5728,9 @@ void free_netdev(struct net_device *dev)
release_net(dev_net(dev));
kfree(dev->_tx);
+#ifdef CONFIG_RPS
+ kfree(dev->_rx);
+#endif
kfree(rcu_dereference_raw(dev->ingress_queue));
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 956a9f4971cb..17741782a345 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -891,6 +891,20 @@ static int ethtool_nway_reset(struct net_device *dev)
return dev->ethtool_ops->nway_reset(dev);
}
+static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value edata = { .cmd = ETHTOOL_GLINK };
+
+ if (!dev->ethtool_ops->get_link)
+ return -EOPNOTSUPP;
+
+ edata.data = netif_running(dev) && dev->ethtool_ops->get_link(dev);
+
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+}
+
static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
{
struct ethtool_eeprom eeprom;
@@ -1171,7 +1185,9 @@ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
return -EFAULT;
if (edata.data && !(dev->features & NETIF_F_SG))
return -EINVAL;
- if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
+ if (edata.data && !((dev->features & NETIF_F_GEN_CSUM) ||
+ (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+ == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)))
return -EINVAL;
return dev->ethtool_ops->set_ufo(dev, edata.data);
}
@@ -1528,8 +1544,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
rc = ethtool_nway_reset(dev);
break;
case ETHTOOL_GLINK:
- rc = ethtool_get_value(dev, useraddr, ethcmd,
- dev->ethtool_ops->get_link);
+ rc = ethtool_get_link(dev, useraddr);
break;
case ETHTOOL_GEEPROM:
rc = ethtool_get_eeprom(dev, useraddr);
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 82a4369ae150..a20e5d3bbfa0 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -181,8 +181,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
{
int ret = 0;
- if (rule->iifindex && (rule->iifindex != fl->iif) &&
- !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF))
+ if (rule->iifindex && (rule->iifindex != fl->iif))
goto out;
if (rule->oifindex && (rule->oifindex != fl->oif))
diff --git a/net/core/filter.c b/net/core/filter.c
index c1ee800bc080..2b27d4efdd48 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -37,9 +37,69 @@
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/filter.h>
+#include <linux/reciprocal_div.h>
+
+enum {
+ BPF_S_RET_K = 1,
+ BPF_S_RET_A,
+ BPF_S_ALU_ADD_K,
+ BPF_S_ALU_ADD_X,
+ BPF_S_ALU_SUB_K,
+ BPF_S_ALU_SUB_X,
+ BPF_S_ALU_MUL_K,
+ BPF_S_ALU_MUL_X,
+ BPF_S_ALU_DIV_X,
+ BPF_S_ALU_AND_K,
+ BPF_S_ALU_AND_X,
+ BPF_S_ALU_OR_K,
+ BPF_S_ALU_OR_X,
+ BPF_S_ALU_LSH_K,
+ BPF_S_ALU_LSH_X,
+ BPF_S_ALU_RSH_K,
+ BPF_S_ALU_RSH_X,
+ BPF_S_ALU_NEG,
+ BPF_S_LD_W_ABS,
+ BPF_S_LD_H_ABS,
+ BPF_S_LD_B_ABS,
+ BPF_S_LD_W_LEN,
+ BPF_S_LD_W_IND,
+ BPF_S_LD_H_IND,
+ BPF_S_LD_B_IND,
+ BPF_S_LD_IMM,
+ BPF_S_LDX_W_LEN,
+ BPF_S_LDX_B_MSH,
+ BPF_S_LDX_IMM,
+ BPF_S_MISC_TAX,
+ BPF_S_MISC_TXA,
+ BPF_S_ALU_DIV_K,
+ BPF_S_LD_MEM,
+ BPF_S_LDX_MEM,
+ BPF_S_ST,
+ BPF_S_STX,
+ BPF_S_JMP_JA,
+ BPF_S_JMP_JEQ_K,
+ BPF_S_JMP_JEQ_X,
+ BPF_S_JMP_JGE_K,
+ BPF_S_JMP_JGE_X,
+ BPF_S_JMP_JGT_K,
+ BPF_S_JMP_JGT_X,
+ BPF_S_JMP_JSET_K,
+ BPF_S_JMP_JSET_X,
+ /* Ancillary data */
+ BPF_S_ANC_PROTOCOL,
+ BPF_S_ANC_PKTTYPE,
+ BPF_S_ANC_IFINDEX,
+ BPF_S_ANC_NLATTR,
+ BPF_S_ANC_NLATTR_NEST,
+ BPF_S_ANC_MARK,
+ BPF_S_ANC_QUEUE,
+ BPF_S_ANC_HATYPE,
+ BPF_S_ANC_RXHASH,
+ BPF_S_ANC_CPU,
+};
/* No hurry in this branch */
-static void *__load_pointer(struct sk_buff *skb, int k)
+static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
{
u8 *ptr = NULL;
@@ -48,21 +108,17 @@ static void *__load_pointer(struct sk_buff *skb, int k)
else if (k >= SKF_LL_OFF)
ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
- if (ptr >= skb->head && ptr < skb_tail_pointer(skb))
+ if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb))
return ptr;
return NULL;
}
-static inline void *load_pointer(struct sk_buff *skb, int k,
+static inline void *load_pointer(const struct sk_buff *skb, int k,
unsigned int size, void *buffer)
{
if (k >= 0)
return skb_header_pointer(skb, k, size, buffer);
- else {
- if (k >= SKF_AD_OFF)
- return NULL;
- return __load_pointer(skb, k);
- }
+ return __load_pointer(skb, k, size);
}
/**
@@ -89,7 +145,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
rcu_read_lock_bh();
filter = rcu_dereference_bh(sk->sk_filter);
if (filter) {
- unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len);
+ unsigned int pkt_len = sk_run_filter(skb, filter->insns);
err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
}
@@ -103,50 +159,52 @@ EXPORT_SYMBOL(sk_filter);
* sk_run_filter - run a filter on a socket
* @skb: buffer to run the filter on
* @filter: filter to apply
- * @flen: length of filter
*
* Decode and apply filter instructions to the skb->data.
- * Return length to keep, 0 for none. skb is the data we are
- * filtering, filter is the array of filter instructions, and
- * len is the number of filter blocks in the array.
+ * Return length to keep, 0 for none. @skb is the data we are
+ * filtering, @filter is the array of filter instructions.
+ * Because all jumps are guaranteed to be before last instruction,
+ * and last instruction guaranteed to be a RET, we dont need to check
+ * flen. (We used to pass to this function the length of filter)
*/
-unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
+unsigned int sk_run_filter(const struct sk_buff *skb,
+ const struct sock_filter *fentry)
{
void *ptr;
u32 A = 0; /* Accumulator */
u32 X = 0; /* Index Register */
u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
- unsigned long memvalid = 0;
u32 tmp;
int k;
- int pc;
- BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
/*
* Process array of filter instructions.
*/
- for (pc = 0; pc < flen; pc++) {
- const struct sock_filter *fentry = &filter[pc];
- u32 f_k = fentry->k;
+ for (;; fentry++) {
+#if defined(CONFIG_X86_32)
+#define K (fentry->k)
+#else
+ const u32 K = fentry->k;
+#endif
switch (fentry->code) {
case BPF_S_ALU_ADD_X:
A += X;
continue;
case BPF_S_ALU_ADD_K:
- A += f_k;
+ A += K;
continue;
case BPF_S_ALU_SUB_X:
A -= X;
continue;
case BPF_S_ALU_SUB_K:
- A -= f_k;
+ A -= K;
continue;
case BPF_S_ALU_MUL_X:
A *= X;
continue;
case BPF_S_ALU_MUL_K:
- A *= f_k;
+ A *= K;
continue;
case BPF_S_ALU_DIV_X:
if (X == 0)
@@ -154,89 +212,89 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
A /= X;
continue;
case BPF_S_ALU_DIV_K:
- A /= f_k;
+ A = reciprocal_divide(A, K);
continue;
case BPF_S_ALU_AND_X:
A &= X;
continue;
case BPF_S_ALU_AND_K:
- A &= f_k;
+ A &= K;
continue;
case BPF_S_ALU_OR_X:
A |= X;
continue;
case BPF_S_ALU_OR_K:
- A |= f_k;
+ A |= K;
continue;
case BPF_S_ALU_LSH_X:
A <<= X;
continue;
case BPF_S_ALU_LSH_K:
- A <<= f_k;
+ A <<= K;
continue;
case BPF_S_ALU_RSH_X:
A >>= X;
continue;
case BPF_S_ALU_RSH_K:
- A >>= f_k;
+ A >>= K;
continue;
case BPF_S_ALU_NEG:
A = -A;
continue;
case BPF_S_JMP_JA:
- pc += f_k;
+ fentry += K;
continue;
case BPF_S_JMP_JGT_K:
- pc += (A > f_k) ? fentry->jt : fentry->jf;
+ fentry += (A > K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGE_K:
- pc += (A >= f_k) ? fentry->jt : fentry->jf;
+ fentry += (A >= K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JEQ_K:
- pc += (A == f_k) ? fentry->jt : fentry->jf;
+ fentry += (A == K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JSET_K:
- pc += (A & f_k) ? fentry->jt : fentry->jf;
+ fentry += (A & K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGT_X:
- pc += (A > X) ? fentry->jt : fentry->jf;
+ fentry += (A > X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGE_X:
- pc += (A >= X) ? fentry->jt : fentry->jf;
+ fentry += (A >= X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JEQ_X:
- pc += (A == X) ? fentry->jt : fentry->jf;
+ fentry += (A == X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JSET_X:
- pc += (A & X) ? fentry->jt : fentry->jf;
+ fentry += (A & X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_LD_W_ABS:
- k = f_k;
+ k = K;
load_w:
ptr = load_pointer(skb, k, 4, &tmp);
if (ptr != NULL) {
A = get_unaligned_be32(ptr);
continue;
}
- break;
+ return 0;
case BPF_S_LD_H_ABS:
- k = f_k;
+ k = K;
load_h:
ptr = load_pointer(skb, k, 2, &tmp);
if (ptr != NULL) {
A = get_unaligned_be16(ptr);
continue;
}
- break;
+ return 0;
case BPF_S_LD_B_ABS:
- k = f_k;
+ k = K;
load_b:
ptr = load_pointer(skb, k, 1, &tmp);
if (ptr != NULL) {
A = *(u8 *)ptr;
continue;
}
- break;
+ return 0;
case BPF_S_LD_W_LEN:
A = skb->len;
continue;
@@ -244,34 +302,32 @@ load_b:
X = skb->len;
continue;
case BPF_S_LD_W_IND:
- k = X + f_k;
+ k = X + K;
goto load_w;
case BPF_S_LD_H_IND:
- k = X + f_k;
+ k = X + K;
goto load_h;
case BPF_S_LD_B_IND:
- k = X + f_k;
+ k = X + K;
goto load_b;
case BPF_S_LDX_B_MSH:
- ptr = load_pointer(skb, f_k, 1, &tmp);
+ ptr = load_pointer(skb, K, 1, &tmp);
if (ptr != NULL) {
X = (*(u8 *)ptr & 0xf) << 2;
continue;
}
return 0;
case BPF_S_LD_IMM:
- A = f_k;
+ A = K;
continue;
case BPF_S_LDX_IMM:
- X = f_k;
+ X = K;
continue;
case BPF_S_LD_MEM:
- A = (memvalid & (1UL << f_k)) ?
- mem[f_k] : 0;
+ A = mem[K];
continue;
case BPF_S_LDX_MEM:
- X = (memvalid & (1UL << f_k)) ?
- mem[f_k] : 0;
+ X = mem[K];
continue;
case BPF_S_MISC_TAX:
X = A;
@@ -280,50 +336,44 @@ load_b:
A = X;
continue;
case BPF_S_RET_K:
- return f_k;
+ return K;
case BPF_S_RET_A:
return A;
case BPF_S_ST:
- memvalid |= 1UL << f_k;
- mem[f_k] = A;
+ mem[K] = A;
continue;
case BPF_S_STX:
- memvalid |= 1UL << f_k;
- mem[f_k] = X;
+ mem[K] = X;
continue;
- default:
- WARN_ON(1);
- return 0;
- }
-
- /*
- * Handle ancillary data, which are impossible
- * (or very difficult) to get parsing packet contents.
- */
- switch (k-SKF_AD_OFF) {
- case SKF_AD_PROTOCOL:
+ case BPF_S_ANC_PROTOCOL:
A = ntohs(skb->protocol);
continue;
- case SKF_AD_PKTTYPE:
+ case BPF_S_ANC_PKTTYPE:
A = skb->pkt_type;
continue;
- case SKF_AD_IFINDEX:
+ case BPF_S_ANC_IFINDEX:
if (!skb->dev)
return 0;
A = skb->dev->ifindex;
continue;
- case SKF_AD_MARK:
+ case BPF_S_ANC_MARK:
A = skb->mark;
continue;
- case SKF_AD_QUEUE:
+ case BPF_S_ANC_QUEUE:
A = skb->queue_mapping;
continue;
- case SKF_AD_HATYPE:
+ case BPF_S_ANC_HATYPE:
if (!skb->dev)
return 0;
A = skb->dev->type;
continue;
- case SKF_AD_NLATTR: {
+ case BPF_S_ANC_RXHASH:
+ A = skb->rxhash;
+ continue;
+ case BPF_S_ANC_CPU:
+ A = raw_smp_processor_id();
+ continue;
+ case BPF_S_ANC_NLATTR: {
struct nlattr *nla;
if (skb_is_nonlinear(skb))
@@ -339,7 +389,7 @@ load_b:
A = 0;
continue;
}
- case SKF_AD_NLATTR_NEST: {
+ case BPF_S_ANC_NLATTR_NEST: {
struct nlattr *nla;
if (skb_is_nonlinear(skb))
@@ -359,6 +409,7 @@ load_b:
continue;
}
default:
+ WARN_ON(1);
return 0;
}
}
@@ -367,6 +418,66 @@ load_b:
}
EXPORT_SYMBOL(sk_run_filter);
+/*
+ * Security :
+ * A BPF program is able to use 16 cells of memory to store intermediate
+ * values (check u32 mem[BPF_MEMWORDS] in sk_run_filter())
+ * As we dont want to clear mem[] array for each packet going through
+ * sk_run_filter(), we check that filter loaded by user never try to read
+ * a cell if not previously written, and we check all branches to be sure
+ * a malicious user doesnt try to abuse us.
+ */
+static int check_load_and_stores(struct sock_filter *filter, int flen)
+{
+ u16 *masks, memvalid = 0; /* one bit per cell, 16 cells */
+ int pc, ret = 0;
+
+ BUILD_BUG_ON(BPF_MEMWORDS > 16);
+ masks = kmalloc(flen * sizeof(*masks), GFP_KERNEL);
+ if (!masks)
+ return -ENOMEM;
+ memset(masks, 0xff, flen * sizeof(*masks));
+
+ for (pc = 0; pc < flen; pc++) {
+ memvalid &= masks[pc];
+
+ switch (filter[pc].code) {
+ case BPF_S_ST:
+ case BPF_S_STX:
+ memvalid |= (1 << filter[pc].k);
+ break;
+ case BPF_S_LD_MEM:
+ case BPF_S_LDX_MEM:
+ if (!(memvalid & (1 << filter[pc].k))) {
+ ret = -EINVAL;
+ goto error;
+ }
+ break;
+ case BPF_S_JMP_JA:
+ /* a jump must set masks on target */
+ masks[pc + 1 + filter[pc].k] &= memvalid;
+ memvalid = ~0;
+ break;
+ case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JGE_K:
+ case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JGT_K:
+ case BPF_S_JMP_JGT_X:
+ case BPF_S_JMP_JSET_X:
+ case BPF_S_JMP_JSET_K:
+ /* a jump must set masks on targets */
+ masks[pc + 1 + filter[pc].jt] &= memvalid;
+ masks[pc + 1 + filter[pc].jf] &= memvalid;
+ memvalid = ~0;
+ break;
+ }
+ }
+error:
+ kfree(masks);
+ return ret;
+}
+
/**
* sk_chk_filter - verify socket filter code
* @filter: filter to verify
@@ -383,7 +494,57 @@ EXPORT_SYMBOL(sk_run_filter);
*/
int sk_chk_filter(struct sock_filter *filter, int flen)
{
- struct sock_filter *ftest;
+ /*
+ * Valid instructions are initialized to non-0.
+ * Invalid instructions are initialized to 0.
+ */
+ static const u8 codes[] = {
+ [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K,
+ [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X,
+ [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K,
+ [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X,
+ [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K,
+ [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X,
+ [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X,
+ [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K,
+ [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X,
+ [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K,
+ [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X,
+ [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K,
+ [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X,
+ [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K,
+ [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X,
+ [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG,
+ [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS,
+ [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS,
+ [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS,
+ [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN,
+ [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND,
+ [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND,
+ [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND,
+ [BPF_LD|BPF_IMM] = BPF_S_LD_IMM,
+ [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN,
+ [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH,
+ [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM,
+ [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX,
+ [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA,
+ [BPF_RET|BPF_K] = BPF_S_RET_K,
+ [BPF_RET|BPF_A] = BPF_S_RET_A,
+ [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K,
+ [BPF_LD|BPF_MEM] = BPF_S_LD_MEM,
+ [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM,
+ [BPF_ST] = BPF_S_ST,
+ [BPF_STX] = BPF_S_STX,
+ [BPF_JMP|BPF_JA] = BPF_S_JMP_JA,
+ [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K,
+ [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X,
+ [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K,
+ [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X,
+ [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K,
+ [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X,
+ [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K,
+ [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X,
+ };
int pc;
if (flen == 0 || flen > BPF_MAXINSNS)
@@ -391,136 +552,31 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
/* check the filter code now */
for (pc = 0; pc < flen; pc++) {
- ftest = &filter[pc];
-
- /* Only allow valid instructions */
- switch (ftest->code) {
- case BPF_ALU|BPF_ADD|BPF_K:
- ftest->code = BPF_S_ALU_ADD_K;
- break;
- case BPF_ALU|BPF_ADD|BPF_X:
- ftest->code = BPF_S_ALU_ADD_X;
- break;
- case BPF_ALU|BPF_SUB|BPF_K:
- ftest->code = BPF_S_ALU_SUB_K;
- break;
- case BPF_ALU|BPF_SUB|BPF_X:
- ftest->code = BPF_S_ALU_SUB_X;
- break;
- case BPF_ALU|BPF_MUL|BPF_K:
- ftest->code = BPF_S_ALU_MUL_K;
- break;
- case BPF_ALU|BPF_MUL|BPF_X:
- ftest->code = BPF_S_ALU_MUL_X;
- break;
- case BPF_ALU|BPF_DIV|BPF_X:
- ftest->code = BPF_S_ALU_DIV_X;
- break;
- case BPF_ALU|BPF_AND|BPF_K:
- ftest->code = BPF_S_ALU_AND_K;
- break;
- case BPF_ALU|BPF_AND|BPF_X:
- ftest->code = BPF_S_ALU_AND_X;
- break;
- case BPF_ALU|BPF_OR|BPF_K:
- ftest->code = BPF_S_ALU_OR_K;
- break;
- case BPF_ALU|BPF_OR|BPF_X:
- ftest->code = BPF_S_ALU_OR_X;
- break;
- case BPF_ALU|BPF_LSH|BPF_K:
- ftest->code = BPF_S_ALU_LSH_K;
- break;
- case BPF_ALU|BPF_LSH|BPF_X:
- ftest->code = BPF_S_ALU_LSH_X;
- break;
- case BPF_ALU|BPF_RSH|BPF_K:
- ftest->code = BPF_S_ALU_RSH_K;
- break;
- case BPF_ALU|BPF_RSH|BPF_X:
- ftest->code = BPF_S_ALU_RSH_X;
- break;
- case BPF_ALU|BPF_NEG:
- ftest->code = BPF_S_ALU_NEG;
- break;
- case BPF_LD|BPF_W|BPF_ABS:
- ftest->code = BPF_S_LD_W_ABS;
- break;
- case BPF_LD|BPF_H|BPF_ABS:
- ftest->code = BPF_S_LD_H_ABS;
- break;
- case BPF_LD|BPF_B|BPF_ABS:
- ftest->code = BPF_S_LD_B_ABS;
- break;
- case BPF_LD|BPF_W|BPF_LEN:
- ftest->code = BPF_S_LD_W_LEN;
- break;
- case BPF_LD|BPF_W|BPF_IND:
- ftest->code = BPF_S_LD_W_IND;
- break;
- case BPF_LD|BPF_H|BPF_IND:
- ftest->code = BPF_S_LD_H_IND;
- break;
- case BPF_LD|BPF_B|BPF_IND:
- ftest->code = BPF_S_LD_B_IND;
- break;
- case BPF_LD|BPF_IMM:
- ftest->code = BPF_S_LD_IMM;
- break;
- case BPF_LDX|BPF_W|BPF_LEN:
- ftest->code = BPF_S_LDX_W_LEN;
- break;
- case BPF_LDX|BPF_B|BPF_MSH:
- ftest->code = BPF_S_LDX_B_MSH;
- break;
- case BPF_LDX|BPF_IMM:
- ftest->code = BPF_S_LDX_IMM;
- break;
- case BPF_MISC|BPF_TAX:
- ftest->code = BPF_S_MISC_TAX;
- break;
- case BPF_MISC|BPF_TXA:
- ftest->code = BPF_S_MISC_TXA;
- break;
- case BPF_RET|BPF_K:
- ftest->code = BPF_S_RET_K;
- break;
- case BPF_RET|BPF_A:
- ftest->code = BPF_S_RET_A;
- break;
+ struct sock_filter *ftest = &filter[pc];
+ u16 code = ftest->code;
+ if (code >= ARRAY_SIZE(codes))
+ return -EINVAL;
+ code = codes[code];
+ if (!code)
+ return -EINVAL;
/* Some instructions need special checks */
-
+ switch (code) {
+ case BPF_S_ALU_DIV_K:
/* check for division by zero */
- case BPF_ALU|BPF_DIV|BPF_K:
if (ftest->k == 0)
return -EINVAL;
- ftest->code = BPF_S_ALU_DIV_K;
- break;
-
- /* check for invalid memory addresses */
- case BPF_LD|BPF_MEM:
- if (ftest->k >= BPF_MEMWORDS)
- return -EINVAL;
- ftest->code = BPF_S_LD_MEM;
+ ftest->k = reciprocal_value(ftest->k);
break;
- case BPF_LDX|BPF_MEM:
- if (ftest->k >= BPF_MEMWORDS)
- return -EINVAL;
- ftest->code = BPF_S_LDX_MEM;
- break;
- case BPF_ST:
- if (ftest->k >= BPF_MEMWORDS)
- return -EINVAL;
- ftest->code = BPF_S_ST;
- break;
- case BPF_STX:
+ case BPF_S_LD_MEM:
+ case BPF_S_LDX_MEM:
+ case BPF_S_ST:
+ case BPF_S_STX:
+ /* check for invalid memory addresses */
if (ftest->k >= BPF_MEMWORDS)
return -EINVAL;
- ftest->code = BPF_S_STX;
break;
-
- case BPF_JMP|BPF_JA:
+ case BPF_S_JMP_JA:
/*
* Note, the large ftest->k might cause loops.
* Compare this with conditional jumps below,
@@ -528,40 +584,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
*/
if (ftest->k >= (unsigned)(flen-pc-1))
return -EINVAL;
- ftest->code = BPF_S_JMP_JA;
- break;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- ftest->code = BPF_S_JMP_JEQ_K;
- break;
- case BPF_JMP|BPF_JEQ|BPF_X:
- ftest->code = BPF_S_JMP_JEQ_X;
- break;
- case BPF_JMP|BPF_JGE|BPF_K:
- ftest->code = BPF_S_JMP_JGE_K;
- break;
- case BPF_JMP|BPF_JGE|BPF_X:
- ftest->code = BPF_S_JMP_JGE_X;
break;
- case BPF_JMP|BPF_JGT|BPF_K:
- ftest->code = BPF_S_JMP_JGT_K;
- break;
- case BPF_JMP|BPF_JGT|BPF_X:
- ftest->code = BPF_S_JMP_JGT_X;
- break;
- case BPF_JMP|BPF_JSET|BPF_K:
- ftest->code = BPF_S_JMP_JSET_K;
- break;
- case BPF_JMP|BPF_JSET|BPF_X:
- ftest->code = BPF_S_JMP_JSET_X;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* for conditionals both must be safe */
- switch (ftest->code) {
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JEQ_X:
case BPF_S_JMP_JGE_K:
@@ -570,42 +593,54 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JSET_X:
case BPF_S_JMP_JSET_K:
+ /* for conditionals both must be safe */
if (pc + ftest->jt + 1 >= flen ||
pc + ftest->jf + 1 >= flen)
return -EINVAL;
+ break;
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
+ code = BPF_S_ANC_##CODE; \
+ break
+ switch (ftest->k) {
+ ANCILLARY(PROTOCOL);
+ ANCILLARY(PKTTYPE);
+ ANCILLARY(IFINDEX);
+ ANCILLARY(NLATTR);
+ ANCILLARY(NLATTR_NEST);
+ ANCILLARY(MARK);
+ ANCILLARY(QUEUE);
+ ANCILLARY(HATYPE);
+ ANCILLARY(RXHASH);
+ ANCILLARY(CPU);
+ }
}
+ ftest->code = code;
}
/* last instruction must be a RET code */
switch (filter[flen - 1].code) {
case BPF_S_RET_K:
case BPF_S_RET_A:
- return 0;
- break;
- default:
- return -EINVAL;
- }
+ return check_load_and_stores(filter, flen);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL(sk_chk_filter);
/**
- * sk_filter_rcu_release - Release a socket filter by rcu_head
+ * sk_filter_release_rcu - Release a socket filter by rcu_head
* @rcu: rcu_head that contains the sk_filter to free
*/
-static void sk_filter_rcu_release(struct rcu_head *rcu)
+void sk_filter_release_rcu(struct rcu_head *rcu)
{
struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
- sk_filter_release(fp);
-}
-
-static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
-{
- unsigned int size = sk_filter_len(fp);
-
- atomic_sub(size, &sk->sk_omem_alloc);
- call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+ kfree(fp);
}
+EXPORT_SYMBOL(sk_filter_release_rcu);
/**
* sk_attach_filter - attach a socket filter
@@ -649,7 +684,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
rcu_assign_pointer(sk->sk_filter, fp);
if (old_fp)
- sk_filter_delayed_uncharge(sk, old_fp);
+ sk_filter_uncharge(sk, old_fp);
return 0;
}
EXPORT_SYMBOL_GPL(sk_attach_filter);
@@ -663,7 +698,7 @@ int sk_detach_filter(struct sock *sk)
sock_owned_by_user(sk));
if (filter) {
rcu_assign_pointer(sk->sk_filter, NULL);
- sk_filter_delayed_uncharge(sk, filter);
+ sk_filter_uncharge(sk, filter);
ret = 0;
}
return ret;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 8cc8f9a79db9..60a902913429 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -41,7 +41,6 @@
#define NEIGH_PRINTK(x...) printk(x)
#define NEIGH_NOPRINTK(x...) do { ; } while(0)
-#define NEIGH_PRINTK0 NEIGH_PRINTK
#define NEIGH_PRINTK1 NEIGH_NOPRINTK
#define NEIGH_PRINTK2 NEIGH_NOPRINTK
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 7f902cad10f8..e23c01be5a5b 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -706,7 +706,6 @@ static struct attribute *rx_queue_default_attrs[] = {
static void rx_queue_release(struct kobject *kobj)
{
struct netdev_rx_queue *queue = to_rx_queue(kobj);
- struct netdev_rx_queue *first = queue->first;
struct rps_map *map;
struct rps_dev_flow_table *flow_table;
@@ -723,10 +722,8 @@ static void rx_queue_release(struct kobject *kobj)
call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
}
- if (atomic_dec_and_test(&first->count))
- kfree(first);
- else
- memset(kobj, 0, sizeof(*kobj));
+ memset(kobj, 0, sizeof(*kobj));
+ dev_put(queue->dev);
}
static struct kobj_type rx_queue_ktype = {
@@ -738,7 +735,6 @@ static struct kobj_type rx_queue_ktype = {
static int rx_queue_add_kobject(struct net_device *net, int index)
{
struct netdev_rx_queue *queue = net->_rx + index;
- struct netdev_rx_queue *first = queue->first;
struct kobject *kobj = &queue->kobj;
int error = 0;
@@ -751,14 +747,16 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
}
kobject_uevent(kobj, KOBJ_ADD);
- atomic_inc(&first->count);
+ dev_hold(queue->dev);
return error;
}
+#endif /* CONFIG_RPS */
int
net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
{
+#ifdef CONFIG_RPS
int i;
int error = 0;
@@ -774,23 +772,423 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
kobject_put(&net->_rx[i].kobj);
return error;
+#else
+ return 0;
+#endif
+}
+
+#ifdef CONFIG_XPS
+/*
+ * netdev_queue sysfs structures and functions.
+ */
+struct netdev_queue_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct netdev_queue *queue,
+ struct netdev_queue_attribute *attr, char *buf);
+ ssize_t (*store)(struct netdev_queue *queue,
+ struct netdev_queue_attribute *attr, const char *buf, size_t len);
+};
+#define to_netdev_queue_attr(_attr) container_of(_attr, \
+ struct netdev_queue_attribute, attr)
+
+#define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj)
+
+static ssize_t netdev_queue_attr_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr);
+ struct netdev_queue *queue = to_netdev_queue(kobj);
+
+ if (!attribute->show)
+ return -EIO;
+
+ return attribute->show(queue, attribute, buf);
}
-static int rx_queue_register_kobjects(struct net_device *net)
+static ssize_t netdev_queue_attr_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf, size_t count)
{
+ struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr);
+ struct netdev_queue *queue = to_netdev_queue(kobj);
+
+ if (!attribute->store)
+ return -EIO;
+
+ return attribute->store(queue, attribute, buf, count);
+}
+
+static const struct sysfs_ops netdev_queue_sysfs_ops = {
+ .show = netdev_queue_attr_show,
+ .store = netdev_queue_attr_store,
+};
+
+static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
+{
+ struct net_device *dev = queue->dev;
+ int i;
+
+ for (i = 0; i < dev->num_tx_queues; i++)
+ if (queue == &dev->_tx[i])
+ break;
+
+ BUG_ON(i >= dev->num_tx_queues);
+
+ return i;
+}
+
+
+static ssize_t show_xps_map(struct netdev_queue *queue,
+ struct netdev_queue_attribute *attribute, char *buf)
+{
+ struct net_device *dev = queue->dev;
+ struct xps_dev_maps *dev_maps;
+ cpumask_var_t mask;
+ unsigned long index;
+ size_t len = 0;
+ int i;
+
+ if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ index = get_netdev_queue_index(queue);
+
+ rcu_read_lock();
+ dev_maps = rcu_dereference(dev->xps_maps);
+ if (dev_maps) {
+ for_each_possible_cpu(i) {
+ struct xps_map *map =
+ rcu_dereference(dev_maps->cpu_map[i]);
+ if (map) {
+ int j;
+ for (j = 0; j < map->len; j++) {
+ if (map->queues[j] == index) {
+ cpumask_set_cpu(i, mask);
+ break;
+ }
+ }
+ }
+ }
+ }
+ rcu_read_unlock();
+
+ len += cpumask_scnprintf(buf + len, PAGE_SIZE, mask);
+ if (PAGE_SIZE - len < 3) {
+ free_cpumask_var(mask);
+ return -EINVAL;
+ }
+
+ free_cpumask_var(mask);
+ len += sprintf(buf + len, "\n");
+ return len;
+}
+
+static void xps_map_release(struct rcu_head *rcu)
+{
+ struct xps_map *map = container_of(rcu, struct xps_map, rcu);
+
+ kfree(map);
+}
+
+static void xps_dev_maps_release(struct rcu_head *rcu)
+{
+ struct xps_dev_maps *dev_maps =
+ container_of(rcu, struct xps_dev_maps, rcu);
+
+ kfree(dev_maps);
+}
+
+static DEFINE_MUTEX(xps_map_mutex);
+#define xmap_dereference(P) \
+ rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex))
+
+static ssize_t store_xps_map(struct netdev_queue *queue,
+ struct netdev_queue_attribute *attribute,
+ const char *buf, size_t len)
+{
+ struct net_device *dev = queue->dev;
+ cpumask_var_t mask;
+ int err, i, cpu, pos, map_len, alloc_len, need_set;
+ unsigned long index;
+ struct xps_map *map, *new_map;
+ struct xps_dev_maps *dev_maps, *new_dev_maps;
+ int nonempty = 0;
+ int numa_node = -2;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ index = get_netdev_queue_index(queue);
+
+ err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
+ if (err) {
+ free_cpumask_var(mask);
+ return err;
+ }
+
+ new_dev_maps = kzalloc(max_t(unsigned,
+ XPS_DEV_MAPS_SIZE, L1_CACHE_BYTES), GFP_KERNEL);
+ if (!new_dev_maps) {
+ free_cpumask_var(mask);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&xps_map_mutex);
+
+ dev_maps = xmap_dereference(dev->xps_maps);
+
+ for_each_possible_cpu(cpu) {
+ map = dev_maps ?
+ xmap_dereference(dev_maps->cpu_map[cpu]) : NULL;
+ new_map = map;
+ if (map) {
+ for (pos = 0; pos < map->len; pos++)
+ if (map->queues[pos] == index)
+ break;
+ map_len = map->len;
+ alloc_len = map->alloc_len;
+ } else
+ pos = map_len = alloc_len = 0;
+
+ need_set = cpu_isset(cpu, *mask) && cpu_online(cpu);
+#ifdef CONFIG_NUMA
+ if (need_set) {
+ if (numa_node == -2)
+ numa_node = cpu_to_node(cpu);
+ else if (numa_node != cpu_to_node(cpu))
+ numa_node = -1;
+ }
+#endif
+ if (need_set && pos >= map_len) {
+ /* Need to add queue to this CPU's map */
+ if (map_len >= alloc_len) {
+ alloc_len = alloc_len ?
+ 2 * alloc_len : XPS_MIN_MAP_ALLOC;
+ new_map = kzalloc_node(XPS_MAP_SIZE(alloc_len),
+ GFP_KERNEL,
+ cpu_to_node(cpu));
+ if (!new_map)
+ goto error;
+ new_map->alloc_len = alloc_len;
+ for (i = 0; i < map_len; i++)
+ new_map->queues[i] = map->queues[i];
+ new_map->len = map_len;
+ }
+ new_map->queues[new_map->len++] = index;
+ } else if (!need_set && pos < map_len) {
+ /* Need to remove queue from this CPU's map */
+ if (map_len > 1)
+ new_map->queues[pos] =
+ new_map->queues[--new_map->len];
+ else
+ new_map = NULL;
+ }
+ RCU_INIT_POINTER(new_dev_maps->cpu_map[cpu], new_map);
+ }
+
+ /* Cleanup old maps */
+ for_each_possible_cpu(cpu) {
+ map = dev_maps ?
+ xmap_dereference(dev_maps->cpu_map[cpu]) : NULL;
+ if (map && xmap_dereference(new_dev_maps->cpu_map[cpu]) != map)
+ call_rcu(&map->rcu, xps_map_release);
+ if (new_dev_maps->cpu_map[cpu])
+ nonempty = 1;
+ }
+
+ if (nonempty)
+ rcu_assign_pointer(dev->xps_maps, new_dev_maps);
+ else {
+ kfree(new_dev_maps);
+ rcu_assign_pointer(dev->xps_maps, NULL);
+ }
+
+ if (dev_maps)
+ call_rcu(&dev_maps->rcu, xps_dev_maps_release);
+
+ netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node :
+ NUMA_NO_NODE);
+
+ mutex_unlock(&xps_map_mutex);
+
+ free_cpumask_var(mask);
+ return len;
+
+error:
+ mutex_unlock(&xps_map_mutex);
+
+ if (new_dev_maps)
+ for_each_possible_cpu(i)
+ kfree(rcu_dereference_protected(
+ new_dev_maps->cpu_map[i],
+ 1));
+ kfree(new_dev_maps);
+ free_cpumask_var(mask);
+ return -ENOMEM;
+}
+
+static struct netdev_queue_attribute xps_cpus_attribute =
+ __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map);
+
+static struct attribute *netdev_queue_default_attrs[] = {
+ &xps_cpus_attribute.attr,
+ NULL
+};
+
+static void netdev_queue_release(struct kobject *kobj)
+{
+ struct netdev_queue *queue = to_netdev_queue(kobj);
+ struct net_device *dev = queue->dev;
+ struct xps_dev_maps *dev_maps;
+ struct xps_map *map;
+ unsigned long index;
+ int i, pos, nonempty = 0;
+
+ index = get_netdev_queue_index(queue);
+
+ mutex_lock(&xps_map_mutex);
+ dev_maps = xmap_dereference(dev->xps_maps);
+
+ if (dev_maps) {
+ for_each_possible_cpu(i) {
+ map = xmap_dereference(dev_maps->cpu_map[i]);
+ if (!map)
+ continue;
+
+ for (pos = 0; pos < map->len; pos++)
+ if (map->queues[pos] == index)
+ break;
+
+ if (pos < map->len) {
+ if (map->len > 1)
+ map->queues[pos] =
+ map->queues[--map->len];
+ else {
+ RCU_INIT_POINTER(dev_maps->cpu_map[i],
+ NULL);
+ call_rcu(&map->rcu, xps_map_release);
+ map = NULL;
+ }
+ }
+ if (map)
+ nonempty = 1;
+ }
+
+ if (!nonempty) {
+ RCU_INIT_POINTER(dev->xps_maps, NULL);
+ call_rcu(&dev_maps->rcu, xps_dev_maps_release);
+ }
+ }
+
+ mutex_unlock(&xps_map_mutex);
+
+ memset(kobj, 0, sizeof(*kobj));
+ dev_put(queue->dev);
+}
+
+static struct kobj_type netdev_queue_ktype = {
+ .sysfs_ops = &netdev_queue_sysfs_ops,
+ .release = netdev_queue_release,
+ .default_attrs = netdev_queue_default_attrs,
+};
+
+static int netdev_queue_add_kobject(struct net_device *net, int index)
+{
+ struct netdev_queue *queue = net->_tx + index;
+ struct kobject *kobj = &queue->kobj;
+ int error = 0;
+
+ kobj->kset = net->queues_kset;
+ error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL,
+ "tx-%u", index);
+ if (error) {
+ kobject_put(kobj);
+ return error;
+ }
+
+ kobject_uevent(kobj, KOBJ_ADD);
+ dev_hold(queue->dev);
+
+ return error;
+}
+#endif /* CONFIG_XPS */
+
+int
+netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
+{
+#ifdef CONFIG_XPS
+ int i;
+ int error = 0;
+
+ for (i = old_num; i < new_num; i++) {
+ error = netdev_queue_add_kobject(net, i);
+ if (error) {
+ new_num = old_num;
+ break;
+ }
+ }
+
+ while (--i >= new_num)
+ kobject_put(&net->_tx[i].kobj);
+
+ return error;
+#else
+ return 0;
+#endif
+}
+
+static int register_queue_kobjects(struct net_device *net)
+{
+ int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0;
+
+#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
net->queues_kset = kset_create_and_add("queues",
NULL, &net->dev.kobj);
if (!net->queues_kset)
return -ENOMEM;
- return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues);
+#endif
+
+#ifdef CONFIG_RPS
+ real_rx = net->real_num_rx_queues;
+#endif
+ real_tx = net->real_num_tx_queues;
+
+ error = net_rx_queue_update_kobjects(net, 0, real_rx);
+ if (error)
+ goto error;
+ rxq = real_rx;
+
+ error = netdev_queue_update_kobjects(net, 0, real_tx);
+ if (error)
+ goto error;
+ txq = real_tx;
+
+ return 0;
+
+error:
+ netdev_queue_update_kobjects(net, txq, 0);
+ net_rx_queue_update_kobjects(net, rxq, 0);
+ return error;
}
-static void rx_queue_remove_kobjects(struct net_device *net)
+static void remove_queue_kobjects(struct net_device *net)
{
- net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0);
+ int real_rx = 0, real_tx = 0;
+
+#ifdef CONFIG_RPS
+ real_rx = net->real_num_rx_queues;
+#endif
+ real_tx = net->real_num_tx_queues;
+
+ net_rx_queue_update_kobjects(net, real_rx, 0);
+ netdev_queue_update_kobjects(net, real_tx, 0);
+#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
kset_unregister(net->queues_kset);
+#endif
}
-#endif /* CONFIG_RPS */
static const void *net_current_ns(void)
{
@@ -889,9 +1287,7 @@ void netdev_unregister_kobject(struct net_device * net)
kobject_get(&dev->kobj);
-#ifdef CONFIG_RPS
- rx_queue_remove_kobjects(net);
-#endif
+ remove_queue_kobjects(net);
device_del(dev);
}
@@ -930,13 +1326,11 @@ int netdev_register_kobject(struct net_device *net)
if (error)
return error;
-#ifdef CONFIG_RPS
- error = rx_queue_register_kobjects(net);
+ error = register_queue_kobjects(net);
if (error) {
device_del(dev);
return error;
}
-#endif
return error;
}
diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h
index 778e1571548d..bd7751ec1c4d 100644
--- a/net/core/net-sysfs.h
+++ b/net/core/net-sysfs.h
@@ -4,8 +4,8 @@
int netdev_kobject_init(void);
int netdev_register_kobject(struct net_device *);
void netdev_unregister_kobject(struct net_device *);
-#ifdef CONFIG_RPS
int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num);
-#endif
+int netdev_queue_update_kobjects(struct net_device *net,
+ int old_num, int new_num);
#endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 4e98ffac3af0..72d9b50109fc 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -35,7 +35,6 @@
#define MAX_UDP_CHUNK 1460
#define MAX_SKBS 32
-#define MAX_QUEUE_DEPTH (MAX_SKBS / 2)
static struct sk_buff_head skb_pool;
@@ -76,8 +75,7 @@ static void queue_process(struct work_struct *work)
local_irq_save(flags);
__netif_tx_lock(txq, smp_processor_id());
- if (netif_tx_queue_stopped(txq) ||
- netif_tx_queue_frozen(txq) ||
+ if (netif_tx_queue_frozen_or_stopped(txq) ||
ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb);
__netif_tx_unlock(txq);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 33bc3823ac6f..a9e7fc4c461f 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -378,6 +378,7 @@ struct pktgen_dev {
u16 queue_map_min;
u16 queue_map_max;
+ __u32 skb_priority; /* skb priority field */
int node; /* Memory node */
#ifdef CONFIG_XFRM
@@ -394,6 +395,8 @@ struct pktgen_hdr {
__be32 tv_usec;
};
+static bool pktgen_exiting __read_mostly;
+
struct pktgen_thread {
spinlock_t if_lock; /* for list of devices */
struct list_head if_list; /* All device here */
@@ -547,6 +550,10 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
pkt_dev->queue_map_min,
pkt_dev->queue_map_max);
+ if (pkt_dev->skb_priority)
+ seq_printf(seq, " skb_priority: %u\n",
+ pkt_dev->skb_priority);
+
if (pkt_dev->flags & F_IPV6) {
char b1[128], b2[128], b3[128];
fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
@@ -1711,6 +1718,18 @@ static ssize_t pktgen_if_write(struct file *file,
return count;
}
+ if (!strcmp(name, "skb_priority")) {
+ len = num_arg(&user_buffer[i], 9, &value);
+ if (len < 0)
+ return len;
+
+ i += len;
+ pkt_dev->skb_priority = value;
+ sprintf(pg_result, "OK: skb_priority=%i",
+ pkt_dev->skb_priority);
+ return count;
+ }
+
sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
return -EINVAL;
}
@@ -2641,6 +2660,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
sprintf(pkt_dev->result, "No memory");
return NULL;
}
+ prefetchw(skb->data);
skb_reserve(skb, datalen);
@@ -2671,6 +2691,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
skb->transport_header = skb->network_header + sizeof(struct iphdr);
skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
skb_set_queue_mapping(skb, queue_map);
+ skb->priority = pkt_dev->skb_priority;
+
iph = ip_hdr(skb);
udph = udp_hdr(skb);
@@ -2986,6 +3008,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
sprintf(pkt_dev->result, "No memory");
return NULL;
}
+ prefetchw(skb->data);
skb_reserve(skb, 16);
@@ -3016,6 +3039,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
skb_set_queue_mapping(skb, queue_map);
+ skb->priority = pkt_dev->skb_priority;
iph = ipv6_hdr(skb);
udph = udp_hdr(skb);
@@ -3431,11 +3455,6 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
remove_proc_entry(t->tsk->comm, pg_proc_dir);
- mutex_lock(&pktgen_thread_lock);
-
- list_del(&t->th_list);
-
- mutex_unlock(&pktgen_thread_lock);
}
static void pktgen_resched(struct pktgen_dev *pkt_dev)
@@ -3510,7 +3529,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
__netif_tx_lock_bh(txq);
- if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq))) {
+ if (unlikely(netif_tx_queue_frozen_or_stopped(txq))) {
ret = NETDEV_TX_BUSY;
pkt_dev->last_ok = 0;
goto unlock;
@@ -3534,8 +3553,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
break;
default: /* Drivers are not supposed to return other values! */
if (net_ratelimit())
- pr_info("pktgen: %s xmit error: %d\n",
- pkt_dev->odevname, ret);
+ pr_info("%s xmit error: %d\n", pkt_dev->odevname, ret);
pkt_dev->errors++;
/* fallthru */
case NETDEV_TX_LOCKED:
@@ -3582,6 +3600,8 @@ static int pktgen_thread_worker(void *arg)
pkt_dev = next_to_run(t);
if (unlikely(!pkt_dev && t->control == 0)) {
+ if (pktgen_exiting)
+ break;
wait_event_interruptible_timeout(t->queue,
t->control != 0,
HZ/10);
@@ -3634,6 +3654,13 @@ static int pktgen_thread_worker(void *arg)
pr_debug("%s removing thread\n", t->tsk->comm);
pktgen_rem_thread(t);
+ /* Wait for kthread_stop */
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+
return 0;
}
@@ -3908,6 +3935,7 @@ static void __exit pg_cleanup(void)
struct list_head *q, *n;
/* Stop all interfaces & threads */
+ pktgen_exiting = true;
list_for_each_safe(q, n, &pktgen_threads) {
t = list_entry(q, struct pktgen_thread, th_list);
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index fceeb37d7161..182236b2510a 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -33,6 +33,7 @@
* Note : Dont forget somaxconn that may limit backlog too.
*/
int sysctl_max_syn_backlog = 256;
+EXPORT_SYMBOL(sysctl_max_syn_backlog);
int reqsk_queue_alloc(struct request_sock_queue *queue,
unsigned int nr_table_entries)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 841c287ef40a..750db57f3bb3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -362,6 +362,95 @@ static size_t rtnl_link_get_size(const struct net_device *dev)
return size;
}
+static LIST_HEAD(rtnl_af_ops);
+
+static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
+{
+ const struct rtnl_af_ops *ops;
+
+ list_for_each_entry(ops, &rtnl_af_ops, list) {
+ if (ops->family == family)
+ return ops;
+ }
+
+ return NULL;
+}
+
+/**
+ * __rtnl_af_register - Register rtnl_af_ops with rtnetlink.
+ * @ops: struct rtnl_af_ops * to register
+ *
+ * The caller must hold the rtnl_mutex.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int __rtnl_af_register(struct rtnl_af_ops *ops)
+{
+ list_add_tail(&ops->list, &rtnl_af_ops);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__rtnl_af_register);
+
+/**
+ * rtnl_af_register - Register rtnl_af_ops with rtnetlink.
+ * @ops: struct rtnl_af_ops * to register
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int rtnl_af_register(struct rtnl_af_ops *ops)
+{
+ int err;
+
+ rtnl_lock();
+ err = __rtnl_af_register(ops);
+ rtnl_unlock();
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtnl_af_register);
+
+/**
+ * __rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink.
+ * @ops: struct rtnl_af_ops * to unregister
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+void __rtnl_af_unregister(struct rtnl_af_ops *ops)
+{
+ list_del(&ops->list);
+}
+EXPORT_SYMBOL_GPL(__rtnl_af_unregister);
+
+/**
+ * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink.
+ * @ops: struct rtnl_af_ops * to unregister
+ */
+void rtnl_af_unregister(struct rtnl_af_ops *ops)
+{
+ rtnl_lock();
+ __rtnl_af_unregister(ops);
+ rtnl_unlock();
+}
+EXPORT_SYMBOL_GPL(rtnl_af_unregister);
+
+static size_t rtnl_link_get_af_size(const struct net_device *dev)
+{
+ struct rtnl_af_ops *af_ops;
+ size_t size;
+
+ /* IFLA_AF_SPEC */
+ size = nla_total_size(sizeof(struct nlattr));
+
+ list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ if (af_ops->get_link_af_size) {
+ /* AF_* + nested data */
+ size += nla_total_size(sizeof(struct nlattr)) +
+ af_ops->get_link_af_size(dev);
+ }
+ }
+
+ return size;
+}
+
static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
{
const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
@@ -671,7 +760,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev)
+ nla_total_size(4) /* IFLA_NUM_VF */
+ rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
- + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
+ + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
+ + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
}
static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
@@ -757,7 +847,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
struct nlmsghdr *nlh;
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *stats;
- struct nlattr *attr;
+ struct nlattr *attr, *af_spec;
+ struct rtnl_af_ops *af_ops;
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
if (nlh == NULL)
@@ -866,6 +957,36 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
}
+ if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
+ goto nla_put_failure;
+
+ list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ if (af_ops->fill_link_af) {
+ struct nlattr *af;
+ int err;
+
+ if (!(af = nla_nest_start(skb, af_ops->family)))
+ goto nla_put_failure;
+
+ err = af_ops->fill_link_af(skb, dev);
+
+ /*
+ * Caller may return ENODATA to indicate that there
+ * was no data to be dumped. This is not an error, it
+ * means we should trim the attribute header and
+ * continue.
+ */
+ if (err == -ENODATA)
+ nla_nest_cancel(skb, af);
+ else if (err < 0)
+ goto nla_put_failure;
+
+ nla_nest_end(skb, af);
+ }
+ }
+
+ nla_nest_end(skb, af_spec);
+
return nlmsg_end(skb, nlh);
nla_put_failure:
@@ -924,6 +1045,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
[IFLA_VF_PORTS] = { .type = NLA_NESTED },
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
+ [IFLA_AF_SPEC] = { .type = NLA_NESTED },
};
EXPORT_SYMBOL(ifla_policy);
@@ -985,6 +1107,28 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
return -EINVAL;
}
+ if (tb[IFLA_AF_SPEC]) {
+ struct nlattr *af;
+ int rem, err;
+
+ nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
+ const struct rtnl_af_ops *af_ops;
+
+ if (!(af_ops = rtnl_af_lookup(nla_type(af))))
+ return -EAFNOSUPPORT;
+
+ if (!af_ops->set_link_af)
+ return -EOPNOTSUPP;
+
+ if (af_ops->validate_link_af) {
+ err = af_ops->validate_link_af(dev,
+ tb[IFLA_AF_SPEC]);
+ if (err < 0)
+ return err;
+ }
+ }
+ }
+
return 0;
}
@@ -1225,6 +1369,24 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
goto errout;
modified = 1;
}
+
+ if (tb[IFLA_AF_SPEC]) {
+ struct nlattr *af;
+ int rem;
+
+ nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
+ const struct rtnl_af_ops *af_ops;
+
+ if (!(af_ops = rtnl_af_lookup(nla_type(af))))
+ BUG();
+
+ err = af_ops->set_link_af(dev, af);
+ if (err < 0)
+ goto errout;
+
+ modified = 1;
+ }
+ }
err = 0;
errout:
diff --git a/net/core/scm.c b/net/core/scm.c
index 413cab89017d..bbe454450801 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -79,10 +79,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
return -ENOMEM;
*fplp = fpl;
fpl->count = 0;
+ fpl->max = SCM_MAX_FD;
}
fpp = &fpl->fp[fpl->count];
- if (fpl->count + num > SCM_MAX_FD)
+ if (fpl->count + num > fpl->max)
return -EINVAL;
/*
@@ -331,11 +332,12 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
if (!fpl)
return NULL;
- new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
+ new_fpl = kmemdup(fpl, offsetof(struct scm_fp_list, fp[fpl->count]),
+ GFP_KERNEL);
if (new_fpl) {
- for (i=fpl->count-1; i>=0; i--)
+ for (i = 0; i < fpl->count; i++)
get_file(fpl->fp[i]);
- memcpy(new_fpl, fpl, sizeof(*fpl));
+ new_fpl->max = new_fpl->count;
}
return new_fpl;
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 104f8444754a..19d6c21220fd 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -778,6 +778,28 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
size = SKB_DATA_ALIGN(size);
+ /* Check if we can avoid taking references on fragments if we own
+ * the last reference on skb->head. (see skb_release_data())
+ */
+ if (!skb->cloned)
+ fastpath = true;
+ else {
+ int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
+
+ fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
+ }
+
+ if (fastpath &&
+ size + sizeof(struct skb_shared_info) <= ksize(skb->head)) {
+ memmove(skb->head + size, skb_shinfo(skb),
+ offsetof(struct skb_shared_info,
+ frags[skb_shinfo(skb)->nr_frags]));
+ memmove(skb->head + nhead, skb->head,
+ skb_tail_pointer(skb) - skb->head);
+ off = nhead;
+ goto adjust_others;
+ }
+
data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
if (!data)
goto nodata;
@@ -791,17 +813,6 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
skb_shinfo(skb),
offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
- /* Check if we can avoid taking references on fragments if we own
- * the last reference on skb->head. (see skb_release_data())
- */
- if (!skb->cloned)
- fastpath = true;
- else {
- int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
-
- fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
- }
-
if (fastpath) {
kfree(skb->head);
} else {
@@ -816,6 +827,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
off = (data + nhead) - skb->head;
skb->head = data;
+adjust_others:
skb->data += off;
#ifdef NET_SKBUFF_DATA_USES_OFFSET
skb->end = size;
@@ -1812,7 +1824,7 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
long csstart;
if (skb->ip_summed == CHECKSUM_PARTIAL)
- csstart = skb->csum_start - skb_headroom(skb);
+ csstart = skb_checksum_start_offset(skb);
else
csstart = skb_headlen(skb);
diff --git a/net/core/sock.c b/net/core/sock.c
index fb6080111461..d6d4337ff9a0 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -157,7 +157,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
"sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" ,
"sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
"sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
- "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" ,
+ "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" ,
"sk_lock-AF_MAX"
};
static const char *const af_family_slock_key_strings[AF_MAX+1] = {
@@ -173,7 +173,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
"slock-27" , "slock-28" , "slock-AF_CAN" ,
"slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
"slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
- "slock-AF_IEEE802154", "slock-AF_CAIF" ,
+ "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" ,
"slock-AF_MAX"
};
static const char *const af_family_clock_key_strings[AF_MAX+1] = {
@@ -189,7 +189,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
"clock-27" , "clock-28" , "clock-AF_CAN" ,
"clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
"clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
- "clock-AF_IEEE802154", "clock-AF_CAIF" ,
+ "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" ,
"clock-AF_MAX"
};
@@ -992,23 +992,54 @@ static inline void sock_lock_init(struct sock *sk)
/*
* Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet,
* even temporarly, because of RCU lookups. sk_node should also be left as is.
+ * We must not copy fields between sk_dontcopy_begin and sk_dontcopy_end
*/
static void sock_copy(struct sock *nsk, const struct sock *osk)
{
#ifdef CONFIG_SECURITY_NETWORK
void *sptr = nsk->sk_security;
#endif
- BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) !=
- sizeof(osk->sk_node) + sizeof(osk->sk_refcnt) +
- sizeof(osk->sk_tx_queue_mapping));
- memcpy(&nsk->sk_copy_start, &osk->sk_copy_start,
- osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start));
+ memcpy(nsk, osk, offsetof(struct sock, sk_dontcopy_begin));
+
+ memcpy(&nsk->sk_dontcopy_end, &osk->sk_dontcopy_end,
+ osk->sk_prot->obj_size - offsetof(struct sock, sk_dontcopy_end));
+
#ifdef CONFIG_SECURITY_NETWORK
nsk->sk_security = sptr;
security_sk_clone(osk, nsk);
#endif
}
+/*
+ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
+ * un-modified. Special care is taken when initializing object to zero.
+ */
+static inline void sk_prot_clear_nulls(struct sock *sk, int size)
+{
+ if (offsetof(struct sock, sk_node.next) != 0)
+ memset(sk, 0, offsetof(struct sock, sk_node.next));
+ memset(&sk->sk_node.pprev, 0,
+ size - offsetof(struct sock, sk_node.pprev));
+}
+
+void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
+{
+ unsigned long nulls1, nulls2;
+
+ nulls1 = offsetof(struct sock, __sk_common.skc_node.next);
+ nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next);
+ if (nulls1 > nulls2)
+ swap(nulls1, nulls2);
+
+ if (nulls1 != 0)
+ memset((char *)sk, 0, nulls1);
+ memset((char *)sk + nulls1 + sizeof(void *), 0,
+ nulls2 - nulls1 - sizeof(void *));
+ memset((char *)sk + nulls2 + sizeof(void *), 0,
+ size - nulls2 - sizeof(void *));
+}
+EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls);
+
static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
int family)
{
@@ -1021,19 +1052,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
if (!sk)
return sk;
if (priority & __GFP_ZERO) {
- /*
- * caches using SLAB_DESTROY_BY_RCU should let
- * sk_node.next un-modified. Special care is taken
- * when initializing object to zero.
- */
- if (offsetof(struct sock, sk_node.next) != 0)
- memset(sk, 0, offsetof(struct sock, sk_node.next));
- memset(&sk->sk_node.pprev, 0,
- prot->obj_size - offsetof(struct sock,
- sk_node.pprev));
+ if (prot->clear_sk)
+ prot->clear_sk(sk, prot->obj_size);
+ else
+ sk_prot_clear_nulls(sk, prot->obj_size);
}
- }
- else
+ } else
sk = kmalloc(prot->obj_size, priority);
if (sk != NULL) {
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 0ae6c22da85b..7e7ca375d431 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -26,12 +26,12 @@ static struct sock_filter ptp_filter[] = {
PTP_FILTER
};
-static unsigned int classify(struct sk_buff *skb)
+static unsigned int classify(const struct sk_buff *skb)
{
if (likely(skb->dev &&
skb->dev->phydev &&
skb->dev->phydev->drv))
- return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter));
+ return sk_run_filter(skb, ptp_filter);
else
return PTP_CLASS_NONE;
}
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
struct phy_device *phydev;
unsigned int type;
- skb_push(skb, ETH_HLEN);
+ if (skb_headroom(skb) < ETH_HLEN)
+ return false;
+ __skb_push(skb, ETH_HLEN);
type = classify(skb);
- skb_pull(skb, ETH_HLEN);
+ __skb_pull(skb, ETH_HLEN);
switch (type) {
case PTP_CLASS_V1_IPV4:
diff --git a/net/dcb/Makefile b/net/dcb/Makefile
index 9930f4cde818..c1282c9e64fa 100644
--- a/net/dcb/Makefile
+++ b/net/dcb/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_DCB) += dcbnl.o
+obj-$(CONFIG_DCB) += dcbnl.o dcbevent.o
diff --git a/net/dcb/dcbevent.c b/net/dcb/dcbevent.c
new file mode 100644
index 000000000000..665a8802105a
--- /dev/null
+++ b/net/dcb/dcbevent.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Author: John Fastabend <john.r.fastabend@intel.com>
+ */
+
+#include <linux/rtnetlink.h>
+#include <linux/notifier.h>
+
+static ATOMIC_NOTIFIER_HEAD(dcbevent_notif_chain);
+
+int register_dcbevent_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&dcbevent_notif_chain, nb);
+}
+EXPORT_SYMBOL(register_dcbevent_notifier);
+
+int unregister_dcbevent_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&dcbevent_notif_chain, nb);
+}
+EXPORT_SYMBOL(unregister_dcbevent_notifier);
+
+int call_dcbevent_notifiers(unsigned long val, void *v)
+{
+ return atomic_notifier_call_chain(&dcbevent_notif_chain, val, v);
+}
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 19ac2b985485..9399af565715 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -23,6 +23,7 @@
#include <net/netlink.h>
#include <net/rtnetlink.h>
#include <linux/dcbnl.h>
+#include <net/dcbevent.h>
#include <linux/rtnetlink.h>
#include <net/sock.h>
@@ -66,6 +67,9 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
[DCB_ATTR_PFC_STATE] = {.type = NLA_U8},
[DCB_ATTR_BCN] = {.type = NLA_NESTED},
[DCB_ATTR_APP] = {.type = NLA_NESTED},
+ [DCB_ATTR_IEEE] = {.type = NLA_NESTED},
+ [DCB_ATTR_DCBX] = {.type = NLA_U8},
+ [DCB_ATTR_FEATCFG] = {.type = NLA_NESTED},
};
/* DCB priority flow control to User Priority nested attributes */
@@ -122,6 +126,7 @@ static const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = {
[DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8},
[DCB_CAP_ATTR_GSP] = {.type = NLA_U8},
[DCB_CAP_ATTR_BCN] = {.type = NLA_U8},
+ [DCB_CAP_ATTR_DCBX] = {.type = NLA_U8},
};
/* DCB capabilities nested attributes. */
@@ -167,6 +172,28 @@ static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = {
[DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8},
};
+/* IEEE 802.1Qaz nested attributes. */
+static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = {
+ [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)},
+ [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
+ [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
+};
+
+static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
+ [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)},
+};
+
+/* DCB number of traffic classes nested attributes. */
+static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = {
+ [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG},
+ [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8},
+ [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8},
+ [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8},
+};
+
+static LIST_HEAD(dcb_app_list);
+static DEFINE_SPINLOCK(dcb_lock);
+
/* standard netlink reply call */
static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
u32 seq, u16 flags)
@@ -622,12 +649,12 @@ out:
static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
{
- int ret = -EINVAL;
+ int err, ret = -EINVAL;
u16 id;
u8 up, idtype;
struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
- if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp)
+ if (!tb[DCB_ATTR_APP])
goto out;
ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
@@ -651,9 +678,18 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
- ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up),
- RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
- pid, seq, flags);
+ if (netdev->dcbnl_ops->setapp) {
+ err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up);
+ } else {
+ struct dcb_app app;
+ app.selector = idtype;
+ app.protocol = id;
+ app.priority = up;
+ err = dcb_setapp(netdev, &app);
+ }
+
+ ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
+ pid, seq, flags);
out:
return ret;
}
@@ -1118,6 +1154,276 @@ err:
return ret;
}
+/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
+ * be completed the entire msg is aborted and error value is returned.
+ * No attempt is made to reconcile the case where only part of the
+ * cmd can be completed.
+ */
+static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
+ struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
+ int err = -EOPNOTSUPP;
+
+ if (!ops)
+ goto err;
+
+ err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
+ tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
+ if (err)
+ goto err;
+
+ if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
+ struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
+ err = ops->ieee_setets(netdev, ets);
+ if (err)
+ goto err;
+ }
+
+ if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) {
+ struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
+ err = ops->ieee_setpfc(netdev, pfc);
+ if (err)
+ goto err;
+ }
+
+ if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
+ struct nlattr *attr;
+ int rem;
+
+ nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
+ struct dcb_app *app_data;
+ if (nla_type(attr) != DCB_ATTR_IEEE_APP)
+ continue;
+ app_data = nla_data(attr);
+ if (ops->ieee_setapp)
+ err = ops->ieee_setapp(netdev, app_data);
+ else
+ err = dcb_setapp(netdev, app_data);
+ if (err)
+ goto err;
+ }
+ }
+
+err:
+ dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
+ pid, seq, flags);
+ return err;
+}
+
+
+/* Handle IEEE 802.1Qaz GET commands. */
+static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct dcbmsg *dcb;
+ struct nlattr *ieee, *app;
+ struct dcb_app_type *itr;
+ const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
+ int err;
+
+ if (!ops)
+ return -EOPNOTSUPP;
+
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!skb)
+ return -ENOBUFS;
+
+ nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
+
+ dcb = NLMSG_DATA(nlh);
+ dcb->dcb_family = AF_UNSPEC;
+ dcb->cmd = DCB_CMD_IEEE_GET;
+
+ NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
+
+ ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
+ if (!ieee)
+ goto nla_put_failure;
+
+ if (ops->ieee_getets) {
+ struct ieee_ets ets;
+ err = ops->ieee_getets(netdev, &ets);
+ if (!err)
+ NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
+ }
+
+ if (ops->ieee_getpfc) {
+ struct ieee_pfc pfc;
+ err = ops->ieee_getpfc(netdev, &pfc);
+ if (!err)
+ NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
+ }
+
+ app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE);
+ if (!app)
+ goto nla_put_failure;
+
+ spin_lock(&dcb_lock);
+ list_for_each_entry(itr, &dcb_app_list, list) {
+ if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0)
+ NLA_PUT(skb, DCB_ATTR_IEEE_APP,
+ sizeof(itr->app), &itr->app);
+ }
+ spin_unlock(&dcb_lock);
+ nla_nest_end(skb, app);
+
+ nla_nest_end(skb, ieee);
+ nlmsg_end(skb, nlh);
+
+ return rtnl_unicast(skb, &init_net, pid);
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+nlmsg_failure:
+ kfree_skb(skb);
+ return -1;
+}
+
+/* DCBX configuration */
+static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ int ret;
+
+ if (!netdev->dcbnl_ops->getdcbx)
+ return -EOPNOTSUPP;
+
+ ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB,
+ DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags);
+
+ return ret;
+}
+
+static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ int ret;
+ u8 value;
+
+ if (!netdev->dcbnl_ops->setdcbx)
+ return -EOPNOTSUPP;
+
+ if (!tb[DCB_ATTR_DCBX])
+ return -EINVAL;
+
+ value = nla_get_u8(tb[DCB_ATTR_DCBX]);
+
+ ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value),
+ RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX,
+ pid, seq, flags);
+
+ return ret;
+}
+
+static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ struct sk_buff *dcbnl_skb;
+ struct nlmsghdr *nlh;
+ struct dcbmsg *dcb;
+ struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest;
+ u8 value;
+ int ret, i;
+ int getall = 0;
+
+ if (!netdev->dcbnl_ops->getfeatcfg)
+ return -EOPNOTSUPP;
+
+ if (!tb[DCB_ATTR_FEATCFG])
+ return -EINVAL;
+
+ ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
+ dcbnl_featcfg_nest);
+ if (ret)
+ goto err_out;
+
+ dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!dcbnl_skb) {
+ ret = -ENOBUFS;
+ goto err_out;
+ }
+
+ nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
+
+ dcb = NLMSG_DATA(nlh);
+ dcb->dcb_family = AF_UNSPEC;
+ dcb->cmd = DCB_CMD_GFEATCFG;
+
+ nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG);
+ if (!nest) {
+ ret = -EMSGSIZE;
+ goto nla_put_failure;
+ }
+
+ if (data[DCB_FEATCFG_ATTR_ALL])
+ getall = 1;
+
+ for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) {
+ if (!getall && !data[i])
+ continue;
+
+ ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value);
+ if (!ret)
+ ret = nla_put_u8(dcbnl_skb, i, value);
+
+ if (ret) {
+ nla_nest_cancel(dcbnl_skb, nest);
+ goto nla_put_failure;
+ }
+ }
+ nla_nest_end(dcbnl_skb, nest);
+
+ nlmsg_end(dcbnl_skb, nlh);
+
+ return rtnl_unicast(dcbnl_skb, &init_net, pid);
+nla_put_failure:
+ nlmsg_cancel(dcbnl_skb, nlh);
+nlmsg_failure:
+ kfree_skb(dcbnl_skb);
+err_out:
+ return ret;
+}
+
+static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb,
+ u32 pid, u32 seq, u16 flags)
+{
+ struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1];
+ int ret, i;
+ u8 value;
+
+ if (!netdev->dcbnl_ops->setfeatcfg)
+ return -ENOTSUPP;
+
+ if (!tb[DCB_ATTR_FEATCFG])
+ return -EINVAL;
+
+ ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
+ dcbnl_featcfg_nest);
+
+ if (ret)
+ goto err;
+
+ for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) {
+ if (data[i] == NULL)
+ continue;
+
+ value = nla_get_u8(data[i]);
+
+ ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value);
+
+ if (ret)
+ goto err;
+ }
+err:
+ dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG,
+ pid, seq, flags);
+
+ return ret;
+}
+
static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct net *net = sock_net(skb->sk);
@@ -1223,6 +1529,30 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
nlh->nlmsg_flags);
goto out;
+ case DCB_CMD_IEEE_SET:
+ ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
+ case DCB_CMD_IEEE_GET:
+ ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
+ case DCB_CMD_GDCBX:
+ ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
+ case DCB_CMD_SDCBX:
+ ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
+ case DCB_CMD_GFEATCFG:
+ ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
+ case DCB_CMD_SFEATCFG:
+ ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq,
+ nlh->nlmsg_flags);
+ goto out;
default:
goto errout;
}
@@ -1233,8 +1563,94 @@ out:
return ret;
}
+/**
+ * dcb_getapp - retrieve the DCBX application user priority
+ *
+ * On success returns a non-zero 802.1p user priority bitmap
+ * otherwise returns 0 as the invalid user priority bitmap to
+ * indicate an error.
+ */
+u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
+{
+ struct dcb_app_type *itr;
+ u8 prio = 0;
+
+ spin_lock(&dcb_lock);
+ list_for_each_entry(itr, &dcb_app_list, list) {
+ if (itr->app.selector == app->selector &&
+ itr->app.protocol == app->protocol &&
+ (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
+ prio = itr->app.priority;
+ break;
+ }
+ }
+ spin_unlock(&dcb_lock);
+
+ return prio;
+}
+EXPORT_SYMBOL(dcb_getapp);
+
+/**
+ * ixgbe_dcbnl_setapp - add dcb application data to app list
+ *
+ * Priority 0 is the default priority this removes applications
+ * from the app list if the priority is set to zero.
+ */
+u8 dcb_setapp(struct net_device *dev, struct dcb_app *new)
+{
+ struct dcb_app_type *itr;
+
+ spin_lock(&dcb_lock);
+ /* Search for existing match and replace */
+ list_for_each_entry(itr, &dcb_app_list, list) {
+ if (itr->app.selector == new->selector &&
+ itr->app.protocol == new->protocol &&
+ (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
+ if (new->priority)
+ itr->app.priority = new->priority;
+ else {
+ list_del(&itr->list);
+ kfree(itr);
+ }
+ goto out;
+ }
+ }
+ /* App type does not exist add new application type */
+ if (new->priority) {
+ struct dcb_app_type *entry;
+ entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC);
+ if (!entry) {
+ spin_unlock(&dcb_lock);
+ return -ENOMEM;
+ }
+
+ memcpy(&entry->app, new, sizeof(*new));
+ strncpy(entry->name, dev->name, IFNAMSIZ);
+ list_add(&entry->list, &dcb_app_list);
+ }
+out:
+ spin_unlock(&dcb_lock);
+ call_dcbevent_notifiers(DCB_APP_EVENT, new);
+ return 0;
+}
+EXPORT_SYMBOL(dcb_setapp);
+
+static void dcb_flushapp(void)
+{
+ struct dcb_app_type *app;
+
+ spin_lock(&dcb_lock);
+ list_for_each_entry(app, &dcb_app_list, list) {
+ list_del(&app->list);
+ kfree(app);
+ }
+ spin_unlock(&dcb_lock);
+}
+
static int __init dcbnl_init(void)
{
+ INIT_LIST_HEAD(&dcb_app_list);
+
rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL);
rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL);
@@ -1246,7 +1662,6 @@ static void __exit dcbnl_exit(void)
{
rtnl_unregister(PF_UNSPEC, RTM_GETDCB);
rtnl_unregister(PF_UNSPEC, RTM_SETDCB);
+ dcb_flushapp();
}
module_exit(dcbnl_exit);
-
-
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 2991efcc8dea..5c8362b037ed 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
-dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
-
+dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o \
+ qpolicy.o
#
# CCID algorithms to be used by dccp.ko
#
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index 92a6fcb40d7d..25b7a8d1ad58 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -1,444 +1,375 @@
/*
* net/dccp/ackvec.c
*
- * An implementation of the DCCP protocol
+ * An implementation of Ack Vectors for the DCCP protocol
+ * Copyright (c) 2007 University of Aberdeen, Scotland, UK
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.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; version 2 of the License;
*/
-
-#include "ackvec.h"
#include "dccp.h"
-
-#include <linux/init.h>
-#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/skbuff.h>
#include <linux/slab.h>
-#include <net/sock.h>
-
static struct kmem_cache *dccp_ackvec_slab;
static struct kmem_cache *dccp_ackvec_record_slab;
-static struct dccp_ackvec_record *dccp_ackvec_record_new(void)
+struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
{
- struct dccp_ackvec_record *avr =
- kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC);
+ struct dccp_ackvec *av = kmem_cache_zalloc(dccp_ackvec_slab, priority);
- if (avr != NULL)
- INIT_LIST_HEAD(&avr->avr_node);
-
- return avr;
+ if (av != NULL) {
+ av->av_buf_head = av->av_buf_tail = DCCPAV_MAX_ACKVEC_LEN - 1;
+ INIT_LIST_HEAD(&av->av_records);
+ }
+ return av;
}
-static void dccp_ackvec_record_delete(struct dccp_ackvec_record *avr)
+static void dccp_ackvec_purge_records(struct dccp_ackvec *av)
{
- if (unlikely(avr == NULL))
- return;
- /* Check if deleting a linked record */
- WARN_ON(!list_empty(&avr->avr_node));
- kmem_cache_free(dccp_ackvec_record_slab, avr);
+ struct dccp_ackvec_record *cur, *next;
+
+ list_for_each_entry_safe(cur, next, &av->av_records, avr_node)
+ kmem_cache_free(dccp_ackvec_record_slab, cur);
+ INIT_LIST_HEAD(&av->av_records);
}
-static void dccp_ackvec_insert_avr(struct dccp_ackvec *av,
- struct dccp_ackvec_record *avr)
+void dccp_ackvec_free(struct dccp_ackvec *av)
{
- /*
- * AVRs are sorted by seqno. Since we are sending them in order, we
- * just add the AVR at the head of the list.
- * -sorbo.
- */
- if (!list_empty(&av->av_records)) {
- const struct dccp_ackvec_record *head =
- list_entry(av->av_records.next,
- struct dccp_ackvec_record,
- avr_node);
- BUG_ON(before48(avr->avr_ack_seqno, head->avr_ack_seqno));
+ if (likely(av != NULL)) {
+ dccp_ackvec_purge_records(av);
+ kmem_cache_free(dccp_ackvec_slab, av);
}
-
- list_add(&avr->avr_node, &av->av_records);
}
-int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
+/**
+ * dccp_ackvec_update_records - Record information about sent Ack Vectors
+ * @av: Ack Vector records to update
+ * @seqno: Sequence number of the packet carrying the Ack Vector just sent
+ * @nonce_sum: The sum of all buffer nonces contained in the Ack Vector
+ */
+int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
- /* Figure out how many options do we need to represent the ackvec */
- const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN);
- u16 len = av->av_vec_len + 2 * nr_opts, i;
- u32 elapsed_time;
- const unsigned char *tail, *from;
- unsigned char *to;
struct dccp_ackvec_record *avr;
- suseconds_t delta;
-
- if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
- return -1;
-
- delta = ktime_us_delta(ktime_get_real(), av->av_time);
- elapsed_time = delta / 10;
- if (elapsed_time != 0 &&
- dccp_insert_option_elapsed_time(skb, elapsed_time))
- return -1;
-
- avr = dccp_ackvec_record_new();
+ avr = kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC);
if (avr == NULL)
- return -1;
-
- DCCP_SKB_CB(skb)->dccpd_opt_len += len;
-
- to = skb_push(skb, len);
- len = av->av_vec_len;
- from = av->av_buf + av->av_buf_head;
- tail = av->av_buf + DCCP_MAX_ACKVEC_LEN;
-
- for (i = 0; i < nr_opts; ++i) {
- int copylen = len;
-
- if (len > DCCP_SINGLE_OPT_MAXLEN)
- copylen = DCCP_SINGLE_OPT_MAXLEN;
-
- *to++ = DCCPO_ACK_VECTOR_0;
- *to++ = copylen + 2;
-
- /* Check if buf_head wraps */
- if (from + copylen > tail) {
- const u16 tailsize = tail - from;
-
- memcpy(to, from, tailsize);
- to += tailsize;
- len -= tailsize;
- copylen -= tailsize;
- from = av->av_buf;
- }
-
- memcpy(to, from, copylen);
- from += copylen;
- to += copylen;
- len -= copylen;
- }
+ return -ENOBUFS;
+ avr->avr_ack_seqno = seqno;
+ avr->avr_ack_ptr = av->av_buf_head;
+ avr->avr_ack_ackno = av->av_buf_ackno;
+ avr->avr_ack_nonce = nonce_sum;
+ avr->avr_ack_runlen = dccp_ackvec_runlen(av->av_buf + av->av_buf_head);
/*
- * From RFC 4340, A.2:
- *
- * For each acknowledgement it sends, the HC-Receiver will add an
- * acknowledgement record. ack_seqno will equal the HC-Receiver
- * sequence number it used for the ack packet; ack_ptr will equal
- * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
- * equal buf_nonce.
+ * When the buffer overflows, we keep no more than one record. This is
+ * the simplest way of disambiguating sender-Acks dating from before the
+ * overflow from sender-Acks which refer to after the overflow; a simple
+ * solution is preferable here since we are handling an exception.
*/
- avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
- avr->avr_ack_ptr = av->av_buf_head;
- avr->avr_ack_ackno = av->av_buf_ackno;
- avr->avr_ack_nonce = av->av_buf_nonce;
- avr->avr_sent_len = av->av_vec_len;
-
- dccp_ackvec_insert_avr(av, avr);
+ if (av->av_overflow)
+ dccp_ackvec_purge_records(av);
+ /*
+ * Since GSS is incremented for each packet, the list is automatically
+ * arranged in descending order of @ack_seqno.
+ */
+ list_add(&avr->avr_node, &av->av_records);
- dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, "
- "ack_ackno=%llu\n",
- dccp_role(sk), avr->avr_sent_len,
+ dccp_pr_debug("Added Vector, ack_seqno=%llu, ack_ackno=%llu (rl=%u)\n",
(unsigned long long)avr->avr_ack_seqno,
- (unsigned long long)avr->avr_ack_ackno);
+ (unsigned long long)avr->avr_ack_ackno,
+ avr->avr_ack_runlen);
return 0;
}
-struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
+static struct dccp_ackvec_record *dccp_ackvec_lookup(struct list_head *av_list,
+ const u64 ackno)
{
- struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority);
-
- if (av != NULL) {
- av->av_buf_head = DCCP_MAX_ACKVEC_LEN - 1;
- av->av_buf_ackno = UINT48_MAX + 1;
- av->av_buf_nonce = 0;
- av->av_time = ktime_set(0, 0);
- av->av_vec_len = 0;
- INIT_LIST_HEAD(&av->av_records);
+ struct dccp_ackvec_record *avr;
+ /*
+ * Exploit that records are inserted in descending order of sequence
+ * number, start with the oldest record first. If @ackno is `before'
+ * the earliest ack_ackno, the packet is too old to be considered.
+ */
+ list_for_each_entry_reverse(avr, av_list, avr_node) {
+ if (avr->avr_ack_seqno == ackno)
+ return avr;
+ if (before48(ackno, avr->avr_ack_seqno))
+ break;
}
-
- return av;
+ return NULL;
}
-void dccp_ackvec_free(struct dccp_ackvec *av)
+/*
+ * Buffer index and length computation using modulo-buffersize arithmetic.
+ * Note that, as pointers move from right to left, head is `before' tail.
+ */
+static inline u16 __ackvec_idx_add(const u16 a, const u16 b)
{
- if (unlikely(av == NULL))
- return;
-
- if (!list_empty(&av->av_records)) {
- struct dccp_ackvec_record *avr, *next;
-
- list_for_each_entry_safe(avr, next, &av->av_records, avr_node) {
- list_del_init(&avr->avr_node);
- dccp_ackvec_record_delete(avr);
- }
- }
-
- kmem_cache_free(dccp_ackvec_slab, av);
+ return (a + b) % DCCPAV_MAX_ACKVEC_LEN;
}
-static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
- const u32 index)
+static inline u16 __ackvec_idx_sub(const u16 a, const u16 b)
{
- return av->av_buf[index] & DCCP_ACKVEC_STATE_MASK;
+ return __ackvec_idx_add(a, DCCPAV_MAX_ACKVEC_LEN - b);
}
-static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
- const u32 index)
+u16 dccp_ackvec_buflen(const struct dccp_ackvec *av)
{
- return av->av_buf[index] & DCCP_ACKVEC_LEN_MASK;
+ if (unlikely(av->av_overflow))
+ return DCCPAV_MAX_ACKVEC_LEN;
+ return __ackvec_idx_sub(av->av_buf_tail, av->av_buf_head);
}
-/*
- * If several packets are missing, the HC-Receiver may prefer to enter multiple
- * bytes with run length 0, rather than a single byte with a larger run length;
- * this simplifies table updates if one of the missing packets arrives.
+/**
+ * dccp_ackvec_update_old - Update previous state as per RFC 4340, 11.4.1
+ * @av: non-empty buffer to update
+ * @distance: negative or zero distance of @seqno from buf_ackno downward
+ * @seqno: the (old) sequence number whose record is to be updated
+ * @state: state in which packet carrying @seqno was received
*/
-static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
- const unsigned int packets,
- const unsigned char state)
+static void dccp_ackvec_update_old(struct dccp_ackvec *av, s64 distance,
+ u64 seqno, enum dccp_ackvec_states state)
{
- long gap;
- long new_head;
+ u16 ptr = av->av_buf_head;
- if (av->av_vec_len + packets > DCCP_MAX_ACKVEC_LEN)
- return -ENOBUFS;
+ BUG_ON(distance > 0);
+ if (unlikely(dccp_ackvec_is_empty(av)))
+ return;
- gap = packets - 1;
- new_head = av->av_buf_head - packets;
+ do {
+ u8 runlen = dccp_ackvec_runlen(av->av_buf + ptr);
- if (new_head < 0) {
- if (gap > 0) {
- memset(av->av_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED,
- gap + new_head + 1);
- gap = -new_head;
+ if (distance + runlen >= 0) {
+ /*
+ * Only update the state if packet has not been received
+ * yet. This is OK as per the second table in RFC 4340,
+ * 11.4.1; i.e. here we are using the following table:
+ * RECEIVED
+ * 0 1 3
+ * S +---+---+---+
+ * T 0 | 0 | 0 | 0 |
+ * O +---+---+---+
+ * R 1 | 1 | 1 | 1 |
+ * E +---+---+---+
+ * D 3 | 0 | 1 | 3 |
+ * +---+---+---+
+ * The "Not Received" state was set by reserve_seats().
+ */
+ if (av->av_buf[ptr] == DCCPAV_NOT_RECEIVED)
+ av->av_buf[ptr] = state;
+ else
+ dccp_pr_debug("Not changing %llu state to %u\n",
+ (unsigned long long)seqno, state);
+ break;
}
- new_head += DCCP_MAX_ACKVEC_LEN;
- }
- av->av_buf_head = new_head;
+ distance += runlen + 1;
+ ptr = __ackvec_idx_add(ptr, 1);
- if (gap > 0)
- memset(av->av_buf + av->av_buf_head + 1,
- DCCP_ACKVEC_STATE_NOT_RECEIVED, gap);
+ } while (ptr != av->av_buf_tail);
+}
- av->av_buf[av->av_buf_head] = state;
- av->av_vec_len += packets;
- return 0;
+/* Mark @num entries after buf_head as "Not yet received". */
+static void dccp_ackvec_reserve_seats(struct dccp_ackvec *av, u16 num)
+{
+ u16 start = __ackvec_idx_add(av->av_buf_head, 1),
+ len = DCCPAV_MAX_ACKVEC_LEN - start;
+
+ /* check for buffer wrap-around */
+ if (num > len) {
+ memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, len);
+ start = 0;
+ num -= len;
+ }
+ if (num)
+ memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, num);
}
-/*
- * Implements the RFC 4340, Appendix A
+/**
+ * dccp_ackvec_add_new - Record one or more new entries in Ack Vector buffer
+ * @av: container of buffer to update (can be empty or non-empty)
+ * @num_packets: number of packets to register (must be >= 1)
+ * @seqno: sequence number of the first packet in @num_packets
+ * @state: state in which packet carrying @seqno was received
*/
-int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
- const u64 ackno, const u8 state)
+static void dccp_ackvec_add_new(struct dccp_ackvec *av, u32 num_packets,
+ u64 seqno, enum dccp_ackvec_states state)
{
- /*
- * Check at the right places if the buffer is full, if it is, tell the
- * caller to start dropping packets till the HC-Sender acks our ACK
- * vectors, when we will free up space in av_buf.
- *
- * We may well decide to do buffer compression, etc, but for now lets
- * just drop.
- *
- * From Appendix A.1.1 (`New Packets'):
- *
- * Of course, the circular buffer may overflow, either when the
- * HC-Sender is sending data at a very high rate, when the
- * HC-Receiver's acknowledgements are not reaching the HC-Sender,
- * or when the HC-Sender is forgetting to acknowledge those acks
- * (so the HC-Receiver is unable to clean up old state). In this
- * case, the HC-Receiver should either compress the buffer (by
- * increasing run lengths when possible), transfer its state to
- * a larger buffer, or, as a last resort, drop all received
- * packets, without processing them whatsoever, until its buffer
- * shrinks again.
- */
+ u32 num_cells = num_packets;
- /* See if this is the first ackno being inserted */
- if (av->av_vec_len == 0) {
- av->av_buf[av->av_buf_head] = state;
- av->av_vec_len = 1;
- } else if (after48(ackno, av->av_buf_ackno)) {
- const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno);
+ if (num_packets > DCCPAV_BURST_THRESH) {
+ u32 lost_packets = num_packets - 1;
+ DCCP_WARN("Warning: large burst loss (%u)\n", lost_packets);
/*
- * Look if the state of this packet is the same as the
- * previous ackno and if so if we can bump the head len.
+ * We received 1 packet and have a loss of size "num_packets-1"
+ * which we squeeze into num_cells-1 rather than reserving an
+ * entire byte for each lost packet.
+ * The reason is that the vector grows in O(burst_length); when
+ * it grows too large there will no room left for the payload.
+ * This is a trade-off: if a few packets out of the burst show
+ * up later, their state will not be changed; it is simply too
+ * costly to reshuffle/reallocate/copy the buffer each time.
+ * Should such problems persist, we will need to switch to a
+ * different underlying data structure.
*/
- if (delta == 1 &&
- dccp_ackvec_state(av, av->av_buf_head) == state &&
- dccp_ackvec_len(av, av->av_buf_head) < DCCP_ACKVEC_LEN_MASK)
- av->av_buf[av->av_buf_head]++;
- else if (dccp_ackvec_set_buf_head_state(av, delta, state))
- return -ENOBUFS;
- } else {
- /*
- * A.1.2. Old Packets
- *
- * When a packet with Sequence Number S <= buf_ackno
- * arrives, the HC-Receiver will scan the table for
- * the byte corresponding to S. (Indexing structures
- * could reduce the complexity of this scan.)
- */
- u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno);
- u32 index = av->av_buf_head;
+ for (num_packets = num_cells = 1; lost_packets; ++num_cells) {
+ u8 len = min(lost_packets, (u32)DCCPAV_MAX_RUNLEN);
- while (1) {
- const u8 len = dccp_ackvec_len(av, index);
- const u8 av_state = dccp_ackvec_state(av, index);
- /*
- * valid packets not yet in av_buf have a reserved
- * entry, with a len equal to 0.
- */
- if (av_state == DCCP_ACKVEC_STATE_NOT_RECEIVED &&
- len == 0 && delta == 0) { /* Found our
- reserved seat! */
- dccp_pr_debug("Found %llu reserved seat!\n",
- (unsigned long long)ackno);
- av->av_buf[index] = state;
- goto out;
- }
- /* len == 0 means one packet */
- if (delta < len + 1)
- goto out_duplicate;
-
- delta -= len + 1;
- if (++index == DCCP_MAX_ACKVEC_LEN)
- index = 0;
+ av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, 1);
+ av->av_buf[av->av_buf_head] = DCCPAV_NOT_RECEIVED | len;
+
+ lost_packets -= len;
}
}
- av->av_buf_ackno = ackno;
- av->av_time = ktime_get_real();
-out:
- return 0;
+ if (num_cells + dccp_ackvec_buflen(av) >= DCCPAV_MAX_ACKVEC_LEN) {
+ DCCP_CRIT("Ack Vector buffer overflow: dropping old entries\n");
+ av->av_overflow = true;
+ }
+
+ av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, num_packets);
+ if (av->av_overflow)
+ av->av_buf_tail = av->av_buf_head;
-out_duplicate:
- /* Duplicate packet */
- dccp_pr_debug("Received a dup or already considered lost "
- "packet: %llu\n", (unsigned long long)ackno);
- return -EILSEQ;
+ av->av_buf[av->av_buf_head] = state;
+ av->av_buf_ackno = seqno;
+
+ if (num_packets > 1)
+ dccp_ackvec_reserve_seats(av, num_packets - 1);
}
-static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
- struct dccp_ackvec_record *avr)
+/**
+ * dccp_ackvec_input - Register incoming packet in the buffer
+ */
+void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb)
{
- struct dccp_ackvec_record *next;
+ u64 seqno = DCCP_SKB_CB(skb)->dccpd_seq;
+ enum dccp_ackvec_states state = DCCPAV_RECEIVED;
- /* sort out vector length */
- if (av->av_buf_head <= avr->avr_ack_ptr)
- av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head;
- else
- av->av_vec_len = DCCP_MAX_ACKVEC_LEN - 1 -
- av->av_buf_head + avr->avr_ack_ptr;
+ if (dccp_ackvec_is_empty(av)) {
+ dccp_ackvec_add_new(av, 1, seqno, state);
+ av->av_tail_ackno = seqno;
- /* free records */
- list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) {
- list_del_init(&avr->avr_node);
- dccp_ackvec_record_delete(avr);
- }
-}
+ } else {
+ s64 num_packets = dccp_delta_seqno(av->av_buf_ackno, seqno);
+ u8 *current_head = av->av_buf + av->av_buf_head;
-void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
- const u64 ackno)
-{
- struct dccp_ackvec_record *avr;
+ if (num_packets == 1 &&
+ dccp_ackvec_state(current_head) == state &&
+ dccp_ackvec_runlen(current_head) < DCCPAV_MAX_RUNLEN) {
- /*
- * If we traverse backwards, it should be faster when we have large
- * windows. We will be receiving ACKs for stuff we sent a while back
- * -sorbo.
- */
- list_for_each_entry_reverse(avr, &av->av_records, avr_node) {
- if (ackno == avr->avr_ack_seqno) {
- dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, "
- "ack_ackno=%llu, ACKED!\n",
- dccp_role(sk), 1,
- (unsigned long long)avr->avr_ack_seqno,
- (unsigned long long)avr->avr_ack_ackno);
- dccp_ackvec_throw_record(av, avr);
- break;
- } else if (avr->avr_ack_seqno > ackno)
- break; /* old news */
+ *current_head += 1;
+ av->av_buf_ackno = seqno;
+
+ } else if (num_packets > 0) {
+ dccp_ackvec_add_new(av, num_packets, seqno, state);
+ } else {
+ dccp_ackvec_update_old(av, num_packets, seqno, state);
+ }
}
}
-static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
- struct sock *sk, u64 *ackno,
- const unsigned char len,
- const unsigned char *vector)
+/**
+ * dccp_ackvec_clear_state - Perform house-keeping / garbage-collection
+ * This routine is called when the peer acknowledges the receipt of Ack Vectors
+ * up to and including @ackno. While based on on section A.3 of RFC 4340, here
+ * are additional precautions to prevent corrupted buffer state. In particular,
+ * we use tail_ackno to identify outdated records; it always marks the earliest
+ * packet of group (2) in 11.4.2.
+ */
+void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno)
{
- unsigned char i;
- struct dccp_ackvec_record *avr;
+ struct dccp_ackvec_record *avr, *next;
+ u8 runlen_now, eff_runlen;
+ s64 delta;
- /* Check if we actually sent an ACK vector */
- if (list_empty(&av->av_records))
+ avr = dccp_ackvec_lookup(&av->av_records, ackno);
+ if (avr == NULL)
return;
+ /*
+ * Deal with outdated acknowledgments: this arises when e.g. there are
+ * several old records and the acks from the peer come in slowly. In
+ * that case we may still have records that pre-date tail_ackno.
+ */
+ delta = dccp_delta_seqno(av->av_tail_ackno, avr->avr_ack_ackno);
+ if (delta < 0)
+ goto free_records;
+ /*
+ * Deal with overlapping Ack Vectors: don't subtract more than the
+ * number of packets between tail_ackno and ack_ackno.
+ */
+ eff_runlen = delta < avr->avr_ack_runlen ? delta : avr->avr_ack_runlen;
- i = len;
+ runlen_now = dccp_ackvec_runlen(av->av_buf + avr->avr_ack_ptr);
/*
- * XXX
- * I think it might be more efficient to work backwards. See comment on
- * rcv_ackno. -sorbo.
+ * The run length of Ack Vector cells does not decrease over time. If
+ * the run length is the same as at the time the Ack Vector was sent, we
+ * free the ack_ptr cell. That cell can however not be freed if the run
+ * length has increased: in this case we need to move the tail pointer
+ * backwards (towards higher indices), to its next-oldest neighbour.
*/
- avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node);
- while (i--) {
- const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
- u64 ackno_end_rl;
+ if (runlen_now > eff_runlen) {
- dccp_set_seqno(&ackno_end_rl, *ackno - rl);
+ av->av_buf[avr->avr_ack_ptr] -= eff_runlen + 1;
+ av->av_buf_tail = __ackvec_idx_add(avr->avr_ack_ptr, 1);
+ /* This move may not have cleared the overflow flag. */
+ if (av->av_overflow)
+ av->av_overflow = (av->av_buf_head == av->av_buf_tail);
+ } else {
+ av->av_buf_tail = avr->avr_ack_ptr;
/*
- * If our AVR sequence number is greater than the ack, go
- * forward in the AVR list until it is not so.
+ * We have made sure that avr points to a valid cell within the
+ * buffer. This cell is either older than head, or equals head
+ * (empty buffer): in both cases we no longer have any overflow.
*/
- list_for_each_entry_from(avr, &av->av_records, avr_node) {
- if (!after48(avr->avr_ack_seqno, *ackno))
- goto found;
- }
- /* End of the av_records list, not found, exit */
- break;
-found:
- if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) {
- const u8 state = *vector & DCCP_ACKVEC_STATE_MASK;
- if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
- dccp_pr_debug("%s ACK vector 0, len=%d, "
- "ack_seqno=%llu, ack_ackno=%llu, "
- "ACKED!\n",
- dccp_role(sk), len,
- (unsigned long long)
- avr->avr_ack_seqno,
- (unsigned long long)
- avr->avr_ack_ackno);
- dccp_ackvec_throw_record(av, avr);
- break;
- }
- /*
- * If it wasn't received, continue scanning... we might
- * find another one.
- */
- }
+ av->av_overflow = 0;
+ }
- dccp_set_seqno(ackno, ackno_end_rl - 1);
- ++vector;
+ /*
+ * The peer has acknowledged up to and including ack_ackno. Hence the
+ * first packet in group (2) of 11.4.2 is the successor of ack_ackno.
+ */
+ av->av_tail_ackno = ADD48(avr->avr_ack_ackno, 1);
+
+free_records:
+ list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) {
+ list_del(&avr->avr_node);
+ kmem_cache_free(dccp_ackvec_record_slab, avr);
}
}
-int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
- u64 *ackno, const u8 opt, const u8 *value, const u8 len)
+/*
+ * Routines to keep track of Ack Vectors received in an skb
+ */
+int dccp_ackvec_parsed_add(struct list_head *head, u8 *vec, u8 len, u8 nonce)
{
- if (len > DCCP_SINGLE_OPT_MAXLEN)
- return -1;
+ struct dccp_ackvec_parsed *new = kmalloc(sizeof(*new), GFP_ATOMIC);
+
+ if (new == NULL)
+ return -ENOBUFS;
+ new->vec = vec;
+ new->len = len;
+ new->nonce = nonce;
- /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */
- dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk,
- ackno, len, value);
+ list_add_tail(&new->node, head);
return 0;
}
+EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_add);
+
+void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks)
+{
+ struct dccp_ackvec_parsed *cur, *next;
+
+ list_for_each_entry_safe(cur, next, parsed_chunks, node)
+ kfree(cur);
+ INIT_LIST_HEAD(parsed_chunks);
+}
+EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_cleanup);
int __init dccp_ackvec_init(void)
{
@@ -448,10 +379,9 @@ int __init dccp_ackvec_init(void)
if (dccp_ackvec_slab == NULL)
goto out_err;
- dccp_ackvec_record_slab =
- kmem_cache_create("dccp_ackvec_record",
- sizeof(struct dccp_ackvec_record),
- 0, SLAB_HWCACHE_ALIGN, NULL);
+ dccp_ackvec_record_slab = kmem_cache_create("dccp_ackvec_record",
+ sizeof(struct dccp_ackvec_record),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
if (dccp_ackvec_record_slab == NULL)
goto out_destroy_slab;
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index 7ea557b7c6b1..e2ab0627a5ff 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -3,9 +3,9 @@
/*
* net/dccp/ackvec.h
*
- * An implementation of the DCCP protocol
+ * An implementation of Ack Vectors for the DCCP protocol
+ * Copyright (c) 2007 University of Aberdeen, Scotland, UK
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.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.
@@ -13,99 +13,124 @@
#include <linux/dccp.h>
#include <linux/compiler.h>
-#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/types.h>
-/* We can spread an ack vector across multiple options */
-#define DCCP_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * 2)
+/*
+ * Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN,
+ * the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1
+ * will be sufficient for most cases of low Ack Ratios, using a value of 2 gives
+ * more headroom if Ack Ratio is higher or when the sender acknowledges slowly.
+ * The maximum value is bounded by the u16 types for indices and functions.
+ */
+#define DCCPAV_NUM_ACKVECS 2
+#define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS)
/* Estimated minimum average Ack Vector length - used for updating MPS */
#define DCCPAV_MIN_OPTLEN 16
-#define DCCP_ACKVEC_STATE_RECEIVED 0
-#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
-#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6)
+/* Threshold for coping with large bursts of losses */
+#define DCCPAV_BURST_THRESH (DCCPAV_MAX_ACKVEC_LEN / 8)
-#define DCCP_ACKVEC_STATE_MASK 0xC0 /* 11000000 */
-#define DCCP_ACKVEC_LEN_MASK 0x3F /* 00111111 */
+enum dccp_ackvec_states {
+ DCCPAV_RECEIVED = 0x00,
+ DCCPAV_ECN_MARKED = 0x40,
+ DCCPAV_RESERVED = 0x80,
+ DCCPAV_NOT_RECEIVED = 0xC0
+};
+#define DCCPAV_MAX_RUNLEN 0x3F
-/** struct dccp_ackvec - ack vector
- *
- * This data structure is the one defined in RFC 4340, Appendix A.
- *
- * @av_buf_head - circular buffer head
- * @av_buf_tail - circular buffer tail
- * @av_buf_ackno - ack # of the most recent packet acknowledgeable in the
- * buffer (i.e. %av_buf_head)
- * @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
- * by the buffer with State 0
- *
- * Additionally, the HC-Receiver must keep some information about the
- * Ack Vectors it has recently sent. For each packet sent carrying an
- * Ack Vector, it remembers four variables:
+static inline u8 dccp_ackvec_runlen(const u8 *cell)
+{
+ return *cell & DCCPAV_MAX_RUNLEN;
+}
+
+static inline u8 dccp_ackvec_state(const u8 *cell)
+{
+ return *cell & ~DCCPAV_MAX_RUNLEN;
+}
+
+/** struct dccp_ackvec - Ack Vector main data structure
*
- * @av_records - list of dccp_ackvec_record
- * @av_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
+ * This implements a fixed-size circular buffer within an array and is largely
+ * based on Appendix A of RFC 4340.
*
- * @av_time - the time in usecs
- * @av_buf - circular buffer of acknowledgeable packets
+ * @av_buf: circular buffer storage area
+ * @av_buf_head: head index; begin of live portion in @av_buf
+ * @av_buf_tail: tail index; first index _after_ the live portion in @av_buf
+ * @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf
+ * @av_tail_ackno: lowest seqno of acknowledgeable packet recorded in @av_buf
+ * @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to
+ * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf
+ * @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound
+ * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously)
*/
struct dccp_ackvec {
- u64 av_buf_ackno;
- struct list_head av_records;
- ktime_t av_time;
+ u8 av_buf[DCCPAV_MAX_ACKVEC_LEN];
u16 av_buf_head;
- u16 av_vec_len;
- u8 av_buf_nonce;
- u8 av_ack_nonce;
- u8 av_buf[DCCP_MAX_ACKVEC_LEN];
+ u16 av_buf_tail;
+ u64 av_buf_ackno:48;
+ u64 av_tail_ackno:48;
+ bool av_buf_nonce[DCCPAV_NUM_ACKVECS];
+ u8 av_overflow:1;
+ struct list_head av_records;
};
-/** struct dccp_ackvec_record - ack vector record
+/** struct dccp_ackvec_record - Records information about sent Ack Vectors
*
- * ACK vector record as defined in Appendix A of spec.
+ * These list entries define the additional information which the HC-Receiver
+ * keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A.
*
- * The list is sorted by avr_ack_seqno
+ * @avr_node: the list node in @av_records
+ * @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on
+ * @avr_ack_ackno: the Ack number that this record/Ack Vector refers to
+ * @avr_ack_ptr: pointer into @av_buf where this record starts
+ * @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending
+ * @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent
*
- * @avr_node - node in av_records
- * @avr_ack_seqno - sequence number of the packet this record was sent on
- * @avr_ack_ackno - sequence number being acknowledged
- * @avr_ack_ptr - pointer into av_buf where this record starts
- * @avr_ack_nonce - av_ack_nonce at the time this record was sent
- * @avr_sent_len - lenght of the record in av_buf
+ * The list as a whole is sorted in descending order by @avr_ack_seqno.
*/
struct dccp_ackvec_record {
struct list_head avr_node;
- u64 avr_ack_seqno;
- u64 avr_ack_ackno;
+ u64 avr_ack_seqno:48;
+ u64 avr_ack_ackno:48;
u16 avr_ack_ptr;
- u16 avr_sent_len;
- u8 avr_ack_nonce;
+ u8 avr_ack_runlen;
+ u8 avr_ack_nonce:1;
};
-struct sock;
-struct sk_buff;
-
extern int dccp_ackvec_init(void);
extern void dccp_ackvec_exit(void);
extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority);
extern void dccp_ackvec_free(struct dccp_ackvec *av);
-extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
- const u64 ackno, const u8 state);
-
-extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
- struct sock *sk, const u64 ackno);
-extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
- u64 *ackno, const u8 opt,
- const u8 *value, const u8 len);
+extern void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb);
+extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum);
+extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno);
+extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av);
-extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb);
-
-static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
+static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av)
{
- return av->av_vec_len;
+ return av->av_overflow == 0 && av->av_buf_head == av->av_buf_tail;
}
+
+/**
+ * struct dccp_ackvec_parsed - Record offsets of Ack Vectors in skb
+ * @vec: start of vector (offset into skb)
+ * @len: length of @vec
+ * @nonce: whether @vec had an ECN nonce of 0 or 1
+ * @node: FIFO - arranged in descending order of ack_ackno
+ * This structure is used by CCIDs to access Ack Vectors in a received skb.
+ */
+struct dccp_ackvec_parsed {
+ u8 *vec,
+ len,
+ nonce:1;
+ struct list_head node;
+};
+
+extern int dccp_ackvec_parsed_add(struct list_head *head,
+ u8 *vec, u8 len, u8 nonce);
+extern void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks);
#endif /* _ACKVEC_H */
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 6576eae9e779..e96d5e810039 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -246,68 +246,6 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
#endif
}
-/* XXX Lame code duplication!
- * returns -1 if none was found.
- * else returns the next offset to use in the function call.
- */
-static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
- unsigned char **vec, unsigned char *veclen)
-{
- const struct dccp_hdr *dh = dccp_hdr(skb);
- unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
- unsigned char *opt_ptr;
- const unsigned char *opt_end = (unsigned char *)dh +
- (dh->dccph_doff * 4);
- unsigned char opt, len;
- unsigned char *value;
-
- BUG_ON(offset < 0);
- options += offset;
- opt_ptr = options;
- if (opt_ptr >= opt_end)
- return -1;
-
- while (opt_ptr != opt_end) {
- opt = *opt_ptr++;
- len = 0;
- value = NULL;
-
- /* Check if this isn't a single byte option */
- if (opt > DCCPO_MAX_RESERVED) {
- if (opt_ptr == opt_end)
- goto out_invalid_option;
-
- len = *opt_ptr++;
- if (len < 3)
- goto out_invalid_option;
- /*
- * Remove the type and len fields, leaving
- * just the value size
- */
- len -= 2;
- value = opt_ptr;
- opt_ptr += len;
-
- if (opt_ptr > opt_end)
- goto out_invalid_option;
- }
-
- switch (opt) {
- case DCCPO_ACK_VECTOR_0:
- case DCCPO_ACK_VECTOR_1:
- *vec = value;
- *veclen = len;
- return offset + (opt_ptr - options);
- }
- }
-
- return -1;
-
-out_invalid_option:
- DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
- return -1;
-}
-
/**
* ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm
* This code is almost identical with TCP's tcp_rtt_estimator(), since
@@ -432,16 +370,28 @@ static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
ccid2_change_l_ack_ratio(sk, hc->tx_cwnd);
}
+static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type,
+ u8 option, u8 *optval, u8 optlen)
+{
+ struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+
+ switch (option) {
+ case DCCPO_ACK_VECTOR_0:
+ case DCCPO_ACK_VECTOR_1:
+ return dccp_ackvec_parsed_add(&hc->tx_av_chunks, optval, optlen,
+ option - DCCPO_ACK_VECTOR_0);
+ }
+ return 0;
+}
+
static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
struct dccp_sock *dp = dccp_sk(sk);
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
const bool sender_was_blocked = ccid2_cwnd_network_limited(hc);
+ struct dccp_ackvec_parsed *avp;
u64 ackno, seqno;
struct ccid2_seq *seqp;
- unsigned char *vector;
- unsigned char veclen;
- int offset = 0;
int done = 0;
unsigned int maxincr = 0;
@@ -475,17 +425,12 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
}
/* check forward path congestion */
- /* still didn't send out new data packets */
- if (hc->tx_seqh == hc->tx_seqt)
+ if (dccp_packet_without_ack(skb))
return;
- switch (DCCP_SKB_CB(skb)->dccpd_type) {
- case DCCP_PKT_ACK:
- case DCCP_PKT_DATAACK:
- break;
- default:
- return;
- }
+ /* still didn't send out new data packets */
+ if (hc->tx_seqh == hc->tx_seqt)
+ goto done;
ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
if (after48(ackno, hc->tx_high_ack))
@@ -509,16 +454,16 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2);
/* go through all ack vectors */
- while ((offset = ccid2_ackvector(sk, skb, offset,
- &vector, &veclen)) != -1) {
+ list_for_each_entry(avp, &hc->tx_av_chunks, node) {
/* go through this ack vector */
- while (veclen--) {
- const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
- u64 ackno_end_rl = SUB48(ackno, rl);
+ for (; avp->len--; avp->vec++) {
+ u64 ackno_end_rl = SUB48(ackno,
+ dccp_ackvec_runlen(avp->vec));
- ccid2_pr_debug("ackvec start:%llu end:%llu\n",
+ ccid2_pr_debug("ackvec %llu |%u,%u|\n",
(unsigned long long)ackno,
- (unsigned long long)ackno_end_rl);
+ dccp_ackvec_state(avp->vec) >> 6,
+ dccp_ackvec_runlen(avp->vec));
/* if the seqno we are analyzing is larger than the
* current ackno, then move towards the tail of our
* seqnos.
@@ -537,17 +482,15 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
* run length
*/
while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
- const u8 state = *vector &
- DCCP_ACKVEC_STATE_MASK;
+ const u8 state = dccp_ackvec_state(avp->vec);
/* new packet received or marked */
- if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&
+ if (state != DCCPAV_NOT_RECEIVED &&
!seqp->ccid2s_acked) {
- if (state ==
- DCCP_ACKVEC_STATE_ECN_MARKED) {
+ if (state == DCCPAV_ECN_MARKED)
ccid2_congestion_event(sk,
seqp);
- } else
+ else
ccid2_new_ack(sk, seqp,
&maxincr);
@@ -566,7 +509,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
break;
ackno = SUB48(ackno_end_rl, 1);
- vector++;
}
if (done)
break;
@@ -634,10 +576,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
sk_stop_timer(sk, &hc->tx_rtotimer);
else
sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
-
+done:
/* check if incoming Acks allow pending packets to be sent */
if (sender_was_blocked && !ccid2_cwnd_network_limited(hc))
tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet);
+ dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks);
}
static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
@@ -666,6 +609,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
hc->tx_last_cong = ccid2_time_stamp;
setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire,
(unsigned long)sk);
+ INIT_LIST_HEAD(&hc->tx_av_chunks);
return 0;
}
@@ -699,16 +643,17 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
}
struct ccid_operations ccid2_ops = {
- .ccid_id = DCCPC_CCID2,
- .ccid_name = "TCP-like",
- .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
- .ccid_hc_tx_init = ccid2_hc_tx_init,
- .ccid_hc_tx_exit = ccid2_hc_tx_exit,
- .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
- .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
- .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
- .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock),
- .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
+ .ccid_id = DCCPC_CCID2,
+ .ccid_name = "TCP-like",
+ .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
+ .ccid_hc_tx_init = ccid2_hc_tx_init,
+ .ccid_hc_tx_exit = ccid2_hc_tx_exit,
+ .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
+ .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
+ .ccid_hc_tx_parse_options = ccid2_hc_tx_parse_options,
+ .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
+ .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock),
+ .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
};
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 25cb6b216eda..e9985dafc2c7 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -55,6 +55,7 @@ struct ccid2_seq {
* @tx_rtt_seq: to decay RTTVAR at most once per flight
* @tx_rpseq: last consecutive seqno
* @tx_rpdupack: dupacks since rpseq
+ * @tx_av_chunks: list of Ack Vectors received on current skb
*/
struct ccid2_hc_tx_sock {
u32 tx_cwnd;
@@ -79,6 +80,7 @@ struct ccid2_hc_tx_sock {
int tx_rpdupack;
u32 tx_last_cong;
u64 tx_high_ack;
+ struct list_head tx_av_chunks;
};
static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc)
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index a8ed459508b2..45087052d894 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -93,9 +93,6 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);
#define DCCP_FALLBACK_RTT (USEC_PER_SEC / 5)
#define DCCP_SANE_RTT_MAX (3 * USEC_PER_SEC)
-/* Maximal interval between probes for local resources. */
-#define DCCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ / 2U))
-
/* sysctl variables for DCCP */
extern int sysctl_dccp_request_retries;
extern int sysctl_dccp_retries1;
@@ -203,12 +200,7 @@ struct dccp_mib {
DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
#define DCCP_INC_STATS(field) SNMP_INC_STATS(dccp_statistics, field)
#define DCCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(dccp_statistics, field)
-#define DCCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(dccp_statistics, field)
#define DCCP_DEC_STATS(field) SNMP_DEC_STATS(dccp_statistics, field)
-#define DCCP_ADD_STATS_BH(field, val) \
- SNMP_ADD_STATS_BH(dccp_statistics, field, val)
-#define DCCP_ADD_STATS_USER(field, val) \
- SNMP_ADD_STATS_USER(dccp_statistics, field, val)
/*
* Checksumming routines
@@ -243,6 +235,19 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
extern void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type);
+/*
+ * TX Packet Dequeueing Interface
+ */
+extern void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb);
+extern bool dccp_qpolicy_full(struct sock *sk);
+extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb);
+extern struct sk_buff *dccp_qpolicy_top(struct sock *sk);
+extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk);
+extern bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param);
+
+/*
+ * TX Packet Output and TX Timers
+ */
extern void dccp_write_xmit(struct sock *sk);
extern void dccp_write_space(struct sock *sk);
extern void dccp_flush_write_queue(struct sock *sk, long *time_budget);
@@ -457,12 +462,15 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
dp->dccps_awh = dp->dccps_gss;
}
+static inline int dccp_ackvec_pending(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_hc_rx_ackvec != NULL &&
+ !dccp_ackvec_is_empty(dccp_sk(sk)->dccps_hc_rx_ackvec);
+}
+
static inline int dccp_ack_pending(const struct sock *sk)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- return (dp->dccps_hc_rx_ackvec != NULL &&
- dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
- inet_csk_ack_scheduled(sk);
+ return dccp_ackvec_pending(sk) || inet_csk_ack_scheduled(sk);
}
extern int dccp_feat_finalise_settings(struct dccp_sock *dp);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index e424a09e83f6..15af247ea007 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -160,13 +160,15 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
}
-static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
+static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb)
{
- struct dccp_sock *dp = dccp_sk(sk);
+ struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec;
- if (dp->dccps_hc_rx_ackvec != NULL)
- dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk,
- DCCP_SKB_CB(skb)->dccpd_ack_seq);
+ if (av == NULL)
+ return;
+ if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+ dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq);
+ dccp_ackvec_input(av, skb);
}
static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
@@ -366,22 +368,13 @@ discard:
int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
const struct dccp_hdr *dh, const unsigned len)
{
- struct dccp_sock *dp = dccp_sk(sk);
-
if (dccp_check_seqno(sk, skb))
goto discard;
if (dccp_parse_options(sk, NULL, skb))
return 1;
- if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
- dccp_event_ack_recv(sk, skb);
-
- if (dp->dccps_hc_rx_ackvec != NULL &&
- dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
- DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_ACKVEC_STATE_RECEIVED))
- goto discard;
+ dccp_handle_ackvec_processing(sk, skb);
dccp_deliver_input_to_ccids(sk, skb);
return __dccp_rcv_established(sk, skb, dh, len);
@@ -633,15 +626,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (dccp_parse_options(sk, NULL, skb))
return 1;
- if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
- dccp_event_ack_recv(sk, skb);
-
- if (dp->dccps_hc_rx_ackvec != NULL &&
- dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
- DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_ACKVEC_STATE_RECEIVED))
- goto discard;
-
+ dccp_handle_ackvec_processing(sk, skb);
dccp_deliver_input_to_ccids(sk, skb);
}
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3f69ea114829..45a434f94169 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -462,15 +462,12 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
{
struct rtable *rt;
struct flowi fl = { .oif = skb_rtable(skb)->rt_iif,
- .nl_u = { .ip4_u =
- { .daddr = ip_hdr(skb)->saddr,
- .saddr = ip_hdr(skb)->daddr,
- .tos = RT_CONN_FLAGS(sk) } },
+ .fl4_dst = ip_hdr(skb)->saddr,
+ .fl4_src = ip_hdr(skb)->daddr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
- .uli_u = { .ports =
- { .sport = dccp_hdr(skb)->dccph_dport,
- .dport = dccp_hdr(skb)->dccph_sport }
- }
+ .fl_ip_sport = dccp_hdr(skb)->dccph_dport,
+ .fl_ip_dport = dccp_hdr(skb)->dccph_sport
};
security_skb_classify_flow(skb, &fl);
diff --git a/net/dccp/options.c b/net/dccp/options.c
index cd3061813009..f06ffcfc8d71 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -54,7 +54,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
struct dccp_sock *dp = dccp_sk(sk);
const struct dccp_hdr *dh = dccp_hdr(skb);
const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
- u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
unsigned char *opt_ptr = options;
const unsigned char *opt_end = (unsigned char *)dh +
@@ -129,14 +128,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
if (rc)
goto out_featneg_failed;
break;
- case DCCPO_ACK_VECTOR_0:
- case DCCPO_ACK_VECTOR_1:
- if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */
- break;
- if (dp->dccps_hc_rx_ackvec != NULL &&
- dccp_ackvec_parse(sk, skb, &ackno, opt, value, len))
- goto out_invalid_option;
- break;
case DCCPO_TIMESTAMP:
if (len != 4)
goto out_invalid_option;
@@ -226,6 +217,16 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
pkt_type, opt, value, len))
goto out_invalid_option;
break;
+ case DCCPO_ACK_VECTOR_0:
+ case DCCPO_ACK_VECTOR_1:
+ if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */
+ break;
+ /*
+ * Ack vectors are processed by the TX CCID if it is
+ * interested. The RX CCID need not parse Ack Vectors,
+ * since it is only interested in clearing old state.
+ * Fall through.
+ */
case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
pkt_type, opt, value, len))
@@ -340,6 +341,7 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time)
return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
}
+/* FIXME: This function is currently not used anywhere */
int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time)
{
const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
@@ -424,6 +426,83 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
return 0;
}
+static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
+ struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+ const u16 buflen = dccp_ackvec_buflen(av);
+ /* Figure out how many options do we need to represent the ackvec */
+ const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN);
+ u16 len = buflen + 2 * nr_opts;
+ u8 i, nonce = 0;
+ const unsigned char *tail, *from;
+ unsigned char *to;
+
+ if (dcb->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
+ DCCP_WARN("Lacking space for %u bytes on %s packet\n", len,
+ dccp_packet_name(dcb->dccpd_type));
+ return -1;
+ }
+ /*
+ * Since Ack Vectors are variable-length, we can not always predict
+ * their size. To catch exception cases where the space is running out
+ * on the skb, a separate Sync is scheduled to carry the Ack Vector.
+ */
+ if (len > DCCPAV_MIN_OPTLEN &&
+ len + dcb->dccpd_opt_len + skb->len > dp->dccps_mss_cache) {
+ DCCP_WARN("No space left for Ack Vector (%u) on skb (%u+%u), "
+ "MPS=%u ==> reduce payload size?\n", len, skb->len,
+ dcb->dccpd_opt_len, dp->dccps_mss_cache);
+ dp->dccps_sync_scheduled = 1;
+ return 0;
+ }
+ dcb->dccpd_opt_len += len;
+
+ to = skb_push(skb, len);
+ len = buflen;
+ from = av->av_buf + av->av_buf_head;
+ tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN;
+
+ for (i = 0; i < nr_opts; ++i) {
+ int copylen = len;
+
+ if (len > DCCP_SINGLE_OPT_MAXLEN)
+ copylen = DCCP_SINGLE_OPT_MAXLEN;
+
+ /*
+ * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via
+ * its type; ack_nonce is the sum of all individual buf_nonce's.
+ */
+ nonce ^= av->av_buf_nonce[i];
+
+ *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i];
+ *to++ = copylen + 2;
+
+ /* Check if buf_head wraps */
+ if (from + copylen > tail) {
+ const u16 tailsize = tail - from;
+
+ memcpy(to, from, tailsize);
+ to += tailsize;
+ len -= tailsize;
+ copylen -= tailsize;
+ from = av->av_buf;
+ }
+
+ memcpy(to, from, copylen);
+ from += copylen;
+ to += copylen;
+ len -= copylen;
+ }
+ /*
+ * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340.
+ */
+ if (dccp_ackvec_update_records(av, dcb->dccpd_seq, nonce))
+ return -ENOBUFS;
+ return 0;
+}
+
/**
* dccp_insert_option_mandatory - Mandatory option (5.8.2)
* Note that since we are using skb_push, this function needs to be called
@@ -519,8 +598,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
if (dccp_insert_option_timestamp(skb))
return -1;
- } else if (dp->dccps_hc_rx_ackvec != NULL &&
- dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
+ } else if (dccp_ackvec_pending(sk) &&
dccp_insert_option_ackvec(sk, skb)) {
return -1;
}
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 45b91853f5ae..784d30210543 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -242,7 +242,7 @@ static void dccp_xmit_packet(struct sock *sk)
{
int err, len;
struct dccp_sock *dp = dccp_sk(sk);
- struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue);
+ struct sk_buff *skb = dccp_qpolicy_pop(sk);
if (unlikely(skb == NULL))
return;
@@ -283,6 +283,15 @@ static void dccp_xmit_packet(struct sock *sk)
* any local drop will eventually be reported via receiver feedback.
*/
ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
+
+ /*
+ * If the CCID needs to transfer additional header options out-of-band
+ * (e.g. Ack Vectors or feature-negotiation options), it activates this
+ * flag to schedule a Sync. The Sync will automatically incorporate all
+ * currently pending header options, thus clearing the backlog.
+ */
+ if (dp->dccps_sync_scheduled)
+ dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
}
/**
@@ -336,7 +345,7 @@ void dccp_write_xmit(struct sock *sk)
struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
- while ((skb = skb_peek(&sk->sk_write_queue))) {
+ while ((skb = dccp_qpolicy_top(sk))) {
int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
switch (ccid_packet_dequeue_eval(rc)) {
@@ -350,8 +359,7 @@ void dccp_write_xmit(struct sock *sk)
dccp_xmit_packet(sk);
break;
case CCID_PACKET_ERR:
- skb_dequeue(&sk->sk_write_queue);
- kfree_skb(skb);
+ dccp_qpolicy_drop(sk, skb);
dccp_pr_debug("packet discarded due to err=%d\n", rc);
}
}
@@ -636,6 +644,12 @@ void dccp_send_sync(struct sock *sk, const u64 ackno,
DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno;
+ /*
+ * Clear the flag in case the Sync was scheduled for out-of-band data,
+ * such as carrying a long Ack Vector.
+ */
+ dccp_sk(sk)->dccps_sync_scheduled = 0;
+
dccp_transmit_skb(sk, skb);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index ef343d53fcea..152975d942d9 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -185,6 +185,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
dp->dccps_role = DCCP_ROLE_UNDEFINED;
dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT;
dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
+ dp->dccps_tx_qlen = sysctl_dccp_tx_qlen;
dccp_init_xmit_timers(sk);
@@ -532,6 +533,20 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
case DCCP_SOCKOPT_RECV_CSCOV:
err = dccp_setsockopt_cscov(sk, val, true);
break;
+ case DCCP_SOCKOPT_QPOLICY_ID:
+ if (sk->sk_state != DCCP_CLOSED)
+ err = -EISCONN;
+ else if (val < 0 || val >= DCCPQ_POLICY_MAX)
+ err = -EINVAL;
+ else
+ dp->dccps_qpolicy = val;
+ break;
+ case DCCP_SOCKOPT_QPOLICY_TXQLEN:
+ if (val < 0)
+ err = -EINVAL;
+ else
+ dp->dccps_tx_qlen = val;
+ break;
default:
err = -ENOPROTOOPT;
break;
@@ -639,6 +654,12 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
case DCCP_SOCKOPT_RECV_CSCOV:
val = dp->dccps_pcrlen;
break;
+ case DCCP_SOCKOPT_QPOLICY_ID:
+ val = dp->dccps_qpolicy;
+ break;
+ case DCCP_SOCKOPT_QPOLICY_TXQLEN:
+ val = dp->dccps_tx_qlen;
+ break;
case 128 ... 191:
return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
len, (u32 __user *)optval, optlen);
@@ -681,6 +702,47 @@ int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
#endif
+static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
+{
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+
+ /*
+ * Assign an (opaque) qpolicy priority value to skb->priority.
+ *
+ * We are overloading this skb field for use with the qpolicy subystem.
+ * The skb->priority is normally used for the SO_PRIORITY option, which
+ * is initialised from sk_priority. Since the assignment of sk_priority
+ * to skb->priority happens later (on layer 3), we overload this field
+ * for use with queueing priorities as long as the skb is on layer 4.
+ * The default priority value (if nothing is set) is 0.
+ */
+ skb->priority = 0;
+
+ for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+
+ if (!CMSG_OK(msg, cmsg))
+ return -EINVAL;
+
+ if (cmsg->cmsg_level != SOL_DCCP)
+ continue;
+
+ if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX &&
+ !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type))
+ return -EINVAL;
+
+ switch (cmsg->cmsg_type) {
+ case DCCP_SCM_PRIORITY:
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32)))
+ return -EINVAL;
+ skb->priority = *(__u32 *)CMSG_DATA(cmsg);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len)
{
@@ -696,8 +758,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
lock_sock(sk);
- if (sysctl_dccp_tx_qlen &&
- (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) {
+ if (dccp_qpolicy_full(sk)) {
rc = -EAGAIN;
goto out_release;
}
@@ -725,7 +786,11 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (rc != 0)
goto out_discard;
- skb_queue_tail(&sk->sk_write_queue, skb);
+ rc = dccp_msghdr_parse(msg, skb);
+ if (rc != 0)
+ goto out_discard;
+
+ dccp_qpolicy_push(sk, skb);
/*
* The xmit_timer is set if the TX CCID is rate-based and will expire
* when congestion control permits to release further packets into the
diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c
new file mode 100644
index 000000000000..63c30bfa4703
--- /dev/null
+++ b/net/dccp/qpolicy.c
@@ -0,0 +1,137 @@
+/*
+ * net/dccp/qpolicy.c
+ *
+ * Policy-based packet dequeueing interface for DCCP.
+ *
+ * Copyright (c) 2008 Tomasz Grobelny <tomasz@grobelny.oswiecenia.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+#include "dccp.h"
+
+/*
+ * Simple Dequeueing Policy:
+ * If tx_qlen is different from 0, enqueue up to tx_qlen elements.
+ */
+static void qpolicy_simple_push(struct sock *sk, struct sk_buff *skb)
+{
+ skb_queue_tail(&sk->sk_write_queue, skb);
+}
+
+static bool qpolicy_simple_full(struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_tx_qlen &&
+ sk->sk_write_queue.qlen >= dccp_sk(sk)->dccps_tx_qlen;
+}
+
+static struct sk_buff *qpolicy_simple_top(struct sock *sk)
+{
+ return skb_peek(&sk->sk_write_queue);
+}
+
+/*
+ * Priority-based Dequeueing Policy:
+ * If tx_qlen is different from 0 and the queue has reached its upper bound
+ * of tx_qlen elements, replace older packets lowest-priority-first.
+ */
+static struct sk_buff *qpolicy_prio_best_skb(struct sock *sk)
+{
+ struct sk_buff *skb, *best = NULL;
+
+ skb_queue_walk(&sk->sk_write_queue, skb)
+ if (best == NULL || skb->priority > best->priority)
+ best = skb;
+ return best;
+}
+
+static struct sk_buff *qpolicy_prio_worst_skb(struct sock *sk)
+{
+ struct sk_buff *skb, *worst = NULL;
+
+ skb_queue_walk(&sk->sk_write_queue, skb)
+ if (worst == NULL || skb->priority < worst->priority)
+ worst = skb;
+ return worst;
+}
+
+static bool qpolicy_prio_full(struct sock *sk)
+{
+ if (qpolicy_simple_full(sk))
+ dccp_qpolicy_drop(sk, qpolicy_prio_worst_skb(sk));
+ return false;
+}
+
+/**
+ * struct dccp_qpolicy_operations - TX Packet Dequeueing Interface
+ * @push: add a new @skb to the write queue
+ * @full: indicates that no more packets will be admitted
+ * @top: peeks at whatever the queueing policy defines as its `top'
+ */
+static struct dccp_qpolicy_operations {
+ void (*push) (struct sock *sk, struct sk_buff *skb);
+ bool (*full) (struct sock *sk);
+ struct sk_buff* (*top) (struct sock *sk);
+ __be32 params;
+
+} qpol_table[DCCPQ_POLICY_MAX] = {
+ [DCCPQ_POLICY_SIMPLE] = {
+ .push = qpolicy_simple_push,
+ .full = qpolicy_simple_full,
+ .top = qpolicy_simple_top,
+ .params = 0,
+ },
+ [DCCPQ_POLICY_PRIO] = {
+ .push = qpolicy_simple_push,
+ .full = qpolicy_prio_full,
+ .top = qpolicy_prio_best_skb,
+ .params = DCCP_SCM_PRIORITY,
+ },
+};
+
+/*
+ * Externally visible interface
+ */
+void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb)
+{
+ qpol_table[dccp_sk(sk)->dccps_qpolicy].push(sk, skb);
+}
+
+bool dccp_qpolicy_full(struct sock *sk)
+{
+ return qpol_table[dccp_sk(sk)->dccps_qpolicy].full(sk);
+}
+
+void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb)
+{
+ if (skb != NULL) {
+ skb_unlink(skb, &sk->sk_write_queue);
+ kfree_skb(skb);
+ }
+}
+
+struct sk_buff *dccp_qpolicy_top(struct sock *sk)
+{
+ return qpol_table[dccp_sk(sk)->dccps_qpolicy].top(sk);
+}
+
+struct sk_buff *dccp_qpolicy_pop(struct sock *sk)
+{
+ struct sk_buff *skb = dccp_qpolicy_top(sk);
+
+ if (skb != NULL) {
+ /* Clear any skb fields that we used internally */
+ skb->priority = 0;
+ skb_unlink(skb, &sk->sk_write_queue);
+ }
+ return skb;
+}
+
+bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param)
+{
+ /* check if exactly one bit is set */
+ if (!param || (param & (param - 1)))
+ return false;
+ return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param;
+}
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 6f97268ed85f..2af15b15d1fa 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -829,7 +829,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
return -EINVAL;
scp->state = DN_CC;
- scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS);
+ scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
dn_send_conn_conf(sk, allocation);
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -958,7 +958,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
sk->sk_route_caps = sk->sk_dst_cache->dev->features;
sock->state = SS_CONNECTING;
scp->state = DN_CI;
- scp->segsize_loc = dst_metric(sk->sk_dst_cache, RTAX_ADVMSS);
+ scp->segsize_loc = dst_metric_advmss(sk->sk_dst_cache);
dn_nsp_send_conninit(sk, NSP_CI);
err = -EINPROGRESS;
@@ -1850,7 +1850,7 @@ unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu)
{
unsigned mss = 230 - DN_MAX_NSP_DATA_HEADER;
if (dev) {
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
mtu -= LL_RESERVED_SPACE(dev);
if (dn_db->use_long)
mtu -= 21;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 4c409b46aa35..0ba15633c418 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -267,7 +267,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
if (table->extra1 == NULL)
return -EINVAL;
- dn_db = dev->dn_ptr;
+ dn_db = rcu_dereference_raw(dev->dn_ptr);
old = dn_db->parms.forwarding;
err = proc_dointvec(table, write, buffer, lenp, ppos);
@@ -332,14 +332,19 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void)
return ifa;
}
-static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa)
+static void dn_dev_free_ifa_rcu(struct rcu_head *head)
{
- kfree(ifa);
+ kfree(container_of(head, struct dn_ifaddr, rcu));
}
-static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy)
+static void dn_dev_free_ifa(struct dn_ifaddr *ifa)
{
- struct dn_ifaddr *ifa1 = *ifap;
+ call_rcu(&ifa->rcu, dn_dev_free_ifa_rcu);
+}
+
+static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy)
+{
+ struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap);
unsigned char mac_addr[6];
struct net_device *dev = dn_db->dev;
@@ -373,7 +378,9 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
ASSERT_RTNL();
/* Check for duplicates */
- for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) {
+ for (ifa1 = rtnl_dereference(dn_db->ifa_list);
+ ifa1 != NULL;
+ ifa1 = rtnl_dereference(ifa1->ifa_next)) {
if (ifa1->ifa_local == ifa->ifa_local)
return -EEXIST;
}
@@ -386,7 +393,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
}
ifa->ifa_next = dn_db->ifa_list;
- dn_db->ifa_list = ifa;
+ rcu_assign_pointer(dn_db->ifa_list, ifa);
dn_ifaddr_notify(RTM_NEWADDR, ifa);
blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
@@ -396,7 +403,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
int rv;
if (dn_db == NULL) {
@@ -425,7 +432,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
struct dn_dev *dn_db;
struct net_device *dev;
- struct dn_ifaddr *ifa = NULL, **ifap = NULL;
+ struct dn_ifaddr *ifa = NULL;
+ struct dn_ifaddr __rcu **ifap = NULL;
int ret = 0;
if (copy_from_user(ifr, arg, DN_IFREQ_SIZE))
@@ -454,8 +462,10 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
goto done;
}
- if ((dn_db = dev->dn_ptr) != NULL) {
- for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next)
+ if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) {
+ for (ifap = &dn_db->ifa_list;
+ (ifa = rtnl_dereference(*ifap)) != NULL;
+ ifap = &ifa->ifa_next)
if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0)
break;
}
@@ -558,7 +568,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
dev = __dev_get_by_index(&init_net, ifindex);
if (dev)
- dn_dev = dev->dn_ptr;
+ dn_dev = rtnl_dereference(dev->dn_ptr);
return dn_dev;
}
@@ -576,7 +586,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct nlattr *tb[IFA_MAX+1];
struct dn_dev *dn_db;
struct ifaddrmsg *ifm;
- struct dn_ifaddr *ifa, **ifap;
+ struct dn_ifaddr *ifa;
+ struct dn_ifaddr __rcu **ifap;
int err = -EINVAL;
if (!net_eq(net, &init_net))
@@ -592,7 +603,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
goto errout;
err = -EADDRNOTAVAIL;
- for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) {
+ for (ifap = &dn_db->ifa_list;
+ (ifa = rtnl_dereference(*ifap)) != NULL;
+ ifap = &ifa->ifa_next) {
if (tb[IFA_LOCAL] &&
nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
continue;
@@ -632,7 +645,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
return -ENODEV;
- if ((dn_db = dev->dn_ptr) == NULL) {
+ if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) {
dn_db = dn_dev_create(dev, &err);
if (!dn_db)
return err;
@@ -748,11 +761,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
skip_naddr = 0;
}
- if ((dn_db = dev->dn_ptr) == NULL)
+ if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL)
goto cont;
- for (ifa = dn_db->ifa_list, dn_idx = 0; ifa;
- ifa = ifa->ifa_next, dn_idx++) {
+ for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
+ ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) {
if (dn_idx < skip_naddr)
continue;
@@ -773,21 +786,22 @@ done:
static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
{
- struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+ struct dn_dev *dn_db;
struct dn_ifaddr *ifa;
int rv = -ENODEV;
+ rcu_read_lock();
+ dn_db = rcu_dereference(dev->dn_ptr);
if (dn_db == NULL)
goto out;
- rtnl_lock();
- ifa = dn_db->ifa_list;
+ ifa = rcu_dereference(dn_db->ifa_list);
if (ifa != NULL) {
*addr = ifa->ifa_local;
rv = 0;
}
- rtnl_unlock();
out:
+ rcu_read_unlock();
return rv;
}
@@ -823,7 +837,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
struct endnode_hello_message *msg;
struct sk_buff *skb = NULL;
__le16 *pktlen;
- struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL)
return;
@@ -889,7 +903,7 @@ static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn
static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
{
int n;
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
struct sk_buff *skb;
size_t size;
@@ -960,7 +974,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
{
- struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
if (dn_db->parms.forwarding == 0)
dn_send_endnode_hello(dev, ifa);
@@ -998,7 +1012,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
static int dn_eth_up(struct net_device *dev)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
if (dn_db->parms.forwarding == 0)
dev_mc_add(dev, dn_rt_all_end_mcast);
@@ -1012,7 +1026,7 @@ static int dn_eth_up(struct net_device *dev)
static void dn_eth_down(struct net_device *dev)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
if (dn_db->parms.forwarding == 0)
dev_mc_del(dev, dn_rt_all_end_mcast);
@@ -1025,12 +1039,16 @@ static void dn_dev_set_timer(struct net_device *dev);
static void dn_dev_timer_func(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db;
struct dn_ifaddr *ifa;
+ rcu_read_lock();
+ dn_db = rcu_dereference(dev->dn_ptr);
if (dn_db->t3 <= dn_db->parms.t2) {
if (dn_db->parms.timer3) {
- for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) {
+ for (ifa = rcu_dereference(dn_db->ifa_list);
+ ifa;
+ ifa = rcu_dereference(ifa->ifa_next)) {
if (!(ifa->ifa_flags & IFA_F_SECONDARY))
dn_db->parms.timer3(dev, ifa);
}
@@ -1039,13 +1057,13 @@ static void dn_dev_timer_func(unsigned long arg)
} else {
dn_db->t3 -= dn_db->parms.t2;
}
-
+ rcu_read_unlock();
dn_dev_set_timer(dev);
}
static void dn_dev_set_timer(struct net_device *dev)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
if (dn_db->parms.t2 > dn_db->parms.t3)
dn_db->parms.t2 = dn_db->parms.t3;
@@ -1077,8 +1095,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
return NULL;
memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
- smp_wmb();
- dev->dn_ptr = dn_db;
+
+ rcu_assign_pointer(dev->dn_ptr, dn_db);
dn_db->dev = dev;
init_timer(&dn_db->timer);
@@ -1086,7 +1104,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
if (!dn_db->neigh_parms) {
- dev->dn_ptr = NULL;
+ rcu_assign_pointer(dev->dn_ptr, NULL);
kfree(dn_db);
return NULL;
}
@@ -1125,7 +1143,7 @@ void dn_dev_up(struct net_device *dev)
struct dn_ifaddr *ifa;
__le16 addr = decnet_address;
int maybe_default = 0;
- struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+ struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
return;
@@ -1176,7 +1194,7 @@ void dn_dev_up(struct net_device *dev)
static void dn_dev_delete(struct net_device *dev)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
if (dn_db == NULL)
return;
@@ -1204,13 +1222,13 @@ static void dn_dev_delete(struct net_device *dev)
void dn_dev_down(struct net_device *dev)
{
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
struct dn_ifaddr *ifa;
if (dn_db == NULL)
return;
- while((ifa = dn_db->ifa_list) != NULL) {
+ while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) {
dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0);
dn_dev_free_ifa(ifa);
}
@@ -1270,7 +1288,7 @@ static inline int is_dn_dev(struct net_device *dev)
}
static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(rcu)
+ __acquires(RCU)
{
int i;
struct net_device *dev;
@@ -1313,7 +1331,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void dn_dev_seq_stop(struct seq_file *seq, void *v)
- __releases(rcu)
+ __releases(RCU)
{
rcu_read_unlock();
}
@@ -1340,7 +1358,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v)
struct net_device *dev = v;
char peer_buf[DN_ASCBUF_LEN];
char router_buf[DN_ASCBUF_LEN];
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr);
seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu"
" %04hu %03d %02x %-10s %-7s %-7s\n",
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 4ab96c15166d..0ef0a81bcd72 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -610,10 +610,12 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
/* Scan device list */
rcu_read_lock();
for_each_netdev_rcu(&init_net, dev) {
- dn_db = dev->dn_ptr;
+ dn_db = rcu_dereference(dev->dn_ptr);
if (dn_db == NULL)
continue;
- for(ifa2 = dn_db->ifa_list; ifa2; ifa2 = ifa2->ifa_next) {
+ for (ifa2 = rcu_dereference(dn_db->ifa_list);
+ ifa2 != NULL;
+ ifa2 = rcu_dereference(ifa2->ifa_next)) {
if (ifa2->ifa_local == ifa->ifa_local) {
found_it = 1;
break;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index a085dbcf5c7f..602dade7e9a3 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -391,7 +391,7 @@ int dn_neigh_router_hello(struct sk_buff *skb)
write_lock(&neigh->lock);
neigh->used = jiffies;
- dn_db = (struct dn_dev *)neigh->dev->dn_ptr;
+ dn_db = rcu_dereference(neigh->dev->dn_ptr);
if (!(neigh->nud_state & NUD_PERMANENT)) {
neigh->updated = jiffies;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index df0f3e54ff8a..5e636365d33c 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -93,7 +93,7 @@
struct dn_rt_hash_bucket
{
- struct dn_route *chain;
+ struct dn_route __rcu *chain;
spinlock_t lock;
};
@@ -110,6 +110,8 @@ static unsigned long dn_rt_deadline;
static int dn_dst_gc(struct dst_ops *ops);
static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
+static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
+static unsigned int dn_dst_default_mtu(const struct dst_entry *dst);
static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
static void dn_dst_link_failure(struct sk_buff *);
static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -129,6 +131,8 @@ static struct dst_ops dn_dst_ops = {
.gc_thresh = 128,
.gc = dn_dst_gc,
.check = dn_dst_check,
+ .default_advmss = dn_dst_default_advmss,
+ .default_mtu = dn_dst_default_mtu,
.negative_advice = dn_dst_negative_advice,
.link_failure = dn_dst_link_failure,
.update_pmtu = dn_dst_update_pmtu,
@@ -157,15 +161,17 @@ static inline void dnrt_drop(struct dn_route *rt)
static void dn_dst_check_expire(unsigned long dummy)
{
int i;
- struct dn_route *rt, **rtp;
+ struct dn_route *rt;
+ struct dn_route __rcu **rtp;
unsigned long now = jiffies;
unsigned long expire = 120 * HZ;
- for(i = 0; i <= dn_rt_hash_mask; i++) {
+ for (i = 0; i <= dn_rt_hash_mask; i++) {
rtp = &dn_rt_hash_table[i].chain;
spin_lock(&dn_rt_hash_table[i].lock);
- while((rt=*rtp) != NULL) {
+ while ((rt = rcu_dereference_protected(*rtp,
+ lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
if (atomic_read(&rt->dst.__refcnt) ||
(now - rt->dst.lastuse) < expire) {
rtp = &rt->dst.dn_next;
@@ -186,17 +192,19 @@ static void dn_dst_check_expire(unsigned long dummy)
static int dn_dst_gc(struct dst_ops *ops)
{
- struct dn_route *rt, **rtp;
+ struct dn_route *rt;
+ struct dn_route __rcu **rtp;
int i;
unsigned long now = jiffies;
unsigned long expire = 10 * HZ;
- for(i = 0; i <= dn_rt_hash_mask; i++) {
+ for (i = 0; i <= dn_rt_hash_mask; i++) {
spin_lock_bh(&dn_rt_hash_table[i].lock);
rtp = &dn_rt_hash_table[i].chain;
- while((rt=*rtp) != NULL) {
+ while ((rt = rcu_dereference_protected(*rtp,
+ lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
if (atomic_read(&rt->dst.__refcnt) ||
(now - rt->dst.lastuse) < expire) {
rtp = &rt->dst.dn_next;
@@ -227,7 +235,7 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
{
u32 min_mtu = 230;
struct dn_dev *dn = dst->neighbour ?
- (struct dn_dev *)dst->neighbour->dev->dn_ptr : NULL;
+ rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL;
if (dn && dn->use_long == 0)
min_mtu -= 6;
@@ -236,13 +244,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
if (!(dst_metric_locked(dst, RTAX_MTU))) {
- dst->metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(dst, RTAX_MTU, mtu);
dst_set_expires(dst, dn_rt_mtu_expires);
}
if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
- if (dst_metric(dst, RTAX_ADVMSS) > mss)
- dst->metrics[RTAX_ADVMSS-1] = mss;
+ u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS);
+ if (!existing_mss || existing_mss > mss)
+ dst_metric_set(dst, RTAX_ADVMSS, mss);
}
}
}
@@ -267,23 +276,25 @@ static void dn_dst_link_failure(struct sk_buff *skb)
static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
{
- return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
- (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
+ return ((fl1->fld_dst ^ fl2->fld_dst) |
+ (fl1->fld_src ^ fl2->fld_src) |
(fl1->mark ^ fl2->mark) |
- (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
+ (fl1->fld_scope ^ fl2->fld_scope) |
(fl1->oif ^ fl2->oif) |
(fl1->iif ^ fl2->iif)) == 0;
}
static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
{
- struct dn_route *rth, **rthp;
+ struct dn_route *rth;
+ struct dn_route __rcu **rthp;
unsigned long now = jiffies;
rthp = &dn_rt_hash_table[hash].chain;
spin_lock_bh(&dn_rt_hash_table[hash].lock);
- while((rth = *rthp) != NULL) {
+ while ((rth = rcu_dereference_protected(*rthp,
+ lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) {
if (compare_keys(&rth->fl, &rt->fl)) {
/* Put it first */
*rthp = rth->dst.dn_next;
@@ -315,15 +326,15 @@ static void dn_run_flush(unsigned long dummy)
int i;
struct dn_route *rt, *next;
- for(i = 0; i < dn_rt_hash_mask; i++) {
+ for (i = 0; i < dn_rt_hash_mask; i++) {
spin_lock_bh(&dn_rt_hash_table[i].lock);
- if ((rt = xchg(&dn_rt_hash_table[i].chain, NULL)) == NULL)
+ if ((rt = xchg((struct dn_route **)&dn_rt_hash_table[i].chain, NULL)) == NULL)
goto nothing_to_declare;
- for(; rt; rt=next) {
- next = rt->dst.dn_next;
- rt->dst.dn_next = NULL;
+ for(; rt; rt = next) {
+ next = rcu_dereference_raw(rt->dst.dn_next);
+ RCU_INIT_POINTER(rt->dst.dn_next, NULL);
dst_free((struct dst_entry *)rt);
}
@@ -458,15 +469,16 @@ static int dn_return_long(struct sk_buff *skb)
*/
static int dn_route_rx_packet(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ struct dn_skb_cb *cb;
int err;
if ((err = dn_route_input(skb)) == 0)
return dst_input(skb);
+ cb = DN_SKB_CB(skb);
if (decnet_debug_level & 4) {
char *devname = skb->dev ? skb->dev->name : "???";
- struct dn_skb_cb *cb = DN_SKB_CB(skb);
+
printk(KERN_DEBUG
"DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n",
(int)cb->rt_flags, devname, skb->len,
@@ -573,7 +585,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
struct dn_skb_cb *cb;
unsigned char flags = 0;
__u16 len = le16_to_cpu(*(__le16 *)skb->data);
- struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr;
+ struct dn_dev *dn = rcu_dereference(dev->dn_ptr);
unsigned char padlen = 0;
if (!net_eq(dev_net(dev), &init_net))
@@ -728,7 +740,7 @@ static int dn_forward(struct sk_buff *skb)
{
struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct dst_entry *dst = skb_dst(skb);
- struct dn_dev *dn_db = dst->dev->dn_ptr;
+ struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
struct dn_route *rt;
struct neighbour *neigh = dst->neighbour;
int header_len;
@@ -788,19 +800,28 @@ static int dn_rt_bug(struct sk_buff *skb)
return NET_RX_DROP;
}
+static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
+{
+ return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
+}
+
+static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
+{
+ return dst->dev->mtu;
+}
+
static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
{
struct dn_fib_info *fi = res->fi;
struct net_device *dev = rt->dst.dev;
struct neighbour *n;
- unsigned mss;
+ unsigned int metric;
if (fi) {
if (DN_FIB_RES_GW(*res) &&
DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = DN_FIB_RES_GW(*res);
- memcpy(rt->dst.metrics, fi->fib_metrics,
- sizeof(rt->dst.metrics));
+ dst_import_metrics(&rt->dst, fi->fib_metrics);
}
rt->rt_type = res->type;
@@ -811,13 +832,14 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
rt->dst.neighbour = n;
}
- if (dst_metric(&rt->dst, RTAX_MTU) == 0 ||
- dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
- rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu;
- mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
- if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 ||
- dst_metric(&rt->dst, RTAX_ADVMSS) > mss)
- rt->dst.metrics[RTAX_ADVMSS-1] = mss;
+ if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
+ dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu);
+ metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS);
+ if (metric) {
+ unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
+ if (metric > mss)
+ dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
+ }
return 0;
}
@@ -835,13 +857,16 @@ static inline int dn_match_addr(__le16 addr1, __le16 addr2)
static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope)
{
__le16 saddr = 0;
- struct dn_dev *dn_db = dev->dn_ptr;
+ struct dn_dev *dn_db;
struct dn_ifaddr *ifa;
int best_match = 0;
int ret;
- read_lock(&dev_base_lock);
- for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) {
+ rcu_read_lock();
+ dn_db = rcu_dereference(dev->dn_ptr);
+ for (ifa = rcu_dereference(dn_db->ifa_list);
+ ifa != NULL;
+ ifa = rcu_dereference(ifa->ifa_next)) {
if (ifa->ifa_scope > scope)
continue;
if (!daddr) {
@@ -854,7 +879,7 @@ static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int
if (best_match == 0)
saddr = ifa->ifa_local;
}
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
return saddr;
}
@@ -872,11 +897,9 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re
static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard)
{
- struct flowi fl = { .nl_u = { .dn_u =
- { .daddr = oldflp->fld_dst,
- .saddr = oldflp->fld_src,
- .scope = RT_SCOPE_UNIVERSE,
- } },
+ struct flowi fl = { .fld_dst = oldflp->fld_dst,
+ .fld_src = oldflp->fld_src,
+ .fld_scope = RT_SCOPE_UNIVERSE,
.mark = oldflp->mark,
.iif = init_net.loopback_dev->ifindex,
.oif = oldflp->oif };
@@ -1020,7 +1043,7 @@ source_ok:
err = -ENODEV;
if (dev_out == NULL)
goto out;
- dn_db = dev_out->dn_ptr;
+ dn_db = rcu_dereference_raw(dev_out->dn_ptr);
/* Possible improvement - check all devices for local addr */
if (dn_dev_islocal(dev_out, fl.fld_dst)) {
dev_put(dev_out);
@@ -1171,7 +1194,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
if ((flp->fld_dst == rt->fl.fld_dst) &&
(flp->fld_src == rt->fl.fld_src) &&
(flp->mark == rt->fl.mark) &&
- (rt->fl.iif == 0) &&
+ dn_is_output_route(rt) &&
(rt->fl.oif == flp->oif)) {
dst_use(&rt->dst, jiffies);
rcu_read_unlock_bh();
@@ -1220,11 +1243,9 @@ static int dn_route_input_slow(struct sk_buff *skb)
int flags = 0;
__le16 gateway = 0;
__le16 local_src = 0;
- struct flowi fl = { .nl_u = { .dn_u =
- { .daddr = cb->dst,
- .saddr = cb->src,
- .scope = RT_SCOPE_UNIVERSE,
- } },
+ struct flowi fl = { .fld_dst = cb->dst,
+ .fld_src = cb->src,
+ .fld_scope = RT_SCOPE_UNIVERSE,
.mark = skb->mark,
.iif = skb->dev->ifindex };
struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
@@ -1233,7 +1254,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
dev_hold(in_dev);
- if ((dn_db = in_dev->dn_ptr) == NULL)
+ if ((dn_db = rcu_dereference(in_dev->dn_ptr)) == NULL)
goto out;
/* Zero source addresses are not allowed */
@@ -1496,13 +1517,13 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src);
if (rt->rt_daddr != rt->rt_gateway)
RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
- if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
+ if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto rtattr_failure;
expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires,
rt->dst.error) < 0)
goto rtattr_failure;
- if (rt->fl.iif)
+ if (dn_is_input_route(rt))
RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
@@ -1677,15 +1698,15 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou
{
struct dn_rt_cache_iter_state *s = seq->private;
- rt = rt->dst.dn_next;
- while(!rt) {
+ rt = rcu_dereference_bh(rt->dst.dn_next);
+ while (!rt) {
rcu_read_unlock_bh();
if (--s->bucket < 0)
break;
rcu_read_lock_bh();
- rt = dn_rt_hash_table[s->bucket].chain;
+ rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain);
}
- return rcu_dereference_bh(rt);
+ return rt;
}
static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 48fdf10be7a1..6eb91df3c550 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -175,7 +175,7 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
unsigned dnet_addr_type(__le16 addr)
{
- struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } };
+ struct flowi fl = { .fld_dst = addr };
struct dn_fib_res res;
unsigned ret = RTN_UNICAST;
struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
diff --git a/net/dns_resolver/Makefile b/net/dns_resolver/Makefile
index c0ef4e71dc49..d5c13c2eb36d 100644
--- a/net/dns_resolver/Makefile
+++ b/net/dns_resolver/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_DNS_RESOLVER) += dns_resolver.o
-dns_resolver-objs := dns_key.o dns_query.o
+dns_resolver-y := dns_key.o dns_query.o
diff --git a/net/econet/Makefile b/net/econet/Makefile
index 39f0a77abdbd..05fae8be2fed 100644
--- a/net/econet/Makefile
+++ b/net/econet/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_ECONET) += econet.o
-econet-objs := af_econet.o
+econet-y := af_econet.o
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 13992e1d2726..15dcc1a586b4 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -661,8 +661,10 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
err = 0;
switch (cmd) {
case SIOCSIFADDR:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ if (!capable(CAP_NET_ADMIN)) {
+ err = -EPERM;
+ break;
+ }
edev = dev->ec_ptr;
if (edev == NULL) {
@@ -849,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
{
struct iphdr *ip = ip_hdr(skb);
unsigned char stn = ntohl(ip->saddr) & 0xff;
+ struct dst_entry *dst = skb_dst(skb);
+ struct ec_device *edev = NULL;
struct sock *sk = NULL;
struct sk_buff *newskb;
- struct ec_device *edev = skb->dev->ec_ptr;
+
+ if (dst)
+ edev = dst->dev->ec_ptr;
if (! edev)
goto bad;
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 93c91b633a56..6df6ecf49708 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -52,11 +52,11 @@ struct net_device *ieee802154_get_dev(struct net *net,
switch (addr->addr_type) {
case IEEE802154_ADDR_LONG:
- rtnl_lock();
- dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr);
+ rcu_read_lock();
+ dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr);
if (dev)
dev_hold(dev);
- rtnl_unlock();
+ rcu_read_unlock();
break;
case IEEE802154_ADDR_SHORT:
if (addr->pan_id == 0xffff ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index f581f77d1097..f2b61107df6c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1148,21 +1148,13 @@ int inet_sk_rebuild_header(struct sock *sk)
struct flowi fl = {
.oif = sk->sk_bound_dev_if,
.mark = sk->sk_mark,
- .nl_u = {
- .ip4_u = {
- .daddr = daddr,
- .saddr = inet->inet_saddr,
- .tos = RT_CONN_FLAGS(sk),
- },
- },
+ .fl4_dst = daddr,
+ .fl4_src = inet->inet_saddr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = {
- .ports = {
- .sport = inet->inet_sport,
- .dport = inet->inet_dport,
- },
- },
+ .fl_ip_sport = inet->inet_sport,
+ .fl_ip_dport = inet->inet_dport,
};
security_sk_classify_flow(sk, &fl);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index d8e540c5b071..a2fc7b961dbc 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -433,8 +433,8 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
{
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,
- .saddr = tip } } };
+ struct flowi fl = { .fl4_dst = sip,
+ .fl4_src = tip };
struct rtable *rt;
int flag = 0;
/*unsigned long now; */
@@ -883,7 +883,7 @@ static int arp_process(struct sk_buff *skb)
dont_send = arp_ignore(in_dev, sip, tip);
if (!dont_send && IN_DEV_ARPFILTER(in_dev))
- dont_send |= arp_filter(sip, tip, dev);
+ dont_send = arp_filter(sip, tip, dev);
if (!dont_send) {
n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
if (n) {
@@ -1017,13 +1017,14 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
return 0;
}
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
+ if (__in_dev_get_rcu(dev)) {
+ IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on);
return 0;
}
return -ENXIO;
}
+/* must be called with rcu_read_lock() */
static int arp_req_set_public(struct net *net, struct arpreq *r,
struct net_device *dev)
{
@@ -1033,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
if (mask && mask != htonl(0xFFFFFFFF))
return -EINVAL;
if (!dev && (r->arp_flags & ATF_COM)) {
- dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
+ dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
r->arp_ha.sa_data);
if (!dev)
return -ENODEV;
@@ -1061,8 +1062,8 @@ static int arp_req_set(struct net *net, struct arpreq *r,
if (r->arp_flags & ATF_PERM)
r->arp_flags |= ATF_COM;
if (dev == NULL) {
- struct flowi fl = { .nl_u.ip4_u = { .daddr = ip,
- .tos = RTO_ONLINK } };
+ struct flowi fl = { .fl4_dst = ip,
+ .fl4_tos = RTO_ONLINK };
struct rtable *rt;
err = ip_route_output_key(net, &rt, &fl);
if (err != 0)
@@ -1169,8 +1170,8 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
if (dev == NULL) {
- struct flowi fl = { .nl_u.ip4_u = { .daddr = ip,
- .tos = RTO_ONLINK } };
+ struct flowi fl = { .fl4_dst = ip,
+ .fl4_tos = RTO_ONLINK };
struct rtable *rt;
err = ip_route_output_key(net, &rt, &fl);
if (err != 0)
@@ -1225,10 +1226,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!(r.arp_flags & ATF_NETMASK))
((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
htonl(0xFFFFFFFFUL);
- rtnl_lock();
+ rcu_read_lock();
if (r.arp_dev[0]) {
err = -ENODEV;
- dev = __dev_get_by_name(net, r.arp_dev);
+ dev = dev_get_by_name_rcu(net, r.arp_dev);
if (dev == NULL)
goto out;
@@ -1252,12 +1253,12 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
break;
case SIOCGARP:
err = arp_req_get(&r, dev);
- if (!err && copy_to_user(arg, &r, sizeof(r)))
- err = -EFAULT;
break;
}
out:
- rtnl_unlock();
+ rcu_read_unlock();
+ if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
+ err = -EFAULT;
return err;
}
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index dc94b0316b78..748cb5b337bd 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1256,6 +1256,87 @@ errout:
rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
}
+static size_t inet_get_link_af_size(const struct net_device *dev)
+{
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+
+ if (!in_dev)
+ return 0;
+
+ return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
+}
+
+static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct nlattr *nla;
+ int i;
+
+ if (!in_dev)
+ return -ENODATA;
+
+ nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4);
+ if (nla == NULL)
+ return -EMSGSIZE;
+
+ for (i = 0; i < IPV4_DEVCONF_MAX; i++)
+ ((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i];
+
+ return 0;
+}
+
+static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = {
+ [IFLA_INET_CONF] = { .type = NLA_NESTED },
+};
+
+static int inet_validate_link_af(const struct net_device *dev,
+ const struct nlattr *nla)
+{
+ struct nlattr *a, *tb[IFLA_INET_MAX+1];
+ int err, rem;
+
+ if (dev && !__in_dev_get_rtnl(dev))
+ return -EAFNOSUPPORT;
+
+ err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[IFLA_INET_CONF]) {
+ nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) {
+ int cfgid = nla_type(a);
+
+ if (nla_len(a) < 4)
+ return -EINVAL;
+
+ if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX)
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
+{
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct nlattr *a, *tb[IFLA_INET_MAX+1];
+ int rem;
+
+ if (!in_dev)
+ return -EAFNOSUPPORT;
+
+ if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL) < 0)
+ BUG();
+
+ if (tb[IFLA_INET_CONF]) {
+ nla_for_each_nested(a, tb[IFLA_INET_CONF], rem)
+ ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a));
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_SYSCTL
static void devinet_copy_dflt_conf(struct net *net, int i)
@@ -1349,9 +1430,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
return ret;
}
-int ipv4_doint_and_flush(ctl_table *ctl, int write,
- void __user *buffer,
- size_t *lenp, loff_t *ppos)
+static int ipv4_doint_and_flush(ctl_table *ctl, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
@@ -1619,6 +1700,14 @@ static __net_initdata struct pernet_operations devinet_ops = {
.exit = devinet_exit_net,
};
+static struct rtnl_af_ops inet_af_ops = {
+ .family = AF_INET,
+ .fill_link_af = inet_fill_link_af,
+ .get_link_af_size = inet_get_link_af_size,
+ .validate_link_af = inet_validate_link_af,
+ .set_link_af = inet_set_link_af,
+};
+
void __init devinet_init(void)
{
register_pernet_subsys(&devinet_ops);
@@ -1626,6 +1715,8 @@ void __init devinet_init(void)
register_gifconf(PF_INET, inet_gifconf);
register_netdevice_notifier(&ip_netdev_notifier);
+ rtnl_af_register(&inet_af_ops);
+
rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL);
rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL);
rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 14ca1f1c3fb0..e42a905180f0 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -23,6 +23,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
+
/*
* Allocate an AEAD request structure with extra space for SG and IV.
*
@@ -117,25 +119,35 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize;
int clen;
int alen;
+ int plen;
+ int tfclen;
int nfrags;
/* skb is pure payload to encrypt */
err = -ENOMEM;
- /* Round to block size */
- clen = skb->len;
-
esp = x->data;
aead = esp->aead;
alen = crypto_aead_authsize(aead);
+ tfclen = 0;
+ if (x->tfcpad) {
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+ padto = min(x->tfcpad, esp4_get_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ tfclen = padto - skb->len;
+ }
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
- clen = ALIGN(clen + 2, blksize);
+ clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen)
clen = ALIGN(clen, esp->padlen);
+ plen = clen - skb->len - tfclen;
- if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+ if (err < 0)
goto error;
nfrags = err;
@@ -150,13 +162,17 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */
tail = skb_tail_pointer(trailer);
+ if (tfclen) {
+ memset(tail, 0, tfclen);
+ tail += tfclen;
+ }
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i = 0; i < plen - 2; i++)
tail[i] = i + 1;
} while (0);
- tail[clen - skb->len - 2] = (clen - skb->len) - 2;
- tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ tail[plen - 2] = plen - 2;
+ tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index eb6f69a8f27a..1d2cdd43a878 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -158,18 +158,20 @@ static void fib_flush(struct net *net)
struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
{
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = addr
- }
- },
- .flags = FLOWI_FLAG_MATCH_ANY_IIF
+ .fl4_dst = addr,
};
struct fib_result res = { 0 };
struct net_device *dev = NULL;
+ struct fib_table *local_table;
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+ res.r = NULL;
+#endif
rcu_read_lock();
- if (fib_lookup(net, &fl, &res)) {
+ local_table = fib_get_table(net, RT_TABLE_LOCAL);
+ if (!local_table ||
+ fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) {
rcu_read_unlock();
return NULL;
}
@@ -193,7 +195,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net,
const struct net_device *dev,
__be32 addr)
{
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
+ struct flowi fl = { .fl4_dst = addr };
struct fib_result res;
unsigned ret = RTN_BROADCAST;
struct fib_table *local_table;
@@ -247,13 +249,9 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
{
struct in_device *in_dev;
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = src,
- .saddr = dst,
- .tos = tos
- }
- },
+ .fl4_dst = src,
+ .fl4_src = dst,
+ .fl4_tos = tos,
.mark = mark,
.iif = oif
};
@@ -853,13 +851,9 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb)
struct fib_result res;
struct flowi fl = {
.mark = frn->fl_mark,
- .nl_u = {
- .ip4_u = {
- .daddr = frn->fl_addr,
- .tos = frn->fl_tos,
- .scope = frn->fl_scope
- }
- }
+ .fl4_dst = frn->fl_addr,
+ .fl4_tos = frn->fl_tos,
+ .fl4_scope = frn->fl_scope,
};
#ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -999,7 +993,11 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
rt_cache_flush(dev_net(dev), 0);
break;
case NETDEV_UNREGISTER_BATCH:
- rt_cache_flush_batch();
+ /* The batch unregister is only called on the first
+ * device in the list of devices being unregistered.
+ * Therefore we should not pass dev_net(dev) in here.
+ */
+ rt_cache_flush_batch(NULL);
break;
}
return NOTIFY_DONE;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 3e0da3ef6116..12d3dc3df1b7 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -563,12 +563,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
rcu_read_lock();
{
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = nh->nh_gw,
- .scope = cfg->fc_scope + 1,
- },
- },
+ .fl4_dst = nh->nh_gw,
+ .fl4_scope = cfg->fc_scope + 1,
.oif = nh->nh_oif,
};
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index e5d1a44bcbdf..4aa1b7f01ea0 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -386,10 +386,9 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
daddr = icmp_param->replyopts.faddr;
}
{
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = daddr,
- .saddr = rt->rt_spec_dst,
- .tos = RT_TOS(ip_hdr(skb)->tos) } },
+ struct flowi fl = { .fl4_dst= daddr,
+ .fl4_src = rt->rt_spec_dst,
+ .fl4_tos = RT_TOS(ip_hdr(skb)->tos),
.proto = IPPROTO_ICMP };
security_skb_classify_flow(skb, &fl);
if (ip_route_output_key(net, &rt, &fl))
@@ -506,8 +505,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
struct net_device *dev = NULL;
rcu_read_lock();
- if (rt->fl.iif &&
- net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
+ if (rt_is_input_route(rt) &&
+ net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
dev = dev_get_by_index_rcu(net, rt->fl.iif);
if (dev)
@@ -542,22 +541,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
{
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = icmp_param.replyopts.srr ?
- icmp_param.replyopts.faddr :
- iph->saddr,
- .saddr = saddr,
- .tos = RT_TOS(tos)
- }
- },
+ .fl4_dst = icmp_param.replyopts.srr ?
+ icmp_param.replyopts.faddr : iph->saddr,
+ .fl4_src = saddr,
+ .fl4_tos = RT_TOS(tos),
.proto = IPPROTO_ICMP,
- .uli_u = {
- .icmpt = {
- .type = type,
- .code = code
- }
- }
+ .fl_icmp_type = type,
+ .fl_icmp_code = code,
};
int err;
struct rtable *rt2;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 3c53c2d89e3b..e0e77e297de3 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -149,21 +149,37 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc);
static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
int sfcount, __be32 *psfsrc, int delta);
+
+static void ip_mc_list_reclaim(struct rcu_head *head)
+{
+ kfree(container_of(head, struct ip_mc_list, rcu));
+}
+
static void ip_ma_put(struct ip_mc_list *im)
{
if (atomic_dec_and_test(&im->refcnt)) {
in_dev_put(im->interface);
- kfree(im);
+ call_rcu(&im->rcu, ip_mc_list_reclaim);
}
}
+#define for_each_pmc_rcu(in_dev, pmc) \
+ for (pmc = rcu_dereference(in_dev->mc_list); \
+ pmc != NULL; \
+ pmc = rcu_dereference(pmc->next_rcu))
+
+#define for_each_pmc_rtnl(in_dev, pmc) \
+ for (pmc = rtnl_dereference(in_dev->mc_list); \
+ pmc != NULL; \
+ pmc = rtnl_dereference(pmc->next_rcu))
+
#ifdef CONFIG_IP_MULTICAST
/*
* Timer management
*/
-static __inline__ void igmp_stop_timer(struct ip_mc_list *im)
+static void igmp_stop_timer(struct ip_mc_list *im)
{
spin_lock_bh(&im->lock);
if (del_timer(&im->timer))
@@ -284,6 +300,8 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
return scount;
}
+#define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb))
+
static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
{
struct sk_buff *skb;
@@ -292,14 +310,20 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
struct igmpv3_report *pig;
struct net *net = dev_net(dev);
- skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
- if (skb == NULL)
- return NULL;
+ while (1) {
+ skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev),
+ GFP_ATOMIC | __GFP_NOWARN);
+ if (skb)
+ break;
+ size >>= 1;
+ if (size < 256)
+ return NULL;
+ }
+ igmp_skb_size(skb) = size;
{
struct flowi fl = { .oif = dev->ifindex,
- .nl_u = { .ip4_u = {
- .daddr = IGMPV3_ALL_MCR } },
+ .fl4_dst = IGMPV3_ALL_MCR,
.proto = IPPROTO_IGMP };
if (ip_route_output_key(net, &rt, &fl)) {
kfree_skb(skb);
@@ -384,7 +408,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
return skb;
}
-#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \
+#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \
skb_tailroom(skb)) : 0)
static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
@@ -502,8 +526,8 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
int type;
if (!pmc) {
- read_lock(&in_dev->mc_list_lock);
- for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, pmc) {
if (pmc->multiaddr == IGMP_ALL_HOSTS)
continue;
spin_lock_bh(&pmc->lock);
@@ -514,7 +538,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
skb = add_grec(skb, pmc, type, 0, 0);
spin_unlock_bh(&pmc->lock);
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
} else {
spin_lock_bh(&pmc->lock);
if (pmc->sfcount[MCAST_EXCLUDE])
@@ -556,7 +580,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
struct sk_buff *skb = NULL;
int type, dtype;
- read_lock(&in_dev->mc_list_lock);
+ rcu_read_lock();
spin_lock_bh(&in_dev->mc_tomb_lock);
/* deleted MCA's */
@@ -593,7 +617,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
spin_unlock_bh(&in_dev->mc_tomb_lock);
/* change recs */
- for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rcu(in_dev, pmc) {
spin_lock_bh(&pmc->lock);
if (pmc->sfcount[MCAST_EXCLUDE]) {
type = IGMPV3_BLOCK_OLD_SOURCES;
@@ -616,7 +640,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
}
spin_unlock_bh(&pmc->lock);
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
if (!skb)
return;
@@ -644,7 +668,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
{
struct flowi fl = { .oif = dev->ifindex,
- .nl_u = { .ip4_u = { .daddr = dst } },
+ .fl4_dst = dst,
.proto = IPPROTO_IGMP };
if (ip_route_output_key(net, &rt, &fl))
return -1;
@@ -813,14 +837,14 @@ static void igmp_heard_report(struct in_device *in_dev, __be32 group)
if (group == IGMP_ALL_HOSTS)
return;
- read_lock(&in_dev->mc_list_lock);
- for (im=in_dev->mc_list; im!=NULL; im=im->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, im) {
if (im->multiaddr == group) {
igmp_stop_timer(im);
break;
}
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
}
static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
@@ -906,8 +930,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
* - Use the igmp->igmp_code field as the maximum
* delay possible
*/
- read_lock(&in_dev->mc_list_lock);
- for (im=in_dev->mc_list; im!=NULL; im=im->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, im) {
int changed;
if (group && group != im->multiaddr)
@@ -925,7 +949,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
if (changed)
igmp_mod_timer(im, max_delay);
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
}
/* called in rcu_read_lock() section */
@@ -961,7 +985,7 @@ int igmp_rcv(struct sk_buff *skb)
case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT:
/* Is it our report looped back? */
- if (skb_rtable(skb)->fl.iif == 0)
+ if (rt_is_output_route(skb_rtable(skb)))
break;
/* don't rely on MC router hearing unicast reports */
if (skb->pkt_type == PACKET_MULTICAST ||
@@ -1110,8 +1134,8 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
kfree(pmc);
}
/* clear dead sources, too */
- read_lock(&in_dev->mc_list_lock);
- for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, pmc) {
struct ip_sf_list *psf, *psf_next;
spin_lock_bh(&pmc->lock);
@@ -1123,7 +1147,7 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
kfree(psf);
}
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
}
#endif
@@ -1209,7 +1233,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
ASSERT_RTNL();
- for (im=in_dev->mc_list; im; im=im->next) {
+ for_each_pmc_rtnl(in_dev, im) {
if (im->multiaddr == addr) {
im->users++;
ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0);
@@ -1217,7 +1241,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
}
}
- im = kmalloc(sizeof(*im), GFP_KERNEL);
+ im = kzalloc(sizeof(*im), GFP_KERNEL);
if (!im)
goto out;
@@ -1227,26 +1251,18 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
im->multiaddr = addr;
/* initial mode is (EX, empty) */
im->sfmode = MCAST_EXCLUDE;
- im->sfcount[MCAST_INCLUDE] = 0;
im->sfcount[MCAST_EXCLUDE] = 1;
- im->sources = NULL;
- im->tomb = NULL;
- im->crcount = 0;
atomic_set(&im->refcnt, 1);
spin_lock_init(&im->lock);
#ifdef CONFIG_IP_MULTICAST
- im->tm_running = 0;
setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im);
im->unsolicit_count = IGMP_Unsolicited_Report_Count;
- im->reporter = 0;
- im->gsquery = 0;
#endif
- im->loaded = 0;
- write_lock_bh(&in_dev->mc_list_lock);
- im->next = in_dev->mc_list;
- in_dev->mc_list = im;
+
+ im->next_rcu = in_dev->mc_list;
in_dev->mc_count++;
- write_unlock_bh(&in_dev->mc_list_lock);
+ rcu_assign_pointer(in_dev->mc_list, im);
+
#ifdef CONFIG_IP_MULTICAST
igmpv3_del_delrec(in_dev, im->multiaddr);
#endif
@@ -1260,26 +1276,32 @@ EXPORT_SYMBOL(ip_mc_inc_group);
/*
* Resend IGMP JOIN report; used for bonding.
+ * Called with rcu_read_lock()
*/
-void ip_mc_rejoin_group(struct ip_mc_list *im)
+void ip_mc_rejoin_groups(struct in_device *in_dev)
{
#ifdef CONFIG_IP_MULTICAST
- struct in_device *in_dev = im->interface;
+ struct ip_mc_list *im;
+ int type;
- if (im->multiaddr == IGMP_ALL_HOSTS)
- return;
+ for_each_pmc_rcu(in_dev, im) {
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ continue;
- /* a failover is happening and switches
- * must be notified immediately */
- if (IGMP_V1_SEEN(in_dev))
- igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT);
- else if (IGMP_V2_SEEN(in_dev))
- igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT);
- else
- igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT);
+ /* a failover is happening and switches
+ * must be notified immediately
+ */
+ if (IGMP_V1_SEEN(in_dev))
+ type = IGMP_HOST_MEMBERSHIP_REPORT;
+ else if (IGMP_V2_SEEN(in_dev))
+ type = IGMPV2_HOST_MEMBERSHIP_REPORT;
+ else
+ type = IGMPV3_HOST_MEMBERSHIP_REPORT;
+ igmp_send_report(in_dev, im, type);
+ }
#endif
}
-EXPORT_SYMBOL(ip_mc_rejoin_group);
+EXPORT_SYMBOL(ip_mc_rejoin_groups);
/*
* A socket has left a multicast group on device dev
@@ -1287,17 +1309,18 @@ EXPORT_SYMBOL(ip_mc_rejoin_group);
void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
{
- struct ip_mc_list *i, **ip;
+ struct ip_mc_list *i;
+ struct ip_mc_list __rcu **ip;
ASSERT_RTNL();
- for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) {
+ for (ip = &in_dev->mc_list;
+ (i = rtnl_dereference(*ip)) != NULL;
+ ip = &i->next_rcu) {
if (i->multiaddr == addr) {
if (--i->users == 0) {
- write_lock_bh(&in_dev->mc_list_lock);
- *ip = i->next;
+ *ip = i->next_rcu;
in_dev->mc_count--;
- write_unlock_bh(&in_dev->mc_list_lock);
igmp_group_dropped(i);
if (!in_dev->dead)
@@ -1316,34 +1339,34 @@ EXPORT_SYMBOL(ip_mc_dec_group);
void ip_mc_unmap(struct in_device *in_dev)
{
- struct ip_mc_list *i;
+ struct ip_mc_list *pmc;
ASSERT_RTNL();
- for (i = in_dev->mc_list; i; i = i->next)
- igmp_group_dropped(i);
+ for_each_pmc_rtnl(in_dev, pmc)
+ igmp_group_dropped(pmc);
}
void ip_mc_remap(struct in_device *in_dev)
{
- struct ip_mc_list *i;
+ struct ip_mc_list *pmc;
ASSERT_RTNL();
- for (i = in_dev->mc_list; i; i = i->next)
- igmp_group_added(i);
+ for_each_pmc_rtnl(in_dev, pmc)
+ igmp_group_added(pmc);
}
/* Device going down */
void ip_mc_down(struct in_device *in_dev)
{
- struct ip_mc_list *i;
+ struct ip_mc_list *pmc;
ASSERT_RTNL();
- for (i=in_dev->mc_list; i; i=i->next)
- igmp_group_dropped(i);
+ for_each_pmc_rtnl(in_dev, pmc)
+ igmp_group_dropped(pmc);
#ifdef CONFIG_IP_MULTICAST
in_dev->mr_ifc_count = 0;
@@ -1374,7 +1397,6 @@ void ip_mc_init_dev(struct in_device *in_dev)
in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
#endif
- rwlock_init(&in_dev->mc_list_lock);
spin_lock_init(&in_dev->mc_tomb_lock);
}
@@ -1382,14 +1404,14 @@ void ip_mc_init_dev(struct in_device *in_dev)
void ip_mc_up(struct in_device *in_dev)
{
- struct ip_mc_list *i;
+ struct ip_mc_list *pmc;
ASSERT_RTNL();
ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
- for (i=in_dev->mc_list; i; i=i->next)
- igmp_group_added(i);
+ for_each_pmc_rtnl(in_dev, pmc)
+ igmp_group_added(pmc);
}
/*
@@ -1405,24 +1427,19 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
/* Deactivate timers */
ip_mc_down(in_dev);
- write_lock_bh(&in_dev->mc_list_lock);
- while ((i = in_dev->mc_list) != NULL) {
- in_dev->mc_list = i->next;
+ while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) {
+ in_dev->mc_list = i->next_rcu;
in_dev->mc_count--;
- write_unlock_bh(&in_dev->mc_list_lock);
+
igmp_group_dropped(i);
ip_ma_put(i);
-
- write_lock_bh(&in_dev->mc_list_lock);
}
- write_unlock_bh(&in_dev->mc_list_lock);
}
/* RTNL is locked */
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = imr->imr_multiaddr.s_addr } } };
+ struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr };
struct rtable *rt;
struct net_device *dev = NULL;
struct in_device *idev = NULL;
@@ -1513,18 +1530,18 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
if (!in_dev)
return -ENODEV;
- read_lock(&in_dev->mc_list_lock);
- for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, pmc) {
if (*pmca == pmc->multiaddr)
break;
}
if (!pmc) {
/* MCA not found?? bug */
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
return -ESRCH;
}
spin_lock_bh(&pmc->lock);
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
#ifdef CONFIG_IP_MULTICAST
sf_markstate(pmc);
#endif
@@ -1685,18 +1702,18 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
if (!in_dev)
return -ENODEV;
- read_lock(&in_dev->mc_list_lock);
- for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, pmc) {
if (*pmca == pmc->multiaddr)
break;
}
if (!pmc) {
/* MCA not found?? bug */
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
return -ESRCH;
}
spin_lock_bh(&pmc->lock);
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
#ifdef CONFIG_IP_MULTICAST
sf_markstate(pmc);
@@ -1793,7 +1810,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
err = -EADDRINUSE;
ifindex = imr->imr_ifindex;
- for (i = inet->mc_list; i; i = i->next) {
+ for_each_pmc_rtnl(inet, i) {
if (i->multi.imr_multiaddr.s_addr == addr &&
i->multi.imr_ifindex == ifindex)
goto done;
@@ -1807,7 +1824,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
goto done;
memcpy(&iml->multi, imr, sizeof(*imr));
- iml->next = inet->mc_list;
+ iml->next_rcu = inet->mc_list;
iml->sflist = NULL;
iml->sfmode = MCAST_EXCLUDE;
rcu_assign_pointer(inet->mc_list, iml);
@@ -1821,17 +1838,14 @@ EXPORT_SYMBOL(ip_mc_join_group);
static void ip_sf_socklist_reclaim(struct rcu_head *rp)
{
- struct ip_sf_socklist *psf;
-
- psf = container_of(rp, struct ip_sf_socklist, rcu);
+ kfree(container_of(rp, struct ip_sf_socklist, rcu));
/* sk_omem_alloc should have been decreased by the caller*/
- kfree(psf);
}
static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
struct in_device *in_dev)
{
- struct ip_sf_socklist *psf = iml->sflist;
+ struct ip_sf_socklist *psf = rtnl_dereference(iml->sflist);
int err;
if (psf == NULL) {
@@ -1851,11 +1865,8 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
static void ip_mc_socklist_reclaim(struct rcu_head *rp)
{
- struct ip_mc_socklist *iml;
-
- iml = container_of(rp, struct ip_mc_socklist, rcu);
+ kfree(container_of(rp, struct ip_mc_socklist, rcu));
/* sk_omem_alloc should have been decreased by the caller*/
- kfree(iml);
}
@@ -1866,7 +1877,8 @@ static void ip_mc_socklist_reclaim(struct rcu_head *rp)
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{
struct inet_sock *inet = inet_sk(sk);
- struct ip_mc_socklist *iml, **imlp;
+ struct ip_mc_socklist *iml;
+ struct ip_mc_socklist __rcu **imlp;
struct in_device *in_dev;
struct net *net = sock_net(sk);
__be32 group = imr->imr_multiaddr.s_addr;
@@ -1876,7 +1888,9 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
rtnl_lock();
in_dev = ip_mc_find_dev(net, imr);
ifindex = imr->imr_ifindex;
- for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
+ for (imlp = &inet->mc_list;
+ (iml = rtnl_dereference(*imlp)) != NULL;
+ imlp = &iml->next_rcu) {
if (iml->multi.imr_multiaddr.s_addr != group)
continue;
if (ifindex) {
@@ -1888,7 +1902,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
(void) ip_mc_leave_src(sk, iml, in_dev);
- rcu_assign_pointer(*imlp, iml->next);
+ *imlp = iml->next_rcu;
if (in_dev)
ip_mc_dec_group(in_dev, group);
@@ -1934,7 +1948,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
}
err = -EADDRNOTAVAIL;
- for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rtnl(inet, pmc) {
if ((pmc->multi.imr_multiaddr.s_addr ==
imr.imr_multiaddr.s_addr) &&
(pmc->multi.imr_ifindex == imr.imr_ifindex))
@@ -1958,7 +1972,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
pmc->sfmode = omode;
}
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
if (!add) {
if (!psl)
goto done; /* err = -EADDRNOTAVAIL */
@@ -2077,7 +2091,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
goto done;
}
- for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rtnl(inet, pmc) {
if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
pmc->multi.imr_ifindex == imr.imr_ifindex)
break;
@@ -2107,7 +2121,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
(void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
msf->imsf_fmode, 0, NULL, 0);
}
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
if (psl) {
(void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
psl->sl_count, psl->sl_addr, 0);
@@ -2155,7 +2169,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
}
err = -EADDRNOTAVAIL;
- for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rtnl(inet, pmc) {
if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
pmc->multi.imr_ifindex == imr.imr_ifindex)
break;
@@ -2163,7 +2177,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
if (!pmc) /* must have a prior join */
goto done;
msf->imsf_fmode = pmc->sfmode;
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
rtnl_unlock();
if (!psl) {
len = 0;
@@ -2208,7 +2222,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
err = -EADDRNOTAVAIL;
- for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rtnl(inet, pmc) {
if (pmc->multi.imr_multiaddr.s_addr == addr &&
pmc->multi.imr_ifindex == gsf->gf_interface)
break;
@@ -2216,7 +2230,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
if (!pmc) /* must have a prior join */
goto done;
gsf->gf_fmode = pmc->sfmode;
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
rtnl_unlock();
count = psl ? psl->sl_count : 0;
copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
@@ -2257,7 +2271,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
goto out;
rcu_read_lock();
- for (pmc=rcu_dereference(inet->mc_list); pmc; pmc=rcu_dereference(pmc->next)) {
+ for_each_pmc_rcu(inet, pmc) {
if (pmc->multi.imr_multiaddr.s_addr == loc_addr &&
pmc->multi.imr_ifindex == dif)
break;
@@ -2265,7 +2279,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
ret = inet->mc_all;
if (!pmc)
goto unlock;
- psl = pmc->sflist;
+ psl = rcu_dereference(pmc->sflist);
ret = (pmc->sfmode == MCAST_EXCLUDE);
if (!psl)
goto unlock;
@@ -2300,10 +2314,10 @@ void ip_mc_drop_socket(struct sock *sk)
return;
rtnl_lock();
- while ((iml = inet->mc_list) != NULL) {
+ while ((iml = rtnl_dereference(inet->mc_list)) != NULL) {
struct in_device *in_dev;
- rcu_assign_pointer(inet->mc_list, iml->next);
+ inet->mc_list = iml->next_rcu;
in_dev = inetdev_by_index(net, iml->multi.imr_ifindex);
(void) ip_mc_leave_src(sk, iml, in_dev);
if (in_dev != NULL)
@@ -2321,8 +2335,8 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p
struct ip_sf_list *psf;
int rv = 0;
- read_lock(&in_dev->mc_list_lock);
- for (im=in_dev->mc_list; im; im=im->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(in_dev, im) {
if (im->multiaddr == mc_addr)
break;
}
@@ -2343,7 +2357,7 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p
} else
rv = 1; /* unspecified source; tentatively allow */
}
- read_unlock(&in_dev->mc_list_lock);
+ rcu_read_unlock();
return rv;
}
@@ -2369,13 +2383,11 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
in_dev = __in_dev_get_rcu(state->dev);
if (!in_dev)
continue;
- read_lock(&in_dev->mc_list_lock);
- im = in_dev->mc_list;
+ im = rcu_dereference(in_dev->mc_list);
if (im) {
state->in_dev = in_dev;
break;
}
- read_unlock(&in_dev->mc_list_lock);
}
return im;
}
@@ -2383,11 +2395,9 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im)
{
struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
- im = im->next;
- while (!im) {
- if (likely(state->in_dev != NULL))
- read_unlock(&state->in_dev->mc_list_lock);
+ im = rcu_dereference(im->next_rcu);
+ while (!im) {
state->dev = next_net_device_rcu(state->dev);
if (!state->dev) {
state->in_dev = NULL;
@@ -2396,8 +2406,7 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li
state->in_dev = __in_dev_get_rcu(state->dev);
if (!state->in_dev)
continue;
- read_lock(&state->in_dev->mc_list_lock);
- im = state->in_dev->mc_list;
+ im = rcu_dereference(state->in_dev->mc_list);
}
return im;
}
@@ -2433,10 +2442,8 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
__releases(rcu)
{
struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
- if (likely(state->in_dev != NULL)) {
- read_unlock(&state->in_dev->mc_list_lock);
- state->in_dev = NULL;
- }
+
+ state->in_dev = NULL;
state->dev = NULL;
rcu_read_unlock();
}
@@ -2458,7 +2465,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
querier = "NONE";
#endif
- if (state->in_dev->mc_list == im) {
+ if (rcu_dereference(state->in_dev->mc_list) == im) {
seq_printf(seq, "%d\t%-10s: %5d %7s\n",
state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier);
}
@@ -2517,8 +2524,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
idev = __in_dev_get_rcu(state->dev);
if (unlikely(idev == NULL))
continue;
- read_lock(&idev->mc_list_lock);
- im = idev->mc_list;
+ im = rcu_dereference(idev->mc_list);
if (likely(im != NULL)) {
spin_lock_bh(&im->lock);
psf = im->sources;
@@ -2529,7 +2535,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
}
spin_unlock_bh(&im->lock);
}
- read_unlock(&idev->mc_list_lock);
}
return psf;
}
@@ -2543,9 +2548,6 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
spin_unlock_bh(&state->im->lock);
state->im = state->im->next;
while (!state->im) {
- if (likely(state->idev != NULL))
- read_unlock(&state->idev->mc_list_lock);
-
state->dev = next_net_device_rcu(state->dev);
if (!state->dev) {
state->idev = NULL;
@@ -2554,8 +2556,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
state->idev = __in_dev_get_rcu(state->dev);
if (!state->idev)
continue;
- read_lock(&state->idev->mc_list_lock);
- state->im = state->idev->mc_list;
+ state->im = rcu_dereference(state->idev->mc_list);
}
if (!state->im)
break;
@@ -2601,10 +2602,7 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
spin_unlock_bh(&state->im->lock);
state->im = NULL;
}
- if (likely(state->idev != NULL)) {
- read_unlock(&state->idev->mc_list_lock);
- state->idev = NULL;
- }
+ state->idev = NULL;
state->dev = NULL;
rcu_read_unlock();
}
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 7174370b1195..25e318153f14 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -55,7 +55,6 @@ EXPORT_SYMBOL(inet_get_local_port_range);
int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb)
{
- const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
struct sock *sk2;
struct hlist_node *node;
int reuse = sk->sk_reuse;
@@ -75,9 +74,9 @@ int inet_csk_bind_conflict(const struct sock *sk,
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
if (!reuse || !sk2->sk_reuse ||
sk2->sk_state == TCP_LISTEN) {
- const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
- if (!sk2_rcv_saddr || !sk_rcv_saddr ||
- sk2_rcv_saddr == sk_rcv_saddr)
+ const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2);
+ if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) ||
+ sk2_rcv_saddr == sk_rcv_saddr(sk))
break;
}
}
@@ -358,17 +357,14 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
struct ip_options *opt = inet_rsk(req)->opt;
struct flowi fl = { .oif = sk->sk_bound_dev_if,
.mark = sk->sk_mark,
- .nl_u = { .ip4_u =
- { .daddr = ((opt && opt->srr) ?
- opt->faddr :
- ireq->rmt_addr),
- .saddr = ireq->loc_addr,
- .tos = RT_CONN_FLAGS(sk) } },
+ .fl4_dst = ((opt && opt->srr) ?
+ opt->faddr : ireq->rmt_addr),
+ .fl4_src = ireq->loc_addr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = { .ports =
- { .sport = inet_sk(sk)->inet_sport,
- .dport = ireq->rmt_port } } };
+ .fl_ip_sport = inet_sk(sk)->inet_sport,
+ .fl_ip_dport = ireq->rmt_port };
struct net *net = sock_net(sk);
security_req_classify_flow(req, &fl);
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 9e94d7cf4f8a..d9bc85751c74 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -63,7 +63,7 @@
* refcnt: atomically against modifications on other CPU;
* usually under some other lock to prevent node disappearing
* dtime: unused node list lock
- * v4daddr: unchangeable
+ * daddr: unchangeable
* ip_id_count: atomic value (no lock needed)
*/
@@ -79,15 +79,24 @@ static const struct inet_peer peer_fake_node = {
.avl_height = 0
};
-static struct {
+struct inet_peer_base {
struct inet_peer __rcu *root;
spinlock_t lock;
int total;
-} peers = {
+};
+
+static struct inet_peer_base v4_peers = {
+ .root = peer_avl_empty_rcu,
+ .lock = __SPIN_LOCK_UNLOCKED(v4_peers.lock),
+ .total = 0,
+};
+
+static struct inet_peer_base v6_peers = {
.root = peer_avl_empty_rcu,
- .lock = __SPIN_LOCK_UNLOCKED(peers.lock),
+ .lock = __SPIN_LOCK_UNLOCKED(v6_peers.lock),
.total = 0,
};
+
#define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
/* Exported for sysctl_net_ipv4. */
@@ -152,28 +161,45 @@ static void unlink_from_unused(struct inet_peer *p)
}
}
+static int addr_compare(const struct inetpeer_addr *a,
+ const struct inetpeer_addr *b)
+{
+ int i, n = (a->family == AF_INET ? 1 : 4);
+
+ for (i = 0; i < n; i++) {
+ if (a->a6[i] == b->a6[i])
+ continue;
+ if (a->a6[i] < b->a6[i])
+ return -1;
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Called with local BH disabled and the pool lock held.
*/
-#define lookup(_daddr, _stack) \
+#define lookup(_daddr, _stack, _base) \
({ \
struct inet_peer *u; \
struct inet_peer __rcu **v; \
\
stackptr = _stack; \
- *stackptr++ = &peers.root; \
- for (u = rcu_dereference_protected(peers.root, \
- lockdep_is_held(&peers.lock)); \
+ *stackptr++ = &_base->root; \
+ for (u = rcu_dereference_protected(_base->root, \
+ lockdep_is_held(&_base->lock)); \
u != peer_avl_empty; ) { \
- if (_daddr == u->v4daddr) \
+ int cmp = addr_compare(_daddr, &u->daddr); \
+ if (cmp == 0) \
break; \
- if ((__force __u32)_daddr < (__force __u32)u->v4daddr) \
+ if (cmp == -1) \
v = &u->avl_left; \
else \
v = &u->avl_right; \
*stackptr++ = v; \
u = rcu_dereference_protected(*v, \
- lockdep_is_held(&peers.lock)); \
+ lockdep_is_held(&_base->lock)); \
} \
u; \
})
@@ -185,13 +211,15 @@ static void unlink_from_unused(struct inet_peer *p)
* But every pointer we follow is guaranteed to be valid thanks to RCU.
* We exit from this function if number of links exceeds PEER_MAXDEPTH
*/
-static struct inet_peer *lookup_rcu_bh(__be32 daddr)
+static struct inet_peer *lookup_rcu_bh(const struct inetpeer_addr *daddr,
+ struct inet_peer_base *base)
{
- struct inet_peer *u = rcu_dereference_bh(peers.root);
+ struct inet_peer *u = rcu_dereference_bh(base->root);
int count = 0;
while (u != peer_avl_empty) {
- if (daddr == u->v4daddr) {
+ int cmp = addr_compare(daddr, &u->daddr);
+ if (cmp == 0) {
/* Before taking a reference, check if this entry was
* deleted, unlink_from_pool() sets refcnt=-1 to make
* distinction between an unused entry (refcnt=0) and
@@ -201,7 +229,7 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr)
u = NULL;
return u;
}
- if ((__force __u32)daddr < (__force __u32)u->v4daddr)
+ if (cmp == -1)
u = rcu_dereference_bh(u->avl_left);
else
u = rcu_dereference_bh(u->avl_right);
@@ -212,19 +240,19 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr)
}
/* Called with local BH disabled and the pool lock held. */
-#define lookup_rightempty(start) \
+#define lookup_rightempty(start, base) \
({ \
struct inet_peer *u; \
struct inet_peer __rcu **v; \
*stackptr++ = &start->avl_left; \
v = &start->avl_left; \
for (u = rcu_dereference_protected(*v, \
- lockdep_is_held(&peers.lock)); \
+ lockdep_is_held(&base->lock)); \
u->avl_right != peer_avl_empty_rcu; ) { \
v = &u->avl_right; \
*stackptr++ = v; \
u = rcu_dereference_protected(*v, \
- lockdep_is_held(&peers.lock)); \
+ lockdep_is_held(&base->lock)); \
} \
u; \
})
@@ -234,7 +262,8 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr)
* Look into mm/map_avl.c for more detail description of the ideas.
*/
static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
- struct inet_peer __rcu ***stackend)
+ struct inet_peer __rcu ***stackend,
+ struct inet_peer_base *base)
{
struct inet_peer __rcu **nodep;
struct inet_peer *node, *l, *r;
@@ -243,20 +272,20 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
while (stackend > stack) {
nodep = *--stackend;
node = rcu_dereference_protected(*nodep,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
l = rcu_dereference_protected(node->avl_left,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
r = rcu_dereference_protected(node->avl_right,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
lh = node_height(l);
rh = node_height(r);
if (lh > rh + 1) { /* l: RH+2 */
struct inet_peer *ll, *lr, *lrl, *lrr;
int lrh;
ll = rcu_dereference_protected(l->avl_left,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
lr = rcu_dereference_protected(l->avl_right,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
lrh = node_height(lr);
if (lrh <= node_height(ll)) { /* ll: RH+1 */
RCU_INIT_POINTER(node->avl_left, lr); /* lr: RH or RH+1 */
@@ -268,9 +297,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
RCU_INIT_POINTER(*nodep, l);
} else { /* ll: RH, lr: RH+1 */
lrl = rcu_dereference_protected(lr->avl_left,
- lockdep_is_held(&peers.lock)); /* lrl: RH or RH-1 */
+ lockdep_is_held(&base->lock)); /* lrl: RH or RH-1 */
lrr = rcu_dereference_protected(lr->avl_right,
- lockdep_is_held(&peers.lock)); /* lrr: RH or RH-1 */
+ lockdep_is_held(&base->lock)); /* lrr: RH or RH-1 */
RCU_INIT_POINTER(node->avl_left, lrr); /* lrr: RH or RH-1 */
RCU_INIT_POINTER(node->avl_right, r); /* r: RH */
node->avl_height = rh + 1; /* node: RH+1 */
@@ -286,9 +315,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
struct inet_peer *rr, *rl, *rlr, *rll;
int rlh;
rr = rcu_dereference_protected(r->avl_right,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
rl = rcu_dereference_protected(r->avl_left,
- lockdep_is_held(&peers.lock));
+ lockdep_is_held(&base->lock));
rlh = node_height(rl);
if (rlh <= node_height(rr)) { /* rr: LH+1 */
RCU_INIT_POINTER(node->avl_right, rl); /* rl: LH or LH+1 */
@@ -300,9 +329,9 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
RCU_INIT_POINTER(*nodep, r);
} else { /* rr: RH, rl: RH+1 */
rlr = rcu_dereference_protected(rl->avl_right,
- lockdep_is_held(&peers.lock)); /* rlr: LH or LH-1 */
+ lockdep_is_held(&base->lock)); /* rlr: LH or LH-1 */
rll = rcu_dereference_protected(rl->avl_left,
- lockdep_is_held(&peers.lock)); /* rll: LH or LH-1 */
+ lockdep_is_held(&base->lock)); /* rll: LH or LH-1 */
RCU_INIT_POINTER(node->avl_right, rll); /* rll: LH or LH-1 */
RCU_INIT_POINTER(node->avl_left, l); /* l: LH */
node->avl_height = lh + 1; /* node: LH+1 */
@@ -321,14 +350,14 @@ static void peer_avl_rebalance(struct inet_peer __rcu **stack[],
}
/* Called with local BH disabled and the pool lock held. */
-#define link_to_pool(n) \
+#define link_to_pool(n, base) \
do { \
n->avl_height = 1; \
n->avl_left = peer_avl_empty_rcu; \
n->avl_right = peer_avl_empty_rcu; \
/* lockless readers can catch us now */ \
rcu_assign_pointer(**--stackptr, n); \
- peer_avl_rebalance(stack, stackptr); \
+ peer_avl_rebalance(stack, stackptr, base); \
} while (0)
static void inetpeer_free_rcu(struct rcu_head *head)
@@ -337,13 +366,13 @@ static void inetpeer_free_rcu(struct rcu_head *head)
}
/* May be called with local BH enabled. */
-static void unlink_from_pool(struct inet_peer *p)
+static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base)
{
int do_free;
do_free = 0;
- spin_lock_bh(&peers.lock);
+ spin_lock_bh(&base->lock);
/* Check the reference counter. It was artificially incremented by 1
* in cleanup() function to prevent sudden disappearing. If we can
* atomically (because of lockless readers) take this last reference,
@@ -353,7 +382,7 @@ static void unlink_from_pool(struct inet_peer *p)
if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) {
struct inet_peer __rcu **stack[PEER_MAXDEPTH];
struct inet_peer __rcu ***stackptr, ***delp;
- if (lookup(p->v4daddr, stack) != p)
+ if (lookup(&p->daddr, stack, base) != p)
BUG();
delp = stackptr - 1; /* *delp[0] == p */
if (p->avl_left == peer_avl_empty_rcu) {
@@ -362,11 +391,11 @@ static void unlink_from_pool(struct inet_peer *p)
} else {
/* look for a node to insert instead of p */
struct inet_peer *t;
- t = lookup_rightempty(p);
+ t = lookup_rightempty(p, base);
BUG_ON(rcu_dereference_protected(*stackptr[-1],
- lockdep_is_held(&peers.lock)) != t);
+ lockdep_is_held(&base->lock)) != t);
**--stackptr = t->avl_left;
- /* t is removed, t->v4daddr > x->v4daddr for any
+ /* t is removed, t->daddr > x->daddr for any
* x in p->avl_left subtree.
* Put t in the old place of p. */
RCU_INIT_POINTER(*delp[0], t);
@@ -376,11 +405,11 @@ static void unlink_from_pool(struct inet_peer *p)
BUG_ON(delp[1] != &p->avl_left);
delp[1] = &t->avl_left; /* was &p->avl_left */
}
- peer_avl_rebalance(stack, stackptr);
- peers.total--;
+ peer_avl_rebalance(stack, stackptr, base);
+ base->total--;
do_free = 1;
}
- spin_unlock_bh(&peers.lock);
+ spin_unlock_bh(&base->lock);
if (do_free)
call_rcu_bh(&p->rcu, inetpeer_free_rcu);
@@ -395,6 +424,16 @@ static void unlink_from_pool(struct inet_peer *p)
inet_putpeer(p);
}
+static struct inet_peer_base *family_to_base(int family)
+{
+ return (family == AF_INET ? &v4_peers : &v6_peers);
+}
+
+static struct inet_peer_base *peer_to_base(struct inet_peer *p)
+{
+ return family_to_base(p->daddr.family);
+}
+
/* May be called with local BH enabled. */
static int cleanup_once(unsigned long ttl)
{
@@ -428,21 +467,22 @@ static int cleanup_once(unsigned long ttl)
* happen because of entry limits in route cache. */
return -1;
- unlink_from_pool(p);
+ unlink_from_pool(p, peer_to_base(p));
return 0;
}
/* Called with or without local BH being disabled. */
-struct inet_peer *inet_getpeer(__be32 daddr, int create)
+struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
{
- struct inet_peer *p;
struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr;
+ struct inet_peer_base *base = family_to_base(AF_INET);
+ struct inet_peer *p;
/* Look up for the address quickly, lockless.
* Because of a concurrent writer, we might not find an existing entry.
*/
rcu_read_lock_bh();
- p = lookup_rcu_bh(daddr);
+ p = lookup_rcu_bh(daddr, base);
rcu_read_unlock_bh();
if (p) {
@@ -456,50 +496,57 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create)
/* retry an exact lookup, taking the lock before.
* At least, nodes should be hot in our cache.
*/
- spin_lock_bh(&peers.lock);
- p = lookup(daddr, stack);
+ spin_lock_bh(&base->lock);
+ p = lookup(daddr, stack, base);
if (p != peer_avl_empty) {
atomic_inc(&p->refcnt);
- spin_unlock_bh(&peers.lock);
+ spin_unlock_bh(&base->lock);
/* Remove the entry from unused list if it was there. */
unlink_from_unused(p);
return p;
}
p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL;
if (p) {
- p->v4daddr = daddr;
+ p->daddr = *daddr;
atomic_set(&p->refcnt, 1);
atomic_set(&p->rid, 0);
- atomic_set(&p->ip_id_count, secure_ip_id(daddr));
+ atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4));
p->tcp_ts_stamp = 0;
INIT_LIST_HEAD(&p->unused);
/* Link the node. */
- link_to_pool(p);
- peers.total++;
+ link_to_pool(p, base);
+ base->total++;
}
- spin_unlock_bh(&peers.lock);
+ spin_unlock_bh(&base->lock);
- if (peers.total >= inet_peer_threshold)
+ if (base->total >= inet_peer_threshold)
/* Remove one less-recently-used entry. */
cleanup_once(0);
return p;
}
+static int compute_total(void)
+{
+ return v4_peers.total + v6_peers.total;
+}
+EXPORT_SYMBOL_GPL(inet_getpeer);
+
/* Called with local BH disabled. */
static void peer_check_expire(unsigned long dummy)
{
unsigned long now = jiffies;
- int ttl;
+ int ttl, total;
- if (peers.total >= inet_peer_threshold)
+ total = compute_total();
+ if (total >= inet_peer_threshold)
ttl = inet_peer_minttl;
else
ttl = inet_peer_maxttl
- (inet_peer_maxttl - inet_peer_minttl) / HZ *
- peers.total / inet_peer_threshold * HZ;
+ total / inet_peer_threshold * HZ;
while (!cleanup_once(ttl)) {
if (jiffies != now)
break;
@@ -508,13 +555,14 @@ static void peer_check_expire(unsigned long dummy)
/* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
* interval depending on the total number of entries (more entries,
* less interval). */
- if (peers.total >= inet_peer_threshold)
+ total = compute_total();
+ if (total >= inet_peer_threshold)
peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;
else
peer_periodic_timer.expires = jiffies
+ inet_peer_gc_maxtime
- (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
- peers.total / inet_peer_threshold * HZ;
+ total / inet_peer_threshold * HZ;
add_timer(&peer_periodic_timer);
}
@@ -530,3 +578,4 @@ void inet_putpeer(struct inet_peer *p)
local_bh_enable();
}
+EXPORT_SYMBOL_GPL(inet_putpeer);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 168440834ade..e6215bdd96c0 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -141,7 +141,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a)
qp->daddr = arg->iph->daddr;
qp->user = arg->user;
qp->peer = sysctl_ipfrag_max_dist ?
- inet_getpeer(arg->iph->saddr, 1) : NULL;
+ inet_getpeer_v4(arg->iph->saddr, 1) : NULL;
}
static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 70ff77f02eee..eb68a0e34e49 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -405,11 +405,11 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "gre%%d");
+ strcpy(name, "gre%d");
dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
if (!dev)
- return NULL;
+ return NULL;
dev_net_set(dev, net);
@@ -634,7 +634,7 @@ static int ipgre_rcv(struct sk_buff *skb)
#ifdef CONFIG_NET_IPGRE_BROADCAST
if (ipv4_is_multicast(iph->daddr)) {
/* Looped back packet, drop it! */
- if (skb_rtable(skb)->fl.iif == 0)
+ if (rt_is_output_route(skb_rtable(skb)))
goto drop;
tunnel->dev->stats.multicast++;
skb->pkt_type = PACKET_BROADCAST;
@@ -772,16 +772,11 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
{
struct flowi fl = {
.oif = tunnel->parms.link,
- .nl_u = {
- .ip4_u = {
- .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos)
- }
- },
- .proto = IPPROTO_GRE
- }
-;
+ .fl4_dst = dst,
+ .fl4_src = tiph->saddr,
+ .fl4_tos = RT_TOS(tos),
+ .fl_gre_key = tunnel->parms.o_key
+ };
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
dev->stats.tx_carrier_errors++;
goto tx_error;
@@ -823,7 +818,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
!ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
rt6->rt6i_dst.plen == 128) {
rt6->rt6i_flags |= RTF_MODIFIED;
- skb_dst(skb)->metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
}
}
@@ -895,7 +890,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
#endif
else
- iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT);
+ iph->ttl = ip4_dst_hoplimit(&rt->dst);
}
((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags;
@@ -951,14 +946,11 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
if (iph->daddr) {
struct flowi fl = {
.oif = tunnel->parms.link,
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos)
- }
- },
- .proto = IPPROTO_GRE
+ .fl4_dst = iph->daddr,
+ .fl4_src = iph->saddr,
+ .fl4_tos = RT_TOS(iph->tos),
+ .proto = IPPROTO_GRE,
+ .fl_gre_key = tunnel->parms.o_key
};
struct rtable *rt;
@@ -1216,14 +1208,11 @@ static int ipgre_open(struct net_device *dev)
if (ipv4_is_multicast(t->parms.iph.daddr)) {
struct flowi fl = {
.oif = t->parms.link,
- .nl_u = {
- .ip4_u = {
- .daddr = t->parms.iph.daddr,
- .saddr = t->parms.iph.saddr,
- .tos = RT_TOS(t->parms.iph.tos)
- }
- },
- .proto = IPPROTO_GRE
+ .fl4_dst = t->parms.iph.daddr,
+ .fl4_src = t->parms.iph.saddr,
+ .fl4_tos = RT_TOS(t->parms.iph.tos),
+ .proto = IPPROTO_GRE,
+ .fl_gre_key = t->parms.o_key
};
struct rtable *rt;
@@ -1775,3 +1764,4 @@ module_exit(ipgre_fini);
MODULE_LICENSE("GPL");
MODULE_ALIAS_RTNL_LINK("gre");
MODULE_ALIAS_RTNL_LINK("gretap");
+MODULE_ALIAS("gre0");
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 439d2a34ee44..04c7b3ba6b39 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -82,6 +82,7 @@
#include <linux/tcp.h>
int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
+EXPORT_SYMBOL(sysctl_ip_default_ttl);
/* Generate a checksum for an outgoing IP datagram. */
__inline__ void ip_send_check(struct iphdr *iph)
@@ -130,7 +131,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
int ttl = inet->uc_ttl;
if (ttl < 0)
- ttl = dst_metric(dst, RTAX_HOPLIMIT);
+ ttl = ip4_dst_hoplimit(dst);
return ttl;
}
@@ -341,15 +342,13 @@ int ip_queue_xmit(struct sk_buff *skb)
{
struct flowi fl = { .oif = sk->sk_bound_dev_if,
.mark = sk->sk_mark,
- .nl_u = { .ip4_u =
- { .daddr = daddr,
- .saddr = inet->inet_saddr,
- .tos = RT_CONN_FLAGS(sk) } },
+ .fl4_dst = daddr,
+ .fl4_src = inet->inet_saddr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = { .ports =
- { .sport = inet->inet_sport,
- .dport = inet->inet_dport } } };
+ .fl_ip_sport = inet->inet_sport,
+ .fl_ip_dport = inet->inet_dport };
/* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times
@@ -1404,14 +1403,11 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
{
struct flowi fl = { .oif = arg->bound_dev_if,
- .nl_u = { .ip4_u =
- { .daddr = daddr,
- .saddr = rt->rt_spec_dst,
- .tos = RT_TOS(ip_hdr(skb)->tos) } },
- /* Not quite clean, but right. */
- .uli_u = { .ports =
- { .sport = tcp_hdr(skb)->dest,
- .dport = tcp_hdr(skb)->source } },
+ .fl4_dst = daddr,
+ .fl4_src = rt->rt_spec_dst,
+ .fl4_tos = RT_TOS(ip_hdr(skb)->tos),
+ .fl_ip_sport = tcp_hdr(skb)->dest,
+ .fl_ip_dport = tcp_hdr(skb)->source,
.proto = sk->sk_protocol,
.flags = ip_reply_arg_flowi_flags(arg) };
security_skb_classify_flow(skb, &fl);
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 3a6e1ec5e9ae..2b097752426b 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1191,13 +1191,13 @@ static int __init ic_dynamic(void)
(ic_proto_enabled & IC_USE_DHCP) &&
ic_dhcp_msgtype != DHCPACK) {
ic_got_reply = 0;
- printk(",");
+ printk(KERN_CONT ",");
continue;
}
#endif /* IPCONFIG_DHCP */
if (ic_got_reply) {
- printk(" OK\n");
+ printk(KERN_CONT " OK\n");
break;
}
@@ -1205,7 +1205,7 @@ static int __init ic_dynamic(void)
continue;
if (! --retries) {
- printk(" timed out!\n");
+ printk(KERN_CONT " timed out!\n");
break;
}
@@ -1215,7 +1215,7 @@ static int __init ic_dynamic(void)
if (timeout > CONF_TIMEOUT_MAX)
timeout = CONF_TIMEOUT_MAX;
- printk(".");
+ printk(KERN_CONT ".");
}
#ifdef IPCONFIG_BOOTP
@@ -1236,7 +1236,7 @@ static int __init ic_dynamic(void)
((ic_got_reply & IC_RARP) ? "RARP"
: (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
&ic_servaddr);
- printk("my address is %pI4\n", &ic_myaddr);
+ printk(KERN_CONT "my address is %pI4\n", &ic_myaddr);
return 0;
}
@@ -1468,19 +1468,19 @@ static int __init ip_auto_config(void)
/*
* Clue in the operator.
*/
- printk("IP-Config: Complete:");
- printk("\n device=%s", ic_dev->name);
- printk(", addr=%pI4", &ic_myaddr);
- printk(", mask=%pI4", &ic_netmask);
- printk(", gw=%pI4", &ic_gateway);
- printk(",\n host=%s, domain=%s, nis-domain=%s",
+ printk("IP-Config: Complete:\n");
+ printk(" device=%s", ic_dev->name);
+ printk(KERN_CONT ", addr=%pI4", &ic_myaddr);
+ printk(KERN_CONT ", mask=%pI4", &ic_netmask);
+ printk(KERN_CONT ", gw=%pI4", &ic_gateway);
+ printk(KERN_CONT ",\n host=%s, domain=%s, nis-domain=%s",
utsname()->nodename, ic_domain, utsname()->domainname);
- printk(",\n bootserver=%pI4", &ic_servaddr);
- printk(", rootserver=%pI4", &root_server_addr);
- printk(", rootpath=%s", root_server_path);
+ printk(KERN_CONT ",\n bootserver=%pI4", &ic_servaddr);
+ printk(KERN_CONT ", rootserver=%pI4", &root_server_addr);
+ printk(KERN_CONT ", rootpath=%s", root_server_path);
if (ic_dev_mtu)
- printk(", mtu=%d", ic_dev_mtu);
- printk("\n");
+ printk(KERN_CONT ", mtu=%d", ic_dev_mtu);
+ printk(KERN_CONT "\n");
#endif /* !SILENT */
return 0;
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index cd300aaee78f..988f52fba54a 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -463,13 +463,9 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct flowi fl = {
.oif = tunnel->parms.link,
- .nl_u = {
- .ip4_u = {
- .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos)
- }
- },
+ .fl4_dst = dst,
+ .fl4_src= tiph->saddr,
+ .fl4_tos = RT_TOS(tos),
.proto = IPPROTO_IPIP
};
@@ -589,13 +585,9 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
if (iph->daddr) {
struct flowi fl = {
.oif = tunnel->parms.link,
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos)
- }
- },
+ .fl4_dst = iph->daddr,
+ .fl4_src = iph->saddr,
+ .fl4_tos = RT_TOS(iph->tos),
.proto = IPPROTO_IPIP
};
struct rtable *rt;
@@ -921,3 +913,4 @@ static void __exit ipip_fini(void)
module_init(ipip_init);
module_exit(ipip_fini);
MODULE_LICENSE("GPL");
+MODULE_ALIAS("tunl0");
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 86dd5691af46..3f3a9afd73e0 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1537,13 +1537,9 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
if (vif->flags & VIFF_TUNNEL) {
struct flowi fl = {
.oif = vif->link,
- .nl_u = {
- .ip4_u = {
- .daddr = vif->remote,
- .saddr = vif->local,
- .tos = RT_TOS(iph->tos)
- }
- },
+ .fl4_dst = vif->remote,
+ .fl4_src = vif->local,
+ .fl4_tos = RT_TOS(iph->tos),
.proto = IPPROTO_IPIP
};
@@ -1553,12 +1549,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
} else {
struct flowi fl = {
.oif = vif->link,
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .tos = RT_TOS(iph->tos)
- }
- },
+ .fl4_dst = iph->daddr,
+ .fl4_tos = RT_TOS(iph->tos),
.proto = IPPROTO_IPIP
};
@@ -1654,7 +1646,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
if (mrt->vif_table[vif].dev != skb->dev) {
int true_vifi;
- if (skb_rtable(skb)->fl.iif == 0) {
+ if (rt_is_output_route(skb_rtable(skb))) {
/* It is our own packet, looped back.
* Very complicated situation...
*
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index d88a46c54fd1..994a1f29ebbc 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -31,10 +31,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
* packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
*/
if (addr_type == RTN_LOCAL) {
- fl.nl_u.ip4_u.daddr = iph->daddr;
+ fl.fl4_dst = iph->daddr;
if (type == RTN_LOCAL)
- fl.nl_u.ip4_u.saddr = iph->saddr;
- fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
+ fl.fl4_src = iph->saddr;
+ fl.fl4_tos = RT_TOS(iph->tos);
fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl.mark = skb->mark;
fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
@@ -47,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
} else {
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
- fl.nl_u.ip4_u.daddr = iph->saddr;
+ fl.fl4_dst = iph->saddr;
if (ip_route_output_key(net, &rt, &fl) != 0)
return -1;
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 48111594ee9b..19eb59d01037 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -3,15 +3,15 @@
#
# objects for l3 independent conntrack
-nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
+nf_conntrack_ipv4-y := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
ifeq ($(CONFIG_PROC_FS),y)
nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
endif
endif
-nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
-iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
+nf_nat-y := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
+iptable_nat-y := nf_nat_rule.o nf_nat_standalone.o
# connection tracking
obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 43eec80c0e7c..1ff79e557f96 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -116,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
if (ip_route_me_harder(nskb, addr_type))
goto free_nskb;
- niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
+ niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
/* "Never happens" */
if (nskb->len > dst_mtu(skb_dst(nskb)))
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 1b48eb1ed453..b14ec7d03b6e 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+ SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 1f85ef289895..a3d5ab786e81 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -549,10 +549,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
{
struct flowi fl = { .oif = ipc.oif,
.mark = sk->sk_mark,
- .nl_u = { .ip4_u =
- { .daddr = daddr,
- .saddr = saddr,
- .tos = tos } },
+ .fl4_dst = daddr,
+ .fl4_src = saddr,
+ .fl4_tos = tos,
.proto = inet->hdrincl ? IPPROTO_RAW :
sk->sk_protocol,
};
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 987bf9adb318..351dc4e85242 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -139,20 +139,26 @@ static unsigned long expires_ljiffies;
*/
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
+static unsigned int ipv4_default_advmss(const struct dst_entry *dst);
+static unsigned int ipv4_default_mtu(const struct dst_entry *dst);
static void ipv4_dst_destroy(struct dst_entry *dst);
-static void ipv4_dst_ifdown(struct dst_entry *dst,
- struct net_device *dev, int how);
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 ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+ int how)
+{
+}
static struct dst_ops ipv4_dst_ops = {
.family = AF_INET,
.protocol = cpu_to_be16(ETH_P_IP),
.gc = rt_garbage_collect,
.check = ipv4_dst_check,
+ .default_advmss = ipv4_default_advmss,
+ .default_mtu = ipv4_default_mtu,
.destroy = ipv4_dst_destroy,
.ifdown = ipv4_dst_ifdown,
.negative_advice = ipv4_negative_advice,
@@ -381,8 +387,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
(__force u32)r->rt_gateway,
r->rt_flags, atomic_read(&r->dst.__refcnt),
r->dst.__use, 0, (__force u32)r->rt_src,
- (dst_metric(&r->dst, RTAX_ADVMSS) ?
- (int)dst_metric(&r->dst, RTAX_ADVMSS) + 40 : 0),
+ dst_metric_advmss(&r->dst) + 40,
dst_metric(&r->dst, RTAX_WINDOW),
(int)((dst_metric(&r->dst, RTAX_RTT) >> 3) +
dst_metric(&r->dst, RTAX_RTTVAR)),
@@ -621,7 +626,7 @@ static inline int rt_fast_clean(struct rtable *rth)
/* Kill broadcast/multicast entries very aggresively, if they
collide in hash table with more useful entries */
return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) &&
- rth->fl.iif && rth->dst.rt_next;
+ rt_is_input_route(rth) && rth->dst.rt_next;
}
static inline int rt_valuable(struct rtable *rth)
@@ -666,7 +671,7 @@ static inline u32 rt_score(struct rtable *rt)
if (rt_valuable(rt))
score |= (1<<31);
- if (!rt->fl.iif ||
+ if (rt_is_output_route(rt) ||
!(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL)))
score |= (1<<30);
@@ -682,17 +687,17 @@ static inline bool rt_caching(const struct net *net)
static inline bool compare_hash_inputs(const struct flowi *fl1,
const struct flowi *fl2)
{
- return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) |
- ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) |
+ return ((((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) |
+ ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) |
(fl1->iif ^ fl2->iif)) == 0);
}
static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
{
- return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) |
- ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) |
+ return (((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) |
+ ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) |
(fl1->mark ^ fl2->mark) |
- (*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) |
+ (*(u16 *)&fl1->fl4_tos ^ *(u16 *)&fl2->fl4_tos) |
(fl1->oif ^ fl2->oif) |
(fl1->iif ^ fl2->iif)) == 0;
}
@@ -712,13 +717,15 @@ static inline int rt_is_expired(struct rtable *rth)
* Can be called by a softirq or a process.
* In the later case, we want to be reschedule if necessary
*/
-static void rt_do_flush(int process_context)
+static void rt_do_flush(struct net *net, int process_context)
{
unsigned int i;
struct rtable *rth, *next;
- struct rtable * tail;
for (i = 0; i <= rt_hash_mask; i++) {
+ struct rtable __rcu **pprev;
+ struct rtable *list;
+
if (process_context && need_resched())
cond_resched();
rth = rcu_dereference_raw(rt_hash_table[i].chain);
@@ -726,50 +733,32 @@ static void rt_do_flush(int process_context)
continue;
spin_lock_bh(rt_hash_lock_addr(i));
-#ifdef CONFIG_NET_NS
- {
- struct rtable __rcu **prev;
- struct rtable *p;
- rth = rcu_dereference_protected(rt_hash_table[i].chain,
+ list = NULL;
+ pprev = &rt_hash_table[i].chain;
+ rth = rcu_dereference_protected(*pprev,
lockdep_is_held(rt_hash_lock_addr(i)));
- /* defer releasing the head of the list after spin_unlock */
- for (tail = rth; tail;
- tail = rcu_dereference_protected(tail->dst.rt_next,
- lockdep_is_held(rt_hash_lock_addr(i))))
- if (!rt_is_expired(tail))
- break;
- if (rth != tail)
- rt_hash_table[i].chain = tail;
-
- /* call rt_free on entries after the tail requiring flush */
- prev = &rt_hash_table[i].chain;
- for (p = rcu_dereference_protected(*prev,
- lockdep_is_held(rt_hash_lock_addr(i)));
- p != NULL;
- p = next) {
- next = rcu_dereference_protected(p->dst.rt_next,
+ while (rth) {
+ next = rcu_dereference_protected(rth->dst.rt_next,
lockdep_is_held(rt_hash_lock_addr(i)));
- if (!rt_is_expired(p)) {
- prev = &p->dst.rt_next;
+
+ if (!net ||
+ net_eq(dev_net(rth->dst.dev), net)) {
+ rcu_assign_pointer(*pprev, next);
+ rcu_assign_pointer(rth->dst.rt_next, list);
+ list = rth;
} else {
- *prev = next;
- rt_free(p);
+ pprev = &rth->dst.rt_next;
}
+ rth = next;
}
- }
-#else
- rth = rcu_dereference_protected(rt_hash_table[i].chain,
- lockdep_is_held(rt_hash_lock_addr(i)));
- rcu_assign_pointer(rt_hash_table[i].chain, NULL);
- tail = NULL;
-#endif
+
spin_unlock_bh(rt_hash_lock_addr(i));
- for (; rth != tail; rth = next) {
- next = rcu_dereference_protected(rth->dst.rt_next, 1);
- rt_free(rth);
+ for (; list; list = next) {
+ next = rcu_dereference_protected(list->dst.rt_next, 1);
+ rt_free(list);
}
}
}
@@ -917,13 +906,13 @@ void rt_cache_flush(struct net *net, int delay)
{
rt_cache_invalidate(net);
if (delay >= 0)
- rt_do_flush(!in_softirq());
+ rt_do_flush(net, !in_softirq());
}
/* Flush previous cache invalidated entries from the cache */
-void rt_cache_flush_batch(void)
+void rt_cache_flush_batch(struct net *net)
{
- rt_do_flush(!in_softirq());
+ rt_do_flush(net, !in_softirq());
}
static void rt_emergency_hash_rebuild(struct net *net)
@@ -1124,7 +1113,7 @@ restart:
*/
rt->dst.flags |= DST_NOCACHE;
- if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
+ if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
if (net_ratelimit())
@@ -1222,7 +1211,7 @@ restart:
/* Try to bind route to arp only if it is output
route or unicast forwarding path.
*/
- if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
+ if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
spin_unlock_bh(rt_hash_lock_addr(hash));
@@ -1287,7 +1276,7 @@ void rt_bind_peer(struct rtable *rt, int create)
{
struct inet_peer *peer;
- peer = inet_getpeer(rt->rt_dst, create);
+ peer = inet_getpeer_v4(rt->rt_dst, create);
if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL)
inet_putpeer(peer);
@@ -1404,7 +1393,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
if (rth->fl.fl4_dst != daddr ||
rth->fl.fl4_src != skeys[i] ||
rth->fl.oif != ikeys[k] ||
- rth->fl.iif != 0 ||
+ rt_is_input_route(rth) ||
rt_is_expired(rth) ||
!net_eq(dev_net(rth->dst.dev), net)) {
rthp = &rth->dst.rt_next;
@@ -1433,8 +1422,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
rt->dst.child = NULL;
if (rt->dst.dev)
dev_hold(rt->dst.dev);
- if (rt->idev)
- in_dev_hold(rt->idev);
rt->dst.obsolete = -1;
rt->dst.lastuse = jiffies;
rt->dst.path = &rt->dst;
@@ -1666,7 +1653,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
rth->rt_dst != daddr ||
rth->rt_src != iph->saddr ||
rth->fl.oif != ikeys[k] ||
- rth->fl.iif != 0 ||
+ rt_is_input_route(rth) ||
dst_metric_locked(&rth->dst, RTAX_MTU) ||
!net_eq(dev_net(rth->dst.dev), net) ||
rt_is_expired(rth))
@@ -1686,11 +1673,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
if (mtu < dst_mtu(&rth->dst)) {
dst_confirm(&rth->dst);
if (mtu < ip_rt_min_pmtu) {
+ u32 lock = dst_metric(&rth->dst,
+ RTAX_LOCK);
mtu = ip_rt_min_pmtu;
- rth->dst.metrics[RTAX_LOCK-1] |=
- (1 << RTAX_MTU);
+ lock |= (1 << RTAX_MTU);
+ dst_metric_set(&rth->dst, RTAX_LOCK,
+ lock);
}
- rth->dst.metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(&rth->dst, RTAX_MTU, mtu);
dst_set_expires(&rth->dst,
ip_rt_mtu_expires);
}
@@ -1708,10 +1698,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
if (dst_mtu(dst) > mtu && mtu >= 68 &&
!(dst_metric_locked(dst, RTAX_MTU))) {
if (mtu < ip_rt_min_pmtu) {
+ u32 lock = dst_metric(dst, RTAX_LOCK);
mtu = ip_rt_min_pmtu;
- dst->metrics[RTAX_LOCK-1] |= (1 << RTAX_MTU);
+ dst_metric_set(dst, RTAX_LOCK, lock | (1 << RTAX_MTU));
}
- dst->metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(dst, RTAX_MTU, mtu);
dst_set_expires(dst, ip_rt_mtu_expires);
call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
@@ -1728,33 +1719,13 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
{
struct rtable *rt = (struct rtable *) dst;
struct inet_peer *peer = rt->peer;
- struct in_device *idev = rt->idev;
if (peer) {
rt->peer = NULL;
inet_putpeer(peer);
}
-
- if (idev) {
- rt->idev = NULL;
- in_dev_put(idev);
- }
}
-static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
- int how)
-{
- struct rtable *rt = (struct rtable *) dst;
- struct in_device *idev = rt->idev;
- if (dev != dev_net(dev)->loopback_dev && idev && idev->dev == dev) {
- struct in_device *loopback_idev =
- in_dev_get(dev_net(dev)->loopback_dev);
- if (loopback_idev) {
- rt->idev = loopback_idev;
- in_dev_put(idev);
- }
- }
-}
static void ipv4_link_failure(struct sk_buff *skb)
{
@@ -1790,7 +1761,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
__be32 src;
struct fib_result res;
- if (rt->fl.iif == 0)
+ if (rt_is_output_route(rt))
src = rt->rt_src;
else {
rcu_read_lock();
@@ -1814,38 +1785,55 @@ static void set_class_tag(struct rtable *rt, u32 tag)
}
#endif
+static unsigned int ipv4_default_advmss(const struct dst_entry *dst)
+{
+ unsigned int advmss = dst_metric_raw(dst, RTAX_ADVMSS);
+
+ if (advmss == 0) {
+ advmss = max_t(unsigned int, dst->dev->mtu - 40,
+ ip_rt_min_advmss);
+ if (advmss > 65535 - 40)
+ advmss = 65535 - 40;
+ }
+ return advmss;
+}
+
+static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
+{
+ unsigned int mtu = dst->dev->mtu;
+
+ if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
+ const struct rtable *rt = (const struct rtable *) dst;
+
+ if (rt->rt_gateway != rt->rt_dst && mtu > 576)
+ mtu = 576;
+ }
+
+ if (mtu > IP_MAX_MTU)
+ mtu = IP_MAX_MTU;
+
+ return mtu;
+}
+
static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
{
+ struct dst_entry *dst = &rt->dst;
struct fib_info *fi = res->fi;
if (fi) {
if (FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = FIB_RES_GW(*res);
- memcpy(rt->dst.metrics, fi->fib_metrics,
- sizeof(rt->dst.metrics));
- if (fi->fib_mtu == 0) {
- rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu;
- if (dst_metric_locked(&rt->dst, RTAX_MTU) &&
- rt->rt_gateway != rt->rt_dst &&
- rt->dst.dev->mtu > 576)
- rt->dst.metrics[RTAX_MTU-1] = 576;
- }
+ dst_import_metrics(dst, fi->fib_metrics);
#ifdef CONFIG_NET_CLS_ROUTE
- rt->dst.tclassid = FIB_RES_NH(*res).nh_tclassid;
+ dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
#endif
- } else
- rt->dst.metrics[RTAX_MTU-1]= rt->dst.dev->mtu;
-
- if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0)
- rt->dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
- if (dst_mtu(&rt->dst) > IP_MAX_MTU)
- rt->dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
- if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0)
- rt->dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->dst.dev->mtu - 40,
- ip_rt_min_advmss);
- if (dst_metric(&rt->dst, RTAX_ADVMSS) > 65535 - 40)
- rt->dst.metrics[RTAX_ADVMSS-1] = 65535 - 40;
+ }
+
+ if (dst_mtu(dst) > IP_MAX_MTU)
+ dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU);
+ if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40)
+ dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40);
#ifdef CONFIG_NET_CLS_ROUTE
#ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -1910,7 +1898,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->fl.iif = dev->ifindex;
rth->dst.dev = init_net.loopback_dev;
dev_hold(rth->dst.dev);
- rth->idev = in_dev_get(rth->dst.dev);
rth->fl.oif = 0;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
@@ -2050,7 +2037,6 @@ static int __mkroute_input(struct sk_buff *skb,
rth->fl.iif = in_dev->dev->ifindex;
rth->dst.dev = (out_dev)->dev;
dev_hold(rth->dst.dev);
- rth->idev = in_dev_get(rth->dst.dev);
rth->fl.oif = 0;
rth->rt_spec_dst= spec_dst;
@@ -2111,12 +2097,10 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
{
struct fib_result res;
struct in_device *in_dev = __in_dev_get_rcu(dev);
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = daddr,
- .saddr = saddr,
- .tos = tos,
- .scope = RT_SCOPE_UNIVERSE,
- } },
+ struct flowi fl = { .fl4_dst = daddr,
+ .fl4_src = saddr,
+ .fl4_tos = tos,
+ .fl4_scope = RT_SCOPE_UNIVERSE,
.mark = skb->mark,
.iif = dev->ifindex };
unsigned flags = 0;
@@ -2231,7 +2215,6 @@ local_input:
rth->fl.iif = dev->ifindex;
rth->dst.dev = net->loopback_dev;
dev_hold(rth->dst.dev);
- rth->idev = in_dev_get(rth->dst.dev);
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
rth->dst.input= ip_local_deliver;
@@ -2417,9 +2400,6 @@ static int __mkroute_output(struct rtable **result,
if (!rth)
return -ENOBUFS;
- in_dev_hold(in_dev);
- rth->idev = in_dev;
-
atomic_set(&rth->dst.__refcnt, 1);
rth->dst.flags= DST_HOST;
if (IN_DEV_CONF_GET(in_dev, NOXFRM))
@@ -2506,14 +2486,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
const struct flowi *oldflp)
{
u32 tos = RT_FL_TOS(oldflp);
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = oldflp->fl4_dst,
- .saddr = oldflp->fl4_src,
- .tos = tos & IPTOS_RT_MASK,
- .scope = ((tos & RTO_ONLINK) ?
- RT_SCOPE_LINK :
- RT_SCOPE_UNIVERSE),
- } },
+ struct flowi fl = { .fl4_dst = oldflp->fl4_dst,
+ .fl4_src = oldflp->fl4_src,
+ .fl4_tos = tos & IPTOS_RT_MASK,
+ .fl4_scope = ((tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK : RT_SCOPE_UNIVERSE),
.mark = oldflp->mark,
.iif = net->loopback_dev->ifindex,
.oif = oldflp->oif };
@@ -2585,9 +2562,10 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
goto out;
/* RACE: Check return value of inet_select_addr instead. */
- if (rcu_dereference(dev_out->ip_ptr) == NULL)
- goto out; /* Wrong error code */
-
+ if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) {
+ err = -ENETUNREACH;
+ goto out;
+ }
if (ipv4_is_local_multicast(oldflp->fl4_dst) ||
ipv4_is_lbcast(oldflp->fl4_dst)) {
if (!fl.fl4_src)
@@ -2648,8 +2626,12 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
}
if (res.type == RTN_LOCAL) {
- if (!fl.fl4_src)
- fl.fl4_src = fl.fl4_dst;
+ if (!fl.fl4_src) {
+ if (res.fi->fib_prefsrc)
+ fl.fl4_src = res.fi->fib_prefsrc;
+ else
+ fl.fl4_src = fl.fl4_dst;
+ }
dev_out = net->loopback_dev;
fl.oif = dev_out->ifindex;
res.fi = NULL;
@@ -2695,7 +2677,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
rth = rcu_dereference_bh(rth->dst.rt_next)) {
if (rth->fl.fl4_dst == flp->fl4_dst &&
rth->fl.fl4_src == flp->fl4_src &&
- rth->fl.iif == 0 &&
+ rt_is_output_route(rth) &&
rth->fl.oif == flp->oif &&
rth->fl.mark == flp->mark &&
!((rth->fl.fl4_tos ^ flp->fl4_tos) &
@@ -2751,7 +2733,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
new->__use = 1;
new->input = dst_discard;
new->output = dst_discard;
- memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32));
+ dst_copy_metrics(new, &ort->dst);
new->dev = ort->dst.dev;
if (new->dev)
@@ -2759,9 +2741,6 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
rt->fl = ort->fl;
- rt->idev = ort->idev;
- if (rt->idev)
- in_dev_hold(rt->idev);
rt->rt_genid = rt_genid(net);
rt->rt_flags = ort->rt_flags;
rt->rt_type = ort->rt_type;
@@ -2853,7 +2832,7 @@ static int rt_fill_info(struct net *net,
if (rt->dst.tclassid)
NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid);
#endif
- if (rt->fl.iif)
+ if (rt_is_input_route(rt))
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
else if (rt->rt_src != rt->fl.fl4_src)
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
@@ -2861,7 +2840,7 @@ static int rt_fill_info(struct net *net,
if (rt->rt_dst != rt->rt_gateway)
NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
- if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
+ if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;
if (rt->fl.mark)
@@ -2878,7 +2857,7 @@ static int rt_fill_info(struct net *net,
}
}
- if (rt->fl.iif) {
+ if (rt_is_input_route(rt)) {
#ifdef CONFIG_IP_MROUTE
__be32 dst = rt->rt_dst;
@@ -2973,13 +2952,9 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
err = -rt->dst.error;
} else {
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = dst,
- .saddr = src,
- .tos = rtm->rtm_tos,
- },
- },
+ .fl4_dst = dst,
+ .fl4_src = src,
+ .fl4_tos = rtm->rtm_tos,
.oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
.mark = mark,
};
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 650cace2180d..47519205a014 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -346,17 +346,14 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
*/
{
struct flowi fl = { .mark = sk->sk_mark,
- .nl_u = { .ip4_u =
- { .daddr = ((opt && opt->srr) ?
- opt->faddr :
- ireq->rmt_addr),
- .saddr = ireq->loc_addr,
- .tos = RT_CONN_FLAGS(sk) } },
+ .fl4_dst = ((opt && opt->srr) ?
+ opt->faddr : ireq->rmt_addr),
+ .fl4_src = ireq->loc_addr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = IPPROTO_TCP,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = { .ports =
- { .sport = th->dest,
- .dport = th->source } } };
+ .fl_ip_sport = th->dest,
+ .fl_ip_dport = th->source };
security_req_classify_flow(req, &fl);
if (ip_route_output_key(sock_net(sk), &rt, &fl)) {
reqsk_free(req);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 1b4ec21497a4..1a456652086b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -28,6 +28,8 @@ static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
+static int ip_ttl_min = 1;
+static int ip_ttl_max = 255;
/* Update system visible IP port range */
static void set_local_port_range(int range[2])
@@ -155,8 +157,9 @@ static struct ctl_table ipv4_table[] = {
.data = &sysctl_ip_default_ttl,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = ipv4_doint_and_flush,
- .extra2 = &init_net,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &ip_ttl_min,
+ .extra2 = &ip_ttl_max,
},
{
.procname = "ip_no_pmtu_disc",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f15c36a706ec..6c11eece262c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1193,7 +1193,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
- KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
+ "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
#endif
@@ -1477,10 +1477,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
* shouldn't happen.
*/
if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
- KERN_INFO "recvmsg bug: copied %X "
- "seq %X rcvnxt %X fl %X\n", *seq,
- TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
- flags))
+ "recvmsg bug: copied %X seq %X rcvnxt %X fl %X\n",
+ *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
+ flags))
break;
offset = *seq - TCP_SKB_CB(skb)->seq;
@@ -1490,10 +1489,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto found_ok_skb;
if (tcp_hdr(skb)->fin)
goto found_fin_ok;
- WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
- "copied %X seq %X rcvnxt %X fl %X\n",
- *seq, TCP_SKB_CB(skb)->seq,
- tp->rcv_nxt, flags);
+ WARN(!(flags & MSG_PEEK),
+ "recvmsg bug 2: copied %X seq %X rcvnxt %X fl %X\n",
+ *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, flags);
}
/* Well, if we have backlog, try to process it now yet. */
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 6d8ab1c4efc3..2549b29b062d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -734,7 +734,7 @@ void tcp_update_metrics(struct sock *sk)
* Reset our results.
*/
if (!(dst_metric_locked(dst, RTAX_RTT)))
- dst->metrics[RTAX_RTT - 1] = 0;
+ dst_metric_set(dst, RTAX_RTT, 0);
return;
}
@@ -776,34 +776,38 @@ void tcp_update_metrics(struct sock *sk)
if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) &&
(tp->snd_cwnd >> 1) > dst_metric(dst, RTAX_SSTHRESH))
- dst->metrics[RTAX_SSTHRESH-1] = tp->snd_cwnd >> 1;
+ dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_cwnd >> 1);
if (!dst_metric_locked(dst, RTAX_CWND) &&
tp->snd_cwnd > dst_metric(dst, RTAX_CWND))
- dst->metrics[RTAX_CWND - 1] = tp->snd_cwnd;
+ dst_metric_set(dst, RTAX_CWND, tp->snd_cwnd);
} else if (tp->snd_cwnd > tp->snd_ssthresh &&
icsk->icsk_ca_state == TCP_CA_Open) {
/* Cong. avoidance phase, cwnd is reliable. */
if (!dst_metric_locked(dst, RTAX_SSTHRESH))
- dst->metrics[RTAX_SSTHRESH-1] =
- max(tp->snd_cwnd >> 1, tp->snd_ssthresh);
+ dst_metric_set(dst, RTAX_SSTHRESH,
+ max(tp->snd_cwnd >> 1, tp->snd_ssthresh));
if (!dst_metric_locked(dst, RTAX_CWND))
- dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1;
+ dst_metric_set(dst, RTAX_CWND,
+ (dst_metric(dst, RTAX_CWND) +
+ tp->snd_cwnd) >> 1);
} else {
/* Else slow start did not finish, cwnd is non-sense,
ssthresh may be also invalid.
*/
if (!dst_metric_locked(dst, RTAX_CWND))
- dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1;
+ dst_metric_set(dst, RTAX_CWND,
+ (dst_metric(dst, RTAX_CWND) +
+ tp->snd_ssthresh) >> 1);
if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) &&
tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH))
- dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh;
+ dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_ssthresh);
}
if (!dst_metric_locked(dst, RTAX_REORDERING)) {
if (dst_metric(dst, RTAX_REORDERING) < tp->reordering &&
tp->reordering != sysctl_tcp_reordering)
- dst->metrics[RTAX_REORDERING-1] = tp->reordering;
+ dst_metric_set(dst, RTAX_REORDERING, tp->reordering);
}
}
}
@@ -912,25 +916,20 @@ static void tcp_init_metrics(struct sock *sk)
tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk));
}
tcp_set_rto(sk);
- if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp)
- goto reset;
-
-cwnd:
- tp->snd_cwnd = tcp_init_cwnd(tp, dst);
- tp->snd_cwnd_stamp = tcp_time_stamp;
- return;
-
+ if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp) {
reset:
- /* Play conservative. If timestamps are not
- * supported, TCP will fail to recalculate correct
- * rtt, if initial rto is too small. FORGET ALL AND RESET!
- */
- if (!tp->rx_opt.saw_tstamp && tp->srtt) {
- tp->srtt = 0;
- tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT;
- inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT;
+ /* Play conservative. If timestamps are not
+ * supported, TCP will fail to recalculate correct
+ * rtt, if initial rto is too small. FORGET ALL AND RESET!
+ */
+ if (!tp->rx_opt.saw_tstamp && tp->srtt) {
+ tp->srtt = 0;
+ tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT;
+ inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT;
+ }
}
- goto cwnd;
+ tp->snd_cwnd = tcp_init_cwnd(tp, dst);
+ tp->snd_cwnd_stamp = tcp_time_stamp;
}
static void tcp_update_reordering(struct sock *sk, const int metric,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index e13da6de1fc7..856f68466d49 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1210,12 +1210,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
};
#endif
-static struct timewait_sock_ops tcp_timewait_sock_ops = {
- .twsk_obj_size = sizeof(struct tcp_timewait_sock),
- .twsk_unique = tcp_twsk_unique,
- .twsk_destructor= tcp_twsk_destructor,
-};
-
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct tcp_extend_values tmp_ext;
@@ -1347,7 +1341,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
tcp_death_row.sysctl_tw_recycle &&
(dst = inet_csk_route_req(sk, req)) != NULL &&
(peer = rt_get_peer((struct rtable *)dst)) != NULL &&
- peer->v4daddr == saddr) {
+ peer->daddr.a4 == saddr) {
inet_peer_refcheck(peer);
if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
(s32)(peer->tcp_ts - req->ts_recent) >
@@ -1442,7 +1436,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
tcp_mtup_init(newsk);
tcp_sync_mss(newsk, dst_mtu(dst));
- newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
+ newtp->advmss = dst_metric_advmss(dst);
if (tcp_sk(sk)->rx_opt.user_mss &&
tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
@@ -1763,64 +1757,40 @@ do_time_wait:
goto discard_it;
}
-/* VJ's idea. Save last timestamp seen from this destination
- * and hold it at least for normal timewait interval to use for duplicate
- * segment detection in subsequent connections, before they enter synchronized
- * state.
- */
-
-int tcp_v4_remember_stamp(struct sock *sk)
+struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it)
{
+ struct rtable *rt = (struct rtable *) __sk_dst_get(sk);
struct inet_sock *inet = inet_sk(sk);
- struct tcp_sock *tp = tcp_sk(sk);
- struct rtable *rt = (struct rtable *)__sk_dst_get(sk);
- struct inet_peer *peer = NULL;
- int release_it = 0;
+ struct inet_peer *peer;
if (!rt || rt->rt_dst != inet->inet_daddr) {
- peer = inet_getpeer(inet->inet_daddr, 1);
- release_it = 1;
+ peer = inet_getpeer_v4(inet->inet_daddr, 1);
+ *release_it = true;
} else {
if (!rt->peer)
rt_bind_peer(rt, 1);
peer = rt->peer;
+ *release_it = false;
}
- if (peer) {
- if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 ||
- ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL &&
- peer->tcp_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) {
- peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp;
- peer->tcp_ts = tp->rx_opt.ts_recent;
- }
- if (release_it)
- inet_putpeer(peer);
- return 1;
- }
-
- return 0;
+ return peer;
}
-EXPORT_SYMBOL(tcp_v4_remember_stamp);
+EXPORT_SYMBOL(tcp_v4_get_peer);
-int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
+void *tcp_v4_tw_get_peer(struct sock *sk)
{
- struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1);
-
- if (peer) {
- const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-
- if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 ||
- ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL &&
- peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) {
- peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp;
- peer->tcp_ts = tcptw->tw_ts_recent;
- }
- inet_putpeer(peer);
- return 1;
- }
+ struct inet_timewait_sock *tw = inet_twsk(sk);
- return 0;
+ return inet_getpeer_v4(tw->tw_daddr, 1);
}
+EXPORT_SYMBOL(tcp_v4_tw_get_peer);
+
+static struct timewait_sock_ops tcp_timewait_sock_ops = {
+ .twsk_obj_size = sizeof(struct tcp_timewait_sock),
+ .twsk_unique = tcp_twsk_unique,
+ .twsk_destructor= tcp_twsk_destructor,
+ .twsk_getpeer = tcp_v4_tw_get_peer,
+};
const struct inet_connection_sock_af_ops ipv4_specific = {
.queue_xmit = ip_queue_xmit,
@@ -1828,7 +1798,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = {
.rebuild_header = inet_sk_rebuild_header,
.conn_request = tcp_v4_conn_request,
.syn_recv_sock = tcp_v4_syn_recv_sock,
- .remember_stamp = tcp_v4_remember_stamp,
+ .get_peer = tcp_v4_get_peer,
.net_header_len = sizeof(struct iphdr),
.setsockopt = ip_setsockopt,
.getsockopt = ip_getsockopt,
@@ -2030,7 +2000,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
get_req:
req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket];
}
- sk = sk_next(st->syn_wait_sk);
+ sk = sk_nulls_next(st->syn_wait_sk);
st->state = TCP_SEQ_STATE_LISTENING;
read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
} else {
@@ -2039,7 +2009,7 @@ get_req:
if (reqsk_queue_len(&icsk->icsk_accept_queue))
goto start_req;
read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
- sk = sk_next(sk);
+ sk = sk_nulls_next(sk);
}
get_sk:
sk_nulls_for_each_from(sk, node) {
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 43cf901d7659..80b1f80759ab 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -49,6 +49,56 @@ struct inet_timewait_death_row tcp_death_row = {
};
EXPORT_SYMBOL_GPL(tcp_death_row);
+/* VJ's idea. Save last timestamp seen from this destination
+ * and hold it at least for normal timewait interval to use for duplicate
+ * segment detection in subsequent connections, before they enter synchronized
+ * state.
+ */
+
+static int tcp_remember_stamp(struct sock *sk)
+{
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct inet_peer *peer;
+ bool release_it;
+
+ peer = icsk->icsk_af_ops->get_peer(sk, &release_it);
+ if (peer) {
+ if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 ||
+ ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL &&
+ peer->tcp_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) {
+ peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp;
+ peer->tcp_ts = tp->rx_opt.ts_recent;
+ }
+ if (release_it)
+ inet_putpeer(peer);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int tcp_tw_remember_stamp(struct inet_timewait_sock *tw)
+{
+ struct sock *sk = (struct sock *) tw;
+ struct inet_peer *peer;
+
+ peer = twsk_getpeer(sk);
+ if (peer) {
+ const struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
+
+ if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 ||
+ ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL &&
+ peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) {
+ peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp;
+ peer->tcp_ts = tcptw->tw_ts_recent;
+ }
+ inet_putpeer(peer);
+ return 1;
+ }
+ return 0;
+}
+
static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
{
if (seq == s_win)
@@ -149,14 +199,9 @@ kill_with_rst:
tcptw->tw_ts_recent = tmp_opt.rcv_tsval;
}
- /* I am shamed, but failed to make it more elegant.
- * Yes, it is direct reference to IP, which is impossible
- * to generalize to IPv6. Taking into account that IPv6
- * do not understand recycling in any case, it not
- * a big problem in practice. --ANK */
- if (tw->tw_family == AF_INET &&
- tcp_death_row.sysctl_tw_recycle && tcptw->tw_ts_recent_stamp &&
- tcp_v4_tw_remember_stamp(tw))
+ if (tcp_death_row.sysctl_tw_recycle &&
+ tcptw->tw_ts_recent_stamp &&
+ tcp_tw_remember_stamp(tw))
inet_twsk_schedule(tw, &tcp_death_row, tw->tw_timeout,
TCP_TIMEWAIT_LEN);
else
@@ -274,7 +319,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
int recycle_ok = 0;
if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
- recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
+ recycle_ok = tcp_remember_stamp(sk);
if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
tw = inet_twsk_alloc(sk, state);
@@ -347,7 +392,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
* socket up. We've got bigger problems than
* non-graceful socket closings.
*/
- LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
}
tcp_update_metrics(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 05b1ecf36763..dc7c096ddfef 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -55,7 +55,7 @@ int sysctl_tcp_workaround_signed_windows __read_mostly = 0;
int sysctl_tcp_tso_win_divisor __read_mostly = 3;
int sysctl_tcp_mtu_probing __read_mostly = 0;
-int sysctl_tcp_base_mss __read_mostly = 512;
+int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS;
/* By default, RFC2861 behavior. */
int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
@@ -119,9 +119,13 @@ static __u16 tcp_advertise_mss(struct sock *sk)
struct dst_entry *dst = __sk_dst_get(sk);
int mss = tp->advmss;
- if (dst && dst_metric(dst, RTAX_ADVMSS) < mss) {
- mss = dst_metric(dst, RTAX_ADVMSS);
- tp->advmss = mss;
+ if (dst) {
+ unsigned int metric = dst_metric_advmss(dst);
+
+ if (metric < mss) {
+ mss = metric;
+ tp->advmss = mss;
+ }
}
return (__u16)mss;
@@ -224,18 +228,22 @@ void tcp_select_initial_window(int __space, __u32 mss,
}
}
- /* Set initial window to value enough for senders, following RFC5681. */
+ /* Set initial window to a value enough for senders starting with
+ * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place
+ * a limit on the initial window when mss is larger than 1460.
+ */
if (mss > (1 << *rcv_wscale)) {
- int init_cwnd = rfc3390_bytes_to_packets(mss);
-
+ int init_cwnd = TCP_DEFAULT_INIT_RCVWND;
+ if (mss > 1460)
+ init_cwnd =
+ max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
/* when initializing use the value from init_rcv_wnd
* rather than the default from above
*/
- if (init_rcv_wnd &&
- (*rcv_wnd > init_rcv_wnd * mss))
- *rcv_wnd = init_rcv_wnd * mss;
- else if (*rcv_wnd > init_cwnd * mss)
- *rcv_wnd = init_cwnd * mss;
+ if (init_rcv_wnd)
+ *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+ else
+ *rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
}
/* Set the clamp no higher than max representable value */
@@ -386,27 +394,30 @@ struct tcp_out_options {
*/
static u8 tcp_cookie_size_check(u8 desired)
{
- if (desired > 0) {
+ int cookie_size;
+
+ if (desired > 0)
/* previously specified */
return desired;
- }
- if (sysctl_tcp_cookie_size <= 0) {
+
+ cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
+ if (cookie_size <= 0)
/* no default specified */
return 0;
- }
- if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) {
+
+ if (cookie_size <= TCP_COOKIE_MIN)
/* value too small, specify minimum */
return TCP_COOKIE_MIN;
- }
- if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) {
+
+ if (cookie_size >= TCP_COOKIE_MAX)
/* value too large, specify maximum */
return TCP_COOKIE_MAX;
- }
- if (0x1 & sysctl_tcp_cookie_size) {
+
+ if (cookie_size & 1)
/* 8-bit multiple, illegal, fix it */
- return (u8)(sysctl_tcp_cookie_size + 0x1);
- }
- return (u8)sysctl_tcp_cookie_size;
+ cookie_size++;
+
+ return (u8)cookie_size;
}
/* Write previously computed TCP options to the packet.
@@ -822,8 +833,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
&md5);
tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
- if (tcp_packets_in_flight(tp) == 0)
+ if (tcp_packets_in_flight(tp) == 0) {
tcp_ca_event(sk, CA_EVENT_TX_START);
+ skb->ooo_okay = 1;
+ } else
+ skb->ooo_okay = 0;
skb_push(skb, tcp_header_size);
skb_reset_transport_header(skb);
@@ -1513,6 +1527,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
struct tcp_sock *tp = tcp_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
u32 send_win, cong_win, limit, in_flight;
+ int win_divisor;
if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
goto send_now;
@@ -1544,13 +1559,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len))
goto send_now;
- if (sysctl_tcp_tso_win_divisor) {
+ win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor);
+ if (win_divisor) {
u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
/* If at least some fraction of a window is available,
* just use it.
*/
- chunk /= sysctl_tcp_tso_win_divisor;
+ chunk /= win_divisor;
if (limit >= chunk)
goto send_now;
} else {
@@ -2415,7 +2431,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
skb_dst_set(skb, dst_clone(dst));
- mss = dst_metric(dst, RTAX_ADVMSS);
+ mss = dst_metric_advmss(dst);
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
mss = tp->rx_opt.user_mss;
@@ -2549,7 +2565,7 @@ static void tcp_connect_init(struct sock *sk)
if (!tp->window_clamp)
tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
- tp->advmss = dst_metric(dst, RTAX_ADVMSS);
+ tp->advmss = dst_metric_advmss(dst);
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss)
tp->advmss = tp->rx_opt.user_mss;
@@ -2592,6 +2608,7 @@ int tcp_connect(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *buff;
+ int err;
tcp_connect_init(sk);
@@ -2614,7 +2631,9 @@ int tcp_connect(struct sock *sk)
sk->sk_wmem_queued += buff->truesize;
sk_mem_charge(sk, buff->truesize);
tp->packets_out += tcp_skb_pcount(buff);
- tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);
+ err = tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);
+ if (err == -ECONNREFUSED)
+ return err;
/* We change tp->snd_nxt after the tcp_transmit_skb() call
* in order to make this packet get counted in tcpOutSegs.
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 6211e2114173..85ee7eb7e38e 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -154,7 +154,7 @@ static int tcpprobe_sprint(char *tbuf, int n)
struct timespec tv
= ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
- return snprintf(tbuf, n,
+ return scnprintf(tbuf, n,
"%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
@@ -174,7 +174,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf,
return -EINVAL;
while (cnt < len) {
- char tbuf[128];
+ char tbuf[164];
int width;
/* Wait for data in buffer */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5e0a3a582a59..8157b17959ee 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -430,7 +430,7 @@ begin:
if (result) {
exact_match:
- if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+ if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
result = NULL;
else if (unlikely(compute_score2(result, net, saddr, sport,
daddr, hnum, dif) < badness)) {
@@ -500,7 +500,7 @@ begin:
goto begin;
if (result) {
- if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+ if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
result = NULL;
else if (unlikely(compute_score(result, net, saddr, hnum, sport,
daddr, dport, dif) < badness)) {
@@ -890,15 +890,13 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (rt == NULL) {
struct flowi fl = { .oif = ipc.oif,
.mark = sk->sk_mark,
- .nl_u = { .ip4_u =
- { .daddr = faddr,
- .saddr = saddr,
- .tos = tos } },
+ .fl4_dst = faddr,
+ .fl4_src = saddr,
+ .fl4_tos = tos,
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = { .ports =
- { .sport = inet->inet_sport,
- .dport = dport } } };
+ .fl_ip_sport = inet->inet_sport,
+ .fl_ip_dport = dport };
struct net *net = sock_net(sk);
security_sk_classify_flow(sk, &fl);
@@ -1899,6 +1897,7 @@ struct proto udp_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
+ .clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udp_prot);
@@ -2228,7 +2227,7 @@ struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features)
/* Do software UFO. Complete and fill in the UDP checksum as HW cannot
* do checksum of UDP packets sent as multiple IP fragments.
*/
- offset = skb->csum_start - skb_headroom(skb);
+ offset = skb_checksum_start_offset(skb);
csum = skb_checksum(skb, offset, skb->len - offset, 0);
offset += skb->csum_offset;
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index ab76aa928fa9..aee9963f7f5a 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -57,6 +57,7 @@ struct proto udplite_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
+ .clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udplite_prot);
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 6f368413eb0e..534972e114ac 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -56,7 +56,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
ip_select_ident(top_iph, dst->child, NULL);
- top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
+ top_iph->ttl = ip4_dst_hoplimit(dst->child);
top_iph->saddr = x->props.saddr.a4;
top_iph->daddr = x->id.daddr.a4;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 4464f3bff6a7..b057d40addec 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -11,6 +11,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/inetdevice.h>
+#include <linux/if_tunnel.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -22,12 +23,8 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
xfrm_address_t *daddr)
{
struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .tos = tos,
- .daddr = daddr->a4,
- },
- },
+ .fl4_dst = daddr->a4,
+ .fl4_tos = tos,
};
struct dst_entry *dst;
struct rtable *rt;
@@ -80,10 +77,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
xdst->u.dst.dev = dev;
dev_hold(dev);
- xdst->u.rt.idev = in_dev_get(dev);
- if (!xdst->u.rt.idev)
- return -ENODEV;
-
xdst->u.rt.peer = rt->peer;
if (rt->peer)
atomic_inc(&rt->peer->refcnt);
@@ -158,6 +151,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;
+
+ case IPPROTO_GRE:
+ if (pskb_may_pull(skb, xprth + 12 - skb->data)) {
+ __be16 *greflags = (__be16 *)xprth;
+ __be32 *gre_hdr = (__be32 *)xprth;
+
+ if (greflags[0] & GRE_KEY) {
+ if (greflags[0] & GRE_CSUM)
+ gre_hdr++;
+ fl->fl_gre_key = gre_hdr[1];
+ }
+ }
+ break;
+
default:
fl->fl_ipsec_spi = 0;
break;
@@ -189,8 +196,6 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
{
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
- if (likely(xdst->u.rt.idev))
- in_dev_put(xdst->u.rt.idev);
if (likely(xdst->u.rt.peer))
inet_putpeer(xdst->u.rt.peer);
xfrm_dst_destroy(xdst);
@@ -199,27 +204,9 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
int unregister)
{
- struct xfrm_dst *xdst;
-
if (!unregister)
return;
- xdst = (struct xfrm_dst *)dst;
- if (xdst->u.rt.idev->dev == dev) {
- struct in_device *loopback_idev =
- in_dev_get(dev_net(dev)->loopback_dev);
- BUG_ON(!loopback_idev);
-
- do {
- in_dev_put(xdst->u.rt.idev);
- xdst->u.rt.idev = loopback_idev;
- in_dev_hold(loopback_idev);
- xdst = (struct xfrm_dst *)xdst->u.dst.child;
- } while (xdst->u.dst.xfrm);
-
- __in_dev_put(loopback_idev);
- }
-
xfrm_dst_ifdown(dst, dev);
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 23cc8e1ce8d4..5b189c97c2fc 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2669,8 +2669,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
ASSERT_RTNL();
- rt6_ifdown(net, dev);
- neigh_ifdown(&nd_tbl, dev);
+ /* Flush routes if device is being removed or it is not loopback */
+ if (how || !(dev->flags & IFF_LOOPBACK))
+ rt6_ifdown(net, dev);
idev = __in6_dev_get(dev);
if (idev == NULL)
@@ -3836,6 +3837,15 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
}
+static inline size_t inet6_ifla6_size(void)
+{
+ return nla_total_size(4) /* IFLA_INET6_FLAGS */
+ + nla_total_size(sizeof(struct ifla_cacheinfo))
+ + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
+ + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
+ + nla_total_size(ICMP6_MIB_MAX * 8); /* IFLA_INET6_ICMP6STATS */
+}
+
static inline size_t inet6_if_nlmsg_size(void)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -3843,13 +3853,7 @@ static inline size_t inet6_if_nlmsg_size(void)
+ nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
- + nla_total_size( /* IFLA_PROTINFO */
- nla_total_size(4) /* IFLA_INET6_FLAGS */
- + nla_total_size(sizeof(struct ifla_cacheinfo))
- + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
- + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
- + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
- );
+ + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */
}
static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
@@ -3896,15 +3900,70 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
}
}
+static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
+{
+ struct nlattr *nla;
+ struct ifla_cacheinfo ci;
+
+ NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
+
+ ci.max_reasm_len = IPV6_MAXPLEN;
+ ci.tstamp = cstamp_delta(idev->tstamp);
+ ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
+ ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
+ NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
+
+ nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
+ if (nla == NULL)
+ goto nla_put_failure;
+ ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
+
+ /* XXX - MC not implemented */
+
+ nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
+ if (nla == NULL)
+ goto nla_put_failure;
+ snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
+
+ nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
+ if (nla == NULL)
+ goto nla_put_failure;
+ snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static size_t inet6_get_link_af_size(const struct net_device *dev)
+{
+ if (!__in6_dev_get(dev))
+ return 0;
+
+ return inet6_ifla6_size();
+}
+
+static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct inet6_dev *idev = __in6_dev_get(dev);
+
+ if (!idev)
+ return -ENODATA;
+
+ if (inet6_fill_ifla6_attrs(skb, idev) < 0)
+ return -EMSGSIZE;
+
+ return 0;
+}
+
static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
u32 pid, u32 seq, int event, unsigned int flags)
{
struct net_device *dev = idev->dev;
- struct nlattr *nla;
struct ifinfomsg *hdr;
struct nlmsghdr *nlh;
void *protoinfo;
- struct ifla_cacheinfo ci;
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
if (nlh == NULL)
@@ -3931,30 +3990,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
if (protoinfo == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
-
- ci.max_reasm_len = IPV6_MAXPLEN;
- ci.tstamp = cstamp_delta(idev->tstamp);
- ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
- ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
- NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
-
- nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
- if (nla == NULL)
- goto nla_put_failure;
- ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
-
- /* XXX - MC not implemented */
-
- nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
- if (nla == NULL)
+ if (inet6_fill_ifla6_attrs(skb, idev) < 0)
goto nla_put_failure;
- snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
-
- nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
- if (nla == NULL)
- goto nla_put_failure;
- snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
nla_nest_end(skb, protoinfo);
return nlmsg_end(skb, nlh);
@@ -4021,11 +4058,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
return;
errout:
if (err < 0)
- rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
}
static inline size_t inet6_prefix_nlmsg_size(void)
@@ -4625,6 +4662,12 @@ int unregister_inet6addr_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_inet6addr_notifier);
+static struct rtnl_af_ops inet6_ops = {
+ .family = AF_INET6,
+ .fill_link_af = inet6_fill_link_af,
+ .get_link_af_size = inet6_get_link_af_size,
+};
+
/*
* Init / cleanup code
*/
@@ -4676,6 +4719,10 @@ int __init addrconf_init(void)
addrconf_verify(0);
+ err = rtnl_af_register(&inet6_ops);
+ if (err < 0)
+ goto errout_af;
+
err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
if (err < 0)
goto errout;
@@ -4691,6 +4738,8 @@ int __init addrconf_init(void)
return 0;
errout:
+ rtnl_af_unregister(&inet6_ops);
+errout_af:
unregister_netdevice_notifier(&ipv6_dev_notf);
errlo:
unregister_pernet_subsys(&addrconf_ops);
@@ -4711,6 +4760,8 @@ void addrconf_cleanup(void)
rtnl_lock();
+ __rtnl_af_unregister(&inet6_ops);
+
/* clean dev list */
for_each_netdev(&init_net, dev) {
if (__in6_dev_get(dev) == NULL)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 54e8e42f7a88..059a3de647db 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -810,7 +810,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
}
rcu_read_unlock();
- if (unlikely(IS_ERR(segs)))
+ if (IS_ERR(segs))
goto out;
for (skb = segs; skb; skb = skb->next) {
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index ee9b93bdd6a2..1b5c9825743b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -49,6 +49,8 @@ struct esp_skb_cb {
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
+
/*
* Allocate an AEAD request structure with extra space for SG and IV.
*
@@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
int blksize;
int clen;
int alen;
+ int plen;
+ int tfclen;
int nfrags;
u8 *iv;
u8 *tail;
@@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* skb is pure payload to encrypt */
err = -ENOMEM;
- /* Round to block size */
- clen = skb->len;
-
aead = esp->aead;
alen = crypto_aead_authsize(aead);
+ tfclen = 0;
+ if (x->tfcpad) {
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+ padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ tfclen = padto - skb->len;
+ }
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
- clen = ALIGN(clen + 2, blksize);
+ clen = ALIGN(skb->len + 2 + tfclen, blksize);
if (esp->padlen)
clen = ALIGN(clen, esp->padlen);
+ plen = clen - skb->len - tfclen;
- if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+ err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+ if (err < 0)
goto error;
nfrags = err;
@@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
/* Fill padding... */
tail = skb_tail_pointer(trailer);
+ if (tfclen) {
+ memset(tail, 0, tfclen);
+ tail += tfclen;
+ }
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i = 0; i < plen - 2; i++)
tail[i] = i + 1;
} while (0);
- tail[clen-skb->len - 2] = (clen - skb->len) - 2;
- tail[clen - skb->len - 1] = *skb_mac_header(skb);
+ tail[plen - 2] = plen - 2;
+ tail[plen - 1] = *skb_mac_header(skb);
pskb_put(skb, trailer, clen - skb->len + alen);
skb_push(skb, -skb_network_offset(skb));
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 8a1628023bd1..e46305d1815a 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -54,24 +54,54 @@ int inet6_csk_bind_conflict(const struct sock *sk,
EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
+struct dst_entry *inet6_csk_route_req(struct sock *sk,
+ const struct request_sock *req)
+{
+ struct inet6_request_sock *treq = inet6_rsk(req);
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct in6_addr *final_p, final;
+ struct dst_entry *dst;
+ struct flowi fl;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
+ final_p = fl6_update_dst(&fl, np->opt, &final);
+ ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
+ fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
+ fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+ fl.fl_ip_sport = inet_rsk(req)->loc_port;
+ security_req_classify_flow(req, &fl);
+
+ if (ip6_dst_lookup(sk, &dst, &fl))
+ return NULL;
+
+ if (final_p)
+ ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+ if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
+ return NULL;
+
+ return dst;
+}
+
/*
* request_sock (formerly open request) hash tables.
*/
static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
const u32 rnd, const u16 synq_hsize)
{
- u32 a = (__force u32)raddr->s6_addr32[0];
- u32 b = (__force u32)raddr->s6_addr32[1];
- u32 c = (__force u32)raddr->s6_addr32[2];
-
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
- c += rnd;
- __jhash_mix(a, b, c);
-
- a += (__force u32)raddr->s6_addr32[3];
- b += (__force u32)rport;
- __jhash_mix(a, b, c);
+ u32 c;
+
+ c = jhash_3words((__force u32)raddr->s6_addr32[0],
+ (__force u32)raddr->s6_addr32[1],
+ (__force u32)raddr->s6_addr32[2],
+ rnd);
+
+ c = jhash_2words((__force u32)raddr->s6_addr32[3],
+ (__force u32)rport,
+ c);
return c & (synq_hsize - 1);
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 99157b4cd56e..94b5bf132b2e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -56,7 +56,7 @@
#include <net/checksum.h>
#include <linux/mroute6.h>
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
int __ip6_local_out(struct sk_buff *skb)
{
@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb)
return -EINVAL;
}
-static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
-{
- struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
-
- return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
- skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
-}
-
static int ip6_finish_output(struct sk_buff *skb)
{
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
@@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
return offset;
}
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
{
struct sk_buff *frag;
struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2a59610c2a58..4f4483e697bd 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -58,8 +58,6 @@ MODULE_AUTHOR("Ville Nuorvala");
MODULE_DESCRIPTION("IPv6 tunneling device");
MODULE_LICENSE("GPL");
-#define IPV6_TLV_TEL_DST_SIZE 8
-
#ifdef IP6_TNL_DEBUG
#define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__)
#else
@@ -1175,6 +1173,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
sizeof (struct ipv6hdr);
dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+ dev->mtu-=8;
if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU;
@@ -1363,12 +1363,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
static void ip6_tnl_dev_setup(struct net_device *dev)
{
+ struct ip6_tnl *t;
+
dev->netdev_ops = &ip6_tnl_netdev_ops;
dev->destructor = ip6_dev_free;
dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+ t = netdev_priv(dev);
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+ dev->mtu-=8;
dev->flags |= IFF_NOARP;
dev->addr_len = sizeof(struct in6_addr);
dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 6f32ffce7022..9fab274019c0 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1843,9 +1843,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
fl = (struct flowi) {
.oif = vif->link,
- .nl_u = { .ip6_u =
- { .daddr = ipv6h->daddr, }
- }
+ .fl6_dst = ipv6h->daddr,
};
dst = ip6_route_output(net, NULL, &fl);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index d1444b95ad7e..49f986d626a0 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -82,7 +82,7 @@ static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
/* Big mc list lock for all the sockets */
-static DEFINE_RWLOCK(ipv6_sk_mc_lock);
+static DEFINE_SPINLOCK(ipv6_sk_mc_lock);
static void igmp6_join_group(struct ifmcaddr6 *ma);
static void igmp6_leave_group(struct ifmcaddr6 *ma);
@@ -123,6 +123,11 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
* socket join on multicast group
*/
+#define for_each_pmc_rcu(np, pmc) \
+ for (pmc = rcu_dereference(np->ipv6_mc_list); \
+ pmc != NULL; \
+ pmc = rcu_dereference(pmc->next))
+
int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct net_device *dev = NULL;
@@ -134,15 +139,15 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
- read_lock_bh(&ipv6_sk_mc_lock);
- for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(np, mc_lst) {
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
ipv6_addr_equal(&mc_lst->addr, addr)) {
- read_unlock_bh(&ipv6_sk_mc_lock);
+ rcu_read_unlock();
return -EADDRINUSE;
}
}
- read_unlock_bh(&ipv6_sk_mc_lock);
+ rcu_read_unlock();
mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
@@ -186,33 +191,41 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
return err;
}
- write_lock_bh(&ipv6_sk_mc_lock);
+ spin_lock(&ipv6_sk_mc_lock);
mc_lst->next = np->ipv6_mc_list;
- np->ipv6_mc_list = mc_lst;
- write_unlock_bh(&ipv6_sk_mc_lock);
+ rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
+ spin_unlock(&ipv6_sk_mc_lock);
rcu_read_unlock();
return 0;
}
+static void ipv6_mc_socklist_reclaim(struct rcu_head *head)
+{
+ kfree(container_of(head, struct ipv6_mc_socklist, rcu));
+}
/*
* socket leave on multicast group
*/
int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
- struct ipv6_mc_socklist *mc_lst, **lnk;
+ struct ipv6_mc_socklist *mc_lst;
+ struct ipv6_mc_socklist __rcu **lnk;
struct net *net = sock_net(sk);
- write_lock_bh(&ipv6_sk_mc_lock);
- for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) {
+ spin_lock(&ipv6_sk_mc_lock);
+ for (lnk = &np->ipv6_mc_list;
+ (mc_lst = rcu_dereference_protected(*lnk,
+ lockdep_is_held(&ipv6_sk_mc_lock))) !=NULL ;
+ lnk = &mc_lst->next) {
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
ipv6_addr_equal(&mc_lst->addr, addr)) {
struct net_device *dev;
*lnk = mc_lst->next;
- write_unlock_bh(&ipv6_sk_mc_lock);
+ spin_unlock(&ipv6_sk_mc_lock);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
@@ -225,11 +238,12 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
} else
(void) ip6_mc_leave_src(sk, mc_lst, NULL);
rcu_read_unlock();
- sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
+ atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
+ call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim);
return 0;
}
}
- write_unlock_bh(&ipv6_sk_mc_lock);
+ spin_unlock(&ipv6_sk_mc_lock);
return -EADDRNOTAVAIL;
}
@@ -257,7 +271,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
return NULL;
idev = __in6_dev_get(dev);
if (!idev)
- return NULL;;
+ return NULL;
read_lock_bh(&idev->lock);
if (idev->dead) {
read_unlock_bh(&idev->lock);
@@ -272,12 +286,13 @@ void ipv6_sock_mc_close(struct sock *sk)
struct ipv6_mc_socklist *mc_lst;
struct net *net = sock_net(sk);
- write_lock_bh(&ipv6_sk_mc_lock);
- while ((mc_lst = np->ipv6_mc_list) != NULL) {
+ spin_lock(&ipv6_sk_mc_lock);
+ while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list,
+ lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {
struct net_device *dev;
np->ipv6_mc_list = mc_lst->next;
- write_unlock_bh(&ipv6_sk_mc_lock);
+ spin_unlock(&ipv6_sk_mc_lock);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
@@ -290,11 +305,13 @@ void ipv6_sock_mc_close(struct sock *sk)
} else
(void) ip6_mc_leave_src(sk, mc_lst, NULL);
rcu_read_unlock();
- sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
- write_lock_bh(&ipv6_sk_mc_lock);
+ atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
+ call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim);
+
+ spin_lock(&ipv6_sk_mc_lock);
}
- write_unlock_bh(&ipv6_sk_mc_lock);
+ spin_unlock(&ipv6_sk_mc_lock);
}
int ip6_mc_source(int add, int omode, struct sock *sk,
@@ -328,8 +345,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
err = -EADDRNOTAVAIL;
- read_lock(&ipv6_sk_mc_lock);
- for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rcu(inet6, pmc) {
if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
continue;
if (ipv6_addr_equal(&pmc->addr, group))
@@ -428,7 +444,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
done:
if (pmclocked)
write_unlock(&pmc->sflock);
- read_unlock(&ipv6_sk_mc_lock);
read_unlock_bh(&idev->lock);
rcu_read_unlock();
if (leavegroup)
@@ -466,14 +481,13 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
dev = idev->dev;
err = 0;
- read_lock(&ipv6_sk_mc_lock);
if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
leavegroup = 1;
goto done;
}
- for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rcu(inet6, pmc) {
if (pmc->ifindex != gsf->gf_interface)
continue;
if (ipv6_addr_equal(&pmc->addr, group))
@@ -521,7 +535,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
write_unlock(&pmc->sflock);
err = 0;
done:
- read_unlock(&ipv6_sk_mc_lock);
read_unlock_bh(&idev->lock);
rcu_read_unlock();
if (leavegroup)
@@ -562,7 +575,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
* so reading the list is safe.
*/
- for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
+ for_each_pmc_rcu(inet6, pmc) {
if (pmc->ifindex != gsf->gf_interface)
continue;
if (ipv6_addr_equal(group, &pmc->addr))
@@ -612,13 +625,13 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
struct ip6_sf_socklist *psl;
int rv = 1;
- read_lock(&ipv6_sk_mc_lock);
- for (mc = np->ipv6_mc_list; mc; mc = mc->next) {
+ rcu_read_lock();
+ for_each_pmc_rcu(np, mc) {
if (ipv6_addr_equal(&mc->addr, mc_addr))
break;
}
if (!mc) {
- read_unlock(&ipv6_sk_mc_lock);
+ rcu_read_unlock();
return 1;
}
read_lock(&mc->sflock);
@@ -638,7 +651,7 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
rv = 0;
}
read_unlock(&mc->sflock);
- read_unlock(&ipv6_sk_mc_lock);
+ rcu_read_unlock();
return rv;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 998d6d27e7cf..2342545a5ee9 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -141,18 +141,18 @@ struct neigh_table nd_tbl = {
.proxy_redo = pndisc_redo,
.id = "ndisc_cache",
.parms = {
- .tbl = &nd_tbl,
- .base_reachable_time = 30 * HZ,
- .retrans_time = 1 * HZ,
- .gc_staletime = 60 * HZ,
- .reachable_time = 30 * HZ,
- .delay_probe_time = 5 * HZ,
- .queue_len = 3,
- .ucast_probes = 3,
- .mcast_probes = 3,
- .anycast_delay = 1 * HZ,
- .proxy_delay = (8 * HZ) / 10,
- .proxy_qlen = 64,
+ .tbl = &nd_tbl,
+ .base_reachable_time = ND_REACHABLE_TIME,
+ .retrans_time = ND_RETRANS_TIMER,
+ .gc_staletime = 60 * HZ,
+ .reachable_time = ND_REACHABLE_TIME,
+ .delay_probe_time = 5 * HZ,
+ .queue_len = 3,
+ .ucast_probes = 3,
+ .mcast_probes = 3,
+ .anycast_delay = 1 * HZ,
+ .proxy_delay = (8 * HZ) / 10,
+ .proxy_qlen = 64,
},
.gc_interval = 30 * HZ,
.gc_thresh1 = 128,
@@ -1259,7 +1259,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (ra_msg->icmph.icmp6_hop_limit) {
in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
if (rt)
- rt->dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
+ dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
+ ra_msg->icmph.icmp6_hop_limit);
}
skip_defrtr:
@@ -1377,7 +1378,7 @@ skip_linkparms:
in6_dev->cnf.mtu6 = mtu;
if (rt)
- rt->dst.metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(&rt->dst, RTAX_MTU, mtu);
rt6_mtu_change(skb->dev, mtu);
}
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 7155b2451d7c..35915e8617f0 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -18,10 +18,8 @@ int ip6_route_me_harder(struct sk_buff *skb)
struct flowi fl = {
.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
.mark = skb->mark,
- .nl_u =
- { .ip6_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr, } },
+ .fl6_dst = iph->daddr,
+ .fl6_src = iph->saddr,
};
dst = ip6_route_output(net, skb->sk, &fl);
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 0a432c9b0795..abfee91ce816 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -11,13 +11,13 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
# objects for l3 independent conntrack
-nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
+nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
# l3 independent conntrack
obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
# defrag
-nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
+nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
# matches
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 2933396e0281..bf998feac14e 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -124,7 +124,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
skb_reset_network_header(nskb);
ip6h = ipv6_hdr(nskb);
ip6h->version = 6;
- ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
+ ip6h->hop_limit = ip6_dst_hoplimit(dst);
ip6h->nexthdr = IPPROTO_TCP;
ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 0f2766453759..07beeb06f752 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -104,26 +104,22 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr,
const struct in6_addr *daddr, u32 rnd)
{
- u32 a, b, c;
-
- a = (__force u32)saddr->s6_addr32[0];
- b = (__force u32)saddr->s6_addr32[1];
- c = (__force u32)saddr->s6_addr32[2];
-
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
- c += rnd;
- __jhash_mix(a, b, c);
-
- a += (__force u32)saddr->s6_addr32[3];
- b += (__force u32)daddr->s6_addr32[0];
- c += (__force u32)daddr->s6_addr32[1];
- __jhash_mix(a, b, c);
-
- a += (__force u32)daddr->s6_addr32[2];
- b += (__force u32)daddr->s6_addr32[3];
- c += (__force u32)id;
- __jhash_mix(a, b, c);
+ u32 c;
+
+ c = jhash_3words((__force u32)saddr->s6_addr32[0],
+ (__force u32)saddr->s6_addr32[1],
+ (__force u32)saddr->s6_addr32[2],
+ rnd);
+
+ c = jhash_3words((__force u32)saddr->s6_addr32[3],
+ (__force u32)daddr->s6_addr32[0],
+ (__force u32)daddr->s6_addr32[1],
+ c);
+
+ c = jhash_3words((__force u32)daddr->s6_addr32[2],
+ (__force u32)daddr->s6_addr32[3],
+ (__force u32)id,
+ c);
return c & (INETFRAGS_HASHSZ - 1);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 96455ffb76fb..373bd0416f69 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -76,6 +76,8 @@
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
+static unsigned int ip6_default_advmss(const struct dst_entry *dst);
+static unsigned int ip6_default_mtu(const struct dst_entry *dst);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_dst_destroy(struct dst_entry *);
static void ip6_dst_ifdown(struct dst_entry *,
@@ -103,6 +105,8 @@ static struct dst_ops ip6_dst_ops_template = {
.gc = ip6_dst_gc,
.gc_thresh = 1024,
.check = ip6_dst_check,
+ .default_advmss = ip6_default_advmss,
+ .default_mtu = ip6_default_mtu,
.destroy = ip6_dst_destroy,
.ifdown = ip6_dst_ifdown,
.negative_advice = ip6_negative_advice,
@@ -129,7 +133,6 @@ static struct rt6_info ip6_null_entry_template = {
.__use = 1,
.obsolete = -1,
.error = -ENETUNREACH,
- .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_discard,
.output = ip6_pkt_discard_out,
},
@@ -150,7 +153,6 @@ static struct rt6_info ip6_prohibit_entry_template = {
.__use = 1,
.obsolete = -1,
.error = -EACCES,
- .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_prohibit,
.output = ip6_pkt_prohibit_out,
},
@@ -166,7 +168,6 @@ static struct rt6_info ip6_blk_hole_entry_template = {
.__use = 1,
.obsolete = -1,
.error = -EINVAL,
- .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = dst_discard,
.output = dst_discard,
},
@@ -188,11 +189,29 @@ static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
struct inet6_dev *idev = rt->rt6i_idev;
+ struct inet_peer *peer = rt->rt6i_peer;
if (idev != NULL) {
rt->rt6i_idev = NULL;
in6_dev_put(idev);
}
+ if (peer) {
+ BUG_ON(!(rt->rt6i_flags & RTF_CACHE));
+ rt->rt6i_peer = NULL;
+ inet_putpeer(peer);
+ }
+}
+
+void rt6_bind_peer(struct rt6_info *rt, int create)
+{
+ struct inet_peer *peer;
+
+ if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE)))
+ return;
+
+ peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create);
+ if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL)
+ inet_putpeer(peer);
}
static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -558,11 +577,7 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
{
struct flowi fl = {
.oif = oif,
- .nl_u = {
- .ip6_u = {
- .daddr = *daddr,
- },
- },
+ .fl6_dst = *daddr,
};
struct dst_entry *dst;
int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
@@ -778,13 +793,9 @@ void ip6_route_input(struct sk_buff *skb)
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi fl = {
.iif = skb->dev->ifindex,
- .nl_u = {
- .ip6_u = {
- .daddr = iph->daddr,
- .saddr = iph->saddr,
- .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
- },
- },
+ .fl6_dst = iph->daddr,
+ .fl6_src = iph->saddr,
+ .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
.mark = skb->mark,
.proto = iph->nexthdr,
};
@@ -834,7 +845,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
new->input = dst_discard;
new->output = dst_discard;
- memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32));
+ dst_copy_metrics(new, &ort->dst);
new->dev = ort->dst.dev;
if (new->dev)
dev_hold(new->dev);
@@ -918,18 +929,22 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
rt6->rt6i_flags |= RTF_MODIFIED;
if (mtu < IPV6_MIN_MTU) {
+ u32 features = dst_metric(dst, RTAX_FEATURES);
mtu = IPV6_MIN_MTU;
- dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
+ features |= RTAX_FEATURE_ALLFRAG;
+ dst_metric_set(dst, RTAX_FEATURES, features);
}
- dst->metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(dst, RTAX_MTU, mtu);
call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
}
-static int ipv6_get_mtu(struct net_device *dev);
-
-static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu)
+static unsigned int ip6_default_advmss(const struct dst_entry *dst)
{
+ struct net_device *dev = dst->dev;
+ unsigned int mtu = dst_mtu(dst);
+ struct net *net = dev_net(dev);
+
mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
@@ -946,6 +961,20 @@ static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu)
return mtu;
}
+static unsigned int ip6_default_mtu(const struct dst_entry *dst)
+{
+ unsigned int mtu = IPV6_MIN_MTU;
+ struct inet6_dev *idev;
+
+ rcu_read_lock();
+ idev = __in6_dev_get(dst->dev);
+ if (idev)
+ mtu = idev->cnf.mtu6;
+ rcu_read_unlock();
+
+ return mtu;
+}
+
static struct dst_entry *icmp6_dst_gc_list;
static DEFINE_SPINLOCK(icmp6_dst_lock);
@@ -979,9 +1008,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
rt->rt6i_idev = idev;
rt->rt6i_nexthop = neigh;
atomic_set(&rt->dst.__refcnt, 1);
- rt->dst.metrics[RTAX_HOPLIMIT-1] = 255;
- rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
- rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst));
+ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
rt->dst.output = ip6_output;
#if 0 /* there's no chance to use these for ndisc */
@@ -1080,23 +1107,10 @@ out:
Remove it only when all the things will work!
*/
-static int ipv6_get_mtu(struct net_device *dev)
-{
- int mtu = IPV6_MIN_MTU;
- struct inet6_dev *idev;
-
- rcu_read_lock();
- idev = __in6_dev_get(dev);
- if (idev)
- mtu = idev->cnf.mtu6;
- rcu_read_unlock();
- return mtu;
-}
-
int ip6_dst_hoplimit(struct dst_entry *dst)
{
- int hoplimit = dst_metric(dst, RTAX_HOPLIMIT);
- if (hoplimit < 0) {
+ int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
+ if (hoplimit == 0) {
struct net_device *dev = dst->dev;
struct inet6_dev *idev;
@@ -1110,6 +1124,7 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
}
return hoplimit;
}
+EXPORT_SYMBOL(ip6_dst_hoplimit);
/*
*
@@ -1295,17 +1310,11 @@ install_route:
goto out;
}
- rt->dst.metrics[type - 1] = nla_get_u32(nla);
+ dst_metric_set(&rt->dst, type, nla_get_u32(nla));
}
}
}
- if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0)
- rt->dst.metrics[RTAX_HOPLIMIT-1] = -1;
- if (!dst_mtu(&rt->dst))
- rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev);
- if (!dst_metric(&rt->dst, RTAX_ADVMSS))
- rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst));
rt->dst.dev = dev;
rt->rt6i_idev = idev;
rt->rt6i_table = table;
@@ -1463,12 +1472,8 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
struct ip6rd_flowi rdfl = {
.fl = {
.oif = dev->ifindex,
- .nl_u = {
- .ip6_u = {
- .daddr = *dest,
- .saddr = *src,
- },
- },
+ .fl6_dst = *dest,
+ .fl6_src = *src,
},
};
@@ -1534,10 +1539,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key);
nrt->rt6i_nexthop = neigh_clone(neigh);
- /* Reset pmtu, it may be better */
- nrt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
- nrt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dev_net(neigh->dev),
- dst_mtu(&nrt->dst));
if (ip6_ins_rt(nrt))
goto out;
@@ -1565,11 +1566,16 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
{
struct rt6_info *rt, *nrt;
int allfrag = 0;
-
+again:
rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
if (rt == NULL)
return;
+ if (rt6_check_expired(rt)) {
+ ip6_del_rt(rt);
+ goto again;
+ }
+
if (pmtu >= dst_mtu(&rt->dst))
goto out;
@@ -1596,9 +1602,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
would return automatically.
*/
if (rt->rt6i_flags & RTF_CACHE) {
- rt->dst.metrics[RTAX_MTU-1] = pmtu;
- if (allfrag)
- rt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
+ dst_metric_set(&rt->dst, RTAX_MTU, pmtu);
+ if (allfrag) {
+ u32 features = dst_metric(&rt->dst, RTAX_FEATURES);
+ features |= RTAX_FEATURE_ALLFRAG;
+ dst_metric_set(&rt->dst, RTAX_FEATURES, features);
+ }
dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
goto out;
@@ -1615,9 +1624,12 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
nrt = rt6_alloc_clone(rt, daddr);
if (nrt) {
- nrt->dst.metrics[RTAX_MTU-1] = pmtu;
- if (allfrag)
- nrt->dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
+ dst_metric_set(&nrt->dst, RTAX_MTU, pmtu);
+ if (allfrag) {
+ u32 features = dst_metric(&nrt->dst, RTAX_FEATURES);
+ features |= RTAX_FEATURE_ALLFRAG;
+ dst_metric_set(&nrt->dst, RTAX_FEATURES, features);
+ }
/* According to RFC 1981, detecting PMTU increase shouldn't be
* happened within 5 mins, the recommended timer is 10 mins.
@@ -1668,7 +1680,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
rt->dst.input = ort->dst.input;
rt->dst.output = ort->dst.output;
- memcpy(rt->dst.metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32));
+ dst_copy_metrics(&rt->dst, &ort->dst);
rt->dst.error = ort->dst.error;
rt->dst.dev = ort->dst.dev;
if (rt->dst.dev)
@@ -1960,9 +1972,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
rt->dst.output = ip6_output;
rt->rt6i_dev = net->loopback_dev;
rt->rt6i_idev = idev;
- rt->dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
- rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->dst));
- rt->dst.metrics[RTAX_HOPLIMIT-1] = -1;
+ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1);
rt->dst.obsolete = -1;
rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
@@ -1999,11 +2009,11 @@ struct arg_dev_net {
static int fib6_ifdown(struct rt6_info *rt, void *arg)
{
- struct net_device *dev = ((struct arg_dev_net *)arg)->dev;
- struct net *net = ((struct arg_dev_net *)arg)->net;
+ const struct arg_dev_net *adn = arg;
+ const struct net_device *dev = adn->dev;
- if (((void *)rt->rt6i_dev == dev || dev == NULL) &&
- rt != net->ipv6.ip6_null_entry) {
+ if ((rt->rt6i_dev == dev || dev == NULL) &&
+ rt != adn->net->ipv6.ip6_null_entry) {
RT6_TRACE("deleted by ifdown %p\n", rt);
return -1;
}
@@ -2031,7 +2041,6 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
{
struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg;
struct inet6_dev *idev;
- struct net *net = dev_net(arg->dev);
/* In IPv6 pmtu discovery is not optional,
so that RTAX_MTU lock cannot disable it.
@@ -2062,8 +2071,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
(dst_mtu(&rt->dst) >= arg->mtu ||
(dst_mtu(&rt->dst) < arg->mtu &&
dst_mtu(&rt->dst) == idev->cnf.mtu6))) {
- rt->dst.metrics[RTAX_MTU-1] = arg->mtu;
- rt->dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, arg->mtu);
+ dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
}
return 0;
}
@@ -2289,7 +2297,7 @@ static int rt6_fill_node(struct net *net,
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
}
- if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
+ if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;
if (rt->dst.neighbour)
@@ -2465,8 +2473,6 @@ static int ip6_route_dev_notify(struct notifier_block *this,
#ifdef CONFIG_PROC_FS
-#define RT6_INFO_LEN (32 + 4 + 32 + 4 + 32 + 40 + 5 + 1)
-
struct rt6_proc_arg
{
char *buffer;
@@ -2682,6 +2688,7 @@ static int __net_init ip6_route_net_init(struct net *net)
net->ipv6.ip6_null_entry->dst.path =
(struct dst_entry *)net->ipv6.ip6_null_entry;
net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
+ dst_metric_set(&net->ipv6.ip6_null_entry->dst, RTAX_HOPLIMIT, 255);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2692,6 +2699,7 @@ static int __net_init ip6_route_net_init(struct net *net)
net->ipv6.ip6_prohibit_entry->dst.path =
(struct dst_entry *)net->ipv6.ip6_prohibit_entry;
net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
+ dst_metric_set(&net->ipv6.ip6_prohibit_entry->dst, RTAX_HOPLIMIT, 255);
net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2701,6 +2709,7 @@ static int __net_init ip6_route_net_init(struct net *net)
net->ipv6.ip6_blk_hole_entry->dst.path =
(struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
+ dst_metric_set(&net->ipv6.ip6_blk_hole_entry->dst, RTAX_HOPLIMIT, 255);
#endif
net->ipv6.sysctl.flush_delay = 0;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d6bfaec3bbbf..8ce38f10a547 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb)
return 0;
}
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+ /* no tunnel matched, let upstream know, ipsec may handle it */
rcu_read_unlock();
+ return 1;
out:
kfree_skb(skb);
return 0;
@@ -730,10 +731,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
}
{
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos) } },
+ struct flowi fl = { .fl4_dst = dst,
+ .fl4_src = tiph->saddr,
+ .fl4_tos = RT_TOS(tos),
.oif = tunnel->parms.link,
.proto = IPPROTO_IPV6 };
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
@@ -855,10 +855,9 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
iph = &tunnel->parms.iph;
if (iph->daddr) {
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos) } },
+ struct flowi fl = { .fl4_dst = iph->daddr,
+ .fl4_src = iph->saddr,
+ .fl4_tos = RT_TOS(iph->tos),
.oif = tunnel->parms.link,
.proto = IPPROTO_IPV6 };
struct rtable *rt;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7e41e2cbb85e..20aa95e37359 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -130,6 +130,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_sock *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
+ struct rt6_info *rt;
struct flowi fl;
struct dst_entry *dst;
int addr_type;
@@ -280,6 +281,26 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
sk->sk_gso_type = SKB_GSO_TCPV6;
__ip6_dst_store(sk, dst, NULL, NULL);
+ rt = (struct rt6_info *) dst;
+ if (tcp_death_row.sysctl_tw_recycle &&
+ !tp->rx_opt.ts_recent_stamp &&
+ ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) {
+ struct inet_peer *peer = rt6_get_peer(rt);
+ /*
+ * VJ's idea. We save last timestamp seen from
+ * the destination in peer table, when entering state
+ * TIME-WAIT * and initialize rx_opt.ts_recent from it,
+ * when trying new connection.
+ */
+ if (peer) {
+ inet_peer_refcheck(peer);
+ if ((u32)get_seconds() - peer->tcp_ts_stamp <= TCP_PAWS_MSL) {
+ tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp;
+ tp->rx_opt.ts_recent = peer->tcp_ts;
+ }
+ }
+ }
+
icsk->icsk_ext_hdr_len = 0;
if (np->opt)
icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
@@ -906,12 +927,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
};
#endif
-static struct timewait_sock_ops tcp6_timewait_sock_ops = {
- .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
- .twsk_unique = tcp_twsk_unique,
- .twsk_destructor= tcp_twsk_destructor,
-};
-
static void __tcp_v6_send_check(struct sk_buff *skb,
struct in6_addr *saddr, struct in6_addr *daddr)
{
@@ -1176,6 +1191,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_sock *tp = tcp_sk(sk);
__u32 isn = TCP_SKB_CB(skb)->when;
+ struct dst_entry *dst = NULL;
#ifdef CONFIG_SYN_COOKIES
int want_cookie = 0;
#else
@@ -1273,6 +1289,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
TCP_ECN_create_request(req, tcp_hdr(skb));
if (!isn) {
+ struct inet_peer *peer = NULL;
+
if (ipv6_opt_accepted(sk, skb) ||
np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
@@ -1285,13 +1303,57 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
if (!sk->sk_bound_dev_if &&
ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
treq->iif = inet6_iif(skb);
- if (!want_cookie) {
- isn = tcp_v6_init_sequence(skb);
- } else {
+
+ if (want_cookie) {
isn = cookie_v6_init_sequence(sk, skb, &req->mss);
req->cookie_ts = tmp_opt.tstamp_ok;
+ goto have_isn;
}
+
+ /* VJ's idea. We save last timestamp seen
+ * from the destination in peer table, when entering
+ * state TIME-WAIT, and check against it before
+ * accepting new connection request.
+ *
+ * If "isn" is not zero, this request hit alive
+ * timewait bucket, so that all the necessary checks
+ * are made in the function processing timewait state.
+ */
+ if (tmp_opt.saw_tstamp &&
+ tcp_death_row.sysctl_tw_recycle &&
+ (dst = inet6_csk_route_req(sk, req)) != NULL &&
+ (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL &&
+ ipv6_addr_equal((struct in6_addr *)peer->daddr.a6,
+ &treq->rmt_addr)) {
+ inet_peer_refcheck(peer);
+ if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
+ (s32)(peer->tcp_ts - req->ts_recent) >
+ TCP_PAWS_WINDOW) {
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
+ goto drop_and_release;
+ }
+ }
+ /* Kill the following clause, if you dislike this way. */
+ else if (!sysctl_tcp_syncookies &&
+ (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+ (sysctl_max_syn_backlog >> 2)) &&
+ (!peer || !peer->tcp_ts_stamp) &&
+ (!dst || !dst_metric(dst, RTAX_RTT))) {
+ /* Without syncookies last quarter of
+ * backlog is filled with destinations,
+ * proven to be alive.
+ * It means that we continue to communicate
+ * to destinations, already remembered
+ * to the moment of synflood.
+ */
+ LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open request from %pI6/%u\n",
+ &treq->rmt_addr, ntohs(tcp_hdr(skb)->source));
+ goto drop_and_release;
+ }
+
+ isn = tcp_v6_init_sequence(skb);
}
+have_isn:
tcp_rsk(req)->snt_isn = isn;
security_inet_conn_request(sk, skb, req);
@@ -1304,6 +1366,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
return 0;
+drop_and_release:
+ dst_release(dst);
drop_and_free:
reqsk_free(req);
drop:
@@ -1382,28 +1446,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (sk_acceptq_is_full(sk))
goto out_overflow;
- if (dst == NULL) {
- struct in6_addr *final_p, final;
- struct flowi fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
- final_p = fl6_update_dst(&fl, opt, &final);
- ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
- fl.oif = sk->sk_bound_dev_if;
- fl.mark = sk->sk_mark;
- fl.fl_ip_dport = inet_rsk(req)->rmt_port;
- fl.fl_ip_sport = inet_rsk(req)->loc_port;
- security_req_classify_flow(req, &fl);
-
- if (ip6_dst_lookup(sk, &dst, &fl))
- goto out;
-
- if (final_p)
- ipv6_addr_copy(&fl.fl6_dst, final_p);
-
- if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
+ if (!dst) {
+ dst = inet6_csk_route_req(sk, req);
+ if (!dst)
goto out;
}
@@ -1476,7 +1521,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
tcp_mtup_init(newsk);
tcp_sync_mss(newsk, dst_mtu(dst));
- newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
+ newtp->advmss = dst_metric_advmss(dst);
tcp_initialize_rcv_mss(newsk);
newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
@@ -1818,19 +1863,51 @@ do_time_wait:
goto discard_it;
}
-static int tcp_v6_remember_stamp(struct sock *sk)
+static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it)
{
- /* Alas, not yet... */
- return 0;
+ struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk);
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct inet_peer *peer;
+
+ if (!rt ||
+ !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) {
+ peer = inet_getpeer_v6(&np->daddr, 1);
+ *release_it = true;
+ } else {
+ if (!rt->rt6i_peer)
+ rt6_bind_peer(rt, 1);
+ peer = rt->rt6i_peer;
+ *release_it = false;
+ }
+
+ return peer;
}
+static void *tcp_v6_tw_get_peer(struct sock *sk)
+{
+ struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
+ struct inet_timewait_sock *tw = inet_twsk(sk);
+
+ if (tw->tw_family == AF_INET)
+ return tcp_v4_tw_get_peer(sk);
+
+ return inet_getpeer_v6(&tw6->tw_v6_daddr, 1);
+}
+
+static struct timewait_sock_ops tcp6_timewait_sock_ops = {
+ .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
+ .twsk_unique = tcp_twsk_unique,
+ .twsk_destructor= tcp_twsk_destructor,
+ .twsk_getpeer = tcp_v6_tw_get_peer,
+};
+
static const struct inet_connection_sock_af_ops ipv6_specific = {
.queue_xmit = inet6_csk_xmit,
.send_check = tcp_v6_send_check,
.rebuild_header = inet6_sk_rebuild_header,
.conn_request = tcp_v6_conn_request,
.syn_recv_sock = tcp_v6_syn_recv_sock,
- .remember_stamp = tcp_v6_remember_stamp,
+ .get_peer = tcp_v6_get_peer,
.net_header_len = sizeof(struct ipv6hdr),
.setsockopt = ipv6_setsockopt,
.getsockopt = ipv6_getsockopt,
@@ -1862,7 +1939,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
.rebuild_header = inet_sk_rebuild_header,
.conn_request = tcp_v6_conn_request,
.syn_recv_sock = tcp_v6_syn_recv_sock,
- .remember_stamp = tcp_v4_remember_stamp,
+ .get_peer = tcp_v4_get_peer,
.net_header_len = sizeof(struct iphdr),
.setsockopt = ipv6_setsockopt,
.getsockopt = ipv6_getsockopt,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 91def93bec85..9a009c66c8a3 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -54,8 +54,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
{
const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
- __be32 sk1_rcv_saddr = inet_sk(sk)->inet_rcv_saddr;
- __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+ __be32 sk1_rcv_saddr = sk_rcv_saddr(sk);
+ __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2);
int sk_ipv6only = ipv6_only_sock(sk);
int sk2_ipv6only = inet_v6_ipv6only(sk2);
int addr_type = ipv6_addr_type(sk_rcv_saddr6);
@@ -227,7 +227,7 @@ begin:
if (result) {
exact_match:
- if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+ if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
result = NULL;
else if (unlikely(compute_score2(result, net, saddr, sport,
daddr, hnum, dif) < badness)) {
@@ -294,7 +294,7 @@ begin:
goto begin;
if (result) {
- if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+ if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
result = NULL;
else if (unlikely(compute_score(result, net, hnum, saddr, sport,
daddr, dport, dif) < badness)) {
@@ -602,7 +602,7 @@ static void flush_stack(struct sock **stack, unsigned int count,
sk = stack[i];
if (skb1) {
- if (sk_rcvqueues_full(sk, skb)) {
+ if (sk_rcvqueues_full(sk, skb1)) {
kfree_skb(skb1);
goto drop;
}
@@ -1477,6 +1477,7 @@ struct proto udpv6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
+ .clear_sk = sk_prot_clear_portaddr_nulls,
};
static struct inet_protosw udpv6_protosw = {
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 5f48fadc27f7..986c4de5292e 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -55,6 +55,7 @@ struct proto udplitev6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
+ .clear_sk = sk_prot_clear_portaddr_nulls,
};
static struct inet_protosw udplite6_protosw = {
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index b809812c8d30..645cb968d450 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -14,6 +14,7 @@
#include <net/dsfield.h>
#include <net/dst.h>
#include <net/inet_ecn.h>
+#include <net/ip6_route.h>
#include <net/ipv6.h>
#include <net/xfrm.h>
@@ -53,7 +54,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
if (x->props.flags & XFRM_STATE_NOECN)
dsfield &= ~INET_ECN_MASK;
ipv6_change_dsfield(top_iph, 0, dsfield);
- top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
+ top_iph->hop_limit = ip6_dst_hoplimit(dst->child);
ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
return 0;
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6434bd5ce088..8e688b3de9ab 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -17,6 +17,7 @@
#include <linux/netfilter_ipv6.h>
#include <net/dst.h>
#include <net/ipv6.h>
+#include <net/ip6_route.h>
#include <net/xfrm.h>
int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
@@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb)
return xfrm_output(skb);
}
+static int __xfrm6_output(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb_dst(skb);
+ struct xfrm_state *x = dst->xfrm;
+
+ if ((x && x->props.mode == XFRM_MODE_TUNNEL) &&
+ ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+ dst_allfrag(skb_dst(skb)))) {
+ return ip6_fragment(skb, xfrm6_output_finish);
+ }
+ return xfrm6_output_finish(skb);
+}
+
int xfrm6_output(struct sk_buff *skb)
{
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
- skb_dst(skb)->dev, xfrm6_output_finish);
+ skb_dst(skb)->dev, __xfrm6_output);
}
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index a6de3059746d..c9890e25cd4c 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2280,6 +2280,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
switch (optname) {
case IRLMP_ENUMDEVICES:
+
+ /* Offset to first device entry */
+ offset = sizeof(struct irda_device_list) -
+ sizeof(struct irda_device_info);
+
+ if (len < offset) {
+ err = -EINVAL;
+ goto out;
+ }
+
/* Ask lmp for the current discovery log */
discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
self->nslots);
@@ -2290,15 +2300,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
}
/* Write total list length back to client */
- if (copy_to_user(optval, &list,
- sizeof(struct irda_device_list) -
- sizeof(struct irda_device_info)))
+ if (copy_to_user(optval, &list, offset))
err = -EFAULT;
- /* Offset to first device entry */
- offset = sizeof(struct irda_device_list) -
- sizeof(struct irda_device_info);
-
/* Copy the list itself - watch for overflow */
if (list.len > 2048) {
err = -EINVAL;
diff --git a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile
index 48689458c086..ab23b5ba7e33 100644
--- a/net/irda/ircomm/Makefile
+++ b/net/irda/ircomm/Makefile
@@ -4,5 +4,5 @@
obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o
-ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o
-ircomm-tty-objs := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o
+ircomm-y := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o
+ircomm-tty-y := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o
diff --git a/net/irda/irlan/Makefile b/net/irda/irlan/Makefile
index 77549bc8641b..94eefbc8e6b9 100644
--- a/net/irda/irlan/Makefile
+++ b/net/irda/irlan/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_IRLAN) += irlan.o
-irlan-objs := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o
+irlan-y := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o
diff --git a/net/irda/irnet/Makefile b/net/irda/irnet/Makefile
index b3ee01e0def3..61c365c8a2a0 100644
--- a/net/irda/irnet/Makefile
+++ b/net/irda/irnet/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_IRNET) += irnet.o
-irnet-objs := irnet_ppp.o irnet_irda.o
+irnet-y := irnet_ppp.o irnet_irda.o
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index f7db676de77d..1ee5dab3cfae 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -36,6 +36,7 @@
#define KMSG_COMPONENT "iucv"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
@@ -1804,6 +1805,7 @@ static void iucv_external_interrupt(unsigned int ext_int_code,
struct iucv_irq_data *p;
struct iucv_irq_list *work;
+ kstat_cpu(smp_processor_id()).irqs[EXTINT_IUC]++;
p = iucv_irq_data[smp_processor_id()];
if (p->ippathid >= iucv_max_pathid) {
WARN_ON(p->ippathid >= iucv_max_pathid);
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 0bf6a59545ab..110efb704c9b 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -476,15 +476,13 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
{
struct flowi fl = { .oif = sk->sk_bound_dev_if,
- .nl_u = { .ip4_u = {
- .daddr = daddr,
- .saddr = inet->inet_saddr,
- .tos = RT_CONN_FLAGS(sk) } },
+ .fl4_dst = daddr,
+ .fl4_src = inet->inet_saddr,
+ .fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
- .uli_u = { .ports = {
- .sport = inet->inet_sport,
- .dport = inet->inet_dport } } };
+ .fl_ip_sport = inet->inet_sport,
+ .fl_ip_dport = inet->inet_dport };
/* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times
@@ -674,4 +672,8 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
MODULE_DESCRIPTION("L2TP over IP");
MODULE_VERSION("1.0");
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP);
+
+/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like
+ * enums
+ */
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
diff --git a/net/lapb/Makefile b/net/lapb/Makefile
index 53f7c90db163..fff797dfc88c 100644
--- a/net/lapb/Makefile
+++ b/net/lapb/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_LAPB) += lapb.o
-lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o
+lapb-y := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 582612998211..dfd3a648a551 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -316,9 +316,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
if (unlikely(addr->sllc_family != AF_LLC))
goto out;
rc = -ENODEV;
- rtnl_lock();
+ rcu_read_lock();
if (sk->sk_bound_dev_if) {
- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
if (llc->dev) {
if (!addr->sllc_arphrd)
addr->sllc_arphrd = llc->dev->type;
@@ -329,14 +329,15 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
!llc_mac_match(addr->sllc_mac,
llc->dev->dev_addr)) {
rc = -EINVAL;
- dev_put(llc->dev);
llc->dev = NULL;
}
}
} else
- llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
+ llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
addr->sllc_mac);
- rtnl_unlock();
+ if (llc->dev)
+ dev_hold(llc->dev);
+ rcu_read_unlock();
if (!llc->dev)
goto out;
if (!addr->sllc_sap) {
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 4d6f8653ec88..9109262abd24 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -6,6 +6,7 @@ config MAC80211
select CRYPTO_ARC4
select CRYPTO_AES
select CRC32
+ select AVERAGE
---help---
This option enables the hardware independent IEEE 802.11
networking stack.
@@ -92,7 +93,7 @@ config MAC80211_MESH
config MAC80211_LEDS
bool "Enable LED triggers"
depends on MAC80211
- select NEW_LEDS
+ depends on LEDS_CLASS
select LEDS_TRIGGERS
---help---
This option enables a few LED triggers for different
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index d2b03e0851ef..4bd6ef0be380 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -147,6 +147,5 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
void ieee80211_aes_key_free(struct crypto_cipher *tfm)
{
- if (tfm)
- crypto_free_cipher(tfm);
+ crypto_free_cipher(tfm);
}
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index b4d66cca76d6..d502b2684a66 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -128,6 +128,5 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
{
- if (tfm)
- crypto_free_cipher(tfm);
+ crypto_free_cipher(tfm);
}
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 720b7a84af59..f138b195d657 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -129,9 +129,7 @@ static void sta_rx_agg_reorder_timer_expired(unsigned long data)
timer_to_tid[0]);
rcu_read_lock();
- spin_lock(&sta->lock);
ieee80211_release_reorder_timeout(sta, *ptid);
- spin_unlock(&sta->lock);
rcu_read_unlock();
}
@@ -256,7 +254,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
}
/* prepare A-MPDU MLME for Rx aggregation */
- tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
+ tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
if (!tid_agg_rx) {
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
@@ -280,9 +278,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
- kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
+ kcalloc(buf_size, sizeof(struct sk_buff *), GFP_KERNEL);
tid_agg_rx->reorder_time =
- kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC);
+ kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL);
if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d4679b265ba8..9cc472c6a6a5 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
/* send AddBA request */
ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
tid_tx->dialog_token, start_seq_num,
- 0x40, 5000);
+ 0x40, tid_tx->timeout);
}
-int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
+int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
+ u16 timeout)
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
skb_queue_head_init(&tid_tx->pending);
__set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
+ tid_tx->timeout = timeout;
+
/* Tx timer */
tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 18bd0e550600..5892b0302454 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -19,9 +19,10 @@
#include "rate.h"
#include "mesh.h"
-static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
+static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type,
+ u32 *flags,
+ struct vif_params *params)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct net_device *dev;
@@ -29,12 +30,15 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
int err;
err = ieee80211_if_add(local, name, &dev, type, params);
- if (err || type != NL80211_IFTYPE_MONITOR || !flags)
- return err;
+ if (err)
+ return ERR_PTR(err);
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- sdata->u.mntr_flags = *flags;
- return 0;
+ if (type == NL80211_IFTYPE_MONITOR && flags) {
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ sdata->u.mntr_flags = *flags;
+ }
+
+ return dev;
}
static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
@@ -56,11 +60,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
if (ret)
return ret;
- if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
- ieee80211_sdata_set_mesh_id(sdata,
- params->mesh_id_len,
- params->mesh_id);
-
if (type == NL80211_IFTYPE_AP_VLAN &&
params && params->use_4addr == 0)
rcu_assign_pointer(sdata->u.vlan.sta, NULL);
@@ -296,11 +295,12 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_config_default_key(struct wiphy *wiphy,
struct net_device *dev,
- u8 key_idx)
+ u8 key_idx, bool uni,
+ bool multi)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- ieee80211_set_default_key(sdata, key_idx);
+ ieee80211_set_default_key(sdata, key_idx, uni, multi);
return 0;
}
@@ -343,8 +343,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
(sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
- sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
sinfo->signal = (s8)sta->last_signal;
+ sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
}
sinfo->txrate.flags = 0;
@@ -983,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
-static int ieee80211_get_mesh_params(struct wiphy *wiphy,
+static int ieee80211_get_mesh_config(struct wiphy *wiphy,
struct net_device *dev,
struct mesh_config *conf)
{
@@ -999,9 +1000,39 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
return (mask >> (parm-1)) & 0x1;
}
-static int ieee80211_set_mesh_params(struct wiphy *wiphy,
- struct net_device *dev,
- const struct mesh_config *nconf, u32 mask)
+static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
+ const struct mesh_setup *setup)
+{
+ u8 *new_ie;
+ const u8 *old_ie;
+
+ /* first allocate the new vendor information element */
+ new_ie = NULL;
+ old_ie = ifmsh->vendor_ie;
+
+ ifmsh->vendor_ie_len = setup->vendor_ie_len;
+ if (setup->vendor_ie_len) {
+ new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
+ GFP_KERNEL);
+ if (!new_ie)
+ return -ENOMEM;
+ }
+
+ /* now copy the rest of the setup parameters */
+ ifmsh->mesh_id_len = setup->mesh_id_len;
+ memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
+ ifmsh->mesh_pp_id = setup->path_sel_proto;
+ ifmsh->mesh_pm_id = setup->path_metric;
+ ifmsh->vendor_ie = new_ie;
+
+ kfree(old_ie);
+
+ return 0;
+}
+
+static int ieee80211_update_mesh_config(struct wiphy *wiphy,
+ struct net_device *dev, u32 mask,
+ const struct mesh_config *nconf)
{
struct mesh_config *conf;
struct ieee80211_sub_if_data *sdata;
@@ -1024,6 +1055,8 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
conf->dot11MeshTTL = nconf->dot11MeshTTL;
+ if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
+ conf->dot11MeshTTL = nconf->element_ttl;
if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
conf->auto_open_plinks = nconf->auto_open_plinks;
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
@@ -1050,6 +1083,31 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
return 0;
}
+static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
+ const struct mesh_config *conf,
+ const struct mesh_setup *setup)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ int err;
+
+ memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
+ err = copy_mesh_setup(ifmsh, setup);
+ if (err)
+ return err;
+ ieee80211_start_mesh(sdata);
+
+ return 0;
+}
+
+static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ ieee80211_stop_mesh(sdata);
+
+ return 0;
+}
#endif
static int ieee80211_change_bss(struct wiphy *wiphy,
@@ -1108,6 +1166,12 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
}
+ if (params->ht_opmode >= 0) {
+ sdata->vif.bss_conf.ht_operation_mode =
+ (u16) params->ht_opmode;
+ changed |= BSS_CHANGED_HT;
+ }
+
ieee80211_bss_info_change_notify(sdata, changed);
return 0;
@@ -1299,6 +1363,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
struct ieee80211_local *local = wiphy_priv(wiphy);
int err;
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+ err = drv_set_frag_threshold(local, wiphy->frag_threshold);
+
+ if (err)
+ return err;
+ }
+
if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
err = drv_set_coverage_class(local, wiphy->coverage_class);
@@ -1544,27 +1615,54 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
}
+static enum work_done_result
+ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
+{
+ /*
+ * Use the data embedded in the work struct for reporting
+ * here so if the driver mangled the SKB before dropping
+ * it (which is the only way we really should get here)
+ * then we don't report mangled data.
+ *
+ * If there was no wait time, then by the time we get here
+ * the driver will likely not have reported the status yet,
+ * so in that case userspace will have to deal with it.
+ */
+
+ if (wk->offchan_tx.wait && wk->offchan_tx.frame)
+ cfg80211_mgmt_tx_status(wk->sdata->dev,
+ (unsigned long) wk->offchan_tx.frame,
+ wk->ie, wk->ie_len, false, GFP_KERNEL);
+
+ return WORK_DONE_DESTROY;
+}
+
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
- bool channel_type_valid,
+ bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
+ struct ieee80211_work *wk;
const struct ieee80211_mgmt *mgmt = (void *)buf;
u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
IEEE80211_TX_CTL_REQ_TX_STATUS;
+ bool is_offchan = false;
/* Check that we are on the requested channel for transmission */
if (chan != local->tmp_channel &&
chan != local->oper_channel)
- return -EBUSY;
+ is_offchan = true;
if (channel_type_valid &&
(channel_type != local->tmp_channel_type &&
channel_type != local->_oper_channel_type))
+ is_offchan = true;
+
+ if (is_offchan && !offchan)
return -EBUSY;
switch (sdata->vif.type) {
@@ -1572,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_MESH_POINT:
if (!ieee80211_is_action(mgmt->frame_control) ||
mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
break;
@@ -1598,12 +1697,70 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
IEEE80211_SKB_CB(skb)->flags = flags;
skb->dev = sdata->dev;
- ieee80211_tx_skb(sdata, skb);
*cookie = (unsigned long) skb;
+
+ /*
+ * Can transmit right away if the channel was the
+ * right one and there's no wait involved... If a
+ * wait is involved, we might otherwise not be on
+ * the right channel for long enough!
+ */
+ if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) {
+ ieee80211_tx_skb(sdata, skb);
+ return 0;
+ }
+
+ wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL);
+ if (!wk) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+
+ wk->type = IEEE80211_WORK_OFFCHANNEL_TX;
+ wk->chan = chan;
+ wk->sdata = sdata;
+ wk->done = ieee80211_offchan_tx_done;
+ wk->offchan_tx.frame = skb;
+ wk->offchan_tx.wait = wait;
+ wk->ie_len = len;
+ memcpy(wk->ie, buf, len);
+
+ ieee80211_add_work(wk);
return 0;
}
+static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev,
+ u64 cookie)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_work *wk;
+ int ret = -ENOENT;
+
+ mutex_lock(&local->mtx);
+ list_for_each_entry(wk, &local->work_list, list) {
+ if (wk->sdata != sdata)
+ continue;
+
+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
+ continue;
+
+ if (cookie != (unsigned long) wk->offchan_tx.frame)
+ continue;
+
+ wk->timeout = jiffies;
+
+ ieee80211_queue_work(&local->hw, &local->work_work);
+ ret = 0;
+ break;
+ }
+ mutex_unlock(&local->mtx);
+
+ return ret;
+}
+
static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
struct net_device *dev,
u16 frame_type, bool reg)
@@ -1621,6 +1778,23 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
}
+static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ if (local->started)
+ return -EOPNOTSUPP;
+
+ return drv_set_antenna(local, tx_ant, rx_ant);
+}
+
+static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ return drv_get_antenna(local, tx_ant, rx_ant);
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -1645,8 +1819,10 @@ struct cfg80211_ops mac80211_config_ops = {
.change_mpath = ieee80211_change_mpath,
.get_mpath = ieee80211_get_mpath,
.dump_mpath = ieee80211_dump_mpath,
- .set_mesh_params = ieee80211_set_mesh_params,
- .get_mesh_params = ieee80211_get_mesh_params,
+ .update_mesh_config = ieee80211_update_mesh_config,
+ .get_mesh_config = ieee80211_get_mesh_config,
+ .join_mesh = ieee80211_join_mesh,
+ .leave_mesh = ieee80211_leave_mesh,
#endif
.change_bss = ieee80211_change_bss,
.set_txq_params = ieee80211_set_txq_params,
@@ -1671,6 +1847,9 @@ struct cfg80211_ops mac80211_config_ops = {
.remain_on_channel = ieee80211_remain_on_channel,
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
.mgmt_tx = ieee80211_mgmt_tx,
+ .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
.mgmt_frame_register = ieee80211_mgmt_frame_register,
+ .set_antenna = ieee80211_set_antenna,
+ .get_antenna = ieee80211_get_antenna,
};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 18260aa99c56..1f02e599a318 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -21,16 +21,30 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file)
return 0;
}
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
+#define DEBUGFS_FORMAT_BUFFER_SIZE 100
+
+int mac80211_format_buffer(char __user *userbuf, size_t count,
+ loff_t *ppos, char *fmt, ...)
+{
+ va_list args;
+ char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
+ int res;
+
+ va_start(args, fmt);
+ res = vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
static ssize_t name## _read(struct file *file, char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
struct ieee80211_local *local = file->private_data; \
- char buf[buflen]; \
- int res; \
\
- res = scnprintf(buf, buflen, fmt "\n", ##value); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+ return mac80211_format_buffer(userbuf, count, ppos, \
+ fmt "\n", ##value); \
} \
\
static const struct file_operations name## _ops = { \
@@ -46,13 +60,13 @@ static const struct file_operations name## _ops = { \
debugfs_create_file(#name, mode, phyd, local, &name## _ops);
-DEBUGFS_READONLY_FILE(frequency, 20, "%d",
+DEBUGFS_READONLY_FILE(frequency, "%d",
local->hw.conf.channel->center_freq);
-DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
+DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
local->total_ps_buffered);
-DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x",
+DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
local->wep_iv & 0xffffff);
-DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s",
+DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
static ssize_t tsf_read(struct file *file, char __user *user_buf,
@@ -60,13 +74,11 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
{
struct ieee80211_local *local = file->private_data;
u64 tsf;
- char buf[100];
tsf = drv_get_tsf(local);
- snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
+ return mac80211_format_buffer(user_buf, count, ppos, "0x%016llx\n",
+ (unsigned long long) tsf);
}
static ssize_t tsf_write(struct file *file,
@@ -131,12 +143,9 @@ static ssize_t noack_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
- int res;
- char buf[10];
- res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+ return mac80211_format_buffer(user_buf, count, ppos, "%d\n",
+ local->wifi_wme_noack_test);
}
static ssize_t noack_write(struct file *file,
@@ -168,12 +177,8 @@ static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
- int res;
- char buf[10];
-
- res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+ return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
+ local->uapsd_queues);
}
static ssize_t uapsd_queues_write(struct file *file,
@@ -215,12 +220,9 @@ static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
- int res;
- char buf[10];
- res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+ return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
+ local->uapsd_max_sp_len);
}
static ssize_t uapsd_max_sp_len_write(struct file *file,
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h
index 09cc9be34796..7c87529630f5 100644
--- a/net/mac80211/debugfs.h
+++ b/net/mac80211/debugfs.h
@@ -4,6 +4,8 @@
#ifdef CONFIG_MAC80211_DEBUGFS
extern void debugfs_hw_add(struct ieee80211_local *local);
extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
+extern int mac80211_format_buffer(char __user *userbuf, size_t count,
+ loff_t *ppos, char *fmt, ...);
#else
static inline void debugfs_hw_add(struct ieee80211_local *local)
{
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 1243d1db5c59..f7ef3477c24a 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -15,18 +15,17 @@
#include "debugfs.h"
#include "debugfs_key.h"
-#define KEY_READ(name, prop, buflen, format_string) \
+#define KEY_READ(name, prop, format_string) \
static ssize_t key_##name##_read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
- char buf[buflen]; \
struct ieee80211_key *key = file->private_data; \
- int res = scnprintf(buf, buflen, format_string, key->prop); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+ return mac80211_format_buffer(userbuf, count, ppos, \
+ format_string, key->prop); \
}
-#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
-#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n")
+#define KEY_READ_D(name) KEY_READ(name, name, "%d\n")
+#define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n")
#define KEY_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
@@ -39,9 +38,9 @@ static const struct file_operations key_ ##name## _ops = { \
KEY_READ_##format(name) \
KEY_OPS(name)
-#define KEY_CONF_READ(name, buflen, format_string) \
- KEY_READ(conf_##name, conf.name, buflen, format_string)
-#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
+#define KEY_CONF_READ(name, format_string) \
+ KEY_READ(conf_##name, conf.name, format_string)
+#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n")
#define KEY_CONF_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
@@ -59,7 +58,7 @@ KEY_CONF_FILE(keyidx, D);
KEY_CONF_FILE(hw_key_idx, D);
KEY_FILE(flags, X);
KEY_FILE(tx_rx_count, D);
-KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n");
+KEY_READ(ifindex, sdata->name, "%s\n");
KEY_OPS(ifindex);
static ssize_t key_algorithm_read(struct file *file,
@@ -275,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
debugfs_remove_recursive(key->debugfs.dir);
key->debugfs.dir = NULL;
}
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
+
+void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
{
char buf[50];
struct ieee80211_key *key;
@@ -283,25 +283,29 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
if (!sdata->debugfs.dir)
return;
- /* this is running under the key lock */
+ lockdep_assert_held(&sdata->local->key_mtx);
- key = sdata->default_key;
- if (key) {
+ if (sdata->default_unicast_key) {
+ key = sdata->default_unicast_key;
sprintf(buf, "../keys/%d", key->debugfs.cnt);
- sdata->debugfs.default_key =
- debugfs_create_symlink("default_key",
+ sdata->debugfs.default_unicast_key =
+ debugfs_create_symlink("default_unicast_key",
sdata->debugfs.dir, buf);
- } else
- ieee80211_debugfs_key_remove_default(sdata);
-}
-
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
-{
- if (!sdata)
- return;
+ } else {
+ debugfs_remove(sdata->debugfs.default_unicast_key);
+ sdata->debugfs.default_unicast_key = NULL;
+ }
- debugfs_remove(sdata->debugfs.default_key);
- sdata->debugfs.default_key = NULL;
+ if (sdata->default_multicast_key) {
+ key = sdata->default_multicast_key;
+ sprintf(buf, "../keys/%d", key->debugfs.cnt);
+ sdata->debugfs.default_multicast_key =
+ debugfs_create_symlink("default_multicast_key",
+ sdata->debugfs.dir, buf);
+ } else {
+ debugfs_remove(sdata->debugfs.default_multicast_key);
+ sdata->debugfs.default_multicast_key = NULL;
+ }
}
void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/debugfs_key.h b/net/mac80211/debugfs_key.h
index 54717b4e1371..32adc77e9c77 100644
--- a/net/mac80211/debugfs_key.h
+++ b/net/mac80211/debugfs_key.h
@@ -4,8 +4,7 @@
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_debugfs_key_add(struct ieee80211_key *key);
void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
+void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_add_mgmt_default(
struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_remove_mgmt_default(
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key)
{}
static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
{}
-static inline void ieee80211_debugfs_key_add_default(
- struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_key_remove_default(
+static inline void ieee80211_debugfs_key_update_default(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_key_add_mgmt_default(
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index cbdf36d7841c..2dabdf7680d0 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -251,6 +251,7 @@ IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
+IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
@@ -355,6 +356,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(dot11MeshConfirmTimeout);
MESHPARAMS_ADD(dot11MeshHoldingTimeout);
MESHPARAMS_ADD(dot11MeshTTL);
+ MESHPARAMS_ADD(element_ttl);
MESHPARAMS_ADD(auto_open_plinks);
MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 4601fea1784d..c04a1396cf8d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -17,20 +17,18 @@
/* sta attributtes */
-#define STA_READ(name, buflen, field, format_string) \
+#define STA_READ(name, field, format_string) \
static ssize_t sta_ ##name## _read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
- int res; \
struct sta_info *sta = file->private_data; \
- char buf[buflen]; \
- res = scnprintf(buf, buflen, format_string, sta->field); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+ return mac80211_format_buffer(userbuf, count, ppos, \
+ format_string, sta->field); \
}
-#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n")
-#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n")
-#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n")
+#define STA_READ_D(name, field) STA_READ(name, field, "%d\n")
+#define STA_READ_U(name, field) STA_READ(name, field, "%u\n")
+#define STA_READ_S(name, field) STA_READ(name, field, "%s\n")
#define STA_OPS(name) \
static const struct file_operations sta_ ##name## _ops = { \
@@ -79,22 +77,18 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
- char buf[20];
struct sta_info *sta = file->private_data;
- int res = scnprintf(buf, sizeof(buf), "%u\n",
- skb_queue_len(&sta->ps_tx_buf));
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+ return mac80211_format_buffer(userbuf, count, ppos, "%u\n",
+ skb_queue_len(&sta->ps_tx_buf));
}
STA_OPS(num_ps_buf_frames);
static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- char buf[20];
struct sta_info *sta = file->private_data;
- int res = scnprintf(buf, sizeof(buf), "%d\n",
- jiffies_to_msecs(jiffies - sta->last_rx));
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+ return mac80211_format_buffer(userbuf, count, ppos, "%d\n",
+ jiffies_to_msecs(jiffies - sta->last_rx));
}
STA_OPS(inactive_ms);
@@ -118,34 +112,35 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
char buf[71 + STA_TID_NUM * 40], *p = buf;
int i;
struct sta_info *sta = file->private_data;
+ struct tid_ampdu_rx *tid_rx;
+ struct tid_ampdu_tx *tid_tx;
+
+ rcu_read_lock();
- spin_lock_bh(&sta->lock);
p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
sta->ampdu_mlme.dialog_token_allocator + 1);
p += scnprintf(p, sizeof(buf) + buf - p,
"TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
+
for (i = 0; i < STA_TID_NUM; i++) {
+ tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]);
+
p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
- p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
- !!sta->ampdu_mlme.tid_rx[i]);
+ p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_rx);
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
- sta->ampdu_mlme.tid_rx[i] ?
- sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
+ tid_rx ? tid_rx->dialog_token : 0);
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
- sta->ampdu_mlme.tid_rx[i] ?
- sta->ampdu_mlme.tid_rx[i]->ssn : 0);
+ tid_rx ? tid_rx->ssn : 0);
- p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
- !!sta->ampdu_mlme.tid_tx[i]);
+ p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_tx);
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
- sta->ampdu_mlme.tid_tx[i] ?
- sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
+ tid_tx ? tid_tx->dialog_token : 0);
p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d",
- sta->ampdu_mlme.tid_tx[i] ?
- skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
+ tid_tx ? skb_queue_len(&tid_tx->pending) : 0);
p += scnprintf(p, sizeof(buf) + buf - p, "\n");
}
- spin_unlock_bh(&sta->lock);
+ rcu_read_unlock();
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
@@ -194,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
if (tx) {
if (start)
- ret = ieee80211_start_tx_ba_session(&sta->sta, tid);
+ ret = ieee80211_start_tx_ba_session(&sta->sta, tid, 5000);
else
ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
} else {
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 16983825f8e8..af0c4398cceb 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -233,6 +233,20 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local,
trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
}
+static inline int drv_set_frag_threshold(struct ieee80211_local *local,
+ u32 value)
+{
+ int ret = 0;
+
+ might_sleep();
+
+ trace_drv_set_frag_threshold(local, value);
+ if (local->ops->set_frag_threshold)
+ ret = local->ops->set_frag_threshold(&local->hw, value);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
static inline int drv_set_rts_threshold(struct ieee80211_local *local,
u32 value)
{
@@ -353,7 +367,7 @@ static inline void drv_reset_tsf(struct ieee80211_local *local)
static inline int drv_tx_last_beacon(struct ieee80211_local *local)
{
- int ret = 1;
+ int ret = 0; /* default unsuported op for less congestion */
might_sleep();
@@ -428,4 +442,27 @@ static inline void drv_channel_switch(struct ieee80211_local *local,
trace_drv_return_void(local);
}
+
+static inline int drv_set_antenna(struct ieee80211_local *local,
+ u32 tx_ant, u32 rx_ant)
+{
+ int ret = -EOPNOTSUPP;
+ might_sleep();
+ if (local->ops->set_antenna)
+ ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
+ trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
+ return ret;
+}
+
+static inline int drv_get_antenna(struct ieee80211_local *local,
+ u32 *tx_ant, u32 *rx_ant)
+{
+ int ret = -EOPNOTSUPP;
+ might_sleep();
+ if (local->ops->get_antenna)
+ ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
+ trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
+ return ret;
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6831fb1641c8..c2772f23ac9c 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -531,6 +531,27 @@ TRACE_EVENT(drv_get_tkip_seq,
)
);
+TRACE_EVENT(drv_set_frag_threshold,
+ TP_PROTO(struct ieee80211_local *local, u32 value),
+
+ TP_ARGS(local, value),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(u32, value)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->value = value;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT " value:%d",
+ LOCAL_PR_ARG, __entry->value
+ )
+);
+
TRACE_EVENT(drv_set_rts_threshold,
TP_PROTO(struct ieee80211_local *local, u32 value),
@@ -862,6 +883,56 @@ TRACE_EVENT(drv_channel_switch,
)
);
+TRACE_EVENT(drv_set_antenna,
+ TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
+
+ TP_ARGS(local, tx_ant, rx_ant, ret),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(u32, tx_ant)
+ __field(u32, rx_ant)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->tx_ant = tx_ant;
+ __entry->rx_ant = rx_ant;
+ __entry->ret = ret;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+ LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
+ )
+);
+
+TRACE_EVENT(drv_get_antenna,
+ TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
+
+ TP_ARGS(local, tx_ant, rx_ant, ret),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ __field(u32, tx_ant)
+ __field(u32, rx_ant)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ __entry->tx_ant = tx_ant;
+ __entry->rx_ant = rx_ant;
+ __entry->ret = ret;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+ LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
+ )
+);
+
/*
* Tracing for API calls that drivers call.
*/
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 239c4836a946..53c7077ffd4f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mutex_lock(&sdata->u.ibss.mtx);
+ if (!sdata->u.ibss.ssid_len)
+ goto mgmt_out; /* not ready to merge yet */
+
switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_PROBE_REQ:
ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len);
@@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
break;
}
+ mgmt_out:
mutex_unlock(&sdata->u.ibss.mtx);
}
@@ -915,6 +919,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.privacy = params->privacy;
sdata->u.ibss.basic_rates = params->basic_rates;
+ memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
+ sizeof(params->mcast_rate));
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b80c38689927..95cdd2a3f809 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
+#include <linux/leds.h>
#include <net/ieee80211_radiotap.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
@@ -167,6 +168,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
* @IEEE80211_RX_FRAGMENTED: fragmented frame
* @IEEE80211_RX_AMSDU: a-MSDU packet
* @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed
+ * @IEEE80211_RX_DEFERRED_RELEASE: frame was subjected to receive reordering
*
* These are per-frame flags that are attached to a frame in the
* @rx_flags field of &struct ieee80211_rx_status.
@@ -177,6 +179,7 @@ enum ieee80211_packet_rx_flags {
IEEE80211_RX_FRAGMENTED = BIT(2),
IEEE80211_RX_AMSDU = BIT(3),
IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4),
+ IEEE80211_RX_DEFERRED_RELEASE = BIT(5),
};
/**
@@ -260,6 +263,7 @@ enum ieee80211_work_type {
IEEE80211_WORK_ASSOC_BEACON_WAIT,
IEEE80211_WORK_ASSOC,
IEEE80211_WORK_REMAIN_ON_CHANNEL,
+ IEEE80211_WORK_OFFCHANNEL_TX,
};
/**
@@ -320,6 +324,10 @@ struct ieee80211_work {
struct {
u32 duration;
} remain;
+ struct {
+ struct sk_buff *frame;
+ u32 wait;
+ } offchan_tx;
};
int ie_len;
@@ -349,8 +357,10 @@ struct ieee80211_if_managed {
struct work_struct chswitch_work;
struct work_struct beacon_connection_loss_work;
+ unsigned long beacon_timeout;
unsigned long probe_timeout;
int probe_send_count;
+ bool nullfunc_failed;
struct mutex mtx;
struct cfg80211_bss *associated;
@@ -477,6 +487,8 @@ struct ieee80211_if_mesh {
struct mesh_config mshcfg;
u32 mesh_seqnum;
bool accepting_plinks;
+ const u8 *vendor_ie;
+ u8 vendor_ie_len;
};
#ifdef CONFIG_MAC80211_MESH
@@ -550,7 +562,7 @@ struct ieee80211_sub_if_data {
unsigned int fragment_next;
struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
- struct ieee80211_key *default_key;
+ struct ieee80211_key *default_unicast_key, *default_multicast_key;
struct ieee80211_key *default_mgmt_key;
u16 sequence_number;
@@ -578,9 +590,7 @@ struct ieee80211_sub_if_data {
struct ieee80211_if_vlan vlan;
struct ieee80211_if_managed mgd;
struct ieee80211_if_ibss ibss;
-#ifdef CONFIG_MAC80211_MESH
struct ieee80211_if_mesh mesh;
-#endif
u32 mntr_flags;
} u;
@@ -588,7 +598,8 @@ struct ieee80211_sub_if_data {
struct {
struct dentry *dir;
struct dentry *subdir_stations;
- struct dentry *default_key;
+ struct dentry *default_unicast_key;
+ struct dentry *default_multicast_key;
struct dentry *default_mgmt_key;
} debugfs;
#endif
@@ -602,19 +613,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
return container_of(p, struct ieee80211_sub_if_data, vif);
}
-static inline void
-ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata,
- u8 mesh_id_len, u8 *mesh_id)
-{
-#ifdef CONFIG_MAC80211_MESH
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- ifmsh->mesh_id_len = mesh_id_len;
- memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len);
-#else
- WARN_ON(1);
-#endif
-}
-
enum sdata_queue_type {
IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0,
IEEE80211_SDATA_QUEUE_AGG_START = 1,
@@ -635,6 +633,20 @@ enum queue_stop_reason {
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
};
+#ifdef CONFIG_MAC80211_LEDS
+struct tpt_led_trigger {
+ struct led_trigger trig;
+ char name[32];
+ const struct ieee80211_tpt_blink *blink_table;
+ unsigned int blink_table_len;
+ struct timer_list timer;
+ unsigned long prev_traffic;
+ unsigned long tx_bytes, rx_bytes;
+ unsigned int active, want;
+ bool running;
+};
+#endif
+
/**
* mac80211 scan flags - currently active scan mode
*
@@ -764,6 +776,15 @@ struct ieee80211_local {
struct sk_buff_head skb_queue;
struct sk_buff_head skb_queue_unreliable;
+ /*
+ * Internal FIFO queue which is shared between multiple rx path
+ * stages. Its main task is to provide a serialization mechanism,
+ * so all rx handlers can enjoy having exclusive access to their
+ * private data structures.
+ */
+ struct sk_buff_head rx_skb_queue;
+ bool running_rx_handler; /* protected by rx_skb_queue.lock */
+
/* Station data */
/*
* The mutex only protects the list and counter,
@@ -843,6 +864,7 @@ struct ieee80211_local {
#ifdef CONFIG_MAC80211_LEDS
int tx_led_counter, rx_led_counter;
struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led;
+ struct tpt_led_trigger *tpt_led_trigger;
char tx_led_name[32], rx_led_name[32],
assoc_led_name[32], radio_led_name[32];
#endif
@@ -1264,6 +1286,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
int powersave);
void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
struct ieee80211_hdr *hdr);
+void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr, bool ack);
void ieee80211_beacon_connection_loss_work(struct work_struct *work);
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
@@ -1278,6 +1302,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct sk_buff *skb);
int ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct sk_buff_head *skbs);
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+ struct sk_buff_head *skbs,
+ void (*fn)(void *data), void *data);
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg,
@@ -1287,6 +1314,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
const u8 *ie, size_t ie_len,
enum ieee80211_band band, u32 rate_mask,
u8 channel);
+struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
+ u8 *dst,
+ const u8 *ssid, size_t ssid_len,
+ const u8 *ie, size_t ie_len);
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7aa85591dbe7..b6db237672ff 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -197,11 +197,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
sdata->bss = &sdata->u.ap;
break;
case NL80211_IFTYPE_MESH_POINT:
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- /* mesh ifaces must set allmulti to forward mcast traffic */
- atomic_inc(&local->iff_allmultis);
- break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_ADHOC:
@@ -225,6 +220,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
/* we're brought up, everything changes */
hw_reconf_flags = ~0;
ieee80211_led_radio(local, true);
+ ieee80211_mod_tpt_led_trig(local,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
}
/*
@@ -273,12 +270,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
goto err_stop;
}
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
- local->fif_other_bss++;
- ieee80211_configure_filter(local);
-
- ieee80211_start_mesh(sdata);
- } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll++;
local->fif_probe_req++;
@@ -503,18 +495,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
ieee80211_adjust_monitor_flags(sdata, -1);
ieee80211_configure_filter(local);
break;
- case NL80211_IFTYPE_MESH_POINT:
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
- /* other_bss and allmulti are always set on mesh
- * ifaces */
- local->fif_other_bss--;
- atomic_dec(&local->iff_allmultis);
-
- ieee80211_configure_filter(local);
-
- ieee80211_stop_mesh(sdata);
- }
- /* fall through */
default:
flush_work(&sdata->work);
/*
@@ -1204,12 +1184,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
if (ret)
goto fail;
- if (ieee80211_vif_is_mesh(&sdata->vif) &&
- params && params->mesh_id_len)
- ieee80211_sdata_set_mesh_id(sdata,
- params->mesh_id_len,
- params->mesh_id);
-
mutex_lock(&local->iflist_mtx);
list_add_tail_rcu(&sdata->list, &local->interfaces);
mutex_unlock(&local->iflist_mtx);
@@ -1292,6 +1266,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
int count = 0;
bool working = false, scanning = false;
struct ieee80211_work *wk;
+ unsigned int led_trig_start = 0, led_trig_stop = 0;
#ifdef CONFIG_PROVE_LOCKING
WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
@@ -1341,6 +1316,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
}
+ if (working || scanning)
+ led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
+ else
+ led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
+
+ if (count)
+ led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
+ else
+ led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
+
+ ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
+
if (working)
return ieee80211_idle_off(local, "working");
if (scanning)
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ccd676b2f599..8c02469b7176 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -30,19 +30,20 @@
* keys and per-station keys. Since each station belongs to an interface,
* each station key also belongs to that interface.
*
- * Hardware acceleration is done on a best-effort basis, for each key
- * that is eligible the hardware is asked to enable that key but if
- * it cannot do that they key is simply kept for software encryption.
- * There is currently no way of knowing this except by looking into
- * debugfs.
+ * Hardware acceleration is done on a best-effort basis for algorithms
+ * that are implemented in software, for each key the hardware is asked
+ * to enable that key for offloading but if it cannot do that the key is
+ * simply kept for software encryption (unless it is for an algorithm
+ * that isn't implemented in software).
+ * There is currently no way of knowing whether a key is handled in SW
+ * or HW except by looking into debugfs.
*
- * All key operations are protected internally.
- *
- * Within mac80211, key references are, just as STA structure references,
- * protected by RCU. Note, however, that some things are unprotected,
- * namely the key->sta dereferences within the hardware acceleration
- * functions. This means that sta_info_destroy() must remove the key
- * which waits for an RCU grace period.
+ * All key management is internally protected by a mutex. Within all
+ * other parts of mac80211, key references are, just as STA structure
+ * references, protected by RCU. Note, however, that some things are
+ * unprotected, namely the key->sta dereferences within the hardware
+ * acceleration functions. This means that sta_info_destroy() must
+ * remove the key which waits for an RCU grace period.
*/
static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -84,10 +85,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
goto out_unsupported;
sdata = key->sdata;
- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /*
+ * The driver doesn't know anything about VLAN interfaces.
+ * Hence, don't send GTKs for VLAN interfaces to the driver.
+ */
+ if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ goto out_unsupported;
sdata = container_of(sdata->bss,
struct ieee80211_sub_if_data,
u.ap);
+ }
ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
@@ -171,7 +179,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
EXPORT_SYMBOL_GPL(ieee80211_key_removed);
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
- int idx)
+ int idx, bool uni, bool multi)
{
struct ieee80211_key *key = NULL;
@@ -180,18 +188,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
key = sdata->keys[idx];
- rcu_assign_pointer(sdata->default_key, key);
+ if (uni)
+ rcu_assign_pointer(sdata->default_unicast_key, key);
+ if (multi)
+ rcu_assign_pointer(sdata->default_multicast_key, key);
- if (key) {
- ieee80211_debugfs_key_remove_default(key->sdata);
- ieee80211_debugfs_key_add_default(key->sdata);
- }
+ ieee80211_debugfs_key_update_default(sdata);
}
-void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
+ bool uni, bool multi)
{
mutex_lock(&sdata->local->key_mtx);
- __ieee80211_set_default_key(sdata, idx);
+ __ieee80211_set_default_key(sdata, idx, uni, multi);
mutex_unlock(&sdata->local->key_mtx);
}
@@ -208,10 +217,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
rcu_assign_pointer(sdata->default_mgmt_key, key);
- if (key) {
- ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
- ieee80211_debugfs_key_add_mgmt_default(key->sdata);
- }
+ ieee80211_debugfs_key_update_default(sdata);
}
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -229,7 +235,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
struct ieee80211_key *old,
struct ieee80211_key *new)
{
- int idx, defkey, defmgmtkey;
+ int idx;
+ bool defunikey, defmultikey, defmgmtkey;
if (new)
list_add(&new->list, &sdata->key_list);
@@ -250,29 +257,31 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
else
idx = new->conf.keyidx;
- defkey = old && sdata->default_key == old;
+ defunikey = old && sdata->default_unicast_key == old;
+ defmultikey = old && sdata->default_multicast_key == old;
defmgmtkey = old && sdata->default_mgmt_key == old;
- if (defkey && !new)
- __ieee80211_set_default_key(sdata, -1);
+ if (defunikey && !new)
+ __ieee80211_set_default_key(sdata, -1, true, false);
+ if (defmultikey && !new)
+ __ieee80211_set_default_key(sdata, -1, false, true);
if (defmgmtkey && !new)
__ieee80211_set_default_mgmt_key(sdata, -1);
rcu_assign_pointer(sdata->keys[idx], new);
- if (defkey && new)
- __ieee80211_set_default_key(sdata, new->conf.keyidx);
+ if (defunikey && new)
+ __ieee80211_set_default_key(sdata, new->conf.keyidx,
+ true, false);
+ if (defmultikey && new)
+ __ieee80211_set_default_key(sdata, new->conf.keyidx,
+ false, true);
if (defmgmtkey && new)
__ieee80211_set_default_mgmt_key(sdata,
new->conf.keyidx);
}
- if (old) {
- /*
- * We'll use an empty list to indicate that the key
- * has already been removed.
- */
- list_del_init(&old->list);
- }
+ if (old)
+ list_del(&old->list);
}
struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
@@ -366,6 +375,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
if (!key)
return;
+ /*
+ * Synchronize so the TX path can no longer be using
+ * this key before we free/remove it.
+ */
+ synchronize_rcu();
+
if (key->local)
ieee80211_key_disable_hw_accel(key);
@@ -407,8 +422,8 @@ int ieee80211_key_link(struct ieee80211_key *key,
struct sta_info *ap;
/*
- * We're getting a sta pointer in,
- * so must be under RCU read lock.
+ * We're getting a sta pointer in, so must be under
+ * appropriate locking for sta_info_get().
*/
/* same here, the AP could be using QoS */
@@ -502,11 +517,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
mutex_lock(&sdata->local->key_mtx);
- ieee80211_debugfs_key_remove_default(sdata);
ieee80211_debugfs_key_remove_mgmt_default(sdata);
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
__ieee80211_key_free(key);
+ ieee80211_debugfs_key_update_default(sdata);
+
mutex_unlock(&sdata->local->key_mtx);
}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 0db1c0f5f697..8106aa1b7466 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -138,7 +138,8 @@ int __must_check ieee80211_key_link(struct ieee80211_key *key,
struct sta_info *sta);
void ieee80211_key_free(struct ieee80211_local *local,
struct ieee80211_key *key);
-void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
+ bool uni, bool multi);
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
int idx);
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 063aad944246..4905eb8af572 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -54,12 +54,22 @@ void ieee80211_led_radio(struct ieee80211_local *local, bool enabled)
led_trigger_event(local->radio_led, LED_OFF);
}
+void ieee80211_led_names(struct ieee80211_local *local)
+{
+ snprintf(local->rx_led_name, sizeof(local->rx_led_name),
+ "%srx", wiphy_name(local->hw.wiphy));
+ snprintf(local->tx_led_name, sizeof(local->tx_led_name),
+ "%stx", wiphy_name(local->hw.wiphy));
+ snprintf(local->assoc_led_name, sizeof(local->assoc_led_name),
+ "%sassoc", wiphy_name(local->hw.wiphy));
+ snprintf(local->radio_led_name, sizeof(local->radio_led_name),
+ "%sradio", wiphy_name(local->hw.wiphy));
+}
+
void ieee80211_led_init(struct ieee80211_local *local)
{
local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (local->rx_led) {
- snprintf(local->rx_led_name, sizeof(local->rx_led_name),
- "%srx", wiphy_name(local->hw.wiphy));
local->rx_led->name = local->rx_led_name;
if (led_trigger_register(local->rx_led)) {
kfree(local->rx_led);
@@ -69,8 +79,6 @@ void ieee80211_led_init(struct ieee80211_local *local)
local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (local->tx_led) {
- snprintf(local->tx_led_name, sizeof(local->tx_led_name),
- "%stx", wiphy_name(local->hw.wiphy));
local->tx_led->name = local->tx_led_name;
if (led_trigger_register(local->tx_led)) {
kfree(local->tx_led);
@@ -80,8 +88,6 @@ void ieee80211_led_init(struct ieee80211_local *local)
local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (local->assoc_led) {
- snprintf(local->assoc_led_name, sizeof(local->assoc_led_name),
- "%sassoc", wiphy_name(local->hw.wiphy));
local->assoc_led->name = local->assoc_led_name;
if (led_trigger_register(local->assoc_led)) {
kfree(local->assoc_led);
@@ -91,14 +97,19 @@ void ieee80211_led_init(struct ieee80211_local *local)
local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (local->radio_led) {
- snprintf(local->radio_led_name, sizeof(local->radio_led_name),
- "%sradio", wiphy_name(local->hw.wiphy));
local->radio_led->name = local->radio_led_name;
if (led_trigger_register(local->radio_led)) {
kfree(local->radio_led);
local->radio_led = NULL;
}
}
+
+ if (local->tpt_led_trigger) {
+ if (led_trigger_register(&local->tpt_led_trigger->trig)) {
+ kfree(local->tpt_led_trigger);
+ local->tpt_led_trigger = NULL;
+ }
+ }
}
void ieee80211_led_exit(struct ieee80211_local *local)
@@ -119,15 +130,18 @@ void ieee80211_led_exit(struct ieee80211_local *local)
led_trigger_unregister(local->rx_led);
kfree(local->rx_led);
}
+
+ if (local->tpt_led_trigger) {
+ led_trigger_unregister(&local->tpt_led_trigger->trig);
+ kfree(local->tpt_led_trigger);
+ }
}
char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- if (local->radio_led)
- return local->radio_led_name;
- return NULL;
+ return local->radio_led_name;
}
EXPORT_SYMBOL(__ieee80211_get_radio_led_name);
@@ -135,9 +149,7 @@ char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- if (local->assoc_led)
- return local->assoc_led_name;
- return NULL;
+ return local->assoc_led_name;
}
EXPORT_SYMBOL(__ieee80211_get_assoc_led_name);
@@ -145,9 +157,7 @@ char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- if (local->tx_led)
- return local->tx_led_name;
- return NULL;
+ return local->tx_led_name;
}
EXPORT_SYMBOL(__ieee80211_get_tx_led_name);
@@ -155,8 +165,144 @@ char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- if (local->rx_led)
- return local->rx_led_name;
- return NULL;
+ return local->rx_led_name;
}
EXPORT_SYMBOL(__ieee80211_get_rx_led_name);
+
+static unsigned long tpt_trig_traffic(struct ieee80211_local *local,
+ struct tpt_led_trigger *tpt_trig)
+{
+ unsigned long traffic, delta;
+
+ traffic = tpt_trig->tx_bytes + tpt_trig->rx_bytes;
+
+ delta = traffic - tpt_trig->prev_traffic;
+ tpt_trig->prev_traffic = traffic;
+ return DIV_ROUND_UP(delta, 1024 / 8);
+}
+
+static void tpt_trig_timer(unsigned long data)
+{
+ struct ieee80211_local *local = (void *)data;
+ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+ struct led_classdev *led_cdev;
+ unsigned long on, off, tpt;
+ int i;
+
+ if (!tpt_trig->running)
+ return;
+
+ mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
+
+ tpt = tpt_trig_traffic(local, tpt_trig);
+
+ /* default to just solid on */
+ on = 1;
+ off = 0;
+
+ for (i = tpt_trig->blink_table_len - 1; i >= 0; i--) {
+ if (tpt_trig->blink_table[i].throughput < 0 ||
+ tpt > tpt_trig->blink_table[i].throughput) {
+ off = tpt_trig->blink_table[i].blink_time / 2;
+ on = tpt_trig->blink_table[i].blink_time - off;
+ break;
+ }
+ }
+
+ read_lock(&tpt_trig->trig.leddev_list_lock);
+ list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list)
+ led_blink_set(led_cdev, &on, &off);
+ read_unlock(&tpt_trig->trig.leddev_list_lock);
+}
+
+extern char *__ieee80211_create_tpt_led_trigger(
+ struct ieee80211_hw *hw, unsigned int flags,
+ const struct ieee80211_tpt_blink *blink_table,
+ unsigned int blink_table_len)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct tpt_led_trigger *tpt_trig;
+
+ if (WARN_ON(local->tpt_led_trigger))
+ return NULL;
+
+ tpt_trig = kzalloc(sizeof(struct tpt_led_trigger), GFP_KERNEL);
+ if (!tpt_trig)
+ return NULL;
+
+ snprintf(tpt_trig->name, sizeof(tpt_trig->name),
+ "%stpt", wiphy_name(local->hw.wiphy));
+
+ tpt_trig->trig.name = tpt_trig->name;
+
+ tpt_trig->blink_table = blink_table;
+ tpt_trig->blink_table_len = blink_table_len;
+ tpt_trig->want = flags;
+
+ setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local);
+
+ local->tpt_led_trigger = tpt_trig;
+
+ return tpt_trig->name;
+}
+EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger);
+
+static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
+{
+ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+
+ if (tpt_trig->running)
+ return;
+
+ /* reset traffic */
+ tpt_trig_traffic(local, tpt_trig);
+ tpt_trig->running = true;
+
+ tpt_trig_timer((unsigned long)local);
+ mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
+}
+
+static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
+{
+ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+ struct led_classdev *led_cdev;
+
+ if (!tpt_trig->running)
+ return;
+
+ tpt_trig->running = false;
+ del_timer_sync(&tpt_trig->timer);
+
+ read_lock(&tpt_trig->trig.leddev_list_lock);
+ list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list)
+ led_brightness_set(led_cdev, LED_OFF);
+ read_unlock(&tpt_trig->trig.leddev_list_lock);
+}
+
+void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
+ unsigned int types_on, unsigned int types_off)
+{
+ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+ bool allowed;
+
+ WARN_ON(types_on & types_off);
+
+ if (!tpt_trig)
+ return;
+
+ tpt_trig->active &= ~types_off;
+ tpt_trig->active |= types_on;
+
+ /*
+ * Regardless of wanted state, we shouldn't blink when
+ * the radio is disabled -- this can happen due to some
+ * code ordering issues with __ieee80211_recalc_idle()
+ * being called before the radio is started.
+ */
+ allowed = tpt_trig->active & IEEE80211_TPT_LEDTRIG_FL_RADIO;
+
+ if (!allowed || !(tpt_trig->active & tpt_trig->want))
+ ieee80211_stop_tpt_led_trig(local);
+ else
+ ieee80211_start_tpt_led_trig(local);
+}
diff --git a/net/mac80211/led.h b/net/mac80211/led.h
index 77b1e1ba6039..e0275d9befa8 100644
--- a/net/mac80211/led.h
+++ b/net/mac80211/led.h
@@ -12,14 +12,17 @@
#include "ieee80211_i.h"
#ifdef CONFIG_MAC80211_LEDS
-extern void ieee80211_led_rx(struct ieee80211_local *local);
-extern void ieee80211_led_tx(struct ieee80211_local *local, int q);
-extern void ieee80211_led_assoc(struct ieee80211_local *local,
- bool associated);
-extern void ieee80211_led_radio(struct ieee80211_local *local,
- bool enabled);
-extern void ieee80211_led_init(struct ieee80211_local *local);
-extern void ieee80211_led_exit(struct ieee80211_local *local);
+void ieee80211_led_rx(struct ieee80211_local *local);
+void ieee80211_led_tx(struct ieee80211_local *local, int q);
+void ieee80211_led_assoc(struct ieee80211_local *local,
+ bool associated);
+void ieee80211_led_radio(struct ieee80211_local *local,
+ bool enabled);
+void ieee80211_led_names(struct ieee80211_local *local);
+void ieee80211_led_init(struct ieee80211_local *local);
+void ieee80211_led_exit(struct ieee80211_local *local);
+void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
+ unsigned int types_on, unsigned int types_off);
#else
static inline void ieee80211_led_rx(struct ieee80211_local *local)
{
@@ -35,10 +38,36 @@ static inline void ieee80211_led_radio(struct ieee80211_local *local,
bool enabled)
{
}
+static inline void ieee80211_led_names(struct ieee80211_local *local)
+{
+}
static inline void ieee80211_led_init(struct ieee80211_local *local)
{
}
static inline void ieee80211_led_exit(struct ieee80211_local *local)
{
}
+static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
+ unsigned int types_on,
+ unsigned int types_off)
+{
+}
+#endif
+
+static inline void
+ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes)
+{
+#ifdef CONFIG_MAC80211_LEDS
+ if (local->tpt_led_trigger && ieee80211_is_data(fc))
+ local->tpt_led_trigger->tx_bytes += bytes;
+#endif
+}
+
+static inline void
+ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes)
+{
+#ifdef CONFIG_MAC80211_LEDS
+ if (local->tpt_led_trigger && ieee80211_is_data(fc))
+ local->tpt_led_trigger->rx_bytes += bytes;
#endif
+}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 107a0cbe52ac..4b088b3c25e8 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -245,9 +245,12 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.enable_beacon =
!!sdata->u.ibss.presp;
break;
+#ifdef CONFIG_MAC80211_MESH
case NL80211_IFTYPE_MESH_POINT:
- sdata->vif.bss_conf.enable_beacon = true;
+ sdata->vif.bss_conf.enable_beacon =
+ !!sdata->u.mesh.mesh_id_len;
break;
+#endif
default:
/* not reached */
WARN_ON(1);
@@ -481,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
BIT(IEEE80211_STYPE_ACTION >> 4),
},
+ [NL80211_IFTYPE_MESH_POINT] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+ },
};
struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
@@ -514,10 +521,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;
+ wiphy->privid = mac80211_wiphy_privid;
+
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_4ADDR_AP |
- WIPHY_FLAG_4ADDR_STATION;
- wiphy->privid = mac80211_wiphy_privid;
+ WIPHY_FLAG_4ADDR_STATION |
+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
+
+ if (!ops->set_key)
+ wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
@@ -557,6 +569,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
spin_lock_init(&local->filter_lock);
spin_lock_init(&local->queue_stop_reason_lock);
+ skb_queue_head_init(&local->rx_skb_queue);
+
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
ieee80211_work_init(local);
@@ -593,6 +607,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
/* init dummy netdev for use w/ NAPI */
init_dummy_netdev(&local->napi_dev);
+ ieee80211_led_names(local);
+
return local_to_hw(local);
}
EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -737,6 +753,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
}
}
+ local->hw.wiphy->max_remain_on_channel_duration = 5000;
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
@@ -898,6 +916,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
skb_queue_purge(&local->skb_queue);
skb_queue_purge(&local->skb_queue_unreliable);
+ skb_queue_purge(&local->rx_skb_queue);
destroy_workqueue(local->workqueue);
wiphy_unregister(local->hw.wiphy);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c8a4f19ed13b..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
}
-void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
-{
- sta->mesh_pp_id = 0; /* HWMP */
- sta->mesh_pm_id = 0; /* Airtime */
- sta->mesh_cc_id = 0; /* Disabled */
- sta->mesh_sp_id = 0; /* Neighbor Offset */
- sta->mesh_auth_id = 0; /* Disabled */
-}
-
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
{
int i;
@@ -287,6 +278,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
*pos++ |= sdata->u.mesh.accepting_plinks ?
MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
*pos++ = 0x00;
+
+ if (sdata->u.mesh.vendor_ie) {
+ int len = sdata->u.mesh.vendor_ie_len;
+ const u8 *data = sdata->u.mesh.vendor_ie;
+ if (skb_tailroom(skb) > len)
+ memcpy(skb_put(skb, len), data, len);
+ }
}
u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
@@ -412,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
* ieee80211_new_mesh_header - create a new mesh header
* @meshhdr: uninitialized mesh header
* @sdata: mesh interface to be used
- * @addr4: addr4 of the mesh frame (1st in ae header)
- * may be NULL
- * @addr5: addr5 of the mesh frame (1st or 2nd in ae header)
- * may be NULL unless addr6 is present
- * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header)
- * may be NULL unless addr5 is present
+ * @addr4or5: 1st address in the ae header, which may correspond to address 4
+ * (if addr6 is NULL) or address 5 (if addr6 is present). It may
+ * be NULL.
+ * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
+ * mesh frame
*
* Return the header length.
*/
int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
- struct ieee80211_sub_if_data *sdata, char *addr4,
- char *addr5, char *addr6)
+ struct ieee80211_sub_if_data *sdata, char *addr4or5,
+ char *addr6)
{
int aelen = 0;
+ BUG_ON(!addr4or5 && addr6);
memset(meshhdr, 0, sizeof(*meshhdr));
meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
sdata->u.mesh.mesh_seqnum++;
- if (addr4) {
+ if (addr4or5 && !addr6) {
meshhdr->flags |= MESH_FLAGS_AE_A4;
aelen += ETH_ALEN;
- memcpy(meshhdr->eaddr1, addr4, ETH_ALEN);
- }
- if (addr5 && addr6) {
+ memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
+ } else if (addr4or5 && addr6) {
meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
aelen += 2 * ETH_ALEN;
- if (!addr4) {
- memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
- memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
- } else {
- memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
- memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
- }
+ memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
+ memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
}
return 6 + aelen;
}
@@ -513,6 +505,14 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
+ local->fif_other_bss++;
+ /* mesh ifaces must set allmulti to forward mcast traffic */
+ atomic_inc(&local->iff_allmultis);
+ ieee80211_configure_filter(local);
+
+ ifmsh->mesh_cc_id = 0; /* Disabled */
+ ifmsh->mesh_sp_id = 0; /* Neighbor Offset */
+ ifmsh->mesh_auth_id = 0; /* Disabled */
set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
ieee80211_mesh_root_setup(ifmsh);
ieee80211_queue_work(&local->hw, &sdata->work);
@@ -524,6 +524,13 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+
+ ifmsh->mesh_id_len = 0;
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+ sta_info_flush(local, NULL);
+
del_timer_sync(&sdata->u.mesh.housekeeping_timer);
del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
/*
@@ -534,6 +541,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
* it no longer is.
*/
cancel_work_sync(&sdata->work);
+
+ local->fif_other_bss--;
+ atomic_dec(&local->iff_allmultis);
+ ieee80211_configure_filter(local);
}
static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
@@ -663,26 +674,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
ieee80211_mesh_housekeeping_timer,
(unsigned long) sdata);
- ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T;
- ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T;
- ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T;
- ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR;
- ifmsh->mshcfg.dot11MeshTTL = MESH_TTL;
- ifmsh->mshcfg.auto_open_plinks = true;
- ifmsh->mshcfg.dot11MeshMaxPeerLinks =
- MESH_MAX_ESTAB_PLINKS;
- ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout =
- MESH_PATH_TIMEOUT;
- ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval =
- MESH_PREQ_MIN_INT;
- ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime =
- MESH_DIAM_TRAVERSAL_TIME;
- ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries =
- MESH_MAX_PREQ_RETRIES;
- ifmsh->mshcfg.path_refresh_time =
- MESH_PATH_REFRESH_TIME;
- ifmsh->mshcfg.min_discovery_timeout =
- MESH_MIN_DISCOVERY_TIMEOUT;
ifmsh->accepting_plinks = true;
ifmsh->preq_id = 0;
ifmsh->sn = 0;
@@ -692,7 +683,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
/* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated)
ieee80211s_init();
- mesh_ids_set_default(ifmsh);
setup_timer(&ifmsh->mesh_path_timer,
ieee80211_mesh_path_timer,
(unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 58e741128968..b99e230fe31c 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -164,44 +164,10 @@ struct mesh_rmc {
};
-/*
- * MESH_CFG_COMP_LEN Includes:
- * - Active path selection protocol ID.
- * - Active path selection metric ID.
- * - Congestion control mode identifier.
- * - Channel precedence.
- * Does not include mesh capabilities, which may vary across nodes in the same
- * mesh
- */
-#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2)
-
-/* Default values, timeouts in ms */
-#define MESH_TTL 31
-#define MESH_MAX_RETR 3
-#define MESH_RET_T 100
-#define MESH_CONF_T 100
-#define MESH_HOLD_T 100
-
-#define MESH_PATH_TIMEOUT 5000
-/* Minimum interval between two consecutive PREQs originated by the same
- * interface
- */
-#define MESH_PREQ_MIN_INT 10
-#define MESH_DIAM_TRAVERSAL_TIME 50
-/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before
- * timing out. This way it will remain ACTIVE and no data frames will be
- * unnecesarily held in the pending queue.
- */
-#define MESH_PATH_REFRESH_TIME 1000
-#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
-#define MESH_MAX_PREQ_RETRIES 4
#define MESH_PATH_EXPIRE (600 * HZ)
-/* Default maximum number of established plinks per interface */
-#define MESH_MAX_ESTAB_PLINKS 32
-
/* Default maximum number of plinks per interface */
#define MESH_MAX_PLINKS 256
@@ -221,8 +187,8 @@ struct mesh_rmc {
int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
const u8 *da, const u8 *sa);
int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
- struct ieee80211_sub_if_data *sdata, char *addr4,
- char *addr5, char *addr6);
+ struct ieee80211_sub_if_data *sdata, char *addr4or5,
+ char *addr6);
int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
struct ieee80211_sub_if_data *sdata);
bool mesh_matches_local(struct ieee802_11_elems *ie,
@@ -318,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
}
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{
+ return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+}
+
#define for_each_mesh_entry(x, p, node, i) \
for (i = 0; i <= x->hash_mask; i++) \
hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -338,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
{}
static inline void mesh_plink_quiesce(struct sta_info *sta) {}
static inline void mesh_plink_restart(struct sta_info *sta) {}
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{ return false; }
#endif
#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 829e08a657d0..5bf64d7112b3 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -232,7 +232,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
*pos++ = WLAN_EID_PERR;
*pos++ = ie_len;
/* ttl */
- *pos++ = MESH_TTL;
+ *pos++ = ttl;
/* number of destinations */
*pos++ = 1;
/*
@@ -522,7 +522,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
if (reply) {
lifetime = PREQ_IE_LIFETIME(preq_elem);
- ttl = ifmsh->mshcfg.dot11MeshTTL;
+ ttl = ifmsh->mshcfg.element_ttl;
if (ttl != 0) {
mhwmp_dbg("replying to the PREQ\n");
mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr,
@@ -877,7 +877,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
sdata->u.mesh.last_sn_update = jiffies;
}
lifetime = default_lifetime(sdata);
- ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
+ ttl = sdata->u.mesh.mshcfg.element_ttl;
if (ttl == 0) {
sdata->u.mesh.mshstats.dropped_frames_ttl++;
spin_unlock_bh(&mpath->state_lock);
@@ -1013,5 +1013,6 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr,
cpu_to_le32(++ifmsh->sn),
0, NULL, 0, broadcast_addr,
- 0, MESH_TTL, 0, 0, 0, sdata);
+ 0, sdata->u.mesh.mshcfg.element_ttl,
+ 0, 0, 0, sdata);
}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 349e466cf08b..8d65b47d9837 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -467,8 +467,8 @@ void mesh_plink_broken(struct sta_info *sta)
mpath->flags &= ~MESH_PATH_ACTIVE;
++mpath->sn;
spin_unlock_bh(&mpath->state_lock);
- mesh_path_error_tx(MESH_TTL, mpath->dst,
- cpu_to_le32(mpath->sn),
+ mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
+ mpath->dst, cpu_to_le32(mpath->sn),
cpu_to_le16(PERR_RCODE_DEST_UNREACH),
bcast, sdata);
} else
@@ -614,7 +614,8 @@ void mesh_path_discard_frame(struct sk_buff *skb,
mpath = mesh_path_lookup(da, sdata);
if (mpath)
sn = ++mpath->sn;
- mesh_path_error_tx(MESH_TTL, skb->data, cpu_to_le32(sn),
+ mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data,
+ cpu_to_le32(sn),
cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata);
}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1c91f0f3c307..44b53931ba5e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -160,7 +160,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
__le16 reason) {
struct ieee80211_local *local = sdata->local;
- struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
+ struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
+ sdata->u.mesh.vendor_ie_len);
struct ieee80211_mgmt *mgmt;
bool include_plid = false;
static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a3a9421555af..45fbb9e33746 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -28,13 +28,19 @@
#include "rate.h"
#include "led.h"
+#define IEEE80211_MAX_NULLFUNC_TRIES 2
#define IEEE80211_MAX_PROBE_TRIES 5
/*
- * beacon loss detection timeout
- * XXX: should depend on beacon interval
+ * Beacon loss timeout is calculated as N frames times the
+ * advertised beacon interval. This may need to be somewhat
+ * higher than what hardware might detect to account for
+ * delays in the host processing frames. But since we also
+ * probe on beacon miss before declaring the connection lost
+ * default to what we want.
*/
-#define IEEE80211_BEACON_LOSS_TIME (2 * HZ)
+#define IEEE80211_BEACON_LOSS_COUNT 7
+
/*
* Time the connection can be idle before we probe
* it to see if we can still talk to the AP.
@@ -121,7 +127,7 @@ void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
return;
mod_timer(&sdata->u.mgd.bcn_mon_timer,
- round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
+ round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
}
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
@@ -619,11 +625,12 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
/*
* Go to full PSM if the user configures a very low
* latency requirement.
- * The 2 second value is there for compatibility until
- * the PM_QOS_NETWORK_LATENCY is configured with real
- * values.
+ * The 2000 second value is there for compatibility
+ * until the PM_QOS_NETWORK_LATENCY is configured
+ * with real values.
*/
- if (latency > 1900000000 && latency != 2000000000)
+ if (latency > (1900 * USEC_PER_MSEC) &&
+ latency != (2000 * USEC_PER_SEC))
timeout = 0;
else
timeout = 100;
@@ -871,6 +878,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
cbss->capability, bss->has_erp_value, bss->erp_value);
+ sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
+ IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
+
sdata->u.mgd.associated = cbss;
memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
@@ -1026,6 +1036,54 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_reset_conn_monitor(sdata);
}
+static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+ if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+ IEEE80211_STA_CONNECTION_POLL)))
+ return;
+
+ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+ IEEE80211_STA_BEACON_POLL);
+ mutex_lock(&sdata->local->iflist_mtx);
+ ieee80211_recalc_ps(sdata->local, -1);
+ mutex_unlock(&sdata->local->iflist_mtx);
+
+ if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+ return;
+
+ /*
+ * We've received a probe response, but are not sure whether
+ * we have or will be receiving any beacons or data, so let's
+ * schedule the timers again, just in case.
+ */
+ ieee80211_sta_reset_beacon_monitor(sdata);
+
+ mod_timer(&ifmgd->conn_mon_timer,
+ round_jiffies_up(jiffies +
+ IEEE80211_CONNECTION_IDLE_TIME));
+}
+
+void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr, bool ack)
+{
+ if (!ieee80211_is_data(hdr->frame_control))
+ return;
+
+ if (ack)
+ ieee80211_sta_reset_conn_monitor(sdata);
+
+ if (ieee80211_is_nullfunc(hdr->frame_control) &&
+ sdata->u.mgd.probe_send_count > 0) {
+ if (ack)
+ sdata->u.mgd.probe_send_count = 0;
+ else
+ sdata->u.mgd.nullfunc_failed = true;
+ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+ }
+}
+
static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1041,8 +1099,20 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
if (ifmgd->probe_send_count >= unicast_limit)
dst = NULL;
- ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
- ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
+ /*
+ * When the hardware reports an accurate Tx ACK status, it's
+ * better to send a nullfunc frame instead of a probe request,
+ * as it will kick us off the AP quickly if we aren't associated
+ * anymore. The timeout will be reset if the frame is ACKed by
+ * the AP.
+ */
+ if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
+ ifmgd->nullfunc_failed = false;
+ ieee80211_send_nullfunc(sdata->local, sdata, 0);
+ } else {
+ ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
+ ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
+ }
ifmgd->probe_send_count++;
ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
@@ -1108,6 +1178,30 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&ifmgd->mtx);
}
+struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct sk_buff *skb;
+ const u8 *ssid;
+
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+ return NULL;
+
+ ASSERT_MGD_MTX(ifmgd);
+
+ if (!ifmgd->associated)
+ return NULL;
+
+ ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
+ skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
+ ssid + 2, ssid[1], NULL, 0);
+
+ return skb;
+}
+EXPORT_SYMBOL(ieee80211_ap_probereq_get);
+
static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1485,29 +1579,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
if (ifmgd->associated &&
- memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
- ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL)) {
- ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
- IEEE80211_STA_BEACON_POLL);
- mutex_lock(&sdata->local->iflist_mtx);
- ieee80211_recalc_ps(sdata->local, -1);
- mutex_unlock(&sdata->local->iflist_mtx);
-
- if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
- return;
-
- /*
- * We've received a probe response, but are not sure whether
- * we have or will be receiving any beacons or data, so let's
- * schedule the timers again, just in case.
- */
- ieee80211_sta_reset_beacon_monitor(sdata);
-
- mod_timer(&ifmgd->conn_mon_timer,
- round_jiffies_up(jiffies +
- IEEE80211_CONNECTION_IDLE_TIME));
- }
+ memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
+ ieee80211_reset_ap_probe(sdata);
}
/*
@@ -1845,6 +1918,31 @@ static void ieee80211_sta_timer(unsigned long data)
ieee80211_queue_work(&local->hw, &sdata->work);
}
+static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
+ u8 *bssid)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+ IEEE80211_STA_BEACON_POLL);
+
+ ieee80211_set_disassoc(sdata, true, true);
+ mutex_unlock(&ifmgd->mtx);
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
+ /*
+ * must be outside lock due to cfg80211,
+ * but that's not a problem.
+ */
+ ieee80211_send_deauth_disassoc(sdata, bssid,
+ IEEE80211_STYPE_DEAUTH,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+ NULL, true);
+ mutex_lock(&ifmgd->mtx);
+}
+
void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
@@ -1857,12 +1955,49 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
IEEE80211_STA_CONNECTION_POLL) &&
ifmgd->associated) {
u8 bssid[ETH_ALEN];
+ int max_tries;
memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
- if (time_is_after_jiffies(ifmgd->probe_timeout))
- run_again(ifmgd, ifmgd->probe_timeout);
- else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+ max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
+ else
+ max_tries = IEEE80211_MAX_PROBE_TRIES;
+
+ /* ACK received for nullfunc probing frame */
+ if (!ifmgd->probe_send_count)
+ ieee80211_reset_ap_probe(sdata);
+ else if (ifmgd->nullfunc_failed) {
+ if (ifmgd->probe_send_count < max_tries) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ wiphy_debug(local->hw.wiphy,
+ "%s: No ack for nullfunc frame to"
+ " AP %pM, try %d\n",
+ sdata->name, bssid,
+ ifmgd->probe_send_count);
+#endif
+ ieee80211_mgd_probe_ap_send(sdata);
+ } else {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ wiphy_debug(local->hw.wiphy,
+ "%s: No ack for nullfunc frame to"
+ " AP %pM, disconnecting.\n",
+ sdata->name, bssid);
+#endif
+ ieee80211_sta_connection_lost(sdata, bssid);
+ }
+ } else if (time_is_after_jiffies(ifmgd->probe_timeout))
+ run_again(ifmgd, ifmgd->probe_timeout);
+ else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ wiphy_debug(local->hw.wiphy,
+ "%s: Failed to send nullfunc to AP %pM"
+ " after %dms, disconnecting.\n",
+ sdata->name,
+ bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+#endif
+ ieee80211_sta_connection_lost(sdata, bssid);
+ } else if (ifmgd->probe_send_count < max_tries) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
wiphy_debug(local->hw.wiphy,
"%s: No probe response from AP %pM"
@@ -1877,27 +2012,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
* We actually lost the connection ... or did we?
* Let's make sure!
*/
- ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
- IEEE80211_STA_BEACON_POLL);
wiphy_debug(local->hw.wiphy,
"%s: No probe response from AP %pM"
" after %dms, disconnecting.\n",
sdata->name,
bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
- ieee80211_set_disassoc(sdata, true, true);
- mutex_unlock(&ifmgd->mtx);
- mutex_lock(&local->mtx);
- ieee80211_recalc_idle(local);
- mutex_unlock(&local->mtx);
- /*
- * must be outside lock due to cfg80211,
- * but that's not a problem.
- */
- ieee80211_send_deauth_disassoc(sdata, bssid,
- IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
- NULL, true);
- mutex_lock(&ifmgd->mtx);
+
+ ieee80211_sta_connection_lost(sdata, bssid);
}
}
@@ -1988,6 +2109,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
add_timer(&ifmgd->timer);
if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
add_timer(&ifmgd->chswitch_timer);
+ ieee80211_sta_reset_beacon_monitor(sdata);
+ ieee80211_restart_sta_timer(sdata);
}
#endif
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 33f76993da08..3d5a2cb835c4 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -211,7 +211,8 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc);
}
-static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx)
+static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
+ struct ieee80211_supported_band *sband)
{
u8 i;
@@ -222,7 +223,7 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx)
if (basic_rates & (1 << *idx))
return; /* selected rate is a basic rate */
- for (i = *idx + 1; i <= max_rate_idx; i++) {
+ for (i = *idx + 1; i <= sband->n_bitrates; i++) {
if (basic_rates & (1 << i)) {
*idx = i;
return;
@@ -237,16 +238,25 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
struct ieee80211_tx_rate_control *txrc)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
+ struct ieee80211_supported_band *sband = txrc->sband;
+ int mcast_rate;
if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta);
info->control.rates[0].count =
(info->flags & IEEE80211_TX_CTL_NO_ACK) ?
1 : txrc->hw->max_rate_tries;
- if (!sta && txrc->ap)
+ if (!sta && txrc->bss) {
+ mcast_rate = txrc->bss_conf->mcast_rate[sband->band];
+ if (mcast_rate > 0) {
+ info->control.rates[0].idx = mcast_rate - 1;
+ return true;
+ }
+
rc_send_low_broadcast(&info->control.rates[0].idx,
txrc->bss_conf->basic_rates,
- txrc->sband->n_bitrates);
+ sband);
+ }
return true;
}
return false;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 2a18d6602d4a..165a4518bb48 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -371,7 +371,10 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru
if (likely(sta->ampdu_mlme.tid_tx[tid]))
return;
- ieee80211_start_tx_ba_session(pubsta, tid);
+ if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
+ return;
+
+ ieee80211_start_tx_ba_session(pubsta, tid, 5000);
}
static void
@@ -407,8 +410,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
mi->ampdu_len += info->status.ampdu_len;
if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
- mi->sample_wait = 4 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
- mi->sample_tries = 3;
+ mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
+ mi->sample_tries = 2;
mi->sample_count--;
}
@@ -506,7 +509,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
if (!mr->retry_updated)
minstrel_calc_retransmit(mp, mi, index);
- if (mr->probability < MINSTREL_FRAC(20, 100))
+ if (sample)
+ rate->count = 1;
+ else if (mr->probability < MINSTREL_FRAC(20, 100))
rate->count = 2;
else if (rtscts)
rate->count = mr->retry_count_rtscts;
@@ -562,7 +567,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
*/
if (minstrel_get_duration(sample_idx) >
minstrel_get_duration(mi->max_tp_rate)) {
- if (mr->sample_skipped < 10)
+ if (mr->sample_skipped < 20)
goto next;
if (mi->sample_slow++ > 2)
@@ -586,6 +591,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct minstrel_ht_sta *mi = &msp->ht;
struct minstrel_priv *mp = priv;
int sample_idx;
+ bool sample = false;
if (rate_control_send_low(sta, priv_sta, txrc))
return;
@@ -596,10 +602,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
info->flags |= mi->tx_flags;
sample_idx = minstrel_get_sample_rate(mp, mi);
if (sample_idx >= 0) {
+ sample = true;
minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
txrc, true, false);
minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
- txrc, false, true);
+ txrc, false, false);
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
} else {
minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
@@ -607,7 +614,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
txrc, false, true);
}
- minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, true);
+ minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, !sample);
ar[3].count = 0;
ar[3].idx = -1;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 902b03ee8f60..a6701ed87f0d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -533,10 +533,13 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
- int index,
- struct sk_buff_head *frames)
+ int index)
{
+ struct ieee80211_local *local = hw_to_local(hw);
struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
+ struct ieee80211_rx_status *status;
+
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
if (!skb)
goto no_frame;
@@ -544,7 +547,9 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
/* release the frame from the reorder ring buffer */
tid_agg_rx->stored_mpdu_num--;
tid_agg_rx->reorder_buf[index] = NULL;
- __skb_queue_tail(frames, skb);
+ status = IEEE80211_SKB_RXCB(skb);
+ status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
+ skb_queue_tail(&local->rx_skb_queue, skb);
no_frame:
tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
@@ -552,15 +557,16 @@ no_frame:
static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
- u16 head_seq_num,
- struct sk_buff_head *frames)
+ u16 head_seq_num)
{
int index;
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
+
while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
- ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
}
}
@@ -576,11 +582,12 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
- struct tid_ampdu_rx *tid_agg_rx,
- struct sk_buff_head *frames)
+ struct tid_ampdu_rx *tid_agg_rx)
{
int index, j;
+ lockdep_assert_held(&tid_agg_rx->reorder_lock);
+
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
@@ -606,8 +613,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
wiphy_debug(hw->wiphy,
"release an RX reorder frame due to timeout on earlier frames\n");
#endif
- ieee80211_release_reorder_frame(hw, tid_agg_rx,
- j, frames);
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
/*
* Increment the head seq# also for the skipped slots.
@@ -617,31 +623,11 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
skipped = 0;
}
} else while (tid_agg_rx->reorder_buf[index]) {
- ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
}
- /*
- * Disable the reorder release timer for now.
- *
- * The current implementation lacks a proper locking scheme
- * which would protect vital statistic and debug counters
- * from being updated by two different but concurrent BHs.
- *
- * More information about the topic is available from:
- * - thread: http://marc.info/?t=128635927000001
- *
- * What was wrong:
- * => http://marc.info/?l=linux-wireless&m=128636170811964
- * "Basically the thing is that until your patch, the data
- * in the struct didn't actually need locking because it
- * was accessed by the RX path only which is not concurrent."
- *
- * List of what needs to be fixed:
- * => http://marc.info/?l=linux-wireless&m=128656352920957
- *
-
if (tid_agg_rx->stored_mpdu_num) {
j = index = seq_sub(tid_agg_rx->head_seq_num,
tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -660,10 +646,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
} else {
del_timer(&tid_agg_rx->reorder_timer);
}
- */
-
-set_release_timer:
- return;
}
/*
@@ -673,8 +655,7 @@ set_release_timer:
*/
static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
- struct sk_buff *skb,
- struct sk_buff_head *frames)
+ struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u16 sc = le16_to_cpu(hdr->seq_ctrl);
@@ -683,10 +664,11 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
int index;
bool ret = true;
+ spin_lock(&tid_agg_rx->reorder_lock);
+
buf_size = tid_agg_rx->buf_size;
head_seq_num = tid_agg_rx->head_seq_num;
- spin_lock(&tid_agg_rx->reorder_lock);
/* frame with out of date sequence number */
if (seq_less(mpdu_seq_num, head_seq_num)) {
dev_kfree_skb(skb);
@@ -700,8 +682,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) {
head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
/* release stored frames up to new head to stack */
- ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num,
- frames);
+ ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num);
}
/* Now the new frame is always in the range of the reordering buffer */
@@ -729,7 +710,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
tid_agg_rx->reorder_buf[index] = skb;
tid_agg_rx->reorder_time[index] = jiffies;
tid_agg_rx->stored_mpdu_num++;
- ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
+ ieee80211_sta_reorder_release(hw, tid_agg_rx);
out:
spin_unlock(&tid_agg_rx->reorder_lock);
@@ -740,8 +721,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
* Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
* true if the MPDU was buffered, false if it should be processed.
*/
-static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
- struct sk_buff_head *frames)
+static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
{
struct sk_buff *skb = rx->skb;
struct ieee80211_local *local = rx->local;
@@ -796,11 +776,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
* sure that we cannot get to it any more before doing
* anything with it.
*/
- if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames))
+ if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb))
return;
dont_reorder:
- __skb_queue_tail(frames, skb);
+ skb_queue_tail(&local->rx_skb_queue, skb);
}
static ieee80211_rx_result debug_noinline
@@ -948,12 +928,31 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
* have been expected.
*/
struct ieee80211_key *key = NULL;
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ int i;
+
if (ieee80211_is_mgmt(fc) &&
is_multicast_ether_addr(hdr->addr1) &&
(key = rcu_dereference(rx->sdata->default_mgmt_key)))
rx->key = key;
- else if ((key = rcu_dereference(rx->sdata->default_key)))
- rx->key = key;
+ else {
+ if (rx->sta) {
+ for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ key = rcu_dereference(rx->sta->gtk[i]);
+ if (key)
+ break;
+ }
+ }
+ if (!key) {
+ for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ key = rcu_dereference(sdata->keys[i]);
+ if (key)
+ break;
+ }
+ }
+ if (key)
+ rx->key = key;
+ }
return RX_CONTINUE;
} else {
u8 keyid;
@@ -1102,8 +1101,6 @@ static void ap_sta_ps_end(struct sta_info *sta)
atomic_dec(&sdata->bss->num_sta_ps);
- clear_sta_flags(sta, WLAN_STA_PS_STA);
-
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
sdata->name, sta->sta.addr, sta->sta.aid);
@@ -1158,12 +1155,14 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
sta->rx_fragments++;
sta->rx_bytes += rx->skb->len;
sta->last_signal = status->signal;
+ ewma_add(&sta->avg_signal, -status->signal);
/*
* Change STA power saving mode only at the end of a frame
* exchange sequence.
*/
if (!ieee80211_has_morefrags(hdr->frame_control) &&
+ !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
if (test_sta_flags(sta, WLAN_STA_PS_STA)) {
@@ -1515,12 +1514,30 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
if (unlikely(!ieee80211_has_protected(fc) &&
ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
- rx->key))
+ rx->key)) {
+ if (ieee80211_is_deauth(fc))
+ cfg80211_send_unprot_deauth(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
+ else if (ieee80211_is_disassoc(fc))
+ cfg80211_send_unprot_disassoc(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
return -EACCES;
+ }
/* BIP does not use Protected field, so need to check MMIE */
if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
- ieee80211_get_mmie_keyidx(rx->skb) < 0))
+ ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
+ if (ieee80211_is_deauth(fc))
+ cfg80211_send_unprot_deauth(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
+ else if (ieee80211_is_disassoc(fc))
+ cfg80211_send_unprot_disassoc(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
return -EACCES;
+ }
/*
* When using MFP, Action frames are not allowed prior to
* having configured keys.
@@ -1791,6 +1808,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (!fwd_skb && net_ratelimit())
printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
sdata->name);
+ if (!fwd_skb)
+ goto out;
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
@@ -1828,6 +1847,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
}
+ out:
if (is_multicast_ether_addr(hdr->addr1) ||
sdata->dev->flags & IFF_PROMISC)
return RX_CONTINUE;
@@ -1872,9 +1892,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
dev->stats.rx_packets++;
dev->stats.rx_bytes += rx->skb->len;
- if (ieee80211_is_data(hdr->frame_control) &&
- !is_multicast_ether_addr(hdr->addr1) &&
- local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) {
+ if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&
+ !is_multicast_ether_addr(((struct ethhdr *)rx->skb->data)->h_dest)) {
mod_timer(&local->dynamic_ps_timer, jiffies +
msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
}
@@ -1885,7 +1904,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
}
static ieee80211_rx_result debug_noinline
-ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
+ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
{
struct ieee80211_local *local = rx->local;
struct ieee80211_hw *hw = &local->hw;
@@ -1923,9 +1942,11 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
mod_timer(&tid_agg_rx->session_timer,
TU_TO_EXP_TIME(tid_agg_rx->timeout));
+ spin_lock(&tid_agg_rx->reorder_lock);
/* release stored frames up to start of BAR */
- ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
- frames);
+ ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num);
+ spin_unlock(&tid_agg_rx->reorder_lock);
+
kfree_skb(skb);
return RX_QUEUED;
}
@@ -2116,10 +2137,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_MESH_PLINK:
- case WLAN_CATEGORY_MESH_PATH_SEL:
if (!ieee80211_vif_is_mesh(&sdata->vif))
break;
goto queue;
+ case WLAN_CATEGORY_MESH_PATH_SEL:
+ if (!mesh_path_sel_is_hwmp(sdata))
+ break;
+ goto queue;
}
return RX_CONTINUE;
@@ -2247,6 +2271,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
break;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+ if (is_multicast_ether_addr(mgmt->da) &&
+ !is_broadcast_ether_addr(mgmt->da))
+ return RX_DROP_MONITOR;
+
/* process only for station */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return RX_DROP_MONITOR;
@@ -2433,8 +2461,7 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
}
}
-static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
- struct sk_buff_head *frames)
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
{
ieee80211_rx_result res = RX_DROP_MONITOR;
struct sk_buff *skb;
@@ -2446,7 +2473,15 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
goto rxh_next; \
} while (0);
- while ((skb = __skb_dequeue(frames))) {
+ spin_lock(&rx->local->rx_skb_queue.lock);
+ if (rx->local->running_rx_handler)
+ goto unlock;
+
+ rx->local->running_rx_handler = true;
+
+ while ((skb = __skb_dequeue(&rx->local->rx_skb_queue))) {
+ spin_unlock(&rx->local->rx_skb_queue.lock);
+
/*
* all the other fields are valid across frames
* that belong to an aMPDU since they are on the
@@ -2469,12 +2504,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
CALL_RXH(ieee80211_rx_h_mesh_fwding);
#endif
CALL_RXH(ieee80211_rx_h_data)
-
- /* special treatment -- needs the queue */
- res = ieee80211_rx_h_ctrl(rx, frames);
- if (res != RX_CONTINUE)
- goto rxh_next;
-
+ CALL_RXH(ieee80211_rx_h_ctrl);
CALL_RXH(ieee80211_rx_h_mgmt_check)
CALL_RXH(ieee80211_rx_h_action)
CALL_RXH(ieee80211_rx_h_userspace_mgmt)
@@ -2483,18 +2513,20 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
rxh_next:
ieee80211_rx_handlers_result(rx, res);
-
+ spin_lock(&rx->local->rx_skb_queue.lock);
#undef CALL_RXH
}
+
+ rx->local->running_rx_handler = false;
+
+ unlock:
+ spin_unlock(&rx->local->rx_skb_queue.lock);
}
static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
{
- struct sk_buff_head reorder_release;
ieee80211_rx_result res = RX_DROP_MONITOR;
- __skb_queue_head_init(&reorder_release);
-
#define CALL_RXH(rxh) \
do { \
res = rxh(rx); \
@@ -2505,9 +2537,9 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
CALL_RXH(ieee80211_rx_h_passive_scan)
CALL_RXH(ieee80211_rx_h_check)
- ieee80211_rx_reorder_ampdu(rx, &reorder_release);
+ ieee80211_rx_reorder_ampdu(rx);
- ieee80211_rx_handlers(rx, &reorder_release);
+ ieee80211_rx_handlers(rx);
return;
rxh_next:
@@ -2517,13 +2549,11 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
}
/*
- * This function makes calls into the RX path. Therefore the
- * caller must hold the sta_info->lock and everything has to
- * be under rcu_read_lock protection as well.
+ * This function makes calls into the RX path, therefore
+ * it has to be invoked under RCU read lock.
*/
void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
{
- struct sk_buff_head frames;
struct ieee80211_rx_data rx = {
.sta = sta,
.sdata = sta->sdata,
@@ -2536,13 +2566,11 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
if (!tid_agg_rx)
return;
- __skb_queue_head_init(&frames);
-
spin_lock(&tid_agg_rx->reorder_lock);
- ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames);
+ ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx);
spin_unlock(&tid_agg_rx->reorder_lock);
- ieee80211_rx_handlers(&rx, &frames);
+ ieee80211_rx_handlers(&rx);
}
/* main receive path */
@@ -2741,6 +2769,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
return;
+ goto out;
}
}
@@ -2780,6 +2809,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
return;
}
+ out:
dev_kfree_skb(skb);
}
@@ -2875,6 +2905,9 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
return;
}
+ ieee80211_tpt_led_trig_rx(local,
+ ((struct ieee80211_hdr *)skb->data)->frame_control,
+ skb->len);
__ieee80211_rx_handle_packet(hw, skb);
rcu_read_unlock();
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 6d8f897d8763..c426504ed1cf 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -199,8 +199,11 @@ static void sta_unblock(struct work_struct *wk)
if (!test_sta_flags(sta, WLAN_STA_PS_STA))
ieee80211_sta_ps_deliver_wakeup(sta);
- else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL))
+ else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
ieee80211_sta_ps_deliver_poll_response(sta);
+ } else
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
}
static int sta_prepare_rate_control(struct ieee80211_local *local,
@@ -241,6 +244,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->local = local;
sta->sdata = sdata;
+ ewma_init(&sta->avg_signal, 1024, 8);
+
if (sta_prepare_rate_control(local, sta, gfp)) {
kfree(sta);
return NULL;
@@ -880,6 +885,13 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
}
EXPORT_SYMBOL(ieee80211_find_sta);
+static void clear_sta_ps_flags(void *_sta)
+{
+ struct sta_info *sta = _sta;
+
+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA);
+}
+
/* powersave support code */
void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
{
@@ -894,7 +906,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
/* Send all buffered frames to the station */
sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
- buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
+ buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf,
+ clear_sta_ps_flags, sta);
sent += buffered;
local->total_ps_buffered -= buffered;
@@ -973,7 +986,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
if (block)
set_sta_flags(sta, WLAN_STA_PS_DRIVER);
- else
+ else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER))
ieee80211_queue_work(hw, &sta->drv_unblock_wk);
}
EXPORT_SYMBOL(ieee80211_sta_block_awake);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9265acadef32..bbdd2a86a94b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/if_ether.h>
#include <linux/workqueue.h>
+#include <linux/average.h>
#include "key.h"
/**
@@ -77,23 +78,26 @@ enum ieee80211_sta_info_flags {
* @addba_resp_timer: timer for peer's response to addba request
* @pending: pending frames queue -- use sta's spinlock to protect
* @dialog_token: dialog token for aggregation session
+ * @timeout: session timeout value to be filled in ADDBA requests
* @state: session state (see above)
* @stop_initiator: initiator of a session stop
* @tx_stop: TX DelBA frame when stopping
*
- * This structure is protected by RCU and the per-station
- * spinlock. Assignments to the array holding it must hold
- * the spinlock, only the TX path can access it under RCU
- * lock-free if, and only if, the state has the flag
- * %HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path
- * must also acquire the spinlock and re-check the state,
- * see comments in the tx code touching it.
+ * This structure's lifetime is managed by RCU, assignments to
+ * the array holding it must hold the aggregation mutex.
+ *
+ * The TX path can access it under RCU lock-free if, and
+ * only if, the state has the flag %HT_AGG_STATE_OPERATIONAL
+ * set. Otherwise, the TX path must also acquire the spinlock
+ * and re-check the state, see comments in the tx code
+ * touching it.
*/
struct tid_ampdu_tx {
struct rcu_head rcu_head;
struct timer_list addba_resp_timer;
struct sk_buff_head pending;
unsigned long state;
+ u16 timeout;
u8 dialog_token;
u8 stop_initiator;
bool tx_stop;
@@ -115,15 +119,13 @@ struct tid_ampdu_tx {
* @rcu_head: RCU head used for freeing this struct
* @reorder_lock: serializes access to reorder buffer, see below.
*
- * This structure is protected by RCU and the per-station
- * spinlock. Assignments to the array holding it must hold
- * the spinlock.
+ * This structure's lifetime is managed by RCU, assignments to
+ * the array holding it must hold the aggregation mutex.
*
- * The @reorder_lock is used to protect the variables and
- * arrays such as @reorder_buf, @reorder_time, @head_seq_num,
- * @stored_mpdu_num and @reorder_time from being corrupted by
- * concurrent access of the RX path and the expired frame
- * release timer.
+ * The @reorder_lock is used to protect the members of this
+ * struct, except for @timeout, @buf_size and @dialog_token,
+ * which are constant across the lifetime of the struct (the
+ * dialog token being used only for debugging).
*/
struct tid_ampdu_rx {
struct rcu_head rcu_head;
@@ -224,6 +226,7 @@ enum plink_state {
* @rx_fragments: number of received MPDUs
* @rx_dropped: number of dropped MPDUs from this STA
* @last_signal: signal of last received frame from this STA
+ * @avg_signal: moving average of signal of received frames from this STA
* @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
* @tx_filtered_count: number of frames the hardware filtered for this STA
* @tx_retry_failed: number of frames that failed retry
@@ -248,6 +251,7 @@ enum plink_state {
* @sta: station information we share with the driver
* @dead: set to true when sta is unlinked
* @uploaded: set to true when sta is uploaded to the driver
+ * @lost_packets: number of consecutive lost packets
*/
struct sta_info {
/* General information, mostly static */
@@ -291,6 +295,7 @@ struct sta_info {
unsigned long rx_fragments;
unsigned long rx_dropped;
int last_signal;
+ struct ewma avg_signal;
__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
/* Updated from TX status path only, no locking requirements */
@@ -335,6 +340,8 @@ struct sta_info {
} debugfs;
#endif
+ unsigned int lost_packets;
+
/* keep last! */
struct ieee80211_sta sta;
};
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 3153c19893b8..38a797217a91 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -157,6 +157,15 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
}
}
+/*
+ * Use a static threshold for now, best value to be determined
+ * by testing ...
+ * Should it depend on:
+ * - on # of retransmissions
+ * - current throughput (higher value for higher tpt)?
+ */
+#define STA_LOST_PKT_THRESHOLD 50
+
void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct sk_buff *skb2;
@@ -173,6 +182,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
int retry_count = -1, i;
int rates_idx = -1;
bool send_to_cooked;
+ bool acked;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
/* the HW cannot have attempted that rate */
@@ -198,8 +208,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
continue;
- if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
- test_sta_flags(sta, WLAN_STA_PS_STA)) {
+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
+ if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
/*
* The STA is in power save mode, so assume
* that this TX packet failed because of that.
@@ -231,7 +241,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
rcu_read_unlock();
return;
} else {
- if (!(info->flags & IEEE80211_TX_STAT_ACK))
+ if (!acked)
sta->tx_retry_failed++;
sta->tx_retry_count += retry_count;
}
@@ -240,9 +250,25 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (ieee80211_vif_is_mesh(&sta->sdata->vif))
ieee80211s_update_metric(local, sta, skb);
- if (!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
- (info->flags & IEEE80211_TX_STAT_ACK))
+ if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
ieee80211_frame_acked(sta, skb);
+
+ if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
+ (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
+ ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked);
+
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
+ if (info->flags & IEEE80211_TX_STAT_ACK) {
+ if (sta->lost_packets)
+ sta->lost_packets = 0;
+ } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
+ cfg80211_cqm_pktloss_notify(sta->sdata->dev,
+ sta->sta.addr,
+ sta->lost_packets,
+ GFP_ATOMIC);
+ sta->lost_packets = 0;
+ }
+ }
}
rcu_read_unlock();
@@ -295,10 +321,23 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
msecs_to_jiffies(10));
}
- if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)
+ if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
+ struct ieee80211_work *wk;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(wk, &local->work_list, list) {
+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
+ continue;
+ if (wk->offchan_tx.frame != skb)
+ continue;
+ wk->offchan_tx.frame = NULL;
+ break;
+ }
+ rcu_read_unlock();
cfg80211_mgmt_tx_status(
skb->dev, (unsigned long) skb, skb->data, skb->len,
!!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
+ }
/* this was a transmitted frame, but now we want to reuse it */
skb_orphan(skb);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 96c594309506..5950e3abead9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -539,7 +539,11 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
ieee80211_is_robust_mgmt_frame(hdr) &&
(key = rcu_dereference(tx->sdata->default_mgmt_key)))
tx->key = key;
- else if ((key = rcu_dereference(tx->sdata->default_key)))
+ else if (is_multicast_ether_addr(hdr->addr1) &&
+ (key = rcu_dereference(tx->sdata->default_multicast_key)))
+ tx->key = key;
+ else if (!is_multicast_ether_addr(hdr->addr1) &&
+ (key = rcu_dereference(tx->sdata->default_unicast_key)))
tx->key = key;
else if (tx->sdata->drop_unencrypted &&
(tx->skb->protocol != tx->sdata->control_port_protocol) &&
@@ -622,7 +626,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
txrc.max_rate_idx = -1;
else
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
- txrc.ap = tx->sdata->vif.type == NL80211_IFTYPE_AP;
+ txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
+ tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
/* set up RTS protection if desired */
if (len > tx->local->hw.wiphy->rts_threshold) {
@@ -665,10 +670,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
if (unlikely(info->control.rates[0].idx < 0))
return TX_DROP;
- if (txrc.reported_rate.idx < 0)
+ if (txrc.reported_rate.idx < 0) {
txrc.reported_rate = info->control.rates[0];
-
- if (tx->sta)
+ if (tx->sta && ieee80211_is_data(hdr->frame_control))
+ tx->sta->last_tx_rate = txrc.reported_rate;
+ } else if (tx->sta)
tx->sta->last_tx_rate = txrc.reported_rate;
if (unlikely(!info->control.rates[0].count))
@@ -1033,6 +1039,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
struct ieee80211_radiotap_header *rthdr =
(struct ieee80211_radiotap_header *) skb->data;
struct ieee80211_supported_band *sband;
+ bool hw_frag;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
@@ -1042,6 +1049,9 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
tx->flags &= ~IEEE80211_TX_FRAGMENTED;
+ /* packet is fragmented in HW if we have a non-NULL driver callback */
+ hw_frag = (tx->local->ops->set_frag_threshold != NULL);
+
/*
* for every radiotap entry that is present
* (ieee80211_radiotap_iterator_next returns -ENOENT when no more
@@ -1078,7 +1088,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
}
if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
- if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
+ if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) &&
+ !hw_frag)
tx->flags |= IEEE80211_TX_FRAGMENTED;
break;
@@ -1181,8 +1192,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
/*
* Set this flag (used below to indicate "automatic fragmentation"),
* it will be cleared/left by radiotap as desired.
+ * Only valid when fragmentation is done by the stack.
*/
- tx->flags |= IEEE80211_TX_FRAGMENTED;
+ if (!local->ops->set_frag_threshold)
+ tx->flags |= IEEE80211_TX_FRAGMENTED;
/* process and remove the injection radiotap header */
if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) {
@@ -1284,6 +1297,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
while (skb) {
int q = skb_get_queue_mapping(skb);
+ __le16 fc;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
ret = IEEE80211_TX_OK;
@@ -1326,6 +1340,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
else
info->control.sta = NULL;
+ fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
ret = drv_tx(local, skb);
if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
dev_kfree_skb(skb);
@@ -1336,6 +1351,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
return IEEE80211_TX_AGAIN;
}
+ ieee80211_tpt_led_trig_tx(local, fc, len);
*skbp = skb = next;
ieee80211_led_tx(local, 1);
fragm = true;
@@ -1533,8 +1549,10 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
if (skb_header_cloned(skb))
I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
- else
+ else if (head_need || tail_need)
I802_DEBUG_INC(local->tx_expand_skb_head);
+ else
+ return 0;
if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
wiphy_debug(local->hw.wiphy,
@@ -1587,7 +1605,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
list) {
if (!ieee80211_sdata_running(tmp_sdata))
continue;
- if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
+ if (tmp_sdata->vif.type ==
+ NL80211_IFTYPE_MONITOR ||
+ tmp_sdata->vif.type ==
+ NL80211_IFTYPE_AP_VLAN ||
+ tmp_sdata->vif.type ==
+ NL80211_IFTYPE_WDS)
continue;
if (compare_ether_addr(tmp_sdata->vif.addr,
hdr->addr2) == 0) {
@@ -1721,26 +1744,25 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_info *info;
int ret = NETDEV_TX_BUSY, head_need;
u16 ethertype, hdrlen, meshhdrlen = 0;
__le16 fc;
struct ieee80211_hdr hdr;
struct ieee80211s_hdr mesh_hdr __maybe_unused;
+ struct mesh_path *mppath = NULL;
const u8 *encaps_data;
int encaps_len, skip_header_bytes;
int nh_pos, h_pos;
struct sta_info *sta = NULL;
u32 sta_flags = 0;
+ struct sk_buff *tmp_skb;
if (unlikely(skb->len < ETH_HLEN)) {
ret = NETDEV_TX_OK;
goto fail;
}
- nh_pos = skb_network_header(skb) - skb->data;
- h_pos = skb_transport_header(skb) - skb->data;
-
/* convert Ethernet header to proper 802.11 header (based on
* operation mode) */
ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1789,16 +1811,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
ret = NETDEV_TX_OK;
goto fail;
}
+ if (!is_multicast_ether_addr(skb->data))
+ mppath = mpp_path_lookup(skb->data, sdata);
+ /*
+ * Do not use address extension, if it is a packet from
+ * the same interface and the destination is not being
+ * proxied by any other mest point.
+ */
if (compare_ether_addr(sdata->vif.addr,
- skb->data + ETH_ALEN) == 0) {
+ skb->data + ETH_ALEN) == 0 &&
+ (!mppath || !compare_ether_addr(mppath->mpp, skb->data))) {
hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
skb->data, skb->data + ETH_ALEN);
meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
- sdata, NULL, NULL, NULL);
+ sdata, NULL, NULL);
} else {
/* packet from other interface */
- struct mesh_path *mppath;
int is_mesh_mcast = 1;
const u8 *mesh_da;
@@ -1809,8 +1838,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
else {
static const u8 bcast[ETH_ALEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- mppath = mpp_path_lookup(skb->data, sdata);
if (mppath) {
/* RA TA mDA mSA AE:DA SA */
mesh_da = mppath->mpp;
@@ -1828,13 +1855,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
ieee80211_new_mesh_header(&mesh_hdr,
sdata,
skb->data + ETH_ALEN,
- NULL,
NULL);
else
meshhdrlen =
ieee80211_new_mesh_header(&mesh_hdr,
sdata,
- NULL,
skb->data,
skb->data + ETH_ALEN);
@@ -1913,6 +1938,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
goto fail;
}
+ /*
+ * If the skb is shared we need to obtain our own copy.
+ */
+ if (skb_shared(skb)) {
+ tmp_skb = skb;
+ skb = skb_clone(skb, GFP_ATOMIC);
+ kfree_skb(tmp_skb);
+
+ if (!skb) {
+ ret = NETDEV_TX_OK;
+ goto fail;
+ }
+ }
+
hdr.frame_control = fc;
hdr.duration_id = 0;
hdr.seq_ctrl = 0;
@@ -1931,6 +1970,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
encaps_len = 0;
}
+ nh_pos = skb_network_header(skb) - skb->data;
+ h_pos = skb_transport_header(skb) - skb->data;
+
skb_pull(skb, skip_header_bytes);
nh_pos -= skip_header_bytes;
h_pos -= skip_header_bytes;
@@ -1997,6 +2039,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
skb_set_network_header(skb, nh_pos);
skb_set_transport_header(skb, h_pos);
+ info = IEEE80211_SKB_CB(skb);
memset(info, 0, sizeof(*info));
dev->trans_start = jiffies;
@@ -2257,7 +2300,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
u8 *pos;
/* headroom, head length, tail length and maximum TIM length */
- skb = dev_alloc_skb(local->tx_headroom + 400);
+ skb = dev_alloc_skb(local->tx_headroom + 400 +
+ sdata->u.mesh.vendor_ie_len);
if (!skb)
goto out;
@@ -2301,7 +2345,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
txrc.max_rate_idx = -1;
else
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
- txrc.ap = true;
+ txrc.bss = true;
rate_control_get_rate(sdata, NULL, &txrc);
info->control.vif = vif;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0b6fc92bc0d7..cf68700abffa 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -368,8 +368,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
-int ieee80211_add_pending_skbs(struct ieee80211_local *local,
- struct sk_buff_head *skbs)
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+ struct sk_buff_head *skbs,
+ void (*fn)(void *data), void *data)
{
struct ieee80211_hw *hw = &local->hw;
struct sk_buff *skb;
@@ -394,6 +395,9 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
__skb_queue_tail(&local->pending[queue], skb);
}
+ if (fn)
+ fn(data);
+
for (i = 0; i < hw->queues; i++)
__ieee80211_wake_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
@@ -402,6 +406,12 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
return ret;
}
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+ struct sk_buff_head *skbs)
+{
+ return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
+}
+
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
enum queue_stop_reason reason)
{
@@ -1011,9 +1021,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
return pos - buffer;
}
-void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
- const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len)
+struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
+ u8 *dst,
+ const u8 *ssid, size_t ssid_len,
+ const u8 *ie, size_t ie_len)
{
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
@@ -1027,7 +1038,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
if (!buf) {
printk(KERN_DEBUG "%s: failed to allocate temporary IE "
"buffer\n", sdata->name);
- return;
+ return NULL;
}
chan = ieee80211_frequency_to_channel(
@@ -1050,8 +1061,20 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
}
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
- ieee80211_tx_skb(sdata, skb);
kfree(buf);
+
+ return skb;
+}
+
+void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
+ const u8 *ssid, size_t ssid_len,
+ const u8 *ie, size_t ie_len)
+{
+ struct sk_buff *skb;
+
+ skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len);
+ if (skb)
+ ieee80211_tx_skb(sdata, skb);
}
u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
@@ -1093,6 +1116,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
void ieee80211_stop_device(struct ieee80211_local *local)
{
ieee80211_led_radio(local, false);
+ ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);
cancel_work_sync(&local->reconfig_filter);
@@ -1127,6 +1151,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
ieee80211_led_radio(local, true);
+ ieee80211_mod_tpt_led_trig(local,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
}
/* add interfaces */
@@ -1152,6 +1178,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
mutex_unlock(&local->sta_mtx);
+ /* setup fragmentation threshold */
+ drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
+
/* setup RTS threshold */
drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 34e6d02da779..28bc084dbfb9 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -21,7 +21,16 @@
/* Default mapping in classifier to work with default
* queue setup.
*/
-const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
+const int ieee802_1d_to_ac[8] = {
+ IEEE80211_AC_BE,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BE,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VO,
+ IEEE80211_AC_VO
+};
static int wme_downgrade_ac(struct sk_buff *skb)
{
@@ -50,26 +59,22 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta = NULL;
- u32 sta_flags = 0;
const u8 *ra = NULL;
bool qos = false;
if (local->hw.queues < 4 || skb->len < 6) {
skb->priority = 0; /* required for correct WPA/11i MIC */
- return min_t(u16, local->hw.queues - 1,
- ieee802_1d_to_ac[skb->priority]);
+ return min_t(u16, local->hw.queues - 1, IEEE80211_AC_BE);
}
rcu_read_lock();
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
- rcu_read_lock();
sta = rcu_dereference(sdata->u.vlan.sta);
- if (sta)
- sta_flags = get_sta_flags(sta);
- rcu_read_unlock();
- if (sta)
+ if (sta) {
+ qos = get_sta_flags(sta) & WLAN_STA_WME;
break;
+ }
case NL80211_IFTYPE_AP:
ra = skb->data;
break;
@@ -98,17 +103,13 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
if (!sta && ra && !is_multicast_ether_addr(ra)) {
sta = sta_info_get(sdata, ra);
if (sta)
- sta_flags = get_sta_flags(sta);
+ qos = get_sta_flags(sta) & WLAN_STA_WME;
}
-
- if (sta_flags & WLAN_STA_WME)
- qos = true;
-
rcu_read_unlock();
if (!qos) {
skb->priority = 0; /* required for correct WPA/11i MIC */
- return ieee802_1d_to_ac[skb->priority];
+ return IEEE80211_AC_BE;
}
/* use the data classifier to determine what 802.1d tag the
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index ae344d1ba056..36305e0d06ef 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -458,8 +458,9 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
return WORK_ACT_TIMEOUT;
}
- printk(KERN_DEBUG "%s: direct probe to %pM (try %d)\n",
- sdata->name, wk->filter_ta, wk->probe_auth.tries);
+ printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
+ sdata->name, wk->filter_ta, wk->probe_auth.tries,
+ IEEE80211_AUTH_MAX_TRIES);
/*
* Direct probe is sent to broadcast address as some APs
@@ -561,6 +562,25 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
}
static enum work_action __must_check
+ieee80211_offchannel_tx(struct ieee80211_work *wk)
+{
+ if (!wk->started) {
+ wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);
+
+ /*
+ * After this, offchan_tx.frame remains but now is no
+ * longer a valid pointer -- we still need it as the
+ * cookie for canceling this work.
+ */
+ ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
+
+ return WORK_ACT_NONE;
+ }
+
+ return WORK_ACT_TIMEOUT;
+}
+
+static enum work_action __must_check
ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
{
if (wk->started)
@@ -955,6 +975,9 @@ static void ieee80211_work_work(struct work_struct *work)
case IEEE80211_WORK_REMAIN_ON_CHANNEL:
rma = ieee80211_remain_on_channel_timeout(wk);
break;
+ case IEEE80211_WORK_OFFCHANNEL_TX:
+ rma = ieee80211_offchannel_tx(wk);
+ break;
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
rma = ieee80211_assoc_beacon_wait(wk);
break;
@@ -1051,11 +1074,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_work *wk;
+ bool cleanup = false;
mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
if (wk->sdata != sdata)
continue;
+ cleanup = true;
wk->type = IEEE80211_WORK_ABORT;
wk->started = true;
wk->timeout = jiffies;
@@ -1063,7 +1088,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
mutex_unlock(&local->mtx);
/* run cleanups etc. */
- ieee80211_work_work(&local->work_work);
+ if (cleanup)
+ ieee80211_work_work(&local->work_work);
mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 85dabb86be6f..32fcbe290c04 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -173,9 +173,11 @@ next_hook:
outdev, &elem, okfn, hook_thresh);
if (verdict == NF_ACCEPT || verdict == NF_STOP) {
ret = 1;
- } else if (verdict == NF_DROP) {
+ } else if ((verdict & NF_VERDICT_MASK) == NF_DROP) {
kfree_skb(skb);
- ret = -EPERM;
+ ret = -(verdict >> NF_VERDICT_BITS);
+ if (ret == 0)
+ ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
verdict >> NF_VERDICT_BITS))
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 5f5daa30b0af..c6f293639220 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -110,10 +110,8 @@ static int __ip_vs_addr_is_local_v6(const struct in6_addr *addr)
struct rt6_info *rt;
struct flowi fl = {
.oif = 0,
- .nl_u = {
- .ip6_u = {
- .daddr = *addr,
- .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } },
+ .fl6_dst = *addr,
+ .fl6_src = { .s6_addr32 = {0, 0, 0, 0} },
};
rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index de04ea39cde8..5325a3fbe4ac 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -96,12 +96,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
if (!(rt = (struct rtable *)
__ip_vs_dst_check(dest, rtos))) {
struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip4_u = {
- .daddr = dest->addr.ip,
- .saddr = 0,
- .tos = rtos, } },
+ .fl4_dst = dest->addr.ip,
+ .fl4_tos = rtos,
};
if (ip_route_output_key(net, &rt, &fl)) {
@@ -118,12 +114,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
spin_unlock(&dest->dst_lock);
} else {
struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip4_u = {
- .daddr = daddr,
- .saddr = 0,
- .tos = rtos, } },
+ .fl4_dst = daddr,
+ .fl4_tos = rtos,
};
if (ip_route_output_key(net, &rt, &fl)) {
@@ -169,7 +161,7 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
struct net *net = dev_net(dev);
struct iphdr *iph = ip_hdr(skb);
- if (rt->fl.iif) {
+ if (rt_is_input_route(rt)) {
unsigned long orefdst = skb->_skb_refdst;
if (ip_route_input(skb, iph->daddr, iph->saddr,
@@ -178,14 +170,9 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
refdst_drop(orefdst);
} else {
struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos),
- }
- },
+ .fl4_dst = iph->daddr,
+ .fl4_src = iph->saddr,
+ .fl4_tos = RT_TOS(iph->tos),
.mark = skb->mark,
};
struct rtable *rt;
@@ -216,12 +203,7 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr,
{
struct dst_entry *dst;
struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip6_u = {
- .daddr = *daddr,
- },
- },
+ .fl6_dst = *daddr,
};
dst = ip6_route_output(net, NULL, &fl);
@@ -552,7 +534,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
#endif
/* From world but DNAT to loopback address? */
- if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) {
+ if (local && ipv4_is_loopback(rt->rt_dst) &&
+ rt_is_input_route(skb_rtable(skb))) {
IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
"stopping DNAT to loopback address");
goto tx_error_put;
@@ -1165,7 +1148,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
#endif
/* From world but DNAT to loopback address? */
- if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) {
+ if (local && ipv4_is_loopback(rt->rt_dst) &&
+ rt_is_input_route(skb_rtable(skb))) {
IP_VS_DBG(1, "%s(): "
"stopping DNAT to loopback %pI4\n",
__func__, &cp->daddr.ip);
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 22a2d421e7eb..5128a6c4cb2c 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -70,9 +70,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false;
fl.oif = info->priv->oif;
}
- fl.nl_u.ip4_u.daddr = info->gw.ip;
- fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
- fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE;
+ fl.fl4_dst = info->gw.ip;
+ fl.fl4_tos = RT_TOS(iph->tos);
+ fl.fl4_scope = RT_SCOPE_UNIVERSE;
if (ip_route_output_key(net, &rt, &fl) != 0)
return false;
@@ -150,9 +150,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false;
fl.oif = info->priv->oif;
}
- fl.nl_u.ip6_u.daddr = info->gw.in6;
- fl.nl_u.ip6_u.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
- (iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
+ fl.fl6_dst = info->gw.in6;
+ fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
+ (iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
dst = ip6_route_output(net, NULL, &fl);
if (dst == NULL)
return false;
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h
index c8a4079261f0..af7f3355103e 100644
--- a/net/netlabel/netlabel_cipso_v4.h
+++ b/net/netlabel/netlabel_cipso_v4.h
@@ -107,7 +107,6 @@ enum {
NLBL_CIPSOV4_C_LISTALL,
__NLBL_CIPSOV4_C_MAX,
};
-#define NLBL_CIPSOV4_C_MAX (__NLBL_CIPSOV4_C_MAX - 1)
/* NetLabel CIPSOv4 attributes */
enum {
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index 05d96431f819..0a25838bcf45 100644
--- a/net/netlabel/netlabel_mgmt.h
+++ b/net/netlabel/netlabel_mgmt.h
@@ -173,7 +173,6 @@ enum {
NLBL_MGMT_C_VERSION,
__NLBL_MGMT_C_MAX,
};
-#define NLBL_MGMT_C_MAX (__NLBL_MGMT_C_MAX - 1)
/* NetLabel Management attributes */
enum {
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h
index 7aba63595137..0bc8dc3f9e3c 100644
--- a/net/netlabel/netlabel_unlabeled.h
+++ b/net/netlabel/netlabel_unlabeled.h
@@ -180,7 +180,6 @@ enum {
NLBL_UNLABEL_C_STATICLISTDEF,
__NLBL_UNLABEL_C_MAX,
};
-#define NLBL_UNLABEL_C_MAX (__NLBL_UNLABEL_C_MAX - 1)
/* NetLabel Unlabeled attributes */
enum {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8298e676f5a0..91cb1d71f018 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -61,6 +61,7 @@
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/protocol.h>
@@ -163,8 +164,13 @@ struct packet_mreq_max {
static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
int closing, int tx_ring);
+#define PGV_FROM_VMALLOC 1
+struct pgv {
+ char *buffer;
+};
+
struct packet_ring_buffer {
- char **pg_vec;
+ struct pgv *pg_vec;
unsigned int head;
unsigned int frames_per_block;
unsigned int frame_size;
@@ -217,6 +223,13 @@ struct packet_skb_cb {
#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
+static inline __pure struct page *pgv_to_page(void *addr)
+{
+ if (is_vmalloc_addr(addr))
+ return vmalloc_to_page(addr);
+ return virt_to_page(addr);
+}
+
static void __packet_set_status(struct packet_sock *po, void *frame, int status)
{
union {
@@ -229,11 +242,11 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
switch (po->tp_version) {
case TPACKET_V1:
h.h1->tp_status = status;
- flush_dcache_page(virt_to_page(&h.h1->tp_status));
+ flush_dcache_page(pgv_to_page(&h.h1->tp_status));
break;
case TPACKET_V2:
h.h2->tp_status = status;
- flush_dcache_page(virt_to_page(&h.h2->tp_status));
+ flush_dcache_page(pgv_to_page(&h.h2->tp_status));
break;
default:
pr_err("TPACKET version not supported\n");
@@ -256,10 +269,10 @@ static int __packet_get_status(struct packet_sock *po, void *frame)
h.raw = frame;
switch (po->tp_version) {
case TPACKET_V1:
- flush_dcache_page(virt_to_page(&h.h1->tp_status));
+ flush_dcache_page(pgv_to_page(&h.h1->tp_status));
return h.h1->tp_status;
case TPACKET_V2:
- flush_dcache_page(virt_to_page(&h.h2->tp_status));
+ flush_dcache_page(pgv_to_page(&h.h2->tp_status));
return h.h2->tp_status;
default:
pr_err("TPACKET version not supported\n");
@@ -283,7 +296,8 @@ static void *packet_lookup_frame(struct packet_sock *po,
pg_vec_pos = position / rb->frames_per_block;
frame_offset = position % rb->frames_per_block;
- h.raw = rb->pg_vec[pg_vec_pos] + (frame_offset * rb->frame_size);
+ h.raw = rb->pg_vec[pg_vec_pos].buffer +
+ (frame_offset * rb->frame_size);
if (status != __packet_get_status(po, h.raw))
return NULL;
@@ -503,7 +517,8 @@ out_free:
return err;
}
-static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
+static inline unsigned int run_filter(const struct sk_buff *skb,
+ const struct sock *sk,
unsigned int res)
{
struct sk_filter *filter;
@@ -511,22 +526,22 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
rcu_read_lock_bh();
filter = rcu_dereference_bh(sk->sk_filter);
if (filter != NULL)
- res = sk_run_filter(skb, filter->insns, filter->len);
+ res = sk_run_filter(skb, filter->insns);
rcu_read_unlock_bh();
return res;
}
/*
- This function makes lazy skb cloning in hope that most of packets
- are discarded by BPF.
-
- Note tricky part: we DO mangle shared skb! skb->data, skb->len
- and skb->cb are mangled. It works because (and until) packets
- falling here are owned by current CPU. Output packets are cloned
- by dev_queue_xmit_nit(), input packets are processed by net_bh
- sequencially, so that if we return skb to original state on exit,
- we will not harm anyone.
+ * This function makes lazy skb cloning in hope that most of packets
+ * are discarded by BPF.
+ *
+ * Note tricky part: we DO mangle shared skb! skb->data, skb->len
+ * and skb->cb are mangled. It works because (and until) packets
+ * falling here are owned by current CPU. Output packets are cloned
+ * by dev_queue_xmit_nit(), input packets are processed by net_bh
+ * sequencially, so that if we return skb to original state on exit,
+ * we will not harm anyone.
*/
static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
@@ -552,11 +567,11 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
if (dev->header_ops) {
/* The device has an explicit notion of ll header,
- exported to higher levels.
-
- Otherwise, the device hides datails of it frame
- structure, so that corresponding packet head
- never delivered to user.
+ * exported to higher levels.
+ *
+ * Otherwise, the device hides details of its frame
+ * structure, so that corresponding packet head is
+ * never delivered to user.
*/
if (sk->sk_type != SOCK_DGRAM)
skb_push(skb, skb->data - skb_mac_header(skb));
@@ -791,17 +806,15 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
__packet_set_status(po, h.raw, status);
smp_mb();
+#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1
{
- struct page *p_start, *p_end;
- u8 *h_end = h.raw + macoff + snaplen - 1;
-
- p_start = virt_to_page(h.raw);
- p_end = virt_to_page(h_end);
- while (p_start <= p_end) {
- flush_dcache_page(p_start);
- p_start++;
- }
+ u8 *start, *end;
+
+ end = (u8 *)PAGE_ALIGN((unsigned long)h.raw + macoff + snaplen);
+ for (start = h.raw; start < end; start += PAGE_SIZE)
+ flush_dcache_page(pgv_to_page(start));
}
+#endif
sk->sk_data_ready(sk, 0);
@@ -907,7 +920,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
}
err = -EFAULT;
- page = virt_to_page(data);
offset = offset_in_page(data);
len_max = PAGE_SIZE - offset;
len = ((to_write > len_max) ? len_max : to_write);
@@ -926,11 +938,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
return -EFAULT;
}
+ page = pgv_to_page(data);
+ data += len;
flush_dcache_page(page);
get_page(page);
- skb_fill_page_desc(skb,
- nr_frags,
- page++, offset, len);
+ skb_fill_page_desc(skb, nr_frags, page, offset, len);
to_write -= len;
offset = 0;
len_max = PAGE_SIZE;
@@ -1638,8 +1650,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- vnet_hdr.csum_start = skb->csum_start -
- skb_headroom(skb);
+ vnet_hdr.csum_start = skb_checksum_start_offset(skb);
vnet_hdr.csum_offset = skb->csum_offset;
} /* else everything is zero */
@@ -2325,37 +2336,70 @@ static const struct vm_operations_struct packet_mmap_ops = {
.close = packet_mm_close,
};
-static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
+static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
+ unsigned int len)
{
int i;
for (i = 0; i < len; i++) {
- if (likely(pg_vec[i]))
- free_pages((unsigned long) pg_vec[i], order);
+ if (likely(pg_vec[i].buffer)) {
+ if (is_vmalloc_addr(pg_vec[i].buffer))
+ vfree(pg_vec[i].buffer);
+ else
+ free_pages((unsigned long)pg_vec[i].buffer,
+ order);
+ pg_vec[i].buffer = NULL;
+ }
}
kfree(pg_vec);
}
static inline char *alloc_one_pg_vec_page(unsigned long order)
{
- gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | __GFP_NOWARN;
+ char *buffer = NULL;
+ gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP |
+ __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY;
- return (char *) __get_free_pages(gfp_flags, order);
+ buffer = (char *) __get_free_pages(gfp_flags, order);
+
+ if (buffer)
+ return buffer;
+
+ /*
+ * __get_free_pages failed, fall back to vmalloc
+ */
+ buffer = vzalloc((1 << order) * PAGE_SIZE);
+
+ if (buffer)
+ return buffer;
+
+ /*
+ * vmalloc failed, lets dig into swap here
+ */
+ gfp_flags &= ~__GFP_NORETRY;
+ buffer = (char *)__get_free_pages(gfp_flags, order);
+ if (buffer)
+ return buffer;
+
+ /*
+ * complete and utter failure
+ */
+ return NULL;
}
-static char **alloc_pg_vec(struct tpacket_req *req, int order)
+static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order)
{
unsigned int block_nr = req->tp_block_nr;
- char **pg_vec;
+ struct pgv *pg_vec;
int i;
- pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL);
+ pg_vec = kcalloc(block_nr, sizeof(struct pgv), GFP_KERNEL);
if (unlikely(!pg_vec))
goto out;
for (i = 0; i < block_nr; i++) {
- pg_vec[i] = alloc_one_pg_vec_page(order);
- if (unlikely(!pg_vec[i]))
+ pg_vec[i].buffer = alloc_one_pg_vec_page(order);
+ if (unlikely(!pg_vec[i].buffer))
goto out_free_pgvec;
}
@@ -2371,7 +2415,7 @@ out_free_pgvec:
static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
int closing, int tx_ring)
{
- char **pg_vec = NULL;
+ struct pgv *pg_vec = NULL;
struct packet_sock *po = pkt_sk(sk);
int was_running, order = 0;
struct packet_ring_buffer *rb;
@@ -2456,22 +2500,20 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
mutex_lock(&po->pg_vec_lock);
if (closing || atomic_read(&po->mapped) == 0) {
err = 0;
-#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
spin_lock_bh(&rb_queue->lock);
- pg_vec = XC(rb->pg_vec, pg_vec);
+ swap(rb->pg_vec, pg_vec);
rb->frame_max = (req->tp_frame_nr - 1);
rb->head = 0;
rb->frame_size = req->tp_frame_size;
spin_unlock_bh(&rb_queue->lock);
- order = XC(rb->pg_vec_order, order);
- req->tp_block_nr = XC(rb->pg_vec_len, req->tp_block_nr);
+ swap(rb->pg_vec_order, order);
+ swap(rb->pg_vec_len, req->tp_block_nr);
rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
po->prot_hook.func = (po->rx_ring.pg_vec) ?
tpacket_rcv : packet_rcv;
skb_queue_purge(rb_queue);
-#undef XC
if (atomic_read(&po->mapped))
pr_err("packet_mmap: vma is busy: %d\n",
atomic_read(&po->mapped));
@@ -2533,15 +2575,17 @@ static int packet_mmap(struct file *file, struct socket *sock,
continue;
for (i = 0; i < rb->pg_vec_len; i++) {
- struct page *page = virt_to_page(rb->pg_vec[i]);
+ struct page *page;
+ void *kaddr = rb->pg_vec[i].buffer;
int pg_num;
- for (pg_num = 0; pg_num < rb->pg_vec_pages;
- pg_num++, page++) {
+ for (pg_num = 0; pg_num < rb->pg_vec_pages; pg_num++) {
+ page = pgv_to_page(kaddr);
err = vm_insert_page(vma, start, page);
if (unlikely(err))
goto out;
start += PAGE_SIZE;
+ kaddr += PAGE_SIZE;
}
}
}
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index d62bbba649b3..e10b1b182ce3 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_PHONET) += phonet.o pn_pep.o
-phonet-objs := \
+phonet-y := \
pn_dev.o \
pn_netlink.o \
socket.o \
@@ -8,4 +8,4 @@ phonet-objs := \
sysctl.o \
af_phonet.o
-pn_pep-objs := pep.o pep-gprs.o
+pn_pep-y := pep.o pep-gprs.o
diff --git a/net/rds/Makefile b/net/rds/Makefile
index b46eca109688..56d3f6023ced 100644
--- a/net/rds/Makefile
+++ b/net/rds/Makefile
@@ -4,7 +4,7 @@ rds-y := af_rds.o bind.o cong.o connection.o info.o message.o \
loop.o page.o rdma.o
obj-$(CONFIG_RDS_RDMA) += rds_rdma.o
-rds_rdma-objs := rdma_transport.o \
+rds_rdma-y := rdma_transport.o \
ib.o ib_cm.o ib_recv.o ib_ring.o ib_send.o ib_stats.o \
ib_sysctl.o ib_rdma.o \
iw.o iw_cm.o iw_recv.o iw_ring.o iw_send.o iw_stats.o \
@@ -12,10 +12,8 @@ rds_rdma-objs := rdma_transport.o \
obj-$(CONFIG_RDS_TCP) += rds_tcp.o
-rds_tcp-objs := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \
+rds_tcp-y := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \
tcp_send.o tcp_stats.o
-ifeq ($(CONFIG_RDS_DEBUG), y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_RDS_DEBUG) := -DDEBUG
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 04f599089e6d..0198191b756d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -149,20 +149,6 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
rfkill_led_trigger_event(rfkill);
}
-const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
-{
- return rfkill->led_trigger.name;
-}
-EXPORT_SYMBOL(rfkill_get_led_trigger_name);
-
-void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
-{
- BUG_ON(!rfkill);
-
- rfkill->ledtrigname = name;
-}
-EXPORT_SYMBOL(rfkill_set_led_trigger_name);
-
static int rfkill_led_trigger_register(struct rfkill *rfkill)
{
rfkill->led_trigger.name = rfkill->ledtrigname
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile
index c46867c61c98..d1c3429b69ed 100644
--- a/net/rxrpc/Makefile
+++ b/net/rxrpc/Makefile
@@ -2,7 +2,7 @@
# Makefile for Linux kernel RxRPC
#
-af-rxrpc-objs := \
+af-rxrpc-y := \
af_rxrpc.o \
ar-accept.o \
ar-ack.o \
@@ -21,7 +21,7 @@ af-rxrpc-objs := \
ar-transport.o
ifeq ($(CONFIG_PROC_FS),y)
-af-rxrpc-objs += ar-proc.o
+af-rxrpc-y += ar-proc.o
endif
obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c
index 9f1729bd60de..a53fb25a64ed 100644
--- a/net/rxrpc/ar-peer.c
+++ b/net/rxrpc/ar-peer.c
@@ -47,12 +47,12 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
case AF_INET:
fl.oif = 0;
fl.proto = IPPROTO_UDP,
- fl.nl_u.ip4_u.saddr = 0;
- fl.nl_u.ip4_u.daddr = peer->srx.transport.sin.sin_addr.s_addr;
- fl.nl_u.ip4_u.tos = 0;
+ fl.fl4_dst = peer->srx.transport.sin.sin_addr.s_addr;
+ fl.fl4_src = 0;
+ fl.fl4_tos = 0;
/* assume AFS.CM talking to AFS.FS */
- fl.uli_u.ports.sport = htons(7001);
- fl.uli_u.ports.dport = htons(7000);
+ fl.fl_ip_sport = htons(7001);
+ fl.fl_ip_dport = htons(7000);
break;
default:
BUG();
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5dbb3cd96e59..34dc598440a2 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -60,8 +60,7 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
/* check the reason of requeuing without tx lock first */
txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
- if (!netif_tx_queue_stopped(txq) &&
- !netif_tx_queue_frozen(txq)) {
+ if (!netif_tx_queue_frozen_or_stopped(txq)) {
q->gso_skb = NULL;
q->q.qlen--;
} else
@@ -122,7 +121,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
spin_unlock(root_lock);
HARD_TX_LOCK(dev, txq, smp_processor_id());
- if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
+ if (!netif_tx_queue_frozen_or_stopped(txq))
ret = dev_hard_start_xmit(skb, dev, txq);
HARD_TX_UNLOCK(dev, txq);
@@ -144,8 +143,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
ret = dev_requeue_skb(skb, q);
}
- if (ret && (netif_tx_queue_stopped(txq) ||
- netif_tx_queue_frozen(txq)))
+ if (ret && netif_tx_queue_frozen_or_stopped(txq))
ret = 0;
return ret;
@@ -555,7 +553,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
size = QDISC_ALIGN(sizeof(*sch));
size += ops->priv_size + (QDISC_ALIGNTO - 1);
- p = kzalloc(size, GFP_KERNEL);
+ p = kzalloc_node(size, GFP_KERNEL,
+ netdev_queue_numa_node_read(dev_queue));
+
if (!p)
goto errout;
sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
@@ -810,20 +810,35 @@ static bool some_qdisc_is_busy(struct net_device *dev)
return false;
}
-void dev_deactivate(struct net_device *dev)
+void dev_deactivate_many(struct list_head *head)
{
- netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
- if (dev_ingress_queue(dev))
- dev_deactivate_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
+ struct net_device *dev;
+
+ list_for_each_entry(dev, head, unreg_list) {
+ netdev_for_each_tx_queue(dev, dev_deactivate_queue,
+ &noop_qdisc);
+ if (dev_ingress_queue(dev))
+ dev_deactivate_queue(dev, dev_ingress_queue(dev),
+ &noop_qdisc);
- dev_watchdog_down(dev);
+ dev_watchdog_down(dev);
+ }
/* Wait for outstanding qdisc-less dev_queue_xmit calls. */
synchronize_rcu();
/* Wait for outstanding qdisc_run calls. */
- while (some_qdisc_is_busy(dev))
- yield();
+ list_for_each_entry(dev, head, unreg_list)
+ while (some_qdisc_is_busy(dev))
+ yield();
+}
+
+void dev_deactivate(struct net_device *dev)
+{
+ LIST_HEAD(single);
+
+ list_add(&dev->unreg_list, &single);
+ dev_deactivate_many(&single);
}
static void dev_init_scheduler_queue(struct net_device *dev,
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 8d42bb3ba540..a67ba3c5a0cc 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -239,6 +239,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
.Scell_log = q->parms.Scell_log,
};
+ sch->qstats.backlog = q->qdisc->qstats.backlog;
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 3cf478d012dd..d54ac94066c2 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -67,27 +67,47 @@
IMPLEMENTATION:
This implementation limits maximal queue length to 128;
- maximal mtu to 2^15-1; number of hash buckets to 1024.
+ max mtu to 2^18-1; max 128 flows, number of hash buckets to 1024.
The only goal of this restrictions was that all data
- fit into one 4K page :-). Struct sfq_sched_data is
- organized in anti-cache manner: all the data for a bucket
- are scattered over different locations. This is not good,
- but it allowed me to put it into 4K.
+ fit into one 4K page on 32bit arches.
It is easy to increase these values, but not in flight. */
-#define SFQ_DEPTH 128
+#define SFQ_DEPTH 128 /* max number of packets per flow */
+#define SFQ_SLOTS 128 /* max number of flows */
+#define SFQ_EMPTY_SLOT 255
#define SFQ_HASH_DIVISOR 1024
+/* We use 16 bits to store allot, and want to handle packets up to 64K
+ * Scale allot by 8 (1<<3) so that no overflow occurs.
+ */
+#define SFQ_ALLOT_SHIFT 3
+#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT)
-/* This type should contain at least SFQ_DEPTH*2 values */
+/* This type should contain at least SFQ_DEPTH + SFQ_SLOTS values */
typedef unsigned char sfq_index;
+/*
+ * We dont use pointers to save space.
+ * Small indexes [0 ... SFQ_SLOTS - 1] are 'pointers' to slots[] array
+ * while following values [SFQ_SLOTS ... SFQ_SLOTS + SFQ_DEPTH - 1]
+ * are 'pointers' to dep[] array
+ */
struct sfq_head
{
sfq_index next;
sfq_index prev;
};
+struct sfq_slot {
+ struct sk_buff *skblist_next;
+ struct sk_buff *skblist_prev;
+ sfq_index qlen; /* number of skbs in skblist */
+ sfq_index next; /* next slot in sfq chain */
+ struct sfq_head dep; /* anchor in dep[] chains */
+ unsigned short hash; /* hash value (index in ht[]) */
+ short allot; /* credit for this slot */
+};
+
struct sfq_sched_data
{
/* Parameters */
@@ -99,17 +119,24 @@ struct sfq_sched_data
struct tcf_proto *filter_list;
struct timer_list perturb_timer;
u32 perturbation;
- sfq_index tail; /* Index of current slot in round */
- sfq_index max_depth; /* Maximal depth */
-
+ sfq_index cur_depth; /* depth of longest slot */
+ unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
+ struct sfq_slot *tail; /* current slot in round */
sfq_index ht[SFQ_HASH_DIVISOR]; /* Hash table */
- sfq_index next[SFQ_DEPTH]; /* Active slots link */
- short allot[SFQ_DEPTH]; /* Current allotment per slot */
- unsigned short hash[SFQ_DEPTH]; /* Hash value indexed by slots */
- struct sk_buff_head qs[SFQ_DEPTH]; /* Slot queue */
- struct sfq_head dep[SFQ_DEPTH*2]; /* Linked list of slots, indexed by depth */
+ struct sfq_slot slots[SFQ_SLOTS];
+ struct sfq_head dep[SFQ_DEPTH]; /* Linked list of slots, indexed by depth */
};
+/*
+ * sfq_head are either in a sfq_slot or in dep[] array
+ */
+static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index val)
+{
+ if (val < SFQ_SLOTS)
+ return &q->slots[val].dep;
+ return &q->dep[val - SFQ_SLOTS];
+}
+
static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1)
{
return jhash_2words(h, h1, q->perturbation) & (SFQ_HASH_DIVISOR - 1);
@@ -200,30 +227,41 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
return 0;
}
+/*
+ * x : slot number [0 .. SFQ_SLOTS - 1]
+ */
static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
{
sfq_index p, n;
- int d = q->qs[x].qlen + SFQ_DEPTH;
+ int qlen = q->slots[x].qlen;
+
+ p = qlen + SFQ_SLOTS;
+ n = q->dep[qlen].next;
- p = d;
- n = q->dep[d].next;
- q->dep[x].next = n;
- q->dep[x].prev = p;
- q->dep[p].next = q->dep[n].prev = x;
+ q->slots[x].dep.next = n;
+ q->slots[x].dep.prev = p;
+
+ q->dep[qlen].next = x; /* sfq_dep_head(q, p)->next = x */
+ sfq_dep_head(q, n)->prev = x;
}
+#define sfq_unlink(q, x, n, p) \
+ n = q->slots[x].dep.next; \
+ p = q->slots[x].dep.prev; \
+ sfq_dep_head(q, p)->next = n; \
+ sfq_dep_head(q, n)->prev = p
+
+
static inline void sfq_dec(struct sfq_sched_data *q, sfq_index x)
{
sfq_index p, n;
+ int d;
- n = q->dep[x].next;
- p = q->dep[x].prev;
- q->dep[p].next = n;
- q->dep[n].prev = p;
-
- if (n == p && q->max_depth == q->qs[x].qlen + 1)
- q->max_depth--;
+ sfq_unlink(q, x, n, p);
+ d = q->slots[x].qlen--;
+ if (n == p && q->cur_depth == d)
+ q->cur_depth--;
sfq_link(q, x);
}
@@ -232,34 +270,74 @@ static inline void sfq_inc(struct sfq_sched_data *q, sfq_index x)
sfq_index p, n;
int d;
- n = q->dep[x].next;
- p = q->dep[x].prev;
- q->dep[p].next = n;
- q->dep[n].prev = p;
- d = q->qs[x].qlen;
- if (q->max_depth < d)
- q->max_depth = d;
+ sfq_unlink(q, x, n, p);
+ d = ++q->slots[x].qlen;
+ if (q->cur_depth < d)
+ q->cur_depth = d;
sfq_link(q, x);
}
+/* helper functions : might be changed when/if skb use a standard list_head */
+
+/* remove one skb from tail of slot queue */
+static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot)
+{
+ struct sk_buff *skb = slot->skblist_prev;
+
+ slot->skblist_prev = skb->prev;
+ skb->prev->next = (struct sk_buff *)slot;
+ skb->next = skb->prev = NULL;
+ return skb;
+}
+
+/* remove one skb from head of slot queue */
+static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
+{
+ struct sk_buff *skb = slot->skblist_next;
+
+ slot->skblist_next = skb->next;
+ skb->next->prev = (struct sk_buff *)slot;
+ skb->next = skb->prev = NULL;
+ return skb;
+}
+
+static inline void slot_queue_init(struct sfq_slot *slot)
+{
+ slot->skblist_prev = slot->skblist_next = (struct sk_buff *)slot;
+}
+
+/* add skb to slot queue (tail add) */
+static inline void slot_queue_add(struct sfq_slot *slot, struct sk_buff *skb)
+{
+ skb->prev = slot->skblist_prev;
+ skb->next = (struct sk_buff *)slot;
+ slot->skblist_prev->next = skb;
+ slot->skblist_prev = skb;
+}
+
+#define slot_queue_walk(slot, skb) \
+ for (skb = slot->skblist_next; \
+ skb != (struct sk_buff *)slot; \
+ skb = skb->next)
+
static unsigned int sfq_drop(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- sfq_index d = q->max_depth;
+ sfq_index x, d = q->cur_depth;
struct sk_buff *skb;
unsigned int len;
+ struct sfq_slot *slot;
- /* Queue is full! Find the longest slot and
- drop a packet from it */
-
+ /* Queue is full! Find the longest slot and drop tail packet from it */
if (d > 1) {
- sfq_index x = q->dep[d + SFQ_DEPTH].next;
- skb = q->qs[x].prev;
+ x = q->dep[d].next;
+ slot = &q->slots[x];
+drop:
+ skb = slot_dequeue_tail(slot);
len = qdisc_pkt_len(skb);
- __skb_unlink(skb, &q->qs[x]);
- kfree_skb(skb);
sfq_dec(q, x);
+ kfree_skb(skb);
sch->q.qlen--;
sch->qstats.drops++;
sch->qstats.backlog -= len;
@@ -268,19 +346,11 @@ static unsigned int sfq_drop(struct Qdisc *sch)
if (d == 1) {
/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
- d = q->next[q->tail];
- q->next[q->tail] = q->next[d];
- q->allot[q->next[d]] += q->quantum;
- skb = q->qs[d].prev;
- len = qdisc_pkt_len(skb);
- __skb_unlink(skb, &q->qs[d]);
- kfree_skb(skb);
- sfq_dec(q, d);
- sch->q.qlen--;
- q->ht[q->hash[d]] = SFQ_DEPTH;
- sch->qstats.drops++;
- sch->qstats.backlog -= len;
- return len;
+ x = q->tail->next;
+ slot = &q->slots[x];
+ q->tail->next = slot->next;
+ q->ht[slot->hash] = SFQ_EMPTY_SLOT;
+ goto drop;
}
return 0;
@@ -292,6 +362,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
struct sfq_sched_data *q = qdisc_priv(sch);
unsigned int hash;
sfq_index x;
+ struct sfq_slot *slot;
int uninitialized_var(ret);
hash = sfq_classify(skb, sch, &ret);
@@ -304,31 +375,32 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
hash--;
x = q->ht[hash];
- if (x == SFQ_DEPTH) {
- q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
- q->hash[x] = hash;
+ slot = &q->slots[x];
+ if (x == SFQ_EMPTY_SLOT) {
+ x = q->dep[0].next; /* get a free slot */
+ q->ht[hash] = x;
+ slot = &q->slots[x];
+ slot->hash = hash;
}
- /* If selected queue has length q->limit, this means that
- * all another queues are empty and that we do simple tail drop,
+ /* If selected queue has length q->limit, do simple tail drop,
* i.e. drop _this_ packet.
*/
- if (q->qs[x].qlen >= q->limit)
+ if (slot->qlen >= q->limit)
return qdisc_drop(skb, sch);
sch->qstats.backlog += qdisc_pkt_len(skb);
- __skb_queue_tail(&q->qs[x], skb);
+ slot_queue_add(slot, skb);
sfq_inc(q, x);
- if (q->qs[x].qlen == 1) { /* The flow is new */
- if (q->tail == SFQ_DEPTH) { /* It is the first flow */
- q->tail = x;
- q->next[x] = x;
- q->allot[x] = q->quantum;
+ if (slot->qlen == 1) { /* The flow is new */
+ if (q->tail == NULL) { /* It is the first flow */
+ slot->next = x;
} else {
- q->next[x] = q->next[q->tail];
- q->next[q->tail] = x;
- q->tail = x;
+ slot->next = q->tail->next;
+ q->tail->next = x;
}
+ q->tail = slot;
+ slot->allot = q->scaled_quantum;
}
if (++sch->q.qlen <= q->limit) {
sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -344,14 +416,12 @@ static struct sk_buff *
sfq_peek(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- sfq_index a;
/* No active slots */
- if (q->tail == SFQ_DEPTH)
+ if (q->tail == NULL)
return NULL;
- a = q->next[q->tail];
- return skb_peek(&q->qs[a]);
+ return q->slots[q->tail->next].skblist_next;
}
static struct sk_buff *
@@ -359,34 +429,37 @@ sfq_dequeue(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
struct sk_buff *skb;
- sfq_index a, old_a;
+ sfq_index a, next_a;
+ struct sfq_slot *slot;
/* No active slots */
- if (q->tail == SFQ_DEPTH)
+ if (q->tail == NULL)
return NULL;
- a = old_a = q->next[q->tail];
-
- /* Grab packet */
- skb = __skb_dequeue(&q->qs[a]);
+next_slot:
+ a = q->tail->next;
+ slot = &q->slots[a];
+ if (slot->allot <= 0) {
+ q->tail = slot;
+ slot->allot += q->scaled_quantum;
+ goto next_slot;
+ }
+ skb = slot_dequeue_head(slot);
sfq_dec(q, a);
sch->q.qlen--;
sch->qstats.backlog -= qdisc_pkt_len(skb);
/* Is the slot empty? */
- if (q->qs[a].qlen == 0) {
- q->ht[q->hash[a]] = SFQ_DEPTH;
- a = q->next[a];
- if (a == old_a) {
- q->tail = SFQ_DEPTH;
+ if (slot->qlen == 0) {
+ q->ht[slot->hash] = SFQ_EMPTY_SLOT;
+ next_a = slot->next;
+ if (a == next_a) {
+ q->tail = NULL; /* no more active slots */
return skb;
}
- q->next[q->tail] = a;
- q->allot[a] += q->quantum;
- } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) {
- q->tail = a;
- a = q->next[a];
- q->allot[a] += q->quantum;
+ q->tail->next = next_a;
+ } else {
+ slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb));
}
return skb;
}
@@ -422,6 +495,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
sch_tree_lock(sch);
q->quantum = ctl->quantum ? : psched_mtu(qdisc_dev(sch));
+ q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
q->perturb_period = ctl->perturb_period * HZ;
if (ctl->limit)
q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1);
@@ -450,19 +524,19 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
init_timer_deferrable(&q->perturb_timer);
for (i = 0; i < SFQ_HASH_DIVISOR; i++)
- q->ht[i] = SFQ_DEPTH;
+ q->ht[i] = SFQ_EMPTY_SLOT;
for (i = 0; i < SFQ_DEPTH; i++) {
- skb_queue_head_init(&q->qs[i]);
- q->dep[i + SFQ_DEPTH].next = i + SFQ_DEPTH;
- q->dep[i + SFQ_DEPTH].prev = i + SFQ_DEPTH;
+ q->dep[i].next = i + SFQ_SLOTS;
+ q->dep[i].prev = i + SFQ_SLOTS;
}
q->limit = SFQ_DEPTH - 1;
- q->max_depth = 0;
- q->tail = SFQ_DEPTH;
+ q->cur_depth = 0;
+ q->tail = NULL;
if (opt == NULL) {
q->quantum = psched_mtu(qdisc_dev(sch));
+ q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
q->perturb_period = 0;
q->perturbation = net_random();
} else {
@@ -471,8 +545,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
return err;
}
- for (i = 0; i < SFQ_DEPTH; i++)
+ for (i = 0; i < SFQ_SLOTS; i++) {
+ slot_queue_init(&q->slots[i]);
sfq_link(q, i);
+ }
return 0;
}
@@ -547,10 +623,19 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
struct gnet_dump *d)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- sfq_index idx = q->ht[cl-1];
- struct gnet_stats_queue qs = { .qlen = q->qs[idx].qlen };
- struct tc_sfq_xstats xstats = { .allot = q->allot[idx] };
+ sfq_index idx = q->ht[cl - 1];
+ struct gnet_stats_queue qs = { 0 };
+ struct tc_sfq_xstats xstats = { 0 };
+ struct sk_buff *skb;
+
+ if (idx != SFQ_EMPTY_SLOT) {
+ const struct sfq_slot *slot = &q->slots[idx];
+ xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
+ qs.qlen = slot->qlen;
+ slot_queue_walk(slot, skb)
+ qs.backlog += qdisc_pkt_len(skb);
+ }
if (gnet_stats_copy_queue(d, &qs) < 0)
return -1;
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
@@ -565,7 +650,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
return;
for (i = 0; i < SFQ_HASH_DIVISOR; i++) {
- if (q->ht[i] == SFQ_DEPTH ||
+ if (q->ht[i] == SFQ_EMPTY_SLOT ||
arg->count < arg->skip) {
arg->count++;
continue;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 401af9596709..106479a7c94a 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -309,8 +309,7 @@ restart:
if (__netif_tx_trylock(slave_txq)) {
unsigned int length = qdisc_pkt_len(skb);
- if (!netif_tx_queue_stopped(slave_txq) &&
- !netif_tx_queue_frozen(slave_txq) &&
+ if (!netif_tx_queue_frozen_or_stopped(slave_txq) &&
slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) {
txq_trans_update(slave_txq);
__netif_tx_unlock(slave_txq);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6bd554323a34..a09b0dd25f50 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
struct sctp_association *asoc = NULL;
struct sctp_setpeerprim prim;
struct sctp_chunk *chunk;
+ struct sctp_af *af;
int err;
sp = sctp_sk(sk);
@@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
if (!sctp_state(asoc, ESTABLISHED))
return -ENOTCONN;
+ af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+ if (!af)
+ return -EINVAL;
+
+ if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+ return -EADDRNOTAVAIL;
+
if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
return -EADDRNOTAVAIL;
@@ -5045,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len,
if (copy_to_user(optval, &val, len))
return -EFAULT;
- return -ENOTSUPP;
+ return 0;
}
/*
@@ -6047,7 +6055,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
* will suddenly eat the receive_queue.
*
* Look at current nfs client by the way...
- * However, this function was corrent in any case. 8)
+ * However, this function was correct in any case. 8)
*/
if (flags & MSG_PEEK) {
spin_lock_bh(&sk->sk_receive_queue.lock);
diff --git a/net/socket.c b/net/socket.c
index 3ca2fd9e3720..ccc576a6a508 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = {
*/
static DEFINE_SPINLOCK(net_family_lock);
-static const struct net_proto_family *net_families[NPROTO] __read_mostly;
+static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
/*
* Statistics counters of the socket lists
@@ -262,6 +262,7 @@ static struct inode *sock_alloc_inode(struct super_block *sb)
}
+
static void wq_free_rcu(struct rcu_head *head)
{
struct socket_wq *wq = container_of(head, struct socket_wq, rcu);
@@ -360,14 +361,14 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
if (unlikely(fd < 0))
return fd;
- path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
+ path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
if (unlikely(!path.dentry)) {
put_unused_fd(fd);
return -ENOMEM;
}
path.mnt = mntget(sock_mnt);
- path.dentry->d_op = &sockfs_dentry_operations;
+ d_set_d_op(path.dentry, &sockfs_dentry_operations);
d_instantiate(path.dentry, SOCK_INODE(sock));
SOCK_INODE(sock)->i_fop = &socket_file_ops;
@@ -732,6 +733,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
return ret;
}
+/**
+ * kernel_recvmsg - Receive a message from a socket (kernel space)
+ * @sock: The socket to receive the message from
+ * @msg: Received message
+ * @vec: Input s/g array for message data
+ * @num: Size of input s/g array
+ * @size: Number of bytes to read
+ * @flags: Message flags (MSG_DONTWAIT, etc...)
+ *
+ * On return the msg structure contains the scatter/gather array passed in the
+ * vec argument. The array is modified so that it consists of the unfilled
+ * portion of the original array.
+ *
+ * The returned value is the total number of bytes received, or an error.
+ */
int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
struct kvec *vec, size_t num, size_t size, int flags)
{
@@ -1200,7 +1216,7 @@ int __sock_create(struct net *net, int family, int type, int protocol,
* requested real, full-featured networking support upon configuration.
* Otherwise module support will break!
*/
- if (net_families[family] == NULL)
+ if (rcu_access_pointer(net_families[family]) == NULL)
request_module("net-pf-%d", family);
#endif
@@ -2332,10 +2348,11 @@ int sock_register(const struct net_proto_family *ops)
}
spin_lock(&net_family_lock);
- if (net_families[ops->family])
+ if (rcu_dereference_protected(net_families[ops->family],
+ lockdep_is_held(&net_family_lock)))
err = -EEXIST;
else {
- net_families[ops->family] = ops;
+ rcu_assign_pointer(net_families[ops->family], ops);
err = 0;
}
spin_unlock(&net_family_lock);
@@ -2363,7 +2380,7 @@ void sock_unregister(int family)
BUG_ON(family < 0 || family >= NPROTO);
spin_lock(&net_family_lock);
- net_families[family] = NULL;
+ rcu_assign_pointer(net_families[family], NULL);
spin_unlock(&net_family_lock);
synchronize_rcu();
@@ -2374,6 +2391,8 @@ EXPORT_SYMBOL(sock_unregister);
static int __init sock_init(void)
{
+ int err;
+
/*
* Initialize sock SLAB cache.
*/
@@ -2390,8 +2409,15 @@ static int __init sock_init(void)
*/
init_inodecache();
- register_filesystem(&sock_fs_type);
+
+ err = register_filesystem(&sock_fs_type);
+ if (err)
+ goto out_fs;
sock_mnt = kern_mount(&sock_fs_type);
+ if (IS_ERR(sock_mnt)) {
+ err = PTR_ERR(sock_mnt);
+ goto out_mount;
+ }
/* The real protocol initialization is performed in later initcalls.
*/
@@ -2404,7 +2430,13 @@ static int __init sock_init(void)
skb_timestamping_init();
#endif
- return 0;
+out:
+ return err;
+
+out_mount:
+ unregister_filesystem(&sock_fs_type);
+out_fs:
+ goto out;
}
core_initcall(sock_init); /* early initcall */
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index afe67849269f..67e31276682a 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -563,8 +563,17 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p)
return cred->cr_ops->crvalidate(task, p);
}
+static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
+ __be32 *data, void *obj)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data);
+ encode(rqstp, &xdr, obj);
+}
+
int
-rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
+rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp,
__be32 *data, void *obj)
{
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
@@ -574,11 +583,22 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
if (cred->cr_ops->crwrap_req)
return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj);
/* By default, we encode the arguments normally. */
- return encode(rqstp, data, obj);
+ rpcauth_wrap_req_encode(encode, rqstp, data, obj);
+ return 0;
+}
+
+static int
+rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
+ __be32 *data, void *obj)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data);
+ return decode(rqstp, &xdr, obj);
}
int
-rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
+rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp,
__be32 *data, void *obj)
{
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
@@ -589,7 +609,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
return cred->cr_ops->crunwrap_resp(task, decode, rqstp,
data, obj);
/* By default, we decode the arguments normally. */
- return decode(rqstp, data, obj);
+ return rpcauth_unwrap_req_decode(decode, rqstp, data, obj);
}
int
diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
index 7350d86a32ee..9e4cb59ef9f0 100644
--- a/net/sunrpc/auth_gss/Makefile
+++ b/net/sunrpc/auth_gss/Makefile
@@ -4,10 +4,10 @@
obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o
-auth_rpcgss-objs := auth_gss.o gss_generic_token.o \
+auth_rpcgss-y := auth_gss.o gss_generic_token.o \
gss_mech_switch.o svcauth_gss.o
obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
-rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
+rpcsec_gss_krb5-y := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 3835ce35e224..45dbf1521b9a 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1231,9 +1231,19 @@ out_bad:
return NULL;
}
+static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
+ __be32 *p, void *obj)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p);
+ encode(rqstp, &xdr, obj);
+}
+
static inline int
gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
+ kxdreproc_t encode, struct rpc_rqst *rqstp,
+ __be32 *p, void *obj)
{
struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
struct xdr_buf integ_buf;
@@ -1249,9 +1259,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
*p++ = htonl(rqstp->rq_seqno);
- status = encode(rqstp, p, obj);
- if (status)
- return status;
+ gss_wrap_req_encode(encode, rqstp, p, obj);
if (xdr_buf_subsegment(snd_buf, &integ_buf,
offset, snd_buf->len - offset))
@@ -1325,7 +1333,8 @@ out:
static inline int
gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
- kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
+ kxdreproc_t encode, struct rpc_rqst *rqstp,
+ __be32 *p, void *obj)
{
struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
u32 offset;
@@ -1342,9 +1351,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
*p++ = htonl(rqstp->rq_seqno);
- status = encode(rqstp, p, obj);
- if (status)
- return status;
+ gss_wrap_req_encode(encode, rqstp, p, obj);
status = alloc_enc_pages(rqstp);
if (status)
@@ -1394,7 +1401,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
static int
gss_wrap_req(struct rpc_task *task,
- kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
+ kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
{
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
@@ -1407,12 +1414,14 @@ gss_wrap_req(struct rpc_task *task,
/* The spec seems a little ambiguous here, but I think that not
* wrapping context destruction requests makes the most sense.
*/
- status = encode(rqstp, p, obj);
+ gss_wrap_req_encode(encode, rqstp, p, obj);
+ status = 0;
goto out;
}
switch (gss_cred->gc_service) {
case RPC_GSS_SVC_NONE:
- status = encode(rqstp, p, obj);
+ gss_wrap_req_encode(encode, rqstp, p, obj);
+ status = 0;
break;
case RPC_GSS_SVC_INTEGRITY:
status = gss_wrap_req_integ(cred, ctx, encode,
@@ -1494,10 +1503,19 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
return 0;
}
+static int
+gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
+ __be32 *p, void *obj)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ return decode(rqstp, &xdr, obj);
+}
static int
gss_unwrap_resp(struct rpc_task *task,
- kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
+ kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
{
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
@@ -1528,7 +1546,7 @@ gss_unwrap_resp(struct rpc_task *task,
cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
+ (savedlen - head->iov_len);
out_decode:
- status = decode(rqstp, p, obj);
+ status = gss_unwrap_req_decode(decode, rqstp, p, obj);
out:
gss_put_ctx(ctx);
dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid,
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 75ee993ea057..9576f35ab701 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4])
ms_usage = 13;
break;
default:
- return EINVAL;;
+ return -EINVAL;
}
salt[0] = (ms_usage >> 0) & 0xff;
salt[1] = (ms_usage >> 8) & 0xff;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index dec2a6fc7c12..bcdae78fdfc6 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b)
#define RSI_HASHBITS 6
#define RSI_HASHMAX (1<<RSI_HASHBITS)
-#define RSI_HASHMASK (RSI_HASHMAX-1)
struct rsi {
struct cache_head h;
@@ -319,7 +318,6 @@ static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
#define RSC_HASHBITS 10
#define RSC_HASHMAX (1<<RSC_HASHBITS)
-#define RSC_HASHMASK (RSC_HASHMAX-1)
#define GSS_SEQ_WIN 128
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index e433e7580e27..72ad836e4fe0 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -37,7 +37,7 @@
#define RPCDBG_FACILITY RPCDBG_CACHE
-static void cache_defer_req(struct cache_req *req, struct cache_head *item);
+static bool cache_defer_req(struct cache_req *req, struct cache_head *item);
static void cache_revisit_request(struct cache_head *item);
static void cache_init(struct cache_head *h)
@@ -128,6 +128,7 @@ static void cache_fresh_locked(struct cache_head *head, time_t expiry)
{
head->expiry_time = expiry;
head->last_refresh = seconds_since_boot();
+ smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */
set_bit(CACHE_VALID, &head->flags);
}
@@ -208,11 +209,36 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head
/* entry is valid */
if (test_bit(CACHE_NEGATIVE, &h->flags))
return -ENOENT;
- else
+ else {
+ /*
+ * In combination with write barrier in
+ * sunrpc_cache_update, ensures that anyone
+ * using the cache entry after this sees the
+ * updated contents:
+ */
+ smp_rmb();
return 0;
+ }
}
}
+static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h)
+{
+ int rv;
+
+ write_lock(&detail->hash_lock);
+ rv = cache_is_valid(detail, h);
+ if (rv != -EAGAIN) {
+ write_unlock(&detail->hash_lock);
+ return rv;
+ }
+ set_bit(CACHE_NEGATIVE, &h->flags);
+ cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
+ write_unlock(&detail->hash_lock);
+ cache_fresh_unlocked(h, detail);
+ return -ENOENT;
+}
+
/*
* This is the generic cache management routine for all
* the authentication caches.
@@ -251,14 +277,8 @@ int cache_check(struct cache_detail *detail,
case -EINVAL:
clear_bit(CACHE_PENDING, &h->flags);
cache_revisit_request(h);
- if (rv == -EAGAIN) {
- set_bit(CACHE_NEGATIVE, &h->flags);
- cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
- cache_fresh_unlocked(h, detail);
- rv = -ENOENT;
- }
+ rv = try_to_negate_entry(detail, h);
break;
-
case -EAGAIN:
clear_bit(CACHE_PENDING, &h->flags);
cache_revisit_request(h);
@@ -268,9 +288,11 @@ int cache_check(struct cache_detail *detail,
}
if (rv == -EAGAIN) {
- cache_defer_req(rqstp, h);
- if (!test_bit(CACHE_PENDING, &h->flags)) {
- /* Request is not deferred */
+ if (!cache_defer_req(rqstp, h)) {
+ /*
+ * Request was not deferred; handle it as best
+ * we can ourselves:
+ */
rv = cache_is_valid(detail, h);
if (rv == -EAGAIN)
rv = -ETIMEDOUT;
@@ -618,18 +640,19 @@ static void cache_limit_defers(void)
discard->revisit(discard, 1);
}
-static void cache_defer_req(struct cache_req *req, struct cache_head *item)
+/* Return true if and only if a deferred request is queued. */
+static bool cache_defer_req(struct cache_req *req, struct cache_head *item)
{
struct cache_deferred_req *dreq;
if (req->thread_wait) {
cache_wait_req(req, item);
if (!test_bit(CACHE_PENDING, &item->flags))
- return;
+ return false;
}
dreq = req->defer(req);
if (dreq == NULL)
- return;
+ return false;
setup_deferral(dreq, item, 1);
if (!test_bit(CACHE_PENDING, &item->flags))
/* Bit could have been cleared before we managed to
@@ -638,6 +661,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
cache_revisit_request(item);
cache_limit_defers();
+ return true;
}
static void cache_revisit_request(struct cache_head *item)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 92ce94f5146b..57d344cf2256 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1095,7 +1095,7 @@ static void
rpc_xdr_encode(struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
- kxdrproc_t encode;
+ kxdreproc_t encode;
__be32 *p;
dprint_status(task);
@@ -1535,7 +1535,7 @@ call_decode(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
- kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode;
+ kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode;
__be32 *p;
dprintk("RPC: %5u call_decode (status %d)\n",
@@ -1776,12 +1776,11 @@ out_overflow:
goto out_garbage;
}
-static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj)
+static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj)
{
- return 0;
}
-static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj)
+static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj)
{
return 0;
}
@@ -1830,23 +1829,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt,
const struct rpc_task *task)
{
const char *rpc_waitq = "none";
- char *p, action[KSYM_SYMBOL_LEN];
if (RPC_IS_QUEUED(task))
rpc_waitq = rpc_qname(task->tk_waitqueue);
- /* map tk_action pointer to a function name; then trim off
- * the "+0x0 [sunrpc]" */
- sprint_symbol(action, (unsigned long)task->tk_action);
- p = strchr(action, '+');
- if (p)
- *p = '\0';
-
- printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n",
+ printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n",
task->tk_pid, task->tk_flags, task->tk_status,
clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops,
clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task),
- action, rpc_waitq);
+ task->tk_action, rpc_waitq);
}
void rpc_show_tasks(void)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 10a17a37ec4e..72bc53683965 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -162,11 +162,19 @@ rpc_alloc_inode(struct super_block *sb)
}
static void
-rpc_destroy_inode(struct inode *inode)
+rpc_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(rpc_inode_cachep, RPC_I(inode));
}
+static void
+rpc_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, rpc_i_callback);
+}
+
static int
rpc_pipe_open(struct inode *inode, struct file *filp)
{
@@ -430,7 +438,7 @@ void rpc_put_mount(void)
}
EXPORT_SYMBOL_GPL(rpc_put_mount);
-static int rpc_delete_dentry(struct dentry *dentry)
+static int rpc_delete_dentry(const struct dentry *dentry)
{
return 1;
}
@@ -466,7 +474,7 @@ static int __rpc_create_common(struct inode *dir, struct dentry *dentry,
{
struct inode *inode;
- BUG_ON(!d_unhashed(dentry));
+ d_drop(dentry);
inode = rpc_get_inode(dir->i_sb, mode);
if (!inode)
goto out_err;
@@ -583,7 +591,7 @@ static struct dentry *__rpc_lookup_create(struct dentry *parent,
}
}
if (!dentry->d_inode)
- dentry->d_op = &rpc_dentry_operations;
+ d_set_d_op(dentry, &rpc_dentry_operations);
out_err:
return dentry;
}
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index fa6d7ca2c851..c652e4cc9fe9 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -57,10 +57,6 @@ enum {
RPCBPROC_GETSTAT,
};
-#define RPCB_HIGHPROC_2 RPCBPROC_CALLIT
-#define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR
-#define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT
-
/*
* r_owner
*
@@ -693,46 +689,37 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
* XDR functions for rpcbind
*/
-static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p,
- const struct rpcbind_args *rpcb)
+static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct rpcbind_args *rpcb)
{
struct rpc_task *task = req->rq_task;
- struct xdr_stream xdr;
+ __be32 *p;
dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
task->tk_pid, task->tk_msg.rpc_proc->p_name,
rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
-
- p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz);
- if (unlikely(p == NULL))
- return -EIO;
-
- *p++ = htonl(rpcb->r_prog);
- *p++ = htonl(rpcb->r_vers);
- *p++ = htonl(rpcb->r_prot);
- *p = htonl(rpcb->r_port);
-
- return 0;
+ p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
+ *p++ = cpu_to_be32(rpcb->r_prog);
+ *p++ = cpu_to_be32(rpcb->r_vers);
+ *p++ = cpu_to_be32(rpcb->r_prot);
+ *p = cpu_to_be32(rpcb->r_port);
}
-static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p,
+static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
struct rpcbind_args *rpcb)
{
struct rpc_task *task = req->rq_task;
- struct xdr_stream xdr;
unsigned long port;
-
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ __be32 *p;
rpcb->r_port = 0;
- p = xdr_inline_decode(&xdr, sizeof(__be32));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
- port = ntohl(*p);
+ port = be32_to_cpup(p);
dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid,
task->tk_msg.rpc_proc->p_name, port);
if (unlikely(port > USHRT_MAX))
@@ -742,20 +729,18 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p,
return 0;
}
-static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p,
+static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
unsigned int *boolp)
{
struct rpc_task *task = req->rq_task;
- struct xdr_stream xdr;
-
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ __be32 *p;
- p = xdr_inline_decode(&xdr, sizeof(__be32));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
return -EIO;
*boolp = 0;
- if (*p)
+ if (*p != xdr_zero)
*boolp = 1;
dprintk("RPC: %5u RPCB_%s call %s\n",
@@ -764,73 +749,53 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p,
return 0;
}
-static int encode_rpcb_string(struct xdr_stream *xdr, const char *string,
- const u32 maxstrlen)
+static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
+ const u32 maxstrlen)
{
- u32 len;
__be32 *p;
+ u32 len;
- if (unlikely(string == NULL))
- return -EIO;
len = strlen(string);
- if (unlikely(len > maxstrlen))
- return -EIO;
-
- p = xdr_reserve_space(xdr, sizeof(__be32) + len);
- if (unlikely(p == NULL))
- return -EIO;
+ BUG_ON(len > maxstrlen);
+ p = xdr_reserve_space(xdr, 4 + len);
xdr_encode_opaque(p, string, len);
-
- return 0;
}
-static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p,
- const struct rpcbind_args *rpcb)
+static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
+ const struct rpcbind_args *rpcb)
{
struct rpc_task *task = req->rq_task;
- struct xdr_stream xdr;
+ __be32 *p;
dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
task->tk_pid, task->tk_msg.rpc_proc->p_name,
rpcb->r_prog, rpcb->r_vers,
rpcb->r_netid, rpcb->r_addr);
- xdr_init_encode(&xdr, &req->rq_snd_buf, p);
-
- p = xdr_reserve_space(&xdr,
- sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz));
- if (unlikely(p == NULL))
- return -EIO;
- *p++ = htonl(rpcb->r_prog);
- *p = htonl(rpcb->r_vers);
-
- if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN))
- return -EIO;
- if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN))
- return -EIO;
- if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN))
- return -EIO;
+ p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
+ *p++ = cpu_to_be32(rpcb->r_prog);
+ *p = cpu_to_be32(rpcb->r_vers);
- return 0;
+ encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
+ encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
+ encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
}
-static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p,
+static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
struct rpcbind_args *rpcb)
{
struct sockaddr_storage address;
struct sockaddr *sap = (struct sockaddr *)&address;
struct rpc_task *task = req->rq_task;
- struct xdr_stream xdr;
+ __be32 *p;
u32 len;
rpcb->r_port = 0;
- xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
-
- p = xdr_inline_decode(&xdr, sizeof(__be32));
+ p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
goto out_fail;
- len = ntohl(*p);
+ len = be32_to_cpup(p);
/*
* If the returned universal address is a null string,
@@ -845,7 +810,7 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p,
if (unlikely(len > RPCBIND_MAXUADDRLEN))
goto out_fail;
- p = xdr_inline_decode(&xdr, len);
+ p = xdr_inline_decode(xdr, len);
if (unlikely(p == NULL))
goto out_fail;
dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
@@ -871,8 +836,8 @@ out_fail:
static struct rpc_procinfo rpcb_procedures2[] = {
[RPCBPROC_SET] = {
.p_proc = RPCBPROC_SET,
- .p_encode = (kxdrproc_t)rpcb_enc_mapping,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_mapping,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_mappingargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_SET,
@@ -881,8 +846,8 @@ static struct rpc_procinfo rpcb_procedures2[] = {
},
[RPCBPROC_UNSET] = {
.p_proc = RPCBPROC_UNSET,
- .p_encode = (kxdrproc_t)rpcb_enc_mapping,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_mapping,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_mappingargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_UNSET,
@@ -891,8 +856,8 @@ static struct rpc_procinfo rpcb_procedures2[] = {
},
[RPCBPROC_GETPORT] = {
.p_proc = RPCBPROC_GETPORT,
- .p_encode = (kxdrproc_t)rpcb_enc_mapping,
- .p_decode = (kxdrproc_t)rpcb_dec_getport,
+ .p_encode = (kxdreproc_t)rpcb_enc_mapping,
+ .p_decode = (kxdrdproc_t)rpcb_dec_getport,
.p_arglen = RPCB_mappingargs_sz,
.p_replen = RPCB_getportres_sz,
.p_statidx = RPCBPROC_GETPORT,
@@ -904,8 +869,8 @@ static struct rpc_procinfo rpcb_procedures2[] = {
static struct rpc_procinfo rpcb_procedures3[] = {
[RPCBPROC_SET] = {
.p_proc = RPCBPROC_SET,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_SET,
@@ -914,8 +879,8 @@ static struct rpc_procinfo rpcb_procedures3[] = {
},
[RPCBPROC_UNSET] = {
.p_proc = RPCBPROC_UNSET,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_UNSET,
@@ -924,8 +889,8 @@ static struct rpc_procinfo rpcb_procedures3[] = {
},
[RPCBPROC_GETADDR] = {
.p_proc = RPCBPROC_GETADDR,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_getaddr,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_getaddrres_sz,
.p_statidx = RPCBPROC_GETADDR,
@@ -937,8 +902,8 @@ static struct rpc_procinfo rpcb_procedures3[] = {
static struct rpc_procinfo rpcb_procedures4[] = {
[RPCBPROC_SET] = {
.p_proc = RPCBPROC_SET,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_SET,
@@ -947,8 +912,8 @@ static struct rpc_procinfo rpcb_procedures4[] = {
},
[RPCBPROC_UNSET] = {
.p_proc = RPCBPROC_UNSET,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_set,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_set,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_setres_sz,
.p_statidx = RPCBPROC_UNSET,
@@ -957,8 +922,8 @@ static struct rpc_procinfo rpcb_procedures4[] = {
},
[RPCBPROC_GETADDR] = {
.p_proc = RPCBPROC_GETADDR,
- .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
- .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
+ .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
+ .p_decode = (kxdrdproc_t)rpcb_dec_getaddr,
.p_arglen = RPCB_getaddrargs_sz,
.p_replen = RPCB_getaddrres_sz,
.p_statidx = RPCBPROC_GETADDR,
@@ -993,19 +958,19 @@ static struct rpcb_info rpcb_next_version6[] = {
static struct rpc_version rpcb_version2 = {
.number = RPCBVERS_2,
- .nrprocs = RPCB_HIGHPROC_2,
+ .nrprocs = ARRAY_SIZE(rpcb_procedures2),
.procs = rpcb_procedures2
};
static struct rpc_version rpcb_version3 = {
.number = RPCBVERS_3,
- .nrprocs = RPCB_HIGHPROC_3,
+ .nrprocs = ARRAY_SIZE(rpcb_procedures3),
.procs = rpcb_procedures3
};
static struct rpc_version rpcb_version4 = {
.number = RPCBVERS_4,
- .nrprocs = RPCB_HIGHPROC_4,
+ .nrprocs = ARRAY_SIZE(rpcb_procedures4),
.procs = rpcb_procedures4
};
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 6359c42c4941..df1931f8ae98 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1005,6 +1005,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
rqstp->rq_splice_ok = 1;
/* Will be turned off only when NFSv4 Sessions are used */
rqstp->rq_usedeferral = 1;
+ rqstp->rq_dropme = false;
/* Setup reply header */
rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
@@ -1106,7 +1107,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
*statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
/* Encode reply */
- if (*statp == rpc_drop_reply) {
+ if (rqstp->rq_dropme) {
if (procp->pc_release)
procp->pc_release(rqstp, NULL, rqstp->rq_resp);
goto dropit;
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ea2ff78dcf7b..173f3b975d49 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
spin_lock(&svc_xprt_class_lock);
list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
struct svc_xprt *newxprt;
+ unsigned short newport;
if (strcmp(xprt_name, xcl->xcl_name))
continue;
@@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
spin_lock_bh(&serv->sv_lock);
list_add(&newxprt->xpt_list, &serv->sv_permsocks);
spin_unlock_bh(&serv->sv_lock);
+ newport = svc_xprt_local_port(newxprt);
clear_bit(XPT_BUSY, &newxprt->xpt_flags);
- return svc_xprt_local_port(newxprt);
+ return newport;
}
err:
spin_unlock(&svc_xprt_class_lock);
@@ -301,6 +303,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
list_del(&rqstp->rq_list);
}
+static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
+{
+ if (xprt->xpt_flags & ((1<<XPT_CONN)|(1<<XPT_CLOSE)))
+ return true;
+ if (xprt->xpt_flags & ((1<<XPT_DATA)|(1<<XPT_DEFERRED)))
+ return xprt->xpt_ops->xpo_has_wspace(xprt);
+ return false;
+}
+
/*
* Queue up a transport with data pending. If there are idle nfsd
* processes, wake 'em up.
@@ -313,8 +324,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
struct svc_rqst *rqstp;
int cpu;
- if (!(xprt->xpt_flags &
- ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
+ if (!svc_xprt_has_something_to_do(xprt))
return;
cpu = get_cpu();
@@ -341,28 +351,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
dprintk("svc: transport %p busy, not enqueued\n", xprt);
goto out_unlock;
}
- BUG_ON(xprt->xpt_pool != NULL);
- xprt->xpt_pool = pool;
-
- /* Handle pending connection */
- if (test_bit(XPT_CONN, &xprt->xpt_flags))
- goto process;
-
- /* Handle close in-progress */
- if (test_bit(XPT_CLOSE, &xprt->xpt_flags))
- goto process;
-
- /* Check if we have space to reply to a request */
- if (!xprt->xpt_ops->xpo_has_wspace(xprt)) {
- /* Don't enqueue while not enough space for reply */
- dprintk("svc: no write space, transport %p not enqueued\n",
- xprt);
- xprt->xpt_pool = NULL;
- clear_bit(XPT_BUSY, &xprt->xpt_flags);
- goto out_unlock;
- }
- process:
if (!list_empty(&pool->sp_threads)) {
rqstp = list_entry(pool->sp_threads.next,
struct svc_rqst,
@@ -379,13 +368,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
rqstp->rq_reserved = serv->sv_max_mesg;
atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
pool->sp_stats.threads_woken++;
- BUG_ON(xprt->xpt_pool != pool);
wake_up(&rqstp->rq_wait);
} else {
dprintk("svc: transport %p put into queue\n", xprt);
list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
pool->sp_stats.sockets_queued++;
- BUG_ON(xprt->xpt_pool != pool);
}
out_unlock:
@@ -424,9 +411,13 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
void svc_xprt_received(struct svc_xprt *xprt)
{
BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
- xprt->xpt_pool = NULL;
+ /* As soon as we clear busy, the xprt could be closed and
+ * 'put', so we need a reference to call svc_xprt_enqueue with:
+ */
+ svc_xprt_get(xprt);
clear_bit(XPT_BUSY, &xprt->xpt_flags);
svc_xprt_enqueue(xprt);
+ svc_xprt_put(xprt);
}
EXPORT_SYMBOL_GPL(svc_xprt_received);
@@ -715,7 +706,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
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)) {
+ /* Leave XPT_BUSY set on the dead xprt: */
+ goto out;
+ }
+ if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
struct svc_xprt *newxpt;
newxpt = xprt->xpt_ops->xpo_accept(xprt);
if (newxpt) {
@@ -740,28 +734,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
spin_unlock_bh(&serv->sv_lock);
svc_xprt_received(newxpt);
}
- svc_xprt_received(xprt);
- } else {
+ } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
rqstp, pool->sp_id, xprt,
atomic_read(&xprt->xpt_ref.refcount));
rqstp->rq_deferred = svc_deferred_dequeue(xprt);
- if (rqstp->rq_deferred) {
- svc_xprt_received(xprt);
+ if (rqstp->rq_deferred)
len = svc_deferred_recv(rqstp);
- } else {
+ else
len = xprt->xpt_ops->xpo_recvfrom(rqstp);
- svc_xprt_received(xprt);
- }
dprintk("svc: got len=%d\n", len);
}
+ svc_xprt_received(xprt);
/* No data, incomplete (TCP) read, or accept() */
- if (len == 0 || len == -EAGAIN) {
- rqstp->rq_res.len = 0;
- svc_xprt_release(rqstp);
- return -EAGAIN;
- }
+ if (len == 0 || len == -EAGAIN)
+ goto out;
+
clear_bit(XPT_OLD, &xprt->xpt_flags);
rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
@@ -770,6 +759,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
if (serv->sv_stats)
serv->sv_stats->netcnt++;
return len;
+out:
+ rqstp->rq_res.len = 0;
+ svc_xprt_release(rqstp);
+ return -EAGAIN;
}
EXPORT_SYMBOL_GPL(svc_recv);
@@ -928,7 +921,12 @@ void svc_close_xprt(struct svc_xprt *xprt)
if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
/* someone else will have to effect the close */
return;
-
+ /*
+ * We expect svc_close_xprt() to work even when no threads are
+ * running (e.g., while configuring the server before starting
+ * any threads), so if the transport isn't busy, we delete
+ * it ourself:
+ */
svc_delete_xprt(xprt);
}
EXPORT_SYMBOL_GPL(svc_close_xprt);
@@ -938,16 +936,16 @@ void svc_close_all(struct list_head *xprt_list)
struct svc_xprt *xprt;
struct svc_xprt *tmp;
+ /*
+ * The server is shutting down, and no more threads are running.
+ * svc_xprt_enqueue() might still be running, but at worst it
+ * will re-add the xprt to sp_sockets, which will soon get
+ * freed. So we don't bother with any more locking, and don't
+ * leave the close to the (nonexistent) server threads:
+ */
list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
set_bit(XPT_CLOSE, &xprt->xpt_flags);
- if (test_bit(XPT_BUSY, &xprt->xpt_flags)) {
- /* Waiting to be processed, but no threads left,
- * So just remove it from the waiting list
- */
- list_del_init(&xprt->xpt_ready);
- clear_bit(XPT_BUSY, &xprt->xpt_flags);
- }
- svc_close_xprt(xprt);
+ svc_delete_xprt(xprt);
}
}
@@ -1021,6 +1019,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
}
svc_xprt_get(rqstp->rq_xprt);
dr->xprt = rqstp->rq_xprt;
+ rqstp->rq_dropme = true;
dr->handle.revisit = svc_revisit;
return &dr->handle;
@@ -1058,14 +1057,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags))
return NULL;
spin_lock(&xprt->xpt_lock);
- clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
if (!list_empty(&xprt->xpt_deferred)) {
dr = list_entry(xprt->xpt_deferred.next,
struct svc_deferred_req,
handle.recent);
list_del_init(&dr->handle.recent);
- set_bit(XPT_DEFERRED, &xprt->xpt_flags);
- }
+ } else
+ clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
spin_unlock(&xprt->xpt_lock);
return dr;
}
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 4e9393c24687..7963569fc04f 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -118,7 +118,6 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister);
#define DN_HASHBITS 6
#define DN_HASHMAX (1<<DN_HASHBITS)
-#define DN_HASHMASK (DN_HASHMAX-1)
static struct hlist_head auth_domain_table[DN_HASHMAX];
static spinlock_t auth_domain_lock =
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 560677d187f1..30916b06c12b 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -30,7 +30,9 @@
struct unix_domain {
struct auth_domain h;
+#ifdef CONFIG_NFSD_DEPRECATED
int addr_changes;
+#endif /* CONFIG_NFSD_DEPRECATED */
/* other stuff later */
};
@@ -64,7 +66,9 @@ struct auth_domain *unix_domain_find(char *name)
return NULL;
}
new->h.flavour = &svcauth_unix;
+#ifdef CONFIG_NFSD_DEPRECATED
new->addr_changes = 0;
+#endif /* CONFIG_NFSD_DEPRECATED */
rv = auth_domain_lookup(name, &new->h);
}
}
@@ -85,14 +89,15 @@ static void svcauth_unix_domain_release(struct auth_domain *dom)
*/
#define IP_HASHBITS 8
#define IP_HASHMAX (1<<IP_HASHBITS)
-#define IP_HASHMASK (IP_HASHMAX-1)
struct ip_map {
struct cache_head h;
char m_class[8]; /* e.g. "nfsd" */
struct in6_addr m_addr;
struct unix_domain *m_client;
+#ifdef CONFIG_NFSD_DEPRECATED
int m_add_change;
+#endif /* CONFIG_NFSD_DEPRECATED */
};
static void ip_map_put(struct kref *kref)
@@ -146,7 +151,9 @@ static void update(struct cache_head *cnew, struct cache_head *citem)
kref_get(&item->m_client->h.ref);
new->m_client = item->m_client;
+#ifdef CONFIG_NFSD_DEPRECATED
new->m_add_change = item->m_add_change;
+#endif /* CONFIG_NFSD_DEPRECATED */
}
static struct cache_head *ip_map_alloc(void)
{
@@ -331,6 +338,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
ip.h.flags = 0;
if (!udom)
set_bit(CACHE_NEGATIVE, &ip.h.flags);
+#ifdef CONFIG_NFSD_DEPRECATED
else {
ip.m_add_change = udom->addr_changes;
/* if this is from the legacy set_client system call,
@@ -339,6 +347,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
if (expiry == NEVER)
ip.m_add_change++;
}
+#endif /* CONFIG_NFSD_DEPRECATED */
ip.h.expiry_time = expiry;
ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
hash_str(ipm->m_class, IP_HASHBITS) ^
@@ -358,6 +367,7 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm,
return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
}
+#ifdef CONFIG_NFSD_DEPRECATED
int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom)
{
struct unix_domain *udom;
@@ -402,8 +412,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
return NULL;
if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) {
- if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0)
- auth_domain_put(&ipm->m_client->h);
+ sunrpc_invalidate(&ipm->h, sn->ip_map_cache);
rv = NULL;
} else {
rv = &ipm->m_client->h;
@@ -413,6 +422,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
return rv;
}
EXPORT_SYMBOL_GPL(auth_unix_lookup);
+#endif /* CONFIG_NFSD_DEPRECATED */
void svcauth_unix_purge(void)
{
@@ -497,7 +507,6 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
*/
#define GID_HASHBITS 8
#define GID_HASHMAX (1<<GID_HASHBITS)
-#define GID_HASHMASK (GID_HASHMAX - 1)
struct unix_gid {
struct cache_head h;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 07919e16be3e..52bd1130e83a 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -324,19 +324,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
len = onelen;
break;
}
- if (toclose && strcmp(toclose, buf + len) == 0)
+ if (toclose && strcmp(toclose, buf + len) == 0) {
closesk = svsk;
- else
+ svc_xprt_get(&closesk->sk_xprt);
+ } else
len += onelen;
}
spin_unlock_bh(&serv->sv_lock);
- if (closesk)
+ if (closesk) {
/* Should unregister with portmap, but you cannot
* unregister just one protocol...
*/
svc_close_xprt(&closesk->sk_xprt);
- else if (toclose)
+ svc_xprt_put(&closesk->sk_xprt);
+ } else if (toclose)
return -ENOENT;
return len;
}
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index b74f78d0c033..0436927369f3 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -29,28 +29,6 @@ config TIPC_ADVANCED
Saying Y here will open some advanced configuration for TIPC.
Most users do not need to bother; if unsure, just say N.
-config TIPC_ZONES
- int "Maximum number of zones in a network"
- depends on TIPC_ADVANCED
- range 1 255
- default "3"
- help
- Specifies how many zones can be supported in a TIPC network.
- Can range from 1 to 255 zones; default is 3.
-
- Setting this to a smaller value saves some memory;
- setting it to a higher value allows for more zones.
-
-config TIPC_CLUSTERS
- int "Maximum number of clusters in a zone"
- depends on TIPC_ADVANCED
- range 1 1
- default "1"
- help
- Specifies how many clusters can be supported in a TIPC zone.
-
- *** Currently TIPC only supports a single cluster per zone. ***
-
config TIPC_NODES
int "Maximum number of nodes in a cluster"
depends on TIPC_ADVANCED
@@ -72,7 +50,7 @@ config TIPC_PORTS
Specifies how many ports can be supported by a node.
Can range from 127 to 65535 ports; default is 8191.
- Setting this to a smaller value saves some memory,
+ Setting this to a smaller value saves some memory,
setting it to higher allows for more ports.
config TIPC_LOG
@@ -89,12 +67,15 @@ config TIPC_LOG
managed remotely via TIPC.
config TIPC_DEBUG
- bool "Enable debug messages"
+ bool "Enable debugging support"
default n
help
- This enables debugging of TIPC.
+ Saying Y here enables TIPC debugging capabilities used by developers.
+ Most users do not need to bother; if unsure, just say N.
- Only say Y here if you are having trouble with TIPC. It will
- enable the display of detailed information about what is going on.
+ Enabling debugging support causes TIPC to display data about its
+ internal state when certain abnormal conditions occur. It also
+ makes it easy for developers to capture additional information of
+ interest using the dbg() or msg_dbg() macros.
endif # TIPC
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index dceb7027946c..521d24d04ab2 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -4,10 +4,10 @@
obj-$(CONFIG_TIPC) := tipc.o
-tipc-y += addr.o bcast.o bearer.o config.o cluster.o \
+tipc-y += addr.o bcast.o bearer.o config.o \
core.o handler.o link.o discover.o msg.o \
name_distr.o subscr.o name_table.o net.o \
netlink.o node.o node_subscr.o port.o ref.o \
- socket.o user_reg.o zone.o dbg.o eth_media.o
+ socket.o log.o eth_media.o
# End of file
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 8a2e89bffde5..88463d9a6f12 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -35,11 +35,7 @@
*/
#include "core.h"
-#include "dbg.h"
#include "addr.h"
-#include "zone.h"
-#include "cluster.h"
-#include "net.h"
/**
* tipc_addr_domain_valid - validates a network domain address
@@ -57,14 +53,8 @@ int tipc_addr_domain_valid(u32 addr)
u32 z = tipc_zone(addr);
u32 max_nodes = tipc_max_nodes;
- if (is_slave(addr))
- max_nodes = LOWEST_SLAVE + tipc_max_slaves;
if (n > max_nodes)
return 0;
- if (c > tipc_max_clusters)
- return 0;
- if (z > tipc_max_zones)
- return 0;
if (n && (!z || !c))
return 0;
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index c1cc5724d8cc..2490fadd0caf 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,36 +37,11 @@
#ifndef _TIPC_ADDR_H
#define _TIPC_ADDR_H
-static inline u32 own_node(void)
-{
- return tipc_node(tipc_own_addr);
-}
-
-static inline u32 own_cluster(void)
-{
- return tipc_cluster(tipc_own_addr);
-}
-
-static inline u32 own_zone(void)
-{
- return tipc_zone(tipc_own_addr);
-}
-
static inline int in_own_cluster(u32 addr)
{
return !((addr ^ tipc_own_addr) >> 12);
}
-static inline int is_slave(u32 addr)
-{
- return addr & 0x800;
-}
-
-static inline int may_route(u32 addr)
-{
- return(addr ^ tipc_own_addr) >> 11;
-}
-
/**
* addr_domain - convert 2-bit scope value to equivalent message lookup domain
*
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 22a60fc98392..70ab5ef48766 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -36,25 +36,14 @@
*/
#include "core.h"
-#include "msg.h"
-#include "dbg.h"
#include "link.h"
-#include "net.h"
-#include "node.h"
#include "port.h"
-#include "addr.h"
-#include "node_subscr.h"
-#include "name_distr.h"
-#include "bearer.h"
-#include "name_table.h"
#include "bcast.h"
#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
-#define BCLINK_LOG_BUF_SIZE 0
-
/*
* Loss rate for incoming broadcast frames; used to test retransmission code.
* Set to N to cause every N'th frame to be discarded; 0 => don't discard any.
@@ -114,11 +103,14 @@ struct bclink {
};
-static struct bcbearer *bcbearer = NULL;
-static struct bclink *bclink = NULL;
-static struct link *bcl = NULL;
+static struct bcbearer *bcbearer;
+static struct bclink *bclink;
+static struct link *bcl;
static DEFINE_SPINLOCK(bc_lock);
+/* broadcast-capable node map */
+struct tipc_node_map tipc_bcast_nmap;
+
const char tipc_bclink_name[] = "broadcast-link";
static void tipc_nmap_diff(struct tipc_node_map *nm_a,
@@ -204,9 +196,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
struct sk_buff *buf;
buf = bcl->first_out;
- while (buf && less_eq(buf_seqno(buf), after)) {
+ while (buf && less_eq(buf_seqno(buf), after))
buf = buf->next;
- }
tipc_link_retransmit(bcl, buf, mod(to - after));
}
@@ -232,9 +223,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
/* Skip over packets that node has previously acknowledged */
crs = bcl->first_out;
- while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) {
+ while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
crs = crs->next;
- }
/* Update packets that node is now acknowledging */
@@ -433,16 +423,14 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
void tipc_bclink_recv_pkt(struct sk_buff *buf)
{
#if (TIPC_BCAST_LOSS_RATE)
- static int rx_count = 0;
+ static int rx_count;
#endif
struct tipc_msg *msg = buf_msg(buf);
- struct tipc_node* node = tipc_node_find(msg_prevnode(msg));
+ struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
u32 next_in;
u32 seqno;
struct sk_buff *deferred;
- msg_dbg(msg, "<BC<<<");
-
if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported ||
(msg_mc_netid(msg) != tipc_net_id))) {
buf_discard(buf);
@@ -450,7 +438,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
}
if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
- msg_dbg(msg, "<BCNACK<<<");
if (msg_destnode(msg) == tipc_own_addr) {
tipc_node_lock(node);
tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
@@ -574,8 +561,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
if (likely(!msg_non_seq(buf_msg(buf)))) {
struct tipc_msg *msg;
- assert(tipc_cltr_bcast_nodes.count != 0);
- bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count);
+ assert(tipc_bcast_nmap.count != 0);
+ bcbuf_set_acks(buf, tipc_bcast_nmap.count);
msg = buf_msg(buf);
msg_set_non_seq(msg, 1);
msg_set_mc_netid(msg, tipc_net_id);
@@ -584,7 +571,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
/* Send buffer over bearers until all targets reached */
- bcbearer->remains = tipc_cltr_bcast_nodes;
+ bcbearer->remains = tipc_bcast_nmap;
for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
struct bearer *p = bcbearer->bpairs[bp_index].primary;
@@ -782,7 +769,6 @@ int tipc_bclink_init(void)
bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
if (!bcbearer || !bclink) {
- nomem:
warn("Multicast link creation failed, no memory\n");
kfree(bcbearer);
bcbearer = NULL;
@@ -807,14 +793,6 @@ int tipc_bclink_init(void)
bcl->state = WORKING_WORKING;
strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
- if (BCLINK_LOG_BUF_SIZE) {
- char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
-
- if (!pb)
- goto nomem;
- tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
- }
-
return 0;
}
@@ -823,8 +801,6 @@ void tipc_bclink_stop(void)
spin_lock_bh(&bc_lock);
if (bcbearer) {
tipc_link_stop(bcl);
- if (BCLINK_LOG_BUF_SIZE)
- kfree(bcl->print_buf.buf);
bcl = NULL;
kfree(bclink);
bclink = NULL;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 011c03f0a4ab..51f8c5326ce6 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -51,6 +51,7 @@ struct tipc_node_map {
u32 map[MAX_NODES / WSIZE];
};
+extern struct tipc_node_map tipc_bcast_nmap;
#define PLSIZE 32
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 9927d1d56c4f..837b7a467885 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -36,17 +36,13 @@
#include "core.h"
#include "config.h"
-#include "dbg.h"
#include "bearer.h"
-#include "link.h"
-#include "port.h"
#include "discover.h"
-#include "bcast.h"
#define MAX_ADDR_STR 32
static struct media media_list[MAX_MEDIA];
-static u32 media_count = 0;
+static u32 media_count;
struct bearer tipc_bearers[MAX_BEARERS];
@@ -167,7 +163,6 @@ int tipc_register_media(u32 media_type,
m_ptr->priority = bearer_priority;
m_ptr->tolerance = link_tolerance;
m_ptr->window = send_window_limit;
- dbg("Media <%s> registered\n", name);
res = 0;
exit:
write_unlock_bh(&tipc_net_lock);
@@ -199,9 +194,8 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
unchar *addr = (unchar *)&a->dev_addr;
tipc_printf(pb, "UNKNOWN(%u)", media_type);
- for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) {
+ for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++)
tipc_printf(pb, "-%02x", addr[i]);
- }
}
}
@@ -256,7 +250,8 @@ static int bearer_name_validate(const char *name,
/* ensure all component parts of bearer name are present */
media_name = name_copy;
- if ((if_name = strchr(media_name, ':')) == NULL)
+ if_name = strchr(media_name, ':');
+ if (if_name == NULL)
return 0;
*(if_name++) = 0;
media_len = if_name - media_name;
@@ -625,7 +620,7 @@ int tipc_block_bearer(const char *name)
* Note: This routine assumes caller holds tipc_net_lock.
*/
-static int bearer_disable(struct bearer *b_ptr)
+static void bearer_disable(struct bearer *b_ptr)
{
struct link *l_ptr;
struct link *temp_l_ptr;
@@ -641,7 +636,6 @@ static int bearer_disable(struct bearer *b_ptr)
}
spin_unlock_bh(&b_ptr->publ.lock);
memset(b_ptr, 0, sizeof(struct bearer));
- return 0;
}
int tipc_disable_bearer(const char *name)
@@ -654,8 +648,10 @@ int tipc_disable_bearer(const char *name)
if (b_ptr == NULL) {
warn("Attempt to disable unknown bearer <%s>\n", name);
res = -EINVAL;
- } else
- res = bearer_disable(b_ptr);
+ } else {
+ bearer_disable(b_ptr);
+ res = 0;
+ }
write_unlock_bh(&tipc_net_lock);
return res;
}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index a850b389663e..85f451d5aacf 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -37,12 +37,50 @@
#ifndef _TIPC_BEARER_H
#define _TIPC_BEARER_H
-#include "core.h"
#include "bcast.h"
#define MAX_BEARERS 8
#define MAX_MEDIA 4
+/*
+ * Identifiers of supported TIPC media types
+ */
+#define TIPC_MEDIA_TYPE_ETH 1
+
+/*
+ * Destination address structure used by TIPC bearers when sending messages
+ *
+ * IMPORTANT: The fields of this structure MUST be stored using the specified
+ * byte order indicated below, as the structure is exchanged between nodes
+ * as part of a link setup process.
+ */
+struct tipc_media_addr {
+ __be32 type; /* bearer type (network byte order) */
+ union {
+ __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */
+ } dev_addr;
+};
+
+/**
+ * struct tipc_bearer - TIPC bearer info available to media code
+ * @usr_handle: pointer to additional media-specific information about bearer
+ * @mtu: max packet size bearer can support
+ * @blocked: non-zero if bearer is blocked
+ * @lock: spinlock for controlling access to bearer
+ * @addr: media-specific address associated with bearer
+ * @name: bearer name (format = media:interface)
+ *
+ * Note: TIPC initializes "name" and "lock" fields; media code is responsible
+ * for initialization all other fields when a bearer is enabled.
+ */
+struct tipc_bearer {
+ void *usr_handle;
+ u32 mtu;
+ int blocked;
+ spinlock_t lock;
+ struct tipc_media_addr addr;
+ char name[TIPC_MAX_BEARER_NAME];
+};
/**
* struct media - TIPC media information available to internal users
@@ -55,7 +93,7 @@
* @priority: default link (and bearer) priority
* @tolerance: default time (in ms) before declaring link failure
* @window: default window (in packets) before declaring link congestion
- * @type_id: TIPC media identifier [defined in tipc_bearer.h]
+ * @type_id: TIPC media identifier
* @name: media name
*/
@@ -116,6 +154,34 @@ struct link;
extern struct bearer tipc_bearers[];
+/*
+ * TIPC routines available to supported media types
+ */
+int tipc_register_media(u32 media_type,
+ char *media_name, int (*enable)(struct tipc_bearer *),
+ void (*disable)(struct tipc_bearer *),
+ int (*send_msg)(struct sk_buff *,
+ struct tipc_bearer *, struct tipc_media_addr *),
+ char *(*addr2str)(struct tipc_media_addr *a,
+ char *str_buf, int str_size),
+ struct tipc_media_addr *bcast_addr, const u32 bearer_priority,
+ const u32 link_tolerance, /* [ms] */
+ const u32 send_window_limit);
+
+void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
+
+int tipc_block_bearer(const char *name);
+void tipc_continue(struct tipc_bearer *tb_ptr);
+
+int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority);
+int tipc_disable_bearer(const char *name);
+
+/*
+ * Routines made available to TIPC by supported media types
+ */
+int tipc_eth_media_start(void);
+void tipc_eth_media_stop(void);
+
void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
struct sk_buff *tipc_media_get_names(void);
@@ -126,7 +192,6 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr);
struct bearer *tipc_bearer_find_interface(const char *if_name);
int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr);
int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr);
-int tipc_bearer_init(void);
void tipc_bearer_stop(void);
void tipc_bearer_lock_push(struct bearer *b_ptr);
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
deleted file mode 100644
index 7fea14b98b97..000000000000
--- a/net/tipc/cluster.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * net/tipc/cluster.c: TIPC cluster management routines
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include "core.h"
-#include "cluster.h"
-#include "addr.h"
-#include "node_subscr.h"
-#include "link.h"
-#include "node.h"
-#include "net.h"
-#include "msg.h"
-#include "bearer.h"
-
-static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
- u32 lower, u32 upper);
-static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
-
-struct tipc_node **tipc_local_nodes = NULL;
-struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
-u32 tipc_highest_allowed_slave = 0;
-
-struct cluster *tipc_cltr_create(u32 addr)
-{
- struct _zone *z_ptr;
- struct cluster *c_ptr;
- int max_nodes;
-
- c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC);
- if (c_ptr == NULL) {
- warn("Cluster creation failure, no memory\n");
- return NULL;
- }
-
- c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
- if (in_own_cluster(addr))
- max_nodes = LOWEST_SLAVE + tipc_max_slaves;
- else
- max_nodes = tipc_max_nodes + 1;
-
- c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC);
- if (c_ptr->nodes == NULL) {
- warn("Cluster creation failure, no memory for node area\n");
- kfree(c_ptr);
- return NULL;
- }
-
- if (in_own_cluster(addr))
- tipc_local_nodes = c_ptr->nodes;
- c_ptr->highest_slave = LOWEST_SLAVE - 1;
- c_ptr->highest_node = 0;
-
- z_ptr = tipc_zone_find(tipc_zone(addr));
- if (!z_ptr) {
- z_ptr = tipc_zone_create(addr);
- }
- if (!z_ptr) {
- kfree(c_ptr->nodes);
- kfree(c_ptr);
- return NULL;
- }
-
- tipc_zone_attach_cluster(z_ptr, c_ptr);
- c_ptr->owner = z_ptr;
- return c_ptr;
-}
-
-void tipc_cltr_delete(struct cluster *c_ptr)
-{
- u32 n_num;
-
- if (!c_ptr)
- return;
- for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
- tipc_node_delete(c_ptr->nodes[n_num]);
- }
- for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) {
- tipc_node_delete(c_ptr->nodes[n_num]);
- }
- kfree(c_ptr->nodes);
- kfree(c_ptr);
-}
-
-
-void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
-{
- u32 n_num = tipc_node(n_ptr->addr);
- u32 max_n_num = tipc_max_nodes;
-
- if (in_own_cluster(n_ptr->addr))
- max_n_num = tipc_highest_allowed_slave;
- assert(n_num > 0);
- assert(n_num <= max_n_num);
- assert(c_ptr->nodes[n_num] == NULL);
- c_ptr->nodes[n_num] = n_ptr;
- if (n_num > c_ptr->highest_node)
- c_ptr->highest_node = n_num;
-}
-
-/**
- * tipc_cltr_select_router - select router to a cluster
- *
- * Uses deterministic and fair algorithm.
- */
-
-u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
-{
- u32 n_num;
- u32 ulim = c_ptr->highest_node;
- u32 mask;
- u32 tstart;
-
- assert(!in_own_cluster(c_ptr->addr));
- if (!ulim)
- return 0;
-
- /* Start entry must be random */
- mask = tipc_max_nodes;
- while (mask > ulim)
- mask >>= 1;
- tstart = ref & mask;
- n_num = tstart;
-
- /* Lookup upwards with wrap-around */
- do {
- if (tipc_node_is_up(c_ptr->nodes[n_num]))
- break;
- } while (++n_num <= ulim);
- if (n_num > ulim) {
- n_num = 1;
- do {
- if (tipc_node_is_up(c_ptr->nodes[n_num]))
- break;
- } while (++n_num < tstart);
- if (n_num == tstart)
- return 0;
- }
- assert(n_num <= ulim);
- return tipc_node_select_router(c_ptr->nodes[n_num], ref);
-}
-
-/**
- * tipc_cltr_select_node - select destination node within a remote cluster
- *
- * Uses deterministic and fair algorithm.
- */
-
-struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
-{
- u32 n_num;
- u32 mask = tipc_max_nodes;
- u32 start_entry;
-
- assert(!in_own_cluster(c_ptr->addr));
- if (!c_ptr->highest_node)
- return NULL;
-
- /* Start entry must be random */
- while (mask > c_ptr->highest_node) {
- mask >>= 1;
- }
- start_entry = (selector & mask) ? selector & mask : 1u;
- assert(start_entry <= c_ptr->highest_node);
-
- /* Lookup upwards with wrap-around */
- for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
- if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
- return c_ptr->nodes[n_num];
- }
- for (n_num = 1; n_num < start_entry; n_num++) {
- if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
- return c_ptr->nodes[n_num];
- }
- return NULL;
-}
-
-/*
- * Routing table management: See description in node.c
- */
-
-static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
-{
- u32 size = INT_H_SIZE + data_size;
- struct sk_buff *buf = tipc_buf_acquire(size);
- struct tipc_msg *msg;
-
- if (buf) {
- msg = buf_msg(buf);
- memset((char *)msg, 0, size);
- tipc_msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
- }
- return buf;
-}
-
-void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest,
- u32 lower, u32 upper)
-{
- struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
- struct tipc_msg *msg;
-
- if (buf) {
- msg = buf_msg(buf);
- msg_set_remote_node(msg, dest);
- msg_set_type(msg, ROUTE_ADDITION);
- tipc_cltr_multicast(c_ptr, buf, lower, upper);
- } else {
- warn("Memory squeeze: broadcast of new route failed\n");
- }
-}
-
-void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
- u32 lower, u32 upper)
-{
- struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
- struct tipc_msg *msg;
-
- if (buf) {
- msg = buf_msg(buf);
- msg_set_remote_node(msg, dest);
- msg_set_type(msg, ROUTE_REMOVAL);
- tipc_cltr_multicast(c_ptr, buf, lower, upper);
- } else {
- warn("Memory squeeze: broadcast of lost route failed\n");
- }
-}
-
-void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest)
-{
- struct sk_buff *buf;
- struct tipc_msg *msg;
- u32 highest = c_ptr->highest_slave;
- u32 n_num;
- int send = 0;
-
- assert(!is_slave(dest));
- assert(in_own_cluster(dest));
- assert(in_own_cluster(c_ptr->addr));
- if (highest <= LOWEST_SLAVE)
- return;
- buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
- c_ptr->addr);
- if (buf) {
- msg = buf_msg(buf);
- msg_set_remote_node(msg, c_ptr->addr);
- msg_set_type(msg, SLAVE_ROUTING_TABLE);
- for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
- if (c_ptr->nodes[n_num] &&
- tipc_node_has_active_links(c_ptr->nodes[n_num])) {
- send = 1;
- msg_set_dataoctet(msg, n_num);
- }
- }
- if (send)
- tipc_link_send(buf, dest, dest);
- else
- buf_discard(buf);
- } else {
- warn("Memory squeeze: broadcast of lost route failed\n");
- }
-}
-
-void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
-{
- struct sk_buff *buf;
- struct tipc_msg *msg;
- u32 highest = c_ptr->highest_node;
- u32 n_num;
- int send = 0;
-
- if (in_own_cluster(c_ptr->addr))
- return;
- assert(!is_slave(dest));
- assert(in_own_cluster(dest));
- highest = c_ptr->highest_node;
- buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
- if (buf) {
- msg = buf_msg(buf);
- msg_set_remote_node(msg, c_ptr->addr);
- msg_set_type(msg, EXT_ROUTING_TABLE);
- for (n_num = 1; n_num <= highest; n_num++) {
- if (c_ptr->nodes[n_num] &&
- tipc_node_has_active_links(c_ptr->nodes[n_num])) {
- send = 1;
- msg_set_dataoctet(msg, n_num);
- }
- }
- if (send)
- tipc_link_send(buf, dest, dest);
- else
- buf_discard(buf);
- } else {
- warn("Memory squeeze: broadcast of external route failed\n");
- }
-}
-
-void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest)
-{
- struct sk_buff *buf;
- struct tipc_msg *msg;
- u32 highest = c_ptr->highest_node;
- u32 n_num;
- int send = 0;
-
- assert(is_slave(dest));
- assert(in_own_cluster(c_ptr->addr));
- buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr);
- if (buf) {
- msg = buf_msg(buf);
- msg_set_remote_node(msg, c_ptr->addr);
- msg_set_type(msg, LOCAL_ROUTING_TABLE);
- for (n_num = 1; n_num <= highest; n_num++) {
- if (c_ptr->nodes[n_num] &&
- tipc_node_has_active_links(c_ptr->nodes[n_num])) {
- send = 1;
- msg_set_dataoctet(msg, n_num);
- }
- }
- if (send)
- tipc_link_send(buf, dest, dest);
- else
- buf_discard(buf);
- } else {
- warn("Memory squeeze: broadcast of local route failed\n");
- }
-}
-
-void tipc_cltr_recv_routing_table(struct sk_buff *buf)
-{
- struct tipc_msg *msg = buf_msg(buf);
- struct cluster *c_ptr;
- struct tipc_node *n_ptr;
- unchar *node_table;
- u32 table_size;
- u32 router;
- u32 rem_node = msg_remote_node(msg);
- u32 z_num;
- u32 c_num;
- u32 n_num;
-
- c_ptr = tipc_cltr_find(rem_node);
- if (!c_ptr) {
- c_ptr = tipc_cltr_create(rem_node);
- if (!c_ptr) {
- buf_discard(buf);
- return;
- }
- }
-
- node_table = buf->data + msg_hdr_sz(msg);
- table_size = msg_size(msg) - msg_hdr_sz(msg);
- router = msg_prevnode(msg);
- z_num = tipc_zone(rem_node);
- c_num = tipc_cluster(rem_node);
-
- switch (msg_type(msg)) {
- case LOCAL_ROUTING_TABLE:
- assert(is_slave(tipc_own_addr));
- case EXT_ROUTING_TABLE:
- for (n_num = 1; n_num < table_size; n_num++) {
- if (node_table[n_num]) {
- u32 addr = tipc_addr(z_num, c_num, n_num);
- n_ptr = c_ptr->nodes[n_num];
- if (!n_ptr) {
- n_ptr = tipc_node_create(addr);
- }
- if (n_ptr)
- tipc_node_add_router(n_ptr, router);
- }
- }
- break;
- case SLAVE_ROUTING_TABLE:
- assert(!is_slave(tipc_own_addr));
- assert(in_own_cluster(c_ptr->addr));
- for (n_num = 1; n_num < table_size; n_num++) {
- if (node_table[n_num]) {
- u32 slave_num = n_num + LOWEST_SLAVE;
- u32 addr = tipc_addr(z_num, c_num, slave_num);
- n_ptr = c_ptr->nodes[slave_num];
- if (!n_ptr) {
- n_ptr = tipc_node_create(addr);
- }
- if (n_ptr)
- tipc_node_add_router(n_ptr, router);
- }
- }
- break;
- case ROUTE_ADDITION:
- if (!is_slave(tipc_own_addr)) {
- assert(!in_own_cluster(c_ptr->addr) ||
- is_slave(rem_node));
- } else {
- assert(in_own_cluster(c_ptr->addr) &&
- !is_slave(rem_node));
- }
- n_ptr = c_ptr->nodes[tipc_node(rem_node)];
- if (!n_ptr)
- n_ptr = tipc_node_create(rem_node);
- if (n_ptr)
- tipc_node_add_router(n_ptr, router);
- break;
- case ROUTE_REMOVAL:
- if (!is_slave(tipc_own_addr)) {
- assert(!in_own_cluster(c_ptr->addr) ||
- is_slave(rem_node));
- } else {
- assert(in_own_cluster(c_ptr->addr) &&
- !is_slave(rem_node));
- }
- n_ptr = c_ptr->nodes[tipc_node(rem_node)];
- if (n_ptr)
- tipc_node_remove_router(n_ptr, router);
- break;
- default:
- assert(!"Illegal routing manager message received\n");
- }
- buf_discard(buf);
-}
-
-void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
-{
- u32 start_entry;
- u32 tstop;
- u32 n_num;
-
- if (is_slave(router))
- return; /* Slave nodes can not be routers */
-
- if (in_own_cluster(c_ptr->addr)) {
- start_entry = LOWEST_SLAVE;
- tstop = c_ptr->highest_slave;
- } else {
- start_entry = 1;
- tstop = c_ptr->highest_node;
- }
-
- for (n_num = start_entry; n_num <= tstop; n_num++) {
- if (c_ptr->nodes[n_num]) {
- tipc_node_remove_router(c_ptr->nodes[n_num], router);
- }
- }
-}
-
-/**
- * tipc_cltr_multicast - multicast message to local nodes
- */
-
-static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
- u32 lower, u32 upper)
-{
- struct sk_buff *buf_copy;
- struct tipc_node *n_ptr;
- u32 n_num;
- u32 tstop;
-
- assert(lower <= upper);
- assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
- ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave)));
- assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
- ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave)));
- assert(in_own_cluster(c_ptr->addr));
-
- tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
- if (tstop > upper)
- tstop = upper;
- for (n_num = lower; n_num <= tstop; n_num++) {
- n_ptr = c_ptr->nodes[n_num];
- if (n_ptr && tipc_node_has_active_links(n_ptr)) {
- buf_copy = skb_copy(buf, GFP_ATOMIC);
- if (buf_copy == NULL)
- break;
- msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
- tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
- }
- }
- buf_discard(buf);
-}
-
-/**
- * tipc_cltr_broadcast - broadcast message to all nodes within cluster
- */
-
-void tipc_cltr_broadcast(struct sk_buff *buf)
-{
- struct sk_buff *buf_copy;
- struct cluster *c_ptr;
- struct tipc_node *n_ptr;
- u32 n_num;
- u32 tstart;
- u32 tstop;
- u32 node_type;
-
- if (tipc_mode == TIPC_NET_MODE) {
- c_ptr = tipc_cltr_find(tipc_own_addr);
- assert(in_own_cluster(c_ptr->addr)); /* For now */
-
- /* Send to standard nodes, then repeat loop sending to slaves */
- tstart = 1;
- tstop = c_ptr->highest_node;
- for (node_type = 1; node_type <= 2; node_type++) {
- for (n_num = tstart; n_num <= tstop; n_num++) {
- n_ptr = c_ptr->nodes[n_num];
- if (n_ptr && tipc_node_has_active_links(n_ptr)) {
- buf_copy = skb_copy(buf, GFP_ATOMIC);
- if (buf_copy == NULL)
- goto exit;
- msg_set_destnode(buf_msg(buf_copy),
- n_ptr->addr);
- tipc_link_send(buf_copy, n_ptr->addr,
- n_ptr->addr);
- }
- }
- tstart = LOWEST_SLAVE;
- tstop = c_ptr->highest_slave;
- }
- }
-exit:
- buf_discard(buf);
-}
-
-int tipc_cltr_init(void)
-{
- tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
- return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM;
-}
-
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
deleted file mode 100644
index 32636d98c9c6..000000000000
--- a/net/tipc/cluster.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * net/tipc/cluster.h: Include file for TIPC cluster management routines
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _TIPC_CLUSTER_H
-#define _TIPC_CLUSTER_H
-
-#include "addr.h"
-#include "zone.h"
-
-#define LOWEST_SLAVE 2048u
-
-/**
- * struct cluster - TIPC cluster structure
- * @addr: network address of cluster
- * @owner: pointer to zone that cluster belongs to
- * @nodes: array of pointers to all nodes within cluster
- * @highest_node: id of highest numbered node within cluster
- * @highest_slave: (used for secondary node support)
- */
-
-struct cluster {
- u32 addr;
- struct _zone *owner;
- struct tipc_node **nodes;
- u32 highest_node;
- u32 highest_slave;
-};
-
-
-extern struct tipc_node **tipc_local_nodes;
-extern u32 tipc_highest_allowed_slave;
-extern struct tipc_node_map tipc_cltr_bcast_nodes;
-
-void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
-void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
-struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
-u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
-void tipc_cltr_recv_routing_table(struct sk_buff *buf);
-struct cluster *tipc_cltr_create(u32 addr);
-void tipc_cltr_delete(struct cluster *c_ptr);
-void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
-void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
-void tipc_cltr_broadcast(struct sk_buff *buf);
-int tipc_cltr_init(void);
-
-void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
-void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest);
-void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
-
-static inline struct cluster *tipc_cltr_find(u32 addr)
-{
- struct _zone *z_ptr = tipc_zone_find(addr);
-
- if (z_ptr)
- return z_ptr->clusters[1];
- return NULL;
-}
-
-#endif
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 50a6133a3668..e16750dcf3c1 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -35,30 +35,11 @@
*/
#include "core.h"
-#include "dbg.h"
-#include "bearer.h"
#include "port.h"
-#include "link.h"
-#include "zone.h"
-#include "addr.h"
#include "name_table.h"
-#include "node.h"
#include "config.h"
-#include "discover.h"
-struct subscr_data {
- char usr_handle[8];
- u32 domain;
- u32 port_ref;
- struct list_head subd_list;
-};
-
-struct manager {
- u32 user_ref;
- u32 port_ref;
-};
-
-static struct manager mng = { 0};
+static u32 config_port_ref;
static DEFINE_SPINLOCK(config_lock);
@@ -83,10 +64,8 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
int new_tlv_space = TLV_SPACE(tlv_data_size);
- if (skb_tailroom(buf) < new_tlv_space) {
- dbg("tipc_cfg_append_tlv unable to append TLV\n");
+ if (skb_tailroom(buf) < new_tlv_space)
return 0;
- }
skb_put(buf, new_tlv_space);
tlv->tlv_type = htons(tlv_type);
tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size));
@@ -281,38 +260,6 @@ static struct sk_buff *cfg_set_max_ports(void)
return tipc_cfg_reply_none();
}
-static struct sk_buff *cfg_set_max_zones(void)
-{
- u32 value;
-
- if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
- return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
- value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value == tipc_max_zones)
- return tipc_cfg_reply_none();
- if (value != delimit(value, 1, 255))
- return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
- " (max zones must be 1-255)");
- if (tipc_mode == TIPC_NET_MODE)
- return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
- " (cannot change max zones once TIPC has joined a network)");
- tipc_max_zones = value;
- return tipc_cfg_reply_none();
-}
-
-static struct sk_buff *cfg_set_max_clusters(void)
-{
- u32 value;
-
- if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
- return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
- value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value != delimit(value, 1, 1))
- return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
- " (max clusters fixed at 1)");
- return tipc_cfg_reply_none();
-}
-
static struct sk_buff *cfg_set_max_nodes(void)
{
u32 value;
@@ -332,19 +279,6 @@ static struct sk_buff *cfg_set_max_nodes(void)
return tipc_cfg_reply_none();
}
-static struct sk_buff *cfg_set_max_slaves(void)
-{
- u32 value;
-
- if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
- return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
- value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value != 0)
- return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
- " (max secondary nodes fixed at 0)");
- return tipc_cfg_reply_none();
-}
-
static struct sk_buff *cfg_set_netid(void)
{
u32 value;
@@ -388,8 +322,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
} else if (!tipc_remote_management) {
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
goto exit;
- }
- else if (cmd >= 0x4000) {
+ } else if (cmd >= 0x4000) {
u32 domain = 0;
if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
@@ -464,18 +397,9 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_SET_MAX_SUBSCR:
rep_tlv_buf = cfg_set_max_subscriptions();
break;
- case TIPC_CMD_SET_MAX_ZONES:
- rep_tlv_buf = cfg_set_max_zones();
- break;
- case TIPC_CMD_SET_MAX_CLUSTERS:
- rep_tlv_buf = cfg_set_max_clusters();
- break;
case TIPC_CMD_SET_MAX_NODES:
rep_tlv_buf = cfg_set_max_nodes();
break;
- case TIPC_CMD_SET_MAX_SLAVES:
- rep_tlv_buf = cfg_set_max_slaves();
- break;
case TIPC_CMD_SET_NETID:
rep_tlv_buf = cfg_set_netid();
break;
@@ -491,18 +415,9 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_GET_MAX_SUBSCR:
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
break;
- case TIPC_CMD_GET_MAX_ZONES:
- rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones);
- break;
- case TIPC_CMD_GET_MAX_CLUSTERS:
- rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters);
- break;
case TIPC_CMD_GET_MAX_NODES:
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
break;
- case TIPC_CMD_GET_MAX_SLAVES:
- rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves);
- break;
case TIPC_CMD_GET_NETID:
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
break;
@@ -510,6 +425,15 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
rep_tlv_buf =
tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
break;
+ case TIPC_CMD_SET_MAX_ZONES:
+ case TIPC_CMD_GET_MAX_ZONES:
+ case TIPC_CMD_SET_MAX_SLAVES:
+ case TIPC_CMD_GET_MAX_SLAVES:
+ case TIPC_CMD_SET_MAX_CLUSTERS:
+ case TIPC_CMD_GET_MAX_CLUSTERS:
+ rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+ " (obsolete command)");
+ break;
default:
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (unknown command)");
@@ -572,20 +496,16 @@ int tipc_cfg_init(void)
struct tipc_name_seq seq;
int res;
- res = tipc_attach(&mng.user_ref, NULL, NULL);
- if (res)
- goto failed;
-
- res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE,
+ res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
NULL, NULL, NULL,
NULL, cfg_named_msg_event, NULL,
- NULL, &mng.port_ref);
+ NULL, &config_port_ref);
if (res)
goto failed;
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = tipc_own_addr;
- res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq);
+ res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
goto failed;
@@ -593,15 +513,13 @@ int tipc_cfg_init(void)
failed:
err("Unable to create configuration service\n");
- tipc_detach(mng.user_ref);
- mng.user_ref = 0;
return res;
}
void tipc_cfg_stop(void)
{
- if (mng.user_ref) {
- tipc_detach(mng.user_ref);
- mng.user_ref = 0;
+ if (config_port_ref) {
+ tipc_deleteport(config_port_ref);
+ config_port_ref = 0;
}
}
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 481e12ece715..443159a166fd 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -39,7 +39,6 @@
/* ---------------------------------------------------------------------- */
-#include "core.h"
#include "link.h"
struct sk_buff *tipc_cfg_reply_alloc(int payload_size);
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e2a09eb8efd4..e071579e0850 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -34,37 +34,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/random.h>
-
#include "core.h"
-#include "dbg.h"
#include "ref.h"
-#include "net.h"
-#include "user_reg.h"
#include "name_table.h"
#include "subscr.h"
#include "config.h"
-#ifndef CONFIG_TIPC_ZONES
-#define CONFIG_TIPC_ZONES 3
-#endif
-
-#ifndef CONFIG_TIPC_CLUSTERS
-#define CONFIG_TIPC_CLUSTERS 1
-#endif
-
#ifndef CONFIG_TIPC_NODES
#define CONFIG_TIPC_NODES 255
#endif
-#ifndef CONFIG_TIPC_SLAVE_NODES
-#define CONFIG_TIPC_SLAVE_NODES 0
-#endif
-
#ifndef CONFIG_TIPC_PORTS
#define CONFIG_TIPC_PORTS 8191
#endif
@@ -85,10 +65,7 @@ const char tipc_alphabet[] =
/* configurable TIPC parameters */
u32 tipc_own_addr;
-int tipc_max_zones;
-int tipc_max_clusters;
int tipc_max_nodes;
-int tipc_max_slaves;
int tipc_max_ports;
int tipc_max_subscriptions;
int tipc_max_publications;
@@ -138,10 +115,11 @@ int tipc_core_start_net(unsigned long addr)
{
int res;
- if ((res = tipc_net_start(addr)) ||
- (res = tipc_eth_media_start())) {
+ res = tipc_net_start(addr);
+ if (!res)
+ res = tipc_eth_media_start();
+ if (res)
tipc_core_stop_net();
- }
return res;
}
@@ -160,7 +138,6 @@ static void tipc_core_stop(void)
tipc_handler_stop();
tipc_cfg_stop();
tipc_subscr_stop();
- tipc_reg_stop();
tipc_nametbl_stop();
tipc_ref_table_stop();
tipc_socket_stop();
@@ -181,16 +158,22 @@ static int tipc_core_start(void)
get_random_bytes(&tipc_random, sizeof(tipc_random));
tipc_mode = TIPC_NODE_MODE;
- if ((res = tipc_handler_start()) ||
- (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) ||
- (res = tipc_reg_start()) ||
- (res = tipc_nametbl_init()) ||
- (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) ||
- (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) ||
- (res = tipc_netlink_start()) ||
- (res = tipc_socket_init())) {
+ res = tipc_handler_start();
+ if (!res)
+ res = tipc_ref_table_init(tipc_max_ports, tipc_random);
+ if (!res)
+ res = tipc_nametbl_init();
+ if (!res)
+ res = tipc_k_signal((Handler)tipc_subscr_start, 0);
+ if (!res)
+ res = tipc_k_signal((Handler)tipc_cfg_init, 0);
+ if (!res)
+ res = tipc_netlink_start();
+ if (!res)
+ res = tipc_socket_init();
+ if (res)
tipc_core_stop();
- }
+
return res;
}
@@ -210,13 +193,11 @@ static int __init tipc_init(void)
tipc_max_publications = 10000;
tipc_max_subscriptions = 2000;
tipc_max_ports = CONFIG_TIPC_PORTS;
- tipc_max_zones = CONFIG_TIPC_ZONES;
- tipc_max_clusters = CONFIG_TIPC_CLUSTERS;
tipc_max_nodes = CONFIG_TIPC_NODES;
- tipc_max_slaves = CONFIG_TIPC_SLAVE_NODES;
tipc_net_id = 4711;
- if ((res = tipc_core_start()))
+ res = tipc_core_start();
+ if (res)
err("Unable to start in single node mode\n");
else
info("Started in single node mode\n");
@@ -236,43 +217,3 @@ module_exit(tipc_exit);
MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(TIPC_MOD_VER);
-
-/* Native TIPC API for kernel-space applications (see tipc.h) */
-
-EXPORT_SYMBOL(tipc_attach);
-EXPORT_SYMBOL(tipc_detach);
-EXPORT_SYMBOL(tipc_createport);
-EXPORT_SYMBOL(tipc_deleteport);
-EXPORT_SYMBOL(tipc_ownidentity);
-EXPORT_SYMBOL(tipc_portimportance);
-EXPORT_SYMBOL(tipc_set_portimportance);
-EXPORT_SYMBOL(tipc_portunreliable);
-EXPORT_SYMBOL(tipc_set_portunreliable);
-EXPORT_SYMBOL(tipc_portunreturnable);
-EXPORT_SYMBOL(tipc_set_portunreturnable);
-EXPORT_SYMBOL(tipc_publish);
-EXPORT_SYMBOL(tipc_withdraw);
-EXPORT_SYMBOL(tipc_connect2port);
-EXPORT_SYMBOL(tipc_disconnect);
-EXPORT_SYMBOL(tipc_shutdown);
-EXPORT_SYMBOL(tipc_send);
-EXPORT_SYMBOL(tipc_send2name);
-EXPORT_SYMBOL(tipc_send2port);
-EXPORT_SYMBOL(tipc_multicast);
-
-/* TIPC API for external bearers (see tipc_bearer.h) */
-
-EXPORT_SYMBOL(tipc_block_bearer);
-EXPORT_SYMBOL(tipc_continue);
-EXPORT_SYMBOL(tipc_disable_bearer);
-EXPORT_SYMBOL(tipc_enable_bearer);
-EXPORT_SYMBOL(tipc_recv_msg);
-EXPORT_SYMBOL(tipc_register_media);
-
-/* TIPC API for external APIs (see tipc_port.h) */
-
-EXPORT_SYMBOL(tipc_createport_raw);
-EXPORT_SYMBOL(tipc_reject_msg);
-EXPORT_SYMBOL(tipc_send_buf_fast);
-EXPORT_SYMBOL(tipc_acknowledge);
-
diff --git a/net/tipc/core.h b/net/tipc/core.h
index e19389e57227..997158546e25 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -39,10 +39,6 @@
#include <linux/tipc.h>
#include <linux/tipc_config.h>
-#include <net/tipc/tipc_msg.h>
-#include <net/tipc/tipc_port.h>
-#include <net/tipc/tipc_bearer.h>
-#include <net/tipc/tipc.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -62,6 +58,9 @@
#define TIPC_MOD_VER "2.0.0"
+struct tipc_msg; /* msg.h */
+struct print_buf; /* log.h */
+
/*
* TIPC sanity test macros
*/
@@ -84,6 +83,7 @@
* user-defined buffers can be configured to do the same thing.
*/
extern struct print_buf *const TIPC_NULL;
+extern struct print_buf *const TIPC_CONS;
extern struct print_buf *const TIPC_LOG;
void tipc_printf(struct print_buf *, const char *fmt, ...);
@@ -96,73 +96,35 @@ void tipc_printf(struct print_buf *, const char *fmt, ...);
#define TIPC_OUTPUT TIPC_LOG
#endif
-/*
- * TIPC can be configured to send system messages to TIPC_OUTPUT
- * or to the system console only.
- */
-
-#ifdef CONFIG_TIPC_DEBUG
-
#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
- KERN_ERR "TIPC: " fmt, ## arg)
+ KERN_ERR "TIPC: " fmt, ## arg)
#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
- KERN_WARNING "TIPC: " fmt, ## arg)
+ KERN_WARNING "TIPC: " fmt, ## arg)
#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
- KERN_NOTICE "TIPC: " fmt, ## arg)
-
-#else
-
-#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg)
-#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
-#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
+ KERN_NOTICE "TIPC: " fmt, ## arg)
-#endif
+#ifdef CONFIG_TIPC_DEBUG
/*
* DBG_OUTPUT is the destination print buffer for debug messages.
- * It defaults to the the null print buffer, but can be redefined
- * (typically in the individual .c files being debugged) to allow
- * selected debug messages to be generated where needed.
*/
#ifndef DBG_OUTPUT
-#define DBG_OUTPUT TIPC_NULL
+#define DBG_OUTPUT TIPC_LOG
#endif
-/*
- * TIPC can be configured to send debug messages to the specified print buffer
- * (typically DBG_OUTPUT) or to suppress them entirely.
- */
+#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg);
-#ifdef CONFIG_TIPC_DEBUG
-
-#define dbg(fmt, arg...) \
- do { \
- if (DBG_OUTPUT != TIPC_NULL) \
- tipc_printf(DBG_OUTPUT, fmt, ## arg); \
- } while (0)
-#define msg_dbg(msg, txt) \
- do { \
- if (DBG_OUTPUT != TIPC_NULL) \
- tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
- } while (0)
-#define dump(fmt, arg...) \
- do { \
- if (DBG_OUTPUT != TIPC_NULL) \
- tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
- } while (0)
+#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt);
void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
-void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
#else
#define dbg(fmt, arg...) do {} while (0)
#define msg_dbg(msg, txt) do {} while (0)
-#define dump(fmt, arg...) do {} while (0)
-#define tipc_msg_dbg(...) do {} while (0)
-#define tipc_dump_dbg(...) do {} while (0)
+#define tipc_msg_dbg(buf, msg, txt) do {} while (0)
#endif
@@ -174,14 +136,18 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
/*
+ * TIPC operating mode routines
+ */
+#define TIPC_NOT_RUNNING 0
+#define TIPC_NODE_MODE 1
+#define TIPC_NET_MODE 2
+
+/*
* Global configuration variables
*/
extern u32 tipc_own_addr;
-extern int tipc_max_zones;
-extern int tipc_max_clusters;
extern int tipc_max_nodes;
-extern int tipc_max_slaves;
extern int tipc_max_ports;
extern int tipc_max_subscriptions;
extern int tipc_max_publications;
@@ -240,7 +206,6 @@ u32 tipc_k_signal(Handler routine, unsigned long argument);
static inline void k_init_timer(struct timer_list *timer, Handler routine,
unsigned long argument)
{
- dbg("initializing timer %p\n", timer);
setup_timer(timer, routine, argument);
}
@@ -260,7 +225,6 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine,
static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
{
- dbg("starting timer %p for %u\n", timer, msec);
mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1);
}
@@ -277,7 +241,6 @@ static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
static inline void k_cancel_timer(struct timer_list *timer)
{
- dbg("cancelling timer %p\n", timer);
del_timer_sync(timer);
}
@@ -295,7 +258,6 @@ static inline void k_cancel_timer(struct timer_list *timer)
static inline void k_term_timer(struct timer_list *timer)
{
- dbg("terminating timer %p\n", timer);
}
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 4a7cd3719b78..fa026bd91a68 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -35,12 +35,8 @@
*/
#include "core.h"
-#include "dbg.h"
#include "link.h"
-#include "zone.h"
#include "discover.h"
-#include "port.h"
-#include "name_table.h"
#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */
#define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */
@@ -134,8 +130,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
u32 net_id = msg_bc_netid(msg);
u32 type = msg_type(msg);
- msg_get_media_addr(msg,&media_addr);
- msg_dbg(msg, "RECV:");
+ msg_get_media_addr(msg, &media_addr);
buf_discard(buf);
if (net_id != tipc_net_id)
@@ -151,10 +146,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
}
if (!tipc_in_scope(dest, tipc_own_addr))
return;
- if (is_slave(tipc_own_addr) && is_slave(orig))
- return;
- if (is_slave(orig) && !in_own_cluster(orig))
- return;
if (in_own_cluster(orig)) {
/* Always accept link here */
struct sk_buff *rbuf;
@@ -162,7 +153,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
struct tipc_node *n_ptr = tipc_node_find(orig);
int link_fully_up;
- dbg(" in own cluster\n");
if (n_ptr == NULL) {
n_ptr = tipc_node_create(orig);
if (!n_ptr)
@@ -179,7 +169,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
link = n_ptr->links[b_ptr->identity];
if (!link) {
- dbg("creating link\n");
link = tipc_link_create(b_ptr, orig, &media_addr);
if (!link) {
spin_unlock_bh(&n_ptr->lock);
@@ -204,7 +193,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
return;
rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
if (rbuf != NULL) {
- msg_dbg(buf_msg(rbuf),"SEND:");
b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr);
buf_discard(rbuf);
}
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index f8e750636123..d2c3cffb79fc 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -37,8 +37,6 @@
#ifndef _TIPC_DISCOVER_H
#define _TIPC_DISCOVER_H
-#include "core.h"
-
struct link_req;
struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 6e988ba485fd..b69092eb95d8 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -34,12 +34,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <net/tipc/tipc.h>
-#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>
+#include "core.h"
+#include "bearer.h"
#define MAX_ETH_BEARERS 2
#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
@@ -60,7 +56,7 @@ struct eth_bearer {
};
static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
-static int eth_started = 0;
+static int eth_started;
static struct notifier_block notifier;
/**
@@ -148,7 +144,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
/* Find device with specified name */
- for_each_netdev(&init_net, pdev){
+ for_each_netdev(&init_net, pdev) {
if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
dev = pdev;
break;
@@ -159,7 +155,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
/* Find Ethernet bearer for device (or create one) */
- for (;(eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev); eb_ptr++);
+ while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev))
+ eb_ptr++;
if (eb_ptr == stop)
return -EDQUOT;
if (!eb_ptr->dev) {
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index 0c70010a7dfe..274c98e164b7 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -45,7 +45,7 @@ struct queue_item {
static struct kmem_cache *tipc_queue_item_cache;
static struct list_head signal_queue_head;
static DEFINE_SPINLOCK(qitem_lock);
-static int handler_enabled = 0;
+static int handler_enabled;
static void process_signal_queue(unsigned long dummy);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index b31992ccd5d3..18702f58d111 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -35,19 +35,11 @@
*/
#include "core.h"
-#include "dbg.h"
#include "link.h"
-#include "net.h"
-#include "node.h"
#include "port.h"
-#include "addr.h"
-#include "node_subscr.h"
#include "name_distr.h"
-#include "bearer.h"
-#include "name_table.h"
#include "discover.h"
#include "config.h"
-#include "bcast.h"
/*
@@ -57,12 +49,6 @@
#define INVALID_SESSION 0x10000
/*
- * Limit for deferred reception queue:
- */
-
-#define DEF_QUEUE_LIMIT 256u
-
-/*
* Link state events:
*/
@@ -110,75 +96,10 @@ static int link_send_sections_long(struct port *sender,
static void link_check_defragm_bufs(struct link *l_ptr);
static void link_state_event(struct link *l_ptr, u32 event);
static void link_reset_statistics(struct link *l_ptr);
-static void link_print(struct link *l_ptr, struct print_buf *buf,
- const char *str);
+static void link_print(struct link *l_ptr, const char *str);
static void link_start(struct link *l_ptr);
static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
-
-/*
- * Debugging code used by link routines only
- *
- * When debugging link problems on a system that has multiple links,
- * the standard TIPC debugging routines may not be useful since they
- * allow the output from multiple links to be intermixed. For this reason
- * routines of the form "dbg_link_XXX()" have been created that will capture
- * debug info into a link's personal print buffer, which can then be dumped
- * into the TIPC system log (TIPC_LOG) upon request.
- *
- * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size
- * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0,
- * the dbg_link_XXX() routines simply send their output to the standard
- * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful
- * when there is only a single link in the system being debugged.
- *
- * Notes:
- * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE
- * - "l_ptr" must be valid when using dbg_link_XXX() macros
- */
-
-#define LINK_LOG_BUF_SIZE 0
-
-#define dbg_link(fmt, arg...) \
- do { \
- if (LINK_LOG_BUF_SIZE) \
- tipc_printf(&l_ptr->print_buf, fmt, ## arg); \
- } while (0)
-#define dbg_link_msg(msg, txt) \
- do { \
- if (LINK_LOG_BUF_SIZE) \
- tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \
- } while (0)
-#define dbg_link_state(txt) \
- do { \
- if (LINK_LOG_BUF_SIZE) \
- link_print(l_ptr, &l_ptr->print_buf, txt); \
- } while (0)
-#define dbg_link_dump() do { \
- if (LINK_LOG_BUF_SIZE) { \
- tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
- tipc_printbuf_move(LOG, &l_ptr->print_buf); \
- } \
-} while (0)
-
-static void dbg_print_link(struct link *l_ptr, const char *str)
-{
- if (DBG_OUTPUT != TIPC_NULL)
- link_print(l_ptr, DBG_OUTPUT, str);
-}
-
-static void dbg_print_buf_chain(struct sk_buff *root_buf)
-{
- if (DBG_OUTPUT != TIPC_NULL) {
- struct sk_buff *buf = root_buf;
-
- while (buf) {
- msg_dbg(buf_msg(buf), "In chain: ");
- buf = buf->next;
- }
- }
-}
-
/*
* Simple link routines
*/
@@ -266,14 +187,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts)
/* ensure all component parts of link name are present */
addr_local = name_copy;
- if ((if_local = strchr(addr_local, ':')) == NULL)
+ if_local = strchr(addr_local, ':');
+ if (if_local == NULL)
return 0;
*(if_local++) = 0;
- if ((addr_peer = strchr(if_local, '-')) == NULL)
+ addr_peer = strchr(if_local, '-');
+ if (addr_peer == NULL)
return 0;
*(addr_peer++) = 0;
if_local_len = addr_peer - if_local;
- if ((if_peer = strchr(addr_peer, ':')) == NULL)
+ if_peer = strchr(addr_peer, ':');
+ if (if_peer == NULL)
return 0;
*(if_peer++) = 0;
if_peer_len = strlen(if_peer) + 1;
@@ -392,17 +316,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
return NULL;
}
- if (LINK_LOG_BUF_SIZE) {
- char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC);
-
- if (!pb) {
- kfree(l_ptr);
- warn("Link creation failed, no memory for print buffer\n");
- return NULL;
- }
- tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
- }
-
l_ptr->addr = peer;
if_name = strchr(b_ptr->publ.name, ':') + 1;
sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
@@ -437,8 +350,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
l_ptr->owner = tipc_node_attach_link(l_ptr);
if (!l_ptr->owner) {
- if (LINK_LOG_BUF_SIZE)
- kfree(l_ptr->print_buf.buf);
kfree(l_ptr);
return NULL;
}
@@ -447,9 +358,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
list_add_tail(&l_ptr->link_list, &b_ptr->links);
tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
- dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
- l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
-
return l_ptr;
}
@@ -469,8 +377,6 @@ void tipc_link_delete(struct link *l_ptr)
return;
}
- dbg("tipc_link_delete()\n");
-
k_cancel_timer(&l_ptr->timer);
tipc_node_lock(l_ptr->owner);
@@ -478,8 +384,6 @@ void tipc_link_delete(struct link *l_ptr)
tipc_node_detach_link(l_ptr->owner, l_ptr);
tipc_link_stop(l_ptr);
list_del_init(&l_ptr->link_list);
- if (LINK_LOG_BUF_SIZE)
- kfree(l_ptr->print_buf.buf);
tipc_node_unlock(l_ptr->owner);
k_term_timer(&l_ptr->timer);
kfree(l_ptr);
@@ -487,7 +391,6 @@ void tipc_link_delete(struct link *l_ptr)
static void link_start(struct link *l_ptr)
{
- dbg("link_start %x\n", l_ptr);
link_state_event(l_ptr, STARTING_EVT);
}
@@ -639,7 +542,6 @@ void tipc_link_reset(struct link *l_ptr)
link_init_max_pkt(l_ptr);
l_ptr->state = RESET_UNKNOWN;
- dbg_link_state("Resetting Link\n");
if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
return;
@@ -713,25 +615,18 @@ static void link_state_event(struct link *l_ptr, unsigned event)
return; /* Not yet. */
if (link_blocked(l_ptr)) {
- if (event == TIMEOUT_EVT) {
+ if (event == TIMEOUT_EVT)
link_set_timer(l_ptr, cont_intv);
- }
return; /* Changeover going on */
}
- dbg_link("STATE_EV: <%s> ", l_ptr->name);
switch (l_ptr->state) {
case WORKING_WORKING:
- dbg_link("WW/");
switch (event) {
case TRAFFIC_MSG_EVT:
- dbg_link("TRF-");
- /* fall through */
case ACTIVATE_MSG:
- dbg_link("ACT\n");
break;
case TIMEOUT_EVT:
- dbg_link("TIM ");
if (l_ptr->next_in_no != l_ptr->checkpoint) {
l_ptr->checkpoint = l_ptr->next_in_no;
if (tipc_bclink_acks_missing(l_ptr->owner)) {
@@ -746,7 +641,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv);
break;
}
- dbg_link(" -> WU\n");
l_ptr->state = WORKING_UNKNOWN;
l_ptr->fsm_msg_cnt = 0;
tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
@@ -754,7 +648,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv / 4);
break;
case RESET_MSG:
- dbg_link("RES -> RR\n");
info("Resetting link <%s>, requested by peer\n",
l_ptr->name);
tipc_link_reset(l_ptr);
@@ -769,18 +662,14 @@ static void link_state_event(struct link *l_ptr, unsigned event)
}
break;
case WORKING_UNKNOWN:
- dbg_link("WU/");
switch (event) {
case TRAFFIC_MSG_EVT:
- dbg_link("TRF-");
case ACTIVATE_MSG:
- dbg_link("ACT -> WW\n");
l_ptr->state = WORKING_WORKING;
l_ptr->fsm_msg_cnt = 0;
link_set_timer(l_ptr, cont_intv);
break;
case RESET_MSG:
- dbg_link("RES -> RR\n");
info("Resetting link <%s>, requested by peer "
"while probing\n", l_ptr->name);
tipc_link_reset(l_ptr);
@@ -791,9 +680,7 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv);
break;
case TIMEOUT_EVT:
- dbg_link("TIM ");
if (l_ptr->next_in_no != l_ptr->checkpoint) {
- dbg_link("-> WW\n");
l_ptr->state = WORKING_WORKING;
l_ptr->fsm_msg_cnt = 0;
l_ptr->checkpoint = l_ptr->next_in_no;
@@ -804,16 +691,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
}
link_set_timer(l_ptr, cont_intv);
} else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
- dbg_link("Probing %u/%u,timer = %u ms)\n",
- l_ptr->fsm_msg_cnt, l_ptr->abort_limit,
- cont_intv / 4);
tipc_link_send_proto_msg(l_ptr, STATE_MSG,
1, 0, 0, 0, 0);
l_ptr->fsm_msg_cnt++;
link_set_timer(l_ptr, cont_intv / 4);
} else { /* Link has failed */
- dbg_link("-> RU (%u probes unanswered)\n",
- l_ptr->fsm_msg_cnt);
warn("Resetting link <%s>, peer not responding\n",
l_ptr->name);
tipc_link_reset(l_ptr);
@@ -830,18 +712,13 @@ static void link_state_event(struct link *l_ptr, unsigned event)
}
break;
case RESET_UNKNOWN:
- dbg_link("RU/");
switch (event) {
case TRAFFIC_MSG_EVT:
- dbg_link("TRF-\n");
break;
case ACTIVATE_MSG:
other = l_ptr->owner->active_links[0];
- if (other && link_working_unknown(other)) {
- dbg_link("ACT\n");
+ if (other && link_working_unknown(other))
break;
- }
- dbg_link("ACT -> WW\n");
l_ptr->state = WORKING_WORKING;
l_ptr->fsm_msg_cnt = 0;
link_activate(l_ptr);
@@ -850,8 +727,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv);
break;
case RESET_MSG:
- dbg_link("RES\n");
- dbg_link(" -> RR\n");
l_ptr->state = RESET_RESET;
l_ptr->fsm_msg_cnt = 0;
tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
@@ -859,11 +734,9 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv);
break;
case STARTING_EVT:
- dbg_link("START-");
l_ptr->started = 1;
/* fall through */
case TIMEOUT_EVT:
- dbg_link("TIM\n");
tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
l_ptr->fsm_msg_cnt++;
link_set_timer(l_ptr, cont_intv);
@@ -873,18 +746,12 @@ static void link_state_event(struct link *l_ptr, unsigned event)
}
break;
case RESET_RESET:
- dbg_link("RR/ ");
switch (event) {
case TRAFFIC_MSG_EVT:
- dbg_link("TRF-");
- /* fall through */
case ACTIVATE_MSG:
other = l_ptr->owner->active_links[0];
- if (other && link_working_unknown(other)) {
- dbg_link("ACT\n");
+ if (other && link_working_unknown(other))
break;
- }
- dbg_link("ACT -> WW\n");
l_ptr->state = WORKING_WORKING;
l_ptr->fsm_msg_cnt = 0;
link_activate(l_ptr);
@@ -893,14 +760,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
link_set_timer(l_ptr, cont_intv);
break;
case RESET_MSG:
- dbg_link("RES\n");
break;
case TIMEOUT_EVT:
- dbg_link("TIM\n");
tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
l_ptr->fsm_msg_cnt++;
link_set_timer(l_ptr, cont_intv);
- dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt);
break;
default:
err("Unknown link event %u in RR state\n", event);
@@ -940,9 +804,6 @@ static int link_bundle_buf(struct link *l_ptr,
skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
msg_set_size(bundler_msg, to_pos + size);
msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
- dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n",
- msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg));
- msg_dbg(msg, "PACKD:");
buf_discard(buf);
l_ptr->stats.sent_bundled++;
return 1;
@@ -991,7 +852,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
return link_schedule_port(l_ptr, msg_origport(msg),
size);
}
- msg_dbg(msg, "TIPC: Congestion, throwing away\n");
buf_discard(buf);
if (imp > CONN_MANAGER) {
warn("Resetting link <%s>, send queue full", l_ptr->name);
@@ -1075,22 +935,16 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
int res = -ELINKCONG;
read_lock_bh(&tipc_net_lock);
- n_ptr = tipc_node_select(dest, selector);
+ n_ptr = tipc_node_find(dest);
if (n_ptr) {
tipc_node_lock(n_ptr);
l_ptr = n_ptr->active_links[selector & 1];
- if (l_ptr) {
- dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
+ if (l_ptr)
res = tipc_link_send_buf(l_ptr, buf);
- } else {
- dbg("Attempt to send msg to unreachable node:\n");
- msg_dbg(buf_msg(buf),">>>");
+ else
buf_discard(buf);
- }
tipc_node_unlock(n_ptr);
} else {
- dbg("Attempt to send msg to unknown node:\n");
- msg_dbg(buf_msg(buf),">>>");
buf_discard(buf);
}
read_unlock_bh(&tipc_net_lock);
@@ -1117,17 +971,14 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf,
if (likely(tipc_bearer_send(l_ptr->b_ptr, buf,
&l_ptr->media_addr))) {
l_ptr->unacked_window = 0;
- msg_dbg(msg,"SENT_FAST:");
return res;
}
- dbg("failed sent fast...\n");
tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
l_ptr->stats.bearer_congs++;
l_ptr->next_out = buf;
return res;
}
- }
- else
+ } else
*used_max_pkt = l_ptr->max_pkt;
}
return tipc_link_send_buf(l_ptr, buf); /* All other cases */
@@ -1151,12 +1002,10 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
return tipc_port_recv_msg(buf);
read_lock_bh(&tipc_net_lock);
- n_ptr = tipc_node_select(destnode, selector);
+ n_ptr = tipc_node_find(destnode);
if (likely(n_ptr)) {
tipc_node_lock(n_ptr);
l_ptr = n_ptr->active_links[selector];
- dbg("send_fast: buf %x selected %x, destnode = %x\n",
- buf, l_ptr, destnode);
if (likely(l_ptr)) {
res = link_send_buf_fast(l_ptr, buf, &dummy);
tipc_node_unlock(n_ptr);
@@ -1200,7 +1049,7 @@ again:
!sender->user_port, &buf);
read_lock_bh(&tipc_net_lock);
- node = tipc_node_select(destaddr, selector);
+ node = tipc_node_find(destaddr);
if (likely(node)) {
tipc_node_lock(node);
l_ptr = node->active_links[selector];
@@ -1283,10 +1132,10 @@ static int link_send_sections_long(struct port *sender,
struct tipc_node *node;
struct tipc_msg *hdr = &sender->publ.phdr;
u32 dsz = msg_data_sz(hdr);
- u32 max_pkt,fragm_sz,rest;
+ u32 max_pkt, fragm_sz, rest;
struct tipc_msg fragm_hdr;
- struct sk_buff *buf,*buf_chain,*prev;
- u32 fragm_crs,fragm_rest,hsz,sect_rest;
+ struct sk_buff *buf, *buf_chain, *prev;
+ u32 fragm_crs, fragm_rest, hsz, sect_rest;
const unchar *sect_crs;
int curr_sect;
u32 fragm_no;
@@ -1306,7 +1155,6 @@ again:
/* Prepare reusable fragment header: */
- msg_dbg(hdr, ">FRAGMENTING>");
tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
INT_H_SIZE, msg_destnode(hdr));
msg_set_link_selector(&fragm_hdr, sender->publ.ref);
@@ -1322,7 +1170,6 @@ again:
skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
hsz = msg_hdr_sz(hdr);
skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz);
- msg_dbg(buf_msg(buf), ">BUILD>");
/* Chop up message: */
@@ -1365,7 +1212,7 @@ error:
/* Initiate new fragment: */
if (rest <= fragm_sz) {
fragm_sz = rest;
- msg_set_type(&fragm_hdr,LAST_FRAGMENT);
+ msg_set_type(&fragm_hdr, LAST_FRAGMENT);
} else {
msg_set_type(&fragm_hdr, FRAGMENT);
}
@@ -1381,16 +1228,14 @@ error:
skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
fragm_crs = INT_H_SIZE;
fragm_rest = fragm_sz;
- msg_dbg(buf_msg(buf)," >BUILD>");
}
- }
- while (rest > 0);
+ } while (rest > 0);
/*
* Now we have a buffer chain. Select a link and check
* that packet size is still OK
*/
- node = tipc_node_select(destaddr, sender->publ.ref & 1);
+ node = tipc_node_find(destaddr);
if (likely(node)) {
tipc_node_lock(node);
l_ptr = node->active_links[sender->publ.ref & 1];
@@ -1431,7 +1276,6 @@ reject:
l_ptr->stats.sent_fragments++;
msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
link_add_to_outqueue(l_ptr, buf, msg);
- msg_dbg(msg, ">ADD>");
buf = next;
}
@@ -1473,14 +1317,12 @@ u32 tipc_link_push_packet(struct link *l_ptr)
msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
- msg_dbg(buf_msg(buf), ">DEF-RETR>");
l_ptr->retransm_queue_head = mod(++r_q_head);
l_ptr->retransm_queue_size = --r_q_size;
l_ptr->stats.retransmitted++;
return 0;
} else {
l_ptr->stats.bearer_congs++;
- msg_dbg(buf_msg(buf), "|>DEF-RETR>");
return PUSH_FAILED;
}
}
@@ -1490,15 +1332,13 @@ u32 tipc_link_push_packet(struct link *l_ptr)
buf = l_ptr->proto_msg_queue;
if (buf) {
msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
- msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in);
+ msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
- msg_dbg(buf_msg(buf), ">DEF-PROT>");
l_ptr->unacked_window = 0;
buf_discard(buf);
l_ptr->proto_msg_queue = NULL;
return 0;
} else {
- msg_dbg(buf_msg(buf), "|>DEF-PROT>");
l_ptr->stats.bearer_congs++;
return PUSH_FAILED;
}
@@ -1518,11 +1358,9 @@ u32 tipc_link_push_packet(struct link *l_ptr)
if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
if (msg_user(msg) == MSG_BUNDLER)
msg_set_type(msg, CLOSED_MSG);
- msg_dbg(msg, ">PUSH-DATA>");
l_ptr->next_out = buf->next;
return 0;
} else {
- msg_dbg(msg, "|PUSH-DATA|");
l_ptr->stats.bearer_congs++;
return PUSH_FAILED;
}
@@ -1570,8 +1408,7 @@ static void link_reset_all(unsigned long addr)
for (i = 0; i < MAX_BEARERS; i++) {
if (n_ptr->links[i]) {
- link_print(n_ptr->links[i], TIPC_OUTPUT,
- "Resetting link\n");
+ link_print(n_ptr->links[i], "Resetting link\n");
tipc_link_reset(n_ptr->links[i]);
}
}
@@ -1585,13 +1422,12 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
struct tipc_msg *msg = buf_msg(buf);
warn("Retransmission failure on link <%s>\n", l_ptr->name);
- tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
if (l_ptr->addr) {
/* Handle failure on standard link */
- link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n");
+ link_print(l_ptr, "Resetting link\n");
tipc_link_reset(l_ptr);
} else {
@@ -1601,21 +1437,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
struct tipc_node *n_ptr;
char addr_string[16];
- tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg));
- tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n",
- (unsigned long) TIPC_SKB_CB(buf)->handle);
+ info("Msg seq number: %u, ", msg_seqno(msg));
+ info("Outstanding acks: %lu\n",
+ (unsigned long) TIPC_SKB_CB(buf)->handle);
n_ptr = l_ptr->owner->next;
tipc_node_lock(n_ptr);
tipc_addr_string_fill(addr_string, n_ptr->addr);
- tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string);
- tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported);
- tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked);
- tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in);
- tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after);
- tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to);
- tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
+ info("Multicast link info for %s\n", addr_string);
+ info("Supported: %d, ", n_ptr->bclink.supported);
+ info("Acked: %u\n", n_ptr->bclink.acked);
+ info("Last in: %u, ", n_ptr->bclink.last_in);
+ info("Gap after: %u, ", n_ptr->bclink.gap_after);
+ info("Gap to: %u\n", n_ptr->bclink.gap_to);
+ info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
@@ -1635,12 +1471,8 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
msg = buf_msg(buf);
- dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
-
if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
if (l_ptr->retransm_queue_size == 0) {
- msg_dbg(msg, ">NO_RETR->BCONG>");
- dbg_print_link(l_ptr, " ");
l_ptr->retransm_queue_head = msg_seqno(msg);
l_ptr->retransm_queue_size = retransmits;
} else {
@@ -1667,7 +1499,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
- msg_dbg(buf_msg(buf), ">RETR>");
buf = buf->next;
retransmits--;
l_ptr->stats.retransmitted++;
@@ -1793,9 +1624,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
/* Ensure message data is a single contiguous unit */
- if (unlikely(buf_linearize(buf))) {
+ if (unlikely(buf_linearize(buf)))
goto cont;
- }
/* Handle arrival of a non-unicast link message */
@@ -1907,7 +1737,7 @@ deliver:
continue;
case ROUTE_DISTRIBUTOR:
tipc_node_unlock(n_ptr);
- tipc_cltr_recv_routing_table(buf);
+ buf_discard(buf);
continue;
case NAME_DISTRIBUTOR:
tipc_node_unlock(n_ptr);
@@ -1953,12 +1783,10 @@ deliver:
tipc_node_unlock(n_ptr);
continue;
}
- msg_dbg(msg,"NSEQ<REC<");
link_state_event(l_ptr, TRAFFIC_MSG_EVT);
if (link_working_working(l_ptr)) {
/* Re-insert in front of queue */
- msg_dbg(msg,"RECV-REINS:");
buf->next = head;
head = buf;
tipc_node_unlock(n_ptr);
@@ -2012,13 +1840,11 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
*head = buf;
return 1;
}
- if (seq_no == msg_seqno(msg)) {
+ if (seq_no == msg_seqno(msg))
break;
- }
prev = crs;
crs = crs->next;
- }
- while (crs);
+ } while (crs);
/* Message is a duplicate of an existing message */
@@ -2040,9 +1866,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
return;
}
- dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n",
- seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no);
-
/* Record OOS packet arrival (force mismatch on next timeout) */
l_ptr->checkpoint--;
@@ -2132,11 +1955,10 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
msg_set_max_pkt(msg, l_ptr->max_pkt_target);
}
- if (tipc_node_has_redundant_links(l_ptr->owner)) {
+ if (tipc_node_has_redundant_links(l_ptr->owner))
msg_set_redundant_link(msg);
- } else {
+ else
msg_clear_redundant_link(msg);
- }
msg_set_linkprio(msg, l_ptr->priority);
/* Ensure sequence number will not fit : */
@@ -2160,8 +1982,6 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
/* Message can be sent */
- msg_dbg(msg, ">>");
-
buf = tipc_buf_acquire(msg_size);
if (!buf)
return;
@@ -2195,8 +2015,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
u32 msg_tol;
struct tipc_msg *msg = buf_msg(buf);
- dbg("AT(%u):", jiffies_to_msecs(jiffies));
- msg_dbg(msg, "<<");
if (link_blocked(l_ptr))
goto exit;
@@ -2215,11 +2033,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
case RESET_MSG:
if (!link_working_unknown(l_ptr) &&
(l_ptr->peer_session != INVALID_SESSION)) {
- if (msg_session(msg) == l_ptr->peer_session) {
- dbg("Duplicate RESET: %u<->%u\n",
- msg_session(msg), l_ptr->peer_session);
+ if (msg_session(msg) == l_ptr->peer_session)
break; /* duplicate: ignore */
- }
}
/* fall thru' */
case ACTIVATE_MSG:
@@ -2227,8 +2042,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg));
- if ((msg_tol = msg_link_tolerance(msg)) &&
- (msg_tol > l_ptr->tolerance))
+ msg_tol = msg_link_tolerance(msg);
+ if (msg_tol > l_ptr->tolerance)
link_set_supervision_props(l_ptr, msg_tol);
if (msg_linkprio(msg) > l_ptr->priority)
@@ -2251,13 +2066,13 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
l_ptr->peer_bearer_id = msg_bearer_id(msg);
/* Synchronize broadcast sequence numbers */
- if (!tipc_node_has_redundant_links(l_ptr->owner)) {
+ if (!tipc_node_has_redundant_links(l_ptr->owner))
l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
- }
break;
case STATE_MSG:
- if ((msg_tol = msg_link_tolerance(msg)))
+ msg_tol = msg_link_tolerance(msg);
+ if (msg_tol)
link_set_supervision_props(l_ptr, msg_tol);
if (msg_linkprio(msg) &&
@@ -2280,8 +2095,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
max_pkt_ack = msg_max_pkt(msg);
if (max_pkt_ack > l_ptr->max_pkt) {
- dbg("Link <%s> updated MTU %u -> %u\n",
- l_ptr->name, l_ptr->max_pkt, max_pkt_ack);
l_ptr->max_pkt = max_pkt_ack;
l_ptr->max_pkt_probes = 0;
}
@@ -2289,9 +2102,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
max_pkt_ack = 0;
if (msg_probe(msg)) {
l_ptr->stats.recv_probes++;
- if (msg_size(msg) > sizeof(l_ptr->proto_msg)) {
+ if (msg_size(msg) > sizeof(l_ptr->proto_msg))
max_pkt_ack = msg_size(msg);
- }
}
/* Protocol message before retransmits, reduce loss risk */
@@ -2303,14 +2115,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
0, rec_gap, 0, 0, max_pkt_ack);
}
if (msg_seq_gap(msg)) {
- msg_dbg(msg, "With Gap:");
l_ptr->stats.recv_nacks++;
tipc_link_retransmit(l_ptr, l_ptr->first_out,
msg_seq_gap(msg));
}
break;
- default:
- msg_dbg(buf_msg(buf), "<DISCARDING UNKNOWN<");
}
exit:
buf_discard(buf);
@@ -2345,8 +2154,6 @@ static void tipc_link_tunnel(struct link *l_ptr,
}
skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
- dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
- msg_dbg(buf_msg(buf), ">SEND>");
tipc_link_send_buf(tunnel, buf);
}
@@ -2378,7 +2185,6 @@ void tipc_link_changeover(struct link *l_ptr)
ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
msg_set_msgcnt(&tunnel_hdr, msgcount);
- dbg("Link changeover requires %u tunnel messages\n", msgcount);
if (!l_ptr->first_out) {
struct sk_buff *buf;
@@ -2387,9 +2193,6 @@ void tipc_link_changeover(struct link *l_ptr)
if (buf) {
skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
msg_set_size(&tunnel_hdr, INT_H_SIZE);
- dbg("%c->%c:", l_ptr->b_ptr->net_plane,
- tunnel->b_ptr->net_plane);
- msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
tipc_link_send_buf(tunnel, buf);
} else {
warn("Link changeover error, "
@@ -2406,11 +2209,11 @@ void tipc_link_changeover(struct link *l_ptr)
if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
struct tipc_msg *m = msg_get_wrapped(msg);
- unchar* pos = (unchar*)m;
+ unchar *pos = (unchar *)m;
msgcount = msg_msgcnt(msg);
while (msgcount--) {
- msg_set_seqno(m,msg_seqno(msg));
+ msg_set_seqno(m, msg_seqno(msg));
tipc_link_tunnel(l_ptr, &tunnel_hdr, m,
msg_link_selector(m));
pos += align(msg_size(m));
@@ -2453,9 +2256,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
length);
- dbg("%c->%c:", l_ptr->b_ptr->net_plane,
- tunnel->b_ptr->net_plane);
- msg_dbg(buf_msg(outbuf), ">SEND>");
tipc_link_send_buf(tunnel, outbuf);
if (!tipc_link_is_up(l_ptr))
return;
@@ -2502,31 +2302,24 @@ static int link_recv_changeover_msg(struct link **l_ptr,
u32 msg_count = msg_msgcnt(tunnel_msg);
dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)];
- if (!dest_link) {
- msg_dbg(tunnel_msg, "NOLINK/<REC<");
+ if (!dest_link)
goto exit;
- }
if (dest_link == *l_ptr) {
err("Unexpected changeover message on link <%s>\n",
(*l_ptr)->name);
goto exit;
}
- dbg("%c<-%c:", dest_link->b_ptr->net_plane,
- (*l_ptr)->b_ptr->net_plane);
*l_ptr = dest_link;
msg = msg_get_wrapped(tunnel_msg);
if (msg_typ == DUPLICATE_MSG) {
- if (less(msg_seqno(msg), mod(dest_link->next_in_no))) {
- msg_dbg(tunnel_msg, "DROP/<REC<");
+ if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
goto exit;
- }
- *buf = buf_extract(tunnel_buf,INT_H_SIZE);
+ *buf = buf_extract(tunnel_buf, INT_H_SIZE);
if (*buf == NULL) {
warn("Link changeover error, duplicate msg dropped\n");
goto exit;
}
- msg_dbg(tunnel_msg, "TNL<REC<");
buf_discard(tunnel_buf);
return 1;
}
@@ -2534,18 +2327,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
/* First original message ?: */
if (tipc_link_is_up(dest_link)) {
- msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
info("Resetting link <%s>, changeover initiated by peer\n",
dest_link->name);
tipc_link_reset(dest_link);
dest_link->exp_msg_count = msg_count;
- dbg("Expecting %u tunnelled messages\n", msg_count);
if (!msg_count)
goto exit;
} else if (dest_link->exp_msg_count == START_CHANGEOVER) {
- msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
dest_link->exp_msg_count = msg_count;
- dbg("Expecting %u tunnelled messages\n", msg_count);
if (!msg_count)
goto exit;
}
@@ -2555,18 +2344,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
if (dest_link->exp_msg_count == 0) {
warn("Link switchover error, "
"got too many tunnelled messages\n");
- msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
- dbg_print_link(dest_link, "LINK:");
goto exit;
}
dest_link->exp_msg_count--;
if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
- msg_dbg(tunnel_msg, "DROP/DUPL/<REC<");
goto exit;
} else {
*buf = buf_extract(tunnel_buf, INT_H_SIZE);
if (*buf != NULL) {
- msg_dbg(tunnel_msg, "TNL<REC<");
buf_discard(tunnel_buf);
return 1;
} else {
@@ -2588,7 +2373,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
u32 pos = INT_H_SIZE;
struct sk_buff *obuf;
- msg_dbg(buf_msg(buf), "<BNDL<: ");
while (msgcount--) {
obuf = buf_extract(buf, pos);
if (obuf == NULL) {
@@ -2596,7 +2380,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
break;
}
pos += align(msg_size(buf_msg(obuf)));
- msg_dbg(buf_msg(obuf), " /");
tipc_net_route_msg(obuf);
}
buf_discard(buf);
@@ -2733,7 +2516,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
u32 long_msg_seq_no = msg_long_msgno(fragm);
*fb = NULL;
- msg_dbg(fragm,"FRG<REC<");
/* Is there an incomplete message waiting for this fragment? */
@@ -2752,7 +2534,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
if (msg_type(imsg) == TIPC_MCAST_MSG)
max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
if (msg_size(imsg) > max) {
- msg_dbg(fragm,"<REC<Oversized: ");
buf_discard(fbuf);
return 0;
}
@@ -2765,8 +2546,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
/* Prepare buffer for subsequent fragments. */
set_long_msg_seqno(pbuf, long_msg_seq_no);
- set_fragm_size(pbuf,fragm_sz);
- set_expected_frags(pbuf,exp_fragm_cnt - 1);
+ set_fragm_size(pbuf, fragm_sz);
+ set_expected_frags(pbuf, exp_fragm_cnt - 1);
} else {
warn("Link unable to reassemble fragmented message\n");
}
@@ -2793,13 +2574,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
*m = buf_msg(pbuf);
return 1;
}
- set_expected_frags(pbuf,exp_frags);
+ set_expected_frags(pbuf, exp_frags);
return 0;
}
- dbg(" Discarding orphan fragment %x\n",fbuf);
- msg_dbg(fragm,"ORPHAN:");
- dbg("Pending long buffers:\n");
- dbg_print_buf_chain(*pending);
buf_discard(fbuf);
return 0;
}
@@ -2827,11 +2604,6 @@ static void link_check_defragm_bufs(struct link *l_ptr)
incr_timer_cnt(buf);
prev = buf;
} else {
- dbg(" Discarding incomplete long buffer\n");
- msg_dbg(buf_msg(buf), "LONG:");
- dbg_print_link(l_ptr, "curr:");
- dbg("Pending long buffers:\n");
- dbg_print_buf_chain(l_ptr->defragm_buf);
if (prev)
prev->next = buf->next;
else
@@ -2866,7 +2638,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
l_ptr->queue_limit[CONN_MANAGER] = 1200;
- l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200;
l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
/* FRAGMENT and LAST_FRAGMENT packets */
@@ -3168,7 +2939,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
return MAX_MSG_SIZE;
read_lock_bh(&tipc_net_lock);
- n_ptr = tipc_node_select(dest, selector);
+ n_ptr = tipc_node_find(dest);
if (n_ptr) {
tipc_node_lock(n_ptr);
l_ptr = n_ptr->active_links[selector & 1];
@@ -3180,27 +2951,22 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
return res;
}
-static void link_dump_send_queue(struct link *l_ptr)
+static void link_print(struct link *l_ptr, const char *str)
{
- if (l_ptr->next_out) {
- info("\nContents of unsent queue:\n");
- dbg_print_buf_chain(l_ptr->next_out);
- }
- info("\nContents of send queue:\n");
- if (l_ptr->first_out) {
- dbg_print_buf_chain(l_ptr->first_out);
- }
- info("Empty send queue\n");
-}
+ char print_area[256];
+ struct print_buf pb;
+ struct print_buf *buf = &pb;
+
+ tipc_printbuf_init(buf, print_area, sizeof(print_area));
-static void link_print(struct link *l_ptr, struct print_buf *buf,
- const char *str)
-{
tipc_printf(buf, str);
- if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
- return;
tipc_printf(buf, "Link %x<%s>:",
l_ptr->addr, l_ptr->b_ptr->publ.name);
+
+#ifdef CONFIG_TIPC_DEBUG
+ if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
+ goto print_state;
+
tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no));
tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no));
tipc_printf(buf, "SQUE");
@@ -3218,7 +2984,6 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
tipc_printf(buf, "first_out= %x ", l_ptr->first_out);
tipc_printf(buf, "next_out= %x ", l_ptr->next_out);
tipc_printf(buf, "last_out= %x ", l_ptr->last_out);
- link_dump_send_queue(l_ptr);
}
} else
tipc_printf(buf, "[]");
@@ -3232,14 +2997,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
l_ptr->deferred_inqueue_sz);
}
}
+print_state:
+#endif
+
if (link_working_unknown(l_ptr))
tipc_printf(buf, ":WU");
- if (link_reset_reset(l_ptr))
+ else if (link_reset_reset(l_ptr))
tipc_printf(buf, ":RR");
- if (link_reset_unknown(l_ptr))
+ else if (link_reset_unknown(l_ptr))
tipc_printf(buf, ":RU");
- if (link_working_working(l_ptr))
+ else if (link_working_working(l_ptr))
tipc_printf(buf, ":WW");
tipc_printf(buf, "\n");
+
+ tipc_printbuf_validate(buf);
+ info("%s", print_area);
}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index f98bc613de67..70967e637027 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -37,9 +37,8 @@
#ifndef _TIPC_LINK_H
#define _TIPC_LINK_H
-#include "dbg.h"
+#include "log.h"
#include "msg.h"
-#include "bearer.h"
#include "node.h"
#define PUSH_FAILED 1
@@ -108,7 +107,6 @@
* @long_msg_seq_no: next identifier to use for outbound fragmented messages
* @defragm_buf: list of partially reassembled inbound message fragments
* @stats: collects statistics regarding link activity
- * @print_buf: print buffer used to log link activity
*/
struct link {
@@ -211,8 +209,6 @@ struct link {
u32 msg_lengths_total;
u32 msg_length_profile[7];
} stats;
-
- struct print_buf print_buf;
};
struct port;
@@ -233,8 +229,8 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
void tipc_link_reset(struct link *l_ptr);
int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
-u32 tipc_link_get_max_pkt(u32 dest,u32 selector);
-int tipc_link_send_sections_fast(struct port* sender,
+u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
+int tipc_link_send_sections_fast(struct port *sender,
struct iovec const *msg_sect,
const u32 num_sect,
u32 destnode);
diff --git a/net/tipc/dbg.c b/net/tipc/log.c
index 46f51d208e5e..952c39f643e6 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/log.c
@@ -1,5 +1,5 @@
/*
- * net/tipc/dbg.c: TIPC print buffer routines for debugging
+ * net/tipc/log.c: TIPC print buffer routines for debugging
*
* Copyright (c) 1996-2006, Ericsson AB
* Copyright (c) 2005-2007, Wind River Systems
@@ -36,7 +36,7 @@
#include "core.h"
#include "config.h"
-#include "dbg.h"
+#include "log.h"
/*
* TIPC pre-defines the following print buffers:
@@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 };
struct print_buf *const TIPC_NULL = &null_buf;
static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
-static struct print_buf *const TIPC_CONS = &cons_buf;
+struct print_buf *const TIPC_CONS = &cons_buf;
static struct print_buf log_buf = { NULL, 0, NULL, 1 };
struct print_buf *const TIPC_LOG = &log_buf;
@@ -64,9 +64,9 @@ struct print_buf *const TIPC_LOG = &log_buf;
* 'print_string' when writing to a print buffer. This also protects against
* concurrent writes to the print buffer being written to.
*
- * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned
- * use of 'print_lock' to protect against all types of concurrent operations
- * on their associated print buffer (not just write operations).
+ * 2) tipc_log_XXX() leverages the aforementioned use of 'print_lock' to
+ * protect against all types of concurrent operations on their associated
+ * print buffer (not just write operations).
*
* Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
* on the caller to prevent simultaneous use of the print buffer(s) being
@@ -76,18 +76,16 @@ struct print_buf *const TIPC_LOG = &log_buf;
static char print_string[TIPC_PB_MAX_STR];
static DEFINE_SPINLOCK(print_lock);
-static void tipc_printbuf_reset(struct print_buf *pb);
-static int tipc_printbuf_empty(struct print_buf *pb);
static void tipc_printbuf_move(struct print_buf *pb_to,
struct print_buf *pb_from);
-#define FORMAT(PTR,LEN,FMT) \
+#define FORMAT(PTR, LEN, FMT) \
{\
- va_list args;\
- va_start(args, FMT);\
- LEN = vsprintf(PTR, FMT, args);\
- va_end(args);\
- *(PTR + LEN) = '\0';\
+ va_list args;\
+ va_start(args, FMT);\
+ LEN = vsprintf(PTR, FMT, args);\
+ va_end(args);\
+ *(PTR + LEN) = '\0';\
}
/**
@@ -268,81 +266,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
spin_unlock_bh(&print_lock);
}
-#ifdef CONFIG_TIPC_DEBUG
-
-/**
- * print_to_console - write string of bytes to console in multiple chunks
- */
-
-static void print_to_console(char *crs, int len)
-{
- int rest = len;
-
- while (rest > 0) {
- int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR;
- char c = crs[sz];
-
- crs[sz] = 0;
- printk((const char *)crs);
- crs[sz] = c;
- rest -= sz;
- crs += sz;
- }
-}
-
-/**
- * printbuf_dump - write print buffer contents to console
- */
-
-static void printbuf_dump(struct print_buf *pb)
-{
- int len;
-
- if (!pb->buf) {
- printk("*** PRINT BUFFER NOT ALLOCATED ***");
- return;
- }
-
- /* Dump print buffer from char after cursor to end (if used) */
-
- len = pb->buf + pb->size - pb->crs - 2;
- if ((pb->buf[pb->size - 1] == 0) && (len > 0))
- print_to_console(pb->crs + 1, len);
-
- /* Dump print buffer from start to cursor (always) */
-
- len = pb->crs - pb->buf;
- print_to_console(pb->buf, len);
-}
-
-/**
- * tipc_dump_dbg - dump (non-console) print buffer to console
- * @pb: pointer to print buffer
- */
-
-void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...)
-{
- int len;
-
- if (pb == TIPC_CONS)
- return;
-
- spin_lock_bh(&print_lock);
-
- FORMAT(print_string, len, fmt);
- printk(print_string);
-
- printk("\n---- Start of %s log dump ----\n\n",
- (pb == TIPC_LOG) ? "global" : "local");
- printbuf_dump(pb);
- tipc_printbuf_reset(pb);
- printk("\n---- End of dump ----\n");
-
- spin_unlock_bh(&print_lock);
-}
-
-#endif
-
/**
* tipc_log_resize - change the size of the TIPC log buffer
* @log_size: print buffer size to use
@@ -353,10 +276,8 @@ int tipc_log_resize(int log_size)
int res = 0;
spin_lock_bh(&print_lock);
- if (TIPC_LOG->buf) {
- kfree(TIPC_LOG->buf);
- TIPC_LOG->buf = NULL;
- }
+ kfree(TIPC_LOG->buf);
+ TIPC_LOG->buf = NULL;
if (log_size) {
if (log_size < TIPC_PB_MIN_SIZE)
log_size = TIPC_PB_MIN_SIZE;
@@ -407,8 +328,7 @@ struct sk_buff *tipc_log_dump(void)
} else if (tipc_printbuf_empty(TIPC_LOG)) {
spin_unlock_bh(&print_lock);
reply = tipc_cfg_reply_ultra_string("log is empty\n");
- }
- else {
+ } else {
struct tlv_desc *rep_tlv;
struct print_buf pb;
int str_len;
@@ -429,4 +349,3 @@ struct sk_buff *tipc_log_dump(void)
}
return reply;
}
-
diff --git a/net/tipc/dbg.h b/net/tipc/log.h
index 3ba6ba8b434a..2248d96238e6 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/log.h
@@ -1,5 +1,5 @@
/*
- * net/tipc/dbg.h: Include file for TIPC print buffer routines
+ * net/tipc/log.h: Include file for TIPC print buffer routines
*
* Copyright (c) 1997-2006, Ericsson AB
* Copyright (c) 2005-2007, Wind River Systems
@@ -34,8 +34,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _TIPC_DBG_H
-#define _TIPC_DBG_H
+#ifndef _TIPC_LOG_H
+#define _TIPC_LOG_H
/**
* struct print_buf - TIPC print buffer structure
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ecb532fb0351..bb6180c4fcbb 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -35,10 +35,7 @@
*/
#include "core.h"
-#include "addr.h"
-#include "dbg.h"
#include "msg.h"
-#include "bearer.h"
u32 tipc_msg_tot_importance(struct tipc_msg *m)
{
@@ -94,7 +91,7 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
int tipc_msg_build(struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
- int max_size, int usrmem, struct sk_buff** buf)
+ int max_size, int usrmem, struct sk_buff **buf)
{
int dsz, sz, hsz, pos, res, cnt;
@@ -140,6 +137,7 @@ int tipc_msg_build(struct tipc_msg *hdr,
void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
{
u32 usr = msg_user(msg);
+ tipc_printf(buf, KERN_DEBUG);
tipc_printf(buf, str);
switch (usr) {
@@ -163,10 +161,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "LAST:");
break;
default:
- tipc_printf(buf, "UNKNOWN:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
}
- tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg),
+ tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg),
msg_fragm_no(msg));
break;
case TIPC_LOW_IMPORTANCE:
@@ -192,7 +190,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "DIR:");
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
}
if (msg_routed(msg) && !msg_non_seq(msg))
tipc_printf(buf, "ROUT:");
@@ -210,7 +208,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "WDRW:");
break;
default:
- tipc_printf(buf, "UNKNOWN:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
}
if (msg_routed(msg))
tipc_printf(buf, "ROUT:");
@@ -229,39 +227,39 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
break;
case CONN_ACK:
tipc_printf(buf, "CONN_ACK:");
- tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg));
+ tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg));
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
}
if (msg_routed(msg))
tipc_printf(buf, "ROUT:");
if (msg_reroute_cnt(msg))
- tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg));
+ tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
break;
case LINK_PROTOCOL:
- tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg));
+ tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg));
switch (msg_type(msg)) {
case STATE_MSG:
tipc_printf(buf, "STATE:");
- tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :"");
- tipc_printf(buf, "NXS(%u):",msg_next_sent(msg));
- tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg));
- tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg));
+ tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : "");
+ tipc_printf(buf, "NXS(%u):", msg_next_sent(msg));
+ tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg));
+ tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg));
break;
case RESET_MSG:
tipc_printf(buf, "RESET:");
if (msg_size(msg) != msg_hdr_sz(msg))
- tipc_printf(buf, "BEAR:%s:",msg_data(msg));
+ tipc_printf(buf, "BEAR:%s:", msg_data(msg));
break;
case ACTIVATE_MSG:
tipc_printf(buf, "ACTIVATE:");
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
}
- tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg));
- tipc_printf(buf, "SESS(%u):",msg_session(msg));
+ tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg));
+ tipc_printf(buf, "SESS(%u):", msg_session(msg));
break;
case CHANGEOVER_PROTOCOL:
tipc_printf(buf, "TUNL:");
@@ -271,10 +269,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
break;
case ORIGINAL_MSG:
tipc_printf(buf, "ORIG:");
- tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg));
+ tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg));
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
}
break;
case ROUTE_DISTRIBUTOR:
@@ -282,26 +280,26 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
switch (msg_type(msg)) {
case EXT_ROUTING_TABLE:
tipc_printf(buf, "EXT_TBL:");
- tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
+ tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
break;
case LOCAL_ROUTING_TABLE:
tipc_printf(buf, "LOCAL_TBL:");
- tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
+ tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
break;
case SLAVE_ROUTING_TABLE:
tipc_printf(buf, "DP_TBL:");
- tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
+ tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
break;
case ROUTE_ADDITION:
tipc_printf(buf, "ADD:");
- tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
+ tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
break;
case ROUTE_REMOVAL:
tipc_printf(buf, "REMOVE:");
- tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
+ tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
}
break;
case LINK_CONFIG:
@@ -314,7 +312,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "DSC_RESP:");
break;
default:
- tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg));
+ tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg));
break;
}
break;
@@ -350,7 +348,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "UNKNOWN ERROR(%x):",
msg_errcode(msg));
}
- default:{}
+ default:
+ break;
}
tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg));
@@ -359,9 +358,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
if (msg_non_seq(msg))
tipc_printf(buf, "NOSEQ:");
- else {
+ else
tipc_printf(buf, "ACK(%u):", msg_ack(msg));
- }
tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg));
tipc_printf(buf, "PRND(%x)", msg_prevnode(msg));
@@ -389,14 +387,13 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
if (msg_user(msg) == NAME_DISTRIBUTOR) {
tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
- if (msg_routed(msg)) {
+ if (msg_routed(msg))
tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
- }
}
if (msg_user(msg) == LINK_CONFIG) {
- u32* raw = (u32*)msg;
- struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5];
+ u32 *raw = (u32 *)msg;
+ struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
@@ -407,12 +404,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg));
}
tipc_printf(buf, "\n");
- if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) {
+ if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg)))
tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
- }
- if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
+ if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT))
tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
- }
}
#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 031aad18efce..92c4c4fd7b3f 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -37,10 +37,51 @@
#ifndef _TIPC_MSG_H
#define _TIPC_MSG_H
-#include "core.h"
+#include "bearer.h"
#define TIPC_VERSION 2
+/*
+ * TIPC user data message header format, version 2:
+ *
+ *
+ * 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w0:|vers | user |hdr sz |n|d|s|-| message size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w2:| link level ack no | broadcast/link level seq no |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w3:| previous node |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w4:| originating port |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w5:| destination port |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w6:| originating node |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w7:| destination node |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w8:| name type / transport sequence number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * w9:| name instance/multicast lower bound |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * wA:| multicast upper bound |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * / /
+ * \ options \
+ * / /
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define TIPC_CONN_MSG 0
+#define TIPC_MCAST_MSG 1
+#define TIPC_NAMED_MSG 2
+#define TIPC_DIRECT_MSG 3
+
+
#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */
#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */
#define LONG_H_SIZE 40 /* Named messages */
@@ -52,20 +93,26 @@
#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
-/*
- TIPC user data message header format, version 2
+struct tipc_msg {
+ __be32 hdr[15];
+};
- - Fundamental definitions available to privileged TIPC users
- are located in tipc_msg.h.
- - Remaining definitions available to TIPC internal users appear below.
-*/
+static inline u32 msg_word(struct tipc_msg *m, u32 pos)
+{
+ return ntohl(m->hdr[pos]);
+}
static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
{
m->hdr[w] = htonl(val);
}
+static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
+{
+ return (msg_word(m, w) >> pos) & mask;
+}
+
static inline void msg_set_bits(struct tipc_msg *m, u32 w,
u32 pos, u32 mask, u32 val)
{
@@ -112,16 +159,36 @@ static inline void msg_set_user(struct tipc_msg *m, u32 n)
msg_set_bits(m, 0, 25, 0xf, n);
}
+static inline u32 msg_importance(struct tipc_msg *m)
+{
+ return msg_bits(m, 0, 25, 0xf);
+}
+
static inline void msg_set_importance(struct tipc_msg *m, u32 i)
{
msg_set_user(m, i);
}
-static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n)
+static inline u32 msg_hdr_sz(struct tipc_msg *m)
+{
+ return msg_bits(m, 0, 21, 0xf) << 2;
+}
+
+static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n)
{
msg_set_bits(m, 0, 21, 0xf, n>>2);
}
+static inline u32 msg_size(struct tipc_msg *m)
+{
+ return msg_bits(m, 0, 0, 0x1ffff);
+}
+
+static inline u32 msg_data_sz(struct tipc_msg *m)
+{
+ return msg_size(m) - msg_hdr_sz(m);
+}
+
static inline int msg_non_seq(struct tipc_msg *m)
{
return msg_bits(m, 0, 20, 1);
@@ -162,11 +229,36 @@ static inline void msg_set_size(struct tipc_msg *m, u32 sz)
* Word 1
*/
+static inline u32 msg_type(struct tipc_msg *m)
+{
+ return msg_bits(m, 1, 29, 0x7);
+}
+
static inline void msg_set_type(struct tipc_msg *m, u32 n)
{
msg_set_bits(m, 1, 29, 0x7, n);
}
+static inline u32 msg_named(struct tipc_msg *m)
+{
+ return msg_type(m) == TIPC_NAMED_MSG;
+}
+
+static inline u32 msg_mcast(struct tipc_msg *m)
+{
+ return msg_type(m) == TIPC_MCAST_MSG;
+}
+
+static inline u32 msg_connected(struct tipc_msg *m)
+{
+ return msg_type(m) == TIPC_CONN_MSG;
+}
+
+static inline u32 msg_errcode(struct tipc_msg *m)
+{
+ return msg_bits(m, 1, 25, 0xf);
+}
+
static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
{
msg_set_bits(m, 1, 25, 0xf, err);
@@ -257,31 +349,68 @@ static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
*/
+static inline u32 msg_prevnode(struct tipc_msg *m)
+{
+ return msg_word(m, 3);
+}
+
static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
{
msg_set_word(m, 3, a);
}
+static inline u32 msg_origport(struct tipc_msg *m)
+{
+ return msg_word(m, 4);
+}
+
static inline void msg_set_origport(struct tipc_msg *m, u32 p)
{
msg_set_word(m, 4, p);
}
+static inline u32 msg_destport(struct tipc_msg *m)
+{
+ return msg_word(m, 5);
+}
+
static inline void msg_set_destport(struct tipc_msg *m, u32 p)
{
msg_set_word(m, 5, p);
}
+static inline u32 msg_mc_netid(struct tipc_msg *m)
+{
+ return msg_word(m, 5);
+}
+
static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
{
msg_set_word(m, 5, p);
}
+static inline int msg_short(struct tipc_msg *m)
+{
+ return msg_hdr_sz(m) == 24;
+}
+
+static inline u32 msg_orignode(struct tipc_msg *m)
+{
+ if (likely(msg_short(m)))
+ return msg_prevnode(m);
+ return msg_word(m, 6);
+}
+
static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
{
msg_set_word(m, 6, a);
}
+static inline u32 msg_destnode(struct tipc_msg *m)
+{
+ return msg_word(m, 7);
+}
+
static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
{
msg_set_word(m, 7, a);
@@ -296,7 +425,12 @@ static inline u32 msg_routed(struct tipc_msg *m)
{
if (likely(msg_short(m)))
return 0;
- return(msg_destnode(m) ^ msg_orignode(m)) >> 11;
+ return (msg_destnode(m) ^ msg_orignode(m)) >> 11;
+}
+
+static inline u32 msg_nametype(struct tipc_msg *m)
+{
+ return msg_word(m, 8);
}
static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
@@ -324,6 +458,16 @@ static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n)
msg_set_word(m, 8, n);
}
+static inline u32 msg_nameinst(struct tipc_msg *m)
+{
+ return msg_word(m, 9);
+}
+
+static inline u32 msg_namelower(struct tipc_msg *m)
+{
+ return msg_nameinst(m);
+}
+
static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
{
msg_set_word(m, 9, n);
@@ -334,11 +478,21 @@ static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
msg_set_namelower(m, n);
}
+static inline u32 msg_nameupper(struct tipc_msg *m)
+{
+ return msg_word(m, 10);
+}
+
static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
{
msg_set_word(m, 10, n);
}
+static inline unchar *msg_data(struct tipc_msg *m)
+{
+ return ((unchar *)m) + msg_hdr_sz(m);
+}
+
static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
{
return (struct tipc_msg *)msg_data(m);
@@ -386,7 +540,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
#define MSG_BUNDLER 6
#define LINK_PROTOCOL 7
#define CONN_MANAGER 8
-#define ROUTE_DISTRIBUTOR 9
+#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
#define CHANGEOVER_PROTOCOL 10
#define NAME_DISTRIBUTOR 11
#define MSG_FRAGMENTER 12
@@ -665,11 +819,6 @@ static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
msg_set_word(m, msg_hdr_sz(m)/4, a);
}
-static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
-{
- msg_data(m)[pos + 4] = 1;
-}
-
/*
* Segmentation message types
*/
@@ -696,7 +845,7 @@ static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
* Routing table message types
*/
#define EXT_ROUTING_TABLE 0
-#define LOCAL_ROUTING_TABLE 1
+#define LOCAL_ROUTING_TABLE 1 /* obsoleted */
#define SLAVE_ROUTING_TABLE 2
#define ROUTE_ADDITION 3
#define ROUTE_REMOVAL 4
@@ -714,7 +863,7 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect);
int tipc_msg_build(struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
- int max_size, int usrmem, struct sk_buff** buf);
+ int max_size, int usrmem, struct sk_buff **buf);
static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
{
@@ -723,7 +872,7 @@ static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr
static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
{
- memcpy(a, &((int*)m)[5], sizeof(*a));
+ memcpy(a, &((int *)m)[5], sizeof(*a));
}
#endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 7b907171f879..483c226c9581 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -35,10 +35,7 @@
*/
#include "core.h"
-#include "cluster.h"
-#include "dbg.h"
#include "link.h"
-#include "msg.h"
#include "name_distr.h"
#define ITEM_SIZE sizeof(struct distr_item)
@@ -76,7 +73,7 @@ struct distr_item {
*/
static LIST_HEAD(publ_root);
-static u32 publ_cnt = 0;
+static u32 publ_cnt;
/**
* publ_to_item - add publication info to a publication message
@@ -89,7 +86,6 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
i->upper = htonl(p->upper);
i->ref = htonl(p->ref);
i->key = htonl(p->key);
- dbg("publ_to_item: %u, %u, %u\n", p->type, p->lower, p->upper);
}
/**
@@ -109,6 +105,26 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
return buf;
}
+static void named_cluster_distribute(struct sk_buff *buf)
+{
+ struct sk_buff *buf_copy;
+ struct tipc_node *n_ptr;
+ u32 n_num;
+
+ for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
+ n_ptr = tipc_net.nodes[n_num];
+ if (n_ptr && tipc_node_has_active_links(n_ptr)) {
+ buf_copy = skb_copy(buf, GFP_ATOMIC);
+ if (!buf_copy)
+ break;
+ msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
+ tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
+ }
+ }
+
+ buf_discard(buf);
+}
+
/**
* tipc_named_publish - tell other nodes about a new publication by this node
*/
@@ -129,8 +145,7 @@ void tipc_named_publish(struct publication *publ)
item = (struct distr_item *)msg_data(buf_msg(buf));
publ_to_item(item, publ);
- dbg("tipc_named_withdraw: broadcasting publish msg\n");
- tipc_cltr_broadcast(buf);
+ named_cluster_distribute(buf);
}
/**
@@ -153,8 +168,7 @@ void tipc_named_withdraw(struct publication *publ)
item = (struct distr_item *)msg_data(buf_msg(buf));
publ_to_item(item, publ);
- dbg("tipc_named_withdraw: broadcasting withdraw msg\n");
- tipc_cltr_broadcast(buf);
+ named_cluster_distribute(buf);
}
/**
@@ -191,9 +205,6 @@ void tipc_named_node_up(unsigned long node)
left -= ITEM_SIZE;
if (!left) {
msg_set_link_selector(buf_msg(buf), node);
- dbg("tipc_named_node_up: sending publish msg to "
- "<%u.%u.%u>\n", tipc_zone(node),
- tipc_cluster(node), tipc_node(node));
tipc_link_send(buf, node, node);
buf = NULL;
}
@@ -218,8 +229,6 @@ static void node_is_down(struct publication *publ)
struct publication *p;
write_lock_bh(&tipc_nametbl_lock);
- dbg("node_is_down: withdrawing %u, %u, %u\n",
- publ->type, publ->lower, publ->upper);
publ->key += 1222345;
p = tipc_nametbl_remove_publ(publ->type, publ->lower,
publ->node, publ->ref, publ->key);
@@ -231,9 +240,7 @@ static void node_is_down(struct publication *publ)
publ->type, publ->lower, publ->node, publ->ref, publ->key);
}
- if (p) {
- kfree(p);
- }
+ kfree(p);
}
/**
@@ -250,9 +257,6 @@ void tipc_named_recv(struct sk_buff *buf)
write_lock_bh(&tipc_nametbl_lock);
while (count--) {
if (msg_type(msg) == PUBLICATION) {
- dbg("tipc_named_recv: got publication for %u, %u, %u\n",
- ntohl(item->type), ntohl(item->lower),
- ntohl(item->upper));
publ = tipc_nametbl_insert_publ(ntohl(item->type),
ntohl(item->lower),
ntohl(item->upper),
@@ -267,9 +271,6 @@ void tipc_named_recv(struct sk_buff *buf)
(net_ev_handler)node_is_down);
}
} else if (msg_type(msg) == WITHDRAWAL) {
- dbg("tipc_named_recv: got withdrawl for %u, %u, %u\n",
- ntohl(item->type), ntohl(item->lower),
- ntohl(item->upper));
publ = tipc_nametbl_remove_publ(ntohl(item->type),
ntohl(item->lower),
msg_orignode(msg),
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 3a8de4334da1..205ed4a4e186 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -36,15 +36,10 @@
#include "core.h"
#include "config.h"
-#include "dbg.h"
#include "name_table.h"
#include "name_distr.h"
-#include "addr.h"
-#include "node_subscr.h"
#include "subscr.h"
#include "port.h"
-#include "cluster.h"
-#include "bcast.h"
static int tipc_nametbl_size = 1024; /* must be a power of 2 */
@@ -109,7 +104,7 @@ struct name_table {
u32 local_publ_count;
};
-static struct name_table table = { NULL } ;
+static struct name_table table;
static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
DEFINE_RWLOCK(tipc_nametbl_lock);
@@ -177,8 +172,6 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea
spin_lock_init(&nseq->lock);
nseq->type = type;
nseq->sseqs = sseq;
- dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n",
- nseq, type, nseq->sseqs, nseq->first_free);
nseq->alloc = 1;
INIT_HLIST_NODE(&nseq->ns_list);
INIT_LIST_HEAD(&nseq->subscriptions);
@@ -256,8 +249,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
int created_subseq = 0;
sseq = nameseq_find_subseq(nseq, lower);
- dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n",
- nseq, type, lower, sseq);
if (sseq) {
/* Lower end overlaps existing entry => need an exact match */
@@ -294,38 +285,30 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
type, lower, upper);
return NULL;
}
- dbg("Allocated %u more sseqs\n", nseq->alloc);
memcpy(sseqs, nseq->sseqs,
nseq->alloc * sizeof(struct sub_seq));
kfree(nseq->sseqs);
nseq->sseqs = sseqs;
nseq->alloc *= 2;
}
- dbg("Have %u sseqs for type %u\n", nseq->alloc, type);
/* Insert new sub-sequence */
- dbg("ins in pos %u, ff = %u\n", inspos, nseq->first_free);
sseq = &nseq->sseqs[inspos];
freesseq = &nseq->sseqs[nseq->first_free];
- memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq));
- memset(sseq, 0, sizeof (*sseq));
+ memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq));
+ memset(sseq, 0, sizeof(*sseq));
nseq->first_free++;
sseq->lower = lower;
sseq->upper = upper;
created_subseq = 1;
}
- dbg("inserting {%u,%u,%u} from <0x%x:%u> into sseq %p(%u,%u) of seq %p\n",
- type, lower, upper, node, port, sseq,
- sseq->lower, sseq->upper, nseq);
/* Insert a publication: */
publ = publ_create(type, lower, upper, scope, node, port, key);
if (!publ)
return NULL;
- dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n",
- publ, node, publ->node, publ->subscr.node);
sseq->zone_list_size++;
if (!sseq->zone_list)
@@ -360,7 +343,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
* Any subscriptions waiting for notification?
*/
list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
- dbg("calling report_overlap()\n");
tipc_subscr_report_overlap(s,
publ->lower,
publ->upper,
@@ -398,9 +380,6 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
if (!sseq)
return NULL;
- dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n",
- nseq, sseq, nseq->type, inst, key);
-
/* Remove publication from zone scope list */
prev = sseq->zone_list;
@@ -492,7 +471,7 @@ end_node:
if (!sseq->zone_list) {
free = &nseq->sseqs[nseq->first_free--];
- memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq));
+ memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
removed_subseq = 1;
}
@@ -528,7 +507,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
while (sseq != &nseq->sseqs[nseq->first_free]) {
struct publication *zl = sseq->zone_list;
- if (zl && tipc_subscr_overlap(s,sseq->lower,sseq->upper)) {
+ if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
struct publication *crs = zl;
int must_report = 1;
@@ -554,15 +533,10 @@ static struct name_seq *nametbl_find_seq(u32 type)
struct hlist_node *seq_node;
struct name_seq *ns;
- dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n",
- type, htonl(type), type, table.types, hash(type));
-
seq_head = &table.types[hash(type)];
hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
- if (ns->type == type) {
- dbg("found %p\n", ns);
+ if (ns->type == type)
return ns;
- }
}
return NULL;
@@ -573,18 +547,14 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
{
struct name_seq *seq = nametbl_find_seq(type);
- dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq);
if (lower > upper) {
warn("Failed to publish illegal {%u,%u,%u}\n",
type, lower, upper);
return NULL;
}
- dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node);
- if (!seq) {
+ if (!seq)
seq = tipc_nameseq_create(type, &table.types[hash(type)]);
- dbg("tipc_nametbl_insert_publ: created %p\n", seq);
- }
if (!seq)
return NULL;
@@ -601,7 +571,6 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
if (!seq)
return NULL;
- dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node);
publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
if (!seq->first_free && list_empty(&seq->subscriptions)) {
@@ -782,9 +751,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
table.local_publ_count++;
publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
tipc_own_addr, port_ref, key);
- if (publ && (scope != TIPC_NODE_SCOPE)) {
+ if (publ && (scope != TIPC_NODE_SCOPE))
tipc_named_publish(publ);
- }
write_unlock_bh(&tipc_nametbl_lock);
return publ;
}
@@ -797,7 +765,6 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
{
struct publication *publ;
- dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key);
write_lock_bh(&tipc_nametbl_lock);
publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
if (likely(publ)) {
@@ -827,13 +794,10 @@ void tipc_nametbl_subscribe(struct subscription *s)
write_lock_bh(&tipc_nametbl_lock);
seq = nametbl_find_seq(type);
- if (!seq) {
+ if (!seq)
seq = tipc_nameseq_create(type, &table.types[hash(type)]);
- }
- if (seq){
+ if (seq) {
spin_lock_bh(&seq->lock);
- dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n",
- seq, type, s->seq.lower, s->seq.upper);
tipc_nameseq_subscribe(seq, s);
spin_unlock_bh(&seq->lock);
} else {
@@ -853,7 +817,7 @@ void tipc_nametbl_unsubscribe(struct subscription *s)
write_lock_bh(&tipc_nametbl_lock);
seq = nametbl_find_seq(s->seq.type);
- if (seq != NULL){
+ if (seq != NULL) {
spin_lock_bh(&seq->lock);
list_del_init(&s->nameseq_list);
spin_unlock_bh(&seq->lock);
@@ -886,7 +850,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
}
do {
- sprintf (portIdStr, "<%u.%u.%u:%u>",
+ sprintf(portIdStr, "<%u.%u.%u:%u>",
tipc_zone(publ->node), tipc_cluster(publ->node),
tipc_node(publ->node), publ->ref);
tipc_printf(buf, "%-26s ", portIdStr);
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 139882d4ed00..d228bd682655 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -46,7 +46,7 @@ struct port_list;
* TIPC name types reserved for internal TIPC use (both current and planned)
*/
-#define TIPC_ZM_SRV 3 /* zone master service name type */
+#define TIPC_ZM_SRV 3 /* zone master service name type */
/**
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 1a621cfd6604..9bacfd00b91e 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -35,18 +35,10 @@
*/
#include "core.h"
-#include "bearer.h"
#include "net.h"
-#include "zone.h"
-#include "addr.h"
-#include "name_table.h"
#include "name_distr.h"
#include "subscr.h"
-#include "link.h"
-#include "msg.h"
#include "port.h"
-#include "bcast.h"
-#include "discover.h"
#include "config.h"
/*
@@ -116,46 +108,25 @@
*/
DEFINE_RWLOCK(tipc_net_lock);
-static struct _zone *tipc_zones[256] = { NULL, };
-struct network tipc_net = { tipc_zones };
+struct network tipc_net;
-struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
+static int net_start(void)
{
- return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
-}
-
-u32 tipc_net_select_router(u32 addr, u32 ref)
-{
- return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
-}
-
-void tipc_net_remove_as_router(u32 router)
-{
- u32 z_num;
-
- for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
- if (!tipc_net.zones[z_num])
- continue;
- tipc_zone_remove_as_router(tipc_net.zones[z_num], router);
- }
-}
-
-void tipc_net_send_external_routes(u32 dest)
-{
- u32 z_num;
+ tipc_net.nodes = kcalloc(tipc_max_nodes + 1,
+ sizeof(*tipc_net.nodes), GFP_ATOMIC);
+ tipc_net.highest_node = 0;
- for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
- if (tipc_net.zones[z_num])
- tipc_zone_send_external_routes(tipc_net.zones[z_num], dest);
- }
+ return tipc_net.nodes ? 0 : -ENOMEM;
}
static void net_stop(void)
{
- u32 z_num;
+ u32 n_num;
- for (z_num = 1; z_num <= tipc_max_zones; z_num++)
- tipc_zone_delete(tipc_net.zones[z_num]);
+ for (n_num = 1; n_num <= tipc_net.highest_node; n_num++)
+ tipc_node_delete(tipc_net.nodes[n_num]);
+ kfree(tipc_net.nodes);
+ tipc_net.nodes = NULL;
}
static void net_route_named_msg(struct sk_buff *buf)
@@ -165,22 +136,18 @@ static void net_route_named_msg(struct sk_buff *buf)
u32 dport;
if (!msg_named(msg)) {
- msg_dbg(msg, "tipc_net->drop_nam:");
buf_discard(buf);
return;
}
dnode = addr_domain(msg_lookup_scope(msg));
dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
- dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n",
- msg_nametype(msg), msg_nameinst(msg), dport, dnode);
if (dport) {
msg_set_destnode(msg, dnode);
msg_set_destport(msg, dport);
tipc_net_route_msg(buf);
return;
}
- msg_dbg(msg, "tipc_net->rej:NO NAME: ");
tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
}
@@ -196,18 +163,14 @@ void tipc_net_route_msg(struct sk_buff *buf)
msg_incr_reroute_cnt(msg);
if (msg_reroute_cnt(msg) > 6) {
if (msg_errcode(msg)) {
- msg_dbg(msg, "NET>DISC>:");
buf_discard(buf);
} else {
- msg_dbg(msg, "NET>REJ>:");
tipc_reject_msg(buf, msg_destport(msg) ?
TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);
}
return;
}
- msg_dbg(msg, "tipc_net->rout: ");
-
/* Handle message for this node */
dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
if (tipc_in_scope(dnode, tipc_own_addr)) {
@@ -221,9 +184,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
return;
}
switch (msg_user(msg)) {
- case ROUTE_DISTRIBUTOR:
- tipc_cltr_recv_routing_table(buf);
- break;
case NAME_DISTRIBUTOR:
tipc_named_recv(buf);
break;
@@ -231,14 +191,12 @@ void tipc_net_route_msg(struct sk_buff *buf)
tipc_port_recv_proto_msg(buf);
break;
default:
- msg_dbg(msg,"DROP/NET/<REC<");
buf_discard(buf);
}
return;
}
/* Handle message for another node */
- msg_dbg(msg, "NET>SEND>: ");
skb_trim(buf, msg_size(msg));
tipc_link_send(buf, dnode, msg_link_selector(msg));
}
@@ -259,10 +217,12 @@ int tipc_net_start(u32 addr)
tipc_named_reinit();
tipc_port_reinit();
- if ((res = tipc_cltr_init()) ||
- (res = tipc_bclink_init())) {
+ res = net_start();
+ if (res)
+ return res;
+ res = tipc_bclink_init();
+ if (res)
return res;
- }
tipc_k_signal((Handler)tipc_subscr_start, 0);
tipc_k_signal((Handler)tipc_cfg_init, 0);
diff --git a/net/tipc/net.h b/net/tipc/net.h
index de2b9ad8f646..4ae59ad04893 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -37,26 +37,26 @@
#ifndef _TIPC_NET_H
#define _TIPC_NET_H
-struct _zone;
+struct tipc_node;
/**
* struct network - TIPC network structure
- * @zones: array of pointers to all zones within network
+ * @nodes: array of pointers to all nodes within cluster
+ * @highest_node: id of highest numbered node within cluster
+ * @links: number of (unicast) links to cluster
*/
struct network {
- struct _zone **zones;
+ struct tipc_node **nodes;
+ u32 highest_node;
+ u32 links;
};
extern struct network tipc_net;
extern rwlock_t tipc_net_lock;
-void tipc_net_remove_as_router(u32 router);
-void tipc_net_send_external_routes(u32 dest);
void tipc_net_route_msg(struct sk_buff *buf);
-struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
-u32 tipc_net_select_router(u32 addr, u32 ref);
int tipc_net_start(u32 addr);
void tipc_net_stop(void);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b4d87eb2dc5d..3af53e327f49 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -37,25 +37,14 @@
#include "core.h"
#include "config.h"
#include "node.h"
-#include "cluster.h"
-#include "net.h"
-#include "addr.h"
-#include "node_subscr.h"
-#include "link.h"
-#include "port.h"
-#include "bearer.h"
#include "name_distr.h"
-void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
static void node_lost_contact(struct tipc_node *n_ptr);
static void node_established_contact(struct tipc_node *n_ptr);
-/* sorted list of nodes within cluster */
-static struct tipc_node *tipc_nodes = NULL;
-
static DEFINE_SPINLOCK(node_create_lock);
-u32 tipc_own_tag = 0;
+u32 tipc_own_tag;
/**
* tipc_node_create - create neighboring node
@@ -69,65 +58,51 @@ u32 tipc_own_tag = 0;
struct tipc_node *tipc_node_create(u32 addr)
{
- struct cluster *c_ptr;
struct tipc_node *n_ptr;
- struct tipc_node **curr_node;
+ u32 n_num;
spin_lock_bh(&node_create_lock);
- for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
- if (addr < n_ptr->addr)
- break;
- if (addr == n_ptr->addr) {
- spin_unlock_bh(&node_create_lock);
- return n_ptr;
- }
+ n_ptr = tipc_node_find(addr);
+ if (n_ptr) {
+ spin_unlock_bh(&node_create_lock);
+ return n_ptr;
}
- n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC);
+ n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
if (!n_ptr) {
spin_unlock_bh(&node_create_lock);
warn("Node creation failed, no memory\n");
return NULL;
}
- c_ptr = tipc_cltr_find(addr);
- if (!c_ptr) {
- c_ptr = tipc_cltr_create(addr);
- }
- if (!c_ptr) {
- spin_unlock_bh(&node_create_lock);
- kfree(n_ptr);
- return NULL;
- }
-
n_ptr->addr = addr;
- spin_lock_init(&n_ptr->lock);
+ spin_lock_init(&n_ptr->lock);
INIT_LIST_HEAD(&n_ptr->nsub);
- n_ptr->owner = c_ptr;
- tipc_cltr_attach_node(c_ptr, n_ptr);
- n_ptr->last_router = -1;
-
- /* Insert node into ordered list */
- for (curr_node = &tipc_nodes; *curr_node;
- curr_node = &(*curr_node)->next) {
- if (addr < (*curr_node)->addr) {
- n_ptr->next = *curr_node;
- break;
- }
- }
- (*curr_node) = n_ptr;
+
+ n_num = tipc_node(addr);
+ tipc_net.nodes[n_num] = n_ptr;
+ if (n_num > tipc_net.highest_node)
+ tipc_net.highest_node = n_num;
+
spin_unlock_bh(&node_create_lock);
return n_ptr;
}
void tipc_node_delete(struct tipc_node *n_ptr)
{
+ u32 n_num;
+
if (!n_ptr)
return;
- dbg("node %x deleted\n", n_ptr->addr);
+ n_num = tipc_node(n_ptr->addr);
+ tipc_net.nodes[n_num] = NULL;
kfree(n_ptr);
+
+ while (!tipc_net.nodes[tipc_net.highest_node])
+ if (--tipc_net.highest_node == 0)
+ break;
}
@@ -147,7 +122,6 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr)
l_ptr->name, l_ptr->b_ptr->net_plane);
if (!active[0]) {
- dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]);
active[0] = active[1] = l_ptr;
node_established_contact(n_ptr);
return;
@@ -236,14 +210,9 @@ int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
return n_ptr->working_links > 1;
}
-static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
-{
- return n_ptr && (n_ptr->last_router >= 0);
-}
-
int tipc_node_is_up(struct tipc_node *n_ptr)
{
- return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr);
+ return tipc_node_has_active_links(n_ptr);
}
struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
@@ -264,7 +233,7 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
if (!n_ptr->links[bearer_id]) {
n_ptr->links[bearer_id] = l_ptr;
- tipc_net.zones[tipc_zone(l_ptr->addr)]->links++;
+ tipc_net.links++;
n_ptr->link_cnt++;
return n_ptr;
}
@@ -278,7 +247,7 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
{
n_ptr->links[l_ptr->b_ptr->identity] = NULL;
- tipc_net.zones[tipc_zone(l_ptr->addr)]->links--;
+ tipc_net.links--;
n_ptr->link_cnt--;
}
@@ -330,48 +299,16 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
static void node_established_contact(struct tipc_node *n_ptr)
{
- struct cluster *c_ptr;
-
- dbg("node_established_contact:-> %x\n", n_ptr->addr);
- if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) {
- tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
- }
+ tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
/* Syncronize broadcast acks */
n_ptr->bclink.acked = tipc_bclink_get_last_sent();
- if (is_slave(tipc_own_addr))
- return;
- if (!in_own_cluster(n_ptr->addr)) {
- /* Usage case 1 (see above) */
- c_ptr = tipc_cltr_find(tipc_own_addr);
- if (!c_ptr)
- c_ptr = tipc_cltr_create(tipc_own_addr);
- if (c_ptr)
- tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1,
- tipc_max_nodes);
- return;
- }
-
- c_ptr = n_ptr->owner;
- if (is_slave(n_ptr->addr)) {
- /* Usage case 2 (see above) */
- tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes);
- tipc_cltr_send_local_routes(c_ptr, n_ptr->addr);
- return;
- }
-
if (n_ptr->bclink.supported) {
- tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr);
+ tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr);
if (n_ptr->addr < tipc_own_addr)
tipc_own_tag++;
}
-
- /* Case 3 (see above) */
- tipc_net_send_external_routes(n_ptr->addr);
- tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr);
- tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE,
- tipc_highest_allowed_slave);
}
static void node_cleanup_finished(unsigned long node_addr)
@@ -390,7 +327,6 @@ static void node_cleanup_finished(unsigned long node_addr)
static void node_lost_contact(struct tipc_node *n_ptr)
{
- struct cluster *c_ptr;
struct tipc_node_subscr *ns, *tns;
char addr_string[16];
u32 i;
@@ -398,7 +334,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
/* Clean up broadcast reception remains */
n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
while (n_ptr->bclink.deferred_head) {
- struct sk_buff* buf = n_ptr->bclink.deferred_head;
+ struct sk_buff *buf = n_ptr->bclink.deferred_head;
n_ptr->bclink.deferred_head = buf->next;
buf_discard(buf);
}
@@ -406,41 +342,14 @@ static void node_lost_contact(struct tipc_node *n_ptr)
buf_discard(n_ptr->bclink.defragm);
n_ptr->bclink.defragm = NULL;
}
- if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) {
- tipc_bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000));
- }
- /* Update routing tables */
- if (is_slave(tipc_own_addr)) {
- tipc_net_remove_as_router(n_ptr->addr);
- } else {
- if (!in_own_cluster(n_ptr->addr)) {
- /* Case 4 (see above) */
- c_ptr = tipc_cltr_find(tipc_own_addr);
- tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
- tipc_max_nodes);
- } else {
- /* Case 5 (see above) */
- c_ptr = tipc_cltr_find(n_ptr->addr);
- if (is_slave(n_ptr->addr)) {
- tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
- tipc_max_nodes);
- } else {
- if (n_ptr->bclink.supported) {
- tipc_nmap_remove(&tipc_cltr_bcast_nodes,
- n_ptr->addr);
- if (n_ptr->addr < tipc_own_addr)
- tipc_own_tag--;
- }
- tipc_net_remove_as_router(n_ptr->addr);
- tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr,
- LOWEST_SLAVE,
- tipc_highest_allowed_slave);
- }
- }
+ if (n_ptr->bclink.supported) {
+ tipc_bclink_acknowledge(n_ptr,
+ mod(n_ptr->bclink.acked + 10000));
+ tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
+ if (n_ptr->addr < tipc_own_addr)
+ tipc_own_tag--;
}
- if (tipc_node_has_active_routes(n_ptr))
- return;
info("Lost contact with %s\n",
tipc_addr_string_fill(addr_string, n_ptr->addr));
@@ -469,125 +378,6 @@ static void node_lost_contact(struct tipc_node *n_ptr)
tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
}
-/**
- * tipc_node_select_next_hop - find the next-hop node for a message
- *
- * Called by when cluster local lookup has failed.
- */
-
-struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
-{
- struct tipc_node *n_ptr;
- u32 router_addr;
-
- if (!tipc_addr_domain_valid(addr))
- return NULL;
-
- /* Look for direct link to destination processsor */
- n_ptr = tipc_node_find(addr);
- if (n_ptr && tipc_node_has_active_links(n_ptr))
- return n_ptr;
-
- /* Cluster local system nodes *must* have direct links */
- if (!is_slave(addr) && in_own_cluster(addr))
- return NULL;
-
- /* Look for cluster local router with direct link to node */
- router_addr = tipc_node_select_router(n_ptr, selector);
- if (router_addr)
- return tipc_node_select(router_addr, selector);
-
- /* Slave nodes can only be accessed within own cluster via a
- known router with direct link -- if no router was found,give up */
- if (is_slave(addr))
- return NULL;
-
- /* Inter zone/cluster -- find any direct link to remote cluster */
- addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
- n_ptr = tipc_net_select_remote_node(addr, selector);
- if (n_ptr && tipc_node_has_active_links(n_ptr))
- return n_ptr;
-
- /* Last resort -- look for any router to anywhere in remote zone */
- router_addr = tipc_net_select_router(addr, selector);
- if (router_addr)
- return tipc_node_select(router_addr, selector);
-
- return NULL;
-}
-
-/**
- * tipc_node_select_router - select router to reach specified node
- *
- * Uses a deterministic and fair algorithm for selecting router node.
- */
-
-u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
-{
- u32 ulim;
- u32 mask;
- u32 start;
- u32 r;
-
- if (!n_ptr)
- return 0;
-
- if (n_ptr->last_router < 0)
- return 0;
- ulim = ((n_ptr->last_router + 1) * 32) - 1;
-
- /* Start entry must be random */
- mask = tipc_max_nodes;
- while (mask > ulim)
- mask >>= 1;
- start = ref & mask;
- r = start;
-
- /* Lookup upwards with wrap-around */
- do {
- if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
- break;
- } while (++r <= ulim);
- if (r > ulim) {
- r = 1;
- do {
- if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
- break;
- } while (++r < start);
- assert(r != start);
- }
- assert(r && (r <= ulim));
- return tipc_addr(own_zone(), own_cluster(), r);
-}
-
-void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
-{
- u32 r_num = tipc_node(router);
-
- n_ptr->routers[r_num / 32] =
- ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]);
- n_ptr->last_router = tipc_max_nodes / 32;
- while ((--n_ptr->last_router >= 0) &&
- !n_ptr->routers[n_ptr->last_router]);
-}
-
-void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
-{
- u32 r_num = tipc_node(router);
-
- if (n_ptr->last_router < 0)
- return; /* No routes */
-
- n_ptr->routers[r_num / 32] =
- ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32]));
- n_ptr->last_router = tipc_max_nodes / 32;
- while ((--n_ptr->last_router >= 0) &&
- !n_ptr->routers[n_ptr->last_router]);
-
- if (!tipc_node_is_up(n_ptr))
- node_lost_contact(n_ptr);
-}
-
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
{
u32 domain;
@@ -595,6 +385,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
struct tipc_node *n_ptr;
struct tipc_node_info node_info;
u32 payload_size;
+ u32 n_num;
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -605,15 +396,15 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
" (network address)");
read_lock_bh(&tipc_net_lock);
- if (!tipc_nodes) {
+ if (!tipc_net.nodes) {
read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_none();
}
- /* For now, get space for all other nodes
- (will need to modify this when slave nodes are supported */
+ /* For now, get space for all other nodes */
- payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1);
+ payload_size = TLV_SPACE(sizeof(node_info)) *
+ (tipc_net.highest_node - 1);
if (payload_size > 32768u) {
read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -627,8 +418,9 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
/* Add TLVs for all nodes in scope */
- for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
- if (!tipc_in_scope(domain, n_ptr->addr))
+ for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
+ n_ptr = tipc_net.nodes[n_num];
+ if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
continue;
node_info.addr = htonl(n_ptr->addr);
node_info.up = htonl(tipc_node_is_up(n_ptr));
@@ -647,6 +439,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
struct tipc_node *n_ptr;
struct tipc_link_info link_info;
u32 payload_size;
+ u32 n_num;
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -663,8 +456,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
/* Get space for all unicast links + multicast link */
- payload_size = TLV_SPACE(sizeof(link_info)) *
- (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
+ payload_size = TLV_SPACE(sizeof(link_info)) * (tipc_net.links + 1);
if (payload_size > 32768u) {
read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -685,10 +477,11 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
/* Add TLVs for any other links in scope */
- for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
+ for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
u32 i;
- if (!tipc_in_scope(domain, n_ptr->addr))
+ n_ptr = tipc_net.nodes[n_num];
+ if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
continue;
tipc_node_lock(n_ptr);
for (i = 0; i < MAX_BEARERS; i++) {
diff --git a/net/tipc/node.h b/net/tipc/node.h
index fff331b2d26c..206a8efa410e 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -39,14 +39,13 @@
#include "node_subscr.h"
#include "addr.h"
-#include "cluster.h"
+#include "net.h"
#include "bearer.h"
/**
* struct tipc_node - TIPC node structure
* @addr: network address of node
* @lock: spinlock governing access to structure
- * @owner: pointer to cluster that node belongs to
* @next: pointer to next node in sorted list of cluster's nodes
* @nsub: list of "node down" subscriptions monitoring node
* @active_links: pointers to active links to node
@@ -55,8 +54,6 @@
* @cleanup_required: non-zero if cleaning up after a prior loss of contact
* @link_cnt: number of links to node
* @permit_changeover: non-zero if node has redundant links to this system
- * @routers: bitmap (used for multicluster communication)
- * @last_router: (used for multicluster communication)
* @bclink: broadcast-related info
* @supported: non-zero if node supports TIPC b'cast capability
* @acked: sequence # of last outbound b'cast message acknowledged by node
@@ -72,7 +69,6 @@
struct tipc_node {
u32 addr;
spinlock_t lock;
- struct cluster *owner;
struct tipc_node *next;
struct list_head nsub;
struct link *active_links[2];
@@ -81,8 +77,6 @@ struct tipc_node {
int working_links;
int cleanup_required;
int permit_changeover;
- u32 routers[512/32];
- int last_router;
struct {
int supported;
u32 acked;
@@ -106,34 +100,17 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
int tipc_node_has_active_links(struct tipc_node *n_ptr);
int tipc_node_has_redundant_links(struct tipc_node *n_ptr);
-u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
-struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
int tipc_node_is_up(struct tipc_node *n_ptr);
-void tipc_node_add_router(struct tipc_node *n_ptr, u32 router);
-void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router);
struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
static inline struct tipc_node *tipc_node_find(u32 addr)
{
if (likely(in_own_cluster(addr)))
- return tipc_local_nodes[tipc_node(addr)];
- else if (tipc_addr_domain_valid(addr)) {
- struct cluster *c_ptr = tipc_cltr_find(addr);
-
- if (c_ptr)
- return c_ptr->nodes[tipc_node(addr)];
- }
+ return tipc_net.nodes[tipc_node(addr)];
return NULL;
}
-static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector)
-{
- if (likely(in_own_cluster(addr)))
- return tipc_local_nodes[tipc_node(addr)];
- return tipc_node_select_next_hop(addr, selector);
-}
-
static inline void tipc_node_lock(struct tipc_node *n_ptr)
{
spin_lock_bh(&n_ptr->lock);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 19194d476a9e..018a55332d91 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -35,10 +35,8 @@
*/
#include "core.h"
-#include "dbg.h"
#include "node_subscr.h"
#include "node.h"
-#include "addr.h"
/**
* tipc_nodesub_subscribe - create "node down" subscription for specified node
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 82092eaa1536..067bab2a0b98 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -36,15 +36,8 @@
#include "core.h"
#include "config.h"
-#include "dbg.h"
#include "port.h"
-#include "addr.h"
-#include "link.h"
-#include "node.h"
#include "name_table.h"
-#include "user_reg.h"
-#include "msg.h"
-#include "bcast.h"
/* Connection management: */
#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
@@ -53,16 +46,16 @@
#define MAX_REJECT_SIZE 1024
-static struct sk_buff *msg_queue_head = NULL;
-static struct sk_buff *msg_queue_tail = NULL;
+static struct sk_buff *msg_queue_head;
+static struct sk_buff *msg_queue_tail;
DEFINE_SPINLOCK(tipc_port_list_lock);
static DEFINE_SPINLOCK(queue_lock);
static LIST_HEAD(ports);
static void port_handle_node_down(unsigned long ref);
-static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err);
-static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err);
+static struct sk_buff *port_build_self_abort_msg(struct port *, u32 err);
+static struct sk_buff *port_build_peer_abort_msg(struct port *, u32 err);
static void port_timeout(unsigned long ref);
@@ -94,7 +87,7 @@ static void port_incr_out_seqno(struct port *p_ptr)
* tipc_multicast - send a multicast message to local and remote destinations
*/
-int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
+int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
u32 num_sect, struct iovec const *msg_sect)
{
struct tipc_msg *hdr;
@@ -138,9 +131,8 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
}
}
res = tipc_bclink_send_msg(buf);
- if ((res < 0) && (dports.count != 0)) {
+ if ((res < 0) && (dports.count != 0))
buf_discard(ibuf);
- }
} else {
ibuf = buf;
}
@@ -162,7 +154,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
{
- struct tipc_msg* msg;
+ struct tipc_msg *msg;
struct port_list dports = {0, NULL, };
struct port_list *item = dp;
int cnt = 0;
@@ -195,13 +187,11 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
if (b == NULL) {
warn("Unable to deliver multicast message(s)\n");
- msg_dbg(msg, "LOST:");
goto exit;
}
- if ((index == 0) && (cnt != 0)) {
+ if ((index == 0) && (cnt != 0))
item = item->next;
- }
- msg_set_destport(buf_msg(b),item->ports[index]);
+ msg_set_destport(buf_msg(b), item->ports[index]);
tipc_port_recv_msg(b);
}
}
@@ -277,10 +267,7 @@ int tipc_deleteport(u32 ref)
buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
tipc_nodesub_unsubscribe(&p_ptr->subscription);
}
- if (p_ptr->user_port) {
- tipc_reg_remove_port(p_ptr->user_port);
- kfree(p_ptr->user_port);
- }
+ kfree(p_ptr->user_port);
spin_lock_bh(&tipc_port_list_lock);
list_del(&p_ptr->port_list);
@@ -288,7 +275,6 @@ int tipc_deleteport(u32 ref)
spin_unlock_bh(&tipc_port_list_lock);
k_term_timer(&p_ptr->timer);
kfree(p_ptr);
- dbg("Deleted port %u\n", ref);
tipc_net_route_msg(buf);
return 0;
}
@@ -374,7 +360,6 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
msg_set_orignode(msg, orignode);
msg_set_transp_seqno(msg, seqno);
msg_set_msgcnt(msg, ack);
- msg_dbg(msg, "PORT>SEND>:");
}
return buf;
}
@@ -392,7 +377,6 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
data_sz = MAX_REJECT_SIZE;
if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
imp++;
- msg_dbg(msg, "port->rej: ");
/* discard rejected message if it shouldn't be returned to sender */
if (msg_errcode(msg) || msg_dest_droppable(msg)) {
@@ -498,7 +482,7 @@ static void port_timeout(unsigned long ref)
static void port_handle_node_down(unsigned long ref)
{
struct port *p_ptr = tipc_port_lock(ref);
- struct sk_buff* buf = NULL;
+ struct sk_buff *buf = NULL;
if (!p_ptr)
return;
@@ -555,8 +539,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
struct sk_buff *r_buf = NULL;
struct sk_buff *abort_buf = NULL;
- msg_dbg(msg, "PORT<RECV<:");
-
if (!p_ptr) {
err = TIPC_ERR_NO_PORT;
} else if (p_ptr->publ.connected) {
@@ -636,8 +618,7 @@ static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id)
tipc_printf(buf, " via {%u,%u}",
p_ptr->publ.conn_type,
p_ptr->publ.conn_instance);
- }
- else if (p_ptr->publ.published) {
+ } else if (p_ptr->publ.published) {
tipc_printf(buf, " bound to");
list_for_each_entry(publ, &p_ptr->publications, pport_list) {
if (publ->lower == publ->upper)
@@ -940,12 +921,10 @@ void tipc_acknowledge(u32 ref, u32 ack)
}
/*
- * tipc_createport(): user level call. Will add port to
- * registry if non-zero user_ref.
+ * tipc_createport(): user level call.
*/
-int tipc_createport(u32 user_ref,
- void *usr_handle,
+int tipc_createport(void *usr_handle,
unsigned int importance,
tipc_msg_err_event error_cb,
tipc_named_msg_err_event named_error_cb,
@@ -972,7 +951,6 @@ int tipc_createport(u32 user_ref,
}
p_ptr->user_port = up_ptr;
- up_ptr->user_ref = user_ref;
up_ptr->usr_handle = usr_handle;
up_ptr->ref = p_ptr->publ.ref;
up_ptr->err_cb = error_cb;
@@ -982,20 +960,11 @@ int tipc_createport(u32 user_ref,
up_ptr->named_msg_cb = named_msg_cb;
up_ptr->conn_msg_cb = conn_msg_cb;
up_ptr->continue_event_cb = continue_event_cb;
- INIT_LIST_HEAD(&up_ptr->uport_list);
- tipc_reg_add_port(up_ptr);
*portref = p_ptr->publ.ref;
tipc_port_unlock(p_ptr);
return 0;
}
-int tipc_ownidentity(u32 ref, struct tipc_portid *id)
-{
- id->ref = ref;
- id->node = tipc_own_addr;
- return 0;
-}
-
int tipc_portimportance(u32 ref, unsigned int *importance)
{
struct port *p_ptr;
@@ -1035,9 +1004,6 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
if (!p_ptr)
return -EINVAL;
- dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
- "lower = %u, upper = %u\n",
- ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
if (p_ptr->publ.connected)
goto exit;
if (seq->lower > seq->upper)
@@ -1123,17 +1089,14 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
msg_set_origport(msg, p_ptr->publ.ref);
msg_set_transp_seqno(msg, 42);
msg_set_type(msg, TIPC_CONN_MSG);
- if (!may_route(peer->node))
- msg_set_hdr_sz(msg, SHORT_H_SIZE);
- else
- msg_set_hdr_sz(msg, LONG_H_SIZE);
+ msg_set_hdr_sz(msg, SHORT_H_SIZE);
p_ptr->probing_interval = PROBING_INTERVAL;
p_ptr->probing_state = CONFIRMED;
p_ptr->publ.connected = 1;
k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
- tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,
+ tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
(void *)(unsigned long)ref,
(net_ev_handler)port_handle_node_down);
res = 0;
@@ -1271,16 +1234,11 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
}
/**
- * tipc_forward2name - forward message sections to port name
+ * tipc_send2name - send message sections to port name
*/
-static int tipc_forward2name(u32 ref,
- struct tipc_name const *name,
- u32 domain,
- u32 num_sect,
- struct iovec const *msg_sect,
- struct tipc_portid const *orig,
- unsigned int importance)
+int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
+ unsigned int num_sect, struct iovec const *msg_sect)
{
struct port *p_ptr;
struct tipc_msg *msg;
@@ -1294,14 +1252,12 @@ static int tipc_forward2name(u32 ref,
msg = &p_ptr->publ.phdr;
msg_set_type(msg, TIPC_NAMED_MSG);
- msg_set_orignode(msg, orig->node);
- msg_set_origport(msg, orig->ref);
+ msg_set_orignode(msg, tipc_own_addr);
+ msg_set_origport(msg, ref);
msg_set_hdr_sz(msg, LONG_H_SIZE);
msg_set_nametype(msg, name->type);
msg_set_nameinst(msg, name->instance);
msg_set_lookup_scope(msg, tipc_addr_scope(domain));
- if (importance <= TIPC_CRITICAL_IMPORTANCE)
- msg_set_importance(msg,importance);
destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
msg_set_destnode(msg, destnode);
msg_set_destport(msg, destport);
@@ -1325,33 +1281,11 @@ static int tipc_forward2name(u32 ref,
}
/**
- * tipc_send2name - send message sections to port name
- */
-
-int tipc_send2name(u32 ref,
- struct tipc_name const *name,
- unsigned int domain,
- unsigned int num_sect,
- struct iovec const *msg_sect)
-{
- struct tipc_portid orig;
-
- orig.ref = ref;
- orig.node = tipc_own_addr;
- return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig,
- TIPC_PORT_IMPORTANCE);
-}
-
-/**
- * tipc_forward2port - forward message sections to port identity
+ * tipc_send2port - send message sections to port identity
*/
-static int tipc_forward2port(u32 ref,
- struct tipc_portid const *dest,
- unsigned int num_sect,
- struct iovec const *msg_sect,
- struct tipc_portid const *orig,
- unsigned int importance)
+int tipc_send2port(u32 ref, struct tipc_portid const *dest,
+ unsigned int num_sect, struct iovec const *msg_sect)
{
struct port *p_ptr;
struct tipc_msg *msg;
@@ -1363,13 +1297,11 @@ static int tipc_forward2port(u32 ref,
msg = &p_ptr->publ.phdr;
msg_set_type(msg, TIPC_DIRECT_MSG);
- msg_set_orignode(msg, orig->node);
- msg_set_origport(msg, orig->ref);
+ msg_set_orignode(msg, tipc_own_addr);
+ msg_set_origport(msg, ref);
msg_set_destnode(msg, dest->node);
msg_set_destport(msg, dest->ref);
msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
- if (importance <= TIPC_CRITICAL_IMPORTANCE)
- msg_set_importance(msg, importance);
p_ptr->sent++;
if (dest->node == tipc_own_addr)
return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
@@ -1384,31 +1316,11 @@ static int tipc_forward2port(u32 ref,
}
/**
- * tipc_send2port - send message sections to port identity
+ * tipc_send_buf2port - send message buffer to port identity
*/
-int tipc_send2port(u32 ref,
- struct tipc_portid const *dest,
- unsigned int num_sect,
- struct iovec const *msg_sect)
-{
- struct tipc_portid orig;
-
- orig.ref = ref;
- orig.node = tipc_own_addr;
- return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig,
- TIPC_PORT_IMPORTANCE);
-}
-
-/**
- * tipc_forward_buf2port - forward message buffer to port identity
- */
-static int tipc_forward_buf2port(u32 ref,
- struct tipc_portid const *dest,
- struct sk_buff *buf,
- unsigned int dsz,
- struct tipc_portid const *orig,
- unsigned int importance)
+int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
+ struct sk_buff *buf, unsigned int dsz)
{
struct port *p_ptr;
struct tipc_msg *msg;
@@ -1420,20 +1332,17 @@ static int tipc_forward_buf2port(u32 ref,
msg = &p_ptr->publ.phdr;
msg_set_type(msg, TIPC_DIRECT_MSG);
- msg_set_orignode(msg, orig->node);
- msg_set_origport(msg, orig->ref);
+ msg_set_orignode(msg, tipc_own_addr);
+ msg_set_origport(msg, ref);
msg_set_destnode(msg, dest->node);
msg_set_destport(msg, dest->ref);
msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
- if (importance <= TIPC_CRITICAL_IMPORTANCE)
- msg_set_importance(msg, importance);
msg_set_size(msg, DIR_MSG_H_SIZE + dsz);
if (skb_cow(buf, DIR_MSG_H_SIZE))
return -ENOMEM;
skb_push(buf, DIR_MSG_H_SIZE);
skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
- msg_dbg(msg, "buf2port: ");
p_ptr->sent++;
if (dest->node == tipc_own_addr)
return tipc_port_recv_msg(buf);
@@ -1445,20 +1354,3 @@ static int tipc_forward_buf2port(u32 ref,
return -ELINKCONG;
}
-/**
- * tipc_send_buf2port - send message buffer to port identity
- */
-
-int tipc_send_buf2port(u32 ref,
- struct tipc_portid const *dest,
- struct sk_buff *buf,
- unsigned int dsz)
-{
- struct tipc_portid orig;
-
- orig.ref = ref;
- orig.node = tipc_own_addr;
- return tipc_forward_buf2port(ref, dest, buf, dsz, &orig,
- TIPC_PORT_IMPORTANCE);
-}
-
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 73bbf442b346..8e84b989949c 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -37,24 +37,52 @@
#ifndef _TIPC_PORT_H
#define _TIPC_PORT_H
-#include "core.h"
#include "ref.h"
#include "net.h"
#include "msg.h"
-#include "dbg.h"
#include "node_subscr.h"
+#define TIPC_FLOW_CONTROL_WIN 512
+
+typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size, int reason,
+ struct tipc_portid const *attmpt_destid);
+
+typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size, int reason,
+ struct tipc_name_seq const *attmpt_dest);
+
+typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size, int reason);
+
+typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size, unsigned int importance,
+ struct tipc_portid const *origin);
+
+typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size, unsigned int importance,
+ struct tipc_portid const *orig,
+ struct tipc_name_seq const *dest);
+
+typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
+ struct sk_buff **buf, unsigned char const *data,
+ unsigned int size);
+
+typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
+
/**
* struct user_port - TIPC user port (used with native API)
- * @user_ref: id of user who created user port
* @usr_handle: user-specified field
* @ref: object reference to associated TIPC port
* <various callback routines>
- * @uport_list: adjacent user ports in list of ports held by user
*/
struct user_port {
- u32 user_ref;
void *usr_handle;
u32 ref;
tipc_msg_err_event err_cb;
@@ -64,7 +92,34 @@ struct user_port {
tipc_named_msg_event named_msg_cb;
tipc_conn_msg_event conn_msg_cb;
tipc_continue_event continue_event_cb;
- struct list_head uport_list;
+};
+
+/**
+ * struct tipc_port - TIPC port info available to socket API
+ * @usr_handle: pointer to additional user-defined information about port
+ * @lock: pointer to spinlock for controlling access to port
+ * @connected: non-zero if port is currently connected to a peer port
+ * @conn_type: TIPC type used when connection was established
+ * @conn_instance: TIPC instance used when connection was established
+ * @conn_unacked: number of unacknowledged messages received from peer port
+ * @published: non-zero if port has one or more associated names
+ * @congested: non-zero if cannot send because of link or port congestion
+ * @max_pkt: maximum packet size "hint" used when building messages sent by port
+ * @ref: unique reference to port in TIPC object registry
+ * @phdr: preformatted message header used when sending messages
+ */
+struct tipc_port {
+ void *usr_handle;
+ spinlock_t *lock;
+ int connected;
+ u32 conn_type;
+ u32 conn_instance;
+ u32 conn_unacked;
+ int published;
+ u32 congested;
+ u32 max_pkt;
+ u32 ref;
+ struct tipc_msg phdr;
};
/**
@@ -109,11 +164,76 @@ struct port {
extern spinlock_t tipc_port_list_lock;
struct port_list;
+/*
+ * TIPC port manipulation routines
+ */
+struct tipc_port *tipc_createport_raw(void *usr_handle,
+ u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
+ void (*wakeup)(struct tipc_port *), const u32 importance);
+
+int tipc_reject_msg(struct sk_buff *buf, u32 err);
+
+int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
+
+void tipc_acknowledge(u32 port_ref, u32 ack);
+
+int tipc_createport(void *usr_handle,
+ unsigned int importance, tipc_msg_err_event error_cb,
+ tipc_named_msg_err_event named_error_cb,
+ tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
+ tipc_named_msg_event named_msg_cb,
+ tipc_conn_msg_event conn_msg_cb,
+ tipc_continue_event continue_event_cb, u32 *portref);
+
+int tipc_deleteport(u32 portref);
+
+int tipc_portimportance(u32 portref, unsigned int *importance);
+int tipc_set_portimportance(u32 portref, unsigned int importance);
+
+int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
+int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
+
+int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
+int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
+
+int tipc_publish(u32 portref, unsigned int scope,
+ struct tipc_name_seq const *name_seq);
+int tipc_withdraw(u32 portref, unsigned int scope,
+ struct tipc_name_seq const *name_seq);
+
+int tipc_connect2port(u32 portref, struct tipc_portid const *port);
+
+int tipc_disconnect(u32 portref);
+
+int tipc_shutdown(u32 ref);
+
+
+/*
+ * The following routines require that the port be locked on entry
+ */
+int tipc_disconnect_port(struct tipc_port *tp_ptr);
+
+/*
+ * TIPC messaging routines
+ */
+int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
+
+int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
+ unsigned int num_sect, struct iovec const *msg_sect);
+
+int tipc_send2port(u32 portref, struct tipc_portid const *dest,
+ unsigned int num_sect, struct iovec const *msg_sect);
+
+int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
+ struct sk_buff *buf, unsigned int dsz);
+
+int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
+ unsigned int section_count, struct iovec const *msg);
+
int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
int err);
struct sk_buff *tipc_port_get_ports(void);
-struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space);
void tipc_port_recv_proto_msg(struct sk_buff *buf);
void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
void tipc_port_reinit(void);
@@ -138,7 +258,7 @@ static inline void tipc_port_unlock(struct port *p_ptr)
spin_unlock_bh(p_ptr->publ.lock);
}
-static inline struct port* tipc_port_deref(u32 ref)
+static inline struct port *tipc_port_deref(u32 ref)
{
return (struct port *)tipc_ref_deref(ref);
}
@@ -196,7 +316,6 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
err = TIPC_ERR_NO_PORT;
}
reject:
- dbg("port->rejecting, err = %x..\n",err);
return tipc_reject_msg(buf, err);
}
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index ab8ad32d8c20..83116892528b 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -89,7 +89,7 @@ struct ref_table {
* have a reference value of 0 (although this is unlikely).
*/
-static struct ref_table tipc_ref_table = { NULL };
+static struct ref_table tipc_ref_table;
static DEFINE_RWLOCK(ref_table_lock);
@@ -178,14 +178,12 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
next_plus_upper = entry->ref;
tipc_ref_table.first_free = next_plus_upper & index_mask;
ref = (next_plus_upper & ~index_mask) + index;
- }
- else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
+ } 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);
ref = tipc_ref_table.start_mask + index;
- }
- else {
+ } else {
ref = 0;
}
write_unlock_bh(&ref_table_lock);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e9f0d5004483..2b02a3a80313 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -34,25 +34,13 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/net.h>
-#include <linux/socket.h>
-#include <linux/errno.h>
-#include <linux/mm.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>
#include <linux/tipc.h>
#include <linux/tipc_config.h>
-#include <net/tipc/tipc_msg.h>
-#include <net/tipc/tipc_port.h>
#include "core.h"
+#include "port.h"
#define SS_LISTENING -1 /* socket is listening */
#define SS_READY -2 /* socket is connectionless */
@@ -80,7 +68,7 @@ static const struct proto_ops msg_ops;
static struct proto tipc_proto;
-static int sockets_enabled = 0;
+static int sockets_enabled;
static atomic_t tipc_queue_size = ATOMIC_INIT(0);
@@ -387,7 +375,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
*
* NOTE: This routine doesn't need to take the socket lock since it only
* accesses socket information that is unchanging (or which changes in
- * a completely predictable manner).
+ * a completely predictable manner).
*/
static int get_name(struct socket *sock, struct sockaddr *uaddr,
@@ -404,7 +392,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
addr->addr.id.ref = tsock->peer_name.ref;
addr->addr.id.node = tsock->peer_name.node;
} else {
- tipc_ownidentity(tsock->p->ref, &addr->addr.id);
+ addr->addr.id.ref = tsock->p->ref;
+ addr->addr.id.node = tipc_own_addr;
}
*uaddr_len = sizeof(*addr);
@@ -574,37 +563,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
do {
if (dest->addrtype == TIPC_ADDR_NAME) {
- if ((res = dest_name_check(dest, m)))
+ res = dest_name_check(dest, m);
+ if (res)
break;
res = tipc_send2name(tport->ref,
&dest->addr.name.name,
dest->addr.name.domain,
m->msg_iovlen,
m->msg_iov);
- }
- else if (dest->addrtype == TIPC_ADDR_ID) {
+ } else if (dest->addrtype == TIPC_ADDR_ID) {
res = tipc_send2port(tport->ref,
&dest->addr.id,
m->msg_iovlen,
m->msg_iov);
- }
- else if (dest->addrtype == TIPC_ADDR_MCAST) {
+ } else if (dest->addrtype == TIPC_ADDR_MCAST) {
if (needs_conn) {
res = -EOPNOTSUPP;
break;
}
- if ((res = dest_name_check(dest, m)))
+ res = dest_name_check(dest, m);
+ if (res)
break;
res = tipc_multicast(tport->ref,
&dest->addr.nameseq,
- 0,
m->msg_iovlen,
m->msg_iov);
}
if (likely(res != -ELINKCONG)) {
- if (needs_conn && (res >= 0)) {
+ if (needs_conn && (res >= 0))
sock->state = SS_CONNECTING;
- }
break;
}
if (m->msg_flags & MSG_DONTWAIT) {
@@ -663,9 +650,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
}
res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
- if (likely(res != -ELINKCONG)) {
+ if (likely(res != -ELINKCONG))
break;
- }
if (m->msg_flags & MSG_DONTWAIT) {
res = -EWOULDBLOCK;
break;
@@ -764,7 +750,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
bytes_to_send = curr_left;
my_iov.iov_base = curr_start;
my_iov.iov_len = bytes_to_send;
- if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) {
+ res = send_packet(NULL, sock, &my_msg, 0);
+ if (res < 0) {
if (bytes_sent)
res = bytes_sent;
goto exit;
@@ -824,8 +811,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
addr->addrtype = TIPC_ADDR_ID;
addr->addr.id.ref = msg_origport(msg);
addr->addr.id.node = msg_orignode(msg);
- addr->addr.name.domain = 0; /* could leave uninitialized */
- addr->scope = 0; /* could leave uninitialized */
+ addr->addr.name.domain = 0; /* could leave uninitialized */
+ addr->scope = 0; /* could leave uninitialized */
m->msg_namelen = sizeof(struct sockaddr_tipc);
}
}
@@ -859,12 +846,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
if (unlikely(err)) {
anc_data[0] = err;
anc_data[1] = msg_data_sz(msg);
- if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data)))
- return res;
- if (anc_data[1] &&
- (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
- msg_data(msg))))
+ res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
+ if (res)
return res;
+ if (anc_data[1]) {
+ res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
+ msg_data(msg));
+ if (res)
+ return res;
+ }
}
/* Optionally capture message destination object */
@@ -892,9 +882,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
default:
has_name = 0;
}
- if (has_name &&
- (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data)))
- return res;
+ if (has_name) {
+ res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
+ if (res)
+ return res;
+ }
return 0;
}
@@ -1227,42 +1219,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
*/
if (sock->state == SS_READY) {
- if (msg_connected(msg)) {
- msg_dbg(msg, "dispatch filter 1\n");
+ if (msg_connected(msg))
return TIPC_ERR_NO_PORT;
- }
} else {
- if (msg_mcast(msg)) {
- msg_dbg(msg, "dispatch filter 2\n");
+ if (msg_mcast(msg))
return TIPC_ERR_NO_PORT;
- }
if (sock->state == SS_CONNECTED) {
- if (!msg_connected(msg)) {
- msg_dbg(msg, "dispatch filter 3\n");
+ if (!msg_connected(msg))
return TIPC_ERR_NO_PORT;
- }
- }
- else if (sock->state == SS_CONNECTING) {
- if (!msg_connected(msg) && (msg_errcode(msg) == 0)) {
- msg_dbg(msg, "dispatch filter 4\n");
+ } else if (sock->state == SS_CONNECTING) {
+ if (!msg_connected(msg) && (msg_errcode(msg) == 0))
return TIPC_ERR_NO_PORT;
- }
- }
- else if (sock->state == SS_LISTENING) {
- if (msg_connected(msg) || msg_errcode(msg)) {
- msg_dbg(msg, "dispatch filter 5\n");
+ } else if (sock->state == SS_LISTENING) {
+ if (msg_connected(msg) || msg_errcode(msg))
return TIPC_ERR_NO_PORT;
- }
- }
- else if (sock->state == SS_DISCONNECTING) {
- msg_dbg(msg, "dispatch filter 6\n");
+ } else if (sock->state == SS_DISCONNECTING) {
return TIPC_ERR_NO_PORT;
- }
- else /* (sock->state == SS_UNCONNECTED) */ {
- if (msg_connected(msg) || msg_errcode(msg)) {
- msg_dbg(msg, "dispatch filter 7\n");
+ } else /* (sock->state == SS_UNCONNECTED) */ {
+ if (msg_connected(msg) || msg_errcode(msg))
return TIPC_ERR_NO_PORT;
- }
}
}
@@ -1281,7 +1256,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
/* Enqueue message (finally!) */
- msg_dbg(msg, "<DISP<: ");
TIPC_SKB_CB(buf)->handle = msg_data(msg);
atomic_inc(&tipc_queue_size);
__skb_queue_tail(&sk->sk_receive_queue, buf);
@@ -1442,9 +1416,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
m.msg_name = dest;
m.msg_namelen = destlen;
res = send_msg(NULL, sock, &m, 0);
- if (res < 0) {
+ if (res < 0)
goto exit;
- }
/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
@@ -1466,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
advance_rx_queue(sk);
}
} else {
- if (sock->state == SS_CONNECTED) {
+ if (sock->state == SS_CONNECTED)
res = -EISCONN;
- } else {
+ else
res = -ECONNREFUSED;
- }
}
} else {
if (res == 0)
@@ -1589,7 +1561,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
* Respond to 'SYN+' by queuing it on new socket.
*/
- msg_dbg(msg,"<ACC<: ");
if (!msg_data_sz(msg)) {
struct msghdr m = {NULL,};
@@ -1697,7 +1668,8 @@ static int setsockopt(struct socket *sock,
return -ENOPROTOOPT;
if (ol < sizeof(value))
return -EINVAL;
- if ((res = get_user(value, (u32 __user *)ov)))
+ res = get_user(value, (u32 __user *)ov);
+ if (res)
return res;
lock_sock(sk);
@@ -1755,7 +1727,8 @@ static int getsockopt(struct socket *sock,
return put_user(0, ol);
if (lvl != SOL_TIPC)
return -ENOPROTOOPT;
- if ((res = get_user(len, ol)))
+ res = get_user(len, ol);
+ if (res)
return res;
lock_sock(sk);
@@ -1774,10 +1747,10 @@ static int getsockopt(struct socket *sock,
value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
/* no need to set "res", since already 0 at this point */
break;
- case TIPC_NODE_RECVQ_DEPTH:
+ case TIPC_NODE_RECVQ_DEPTH:
value = (u32)atomic_read(&tipc_queue_size);
break;
- case TIPC_SOCK_RECVQ_DEPTH:
+ case TIPC_SOCK_RECVQ_DEPTH:
value = skb_queue_len(&sk->sk_receive_queue);
break;
default:
@@ -1786,20 +1759,16 @@ static int getsockopt(struct socket *sock,
release_sock(sk);
- if (res) {
- /* "get" failed */
- }
- else if (len < sizeof(value)) {
- res = -EINVAL;
- }
- else if (copy_to_user(ov, &value, sizeof(value))) {
- res = -EFAULT;
- }
- else {
- res = put_user(sizeof(value), ol);
- }
+ if (res)
+ return res; /* "get" failed */
- return res;
+ if (len < sizeof(value))
+ return -EINVAL;
+
+ if (copy_to_user(ov, &value, sizeof(value)))
+ return -EFAULT;
+
+ return put_user(sizeof(value), ol);
}
/**
@@ -1807,7 +1776,7 @@ static int getsockopt(struct socket *sock,
*/
static const struct proto_ops msg_ops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.family = AF_TIPC,
.release = release,
.bind = bind,
@@ -1828,7 +1797,7 @@ static const struct proto_ops msg_ops = {
};
static const struct proto_ops packet_ops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.family = AF_TIPC,
.release = release,
.bind = bind,
@@ -1849,7 +1818,7 @@ static const struct proto_ops packet_ops = {
};
static const struct proto_ops stream_ops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.family = AF_TIPC,
.release = release,
.bind = bind,
@@ -1870,7 +1839,7 @@ static const struct proto_ops stream_ops = {
};
static const struct net_proto_family tipc_family_ops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.family = AF_TIPC,
.create = tipc_create
};
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 33313961d010..ca04479c3d42 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -35,10 +35,8 @@
*/
#include "core.h"
-#include "dbg.h"
#include "name_table.h"
#include "port.h"
-#include "ref.h"
#include "subscr.h"
/**
@@ -66,14 +64,13 @@ struct subscriber {
*/
struct top_srv {
- u32 user_ref;
u32 setup_port;
atomic_t subscription_count;
struct list_head subscriber_list;
spinlock_t lock;
};
-static struct top_srv topsrv = { 0 };
+static struct top_srv topsrv;
/**
* htohl - convert value to endianness used by destination
@@ -252,8 +249,6 @@ static void subscr_terminate(struct subscriber *subscriber)
k_cancel_timer(&sub->timer);
k_term_timer(&sub->timer);
}
- dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
- sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
subscr_del(sub);
}
@@ -310,8 +305,6 @@ static void subscr_cancel(struct tipc_subscr *s,
k_term_timer(&sub->timer);
spin_lock_bh(subscriber->lock);
}
- dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
- sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
subscr_del(sub);
}
@@ -496,8 +489,7 @@ static void subscr_named_msg_event(void *usr_handle,
/* Create server port & establish connection to subscriber */
- tipc_createport(topsrv.user_ref,
- subscriber,
+ tipc_createport(subscriber,
importance,
NULL,
NULL,
@@ -544,21 +536,14 @@ static void subscr_named_msg_event(void *usr_handle,
int tipc_subscr_start(void)
{
struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
- int res = -1;
+ int res;
- memset(&topsrv, 0, sizeof (topsrv));
+ memset(&topsrv, 0, sizeof(topsrv));
spin_lock_init(&topsrv.lock);
INIT_LIST_HEAD(&topsrv.subscriber_list);
spin_lock_bh(&topsrv.lock);
- res = tipc_attach(&topsrv.user_ref, NULL, NULL);
- if (res) {
- spin_unlock_bh(&topsrv.lock);
- return res;
- }
-
- res = tipc_createport(topsrv.user_ref,
- NULL,
+ res = tipc_createport(NULL,
TIPC_CRITICAL_IMPORTANCE,
NULL,
NULL,
@@ -572,16 +557,17 @@ int tipc_subscr_start(void)
goto failed;
res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
- if (res)
+ if (res) {
+ tipc_deleteport(topsrv.setup_port);
+ topsrv.setup_port = 0;
goto failed;
+ }
spin_unlock_bh(&topsrv.lock);
return 0;
failed:
err("Failed to create subscription service\n");
- tipc_detach(topsrv.user_ref);
- topsrv.user_ref = 0;
spin_unlock_bh(&topsrv.lock);
return res;
}
@@ -592,8 +578,10 @@ void tipc_subscr_stop(void)
struct subscriber *subscriber_temp;
spinlock_t *subscriber_lock;
- if (topsrv.user_ref) {
+ if (topsrv.setup_port) {
tipc_deleteport(topsrv.setup_port);
+ topsrv.setup_port = 0;
+
list_for_each_entry_safe(subscriber, subscriber_temp,
&topsrv.subscriber_list,
subscriber_list) {
@@ -602,7 +590,5 @@ void tipc_subscr_stop(void)
subscr_terminate(subscriber);
spin_unlock_bh(subscriber_lock);
}
- tipc_detach(topsrv.user_ref);
- topsrv.user_ref = 0;
}
}
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c
deleted file mode 100644
index 506928803162..000000000000
--- a/net/tipc/user_reg.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * net/tipc/user_reg.c: TIPC user registry code
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include "core.h"
-#include "user_reg.h"
-
-/*
- * TIPC user registry keeps track of users of the tipc_port interface.
- *
- * The registry utilizes an array of "TIPC user" entries;
- * a user's ID is the index of their associated array entry.
- * Array entry 0 is not used, so userid 0 is not valid;
- * TIPC sometimes uses this value to denote an anonymous user.
- * The list of free entries is initially chained from last entry to entry 1.
- */
-
-/**
- * struct tipc_user - registered TIPC user info
- * @next: index of next free registry entry (or -1 for an allocated entry)
- * @callback: ptr to routine to call when TIPC mode changes (NULL if none)
- * @usr_handle: user-defined value passed to callback routine
- * @ports: list of user ports owned by the user
- */
-
-struct tipc_user {
- int next;
- tipc_mode_event callback;
- void *usr_handle;
- struct list_head ports;
-};
-
-#define MAX_USERID 64
-#define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user))
-
-static struct tipc_user *users = NULL;
-static u32 next_free_user = MAX_USERID + 1;
-static DEFINE_SPINLOCK(reg_lock);
-
-/**
- * reg_init - create TIPC user registry (but don't activate it)
- *
- * If registry has been pre-initialized it is left "as is".
- * NOTE: This routine may be called when TIPC is inactive.
- */
-
-static int reg_init(void)
-{
- u32 i;
-
- spin_lock_bh(&reg_lock);
- if (!users) {
- users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC);
- if (users) {
- for (i = 1; i <= MAX_USERID; i++) {
- users[i].next = i - 1;
- }
- next_free_user = MAX_USERID;
- }
- }
- spin_unlock_bh(&reg_lock);
- return users ? 0 : -ENOMEM;
-}
-
-/**
- * reg_callback - inform TIPC user about current operating mode
- */
-
-static void reg_callback(struct tipc_user *user_ptr)
-{
- tipc_mode_event cb;
- void *arg;
-
- spin_lock_bh(&reg_lock);
- cb = user_ptr->callback;
- arg = user_ptr->usr_handle;
- spin_unlock_bh(&reg_lock);
-
- if (cb)
- cb(arg, tipc_mode, tipc_own_addr);
-}
-
-/**
- * tipc_reg_start - activate TIPC user registry
- */
-
-int tipc_reg_start(void)
-{
- u32 u;
- int res;
-
- if ((res = reg_init()))
- return res;
-
- for (u = 1; u <= MAX_USERID; u++) {
- if (users[u].callback)
- tipc_k_signal((Handler)reg_callback,
- (unsigned long)&users[u]);
- }
- return 0;
-}
-
-/**
- * tipc_reg_stop - shut down & delete TIPC user registry
- */
-
-void tipc_reg_stop(void)
-{
- int id;
-
- if (!users)
- return;
-
- for (id = 1; id <= MAX_USERID; id++) {
- if (users[id].callback)
- reg_callback(&users[id]);
- }
- kfree(users);
- users = NULL;
-}
-
-/**
- * tipc_attach - register a TIPC user
- *
- * NOTE: This routine may be called when TIPC is inactive.
- */
-
-int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle)
-{
- struct tipc_user *user_ptr;
-
- if ((tipc_mode == TIPC_NOT_RUNNING) && !cb)
- return -ENOPROTOOPT;
- if (!users)
- reg_init();
-
- spin_lock_bh(&reg_lock);
- if (!next_free_user) {
- spin_unlock_bh(&reg_lock);
- return -EBUSY;
- }
- user_ptr = &users[next_free_user];
- *userid = next_free_user;
- next_free_user = user_ptr->next;
- user_ptr->next = -1;
- spin_unlock_bh(&reg_lock);
-
- user_ptr->callback = cb;
- user_ptr->usr_handle = usr_handle;
- INIT_LIST_HEAD(&user_ptr->ports);
- atomic_inc(&tipc_user_count);
-
- if (cb && (tipc_mode != TIPC_NOT_RUNNING))
- tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr);
- return 0;
-}
-
-/**
- * tipc_detach - deregister a TIPC user
- */
-
-void tipc_detach(u32 userid)
-{
- struct tipc_user *user_ptr;
- struct list_head ports_temp;
- struct user_port *up_ptr, *temp_up_ptr;
-
- if ((userid == 0) || (userid > MAX_USERID))
- return;
-
- spin_lock_bh(&reg_lock);
- if ((!users) || (users[userid].next >= 0)) {
- spin_unlock_bh(&reg_lock);
- return;
- }
-
- user_ptr = &users[userid];
- user_ptr->callback = NULL;
- INIT_LIST_HEAD(&ports_temp);
- list_splice(&user_ptr->ports, &ports_temp);
- user_ptr->next = next_free_user;
- next_free_user = userid;
- spin_unlock_bh(&reg_lock);
-
- atomic_dec(&tipc_user_count);
-
- list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) {
- tipc_deleteport(up_ptr->ref);
- }
-}
-
-/**
- * tipc_reg_add_port - register a user's driver port
- */
-
-int tipc_reg_add_port(struct user_port *up_ptr)
-{
- struct tipc_user *user_ptr;
-
- if (up_ptr->user_ref == 0)
- return 0;
- if (up_ptr->user_ref > MAX_USERID)
- return -EINVAL;
- if ((tipc_mode == TIPC_NOT_RUNNING) || !users )
- return -ENOPROTOOPT;
-
- spin_lock_bh(&reg_lock);
- user_ptr = &users[up_ptr->user_ref];
- list_add(&up_ptr->uport_list, &user_ptr->ports);
- spin_unlock_bh(&reg_lock);
- return 0;
-}
-
-/**
- * tipc_reg_remove_port - deregister a user's driver port
- */
-
-int tipc_reg_remove_port(struct user_port *up_ptr)
-{
- if (up_ptr->user_ref == 0)
- return 0;
- if (up_ptr->user_ref > MAX_USERID)
- return -EINVAL;
- if (!users )
- return -ENOPROTOOPT;
-
- spin_lock_bh(&reg_lock);
- list_del_init(&up_ptr->uport_list);
- spin_unlock_bh(&reg_lock);
- return 0;
-}
-
diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h
deleted file mode 100644
index 81dc12e2882f..000000000000
--- a/net/tipc/user_reg.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * net/tipc/user_reg.h: Include file for TIPC user registry code
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _TIPC_USER_REG_H
-#define _TIPC_USER_REG_H
-
-#include "port.h"
-
-int tipc_reg_start(void);
-void tipc_reg_stop(void);
-
-int tipc_reg_add_port(struct user_port *up_ptr);
-int tipc_reg_remove_port(struct user_port *up_ptr);
-
-#endif
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
deleted file mode 100644
index 83f8b5e91fc8..000000000000
--- a/net/tipc/zone.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * net/tipc/zone.c: TIPC zone management routines
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include "core.h"
-#include "zone.h"
-#include "net.h"
-#include "addr.h"
-#include "node_subscr.h"
-#include "cluster.h"
-#include "node.h"
-
-struct _zone *tipc_zone_create(u32 addr)
-{
- struct _zone *z_ptr;
- u32 z_num;
-
- if (!tipc_addr_domain_valid(addr)) {
- err("Zone creation failed, invalid domain 0x%x\n", addr);
- return NULL;
- }
-
- z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC);
- if (!z_ptr) {
- warn("Zone creation failed, insufficient memory\n");
- return NULL;
- }
-
- z_num = tipc_zone(addr);
- z_ptr->addr = tipc_addr(z_num, 0, 0);
- tipc_net.zones[z_num] = z_ptr;
- return z_ptr;
-}
-
-void tipc_zone_delete(struct _zone *z_ptr)
-{
- u32 c_num;
-
- if (!z_ptr)
- return;
- for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
- tipc_cltr_delete(z_ptr->clusters[c_num]);
- }
- kfree(z_ptr);
-}
-
-void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
-{
- u32 c_num = tipc_cluster(c_ptr->addr);
-
- assert(c_ptr->addr);
- assert(c_num <= tipc_max_clusters);
- assert(z_ptr->clusters[c_num] == NULL);
- z_ptr->clusters[c_num] = c_ptr;
-}
-
-void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router)
-{
- u32 c_num;
-
- for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
- if (z_ptr->clusters[c_num]) {
- tipc_cltr_remove_as_router(z_ptr->clusters[c_num],
- router);
- }
- }
-}
-
-void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest)
-{
- u32 c_num;
-
- for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
- if (z_ptr->clusters[c_num]) {
- if (in_own_cluster(z_ptr->addr))
- continue;
- tipc_cltr_send_ext_routes(z_ptr->clusters[c_num], dest);
- }
- }
-}
-
-struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
-{
- struct cluster *c_ptr;
- struct tipc_node *n_ptr;
- u32 c_num;
-
- if (!z_ptr)
- return NULL;
- c_ptr = z_ptr->clusters[tipc_cluster(addr)];
- if (!c_ptr)
- return NULL;
- n_ptr = tipc_cltr_select_node(c_ptr, ref);
- if (n_ptr)
- return n_ptr;
-
- /* Links to any other clusters within this zone ? */
- for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
- c_ptr = z_ptr->clusters[c_num];
- if (!c_ptr)
- return NULL;
- n_ptr = tipc_cltr_select_node(c_ptr, ref);
- if (n_ptr)
- return n_ptr;
- }
- return NULL;
-}
-
-u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
-{
- struct cluster *c_ptr;
- u32 c_num;
- u32 router;
-
- if (!z_ptr)
- return 0;
- c_ptr = z_ptr->clusters[tipc_cluster(addr)];
- router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
- if (router)
- return router;
-
- /* Links to any other clusters within the zone? */
- for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
- c_ptr = z_ptr->clusters[c_num];
- router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
- if (router)
- return router;
- }
- return 0;
-}
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
deleted file mode 100644
index bd1c20ce9d06..000000000000
--- a/net/tipc/zone.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * net/tipc/zone.h: Include file for TIPC zone management routines
- *
- * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005-2006, Wind River Systems
- * 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 names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef _TIPC_ZONE_H
-#define _TIPC_ZONE_H
-
-#include "node_subscr.h"
-#include "net.h"
-
-
-/**
- * struct _zone - TIPC zone structure
- * @addr: network address of zone
- * @clusters: array of pointers to all clusters within zone
- * @links: number of (unicast) links to zone
- */
-
-struct _zone {
- u32 addr;
- struct cluster *clusters[2]; /* currently limited to just 1 cluster */
- u32 links;
-};
-
-struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
-u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
-void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router);
-void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
-struct _zone *tipc_zone_create(u32 addr);
-void tipc_zone_delete(struct _zone *z_ptr);
-void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr);
-
-static inline struct _zone *tipc_zone_find(u32 addr)
-{
- return tipc_net.zones[tipc_zone(addr)];
-}
-
-#endif
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 2268e6798124..417d7a6c36cf 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -316,7 +316,8 @@ static void unix_write_space(struct sock *sk)
if (unix_writable(sk)) {
wq = rcu_dereference(sk->sk_wq);
if (wq_has_sleeper(wq))
- wake_up_interruptible_sync(&wq->wait);
+ wake_up_interruptible_sync_poll(&wq->wait,
+ POLLOUT | POLLWRNORM | POLLWRBAND);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
}
rcu_read_unlock();
@@ -1736,7 +1737,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
goto out_unlock;
}
- wake_up_interruptible_sync(&u->peer_wait);
+ wake_up_interruptible_sync_poll(&u->peer_wait,
+ POLLOUT | POLLWRNORM | POLLWRBAND);
if (msg->msg_name)
unix_copy_addr(msg, skb->sk);
@@ -2099,13 +2101,12 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLRDHUP;
+ mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
+ if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
@@ -2117,20 +2118,19 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
return mask;
}
- /* writable? */
- writable = unix_writable(sk);
- if (writable) {
- other = unix_peer_get(sk);
- if (other) {
- if (unix_peer(other) != sk) {
- sock_poll_wait(file, &unix_sk(other)->peer_wait,
- wait);
- if (unix_recvq_full(other))
- writable = 0;
- }
+ /* No write status requested, avoid expensive OUT tests. */
+ if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT)))
+ return mask;
- sock_put(other);
+ writable = unix_writable(sk);
+ other = unix_peer_get(sk);
+ if (other) {
+ if (unix_peer(other) != sk) {
+ sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
+ if (unix_recvq_full(other))
+ writable = 0;
}
+ sock_put(other);
}
if (writable)
diff --git a/net/wanrouter/Makefile b/net/wanrouter/Makefile
index 9f188ab3dcd0..4da14bc48078 100644
--- a/net/wanrouter/Makefile
+++ b/net/wanrouter/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_WAN_ROUTER) += wanrouter.o
-wanrouter-objs := wanproc.o wanmain.o
+wanrouter-y := wanproc.o wanmain.o
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index e77e508126fa..55a28ab21db9 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o
obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
-cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o
+cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o
cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 9c21ebf9780e..e9a5f8ca4c27 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -4,6 +4,8 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/if.h>
#include <linux/module.h>
#include <linux/err.h>
@@ -216,8 +218,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent,
newname))
- printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
- newname);
+ pr_err("failed to rename debugfs dir to %s!\n", newname);
nl80211_notify_dev_rename(rdev);
@@ -331,6 +332,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
WARN_ON(ops->add_station && !ops->del_station);
WARN_ON(ops->add_mpath && !ops->del_mpath);
+ WARN_ON(ops->join_mesh && !ops->leave_mesh);
alloc_size = sizeof(*rdev) + sizeof_priv;
@@ -699,8 +701,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
"phy80211")) {
- printk(KERN_ERR "wireless: failed to add phy80211 "
- "symlink to netdev!\n");
+ pr_err("failed to add phy80211 symlink to netdev!\n");
}
wdev->netdev = dev;
wdev->sme_state = CFG80211_SME_IDLE;
@@ -752,6 +753,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
cfg80211_mlme_down(rdev, dev);
wdev_unlock(wdev);
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ cfg80211_leave_mesh(rdev, dev);
+ break;
default:
break;
}
@@ -775,20 +779,37 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
}
cfg80211_lock_rdev(rdev);
mutex_lock(&rdev->devlist_mtx);
-#ifdef CONFIG_CFG80211_WEXT
wdev_lock(wdev);
switch (wdev->iftype) {
+#ifdef CONFIG_CFG80211_WEXT
case NL80211_IFTYPE_ADHOC:
cfg80211_ibss_wext_join(rdev, wdev);
break;
case NL80211_IFTYPE_STATION:
cfg80211_mgd_wext_connect(rdev, wdev);
break;
+#endif
+#ifdef CONFIG_MAC80211_MESH
+ case NL80211_IFTYPE_MESH_POINT:
+ {
+ /* backward compat code... */
+ struct mesh_setup setup;
+ memcpy(&setup, &default_mesh_setup,
+ sizeof(setup));
+ /* back compat only needed for mesh_id */
+ setup.mesh_id = wdev->ssid;
+ setup.mesh_id_len = wdev->mesh_id_up_len;
+ if (wdev->mesh_id_up_len)
+ __cfg80211_join_mesh(rdev, dev,
+ &setup,
+ &default_mesh_config);
+ break;
+ }
+#endif
default:
break;
}
wdev_unlock(wdev);
-#endif
rdev->opencount++;
mutex_unlock(&rdev->devlist_mtx);
cfg80211_unlock_rdev(rdev);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6583cca0e2ee..26a0a084e16b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -285,6 +285,20 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev);
+/* mesh */
+extern const struct mesh_config default_mesh_config;
+extern const struct mesh_setup default_mesh_setup;
+int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ const struct mesh_setup *setup,
+ const struct mesh_config *conf);
+int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ const struct mesh_setup *setup,
+ const struct mesh_config *conf);
+int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev);
+
/* MLME */
int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
struct net_device *dev,
@@ -341,9 +355,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct net_device *dev,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
- bool channel_type_valid,
+ bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, u64 *cookie);
/* SME */
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
index 97d411f74507..3268fac5ab22 100644
--- a/net/wireless/lib80211.c
+++ b/net/wireless/lib80211.c
@@ -13,6 +13,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/ieee80211.h>
@@ -224,8 +226,8 @@ int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
return -EINVAL;
found:
- printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm "
- "'%s'\n", ops->name);
+ printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm '%s'\n",
+ ops->name);
list_del(&alg->list);
spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
kfree(alg);
@@ -270,7 +272,7 @@ static struct lib80211_crypto_ops lib80211_crypt_null = {
static int __init lib80211_init(void)
{
- printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n");
+ pr_info(DRV_DESCRIPTION "\n");
return lib80211_register_crypto_ops(&lib80211_crypt_null);
}
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index 0fe40510e2cb..7ea4f2b0770e 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -10,6 +10,8 @@
* more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -99,8 +101,7 @@ static void *lib80211_tkip_init(int key_idx)
priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_arc4)) {
- printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
+ printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n"));
priv->tx_tfm_arc4 = NULL;
goto fail;
}
@@ -108,8 +109,7 @@ static void *lib80211_tkip_init(int key_idx)
priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_michael)) {
- printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
+ printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n"));
priv->tx_tfm_michael = NULL;
goto fail;
}
@@ -117,8 +117,7 @@ static void *lib80211_tkip_init(int key_idx)
priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_arc4)) {
- printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
+ printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n"));
priv->rx_tfm_arc4 = NULL;
goto fail;
}
@@ -126,8 +125,7 @@ static void *lib80211_tkip_init(int key_idx)
priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_michael)) {
- printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
+ printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n"));
priv->rx_tfm_michael = NULL;
goto fail;
}
@@ -536,7 +534,7 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
struct scatterlist sg[2];
if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
+ pr_warn("%s(): tfm_michael == NULL\n", __func__);
return -1;
}
sg_init_table(sg, 2);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
new file mode 100644
index 000000000000..73e39c171ffb
--- /dev/null
+++ b/net/wireless/mesh.c
@@ -0,0 +1,142 @@
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include "core.h"
+
+/* Default values, timeouts in ms */
+#define MESH_TTL 31
+#define MESH_DEFAULT_ELEMENT_TTL 31
+#define MESH_MAX_RETR 3
+#define MESH_RET_T 100
+#define MESH_CONF_T 100
+#define MESH_HOLD_T 100
+
+#define MESH_PATH_TIMEOUT 5000
+
+/*
+ * Minimum interval between two consecutive PREQs originated by the same
+ * interface
+ */
+#define MESH_PREQ_MIN_INT 10
+#define MESH_DIAM_TRAVERSAL_TIME 50
+
+/*
+ * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds
+ * before timing out. This way it will remain ACTIVE and no data frames
+ * will be unnecessarily held in the pending queue.
+ */
+#define MESH_PATH_REFRESH_TIME 1000
+#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
+
+/* Default maximum number of established plinks per interface */
+#define MESH_MAX_ESTAB_PLINKS 32
+
+#define MESH_MAX_PREQ_RETRIES 4
+
+
+const struct mesh_config default_mesh_config = {
+ .dot11MeshRetryTimeout = MESH_RET_T,
+ .dot11MeshConfirmTimeout = MESH_CONF_T,
+ .dot11MeshHoldingTimeout = MESH_HOLD_T,
+ .dot11MeshMaxRetries = MESH_MAX_RETR,
+ .dot11MeshTTL = MESH_TTL,
+ .element_ttl = MESH_DEFAULT_ELEMENT_TTL,
+ .auto_open_plinks = true,
+ .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
+ .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
+ .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
+ .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME,
+ .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
+ .path_refresh_time = MESH_PATH_REFRESH_TIME,
+ .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
+};
+
+const struct mesh_setup default_mesh_setup = {
+ .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
+ .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
+ .vendor_ie = NULL,
+ .vendor_ie_len = 0,
+};
+
+int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ const struct mesh_setup *setup,
+ const struct mesh_config *conf)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
+
+ ASSERT_WDEV_LOCK(wdev);
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ if (wdev->mesh_id_len)
+ return -EALREADY;
+
+ if (!setup->mesh_id_len)
+ return -EINVAL;
+
+ if (!rdev->ops->join_mesh)
+ return -EOPNOTSUPP;
+
+ err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
+ if (!err) {
+ memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+ wdev->mesh_id_len = setup->mesh_id_len;
+ }
+
+ return err;
+}
+
+int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ const struct mesh_setup *setup,
+ const struct mesh_config *conf)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ wdev_lock(wdev);
+ err = __cfg80211_join_mesh(rdev, dev, setup, conf);
+ wdev_unlock(wdev);
+
+ return err;
+}
+
+static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ ASSERT_WDEV_LOCK(wdev);
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ if (!rdev->ops->leave_mesh)
+ return -EOPNOTSUPP;
+
+ if (!wdev->mesh_id_len)
+ return -ENOTCONN;
+
+ err = rdev->ops->leave_mesh(&rdev->wiphy, dev);
+ if (!err)
+ wdev->mesh_id_len = 0;
+ return err;
+}
+
+int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
+
+ wdev_lock(wdev);
+ err = __cfg80211_leave_mesh(rdev, dev);
+ wdev_unlock(wdev);
+
+ return err;
+}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 26838d903b9a..aa5df8865ff7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
}
EXPORT_SYMBOL(cfg80211_send_disassoc);
+void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
+ size_t len)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
+
+void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
+ size_t len)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
+
static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
{
int i;
@@ -864,9 +886,9 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct net_device *dev,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
- bool channel_type_valid,
+ bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, u64 *cookie)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -946,8 +968,9 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
return -EINVAL;
/* Transmit the Action frame as requested by user space */
- return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type,
- channel_type_valid, buf, len, cookie);
+ return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
+ channel_type, channel_type_valid,
+ wait, buf, len, cookie);
}
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
@@ -1028,3 +1051,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
}
EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
+
+void cfg80211_cqm_pktloss_notify(struct net_device *dev,
+ const u8 *peer, u32 num_packets, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ /* Indicate roaming trigger event to user space */
+ nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
+}
+EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4e78e3f26798..9b62710891a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -121,8 +121,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
[NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
.len = NL80211_MAX_SUPP_RATES },
+ [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
- [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
+ [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
.len = NL80211_HT_CAPABILITY_LEN },
@@ -163,10 +164,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
[NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
-
[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
[NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
+ [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
+ [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
+ [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
+ [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
};
/* policy for the key attributes */
@@ -178,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
[NL80211_KEY_TYPE] = { .type = NLA_U32 },
+ [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+};
+
+/* policy for the key default flags */
+static const struct nla_policy
+nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
+ [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
+ [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
};
/* ifidx get helper */
@@ -310,6 +323,7 @@ struct key_parse {
int idx;
int type;
bool def, defmgmt;
+ bool def_uni, def_multi;
};
static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -323,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
k->def = !!tb[NL80211_KEY_DEFAULT];
k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
+ if (k->def) {
+ k->def_uni = true;
+ k->def_multi = true;
+ }
+ if (k->defmgmt)
+ k->def_multi = true;
+
if (tb[NL80211_KEY_IDX])
k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
@@ -345,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
return -EINVAL;
}
+ if (tb[NL80211_KEY_DEFAULT_TYPES]) {
+ struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+ int err = nla_parse_nested(kdt,
+ NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+ tb[NL80211_KEY_DEFAULT_TYPES],
+ nl80211_key_default_policy);
+ if (err)
+ return err;
+
+ k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+ k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+ }
+
return 0;
}
@@ -369,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
+ if (k->def) {
+ k->def_uni = true;
+ k->def_multi = true;
+ }
+ if (k->defmgmt)
+ k->def_multi = true;
+
if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
return -EINVAL;
}
+ if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
+ struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+ int err = nla_parse_nested(
+ kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+ info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
+ nl80211_key_default_policy);
+ if (err)
+ return err;
+
+ k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+ k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+ }
+
return 0;
}
@@ -397,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
if (k->def && k->defmgmt)
return -EINVAL;
+ if (k->defmgmt) {
+ if (k->def_uni || !k->def_multi)
+ return -EINVAL;
+ }
+
if (k->idx != -1) {
if (k->defmgmt) {
if (k->idx < 4 || k->idx > 5)
@@ -446,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
goto error;
def = 1;
result->def = parse.idx;
+ if (!parse.def_uni || !parse.def_multi)
+ goto error;
} else if (parse.defmgmt)
goto error;
err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -526,7 +587,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
dev->wiphy.rts_threshold);
NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
dev->wiphy.coverage_class);
-
NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
dev->wiphy.max_scan_ssids);
NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
@@ -545,6 +605,22 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
+ dev->wiphy.available_antennas_tx);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+ dev->wiphy.available_antennas_rx);
+
+ if ((dev->wiphy.available_antennas_tx ||
+ dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
+ u32 tx_ant = 0, rx_ant = 0;
+ int res;
+ res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
+ if (!res) {
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);
+ }
+ }
+
nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
if (!nl_modes)
goto nla_put_failure;
@@ -649,19 +725,21 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(add_beacon, NEW_BEACON);
CMD(add_station, NEW_STATION);
CMD(add_mpath, NEW_MPATH);
- CMD(set_mesh_params, SET_MESH_PARAMS);
+ CMD(update_mesh_config, SET_MESH_CONFIG);
CMD(change_bss, SET_BSS);
CMD(auth, AUTHENTICATE);
CMD(assoc, ASSOCIATE);
CMD(deauth, DEAUTHENTICATE);
CMD(disassoc, DISASSOCIATE);
CMD(join_ibss, JOIN_IBSS);
+ CMD(join_mesh, JOIN_MESH);
CMD(set_pmksa, SET_PMKSA);
CMD(del_pmksa, DEL_PMKSA);
CMD(flush_pmksa, FLUSH_PMKSA);
CMD(remain_on_channel, REMAIN_ON_CHANNEL);
CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
CMD(mgmt_tx, FRAME);
+ CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
i++;
NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
@@ -683,6 +761,14 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end(msg, nl_cmds);
+ if (dev->ops->remain_on_channel)
+ NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
+ dev->wiphy.max_remain_on_channel_duration);
+
+ /* for now at least assume all drivers have it */
+ if (dev->ops->mgmt_tx)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
+
if (mgmt_stypes) {
u16 stypes;
struct nlattr *nl_ftypes, *nl_ifs;
@@ -1024,6 +1110,35 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
}
+ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+ info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+ u32 tx_ant, rx_ant;
+ if ((!rdev->wiphy.available_antennas_tx &&
+ !rdev->wiphy.available_antennas_rx) ||
+ !rdev->ops->set_antenna) {
+ result = -EOPNOTSUPP;
+ goto bad_res;
+ }
+
+ tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
+ rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+
+ /* reject antenna configurations which don't match the
+ * available antenna masks, except for the "all" mask */
+ if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
+ (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
+ result = -EINVAL;
+ goto bad_res;
+ }
+
+ tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
+ rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
+
+ result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
+ if (result)
+ goto bad_res;
+ }
+
changed = 0;
if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
@@ -1291,11 +1406,21 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
if (ntype != NL80211_IFTYPE_MESH_POINT)
return -EINVAL;
- params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
- params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
- change = true;
+ if (netif_running(dev))
+ return -EBUSY;
+
+ wdev_lock(wdev);
+ BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
+ IEEE80211_MAX_MESH_ID_LEN);
+ wdev->mesh_id_up_len =
+ nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+ memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
+ wdev->mesh_id_up_len);
+ wdev_unlock(wdev);
}
if (info->attrs[NL80211_ATTR_4ADDR]) {
@@ -1335,6 +1460,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct vif_params params;
+ struct net_device *dev;
int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
u32 flags;
@@ -1354,12 +1480,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
!(rdev->wiphy.interface_modes & (1 << type)))
return -EOPNOTSUPP;
- if (type == NL80211_IFTYPE_MESH_POINT &&
- info->attrs[NL80211_ATTR_MESH_ID]) {
- params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
- params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
- }
-
if (info->attrs[NL80211_ATTR_4ADDR]) {
params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
@@ -1370,11 +1490,27 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
&flags);
- err = rdev->ops->add_virtual_intf(&rdev->wiphy,
+ dev = rdev->ops->add_virtual_intf(&rdev->wiphy,
nla_data(info->attrs[NL80211_ATTR_IFNAME]),
type, err ? NULL : &flags, &params);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
- return err;
+ if (type == NL80211_IFTYPE_MESH_POINT &&
+ info->attrs[NL80211_ATTR_MESH_ID]) {
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ wdev_lock(wdev);
+ BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
+ IEEE80211_MAX_MESH_ID_LEN);
+ wdev->mesh_id_up_len =
+ nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+ memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
+ wdev->mesh_id_up_len);
+ wdev_unlock(wdev);
+ }
+
+ return 0;
}
static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
@@ -1519,8 +1655,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
struct key_parse key;
int err;
struct net_device *dev = info->user_ptr[1];
- int (*func)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index);
err = nl80211_parse_key(info, &key);
if (err)
@@ -1533,27 +1667,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (!key.def && !key.defmgmt)
return -EINVAL;
- if (key.def)
- func = rdev->ops->set_default_key;
- else
- func = rdev->ops->set_default_mgmt_key;
+ wdev_lock(dev->ieee80211_ptr);
- if (!func)
- return -EOPNOTSUPP;
+ if (key.def) {
+ if (!rdev->ops->set_default_key) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
- wdev_lock(dev->ieee80211_ptr);
- err = nl80211_key_allowed(dev->ieee80211_ptr);
- if (!err)
- err = func(&rdev->wiphy, dev, key.idx);
+ err = nl80211_key_allowed(dev->ieee80211_ptr);
+ if (err)
+ goto out;
+
+ if (!(rdev->wiphy.flags &
+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
+ if (!key.def_uni || !key.def_multi) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+ }
+
+ err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
+ key.def_uni, key.def_multi);
+
+ if (err)
+ goto out;
#ifdef CONFIG_CFG80211_WEXT
- if (!err) {
- if (func == rdev->ops->set_default_key)
- dev->ieee80211_ptr->wext.default_key = key.idx;
- else
- dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
- }
+ dev->ieee80211_ptr->wext.default_key = key.idx;
+#endif
+ } else {
+ if (key.def_uni || !key.def_multi) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!rdev->ops->set_default_mgmt_key) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ err = nl80211_key_allowed(dev->ieee80211_ptr);
+ if (err)
+ goto out;
+
+ err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
+ dev, key.idx);
+ if (err)
+ goto out;
+
+#ifdef CONFIG_CFG80211_WEXT
+ dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
#endif
+ }
+
+ out:
wdev_unlock(dev->ieee80211_ptr);
return err;
@@ -1841,6 +2009,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_SIGNAL)
NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
sinfo->signal);
+ if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
+ sinfo->signal_avg);
if (sinfo->filled & STATION_INFO_TX_BITRATE) {
txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
if (!txrate)
@@ -2404,6 +2575,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
params.use_short_preamble = -1;
params.use_short_slot_time = -1;
params.ap_isolate = -1;
+ params.ht_opmode = -1;
if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
params.use_cts_prot =
@@ -2422,6 +2594,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_AP_ISOLATE])
params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
+ if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
+ params.ht_opmode =
+ nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
if (!rdev->ops->change_bss)
return -EOPNOTSUPP;
@@ -2506,22 +2681,33 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
return r;
}
-static int nl80211_get_mesh_params(struct sk_buff *skb,
- struct genl_info *info)
+static int nl80211_get_mesh_config(struct sk_buff *skb,
+ struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct mesh_config cur_params;
- int err;
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct mesh_config cur_params;
+ int err = 0;
void *hdr;
struct nlattr *pinfoattr;
struct sk_buff *msg;
- if (!rdev->ops->get_mesh_params)
+ if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
return -EOPNOTSUPP;
- /* Get the mesh params */
- err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
+ if (!rdev->ops->get_mesh_config)
+ return -EOPNOTSUPP;
+
+ wdev_lock(wdev);
+ /* If not connected, get default parameters */
+ if (!wdev->mesh_id_len)
+ memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
+ else
+ err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
+ &cur_params);
+ wdev_unlock(wdev);
+
if (err)
return err;
@@ -2530,10 +2716,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
if (!msg)
return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
- NL80211_CMD_GET_MESH_PARAMS);
+ NL80211_CMD_GET_MESH_CONFIG);
if (!hdr)
goto nla_put_failure;
- pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
+ pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
if (!pinfoattr)
goto nla_put_failure;
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2549,6 +2735,8 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
cur_params.dot11MeshMaxRetries);
NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
cur_params.dot11MeshTTL);
+ NLA_PUT_U8(msg, NL80211_MESHCONF_ELEMENT_TTL,
+ cur_params.element_ttl);
NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
cur_params.auto_open_plinks);
NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
@@ -2575,14 +2763,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
return -ENOBUFS;
}
-#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
-do {\
- if (table[attr_num]) {\
- cfg.param = nla_fn(table[attr_num]); \
- mask |= (1 << (attr_num - 1)); \
- } \
-} while (0);\
-
static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
[NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
@@ -2590,6 +2770,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
[NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
[NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
+ [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
[NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
@@ -2600,31 +2781,42 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
};
-static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
+static const struct nla_policy
+ nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
+ [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
+ [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
+ [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
+ .len = IEEE80211_MAX_DATA_LEN },
+};
+
+static int nl80211_parse_mesh_config(struct genl_info *info,
+ struct mesh_config *cfg,
+ u32 *mask_out)
{
- u32 mask;
- struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct net_device *dev = info->user_ptr[1];
- struct mesh_config cfg;
struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
- struct nlattr *parent_attr;
+ u32 mask = 0;
- parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
- if (!parent_attr)
+#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
+do {\
+ if (table[attr_num]) {\
+ cfg->param = nla_fn(table[attr_num]); \
+ mask |= (1 << (attr_num - 1)); \
+ } \
+} while (0);\
+
+
+ if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
return -EINVAL;
if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
- parent_attr, nl80211_meshconf_params_policy))
+ info->attrs[NL80211_ATTR_MESH_CONFIG],
+ nl80211_meshconf_params_policy))
return -EINVAL;
- if (!rdev->ops->set_mesh_params)
- return -EOPNOTSUPP;
-
/* This makes sure that there aren't more than 32 mesh config
* parameters (otherwise our bitfield scheme would not work.) */
BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
/* Fill in the params struct */
- mask = 0;
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
@@ -2637,6 +2829,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
mask, NL80211_MESHCONF_TTL, nla_get_u8);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
+ mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
@@ -2661,12 +2855,82 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
dot11MeshHWMPRootMode, mask,
NL80211_MESHCONF_HWMP_ROOTMODE,
nla_get_u8);
+ if (mask_out)
+ *mask_out = mask;
- /* Apply changes */
- return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
-}
+ return 0;
#undef FILL_IN_MESH_PARAM_IF_SET
+}
+
+static int nl80211_parse_mesh_setup(struct genl_info *info,
+ struct mesh_setup *setup)
+{
+ struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
+
+ if (!info->attrs[NL80211_ATTR_MESH_SETUP])
+ return -EINVAL;
+ if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
+ info->attrs[NL80211_ATTR_MESH_SETUP],
+ nl80211_mesh_setup_params_policy))
+ return -EINVAL;
+
+ if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
+ setup->path_sel_proto =
+ (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
+ IEEE80211_PATH_PROTOCOL_VENDOR :
+ IEEE80211_PATH_PROTOCOL_HWMP;
+
+ if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
+ setup->path_metric =
+ (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
+ IEEE80211_PATH_METRIC_VENDOR :
+ IEEE80211_PATH_METRIC_AIRTIME;
+
+ if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
+ struct nlattr *ieattr =
+ tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
+ if (!is_valid_ie_attr(ieattr))
+ return -EINVAL;
+ setup->vendor_ie = nla_data(ieattr);
+ setup->vendor_ie_len = nla_len(ieattr);
+ }
+
+ return 0;
+}
+
+static int nl80211_update_mesh_config(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct mesh_config cfg;
+ u32 mask;
+ int err;
+
+ if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ if (!rdev->ops->update_mesh_config)
+ return -EOPNOTSUPP;
+
+ err = nl80211_parse_mesh_config(info, &cfg, &mask);
+ if (err)
+ return err;
+
+ wdev_lock(wdev);
+ if (!wdev->mesh_id_len)
+ err = -ENOLINK;
+
+ if (!err)
+ err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
+ mask, &cfg);
+
+ wdev_unlock(wdev);
+
+ return err;
+}
static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
{
@@ -3569,6 +3833,34 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
local_state_change);
}
+static bool
+nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
+ int mcast_rate[IEEE80211_NUM_BANDS],
+ int rateval)
+{
+ struct wiphy *wiphy = &rdev->wiphy;
+ bool found = false;
+ int band, i;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ struct ieee80211_supported_band *sband;
+
+ sband = wiphy->bands[band];
+ if (!sband)
+ continue;
+
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if (sband->bitrates[i].bitrate == rateval) {
+ mcast_rate[band] = i + 1;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ return found;
+}
+
static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -3653,6 +3945,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
}
}
+ if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
+ !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
+ nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
+ return -EINVAL;
+
if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
connkeys = nl80211_parse_connkeys(rdev,
info->attrs[NL80211_ATTR_KEYS]);
@@ -3987,7 +4284,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
* We should be on that channel for at least one jiffie,
* and more than 5 seconds seems excessive.
*/
- if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
+ if (!duration || !msecs_to_jiffies(duration) ||
+ duration > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
if (!rdev->ops->remain_on_channel)
@@ -4155,6 +4453,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
@@ -4180,6 +4479,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
void *hdr;
u64 cookie;
struct sk_buff *msg;
+ unsigned int wait = 0;
+ bool offchan;
if (!info->attrs[NL80211_ATTR_FRAME] ||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -4193,9 +4494,16 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
+ if (info->attrs[NL80211_ATTR_DURATION]) {
+ if (!rdev->ops->mgmt_tx_cancel_wait)
+ return -EINVAL;
+ wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
+ }
+
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
channel_type = nla_get_u32(
info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
@@ -4207,6 +4515,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
channel_type_valid = true;
}
+ offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
+
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = rdev_freq_to_chan(rdev, freq, channel_type);
if (chan == NULL)
@@ -4223,8 +4533,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
err = PTR_ERR(hdr);
goto free_msg;
}
- err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type,
- channel_type_valid,
+ err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
+ channel_type_valid, wait,
nla_data(info->attrs[NL80211_ATTR_FRAME]),
nla_len(info->attrs[NL80211_ATTR_FRAME]),
&cookie);
@@ -4243,6 +4553,31 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
return err;
}
+static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ u64 cookie;
+
+ if (!info->attrs[NL80211_ATTR_COOKIE])
+ return -EINVAL;
+
+ if (!rdev->ops->mgmt_tx_cancel_wait)
+ return -EOPNOTSUPP;
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
+
+ cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
+
+ return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie);
+}
+
static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4381,6 +4716,50 @@ out:
return err;
}
+static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct mesh_config cfg;
+ struct mesh_setup setup;
+ int err;
+
+ /* start with default */
+ memcpy(&cfg, &default_mesh_config, sizeof(cfg));
+ memcpy(&setup, &default_mesh_setup, sizeof(setup));
+
+ if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
+ /* and parse parameters if given */
+ err = nl80211_parse_mesh_config(info, &cfg, NULL);
+ if (err)
+ return err;
+ }
+
+ if (!info->attrs[NL80211_ATTR_MESH_ID] ||
+ !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
+ return -EINVAL;
+
+ setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
+ setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+
+ if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
+ /* parse additional setup parameters if given */
+ err = nl80211_parse_mesh_setup(info, &setup);
+ if (err)
+ return err;
+ }
+
+ return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
+}
+
+static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+
+ return cfg80211_leave_mesh(rdev, dev);
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -4636,19 +5015,19 @@ static struct genl_ops nl80211_ops[] = {
.flags = GENL_ADMIN_PERM,
},
{
- .cmd = NL80211_CMD_GET_MESH_PARAMS,
- .doit = nl80211_get_mesh_params,
+ .cmd = NL80211_CMD_GET_MESH_CONFIG,
+ .doit = nl80211_get_mesh_config,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
{
- .cmd = NL80211_CMD_SET_MESH_PARAMS,
- .doit = nl80211_set_mesh_params,
+ .cmd = NL80211_CMD_SET_MESH_CONFIG,
+ .doit = nl80211_update_mesh_config,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -4816,6 +5195,14 @@ static struct genl_ops nl80211_ops[] = {
NL80211_FLAG_NEED_RTNL,
},
{
+ .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
+ .doit = nl80211_tx_mgmt_cancel_wait,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
.cmd = NL80211_CMD_SET_POWER_SAVE,
.doit = nl80211_set_power_save,
.policy = nl80211_policy,
@@ -4855,6 +5242,22 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_JOIN_MESH,
+ .doit = nl80211_join_mesh,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_LEAVE_MESH,
+ .doit = nl80211_leave_mesh,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5133,6 +5536,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
NL80211_CMD_DISASSOCIATE, gfp);
}
+void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf,
+ size_t len, gfp_t gfp)
+{
+ nl80211_send_mlme_event(rdev, netdev, buf, len,
+ NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
+}
+
+void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf,
+ size_t len, gfp_t gfp)
+{
+ nl80211_send_mlme_event(rdev, netdev, buf, len,
+ NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
+}
+
static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
struct net_device *netdev, int cmd,
const u8 *addr, gfp_t gfp)
@@ -5651,6 +6070,51 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
nlmsg_free(msg);
}
+void
+nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *peer,
+ u32 num_packets, gfp_t gfp)
+{
+ struct sk_buff *msg;
+ struct nlattr *pinfoattr;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
+
+ pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
+ if (!pinfoattr)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets);
+
+ nla_nest_end(msg, pinfoattr);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
static int nl80211_netlink_notify(struct notifier_block * nb,
unsigned long state,
void *_notify)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 30d2f939150d..e3f7fa886966 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len, gfp_t gfp);
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *addr, gfp_t gfp);
@@ -87,5 +93,9 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
enum nl80211_cqm_rssi_threshold_event rssi_event,
gfp_t gfp);
+void
+nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *peer,
+ u32 num_packets, gfp_t gfp);
#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4b9f8912526c..37693b6ef23a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -32,6 +32,9 @@
* rely on some SHA1 checksum of the regdomain for example.
*
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/list.h>
@@ -48,7 +51,7 @@
#ifdef CONFIG_CFG80211_REG_DEBUG
#define REG_DBG_PRINT(format, args...) \
do { \
- printk(KERN_DEBUG format , ## args); \
+ printk(KERN_DEBUG pr_fmt(format), ##args); \
} while (0)
#else
#define REG_DBG_PRINT(args...)
@@ -96,6 +99,9 @@ struct reg_beacon {
struct ieee80211_channel chan;
};
+static void reg_todo(struct work_struct *work);
+static DECLARE_WORK(reg_work, reg_todo);
+
/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 5,
@@ -367,11 +373,10 @@ static int call_crda(const char *alpha2)
};
if (!is_world_regdom((char *) alpha2))
- printk(KERN_INFO "cfg80211: Calling CRDA for country: %c%c\n",
+ pr_info("Calling CRDA for country: %c%c\n",
alpha2[0], alpha2[1]);
else
- printk(KERN_INFO "cfg80211: Calling CRDA to update world "
- "regulatory domain\n");
+ pr_info("Calling CRDA to update world regulatory domain\n");
/* query internal regulatory database (if it exists) */
reg_regdb_query(alpha2);
@@ -656,7 +661,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
* Follow the driver's regulatory domain, if present, unless a country
* IE has been processed or a user wants to help complaince further
*/
- if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+ if (!custom_regd &&
+ last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
wiphy->regd)
regd = wiphy->regd;
@@ -711,6 +717,60 @@ int freq_reg_info(struct wiphy *wiphy,
}
EXPORT_SYMBOL(freq_reg_info);
+#ifdef CONFIG_CFG80211_REG_DEBUG
+static const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
+{
+ switch (initiator) {
+ case NL80211_REGDOM_SET_BY_CORE:
+ return "Set by core";
+ case NL80211_REGDOM_SET_BY_USER:
+ return "Set by user";
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ return "Set by driver";
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ return "Set by country IE";
+ default:
+ WARN_ON(1);
+ return "Set by bug";
+ }
+}
+
+static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+ u32 desired_bw_khz,
+ const struct ieee80211_reg_rule *reg_rule)
+{
+ const struct ieee80211_power_rule *power_rule;
+ const struct ieee80211_freq_range *freq_range;
+ char max_antenna_gain[32];
+
+ power_rule = &reg_rule->power_rule;
+ freq_range = &reg_rule->freq_range;
+
+ if (!power_rule->max_antenna_gain)
+ snprintf(max_antenna_gain, 32, "N/A");
+ else
+ snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);
+
+ REG_DBG_PRINT("Updating information on frequency %d MHz "
+ "for a %d MHz width channel with regulatory rule:\n",
+ chan->center_freq,
+ KHZ_TO_MHZ(desired_bw_khz));
+
+ REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n",
+ freq_range->start_freq_khz,
+ freq_range->end_freq_khz,
+ max_antenna_gain,
+ power_rule->max_eirp);
+}
+#else
+static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+ u32 desired_bw_khz,
+ const struct ieee80211_reg_rule *reg_rule)
+{
+ return;
+}
+#endif
+
/*
* Note that right now we assume the desired channel bandwidth
* is always 20 MHz for each individual channel (HT40 uses 20 MHz
@@ -720,7 +780,9 @@ EXPORT_SYMBOL(freq_reg_info);
* on the wiphy with the target_bw specified. Then we can simply use
* that below for the desired_bw_khz below.
*/
-static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
+static void handle_channel(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator,
+ enum ieee80211_band band,
unsigned int chan_idx)
{
int r;
@@ -748,8 +810,27 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
desired_bw_khz,
&reg_rule);
- if (r)
+ if (r) {
+ /*
+ * We will disable all channels that do not match our
+ * recieved regulatory rule unless the hint is coming
+ * from a Country IE and the Country IE had no information
+ * about a band. The IEEE 802.11 spec allows for an AP
+ * to send only a subset of the regulatory rules allowed,
+ * so an AP in the US that only supports 2.4 GHz may only send
+ * a country IE with information for the 2.4 GHz band
+ * while 5 GHz is still supported.
+ */
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+ r == -ERANGE)
+ return;
+
+ REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
+ chan->flags = IEEE80211_CHAN_DISABLED;
return;
+ }
+
+ chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
power_rule = &reg_rule->power_rule;
freq_range = &reg_rule->freq_range;
@@ -784,7 +865,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
}
-static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
+static void handle_band(struct wiphy *wiphy,
+ enum ieee80211_band band,
+ enum nl80211_reg_initiator initiator)
{
unsigned int i;
struct ieee80211_supported_band *sband;
@@ -793,24 +876,42 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels; i++)
- handle_channel(wiphy, band, i);
+ handle_channel(wiphy, initiator, band, i);
}
static bool ignore_reg_update(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
- if (!last_request)
+ if (!last_request) {
+ REG_DBG_PRINT("Ignoring regulatory request %s since "
+ "last_request is not set\n",
+ reg_initiator_name(initiator));
return true;
+ }
+
if (initiator == NL80211_REGDOM_SET_BY_CORE &&
- wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
+ wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
+ REG_DBG_PRINT("Ignoring regulatory request %s "
+ "since the driver uses its own custom "
+ "regulatory domain ",
+ reg_initiator_name(initiator));
return true;
+ }
+
/*
* wiphy->regd will be set once the device has its own
* desired regulatory domain set
*/
if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd &&
- !is_world_regdom(last_request->alpha2))
+ initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+ !is_world_regdom(last_request->alpha2)) {
+ REG_DBG_PRINT("Ignoring regulatory request %s "
+ "since the driver requires its own regulaotry "
+ "domain to be set first",
+ reg_initiator_name(initiator));
return true;
+ }
+
return false;
}
@@ -1030,7 +1131,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
goto out;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (wiphy->bands[band])
- handle_band(wiphy, band);
+ handle_band(wiphy, band, initiator);
}
out:
reg_process_beacons(wiphy);
@@ -1066,10 +1167,17 @@ static void handle_channel_custom(struct wiphy *wiphy,
regd);
if (r) {
+ REG_DBG_PRINT("Disabling freq %d MHz as custom "
+ "regd has no rule that fits a %d MHz "
+ "wide channel\n",
+ chan->center_freq,
+ KHZ_TO_MHZ(desired_bw_khz));
chan->flags = IEEE80211_CHAN_DISABLED;
return;
}
+ chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
+
power_rule = &reg_rule->power_rule;
freq_range = &reg_rule->freq_range;
@@ -1215,6 +1323,21 @@ static int ignore_request(struct wiphy *wiphy,
return -EINVAL;
}
+static void reg_set_request_processed(void)
+{
+ bool need_more_processing = false;
+
+ last_request->processed = true;
+
+ spin_lock(&reg_requests_lock);
+ if (!list_empty(&reg_requests_list))
+ need_more_processing = true;
+ spin_unlock(&reg_requests_lock);
+
+ if (need_more_processing)
+ schedule_work(&reg_work);
+}
+
/**
* __regulatory_hint - hint to the wireless core a regulatory domain
* @wiphy: if the hint comes from country information from an AP, this
@@ -1290,8 +1413,10 @@ new_request:
* have applied the requested regulatory domain before we just
* inform userspace we have processed the request
*/
- if (r == -EALREADY)
+ if (r == -EALREADY) {
nl80211_send_reg_change_event(last_request);
+ reg_set_request_processed();
+ }
return r;
}
@@ -1307,16 +1432,13 @@ static void reg_process_hint(struct regulatory_request *reg_request)
BUG_ON(!reg_request->alpha2);
- mutex_lock(&cfg80211_mutex);
- mutex_lock(&reg_mutex);
-
if (wiphy_idx_valid(reg_request->wiphy_idx))
wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
!wiphy) {
kfree(reg_request);
- goto out;
+ return;
}
r = __regulatory_hint(wiphy, reg_request);
@@ -1324,28 +1446,46 @@ static void reg_process_hint(struct regulatory_request *reg_request)
if (r == -EALREADY && wiphy &&
wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
wiphy_update_regulatory(wiphy, initiator);
-out:
- mutex_unlock(&reg_mutex);
- mutex_unlock(&cfg80211_mutex);
}
-/* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */
+/*
+ * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_*
+ * Regulatory hints come on a first come first serve basis and we
+ * must process each one atomically.
+ */
static void reg_process_pending_hints(void)
- {
+{
struct regulatory_request *reg_request;
+ mutex_lock(&cfg80211_mutex);
+ mutex_lock(&reg_mutex);
+
+ /* When last_request->processed becomes true this will be rescheduled */
+ if (last_request && !last_request->processed) {
+ REG_DBG_PRINT("Pending regulatory request, waiting "
+ "for it to be processed...");
+ goto out;
+ }
+
spin_lock(&reg_requests_lock);
- while (!list_empty(&reg_requests_list)) {
- reg_request = list_first_entry(&reg_requests_list,
- struct regulatory_request,
- list);
- list_del_init(&reg_request->list);
+ if (list_empty(&reg_requests_list)) {
spin_unlock(&reg_requests_lock);
- reg_process_hint(reg_request);
- spin_lock(&reg_requests_lock);
+ goto out;
}
+
+ reg_request = list_first_entry(&reg_requests_list,
+ struct regulatory_request,
+ list);
+ list_del_init(&reg_request->list);
+
spin_unlock(&reg_requests_lock);
+
+ reg_process_hint(reg_request);
+
+out:
+ mutex_unlock(&reg_mutex);
+ mutex_unlock(&cfg80211_mutex);
}
/* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1392,8 +1532,6 @@ static void reg_todo(struct work_struct *work)
reg_process_pending_beacon_hints();
}
-static DECLARE_WORK(reg_work, reg_todo);
-
static void queue_regulatory_request(struct regulatory_request *request)
{
if (isalpha(request->alpha2[0]))
@@ -1428,12 +1566,7 @@ static int regulatory_hint_core(const char *alpha2)
request->alpha2[1] = alpha2[1];
request->initiator = NL80211_REGDOM_SET_BY_CORE;
- /*
- * This ensures last_request is populated once modules
- * come swinging in and calling regulatory hints and
- * wiphy_apply_custom_regulatory().
- */
- reg_process_hint(request);
+ queue_regulatory_request(request);
return 0;
}
@@ -1559,7 +1692,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
if (is_user_regdom_saved()) {
/* Unless we're asked to ignore it and reset it */
if (reset_user) {
- REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
+ REG_DBG_PRINT("Restoring regulatory settings "
"including user preference\n");
user_alpha2[0] = '9';
user_alpha2[1] = '7';
@@ -1570,7 +1703,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
* back as they were for a full restore.
*/
if (!is_world_regdom(ieee80211_regdom)) {
- REG_DBG_PRINT("cfg80211: Keeping preference on "
+ REG_DBG_PRINT("Keeping preference on "
"module parameter ieee80211_regdom: %c%c\n",
ieee80211_regdom[0],
ieee80211_regdom[1]);
@@ -1578,7 +1711,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
alpha2[1] = ieee80211_regdom[1];
}
} else {
- REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
+ REG_DBG_PRINT("Restoring regulatory settings "
"while preserving user preference for: %c%c\n",
user_alpha2[0],
user_alpha2[1]);
@@ -1586,14 +1719,14 @@ static void restore_alpha2(char *alpha2, bool reset_user)
alpha2[1] = user_alpha2[1];
}
} else if (!is_world_regdom(ieee80211_regdom)) {
- REG_DBG_PRINT("cfg80211: Keeping preference on "
+ REG_DBG_PRINT("Keeping preference on "
"module parameter ieee80211_regdom: %c%c\n",
ieee80211_regdom[0],
ieee80211_regdom[1]);
alpha2[0] = ieee80211_regdom[0];
alpha2[1] = ieee80211_regdom[1];
} else
- REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n");
+ REG_DBG_PRINT("Restoring regulatory settings\n");
}
/*
@@ -1661,7 +1794,7 @@ static void restore_regulatory_settings(bool reset_user)
void regulatory_hint_disconnect(void)
{
- REG_DBG_PRINT("cfg80211: All devices are disconnected, going to "
+ REG_DBG_PRINT("All devices are disconnected, going to "
"restore regulatory settings\n");
restore_regulatory_settings(false);
}
@@ -1691,7 +1824,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
if (!reg_beacon)
return -ENOMEM;
- REG_DBG_PRINT("cfg80211: Found new beacon on "
+ REG_DBG_PRINT("Found new beacon on "
"frequency: %d MHz (Ch %d) on %s\n",
beacon_chan->center_freq,
ieee80211_frequency_to_channel(beacon_chan->center_freq),
@@ -1721,8 +1854,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
const struct ieee80211_freq_range *freq_range = NULL;
const struct ieee80211_power_rule *power_rule = NULL;
- printk(KERN_INFO " (start_freq - end_freq @ bandwidth), "
- "(max_antenna_gain, max_eirp)\n");
+ pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n");
for (i = 0; i < rd->n_reg_rules; i++) {
reg_rule = &rd->reg_rules[i];
@@ -1734,16 +1866,14 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
* in certain regions
*/
if (power_rule->max_antenna_gain)
- printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
- "(%d mBi, %d mBm)\n",
+ pr_info(" (%d KHz - %d KHz @ %d KHz), (%d mBi, %d mBm)\n",
freq_range->start_freq_khz,
freq_range->end_freq_khz,
freq_range->max_bandwidth_khz,
power_rule->max_antenna_gain,
power_rule->max_eirp);
else
- printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
- "(N/A, %d mBm)\n",
+ pr_info(" (%d KHz - %d KHz @ %d KHz), (N/A, %d mBm)\n",
freq_range->start_freq_khz,
freq_range->end_freq_khz,
freq_range->max_bandwidth_khz,
@@ -1762,27 +1892,20 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
rdev = cfg80211_rdev_by_wiphy_idx(
last_request->wiphy_idx);
if (rdev) {
- printk(KERN_INFO "cfg80211: Current regulatory "
- "domain updated by AP to: %c%c\n",
+ pr_info("Current regulatory domain updated by AP to: %c%c\n",
rdev->country_ie_alpha2[0],
rdev->country_ie_alpha2[1]);
} else
- printk(KERN_INFO "cfg80211: Current regulatory "
- "domain intersected:\n");
+ pr_info("Current regulatory domain intersected:\n");
} else
- printk(KERN_INFO "cfg80211: Current regulatory "
- "domain intersected:\n");
+ pr_info("Current regulatory domain intersected:\n");
} else if (is_world_regdom(rd->alpha2))
- printk(KERN_INFO "cfg80211: World regulatory "
- "domain updated:\n");
+ pr_info("World regulatory domain updated:\n");
else {
if (is_unknown_alpha2(rd->alpha2))
- printk(KERN_INFO "cfg80211: Regulatory domain "
- "changed to driver built-in settings "
- "(unknown country)\n");
+ pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n");
else
- printk(KERN_INFO "cfg80211: Regulatory domain "
- "changed to country: %c%c\n",
+ pr_info("Regulatory domain changed to country: %c%c\n",
rd->alpha2[0], rd->alpha2[1]);
}
print_rd_rules(rd);
@@ -1790,8 +1913,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
static void print_regdomain_info(const struct ieee80211_regdomain *rd)
{
- printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
- rd->alpha2[0], rd->alpha2[1]);
+ pr_info("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]);
print_rd_rules(rd);
}
@@ -1842,8 +1964,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
return -EINVAL;
if (!is_valid_rd(rd)) {
- printk(KERN_ERR "cfg80211: Invalid "
- "regulatory domain detected:\n");
+ pr_err("Invalid regulatory domain detected:\n");
print_regdomain_info(rd);
return -EINVAL;
}
@@ -1959,6 +2080,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
nl80211_send_reg_change_event(last_request);
+ reg_set_request_processed();
+
mutex_unlock(&reg_mutex);
return r;
@@ -2015,8 +2138,7 @@ int __init regulatory_init(void)
* early boot for call_usermodehelper(). For now treat these
* errors as non-fatal.
*/
- printk(KERN_ERR "cfg80211: kobject_uevent_env() was unable "
- "to call CRDA during init");
+ pr_err("kobject_uevent_env() was unable to call CRDA during init\n");
#ifdef CONFIG_CFG80211_REG_DEBUG
/* We want to find out exactly why when debugging */
WARN_ON(err);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 503ebb86ba18..ea427f418f64 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
if (res->pub.beacon_ies) {
size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
size_t ielen = res->pub.len_beacon_ies;
+ bool information_elements_is_beacon_ies =
+ (found->pub.information_elements ==
+ found->pub.beacon_ies);
if (found->pub.beacon_ies &&
!found->beacon_ies_allocated &&
@@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
found->pub.len_beacon_ies = ielen;
}
}
+
+ /* Override IEs if they were from a beacon before */
+ if (information_elements_is_beacon_ies) {
+ found->pub.information_elements =
+ found->pub.beacon_ies;
+ found->pub.len_information_elements =
+ found->pub.len_beacon_ies;
+ }
}
kref_put(&res->ref, bss_release);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 76120aeda57d..7620ae2fcf18 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -502,7 +502,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
skb_orphan(skb);
if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) {
- printk(KERN_ERR "failed to reallocate Tx buffer\n");
+ pr_err("failed to reallocate Tx buffer\n");
return -ENOMEM;
}
skb->truesize += head_need;
@@ -685,20 +685,18 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
continue;
if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
&wdev->connect_keys->params[i])) {
- printk(KERN_ERR "%s: failed to set key %d\n",
- dev->name, i);
+ netdev_err(dev, "failed to set key %d\n", i);
continue;
}
if (wdev->connect_keys->def == i)
- if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
- printk(KERN_ERR "%s: failed to set defkey %d\n",
- dev->name, i);
+ if (rdev->ops->set_default_key(wdev->wiphy, dev,
+ i, true, true)) {
+ netdev_err(dev, "failed to set defkey %d\n", i);
continue;
}
if (wdev->connect_keys->defmgmt == i)
if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i))
- printk(KERN_ERR "%s: failed to set mgtdef %d\n",
- dev->name, i);
+ netdev_err(dev, "failed to set mgtdef %d\n", i);
}
kfree(wdev->connect_keys);
@@ -795,6 +793,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
if (ntype != otype) {
dev->ieee80211_ptr->use_4addr = false;
+ dev->ieee80211_ptr->mesh_id_up_len = 0;
switch (otype) {
case NL80211_IFTYPE_ADHOC:
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 12222ee6ebf2..3e5dbd4e4cd5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
__cfg80211_leave_ibss(rdev, wdev->netdev, true);
rejoin = true;
}
- err = rdev->ops->set_default_key(&rdev->wiphy,
- dev, idx);
+ err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+ idx, true, true);
}
if (!err) {
wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_device *dev,
err = 0;
wdev_lock(wdev);
if (wdev->current_bss)
- err = rdev->ops->set_default_key(&rdev->wiphy,
- dev, idx);
+ err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+ idx, true, true);
if (!err)
wdev->wext.default_key = idx;
wdev_unlock(wdev);
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index dc675a3daa3d..fdbc23c10d8c 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -467,8 +467,8 @@ void wireless_send_event(struct net_device * dev,
* The best the driver could do is to log an error message.
* We will do it ourselves instead...
*/
- printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n",
- dev->name, cmd);
+ netdev_err(dev, "(WE) : Invalid/Unknown Wireless Event (0x%04X)\n",
+ cmd);
return;
}
@@ -476,11 +476,13 @@ void wireless_send_event(struct net_device * dev,
if (descr->header_type == IW_HEADER_TYPE_POINT) {
/* Check if number of token fits within bounds */
if (wrqu->data.length > descr->max_tokens) {
- printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length);
+ netdev_err(dev, "(WE) : Wireless Event too big (%d)\n",
+ wrqu->data.length);
return;
}
if (wrqu->data.length < descr->min_tokens) {
- printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length);
+ netdev_err(dev, "(WE) : Wireless Event too small (%d)\n",
+ wrqu->data.length);
return;
}
/* Calculate extra_len - extra is NULL for restricted events */
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index f7af98dff409..ad96ee90fe27 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1357,11 +1357,11 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int rc;
- lock_kernel();
switch (cmd) {
case TIOCOUTQ: {
- int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
+ int amount;
+ amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0)
amount = 0;
rc = put_user(amount, (unsigned int __user *)argp);
@@ -1375,8 +1375,10 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
* These two are safe on a single CPU system as
* only user tasks fiddle here
*/
+ lock_sock(sk);
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
+ release_sock(sk);
rc = put_user(amount, (unsigned int __user *)argp);
break;
}
@@ -1422,9 +1424,11 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = x25_subscr_ioctl(cmd, argp);
break;
case SIOCX25GFACILITIES: {
- struct x25_facilities fac = x25->facilities;
- rc = copy_to_user(argp, &fac,
- sizeof(fac)) ? -EFAULT : 0;
+ lock_sock(sk);
+ rc = copy_to_user(argp, &x25->facilities,
+ sizeof(x25->facilities))
+ ? -EFAULT : 0;
+ release_sock(sk);
break;
}
@@ -1435,18 +1439,19 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
sizeof(facilities)))
break;
rc = -EINVAL;
+ lock_sock(sk);
if (sk->sk_state != TCP_LISTEN &&
sk->sk_state != TCP_CLOSE)
- break;
+ goto out_fac_release;
if (facilities.pacsize_in < X25_PS16 ||
facilities.pacsize_in > X25_PS4096)
- break;
+ goto out_fac_release;
if (facilities.pacsize_out < X25_PS16 ||
facilities.pacsize_out > X25_PS4096)
- break;
+ goto out_fac_release;
if (facilities.winsize_in < 1 ||
facilities.winsize_in > 127)
- break;
+ goto out_fac_release;
if (facilities.throughput) {
int out = facilities.throughput & 0xf0;
int in = facilities.throughput & 0x0f;
@@ -1454,24 +1459,28 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
facilities.throughput |=
X25_DEFAULT_THROUGHPUT << 4;
else if (out < 0x30 || out > 0xD0)
- break;
+ goto out_fac_release;
if (!in)
facilities.throughput |=
X25_DEFAULT_THROUGHPUT;
else if (in < 0x03 || in > 0x0D)
- break;
+ goto out_fac_release;
}
if (facilities.reverse &&
(facilities.reverse & 0x81) != 0x81)
- break;
+ goto out_fac_release;
x25->facilities = facilities;
rc = 0;
+out_fac_release:
+ release_sock(sk);
break;
}
case SIOCX25GDTEFACILITIES: {
+ lock_sock(sk);
rc = copy_to_user(argp, &x25->dte_facilities,
sizeof(x25->dte_facilities));
+ release_sock(sk);
if (rc)
rc = -EFAULT;
break;
@@ -1483,26 +1492,31 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
break;
rc = -EINVAL;
+ lock_sock(sk);
if (sk->sk_state != TCP_LISTEN &&
sk->sk_state != TCP_CLOSE)
- break;
+ goto out_dtefac_release;
if (dtefacs.calling_len > X25_MAX_AE_LEN)
- break;
+ goto out_dtefac_release;
if (dtefacs.calling_ae == NULL)
- break;
+ goto out_dtefac_release;
if (dtefacs.called_len > X25_MAX_AE_LEN)
- break;
+ goto out_dtefac_release;
if (dtefacs.called_ae == NULL)
- break;
+ goto out_dtefac_release;
x25->dte_facilities = dtefacs;
rc = 0;
+out_dtefac_release:
+ release_sock(sk);
break;
}
case SIOCX25GCALLUSERDATA: {
- struct x25_calluserdata cud = x25->calluserdata;
- rc = copy_to_user(argp, &cud,
- sizeof(cud)) ? -EFAULT : 0;
+ lock_sock(sk);
+ rc = copy_to_user(argp, &x25->calluserdata,
+ sizeof(x25->calluserdata))
+ ? -EFAULT : 0;
+ release_sock(sk);
break;
}
@@ -1516,16 +1530,19 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -EINVAL;
if (calluserdata.cudlength > X25_MAX_CUD_LEN)
break;
+ lock_sock(sk);
x25->calluserdata = calluserdata;
+ release_sock(sk);
rc = 0;
break;
}
case SIOCX25GCAUSEDIAG: {
- struct x25_causediag causediag;
- causediag = x25->causediag;
- rc = copy_to_user(argp, &causediag,
- sizeof(causediag)) ? -EFAULT : 0;
+ lock_sock(sk);
+ rc = copy_to_user(argp, &x25->causediag,
+ sizeof(x25->causediag))
+ ? -EFAULT : 0;
+ release_sock(sk);
break;
}
@@ -1534,7 +1551,9 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -EFAULT;
if (copy_from_user(&causediag, argp, sizeof(causediag)))
break;
+ lock_sock(sk);
x25->causediag = causediag;
+ release_sock(sk);
rc = 0;
break;
@@ -1543,31 +1562,37 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCX25SCUDMATCHLEN: {
struct x25_subaddr sub_addr;
rc = -EINVAL;
+ lock_sock(sk);
if(sk->sk_state != TCP_CLOSE)
- break;
+ goto out_cud_release;
rc = -EFAULT;
if (copy_from_user(&sub_addr, argp,
sizeof(sub_addr)))
- break;
+ goto out_cud_release;
rc = -EINVAL;
if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
- break;
+ goto out_cud_release;
x25->cudmatchlength = sub_addr.cudmatchlength;
rc = 0;
+out_cud_release:
+ release_sock(sk);
break;
}
case SIOCX25CALLACCPTAPPRV: {
rc = -EINVAL;
+ lock_kernel();
if (sk->sk_state != TCP_CLOSE)
break;
clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);
+ unlock_kernel();
rc = 0;
break;
}
case SIOCX25SENDCALLACCPT: {
rc = -EINVAL;
+ lock_kernel();
if (sk->sk_state != TCP_ESTABLISHED)
break;
/* must call accptapprv above */
@@ -1575,6 +1600,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
x25_write_internal(sk, X25_CALL_ACCEPTED);
x25->state = X25_STATE_3;
+ unlock_kernel();
rc = 0;
break;
}
@@ -1583,7 +1609,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
return rc;
}
@@ -1619,16 +1644,20 @@ static int compat_x25_subscr_ioctl(unsigned int cmd,
dev_put(dev);
if (cmd == SIOCX25GSUBSCRIP) {
+ read_lock_bh(&x25_neigh_list_lock);
x25_subscr.extended = nb->extended;
x25_subscr.global_facil_mask = nb->global_facil_mask;
+ read_unlock_bh(&x25_neigh_list_lock);
rc = copy_to_user(x25_subscr32, &x25_subscr,
sizeof(*x25_subscr32)) ? -EFAULT : 0;
} else {
rc = -EINVAL;
if (x25_subscr.extended == 0 || x25_subscr.extended == 1) {
rc = 0;
+ write_lock_bh(&x25_neigh_list_lock);
nb->extended = x25_subscr.extended;
nb->global_facil_mask = x25_subscr.global_facil_mask;
+ write_unlock_bh(&x25_neigh_list_lock);
}
}
x25_neigh_put(nb);
@@ -1654,19 +1683,15 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
break;
case SIOCGSTAMP:
rc = -EINVAL;
- lock_kernel();
if (sk)
rc = compat_sock_get_timestamp(sk,
(struct timeval __user*)argp);
- unlock_kernel();
break;
case SIOCGSTAMPNS:
rc = -EINVAL;
- lock_kernel();
if (sk)
rc = compat_sock_get_timestampns(sk,
(struct timespec __user*)argp);
- unlock_kernel();
break;
case SIOCGIFADDR:
case SIOCSIFADDR:
@@ -1685,22 +1710,16 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
- lock_kernel();
rc = x25_route_ioctl(cmd, argp);
- unlock_kernel();
break;
case SIOCX25GSUBSCRIP:
- lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp);
- unlock_kernel();
break;
case SIOCX25SSUBSCRIP:
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
- lock_kernel();
rc = compat_x25_subscr_ioctl(cmd, argp);
- unlock_kernel();
break;
case SIOCX25GFACILITIES:
case SIOCX25SFACILITIES:
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index 73e7b954ad28..4cbc942f762a 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -31,8 +31,8 @@
#include <linux/init.h>
#include <net/x25.h>
-static LIST_HEAD(x25_neigh_list);
-static DEFINE_RWLOCK(x25_neigh_list_lock);
+LIST_HEAD(x25_neigh_list);
+DEFINE_RWLOCK(x25_neigh_list_lock);
static void x25_t20timer_expiry(unsigned long);
@@ -360,16 +360,20 @@ int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
dev_put(dev);
if (cmd == SIOCX25GSUBSCRIP) {
+ read_lock_bh(&x25_neigh_list_lock);
x25_subscr.extended = nb->extended;
x25_subscr.global_facil_mask = nb->global_facil_mask;
+ read_unlock_bh(&x25_neigh_list_lock);
rc = copy_to_user(arg, &x25_subscr,
sizeof(x25_subscr)) ? -EFAULT : 0;
} else {
rc = -EINVAL;
if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
rc = 0;
+ write_lock_bh(&x25_neigh_list_lock);
nb->extended = x25_subscr.extended;
nb->global_facil_mask = x25_subscr.global_facil_mask;
+ write_unlock_bh(&x25_neigh_list_lock);
}
}
x25_neigh_put(nb);
@@ -394,6 +398,7 @@ void __exit x25_link_free(void)
list_for_each_safe(entry, tmp, &x25_neigh_list) {
nb = list_entry(entry, struct x25_neigh, node);
__x25_remove_neigh(nb);
+ dev_put(nb->dev);
}
write_unlock_bh(&x25_neigh_list_lock);
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 044e77898512..8b3ef404c794 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1433,7 +1433,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
}
xdst->route = dst;
- memcpy(&dst1->metrics, &dst->metrics, sizeof(dst->metrics));
+ dst_copy_metrics(dst1, dst);
if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
family = xfrm[i]->props.family;
@@ -2271,7 +2271,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst)
if (pmtu > route_mtu_cached)
pmtu = route_mtu_cached;
- dst->metrics[RTAX_MTU-1] = pmtu;
+ dst_metric_set(dst, RTAX_MTU, pmtu);
} while ((dst = dst->next));
}
@@ -2349,7 +2349,7 @@ static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
mtu = xfrm_state_mtu(dst->xfrm, mtu);
if (mtu > last->route_mtu_cached)
mtu = last->route_mtu_cached;
- dst->metrics[RTAX_MTU-1] = mtu;
+ dst_metric_set(dst, RTAX_MTU, mtu);
if (last == first)
break;
@@ -2361,6 +2361,16 @@ static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
return 1;
}
+static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
+{
+ return dst_metric_advmss(dst->path);
+}
+
+static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
+{
+ return dst_mtu(dst->path);
+}
+
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
struct net *net;
@@ -2378,6 +2388,10 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->kmem_cachep = xfrm_dst_cache;
if (likely(dst_ops->check == NULL))
dst_ops->check = xfrm_dst_check;
+ if (likely(dst_ops->default_advmss == NULL))
+ dst_ops->default_advmss = xfrm_default_advmss;
+ if (likely(dst_ops->default_mtu == NULL))
+ dst_ops->default_mtu = xfrm_default_mtu;
if (likely(dst_ops->negative_advice == NULL))
dst_ops->negative_advice = xfrm_negative_advice;
if (likely(dst_ops->link_failure == NULL))
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index eb96ce52f178..220ebc05c7af 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
return xc;
error:
- kfree(xc);
+ xfrm_state_put(xc);
return NULL;
}
EXPORT_SYMBOL(xfrm_state_migrate);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8bae6b22c846..8eb889510916 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -148,7 +148,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
!attrs[XFRMA_ALG_AUTH_TRUNC]) ||
attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_CRYPT] ||
- attrs[XFRMA_ALG_COMP])
+ attrs[XFRMA_ALG_COMP] ||
+ attrs[XFRMA_TFCPAD])
goto out;
break;
@@ -165,6 +166,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_CRYPT]) &&
attrs[XFRMA_ALG_AEAD])
goto out;
+ if (attrs[XFRMA_TFCPAD] &&
+ p->mode != XFRM_MODE_TUNNEL)
+ goto out;
break;
case IPPROTO_COMP:
@@ -172,7 +176,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_AUTH] ||
attrs[XFRMA_ALG_AUTH_TRUNC] ||
- attrs[XFRMA_ALG_CRYPT])
+ attrs[XFRMA_ALG_CRYPT] ||
+ attrs[XFRMA_TFCPAD])
goto out;
break;
@@ -186,6 +191,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ENCAP] ||
attrs[XFRMA_SEC_CTX] ||
+ attrs[XFRMA_TFCPAD] ||
!attrs[XFRMA_COADDR])
goto out;
break;
@@ -439,6 +445,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
goto error;
}
+ if (attrs[XFRMA_TFCPAD])
+ x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]);
+
if (attrs[XFRMA_COADDR]) {
x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
sizeof(*x->coaddr), GFP_KERNEL);
@@ -688,6 +697,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
if (x->encap)
NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+ if (x->tfcpad)
+ NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad);
+
if (xfrm_mark_put(skb, &x->mark))
goto nla_put_failure;
@@ -2122,6 +2134,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
[XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
[XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) },
[XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) },
+ [XFRMA_TFCPAD] = { .type = NLA_U32 },
};
static struct xfrm_link {
@@ -2301,6 +2314,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
l += nla_total_size(sizeof(*x->calg));
if (x->encap)
l += nla_total_size(sizeof(*x->encap));
+ if (x->tfcpad)
+ l += nla_total_size(sizeof(x->tfcpad));
if (x->security)
l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) +
x->security->ctx_len);
diff --git a/scripts/.gitignore b/scripts/.gitignore
index c5d5db54c009..e2741d23bab8 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -7,3 +7,4 @@ pnmtologo
bin2c
unifdef
ihex2fw
+recordmcount
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index ea26b23de082..c9a16abacab4 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -138,38 +138,36 @@ static void print_cmdline(void)
printf("cmd_%s := %s\n\n", target, cmdline);
}
-char * str_config = NULL;
-int size_config = 0;
-int len_config = 0;
+struct item {
+ struct item *next;
+ unsigned int len;
+ unsigned int hash;
+ char name[0];
+};
-/*
- * Grow the configuration string to a desired length.
- * Usually the first growth is plenty.
- */
-static void grow_config(int len)
-{
- while (len_config + len > size_config) {
- if (size_config == 0)
- size_config = 2048;
- str_config = realloc(str_config, size_config *= 2);
- if (str_config == NULL)
- { perror("fixdep:malloc"); exit(1); }
- }
-}
+#define HASHSZ 256
+static struct item *hashtab[HASHSZ];
+static unsigned int strhash(const char *str, unsigned int sz)
+{
+ /* fnv32 hash */
+ unsigned int i, hash = 2166136261U;
+ for (i = 0; i < sz; i++)
+ hash = (hash ^ str[i]) * 0x01000193;
+ return hash;
+}
/*
* Lookup a value in the configuration string.
*/
-static int is_defined_config(const char * name, int len)
+static int is_defined_config(const char *name, int len, unsigned int hash)
{
- const char * pconfig;
- const char * plast = str_config + len_config - len;
- for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
- if (pconfig[ -1] == '\n'
- && pconfig[len] == '\n'
- && !memcmp(pconfig, name, len))
+ struct item *aux;
+
+ for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) {
+ if (aux->hash == hash && aux->len == len &&
+ memcmp(aux->name, name, len) == 0)
return 1;
}
return 0;
@@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len)
/*
* Add a new value to the configuration string.
*/
-static void define_config(const char * name, int len)
+static void define_config(const char *name, int len, unsigned int hash)
{
- grow_config(len + 1);
+ struct item *aux = malloc(sizeof(*aux) + len);
- memcpy(str_config+len_config, name, len);
- len_config += len;
- str_config[len_config++] = '\n';
+ if (!aux) {
+ perror("fixdep:malloc");
+ exit(1);
+ }
+ memcpy(aux->name, name, len);
+ aux->len = len;
+ aux->hash = hash;
+ aux->next = hashtab[hash % HASHSZ];
+ hashtab[hash % HASHSZ] = aux;
}
/*
@@ -192,40 +196,49 @@ static void define_config(const char * name, int len)
*/
static void clear_config(void)
{
- len_config = 0;
- define_config("", 0);
+ struct item *aux, *next;
+ unsigned int i;
+
+ for (i = 0; i < HASHSZ; i++) {
+ for (aux = hashtab[i]; aux; aux = next) {
+ next = aux->next;
+ free(aux);
+ }
+ hashtab[i] = NULL;
+ }
}
/*
* Record the use of a CONFIG_* word.
*/
-static void use_config(char *m, int slen)
+static void use_config(const char *m, int slen)
{
- char s[PATH_MAX];
- char *p;
+ unsigned int hash = strhash(m, slen);
+ int c, i;
- if (is_defined_config(m, slen))
+ if (is_defined_config(m, slen, hash))
return;
- define_config(m, slen);
+ define_config(m, slen, hash);
- memcpy(s, m, slen); s[slen] = 0;
-
- for (p = s; p < s + slen; p++) {
- if (*p == '_')
- *p = '/';
+ printf(" $(wildcard include/config/");
+ for (i = 0; i < slen; i++) {
+ c = m[i];
+ if (c == '_')
+ c = '/';
else
- *p = tolower((int)*p);
+ c = tolower(c);
+ putchar(c);
}
- printf(" $(wildcard include/config/%s.h) \\\n", s);
+ printf(".h) \\\n");
}
-static void parse_config_file(char *map, size_t len)
+static void parse_config_file(const char *map, size_t len)
{
- int *end = (int *) (map + len);
+ const int *end = (const int *) (map + len);
/* start at +1, so that p can never be < map */
- int *m = (int *) map + 1;
- char *p, *q;
+ const int *m = (const int *) map + 1;
+ const char *p, *q;
for (; m < end; m++) {
if (*m == INT_CONF) { p = (char *) m ; goto conf; }
@@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub)
return memcmp(s + slen - sublen, sub, sublen);
}
-static void do_config_file(char *filename)
+static void do_config_file(const char *filename)
{
struct stat st;
int fd;
@@ -273,7 +286,7 @@ static void do_config_file(char *filename)
fd = open(filename, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "fixdep: ");
+ fprintf(stderr, "fixdep: error opening config file: ");
perror(filename);
exit(2);
}
@@ -344,11 +357,15 @@ static void print_deps(void)
fd = open(depfile, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "fixdep: ");
+ fprintf(stderr, "fixdep: error opening depfile: ");
perror(depfile);
exit(2);
}
- fstat(fd, &st);
+ if (fstat(fd, &st) < 0) {
+ fprintf(stderr, "fixdep: error fstat'ing depfile: ");
+ perror(depfile);
+ exit(2);
+ }
if (st.st_size == 0) {
fprintf(stderr,"fixdep: %s is empty\n",depfile);
close(fd);
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
index 6bb42e72e0e5..3ab316e52313 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -6,7 +6,7 @@
# and listed below so they are ignored.
#
# Usage:
-# syscallchk gcc gcc-options
+# checksyscalls.sh gcc gcc-options
#
ignore_list() {
@@ -204,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\
\#endif/p' $1
}
-(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \
+(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \
$* -E -x c - > /dev/null
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci
index 55d7dc19dfe0..156b20adb351 100644
--- a/scripts/coccinelle/misc/doubleinit.cocci
+++ b/scripts/coccinelle/misc/doubleinit.cocci
@@ -7,7 +7,7 @@
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
// URL: http://coccinelle.lip6.fr/
-// Comments:
+// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
// Options: -no_includes -include_headers
virtual org
@@ -19,7 +19,7 @@ position p0,p;
expression E;
@@
-struct I s =@p0 { ... .fld@p = E, ...};
+struct I s =@p0 { ..., .fld@p = E, ...};
@s@
identifier I, s, r.fld;
@@ -27,7 +27,7 @@ position r.p0,p;
expression E;
@@
-struct I s =@p0 { ... .fld@p = E, ...};
+struct I s =@p0 { ..., .fld@p = E, ...};
@script:python depends on org@
p0 << r.p0;
diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci
index 9969d76d0f4b..cdac6cfcce92 100644
--- a/scripts/coccinelle/null/deref_null.cocci
+++ b/scripts/coccinelle/null/deref_null.cocci
@@ -11,21 +11,10 @@
// Options:
virtual context
-virtual patch
virtual org
virtual report
-@initialize:python depends on !context && patch && !org && !report@
-
-import sys
-print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
-
-@depends on patch@
-@@
-
-this_rule_should_never_matches();
-
-@ifm depends on !patch@
+@ifm@
expression *E;
statement S1,S2;
position p1;
@@ -35,7 +24,7 @@ if@p1 ((E == NULL && ...) || ...) S1 else S2
// The following two rules are separate, because both can match a single
// expression in different ways
-@pr1 depends on !patch expression@
+@pr1 expression@
expression *ifm.E;
identifier f;
position p1;
@@ -43,7 +32,7 @@ position p1;
(E != NULL && ...) ? <+...E->f@p1...+> : ...
-@pr2 depends on !patch expression@
+@pr2 expression@
expression *ifm.E;
identifier f;
position p2;
@@ -59,7 +48,7 @@ position p2;
// For org and report modes
-@r depends on !context && !patch && (org || report) exists@
+@r depends on !context && (org || report) exists@
expression subE <= ifm.E;
expression *ifm.E;
expression E1,E2;
@@ -99,7 +88,7 @@ if@p1 ((E == NULL && ...) || ...)
}
else S3
-@script:python depends on !context && !patch && !org && report@
+@script:python depends on !context && !org && report@
p << r.p;
p1 << ifm.p1;
x << ifm.E;
@@ -109,7 +98,7 @@ msg="ERROR: %s is NULL but dereferenced." % (x)
coccilib.report.print_report(p[0], msg)
cocci.include_match(False)
-@script:python depends on !context && !patch && org && !report@
+@script:python depends on !context && org && !report@
p << r.p;
p1 << ifm.p1;
x << ifm.E;
@@ -120,7 +109,7 @@ msg_safe=msg.replace("[","@(").replace("]",")")
cocci.print_main(msg_safe,p)
cocci.include_match(False)
-@s depends on !context && !patch && (org || report) exists@
+@s depends on !context && (org || report) exists@
expression subE <= ifm.E;
expression *ifm.E;
expression E1,E2;
@@ -159,7 +148,7 @@ if@p1 ((E == NULL && ...) || ...)
}
else S3
-@script:python depends on !context && !patch && !org && report@
+@script:python depends on !context && !org && report@
p << s.p;
p1 << ifm.p1;
x << ifm.E;
@@ -168,7 +157,7 @@ x << ifm.E;
msg="ERROR: %s is NULL but dereferenced." % (x)
coccilib.report.print_report(p[0], msg)
-@script:python depends on !context && !patch && org && !report@
+@script:python depends on !context && org && !report@
p << s.p;
p1 << ifm.p1;
x << ifm.E;
@@ -180,7 +169,7 @@ cocci.print_main(msg_safe,p)
// For context mode
-@depends on context && !patch && !org && !report exists@
+@depends on context && !org && !report exists@
expression subE <= ifm.E;
expression *ifm.E;
expression E1,E2;
@@ -223,7 +212,7 @@ else S3
// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
// It is need because the previous rule as already made a "change".
-@ifm1 depends on !patch@
+@ifm1@
expression *E;
statement S1,S2;
position p1;
@@ -231,7 +220,7 @@ position p1;
if@p1 ((E == NULL && ...) || ...) S1 else S2
-@pr11 depends on !patch expression@
+@pr11 expression@
expression *ifm1.E;
identifier f;
position p1;
@@ -239,7 +228,7 @@ position p1;
(E != NULL && ...) ? <+...E->f@p1...+> : ...
-@pr12 depends on !patch expression@
+@pr12 expression@
expression *ifm1.E;
identifier f;
position p2;
@@ -253,7 +242,7 @@ position p2;
sizeof(<+...E->f@p2...+>)
)
-@depends on context && !patch && !org && !report exists@
+@depends on context && !org && !report exists@
expression subE <= ifm1.E;
expression *ifm1.E;
expression E1,E2;
diff --git a/scripts/config b/scripts/config
index 608d7fdb13e8..a7c7c4b8e957 100755
--- a/scripts/config
+++ b/scripts/config
@@ -10,8 +10,10 @@ commands:
--enable|-e option Enable option
--disable|-d option Disable option
--module|-m option Turn option into a module
- --set-str option value
- Set option to "value"
+ --set-str option string
+ Set option to "string"
+ --set-val option value
+ Set option to value
--state|-s option Print state of option (n,y,m,undef)
--enable-after|-E beforeopt option
@@ -86,7 +88,7 @@ while [ "$1" != "" ] ; do
B=$ARG
shift 2
;;
- --*)
+ -*)
checkarg "$1"
shift
;;
@@ -109,6 +111,11 @@ while [ "$1" != "" ] ; do
shift
;;
+ --set-val)
+ set_var "CONFIG_$ARG" "CONFIG_$ARG=$1"
+ shift
+ ;;
+
--state|-s)
if grep -q "# CONFIG_$ARG is not set" $FN ; then
echo n
diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
index eaee44e66a43..809b949e495b 100644
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -160,7 +160,7 @@
#include <assert.h>
-#include <malloc.h>
+#include <stdlib.h>
#include "genksyms.h"
static int is_typedef;
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
index 10d7dc724b6d..09a265cd7193 100644
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -24,7 +24,7 @@
%{
#include <assert.h>
-#include <malloc.h>
+#include <stdlib.h>
#include "genksyms.h"
static int is_typedef;
diff --git a/scripts/headers.sh b/scripts/headers.sh
index 1ddcdd38d97f..978b42b3acd7 100755
--- a/scripts/headers.sh
+++ b/scripts/headers.sh
@@ -13,7 +13,7 @@ do_command()
fi
}
-archs=$(ls ${srctree}/arch)
+archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)}
for arch in ${archs}; do
case ${arch} in
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index 50d6cfd1fa77..7957e7a5166a 100644
--- a/scripts/headers_check.pl
+++ b/scripts/headers_check.pl
@@ -64,10 +64,10 @@ sub check_include
sub check_declarations
{
- if ($line =~m/^\s*extern\b/) {
+ if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) {
printf STDERR "$filename:$lineno: " .
- "userspace cannot call function or variable " .
- "defined in the kernel\n";
+ "userspace cannot reference function or " .
+ "variable defined in the kernel\n";
}
}
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index 4ca3be3b2e50..efb3be10d428 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -45,6 +45,13 @@ foreach my $file (@files) {
close $in;
system $unifdef . " $tmpfile > $installdir/$file";
+ # unifdef will exit 0 on success, and will exit 1 when the
+ # file was processed successfully but no changes were made,
+ # so abort only when it's higher than that.
+ my $e = $? >> 8;
+ if ($e > 1) {
+ die "$tmpfile: $!\n";
+ }
unlink $tmpfile;
}
exit 0;
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 5459a38be866..659326c3e895 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -529,8 +529,6 @@ int main(int ac, char **av)
}
break;
case savedefconfig:
- conf_read(NULL);
- break;
case silentoldconfig:
case oldaskconfig:
case oldconfig:
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 9df80114b47b..61c35bf2d9cb 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -440,12 +440,11 @@ static void conf_write_string(bool headerfile, const char *name,
fputs("\"\n", out);
}
-static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
- FILE *out, bool write_no)
+static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
{
const char *str;
- switch (type) {
+ switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
@@ -532,7 +531,7 @@ int conf_write_defconfig(const char *filename)
goto next_menu;
}
}
- conf_write_symbol(sym, sym->type, out, true);
+ conf_write_symbol(sym, out, true);
}
next_menu:
if (menu->list != NULL) {
@@ -561,7 +560,6 @@ int conf_write(const char *name)
const char *basename;
const char *str;
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
- enum symbol_type type;
time_t now;
int use_timestamp = 1;
char *env;
@@ -633,14 +631,8 @@ int conf_write(const char *name)
if (!(sym->flags & SYMBOL_WRITE))
goto next;
sym->flags &= ~SYMBOL_WRITE;
- type = sym->type;
- if (type == S_TRISTATE) {
- sym_calc_value(modules_sym);
- if (modules_sym->curr.tri == no)
- type = S_BOOLEAN;
- }
/* Write config symbol to file */
- conf_write_symbol(sym, type, out, true);
+ conf_write_symbol(sym, out, true);
}
next:
@@ -833,8 +825,7 @@ int conf_write_autoconf(void)
" * Automatically generated C config: don't edit\n"
" * %s\n"
" * %s"
- " */\n"
- "#define AUTOCONF_INCLUDED\n",
+ " */\n",
rootmenu.prompt->text, ctime(&now));
for_all_symbols(i, sym) {
@@ -843,7 +834,7 @@ int conf_write_autoconf(void)
continue;
/* write symbol to config file */
- conf_write_symbol(sym, sym->type, out, false);
+ conf_write_symbol(sym, out, false);
/* update autoconf and tristate files */
switch (sym->type) {
@@ -946,7 +937,7 @@ static void randomize_choice_values(struct symbol *csym)
int cnt, def;
/*
- * If choice is mod then we may have more items slected
+ * If choice is mod then we may have more items selected
* and if no then no-one.
* In both cases stop.
*/
@@ -1042,10 +1033,10 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
/*
* We have different type of choice blocks.
- * If curr.tri equal to mod then we can select several
+ * If curr.tri equals to mod then we can select several
* choice symbols in one block.
* In this case we do nothing.
- * If curr.tri equal yes then only one symbol can be
+ * If curr.tri equals yes then only one symbol can be
* selected in a choice block and we set it to yes,
* and the rest to no.
*/
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 330e7c0048a8..001003452f68 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -64,7 +64,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
}
-struct expr *expr_copy(struct expr *org)
+struct expr *expr_copy(const struct expr *org)
{
struct expr *e;
@@ -1013,6 +1013,48 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
#endif
}
+static inline struct expr *
+expr_get_leftmost_symbol(const struct expr *e)
+{
+
+ if (e == NULL)
+ return NULL;
+
+ while (e->type != E_SYMBOL)
+ e = e->left.expr;
+
+ return expr_copy(e);
+}
+
+/*
+ * Given expression `e1' and `e2', returns the leaf of the longest
+ * sub-expression of `e1' not containing 'e2.
+ */
+struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
+{
+ struct expr *ret;
+
+ switch (e1->type) {
+ case E_OR:
+ return expr_alloc_and(
+ expr_simplify_unmet_dep(e1->left.expr, e2),
+ expr_simplify_unmet_dep(e1->right.expr, e2));
+ case E_AND: {
+ struct expr *e;
+ e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
+ e = expr_eliminate_dups(e);
+ ret = (!expr_eq(e, e1)) ? e1 : NULL;
+ expr_free(e);
+ break;
+ }
+ default:
+ ret = e1;
+ break;
+ }
+
+ return expr_get_leftmost_symbol(ret);
+}
+
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{
if (!e) {
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 184eb6a0b505..3d238db49764 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -164,6 +164,7 @@ struct menu {
struct menu *list;
struct symbol *sym;
struct property *prompt;
+ struct expr *visibility;
struct expr *dep;
unsigned int flags;
char *help;
@@ -191,7 +192,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
-struct expr *expr_copy(struct expr *org);
+struct expr *expr_copy(const struct expr *org);
void expr_free(struct expr *e);
int expr_eq(struct expr *e1, struct expr *e2);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
@@ -206,6 +207,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
+struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
void expr_fprint(struct expr *e, FILE *out);
struct gstr; /* forward */
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 753cdbd7b805..febf0c94d558 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -14,6 +14,7 @@
static inline const char *gettext(const char *txt) { return txt; }
static inline void textdomain(const char *domainname) {}
static inline void bindtextdomain(const char *name, const char *dir) {}
+static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
#endif
#ifdef __cplusplus
@@ -67,10 +68,12 @@ struct kconf_id {
enum symbol_type stype;
};
+#ifdef YYDEBUG
+extern int zconfdebug;
+#endif
+
int zconfparse(void);
void zconfdump(FILE *out);
-
-extern int zconfdebug;
void zconf_starthelp(void);
FILE *zconf_fopen(const char *name);
void zconf_initscan(const char *name);
@@ -107,6 +110,7 @@ void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
void menu_add_dep(struct expr *dep);
+void menu_add_visibility(struct expr *dep);
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 7e83aef42c6d..5fdf10dc1d8a 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
}
if (current_entry->prompt && current_entry != &rootmenu)
prop_warn(prop, "prompt redefined");
+
+ /* Apply all upper menus' visibilities to actual prompts. */
+ if(type == P_PROMPT) {
+ struct menu *menu = current_entry;
+
+ while ((menu = menu->parent) != NULL) {
+ if (!menu->visibility)
+ continue;
+ prop->visible.expr
+ = expr_alloc_and(prop->visible.expr,
+ menu->visibility);
+ }
+ }
+
current_entry->prompt = prop;
}
prop->text = prompt;
@@ -152,6 +166,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
return menu_add_prop(type, prompt, NULL, dep);
}
+void menu_add_visibility(struct expr *expr)
+{
+ current_entry->visibility = expr_alloc_and(current_entry->visibility,
+ expr);
+}
+
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
{
menu_add_prop(type, NULL, expr, dep);
@@ -183,7 +203,7 @@ void menu_add_option(int token, char *arg)
}
}
-static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
+static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
{
return sym2->type == S_INT || sym2->type == S_HEX ||
(sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
@@ -201,6 +221,15 @@ static void sym_check_prop(struct symbol *sym)
prop_warn(prop,
"default for config symbol '%s'"
" must be a single symbol", sym->name);
+ if (prop->expr->type != E_SYMBOL)
+ break;
+ sym2 = prop_get_symbol(prop);
+ if (sym->type == S_HEX || sym->type == S_INT) {
+ if (!menu_validate_number(sym, sym2))
+ prop_warn(prop,
+ "'%s': number is invalid",
+ sym->name);
+ }
break;
case P_SELECT:
sym2 = prop_get_symbol(prop);
@@ -220,8 +249,8 @@ static void sym_check_prop(struct symbol *sym)
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
- if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
- !menu_range_valid_sym(sym, prop->expr->right.sym))
+ if (!menu_validate_number(sym, prop->expr->left.sym) ||
+ !menu_validate_number(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid");
break;
default:
@@ -410,6 +439,11 @@ bool menu_is_visible(struct menu *menu)
if (!menu->prompt)
return false;
+ if (menu->visibility) {
+ if (expr_calc_value(menu->visibility) == no)
+ return no;
+ }
+
sym = menu->sym;
if (sym) {
sym_calc_value(sym);
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 272a987f23e0..eda49ffc1c8c 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -248,7 +248,7 @@ search_help[] = N_(
"Only relevant lines are shown.\n"
"\n\n"
"Search examples:\n"
-"Examples: USB = > find all symbols containing USB\n"
+"Examples: USB => find all symbols containing USB\n"
" ^USB => find all symbols starting with USB\n"
" USB$ => find all symbols ending with USB\n"
"\n");
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index af6e9f3de950..a796c95fe8a0 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -351,12 +351,16 @@ void sym_calc_value(struct symbol *sym)
}
calc_newval:
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
+ struct expr *e;
+ e = expr_simplify_unmet_dep(sym->rev_dep.expr,
+ sym->dir_dep.expr);
fprintf(stderr, "warning: (");
- expr_fprint(sym->rev_dep.expr, stderr);
+ expr_fprint(e, stderr);
fprintf(stderr, ") selects %s which has unmet direct dependencies (",
sym->name);
expr_fprint(sym->dir_dep.expr, stderr);
fprintf(stderr, ")\n");
+ expr_free(e);
}
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
@@ -686,7 +690,7 @@ const char *sym_get_string_default(struct symbol *sym)
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
- /* The visibility imay limit the value from yes => mod */
+ /* The visibility may limit the value from yes => mod */
val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
break;
default:
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index d8bc74249622..c9e690eb7545 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -38,6 +38,7 @@ hex, T_TYPE, TF_COMMAND, S_HEX
string, T_TYPE, TF_COMMAND, S_STRING
select, T_SELECT, TF_COMMAND
range, T_RANGE, TF_COMMAND
+visible, T_VISIBLE, TF_COMMAND
option, T_OPTION, TF_COMMAND
on, T_ON, TF_PARAM
modules, T_OPT_MODULES, TF_OPTION
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index c1748faf4634..4055d5de1750 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -32,7 +32,7 @@
struct kconf_id;
static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-/* maximum key range = 47, duplicates = 0 */
+/* maximum key range = 50, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -46,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
{
static unsigned char asso_values[] =
{
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 11, 5,
- 0, 0, 5, 49, 5, 20, 49, 49, 5, 20,
- 5, 0, 30, 49, 0, 15, 0, 10, 0, 49,
- 25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 40, 5,
+ 0, 0, 5, 52, 0, 20, 52, 52, 10, 20,
+ 5, 0, 35, 52, 0, 30, 0, 15, 0, 52,
+ 15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52
};
register int hval = len;
@@ -102,25 +102,26 @@ struct kconf_id_strings_t
char kconf_id_strings_str12[sizeof("default")];
char kconf_id_strings_str13[sizeof("def_bool")];
char kconf_id_strings_str14[sizeof("help")];
- char kconf_id_strings_str15[sizeof("bool")];
char kconf_id_strings_str16[sizeof("config")];
char kconf_id_strings_str17[sizeof("def_tristate")];
- char kconf_id_strings_str18[sizeof("boolean")];
+ char kconf_id_strings_str18[sizeof("hex")];
char kconf_id_strings_str19[sizeof("defconfig_list")];
- char kconf_id_strings_str21[sizeof("string")];
char kconf_id_strings_str22[sizeof("if")];
char kconf_id_strings_str23[sizeof("int")];
- char kconf_id_strings_str26[sizeof("select")];
char kconf_id_strings_str27[sizeof("modules")];
char kconf_id_strings_str28[sizeof("tristate")];
char kconf_id_strings_str29[sizeof("menu")];
- char kconf_id_strings_str31[sizeof("source")];
char kconf_id_strings_str32[sizeof("comment")];
- char kconf_id_strings_str33[sizeof("hex")];
char kconf_id_strings_str35[sizeof("menuconfig")];
- char kconf_id_strings_str36[sizeof("prompt")];
- char kconf_id_strings_str37[sizeof("depends")];
+ char kconf_id_strings_str36[sizeof("string")];
+ char kconf_id_strings_str37[sizeof("visible")];
+ char kconf_id_strings_str41[sizeof("prompt")];
+ char kconf_id_strings_str42[sizeof("depends")];
+ char kconf_id_strings_str44[sizeof("bool")];
+ char kconf_id_strings_str46[sizeof("select")];
+ char kconf_id_strings_str47[sizeof("boolean")];
char kconf_id_strings_str48[sizeof("mainmenu")];
+ char kconf_id_strings_str51[sizeof("source")];
};
static struct kconf_id_strings_t kconf_id_strings_contents =
{
@@ -136,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
"default",
"def_bool",
"help",
- "bool",
"config",
"def_tristate",
- "boolean",
+ "hex",
"defconfig_list",
- "string",
"if",
"int",
- "select",
"modules",
"tristate",
"menu",
- "source",
"comment",
- "hex",
"menuconfig",
+ "string",
+ "visible",
"prompt",
"depends",
- "mainmenu"
+ "bool",
+ "select",
+ "boolean",
+ "mainmenu",
+ "source"
};
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__
@@ -168,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len)
{
enum
{
- TOTAL_KEYWORDS = 31,
+ TOTAL_KEYWORDS = 32,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2,
- MAX_HASH_VALUE = 48
+ MAX_HASH_VALUE = 51
};
static struct kconf_id wordlist[] =
@@ -191,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len)
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_HEX},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
+ {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
+ {-1}, {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
+ {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX},
- {-1},
+ {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_TYPE, TF_COMMAND, S_STRING},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND},
+ {-1}, {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND},
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_SOURCE, TF_COMMAND}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 699d4b265186..4c5495ea205e 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -160,18 +160,19 @@ static struct menu *current_menu, *current_entry;
T_DEFAULT = 275,
T_SELECT = 276,
T_RANGE = 277,
- T_OPTION = 278,
- T_ON = 279,
- T_WORD = 280,
- T_WORD_QUOTE = 281,
- T_UNEQUAL = 282,
- T_CLOSE_PAREN = 283,
- T_OPEN_PAREN = 284,
- T_EOL = 285,
- T_OR = 286,
- T_AND = 287,
- T_EQUAL = 288,
- T_NOT = 289
+ T_VISIBLE = 278,
+ T_OPTION = 279,
+ T_ON = 280,
+ T_WORD = 281,
+ T_WORD_QUOTE = 282,
+ T_UNEQUAL = 283,
+ T_CLOSE_PAREN = 284,
+ T_OPEN_PAREN = 285,
+ T_EOL = 286,
+ T_OR = 287,
+ T_AND = 288,
+ T_EQUAL = 289,
+ T_NOT = 290
};
#endif
@@ -419,20 +420,20 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 11
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 277
+#define YYLAST 290
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 35
+#define YYNTOKENS 36
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 48
+#define YYNNTS 50
/* YYNRULES -- Number of rules. */
-#define YYNRULES 113
+#define YYNRULES 118
/* YYNRULES -- Number of states. */
-#define YYNSTATES 185
+#define YYNSTATES 191
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 289
+#define YYMAXUTOK 290
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -468,7 +469,8 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35
};
#if YYDEBUG
@@ -478,72 +480,73 @@ static const yytype_uint16 yyprhs[] =
{
0, 0, 3, 6, 8, 11, 13, 14, 17, 20,
23, 26, 31, 36, 40, 42, 44, 46, 48, 50,
- 52, 54, 56, 58, 60, 62, 64, 66, 70, 73,
- 77, 80, 84, 87, 88, 91, 94, 97, 100, 103,
- 106, 110, 115, 120, 125, 131, 135, 136, 140, 141,
- 144, 148, 151, 153, 157, 158, 161, 164, 167, 170,
- 173, 178, 182, 185, 190, 191, 194, 198, 200, 204,
- 205, 208, 211, 214, 218, 222, 225, 227, 231, 232,
- 235, 238, 241, 245, 249, 252, 255, 258, 259, 262,
- 265, 268, 273, 274, 277, 279, 281, 284, 287, 290,
- 292, 295, 296, 299, 301, 305, 309, 313, 316, 320,
- 324, 326, 328, 329
+ 52, 54, 56, 58, 60, 62, 64, 66, 68, 72,
+ 75, 79, 82, 86, 89, 90, 93, 96, 99, 102,
+ 105, 108, 112, 117, 122, 127, 133, 137, 138, 142,
+ 143, 146, 150, 153, 155, 159, 160, 163, 166, 169,
+ 172, 175, 180, 184, 187, 192, 193, 196, 200, 202,
+ 206, 207, 210, 213, 216, 220, 224, 228, 230, 234,
+ 235, 238, 241, 244, 248, 252, 255, 258, 261, 262,
+ 265, 268, 271, 276, 277, 280, 283, 286, 287, 290,
+ 292, 294, 297, 300, 303, 305, 308, 309, 312, 314,
+ 318, 322, 326, 329, 333, 337, 339, 341, 342
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 36, 0, -1, 78, 37, -1, 37, -1, 62, 38,
- -1, 38, -1, -1, 38, 40, -1, 38, 54, -1,
- 38, 66, -1, 38, 77, -1, 38, 25, 1, 30,
- -1, 38, 39, 1, 30, -1, 38, 1, 30, -1,
+ 37, 0, -1, 81, 38, -1, 38, -1, 63, 39,
+ -1, 39, -1, -1, 39, 41, -1, 39, 55, -1,
+ 39, 67, -1, 39, 80, -1, 39, 26, 1, 31,
+ -1, 39, 40, 1, 31, -1, 39, 1, 31, -1,
16, -1, 18, -1, 19, -1, 21, -1, 17, -1,
- 22, -1, 20, -1, 30, -1, 60, -1, 70, -1,
- 43, -1, 45, -1, 68, -1, 25, 1, 30, -1,
- 1, 30, -1, 10, 25, 30, -1, 42, 46, -1,
- 11, 25, 30, -1, 44, 46, -1, -1, 46, 47,
- -1, 46, 48, -1, 46, 74, -1, 46, 72, -1,
- 46, 41, -1, 46, 30, -1, 19, 75, 30, -1,
- 18, 76, 79, 30, -1, 20, 80, 79, 30, -1,
- 21, 25, 79, 30, -1, 22, 81, 81, 79, 30,
- -1, 23, 49, 30, -1, -1, 49, 25, 50, -1,
- -1, 33, 76, -1, 7, 82, 30, -1, 51, 55,
- -1, 77, -1, 52, 57, 53, -1, -1, 55, 56,
- -1, 55, 74, -1, 55, 72, -1, 55, 30, -1,
- 55, 41, -1, 18, 76, 79, 30, -1, 19, 75,
- 30, -1, 17, 30, -1, 20, 25, 79, 30, -1,
- -1, 57, 40, -1, 14, 80, 78, -1, 77, -1,
- 58, 61, 59, -1, -1, 61, 40, -1, 61, 66,
- -1, 61, 54, -1, 3, 76, 78, -1, 4, 76,
- 30, -1, 63, 73, -1, 77, -1, 64, 67, 65,
- -1, -1, 67, 40, -1, 67, 66, -1, 67, 54,
- -1, 6, 76, 30, -1, 9, 76, 30, -1, 69,
- 73, -1, 12, 30, -1, 71, 13, -1, -1, 73,
- 74, -1, 73, 30, -1, 73, 41, -1, 16, 24,
- 80, 30, -1, -1, 76, 79, -1, 25, -1, 26,
- -1, 5, 30, -1, 8, 30, -1, 15, 30, -1,
- 30, -1, 78, 30, -1, -1, 14, 80, -1, 81,
- -1, 81, 33, 81, -1, 81, 27, 81, -1, 29,
- 80, 28, -1, 34, 80, -1, 80, 31, 80, -1,
- 80, 32, 80, -1, 25, -1, 26, -1, -1, 25,
- -1
+ 22, -1, 20, -1, 23, -1, 31, -1, 61, -1,
+ 71, -1, 44, -1, 46, -1, 69, -1, 26, 1,
+ 31, -1, 1, 31, -1, 10, 26, 31, -1, 43,
+ 47, -1, 11, 26, 31, -1, 45, 47, -1, -1,
+ 47, 48, -1, 47, 49, -1, 47, 75, -1, 47,
+ 73, -1, 47, 42, -1, 47, 31, -1, 19, 78,
+ 31, -1, 18, 79, 82, 31, -1, 20, 83, 82,
+ 31, -1, 21, 26, 82, 31, -1, 22, 84, 84,
+ 82, 31, -1, 24, 50, 31, -1, -1, 50, 26,
+ 51, -1, -1, 34, 79, -1, 7, 85, 31, -1,
+ 52, 56, -1, 80, -1, 53, 58, 54, -1, -1,
+ 56, 57, -1, 56, 75, -1, 56, 73, -1, 56,
+ 31, -1, 56, 42, -1, 18, 79, 82, 31, -1,
+ 19, 78, 31, -1, 17, 31, -1, 20, 26, 82,
+ 31, -1, -1, 58, 41, -1, 14, 83, 81, -1,
+ 80, -1, 59, 62, 60, -1, -1, 62, 41, -1,
+ 62, 67, -1, 62, 55, -1, 3, 79, 81, -1,
+ 4, 79, 31, -1, 64, 76, 74, -1, 80, -1,
+ 65, 68, 66, -1, -1, 68, 41, -1, 68, 67,
+ -1, 68, 55, -1, 6, 79, 31, -1, 9, 79,
+ 31, -1, 70, 74, -1, 12, 31, -1, 72, 13,
+ -1, -1, 74, 75, -1, 74, 31, -1, 74, 42,
+ -1, 16, 25, 83, 31, -1, -1, 76, 77, -1,
+ 76, 31, -1, 23, 82, -1, -1, 79, 82, -1,
+ 26, -1, 27, -1, 5, 31, -1, 8, 31, -1,
+ 15, 31, -1, 31, -1, 81, 31, -1, -1, 14,
+ 83, -1, 84, -1, 84, 34, 84, -1, 84, 28,
+ 84, -1, 30, 83, 29, -1, 35, 83, -1, 83,
+ 32, 83, -1, 83, 33, 83, -1, 26, -1, 27,
+ -1, -1, 26, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 107, 107, 107, 109, 109, 111, 113, 114, 115,
- 116, 117, 118, 122, 126, 126, 126, 126, 126, 126,
- 126, 130, 131, 132, 133, 134, 135, 139, 140, 146,
- 154, 160, 168, 178, 180, 181, 182, 183, 184, 185,
- 188, 196, 202, 212, 218, 224, 227, 229, 240, 241,
- 246, 255, 260, 268, 271, 273, 274, 275, 276, 277,
- 280, 286, 297, 303, 313, 315, 320, 328, 336, 339,
- 341, 342, 343, 348, 355, 362, 367, 375, 378, 380,
- 381, 382, 385, 393, 400, 407, 413, 420, 422, 423,
- 424, 427, 435, 437, 442, 443, 446, 447, 448, 452,
- 453, 456, 457, 460, 461, 462, 463, 464, 465, 466,
- 469, 470, 473, 474
+ 0, 108, 108, 108, 110, 110, 112, 114, 115, 116,
+ 117, 118, 119, 123, 127, 127, 127, 127, 127, 127,
+ 127, 127, 131, 132, 133, 134, 135, 136, 140, 141,
+ 147, 155, 161, 169, 179, 181, 182, 183, 184, 185,
+ 186, 189, 197, 203, 213, 219, 225, 228, 230, 241,
+ 242, 247, 256, 261, 269, 272, 274, 275, 276, 277,
+ 278, 281, 287, 298, 304, 314, 316, 321, 329, 337,
+ 340, 342, 343, 344, 349, 356, 363, 368, 376, 379,
+ 381, 382, 383, 386, 394, 401, 408, 414, 421, 423,
+ 424, 425, 428, 436, 438, 439, 442, 449, 451, 456,
+ 457, 460, 461, 462, 466, 467, 470, 471, 474, 475,
+ 476, 477, 478, 479, 480, 483, 484, 487, 488
};
#endif
@@ -556,7 +559,7 @@ static const char *const yytname[] =
"T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
"T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
"T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
- "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+ "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
"T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
"T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
"common_stmt", "option_error", "config_entry_start", "config_stmt",
@@ -567,8 +570,8 @@ static const char *const yytname[] =
"if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
"menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
"comment", "comment_stmt", "help_start", "help", "depends_list",
- "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr",
- "symbol", "word_opt", 0
+ "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
+ "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0
};
#endif
@@ -580,25 +583,25 @@ static const yytype_uint16 yytoknum[] =
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289
+ 285, 286, 287, 288, 289, 290
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 35, 36, 36, 37, 37, 38, 38, 38, 38,
- 38, 38, 38, 38, 39, 39, 39, 39, 39, 39,
- 39, 40, 40, 40, 40, 40, 40, 41, 41, 42,
- 43, 44, 45, 46, 46, 46, 46, 46, 46, 46,
- 47, 47, 47, 47, 47, 48, 49, 49, 50, 50,
- 51, 52, 53, 54, 55, 55, 55, 55, 55, 55,
- 56, 56, 56, 56, 57, 57, 58, 59, 60, 61,
- 61, 61, 61, 62, 63, 64, 65, 66, 67, 67,
- 67, 67, 68, 69, 70, 71, 72, 73, 73, 73,
- 73, 74, 75, 75, 76, 76, 77, 77, 77, 78,
- 78, 79, 79, 80, 80, 80, 80, 80, 80, 80,
- 81, 81, 82, 82
+ 0, 36, 37, 37, 38, 38, 39, 39, 39, 39,
+ 39, 39, 39, 39, 40, 40, 40, 40, 40, 40,
+ 40, 40, 41, 41, 41, 41, 41, 41, 42, 42,
+ 43, 44, 45, 46, 47, 47, 47, 47, 47, 47,
+ 47, 48, 48, 48, 48, 48, 49, 50, 50, 51,
+ 51, 52, 53, 54, 55, 56, 56, 56, 56, 56,
+ 56, 57, 57, 57, 57, 58, 58, 59, 60, 61,
+ 62, 62, 62, 62, 63, 64, 65, 66, 67, 68,
+ 68, 68, 68, 69, 70, 71, 72, 73, 74, 74,
+ 74, 74, 75, 76, 76, 76, 77, 78, 78, 79,
+ 79, 80, 80, 80, 81, 81, 82, 82, 83, 83,
+ 83, 83, 83, 83, 83, 84, 84, 85, 85
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -606,16 +609,16 @@ static const yytype_uint8 yyr2[] =
{
0, 2, 2, 1, 2, 1, 0, 2, 2, 2,
2, 4, 4, 3, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 2, 3,
- 2, 3, 2, 0, 2, 2, 2, 2, 2, 2,
- 3, 4, 4, 4, 5, 3, 0, 3, 0, 2,
- 3, 2, 1, 3, 0, 2, 2, 2, 2, 2,
- 4, 3, 2, 4, 0, 2, 3, 1, 3, 0,
- 2, 2, 2, 3, 3, 2, 1, 3, 0, 2,
- 2, 2, 3, 3, 2, 2, 2, 0, 2, 2,
- 2, 4, 0, 2, 1, 1, 2, 2, 2, 1,
- 2, 0, 2, 1, 3, 3, 3, 2, 3, 3,
- 1, 1, 0, 1
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 2,
+ 3, 2, 3, 2, 0, 2, 2, 2, 2, 2,
+ 2, 3, 4, 4, 4, 5, 3, 0, 3, 0,
+ 2, 3, 2, 1, 3, 0, 2, 2, 2, 2,
+ 2, 4, 3, 2, 4, 0, 2, 3, 1, 3,
+ 0, 2, 2, 2, 3, 3, 3, 1, 3, 0,
+ 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
+ 2, 2, 4, 0, 2, 2, 2, 0, 2, 1,
+ 1, 2, 2, 2, 1, 2, 0, 2, 1, 3,
+ 3, 3, 2, 3, 3, 1, 1, 0, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -623,165 +626,172 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 6, 0, 99, 0, 3, 0, 6, 6, 94, 95,
- 0, 1, 0, 0, 0, 0, 112, 0, 0, 0,
+ 6, 0, 104, 0, 3, 0, 6, 6, 99, 100,
+ 0, 1, 0, 0, 0, 0, 117, 0, 0, 0,
0, 0, 0, 14, 18, 15, 16, 20, 17, 19,
- 0, 21, 0, 7, 33, 24, 33, 25, 54, 64,
- 8, 69, 22, 87, 78, 9, 26, 87, 23, 10,
- 0, 100, 2, 73, 13, 0, 96, 0, 113, 0,
- 97, 0, 0, 0, 110, 111, 0, 0, 0, 103,
- 98, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 74, 82, 50, 83, 29, 31, 0, 107, 0,
- 0, 66, 0, 0, 11, 12, 0, 0, 0, 0,
- 92, 0, 0, 0, 46, 0, 39, 38, 34, 35,
- 0, 37, 36, 0, 0, 92, 0, 58, 59, 55,
- 57, 56, 65, 53, 52, 70, 72, 68, 71, 67,
- 89, 90, 88, 79, 81, 77, 80, 76, 106, 108,
- 109, 105, 104, 28, 85, 0, 101, 0, 101, 101,
- 101, 0, 0, 0, 86, 62, 101, 0, 101, 0,
- 0, 0, 40, 93, 0, 0, 101, 48, 45, 27,
- 0, 61, 0, 91, 102, 41, 42, 43, 0, 0,
- 47, 60, 63, 44, 49
+ 21, 0, 22, 0, 7, 34, 25, 34, 26, 55,
+ 65, 8, 70, 23, 93, 79, 9, 27, 88, 24,
+ 10, 0, 105, 2, 74, 13, 0, 101, 0, 118,
+ 0, 102, 0, 0, 0, 115, 116, 0, 0, 0,
+ 108, 103, 0, 0, 0, 0, 0, 0, 0, 88,
+ 0, 0, 75, 83, 51, 84, 30, 32, 0, 112,
+ 0, 0, 67, 0, 0, 11, 12, 0, 0, 0,
+ 0, 97, 0, 0, 0, 47, 0, 40, 39, 35,
+ 36, 0, 38, 37, 0, 0, 97, 0, 59, 60,
+ 56, 58, 57, 66, 54, 53, 71, 73, 69, 72,
+ 68, 106, 95, 0, 94, 80, 82, 78, 81, 77,
+ 90, 91, 89, 111, 113, 114, 110, 109, 29, 86,
+ 0, 106, 0, 106, 106, 106, 0, 0, 0, 87,
+ 63, 106, 0, 106, 0, 96, 0, 0, 41, 98,
+ 0, 0, 106, 49, 46, 28, 0, 62, 0, 107,
+ 92, 42, 43, 44, 0, 0, 48, 61, 64, 45,
+ 50
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 3, 4, 5, 32, 33, 107, 34, 35, 36,
- 37, 73, 108, 109, 152, 180, 38, 39, 123, 40,
- 75, 119, 76, 41, 127, 42, 77, 6, 43, 44,
- 135, 45, 79, 46, 47, 48, 110, 111, 78, 112,
- 147, 148, 49, 7, 161, 68, 69, 59
+ -1, 3, 4, 5, 33, 34, 108, 35, 36, 37,
+ 38, 74, 109, 110, 157, 186, 39, 40, 124, 41,
+ 76, 120, 77, 42, 128, 43, 78, 6, 44, 45,
+ 137, 46, 80, 47, 48, 49, 111, 112, 81, 113,
+ 79, 134, 152, 153, 50, 7, 165, 69, 70, 60
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -89
+#define YYPACT_NINF -90
static const yytype_int16 yypact[] =
{
- 3, 4, -89, 20, -89, 100, -89, 7, -89, -89,
- -8, -89, 17, 4, 28, 4, 37, 36, 4, 68,
- 87, -18, 69, -89, -89, -89, -89, -89, -89, -89,
- 128, -89, 138, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- 127, -89, -89, 110, -89, 126, -89, 136, -89, 137,
- -89, 147, 150, 152, -89, -89, -18, -18, 171, -14,
- -89, 153, 157, 34, 67, 180, 233, 220, 207, 220,
- 154, -89, -89, -89, -89, -89, -89, 0, -89, -18,
- -18, 110, 44, 44, -89, -89, 163, 174, 182, 4,
- 4, -18, 194, 44, -89, 219, -89, -89, -89, -89,
- 223, -89, -89, 203, 4, 4, 215, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, 213,
- -89, -89, -89, -89, -89, -18, 232, 227, 232, -5,
- 232, 44, 35, 234, -89, -89, 232, 235, 232, 224,
- -18, 236, -89, -89, 237, 238, 232, 216, -89, -89,
- 240, -89, 241, -89, 71, -89, -89, -89, 242, 4,
- -89, -89, -89, -89, -89
+ 4, 42, -90, 96, -90, 111, -90, 15, -90, -90,
+ 75, -90, 82, 42, 104, 42, 110, 107, 42, 115,
+ 125, -4, 121, -90, -90, -90, -90, -90, -90, -90,
+ -90, 162, -90, 163, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, 139, -90, -90, 138, -90, 142, -90, 143, -90,
+ 152, -90, 164, 167, 168, -90, -90, -4, -4, 77,
+ -18, -90, 177, 185, 33, 71, 195, 247, 236, -2,
+ 236, 171, -90, -90, -90, -90, -90, -90, 41, -90,
+ -4, -4, 138, 97, 97, -90, -90, 186, 187, 194,
+ 42, 42, -4, 196, 97, -90, 219, -90, -90, -90,
+ -90, 210, -90, -90, 204, 42, 42, 199, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, 222, -90, 223, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, 215, -90, -90, -90, -90, -90,
+ -4, 222, 228, 222, -5, 222, 97, 35, 229, -90,
+ -90, 222, 232, 222, -4, -90, 135, 233, -90, -90,
+ 234, 235, 222, 240, -90, -90, 237, -90, 239, -13,
+ -90, -90, -90, -90, 244, 42, -90, -90, -90, -90,
+ -90
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -89, -89, 255, 267, -89, 47, -57, -89, -89, -89,
- -89, 239, -89, -89, -89, -89, -89, -89, -89, 130,
- -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, 181, -89, -89, -89, -89, -89, 199, 229, 16,
- 162, -1, 74, -7, 103, -65, -88, -89
+ -90, -90, 269, 271, -90, 23, -70, -90, -90, -90,
+ -90, 243, -90, -90, -90, -90, -90, -90, -90, -48,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -20, -90, -90, -90, -90, -90, 206, 205, -68,
+ -90, -90, 169, -1, 27, -7, 118, -66, -89, -90
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -85
+#define YYTABLE_NINF -86
static const yytype_int16 yytable[] =
{
- 10, 87, 88, 53, 141, 142, 1, 64, 65, 160,
- 1, 66, 55, 92, 57, 151, 67, 61, 118, 93,
- 11, 131, 2, 131, 139, 140, 89, 90, 138, 8,
- 9, 89, 90, 2, -30, 96, 149, 51, -30, -30,
- -30, -30, -30, -30, -30, -30, 97, 54, -30, -30,
- 98, -30, 99, 100, 101, 102, 103, 104, 56, 105,
- 167, 91, 58, 166, 106, 168, 60, -32, 96, 64,
- 65, -32, -32, -32, -32, -32, -32, -32, -32, 97,
- 159, -32, -32, 98, -32, 99, 100, 101, 102, 103,
- 104, 121, 105, 62, 132, 174, 132, 106, 146, 70,
- -5, 12, 89, 90, 13, 14, 15, 16, 17, 18,
- 19, 20, 63, 156, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 122, 125, 30, 133, -4, 12, 71,
- 31, 13, 14, 15, 16, 17, 18, 19, 20, 72,
- 51, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 124, 129, 30, 137, -84, 96, 81, 31, -84, -84,
- -84, -84, -84, -84, -84, -84, 82, 83, -84, -84,
- 98, -84, -84, -84, -84, -84, -84, 84, 184, 105,
- 85, 96, 86, 94, 130, -51, -51, 95, -51, -51,
- -51, -51, 97, 143, -51, -51, 98, 113, 114, 115,
- 116, 2, 89, 90, 144, 105, 145, 126, 96, 134,
- 117, -75, -75, -75, -75, -75, -75, -75, -75, 150,
- 153, -75, -75, 98, 13, 14, 15, 16, 17, 18,
- 19, 20, 105, 155, 21, 22, 154, 130, 14, 15,
- 158, 17, 18, 19, 20, 90, 160, 21, 22, 179,
- 31, 163, 164, 165, 173, 89, 90, 162, 128, 170,
- 136, 172, 52, 31, 169, 171, 175, 176, 177, 178,
- 181, 182, 183, 50, 120, 74, 80, 157
+ 10, 88, 89, 54, 146, 147, 119, 1, 122, 164,
+ 93, 141, 56, 142, 58, 156, 94, 62, 1, 90,
+ 91, 131, 65, 66, 144, 145, 67, 90, 91, 132,
+ 127, 68, 136, -31, 97, 2, 154, -31, -31, -31,
+ -31, -31, -31, -31, -31, 98, 52, -31, -31, 99,
+ -31, 100, 101, 102, 103, 104, -31, 105, 129, 106,
+ 138, 173, 92, 141, 107, 142, 174, 172, 8, 9,
+ 143, -33, 97, 90, 91, -33, -33, -33, -33, -33,
+ -33, -33, -33, 98, 166, -33, -33, 99, -33, 100,
+ 101, 102, 103, 104, -33, 105, 11, 106, 179, 151,
+ 123, 126, 107, 135, 125, 130, 2, 139, 2, 90,
+ 91, -5, 12, 55, 161, 13, 14, 15, 16, 17,
+ 18, 19, 20, 65, 66, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 57, 59, 31, 61, -4,
+ 12, 63, 32, 13, 14, 15, 16, 17, 18, 19,
+ 20, 64, 71, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 72, 73, 31, 180, 90, 91, 52,
+ 32, -85, 97, 82, 83, -85, -85, -85, -85, -85,
+ -85, -85, -85, 84, 190, -85, -85, 99, -85, -85,
+ -85, -85, -85, -85, -85, 85, 97, 106, 86, 87,
+ -52, -52, 140, -52, -52, -52, -52, 98, 95, -52,
+ -52, 99, 114, 115, 116, 117, 96, 148, 149, 150,
+ 158, 106, 155, 159, 97, 163, 118, -76, -76, -76,
+ -76, -76, -76, -76, -76, 160, 164, -76, -76, 99,
+ 13, 14, 15, 16, 17, 18, 19, 20, 91, 106,
+ 21, 22, 14, 15, 140, 17, 18, 19, 20, 168,
+ 175, 21, 22, 177, 181, 182, 183, 32, 187, 167,
+ 188, 169, 170, 171, 185, 189, 53, 51, 32, 176,
+ 75, 178, 121, 0, 133, 162, 0, 0, 0, 0,
+ 184
};
-static const yytype_uint8 yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 1, 66, 67, 10, 92, 93, 3, 25, 26, 14,
- 3, 29, 13, 27, 15, 103, 34, 18, 75, 33,
- 0, 78, 30, 80, 89, 90, 31, 32, 28, 25,
- 26, 31, 32, 30, 0, 1, 101, 30, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 30, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 30, 25,
- 25, 68, 25, 151, 30, 30, 30, 0, 1, 25,
- 26, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 145, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 75, 25, 25, 78, 160, 80, 30, 99, 30,
- 0, 1, 31, 32, 4, 5, 6, 7, 8, 9,
- 10, 11, 25, 114, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 76, 77, 25, 79, 0, 1, 1,
- 30, 4, 5, 6, 7, 8, 9, 10, 11, 1,
- 30, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 76, 77, 25, 79, 0, 1, 30, 30, 4, 5,
- 6, 7, 8, 9, 10, 11, 30, 30, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 30, 179, 25,
- 30, 1, 30, 30, 30, 5, 6, 30, 8, 9,
- 10, 11, 12, 30, 14, 15, 16, 17, 18, 19,
- 20, 30, 31, 32, 30, 25, 24, 77, 1, 79,
- 30, 4, 5, 6, 7, 8, 9, 10, 11, 25,
- 1, 14, 15, 16, 4, 5, 6, 7, 8, 9,
- 10, 11, 25, 30, 14, 15, 13, 30, 5, 6,
- 25, 8, 9, 10, 11, 32, 14, 14, 15, 33,
- 30, 148, 149, 150, 30, 31, 32, 30, 77, 156,
- 79, 158, 7, 30, 30, 30, 30, 30, 30, 166,
- 30, 30, 30, 6, 75, 36, 47, 115
+ 1, 67, 68, 10, 93, 94, 76, 3, 76, 14,
+ 28, 81, 13, 81, 15, 104, 34, 18, 3, 32,
+ 33, 23, 26, 27, 90, 91, 30, 32, 33, 31,
+ 78, 35, 80, 0, 1, 31, 102, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 31, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 78, 26,
+ 80, 26, 69, 133, 31, 133, 31, 156, 26, 27,
+ 29, 0, 1, 32, 33, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 150, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 0, 26, 164, 100,
+ 77, 78, 31, 80, 77, 78, 31, 80, 31, 32,
+ 33, 0, 1, 31, 115, 4, 5, 6, 7, 8,
+ 9, 10, 11, 26, 27, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 31, 26, 26, 31, 0,
+ 1, 26, 31, 4, 5, 6, 7, 8, 9, 10,
+ 11, 26, 31, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 1, 1, 26, 31, 32, 33, 31,
+ 31, 0, 1, 31, 31, 4, 5, 6, 7, 8,
+ 9, 10, 11, 31, 185, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 31, 1, 26, 31, 31,
+ 5, 6, 31, 8, 9, 10, 11, 12, 31, 14,
+ 15, 16, 17, 18, 19, 20, 31, 31, 31, 25,
+ 1, 26, 26, 13, 1, 26, 31, 4, 5, 6,
+ 7, 8, 9, 10, 11, 31, 14, 14, 15, 16,
+ 4, 5, 6, 7, 8, 9, 10, 11, 33, 26,
+ 14, 15, 5, 6, 31, 8, 9, 10, 11, 31,
+ 31, 14, 15, 31, 31, 31, 31, 31, 31, 151,
+ 31, 153, 154, 155, 34, 31, 7, 6, 31, 161,
+ 37, 163, 76, -1, 79, 116, -1, -1, -1, -1,
+ 172
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 30, 36, 37, 38, 62, 78, 25, 26,
- 76, 0, 1, 4, 5, 6, 7, 8, 9, 10,
+ 0, 3, 31, 37, 38, 39, 63, 81, 26, 27,
+ 79, 0, 1, 4, 5, 6, 7, 8, 9, 10,
11, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 25, 30, 39, 40, 42, 43, 44, 45, 51, 52,
- 54, 58, 60, 63, 64, 66, 68, 69, 70, 77,
- 38, 30, 37, 78, 30, 76, 30, 76, 25, 82,
- 30, 76, 25, 25, 25, 26, 29, 34, 80, 81,
- 30, 1, 1, 46, 46, 55, 57, 61, 73, 67,
- 73, 30, 30, 30, 30, 30, 30, 80, 80, 31,
- 32, 78, 27, 33, 30, 30, 1, 12, 16, 18,
- 19, 20, 21, 22, 23, 25, 30, 41, 47, 48,
- 71, 72, 74, 17, 18, 19, 20, 30, 41, 56,
- 72, 74, 40, 53, 77, 40, 54, 59, 66, 77,
- 30, 41, 74, 40, 54, 65, 66, 77, 28, 80,
- 80, 81, 81, 30, 30, 24, 76, 75, 76, 80,
- 25, 81, 49, 1, 13, 30, 76, 75, 25, 80,
- 14, 79, 30, 79, 79, 79, 81, 25, 30, 30,
- 79, 30, 79, 30, 80, 30, 30, 30, 79, 33,
- 50, 30, 30, 30, 76
+ 23, 26, 31, 40, 41, 43, 44, 45, 46, 52,
+ 53, 55, 59, 61, 64, 65, 67, 69, 70, 71,
+ 80, 39, 31, 38, 81, 31, 79, 31, 79, 26,
+ 85, 31, 79, 26, 26, 26, 27, 30, 35, 83,
+ 84, 31, 1, 1, 47, 47, 56, 58, 62, 76,
+ 68, 74, 31, 31, 31, 31, 31, 31, 83, 83,
+ 32, 33, 81, 28, 34, 31, 31, 1, 12, 16,
+ 18, 19, 20, 21, 22, 24, 26, 31, 42, 48,
+ 49, 72, 73, 75, 17, 18, 19, 20, 31, 42,
+ 57, 73, 75, 41, 54, 80, 41, 55, 60, 67,
+ 80, 23, 31, 74, 77, 41, 55, 66, 67, 80,
+ 31, 42, 75, 29, 83, 83, 84, 84, 31, 31,
+ 25, 79, 78, 79, 83, 26, 84, 50, 1, 13,
+ 31, 79, 78, 26, 14, 82, 83, 82, 31, 82,
+ 82, 82, 84, 26, 31, 31, 82, 31, 82, 83,
+ 31, 31, 31, 31, 82, 34, 51, 31, 31, 31,
+ 79
};
#define yyerrok (yyerrstatus = 0)
@@ -1292,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep)
switch (yytype)
{
- case 52: /* "choice_entry" */
+ case 53: /* "choice_entry" */
{
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1302,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep)
};
break;
- case 58: /* "if_entry" */
+ case 59: /* "if_entry" */
{
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1312,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep)
};
break;
- case 64: /* "menu_entry" */
+ case 65: /* "menu_entry" */
{
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1644,17 +1654,17 @@ yyreduce:
{ zconf_error("invalid statement"); ;}
break;
- case 27:
+ case 28:
{ zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
break;
- case 28:
+ case 29:
{ zconf_error("invalid option"); ;}
break;
- case 29:
+ case 30:
{
struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1664,7 +1674,7 @@ yyreduce:
;}
break;
- case 30:
+ case 31:
{
menu_end_entry();
@@ -1672,7 +1682,7 @@ yyreduce:
;}
break;
- case 31:
+ case 32:
{
struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1682,7 +1692,7 @@ yyreduce:
;}
break;
- case 32:
+ case 33:
{
if (current_entry->prompt)
@@ -1694,7 +1704,7 @@ yyreduce:
;}
break;
- case 40:
+ case 41:
{
menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1704,7 +1714,7 @@ yyreduce:
;}
break;
- case 41:
+ case 42:
{
menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1712,7 +1722,7 @@ yyreduce:
;}
break;
- case 42:
+ case 43:
{
menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1724,7 +1734,7 @@ yyreduce:
;}
break;
- case 43:
+ case 44:
{
menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1732,7 +1742,7 @@ yyreduce:
;}
break;
- case 44:
+ case 45:
{
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1740,7 +1750,7 @@ yyreduce:
;}
break;
- case 47:
+ case 48:
{
struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1752,17 +1762,17 @@ yyreduce:
;}
break;
- case 48:
+ case 49:
{ (yyval.string) = NULL; ;}
break;
- case 49:
+ case 50:
{ (yyval.string) = (yyvsp[(2) - (2)].string); ;}
break;
- case 50:
+ case 51:
{
struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1773,14 +1783,14 @@ yyreduce:
;}
break;
- case 51:
+ case 52:
{
(yyval.menu) = menu_add_menu();
;}
break;
- case 52:
+ case 53:
{
if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1790,7 +1800,7 @@ yyreduce:
;}
break;
- case 60:
+ case 61:
{
menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1798,7 +1808,7 @@ yyreduce:
;}
break;
- case 61:
+ case 62:
{
if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1811,7 +1821,7 @@ yyreduce:
;}
break;
- case 62:
+ case 63:
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1819,7 +1829,7 @@ yyreduce:
;}
break;
- case 63:
+ case 64:
{
if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1831,7 +1841,7 @@ yyreduce:
;}
break;
- case 66:
+ case 67:
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1841,7 +1851,7 @@ yyreduce:
;}
break;
- case 67:
+ case 68:
{
if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1851,14 +1861,14 @@ yyreduce:
;}
break;
- case 73:
+ case 74:
{
menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
;}
break;
- case 74:
+ case 75:
{
menu_add_entry(NULL);
@@ -1867,14 +1877,14 @@ yyreduce:
;}
break;
- case 75:
+ case 76:
{
(yyval.menu) = menu_add_menu();
;}
break;
- case 76:
+ case 77:
{
if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1884,7 +1894,7 @@ yyreduce:
;}
break;
- case 82:
+ case 83:
{
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1892,7 +1902,7 @@ yyreduce:
;}
break;
- case 83:
+ case 84:
{
menu_add_entry(NULL);
@@ -1901,14 +1911,14 @@ yyreduce:
;}
break;
- case 84:
+ case 85:
{
menu_end_entry();
;}
break;
- case 85:
+ case 86:
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1916,14 +1926,14 @@ yyreduce:
;}
break;
- case 86:
+ case 87:
{
current_entry->help = (yyvsp[(2) - (2)].string);
;}
break;
- case 91:
+ case 92:
{
menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1931,84 +1941,91 @@ yyreduce:
;}
break;
- case 93:
+ case 96:
+
+ {
+ menu_add_visibility((yyvsp[(2) - (2)].expr));
+;}
+ break;
+
+ case 98:
{
menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
;}
break;
- case 96:
+ case 101:
{ (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 97:
+ case 102:
{ (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 98:
+ case 103:
{ (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 101:
+ case 106:
{ (yyval.expr) = NULL; ;}
break;
- case 102:
+ case 107:
{ (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
break;
- case 103:
+ case 108:
{ (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
break;
- case 104:
+ case 109:
{ (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
- case 105:
+ case 110:
{ (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
- case 106:
+ case 111:
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
break;
- case 107:
+ case 112:
{ (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
break;
- case 108:
+ case 113:
{ (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
- case 109:
+ case 114:
{ (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
- case 110:
+ case 115:
{ (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
break;
- case 111:
+ case 116:
{ (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
break;
- case 112:
+ case 117:
{ (yyval.string) = NULL; ;}
break;
@@ -2278,6 +2295,7 @@ static const char *zconf_tokenname(int token)
case T_IF: return "if";
case T_ENDIF: return "endif";
case T_DEPENDS: return "depends";
+ case T_VISIBLE: return "visible";
}
return "<token>";
}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 2abd3c7ff15d..49fb4ab664c3 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry;
#define YYERROR_VERBOSE
#endif
%}
-%expect 28
+%expect 30
%union
{
@@ -68,6 +68,7 @@ static struct menu *current_menu, *current_entry;
%token <id>T_DEFAULT
%token <id>T_SELECT
%token <id>T_RANGE
+%token <id>T_VISIBLE
%token <id>T_OPTION
%token <id>T_ON
%token <string> T_WORD
@@ -123,7 +124,7 @@ stmt_list:
;
option_name:
- T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
+ T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
;
common_stmt:
@@ -359,7 +360,7 @@ menu: T_MENU prompt T_EOL
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
};
-menu_entry: menu depends_list
+menu_entry: menu visibility_list depends_list
{
$$ = menu_add_menu();
};
@@ -430,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
};
+/* visibility option */
+
+visibility_list:
+ /* empty */
+ | visibility_list visible
+ | visibility_list T_EOL
+;
+
+visible: T_VISIBLE if_expr
+{
+ menu_add_visibility($2);
+};
+
/* prompt statement */
prompt_stmt_opt:
@@ -526,6 +540,7 @@ static const char *zconf_tokenname(int token)
case T_IF: return "if";
case T_ENDIF: return "endif";
case T_DEPENDS: return "depends";
+ case T_VISIBLE: return "visible";
}
return "<token>";
}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 39580a5dc5df..9f85012acf0d 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -155,6 +155,8 @@ use strict;
# '@parameter' - name of a parameter
# '%CONST' - name of a constant.
+## init lots of data
+
my $errors = 0;
my $warnings = 0;
my $anon_struct_union = 0;
@@ -218,21 +220,14 @@ my %highlights_list = ( $type_constant, "\$1",
$type_param, "\$1" );
my $blankline_list = "";
-sub usage {
- print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
- print " [ -no-doc-sections ]\n";
- print " [ -function funcname [ -function funcname ...] ]\n";
- print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
- print " c source file(s) > outputfile\n";
- print " -v : verbose output, more warnings & other info listed\n";
- exit 1;
-}
-
# read arguments
if ($#ARGV == -1) {
usage();
}
+my $kernelversion;
+my $dohighlight = "";
+
my $verbose = 0;
my $output_mode = "man";
my $no_doc_sections = 0;
@@ -245,7 +240,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
'November', 'December')[(localtime)[4]] .
" " . ((localtime)[5]+1900);
-# Essentially these are globals
+# Essentially these are globals.
# They probably want to be tidied up, made more localised or something.
# CAVEAT EMPTOR! Some of the others I localised may not want to be, which
# could cause "use of undefined value" or other bugs.
@@ -353,6 +348,18 @@ while ($ARGV[0] =~ m/^-(.*)/) {
}
}
+# continue execution near EOF;
+
+sub usage {
+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
+ print " [ -no-doc-sections ]\n";
+ print " [ -function funcname [ -function funcname ...] ]\n";
+ print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
+ print " c source file(s) > outputfile\n";
+ print " -v : verbose output, more warnings & other info listed\n";
+ exit 1;
+}
+
# get kernel version from env
sub get_kernel_version() {
my $version = 'unknown kernel version';
@@ -362,15 +369,6 @@ sub get_kernel_version() {
}
return $version;
}
-my $kernelversion = get_kernel_version();
-
-# generate a sequence of code that will splice in highlighting information
-# using the s// operator.
-my $dohighlight = "";
-foreach my $pattern (keys %highlights) {
-# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
- $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
-}
##
# dumps section contents to arrays/hashes intended for that purpose.
@@ -1851,34 +1849,6 @@ sub dump_function($$) {
});
}
-sub process_file($);
-
-# Read the file that maps relative names to absolute names for
-# separate source and object directories and for shadow trees.
-if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
- my ($relname, $absname);
- while(<SOURCE_MAP>) {
- chop();
- ($relname, $absname) = (split())[0..1];
- $relname =~ s:^/+::;
- $source_map{$relname} = $absname;
- }
- close(SOURCE_MAP);
-}
-
-foreach (@ARGV) {
- chomp;
- process_file($_);
-}
-if ($verbose && $errors) {
- print STDERR "$errors errors\n";
-}
-if ($verbose && $warnings) {
- print STDERR "$warnings warnings\n";
-}
-
-exit($errors);
-
sub reset_state {
$function = "";
%constants = ();
@@ -2285,3 +2255,39 @@ sub process_file($) {
}
}
}
+
+
+$kernelversion = get_kernel_version();
+
+# generate a sequence of code that will splice in highlighting information
+# using the s// operator.
+foreach my $pattern (keys %highlights) {
+# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
+ $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
+}
+
+# Read the file that maps relative names to absolute names for
+# separate source and object directories and for shadow trees.
+if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
+ my ($relname, $absname);
+ while(<SOURCE_MAP>) {
+ chop();
+ ($relname, $absname) = (split())[0..1];
+ $relname =~ s:^/+::;
+ $source_map{$relname} = $absname;
+ }
+ close(SOURCE_MAP);
+}
+
+foreach (@ARGV) {
+ chomp;
+ process_file($_);
+}
+if ($verbose && $errors) {
+ print STDERR "$errors errors\n";
+}
+if ($verbose && $warnings) {
+ print STDERR "$warnings warnings\n";
+}
+
+exit($errors);
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 33122ca04e7c..97d2259ae999 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -790,6 +790,7 @@ static const char *section_white_list[] =
{
".comment*",
".debug*",
+ ".zdebug*", /* Compressed debug sections. */
".GCC-command-line", /* mn10300 */
".mdebug*", /* alpha, score, mips etc. */
".pdr", /* alpha, score, mips etc. */
@@ -1441,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
int section = shndx2secindex(sechdr->sh_info);
return (void *)elf->hdr + sechdrs[section].sh_offset +
- r->r_offset - sechdrs[section].sh_addr;
+ r->r_offset;
}
static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 49b74e1ee12d..5fc1e6f71838 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -25,8 +25,44 @@ create_package() {
chown -R root:root "$pdir"
chmod -R go-w "$pdir"
+ # Attempt to find the correct Debian architecture
+ local forcearch="" debarch=""
+ case "$UTS_MACHINE" in
+ i386|ia64|alpha)
+ debarch="$UTS_MACHINE" ;;
+ x86_64)
+ debarch=amd64 ;;
+ sparc*)
+ debarch=sparc ;;
+ s390*)
+ debarch=s390 ;;
+ ppc*)
+ debarch=powerpc ;;
+ parisc*)
+ debarch=hppa ;;
+ mips*)
+ debarch=mips$(grep -q CPU_LITTLE_ENDIAN=y .config && echo el) ;;
+ arm*)
+ debarch=arm$(grep -q CONFIG_AEABI=y .config && echo el) ;;
+ *)
+ echo "" >&2
+ echo "** ** ** WARNING ** ** **" >&2
+ echo "" >&2
+ echo "Your architecture doesn't have it's equivalent" >&2
+ echo "Debian userspace architecture defined!" >&2
+ echo "Falling back to using your current userspace instead!" >&2
+ echo "Please add support for $UTS_MACHINE to ${0} ..." >&2
+ echo "" >&2
+ esac
+ if [ -n "$KBUILD_DEBARCH" ] ; then
+ debarch="$KBUILD_DEBARCH"
+ fi
+ if [ -n "$debarch" ] ; then
+ forcearch="-DArchitecture=$debarch"
+ fi
+
# Create the package
- dpkg-gencontrol -isp -p$pname -P"$pdir"
+ dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir"
dpkg --build "$pdir" ..
}
@@ -40,17 +76,21 @@ else
fi
tmpdir="$objtree/debian/tmp"
fwdir="$objtree/debian/fwtmp"
+hdrdir="$objtree/debian/hdrtmp"
packagename=linux-image-$version
fwpackagename=linux-firmware-image
+hdrpackagename=linux-headers-$version
if [ "$ARCH" = "um" ] ; then
packagename=user-mode-linux-$version
fi
# Setup the directory structure
-rm -rf "$tmpdir" "$fwdir"
-mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename"
-mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename"
+rm -rf "$tmpdir" "$fwdir" "$hdrdir"
+mkdir -m 755 -p "$tmpdir/DEBIAN"
+mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename"
+mkdir -m 755 -p "$fwdir/DEBIAN"
+mkdir -p "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename"
if [ "$ARCH" = "um" ] ; then
mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin"
fi
@@ -188,6 +228,30 @@ EOF
fi
+# Build header package
+find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$
+find arch/x86/include include scripts -type f >> /tmp/files$$
+(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
+destdir=$hdrdir/usr/src/linux-headers-$version
+mkdir -p "$destdir" "$hdrdir/DEBIAN" "$hdrdir/usr/share/doc/$hdrpackagename"
+tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -)
+(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
+rm -f /tmp/files$$ /tmp/objfiles$$
+arch=$(dpkg --print-architecture)
+
+cat <<EOF >> debian/control
+
+Package: $hdrpackagename
+Provides: linux-headers, linux-headers-2.6
+Architecture: $arch
+Description: Linux kernel headers for $KERNELRELEASE on $arch
+ This package provides kernel header files for $KERNELRELEASE on $arch
+ .
+ This is useful for people who need to build external modules
+EOF
+
+create_package "$hdrpackagename" "$hdrdir"
+
# Do we have firmware? Move it out of the way and build it into a package.
if [ -e "$tmpdir/lib/firmware" ]; then
mv "$tmpdir/lib/firmware" "$fwdir/lib/"
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index f2f32eee2c5b..038b3d1e2981 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -38,6 +38,7 @@ static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
static char gpfx; /* prefix for global symbol name (sometimes '_') */
static struct stat sb; /* Remember .st_size, etc. */
static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
+static const char *altmcount; /* alternate mcount symbol name */
/* setjmp() return values */
enum {
@@ -299,7 +300,9 @@ do_file(char const *const fname)
fail_file();
} break;
case EM_386: reltype = R_386_32; break;
- case EM_ARM: reltype = R_ARM_ABS32; break;
+ case EM_ARM: reltype = R_ARM_ABS32;
+ altmcount = "__gnu_mcount_nc";
+ break;
case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
@@ -357,7 +360,7 @@ do_file(char const *const fname)
int
main(int argc, char const *argv[])
{
- const char ftrace[] = "kernel/trace/ftrace.o";
+ const char ftrace[] = "/ftrace.o";
int ftrace_size = sizeof(ftrace) - 1;
int n_error = 0; /* gcc-4.3.0 false positive complaint */
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index 58e933a20544..baf187bee983 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
{
- rp->r_info = ELF_R_INFO(sym, type);
+ rp->r_info = _w(ELF_R_INFO(sym, type));
}
static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
@@ -275,11 +275,12 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
Elf_Sym const *const symp =
&sym0[Elf_r_sym(relp)];
char const *symname = &str0[w(symp->st_name)];
+ char const *mcount = '_' == gpfx ? "_mcount" : "mcount";
if ('.' == symname[0])
++symname; /* ppc64 hack */
- if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"),
- symname))
+ if (0 == strcmp(mcount, symname) ||
+ (altmcount && 0 == strcmp(altmcount, symname)))
mcountsym = Elf_r_sym(relp);
}
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 8509bb512935..92fdc4546141 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -123,9 +123,11 @@ exuberant()
-I ____cacheline_internodealigned_in_smp \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
-I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
- --extra=+f --c-kinds=-px \
+ --extra=+f --c-kinds=+px \
--regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
- --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/'
+ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
+ --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
+ --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
all_kconfigs | xargs $1 -a \
--langdef=kconfig --language-force=kconfig \
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index aef8c0a923ab..d661afbe474c 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -253,6 +253,8 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
result = security_filter_rule_init(entry->lsm[lsm_rule].type,
Audit_equal, args,
&entry->lsm[lsm_rule].rule);
+ if (!entry->lsm[lsm_rule].rule)
+ return -EINVAL;
return result;
}
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 0088dd8bf68a..0ea52d25a6bd 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -403,7 +403,6 @@ link_check_failed:
return ret;
link_prealloc_failed:
- up_write(&dest_keyring->sem);
mutex_unlock(&user->cons_lock);
kleave(" = %d [prelink]", ret);
return ret;
diff --git a/security/security.c b/security/security.c
index 1b798d3df710..c645e263ca8d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -513,6 +513,15 @@ int security_inode_permission(struct inode *inode, int mask)
return security_ops->inode_permission(inode, mask);
}
+int security_inode_exec_permission(struct inode *inode, unsigned int flags)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+ if (flags)
+ return -ECHILD;
+ return security_ops->inode_permission(inode, MAY_EXEC);
+}
+
int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
{
if (unlikely(IS_PRIVATE(dentry->d_inode)))
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 65fa8bf596f5..c82538a4b1a4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4520,11 +4520,11 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
if (selinux_secmark_enabled())
if (avc_has_perm(sksec->sid, skb->secmark,
SECCLASS_PACKET, PACKET__SEND, &ad))
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
if (selinux_policycap_netpeer)
if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
return NF_ACCEPT;
}
@@ -4581,7 +4581,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
secmark_perm = PACKET__SEND;
break;
default:
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
}
if (secmark_perm == PACKET__FORWARD_OUT) {
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
@@ -4603,7 +4603,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
if (secmark_active)
if (avc_has_perm(peer_sid, skb->secmark,
SECCLASS_PACKET, secmark_perm, &ad))
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
if (peerlbl_active) {
u32 if_sid;
@@ -4613,13 +4613,13 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
return NF_DROP;
if (avc_has_perm(peer_sid, if_sid,
SECCLASS_NETIF, NETIF__EGRESS, &ad))
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
if (sel_netnode_sid(addrp, family, &node_sid))
return NF_DROP;
if (avc_has_perm(peer_sid, node_sid,
SECCLASS_NODE, NODE__SENDTO, &ad))
- return NF_DROP;
+ return NF_DROP_ERR(-ECONNREFUSED);
}
return NF_ACCEPT;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 073fd5b0a53a..43deac219491 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1145,24 +1145,28 @@ static void sel_remove_entries(struct dentry *de)
{
struct list_head *node;
- spin_lock(&dcache_lock);
+ spin_lock(&de->d_lock);
node = de->d_subdirs.next;
while (node != &de->d_subdirs) {
struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+
+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
list_del_init(node);
if (d->d_inode) {
- d = dget_locked(d);
- spin_unlock(&dcache_lock);
+ dget_dlock(d);
+ spin_unlock(&de->d_lock);
+ spin_unlock(&d->d_lock);
d_delete(d);
simple_unlink(de->d_inode, d);
dput(d);
- spin_lock(&dcache_lock);
- }
+ spin_lock(&de->d_lock);
+ } else
+ spin_unlock(&d->d_lock);
node = de->d_subdirs.next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&de->d_lock);
}
#define BOOL_DIR_NAME "booleans"
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 1d0bf8fa1922..d1e05b047715 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <net/sock.h>
#include "common.h"
+#include "../../fs/internal.h"
/**
* tomoyo_encode: Convert binary string to ascii string.
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index a351dd0a09c7..2b50cbe6aca9 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -19,8 +19,8 @@
/*
* Let drivers decide whether they want to support given codec from their
- * probe method. Drivers have direct access to the struct snd_ac97 structure and may
- * decide based on the id field amongst other things.
+ * probe method. Drivers have direct access to the struct snd_ac97
+ * structure and may decide based on the id field amongst other things.
*/
static int ac97_bus_match(struct device *dev, struct device_driver *drv)
{
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 91852e49910e..3687a6cc9881 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1114,7 +1114,6 @@ static int onyx_i2c_remove(struct i2c_client *client)
of_node_put(onyx->codec.node);
if (onyx->codec_info)
kfree(onyx->codec_info);
- i2c_set_clientdata(client, onyx);
kfree(onyx);
return 0;
}
diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c
index de8e03afa97b..faa317490545 100644
--- a/sound/aoa/core/gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -287,10 +287,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt)
free_irq(linein_detect_irq, &rt->line_in_notify);
if (rt->line_out_notify.gpio_private)
free_irq(lineout_detect_irq, &rt->line_out_notify);
- cancel_delayed_work(&rt->headphone_notify.work);
- cancel_delayed_work(&rt->line_in_notify.work);
- cancel_delayed_work(&rt->line_out_notify.work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&rt->headphone_notify.work);
+ cancel_delayed_work_sync(&rt->line_in_notify.work);
+ cancel_delayed_work_sync(&rt->line_out_notify.work);
mutex_destroy(&rt->headphone_notify.mutex);
mutex_destroy(&rt->line_in_notify.mutex);
mutex_destroy(&rt->line_out_notify.mutex);
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 7e267c9379bc..c8d8a1a6f964 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -107,10 +107,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt)
/* make sure no work is pending before freeing
* all things */
- cancel_delayed_work(&rt->headphone_notify.work);
- cancel_delayed_work(&rt->line_in_notify.work);
- cancel_delayed_work(&rt->line_out_notify.work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&rt->headphone_notify.work);
+ cancel_delayed_work_sync(&rt->line_in_notify.work);
+ cancel_delayed_work_sync(&rt->line_out_notify.work);
mutex_destroy(&rt->headphone_notify.mutex);
mutex_destroy(&rt->line_in_notify.mutex);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 5c8c7dff8ede..b753ec661fcf 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1510,16 +1510,19 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
{
struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+ int i;
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream != NULL) {
- snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
- substream->runtime->oss.prepare = 1;
- }
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (substream != NULL) {
+ for (i = 0; i < 2; i++) {
+ substream = pcm_oss_file->streams[i];
+ if (!substream)
+ continue;
+ runtime = substream->runtime;
snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
- substream->runtime->oss.prepare = 1;
+ runtime->oss.prepare = 1;
+ runtime->oss.buffer_used = 0;
+ runtime->oss.prev_hw_ptr_period = 0;
+ runtime->oss.period_ptr = 0;
}
return 0;
}
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b75db8e9cc0f..a82e3756a72d 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -373,6 +373,27 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
(unsigned long)new_hw_ptr,
(unsigned long)runtime->hw_ptr_base);
}
+
+ if (runtime->no_period_wakeup) {
+ /*
+ * Without regular period interrupts, we have to check
+ * the elapsed time to detect xruns.
+ */
+ jdelta = jiffies - runtime->hw_ptr_jiffies;
+ if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
+ goto no_delta_check;
+ hdelta = jdelta - delta * HZ / runtime->rate;
+ while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
+ delta += runtime->buffer_size;
+ hw_base += runtime->buffer_size;
+ if (hw_base >= runtime->boundary)
+ hw_base = 0;
+ new_hw_ptr = hw_base + pos;
+ hdelta -= runtime->hw_ptr_buffer_jiffies;
+ }
+ goto no_delta_check;
+ }
+
/* something must be really wrong */
if (delta >= runtime->buffer_size + runtime->period_size) {
hw_ptr_error(substream,
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
(long)old_hw_ptr);
}
+ no_delta_check:
if (runtime->status->hw_ptr == new_hw_ptr)
return 0;
@@ -1070,8 +1092,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
struct snd_pcm_hw_rule *new;
unsigned int new_rules = constrs->rules_all + 16;
new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
- if (!new)
+ if (!new) {
+ va_end(args);
return -ENOMEM;
+ }
if (constrs->rules) {
memcpy(new, constrs->rules,
constrs->rules_num * sizeof(*c));
@@ -1087,8 +1111,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
c->private = private;
k = 0;
while (1) {
- if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps)))
+ if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
+ va_end(args);
return -EINVAL;
+ }
c->deps[k++] = dep;
if (dep < 0)
break;
@@ -1097,7 +1123,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
constrs->rules_num++;
va_end(args);
return 0;
-}
+}
EXPORT_SYMBOL(snd_pcm_hw_rule_add);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e82c1f97d99e..0db714e87a80 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -422,6 +422,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
runtime->info = params->info;
runtime->rate_num = params->rate_num;
runtime->rate_den = params->rate_den;
+ runtime->no_period_wakeup =
+ (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
+ (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
bits = snd_pcm_format_physical_width(runtime->format);
runtime->sample_bits = bits;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index bf09a5ad1865..119fddb6fc99 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -32,6 +32,7 @@
#include "seq_timer.h"
#include "seq_system.h"
#include "seq_info.h"
+#include <sound/minors.h>
#include <sound/seq_device.h>
#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
@@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe
module_param(seq_default_timer_resolution, int, 0644);
MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
+MODULE_ALIAS("devname:snd/seq");
+
/*
* INIT PART
*/
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 66691fe437e6..1c7a3efe1778 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -188,14 +188,22 @@ static const struct file_operations snd_fops =
};
#ifdef CONFIG_SND_DYNAMIC_MINORS
-static int snd_find_free_minor(void)
+static int snd_find_free_minor(int type)
{
int minor;
+ /* static minors for module auto loading */
+ if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
+ return SNDRV_MINOR_SEQUENCER;
+ if (type == SNDRV_DEVICE_TYPE_TIMER)
+ return SNDRV_MINOR_TIMER;
+
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
- /* skip minors still used statically for autoloading devices */
- if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL ||
- minor == SNDRV_MINOR_SEQUENCER)
+ /* skip static minors still used for module auto loading */
+ if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
+ continue;
+ if (minor == SNDRV_MINOR_SEQUENCER ||
+ minor == SNDRV_MINOR_TIMER)
continue;
if (!snd_minors[minor])
return minor;
@@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
preg->private_data = private_data;
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
- minor = snd_find_free_minor();
+ minor = snd_find_free_minor(type);
#else
minor = snd_kernel_minor(type, card, dev);
if (minor >= 0 && snd_minors[minor])
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 13afb60999b9..ed016329e911 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -34,8 +34,8 @@
#include <sound/initval.h>
#include <linux/kmod.h>
-#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
-#define DEFAULT_TIMER_LIMIT 3
+#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
+#define DEFAULT_TIMER_LIMIT 4
#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
#define DEFAULT_TIMER_LIMIT 2
#else
@@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
module_param(timer_tstamp_monotonic, int, 0444);
MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
+MODULE_ALIAS("devname:snd/timer");
+
struct snd_timer_user {
struct snd_timer_instance *timeri;
int tread; /* enhanced read with timestamps and events */
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index a1282c1c0591..5cfcb908c430 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
(resource->start) + 1);
if (ml403_ac97cr->port == NULL) {
snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to remap memory region (%x to %x)\n",
- resource->start, resource->end);
+ "unable to remap memory region (%pR)\n",
+ resource);
snd_ml403_ac97cr_free(ml403_ac97cr);
return -EBUSY;
}
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index 971a84a4fa77..c424d329f806 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -57,8 +57,7 @@ static void snd_ak4113_free(struct ak4113 *chip)
{
chip->init = 1; /* don't schedule new work */
mb();
- cancel_delayed_work(&chip->work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -141,7 +140,7 @@ void snd_ak4113_reinit(struct ak4113 *chip)
{
chip->init = 1;
mb();
- flush_scheduled_work();
+ flush_delayed_work_sync(&chip->work);
ak4113_init_regs(chip);
/* bring up statistics / event queing */
chip->init = 0;
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 0341451f814c..d9fb537b0b94 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -67,8 +67,7 @@ static void snd_ak4114_free(struct ak4114 *chip)
{
chip->init = 1; /* don't schedule new work */
mb();
- cancel_delayed_work(&chip->work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -154,7 +153,7 @@ void snd_ak4114_reinit(struct ak4114 *chip)
{
chip->init = 1;
mb();
- flush_scheduled_work();
+ flush_delayed_work_sync(&chip->work);
ak4114_init_regs(chip);
/* bring up statistics / event queing */
chip->init = 0;
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 46c0d03dbecc..fcb14a099822 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
int i, n;
for (i = 0; i < num_mixer_volumes; i++) {
- if (strcmp(name, mixer_vols[i].name) == 0) {
+ if (strncmp(name, mixer_vols[i].name, 32) == 0) {
if (present)
mixer_vols[i].num = i;
return mixer_vols[i].levels;
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
}
n = num_mixer_volumes++;
- strcpy(mixer_vols[n].name, name);
+ strncpy(mixer_vols[n].name, name, 32);
if (present)
mixer_vols[n].num = n;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 12e34653b8a8..7b2678a25ca0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -209,7 +209,7 @@ config SND_OXYGEN_LIB
tristate
config SND_OXYGEN
- tristate "C-Media 8788 (Oxygen)"
+ tristate "C-Media 8787, 8788 (Oxygen)"
select SND_OXYGEN_LIB
select SND_PCM
select SND_MPU401_UART
@@ -222,8 +222,11 @@ config SND_OXYGEN
* Club3D Theatron DTS
* HT-Omega Claro (plus)
* HT-Omega Claro halo (XT)
+ * Kuroutoshikou CMI8787-HG2PCI
* Razer Barracuda AC-1
* Sondigo Inferno
+ * TempoTec/MediaTek HiFier Fantasia
+ * TempoTec/MediaTek HiFier Serenade
To compile this driver as a module, choose M here: the module
will be called snd-oxygen.
@@ -578,18 +581,6 @@ config SND_HDSPM
To compile this driver as a module, choose M here: the module
will be called snd-hdspm.
-config SND_HIFIER
- tristate "TempoTec HiFier Fantasia"
- select SND_OXYGEN_LIB
- select SND_PCM
- select SND_MPU401_UART
- help
- Say Y here to include support for the MediaTek/TempoTec HiFier
- Fantasia sound card.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hifier.
-
config SND_ICE1712
tristate "ICEnsemble ICE1712 (Envy24)"
select SND_MPU401_UART
@@ -826,7 +817,7 @@ config SND_VIRTUOSO
Say Y here to include support for sound cards based on the
Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
Essence ST (Deluxe), and Essence STX.
- Support for the HDAV1.3 (Deluxe) is incomplete; for the
+ Support for the HDAV1.3 (Deluxe) is experimental; for the
HDAV1.3 Slim and Xense, missing.
To compile this driver as a module, choose M here: the module
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index a7630e9edf8a..0fc614ce16c1 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1014,8 +1014,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
{
if (ac97) {
#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work(&ac97->power_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ac97->power_work);
#endif
snd_ac97_proc_done(ac97);
if (ac97->bus)
@@ -2456,8 +2455,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
if (ac97->build_ops->suspend)
ac97->build_ops->suspend(ac97);
#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work(&ac97->power_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ac97->power_work);
#endif
snd_ac97_powerdown(ac97);
}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 2f3cacbd5528..6117595fc075 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
/*
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de>
+ * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr <andi AT lisas.de>
*
* Framework borrowed from Bart Hartgers's als4000.c.
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -175,6 +175,7 @@
#include <asm/io.h>
#include <linux/init.h>
+#include <linux/bug.h> /* WARN_ONCE */
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/slab.h>
@@ -201,14 +202,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
/* === Debug settings ===
Further diagnostic functionality than the settings below
- does not need to be provided, since one can easily write a bash script
+ does not need to be provided, since one can easily write a POSIX shell script
to dump the card's I/O ports (those listed in lspci -v -v):
- function dump()
+ dump()
{
local descr=$1; local addr=$2; local count=$3
echo "${descr}: ${count} @ ${addr}:"
- dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C
+ dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
+ 2>/dev/null| hexdump -C
}
and then use something like
"dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
@@ -216,14 +218,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
possibly within a "while true; do ... sleep 1; done" loop.
Tweaking ports could be done using
VALSTRING="`printf "%02x" $value`"
- printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null
+ printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
+ 2>/dev/null
*/
#define DEBUG_MISC 0
#define DEBUG_CALLS 0
#define DEBUG_MIXER 0
#define DEBUG_CODEC 0
-#define DEBUG_IO 0
#define DEBUG_TIMER 0
#define DEBUG_GAME 0
#define DEBUG_PM 0
@@ -291,19 +293,23 @@ static int seqtimer_scaling = 128;
module_param(seqtimer_scaling, int, 0444);
MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
-struct snd_azf3328_codec_data {
- unsigned long io_base;
- struct snd_pcm_substream *substream;
- bool running;
- const char *name;
-};
-
enum snd_azf3328_codec_type {
+ /* warning: fixed indices (also used for bitmask checks!) */
AZF_CODEC_PLAYBACK = 0,
AZF_CODEC_CAPTURE = 1,
AZF_CODEC_I2S_OUT = 2,
};
+struct snd_azf3328_codec_data {
+ unsigned long io_base; /* keep first! (avoid offset calc) */
+ unsigned int dma_base; /* helper to avoid an indirection in hotpath */
+ spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
+ struct snd_pcm_substream *substream;
+ bool running;
+ enum snd_azf3328_codec_type type;
+ const char *name;
+};
+
struct snd_azf3328 {
/* often-used fields towards beginning, then grouped */
@@ -362,6 +368,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
static int
snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
{
+ /* Well, strictly spoken, the inb/outb sequence isn't atomic
+ and would need locking. However we currently don't care
+ since it potentially complicates matters. */
u8 prev = inb(reg), new;
new = (do_set) ? (prev|mask) : (prev & ~mask);
@@ -413,6 +422,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
outl(value, codec->io_base + reg);
}
+static inline void
+snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
+ unsigned reg, const void *buffer, int count
+)
+{
+ unsigned long addr = codec->io_base + reg;
+ if (count) {
+ const u32 *buf = buffer;
+ do {
+ outl(*buf++, addr);
+ addr += 4;
+ } while (--count);
+ }
+}
+
static inline u32
snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
{
@@ -943,38 +967,43 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
}
static void
-snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
- enum snd_azf3328_codec_type codec_type,
+snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
enum azf_freq_t bitrate,
unsigned int format_width,
unsigned int channels
)
{
unsigned long flags;
- const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
u16 val = 0xff00;
+ u8 freq = 0;
snd_azf3328_dbgcallenter();
switch (bitrate) {
- case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
- case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
- case AZF_FREQ_5512:
- /* the AZF3328 names it "5510" for some strange reason */
- val |= SOUNDFORMAT_FREQ_5510; break;
- case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
- case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
- case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
- case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
- case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
- case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
- case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
- case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
+#define AZF_FMT_XLATE(in_freq, out_bits) \
+ do { \
+ case AZF_FREQ_ ## in_freq: \
+ freq = SOUNDFORMAT_FREQ_ ## out_bits; \
+ break; \
+ } while (0);
+ AZF_FMT_XLATE(4000, SUSPECTED_4000)
+ AZF_FMT_XLATE(4800, SUSPECTED_4800)
+ /* the AZF3328 names it "5510" for some strange reason: */
+ AZF_FMT_XLATE(5512, 5510)
+ AZF_FMT_XLATE(6620, 6620)
+ AZF_FMT_XLATE(8000, 8000)
+ AZF_FMT_XLATE(9600, 9600)
+ AZF_FMT_XLATE(11025, 11025)
+ AZF_FMT_XLATE(13240, SUSPECTED_13240)
+ AZF_FMT_XLATE(16000, 16000)
+ AZF_FMT_XLATE(22050, 22050)
+ AZF_FMT_XLATE(32000, 32000)
default:
snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
/* fall-through */
- case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
- case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
- case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
+ AZF_FMT_XLATE(44100, 44100)
+ AZF_FMT_XLATE(48000, 48000)
+ AZF_FMT_XLATE(66200, SUSPECTED_66200)
+#undef AZF_FMT_XLATE
}
/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -986,13 +1015,15 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
+ val |= freq;
+
if (channels == 2)
val |= SOUNDFORMAT_FLAG_2CHANNELS;
if (format_width == 16)
val |= SOUNDFORMAT_FLAG_16BIT;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ spin_lock_irqsave(codec->lock, flags);
/* set bitrate/format */
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1004,7 +1035,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
* (FIXME: yes, it works, but what exactly am I doing here?? :)
* FIXME: does this have some side effects for full-duplex
* or other dramatic side effects? */
- if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */
+ /* do it for non-capture codecs only */
+ if (codec->type != AZF_CODEC_CAPTURE)
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
DMA_RUN_SOMETHING1 |
@@ -1014,20 +1046,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
DMA_SOMETHING_ELSE
);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ spin_unlock_irqrestore(codec->lock, flags);
snd_azf3328_dbgcallleave();
}
static inline void
-snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
- enum snd_azf3328_codec_type codec_type
+snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
)
{
/* choose lowest frequency for low power consumption.
* While this will cause louder noise due to rather coarse frequency,
* it should never matter since output should always
* get disabled properly when idle anyway. */
- snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1);
+ snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
}
static void
@@ -1101,69 +1132,87 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
/* ...and adjust clock, too
* (reduce noise and power consumption) */
if (!enable)
- snd_azf3328_codec_setfmt_lowpower(
- chip,
- codec_type
- );
+ snd_azf3328_codec_setfmt_lowpower(codec);
codec->running = enable;
}
}
static void
-snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
- enum snd_azf3328_codec_type codec_type,
+snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
unsigned long addr,
- unsigned int count,
- unsigned int size
+ unsigned int period_bytes,
+ unsigned int buffer_bytes
)
{
- const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
snd_azf3328_dbgcallenter();
+ WARN_ONCE(period_bytes & 1, "odd period length!?\n");
+ WARN_ONCE(buffer_bytes != 2 * period_bytes,
+ "missed our input expectations! %u vs. %u\n",
+ buffer_bytes, period_bytes);
if (!codec->running) {
/* AZF3328 uses a two buffer pointer DMA transfer approach */
- unsigned long flags, addr_area2;
+ unsigned long flags;
/* width 32bit (prevent overflow): */
- u32 count_areas, lengths;
+ u32 area_length;
+ struct codec_setup_io {
+ u32 dma_start_1;
+ u32 dma_start_2;
+ u32 dma_lengths;
+ } __attribute__((packed)) setup_io;
+
+ area_length = buffer_bytes/2;
+
+ setup_io.dma_start_1 = addr;
+ setup_io.dma_start_2 = addr+area_length;
- count_areas = size/2;
- addr_area2 = addr+count_areas;
- snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
- addr, count_areas, addr_area2, count_areas);
+ snd_azf3328_dbgcodec(
+ "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
+ setup_io.dma_start_1, area_length,
+ setup_io.dma_start_2, area_length,
+ period_bytes, buffer_bytes);
- count_areas--; /* max. index */
+ /* Hmm, are we really supposed to decrement this by 1??
+ Most definitely certainly not: configuring full length does
+ work properly (i.e. likely better), and BTW we
+ violated possibly differing frame sizes with this...
+
+ area_length--; |* max. index *|
+ */
/* build combined I/O buffer length word */
- lengths = (count_areas << 16) | (count_areas);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr);
- snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2,
- addr_area2);
- snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS,
- lengths);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ setup_io.dma_lengths = (area_length << 16) | (area_length);
+
+ spin_lock_irqsave(codec->lock, flags);
+ snd_azf3328_codec_outl_multi(
+ codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
+ );
+ spin_unlock_irqrestore(codec->lock, flags);
}
snd_azf3328_dbgcallleave();
}
static int
-snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
+snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
{
-#if 0
- struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_azf3328_codec_data *codec = runtime->private_data;
+#if 0
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
unsigned int count = snd_pcm_lib_period_bytes(substream);
#endif
snd_azf3328_dbgcallenter();
+
+ codec->dma_base = runtime->dma_addr;
+
#if 0
- snd_azf3328_codec_setfmt(chip, AZF_CODEC_...,
+ snd_azf3328_codec_setfmt(codec,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
- snd_azf3328_codec_setdmaa(chip, AZF_CODEC_...,
+ snd_azf3328_codec_setdmaa(codec,
runtime->dma_addr, count, size);
#endif
snd_azf3328_dbgcallleave();
@@ -1171,24 +1220,23 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
}
static int
-snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
- struct snd_pcm_substream *substream, int cmd)
+snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
- const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_azf3328_codec_data *codec = runtime->private_data;
int result = 0;
u16 flags1;
bool previously_muted = 0;
- bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type);
+ bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
- snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd);
+ snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_azf3328_dbgcodec("START %s\n", codec->name);
- if (is_playback_codec) {
+ if (is_main_mixer_playback_codec) {
/* mute WaveOut (avoid clicking during setup) */
previously_muted =
snd_azf3328_mixer_set_mute(
@@ -1196,12 +1244,12 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
);
}
- snd_azf3328_codec_setfmt(chip, codec_type,
+ snd_azf3328_codec_setfmt(codec,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
- spin_lock(&chip->reg_lock);
+ spin_lock(codec->lock);
/* first, remember current value: */
flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
@@ -1211,14 +1259,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
/* FIXME: clear interrupts or what??? */
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
- spin_unlock(&chip->reg_lock);
+ spin_unlock(codec->lock);
- snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr,
+ snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream)
);
- spin_lock(&chip->reg_lock);
+ spin_lock(codec->lock);
#ifdef WIN9X
/* FIXME: enable playback/recording??? */
flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
@@ -1242,10 +1290,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
DMA_EPILOGUE_SOMETHING |
DMA_SOMETHING_ELSE);
#endif
- spin_unlock(&chip->reg_lock);
- snd_azf3328_ctrl_codec_activity(chip, codec_type, 1);
+ spin_unlock(codec->lock);
+ snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
- if (is_playback_codec) {
+ if (is_main_mixer_playback_codec) {
/* now unmute WaveOut */
if (!previously_muted)
snd_azf3328_mixer_set_mute(
@@ -1258,19 +1306,19 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
case SNDRV_PCM_TRIGGER_RESUME:
snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
/* resume codec if we were active */
- spin_lock(&chip->reg_lock);
+ spin_lock(codec->lock);
if (codec->running)
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
snd_azf3328_codec_inw(
codec, IDX_IO_CODEC_DMA_FLAGS
) | DMA_RESUME
);
- spin_unlock(&chip->reg_lock);
+ spin_unlock(codec->lock);
break;
case SNDRV_PCM_TRIGGER_STOP:
snd_azf3328_dbgcodec("STOP %s\n", codec->name);
- if (is_playback_codec) {
+ if (is_main_mixer_playback_codec) {
/* mute WaveOut (avoid clicking during setup) */
previously_muted =
snd_azf3328_mixer_set_mute(
@@ -1278,7 +1326,7 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
);
}
- spin_lock(&chip->reg_lock);
+ spin_lock(codec->lock);
/* first, remember current value: */
flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
@@ -1293,10 +1341,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
flags1 &= ~DMA_RUN_SOMETHING1;
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- spin_unlock(&chip->reg_lock);
- snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
+ spin_unlock(codec->lock);
+ snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
- if (is_playback_codec) {
+ if (is_main_mixer_playback_codec) {
/* now unmute WaveOut */
if (!previously_muted)
snd_azf3328_mixer_set_mute(
@@ -1330,67 +1378,29 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
return result;
}
-static int
-snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
-}
-
-static int
-snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
-}
-
-static int
-snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
-}
-
static snd_pcm_uframes_t
-snd_azf3328_codec_pointer(struct snd_pcm_substream *substream,
- enum snd_azf3328_codec_type codec_type
+snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
)
{
- const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
- const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
- unsigned long bufptr, result;
+ const struct snd_azf3328_codec_data *codec =
+ substream->runtime->private_data;
+ unsigned long result;
snd_pcm_uframes_t frmres;
-#ifdef QUERY_HARDWARE
- bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
-#else
- bufptr = substream->runtime->dma_addr;
-#endif
result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
/* calculate offset */
- result -= bufptr;
+#ifdef QUERY_HARDWARE
+ result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
+#else
+ result -= codec->dma_base;
+#endif
frmres = bytes_to_frames( substream->runtime, result);
- snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n",
- codec->name, result, frmres);
+ snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
+ jiffies, codec->name, result, frmres);
return frmres;
}
-static snd_pcm_uframes_t
-snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
-}
-
-static snd_pcm_uframes_t
-snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
-}
-
-static snd_pcm_uframes_t
-snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
-}
-
/******************************************************************/
#ifdef SUPPORT_GAMEPORT
@@ -1532,7 +1542,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
}
}
- /* trigger next axes sampling, to be evaluated the next time we
+ /* trigger next sampling of axes, to be evaluated the next time we
* enter this function */
/* for some very, very strange reason we cannot enable
@@ -1624,29 +1634,29 @@ snd_azf3328_irq_log_unknown_type(u8 which)
}
static inline void
-snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status)
+snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
+ u8 status
+)
{
u8 which;
enum snd_azf3328_codec_type codec_type;
- const struct snd_azf3328_codec_data *codec;
+ const struct snd_azf3328_codec_data *codec = first_codec;
for (codec_type = AZF_CODEC_PLAYBACK;
codec_type <= AZF_CODEC_I2S_OUT;
- ++codec_type) {
+ ++codec_type, ++codec) {
/* skip codec if there's no interrupt for it */
if (!(status & (1 << codec_type)))
continue;
- codec = &chip->codecs[codec_type];
-
- spin_lock(&chip->reg_lock);
+ spin_lock(codec->lock);
which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
/* ack all IRQ types immediately */
snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
- spin_unlock(&chip->reg_lock);
+ spin_unlock(codec->lock);
- if ((chip->pcm[codec_type]) && (codec->substream)) {
+ if (codec->substream) {
snd_pcm_period_elapsed(codec->substream);
snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
codec->name,
@@ -1701,7 +1711,7 @@ snd_azf3328_interrupt(int irq, void *dev_id)
}
if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
- snd_azf3328_codec_interrupt(chip, status);
+ snd_azf3328_pcm_interrupt(chip->codecs, status);
if (status & IRQ_GAMEPORT)
snd_azf3328_gameport_interrupt(chip);
@@ -1789,101 +1799,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
{
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
snd_azf3328_dbgcallenter();
- chip->codecs[codec_type].substream = substream;
+ codec->substream = substream;
/* same parameters for all our codecs - at least we think so... */
runtime->hw = snd_azf3328_hardware;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&snd_azf3328_hw_constraints_rates);
+ runtime->private_data = codec;
snd_azf3328_dbgcallleave();
return 0;
}
static int
-snd_azf3328_playback_open(struct snd_pcm_substream *substream)
+snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
{
return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
}
static int
-snd_azf3328_capture_open(struct snd_pcm_substream *substream)
+snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
{
return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
}
static int
-snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream)
+snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
{
return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
}
static int
-snd_azf3328_pcm_close(struct snd_pcm_substream *substream,
- enum snd_azf3328_codec_type codec_type
+snd_azf3328_pcm_close(struct snd_pcm_substream *substream
)
{
- struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+ struct snd_azf3328_codec_data *codec =
+ substream->runtime->private_data;
snd_azf3328_dbgcallenter();
- chip->codecs[codec_type].substream = NULL;
+ codec->substream = NULL;
snd_azf3328_dbgcallleave();
return 0;
}
-static int
-snd_azf3328_playback_close(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
-}
-
-static int
-snd_azf3328_capture_close(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
-}
-
-static int
-snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
-}
-
/******************************************************************/
static struct snd_pcm_ops snd_azf3328_playback_ops = {
- .open = snd_azf3328_playback_open,
- .close = snd_azf3328_playback_close,
+ .open = snd_azf3328_pcm_playback_open,
+ .close = snd_azf3328_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_azf3328_hw_params,
.hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_codec_prepare,
- .trigger = snd_azf3328_codec_playback_trigger,
- .pointer = snd_azf3328_codec_playback_pointer
+ .prepare = snd_azf3328_pcm_prepare,
+ .trigger = snd_azf3328_pcm_trigger,
+ .pointer = snd_azf3328_pcm_pointer
};
static struct snd_pcm_ops snd_azf3328_capture_ops = {
- .open = snd_azf3328_capture_open,
- .close = snd_azf3328_capture_close,
+ .open = snd_azf3328_pcm_capture_open,
+ .close = snd_azf3328_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_azf3328_hw_params,
.hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_codec_prepare,
- .trigger = snd_azf3328_codec_capture_trigger,
- .pointer = snd_azf3328_codec_capture_pointer
+ .prepare = snd_azf3328_pcm_prepare,
+ .trigger = snd_azf3328_pcm_trigger,
+ .pointer = snd_azf3328_pcm_pointer
};
static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
- .open = snd_azf3328_i2s_out_open,
- .close = snd_azf3328_i2s_out_close,
+ .open = snd_azf3328_pcm_i2s_out_open,
+ .close = snd_azf3328_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_azf3328_hw_params,
.hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_codec_prepare,
- .trigger = snd_azf3328_codec_i2s_out_trigger,
- .pointer = snd_azf3328_codec_i2s_out_pointer
+ .prepare = snd_azf3328_pcm_prepare,
+ .trigger = snd_azf3328_pcm_trigger,
+ .pointer = snd_azf3328_pcm_pointer
};
static int __devinit
@@ -1966,7 +1960,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
delay = 49; /* minimum time is 49 ticks */
}
- snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
+ snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
spin_lock_irqsave(&chip->reg_lock, flags);
snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
@@ -2180,6 +2174,7 @@ snd_azf3328_create(struct snd_card *card,
};
u8 dma_init;
enum snd_azf3328_codec_type codec_type;
+ struct snd_azf3328_codec_data *codec_setup;
*rchip = NULL;
@@ -2217,15 +2212,23 @@ snd_azf3328_create(struct snd_card *card,
chip->opl3_io = pci_resource_start(pci, 3);
chip->mixer_io = pci_resource_start(pci, 4);
- chip->codecs[AZF_CODEC_PLAYBACK].io_base =
- chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
- chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK";
- chip->codecs[AZF_CODEC_CAPTURE].io_base =
- chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
- chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE";
- chip->codecs[AZF_CODEC_I2S_OUT].io_base =
- chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
- chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT";
+ codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
+ codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
+ codec_setup->lock = &chip->reg_lock;
+ codec_setup->type = AZF_CODEC_PLAYBACK;
+ codec_setup->name = "PLAYBACK";
+
+ codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
+ codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
+ codec_setup->lock = &chip->reg_lock;
+ codec_setup->type = AZF_CODEC_CAPTURE;
+ codec_setup->name = "CAPTURE";
+
+ codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
+ codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
+ codec_setup->lock = &chip->reg_lock;
+ codec_setup->type = AZF_CODEC_I2S_OUT;
+ codec_setup->name = "I2S_OUT";
if (request_irq(pci->irq, snd_azf3328_interrupt,
IRQF_SHARED, card->shortname, chip)) {
@@ -2257,15 +2260,15 @@ snd_azf3328_create(struct snd_card *card,
struct snd_azf3328_codec_data *codec =
&chip->codecs[codec_type];
- /* shutdown codecs to save power */
+ /* shutdown codecs to reduce power / noise */
/* have ...ctrl_codec_activity() act properly */
codec->running = 1;
snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
- spin_lock_irq(&chip->reg_lock);
+ spin_lock_irq(codec->lock);
snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
dma_init);
- spin_unlock_irq(&chip->reg_lock);
+ spin_unlock_irq(codec->lock);
}
snd_card_set_dev(card, &pci->dev);
@@ -2419,6 +2422,7 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ /* same pcm object for playback/capture */
snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index a3301cc4ab82..185b00088320 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
int i;
pci_set_power_state(pci, PCI_D0);
- if (pci_restore_state(pci) < 0) {
- printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
+ pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
"disabling device\n");
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 644e3f14f8ca..98b6d02a36c9 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
+static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
+{
+ int idx;
+ for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
+ if (!_snd_hda_find_mixer_ctl(codec, name, idx))
+ return idx;
+ }
+ return -EBUSY;
+}
+
/**
* snd_hda_ctl_add - Add a control element and assign to the codec
* @codec: HD-audio codec
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ } /* end */
};
-#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
-
/**
* snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
* @codec: the HDA codec
@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
struct snd_kcontrol_new *dig_mix;
int idx;
- for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
- if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
- idx))
- break;
- }
- if (idx >= SPDIF_MAX_IDX) {
+ idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
+ if (idx < 0) {
printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
return -EBUSY;
}
@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
struct snd_kcontrol_new *dig_mix;
int idx;
- for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
- if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
- idx))
- break;
- }
- if (idx >= SPDIF_MAX_IDX) {
+ idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
+ if (idx < 0) {
printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
return -EBUSY;
}
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
for (; knew->name; knew++) {
struct snd_kcontrol *kctl;
+ int addr = 0, idx = 0;
if (knew->iface == -1) /* skip this codec private value */
continue;
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0) {
- if (!codec->addr)
- return err;
+ for (;;) {
kctl = snd_ctl_new1(knew, codec);
if (!kctl)
return -ENOMEM;
- kctl->id.device = codec->addr;
+ if (addr > 0)
+ kctl->id.device = addr;
+ if (idx > 0)
+ kctl->id.index = idx;
err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
+ if (!err)
+ break;
+ /* try first with another device index corresponding to
+ * the codec addr; if it still fails (or it's the
+ * primary codec), then try another control index
+ */
+ if (!addr && codec->addr)
+ addr = codec->addr;
+ else if (!idx && !knew->index) {
+ idx = find_empty_mixer_ctl_idx(codec,
+ knew->name);
+ if (idx <= 0)
+ return err;
+ } else
return err;
}
}
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index cb0c23a6b473..4a663471dadc 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
a->channels = GRAB_BITS(buf, 0, 0, 3);
a->channels++;
+ a->sample_bits = 0;
+ a->max_bitrate = 0;
+
a->format = GRAB_BITS(buf, 0, 3, 4);
switch (a->format) {
case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
case AUDIO_CODING_TYPE_LPCM:
val = GRAB_BITS(buf, 2, 0, 3);
- a->sample_bits = 0;
for (i = 0; i < 3; i++)
if (val & (1 << i))
a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
{
int i;
- pcm->rates = 0;
- pcm->formats = 0;
- pcm->maxbps = 0;
- pcm->channels_min = -1;
- pcm->channels_max = 0;
+ /* assume basic audio support (the basic audio flag is not in ELD;
+ * however, all audio capable sinks are required to support basic
+ * audio) */
+ pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
+ pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
+ pcm->maxbps = 16;
+ pcm->channels_max = 2;
for (i = 0; i < eld->sad_count; i++) {
struct cea_sad *a = &eld->sad[i];
pcm->rates |= a->rates;
- if (a->channels < pcm->channels_min)
- pcm->channels_min = a->channels;
if (a->channels > pcm->channels_max)
pcm->channels_max = a->channels;
if (a->format == AUDIO_CODING_TYPE_LPCM) {
- if (a->sample_bits & AC_SUPPCM_BITS_16) {
- pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
- if (pcm->maxbps < 16)
- pcm->maxbps = 16;
- }
if (a->sample_bits & AC_SUPPCM_BITS_20) {
pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
/* restrict the parameters by the values the codec provides */
pcm->rates &= codec_pars->rates;
pcm->formats &= codec_pars->formats;
- pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21aa9b0e28f6..d3d18be483e1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip,
pos_adj = 0;
} else {
ofs = setup_bdle(substream, azx_dev,
- &bdl, ofs, pos_adj, 1);
+ &bdl, ofs, pos_adj,
+ !substream->runtime->no_period_wakeup);
if (ofs < 0)
goto error;
}
@@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip,
period_bytes - pos_adj, 0);
else
ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
- period_bytes, 1);
+ period_bytes,
+ !substream->runtime->no_period_wakeup);
if (ofs < 0)
goto error;
}
@@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
/* No full-resume yet implemented */
/* SNDRV_PCM_INFO_RESUME |*/
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
@@ -2296,9 +2299,11 @@ static int azx_dev_free(struct snd_device *device)
*/
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
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(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 846d1ead47fd..74291f744c68 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -869,16 +869,16 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
}
static struct snd_kcontrol_new cxt5045_mixers[] = {
- HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -910,16 +910,16 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
};
static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
- HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -947,7 +947,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -960,7 +960,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
};
static struct hda_verb cxt5045_benq_init_verbs[] = {
- /* Int Mic, Mic */
+ /* Internal Mic, Mic */
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
/* Line In,HP, Amp */
@@ -973,7 +973,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -1796,8 +1796,8 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
{}
@@ -1806,8 +1806,8 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
{}
};
@@ -1826,8 +1826,8 @@ static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
{}
};
@@ -1847,7 +1847,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
/* DAC1 */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1874,7 +1874,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
/* DAC1 */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
/* SPDIF route: PCM */
@@ -1904,7 +1904,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
{0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
/* DAC1 */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1932,7 +1932,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
/* DAC1 */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Int mic */
+ /* Record selector: Internal mic */
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
/* SPDIF route: PCM */
@@ -2111,25 +2111,35 @@ static struct hda_channel_mode cxt5066_modes[1] = {
{ 2, NULL },
};
+#define HP_PRESENT_PORT_A (1 << 0)
+#define HP_PRESENT_PORT_D (1 << 1)
+#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
+#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
+
static void cxt5066_update_speaker(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
unsigned int pinctl;
- snd_printdd("CXT5066: update speaker, hp_present=%d\n",
- spec->hp_present);
+ snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+ spec->hp_present, spec->cur_eapd);
/* Port A (HP) */
- pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
+ pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
/* Port D (HP/LO) */
- pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
- ? spec->port_d_mode : 0;
- /* Mute if Port A is connected on Thinkpad */
- if (spec->thinkpad && (spec->hp_present & 1))
- pinctl = 0;
+ pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
+ if (spec->dell_automute || spec->thinkpad) {
+ /* Mute if Port A is connected */
+ if (hp_port_a_present(spec))
+ pinctl = 0;
+ } else {
+ /* Thinkpad/Dell doesn't give pin-D status */
+ if (!hp_port_d_present(spec))
+ pinctl = 0;
+ }
snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
@@ -2137,14 +2147,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
-
- if (spec->dell_automute) {
- /* DELL AIO Port Rule: PortA > PortD > IntSpk */
- pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
- ? PIN_OUT : 0;
- snd_hda_codec_write(codec, 0x1c, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
- }
}
/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2378,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
/* Port D */
portD = snd_hda_jack_detect(codec, 0x1c);
- spec->hp_present = !!(portA);
- spec->hp_present |= portD ? 2 : 0;
+ spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
+ spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
portA, portD, spec->hp_present);
cxt5066_update_speaker(codec);
@@ -2727,7 +2729,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Int Mic Boost Capture Enum",
+ .name = "Internal Mic Boost Capture Enum",
.info = cxt5066_mic_boost_mux_enum_info,
.get = cxt5066_mic_boost_mux_enum_get,
.put = cxt5066_mic_boost_mux_enum_put,
@@ -2953,7 +2955,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
/* internal microphone */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
+ {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
/* EAPD */
{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3008,7 +3010,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
/* internal microphone */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
+ {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
/* EAPD */
{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3095,8 +3097,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
- SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
- CXT5066_DELL_LAPTOP),
+ SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3109,6 +3110,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+ SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
@@ -3421,6 +3423,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
AC_VERB_SET_PIN_WIDGET_CONTROL,
present ? 0 : PIN_OUT);
}
+ for (i = 0; !present && i < cfg->line_outs; i++)
+ if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
+ present = 1;
for (i = 0; i < cfg->speaker_outs; i++) {
snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d3e49aa5b9ec..d1b1b5796c98 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
return -ENODEV;
} else {
/* fallback to the codec default */
- hinfo->channels_min = codec_pars->channels_min;
hinfo->channels_max = codec_pars->channels_max;
hinfo->rates = codec_pars->rates;
hinfo->formats = codec_pars->formats;
@@ -905,23 +904,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
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)
{
+ int i, found_pin = 0;
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 -E2BIG;
+ for (i = 0; i < spec->num_pins; i++)
+ if (nid == spec->pin_cvt[i]) {
+ found_pin = 1;
+ break;
+ }
+
+ if (!found_pin) {
+ snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
+ return -EINVAL;
}
+ if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
+ return -E2BIG;
+
spec->cvt[spec->num_cvts] = nid;
spec->num_cvts++;
@@ -932,6 +936,8 @@ static int hdmi_parse_codec(struct hda_codec *codec)
{
hda_nid_t nid;
int i, nodes;
+ int num_tmp_cvts = 0;
+ hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
if (!nid || nodes < 0) {
@@ -942,6 +948,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
for (i = 0; i < nodes; i++, nid++) {
unsigned int caps;
unsigned int type;
+ unsigned int config;
caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
type = get_wcaps_type(caps);
@@ -951,17 +958,32 @@ static int hdmi_parse_codec(struct hda_codec *codec)
switch (type) {
case AC_WID_AUD_OUT:
- hdmi_add_cvt(codec, nid);
+ if (num_tmp_cvts >= MAX_HDMI_CVTS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for converter %d\n", nid);
+ continue;
+ }
+ tmp_cvt[num_tmp_cvts] = nid;
+ num_tmp_cvts++;
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;
+
+ config = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
+ if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
+ continue;
+
hdmi_add_pin(codec, nid);
break;
}
}
+ for (i = 0; i < num_tmp_cvts; i++)
+ hdmi_add_cvt(codec, tmp_cvt[i]);
+
/*
* G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
* can be lost and presence sense verb will become inaccurate if the
@@ -1533,7 +1555,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = {
{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
-{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
+{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 886d7c72936e..f39efa440c0f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -231,7 +231,6 @@ enum {
ALC888_ACER_ASPIRE_8930G,
ALC888_ACER_ASPIRE_7730G,
ALC883_MEDION,
- ALC883_MEDION_MD2,
ALC883_MEDION_WIM2160,
ALC883_LAPTOP_EAPD,
ALC883_LENOVO_101E_2ch,
@@ -1678,29 +1677,32 @@ struct alc_pincfg {
u32 val;
};
+struct alc_model_fixup {
+ const int id;
+ const char *name;
+};
+
struct alc_fixup {
unsigned int sku;
const struct alc_pincfg *pins;
const struct hda_verb *verbs;
+ void (*func)(struct hda_codec *codec, const struct alc_fixup *fix,
+ int pre_init);
};
-static void alc_pick_fixup(struct hda_codec *codec,
- const struct snd_pci_quirk *quirk,
- const struct alc_fixup *fix,
- int pre_init)
+static void __alc_pick_fixup(struct hda_codec *codec,
+ const struct alc_fixup *fix,
+ const char *modelname,
+ int pre_init)
{
const struct alc_pincfg *cfg;
struct alc_spec *spec;
- quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (!quirk)
- return;
- fix += quirk->value;
cfg = fix->pins;
if (pre_init && fix->sku) {
#ifdef CONFIG_SND_DEBUG_VERBOSE
snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
- codec->chip_name, quirk->name);
+ codec->chip_name, modelname);
#endif
spec = codec->spec;
spec->cdefine.sku_cfg = fix->sku;
@@ -1709,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
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);
+ codec->chip_name, modelname);
#endif
for (; cfg->nid; cfg++)
snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
@@ -1717,10 +1719,53 @@ static void alc_pick_fixup(struct hda_codec *codec,
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);
+ codec->chip_name, modelname);
#endif
add_verb(codec->spec, fix->verbs);
}
+ if (fix->func) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
+ codec->chip_name, modelname);
+#endif
+ fix->func(codec, fix, pre_init);
+ }
+}
+
+static void alc_pick_fixup(struct hda_codec *codec,
+ const struct snd_pci_quirk *quirk,
+ const struct alc_fixup *fix,
+ int pre_init)
+{
+ quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
+ if (quirk) {
+ fix += quirk->value;
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ __alc_pick_fixup(codec, fix, quirk->name, pre_init);
+#else
+ __alc_pick_fixup(codec, fix, NULL, pre_init);
+#endif
+ }
+}
+
+static void alc_pick_fixup_model(struct hda_codec *codec,
+ const struct alc_model_fixup *models,
+ const struct snd_pci_quirk *quirk,
+ const struct alc_fixup *fix,
+ int pre_init)
+{
+ if (codec->modelname && models) {
+ while (models->name) {
+ if (!strcmp(codec->modelname, models->name)) {
+ fix += models->id;
+ break;
+ }
+ models++;
+ }
+ __alc_pick_fixup(codec, fix, codec->modelname, pre_init);
+ } else {
+ alc_pick_fixup(codec, quirk, fix, pre_init);
+ }
}
static int alc_read_coef_idx(struct hda_codec *codec,
@@ -2120,17 +2165,17 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
{
.num_items = 5,
.items = {
- { "Ext Mic", 0x0 },
+ { "Mic", 0x0 },
{ "Line In", 0x2 },
{ "CD", 0x4 },
{ "Input Mix", 0xa },
- { "Int Mic", 0xb },
+ { "Internal Mic", 0xb },
},
},
{
.num_items = 4,
.items = {
- { "Ext Mic", 0x0 },
+ { "Mic", 0x0 },
{ "Line In", 0x2 },
{ "CD", 0x4 },
{ "Input Mix", 0xa },
@@ -2796,10 +2841,10 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -3307,7 +3352,7 @@ static struct hda_verb alc880_beep_init_verbs[] = {
};
/* auto-toggle front mic */
-static void alc880_uniwill_mic_automute(struct hda_codec *codec)
+static void alc88x_simple_mic_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
@@ -3329,7 +3374,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
static void alc880_uniwill_init_hook(struct hda_codec *codec)
{
alc_automute_amp(codec);
- alc880_uniwill_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
}
static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -3340,7 +3385,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
*/
switch (res >> 28) {
case ALC880_MIC_EVENT:
- alc880_uniwill_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
break;
default:
alc_automute_amp_unsol_event(codec, res);
@@ -4595,6 +4640,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
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),
+ SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -7405,7 +7451,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
.num_items = 4,
.items = {
{ "Mic", 0x0 },
- { "Int Mic", 0x1 },
+ { "Internal Mic", 0x1 },
{ "Line", 0x2 },
{ "CD", 0x4 },
},
@@ -7415,7 +7461,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
.num_items = 2,
.items = {
{ "Mic", 0x0 },
- { "Int Mic", 0x1 },
+ { "Internal Mic", 0x1 },
},
};
@@ -8778,9 +8824,9 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -8792,9 +8838,9 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -8940,18 +8986,18 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -8975,21 +9021,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -9181,16 +9214,6 @@ static void alc883_mitac_setup(struct hda_codec *codec)
spec->autocfg.speaker_pins[1] = 0x17;
}
-/* auto-toggle front mic */
-/*
-static void alc883_mitac_mic_automute(struct hda_codec *codec)
-{
- unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
-
- snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
-}
-*/
-
static struct hda_verb alc883_mitac_verbs[] = {
/* HP */
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -9434,18 +9457,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
alc888_lenovo_ms7195_rca_automute(codec);
}
-static struct hda_verb alc883_medion_md2_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-
- {0x14, 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_md2_setup(struct hda_codec *codec)
+static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -9457,15 +9470,6 @@ static void alc883_medion_md2_setup(struct hda_codec *codec)
#define alc883_targa_init_hook alc882_targa_init_hook
#define alc883_targa_unsol_event alc882_targa_unsol_event
-static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x18);
- snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-}
-
static void alc883_clevo_m720_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -9477,7 +9481,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)
static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
{
alc_automute_amp(codec);
- alc883_clevo_m720_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
}
static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
@@ -9485,7 +9489,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
{
switch (res >> 26) {
case ALC880_MIC_EVENT:
- alc883_clevo_m720_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
break;
default:
alc_automute_amp_unsol_event(codec, res);
@@ -9730,7 +9734,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
[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",
@@ -9865,7 +9868,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
- SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@ -10379,19 +10381,6 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source,
},
- [ALC883_MEDION_MD2] = {
- .mixers = { alc883_medion_md2_mixer},
- .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .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_md2_setup,
- .init_hook = alc_automute_amp,
- },
[ALC883_MEDION_WIM2160] = {
.mixers = { alc883_medion_wim2160_mixer },
.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
@@ -10468,7 +10457,7 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_nb0763_capture_source,
.unsol_event = alc_automute_amp_unsol_event,
- .setup = alc883_medion_md2_setup,
+ .setup = alc883_lenovo_nb0763_setup,
.init_hook = alc_automute_amp,
},
[ALC888_LENOVO_MS7195_DIG] = {
@@ -10830,7 +10819,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err;
+ int i, err, type;
+ int type_idx = 0;
hda_nid_t nid;
for (i = 0; i < cfg->num_inputs; i++) {
@@ -10839,9 +10829,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
nid = cfg->inputs[i].pin;
if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
char label[32];
+ type = cfg->inputs[i].type;
+ if (i > 0 && type == cfg->inputs[i - 1].type)
+ type_idx++;
+ else
+ type_idx = 0;
snprintf(label, sizeof(label), "%s Boost",
hda_get_autocfg_input_label(codec, cfg, i));
- err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, label,
+ type_idx,
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
if (err < 0)
return err;
@@ -11680,7 +11676,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = {
.num_items = 3,
.items = {
{ "Mic", 0x0 },
- { "Int Mic", 0x1 },
+ { "Internal Mic", 0x1 },
{ "CD", 0x4 },
},
};
@@ -11835,9 +11831,9 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -11871,9 +11867,9 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -13251,8 +13247,8 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
{ }
};
@@ -14799,7 +14795,10 @@ static int alc269_resume(struct hda_codec *codec)
enum {
ALC269_FIXUP_SONY_VAIO,
+ ALC275_FIX_SONY_VAIO_GPIO2,
ALC269_FIXUP_DELL_M101Z,
+ ALC269_FIXUP_SKU_IGNORE,
+ ALC269_FIXUP_ASUS_G73JW,
};
static const struct alc_fixup alc269_fixups[] = {
@@ -14809,6 +14808,14 @@ static const struct alc_fixup alc269_fixups[] = {
{}
}
},
+ [ALC275_FIX_SONY_VAIO_GPIO2] = {
+ .verbs = (const struct hda_verb[]) {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+ { }
+ }
+ },
[ALC269_FIXUP_DELL_M101Z] = {
.verbs = (const struct hda_verb[]) {
/* Enables internal speaker */
@@ -14817,11 +14824,26 @@ static const struct alc_fixup alc269_fixups[] = {
{}
}
},
+ [ALC269_FIXUP_SKU_IGNORE] = {
+ .sku = ALC_FIXUP_SKU_IGNORE,
+ },
+ [ALC269_FIXUP_ASUS_G73JW] = {
+ .pins = (const struct alc_pincfg[]) {
+ { 0x17, 0x99130111 }, /* subwoofer */
+ { }
+ }
+ },
};
static struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
+ SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
+ SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
+ SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
+ SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
+ SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
{}
};
@@ -15071,28 +15093,29 @@ static int patch_alc269(struct hda_codec *codec)
alc_auto_parse_customize_define(codec);
- coef = alc_read_coef_idx(codec, 0);
- if ((coef & 0x00f0) == 0x0010) {
- if (codec->bus->pci->subsystem_vendor == 0x1025 &&
- spec->cdefine.platform_type == 1) {
- alc_codec_rename(codec, "ALC271X");
- spec->codec_variant = ALC269_TYPE_ALC271X;
- } else if ((coef & 0xf000) == 0x1000) {
- spec->codec_variant = ALC269_TYPE_ALC270;
- } else if ((coef & 0xf000) == 0x2000) {
- alc_codec_rename(codec, "ALC259");
- spec->codec_variant = ALC269_TYPE_ALC259;
- } else if ((coef & 0xf000) == 0x3000) {
- alc_codec_rename(codec, "ALC258");
- spec->codec_variant = ALC269_TYPE_ALC258;
- } else {
- alc_codec_rename(codec, "ALC269VB");
- spec->codec_variant = ALC269_TYPE_ALC269VB;
- }
- } else
- alc_fix_pll_init(codec, 0x20, 0x04, 15);
-
- alc269_fill_coef(codec);
+ if (codec->vendor_id == 0x10ec0269) {
+ coef = alc_read_coef_idx(codec, 0);
+ if ((coef & 0x00f0) == 0x0010) {
+ if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+ spec->cdefine.platform_type == 1) {
+ alc_codec_rename(codec, "ALC271X");
+ spec->codec_variant = ALC269_TYPE_ALC271X;
+ } else if ((coef & 0xf000) == 0x1000) {
+ spec->codec_variant = ALC269_TYPE_ALC270;
+ } else if ((coef & 0xf000) == 0x2000) {
+ alc_codec_rename(codec, "ALC259");
+ spec->codec_variant = ALC269_TYPE_ALC259;
+ } else if ((coef & 0xf000) == 0x3000) {
+ alc_codec_rename(codec, "ALC258");
+ spec->codec_variant = ALC269_TYPE_ALC258;
+ } else {
+ alc_codec_rename(codec, "ALC269VB");
+ spec->codec_variant = ALC269_TYPE_ALC269VB;
+ }
+ } else
+ alc_fix_pll_init(codec, 0x20, 0x04, 15);
+ alc269_fill_coef(codec);
+ }
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models,
@@ -16370,8 +16393,8 @@ static struct hda_input_mux alc861vd_capture_source = {
static struct hda_input_mux alc861vd_dallas_capture_source = {
.num_items = 2,
.items = {
- { "Ext Mic", 0x0 },
- { "Int Mic", 0x1 },
+ { "Mic", 0x0 },
+ { "Internal Mic", 0x1 },
},
};
@@ -16512,19 +16535,19 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
};
/* Pin assignment: Speaker=0x14, HP = 0x15,
- * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
+ * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
*/
static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -16689,18 +16712,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
{}
};
-static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
-{
- unsigned int present;
- unsigned char bits;
-
- present = snd_hda_jack_detect(codec, 0x18);
- bits = present ? HDA_AMP_MUTE : 0;
-
- snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
- HDA_AMP_MUTE, bits);
-}
-
static void alc861vd_lenovo_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -16711,7 +16722,7 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec)
static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
{
alc_automute_amp(codec);
- alc861vd_lenovo_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
}
static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
@@ -16719,7 +16730,7 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
{
switch (res >> 26) {
case ALC880_MIC_EVENT:
- alc861vd_lenovo_mic_automute(codec);
+ alc88x_simple_mic_automute(codec);
break;
default:
alc_automute_amp_unsol_event(codec, res);
@@ -17536,13 +17547,13 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -17686,8 +17697,8 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -17698,8 +17709,8 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
{ } /* end */
@@ -18532,13 +18543,13 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -18549,13 +18560,13 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = {
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
{ } /* end */
};
@@ -19324,9 +19335,21 @@ static void alc662_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
+static void alc272_fixup_mario(struct hda_codec *codec,
+ const struct alc_fixup *fix, int pre_init) {
+ if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
+ (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (0 << AC_AMPCAP_MUTE_SHIFT)))
+ printk(KERN_WARNING
+ "hda_codec: failed to override amp caps for NID 0x2\n");
+}
+
enum {
ALC662_FIXUP_ASPIRE,
ALC662_FIXUP_IDEAPAD,
+ ALC272_FIXUP_MARIO,
};
static const struct alc_fixup alc662_fixups[] = {
@@ -19342,6 +19365,9 @@ static const struct alc_fixup alc662_fixups[] = {
{ }
}
},
+ [ALC272_FIXUP_MARIO] = {
+ .func = alc272_fixup_mario,
+ }
};
static struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -19352,6 +19378,10 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = {
{}
};
+static const struct alc_model_fixup alc662_fixup_models[] = {
+ {.id = ALC272_FIXUP_MARIO, .name = "mario"},
+ {}
+};
static int patch_alc662(struct hda_codec *codec)
@@ -19451,7 +19481,8 @@ static int patch_alc662(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC662_AUTO) {
spec->init_hook = alc662_auto_init;
- alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
+ alc_pick_fixup_model(codec, alc662_fixup_models,
+ alc662_fixup_tbl, alc662_fixups, 0);
}
alc_init_jacks(codec);
@@ -19578,7 +19609,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = {
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x12, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
{ }
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 5c710807dfe5..6131a92f0898 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1627,6 +1627,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
"Alienware M17x", STAC_ALIENWARE_M17X),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
+ "Alienware M17x", STAC_ALIENWARE_M17X),
{} /* terminator */
};
@@ -3479,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
label = hda_get_input_pin_label(codec, nid, 1);
snd_hda_add_imux_item(dimux, label, index, &type_idx);
+ if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
+ snd_hda_add_imux_item(imux, label, index, &type_idx);
err = create_elem_capture_vol(codec, nid, label, type_idx,
HDA_INPUT);
@@ -3490,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
if (err < 0)
return err;
}
-
- if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
- snd_hda_add_imux_item(imux, label, index, NULL);
}
return 0;
@@ -5421,7 +5422,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
codec->no_trigger_sense = 1;
codec->spec = spec;
- spec->linear_tone_beep = 1;
+ spec->linear_tone_beep = 0;
codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
spec->digbeep_nid = 0x21;
spec->dmic_nids = stac92hd83xxx_dmic_nids;
@@ -5469,7 +5470,6 @@ again:
spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
spec->pin_nids = stac92hd88xxx_pin_nids;
spec->mono_nid = 0;
- spec->digbeep_nid = 0;
spec->num_pwrs = 0;
break;
case 0x111d7604:
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index d1c3f8defc48..7f4852a478a1 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -263,8 +263,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
return;
snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
!spec->vt1708_jack_detectect);
- cancel_delayed_work(&spec->vt1708_hp_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&spec->vt1708_hp_work);
}
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 712c1710f9a2..7b62de089fee 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
+ ICE1712_DELTA_66E_CS_CHIP_B;
+ tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
+ break;
case ICE1712_SUBDEVICE_VX442:
tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
tmp &= ~ICE1712_VX442_CS_DIGITAL;
@@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
case ICE1712_SUBDEVICE_DELTA410:
tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ tmp |= ICE1712_DELTA_66E_CS_CS8427;
+ break;
case ICE1712_SUBDEVICE_VX442:
tmp |= ICE1712_VX442_CS_DIGITAL;
break;
@@ -276,6 +284,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
}
/*
+ * AK4524 on Delta66 rev E to choose the chip address
+ */
+static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
+{
+ struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
+ struct snd_ice1712 *ice = ak->private_data[0];
+
+ snd_ice1712_save_gpio_status(ice);
+ priv->cs_mask =
+ priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
+ ICE1712_DELTA_66E_CS_CHIP_B;
+}
+
+/*
* AK4528 on VX442 to choose the chip mask
*/
static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
@@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
.mask_flags = 0,
};
+static struct snd_akm4xxx akm_delta66e __devinitdata = {
+ .type = SND_AK4524,
+ .num_adcs = 4,
+ .num_dacs = 4,
+ .ops = {
+ .lock = delta66e_ak4524_lock,
+ .set_rate_val = delta_ak4524_set_rate_val
+ }
+};
+
+static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
+ .caddr = 2,
+ .cif = 0, /* the default level of the CIF pin from AK4524 */
+ .data_mask = ICE1712_DELTA_66E_DOUT,
+ .clk_mask = ICE1712_DELTA_66E_CCLK,
+ .cs_mask = 0,
+ .cs_addr = 0, /* set later */
+ .cs_none = 0,
+ .add_flags = 0,
+ .mask_flags = 0,
+};
+
+
static struct snd_akm4xxx akm_delta44 __devinitdata = {
.type = SND_AK4524,
.num_adcs = 4,
@@ -644,9 +689,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
break;
case ICE1712_SUBDEVICE_VX442:
- case ICE1712_SUBDEVICE_DELTA66E:
err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
break;
+ case ICE1712_SUBDEVICE_DELTA66E:
+ err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
+ break;
default:
snd_BUG();
return -EINVAL;
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 1a0ac6cd6501..11a9c3a76507 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
+/* M-Audio Delta 66 rev. E definitions.
+ * Newer revisions of Delta 66 have CS8427 over SPI for
+ * S/PDIF transceiver instead of CS8404/CS8414. */
+/* 0x01 = DFS */
+#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
+#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
+#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
+#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
+#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
+#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
+
/* Digigram VX442 definitions */
#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
#define ICE1712_VX442_DIN 0x04 /* data input */
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..bd67c0d7779c 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
-snd-hifier-objs := hifier.o
snd-oxygen-objs := oxygen.o
snd-virtuoso-objs := virtuoso.o xonar_lib.o \
xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
-obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * CMI8788:
- *
- * SPI 0 -> AK4396
- */
-
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include "oxygen.h"
-#include "ak4396.h"
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("TempoTec HiFier driver");
-MODULE_LICENSE("GPL v2");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-
-static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
- { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
- { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
- { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
- { }
-};
-MODULE_DEVICE_TABLE(pci, hifier_ids);
-
-struct hifier_data {
- u8 ak4396_regs[5];
-};
-
-static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
-{
- struct hifier_data *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (0 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
- AK4396_WRITE | (reg << 8) | value);
- data->ak4396_regs[reg] = value;
-}
-
-static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
-{
- struct hifier_data *data = chip->model_data;
-
- if (value != data->ak4396_regs[reg])
- ak4396_write(chip, reg, value);
-}
-
-static void hifier_registers_init(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
-
- ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
- ak4396_write(chip, AK4396_CONTROL_2,
- data->ak4396_regs[AK4396_CONTROL_2]);
- ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
- ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
- ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
-}
-
-static void hifier_init(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
-
- data->ak4396_regs[AK4396_CONTROL_2] =
- AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
- hifier_registers_init(chip);
-
- snd_component_add(chip->card, "AK4396");
- snd_component_add(chip->card, "CS5340");
-}
-
-static void hifier_cleanup(struct oxygen *chip)
-{
-}
-
-static void hifier_resume(struct oxygen *chip)
-{
- hifier_registers_init(chip);
-}
-
-static void set_ak4396_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct hifier_data *data = chip->model_data;
- u8 value;
-
- value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
- if (params_rate(params) <= 54000)
- value |= AK4396_DFS_NORMAL;
- else if (params_rate(params) <= 108000)
- value |= AK4396_DFS_DOUBLE;
- else
- value |= AK4396_DFS_QUAD;
-
- msleep(1); /* wait for the new MCLK to become stable */
-
- if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
- ak4396_write(chip, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB);
- ak4396_write(chip, AK4396_CONTROL_2, value);
- ak4396_write(chip, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB | AK4396_RSTN);
- }
-}
-
-static void update_ak4396_volume(struct oxygen *chip)
-{
- ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
- ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
-}
-
-static void update_ak4396_mute(struct oxygen *chip)
-{
- struct hifier_data *data = chip->model_data;
- u8 value;
-
- value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
- if (chip->dac_mute)
- value |= AK4396_SMUTE;
- ak4396_write_cached(chip, AK4396_CONTROL_2, value);
-}
-
-static void set_cs5340_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
-}
-
-static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
-
-static const struct oxygen_model model_hifier = {
- .shortname = "C-Media CMI8787",
- .longname = "C-Media Oxygen HD Audio",
- .chip = "CMI8788",
- .init = hifier_init,
- .cleanup = hifier_cleanup,
- .resume = hifier_resume,
- .get_i2s_mclk = oxygen_default_i2s_mclk,
- .set_dac_params = set_ak4396_params,
- .set_adc_params = set_cs5340_params,
- .update_dac_volume = update_ak4396_volume,
- .update_dac_mute = update_ak4396_mute,
- .dac_tlv = ak4396_db_scale,
- .model_data_size = sizeof(struct hifier_data),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1,
- .dac_channels = 2,
- .dac_volume_min = 0,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_SPI,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static int __devinit get_hifier_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- chip->model = model_hifier;
- return 0;
-}
-
-static int __devinit hifier_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- ++dev;
- return -ENOENT;
- }
- err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
- hifier_ids, get_hifier_model);
- if (err >= 0)
- ++dev;
- return err;
-}
-
-static struct pci_driver hifier_driver = {
- .name = "CMI8787HiFier",
- .id_table = hifier_ids,
- .probe = hifier_probe,
- .remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
- .suspend = oxygen_pci_suspend,
- .resume = oxygen_pci_resume,
-#endif
-};
-
-static int __init alsa_card_hifier_init(void)
-{
- return pci_register_driver(&hifier_driver);
-}
-
-static void __exit alsa_card_hifier_exit(void)
-{
- pci_unregister_driver(&hifier_driver);
-}
-
-module_init(alsa_card_hifier_init)
-module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..dc47977becae 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -20,19 +20,25 @@
/*
* CMI8788:
*
- * SPI 0 -> 1st AK4396 (front)
- * SPI 1 -> 2nd AK4396 (surround)
- * SPI 2 -> 3rd AK4396 (center/LFE)
- * SPI 3 -> WM8785
- * SPI 4 -> 4th AK4396 (back)
+ * SPI 0 -> 1st AK4396 (front)
+ * SPI 1 -> 2nd AK4396 (surround)
+ * SPI 2 -> 3rd AK4396 (center/LFE)
+ * SPI 3 -> WM8785
+ * SPI 4 -> 4th AK4396 (back)
*
- * GPIO 0 -> DFS0 of AK5385
- * GPIO 1 -> DFS1 of AK5385
- * GPIO 8 -> enable headphone amplifier on HT-Omega models
+ * GPIO 0 -> DFS0 of AK5385
+ * GPIO 1 -> DFS1 of AK5385
+ * GPIO 8 -> enable headphone amplifier on HT-Omega models
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * CD_IN <- CD
+ * MIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
*/
#include <linux/delay.h>
@@ -41,6 +47,7 @@
#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -66,24 +73,35 @@ module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");
enum {
- MODEL_CMEDIA_REF, /* C-Media's reference design */
- MODEL_MERIDIAN, /* AuzenTech X-Meridian */
- MODEL_CLARO, /* HT-Omega Claro */
- MODEL_CLARO_HALO, /* HT-Omega Claro halo */
+ MODEL_CMEDIA_REF,
+ MODEL_MERIDIAN,
+ MODEL_CLARO,
+ MODEL_CLARO_HALO,
+ MODEL_FANTASIA,
+ MODEL_2CH_OUTPUT,
};
static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
+ /* C-Media's reference design */
{ OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
{ OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
+ /* Kuroutoshikou CMI8787-HG2PCI */
+ { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT },
+ /* TempoTec HiFier Fantasia */
+ { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
+ /* TempoTec HiFier Serenade */
+ { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT },
+ /* AuzenTech X-Meridian */
{ OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
+ /* HT-Omega Claro */
{ OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
+ /* HT-Omega Claro halo */
{ OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
{ }
};
@@ -98,6 +116,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
#define GPIO_CLARO_HP 0x0100
struct generic_data {
+ unsigned int dacs;
u8 ak4396_regs[4][5];
u16 wm8785_regs[3];
};
@@ -148,7 +167,7 @@ static void ak4396_registers_init(struct oxygen *chip)
struct generic_data *data = chip->model_data;
unsigned int i;
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write(chip, i, AK4396_CONTROL_1,
AK4396_DIF_24_MSB | AK4396_RSTN);
ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +185,7 @@ static void ak4396_init(struct oxygen *chip)
{
struct generic_data *data = chip->model_data;
+ data->dacs = chip->model.dac_channels / 2;
data->ak4396_regs[0][AK4396_CONTROL_2] =
AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
ak4396_registers_init(chip);
@@ -232,6 +252,17 @@ static void claro_halo_init(struct oxygen *chip)
claro_enable_hp(chip);
}
+static void fantasia_init(struct oxygen *chip)
+{
+ ak4396_init(chip);
+ snd_component_add(chip->card, "CS5340");
+}
+
+static void stereo_output_init(struct oxygen *chip)
+{
+ ak4396_init(chip);
+}
+
static void generic_cleanup(struct oxygen *chip)
{
}
@@ -268,6 +299,11 @@ static void claro_resume(struct oxygen *chip)
claro_enable_hp(chip);
}
+static void stereo_resume(struct oxygen *chip)
+{
+ ak4396_registers_init(chip);
+}
+
static void set_ak4396_params(struct oxygen *chip,
struct snd_pcm_hw_params *params)
{
@@ -286,7 +322,7 @@ static void set_ak4396_params(struct oxygen *chip,
msleep(1); /* wait for the new MCLK to become stable */
if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write(chip, i, AK4396_CONTROL_1,
AK4396_DIF_24_MSB);
ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +334,10 @@ static void set_ak4396_params(struct oxygen *chip,
static void update_ak4396_volume(struct oxygen *chip)
{
+ struct generic_data *data = chip->model_data;
unsigned int i;
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < data->dacs; ++i) {
ak4396_write_cached(chip, i, AK4396_LCH_ATT,
chip->dac_volume[i * 2]);
ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +354,7 @@ static void update_ak4396_mute(struct oxygen *chip)
value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
if (chip->dac_mute)
value |= AK4396_SMUTE;
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < data->dacs; ++i)
ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
}
@@ -356,6 +393,10 @@ static void set_ak5385_params(struct oxygen *chip,
value, GPIO_AK5385_DFS_MASK);
}
+static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
+{
+}
+
static int rolloff_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -400,7 +441,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
reg &= ~AK4396_SLOW;
changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
if (changed) {
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < data->dacs; ++i)
ak4396_write(chip, i, AK4396_CONTROL_2, reg);
}
mutex_unlock(&chip->mutex);
@@ -484,6 +525,39 @@ static int generic_wm8785_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_ak4396_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct generic_data *data = chip->model_data;
+ unsigned int dac, i;
+
+ for (dac = 0; dac < data->dacs; ++dac) {
+ snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
+ for (i = 0; i < 5; ++i)
+ snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
+ }
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_wm8785_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct generic_data *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nWM8785:");
+ for (i = 0; i < 3; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_oxygen_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ dump_ak4396_registers(chip, buffer);
+ dump_wm8785_registers(chip, buffer);
+}
+
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
static const struct oxygen_model model_generic = {
@@ -499,6 +573,7 @@ static const struct oxygen_model model_generic = {
.set_adc_params = set_wm8785_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
+ .dump_registers = dump_oxygen_registers,
.dac_tlv = ak4396_db_scale,
.model_data_size = sizeof(struct generic_data),
.device_config = PLAYBACK_0_TO_I2S |
@@ -527,6 +602,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
chip->model.mixer_init = generic_mixer_init;
chip->model.resume = meridian_resume;
chip->model.set_adc_params = set_ak5385_params;
+ chip->model.dump_registers = dump_ak4396_registers;
chip->model.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
CAPTURE_0_FROM_I2S_2 |
@@ -545,11 +621,30 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
chip->model.suspend = claro_suspend;
chip->model.resume = claro_resume;
chip->model.set_adc_params = set_ak5385_params;
+ chip->model.dump_registers = dump_ak4396_registers;
chip->model.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
CAPTURE_0_FROM_I2S_2 |
CAPTURE_1_FROM_SPDIF;
break;
+ case MODEL_FANTASIA:
+ case MODEL_2CH_OUTPUT:
+ chip->model.shortname = "C-Media CMI8787";
+ chip->model.chip = "CMI8787";
+ if (id->driver_data == MODEL_FANTASIA)
+ chip->model.init = fantasia_init;
+ else
+ chip->model.init = stereo_output_init;
+ chip->model.resume = stereo_resume;
+ chip->model.mixer_init = generic_mixer_init;
+ chip->model.set_adc_params = set_no_params;
+ chip->model.dump_registers = dump_ak4396_registers;
+ chip->model.device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF;
+ if (id->driver_data == MODEL_FANTASIA)
+ chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
+ chip->model.dac_channels = 2;
+ break;
}
if (id->driver_data == MODEL_MERIDIAN ||
id->driver_data == MODEL_CLARO_HALO) {
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7d5222caa0a9..b8fbc15b89a3 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -35,6 +35,7 @@
#define MIDI_OUTPUT 0x0800
#define MIDI_INPUT 0x1000
#define AC97_CD_INPUT 0x2000
+#define AC97_FMIC_SWITCH 0x4000
enum {
CONTROL_SPDIF_PCM,
@@ -65,6 +66,7 @@ struct snd_pcm_hardware;
struct snd_pcm_hw_params;
struct snd_kcontrol_new;
struct snd_rawmidi;
+struct snd_info_buffer;
struct oxygen;
struct oxygen_model {
@@ -92,6 +94,8 @@ struct oxygen_model {
void (*uart_input)(struct oxygen *chip);
void (*ac97_switch)(struct oxygen *chip,
unsigned int reg, unsigned int mute);
+ void (*dump_registers)(struct oxygen *chip,
+ struct snd_info_buffer *buffer);
const unsigned int *dac_tlv;
unsigned long private_data;
size_t model_data_size;
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index e5ebe56fb0c5..c44c91e6fb18 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
struct oxygen *chip = entry->private_data;
int i, j;
- snd_iprintf(buffer, "CMI8788\n\n");
+ switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
+ case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
+ case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
+ case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
+ default: i = '?'; break;
+ }
+ snd_iprintf(buffer, "CMI878%c:\n", i);
for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; ++j)
@@ -212,7 +218,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
if (mutex_lock_interruptible(&chip->mutex) < 0)
return;
if (chip->has_ac97_0) {
- snd_iprintf(buffer, "\nAC97\n");
+ snd_iprintf(buffer, "\nAC97:\n");
for (i = 0; i < 0x80; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; j += 2)
@@ -222,7 +228,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
}
}
if (chip->has_ac97_1) {
- snd_iprintf(buffer, "\nAC97 2\n");
+ snd_iprintf(buffer, "\nAC97 2:\n");
for (i = 0; i < 0x80; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; j += 2)
@@ -232,13 +238,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
}
}
mutex_unlock(&chip->mutex);
+ if (chip->model.dump_registers)
+ chip->model.dump_registers(chip, buffer);
}
static void oxygen_proc_init(struct oxygen *chip)
{
struct snd_info_entry *entry;
- if (!snd_card_proc_new(chip->card, "cmi8788", &entry))
+ if (!snd_card_proc_new(chip->card, "oxygen", &entry))
snd_info_set_text_ops(entry, chip, oxygen_proc_read);
}
#else
@@ -262,7 +270,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
*/
subdevice = oxygen_read_eeprom(chip, 2);
/* use default ID if EEPROM is missing */
- if (subdevice == 0xffff)
+ if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
subdevice = 0x8788;
/*
* We use only the subsystem device ID for searching because it is
@@ -557,7 +565,8 @@ static void oxygen_card_free(struct snd_card *card)
oxygen_shutdown(chip);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
- flush_scheduled_work();
+ flush_work_sync(&chip->spdif_input_bits_work);
+ flush_work_sync(&chip->gpio_work);
chip->model.cleanup(chip);
kfree(chip->model_data);
mutex_destroy(&chip->mutex);
@@ -733,7 +742,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
spin_unlock_irq(&chip->reg_lock);
synchronize_irq(chip->irq);
- flush_scheduled_work();
+ flush_work_sync(&chip->spdif_input_bits_work);
+ flush_work_sync(&chip->gpio_work);
chip->interrupt_mask = saved_interrupt_mask;
pci_disable_device(pci);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7e..605e84b9e1ec 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -644,6 +644,51 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
return change;
}
+static int mic_fmic_source_info(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_info *info)
+{
+ static const char *const names[] = { "Mic Jack", "Front Panel" };
+
+ info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ info->count = 1;
+ info->value.enumerated.items = 2;
+ info->value.enumerated.item &= 1;
+ strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
+ return 0;
+}
+
+static int mic_fmic_source_get(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
+{
+ struct oxygen *chip = ctl->private_data;
+
+ mutex_lock(&chip->mutex);
+ value->value.enumerated.item[0] =
+ !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
+ mutex_unlock(&chip->mutex);
+ return 0;
+}
+
+static int mic_fmic_source_put(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
+{
+ struct oxygen *chip = ctl->private_data;
+ u16 oldreg, newreg;
+ int change;
+
+ mutex_lock(&chip->mutex);
+ oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
+ if (value->value.enumerated.item[0])
+ newreg = oldreg | CM9780_FMIC2MIC;
+ else
+ newreg = oldreg & ~CM9780_FMIC2MIC;
+ change = newreg != oldreg;
+ if (change)
+ oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
+ mutex_unlock(&chip->mutex);
+ return change;
+}
+
static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -908,6 +953,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Source Capture Enum",
+ .info = mic_fmic_source_info,
+ .get = mic_fmic_source_get,
+ .put = mic_fmic_source_put,
+ },
AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -972,6 +1024,9 @@ static int add_controls(struct oxygen *chip,
if (!strcmp(template.name, "Stereo Upmixing") &&
chip->model.dac_channels == 2)
continue;
+ if (!strcmp(template.name, "Mic Source Capture Enum") &&
+ !(chip->model.device_config & AC97_FMIC_SWITCH))
+ continue;
if (!strncmp(template.name, "CD Capture ", 11) &&
!(chip->model.device_config & AC97_CD_INPUT))
continue;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 814667442eb0..60e4aa00c042 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.rates = SNDRV_PCM_RATE_32000 |
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.rates = SNDRV_PCM_RATE_32000 |
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
@@ -530,7 +533,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- chip->interrupt_mask |= channel_mask;
+ if (substream->runtime->no_period_wakeup)
+ chip->interrupt_mask &= ~channel_mask;
+ else
+ chip->interrupt_mask |= channel_mask;
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
spin_unlock_irq(&chip->reg_lock);
return 0;
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index b35343b0a9a5..0434c207e811 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip);
void xonar_init_cs53x1(struct oxygen *chip);
void xonar_set_cs53x1_params(struct oxygen *chip,
struct snd_pcm_hw_params *params);
+
+#define XONAR_GPIO_BIT_INVERT (1 << 16)
int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
struct snd_ctl_elem_value *value);
int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index aa27c31049af..de32895b3172 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -22,29 +22,28 @@
*
* CMI8788:
*
- * I²C <-> CS4398 (front)
- * <-> CS4362A (surround, center/LFE, back)
+ * I²C <-> CS4398 (addr 1001111) (front)
+ * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
*
- * GPI 0 <- external power present (DX only)
+ * GPI 0 <- external power present (DX only)
*
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> enable front panel I/O
- * GPIO 2 -> M0 of CS5361
- * GPIO 3 -> M1 of CS5361
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable output to speakers
+ * GPIO 1 -> route output to front panel
+ * GPIO 2 -> M0 of CS5361
+ * GPIO 3 -> M1 of CS5361
+ * GPIO 6 -> ?
+ * GPIO 7 -> ?
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
- * CS4398:
- *
- * AD0 <- 1
- * AD1 <- 1
- *
- * CS4362A:
+ * CM9780:
*
- * AD0 <- 0
+ * LINE_OUT -> input of ADC
*
- * CM9780:
+ * AUX_IN <- aux
+ * MIC_IN <- mic
+ * FMIC_IN <- front mic
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
*/
#include <linux/pci.h>
@@ -63,6 +62,7 @@
#define GPI_EXT_POWER 0x01
#define GPIO_D1_OUTPUT_ENABLE 0x0001
#define GPIO_D1_FRONT_PANEL 0x0002
+#define GPIO_D1_MAGIC 0x00c0
#define GPIO_D1_INPUT_ROUTE 0x0100
#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
@@ -169,12 +169,12 @@ static void xonar_d1_init(struct oxygen *chip)
cs43xx_registers_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
+ GPIO_D1_FRONT_PANEL |
+ GPIO_D1_MAGIC |
+ GPIO_D1_INPUT_ROUTE);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
- oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
-
xonar_init_cs53x1(chip);
xonar_enable_output(chip);
@@ -284,7 +284,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
static const struct snd_kcontrol_new front_panel_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Panel Switch",
+ .name = "Front Panel Playback Switch",
.info = snd_ctl_boolean_mono_info,
.get = xonar_gpio_bit_switch_get,
.put = xonar_gpio_bit_switch_put,
@@ -380,6 +380,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_cs4362a_registers(struct xonar_cs43xx *data,
+ struct snd_info_buffer *buffer)
+{
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nCS4362A:");
+ for (i = 1; i <= 14; ++i)
+ snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_d1_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_cs43xx *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nCS4398: 7?");
+ for (i = 2; i <= 8; ++i)
+ snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
+ snd_iprintf(buffer, "\n");
+ dump_cs4362a_registers(data, buffer);
+}
+
static const struct oxygen_model model_xonar_d1 = {
.longname = "Asus Virtuoso 100",
.chip = "AV200",
@@ -395,11 +419,13 @@ static const struct oxygen_model model_xonar_d1 = {
.update_dac_mute = update_cs43xx_mute,
.update_center_lfe_mix = update_cs43xx_center_lfe_mix,
.ac97_switch = xonar_d1_line_mic_ac97_switch,
+ .dump_registers = dump_d1_registers,
.dac_tlv = cs4362a_db_scale,
.model_data_size = sizeof(struct xonar_cs43xx),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
+ CAPTURE_0_FROM_I2S_2 |
+ AC97_FMIC_SWITCH,
.dac_channels = 8,
.dac_volume_min = 127 - 60,
.dac_volume_max = 127,
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index b3ff71316653..0ebe7f5916f9 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
u16 bit = ctl->private_value;
+ bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
value->value.integer.value[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
+ !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
return 0;
}
@@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
u16 bit = ctl->private_value;
+ bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
u16 old_bits, new_bits;
int changed;
spin_lock_irq(&chip->reg_lock);
old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- if (value->value.integer.value[0])
+ if (!!value->value.integer.value[0] ^ invert)
new_bits = old_bits | bit;
else
new_bits = old_bits & ~bit;
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index d491fd6c0be2..bf357c01afd2 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -22,20 +22,26 @@
*
* CMI8788:
*
- * SPI 0 -> 1st PCM1796 (front)
- * SPI 1 -> 2nd PCM1796 (surround)
- * SPI 2 -> 3rd PCM1796 (center/LFE)
- * SPI 4 -> 4th PCM1796 (back)
+ * SPI 0 -> 1st PCM1796 (front)
+ * SPI 1 -> 2nd PCM1796 (surround)
+ * SPI 2 -> 3rd PCM1796 (center/LFE)
+ * SPI 4 -> 4th PCM1796 (back)
*
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 5 <- external power present (D2X only)
- * GPIO 7 -> ALT
- * GPIO 8 -> enable output to speakers
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 5 <- external power present (D2X only)
+ * GPIO 7 -> ALT
+ * GPIO 8 -> enable output to speakers
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * VIDEO_IN <- CD
+ * FMIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*/
/*
@@ -44,52 +50,53 @@
*
* CMI8788:
*
- * I²C <-> PCM1796 (front)
+ * I²C <-> PCM1796 (addr 1001100) (front)
*
- * GPI 0 <- external power present
+ * GPI 0 <- external power present
*
- * GPIO 0 -> enable output to speakers
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable HDMI (0) or speaker (1) output
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 <- daughterboard detection
+ * GPIO 5 <- daughterboard detection
+ * GPIO 6 -> ?
+ * GPIO 7 -> ?
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
- * TXD -> HDMI controller
- * RXD <- HDMI controller
- *
- * PCM1796 front: AD1,0 <- 0,0
+ * UART <-> HDMI controller
*
* CM9780:
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * CD_IN <- CD
+ * MIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*
* no daughterboard
* ----------------
*
- * GPIO 4 <- 1
+ * GPIO 4 <- 1
*
* H6 daughterboard
* ----------------
*
- * GPIO 4 <- 0
- * GPIO 5 <- 0
+ * GPIO 4 <- 0
+ * GPIO 5 <- 0
*
- * I²C <-> PCM1796 (surround)
- * <-> PCM1796 (center/LFE)
- * <-> PCM1796 (back)
- *
- * PCM1796 surround: AD1,0 <- 0,1
- * PCM1796 center/LFE: AD1,0 <- 1,0
- * PCM1796 back: AD1,0 <- 1,1
+ * I²C <-> PCM1796 (addr 1001101) (surround)
+ * <-> PCM1796 (addr 1001110) (center/LFE)
+ * <-> PCM1796 (addr 1001111) (back)
*
* unknown daughterboard
* ---------------------
*
- * GPIO 4 <- 0
- * GPIO 5 <- 1
- *
- * I²C <-> CS4362A (surround, center/LFE, back)
+ * GPIO 4 <- 0
+ * GPIO 5 <- 1
*
- * CS4362A: AD0 <- 0
+ * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
*/
/*
@@ -98,32 +105,35 @@
*
* CMI8788:
*
- * I²C <-> PCM1792A
- * <-> CS2000 (ST only)
+ * I²C <-> PCM1792A (addr 1001100)
+ * <-> CS2000 (addr 1001110) (ST only)
*
- * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
+ * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
*
- * GPI 0 <- external power present (STX only)
+ * GPI 0 <- external power present (STX only)
*
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> route HP to front panel (0) or rear jack (1)
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 7 -> route output to speaker jacks (0) or HP (1)
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ * GPIO 0 -> enable output to speakers
+ * GPIO 1 -> route HP to front panel (0) or rear jack (1)
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 <- daughterboard detection
+ * GPIO 5 <- daughterboard detection
+ * GPIO 6 -> ?
+ * GPIO 7 -> route output to speaker jacks (0) or HP (1)
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
* PCM1792A:
*
- * AD1,0 <- 0,0
- * SCK <- CLK_OUT of CS2000 (ST only)
+ * SCK <- CLK_OUT of CS2000 (ST only)
*
- * CS2000:
+ * CM9780:
*
- * AD0 <- 0
+ * LINE_OUT -> input of ADC
*
- * CM9780:
+ * AUX_IN <- aux
+ * MIC_IN <- mic
*
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
*
* H6 daughterboard
* ----------------
@@ -133,15 +143,39 @@
*/
/*
- * Xonar HDAV1.3 Slim
- * ------------------
+ * Xonar Xense
+ * -----------
*
* CMI8788:
*
- * GPIO 1 -> enable output
+ * I²C <-> PCM1796 (addr 1001100) (front)
+ * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
+ * <-> CS2000 (addr 1001110)
+ *
+ * ADC1 MCLK -> REF_CLK of CS2000
*
- * TXD -> HDMI controller
- * RXD <- HDMI controller
+ * GPI 0 <- external power present
+ *
+ * GPIO 0 -> enable output
+ * GPIO 1 -> route HP to front panel (0) or rear jack (1)
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 4 -> enable output
+ * GPIO 5 -> enable output
+ * GPIO 6 -> ?
+ * GPIO 7 -> route output to HP (0) or speaker (1)
+ * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
+ *
+ * CM9780:
+ *
+ * LINE_OUT -> input of ADC
+ *
+ * AUX_IN <- aux
+ * VIDEO_IN <- ?
+ * FMIC_IN <- mic
+ *
+ * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
+ * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
*/
#include <linux/pci.h>
@@ -150,6 +184,7 @@
#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
@@ -167,12 +202,14 @@
#define GPIO_INPUT_ROUTE 0x0100
#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
+#define GPIO_HDAV_MAGIC 0x00c0
#define GPIO_DB_MASK 0x0030
#define GPIO_DB_H6 0x0000
#define GPIO_ST_OUTPUT_ENABLE 0x0001
#define GPIO_ST_HP_REAR 0x0002
+#define GPIO_ST_MAGIC 0x0040
#define GPIO_ST_HP 0x0080
#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
@@ -190,7 +227,7 @@ struct xonar_pcm179x {
bool hp_active;
s8 hp_gain_offset;
bool has_cs2000;
- u8 cs2000_fun_cfg_1;
+ u8 cs2000_regs[0x1f];
};
struct xonar_hdav {
@@ -249,16 +286,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
struct xonar_pcm179x *data = chip->model_data;
oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
- if (reg == CS2000_FUN_CFG_1)
- data->cs2000_fun_cfg_1 = value;
+ data->cs2000_regs[reg] = value;
}
static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
{
struct xonar_pcm179x *data = chip->model_data;
- if (reg != CS2000_FUN_CFG_1 ||
- value != data->cs2000_fun_cfg_1)
+ if (value != data->cs2000_regs[reg])
cs2000_write(chip, reg, value);
}
@@ -350,7 +385,8 @@ static void xonar_hdav_init(struct oxygen *chip)
pcm1796_init(chip);
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
+ GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
xonar_init_cs53x1(chip);
@@ -381,7 +417,8 @@ static void xonar_st_init_common(struct oxygen *chip)
pcm1796_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
+ GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
+ GPIO_ST_MAGIC | GPIO_ST_HP);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
@@ -410,7 +447,8 @@ static void cs2000_registers_init(struct oxygen *chip)
cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
- cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1);
+ cs2000_write(chip, CS2000_FUN_CFG_1,
+ data->cs2000_regs[CS2000_FUN_CFG_1]);
cs2000_write(chip, CS2000_FUN_CFG_2, 0);
cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
}
@@ -421,7 +459,7 @@ static void xonar_st_init(struct oxygen *chip)
data->generic.anti_pop_delay = 100;
data->has_cs2000 = 1;
- data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1;
+ data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S |
@@ -772,6 +810,15 @@ static const struct snd_kcontrol_new os_128_control = {
.put = os_128_put,
};
+static const struct snd_kcontrol_new hdav_hdmi_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "HDMI Playback Switch",
+ .info = snd_ctl_boolean_mono_info,
+ .get = xonar_gpio_bit_switch_get,
+ .put = xonar_gpio_bit_switch_put,
+ .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
+};
+
static int st_output_switch_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
@@ -956,7 +1003,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip)
static int xonar_hdav_mixer_init(struct oxygen *chip)
{
- return add_pcm1796_controls(chip);
+ int err;
+
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
+ if (err < 0)
+ return err;
+ err = add_pcm1796_controls(chip);
+ if (err < 0)
+ return err;
+ return 0;
}
static int xonar_st_mixer_init(struct oxygen *chip)
@@ -976,6 +1031,45 @@ static int xonar_st_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_pcm1796_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_pcm179x *data = chip->model_data;
+ unsigned int dac, i;
+
+ for (dac = 0; dac < data->dacs; ++dac) {
+ snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
+ for (i = 0; i < 5; ++i)
+ snd_iprintf(buffer, " %02x",
+ data->pcm1796_regs[dac][i]);
+ }
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_cs2000_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_pcm179x *data = chip->model_data;
+ unsigned int i;
+
+ if (data->has_cs2000) {
+ snd_iprintf(buffer, "\nCS2000:\n00: ");
+ for (i = 1; i < 0x10; ++i)
+ snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
+ snd_iprintf(buffer, "\n10:");
+ for (i = 0x10; i < 0x1f; ++i)
+ snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
+ snd_iprintf(buffer, "\n");
+ }
+}
+
+static void dump_st_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ dump_pcm1796_registers(chip, buffer);
+ dump_cs2000_registers(chip, buffer);
+}
+
static const struct oxygen_model model_xonar_d2 = {
.longname = "Asus Virtuoso 200",
.chip = "AV200",
@@ -990,6 +1084,7 @@ static const struct oxygen_model model_xonar_d2 = {
.set_adc_params = xonar_set_cs53x1_params,
.update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute,
+ .dump_registers = dump_pcm1796_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_pcm179x),
.device_config = PLAYBACK_0_TO_I2S |
@@ -1025,6 +1120,7 @@ static const struct oxygen_model model_xonar_hdav = {
.update_dac_mute = update_pcm1796_mute,
.uart_input = xonar_hdmi_uart_input,
.ac97_switch = xonar_line_mic_ac97_switch,
+ .dump_registers = dump_pcm1796_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_hdav),
.device_config = PLAYBACK_0_TO_I2S |
@@ -1054,11 +1150,13 @@ static const struct oxygen_model model_xonar_st = {
.update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute,
.ac97_switch = xonar_line_mic_ac97_switch,
+ .dump_registers = dump_st_registers,
.dac_tlv = pcm1796_db_scale,
.model_data_size = sizeof(struct xonar_pcm179x),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
+ CAPTURE_0_FROM_I2S_2 |
+ AC97_FMIC_SWITCH,
.dac_channels = 2,
.dac_volume_min = 255 - 2*60,
.dac_volume_max = 255,
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 200f7601276f..1705d1e93115 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -22,26 +22,48 @@
*
* CMI8788:
*
- * SPI 0 -> WM8766 (surround, center/LFE, back)
- * SPI 1 -> WM8776 (front, input)
+ * SPI 0 -> WM8766 (surround, center/LFE, back)
+ * SPI 1 -> WM8776 (front, input)
*
- * GPIO 4 <- headphone detect, 0 = plugged
- * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
- * GPIO 7 -> enable output to front L/R speaker channels
- * GPIO 8 -> enable output to other speaker channels and front panel headphone
+ * GPIO 4 <- headphone detect, 0 = plugged
+ * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
+ * GPIO 7 -> enable output to front L/R speaker channels
+ * GPIO 8 -> enable output to other speaker channels and front panel headphone
*
- * WM8766:
+ * WM8776:
*
- * input 1 <- line
- * input 2 <- mic
- * input 3 <- front mic
- * input 4 <- aux
+ * input 1 <- line
+ * input 2 <- mic
+ * input 3 <- front mic
+ * input 4 <- aux
+ */
+
+/*
+ * Xonar HDAV1.3 Slim
+ * ------------------
+ *
+ * CMI8788:
+ *
+ * I²C <-> WM8776 (addr 0011010)
+ *
+ * GPIO 0 -> disable HDMI output
+ * GPIO 1 -> enable HP output
+ * GPIO 6 -> firmware EEPROM I²C clock
+ * GPIO 7 <-> firmware EEPROM I²C data
+ *
+ * UART <-> HDMI controller
+ *
+ * WM8776:
+ *
+ * input 1 <- mic
+ * input 2 <- aux
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <sound/control.h>
#include <sound/core.h>
+#include <sound/info.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -1062,6 +1084,34 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
return 0;
}
+static void dump_wm8776_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_wm87x6 *data = chip->model_data;
+ unsigned int i;
+
+ snd_iprintf(buffer, "\nWM8776:\n00:");
+ for (i = 0; i < 0x10; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
+ snd_iprintf(buffer, "\n10:");
+ for (i = 0x10; i < 0x17; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void dump_wm87x6_registers(struct oxygen *chip,
+ struct snd_info_buffer *buffer)
+{
+ struct xonar_wm87x6 *data = chip->model_data;
+ unsigned int i;
+
+ dump_wm8776_registers(chip, buffer);
+ snd_iprintf(buffer, "\nWM8766:\n00:");
+ for (i = 0; i < 0x10; ++i)
+ snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
+ snd_iprintf(buffer, "\n");
+}
+
static const struct oxygen_model model_xonar_ds = {
.shortname = "Xonar DS",
.longname = "Asus Virtuoso 66",
@@ -1079,6 +1129,7 @@ static const struct oxygen_model model_xonar_ds = {
.update_dac_mute = update_wm87x6_mute,
.update_center_lfe_mix = update_wm8766_center_lfe_mix,
.gpio_changed = xonar_ds_gpio_changed,
+ .dump_registers = dump_wm87x6_registers,
.dac_tlv = wm87x6_dac_db_scale,
.model_data_size = sizeof(struct xonar_wm87x6),
.device_config = PLAYBACK_0_TO_I2S |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0b720cf7783e..2d8332416c83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
"{RME HDSP-9652},"
"{RME HDSP-9632}}");
#ifdef HDSP_FW_LOADER
+MODULE_FIRMWARE("rpm_firmware.bin");
MODULE_FIRMWARE("multiface_firmware.bin");
MODULE_FIRMWARE("multiface_firmware_rev11.bin");
MODULE_FIRMWARE("digiface_firmware.bin");
@@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define H9632_SS_CHANNELS 12
#define H9632_DS_CHANNELS 8
#define H9632_QS_CHANNELS 4
+#define RPM_CHANNELS 6
/* Write registers. These are defined as byte-offsets from the iobase value.
*/
@@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_PhoneGain1 (1<<30)
#define HDSP_QuadSpeed (1<<31)
+/* RPM uses some of the registers for special purposes */
+#define HDSP_RPM_Inp12 0x04A00
+#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
+#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
+#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
+#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
+#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
+
+#define HDSP_RPM_Inp34 0x32000
+#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
+#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
+#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
+#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
+#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
+
+#define HDSP_RPM_Bypass 0x01000
+
+#define HDSP_RPM_Disconnect 0x00001
+
#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
@@ -450,7 +471,7 @@ struct hdsp {
u32 creg_spdif;
u32 creg_spdif_stream;
int clock_source_locked;
- char *card_name; /* digiface/multiface */
+ char *card_name; /* digiface/multiface/rpm */
enum HDSP_IO_Type io_type; /* ditto, but for code use */
unsigned short firmware_rev;
unsigned short state; /* stores state bits */
@@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
switch (hdsp->io_type) {
case Multiface:
case Digiface:
+ case RPM:
default:
if (hdsp->firmware_rev == 0xa)
return (64 * out) + (32 + (in));
@@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
switch (hdsp->io_type) {
case Multiface:
case Digiface:
+ case RPM:
default:
if (hdsp->firmware_rev == 0xa)
return (64 * out) + in;
@@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp)
{
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
- snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n");
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
return -EIO;
}
@@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
}
}
- snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n");
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
return -EIO;
}
@@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) {
- hdsp->io_type = Multiface;
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT);
+ if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
+ hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
+ hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+ if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
+ hdsp->io_type = RPM;
+ else
+ hdsp->io_type = Multiface;
} else {
hdsp->io_type = Digiface;
}
} else {
/* firmware was already loaded, get iobox type */
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
+ hdsp->io_type = RPM;
+ else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
else
hdsp->io_type = Digiface;
@@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
hdsp->channel_map = channel_map_ds;
} else {
switch (hdsp->io_type) {
+ case RPM:
case Multiface:
hdsp->channel_map = channel_map_mf_ss;
break;
@@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0),
HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
};
+
+static int hdsp_rpm_input12(struct hdsp *hdsp)
+{
+ switch (hdsp->control_register & HDSP_RPM_Inp12) {
+ case HDSP_RPM_Inp12_Phon_6dB:
+ return 0;
+ case HDSP_RPM_Inp12_Phon_n6dB:
+ return 2;
+ case HDSP_RPM_Inp12_Line_0dB:
+ return 3;
+ case HDSP_RPM_Inp12_Line_n6dB:
+ return 4;
+ }
+ return 1;
+}
+
+
+static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
+{
+ hdsp->control_register &= ~HDSP_RPM_Inp12;
+ switch (mode) {
+ case 0:
+ hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
+ break;
+ case 1:
+ break;
+ case 2:
+ hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
+ break;
+ case 3:
+ hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
+ break;
+ case 4:
+ hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
+ break;
+ default:
+ return -1;
+ }
+
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.enumerated.item[0];
+ if (val < 0)
+ val = 0;
+ if (val > 4)
+ val = 4;
+ spin_lock_irq(&hdsp->lock);
+ if (val != hdsp_rpm_input12(hdsp))
+ change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
+ else
+ change = 0;
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 5;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+
+static int hdsp_rpm_input34(struct hdsp *hdsp)
+{
+ switch (hdsp->control_register & HDSP_RPM_Inp34) {
+ case HDSP_RPM_Inp34_Phon_6dB:
+ return 0;
+ case HDSP_RPM_Inp34_Phon_n6dB:
+ return 2;
+ case HDSP_RPM_Inp34_Line_0dB:
+ return 3;
+ case HDSP_RPM_Inp34_Line_n6dB:
+ return 4;
+ }
+ return 1;
+}
+
+
+static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
+{
+ hdsp->control_register &= ~HDSP_RPM_Inp34;
+ switch (mode) {
+ case 0:
+ hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
+ break;
+ case 1:
+ break;
+ case 2:
+ hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
+ break;
+ case 3:
+ hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
+ break;
+ case 4:
+ hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
+ break;
+ default:
+ return -1;
+ }
+
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.enumerated.item[0];
+ if (val < 0)
+ val = 0;
+ if (val > 4)
+ val = 4;
+ spin_lock_irq(&hdsp->lock);
+ if (val != hdsp_rpm_input34(hdsp))
+ change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
+ else
+ change = 0;
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+/* RPM Bypass switch */
+static int hdsp_rpm_bypass(struct hdsp *hdsp)
+{
+ return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
+}
+
+
+static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
+{
+ if (on)
+ hdsp->control_register |= HDSP_RPM_Bypass;
+ else
+ hdsp->control_register &= ~HDSP_RPM_Bypass;
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ unsigned int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.integer.value[0] & 1;
+ spin_lock_irq(&hdsp->lock);
+ change = (int)val != hdsp_rpm_bypass(hdsp);
+ hdsp_set_rpm_bypass(hdsp, val);
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+
+static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"On", "Off"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+
+/* RPM Disconnect switch */
+static int hdsp_rpm_disconnect(struct hdsp *hdsp)
+{
+ return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
+}
+
+
+static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
+ return 0;
+}
+
+
+static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
+{
+ if (on)
+ hdsp->control_register |= HDSP_RPM_Disconnect;
+ else
+ hdsp->control_register &= ~HDSP_RPM_Disconnect;
+ hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
+ return 0;
+}
+
+
+static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ unsigned int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.integer.value[0] & 1;
+ spin_lock_irq(&hdsp->lock);
+ change = (int)val != hdsp_rpm_disconnect(hdsp);
+ hdsp_set_rpm_disconnect(hdsp, val);
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
+static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = {"On", "Off"};
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "RPM Bypass",
+ .get = snd_hdsp_get_rpm_bypass,
+ .put = snd_hdsp_put_rpm_bypass,
+ .info = snd_hdsp_info_rpm_bypass
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "RPM Disconnect",
+ .get = snd_hdsp_get_rpm_disconnect,
+ .put = snd_hdsp_put_rpm_disconnect,
+ .info = snd_hdsp_info_rpm_disconnect
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Input 1/2",
+ .get = snd_hdsp_get_rpm_input12,
+ .put = snd_hdsp_put_rpm_input12,
+ .info = snd_hdsp_info_rpm_input
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Input 3/4",
+ .get = snd_hdsp_get_rpm_input34,
+ .put = snd_hdsp_put_rpm_input34,
+ .info = snd_hdsp_info_rpm_input
+ },
+ HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
+ HDSP_MIXER("Mixer", 0)
+};
+
static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
@@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
int err;
struct snd_kcontrol *kctl;
+ if (hdsp->io_type == RPM) {
+ /* RPM Bypass, Disconnect and Input switches */
+ for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
+ err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+ }
+
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
return err;
@@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
snd_iprintf(buffer, "\n");
- switch (hdsp_spdif_in(hdsp)) {
- case HDSP_SPDIFIN_OPTICAL:
- snd_iprintf(buffer, "IEC958 input: Optical\n");
- break;
- case HDSP_SPDIFIN_COAXIAL:
- snd_iprintf(buffer, "IEC958 input: Coaxial\n");
- break;
- case HDSP_SPDIFIN_INTERNAL:
- snd_iprintf(buffer, "IEC958 input: Internal\n");
- break;
- case HDSP_SPDIFIN_AES:
- snd_iprintf(buffer, "IEC958 input: AES\n");
- break;
- default:
- snd_iprintf(buffer, "IEC958 input: ???\n");
- break;
+ if (hdsp->io_type != RPM) {
+ switch (hdsp_spdif_in(hdsp)) {
+ case HDSP_SPDIFIN_OPTICAL:
+ snd_iprintf(buffer, "IEC958 input: Optical\n");
+ break;
+ case HDSP_SPDIFIN_COAXIAL:
+ snd_iprintf(buffer, "IEC958 input: Coaxial\n");
+ break;
+ case HDSP_SPDIFIN_INTERNAL:
+ snd_iprintf(buffer, "IEC958 input: Internal\n");
+ break;
+ case HDSP_SPDIFIN_AES:
+ snd_iprintf(buffer, "IEC958 input: AES\n");
+ break;
+ default:
+ snd_iprintf(buffer, "IEC958 input: ???\n");
+ break;
+ }
}
- if (hdsp->control_register & HDSP_SPDIFOpticalOut)
- snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- else
- snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
+ if (RPM == hdsp->io_type) {
+ if (hdsp->control_register & HDSP_RPM_Bypass)
+ snd_iprintf(buffer, "RPM Bypass: disabled\n");
+ else
+ snd_iprintf(buffer, "RPM Bypass: enabled\n");
+ if (hdsp->control_register & HDSP_RPM_Disconnect)
+ snd_iprintf(buffer, "RPM disconnected\n");
+ else
+ snd_iprintf(buffer, "RPM connected\n");
- if (hdsp->control_register & HDSP_SPDIFProfessional)
- snd_iprintf(buffer, "IEC958 quality: Professional\n");
- else
- snd_iprintf(buffer, "IEC958 quality: Consumer\n");
+ switch (hdsp->control_register & HDSP_RPM_Inp12) {
+ case HDSP_RPM_Inp12_Phon_6dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
+ break;
+ case HDSP_RPM_Inp12_Phon_0dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
+ break;
+ case HDSP_RPM_Inp12_Phon_n6dB:
+ snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
+ break;
+ case HDSP_RPM_Inp12_Line_0dB:
+ snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
+ break;
+ case HDSP_RPM_Inp12_Line_n6dB:
+ snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
+ break;
+ default:
+ snd_iprintf(buffer, "Input 1/2: ???\n");
+ }
- if (hdsp->control_register & HDSP_SPDIFEmphasis)
- snd_iprintf(buffer, "IEC958 emphasis: on\n");
- else
- snd_iprintf(buffer, "IEC958 emphasis: off\n");
+ switch (hdsp->control_register & HDSP_RPM_Inp34) {
+ case HDSP_RPM_Inp34_Phon_6dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
+ break;
+ case HDSP_RPM_Inp34_Phon_0dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
+ break;
+ case HDSP_RPM_Inp34_Phon_n6dB:
+ snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
+ break;
+ case HDSP_RPM_Inp34_Line_0dB:
+ snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
+ break;
+ case HDSP_RPM_Inp34_Line_n6dB:
+ snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
+ break;
+ default:
+ snd_iprintf(buffer, "Input 3/4: ???\n");
+ }
- if (hdsp->control_register & HDSP_SPDIFNonAudio)
- snd_iprintf(buffer, "IEC958 NonAudio: on\n");
- else
- snd_iprintf(buffer, "IEC958 NonAudio: off\n");
- if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
- snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
- else
- snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
+ } else {
+ if (hdsp->control_register & HDSP_SPDIFOpticalOut)
+ snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
+ else
+ snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
+
+ if (hdsp->control_register & HDSP_SPDIFProfessional)
+ snd_iprintf(buffer, "IEC958 quality: Professional\n");
+ else
+ snd_iprintf(buffer, "IEC958 quality: Consumer\n");
+
+ if (hdsp->control_register & HDSP_SPDIFEmphasis)
+ snd_iprintf(buffer, "IEC958 emphasis: on\n");
+ else
+ snd_iprintf(buffer, "IEC958 emphasis: off\n");
+ if (hdsp->control_register & HDSP_SPDIFNonAudio)
+ snd_iprintf(buffer, "IEC958 NonAudio: on\n");
+ else
+ snd_iprintf(buffer, "IEC958 NonAudio: off\n");
+ x = hdsp_spdif_sample_rate(hdsp);
+ if (x != 0)
+ snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
+ else
+ snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
+ }
snd_iprintf(buffer, "\n");
/* Sync Check */
@@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
snd_hdsp_midi_input_read (&hdsp->midi[0]);
}
}
- if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) {
+ if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
if (hdsp->use_midi_tasklet) {
/* we disable interrupts for this input until processing is done */
hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
@@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
SNDRV_PCM_RATE_96000),
.rate_min = 32000,
.rate_max = 96000,
- .channels_min = 14,
+ .channels_min = 6,
.channels_max = HDSP_MAX_CHANNELS,
.buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
.period_bytes_min = (64 * 4) * 10,
@@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
SNDRV_PCM_RATE_96000),
.rate_min = 32000,
.rate_max = 96000,
- .channels_min = 14,
+ .channels_min = 5,
.channels_max = HDSP_MAX_CHANNELS,
.buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
.period_bytes_min = (64 * 4) * 10,
@@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
snd_hdsp_hw_rule_rate_out_channels, hdsp,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- hdsp->creg_spdif_stream = hdsp->creg_spdif;
- hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ if (RPM != hdsp->io_type) {
+ hdsp->creg_spdif_stream = hdsp->creg_spdif;
+ hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ }
return 0;
}
@@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
spin_unlock_irq(&hdsp->lock);
- hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ if (RPM != hdsp->io_type) {
+ hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
+ }
return 0;
}
@@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
if (hdsp->io_type != H9632)
info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
+ for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
@@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
+ } else if (hdsp->io_type == RPM) {
+ info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
+ info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
}
if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
@@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
break;
+ case RPM:
+ hdsp->card_name = "RME Hammerfall DSP + RPM";
+ hdsp->ss_in_channels = RPM_CHANNELS-1;
+ hdsp->ss_out_channels = RPM_CHANNELS;
+ hdsp->ds_in_channels = RPM_CHANNELS-1;
+ hdsp->ds_out_channels = RPM_CHANNELS;
+ break;
+
default:
/* should never get here */
break;
@@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
/* caution: max length of firmware filename is 30! */
switch (hdsp->io_type) {
+ case RPM:
+ fwfile = "rpm_firmware.bin";
+ break;
case Multiface:
if (hdsp->firmware_rev == 0xa)
fwfile = "multiface_firmware.bin";
@@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
return 0;
} else {
snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
+ hdsp->io_type = RPM;
+ else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
else
hdsp->io_type = Digiface;
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3e598e756e54..a3efc52a34da 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -20,6 +20,21 @@ menuconfig SND_SOC
if SND_SOC
+config SND_SOC_CACHE_LZO
+ bool "Support LZO compression for register caches"
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+ ---help---
+ Select this to enable LZO compression for register caches.
+ This will allow machine or CODEC drivers to compress register
+ caches in memory, reducing the memory consumption at the
+ expense of performance. If this is not present and is used
+ the system will fall back to uncompressed caches.
+
+ Usually it is safe to disable this option, where cache
+ compression in used the rbtree option will typically perform
+ better.
+
config SND_SOC_AC97_BUS
bool
@@ -36,7 +51,7 @@ source "sound/soc/nuc900/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/kirkwood/Kconfig"
source "sound/soc/pxa/Kconfig"
-source "sound/soc/s3c24xx/Kconfig"
+source "sound/soc/samsung/Kconfig"
source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/txx9/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index eb183443eee4..ce913bf5213c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
obj-$(CONFIG_SND_SOC) += omap/
obj-$(CONFIG_SND_SOC) += kirkwood/
obj-$(CONFIG_SND_SOC) += pxa/
-obj-$(CONFIG_SND_SOC) += s3c24xx/
+obj-$(CONFIG_SND_SOC) += samsung/
obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 5f4e59f4461c..1aac2f4dbcf6 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -33,7 +33,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/at32ap700x.h>
#include <mach/portmux.h>
@@ -318,27 +317,28 @@ static const struct snd_soc_dapm_route intercon[] = {
static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
/*
* Add DAPM widgets
*/
for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
- snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]);
+ snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]);
/*
* Setup audio path interconnects
*/
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
/* always connected pins */
- snd_soc_dapm_enable_pin(codec, "Int Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_sync(dapm);
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index e521ada80542..af3c73053ee4 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -44,7 +44,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -140,6 +139,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
printk(KERN_DEBUG
@@ -154,25 +154,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
}
/* Add specific widgets */
- snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
/* Set up specific audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
/* not connected */
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
#ifdef ENABLE_MIC_INPUT
- snd_soc_dapm_enable_pin(codec, "Int Mic");
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
#else
- snd_soc_dapm_nc_pin(codec, "Int Mic");
+ snd_soc_dapm_nc_pin(dapm, "Int Mic");
#endif
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 86e0f8586dc3..da2208e06b0d 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -105,19 +104,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add afeb9260 specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up afeb9260 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index b62fcd33e586..cb99f04abe88 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -13,7 +13,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 2394bff2b655..83012da9dfc2 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -20,7 +20,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index e4a625317a1a..d3ccb926b5e4 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -29,7 +29,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 900ced54ac79..732fb8bad076 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -35,7 +35,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 36f2769eb912..e902b24c1856 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -33,7 +33,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <asm/dma.h>
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 01d19e9f53f9..06b6981b8d6d 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -19,10 +19,10 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <sound/jack.h>
+#include <trace/events/asoc.h>
#include "88pm860x-codec.h"
@@ -146,7 +146,6 @@ struct pm860x_priv {
int irq[4];
unsigned char name[4][MAX_NAME_LEN];
- unsigned char reg_cache[REG_CACHE_SIZE];
};
/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
@@ -1172,7 +1171,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable Audio PLL & Audio section */
data = AUDIO_PLL | AUDIO_SECTION_RESET
| AUDIO_SECTION_ON;
@@ -1185,7 +1184,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1263,6 +1262,12 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt
| pm860x->det.hp_det;
+#ifndef CONFIG_SND_SOC_88PM860X_MODULE
+ if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
+ SHORT_LO1 | SHORT_LO2))
+ trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
+#endif
+
if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
&& (status & HEADSET_STATUS))
report |= SND_JACK_HEADPHONE;
@@ -1346,6 +1351,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
static int pm860x_probe(struct snd_soc_codec *codec)
{
struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i, ret;
pm860x->codec = codec;
@@ -1358,7 +1364,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
pm860x->name[i], pm860x);
if (ret < 0) {
dev_err(codec->dev, "Failed to request IRQ!\n");
- goto out_irq;
+ goto out;
}
}
@@ -1369,22 +1375,20 @@ static int pm860x_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "Failed to fill register cache: %d\n",
ret);
- goto out_codec;
+ goto out;
}
snd_soc_add_controls(codec, pm860x_snd_controls,
ARRAY_SIZE(pm860x_snd_controls));
- snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
ARRAY_SIZE(pm860x_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
-out_codec:
- i = 3;
-out_irq:
- for (; i >= 0; i--)
+out:
+ while (--i >= 0)
free_irq(pm860x->irq[i], pm860x);
- return -EINVAL;
+ return ret;
}
static int pm860x_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3b5690d28b8b..054191ed08ef 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4535 if I2C
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
+ select SND_SOC_ALC5623 if I2C
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CS42L51 if I2C
select SND_SOC_CS4270 if I2C
@@ -54,9 +55,11 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8727
select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
+ select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
+ select SND_SOC_WM8770 if SPI_MASTER
select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
@@ -75,6 +78,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8990 if I2C
select SND_SOC_WM8993 if I2C
select SND_SOC_WM8994 if MFD_WM8994
+ select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM9081 if I2C
select SND_SOC_WM9090 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -130,6 +134,9 @@ config SND_SOC_AK4642
config SND_SOC_AK4671
tristate
+config SND_SOC_ALC5623
+ tristate
+
config SND_SOC_CQ0093VC
tristate
@@ -231,6 +238,9 @@ config SND_SOC_WM8728
config SND_SOC_WM8731
tristate
+config SND_SOC_WM8737
+ tristate
+
config SND_SOC_WM8741
tristate
@@ -240,6 +250,9 @@ config SND_SOC_WM8750
config SND_SOC_WM8753
tristate
+config SND_SOC_WM8770
+ tristate
+
config SND_SOC_WM8776
tristate
@@ -294,6 +307,9 @@ config SND_SOC_WM8993
config SND_SOC_WM8994
tristate
+config SND_SOC_WM8995
+ tristate
+
config SND_SOC_WM9081
tristate
@@ -318,3 +334,4 @@ config SND_SOC_WM2000
config SND_SOC_WM9090
tristate
+
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f67a2d6f7a46..6a1e17bbbf83 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -17,6 +17,7 @@ snd-soc-da7210-objs := da7210.o
snd-soc-l3-objs := l3.o
snd-soc-max98088-objs := max98088.o
snd-soc-pcm3008-objs := pcm3008.o
+snd-soc-alc5623-objs := alc5623.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
snd-soc-stac9766-objs := stac9766.o
@@ -38,9 +39,11 @@ snd-soc-wm8711-objs := wm8711.o
snd-soc-wm8727-objs := wm8727.o
snd-soc-wm8728-objs := wm8728.o
snd-soc-wm8731-objs := wm8731.o
+snd-soc-wm8737-objs := wm8737.o
snd-soc-wm8741-objs := wm8741.o
snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
+snd-soc-wm8770-objs := wm8770.o
snd-soc-wm8776-objs := wm8776.o
snd-soc-wm8804-objs := wm8804.o
snd-soc-wm8900-objs := wm8900.o
@@ -58,7 +61,8 @@ snd-soc-wm8985-objs := wm8985.o
snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm8993-objs := wm8993.o
-snd-soc-wm8994-objs := wm8994.o
+snd-soc-wm8994-objs := wm8994.o wm8994-tables.o
+snd-soc-wm8995-objs := wm8995.o
snd-soc-wm9081-objs := wm9081.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
@@ -92,6 +96,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
+obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
@@ -113,9 +118,11 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
+obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o
obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
+obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
@@ -134,6 +141,7 @@ obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
+obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index d272534c8f84..ab63d52e36e1 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -27,7 +27,6 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
-#include <sound/soc-dapm.h>
#include <linux/spi/spi.h>
#include "ad1836.h"
@@ -220,6 +219,7 @@ static struct snd_soc_dai_driver ad1836_dai = {
static int ad1836_probe(struct snd_soc_codec *codec)
{
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
codec->control_data = ad1836->control_data;
@@ -227,7 +227,6 @@ static int ad1836_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
- kfree(ad1836);
return ret;
}
@@ -252,9 +251,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, ad1836_snd_controls,
ARRAY_SIZE(ad1836_snd_controls));
- snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
ARRAY_SIZE(ad1836_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index fa2834c91b9f..da46479bfcfa 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -19,12 +19,10 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
-#include <sound/soc-dapm.h>
#include "ad193x.h"
/* codec private data */
struct ad193x_priv {
- u8 reg_cache[AD193X_NUM_REGS];
enum snd_soc_control_type bus_type;
void *control_data;
int sysclk;
@@ -353,6 +351,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
codec->control_data = ad193x->control_data;
@@ -363,7 +362,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
- kfree(ad193x);
return ret;
}
@@ -385,9 +383,9 @@ static int ad193x_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, ad193x_snd_controls,
ARRAY_SIZE(ad193x_snd_controls));
- snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
ARRAY_SIZE(ad193x_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 410ccd5d41cd..34cb51ef2156 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -29,7 +29,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "ad1980.h"
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index cd88c8f32a38..8b38739c88f8 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "ak4535.h"
@@ -290,10 +289,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int ak4535_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets,
- ARRAY_SIZE(ak4535_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
+ ARRAY_SIZE(ak4535_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -366,9 +366,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int ak4535_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
if (!mute)
- ak4535_write(codec, AK4535_DAC, mute_reg);
+ ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
else
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
return 0;
@@ -381,11 +381,11 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
switch (level) {
case SND_SOC_BIAS_ON:
- mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
- ak4535_write(codec, AK4535_DAC, mute_reg);
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
+ ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
break;
case SND_SOC_BIAS_PREPARE:
- mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
break;
case SND_SOC_BIAS_STANDBY:
@@ -399,7 +399,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
ak4535_write(codec, AK4535_PM1, i & (~0x80));
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 90c90b7f4a2e..f00eba313dfd 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -26,7 +26,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 24f5f49bb9d2..2ec75abfa3e9 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -28,7 +27,6 @@
struct ak4671_priv {
enum snd_soc_control_type control_type;
void *control_data;
- u8 reg_cache[AK4671_CACHEREGNUM];
};
/* ak4671 register cache & default register settings */
@@ -437,10 +435,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int ak4671_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
- ARRAY_SIZE(ak4671_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
+ ARRAY_SIZE(ak4671_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -602,7 +601,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
new file mode 100644
index 000000000000..4f377c9e868d
--- /dev/null
+++ b/sound/soc/codecs/alc5623.c
@@ -0,0 +1,1117 @@
+/*
+ * alc5623.c -- alc562[123] ALSA Soc Audio driver
+ *
+ * Copyright 2008 Realtek Microelectronics
+ * Author: flove <flove@realtek.com> Ethan <eku@marvell.com>
+ *
+ * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * Based on WM8753.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/alc5623.h>
+
+#include "alc5623.h"
+
+static int caps_charge = 2000;
+module_param(caps_charge, int, 0);
+MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
+
+/* codec private data */
+struct alc5623_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
+ struct mutex mutex;
+ u8 id;
+ unsigned int sysclk;
+ u16 reg_cache[ALC5623_VENDOR_ID2+2];
+ unsigned int add_ctrl;
+ unsigned int jack_det_ctrl;
+};
+
+static void alc5623_fill_cache(struct snd_soc_codec *codec)
+{
+ int i, step = codec->driver->reg_cache_step;
+ u16 *cache = codec->reg_cache;
+
+ /* not really efficient ... */
+ for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
+ cache[i] = codec->hw_read(codec, i);
+}
+
+static inline int alc5623_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, ALC5623_RESET, 0);
+}
+
+static int amp_mixer_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ /* to power-on/off class-d amp generators/speaker */
+ /* need to write to 'index-46h' register : */
+ /* so write index num (here 0x46) to reg 0x6a */
+ /* and then 0xffff/0 to reg 0x6c */
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * ALC5623 Controls
+ */
+
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
+static const unsigned int boost_tlv[] = {
+ TLV_DB_RANGE_HEAD(3),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
+};
+static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
+
+static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Speaker Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Speaker Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Headphone Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Headphone Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Speaker Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Speaker Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Line Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Line Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = {
+ SOC_DOUBLE_TLV("Line Playback Volume",
+ ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Line Playback Switch",
+ ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Headphone Playback Volume",
+ ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Headphone Playback Switch",
+ ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_snd_controls[] = {
+ SOC_DOUBLE_TLV("Auxout Playback Volume",
+ ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Auxout Playback Switch",
+ ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("PCM Playback Volume",
+ ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("AuxI Capture Volume",
+ ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("LineIn Capture Volume",
+ ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_SINGLE_TLV("Mic1 Capture Volume",
+ ALC5623_MIC_VOL, 8, 31, 1, vol_tlv),
+ SOC_SINGLE_TLV("Mic2 Capture Volume",
+ ALC5623_MIC_VOL, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("Rec Capture Volume",
+ ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv),
+ SOC_SINGLE_TLV("Mic 1 Boost Volume",
+ ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Mic 2 Boost Volume",
+ ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Digital Boost Volume",
+ ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1),
+SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1),
+SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1),
+SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1),
+SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1),
+SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1),
+};
+
+/* Left Record Mixer */
+static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1),
+SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1),
+SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1),
+SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1),
+};
+
+/* Right Record Mixer */
+static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1),
+SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1),
+SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1),
+SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1),
+};
+
+static const char *alc5623_spk_n_sour_sel[] = {
+ "RN/-R", "RP/+R", "LN/-R", "Vmid" };
+static const char *alc5623_hpl_out_input_sel[] = {
+ "Vmid", "HP Left Mix"};
+static const char *alc5623_hpr_out_input_sel[] = {
+ "Vmid", "HP Right Mix"};
+static const char *alc5623_spkout_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+static const char *alc5623_aux_out_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+
+/* auxout output mux */
+static const struct soc_enum alc5623_aux_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel);
+static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
+
+/* speaker output mux */
+static const struct soc_enum alc5623_spkout_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel);
+static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
+
+/* headphone left output mux */
+static const struct soc_enum alc5623_hpl_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel);
+static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
+
+/* headphone right output mux */
+static const struct soc_enum alc5623_hpr_out_input_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel);
+static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
+
+/* speaker output N select */
+static const struct soc_enum alc5623_spk_n_sour_enum =
+SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel);
+static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
+SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
+
+static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = {
+/* Muxes */
+SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_auxout_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_spkout_mux_controls),
+SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_hpl_out_mux_controls),
+SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_hpr_out_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_spkoutn_mux_controls),
+
+/* output mixers */
+SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
+ &alc5623_hp_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hp_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0,
+ &alc5623_hpr_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hpr_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0,
+ &alc5623_hpl_mixer_controls[0],
+ ARRAY_SIZE(alc5623_hpl_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0,
+ &alc5623_mono_mixer_controls[0],
+ ARRAY_SIZE(alc5623_mono_mixer_controls)),
+SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0,
+ &alc5623_speaker_mixer_controls[0],
+ ARRAY_SIZE(alc5623_speaker_mixer_controls)),
+
+/* input mixers */
+SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0,
+ &alc5623_captureL_mixer_controls[0],
+ ARRAY_SIZE(alc5623_captureL_mixer_controls)),
+SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0,
+ &alc5623_captureR_mixer_controls[0],
+ ARRAY_SIZE(alc5623_captureR_mixer_controls)),
+
+SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
+ ALC5623_PWR_MANAG_ADD2, 9, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
+ ALC5623_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
+ ALC5623_PWR_MANAG_ADD2, 7, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
+ ALC5623_PWR_MANAG_ADD2, 6, 0),
+SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0),
+SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0),
+
+SND_SOC_DAPM_OUTPUT("AUXOUTL"),
+SND_SOC_DAPM_OUTPUT("AUXOUTR"),
+SND_SOC_DAPM_OUTPUT("HPL"),
+SND_SOC_DAPM_OUTPUT("HPR"),
+SND_SOC_DAPM_OUTPUT("SPKOUT"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+SND_SOC_DAPM_INPUT("LINEINL"),
+SND_SOC_DAPM_INPUT("LINEINR"),
+SND_SOC_DAPM_INPUT("AUXINL"),
+SND_SOC_DAPM_INPUT("AUXINR"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("Vmid"),
+};
+
+static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
+static const struct soc_enum alc5623_amp_enum =
+ SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names);
+static const struct snd_kcontrol_new alc5623_amp_mux_controls =
+ SOC_DAPM_ENUM("Route", alc5623_amp_enum);
+
+static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = {
+SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0,
+ amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0),
+SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0,
+ &alc5623_amp_mux_controls),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ /* virtual mixer - mixes left & right channels */
+ {"I2S Mix", NULL, "Left DAC"},
+ {"I2S Mix", NULL, "Right DAC"},
+ {"Line Mix", NULL, "Right LineIn"},
+ {"Line Mix", NULL, "Left LineIn"},
+ {"AuxI Mix", NULL, "Left AuxI"},
+ {"AuxI Mix", NULL, "Right AuxI"},
+ {"AUXOUTL", NULL, "Left AuxOut"},
+ {"AUXOUTR", NULL, "Right AuxOut"},
+
+ /* HP mixer */
+ {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
+ {"HPL Mix", NULL, "HP Mix"},
+ {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
+ {"HPR Mix", NULL, "HP Mix"},
+ {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
+ {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"},
+ {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
+ {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
+ {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"},
+
+ /* speaker mixer */
+ {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
+ {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"},
+ {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
+ {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
+ {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"},
+
+ /* mono mixer */
+ {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
+ {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
+ {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
+ {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"},
+ {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
+ {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
+ {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"},
+
+ /* Left record mixer */
+ {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
+ {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"},
+ {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
+ {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /*Right record mixer */
+ {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
+ {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"},
+ {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
+ {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /* headphone left mux */
+ {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
+ {"Left Headphone Mux", "Vmid", "Vmid"},
+
+ /* headphone right mux */
+ {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
+ {"Right Headphone Mux", "Vmid", "Vmid"},
+
+ /* speaker out mux */
+ {"SpeakerOut Mux", "Vmid", "Vmid"},
+ {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* Mono/Aux Out mux */
+ {"AuxOut Mux", "Vmid", "Vmid"},
+ {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"AuxOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* output pga */
+ {"HPL", NULL, "Left Headphone"},
+ {"Left Headphone", NULL, "Left Headphone Mux"},
+ {"HPR", NULL, "Right Headphone"},
+ {"Right Headphone", NULL, "Right Headphone Mux"},
+ {"Left AuxOut", NULL, "AuxOut Mux"},
+ {"Right AuxOut", NULL, "AuxOut Mux"},
+
+ /* input pga */
+ {"Left LineIn", NULL, "LINEINL"},
+ {"Right LineIn", NULL, "LINEINR"},
+ {"Left AuxI", NULL, "AUXINL"},
+ {"Right AuxI", NULL, "AUXINR"},
+ {"MIC1 Pre Amp", NULL, "MIC1"},
+ {"MIC2 Pre Amp", NULL, "MIC2"},
+ {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
+ {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
+
+ /* left ADC */
+ {"Left ADC", NULL, "Left Capture Mix"},
+
+ /* right ADC */
+ {"Right ADC", NULL, "Right Capture Mix"},
+
+ {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"},
+ {"SpeakerOut N Mux", "Vmid", "Vmid"},
+
+ {"SPKOUT", NULL, "SpeakerOut"},
+ {"SPKOUTN", NULL, "SpeakerOut N Mux"},
+};
+
+static const struct snd_soc_dapm_route intercon_spk[] = {
+ {"SpeakerOut", NULL, "SpeakerOut Mux"},
+};
+
+static const struct snd_soc_dapm_route intercon_amp_spk[] = {
+ {"AB Amp", NULL, "SpeakerOut Mux"},
+ {"D Amp", NULL, "SpeakerOut Mux"},
+ {"AB-D Amp Mux", "AB Amp", "AB Amp"},
+ {"AB-D Amp Mux", "D Amp", "D Amp"},
+ {"SpeakerOut", NULL, "AB-D Amp Mux"},
+};
+
+/* PLL divisors */
+struct _pll_div {
+ u32 pll_in;
+ u32 pll_out;
+ u16 regvalue;
+};
+
+/* Note : pll code from original alc5623 driver. Not sure of how good it is */
+/* usefull only for master mode */
+static const struct _pll_div codec_master_pll_div[] = {
+
+ { 2048000, 8192000, 0x0ea0},
+ { 3686400, 8192000, 0x4e27},
+ { 12000000, 8192000, 0x456b},
+ { 13000000, 8192000, 0x495f},
+ { 13100000, 8192000, 0x0320},
+ { 2048000, 11289600, 0xf637},
+ { 3686400, 11289600, 0x2f22},
+ { 12000000, 11289600, 0x3e2f},
+ { 13000000, 11289600, 0x4d5b},
+ { 13100000, 11289600, 0x363b},
+ { 2048000, 16384000, 0x1ea0},
+ { 3686400, 16384000, 0x9e27},
+ { 12000000, 16384000, 0x452b},
+ { 13000000, 16384000, 0x542f},
+ { 13100000, 16384000, 0x03a0},
+ { 2048000, 16934400, 0xe625},
+ { 3686400, 16934400, 0x9126},
+ { 12000000, 16934400, 0x4d2c},
+ { 13000000, 16934400, 0x742f},
+ { 13100000, 16934400, 0x3c27},
+ { 2048000, 22579200, 0x2aa0},
+ { 3686400, 22579200, 0x2f20},
+ { 12000000, 22579200, 0x7e2f},
+ { 13000000, 22579200, 0x742f},
+ { 13100000, 22579200, 0x3c27},
+ { 2048000, 24576000, 0x2ea0},
+ { 3686400, 24576000, 0xee27},
+ { 12000000, 24576000, 0x2915},
+ { 13000000, 24576000, 0x772e},
+ { 13100000, 24576000, 0x0d20},
+};
+
+static const struct _pll_div codec_slave_pll_div[] = {
+
+ { 1024000, 16384000, 0x3ea0},
+ { 1411200, 22579200, 0x3ea0},
+ { 1536000, 24576000, 0x3ea0},
+ { 2048000, 16384000, 0x1ea0},
+ { 2822400, 22579200, 0x1ea0},
+ { 3072000, 24576000, 0x1ea0},
+
+};
+
+static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ int i;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int gbl_clk = 0, pll_div = 0;
+ u16 reg;
+
+ if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK)
+ return -ENODEV;
+
+ /* Disable PLL power */
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_PLL,
+ 0);
+
+ /* pll is not used in slave mode */
+ reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+ if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
+ return 0;
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ switch (pll_id) {
+ case ALC5623_PLL_FR_MCLK:
+ for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
+ if (codec_master_pll_div[i].pll_in == freq_in
+ && codec_master_pll_div[i].pll_out == freq_out) {
+ /* PLL source from MCLK */
+ pll_div = codec_master_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ case ALC5623_PLL_FR_BCK:
+ for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+ if (codec_slave_pll_div[i].pll_in == freq_in
+ && codec_slave_pll_div[i].pll_out == freq_out) {
+ /* PLL source from Bitclk */
+ gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK;
+ pll_div = codec_slave_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!pll_div)
+ return -EINVAL;
+
+ snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+ snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_PLL,
+ ALC5623_PWR_ADD2_PLL);
+ gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
+ snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+
+ return 0;
+}
+
+struct _coeff_div {
+ u16 fs;
+ u16 regvalue;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+/* values inspired from column BCLK=32Fs of Appendix A table */
+static const struct _coeff_div coeff_div[] = {
+ {256*8, 0x3a69},
+ {384*8, 0x3c6b},
+ {256*4, 0x2a69},
+ {384*4, 0x2c6b},
+ {256*2, 0x1a69},
+ {384*2, 0x1c6b},
+ {256*1, 0x0a69},
+ {384*1, 0x0c6b},
+};
+
+static int get_coeff(struct snd_soc_codec *codec, int rate)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].fs * rate == alc5623->sysclk)
+ return i;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+
+ switch (freq) {
+ case 8192000:
+ case 11289600:
+ case 12288000:
+ case 16384000:
+ case 16934400:
+ case 18432000:
+ case 22579200:
+ case 24576000:
+ alc5623->sysclk = freq;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface = ALC5623_DAI_SDP_MASTER_MODE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ iface = ALC5623_DAI_SDP_SLAVE_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= ALC5623_DAI_I2S_DF_I2S;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ iface |= ALC5623_DAI_I2S_DF_RIGHT;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= ALC5623_DAI_I2S_DF_LEFT;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= ALC5623_DAI_I2S_DF_PCM;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+}
+
+static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ int coeff, rate;
+ u16 iface;
+
+ iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+ iface &= ~ALC5623_DAI_I2S_DL_MASK;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= ALC5623_DAI_I2S_DL_16;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= ALC5623_DAI_I2S_DL_20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= ALC5623_DAI_I2S_DL_24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= ALC5623_DAI_I2S_DL_32;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set iface & srate */
+ snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+ rate = params_rate(params);
+ coeff = get_coeff(codec, rate);
+ if (coeff < 0)
+ return -EINVAL;
+
+ coeff = coeff_div[coeff].regvalue;
+ dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
+ __func__, alc5623->sysclk, rate, coeff);
+ snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
+
+ return 0;
+}
+
+static int alc5623_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
+ u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
+
+ if (mute)
+ mute_reg |= hp_mute;
+
+ return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
+}
+
+#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
+ | ALC5623_PWR_ADD2_DAC_REF_CIR)
+
+#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \
+ | ALC5623_PWR_ADD3_MIC1_BOOST_AD)
+
+#define ALC5623_ADD1_POWER_EN \
+ (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \
+ | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \
+ | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP)
+
+#define ALC5623_ADD1_POWER_EN_5622 \
+ (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
+ | ALC5623_PWR_ADD1_HP_OUT_AMP)
+
+static void enable_power_depop(struct snd_soc_codec *codec)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+
+ snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_PWR_ADD1_SOFTGEN_EN,
+ ALC5623_PWR_ADD1_SOFTGEN_EN);
+
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
+
+ snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN);
+
+ msleep(500);
+
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
+
+ /* avoid writing '1' into 5622 reserved bits */
+ if (alc5623->id == 0x22)
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_ADD1_POWER_EN_5622);
+ else
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+ ALC5623_ADD1_POWER_EN);
+
+ /* disable HP Depop2 */
+ snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+ ALC5623_MISC_HP_DEPOP_MODE2_EN,
+ 0);
+
+}
+
+static int alc5623_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ enable_power_depop(codec);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* everything off except vref/vmid, */
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
+ ALC5623_PWR_ADD2_VREF);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
+ ALC5623_PWR_ADD3_MAIN_BIAS);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* everything off, dac mute, inactive */
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
+ snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
+ | SNDRV_PCM_FMTBIT_S24_LE \
+ | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops alc5623_dai_ops = {
+ .hw_params = alc5623_pcm_hw_params,
+ .digital_mute = alc5623_mute,
+ .set_fmt = alc5623_set_dai_fmt,
+ .set_sysclk = alc5623_set_dai_sysclk,
+ .set_pll = alc5623_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver alc5623_dai = {
+ .name = "alc5623-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5623_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5623_FORMATS,},
+
+ .ops = &alc5623_dai_ops,
+};
+
+static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+{
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int alc5623_resume(struct snd_soc_codec *codec)
+{
+ int i, step = codec->driver->reg_cache_step;
+ u16 *cache = codec->reg_cache;
+
+ /* Sync reg_cache with the hardware */
+ for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
+ snd_soc_write(codec, i, cache[i]);
+
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* charge alc5623 caps */
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ alc5623_set_bias_level(codec, codec->dapm.bias_level);
+ }
+
+ return 0;
+}
+
+static int alc5623_probe(struct snd_soc_codec *codec)
+{
+ struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int ret;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ alc5623_reset(codec);
+ alc5623_fill_cache(codec);
+
+ /* power on device */
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ if (alc5623->add_ctrl) {
+ snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
+ alc5623->add_ctrl);
+ }
+
+ if (alc5623->jack_det_ctrl) {
+ snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
+ alc5623->jack_det_ctrl);
+ }
+
+ switch (alc5623->id) {
+ case 0x21:
+ snd_soc_add_controls(codec, rt5621_vol_snd_controls,
+ ARRAY_SIZE(rt5621_vol_snd_controls));
+ break;
+ case 0x22:
+ snd_soc_add_controls(codec, rt5622_vol_snd_controls,
+ ARRAY_SIZE(rt5622_vol_snd_controls));
+ break;
+ case 0x23:
+ snd_soc_add_controls(codec, alc5623_vol_snd_controls,
+ ARRAY_SIZE(alc5623_vol_snd_controls));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_add_controls(codec, alc5623_snd_controls,
+ ARRAY_SIZE(alc5623_snd_controls));
+
+ snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
+ ARRAY_SIZE(alc5623_dapm_widgets));
+
+ /* set up audio path interconnects */
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ switch (alc5623->id) {
+ case 0x21:
+ case 0x22:
+ snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets,
+ ARRAY_SIZE(alc5623_dapm_amp_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon_amp_spk,
+ ARRAY_SIZE(intercon_amp_spk));
+ break;
+ case 0x23:
+ snd_soc_dapm_add_routes(dapm, intercon_spk,
+ ARRAY_SIZE(intercon_spk));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/* power down chip */
+static int alc5623_remove(struct snd_soc_codec *codec)
+{
+ alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
+ .probe = alc5623_probe,
+ .remove = alc5623_remove,
+ .suspend = alc5623_suspend,
+ .resume = alc5623_resume,
+ .set_bias_level = alc5623_set_bias_level,
+ .reg_cache_size = ALC5623_VENDOR_ID2+2,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+};
+
+/*
+ * ALC5623 2 wire address is determined by A1 pin
+ * state during powerup.
+ * low = 0x1a
+ * high = 0x1b
+ */
+static int alc5623_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct alc5623_platform_data *pdata;
+ struct alc5623_priv *alc5623;
+ int ret, vid1, vid2;
+
+ vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
+ if (vid1 < 0) {
+ dev_err(&client->dev, "failed to read I2C\n");
+ return -EIO;
+ }
+ vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
+
+ vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
+ if (vid2 < 0) {
+ dev_err(&client->dev, "failed to read I2C\n");
+ return -EIO;
+ }
+
+ if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
+ dev_err(&client->dev, "unknown or wrong codec\n");
+ dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
+ 0x10ec, id->driver_data,
+ vid1, vid2);
+ return -ENODEV;
+ }
+
+ dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
+
+ alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL);
+ if (alc5623 == NULL)
+ return -ENOMEM;
+
+ pdata = client->dev.platform_data;
+ if (pdata) {
+ alc5623->add_ctrl = pdata->add_ctrl;
+ alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
+ }
+
+ alc5623->id = vid2;
+ switch (alc5623->id) {
+ case 0x21:
+ alc5623_dai.name = "alc5621-hifi";
+ break;
+ case 0x22:
+ alc5623_dai.name = "alc5622-hifi";
+ break;
+ case 0x23:
+ alc5623_dai.name = "alc5623-hifi";
+ break;
+ default:
+ kfree(alc5623);
+ return -EINVAL;
+ }
+
+ i2c_set_clientdata(client, alc5623);
+ alc5623->control_data = client;
+ alc5623->control_type = SND_SOC_I2C;
+ mutex_init(&alc5623->mutex);
+
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_device_alc5623, &alc5623_dai, 1);
+ if (ret != 0) {
+ dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+ kfree(alc5623);
+ }
+
+ return ret;
+}
+
+static int alc5623_i2c_remove(struct i2c_client *client)
+{
+ struct alc5623_priv *alc5623 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+ kfree(alc5623);
+ return 0;
+}
+
+static const struct i2c_device_id alc5623_i2c_table[] = {
+ {"alc5621", 0x21},
+ {"alc5622", 0x22},
+ {"alc5623", 0x23},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
+
+/* i2c codec control layer */
+static struct i2c_driver alc5623_i2c_driver = {
+ .driver = {
+ .name = "alc562x-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = alc5623_i2c_probe,
+ .remove = __devexit_p(alc5623_i2c_remove),
+ .id_table = alc5623_i2c_table,
+};
+
+static int __init alc5623_modinit(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&alc5623_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "%s: can't add i2c driver", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(alc5623_modinit);
+
+static void __exit alc5623_modexit(void)
+{
+ i2c_del_driver(&alc5623_i2c_driver);
+}
+module_exit(alc5623_modexit);
+
+MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h
new file mode 100644
index 000000000000..f3d68260d425
--- /dev/null
+++ b/sound/soc/codecs/alc5623.h
@@ -0,0 +1,161 @@
+/*
+ * alc5623.h -- alc562[123] ALSA Soc Audio driver
+ *
+ * Copyright 2008 Realtek Microelectronics
+ * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Author: flove <flove@realtek.com>
+ * Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ALC5623_H
+#define _ALC5623_H
+
+#define ALC5623_RESET 0x00
+/* 5621 5622 5623 */
+/* speaker output vol 2 2 */
+/* line output vol 4 2 */
+/* HP output vol 4 0 4 */
+#define ALC5623_SPK_OUT_VOL 0x02
+#define ALC5623_HP_OUT_VOL 0x04
+#define ALC5623_MONO_AUX_OUT_VOL 0x06
+#define ALC5623_AUXIN_VOL 0x08
+#define ALC5623_LINE_IN_VOL 0x0A
+#define ALC5623_STEREO_DAC_VOL 0x0C
+#define ALC5623_MIC_VOL 0x0E
+#define ALC5623_MIC_ROUTING_CTRL 0x10
+#define ALC5623_ADC_REC_GAIN 0x12
+#define ALC5623_ADC_REC_MIXER 0x14
+#define ALC5623_SOFT_VOL_CTRL_TIME 0x16
+/* ALC5623_OUTPUT_MIXER_CTRL : */
+/* same remark as for reg 2 line vs speaker */
+#define ALC5623_OUTPUT_MIXER_CTRL 0x1C
+#define ALC5623_MIC_CTRL 0x22
+
+#define ALC5623_DAI_CONTROL 0x34
+#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15)
+#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15)
+#define ALC5623_DAI_I2S_PCM_MODE (1 << 14)
+#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
+#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5)
+#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4)
+#define ALC5623_DAI_I2S_DL_MASK (3 << 2)
+#define ALC5623_DAI_I2S_DL_32 (3 << 2)
+#define ALC5623_DAI_I2S_DL_24 (2 << 2)
+#define ALC5623_DAI_I2S_DL_20 (1 << 2)
+#define ALC5623_DAI_I2S_DL_16 (0 << 2)
+#define ALC5623_DAI_I2S_DF_PCM (3 << 0)
+#define ALC5623_DAI_I2S_DF_LEFT (2 << 0)
+#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0)
+#define ALC5623_DAI_I2S_DF_I2S (0 << 0)
+
+#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36
+#define ALC5623_COMPANDING_CTRL 0x38
+
+#define ALC5623_PWR_MANAG_ADD1 0x3A
+#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15)
+#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14)
+#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11)
+#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10)
+#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5)
+#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */
+#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2)
+#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1)
+#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */
+
+#define ALC5623_PWR_MANAG_ADD2 0x3C
+#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */
+#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */
+#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */
+#define ALC5623_PWR_ADD2_VREF (1 << 13)
+#define ALC5623_PWR_ADD2_PLL (1 << 12)
+#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10)
+#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9)
+#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8)
+#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
+#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
+#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5)
+#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4)
+#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3)
+#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2)
+#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
+#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
+
+#define ALC5623_PWR_MANAG_ADD3 0x3E
+#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15)
+#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14)
+#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13)
+#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12)
+#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10)
+#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9)
+#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7)
+#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6)
+#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5)
+#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4)
+#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3)
+#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2)
+#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
+#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
+
+#define ALC5623_ADD_CTRL_REG 0x40
+
+#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42
+#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15)
+#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15)
+#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14)
+#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1)
+#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1)
+#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0)
+#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0)
+
+#define ALC5623_PLL_CTRL 0x44
+#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
+#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
+#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf)
+
+#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A
+#define ALC5623_GPIO_PIN_CONFIG 0x4C
+#define ALC5623_GPIO_PIN_POLARITY 0x4E
+#define ALC5623_GPIO_PIN_STICKY 0x50
+#define ALC5623_GPIO_PIN_WAKEUP 0x52
+#define ALC5623_GPIO_PIN_STATUS 0x54
+#define ALC5623_GPIO_PIN_SHARING 0x56
+#define ALC5623_OVER_CURR_STATUS 0x58
+#define ALC5623_JACK_DET_CTRL 0x5A
+
+#define ALC5623_MISC_CTRL 0x5E
+#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15)
+#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */
+#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */
+#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10)
+#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9)
+#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5)
+#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4)
+#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3)
+#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2)
+#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0)
+
+#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60
+#define ALC5623_EQ_CTRL 0x62
+#define ALC5623_EQ_MODE_ENABLE 0x66
+#define ALC5623_AVC_CTRL 0x68
+#define ALC5623_HID_CTRL_INDEX 0x6A
+#define ALC5623_HID_CTRL_DATA 0x6C
+#define ALC5623_VENDOR_ID1 0x7C
+#define ALC5623_VENDOR_ID2 0x7E
+
+#define ALC5623_PLL_FR_MCLK 0
+#define ALC5623_PLL_FR_BCK 1
+#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 823643932dde..46dbfd067f79 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -36,8 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dai.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <mach/dm365.h>
@@ -116,7 +114,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
DAVINCI_VC_REG12_POWER_ALL_OFF);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 6d4bdc609ac8..3a582caa6ef9 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -114,7 +114,6 @@ static const char *supply_names[] = {
struct cs4270_private {
enum snd_soc_control_type control_type;
void *control_data;
- u8 reg_cache[CS4270_NUMREGS];
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
unsigned int slave_mode;
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index cb086eaf4e07..8fb7070108dd 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <sound/pcm_params.h>
@@ -47,7 +46,6 @@ struct cs42l51_private {
unsigned int mclk;
unsigned int audio_mode; /* The mode (I2S or left-justified) */
enum master_slave_mode func;
- u8 reg_cache[CS42L51_NUMREGS];
};
#define CS42L51_FORMATS ( \
@@ -519,6 +517,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
static int cs42l51_probe(struct snd_soc_codec *codec)
{
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, reg;
codec->control_data = cs42l51->control_data;
@@ -550,9 +549,9 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, cs42l51_snd_controls,
ARRAY_SIZE(cs42l51_snd_controls));
- snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets,
ARRAY_SIZE(cs42l51_dapm_widgets));
- snd_soc_dapm_add_routes(codec, cs42l51_routes,
+ snd_soc_dapm_add_routes(dapm, cs42l51_routes,
ARRAY_SIZE(cs42l51_routes));
return 0;
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index e8d27c8f9ba3..03d1e860d229 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -18,7 +18,7 @@
#include <sound/core.h>
#include <sound/initval.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include "cx20442.h"
@@ -26,7 +26,6 @@
struct cx20442_priv {
enum snd_soc_control_type control_type;
void *control_data;
- u8 reg_cache[1];
};
#define CX20442_PM 0x0
@@ -89,10 +88,11 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
static int cx20442_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
- ARRAY_SIZE(cx20442_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, cx20442_audio_map,
+ snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
+ ARRAY_SIZE(cx20442_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
ARRAY_SIZE(cx20442_audio_map));
return 0;
@@ -263,7 +263,7 @@ static void v253_close(struct tty_struct *tty)
/* Prevent the codec driver from further accessing the modem */
codec->hw_write = NULL;
cx20442->control_data = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
}
/* Line discipline .hangup() */
@@ -291,7 +291,7 @@ static void v253_receive(struct tty_struct *tty,
/* Set up codec driver access to modem controls */
cx20442->control_data = tty;
codec->hw_write = (hw_write_t)tty->ops->write;
- codec->pop_time = 1;
+ codec->card->pop_time = 1;
}
}
@@ -348,7 +348,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
cx20442->control_data = NULL;
codec->hw_write = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
return 0;
}
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 58bb9b994811..92fd9d7a9221 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 16253ec9b022..f7cd346fd727 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -22,7 +22,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
-#include <sound/soc-dapm.h>
#include <sound/soc.h>
#define JZ4740_REG_CODEC_1 0x0
@@ -266,7 +265,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
/* The only way to clear the suspend flag is to reset the codec */
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
jz4740_codec_wakeup(codec);
mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -288,23 +287,25 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
snd_soc_add_controls(codec, jz4740_codec_controls,
ARRAY_SIZE(jz4740_codec_controls));
- snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
ARRAY_SIZE(jz4740_codec_dapm_widgets));
- snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes,
+ snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
ARRAY_SIZE(jz4740_codec_dapm_routes));
snd_soc_dapm_new_widgets(codec);
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index d63e28773eb1..37133c40e762 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <linux/slab.h>
@@ -40,7 +39,6 @@ struct max98088_cdata {
};
struct max98088_priv {
- u8 reg_cache[M98088_REG_CNT];
enum max98088_type devtype;
void *control_data;
struct max98088_pdata *pdata;
@@ -1230,15 +1228,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int max98088_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, max98088_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
ARRAY_SIZE(max98088_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
snd_soc_add_controls(codec, max98088_snd_controls,
ARRAY_SIZE(max98088_snd_controls));
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -1588,7 +1588,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
static void max98088_sync_cache(struct snd_soc_codec *codec)
{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -1599,14 +1599,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec)
/* write back cached values if they're writeable and
* different from the hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (!max98088_access[i].writable)
continue;
- if (max98088->reg_cache[i] == max98088_reg[i])
+ if (reg_cache[i] == max98088_reg[i])
continue;
- snd_soc_write(codec, i, max98088->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -1623,7 +1623,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
max98088_sync_cache(codec);
snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
@@ -1636,7 +1636,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
codec->cache_sync = 1;
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1951,7 +1951,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
int ret = 0;
codec->cache_sync = 1;
- memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg));
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
if (ret != 0) {
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 6f38d619bf8a..2727befd158e 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -38,7 +38,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "ssm2602.h"
@@ -207,10 +206,11 @@ static const struct snd_soc_dapm_route audio_conn[] = {
static int ssm2602_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
- ARRAY_SIZE(ssm2602_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
+ snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
+ ARRAY_SIZE(ssm2602_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
return 0;
}
@@ -493,7 +493,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 061f9e5a497b..78b2b50271e2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -236,7 +236,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index e8652b1ae326..54a30ef0ec8b 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
@@ -391,11 +390,12 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
- ARRAY_SIZE(tlv320aic23_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
+ ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -574,7 +574,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 6b7d71ec0004..e2a7608d3944 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "tlv320aic26.h"
@@ -31,7 +30,6 @@ MODULE_LICENSE("GPL");
struct aic26 {
struct spi_device *spi;
struct snd_soc_codec codec;
- u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
int master;
int datfm;
int mclk;
@@ -355,7 +353,6 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
*/
static int aic26_probe(struct snd_soc_codec *codec)
{
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
int ret, err, i, reg;
dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
@@ -373,7 +370,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
/* Fill register cache */
- for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
+ for (i = 0; i < codec->driver->reg_cache_size; i++)
aic26_reg_read(codec, i);
/* Register the sysfs files for debugging */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 77b8f9ae29be..3bedab26892f 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -46,7 +46,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/tlv320aic3x.h>
@@ -61,6 +60,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
"DRVDD", /* ADC Analog and Output Driver Voltage */
};
+static LIST_HEAD(reset_list);
+
struct aic3x_priv;
struct aic3x_disable_nb {
@@ -77,6 +78,7 @@ struct aic3x_priv {
struct aic3x_setup_data *setup;
void *control_data;
unsigned int sysclk;
+ struct list_head list;
int master;
int gpio_reset;
int power;
@@ -183,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->card->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -199,7 +201,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
}
if (found)
- snd_soc_dapm_sync(widget->codec);
+ snd_soc_dapm_sync(widget->dapm);
}
ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
@@ -788,17 +790,19 @@ static const struct snd_soc_dapm_route intercon_3007[] = {
static int aic3x_add_widgets(struct snd_soc_codec *codec)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
if (aic3x->model == AIC3X_MODEL_3007) {
- snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
ARRAY_SIZE(aic3007_dapm_widgets));
- snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(intercon_3007));
+ snd_soc_dapm_add_routes(dapm, intercon_3007,
+ ARRAY_SIZE(intercon_3007));
}
return 0;
@@ -1075,7 +1079,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
* Put codec to reset and require cache sync as at least one
* of the supplies was disabled
*/
- if (aic3x->gpio_reset >= 0)
+ if (gpio_is_valid(aic3x->gpio_reset))
gpio_set_value(aic3x->gpio_reset, 0);
aic3x->codec->cache_sync = 1;
}
@@ -1102,7 +1106,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
if (!codec->cache_sync)
goto out;
- if (aic3x->gpio_reset >= 0) {
+ if (gpio_is_valid(aic3x->gpio_reset)) {
udelay(1);
gpio_set_value(aic3x->gpio_reset, 1);
}
@@ -1135,7 +1139,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
aic3x->master) {
/* enable pll */
reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1146,7 +1150,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (!aic3x->power)
aic3x_set_power(codec, 1);
- if (codec->bias_level == SND_SOC_BIAS_PREPARE &&
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
aic3x->master) {
/* disable pll */
reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1159,7 +1163,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
aic3x_set_power(codec, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1344,14 +1348,28 @@ static int aic3x_init(struct snd_soc_codec *codec)
return 0;
}
+static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
+{
+ struct aic3x_priv *a;
+
+ list_for_each_entry(a, &reset_list, list) {
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ aic3x->gpio_reset == a->gpio_reset)
+ return true;
+ }
+
+ return false;
+}
+
static int aic3x_probe(struct snd_soc_codec *codec)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int ret, i;
+ INIT_LIST_HEAD(&aic3x->list);
codec->control_data = aic3x->control_data;
aic3x->codec = codec;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
if (ret != 0) {
@@ -1359,7 +1377,8 @@ static int aic3x_probe(struct snd_soc_codec *codec)
return ret;
}
- if (aic3x->gpio_reset >= 0) {
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x)) {
ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
if (ret != 0)
goto err_gpio;
@@ -1405,6 +1424,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
aic3x_add_widgets(codec);
+ list_add(&aic3x->list, &reset_list);
return 0;
@@ -1414,10 +1434,10 @@ err_notif:
&aic3x->disable_nb[i].nb);
regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
err_get:
- if (aic3x->gpio_reset >= 0)
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x))
gpio_free(aic3x->gpio_reset);
err_gpio:
- kfree(aic3x);
return ret;
}
@@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
int i;
aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (aic3x->gpio_reset >= 0) {
+ list_del(&aic3x->list);
+ if (gpio_is_valid(aic3x->gpio_reset) &&
+ !aic3x_is_shared_reset(aic3x)) {
gpio_set_value(aic3x->gpio_reset, 0);
gpio_free(aic3x->gpio_reset);
}
@@ -1523,21 +1545,6 @@ static struct i2c_driver aic3x_i2c_driver = {
.remove = aic3x_i2c_remove,
.id_table = aic3x_i2c_id,
};
-
-static inline void aic3x_i2c_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&aic3x_i2c_driver);
- if (ret)
- printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
- __func__, ret);
-}
-
-static inline void aic3x_i2c_exit(void)
-{
- i2c_del_driver(&aic3x_i2c_driver);
-}
#endif
static int __init aic3x_modinit(void)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index c5ab8c805771..776ac80cc1a8 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -36,7 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -316,8 +315,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
clock source = internal osc (?) */
dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
- dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
-
/* Restore only selected registers (gains mostly) */
dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
@@ -357,6 +354,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
dac33_write(codec, DAC33_PWR_CTRL, reg);
}
+static inline void dac33_disable_digital(struct snd_soc_codec *codec)
+{
+ u8 reg;
+
+ /* Stop the DAI clock */
+ reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+ reg &= ~DAC33_BCLKON;
+ dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
+
+ /* Power down the Oscillator, and DACs */
+ reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+ reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
+ dac33_write(codec, DAC33_PWR_CTRL, reg);
+}
+
static int dac33_hard_power(struct snd_soc_codec *codec, int power)
{
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
@@ -405,7 +417,7 @@ exit:
return ret;
}
-static int playback_event(struct snd_soc_dapm_widget *w,
+static int dac33_playback_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
@@ -417,6 +429,9 @@ static int playback_event(struct snd_soc_dapm_widget *w,
dac33_prepare_chip(dac33->substream);
}
break;
+ case SND_SOC_DAPM_POST_PMD:
+ dac33_disable_digital(w->codec);
+ break;
}
return 0;
}
@@ -593,8 +608,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("LINEL"),
SND_SOC_DAPM_INPUT("LINER"),
- SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
- SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
+ SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
/* Analog bypass */
SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
@@ -602,12 +617,18 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
&dac33_dapm_abypassr_control),
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
+ SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
+ SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
- SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
+ SND_SOC_DAPM_SUPPLY("Left DAC Power",
+ DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Right DAC Power",
+ DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
+
+ SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
+ SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
};
static const struct snd_soc_dapm_route audio_map[] = {
@@ -615,24 +636,28 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"Analog Left Bypass", "Switch", "LINEL"},
{"Analog Right Bypass", "Switch", "LINER"},
- {"Output Left Amp Power", NULL, "DACL"},
- {"Output Right Amp Power", NULL, "DACR"},
+ {"Output Left Amplifier", NULL, "DACL"},
+ {"Output Right Amplifier", NULL, "DACR"},
+
+ {"Output Left Amplifier", NULL, "Analog Left Bypass"},
+ {"Output Right Amplifier", NULL, "Analog Right Bypass"},
- {"Output Left Amp Power", NULL, "Analog Left Bypass"},
- {"Output Right Amp Power", NULL, "Analog Right Bypass"},
+ {"Output Left Amplifier", NULL, "Left DAC Power"},
+ {"Output Right Amplifier", NULL, "Right DAC Power"},
/* output */
- {"LEFT_LO", NULL, "Output Left Amp Power"},
- {"RIGHT_LO", NULL, "Output Right Amp Power"},
+ {"LEFT_LO", NULL, "Output Left Amplifier"},
+ {"RIGHT_LO", NULL, "Output Right Amplifier"},
};
static int dac33_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
- ARRAY_SIZE(dac33_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
+ ARRAY_SIZE(dac33_dapm_widgets));
/* set up audio path interconnects */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -640,16 +665,18 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
static int dac33_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) {
case SND_SOC_BIAS_ON:
- dac33_soft_power(codec, 1);
+ if (!dac33->substream)
+ dac33_soft_power(codec, 1);
break;
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Coming from OFF, switch on the codec */
ret = dac33_hard_power(codec, 1);
if (ret != 0)
@@ -660,14 +687,14 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
/* Do not power off, when the codec is already off */
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
return 0;
ret = dac33_hard_power(codec, 0);
if (ret != 0)
return ret;
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1415,7 +1442,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
codec->control_data = dac33->control_data;
codec->hw_write = (hw_write_t) i2c_master_send;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
dac33->codec = codec;
/* Read the tlv320dac33 ID registers */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index d2c243095673..0a99f313e218 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -29,7 +29,6 @@
#include <linux/slab.h>
#include <sound/tpa6130a2-plat.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "tpa6130a2.h"
@@ -42,7 +41,7 @@ struct tpa6130a2_data {
unsigned char regs[TPA6130A2_CACHEREGNUM];
struct regulator *supply;
int power_gpio;
- unsigned char power_state;
+ u8 power_state:1;
enum tpa_model id;
};
@@ -117,7 +116,7 @@ static int tpa6130a2_initialize(void)
return ret;
}
-static int tpa6130a2_power(int power)
+static int tpa6130a2_power(u8 power)
{
struct tpa6130a2_data *data;
u8 val;
@@ -127,17 +126,19 @@ static int tpa6130a2_power(int power)
data = i2c_get_clientdata(tpa6130a2_client);
mutex_lock(&data->mutex);
- if (power && !data->power_state) {
- /* Power on */
- if (data->power_gpio >= 0)
- gpio_set_value(data->power_gpio, 1);
+ if (power == data->power_state)
+ goto exit;
+ if (power) {
ret = regulator_enable(data->supply);
if (ret != 0) {
dev_err(&tpa6130a2_client->dev,
"Failed to enable supply: %d\n", ret);
goto exit;
}
+ /* Power on */
+ if (data->power_gpio >= 0)
+ gpio_set_value(data->power_gpio, 1);
data->power_state = 1;
ret = tpa6130a2_initialize();
@@ -150,12 +151,7 @@ static int tpa6130a2_power(int power)
data->power_state = 0;
goto exit;
}
-
- /* Clear SWS */
- val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
- val &= ~TPA6130A2_SWS;
- tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
- } else if (!power && data->power_state) {
+ } else {
/* set SWS */
val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
val |= TPA6130A2_SWS;
@@ -300,6 +296,7 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
/* Enable amplifier */
val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
val |= channel;
+ val &= ~TPA6130A2_SWS;
tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
/* Unmute channel */
@@ -320,94 +317,41 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
}
}
-static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
- break;
- }
- return 0;
-}
-
-static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
- break;
- }
- return 0;
-}
-
-static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
{
int ret = 0;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
+ if (enable) {
ret = tpa6130a2_power(1);
- break;
- case SND_SOC_DAPM_POST_PMD:
+ if (ret < 0)
+ return ret;
+ tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
+ 1);
+ } else {
+ tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
+ 0);
ret = tpa6130a2_power(0);
- break;
}
+
return ret;
}
-
-static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
- SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
- 0, 0, NULL, 0, tpa6130a2_left_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
- 0, 0, NULL, 0, tpa6130a2_right_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
- 0, 0, tpa6130a2_supply_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- /* Outputs */
- SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"),
- SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
- {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
-
- {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
- {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
-};
+EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
int tpa6130a2_add_controls(struct snd_soc_codec *codec)
{
struct tpa6130a2_data *data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
if (tpa6130a2_client == NULL)
return -ENODEV;
data = i2c_get_clientdata(tpa6130a2_client);
- snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
- ARRAY_SIZE(tpa6130a2_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-
if (data->id == TPA6140A2)
return snd_soc_add_controls(codec, tpa6140a2_controls,
ARRAY_SIZE(tpa6140a2_controls));
else
return snd_soc_add_controls(codec, tpa6130a2_controls,
ARRAY_SIZE(tpa6130a2_controls));
-
}
EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 57e867fd86d1..5df49c8756b2 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -57,5 +57,6 @@
#define TPA6130A2_VERSION_MASK (0x0f)
extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
+extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index cbebec6ba1ba..e4d464b937d6 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -32,7 +32,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -233,6 +232,16 @@ static int twl4030_write(struct snd_soc_codec *codec,
return 0;
}
+static inline void twl4030_wait_ms(int time)
+{
+ if (time < 60) {
+ time *= 1000;
+ usleep_range(time, time + 500);
+ } else {
+ msleep(time);
+ }
+}
+
static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -338,10 +347,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
twl4030_write(codec, TWL4030_REG_ANAMICL,
reg | TWL4030_CNCL_OFFSET_START);
- /* wait for offset cancellation to complete */
+ /*
+ * Wait for offset cancellation to complete.
+ * Since this takes a while, do not slam the i2c.
+ * Start polling the status after ~20ms.
+ */
+ msleep(20);
do {
- /* this takes a little while, so don't slam i2c */
- udelay(2000);
+ usleep_range(1000, 2000);
twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
TWL4030_REG_ANAMICL);
} while ((i++ < 100) &&
@@ -725,9 +738,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
/* Base values for ramp delay calculation: 2^19 - 2^26 */
unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
8388608, 16777216, 33554432, 67108864};
+ unsigned int delay;
hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
+ delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
+ twl4030->sysclk) + 1;
/* Enable external mute control, this dramatically reduces
* the pop-noise */
@@ -751,16 +767,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
hs_pop |= TWL4030_RAMP_EN;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
/* Wait ramp delay time + 1, so the VMID can settle */
- mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
- twl4030->sysclk) + 1);
+ twl4030_wait_ms(delay);
} else {
/* Headset ramp-down _not_ according to
* the TRM, but in a way that it is working */
hs_pop &= ~TWL4030_RAMP_EN;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
/* Wait ramp delay time + 1, so the VMID can settle */
- mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
- twl4030->sysclk) + 1);
+ twl4030_wait_ms(delay);
/* Bypass the reg_cache to mute the headset */
twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
hs_gain & (~0x0f),
@@ -835,7 +849,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
if (twl4030->digimic_delay)
- mdelay(twl4030->digimic_delay);
+ twl4030_wait_ms(twl4030->digimic_delay);
return 0;
}
@@ -1621,10 +1635,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int twl4030_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
- ARRAY_SIZE(twl4030_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
+ ARRAY_SIZE(twl4030_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -1638,14 +1653,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
twl4030_codec_enable(codec, 1);
break;
case SND_SOC_BIAS_OFF:
twl4030_codec_enable(codec, 0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1709,6 +1724,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = rtd->codec;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+ snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
if (twl4030->master_substream) {
twl4030->slave_substream = substream;
/* The DAI has one configuration for playback and capture, so
@@ -1833,7 +1849,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_S16_LE:
format |= TWL4030_DATA_WIDTH_16S_16W;
break;
- case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
format |= TWL4030_DATA_WIDTH_32S_24W;
break;
default:
@@ -2166,7 +2182,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
}
#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
-#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
+#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
.startup = twl4030_startup,
@@ -2245,7 +2261,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */
twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec);
@@ -2257,9 +2273,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
static int twl4030_soc_remove(struct snd_soc_codec *codec)
{
+ struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+
/* Reset registers to their chip default before leaving */
twl4030_reset_registers(codec);
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ kfree(twl4030);
return 0;
}
@@ -2291,10 +2310,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
static int __devexit twl4030_codec_remove(struct platform_device *pdev)
{
- struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
-
snd_soc_unregister_codec(&pdev->dev);
- kfree(twl4030);
return 0;
}
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 10f6e5214511..2f68f5949a63 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -34,14 +34,46 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include "twl6040.h"
-#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
+#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
+#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
+
+#define TWL6040_OUTHS_0dB 0x00
+#define TWL6040_OUTHS_M30dB 0x0F
+#define TWL6040_OUTHF_0dB 0x03
+#define TWL6040_OUTHF_M52dB 0x1D
+
+#define TWL6040_RAMP_NONE 0
+#define TWL6040_RAMP_UP 1
+#define TWL6040_RAMP_DOWN 2
+
+#define TWL6040_HSL_VOL_MASK 0x0F
+#define TWL6040_HSL_VOL_SHIFT 0
+#define TWL6040_HSR_VOL_MASK 0xF0
+#define TWL6040_HSR_VOL_SHIFT 4
+#define TWL6040_HF_VOL_MASK 0x1F
+#define TWL6040_HF_VOL_SHIFT 0
+
+struct twl6040_output {
+ u16 active;
+ u16 left_vol;
+ u16 right_vol;
+ u16 left_step;
+ u16 right_step;
+ unsigned int step_delay;
+ u16 ramp;
+ u16 mute;
+ struct completion ramp_done;
+};
+
+struct twl6040_jack_data {
+ struct snd_soc_jack *jack;
+ int report;
+};
/* codec private data */
struct twl6040_data {
@@ -53,6 +85,17 @@ struct twl6040_data {
unsigned int sysclk;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
struct completion ready;
+ struct twl6040_jack_data hs_jack;
+ struct snd_soc_codec *codec;
+ struct workqueue_struct *workqueue;
+ struct delayed_work delayed_work;
+ struct mutex mutex;
+ struct twl6040_output headset;
+ struct twl6040_output handsfree;
+ struct workqueue_struct *hf_workqueue;
+ struct workqueue_struct *hs_workqueue;
+ struct delayed_work hs_delayed_work;
+ struct delayed_work hf_delayed_work;
};
/*
@@ -201,7 +244,7 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
if (reg >= TWL6040_CACHEREGNUM)
return -EIO;
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
+ twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg);
twl6040_write_reg_cache(codec, reg, value);
return value;
@@ -217,7 +260,7 @@ static int twl6040_write(struct snd_soc_codec *codec,
return -EIO;
twl6040_write_reg_cache(codec, reg, value);
- return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
+ return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg);
}
static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
@@ -254,6 +297,305 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
}
}
+/*
+ * Ramp HS PGA volume to minimise pops at stream startup and shutdown.
+ */
+static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
+ unsigned int left_step, unsigned int right_step)
+{
+
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *headset = &priv->headset;
+ int left_complete = 0, right_complete = 0;
+ u8 reg, val;
+
+ /* left channel */
+ left_step = (left_step > 0xF) ? 0xF : left_step;
+ reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
+ val = (~reg & TWL6040_HSL_VOL_MASK);
+
+ if (headset->ramp == TWL6040_RAMP_UP) {
+ /* ramp step up */
+ if (val < headset->left_vol) {
+ val += left_step;
+ reg &= ~TWL6040_HSL_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HSGAIN,
+ (reg | (~val & TWL6040_HSL_VOL_MASK)));
+ } else {
+ left_complete = 1;
+ }
+ } else if (headset->ramp == TWL6040_RAMP_DOWN) {
+ /* ramp step down */
+ if (val > 0x0) {
+ val -= left_step;
+ reg &= ~TWL6040_HSL_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
+ (~val & TWL6040_HSL_VOL_MASK));
+ } else {
+ left_complete = 1;
+ }
+ }
+
+ /* right channel */
+ right_step = (right_step > 0xF) ? 0xF : right_step;
+ reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
+ val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
+
+ if (headset->ramp == TWL6040_RAMP_UP) {
+ /* ramp step up */
+ if (val < headset->right_vol) {
+ val += right_step;
+ reg &= ~TWL6040_HSR_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HSGAIN,
+ (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
+ } else {
+ right_complete = 1;
+ }
+ } else if (headset->ramp == TWL6040_RAMP_DOWN) {
+ /* ramp step down */
+ if (val > 0x0) {
+ val -= right_step;
+ reg &= ~TWL6040_HSR_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HSGAIN,
+ reg | (~val << TWL6040_HSR_VOL_SHIFT));
+ } else {
+ right_complete = 1;
+ }
+ }
+
+ return left_complete & right_complete;
+}
+
+/*
+ * Ramp HF PGA volume to minimise pops at stream startup and shutdown.
+ */
+static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
+ unsigned int left_step, unsigned int right_step)
+{
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *handsfree = &priv->handsfree;
+ int left_complete = 0, right_complete = 0;
+ u16 reg, val;
+
+ /* left channel */
+ left_step = (left_step > 0x1D) ? 0x1D : left_step;
+ reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
+ reg = 0x1D - reg;
+ val = (reg & TWL6040_HF_VOL_MASK);
+ if (handsfree->ramp == TWL6040_RAMP_UP) {
+ /* ramp step up */
+ if (val < handsfree->left_vol) {
+ val += left_step;
+ reg &= ~TWL6040_HF_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HFLGAIN,
+ reg | (0x1D - val));
+ } else {
+ left_complete = 1;
+ }
+ } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
+ /* ramp step down */
+ if (val > 0) {
+ val -= left_step;
+ reg &= ~TWL6040_HF_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HFLGAIN,
+ reg | (0x1D - val));
+ } else {
+ left_complete = 1;
+ }
+ }
+
+ /* right channel */
+ right_step = (right_step > 0x1D) ? 0x1D : right_step;
+ reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
+ reg = 0x1D - reg;
+ val = (reg & TWL6040_HF_VOL_MASK);
+ if (handsfree->ramp == TWL6040_RAMP_UP) {
+ /* ramp step up */
+ if (val < handsfree->right_vol) {
+ val += right_step;
+ reg &= ~TWL6040_HF_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HFRGAIN,
+ reg | (0x1D - val));
+ } else {
+ right_complete = 1;
+ }
+ } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
+ /* ramp step down */
+ if (val > 0) {
+ val -= right_step;
+ reg &= ~TWL6040_HF_VOL_MASK;
+ twl6040_write(codec, TWL6040_REG_HFRGAIN,
+ reg | (0x1D - val));
+ }
+ }
+
+ return left_complete & right_complete;
+}
+
+/*
+ * This work ramps both output PGAs at stream start/stop time to
+ * minimise pop associated with DAPM power switching.
+ */
+static void twl6040_pga_hs_work(struct work_struct *work)
+{
+ struct twl6040_data *priv =
+ container_of(work, struct twl6040_data, hs_delayed_work.work);
+ struct snd_soc_codec *codec = priv->codec;
+ struct twl6040_output *headset = &priv->headset;
+ unsigned int delay = headset->step_delay;
+ int i, headset_complete;
+
+ /* do we need to ramp at all ? */
+ if (headset->ramp == TWL6040_RAMP_NONE)
+ return;
+
+ /* HS PGA volumes have 4 bits of resolution to ramp */
+ for (i = 0; i <= 16; i++) {
+ headset_complete = 1;
+ if (headset->ramp != TWL6040_RAMP_NONE)
+ headset_complete = twl6040_hs_ramp_step(codec,
+ headset->left_step,
+ headset->right_step);
+
+ /* ramp finished ? */
+ if (headset_complete)
+ break;
+
+ /*
+ * TODO: tune: delay is longer over 0dB
+ * as increases are larger.
+ */
+ if (i >= 8)
+ schedule_timeout_interruptible(msecs_to_jiffies(delay +
+ (delay >> 1)));
+ else
+ schedule_timeout_interruptible(msecs_to_jiffies(delay));
+ }
+
+ if (headset->ramp == TWL6040_RAMP_DOWN) {
+ headset->active = 0;
+ complete(&headset->ramp_done);
+ } else {
+ headset->active = 1;
+ }
+ headset->ramp = TWL6040_RAMP_NONE;
+}
+
+static void twl6040_pga_hf_work(struct work_struct *work)
+{
+ struct twl6040_data *priv =
+ container_of(work, struct twl6040_data, hf_delayed_work.work);
+ struct snd_soc_codec *codec = priv->codec;
+ struct twl6040_output *handsfree = &priv->handsfree;
+ unsigned int delay = handsfree->step_delay;
+ int i, handsfree_complete;
+
+ /* do we need to ramp at all ? */
+ if (handsfree->ramp == TWL6040_RAMP_NONE)
+ return;
+
+ /* HF PGA volumes have 5 bits of resolution to ramp */
+ for (i = 0; i <= 32; i++) {
+ handsfree_complete = 1;
+ if (handsfree->ramp != TWL6040_RAMP_NONE)
+ handsfree_complete = twl6040_hf_ramp_step(codec,
+ handsfree->left_step,
+ handsfree->right_step);
+
+ /* ramp finished ? */
+ if (handsfree_complete)
+ break;
+
+ /*
+ * TODO: tune: delay is longer over 0dB
+ * as increases are larger.
+ */
+ if (i >= 16)
+ schedule_timeout_interruptible(msecs_to_jiffies(delay +
+ (delay >> 1)));
+ else
+ schedule_timeout_interruptible(msecs_to_jiffies(delay));
+ }
+
+
+ if (handsfree->ramp == TWL6040_RAMP_DOWN) {
+ handsfree->active = 0;
+ complete(&handsfree->ramp_done);
+ } else
+ handsfree->active = 1;
+ handsfree->ramp = TWL6040_RAMP_NONE;
+}
+
+static int pga_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *out;
+ struct delayed_work *work;
+ struct workqueue_struct *queue;
+
+ switch (w->shift) {
+ case 2:
+ case 3:
+ out = &priv->headset;
+ work = &priv->hs_delayed_work;
+ queue = priv->hs_workqueue;
+ out->step_delay = 5; /* 5 ms between volume ramp steps */
+ break;
+ case 4:
+ out = &priv->handsfree;
+ work = &priv->hf_delayed_work;
+ queue = priv->hf_workqueue;
+ out->step_delay = 5; /* 5 ms between volume ramp steps */
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ priv->non_lp++;
+ else
+ priv->non_lp--;
+ break;
+ default:
+ return -1;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if (out->active)
+ break;
+
+ /* don't use volume ramp for power-up */
+ out->left_step = out->left_vol;
+ out->right_step = out->right_vol;
+
+ if (!delayed_work_pending(work)) {
+ out->ramp = TWL6040_RAMP_UP;
+ queue_delayed_work(queue, work,
+ msecs_to_jiffies(1));
+ }
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ if (!out->active)
+ break;
+
+ if (!delayed_work_pending(work)) {
+ /* use volume ramp for power-down */
+ out->left_step = 1;
+ out->right_step = 1;
+ out->ramp = TWL6040_RAMP_DOWN;
+ INIT_COMPLETION(out->ramp_done);
+
+ queue_delayed_work(queue, work,
+ msecs_to_jiffies(1));
+
+ wait_for_completion_timeout(&out->ramp_done,
+ msecs_to_jiffies(2000));
+ }
+ break;
+ }
+
+ return 0;
+}
+
/* twl6040 codec manual power-up sequence */
static void twl6040_power_up(struct snd_soc_codec *codec)
{
@@ -382,6 +724,47 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
return 0;
}
+void twl6040_hs_jack_report(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, int report)
+{
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ int status;
+
+ mutex_lock(&priv->mutex);
+
+ /* Sync status */
+ status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
+ if (status & TWL6040_PLUGCOMP)
+ snd_soc_jack_report(jack, report, report);
+ else
+ snd_soc_jack_report(jack, 0, report);
+
+ mutex_unlock(&priv->mutex);
+}
+
+void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, int report)
+{
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_jack_data *hs_jack = &priv->hs_jack;
+
+ hs_jack->jack = jack;
+ hs_jack->report = report;
+
+ twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+}
+EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
+
+static void twl6040_accessory_work(struct work_struct *work)
+{
+ struct twl6040_data *priv = container_of(work,
+ struct twl6040_data, delayed_work.work);
+ struct snd_soc_codec *codec = priv->codec;
+ struct twl6040_jack_data *hs_jack = &priv->hs_jack;
+
+ twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+}
+
/* audio interrupt handler */
static irqreturn_t twl6040_naudint_handler(int irq, void *data)
{
@@ -389,33 +772,180 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data)
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
u8 intid;
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
+ twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
- switch (intid) {
- case TWL6040_THINT:
+ if (intid & TWL6040_THINT)
dev_alert(codec->dev, "die temp over-limit detection\n");
+
+ if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
+ queue_delayed_work(priv->workqueue, &priv->delayed_work,
+ msecs_to_jiffies(200));
+
+ if (intid & TWL6040_HOOKINT)
+ dev_info(codec->dev, "hook detection\n");
+
+ if (intid & TWL6040_HFINT)
+ dev_alert(codec->dev, "hf drivers over current detection\n");
+
+ if (intid & TWL6040_VIBINT)
+ dev_alert(codec->dev, "vib drivers over current detection\n");
+
+ if (intid & TWL6040_READYINT)
+ complete(&priv->ready);
+
+ return IRQ_HANDLED;
+}
+
+static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *out = NULL;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ int ret;
+ unsigned int reg = mc->reg;
+
+ /* For HS and HF we shadow the values and only actually write
+ * them out when active in order to ensure the amplifier comes on
+ * as quietly as possible. */
+ switch (reg) {
+ case TWL6040_REG_HSGAIN:
+ out = &twl6040_priv->headset;
break;
- case TWL6040_PLUGINT:
- case TWL6040_UNPLUGINT:
- case TWL6040_HOOKINT:
+ default:
break;
- case TWL6040_HFINT:
- dev_alert(codec->dev, "hf drivers over current detection\n");
+ }
+
+ if (out) {
+ out->left_vol = ucontrol->value.integer.value[0];
+ out->right_vol = ucontrol->value.integer.value[1];
+ if (!out->active)
+ return 1;
+ }
+
+ ret = snd_soc_put_volsw(kcontrol, ucontrol);
+ if (ret < 0)
+ return ret;
+
+ return 1;
+}
+
+static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *out = &twl6040_priv->headset;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int reg = mc->reg;
+
+ switch (reg) {
+ case TWL6040_REG_HSGAIN:
+ out = &twl6040_priv->headset;
+ ucontrol->value.integer.value[0] = out->left_vol;
+ ucontrol->value.integer.value[1] = out->right_vol;
+ return 0;
+
+ default:
break;
- case TWL6040_VIBINT:
- dev_alert(codec->dev, "vib drivers over current detection\n");
+ }
+
+ return snd_soc_get_volsw(kcontrol, ucontrol);
+}
+
+static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *out = NULL;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ int ret;
+ unsigned int reg = mc->reg;
+
+ /* For HS and HF we shadow the values and only actually write
+ * them out when active in order to ensure the amplifier comes on
+ * as quietly as possible. */
+ switch (reg) {
+ case TWL6040_REG_HFLGAIN:
+ case TWL6040_REG_HFRGAIN:
+ out = &twl6040_priv->handsfree;
break;
- case TWL6040_READYINT:
- complete(&priv->ready);
+ default:
break;
+ }
+
+ if (out) {
+ out->left_vol = ucontrol->value.integer.value[0];
+ out->right_vol = ucontrol->value.integer.value[1];
+ if (!out->active)
+ return 1;
+ }
+
+ ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ if (ret < 0)
+ return ret;
+
+ return 1;
+}
+
+static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
+ struct twl6040_output *out = &twl6040_priv->handsfree;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int reg = mc->reg;
+
+ /* If these are cached registers use the cache */
+ switch (reg) {
+ case TWL6040_REG_HFLGAIN:
+ case TWL6040_REG_HFRGAIN:
+ out = &twl6040_priv->handsfree;
+ ucontrol->value.integer.value[0] = out->left_vol;
+ ucontrol->value.integer.value[1] = out->right_vol;
+ return 0;
+
default:
- dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
break;
}
- return IRQ_HANDLED;
+ return snd_soc_get_volsw_2r(kcontrol, ucontrol);
}
+/* double control with volume update */
+#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
+ xinvert, tlv_array)\
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+ .tlv.p = (tlv_array), \
+ .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
+ .put = twl6040_put_volsw, \
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
+ .max = xmax, .platform_max = xmax, .invert = xinvert} }
+
+/* double control with volume update */
+#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
+ xinvert, tlv_array)\
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+ SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+ .tlv.p = (tlv_array), \
+ .info = snd_soc_info_volsw_2r, \
+ .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+ .rshift = xshift, .max = xmax, .invert = xinvert}, }
+
/*
* MICATT volume control:
* from -6 to 0 dB in 6 dB steps
@@ -424,9 +954,15 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
/*
* MICGAIN volume control:
- * from 6 to 30 dB in 6 dB steps
+ * from -6 to 30 dB in 6 dB steps
*/
-static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
+static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
+
+/*
+ * AFMGAIN volume control:
+ * from 18 to 24 dB in 6 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0);
/*
* HSGAIN volume control:
@@ -455,8 +991,30 @@ static const char *twl6040_amicr_texts[] =
{"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
static const struct soc_enum twl6040_enum[] = {
- SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts),
- SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts),
+ SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
+ SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
+};
+
+static const char *twl6040_hs_texts[] = {
+ "Off", "HS DAC", "Line-In amp"
+};
+
+static const struct soc_enum twl6040_hs_enum[] = {
+ SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
+ twl6040_hs_texts),
+ SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
+ twl6040_hs_texts),
+};
+
+static const char *twl6040_hf_texts[] = {
+ "Off", "HF DAC", "Line-In amp"
+};
+
+static const struct soc_enum twl6040_hf_enum[] = {
+ SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
+ twl6040_hf_texts),
+ SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
+ twl6040_hf_texts),
};
static const struct snd_kcontrol_new amicl_control =
@@ -466,18 +1024,18 @@ static const struct snd_kcontrol_new amicr_control =
SOC_DAPM_ENUM("Route", twl6040_enum[1]);
/* Headset DAC playback switches */
-static const struct snd_kcontrol_new hsdacl_switch_controls =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0);
+static const struct snd_kcontrol_new hsl_mux_controls =
+ SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
-static const struct snd_kcontrol_new hsdacr_switch_controls =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0);
+static const struct snd_kcontrol_new hsr_mux_controls =
+ SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
/* Handsfree DAC playback switches */
-static const struct snd_kcontrol_new hfdacl_switch_controls =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0);
+static const struct snd_kcontrol_new hfl_mux_controls =
+ SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
-static const struct snd_kcontrol_new hfdacr_switch_controls =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
+static const struct snd_kcontrol_new hfr_mux_controls =
+ SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
static const struct snd_kcontrol_new ep_driver_switch_controls =
SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
@@ -489,10 +1047,14 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
SOC_DOUBLE_TLV("Capture Volume",
TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
+ /* AFM gains */
+ SOC_DOUBLE_TLV("Aux FM Volume",
+ TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv),
+
/* Playback gains */
- SOC_DOUBLE_TLV("Headset Playback Volume",
+ SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
- SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
+ SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume",
TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
SOC_SINGLE_TLV("Earphone Playback Volume",
TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
@@ -525,6 +1087,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
SND_SOC_DAPM_PGA("MicAmpR",
TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
+ /* Auxiliary FM PGAs */
+ SND_SOC_DAPM_PGA("AFMAmpL",
+ TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("AFMAmpR",
+ TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
+
/* ADCs */
SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
TWL6040_REG_MICLCTL, 2, 0),
@@ -559,29 +1127,33 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
twl6040_power_mode_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- /* Analog playback switches */
- SND_SOC_DAPM_SWITCH("HSDAC Left Playback",
- SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls),
- SND_SOC_DAPM_SWITCH("HSDAC Right Playback",
- SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls),
- SND_SOC_DAPM_SWITCH("HFDAC Left Playback",
- SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls),
- SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
- SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
+ SND_SOC_DAPM_MUX("HF Left Playback",
+ SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
+ SND_SOC_DAPM_MUX("HF Right Playback",
+ SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
+ /* Analog playback Muxes */
+ SND_SOC_DAPM_MUX("HS Left Playback",
+ SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
+ SND_SOC_DAPM_MUX("HS Right Playback",
+ SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
/* Analog playback drivers */
SND_SOC_DAPM_PGA_E("Handsfree Left Driver",
TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
- twl6040_power_mode_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ pga_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Handsfree Right Driver",
TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
- twl6040_power_mode_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA("Headset Left Driver",
- TWL6040_REG_HSLCTL, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset Right Driver",
- TWL6040_REG_HSRCTL, 2, 0, NULL, 0),
+ pga_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PGA_E("Headset Left Driver",
+ TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
+ pga_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PGA_E("Headset Right Driver",
+ TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
+ pga_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SWITCH_E("Earphone Driver",
SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
twl6040_power_mode_event,
@@ -611,12 +1183,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"ADC Left", NULL, "MicAmpL"},
{"ADC Right", NULL, "MicAmpR"},
- /* Headset playback path */
- {"HSDAC Left Playback", "Switch", "HSDAC Left"},
- {"HSDAC Right Playback", "Switch", "HSDAC Right"},
+ /* AFM path */
+ {"AFMAmpL", "NULL", "AFML"},
+ {"AFMAmpR", "NULL", "AFMR"},
+
+ {"HS Left Playback", "HS DAC", "HSDAC Left"},
+ {"HS Left Playback", "Line-In amp", "AFMAmpL"},
- {"Headset Left Driver", NULL, "HSDAC Left Playback"},
- {"Headset Right Driver", NULL, "HSDAC Right Playback"},
+ {"HS Right Playback", "HS DAC", "HSDAC Right"},
+ {"HS Right Playback", "Line-In amp", "AFMAmpR"},
+
+ {"Headset Left Driver", "NULL", "HS Left Playback"},
+ {"Headset Right Driver", "NULL", "HS Right Playback"},
{"HSOL", NULL, "Headset Left Driver"},
{"HSOR", NULL, "Headset Right Driver"},
@@ -625,12 +1203,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Earphone Driver", "Switch", "HSDAC Left"},
{"EP", NULL, "Earphone Driver"},
- /* Handsfree playback path */
- {"HFDAC Left Playback", "Switch", "HFDAC Left"},
- {"HFDAC Right Playback", "Switch", "HFDAC Right"},
+ {"HF Left Playback", "HF DAC", "HFDAC Left"},
+ {"HF Left Playback", "Line-In amp", "AFMAmpL"},
+
+ {"HF Right Playback", "HF DAC", "HFDAC Right"},
+ {"HF Right Playback", "Line-In amp", "AFMAmpR"},
- {"HFDAC Left PGA", NULL, "HFDAC Left Playback"},
- {"HFDAC Right PGA", NULL, "HFDAC Right Playback"},
+ {"HFDAC Left PGA", NULL, "HF Left Playback"},
+ {"HFDAC Right PGA", NULL, "HF Right Playback"},
{"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
{"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
@@ -641,12 +1221,12 @@ static const struct snd_soc_dapm_route intercon[] = {
static int twl6040_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets,
- ARRAY_SIZE(twl6040_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets,
+ ARRAY_SIZE(twl6040_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -659,10 +1239,10 @@ static int twl6040_power_up_completion(struct snd_soc_codec *codec,
u8 intid;
time_left = wait_for_completion_timeout(&priv->ready,
- msecs_to_jiffies(48));
+ msecs_to_jiffies(144));
if (!time_left) {
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid,
+ twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
TWL6040_REG_INTID);
if (!(intid & TWL6040_READYINT)) {
dev_err(codec->dev, "timeout waiting for READYINT\n");
@@ -713,6 +1293,15 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
/* initialize vdd/vss registers with reg_cache */
twl6040_init_vdd_regs(codec);
+
+ /* Set external boost GPO */
+ twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
+
+ /* Set initial minimal gain values */
+ twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
+ twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
+ twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
+ twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
break;
case SND_SOC_BIAS_OFF:
if (!priv->codec_powered)
@@ -739,7 +1328,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -772,23 +1361,6 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- if (!priv->sysclk) {
- dev_err(codec->dev,
- "no mclk configured, call set_sysclk() on init\n");
- return -EINVAL;
- }
-
- /*
- * capture is not supported at 17.64 MHz,
- * it's reserved for headset low-power playback scenario
- */
- if ((priv->sysclk == 17640000) && substream->stream) {
- dev_err(codec->dev,
- "capture mode is not supported at %dHz\n",
- priv->sysclk);
- return -EINVAL;
- }
-
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
priv->sysclk_constraints);
@@ -814,10 +1386,17 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
rate = params_rate(params);
switch (rate) {
+ case 11250:
+ case 22500:
+ case 44100:
case 88200:
lppllctl |= TWL6040_LPLLFIN;
priv->sysclk = 17640000;
break;
+ case 8000:
+ case 16000:
+ case 32000:
+ case 48000:
case 96000:
lppllctl &= ~TWL6040_LPLLFIN;
priv->sysclk = 19200000;
@@ -832,31 +1411,37 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int twl6040_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
+static int twl6040_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- /*
- * low-power playback mode is restricted
- * for headset path only
- */
- if ((priv->sysclk == 17640000) && priv->non_lp) {
+ if (!priv->sysclk) {
+ dev_err(codec->dev,
+ "no mclk configured, call set_sysclk() on init\n");
+ return -EINVAL;
+ }
+
+ /*
+ * capture is not supported at 17.64 MHz,
+ * it's reserved for headset low-power playback scenario
+ */
+ if ((priv->sysclk == 17640000) &&
+ substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ dev_err(codec->dev,
+ "capture mode is not supported at %dHz\n",
+ priv->sysclk);
+ return -EINVAL;
+ }
+
+ if ((priv->sysclk == 17640000) && priv->non_lp) {
dev_err(codec->dev,
"some enabled paths aren't supported at %dHz\n",
priv->sysclk);
return -EPERM;
- }
- break;
- default:
- break;
}
-
return 0;
}
@@ -970,7 +1555,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
static struct snd_soc_dai_ops twl6040_dai_ops = {
.startup = twl6040_startup,
.hw_params = twl6040_hw_params,
- .trigger = twl6040_trigger,
+ .prepare = twl6040_prepare,
.set_sysclk = twl6040_set_dai_sysclk,
};
@@ -1004,6 +1589,7 @@ static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int twl6040_resume(struct snd_soc_codec *codec)
{
twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
return 0;
}
@@ -1018,24 +1604,41 @@ static int twl6040_probe(struct snd_soc_codec *codec)
struct twl6040_data *priv;
int audpwron, naudint;
int ret = 0;
+ u8 icrev, intmr = TWL6040_ALLINT_MSK;
priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, priv);
- if (twl_codec) {
+ priv->codec = codec;
+
+ twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV);
+
+ if (twl_codec && (icrev > 0))
audpwron = twl_codec->audpwron_gpio;
- naudint = twl_codec->naudint_irq;
- } else {
+ else
audpwron = -EINVAL;
+
+ if (twl_codec)
+ naudint = twl_codec->naudint_irq;
+ else
naudint = 0;
- }
priv->audpwron = audpwron;
priv->naudint = naudint;
+ priv->workqueue = create_singlethread_workqueue("twl6040-codec");
+
+ if (!priv->workqueue)
+ goto work_err;
+
+ INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work);
+
+ mutex_init(&priv->mutex);
init_completion(&priv->ready);
+ init_completion(&priv->headset.ramp_done);
+ init_completion(&priv->handsfree.ramp_done);
if (gpio_is_valid(audpwron)) {
ret = gpio_request(audpwron, "audpwron");
@@ -1047,7 +1650,14 @@ static int twl6040_probe(struct snd_soc_codec *codec)
goto gpio2_err;
priv->codec_powered = 0;
+
+ /* enable only codec ready interrupt */
+ intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
+
+ /* reset interrupt status to allow correct power up sequence */
+ twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
}
+ twl6040_write(codec, TWL6040_REG_INTMR, intmr);
if (naudint) {
/* audio interrupt */
@@ -1057,25 +1667,29 @@ static int twl6040_probe(struct snd_soc_codec *codec)
"twl6040_codec", codec);
if (ret)
goto gpio2_err;
- } else {
- if (gpio_is_valid(audpwron)) {
- /* enable only codec ready interrupt */
- twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
- ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
- } else {
- /* no interrupts at all */
- twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
- TWL6040_ALLINT_MSK);
- }
}
/* init vio registers */
twl6040_init_vio_regs(codec);
+ priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
+ if (priv->hf_workqueue == NULL) {
+ ret = -ENOMEM;
+ goto irq_err;
+ }
+ priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
+ if (priv->hs_workqueue == NULL) {
+ ret = -ENOMEM;
+ goto wq_err;
+ }
+
+ INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
+ INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
+
/* power on device */
ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
if (ret)
- goto irq_err;
+ goto bias_err;
snd_soc_add_controls(codec, twl6040_snd_controls,
ARRAY_SIZE(twl6040_snd_controls));
@@ -1083,6 +1697,10 @@ static int twl6040_probe(struct snd_soc_codec *codec)
return 0;
+bias_err:
+ destroy_workqueue(priv->hs_workqueue);
+wq_err:
+ destroy_workqueue(priv->hf_workqueue);
irq_err:
if (naudint)
free_irq(naudint, codec);
@@ -1090,6 +1708,8 @@ gpio2_err:
if (gpio_is_valid(audpwron))
gpio_free(audpwron);
gpio1_err:
+ destroy_workqueue(priv->workqueue);
+work_err:
kfree(priv);
return ret;
}
@@ -1108,6 +1728,9 @@ static int twl6040_remove(struct snd_soc_codec *codec)
if (naudint)
free_irq(naudint, codec);
+ destroy_workqueue(priv->workqueue);
+ destroy_workqueue(priv->hf_workqueue);
+ destroy_workqueue(priv->hs_workqueue);
kfree(priv);
return 0;
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index f7c77fa58a3c..23aeed0963e6 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -79,6 +79,7 @@
/* INTMR (0x04) fields */
+#define TWL6040_PLUGMSK 0x02
#define TWL6040_READYMSK 0x40
#define TWL6040_ALLINT_MSK 0x7B
@@ -135,4 +136,11 @@
#define TWL6040_HPPLL_ID 1
#define TWL6040_LPPLL_ID 2
+/* STATUS (0x2E) fields */
+
+#define TWL6040_PLUGCOMP 0x02
+
+void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, int report);
+
#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 464f0cfa4c7a..e76847a9438b 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/uda134x.h>
@@ -389,7 +388,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
pd->power(0);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 0c6c725736c6..c5ca8cfea60f 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -27,7 +27,6 @@
#include <sound/control.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/uda1380.h>
@@ -36,7 +35,6 @@
/* codec private data */
struct uda1380_priv {
struct snd_soc_codec *codec;
- u16 reg_cache[UDA1380_CACHEREGNUM];
unsigned int dac_clk;
struct work_struct work;
void *control_data;
@@ -414,10 +412,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int uda1380_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
- ARRAY_SIZE(uda1380_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
+ ARRAY_SIZE(uda1380_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -603,7 +602,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
int reg;
struct uda1380_platform_data *pdata = codec->dev->platform_data;
- if (codec->bias_level == level)
+ if (codec->dapm.bias_level == level)
return 0;
switch (level) {
@@ -613,7 +612,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
if (gpio_is_valid(pdata->gpio_power)) {
gpio_set_value(pdata->gpio_power, 1);
mdelay(1);
@@ -636,7 +635,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
set_bit(reg - 0x10, &uda1380_cache_dirty);
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 0c47c788ccdf..d3ffa2f0122a 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -25,8 +25,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dai.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
#include "wl1273.h"
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 4bcd168794e1..80ddf4fd23db 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -36,7 +36,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -705,6 +704,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Called from the machine driver */
int wm2000_add_controls(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
if (!wm2000_i2c) {
@@ -712,12 +712,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec)
return -ENODEV;
}
- ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets,
ARRAY_SIZE(wm2000_dapm_widgets));
if (ret < 0)
return ret;
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret < 0)
return ret;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 7611add7f8c3..6d6dc9efe914 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -24,9 +24,9 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
+#include <trace/events/asoc.h>
#include "wm8350.h"
@@ -54,6 +54,7 @@ struct wm8350_output {
struct wm8350_jack_data {
struct snd_soc_jack *jack;
+ struct delayed_work work;
int report;
int short_report;
};
@@ -230,8 +231,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
*/
static void wm8350_pga_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context, delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
struct wm8350_output *out1 = &wm8350_data->out1,
*out2 = &wm8350_data->out2;
@@ -302,8 +304,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out->ramp = WM8350_RAMP_UP;
out->active = 1;
- if (!delayed_work_pending(&codec->delayed_work))
- schedule_delayed_work(&codec->delayed_work,
+ if (!delayed_work_pending(&codec->dapm.delayed_work))
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(1));
break;
@@ -311,8 +313,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out->ramp = WM8350_RAMP_DOWN;
out->active = 0;
- if (!delayed_work_pending(&codec->delayed_work))
- schedule_delayed_work(&codec->delayed_work,
+ if (!delayed_work_pending(&codec->dapm.delayed_work))
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(1));
break;
}
@@ -786,9 +788,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8350_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- ret = snd_soc_dapm_new_controls(codec,
+ ret = snd_soc_dapm_new_controls(dapm,
wm8350_dapm_widgets,
ARRAY_SIZE(wm8350_dapm_widgets));
if (ret != 0) {
@@ -797,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
}
/* set up audio paths */
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret != 0) {
dev_err(codec->dev, "DAPM route register failed\n");
return ret;
@@ -1184,7 +1187,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
priv->supplies);
if (ret != 0)
@@ -1317,7 +1320,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
priv->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1334,45 +1337,69 @@ static int wm8350_resume(struct snd_soc_codec *codec)
return 0;
}
-static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
+static void wm8350_hp_work(struct wm8350_data *priv,
+ struct wm8350_jack_data *jack,
+ u16 mask)
{
- struct wm8350_data *priv = data;
struct wm8350 *wm8350 = priv->codec.control_data;
u16 reg;
int report;
- int mask;
+
+ reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
+ if (reg & mask)
+ report = jack->report;
+ else
+ report = 0;
+
+ snd_soc_jack_report(jack->jack, report, jack->report);
+
+}
+
+static void wm8350_hpl_work(struct work_struct *work)
+{
+ struct wm8350_data *priv =
+ container_of(work, struct wm8350_data, hpl.work.work);
+
+ wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
+}
+
+static void wm8350_hpr_work(struct work_struct *work)
+{
+ struct wm8350_data *priv =
+ container_of(work, struct wm8350_data, hpr.work.work);
+
+ wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
+}
+
+static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
+{
+ struct wm8350_data *priv = data;
+ struct wm8350 *wm8350 = priv->codec.control_data;
struct wm8350_jack_data *jack = NULL;
switch (irq - wm8350->irq_base) {
case WM8350_IRQ_CODEC_JCK_DET_L:
+#ifndef CONFIG_SND_SOC_WM8350_MODULE
+ trace_snd_soc_jack_irq("WM8350 HPL");
+#endif
jack = &priv->hpl;
- mask = WM8350_JACK_L_LVL;
break;
case WM8350_IRQ_CODEC_JCK_DET_R:
+#ifndef CONFIG_SND_SOC_WM8350_MODULE
+ trace_snd_soc_jack_irq("WM8350 HPR");
+#endif
jack = &priv->hpr;
- mask = WM8350_JACK_R_LVL;
break;
default:
BUG();
}
- if (!jack->jack) {
- dev_warn(wm8350->dev, "Jack interrupt called with no jack\n");
- return IRQ_NONE;
- }
-
- /* Debounce */
- msleep(200);
-
- reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
- if (reg & mask)
- report = jack->report;
- else
- report = 0;
+ if (device_may_wakeup(wm8350->dev))
+ pm_wakeup_event(wm8350->dev, 250);
- snd_soc_jack_report(jack->jack, report, jack->report);
+ schedule_delayed_work(&jack->work, 200);
return IRQ_HANDLED;
}
@@ -1436,6 +1463,10 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
u16 reg;
int report = 0;
+#ifndef CONFIG_SND_SOC_WM8350_MODULE
+ trace_snd_soc_jack_irq("WM8350 mic");
+#endif
+
reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
if (reg & WM8350_JACK_MICSCD_LVL)
report |= priv->mic.short_report;
@@ -1550,7 +1581,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
/* Put the codec into reset if it wasn't already */
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
- INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
+ INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
+ INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
/* Enable the codec */
wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1626,7 +1659,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
{
struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
- int ret;
wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1641,15 +1673,12 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
priv->hpr.jack = NULL;
priv->mic.jack = NULL;
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(&codec->delayed_work);
+ cancel_delayed_work_sync(&priv->hpl.work);
+ cancel_delayed_work_sync(&priv->hpr.work);
/* if there was any work waiting then we run it now and
* wait for its completion */
- if (ret) {
- schedule_delayed_work(&codec->delayed_work, 0);
- flush_scheduled_work();
- }
+ flush_delayed_work_sync(&codec->dapm.delayed_work);
wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 850299786e02..3c3bc079167e 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -911,10 +910,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8400_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets,
- ARRAY_SIZE(wm8400_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets,
+ ARRAY_SIZE(wm8400_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1219,7 +1219,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(power),
&power[0]);
if (ret != 0) {
@@ -1306,7 +1306,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 8f107095760e..db0dced74843 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8510.h"
@@ -216,10 +215,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8510_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets,
- ARRAY_SIZE(wm8510_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets,
+ ARRAY_SIZE(wm8510_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -478,7 +478,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
mdelay(100);
@@ -495,7 +495,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 9a433a5396cb..5eb2f501ce32 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -41,7 +40,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
/* codec private data */
struct wm8523_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8523_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
unsigned int sysclk;
unsigned int rate_constraint_list[WM8523_NUM_RATES];
@@ -110,10 +108,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8523_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets,
- ARRAY_SIZE(wm8523_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
+ ARRAY_SIZE(wm8523_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
switch (level) {
@@ -327,7 +327,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
wm8523->supplies);
if (ret != 0) {
@@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
/* Sync back default/cached values */
for (i = WM8523_AIF_CTRL1;
i < WM8523_MAX_REGISTER; i++)
- snd_soc_write(codec, i, wm8523->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
msleep(100);
@@ -366,7 +366,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
wm8523->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
codec->hw_write = (hw_write_t)i2c_master_send;
@@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
- wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
+ reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
+ reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index a2e0ed59b376..8f6b5ee6645b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -31,7 +31,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <asm/div64.h>
@@ -161,7 +160,7 @@
static const u16 wm8580_reg[] = {
0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+ 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -191,7 +190,6 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
struct wm8580_priv {
enum snd_soc_control_type control_type;
struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
- u16 reg_cache[WM8580_MAX_REGISTER + 1];
struct pll_state a;
struct pll_state b;
int sysclk[2];
@@ -302,10 +300,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8580_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
- ARRAY_SIZE(wm8580_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets,
+ ARRAY_SIZE(wm8580_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -491,29 +490,29 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
paifa |= 0x8;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
- paifa |= 0x10;
- paifb |= WM8580_AIF_LENGTH_24;
+ paifa |= 0x0;
+ paifb |= WM8580_AIF_LENGTH_32;
break;
default:
return -EINVAL;
}
/* Look up the SYSCLK ratio; accept only exact matches */
- ratio = wm8580->sysclk[dai->id] / params_rate(params);
+ ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);
for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
if (ratio == wm8580_sysclk_ratios[i])
break;
if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
- wm8580->sysclk[dai->id], params_rate(params));
+ wm8580->sysclk[dai->driver->id], params_rate(params));
return -EINVAL;
}
paifa |= i;
@@ -716,7 +715,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
switch (clk_id) {
case WM8580_CLKSRC_ADCMCLK:
- if (dai->id != WM8580_DAI_PAIFTX)
+ if (dai->driver->id != WM8580_DAI_PAIFTX)
return -EINVAL;
sel = 0 << sel_shift;
break;
@@ -735,7 +734,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
}
/* We really should validate PLL settings but not yet */
- wm8580->sysclk[dai->id] = freq;
+ wm8580->sysclk[dai->driver->id] = freq;
return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
}
@@ -767,7 +766,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Power up and get individual control of the DACs */
reg = snd_soc_read(codec, WM8580_PWRDN1);
reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
@@ -785,7 +784,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -905,7 +904,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
.set_bias_level = wm8580_set_bias_level,
.reg_cache_size = ARRAY_SIZE(wm8580_reg),
.reg_word_size = sizeof(u16),
- .reg_cache_default = &wm8580_reg,
+ .reg_cache_default = wm8580_reg,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 54fbd76c8bca..97c30382d3ff 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
@@ -34,7 +33,6 @@
/* codec private data */
struct wm8711_priv {
enum snd_soc_control_type bus_type;
- u16 reg_cache[WM8711_CACHEREGNUM];
unsigned int sysclk;
};
@@ -93,10 +91,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8711_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
- ARRAY_SIZE(wm8711_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
+ ARRAY_SIZE(wm8711_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -318,7 +317,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8711_PWR, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 075f35e4f4cb..736b0352d0a7 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -73,10 +72,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8728_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
- ARRAY_SIZE(wm8728_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
+ ARRAY_SIZE(wm8728_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -180,7 +180,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Power everything up... */
reg = snd_soc_read(codec, WM8728_DACCTL);
snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
@@ -197,7 +197,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 631385802eb4..0a67c31b2663 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -44,9 +43,10 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
struct wm8731_priv {
enum snd_soc_control_type control_type;
struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
- u16 reg_cache[WM8731_CACHEREGNUM];
unsigned int sysclk;
int sysclk_type;
+ int playback_fs;
+ bool deemph;
};
@@ -65,16 +65,79 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
static const char *wm8731_input_select[] = {"Line In", "Mic"};
-static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const struct soc_enum wm8731_enum[] = {
- SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select),
- SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
-};
+static const struct soc_enum wm8731_insel_enum =
+ SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select);
+
+static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
+
+static int wm8731_set_deemph(struct snd_soc_codec *codec)
+{
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+ int val, i, best;
+
+ /* If we're using deemphasis select the nearest available sample
+ * rate.
+ */
+ if (wm8731->deemph) {
+ best = 1;
+ for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
+ if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
+ abs(wm8731_deemph[best] - wm8731->playback_fs))
+ best = i;
+ }
+
+ val = best << 1;
+ } else {
+ best = 0;
+ val = 0;
+ }
+
+ dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+ best, wm8731_deemph[best]);
+
+ return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
+}
+
+static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8731->deemph;
+
+ return 0;
+}
+
+static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+ int deemph = ucontrol->value.enumerated.item[0];
+ int ret = 0;
+
+ if (deemph > 1)
+ return -EINVAL;
+
+ mutex_lock(&codec->mutex);
+ if (wm8731->deemph != deemph) {
+ wm8731->deemph = deemph;
+
+ wm8731_set_deemph(codec);
+
+ ret = 1;
+ }
+ mutex_unlock(&codec->mutex);
+
+ return ret;
+}
static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
static const struct snd_kcontrol_new wm8731_snd_controls[] = {
@@ -87,7 +150,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
in_tlv),
SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
-SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
+SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
@@ -96,7 +159,8 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
-SOC_ENUM("Playback De-emphasis", wm8731_enum[1]),
+SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
+ wm8731_get_deemph, wm8731_put_deemph),
};
/* Output Mixer */
@@ -108,7 +172,7 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
/* Input mux */
static const struct snd_kcontrol_new wm8731_input_mux_controls =
-SOC_DAPM_ENUM("Input Select", wm8731_enum[0]);
+SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
@@ -165,10 +229,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8731_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
- ARRAY_SIZE(wm8731_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
+ ARRAY_SIZE(wm8731_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -239,6 +304,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
u16 srate = (coeff_div[i].sr << 2) |
(coeff_div[i].bosr << 1) | coeff_div[i].usb;
+ wm8731->playback_fs = params_rate(params);
+
snd_soc_write(codec, WM8731_SRATE, srate);
/* bit size */
@@ -253,6 +320,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
break;
}
+ wm8731_set_deemph(codec);
+
snd_soc_write(codec, WM8731_IFACE, iface);
return 0;
}
@@ -319,7 +388,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
return 0;
}
@@ -399,7 +468,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
wm8731->supplies);
if (ret != 0)
@@ -428,7 +497,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
wm8731->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -526,7 +595,7 @@ static int wm8731_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
/* Disable bypass path by default */
- snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
+ snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
snd_soc_add_controls(codec, wm8731_snd_controls,
ARRAY_SIZE(wm8731_snd_controls));
@@ -542,7 +611,6 @@ err_regulator_enable:
err_regulator_get:
regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
- kfree(wm8731);
return ret;
}
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
new file mode 100644
index 000000000000..30c67d06a904
--- /dev/null
+++ b/sound/soc/codecs/wm8737.c
@@ -0,0 +1,754 @@
+/*
+ * wm8737.c -- WM8737 ALSA SoC Audio driver
+ *
+ * Copyright 2010 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.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>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8737.h"
+
+#define WM8737_NUM_SUPPLIES 4
+static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
+ "DCVDD",
+ "DBVDD",
+ "AVDD",
+ "MVDD",
+};
+
+/* codec private data */
+struct wm8737_priv {
+ enum snd_soc_control_type control_type;
+ struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
+ unsigned int mclk;
+};
+
+static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
+ 0x00C3, /* R0 - Left PGA volume */
+ 0x00C3, /* R1 - Right PGA volume */
+ 0x0007, /* R2 - AUDIO path L */
+ 0x0007, /* R3 - AUDIO path R */
+ 0x0000, /* R4 - 3D Enhance */
+ 0x0000, /* R5 - ADC Control */
+ 0x0000, /* R6 - Power Management */
+ 0x000A, /* R7 - Audio Format */
+ 0x0000, /* R8 - Clocking */
+ 0x000F, /* R9 - MIC Preamp Control */
+ 0x0003, /* R10 - Misc Bias Control */
+ 0x0000, /* R11 - Noise Gate */
+ 0x007C, /* R12 - ALC1 */
+ 0x0000, /* R13 - ALC2 */
+ 0x0032, /* R14 - ALC3 */
+};
+
+static int wm8737_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, WM8737_RESET, 0);
+}
+
+static const unsigned int micboost_tlv[] = {
+ TLV_DB_RANGE_HEAD(4),
+ 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
+ 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
+};
+static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
+static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
+static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
+
+static const char *micbias_enum_text[] = {
+ "25%",
+ "50%",
+ "75%",
+ "100%",
+};
+
+static const struct soc_enum micbias_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
+
+static const char *low_cutoff_text[] = {
+ "Low", "High"
+};
+
+static const struct soc_enum low_3d =
+ SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
+
+static const char *high_cutoff_text[] = {
+ "High", "Low"
+};
+
+static const struct soc_enum high_3d =
+ SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
+
+static const char *alc_fn_text[] = {
+ "Disabled", "Right", "Left", "Stereo"
+};
+
+static const struct soc_enum alc_fn =
+ SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
+
+static const char *alc_hold_text[] = {
+ "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
+ "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
+ "10.916s", "21.832s", "43.691s"
+};
+
+static const struct soc_enum alc_hold =
+ SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
+
+static const char *alc_atk_text[] = {
+ "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
+ "1.075s", "2.15s", "4.3s", "8.6s"
+};
+
+static const struct soc_enum alc_atk =
+ SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
+
+static const char *alc_dcy_text[] = {
+ "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
+ "4.3s", "8.6s", "17.2s", "34.41s"
+};
+
+static const struct soc_enum alc_dcy =
+ SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
+
+static const struct snd_kcontrol_new wm8737_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 6, 3, 0, micboost_tlv),
+SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 4, 1, 0),
+SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 3, 1, 0),
+
+SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
+ WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
+SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
+ 2, 1, 0),
+
+SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
+
+SOC_ENUM("Mic PGA Bias", micbias_enum),
+SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
+SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
+SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
+
+SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
+SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
+SOC_ENUM("3D Low Cut-off", low_3d),
+SOC_ENUM("3D High Cut-off", low_3d),
+SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
+
+SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
+SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
+ ng_tlv),
+
+SOC_ENUM("ALC", alc_fn),
+SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
+SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
+SOC_ENUM("ALC Hold Time", alc_hold),
+SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
+SOC_ENUM("ALC Attack Time", alc_atk),
+SOC_ENUM("ALC Decay Time", alc_dcy),
+};
+
+static const char *linsel_text[] = {
+ "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
+};
+
+static const struct soc_enum linsel_enum =
+ SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
+
+static const struct snd_kcontrol_new linsel_mux =
+ SOC_DAPM_ENUM("LINSEL", linsel_enum);
+
+
+static const char *rinsel_text[] = {
+ "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
+};
+
+static const struct soc_enum rinsel_enum =
+ SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
+
+static const struct snd_kcontrol_new rinsel_mux =
+ SOC_DAPM_ENUM("RINSEL", rinsel_enum);
+
+static const char *bypass_text[] = {
+ "Direct", "Preamp"
+};
+
+static const struct soc_enum lbypass_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
+
+static const struct snd_kcontrol_new lbypass_mux =
+ SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
+
+
+static const struct soc_enum rbypass_enum =
+ SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
+
+static const struct snd_kcontrol_new rbypass_mux =
+ SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
+
+static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("LINPUT1"),
+SND_SOC_DAPM_INPUT("LINPUT2"),
+SND_SOC_DAPM_INPUT("LINPUT3"),
+SND_SOC_DAPM_INPUT("RINPUT1"),
+SND_SOC_DAPM_INPUT("RINPUT2"),
+SND_SOC_DAPM_INPUT("RINPUT3"),
+SND_SOC_DAPM_INPUT("LACIN"),
+SND_SOC_DAPM_INPUT("RACIN"),
+
+SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
+SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
+
+SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
+SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
+
+SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
+
+SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
+SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ { "LINSEL", "LINPUT1", "LINPUT1" },
+ { "LINSEL", "LINPUT2", "LINPUT2" },
+ { "LINSEL", "LINPUT3", "LINPUT3" },
+ { "LINSEL", "LINPUT1 DC", "LINPUT1" },
+
+ { "RINSEL", "RINPUT1", "RINPUT1" },
+ { "RINSEL", "RINPUT2", "RINPUT2" },
+ { "RINSEL", "RINPUT3", "RINPUT3" },
+ { "RINSEL", "RINPUT1 DC", "RINPUT1" },
+
+ { "Left Preamp Mux", "Preamp", "LINSEL" },
+ { "Left Preamp Mux", "Direct", "LACIN" },
+
+ { "Right Preamp Mux", "Preamp", "RINSEL" },
+ { "Right Preamp Mux", "Direct", "RACIN" },
+
+ { "PGAL", NULL, "Left Preamp Mux" },
+ { "PGAR", NULL, "Right Preamp Mux" },
+
+ { "ADCL", NULL, "PGAL" },
+ { "ADCR", NULL, "PGAR" },
+
+ { "AIF", NULL, "ADCL" },
+ { "AIF", NULL, "ADCR" },
+};
+
+static int wm8737_add_widgets(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
+ ARRAY_SIZE(wm8737_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ return 0;
+}
+
+/* codec mclk clock divider coefficients */
+static const struct {
+ u32 mclk;
+ u32 rate;
+ u8 usb;
+ u8 sr;
+} coeff_div[] = {
+ { 12288000, 8000, 0, 0x4 },
+ { 12288000, 12000, 0, 0x8 },
+ { 12288000, 16000, 0, 0xa },
+ { 12288000, 24000, 0, 0x1c },
+ { 12288000, 32000, 0, 0xc },
+ { 12288000, 48000, 0, 0 },
+ { 12288000, 96000, 0, 0xe },
+
+ { 11289600, 8000, 0, 0x14 },
+ { 11289600, 11025, 0, 0x18 },
+ { 11289600, 22050, 0, 0x1a },
+ { 11289600, 44100, 0, 0x10 },
+ { 11289600, 88200, 0, 0x1e },
+
+ { 18432000, 8000, 0, 0x5 },
+ { 18432000, 12000, 0, 0x9 },
+ { 18432000, 16000, 0, 0xb },
+ { 18432000, 24000, 0, 0x1b },
+ { 18432000, 32000, 0, 0xd },
+ { 18432000, 48000, 0, 0x1 },
+ { 18432000, 96000, 0, 0x1f },
+
+ { 16934400, 8000, 0, 0x15 },
+ { 16934400, 11025, 0, 0x19 },
+ { 16934400, 22050, 0, 0x1b },
+ { 16934400, 44100, 0, 0x11 },
+ { 16934400, 88200, 0, 0x1f },
+
+ { 12000000, 8000, 1, 0x4 },
+ { 12000000, 11025, 1, 0x19 },
+ { 12000000, 12000, 1, 0x8 },
+ { 12000000, 16000, 1, 0xa },
+ { 12000000, 22050, 1, 0x1b },
+ { 12000000, 24000, 1, 0x1c },
+ { 12000000, 32000, 1, 0xc },
+ { 12000000, 44100, 1, 0x11 },
+ { 12000000, 48000, 1, 0x0 },
+ { 12000000, 88200, 1, 0x1f },
+ { 12000000, 96000, 1, 0xe },
+};
+
+static int wm8737_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int i;
+ u16 clocking = 0;
+ u16 af = 0;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate != params_rate(params))
+ continue;
+
+ if (coeff_div[i].mclk == wm8737->mclk)
+ break;
+
+ if (coeff_div[i].mclk == wm8737->mclk * 2) {
+ clocking |= WM8737_CLKDIV2;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(coeff_div)) {
+ dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
+ wm8737->mclk, params_rate(params));
+ return -EINVAL;
+ }
+
+ clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ af |= 0x8;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ af |= 0x10;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ af |= 0x18;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
+ snd_soc_update_bits(codec, WM8737_CLOCKING,
+ WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
+ clocking);
+
+ return 0;
+}
+
+static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (freq == coeff_div[i].mclk ||
+ freq == coeff_div[i].mclk * 2) {
+ wm8737->mclk = freq;
+ return 0;
+ }
+ }
+
+ dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
+
+ return -EINVAL;
+}
+
+
+static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 af = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ af |= WM8737_MS;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ af |= 0x2;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ af |= 0x1;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ af |= 0x3;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ af |= 0x13;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ af |= WM8737_LRP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
+ WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
+
+ return 0;
+}
+
+static int wm8737_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ /* VMID at 2*75k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 0);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to enable supplies: %d\n",
+ ret);
+ return ret;
+ }
+
+ snd_soc_cache_sync(codec);
+
+ /* Fast VMID ramp at 2*2.5k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 0x4);
+
+ /* Bring VMID up */
+ snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+ WM8737_VMID_MASK |
+ WM8737_VREF_MASK,
+ WM8737_VMID_MASK |
+ WM8737_VREF_MASK);
+
+ msleep(500);
+ }
+
+ /* VMID at 2*300k */
+ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+ WM8737_VMIDSEL_MASK, 2);
+
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+ WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
+
+#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8737_dai_ops = {
+ .hw_params = wm8737_hw_params,
+ .set_sysclk = wm8737_set_dai_sysclk,
+ .set_fmt = wm8737_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver wm8737_dai = {
+ .name = "wm8737",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2, /* Mono modes not yet supported */
+ .channels_max = 2,
+ .rates = WM8737_RATES,
+ .formats = WM8737_FORMATS,
+ },
+ .ops = &wm8737_dai_ops,
+};
+
+#ifdef CONFIG_PM
+static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8737_resume(struct snd_soc_codec *codec)
+{
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define wm8737_suspend NULL
+#define wm8737_resume NULL
+#endif
+
+static int wm8737_probe(struct snd_soc_codec *codec)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+ int ret, i;
+
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+ wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
+
+ ret = wm8737_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ goto err_enable;
+ }
+
+ snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
+ WM8737_LVU);
+ snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
+ WM8737_RVU);
+
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Bias level configuration will have done an extra enable */
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+
+ snd_soc_add_controls(codec, wm8737_snd_controls,
+ ARRAY_SIZE(wm8737_snd_controls));
+ wm8737_add_widgets(codec);
+
+ return 0;
+
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+
+ return ret;
+}
+
+static int wm8737_remove(struct snd_soc_codec *codec)
+{
+ struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+
+ wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
+ .probe = wm8737_probe,
+ .remove = wm8737_remove,
+ .suspend = wm8737_suspend,
+ .resume = wm8737_resume,
+ .set_bias_level = wm8737_set_bias_level,
+
+ .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8737_reg,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8737_priv *wm8737;
+ int ret;
+
+ wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ if (wm8737 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8737);
+ wm8737->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8737, &wm8737_dai, 1);
+ if (ret < 0)
+ kfree(wm8737);
+ return ret;
+
+}
+
+static __devexit int wm8737_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id wm8737_i2c_id[] = {
+ { "wm8737", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
+
+static struct i2c_driver wm8737_i2c_driver = {
+ .driver = {
+ .name = "wm8737",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8737_i2c_probe,
+ .remove = __devexit_p(wm8737_i2c_remove),
+ .id_table = wm8737_i2c_id,
+};
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8737_spi_probe(struct spi_device *spi)
+{
+ struct wm8737_priv *wm8737;
+ int ret;
+
+ wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ if (wm8737 == NULL)
+ return -ENOMEM;
+
+ wm8737->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8737);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8737, &wm8737_dai, 1);
+ if (ret < 0)
+ kfree(wm8737);
+ return ret;
+}
+
+static int __devexit wm8737_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8737_spi_driver = {
+ .driver = {
+ .name = "wm8737",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8737_spi_probe,
+ .remove = __devexit_p(wm8737_spi_remove),
+};
+#endif /* CONFIG_SPI_MASTER */
+
+static int __init wm8737_modinit(void)
+{
+ int ret;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8737_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
+ ret);
+ }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8737_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return 0;
+}
+module_init(wm8737_modinit);
+
+static void __exit wm8737_exit(void)
+{
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8737_spi_driver);
+#endif
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8737_i2c_driver);
+#endif
+}
+module_exit(wm8737_exit);
+
+MODULE_DESCRIPTION("ASoC WM8737 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h
new file mode 100644
index 000000000000..23d14c8ff6e7
--- /dev/null
+++ b/sound/soc/codecs/wm8737.h
@@ -0,0 +1,322 @@
+#ifndef _WM8737_H
+#define _WM8737_H
+
+/*
+ * wm8737.c -- WM8523 ALSA SoC Audio driver
+ *
+ * Copyright 2010 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Register values.
+ */
+#define WM8737_LEFT_PGA_VOLUME 0x00
+#define WM8737_RIGHT_PGA_VOLUME 0x01
+#define WM8737_AUDIO_PATH_L 0x02
+#define WM8737_AUDIO_PATH_R 0x03
+#define WM8737_3D_ENHANCE 0x04
+#define WM8737_ADC_CONTROL 0x05
+#define WM8737_POWER_MANAGEMENT 0x06
+#define WM8737_AUDIO_FORMAT 0x07
+#define WM8737_CLOCKING 0x08
+#define WM8737_MIC_PREAMP_CONTROL 0x09
+#define WM8737_MISC_BIAS_CONTROL 0x0A
+#define WM8737_NOISE_GATE 0x0B
+#define WM8737_ALC1 0x0C
+#define WM8737_ALC2 0x0D
+#define WM8737_ALC3 0x0E
+#define WM8737_RESET 0x0F
+
+#define WM8737_REGISTER_COUNT 16
+#define WM8737_MAX_REGISTER 0x0F
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Left PGA volume
+ */
+#define WM8737_LVU 0x0100 /* LVU */
+#define WM8737_LVU_MASK 0x0100 /* LVU */
+#define WM8737_LVU_SHIFT 8 /* LVU */
+#define WM8737_LVU_WIDTH 1 /* LVU */
+#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */
+#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */
+#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */
+
+/*
+ * R1 (0x01) - Right PGA volume
+ */
+#define WM8737_RVU 0x0100 /* RVU */
+#define WM8737_RVU_MASK 0x0100 /* RVU */
+#define WM8737_RVU_SHIFT 8 /* RVU */
+#define WM8737_RVU_WIDTH 1 /* RVU */
+#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */
+#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */
+#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */
+
+/*
+ * R2 (0x02) - AUDIO path L
+ */
+#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */
+#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */
+#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */
+#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */
+#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */
+#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */
+#define WM8737_LMBE 0x0010 /* LMBE */
+#define WM8737_LMBE_MASK 0x0010 /* LMBE */
+#define WM8737_LMBE_SHIFT 4 /* LMBE */
+#define WM8737_LMBE_WIDTH 1 /* LMBE */
+#define WM8737_LMZC 0x0008 /* LMZC */
+#define WM8737_LMZC_MASK 0x0008 /* LMZC */
+#define WM8737_LMZC_SHIFT 3 /* LMZC */
+#define WM8737_LMZC_WIDTH 1 /* LMZC */
+#define WM8737_LPZC 0x0004 /* LPZC */
+#define WM8737_LPZC_MASK 0x0004 /* LPZC */
+#define WM8737_LPZC_SHIFT 2 /* LPZC */
+#define WM8737_LPZC_WIDTH 1 /* LPZC */
+#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */
+#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */
+#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */
+
+/*
+ * R3 (0x03) - AUDIO path R
+ */
+#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */
+#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */
+#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */
+#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */
+#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */
+#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */
+#define WM8737_RMBE 0x0010 /* RMBE */
+#define WM8737_RMBE_MASK 0x0010 /* RMBE */
+#define WM8737_RMBE_SHIFT 4 /* RMBE */
+#define WM8737_RMBE_WIDTH 1 /* RMBE */
+#define WM8737_RMZC 0x0008 /* RMZC */
+#define WM8737_RMZC_MASK 0x0008 /* RMZC */
+#define WM8737_RMZC_SHIFT 3 /* RMZC */
+#define WM8737_RMZC_WIDTH 1 /* RMZC */
+#define WM8737_RPZC 0x0004 /* RPZC */
+#define WM8737_RPZC_MASK 0x0004 /* RPZC */
+#define WM8737_RPZC_SHIFT 2 /* RPZC */
+#define WM8737_RPZC_WIDTH 1 /* RPZC */
+#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */
+#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */
+#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */
+
+/*
+ * R4 (0x04) - 3D Enhance
+ */
+#define WM8737_DIV2 0x0080 /* DIV2 */
+#define WM8737_DIV2_MASK 0x0080 /* DIV2 */
+#define WM8737_DIV2_SHIFT 7 /* DIV2 */
+#define WM8737_DIV2_WIDTH 1 /* DIV2 */
+#define WM8737_3DLC 0x0040 /* 3DLC */
+#define WM8737_3DLC_MASK 0x0040 /* 3DLC */
+#define WM8737_3DLC_SHIFT 6 /* 3DLC */
+#define WM8737_3DLC_WIDTH 1 /* 3DLC */
+#define WM8737_3DUC 0x0020 /* 3DUC */
+#define WM8737_3DUC_MASK 0x0020 /* 3DUC */
+#define WM8737_3DUC_SHIFT 5 /* 3DUC */
+#define WM8737_3DUC_WIDTH 1 /* 3DUC */
+#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */
+#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */
+#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */
+#define WM8737_3DE 0x0001 /* 3DE */
+#define WM8737_3DE_MASK 0x0001 /* 3DE */
+#define WM8737_3DE_SHIFT 0 /* 3DE */
+#define WM8737_3DE_WIDTH 1 /* 3DE */
+
+/*
+ * R5 (0x05) - ADC Control
+ */
+#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */
+#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */
+#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */
+#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */
+#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */
+#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */
+#define WM8737_HPOR 0x0010 /* HPOR */
+#define WM8737_HPOR_MASK 0x0010 /* HPOR */
+#define WM8737_HPOR_SHIFT 4 /* HPOR */
+#define WM8737_HPOR_WIDTH 1 /* HPOR */
+#define WM8737_LP 0x0004 /* LP */
+#define WM8737_LP_MASK 0x0004 /* LP */
+#define WM8737_LP_SHIFT 2 /* LP */
+#define WM8737_LP_WIDTH 1 /* LP */
+#define WM8737_MONOUT 0x0002 /* MONOUT */
+#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */
+#define WM8737_MONOUT_SHIFT 1 /* MONOUT */
+#define WM8737_MONOUT_WIDTH 1 /* MONOUT */
+#define WM8737_ADCHPD 0x0001 /* ADCHPD */
+#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */
+#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */
+#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */
+
+/*
+ * R6 (0x06) - Power Management
+ */
+#define WM8737_VMID 0x0100 /* VMID */
+#define WM8737_VMID_MASK 0x0100 /* VMID */
+#define WM8737_VMID_SHIFT 8 /* VMID */
+#define WM8737_VMID_WIDTH 1 /* VMID */
+#define WM8737_VREF 0x0080 /* VREF */
+#define WM8737_VREF_MASK 0x0080 /* VREF */
+#define WM8737_VREF_SHIFT 7 /* VREF */
+#define WM8737_VREF_WIDTH 1 /* VREF */
+#define WM8737_AI 0x0040 /* AI */
+#define WM8737_AI_MASK 0x0040 /* AI */
+#define WM8737_AI_SHIFT 6 /* AI */
+#define WM8737_AI_WIDTH 1 /* AI */
+#define WM8737_PGL 0x0020 /* PGL */
+#define WM8737_PGL_MASK 0x0020 /* PGL */
+#define WM8737_PGL_SHIFT 5 /* PGL */
+#define WM8737_PGL_WIDTH 1 /* PGL */
+#define WM8737_PGR 0x0010 /* PGR */
+#define WM8737_PGR_MASK 0x0010 /* PGR */
+#define WM8737_PGR_SHIFT 4 /* PGR */
+#define WM8737_PGR_WIDTH 1 /* PGR */
+#define WM8737_ADL 0x0008 /* ADL */
+#define WM8737_ADL_MASK 0x0008 /* ADL */
+#define WM8737_ADL_SHIFT 3 /* ADL */
+#define WM8737_ADL_WIDTH 1 /* ADL */
+#define WM8737_ADR 0x0004 /* ADR */
+#define WM8737_ADR_MASK 0x0004 /* ADR */
+#define WM8737_ADR_SHIFT 2 /* ADR */
+#define WM8737_ADR_WIDTH 1 /* ADR */
+#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */
+#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */
+#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */
+
+/*
+ * R7 (0x07) - Audio Format
+ */
+#define WM8737_SDODIS 0x0080 /* SDODIS */
+#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */
+#define WM8737_SDODIS_SHIFT 7 /* SDODIS */
+#define WM8737_SDODIS_WIDTH 1 /* SDODIS */
+#define WM8737_MS 0x0040 /* MS */
+#define WM8737_MS_MASK 0x0040 /* MS */
+#define WM8737_MS_SHIFT 6 /* MS */
+#define WM8737_MS_WIDTH 1 /* MS */
+#define WM8737_LRP 0x0010 /* LRP */
+#define WM8737_LRP_MASK 0x0010 /* LRP */
+#define WM8737_LRP_SHIFT 4 /* LRP */
+#define WM8737_LRP_WIDTH 1 /* LRP */
+#define WM8737_WL_MASK 0x000C /* WL - [3:2] */
+#define WM8737_WL_SHIFT 2 /* WL - [3:2] */
+#define WM8737_WL_WIDTH 2 /* WL - [3:2] */
+#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
+#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
+#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
+
+/*
+ * R8 (0x08) - Clocking
+ */
+#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */
+#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */
+#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */
+#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */
+#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */
+#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */
+#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */
+#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */
+#define WM8737_SR_MASK 0x003E /* SR - [5:1] */
+#define WM8737_SR_SHIFT 1 /* SR - [5:1] */
+#define WM8737_SR_WIDTH 5 /* SR - [5:1] */
+#define WM8737_USB_MODE 0x0001 /* USB MODE */
+#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */
+#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */
+#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */
+
+/*
+ * R9 (0x09) - MIC Preamp Control
+ */
+#define WM8737_RBYPEN 0x0008 /* RBYPEN */
+#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */
+#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */
+#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */
+#define WM8737_LBYPEN 0x0004 /* LBYPEN */
+#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */
+#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */
+#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */
+#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */
+#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */
+#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */
+
+/*
+ * R10 (0x0A) - Misc Bias Control
+ */
+#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */
+#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */
+#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */
+#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */
+
+/*
+ * R11 (0x0B) - Noise Gate
+ */
+#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */
+#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */
+#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */
+#define WM8737_NGAT 0x0001 /* NGAT */
+#define WM8737_NGAT_MASK 0x0001 /* NGAT */
+#define WM8737_NGAT_SHIFT 0 /* NGAT */
+#define WM8737_NGAT_WIDTH 1 /* NGAT */
+
+/*
+ * R12 (0x0C) - ALC1
+ */
+#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
+#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
+#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
+#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */
+#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */
+#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */
+#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */
+#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */
+#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */
+
+/*
+ * R13 (0x0D) - ALC2
+ */
+#define WM8737_ALCZCE 0x0010 /* ALCZCE */
+#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */
+#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */
+#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */
+#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */
+#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */
+#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */
+
+/*
+ * R14 (0x0E) - ALC3
+ */
+#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */
+#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */
+#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */
+#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */
+#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */
+#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */
+
+/*
+ * R15 (0x0F) - Reset
+ */
+#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */
+#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */
+#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */
+
+#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 90e31e9aa6f7..494f2d31d75b 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -41,7 +40,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
/* codec private data */
struct wm8741_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8741_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
unsigned int sysclk;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
@@ -95,10 +93,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8741_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets,
- ARRAY_SIZE(wm8741_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets,
+ ARRAY_SIZE(wm8741_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec)
static int wm8741_probe(struct snd_soc_codec *codec)
{
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret = 0;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU */
- wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
- wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
+ reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
+ reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
snd_soc_add_controls(codec, wm8741_snd_controls,
ARRAY_SIZE(wm8741_snd_controls));
@@ -455,7 +455,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
.resume = wm8741_resume,
.reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
.reg_word_size = sizeof(u16),
- .reg_cache_default = &wm8741_reg_defaults,
+ .reg_cache_default = wm8741_reg_defaults,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 6c924cd2cfd4..38f38fddd190 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8750.h"
@@ -53,7 +52,6 @@ static const u16 wm8750_reg[] = {
struct wm8750_priv {
unsigned int sysclk;
enum snd_soc_control_type control_type;
- u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
};
#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
@@ -399,10 +397,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8750_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
- ARRAY_SIZE(wm8750_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
+ ARRAY_SIZE(wm8750_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -615,7 +614,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Set VMID to 5k */
snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
@@ -630,7 +629,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8750_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8f679a13f2bc..79b02ae125c5 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -45,7 +45,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -65,22 +64,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
* are using 2 wire for device control, so we cache them instead.
*/
static const u16 wm8753_reg[] = {
- 0x0008, 0x0000, 0x000a, 0x000a,
- 0x0033, 0x0000, 0x0007, 0x00ff,
- 0x00ff, 0x000f, 0x000f, 0x007b,
- 0x0000, 0x0032, 0x0000, 0x00c3,
- 0x00c3, 0x00c0, 0x0000, 0x0000,
+ 0x0000, 0x0008, 0x0000, 0x000a,
+ 0x000a, 0x0033, 0x0000, 0x0007,
+ 0x00ff, 0x00ff, 0x000f, 0x000f,
+ 0x007b, 0x0000, 0x0032, 0x0000,
+ 0x00c3, 0x00c3, 0x00c0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0055,
- 0x0005, 0x0050, 0x0055, 0x0050,
- 0x0055, 0x0050, 0x0055, 0x0079,
- 0x0079, 0x0079, 0x0079, 0x0079,
0x0000, 0x0000, 0x0000, 0x0000,
- 0x0097, 0x0097, 0x0000, 0x0004,
- 0x0000, 0x0083, 0x0024, 0x01ba,
- 0x0000, 0x0083, 0x0024, 0x01ba,
- 0x0000, 0x0000, 0x0000
+ 0x0055, 0x0005, 0x0050, 0x0055,
+ 0x0050, 0x0055, 0x0050, 0x0055,
+ 0x0079, 0x0079, 0x0079, 0x0079,
+ 0x0079, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0097, 0x0097, 0x0000,
+ 0x0004, 0x0000, 0x0083, 0x0024,
+ 0x01ba, 0x0000, 0x0083, 0x0024,
+ 0x01ba, 0x0000, 0x0000, 0x0000
};
/* codec private data */
@@ -88,57 +87,10 @@ struct wm8753_priv {
enum snd_soc_control_type control_type;
unsigned int sysclk;
unsigned int pcmclk;
- u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
int dai_func;
};
-/*
- * read wm8753 register cache
- */
-static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
- return -1;
- return cache[reg - 1];
-}
-
-/*
- * write wm8753 register cache
- */
-static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- u16 *cache = codec->reg_cache;
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
- return;
- cache[reg - 1] = value;
-}
-
-/*
- * write to the WM8753 register space
- */
-static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u8 data[2];
-
- /* data is
- * D15..D9 WM8753 register offset
- * D8...D0 register data
- */
- data[0] = (reg << 1) | ((value >> 8) & 0x0001);
- data[1] = value & 0x00ff;
-
- wm8753_write_reg_cache(codec, reg, value);
- if (codec->hw_write(codec->control_data, data, 2) == 2)
- return 0;
- else
- return -EIO;
-}
-
-#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
+#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
/*
* WM8753 Controls
@@ -218,7 +170,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
return 0;
@@ -228,7 +180,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
@@ -670,10 +622,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8753_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
- ARRAY_SIZE(wm8753_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
+ ARRAY_SIZE(wm8753_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
if (pll_id == WM8753_PLL1) {
offset = 0;
enable = 0x10;
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
} else {
offset = 4;
enable = 0x8;
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
}
if (!freq_in || !freq_out) {
/* disable PLL */
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
- wm8753_write(codec, WM8753_CLOCK, reg);
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
+ snd_soc_write(codec, WM8753_CLOCK, reg);
return 0;
} else {
u16 value = 0;
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
/* set up N and K PLL divisor ratios */
/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
- wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
/* bits 8:0 = PLL_K[17:9] */
value = (pll_div.k & 0x03fe00) >> 9;
- wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
/* bits 8:0 = PLL_K[8:0] */
value = pll_div.k & 0x0001ff;
- wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
/* set PLL as input and enable */
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
(pll_div.div2 << 3));
- wm8753_write(codec, WM8753_CLOCK, reg | enable);
+ snd_soc_write(codec, WM8753_CLOCK, reg | enable);
}
return 0;
}
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_PCM, voice);
return 0;
}
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
/* bit size */
switch (params_format(params)) {
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
/* sample rate */
if (params_rate(params) * 384 == wm8753->pcmclk)
srate |= 0x80;
- wm8753_write(codec, WM8753_SRATE1, srate);
+ snd_soc_write(codec, WM8753_SRATE1, srate);
- wm8753_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_PCM, voice);
return 0;
}
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
u16 voice, ioctl;
- voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
+ voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_PCM, voice);
- wm8753_write(codec, WM8753_IOCTL, ioctl);
+ snd_soc_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
return 0;
}
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
switch (div_id) {
case WM8753_PCMDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
- wm8753_write(codec, WM8753_CLOCK, reg | div);
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
+ snd_soc_write(codec, WM8753_CLOCK, reg | div);
break;
case WM8753_BCLKDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
- wm8753_write(codec, WM8753_SRATE2, reg | div);
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
break;
case WM8753_VXCLKDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
- wm8753_write(codec, WM8753_SRATE2, reg | div);
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
break;
default:
return -EINVAL;
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
return 0;
}
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
u16 ioctl, hifi;
- hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
+ hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
- wm8753_write(codec, WM8753_IOCTL, ioctl);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
return 0;
}
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
int coeff;
/* is digital filter coefficient valid ? */
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
return coeff;
}
- wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+ snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
coeff_div[coeff].usb);
/* bit size */
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
break;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
return 0;
}
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as pcmclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock);
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as pcmclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock);
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as mclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int wm8753_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+ u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
* make sure we check if they are not both active when we mute */
if (mute && wm8753->dai_func == 1) {
if (!codec->active)
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
} else {
if (mute)
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
else
- wm8753_write(codec, WM8753_DAC, mute_reg);
+ snd_soc_write(codec, WM8753_DAC, mute_reg);
}
return 0;
@@ -1273,26 +1226,26 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
static int wm8753_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
+ u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
switch (level) {
case SND_SOC_BIAS_ON:
/* set vmid to 50k and unmute dac */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
break;
case SND_SOC_BIAS_PREPARE:
/* set vmid to 5k for quick power up */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
break;
case SND_SOC_BIAS_STANDBY:
/* mute dac and set vmid to 500k, enable VREF */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
break;
case SND_SOC_BIAS_OFF:
- wm8753_write(codec, WM8753_PWR1, 0x0001);
+ snd_soc_write(codec, WM8753_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1477,14 +1430,16 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
else
dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
}
- wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
+ snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
}
static void wm8753_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
- wm8753_set_bias_level(codec, codec->bias_level);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context,
+ delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
+ wm8753_set_bias_level(codec, dapm->bias_level);
}
static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -1495,62 +1450,40 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int wm8753_resume(struct snd_soc_codec *codec)
{
+ u16 *reg_cache = codec->reg_cache;
int i;
- u8 data[2];
- u16 *cache = codec->reg_cache;
/* Sync reg_cache with the hardware */
- for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
- if (i + 1 == WM8753_RESET)
+ for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
+ if (i == WM8753_RESET)
continue;
/* No point in writing hardware default values back */
- if (cache[i] == wm8753_reg[i])
+ if (reg_cache[i] == wm8753_reg[i])
continue;
- data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
- data[1] = cache[i] & 0x00ff;
- codec->hw_write(codec->control_data, data, 2);
+ snd_soc_write(codec, i, reg_cache[i]);
}
wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* charge wm8753 caps */
- if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->bias_level = SND_SOC_BIAS_ON;
- schedule_delayed_work(&codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(caps_charge));
}
return 0;
}
-/*
- * This function forces any delayed work to be queued and run.
- */
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
-
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
-
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
- }
- return ret;
-}
-
static int wm8753_probe(struct snd_soc_codec *codec)
{
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, reg;
+ int ret;
- INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
if (ret < 0) {
@@ -1569,30 +1502,20 @@ static int wm8753_probe(struct snd_soc_codec *codec)
/* charge output caps */
wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- schedule_delayed_work(&codec->delayed_work,
+ schedule_delayed_work(&codec->dapm.delayed_work,
msecs_to_jiffies(caps_charge));
/* set the update bits */
- reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
- wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
- wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LADC);
- wm8753_write(codec, WM8753_LADC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RADC);
- wm8753_write(codec, WM8753_RADC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
- wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
- wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
- wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
- wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
- wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
- wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
snd_soc_add_controls(codec, wm8753_snd_controls,
ARRAY_SIZE(wm8753_snd_controls));
@@ -1604,7 +1527,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
/* power down chip */
static int wm8753_remove(struct snd_soc_codec *codec)
{
- run_delayed_work(&codec->delayed_work);
+ flush_delayed_work_sync(&codec->dapm.delayed_work);
wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
new file mode 100644
index 000000000000..19b92baa9e8c
--- /dev/null
+++ b/sound/soc/codecs/wm8770.c
@@ -0,0 +1,749 @@
+/*
+ * wm8770.c -- WM8770 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8770.h"
+
+#define WM8770_NUM_SUPPLIES 3
+static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = {
+ "AVDD1",
+ "AVDD2",
+ "DVDD"
+};
+
+static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
+ 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0, 0x90, 0,
+ 0, 0x22, 0x22, 0x3e,
+ 0xc, 0xc, 0x100, 0x189,
+ 0x189, 0x8770
+};
+
+struct wm8770_priv {
+ enum snd_soc_control_type control_type;
+ struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
+ struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
+ struct snd_soc_codec *codec;
+ int sysclk;
+};
+
+static int vout12supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+static int vout34supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+
+/*
+ * We can't use the same notifier block for more than one supply and
+ * there's no way I can see to get from a callback to the caller
+ * except container_of().
+ */
+#define WM8770_REGULATOR_EVENT(n) \
+static int wm8770_regulator_event_##n(struct notifier_block *nb, \
+ unsigned long event, void *data) \
+{ \
+ struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
+ disable_nb[n]); \
+ if (event & REGULATOR_EVENT_DISABLE) { \
+ wm8770->codec->cache_sync = 1; \
+ } \
+ return 0; \
+}
+
+WM8770_REGULATOR_EVENT(0)
+WM8770_REGULATOR_EVENT(1)
+WM8770_REGULATOR_EVENT(2)
+
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1);
+
+static const char *dac_phase_text[][2] = {
+ { "DAC1 Normal", "DAC1 Inverted" },
+ { "DAC2 Normal", "DAC2 Inverted" },
+ { "DAC3 Normal", "DAC3 Inverted" },
+ { "DAC4 Normal", "DAC4 Inverted" },
+};
+
+static const struct soc_enum dac_phase[] = {
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]),
+ SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]),
+};
+
+static const struct snd_kcontrol_new wm8770_snd_controls[] = {
+ /* global DAC playback controls */
+ SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0,
+ dac_dig_tlv),
+ SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1),
+ SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0),
+
+ /* global VOUT playback controls */
+ SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0,
+ dac_alg_tlv),
+ SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0),
+
+ /* VOUT1/2/3/4 specific controls */
+ SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL,
+ WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL,
+ WM8770_VOUT1RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL,
+ WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL,
+ WM8770_VOUT2RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL,
+ WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL,
+ WM8770_VOUT3RVOL, 7, 1, 0),
+ SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL,
+ WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv),
+ SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL,
+ WM8770_VOUT4RVOL, 7, 1, 0),
+
+ /* DAC1/2/3/4 specific controls */
+ SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL,
+ WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0),
+ SOC_ENUM("DAC1 Phase", dac_phase[0]),
+ SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL,
+ WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0),
+ SOC_ENUM("DAC2 Phase", dac_phase[1]),
+ SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL,
+ WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0),
+ SOC_ENUM("DAC3 Phase", dac_phase[2]),
+ SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL,
+ WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv),
+ SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0),
+ SOC_ENUM("DAC4 Phase", dac_phase[3]),
+
+ /* ADC specific controls */
+ SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
+ 0, 31, 0, adc_tlv),
+ SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
+ 5, 1, 1),
+
+ /* other controls */
+ SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0),
+ SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1)
+};
+
+static const char *ain_text[] = {
+ "AIN1", "AIN2", "AIN3", "AIN4",
+ "AIN5", "AIN6", "AIN7", "AIN8"
+};
+
+static const struct soc_enum ain_enum =
+ SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
+
+static const struct snd_kcontrol_new ain_mux =
+ SOC_DAPM_ENUM("Capture Mux", ain_enum);
+
+static const struct snd_kcontrol_new vout1_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0),
+ SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout2_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0),
+ SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout3_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0),
+ SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0)
+};
+
+static const struct snd_kcontrol_new vout4_mix_controls[] = {
+ SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0),
+ SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0)
+};
+
+static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("AUX1"),
+ SND_SOC_DAPM_INPUT("AUX2"),
+ SND_SOC_DAPM_INPUT("AUX3"),
+
+ SND_SOC_DAPM_INPUT("AIN1"),
+ SND_SOC_DAPM_INPUT("AIN2"),
+ SND_SOC_DAPM_INPUT("AIN3"),
+ SND_SOC_DAPM_INPUT("AIN4"),
+ SND_SOC_DAPM_INPUT("AIN5"),
+ SND_SOC_DAPM_INPUT("AIN6"),
+ SND_SOC_DAPM_INPUT("AIN7"),
+ SND_SOC_DAPM_INPUT("AIN8"),
+
+ SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux),
+
+ SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1),
+
+ SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1),
+ SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1),
+ SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1),
+ SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1),
+
+ SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0,
+ vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0,
+ vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0,
+ vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0,
+ vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0,
+ vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)),
+ SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0,
+ vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)),
+
+ SND_SOC_DAPM_OUTPUT("VOUT1"),
+ SND_SOC_DAPM_OUTPUT("VOUT2"),
+ SND_SOC_DAPM_OUTPUT("VOUT3"),
+ SND_SOC_DAPM_OUTPUT("VOUT4")
+};
+
+static const struct snd_soc_dapm_route wm8770_intercon[] = {
+ { "Capture Mux", "AIN1", "AIN1" },
+ { "Capture Mux", "AIN2", "AIN2" },
+ { "Capture Mux", "AIN3", "AIN3" },
+ { "Capture Mux", "AIN4", "AIN4" },
+ { "Capture Mux", "AIN5", "AIN5" },
+ { "Capture Mux", "AIN6", "AIN6" },
+ { "Capture Mux", "AIN7", "AIN7" },
+ { "Capture Mux", "AIN8", "AIN8" },
+
+ { "ADC", NULL, "Capture Mux" },
+
+ { "VOUT1 Mixer", NULL, "VOUT12 Supply" },
+ { "VOUT1 Mixer", "DAC1 Switch", "DAC1" },
+ { "VOUT1 Mixer", "AUX1 Switch", "AUX1" },
+ { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT2 Mixer", NULL, "VOUT12 Supply" },
+ { "VOUT2 Mixer", "DAC2 Switch", "DAC2" },
+ { "VOUT2 Mixer", "AUX2 Switch", "AUX2" },
+ { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT3 Mixer", NULL, "VOUT34 Supply" },
+ { "VOUT3 Mixer", "DAC3 Switch", "DAC3" },
+ { "VOUT3 Mixer", "AUX3 Switch", "AUX3" },
+ { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT4 Mixer", NULL, "VOUT34 Supply" },
+ { "VOUT4 Mixer", "DAC4 Switch", "DAC4" },
+ { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" },
+
+ { "VOUT1", NULL, "VOUT1 Mixer" },
+ { "VOUT2", NULL, "VOUT2 Mixer" },
+ { "VOUT3", NULL, "VOUT3 Mixer" },
+ { "VOUT4", NULL, "VOUT4 Mixer" }
+};
+
+static int vout12supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+
+ codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
+ break;
+ }
+
+ return 0;
+}
+
+static int vout34supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+
+ codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8770_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, WM8770_RESET, 0);
+}
+
+static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec;
+ int iface, master;
+
+ codec = dai->codec;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ master = 0x100;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ master = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ iface = 0;
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x2;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0xc;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x8;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
+ snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
+
+ return 0;
+}
+
+static const int mclk_ratios[] = {
+ 128,
+ 192,
+ 256,
+ 384,
+ 512,
+ 768
+};
+
+static int wm8770_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec;
+ struct wm8770_priv *wm8770;
+ int i;
+ int iface;
+ int shift;
+ int ratio;
+
+ codec = dai->codec;
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+
+ iface = 0;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x10;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x20;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x30;
+ break;
+ }
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ i = 0;
+ shift = 4;
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ i = 2;
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Only need to set MCLK/LRCLK ratio if we're master */
+ if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
+ for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
+ ratio = wm8770->sysclk / params_rate(params);
+ if (ratio == mclk_ratios[i])
+ break;
+ }
+
+ if (i == ARRAY_SIZE(mclk_ratios)) {
+ dev_err(codec->dev,
+ "Unable to configure MCLK ratio %d/%d\n",
+ wm8770->sysclk, params_rate(params));
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
+
+ snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
+ i << shift);
+ }
+
+ snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
+
+ return 0;
+}
+
+static int wm8770_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec;
+
+ codec = dai->codec;
+ return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
+ !!mute << 4);
+}
+
+static int wm8770_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec;
+ struct wm8770_priv *wm8770;
+
+ codec = dai->codec;
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770->sysclk = freq;
+ return 0;
+}
+
+static void wm8770_sync_cache(struct snd_soc_codec *codec)
+{
+ int i;
+ u16 *cache;
+
+ if (!codec->cache_sync)
+ return;
+
+ codec->cache_only = 0;
+ cache = codec->reg_cache;
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
+ if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
+ continue;
+ snd_soc_write(codec, i, cache[i]);
+ }
+ codec->cache_sync = 0;
+}
+
+static int wm8770_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ int ret;
+ struct wm8770_priv *wm8770;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to enable supplies: %d\n",
+ ret);
+ return ret;
+ }
+ wm8770_sync_cache(codec);
+ /* global powerup */
+ snd_soc_write(codec, WM8770_PWDNCTRL, 0);
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* global powerdown */
+ snd_soc_write(codec, WM8770_PWDNCTRL, 1);
+ regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8770_dai_ops = {
+ .digital_mute = wm8770_mute,
+ .hw_params = wm8770_hw_params,
+ .set_fmt = wm8770_set_fmt,
+ .set_sysclk = wm8770_set_sysclk,
+};
+
+static struct snd_soc_dai_driver wm8770_dai = {
+ .name = "wm8770-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = WM8770_FORMATS
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = WM8770_FORMATS
+ },
+ .ops = &wm8770_dai_ops,
+ .symmetric_rates = 1
+};
+
+#ifdef CONFIG_PM
+static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8770_resume(struct snd_soc_codec *codec)
+{
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define wm8770_suspend NULL
+#define wm8770_resume NULL
+#endif
+
+static int wm8770_probe(struct snd_soc_codec *codec)
+{
+ struct wm8770_priv *wm8770;
+ int ret;
+ int i;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770->codec = codec;
+
+ codec->dapm.idle_bias_off = 1;
+
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
+ wm8770->supplies[i].supply = wm8770_supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
+ wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
+ wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
+
+ /* This should really be moved into the regulator core */
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
+ ret = regulator_register_notifier(wm8770->supplies[i].consumer,
+ &wm8770->disable_nb[i]);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to register regulator notifier: %d\n",
+ ret);
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
+ wm8770->supplies);
+ if (ret) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_reg_get;
+ }
+
+ ret = wm8770_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+ goto err_reg_enable;
+ }
+
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* latch the volume update bits */
+ snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
+
+ /* mute all DACs */
+ snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
+
+ snd_soc_add_controls(codec, wm8770_snd_controls,
+ ARRAY_SIZE(wm8770_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
+ ARRAY_SIZE(wm8770_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
+ ARRAY_SIZE(wm8770_intercon));
+ return 0;
+
+err_reg_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+err_reg_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+ return ret;
+}
+
+static int wm8770_remove(struct snd_soc_codec *codec)
+{
+ struct wm8770_priv *wm8770;
+ int i;
+
+ wm8770 = snd_soc_codec_get_drvdata(codec);
+ wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
+ regulator_unregister_notifier(wm8770->supplies[i].consumer,
+ &wm8770->disable_nb[i]);
+ regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
+ .probe = wm8770_probe,
+ .remove = wm8770_remove,
+ .suspend = wm8770_suspend,
+ .resume = wm8770_resume,
+ .set_bias_level = wm8770_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
+ .reg_word_size = sizeof (u16),
+ .reg_cache_default = wm8770_reg_defs
+};
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8770_spi_probe(struct spi_device *spi)
+{
+ struct wm8770_priv *wm8770;
+ int ret;
+
+ wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL);
+ if (!wm8770)
+ return -ENOMEM;
+
+ wm8770->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8770);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8770, &wm8770_dai, 1);
+ if (ret < 0)
+ kfree(wm8770);
+ return ret;
+}
+
+static int __devexit wm8770_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8770_spi_driver = {
+ .driver = {
+ .name = "wm8770",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8770_spi_probe,
+ .remove = __devexit_p(wm8770_spi_remove)
+};
+#endif
+
+static int __init wm8770_modinit(void)
+{
+ int ret = 0;
+
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8770_spi_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+module_init(wm8770_modinit);
+
+static void __exit wm8770_exit(void)
+{
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8770_spi_driver);
+#endif
+}
+module_exit(wm8770_exit);
+
+MODULE_DESCRIPTION("ASoC WM8770 driver");
+MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h
new file mode 100644
index 000000000000..5f1b3bda6cc8
--- /dev/null
+++ b/sound/soc/codecs/wm8770.h
@@ -0,0 +1,51 @@
+/*
+ * wm8770.h -- WM8770 ASoC driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@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.
+ */
+
+#ifndef _WM8770_H
+#define _WM8770_H
+
+/* Registers */
+#define WM8770_VOUT1LVOL 0
+#define WM8770_VOUT1RVOL 0x1
+#define WM8770_VOUT2LVOL 0x2
+#define WM8770_VOUT2RVOL 0x3
+#define WM8770_VOUT3LVOL 0x4
+#define WM8770_VOUT3RVOL 0x5
+#define WM8770_VOUT4LVOL 0x6
+#define WM8770_VOUT4RVOL 0x7
+#define WM8770_MSALGVOL 0x8
+#define WM8770_DAC1LVOL 0x9
+#define WM8770_DAC1RVOL 0xa
+#define WM8770_DAC2LVOL 0xb
+#define WM8770_DAC2RVOL 0xc
+#define WM8770_DAC3LVOL 0xd
+#define WM8770_DAC3RVOL 0xe
+#define WM8770_DAC4LVOL 0xf
+#define WM8770_DAC4RVOL 0x10
+#define WM8770_MSDIGVOL 0x11
+#define WM8770_DACPHASE 0x12
+#define WM8770_DACCTRL1 0x13
+#define WM8770_DACMUTE 0x14
+#define WM8770_DACCTRL2 0x15
+#define WM8770_IFACECTRL 0x16
+#define WM8770_MSTRCTRL 0x17
+#define WM8770_PWDNCTRL 0x18
+#define WM8770_ADCLCTRL 0x19
+#define WM8770_ADCRCTRL 0x1a
+#define WM8770_ADCMUX 0x1b
+#define WM8770_OUTMUX1 0x1c
+#define WM8770_OUTMUX2 0x1d
+#define WM8770_RESET 0x31
+
+#define WM8770_CACHEREGNUM 0x20
+
+#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 0132a27140ae..8e7953b1b790 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -306,7 +305,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Disable the global powerdown; DAPM does the rest */
snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
}
@@ -317,7 +316,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -404,6 +403,7 @@ static int wm8776_resume(struct snd_soc_codec *codec)
static int wm8776_probe(struct snd_soc_codec *codec)
{
struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
@@ -427,9 +427,9 @@ static int wm8776_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8776_snd_controls,
ARRAY_SIZE(wm8776_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
ARRAY_SIZE(wm8776_dapm_widgets));
- snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
+ snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
return ret;
}
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 4599e8e95aa2..6dae1b40c9f7 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -515,7 +514,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
wm8804->supplies);
if (ret) {
@@ -537,7 +536,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -581,7 +580,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
wm8804 = snd_soc_codec_get_drvdata(codec);
wm8804->codec = codec;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
if (ret < 0) {
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index aca4b1ea10bb..cd0959926d12 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -30,7 +30,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -140,7 +139,6 @@
struct wm8900_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8900_MAXREG];
u32 fll_in; /* FLL input frequency */
u32 fll_out; /* FLL output frequency */
@@ -611,10 +609,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8900_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
- ARRAY_SIZE(wm8900_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets,
+ ARRAY_SIZE(wm8900_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1051,7 +1050,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
/* Charge capacitors if initial power up */
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* STARTUP_BIAS_ENA on */
snd_soc_write(codec, WM8900_REG_POWER1,
WM8900_REG_POWER1_STARTUP_BIAS_ENA);
@@ -1119,7 +1118,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
WM8900_REG_POWER2_SYSCLK_ENA);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 622b60238a82..987476a5895f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -29,9 +29,9 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/wm8903.h>
+#include <trace/events/asoc.h>
#include "wm8903.h"
@@ -214,15 +214,14 @@ static u16 wm8903_reg_defaults[] = {
struct wm8903_priv {
- u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
-
int sysclk;
int irq;
- /* Reference counts */
+ int fs;
+ int deemph;
+
+ /* Reference count */
int class_w_users;
- int playback_active;
- int capture_active;
struct completion wseq;
@@ -231,9 +230,6 @@ struct wm8903_priv {
int mic_short;
int mic_last_report;
int mic_delay;
-
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
};
static int wm8903_volatile_register(unsigned int reg)
@@ -463,6 +459,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
+static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
+
+static int wm8903_set_deemph(struct snd_soc_codec *codec)
+{
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+ int val, i, best;
+
+ /* If we're using deemphasis select the nearest available sample
+ * rate.
+ */
+ if (wm8903->deemph) {
+ best = 1;
+ for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
+ if (abs(wm8903_deemph[i] - wm8903->fs) <
+ abs(wm8903_deemph[best] - wm8903->fs))
+ best = i;
+ }
+
+ val = best << WM8903_DEEMPH_SHIFT;
+ } else {
+ best = 0;
+ val = 0;
+ }
+
+ dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+ best, wm8903_deemph[best]);
+
+ return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
+ WM8903_DEEMPH_MASK, val);
+}
+
+static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8903->deemph;
+
+ return 0;
+}
+
+static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+ int deemph = ucontrol->value.enumerated.item[0];
+ int ret = 0;
+
+ if (deemph > 1)
+ return -EINVAL;
+
+ mutex_lock(&codec->mutex);
+ if (wm8903->deemph != deemph) {
+ wm8903->deemph = deemph;
+
+ wm8903_set_deemph(codec);
+
+ ret = 1;
+ }
+ mutex_unlock(&codec->mutex);
+
+ return ret;
+}
+
/* ALSA can only do steps of .01dB */
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
@@ -475,6 +537,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
+static const char *hpf_mode_text[] = {
+ "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
+};
+
+static const struct soc_enum hpf_mode =
+ SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
+
+static const char *osr_text[] = {
+ "Low power", "High performance"
+};
+
+static const struct soc_enum adc_osr =
+ SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
+
+static const struct soc_enum dac_osr =
+ SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
+
static const char *drc_slope_text[] = {
"1", "1/2", "1/4", "1/8", "1/16", "0"
};
@@ -537,13 +616,6 @@ static const char *mute_mode_text[] = {
static const struct soc_enum mute_mode =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
-static const char *dac_deemphasis_text[] = {
- "Disabled", "32kHz", "44.1kHz", "48kHz"
-};
-
-static const struct soc_enum dac_deemphasis =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
-
static const char *companding_text[] = {
"ulaw", "alaw"
};
@@ -613,6 +685,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
6, 1, 0),
/* ADCs */
+SOC_ENUM("ADC OSR", adc_osr),
+SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
+SOC_ENUM("HPF Mode", hpf_mode),
SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
@@ -642,14 +717,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
12, 0, digital_sidetone_tlv),
/* DAC */
+SOC_ENUM("DAC OSR", dac_osr),
SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
SOC_ENUM("DAC Soft Mute Rate", soft_mute),
SOC_ENUM("DAC Mute Mode", mute_mode),
SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
-SOC_ENUM("DAC De-emphasis", dac_deemphasis),
SOC_ENUM("DAC Companding Mode", dac_companding),
SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
+SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
+ wm8903_get_deemph, wm8903_put_deemph),
/* Headphones */
SOC_DOUBLE_R("Headphone Switch",
@@ -923,10 +1000,11 @@ static const struct snd_soc_dapm_route intercon[] = {
static int wm8903_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
- ARRAY_SIZE(wm8903_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
+ ARRAY_SIZE(wm8903_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
return 0;
}
@@ -934,7 +1012,7 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
static int wm8903_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 reg, reg2;
+ u16 reg;
switch (level) {
case SND_SOC_BIAS_ON:
@@ -946,7 +1024,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
snd_soc_write(codec, WM8903_CLOCK_RATES_2,
WM8903_CLK_SYS_ENA);
@@ -958,23 +1036,15 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
wm8903_run_sequence(codec, 0);
wm8903_sync_reg_cache(codec, codec->reg_cache);
- /* Enable low impedence charge pump output */
- reg = snd_soc_read(codec,
- WM8903_CONTROL_INTERFACE_TEST_1);
- snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
- reg | WM8903_TEST_KEY);
- reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
- snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
- reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
- snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
- reg);
-
/* By default no bypass paths are enabled so
* enable Class W support.
*/
dev_dbg(codec->dev, "Enabling Class W\n");
- snd_soc_write(codec, WM8903_CLASS_W_0, reg |
- WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
+ snd_soc_update_bits(codec, WM8903_CLASS_W_0,
+ WM8903_CP_DYN_FREQ |
+ WM8903_CP_DYN_V,
+ WM8903_CP_DYN_FREQ |
+ WM8903_CP_DYN_V);
}
reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
@@ -991,7 +1061,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1222,58 +1292,6 @@ static struct {
{ 0, 0 },
};
-static int wm8903_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct snd_pcm_runtime *master_runtime;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- wm8903->playback_active++;
- else
- wm8903->capture_active++;
-
- /* The DAI has shared clocks so if we already have a playback or
- * capture going then constrain this substream to match it.
- */
- if (wm8903->master_substream) {
- master_runtime = wm8903->master_substream->runtime;
-
- dev_dbg(codec->dev, "Constraining to %d bits\n",
- master_runtime->sample_bits);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- master_runtime->sample_bits,
- master_runtime->sample_bits);
-
- wm8903->slave_substream = substream;
- } else
- wm8903->master_substream = substream;
-
- return 0;
-}
-
-static void wm8903_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- wm8903->playback_active--;
- else
- wm8903->capture_active--;
-
- if (wm8903->master_substream == substream)
- wm8903->master_substream = wm8903->slave_substream;
-
- wm8903->slave_substream = NULL;
-}
-
static int wm8903_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -1298,11 +1316,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
- if (substream == wm8903->slave_substream) {
- dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
- return 0;
- }
-
/* Enable sloping stopband filter for low sample rates */
if (fs <= 24000)
dac_digital1 |= WM8903_DAC_SB_FILT;
@@ -1320,19 +1333,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
}
}
- /* Constraints should stop us hitting this but let's make sure */
- if (wm8903->capture_active)
- switch (sample_rates[dsp_config].rate) {
- case 88200:
- case 96000:
- dev_err(codec->dev, "%dHz unsupported by ADC\n",
- fs);
- return -EINVAL;
-
- default:
- break;
- }
-
dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
clock1 &= ~WM8903_SAMPLE_RATE_MASK;
clock1 |= sample_rates[dsp_config].value;
@@ -1428,6 +1428,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
aif2 |= bclk_divs[bclk_div].div;
aif3 |= bclk / fs;
+ wm8903->fs = params_rate(params);
+ wm8903_set_deemph(codec);
+
snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
@@ -1521,6 +1524,11 @@ static irqreturn_t wm8903_irq(int irq, void *data)
mic_report = wm8903->mic_last_report;
int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
+#ifndef CONFIG_SND_SOC_WM8903_MODULE
+ if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
+ trace_snd_soc_jack_irq(dev_name(codec->dev));
+#endif
+
if (int_val & WM8903_MICSHRT_EINT) {
dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
@@ -1571,8 +1579,6 @@ static irqreturn_t wm8903_irq(int irq, void *data)
SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops wm8903_dai_ops = {
- .startup = wm8903_startup,
- .shutdown = wm8903_shutdown,
.hw_params = wm8903_hw_params,
.digital_mute = wm8903_digital_mute,
.set_fmt = wm8903_set_dai_fmt,
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index 996435e681e5..e8490f3edd03 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -19,10 +19,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack,
int det, int shrt);
-#define WM8903_MCLK_DIV_2 1
-#define WM8903_CLK_SYS 2
-#define WM8903_BCLK 3
-#define WM8903_LRCLK 4
/*
* Register values.
@@ -98,8 +94,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
#define WM8903_INTERRUPT_POLARITY_1 0x7B
#define WM8903_INTERRUPT_CONTROL 0x7E
-#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
-#define WM8903_CHARGE_PUMP_TEST_1 0x95
#define WM8903_CLOCK_RATE_TEST_4 0xA4
#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
@@ -1206,25 +1200,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
/*
- * R129 (0x81) - Control Interface Test 1
- */
-#define WM8903_USER_KEY 0x0002 /* USER_KEY */
-#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
-#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
-#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
-#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
-#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
-#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
-#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
-
-/*
- * R149 (0x95) - Charge Pump Test 1
- */
-#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
-#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
-#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
-
-/*
* R164 (0xA4) - Clock Rate Test 4
*/
#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index fca60a0b57b8..9de44a4c05c0 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8904.h>
@@ -50,8 +49,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
/* codec private data */
struct wm8904_priv {
- u16 reg_cache[WM8904_MAX_REGISTER + 1];
-
enum wm8904_type devtype;
void *control_data;
@@ -818,7 +815,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- return wm8904->deemph;
+ ucontrol->value.enumerated.item[0] = wm8904->deemph;
+ return 0;
}
static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -1428,10 +1426,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
static int wm8904_add_widgets(struct snd_soc_codec *codec)
{
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
ARRAY_SIZE(wm8904_core_dapm_widgets));
- snd_soc_dapm_add_routes(codec, core_intercon,
+ snd_soc_dapm_add_routes(dapm, core_intercon,
ARRAY_SIZE(core_intercon));
switch (wm8904->devtype) {
@@ -1443,20 +1442,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8904_snd_controls,
ARRAY_SIZE(wm8904_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
ARRAY_SIZE(wm8904_adc_dapm_widgets));
- snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
ARRAY_SIZE(wm8904_dac_dapm_widgets));
- snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
ARRAY_SIZE(wm8904_dapm_widgets));
- snd_soc_dapm_add_routes(codec, core_intercon,
+ snd_soc_dapm_add_routes(dapm, core_intercon,
ARRAY_SIZE(core_intercon));
- snd_soc_dapm_add_routes(codec, adc_intercon,
+ snd_soc_dapm_add_routes(dapm, adc_intercon,
ARRAY_SIZE(adc_intercon));
- snd_soc_dapm_add_routes(codec, dac_intercon,
+ snd_soc_dapm_add_routes(dapm, dac_intercon,
ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(codec, wm8904_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8904_intercon,
ARRAY_SIZE(wm8904_intercon));
break;
@@ -1464,17 +1463,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8904_dac_snd_controls,
ARRAY_SIZE(wm8904_dac_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
ARRAY_SIZE(wm8904_dac_dapm_widgets));
- snd_soc_dapm_add_routes(codec, dac_intercon,
+ snd_soc_dapm_add_routes(dapm, dac_intercon,
ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(codec, wm8912_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8912_intercon,
ARRAY_SIZE(wm8912_intercon));
break;
}
- snd_soc_dapm_new_widgets(codec);
+ snd_soc_dapm_new_widgets(dapm);
return 0;
}
@@ -1590,7 +1589,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
- wm8904->fs);
for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
cur_val = abs((wm8904->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8904->fs);;
+ clk_sys_rates[i].ratio) - wm8904->fs);
if (cur_val < best_val) {
best = i;
best_val = cur_val;
@@ -2093,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
static void wm8904_sync_cache(struct snd_soc_codec *codec)
{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -2104,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
/* Sync back cached values if they're different from the
* hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (!wm8904_access[i].writable)
continue;
- if (wm8904->reg_cache[i] == wm8904_reg[i])
+ if (reg_cache[i] == wm8904_reg[i])
continue;
- snd_soc_write(codec, i, wm8904->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -2139,7 +2138,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
wm8904->supplies);
if (ret != 0) {
@@ -2198,7 +2197,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
wm8904->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -2370,10 +2369,11 @@ static int wm8904_probe(struct snd_soc_codec *codec)
{
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
codec->cache_sync = 1;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
switch (wm8904->devtype) {
case WM8904:
@@ -2436,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
+ reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
WM8904_HPOUTLZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
WM8904_HPOUTRZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
WM8904_LINEOUTLZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
WM8904_LINEOUTRZC;
- wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
+ reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
/* Apply configuration from the platform data. */
if (wm8904->pdata) {
@@ -2456,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
if (!pdata->gpio_cfg[i])
continue;
- wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
+ reg_cache[WM8904_GPIO_CONTROL_1 + i]
= pdata->gpio_cfg[i] & 0xffff;
}
/* Zero is the default value for these anyway */
for (i = 0; i < WM8904_MIC_REGS; i++)
- wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
+ reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
= pdata->mic_cfg[i];
}
/* Set Class W by default - this will be managed by the Class
* G widget at runtime where bypass paths are available.
*/
- wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
+ reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
/* Use normal bias source */
- wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
+ reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 2cb16f895c46..25580e3ee7c4 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -35,7 +35,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -43,7 +42,6 @@
struct wm8940_priv {
unsigned int sysclk;
- u16 reg_cache[WM8940_CACHEREGNUM];
enum snd_soc_control_type control_type;
void *control_data;
};
@@ -291,13 +289,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8940_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
ARRAY_SIZE(wm8940_dapm_widgets));
if (ret)
goto error_ret;
- ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret)
goto error_ret;
@@ -735,7 +734,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
return ret;
return ret;
-;
}
static int wm8940_remove(struct snd_soc_codec *codec)
@@ -768,6 +766,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8940);
wm8940->control_data = i2c;
+ wm8940->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8940, &wm8940_dai, 1);
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index f89ad6c9a80b..7167dfc96aa7 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8955.h>
@@ -42,8 +41,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
struct wm8955_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8955_MAX_REGISTER + 1];
-
unsigned int mclk_rate;
int deemph;
@@ -380,7 +377,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- return wm8955->deemph;
+ ucontrol->value.enumerated.item[0] = wm8955->deemph;
+ return 0;
}
static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
@@ -577,13 +575,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
static int wm8955_add_widgets(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
snd_soc_add_controls(codec, wm8955_snd_controls,
ARRAY_SIZE(wm8955_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
ARRAY_SIZE(wm8955_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, wm8955_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8955_intercon,
ARRAY_SIZE(wm8955_intercon));
return 0;
@@ -767,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
switch (level) {
@@ -786,7 +786,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
wm8955->supplies);
if (ret != 0) {
@@ -799,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
/* Sync back cached values if they're
* different from the hardware default.
*/
- for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
if (i == WM8955_RESET)
continue;
- if (wm8955->reg_cache[i] == wm8955_reg[i])
+ if (reg_cache[i] == wm8955_reg[i])
continue;
- snd_soc_write(codec, i, wm8955->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
/* Enable VREF and VMID */
@@ -850,7 +850,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
wm8955->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -901,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec)
{
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
@@ -933,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
- wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
- wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
- wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
- wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
- wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
- wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
+ reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
+ reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
+ reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
+ reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
+ reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
+ reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
+ reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
/* Also enable adaptive bass boost by default */
- wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
+ reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
/* Set platform data values */
if (pdata) {
if (pdata->out2_speaker)
- wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
+ reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|= WM8955_ROUT2INV;
if (pdata->monoin_diff)
- wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
+ reg_cache[WM8955_MONO_OUT_MIX_1]
|= WM8955_DMEN;
}
@@ -1002,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8955);
+ wm8955->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8955, &wm8955_dai, 1);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8d5efb333c33..4393394b7bc1 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8960.h>
@@ -72,7 +71,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
};
struct wm8960_priv {
- u16 reg_cache[WM8960_CACHEREGNUM];
enum snd_soc_control_type control_type;
void *control_data;
int (*set_bias_level)(struct snd_soc_codec *,
@@ -138,7 +136,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- return wm8960->deemph;
+ ucontrol->value.enumerated.item[0] = wm8960->deemph;
+ return 0;
}
static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
@@ -388,27 +387,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
{
struct wm8960_data *pdata = codec->dev->platform_data;
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dapm_widget *w;
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
ARRAY_SIZE(wm8960_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
/* In capless mode OUT3 is used to provide VMID for the
* headphone outputs, otherwise it is used as a mono mixer.
*/
if (pdata && pdata->capless) {
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
ARRAY_SIZE(wm8960_dapm_widgets_capless));
- snd_soc_dapm_add_routes(codec, audio_paths_capless,
+ snd_soc_dapm_add_routes(dapm, audio_paths_capless,
ARRAY_SIZE(audio_paths_capless));
} else {
- snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3,
+ snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
ARRAY_SIZE(wm8960_dapm_widgets_out3));
- snd_soc_dapm_add_routes(codec, audio_paths_out3,
+ snd_soc_dapm_add_routes(dapm, audio_paths_out3,
ARRAY_SIZE(audio_paths_out3));
}
@@ -417,7 +417,9 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
* list each time to find the desired power state do so now
* and save the result.
*/
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &codec->card->widgets, list) {
+ if (w->dapm != &codec->dapm)
+ continue;
if (strcmp(w->name, "LOUT1 PGA") == 0)
wm8960->lout1 = w;
if (strcmp(w->name, "ROUT1 PGA") == 0)
@@ -572,7 +574,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable anti-pop features */
snd_soc_write(codec, WM8960_APOP1,
WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -610,7 +612,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -626,7 +628,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_PREPARE:
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
/* Enable anti pop mode */
snd_soc_update_bits(codec, WM8960_APOP1,
@@ -681,7 +683,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_PREPARE:
/* Disable HP discharge */
snd_soc_update_bits(codec, WM8960_APOP2,
@@ -705,7 +707,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1012,6 +1014,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8960);
+ wm8960->control_type = SND_SOC_I2C;
wm8960->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 8340485c9851..55252e7d02c9 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -290,7 +289,6 @@ static u16 wm8961_reg_defaults[] = {
struct wm8961_priv {
enum snd_soc_control_type control_type;
int sysclk;
- u16 reg_cache[WM8961_MAX_REGISTER];
};
static int wm8961_volatile_register(unsigned int reg)
@@ -882,7 +880,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_PREPARE:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
/* Enable bias generation */
reg = snd_soc_read(codec, WM8961_ANTI_POP);
reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
@@ -897,7 +895,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_PREPARE) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
/* VREF off */
reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
reg &= ~WM8961_VREF;
@@ -919,7 +917,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -959,6 +957,7 @@ static struct snd_soc_dai_driver wm8961_dai = {
static int wm8961_probe(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
u16 reg;
@@ -1024,9 +1023,9 @@ static int wm8961_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8961_snd_controls,
ARRAY_SIZE(wm8961_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
ARRAY_SIZE(wm8961_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return 0;
}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index e8092745a207..b9cb1fcf8c92 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -29,10 +29,10 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8962.h>
+#include <trace/events/asoc.h>
#include "wm8962.h"
@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
struct wm8962_priv {
struct snd_soc_codec *codec;
- u16 reg_cache[WM8962_MAX_REGISTER + 1];
-
int sysclk;
int sysclk_rate;
@@ -1958,7 +1956,7 @@ static int wm8962_readable_register(unsigned int reg)
static int wm8962_reset(struct snd_soc_codec *codec)
{
- return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0);
+ return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
}
static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int ret;
/* Apply the update (if any) */
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int ret;
/* Apply the update (if any) */
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int reg;
switch (w->shift) {
@@ -2682,6 +2677,7 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
static int wm8962_add_widgets(struct snd_soc_codec *codec)
{
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
snd_soc_add_controls(codec, wm8962_snd_controls,
ARRAY_SIZE(wm8962_snd_controls));
@@ -2693,33 +2689,33 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
ARRAY_SIZE(wm8962_spk_stereo_controls));
- snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
ARRAY_SIZE(wm8962_dapm_widgets));
if (pdata && pdata->spk_mono)
- snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
else
- snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets,
ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
- snd_soc_dapm_add_routes(codec, wm8962_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_intercon,
ARRAY_SIZE(wm8962_intercon));
if (pdata && pdata->spk_mono)
- snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
ARRAY_SIZE(wm8962_spk_mono_intercon));
else
- snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon,
+ snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon,
ARRAY_SIZE(wm8962_spk_stereo_intercon));
- snd_soc_dapm_disable_pin(codec, "Beep");
+ snd_soc_dapm_disable_pin(dapm, "Beep");
return 0;
}
static void wm8962_sync_cache(struct snd_soc_codec *codec)
{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -2732,13 +2728,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec)
/* Sync back cached values if they're different from the
* hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (i == WM8962_SOFTWARE_RESET)
continue;
- if (wm8962->reg_cache[i] == wm8962_reg[i])
+ if (reg_cache[i] == wm8962_reg[i])
continue;
- snd_soc_write(codec, i, wm8962->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -2819,7 +2815,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
int ret;
- if (level == codec->bias_level)
+ if (level == codec->dapm.bias_level)
return 0;
switch (level) {
@@ -2833,7 +2829,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
if (ret != 0) {
@@ -2883,7 +2879,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
wm8962->supplies);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -3339,7 +3335,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
int mask;
int active;
- mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+ mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
active &= ~mask;
@@ -3353,6 +3349,12 @@ static irqreturn_t wm8962_irq(int irq, void *data)
if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
dev_dbg(codec->dev, "Microphone event detected\n");
+#ifndef CONFIG_SND_SOC_WM8962_MODULE
+ trace_snd_soc_jack_irq(dev_name(codec->dev));
+#endif
+
+ pm_wakeup_event(codec->dev, 300);
+
schedule_delayed_work(&wm8962->mic_work,
msecs_to_jiffies(250));
}
@@ -3406,12 +3408,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect);
#ifdef CONFIG_PM
static int wm8962_resume(struct snd_soc_codec *codec)
{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
u16 *reg_cache = codec->reg_cache;
int i;
/* Restore the registers */
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
switch (i) {
case WM8962_SOFTWARE_RESET:
continue;
@@ -3439,6 +3440,7 @@ static void wm8962_beep_work(struct work_struct *work)
struct wm8962_priv *wm8962 =
container_of(work, struct wm8962_priv, beep_work);
struct snd_soc_codec *codec = wm8962->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
int reg = 0;
int best = 0;
@@ -3455,16 +3457,16 @@ static void wm8962_beep_work(struct work_struct *work)
reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
- snd_soc_dapm_enable_pin(codec, "Beep");
+ snd_soc_dapm_enable_pin(dapm, "Beep");
} else {
dev_dbg(codec->dev, "Disabling beep\n");
- snd_soc_dapm_disable_pin(codec, "Beep");
+ snd_soc_dapm_disable_pin(dapm, "Beep");
}
snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
/* For usability define a way of injecting beep events for the device -
@@ -3705,13 +3707,14 @@ static int wm8962_probe(struct snd_soc_codec *codec)
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
dev);
+ u16 *reg_cache = codec->reg_cache;
int i, trigger, irq_pol;
wm8962->codec = codec;
INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
codec->cache_sync = 1;
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
if (ret != 0) {
@@ -3804,7 +3807,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
/* Put the speakers into mono mode? */
if (pdata->spk_mono)
- wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2]
+ reg_cache[WM8962_CLASS_D_CONTROL_2]
|= WM8962_SPK_MONO;
/* Micbias setup, detection enable and detection
@@ -3819,16 +3822,16 @@ static int wm8962_probe(struct snd_soc_codec *codec)
}
/* Latch volume update bits */
- wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
- wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
- wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
- wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
- wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
- wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
- wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
- wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
- wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
- wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
+ reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
+ reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
+ reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
+ reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
+ reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
+ reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
+ reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
+ reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
+ reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
+ reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
wm8962_add_widgets(codec);
@@ -3870,7 +3873,6 @@ err_enable:
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
err:
- kfree(wm8962);
return ret;
}
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 63f6dbf5d070..572bb80627a4 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -25,7 +25,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8971.h"
@@ -333,10 +332,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8971_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets,
- ARRAY_SIZE(wm8971_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
+ ARRAY_SIZE(wm8971_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -553,7 +553,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8971_PWR1, 0x0001);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -590,9 +590,11 @@ static struct snd_soc_dai_driver wm8971_dai = {
static void wm8971_work(struct work_struct *work)
{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
- wm8971_set_bias_level(codec, codec->bias_level);
+ struct snd_soc_dapm_context *dapm =
+ container_of(work, struct snd_soc_dapm_context,
+ delayed_work.work);
+ struct snd_soc_codec *codec = dapm->codec;
+ wm8971_set_bias_level(codec, codec->dapm.bias_level);
}
static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -620,11 +622,11 @@ static int wm8971_resume(struct snd_soc_codec *codec)
wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* charge wm8971 caps */
- if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
+ if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->bias_level = SND_SOC_BIAS_ON;
- queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_ON;
+ queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
msecs_to_jiffies(1000));
}
@@ -643,7 +645,7 @@ static int wm8971_probe(struct snd_soc_codec *codec)
return ret;
}
- INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
+ INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
wm8971_workq = create_workqueue("wm8971");
if (wm8971_workq == NULL)
return -ENOMEM;
@@ -653,8 +655,8 @@ static int wm8971_probe(struct snd_soc_codec *codec)
/* charge output caps - set vmid to 5k for quick power up */
reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->bias_level = SND_SOC_BIAS_STANDBY;
- queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
+ queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
msecs_to_jiffies(1000));
/* set the update bits */
@@ -718,6 +720,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
if (wm8971 == NULL)
return -ENOMEM;
+ wm8971->control_type = SND_SOC_I2C;
i2c_set_clientdata(i2c, wm8971);
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index b4363f6d19b3..ca646a822444 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -52,7 +51,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
struct wm8974_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8974_CACHEREGNUM];
};
#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
@@ -274,10 +272,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8974_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets,
- ARRAY_SIZE(wm8974_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
+ ARRAY_SIZE(wm8974_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -530,7 +529,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
mdelay(100);
@@ -547,7 +546,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 13b979a71a7c..4bbc3442703f 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -60,7 +59,6 @@ struct wm8978_priv {
unsigned int f_opclk;
int mclk_idx;
enum wm8978_sysclk_src sysclk;
- u16 reg_cache[WM8978_CACHEREGNUM];
};
static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
@@ -355,11 +353,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8978_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
- ARRAY_SIZE(wm8978_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
+ ARRAY_SIZE(wm8978_dapm_widgets));
/* set up the WM8978 audio map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -837,7 +836,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
/* bit 3: enable bias, bit 2: enable I/O tie off buffer */
power1 |= 0xc;
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
power1 | 0x3);
@@ -857,7 +856,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index fd2e7cca1228..bae510acdec8 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -533,10 +532,11 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
static int wm8985_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets,
- ARRAY_SIZE(wm8985_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map,
+ snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
+ ARRAY_SIZE(wm8985_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map,
ARRAY_SIZE(audio_map));
return 0;
}
@@ -879,7 +879,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
1 << WM8985_VMIDSEL_SHIFT);
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
wm8985->supplies);
if (ret) {
@@ -939,7 +939,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index d7f259711970..d7170f1381aa 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -25,7 +25,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "wm8988.h"
@@ -54,7 +53,6 @@ struct wm8988_priv {
unsigned int sysclk;
enum snd_soc_control_type control_type;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
- u16 reg_cache[WM8988_NUM_REG];
};
@@ -677,7 +675,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* VREF, VMID=2x5k */
snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -693,7 +691,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8988_PWR1, 0x0000);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -759,6 +757,7 @@ static int wm8988_resume(struct snd_soc_codec *codec)
static int wm8988_probe(struct snd_soc_codec *codec)
{
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
u16 reg;
@@ -790,9 +789,9 @@ static int wm8988_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm8988_snd_controls,
ARRAY_SIZE(wm8988_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
ARRAY_SIZE(wm8988_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 264828e4e67c..5c87a634fc04 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
@@ -914,11 +913,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm8990_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets,
- ARRAY_SIZE(wm8990_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
+ ARRAY_SIZE(wm8990_dapm_widgets));
/* set up the WM8990 audio map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1170,7 +1170,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable all output discharge bits */
snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1266,7 +1266,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 589e3fa24734..18c0d9ce7c32 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -24,7 +24,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/wm8993.h>
@@ -226,7 +225,6 @@ static struct {
struct wm8993_priv {
struct wm_hubs_data hubs_data;
- u16 reg_cache[WM8993_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
struct wm8993_platform_data pdata;
enum snd_soc_control_type control_type;
@@ -735,6 +733,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
0);
}
wm8993->class_w_users++;
+ wm8993->hubs_data.class_w = true;
}
/* Implement the change */
@@ -751,6 +750,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
WM8993_CP_DYN_V);
}
wm8993->class_w_users--;
+ wm8993->hubs_data.class_w = false;
}
dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
@@ -968,7 +968,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
wm8993->supplies);
if (ret != 0)
@@ -1029,6 +1029,12 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
0);
+ snd_soc_update_bits(codec, WM8993_ANTIPOP2,
+ WM8993_STARTUP_BIAS_ENA |
+ WM8993_VMID_BUF_ENA |
+ WM8993_VMID_RAMP_MASK |
+ WM8993_BIAS_SRC, 0);
+
#ifdef CONFIG_REGULATOR
/* Post 2.6.34 we will be able to get a callback when
* the regulators are disabled which we can use but
@@ -1043,7 +1049,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1225,7 +1231,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
- wm8993->fs);
for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
cur_val = abs((wm8993->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8993->fs);;
+ clk_sys_rates[i].ratio) - wm8993->fs);
if (cur_val < best_val) {
best = i;
best_val = cur_val;
@@ -1422,6 +1428,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
static int wm8993_probe(struct snd_soc_codec *codec)
{
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i, val;
wm8993->hubs_data.hp_startup_mode = 1;
@@ -1503,11 +1510,11 @@ static int wm8993_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(wm8993_eq_controls));
}
- snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
ARRAY_SIZE(wm8993_dapm_widgets));
wm_hubs_add_analogue_controls(codec);
- snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
+ snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
wm8993->pdata.lineout2_diff);
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
new file mode 100644
index 000000000000..68e9b024dd48
--- /dev/null
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -0,0 +1,3147 @@
+#include "wm8994.h"
+
+const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
+ { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
+ { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
+ { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
+ { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
+ { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
+ { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
+ { 0x003F, 0x003F }, /* R6 - Power Management (6) */
+ { 0x0000, 0x0000 }, /* R7 */
+ { 0x0000, 0x0000 }, /* R8 */
+ { 0x0000, 0x0000 }, /* R9 */
+ { 0x0000, 0x0000 }, /* R10 */
+ { 0x0000, 0x0000 }, /* R11 */
+ { 0x0000, 0x0000 }, /* R12 */
+ { 0x0000, 0x0000 }, /* R13 */
+ { 0x0000, 0x0000 }, /* R14 */
+ { 0x0000, 0x0000 }, /* R15 */
+ { 0x0000, 0x0000 }, /* R16 */
+ { 0x0000, 0x0000 }, /* R17 */
+ { 0x0000, 0x0000 }, /* R18 */
+ { 0x0000, 0x0000 }, /* R19 */
+ { 0x0000, 0x0000 }, /* R20 */
+ { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
+ { 0x0000, 0x0000 }, /* R22 */
+ { 0x0000, 0x0000 }, /* R23 */
+ { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
+ { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
+ { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
+ { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
+ { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
+ { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
+ { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
+ { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
+ { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
+ { 0x003F, 0x003F }, /* R37 - ClassD */
+ { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
+ { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
+ { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
+ { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
+ { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
+ { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
+ { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
+ { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
+ { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
+ { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
+ { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
+ { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
+ { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
+ { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
+ { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
+ { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
+ { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
+ { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
+ { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
+ { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
+ { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
+ { 0x000F, 0x000F }, /* R59 - LDO 1 */
+ { 0x0007, 0x0007 }, /* R60 - LDO 2 */
+ { 0x0000, 0x0000 }, /* R61 */
+ { 0x0000, 0x0000 }, /* R62 */
+ { 0x0000, 0x0000 }, /* R63 */
+ { 0x0000, 0x0000 }, /* R64 */
+ { 0x0000, 0x0000 }, /* R65 */
+ { 0x0000, 0x0000 }, /* R66 */
+ { 0x0000, 0x0000 }, /* R67 */
+ { 0x0000, 0x0000 }, /* R68 */
+ { 0x0000, 0x0000 }, /* R69 */
+ { 0x0000, 0x0000 }, /* R70 */
+ { 0x0000, 0x0000 }, /* R71 */
+ { 0x0000, 0x0000 }, /* R72 */
+ { 0x0000, 0x0000 }, /* R73 */
+ { 0x0000, 0x0000 }, /* R74 */
+ { 0x0000, 0x0000 }, /* R75 */
+ { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
+ { 0x0000, 0x0000 }, /* R77 */
+ { 0x0000, 0x0000 }, /* R78 */
+ { 0x0000, 0x0000 }, /* R79 */
+ { 0x0000, 0x0000 }, /* R80 */
+ { 0x0301, 0x0301 }, /* R81 - Class W (1) */
+ { 0x0000, 0x0000 }, /* R82 */
+ { 0x0000, 0x0000 }, /* R83 */
+ { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
+ { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
+ { 0x0000, 0x0000 }, /* R86 */
+ { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
+ { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
+ { 0x0000, 0x0000 }, /* R89 */
+ { 0x0000, 0x0000 }, /* R90 */
+ { 0x0000, 0x0000 }, /* R91 */
+ { 0x0000, 0x0000 }, /* R92 */
+ { 0x0000, 0x0000 }, /* R93 */
+ { 0x0000, 0x0000 }, /* R94 */
+ { 0x0000, 0x0000 }, /* R95 */
+ { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
+ { 0x0000, 0x0000 }, /* R97 */
+ { 0x0000, 0x0000 }, /* R98 */
+ { 0x0000, 0x0000 }, /* R99 */
+ { 0x0000, 0x0000 }, /* R100 */
+ { 0x0000, 0x0000 }, /* R101 */
+ { 0x0000, 0x0000 }, /* R102 */
+ { 0x0000, 0x0000 }, /* R103 */
+ { 0x0000, 0x0000 }, /* R104 */
+ { 0x0000, 0x0000 }, /* R105 */
+ { 0x0000, 0x0000 }, /* R106 */
+ { 0x0000, 0x0000 }, /* R107 */
+ { 0x0000, 0x0000 }, /* R108 */
+ { 0x0000, 0x0000 }, /* R109 */
+ { 0x0000, 0x0000 }, /* R110 */
+ { 0x0000, 0x0000 }, /* R111 */
+ { 0x0000, 0x0000 }, /* R112 */
+ { 0x0000, 0x0000 }, /* R113 */
+ { 0x0000, 0x0000 }, /* R114 */
+ { 0x0000, 0x0000 }, /* R115 */
+ { 0x0000, 0x0000 }, /* R116 */
+ { 0x0000, 0x0000 }, /* R117 */
+ { 0x0000, 0x0000 }, /* R118 */
+ { 0x0000, 0x0000 }, /* R119 */
+ { 0x0000, 0x0000 }, /* R120 */
+ { 0x0000, 0x0000 }, /* R121 */
+ { 0x0000, 0x0000 }, /* R122 */
+ { 0x0000, 0x0000 }, /* R123 */
+ { 0x0000, 0x0000 }, /* R124 */
+ { 0x0000, 0x0000 }, /* R125 */
+ { 0x0000, 0x0000 }, /* R126 */
+ { 0x0000, 0x0000 }, /* R127 */
+ { 0x0000, 0x0000 }, /* R128 */
+ { 0x0000, 0x0000 }, /* R129 */
+ { 0x0000, 0x0000 }, /* R130 */
+ { 0x0000, 0x0000 }, /* R131 */
+ { 0x0000, 0x0000 }, /* R132 */
+ { 0x0000, 0x0000 }, /* R133 */
+ { 0x0000, 0x0000 }, /* R134 */
+ { 0x0000, 0x0000 }, /* R135 */
+ { 0x0000, 0x0000 }, /* R136 */
+ { 0x0000, 0x0000 }, /* R137 */
+ { 0x0000, 0x0000 }, /* R138 */
+ { 0x0000, 0x0000 }, /* R139 */
+ { 0x0000, 0x0000 }, /* R140 */
+ { 0x0000, 0x0000 }, /* R141 */
+ { 0x0000, 0x0000 }, /* R142 */
+ { 0x0000, 0x0000 }, /* R143 */
+ { 0x0000, 0x0000 }, /* R144 */
+ { 0x0000, 0x0000 }, /* R145 */
+ { 0x0000, 0x0000 }, /* R146 */
+ { 0x0000, 0x0000 }, /* R147 */
+ { 0x0000, 0x0000 }, /* R148 */
+ { 0x0000, 0x0000 }, /* R149 */
+ { 0x0000, 0x0000 }, /* R150 */
+ { 0x0000, 0x0000 }, /* R151 */
+ { 0x0000, 0x0000 }, /* R152 */
+ { 0x0000, 0x0000 }, /* R153 */
+ { 0x0000, 0x0000 }, /* R154 */
+ { 0x0000, 0x0000 }, /* R155 */
+ { 0x0000, 0x0000 }, /* R156 */
+ { 0x0000, 0x0000 }, /* R157 */
+ { 0x0000, 0x0000 }, /* R158 */
+ { 0x0000, 0x0000 }, /* R159 */
+ { 0x0000, 0x0000 }, /* R160 */
+ { 0x0000, 0x0000 }, /* R161 */
+ { 0x0000, 0x0000 }, /* R162 */
+ { 0x0000, 0x0000 }, /* R163 */
+ { 0x0000, 0x0000 }, /* R164 */
+ { 0x0000, 0x0000 }, /* R165 */
+ { 0x0000, 0x0000 }, /* R166 */
+ { 0x0000, 0x0000 }, /* R167 */
+ { 0x0000, 0x0000 }, /* R168 */
+ { 0x0000, 0x0000 }, /* R169 */
+ { 0x0000, 0x0000 }, /* R170 */
+ { 0x0000, 0x0000 }, /* R171 */
+ { 0x0000, 0x0000 }, /* R172 */
+ { 0x0000, 0x0000 }, /* R173 */
+ { 0x0000, 0x0000 }, /* R174 */
+ { 0x0000, 0x0000 }, /* R175 */
+ { 0x0000, 0x0000 }, /* R176 */
+ { 0x0000, 0x0000 }, /* R177 */
+ { 0x0000, 0x0000 }, /* R178 */
+ { 0x0000, 0x0000 }, /* R179 */
+ { 0x0000, 0x0000 }, /* R180 */
+ { 0x0000, 0x0000 }, /* R181 */
+ { 0x0000, 0x0000 }, /* R182 */
+ { 0x0000, 0x0000 }, /* R183 */
+ { 0x0000, 0x0000 }, /* R184 */
+ { 0x0000, 0x0000 }, /* R185 */
+ { 0x0000, 0x0000 }, /* R186 */
+ { 0x0000, 0x0000 }, /* R187 */
+ { 0x0000, 0x0000 }, /* R188 */
+ { 0x0000, 0x0000 }, /* R189 */
+ { 0x0000, 0x0000 }, /* R190 */
+ { 0x0000, 0x0000 }, /* R191 */
+ { 0x0000, 0x0000 }, /* R192 */
+ { 0x0000, 0x0000 }, /* R193 */
+ { 0x0000, 0x0000 }, /* R194 */
+ { 0x0000, 0x0000 }, /* R195 */
+ { 0x0000, 0x0000 }, /* R196 */
+ { 0x0000, 0x0000 }, /* R197 */
+ { 0x0000, 0x0000 }, /* R198 */
+ { 0x0000, 0x0000 }, /* R199 */
+ { 0x0000, 0x0000 }, /* R200 */
+ { 0x0000, 0x0000 }, /* R201 */
+ { 0x0000, 0x0000 }, /* R202 */
+ { 0x0000, 0x0000 }, /* R203 */
+ { 0x0000, 0x0000 }, /* R204 */
+ { 0x0000, 0x0000 }, /* R205 */
+ { 0x0000, 0x0000 }, /* R206 */
+ { 0x0000, 0x0000 }, /* R207 */
+ { 0x0000, 0x0000 }, /* R208 */
+ { 0x0000, 0x0000 }, /* R209 */
+ { 0x0000, 0x0000 }, /* R210 */
+ { 0x0000, 0x0000 }, /* R211 */
+ { 0x0000, 0x0000 }, /* R212 */
+ { 0x0000, 0x0000 }, /* R213 */
+ { 0x0000, 0x0000 }, /* R214 */
+ { 0x0000, 0x0000 }, /* R215 */
+ { 0x0000, 0x0000 }, /* R216 */
+ { 0x0000, 0x0000 }, /* R217 */
+ { 0x0000, 0x0000 }, /* R218 */
+ { 0x0000, 0x0000 }, /* R219 */
+ { 0x0000, 0x0000 }, /* R220 */
+ { 0x0000, 0x0000 }, /* R221 */
+ { 0x0000, 0x0000 }, /* R222 */
+ { 0x0000, 0x0000 }, /* R223 */
+ { 0x0000, 0x0000 }, /* R224 */
+ { 0x0000, 0x0000 }, /* R225 */
+ { 0x0000, 0x0000 }, /* R226 */
+ { 0x0000, 0x0000 }, /* R227 */
+ { 0x0000, 0x0000 }, /* R228 */
+ { 0x0000, 0x0000 }, /* R229 */
+ { 0x0000, 0x0000 }, /* R230 */
+ { 0x0000, 0x0000 }, /* R231 */
+ { 0x0000, 0x0000 }, /* R232 */
+ { 0x0000, 0x0000 }, /* R233 */
+ { 0x0000, 0x0000 }, /* R234 */
+ { 0x0000, 0x0000 }, /* R235 */
+ { 0x0000, 0x0000 }, /* R236 */
+ { 0x0000, 0x0000 }, /* R237 */
+ { 0x0000, 0x0000 }, /* R238 */
+ { 0x0000, 0x0000 }, /* R239 */
+ { 0x0000, 0x0000 }, /* R240 */
+ { 0x0000, 0x0000 }, /* R241 */
+ { 0x0000, 0x0000 }, /* R242 */
+ { 0x0000, 0x0000 }, /* R243 */
+ { 0x0000, 0x0000 }, /* R244 */
+ { 0x0000, 0x0000 }, /* R245 */
+ { 0x0000, 0x0000 }, /* R246 */
+ { 0x0000, 0x0000 }, /* R247 */
+ { 0x0000, 0x0000 }, /* R248 */
+ { 0x0000, 0x0000 }, /* R249 */
+ { 0x0000, 0x0000 }, /* R250 */
+ { 0x0000, 0x0000 }, /* R251 */
+ { 0x0000, 0x0000 }, /* R252 */
+ { 0x0000, 0x0000 }, /* R253 */
+ { 0x0000, 0x0000 }, /* R254 */
+ { 0x0000, 0x0000 }, /* R255 */
+ { 0x000F, 0x0000 }, /* R256 - Chip Revision */
+ { 0x0074, 0x0074 }, /* R257 - Control Interface */
+ { 0x0000, 0x0000 }, /* R258 */
+ { 0x0000, 0x0000 }, /* R259 */
+ { 0x0000, 0x0000 }, /* R260 */
+ { 0x0000, 0x0000 }, /* R261 */
+ { 0x0000, 0x0000 }, /* R262 */
+ { 0x0000, 0x0000 }, /* R263 */
+ { 0x0000, 0x0000 }, /* R264 */
+ { 0x0000, 0x0000 }, /* R265 */
+ { 0x0000, 0x0000 }, /* R266 */
+ { 0x0000, 0x0000 }, /* R267 */
+ { 0x0000, 0x0000 }, /* R268 */
+ { 0x0000, 0x0000 }, /* R269 */
+ { 0x0000, 0x0000 }, /* R270 */
+ { 0x0000, 0x0000 }, /* R271 */
+ { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
+ { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
+ { 0x0000, 0x0000 }, /* R274 */
+ { 0x0000, 0x0000 }, /* R275 */
+ { 0x0000, 0x0000 }, /* R276 */
+ { 0x0000, 0x0000 }, /* R277 */
+ { 0x0000, 0x0000 }, /* R278 */
+ { 0x0000, 0x0000 }, /* R279 */
+ { 0x0000, 0x0000 }, /* R280 */
+ { 0x0000, 0x0000 }, /* R281 */
+ { 0x0000, 0x0000 }, /* R282 */
+ { 0x0000, 0x0000 }, /* R283 */
+ { 0x0000, 0x0000 }, /* R284 */
+ { 0x0000, 0x0000 }, /* R285 */
+ { 0x0000, 0x0000 }, /* R286 */
+ { 0x0000, 0x0000 }, /* R287 */
+ { 0x0000, 0x0000 }, /* R288 */
+ { 0x0000, 0x0000 }, /* R289 */
+ { 0x0000, 0x0000 }, /* R290 */
+ { 0x0000, 0x0000 }, /* R291 */
+ { 0x0000, 0x0000 }, /* R292 */
+ { 0x0000, 0x0000 }, /* R293 */
+ { 0x0000, 0x0000 }, /* R294 */
+ { 0x0000, 0x0000 }, /* R295 */
+ { 0x0000, 0x0000 }, /* R296 */
+ { 0x0000, 0x0000 }, /* R297 */
+ { 0x0000, 0x0000 }, /* R298 */
+ { 0x0000, 0x0000 }, /* R299 */
+ { 0x0000, 0x0000 }, /* R300 */
+ { 0x0000, 0x0000 }, /* R301 */
+ { 0x0000, 0x0000 }, /* R302 */
+ { 0x0000, 0x0000 }, /* R303 */
+ { 0x0000, 0x0000 }, /* R304 */
+ { 0x0000, 0x0000 }, /* R305 */
+ { 0x0000, 0x0000 }, /* R306 */
+ { 0x0000, 0x0000 }, /* R307 */
+ { 0x0000, 0x0000 }, /* R308 */
+ { 0x0000, 0x0000 }, /* R309 */
+ { 0x0000, 0x0000 }, /* R310 */
+ { 0x0000, 0x0000 }, /* R311 */
+ { 0x0000, 0x0000 }, /* R312 */
+ { 0x0000, 0x0000 }, /* R313 */
+ { 0x0000, 0x0000 }, /* R314 */
+ { 0x0000, 0x0000 }, /* R315 */
+ { 0x0000, 0x0000 }, /* R316 */
+ { 0x0000, 0x0000 }, /* R317 */
+ { 0x0000, 0x0000 }, /* R318 */
+ { 0x0000, 0x0000 }, /* R319 */
+ { 0x0000, 0x0000 }, /* R320 */
+ { 0x0000, 0x0000 }, /* R321 */
+ { 0x0000, 0x0000 }, /* R322 */
+ { 0x0000, 0x0000 }, /* R323 */
+ { 0x0000, 0x0000 }, /* R324 */
+ { 0x0000, 0x0000 }, /* R325 */
+ { 0x0000, 0x0000 }, /* R326 */
+ { 0x0000, 0x0000 }, /* R327 */
+ { 0x0000, 0x0000 }, /* R328 */
+ { 0x0000, 0x0000 }, /* R329 */
+ { 0x0000, 0x0000 }, /* R330 */
+ { 0x0000, 0x0000 }, /* R331 */
+ { 0x0000, 0x0000 }, /* R332 */
+ { 0x0000, 0x0000 }, /* R333 */
+ { 0x0000, 0x0000 }, /* R334 */
+ { 0x0000, 0x0000 }, /* R335 */
+ { 0x0000, 0x0000 }, /* R336 */
+ { 0x0000, 0x0000 }, /* R337 */
+ { 0x0000, 0x0000 }, /* R338 */
+ { 0x0000, 0x0000 }, /* R339 */
+ { 0x0000, 0x0000 }, /* R340 */
+ { 0x0000, 0x0000 }, /* R341 */
+ { 0x0000, 0x0000 }, /* R342 */
+ { 0x0000, 0x0000 }, /* R343 */
+ { 0x0000, 0x0000 }, /* R344 */
+ { 0x0000, 0x0000 }, /* R345 */
+ { 0x0000, 0x0000 }, /* R346 */
+ { 0x0000, 0x0000 }, /* R347 */
+ { 0x0000, 0x0000 }, /* R348 */
+ { 0x0000, 0x0000 }, /* R349 */
+ { 0x0000, 0x0000 }, /* R350 */
+ { 0x0000, 0x0000 }, /* R351 */
+ { 0x0000, 0x0000 }, /* R352 */
+ { 0x0000, 0x0000 }, /* R353 */
+ { 0x0000, 0x0000 }, /* R354 */
+ { 0x0000, 0x0000 }, /* R355 */
+ { 0x0000, 0x0000 }, /* R356 */
+ { 0x0000, 0x0000 }, /* R357 */
+ { 0x0000, 0x0000 }, /* R358 */
+ { 0x0000, 0x0000 }, /* R359 */
+ { 0x0000, 0x0000 }, /* R360 */
+ { 0x0000, 0x0000 }, /* R361 */
+ { 0x0000, 0x0000 }, /* R362 */
+ { 0x0000, 0x0000 }, /* R363 */
+ { 0x0000, 0x0000 }, /* R364 */
+ { 0x0000, 0x0000 }, /* R365 */
+ { 0x0000, 0x0000 }, /* R366 */
+ { 0x0000, 0x0000 }, /* R367 */
+ { 0x0000, 0x0000 }, /* R368 */
+ { 0x0000, 0x0000 }, /* R369 */
+ { 0x0000, 0x0000 }, /* R370 */
+ { 0x0000, 0x0000 }, /* R371 */
+ { 0x0000, 0x0000 }, /* R372 */
+ { 0x0000, 0x0000 }, /* R373 */
+ { 0x0000, 0x0000 }, /* R374 */
+ { 0x0000, 0x0000 }, /* R375 */
+ { 0x0000, 0x0000 }, /* R376 */
+ { 0x0000, 0x0000 }, /* R377 */
+ { 0x0000, 0x0000 }, /* R378 */
+ { 0x0000, 0x0000 }, /* R379 */
+ { 0x0000, 0x0000 }, /* R380 */
+ { 0x0000, 0x0000 }, /* R381 */
+ { 0x0000, 0x0000 }, /* R382 */
+ { 0x0000, 0x0000 }, /* R383 */
+ { 0x0000, 0x0000 }, /* R384 */
+ { 0x0000, 0x0000 }, /* R385 */
+ { 0x0000, 0x0000 }, /* R386 */
+ { 0x0000, 0x0000 }, /* R387 */
+ { 0x0000, 0x0000 }, /* R388 */
+ { 0x0000, 0x0000 }, /* R389 */
+ { 0x0000, 0x0000 }, /* R390 */
+ { 0x0000, 0x0000 }, /* R391 */
+ { 0x0000, 0x0000 }, /* R392 */
+ { 0x0000, 0x0000 }, /* R393 */
+ { 0x0000, 0x0000 }, /* R394 */
+ { 0x0000, 0x0000 }, /* R395 */
+ { 0x0000, 0x0000 }, /* R396 */
+ { 0x0000, 0x0000 }, /* R397 */
+ { 0x0000, 0x0000 }, /* R398 */
+ { 0x0000, 0x0000 }, /* R399 */
+ { 0x0000, 0x0000 }, /* R400 */
+ { 0x0000, 0x0000 }, /* R401 */
+ { 0x0000, 0x0000 }, /* R402 */
+ { 0x0000, 0x0000 }, /* R403 */
+ { 0x0000, 0x0000 }, /* R404 */
+ { 0x0000, 0x0000 }, /* R405 */
+ { 0x0000, 0x0000 }, /* R406 */
+ { 0x0000, 0x0000 }, /* R407 */
+ { 0x0000, 0x0000 }, /* R408 */
+ { 0x0000, 0x0000 }, /* R409 */
+ { 0x0000, 0x0000 }, /* R410 */
+ { 0x0000, 0x0000 }, /* R411 */
+ { 0x0000, 0x0000 }, /* R412 */
+ { 0x0000, 0x0000 }, /* R413 */
+ { 0x0000, 0x0000 }, /* R414 */
+ { 0x0000, 0x0000 }, /* R415 */
+ { 0x0000, 0x0000 }, /* R416 */
+ { 0x0000, 0x0000 }, /* R417 */
+ { 0x0000, 0x0000 }, /* R418 */
+ { 0x0000, 0x0000 }, /* R419 */
+ { 0x0000, 0x0000 }, /* R420 */
+ { 0x0000, 0x0000 }, /* R421 */
+ { 0x0000, 0x0000 }, /* R422 */
+ { 0x0000, 0x0000 }, /* R423 */
+ { 0x0000, 0x0000 }, /* R424 */
+ { 0x0000, 0x0000 }, /* R425 */
+ { 0x0000, 0x0000 }, /* R426 */
+ { 0x0000, 0x0000 }, /* R427 */
+ { 0x0000, 0x0000 }, /* R428 */
+ { 0x0000, 0x0000 }, /* R429 */
+ { 0x0000, 0x0000 }, /* R430 */
+ { 0x0000, 0x0000 }, /* R431 */
+ { 0x0000, 0x0000 }, /* R432 */
+ { 0x0000, 0x0000 }, /* R433 */
+ { 0x0000, 0x0000 }, /* R434 */
+ { 0x0000, 0x0000 }, /* R435 */
+ { 0x0000, 0x0000 }, /* R436 */
+ { 0x0000, 0x0000 }, /* R437 */
+ { 0x0000, 0x0000 }, /* R438 */
+ { 0x0000, 0x0000 }, /* R439 */
+ { 0x0000, 0x0000 }, /* R440 */
+ { 0x0000, 0x0000 }, /* R441 */
+ { 0x0000, 0x0000 }, /* R442 */
+ { 0x0000, 0x0000 }, /* R443 */
+ { 0x0000, 0x0000 }, /* R444 */
+ { 0x0000, 0x0000 }, /* R445 */
+ { 0x0000, 0x0000 }, /* R446 */
+ { 0x0000, 0x0000 }, /* R447 */
+ { 0x0000, 0x0000 }, /* R448 */
+ { 0x0000, 0x0000 }, /* R449 */
+ { 0x0000, 0x0000 }, /* R450 */
+ { 0x0000, 0x0000 }, /* R451 */
+ { 0x0000, 0x0000 }, /* R452 */
+ { 0x0000, 0x0000 }, /* R453 */
+ { 0x0000, 0x0000 }, /* R454 */
+ { 0x0000, 0x0000 }, /* R455 */
+ { 0x0000, 0x0000 }, /* R456 */
+ { 0x0000, 0x0000 }, /* R457 */
+ { 0x0000, 0x0000 }, /* R458 */
+ { 0x0000, 0x0000 }, /* R459 */
+ { 0x0000, 0x0000 }, /* R460 */
+ { 0x0000, 0x0000 }, /* R461 */
+ { 0x0000, 0x0000 }, /* R462 */
+ { 0x0000, 0x0000 }, /* R463 */
+ { 0x0000, 0x0000 }, /* R464 */
+ { 0x0000, 0x0000 }, /* R465 */
+ { 0x0000, 0x0000 }, /* R466 */
+ { 0x0000, 0x0000 }, /* R467 */
+ { 0x0000, 0x0000 }, /* R468 */
+ { 0x0000, 0x0000 }, /* R469 */
+ { 0x0000, 0x0000 }, /* R470 */
+ { 0x0000, 0x0000 }, /* R471 */
+ { 0x0000, 0x0000 }, /* R472 */
+ { 0x0000, 0x0000 }, /* R473 */
+ { 0x0000, 0x0000 }, /* R474 */
+ { 0x0000, 0x0000 }, /* R475 */
+ { 0x0000, 0x0000 }, /* R476 */
+ { 0x0000, 0x0000 }, /* R477 */
+ { 0x0000, 0x0000 }, /* R478 */
+ { 0x0000, 0x0000 }, /* R479 */
+ { 0x0000, 0x0000 }, /* R480 */
+ { 0x0000, 0x0000 }, /* R481 */
+ { 0x0000, 0x0000 }, /* R482 */
+ { 0x0000, 0x0000 }, /* R483 */
+ { 0x0000, 0x0000 }, /* R484 */
+ { 0x0000, 0x0000 }, /* R485 */
+ { 0x0000, 0x0000 }, /* R486 */
+ { 0x0000, 0x0000 }, /* R487 */
+ { 0x0000, 0x0000 }, /* R488 */
+ { 0x0000, 0x0000 }, /* R489 */
+ { 0x0000, 0x0000 }, /* R490 */
+ { 0x0000, 0x0000 }, /* R491 */
+ { 0x0000, 0x0000 }, /* R492 */
+ { 0x0000, 0x0000 }, /* R493 */
+ { 0x0000, 0x0000 }, /* R494 */
+ { 0x0000, 0x0000 }, /* R495 */
+ { 0x0000, 0x0000 }, /* R496 */
+ { 0x0000, 0x0000 }, /* R497 */
+ { 0x0000, 0x0000 }, /* R498 */
+ { 0x0000, 0x0000 }, /* R499 */
+ { 0x0000, 0x0000 }, /* R500 */
+ { 0x0000, 0x0000 }, /* R501 */
+ { 0x0000, 0x0000 }, /* R502 */
+ { 0x0000, 0x0000 }, /* R503 */
+ { 0x0000, 0x0000 }, /* R504 */
+ { 0x0000, 0x0000 }, /* R505 */
+ { 0x0000, 0x0000 }, /* R506 */
+ { 0x0000, 0x0000 }, /* R507 */
+ { 0x0000, 0x0000 }, /* R508 */
+ { 0x0000, 0x0000 }, /* R509 */
+ { 0x0000, 0x0000 }, /* R510 */
+ { 0x0000, 0x0000 }, /* R511 */
+ { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
+ { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R514 */
+ { 0x0000, 0x0000 }, /* R515 */
+ { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
+ { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R518 */
+ { 0x0000, 0x0000 }, /* R519 */
+ { 0x001F, 0x001F }, /* R520 - Clocking (1) */
+ { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
+ { 0x0000, 0x0000 }, /* R522 */
+ { 0x0000, 0x0000 }, /* R523 */
+ { 0x0000, 0x0000 }, /* R524 */
+ { 0x0000, 0x0000 }, /* R525 */
+ { 0x0000, 0x0000 }, /* R526 */
+ { 0x0000, 0x0000 }, /* R527 */
+ { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
+ { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
+ { 0x000F, 0x0000 }, /* R530 - Rate Status */
+ { 0x0000, 0x0000 }, /* R531 */
+ { 0x0000, 0x0000 }, /* R532 */
+ { 0x0000, 0x0000 }, /* R533 */
+ { 0x0000, 0x0000 }, /* R534 */
+ { 0x0000, 0x0000 }, /* R535 */
+ { 0x0000, 0x0000 }, /* R536 */
+ { 0x0000, 0x0000 }, /* R537 */
+ { 0x0000, 0x0000 }, /* R538 */
+ { 0x0000, 0x0000 }, /* R539 */
+ { 0x0000, 0x0000 }, /* R540 */
+ { 0x0000, 0x0000 }, /* R541 */
+ { 0x0000, 0x0000 }, /* R542 */
+ { 0x0000, 0x0000 }, /* R543 */
+ { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
+ { 0x0000, 0x0000 }, /* R549 */
+ { 0x0000, 0x0000 }, /* R550 */
+ { 0x0000, 0x0000 }, /* R551 */
+ { 0x0000, 0x0000 }, /* R552 */
+ { 0x0000, 0x0000 }, /* R553 */
+ { 0x0000, 0x0000 }, /* R554 */
+ { 0x0000, 0x0000 }, /* R555 */
+ { 0x0000, 0x0000 }, /* R556 */
+ { 0x0000, 0x0000 }, /* R557 */
+ { 0x0000, 0x0000 }, /* R558 */
+ { 0x0000, 0x0000 }, /* R559 */
+ { 0x0000, 0x0000 }, /* R560 */
+ { 0x0000, 0x0000 }, /* R561 */
+ { 0x0000, 0x0000 }, /* R562 */
+ { 0x0000, 0x0000 }, /* R563 */
+ { 0x0000, 0x0000 }, /* R564 */
+ { 0x0000, 0x0000 }, /* R565 */
+ { 0x0000, 0x0000 }, /* R566 */
+ { 0x0000, 0x0000 }, /* R567 */
+ { 0x0000, 0x0000 }, /* R568 */
+ { 0x0000, 0x0000 }, /* R569 */
+ { 0x0000, 0x0000 }, /* R570 */
+ { 0x0000, 0x0000 }, /* R571 */
+ { 0x0000, 0x0000 }, /* R572 */
+ { 0x0000, 0x0000 }, /* R573 */
+ { 0x0000, 0x0000 }, /* R574 */
+ { 0x0000, 0x0000 }, /* R575 */
+ { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
+ { 0x0000, 0x0000 }, /* R581 */
+ { 0x0000, 0x0000 }, /* R582 */
+ { 0x0000, 0x0000 }, /* R583 */
+ { 0x0000, 0x0000 }, /* R584 */
+ { 0x0000, 0x0000 }, /* R585 */
+ { 0x0000, 0x0000 }, /* R586 */
+ { 0x0000, 0x0000 }, /* R587 */
+ { 0x0000, 0x0000 }, /* R588 */
+ { 0x0000, 0x0000 }, /* R589 */
+ { 0x0000, 0x0000 }, /* R590 */
+ { 0x0000, 0x0000 }, /* R591 */
+ { 0x0000, 0x0000 }, /* R592 */
+ { 0x0000, 0x0000 }, /* R593 */
+ { 0x0000, 0x0000 }, /* R594 */
+ { 0x0000, 0x0000 }, /* R595 */
+ { 0x0000, 0x0000 }, /* R596 */
+ { 0x0000, 0x0000 }, /* R597 */
+ { 0x0000, 0x0000 }, /* R598 */
+ { 0x0000, 0x0000 }, /* R599 */
+ { 0x0000, 0x0000 }, /* R600 */
+ { 0x0000, 0x0000 }, /* R601 */
+ { 0x0000, 0x0000 }, /* R602 */
+ { 0x0000, 0x0000 }, /* R603 */
+ { 0x0000, 0x0000 }, /* R604 */
+ { 0x0000, 0x0000 }, /* R605 */
+ { 0x0000, 0x0000 }, /* R606 */
+ { 0x0000, 0x0000 }, /* R607 */
+ { 0x0000, 0x0000 }, /* R608 */
+ { 0x0000, 0x0000 }, /* R609 */
+ { 0x0000, 0x0000 }, /* R610 */
+ { 0x0000, 0x0000 }, /* R611 */
+ { 0x0000, 0x0000 }, /* R612 */
+ { 0x0000, 0x0000 }, /* R613 */
+ { 0x0000, 0x0000 }, /* R614 */
+ { 0x0000, 0x0000 }, /* R615 */
+ { 0x0000, 0x0000 }, /* R616 */
+ { 0x0000, 0x0000 }, /* R617 */
+ { 0x0000, 0x0000 }, /* R618 */
+ { 0x0000, 0x0000 }, /* R619 */
+ { 0x0000, 0x0000 }, /* R620 */
+ { 0x0000, 0x0000 }, /* R621 */
+ { 0x0000, 0x0000 }, /* R622 */
+ { 0x0000, 0x0000 }, /* R623 */
+ { 0x0000, 0x0000 }, /* R624 */
+ { 0x0000, 0x0000 }, /* R625 */
+ { 0x0000, 0x0000 }, /* R626 */
+ { 0x0000, 0x0000 }, /* R627 */
+ { 0x0000, 0x0000 }, /* R628 */
+ { 0x0000, 0x0000 }, /* R629 */
+ { 0x0000, 0x0000 }, /* R630 */
+ { 0x0000, 0x0000 }, /* R631 */
+ { 0x0000, 0x0000 }, /* R632 */
+ { 0x0000, 0x0000 }, /* R633 */
+ { 0x0000, 0x0000 }, /* R634 */
+ { 0x0000, 0x0000 }, /* R635 */
+ { 0x0000, 0x0000 }, /* R636 */
+ { 0x0000, 0x0000 }, /* R637 */
+ { 0x0000, 0x0000 }, /* R638 */
+ { 0x0000, 0x0000 }, /* R639 */
+ { 0x0000, 0x0000 }, /* R640 */
+ { 0x0000, 0x0000 }, /* R641 */
+ { 0x0000, 0x0000 }, /* R642 */
+ { 0x0000, 0x0000 }, /* R643 */
+ { 0x0000, 0x0000 }, /* R644 */
+ { 0x0000, 0x0000 }, /* R645 */
+ { 0x0000, 0x0000 }, /* R646 */
+ { 0x0000, 0x0000 }, /* R647 */
+ { 0x0000, 0x0000 }, /* R648 */
+ { 0x0000, 0x0000 }, /* R649 */
+ { 0x0000, 0x0000 }, /* R650 */
+ { 0x0000, 0x0000 }, /* R651 */
+ { 0x0000, 0x0000 }, /* R652 */
+ { 0x0000, 0x0000 }, /* R653 */
+ { 0x0000, 0x0000 }, /* R654 */
+ { 0x0000, 0x0000 }, /* R655 */
+ { 0x0000, 0x0000 }, /* R656 */
+ { 0x0000, 0x0000 }, /* R657 */
+ { 0x0000, 0x0000 }, /* R658 */
+ { 0x0000, 0x0000 }, /* R659 */
+ { 0x0000, 0x0000 }, /* R660 */
+ { 0x0000, 0x0000 }, /* R661 */
+ { 0x0000, 0x0000 }, /* R662 */
+ { 0x0000, 0x0000 }, /* R663 */
+ { 0x0000, 0x0000 }, /* R664 */
+ { 0x0000, 0x0000 }, /* R665 */
+ { 0x0000, 0x0000 }, /* R666 */
+ { 0x0000, 0x0000 }, /* R667 */
+ { 0x0000, 0x0000 }, /* R668 */
+ { 0x0000, 0x0000 }, /* R669 */
+ { 0x0000, 0x0000 }, /* R670 */
+ { 0x0000, 0x0000 }, /* R671 */
+ { 0x0000, 0x0000 }, /* R672 */
+ { 0x0000, 0x0000 }, /* R673 */
+ { 0x0000, 0x0000 }, /* R674 */
+ { 0x0000, 0x0000 }, /* R675 */
+ { 0x0000, 0x0000 }, /* R676 */
+ { 0x0000, 0x0000 }, /* R677 */
+ { 0x0000, 0x0000 }, /* R678 */
+ { 0x0000, 0x0000 }, /* R679 */
+ { 0x0000, 0x0000 }, /* R680 */
+ { 0x0000, 0x0000 }, /* R681 */
+ { 0x0000, 0x0000 }, /* R682 */
+ { 0x0000, 0x0000 }, /* R683 */
+ { 0x0000, 0x0000 }, /* R684 */
+ { 0x0000, 0x0000 }, /* R685 */
+ { 0x0000, 0x0000 }, /* R686 */
+ { 0x0000, 0x0000 }, /* R687 */
+ { 0x0000, 0x0000 }, /* R688 */
+ { 0x0000, 0x0000 }, /* R689 */
+ { 0x0000, 0x0000 }, /* R690 */
+ { 0x0000, 0x0000 }, /* R691 */
+ { 0x0000, 0x0000 }, /* R692 */
+ { 0x0000, 0x0000 }, /* R693 */
+ { 0x0000, 0x0000 }, /* R694 */
+ { 0x0000, 0x0000 }, /* R695 */
+ { 0x0000, 0x0000 }, /* R696 */
+ { 0x0000, 0x0000 }, /* R697 */
+ { 0x0000, 0x0000 }, /* R698 */
+ { 0x0000, 0x0000 }, /* R699 */
+ { 0x0000, 0x0000 }, /* R700 */
+ { 0x0000, 0x0000 }, /* R701 */
+ { 0x0000, 0x0000 }, /* R702 */
+ { 0x0000, 0x0000 }, /* R703 */
+ { 0x0000, 0x0000 }, /* R704 */
+ { 0x0000, 0x0000 }, /* R705 */
+ { 0x0000, 0x0000 }, /* R706 */
+ { 0x0000, 0x0000 }, /* R707 */
+ { 0x0000, 0x0000 }, /* R708 */
+ { 0x0000, 0x0000 }, /* R709 */
+ { 0x0000, 0x0000 }, /* R710 */
+ { 0x0000, 0x0000 }, /* R711 */
+ { 0x0000, 0x0000 }, /* R712 */
+ { 0x0000, 0x0000 }, /* R713 */
+ { 0x0000, 0x0000 }, /* R714 */
+ { 0x0000, 0x0000 }, /* R715 */
+ { 0x0000, 0x0000 }, /* R716 */
+ { 0x0000, 0x0000 }, /* R717 */
+ { 0x0000, 0x0000 }, /* R718 */
+ { 0x0000, 0x0000 }, /* R719 */
+ { 0x0000, 0x0000 }, /* R720 */
+ { 0x0000, 0x0000 }, /* R721 */
+ { 0x0000, 0x0000 }, /* R722 */
+ { 0x0000, 0x0000 }, /* R723 */
+ { 0x0000, 0x0000 }, /* R724 */
+ { 0x0000, 0x0000 }, /* R725 */
+ { 0x0000, 0x0000 }, /* R726 */
+ { 0x0000, 0x0000 }, /* R727 */
+ { 0x0000, 0x0000 }, /* R728 */
+ { 0x0000, 0x0000 }, /* R729 */
+ { 0x0000, 0x0000 }, /* R730 */
+ { 0x0000, 0x0000 }, /* R731 */
+ { 0x0000, 0x0000 }, /* R732 */
+ { 0x0000, 0x0000 }, /* R733 */
+ { 0x0000, 0x0000 }, /* R734 */
+ { 0x0000, 0x0000 }, /* R735 */
+ { 0x0000, 0x0000 }, /* R736 */
+ { 0x0000, 0x0000 }, /* R737 */
+ { 0x0000, 0x0000 }, /* R738 */
+ { 0x0000, 0x0000 }, /* R739 */
+ { 0x0000, 0x0000 }, /* R740 */
+ { 0x0000, 0x0000 }, /* R741 */
+ { 0x0000, 0x0000 }, /* R742 */
+ { 0x0000, 0x0000 }, /* R743 */
+ { 0x0000, 0x0000 }, /* R744 */
+ { 0x0000, 0x0000 }, /* R745 */
+ { 0x0000, 0x0000 }, /* R746 */
+ { 0x0000, 0x0000 }, /* R747 */
+ { 0x0000, 0x0000 }, /* R748 */
+ { 0x0000, 0x0000 }, /* R749 */
+ { 0x0000, 0x0000 }, /* R750 */
+ { 0x0000, 0x0000 }, /* R751 */
+ { 0x0000, 0x0000 }, /* R752 */
+ { 0x0000, 0x0000 }, /* R753 */
+ { 0x0000, 0x0000 }, /* R754 */
+ { 0x0000, 0x0000 }, /* R755 */
+ { 0x0000, 0x0000 }, /* R756 */
+ { 0x0000, 0x0000 }, /* R757 */
+ { 0x0000, 0x0000 }, /* R758 */
+ { 0x0000, 0x0000 }, /* R759 */
+ { 0x0000, 0x0000 }, /* R760 */
+ { 0x0000, 0x0000 }, /* R761 */
+ { 0x0000, 0x0000 }, /* R762 */
+ { 0x0000, 0x0000 }, /* R763 */
+ { 0x0000, 0x0000 }, /* R764 */
+ { 0x0000, 0x0000 }, /* R765 */
+ { 0x0000, 0x0000 }, /* R766 */
+ { 0x0000, 0x0000 }, /* R767 */
+ { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
+ { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
+ { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
+ { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
+ { 0x0000, 0x0000 }, /* R776 */
+ { 0x0000, 0x0000 }, /* R777 */
+ { 0x0000, 0x0000 }, /* R778 */
+ { 0x0000, 0x0000 }, /* R779 */
+ { 0x0000, 0x0000 }, /* R780 */
+ { 0x0000, 0x0000 }, /* R781 */
+ { 0x0000, 0x0000 }, /* R782 */
+ { 0x0000, 0x0000 }, /* R783 */
+ { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
+ { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
+ { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
+ { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
+ { 0x0000, 0x0000 }, /* R792 */
+ { 0x0000, 0x0000 }, /* R793 */
+ { 0x0000, 0x0000 }, /* R794 */
+ { 0x0000, 0x0000 }, /* R795 */
+ { 0x0000, 0x0000 }, /* R796 */
+ { 0x0000, 0x0000 }, /* R797 */
+ { 0x0000, 0x0000 }, /* R798 */
+ { 0x0000, 0x0000 }, /* R799 */
+ { 0x0000, 0x0000 }, /* R800 */
+ { 0x0000, 0x0000 }, /* R801 */
+ { 0x0000, 0x0000 }, /* R802 */
+ { 0x0000, 0x0000 }, /* R803 */
+ { 0x0000, 0x0000 }, /* R804 */
+ { 0x0000, 0x0000 }, /* R805 */
+ { 0x0000, 0x0000 }, /* R806 */
+ { 0x0000, 0x0000 }, /* R807 */
+ { 0x0000, 0x0000 }, /* R808 */
+ { 0x0000, 0x0000 }, /* R809 */
+ { 0x0000, 0x0000 }, /* R810 */
+ { 0x0000, 0x0000 }, /* R811 */
+ { 0x0000, 0x0000 }, /* R812 */
+ { 0x0000, 0x0000 }, /* R813 */
+ { 0x0000, 0x0000 }, /* R814 */
+ { 0x0000, 0x0000 }, /* R815 */
+ { 0x0000, 0x0000 }, /* R816 */
+ { 0x0000, 0x0000 }, /* R817 */
+ { 0x0000, 0x0000 }, /* R818 */
+ { 0x0000, 0x0000 }, /* R819 */
+ { 0x0000, 0x0000 }, /* R820 */
+ { 0x0000, 0x0000 }, /* R821 */
+ { 0x0000, 0x0000 }, /* R822 */
+ { 0x0000, 0x0000 }, /* R823 */
+ { 0x0000, 0x0000 }, /* R824 */
+ { 0x0000, 0x0000 }, /* R825 */
+ { 0x0000, 0x0000 }, /* R826 */
+ { 0x0000, 0x0000 }, /* R827 */
+ { 0x0000, 0x0000 }, /* R828 */
+ { 0x0000, 0x0000 }, /* R829 */
+ { 0x0000, 0x0000 }, /* R830 */
+ { 0x0000, 0x0000 }, /* R831 */
+ { 0x0000, 0x0000 }, /* R832 */
+ { 0x0000, 0x0000 }, /* R833 */
+ { 0x0000, 0x0000 }, /* R834 */
+ { 0x0000, 0x0000 }, /* R835 */
+ { 0x0000, 0x0000 }, /* R836 */
+ { 0x0000, 0x0000 }, /* R837 */
+ { 0x0000, 0x0000 }, /* R838 */
+ { 0x0000, 0x0000 }, /* R839 */
+ { 0x0000, 0x0000 }, /* R840 */
+ { 0x0000, 0x0000 }, /* R841 */
+ { 0x0000, 0x0000 }, /* R842 */
+ { 0x0000, 0x0000 }, /* R843 */
+ { 0x0000, 0x0000 }, /* R844 */
+ { 0x0000, 0x0000 }, /* R845 */
+ { 0x0000, 0x0000 }, /* R846 */
+ { 0x0000, 0x0000 }, /* R847 */
+ { 0x0000, 0x0000 }, /* R848 */
+ { 0x0000, 0x0000 }, /* R849 */
+ { 0x0000, 0x0000 }, /* R850 */
+ { 0x0000, 0x0000 }, /* R851 */
+ { 0x0000, 0x0000 }, /* R852 */
+ { 0x0000, 0x0000 }, /* R853 */
+ { 0x0000, 0x0000 }, /* R854 */
+ { 0x0000, 0x0000 }, /* R855 */
+ { 0x0000, 0x0000 }, /* R856 */
+ { 0x0000, 0x0000 }, /* R857 */
+ { 0x0000, 0x0000 }, /* R858 */
+ { 0x0000, 0x0000 }, /* R859 */
+ { 0x0000, 0x0000 }, /* R860 */
+ { 0x0000, 0x0000 }, /* R861 */
+ { 0x0000, 0x0000 }, /* R862 */
+ { 0x0000, 0x0000 }, /* R863 */
+ { 0x0000, 0x0000 }, /* R864 */
+ { 0x0000, 0x0000 }, /* R865 */
+ { 0x0000, 0x0000 }, /* R866 */
+ { 0x0000, 0x0000 }, /* R867 */
+ { 0x0000, 0x0000 }, /* R868 */
+ { 0x0000, 0x0000 }, /* R869 */
+ { 0x0000, 0x0000 }, /* R870 */
+ { 0x0000, 0x0000 }, /* R871 */
+ { 0x0000, 0x0000 }, /* R872 */
+ { 0x0000, 0x0000 }, /* R873 */
+ { 0x0000, 0x0000 }, /* R874 */
+ { 0x0000, 0x0000 }, /* R875 */
+ { 0x0000, 0x0000 }, /* R876 */
+ { 0x0000, 0x0000 }, /* R877 */
+ { 0x0000, 0x0000 }, /* R878 */
+ { 0x0000, 0x0000 }, /* R879 */
+ { 0x0000, 0x0000 }, /* R880 */
+ { 0x0000, 0x0000 }, /* R881 */
+ { 0x0000, 0x0000 }, /* R882 */
+ { 0x0000, 0x0000 }, /* R883 */
+ { 0x0000, 0x0000 }, /* R884 */
+ { 0x0000, 0x0000 }, /* R885 */
+ { 0x0000, 0x0000 }, /* R886 */
+ { 0x0000, 0x0000 }, /* R887 */
+ { 0x0000, 0x0000 }, /* R888 */
+ { 0x0000, 0x0000 }, /* R889 */
+ { 0x0000, 0x0000 }, /* R890 */
+ { 0x0000, 0x0000 }, /* R891 */
+ { 0x0000, 0x0000 }, /* R892 */
+ { 0x0000, 0x0000 }, /* R893 */
+ { 0x0000, 0x0000 }, /* R894 */
+ { 0x0000, 0x0000 }, /* R895 */
+ { 0x0000, 0x0000 }, /* R896 */
+ { 0x0000, 0x0000 }, /* R897 */
+ { 0x0000, 0x0000 }, /* R898 */
+ { 0x0000, 0x0000 }, /* R899 */
+ { 0x0000, 0x0000 }, /* R900 */
+ { 0x0000, 0x0000 }, /* R901 */
+ { 0x0000, 0x0000 }, /* R902 */
+ { 0x0000, 0x0000 }, /* R903 */
+ { 0x0000, 0x0000 }, /* R904 */
+ { 0x0000, 0x0000 }, /* R905 */
+ { 0x0000, 0x0000 }, /* R906 */
+ { 0x0000, 0x0000 }, /* R907 */
+ { 0x0000, 0x0000 }, /* R908 */
+ { 0x0000, 0x0000 }, /* R909 */
+ { 0x0000, 0x0000 }, /* R910 */
+ { 0x0000, 0x0000 }, /* R911 */
+ { 0x0000, 0x0000 }, /* R912 */
+ { 0x0000, 0x0000 }, /* R913 */
+ { 0x0000, 0x0000 }, /* R914 */
+ { 0x0000, 0x0000 }, /* R915 */
+ { 0x0000, 0x0000 }, /* R916 */
+ { 0x0000, 0x0000 }, /* R917 */
+ { 0x0000, 0x0000 }, /* R918 */
+ { 0x0000, 0x0000 }, /* R919 */
+ { 0x0000, 0x0000 }, /* R920 */
+ { 0x0000, 0x0000 }, /* R921 */
+ { 0x0000, 0x0000 }, /* R922 */
+ { 0x0000, 0x0000 }, /* R923 */
+ { 0x0000, 0x0000 }, /* R924 */
+ { 0x0000, 0x0000 }, /* R925 */
+ { 0x0000, 0x0000 }, /* R926 */
+ { 0x0000, 0x0000 }, /* R927 */
+ { 0x0000, 0x0000 }, /* R928 */
+ { 0x0000, 0x0000 }, /* R929 */
+ { 0x0000, 0x0000 }, /* R930 */
+ { 0x0000, 0x0000 }, /* R931 */
+ { 0x0000, 0x0000 }, /* R932 */
+ { 0x0000, 0x0000 }, /* R933 */
+ { 0x0000, 0x0000 }, /* R934 */
+ { 0x0000, 0x0000 }, /* R935 */
+ { 0x0000, 0x0000 }, /* R936 */
+ { 0x0000, 0x0000 }, /* R937 */
+ { 0x0000, 0x0000 }, /* R938 */
+ { 0x0000, 0x0000 }, /* R939 */
+ { 0x0000, 0x0000 }, /* R940 */
+ { 0x0000, 0x0000 }, /* R941 */
+ { 0x0000, 0x0000 }, /* R942 */
+ { 0x0000, 0x0000 }, /* R943 */
+ { 0x0000, 0x0000 }, /* R944 */
+ { 0x0000, 0x0000 }, /* R945 */
+ { 0x0000, 0x0000 }, /* R946 */
+ { 0x0000, 0x0000 }, /* R947 */
+ { 0x0000, 0x0000 }, /* R948 */
+ { 0x0000, 0x0000 }, /* R949 */
+ { 0x0000, 0x0000 }, /* R950 */
+ { 0x0000, 0x0000 }, /* R951 */
+ { 0x0000, 0x0000 }, /* R952 */
+ { 0x0000, 0x0000 }, /* R953 */
+ { 0x0000, 0x0000 }, /* R954 */
+ { 0x0000, 0x0000 }, /* R955 */
+ { 0x0000, 0x0000 }, /* R956 */
+ { 0x0000, 0x0000 }, /* R957 */
+ { 0x0000, 0x0000 }, /* R958 */
+ { 0x0000, 0x0000 }, /* R959 */
+ { 0x0000, 0x0000 }, /* R960 */
+ { 0x0000, 0x0000 }, /* R961 */
+ { 0x0000, 0x0000 }, /* R962 */
+ { 0x0000, 0x0000 }, /* R963 */
+ { 0x0000, 0x0000 }, /* R964 */
+ { 0x0000, 0x0000 }, /* R965 */
+ { 0x0000, 0x0000 }, /* R966 */
+ { 0x0000, 0x0000 }, /* R967 */
+ { 0x0000, 0x0000 }, /* R968 */
+ { 0x0000, 0x0000 }, /* R969 */
+ { 0x0000, 0x0000 }, /* R970 */
+ { 0x0000, 0x0000 }, /* R971 */
+ { 0x0000, 0x0000 }, /* R972 */
+ { 0x0000, 0x0000 }, /* R973 */
+ { 0x0000, 0x0000 }, /* R974 */
+ { 0x0000, 0x0000 }, /* R975 */
+ { 0x0000, 0x0000 }, /* R976 */
+ { 0x0000, 0x0000 }, /* R977 */
+ { 0x0000, 0x0000 }, /* R978 */
+ { 0x0000, 0x0000 }, /* R979 */
+ { 0x0000, 0x0000 }, /* R980 */
+ { 0x0000, 0x0000 }, /* R981 */
+ { 0x0000, 0x0000 }, /* R982 */
+ { 0x0000, 0x0000 }, /* R983 */
+ { 0x0000, 0x0000 }, /* R984 */
+ { 0x0000, 0x0000 }, /* R985 */
+ { 0x0000, 0x0000 }, /* R986 */
+ { 0x0000, 0x0000 }, /* R987 */
+ { 0x0000, 0x0000 }, /* R988 */
+ { 0x0000, 0x0000 }, /* R989 */
+ { 0x0000, 0x0000 }, /* R990 */
+ { 0x0000, 0x0000 }, /* R991 */
+ { 0x0000, 0x0000 }, /* R992 */
+ { 0x0000, 0x0000 }, /* R993 */
+ { 0x0000, 0x0000 }, /* R994 */
+ { 0x0000, 0x0000 }, /* R995 */
+ { 0x0000, 0x0000 }, /* R996 */
+ { 0x0000, 0x0000 }, /* R997 */
+ { 0x0000, 0x0000 }, /* R998 */
+ { 0x0000, 0x0000 }, /* R999 */
+ { 0x0000, 0x0000 }, /* R1000 */
+ { 0x0000, 0x0000 }, /* R1001 */
+ { 0x0000, 0x0000 }, /* R1002 */
+ { 0x0000, 0x0000 }, /* R1003 */
+ { 0x0000, 0x0000 }, /* R1004 */
+ { 0x0000, 0x0000 }, /* R1005 */
+ { 0x0000, 0x0000 }, /* R1006 */
+ { 0x0000, 0x0000 }, /* R1007 */
+ { 0x0000, 0x0000 }, /* R1008 */
+ { 0x0000, 0x0000 }, /* R1009 */
+ { 0x0000, 0x0000 }, /* R1010 */
+ { 0x0000, 0x0000 }, /* R1011 */
+ { 0x0000, 0x0000 }, /* R1012 */
+ { 0x0000, 0x0000 }, /* R1013 */
+ { 0x0000, 0x0000 }, /* R1014 */
+ { 0x0000, 0x0000 }, /* R1015 */
+ { 0x0000, 0x0000 }, /* R1016 */
+ { 0x0000, 0x0000 }, /* R1017 */
+ { 0x0000, 0x0000 }, /* R1018 */
+ { 0x0000, 0x0000 }, /* R1019 */
+ { 0x0000, 0x0000 }, /* R1020 */
+ { 0x0000, 0x0000 }, /* R1021 */
+ { 0x0000, 0x0000 }, /* R1022 */
+ { 0x0000, 0x0000 }, /* R1023 */
+ { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
+ { 0x0000, 0x0000 }, /* R1032 */
+ { 0x0000, 0x0000 }, /* R1033 */
+ { 0x0000, 0x0000 }, /* R1034 */
+ { 0x0000, 0x0000 }, /* R1035 */
+ { 0x0000, 0x0000 }, /* R1036 */
+ { 0x0000, 0x0000 }, /* R1037 */
+ { 0x0000, 0x0000 }, /* R1038 */
+ { 0x0000, 0x0000 }, /* R1039 */
+ { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
+ { 0x0000, 0x0000 }, /* R1042 */
+ { 0x0000, 0x0000 }, /* R1043 */
+ { 0x0000, 0x0000 }, /* R1044 */
+ { 0x0000, 0x0000 }, /* R1045 */
+ { 0x0000, 0x0000 }, /* R1046 */
+ { 0x0000, 0x0000 }, /* R1047 */
+ { 0x0000, 0x0000 }, /* R1048 */
+ { 0x0000, 0x0000 }, /* R1049 */
+ { 0x0000, 0x0000 }, /* R1050 */
+ { 0x0000, 0x0000 }, /* R1051 */
+ { 0x0000, 0x0000 }, /* R1052 */
+ { 0x0000, 0x0000 }, /* R1053 */
+ { 0x0000, 0x0000 }, /* R1054 */
+ { 0x0000, 0x0000 }, /* R1055 */
+ { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
+ { 0x0000, 0x0000 }, /* R1060 */
+ { 0x0000, 0x0000 }, /* R1061 */
+ { 0x0000, 0x0000 }, /* R1062 */
+ { 0x0000, 0x0000 }, /* R1063 */
+ { 0x0000, 0x0000 }, /* R1064 */
+ { 0x0000, 0x0000 }, /* R1065 */
+ { 0x0000, 0x0000 }, /* R1066 */
+ { 0x0000, 0x0000 }, /* R1067 */
+ { 0x0000, 0x0000 }, /* R1068 */
+ { 0x0000, 0x0000 }, /* R1069 */
+ { 0x0000, 0x0000 }, /* R1070 */
+ { 0x0000, 0x0000 }, /* R1071 */
+ { 0x0000, 0x0000 }, /* R1072 */
+ { 0x0000, 0x0000 }, /* R1073 */
+ { 0x0000, 0x0000 }, /* R1074 */
+ { 0x0000, 0x0000 }, /* R1075 */
+ { 0x0000, 0x0000 }, /* R1076 */
+ { 0x0000, 0x0000 }, /* R1077 */
+ { 0x0000, 0x0000 }, /* R1078 */
+ { 0x0000, 0x0000 }, /* R1079 */
+ { 0x0000, 0x0000 }, /* R1080 */
+ { 0x0000, 0x0000 }, /* R1081 */
+ { 0x0000, 0x0000 }, /* R1082 */
+ { 0x0000, 0x0000 }, /* R1083 */
+ { 0x0000, 0x0000 }, /* R1084 */
+ { 0x0000, 0x0000 }, /* R1085 */
+ { 0x0000, 0x0000 }, /* R1086 */
+ { 0x0000, 0x0000 }, /* R1087 */
+ { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0000, 0x0000 }, /* R1093 */
+ { 0x0000, 0x0000 }, /* R1094 */
+ { 0x0000, 0x0000 }, /* R1095 */
+ { 0x0000, 0x0000 }, /* R1096 */
+ { 0x0000, 0x0000 }, /* R1097 */
+ { 0x0000, 0x0000 }, /* R1098 */
+ { 0x0000, 0x0000 }, /* R1099 */
+ { 0x0000, 0x0000 }, /* R1100 */
+ { 0x0000, 0x0000 }, /* R1101 */
+ { 0x0000, 0x0000 }, /* R1102 */
+ { 0x0000, 0x0000 }, /* R1103 */
+ { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
+ { 0x0000, 0x0000 }, /* R1109 */
+ { 0x0000, 0x0000 }, /* R1110 */
+ { 0x0000, 0x0000 }, /* R1111 */
+ { 0x0000, 0x0000 }, /* R1112 */
+ { 0x0000, 0x0000 }, /* R1113 */
+ { 0x0000, 0x0000 }, /* R1114 */
+ { 0x0000, 0x0000 }, /* R1115 */
+ { 0x0000, 0x0000 }, /* R1116 */
+ { 0x0000, 0x0000 }, /* R1117 */
+ { 0x0000, 0x0000 }, /* R1118 */
+ { 0x0000, 0x0000 }, /* R1119 */
+ { 0x0000, 0x0000 }, /* R1120 */
+ { 0x0000, 0x0000 }, /* R1121 */
+ { 0x0000, 0x0000 }, /* R1122 */
+ { 0x0000, 0x0000 }, /* R1123 */
+ { 0x0000, 0x0000 }, /* R1124 */
+ { 0x0000, 0x0000 }, /* R1125 */
+ { 0x0000, 0x0000 }, /* R1126 */
+ { 0x0000, 0x0000 }, /* R1127 */
+ { 0x0000, 0x0000 }, /* R1128 */
+ { 0x0000, 0x0000 }, /* R1129 */
+ { 0x0000, 0x0000 }, /* R1130 */
+ { 0x0000, 0x0000 }, /* R1131 */
+ { 0x0000, 0x0000 }, /* R1132 */
+ { 0x0000, 0x0000 }, /* R1133 */
+ { 0x0000, 0x0000 }, /* R1134 */
+ { 0x0000, 0x0000 }, /* R1135 */
+ { 0x0000, 0x0000 }, /* R1136 */
+ { 0x0000, 0x0000 }, /* R1137 */
+ { 0x0000, 0x0000 }, /* R1138 */
+ { 0x0000, 0x0000 }, /* R1139 */
+ { 0x0000, 0x0000 }, /* R1140 */
+ { 0x0000, 0x0000 }, /* R1141 */
+ { 0x0000, 0x0000 }, /* R1142 */
+ { 0x0000, 0x0000 }, /* R1143 */
+ { 0x0000, 0x0000 }, /* R1144 */
+ { 0x0000, 0x0000 }, /* R1145 */
+ { 0x0000, 0x0000 }, /* R1146 */
+ { 0x0000, 0x0000 }, /* R1147 */
+ { 0x0000, 0x0000 }, /* R1148 */
+ { 0x0000, 0x0000 }, /* R1149 */
+ { 0x0000, 0x0000 }, /* R1150 */
+ { 0x0000, 0x0000 }, /* R1151 */
+ { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1172 */
+ { 0x0000, 0x0000 }, /* R1173 */
+ { 0x0000, 0x0000 }, /* R1174 */
+ { 0x0000, 0x0000 }, /* R1175 */
+ { 0x0000, 0x0000 }, /* R1176 */
+ { 0x0000, 0x0000 }, /* R1177 */
+ { 0x0000, 0x0000 }, /* R1178 */
+ { 0x0000, 0x0000 }, /* R1179 */
+ { 0x0000, 0x0000 }, /* R1180 */
+ { 0x0000, 0x0000 }, /* R1181 */
+ { 0x0000, 0x0000 }, /* R1182 */
+ { 0x0000, 0x0000 }, /* R1183 */
+ { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1204 */
+ { 0x0000, 0x0000 }, /* R1205 */
+ { 0x0000, 0x0000 }, /* R1206 */
+ { 0x0000, 0x0000 }, /* R1207 */
+ { 0x0000, 0x0000 }, /* R1208 */
+ { 0x0000, 0x0000 }, /* R1209 */
+ { 0x0000, 0x0000 }, /* R1210 */
+ { 0x0000, 0x0000 }, /* R1211 */
+ { 0x0000, 0x0000 }, /* R1212 */
+ { 0x0000, 0x0000 }, /* R1213 */
+ { 0x0000, 0x0000 }, /* R1214 */
+ { 0x0000, 0x0000 }, /* R1215 */
+ { 0x0000, 0x0000 }, /* R1216 */
+ { 0x0000, 0x0000 }, /* R1217 */
+ { 0x0000, 0x0000 }, /* R1218 */
+ { 0x0000, 0x0000 }, /* R1219 */
+ { 0x0000, 0x0000 }, /* R1220 */
+ { 0x0000, 0x0000 }, /* R1221 */
+ { 0x0000, 0x0000 }, /* R1222 */
+ { 0x0000, 0x0000 }, /* R1223 */
+ { 0x0000, 0x0000 }, /* R1224 */
+ { 0x0000, 0x0000 }, /* R1225 */
+ { 0x0000, 0x0000 }, /* R1226 */
+ { 0x0000, 0x0000 }, /* R1227 */
+ { 0x0000, 0x0000 }, /* R1228 */
+ { 0x0000, 0x0000 }, /* R1229 */
+ { 0x0000, 0x0000 }, /* R1230 */
+ { 0x0000, 0x0000 }, /* R1231 */
+ { 0x0000, 0x0000 }, /* R1232 */
+ { 0x0000, 0x0000 }, /* R1233 */
+ { 0x0000, 0x0000 }, /* R1234 */
+ { 0x0000, 0x0000 }, /* R1235 */
+ { 0x0000, 0x0000 }, /* R1236 */
+ { 0x0000, 0x0000 }, /* R1237 */
+ { 0x0000, 0x0000 }, /* R1238 */
+ { 0x0000, 0x0000 }, /* R1239 */
+ { 0x0000, 0x0000 }, /* R1240 */
+ { 0x0000, 0x0000 }, /* R1241 */
+ { 0x0000, 0x0000 }, /* R1242 */
+ { 0x0000, 0x0000 }, /* R1243 */
+ { 0x0000, 0x0000 }, /* R1244 */
+ { 0x0000, 0x0000 }, /* R1245 */
+ { 0x0000, 0x0000 }, /* R1246 */
+ { 0x0000, 0x0000 }, /* R1247 */
+ { 0x0000, 0x0000 }, /* R1248 */
+ { 0x0000, 0x0000 }, /* R1249 */
+ { 0x0000, 0x0000 }, /* R1250 */
+ { 0x0000, 0x0000 }, /* R1251 */
+ { 0x0000, 0x0000 }, /* R1252 */
+ { 0x0000, 0x0000 }, /* R1253 */
+ { 0x0000, 0x0000 }, /* R1254 */
+ { 0x0000, 0x0000 }, /* R1255 */
+ { 0x0000, 0x0000 }, /* R1256 */
+ { 0x0000, 0x0000 }, /* R1257 */
+ { 0x0000, 0x0000 }, /* R1258 */
+ { 0x0000, 0x0000 }, /* R1259 */
+ { 0x0000, 0x0000 }, /* R1260 */
+ { 0x0000, 0x0000 }, /* R1261 */
+ { 0x0000, 0x0000 }, /* R1262 */
+ { 0x0000, 0x0000 }, /* R1263 */
+ { 0x0000, 0x0000 }, /* R1264 */
+ { 0x0000, 0x0000 }, /* R1265 */
+ { 0x0000, 0x0000 }, /* R1266 */
+ { 0x0000, 0x0000 }, /* R1267 */
+ { 0x0000, 0x0000 }, /* R1268 */
+ { 0x0000, 0x0000 }, /* R1269 */
+ { 0x0000, 0x0000 }, /* R1270 */
+ { 0x0000, 0x0000 }, /* R1271 */
+ { 0x0000, 0x0000 }, /* R1272 */
+ { 0x0000, 0x0000 }, /* R1273 */
+ { 0x0000, 0x0000 }, /* R1274 */
+ { 0x0000, 0x0000 }, /* R1275 */
+ { 0x0000, 0x0000 }, /* R1276 */
+ { 0x0000, 0x0000 }, /* R1277 */
+ { 0x0000, 0x0000 }, /* R1278 */
+ { 0x0000, 0x0000 }, /* R1279 */
+ { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0000, 0x0000 }, /* R1284 */
+ { 0x0000, 0x0000 }, /* R1285 */
+ { 0x0000, 0x0000 }, /* R1286 */
+ { 0x0000, 0x0000 }, /* R1287 */
+ { 0x0000, 0x0000 }, /* R1288 */
+ { 0x0000, 0x0000 }, /* R1289 */
+ { 0x0000, 0x0000 }, /* R1290 */
+ { 0x0000, 0x0000 }, /* R1291 */
+ { 0x0000, 0x0000 }, /* R1292 */
+ { 0x0000, 0x0000 }, /* R1293 */
+ { 0x0000, 0x0000 }, /* R1294 */
+ { 0x0000, 0x0000 }, /* R1295 */
+ { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0000, 0x0000 }, /* R1297 */
+ { 0x0000, 0x0000 }, /* R1298 */
+ { 0x0000, 0x0000 }, /* R1299 */
+ { 0x0000, 0x0000 }, /* R1300 */
+ { 0x0000, 0x0000 }, /* R1301 */
+ { 0x0000, 0x0000 }, /* R1302 */
+ { 0x0000, 0x0000 }, /* R1303 */
+ { 0x0000, 0x0000 }, /* R1304 */
+ { 0x0000, 0x0000 }, /* R1305 */
+ { 0x0000, 0x0000 }, /* R1306 */
+ { 0x0000, 0x0000 }, /* R1307 */
+ { 0x0000, 0x0000 }, /* R1308 */
+ { 0x0000, 0x0000 }, /* R1309 */
+ { 0x0000, 0x0000 }, /* R1310 */
+ { 0x0000, 0x0000 }, /* R1311 */
+ { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0000, 0x0000 }, /* R1314 */
+ { 0x0000, 0x0000 }, /* R1315 */
+ { 0x0000, 0x0000 }, /* R1316 */
+ { 0x0000, 0x0000 }, /* R1317 */
+ { 0x0000, 0x0000 }, /* R1318 */
+ { 0x0000, 0x0000 }, /* R1319 */
+ { 0x0000, 0x0000 }, /* R1320 */
+ { 0x0000, 0x0000 }, /* R1321 */
+ { 0x0000, 0x0000 }, /* R1322 */
+ { 0x0000, 0x0000 }, /* R1323 */
+ { 0x0000, 0x0000 }, /* R1324 */
+ { 0x0000, 0x0000 }, /* R1325 */
+ { 0x0000, 0x0000 }, /* R1326 */
+ { 0x0000, 0x0000 }, /* R1327 */
+ { 0x0000, 0x0000 }, /* R1328 */
+ { 0x0000, 0x0000 }, /* R1329 */
+ { 0x0000, 0x0000 }, /* R1330 */
+ { 0x0000, 0x0000 }, /* R1331 */
+ { 0x0000, 0x0000 }, /* R1332 */
+ { 0x0000, 0x0000 }, /* R1333 */
+ { 0x0000, 0x0000 }, /* R1334 */
+ { 0x0000, 0x0000 }, /* R1335 */
+ { 0x0000, 0x0000 }, /* R1336 */
+ { 0x0000, 0x0000 }, /* R1337 */
+ { 0x0000, 0x0000 }, /* R1338 */
+ { 0x0000, 0x0000 }, /* R1339 */
+ { 0x0000, 0x0000 }, /* R1340 */
+ { 0x0000, 0x0000 }, /* R1341 */
+ { 0x0000, 0x0000 }, /* R1342 */
+ { 0x0000, 0x0000 }, /* R1343 */
+ { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
+ { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
+ { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
+ { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
+ { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
+ { 0x0000, 0x0000 }, /* R1349 */
+ { 0x0000, 0x0000 }, /* R1350 */
+ { 0x0000, 0x0000 }, /* R1351 */
+ { 0x0000, 0x0000 }, /* R1352 */
+ { 0x0000, 0x0000 }, /* R1353 */
+ { 0x0000, 0x0000 }, /* R1354 */
+ { 0x0000, 0x0000 }, /* R1355 */
+ { 0x0000, 0x0000 }, /* R1356 */
+ { 0x0000, 0x0000 }, /* R1357 */
+ { 0x0000, 0x0000 }, /* R1358 */
+ { 0x0000, 0x0000 }, /* R1359 */
+ { 0x0000, 0x0000 }, /* R1360 */
+ { 0x0000, 0x0000 }, /* R1361 */
+ { 0x0000, 0x0000 }, /* R1362 */
+ { 0x0000, 0x0000 }, /* R1363 */
+ { 0x0000, 0x0000 }, /* R1364 */
+ { 0x0000, 0x0000 }, /* R1365 */
+ { 0x0000, 0x0000 }, /* R1366 */
+ { 0x0000, 0x0000 }, /* R1367 */
+ { 0x0000, 0x0000 }, /* R1368 */
+ { 0x0000, 0x0000 }, /* R1369 */
+ { 0x0000, 0x0000 }, /* R1370 */
+ { 0x0000, 0x0000 }, /* R1371 */
+ { 0x0000, 0x0000 }, /* R1372 */
+ { 0x0000, 0x0000 }, /* R1373 */
+ { 0x0000, 0x0000 }, /* R1374 */
+ { 0x0000, 0x0000 }, /* R1375 */
+ { 0x0000, 0x0000 }, /* R1376 */
+ { 0x0000, 0x0000 }, /* R1377 */
+ { 0x0000, 0x0000 }, /* R1378 */
+ { 0x0000, 0x0000 }, /* R1379 */
+ { 0x0000, 0x0000 }, /* R1380 */
+ { 0x0000, 0x0000 }, /* R1381 */
+ { 0x0000, 0x0000 }, /* R1382 */
+ { 0x0000, 0x0000 }, /* R1383 */
+ { 0x0000, 0x0000 }, /* R1384 */
+ { 0x0000, 0x0000 }, /* R1385 */
+ { 0x0000, 0x0000 }, /* R1386 */
+ { 0x0000, 0x0000 }, /* R1387 */
+ { 0x0000, 0x0000 }, /* R1388 */
+ { 0x0000, 0x0000 }, /* R1389 */
+ { 0x0000, 0x0000 }, /* R1390 */
+ { 0x0000, 0x0000 }, /* R1391 */
+ { 0x0000, 0x0000 }, /* R1392 */
+ { 0x0000, 0x0000 }, /* R1393 */
+ { 0x0000, 0x0000 }, /* R1394 */
+ { 0x0000, 0x0000 }, /* R1395 */
+ { 0x0000, 0x0000 }, /* R1396 */
+ { 0x0000, 0x0000 }, /* R1397 */
+ { 0x0000, 0x0000 }, /* R1398 */
+ { 0x0000, 0x0000 }, /* R1399 */
+ { 0x0000, 0x0000 }, /* R1400 */
+ { 0x0000, 0x0000 }, /* R1401 */
+ { 0x0000, 0x0000 }, /* R1402 */
+ { 0x0000, 0x0000 }, /* R1403 */
+ { 0x0000, 0x0000 }, /* R1404 */
+ { 0x0000, 0x0000 }, /* R1405 */
+ { 0x0000, 0x0000 }, /* R1406 */
+ { 0x0000, 0x0000 }, /* R1407 */
+ { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1428 */
+ { 0x0000, 0x0000 }, /* R1429 */
+ { 0x0000, 0x0000 }, /* R1430 */
+ { 0x0000, 0x0000 }, /* R1431 */
+ { 0x0000, 0x0000 }, /* R1432 */
+ { 0x0000, 0x0000 }, /* R1433 */
+ { 0x0000, 0x0000 }, /* R1434 */
+ { 0x0000, 0x0000 }, /* R1435 */
+ { 0x0000, 0x0000 }, /* R1436 */
+ { 0x0000, 0x0000 }, /* R1437 */
+ { 0x0000, 0x0000 }, /* R1438 */
+ { 0x0000, 0x0000 }, /* R1439 */
+ { 0x0000, 0x0000 }, /* R1440 */
+ { 0x0000, 0x0000 }, /* R1441 */
+ { 0x0000, 0x0000 }, /* R1442 */
+ { 0x0000, 0x0000 }, /* R1443 */
+ { 0x0000, 0x0000 }, /* R1444 */
+ { 0x0000, 0x0000 }, /* R1445 */
+ { 0x0000, 0x0000 }, /* R1446 */
+ { 0x0000, 0x0000 }, /* R1447 */
+ { 0x0000, 0x0000 }, /* R1448 */
+ { 0x0000, 0x0000 }, /* R1449 */
+ { 0x0000, 0x0000 }, /* R1450 */
+ { 0x0000, 0x0000 }, /* R1451 */
+ { 0x0000, 0x0000 }, /* R1452 */
+ { 0x0000, 0x0000 }, /* R1453 */
+ { 0x0000, 0x0000 }, /* R1454 */
+ { 0x0000, 0x0000 }, /* R1455 */
+ { 0x0000, 0x0000 }, /* R1456 */
+ { 0x0000, 0x0000 }, /* R1457 */
+ { 0x0000, 0x0000 }, /* R1458 */
+ { 0x0000, 0x0000 }, /* R1459 */
+ { 0x0000, 0x0000 }, /* R1460 */
+ { 0x0000, 0x0000 }, /* R1461 */
+ { 0x0000, 0x0000 }, /* R1462 */
+ { 0x0000, 0x0000 }, /* R1463 */
+ { 0x0000, 0x0000 }, /* R1464 */
+ { 0x0000, 0x0000 }, /* R1465 */
+ { 0x0000, 0x0000 }, /* R1466 */
+ { 0x0000, 0x0000 }, /* R1467 */
+ { 0x0000, 0x0000 }, /* R1468 */
+ { 0x0000, 0x0000 }, /* R1469 */
+ { 0x0000, 0x0000 }, /* R1470 */
+ { 0x0000, 0x0000 }, /* R1471 */
+ { 0x0000, 0x0000 }, /* R1472 */
+ { 0x0000, 0x0000 }, /* R1473 */
+ { 0x0000, 0x0000 }, /* R1474 */
+ { 0x0000, 0x0000 }, /* R1475 */
+ { 0x0000, 0x0000 }, /* R1476 */
+ { 0x0000, 0x0000 }, /* R1477 */
+ { 0x0000, 0x0000 }, /* R1478 */
+ { 0x0000, 0x0000 }, /* R1479 */
+ { 0x0000, 0x0000 }, /* R1480 */
+ { 0x0000, 0x0000 }, /* R1481 */
+ { 0x0000, 0x0000 }, /* R1482 */
+ { 0x0000, 0x0000 }, /* R1483 */
+ { 0x0000, 0x0000 }, /* R1484 */
+ { 0x0000, 0x0000 }, /* R1485 */
+ { 0x0000, 0x0000 }, /* R1486 */
+ { 0x0000, 0x0000 }, /* R1487 */
+ { 0x0000, 0x0000 }, /* R1488 */
+ { 0x0000, 0x0000 }, /* R1489 */
+ { 0x0000, 0x0000 }, /* R1490 */
+ { 0x0000, 0x0000 }, /* R1491 */
+ { 0x0000, 0x0000 }, /* R1492 */
+ { 0x0000, 0x0000 }, /* R1493 */
+ { 0x0000, 0x0000 }, /* R1494 */
+ { 0x0000, 0x0000 }, /* R1495 */
+ { 0x0000, 0x0000 }, /* R1496 */
+ { 0x0000, 0x0000 }, /* R1497 */
+ { 0x0000, 0x0000 }, /* R1498 */
+ { 0x0000, 0x0000 }, /* R1499 */
+ { 0x0000, 0x0000 }, /* R1500 */
+ { 0x0000, 0x0000 }, /* R1501 */
+ { 0x0000, 0x0000 }, /* R1502 */
+ { 0x0000, 0x0000 }, /* R1503 */
+ { 0x0000, 0x0000 }, /* R1504 */
+ { 0x0000, 0x0000 }, /* R1505 */
+ { 0x0000, 0x0000 }, /* R1506 */
+ { 0x0000, 0x0000 }, /* R1507 */
+ { 0x0000, 0x0000 }, /* R1508 */
+ { 0x0000, 0x0000 }, /* R1509 */
+ { 0x0000, 0x0000 }, /* R1510 */
+ { 0x0000, 0x0000 }, /* R1511 */
+ { 0x0000, 0x0000 }, /* R1512 */
+ { 0x0000, 0x0000 }, /* R1513 */
+ { 0x0000, 0x0000 }, /* R1514 */
+ { 0x0000, 0x0000 }, /* R1515 */
+ { 0x0000, 0x0000 }, /* R1516 */
+ { 0x0000, 0x0000 }, /* R1517 */
+ { 0x0000, 0x0000 }, /* R1518 */
+ { 0x0000, 0x0000 }, /* R1519 */
+ { 0x0000, 0x0000 }, /* R1520 */
+ { 0x0000, 0x0000 }, /* R1521 */
+ { 0x0000, 0x0000 }, /* R1522 */
+ { 0x0000, 0x0000 }, /* R1523 */
+ { 0x0000, 0x0000 }, /* R1524 */
+ { 0x0000, 0x0000 }, /* R1525 */
+ { 0x0000, 0x0000 }, /* R1526 */
+ { 0x0000, 0x0000 }, /* R1527 */
+ { 0x0000, 0x0000 }, /* R1528 */
+ { 0x0000, 0x0000 }, /* R1529 */
+ { 0x0000, 0x0000 }, /* R1530 */
+ { 0x0000, 0x0000 }, /* R1531 */
+ { 0x0000, 0x0000 }, /* R1532 */
+ { 0x0000, 0x0000 }, /* R1533 */
+ { 0x0000, 0x0000 }, /* R1534 */
+ { 0x0000, 0x0000 }, /* R1535 */
+ { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ { 0x0000, 0x0000 }, /* R1546 */
+ { 0x0000, 0x0000 }, /* R1547 */
+ { 0x0000, 0x0000 }, /* R1548 */
+ { 0x0000, 0x0000 }, /* R1549 */
+ { 0x0000, 0x0000 }, /* R1550 */
+ { 0x0000, 0x0000 }, /* R1551 */
+ { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
+ { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
+ { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
+ { 0x0000, 0x0000 }, /* R1557 */
+ { 0x0000, 0x0000 }, /* R1558 */
+ { 0x0000, 0x0000 }, /* R1559 */
+ { 0x0000, 0x0000 }, /* R1560 */
+ { 0x0000, 0x0000 }, /* R1561 */
+ { 0x0000, 0x0000 }, /* R1562 */
+ { 0x0000, 0x0000 }, /* R1563 */
+ { 0x0000, 0x0000 }, /* R1564 */
+ { 0x0000, 0x0000 }, /* R1565 */
+ { 0x0000, 0x0000 }, /* R1566 */
+ { 0x0000, 0x0000 }, /* R1567 */
+ { 0x0003, 0x0003 }, /* R1568 - Oversampling */
+ { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
+};
+
+const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
+ 0x8994, /* R0 - Software Reset */
+ 0x0000, /* R1 - Power Management (1) */
+ 0x6000, /* R2 - Power Management (2) */
+ 0x0000, /* R3 - Power Management (3) */
+ 0x0000, /* R4 - Power Management (4) */
+ 0x0000, /* R5 - Power Management (5) */
+ 0x0000, /* R6 - Power Management (6) */
+ 0x0000, /* R7 */
+ 0x0000, /* R8 */
+ 0x0000, /* R9 */
+ 0x0000, /* R10 */
+ 0x0000, /* R11 */
+ 0x0000, /* R12 */
+ 0x0000, /* R13 */
+ 0x0000, /* R14 */
+ 0x0000, /* R15 */
+ 0x0000, /* R16 */
+ 0x0000, /* R17 */
+ 0x0000, /* R18 */
+ 0x0000, /* R19 */
+ 0x0000, /* R20 */
+ 0x0000, /* R21 - Input Mixer (1) */
+ 0x0000, /* R22 */
+ 0x0000, /* R23 */
+ 0x008B, /* R24 - Left Line Input 1&2 Volume */
+ 0x008B, /* R25 - Left Line Input 3&4 Volume */
+ 0x008B, /* R26 - Right Line Input 1&2 Volume */
+ 0x008B, /* R27 - Right Line Input 3&4 Volume */
+ 0x006D, /* R28 - Left Output Volume */
+ 0x006D, /* R29 - Right Output Volume */
+ 0x0066, /* R30 - Line Outputs Volume */
+ 0x0020, /* R31 - HPOUT2 Volume */
+ 0x0079, /* R32 - Left OPGA Volume */
+ 0x0079, /* R33 - Right OPGA Volume */
+ 0x0003, /* R34 - SPKMIXL Attenuation */
+ 0x0003, /* R35 - SPKMIXR Attenuation */
+ 0x0011, /* R36 - SPKOUT Mixers */
+ 0x0140, /* R37 - ClassD */
+ 0x0079, /* R38 - Speaker Volume Left */
+ 0x0079, /* R39 - Speaker Volume Right */
+ 0x0000, /* R40 - Input Mixer (2) */
+ 0x0000, /* R41 - Input Mixer (3) */
+ 0x0000, /* R42 - Input Mixer (4) */
+ 0x0000, /* R43 - Input Mixer (5) */
+ 0x0000, /* R44 - Input Mixer (6) */
+ 0x0000, /* R45 - Output Mixer (1) */
+ 0x0000, /* R46 - Output Mixer (2) */
+ 0x0000, /* R47 - Output Mixer (3) */
+ 0x0000, /* R48 - Output Mixer (4) */
+ 0x0000, /* R49 - Output Mixer (5) */
+ 0x0000, /* R50 - Output Mixer (6) */
+ 0x0000, /* R51 - HPOUT2 Mixer */
+ 0x0000, /* R52 - Line Mixer (1) */
+ 0x0000, /* R53 - Line Mixer (2) */
+ 0x0000, /* R54 - Speaker Mixer */
+ 0x0000, /* R55 - Additional Control */
+ 0x0000, /* R56 - AntiPOP (1) */
+ 0x0000, /* R57 - AntiPOP (2) */
+ 0x0000, /* R58 - MICBIAS */
+ 0x000D, /* R59 - LDO 1 */
+ 0x0003, /* R60 - LDO 2 */
+ 0x0000, /* R61 */
+ 0x0000, /* R62 */
+ 0x0000, /* R63 */
+ 0x0000, /* R64 */
+ 0x0000, /* R65 */
+ 0x0000, /* R66 */
+ 0x0000, /* R67 */
+ 0x0000, /* R68 */
+ 0x0000, /* R69 */
+ 0x0000, /* R70 */
+ 0x0000, /* R71 */
+ 0x0000, /* R72 */
+ 0x0000, /* R73 */
+ 0x0000, /* R74 */
+ 0x0000, /* R75 */
+ 0x1F25, /* R76 - Charge Pump (1) */
+ 0x0000, /* R77 */
+ 0x0000, /* R78 */
+ 0x0000, /* R79 */
+ 0x0000, /* R80 */
+ 0x0004, /* R81 - Class W (1) */
+ 0x0000, /* R82 */
+ 0x0000, /* R83 */
+ 0x0000, /* R84 - DC Servo (1) */
+ 0x054A, /* R85 - DC Servo (2) */
+ 0x0000, /* R86 */
+ 0x0000, /* R87 - DC Servo (4) */
+ 0x0000, /* R88 - DC Servo Readback */
+ 0x0000, /* R89 */
+ 0x0000, /* R90 */
+ 0x0000, /* R91 */
+ 0x0000, /* R92 */
+ 0x0000, /* R93 */
+ 0x0000, /* R94 */
+ 0x0000, /* R95 */
+ 0x0000, /* R96 - Analogue HP (1) */
+ 0x0000, /* R97 */
+ 0x0000, /* R98 */
+ 0x0000, /* R99 */
+ 0x0000, /* R100 */
+ 0x0000, /* R101 */
+ 0x0000, /* R102 */
+ 0x0000, /* R103 */
+ 0x0000, /* R104 */
+ 0x0000, /* R105 */
+ 0x0000, /* R106 */
+ 0x0000, /* R107 */
+ 0x0000, /* R108 */
+ 0x0000, /* R109 */
+ 0x0000, /* R110 */
+ 0x0000, /* R111 */
+ 0x0000, /* R112 */
+ 0x0000, /* R113 */
+ 0x0000, /* R114 */
+ 0x0000, /* R115 */
+ 0x0000, /* R116 */
+ 0x0000, /* R117 */
+ 0x0000, /* R118 */
+ 0x0000, /* R119 */
+ 0x0000, /* R120 */
+ 0x0000, /* R121 */
+ 0x0000, /* R122 */
+ 0x0000, /* R123 */
+ 0x0000, /* R124 */
+ 0x0000, /* R125 */
+ 0x0000, /* R126 */
+ 0x0000, /* R127 */
+ 0x0000, /* R128 */
+ 0x0000, /* R129 */
+ 0x0000, /* R130 */
+ 0x0000, /* R131 */
+ 0x0000, /* R132 */
+ 0x0000, /* R133 */
+ 0x0000, /* R134 */
+ 0x0000, /* R135 */
+ 0x0000, /* R136 */
+ 0x0000, /* R137 */
+ 0x0000, /* R138 */
+ 0x0000, /* R139 */
+ 0x0000, /* R140 */
+ 0x0000, /* R141 */
+ 0x0000, /* R142 */
+ 0x0000, /* R143 */
+ 0x0000, /* R144 */
+ 0x0000, /* R145 */
+ 0x0000, /* R146 */
+ 0x0000, /* R147 */
+ 0x0000, /* R148 */
+ 0x0000, /* R149 */
+ 0x0000, /* R150 */
+ 0x0000, /* R151 */
+ 0x0000, /* R152 */
+ 0x0000, /* R153 */
+ 0x0000, /* R154 */
+ 0x0000, /* R155 */
+ 0x0000, /* R156 */
+ 0x0000, /* R157 */
+ 0x0000, /* R158 */
+ 0x0000, /* R159 */
+ 0x0000, /* R160 */
+ 0x0000, /* R161 */
+ 0x0000, /* R162 */
+ 0x0000, /* R163 */
+ 0x0000, /* R164 */
+ 0x0000, /* R165 */
+ 0x0000, /* R166 */
+ 0x0000, /* R167 */
+ 0x0000, /* R168 */
+ 0x0000, /* R169 */
+ 0x0000, /* R170 */
+ 0x0000, /* R171 */
+ 0x0000, /* R172 */
+ 0x0000, /* R173 */
+ 0x0000, /* R174 */
+ 0x0000, /* R175 */
+ 0x0000, /* R176 */
+ 0x0000, /* R177 */
+ 0x0000, /* R178 */
+ 0x0000, /* R179 */
+ 0x0000, /* R180 */
+ 0x0000, /* R181 */
+ 0x0000, /* R182 */
+ 0x0000, /* R183 */
+ 0x0000, /* R184 */
+ 0x0000, /* R185 */
+ 0x0000, /* R186 */
+ 0x0000, /* R187 */
+ 0x0000, /* R188 */
+ 0x0000, /* R189 */
+ 0x0000, /* R190 */
+ 0x0000, /* R191 */
+ 0x0000, /* R192 */
+ 0x0000, /* R193 */
+ 0x0000, /* R194 */
+ 0x0000, /* R195 */
+ 0x0000, /* R196 */
+ 0x0000, /* R197 */
+ 0x0000, /* R198 */
+ 0x0000, /* R199 */
+ 0x0000, /* R200 */
+ 0x0000, /* R201 */
+ 0x0000, /* R202 */
+ 0x0000, /* R203 */
+ 0x0000, /* R204 */
+ 0x0000, /* R205 */
+ 0x0000, /* R206 */
+ 0x0000, /* R207 */
+ 0x0000, /* R208 */
+ 0x0000, /* R209 */
+ 0x0000, /* R210 */
+ 0x0000, /* R211 */
+ 0x0000, /* R212 */
+ 0x0000, /* R213 */
+ 0x0000, /* R214 */
+ 0x0000, /* R215 */
+ 0x0000, /* R216 */
+ 0x0000, /* R217 */
+ 0x0000, /* R218 */
+ 0x0000, /* R219 */
+ 0x0000, /* R220 */
+ 0x0000, /* R221 */
+ 0x0000, /* R222 */
+ 0x0000, /* R223 */
+ 0x0000, /* R224 */
+ 0x0000, /* R225 */
+ 0x0000, /* R226 */
+ 0x0000, /* R227 */
+ 0x0000, /* R228 */
+ 0x0000, /* R229 */
+ 0x0000, /* R230 */
+ 0x0000, /* R231 */
+ 0x0000, /* R232 */
+ 0x0000, /* R233 */
+ 0x0000, /* R234 */
+ 0x0000, /* R235 */
+ 0x0000, /* R236 */
+ 0x0000, /* R237 */
+ 0x0000, /* R238 */
+ 0x0000, /* R239 */
+ 0x0000, /* R240 */
+ 0x0000, /* R241 */
+ 0x0000, /* R242 */
+ 0x0000, /* R243 */
+ 0x0000, /* R244 */
+ 0x0000, /* R245 */
+ 0x0000, /* R246 */
+ 0x0000, /* R247 */
+ 0x0000, /* R248 */
+ 0x0000, /* R249 */
+ 0x0000, /* R250 */
+ 0x0000, /* R251 */
+ 0x0000, /* R252 */
+ 0x0000, /* R253 */
+ 0x0000, /* R254 */
+ 0x0000, /* R255 */
+ 0x0003, /* R256 - Chip Revision */
+ 0x8004, /* R257 - Control Interface */
+ 0x0000, /* R258 */
+ 0x0000, /* R259 */
+ 0x0000, /* R260 */
+ 0x0000, /* R261 */
+ 0x0000, /* R262 */
+ 0x0000, /* R263 */
+ 0x0000, /* R264 */
+ 0x0000, /* R265 */
+ 0x0000, /* R266 */
+ 0x0000, /* R267 */
+ 0x0000, /* R268 */
+ 0x0000, /* R269 */
+ 0x0000, /* R270 */
+ 0x0000, /* R271 */
+ 0x0000, /* R272 - Write Sequencer Ctrl (1) */
+ 0x0000, /* R273 - Write Sequencer Ctrl (2) */
+ 0x0000, /* R274 */
+ 0x0000, /* R275 */
+ 0x0000, /* R276 */
+ 0x0000, /* R277 */
+ 0x0000, /* R278 */
+ 0x0000, /* R279 */
+ 0x0000, /* R280 */
+ 0x0000, /* R281 */
+ 0x0000, /* R282 */
+ 0x0000, /* R283 */
+ 0x0000, /* R284 */
+ 0x0000, /* R285 */
+ 0x0000, /* R286 */
+ 0x0000, /* R287 */
+ 0x0000, /* R288 */
+ 0x0000, /* R289 */
+ 0x0000, /* R290 */
+ 0x0000, /* R291 */
+ 0x0000, /* R292 */
+ 0x0000, /* R293 */
+ 0x0000, /* R294 */
+ 0x0000, /* R295 */
+ 0x0000, /* R296 */
+ 0x0000, /* R297 */
+ 0x0000, /* R298 */
+ 0x0000, /* R299 */
+ 0x0000, /* R300 */
+ 0x0000, /* R301 */
+ 0x0000, /* R302 */
+ 0x0000, /* R303 */
+ 0x0000, /* R304 */
+ 0x0000, /* R305 */
+ 0x0000, /* R306 */
+ 0x0000, /* R307 */
+ 0x0000, /* R308 */
+ 0x0000, /* R309 */
+ 0x0000, /* R310 */
+ 0x0000, /* R311 */
+ 0x0000, /* R312 */
+ 0x0000, /* R313 */
+ 0x0000, /* R314 */
+ 0x0000, /* R315 */
+ 0x0000, /* R316 */
+ 0x0000, /* R317 */
+ 0x0000, /* R318 */
+ 0x0000, /* R319 */
+ 0x0000, /* R320 */
+ 0x0000, /* R321 */
+ 0x0000, /* R322 */
+ 0x0000, /* R323 */
+ 0x0000, /* R324 */
+ 0x0000, /* R325 */
+ 0x0000, /* R326 */
+ 0x0000, /* R327 */
+ 0x0000, /* R328 */
+ 0x0000, /* R329 */
+ 0x0000, /* R330 */
+ 0x0000, /* R331 */
+ 0x0000, /* R332 */
+ 0x0000, /* R333 */
+ 0x0000, /* R334 */
+ 0x0000, /* R335 */
+ 0x0000, /* R336 */
+ 0x0000, /* R337 */
+ 0x0000, /* R338 */
+ 0x0000, /* R339 */
+ 0x0000, /* R340 */
+ 0x0000, /* R341 */
+ 0x0000, /* R342 */
+ 0x0000, /* R343 */
+ 0x0000, /* R344 */
+ 0x0000, /* R345 */
+ 0x0000, /* R346 */
+ 0x0000, /* R347 */
+ 0x0000, /* R348 */
+ 0x0000, /* R349 */
+ 0x0000, /* R350 */
+ 0x0000, /* R351 */
+ 0x0000, /* R352 */
+ 0x0000, /* R353 */
+ 0x0000, /* R354 */
+ 0x0000, /* R355 */
+ 0x0000, /* R356 */
+ 0x0000, /* R357 */
+ 0x0000, /* R358 */
+ 0x0000, /* R359 */
+ 0x0000, /* R360 */
+ 0x0000, /* R361 */
+ 0x0000, /* R362 */
+ 0x0000, /* R363 */
+ 0x0000, /* R364 */
+ 0x0000, /* R365 */
+ 0x0000, /* R366 */
+ 0x0000, /* R367 */
+ 0x0000, /* R368 */
+ 0x0000, /* R369 */
+ 0x0000, /* R370 */
+ 0x0000, /* R371 */
+ 0x0000, /* R372 */
+ 0x0000, /* R373 */
+ 0x0000, /* R374 */
+ 0x0000, /* R375 */
+ 0x0000, /* R376 */
+ 0x0000, /* R377 */
+ 0x0000, /* R378 */
+ 0x0000, /* R379 */
+ 0x0000, /* R380 */
+ 0x0000, /* R381 */
+ 0x0000, /* R382 */
+ 0x0000, /* R383 */
+ 0x0000, /* R384 */
+ 0x0000, /* R385 */
+ 0x0000, /* R386 */
+ 0x0000, /* R387 */
+ 0x0000, /* R388 */
+ 0x0000, /* R389 */
+ 0x0000, /* R390 */
+ 0x0000, /* R391 */
+ 0x0000, /* R392 */
+ 0x0000, /* R393 */
+ 0x0000, /* R394 */
+ 0x0000, /* R395 */
+ 0x0000, /* R396 */
+ 0x0000, /* R397 */
+ 0x0000, /* R398 */
+ 0x0000, /* R399 */
+ 0x0000, /* R400 */
+ 0x0000, /* R401 */
+ 0x0000, /* R402 */
+ 0x0000, /* R403 */
+ 0x0000, /* R404 */
+ 0x0000, /* R405 */
+ 0x0000, /* R406 */
+ 0x0000, /* R407 */
+ 0x0000, /* R408 */
+ 0x0000, /* R409 */
+ 0x0000, /* R410 */
+ 0x0000, /* R411 */
+ 0x0000, /* R412 */
+ 0x0000, /* R413 */
+ 0x0000, /* R414 */
+ 0x0000, /* R415 */
+ 0x0000, /* R416 */
+ 0x0000, /* R417 */
+ 0x0000, /* R418 */
+ 0x0000, /* R419 */
+ 0x0000, /* R420 */
+ 0x0000, /* R421 */
+ 0x0000, /* R422 */
+ 0x0000, /* R423 */
+ 0x0000, /* R424 */
+ 0x0000, /* R425 */
+ 0x0000, /* R426 */
+ 0x0000, /* R427 */
+ 0x0000, /* R428 */
+ 0x0000, /* R429 */
+ 0x0000, /* R430 */
+ 0x0000, /* R431 */
+ 0x0000, /* R432 */
+ 0x0000, /* R433 */
+ 0x0000, /* R434 */
+ 0x0000, /* R435 */
+ 0x0000, /* R436 */
+ 0x0000, /* R437 */
+ 0x0000, /* R438 */
+ 0x0000, /* R439 */
+ 0x0000, /* R440 */
+ 0x0000, /* R441 */
+ 0x0000, /* R442 */
+ 0x0000, /* R443 */
+ 0x0000, /* R444 */
+ 0x0000, /* R445 */
+ 0x0000, /* R446 */
+ 0x0000, /* R447 */
+ 0x0000, /* R448 */
+ 0x0000, /* R449 */
+ 0x0000, /* R450 */
+ 0x0000, /* R451 */
+ 0x0000, /* R452 */
+ 0x0000, /* R453 */
+ 0x0000, /* R454 */
+ 0x0000, /* R455 */
+ 0x0000, /* R456 */
+ 0x0000, /* R457 */
+ 0x0000, /* R458 */
+ 0x0000, /* R459 */
+ 0x0000, /* R460 */
+ 0x0000, /* R461 */
+ 0x0000, /* R462 */
+ 0x0000, /* R463 */
+ 0x0000, /* R464 */
+ 0x0000, /* R465 */
+ 0x0000, /* R466 */
+ 0x0000, /* R467 */
+ 0x0000, /* R468 */
+ 0x0000, /* R469 */
+ 0x0000, /* R470 */
+ 0x0000, /* R471 */
+ 0x0000, /* R472 */
+ 0x0000, /* R473 */
+ 0x0000, /* R474 */
+ 0x0000, /* R475 */
+ 0x0000, /* R476 */
+ 0x0000, /* R477 */
+ 0x0000, /* R478 */
+ 0x0000, /* R479 */
+ 0x0000, /* R480 */
+ 0x0000, /* R481 */
+ 0x0000, /* R482 */
+ 0x0000, /* R483 */
+ 0x0000, /* R484 */
+ 0x0000, /* R485 */
+ 0x0000, /* R486 */
+ 0x0000, /* R487 */
+ 0x0000, /* R488 */
+ 0x0000, /* R489 */
+ 0x0000, /* R490 */
+ 0x0000, /* R491 */
+ 0x0000, /* R492 */
+ 0x0000, /* R493 */
+ 0x0000, /* R494 */
+ 0x0000, /* R495 */
+ 0x0000, /* R496 */
+ 0x0000, /* R497 */
+ 0x0000, /* R498 */
+ 0x0000, /* R499 */
+ 0x0000, /* R500 */
+ 0x0000, /* R501 */
+ 0x0000, /* R502 */
+ 0x0000, /* R503 */
+ 0x0000, /* R504 */
+ 0x0000, /* R505 */
+ 0x0000, /* R506 */
+ 0x0000, /* R507 */
+ 0x0000, /* R508 */
+ 0x0000, /* R509 */
+ 0x0000, /* R510 */
+ 0x0000, /* R511 */
+ 0x0000, /* R512 - AIF1 Clocking (1) */
+ 0x0000, /* R513 - AIF1 Clocking (2) */
+ 0x0000, /* R514 */
+ 0x0000, /* R515 */
+ 0x0000, /* R516 - AIF2 Clocking (1) */
+ 0x0000, /* R517 - AIF2 Clocking (2) */
+ 0x0000, /* R518 */
+ 0x0000, /* R519 */
+ 0x0000, /* R520 - Clocking (1) */
+ 0x0000, /* R521 - Clocking (2) */
+ 0x0000, /* R522 */
+ 0x0000, /* R523 */
+ 0x0000, /* R524 */
+ 0x0000, /* R525 */
+ 0x0000, /* R526 */
+ 0x0000, /* R527 */
+ 0x0083, /* R528 - AIF1 Rate */
+ 0x0083, /* R529 - AIF2 Rate */
+ 0x0000, /* R530 - Rate Status */
+ 0x0000, /* R531 */
+ 0x0000, /* R532 */
+ 0x0000, /* R533 */
+ 0x0000, /* R534 */
+ 0x0000, /* R535 */
+ 0x0000, /* R536 */
+ 0x0000, /* R537 */
+ 0x0000, /* R538 */
+ 0x0000, /* R539 */
+ 0x0000, /* R540 */
+ 0x0000, /* R541 */
+ 0x0000, /* R542 */
+ 0x0000, /* R543 */
+ 0x0000, /* R544 - FLL1 Control (1) */
+ 0x0000, /* R545 - FLL1 Control (2) */
+ 0x0000, /* R546 - FLL1 Control (3) */
+ 0x0000, /* R547 - FLL1 Control (4) */
+ 0x0C80, /* R548 - FLL1 Control (5) */
+ 0x0000, /* R549 */
+ 0x0000, /* R550 */
+ 0x0000, /* R551 */
+ 0x0000, /* R552 */
+ 0x0000, /* R553 */
+ 0x0000, /* R554 */
+ 0x0000, /* R555 */
+ 0x0000, /* R556 */
+ 0x0000, /* R557 */
+ 0x0000, /* R558 */
+ 0x0000, /* R559 */
+ 0x0000, /* R560 */
+ 0x0000, /* R561 */
+ 0x0000, /* R562 */
+ 0x0000, /* R563 */
+ 0x0000, /* R564 */
+ 0x0000, /* R565 */
+ 0x0000, /* R566 */
+ 0x0000, /* R567 */
+ 0x0000, /* R568 */
+ 0x0000, /* R569 */
+ 0x0000, /* R570 */
+ 0x0000, /* R571 */
+ 0x0000, /* R572 */
+ 0x0000, /* R573 */
+ 0x0000, /* R574 */
+ 0x0000, /* R575 */
+ 0x0000, /* R576 - FLL2 Control (1) */
+ 0x0000, /* R577 - FLL2 Control (2) */
+ 0x0000, /* R578 - FLL2 Control (3) */
+ 0x0000, /* R579 - FLL2 Control (4) */
+ 0x0C80, /* R580 - FLL2 Control (5) */
+ 0x0000, /* R581 */
+ 0x0000, /* R582 */
+ 0x0000, /* R583 */
+ 0x0000, /* R584 */
+ 0x0000, /* R585 */
+ 0x0000, /* R586 */
+ 0x0000, /* R587 */
+ 0x0000, /* R588 */
+ 0x0000, /* R589 */
+ 0x0000, /* R590 */
+ 0x0000, /* R591 */
+ 0x0000, /* R592 */
+ 0x0000, /* R593 */
+ 0x0000, /* R594 */
+ 0x0000, /* R595 */
+ 0x0000, /* R596 */
+ 0x0000, /* R597 */
+ 0x0000, /* R598 */
+ 0x0000, /* R599 */
+ 0x0000, /* R600 */
+ 0x0000, /* R601 */
+ 0x0000, /* R602 */
+ 0x0000, /* R603 */
+ 0x0000, /* R604 */
+ 0x0000, /* R605 */
+ 0x0000, /* R606 */
+ 0x0000, /* R607 */
+ 0x0000, /* R608 */
+ 0x0000, /* R609 */
+ 0x0000, /* R610 */
+ 0x0000, /* R611 */
+ 0x0000, /* R612 */
+ 0x0000, /* R613 */
+ 0x0000, /* R614 */
+ 0x0000, /* R615 */
+ 0x0000, /* R616 */
+ 0x0000, /* R617 */
+ 0x0000, /* R618 */
+ 0x0000, /* R619 */
+ 0x0000, /* R620 */
+ 0x0000, /* R621 */
+ 0x0000, /* R622 */
+ 0x0000, /* R623 */
+ 0x0000, /* R624 */
+ 0x0000, /* R625 */
+ 0x0000, /* R626 */
+ 0x0000, /* R627 */
+ 0x0000, /* R628 */
+ 0x0000, /* R629 */
+ 0x0000, /* R630 */
+ 0x0000, /* R631 */
+ 0x0000, /* R632 */
+ 0x0000, /* R633 */
+ 0x0000, /* R634 */
+ 0x0000, /* R635 */
+ 0x0000, /* R636 */
+ 0x0000, /* R637 */
+ 0x0000, /* R638 */
+ 0x0000, /* R639 */
+ 0x0000, /* R640 */
+ 0x0000, /* R641 */
+ 0x0000, /* R642 */
+ 0x0000, /* R643 */
+ 0x0000, /* R644 */
+ 0x0000, /* R645 */
+ 0x0000, /* R646 */
+ 0x0000, /* R647 */
+ 0x0000, /* R648 */
+ 0x0000, /* R649 */
+ 0x0000, /* R650 */
+ 0x0000, /* R651 */
+ 0x0000, /* R652 */
+ 0x0000, /* R653 */
+ 0x0000, /* R654 */
+ 0x0000, /* R655 */
+ 0x0000, /* R656 */
+ 0x0000, /* R657 */
+ 0x0000, /* R658 */
+ 0x0000, /* R659 */
+ 0x0000, /* R660 */
+ 0x0000, /* R661 */
+ 0x0000, /* R662 */
+ 0x0000, /* R663 */
+ 0x0000, /* R664 */
+ 0x0000, /* R665 */
+ 0x0000, /* R666 */
+ 0x0000, /* R667 */
+ 0x0000, /* R668 */
+ 0x0000, /* R669 */
+ 0x0000, /* R670 */
+ 0x0000, /* R671 */
+ 0x0000, /* R672 */
+ 0x0000, /* R673 */
+ 0x0000, /* R674 */
+ 0x0000, /* R675 */
+ 0x0000, /* R676 */
+ 0x0000, /* R677 */
+ 0x0000, /* R678 */
+ 0x0000, /* R679 */
+ 0x0000, /* R680 */
+ 0x0000, /* R681 */
+ 0x0000, /* R682 */
+ 0x0000, /* R683 */
+ 0x0000, /* R684 */
+ 0x0000, /* R685 */
+ 0x0000, /* R686 */
+ 0x0000, /* R687 */
+ 0x0000, /* R688 */
+ 0x0000, /* R689 */
+ 0x0000, /* R690 */
+ 0x0000, /* R691 */
+ 0x0000, /* R692 */
+ 0x0000, /* R693 */
+ 0x0000, /* R694 */
+ 0x0000, /* R695 */
+ 0x0000, /* R696 */
+ 0x0000, /* R697 */
+ 0x0000, /* R698 */
+ 0x0000, /* R699 */
+ 0x0000, /* R700 */
+ 0x0000, /* R701 */
+ 0x0000, /* R702 */
+ 0x0000, /* R703 */
+ 0x0000, /* R704 */
+ 0x0000, /* R705 */
+ 0x0000, /* R706 */
+ 0x0000, /* R707 */
+ 0x0000, /* R708 */
+ 0x0000, /* R709 */
+ 0x0000, /* R710 */
+ 0x0000, /* R711 */
+ 0x0000, /* R712 */
+ 0x0000, /* R713 */
+ 0x0000, /* R714 */
+ 0x0000, /* R715 */
+ 0x0000, /* R716 */
+ 0x0000, /* R717 */
+ 0x0000, /* R718 */
+ 0x0000, /* R719 */
+ 0x0000, /* R720 */
+ 0x0000, /* R721 */
+ 0x0000, /* R722 */
+ 0x0000, /* R723 */
+ 0x0000, /* R724 */
+ 0x0000, /* R725 */
+ 0x0000, /* R726 */
+ 0x0000, /* R727 */
+ 0x0000, /* R728 */
+ 0x0000, /* R729 */
+ 0x0000, /* R730 */
+ 0x0000, /* R731 */
+ 0x0000, /* R732 */
+ 0x0000, /* R733 */
+ 0x0000, /* R734 */
+ 0x0000, /* R735 */
+ 0x0000, /* R736 */
+ 0x0000, /* R737 */
+ 0x0000, /* R738 */
+ 0x0000, /* R739 */
+ 0x0000, /* R740 */
+ 0x0000, /* R741 */
+ 0x0000, /* R742 */
+ 0x0000, /* R743 */
+ 0x0000, /* R744 */
+ 0x0000, /* R745 */
+ 0x0000, /* R746 */
+ 0x0000, /* R747 */
+ 0x0000, /* R748 */
+ 0x0000, /* R749 */
+ 0x0000, /* R750 */
+ 0x0000, /* R751 */
+ 0x0000, /* R752 */
+ 0x0000, /* R753 */
+ 0x0000, /* R754 */
+ 0x0000, /* R755 */
+ 0x0000, /* R756 */
+ 0x0000, /* R757 */
+ 0x0000, /* R758 */
+ 0x0000, /* R759 */
+ 0x0000, /* R760 */
+ 0x0000, /* R761 */
+ 0x0000, /* R762 */
+ 0x0000, /* R763 */
+ 0x0000, /* R764 */
+ 0x0000, /* R765 */
+ 0x0000, /* R766 */
+ 0x0000, /* R767 */
+ 0x4050, /* R768 - AIF1 Control (1) */
+ 0x4000, /* R769 - AIF1 Control (2) */
+ 0x0000, /* R770 - AIF1 Master/Slave */
+ 0x0040, /* R771 - AIF1 BCLK */
+ 0x0040, /* R772 - AIF1ADC LRCLK */
+ 0x0040, /* R773 - AIF1DAC LRCLK */
+ 0x0004, /* R774 - AIF1DAC Data */
+ 0x0100, /* R775 - AIF1ADC Data */
+ 0x0000, /* R776 */
+ 0x0000, /* R777 */
+ 0x0000, /* R778 */
+ 0x0000, /* R779 */
+ 0x0000, /* R780 */
+ 0x0000, /* R781 */
+ 0x0000, /* R782 */
+ 0x0000, /* R783 */
+ 0x4050, /* R784 - AIF2 Control (1) */
+ 0x4000, /* R785 - AIF2 Control (2) */
+ 0x0000, /* R786 - AIF2 Master/Slave */
+ 0x0040, /* R787 - AIF2 BCLK */
+ 0x0040, /* R788 - AIF2ADC LRCLK */
+ 0x0040, /* R789 - AIF2DAC LRCLK */
+ 0x0000, /* R790 - AIF2DAC Data */
+ 0x0000, /* R791 - AIF2ADC Data */
+ 0x0000, /* R792 */
+ 0x0000, /* R793 */
+ 0x0000, /* R794 */
+ 0x0000, /* R795 */
+ 0x0000, /* R796 */
+ 0x0000, /* R797 */
+ 0x0000, /* R798 */
+ 0x0000, /* R799 */
+ 0x0000, /* R800 */
+ 0x0000, /* R801 */
+ 0x0000, /* R802 */
+ 0x0000, /* R803 */
+ 0x0000, /* R804 */
+ 0x0000, /* R805 */
+ 0x0000, /* R806 */
+ 0x0000, /* R807 */
+ 0x0000, /* R808 */
+ 0x0000, /* R809 */
+ 0x0000, /* R810 */
+ 0x0000, /* R811 */
+ 0x0000, /* R812 */
+ 0x0000, /* R813 */
+ 0x0000, /* R814 */
+ 0x0000, /* R815 */
+ 0x0000, /* R816 */
+ 0x0000, /* R817 */
+ 0x0000, /* R818 */
+ 0x0000, /* R819 */
+ 0x0000, /* R820 */
+ 0x0000, /* R821 */
+ 0x0000, /* R822 */
+ 0x0000, /* R823 */
+ 0x0000, /* R824 */
+ 0x0000, /* R825 */
+ 0x0000, /* R826 */
+ 0x0000, /* R827 */
+ 0x0000, /* R828 */
+ 0x0000, /* R829 */
+ 0x0000, /* R830 */
+ 0x0000, /* R831 */
+ 0x0000, /* R832 */
+ 0x0000, /* R833 */
+ 0x0000, /* R834 */
+ 0x0000, /* R835 */
+ 0x0000, /* R836 */
+ 0x0000, /* R837 */
+ 0x0000, /* R838 */
+ 0x0000, /* R839 */
+ 0x0000, /* R840 */
+ 0x0000, /* R841 */
+ 0x0000, /* R842 */
+ 0x0000, /* R843 */
+ 0x0000, /* R844 */
+ 0x0000, /* R845 */
+ 0x0000, /* R846 */
+ 0x0000, /* R847 */
+ 0x0000, /* R848 */
+ 0x0000, /* R849 */
+ 0x0000, /* R850 */
+ 0x0000, /* R851 */
+ 0x0000, /* R852 */
+ 0x0000, /* R853 */
+ 0x0000, /* R854 */
+ 0x0000, /* R855 */
+ 0x0000, /* R856 */
+ 0x0000, /* R857 */
+ 0x0000, /* R858 */
+ 0x0000, /* R859 */
+ 0x0000, /* R860 */
+ 0x0000, /* R861 */
+ 0x0000, /* R862 */
+ 0x0000, /* R863 */
+ 0x0000, /* R864 */
+ 0x0000, /* R865 */
+ 0x0000, /* R866 */
+ 0x0000, /* R867 */
+ 0x0000, /* R868 */
+ 0x0000, /* R869 */
+ 0x0000, /* R870 */
+ 0x0000, /* R871 */
+ 0x0000, /* R872 */
+ 0x0000, /* R873 */
+ 0x0000, /* R874 */
+ 0x0000, /* R875 */
+ 0x0000, /* R876 */
+ 0x0000, /* R877 */
+ 0x0000, /* R878 */
+ 0x0000, /* R879 */
+ 0x0000, /* R880 */
+ 0x0000, /* R881 */
+ 0x0000, /* R882 */
+ 0x0000, /* R883 */
+ 0x0000, /* R884 */
+ 0x0000, /* R885 */
+ 0x0000, /* R886 */
+ 0x0000, /* R887 */
+ 0x0000, /* R888 */
+ 0x0000, /* R889 */
+ 0x0000, /* R890 */
+ 0x0000, /* R891 */
+ 0x0000, /* R892 */
+ 0x0000, /* R893 */
+ 0x0000, /* R894 */
+ 0x0000, /* R895 */
+ 0x0000, /* R896 */
+ 0x0000, /* R897 */
+ 0x0000, /* R898 */
+ 0x0000, /* R899 */
+ 0x0000, /* R900 */
+ 0x0000, /* R901 */
+ 0x0000, /* R902 */
+ 0x0000, /* R903 */
+ 0x0000, /* R904 */
+ 0x0000, /* R905 */
+ 0x0000, /* R906 */
+ 0x0000, /* R907 */
+ 0x0000, /* R908 */
+ 0x0000, /* R909 */
+ 0x0000, /* R910 */
+ 0x0000, /* R911 */
+ 0x0000, /* R912 */
+ 0x0000, /* R913 */
+ 0x0000, /* R914 */
+ 0x0000, /* R915 */
+ 0x0000, /* R916 */
+ 0x0000, /* R917 */
+ 0x0000, /* R918 */
+ 0x0000, /* R919 */
+ 0x0000, /* R920 */
+ 0x0000, /* R921 */
+ 0x0000, /* R922 */
+ 0x0000, /* R923 */
+ 0x0000, /* R924 */
+ 0x0000, /* R925 */
+ 0x0000, /* R926 */
+ 0x0000, /* R927 */
+ 0x0000, /* R928 */
+ 0x0000, /* R929 */
+ 0x0000, /* R930 */
+ 0x0000, /* R931 */
+ 0x0000, /* R932 */
+ 0x0000, /* R933 */
+ 0x0000, /* R934 */
+ 0x0000, /* R935 */
+ 0x0000, /* R936 */
+ 0x0000, /* R937 */
+ 0x0000, /* R938 */
+ 0x0000, /* R939 */
+ 0x0000, /* R940 */
+ 0x0000, /* R941 */
+ 0x0000, /* R942 */
+ 0x0000, /* R943 */
+ 0x0000, /* R944 */
+ 0x0000, /* R945 */
+ 0x0000, /* R946 */
+ 0x0000, /* R947 */
+ 0x0000, /* R948 */
+ 0x0000, /* R949 */
+ 0x0000, /* R950 */
+ 0x0000, /* R951 */
+ 0x0000, /* R952 */
+ 0x0000, /* R953 */
+ 0x0000, /* R954 */
+ 0x0000, /* R955 */
+ 0x0000, /* R956 */
+ 0x0000, /* R957 */
+ 0x0000, /* R958 */
+ 0x0000, /* R959 */
+ 0x0000, /* R960 */
+ 0x0000, /* R961 */
+ 0x0000, /* R962 */
+ 0x0000, /* R963 */
+ 0x0000, /* R964 */
+ 0x0000, /* R965 */
+ 0x0000, /* R966 */
+ 0x0000, /* R967 */
+ 0x0000, /* R968 */
+ 0x0000, /* R969 */
+ 0x0000, /* R970 */
+ 0x0000, /* R971 */
+ 0x0000, /* R972 */
+ 0x0000, /* R973 */
+ 0x0000, /* R974 */
+ 0x0000, /* R975 */
+ 0x0000, /* R976 */
+ 0x0000, /* R977 */
+ 0x0000, /* R978 */
+ 0x0000, /* R979 */
+ 0x0000, /* R980 */
+ 0x0000, /* R981 */
+ 0x0000, /* R982 */
+ 0x0000, /* R983 */
+ 0x0000, /* R984 */
+ 0x0000, /* R985 */
+ 0x0000, /* R986 */
+ 0x0000, /* R987 */
+ 0x0000, /* R988 */
+ 0x0000, /* R989 */
+ 0x0000, /* R990 */
+ 0x0000, /* R991 */
+ 0x0000, /* R992 */
+ 0x0000, /* R993 */
+ 0x0000, /* R994 */
+ 0x0000, /* R995 */
+ 0x0000, /* R996 */
+ 0x0000, /* R997 */
+ 0x0000, /* R998 */
+ 0x0000, /* R999 */
+ 0x0000, /* R1000 */
+ 0x0000, /* R1001 */
+ 0x0000, /* R1002 */
+ 0x0000, /* R1003 */
+ 0x0000, /* R1004 */
+ 0x0000, /* R1005 */
+ 0x0000, /* R1006 */
+ 0x0000, /* R1007 */
+ 0x0000, /* R1008 */
+ 0x0000, /* R1009 */
+ 0x0000, /* R1010 */
+ 0x0000, /* R1011 */
+ 0x0000, /* R1012 */
+ 0x0000, /* R1013 */
+ 0x0000, /* R1014 */
+ 0x0000, /* R1015 */
+ 0x0000, /* R1016 */
+ 0x0000, /* R1017 */
+ 0x0000, /* R1018 */
+ 0x0000, /* R1019 */
+ 0x0000, /* R1020 */
+ 0x0000, /* R1021 */
+ 0x0000, /* R1022 */
+ 0x0000, /* R1023 */
+ 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */
+ 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */
+ 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */
+ 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */
+ 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */
+ 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */
+ 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */
+ 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */
+ 0x0000, /* R1032 */
+ 0x0000, /* R1033 */
+ 0x0000, /* R1034 */
+ 0x0000, /* R1035 */
+ 0x0000, /* R1036 */
+ 0x0000, /* R1037 */
+ 0x0000, /* R1038 */
+ 0x0000, /* R1039 */
+ 0x0000, /* R1040 - AIF1 ADC1 Filters */
+ 0x0000, /* R1041 - AIF1 ADC2 Filters */
+ 0x0000, /* R1042 */
+ 0x0000, /* R1043 */
+ 0x0000, /* R1044 */
+ 0x0000, /* R1045 */
+ 0x0000, /* R1046 */
+ 0x0000, /* R1047 */
+ 0x0000, /* R1048 */
+ 0x0000, /* R1049 */
+ 0x0000, /* R1050 */
+ 0x0000, /* R1051 */
+ 0x0000, /* R1052 */
+ 0x0000, /* R1053 */
+ 0x0000, /* R1054 */
+ 0x0000, /* R1055 */
+ 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */
+ 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */
+ 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */
+ 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */
+ 0x0000, /* R1060 */
+ 0x0000, /* R1061 */
+ 0x0000, /* R1062 */
+ 0x0000, /* R1063 */
+ 0x0000, /* R1064 */
+ 0x0000, /* R1065 */
+ 0x0000, /* R1066 */
+ 0x0000, /* R1067 */
+ 0x0000, /* R1068 */
+ 0x0000, /* R1069 */
+ 0x0000, /* R1070 */
+ 0x0000, /* R1071 */
+ 0x0000, /* R1072 */
+ 0x0000, /* R1073 */
+ 0x0000, /* R1074 */
+ 0x0000, /* R1075 */
+ 0x0000, /* R1076 */
+ 0x0000, /* R1077 */
+ 0x0000, /* R1078 */
+ 0x0000, /* R1079 */
+ 0x0000, /* R1080 */
+ 0x0000, /* R1081 */
+ 0x0000, /* R1082 */
+ 0x0000, /* R1083 */
+ 0x0000, /* R1084 */
+ 0x0000, /* R1085 */
+ 0x0000, /* R1086 */
+ 0x0000, /* R1087 */
+ 0x0098, /* R1088 - AIF1 DRC1 (1) */
+ 0x0845, /* R1089 - AIF1 DRC1 (2) */
+ 0x0000, /* R1090 - AIF1 DRC1 (3) */
+ 0x0000, /* R1091 - AIF1 DRC1 (4) */
+ 0x0000, /* R1092 - AIF1 DRC1 (5) */
+ 0x0000, /* R1093 */
+ 0x0000, /* R1094 */
+ 0x0000, /* R1095 */
+ 0x0000, /* R1096 */
+ 0x0000, /* R1097 */
+ 0x0000, /* R1098 */
+ 0x0000, /* R1099 */
+ 0x0000, /* R1100 */
+ 0x0000, /* R1101 */
+ 0x0000, /* R1102 */
+ 0x0000, /* R1103 */
+ 0x0098, /* R1104 - AIF1 DRC2 (1) */
+ 0x0845, /* R1105 - AIF1 DRC2 (2) */
+ 0x0000, /* R1106 - AIF1 DRC2 (3) */
+ 0x0000, /* R1107 - AIF1 DRC2 (4) */
+ 0x0000, /* R1108 - AIF1 DRC2 (5) */
+ 0x0000, /* R1109 */
+ 0x0000, /* R1110 */
+ 0x0000, /* R1111 */
+ 0x0000, /* R1112 */
+ 0x0000, /* R1113 */
+ 0x0000, /* R1114 */
+ 0x0000, /* R1115 */
+ 0x0000, /* R1116 */
+ 0x0000, /* R1117 */
+ 0x0000, /* R1118 */
+ 0x0000, /* R1119 */
+ 0x0000, /* R1120 */
+ 0x0000, /* R1121 */
+ 0x0000, /* R1122 */
+ 0x0000, /* R1123 */
+ 0x0000, /* R1124 */
+ 0x0000, /* R1125 */
+ 0x0000, /* R1126 */
+ 0x0000, /* R1127 */
+ 0x0000, /* R1128 */
+ 0x0000, /* R1129 */
+ 0x0000, /* R1130 */
+ 0x0000, /* R1131 */
+ 0x0000, /* R1132 */
+ 0x0000, /* R1133 */
+ 0x0000, /* R1134 */
+ 0x0000, /* R1135 */
+ 0x0000, /* R1136 */
+ 0x0000, /* R1137 */
+ 0x0000, /* R1138 */
+ 0x0000, /* R1139 */
+ 0x0000, /* R1140 */
+ 0x0000, /* R1141 */
+ 0x0000, /* R1142 */
+ 0x0000, /* R1143 */
+ 0x0000, /* R1144 */
+ 0x0000, /* R1145 */
+ 0x0000, /* R1146 */
+ 0x0000, /* R1147 */
+ 0x0000, /* R1148 */
+ 0x0000, /* R1149 */
+ 0x0000, /* R1150 */
+ 0x0000, /* R1151 */
+ 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ 0x0000, /* R1172 */
+ 0x0000, /* R1173 */
+ 0x0000, /* R1174 */
+ 0x0000, /* R1175 */
+ 0x0000, /* R1176 */
+ 0x0000, /* R1177 */
+ 0x0000, /* R1178 */
+ 0x0000, /* R1179 */
+ 0x0000, /* R1180 */
+ 0x0000, /* R1181 */
+ 0x0000, /* R1182 */
+ 0x0000, /* R1183 */
+ 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ 0x0000, /* R1204 */
+ 0x0000, /* R1205 */
+ 0x0000, /* R1206 */
+ 0x0000, /* R1207 */
+ 0x0000, /* R1208 */
+ 0x0000, /* R1209 */
+ 0x0000, /* R1210 */
+ 0x0000, /* R1211 */
+ 0x0000, /* R1212 */
+ 0x0000, /* R1213 */
+ 0x0000, /* R1214 */
+ 0x0000, /* R1215 */
+ 0x0000, /* R1216 */
+ 0x0000, /* R1217 */
+ 0x0000, /* R1218 */
+ 0x0000, /* R1219 */
+ 0x0000, /* R1220 */
+ 0x0000, /* R1221 */
+ 0x0000, /* R1222 */
+ 0x0000, /* R1223 */
+ 0x0000, /* R1224 */
+ 0x0000, /* R1225 */
+ 0x0000, /* R1226 */
+ 0x0000, /* R1227 */
+ 0x0000, /* R1228 */
+ 0x0000, /* R1229 */
+ 0x0000, /* R1230 */
+ 0x0000, /* R1231 */
+ 0x0000, /* R1232 */
+ 0x0000, /* R1233 */
+ 0x0000, /* R1234 */
+ 0x0000, /* R1235 */
+ 0x0000, /* R1236 */
+ 0x0000, /* R1237 */
+ 0x0000, /* R1238 */
+ 0x0000, /* R1239 */
+ 0x0000, /* R1240 */
+ 0x0000, /* R1241 */
+ 0x0000, /* R1242 */
+ 0x0000, /* R1243 */
+ 0x0000, /* R1244 */
+ 0x0000, /* R1245 */
+ 0x0000, /* R1246 */
+ 0x0000, /* R1247 */
+ 0x0000, /* R1248 */
+ 0x0000, /* R1249 */
+ 0x0000, /* R1250 */
+ 0x0000, /* R1251 */
+ 0x0000, /* R1252 */
+ 0x0000, /* R1253 */
+ 0x0000, /* R1254 */
+ 0x0000, /* R1255 */
+ 0x0000, /* R1256 */
+ 0x0000, /* R1257 */
+ 0x0000, /* R1258 */
+ 0x0000, /* R1259 */
+ 0x0000, /* R1260 */
+ 0x0000, /* R1261 */
+ 0x0000, /* R1262 */
+ 0x0000, /* R1263 */
+ 0x0000, /* R1264 */
+ 0x0000, /* R1265 */
+ 0x0000, /* R1266 */
+ 0x0000, /* R1267 */
+ 0x0000, /* R1268 */
+ 0x0000, /* R1269 */
+ 0x0000, /* R1270 */
+ 0x0000, /* R1271 */
+ 0x0000, /* R1272 */
+ 0x0000, /* R1273 */
+ 0x0000, /* R1274 */
+ 0x0000, /* R1275 */
+ 0x0000, /* R1276 */
+ 0x0000, /* R1277 */
+ 0x0000, /* R1278 */
+ 0x0000, /* R1279 */
+ 0x00C0, /* R1280 - AIF2 ADC Left Volume */
+ 0x00C0, /* R1281 - AIF2 ADC Right Volume */
+ 0x00C0, /* R1282 - AIF2 DAC Left Volume */
+ 0x00C0, /* R1283 - AIF2 DAC Right Volume */
+ 0x0000, /* R1284 */
+ 0x0000, /* R1285 */
+ 0x0000, /* R1286 */
+ 0x0000, /* R1287 */
+ 0x0000, /* R1288 */
+ 0x0000, /* R1289 */
+ 0x0000, /* R1290 */
+ 0x0000, /* R1291 */
+ 0x0000, /* R1292 */
+ 0x0000, /* R1293 */
+ 0x0000, /* R1294 */
+ 0x0000, /* R1295 */
+ 0x0000, /* R1296 - AIF2 ADC Filters */
+ 0x0000, /* R1297 */
+ 0x0000, /* R1298 */
+ 0x0000, /* R1299 */
+ 0x0000, /* R1300 */
+ 0x0000, /* R1301 */
+ 0x0000, /* R1302 */
+ 0x0000, /* R1303 */
+ 0x0000, /* R1304 */
+ 0x0000, /* R1305 */
+ 0x0000, /* R1306 */
+ 0x0000, /* R1307 */
+ 0x0000, /* R1308 */
+ 0x0000, /* R1309 */
+ 0x0000, /* R1310 */
+ 0x0000, /* R1311 */
+ 0x0200, /* R1312 - AIF2 DAC Filters (1) */
+ 0x0010, /* R1313 - AIF2 DAC Filters (2) */
+ 0x0000, /* R1314 */
+ 0x0000, /* R1315 */
+ 0x0000, /* R1316 */
+ 0x0000, /* R1317 */
+ 0x0000, /* R1318 */
+ 0x0000, /* R1319 */
+ 0x0000, /* R1320 */
+ 0x0000, /* R1321 */
+ 0x0000, /* R1322 */
+ 0x0000, /* R1323 */
+ 0x0000, /* R1324 */
+ 0x0000, /* R1325 */
+ 0x0000, /* R1326 */
+ 0x0000, /* R1327 */
+ 0x0000, /* R1328 */
+ 0x0000, /* R1329 */
+ 0x0000, /* R1330 */
+ 0x0000, /* R1331 */
+ 0x0000, /* R1332 */
+ 0x0000, /* R1333 */
+ 0x0000, /* R1334 */
+ 0x0000, /* R1335 */
+ 0x0000, /* R1336 */
+ 0x0000, /* R1337 */
+ 0x0000, /* R1338 */
+ 0x0000, /* R1339 */
+ 0x0000, /* R1340 */
+ 0x0000, /* R1341 */
+ 0x0000, /* R1342 */
+ 0x0000, /* R1343 */
+ 0x0098, /* R1344 - AIF2 DRC (1) */
+ 0x0845, /* R1345 - AIF2 DRC (2) */
+ 0x0000, /* R1346 - AIF2 DRC (3) */
+ 0x0000, /* R1347 - AIF2 DRC (4) */
+ 0x0000, /* R1348 - AIF2 DRC (5) */
+ 0x0000, /* R1349 */
+ 0x0000, /* R1350 */
+ 0x0000, /* R1351 */
+ 0x0000, /* R1352 */
+ 0x0000, /* R1353 */
+ 0x0000, /* R1354 */
+ 0x0000, /* R1355 */
+ 0x0000, /* R1356 */
+ 0x0000, /* R1357 */
+ 0x0000, /* R1358 */
+ 0x0000, /* R1359 */
+ 0x0000, /* R1360 */
+ 0x0000, /* R1361 */
+ 0x0000, /* R1362 */
+ 0x0000, /* R1363 */
+ 0x0000, /* R1364 */
+ 0x0000, /* R1365 */
+ 0x0000, /* R1366 */
+ 0x0000, /* R1367 */
+ 0x0000, /* R1368 */
+ 0x0000, /* R1369 */
+ 0x0000, /* R1370 */
+ 0x0000, /* R1371 */
+ 0x0000, /* R1372 */
+ 0x0000, /* R1373 */
+ 0x0000, /* R1374 */
+ 0x0000, /* R1375 */
+ 0x0000, /* R1376 */
+ 0x0000, /* R1377 */
+ 0x0000, /* R1378 */
+ 0x0000, /* R1379 */
+ 0x0000, /* R1380 */
+ 0x0000, /* R1381 */
+ 0x0000, /* R1382 */
+ 0x0000, /* R1383 */
+ 0x0000, /* R1384 */
+ 0x0000, /* R1385 */
+ 0x0000, /* R1386 */
+ 0x0000, /* R1387 */
+ 0x0000, /* R1388 */
+ 0x0000, /* R1389 */
+ 0x0000, /* R1390 */
+ 0x0000, /* R1391 */
+ 0x0000, /* R1392 */
+ 0x0000, /* R1393 */
+ 0x0000, /* R1394 */
+ 0x0000, /* R1395 */
+ 0x0000, /* R1396 */
+ 0x0000, /* R1397 */
+ 0x0000, /* R1398 */
+ 0x0000, /* R1399 */
+ 0x0000, /* R1400 */
+ 0x0000, /* R1401 */
+ 0x0000, /* R1402 */
+ 0x0000, /* R1403 */
+ 0x0000, /* R1404 */
+ 0x0000, /* R1405 */
+ 0x0000, /* R1406 */
+ 0x0000, /* R1407 */
+ 0x6318, /* R1408 - AIF2 EQ Gains (1) */
+ 0x6300, /* R1409 - AIF2 EQ Gains (2) */
+ 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */
+ 0x0400, /* R1411 - AIF2 EQ Band 1 B */
+ 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */
+ 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */
+ 0xF145, /* R1414 - AIF2 EQ Band 2 B */
+ 0x0B75, /* R1415 - AIF2 EQ Band 2 C */
+ 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */
+ 0x1C58, /* R1417 - AIF2 EQ Band 3 A */
+ 0xF373, /* R1418 - AIF2 EQ Band 3 B */
+ 0x0A54, /* R1419 - AIF2 EQ Band 3 C */
+ 0x0558, /* R1420 - AIF2 EQ Band 3 PG */
+ 0x168E, /* R1421 - AIF2 EQ Band 4 A */
+ 0xF829, /* R1422 - AIF2 EQ Band 4 B */
+ 0x07AD, /* R1423 - AIF2 EQ Band 4 C */
+ 0x1103, /* R1424 - AIF2 EQ Band 4 PG */
+ 0x0564, /* R1425 - AIF2 EQ Band 5 A */
+ 0x0559, /* R1426 - AIF2 EQ Band 5 B */
+ 0x4000, /* R1427 - AIF2 EQ Band 5 PG */
+ 0x0000, /* R1428 */
+ 0x0000, /* R1429 */
+ 0x0000, /* R1430 */
+ 0x0000, /* R1431 */
+ 0x0000, /* R1432 */
+ 0x0000, /* R1433 */
+ 0x0000, /* R1434 */
+ 0x0000, /* R1435 */
+ 0x0000, /* R1436 */
+ 0x0000, /* R1437 */
+ 0x0000, /* R1438 */
+ 0x0000, /* R1439 */
+ 0x0000, /* R1440 */
+ 0x0000, /* R1441 */
+ 0x0000, /* R1442 */
+ 0x0000, /* R1443 */
+ 0x0000, /* R1444 */
+ 0x0000, /* R1445 */
+ 0x0000, /* R1446 */
+ 0x0000, /* R1447 */
+ 0x0000, /* R1448 */
+ 0x0000, /* R1449 */
+ 0x0000, /* R1450 */
+ 0x0000, /* R1451 */
+ 0x0000, /* R1452 */
+ 0x0000, /* R1453 */
+ 0x0000, /* R1454 */
+ 0x0000, /* R1455 */
+ 0x0000, /* R1456 */
+ 0x0000, /* R1457 */
+ 0x0000, /* R1458 */
+ 0x0000, /* R1459 */
+ 0x0000, /* R1460 */
+ 0x0000, /* R1461 */
+ 0x0000, /* R1462 */
+ 0x0000, /* R1463 */
+ 0x0000, /* R1464 */
+ 0x0000, /* R1465 */
+ 0x0000, /* R1466 */
+ 0x0000, /* R1467 */
+ 0x0000, /* R1468 */
+ 0x0000, /* R1469 */
+ 0x0000, /* R1470 */
+ 0x0000, /* R1471 */
+ 0x0000, /* R1472 */
+ 0x0000, /* R1473 */
+ 0x0000, /* R1474 */
+ 0x0000, /* R1475 */
+ 0x0000, /* R1476 */
+ 0x0000, /* R1477 */
+ 0x0000, /* R1478 */
+ 0x0000, /* R1479 */
+ 0x0000, /* R1480 */
+ 0x0000, /* R1481 */
+ 0x0000, /* R1482 */
+ 0x0000, /* R1483 */
+ 0x0000, /* R1484 */
+ 0x0000, /* R1485 */
+ 0x0000, /* R1486 */
+ 0x0000, /* R1487 */
+ 0x0000, /* R1488 */
+ 0x0000, /* R1489 */
+ 0x0000, /* R1490 */
+ 0x0000, /* R1491 */
+ 0x0000, /* R1492 */
+ 0x0000, /* R1493 */
+ 0x0000, /* R1494 */
+ 0x0000, /* R1495 */
+ 0x0000, /* R1496 */
+ 0x0000, /* R1497 */
+ 0x0000, /* R1498 */
+ 0x0000, /* R1499 */
+ 0x0000, /* R1500 */
+ 0x0000, /* R1501 */
+ 0x0000, /* R1502 */
+ 0x0000, /* R1503 */
+ 0x0000, /* R1504 */
+ 0x0000, /* R1505 */
+ 0x0000, /* R1506 */
+ 0x0000, /* R1507 */
+ 0x0000, /* R1508 */
+ 0x0000, /* R1509 */
+ 0x0000, /* R1510 */
+ 0x0000, /* R1511 */
+ 0x0000, /* R1512 */
+ 0x0000, /* R1513 */
+ 0x0000, /* R1514 */
+ 0x0000, /* R1515 */
+ 0x0000, /* R1516 */
+ 0x0000, /* R1517 */
+ 0x0000, /* R1518 */
+ 0x0000, /* R1519 */
+ 0x0000, /* R1520 */
+ 0x0000, /* R1521 */
+ 0x0000, /* R1522 */
+ 0x0000, /* R1523 */
+ 0x0000, /* R1524 */
+ 0x0000, /* R1525 */
+ 0x0000, /* R1526 */
+ 0x0000, /* R1527 */
+ 0x0000, /* R1528 */
+ 0x0000, /* R1529 */
+ 0x0000, /* R1530 */
+ 0x0000, /* R1531 */
+ 0x0000, /* R1532 */
+ 0x0000, /* R1533 */
+ 0x0000, /* R1534 */
+ 0x0000, /* R1535 */
+ 0x0000, /* R1536 - DAC1 Mixer Volumes */
+ 0x0000, /* R1537 - DAC1 Left Mixer Routing */
+ 0x0000, /* R1538 - DAC1 Right Mixer Routing */
+ 0x0000, /* R1539 - DAC2 Mixer Volumes */
+ 0x0000, /* R1540 - DAC2 Left Mixer Routing */
+ 0x0000, /* R1541 - DAC2 Right Mixer Routing */
+ 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ 0x0000, /* R1546 */
+ 0x0000, /* R1547 */
+ 0x0000, /* R1548 */
+ 0x0000, /* R1549 */
+ 0x0000, /* R1550 */
+ 0x0000, /* R1551 */
+ 0x02C0, /* R1552 - DAC1 Left Volume */
+ 0x02C0, /* R1553 - DAC1 Right Volume */
+ 0x02C0, /* R1554 - DAC2 Left Volume */
+ 0x02C0, /* R1555 - DAC2 Right Volume */
+ 0x0000, /* R1556 - DAC Softmute */
+ 0x0000, /* R1557 */
+ 0x0000, /* R1558 */
+ 0x0000, /* R1559 */
+ 0x0000, /* R1560 */
+ 0x0000, /* R1561 */
+ 0x0000, /* R1562 */
+ 0x0000, /* R1563 */
+ 0x0000, /* R1564 */
+ 0x0000, /* R1565 */
+ 0x0000, /* R1566 */
+ 0x0000, /* R1567 */
+ 0x0002, /* R1568 - Oversampling */
+ 0x0000, /* R1569 - Sidetone */
+};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 4d3e6f1ac584..247a6a99feb8 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -18,15 +18,17 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
+#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
+#include <trace/events/asoc.h>
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
@@ -57,8 +59,6 @@ static int wm8994_retune_mobile_base[] = {
WM8994_AIF2_EQ_GAINS_1,
};
-#define WM8994_REG_CACHE_SIZE 0x621
-
struct wm8994_micdet {
struct snd_soc_jack *jack;
int det;
@@ -71,7 +71,6 @@ struct wm8994_priv {
enum snd_soc_control_type control_type;
void *control_data;
struct snd_soc_codec *codec;
- u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
int sysclk[2];
int sysclk_rate[2];
int mclk[2];
@@ -81,6 +80,8 @@ struct wm8994_priv {
int dac_rates[2];
int lrclk_shared[2];
+ int mbc_ena[3];
+
/* Platform dependant DRC configuration */
const char **drc_texts;
int drc_cfg[WM8994_NUM_DRC];
@@ -92,1588 +93,22 @@ struct wm8994_priv {
int retune_mobile_cfg[WM8994_NUM_EQ];
struct soc_enum retune_mobile_enum;
+ /* Platform dependant MBC configuration */
+ int mbc_cfg;
+ const char **mbc_texts;
+ struct soc_enum mbc_enum;
+
struct wm8994_micdet micdet[2];
+ wm8958_micdet_cb jack_cb;
+ void *jack_cb_data;
+ bool jack_is_mic;
+ bool jack_is_video;
+
int revision;
struct wm8994_pdata *pdata;
};
-static const struct {
- unsigned short readable; /* Mask of readable bits */
- unsigned short writable; /* Mask of writable bits */
-} access_masks[] = {
- { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
- { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
- { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
- { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
- { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
- { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
- { 0x003F, 0x003F }, /* R6 - Power Management (6) */
- { 0x0000, 0x0000 }, /* R7 */
- { 0x0000, 0x0000 }, /* R8 */
- { 0x0000, 0x0000 }, /* R9 */
- { 0x0000, 0x0000 }, /* R10 */
- { 0x0000, 0x0000 }, /* R11 */
- { 0x0000, 0x0000 }, /* R12 */
- { 0x0000, 0x0000 }, /* R13 */
- { 0x0000, 0x0000 }, /* R14 */
- { 0x0000, 0x0000 }, /* R15 */
- { 0x0000, 0x0000 }, /* R16 */
- { 0x0000, 0x0000 }, /* R17 */
- { 0x0000, 0x0000 }, /* R18 */
- { 0x0000, 0x0000 }, /* R19 */
- { 0x0000, 0x0000 }, /* R20 */
- { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
- { 0x0000, 0x0000 }, /* R22 */
- { 0x0000, 0x0000 }, /* R23 */
- { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
- { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
- { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
- { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
- { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
- { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
- { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
- { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
- { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
- { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
- { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
- { 0x003F, 0x003F }, /* R37 - ClassD */
- { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
- { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
- { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
- { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
- { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
- { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
- { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
- { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
- { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
- { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
- { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
- { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
- { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
- { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
- { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
- { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
- { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
- { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
- { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
- { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
- { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
- { 0x000F, 0x000F }, /* R59 - LDO 1 */
- { 0x0007, 0x0007 }, /* R60 - LDO 2 */
- { 0x0000, 0x0000 }, /* R61 */
- { 0x0000, 0x0000 }, /* R62 */
- { 0x0000, 0x0000 }, /* R63 */
- { 0x0000, 0x0000 }, /* R64 */
- { 0x0000, 0x0000 }, /* R65 */
- { 0x0000, 0x0000 }, /* R66 */
- { 0x0000, 0x0000 }, /* R67 */
- { 0x0000, 0x0000 }, /* R68 */
- { 0x0000, 0x0000 }, /* R69 */
- { 0x0000, 0x0000 }, /* R70 */
- { 0x0000, 0x0000 }, /* R71 */
- { 0x0000, 0x0000 }, /* R72 */
- { 0x0000, 0x0000 }, /* R73 */
- { 0x0000, 0x0000 }, /* R74 */
- { 0x0000, 0x0000 }, /* R75 */
- { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
- { 0x0000, 0x0000 }, /* R77 */
- { 0x0000, 0x0000 }, /* R78 */
- { 0x0000, 0x0000 }, /* R79 */
- { 0x0000, 0x0000 }, /* R80 */
- { 0x0301, 0x0301 }, /* R81 - Class W (1) */
- { 0x0000, 0x0000 }, /* R82 */
- { 0x0000, 0x0000 }, /* R83 */
- { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
- { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
- { 0x0000, 0x0000 }, /* R86 */
- { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
- { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
- { 0x0000, 0x0000 }, /* R89 */
- { 0x0000, 0x0000 }, /* R90 */
- { 0x0000, 0x0000 }, /* R91 */
- { 0x0000, 0x0000 }, /* R92 */
- { 0x0000, 0x0000 }, /* R93 */
- { 0x0000, 0x0000 }, /* R94 */
- { 0x0000, 0x0000 }, /* R95 */
- { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
- { 0x0000, 0x0000 }, /* R97 */
- { 0x0000, 0x0000 }, /* R98 */
- { 0x0000, 0x0000 }, /* R99 */
- { 0x0000, 0x0000 }, /* R100 */
- { 0x0000, 0x0000 }, /* R101 */
- { 0x0000, 0x0000 }, /* R102 */
- { 0x0000, 0x0000 }, /* R103 */
- { 0x0000, 0x0000 }, /* R104 */
- { 0x0000, 0x0000 }, /* R105 */
- { 0x0000, 0x0000 }, /* R106 */
- { 0x0000, 0x0000 }, /* R107 */
- { 0x0000, 0x0000 }, /* R108 */
- { 0x0000, 0x0000 }, /* R109 */
- { 0x0000, 0x0000 }, /* R110 */
- { 0x0000, 0x0000 }, /* R111 */
- { 0x0000, 0x0000 }, /* R112 */
- { 0x0000, 0x0000 }, /* R113 */
- { 0x0000, 0x0000 }, /* R114 */
- { 0x0000, 0x0000 }, /* R115 */
- { 0x0000, 0x0000 }, /* R116 */
- { 0x0000, 0x0000 }, /* R117 */
- { 0x0000, 0x0000 }, /* R118 */
- { 0x0000, 0x0000 }, /* R119 */
- { 0x0000, 0x0000 }, /* R120 */
- { 0x0000, 0x0000 }, /* R121 */
- { 0x0000, 0x0000 }, /* R122 */
- { 0x0000, 0x0000 }, /* R123 */
- { 0x0000, 0x0000 }, /* R124 */
- { 0x0000, 0x0000 }, /* R125 */
- { 0x0000, 0x0000 }, /* R126 */
- { 0x0000, 0x0000 }, /* R127 */
- { 0x0000, 0x0000 }, /* R128 */
- { 0x0000, 0x0000 }, /* R129 */
- { 0x0000, 0x0000 }, /* R130 */
- { 0x0000, 0x0000 }, /* R131 */
- { 0x0000, 0x0000 }, /* R132 */
- { 0x0000, 0x0000 }, /* R133 */
- { 0x0000, 0x0000 }, /* R134 */
- { 0x0000, 0x0000 }, /* R135 */
- { 0x0000, 0x0000 }, /* R136 */
- { 0x0000, 0x0000 }, /* R137 */
- { 0x0000, 0x0000 }, /* R138 */
- { 0x0000, 0x0000 }, /* R139 */
- { 0x0000, 0x0000 }, /* R140 */
- { 0x0000, 0x0000 }, /* R141 */
- { 0x0000, 0x0000 }, /* R142 */
- { 0x0000, 0x0000 }, /* R143 */
- { 0x0000, 0x0000 }, /* R144 */
- { 0x0000, 0x0000 }, /* R145 */
- { 0x0000, 0x0000 }, /* R146 */
- { 0x0000, 0x0000 }, /* R147 */
- { 0x0000, 0x0000 }, /* R148 */
- { 0x0000, 0x0000 }, /* R149 */
- { 0x0000, 0x0000 }, /* R150 */
- { 0x0000, 0x0000 }, /* R151 */
- { 0x0000, 0x0000 }, /* R152 */
- { 0x0000, 0x0000 }, /* R153 */
- { 0x0000, 0x0000 }, /* R154 */
- { 0x0000, 0x0000 }, /* R155 */
- { 0x0000, 0x0000 }, /* R156 */
- { 0x0000, 0x0000 }, /* R157 */
- { 0x0000, 0x0000 }, /* R158 */
- { 0x0000, 0x0000 }, /* R159 */
- { 0x0000, 0x0000 }, /* R160 */
- { 0x0000, 0x0000 }, /* R161 */
- { 0x0000, 0x0000 }, /* R162 */
- { 0x0000, 0x0000 }, /* R163 */
- { 0x0000, 0x0000 }, /* R164 */
- { 0x0000, 0x0000 }, /* R165 */
- { 0x0000, 0x0000 }, /* R166 */
- { 0x0000, 0x0000 }, /* R167 */
- { 0x0000, 0x0000 }, /* R168 */
- { 0x0000, 0x0000 }, /* R169 */
- { 0x0000, 0x0000 }, /* R170 */
- { 0x0000, 0x0000 }, /* R171 */
- { 0x0000, 0x0000 }, /* R172 */
- { 0x0000, 0x0000 }, /* R173 */
- { 0x0000, 0x0000 }, /* R174 */
- { 0x0000, 0x0000 }, /* R175 */
- { 0x0000, 0x0000 }, /* R176 */
- { 0x0000, 0x0000 }, /* R177 */
- { 0x0000, 0x0000 }, /* R178 */
- { 0x0000, 0x0000 }, /* R179 */
- { 0x0000, 0x0000 }, /* R180 */
- { 0x0000, 0x0000 }, /* R181 */
- { 0x0000, 0x0000 }, /* R182 */
- { 0x0000, 0x0000 }, /* R183 */
- { 0x0000, 0x0000 }, /* R184 */
- { 0x0000, 0x0000 }, /* R185 */
- { 0x0000, 0x0000 }, /* R186 */
- { 0x0000, 0x0000 }, /* R187 */
- { 0x0000, 0x0000 }, /* R188 */
- { 0x0000, 0x0000 }, /* R189 */
- { 0x0000, 0x0000 }, /* R190 */
- { 0x0000, 0x0000 }, /* R191 */
- { 0x0000, 0x0000 }, /* R192 */
- { 0x0000, 0x0000 }, /* R193 */
- { 0x0000, 0x0000 }, /* R194 */
- { 0x0000, 0x0000 }, /* R195 */
- { 0x0000, 0x0000 }, /* R196 */
- { 0x0000, 0x0000 }, /* R197 */
- { 0x0000, 0x0000 }, /* R198 */
- { 0x0000, 0x0000 }, /* R199 */
- { 0x0000, 0x0000 }, /* R200 */
- { 0x0000, 0x0000 }, /* R201 */
- { 0x0000, 0x0000 }, /* R202 */
- { 0x0000, 0x0000 }, /* R203 */
- { 0x0000, 0x0000 }, /* R204 */
- { 0x0000, 0x0000 }, /* R205 */
- { 0x0000, 0x0000 }, /* R206 */
- { 0x0000, 0x0000 }, /* R207 */
- { 0x0000, 0x0000 }, /* R208 */
- { 0x0000, 0x0000 }, /* R209 */
- { 0x0000, 0x0000 }, /* R210 */
- { 0x0000, 0x0000 }, /* R211 */
- { 0x0000, 0x0000 }, /* R212 */
- { 0x0000, 0x0000 }, /* R213 */
- { 0x0000, 0x0000 }, /* R214 */
- { 0x0000, 0x0000 }, /* R215 */
- { 0x0000, 0x0000 }, /* R216 */
- { 0x0000, 0x0000 }, /* R217 */
- { 0x0000, 0x0000 }, /* R218 */
- { 0x0000, 0x0000 }, /* R219 */
- { 0x0000, 0x0000 }, /* R220 */
- { 0x0000, 0x0000 }, /* R221 */
- { 0x0000, 0x0000 }, /* R222 */
- { 0x0000, 0x0000 }, /* R223 */
- { 0x0000, 0x0000 }, /* R224 */
- { 0x0000, 0x0000 }, /* R225 */
- { 0x0000, 0x0000 }, /* R226 */
- { 0x0000, 0x0000 }, /* R227 */
- { 0x0000, 0x0000 }, /* R228 */
- { 0x0000, 0x0000 }, /* R229 */
- { 0x0000, 0x0000 }, /* R230 */
- { 0x0000, 0x0000 }, /* R231 */
- { 0x0000, 0x0000 }, /* R232 */
- { 0x0000, 0x0000 }, /* R233 */
- { 0x0000, 0x0000 }, /* R234 */
- { 0x0000, 0x0000 }, /* R235 */
- { 0x0000, 0x0000 }, /* R236 */
- { 0x0000, 0x0000 }, /* R237 */
- { 0x0000, 0x0000 }, /* R238 */
- { 0x0000, 0x0000 }, /* R239 */
- { 0x0000, 0x0000 }, /* R240 */
- { 0x0000, 0x0000 }, /* R241 */
- { 0x0000, 0x0000 }, /* R242 */
- { 0x0000, 0x0000 }, /* R243 */
- { 0x0000, 0x0000 }, /* R244 */
- { 0x0000, 0x0000 }, /* R245 */
- { 0x0000, 0x0000 }, /* R246 */
- { 0x0000, 0x0000 }, /* R247 */
- { 0x0000, 0x0000 }, /* R248 */
- { 0x0000, 0x0000 }, /* R249 */
- { 0x0000, 0x0000 }, /* R250 */
- { 0x0000, 0x0000 }, /* R251 */
- { 0x0000, 0x0000 }, /* R252 */
- { 0x0000, 0x0000 }, /* R253 */
- { 0x0000, 0x0000 }, /* R254 */
- { 0x0000, 0x0000 }, /* R255 */
- { 0x000F, 0x0000 }, /* R256 - Chip Revision */
- { 0x0074, 0x0074 }, /* R257 - Control Interface */
- { 0x0000, 0x0000 }, /* R258 */
- { 0x0000, 0x0000 }, /* R259 */
- { 0x0000, 0x0000 }, /* R260 */
- { 0x0000, 0x0000 }, /* R261 */
- { 0x0000, 0x0000 }, /* R262 */
- { 0x0000, 0x0000 }, /* R263 */
- { 0x0000, 0x0000 }, /* R264 */
- { 0x0000, 0x0000 }, /* R265 */
- { 0x0000, 0x0000 }, /* R266 */
- { 0x0000, 0x0000 }, /* R267 */
- { 0x0000, 0x0000 }, /* R268 */
- { 0x0000, 0x0000 }, /* R269 */
- { 0x0000, 0x0000 }, /* R270 */
- { 0x0000, 0x0000 }, /* R271 */
- { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
- { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
- { 0x0000, 0x0000 }, /* R274 */
- { 0x0000, 0x0000 }, /* R275 */
- { 0x0000, 0x0000 }, /* R276 */
- { 0x0000, 0x0000 }, /* R277 */
- { 0x0000, 0x0000 }, /* R278 */
- { 0x0000, 0x0000 }, /* R279 */
- { 0x0000, 0x0000 }, /* R280 */
- { 0x0000, 0x0000 }, /* R281 */
- { 0x0000, 0x0000 }, /* R282 */
- { 0x0000, 0x0000 }, /* R283 */
- { 0x0000, 0x0000 }, /* R284 */
- { 0x0000, 0x0000 }, /* R285 */
- { 0x0000, 0x0000 }, /* R286 */
- { 0x0000, 0x0000 }, /* R287 */
- { 0x0000, 0x0000 }, /* R288 */
- { 0x0000, 0x0000 }, /* R289 */
- { 0x0000, 0x0000 }, /* R290 */
- { 0x0000, 0x0000 }, /* R291 */
- { 0x0000, 0x0000 }, /* R292 */
- { 0x0000, 0x0000 }, /* R293 */
- { 0x0000, 0x0000 }, /* R294 */
- { 0x0000, 0x0000 }, /* R295 */
- { 0x0000, 0x0000 }, /* R296 */
- { 0x0000, 0x0000 }, /* R297 */
- { 0x0000, 0x0000 }, /* R298 */
- { 0x0000, 0x0000 }, /* R299 */
- { 0x0000, 0x0000 }, /* R300 */
- { 0x0000, 0x0000 }, /* R301 */
- { 0x0000, 0x0000 }, /* R302 */
- { 0x0000, 0x0000 }, /* R303 */
- { 0x0000, 0x0000 }, /* R304 */
- { 0x0000, 0x0000 }, /* R305 */
- { 0x0000, 0x0000 }, /* R306 */
- { 0x0000, 0x0000 }, /* R307 */
- { 0x0000, 0x0000 }, /* R308 */
- { 0x0000, 0x0000 }, /* R309 */
- { 0x0000, 0x0000 }, /* R310 */
- { 0x0000, 0x0000 }, /* R311 */
- { 0x0000, 0x0000 }, /* R312 */
- { 0x0000, 0x0000 }, /* R313 */
- { 0x0000, 0x0000 }, /* R314 */
- { 0x0000, 0x0000 }, /* R315 */
- { 0x0000, 0x0000 }, /* R316 */
- { 0x0000, 0x0000 }, /* R317 */
- { 0x0000, 0x0000 }, /* R318 */
- { 0x0000, 0x0000 }, /* R319 */
- { 0x0000, 0x0000 }, /* R320 */
- { 0x0000, 0x0000 }, /* R321 */
- { 0x0000, 0x0000 }, /* R322 */
- { 0x0000, 0x0000 }, /* R323 */
- { 0x0000, 0x0000 }, /* R324 */
- { 0x0000, 0x0000 }, /* R325 */
- { 0x0000, 0x0000 }, /* R326 */
- { 0x0000, 0x0000 }, /* R327 */
- { 0x0000, 0x0000 }, /* R328 */
- { 0x0000, 0x0000 }, /* R329 */
- { 0x0000, 0x0000 }, /* R330 */
- { 0x0000, 0x0000 }, /* R331 */
- { 0x0000, 0x0000 }, /* R332 */
- { 0x0000, 0x0000 }, /* R333 */
- { 0x0000, 0x0000 }, /* R334 */
- { 0x0000, 0x0000 }, /* R335 */
- { 0x0000, 0x0000 }, /* R336 */
- { 0x0000, 0x0000 }, /* R337 */
- { 0x0000, 0x0000 }, /* R338 */
- { 0x0000, 0x0000 }, /* R339 */
- { 0x0000, 0x0000 }, /* R340 */
- { 0x0000, 0x0000 }, /* R341 */
- { 0x0000, 0x0000 }, /* R342 */
- { 0x0000, 0x0000 }, /* R343 */
- { 0x0000, 0x0000 }, /* R344 */
- { 0x0000, 0x0000 }, /* R345 */
- { 0x0000, 0x0000 }, /* R346 */
- { 0x0000, 0x0000 }, /* R347 */
- { 0x0000, 0x0000 }, /* R348 */
- { 0x0000, 0x0000 }, /* R349 */
- { 0x0000, 0x0000 }, /* R350 */
- { 0x0000, 0x0000 }, /* R351 */
- { 0x0000, 0x0000 }, /* R352 */
- { 0x0000, 0x0000 }, /* R353 */
- { 0x0000, 0x0000 }, /* R354 */
- { 0x0000, 0x0000 }, /* R355 */
- { 0x0000, 0x0000 }, /* R356 */
- { 0x0000, 0x0000 }, /* R357 */
- { 0x0000, 0x0000 }, /* R358 */
- { 0x0000, 0x0000 }, /* R359 */
- { 0x0000, 0x0000 }, /* R360 */
- { 0x0000, 0x0000 }, /* R361 */
- { 0x0000, 0x0000 }, /* R362 */
- { 0x0000, 0x0000 }, /* R363 */
- { 0x0000, 0x0000 }, /* R364 */
- { 0x0000, 0x0000 }, /* R365 */
- { 0x0000, 0x0000 }, /* R366 */
- { 0x0000, 0x0000 }, /* R367 */
- { 0x0000, 0x0000 }, /* R368 */
- { 0x0000, 0x0000 }, /* R369 */
- { 0x0000, 0x0000 }, /* R370 */
- { 0x0000, 0x0000 }, /* R371 */
- { 0x0000, 0x0000 }, /* R372 */
- { 0x0000, 0x0000 }, /* R373 */
- { 0x0000, 0x0000 }, /* R374 */
- { 0x0000, 0x0000 }, /* R375 */
- { 0x0000, 0x0000 }, /* R376 */
- { 0x0000, 0x0000 }, /* R377 */
- { 0x0000, 0x0000 }, /* R378 */
- { 0x0000, 0x0000 }, /* R379 */
- { 0x0000, 0x0000 }, /* R380 */
- { 0x0000, 0x0000 }, /* R381 */
- { 0x0000, 0x0000 }, /* R382 */
- { 0x0000, 0x0000 }, /* R383 */
- { 0x0000, 0x0000 }, /* R384 */
- { 0x0000, 0x0000 }, /* R385 */
- { 0x0000, 0x0000 }, /* R386 */
- { 0x0000, 0x0000 }, /* R387 */
- { 0x0000, 0x0000 }, /* R388 */
- { 0x0000, 0x0000 }, /* R389 */
- { 0x0000, 0x0000 }, /* R390 */
- { 0x0000, 0x0000 }, /* R391 */
- { 0x0000, 0x0000 }, /* R392 */
- { 0x0000, 0x0000 }, /* R393 */
- { 0x0000, 0x0000 }, /* R394 */
- { 0x0000, 0x0000 }, /* R395 */
- { 0x0000, 0x0000 }, /* R396 */
- { 0x0000, 0x0000 }, /* R397 */
- { 0x0000, 0x0000 }, /* R398 */
- { 0x0000, 0x0000 }, /* R399 */
- { 0x0000, 0x0000 }, /* R400 */
- { 0x0000, 0x0000 }, /* R401 */
- { 0x0000, 0x0000 }, /* R402 */
- { 0x0000, 0x0000 }, /* R403 */
- { 0x0000, 0x0000 }, /* R404 */
- { 0x0000, 0x0000 }, /* R405 */
- { 0x0000, 0x0000 }, /* R406 */
- { 0x0000, 0x0000 }, /* R407 */
- { 0x0000, 0x0000 }, /* R408 */
- { 0x0000, 0x0000 }, /* R409 */
- { 0x0000, 0x0000 }, /* R410 */
- { 0x0000, 0x0000 }, /* R411 */
- { 0x0000, 0x0000 }, /* R412 */
- { 0x0000, 0x0000 }, /* R413 */
- { 0x0000, 0x0000 }, /* R414 */
- { 0x0000, 0x0000 }, /* R415 */
- { 0x0000, 0x0000 }, /* R416 */
- { 0x0000, 0x0000 }, /* R417 */
- { 0x0000, 0x0000 }, /* R418 */
- { 0x0000, 0x0000 }, /* R419 */
- { 0x0000, 0x0000 }, /* R420 */
- { 0x0000, 0x0000 }, /* R421 */
- { 0x0000, 0x0000 }, /* R422 */
- { 0x0000, 0x0000 }, /* R423 */
- { 0x0000, 0x0000 }, /* R424 */
- { 0x0000, 0x0000 }, /* R425 */
- { 0x0000, 0x0000 }, /* R426 */
- { 0x0000, 0x0000 }, /* R427 */
- { 0x0000, 0x0000 }, /* R428 */
- { 0x0000, 0x0000 }, /* R429 */
- { 0x0000, 0x0000 }, /* R430 */
- { 0x0000, 0x0000 }, /* R431 */
- { 0x0000, 0x0000 }, /* R432 */
- { 0x0000, 0x0000 }, /* R433 */
- { 0x0000, 0x0000 }, /* R434 */
- { 0x0000, 0x0000 }, /* R435 */
- { 0x0000, 0x0000 }, /* R436 */
- { 0x0000, 0x0000 }, /* R437 */
- { 0x0000, 0x0000 }, /* R438 */
- { 0x0000, 0x0000 }, /* R439 */
- { 0x0000, 0x0000 }, /* R440 */
- { 0x0000, 0x0000 }, /* R441 */
- { 0x0000, 0x0000 }, /* R442 */
- { 0x0000, 0x0000 }, /* R443 */
- { 0x0000, 0x0000 }, /* R444 */
- { 0x0000, 0x0000 }, /* R445 */
- { 0x0000, 0x0000 }, /* R446 */
- { 0x0000, 0x0000 }, /* R447 */
- { 0x0000, 0x0000 }, /* R448 */
- { 0x0000, 0x0000 }, /* R449 */
- { 0x0000, 0x0000 }, /* R450 */
- { 0x0000, 0x0000 }, /* R451 */
- { 0x0000, 0x0000 }, /* R452 */
- { 0x0000, 0x0000 }, /* R453 */
- { 0x0000, 0x0000 }, /* R454 */
- { 0x0000, 0x0000 }, /* R455 */
- { 0x0000, 0x0000 }, /* R456 */
- { 0x0000, 0x0000 }, /* R457 */
- { 0x0000, 0x0000 }, /* R458 */
- { 0x0000, 0x0000 }, /* R459 */
- { 0x0000, 0x0000 }, /* R460 */
- { 0x0000, 0x0000 }, /* R461 */
- { 0x0000, 0x0000 }, /* R462 */
- { 0x0000, 0x0000 }, /* R463 */
- { 0x0000, 0x0000 }, /* R464 */
- { 0x0000, 0x0000 }, /* R465 */
- { 0x0000, 0x0000 }, /* R466 */
- { 0x0000, 0x0000 }, /* R467 */
- { 0x0000, 0x0000 }, /* R468 */
- { 0x0000, 0x0000 }, /* R469 */
- { 0x0000, 0x0000 }, /* R470 */
- { 0x0000, 0x0000 }, /* R471 */
- { 0x0000, 0x0000 }, /* R472 */
- { 0x0000, 0x0000 }, /* R473 */
- { 0x0000, 0x0000 }, /* R474 */
- { 0x0000, 0x0000 }, /* R475 */
- { 0x0000, 0x0000 }, /* R476 */
- { 0x0000, 0x0000 }, /* R477 */
- { 0x0000, 0x0000 }, /* R478 */
- { 0x0000, 0x0000 }, /* R479 */
- { 0x0000, 0x0000 }, /* R480 */
- { 0x0000, 0x0000 }, /* R481 */
- { 0x0000, 0x0000 }, /* R482 */
- { 0x0000, 0x0000 }, /* R483 */
- { 0x0000, 0x0000 }, /* R484 */
- { 0x0000, 0x0000 }, /* R485 */
- { 0x0000, 0x0000 }, /* R486 */
- { 0x0000, 0x0000 }, /* R487 */
- { 0x0000, 0x0000 }, /* R488 */
- { 0x0000, 0x0000 }, /* R489 */
- { 0x0000, 0x0000 }, /* R490 */
- { 0x0000, 0x0000 }, /* R491 */
- { 0x0000, 0x0000 }, /* R492 */
- { 0x0000, 0x0000 }, /* R493 */
- { 0x0000, 0x0000 }, /* R494 */
- { 0x0000, 0x0000 }, /* R495 */
- { 0x0000, 0x0000 }, /* R496 */
- { 0x0000, 0x0000 }, /* R497 */
- { 0x0000, 0x0000 }, /* R498 */
- { 0x0000, 0x0000 }, /* R499 */
- { 0x0000, 0x0000 }, /* R500 */
- { 0x0000, 0x0000 }, /* R501 */
- { 0x0000, 0x0000 }, /* R502 */
- { 0x0000, 0x0000 }, /* R503 */
- { 0x0000, 0x0000 }, /* R504 */
- { 0x0000, 0x0000 }, /* R505 */
- { 0x0000, 0x0000 }, /* R506 */
- { 0x0000, 0x0000 }, /* R507 */
- { 0x0000, 0x0000 }, /* R508 */
- { 0x0000, 0x0000 }, /* R509 */
- { 0x0000, 0x0000 }, /* R510 */
- { 0x0000, 0x0000 }, /* R511 */
- { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
- { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
- { 0x0000, 0x0000 }, /* R514 */
- { 0x0000, 0x0000 }, /* R515 */
- { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
- { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
- { 0x0000, 0x0000 }, /* R518 */
- { 0x0000, 0x0000 }, /* R519 */
- { 0x001F, 0x001F }, /* R520 - Clocking (1) */
- { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
- { 0x0000, 0x0000 }, /* R522 */
- { 0x0000, 0x0000 }, /* R523 */
- { 0x0000, 0x0000 }, /* R524 */
- { 0x0000, 0x0000 }, /* R525 */
- { 0x0000, 0x0000 }, /* R526 */
- { 0x0000, 0x0000 }, /* R527 */
- { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
- { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
- { 0x000F, 0x0000 }, /* R530 - Rate Status */
- { 0x0000, 0x0000 }, /* R531 */
- { 0x0000, 0x0000 }, /* R532 */
- { 0x0000, 0x0000 }, /* R533 */
- { 0x0000, 0x0000 }, /* R534 */
- { 0x0000, 0x0000 }, /* R535 */
- { 0x0000, 0x0000 }, /* R536 */
- { 0x0000, 0x0000 }, /* R537 */
- { 0x0000, 0x0000 }, /* R538 */
- { 0x0000, 0x0000 }, /* R539 */
- { 0x0000, 0x0000 }, /* R540 */
- { 0x0000, 0x0000 }, /* R541 */
- { 0x0000, 0x0000 }, /* R542 */
- { 0x0000, 0x0000 }, /* R543 */
- { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
- { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
- { 0x0000, 0x0000 }, /* R549 */
- { 0x0000, 0x0000 }, /* R550 */
- { 0x0000, 0x0000 }, /* R551 */
- { 0x0000, 0x0000 }, /* R552 */
- { 0x0000, 0x0000 }, /* R553 */
- { 0x0000, 0x0000 }, /* R554 */
- { 0x0000, 0x0000 }, /* R555 */
- { 0x0000, 0x0000 }, /* R556 */
- { 0x0000, 0x0000 }, /* R557 */
- { 0x0000, 0x0000 }, /* R558 */
- { 0x0000, 0x0000 }, /* R559 */
- { 0x0000, 0x0000 }, /* R560 */
- { 0x0000, 0x0000 }, /* R561 */
- { 0x0000, 0x0000 }, /* R562 */
- { 0x0000, 0x0000 }, /* R563 */
- { 0x0000, 0x0000 }, /* R564 */
- { 0x0000, 0x0000 }, /* R565 */
- { 0x0000, 0x0000 }, /* R566 */
- { 0x0000, 0x0000 }, /* R567 */
- { 0x0000, 0x0000 }, /* R568 */
- { 0x0000, 0x0000 }, /* R569 */
- { 0x0000, 0x0000 }, /* R570 */
- { 0x0000, 0x0000 }, /* R571 */
- { 0x0000, 0x0000 }, /* R572 */
- { 0x0000, 0x0000 }, /* R573 */
- { 0x0000, 0x0000 }, /* R574 */
- { 0x0000, 0x0000 }, /* R575 */
- { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
- { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
- { 0x0000, 0x0000 }, /* R581 */
- { 0x0000, 0x0000 }, /* R582 */
- { 0x0000, 0x0000 }, /* R583 */
- { 0x0000, 0x0000 }, /* R584 */
- { 0x0000, 0x0000 }, /* R585 */
- { 0x0000, 0x0000 }, /* R586 */
- { 0x0000, 0x0000 }, /* R587 */
- { 0x0000, 0x0000 }, /* R588 */
- { 0x0000, 0x0000 }, /* R589 */
- { 0x0000, 0x0000 }, /* R590 */
- { 0x0000, 0x0000 }, /* R591 */
- { 0x0000, 0x0000 }, /* R592 */
- { 0x0000, 0x0000 }, /* R593 */
- { 0x0000, 0x0000 }, /* R594 */
- { 0x0000, 0x0000 }, /* R595 */
- { 0x0000, 0x0000 }, /* R596 */
- { 0x0000, 0x0000 }, /* R597 */
- { 0x0000, 0x0000 }, /* R598 */
- { 0x0000, 0x0000 }, /* R599 */
- { 0x0000, 0x0000 }, /* R600 */
- { 0x0000, 0x0000 }, /* R601 */
- { 0x0000, 0x0000 }, /* R602 */
- { 0x0000, 0x0000 }, /* R603 */
- { 0x0000, 0x0000 }, /* R604 */
- { 0x0000, 0x0000 }, /* R605 */
- { 0x0000, 0x0000 }, /* R606 */
- { 0x0000, 0x0000 }, /* R607 */
- { 0x0000, 0x0000 }, /* R608 */
- { 0x0000, 0x0000 }, /* R609 */
- { 0x0000, 0x0000 }, /* R610 */
- { 0x0000, 0x0000 }, /* R611 */
- { 0x0000, 0x0000 }, /* R612 */
- { 0x0000, 0x0000 }, /* R613 */
- { 0x0000, 0x0000 }, /* R614 */
- { 0x0000, 0x0000 }, /* R615 */
- { 0x0000, 0x0000 }, /* R616 */
- { 0x0000, 0x0000 }, /* R617 */
- { 0x0000, 0x0000 }, /* R618 */
- { 0x0000, 0x0000 }, /* R619 */
- { 0x0000, 0x0000 }, /* R620 */
- { 0x0000, 0x0000 }, /* R621 */
- { 0x0000, 0x0000 }, /* R622 */
- { 0x0000, 0x0000 }, /* R623 */
- { 0x0000, 0x0000 }, /* R624 */
- { 0x0000, 0x0000 }, /* R625 */
- { 0x0000, 0x0000 }, /* R626 */
- { 0x0000, 0x0000 }, /* R627 */
- { 0x0000, 0x0000 }, /* R628 */
- { 0x0000, 0x0000 }, /* R629 */
- { 0x0000, 0x0000 }, /* R630 */
- { 0x0000, 0x0000 }, /* R631 */
- { 0x0000, 0x0000 }, /* R632 */
- { 0x0000, 0x0000 }, /* R633 */
- { 0x0000, 0x0000 }, /* R634 */
- { 0x0000, 0x0000 }, /* R635 */
- { 0x0000, 0x0000 }, /* R636 */
- { 0x0000, 0x0000 }, /* R637 */
- { 0x0000, 0x0000 }, /* R638 */
- { 0x0000, 0x0000 }, /* R639 */
- { 0x0000, 0x0000 }, /* R640 */
- { 0x0000, 0x0000 }, /* R641 */
- { 0x0000, 0x0000 }, /* R642 */
- { 0x0000, 0x0000 }, /* R643 */
- { 0x0000, 0x0000 }, /* R644 */
- { 0x0000, 0x0000 }, /* R645 */
- { 0x0000, 0x0000 }, /* R646 */
- { 0x0000, 0x0000 }, /* R647 */
- { 0x0000, 0x0000 }, /* R648 */
- { 0x0000, 0x0000 }, /* R649 */
- { 0x0000, 0x0000 }, /* R650 */
- { 0x0000, 0x0000 }, /* R651 */
- { 0x0000, 0x0000 }, /* R652 */
- { 0x0000, 0x0000 }, /* R653 */
- { 0x0000, 0x0000 }, /* R654 */
- { 0x0000, 0x0000 }, /* R655 */
- { 0x0000, 0x0000 }, /* R656 */
- { 0x0000, 0x0000 }, /* R657 */
- { 0x0000, 0x0000 }, /* R658 */
- { 0x0000, 0x0000 }, /* R659 */
- { 0x0000, 0x0000 }, /* R660 */
- { 0x0000, 0x0000 }, /* R661 */
- { 0x0000, 0x0000 }, /* R662 */
- { 0x0000, 0x0000 }, /* R663 */
- { 0x0000, 0x0000 }, /* R664 */
- { 0x0000, 0x0000 }, /* R665 */
- { 0x0000, 0x0000 }, /* R666 */
- { 0x0000, 0x0000 }, /* R667 */
- { 0x0000, 0x0000 }, /* R668 */
- { 0x0000, 0x0000 }, /* R669 */
- { 0x0000, 0x0000 }, /* R670 */
- { 0x0000, 0x0000 }, /* R671 */
- { 0x0000, 0x0000 }, /* R672 */
- { 0x0000, 0x0000 }, /* R673 */
- { 0x0000, 0x0000 }, /* R674 */
- { 0x0000, 0x0000 }, /* R675 */
- { 0x0000, 0x0000 }, /* R676 */
- { 0x0000, 0x0000 }, /* R677 */
- { 0x0000, 0x0000 }, /* R678 */
- { 0x0000, 0x0000 }, /* R679 */
- { 0x0000, 0x0000 }, /* R680 */
- { 0x0000, 0x0000 }, /* R681 */
- { 0x0000, 0x0000 }, /* R682 */
- { 0x0000, 0x0000 }, /* R683 */
- { 0x0000, 0x0000 }, /* R684 */
- { 0x0000, 0x0000 }, /* R685 */
- { 0x0000, 0x0000 }, /* R686 */
- { 0x0000, 0x0000 }, /* R687 */
- { 0x0000, 0x0000 }, /* R688 */
- { 0x0000, 0x0000 }, /* R689 */
- { 0x0000, 0x0000 }, /* R690 */
- { 0x0000, 0x0000 }, /* R691 */
- { 0x0000, 0x0000 }, /* R692 */
- { 0x0000, 0x0000 }, /* R693 */
- { 0x0000, 0x0000 }, /* R694 */
- { 0x0000, 0x0000 }, /* R695 */
- { 0x0000, 0x0000 }, /* R696 */
- { 0x0000, 0x0000 }, /* R697 */
- { 0x0000, 0x0000 }, /* R698 */
- { 0x0000, 0x0000 }, /* R699 */
- { 0x0000, 0x0000 }, /* R700 */
- { 0x0000, 0x0000 }, /* R701 */
- { 0x0000, 0x0000 }, /* R702 */
- { 0x0000, 0x0000 }, /* R703 */
- { 0x0000, 0x0000 }, /* R704 */
- { 0x0000, 0x0000 }, /* R705 */
- { 0x0000, 0x0000 }, /* R706 */
- { 0x0000, 0x0000 }, /* R707 */
- { 0x0000, 0x0000 }, /* R708 */
- { 0x0000, 0x0000 }, /* R709 */
- { 0x0000, 0x0000 }, /* R710 */
- { 0x0000, 0x0000 }, /* R711 */
- { 0x0000, 0x0000 }, /* R712 */
- { 0x0000, 0x0000 }, /* R713 */
- { 0x0000, 0x0000 }, /* R714 */
- { 0x0000, 0x0000 }, /* R715 */
- { 0x0000, 0x0000 }, /* R716 */
- { 0x0000, 0x0000 }, /* R717 */
- { 0x0000, 0x0000 }, /* R718 */
- { 0x0000, 0x0000 }, /* R719 */
- { 0x0000, 0x0000 }, /* R720 */
- { 0x0000, 0x0000 }, /* R721 */
- { 0x0000, 0x0000 }, /* R722 */
- { 0x0000, 0x0000 }, /* R723 */
- { 0x0000, 0x0000 }, /* R724 */
- { 0x0000, 0x0000 }, /* R725 */
- { 0x0000, 0x0000 }, /* R726 */
- { 0x0000, 0x0000 }, /* R727 */
- { 0x0000, 0x0000 }, /* R728 */
- { 0x0000, 0x0000 }, /* R729 */
- { 0x0000, 0x0000 }, /* R730 */
- { 0x0000, 0x0000 }, /* R731 */
- { 0x0000, 0x0000 }, /* R732 */
- { 0x0000, 0x0000 }, /* R733 */
- { 0x0000, 0x0000 }, /* R734 */
- { 0x0000, 0x0000 }, /* R735 */
- { 0x0000, 0x0000 }, /* R736 */
- { 0x0000, 0x0000 }, /* R737 */
- { 0x0000, 0x0000 }, /* R738 */
- { 0x0000, 0x0000 }, /* R739 */
- { 0x0000, 0x0000 }, /* R740 */
- { 0x0000, 0x0000 }, /* R741 */
- { 0x0000, 0x0000 }, /* R742 */
- { 0x0000, 0x0000 }, /* R743 */
- { 0x0000, 0x0000 }, /* R744 */
- { 0x0000, 0x0000 }, /* R745 */
- { 0x0000, 0x0000 }, /* R746 */
- { 0x0000, 0x0000 }, /* R747 */
- { 0x0000, 0x0000 }, /* R748 */
- { 0x0000, 0x0000 }, /* R749 */
- { 0x0000, 0x0000 }, /* R750 */
- { 0x0000, 0x0000 }, /* R751 */
- { 0x0000, 0x0000 }, /* R752 */
- { 0x0000, 0x0000 }, /* R753 */
- { 0x0000, 0x0000 }, /* R754 */
- { 0x0000, 0x0000 }, /* R755 */
- { 0x0000, 0x0000 }, /* R756 */
- { 0x0000, 0x0000 }, /* R757 */
- { 0x0000, 0x0000 }, /* R758 */
- { 0x0000, 0x0000 }, /* R759 */
- { 0x0000, 0x0000 }, /* R760 */
- { 0x0000, 0x0000 }, /* R761 */
- { 0x0000, 0x0000 }, /* R762 */
- { 0x0000, 0x0000 }, /* R763 */
- { 0x0000, 0x0000 }, /* R764 */
- { 0x0000, 0x0000 }, /* R765 */
- { 0x0000, 0x0000 }, /* R766 */
- { 0x0000, 0x0000 }, /* R767 */
- { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
- { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
- { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
- { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
- { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
- { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
- { 0x0000, 0x0000 }, /* R776 */
- { 0x0000, 0x0000 }, /* R777 */
- { 0x0000, 0x0000 }, /* R778 */
- { 0x0000, 0x0000 }, /* R779 */
- { 0x0000, 0x0000 }, /* R780 */
- { 0x0000, 0x0000 }, /* R781 */
- { 0x0000, 0x0000 }, /* R782 */
- { 0x0000, 0x0000 }, /* R783 */
- { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
- { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
- { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
- { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
- { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
- { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
- { 0x0000, 0x0000 }, /* R792 */
- { 0x0000, 0x0000 }, /* R793 */
- { 0x0000, 0x0000 }, /* R794 */
- { 0x0000, 0x0000 }, /* R795 */
- { 0x0000, 0x0000 }, /* R796 */
- { 0x0000, 0x0000 }, /* R797 */
- { 0x0000, 0x0000 }, /* R798 */
- { 0x0000, 0x0000 }, /* R799 */
- { 0x0000, 0x0000 }, /* R800 */
- { 0x0000, 0x0000 }, /* R801 */
- { 0x0000, 0x0000 }, /* R802 */
- { 0x0000, 0x0000 }, /* R803 */
- { 0x0000, 0x0000 }, /* R804 */
- { 0x0000, 0x0000 }, /* R805 */
- { 0x0000, 0x0000 }, /* R806 */
- { 0x0000, 0x0000 }, /* R807 */
- { 0x0000, 0x0000 }, /* R808 */
- { 0x0000, 0x0000 }, /* R809 */
- { 0x0000, 0x0000 }, /* R810 */
- { 0x0000, 0x0000 }, /* R811 */
- { 0x0000, 0x0000 }, /* R812 */
- { 0x0000, 0x0000 }, /* R813 */
- { 0x0000, 0x0000 }, /* R814 */
- { 0x0000, 0x0000 }, /* R815 */
- { 0x0000, 0x0000 }, /* R816 */
- { 0x0000, 0x0000 }, /* R817 */
- { 0x0000, 0x0000 }, /* R818 */
- { 0x0000, 0x0000 }, /* R819 */
- { 0x0000, 0x0000 }, /* R820 */
- { 0x0000, 0x0000 }, /* R821 */
- { 0x0000, 0x0000 }, /* R822 */
- { 0x0000, 0x0000 }, /* R823 */
- { 0x0000, 0x0000 }, /* R824 */
- { 0x0000, 0x0000 }, /* R825 */
- { 0x0000, 0x0000 }, /* R826 */
- { 0x0000, 0x0000 }, /* R827 */
- { 0x0000, 0x0000 }, /* R828 */
- { 0x0000, 0x0000 }, /* R829 */
- { 0x0000, 0x0000 }, /* R830 */
- { 0x0000, 0x0000 }, /* R831 */
- { 0x0000, 0x0000 }, /* R832 */
- { 0x0000, 0x0000 }, /* R833 */
- { 0x0000, 0x0000 }, /* R834 */
- { 0x0000, 0x0000 }, /* R835 */
- { 0x0000, 0x0000 }, /* R836 */
- { 0x0000, 0x0000 }, /* R837 */
- { 0x0000, 0x0000 }, /* R838 */
- { 0x0000, 0x0000 }, /* R839 */
- { 0x0000, 0x0000 }, /* R840 */
- { 0x0000, 0x0000 }, /* R841 */
- { 0x0000, 0x0000 }, /* R842 */
- { 0x0000, 0x0000 }, /* R843 */
- { 0x0000, 0x0000 }, /* R844 */
- { 0x0000, 0x0000 }, /* R845 */
- { 0x0000, 0x0000 }, /* R846 */
- { 0x0000, 0x0000 }, /* R847 */
- { 0x0000, 0x0000 }, /* R848 */
- { 0x0000, 0x0000 }, /* R849 */
- { 0x0000, 0x0000 }, /* R850 */
- { 0x0000, 0x0000 }, /* R851 */
- { 0x0000, 0x0000 }, /* R852 */
- { 0x0000, 0x0000 }, /* R853 */
- { 0x0000, 0x0000 }, /* R854 */
- { 0x0000, 0x0000 }, /* R855 */
- { 0x0000, 0x0000 }, /* R856 */
- { 0x0000, 0x0000 }, /* R857 */
- { 0x0000, 0x0000 }, /* R858 */
- { 0x0000, 0x0000 }, /* R859 */
- { 0x0000, 0x0000 }, /* R860 */
- { 0x0000, 0x0000 }, /* R861 */
- { 0x0000, 0x0000 }, /* R862 */
- { 0x0000, 0x0000 }, /* R863 */
- { 0x0000, 0x0000 }, /* R864 */
- { 0x0000, 0x0000 }, /* R865 */
- { 0x0000, 0x0000 }, /* R866 */
- { 0x0000, 0x0000 }, /* R867 */
- { 0x0000, 0x0000 }, /* R868 */
- { 0x0000, 0x0000 }, /* R869 */
- { 0x0000, 0x0000 }, /* R870 */
- { 0x0000, 0x0000 }, /* R871 */
- { 0x0000, 0x0000 }, /* R872 */
- { 0x0000, 0x0000 }, /* R873 */
- { 0x0000, 0x0000 }, /* R874 */
- { 0x0000, 0x0000 }, /* R875 */
- { 0x0000, 0x0000 }, /* R876 */
- { 0x0000, 0x0000 }, /* R877 */
- { 0x0000, 0x0000 }, /* R878 */
- { 0x0000, 0x0000 }, /* R879 */
- { 0x0000, 0x0000 }, /* R880 */
- { 0x0000, 0x0000 }, /* R881 */
- { 0x0000, 0x0000 }, /* R882 */
- { 0x0000, 0x0000 }, /* R883 */
- { 0x0000, 0x0000 }, /* R884 */
- { 0x0000, 0x0000 }, /* R885 */
- { 0x0000, 0x0000 }, /* R886 */
- { 0x0000, 0x0000 }, /* R887 */
- { 0x0000, 0x0000 }, /* R888 */
- { 0x0000, 0x0000 }, /* R889 */
- { 0x0000, 0x0000 }, /* R890 */
- { 0x0000, 0x0000 }, /* R891 */
- { 0x0000, 0x0000 }, /* R892 */
- { 0x0000, 0x0000 }, /* R893 */
- { 0x0000, 0x0000 }, /* R894 */
- { 0x0000, 0x0000 }, /* R895 */
- { 0x0000, 0x0000 }, /* R896 */
- { 0x0000, 0x0000 }, /* R897 */
- { 0x0000, 0x0000 }, /* R898 */
- { 0x0000, 0x0000 }, /* R899 */
- { 0x0000, 0x0000 }, /* R900 */
- { 0x0000, 0x0000 }, /* R901 */
- { 0x0000, 0x0000 }, /* R902 */
- { 0x0000, 0x0000 }, /* R903 */
- { 0x0000, 0x0000 }, /* R904 */
- { 0x0000, 0x0000 }, /* R905 */
- { 0x0000, 0x0000 }, /* R906 */
- { 0x0000, 0x0000 }, /* R907 */
- { 0x0000, 0x0000 }, /* R908 */
- { 0x0000, 0x0000 }, /* R909 */
- { 0x0000, 0x0000 }, /* R910 */
- { 0x0000, 0x0000 }, /* R911 */
- { 0x0000, 0x0000 }, /* R912 */
- { 0x0000, 0x0000 }, /* R913 */
- { 0x0000, 0x0000 }, /* R914 */
- { 0x0000, 0x0000 }, /* R915 */
- { 0x0000, 0x0000 }, /* R916 */
- { 0x0000, 0x0000 }, /* R917 */
- { 0x0000, 0x0000 }, /* R918 */
- { 0x0000, 0x0000 }, /* R919 */
- { 0x0000, 0x0000 }, /* R920 */
- { 0x0000, 0x0000 }, /* R921 */
- { 0x0000, 0x0000 }, /* R922 */
- { 0x0000, 0x0000 }, /* R923 */
- { 0x0000, 0x0000 }, /* R924 */
- { 0x0000, 0x0000 }, /* R925 */
- { 0x0000, 0x0000 }, /* R926 */
- { 0x0000, 0x0000 }, /* R927 */
- { 0x0000, 0x0000 }, /* R928 */
- { 0x0000, 0x0000 }, /* R929 */
- { 0x0000, 0x0000 }, /* R930 */
- { 0x0000, 0x0000 }, /* R931 */
- { 0x0000, 0x0000 }, /* R932 */
- { 0x0000, 0x0000 }, /* R933 */
- { 0x0000, 0x0000 }, /* R934 */
- { 0x0000, 0x0000 }, /* R935 */
- { 0x0000, 0x0000 }, /* R936 */
- { 0x0000, 0x0000 }, /* R937 */
- { 0x0000, 0x0000 }, /* R938 */
- { 0x0000, 0x0000 }, /* R939 */
- { 0x0000, 0x0000 }, /* R940 */
- { 0x0000, 0x0000 }, /* R941 */
- { 0x0000, 0x0000 }, /* R942 */
- { 0x0000, 0x0000 }, /* R943 */
- { 0x0000, 0x0000 }, /* R944 */
- { 0x0000, 0x0000 }, /* R945 */
- { 0x0000, 0x0000 }, /* R946 */
- { 0x0000, 0x0000 }, /* R947 */
- { 0x0000, 0x0000 }, /* R948 */
- { 0x0000, 0x0000 }, /* R949 */
- { 0x0000, 0x0000 }, /* R950 */
- { 0x0000, 0x0000 }, /* R951 */
- { 0x0000, 0x0000 }, /* R952 */
- { 0x0000, 0x0000 }, /* R953 */
- { 0x0000, 0x0000 }, /* R954 */
- { 0x0000, 0x0000 }, /* R955 */
- { 0x0000, 0x0000 }, /* R956 */
- { 0x0000, 0x0000 }, /* R957 */
- { 0x0000, 0x0000 }, /* R958 */
- { 0x0000, 0x0000 }, /* R959 */
- { 0x0000, 0x0000 }, /* R960 */
- { 0x0000, 0x0000 }, /* R961 */
- { 0x0000, 0x0000 }, /* R962 */
- { 0x0000, 0x0000 }, /* R963 */
- { 0x0000, 0x0000 }, /* R964 */
- { 0x0000, 0x0000 }, /* R965 */
- { 0x0000, 0x0000 }, /* R966 */
- { 0x0000, 0x0000 }, /* R967 */
- { 0x0000, 0x0000 }, /* R968 */
- { 0x0000, 0x0000 }, /* R969 */
- { 0x0000, 0x0000 }, /* R970 */
- { 0x0000, 0x0000 }, /* R971 */
- { 0x0000, 0x0000 }, /* R972 */
- { 0x0000, 0x0000 }, /* R973 */
- { 0x0000, 0x0000 }, /* R974 */
- { 0x0000, 0x0000 }, /* R975 */
- { 0x0000, 0x0000 }, /* R976 */
- { 0x0000, 0x0000 }, /* R977 */
- { 0x0000, 0x0000 }, /* R978 */
- { 0x0000, 0x0000 }, /* R979 */
- { 0x0000, 0x0000 }, /* R980 */
- { 0x0000, 0x0000 }, /* R981 */
- { 0x0000, 0x0000 }, /* R982 */
- { 0x0000, 0x0000 }, /* R983 */
- { 0x0000, 0x0000 }, /* R984 */
- { 0x0000, 0x0000 }, /* R985 */
- { 0x0000, 0x0000 }, /* R986 */
- { 0x0000, 0x0000 }, /* R987 */
- { 0x0000, 0x0000 }, /* R988 */
- { 0x0000, 0x0000 }, /* R989 */
- { 0x0000, 0x0000 }, /* R990 */
- { 0x0000, 0x0000 }, /* R991 */
- { 0x0000, 0x0000 }, /* R992 */
- { 0x0000, 0x0000 }, /* R993 */
- { 0x0000, 0x0000 }, /* R994 */
- { 0x0000, 0x0000 }, /* R995 */
- { 0x0000, 0x0000 }, /* R996 */
- { 0x0000, 0x0000 }, /* R997 */
- { 0x0000, 0x0000 }, /* R998 */
- { 0x0000, 0x0000 }, /* R999 */
- { 0x0000, 0x0000 }, /* R1000 */
- { 0x0000, 0x0000 }, /* R1001 */
- { 0x0000, 0x0000 }, /* R1002 */
- { 0x0000, 0x0000 }, /* R1003 */
- { 0x0000, 0x0000 }, /* R1004 */
- { 0x0000, 0x0000 }, /* R1005 */
- { 0x0000, 0x0000 }, /* R1006 */
- { 0x0000, 0x0000 }, /* R1007 */
- { 0x0000, 0x0000 }, /* R1008 */
- { 0x0000, 0x0000 }, /* R1009 */
- { 0x0000, 0x0000 }, /* R1010 */
- { 0x0000, 0x0000 }, /* R1011 */
- { 0x0000, 0x0000 }, /* R1012 */
- { 0x0000, 0x0000 }, /* R1013 */
- { 0x0000, 0x0000 }, /* R1014 */
- { 0x0000, 0x0000 }, /* R1015 */
- { 0x0000, 0x0000 }, /* R1016 */
- { 0x0000, 0x0000 }, /* R1017 */
- { 0x0000, 0x0000 }, /* R1018 */
- { 0x0000, 0x0000 }, /* R1019 */
- { 0x0000, 0x0000 }, /* R1020 */
- { 0x0000, 0x0000 }, /* R1021 */
- { 0x0000, 0x0000 }, /* R1022 */
- { 0x0000, 0x0000 }, /* R1023 */
- { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
- { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
- { 0x0000, 0x0000 }, /* R1032 */
- { 0x0000, 0x0000 }, /* R1033 */
- { 0x0000, 0x0000 }, /* R1034 */
- { 0x0000, 0x0000 }, /* R1035 */
- { 0x0000, 0x0000 }, /* R1036 */
- { 0x0000, 0x0000 }, /* R1037 */
- { 0x0000, 0x0000 }, /* R1038 */
- { 0x0000, 0x0000 }, /* R1039 */
- { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
- { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
- { 0x0000, 0x0000 }, /* R1042 */
- { 0x0000, 0x0000 }, /* R1043 */
- { 0x0000, 0x0000 }, /* R1044 */
- { 0x0000, 0x0000 }, /* R1045 */
- { 0x0000, 0x0000 }, /* R1046 */
- { 0x0000, 0x0000 }, /* R1047 */
- { 0x0000, 0x0000 }, /* R1048 */
- { 0x0000, 0x0000 }, /* R1049 */
- { 0x0000, 0x0000 }, /* R1050 */
- { 0x0000, 0x0000 }, /* R1051 */
- { 0x0000, 0x0000 }, /* R1052 */
- { 0x0000, 0x0000 }, /* R1053 */
- { 0x0000, 0x0000 }, /* R1054 */
- { 0x0000, 0x0000 }, /* R1055 */
- { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
- { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
- { 0x0000, 0x0000 }, /* R1060 */
- { 0x0000, 0x0000 }, /* R1061 */
- { 0x0000, 0x0000 }, /* R1062 */
- { 0x0000, 0x0000 }, /* R1063 */
- { 0x0000, 0x0000 }, /* R1064 */
- { 0x0000, 0x0000 }, /* R1065 */
- { 0x0000, 0x0000 }, /* R1066 */
- { 0x0000, 0x0000 }, /* R1067 */
- { 0x0000, 0x0000 }, /* R1068 */
- { 0x0000, 0x0000 }, /* R1069 */
- { 0x0000, 0x0000 }, /* R1070 */
- { 0x0000, 0x0000 }, /* R1071 */
- { 0x0000, 0x0000 }, /* R1072 */
- { 0x0000, 0x0000 }, /* R1073 */
- { 0x0000, 0x0000 }, /* R1074 */
- { 0x0000, 0x0000 }, /* R1075 */
- { 0x0000, 0x0000 }, /* R1076 */
- { 0x0000, 0x0000 }, /* R1077 */
- { 0x0000, 0x0000 }, /* R1078 */
- { 0x0000, 0x0000 }, /* R1079 */
- { 0x0000, 0x0000 }, /* R1080 */
- { 0x0000, 0x0000 }, /* R1081 */
- { 0x0000, 0x0000 }, /* R1082 */
- { 0x0000, 0x0000 }, /* R1083 */
- { 0x0000, 0x0000 }, /* R1084 */
- { 0x0000, 0x0000 }, /* R1085 */
- { 0x0000, 0x0000 }, /* R1086 */
- { 0x0000, 0x0000 }, /* R1087 */
- { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
- { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
- { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
- { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
- { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
- { 0x0000, 0x0000 }, /* R1093 */
- { 0x0000, 0x0000 }, /* R1094 */
- { 0x0000, 0x0000 }, /* R1095 */
- { 0x0000, 0x0000 }, /* R1096 */
- { 0x0000, 0x0000 }, /* R1097 */
- { 0x0000, 0x0000 }, /* R1098 */
- { 0x0000, 0x0000 }, /* R1099 */
- { 0x0000, 0x0000 }, /* R1100 */
- { 0x0000, 0x0000 }, /* R1101 */
- { 0x0000, 0x0000 }, /* R1102 */
- { 0x0000, 0x0000 }, /* R1103 */
- { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
- { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
- { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
- { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
- { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
- { 0x0000, 0x0000 }, /* R1109 */
- { 0x0000, 0x0000 }, /* R1110 */
- { 0x0000, 0x0000 }, /* R1111 */
- { 0x0000, 0x0000 }, /* R1112 */
- { 0x0000, 0x0000 }, /* R1113 */
- { 0x0000, 0x0000 }, /* R1114 */
- { 0x0000, 0x0000 }, /* R1115 */
- { 0x0000, 0x0000 }, /* R1116 */
- { 0x0000, 0x0000 }, /* R1117 */
- { 0x0000, 0x0000 }, /* R1118 */
- { 0x0000, 0x0000 }, /* R1119 */
- { 0x0000, 0x0000 }, /* R1120 */
- { 0x0000, 0x0000 }, /* R1121 */
- { 0x0000, 0x0000 }, /* R1122 */
- { 0x0000, 0x0000 }, /* R1123 */
- { 0x0000, 0x0000 }, /* R1124 */
- { 0x0000, 0x0000 }, /* R1125 */
- { 0x0000, 0x0000 }, /* R1126 */
- { 0x0000, 0x0000 }, /* R1127 */
- { 0x0000, 0x0000 }, /* R1128 */
- { 0x0000, 0x0000 }, /* R1129 */
- { 0x0000, 0x0000 }, /* R1130 */
- { 0x0000, 0x0000 }, /* R1131 */
- { 0x0000, 0x0000 }, /* R1132 */
- { 0x0000, 0x0000 }, /* R1133 */
- { 0x0000, 0x0000 }, /* R1134 */
- { 0x0000, 0x0000 }, /* R1135 */
- { 0x0000, 0x0000 }, /* R1136 */
- { 0x0000, 0x0000 }, /* R1137 */
- { 0x0000, 0x0000 }, /* R1138 */
- { 0x0000, 0x0000 }, /* R1139 */
- { 0x0000, 0x0000 }, /* R1140 */
- { 0x0000, 0x0000 }, /* R1141 */
- { 0x0000, 0x0000 }, /* R1142 */
- { 0x0000, 0x0000 }, /* R1143 */
- { 0x0000, 0x0000 }, /* R1144 */
- { 0x0000, 0x0000 }, /* R1145 */
- { 0x0000, 0x0000 }, /* R1146 */
- { 0x0000, 0x0000 }, /* R1147 */
- { 0x0000, 0x0000 }, /* R1148 */
- { 0x0000, 0x0000 }, /* R1149 */
- { 0x0000, 0x0000 }, /* R1150 */
- { 0x0000, 0x0000 }, /* R1151 */
- { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1172 */
- { 0x0000, 0x0000 }, /* R1173 */
- { 0x0000, 0x0000 }, /* R1174 */
- { 0x0000, 0x0000 }, /* R1175 */
- { 0x0000, 0x0000 }, /* R1176 */
- { 0x0000, 0x0000 }, /* R1177 */
- { 0x0000, 0x0000 }, /* R1178 */
- { 0x0000, 0x0000 }, /* R1179 */
- { 0x0000, 0x0000 }, /* R1180 */
- { 0x0000, 0x0000 }, /* R1181 */
- { 0x0000, 0x0000 }, /* R1182 */
- { 0x0000, 0x0000 }, /* R1183 */
- { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1204 */
- { 0x0000, 0x0000 }, /* R1205 */
- { 0x0000, 0x0000 }, /* R1206 */
- { 0x0000, 0x0000 }, /* R1207 */
- { 0x0000, 0x0000 }, /* R1208 */
- { 0x0000, 0x0000 }, /* R1209 */
- { 0x0000, 0x0000 }, /* R1210 */
- { 0x0000, 0x0000 }, /* R1211 */
- { 0x0000, 0x0000 }, /* R1212 */
- { 0x0000, 0x0000 }, /* R1213 */
- { 0x0000, 0x0000 }, /* R1214 */
- { 0x0000, 0x0000 }, /* R1215 */
- { 0x0000, 0x0000 }, /* R1216 */
- { 0x0000, 0x0000 }, /* R1217 */
- { 0x0000, 0x0000 }, /* R1218 */
- { 0x0000, 0x0000 }, /* R1219 */
- { 0x0000, 0x0000 }, /* R1220 */
- { 0x0000, 0x0000 }, /* R1221 */
- { 0x0000, 0x0000 }, /* R1222 */
- { 0x0000, 0x0000 }, /* R1223 */
- { 0x0000, 0x0000 }, /* R1224 */
- { 0x0000, 0x0000 }, /* R1225 */
- { 0x0000, 0x0000 }, /* R1226 */
- { 0x0000, 0x0000 }, /* R1227 */
- { 0x0000, 0x0000 }, /* R1228 */
- { 0x0000, 0x0000 }, /* R1229 */
- { 0x0000, 0x0000 }, /* R1230 */
- { 0x0000, 0x0000 }, /* R1231 */
- { 0x0000, 0x0000 }, /* R1232 */
- { 0x0000, 0x0000 }, /* R1233 */
- { 0x0000, 0x0000 }, /* R1234 */
- { 0x0000, 0x0000 }, /* R1235 */
- { 0x0000, 0x0000 }, /* R1236 */
- { 0x0000, 0x0000 }, /* R1237 */
- { 0x0000, 0x0000 }, /* R1238 */
- { 0x0000, 0x0000 }, /* R1239 */
- { 0x0000, 0x0000 }, /* R1240 */
- { 0x0000, 0x0000 }, /* R1241 */
- { 0x0000, 0x0000 }, /* R1242 */
- { 0x0000, 0x0000 }, /* R1243 */
- { 0x0000, 0x0000 }, /* R1244 */
- { 0x0000, 0x0000 }, /* R1245 */
- { 0x0000, 0x0000 }, /* R1246 */
- { 0x0000, 0x0000 }, /* R1247 */
- { 0x0000, 0x0000 }, /* R1248 */
- { 0x0000, 0x0000 }, /* R1249 */
- { 0x0000, 0x0000 }, /* R1250 */
- { 0x0000, 0x0000 }, /* R1251 */
- { 0x0000, 0x0000 }, /* R1252 */
- { 0x0000, 0x0000 }, /* R1253 */
- { 0x0000, 0x0000 }, /* R1254 */
- { 0x0000, 0x0000 }, /* R1255 */
- { 0x0000, 0x0000 }, /* R1256 */
- { 0x0000, 0x0000 }, /* R1257 */
- { 0x0000, 0x0000 }, /* R1258 */
- { 0x0000, 0x0000 }, /* R1259 */
- { 0x0000, 0x0000 }, /* R1260 */
- { 0x0000, 0x0000 }, /* R1261 */
- { 0x0000, 0x0000 }, /* R1262 */
- { 0x0000, 0x0000 }, /* R1263 */
- { 0x0000, 0x0000 }, /* R1264 */
- { 0x0000, 0x0000 }, /* R1265 */
- { 0x0000, 0x0000 }, /* R1266 */
- { 0x0000, 0x0000 }, /* R1267 */
- { 0x0000, 0x0000 }, /* R1268 */
- { 0x0000, 0x0000 }, /* R1269 */
- { 0x0000, 0x0000 }, /* R1270 */
- { 0x0000, 0x0000 }, /* R1271 */
- { 0x0000, 0x0000 }, /* R1272 */
- { 0x0000, 0x0000 }, /* R1273 */
- { 0x0000, 0x0000 }, /* R1274 */
- { 0x0000, 0x0000 }, /* R1275 */
- { 0x0000, 0x0000 }, /* R1276 */
- { 0x0000, 0x0000 }, /* R1277 */
- { 0x0000, 0x0000 }, /* R1278 */
- { 0x0000, 0x0000 }, /* R1279 */
- { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
- { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
- { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
- { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
- { 0x0000, 0x0000 }, /* R1284 */
- { 0x0000, 0x0000 }, /* R1285 */
- { 0x0000, 0x0000 }, /* R1286 */
- { 0x0000, 0x0000 }, /* R1287 */
- { 0x0000, 0x0000 }, /* R1288 */
- { 0x0000, 0x0000 }, /* R1289 */
- { 0x0000, 0x0000 }, /* R1290 */
- { 0x0000, 0x0000 }, /* R1291 */
- { 0x0000, 0x0000 }, /* R1292 */
- { 0x0000, 0x0000 }, /* R1293 */
- { 0x0000, 0x0000 }, /* R1294 */
- { 0x0000, 0x0000 }, /* R1295 */
- { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
- { 0x0000, 0x0000 }, /* R1297 */
- { 0x0000, 0x0000 }, /* R1298 */
- { 0x0000, 0x0000 }, /* R1299 */
- { 0x0000, 0x0000 }, /* R1300 */
- { 0x0000, 0x0000 }, /* R1301 */
- { 0x0000, 0x0000 }, /* R1302 */
- { 0x0000, 0x0000 }, /* R1303 */
- { 0x0000, 0x0000 }, /* R1304 */
- { 0x0000, 0x0000 }, /* R1305 */
- { 0x0000, 0x0000 }, /* R1306 */
- { 0x0000, 0x0000 }, /* R1307 */
- { 0x0000, 0x0000 }, /* R1308 */
- { 0x0000, 0x0000 }, /* R1309 */
- { 0x0000, 0x0000 }, /* R1310 */
- { 0x0000, 0x0000 }, /* R1311 */
- { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
- { 0x0000, 0x0000 }, /* R1314 */
- { 0x0000, 0x0000 }, /* R1315 */
- { 0x0000, 0x0000 }, /* R1316 */
- { 0x0000, 0x0000 }, /* R1317 */
- { 0x0000, 0x0000 }, /* R1318 */
- { 0x0000, 0x0000 }, /* R1319 */
- { 0x0000, 0x0000 }, /* R1320 */
- { 0x0000, 0x0000 }, /* R1321 */
- { 0x0000, 0x0000 }, /* R1322 */
- { 0x0000, 0x0000 }, /* R1323 */
- { 0x0000, 0x0000 }, /* R1324 */
- { 0x0000, 0x0000 }, /* R1325 */
- { 0x0000, 0x0000 }, /* R1326 */
- { 0x0000, 0x0000 }, /* R1327 */
- { 0x0000, 0x0000 }, /* R1328 */
- { 0x0000, 0x0000 }, /* R1329 */
- { 0x0000, 0x0000 }, /* R1330 */
- { 0x0000, 0x0000 }, /* R1331 */
- { 0x0000, 0x0000 }, /* R1332 */
- { 0x0000, 0x0000 }, /* R1333 */
- { 0x0000, 0x0000 }, /* R1334 */
- { 0x0000, 0x0000 }, /* R1335 */
- { 0x0000, 0x0000 }, /* R1336 */
- { 0x0000, 0x0000 }, /* R1337 */
- { 0x0000, 0x0000 }, /* R1338 */
- { 0x0000, 0x0000 }, /* R1339 */
- { 0x0000, 0x0000 }, /* R1340 */
- { 0x0000, 0x0000 }, /* R1341 */
- { 0x0000, 0x0000 }, /* R1342 */
- { 0x0000, 0x0000 }, /* R1343 */
- { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
- { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
- { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
- { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
- { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
- { 0x0000, 0x0000 }, /* R1349 */
- { 0x0000, 0x0000 }, /* R1350 */
- { 0x0000, 0x0000 }, /* R1351 */
- { 0x0000, 0x0000 }, /* R1352 */
- { 0x0000, 0x0000 }, /* R1353 */
- { 0x0000, 0x0000 }, /* R1354 */
- { 0x0000, 0x0000 }, /* R1355 */
- { 0x0000, 0x0000 }, /* R1356 */
- { 0x0000, 0x0000 }, /* R1357 */
- { 0x0000, 0x0000 }, /* R1358 */
- { 0x0000, 0x0000 }, /* R1359 */
- { 0x0000, 0x0000 }, /* R1360 */
- { 0x0000, 0x0000 }, /* R1361 */
- { 0x0000, 0x0000 }, /* R1362 */
- { 0x0000, 0x0000 }, /* R1363 */
- { 0x0000, 0x0000 }, /* R1364 */
- { 0x0000, 0x0000 }, /* R1365 */
- { 0x0000, 0x0000 }, /* R1366 */
- { 0x0000, 0x0000 }, /* R1367 */
- { 0x0000, 0x0000 }, /* R1368 */
- { 0x0000, 0x0000 }, /* R1369 */
- { 0x0000, 0x0000 }, /* R1370 */
- { 0x0000, 0x0000 }, /* R1371 */
- { 0x0000, 0x0000 }, /* R1372 */
- { 0x0000, 0x0000 }, /* R1373 */
- { 0x0000, 0x0000 }, /* R1374 */
- { 0x0000, 0x0000 }, /* R1375 */
- { 0x0000, 0x0000 }, /* R1376 */
- { 0x0000, 0x0000 }, /* R1377 */
- { 0x0000, 0x0000 }, /* R1378 */
- { 0x0000, 0x0000 }, /* R1379 */
- { 0x0000, 0x0000 }, /* R1380 */
- { 0x0000, 0x0000 }, /* R1381 */
- { 0x0000, 0x0000 }, /* R1382 */
- { 0x0000, 0x0000 }, /* R1383 */
- { 0x0000, 0x0000 }, /* R1384 */
- { 0x0000, 0x0000 }, /* R1385 */
- { 0x0000, 0x0000 }, /* R1386 */
- { 0x0000, 0x0000 }, /* R1387 */
- { 0x0000, 0x0000 }, /* R1388 */
- { 0x0000, 0x0000 }, /* R1389 */
- { 0x0000, 0x0000 }, /* R1390 */
- { 0x0000, 0x0000 }, /* R1391 */
- { 0x0000, 0x0000 }, /* R1392 */
- { 0x0000, 0x0000 }, /* R1393 */
- { 0x0000, 0x0000 }, /* R1394 */
- { 0x0000, 0x0000 }, /* R1395 */
- { 0x0000, 0x0000 }, /* R1396 */
- { 0x0000, 0x0000 }, /* R1397 */
- { 0x0000, 0x0000 }, /* R1398 */
- { 0x0000, 0x0000 }, /* R1399 */
- { 0x0000, 0x0000 }, /* R1400 */
- { 0x0000, 0x0000 }, /* R1401 */
- { 0x0000, 0x0000 }, /* R1402 */
- { 0x0000, 0x0000 }, /* R1403 */
- { 0x0000, 0x0000 }, /* R1404 */
- { 0x0000, 0x0000 }, /* R1405 */
- { 0x0000, 0x0000 }, /* R1406 */
- { 0x0000, 0x0000 }, /* R1407 */
- { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1428 */
- { 0x0000, 0x0000 }, /* R1429 */
- { 0x0000, 0x0000 }, /* R1430 */
- { 0x0000, 0x0000 }, /* R1431 */
- { 0x0000, 0x0000 }, /* R1432 */
- { 0x0000, 0x0000 }, /* R1433 */
- { 0x0000, 0x0000 }, /* R1434 */
- { 0x0000, 0x0000 }, /* R1435 */
- { 0x0000, 0x0000 }, /* R1436 */
- { 0x0000, 0x0000 }, /* R1437 */
- { 0x0000, 0x0000 }, /* R1438 */
- { 0x0000, 0x0000 }, /* R1439 */
- { 0x0000, 0x0000 }, /* R1440 */
- { 0x0000, 0x0000 }, /* R1441 */
- { 0x0000, 0x0000 }, /* R1442 */
- { 0x0000, 0x0000 }, /* R1443 */
- { 0x0000, 0x0000 }, /* R1444 */
- { 0x0000, 0x0000 }, /* R1445 */
- { 0x0000, 0x0000 }, /* R1446 */
- { 0x0000, 0x0000 }, /* R1447 */
- { 0x0000, 0x0000 }, /* R1448 */
- { 0x0000, 0x0000 }, /* R1449 */
- { 0x0000, 0x0000 }, /* R1450 */
- { 0x0000, 0x0000 }, /* R1451 */
- { 0x0000, 0x0000 }, /* R1452 */
- { 0x0000, 0x0000 }, /* R1453 */
- { 0x0000, 0x0000 }, /* R1454 */
- { 0x0000, 0x0000 }, /* R1455 */
- { 0x0000, 0x0000 }, /* R1456 */
- { 0x0000, 0x0000 }, /* R1457 */
- { 0x0000, 0x0000 }, /* R1458 */
- { 0x0000, 0x0000 }, /* R1459 */
- { 0x0000, 0x0000 }, /* R1460 */
- { 0x0000, 0x0000 }, /* R1461 */
- { 0x0000, 0x0000 }, /* R1462 */
- { 0x0000, 0x0000 }, /* R1463 */
- { 0x0000, 0x0000 }, /* R1464 */
- { 0x0000, 0x0000 }, /* R1465 */
- { 0x0000, 0x0000 }, /* R1466 */
- { 0x0000, 0x0000 }, /* R1467 */
- { 0x0000, 0x0000 }, /* R1468 */
- { 0x0000, 0x0000 }, /* R1469 */
- { 0x0000, 0x0000 }, /* R1470 */
- { 0x0000, 0x0000 }, /* R1471 */
- { 0x0000, 0x0000 }, /* R1472 */
- { 0x0000, 0x0000 }, /* R1473 */
- { 0x0000, 0x0000 }, /* R1474 */
- { 0x0000, 0x0000 }, /* R1475 */
- { 0x0000, 0x0000 }, /* R1476 */
- { 0x0000, 0x0000 }, /* R1477 */
- { 0x0000, 0x0000 }, /* R1478 */
- { 0x0000, 0x0000 }, /* R1479 */
- { 0x0000, 0x0000 }, /* R1480 */
- { 0x0000, 0x0000 }, /* R1481 */
- { 0x0000, 0x0000 }, /* R1482 */
- { 0x0000, 0x0000 }, /* R1483 */
- { 0x0000, 0x0000 }, /* R1484 */
- { 0x0000, 0x0000 }, /* R1485 */
- { 0x0000, 0x0000 }, /* R1486 */
- { 0x0000, 0x0000 }, /* R1487 */
- { 0x0000, 0x0000 }, /* R1488 */
- { 0x0000, 0x0000 }, /* R1489 */
- { 0x0000, 0x0000 }, /* R1490 */
- { 0x0000, 0x0000 }, /* R1491 */
- { 0x0000, 0x0000 }, /* R1492 */
- { 0x0000, 0x0000 }, /* R1493 */
- { 0x0000, 0x0000 }, /* R1494 */
- { 0x0000, 0x0000 }, /* R1495 */
- { 0x0000, 0x0000 }, /* R1496 */
- { 0x0000, 0x0000 }, /* R1497 */
- { 0x0000, 0x0000 }, /* R1498 */
- { 0x0000, 0x0000 }, /* R1499 */
- { 0x0000, 0x0000 }, /* R1500 */
- { 0x0000, 0x0000 }, /* R1501 */
- { 0x0000, 0x0000 }, /* R1502 */
- { 0x0000, 0x0000 }, /* R1503 */
- { 0x0000, 0x0000 }, /* R1504 */
- { 0x0000, 0x0000 }, /* R1505 */
- { 0x0000, 0x0000 }, /* R1506 */
- { 0x0000, 0x0000 }, /* R1507 */
- { 0x0000, 0x0000 }, /* R1508 */
- { 0x0000, 0x0000 }, /* R1509 */
- { 0x0000, 0x0000 }, /* R1510 */
- { 0x0000, 0x0000 }, /* R1511 */
- { 0x0000, 0x0000 }, /* R1512 */
- { 0x0000, 0x0000 }, /* R1513 */
- { 0x0000, 0x0000 }, /* R1514 */
- { 0x0000, 0x0000 }, /* R1515 */
- { 0x0000, 0x0000 }, /* R1516 */
- { 0x0000, 0x0000 }, /* R1517 */
- { 0x0000, 0x0000 }, /* R1518 */
- { 0x0000, 0x0000 }, /* R1519 */
- { 0x0000, 0x0000 }, /* R1520 */
- { 0x0000, 0x0000 }, /* R1521 */
- { 0x0000, 0x0000 }, /* R1522 */
- { 0x0000, 0x0000 }, /* R1523 */
- { 0x0000, 0x0000 }, /* R1524 */
- { 0x0000, 0x0000 }, /* R1525 */
- { 0x0000, 0x0000 }, /* R1526 */
- { 0x0000, 0x0000 }, /* R1527 */
- { 0x0000, 0x0000 }, /* R1528 */
- { 0x0000, 0x0000 }, /* R1529 */
- { 0x0000, 0x0000 }, /* R1530 */
- { 0x0000, 0x0000 }, /* R1531 */
- { 0x0000, 0x0000 }, /* R1532 */
- { 0x0000, 0x0000 }, /* R1533 */
- { 0x0000, 0x0000 }, /* R1534 */
- { 0x0000, 0x0000 }, /* R1535 */
- { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
- { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
- { 0x0000, 0x0000 }, /* R1546 */
- { 0x0000, 0x0000 }, /* R1547 */
- { 0x0000, 0x0000 }, /* R1548 */
- { 0x0000, 0x0000 }, /* R1549 */
- { 0x0000, 0x0000 }, /* R1550 */
- { 0x0000, 0x0000 }, /* R1551 */
- { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
- { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
- { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
- { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
- { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
- { 0x0000, 0x0000 }, /* R1557 */
- { 0x0000, 0x0000 }, /* R1558 */
- { 0x0000, 0x0000 }, /* R1559 */
- { 0x0000, 0x0000 }, /* R1560 */
- { 0x0000, 0x0000 }, /* R1561 */
- { 0x0000, 0x0000 }, /* R1562 */
- { 0x0000, 0x0000 }, /* R1563 */
- { 0x0000, 0x0000 }, /* R1564 */
- { 0x0000, 0x0000 }, /* R1565 */
- { 0x0000, 0x0000 }, /* R1566 */
- { 0x0000, 0x0000 }, /* R1567 */
- { 0x0003, 0x0003 }, /* R1568 - Oversampling */
- { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
-};
-
static int wm8994_readable(unsigned int reg)
{
switch (reg) {
@@ -1696,14 +131,14 @@ static int wm8994_readable(unsigned int reg)
break;
}
- if (reg >= ARRAY_SIZE(access_masks))
+ if (reg >= WM8994_CACHE_SIZE)
return 0;
- return access_masks[reg].readable != 0;
+ return wm8994_access_masks[reg].readable != 0;
}
static int wm8994_volatile(unsigned int reg)
{
- if (reg >= WM8994_REG_CACHE_SIZE)
+ if (reg >= WM8994_CACHE_SIZE)
return 1;
switch (reg) {
@@ -1714,6 +149,8 @@ static int wm8994_volatile(unsigned int reg)
case WM8994_RATE_STATUS:
case WM8994_LDO_1:
case WM8994_LDO_2:
+ case WM8958_DSP2_EXECCONTROL:
+ case WM8958_MIC_DETECT_3:
return 1;
default:
return 0;
@@ -1723,14 +160,16 @@ static int wm8994_volatile(unsigned int reg)
static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int ret;
BUG_ON(reg > WM8994_MAX_REGISTER);
- if (!wm8994_volatile(reg))
- wm8994->reg_cache[reg] = value;
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
+ if (!wm8994_volatile(reg)) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret != 0)
+ dev_err(codec->dev, "Cache write to %x failed: %d\n",
+ reg, ret);
+ }
return wm8994_reg_write(codec->control_data, reg, value);
}
@@ -1738,14 +177,22 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int wm8994_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *reg_cache = codec->reg_cache;
+ unsigned int val;
+ int ret;
BUG_ON(reg > WM8994_MAX_REGISTER);
- if (wm8994_volatile(reg))
- return wm8994_reg_read(codec->control_data, reg);
- else
- return reg_cache[reg];
+ if (!wm8994_volatile(reg) && wm8994_readable(reg) &&
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret >= 0)
+ return val;
+ else
+ dev_err(codec->dev, "Cache read from %x failed: %d\n",
+ reg, ret);
+ }
+
+ return wm8994_reg_read(codec->control_data, reg);
}
static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -1837,7 +284,7 @@ static int configure_clock(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
return 0;
}
@@ -1864,6 +311,19 @@ static const char *sidetone_hpf_text[] = {
static const struct soc_enum sidetone_hpf =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
+static const char *adc_hpf_text[] = {
+ "HiFi", "Voice 1", "Voice 2", "Voice 3"
+};
+
+static const struct soc_enum aif1adc1_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
+
+static const struct soc_enum aif1adc2_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
+
+static const struct soc_enum aif2adc_hpf =
+ SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
+
static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
@@ -2071,21 +531,252 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
return 0;
}
-static const char *aifdac_src_text[] = {
+static const char *aif_chan_src_text[] = {
"Left", "Right"
};
+static const struct soc_enum aif1adcl_src =
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
+
+static const struct soc_enum aif1adcr_src =
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
+
+static const struct soc_enum aif2adcl_src =
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
+
+static const struct soc_enum aif2adcr_src =
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
+
static const struct soc_enum aif1dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
static const struct soc_enum aif1dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
static const struct soc_enum aif2dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
static const struct soc_enum aif2dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aifdac_src_text);
+ SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
+
+static const char *osr_text[] = {
+ "Low Power", "High Performance",
+};
+
+static const struct soc_enum dac_osr =
+ SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
+
+static const struct soc_enum adc_osr =
+ SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
+
+static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_pdata *pdata = wm8994->pdata;
+ int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
+ int ena, reg, aif, i;
+
+ switch (mbc) {
+ case 0:
+ pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
+ aif = 0;
+ break;
+ case 1:
+ pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
+ aif = 0;
+ break;
+ case 2:
+ pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
+ aif = 1;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ /* We can only enable the MBC if the AIF is enabled and we
+ * want it to be enabled. */
+ ena = pwr_reg && wm8994->mbc_ena[mbc];
+
+ reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
+
+ dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
+ mbc, start, pwr_reg, reg);
+
+ if (start && ena) {
+ /* If the DSP is already running then noop */
+ if (reg & WM8958_DSP2_ENA)
+ return;
+
+ /* Switch the clock over to the appropriate AIF */
+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+ WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
+ aif << WM8958_DSP2CLK_SRC_SHIFT |
+ WM8958_DSP2CLK_ENA);
+
+ snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+ WM8958_DSP2_ENA, WM8958_DSP2_ENA);
+
+ /* If we've got user supplied MBC settings use them */
+ if (pdata && pdata->num_mbc_cfgs) {
+ struct wm8958_mbc_cfg *cfg
+ = &pdata->mbc_cfgs[wm8994->mbc_cfg];
+
+ for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
+ snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
+ cfg->coeff_regs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
+ snd_soc_write(codec,
+ i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
+ cfg->cutoff_regs[i]);
+ }
+
+ /* Run the DSP */
+ snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+ WM8958_DSP2_RUNR);
+
+ /* And we're off! */
+ snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+ WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
+ mbc << WM8958_MBC_SEL_SHIFT |
+ WM8958_MBC_ENA);
+ } else {
+ /* If the DSP is already stopped then noop */
+ if (!(reg & WM8958_DSP2_ENA))
+ return;
+
+ snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+ WM8958_MBC_ENA, 0);
+ snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+ WM8958_DSP2_ENA, 0);
+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+ WM8958_DSP2CLK_ENA, 0);
+ }
+}
+
+static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ int mbc;
+
+ switch (w->shift) {
+ case 13:
+ case 12:
+ mbc = 2;
+ break;
+ case 11:
+ case 10:
+ mbc = 1;
+ break;
+ case 9:
+ case 8:
+ mbc = 0;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ wm8958_mbc_apply(codec, mbc, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ wm8958_mbc_apply(codec, mbc, 0);
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_pdata *pdata = wm8994->pdata;
+ int value = ucontrol->value.integer.value[0];
+ int reg;
+
+ /* Don't allow on the fly reconfiguration */
+ reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+ if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
+ return -EBUSY;
+
+ if (value >= pdata->num_mbc_cfgs)
+ return -EINVAL;
+
+ wm8994->mbc_cfg = value;
+
+ return 0;
+}
+
+static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
+
+ return 0;
+}
+
+static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mbc = kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
+
+ return 0;
+}
+
+static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int mbc = kcontrol->private_value;
+ int i;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (ucontrol->value.integer.value[0] > 1)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
+ if (mbc != i && wm8994->mbc_ena[i]) {
+ dev_dbg(codec->dev, "MBC %d active already\n", mbc);
+ return -EBUSY;
+ }
+ }
+
+ wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
+
+ wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
+
+ return 0;
+}
+
+#define WM8958_MBC_SWITCH(xname, xval) {\
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+ .info = wm8958_mbc_info, \
+ .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
+ .private_value = xval }
static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
@@ -2098,10 +789,15 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
WM8994_AIF2_ADC_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
+SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
+SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
+SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
+SOC_ENUM("AIF2ADCR Source", aif2adcr_src),
+
SOC_ENUM("AIF1DACL Source", aif1dacl_src),
SOC_ENUM("AIF1DACR Source", aif1dacr_src),
-SOC_ENUM("AIF2DACL Source", aif1dacl_src),
-SOC_ENUM("AIF2DACR Source", aif1dacr_src),
+SOC_ENUM("AIF2DACL Source", aif2dacl_src),
+SOC_ENUM("AIF2DACR Source", aif2dacr_src),
SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
@@ -2140,6 +836,18 @@ SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
+SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
+SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
+SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
+SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
+
+SOC_ENUM("ADC OSR", adc_osr),
+SOC_ENUM("DAC OSR", dac_osr),
+
SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
@@ -2162,15 +870,15 @@ SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
-SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
+SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC1_FILTERS_2,
8, 1, 0),
SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
8, 1, 0),
-SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
+SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF2_DAC_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
-SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
+SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
8, 1, 0),
};
@@ -2209,6 +917,13 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
};
+static const struct snd_kcontrol_new wm8958_snd_controls[] = {
+SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
+WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
+WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
+WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
+};
+
static int clk_sys_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -2228,6 +943,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
static void wm8994_update_class_w(struct snd_soc_codec *codec)
{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int enable = 1;
int source = 0; /* GCC flow analysis can't track enable */
int reg, reg_r;
@@ -2278,11 +994,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
WM8994_CP_DYN_PWR |
WM8994_CP_DYN_SRC_SEL_MASK,
source | WM8994_CP_DYN_PWR);
+ wm8994->hubs.class_w = true;
} else {
dev_dbg(codec->dev, "Class W disabled\n");
snd_soc_update_bits(codec, WM8994_CLASS_W_1,
WM8994_CP_DYN_PWR, 0);
+ wm8994->hubs.class_w = false;
}
}
@@ -2512,14 +1230,47 @@ static const struct snd_kcontrol_new aif2adc_mux =
SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
static const char *aif3adc_text[] = {
- "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
+ "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
};
-static const struct soc_enum aif3adc_enum =
+static const struct soc_enum wm8994_aif3adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
-static const struct snd_kcontrol_new aif3adc_mux =
- SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
+static const struct snd_kcontrol_new wm8994_aif3adc_mux =
+ SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
+
+static const struct soc_enum wm8958_aif3adc_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
+
+static const struct snd_kcontrol_new wm8958_aif3adc_mux =
+ SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
+
+static const char *mono_pcm_out_text[] = {
+ "None", "AIF2ADCL", "AIF2ADCR",
+};
+
+static const struct soc_enum mono_pcm_out_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
+
+static const struct snd_kcontrol_new mono_pcm_out_mux =
+ SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
+
+static const char *aif2dac_src_text[] = {
+ "AIF2", "AIF3",
+};
+
+/* Note that these two control shouldn't be simultaneously switched to AIF3 */
+static const struct soc_enum aif2dacl_src_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
+
+static const struct snd_kcontrol_new aif2dacl_src_mux =
+ SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
+
+static const struct soc_enum aif2dacr_src_enum =
+ SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
+
+static const struct snd_kcontrol_new aif2dacr_src_mux =
+ SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("DMIC1DAT"),
@@ -2540,19 +1291,23 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 9, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 8, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 9, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 8, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 11, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 10, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 11, 0),
-SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 10, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
@@ -2581,10 +1336,12 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 13, 0),
SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 12, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 13, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
- WM8994_POWER_MANAGEMENT_5, 12, 0),
+SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
+ WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
@@ -2593,7 +1350,6 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
-SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -2631,8 +1387,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
SND_SOC_DAPM_POST("Debug log", post_ev),
};
-static const struct snd_soc_dapm_route intercon[] = {
+static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
+};
+
+static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
+SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
+SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
+SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
+};
+static const struct snd_soc_dapm_route intercon[] = {
{ "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
{ "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
@@ -2740,9 +1506,6 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "AIF1DAC2L", NULL, "AIF1DAC Mux" },
{ "AIF1DAC2R", NULL, "AIF1DAC Mux" },
- { "AIF2DACL", NULL, "AIF2DAC Mux" },
- { "AIF2DACR", NULL, "AIF2DAC Mux" },
-
{ "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
{ "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
{ "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
@@ -2815,6 +1578,26 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "Right Headphone Mux", "DAC", "DAC1R" },
};
+static const struct snd_soc_dapm_route wm8994_intercon[] = {
+ { "AIF2DACL", NULL, "AIF2DAC Mux" },
+ { "AIF2DACR", NULL, "AIF2DAC Mux" },
+};
+
+static const struct snd_soc_dapm_route wm8958_intercon[] = {
+ { "AIF2DACL", NULL, "AIF2DACL Mux" },
+ { "AIF2DACR", NULL, "AIF2DACR Mux" },
+
+ { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
+ { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
+ { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
+ { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
+
+ { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
+ { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
+
+ { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
+};
+
/* The size in bits of the FLL divide multiplied by 10
* to allow rounding later */
#define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2930,6 +1713,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
/* Allow no source specification when stopping */
if (freq_out)
return -EINVAL;
+ src = wm8994->fll[id].src;
break;
case WM8994_FLL_SRC_MCLK1:
case WM8994_FLL_SRC_MCLK2:
@@ -3094,6 +1878,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
switch (level) {
@@ -3107,16 +1892,36 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
- /* Tweak DC servo and DSP configuration for
- * improved performance. */
- if (wm8994->revision < 4) {
- /* Tweak DC servo and DSP configuration for
- * improved performance. */
- snd_soc_write(codec, 0x102, 0x3);
- snd_soc_write(codec, 0x56, 0x3);
- snd_soc_write(codec, 0x817, 0);
- snd_soc_write(codec, 0x102, 0);
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ pm_runtime_get_sync(codec->dev);
+
+ switch (control->type) {
+ case WM8994:
+ if (wm8994->revision < 4) {
+ /* Tweak DC servo and DSP
+ * configuration for improved
+ * performance. */
+ snd_soc_write(codec, 0x102, 0x3);
+ snd_soc_write(codec, 0x56, 0x3);
+ snd_soc_write(codec, 0x817, 0);
+ snd_soc_write(codec, 0x102, 0);
+ }
+ break;
+
+ case WM8958:
+ if (wm8994->revision == 0) {
+ /* Optimise performance for rev A */
+ snd_soc_write(codec, 0x102, 0x3);
+ snd_soc_write(codec, 0xcb, 0x81);
+ snd_soc_write(codec, 0x817, 0);
+ snd_soc_write(codec, 0x102, 0);
+
+ snd_soc_update_bits(codec,
+ WM8958_CHARGE_PUMP_2,
+ WM8958_CP_DISCH,
+ WM8958_CP_DISCH);
+ }
+ break;
}
/* Discharge LINEOUT1 & 2 */
@@ -3151,7 +1956,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
- if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
/* Switch over to startup biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC |
@@ -3183,16 +1988,19 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0);
+
+ pm_runtime_put(codec->dev);
}
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
int ms_reg;
int aif1_reg;
int ms = 0;
@@ -3277,6 +2085,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
+ /* The AIF2 format configuration needs to be mirrored to AIF3
+ * on WM8958 if it's in use so just do it all the time. */
+ if (control->type == WM8958 && dai->id == 2)
+ snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
+ WM8994_AIF1_LRCLK_INV |
+ WM8958_AIF3_FMT_MASK, aif1);
+
snd_soc_update_bits(codec, aif1_reg,
WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
WM8994_AIF1_FMT_MASK,
@@ -3317,12 +2132,15 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int aif1_reg;
+ int aif2_reg;
int bclk_reg;
int lrclk_reg;
int rate_reg;
int aif1 = 0;
+ int aif2 = 0;
int bclk = 0;
int lrclk = 0;
int rate_val = 0;
@@ -3333,6 +2151,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
switch (dai->id) {
case 1:
aif1_reg = WM8994_AIF1_CONTROL_1;
+ aif2_reg = WM8994_AIF1_CONTROL_2;
bclk_reg = WM8994_AIF1_BCLK;
rate_reg = WM8994_AIF1_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3345,6 +2164,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
break;
case 2:
aif1_reg = WM8994_AIF2_CONTROL_1;
+ aif2_reg = WM8994_AIF2_CONTROL_2;
bclk_reg = WM8994_AIF2_BCLK;
rate_reg = WM8994_AIF2_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3355,6 +2175,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
}
break;
+ case 3:
+ switch (control->type) {
+ case WM8958:
+ aif1_reg = WM8958_AIF3_CONTROL_1;
+ break;
+ default:
+ return 0;
+ }
default:
return -EINVAL;
}
@@ -3392,6 +2220,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
dai->id, wm8994->aifclk[id], bclk_rate);
+ if (params_channels(params) == 1 &&
+ (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
+ aif2 |= WM8994_AIF1_MONO;
+
if (wm8994->aifclk[id] == 0) {
dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
return -EINVAL;
@@ -3435,6 +2267,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
lrclk, bclk_rate / lrclk);
snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+ snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
lrclk);
@@ -3458,6 +2291,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
return 0;
}
+static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8994 *control = codec->control_data;
+ int aif1_reg;
+ int aif1 = 0;
+
+ switch (dai->id) {
+ case 3:
+ switch (control->type) {
+ case WM8958:
+ aif1_reg = WM8958_AIF3_CONTROL_1;
+ break;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ aif1 |= 0x20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ aif1 |= 0x40;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ aif1 |= 0x60;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+}
+
static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
{
struct snd_soc_codec *codec = codec_dai->codec;
@@ -3539,6 +2413,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
};
static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
+ .hw_params = wm8994_aif3_hw_params,
.set_tristate = wm8994_set_tristate,
};
@@ -3548,14 +2423,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 1,
.playback = {
.stream_name = "AIF1 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF1 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3567,14 +2442,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 2,
.playback = {
.stream_name = "AIF2 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF2 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3586,14 +2461,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
.id = 3,
.playback = {
.stream_name = "AIF3 Playback",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF3 Capture",
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
@@ -3625,26 +2500,12 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int wm8994_resume(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = codec->reg_cache;
int i, ret;
/* Restore the registers */
- for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
- switch (i) {
- case WM8994_LDO_1:
- case WM8994_LDO_2:
- case WM8994_SOFTWARE_RESET:
- /* Handled by other MFD drivers */
- continue;
- default:
- break;
- }
-
- if (!access_masks[i].writable)
- continue;
-
- wm8994_reg_write(codec->control_data, i, reg_cache[i]);
- }
+ ret = snd_soc_cache_sync(codec);
+ if (ret != 0)
+ dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -3794,6 +2655,34 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
pdata->num_retune_mobile_cfgs);
+ if (pdata->num_mbc_cfgs) {
+ struct snd_kcontrol_new control[] = {
+ SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
+ wm8958_get_mbc_enum, wm8958_put_mbc_enum),
+ };
+
+ /* We need an array of texts for the enum API */
+ wm8994->mbc_texts = kmalloc(sizeof(char *)
+ * pdata->num_mbc_cfgs, GFP_KERNEL);
+ if (!wm8994->mbc_texts) {
+ dev_err(wm8994->codec->dev,
+ "Failed to allocate %d MBC config texts\n",
+ pdata->num_mbc_cfgs);
+ return;
+ }
+
+ for (i = 0; i < pdata->num_mbc_cfgs; i++)
+ wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
+
+ wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
+ wm8994->mbc_enum.texts = wm8994->mbc_texts;
+
+ ret = snd_soc_add_controls(wm8994->codec, control, 1);
+ if (ret != 0)
+ dev_err(wm8994->codec->dev,
+ "Failed to add MBC mode controls: %d\n", ret);
+ }
+
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994);
else
@@ -3823,8 +2712,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
+ struct wm8994 *control = codec->control_data;
int reg;
+ if (control->type != WM8994)
+ return -EINVAL;
+
switch (micbias) {
case 1:
micdet = &wm8994->micdet[0];
@@ -3863,6 +2756,10 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
int reg;
int report;
+#ifndef CONFIG_SND_SOC_WM8994_MODULE
+ trace_snd_soc_jack_irq(dev_name(codec->dev));
+#endif
+
reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
if (reg < 0) {
dev_err(codec->dev, "Failed to read microphone status: %d\n",
@@ -3891,77 +2788,251 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
return IRQ_HANDLED;
}
+/* Default microphone detection handler for WM8958 - the user can
+ * override this if they wish.
+ */
+static void wm8958_default_micdet(u16 status, void *data)
+{
+ struct snd_soc_codec *codec = data;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int report = 0;
+
+ /* If nothing present then clear our statuses */
+ if (!(status & WM8958_MICD_STS)) {
+ wm8994->jack_is_video = false;
+ wm8994->jack_is_mic = false;
+ goto done;
+ }
+
+ /* Assume anything over 475 ohms is a microphone and remember
+ * that we've seen one (since buttons override it) */
+ if (status & 0x600)
+ wm8994->jack_is_mic = true;
+ if (wm8994->jack_is_mic)
+ report |= SND_JACK_MICROPHONE;
+
+ /* Video has an impedence of approximately 75 ohms; assume
+ * this isn't used as a button and remember it since buttons
+ * override it. */
+ if (status & 0x40)
+ wm8994->jack_is_video = true;
+ if (wm8994->jack_is_video)
+ report |= SND_JACK_VIDEOOUT;
+
+ /* Everything else is buttons; just assign slots */
+ if (status & 0x4)
+ report |= SND_JACK_BTN_0;
+ if (status & 0x8)
+ report |= SND_JACK_BTN_1;
+ if (status & 0x10)
+ report |= SND_JACK_BTN_2;
+ if (status & 0x20)
+ report |= SND_JACK_BTN_3;
+ if (status & 0x80)
+ report |= SND_JACK_BTN_4;
+ if (status & 0x100)
+ report |= SND_JACK_BTN_5;
+
+done:
+ snd_soc_jack_report(wm8994->micdet[0].jack,
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+ SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
+ SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT,
+ report);
+}
+
+/**
+ * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
+ *
+ * @codec: WM8958 codec
+ * @jack: jack to report detection events on
+ *
+ * Enable microphone detection functionality for the WM8958. By
+ * default simple detection which supports the detection of up to 6
+ * buttons plus video and microphone functionality is supported.
+ *
+ * The WM8958 has an advanced jack detection facility which is able to
+ * support complex accessory detection, especially when used in
+ * conjunction with external circuitry. In order to provide maximum
+ * flexiblity a callback is provided which allows a completely custom
+ * detection algorithm.
+ */
+int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8958_micdet_cb cb, void *cb_data)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = codec->control_data;
+
+ if (control->type != WM8958)
+ return -EINVAL;
+
+ if (jack) {
+ if (!cb) {
+ dev_dbg(codec->dev, "Using default micdet callback\n");
+ cb = wm8958_default_micdet;
+ cb_data = codec;
+ }
+
+ wm8994->micdet[0].jack = jack;
+ wm8994->jack_cb = cb;
+ wm8994->jack_cb_data = cb_data;
+
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, WM8958_MICD_ENA);
+ } else {
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, 0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wm8958_mic_detect);
+
+static irqreturn_t wm8958_mic_irq(int irq, void *data)
+{
+ struct wm8994_priv *wm8994 = data;
+ struct snd_soc_codec *codec = wm8994->codec;
+ int reg;
+
+ reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
+ if (reg < 0) {
+ dev_err(codec->dev, "Failed to read mic detect status: %d\n",
+ reg);
+ return IRQ_NONE;
+ }
+
+ if (!(reg & WM8958_MICD_VALID)) {
+ dev_dbg(codec->dev, "Mic detect data not valid\n");
+ goto out;
+ }
+
+#ifndef CONFIG_SND_SOC_WM8994_MODULE
+ trace_snd_soc_jack_irq(dev_name(codec->dev));
+#endif
+
+ if (wm8994->jack_cb)
+ wm8994->jack_cb(reg, wm8994->jack_cb_data);
+ else
+ dev_warn(codec->dev, "Accessory detection with no callback\n");
+
+out:
+ return IRQ_HANDLED;
+}
+
static int wm8994_codec_probe(struct snd_soc_codec *codec)
{
+ struct wm8994 *control;
struct wm8994_priv *wm8994;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i;
codec->control_data = dev_get_drvdata(codec->dev->parent);
+ control = codec->control_data;
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
if (wm8994 == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm8994);
- codec->reg_cache = &wm8994->reg_cache;
-
wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec;
- /* Fill the cache with physical values we inherited; don't reset */
- ret = wm8994_bulk_read(codec->control_data, 0,
- ARRAY_SIZE(wm8994->reg_cache) - 1,
- codec->reg_cache);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to fill register cache: %d\n",
- ret);
- goto err;
- }
+ pm_runtime_enable(codec->dev);
+ pm_runtime_resume(codec->dev);
- /* Clear the cached values for unreadable/volatile registers to
- * avoid potential confusion.
- */
- for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
- if (wm8994_volatile(i) || !wm8994_readable(i))
- wm8994->reg_cache[i] = 0;
+ /* Read our current status back from the chip - we don't want to
+ * reset as this may interfere with the GPIO or LDO operation. */
+ for (i = 0; i < WM8994_CACHE_SIZE; i++) {
+ if (!wm8994_readable(i) || wm8994_volatile(i))
+ continue;
+
+ ret = wm8994_reg_read(codec->control_data, i);
+ if (ret <= 0)
+ continue;
+
+ ret = snd_soc_cache_write(codec, i, ret);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to initialise cache for 0x%x: %d\n",
+ i, ret);
+ goto err;
+ }
+ }
/* Set revision-specific configuration */
wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
- switch (wm8994->revision) {
- case 2:
- case 3:
- wm8994->hubs.dcs_codes = -5;
- wm8994->hubs.hp_startup_mode = 1;
+ switch (control->type) {
+ case WM8994:
+ switch (wm8994->revision) {
+ case 2:
+ 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;
+ }
+
+ case WM8958:
wm8994->hubs.dcs_readback_mode = 1;
break;
+
default:
- wm8994->hubs.dcs_readback_mode = 1;
break;
}
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
- wm8994_mic_irq, "Mic 1 detect", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 detect IRQ: %d\n", ret);
-
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
- wm8994_mic_irq, "Mic 1 short", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 short IRQ: %d\n", ret);
-
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
- wm8994_mic_irq, "Mic 2 detect", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 detect IRQ: %d\n", ret);
+ switch (control->type) {
+ case WM8994:
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_DET,
+ wm8994_mic_irq, "Mic 1 detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic1 detect IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_SHRT,
+ wm8994_mic_irq, "Mic 1 short",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic1 short IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC2_DET,
+ wm8994_mic_irq, "Mic 2 detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic2 detect IRQ: %d\n",
+ ret);
+
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC2_SHRT,
+ wm8994_mic_irq, "Mic 2 short",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic2 short IRQ: %d\n",
+ ret);
+ break;
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
- wm8994_mic_irq, "Mic 2 short", wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 short IRQ: %d\n", ret);
+ case WM8958:
+ ret = wm8994_request_irq(codec->control_data,
+ WM8994_IRQ_MIC1_DET,
+ wm8958_mic_irq, "Mic detect",
+ wm8994);
+ if (ret != 0)
+ dev_warn(codec->dev,
+ "Failed to request Mic detect IRQ: %d\n",
+ ret);
+ break;
+ }
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
@@ -4034,10 +3105,36 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
wm_hubs_add_analogue_controls(codec);
snd_soc_add_controls(codec, wm8994_snd_controls,
ARRAY_SIZE(wm8994_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
ARRAY_SIZE(wm8994_dapm_widgets));
+
+ switch (control->type) {
+ case WM8994:
+ snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
+ ARRAY_SIZE(wm8994_specific_dapm_widgets));
+ break;
+ case WM8958:
+ snd_soc_add_controls(codec, wm8958_snd_controls,
+ ARRAY_SIZE(wm8958_snd_controls));
+ snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
+ ARRAY_SIZE(wm8958_dapm_widgets));
+ break;
+ }
+
+
wm_hubs_add_analogue_routes(codec, 0, 0);
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+ snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
+
+ switch (control->type) {
+ case WM8994:
+ snd_soc_dapm_add_routes(dapm, wm8994_intercon,
+ ARRAY_SIZE(wm8994_intercon));
+ break;
+ case WM8958:
+ snd_soc_dapm_add_routes(dapm, wm8958_intercon,
+ ARRAY_SIZE(wm8958_intercon));
+ break;
+ }
return 0;
@@ -4054,13 +3151,29 @@ err:
static int wm8994_codec_remove(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = codec->control_data;
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
+ pm_runtime_disable(codec->dev);
+
+ switch (control->type) {
+ case WM8994:
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
+ wm8994);
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
+ wm8994);
+ break;
+
+ case WM8958:
+ wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
+ wm8994);
+ break;
+ }
kfree(wm8994->retune_mobile_texts);
kfree(wm8994->drc_texts);
kfree(wm8994);
@@ -4073,11 +3186,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.remove = wm8994_codec_remove,
.suspend = wm8994_suspend,
.resume = wm8994_resume,
- .read = wm8994_read,
- .write = wm8994_write,
+ .read = wm8994_read,
+ .write = wm8994_write,
.readable_register = wm8994_readable,
.volatile_register = wm8994_volatile,
.set_bias_level = wm8994_set_bias_level,
+
+ .reg_cache_size = WM8994_CACHE_SIZE,
+ .reg_cache_default = wm8994_reg_defaults,
+ .reg_word_size = 2,
+ .compress_type = SND_SOC_RBTREE_COMPRESSION,
};
static int __devinit wm8994_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d8dce260c430..0c355bfc88f1 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,7 +28,21 @@
#define WM8994_FLL_SRC_LRCLK 3
#define WM8994_FLL_SRC_BCLK 4
+typedef void (*wm8958_micdet_cb)(u16 status, void *data);
+
int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
int micbias, int det, int shrt);
+int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8958_micdet_cb cb, void *cb_data);
+
+#define WM8994_CACHE_SIZE 1570
+
+struct wm8994_access_mask {
+ unsigned short readable; /* Mask of readable bits */
+ unsigned short writable; /* Mask of writable bits */
+};
+
+extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
+extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
new file mode 100644
index 000000000000..3d2110c1d81f
--- /dev/null
+++ b/sound/soc/codecs/wm8995.c
@@ -0,0 +1,1818 @@
+/*
+ * wm8995.c -- WM8995 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *
+ * Based on wm8994.c and wm_hubs.c by Mark Brown
+ *
+ * This program is free software; you can 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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8995.h"
+
+static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] __devinitconst = {
+ [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
+ [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
+ [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003,
+ [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25,
+ [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060,
+ [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083,
+ [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050,
+ [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040,
+ [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000,
+ [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0,
+ [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0,
+ [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200,
+ [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098,
+ [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318,
+ [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8,
+ [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5,
+ [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558,
+ [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103,
+ [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318,
+ [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8,
+ [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5,
+ [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558,
+ [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103,
+ [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0,
+ [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200,
+ [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318,
+ [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8,
+ [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5,
+ [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558,
+ [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103,
+ [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002,
+ [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101,
+ [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101,
+ [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101,
+ [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff,
+ [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002,
+ [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001,
+ [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f,
+ [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104,
+ [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050,
+ [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003,
+ [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b,
+ [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff,
+ [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff,
+ [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001,
+ [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001,
+ [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003,
+ [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401,
+ [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060,
+ [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff,
+ [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff,
+ [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff,
+ [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006,
+ [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006,
+ [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061,
+ [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003,
+ [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106,
+ [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502,
+ [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff,
+ [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff,
+ [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001,
+ [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f,
+ [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106,
+ [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050,
+ [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b,
+ [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff,
+ [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff,
+ [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff,
+ [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100,
+ [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff,
+ [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff,
+ [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff,
+ [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff,
+ [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102,
+ [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff,
+ [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff,
+ [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff,
+ [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff,
+ [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601,
+ [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304,
+ [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100
+};
+
+struct fll_config {
+ int src;
+ int in;
+ int out;
+};
+
+struct wm8995_priv {
+ enum snd_soc_control_type control_type;
+ int sysclk[2];
+ int mclk[2];
+ int aifclk[2];
+ struct fll_config fll[2], fll_suspend[2];
+};
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
+static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
+static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
+
+static const char *in1l_text[] = {
+ "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
+};
+
+static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
+ 2, in1l_text);
+
+static const char *in1r_text[] = {
+ "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
+};
+
+static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
+ 0, in1r_text);
+
+static const char *dmic_src_text[] = {
+ "DMICDAT1", "DMICDAT2", "DMICDAT3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5,
+ 8, dmic_src_text);
+static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5,
+ 6, dmic_src_text);
+
+static const struct snd_kcontrol_new wm8995_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME,
+ WM8995_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R("DAC1 Switch", WM8995_DAC1_LEFT_VOLUME,
+ WM8995_DAC1_RIGHT_VOLUME, 9, 1, 1),
+
+ SOC_DOUBLE_R_TLV("DAC2 Volume", WM8995_DAC2_LEFT_VOLUME,
+ WM8995_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R("DAC2 Switch", WM8995_DAC2_LEFT_VOLUME,
+ WM8995_DAC2_RIGHT_VOLUME, 9, 1, 1),
+
+ SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8995_AIF1_DAC1_LEFT_VOLUME,
+ WM8995_AIF1_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8995_AIF1_DAC2_LEFT_VOLUME,
+ WM8995_AIF1_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8995_AIF2_DAC_LEFT_VOLUME,
+ WM8995_AIF2_DAC_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+
+ SOC_DOUBLE_R_TLV("IN1LR Volume", WM8995_LEFT_LINE_INPUT_1_VOLUME,
+ WM8995_RIGHT_LINE_INPUT_1_VOLUME, 0, 31, 0, in1lr_pga_tlv),
+
+ SOC_SINGLE_TLV("IN1L Boost", WM8995_LEFT_LINE_INPUT_CONTROL,
+ 4, 3, 0, in1l_boost_tlv),
+
+ SOC_ENUM("IN1L Mode", in1l_enum),
+ SOC_ENUM("IN1R Mode", in1r_enum),
+
+ SOC_ENUM("DMIC1 SRC", dmic_src1_enum),
+ SOC_ENUM("DMIC2 SRC", dmic_src2_enum),
+
+ SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8995_DAC1_MIXER_VOLUMES, 0, 5,
+ 24, 0, sidetone_tlv),
+ SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8995_DAC2_MIXER_VOLUMES, 0, 5,
+ 24, 0, sidetone_tlv),
+
+ SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8995_AIF1_ADC1_LEFT_VOLUME,
+ WM8995_AIF1_ADC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8995_AIF1_ADC2_LEFT_VOLUME,
+ WM8995_AIF1_ADC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8995_AIF2_ADC_LEFT_VOLUME,
+ WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv)
+};
+
+static void wm8995_update_class_w(struct snd_soc_codec *codec)
+{
+ int enable = 1;
+ int source = 0; /* GCC flow analysis can't track enable */
+ int reg, reg_r;
+
+ /* We also need the same setting for L/R and only one path */
+ reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING);
+ switch (reg) {
+ case WM8995_AIF2DACL_TO_DAC1L:
+ dev_dbg(codec->dev, "Class W source AIF2DAC\n");
+ source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT;
+ break;
+ case WM8995_AIF1DAC2L_TO_DAC1L:
+ dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
+ source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT;
+ break;
+ case WM8995_AIF1DAC1L_TO_DAC1L:
+ dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
+ source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT;
+ break;
+ default:
+ dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
+ enable = 0;
+ break;
+ }
+
+ reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING);
+ if (reg_r != reg) {
+ dev_dbg(codec->dev, "Left and right DAC mixers different\n");
+ enable = 0;
+ }
+
+ if (enable) {
+ dev_dbg(codec->dev, "Class W enabled\n");
+ snd_soc_update_bits(codec, WM8995_CLASS_W_1,
+ WM8995_CP_DYN_PWR_MASK |
+ WM8995_CP_DYN_SRC_SEL_MASK,
+ source | WM8995_CP_DYN_PWR);
+ } else {
+ dev_dbg(codec->dev, "Class W disabled\n");
+ snd_soc_update_bits(codec, WM8995_CLASS_W_1,
+ WM8995_CP_DYN_PWR_MASK, 0);
+ }
+}
+
+static int check_clk_sys(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
+ const char *clk;
+
+ reg = snd_soc_read(source->codec, WM8995_CLOCKING_1);
+ /* Check what we're currently using for CLK_SYS */
+ if (reg & WM8995_SYSCLK_SRC)
+ clk = "AIF2CLK";
+ else
+ clk = "AIF1CLK";
+ return !strcmp(source->name, clk);
+}
+
+static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *w;
+ struct snd_soc_codec *codec;
+ int ret;
+
+ w = snd_kcontrol_chip(kcontrol);
+ codec = w->codec;
+ ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
+ wm8995_update_class_w(codec);
+ return ret;
+}
+
+static int hp_supply_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+ struct wm8995_priv *wm8995;
+
+ codec = w->codec;
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable the headphone amp */
+ snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+ WM8995_HPOUT1L_ENA_MASK |
+ WM8995_HPOUT1R_ENA_MASK,
+ WM8995_HPOUT1L_ENA |
+ WM8995_HPOUT1R_ENA);
+
+ /* Enable the second stage */
+ snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+ WM8995_HPOUT1L_DLY_MASK |
+ WM8995_HPOUT1R_DLY_MASK,
+ WM8995_HPOUT1L_DLY |
+ WM8995_HPOUT1R_DLY);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
+ WM8995_CP_ENA_MASK, 0);
+ break;
+ }
+
+ return 0;
+}
+
+static void dc_servo_cmd(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int val, unsigned int mask)
+{
+ int timeout = 10;
+
+ dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
+ __func__, reg, val, mask);
+
+ snd_soc_write(codec, reg, val);
+ while (timeout--) {
+ msleep(10);
+ val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0);
+ if ((val & mask) == mask)
+ return;
+ }
+
+ dev_err(codec->dev, "Timed out waiting for DC Servo\n");
+}
+
+static int hp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+ unsigned int reg;
+
+ codec = w->codec;
+ reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
+ WM8995_CP_ENA_MASK, WM8995_CP_ENA);
+
+ msleep(5);
+
+ snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+ WM8995_HPOUT1L_ENA_MASK |
+ WM8995_HPOUT1R_ENA_MASK,
+ WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA);
+
+ udelay(20);
+
+ reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY;
+ snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
+
+ snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
+ WM8995_DCS_ENA_CHAN_1);
+
+ dc_servo_cmd(codec, WM8995_DC_SERVO_2,
+ WM8995_DCS_TRIG_STARTUP_0 |
+ WM8995_DCS_TRIG_STARTUP_1,
+ WM8995_DCS_TRIG_DAC_WR_0 |
+ WM8995_DCS_TRIG_DAC_WR_1);
+
+ reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT |
+ WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT;
+ snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
+
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+ WM8995_HPOUT1L_OUTP_MASK |
+ WM8995_HPOUT1R_OUTP_MASK |
+ WM8995_HPOUT1L_RMV_SHORT_MASK |
+ WM8995_HPOUT1R_RMV_SHORT_MASK, 0);
+
+ snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+ WM8995_HPOUT1L_DLY_MASK |
+ WM8995_HPOUT1R_DLY_MASK, 0);
+
+ snd_soc_write(codec, WM8995_DC_SERVO_1, 0);
+
+ snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+ WM8995_HPOUT1L_ENA_MASK |
+ WM8995_HPOUT1R_ENA_MASK,
+ 0);
+ break;
+ }
+
+ return 0;
+}
+
+static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
+{
+ struct wm8995_priv *wm8995;
+ int rate;
+ int reg1 = 0;
+ int offset;
+
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ if (aif)
+ offset = 4;
+ else
+ offset = 0;
+
+ switch (wm8995->sysclk[aif]) {
+ case WM8995_SYSCLK_MCLK1:
+ rate = wm8995->mclk[0];
+ break;
+ case WM8995_SYSCLK_MCLK2:
+ reg1 |= 0x8;
+ rate = wm8995->mclk[1];
+ break;
+ case WM8995_SYSCLK_FLL1:
+ reg1 |= 0x10;
+ rate = wm8995->fll[0].out;
+ break;
+ case WM8995_SYSCLK_FLL2:
+ reg1 |= 0x18;
+ rate = wm8995->fll[1].out;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (rate >= 13500000) {
+ rate /= 2;
+ reg1 |= WM8995_AIF1CLK_DIV;
+
+ dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
+ aif + 1, rate);
+ }
+
+ wm8995->aifclk[aif] = rate;
+
+ snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset,
+ WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK,
+ reg1);
+ return 0;
+}
+
+static int configure_clock(struct snd_soc_codec *codec)
+{
+ struct wm8995_priv *wm8995;
+ int old, new;
+
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ /* Bring up the AIF clocks first */
+ configure_aif_clock(codec, 0);
+ configure_aif_clock(codec, 1);
+
+ /*
+ * Then switch CLK_SYS over to the higher of them; a change
+ * can only happen as a result of a clocking change which can
+ * only be made outside of DAPM so we can safely redo the
+ * clocking.
+ */
+
+ /* If they're equal it doesn't matter which is used */
+ if (wm8995->aifclk[0] == wm8995->aifclk[1])
+ return 0;
+
+ if (wm8995->aifclk[0] < wm8995->aifclk[1])
+ new = WM8995_SYSCLK_SRC;
+ else
+ new = 0;
+
+ old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC;
+
+ /* If there's no change then we're done. */
+ if (old == new)
+ return 0;
+
+ snd_soc_update_bits(codec, WM8995_CLOCKING_1,
+ WM8995_SYSCLK_SRC_MASK, new);
+
+ snd_soc_dapm_sync(&codec->dapm);
+
+ return 0;
+}
+
+static int clk_sys_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec;
+
+ codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return configure_clock(codec);
+
+ case SND_SOC_DAPM_POST_PMD:
+ configure_clock(codec);
+ break;
+ }
+
+ return 0;
+}
+
+static const char *sidetone_text[] = {
+ "ADC/DMIC1", "DMIC2",
+};
+
+static const struct soc_enum sidetone1_enum =
+ SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text);
+
+static const struct snd_kcontrol_new sidetone1_mux =
+ SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
+
+static const struct soc_enum sidetone2_enum =
+ SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text);
+
+static const struct snd_kcontrol_new sidetone2_mux =
+ SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
+
+static const struct snd_kcontrol_new aif1adc1l_mix[] = {
+ SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new aif1adc1r_mix[] = {
+ SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new aif1adc2l_mix[] = {
+ SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new aif1adc2r_mix[] = {
+ SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dac1l_mix[] = {
+ WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
+ 5, 1, 0),
+ WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
+ 4, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
+ 2, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dac1r_mix[] = {
+ WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
+ 5, 1, 0),
+ WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
+ 4, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
+ 2, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+ WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new aif2dac2l_mix[] = {
+ SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
+ 5, 1, 0),
+ SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
+ 4, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
+ 2, 1, 0),
+ SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new aif2dac2r_mix[] = {
+ SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
+ 5, 1, 0),
+ SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
+ 4, 1, 0),
+ SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
+ 2, 1, 0),
+ SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new in1l_pga =
+ SOC_DAPM_SINGLE("IN1L Switch", WM8995_POWER_MANAGEMENT_2, 5, 1, 0);
+
+static const struct snd_kcontrol_new in1r_pga =
+ SOC_DAPM_SINGLE("IN1R Switch", WM8995_POWER_MANAGEMENT_2, 4, 1, 0);
+
+static const char *adc_mux_text[] = {
+ "ADC",
+ "DMIC",
+};
+
+static const struct soc_enum adc_enum =
+ SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
+
+static const struct snd_kcontrol_new adcl_mux =
+ SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
+
+static const struct snd_kcontrol_new adcr_mux =
+ SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
+
+static const char *spk_src_text[] = {
+ "DAC1L", "DAC1R", "DAC2L", "DAC2R"
+};
+
+static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1,
+ 0, spk_src_text);
+static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1,
+ 0, spk_src_text);
+static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2,
+ 0, spk_src_text);
+static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2,
+ 0, spk_src_text);
+
+static const struct snd_kcontrol_new spk1l_mux =
+ SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum);
+static const struct snd_kcontrol_new spk1r_mux =
+ SOC_DAPM_ENUM("SPK1R SRC", spk1r_src_enum);
+static const struct snd_kcontrol_new spk2l_mux =
+ SOC_DAPM_ENUM("SPK2L SRC", spk2l_src_enum);
+static const struct snd_kcontrol_new spk2r_mux =
+ SOC_DAPM_ENUM("SPK2R SRC", spk2r_src_enum);
+
+static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("DMIC1DAT"),
+ SND_SOC_DAPM_INPUT("DMIC2DAT"),
+
+ SND_SOC_DAPM_INPUT("IN1L"),
+ SND_SOC_DAPM_INPUT("IN1R"),
+
+ SND_SOC_DAPM_MIXER("IN1L PGA", SND_SOC_NOPM, 0, 0,
+ &in1l_pga, 1),
+ SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
+ &in1r_pga, 1),
+
+ SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0),
+ SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0),
+
+ SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8995_CLOCKING_1, 3, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8995_CLOCKING_1, 2, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("SYSDSPCLK", WM8995_CLOCKING_1, 1, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0,
+ WM8995_POWER_MANAGEMENT_3, 9, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0,
+ WM8995_POWER_MANAGEMENT_3, 8, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0,
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
+ 0, WM8995_POWER_MANAGEMENT_3, 11, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
+ 0, WM8995_POWER_MANAGEMENT_3, 10, 0),
+
+ SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0,
+ &adcl_mux),
+ SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
+ &adcr_mux),
+
+ SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0),
+ SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0),
+ SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8995_POWER_MANAGEMENT_3, 3, 0),
+ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8995_POWER_MANAGEMENT_3, 2, 0),
+
+ SND_SOC_DAPM_ADC("ADCL", NULL, WM8995_POWER_MANAGEMENT_3, 1, 0),
+ SND_SOC_DAPM_ADC("ADCR", NULL, WM8995_POWER_MANAGEMENT_3, 0, 0),
+
+ SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
+ aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
+ SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
+ aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
+ SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
+ aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
+ SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
+ aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
+
+ SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
+ 9, 0),
+ SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
+ 8, 0),
+ SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM,
+ 0, 0),
+
+ SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
+ 11, 0),
+ SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
+ 10, 0),
+
+ SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
+ aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
+ SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
+ aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
+
+ SND_SOC_DAPM_DAC("DAC2L", NULL, WM8995_POWER_MANAGEMENT_4, 3, 0),
+ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8995_POWER_MANAGEMENT_4, 2, 0),
+ SND_SOC_DAPM_DAC("DAC1L", NULL, WM8995_POWER_MANAGEMENT_4, 1, 0),
+ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8995_POWER_MANAGEMENT_4, 0, 0),
+
+ SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, dac1l_mix,
+ ARRAY_SIZE(dac1l_mix)),
+ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix,
+ ARRAY_SIZE(dac1r_mix)),
+
+ SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
+ SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
+
+ SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0,
+ hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_MUX("SPK1L Driver", WM8995_LEFT_PDM_SPEAKER_1,
+ 4, 0, &spk1l_mux),
+ SND_SOC_DAPM_MUX("SPK1R Driver", WM8995_RIGHT_PDM_SPEAKER_1,
+ 4, 0, &spk1r_mux),
+ SND_SOC_DAPM_MUX("SPK2L Driver", WM8995_LEFT_PDM_SPEAKER_2,
+ 4, 0, &spk2l_mux),
+ SND_SOC_DAPM_MUX("SPK2R Driver", WM8995_RIGHT_PDM_SPEAKER_2,
+ 4, 0, &spk2r_mux),
+
+ SND_SOC_DAPM_SUPPLY("LDO2", WM8995_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("HP1L"),
+ SND_SOC_DAPM_OUTPUT("HP1R"),
+ SND_SOC_DAPM_OUTPUT("SPK1L"),
+ SND_SOC_DAPM_OUTPUT("SPK1R"),
+ SND_SOC_DAPM_OUTPUT("SPK2L"),
+ SND_SOC_DAPM_OUTPUT("SPK2R")
+};
+
+static const struct snd_soc_dapm_route wm8995_intercon[] = {
+ { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
+ { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
+
+ { "DSP1CLK", NULL, "CLK_SYS" },
+ { "DSP2CLK", NULL, "CLK_SYS" },
+ { "SYSDSPCLK", NULL, "CLK_SYS" },
+
+ { "AIF1ADC1L", NULL, "AIF1CLK" },
+ { "AIF1ADC1L", NULL, "DSP1CLK" },
+ { "AIF1ADC1R", NULL, "AIF1CLK" },
+ { "AIF1ADC1R", NULL, "DSP1CLK" },
+ { "AIF1ADC1R", NULL, "SYSDSPCLK" },
+
+ { "AIF1ADC2L", NULL, "AIF1CLK" },
+ { "AIF1ADC2L", NULL, "DSP1CLK" },
+ { "AIF1ADC2R", NULL, "AIF1CLK" },
+ { "AIF1ADC2R", NULL, "DSP1CLK" },
+ { "AIF1ADC2R", NULL, "SYSDSPCLK" },
+
+ { "DMIC1L", NULL, "DMIC1DAT" },
+ { "DMIC1L", NULL, "CLK_SYS" },
+ { "DMIC1R", NULL, "DMIC1DAT" },
+ { "DMIC1R", NULL, "CLK_SYS" },
+ { "DMIC2L", NULL, "DMIC2DAT" },
+ { "DMIC2L", NULL, "CLK_SYS" },
+ { "DMIC2R", NULL, "DMIC2DAT" },
+ { "DMIC2R", NULL, "CLK_SYS" },
+
+ { "ADCL", NULL, "AIF1CLK" },
+ { "ADCL", NULL, "DSP1CLK" },
+ { "ADCL", NULL, "SYSDSPCLK" },
+
+ { "ADCR", NULL, "AIF1CLK" },
+ { "ADCR", NULL, "DSP1CLK" },
+ { "ADCR", NULL, "SYSDSPCLK" },
+
+ { "IN1L PGA", "IN1L Switch", "IN1L" },
+ { "IN1R PGA", "IN1R Switch", "IN1R" },
+ { "IN1L PGA", NULL, "LDO2" },
+ { "IN1R PGA", NULL, "LDO2" },
+
+ { "ADCL", NULL, "IN1L PGA" },
+ { "ADCR", NULL, "IN1R PGA" },
+
+ { "ADCL Mux", "ADC", "ADCL" },
+ { "ADCL Mux", "DMIC", "DMIC1L" },
+ { "ADCR Mux", "ADC", "ADCR" },
+ { "ADCR Mux", "DMIC", "DMIC1R" },
+
+ /* AIF1 outputs */
+ { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
+ { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
+
+ { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
+ { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
+
+ { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
+ { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
+
+ { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
+ { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
+
+ /* Sidetone */
+ { "Left Sidetone", "ADC/DMIC1", "AIF1ADC1L" },
+ { "Left Sidetone", "DMIC2", "AIF1ADC2L" },
+ { "Right Sidetone", "ADC/DMIC1", "AIF1ADC1R" },
+ { "Right Sidetone", "DMIC2", "AIF1ADC2R" },
+
+ { "AIF1DAC1L", NULL, "AIF1CLK" },
+ { "AIF1DAC1L", NULL, "DSP1CLK" },
+ { "AIF1DAC1R", NULL, "AIF1CLK" },
+ { "AIF1DAC1R", NULL, "DSP1CLK" },
+ { "AIF1DAC1R", NULL, "SYSDSPCLK" },
+
+ { "AIF1DAC2L", NULL, "AIF1CLK" },
+ { "AIF1DAC2L", NULL, "DSP1CLK" },
+ { "AIF1DAC2R", NULL, "AIF1CLK" },
+ { "AIF1DAC2R", NULL, "DSP1CLK" },
+ { "AIF1DAC2R", NULL, "SYSDSPCLK" },
+
+ { "DAC1L", NULL, "AIF1CLK" },
+ { "DAC1L", NULL, "DSP1CLK" },
+ { "DAC1L", NULL, "SYSDSPCLK" },
+
+ { "DAC1R", NULL, "AIF1CLK" },
+ { "DAC1R", NULL, "DSP1CLK" },
+ { "DAC1R", NULL, "SYSDSPCLK" },
+
+ { "AIF1DAC1L", NULL, "AIF1DACDAT" },
+ { "AIF1DAC1R", NULL, "AIF1DACDAT" },
+ { "AIF1DAC2L", NULL, "AIF1DACDAT" },
+ { "AIF1DAC2R", NULL, "AIF1DACDAT" },
+
+ /* DAC1 inputs */
+ { "DAC1L", NULL, "DAC1L Mixer" },
+ { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
+ { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
+ { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
+ { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
+
+ { "DAC1R", NULL, "DAC1R Mixer" },
+ { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
+ { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
+ { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
+ { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
+
+ /* DAC2/AIF2 outputs */
+ { "DAC2L", NULL, "AIF2DAC2L Mixer" },
+ { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
+ { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
+
+ { "DAC2R", NULL, "AIF2DAC2R Mixer" },
+ { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
+ { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
+
+ /* Output stages */
+ { "Headphone PGA", NULL, "DAC1L" },
+ { "Headphone PGA", NULL, "DAC1R" },
+
+ { "Headphone PGA", NULL, "DAC2L" },
+ { "Headphone PGA", NULL, "DAC2R" },
+
+ { "Headphone PGA", NULL, "Headphone Supply" },
+ { "Headphone PGA", NULL, "CLK_SYS" },
+ { "Headphone PGA", NULL, "LDO2" },
+
+ { "HP1L", NULL, "Headphone PGA" },
+ { "HP1R", NULL, "Headphone PGA" },
+
+ { "SPK1L Driver", "DAC1L", "DAC1L" },
+ { "SPK1L Driver", "DAC1R", "DAC1R" },
+ { "SPK1L Driver", "DAC2L", "DAC2L" },
+ { "SPK1L Driver", "DAC2R", "DAC2R" },
+ { "SPK1L Driver", NULL, "CLK_SYS" },
+
+ { "SPK1R Driver", "DAC1L", "DAC1L" },
+ { "SPK1R Driver", "DAC1R", "DAC1R" },
+ { "SPK1R Driver", "DAC2L", "DAC2L" },
+ { "SPK1R Driver", "DAC2R", "DAC2R" },
+ { "SPK1R Driver", NULL, "CLK_SYS" },
+
+ { "SPK2L Driver", "DAC1L", "DAC1L" },
+ { "SPK2L Driver", "DAC1R", "DAC1R" },
+ { "SPK2L Driver", "DAC2L", "DAC2L" },
+ { "SPK2L Driver", "DAC2R", "DAC2R" },
+ { "SPK2L Driver", NULL, "CLK_SYS" },
+
+ { "SPK2R Driver", "DAC1L", "DAC1L" },
+ { "SPK2R Driver", "DAC1R", "DAC1R" },
+ { "SPK2R Driver", "DAC2L", "DAC2L" },
+ { "SPK2R Driver", "DAC2R", "DAC2R" },
+ { "SPK2R Driver", NULL, "CLK_SYS" },
+
+ { "SPK1L", NULL, "SPK1L Driver" },
+ { "SPK1R", NULL, "SPK1R Driver" },
+ { "SPK2L", NULL, "SPK2L Driver" },
+ { "SPK2R", NULL, "SPK2R Driver" }
+};
+
+static int wm8995_volatile(unsigned int reg)
+{
+ /* out of bounds registers are generally considered
+ * volatile to support register banks that are partially
+ * owned by something else for e.g. a DSP
+ */
+ if (reg > WM8995_MAX_CACHED_REGISTER)
+ return 1;
+
+ switch (reg) {
+ case WM8995_SOFTWARE_RESET:
+ case WM8995_DC_SERVO_READBACK_0:
+ case WM8995_INTERRUPT_STATUS_1:
+ case WM8995_INTERRUPT_STATUS_2:
+ case WM8995_INTERRUPT_STATUS_1_MASK:
+ case WM8995_INTERRUPT_STATUS_2_MASK:
+ case WM8995_INTERRUPT_CONTROL:
+ case WM8995_ACCESSORY_DETECT_MODE1:
+ case WM8995_ACCESSORY_DETECT_MODE2:
+ case WM8995_HEADPHONE_DETECT1:
+ case WM8995_HEADPHONE_DETECT2:
+ return 1;
+ }
+
+ return 0;
+}
+
+static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int mute_reg;
+
+ switch (dai->id) {
+ case 0:
+ mute_reg = WM8995_AIF1_DAC1_FILTERS_1;
+ break;
+ case 1:
+ mute_reg = WM8995_AIF2_DAC_FILTERS_1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
+ !!mute << WM8995_AIF1DAC1_MUTE_SHIFT);
+ return 0;
+}
+
+static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec;
+ int master;
+ int aif;
+
+ codec = dai->codec;
+
+ master = 0;
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ master = WM8995_AIF1_MSTR;
+ break;
+ default:
+ dev_err(dai->dev, "Unknown master/slave configuration\n");
+ return -EINVAL;
+ }
+
+ aif = 0;
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_B:
+ aif |= WM8995_AIF1_LRCLK_INV;
+ case SND_SOC_DAIFMT_DSP_A:
+ aif |= (0x3 << WM8995_AIF1_FMT_SHIFT);
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ aif |= (0x2 << WM8995_AIF1_FMT_SHIFT);
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ aif |= (0x1 << WM8995_AIF1_FMT_SHIFT);
+ break;
+ default:
+ dev_err(dai->dev, "Unknown dai format\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ /* frame inversion not valid for DSP modes */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ aif |= WM8995_AIF1_BCLK_INV;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ aif |= WM8995_AIF1_BCLK_INV | WM8995_AIF1_LRCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ aif |= WM8995_AIF1_BCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ aif |= WM8995_AIF1_LRCLK_INV;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1,
+ WM8995_AIF1_BCLK_INV_MASK |
+ WM8995_AIF1_LRCLK_INV_MASK |
+ WM8995_AIF1_FMT_MASK, aif);
+ snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE,
+ WM8995_AIF1_MSTR_MASK, master);
+ return 0;
+}
+
+static const int srs[] = {
+ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
+ 48000, 88200, 96000
+};
+
+static const int fs_ratios[] = {
+ -1 /* reserved */,
+ 128, 192, 256, 384, 512, 768, 1024, 1408, 1536
+};
+
+static const int bclk_divs[] = {
+ 10, 15, 20, 30, 40, 55, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480
+};
+
+static int wm8995_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec;
+ struct wm8995_priv *wm8995;
+ int aif1_reg;
+ int bclk_reg;
+ int lrclk_reg;
+ int rate_reg;
+ int bclk_rate;
+ int aif1;
+ int lrclk, bclk;
+ int i, rate_val, best, best_val, cur_val;
+
+ codec = dai->codec;
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ switch (dai->id) {
+ case 0:
+ aif1_reg = WM8995_AIF1_CONTROL_1;
+ bclk_reg = WM8995_AIF1_BCLK;
+ rate_reg = WM8995_AIF1_RATE;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
+ wm8995->lrclk_shared[0] */) {
+ lrclk_reg = WM8995_AIF1DAC_LRCLK;
+ } else {
+ lrclk_reg = WM8995_AIF1ADC_LRCLK;
+ dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
+ }
+ break;
+ case 1:
+ aif1_reg = WM8995_AIF2_CONTROL_1;
+ bclk_reg = WM8995_AIF2_BCLK;
+ rate_reg = WM8995_AIF2_RATE;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
+ wm8995->lrclk_shared[1] */) {
+ lrclk_reg = WM8995_AIF2DAC_LRCLK;
+ } else {
+ lrclk_reg = WM8995_AIF2ADC_LRCLK;
+ dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ bclk_rate = snd_soc_params_to_bclk(params);
+ if (bclk_rate < 0)
+ return bclk_rate;
+
+ aif1 = 0;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ aif1 |= (0x1 << WM8995_AIF1_WL_SHIFT);
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ aif1 |= (0x2 << WM8995_AIF1_WL_SHIFT);
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ aif1 |= (0x3 << WM8995_AIF1_WL_SHIFT);
+ break;
+ default:
+ dev_err(dai->dev, "Unsupported word length %u\n",
+ params_format(params));
+ return -EINVAL;
+ }
+
+ /* try to find a suitable sample rate */
+ for (i = 0; i < ARRAY_SIZE(srs); ++i)
+ if (srs[i] == params_rate(params))
+ break;
+ if (i == ARRAY_SIZE(srs)) {
+ dev_err(dai->dev, "Sample rate %d is not supported\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+ rate_val = i << WM8995_AIF1_SR_SHIFT;
+
+ dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]);
+ dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
+ dai->id + 1, wm8995->aifclk[dai->id], bclk_rate);
+
+ /* AIFCLK/fs ratio; look for a close match in either direction */
+ best = 1;
+ best_val = abs((fs_ratios[1] * params_rate(params))
+ - wm8995->aifclk[dai->id]);
+ for (i = 2; i < ARRAY_SIZE(fs_ratios); i++) {
+ cur_val = abs((fs_ratios[i] * params_rate(params))
+ - wm8995->aifclk[dai->id]);
+ if (cur_val >= best_val)
+ continue;
+ best = i;
+ best_val = cur_val;
+ }
+ rate_val |= best;
+
+ dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
+ dai->id + 1, fs_ratios[best]);
+
+ /*
+ * We may not get quite the right frequency if using
+ * approximate clocks so look for the closest match that is
+ * higher than the target (we need to ensure that there enough
+ * BCLKs to clock out the samples).
+ */
+ best = 0;
+ bclk = 0;
+ for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
+ cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate;
+ if (cur_val < 0) /* BCLK table is sorted */
+ break;
+ best = i;
+ }
+ bclk |= best << WM8995_AIF1_BCLK_DIV_SHIFT;
+
+ bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best];
+ dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
+ bclk_divs[best], bclk_rate);
+
+ lrclk = bclk_rate / params_rate(params);
+ dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
+ lrclk, bclk_rate / lrclk);
+
+ snd_soc_update_bits(codec, aif1_reg,
+ WM8995_AIF1_WL_MASK, aif1);
+ snd_soc_update_bits(codec, bclk_reg,
+ WM8995_AIF1_BCLK_DIV_MASK, bclk);
+ snd_soc_update_bits(codec, lrclk_reg,
+ WM8995_AIF1DAC_RATE_MASK, lrclk);
+ snd_soc_update_bits(codec, rate_reg,
+ WM8995_AIF1_SR_MASK |
+ WM8995_AIF1CLK_RATE_MASK, rate_val);
+ return 0;
+}
+
+static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int reg, val, mask;
+
+ switch (codec_dai->id) {
+ case 0:
+ reg = WM8995_AIF1_MASTER_SLAVE;
+ mask = WM8995_AIF1_TRI;
+ break;
+ case 1:
+ reg = WM8995_AIF2_MASTER_SLAVE;
+ mask = WM8995_AIF2_TRI;
+ break;
+ case 2:
+ reg = WM8995_POWER_MANAGEMENT_5;
+ mask = WM8995_AIF3_TRI;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (tristate)
+ val = mask;
+ else
+ val = 0;
+
+ return snd_soc_update_bits(codec, reg, mask, reg);
+}
+
+/* The size in bits of the FLL divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_FLL_SIZE ((1 << 16) * 10)
+
+struct fll_div {
+ u16 outdiv;
+ u16 n;
+ u16 k;
+ u16 clk_ref_div;
+ u16 fll_fratio;
+};
+
+static int wm8995_get_fll_config(struct fll_div *fll,
+ int freq_in, int freq_out)
+{
+ u64 Kpart;
+ unsigned int K, Ndiv, Nmod;
+
+ pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
+
+ /* Scale the input frequency down to <= 13.5MHz */
+ fll->clk_ref_div = 0;
+ while (freq_in > 13500000) {
+ fll->clk_ref_div++;
+ freq_in /= 2;
+
+ if (fll->clk_ref_div > 3)
+ return -EINVAL;
+ }
+ pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
+
+ /* Scale the output to give 90MHz<=Fvco<=100MHz */
+ fll->outdiv = 3;
+ while (freq_out * (fll->outdiv + 1) < 90000000) {
+ fll->outdiv++;
+ if (fll->outdiv > 63)
+ return -EINVAL;
+ }
+ freq_out *= fll->outdiv + 1;
+ pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
+
+ if (freq_in > 1000000) {
+ fll->fll_fratio = 0;
+ } else if (freq_in > 256000) {
+ fll->fll_fratio = 1;
+ freq_in *= 2;
+ } else if (freq_in > 128000) {
+ fll->fll_fratio = 2;
+ freq_in *= 4;
+ } else if (freq_in > 64000) {
+ fll->fll_fratio = 3;
+ freq_in *= 8;
+ } else {
+ fll->fll_fratio = 4;
+ freq_in *= 16;
+ }
+ pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
+
+ /* Now, calculate N.K */
+ Ndiv = freq_out / freq_in;
+
+ fll->n = Ndiv;
+ Nmod = freq_out % freq_in;
+ pr_debug("Nmod=%d\n", Nmod);
+
+ /* Calculate fractional part - scale up so we can round. */
+ Kpart = FIXED_FLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, freq_in);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ fll->k = K / 10;
+
+ pr_debug("N=%x K=%x\n", fll->n, fll->k);
+
+ return 0;
+}
+
+static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
+ int src, unsigned int freq_in,
+ unsigned int freq_out)
+{
+ struct snd_soc_codec *codec;
+ struct wm8995_priv *wm8995;
+ int reg_offset, ret;
+ struct fll_div fll;
+ u16 reg, aif1, aif2;
+
+ codec = dai->codec;
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1)
+ & WM8995_AIF1CLK_ENA;
+
+ aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1)
+ & WM8995_AIF2CLK_ENA;
+
+ switch (id) {
+ case WM8995_FLL1:
+ reg_offset = 0;
+ id = 0;
+ break;
+ case WM8995_FLL2:
+ reg_offset = 0x20;
+ id = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (src) {
+ case 0:
+ /* Allow no source specification when stopping */
+ if (freq_out)
+ return -EINVAL;
+ break;
+ case WM8995_FLL_SRC_MCLK1:
+ case WM8995_FLL_SRC_MCLK2:
+ case WM8995_FLL_SRC_LRCLK:
+ case WM8995_FLL_SRC_BCLK:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Are we changing anything? */
+ if (wm8995->fll[id].src == src &&
+ wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out)
+ return 0;
+
+ /* If we're stopping the FLL redo the old config - no
+ * registers will actually be written but we avoid GCC flow
+ * analysis bugs spewing warnings.
+ */
+ if (freq_out)
+ ret = wm8995_get_fll_config(&fll, freq_in, freq_out);
+ else
+ ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in,
+ wm8995->fll[id].out);
+ if (ret < 0)
+ return ret;
+
+ /* Gate the AIF clocks while we reclock */
+ snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
+ WM8995_AIF1CLK_ENA_MASK, 0);
+ snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
+ WM8995_AIF2CLK_ENA_MASK, 0);
+
+ /* We always need to disable the FLL while reconfiguring */
+ snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
+ WM8995_FLL1_ENA_MASK, 0);
+
+ reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) |
+ (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT);
+ snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset,
+ WM8995_FLL1_OUTDIV_MASK |
+ WM8995_FLL1_FRATIO_MASK, reg);
+
+ snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
+
+ snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset,
+ WM8995_FLL1_N_MASK,
+ fll.n << WM8995_FLL1_N_SHIFT);
+
+ snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset,
+ WM8995_FLL1_REFCLK_DIV_MASK |
+ WM8995_FLL1_REFCLK_SRC_MASK,
+ (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) |
+ (src - 1));
+
+ if (freq_out)
+ snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
+ WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA);
+
+ wm8995->fll[id].in = freq_in;
+ wm8995->fll[id].out = freq_out;
+ wm8995->fll[id].src = src;
+
+ /* Enable any gated AIF clocks */
+ snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
+ WM8995_AIF1CLK_ENA_MASK, aif1);
+ snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
+ WM8995_AIF2CLK_ENA_MASK, aif2);
+
+ configure_clock(codec);
+
+ return 0;
+}
+
+static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec;
+ struct wm8995_priv *wm8995;
+
+ codec = dai->codec;
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ switch (dai->id) {
+ case 0:
+ case 1:
+ break;
+ default:
+ /* AIF3 shares clocking with AIF1/2 */
+ return -EINVAL;
+ }
+
+ switch (clk_id) {
+ case WM8995_SYSCLK_MCLK1:
+ wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
+ wm8995->mclk[0] = freq;
+ dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
+ dai->id + 1, freq);
+ break;
+ case WM8995_SYSCLK_MCLK2:
+ wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
+ wm8995->mclk[1] = freq;
+ dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
+ dai->id + 1, freq);
+ break;
+ case WM8995_SYSCLK_FLL1:
+ wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1;
+ dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1);
+ break;
+ case WM8995_SYSCLK_FLL2:
+ wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2;
+ dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1);
+ break;
+ case WM8995_SYSCLK_OPCLK:
+ default:
+ dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
+ return -EINVAL;
+ }
+
+ configure_clock(codec);
+
+ return 0;
+}
+
+static int wm8995_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8995_priv *wm8995;
+ int ret;
+
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = snd_soc_cache_sync(codec);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to sync cache: %d\n", ret);
+ return ret;
+ }
+
+ snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+ WM8995_BG_ENA_MASK, WM8995_BG_ENA);
+
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+ WM8995_BG_ENA_MASK, 0);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8995_resume(struct snd_soc_codec *codec)
+{
+ wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define wm8995_suspend NULL
+#define wm8995_resume NULL
+#endif
+
+static int wm8995_remove(struct snd_soc_codec *codec)
+{
+ struct wm8995_priv *wm8995;
+ struct i2c_client *i2c;
+
+ i2c = container_of(codec->dev, struct i2c_client, dev);
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+ wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8995_probe(struct snd_soc_codec *codec)
+{
+ struct wm8995_priv *wm8995;
+ int ret;
+
+ codec->dapm.idle_bias_off = 1;
+ wm8995 = snd_soc_codec_get_drvdata(codec);
+
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
+ return ret;
+ }
+
+ if (ret != 0x8995) {
+ dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
+ return -EINVAL;
+ }
+
+ ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+ return ret;
+ }
+
+ wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Latch volume updates (right only; we always do left then right). */
+ snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME,
+ WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU);
+ snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME,
+ WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU);
+ snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME,
+ WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU);
+ snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME,
+ WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU);
+ snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME,
+ WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU);
+ snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME,
+ WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU);
+ snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME,
+ WM8995_DAC1_VU_MASK, WM8995_DAC1_VU);
+ snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME,
+ WM8995_DAC2_VU_MASK, WM8995_DAC2_VU);
+ snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
+ WM8995_IN1_VU_MASK, WM8995_IN1_VU);
+
+ wm8995_update_class_w(codec);
+
+ snd_soc_add_controls(codec, wm8995_snd_controls,
+ ARRAY_SIZE(wm8995_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
+ ARRAY_SIZE(wm8995_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, wm8995_intercon,
+ ARRAY_SIZE(wm8995_intercon));
+
+ return 0;
+}
+
+#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
+ .set_sysclk = wm8995_set_dai_sysclk,
+ .set_fmt = wm8995_set_dai_fmt,
+ .hw_params = wm8995_hw_params,
+ .digital_mute = wm8995_aif_mute,
+ .set_pll = wm8995_set_fll,
+ .set_tristate = wm8995_set_tristate,
+};
+
+static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
+ .set_sysclk = wm8995_set_dai_sysclk,
+ .set_fmt = wm8995_set_dai_fmt,
+ .hw_params = wm8995_hw_params,
+ .digital_mute = wm8995_aif_mute,
+ .set_pll = wm8995_set_fll,
+ .set_tristate = wm8995_set_tristate,
+};
+
+static struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
+ .set_tristate = wm8995_set_tristate,
+};
+
+static struct snd_soc_dai_driver wm8995_dai[] = {
+ {
+ .name = "wm8995-aif1",
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = WM8995_FORMATS
+ },
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = WM8995_FORMATS
+ },
+ .ops = &wm8995_aif1_dai_ops
+ },
+ {
+ .name = "wm8995-aif2",
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = WM8995_FORMATS
+ },
+ .capture = {
+ .stream_name = "AIF2 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = WM8995_FORMATS
+ },
+ .ops = &wm8995_aif2_dai_ops
+ },
+ {
+ .name = "wm8995-aif3",
+ .playback = {
+ .stream_name = "AIF3 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = WM8995_FORMATS
+ },
+ .capture = {
+ .stream_name = "AIF3 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = WM8995_FORMATS
+ },
+ .ops = &wm8995_aif3_dai_ops
+ }
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
+ .probe = wm8995_probe,
+ .remove = wm8995_remove,
+ .suspend = wm8995_suspend,
+ .resume = wm8995_resume,
+ .set_bias_level = wm8995_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8995_reg_defs,
+ .volatile_register = wm8995_volatile,
+ .compress_type = SND_SOC_RBTREE_COMPRESSION
+};
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8995_spi_probe(struct spi_device *spi)
+{
+ struct wm8995_priv *wm8995;
+ int ret;
+
+ wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
+ if (!wm8995)
+ return -ENOMEM;
+
+ wm8995->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8995);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8995, wm8995_dai,
+ ARRAY_SIZE(wm8995_dai));
+ if (ret < 0)
+ kfree(wm8995);
+ return ret;
+}
+
+static int __devexit wm8995_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8995_spi_driver = {
+ .driver = {
+ .name = "wm8995",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8995_spi_probe,
+ .remove = __devexit_p(wm8995_spi_remove)
+};
+#endif
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8995_priv *wm8995;
+ int ret;
+
+ wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
+ if (!wm8995)
+ return -ENOMEM;
+
+ wm8995->control_type = SND_SOC_I2C;
+ i2c_set_clientdata(i2c, wm8995);
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8995, wm8995_dai,
+ ARRAY_SIZE(wm8995_dai));
+ if (ret < 0)
+ kfree(wm8995);
+ return ret;
+}
+
+static __devexit int wm8995_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id wm8995_i2c_id[] = {
+ {"wm8995", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, wm8995_i2c_id);
+
+static struct i2c_driver wm8995_i2c_driver = {
+ .driver = {
+ .name = "wm8995",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8995_i2c_probe,
+ .remove = __devexit_p(wm8995_i2c_remove),
+ .id_table = wm8995_i2c_id
+};
+#endif
+
+static int __init wm8995_modinit(void)
+{
+ int ret = 0;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8995_i2c_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n",
+ ret);
+ }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8995_spi_driver);
+ if (ret) {
+ printk(KERN_ERR "Failed to register wm8995 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+
+module_init(wm8995_modinit);
+
+static void __exit wm8995_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8995_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8995_spi_driver);
+#endif
+}
+
+module_exit(wm8995_exit);
+
+MODULE_DESCRIPTION("ASoC WM8995 driver");
+MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
new file mode 100644
index 000000000000..5642121c4977
--- /dev/null
+++ b/sound/soc/codecs/wm8995.h
@@ -0,0 +1,4269 @@
+/*
+ * wm8995.h -- WM8995 ALSA SoC Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics plc
+ *
+ * Author: Dimitris Papastamos <dp@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.
+ */
+
+#ifndef _WM8995_H
+#define _WM8995_H
+
+#include <asm/types.h>
+
+/*
+ * Register values.
+ */
+#define WM8995_SOFTWARE_RESET 0x00
+#define WM8995_POWER_MANAGEMENT_1 0x01
+#define WM8995_POWER_MANAGEMENT_2 0x02
+#define WM8995_POWER_MANAGEMENT_3 0x03
+#define WM8995_POWER_MANAGEMENT_4 0x04
+#define WM8995_POWER_MANAGEMENT_5 0x05
+#define WM8995_LEFT_LINE_INPUT_1_VOLUME 0x10
+#define WM8995_RIGHT_LINE_INPUT_1_VOLUME 0x11
+#define WM8995_LEFT_LINE_INPUT_CONTROL 0x12
+#define WM8995_DAC1_LEFT_VOLUME 0x18
+#define WM8995_DAC1_RIGHT_VOLUME 0x19
+#define WM8995_DAC2_LEFT_VOLUME 0x1A
+#define WM8995_DAC2_RIGHT_VOLUME 0x1B
+#define WM8995_OUTPUT_VOLUME_ZC_1 0x1C
+#define WM8995_MICBIAS_1 0x20
+#define WM8995_MICBIAS_2 0x21
+#define WM8995_LDO_1 0x28
+#define WM8995_LDO_2 0x29
+#define WM8995_ACCESSORY_DETECT_MODE1 0x30
+#define WM8995_ACCESSORY_DETECT_MODE2 0x31
+#define WM8995_HEADPHONE_DETECT1 0x34
+#define WM8995_HEADPHONE_DETECT2 0x35
+#define WM8995_MIC_DETECT_1 0x38
+#define WM8995_MIC_DETECT_2 0x39
+#define WM8995_CHARGE_PUMP_1 0x40
+#define WM8995_CLASS_W_1 0x45
+#define WM8995_DC_SERVO_1 0x50
+#define WM8995_DC_SERVO_2 0x51
+#define WM8995_DC_SERVO_3 0x52
+#define WM8995_DC_SERVO_5 0x54
+#define WM8995_DC_SERVO_6 0x55
+#define WM8995_DC_SERVO_7 0x56
+#define WM8995_DC_SERVO_READBACK_0 0x57
+#define WM8995_ANALOGUE_HP_1 0x60
+#define WM8995_ANALOGUE_HP_2 0x61
+#define WM8995_CHIP_REVISION 0x100
+#define WM8995_CONTROL_INTERFACE_1 0x101
+#define WM8995_CONTROL_INTERFACE_2 0x102
+#define WM8995_WRITE_SEQUENCER_CTRL_1 0x110
+#define WM8995_WRITE_SEQUENCER_CTRL_2 0x111
+#define WM8995_AIF1_CLOCKING_1 0x200
+#define WM8995_AIF1_CLOCKING_2 0x201
+#define WM8995_AIF2_CLOCKING_1 0x204
+#define WM8995_AIF2_CLOCKING_2 0x205
+#define WM8995_CLOCKING_1 0x208
+#define WM8995_CLOCKING_2 0x209
+#define WM8995_AIF1_RATE 0x210
+#define WM8995_AIF2_RATE 0x211
+#define WM8995_RATE_STATUS 0x212
+#define WM8995_FLL1_CONTROL_1 0x220
+#define WM8995_FLL1_CONTROL_2 0x221
+#define WM8995_FLL1_CONTROL_3 0x222
+#define WM8995_FLL1_CONTROL_4 0x223
+#define WM8995_FLL1_CONTROL_5 0x224
+#define WM8995_FLL2_CONTROL_1 0x240
+#define WM8995_FLL2_CONTROL_2 0x241
+#define WM8995_FLL2_CONTROL_3 0x242
+#define WM8995_FLL2_CONTROL_4 0x243
+#define WM8995_FLL2_CONTROL_5 0x244
+#define WM8995_AIF1_CONTROL_1 0x300
+#define WM8995_AIF1_CONTROL_2 0x301
+#define WM8995_AIF1_MASTER_SLAVE 0x302
+#define WM8995_AIF1_BCLK 0x303
+#define WM8995_AIF1ADC_LRCLK 0x304
+#define WM8995_AIF1DAC_LRCLK 0x305
+#define WM8995_AIF1DAC_DATA 0x306
+#define WM8995_AIF1ADC_DATA 0x307
+#define WM8995_AIF2_CONTROL_1 0x310
+#define WM8995_AIF2_CONTROL_2 0x311
+#define WM8995_AIF2_MASTER_SLAVE 0x312
+#define WM8995_AIF2_BCLK 0x313
+#define WM8995_AIF2ADC_LRCLK 0x314
+#define WM8995_AIF2DAC_LRCLK 0x315
+#define WM8995_AIF2DAC_DATA 0x316
+#define WM8995_AIF2ADC_DATA 0x317
+#define WM8995_AIF1_ADC1_LEFT_VOLUME 0x400
+#define WM8995_AIF1_ADC1_RIGHT_VOLUME 0x401
+#define WM8995_AIF1_DAC1_LEFT_VOLUME 0x402
+#define WM8995_AIF1_DAC1_RIGHT_VOLUME 0x403
+#define WM8995_AIF1_ADC2_LEFT_VOLUME 0x404
+#define WM8995_AIF1_ADC2_RIGHT_VOLUME 0x405
+#define WM8995_AIF1_DAC2_LEFT_VOLUME 0x406
+#define WM8995_AIF1_DAC2_RIGHT_VOLUME 0x407
+#define WM8995_AIF1_ADC1_FILTERS 0x410
+#define WM8995_AIF1_ADC2_FILTERS 0x411
+#define WM8995_AIF1_DAC1_FILTERS_1 0x420
+#define WM8995_AIF1_DAC1_FILTERS_2 0x421
+#define WM8995_AIF1_DAC2_FILTERS_1 0x422
+#define WM8995_AIF1_DAC2_FILTERS_2 0x423
+#define WM8995_AIF1_DRC1_1 0x440
+#define WM8995_AIF1_DRC1_2 0x441
+#define WM8995_AIF1_DRC1_3 0x442
+#define WM8995_AIF1_DRC1_4 0x443
+#define WM8995_AIF1_DRC1_5 0x444
+#define WM8995_AIF1_DRC2_1 0x450
+#define WM8995_AIF1_DRC2_2 0x451
+#define WM8995_AIF1_DRC2_3 0x452
+#define WM8995_AIF1_DRC2_4 0x453
+#define WM8995_AIF1_DRC2_5 0x454
+#define WM8995_AIF1_DAC1_EQ_GAINS_1 0x480
+#define WM8995_AIF1_DAC1_EQ_GAINS_2 0x481
+#define WM8995_AIF1_DAC1_EQ_BAND_1_A 0x482
+#define WM8995_AIF1_DAC1_EQ_BAND_1_B 0x483
+#define WM8995_AIF1_DAC1_EQ_BAND_1_PG 0x484
+#define WM8995_AIF1_DAC1_EQ_BAND_2_A 0x485
+#define WM8995_AIF1_DAC1_EQ_BAND_2_B 0x486
+#define WM8995_AIF1_DAC1_EQ_BAND_2_C 0x487
+#define WM8995_AIF1_DAC1_EQ_BAND_2_PG 0x488
+#define WM8995_AIF1_DAC1_EQ_BAND_3_A 0x489
+#define WM8995_AIF1_DAC1_EQ_BAND_3_B 0x48A
+#define WM8995_AIF1_DAC1_EQ_BAND_3_C 0x48B
+#define WM8995_AIF1_DAC1_EQ_BAND_3_PG 0x48C
+#define WM8995_AIF1_DAC1_EQ_BAND_4_A 0x48D
+#define WM8995_AIF1_DAC1_EQ_BAND_4_B 0x48E
+#define WM8995_AIF1_DAC1_EQ_BAND_4_C 0x48F
+#define WM8995_AIF1_DAC1_EQ_BAND_4_PG 0x490
+#define WM8995_AIF1_DAC1_EQ_BAND_5_A 0x491
+#define WM8995_AIF1_DAC1_EQ_BAND_5_B 0x492
+#define WM8995_AIF1_DAC1_EQ_BAND_5_PG 0x493
+#define WM8995_AIF1_DAC2_EQ_GAINS_1 0x4A0
+#define WM8995_AIF1_DAC2_EQ_GAINS_2 0x4A1
+#define WM8995_AIF1_DAC2_EQ_BAND_1_A 0x4A2
+#define WM8995_AIF1_DAC2_EQ_BAND_1_B 0x4A3
+#define WM8995_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
+#define WM8995_AIF1_DAC2_EQ_BAND_2_A 0x4A5
+#define WM8995_AIF1_DAC2_EQ_BAND_2_B 0x4A6
+#define WM8995_AIF1_DAC2_EQ_BAND_2_C 0x4A7
+#define WM8995_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
+#define WM8995_AIF1_DAC2_EQ_BAND_3_A 0x4A9
+#define WM8995_AIF1_DAC2_EQ_BAND_3_B 0x4AA
+#define WM8995_AIF1_DAC2_EQ_BAND_3_C 0x4AB
+#define WM8995_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
+#define WM8995_AIF1_DAC2_EQ_BAND_4_A 0x4AD
+#define WM8995_AIF1_DAC2_EQ_BAND_4_B 0x4AE
+#define WM8995_AIF1_DAC2_EQ_BAND_4_C 0x4AF
+#define WM8995_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
+#define WM8995_AIF1_DAC2_EQ_BAND_5_A 0x4B1
+#define WM8995_AIF1_DAC2_EQ_BAND_5_B 0x4B2
+#define WM8995_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
+#define WM8995_AIF2_ADC_LEFT_VOLUME 0x500
+#define WM8995_AIF2_ADC_RIGHT_VOLUME 0x501
+#define WM8995_AIF2_DAC_LEFT_VOLUME 0x502
+#define WM8995_AIF2_DAC_RIGHT_VOLUME 0x503
+#define WM8995_AIF2_ADC_FILTERS 0x510
+#define WM8995_AIF2_DAC_FILTERS_1 0x520
+#define WM8995_AIF2_DAC_FILTERS_2 0x521
+#define WM8995_AIF2_DRC_1 0x540
+#define WM8995_AIF2_DRC_2 0x541
+#define WM8995_AIF2_DRC_3 0x542
+#define WM8995_AIF2_DRC_4 0x543
+#define WM8995_AIF2_DRC_5 0x544
+#define WM8995_AIF2_EQ_GAINS_1 0x580
+#define WM8995_AIF2_EQ_GAINS_2 0x581
+#define WM8995_AIF2_EQ_BAND_1_A 0x582
+#define WM8995_AIF2_EQ_BAND_1_B 0x583
+#define WM8995_AIF2_EQ_BAND_1_PG 0x584
+#define WM8995_AIF2_EQ_BAND_2_A 0x585
+#define WM8995_AIF2_EQ_BAND_2_B 0x586
+#define WM8995_AIF2_EQ_BAND_2_C 0x587
+#define WM8995_AIF2_EQ_BAND_2_PG 0x588
+#define WM8995_AIF2_EQ_BAND_3_A 0x589
+#define WM8995_AIF2_EQ_BAND_3_B 0x58A
+#define WM8995_AIF2_EQ_BAND_3_C 0x58B
+#define WM8995_AIF2_EQ_BAND_3_PG 0x58C
+#define WM8995_AIF2_EQ_BAND_4_A 0x58D
+#define WM8995_AIF2_EQ_BAND_4_B 0x58E
+#define WM8995_AIF2_EQ_BAND_4_C 0x58F
+#define WM8995_AIF2_EQ_BAND_4_PG 0x590
+#define WM8995_AIF2_EQ_BAND_5_A 0x591
+#define WM8995_AIF2_EQ_BAND_5_B 0x592
+#define WM8995_AIF2_EQ_BAND_5_PG 0x593
+#define WM8995_DAC1_MIXER_VOLUMES 0x600
+#define WM8995_DAC1_LEFT_MIXER_ROUTING 0x601
+#define WM8995_DAC1_RIGHT_MIXER_ROUTING 0x602
+#define WM8995_DAC2_MIXER_VOLUMES 0x603
+#define WM8995_DAC2_LEFT_MIXER_ROUTING 0x604
+#define WM8995_DAC2_RIGHT_MIXER_ROUTING 0x605
+#define WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
+#define WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
+#define WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
+#define WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
+#define WM8995_DAC_SOFTMUTE 0x610
+#define WM8995_OVERSAMPLING 0x620
+#define WM8995_SIDETONE 0x621
+#define WM8995_GPIO_1 0x700
+#define WM8995_GPIO_2 0x701
+#define WM8995_GPIO_3 0x702
+#define WM8995_GPIO_4 0x703
+#define WM8995_GPIO_5 0x704
+#define WM8995_GPIO_6 0x705
+#define WM8995_GPIO_7 0x706
+#define WM8995_GPIO_8 0x707
+#define WM8995_GPIO_9 0x708
+#define WM8995_GPIO_10 0x709
+#define WM8995_GPIO_11 0x70A
+#define WM8995_GPIO_12 0x70B
+#define WM8995_GPIO_13 0x70C
+#define WM8995_GPIO_14 0x70D
+#define WM8995_PULL_CONTROL_1 0x720
+#define WM8995_PULL_CONTROL_2 0x721
+#define WM8995_INTERRUPT_STATUS_1 0x730
+#define WM8995_INTERRUPT_STATUS_2 0x731
+#define WM8995_INTERRUPT_RAW_STATUS_2 0x732
+#define WM8995_INTERRUPT_STATUS_1_MASK 0x738
+#define WM8995_INTERRUPT_STATUS_2_MASK 0x739
+#define WM8995_INTERRUPT_CONTROL 0x740
+#define WM8995_LEFT_PDM_SPEAKER_1 0x800
+#define WM8995_RIGHT_PDM_SPEAKER_1 0x801
+#define WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE 0x802
+#define WM8995_LEFT_PDM_SPEAKER_2 0x808
+#define WM8995_RIGHT_PDM_SPEAKER_2 0x809
+#define WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE 0x80A
+#define WM8995_WRITE_SEQUENCER_0 0x3000
+#define WM8995_WRITE_SEQUENCER_1 0x3001
+#define WM8995_WRITE_SEQUENCER_2 0x3002
+#define WM8995_WRITE_SEQUENCER_3 0x3003
+#define WM8995_WRITE_SEQUENCER_4 0x3004
+#define WM8995_WRITE_SEQUENCER_5 0x3005
+#define WM8995_WRITE_SEQUENCER_6 0x3006
+#define WM8995_WRITE_SEQUENCER_7 0x3007
+#define WM8995_WRITE_SEQUENCER_8 0x3008
+#define WM8995_WRITE_SEQUENCER_9 0x3009
+#define WM8995_WRITE_SEQUENCER_10 0x300A
+#define WM8995_WRITE_SEQUENCER_11 0x300B
+#define WM8995_WRITE_SEQUENCER_12 0x300C
+#define WM8995_WRITE_SEQUENCER_13 0x300D
+#define WM8995_WRITE_SEQUENCER_14 0x300E
+#define WM8995_WRITE_SEQUENCER_15 0x300F
+#define WM8995_WRITE_SEQUENCER_16 0x3010
+#define WM8995_WRITE_SEQUENCER_17 0x3011
+#define WM8995_WRITE_SEQUENCER_18 0x3012
+#define WM8995_WRITE_SEQUENCER_19 0x3013
+#define WM8995_WRITE_SEQUENCER_20 0x3014
+#define WM8995_WRITE_SEQUENCER_21 0x3015
+#define WM8995_WRITE_SEQUENCER_22 0x3016
+#define WM8995_WRITE_SEQUENCER_23 0x3017
+#define WM8995_WRITE_SEQUENCER_24 0x3018
+#define WM8995_WRITE_SEQUENCER_25 0x3019
+#define WM8995_WRITE_SEQUENCER_26 0x301A
+#define WM8995_WRITE_SEQUENCER_27 0x301B
+#define WM8995_WRITE_SEQUENCER_28 0x301C
+#define WM8995_WRITE_SEQUENCER_29 0x301D
+#define WM8995_WRITE_SEQUENCER_30 0x301E
+#define WM8995_WRITE_SEQUENCER_31 0x301F
+#define WM8995_WRITE_SEQUENCER_32 0x3020
+#define WM8995_WRITE_SEQUENCER_33 0x3021
+#define WM8995_WRITE_SEQUENCER_34 0x3022
+#define WM8995_WRITE_SEQUENCER_35 0x3023
+#define WM8995_WRITE_SEQUENCER_36 0x3024
+#define WM8995_WRITE_SEQUENCER_37 0x3025
+#define WM8995_WRITE_SEQUENCER_38 0x3026
+#define WM8995_WRITE_SEQUENCER_39 0x3027
+#define WM8995_WRITE_SEQUENCER_40 0x3028
+#define WM8995_WRITE_SEQUENCER_41 0x3029
+#define WM8995_WRITE_SEQUENCER_42 0x302A
+#define WM8995_WRITE_SEQUENCER_43 0x302B
+#define WM8995_WRITE_SEQUENCER_44 0x302C
+#define WM8995_WRITE_SEQUENCER_45 0x302D
+#define WM8995_WRITE_SEQUENCER_46 0x302E
+#define WM8995_WRITE_SEQUENCER_47 0x302F
+#define WM8995_WRITE_SEQUENCER_48 0x3030
+#define WM8995_WRITE_SEQUENCER_49 0x3031
+#define WM8995_WRITE_SEQUENCER_50 0x3032
+#define WM8995_WRITE_SEQUENCER_51 0x3033
+#define WM8995_WRITE_SEQUENCER_52 0x3034
+#define WM8995_WRITE_SEQUENCER_53 0x3035
+#define WM8995_WRITE_SEQUENCER_54 0x3036
+#define WM8995_WRITE_SEQUENCER_55 0x3037
+#define WM8995_WRITE_SEQUENCER_56 0x3038
+#define WM8995_WRITE_SEQUENCER_57 0x3039
+#define WM8995_WRITE_SEQUENCER_58 0x303A
+#define WM8995_WRITE_SEQUENCER_59 0x303B
+#define WM8995_WRITE_SEQUENCER_60 0x303C
+#define WM8995_WRITE_SEQUENCER_61 0x303D
+#define WM8995_WRITE_SEQUENCER_62 0x303E
+#define WM8995_WRITE_SEQUENCER_63 0x303F
+#define WM8995_WRITE_SEQUENCER_64 0x3040
+#define WM8995_WRITE_SEQUENCER_65 0x3041
+#define WM8995_WRITE_SEQUENCER_66 0x3042
+#define WM8995_WRITE_SEQUENCER_67 0x3043
+#define WM8995_WRITE_SEQUENCER_68 0x3044
+#define WM8995_WRITE_SEQUENCER_69 0x3045
+#define WM8995_WRITE_SEQUENCER_70 0x3046
+#define WM8995_WRITE_SEQUENCER_71 0x3047
+#define WM8995_WRITE_SEQUENCER_72 0x3048
+#define WM8995_WRITE_SEQUENCER_73 0x3049
+#define WM8995_WRITE_SEQUENCER_74 0x304A
+#define WM8995_WRITE_SEQUENCER_75 0x304B
+#define WM8995_WRITE_SEQUENCER_76 0x304C
+#define WM8995_WRITE_SEQUENCER_77 0x304D
+#define WM8995_WRITE_SEQUENCER_78 0x304E
+#define WM8995_WRITE_SEQUENCER_79 0x304F
+#define WM8995_WRITE_SEQUENCER_80 0x3050
+#define WM8995_WRITE_SEQUENCER_81 0x3051
+#define WM8995_WRITE_SEQUENCER_82 0x3052
+#define WM8995_WRITE_SEQUENCER_83 0x3053
+#define WM8995_WRITE_SEQUENCER_84 0x3054
+#define WM8995_WRITE_SEQUENCER_85 0x3055
+#define WM8995_WRITE_SEQUENCER_86 0x3056
+#define WM8995_WRITE_SEQUENCER_87 0x3057
+#define WM8995_WRITE_SEQUENCER_88 0x3058
+#define WM8995_WRITE_SEQUENCER_89 0x3059
+#define WM8995_WRITE_SEQUENCER_90 0x305A
+#define WM8995_WRITE_SEQUENCER_91 0x305B
+#define WM8995_WRITE_SEQUENCER_92 0x305C
+#define WM8995_WRITE_SEQUENCER_93 0x305D
+#define WM8995_WRITE_SEQUENCER_94 0x305E
+#define WM8995_WRITE_SEQUENCER_95 0x305F
+#define WM8995_WRITE_SEQUENCER_96 0x3060
+#define WM8995_WRITE_SEQUENCER_97 0x3061
+#define WM8995_WRITE_SEQUENCER_98 0x3062
+#define WM8995_WRITE_SEQUENCER_99 0x3063
+#define WM8995_WRITE_SEQUENCER_100 0x3064
+#define WM8995_WRITE_SEQUENCER_101 0x3065
+#define WM8995_WRITE_SEQUENCER_102 0x3066
+#define WM8995_WRITE_SEQUENCER_103 0x3067
+#define WM8995_WRITE_SEQUENCER_104 0x3068
+#define WM8995_WRITE_SEQUENCER_105 0x3069
+#define WM8995_WRITE_SEQUENCER_106 0x306A
+#define WM8995_WRITE_SEQUENCER_107 0x306B
+#define WM8995_WRITE_SEQUENCER_108 0x306C
+#define WM8995_WRITE_SEQUENCER_109 0x306D
+#define WM8995_WRITE_SEQUENCER_110 0x306E
+#define WM8995_WRITE_SEQUENCER_111 0x306F
+#define WM8995_WRITE_SEQUENCER_112 0x3070
+#define WM8995_WRITE_SEQUENCER_113 0x3071
+#define WM8995_WRITE_SEQUENCER_114 0x3072
+#define WM8995_WRITE_SEQUENCER_115 0x3073
+#define WM8995_WRITE_SEQUENCER_116 0x3074
+#define WM8995_WRITE_SEQUENCER_117 0x3075
+#define WM8995_WRITE_SEQUENCER_118 0x3076
+#define WM8995_WRITE_SEQUENCER_119 0x3077
+#define WM8995_WRITE_SEQUENCER_120 0x3078
+#define WM8995_WRITE_SEQUENCER_121 0x3079
+#define WM8995_WRITE_SEQUENCER_122 0x307A
+#define WM8995_WRITE_SEQUENCER_123 0x307B
+#define WM8995_WRITE_SEQUENCER_124 0x307C
+#define WM8995_WRITE_SEQUENCER_125 0x307D
+#define WM8995_WRITE_SEQUENCER_126 0x307E
+#define WM8995_WRITE_SEQUENCER_127 0x307F
+#define WM8995_WRITE_SEQUENCER_128 0x3080
+#define WM8995_WRITE_SEQUENCER_129 0x3081
+#define WM8995_WRITE_SEQUENCER_130 0x3082
+#define WM8995_WRITE_SEQUENCER_131 0x3083
+#define WM8995_WRITE_SEQUENCER_132 0x3084
+#define WM8995_WRITE_SEQUENCER_133 0x3085
+#define WM8995_WRITE_SEQUENCER_134 0x3086
+#define WM8995_WRITE_SEQUENCER_135 0x3087
+#define WM8995_WRITE_SEQUENCER_136 0x3088
+#define WM8995_WRITE_SEQUENCER_137 0x3089
+#define WM8995_WRITE_SEQUENCER_138 0x308A
+#define WM8995_WRITE_SEQUENCER_139 0x308B
+#define WM8995_WRITE_SEQUENCER_140 0x308C
+#define WM8995_WRITE_SEQUENCER_141 0x308D
+#define WM8995_WRITE_SEQUENCER_142 0x308E
+#define WM8995_WRITE_SEQUENCER_143 0x308F
+#define WM8995_WRITE_SEQUENCER_144 0x3090
+#define WM8995_WRITE_SEQUENCER_145 0x3091
+#define WM8995_WRITE_SEQUENCER_146 0x3092
+#define WM8995_WRITE_SEQUENCER_147 0x3093
+#define WM8995_WRITE_SEQUENCER_148 0x3094
+#define WM8995_WRITE_SEQUENCER_149 0x3095
+#define WM8995_WRITE_SEQUENCER_150 0x3096
+#define WM8995_WRITE_SEQUENCER_151 0x3097
+#define WM8995_WRITE_SEQUENCER_152 0x3098
+#define WM8995_WRITE_SEQUENCER_153 0x3099
+#define WM8995_WRITE_SEQUENCER_154 0x309A
+#define WM8995_WRITE_SEQUENCER_155 0x309B
+#define WM8995_WRITE_SEQUENCER_156 0x309C
+#define WM8995_WRITE_SEQUENCER_157 0x309D
+#define WM8995_WRITE_SEQUENCER_158 0x309E
+#define WM8995_WRITE_SEQUENCER_159 0x309F
+#define WM8995_WRITE_SEQUENCER_160 0x30A0
+#define WM8995_WRITE_SEQUENCER_161 0x30A1
+#define WM8995_WRITE_SEQUENCER_162 0x30A2
+#define WM8995_WRITE_SEQUENCER_163 0x30A3
+#define WM8995_WRITE_SEQUENCER_164 0x30A4
+#define WM8995_WRITE_SEQUENCER_165 0x30A5
+#define WM8995_WRITE_SEQUENCER_166 0x30A6
+#define WM8995_WRITE_SEQUENCER_167 0x30A7
+#define WM8995_WRITE_SEQUENCER_168 0x30A8
+#define WM8995_WRITE_SEQUENCER_169 0x30A9
+#define WM8995_WRITE_SEQUENCER_170 0x30AA
+#define WM8995_WRITE_SEQUENCER_171 0x30AB
+#define WM8995_WRITE_SEQUENCER_172 0x30AC
+#define WM8995_WRITE_SEQUENCER_173 0x30AD
+#define WM8995_WRITE_SEQUENCER_174 0x30AE
+#define WM8995_WRITE_SEQUENCER_175 0x30AF
+#define WM8995_WRITE_SEQUENCER_176 0x30B0
+#define WM8995_WRITE_SEQUENCER_177 0x30B1
+#define WM8995_WRITE_SEQUENCER_178 0x30B2
+#define WM8995_WRITE_SEQUENCER_179 0x30B3
+#define WM8995_WRITE_SEQUENCER_180 0x30B4
+#define WM8995_WRITE_SEQUENCER_181 0x30B5
+#define WM8995_WRITE_SEQUENCER_182 0x30B6
+#define WM8995_WRITE_SEQUENCER_183 0x30B7
+#define WM8995_WRITE_SEQUENCER_184 0x30B8
+#define WM8995_WRITE_SEQUENCER_185 0x30B9
+#define WM8995_WRITE_SEQUENCER_186 0x30BA
+#define WM8995_WRITE_SEQUENCER_187 0x30BB
+#define WM8995_WRITE_SEQUENCER_188 0x30BC
+#define WM8995_WRITE_SEQUENCER_189 0x30BD
+#define WM8995_WRITE_SEQUENCER_190 0x30BE
+#define WM8995_WRITE_SEQUENCER_191 0x30BF
+#define WM8995_WRITE_SEQUENCER_192 0x30C0
+#define WM8995_WRITE_SEQUENCER_193 0x30C1
+#define WM8995_WRITE_SEQUENCER_194 0x30C2
+#define WM8995_WRITE_SEQUENCER_195 0x30C3
+#define WM8995_WRITE_SEQUENCER_196 0x30C4
+#define WM8995_WRITE_SEQUENCER_197 0x30C5
+#define WM8995_WRITE_SEQUENCER_198 0x30C6
+#define WM8995_WRITE_SEQUENCER_199 0x30C7
+#define WM8995_WRITE_SEQUENCER_200 0x30C8
+#define WM8995_WRITE_SEQUENCER_201 0x30C9
+#define WM8995_WRITE_SEQUENCER_202 0x30CA
+#define WM8995_WRITE_SEQUENCER_203 0x30CB
+#define WM8995_WRITE_SEQUENCER_204 0x30CC
+#define WM8995_WRITE_SEQUENCER_205 0x30CD
+#define WM8995_WRITE_SEQUENCER_206 0x30CE
+#define WM8995_WRITE_SEQUENCER_207 0x30CF
+#define WM8995_WRITE_SEQUENCER_208 0x30D0
+#define WM8995_WRITE_SEQUENCER_209 0x30D1
+#define WM8995_WRITE_SEQUENCER_210 0x30D2
+#define WM8995_WRITE_SEQUENCER_211 0x30D3
+#define WM8995_WRITE_SEQUENCER_212 0x30D4
+#define WM8995_WRITE_SEQUENCER_213 0x30D5
+#define WM8995_WRITE_SEQUENCER_214 0x30D6
+#define WM8995_WRITE_SEQUENCER_215 0x30D7
+#define WM8995_WRITE_SEQUENCER_216 0x30D8
+#define WM8995_WRITE_SEQUENCER_217 0x30D9
+#define WM8995_WRITE_SEQUENCER_218 0x30DA
+#define WM8995_WRITE_SEQUENCER_219 0x30DB
+#define WM8995_WRITE_SEQUENCER_220 0x30DC
+#define WM8995_WRITE_SEQUENCER_221 0x30DD
+#define WM8995_WRITE_SEQUENCER_222 0x30DE
+#define WM8995_WRITE_SEQUENCER_223 0x30DF
+#define WM8995_WRITE_SEQUENCER_224 0x30E0
+#define WM8995_WRITE_SEQUENCER_225 0x30E1
+#define WM8995_WRITE_SEQUENCER_226 0x30E2
+#define WM8995_WRITE_SEQUENCER_227 0x30E3
+#define WM8995_WRITE_SEQUENCER_228 0x30E4
+#define WM8995_WRITE_SEQUENCER_229 0x30E5
+#define WM8995_WRITE_SEQUENCER_230 0x30E6
+#define WM8995_WRITE_SEQUENCER_231 0x30E7
+#define WM8995_WRITE_SEQUENCER_232 0x30E8
+#define WM8995_WRITE_SEQUENCER_233 0x30E9
+#define WM8995_WRITE_SEQUENCER_234 0x30EA
+#define WM8995_WRITE_SEQUENCER_235 0x30EB
+#define WM8995_WRITE_SEQUENCER_236 0x30EC
+#define WM8995_WRITE_SEQUENCER_237 0x30ED
+#define WM8995_WRITE_SEQUENCER_238 0x30EE
+#define WM8995_WRITE_SEQUENCER_239 0x30EF
+#define WM8995_WRITE_SEQUENCER_240 0x30F0
+#define WM8995_WRITE_SEQUENCER_241 0x30F1
+#define WM8995_WRITE_SEQUENCER_242 0x30F2
+#define WM8995_WRITE_SEQUENCER_243 0x30F3
+#define WM8995_WRITE_SEQUENCER_244 0x30F4
+#define WM8995_WRITE_SEQUENCER_245 0x30F5
+#define WM8995_WRITE_SEQUENCER_246 0x30F6
+#define WM8995_WRITE_SEQUENCER_247 0x30F7
+#define WM8995_WRITE_SEQUENCER_248 0x30F8
+#define WM8995_WRITE_SEQUENCER_249 0x30F9
+#define WM8995_WRITE_SEQUENCER_250 0x30FA
+#define WM8995_WRITE_SEQUENCER_251 0x30FB
+#define WM8995_WRITE_SEQUENCER_252 0x30FC
+#define WM8995_WRITE_SEQUENCER_253 0x30FD
+#define WM8995_WRITE_SEQUENCER_254 0x30FE
+#define WM8995_WRITE_SEQUENCER_255 0x30FF
+#define WM8995_WRITE_SEQUENCER_256 0x3100
+#define WM8995_WRITE_SEQUENCER_257 0x3101
+#define WM8995_WRITE_SEQUENCER_258 0x3102
+#define WM8995_WRITE_SEQUENCER_259 0x3103
+#define WM8995_WRITE_SEQUENCER_260 0x3104
+#define WM8995_WRITE_SEQUENCER_261 0x3105
+#define WM8995_WRITE_SEQUENCER_262 0x3106
+#define WM8995_WRITE_SEQUENCER_263 0x3107
+#define WM8995_WRITE_SEQUENCER_264 0x3108
+#define WM8995_WRITE_SEQUENCER_265 0x3109
+#define WM8995_WRITE_SEQUENCER_266 0x310A
+#define WM8995_WRITE_SEQUENCER_267 0x310B
+#define WM8995_WRITE_SEQUENCER_268 0x310C
+#define WM8995_WRITE_SEQUENCER_269 0x310D
+#define WM8995_WRITE_SEQUENCER_270 0x310E
+#define WM8995_WRITE_SEQUENCER_271 0x310F
+#define WM8995_WRITE_SEQUENCER_272 0x3110
+#define WM8995_WRITE_SEQUENCER_273 0x3111
+#define WM8995_WRITE_SEQUENCER_274 0x3112
+#define WM8995_WRITE_SEQUENCER_275 0x3113
+#define WM8995_WRITE_SEQUENCER_276 0x3114
+#define WM8995_WRITE_SEQUENCER_277 0x3115
+#define WM8995_WRITE_SEQUENCER_278 0x3116
+#define WM8995_WRITE_SEQUENCER_279 0x3117
+#define WM8995_WRITE_SEQUENCER_280 0x3118
+#define WM8995_WRITE_SEQUENCER_281 0x3119
+#define WM8995_WRITE_SEQUENCER_282 0x311A
+#define WM8995_WRITE_SEQUENCER_283 0x311B
+#define WM8995_WRITE_SEQUENCER_284 0x311C
+#define WM8995_WRITE_SEQUENCER_285 0x311D
+#define WM8995_WRITE_SEQUENCER_286 0x311E
+#define WM8995_WRITE_SEQUENCER_287 0x311F
+#define WM8995_WRITE_SEQUENCER_288 0x3120
+#define WM8995_WRITE_SEQUENCER_289 0x3121
+#define WM8995_WRITE_SEQUENCER_290 0x3122
+#define WM8995_WRITE_SEQUENCER_291 0x3123
+#define WM8995_WRITE_SEQUENCER_292 0x3124
+#define WM8995_WRITE_SEQUENCER_293 0x3125
+#define WM8995_WRITE_SEQUENCER_294 0x3126
+#define WM8995_WRITE_SEQUENCER_295 0x3127
+#define WM8995_WRITE_SEQUENCER_296 0x3128
+#define WM8995_WRITE_SEQUENCER_297 0x3129
+#define WM8995_WRITE_SEQUENCER_298 0x312A
+#define WM8995_WRITE_SEQUENCER_299 0x312B
+#define WM8995_WRITE_SEQUENCER_300 0x312C
+#define WM8995_WRITE_SEQUENCER_301 0x312D
+#define WM8995_WRITE_SEQUENCER_302 0x312E
+#define WM8995_WRITE_SEQUENCER_303 0x312F
+#define WM8995_WRITE_SEQUENCER_304 0x3130
+#define WM8995_WRITE_SEQUENCER_305 0x3131
+#define WM8995_WRITE_SEQUENCER_306 0x3132
+#define WM8995_WRITE_SEQUENCER_307 0x3133
+#define WM8995_WRITE_SEQUENCER_308 0x3134
+#define WM8995_WRITE_SEQUENCER_309 0x3135
+#define WM8995_WRITE_SEQUENCER_310 0x3136
+#define WM8995_WRITE_SEQUENCER_311 0x3137
+#define WM8995_WRITE_SEQUENCER_312 0x3138
+#define WM8995_WRITE_SEQUENCER_313 0x3139
+#define WM8995_WRITE_SEQUENCER_314 0x313A
+#define WM8995_WRITE_SEQUENCER_315 0x313B
+#define WM8995_WRITE_SEQUENCER_316 0x313C
+#define WM8995_WRITE_SEQUENCER_317 0x313D
+#define WM8995_WRITE_SEQUENCER_318 0x313E
+#define WM8995_WRITE_SEQUENCER_319 0x313F
+#define WM8995_WRITE_SEQUENCER_320 0x3140
+#define WM8995_WRITE_SEQUENCER_321 0x3141
+#define WM8995_WRITE_SEQUENCER_322 0x3142
+#define WM8995_WRITE_SEQUENCER_323 0x3143
+#define WM8995_WRITE_SEQUENCER_324 0x3144
+#define WM8995_WRITE_SEQUENCER_325 0x3145
+#define WM8995_WRITE_SEQUENCER_326 0x3146
+#define WM8995_WRITE_SEQUENCER_327 0x3147
+#define WM8995_WRITE_SEQUENCER_328 0x3148
+#define WM8995_WRITE_SEQUENCER_329 0x3149
+#define WM8995_WRITE_SEQUENCER_330 0x314A
+#define WM8995_WRITE_SEQUENCER_331 0x314B
+#define WM8995_WRITE_SEQUENCER_332 0x314C
+#define WM8995_WRITE_SEQUENCER_333 0x314D
+#define WM8995_WRITE_SEQUENCER_334 0x314E
+#define WM8995_WRITE_SEQUENCER_335 0x314F
+#define WM8995_WRITE_SEQUENCER_336 0x3150
+#define WM8995_WRITE_SEQUENCER_337 0x3151
+#define WM8995_WRITE_SEQUENCER_338 0x3152
+#define WM8995_WRITE_SEQUENCER_339 0x3153
+#define WM8995_WRITE_SEQUENCER_340 0x3154
+#define WM8995_WRITE_SEQUENCER_341 0x3155
+#define WM8995_WRITE_SEQUENCER_342 0x3156
+#define WM8995_WRITE_SEQUENCER_343 0x3157
+#define WM8995_WRITE_SEQUENCER_344 0x3158
+#define WM8995_WRITE_SEQUENCER_345 0x3159
+#define WM8995_WRITE_SEQUENCER_346 0x315A
+#define WM8995_WRITE_SEQUENCER_347 0x315B
+#define WM8995_WRITE_SEQUENCER_348 0x315C
+#define WM8995_WRITE_SEQUENCER_349 0x315D
+#define WM8995_WRITE_SEQUENCER_350 0x315E
+#define WM8995_WRITE_SEQUENCER_351 0x315F
+#define WM8995_WRITE_SEQUENCER_352 0x3160
+#define WM8995_WRITE_SEQUENCER_353 0x3161
+#define WM8995_WRITE_SEQUENCER_354 0x3162
+#define WM8995_WRITE_SEQUENCER_355 0x3163
+#define WM8995_WRITE_SEQUENCER_356 0x3164
+#define WM8995_WRITE_SEQUENCER_357 0x3165
+#define WM8995_WRITE_SEQUENCER_358 0x3166
+#define WM8995_WRITE_SEQUENCER_359 0x3167
+#define WM8995_WRITE_SEQUENCER_360 0x3168
+#define WM8995_WRITE_SEQUENCER_361 0x3169
+#define WM8995_WRITE_SEQUENCER_362 0x316A
+#define WM8995_WRITE_SEQUENCER_363 0x316B
+#define WM8995_WRITE_SEQUENCER_364 0x316C
+#define WM8995_WRITE_SEQUENCER_365 0x316D
+#define WM8995_WRITE_SEQUENCER_366 0x316E
+#define WM8995_WRITE_SEQUENCER_367 0x316F
+#define WM8995_WRITE_SEQUENCER_368 0x3170
+#define WM8995_WRITE_SEQUENCER_369 0x3171
+#define WM8995_WRITE_SEQUENCER_370 0x3172
+#define WM8995_WRITE_SEQUENCER_371 0x3173
+#define WM8995_WRITE_SEQUENCER_372 0x3174
+#define WM8995_WRITE_SEQUENCER_373 0x3175
+#define WM8995_WRITE_SEQUENCER_374 0x3176
+#define WM8995_WRITE_SEQUENCER_375 0x3177
+#define WM8995_WRITE_SEQUENCER_376 0x3178
+#define WM8995_WRITE_SEQUENCER_377 0x3179
+#define WM8995_WRITE_SEQUENCER_378 0x317A
+#define WM8995_WRITE_SEQUENCER_379 0x317B
+#define WM8995_WRITE_SEQUENCER_380 0x317C
+#define WM8995_WRITE_SEQUENCER_381 0x317D
+#define WM8995_WRITE_SEQUENCER_382 0x317E
+#define WM8995_WRITE_SEQUENCER_383 0x317F
+#define WM8995_WRITE_SEQUENCER_384 0x3180
+#define WM8995_WRITE_SEQUENCER_385 0x3181
+#define WM8995_WRITE_SEQUENCER_386 0x3182
+#define WM8995_WRITE_SEQUENCER_387 0x3183
+#define WM8995_WRITE_SEQUENCER_388 0x3184
+#define WM8995_WRITE_SEQUENCER_389 0x3185
+#define WM8995_WRITE_SEQUENCER_390 0x3186
+#define WM8995_WRITE_SEQUENCER_391 0x3187
+#define WM8995_WRITE_SEQUENCER_392 0x3188
+#define WM8995_WRITE_SEQUENCER_393 0x3189
+#define WM8995_WRITE_SEQUENCER_394 0x318A
+#define WM8995_WRITE_SEQUENCER_395 0x318B
+#define WM8995_WRITE_SEQUENCER_396 0x318C
+#define WM8995_WRITE_SEQUENCER_397 0x318D
+#define WM8995_WRITE_SEQUENCER_398 0x318E
+#define WM8995_WRITE_SEQUENCER_399 0x318F
+#define WM8995_WRITE_SEQUENCER_400 0x3190
+#define WM8995_WRITE_SEQUENCER_401 0x3191
+#define WM8995_WRITE_SEQUENCER_402 0x3192
+#define WM8995_WRITE_SEQUENCER_403 0x3193
+#define WM8995_WRITE_SEQUENCER_404 0x3194
+#define WM8995_WRITE_SEQUENCER_405 0x3195
+#define WM8995_WRITE_SEQUENCER_406 0x3196
+#define WM8995_WRITE_SEQUENCER_407 0x3197
+#define WM8995_WRITE_SEQUENCER_408 0x3198
+#define WM8995_WRITE_SEQUENCER_409 0x3199
+#define WM8995_WRITE_SEQUENCER_410 0x319A
+#define WM8995_WRITE_SEQUENCER_411 0x319B
+#define WM8995_WRITE_SEQUENCER_412 0x319C
+#define WM8995_WRITE_SEQUENCER_413 0x319D
+#define WM8995_WRITE_SEQUENCER_414 0x319E
+#define WM8995_WRITE_SEQUENCER_415 0x319F
+#define WM8995_WRITE_SEQUENCER_416 0x31A0
+#define WM8995_WRITE_SEQUENCER_417 0x31A1
+#define WM8995_WRITE_SEQUENCER_418 0x31A2
+#define WM8995_WRITE_SEQUENCER_419 0x31A3
+#define WM8995_WRITE_SEQUENCER_420 0x31A4
+#define WM8995_WRITE_SEQUENCER_421 0x31A5
+#define WM8995_WRITE_SEQUENCER_422 0x31A6
+#define WM8995_WRITE_SEQUENCER_423 0x31A7
+#define WM8995_WRITE_SEQUENCER_424 0x31A8
+#define WM8995_WRITE_SEQUENCER_425 0x31A9
+#define WM8995_WRITE_SEQUENCER_426 0x31AA
+#define WM8995_WRITE_SEQUENCER_427 0x31AB
+#define WM8995_WRITE_SEQUENCER_428 0x31AC
+#define WM8995_WRITE_SEQUENCER_429 0x31AD
+#define WM8995_WRITE_SEQUENCER_430 0x31AE
+#define WM8995_WRITE_SEQUENCER_431 0x31AF
+#define WM8995_WRITE_SEQUENCER_432 0x31B0
+#define WM8995_WRITE_SEQUENCER_433 0x31B1
+#define WM8995_WRITE_SEQUENCER_434 0x31B2
+#define WM8995_WRITE_SEQUENCER_435 0x31B3
+#define WM8995_WRITE_SEQUENCER_436 0x31B4
+#define WM8995_WRITE_SEQUENCER_437 0x31B5
+#define WM8995_WRITE_SEQUENCER_438 0x31B6
+#define WM8995_WRITE_SEQUENCER_439 0x31B7
+#define WM8995_WRITE_SEQUENCER_440 0x31B8
+#define WM8995_WRITE_SEQUENCER_441 0x31B9
+#define WM8995_WRITE_SEQUENCER_442 0x31BA
+#define WM8995_WRITE_SEQUENCER_443 0x31BB
+#define WM8995_WRITE_SEQUENCER_444 0x31BC
+#define WM8995_WRITE_SEQUENCER_445 0x31BD
+#define WM8995_WRITE_SEQUENCER_446 0x31BE
+#define WM8995_WRITE_SEQUENCER_447 0x31BF
+#define WM8995_WRITE_SEQUENCER_448 0x31C0
+#define WM8995_WRITE_SEQUENCER_449 0x31C1
+#define WM8995_WRITE_SEQUENCER_450 0x31C2
+#define WM8995_WRITE_SEQUENCER_451 0x31C3
+#define WM8995_WRITE_SEQUENCER_452 0x31C4
+#define WM8995_WRITE_SEQUENCER_453 0x31C5
+#define WM8995_WRITE_SEQUENCER_454 0x31C6
+#define WM8995_WRITE_SEQUENCER_455 0x31C7
+#define WM8995_WRITE_SEQUENCER_456 0x31C8
+#define WM8995_WRITE_SEQUENCER_457 0x31C9
+#define WM8995_WRITE_SEQUENCER_458 0x31CA
+#define WM8995_WRITE_SEQUENCER_459 0x31CB
+#define WM8995_WRITE_SEQUENCER_460 0x31CC
+#define WM8995_WRITE_SEQUENCER_461 0x31CD
+#define WM8995_WRITE_SEQUENCER_462 0x31CE
+#define WM8995_WRITE_SEQUENCER_463 0x31CF
+#define WM8995_WRITE_SEQUENCER_464 0x31D0
+#define WM8995_WRITE_SEQUENCER_465 0x31D1
+#define WM8995_WRITE_SEQUENCER_466 0x31D2
+#define WM8995_WRITE_SEQUENCER_467 0x31D3
+#define WM8995_WRITE_SEQUENCER_468 0x31D4
+#define WM8995_WRITE_SEQUENCER_469 0x31D5
+#define WM8995_WRITE_SEQUENCER_470 0x31D6
+#define WM8995_WRITE_SEQUENCER_471 0x31D7
+#define WM8995_WRITE_SEQUENCER_472 0x31D8
+#define WM8995_WRITE_SEQUENCER_473 0x31D9
+#define WM8995_WRITE_SEQUENCER_474 0x31DA
+#define WM8995_WRITE_SEQUENCER_475 0x31DB
+#define WM8995_WRITE_SEQUENCER_476 0x31DC
+#define WM8995_WRITE_SEQUENCER_477 0x31DD
+#define WM8995_WRITE_SEQUENCER_478 0x31DE
+#define WM8995_WRITE_SEQUENCER_479 0x31DF
+#define WM8995_WRITE_SEQUENCER_480 0x31E0
+#define WM8995_WRITE_SEQUENCER_481 0x31E1
+#define WM8995_WRITE_SEQUENCER_482 0x31E2
+#define WM8995_WRITE_SEQUENCER_483 0x31E3
+#define WM8995_WRITE_SEQUENCER_484 0x31E4
+#define WM8995_WRITE_SEQUENCER_485 0x31E5
+#define WM8995_WRITE_SEQUENCER_486 0x31E6
+#define WM8995_WRITE_SEQUENCER_487 0x31E7
+#define WM8995_WRITE_SEQUENCER_488 0x31E8
+#define WM8995_WRITE_SEQUENCER_489 0x31E9
+#define WM8995_WRITE_SEQUENCER_490 0x31EA
+#define WM8995_WRITE_SEQUENCER_491 0x31EB
+#define WM8995_WRITE_SEQUENCER_492 0x31EC
+#define WM8995_WRITE_SEQUENCER_493 0x31ED
+#define WM8995_WRITE_SEQUENCER_494 0x31EE
+#define WM8995_WRITE_SEQUENCER_495 0x31EF
+#define WM8995_WRITE_SEQUENCER_496 0x31F0
+#define WM8995_WRITE_SEQUENCER_497 0x31F1
+#define WM8995_WRITE_SEQUENCER_498 0x31F2
+#define WM8995_WRITE_SEQUENCER_499 0x31F3
+#define WM8995_WRITE_SEQUENCER_500 0x31F4
+#define WM8995_WRITE_SEQUENCER_501 0x31F5
+#define WM8995_WRITE_SEQUENCER_502 0x31F6
+#define WM8995_WRITE_SEQUENCER_503 0x31F7
+#define WM8995_WRITE_SEQUENCER_504 0x31F8
+#define WM8995_WRITE_SEQUENCER_505 0x31F9
+#define WM8995_WRITE_SEQUENCER_506 0x31FA
+#define WM8995_WRITE_SEQUENCER_507 0x31FB
+#define WM8995_WRITE_SEQUENCER_508 0x31FC
+#define WM8995_WRITE_SEQUENCER_509 0x31FD
+#define WM8995_WRITE_SEQUENCER_510 0x31FE
+#define WM8995_WRITE_SEQUENCER_511 0x31FF
+
+#define WM8995_REGISTER_COUNT 725
+#define WM8995_MAX_REGISTER 0x31FF
+
+#define WM8995_MAX_CACHED_REGISTER WM8995_MAX_REGISTER
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Software Reset
+ */
+#define WM8995_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
+#define WM8995_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
+#define WM8995_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
+
+/*
+ * R1 (0x01) - Power Management (1)
+ */
+#define WM8995_MICB2_ENA 0x0200 /* MICB2_ENA */
+#define WM8995_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
+#define WM8995_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
+#define WM8995_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
+#define WM8995_MICB1_ENA 0x0100 /* MICB1_ENA */
+#define WM8995_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
+#define WM8995_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
+#define WM8995_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
+#define WM8995_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
+#define WM8995_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
+#define WM8995_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
+#define WM8995_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
+#define WM8995_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
+#define WM8995_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
+#define WM8995_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
+#define WM8995_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
+#define WM8995_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
+#define WM8995_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
+#define WM8995_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
+#define WM8995_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
+#define WM8995_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
+#define WM8995_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
+#define WM8995_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
+#define WM8995_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
+#define WM8995_BG_ENA 0x0001 /* BG_ENA */
+#define WM8995_BG_ENA_MASK 0x0001 /* BG_ENA */
+#define WM8995_BG_ENA_SHIFT 0 /* BG_ENA */
+#define WM8995_BG_ENA_WIDTH 1 /* BG_ENA */
+
+/*
+ * R2 (0x02) - Power Management (2)
+ */
+#define WM8995_OPCLK_ENA 0x0800 /* OPCLK_ENA */
+#define WM8995_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
+#define WM8995_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
+#define WM8995_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
+#define WM8995_IN1L_ENA 0x0020 /* IN1L_ENA */
+#define WM8995_IN1L_ENA_MASK 0x0020 /* IN1L_ENA */
+#define WM8995_IN1L_ENA_SHIFT 5 /* IN1L_ENA */
+#define WM8995_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
+#define WM8995_IN1R_ENA 0x0010 /* IN1R_ENA */
+#define WM8995_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
+#define WM8995_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
+#define WM8995_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
+#define WM8995_LDO2_ENA 0x0002 /* LDO2_ENA */
+#define WM8995_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
+#define WM8995_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
+#define WM8995_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
+
+/*
+ * R3 (0x03) - Power Management (3)
+ */
+#define WM8995_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
+#define WM8995_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
+#define WM8995_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
+#define WM8995_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
+#define WM8995_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
+#define WM8995_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
+#define WM8995_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
+#define WM8995_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
+#define WM8995_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
+#define WM8995_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
+#define WM8995_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
+#define WM8995_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
+#define WM8995_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
+#define WM8995_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
+#define WM8995_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
+#define WM8995_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
+#define WM8995_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
+#define WM8995_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
+#define WM8995_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
+#define WM8995_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
+#define WM8995_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
+#define WM8995_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
+#define WM8995_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
+#define WM8995_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
+#define WM8995_DMIC3L_ENA 0x0080 /* DMIC3L_ENA */
+#define WM8995_DMIC3L_ENA_MASK 0x0080 /* DMIC3L_ENA */
+#define WM8995_DMIC3L_ENA_SHIFT 7 /* DMIC3L_ENA */
+#define WM8995_DMIC3L_ENA_WIDTH 1 /* DMIC3L_ENA */
+#define WM8995_DMIC3R_ENA 0x0040 /* DMIC3R_ENA */
+#define WM8995_DMIC3R_ENA_MASK 0x0040 /* DMIC3R_ENA */
+#define WM8995_DMIC3R_ENA_SHIFT 6 /* DMIC3R_ENA */
+#define WM8995_DMIC3R_ENA_WIDTH 1 /* DMIC3R_ENA */
+#define WM8995_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
+#define WM8995_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
+#define WM8995_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
+#define WM8995_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
+#define WM8995_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
+#define WM8995_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
+#define WM8995_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
+#define WM8995_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
+#define WM8995_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
+#define WM8995_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
+#define WM8995_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
+#define WM8995_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
+#define WM8995_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
+#define WM8995_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
+#define WM8995_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
+#define WM8995_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
+#define WM8995_ADCL_ENA 0x0002 /* ADCL_ENA */
+#define WM8995_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
+#define WM8995_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
+#define WM8995_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
+#define WM8995_ADCR_ENA 0x0001 /* ADCR_ENA */
+#define WM8995_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
+#define WM8995_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
+#define WM8995_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
+
+/*
+ * R4 (0x04) - Power Management (4)
+ */
+#define WM8995_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
+#define WM8995_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
+#define WM8995_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
+#define WM8995_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
+#define WM8995_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
+#define WM8995_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
+#define WM8995_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
+#define WM8995_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
+#define WM8995_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
+#define WM8995_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
+#define WM8995_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
+#define WM8995_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
+#define WM8995_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
+#define WM8995_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
+#define WM8995_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
+#define WM8995_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
+#define WM8995_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
+#define WM8995_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
+#define WM8995_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
+#define WM8995_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
+#define WM8995_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
+#define WM8995_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
+#define WM8995_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
+#define WM8995_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
+#define WM8995_DAC2L_ENA 0x0008 /* DAC2L_ENA */
+#define WM8995_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
+#define WM8995_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
+#define WM8995_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
+#define WM8995_DAC2R_ENA 0x0004 /* DAC2R_ENA */
+#define WM8995_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
+#define WM8995_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
+#define WM8995_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
+#define WM8995_DAC1L_ENA 0x0002 /* DAC1L_ENA */
+#define WM8995_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
+#define WM8995_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
+#define WM8995_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
+#define WM8995_DAC1R_ENA 0x0001 /* DAC1R_ENA */
+#define WM8995_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
+#define WM8995_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
+#define WM8995_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
+
+/*
+ * R5 (0x05) - Power Management (5)
+ */
+#define WM8995_DMIC_SRC2_MASK 0x0300 /* DMIC_SRC2 - [9:8] */
+#define WM8995_DMIC_SRC2_SHIFT 8 /* DMIC_SRC2 - [9:8] */
+#define WM8995_DMIC_SRC2_WIDTH 2 /* DMIC_SRC2 - [9:8] */
+#define WM8995_DMIC_SRC1_MASK 0x00C0 /* DMIC_SRC1 - [7:6] */
+#define WM8995_DMIC_SRC1_SHIFT 6 /* DMIC_SRC1 - [7:6] */
+#define WM8995_DMIC_SRC1_WIDTH 2 /* DMIC_SRC1 - [7:6] */
+#define WM8995_AIF3_TRI 0x0020 /* AIF3_TRI */
+#define WM8995_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
+#define WM8995_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
+#define WM8995_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
+#define WM8995_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8995_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8995_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8995_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8995_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8995_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
+#define WM8995_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
+#define WM8995_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8995_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8995_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
+#define WM8995_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
+#define WM8995_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8995_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8995_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
+#define WM8995_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
+
+/*
+ * R16 (0x10) - Left Line Input 1 Volume
+ */
+#define WM8995_IN1_VU 0x0080 /* IN1_VU */
+#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
+#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
+#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8995_IN1L_ZC 0x0020 /* IN1L_ZC */
+#define WM8995_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
+#define WM8995_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
+#define WM8995_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
+#define WM8995_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
+#define WM8995_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
+#define WM8995_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
+
+/*
+ * R17 (0x11) - Right Line Input 1 Volume
+ */
+#define WM8995_IN1_VU 0x0080 /* IN1_VU */
+#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
+#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
+#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8995_IN1R_ZC 0x0020 /* IN1R_ZC */
+#define WM8995_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
+#define WM8995_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
+#define WM8995_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
+#define WM8995_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
+#define WM8995_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
+#define WM8995_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
+
+/*
+ * R18 (0x12) - Left Line Input Control
+ */
+#define WM8995_IN1L_BOOST_MASK 0x0030 /* IN1L_BOOST - [5:4] */
+#define WM8995_IN1L_BOOST_SHIFT 4 /* IN1L_BOOST - [5:4] */
+#define WM8995_IN1L_BOOST_WIDTH 2 /* IN1L_BOOST - [5:4] */
+#define WM8995_IN1L_MODE_MASK 0x000C /* IN1L_MODE - [3:2] */
+#define WM8995_IN1L_MODE_SHIFT 2 /* IN1L_MODE - [3:2] */
+#define WM8995_IN1L_MODE_WIDTH 2 /* IN1L_MODE - [3:2] */
+#define WM8995_IN1R_MODE_MASK 0x0003 /* IN1R_MODE - [1:0] */
+#define WM8995_IN1R_MODE_SHIFT 0 /* IN1R_MODE - [1:0] */
+#define WM8995_IN1R_MODE_WIDTH 2 /* IN1R_MODE - [1:0] */
+
+/*
+ * R24 (0x18) - DAC1 Left Volume
+ */
+#define WM8995_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
+#define WM8995_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
+#define WM8995_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
+#define WM8995_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
+#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8995_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
+#define WM8995_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
+#define WM8995_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
+
+/*
+ * R25 (0x19) - DAC1 Right Volume
+ */
+#define WM8995_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
+#define WM8995_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
+#define WM8995_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
+#define WM8995_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
+#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8995_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
+#define WM8995_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
+#define WM8995_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
+
+/*
+ * R26 (0x1A) - DAC2 Left Volume
+ */
+#define WM8995_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
+#define WM8995_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
+#define WM8995_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
+#define WM8995_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
+#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8995_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
+#define WM8995_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
+#define WM8995_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
+
+/*
+ * R27 (0x1B) - DAC2 Right Volume
+ */
+#define WM8995_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
+#define WM8995_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
+#define WM8995_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
+#define WM8995_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
+#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8995_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
+#define WM8995_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
+#define WM8995_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
+
+/*
+ * R28 (0x1C) - Output Volume ZC (1)
+ */
+#define WM8995_HPOUT2L_ZC 0x0008 /* HPOUT2L_ZC */
+#define WM8995_HPOUT2L_ZC_MASK 0x0008 /* HPOUT2L_ZC */
+#define WM8995_HPOUT2L_ZC_SHIFT 3 /* HPOUT2L_ZC */
+#define WM8995_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
+#define WM8995_HPOUT2R_ZC 0x0004 /* HPOUT2R_ZC */
+#define WM8995_HPOUT2R_ZC_MASK 0x0004 /* HPOUT2R_ZC */
+#define WM8995_HPOUT2R_ZC_SHIFT 2 /* HPOUT2R_ZC */
+#define WM8995_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
+#define WM8995_HPOUT1L_ZC 0x0002 /* HPOUT1L_ZC */
+#define WM8995_HPOUT1L_ZC_MASK 0x0002 /* HPOUT1L_ZC */
+#define WM8995_HPOUT1L_ZC_SHIFT 1 /* HPOUT1L_ZC */
+#define WM8995_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
+#define WM8995_HPOUT1R_ZC 0x0001 /* HPOUT1R_ZC */
+#define WM8995_HPOUT1R_ZC_MASK 0x0001 /* HPOUT1R_ZC */
+#define WM8995_HPOUT1R_ZC_SHIFT 0 /* HPOUT1R_ZC */
+#define WM8995_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
+
+/*
+ * R32 (0x20) - MICBIAS (1)
+ */
+#define WM8995_MICB1_MODE 0x0008 /* MICB1_MODE */
+#define WM8995_MICB1_MODE_MASK 0x0008 /* MICB1_MODE */
+#define WM8995_MICB1_MODE_SHIFT 3 /* MICB1_MODE */
+#define WM8995_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
+#define WM8995_MICB1_LVL_MASK 0x0006 /* MICB1_LVL - [2:1] */
+#define WM8995_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [2:1] */
+#define WM8995_MICB1_LVL_WIDTH 2 /* MICB1_LVL - [2:1] */
+#define WM8995_MICB1_DISCH 0x0001 /* MICB1_DISCH */
+#define WM8995_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
+#define WM8995_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
+#define WM8995_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
+
+/*
+ * R33 (0x21) - MICBIAS (2)
+ */
+#define WM8995_MICB2_MODE 0x0008 /* MICB2_MODE */
+#define WM8995_MICB2_MODE_MASK 0x0008 /* MICB2_MODE */
+#define WM8995_MICB2_MODE_SHIFT 3 /* MICB2_MODE */
+#define WM8995_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
+#define WM8995_MICB2_LVL_MASK 0x0006 /* MICB2_LVL - [2:1] */
+#define WM8995_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [2:1] */
+#define WM8995_MICB2_LVL_WIDTH 2 /* MICB2_LVL - [2:1] */
+#define WM8995_MICB2_DISCH 0x0001 /* MICB2_DISCH */
+#define WM8995_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
+#define WM8995_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
+#define WM8995_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
+
+/*
+ * R40 (0x28) - LDO 1
+ */
+#define WM8995_LDO1_MODE 0x0020 /* LDO1_MODE */
+#define WM8995_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
+#define WM8995_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
+#define WM8995_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
+#define WM8995_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
+#define WM8995_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
+#define WM8995_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
+#define WM8995_LDO1_DISCH 0x0001 /* LDO1_DISCH */
+#define WM8995_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
+#define WM8995_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
+#define WM8995_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
+
+/*
+ * R41 (0x29) - LDO 2
+ */
+#define WM8995_LDO2_MODE 0x0020 /* LDO2_MODE */
+#define WM8995_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
+#define WM8995_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
+#define WM8995_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
+#define WM8995_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
+#define WM8995_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
+#define WM8995_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
+#define WM8995_LDO2_DISCH 0x0001 /* LDO2_DISCH */
+#define WM8995_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
+#define WM8995_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
+#define WM8995_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
+
+/*
+ * R48 (0x30) - Accessory Detect Mode1
+ */
+#define WM8995_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
+#define WM8995_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
+#define WM8995_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
+
+/*
+ * R49 (0x31) - Accessory Detect Mode2
+ */
+#define WM8995_VID_ENA 0x0001 /* VID_ENA */
+#define WM8995_VID_ENA_MASK 0x0001 /* VID_ENA */
+#define WM8995_VID_ENA_SHIFT 0 /* VID_ENA */
+#define WM8995_VID_ENA_WIDTH 1 /* VID_ENA */
+
+/*
+ * R52 (0x34) - Headphone Detect1
+ */
+#define WM8995_HP_RAMPRATE 0x0002 /* HP_RAMPRATE */
+#define WM8995_HP_RAMPRATE_MASK 0x0002 /* HP_RAMPRATE */
+#define WM8995_HP_RAMPRATE_SHIFT 1 /* HP_RAMPRATE */
+#define WM8995_HP_RAMPRATE_WIDTH 1 /* HP_RAMPRATE */
+#define WM8995_HP_POLL 0x0001 /* HP_POLL */
+#define WM8995_HP_POLL_MASK 0x0001 /* HP_POLL */
+#define WM8995_HP_POLL_SHIFT 0 /* HP_POLL */
+#define WM8995_HP_POLL_WIDTH 1 /* HP_POLL */
+
+/*
+ * R53 (0x35) - Headphone Detect2
+ */
+#define WM8995_HP_DONE 0x0080 /* HP_DONE */
+#define WM8995_HP_DONE_MASK 0x0080 /* HP_DONE */
+#define WM8995_HP_DONE_SHIFT 7 /* HP_DONE */
+#define WM8995_HP_DONE_WIDTH 1 /* HP_DONE */
+#define WM8995_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
+#define WM8995_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
+#define WM8995_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
+
+/*
+ * R56 (0x38) - Mic Detect (1)
+ */
+#define WM8995_MICD_RATE_MASK 0x7800 /* MICD_RATE - [14:11] */
+#define WM8995_MICD_RATE_SHIFT 11 /* MICD_RATE - [14:11] */
+#define WM8995_MICD_RATE_WIDTH 4 /* MICD_RATE - [14:11] */
+#define WM8995_MICD_LVL_SEL_MASK 0x01F8 /* MICD_LVL_SEL - [8:3] */
+#define WM8995_MICD_LVL_SEL_SHIFT 3 /* MICD_LVL_SEL - [8:3] */
+#define WM8995_MICD_LVL_SEL_WIDTH 6 /* MICD_LVL_SEL - [8:3] */
+#define WM8995_MICD_DBTIME 0x0002 /* MICD_DBTIME */
+#define WM8995_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
+#define WM8995_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
+#define WM8995_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
+#define WM8995_MICD_ENA 0x0001 /* MICD_ENA */
+#define WM8995_MICD_ENA_MASK 0x0001 /* MICD_ENA */
+#define WM8995_MICD_ENA_SHIFT 0 /* MICD_ENA */
+#define WM8995_MICD_ENA_WIDTH 1 /* MICD_ENA */
+
+/*
+ * R57 (0x39) - Mic Detect (2)
+ */
+#define WM8995_MICD_LVL_MASK 0x01FC /* MICD_LVL - [8:2] */
+#define WM8995_MICD_LVL_SHIFT 2 /* MICD_LVL - [8:2] */
+#define WM8995_MICD_LVL_WIDTH 7 /* MICD_LVL - [8:2] */
+#define WM8995_MICD_VALID 0x0002 /* MICD_VALID */
+#define WM8995_MICD_VALID_MASK 0x0002 /* MICD_VALID */
+#define WM8995_MICD_VALID_SHIFT 1 /* MICD_VALID */
+#define WM8995_MICD_VALID_WIDTH 1 /* MICD_VALID */
+#define WM8995_MICD_STS 0x0001 /* MICD_STS */
+#define WM8995_MICD_STS_MASK 0x0001 /* MICD_STS */
+#define WM8995_MICD_STS_SHIFT 0 /* MICD_STS */
+#define WM8995_MICD_STS_WIDTH 1 /* MICD_STS */
+
+/*
+ * R64 (0x40) - Charge Pump (1)
+ */
+#define WM8995_CP_ENA 0x8000 /* CP_ENA */
+#define WM8995_CP_ENA_MASK 0x8000 /* CP_ENA */
+#define WM8995_CP_ENA_SHIFT 15 /* CP_ENA */
+#define WM8995_CP_ENA_WIDTH 1 /* CP_ENA */
+
+/*
+ * R69 (0x45) - Class W (1)
+ */
+#define WM8995_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8995_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8995_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8995_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
+#define WM8995_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
+#define WM8995_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
+#define WM8995_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
+
+/*
+ * R80 (0x50) - DC Servo (1)
+ */
+#define WM8995_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
+#define WM8995_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
+#define WM8995_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
+#define WM8995_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
+#define WM8995_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
+#define WM8995_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
+#define WM8995_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
+#define WM8995_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
+#define WM8995_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8995_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8995_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
+#define WM8995_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
+#define WM8995_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8995_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8995_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
+#define WM8995_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
+
+/*
+ * R81 (0x51) - DC Servo (2)
+ */
+#define WM8995_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
+#define WM8995_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
+#define WM8995_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
+#define WM8995_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
+#define WM8995_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
+#define WM8995_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
+#define WM8995_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
+#define WM8995_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
+#define WM8995_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8995_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8995_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
+#define WM8995_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
+#define WM8995_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8995_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8995_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
+#define WM8995_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
+#define WM8995_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
+#define WM8995_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
+#define WM8995_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
+#define WM8995_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
+#define WM8995_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
+#define WM8995_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
+#define WM8995_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
+#define WM8995_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
+#define WM8995_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8995_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8995_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
+#define WM8995_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
+#define WM8995_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8995_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8995_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
+#define WM8995_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
+#define WM8995_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
+#define WM8995_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
+#define WM8995_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
+#define WM8995_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
+#define WM8995_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
+#define WM8995_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
+#define WM8995_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
+#define WM8995_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
+#define WM8995_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8995_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8995_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
+#define WM8995_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
+#define WM8995_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8995_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8995_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
+#define WM8995_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
+#define WM8995_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
+#define WM8995_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
+#define WM8995_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
+#define WM8995_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
+#define WM8995_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
+#define WM8995_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
+#define WM8995_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
+#define WM8995_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
+#define WM8995_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
+#define WM8995_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
+#define WM8995_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8995_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8995_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
+#define WM8995_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
+#define WM8995_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
+#define WM8995_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
+
+/*
+ * R82 (0x52) - DC Servo (3)
+ */
+#define WM8995_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8995_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8995_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8995_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8995_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8995_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
+
+/*
+ * R84 (0x54) - DC Servo (5)
+ */
+#define WM8995_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8995_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8995_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8995_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
+#define WM8995_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
+#define WM8995_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
+
+/*
+ * R85 (0x55) - DC Servo (6)
+ */
+#define WM8995_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
+#define WM8995_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
+#define WM8995_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
+
+/*
+ * R86 (0x56) - DC Servo (7)
+ */
+#define WM8995_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8995_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8995_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8995_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
+
+/*
+ * R87 (0x57) - DC Servo Readback 0
+ */
+#define WM8995_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8995_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8995_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8995_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8995_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8995_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8995_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
+#define WM8995_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
+#define WM8995_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
+
+/*
+ * R96 (0x60) - Analogue HP (1)
+ */
+#define WM8995_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8995_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8995_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
+#define WM8995_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
+#define WM8995_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
+#define WM8995_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
+#define WM8995_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
+#define WM8995_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
+#define WM8995_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
+#define WM8995_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
+#define WM8995_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
+#define WM8995_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
+#define WM8995_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8995_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8995_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
+#define WM8995_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
+#define WM8995_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
+#define WM8995_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
+#define WM8995_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
+#define WM8995_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
+#define WM8995_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
+#define WM8995_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
+#define WM8995_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
+#define WM8995_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
+
+/*
+ * R97 (0x61) - Analogue HP (2)
+ */
+#define WM8995_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
+#define WM8995_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
+#define WM8995_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
+#define WM8995_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
+#define WM8995_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
+#define WM8995_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
+#define WM8995_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
+#define WM8995_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
+#define WM8995_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
+#define WM8995_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
+#define WM8995_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
+#define WM8995_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
+#define WM8995_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
+#define WM8995_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
+#define WM8995_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
+#define WM8995_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
+#define WM8995_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
+#define WM8995_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
+#define WM8995_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
+#define WM8995_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
+#define WM8995_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
+#define WM8995_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
+#define WM8995_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
+#define WM8995_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
+
+/*
+ * R256 (0x100) - Chip Revision
+ */
+#define WM8995_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
+#define WM8995_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
+#define WM8995_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
+
+/*
+ * R257 (0x101) - Control Interface (1)
+ */
+#define WM8995_REG_SYNC 0x8000 /* REG_SYNC */
+#define WM8995_REG_SYNC_MASK 0x8000 /* REG_SYNC */
+#define WM8995_REG_SYNC_SHIFT 15 /* REG_SYNC */
+#define WM8995_REG_SYNC_WIDTH 1 /* REG_SYNC */
+#define WM8995_SPI_CONTRD 0x0040 /* SPI_CONTRD */
+#define WM8995_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
+#define WM8995_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
+#define WM8995_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
+#define WM8995_SPI_4WIRE 0x0020 /* SPI_4WIRE */
+#define WM8995_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
+#define WM8995_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
+#define WM8995_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
+#define WM8995_SPI_CFG 0x0010 /* SPI_CFG */
+#define WM8995_SPI_CFG_MASK 0x0010 /* SPI_CFG */
+#define WM8995_SPI_CFG_SHIFT 4 /* SPI_CFG */
+#define WM8995_SPI_CFG_WIDTH 1 /* SPI_CFG */
+#define WM8995_AUTO_INC 0x0004 /* AUTO_INC */
+#define WM8995_AUTO_INC_MASK 0x0004 /* AUTO_INC */
+#define WM8995_AUTO_INC_SHIFT 2 /* AUTO_INC */
+#define WM8995_AUTO_INC_WIDTH 1 /* AUTO_INC */
+
+/*
+ * R258 (0x102) - Control Interface (2)
+ */
+#define WM8995_CTRL_IF_SRC 0x0001 /* CTRL_IF_SRC */
+#define WM8995_CTRL_IF_SRC_MASK 0x0001 /* CTRL_IF_SRC */
+#define WM8995_CTRL_IF_SRC_SHIFT 0 /* CTRL_IF_SRC */
+#define WM8995_CTRL_IF_SRC_WIDTH 1 /* CTRL_IF_SRC */
+
+/*
+ * R272 (0x110) - Write Sequencer Ctrl (1)
+ */
+#define WM8995_WSEQ_ENA 0x8000 /* WSEQ_ENA */
+#define WM8995_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
+#define WM8995_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
+#define WM8995_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
+#define WM8995_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
+#define WM8995_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
+#define WM8995_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
+#define WM8995_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
+#define WM8995_WSEQ_START 0x0100 /* WSEQ_START */
+#define WM8995_WSEQ_START_MASK 0x0100 /* WSEQ_START */
+#define WM8995_WSEQ_START_SHIFT 8 /* WSEQ_START */
+#define WM8995_WSEQ_START_WIDTH 1 /* WSEQ_START */
+#define WM8995_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
+#define WM8995_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
+#define WM8995_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
+
+/*
+ * R273 (0x111) - Write Sequencer Ctrl (2)
+ */
+#define WM8995_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
+#define WM8995_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
+#define WM8995_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
+#define WM8995_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
+#define WM8995_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8995_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8995_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
+
+/*
+ * R512 (0x200) - AIF1 Clocking (1)
+ */
+#define WM8995_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
+#define WM8995_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
+#define WM8995_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
+#define WM8995_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
+#define WM8995_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
+#define WM8995_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
+#define WM8995_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
+#define WM8995_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
+#define WM8995_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
+#define WM8995_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
+#define WM8995_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
+#define WM8995_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
+#define WM8995_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
+#define WM8995_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
+#define WM8995_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
+
+/*
+ * R513 (0x201) - AIF1 Clocking (2)
+ */
+#define WM8995_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
+#define WM8995_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8995_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8995_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
+#define WM8995_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
+#define WM8995_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
+
+/*
+ * R516 (0x204) - AIF2 Clocking (1)
+ */
+#define WM8995_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
+#define WM8995_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
+#define WM8995_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
+#define WM8995_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
+#define WM8995_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
+#define WM8995_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
+#define WM8995_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
+#define WM8995_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
+#define WM8995_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
+#define WM8995_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
+#define WM8995_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
+#define WM8995_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
+#define WM8995_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
+#define WM8995_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
+#define WM8995_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
+
+/*
+ * R517 (0x205) - AIF2 Clocking (2)
+ */
+#define WM8995_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
+#define WM8995_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8995_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8995_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
+#define WM8995_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
+#define WM8995_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
+
+/*
+ * R520 (0x208) - Clocking (1)
+ */
+#define WM8995_LFCLK_ENA 0x0020 /* LFCLK_ENA */
+#define WM8995_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
+#define WM8995_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
+#define WM8995_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
+#define WM8995_TOCLK_ENA 0x0010 /* TOCLK_ENA */
+#define WM8995_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
+#define WM8995_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
+#define WM8995_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
+#define WM8995_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
+#define WM8995_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
+#define WM8995_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
+#define WM8995_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
+#define WM8995_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
+#define WM8995_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
+#define WM8995_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
+#define WM8995_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
+#define WM8995_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
+#define WM8995_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
+#define WM8995_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
+#define WM8995_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
+#define WM8995_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
+#define WM8995_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
+#define WM8995_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
+#define WM8995_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
+
+/*
+ * R521 (0x209) - Clocking (2)
+ */
+#define WM8995_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
+#define WM8995_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
+#define WM8995_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
+#define WM8995_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
+#define WM8995_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
+#define WM8995_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
+#define WM8995_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
+#define WM8995_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
+#define WM8995_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
+
+/*
+ * R528 (0x210) - AIF1 Rate
+ */
+#define WM8995_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
+#define WM8995_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
+#define WM8995_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
+#define WM8995_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
+#define WM8995_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
+#define WM8995_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
+
+/*
+ * R529 (0x211) - AIF2 Rate
+ */
+#define WM8995_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
+#define WM8995_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
+#define WM8995_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
+#define WM8995_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
+#define WM8995_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
+#define WM8995_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
+
+/*
+ * R530 (0x212) - Rate Status
+ */
+#define WM8995_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
+#define WM8995_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
+#define WM8995_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
+
+/*
+ * R544 (0x220) - FLL1 Control (1)
+ */
+#define WM8995_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
+#define WM8995_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
+#define WM8995_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
+#define WM8995_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
+#define WM8995_FLL1_ENA 0x0001 /* FLL1_ENA */
+#define WM8995_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
+#define WM8995_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
+#define WM8995_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
+
+/*
+ * R545 (0x221) - FLL1 Control (2)
+ */
+#define WM8995_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
+#define WM8995_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
+#define WM8995_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
+#define WM8995_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8995_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8995_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8995_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
+#define WM8995_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
+#define WM8995_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
+
+/*
+ * R546 (0x222) - FLL1 Control (3)
+ */
+#define WM8995_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
+#define WM8995_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
+#define WM8995_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
+
+/*
+ * R547 (0x223) - FLL1 Control (4)
+ */
+#define WM8995_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
+#define WM8995_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
+#define WM8995_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
+#define WM8995_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
+#define WM8995_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
+#define WM8995_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
+
+/*
+ * R548 (0x224) - FLL1 Control (5)
+ */
+#define WM8995_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
+#define WM8995_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
+#define WM8995_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
+#define WM8995_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
+#define WM8995_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8995_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8995_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8995_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
+#define WM8995_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
+#define WM8995_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
+
+/*
+ * R576 (0x240) - FLL2 Control (1)
+ */
+#define WM8995_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
+#define WM8995_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
+#define WM8995_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
+#define WM8995_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
+#define WM8995_FLL2_ENA 0x0001 /* FLL2_ENA */
+#define WM8995_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
+#define WM8995_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
+#define WM8995_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
+
+/*
+ * R577 (0x241) - FLL2 Control (2)
+ */
+#define WM8995_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
+#define WM8995_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
+#define WM8995_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
+#define WM8995_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8995_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8995_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8995_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
+#define WM8995_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
+#define WM8995_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
+
+/*
+ * R578 (0x242) - FLL2 Control (3)
+ */
+#define WM8995_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
+#define WM8995_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
+#define WM8995_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
+
+/*
+ * R579 (0x243) - FLL2 Control (4)
+ */
+#define WM8995_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
+#define WM8995_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
+#define WM8995_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
+#define WM8995_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
+#define WM8995_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
+#define WM8995_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
+
+/*
+ * R580 (0x244) - FLL2 Control (5)
+ */
+#define WM8995_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8995_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
+#define WM8995_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
+#define WM8995_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
+#define WM8995_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
+#define WM8995_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8995_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8995_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8995_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
+#define WM8995_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
+#define WM8995_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
+
+/*
+ * R768 (0x300) - AIF1 Control (1)
+ */
+#define WM8995_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
+#define WM8995_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
+#define WM8995_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
+#define WM8995_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
+#define WM8995_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
+#define WM8995_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
+#define WM8995_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
+#define WM8995_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
+#define WM8995_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
+#define WM8995_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
+#define WM8995_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
+#define WM8995_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
+#define WM8995_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
+#define WM8995_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
+#define WM8995_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
+#define WM8995_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
+#define WM8995_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
+#define WM8995_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
+#define WM8995_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
+#define WM8995_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
+#define WM8995_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
+#define WM8995_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
+#define WM8995_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
+#define WM8995_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
+#define WM8995_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
+#define WM8995_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
+
+/*
+ * R769 (0x301) - AIF1 Control (2)
+ */
+#define WM8995_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
+#define WM8995_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
+#define WM8995_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
+#define WM8995_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
+#define WM8995_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
+#define WM8995_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
+#define WM8995_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
+#define WM8995_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
+#define WM8995_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
+#define WM8995_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
+#define WM8995_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
+#define WM8995_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
+#define WM8995_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
+#define WM8995_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
+#define WM8995_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
+#define WM8995_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8995_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8995_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
+#define WM8995_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
+#define WM8995_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
+#define WM8995_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
+#define WM8995_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
+#define WM8995_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
+#define WM8995_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8995_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8995_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
+#define WM8995_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
+#define WM8995_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
+#define WM8995_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
+#define WM8995_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
+#define WM8995_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
+
+/*
+ * R770 (0x302) - AIF1 Master/Slave
+ */
+#define WM8995_AIF1_TRI 0x8000 /* AIF1_TRI */
+#define WM8995_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
+#define WM8995_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
+#define WM8995_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
+#define WM8995_AIF1_MSTR 0x4000 /* AIF1_MSTR */
+#define WM8995_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
+#define WM8995_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
+#define WM8995_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
+#define WM8995_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
+#define WM8995_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
+#define WM8995_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
+#define WM8995_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
+#define WM8995_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8995_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8995_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
+#define WM8995_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
+
+/*
+ * R771 (0x303) - AIF1 BCLK
+ */
+#define WM8995_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */
+#define WM8995_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */
+#define WM8995_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */
+
+/*
+ * R772 (0x304) - AIF1ADC LRCLK
+ */
+#define WM8995_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8995_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8995_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
+#define WM8995_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
+#define WM8995_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
+#define WM8995_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
+#define WM8995_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
+
+/*
+ * R773 (0x305) - AIF1DAC LRCLK
+ */
+#define WM8995_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8995_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8995_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
+#define WM8995_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
+#define WM8995_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
+#define WM8995_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
+#define WM8995_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
+
+/*
+ * R774 (0x306) - AIF1DAC Data
+ */
+#define WM8995_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8995_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8995_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
+#define WM8995_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
+#define WM8995_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8995_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8995_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
+#define WM8995_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
+
+/*
+ * R775 (0x307) - AIF1ADC Data
+ */
+#define WM8995_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8995_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8995_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
+#define WM8995_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
+#define WM8995_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8995_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8995_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
+#define WM8995_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
+
+/*
+ * R784 (0x310) - AIF2 Control (1)
+ */
+#define WM8995_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
+#define WM8995_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
+#define WM8995_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
+#define WM8995_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
+#define WM8995_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
+#define WM8995_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
+#define WM8995_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
+#define WM8995_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
+#define WM8995_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
+#define WM8995_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
+#define WM8995_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
+#define WM8995_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
+#define WM8995_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8995_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8995_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
+#define WM8995_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
+#define WM8995_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
+#define WM8995_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
+#define WM8995_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
+#define WM8995_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
+#define WM8995_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
+#define WM8995_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
+#define WM8995_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
+#define WM8995_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
+#define WM8995_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
+#define WM8995_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
+#define WM8995_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
+#define WM8995_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
+#define WM8995_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
+#define WM8995_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
+
+/*
+ * R785 (0x311) - AIF2 Control (2)
+ */
+#define WM8995_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
+#define WM8995_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
+#define WM8995_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
+#define WM8995_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
+#define WM8995_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
+#define WM8995_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
+#define WM8995_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
+#define WM8995_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
+#define WM8995_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
+#define WM8995_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
+#define WM8995_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
+#define WM8995_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
+#define WM8995_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8995_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8995_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
+#define WM8995_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
+#define WM8995_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
+#define WM8995_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
+#define WM8995_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
+#define WM8995_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
+#define WM8995_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
+#define WM8995_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
+#define WM8995_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
+#define WM8995_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8995_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8995_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
+#define WM8995_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
+#define WM8995_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
+#define WM8995_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
+#define WM8995_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
+#define WM8995_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
+#define WM8995_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8995_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8995_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
+#define WM8995_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
+#define WM8995_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
+#define WM8995_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
+#define WM8995_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
+#define WM8995_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
+
+/*
+ * R786 (0x312) - AIF2 Master/Slave
+ */
+#define WM8995_AIF2_TRI 0x8000 /* AIF2_TRI */
+#define WM8995_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
+#define WM8995_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
+#define WM8995_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
+#define WM8995_AIF2_MSTR 0x4000 /* AIF2_MSTR */
+#define WM8995_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
+#define WM8995_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
+#define WM8995_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
+#define WM8995_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
+#define WM8995_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
+#define WM8995_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
+#define WM8995_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
+#define WM8995_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8995_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8995_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
+#define WM8995_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
+
+/*
+ * R787 (0x313) - AIF2 BCLK
+ */
+#define WM8995_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */
+#define WM8995_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */
+#define WM8995_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */
+
+/*
+ * R788 (0x314) - AIF2ADC LRCLK
+ */
+#define WM8995_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8995_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8995_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
+#define WM8995_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
+#define WM8995_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
+#define WM8995_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
+#define WM8995_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
+
+/*
+ * R789 (0x315) - AIF2DAC LRCLK
+ */
+#define WM8995_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8995_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8995_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
+#define WM8995_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
+#define WM8995_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
+#define WM8995_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
+#define WM8995_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
+
+/*
+ * R790 (0x316) - AIF2DAC Data
+ */
+#define WM8995_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8995_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8995_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
+#define WM8995_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
+#define WM8995_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8995_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8995_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
+#define WM8995_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
+
+/*
+ * R791 (0x317) - AIF2ADC Data
+ */
+#define WM8995_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8995_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8995_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
+#define WM8995_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
+#define WM8995_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8995_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8995_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
+#define WM8995_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
+
+/*
+ * R1024 (0x400) - AIF1 ADC1 Left Volume
+ */
+#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
+#define WM8995_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
+#define WM8995_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
+
+/*
+ * R1025 (0x401) - AIF1 ADC1 Right Volume
+ */
+#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8995_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
+#define WM8995_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
+#define WM8995_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
+
+/*
+ * R1026 (0x402) - AIF1 DAC1 Left Volume
+ */
+#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
+#define WM8995_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
+#define WM8995_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
+
+/*
+ * R1027 (0x403) - AIF1 DAC1 Right Volume
+ */
+#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8995_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
+#define WM8995_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
+#define WM8995_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
+
+/*
+ * R1028 (0x404) - AIF1 ADC2 Left Volume
+ */
+#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
+#define WM8995_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
+#define WM8995_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
+
+/*
+ * R1029 (0x405) - AIF1 ADC2 Right Volume
+ */
+#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8995_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
+#define WM8995_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
+#define WM8995_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
+
+/*
+ * R1030 (0x406) - AIF1 DAC2 Left Volume
+ */
+#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
+#define WM8995_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
+#define WM8995_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
+
+/*
+ * R1031 (0x407) - AIF1 DAC2 Right Volume
+ */
+#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8995_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
+#define WM8995_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
+#define WM8995_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
+
+/*
+ * R1040 (0x410) - AIF1 ADC1 Filters
+ */
+#define WM8995_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
+#define WM8995_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
+#define WM8995_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
+#define WM8995_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
+#define WM8995_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
+#define WM8995_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
+#define WM8995_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
+#define WM8995_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
+#define WM8995_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
+#define WM8995_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
+#define WM8995_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
+#define WM8995_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
+#define WM8995_AIF1ADC1_HPF_MODE 0x0008 /* AIF1ADC1_HPF_MODE */
+#define WM8995_AIF1ADC1_HPF_MODE_MASK 0x0008 /* AIF1ADC1_HPF_MODE */
+#define WM8995_AIF1ADC1_HPF_MODE_SHIFT 3 /* AIF1ADC1_HPF_MODE */
+#define WM8995_AIF1ADC1_HPF_MODE_WIDTH 1 /* AIF1ADC1_HPF_MODE */
+#define WM8995_AIF1ADC1_HPF_CUT_MASK 0x0007 /* AIF1ADC1_HPF_CUT - [2:0] */
+#define WM8995_AIF1ADC1_HPF_CUT_SHIFT 0 /* AIF1ADC1_HPF_CUT - [2:0] */
+#define WM8995_AIF1ADC1_HPF_CUT_WIDTH 3 /* AIF1ADC1_HPF_CUT - [2:0] */
+
+/*
+ * R1041 (0x411) - AIF1 ADC2 Filters
+ */
+#define WM8995_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
+#define WM8995_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
+#define WM8995_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
+#define WM8995_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
+#define WM8995_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
+#define WM8995_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
+#define WM8995_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
+#define WM8995_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
+#define WM8995_AIF1ADC2_HPF_MODE 0x0008 /* AIF1ADC2_HPF_MODE */
+#define WM8995_AIF1ADC2_HPF_MODE_MASK 0x0008 /* AIF1ADC2_HPF_MODE */
+#define WM8995_AIF1ADC2_HPF_MODE_SHIFT 3 /* AIF1ADC2_HPF_MODE */
+#define WM8995_AIF1ADC2_HPF_MODE_WIDTH 1 /* AIF1ADC2_HPF_MODE */
+#define WM8995_AIF1ADC2_HPF_CUT_MASK 0x0007 /* AIF1ADC2_HPF_CUT - [2:0] */
+#define WM8995_AIF1ADC2_HPF_CUT_SHIFT 0 /* AIF1ADC2_HPF_CUT - [2:0] */
+#define WM8995_AIF1ADC2_HPF_CUT_WIDTH 3 /* AIF1ADC2_HPF_CUT - [2:0] */
+
+/*
+ * R1056 (0x420) - AIF1 DAC1 Filters (1)
+ */
+#define WM8995_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
+#define WM8995_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
+#define WM8995_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
+#define WM8995_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
+#define WM8995_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
+#define WM8995_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
+#define WM8995_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
+#define WM8995_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
+#define WM8995_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8995_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8995_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
+#define WM8995_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
+#define WM8995_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8995_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8995_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8995_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8995_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8995_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8995_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
+
+/*
+ * R1057 (0x421) - AIF1 DAC1 Filters (2)
+ */
+#define WM8995_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8995_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8995_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
+#define WM8995_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
+
+/*
+ * R1058 (0x422) - AIF1 DAC2 Filters (1)
+ */
+#define WM8995_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
+#define WM8995_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
+#define WM8995_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
+#define WM8995_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
+#define WM8995_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
+#define WM8995_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
+#define WM8995_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
+#define WM8995_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
+#define WM8995_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8995_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8995_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
+#define WM8995_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
+#define WM8995_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8995_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8995_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8995_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8995_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8995_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8995_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
+
+/*
+ * R1059 (0x423) - AIF1 DAC2 Filters (2)
+ */
+#define WM8995_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8995_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8995_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8995_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
+#define WM8995_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
+
+/*
+ * R1088 (0x440) - AIF1 DRC1 (1)
+ */
+#define WM8995_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8995_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8995_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
+#define WM8995_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
+#define WM8995_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8995_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8995_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8995_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8995_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8995_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8995_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
+#define WM8995_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
+#define WM8995_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
+#define WM8995_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
+#define WM8995_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
+#define WM8995_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
+#define WM8995_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8995_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8995_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
+#define WM8995_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
+#define WM8995_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8995_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8995_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
+#define WM8995_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
+#define WM8995_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8995_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8995_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8995_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8995_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8995_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8995_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
+#define WM8995_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
+
+/*
+ * R1089 (0x441) - AIF1 DRC1 (2)
+ */
+#define WM8995_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
+#define WM8995_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
+#define WM8995_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
+#define WM8995_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
+#define WM8995_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
+#define WM8995_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
+#define WM8995_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8995_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8995_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
+
+/*
+ * R1090 (0x442) - AIF1 DRC1 (3)
+ */
+#define WM8995_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8995_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8995_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8995_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8995_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8995_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
+
+/*
+ * R1091 (0x443) - AIF1 DRC1 (4)
+ */
+#define WM8995_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8995_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8995_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
+
+/*
+ * R1092 (0x444) - AIF1 DRC1 (5)
+ */
+#define WM8995_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8995_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8995_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
+
+/*
+ * R1104 (0x450) - AIF1 DRC2 (1)
+ */
+#define WM8995_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8995_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8995_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8995_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
+#define WM8995_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
+#define WM8995_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8995_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8995_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8995_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8995_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8995_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8995_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
+#define WM8995_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
+#define WM8995_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8995_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
+#define WM8995_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
+#define WM8995_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
+#define WM8995_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
+#define WM8995_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8995_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8995_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
+#define WM8995_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
+#define WM8995_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8995_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8995_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
+#define WM8995_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
+#define WM8995_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8995_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8995_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8995_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8995_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8995_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8995_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
+#define WM8995_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
+
+/*
+ * R1105 (0x451) - AIF1 DRC2 (2)
+ */
+#define WM8995_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
+#define WM8995_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
+#define WM8995_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
+#define WM8995_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
+#define WM8995_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
+#define WM8995_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
+#define WM8995_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8995_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8995_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8995_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
+
+/*
+ * R1106 (0x452) - AIF1 DRC2 (3)
+ */
+#define WM8995_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8995_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8995_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8995_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8995_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8995_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8995_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8995_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8995_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8995_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
+
+/*
+ * R1107 (0x453) - AIF1 DRC2 (4)
+ */
+#define WM8995_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8995_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8995_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8995_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
+
+/*
+ * R1108 (0x454) - AIF1 DRC2 (5)
+ */
+#define WM8995_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8995_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8995_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8995_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
+
+/*
+ * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
+ */
+#define WM8995_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8995_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8995_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
+#define WM8995_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
+
+/*
+ * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
+ */
+#define WM8995_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
+ */
+#define WM8995_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
+
+/*
+ * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
+ */
+#define WM8995_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
+
+/*
+ * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
+ */
+#define WM8995_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+
+/*
+ * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
+ */
+#define WM8995_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
+
+/*
+ * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
+ */
+#define WM8995_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
+
+/*
+ * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
+ */
+#define WM8995_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
+
+/*
+ * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
+ */
+#define WM8995_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+
+/*
+ * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
+ */
+#define WM8995_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
+
+/*
+ * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
+ */
+#define WM8995_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
+
+/*
+ * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
+ */
+#define WM8995_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
+
+/*
+ * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
+ */
+#define WM8995_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+
+/*
+ * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
+ */
+#define WM8995_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
+
+/*
+ * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
+ */
+#define WM8995_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
+
+/*
+ * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
+ */
+#define WM8995_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
+
+/*
+ * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
+ */
+#define WM8995_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+
+/*
+ * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
+ */
+#define WM8995_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
+
+/*
+ * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
+ */
+#define WM8995_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
+
+/*
+ * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
+ */
+#define WM8995_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8995_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+
+/*
+ * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
+ */
+#define WM8995_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8995_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8995_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
+#define WM8995_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
+
+/*
+ * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
+ */
+#define WM8995_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
+ */
+#define WM8995_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
+
+/*
+ * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
+ */
+#define WM8995_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
+
+/*
+ * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
+ */
+#define WM8995_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+
+/*
+ * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
+ */
+#define WM8995_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
+
+/*
+ * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
+ */
+#define WM8995_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
+
+/*
+ * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
+ */
+#define WM8995_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
+
+/*
+ * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
+ */
+#define WM8995_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+
+/*
+ * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
+ */
+#define WM8995_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
+
+/*
+ * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
+ */
+#define WM8995_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
+
+/*
+ * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
+ */
+#define WM8995_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
+
+/*
+ * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
+ */
+#define WM8995_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+
+/*
+ * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
+ */
+#define WM8995_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
+
+/*
+ * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
+ */
+#define WM8995_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
+
+/*
+ * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
+ */
+#define WM8995_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
+
+/*
+ * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
+ */
+#define WM8995_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+
+/*
+ * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
+ */
+#define WM8995_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
+
+/*
+ * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
+ */
+#define WM8995_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
+
+/*
+ * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
+ */
+#define WM8995_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8995_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+
+/*
+ * R1280 (0x500) - AIF2 ADC Left Volume
+ */
+#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8995_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
+#define WM8995_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
+#define WM8995_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
+
+/*
+ * R1281 (0x501) - AIF2 ADC Right Volume
+ */
+#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8995_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
+#define WM8995_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
+#define WM8995_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
+
+/*
+ * R1282 (0x502) - AIF2 DAC Left Volume
+ */
+#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8995_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
+#define WM8995_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
+#define WM8995_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
+
+/*
+ * R1283 (0x503) - AIF2 DAC Right Volume
+ */
+#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8995_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
+#define WM8995_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
+#define WM8995_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
+
+/*
+ * R1296 (0x510) - AIF2 ADC Filters
+ */
+#define WM8995_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
+#define WM8995_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
+#define WM8995_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
+#define WM8995_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
+#define WM8995_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
+#define WM8995_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
+#define WM8995_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
+#define WM8995_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
+#define WM8995_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
+#define WM8995_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
+#define WM8995_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
+#define WM8995_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
+#define WM8995_AIF2ADC_HPF_MODE 0x0008 /* AIF2ADC_HPF_MODE */
+#define WM8995_AIF2ADC_HPF_MODE_MASK 0x0008 /* AIF2ADC_HPF_MODE */
+#define WM8995_AIF2ADC_HPF_MODE_SHIFT 3 /* AIF2ADC_HPF_MODE */
+#define WM8995_AIF2ADC_HPF_MODE_WIDTH 1 /* AIF2ADC_HPF_MODE */
+#define WM8995_AIF2ADC_HPF_CUT_MASK 0x0007 /* AIF2ADC_HPF_CUT - [2:0] */
+#define WM8995_AIF2ADC_HPF_CUT_SHIFT 0 /* AIF2ADC_HPF_CUT - [2:0] */
+#define WM8995_AIF2ADC_HPF_CUT_WIDTH 3 /* AIF2ADC_HPF_CUT - [2:0] */
+
+/*
+ * R1312 (0x520) - AIF2 DAC Filters (1)
+ */
+#define WM8995_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
+#define WM8995_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
+#define WM8995_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
+#define WM8995_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
+#define WM8995_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
+#define WM8995_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
+#define WM8995_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
+#define WM8995_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
+#define WM8995_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8995_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8995_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
+#define WM8995_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
+#define WM8995_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8995_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8995_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8995_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8995_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8995_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8995_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
+
+/*
+ * R1313 (0x521) - AIF2 DAC Filters (2)
+ */
+#define WM8995_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8995_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8995_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8995_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8995_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8995_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
+#define WM8995_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
+
+/*
+ * R1344 (0x540) - AIF2 DRC (1)
+ */
+#define WM8995_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8995_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8995_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8995_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8995_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8995_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8995_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
+#define WM8995_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
+#define WM8995_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8995_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8995_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
+#define WM8995_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
+#define WM8995_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8995_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8995_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
+#define WM8995_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
+#define WM8995_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8995_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8995_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8995_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8995_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
+#define WM8995_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
+#define WM8995_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
+#define WM8995_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
+#define WM8995_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8995_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8995_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
+#define WM8995_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
+#define WM8995_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8995_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8995_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
+#define WM8995_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
+#define WM8995_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8995_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8995_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
+#define WM8995_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
+#define WM8995_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8995_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8995_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
+#define WM8995_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
+
+/*
+ * R1345 (0x541) - AIF2 DRC (2)
+ */
+#define WM8995_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
+#define WM8995_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
+#define WM8995_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
+#define WM8995_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
+#define WM8995_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
+#define WM8995_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
+#define WM8995_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8995_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8995_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8995_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8995_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8995_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
+
+/*
+ * R1346 (0x542) - AIF2 DRC (3)
+ */
+#define WM8995_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8995_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8995_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8995_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8995_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8995_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8995_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8995_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8995_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8995_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8995_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8995_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8995_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8995_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8995_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8995_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8995_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8995_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
+
+/*
+ * R1347 (0x543) - AIF2 DRC (4)
+ */
+#define WM8995_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8995_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8995_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8995_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8995_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8995_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
+
+/*
+ * R1348 (0x544) - AIF2 DRC (5)
+ */
+#define WM8995_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8995_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8995_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8995_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8995_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8995_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
+
+/*
+ * R1408 (0x580) - AIF2 EQ Gains (1)
+ */
+#define WM8995_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8995_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8995_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8995_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8995_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
+#define WM8995_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
+
+/*
+ * R1409 (0x581) - AIF2 EQ Gains (2)
+ */
+#define WM8995_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8995_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8995_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1410 (0x582) - AIF2 EQ Band 1 A
+ */
+#define WM8995_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
+
+/*
+ * R1411 (0x583) - AIF2 EQ Band 1 B
+ */
+#define WM8995_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
+
+/*
+ * R1412 (0x584) - AIF2 EQ Band 1 PG
+ */
+#define WM8995_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
+
+/*
+ * R1413 (0x585) - AIF2 EQ Band 2 A
+ */
+#define WM8995_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
+
+/*
+ * R1414 (0x586) - AIF2 EQ Band 2 B
+ */
+#define WM8995_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
+
+/*
+ * R1415 (0x587) - AIF2 EQ Band 2 C
+ */
+#define WM8995_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
+
+/*
+ * R1416 (0x588) - AIF2 EQ Band 2 PG
+ */
+#define WM8995_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
+
+/*
+ * R1417 (0x589) - AIF2 EQ Band 3 A
+ */
+#define WM8995_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
+
+/*
+ * R1418 (0x58A) - AIF2 EQ Band 3 B
+ */
+#define WM8995_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
+
+/*
+ * R1419 (0x58B) - AIF2 EQ Band 3 C
+ */
+#define WM8995_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
+
+/*
+ * R1420 (0x58C) - AIF2 EQ Band 3 PG
+ */
+#define WM8995_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
+
+/*
+ * R1421 (0x58D) - AIF2 EQ Band 4 A
+ */
+#define WM8995_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
+
+/*
+ * R1422 (0x58E) - AIF2 EQ Band 4 B
+ */
+#define WM8995_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
+
+/*
+ * R1423 (0x58F) - AIF2 EQ Band 4 C
+ */
+#define WM8995_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
+
+/*
+ * R1424 (0x590) - AIF2 EQ Band 4 PG
+ */
+#define WM8995_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
+
+/*
+ * R1425 (0x591) - AIF2 EQ Band 5 A
+ */
+#define WM8995_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
+
+/*
+ * R1426 (0x592) - AIF2 EQ Band 5 B
+ */
+#define WM8995_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
+
+/*
+ * R1427 (0x593) - AIF2 EQ Band 5 PG
+ */
+#define WM8995_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8995_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
+
+/*
+ * R1536 (0x600) - DAC1 Mixer Volumes
+ */
+#define WM8995_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8995_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8995_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8995_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
+#define WM8995_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
+#define WM8995_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
+
+/*
+ * R1537 (0x601) - DAC1 Left Mixer Routing
+ */
+#define WM8995_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
+#define WM8995_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
+#define WM8995_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
+#define WM8995_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
+#define WM8995_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
+#define WM8995_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
+#define WM8995_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
+#define WM8995_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
+#define WM8995_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8995_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8995_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
+#define WM8995_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
+#define WM8995_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8995_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8995_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8995_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8995_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8995_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8995_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
+#define WM8995_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
+
+/*
+ * R1538 (0x602) - DAC1 Right Mixer Routing
+ */
+#define WM8995_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
+#define WM8995_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
+#define WM8995_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
+#define WM8995_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
+#define WM8995_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
+#define WM8995_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
+#define WM8995_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
+#define WM8995_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
+#define WM8995_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8995_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8995_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
+#define WM8995_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
+#define WM8995_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8995_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8995_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8995_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8995_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8995_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8995_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
+#define WM8995_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
+
+/*
+ * R1539 (0x603) - DAC2 Mixer Volumes
+ */
+#define WM8995_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8995_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8995_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8995_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
+#define WM8995_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
+#define WM8995_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
+
+/*
+ * R1540 (0x604) - DAC2 Left Mixer Routing
+ */
+#define WM8995_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
+#define WM8995_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
+#define WM8995_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
+#define WM8995_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
+#define WM8995_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
+#define WM8995_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
+#define WM8995_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
+#define WM8995_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
+#define WM8995_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8995_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8995_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
+#define WM8995_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
+#define WM8995_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8995_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8995_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8995_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8995_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8995_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8995_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
+#define WM8995_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
+
+/*
+ * R1541 (0x605) - DAC2 Right Mixer Routing
+ */
+#define WM8995_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
+#define WM8995_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
+#define WM8995_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
+#define WM8995_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
+#define WM8995_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
+#define WM8995_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
+#define WM8995_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
+#define WM8995_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
+#define WM8995_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8995_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8995_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
+#define WM8995_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
+#define WM8995_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8995_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8995_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8995_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8995_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8995_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8995_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
+#define WM8995_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
+
+/*
+ * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
+ */
+#define WM8995_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8995_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8995_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8995_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8995_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8995_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8995_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8995_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
+
+/*
+ * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
+ */
+#define WM8995_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8995_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8995_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8995_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8995_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8995_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8995_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8995_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
+
+/*
+ * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
+ */
+#define WM8995_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8995_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8995_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8995_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8995_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8995_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8995_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8995_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
+
+/*
+ * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
+ */
+#define WM8995_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8995_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8995_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8995_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8995_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8995_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8995_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8995_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
+
+/*
+ * R1552 (0x610) - DAC Softmute
+ */
+#define WM8995_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8995_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8995_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
+#define WM8995_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
+#define WM8995_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
+#define WM8995_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
+#define WM8995_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
+#define WM8995_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
+
+/*
+ * R1568 (0x620) - Oversampling
+ */
+#define WM8995_ADC_OSR128 0x0002 /* ADC_OSR128 */
+#define WM8995_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
+#define WM8995_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
+#define WM8995_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
+#define WM8995_DAC_OSR128 0x0001 /* DAC_OSR128 */
+#define WM8995_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
+#define WM8995_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
+#define WM8995_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
+
+/*
+ * R1569 (0x621) - Sidetone
+ */
+#define WM8995_ST_LPF 0x1000 /* ST_LPF */
+#define WM8995_ST_LPF_MASK 0x1000 /* ST_LPF */
+#define WM8995_ST_LPF_SHIFT 12 /* ST_LPF */
+#define WM8995_ST_LPF_WIDTH 1 /* ST_LPF */
+#define WM8995_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
+#define WM8995_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
+#define WM8995_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
+#define WM8995_ST_HPF 0x0040 /* ST_HPF */
+#define WM8995_ST_HPF_MASK 0x0040 /* ST_HPF */
+#define WM8995_ST_HPF_SHIFT 6 /* ST_HPF */
+#define WM8995_ST_HPF_WIDTH 1 /* ST_HPF */
+#define WM8995_STR_SEL 0x0002 /* STR_SEL */
+#define WM8995_STR_SEL_MASK 0x0002 /* STR_SEL */
+#define WM8995_STR_SEL_SHIFT 1 /* STR_SEL */
+#define WM8995_STR_SEL_WIDTH 1 /* STR_SEL */
+#define WM8995_STL_SEL 0x0001 /* STL_SEL */
+#define WM8995_STL_SEL_MASK 0x0001 /* STL_SEL */
+#define WM8995_STL_SEL_SHIFT 0 /* STL_SEL */
+#define WM8995_STL_SEL_WIDTH 1 /* STL_SEL */
+
+/*
+ * R1792 (0x700) - GPIO 1
+ */
+#define WM8995_GP1_DIR 0x8000 /* GP1_DIR */
+#define WM8995_GP1_DIR_MASK 0x8000 /* GP1_DIR */
+#define WM8995_GP1_DIR_SHIFT 15 /* GP1_DIR */
+#define WM8995_GP1_DIR_WIDTH 1 /* GP1_DIR */
+#define WM8995_GP1_PU 0x4000 /* GP1_PU */
+#define WM8995_GP1_PU_MASK 0x4000 /* GP1_PU */
+#define WM8995_GP1_PU_SHIFT 14 /* GP1_PU */
+#define WM8995_GP1_PU_WIDTH 1 /* GP1_PU */
+#define WM8995_GP1_PD 0x2000 /* GP1_PD */
+#define WM8995_GP1_PD_MASK 0x2000 /* GP1_PD */
+#define WM8995_GP1_PD_SHIFT 13 /* GP1_PD */
+#define WM8995_GP1_PD_WIDTH 1 /* GP1_PD */
+#define WM8995_GP1_POL 0x0400 /* GP1_POL */
+#define WM8995_GP1_POL_MASK 0x0400 /* GP1_POL */
+#define WM8995_GP1_POL_SHIFT 10 /* GP1_POL */
+#define WM8995_GP1_POL_WIDTH 1 /* GP1_POL */
+#define WM8995_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
+#define WM8995_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
+#define WM8995_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
+#define WM8995_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
+#define WM8995_GP1_DB 0x0100 /* GP1_DB */
+#define WM8995_GP1_DB_MASK 0x0100 /* GP1_DB */
+#define WM8995_GP1_DB_SHIFT 8 /* GP1_DB */
+#define WM8995_GP1_DB_WIDTH 1 /* GP1_DB */
+#define WM8995_GP1_LVL 0x0040 /* GP1_LVL */
+#define WM8995_GP1_LVL_MASK 0x0040 /* GP1_LVL */
+#define WM8995_GP1_LVL_SHIFT 6 /* GP1_LVL */
+#define WM8995_GP1_LVL_WIDTH 1 /* GP1_LVL */
+#define WM8995_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */
+#define WM8995_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */
+#define WM8995_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */
+
+/*
+ * R1793 (0x701) - GPIO 2
+ */
+#define WM8995_GP2_DIR 0x8000 /* GP2_DIR */
+#define WM8995_GP2_DIR_MASK 0x8000 /* GP2_DIR */
+#define WM8995_GP2_DIR_SHIFT 15 /* GP2_DIR */
+#define WM8995_GP2_DIR_WIDTH 1 /* GP2_DIR */
+#define WM8995_GP2_PU 0x4000 /* GP2_PU */
+#define WM8995_GP2_PU_MASK 0x4000 /* GP2_PU */
+#define WM8995_GP2_PU_SHIFT 14 /* GP2_PU */
+#define WM8995_GP2_PU_WIDTH 1 /* GP2_PU */
+#define WM8995_GP2_PD 0x2000 /* GP2_PD */
+#define WM8995_GP2_PD_MASK 0x2000 /* GP2_PD */
+#define WM8995_GP2_PD_SHIFT 13 /* GP2_PD */
+#define WM8995_GP2_PD_WIDTH 1 /* GP2_PD */
+#define WM8995_GP2_POL 0x0400 /* GP2_POL */
+#define WM8995_GP2_POL_MASK 0x0400 /* GP2_POL */
+#define WM8995_GP2_POL_SHIFT 10 /* GP2_POL */
+#define WM8995_GP2_POL_WIDTH 1 /* GP2_POL */
+#define WM8995_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
+#define WM8995_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
+#define WM8995_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
+#define WM8995_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
+#define WM8995_GP2_DB 0x0100 /* GP2_DB */
+#define WM8995_GP2_DB_MASK 0x0100 /* GP2_DB */
+#define WM8995_GP2_DB_SHIFT 8 /* GP2_DB */
+#define WM8995_GP2_DB_WIDTH 1 /* GP2_DB */
+#define WM8995_GP2_LVL 0x0040 /* GP2_LVL */
+#define WM8995_GP2_LVL_MASK 0x0040 /* GP2_LVL */
+#define WM8995_GP2_LVL_SHIFT 6 /* GP2_LVL */
+#define WM8995_GP2_LVL_WIDTH 1 /* GP2_LVL */
+#define WM8995_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
+#define WM8995_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
+#define WM8995_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
+
+/*
+ * R1794 (0x702) - GPIO 3
+ */
+#define WM8995_GP3_DIR 0x8000 /* GP3_DIR */
+#define WM8995_GP3_DIR_MASK 0x8000 /* GP3_DIR */
+#define WM8995_GP3_DIR_SHIFT 15 /* GP3_DIR */
+#define WM8995_GP3_DIR_WIDTH 1 /* GP3_DIR */
+#define WM8995_GP3_PU 0x4000 /* GP3_PU */
+#define WM8995_GP3_PU_MASK 0x4000 /* GP3_PU */
+#define WM8995_GP3_PU_SHIFT 14 /* GP3_PU */
+#define WM8995_GP3_PU_WIDTH 1 /* GP3_PU */
+#define WM8995_GP3_PD 0x2000 /* GP3_PD */
+#define WM8995_GP3_PD_MASK 0x2000 /* GP3_PD */
+#define WM8995_GP3_PD_SHIFT 13 /* GP3_PD */
+#define WM8995_GP3_PD_WIDTH 1 /* GP3_PD */
+#define WM8995_GP3_POL 0x0400 /* GP3_POL */
+#define WM8995_GP3_POL_MASK 0x0400 /* GP3_POL */
+#define WM8995_GP3_POL_SHIFT 10 /* GP3_POL */
+#define WM8995_GP3_POL_WIDTH 1 /* GP3_POL */
+#define WM8995_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
+#define WM8995_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
+#define WM8995_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
+#define WM8995_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
+#define WM8995_GP3_DB 0x0100 /* GP3_DB */
+#define WM8995_GP3_DB_MASK 0x0100 /* GP3_DB */
+#define WM8995_GP3_DB_SHIFT 8 /* GP3_DB */
+#define WM8995_GP3_DB_WIDTH 1 /* GP3_DB */
+#define WM8995_GP3_LVL 0x0040 /* GP3_LVL */
+#define WM8995_GP3_LVL_MASK 0x0040 /* GP3_LVL */
+#define WM8995_GP3_LVL_SHIFT 6 /* GP3_LVL */
+#define WM8995_GP3_LVL_WIDTH 1 /* GP3_LVL */
+#define WM8995_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
+#define WM8995_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
+#define WM8995_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
+
+/*
+ * R1795 (0x703) - GPIO 4
+ */
+#define WM8995_GP4_DIR 0x8000 /* GP4_DIR */
+#define WM8995_GP4_DIR_MASK 0x8000 /* GP4_DIR */
+#define WM8995_GP4_DIR_SHIFT 15 /* GP4_DIR */
+#define WM8995_GP4_DIR_WIDTH 1 /* GP4_DIR */
+#define WM8995_GP4_PU 0x4000 /* GP4_PU */
+#define WM8995_GP4_PU_MASK 0x4000 /* GP4_PU */
+#define WM8995_GP4_PU_SHIFT 14 /* GP4_PU */
+#define WM8995_GP4_PU_WIDTH 1 /* GP4_PU */
+#define WM8995_GP4_PD 0x2000 /* GP4_PD */
+#define WM8995_GP4_PD_MASK 0x2000 /* GP4_PD */
+#define WM8995_GP4_PD_SHIFT 13 /* GP4_PD */
+#define WM8995_GP4_PD_WIDTH 1 /* GP4_PD */
+#define WM8995_GP4_POL 0x0400 /* GP4_POL */
+#define WM8995_GP4_POL_MASK 0x0400 /* GP4_POL */
+#define WM8995_GP4_POL_SHIFT 10 /* GP4_POL */
+#define WM8995_GP4_POL_WIDTH 1 /* GP4_POL */
+#define WM8995_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
+#define WM8995_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
+#define WM8995_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
+#define WM8995_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
+#define WM8995_GP4_DB 0x0100 /* GP4_DB */
+#define WM8995_GP4_DB_MASK 0x0100 /* GP4_DB */
+#define WM8995_GP4_DB_SHIFT 8 /* GP4_DB */
+#define WM8995_GP4_DB_WIDTH 1 /* GP4_DB */
+#define WM8995_GP4_LVL 0x0040 /* GP4_LVL */
+#define WM8995_GP4_LVL_MASK 0x0040 /* GP4_LVL */
+#define WM8995_GP4_LVL_SHIFT 6 /* GP4_LVL */
+#define WM8995_GP4_LVL_WIDTH 1 /* GP4_LVL */
+#define WM8995_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */
+#define WM8995_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */
+#define WM8995_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */
+
+/*
+ * R1796 (0x704) - GPIO 5
+ */
+#define WM8995_GP5_DIR 0x8000 /* GP5_DIR */
+#define WM8995_GP5_DIR_MASK 0x8000 /* GP5_DIR */
+#define WM8995_GP5_DIR_SHIFT 15 /* GP5_DIR */
+#define WM8995_GP5_DIR_WIDTH 1 /* GP5_DIR */
+#define WM8995_GP5_PU 0x4000 /* GP5_PU */
+#define WM8995_GP5_PU_MASK 0x4000 /* GP5_PU */
+#define WM8995_GP5_PU_SHIFT 14 /* GP5_PU */
+#define WM8995_GP5_PU_WIDTH 1 /* GP5_PU */
+#define WM8995_GP5_PD 0x2000 /* GP5_PD */
+#define WM8995_GP5_PD_MASK 0x2000 /* GP5_PD */
+#define WM8995_GP5_PD_SHIFT 13 /* GP5_PD */
+#define WM8995_GP5_PD_WIDTH 1 /* GP5_PD */
+#define WM8995_GP5_POL 0x0400 /* GP5_POL */
+#define WM8995_GP5_POL_MASK 0x0400 /* GP5_POL */
+#define WM8995_GP5_POL_SHIFT 10 /* GP5_POL */
+#define WM8995_GP5_POL_WIDTH 1 /* GP5_POL */
+#define WM8995_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
+#define WM8995_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
+#define WM8995_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
+#define WM8995_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
+#define WM8995_GP5_DB 0x0100 /* GP5_DB */
+#define WM8995_GP5_DB_MASK 0x0100 /* GP5_DB */
+#define WM8995_GP5_DB_SHIFT 8 /* GP5_DB */
+#define WM8995_GP5_DB_WIDTH 1 /* GP5_DB */
+#define WM8995_GP5_LVL 0x0040 /* GP5_LVL */
+#define WM8995_GP5_LVL_MASK 0x0040 /* GP5_LVL */
+#define WM8995_GP5_LVL_SHIFT 6 /* GP5_LVL */
+#define WM8995_GP5_LVL_WIDTH 1 /* GP5_LVL */
+#define WM8995_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
+#define WM8995_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
+#define WM8995_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
+
+/*
+ * R1797 (0x705) - GPIO 6
+ */
+#define WM8995_GP6_DIR 0x8000 /* GP6_DIR */
+#define WM8995_GP6_DIR_MASK 0x8000 /* GP6_DIR */
+#define WM8995_GP6_DIR_SHIFT 15 /* GP6_DIR */
+#define WM8995_GP6_DIR_WIDTH 1 /* GP6_DIR */
+#define WM8995_GP6_PU 0x4000 /* GP6_PU */
+#define WM8995_GP6_PU_MASK 0x4000 /* GP6_PU */
+#define WM8995_GP6_PU_SHIFT 14 /* GP6_PU */
+#define WM8995_GP6_PU_WIDTH 1 /* GP6_PU */
+#define WM8995_GP6_PD 0x2000 /* GP6_PD */
+#define WM8995_GP6_PD_MASK 0x2000 /* GP6_PD */
+#define WM8995_GP6_PD_SHIFT 13 /* GP6_PD */
+#define WM8995_GP6_PD_WIDTH 1 /* GP6_PD */
+#define WM8995_GP6_POL 0x0400 /* GP6_POL */
+#define WM8995_GP6_POL_MASK 0x0400 /* GP6_POL */
+#define WM8995_GP6_POL_SHIFT 10 /* GP6_POL */
+#define WM8995_GP6_POL_WIDTH 1 /* GP6_POL */
+#define WM8995_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
+#define WM8995_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
+#define WM8995_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
+#define WM8995_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
+#define WM8995_GP6_DB 0x0100 /* GP6_DB */
+#define WM8995_GP6_DB_MASK 0x0100 /* GP6_DB */
+#define WM8995_GP6_DB_SHIFT 8 /* GP6_DB */
+#define WM8995_GP6_DB_WIDTH 1 /* GP6_DB */
+#define WM8995_GP6_LVL 0x0040 /* GP6_LVL */
+#define WM8995_GP6_LVL_MASK 0x0040 /* GP6_LVL */
+#define WM8995_GP6_LVL_SHIFT 6 /* GP6_LVL */
+#define WM8995_GP6_LVL_WIDTH 1 /* GP6_LVL */
+#define WM8995_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
+#define WM8995_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
+#define WM8995_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
+
+/*
+ * R1798 (0x706) - GPIO 7
+ */
+#define WM8995_GP7_DIR 0x8000 /* GP7_DIR */
+#define WM8995_GP7_DIR_MASK 0x8000 /* GP7_DIR */
+#define WM8995_GP7_DIR_SHIFT 15 /* GP7_DIR */
+#define WM8995_GP7_DIR_WIDTH 1 /* GP7_DIR */
+#define WM8995_GP7_PU 0x4000 /* GP7_PU */
+#define WM8995_GP7_PU_MASK 0x4000 /* GP7_PU */
+#define WM8995_GP7_PU_SHIFT 14 /* GP7_PU */
+#define WM8995_GP7_PU_WIDTH 1 /* GP7_PU */
+#define WM8995_GP7_PD 0x2000 /* GP7_PD */
+#define WM8995_GP7_PD_MASK 0x2000 /* GP7_PD */
+#define WM8995_GP7_PD_SHIFT 13 /* GP7_PD */
+#define WM8995_GP7_PD_WIDTH 1 /* GP7_PD */
+#define WM8995_GP7_POL 0x0400 /* GP7_POL */
+#define WM8995_GP7_POL_MASK 0x0400 /* GP7_POL */
+#define WM8995_GP7_POL_SHIFT 10 /* GP7_POL */
+#define WM8995_GP7_POL_WIDTH 1 /* GP7_POL */
+#define WM8995_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */
+#define WM8995_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */
+#define WM8995_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */
+#define WM8995_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */
+#define WM8995_GP7_DB 0x0100 /* GP7_DB */
+#define WM8995_GP7_DB_MASK 0x0100 /* GP7_DB */
+#define WM8995_GP7_DB_SHIFT 8 /* GP7_DB */
+#define WM8995_GP7_DB_WIDTH 1 /* GP7_DB */
+#define WM8995_GP7_LVL 0x0040 /* GP7_LVL */
+#define WM8995_GP7_LVL_MASK 0x0040 /* GP7_LVL */
+#define WM8995_GP7_LVL_SHIFT 6 /* GP7_LVL */
+#define WM8995_GP7_LVL_WIDTH 1 /* GP7_LVL */
+#define WM8995_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */
+#define WM8995_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */
+#define WM8995_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */
+
+/*
+ * R1799 (0x707) - GPIO 8
+ */
+#define WM8995_GP8_DIR 0x8000 /* GP8_DIR */
+#define WM8995_GP8_DIR_MASK 0x8000 /* GP8_DIR */
+#define WM8995_GP8_DIR_SHIFT 15 /* GP8_DIR */
+#define WM8995_GP8_DIR_WIDTH 1 /* GP8_DIR */
+#define WM8995_GP8_PU 0x4000 /* GP8_PU */
+#define WM8995_GP8_PU_MASK 0x4000 /* GP8_PU */
+#define WM8995_GP8_PU_SHIFT 14 /* GP8_PU */
+#define WM8995_GP8_PU_WIDTH 1 /* GP8_PU */
+#define WM8995_GP8_PD 0x2000 /* GP8_PD */
+#define WM8995_GP8_PD_MASK 0x2000 /* GP8_PD */
+#define WM8995_GP8_PD_SHIFT 13 /* GP8_PD */
+#define WM8995_GP8_PD_WIDTH 1 /* GP8_PD */
+#define WM8995_GP8_POL 0x0400 /* GP8_POL */
+#define WM8995_GP8_POL_MASK 0x0400 /* GP8_POL */
+#define WM8995_GP8_POL_SHIFT 10 /* GP8_POL */
+#define WM8995_GP8_POL_WIDTH 1 /* GP8_POL */
+#define WM8995_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */
+#define WM8995_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */
+#define WM8995_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */
+#define WM8995_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */
+#define WM8995_GP8_DB 0x0100 /* GP8_DB */
+#define WM8995_GP8_DB_MASK 0x0100 /* GP8_DB */
+#define WM8995_GP8_DB_SHIFT 8 /* GP8_DB */
+#define WM8995_GP8_DB_WIDTH 1 /* GP8_DB */
+#define WM8995_GP8_LVL 0x0040 /* GP8_LVL */
+#define WM8995_GP8_LVL_MASK 0x0040 /* GP8_LVL */
+#define WM8995_GP8_LVL_SHIFT 6 /* GP8_LVL */
+#define WM8995_GP8_LVL_WIDTH 1 /* GP8_LVL */
+#define WM8995_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */
+#define WM8995_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */
+#define WM8995_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */
+
+/*
+ * R1800 (0x708) - GPIO 9
+ */
+#define WM8995_GP9_DIR 0x8000 /* GP9_DIR */
+#define WM8995_GP9_DIR_MASK 0x8000 /* GP9_DIR */
+#define WM8995_GP9_DIR_SHIFT 15 /* GP9_DIR */
+#define WM8995_GP9_DIR_WIDTH 1 /* GP9_DIR */
+#define WM8995_GP9_PU 0x4000 /* GP9_PU */
+#define WM8995_GP9_PU_MASK 0x4000 /* GP9_PU */
+#define WM8995_GP9_PU_SHIFT 14 /* GP9_PU */
+#define WM8995_GP9_PU_WIDTH 1 /* GP9_PU */
+#define WM8995_GP9_PD 0x2000 /* GP9_PD */
+#define WM8995_GP9_PD_MASK 0x2000 /* GP9_PD */
+#define WM8995_GP9_PD_SHIFT 13 /* GP9_PD */
+#define WM8995_GP9_PD_WIDTH 1 /* GP9_PD */
+#define WM8995_GP9_POL 0x0400 /* GP9_POL */
+#define WM8995_GP9_POL_MASK 0x0400 /* GP9_POL */
+#define WM8995_GP9_POL_SHIFT 10 /* GP9_POL */
+#define WM8995_GP9_POL_WIDTH 1 /* GP9_POL */
+#define WM8995_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */
+#define WM8995_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */
+#define WM8995_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */
+#define WM8995_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */
+#define WM8995_GP9_DB 0x0100 /* GP9_DB */
+#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */
+#define WM8995_GP9_DB_SHIFT 8 /* GP9_DB */
+#define WM8995_GP9_DB_WIDTH 1 /* GP9_DB */
+#define WM8995_GP9_LVL 0x0040 /* GP9_LVL */
+#define WM8995_GP9_LVL_MASK 0x0040 /* GP9_LVL */
+#define WM8995_GP9_LVL_SHIFT 6 /* GP9_LVL */
+#define WM8995_GP9_LVL_WIDTH 1 /* GP9_LVL */
+#define WM8995_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */
+#define WM8995_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */
+#define WM8995_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */
+
+/*
+ * R1801 (0x709) - GPIO 10
+ */
+#define WM8995_GP10_DIR 0x8000 /* GP10_DIR */
+#define WM8995_GP10_DIR_MASK 0x8000 /* GP10_DIR */
+#define WM8995_GP10_DIR_SHIFT 15 /* GP10_DIR */
+#define WM8995_GP10_DIR_WIDTH 1 /* GP10_DIR */
+#define WM8995_GP10_PU 0x4000 /* GP10_PU */
+#define WM8995_GP10_PU_MASK 0x4000 /* GP10_PU */
+#define WM8995_GP10_PU_SHIFT 14 /* GP10_PU */
+#define WM8995_GP10_PU_WIDTH 1 /* GP10_PU */
+#define WM8995_GP10_PD 0x2000 /* GP10_PD */
+#define WM8995_GP10_PD_MASK 0x2000 /* GP10_PD */
+#define WM8995_GP10_PD_SHIFT 13 /* GP10_PD */
+#define WM8995_GP10_PD_WIDTH 1 /* GP10_PD */
+#define WM8995_GP10_POL 0x0400 /* GP10_POL */
+#define WM8995_GP10_POL_MASK 0x0400 /* GP10_POL */
+#define WM8995_GP10_POL_SHIFT 10 /* GP10_POL */
+#define WM8995_GP10_POL_WIDTH 1 /* GP10_POL */
+#define WM8995_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */
+#define WM8995_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */
+#define WM8995_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */
+#define WM8995_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */
+#define WM8995_GP10_DB 0x0100 /* GP10_DB */
+#define WM8995_GP10_DB_MASK 0x0100 /* GP10_DB */
+#define WM8995_GP10_DB_SHIFT 8 /* GP10_DB */
+#define WM8995_GP10_DB_WIDTH 1 /* GP10_DB */
+#define WM8995_GP10_LVL 0x0040 /* GP10_LVL */
+#define WM8995_GP10_LVL_MASK 0x0040 /* GP10_LVL */
+#define WM8995_GP10_LVL_SHIFT 6 /* GP10_LVL */
+#define WM8995_GP10_LVL_WIDTH 1 /* GP10_LVL */
+#define WM8995_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */
+#define WM8995_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */
+#define WM8995_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */
+
+/*
+ * R1802 (0x70A) - GPIO 11
+ */
+#define WM8995_GP11_DIR 0x8000 /* GP11_DIR */
+#define WM8995_GP11_DIR_MASK 0x8000 /* GP11_DIR */
+#define WM8995_GP11_DIR_SHIFT 15 /* GP11_DIR */
+#define WM8995_GP11_DIR_WIDTH 1 /* GP11_DIR */
+#define WM8995_GP11_PU 0x4000 /* GP11_PU */
+#define WM8995_GP11_PU_MASK 0x4000 /* GP11_PU */
+#define WM8995_GP11_PU_SHIFT 14 /* GP11_PU */
+#define WM8995_GP11_PU_WIDTH 1 /* GP11_PU */
+#define WM8995_GP11_PD 0x2000 /* GP11_PD */
+#define WM8995_GP11_PD_MASK 0x2000 /* GP11_PD */
+#define WM8995_GP11_PD_SHIFT 13 /* GP11_PD */
+#define WM8995_GP11_PD_WIDTH 1 /* GP11_PD */
+#define WM8995_GP11_POL 0x0400 /* GP11_POL */
+#define WM8995_GP11_POL_MASK 0x0400 /* GP11_POL */
+#define WM8995_GP11_POL_SHIFT 10 /* GP11_POL */
+#define WM8995_GP11_POL_WIDTH 1 /* GP11_POL */
+#define WM8995_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */
+#define WM8995_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */
+#define WM8995_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */
+#define WM8995_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */
+#define WM8995_GP11_DB 0x0100 /* GP11_DB */
+#define WM8995_GP11_DB_MASK 0x0100 /* GP11_DB */
+#define WM8995_GP11_DB_SHIFT 8 /* GP11_DB */
+#define WM8995_GP11_DB_WIDTH 1 /* GP11_DB */
+#define WM8995_GP11_LVL 0x0040 /* GP11_LVL */
+#define WM8995_GP11_LVL_MASK 0x0040 /* GP11_LVL */
+#define WM8995_GP11_LVL_SHIFT 6 /* GP11_LVL */
+#define WM8995_GP11_LVL_WIDTH 1 /* GP11_LVL */
+#define WM8995_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */
+#define WM8995_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */
+#define WM8995_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */
+
+/*
+ * R1803 (0x70B) - GPIO 12
+ */
+#define WM8995_GP12_DIR 0x8000 /* GP12_DIR */
+#define WM8995_GP12_DIR_MASK 0x8000 /* GP12_DIR */
+#define WM8995_GP12_DIR_SHIFT 15 /* GP12_DIR */
+#define WM8995_GP12_DIR_WIDTH 1 /* GP12_DIR */
+#define WM8995_GP12_PU 0x4000 /* GP12_PU */
+#define WM8995_GP12_PU_MASK 0x4000 /* GP12_PU */
+#define WM8995_GP12_PU_SHIFT 14 /* GP12_PU */
+#define WM8995_GP12_PU_WIDTH 1 /* GP12_PU */
+#define WM8995_GP12_PD 0x2000 /* GP12_PD */
+#define WM8995_GP12_PD_MASK 0x2000 /* GP12_PD */
+#define WM8995_GP12_PD_SHIFT 13 /* GP12_PD */
+#define WM8995_GP12_PD_WIDTH 1 /* GP12_PD */
+#define WM8995_GP12_POL 0x0400 /* GP12_POL */
+#define WM8995_GP12_POL_MASK 0x0400 /* GP12_POL */
+#define WM8995_GP12_POL_SHIFT 10 /* GP12_POL */
+#define WM8995_GP12_POL_WIDTH 1 /* GP12_POL */
+#define WM8995_GP12_OP_CFG 0x0200 /* GP12_OP_CFG */
+#define WM8995_GP12_OP_CFG_MASK 0x0200 /* GP12_OP_CFG */
+#define WM8995_GP12_OP_CFG_SHIFT 9 /* GP12_OP_CFG */
+#define WM8995_GP12_OP_CFG_WIDTH 1 /* GP12_OP_CFG */
+#define WM8995_GP12_DB 0x0100 /* GP12_DB */
+#define WM8995_GP12_DB_MASK 0x0100 /* GP12_DB */
+#define WM8995_GP12_DB_SHIFT 8 /* GP12_DB */
+#define WM8995_GP12_DB_WIDTH 1 /* GP12_DB */
+#define WM8995_GP12_LVL 0x0040 /* GP12_LVL */
+#define WM8995_GP12_LVL_MASK 0x0040 /* GP12_LVL */
+#define WM8995_GP12_LVL_SHIFT 6 /* GP12_LVL */
+#define WM8995_GP12_LVL_WIDTH 1 /* GP12_LVL */
+#define WM8995_GP12_FN_MASK 0x001F /* GP12_FN - [4:0] */
+#define WM8995_GP12_FN_SHIFT 0 /* GP12_FN - [4:0] */
+#define WM8995_GP12_FN_WIDTH 5 /* GP12_FN - [4:0] */
+
+/*
+ * R1804 (0x70C) - GPIO 13
+ */
+#define WM8995_GP13_DIR 0x8000 /* GP13_DIR */
+#define WM8995_GP13_DIR_MASK 0x8000 /* GP13_DIR */
+#define WM8995_GP13_DIR_SHIFT 15 /* GP13_DIR */
+#define WM8995_GP13_DIR_WIDTH 1 /* GP13_DIR */
+#define WM8995_GP13_PU 0x4000 /* GP13_PU */
+#define WM8995_GP13_PU_MASK 0x4000 /* GP13_PU */
+#define WM8995_GP13_PU_SHIFT 14 /* GP13_PU */
+#define WM8995_GP13_PU_WIDTH 1 /* GP13_PU */
+#define WM8995_GP13_PD 0x2000 /* GP13_PD */
+#define WM8995_GP13_PD_MASK 0x2000 /* GP13_PD */
+#define WM8995_GP13_PD_SHIFT 13 /* GP13_PD */
+#define WM8995_GP13_PD_WIDTH 1 /* GP13_PD */
+#define WM8995_GP13_POL 0x0400 /* GP13_POL */
+#define WM8995_GP13_POL_MASK 0x0400 /* GP13_POL */
+#define WM8995_GP13_POL_SHIFT 10 /* GP13_POL */
+#define WM8995_GP13_POL_WIDTH 1 /* GP13_POL */
+#define WM8995_GP13_OP_CFG 0x0200 /* GP13_OP_CFG */
+#define WM8995_GP13_OP_CFG_MASK 0x0200 /* GP13_OP_CFG */
+#define WM8995_GP13_OP_CFG_SHIFT 9 /* GP13_OP_CFG */
+#define WM8995_GP13_OP_CFG_WIDTH 1 /* GP13_OP_CFG */
+#define WM8995_GP13_DB 0x0100 /* GP13_DB */
+#define WM8995_GP13_DB_MASK 0x0100 /* GP13_DB */
+#define WM8995_GP13_DB_SHIFT 8 /* GP13_DB */
+#define WM8995_GP13_DB_WIDTH 1 /* GP13_DB */
+#define WM8995_GP13_LVL 0x0040 /* GP13_LVL */
+#define WM8995_GP13_LVL_MASK 0x0040 /* GP13_LVL */
+#define WM8995_GP13_LVL_SHIFT 6 /* GP13_LVL */
+#define WM8995_GP13_LVL_WIDTH 1 /* GP13_LVL */
+#define WM8995_GP13_FN_MASK 0x001F /* GP13_FN - [4:0] */
+#define WM8995_GP13_FN_SHIFT 0 /* GP13_FN - [4:0] */
+#define WM8995_GP13_FN_WIDTH 5 /* GP13_FN - [4:0] */
+
+/*
+ * R1805 (0x70D) - GPIO 14
+ */
+#define WM8995_GP14_DIR 0x8000 /* GP14_DIR */
+#define WM8995_GP14_DIR_MASK 0x8000 /* GP14_DIR */
+#define WM8995_GP14_DIR_SHIFT 15 /* GP14_DIR */
+#define WM8995_GP14_DIR_WIDTH 1 /* GP14_DIR */
+#define WM8995_GP14_PU 0x4000 /* GP14_PU */
+#define WM8995_GP14_PU_MASK 0x4000 /* GP14_PU */
+#define WM8995_GP14_PU_SHIFT 14 /* GP14_PU */
+#define WM8995_GP14_PU_WIDTH 1 /* GP14_PU */
+#define WM8995_GP14_PD 0x2000 /* GP14_PD */
+#define WM8995_GP14_PD_MASK 0x2000 /* GP14_PD */
+#define WM8995_GP14_PD_SHIFT 13 /* GP14_PD */
+#define WM8995_GP14_PD_WIDTH 1 /* GP14_PD */
+#define WM8995_GP14_POL 0x0400 /* GP14_POL */
+#define WM8995_GP14_POL_MASK 0x0400 /* GP14_POL */
+#define WM8995_GP14_POL_SHIFT 10 /* GP14_POL */
+#define WM8995_GP14_POL_WIDTH 1 /* GP14_POL */
+#define WM8995_GP14_OP_CFG 0x0200 /* GP14_OP_CFG */
+#define WM8995_GP14_OP_CFG_MASK 0x0200 /* GP14_OP_CFG */
+#define WM8995_GP14_OP_CFG_SHIFT 9 /* GP14_OP_CFG */
+#define WM8995_GP14_OP_CFG_WIDTH 1 /* GP14_OP_CFG */
+#define WM8995_GP14_DB 0x0100 /* GP14_DB */
+#define WM8995_GP14_DB_MASK 0x0100 /* GP14_DB */
+#define WM8995_GP14_DB_SHIFT 8 /* GP14_DB */
+#define WM8995_GP14_DB_WIDTH 1 /* GP14_DB */
+#define WM8995_GP14_LVL 0x0040 /* GP14_LVL */
+#define WM8995_GP14_LVL_MASK 0x0040 /* GP14_LVL */
+#define WM8995_GP14_LVL_SHIFT 6 /* GP14_LVL */
+#define WM8995_GP14_LVL_WIDTH 1 /* GP14_LVL */
+#define WM8995_GP14_FN_MASK 0x001F /* GP14_FN - [4:0] */
+#define WM8995_GP14_FN_SHIFT 0 /* GP14_FN - [4:0] */
+#define WM8995_GP14_FN_WIDTH 5 /* GP14_FN - [4:0] */
+
+/*
+ * R1824 (0x720) - Pull Control (1)
+ */
+#define WM8995_DMICDAT3_PD 0x4000 /* DMICDAT3_PD */
+#define WM8995_DMICDAT3_PD_MASK 0x4000 /* DMICDAT3_PD */
+#define WM8995_DMICDAT3_PD_SHIFT 14 /* DMICDAT3_PD */
+#define WM8995_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
+#define WM8995_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
+#define WM8995_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
+#define WM8995_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
+#define WM8995_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
+#define WM8995_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
+#define WM8995_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
+#define WM8995_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
+#define WM8995_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
+#define WM8995_MCLK2_PU 0x0200 /* MCLK2_PU */
+#define WM8995_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
+#define WM8995_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
+#define WM8995_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
+#define WM8995_MCLK2_PD 0x0100 /* MCLK2_PD */
+#define WM8995_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
+#define WM8995_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
+#define WM8995_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
+#define WM8995_MCLK1_PU 0x0080 /* MCLK1_PU */
+#define WM8995_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
+#define WM8995_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
+#define WM8995_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
+#define WM8995_MCLK1_PD 0x0040 /* MCLK1_PD */
+#define WM8995_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
+#define WM8995_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
+#define WM8995_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
+#define WM8995_DACDAT1_PU 0x0020 /* DACDAT1_PU */
+#define WM8995_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
+#define WM8995_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
+#define WM8995_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
+#define WM8995_DACDAT1_PD 0x0010 /* DACDAT1_PD */
+#define WM8995_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
+#define WM8995_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
+#define WM8995_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
+#define WM8995_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
+#define WM8995_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
+#define WM8995_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
+#define WM8995_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
+#define WM8995_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
+#define WM8995_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
+#define WM8995_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
+#define WM8995_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
+#define WM8995_BCLK1_PU 0x0002 /* BCLK1_PU */
+#define WM8995_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
+#define WM8995_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
+#define WM8995_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
+#define WM8995_BCLK1_PD 0x0001 /* BCLK1_PD */
+#define WM8995_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
+#define WM8995_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
+#define WM8995_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
+
+/*
+ * R1825 (0x721) - Pull Control (2)
+ */
+#define WM8995_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
+#define WM8995_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
+#define WM8995_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
+#define WM8995_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
+#define WM8995_MODE_PD 0x0004 /* MODE_PD */
+#define WM8995_MODE_PD_MASK 0x0004 /* MODE_PD */
+#define WM8995_MODE_PD_SHIFT 2 /* MODE_PD */
+#define WM8995_MODE_PD_WIDTH 1 /* MODE_PD */
+#define WM8995_CSNADDR_PD 0x0001 /* CSNADDR_PD */
+#define WM8995_CSNADDR_PD_MASK 0x0001 /* CSNADDR_PD */
+#define WM8995_CSNADDR_PD_SHIFT 0 /* CSNADDR_PD */
+#define WM8995_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
+
+/*
+ * R1840 (0x730) - Interrupt Status 1
+ */
+#define WM8995_GP14_EINT 0x2000 /* GP14_EINT */
+#define WM8995_GP14_EINT_MASK 0x2000 /* GP14_EINT */
+#define WM8995_GP14_EINT_SHIFT 13 /* GP14_EINT */
+#define WM8995_GP14_EINT_WIDTH 1 /* GP14_EINT */
+#define WM8995_GP13_EINT 0x1000 /* GP13_EINT */
+#define WM8995_GP13_EINT_MASK 0x1000 /* GP13_EINT */
+#define WM8995_GP13_EINT_SHIFT 12 /* GP13_EINT */
+#define WM8995_GP13_EINT_WIDTH 1 /* GP13_EINT */
+#define WM8995_GP12_EINT 0x0800 /* GP12_EINT */
+#define WM8995_GP12_EINT_MASK 0x0800 /* GP12_EINT */
+#define WM8995_GP12_EINT_SHIFT 11 /* GP12_EINT */
+#define WM8995_GP12_EINT_WIDTH 1 /* GP12_EINT */
+#define WM8995_GP11_EINT 0x0400 /* GP11_EINT */
+#define WM8995_GP11_EINT_MASK 0x0400 /* GP11_EINT */
+#define WM8995_GP11_EINT_SHIFT 10 /* GP11_EINT */
+#define WM8995_GP11_EINT_WIDTH 1 /* GP11_EINT */
+#define WM8995_GP10_EINT 0x0200 /* GP10_EINT */
+#define WM8995_GP10_EINT_MASK 0x0200 /* GP10_EINT */
+#define WM8995_GP10_EINT_SHIFT 9 /* GP10_EINT */
+#define WM8995_GP10_EINT_WIDTH 1 /* GP10_EINT */
+#define WM8995_GP9_EINT 0x0100 /* GP9_EINT */
+#define WM8995_GP9_EINT_MASK 0x0100 /* GP9_EINT */
+#define WM8995_GP9_EINT_SHIFT 8 /* GP9_EINT */
+#define WM8995_GP9_EINT_WIDTH 1 /* GP9_EINT */
+#define WM8995_GP8_EINT 0x0080 /* GP8_EINT */
+#define WM8995_GP8_EINT_MASK 0x0080 /* GP8_EINT */
+#define WM8995_GP8_EINT_SHIFT 7 /* GP8_EINT */
+#define WM8995_GP8_EINT_WIDTH 1 /* GP8_EINT */
+#define WM8995_GP7_EINT 0x0040 /* GP7_EINT */
+#define WM8995_GP7_EINT_MASK 0x0040 /* GP7_EINT */
+#define WM8995_GP7_EINT_SHIFT 6 /* GP7_EINT */
+#define WM8995_GP7_EINT_WIDTH 1 /* GP7_EINT */
+#define WM8995_GP6_EINT 0x0020 /* GP6_EINT */
+#define WM8995_GP6_EINT_MASK 0x0020 /* GP6_EINT */
+#define WM8995_GP6_EINT_SHIFT 5 /* GP6_EINT */
+#define WM8995_GP6_EINT_WIDTH 1 /* GP6_EINT */
+#define WM8995_GP5_EINT 0x0010 /* GP5_EINT */
+#define WM8995_GP5_EINT_MASK 0x0010 /* GP5_EINT */
+#define WM8995_GP5_EINT_SHIFT 4 /* GP5_EINT */
+#define WM8995_GP5_EINT_WIDTH 1 /* GP5_EINT */
+#define WM8995_GP4_EINT 0x0008 /* GP4_EINT */
+#define WM8995_GP4_EINT_MASK 0x0008 /* GP4_EINT */
+#define WM8995_GP4_EINT_SHIFT 3 /* GP4_EINT */
+#define WM8995_GP4_EINT_WIDTH 1 /* GP4_EINT */
+#define WM8995_GP3_EINT 0x0004 /* GP3_EINT */
+#define WM8995_GP3_EINT_MASK 0x0004 /* GP3_EINT */
+#define WM8995_GP3_EINT_SHIFT 2 /* GP3_EINT */
+#define WM8995_GP3_EINT_WIDTH 1 /* GP3_EINT */
+#define WM8995_GP2_EINT 0x0002 /* GP2_EINT */
+#define WM8995_GP2_EINT_MASK 0x0002 /* GP2_EINT */
+#define WM8995_GP2_EINT_SHIFT 1 /* GP2_EINT */
+#define WM8995_GP2_EINT_WIDTH 1 /* GP2_EINT */
+#define WM8995_GP1_EINT 0x0001 /* GP1_EINT */
+#define WM8995_GP1_EINT_MASK 0x0001 /* GP1_EINT */
+#define WM8995_GP1_EINT_SHIFT 0 /* GP1_EINT */
+#define WM8995_GP1_EINT_WIDTH 1 /* GP1_EINT */
+
+/*
+ * R1841 (0x731) - Interrupt Status 2
+ */
+#define WM8995_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
+#define WM8995_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
+#define WM8995_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
+#define WM8995_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
+#define WM8995_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
+#define WM8995_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
+#define WM8995_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
+#define WM8995_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
+#define WM8995_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
+#define WM8995_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
+#define WM8995_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
+#define WM8995_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
+#define WM8995_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
+#define WM8995_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
+#define WM8995_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
+#define WM8995_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
+#define WM8995_AIF2DRC_SIG_DET_EINT 0x0100 /* AIF2DRC_SIG_DET_EINT */
+#define WM8995_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* AIF2DRC_SIG_DET_EINT */
+#define WM8995_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* AIF2DRC_SIG_DET_EINT */
+#define WM8995_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
+#define WM8995_AIF1DRC2_SIG_DET_EINT 0x0080 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8995_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8995_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8995_AIF1DRC1_SIG_DET_EINT 0x0040 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8995_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8995_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8995_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8995_SRC2_LOCK_EINT 0x0020 /* SRC2_LOCK_EINT */
+#define WM8995_SRC2_LOCK_EINT_MASK 0x0020 /* SRC2_LOCK_EINT */
+#define WM8995_SRC2_LOCK_EINT_SHIFT 5 /* SRC2_LOCK_EINT */
+#define WM8995_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
+#define WM8995_SRC1_LOCK_EINT 0x0010 /* SRC1_LOCK_EINT */
+#define WM8995_SRC1_LOCK_EINT_MASK 0x0010 /* SRC1_LOCK_EINT */
+#define WM8995_SRC1_LOCK_EINT_SHIFT 4 /* SRC1_LOCK_EINT */
+#define WM8995_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
+#define WM8995_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
+#define WM8995_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
+#define WM8995_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
+#define WM8995_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
+#define WM8995_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
+#define WM8995_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
+#define WM8995_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
+#define WM8995_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
+#define WM8995_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
+#define WM8995_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
+#define WM8995_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
+#define WM8995_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
+#define WM8995_MICD_EINT 0x0001 /* MICD_EINT */
+#define WM8995_MICD_EINT_MASK 0x0001 /* MICD_EINT */
+#define WM8995_MICD_EINT_SHIFT 0 /* MICD_EINT */
+#define WM8995_MICD_EINT_WIDTH 1 /* MICD_EINT */
+
+/*
+ * R1842 (0x732) - Interrupt Raw Status 2
+ */
+#define WM8995_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
+#define WM8995_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
+#define WM8995_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
+#define WM8995_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
+#define WM8995_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
+#define WM8995_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
+#define WM8995_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
+#define WM8995_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
+#define WM8995_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
+#define WM8995_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
+#define WM8995_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
+#define WM8995_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
+#define WM8995_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
+#define WM8995_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
+#define WM8995_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
+#define WM8995_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
+#define WM8995_AIF2DRC_SIG_DET_STS 0x0100 /* AIF2DRC_SIG_DET_STS */
+#define WM8995_AIF2DRC_SIG_DET_STS_MASK 0x0100 /* AIF2DRC_SIG_DET_STS */
+#define WM8995_AIF2DRC_SIG_DET_STS_SHIFT 8 /* AIF2DRC_SIG_DET_STS */
+#define WM8995_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
+#define WM8995_AIF1DRC2_SIG_DET_STS 0x0080 /* AIF1DRC2_SIG_DET_STS */
+#define WM8995_AIF1DRC2_SIG_DET_STS_MASK 0x0080 /* AIF1DRC2_SIG_DET_STS */
+#define WM8995_AIF1DRC2_SIG_DET_STS_SHIFT 7 /* AIF1DRC2_SIG_DET_STS */
+#define WM8995_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
+#define WM8995_AIF1DRC1_SIG_DET_STS 0x0040 /* AIF1DRC1_SIG_DET_STS */
+#define WM8995_AIF1DRC1_SIG_DET_STS_MASK 0x0040 /* AIF1DRC1_SIG_DET_STS */
+#define WM8995_AIF1DRC1_SIG_DET_STS_SHIFT 6 /* AIF1DRC1_SIG_DET_STS */
+#define WM8995_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
+#define WM8995_SRC2_LOCK_STS 0x0020 /* SRC2_LOCK_STS */
+#define WM8995_SRC2_LOCK_STS_MASK 0x0020 /* SRC2_LOCK_STS */
+#define WM8995_SRC2_LOCK_STS_SHIFT 5 /* SRC2_LOCK_STS */
+#define WM8995_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
+#define WM8995_SRC1_LOCK_STS 0x0010 /* SRC1_LOCK_STS */
+#define WM8995_SRC1_LOCK_STS_MASK 0x0010 /* SRC1_LOCK_STS */
+#define WM8995_SRC1_LOCK_STS_SHIFT 4 /* SRC1_LOCK_STS */
+#define WM8995_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
+#define WM8995_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
+#define WM8995_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
+#define WM8995_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
+#define WM8995_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
+#define WM8995_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
+#define WM8995_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
+#define WM8995_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
+#define WM8995_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
+
+/*
+ * R1848 (0x738) - Interrupt Status 1 Mask
+ */
+#define WM8995_IM_GP14_EINT 0x2000 /* IM_GP14_EINT */
+#define WM8995_IM_GP14_EINT_MASK 0x2000 /* IM_GP14_EINT */
+#define WM8995_IM_GP14_EINT_SHIFT 13 /* IM_GP14_EINT */
+#define WM8995_IM_GP14_EINT_WIDTH 1 /* IM_GP14_EINT */
+#define WM8995_IM_GP13_EINT 0x1000 /* IM_GP13_EINT */
+#define WM8995_IM_GP13_EINT_MASK 0x1000 /* IM_GP13_EINT */
+#define WM8995_IM_GP13_EINT_SHIFT 12 /* IM_GP13_EINT */
+#define WM8995_IM_GP13_EINT_WIDTH 1 /* IM_GP13_EINT */
+#define WM8995_IM_GP12_EINT 0x0800 /* IM_GP12_EINT */
+#define WM8995_IM_GP12_EINT_MASK 0x0800 /* IM_GP12_EINT */
+#define WM8995_IM_GP12_EINT_SHIFT 11 /* IM_GP12_EINT */
+#define WM8995_IM_GP12_EINT_WIDTH 1 /* IM_GP12_EINT */
+#define WM8995_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
+#define WM8995_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
+#define WM8995_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
+#define WM8995_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
+#define WM8995_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
+#define WM8995_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
+#define WM8995_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
+#define WM8995_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
+#define WM8995_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
+#define WM8995_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
+#define WM8995_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
+#define WM8995_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
+#define WM8995_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
+#define WM8995_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
+#define WM8995_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
+#define WM8995_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
+#define WM8995_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
+#define WM8995_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
+#define WM8995_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
+#define WM8995_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
+#define WM8995_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
+#define WM8995_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
+#define WM8995_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
+#define WM8995_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
+#define WM8995_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
+#define WM8995_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
+#define WM8995_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
+#define WM8995_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
+#define WM8995_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
+#define WM8995_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
+#define WM8995_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
+#define WM8995_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
+#define WM8995_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
+#define WM8995_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
+#define WM8995_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
+#define WM8995_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
+#define WM8995_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
+#define WM8995_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
+#define WM8995_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
+#define WM8995_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
+#define WM8995_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
+#define WM8995_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
+#define WM8995_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
+#define WM8995_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
+
+/*
+ * R1849 (0x739) - Interrupt Status 2 Mask
+ */
+#define WM8995_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
+#define WM8995_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
+#define WM8995_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
+#define WM8995_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
+#define WM8995_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
+#define WM8995_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
+#define WM8995_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
+#define WM8995_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
+#define WM8995_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
+#define WM8995_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
+#define WM8995_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
+#define WM8995_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
+#define WM8995_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
+#define WM8995_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
+#define WM8995_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
+#define WM8995_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
+#define WM8995_IM_AIF2DRC_SIG_DET_EINT 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8995_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8995_IM_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8995_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC2_SIG_DET_EINT 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC1_SIG_DET_EINT 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8995_IM_SRC2_LOCK_EINT 0x0020 /* IM_SRC2_LOCK_EINT */
+#define WM8995_IM_SRC2_LOCK_EINT_MASK 0x0020 /* IM_SRC2_LOCK_EINT */
+#define WM8995_IM_SRC2_LOCK_EINT_SHIFT 5 /* IM_SRC2_LOCK_EINT */
+#define WM8995_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
+#define WM8995_IM_SRC1_LOCK_EINT 0x0010 /* IM_SRC1_LOCK_EINT */
+#define WM8995_IM_SRC1_LOCK_EINT_MASK 0x0010 /* IM_SRC1_LOCK_EINT */
+#define WM8995_IM_SRC1_LOCK_EINT_SHIFT 4 /* IM_SRC1_LOCK_EINT */
+#define WM8995_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
+#define WM8995_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
+#define WM8995_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
+#define WM8995_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
+#define WM8995_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
+#define WM8995_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
+#define WM8995_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
+#define WM8995_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
+#define WM8995_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
+#define WM8995_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
+#define WM8995_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
+#define WM8995_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
+#define WM8995_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
+#define WM8995_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
+#define WM8995_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
+#define WM8995_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
+#define WM8995_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
+
+/*
+ * R1856 (0x740) - Interrupt Control
+ */
+#define WM8995_IM_IRQ 0x0001 /* IM_IRQ */
+#define WM8995_IM_IRQ_MASK 0x0001 /* IM_IRQ */
+#define WM8995_IM_IRQ_SHIFT 0 /* IM_IRQ */
+#define WM8995_IM_IRQ_WIDTH 1 /* IM_IRQ */
+
+/*
+ * R2048 (0x800) - Left PDM Speaker 1
+ */
+#define WM8995_SPK1L_ENA 0x0010 /* SPK1L_ENA */
+#define WM8995_SPK1L_ENA_MASK 0x0010 /* SPK1L_ENA */
+#define WM8995_SPK1L_ENA_SHIFT 4 /* SPK1L_ENA */
+#define WM8995_SPK1L_ENA_WIDTH 1 /* SPK1L_ENA */
+#define WM8995_SPK1L_MUTE 0x0008 /* SPK1L_MUTE */
+#define WM8995_SPK1L_MUTE_MASK 0x0008 /* SPK1L_MUTE */
+#define WM8995_SPK1L_MUTE_SHIFT 3 /* SPK1L_MUTE */
+#define WM8995_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
+#define WM8995_SPK1L_MUTE_ZC 0x0004 /* SPK1L_MUTE_ZC */
+#define WM8995_SPK1L_MUTE_ZC_MASK 0x0004 /* SPK1L_MUTE_ZC */
+#define WM8995_SPK1L_MUTE_ZC_SHIFT 2 /* SPK1L_MUTE_ZC */
+#define WM8995_SPK1L_MUTE_ZC_WIDTH 1 /* SPK1L_MUTE_ZC */
+#define WM8995_SPK1L_SRC_MASK 0x0003 /* SPK1L_SRC - [1:0] */
+#define WM8995_SPK1L_SRC_SHIFT 0 /* SPK1L_SRC - [1:0] */
+#define WM8995_SPK1L_SRC_WIDTH 2 /* SPK1L_SRC - [1:0] */
+
+/*
+ * R2049 (0x801) - Right PDM Speaker 1
+ */
+#define WM8995_SPK1R_ENA 0x0010 /* SPK1R_ENA */
+#define WM8995_SPK1R_ENA_MASK 0x0010 /* SPK1R_ENA */
+#define WM8995_SPK1R_ENA_SHIFT 4 /* SPK1R_ENA */
+#define WM8995_SPK1R_ENA_WIDTH 1 /* SPK1R_ENA */
+#define WM8995_SPK1R_MUTE 0x0008 /* SPK1R_MUTE */
+#define WM8995_SPK1R_MUTE_MASK 0x0008 /* SPK1R_MUTE */
+#define WM8995_SPK1R_MUTE_SHIFT 3 /* SPK1R_MUTE */
+#define WM8995_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
+#define WM8995_SPK1R_MUTE_ZC 0x0004 /* SPK1R_MUTE_ZC */
+#define WM8995_SPK1R_MUTE_ZC_MASK 0x0004 /* SPK1R_MUTE_ZC */
+#define WM8995_SPK1R_MUTE_ZC_SHIFT 2 /* SPK1R_MUTE_ZC */
+#define WM8995_SPK1R_MUTE_ZC_WIDTH 1 /* SPK1R_MUTE_ZC */
+#define WM8995_SPK1R_SRC_MASK 0x0003 /* SPK1R_SRC - [1:0] */
+#define WM8995_SPK1R_SRC_SHIFT 0 /* SPK1R_SRC - [1:0] */
+#define WM8995_SPK1R_SRC_WIDTH 2 /* SPK1R_SRC - [1:0] */
+
+/*
+ * R2050 (0x802) - PDM Speaker 1 Mute Sequence
+ */
+#define WM8995_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
+#define WM8995_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
+#define WM8995_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
+
+/*
+ * R2056 (0x808) - Left PDM Speaker 2
+ */
+#define WM8995_SPK2L_ENA 0x0010 /* SPK2L_ENA */
+#define WM8995_SPK2L_ENA_MASK 0x0010 /* SPK2L_ENA */
+#define WM8995_SPK2L_ENA_SHIFT 4 /* SPK2L_ENA */
+#define WM8995_SPK2L_ENA_WIDTH 1 /* SPK2L_ENA */
+#define WM8995_SPK2L_MUTE 0x0008 /* SPK2L_MUTE */
+#define WM8995_SPK2L_MUTE_MASK 0x0008 /* SPK2L_MUTE */
+#define WM8995_SPK2L_MUTE_SHIFT 3 /* SPK2L_MUTE */
+#define WM8995_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
+#define WM8995_SPK2L_MUTE_ZC 0x0004 /* SPK2L_MUTE_ZC */
+#define WM8995_SPK2L_MUTE_ZC_MASK 0x0004 /* SPK2L_MUTE_ZC */
+#define WM8995_SPK2L_MUTE_ZC_SHIFT 2 /* SPK2L_MUTE_ZC */
+#define WM8995_SPK2L_MUTE_ZC_WIDTH 1 /* SPK2L_MUTE_ZC */
+#define WM8995_SPK2L_SRC_MASK 0x0003 /* SPK2L_SRC - [1:0] */
+#define WM8995_SPK2L_SRC_SHIFT 0 /* SPK2L_SRC - [1:0] */
+#define WM8995_SPK2L_SRC_WIDTH 2 /* SPK2L_SRC - [1:0] */
+
+/*
+ * R2057 (0x809) - Right PDM Speaker 2
+ */
+#define WM8995_SPK2R_ENA 0x0010 /* SPK2R_ENA */
+#define WM8995_SPK2R_ENA_MASK 0x0010 /* SPK2R_ENA */
+#define WM8995_SPK2R_ENA_SHIFT 4 /* SPK2R_ENA */
+#define WM8995_SPK2R_ENA_WIDTH 1 /* SPK2R_ENA */
+#define WM8995_SPK2R_MUTE 0x0008 /* SPK2R_MUTE */
+#define WM8995_SPK2R_MUTE_MASK 0x0008 /* SPK2R_MUTE */
+#define WM8995_SPK2R_MUTE_SHIFT 3 /* SPK2R_MUTE */
+#define WM8995_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
+#define WM8995_SPK2R_MUTE_ZC 0x0004 /* SPK2R_MUTE_ZC */
+#define WM8995_SPK2R_MUTE_ZC_MASK 0x0004 /* SPK2R_MUTE_ZC */
+#define WM8995_SPK2R_MUTE_ZC_SHIFT 2 /* SPK2R_MUTE_ZC */
+#define WM8995_SPK2R_MUTE_ZC_WIDTH 1 /* SPK2R_MUTE_ZC */
+#define WM8995_SPK2R_SRC_MASK 0x0003 /* SPK2R_SRC - [1:0] */
+#define WM8995_SPK2R_SRC_SHIFT 0 /* SPK2R_SRC - [1:0] */
+#define WM8995_SPK2R_SRC_WIDTH 2 /* SPK2R_SRC - [1:0] */
+
+/*
+ * R2058 (0x80A) - PDM Speaker 2 Mute Sequence
+ */
+#define WM8995_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
+#define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
+#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
+
+#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_volsw, \
+ .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
+ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
+}
+
+struct wm8995_reg_access {
+ u16 read;
+ u16 write;
+ u16 vol;
+};
+
+/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
+enum clk_src {
+ WM8995_SYSCLK_MCLK1 = 1,
+ WM8995_SYSCLK_MCLK2,
+ WM8995_SYSCLK_FLL1,
+ WM8995_SYSCLK_FLL2,
+ WM8995_SYSCLK_OPCLK
+};
+
+#define WM8995_FLL1 1
+#define WM8995_FLL2 2
+
+#define WM8995_FLL_SRC_MCLK1 1
+#define WM8995_FLL_SRC_MCLK2 2
+#define WM8995_FLL_SRC_LRCLK 3
+#define WM8995_FLL_SRC_BCLK 4
+
+#endif /* _WM8995_H */
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index ecc7c37180c7..43825b2102a5 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -23,7 +23,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -158,7 +157,6 @@ static struct {
struct wm9081_priv {
enum snd_soc_control_type control_type;
void *control_data;
- u16 reg_cache[WM9081_MAX_REGISTER + 1];
int sysclk_source;
int mclk_rate;
int sysclk_rate;
@@ -591,6 +589,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
+ /* Set gain to the recommended value */
+ snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
+ WM9081_FLL_GAIN_MASK, 0);
+
/* Enable the FLL */
snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
@@ -805,7 +807,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
/* Initial cold start */
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Disable LINEOUT discharge */
reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
reg &= ~WM9081_LINEOUT_DISCH;
@@ -865,7 +867,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -1228,6 +1230,7 @@ static struct snd_soc_dai_driver wm9081_dai = {
static int wm9081_probe(struct snd_soc_codec *codec)
{
struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
u16 reg;
@@ -1269,9 +1272,9 @@ static int wm9081_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(wm9081_eq_controls));
}
- snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
ARRAY_SIZE(wm9081_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+ snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
}
@@ -1335,6 +1338,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm9081);
+ wm9081->control_type = SND_SOC_I2C;
wm9081->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 99c046ba46bb..a788c4297046 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/wm9090.h>
@@ -141,7 +140,6 @@ static const u16 wm9090_reg_defaults[] = {
/* This struct is used to save the context */
struct wm9090_priv {
struct mutex mutex;
- u16 reg_cache[WM9090_MAX_REGISTER + 1];
struct wm9090_platform_data pdata;
void *control_data;
};
@@ -443,31 +441,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
static int wm9090_add_controls(struct snd_soc_codec *codec)
{
struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;
- snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
ARRAY_SIZE(wm9090_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
snd_soc_add_controls(codec, wm9090_controls,
ARRAY_SIZE(wm9090_controls));
if (wm9090->pdata.lin1_diff) {
- snd_soc_dapm_add_routes(codec, audio_map_in1_diff,
+ snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
ARRAY_SIZE(audio_map_in1_diff));
} else {
- snd_soc_dapm_add_routes(codec, audio_map_in1_se,
+ snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
ARRAY_SIZE(audio_map_in1_se));
snd_soc_add_controls(codec, wm9090_in1_se_controls,
ARRAY_SIZE(wm9090_in1_se_controls));
}
if (wm9090->pdata.lin2_diff) {
- snd_soc_dapm_add_routes(codec, audio_map_in2_diff,
+ snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
ARRAY_SIZE(audio_map_in2_diff));
} else {
- snd_soc_dapm_add_routes(codec, audio_map_in2_se,
+ snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
ARRAY_SIZE(audio_map_in2_se));
snd_soc_add_controls(codec, wm9090_in2_se_controls,
ARRAY_SIZE(wm9090_in2_se_controls));
@@ -514,7 +513,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Restore the register cache */
for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (reg_cache[i] == wm9090_reg_defaults[i])
@@ -544,7 +543,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
static int wm9090_probe(struct snd_soc_codec *codec)
{
struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret;
codec->control_data = wm9090->control_data;
@@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec)
/* Configure some defaults; they will be written out when we
* bring the bias up.
*/
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
+ reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
| WM9090_IN1A_ZC;
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
+ reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
| WM9090_IN1B_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
+ reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
| WM9090_IN2A_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
+ reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
| WM9090_IN2B_ZC;
- wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
+ reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
- wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
+ reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
- wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
+ reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
- wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
+ reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index a144acda751c..47b357adabdd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -19,7 +19,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9705.h"
@@ -203,9 +202,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9705_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
ARRAY_SIZE(wm9705_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index d2f224d62744..bf5d4ef1a2a6 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,7 +20,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9712.h"
#define WM9712_VERSION "0.4"
@@ -432,10 +431,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9712_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets,
- ARRAY_SIZE(wm9712_dapm_widgets));
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
+ ARRAY_SIZE(wm9712_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -570,7 +570,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 7da13b07a53d..38ed98558718 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -26,7 +26,6 @@
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "wm9713.h"
@@ -647,10 +646,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int wm9713_add_widgets(struct snd_soc_codec *codec)
{
- snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
ARRAY_SIZE(wm9713_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
@@ -1147,7 +1148,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
ac97_write(codec, AC97_POWERDOWN, 0xffff);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 19ca782ac970..c466982eed23 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -22,7 +22,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -94,41 +93,61 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
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);
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
+ /* If we're using a digital only path and have a previously
+ * callibrated DC servo offset stored then use that. */
+ if (hubs->class_w && hubs->class_w_dcs) {
+ dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
+ hubs->class_w_dcs);
+ snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_DAC_WR_0 |
+ WM8993_DCS_TRIG_DAC_WR_1);
+ return;
+ }
+
+ /* Devices not using a DCS code correction have startup mode */
+ if (hubs->dcs_codes) {
+ /* 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);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_SERIES_0 |
+ WM8993_DCS_TRIG_SERIES_1);
+ } else {
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_STARTUP_0 |
+ WM8993_DCS_TRIG_STARTUP_1);
+ }
+
+ /* 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\n");
+ break;
+ }
+
+ dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
/* 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\n");
- break;
- }
-
- dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
-
/* HPOUT1L */
if (reg_l + hubs->dcs_codes > 0 &&
reg_l + hubs->dcs_codes < 0xff)
@@ -148,7 +167,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
wait_for_dc_servo(codec,
WM8993_DCS_TRIG_DAC_WR_0 |
WM8993_DCS_TRIG_DAC_WR_1);
+ } else {
+ dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ dcs_cfg |= reg_r;
}
+
+ /* Save the callibrated offset if we're in class W mode and
+ * therefore don't have any analogue signal mixed in. */
+ if (hubs->class_w)
+ hubs->class_w_dcs = dcs_cfg;
}
/*
@@ -163,6 +190,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ /* Updating the analogue gains invalidates the DC servo cache */
+ hubs->class_w_dcs = 0;
+
/* If we're applying an offset correction then updating the
* callibration would be likely to introduce further offsets. */
if (hubs->dcs_codes)
@@ -293,7 +323,7 @@ SOC_DOUBLE_R("Speaker Switch",
SOC_DOUBLE_R("Speaker ZC Switch",
WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
spkboost_tlv),
SOC_ENUM("Speaker Reference", speaker_ref),
SOC_ENUM("Speaker Mode", speaker_mode),
@@ -791,6 +821,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = {
int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* Latch volume update bits & default ZC on */
snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
WM8993_IN1_VU, WM8993_IN1_VU);
@@ -819,7 +851,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, analogue_snd_controls,
ARRAY_SIZE(analogue_snd_controls));
- snd_soc_dapm_new_controls(codec, analogue_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
ARRAY_SIZE(analogue_dapm_widgets));
return 0;
}
@@ -828,24 +860,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
int lineout1_diff, int lineout2_diff)
{
- snd_soc_dapm_add_routes(codec, analogue_routes,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_add_routes(dapm, analogue_routes,
ARRAY_SIZE(analogue_routes));
if (lineout1_diff)
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout1_diff_routes,
ARRAY_SIZE(lineout1_diff_routes));
else
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout1_se_routes,
ARRAY_SIZE(lineout1_se_routes));
if (lineout2_diff)
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout2_diff_routes,
ARRAY_SIZE(lineout2_diff_routes));
else
- snd_soc_dapm_add_routes(codec,
+ snd_soc_dapm_add_routes(dapm,
lineout2_se_routes,
ARRAY_SIZE(lineout2_se_routes));
@@ -872,7 +906,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
* VMID as an output and can disable it.
*/
if (lineout1_diff && lineout2_diff)
- codec->idle_bias_off = 1;
+ codec->dapm.idle_bias_off = 1;
if (lineout1fb)
snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index e51c16683589..f8a5e976b5e6 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,6 +23,9 @@ struct wm_hubs_data {
int dcs_codes;
int dcs_readback_mode;
int hp_startup_mode;
+
+ bool class_w;
+ u16 class_w_dcs;
};
extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index bc9e6b0b3f6f..24b031e26342 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/dma.h>
#include <asm/mach-types.h>
@@ -132,26 +131,27 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add davinci-evm specific widgets */
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* Set up davinci-evm specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* not connected */
- snd_soc_dapm_disable_pin(codec, "MONO_LOUT");
- snd_soc_dapm_disable_pin(codec, "HPLCOM");
- snd_soc_dapm_disable_pin(codec, "HPRCOM");
+ snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_disable_pin(dapm, "HPLCOM");
+ snd_soc_dapm_disable_pin(dapm, "HPRCOM");
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 6c6666a1f942..0fe558c65145 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/dma.h>
#include <asm/mach-types.h>
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 4f4873359613..9ac93f6b4f85 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -352,13 +352,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
.playback = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.capture = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 2f121ddbe4bb..06670776f649 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.rate_min = SNDRV_PCM_RATE_8000,
- .rate_max = SNDRV_PCM_RATE_48000,
+ .rate_max = SNDRV_PCM_RATE_96000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index 28ab5ff772ac..dfe1d7f74ea6 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -15,7 +15,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -79,11 +78,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 0d7dcf1e4863..7d7847a1e66b 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -498,6 +498,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "platform device add failed\n");
goto error;
}
+ dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 63b9eaa1ebc2..026b756961e0 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -498,6 +498,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "platform device add failed\n");
goto error;
}
+ dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index dd4fffdbd177..e20c9e1457c0 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include "../codecs/tlv320aic23.h"
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 390b6ffc2658..30894ea7f333 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -456,13 +456,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
static struct snd_soc_dai_driver imx_ssi_dai = {
.probe = imx_ssi_dai_probe,
.playback = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.capture = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 9eabc28667e6..a7deb5cb2433 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -17,7 +17,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
static struct snd_soc_card imx_phycore;
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index 30fdb15065be..75b4c72787e2 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audmux.h>
@@ -213,11 +212,12 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
+ snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
ARRAY_SIZE(wm1133_ev1_widgets));
- snd_soc_dapm_add_routes(codec, wm1133_ev1_map,
+ snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
ARRAY_SIZE(wm1133_ev1_map));
/* Headphone jack detection */
@@ -234,7 +234,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
SND_JACK_BTN_0);
- snd_soc_dapm_force_enable_pin(codec, "Mic Bias");
+ snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
return 0;
}
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index f3cffd183401..419bf4f5534a 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -28,7 +28,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "jz4740-i2s.h"
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index ef1a99e6a3bd..49723e3e7e38 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -19,7 +19,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <linux/gpio.h>
#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
@@ -59,10 +58,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_nc_pin(codec, "LIN");
- snd_soc_dapm_nc_pin(codec, "RIN");
+ snd_soc_dapm_nc_pin(dapm, "LIN");
+ snd_soc_dapm_nc_pin(dapm, "RIN");
ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
if (ret < 0) {
@@ -70,9 +70,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
- snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets));
- snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
+ ARRAY_SIZE(qi_lb60_widgets));
+ snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
+ ARRAY_SIZE(qi_lb60_routes));
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 16ec2a2dba4d..8f49e165f4d1 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -11,10 +11,19 @@ config SND_KIRKWOOD_SOC_I2S
config SND_KIRKWOOD_SOC_OPENRD
tristate "SoC Audio support for Kirkwood Openrd Client"
- depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT
+ depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE)
select SND_KIRKWOOD_SOC_I2S
select SND_SOC_CS42L51
help
Say Y if you want to add support for SoC audio on
Openrd Client.
+config SND_KIRKWOOD_SOC_T5325
+ tristate "SoC Audio support for HP t5325"
+ depends on SND_KIRKWOOD_SOC && MACH_T5325
+ select SND_KIRKWOOD_SOC_I2S
+ select SND_SOC_ALC5623
+ help
+ Say Y if you want to add support for SoC audio on
+ the HP t5325 thin client.
+
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
index 33a16dcab5b5..3e62ae9e7bbe 100644
--- a/sound/soc/kirkwood/Makefile
+++ b/sound/soc/kirkwood/Makefile
@@ -5,5 +5,7 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
snd-soc-openrd-objs := kirkwood-openrd.o
+snd-soc-t5325-objs := kirkwood-t5325.o
obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
+obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 9d7c81e921f1..d863afb3ee52 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -86,7 +86,7 @@ static int __init openrd_client_init(void)
{
int ret;
- if (!machine_is_openrd_client())
+ if (!machine_is_openrd_client() && !machine_is_openrd_ultimate())
return 0;
openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
new file mode 100644
index 000000000000..c8d21956ab52
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -0,0 +1,141 @@
+/*
+ * kirkwood-t5325.c
+ *
+ * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <mach/kirkwood.h>
+#include <plat/audio.h>
+#include <asm/mach-types.h>
+#include "../codecs/alc5623.h"
+
+static int t5325_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret;
+ unsigned int freq, fmt;
+
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0)
+ return ret;
+
+ freq = params_rate(params) * 256;
+
+ return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
+
+}
+
+static struct snd_soc_ops t5325_ops = {
+ .hw_params = t5325_hw_params,
+};
+
+static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route t5325_route[] = {
+ { "Headphone Jack", NULL, "HPL" },
+ { "Headphone Jack", NULL, "HPR" },
+
+ {"Speaker", NULL, "SPKOUT"},
+ {"Speaker", NULL, "SPKOUTN"},
+
+ { "MIC1", NULL, "Mic Jack" },
+ { "MIC2", NULL, "Mic Jack" },
+};
+
+static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets,
+ ARRAY_SIZE(t5325_dapm_widgets));
+
+ snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route));
+
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
+
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link t5325_dai[] = {
+{
+ .name = "ALC5621",
+ .stream_name = "ALC5621 HiFi",
+ .cpu_dai_name = "kirkwood-i2s",
+ .platform_name = "kirkwood-pcm-audio",
+ .codec_dai_name = "alc5621-hifi",
+ .codec_name = "alc562x-codec.0-001a",
+ .ops = &t5325_ops,
+ .init = t5325_dai_init,
+},
+};
+
+
+static struct snd_soc_card t5325 = {
+ .name = "t5325",
+ .dai_link = t5325_dai,
+ .num_links = ARRAY_SIZE(t5325_dai),
+};
+
+static struct platform_device *t5325_snd_device;
+
+static int __init t5325_init(void)
+{
+ int ret;
+
+ if (!machine_is_t5325())
+ return 0;
+
+ t5325_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!t5325_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(t5325_snd_device,
+ &t5325);
+
+ ret = platform_device_add(t5325_snd_device);
+ if (ret) {
+ printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
+ platform_device_put(t5325_snd_device);
+ }
+
+ return ret;
+}
+module_init(t5325_init);
+
+static void __exit t5325_exit(void)
+{
+ platform_device_unregister(t5325_snd_device);
+}
+module_exit(t5325_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index e00e39dd6576..dac6732da969 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -49,7 +49,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
mutex_lock(&ac97_mutex);
val = nuc900_checkready();
- if (!!val) {
+ if (val) {
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
goto out;
}
@@ -102,7 +102,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
mutex_lock(&ac97_mutex);
tmp = nuc900_checkready();
- if (!!tmp)
+ if (tmp)
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
/* clear the R_WB bit and write register index */
@@ -149,7 +149,7 @@ static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
udelay(100);
val = nuc900_checkready();
- if (!!val)
+ if (val)
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
mutex_unlock(&ac97_mutex);
@@ -263,8 +263,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
return ret;
}
-static int nuc900_ac97_probe(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int nuc900_ac97_probe(struct snd_soc_dai *dai)
{
struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
unsigned long val;
@@ -284,12 +283,12 @@ static int nuc900_ac97_probe(struct platform_device *pdev,
return 0;
}
-static void nuc900_ac97_remove(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int nuc900_ac97_remove(struct snd_soc_dai *dai)
{
struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
clk_disable(nuc900_audio->clk);
+ return 0;
}
static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
@@ -313,7 +312,7 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = {
.channels_max = 2,
},
.ops = &nuc900_ac97_dai_ops,
-}
+};
static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
{
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
index 161f5b667d7b..38a2d0d883b5 100644
--- a/sound/soc/nuc900/nuc900-audio.c
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "nuc900-audio.h"
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
index aeed8ead2b2b..59f7e8ed1a68 100644
--- a/sound/soc/nuc900/nuc900-audio.h
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -110,4 +110,6 @@ struct nuc900_audio {
};
+extern struct nuc900_audio *nuc900_ac97_data;
+
#endif /*end _NUC900_AUDIO_H */
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index 195d1ac94771..8263f56dc665 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -50,12 +50,12 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&nuc900_audio->lock, flags);
-
ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
if (ret < 0)
return ret;
+ spin_lock_irqsave(&nuc900_audio->lock, flags);
+
nuc900_audio->substream = substream;
nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
nuc900_audio->buffersize[substream->stream] =
@@ -169,6 +169,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct nuc900_audio *nuc900_audio = runtime->private_data;
unsigned long flags, val;
+ int ret = 0;
spin_lock_irqsave(&nuc900_audio->lock, flags);
@@ -197,10 +198,10 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
spin_unlock_irqrestore(&nuc900_audio->lock, flags);
- return 0;
+ return ret;
}
static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -332,7 +333,7 @@ static struct snd_soc_platform_driver nuc900_soc_platform = {
.ops = &nuc900_dma_ops,
.pcm_new = nuc900_dma_new,
.pcm_free = nuc900_dma_free_dma_buffers,
-}
+};
static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
{
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index d542ea2ff6be..a088db6d5091 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -12,8 +12,8 @@ config SND_OMAP_SOC_MCPDM
config SND_OMAP_SOC_N810
tristate "SoC Audio support for Nokia N810"
depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
+ depends on OMAP_MUX
select SND_OMAP_SOC_MCBSP
- select OMAP_MUX
select SND_SOC_TLV320AIC3X
help
Say Y if you want to add support for SoC audio on Nokia N810.
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 979dd508305f..161750443ebc 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -114,20 +113,21 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add am3517-evm specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up davinci-evm specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic In");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 438146addbb8..2101bdcee21f 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -26,7 +26,7 @@
#include <linux/spinlock.h>
#include <linux/tty.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -94,6 +94,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
unsigned short pins;
int pin, changed = 0;
@@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
/* Setup pins after corresponding bits if changed */
pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
else
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
}
pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
else
- snd_soc_dapm_disable_pin(codec, "Earpiece");
+ snd_soc_dapm_disable_pin(dapm, "Earpiece");
}
pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Microphone");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
else
- snd_soc_dapm_disable_pin(codec, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Microphone");
}
pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
- if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) {
+ if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
}
pin = !!(pins & (1 << AMS_DELTA_AGC));
if (pin != ams_delta_audio_agc) {
ams_delta_audio_agc = pin;
changed = 1;
if (pin)
- snd_soc_dapm_enable_pin(codec, "AGCIN");
+ snd_soc_dapm_enable_pin(dapm, "AGCIN");
else
- snd_soc_dapm_disable_pin(codec, "AGCIN");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
}
if (changed)
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
mutex_unlock(&codec->mutex);
@@ -164,19 +165,20 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned short pins, mode;
- pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") <<
+ pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
AMS_DELTA_MOUTHPIECE) |
- (snd_soc_dapm_get_pin_status(codec, "Earpiece") <<
+ (snd_soc_dapm_get_pin_status(dapm, "Earpiece") <<
AMS_DELTA_EARPIECE));
if (pins)
- pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+ pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
AMS_DELTA_MICROPHONE);
else
- pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+ pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
AMS_DELTA_MICROPHONE) |
- (snd_soc_dapm_get_pin_status(codec, "Speaker") <<
+ (snd_soc_dapm_get_pin_status(dapm, "Speaker") <<
AMS_DELTA_SPEAKER) |
(ams_delta_audio_agc << AMS_DELTA_AGC));
@@ -300,6 +302,7 @@ static int cx81801_open(struct tty_struct *tty)
static void cx81801_close(struct tty_struct *tty)
{
struct snd_soc_codec *codec = tty->disc_data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
del_timer_sync(&cx81801_timer);
@@ -312,12 +315,12 @@ static void cx81801_close(struct tty_struct *tty)
v253_ops.close(tty);
/* Revert back to default audio input/output constellation */
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
- snd_soc_dapm_enable_pin(codec, "Earpiece");
- snd_soc_dapm_enable_pin(codec, "Microphone");
- snd_soc_dapm_disable_pin(codec, "Speaker");
- snd_soc_dapm_disable_pin(codec, "AGCIN");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
+ snd_soc_dapm_sync(dapm);
}
/* Line discipline .hangup() */
@@ -432,16 +435,16 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card,
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY:
- if (codec->bias_level == SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
AMS_DELTA_LATCH2_MODEM_NRESET);
break;
case SND_SOC_BIAS_OFF:
- if (codec->bias_level != SND_SOC_BIAS_OFF)
+ if (codec->dapm.bias_level != SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
0);
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
return 0;
}
@@ -492,6 +495,7 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_card *card = rtd->card;
int ret;
@@ -541,7 +545,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Add board specific DAPM widgets and routes */
- ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
ARRAY_SIZE(ams_delta_dapm_widgets));
if (ret) {
dev_warn(card->dev,
@@ -550,7 +554,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
- ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map,
+ ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
ARRAY_SIZE(ams_delta_audio_map));
if (ret) {
dev_warn(card->dev,
@@ -560,13 +564,13 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Set up initial pin constellation */
- snd_soc_dapm_disable_pin(codec, "Mouthpiece");
- snd_soc_dapm_enable_pin(codec, "Earpiece");
- snd_soc_dapm_enable_pin(codec, "Microphone");
- snd_soc_dapm_disable_pin(codec, "Speaker");
- snd_soc_dapm_disable_pin(codec, "AGCIN");
- snd_soc_dapm_disable_pin(codec, "AGCOUT");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+ snd_soc_dapm_enable_pin(dapm, "Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Microphone");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "AGCIN");
+ snd_soc_dapm_disable_pin(dapm, "AGCOUT");
+ snd_soc_dapm_sync(dapm);
/* Add virtual switch */
ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index fd3a40f309c8..0ae34702995b 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a3b6d897ad84..fe215f3e8afc 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -27,7 +27,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -58,6 +57,7 @@ static int n810_dmic_func;
static void n810_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int hp = 0, line1l = 0;
switch (n810_jack_func) {
@@ -72,25 +72,25 @@ static void n810_ext_control(struct snd_soc_codec *codec)
}
if (n810_spk_func)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
if (hp)
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
else
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
if (line1l)
- snd_soc_dapm_enable_pin(codec, "LINE1L");
+ snd_soc_dapm_enable_pin(dapm, "LINE1L");
else
- snd_soc_dapm_disable_pin(codec, "LINE1L");
+ snd_soc_dapm_disable_pin(dapm, "LINE1L");
if (n810_dmic_func)
- snd_soc_dapm_enable_pin(codec, "DMic");
+ snd_soc_dapm_enable_pin(dapm, "DMic");
else
- snd_soc_dapm_disable_pin(codec, "DMic");
+ snd_soc_dapm_disable_pin(dapm, "DMic");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int n810_startup(struct snd_pcm_substream *substream)
@@ -274,17 +274,18 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Not connected */
- snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
- snd_soc_dapm_nc_pin(codec, "HPLCOM");
- snd_soc_dapm_nc_pin(codec, "HPRCOM");
- snd_soc_dapm_nc_pin(codec, "MIC3L");
- snd_soc_dapm_nc_pin(codec, "MIC3R");
- snd_soc_dapm_nc_pin(codec, "LINE1R");
- snd_soc_dapm_nc_pin(codec, "LINE2L");
- snd_soc_dapm_nc_pin(codec, "LINE2R");
+ snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_nc_pin(dapm, "HPLCOM");
+ snd_soc_dapm_nc_pin(dapm, "HPRCOM");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L");
+ snd_soc_dapm_nc_pin(dapm, "MIC3R");
+ snd_soc_dapm_nc_pin(dapm, "LINE1R");
+ snd_soc_dapm_nc_pin(dapm, "LINE2L");
+ snd_soc_dapm_nc_pin(dapm, "LINE2R");
/* Add N810 specific controls */
err = snd_soc_add_controls(codec, aic33_n810_controls,
@@ -293,13 +294,13 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add N810 specific widgets */
- snd_soc_dapm_new_controls(codec, aic33_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets,
ARRAY_SIZE(aic33_dapm_widgets));
/* Set up N810 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index cf3fc8a675b5..29b60d6796e7 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index e56832b0c444..40db813c0795 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 810f1e36da21..0daa04469836 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 4ee33ce2cb98..8047c521e318 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -28,7 +28,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <plat/mcbsp.h>
@@ -170,51 +169,53 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* All TWL4030 output pins are floating */
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "HSOL");
- snd_soc_dapm_nc_pin(codec, "HSOR");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
- snd_soc_dapm_nc_pin(codec, "HFL");
- snd_soc_dapm_nc_pin(codec, "HFR");
- snd_soc_dapm_nc_pin(codec, "VIBRA");
-
- ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "HSOL");
+ snd_soc_dapm_nc_pin(dapm, "HSOR");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+ snd_soc_dapm_nc_pin(dapm, "HFL");
+ snd_soc_dapm_nc_pin(dapm, "HFR");
+ snd_soc_dapm_nc_pin(dapm, "VIBRA");
+
+ ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets,
ARRAY_SIZE(omap3pandora_out_dapm_widgets));
if (ret < 0)
return ret;
- snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
+ snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
ARRAY_SIZE(omap3pandora_out_map));
- return snd_soc_dapm_sync(codec);
+ return snd_soc_dapm_sync(dapm);
}
static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Not comnnected */
- snd_soc_dapm_nc_pin(codec, "HSMIC");
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
+ snd_soc_dapm_nc_pin(dapm, "HSMIC");
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
- ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets,
ARRAY_SIZE(omap3pandora_in_dapm_widgets));
if (ret < 0)
return ret;
- snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
+ snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
ARRAY_SIZE(omap3pandora_in_map));
- return snd_soc_dapm_sync(codec);
+ return snd_soc_dapm_sync(dapm);
}
static struct snd_soc_ops omap3pandora_ops = {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 65ae00e976ef..7e75e775fb4a 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -116,19 +115,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add osk5912 specific widgets */
- snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up osk5912 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index e95a607937de..bbcf380bfb56 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 04b5723bf89b..150042a785d0 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -30,7 +30,6 @@
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/mcbsp.h>
#include <asm/mach-types.h>
@@ -58,19 +57,21 @@ static int rx51_jack_func;
static void rx51_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (rx51_spk_func)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
if (rx51_dmic_func)
- snd_soc_dapm_enable_pin(codec, "DMic");
+ snd_soc_dapm_enable_pin(dapm, "DMic");
else
- snd_soc_dapm_disable_pin(codec, "DMic");
+ snd_soc_dapm_disable_pin(dapm, "DMic");
gpio_set_value(RX51_TVOUT_SEL_GPIO,
rx51_jack_func == RX51_JACK_TVOUT);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int rx51_startup(struct snd_pcm_substream *substream)
@@ -244,12 +245,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "MIC3L");
- snd_soc_dapm_nc_pin(codec, "MIC3R");
- snd_soc_dapm_nc_pin(codec, "LINE1R");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L");
+ snd_soc_dapm_nc_pin(dapm, "MIC3R");
+ snd_soc_dapm_nc_pin(dapm, "LINE1R");
/* Add RX-51 specific controls */
err = snd_soc_add_controls(codec, aic34_rx51_controls,
@@ -258,13 +260,13 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add RX-51 specific widgets */
- snd_soc_dapm_new_controls(codec, aic34_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
ARRAY_SIZE(aic34_dapm_widgets));
/* Set up RX-51 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
/* AV jack detection */
err = snd_soc_jack_new(codec, "AV Jack",
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 07fbcf7d2411..3f72d17d1ef0 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -28,7 +28,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -191,39 +190,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add SDP3430 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets,
ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
if (ret)
return ret;
/* Set up SDP3430 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* SDP3430 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
/* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(codec, "AUXL");
- snd_soc_dapm_nc_pin(codec, "AUXR");
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
-
- snd_soc_dapm_nc_pin(codec, "OUTL");
- snd_soc_dapm_nc_pin(codec, "OUTR");
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
-
- ret = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "AUXL");
+ snd_soc_dapm_nc_pin(dapm, "AUXR");
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
+
+ snd_soc_dapm_nc_pin(dapm, "OUTL");
+ snd_soc_dapm_nc_pin(dapm, "OUTR");
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 4b4463db6ba0..189e03900637 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -24,7 +24,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
+#include <sound/jack.h>
#include <asm/mach-types.h>
#include <plat/hardware.h>
@@ -66,6 +66,21 @@ static struct snd_soc_ops sdp4430_ops = {
.hw_params = sdp4430_hw_params,
};
+/* Headset jack */
+static struct snd_soc_jack hs_jack;
+
+/*Headset jack detection DAPM pins */
+static struct snd_soc_jack_pin hs_jack_pins[] = {
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+ {
+ .pin = "Headset Stereophone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+};
+
static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -102,6 +117,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
SND_SOC_DAPM_SPK("Earphone Spk", NULL),
+ SND_SOC_DAPM_INPUT("Aux/FM Stereo In"),
};
static const struct snd_soc_dapm_route audio_map[] = {
@@ -124,11 +140,16 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Earphone speaker */
{"Earphone Spk", NULL, "EP"},
+
+ /* Aux/FM Stereo In: AFML, AFMR */
+ {"AFML", NULL, "Aux/FM Stereo In"},
+ {"AFMR", NULL, "Aux/FM Stereo In"},
};
static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add SDP4430 specific controls */
@@ -138,25 +159,39 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
return ret;
/* Add SDP4430 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
if (ret)
return ret;
/* Set up SDP4430 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* SDP4430 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "AFML");
+ snd_soc_dapm_enable_pin(dapm, "AFMR");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
+
+ ret = snd_soc_dapm_sync(dapm);
+ if (ret)
+ return ret;
+
+ /* Headset jack detection */
+ ret = snd_soc_jack_new(codec, "Headset Jack",
+ SND_JACK_HEADSET, &hs_jack);
+ if (ret)
+ return ret;
- /* TWL6040 not connected pins */
- snd_soc_dapm_nc_pin(codec, "AFML");
- snd_soc_dapm_nc_pin(codec, "AFMR");
+ ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
+ hs_jack_pins);
- ret = snd_soc_dapm_sync(codec);
+ if (machine_is_omap_4430sdp())
+ twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
+ else
+ snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET);
return ret;
}
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 718031eeac34..01709940a43c 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -24,7 +24,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
@@ -162,35 +161,36 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* Add Zoom2 specific widgets */
- ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets,
+ ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets,
ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
if (ret)
return ret;
/* Set up Zoom2 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* Zoom2 connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Mic");
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
- snd_soc_dapm_enable_pin(codec, "Aux In");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Aux In");
/* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(codec, "CARKITMIC");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
- snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
- snd_soc_dapm_nc_pin(codec, "EARPIECE");
- snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
- snd_soc_dapm_nc_pin(codec, "PREDRIVER");
- snd_soc_dapm_nc_pin(codec, "CARKITL");
- snd_soc_dapm_nc_pin(codec, "CARKITR");
-
- ret = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
+ snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
+ snd_soc_dapm_nc_pin(dapm, "EARPIECE");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
+ snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
+ snd_soc_dapm_nc_pin(dapm, "CARKITL");
+ snd_soc_dapm_nc_pin(dapm, "CARKITR");
+
+ ret = snd_soc_dapm_sync(dapm);
return ret;
}
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index f451acd4935b..fc592f0d5fc7 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/corgi.h>
@@ -48,51 +47,53 @@ static int corgi_spk_func;
static void corgi_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
switch (corgi_jack_func) {
case CORGI_HP:
/* set = unmute headphone */
gpio_set_value(CORGI_GPIO_MUTE_L, 1);
gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_MIC:
/* reset = mute headphone */
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_LINE:
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case CORGI_HEADSET:
gpio_set_value(CORGI_GPIO_MUTE_L, 0);
gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
break;
}
if (corgi_spk_func == CORGI_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int corgi_startup(struct snd_pcm_substream *substream)
@@ -279,10 +280,11 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
/* Add corgi specific controls */
err = snd_soc_add_controls(codec, wm8731_corgi_controls,
@@ -291,13 +293,13 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add corgi specific widgets */
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
ARRAY_SIZE(wm8731_dapm_widgets));
/* Set up corgi specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index c82cedb602fd..28333e7d9c50 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audio.h>
#include <mach/eseries-gpio.h>
@@ -92,23 +91,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
-
- snd_soc_dapm_nc_pin(codec, "HPOUTL");
- snd_soc_dapm_nc_pin(codec, "HPOUTR");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "CDINL");
- snd_soc_dapm_nc_pin(codec, "CDINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- snd_soc_dapm_new_controls(codec, e740_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_nc_pin(dapm, "HPOUTL");
+ snd_soc_dapm_nc_pin(dapm, "HPOUTR");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "CDINL");
+ snd_soc_dapm_nc_pin(dapm, "CDINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ snd_soc_dapm_new_controls(dapm, e740_dapm_widgets,
ARRAY_SIZE(e740_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 4c143803a75e..01bf31675c55 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <mach/audio.h>
#include <mach/eseries-gpio.h>
@@ -74,23 +73,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
-
- snd_soc_dapm_nc_pin(codec, "LOUT");
- snd_soc_dapm_nc_pin(codec, "ROUT");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "CDINL");
- snd_soc_dapm_nc_pin(codec, "CDINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- snd_soc_dapm_new_controls(codec, e750_dapm_widgets,
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_dapm_nc_pin(dapm, "LOUT");
+ snd_soc_dapm_nc_pin(dapm, "ROUT");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "CDINL");
+ snd_soc_dapm_nc_pin(dapm, "CDINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ snd_soc_dapm_new_controls(dapm, e750_dapm_widgets,
ARRAY_SIZE(e750_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index d42e5fe832c5..c6a37c6ef23b 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -16,7 +16,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/audio.h>
@@ -75,12 +74,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, e800_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, e800_dapm_widgets,
ARRAY_SIZE(e800_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index eadf9d351a04..fc22e6eefc98 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/audio.h>
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 5ef0526924b9..67dcc36cd621 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -26,7 +26,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/uda1380.h>
#include <mach/magician.h>
@@ -44,27 +43,29 @@ static int magician_in_sel = MAGICIAN_MIC;
static void magician_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (magician_spk_switch)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
if (magician_hp_switch)
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
else
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
switch (magician_in_sel) {
case MAGICIAN_MIC:
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case MAGICIAN_MIC_EXT:
- snd_soc_dapm_disable_pin(codec, "Call Mic");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
break;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int magician_startup(struct snd_pcm_substream *substream)
@@ -399,15 +400,16 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* NC codec pins */
- snd_soc_dapm_nc_pin(codec, "VOUTLHP");
- snd_soc_dapm_nc_pin(codec, "VOUTRHP");
+ snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
+ snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
/* FIXME: is anything connected here? */
- snd_soc_dapm_nc_pin(codec, "VINL");
- snd_soc_dapm_nc_pin(codec, "VINR");
+ snd_soc_dapm_nc_pin(dapm, "VINL");
+ snd_soc_dapm_nc_pin(dapm, "VINR");
/* Add magician specific controls */
err = snd_soc_add_controls(codec, uda1380_magician_controls,
@@ -416,13 +418,13 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add magician specific widgets */
- snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
ARRAY_SIZE(uda1380_dapm_widgets));
/* Set up magician specific audio path interconnects */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index f284cc54bc80..0d70fc8c12bd 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -50,7 +50,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/ac97_codec.h>
@@ -130,13 +129,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned short reg;
/* Add mioa701 specific widgets */
- snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets));
+ snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
/* Set up mioa701 specific audio path audio_mapnects */
- snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
/* Prepare GPIO8 for rear speaker amplifier */
reg = codec->driver->read(codec, AC97_GPIO_CFG);
@@ -146,12 +146,12 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
reg = codec->driver->read(codec, AC97_3D_CONTROL);
codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
- snd_soc_dapm_enable_pin(codec, "Front Speaker");
- snd_soc_dapm_enable_pin(codec, "Rear Speaker");
- snd_soc_dapm_enable_pin(codec, "Front Mic");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_enable_pin(dapm, "Front Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Rear Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Front Mic");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 13f6d485d571..857db96d4a4f 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -77,37 +76,38 @@ static struct snd_soc_card palm27x_asoc;
static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* add palm27x specific widgets */
- err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
ARRAY_SIZE(palm27x_dapm_widgets));
if (err)
return err;
/* set up palm27x specific audio path audio_map */
- err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (err)
return err;
/* connected pins */
if (machine_is_palmld())
- snd_soc_dapm_enable_pin(codec, "MIC1");
- snd_soc_dapm_enable_pin(codec, "HPOUTL");
- snd_soc_dapm_enable_pin(codec, "HPOUTR");
- snd_soc_dapm_enable_pin(codec, "LOUT2");
- snd_soc_dapm_enable_pin(codec, "ROUT2");
+ snd_soc_dapm_enable_pin(dapm, "MIC1");
+ snd_soc_dapm_enable_pin(dapm, "HPOUTL");
+ snd_soc_dapm_enable_pin(dapm, "HPOUTR");
+ snd_soc_dapm_enable_pin(dapm, "LOUT2");
+ snd_soc_dapm_enable_pin(dapm, "ROUT2");
/* not connected pins */
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONOOUT");
- snd_soc_dapm_nc_pin(codec, "LINEINL");
- snd_soc_dapm_nc_pin(codec, "LINEINR");
- snd_soc_dapm_nc_pin(codec, "PCBEEP");
- snd_soc_dapm_nc_pin(codec, "PHONE");
- snd_soc_dapm_nc_pin(codec, "MIC2");
-
- err = snd_soc_dapm_sync(codec);
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONOOUT");
+ snd_soc_dapm_nc_pin(dapm, "LINEINL");
+ snd_soc_dapm_nc_pin(dapm, "LINEINR");
+ snd_soc_dapm_nc_pin(dapm, "PCBEEP");
+ snd_soc_dapm_nc_pin(dapm, "PHONE");
+ snd_soc_dapm_nc_pin(dapm, "MIC2");
+
+ err = snd_soc_dapm_sync(dapm);
if (err)
return err;
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 84edd0385a21..6298ee115e27 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <asm/hardware/locomo.h>
@@ -46,6 +45,8 @@ static int poodle_spk_func;
static void poodle_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
if (poodle_jack_func == POODLE_HP) {
/* set = unmute headphone */
@@ -53,23 +54,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
POODLE_LOCOMO_GPIO_MUTE_L, 1);
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
} else {
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_L, 0);
locomo_gpio_write(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
}
/* set the enpoints to their new connetion states */
if (poodle_spk_func == POODLE_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int poodle_startup(struct snd_pcm_substream *substream)
@@ -244,11 +245,12 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "LLINEIN");
- snd_soc_dapm_nc_pin(codec, "RLINEIN");
- snd_soc_dapm_enable_pin(codec, "MICIN");
+ snd_soc_dapm_nc_pin(dapm, "LLINEIN");
+ snd_soc_dapm_nc_pin(dapm, "RLINEIN");
+ snd_soc_dapm_enable_pin(dapm, "MICIN");
/* Add poodle specific controls */
err = snd_soc_add_controls(codec, wm8731_poodle_controls,
@@ -257,13 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add poodle specific widgets */
- snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
ARRAY_SIZE(wm8731_dapm_widgets));
/* Set up poodle specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 2cda82bc5d2e..0fd60f423036 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -22,7 +22,6 @@
#include <linux/gpio.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index d63cb474b4e1..9595189fc681 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_saarb = {
static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_new_controls(codec, saarb_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets,
ARRAY_SIZE(saarb_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Speaker");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 1");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 3");
- snd_soc_dapm_disable_pin(codec, "Headset Mic 2");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 0b30d7de24ec..c2acb69b957a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/spitz.h>
@@ -46,61 +45,63 @@ static int spitz_spk_func;
static void spitz_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
if (spitz_spk_func == SPITZ_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
/* set up jack connection */
switch (spitz_jack_func) {
case SPITZ_HP:
/* enable and unmute hp jack, disable mic bias */
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
break;
case SPITZ_MIC:
/* enable mic jack and bias, mute hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
case SPITZ_LINE:
/* enable line jack, disable mic bias and mute hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
case SPITZ_HEADSET:
/* enable and unmute headset jack enable mic bias, mute L hp */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
break;
case SPITZ_HP_OFF:
/* jack removed, everything off */
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin(dapm, "Line Jack");
gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
break;
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int spitz_startup(struct snd_pcm_substream *substream)
@@ -281,16 +282,17 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* NC codec pins */
- snd_soc_dapm_nc_pin(codec, "RINPUT1");
- snd_soc_dapm_nc_pin(codec, "LINPUT2");
- snd_soc_dapm_nc_pin(codec, "RINPUT2");
- snd_soc_dapm_nc_pin(codec, "LINPUT3");
- snd_soc_dapm_nc_pin(codec, "RINPUT3");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONO1");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONO1");
/* Add spitz specific controls */
err = snd_soc_add_controls(codec, wm8750_spitz_controls,
@@ -299,13 +301,13 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* Add spitz specific widgets */
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
/* Set up spitz specific audio paths */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index 248c283fc4df..f881f65ec172 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -18,7 +18,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_evb3 = {
static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- snd_soc_dapm_new_controls(codec, evb3_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets,
ARRAY_SIZE(evb3_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
- snd_soc_dapm_enable_pin(codec, "Ext Speaker");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 1");
- snd_soc_dapm_enable_pin(codec, "Ext Mic 3");
- snd_soc_dapm_disable_pin(codec, "Headset Mic 2");
- snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
+ snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
+ snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
+ snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
return ret;
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 7b983f935454..f75804ef0897 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/tosa.h>
@@ -49,31 +48,33 @@ static int tosa_spk_func;
static void tosa_ext_control(struct snd_soc_codec *codec)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
/* set up jack connection */
switch (tosa_jack_func) {
case TOSA_HP:
- snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case TOSA_MIC_INT:
- snd_soc_dapm_enable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
+ snd_soc_dapm_enable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin(dapm, "Headset Jack");
break;
case TOSA_HEADSET:
- snd_soc_dapm_disable_pin(codec, "Mic (Internal)");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
+ snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headset Jack");
break;
}
if (tosa_spk_func == TOSA_SPK_ON)
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
else
- snd_soc_dapm_disable_pin(codec, "Speaker");
+ snd_soc_dapm_disable_pin(dapm, "Speaker");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
}
static int tosa_startup(struct snd_pcm_substream *substream)
@@ -191,10 +192,11 @@ static const struct snd_kcontrol_new tosa_controls[] = {
static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONOOUT");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONOOUT");
/* add tosa specific controls */
err = snd_soc_add_controls(codec, tosa_controls,
@@ -203,13 +205,13 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* add tosa specific widgets */
- snd_soc_dapm_new_controls(codec, tosa_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
ARRAY_SIZE(tosa_dapm_widgets));
/* set up tosa specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4cc841b44182..2d4f896d7fec 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
@@ -140,22 +139,23 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* NC codec pins */
- snd_soc_dapm_disable_pin(codec, "LINPUT3");
- snd_soc_dapm_disable_pin(codec, "RINPUT3");
- snd_soc_dapm_disable_pin(codec, "OUT3");
- snd_soc_dapm_disable_pin(codec, "MONO");
+ snd_soc_dapm_disable_pin(dapm, "LINPUT3");
+ snd_soc_dapm_disable_pin(dapm, "RINPUT3");
+ snd_soc_dapm_disable_pin(dapm, "OUT3");
+ snd_soc_dapm_disable_pin(dapm, "MONO");
/* Add z2 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
/* Set up z2 specific audio paths */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- ret = snd_soc_dapm_sync(codec);
+ ret = snd_soc_dapm_sync(dapm);
if (ret)
goto err;
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index d27e05af7759..b222a7d72027 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -20,7 +20,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "../codecs/wm9713.h"
#include "pxa2xx-ac97.h"
@@ -73,21 +72,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
if (clk_pout)
snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
clk_get_rate(pout), 0);
- snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
ARRAY_SIZE(zylonite_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* Static setup for now */
- snd_soc_dapm_enable_pin(codec, "Headphone");
- snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
+ snd_soc_dapm_enable_pin(dapm, "Headphone");
+ snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
deleted file mode 100644
index d85bf8a0abb2..000000000000
--- a/sound/soc/s3c24xx/Kconfig
+++ /dev/null
@@ -1,171 +0,0 @@
-config SND_S3C24XX_SOC
- tristate "SoC Audio for the Samsung S3CXXXX chips"
- depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
- select S3C64XX_DMA if ARCH_S3C64XX
- select S3C2410_DMA if ARCH_S3C2410
- help
- Say Y or M if you want to add support for codecs attached to
- the S3C24XX AC97 or I2S interfaces. You will also need to
- select the audio interfaces to support below.
-
-config SND_S3C24XX_SOC_I2S
- tristate
- select S3C2410_DMA
-
-config SND_S3C_I2SV2_SOC
- tristate
-
-config SND_S3C2412_SOC_I2S
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C2410_DMA
-
-config SND_S3C64XX_SOC_I2S
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C64XX_DMA
-
-config SND_S3C64XX_SOC_I2S_V4
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C64XX_DMA
-
-config SND_S3C_SOC_PCM
- tristate
-
-config SND_S3C_SOC_AC97
- tristate
- select SND_SOC_AC97_BUS
-
-config SND_S5P_SOC_SPDIF
- tristate
- select SND_SOC_SPDIF
-
-config SND_S3C24XX_SOC_NEO1973_WM8753
- tristate "SoC I2S Audio support for NEO1973 - WM8753"
- depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_WM8753
- help
- Say Y if you want to add support for SoC audio on smdk2440
- with the WM8753.
-
-config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753
- tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
- depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_WM8753
- help
- This driver provides audio support for the Openmoko Neo FreeRunner
- smartphone.
-
-config SND_S3C24XX_SOC_JIVE_WM8750
- tristate "SoC I2S Audio support for Jive"
- depends on SND_S3C24XX_SOC && MACH_JIVE
- select SND_SOC_WM8750
- select SND_S3C2412_SOC_I2S
- help
- Sat Y if you want to add support for SoC audio on the Jive.
-
-config SND_S3C64XX_SOC_WM8580
- tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
- depends on SND_S3C24XX_SOC && MACH_SMDK6410
- select SND_SOC_WM8580
- select SND_S3C64XX_SOC_I2S_V4
- help
- Say Y if you want to add support for SoC audio on the SMDK6410.
-
-config SND_S3C24XX_SOC_SMDK2443_WM9710
- tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
- depends on SND_S3C24XX_SOC && MACH_SMDK2443
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_S3C_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on smdk2443
- with the WM9710.
-
-config SND_S3C24XX_SOC_LN2440SBC_ALC650
- tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_S3C_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on ln2440sbc
- with the ALC650.
-
-config SND_S3C24XX_SOC_S3C24XX_UDA134X
- tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_L3
- select SND_SOC_UDA134X
-
-config SND_S3C24XX_SOC_SIMTEC
- tristate
- help
- Internal node for common S3C24XX/Simtec suppor
-
-config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23
- tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_TLV320AIC23
- select SND_S3C24XX_SOC_SIMTEC
-
-config SND_S3C24XX_SOC_SIMTEC_HERMES
- tristate "SoC I2S Audio support for Simtec Hermes board"
- depends on SND_S3C24XX_SOC && ARCH_S3C2410
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_TLV320AIC3X
- select SND_S3C24XX_SOC_SIMTEC
-
-config SND_S3C24XX_SOC_RX1950_UDA1380
- tristate "Audio support for the HP iPAQ RX1950"
- depends on SND_S3C24XX_SOC && MACH_RX1950
- select SND_S3C24XX_SOC_I2S
- select SND_SOC_UDA1380
- help
- This driver provides audio support for HP iPAQ RX1950 PDA.
-
-config SND_SOC_SMDK_WM9713
- tristate "SoC AC97 Audio support for SMDK with WM9713"
- depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
- select SND_SOC_WM9713
- select SND_S3C_SOC_AC97
- help
- Sat Y if you want to add support for SoC audio on the SMDK.
-
-config SND_S3C64XX_SOC_SMARTQ
- tristate "SoC I2S Audio support for SmartQ board"
- depends on SND_S3C24XX_SOC && MACH_SMARTQ
- select SND_S3C64XX_SOC_I2S
- select SND_SOC_WM8750
-
-config SND_S5PC110_SOC_AQUILA_WM8994
- tristate "SoC I2S Audio support for AQUILA - WM8994"
- depends on SND_S3C24XX_SOC && MACH_AQUILA
- select SND_S3C64XX_SOC_I2S_V4
- select SND_SOC_WM8994
- help
- Say Y if you want to add support for SoC audio on aquila
- with the WM8994.
-
-config SND_S5PV210_SOC_GONI_WM8994
- tristate "SoC I2S Audio support for GONI - WM8994"
- depends on SND_S3C24XX_SOC && MACH_GONI
- select SND_S3C64XX_SOC_I2S_V4
- select SND_SOC_WM8994
- help
- Say Y if you want to add support for SoC audio on goni
- with the WM8994.
-
-config SND_SOC_SMDK_SPDIF
- tristate "SoC S/PDIF Audio support for SMDK"
- depends on SND_S3C24XX_SOC && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
- select SND_S5P_SOC_SPDIF
- help
- Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
deleted file mode 100644
index ee8f41d6df99..000000000000
--- a/sound/soc/s3c24xx/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# S3c24XX Platform Support
-snd-soc-s3c24xx-objs := s3c-dma.o
-snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
-snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
-snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
-snd-soc-s3c-ac97-objs := s3c-ac97.o
-snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o
-snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
-snd-soc-s3c-pcm-objs := s3c-pcm.o
-snd-soc-samsung-spdif-objs := spdif.o
-
-obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
-obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
-obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
-obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
-obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
-obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o
-obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
-obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
-obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o
-
-# S3C24XX Machine Support
-snd-soc-jive-wm8750-objs := jive_wm8750.o
-snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
-snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
-snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
-snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
-snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
-snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
-snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
-snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
-snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
-snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
-snd-soc-smdk-wm9713-objs := smdk_wm9713.o
-snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
-snd-soc-aquila-wm8994-objs := aquila_wm8994.o
-snd-soc-goni-wm8994-objs := goni_wm8994.o
-snd-soc-smdk-spdif-objs := smdk_spdif.o
-
-obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
-obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
-obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
-obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
-obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
-obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
-obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
-obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
-obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
-obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
-obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o
-obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o
-obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o
diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c
deleted file mode 100644
index 235d1973f7d0..000000000000
--- a/sound/soc/s3c24xx/aquila_wm8994.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * aquila_wm8994.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <asm/mach-types.h>
-#include <mach/gpio.h>
-#include <mach/regs-clock.h>
-
-#include <linux/mfd/wm8994/core.h>
-#include <linux/mfd/wm8994/registers.h>
-#include "../codecs/wm8994.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
-
-static struct snd_soc_card aquila;
-static struct platform_device *aquila_snd_device;
-
-/* 3.5 pie jack */
-static struct snd_soc_jack jack;
-
-/* 3.5 pie jack detection DAPM pins */
-static struct snd_soc_jack_pin jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- }, {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- },
-};
-
-/* 3.5 pie jack detection gpios */
-static struct snd_soc_jack_gpio jack_gpios[] = {
- {
- .gpio = S5PV210_GPH0(6),
- .name = "DET_3.5",
- .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- .debounce_time = 200,
- },
-};
-
-static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_SPK("Ext Rcv", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Main Mic", NULL),
- SND_SOC_DAPM_MIC("2nd Mic", NULL),
- SND_SOC_DAPM_LINE("Radio In", NULL),
-};
-
-static const struct snd_soc_dapm_route aquila_dapm_routes[] = {
- {"Ext Spk", NULL, "SPKOUTLP"},
- {"Ext Spk", NULL, "SPKOUTLN"},
-
- {"Ext Rcv", NULL, "HPOUT2N"},
- {"Ext Rcv", NULL, "HPOUT2P"},
-
- {"Headset Stereophone", NULL, "HPOUT1L"},
- {"Headset Stereophone", NULL, "HPOUT1R"},
-
- {"IN1RN", NULL, "Headset Mic"},
- {"IN1RP", NULL, "Headset Mic"},
-
- {"IN1RN", NULL, "2nd Mic"},
- {"IN1RP", NULL, "2nd Mic"},
-
- {"IN1LN", NULL, "Main Mic"},
- {"IN1LP", NULL, "Main Mic"},
-
- {"IN2LN", NULL, "Radio In"},
- {"IN2RN", NULL, "Radio In"},
-};
-
-static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- int ret;
-
- /* add aquila specific widgets */
- snd_soc_dapm_new_controls(codec, aquila_dapm_widgets,
- ARRAY_SIZE(aquila_dapm_widgets));
-
- /* set up aquila specific audio routes */
- snd_soc_dapm_add_routes(codec, aquila_dapm_routes,
- ARRAY_SIZE(aquila_dapm_routes));
-
- /* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
- snd_soc_dapm_nc_pin(codec, "SPKOUTRN");
- snd_soc_dapm_nc_pin(codec, "SPKOUTRP");
-
- snd_soc_dapm_sync(codec);
-
- /* Headset jack detection */
- ret = snd_soc_jack_new(&aquila, "Headset Jack",
- SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
- &jack);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int aquila_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- /* set the cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the cpu system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops aquila_hifi_ops = {
- .hw_params = aquila_hifi_hw_params,
-};
-
-static int aquila_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- if (params_rate(params) != 8000)
- return -EINVAL;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_dai_driver voice_dai = {
- .name = "aquila-voice-dai",
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-};
-
-static struct snd_soc_ops aquila_voice_ops = {
- .hw_params = aquila_voice_hw_params,
-};
-
-static struct snd_soc_dai_link aquila_dai[] = {
-{
- .name = "WM8994",
- .stream_name = "WM8994 HiFi",
- .cpu_dai_name = "s3c64xx-i2s-v4",
- .codec_dai_name = "wm8994-hifi",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8994-codec.0-0x1a",
- .init = aquila_wm8994_init,
- .ops = &aquila_hifi_ops,
-}, {
- .name = "WM8994 Voice",
- .stream_name = "Voice",
- .cpu_dai_name = "aquila-voice-dai",
- .codec_dai_name = "wm8994-voice",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8994-codec.0-0x1a",
- .ops = &aquila_voice_ops,
-},
-};
-
-static struct snd_soc_card aquila = {
- .name = "aquila",
- .dai_link = aquila_dai,
- .num_links = ARRAY_SIZE(aquila_dai),
-};
-
-static int __init aquila_init(void)
-{
- int ret;
-
- if (!machine_is_aquila())
- return -ENODEV;
-
- aquila_snd_device = platform_device_alloc("soc-audio", -1);
- if (!aquila_snd_device)
- return -ENOMEM;
-
- /* register voice DAI here */
- ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai);
- if (ret)
- return ret;
-
- platform_set_drvdata(aquila_snd_device, &aquila);
- ret = platform_device_add(aquila_snd_device);
-
- if (ret)
- platform_device_put(aquila_snd_device);
-
- return ret;
-}
-
-static void __exit aquila_exit(void)
-{
- platform_device_unregister(aquila_snd_device);
-}
-
-module_init(aquila_init);
-module_exit(aquila_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)");
-MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
deleted file mode 100644
index a9628472ebfe..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c
- *
- * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver
- * Copyright (c) 2010 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.
- */
-
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include "s3c-dma.h"
-#include "regs-i2s-v2.h"
-#include "s3c64xx-i2s.h"
-
-static struct s3c2410_dma_client s3c64xx_dma_client_out = {
- .name = "I2Sv4 PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c64xx_dma_client_in = {
- .name = "I2Sv4 PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
-static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
-static struct s3c_i2sv2_info s3c64xx_i2sv4;
-
-static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
- int ret = 0;
-
- snd_soc_dai_set_drvdata(dai, i2s);
-
- ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
-
- return ret;
-}
-
-static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- struct s3c_dma_params *dma_data;
- u32 iismod;
-
- dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = i2s->dma_playback;
- else
- dma_data = i2s->dma_capture;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);
-
- iismod &= ~S3C64XX_IISMOD_BLC_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- iismod |= S3C64XX_IISMOD_BLC_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iismod |= S3C64XX_IISMOD_BLC_24BIT;
- break;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);
-
- return 0;
-}
-
-static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
- .hw_params = s3c_i2sv4_hw_params,
-};
-
-static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = {
- .symmetric_rates = 1,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,
- },
- .probe = s3c64xx_i2sv4_probe,
- .ops = &s3c64xx_i2sv4_dai_ops,
-};
-
-static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
-{
- struct s3c_audio_pdata *i2s_pdata;
- struct s3c_i2sv2_info *i2s;
- struct resource *res;
- int ret;
-
- i2s = &s3c64xx_i2sv4;
-
- i2s->feature |= S3C_FEATURE_CDCLKCON;
-
- i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
- i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_playback->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_capture->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(res->start, resource_size(res),
- "s3c64xx-i2s-v4")) {
- dev_err(&pdev->dev, "Unable to request SFR region\n");
- return -EBUSY;
- }
- i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
- i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
-
- i2s->dma_capture->client = &s3c64xx_dma_client_in;
- i2s->dma_capture->dma_size = 4;
- i2s->dma_playback->client = &s3c64xx_dma_client_out;
- i2s->dma_playback->dma_size = 4;
-
- i2s->base = res->start;
-
- i2s_pdata = pdev->dev.platform_data;
- if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- return -EINVAL;
- }
-
- i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
- if (IS_ERR(i2s->iis_cclk)) {
- dev_err(&pdev->dev, "failed to get audio-bus\n");
- ret = PTR_ERR(i2s->iis_cclk);
- goto err;
- }
-
- clk_enable(i2s->iis_cclk);
-
- ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai);
- if (ret != 0)
- goto err_i2sv2;
-
- return 0;
-
-err_i2sv2:
- clk_put(i2s->iis_cclk);
-err:
- return ret;
-}
-
-static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
-{
- struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
- struct resource *res;
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_put(i2s->iis_cclk);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- else
- dev_warn(&pdev->dev, "Unable to get I2S SFR address\n");
-
- return 0;
-}
-
-static struct platform_driver s3c64xx_i2sv4_driver = {
- .probe = s3c64xx_i2sv4_dev_probe,
- .remove = s3c64xx_i2sv4_dev_remove,
- .driver = {
- .name = "s3c64xx-iis-v4",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c64xx_i2sv4_init(void)
-{
- return platform_driver_register(&s3c64xx_i2sv4_driver);
-}
-module_init(s3c64xx_i2sv4_init);
-
-static void __exit s3c64xx_i2sv4_exit(void)
-{
- platform_driver_unregister(&s3c64xx_i2sv4_driver);
-}
-module_exit(s3c64xx_i2sv4_exit);
-
-/* Module information */
-MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
-MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c64xx-iis-v4");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
deleted file mode 100644
index ae7acb6c4f1d..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s.c
- *
- * ALSA SoC Audio Layer - S3C64XX I2S driver
- *
- * 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/module.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <sound/soc.h>
-
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include "s3c-dma.h"
-#include "regs-i2s-v2.h"
-#include "s3c64xx-i2s.h"
-
-/* The value should be set to maximum of the total number
- * of I2Sv3 controllers that any supported SoC has.
- */
-#define MAX_I2SV3 2
-
-static struct s3c2410_dma_client s3c64xx_dma_client_out = {
- .name = "I2S PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c64xx_dma_client_in = {
- .name = "I2S PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
-static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
-static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
-
-struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
- u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
-
- if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
- return i2s->iis_cclk;
- else
- return i2s->iis_pclk;
-}
-EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
-
-static int s3c64xx_i2s_probe(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s;
- int ret;
-
- if (dai->id >= MAX_I2SV3) {
- dev_err(dai->dev, "id %d out of range\n", dai->id);
- return -EINVAL;
- }
-
- i2s = &s3c64xx_i2s[dai->id];
- snd_soc_dai_set_drvdata(dai, i2s);
-
- i2s->iis_cclk = clk_get(dai->dev, "audio-bus");
- if (IS_ERR(i2s->iis_cclk)) {
- dev_err(dai->dev, "failed to get audio-bus\n");
- ret = PTR_ERR(i2s->iis_cclk);
- goto err;
- }
-
- clk_enable(i2s->iis_cclk);
-
- ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
- if (ret)
- goto err_clk;
-
- return 0;
-
-err_clk:
- clk_disable(i2s->iis_cclk);
- clk_put(i2s->iis_cclk);
-err:
- kfree(i2s);
- return ret;
-}
-
-static int s3c64xx_i2s_remove(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
-
- clk_disable(i2s->iis_cclk);
- clk_put(i2s->iis_cclk);
- kfree(i2s);
- return 0;
-}
-
-static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
-
-static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = {
-{
- .name = "s3c64xx-i2s-0",
- .probe = s3c64xx_i2s_probe,
- .remove = s3c64xx_i2s_remove,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .ops = &s3c64xx_i2s_dai_ops,
- .symmetric_rates = 1,
-}, {
- .name = "s3c64xx-i2s-1",
- .probe = s3c64xx_i2s_probe,
- .remove = s3c64xx_i2s_remove,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C64XX_I2S_RATES,
- .formats = S3C64XX_I2S_FMTS,},
- .ops = &s3c64xx_i2s_dai_ops,
- .symmetric_rates = 1,
-},};
-
-static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
-{
- struct s3c_audio_pdata *i2s_pdata;
- struct s3c_i2sv2_info *i2s;
- struct resource *res;
- int i, ret;
-
- if (pdev->id >= MAX_I2SV3) {
- dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
- return -EINVAL;
- }
-
- i2s = &s3c64xx_i2s[pdev->id];
-
- i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
- i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_playback->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
- return -ENXIO;
- }
- i2s->dma_capture->channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(res->start, resource_size(res),
- "s3c64xx-i2s")) {
- dev_err(&pdev->dev, "Unable to request SFR region\n");
- return -EBUSY;
- }
- i2s->base = res->start;
-
- i2s_pdata = pdev->dev.platform_data;
- if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- return -EINVAL;
- }
- i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
- i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
-
- i2s->dma_capture->client = &s3c64xx_dma_client_in;
- i2s->dma_capture->dma_size = 4;
- i2s->dma_playback->client = &s3c64xx_dma_client_out;
- i2s->dma_playback->dma_size = 4;
-
- for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) {
- ret = s3c_i2sv2_register_dai(&pdev->dev, i,
- &s3c64xx_i2s_dai[i]);
- if (ret != 0)
- return ret;
- }
-
- return 0;
-}
-
-static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai));
- return 0;
-}
-
-static struct platform_driver s3c64xx_iis_driver = {
- .probe = s3c64xx_iis_dev_probe,
- .remove = s3c64xx_iis_dev_remove,
- .driver = {
- .name = "s3c64xx-iis",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init s3c64xx_i2s_init(void)
-{
- return platform_driver_register(&s3c64xx_iis_driver);
-}
-module_init(s3c64xx_i2s_init);
-
-static void __exit s3c64xx_i2s_exit(void)
-{
- platform_driver_unregister(&s3c64xx_iis_driver);
-}
-module_exit(s3c64xx_i2s_exit);
-
-/* Module information */
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c64xx-iis");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
deleted file mode 100644
index de4075d26f0c..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* sound/soc/s3c24xx/s3c64xx-i2s.h
- *
- * ALSA SoC Audio Layer - S3C64XX I2S driver
- *
- * 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.
- */
-
-#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
-#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
-
-struct clk;
-
-#include "s3c-i2s-v2.h"
-
-#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
-#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
-#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
-
-#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
-#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS
-#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK
-
-#define S3C64XX_I2S_RATES \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define S3C64XX_I2S_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
-
-#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 8778faa174a6..3052f64b2403 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -434,7 +434,7 @@ static struct snd_soc_dai_driver s6000_i2s_dai = {
.rate_max = 1562500,
},
.ops = &s6000_i2s_dai_ops,
-}
+};
static int __devinit s6000_i2s_probe(struct platform_device *pdev)
{
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 271fd222bf19..ab3ccaec72d2 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -473,7 +473,7 @@ static int s6000_pcm_new(struct snd_card *card,
}
res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
- s6000_soc_platform.name, pcm);
+ "s6000-audio", pcm);
if (res) {
printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
return res;
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 96c05e137538..bf3f3f9165e4 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <variant/dmac.h>
@@ -107,6 +106,7 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
char *differential = "Audio Out Differential";
char *stereo = "Audio Out Stereo";
@@ -114,10 +114,10 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
if (kcontrol->private_value == val)
return 0;
kcontrol->private_value = val;
- snd_soc_dapm_disable_pin(codec, val ? differential : stereo);
- snd_soc_dapm_sync(codec);
- snd_soc_dapm_enable_pin(codec, val ? stereo : differential);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_disable_pin(dapm, val ? differential : stereo);
+ snd_soc_dapm_sync(dapm);
+ snd_soc_dapm_enable_pin(dapm, val ? stereo : differential);
+ snd_soc_dapm_sync(dapm);
return 1;
}
@@ -137,37 +137,38 @@ static const struct snd_kcontrol_new audio_out_mux = {
static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add s6105 specific widgets */
- snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
ARRAY_SIZE(aic3x_dapm_widgets));
/* Set up s6105 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* not present */
- snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
- snd_soc_dapm_nc_pin(codec, "LINE2L");
- snd_soc_dapm_nc_pin(codec, "LINE2R");
+ snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
+ snd_soc_dapm_nc_pin(dapm, "LINE2L");
+ snd_soc_dapm_nc_pin(dapm, "LINE2R");
/* not connected */
- snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */
- snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */
- snd_soc_dapm_nc_pin(codec, "LLOUT");
- snd_soc_dapm_nc_pin(codec, "RLOUT");
- snd_soc_dapm_nc_pin(codec, "HPRCOM");
+ snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */
+ snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */
+ snd_soc_dapm_nc_pin(dapm, "LLOUT");
+ snd_soc_dapm_nc_pin(dapm, "RLOUT");
+ snd_soc_dapm_nc_pin(dapm, "HPRCOM");
/* always connected */
- snd_soc_dapm_enable_pin(codec, "Audio In");
+ snd_soc_dapm_enable_pin(dapm, "Audio In");
/* must correspond to audio_out_mux.private_value initializer */
- snd_soc_dapm_disable_pin(codec, "Audio Out Differential");
- snd_soc_dapm_sync(codec);
- snd_soc_dapm_enable_pin(codec, "Audio Out Stereo");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
+ snd_soc_dapm_sync(dapm);
+ snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
- snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+ snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
return 0;
}
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
new file mode 100644
index 000000000000..11ff4adf9901
--- /dev/null
+++ b/sound/soc/samsung/Kconfig
@@ -0,0 +1,171 @@
+config ASOC_SAMSUNG
+ tristate "ASoC support for Samsung"
+ depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PV310
+ select S3C64XX_DMA if ARCH_S3C64XX
+ select S3C2410_DMA if ARCH_S3C2410
+ help
+ Say Y or M if you want to add support for codecs attached to
+ the Samsung SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
+config SND_S3C24XX_I2S
+ tristate
+ select S3C2410_DMA
+
+config SND_S3C_I2SV2_SOC
+ tristate
+
+config SND_S3C2412_SOC_I2S
+ tristate
+ select SND_S3C_I2SV2_SOC
+ select S3C2410_DMA
+
+config SND_SAMSUNG_PCM
+ tristate
+
+config SND_SAMSUNG_AC97
+ tristate
+ select SND_SOC_AC97_BUS
+
+config SND_SAMSUNG_SPDIF
+ tristate
+ select SND_SOC_SPDIF
+
+config SND_SAMSUNG_I2S
+ tristate
+
+config ASOC_SAMSUNG_NEO1973_WM8753
+ tristate "SoC I2S Audio support for NEO1973 - WM8753"
+ depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01
+ select SND_S3C24XX_I2S
+ select SND_SOC_WM8753
+ help
+ Say Y if you want to add support for SoC audio on smdk2440
+ with the WM8753.
+
+config ASOC_SAMSUNG_NEO1973_GTA02_WM8753
+ tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
+ depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02
+ select SND_S3C24XX_I2S
+ select SND_SOC_WM8753
+ help
+ This driver provides audio support for the Openmoko Neo FreeRunner
+ smartphone.
+
+config ASOC_SAMSUNG_JIVE_WM8750
+ tristate "SoC I2S Audio support for Jive"
+ depends on ASOC_SAMSUNG && MACH_JIVE
+ select SND_SOC_WM8750
+ select SND_S3C2412_SOC_I2S
+ help
+ Sat Y if you want to add support for SoC audio on the Jive.
+
+config ASOC_SAMSUNG_SMDK_WM8580
+ tristate "SoC I2S Audio support for WM8580 on SMDK"
+ depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210 || MACH_SMDKC110)
+ select SND_SOC_WM8580
+ select SND_SAMSUNG_I2S
+ help
+ Say Y if you want to add support for SoC audio on the SMDKs.
+
+config ASOC_SAMSUNG_SMDK_WM8994
+ tristate "SoC I2S Audio support for WM8994 on SMDK"
+ depends on ASOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210)
+ select SND_SOC_WM8994
+ select SND_SAMSUNG_I2S
+ help
+ Say Y if you want to add support for SoC audio on the SMDKs.
+
+config ASOC_SAMSUNG_SMDK2443_WM9710
+ tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
+ depends on ASOC_SAMSUNG && MACH_SMDK2443
+ select S3C2410_DMA
+ select AC97_BUS
+ select SND_SOC_AC97_CODEC
+ select SND_SAMSUNG_AC97
+ help
+ Say Y if you want to add support for SoC audio on smdk2443
+ with the WM9710.
+
+config ASOC_SAMSUNG_LN2440SBC_ALC650
+ tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select S3C2410_DMA
+ select AC97_BUS
+ select SND_SOC_AC97_CODEC
+ select SND_SAMSUNG_AC97
+ help
+ Say Y if you want to add support for SoC audio on ln2440sbc
+ with the ALC650.
+
+config ASOC_SAMSUNG_S3C24XX_UDA134X
+ tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_L3
+ select SND_SOC_UDA134X
+
+config ASOC_SAMSUNG_SIMTEC
+ tristate
+ help
+ Internal node for common S3C24XX/Simtec suppor
+
+config ASOC_SAMSUNG_SIMTEC_TLV320AIC23
+ tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_TLV320AIC23
+ select ASOC_SAMSUNG_SIMTEC
+
+config ASOC_SAMSUNG_SIMTEC_HERMES
+ tristate "SoC I2S Audio support for Simtec Hermes board"
+ depends on ASOC_SAMSUNG && ARCH_S3C2410
+ select SND_S3C24XX_I2S
+ select SND_SOC_TLV320AIC3X
+ select ASOC_SAMSUNG_SIMTEC
+
+config ASOC_SAMSUNG_H1940_UDA1380
+ tristate "Audio support for the HP iPAQ H1940"
+ depends on ASOC_SAMSUNG && ARCH_H1940
+ select SND_S3C24XX_I2S
+ select SND_SOC_UDA1380
+ help
+ This driver provides audio support for HP iPAQ h1940 PDA.
+
+config ASOC_SAMSUNG_RX1950_UDA1380
+ tristate "Audio support for the HP iPAQ RX1950"
+ depends on ASOC_SAMSUNG && MACH_RX1950
+ select SND_S3C24XX_I2S
+ select SND_SOC_UDA1380
+ help
+ This driver provides audio support for HP iPAQ RX1950 PDA.
+
+config ASOC_SAMSUNG_SMDK_WM9713
+ tristate "SoC AC97 Audio support for SMDK with WM9713"
+ depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210)
+ select SND_SOC_WM9713
+ select SND_SAMSUNG_AC97
+ help
+ Sat Y if you want to add support for SoC audio on the SMDK.
+
+config ASOC_SMARTQ
+ tristate "SoC I2S Audio support for SmartQ board"
+ depends on ASOC_SAMSUNG && MACH_SMARTQ
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM8750
+
+config ASOC_GONI_AQUILA_WM8994
+ tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
+ depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM8994
+ help
+ Say Y if you want to add support for SoC audio on goni or aquila
+ with the WM8994.
+
+config ASOC_SAMSUNG_SMDK_SPDIF
+ tristate "SoC S/PDIF Audio support for SMDK"
+ depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
+ select SND_SAMSUNG_SPDIF
+ help
+ Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
new file mode 100644
index 000000000000..fe694cc5c3a3
--- /dev/null
+++ b/sound/soc/samsung/Makefile
@@ -0,0 +1,55 @@
+# S3c24XX Platform Support
+snd-soc-s3c24xx-objs := dma.o
+snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
+snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
+snd-soc-ac97-objs := ac97.o
+snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
+snd-soc-samsung-spdif-objs := spdif.o
+snd-soc-pcm-objs := pcm.o
+snd-soc-i2s-objs := i2s.o
+
+obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o
+obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
+obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
+obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
+obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
+obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
+obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
+obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
+
+# S3C24XX Machine Support
+snd-soc-jive-wm8750-objs := jive_wm8750.o
+snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
+snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
+snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
+snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
+snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
+snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
+snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
+snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
+snd-soc-h1940-uda1380-objs := h1940_uda1380.o
+snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
+snd-soc-smdk-wm8580-objs := smdk_wm8580.o
+snd-soc-smdk-wm8994-objs := smdk_wm8994.o
+snd-soc-smdk-wm9713-objs := smdk_wm9713.o
+snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
+snd-soc-goni-wm8994-objs := goni_wm8994.o
+snd-soc-smdk-spdif-objs := smdk_spdif.o
+
+obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
+obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
+obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
+obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
+obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
+obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
+obj-$(CONFIG_ASOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
+obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
+obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
+obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
+obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/samsung/ac97.c
index f891eb79b575..4770a9550341 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-ac97.c
+/* sound/soc/samsung/ac97.c
*
* ALSA SoC Audio Layer - S3C AC97 Controller driver
* Evolved from s3c2443-ac97.c
@@ -24,8 +24,8 @@
#include <mach/dma.h>
#include <plat/audio.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
#define AC_CMD_ADDR(x) (x << 16)
#define AC_CMD_DATA(x) (x & 0xffff)
@@ -122,7 +122,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
data = (stat & 0xffff);
if (addr != reg)
- pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n",
+ pr_err("ac97: req addr = %02x, rep addr = %02x\n",
reg, addr);
mutex_unlock(&s3c_ac97.lock);
@@ -334,7 +334,7 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
static struct snd_soc_dai_driver s3c_ac97_dai[] = {
[S3C_AC97_DAI_PCM] = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.ac97_control = 1,
.playback = {
.stream_name = "AC97 Playback",
@@ -351,7 +351,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = {
.ops = &s3c_ac97_dai_ops,
},
[S3C_AC97_DAI_MIC] = {
- .name = "s3c-ac97-mic",
+ .name = "samsung-ac97-mic",
.ac97_control = 1,
.capture = {
.stream_name = "AC97 Mic Capture",
@@ -407,7 +407,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
}
if (!request_mem_region(mem_res->start,
- resource_size(mem_res), "s3c-ac97")) {
+ resource_size(mem_res), "ac97")) {
dev_err(&pdev->dev, "Unable to request register region\n");
return -EBUSY;
}
@@ -431,7 +431,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
if (IS_ERR(s3c_ac97.ac97_clk)) {
- dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n");
+ dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
ret = -ENODEV;
goto err2;
}
@@ -446,7 +446,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
ret = request_irq(irq_res->start, s3c_ac97_irq,
IRQF_DISABLED, "AC97", NULL);
if (ret < 0) {
- dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n");
+ dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
goto err4;
}
@@ -497,7 +497,7 @@ static struct platform_driver s3c_ac97_driver = {
.probe = s3c_ac97_probe,
.remove = s3c_ac97_remove,
.driver = {
- .name = "s3c-ac97",
+ .name = "samsung-ac97",
.owner = THIS_MODULE,
},
};
@@ -517,4 +517,4 @@ module_exit(s3c_ac97_exit);
MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c-ac97");
+MODULE_ALIAS("platform:samsung-ac97");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/samsung/ac97.h
index 5dcedd07fdbb..0d0e1b511457 100644
--- a/sound/soc/s3c24xx/s3c-ac97.h
+++ b/sound/soc/samsung/ac97.h
@@ -1,11 +1,11 @@
-/* sound/soc/s3c24xx/s3c-ac97.h
+/* sound/soc/samsung/ac97.h
*
* ALSA SoC Audio Layer - S3C AC97 Controller driver
- * Evolved from s3c2443-ac97.h
+ * Evolved from s3c2443-ac97.h
*
* Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassi.brar@samsung.com>
- * Credits: Graeme Gregory, Sean Choi
+ * Author: Jaswinder Singh <jassi.brar@samsung.com>
+ * Credits: Graeme Gregory, Sean Choi
*
* This 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/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/samsung/dma.c
index 243f79bf43bb..21240198c5d6 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/samsung/dma.c
@@ -1,5 +1,5 @@
/*
- * s3c-dma.c -- ALSA Soc Audio Layer
+ * dma.c -- ALSA Soc Audio Layer
*
* (c) 2006 Wolfson Microelectronics PLC.
* Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
@@ -30,9 +30,9 @@
#include <mach/hardware.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
-static const struct snd_pcm_hardware s3c_dma_hardware = {
+static const struct snd_pcm_hardware dma_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
@@ -53,7 +53,7 @@ static const struct snd_pcm_hardware s3c_dma_hardware = {
.fifo_size = 32,
};
-struct s3c24xx_runtime_data {
+struct runtime_data {
spinlock_t lock;
int state;
unsigned int dma_loaded;
@@ -65,14 +65,14 @@ struct s3c24xx_runtime_data {
struct s3c_dma_params *params;
};
-/* s3c_dma_enqueue
+/* dma_enqueue
*
* place a dma buffer onto the queue for the dma system
* to handle.
*/
-static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
+static void dma_enqueue(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
dma_addr_t pos = prtd->dma_pos;
unsigned int limit;
int ret;
@@ -112,12 +112,12 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
prtd->dma_pos = pos;
}
-static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
+static void audio_buffdone(struct s3c2410_dma_chan *channel,
void *dev_id, int size,
enum s3c2410_dma_buffresult result)
{
struct snd_pcm_substream *substream = dev_id;
- struct s3c24xx_runtime_data *prtd;
+ struct runtime_data *prtd;
pr_debug("Entered %s\n", __func__);
@@ -132,17 +132,17 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
spin_lock(&prtd->lock);
if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
prtd->dma_loaded--;
- s3c_dma_enqueue(substream);
+ dma_enqueue(substream);
}
spin_unlock(&prtd->lock);
}
-static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
+static int dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned long totbytes = params_buffer_bytes(params);
struct s3c_dma_params *dma =
@@ -181,7 +181,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
}
s3c2410_dma_set_buffdone_fn(prtd->params->channel,
- s3c24xx_audio_buffdone);
+ audio_buffdone);
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
@@ -199,9 +199,9 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
+static int dma_hw_free(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
pr_debug("Entered %s\n", __func__);
@@ -216,9 +216,9 @@ static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
return 0;
}
-static int s3c_dma_prepare(struct snd_pcm_substream *substream)
+static int dma_prepare(struct snd_pcm_substream *substream)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
@@ -249,14 +249,14 @@ static int s3c_dma_prepare(struct snd_pcm_substream *substream)
prtd->dma_pos = prtd->dma_start;
/* enqueue dma buffers */
- s3c_dma_enqueue(substream);
+ dma_enqueue(substream);
return ret;
}
-static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
+static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
@@ -289,10 +289,10 @@ static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
}
static snd_pcm_uframes_t
-s3c_dma_pointer(struct snd_pcm_substream *substream)
+dma_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
unsigned long res;
dma_addr_t src, dst;
@@ -324,17 +324,17 @@ s3c_dma_pointer(struct snd_pcm_substream *substream)
return bytes_to_frames(substream->runtime, res);
}
-static int s3c_dma_open(struct snd_pcm_substream *substream)
+static int dma_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd;
+ struct runtime_data *prtd;
pr_debug("Entered %s\n", __func__);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware);
+ snd_soc_set_runtime_hwparams(substream, &dma_hardware);
- prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+ prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL);
if (prtd == NULL)
return -ENOMEM;
@@ -344,22 +344,22 @@ static int s3c_dma_open(struct snd_pcm_substream *substream)
return 0;
}
-static int s3c_dma_close(struct snd_pcm_substream *substream)
+static int dma_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct runtime_data *prtd = runtime->private_data;
pr_debug("Entered %s\n", __func__);
if (!prtd)
- pr_debug("s3c_dma_close called with prtd == NULL\n");
+ pr_debug("dma_close called with prtd == NULL\n");
kfree(prtd);
return 0;
}
-static int s3c_dma_mmap(struct snd_pcm_substream *substream,
+static int dma_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -372,23 +372,23 @@ static int s3c_dma_mmap(struct snd_pcm_substream *substream,
runtime->dma_bytes);
}
-static struct snd_pcm_ops s3c_dma_ops = {
- .open = s3c_dma_open,
- .close = s3c_dma_close,
+static struct snd_pcm_ops dma_ops = {
+ .open = dma_open,
+ .close = dma_close,
.ioctl = snd_pcm_lib_ioctl,
- .hw_params = s3c_dma_hw_params,
- .hw_free = s3c_dma_hw_free,
- .prepare = s3c_dma_prepare,
- .trigger = s3c_dma_trigger,
- .pointer = s3c_dma_pointer,
- .mmap = s3c_dma_mmap,
+ .hw_params = dma_hw_params,
+ .hw_free = dma_hw_free,
+ .prepare = dma_prepare,
+ .trigger = dma_trigger,
+ .pointer = dma_pointer,
+ .mmap = dma_mmap,
};
-static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = s3c_dma_hardware.buffer_bytes_max;
+ size_t size = dma_hardware.buffer_bytes_max;
pr_debug("Entered %s\n", __func__);
@@ -403,7 +403,7 @@ static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
return 0;
}
-static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
+static void dma_free_dma_buffers(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
@@ -426,9 +426,9 @@ static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
}
}
-static u64 s3c_dma_mask = DMA_BIT_MASK(32);
+static u64 dma_mask = DMA_BIT_MASK(32);
-static int s3c_dma_new(struct snd_card *card,
+static int dma_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
{
int ret = 0;
@@ -436,67 +436,67 @@ static int s3c_dma_new(struct snd_card *card,
pr_debug("Entered %s\n", __func__);
if (!card->dev->dma_mask)
- card->dev->dma_mask = &s3c_dma_mask;
+ card->dev->dma_mask = &dma_mask;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
if (dai->driver->playback.channels_min) {
- ret = s3c_preallocate_dma_buffer(pcm,
+ ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->driver->capture.channels_min) {
- ret = s3c_preallocate_dma_buffer(pcm,
+ ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}
- out:
+out:
return ret;
}
-static struct snd_soc_platform_driver s3c24xx_soc_platform = {
- .ops = &s3c_dma_ops,
- .pcm_new = s3c_dma_new,
- .pcm_free = s3c_dma_free_dma_buffers,
+static struct snd_soc_platform_driver samsung_asoc_platform = {
+ .ops = &dma_ops,
+ .pcm_new = dma_new,
+ .pcm_free = dma_free_dma_buffers,
};
-static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev)
+static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
{
- return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform);
+ return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
}
-static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev)
+static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
-static struct platform_driver s3c24xx_pcm_driver = {
+static struct platform_driver asoc_dma_driver = {
.driver = {
- .name = "s3c24xx-pcm-audio",
+ .name = "samsung-audio",
.owner = THIS_MODULE,
},
- .probe = s3c24xx_soc_platform_probe,
- .remove = __devexit_p(s3c24xx_soc_platform_remove),
+ .probe = samsung_asoc_platform_probe,
+ .remove = __devexit_p(samsung_asoc_platform_remove),
};
-static int __init snd_s3c24xx_pcm_init(void)
+static int __init samsung_asoc_init(void)
{
- return platform_driver_register(&s3c24xx_pcm_driver);
+ return platform_driver_register(&asoc_dma_driver);
}
-module_init(snd_s3c24xx_pcm_init);
+module_init(samsung_asoc_init);
-static void __exit snd_s3c24xx_pcm_exit(void)
+static void __exit samsung_asoc_exit(void)
{
- platform_driver_unregister(&s3c24xx_pcm_driver);
+ platform_driver_unregister(&asoc_dma_driver);
}
-module_exit(snd_s3c24xx_pcm_exit);
+module_exit(samsung_asoc_exit);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
+MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c24xx-pcm-audio");
+MODULE_ALIAS("platform:samsung-audio");
diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/samsung/dma.h
index 748c07d7c075..f8cd2b4223af 100644
--- a/sound/soc/s3c24xx/s3c-dma.h
+++ b/sound/soc/samsung/dma.h
@@ -1,5 +1,5 @@
/*
- * s3c-dma.h --
+ * dma.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
diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 694f702cc8e2..34dd9ef1b9c0 100644
--- a/sound/soc/s3c24xx/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <mach/gpio.h>
@@ -25,8 +24,16 @@
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include "../codecs/wm8994.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
+
+#define MACHINE_NAME 0
+#define CPU_VOICE_DAI 1
+
+static const char *aquila_str[] = {
+ [MACHINE_NAME] = "aquila",
+ [CPU_VOICE_DAI] = "aquila-voice-dai",
+};
static struct snd_soc_card goni;
static struct platform_device *goni_snd_device;
@@ -97,28 +104,34 @@ static const struct snd_soc_dapm_route goni_dapm_routes[] = {
static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
/* add goni specific widgets */
- snd_soc_dapm_new_controls(codec, goni_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
ARRAY_SIZE(goni_dapm_widgets));
/* set up goni specific audio routes */
- snd_soc_dapm_add_routes(codec, goni_dapm_routes,
+ snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
ARRAY_SIZE(goni_dapm_routes));
/* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
- snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
+ snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
+ snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
- snd_soc_dapm_sync(codec);
+ if (machine_is_aquila()) {
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
+ }
+
+ snd_soc_dapm_sync(dapm);
/* Headset jack detection */
- ret = snd_soc_jack_new(&goni, "Headset Jack",
+ ret = snd_soc_jack_new(codec, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
&jack);
if (ret)
@@ -150,12 +163,6 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- /* set the cpu system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
@@ -236,9 +243,9 @@ static struct snd_soc_dai_link goni_dai[] = {
{
.name = "WM8994",
.stream_name = "WM8994 HiFi",
- .cpu_dai_name = "s3c64xx-i2s-v4",
+ .cpu_dai_name = "samsung-i2s.0",
.codec_dai_name = "wm8994-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8994-codec.0-0x1a",
.init = goni_wm8994_init,
.ops = &goni_hifi_ops,
@@ -247,7 +254,7 @@ static struct snd_soc_dai_link goni_dai[] = {
.stream_name = "Voice",
.cpu_dai_name = "goni-voice-dai",
.codec_dai_name = "wm8994-voice",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8994-codec.0-0x1a",
.ops = &goni_voice_ops,
},
@@ -263,7 +270,11 @@ static int __init goni_init(void)
{
int ret;
- if (!machine_is_goni())
+ if (machine_is_aquila()) {
+ voice_dai.name = aquila_str[CPU_VOICE_DAI];
+ goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI];
+ goni.name = aquila_str[MACHINE_NAME];
+ } else if (!machine_is_goni())
return -ENODEV;
goni_snd_device = platform_device_alloc("soc-audio", -1);
@@ -272,20 +283,25 @@ static int __init goni_init(void)
/* register voice DAI here */
ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai);
- if (ret)
+ if (ret) {
+ platform_device_put(goni_snd_device);
return ret;
+ }
platform_set_drvdata(goni_snd_device, &goni);
ret = platform_device_add(goni_snd_device);
- if (ret)
+ if (ret) {
+ snd_soc_unregister_dai(&goni_snd_device->dev);
platform_device_put(goni_snd_device);
+ }
return ret;
}
static void __exit goni_exit(void)
{
+ snd_soc_unregister_dai(&goni_snd_device->dev);
platform_device_unregister(goni_snd_device);
}
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
new file mode 100644
index 000000000000..c45f7ce14d61
--- /dev/null
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -0,0 +1,296 @@
+/*
+ * h1940-uda1380.c -- ALSA Soc Audio Layer
+ *
+ * Copyright (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com>
+ *
+ * Based on version from Arnaud Patard <arnaud.patard@rtp-net.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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#include <sound/soc.h>
+#include <sound/uda1380.h>
+#include <sound/jack.h>
+
+#include <plat/regs-iis.h>
+
+#include <mach/h1940-latch.h>
+
+#include <asm/mach-types.h>
+
+#include "dma.h"
+#include "s3c24xx-i2s.h"
+#include "../codecs/uda1380.h"
+
+static unsigned int rates[] = {
+ 11025,
+ 22050,
+ 44100,
+};
+
+static struct snd_pcm_hw_constraint_list hw_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+static struct snd_soc_jack hp_jack;
+
+static struct snd_soc_jack_pin hp_jack_pins[] = {
+ {
+ .pin = "Headphone Jack",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Speaker",
+ .mask = SND_JACK_HEADPHONE,
+ .invert = 1,
+ },
+};
+
+static struct snd_soc_jack_gpio hp_jack_gpios[] = {
+ {
+ .gpio = S3C2410_GPG(4),
+ .name = "hp-gpio",
+ .report = SND_JACK_HEADPHONE,
+ .invert = 1,
+ .debounce_time = 200,
+ },
+};
+
+static int h1940_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ runtime->hw.rate_min = hw_rates.list[0];
+ runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1];
+ runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
+
+ return snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &hw_rates);
+}
+
+static int h1940_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int div;
+ int ret;
+ unsigned int rate = params_rate(params);
+
+ switch (rate) {
+ case 11025:
+ case 22050:
+ case 44100:
+ div = s3c24xx_i2s_get_clockrate() / (384 * rate);
+ if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate))
+ div++;
+ break;
+ default:
+ dev_err(&rtd->dev, "%s: rate %d is not supported\n",
+ __func__, rate);
+ return -EINVAL;
+ }
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* select clock source */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+
+ /* set MCLK division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
+ S3C2410_IISMOD_384FS);
+ if (ret < 0)
+ return ret;
+
+ /* set BCLK division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
+ S3C2410_IISMOD_32FS);
+ if (ret < 0)
+ return ret;
+
+ /* set prescaler division for sample rate */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
+ S3C24XX_PRESCALE(div, div));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops h1940_ops = {
+ .startup = h1940_startup,
+ .hw_params = h1940_hw_params,
+};
+
+static int h1940_spk_power(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ gpio_set_value(H1940_LATCH_AUDIO_POWER, 1);
+ else
+ gpio_set_value(H1940_LATCH_AUDIO_POWER, 0);
+
+ return 0;
+}
+
+/* h1940 machine dapm widgets */
+static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_SPK("Speaker", h1940_spk_power),
+};
+
+/* h1940 machine audio_map */
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* headphone connected to VOUTLHP, VOUTRHP */
+ {"Headphone Jack", NULL, "VOUTLHP"},
+ {"Headphone Jack", NULL, "VOUTRHP"},
+
+ /* ext speaker connected to VOUTL, VOUTR */
+ {"Speaker", NULL, "VOUTL"},
+ {"Speaker", NULL, "VOUTR"},
+
+ /* mic is connected to VINM */
+ {"VINM", NULL, "Mic Jack"},
+};
+
+static struct platform_device *s3c24xx_snd_device;
+
+static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int err;
+
+ /* Add h1940 specific widgets */
+ err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
+ ARRAY_SIZE(uda1380_dapm_widgets));
+ if (err)
+ return err;
+
+ /* Set up h1940 specific audio path audio_mapnects */
+ err = snd_soc_dapm_add_routes(dapm, audio_map,
+ ARRAY_SIZE(audio_map));
+ if (err)
+ return err;
+
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
+
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
+ &hp_jack);
+
+ snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
+ hp_jack_pins);
+
+ snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
+ hp_jack_gpios);
+
+ return 0;
+}
+
+/* s3c24xx digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link h1940_uda1380_dai[] = {
+ {
+ .name = "uda1380",
+ .stream_name = "UDA1380 Duplex",
+ .cpu_dai_name = "s3c24xx-iis",
+ .codec_dai_name = "uda1380-hifi",
+ .init = h1940_uda1380_init,
+ .platform_name = "samsung-audio",
+ .codec_name = "uda1380-codec.0-001a",
+ .ops = &h1940_ops,
+ },
+};
+
+static struct snd_soc_card h1940_asoc = {
+ .name = "h1940",
+ .dai_link = h1940_uda1380_dai,
+ .num_links = ARRAY_SIZE(h1940_uda1380_dai),
+};
+
+static int __init h1940_init(void)
+{
+ int ret;
+
+ if (!machine_is_h1940())
+ return -ENODEV;
+
+ /* configure some gpios */
+ ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power");
+ if (ret)
+ goto err_out;
+
+ ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0);
+ if (ret)
+ goto err_gpio;
+
+ s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!s3c24xx_snd_device) {
+ ret = -ENOMEM;
+ goto err_gpio;
+ }
+
+ platform_set_drvdata(s3c24xx_snd_device, &h1940_asoc);
+ ret = platform_device_add(s3c24xx_snd_device);
+
+ if (ret)
+ goto err_plat;
+
+ return 0;
+
+err_plat:
+ platform_device_put(s3c24xx_snd_device);
+err_gpio:
+ gpio_free(H1940_LATCH_AUDIO_POWER);
+
+err_out:
+ return ret;
+}
+
+static void __exit h1940_exit(void)
+{
+ platform_device_unregister(s3c24xx_snd_device);
+ snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
+ hp_jack_gpios);
+ gpio_free(H1940_LATCH_AUDIO_POWER);
+}
+
+module_init(h1940_init);
+module_exit(h1940_exit);
+
+/* Module information */
+MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick");
+MODULE_DESCRIPTION("ALSA SoC H1940");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
new file mode 100644
index 000000000000..d00ac3a7102c
--- /dev/null
+++ b/sound/soc/samsung/i2s.c
@@ -0,0 +1,1258 @@
+/* sound/soc/samsung/i2s.c
+ *
+ * ALSA SoC Audio Layer - Samsung I2S Controller driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. 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/delay.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <plat/audio.h>
+
+#include "dma.h"
+#include "i2s.h"
+
+#define I2SCON 0x0
+#define I2SMOD 0x4
+#define I2SFIC 0x8
+#define I2SPSR 0xc
+#define I2STXD 0x10
+#define I2SRXD 0x14
+#define I2SFICS 0x18
+#define I2STXDS 0x1c
+
+#define CON_RSTCLR (1 << 31)
+#define CON_FRXOFSTATUS (1 << 26)
+#define CON_FRXORINTEN (1 << 25)
+#define CON_FTXSURSTAT (1 << 24)
+#define CON_FTXSURINTEN (1 << 23)
+#define CON_TXSDMA_PAUSE (1 << 20)
+#define CON_TXSDMA_ACTIVE (1 << 18)
+
+#define CON_FTXURSTATUS (1 << 17)
+#define CON_FTXURINTEN (1 << 16)
+#define CON_TXFIFO2_EMPTY (1 << 15)
+#define CON_TXFIFO1_EMPTY (1 << 14)
+#define CON_TXFIFO2_FULL (1 << 13)
+#define CON_TXFIFO1_FULL (1 << 12)
+
+#define CON_LRINDEX (1 << 11)
+#define CON_TXFIFO_EMPTY (1 << 10)
+#define CON_RXFIFO_EMPTY (1 << 9)
+#define CON_TXFIFO_FULL (1 << 8)
+#define CON_RXFIFO_FULL (1 << 7)
+#define CON_TXDMA_PAUSE (1 << 6)
+#define CON_RXDMA_PAUSE (1 << 5)
+#define CON_TXCH_PAUSE (1 << 4)
+#define CON_RXCH_PAUSE (1 << 3)
+#define CON_TXDMA_ACTIVE (1 << 2)
+#define CON_RXDMA_ACTIVE (1 << 1)
+#define CON_ACTIVE (1 << 0)
+
+#define MOD_OPCLK_CDCLK_OUT (0 << 30)
+#define MOD_OPCLK_CDCLK_IN (1 << 30)
+#define MOD_OPCLK_BCLK_OUT (2 << 30)
+#define MOD_OPCLK_PCLK (3 << 30)
+#define MOD_OPCLK_MASK (3 << 30)
+#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
+
+#define MOD_BLCS_SHIFT 26
+#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
+#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
+#define MOD_BLCP_SHIFT 24
+#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
+#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
+
+#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
+#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
+#define MOD_C1DD_HHALF (1 << 19)
+#define MOD_C1DD_LHALF (1 << 18)
+#define MOD_DC2_EN (1 << 17)
+#define MOD_DC1_EN (1 << 16)
+#define MOD_BLC_16BIT (0 << 13)
+#define MOD_BLC_8BIT (1 << 13)
+#define MOD_BLC_24BIT (2 << 13)
+#define MOD_BLC_MASK (3 << 13)
+
+#define MOD_IMS_SYSMUX (1 << 10)
+#define MOD_SLAVE (1 << 11)
+#define MOD_TXONLY (0 << 8)
+#define MOD_RXONLY (1 << 8)
+#define MOD_TXRX (2 << 8)
+#define MOD_MASK (3 << 8)
+#define MOD_LR_LLOW (0 << 7)
+#define MOD_LR_RLOW (1 << 7)
+#define MOD_SDF_IIS (0 << 5)
+#define MOD_SDF_MSB (1 << 5)
+#define MOD_SDF_LSB (2 << 5)
+#define MOD_SDF_MASK (3 << 5)
+#define MOD_RCLK_256FS (0 << 3)
+#define MOD_RCLK_512FS (1 << 3)
+#define MOD_RCLK_384FS (2 << 3)
+#define MOD_RCLK_768FS (3 << 3)
+#define MOD_RCLK_MASK (3 << 3)
+#define MOD_BCLK_32FS (0 << 1)
+#define MOD_BCLK_48FS (1 << 1)
+#define MOD_BCLK_16FS (2 << 1)
+#define MOD_BCLK_24FS (3 << 1)
+#define MOD_BCLK_MASK (3 << 1)
+#define MOD_8BIT (1 << 0)
+
+#define MOD_CDCLKCON (1 << 12)
+
+#define PSR_PSREN (1 << 15)
+
+#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
+#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
+
+#define FIC_TXFLUSH (1 << 15)
+#define FIC_RXFLUSH (1 << 7)
+#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
+#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
+#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+struct i2s_dai {
+ /* Platform device for this DAI */
+ struct platform_device *pdev;
+ /* IOREMAP'd SFRs */
+ void __iomem *addr;
+ /* Physical base address of SFRs */
+ u32 base;
+ /* Rate of RCLK source clock */
+ unsigned long rclk_srcrate;
+ /* Frame Clock */
+ unsigned frmclk;
+ /*
+ * Specifically requested RCLK,BCLK by MACHINE Driver.
+ * 0 indicates CPU driver is free to choose any value.
+ */
+ unsigned rfs, bfs;
+ /* I2S Controller's core clock */
+ struct clk *clk;
+ /* Clock for generating I2S signals */
+ struct clk *op_clk;
+ /* Array of clock names for op_clk */
+ const char **src_clk;
+ /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
+ struct i2s_dai *pri_dai;
+ /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
+ struct i2s_dai *sec_dai;
+#define DAI_OPENED (1 << 0) /* Dai is opened */
+#define DAI_MANAGER (1 << 1) /* Dai is the manager */
+ unsigned mode;
+ /* Driver for this DAI */
+ struct snd_soc_dai_driver i2s_dai_drv;
+ /* DMA parameters */
+ struct s3c_dma_params dma_playback;
+ struct s3c_dma_params dma_capture;
+ u32 quirks;
+ u32 suspend_i2smod;
+ u32 suspend_i2scon;
+ u32 suspend_i2spsr;
+};
+
+/* Lock for cross i/f checks */
+static DEFINE_SPINLOCK(lock);
+
+/* If this is the 'overlay' stereo DAI */
+static inline bool is_secondary(struct i2s_dai *i2s)
+{
+ return i2s->pri_dai ? true : false;
+}
+
+/* If operating in SoC-Slave mode */
+static inline bool is_slave(struct i2s_dai *i2s)
+{
+ return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
+}
+
+/* If this interface of the controller is transmitting data */
+static inline bool tx_active(struct i2s_dai *i2s)
+{
+ u32 active;
+
+ if (!i2s)
+ return false;
+
+ active = readl(i2s->addr + I2SMOD);
+
+ if (is_secondary(i2s))
+ active &= CON_TXSDMA_ACTIVE;
+ else
+ active &= CON_TXDMA_ACTIVE;
+
+ return active ? true : false;
+}
+
+/* If the other interface of the controller is transmitting data */
+static inline bool other_tx_active(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ return tx_active(other);
+}
+
+/* If any interface of the controller is transmitting data */
+static inline bool any_tx_active(struct i2s_dai *i2s)
+{
+ return tx_active(i2s) || other_tx_active(i2s);
+}
+
+/* If this interface of the controller is receiving data */
+static inline bool rx_active(struct i2s_dai *i2s)
+{
+ u32 active;
+
+ if (!i2s)
+ return false;
+
+ active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE;
+
+ return active ? true : false;
+}
+
+/* If the other interface of the controller is receiving data */
+static inline bool other_rx_active(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ return rx_active(other);
+}
+
+/* If any interface of the controller is receiving data */
+static inline bool any_rx_active(struct i2s_dai *i2s)
+{
+ return rx_active(i2s) || other_rx_active(i2s);
+}
+
+/* If the other DAI is transmitting or receiving data */
+static inline bool other_active(struct i2s_dai *i2s)
+{
+ return other_rx_active(i2s) || other_tx_active(i2s);
+}
+
+/* If this DAI is transmitting or receiving data */
+static inline bool this_active(struct i2s_dai *i2s)
+{
+ return tx_active(i2s) || rx_active(i2s);
+}
+
+/* If the controller is active anyway */
+static inline bool any_active(struct i2s_dai *i2s)
+{
+ return this_active(i2s) || other_active(i2s);
+}
+
+static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
+{
+ return snd_soc_dai_get_drvdata(dai);
+}
+
+static inline bool is_opened(struct i2s_dai *i2s)
+{
+ if (i2s && (i2s->mode & DAI_OPENED))
+ return true;
+ else
+ return false;
+}
+
+static inline bool is_manager(struct i2s_dai *i2s)
+{
+ if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
+ return true;
+ else
+ return false;
+}
+
+/* Read RCLK of I2S (in multiples of LRCLK) */
+static inline unsigned get_rfs(struct i2s_dai *i2s)
+{
+ u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
+
+ switch (rfs) {
+ case 3: return 768;
+ case 2: return 384;
+ case 1: return 512;
+ default: return 256;
+ }
+}
+
+/* Write RCLK of I2S (in multiples of LRCLK) */
+static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
+{
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ mod &= ~MOD_RCLK_MASK;
+
+ switch (rfs) {
+ case 768:
+ mod |= MOD_RCLK_768FS;
+ break;
+ case 512:
+ mod |= MOD_RCLK_512FS;
+ break;
+ case 384:
+ mod |= MOD_RCLK_384FS;
+ break;
+ default:
+ mod |= MOD_RCLK_256FS;
+ break;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+}
+
+/* Read Bit-Clock of I2S (in multiples of LRCLK) */
+static inline unsigned get_bfs(struct i2s_dai *i2s)
+{
+ u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
+
+ switch (bfs) {
+ case 3: return 24;
+ case 2: return 16;
+ case 1: return 48;
+ default: return 32;
+ }
+}
+
+/* Write Bit-Clock of I2S (in multiples of LRCLK) */
+static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
+{
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ mod &= ~MOD_BCLK_MASK;
+
+ switch (bfs) {
+ case 48:
+ mod |= MOD_BCLK_48FS;
+ break;
+ case 32:
+ mod |= MOD_BCLK_32FS;
+ break;
+ case 24:
+ mod |= MOD_BCLK_24FS;
+ break;
+ case 16:
+ mod |= MOD_BCLK_16FS;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
+ return;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+}
+
+/* Sample-Size */
+static inline int get_blc(struct i2s_dai *i2s)
+{
+ int blc = readl(i2s->addr + I2SMOD);
+
+ blc = (blc >> 13) & 0x3;
+
+ switch (blc) {
+ case 2: return 24;
+ case 1: return 8;
+ default: return 16;
+ }
+}
+
+/* TX Channel Control */
+static void i2s_txctrl(struct i2s_dai *i2s, int on)
+{
+ void __iomem *addr = i2s->addr;
+ u32 con = readl(addr + I2SCON);
+ u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+
+ if (on) {
+ con |= CON_ACTIVE;
+ con &= ~CON_TXCH_PAUSE;
+
+ if (is_secondary(i2s)) {
+ con |= CON_TXSDMA_ACTIVE;
+ con &= ~CON_TXSDMA_PAUSE;
+ } else {
+ con |= CON_TXDMA_ACTIVE;
+ con &= ~CON_TXDMA_PAUSE;
+ }
+
+ if (any_rx_active(i2s))
+ mod |= MOD_TXRX;
+ else
+ mod |= MOD_TXONLY;
+ } else {
+ if (is_secondary(i2s)) {
+ con |= CON_TXSDMA_PAUSE;
+ con &= ~CON_TXSDMA_ACTIVE;
+ } else {
+ con |= CON_TXDMA_PAUSE;
+ con &= ~CON_TXDMA_ACTIVE;
+ }
+
+ if (other_tx_active(i2s)) {
+ writel(con, addr + I2SCON);
+ return;
+ }
+
+ con |= CON_TXCH_PAUSE;
+
+ if (any_rx_active(i2s))
+ mod |= MOD_RXONLY;
+ else
+ con &= ~CON_ACTIVE;
+ }
+
+ writel(mod, addr + I2SMOD);
+ writel(con, addr + I2SCON);
+}
+
+/* RX Channel Control */
+static void i2s_rxctrl(struct i2s_dai *i2s, int on)
+{
+ void __iomem *addr = i2s->addr;
+ u32 con = readl(addr + I2SCON);
+ u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
+
+ if (on) {
+ con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
+ con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
+
+ if (any_tx_active(i2s))
+ mod |= MOD_TXRX;
+ else
+ mod |= MOD_RXONLY;
+ } else {
+ con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
+ con &= ~CON_RXDMA_ACTIVE;
+
+ if (any_tx_active(i2s))
+ mod |= MOD_TXONLY;
+ else
+ con &= ~CON_ACTIVE;
+ }
+
+ writel(mod, addr + I2SMOD);
+ writel(con, addr + I2SCON);
+}
+
+/* Flush FIFO of an interface */
+static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
+{
+ void __iomem *fic;
+ u32 val;
+
+ if (!i2s)
+ return;
+
+ if (is_secondary(i2s))
+ fic = i2s->addr + I2SFICS;
+ else
+ fic = i2s->addr + I2SFIC;
+
+ /* Flush the FIFO */
+ writel(readl(fic) | flush, fic);
+
+ /* Be patient */
+ val = msecs_to_loops(1) / 1000; /* 1 usec */
+ while (--val)
+ cpu_relax();
+
+ writel(readl(fic) & ~flush, fic);
+}
+
+static int i2s_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int rfs, int dir)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ switch (clk_id) {
+ case SAMSUNG_I2S_CDCLK:
+ /* Shouldn't matter in GATING(CLOCK_IN) mode */
+ if (dir == SND_SOC_CLOCK_IN)
+ rfs = 0;
+
+ if ((rfs && other->rfs && (other->rfs != rfs)) ||
+ (any_active(i2s) &&
+ (((dir == SND_SOC_CLOCK_IN)
+ && !(mod & MOD_CDCLKCON)) ||
+ ((dir == SND_SOC_CLOCK_OUT)
+ && (mod & MOD_CDCLKCON))))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ if (dir == SND_SOC_CLOCK_IN)
+ mod |= MOD_CDCLKCON;
+ else
+ mod &= ~MOD_CDCLKCON;
+
+ i2s->rfs = rfs;
+ break;
+
+ case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
+ case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
+ if ((i2s->quirks & QUIRK_NO_MUXPSR)
+ || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
+ clk_id = 0;
+ else
+ clk_id = 1;
+
+ if (!any_active(i2s)) {
+ if (i2s->op_clk) {
+ if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
+ (!clk_id && (mod & MOD_IMS_SYSMUX))) {
+ clk_disable(i2s->op_clk);
+ clk_put(i2s->op_clk);
+ } else {
+ i2s->rclk_srcrate =
+ clk_get_rate(i2s->op_clk);
+ return 0;
+ }
+ }
+
+ i2s->op_clk = clk_get(&i2s->pdev->dev,
+ i2s->src_clk[clk_id]);
+ clk_enable(i2s->op_clk);
+ i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
+
+ /* Over-ride the other's */
+ if (other) {
+ other->op_clk = i2s->op_clk;
+ other->rclk_srcrate = i2s->rclk_srcrate;
+ }
+ } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
+ || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ } else {
+ /* Call can't be on the active DAI */
+ i2s->op_clk = other->op_clk;
+ i2s->rclk_srcrate = other->rclk_srcrate;
+ return 0;
+ }
+
+ if (clk_id == 0)
+ mod &= ~MOD_IMS_SYSMUX;
+ else
+ mod |= MOD_IMS_SYSMUX;
+ break;
+
+ default:
+ dev_err(&i2s->pdev->dev, "We don't serve that!\n");
+ return -EINVAL;
+ }
+
+ writel(mod, i2s->addr + I2SMOD);
+
+ return 0;
+}
+
+static int i2s_set_fmt(struct snd_soc_dai *dai,
+ unsigned int fmt)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 mod = readl(i2s->addr + I2SMOD);
+ u32 tmp = 0;
+
+ /* Format is priority */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_RIGHT_J:
+ tmp |= MOD_LR_RLOW;
+ tmp |= MOD_SDF_MSB;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ tmp |= MOD_LR_RLOW;
+ tmp |= MOD_SDF_LSB;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ tmp |= MOD_SDF_IIS;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Format not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * INV flag is relative to the FORMAT flag - if set it simply
+ * flips the polarity specified by the Standard
+ */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ if (tmp & MOD_LR_RLOW)
+ tmp &= ~MOD_LR_RLOW;
+ else
+ tmp |= MOD_LR_RLOW;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Polarity not supported\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ tmp |= MOD_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ /* Set default source clock in Master mode */
+ if (i2s->rclk_srcrate == 0)
+ i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
+ 0, SND_SOC_CLOCK_IN);
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
+ return -EINVAL;
+ }
+
+ if (any_active(i2s) &&
+ ((mod & (MOD_SDF_MASK | MOD_LR_RLOW
+ | MOD_SLAVE)) != tmp)) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
+ mod |= tmp;
+ writel(mod, i2s->addr + I2SMOD);
+
+ return 0;
+}
+
+static int i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 mod = readl(i2s->addr + I2SMOD);
+
+ if (!is_secondary(i2s))
+ mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
+
+ switch (params_channels(params)) {
+ case 6:
+ mod |= MOD_DC2_EN;
+ case 4:
+ mod |= MOD_DC1_EN;
+ break;
+ case 2:
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "%d channels not supported\n",
+ params_channels(params));
+ return -EINVAL;
+ }
+
+ if (is_secondary(i2s))
+ mod &= ~MOD_BLCS_MASK;
+ else
+ mod &= ~MOD_BLCP_MASK;
+
+ if (is_manager(i2s))
+ mod &= ~MOD_BLC_MASK;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_8BIT;
+ else
+ mod |= MOD_BLCP_8BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_8BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_16BIT;
+ else
+ mod |= MOD_BLCP_16BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_16BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ if (is_secondary(i2s))
+ mod |= MOD_BLCS_24BIT;
+ else
+ mod |= MOD_BLCP_24BIT;
+ if (is_manager(i2s))
+ mod |= MOD_BLC_24BIT;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
+ params_format(params));
+ return -EINVAL;
+ }
+ writel(mod, i2s->addr + I2SMOD);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_soc_dai_set_dma_data(dai, substream,
+ (void *)&i2s->dma_playback);
+ else
+ snd_soc_dai_set_dma_data(dai, substream,
+ (void *)&i2s->dma_capture);
+
+ i2s->frmclk = params_rate(params);
+
+ return 0;
+}
+
+/* We set constraints on the substream acc to the version of I2S */
+static int i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ i2s->mode |= DAI_OPENED;
+
+ if (is_manager(other))
+ i2s->mode &= ~DAI_MANAGER;
+ else
+ i2s->mode |= DAI_MANAGER;
+
+ /* Enforce set_sysclk in Master mode */
+ i2s->rclk_srcrate = 0;
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ return 0;
+}
+
+static void i2s_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ i2s->mode &= ~DAI_OPENED;
+ i2s->mode &= ~DAI_MANAGER;
+
+ if (is_opened(other))
+ other->mode |= DAI_MANAGER;
+
+ /* Reset any constraint on RFS and BFS */
+ i2s->rfs = 0;
+ i2s->bfs = 0;
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ /* Gate CDCLK by default */
+ if (!is_opened(other))
+ i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
+}
+
+static int config_setup(struct i2s_dai *i2s)
+{
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+ unsigned rfs, bfs, blc;
+ u32 psr;
+
+ blc = get_blc(i2s);
+
+ bfs = i2s->bfs;
+
+ if (!bfs && other)
+ bfs = other->bfs;
+
+ /* Select least possible multiple(2) if no constraint set */
+ if (!bfs)
+ bfs = blc * 2;
+
+ rfs = i2s->rfs;
+
+ if (!rfs && other)
+ rfs = other->rfs;
+
+ if ((rfs == 256 || rfs == 512) && (blc == 24)) {
+ dev_err(&i2s->pdev->dev,
+ "%d-RFS not supported for 24-blc\n", rfs);
+ return -EINVAL;
+ }
+
+ if (!rfs) {
+ if (bfs == 16 || bfs == 32)
+ rfs = 256;
+ else
+ rfs = 384;
+ }
+
+ /* If already setup and running */
+ if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ /* Don't bother RFS, BFS & PSR in Slave mode */
+ if (is_slave(i2s))
+ return 0;
+
+ set_bfs(i2s, bfs);
+ set_rfs(i2s, rfs);
+
+ if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+ psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
+ writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
+ dev_dbg(&i2s->pdev->dev,
+ "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
+ i2s->rclk_srcrate, psr, rfs, bfs);
+ }
+
+ return 0;
+}
+
+static int i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct i2s_dai *i2s = to_info(rtd->cpu_dai);
+ unsigned long flags;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ local_irq_save(flags);
+
+ if (config_setup(i2s)) {
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+
+ if (capture)
+ i2s_rxctrl(i2s, 1);
+ else
+ i2s_txctrl(i2s, 1);
+
+ local_irq_restore(flags);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ local_irq_save(flags);
+
+ if (capture)
+ i2s_rxctrl(i2s, 0);
+ else
+ i2s_txctrl(i2s, 0);
+
+ if (capture)
+ i2s_fifo(i2s, FIC_RXFLUSH);
+ else
+ i2s_fifo(i2s, FIC_TXFLUSH);
+
+ local_irq_restore(flags);
+ break;
+ }
+
+ return 0;
+}
+
+static int i2s_set_clkdiv(struct snd_soc_dai *dai,
+ int div_id, int div)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ switch (div_id) {
+ case SAMSUNG_I2S_DIV_BCLK:
+ if ((any_active(i2s) && div && (get_bfs(i2s) != div))
+ || (other && other->bfs && (other->bfs != div))) {
+ dev_err(&i2s->pdev->dev,
+ "%s:%d Other DAI busy\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+ i2s->bfs = div;
+ break;
+ default:
+ dev_err(&i2s->pdev->dev,
+ "Invalid clock divider(%d)\n", div_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_sframes_t
+i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ u32 reg = readl(i2s->addr + I2SFIC);
+ snd_pcm_sframes_t delay;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ delay = FIC_RXCOUNT(reg);
+ else if (is_secondary(i2s))
+ delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
+ else
+ delay = FIC_TXCOUNT(reg);
+
+ return delay;
+}
+
+#ifdef CONFIG_PM
+static int i2s_suspend(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+
+ if (dai->active) {
+ i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
+ i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
+ i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+ }
+
+ return 0;
+}
+
+static int i2s_resume(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+
+ if (dai->active) {
+ writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
+ writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
+ writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
+ }
+
+ return 0;
+}
+#else
+#define i2s_suspend NULL
+#define i2s_resume NULL
+#endif
+
+static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = to_info(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (other && other->clk) /* If this is probe on secondary */
+ goto probe_exit;
+
+ i2s->addr = ioremap(i2s->base, 0x100);
+ if (i2s->addr == NULL) {
+ dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
+ return -ENXIO;
+ }
+
+ i2s->clk = clk_get(&i2s->pdev->dev, "iis");
+ if (IS_ERR(i2s->clk)) {
+ dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
+ iounmap(i2s->addr);
+ return -ENOENT;
+ }
+ clk_enable(i2s->clk);
+
+ if (other) {
+ other->addr = i2s->addr;
+ other->clk = i2s->clk;
+ }
+
+ if (i2s->quirks & QUIRK_NEED_RSTCLR)
+ writel(CON_RSTCLR, i2s->addr + I2SCON);
+
+probe_exit:
+ /* Reset any constraint on RFS and BFS */
+ i2s->rfs = 0;
+ i2s->bfs = 0;
+ i2s_txctrl(i2s, 0);
+ i2s_rxctrl(i2s, 0);
+ i2s_fifo(i2s, FIC_TXFLUSH);
+ i2s_fifo(other, FIC_TXFLUSH);
+ i2s_fifo(i2s, FIC_RXFLUSH);
+
+ /* Gate CDCLK by default */
+ if (!is_opened(other))
+ i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
+
+ return 0;
+}
+
+static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
+{
+ struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
+ struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (!other || !other->clk) {
+
+ if (i2s->quirks & QUIRK_NEED_RSTCLR)
+ writel(0, i2s->addr + I2SCON);
+
+ clk_disable(i2s->clk);
+ clk_put(i2s->clk);
+
+ iounmap(i2s->addr);
+ }
+
+ i2s->clk = NULL;
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
+ .trigger = i2s_trigger,
+ .hw_params = i2s_hw_params,
+ .set_fmt = i2s_set_fmt,
+ .set_clkdiv = i2s_set_clkdiv,
+ .set_sysclk = i2s_set_sysclk,
+ .startup = i2s_startup,
+ .shutdown = i2s_shutdown,
+ .delay = i2s_delay,
+};
+
+#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
+
+#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static __devinit
+struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
+{
+ struct i2s_dai *i2s;
+
+ i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL);
+ if (i2s == NULL)
+ return NULL;
+
+ i2s->pdev = pdev;
+ i2s->pri_dai = NULL;
+ i2s->sec_dai = NULL;
+ i2s->i2s_dai_drv.symmetric_rates = 1;
+ i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
+ i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
+ i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
+ i2s->i2s_dai_drv.suspend = i2s_suspend;
+ i2s->i2s_dai_drv.resume = i2s_resume;
+ i2s->i2s_dai_drv.playback.channels_min = 2;
+ i2s->i2s_dai_drv.playback.channels_max = 2;
+ i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
+ i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
+
+ if (!sec) {
+ i2s->i2s_dai_drv.capture.channels_min = 2;
+ i2s->i2s_dai_drv.capture.channels_max = 2;
+ i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
+ i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
+ } else { /* Create a new platform_device for Secondary */
+ i2s->pdev = platform_device_register_resndata(NULL,
+ pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
+ NULL, 0, NULL, 0);
+ if (IS_ERR(i2s->pdev)) {
+ kfree(i2s);
+ return NULL;
+ }
+ }
+
+ /* Pre-assign snd_soc_dai_set_drvdata */
+ dev_set_drvdata(&i2s->pdev->dev, i2s);
+
+ return i2s;
+}
+
+static __devinit int samsung_i2s_probe(struct platform_device *pdev)
+{
+ u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
+ struct i2s_dai *pri_dai, *sec_dai = NULL;
+ struct s3c_audio_pdata *i2s_pdata;
+ struct samsung_i2s *i2s_cfg;
+ struct resource *res;
+ u32 regs_base, quirks;
+ int ret = 0;
+
+ /* Call during Seconday interface registration */
+ if (pdev->id >= SAMSUNG_I2S_SECOFF) {
+ sec_dai = dev_get_drvdata(&pdev->dev);
+ snd_soc_register_dai(&sec_dai->pdev->dev,
+ &sec_dai->i2s_dai_drv);
+ return 0;
+ }
+
+ i2s_pdata = pdev->dev.platform_data;
+ if (i2s_pdata == NULL) {
+ dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
+ return -ENXIO;
+ }
+ dma_pl_chan = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
+ return -ENXIO;
+ }
+ dma_cp_chan = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
+ if (res)
+ dma_pl_sec_chan = res->start;
+ else
+ dma_pl_sec_chan = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
+ return -ENXIO;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res),
+ "samsung-i2s")) {
+ dev_err(&pdev->dev, "Unable to request SFR region\n");
+ return -EBUSY;
+ }
+ regs_base = res->start;
+
+ i2s_cfg = &i2s_pdata->type.i2s;
+ quirks = i2s_cfg->quirks;
+
+ pri_dai = i2s_alloc_dai(pdev, false);
+ if (!pri_dai) {
+ dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
+ pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
+ pri_dai->dma_playback.client =
+ (struct s3c2410_dma_client *)&pri_dai->dma_playback;
+ pri_dai->dma_capture.client =
+ (struct s3c2410_dma_client *)&pri_dai->dma_capture;
+ pri_dai->dma_playback.channel = dma_pl_chan;
+ pri_dai->dma_capture.channel = dma_cp_chan;
+ pri_dai->src_clk = i2s_cfg->src_clk;
+ pri_dai->dma_playback.dma_size = 4;
+ pri_dai->dma_capture.dma_size = 4;
+ pri_dai->base = regs_base;
+ pri_dai->quirks = quirks;
+
+ if (quirks & QUIRK_PRI_6CHAN)
+ pri_dai->i2s_dai_drv.playback.channels_max = 6;
+
+ if (quirks & QUIRK_SEC_DAI) {
+ sec_dai = i2s_alloc_dai(pdev, true);
+ if (!sec_dai) {
+ dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+ sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
+ sec_dai->dma_playback.client =
+ (struct s3c2410_dma_client *)&sec_dai->dma_playback;
+ /* Use iDMA always if SysDMA not provided */
+ sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
+ sec_dai->src_clk = i2s_cfg->src_clk;
+ sec_dai->dma_playback.dma_size = 4;
+ sec_dai->base = regs_base;
+ sec_dai->quirks = quirks;
+ sec_dai->pri_dai = pri_dai;
+ pri_dai->sec_dai = sec_dai;
+ }
+
+ if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
+ dev_err(&pdev->dev, "Unable to configure gpio\n");
+ ret = -EINVAL;
+ goto err3;
+ }
+
+ snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
+
+ return 0;
+err3:
+ kfree(sec_dai);
+err2:
+ kfree(pri_dai);
+err1:
+ release_mem_region(regs_base, resource_size(res));
+
+ return ret;
+}
+
+static __devexit int samsung_i2s_remove(struct platform_device *pdev)
+{
+ struct i2s_dai *i2s, *other;
+
+ i2s = dev_get_drvdata(&pdev->dev);
+ other = i2s->pri_dai ? : i2s->sec_dai;
+
+ if (other) {
+ other->pri_dai = NULL;
+ other->sec_dai = NULL;
+ } else {
+ struct resource *res;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+ }
+
+ i2s->pri_dai = NULL;
+ i2s->sec_dai = NULL;
+
+ kfree(i2s);
+
+ snd_soc_unregister_dai(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver samsung_i2s_driver = {
+ .probe = samsung_i2s_probe,
+ .remove = samsung_i2s_remove,
+ .driver = {
+ .name = "samsung-i2s",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init samsung_i2s_init(void)
+{
+ return platform_driver_register(&samsung_i2s_driver);
+}
+module_init(samsung_i2s_init);
+
+static void __exit samsung_i2s_exit(void)
+{
+ platform_driver_unregister(&samsung_i2s_driver);
+}
+module_exit(samsung_i2s_exit);
+
+/* Module information */
+MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Samsung I2S Interface");
+MODULE_ALIAS("platform:samsung-i2s");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
new file mode 100644
index 000000000000..8e15f6a616d1
--- /dev/null
+++ b/sound/soc/samsung/i2s.h
@@ -0,0 +1,29 @@
+/* sound/soc/samsung/i2s.h
+ *
+ * ALSA SoC Audio Layer - Samsung I2S Controller driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. 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 __SND_SOC_SAMSUNG_I2S_H
+#define __SND_SOC_SAMSUNG_I2S_H
+
+/*
+ * Maximum number of I2S blocks that any SoC can have.
+ * The secondary interface of a CPU dai(if there exists any),
+ * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
+ */
+#define SAMSUNG_I2S_SECOFF 4
+
+#define SAMSUNG_I2S_DIV_BCLK 1
+
+#define SAMSUNG_I2S_RCLKSRC_0 0
+#define SAMSUNG_I2S_RCLKSRC_1 1
+#define SAMSUNG_I2S_CDCLK 2
+
+#endif /* __SND_SOC_SAMSUNG_I2S_H */
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 49605cd83947..08802520e014 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/jive_wm8750.c
+/* sound/soc/samsung/jive_wm8750.c
*
* Copyright 2007,2008 Simtec Electronics
*
@@ -21,11 +21,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c2412-i2s.h"
#include "../codecs/wm8750.h"
@@ -111,18 +110,19 @@ static struct snd_soc_ops jive_ops = {
static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* These endpoints are not being used. */
- snd_soc_dapm_nc_pin(codec, "LINPUT2");
- snd_soc_dapm_nc_pin(codec, "RINPUT2");
- snd_soc_dapm_nc_pin(codec, "LINPUT3");
- snd_soc_dapm_nc_pin(codec, "RINPUT3");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "MONO");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT2");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "MONO");
/* Add jive specific widgets */
- err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
ARRAY_SIZE(wm8750_dapm_widgets));
if (err) {
printk(KERN_ERR "%s: failed to add widgets (%d)\n",
@@ -130,8 +130,8 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
return err;
}
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -141,7 +141,7 @@ static struct snd_soc_dai_link jive_dai = {
.stream_name = "WM8750",
.cpu_dai_name = "s3c2412-i2s",
.codec_dai_name = "wm8750-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8750-codec.0-0x1a",
.init = jive_wm8750_init,
.ops = &jive_ops,
diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/samsung/lm4857.h
index 0cf5b7011d6f..0cf5b7011d6f 100644
--- a/sound/soc/s3c24xx/lm4857.h
+++ b/sound/soc/samsung/lm4857.h
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index abe64abe8c84..a2bb34def740 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -21,10 +21,9 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card ln2440sbc;
@@ -32,10 +31,10 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 HiFi",
- .cpu_dai_name = "s3c-ac97",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
index e97bdf150a03..3eec610c10f9 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/samsung/neo1973_gta02_wm8753.c
@@ -22,7 +22,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
@@ -32,7 +31,7 @@
#include <asm/io.h>
#include <mach/gta02.h>
#include "../codecs/wm8753.h"
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
static struct snd_soc_card neo1973_gta02;
@@ -333,16 +332,17 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "OUT4");
- snd_soc_dapm_nc_pin(codec, "LINE1");
- snd_soc_dapm_nc_pin(codec, "LINE2");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT4");
+ snd_soc_dapm_nc_pin(dapm, "LINE1");
+ snd_soc_dapm_nc_pin(dapm, "LINE2");
/* Add neo1973 gta02 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
ARRAY_SIZE(wm8753_dapm_widgets));
/* add neo1973 gta02 specific controls */
@@ -353,25 +353,25 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* set up neo1973 gta02 specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* set endpoints to default off mode */
- snd_soc_dapm_disable_pin(codec, "Stereo Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Handset Mic");
- snd_soc_dapm_disable_pin(codec, "Handset Spk");
+ snd_soc_dapm_disable_pin(dapm, "Stereo Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Handset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Handset Spk");
/* allow audio paths from the GSM modem to run during suspend */
- snd_soc_dapm_ignore_suspend(codec, "Stereo Out");
- snd_soc_dapm_ignore_suspend(codec, "GSM Line Out");
- snd_soc_dapm_ignore_suspend(codec, "GSM Line In");
- snd_soc_dapm_ignore_suspend(codec, "Headset Mic");
- snd_soc_dapm_ignore_suspend(codec, "Handset Mic");
- snd_soc_dapm_ignore_suspend(codec, "Handset Spk");
+ snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
+ snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
+ snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "wm8753-hifi",
.init = neo1973_gta02_wm8753_init,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8753-codec.0-0x1a",
.ops = &neo1973_gta02_hifi_ops,
},
@@ -411,7 +411,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
.codec_dai_name = "wm8753-voice",
.ops = &neo1973_gta02_voice_ops,
.codec_name = "wm8753-codec.0-0x1a",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
@@ -438,25 +438,21 @@ static int __init neo1973_gta02_init(void)
return -ENOMEM;
/* register bluetooth DAI here */
- ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai);
- if (ret) {
- platform_device_put(neo1973_gta02_snd_device);
- return ret;
- }
+ ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
+ if (ret)
+ goto err_put_device;
platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
ret = platform_device_add(neo1973_gta02_snd_device);
- if (ret) {
- platform_device_put(neo1973_gta02_snd_device);
- return ret;
- }
+ if (ret)
+ goto err_unregister_dai;
/* Initialise GPIOs used by amp */
ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
if (ret) {
pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
- goto err_unregister_device;
+ goto err_del_device;
}
ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
@@ -483,15 +479,19 @@ err_free_gpio_amp_shut:
gpio_free(GTA02_GPIO_AMP_SHUT);
err_free_gpio_hp_in:
gpio_free(GTA02_GPIO_HP_IN);
-err_unregister_device:
- platform_device_unregister(neo1973_gta02_snd_device);
+err_del_device:
+ platform_device_del(neo1973_gta02_snd_device);
+err_unregister_dai:
+ snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
+err_put_device:
+ platform_device_put(neo1973_gta02_snd_device);
return ret;
}
module_init(neo1973_gta02_init);
static void __exit neo1973_gta02_exit(void)
{
- snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1);
+ snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
platform_device_unregister(neo1973_gta02_snd_device);
gpio_free(GTA02_GPIO_HP_IN);
gpio_free(GTA02_GPIO_AMP_SHUT);
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index f4f2ee731f01..c7a24514beb5 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -21,7 +21,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <asm/mach-types.h>
@@ -36,7 +35,7 @@
#include "../codecs/wm8753.h"
#include "lm4857.h"
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
/* define the scenarios */
@@ -237,81 +236,83 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
pr_debug("Entered %s\n", __func__);
switch (neo1973_scenario) {
case NEO_AUDIO_OFF:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_HANDSET:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_HEADSET:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_GSM_CALL_AUDIO_BLUETOOTH:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line Out");
- snd_soc_dapm_enable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_enable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_STEREO_TO_SPEAKERS:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_STEREO_TO_HEADPHONES:
- snd_soc_dapm_enable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_HANDSET:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_enable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_HEADSET:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_enable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
case NEO_CAPTURE_BLUETOOTH:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
break;
default:
- snd_soc_dapm_disable_pin(codec, "Audio Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line Out");
- snd_soc_dapm_disable_pin(codec, "GSM Line In");
- snd_soc_dapm_disable_pin(codec, "Headset Mic");
- snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_disable_pin(dapm, "Audio Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
+ snd_soc_dapm_disable_pin(dapm, "GSM Line In");
+ snd_soc_dapm_disable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_disable_pin(dapm, "Call Mic");
}
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -502,20 +503,21 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
pr_debug("Entered %s\n", __func__);
/* set up NC codec pins */
- snd_soc_dapm_nc_pin(codec, "LOUT2");
- snd_soc_dapm_nc_pin(codec, "ROUT2");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "OUT4");
- snd_soc_dapm_nc_pin(codec, "LINE1");
- snd_soc_dapm_nc_pin(codec, "LINE2");
+ snd_soc_dapm_nc_pin(dapm, "LOUT2");
+ snd_soc_dapm_nc_pin(dapm, "ROUT2");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "OUT4");
+ snd_soc_dapm_nc_pin(dapm, "LINE1");
+ snd_soc_dapm_nc_pin(dapm, "LINE2");
/* Add neo1973 specific widgets */
- snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
ARRAY_SIZE(wm8753_dapm_widgets));
/* set endpoints to default mode */
@@ -528,10 +530,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
return err;
/* set up neo1973 specific audio routes */
- err = snd_soc_dapm_add_routes(codec, dapm_routes,
+ err = snd_soc_dapm_add_routes(dapm, dapm_routes,
ARRAY_SIZE(dapm_routes));
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -556,7 +558,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
{ /* Hifi Playback - for similatious use with voice below */
.name = "WM8753",
.stream_name = "WM8753 HiFi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "wm8753-hifi",
.codec_name = "wm8753-codec.0-0x1a",
@@ -566,7 +568,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
{ /* Voice via BT */
.name = "Bluetooth",
.stream_name = "Voice",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "bluetooth-dai",
.codec_dai_name = "wm8753-voice",
.codec_name = "wm8753-codec.0-0x1a",
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/samsung/pcm.c
index 2e020e1b4eab..48d0b750406b 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-pcm.c
+/* sound/soc/samsung/pcm.c
*
* ALSA SoC Audio Layer - S3C PCM-Controller driver
*
@@ -29,8 +29,8 @@
#include <plat/audio.h>
#include <plat/dma.h>
-#include "s3c-dma.h"
-#include "s3c-pcm.h"
+#include "dma.h"
+#include "pcm.h"
static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
.name = "PCM Stereo out"
diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/samsung/pcm.h
index f60baa19387d..03393dcf852d 100644
--- a/sound/soc/s3c24xx/s3c-pcm.h
+++ b/sound/soc/samsung/pcm.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-pcm.h
+/* sound/soc/samsung/pcm.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
diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h
index 5e5e5680580b..5e5e5680580b 100644
--- a/sound/soc/s3c24xx/regs-i2s-v2.h
+++ b/sound/soc/samsung/regs-i2s-v2.h
diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 468cc11fdf47..5a4587e02886 100644
--- a/sound/soc/s3c24xx/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -25,7 +25,6 @@
#include <linux/clk.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/uda1380.h>
#include <sound/jack.h>
@@ -35,7 +34,7 @@
#include <asm/mach-types.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "../codecs/uda1380.h"
@@ -95,7 +94,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
.cpu_dai_name = "s3c24xx-iis",
.codec_dai_name = "uda1380-hifi",
.init = rx1950_uda1380_init,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "uda1380-codec.0-001a",
.ops = &rx1950_ops,
},
@@ -228,26 +227,27 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
/* Add rx1950 specific widgets */
- err = snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
+ err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
ARRAY_SIZE(uda1380_dapm_widgets));
if (err)
return err;
/* Set up rx1950 specific audio path audio_mapnects */
- err = snd_soc_dapm_add_routes(codec, audio_map,
+ err = snd_soc_dapm_add_routes(dapm, audio_map,
ARRAY_SIZE(audio_map));
if (err)
return err;
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
&hp_jack);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index b3866d5b19e9..094f36e41e83 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-i2c-v2.c
+/* sound/soc/samsung/s3c-i2c-v2.c
*
* ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
*
@@ -28,7 +28,7 @@
#include "regs-i2s-v2.h"
#include "s3c-i2s-v2.h"
-#include "s3c-dma.h"
+#include "dma.h"
#undef S3C_IIS_V2_SUPPORTED
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h
index d45830151484..f8297d9bb8a3 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/samsung/s3c-i2s-v2.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c-i2s-v2.h
+/* sound/soc/samsung/s3c-i2s-v2.h
*
* ALSA Soc Audio Layer - S3C_I2SV2 I2S driver
*
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 4a861cfa52c5..7ea837867124 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c2412-i2s.c
+/* sound/soc/samsung/s3c2412-i2s.c
*
* ALSA Soc Audio Layer - S3C2412 I2S driver
*
@@ -35,7 +35,7 @@
#include <mach/regs-gpio.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "regs-i2s-v2.h"
#include "s3c2412-i2s.h"
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h
index 01a0471ac65c..02ad5794c0a9 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/samsung/s3c2412-i2s.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c2412-i2s.c
+/* sound/soc/samsung/s3c2412-i2s.c
*
* ALSA Soc Audio Layer - S3C2412 I2S driver
*
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index e060daaa458f..13e41ed8e22b 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -38,7 +38,7 @@
#include <plat/regs-iis.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
static struct s3c2410_dma_client s3c24xx_dma_client_out = {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h
index f9ca04edacb7..f9ca04edacb7 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.h
+++ b/sound/soc/samsung/s3c24xx-i2s.h
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index c4c111442010..a434032d1832 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec.c
+/* sound/soc/samsung/s3c24xx_simtec.c
*
* Copyright 2009 Simtec Electronics
*
@@ -17,11 +17,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h
index e63d5ff9c41f..8270748a2c41 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.h
+++ b/sound/soc/samsung/s3c24xx_simtec.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec.h
+/* sound/soc/samsung/s3c24xx_simtec.h
*
* Copyright 2009 Simtec Electronics
*
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index f88453735ae2..0083aff5a83d 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+/* sound/soc/samsung/s3c24xx_simtec_hermes.c
*
* Copyright 2009 Simtec Electronics
*
@@ -14,11 +14,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
@@ -76,19 +75,20 @@ static const struct snd_soc_dapm_route base_map[] = {
static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, dapm_widgets,
ARRAY_SIZE(dapm_widgets));
- snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
+ snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
simtec_audio_init(rtd);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -99,7 +99,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = {
.codec_name = "tlv320aic3x-codec.0-0x1a",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.init = simtec_hermes_init,
};
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index c0967593510d..fbba4e367729 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
*
* Copyright 2009 Simtec Electronics
*
@@ -14,11 +14,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <plat/audio-simtec.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "s3c24xx_simtec.h"
@@ -65,19 +64,20 @@ static const struct snd_soc_dapm_route base_map[] = {
static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, dapm_widgets,
ARRAY_SIZE(dapm_widgets));
- snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
+ snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Line In");
- snd_soc_dapm_enable_pin(codec, "Line Out");
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Line In");
+ snd_soc_dapm_enable_pin(dapm, "Line Out");
+ snd_soc_dapm_enable_pin(dapm, "Mic Jack");
simtec_audio_init(rtd);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
@@ -88,7 +88,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = {
.codec_name = "tlv320aic3x-codec.0-0x1a",
.cpu_dai_name = "s3c24xx-i2s",
.codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.init = simtec_tlv320aic23_init,
};
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index bd48ffbde880..cdc8ecbcb8ef 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -18,13 +18,12 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/s3c24xx_uda134x.h>
#include <sound/uda134x.h>
#include <plat/regs-iis.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "s3c24xx-i2s.h"
#include "../codecs/uda134x.h"
@@ -231,7 +230,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
.codec_dai_name = "uda134x-hifi",
.cpu_dai_name = "s3c24xx-i2s",
.ops = &s3c24xx_uda134x_ops,
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
};
static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index dd20ca7f4681..61e2b5219d42 100644
--- a/sound/soc/s3c24xx/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/smartq_wm8987.c
+/* sound/soc/samsung/smartq_wm8987.c
*
* Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com>
*
@@ -19,13 +19,13 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
#include "../codecs/wm8750.h"
@@ -39,15 +39,11 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct s3c_i2sv2_rate_calc div;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned int clk = 0;
int ret;
- s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
- s3c_i2sv2_get_clock(cpu_dai));
-
switch (params_rate(params)) {
case 8000:
case 16000:
@@ -78,20 +74,21 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
+ /* Use PCLK for I2S signal generation */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
+ 0, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
- /* set MCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div);
+ /* Gate the RCLK output on PAD */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
+ 0, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
- /* set prescaler division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER,
- div.clk_div - 1);
+ /* set the codec system clock for DAC and ADC */
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
+ SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
@@ -156,12 +153,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LINPUT2", NULL, "Mic Bias"},
};
-static int smartq_wm8987_init(struct snd_soc_codec *codec)
+static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
int err = 0;
/* Add SmartQ specific widgets */
- snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets,
ARRAY_SIZE(wm8987_dapm_widgets));
/* add SmartQ specific controls */
@@ -172,25 +171,25 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec)
return err;
/* setup SmartQ specific audio path */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* set endpoints to not connected */
- snd_soc_dapm_nc_pin(codec, "LINPUT1");
- snd_soc_dapm_nc_pin(codec, "RINPUT1");
- snd_soc_dapm_nc_pin(codec, "OUT3");
- snd_soc_dapm_nc_pin(codec, "ROUT1");
+ snd_soc_dapm_nc_pin(dapm, "LINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "RINPUT1");
+ snd_soc_dapm_nc_pin(dapm, "OUT3");
+ snd_soc_dapm_nc_pin(dapm, "ROUT1");
/* set endpoints to default off mode */
- snd_soc_dapm_enable_pin(codec, "Internal Speaker");
- snd_soc_dapm_enable_pin(codec, "Internal Mic");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+ snd_soc_dapm_enable_pin(dapm, "Internal Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Internal Mic");
+ snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- err = snd_soc_dapm_sync(codec);
+ err = snd_soc_dapm_sync(dapm);
if (err)
return err;
/* Headphone jack detection */
- err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack",
+ err = snd_soc_jack_new(codec, "Headphone Jack",
SND_JACK_HEADPHONE, &smartq_jack);
if (err)
return err;
@@ -211,9 +210,9 @@ static struct snd_soc_dai_link smartq_dai[] = {
{
.name = "wm8987",
.stream_name = "SmartQ Hi-Fi",
- .cpu_dai_name = "s3c64xx-i2s.0",
+ .cpu_dai_name = "samsung-i2s.0",
.codec_dai_name = "wm8750-hifi",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.codec_name = "wm8750-codec.0-0x1a",
.init = smartq_wm8987_init,
.ops = &smartq_hifi_ops,
@@ -275,6 +274,7 @@ err_unregister_device:
static void __exit smartq_exit(void)
{
+ gpio_free(S3C64XX_GPK(12));
snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios),
smartq_jack_gpios);
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 4613288c2772..3be7e7e92d6e 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -17,10 +17,9 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card smdk2443;
@@ -28,10 +27,10 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 HiFi",
- .cpu_dai_name = "s3c-ac97",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
},
};
diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index c8bd90488a87..cb2f4d04ab7e 100644
--- a/sound/soc/s3c24xx/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -18,7 +18,7 @@
#include <sound/soc.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "spdif.h"
/* Audio clock settings are belonged to board specific part. Every
@@ -28,7 +28,7 @@
static int set_audio_clock_heirachy(struct platform_device *pdev)
{
struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif;
- int ret;
+ int ret = 0;
fout_epll = clk_get(NULL, "fout_epll");
if (IS_ERR(fout_epll)) {
@@ -152,12 +152,10 @@ static struct snd_soc_ops smdk_spdif_ops = {
.hw_params = smdk_hw_params,
};
-static struct snd_soc_card smdk;
-
static struct snd_soc_dai_link smdk_dai = {
.name = "S/PDIF",
.stream_name = "S/PDIF PCM Playback",
- .platform_name = "s3c24xx-pcm-audio",
+ .platform_name = "samsung-audio",
.cpu_dai_name = "samsung-spdif",
.codec_dai_name = "dit-hifi",
.codec_name = "spdif-dit",
@@ -183,7 +181,7 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_spdif_dit_device);
if (ret)
- goto err2;
+ goto err1;
smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1);
if (!smdk_snd_spdif_device) {
@@ -195,17 +193,21 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_spdif_device);
if (ret)
- goto err1;
+ goto err3;
/* Set audio clock heirachy manually */
ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
if (ret)
- goto err1;
+ goto err4;
return 0;
-err1:
+err4:
+ platform_device_del(smdk_snd_spdif_device);
+err3:
platform_device_put(smdk_snd_spdif_device);
err2:
+ platform_device_del(smdk_snd_spdif_dit_device);
+err1:
platform_device_put(smdk_snd_spdif_dit_device);
return ret;
}
@@ -213,6 +215,7 @@ err2:
static void __exit smdk_exit(void)
{
platform_device_unregister(smdk_snd_spdif_device);
+ platform_device_unregister(smdk_snd_spdif_dit_device);
}
module_init(smdk_init);
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 052e499b68d1..b2cff1a44aed 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -1,5 +1,5 @@
/*
- * smdk64xx_wm8580.c
+ * smdk_wm8580.c
*
* Copyright (c) 2009 Samsung Electronics Co. Ltd
* Author: Jaswinder Singh <jassi.brar@samsung.com>
@@ -16,11 +16,12 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
#include "../codecs/wm8580.h"
-#include "s3c-dma.h"
-#include "s3c64xx-i2s.h"
+#include "dma.h"
+#include "i2s.h"
/*
* Default CFG switch settings to use this driver:
@@ -28,10 +29,10 @@
* SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On
*/
-/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
-#define SMDK64XX_WM8580_FREQ 12000000
+/* SMDK has a 12MHZ crystal attached to WM8580 */
+#define SMDK_WM8580_FREQ 12000000
-static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
+static int smdk_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -96,17 +97,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* We use PCLK for basic ops in SoC-Slave mode */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
/* Set WM8580 to drive MCLK from its PLLA */
ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
WM8580_CLKSRC_PLLA);
@@ -114,7 +104,7 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
return ret;
ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
- SMDK64XX_WM8580_FREQ, pll_out);
+ SMDK_WM8580_FREQ, pll_out);
if (ret < 0)
return ret;
@@ -123,32 +113,24 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
- if (ret < 0)
- return ret;
-
return 0;
}
/*
- * SMDK64XX WM8580 DAI operations.
+ * SMDK WM8580 DAI operations.
*/
-static struct snd_soc_ops smdk64xx_ops = {
- .hw_params = smdk64xx_hw_params,
+static struct snd_soc_ops smdk_ops = {
+ .hw_params = smdk_hw_params,
};
-/* SMDK64xx Playback widgets */
+/* SMDK Playback widgets */
static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
SND_SOC_DAPM_HP("Front", NULL),
SND_SOC_DAPM_HP("Center+Sub", NULL),
SND_SOC_DAPM_HP("Rear", NULL),
};
-/* SMDK64xx Capture widgets */
+/* SMDK Capture widgets */
static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
SND_SOC_DAPM_MIC("MicIn", NULL),
SND_SOC_DAPM_LINE("LineIn", NULL),
@@ -179,94 +161,132 @@ static const struct snd_soc_dapm_route audio_map_rx[] = {
{"Rear", NULL, "VOUT3R"},
};
-static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
+static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- /* Add smdk64xx specific Capture widgets */
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
+ /* Add smdk specific Capture widgets */
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt,
ARRAY_SIZE(wm8580_dapm_widgets_cpt));
/* Set up PAIFTX audio path */
- snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx));
+ snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx));
/* Enabling the microphone requires the fitting of a 0R
* resistor to connect the line from the microphone jack.
*/
- snd_soc_dapm_disable_pin(codec, "MicIn");
+ snd_soc_dapm_disable_pin(dapm, "MicIn");
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
-static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
+static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- /* Add smdk64xx specific Playback widgets */
- snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
+ /* Add smdk specific Playback widgets */
+ snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk,
ARRAY_SIZE(wm8580_dapm_widgets_pbk));
/* Set up PAIFRX audio path */
- snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx));
+ snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx));
/* signal a DAPM event */
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
return 0;
}
-static struct snd_soc_dai_link smdk64xx_dai[] = {
-{ /* Primary Playback i/f */
- .name = "WM8580 PAIF RX",
- .stream_name = "Playback",
- .cpu_dai_name = "s3c64xx-iis-v4",
- .codec_dai_name = "wm8580-hifi-playback",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8580-codec.0-001b",
- .init = smdk64xx_wm8580_init_paifrx,
- .ops = &smdk64xx_ops,
-},
-{ /* Primary Capture i/f */
- .name = "WM8580 PAIF TX",
- .stream_name = "Capture",
- .cpu_dai_name = "s3c64xx-iis-v4",
- .codec_dai_name = "wm8580-hifi-capture",
- .platform_name = "s3c24xx-pcm-audio",
- .codec_name = "wm8580-codec.0-001b",
- .init = smdk64xx_wm8580_init_paiftx,
- .ops = &smdk64xx_ops,
-},
+enum {
+ PRI_PLAYBACK = 0,
+ PRI_CAPTURE,
+ SEC_PLAYBACK,
+};
+
+static struct snd_soc_dai_link smdk_dai[] = {
+ [PRI_PLAYBACK] = { /* Primary Playback i/f */
+ .name = "WM8580 PAIF RX",
+ .stream_name = "Playback",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm8580-hifi-playback",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paifrx,
+ .ops = &smdk_ops,
+ },
+ [PRI_CAPTURE] = { /* Primary Capture i/f */
+ .name = "WM8580 PAIF TX",
+ .stream_name = "Capture",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm8580-hifi-capture",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paiftx,
+ .ops = &smdk_ops,
+ },
+ [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
+ .name = "Sec_FIFO TX",
+ .stream_name = "Playback",
+ .cpu_dai_name = "samsung-i2s.x",
+ .codec_dai_name = "wm8580-hifi-playback",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8580-codec.0-001b",
+ .init = smdk_wm8580_init_paifrx,
+ .ops = &smdk_ops,
+ },
};
-static struct snd_soc_card smdk64xx = {
- .name = "SMDK64xx 5.1",
- .dai_link = smdk64xx_dai,
- .num_links = ARRAY_SIZE(smdk64xx_dai),
+static struct snd_soc_card smdk = {
+ .name = "SMDK-I2S",
+ .dai_link = smdk_dai,
+ .num_links = 2,
};
-static struct platform_device *smdk64xx_snd_device;
+static struct platform_device *smdk_snd_device;
-static int __init smdk64xx_audio_init(void)
+static int __init smdk_audio_init(void)
{
int ret;
+ char *str;
+
+ if (machine_is_smdkc100() || machine_is_smdk6442()
+ || machine_is_smdkv210() || machine_is_smdkc110()) {
+ smdk.num_links = 3;
+ /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
+ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
+ str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
+ } else if (machine_is_smdk6410()) {
+ str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
+ str[strlen(str) - 1] = '2';
+ str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name;
+ str[strlen(str) - 1] = '2';
+ }
- smdk64xx_snd_device = platform_device_alloc("soc-audio", -1);
- if (!smdk64xx_snd_device)
+ smdk_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!smdk_snd_device)
return -ENOMEM;
- platform_set_drvdata(smdk64xx_snd_device, &smdk64xx);
- ret = platform_device_add(smdk64xx_snd_device);
+ platform_set_drvdata(smdk_snd_device, &smdk);
+ ret = platform_device_add(smdk_snd_device);
if (ret)
- platform_device_put(smdk64xx_snd_device);
+ platform_device_put(smdk_snd_device);
return ret;
}
-module_init(smdk64xx_audio_init);
+module_init(smdk_audio_init);
+
+static void __exit smdk_audio_exit(void)
+{
+ platform_device_unregister(smdk_snd_device);
+}
+module_exit(smdk_audio_exit);
MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
-MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580");
+MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
new file mode 100644
index 000000000000..e7c1009a1e1d
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -0,0 +1,176 @@
+/*
+ * smdk_wm8994.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include "../codecs/wm8994.h"
+
+ /*
+ * Default CFG switch settings to use this driver:
+ * SMDKV310: CFG5-1000, CFG7-111111
+ */
+
+ /*
+ * Configure audio route as :-
+ * $ amixer sset 'DAC1' on,on
+ * $ amixer sset 'Right Headphone Mux' 'DAC'
+ * $ amixer sset 'Left Headphone Mux' 'DAC'
+ * $ amixer sset 'DAC1R Mixer AIF1.1' on
+ * $ amixer sset 'DAC1L Mixer AIF1.1' on
+ * $ amixer sset 'IN2L' on
+ * $ amixer sset 'IN2L PGA IN2LN' on
+ * $ amixer sset 'MIXINL IN2L' on
+ * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
+ * $ amixer sset 'IN2R' on
+ * $ amixer sset 'IN2R PGA IN2RN' on
+ * $ amixer sset 'MIXINR IN2R' on
+ * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
+ */
+
+/* SMDK has a 16.934MHZ crystal attached to WM8994 */
+#define SMDK_WM8994_FREQ 16934000
+
+static int smdk_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ unsigned int pll_out;
+ int ret;
+
+ /* AIF1CLK should be >=3MHz for optimal performance */
+ if (params_rate(params) == 8000 || params_rate(params) == 11025)
+ pll_out = params_rate(params) * 512;
+ else
+ pll_out = params_rate(params) * 256;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
+ SMDK_WM8994_FREQ, pll_out);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
+ pll_out, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * SMDK WM8994 DAI operations.
+ */
+static struct snd_soc_ops smdk_ops = {
+ .hw_params = smdk_hw_params,
+};
+
+static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ /* HeadPhone */
+ snd_soc_dapm_enable_pin(dapm, "HPOUT1R");
+ snd_soc_dapm_enable_pin(dapm, "HPOUT1L");
+
+ /* MicIn */
+ snd_soc_dapm_enable_pin(dapm, "IN1LN");
+ snd_soc_dapm_enable_pin(dapm, "IN1RN");
+
+ /* LineIn */
+ snd_soc_dapm_enable_pin(dapm, "IN2LN");
+ snd_soc_dapm_enable_pin(dapm, "IN2RN");
+
+ /* Other pins NC */
+ snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
+ snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTLN");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTLP");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
+ snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
+ snd_soc_dapm_nc_pin(dapm, "IN1LP");
+ snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
+ snd_soc_dapm_nc_pin(dapm, "IN1RP");
+ snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
+
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link smdk_dai[] = {
+ { /* Primary DAI i/f */
+ .name = "WM8994 AIF1",
+ .stream_name = "Pri_Dai",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm8994-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8994-codec",
+ .init = smdk_wm8994_init_paiftx,
+ .ops = &smdk_ops,
+ }, { /* Sec_Fifo Playback i/f */
+ .name = "Sec_FIFO TX",
+ .stream_name = "Sec_Dai",
+ .cpu_dai_name = "samsung-i2s.4",
+ .codec_dai_name = "wm8994-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8994-codec",
+ .ops = &smdk_ops,
+ },
+};
+
+static struct snd_soc_card smdk = {
+ .name = "SMDK-I2S",
+ .dai_link = smdk_dai,
+ .num_links = ARRAY_SIZE(smdk_dai),
+};
+
+static struct platform_device *smdk_snd_device;
+
+static int __init smdk_audio_init(void)
+{
+ int ret;
+
+ smdk_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!smdk_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(smdk_snd_device, &smdk);
+
+ ret = platform_device_add(smdk_snd_device);
+ if (ret)
+ platform_device_put(smdk_snd_device);
+
+ return ret;
+}
+module_init(smdk_audio_init);
+
+static void __exit smdk_audio_exit(void)
+{
+ platform_device_unregister(smdk_snd_device);
+}
+module_exit(smdk_audio_exit);
+
+MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 33ba8fdbcf07..ae5fed6f772f 100644
--- a/sound/soc/s3c24xx/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -15,8 +15,8 @@
#include <linux/device.h>
#include <sound/soc.h>
-#include "s3c-dma.h"
-#include "s3c-ac97.h"
+#include "dma.h"
+#include "ac97.h"
static struct snd_soc_card smdk;
@@ -27,6 +27,7 @@ static struct snd_soc_card smdk;
* SMDKC100: Set CFG6 1-3 On, CFG7 1 On
* SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On
* SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On
+ * SMDKV310: Set CFG2 1-2 Off, CFG4 All On, CFG7 All Off, CFG8 1-On
*/
/*
@@ -45,8 +46,8 @@ static struct snd_soc_card smdk;
static struct snd_soc_dai_link smdk_dai = {
.name = "AC97",
.stream_name = "AC97 PCM",
- .platform_name = "s3c24xx-pcm-audio",
- .cpu_dai_name = "s3c-ac97",
+ .platform_name = "samsung-audio",
+ .cpu_dai_name = "samsung-ac97",
.codec_dai_name = "wm9713-hifi",
.codec_name = "wm9713-codec",
};
@@ -70,24 +71,27 @@ static int __init smdk_init(void)
ret = platform_device_add(smdk_snd_wm9713_device);
if (ret)
- goto err;
+ goto err1;
smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
if (!smdk_snd_ac97_device) {
ret = -ENOMEM;
- goto err;
+ goto err2;
}
platform_set_drvdata(smdk_snd_ac97_device, &smdk);
ret = platform_device_add(smdk_snd_ac97_device);
- if (ret) {
- platform_device_put(smdk_snd_ac97_device);
- goto err;
- }
+ if (ret)
+ goto err3;
return 0;
-err:
+
+err3:
+ platform_device_put(smdk_snd_ac97_device);
+err2:
+ platform_device_del(smdk_snd_wm9713_device);
+err1:
platform_device_put(smdk_snd_wm9713_device);
return ret;
}
diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/samsung/spdif.c
index ce554e9cabcc..f0816404ea3e 100644
--- a/sound/soc/s3c24xx/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/spdif.c
+/* sound/soc/samsung/spdif.c
*
* ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
*
@@ -20,7 +20,7 @@
#include <plat/audio.h>
#include <mach/dma.h>
-#include "s3c-dma.h"
+#include "dma.h"
#include "spdif.h"
/* Registers */
diff --git a/sound/soc/s3c24xx/spdif.h b/sound/soc/samsung/spdif.h
index 3ed55592710f..4f72cb446dbf 100644
--- a/sound/soc/s3c24xx/spdif.h
+++ b/sound/soc/samsung/spdif.h
@@ -1,4 +1,4 @@
-/* sound/soc/s3c24xx/spdif.h
+/* sound/soc/samsung/spdif.h
*
* ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
*
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 7f0a496e07ce..d8e06a607a22 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -48,7 +48,7 @@ config SND_SH7760_AC97
config SND_FSI_AK4642
tristate "FSI-AK4642 sound support"
- depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
+ depends on SND_SOC_SH4_FSI && I2C
select SND_SOC_AK4642
help
This option enables generic sound support for the
@@ -56,7 +56,7 @@ config SND_FSI_AK4642
config SND_FSI_DA7210
tristate "FSI-DA7210 sound support"
- depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
+ depends on SND_SOC_SH4_FSI && I2C
select SND_SOC_DA7210
help
This option enables generic sound support for the
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index d96602de71de..a14820ac9665 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -12,6 +12,14 @@
#include <linux/platform_device.h>
#include <sound/sh_fsi.h>
+struct fsi_ak4642_data {
+ const char *name;
+ const char *card;
+ const char *cpu_dai;
+ const char *codec;
+ const char *platform;
+};
+
static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->codec_dai;
@@ -27,37 +35,42 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
}
static struct snd_soc_dai_link fsi_dai_link = {
- .name = "AK4642",
- .stream_name = "AK4642",
- .cpu_dai_name = "fsia-dai", /* fsi A */
.codec_dai_name = "ak4642-hifi",
-#ifdef CONFIG_MACH_AP4EVB
- .platform_name = "sh_fsi2",
- .codec_name = "ak4642-codec.0-0013",
-#else
- .platform_name = "sh_fsi.0",
- .codec_name = "ak4642-codec.0-0012",
-#endif
.init = fsi_ak4642_dai_init,
- .ops = NULL,
};
static struct snd_soc_card fsi_soc_card = {
- .name = "FSI (AK4642)",
.dai_link = &fsi_dai_link,
.num_links = 1,
};
static struct platform_device *fsi_snd_device;
-static int __init fsi_ak4642_init(void)
+static int fsi_ak4642_probe(struct platform_device *pdev)
{
int ret = -ENOMEM;
+ const struct platform_device_id *id_entry;
+ struct fsi_ak4642_data *pdata;
+
+ id_entry = pdev->id_entry;
+ if (!id_entry) {
+ dev_err(&pdev->dev, "unknown fsi ak4642\n");
+ return -ENODEV;
+ }
+
+ pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A);
if (!fsi_snd_device)
goto out;
+ fsi_dai_link.name = pdata->name;
+ fsi_dai_link.stream_name = pdata->name;
+ fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
+ fsi_dai_link.platform_name = pdata->platform;
+ fsi_dai_link.codec_name = pdata->codec;
+ fsi_soc_card.name = pdata->card;
+
platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_snd_device);
@@ -68,9 +81,108 @@ out:
return ret;
}
-static void __exit fsi_ak4642_exit(void)
+static int fsi_ak4642_remove(struct platform_device *pdev)
{
platform_device_unregister(fsi_snd_device);
+ return 0;
+}
+
+static struct fsi_ak4642_data fsi_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIA (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSIB (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIA (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSIB (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi.0",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2A (AK4642)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4642 = {
+ .name = "AK4642",
+ .card = "FSI2B (AK4642)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_a_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2A (AK4643)",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct fsi_ak4642_data fsi2_b_ak4643 = {
+ .name = "AK4643",
+ .card = "FSI2B (AK4643)",
+ .cpu_dai = "fsib-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+};
+
+static struct platform_device_id fsi_id_table[] = {
+ /* FSI */
+ { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
+ { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
+ { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
+ { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
+
+ /* FSI 2 */
+ { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
+ { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
+ { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
+ { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
+ {},
+};
+
+static struct platform_driver fsi_ak4642 = {
+ .driver = {
+ .name = "fsi-ak4642-audio",
+ },
+ .probe = fsi_ak4642_probe,
+ .remove = fsi_ak4642_remove,
+ .id_table = fsi_id_table,
+};
+
+static int __init fsi_ak4642_init(void)
+{
+ return platform_driver_register(&fsi_ak4642);
+}
+
+static void __exit fsi_ak4642_exit(void)
+{
+ platform_driver_unregister(&fsi_ak4642);
}
module_init(fsi_ak4642_init);
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index a6adb6e43250..e8df9da92f71 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -18,7 +18,7 @@ static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_dai *dai = rtd->codec_dai;
return snd_soc_dai_set_fmt(dai,
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_CBM_CFM);
}
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 4c2404b1b862..2b06402801ef 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,20 +19,26 @@
#include <sound/soc.h>
#include <sound/sh_fsi.h>
-#define DO_FMT 0x0000
-#define DOFF_CTL 0x0004
-#define DOFF_ST 0x0008
-#define DI_FMT 0x000C
-#define DIFF_CTL 0x0010
-#define DIFF_ST 0x0014
-#define CKG1 0x0018
-#define CKG2 0x001C
-#define DIDT 0x0020
-#define DODT 0x0024
-#define MUTE_ST 0x0028
-#define OUT_SEL 0x0030
-#define REG_END OUT_SEL
-
+/* PortA/PortB register */
+#define REG_DO_FMT 0x0000
+#define REG_DOFF_CTL 0x0004
+#define REG_DOFF_ST 0x0008
+#define REG_DI_FMT 0x000C
+#define REG_DIFF_CTL 0x0010
+#define REG_DIFF_ST 0x0014
+#define REG_CKG1 0x0018
+#define REG_CKG2 0x001C
+#define REG_DIDT 0x0020
+#define REG_DODT 0x0024
+#define REG_MUTE_ST 0x0028
+#define REG_OUT_SEL 0x0030
+
+/* master register */
+#define MST_CLK_RST 0x0210
+#define MST_SOFT_RST 0x0214
+#define MST_FIFO_SZ 0x0218
+
+/* core register (depend on FSI version) */
#define A_MST_CTLR 0x0180
#define B_MST_CTLR 0x01A0
#define CPU_INT_ST 0x01F4
@@ -41,22 +47,23 @@
#define INT_ST 0x0200
#define IEMSK 0x0204
#define IMSK 0x0208
-#define MUTE 0x020C
-#define CLK_RST 0x0210
-#define SOFT_RST 0x0214
-#define FIFO_SZ 0x0218
-#define MREG_START A_MST_CTLR
-#define MREG_END FIFO_SZ
/* DO_FMT */
/* DI_FMT */
+#define CR_BWS_24 (0x0 << 20) /* FSI2 */
+#define CR_BWS_16 (0x1 << 20) /* FSI2 */
+#define CR_BWS_20 (0x2 << 20) /* FSI2 */
+
+#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */
+#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */
+
#define CR_MONO (0x0 << 4)
#define CR_MONO_D (0x1 << 4)
#define CR_PCM (0x2 << 4)
#define CR_I2S (0x3 << 4)
#define CR_TDM (0x4 << 4)
#define CR_TDM_D (0x5 << 4)
-#define CR_SPDIF 0x00100120
/* DOFF_CTL */
/* DIFF_CTL */
@@ -93,6 +100,10 @@
#define IR (1 << 4) /* Interrupt Reset */
#define FSISR (1 << 0) /* Software Reset */
+/* OUT_SEL (FSI2) */
+#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */
+ /* 1: Biphase and serial */
+
/* FIFO_SZ */
#define FIFO_SZ_MASK 0x7
@@ -123,6 +134,9 @@ struct fsi_stream {
int buff_len;
int period_len;
int period_num;
+
+ int uerr_num;
+ int oerr_num;
};
struct fsi_priv {
@@ -133,8 +147,6 @@ struct fsi_priv {
struct fsi_stream capture;
long rate;
-
- u32 mst_ctrl;
};
struct fsi_core {
@@ -143,6 +155,8 @@ struct fsi_core {
u32 int_st;
u32 iemsk;
u32 imsk;
+ u32 a_mclk;
+ u32 b_mclk;
};
struct fsi_master {
@@ -182,62 +196,22 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
__fsi_reg_write(reg, val);
}
-static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
+#define fsi_reg_write(p, r, d)\
+ __fsi_reg_write((u32)(p->base + REG_##r), d)
- __fsi_reg_write((u32)(fsi->base + reg), data);
-}
+#define fsi_reg_read(p, r)\
+ __fsi_reg_read((u32)(p->base + REG_##r))
-static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
+#define fsi_reg_mask_set(p, r, m, d)\
+ __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
- return __fsi_reg_read((u32)(fsi->base + reg));
-}
-
-static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
-{
- if (reg > REG_END) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
-}
-
-static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
-{
- unsigned long flags;
-
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&master->lock, flags);
- __fsi_reg_write((u32)(master->base + reg), data);
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-static u32 fsi_master_read(struct fsi_master *master, u32 reg)
+#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
+#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
+static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
{
u32 ret;
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return 0;
- }
-
spin_lock_irqsave(&master->lock, flags);
ret = __fsi_reg_read((u32)(master->base + reg));
spin_unlock_irqrestore(&master->lock, flags);
@@ -245,17 +219,13 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg)
return ret;
}
-static void fsi_master_mask_set(struct fsi_master *master,
+#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
+#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d)
+static void _fsi_master_mask_set(struct fsi_master *master,
u32 reg, u32 mask, u32 data)
{
unsigned long flags;
- if ((reg < MREG_START) ||
- (reg > MREG_END)) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
spin_lock_irqsave(&master->lock, flags);
__fsi_reg_mask_set((u32)(master->base + reg), mask, data);
spin_unlock_irqrestore(&master->lock, flags);
@@ -359,27 +329,41 @@ static void fsi_stream_push(struct fsi_priv *fsi,
io->buff_offset = 0;
io->period_len = period_len;
io->period_num = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
}
static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
{
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+
+
+ if (io->oerr_num > 0)
+ dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
+
+ if (io->uerr_num > 0)
+ dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
io->substream = NULL;
io->buff_len = 0;
io->buff_offset = 0;
io->period_len = 0;
io->period_num = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
}
static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
{
u32 status;
- u32 reg = is_play ? DOFF_ST : DIFF_ST;
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
int data_num;
- status = fsi_reg_read(fsi, reg);
+ status = is_play ?
+ fsi_reg_read(fsi, DOFF_ST) :
+ fsi_reg_read(fsi, DIFF_ST);
+
data_num = 0x1ff & (status >> 8);
data_num *= io->chan_num;
@@ -406,6 +390,27 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
return frames_to_bytes(runtime, 1) / io->chan_num;
}
+static void fsi_count_fifo_err(struct fsi_priv *fsi)
+{
+ u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
+ u32 istatus = fsi_reg_read(fsi, DIFF_ST);
+
+ if (ostatus & ERR_OVER)
+ fsi->playback.oerr_num++;
+
+ if (ostatus & ERR_UNDER)
+ fsi->playback.uerr_num++;
+
+ if (istatus & ERR_OVER)
+ fsi->capture.oerr_num++;
+
+ if (istatus & ERR_UNDER)
+ fsi->capture.uerr_num++;
+
+ fsi_reg_write(fsi, DOFF_ST, 0);
+ fsi_reg_write(fsi, DIFF_ST, 0);
+}
+
/*
* dma function
*/
@@ -473,8 +478,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
- fsi_master_mask_set(master, master->core->imsk, data, data);
- fsi_master_mask_set(master, master->core->iemsk, data, data);
+ fsi_core_mask_set(master, imsk, data, data);
+ fsi_core_mask_set(master, iemsk, data, data);
}
static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -482,18 +487,13 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
struct fsi_master *master = fsi_get_master(fsi);
- fsi_master_mask_set(master, master->core->imsk, data, 0);
- fsi_master_mask_set(master, master->core->iemsk, data, 0);
+ fsi_core_mask_set(master, imsk, data, 0);
+ fsi_core_mask_set(master, iemsk, data, 0);
}
static u32 fsi_irq_get_status(struct fsi_master *master)
{
- return fsi_master_read(master, master->core->int_st);
-}
-
-static void fsi_irq_clear_all_status(struct fsi_master *master)
-{
- fsi_master_write(master, master->core->int_st, 0);
+ return fsi_core_read(master, int_st);
}
static void fsi_irq_clear_status(struct fsi_priv *fsi)
@@ -505,7 +505,7 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
/* clear interrupt factor */
- fsi_master_mask_set(master, master->core->int_st, data, 0);
+ fsi_core_mask_set(master, int_st, data, 0);
}
/*
@@ -516,17 +516,19 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
{
struct fsi_master *master = fsi_get_master(fsi);
- u32 val = BP | SE;
+ u32 mask, val;
if (master->core->ver < 2) {
pr_err("fsi: register access err (%s)\n", __func__);
return;
}
- if (enable)
- fsi_master_mask_set(master, fsi->mst_ctrl, val, val);
- else
- fsi_master_mask_set(master, fsi->mst_ctrl, val, 0);
+ mask = BP | SE;
+ val = enable ? mask : 0;
+
+ fsi_is_port_a(fsi) ?
+ fsi_core_mask_set(master, a_mclk, mask, val) :
+ fsi_core_mask_set(master, b_mclk, mask, val);
}
/*
@@ -550,7 +552,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
{
struct fsi_master *master = fsi_get_master(fsi);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- u32 ctrl, shift, i;
+ u32 shift, i;
/* get on-chip RAM capacity */
shift = fsi_master_read(master, FIFO_SZ);
@@ -583,13 +585,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
dev_dbg(dai->dev, "%d channel %d store\n",
io->chan_num, io->fifo_max_num);
- ctrl = is_play ? DOFF_CTL : DIFF_CTL;
-
- /* set interrupt generation factor */
- fsi_reg_write(fsi, ctrl, IRQ_HALF);
-
- /* clear FIFO */
- fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
+ /*
+ * set interrupt generation factor
+ * clear FIFO
+ */
+ if (is_play) {
+ fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
+ } else {
+ fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
+ fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
+ }
}
static void fsi_soft_all_reset(struct fsi_master *master)
@@ -604,13 +610,12 @@ static void fsi_soft_all_reset(struct fsi_master *master)
mdelay(10);
}
-static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
+static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *substream = NULL;
int is_play = fsi_stream_is_play(stream);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- u32 status_reg = is_play ? DOFF_ST : DIFF_ST;
int data_residue_num;
int data_num;
int data_num_max;
@@ -698,35 +703,20 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
/* update buff_offset */
io->buff_offset += fsi_num2offset(data_num, ch_width);
- /* check fifo status */
- if (!startup) {
- struct snd_soc_dai *dai = fsi_get_dai(substream);
- u32 status = fsi_reg_read(fsi, status_reg);
-
- if (status & ERR_OVER)
- dev_err(dai->dev, "over run\n");
- if (status & ERR_UNDER)
- dev_err(dai->dev, "under run\n");
- }
- fsi_reg_write(fsi, status_reg, 0);
-
- /* re-enable irq */
- fsi_irq_enable(fsi, is_play);
-
if (over_period)
snd_pcm_period_elapsed(substream);
return 0;
}
-static int fsi_data_pop(struct fsi_priv *fsi, int startup)
+static int fsi_data_pop(struct fsi_priv *fsi)
{
- return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE);
+ return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
}
-static int fsi_data_push(struct fsi_priv *fsi, int startup)
+static int fsi_data_push(struct fsi_priv *fsi)
{
- return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK);
+ return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
}
static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -739,15 +729,19 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
fsi_master_mask_set(master, SOFT_RST, IR, IR);
if (int_st & AB_IO(1, AO_SHIFT))
- fsi_data_push(&master->fsia, 0);
+ fsi_data_push(&master->fsia);
if (int_st & AB_IO(1, BO_SHIFT))
- fsi_data_push(&master->fsib, 0);
+ fsi_data_push(&master->fsib);
if (int_st & AB_IO(1, AI_SHIFT))
- fsi_data_pop(&master->fsia, 0);
+ fsi_data_pop(&master->fsia);
if (int_st & AB_IO(1, BI_SHIFT))
- fsi_data_pop(&master->fsib, 0);
+ fsi_data_pop(&master->fsib);
+
+ fsi_count_fifo_err(&master->fsia);
+ fsi_count_fifo_err(&master->fsib);
- fsi_irq_clear_all_status(master);
+ fsi_irq_clear_status(&master->fsia);
+ fsi_irq_clear_status(&master->fsib);
return IRQ_HANDLED;
}
@@ -764,7 +758,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
struct fsi_stream *io;
u32 flags = fsi_get_info_flags(fsi);
u32 fmt;
- u32 reg;
u32 data;
int is_play = fsi_is_play(substream);
int is_master;
@@ -796,7 +789,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
/* do fmt, di fmt */
data = 0;
- reg = is_play ? DO_FMT : DI_FMT;
fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
switch (fmt) {
case SH_FSI_FMT_MONO:
@@ -830,16 +822,18 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
dev_err(dai->dev, "This FSI can not use SPDIF\n");
return -EINVAL;
}
- data = CR_SPDIF;
+ data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
io->chan_num = 2;
fsi_spdif_clk_ctrl(fsi, 1);
- fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
+ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
break;
default:
dev_err(dai->dev, "unknown format.\n");
return -EINVAL;
}
- fsi_reg_write(fsi, reg, data);
+ is_play ?
+ fsi_reg_write(fsi, DO_FMT, data) :
+ fsi_reg_write(fsi, DI_FMT, data);
/* irq clear */
fsi_irq_disable(fsi, is_play);
@@ -883,7 +877,8 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
fsi_stream_push(fsi, is_play, substream,
frames_to_bytes(runtime, runtime->buffer_size),
frames_to_bytes(runtime, runtime->period_size));
- ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
+ ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+ fsi_irq_enable(fsi, is_play);
break;
case SNDRV_PCM_TRIGGER_STOP:
fsi_irq_disable(fsi, is_play);
@@ -1174,12 +1169,10 @@ static int fsi_probe(struct platform_device *pdev)
/* FSI A setting */
master->fsia.base = master->base;
master->fsia.master = master;
- master->fsia.mst_ctrl = A_MST_CTLR;
/* FSI B setting */
master->fsib.base = master->base + 0x40;
master->fsib.master = master;
- master->fsib.mst_ctrl = B_MST_CTLR;
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
@@ -1266,6 +1259,8 @@ static struct fsi_core fsi2_core = {
.int_st = CPU_INT_ST,
.iemsk = CPU_IEMSK,
.imsk = CPU_IMSK,
+ .a_mclk = A_MST_CTLR,
+ .b_mclk = B_MST_CTLR,
};
static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index ac6c49ce6fdf..df13338cb3e2 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -20,7 +20,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include "../codecs/wm8978.h"
#include "siu.h"
@@ -140,11 +139,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, migor_dapm_widgets,
ARRAY_SIZE(migor_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
}
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index f8e0ab82ef59..917d3ceadc9d 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -12,7 +12,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <asm/io.h>
#define IPSEL 0xFE400034
@@ -23,7 +22,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform;
static int machine_init(struct snd_soc_pcm_runtime *rtd)
{
- snd_soc_dapm_sync(rtd->codec);
+ snd_soc_dapm_sync(&rtd->codec->dapm);
return 0;
}
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9f4dcb921ff0..83c3430ad797 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -75,7 +75,7 @@ struct siu_firmware {
#include <sound/core.h>
#include <sound/pcm.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index af53b64d8af2..4973c2939d79 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -28,7 +28,7 @@
#include <asm/siu.h>
#include <sound/control.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include "siu.h"
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index ed29c9e1ed4e..a423babcf145 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -29,7 +29,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dai.h>
+#include <sound/soc.h>
#include <asm/siu.h>
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d214f02cbb65..a9ebc078bea8 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -14,27 +14,34 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
+#include <linux/lzo.h>
+#include <linux/bitmap.h>
+#include <linux/rbtree.h>
static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[2];
int ret;
@@ -42,16 +49,17 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
data[1] = value & 0x00ff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 2);
if (ret == 2)
return 0;
@@ -77,7 +85,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
msg[1] = data[0];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -94,23 +102,27 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[2];
int ret;
@@ -118,16 +130,17 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
data[1] = value & 0x00ff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 2);
if (ret == 2)
return 0;
@@ -153,7 +166,7 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -170,24 +183,25 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u8 *cache = codec->reg_cache;
u8 data[2];
+ int ret;
reg &= 0xff;
data[0] = reg;
data[1] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
if (codec->hw_write(codec->control_data, data, 2) == 2)
return 0;
else
@@ -197,7 +211,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u8 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
reg &= 0xff;
if (reg >= codec->driver->reg_cache_size ||
@@ -205,10 +220,14 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
#if defined(CONFIG_SPI_MASTER)
@@ -227,7 +246,7 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -244,24 +263,25 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *reg_cache = codec->reg_cache;
u8 data[3];
+ int ret;
data[0] = reg;
data[1] = (value >> 8) & 0xff;
data[2] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- reg_cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
if (codec->hw_write(codec->control_data, data, 3) == 3)
return 0;
else
@@ -271,17 +291,22 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
- } else {
- return cache[reg];
}
+
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
#if defined(CONFIG_SPI_MASTER)
@@ -301,7 +326,7 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data,
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -420,7 +445,8 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u8 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
reg &= 0xff;
if (reg >= codec->driver->reg_cache_size ||
@@ -428,16 +454,19 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+ return val;
}
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u8 *cache = codec->reg_cache;
u8 data[3];
int ret;
@@ -447,16 +476,17 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
reg &= 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 3);
if (ret == 3)
return 0;
@@ -483,7 +513,7 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -534,23 +564,28 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- u16 *cache = codec->reg_cache;
+ int ret;
+ unsigned int val;
if (reg >= codec->driver->reg_cache_size ||
snd_soc_codec_volatile_register(codec, reg)) {
if (codec->cache_only)
return -1;
+ BUG_ON(!codec->hw_read);
return codec->hw_read(codec, reg);
}
- return cache[reg];
+ ret = snd_soc_cache_read(codec, reg, &val);
+ if (ret < 0)
+ return -1;
+
+ return val;
}
static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u16 *cache = codec->reg_cache;
u8 data[4];
int ret;
@@ -560,16 +595,17 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
data[3] = value & 0xff;
if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ reg < codec->driver->reg_cache_size) {
+ ret = snd_soc_cache_write(codec, reg, value);
+ if (ret < 0)
+ return -1;
+ }
if (codec->cache_only) {
codec->cache_sync = 1;
return 0;
}
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
ret = codec->hw_write(codec->control_data, data, 4);
if (ret == 4)
return 0;
@@ -597,7 +633,7 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data,
msg[3] = data[3];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
@@ -692,8 +728,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
return -EINVAL;
}
- codec->driver->write = io_types[i].write;
- codec->driver->read = io_types[i].read;
+ codec->write = io_types[i].write;
+ codec->read = io_types[i].read;
switch (control) {
case SND_SOC_CUSTOM:
@@ -724,3 +760,930 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+
+struct snd_soc_rbtree_node {
+ struct rb_node node;
+ unsigned int reg;
+ unsigned int value;
+ unsigned int defval;
+} __attribute__ ((packed));
+
+struct snd_soc_rbtree_ctx {
+ struct rb_root root;
+};
+
+static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
+ struct rb_root *root, unsigned int reg)
+{
+ struct rb_node *node;
+ struct snd_soc_rbtree_node *rbnode;
+
+ node = root->rb_node;
+ while (node) {
+ rbnode = container_of(node, struct snd_soc_rbtree_node, node);
+ if (rbnode->reg < reg)
+ node = node->rb_left;
+ else if (rbnode->reg > reg)
+ node = node->rb_right;
+ else
+ return rbnode;
+ }
+
+ return NULL;
+}
+
+static int snd_soc_rbtree_insert(struct rb_root *root,
+ struct snd_soc_rbtree_node *rbnode)
+{
+ struct rb_node **new, *parent;
+ struct snd_soc_rbtree_node *rbnode_tmp;
+
+ parent = NULL;
+ new = &root->rb_node;
+ while (*new) {
+ rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
+ node);
+ parent = *new;
+ if (rbnode_tmp->reg < rbnode->reg)
+ new = &((*new)->rb_left);
+ else if (rbnode_tmp->reg > rbnode->reg)
+ new = &((*new)->rb_right);
+ else
+ return 0;
+ }
+
+ /* insert the node into the rbtree */
+ rb_link_node(&rbnode->node, parent, new);
+ rb_insert_color(&rbnode->node, root);
+
+ return 1;
+}
+
+static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct rb_node *node;
+ struct snd_soc_rbtree_node *rbnode;
+ unsigned int val;
+ int ret;
+
+ rbtree_ctx = codec->reg_cache;
+ for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
+ rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
+ if (rbnode->value == rbnode->defval)
+ continue;
+ ret = snd_soc_cache_read(codec, rbnode->reg, &val);
+ if (ret)
+ return ret;
+ ret = snd_soc_write(codec, rbnode->reg, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ rbnode->reg, val);
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbnode;
+
+ rbtree_ctx = codec->reg_cache;
+ rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
+ if (rbnode) {
+ if (rbnode->value == value)
+ return 0;
+ rbnode->value = value;
+ } else {
+ /* bail out early, no need to create the rbnode yet */
+ if (!value)
+ return 0;
+ /*
+ * for uninitialized registers whose value is changed
+ * from the default zero, create an rbnode and insert
+ * it into the tree.
+ */
+ rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
+ if (!rbnode)
+ return -ENOMEM;
+ rbnode->reg = reg;
+ rbnode->value = value;
+ snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbnode;
+
+ rbtree_ctx = codec->reg_cache;
+ rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
+ if (rbnode) {
+ *value = rbnode->value;
+ } else {
+ /* uninitialized registers default to 0 */
+ *value = 0;
+ }
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
+{
+ struct rb_node *next;
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+ struct snd_soc_rbtree_node *rbtree_node;
+
+ /* if we've already been called then just return */
+ rbtree_ctx = codec->reg_cache;
+ if (!rbtree_ctx)
+ return 0;
+
+ /* free up the rbtree */
+ next = rb_first(&rbtree_ctx->root);
+ while (next) {
+ rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
+ next = rb_next(&rbtree_node->node);
+ rb_erase(&rbtree_node->node, &rbtree_ctx->root);
+ kfree(rbtree_node);
+ }
+
+ /* release the resources */
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+
+ return 0;
+}
+
+static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
+{
+ struct snd_soc_rbtree_ctx *rbtree_ctx;
+
+ codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
+ if (!codec->reg_cache)
+ return -ENOMEM;
+
+ rbtree_ctx = codec->reg_cache;
+ rbtree_ctx->root = RB_ROOT;
+
+ if (!codec->reg_def_copy)
+ return 0;
+
+/*
+ * populate the rbtree with the initialized registers. All other
+ * registers will be inserted into the tree when they are first written.
+ *
+ * The reasoning behind this, is that we need to step through and
+ * dereference the cache in u8/u16 increments without sacrificing
+ * portability. This could also be done using memcpy() but that would
+ * be slightly more cryptic.
+ */
+#define snd_soc_rbtree_populate(cache) \
+({ \
+ int ret, i; \
+ struct snd_soc_rbtree_node *rbtree_node; \
+ \
+ ret = 0; \
+ cache = codec->reg_def_copy; \
+ for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
+ if (!cache[i]) \
+ continue; \
+ rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
+ if (!rbtree_node) { \
+ ret = -ENOMEM; \
+ snd_soc_cache_exit(codec); \
+ break; \
+ } \
+ rbtree_node->reg = i; \
+ rbtree_node->value = cache[i]; \
+ rbtree_node->defval = cache[i]; \
+ snd_soc_rbtree_insert(&rbtree_ctx->root, \
+ rbtree_node); \
+ } \
+ ret; \
+})
+
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ const u8 *cache;
+
+ return snd_soc_rbtree_populate(cache);
+ }
+ case 2: {
+ const u16 *cache;
+
+ return snd_soc_rbtree_populate(cache);
+ }
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SND_SOC_CACHE_LZO
+struct snd_soc_lzo_ctx {
+ void *wmem;
+ void *dst;
+ const void *src;
+ size_t src_len;
+ size_t dst_len;
+ size_t decompressed_size;
+ unsigned long *sync_bmp;
+ int sync_bmp_nbits;
+};
+
+#define LZO_BLOCK_NUM 8
+static int snd_soc_lzo_block_count(void)
+{
+ return LZO_BLOCK_NUM;
+}
+
+static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ if (!lzo_ctx->wmem)
+ return -ENOMEM;
+ return 0;
+}
+
+static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ size_t compress_size;
+ int ret;
+
+ ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
+ lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
+ if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
+ return -EINVAL;
+ lzo_ctx->dst_len = compress_size;
+ return 0;
+}
+
+static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ size_t dst_len;
+ int ret;
+
+ dst_len = lzo_ctx->dst_len;
+ ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
+ lzo_ctx->dst, &dst_len);
+ if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
+ return -EINVAL;
+ return 0;
+}
+
+static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
+ struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ int ret;
+
+ lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
+ lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
+ if (!lzo_ctx->dst) {
+ lzo_ctx->dst_len = 0;
+ return -ENOMEM;
+ }
+
+ ret = snd_soc_lzo_compress(lzo_ctx);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
+ struct snd_soc_lzo_ctx *lzo_ctx)
+{
+ int ret;
+
+ lzo_ctx->dst_len = lzo_ctx->decompressed_size;
+ lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
+ if (!lzo_ctx->dst) {
+ lzo_ctx->dst_len = 0;
+ return -ENOMEM;
+ }
+
+ ret = snd_soc_lzo_decompress(lzo_ctx);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return (reg * codec_drv->reg_word_size) /
+ DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
+}
+
+static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
+ codec_drv->reg_word_size);
+}
+
+static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
+}
+
+static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ unsigned int val;
+ int i;
+ int ret;
+
+ lzo_blocks = codec->reg_cache;
+ for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ i, val);
+ }
+
+ return 0;
+}
+
+static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
+ int ret, blkindex, blkpos;
+ size_t blksize, tmp_dst_len;
+ void *tmp_dst;
+
+ /* index of the compressed lzo block */
+ blkindex = snd_soc_lzo_get_blkindex(codec, reg);
+ /* register index within the decompressed block */
+ blkpos = snd_soc_lzo_get_blkpos(codec, reg);
+ /* size of the compressed block */
+ blksize = snd_soc_lzo_get_blksize(codec);
+ lzo_blocks = codec->reg_cache;
+ lzo_block = lzo_blocks[blkindex];
+
+ /* save the pointer and length of the compressed block */
+ tmp_dst = lzo_block->dst;
+ tmp_dst_len = lzo_block->dst_len;
+
+ /* prepare the source to be the compressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* decompress the block */
+ ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
+ if (ret < 0) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+
+ /* write the new value to the cache */
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+ cache = lzo_block->dst;
+ if (cache[blkpos] == value) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+ cache[blkpos] = value;
+ }
+ break;
+ case 2: {
+ u16 *cache;
+ cache = lzo_block->dst;
+ if (cache[blkpos] == value) {
+ kfree(lzo_block->dst);
+ goto out;
+ }
+ cache[blkpos] = value;
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ /* prepare the source to be the decompressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* compress the block */
+ ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
+ if (ret < 0) {
+ kfree(lzo_block->dst);
+ kfree(lzo_block->src);
+ goto out;
+ }
+
+ /* set the bit so we know we have to sync this register */
+ set_bit(reg, lzo_block->sync_bmp);
+ kfree(tmp_dst);
+ kfree(lzo_block->src);
+ return 0;
+out:
+ lzo_block->dst = tmp_dst;
+ lzo_block->dst_len = tmp_dst_len;
+ return ret;
+}
+
+static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
+ int ret, blkindex, blkpos;
+ size_t blksize, tmp_dst_len;
+ void *tmp_dst;
+
+ *value = 0;
+ /* index of the compressed lzo block */
+ blkindex = snd_soc_lzo_get_blkindex(codec, reg);
+ /* register index within the decompressed block */
+ blkpos = snd_soc_lzo_get_blkpos(codec, reg);
+ /* size of the compressed block */
+ blksize = snd_soc_lzo_get_blksize(codec);
+ lzo_blocks = codec->reg_cache;
+ lzo_block = lzo_blocks[blkindex];
+
+ /* save the pointer and length of the compressed block */
+ tmp_dst = lzo_block->dst;
+ tmp_dst_len = lzo_block->dst_len;
+
+ /* prepare the source to be the compressed block */
+ lzo_block->src = lzo_block->dst;
+ lzo_block->src_len = lzo_block->dst_len;
+
+ /* decompress the block */
+ ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
+ if (ret >= 0) {
+ /* fetch the value from the cache */
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+ cache = lzo_block->dst;
+ *value = cache[blkpos];
+ }
+ break;
+ case 2: {
+ u16 *cache;
+ cache = lzo_block->dst;
+ *value = cache[blkpos];
+ }
+ break;
+ default:
+ BUG();
+ }
+ }
+
+ kfree(lzo_block->dst);
+ /* restore the pointer and length of the compressed block */
+ lzo_block->dst = tmp_dst;
+ lzo_block->dst_len = tmp_dst_len;
+ return 0;
+}
+
+static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ int i, blkcount;
+
+ lzo_blocks = codec->reg_cache;
+ if (!lzo_blocks)
+ return 0;
+
+ blkcount = snd_soc_lzo_block_count();
+ /*
+ * the pointer to the bitmap used for syncing the cache
+ * is shared amongst all lzo_blocks. Ensure it is freed
+ * only once.
+ */
+ if (lzo_blocks[0])
+ kfree(lzo_blocks[0]->sync_bmp);
+ for (i = 0; i < blkcount; ++i) {
+ if (lzo_blocks[i]) {
+ kfree(lzo_blocks[i]->wmem);
+ kfree(lzo_blocks[i]->dst);
+ }
+ /* each lzo_block is a pointer returned by kmalloc or NULL */
+ kfree(lzo_blocks[i]);
+ }
+ kfree(lzo_blocks);
+ codec->reg_cache = NULL;
+ return 0;
+}
+
+static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
+{
+ struct snd_soc_lzo_ctx **lzo_blocks;
+ size_t reg_size, bmp_size;
+ const struct snd_soc_codec_driver *codec_drv;
+ int ret, tofree, i, blksize, blkcount;
+ const char *p, *end;
+ unsigned long *sync_bmp;
+
+ ret = 0;
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+
+ /*
+ * If we have not been given a default register cache
+ * then allocate a dummy zero-ed out region, compress it
+ * and remember to free it afterwards.
+ */
+ tofree = 0;
+ if (!codec->reg_def_copy)
+ tofree = 1;
+
+ if (!codec->reg_def_copy) {
+ codec->reg_def_copy = kzalloc(reg_size,
+ GFP_KERNEL);
+ if (!codec->reg_def_copy)
+ return -ENOMEM;
+ }
+
+ blkcount = snd_soc_lzo_block_count();
+ codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
+ GFP_KERNEL);
+ if (!codec->reg_cache) {
+ ret = -ENOMEM;
+ goto err_tofree;
+ }
+ lzo_blocks = codec->reg_cache;
+
+ /*
+ * allocate a bitmap to be used when syncing the cache with
+ * the hardware. Each time a register is modified, the corresponding
+ * bit is set in the bitmap, so we know that we have to sync
+ * that register.
+ */
+ bmp_size = codec_drv->reg_cache_size;
+ sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
+ GFP_KERNEL);
+ if (!sync_bmp) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ bitmap_zero(sync_bmp, bmp_size);
+
+ /* allocate the lzo blocks and initialize them */
+ for (i = 0; i < blkcount; ++i) {
+ lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
+ GFP_KERNEL);
+ if (!lzo_blocks[i]) {
+ kfree(sync_bmp);
+ ret = -ENOMEM;
+ goto err;
+ }
+ lzo_blocks[i]->sync_bmp = sync_bmp;
+ lzo_blocks[i]->sync_bmp_nbits = reg_size;
+ /* alloc the working space for the compressed block */
+ ret = snd_soc_lzo_prepare(lzo_blocks[i]);
+ if (ret < 0)
+ goto err;
+ }
+
+ blksize = snd_soc_lzo_get_blksize(codec);
+ p = codec->reg_def_copy;
+ end = codec->reg_def_copy + reg_size;
+ /* compress the register map and fill the lzo blocks */
+ for (i = 0; i < blkcount; ++i, p += blksize) {
+ lzo_blocks[i]->src = p;
+ if (p + blksize > end)
+ lzo_blocks[i]->src_len = end - p;
+ else
+ lzo_blocks[i]->src_len = blksize;
+ ret = snd_soc_lzo_compress_cache_block(codec,
+ lzo_blocks[i]);
+ if (ret < 0)
+ goto err;
+ lzo_blocks[i]->decompressed_size =
+ lzo_blocks[i]->src_len;
+ }
+
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
+ return 0;
+err:
+ snd_soc_cache_exit(codec);
+err_tofree:
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
+ return ret;
+}
+#endif
+
+static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
+{
+ int i;
+ int ret;
+ const struct snd_soc_codec_driver *codec_drv;
+ unsigned int val;
+
+ codec_drv = codec->driver;
+ for (i = 0; i < codec_drv->reg_cache_size; ++i) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ if (codec_drv->reg_cache_default) {
+ switch (codec_drv->reg_word_size) {
+ case 1: {
+ const u8 *cache;
+
+ cache = codec_drv->reg_cache_default;
+ if (cache[i] == val)
+ continue;
+ }
+ break;
+ case 2: {
+ const u16 *cache;
+
+ cache = codec_drv->reg_cache_default;
+ if (cache[i] == val)
+ continue;
+ }
+ break;
+ default:
+ BUG();
+ }
+ }
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+ i, val);
+ }
+ return 0;
+}
+
+static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+
+ cache = codec->reg_cache;
+ cache[reg] = value;
+ }
+ break;
+ case 2: {
+ u16 *cache;
+
+ cache = codec->reg_cache;
+ cache[reg] = value;
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ switch (codec->driver->reg_word_size) {
+ case 1: {
+ u8 *cache;
+
+ cache = codec->reg_cache;
+ *value = cache[reg];
+ }
+ break;
+ case 2: {
+ u16 *cache;
+
+ cache = codec->reg_cache;
+ *value = cache[reg];
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
+{
+ if (!codec->reg_cache)
+ return 0;
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+ return 0;
+}
+
+static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
+{
+ const struct snd_soc_codec_driver *codec_drv;
+ size_t reg_size;
+
+ codec_drv = codec->driver;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+
+ /*
+ * for flat compression, we don't need to keep a copy of the
+ * original defaults register cache as it will definitely not
+ * be marked as __devinitconst
+ */
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+
+ if (codec_drv->reg_cache_default)
+ codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
+ else
+ codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
+ if (!codec->reg_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/* an array of all supported compression types */
+static const struct snd_soc_cache_ops cache_types[] = {
+ /* Flat *must* be the first entry for fallback */
+ {
+ .id = SND_SOC_FLAT_COMPRESSION,
+ .name = "flat",
+ .init = snd_soc_flat_cache_init,
+ .exit = snd_soc_flat_cache_exit,
+ .read = snd_soc_flat_cache_read,
+ .write = snd_soc_flat_cache_write,
+ .sync = snd_soc_flat_cache_sync
+ },
+#ifdef CONFIG_SND_SOC_CACHE_LZO
+ {
+ .id = SND_SOC_LZO_COMPRESSION,
+ .name = "LZO",
+ .init = snd_soc_lzo_cache_init,
+ .exit = snd_soc_lzo_cache_exit,
+ .read = snd_soc_lzo_cache_read,
+ .write = snd_soc_lzo_cache_write,
+ .sync = snd_soc_lzo_cache_sync
+ },
+#endif
+ {
+ .id = SND_SOC_RBTREE_COMPRESSION,
+ .name = "rbtree",
+ .init = snd_soc_rbtree_cache_init,
+ .exit = snd_soc_rbtree_cache_exit,
+ .read = snd_soc_rbtree_cache_read,
+ .write = snd_soc_rbtree_cache_write,
+ .sync = snd_soc_rbtree_cache_sync
+ }
+};
+
+int snd_soc_cache_init(struct snd_soc_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
+ if (cache_types[i].id == codec->compress_type)
+ break;
+
+ /* Fall back to flat compression */
+ if (i == ARRAY_SIZE(cache_types)) {
+ dev_warn(codec->dev, "Could not match compress type: %d\n",
+ codec->compress_type);
+ i = 0;
+ }
+
+ mutex_init(&codec->cache_rw_mutex);
+ codec->cache_ops = &cache_types[i];
+
+ if (codec->cache_ops->init) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ return codec->cache_ops->init(codec);
+ }
+ return -EINVAL;
+}
+
+/*
+ * NOTE: keep in mind that this function might be called
+ * multiple times.
+ */
+int snd_soc_cache_exit(struct snd_soc_codec *codec)
+{
+ if (codec->cache_ops && codec->cache_ops->exit) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ return codec->cache_ops->exit(codec);
+ }
+ return -EINVAL;
+}
+
+/**
+ * snd_soc_cache_read: Fetch the value of a given register from the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The value to be returned.
+ */
+int snd_soc_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
+{
+ int ret;
+
+ mutex_lock(&codec->cache_rw_mutex);
+
+ if (value && codec->cache_ops && codec->cache_ops->read) {
+ ret = codec->cache_ops->read(codec, reg, value);
+ mutex_unlock(&codec->cache_rw_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&codec->cache_rw_mutex);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_read);
+
+/**
+ * snd_soc_cache_write: Set the value of a given register in the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The new register value.
+ */
+int snd_soc_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ mutex_lock(&codec->cache_rw_mutex);
+
+ if (codec->cache_ops && codec->cache_ops->write) {
+ ret = codec->cache_ops->write(codec, reg, value);
+ mutex_unlock(&codec->cache_rw_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&codec->cache_rw_mutex);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_write);
+
+/**
+ * snd_soc_cache_sync: Sync the register cache with the hardware.
+ *
+ * @codec: CODEC to configure.
+ *
+ * Any registers that should not be synced should be marked as
+ * volatile. In general drivers can choose not to use the provided
+ * syncing functionality if they so require.
+ */
+int snd_soc_cache_sync(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ if (!codec->cache_sync) {
+ return 0;
+ }
+
+ if (codec->cache_ops && codec->cache_ops->sync) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
+ ret = codec->cache_ops->sync(codec);
+ if (!ret)
+ codec->cache_sync = 0;
+ return ret;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 441285ade024..a233607a73c6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -33,12 +33,15 @@
#include <linux/slab.h>
#include <sound/ac97_codec.h>
#include <sound/core.h>
+#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <sound/initval.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/asoc.h>
+
#define NAME_SIZE 32
static DEFINE_MUTEX(pcm_mutex);
@@ -67,25 +70,6 @@ static int pmdown_time = 5000;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
-/*
- * This function forces any delayed work to be queued and run.
- */
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
-
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
-
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
- }
- return ret;
-}
-
/* codec register dump */
static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
{
@@ -114,7 +98,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
* the register being volatile and the device being
* powered off.
*/
- ret = codec->driver->read(codec, i);
+ ret = snd_soc_read(codec, i);
if (ret >= 0)
count += snprintf(buf + count,
PAGE_SIZE - count,
@@ -225,7 +209,7 @@ static ssize_t codec_reg_write_file(struct file *file,
start++;
if (strict_strtoul(start, 16, &value))
return -EINVAL;
- codec->driver->write(codec, reg, value);
+ snd_soc_write(codec, reg, value);
return buf_size;
}
@@ -238,8 +222,10 @@ static const struct file_operations codec_reg_fops = {
static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
{
- codec->debugfs_codec_root = debugfs_create_dir(codec->name ,
- debugfs_root);
+ struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
+
+ codec->debugfs_codec_root = debugfs_create_dir(codec->name,
+ debugfs_card_root);
if (!codec->debugfs_codec_root) {
printk(KERN_WARNING
"ASoC: Failed to create codec debugfs directory\n");
@@ -253,20 +239,13 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
printk(KERN_WARNING
"ASoC: Failed to create codec register debugfs file\n");
- codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
- codec->debugfs_codec_root,
- &codec->pop_time);
- if (!codec->debugfs_pop_time)
- printk(KERN_WARNING
- "Failed to create pop time debugfs file\n");
-
- codec->debugfs_dapm = debugfs_create_dir("dapm",
+ codec->dapm.debugfs_dapm = debugfs_create_dir("dapm",
codec->debugfs_codec_root);
- if (!codec->debugfs_dapm)
+ if (!codec->dapm.debugfs_dapm)
printk(KERN_WARNING
"Failed to create DAPM debugfs directory\n");
- snd_soc_dapm_debugfs_init(codec);
+ snd_soc_dapm_debugfs_init(&codec->dapm);
}
static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
@@ -374,6 +353,29 @@ static const struct file_operations platform_list_fops = {
.llseek = default_llseek,/* read accesses f_pos */
};
+static void soc_init_card_debugfs(struct snd_soc_card *card)
+{
+ card->debugfs_card_root = debugfs_create_dir(card->name,
+ debugfs_root);
+ if (!card->debugfs_card_root) {
+ dev_warn(card->dev,
+ "ASoC: Failed to create codec debugfs directory\n");
+ return;
+ }
+
+ card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
+ card->debugfs_card_root,
+ &card->pop_time);
+ if (!card->debugfs_pop_time)
+ dev_warn(card->dev,
+ "Failed to create pop time debugfs file\n");
+}
+
+static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
+{
+ debugfs_remove_recursive(card->debugfs_card_root);
+}
+
#else
static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
@@ -383,6 +385,14 @@ static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
{
}
+
+static inline void soc_init_card_debugfs(struct snd_soc_card *card)
+{
+}
+
+static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
+{
+}
#endif
#ifdef CONFIG_SND_SOC_AC97_BUS
@@ -497,7 +507,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
- /* Check that the codec and cpu DAI's are compatible */
+ /* Check that the codec and cpu DAIs are compatible */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
runtime->hw.rate_min =
max(codec_dai_drv->playback.rate_min,
@@ -846,7 +856,7 @@ codec_err:
}
/*
- * Free's resources allocated by hw_params, can be called multiple times
+ * Frees resources allocated by hw_params, can be called multiple times
*/
static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
{
@@ -870,7 +880,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
if (platform->driver->ops->hw_free)
platform->driver->ops->hw_free(substream);
- /* now free hw params for the DAI's */
+ /* now free hw params for the DAIs */
if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
@@ -958,6 +968,7 @@ static int soc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
int i;
/* If the initialization of this soc device failed, there is no codec
@@ -976,7 +987,7 @@ static int soc_suspend(struct device *dev)
/* we're going to block userspace touching us until resume completes */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
- /* mute any active DAC's */
+ /* mute any active DACs */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_dai *dai = card->rtd[i].codec_dai;
struct snd_soc_dai_driver *drv = dai->driver;
@@ -1016,8 +1027,8 @@ static int soc_suspend(struct device *dev)
/* close any waiting streams and save state */
for (i = 0; i < card->num_rtd; i++) {
- run_delayed_work(&card->rtd[i].delayed_work);
- card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level;
+ flush_delayed_work_sync(&card->rtd[i].delayed_work);
+ card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
}
for (i = 0; i < card->num_rtd; i++) {
@@ -1036,12 +1047,11 @@ static int soc_suspend(struct device *dev)
}
/* suspend all CODECs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_codec *codec = card->rtd[i].codec;
+ list_for_each_entry(codec, &card->codec_dev_list, card_list) {
/* If there are paths active then the CODEC will be held with
* bias _ON and should not be suspended. */
if (!codec->suspended && codec->driver->suspend) {
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
codec->driver->suspend(codec, PMSG_SUSPEND);
@@ -1078,6 +1088,7 @@ static void soc_resume_deferred(struct work_struct *work)
struct snd_soc_card *card =
container_of(work, struct snd_soc_card, deferred_resume_work);
struct platform_device *pdev = to_platform_device(card->dev);
+ struct snd_soc_codec *codec;
int i;
/* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
@@ -1103,14 +1114,13 @@ static void soc_resume_deferred(struct work_struct *work)
cpu_dai->driver->resume(cpu_dai);
}
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_codec *codec = card->rtd[i].codec;
+ list_for_each_entry(codec, &card->codec_dev_list, card_list) {
/* If the CODEC was idle over suspend then it will have been
* left with bias OFF or STANDBY and suspended so we must now
* resume. Otherwise the suspend was suppressed.
*/
if (codec->driver->resume && codec->suspended) {
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
codec->driver->resume(codec);
@@ -1299,6 +1309,27 @@ out:
return 1;
}
+static void soc_remove_codec(struct snd_soc_codec *codec)
+{
+ int err;
+
+ if (codec->driver->remove) {
+ err = codec->driver->remove(codec);
+ if (err < 0)
+ dev_err(codec->dev,
+ "asoc: failed to remove %s: %d\n",
+ codec->name, err);
+ }
+
+ /* Make sure all DAPM widgets are freed */
+ snd_soc_dapm_free(&codec->dapm);
+
+ soc_cleanup_codec_debugfs(codec);
+ codec->probed = 0;
+ list_del(&codec->card_list);
+ module_put(codec->dev->driver->owner);
+}
+
static void soc_remove_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1310,6 +1341,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
/* unregister the rtd device */
if (rtd->dev_registered) {
device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
device_unregister(&rtd->dev);
rtd->dev_registered = 0;
}
@@ -1338,22 +1370,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
}
/* remove the CODEC */
- if (codec && codec->probed) {
- if (codec->driver->remove) {
- err = codec->driver->remove(codec);
- if (err < 0)
- printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(codec);
-
- soc_cleanup_codec_debugfs(codec);
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- codec->probed = 0;
- list_del(&codec->card_list);
- module_put(codec->dev->driver->owner);
- }
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
/* remove the cpu_dai */
if (cpu_dai && cpu_dai->probed) {
@@ -1368,8 +1386,123 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
}
}
+static void soc_set_name_prefix(struct snd_soc_card *card,
+ struct snd_soc_codec *codec)
+{
+ int i;
+
+ if (card->codec_conf == NULL)
+ return;
+
+ for (i = 0; i < card->num_configs; i++) {
+ struct snd_soc_codec_conf *map = &card->codec_conf[i];
+ if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
+ codec->name_prefix = map->name_prefix;
+ break;
+ }
+ }
+}
+
+static int soc_probe_codec(struct snd_soc_card *card,
+ struct snd_soc_codec *codec)
+{
+ int ret = 0;
+
+ codec->card = card;
+ codec->dapm.card = card;
+ soc_set_name_prefix(card, codec);
+
+ if (codec->driver->probe) {
+ ret = codec->driver->probe(codec);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "asoc: failed to probe CODEC %s: %d\n",
+ codec->name, ret);
+ return ret;
+ }
+ }
+
+ soc_init_codec_debugfs(codec);
+
+ /* mark codec as probed and add to card codec list */
+ codec->probed = 1;
+ list_add(&codec->card_list, &card->codec_dev_list);
+ list_add(&codec->dapm.list, &card->dapm_list);
+
+ return ret;
+}
+
static void rtd_release(struct device *dev) {}
+static int soc_post_component_init(struct snd_soc_card *card,
+ struct snd_soc_codec *codec,
+ int num, int dailess)
+{
+ struct snd_soc_dai_link *dai_link = NULL;
+ struct snd_soc_aux_dev *aux_dev = NULL;
+ struct snd_soc_pcm_runtime *rtd;
+ const char *temp, *name;
+ int ret = 0;
+
+ if (!dailess) {
+ dai_link = &card->dai_link[num];
+ rtd = &card->rtd[num];
+ name = dai_link->name;
+ } else {
+ aux_dev = &card->aux_dev[num];
+ rtd = &card->rtd_aux[num];
+ name = aux_dev->name;
+ }
+
+ /* machine controls, routes and widgets are not prefixed */
+ temp = codec->name_prefix;
+ codec->name_prefix = NULL;
+
+ /* do machine specific initialization */
+ if (!dailess && dai_link->init)
+ ret = dai_link->init(rtd);
+ else if (dailess && aux_dev->init)
+ ret = aux_dev->init(&codec->dapm);
+ if (ret < 0) {
+ dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
+ return ret;
+ }
+ codec->name_prefix = temp;
+
+ /* Make sure all DAPM widgets are instantiated */
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ snd_soc_dapm_sync(&codec->dapm);
+
+ /* register the rtd device */
+ rtd->codec = codec;
+ rtd->card = card;
+ rtd->dev.parent = card->dev;
+ rtd->dev.release = rtd_release;
+ rtd->dev.init_name = name;
+ ret = device_register(&rtd->dev);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "asoc: failed to register runtime device: %d\n", ret);
+ return ret;
+ }
+ rtd->dev_registered = 1;
+
+ /* add DAPM sysfs entries for this codec */
+ ret = snd_soc_dapm_sys_add(&rtd->dev);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec dapm sysfs entries: %d\n",
+ ret);
+
+ /* add codec sysfs entries */
+ ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec sysfs files: %d\n", ret);
+
+ return 0;
+}
+
static int soc_probe_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_dai_link *dai_link = &card->dai_link[num];
@@ -1383,10 +1516,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* config components */
codec_dai->codec = codec;
- codec->card = card;
cpu_dai->platform = platform;
- rtd->card = card;
- rtd->dev.parent = card->dev;
codec_dai->card = card;
cpu_dai->card = card;
@@ -1410,20 +1540,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* probe the CODEC */
if (!codec->probed) {
- if (codec->driver->probe) {
- ret = codec->driver->probe(codec);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
- codec->name);
- return ret;
- }
- }
-
- soc_init_codec_debugfs(codec);
-
- /* mark codec as probed and add to card codec list */
- codec->probed = 1;
- list_add(&codec->card_list, &card->codec_dev_list);
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
}
/* probe the platform */
@@ -1460,43 +1579,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* DAPM dai link stream work */
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
- /* now that all clients have probed, initialise the DAI link */
- if (dai_link->init) {
- ret = dai_link->init(rtd);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
- return ret;
- }
- }
-
- /* Make sure all DAPM widgets are instantiated */
- snd_soc_dapm_new_widgets(codec);
- snd_soc_dapm_sync(codec);
-
- /* register the rtd device */
- rtd->dev.release = rtd_release;
- rtd->dev.init_name = dai_link->name;
- ret = device_register(&rtd->dev);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
+ ret = soc_post_component_init(card, codec, num, 0);
+ if (ret)
return ret;
- }
- rtd->dev_registered = 1;
ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
if (ret < 0)
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
- /* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(&rtd->dev);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
-
- /* add codec sysfs entries */
- ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
-
/* create the pcm */
ret = soc_new_pcm(rtd, num);
if (ret < 0) {
@@ -1551,9 +1641,85 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
}
#endif
+static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
+{
+ struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
+ struct snd_soc_codec *codec;
+ int ret = -ENODEV;
+
+ /* find CODEC from registered CODECs*/
+ list_for_each_entry(codec, &codec_list, list) {
+ if (!strcmp(codec->name, aux_dev->codec_name)) {
+ if (codec->probed) {
+ dev_err(codec->dev,
+ "asoc: codec already probed");
+ ret = -EBUSY;
+ goto out;
+ }
+ goto found;
+ }
+ }
+ /* codec not found */
+ dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
+ goto out;
+
+found:
+ if (!try_module_get(codec->dev->driver->owner))
+ return -ENODEV;
+
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
+
+ ret = soc_post_component_init(card, codec, num, 1);
+
+out:
+ return ret;
+}
+
+static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
+{
+ struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
+ struct snd_soc_codec *codec = rtd->codec;
+
+ /* unregister the rtd device */
+ if (rtd->dev_registered) {
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
+ device_unregister(&rtd->dev);
+ rtd->dev_registered = 0;
+ }
+
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
+}
+
+static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
+ enum snd_soc_compress_type compress_type)
+{
+ int ret;
+
+ if (codec->cache_init)
+ return 0;
+
+ /* override the compress_type if necessary */
+ if (compress_type && codec->compress_type != compress_type)
+ codec->compress_type = compress_type;
+ ret = snd_soc_cache_init(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache compression type: %d\n",
+ ret);
+ return ret;
+ }
+ codec->cache_init = 1;
+ return 0;
+}
+
static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct platform_device *pdev = to_platform_device(card->dev);
+ struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
int ret, i;
mutex_lock(&card->mutex);
@@ -1573,6 +1739,39 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
return;
}
+ /* initialize the register cache for each available codec */
+ list_for_each_entry(codec, &codec_list, list) {
+ if (codec->cache_init)
+ continue;
+ /* check to see if we need to override the compress_type */
+ for (i = 0; i < card->num_configs; ++i) {
+ codec_conf = &card->codec_conf[i];
+ if (!strcmp(codec->name, codec_conf->dev_name)) {
+ compress_type = codec_conf->compress_type;
+ if (compress_type && compress_type
+ != codec->compress_type)
+ break;
+ }
+ }
+ if (i == card->num_configs) {
+ /* no need to override the compress_type so
+ * go ahead and do the standard thing */
+ ret = snd_soc_init_codec_cache(codec, 0);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ continue;
+ }
+ /* override the compress_type with the one supplied in
+ * the machine driver */
+ ret = snd_soc_init_codec_cache(codec, compress_type);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ }
+
/* card bind complete so register a sound card */
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
card->owner, 0, &card->snd_card);
@@ -1605,6 +1804,15 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
}
}
+ for (i = 0; i < card->num_aux_devs; i++) {
+ ret = soc_probe_aux_dev(card, i);
+ if (ret < 0) {
+ pr_err("asoc: failed to add auxiliary devices %s: %d\n",
+ card->name, ret);
+ goto probe_aux_dev_err;
+ }
+ }
+
snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
"%s", card->name);
snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1613,24 +1821,30 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
ret = snd_card_register(card->snd_card);
if (ret < 0) {
printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
- goto probe_dai_err;
+ goto probe_aux_dev_err;
}
#ifdef CONFIG_SND_SOC_AC97_BUS
/* register any AC97 codecs */
for (i = 0; i < card->num_rtd; i++) {
- ret = soc_register_ac97_dai_link(&card->rtd[i]);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
- goto probe_dai_err;
- }
+ ret = soc_register_ac97_dai_link(&card->rtd[i]);
+ if (ret < 0) {
+ printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+ while (--i >= 0)
+ soc_unregister_ac97_dai_link(card->rtd[i].codec);
+ goto probe_aux_dev_err;
}
+ }
#endif
card->instantiated = 1;
mutex_unlock(&card->mutex);
return;
+probe_aux_dev_err:
+ for (i = 0; i < card->num_aux_devs; i++)
+ soc_remove_aux_dev(card, i);
+
probe_dai_err:
for (i = 0; i < card->num_links; i++)
soc_remove_dai_link(card, i);
@@ -1666,6 +1880,11 @@ static int soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&card->dai_dev_list);
INIT_LIST_HEAD(&card->codec_dev_list);
INIT_LIST_HEAD(&card->platform_dev_list);
+ INIT_LIST_HEAD(&card->widgets);
+ INIT_LIST_HEAD(&card->paths);
+ INIT_LIST_HEAD(&card->dapm_list);
+
+ soc_init_card_debugfs(card);
ret = snd_soc_register_card(card);
if (ret != 0) {
@@ -1687,13 +1906,19 @@ static int soc_remove(struct platform_device *pdev)
/* make sure any delayed work runs */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- run_delayed_work(&rtd->delayed_work);
+ flush_delayed_work_sync(&rtd->delayed_work);
}
+ /* remove auxiliary devices */
+ for (i = 0; i < card->num_aux_devs; i++)
+ soc_remove_aux_dev(card, i);
+
/* remove and free each DAI */
for (i = 0; i < card->num_rtd; i++)
soc_remove_dai_link(card, i);
+ soc_cleanup_card_debugfs(card);
+
/* remove the card */
if (card->remove)
card->remove(pdev);
@@ -1718,7 +1943,7 @@ static int soc_poweroff(struct device *dev)
* now, we're shutting down so no imminent restart. */
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- run_delayed_work(&rtd->delayed_work);
+ flush_delayed_work_sync(&rtd->delayed_work);
}
snd_soc_dapm_shutdown(card);
@@ -1877,6 +2102,27 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ unsigned int ret;
+
+ ret = codec->read(codec, reg);
+ dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
+ trace_snd_soc_reg_read(codec, reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_read);
+
+unsigned int snd_soc_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int val)
+{
+ dev_dbg(codec->dev, "write %x = %x\n", reg, val);
+ trace_snd_soc_reg_write(codec, reg, val);
+ return codec->write(codec, reg, val);
+}
+EXPORT_SYMBOL_GPL(snd_soc_write);
+
/**
* snd_soc_update_bits - update codec register bits
* @codec: audio codec
@@ -2017,14 +2263,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
const struct snd_kcontrol_new *controls, int num_controls)
{
struct snd_card *card = codec->card->snd_card;
+ char prefixed_name[44], *name;
int err, i;
for (i = 0; i < num_controls; i++) {
const struct snd_kcontrol_new *control = &controls[i];
- err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL));
+ if (codec->name_prefix) {
+ snprintf(prefixed_name, sizeof(prefixed_name), "%s %s",
+ codec->name_prefix, control->name);
+ name = prefixed_name;
+ } else {
+ name = control->name;
+ }
+ err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
if (err < 0) {
dev_err(codec->dev, "%s: Failed to add %s: %d\n",
- codec->name, control->name, err);
+ codec->name, name, err);
return err;
}
}
@@ -2861,10 +3115,12 @@ static int snd_soc_register_card(struct snd_soc_card *card)
if (!card->name || !card->dev)
return -EINVAL;
- card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * card->num_links,
- GFP_KERNEL);
+ card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
+ (card->num_links + card->num_aux_devs),
+ GFP_KERNEL);
if (card->rtd == NULL)
return -ENOMEM;
+ card->rtd_aux = &card->rtd[card->num_links];
for (i = 0; i < card->num_links; i++)
card->rtd[i].dai_link = &card->dai_link[i];
@@ -2906,7 +3162,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
* Simplify DAI link configuration by removing ".-1" from device names
* and sanitizing names.
*/
-static inline char *fmt_single_name(struct device *dev, int *id)
+static char *fmt_single_name(struct device *dev, int *id)
{
char *found, name[NAME_SIZE];
int id1, id2;
@@ -2914,7 +3170,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
if (dev_name(dev) == NULL)
return NULL;
- strncpy(name, dev_name(dev), NAME_SIZE);
+ strlcpy(name, dev_name(dev), NAME_SIZE);
/* are we a "%s.%d" name (platform and SPI components) */
found = strstr(name, dev->driver->name);
@@ -2937,7 +3193,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
/* sanitize component name for DAI link creation */
snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name);
- strncpy(name, tmp, NAME_SIZE);
+ strlcpy(name, tmp, NAME_SIZE);
} else
*id = 0;
}
@@ -3072,7 +3328,9 @@ int snd_soc_register_dais(struct device *dev,
pr_debug("Registered DAI '%s'\n", dai->name);
}
+ mutex_lock(&client_mutex);
snd_soc_instantiate_cards();
+ mutex_unlock(&client_mutex);
return 0;
err:
@@ -3200,9 +3458,11 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
* @codec: codec to register
*/
int snd_soc_register_codec(struct device *dev,
- struct snd_soc_codec_driver *codec_drv,
- struct snd_soc_dai_driver *dai_drv, int num_dai)
+ const struct snd_soc_codec_driver *codec_drv,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai)
{
+ size_t reg_size;
struct snd_soc_codec *codec;
int ret, i;
@@ -3219,30 +3479,37 @@ int snd_soc_register_codec(struct device *dev,
return -ENOMEM;
}
- /* allocate CODEC register cache */
- if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
-
- if (codec_drv->reg_cache_default)
- codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
- codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL);
- else
- codec->reg_cache = kzalloc(codec_drv->reg_cache_size *
- codec_drv->reg_word_size, GFP_KERNEL);
-
- if (codec->reg_cache == NULL) {
- kfree(codec->name);
- kfree(codec);
- return -ENOMEM;
- }
- }
+ if (codec_drv->compress_type)
+ codec->compress_type = codec_drv->compress_type;
+ else
+ codec->compress_type = SND_SOC_FLAT_COMPRESSION;
+ codec->write = codec_drv->write;
+ codec->read = codec_drv->read;
+ codec->dapm.bias_level = SND_SOC_BIAS_OFF;
+ codec->dapm.dev = dev;
+ codec->dapm.codec = codec;
codec->dev = dev;
codec->driver = codec_drv;
- codec->bias_level = SND_SOC_BIAS_OFF;
codec->num_dai = num_dai;
mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+
+ /* allocate CODEC register cache */
+ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ /* it is necessary to make a copy of the default register cache
+ * because in the case of using a compression type that requires
+ * the default register cache to be marked as __devinitconst the
+ * kernel might have freed the array by the time we initialize
+ * the cache.
+ */
+ codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
+ if (!codec->reg_def_copy) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
for (i = 0; i < num_dai; i++) {
fixup_codec_formats(&dai_drv[i].playback);
@@ -3253,7 +3520,7 @@ int snd_soc_register_codec(struct device *dev,
if (num_dai) {
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0)
- goto error;
+ goto fail;
}
mutex_lock(&client_mutex);
@@ -3264,9 +3531,9 @@ int snd_soc_register_codec(struct device *dev,
pr_debug("Registered codec '%s'\n", codec->name);
return 0;
-error:
- if (codec->reg_cache)
- kfree(codec->reg_cache);
+fail:
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
kfree(codec->name);
kfree(codec);
return ret;
@@ -3300,8 +3567,8 @@ found:
pr_debug("Unregistered codec '%s'\n", codec->name);
- if (codec->reg_cache)
- kfree(codec->reg_cache);
+ snd_soc_cache_exit(codec);
+ kfree(codec->reg_def_copy);
kfree(codec->name);
kfree(codec);
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 75ed6491222d..499730ab5638 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -42,9 +42,11 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include <sound/initval.h>
+#include <trace/events/asoc.h>
+
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
[snd_soc_dapm_pre] = 0,
@@ -54,12 +56,14 @@ static int dapm_up_seq[] = {
[snd_soc_dapm_aif_out] = 3,
[snd_soc_dapm_mic] = 4,
[snd_soc_dapm_mux] = 5,
+ [snd_soc_dapm_virt_mux] = 5,
[snd_soc_dapm_value_mux] = 5,
[snd_soc_dapm_dac] = 6,
[snd_soc_dapm_mixer] = 7,
[snd_soc_dapm_mixer_named_ctl] = 7,
[snd_soc_dapm_pga] = 8,
[snd_soc_dapm_adc] = 9,
+ [snd_soc_dapm_out_drv] = 10,
[snd_soc_dapm_hp] = 10,
[snd_soc_dapm_spk] = 10,
[snd_soc_dapm_post] = 11,
@@ -70,6 +74,7 @@ static int dapm_down_seq[] = {
[snd_soc_dapm_adc] = 1,
[snd_soc_dapm_hp] = 2,
[snd_soc_dapm_spk] = 2,
+ [snd_soc_dapm_out_drv] = 2,
[snd_soc_dapm_pga] = 4,
[snd_soc_dapm_mixer_named_ctl] = 5,
[snd_soc_dapm_mixer] = 5,
@@ -77,6 +82,7 @@ static int dapm_down_seq[] = {
[snd_soc_dapm_mic] = 7,
[snd_soc_dapm_micbias] = 8,
[snd_soc_dapm_mux] = 9,
+ [snd_soc_dapm_virt_mux] = 9,
[snd_soc_dapm_value_mux] = 9,
[snd_soc_dapm_aif_in] = 10,
[snd_soc_dapm_aif_out] = 10,
@@ -90,17 +96,24 @@ static void pop_wait(u32 pop_time)
schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
}
-static void pop_dbg(u32 pop_time, const char *fmt, ...)
+static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
{
va_list args;
+ char *buf;
- va_start(args, fmt);
+ if (!pop_time)
+ return;
- if (pop_time) {
- vprintk(fmt, args);
- }
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (buf == NULL)
+ return;
+ va_start(args, fmt);
+ vsnprintf(buf, PAGE_SIZE, fmt, args);
+ dev_info(dev, "%s", buf);
va_end(args);
+
+ kfree(buf);
}
/* create a new dapm widget */
@@ -120,36 +133,45 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
* Returns 0 for success else error.
*/
static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_codec *codec, enum snd_soc_bias_level level)
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
{
int ret = 0;
switch (level) {
case SND_SOC_BIAS_ON:
- dev_dbg(codec->dev, "Setting full bias\n");
+ dev_dbg(dapm->dev, "Setting full bias\n");
break;
case SND_SOC_BIAS_PREPARE:
- dev_dbg(codec->dev, "Setting bias prepare\n");
+ dev_dbg(dapm->dev, "Setting bias prepare\n");
break;
case SND_SOC_BIAS_STANDBY:
- dev_dbg(codec->dev, "Setting standby bias\n");
+ dev_dbg(dapm->dev, "Setting standby bias\n");
break;
case SND_SOC_BIAS_OFF:
- dev_dbg(codec->dev, "Setting bias off\n");
+ dev_dbg(dapm->dev, "Setting bias off\n");
break;
default:
- dev_err(codec->dev, "Setting invalid bias %d\n", level);
+ dev_err(dapm->dev, "Setting invalid bias %d\n", level);
return -EINVAL;
}
+ trace_snd_soc_bias_level_start(card, level);
+
if (card && card->set_bias_level)
ret = card->set_bias_level(card, level);
if (ret == 0) {
- if (codec->driver->set_bias_level)
- ret = codec->driver->set_bias_level(codec, level);
+ if (dapm->codec && dapm->codec->driver->set_bias_level)
+ ret = dapm->codec->driver->set_bias_level(dapm->codec, level);
else
- codec->bias_level = level;
+ dapm->bias_level = level;
}
+ if (ret == 0) {
+ if (card && card->set_bias_level_post)
+ ret = card->set_bias_level_post(card, level);
+ }
+
+ trace_snd_soc_bias_level_done(card, level);
return ret;
}
@@ -196,6 +218,20 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
}
}
break;
+ case snd_soc_dapm_virt_mux: {
+ struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
+
+ p->connect = 0;
+ /* since a virtual mux has no backing registers to
+ * decide which path to connect, it will try to match
+ * with the first enumeration. This is to ensure
+ * that the default mux choice (the first) will be
+ * correctly powered up during initialization.
+ */
+ if (!strcmp(p->name, e->texts[0]))
+ p->connect = 1;
+ }
+ break;
case snd_soc_dapm_value_mux: {
struct soc_enum *e = (struct soc_enum *)
w->kcontrols[i].private_value;
@@ -217,6 +253,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
break;
/* does not effect routing - always connected */
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_output:
case snd_soc_dapm_adc:
case snd_soc_dapm_input:
@@ -241,7 +278,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
}
/* connect mux widget to its interconnecting audio paths */
-static int dapm_connect_mux(struct snd_soc_codec *codec,
+static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
struct snd_soc_dapm_path *path, const char *control_name,
const struct snd_kcontrol_new *kcontrol)
@@ -251,7 +288,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
for (i = 0; i < e->max; i++) {
if (!(strcmp(control_name, e->texts[i]))) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &dest->sources);
list_add(&path->list_source, &src->sinks);
path->name = (char*)e->texts[i];
@@ -264,7 +301,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
}
/* connect mixer widget to its interconnecting audio paths */
-static int dapm_connect_mixer(struct snd_soc_codec *codec,
+static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
struct snd_soc_dapm_path *path, const char *control_name)
{
@@ -273,7 +310,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec,
/* search for mixer kcontrol */
for (i = 0; i < dest->num_kcontrols; i++) {
if (!strcmp(control_name, dest->kcontrols[i].name)) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &dest->sources);
list_add(&path->list_source, &src->sinks);
path->name = dest->kcontrols[i].name;
@@ -290,6 +327,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
int change, power;
unsigned int old, new;
struct snd_soc_codec *codec = widget->codec;
+ struct snd_soc_dapm_context *dapm = widget->dapm;
+ struct snd_soc_card *card = dapm->card;
/* check for valid widgets */
if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
@@ -309,24 +348,26 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
change = old != new;
if (change) {
- pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
+ pop_dbg(dapm->dev, card->pop_time,
+ "pop test %s : %s in %d ms\n",
widget->name, widget->power ? "on" : "off",
- codec->pop_time);
- pop_wait(codec->pop_time);
+ card->pop_time);
+ pop_wait(card->pop_time);
snd_soc_write(codec, widget->reg, new);
}
- pr_debug("reg %x old %x new %x change %d\n", widget->reg,
- old, new, change);
+ dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg,
+ old, new, change);
return change;
}
/* create new dapm mixer control */
-static int dapm_new_mixer(struct snd_soc_codec *codec,
+static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
int i, ret = 0;
size_t name_len;
struct snd_soc_dapm_path *path;
+ struct snd_card *card = dapm->codec->card->snd_card;
/* add kcontrol */
for (i = 0; i < w->num_kcontrols; i++) {
@@ -368,11 +409,11 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
path->long_name);
- ret = snd_ctl_add(codec->card->snd_card, path->kcontrol);
+ ret = snd_ctl_add(card, path->kcontrol);
if (ret < 0) {
- printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
- path->long_name,
- ret);
+ dev_err(dapm->dev,
+ "asoc: failed to add dapm kcontrol %s: %d\n",
+ path->long_name, ret);
kfree(path->long_name);
path->long_name = NULL;
return ret;
@@ -383,20 +424,22 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
}
/* create new dapm mux control */
-static int dapm_new_mux(struct snd_soc_codec *codec,
+static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
struct snd_soc_dapm_path *path = NULL;
struct snd_kcontrol *kcontrol;
+ struct snd_card *card = dapm->codec->card->snd_card;
int ret = 0;
if (!w->num_kcontrols) {
- printk(KERN_ERR "asoc: mux %s has no controls\n", w->name);
+ dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name);
return -EINVAL;
}
kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
- ret = snd_ctl_add(codec->card->snd_card, kcontrol);
+ ret = snd_ctl_add(card, kcontrol);
+
if (ret < 0)
goto err;
@@ -406,26 +449,27 @@ static int dapm_new_mux(struct snd_soc_codec *codec,
return ret;
err:
- printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
+ dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
return ret;
}
/* create new dapm volume control */
-static int dapm_new_pga(struct snd_soc_codec *codec,
+static int dapm_new_pga(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w)
{
if (w->num_kcontrols)
- pr_err("asoc: PGA controls not supported: '%s'\n", w->name);
+ dev_err(w->dapm->dev,
+ "asoc: PGA controls not supported: '%s'\n", w->name);
return 0;
}
/* reset 'walked' bit for each dapm path */
-static inline void dapm_clear_walk(struct snd_soc_codec *codec)
+static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_path *p;
- list_for_each_entry(p, &codec->dapm_paths, list)
+ list_for_each_entry(p, &dapm->card->paths, list)
p->walked = 0;
}
@@ -435,13 +479,14 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
*/
static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
{
- int level = snd_power_get_state(widget->codec->card->snd_card);
+ int level = snd_power_get_state(widget->dapm->codec->card->snd_card);
switch (level) {
case SNDRV_CTL_POWER_D3hot:
case SNDRV_CTL_POWER_D3cold:
if (widget->ignore_suspend)
- pr_debug("%s ignoring suspend\n", widget->name);
+ dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
+ widget->name);
return widget->ignore_suspend;
default:
return 1;
@@ -572,7 +617,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
/* call any power change event handlers */
if (w->event)
- pr_debug("power %s event for %s flags %x\n",
+ dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
w->power ? "on" : "off",
w->name, w->event_flags);
@@ -621,9 +666,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
int in, out;
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return out != 0 && in != 0;
}
@@ -634,7 +679,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
if (w->active) {
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return in != 0;
} else {
return dapm_generic_check_power(w);
@@ -648,7 +693,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
if (w->active) {
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return out != 0;
} else {
return dapm_generic_check_power(w);
@@ -674,7 +719,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
}
}
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
return power;
}
@@ -687,8 +732,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
return sort[a->id] - sort[b->id];
if (a->reg != b->reg)
return a->reg - b->reg;
- if (a->codec != b->codec)
- return (unsigned long)a->codec - (unsigned long)b->codec;
+ if (a->dapm != b->dapm)
+ return (unsigned long)a->dapm - (unsigned long)b->dapm;
return 0;
}
@@ -709,12 +754,57 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
list_add_tail(&new_widget->power_list, list);
}
+static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
+ struct snd_soc_dapm_widget *w, int event)
+{
+ struct snd_soc_card *card = dapm->card;
+ const char *ev_name;
+ int power, ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ev_name = "PRE_PMU";
+ power = 1;
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ ev_name = "POST_PMU";
+ power = 1;
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ ev_name = "PRE_PMD";
+ power = 0;
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ev_name = "POST_PMD";
+ power = 0;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ if (w->power != power)
+ return;
+
+ if (w->event && (w->event_flags & event)) {
+ pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n",
+ w->name, ev_name);
+ trace_snd_soc_dapm_widget_event_start(w, event);
+ ret = w->event(w, NULL, event);
+ trace_snd_soc_dapm_widget_event_done(w, event);
+ if (ret < 0)
+ pr_err("%s: %s event failed: %d\n",
+ ev_name, w->name, ret);
+ }
+}
+
/* Apply the coalesced changes from a DAPM sequence */
-static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
+static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
struct list_head *pending)
{
+ struct snd_soc_card *card = dapm->card;
struct snd_soc_dapm_widget *w;
- int reg, power, ret;
+ int reg, power;
unsigned int value = 0;
unsigned int mask = 0;
unsigned int cur_mask;
@@ -735,64 +825,26 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
if (power)
value |= cur_mask;
- pop_dbg(codec->pop_time,
+ pop_dbg(dapm->dev, card->pop_time,
"pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
w->name, reg, value, mask);
- /* power up pre event */
- if (w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
- pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
- if (ret < 0)
- pr_err("%s: pre event failed: %d\n",
- w->name, ret);
- }
-
- /* power down pre event */
- if (!w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
- pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
- if (ret < 0)
- pr_err("%s: pre event failed: %d\n",
- w->name, ret);
- }
+ /* Check for events */
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU);
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD);
}
if (reg >= 0) {
- pop_dbg(codec->pop_time,
+ pop_dbg(dapm->dev, card->pop_time,
"pop test : Applying 0x%x/0x%x to %x in %dms\n",
- value, mask, reg, codec->pop_time);
- pop_wait(codec->pop_time);
- snd_soc_update_bits(codec, reg, mask, value);
+ value, mask, reg, card->pop_time);
+ pop_wait(card->pop_time);
+ snd_soc_update_bits(dapm->codec, reg, mask, value);
}
list_for_each_entry(w, pending, power_list) {
- /* power up post event */
- if (w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
- pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
- w->name);
- ret = w->event(w,
- NULL, SND_SOC_DAPM_POST_PMU);
- if (ret < 0)
- pr_err("%s: post event failed: %d\n",
- w->name, ret);
- }
-
- /* power down post event */
- if (!w->power && w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
- pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
- w->name);
- ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
- if (ret < 0)
- pr_err("%s: post event failed: %d\n",
- w->name, ret);
- }
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU);
+ dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD);
}
}
@@ -804,26 +856,29 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
* Currently anything that requires more than a single write is not
* handled.
*/
-static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
- int event, int sort[])
+static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
+ struct list_head *list, int event, int sort[])
{
struct snd_soc_dapm_widget *w, *n;
LIST_HEAD(pending);
int cur_sort = -1;
int cur_reg = SND_SOC_NOPM;
+ struct snd_soc_dapm_context *cur_dapm = NULL;
int ret;
list_for_each_entry_safe(w, n, list, power_list) {
ret = 0;
/* Do we need to apply any queued changes? */
- if (sort[w->id] != cur_sort || w->reg != cur_reg) {
+ if (sort[w->id] != cur_sort || w->reg != cur_reg ||
+ w->dapm != cur_dapm) {
if (!list_empty(&pending))
- dapm_seq_run_coalesced(codec, &pending);
+ dapm_seq_run_coalesced(cur_dapm, &pending);
INIT_LIST_HEAD(&pending);
cur_sort = -1;
cur_reg = SND_SOC_NOPM;
+ cur_dapm = NULL;
}
switch (w->id) {
@@ -867,19 +922,55 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
/* Queue it up for application */
cur_sort = sort[w->id];
cur_reg = w->reg;
+ cur_dapm = w->dapm;
list_move(&w->power_list, &pending);
break;
}
if (ret < 0)
- pr_err("Failed to apply widget power: %d\n",
- ret);
+ dev_err(w->dapm->dev,
+ "Failed to apply widget power: %d\n", ret);
}
if (!list_empty(&pending))
- dapm_seq_run_coalesced(codec, &pending);
+ dapm_seq_run_coalesced(dapm, &pending);
}
+static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
+{
+ struct snd_soc_dapm_update *update = dapm->update;
+ struct snd_soc_dapm_widget *w;
+ int ret;
+
+ if (!update)
+ return;
+
+ w = update->widget;
+
+ if (w->event &&
+ (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
+ ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
+ if (ret != 0)
+ pr_err("%s DAPM pre-event failed: %d\n",
+ w->name, ret);
+ }
+
+ ret = snd_soc_update_bits(w->codec, update->reg, update->mask,
+ update->val);
+ if (ret < 0)
+ pr_err("%s DAPM update failed: %d\n", w->name, ret);
+
+ if (w->event &&
+ (w->event_flags & SND_SOC_DAPM_POST_REG)) {
+ ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
+ if (ret != 0)
+ pr_err("%s DAPM post-event failed: %d\n",
+ w->name, ret);
+ }
+}
+
+
+
/*
* Scan each dapm widget for complete audio path.
* A complete path is a route that has valid endpoints i.e.:-
@@ -889,20 +980,26 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
* o Input pin to Output pin (bypass, sidetone)
* o DAC to ADC (loopback).
*/
-static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
+static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
{
- struct snd_soc_card *card = codec->card;
+ struct snd_soc_card *card = dapm->codec->card;
struct snd_soc_dapm_widget *w;
+ struct snd_soc_dapm_context *d;
LIST_HEAD(up_list);
LIST_HEAD(down_list);
int ret = 0;
int power;
- int sys_power = 0;
+
+ trace_snd_soc_dapm_start(card);
+
+ list_for_each_entry(d, &card->dapm_list, list)
+ if (d->n_widgets)
+ d->dev_power = 0;
/* Check which widgets we need to power and store them in
* lists indicating if they should be powered up or down.
*/
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &card->widgets, list) {
switch (w->id) {
case snd_soc_dapm_pre:
dapm_seq_insert(w, &down_list, dapm_down_seq);
@@ -920,11 +1017,13 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
else
power = 1;
if (power)
- sys_power = 1;
+ w->dapm->dev_power = 1;
if (w->power == power)
continue;
+ trace_snd_soc_dapm_widget_power(w, power);
+
if (power)
dapm_seq_insert(w, &up_list, dapm_up_seq);
else
@@ -938,23 +1037,26 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
/* If there are no DAPM widgets then try to figure out power from the
* event type.
*/
- if (list_empty(&codec->dapm_widgets)) {
+ if (!dapm->n_widgets) {
switch (event) {
case SND_SOC_DAPM_STREAM_START:
case SND_SOC_DAPM_STREAM_RESUME:
- sys_power = 1;
+ dapm->dev_power = 1;
+ break;
+ case SND_SOC_DAPM_STREAM_STOP:
+ dapm->dev_power = !!dapm->codec->active;
break;
case SND_SOC_DAPM_STREAM_SUSPEND:
- sys_power = 0;
+ dapm->dev_power = 0;
break;
case SND_SOC_DAPM_STREAM_NOP:
- switch (codec->bias_level) {
+ switch (dapm->bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
- sys_power = 0;
+ dapm->dev_power = 0;
break;
default:
- sys_power = 1;
+ dapm->dev_power = 1;
break;
}
break;
@@ -963,52 +1065,71 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
}
}
- if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_dapm_set_bias_level(card, codec,
- SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- pr_err("Failed to turn on bias: %d\n", ret);
- }
+ list_for_each_entry(d, &dapm->card->dapm_list, list) {
+ if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
+ ret = snd_soc_dapm_set_bias_level(card, d,
+ SND_SOC_BIAS_STANDBY);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to turn on bias: %d\n", ret);
+ }
- /* If we're changing to all on or all off then prepare */
- if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
- (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE);
- if (ret != 0)
- pr_err("Failed to prepare bias: %d\n", ret);
+ /* If we're changing to all on or all off then prepare */
+ if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
+ (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
+ ret = snd_soc_dapm_set_bias_level(card, d,
+ SND_SOC_BIAS_PREPARE);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to prepare bias: %d\n", ret);
+ }
}
/* Power down widgets first; try to avoid amplifying pops. */
- dapm_seq_run(codec, &down_list, event, dapm_down_seq);
+ dapm_seq_run(dapm, &down_list, event, dapm_down_seq);
+
+ dapm_widget_update(dapm);
/* Now power up. */
- dapm_seq_run(codec, &up_list, event, dapm_up_seq);
+ dapm_seq_run(dapm, &up_list, event, dapm_up_seq);
+
+ list_for_each_entry(d, &dapm->card->dapm_list, list) {
+ /* If we just powered the last thing off drop to standby bias */
+ if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
+ ret = snd_soc_dapm_set_bias_level(card, d,
+ SND_SOC_BIAS_STANDBY);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to apply standby bias: %d\n",
+ ret);
+ }
- /* If we just powered the last thing off drop to standby bias */
- if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- pr_err("Failed to apply standby bias: %d\n", ret);
- }
+ /* If we're in standby and can support bias off then do that */
+ if (d->bias_level == SND_SOC_BIAS_STANDBY &&
+ d->idle_bias_off) {
+ ret = snd_soc_dapm_set_bias_level(card, d,
+ SND_SOC_BIAS_OFF);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to turn off bias: %d\n", ret);
+ }
- /* If we're in standby and can support bias off then do that */
- if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
- codec->idle_bias_off) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
- if (ret != 0)
- pr_err("Failed to turn off bias: %d\n", ret);
+ /* If we just powered up then move to active bias */
+ if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
+ ret = snd_soc_dapm_set_bias_level(card, d,
+ SND_SOC_BIAS_ON);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to apply active bias: %d\n",
+ ret);
+ }
}
- /* If we just powered up then move to active bias */
- if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
- ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON);
- if (ret != 0)
- pr_err("Failed to apply active bias: %d\n", ret);
- }
+ pop_dbg(dapm->dev, card->pop_time,
+ "DAPM sequencing finished, waiting %dms\n", card->pop_time);
+ pop_wait(card->pop_time);
- pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
- codec->pop_time);
- pop_wait(codec->pop_time);
+ trace_snd_soc_dapm_done(card);
return 0;
}
@@ -1035,9 +1156,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
return -ENOMEM;
in = is_connected_input_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
out = is_connected_output_ep(w);
- dapm_clear_walk(w->codec);
+ dapm_clear_walk(w->dapm);
ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
w->name, w->power ? "On" : "Off", in, out);
@@ -1087,29 +1208,29 @@ static const struct file_operations dapm_widget_power_fops = {
.llseek = default_llseek,
};
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
struct dentry *d;
- if (!codec->debugfs_dapm)
+ if (!dapm->debugfs_dapm)
return;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
- if (!w->name)
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (!w->name || w->dapm != dapm)
continue;
d = debugfs_create_file(w->name, 0444,
- codec->debugfs_dapm, w,
+ dapm->debugfs_dapm, w,
&dapm_widget_power_fops);
if (!d)
- printk(KERN_WARNING
- "ASoC: Failed to create %s debugfs file\n",
- w->name);
+ dev_warn(w->dapm->dev,
+ "ASoC: Failed to create %s debugfs file\n",
+ w->name);
}
}
#else
-void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
{
}
#endif
@@ -1123,6 +1244,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
int found = 0;
if (widget->id != snd_soc_dapm_mux &&
+ widget->id != snd_soc_dapm_virt_mux &&
widget->id != snd_soc_dapm_value_mux)
return -ENODEV;
@@ -1130,7 +1252,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
return 0;
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->card->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -1146,7 +1268,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
}
if (found)
- dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
@@ -1164,7 +1286,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
return -ENODEV;
/* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
+ list_for_each_entry(path, &widget->dapm->card->paths, list) {
if (path->kcontrol != kcontrol)
continue;
@@ -1175,7 +1297,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
}
if (found)
- dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
@@ -1191,7 +1313,9 @@ static ssize_t dapm_widget_show(struct device *dev,
int count = 0;
char *state = "not set";
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &codec->card->widgets, list) {
+ if (w->dapm != &codec->dapm)
+ continue;
/* only display widgets that burnm power */
switch (w->id) {
@@ -1203,6 +1327,7 @@ static ssize_t dapm_widget_show(struct device *dev,
case snd_soc_dapm_dac:
case snd_soc_dapm_adc:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
case snd_soc_dapm_supply:
@@ -1215,7 +1340,7 @@ static ssize_t dapm_widget_show(struct device *dev,
}
}
- switch (codec->bias_level) {
+ switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_ON:
state = "On";
break;
@@ -1247,31 +1372,50 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
}
/* free all dapm widgets and resources */
-static void dapm_free_widgets(struct snd_soc_codec *codec)
+static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w, *next_w;
struct snd_soc_dapm_path *p, *next_p;
- list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) {
+ list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
list_del(&w->list);
+ /*
+ * remove source and sink paths associated to this widget.
+ * While removing the path, remove reference to it from both
+ * source and sink widgets so that path is removed only once.
+ */
+ list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
+ list_del(&p->list_sink);
+ list_del(&p->list_source);
+ list_del(&p->list);
+ kfree(p->long_name);
+ kfree(p);
+ }
+ list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
+ list_del(&p->list_sink);
+ list_del(&p->list_source);
+ list_del(&p->list);
+ kfree(p->long_name);
+ kfree(p);
+ }
+ kfree(w->name);
kfree(w);
}
-
- list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) {
- list_del(&p->list);
- kfree(p->long_name);
- kfree(p);
- }
}
-static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
+static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
const char *pin, int status)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
if (!strcmp(w->name, pin)) {
- pr_debug("dapm: %s: pin %s\n", codec->name, pin);
+ dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
+ pin, status);
w->connected = status;
/* Allow disabling of forced pins */
if (status == 0)
@@ -1280,46 +1424,72 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
}
}
- pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
/**
* snd_soc_dapm_sync - scan and power dapm paths
- * @codec: audio codec
+ * @dapm: DAPM context
*
* Walks all dapm audio paths and powers widgets according to their
* stream or path usage.
*
* Returns 0 for success.
*/
-int snd_soc_dapm_sync(struct snd_soc_codec *codec)
+int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
{
- return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
+ return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
-static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
+static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route)
{
struct snd_soc_dapm_path *path;
struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
- const char *sink = route->sink;
+ struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
+ const char *sink;
const char *control = route->control;
- const char *source = route->source;
+ const char *source;
+ char prefixed_sink[80];
+ char prefixed_source[80];
int ret = 0;
- /* find src and dest widgets */
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ if (dapm->codec->name_prefix) {
+ snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
+ dapm->codec->name_prefix, route->sink);
+ sink = prefixed_sink;
+ snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
+ dapm->codec->name_prefix, route->source);
+ source = prefixed_source;
+ } else {
+ sink = route->sink;
+ source = route->source;
+ }
+ /*
+ * find src and dest widgets over all widgets but favor a widget from
+ * current DAPM context
+ */
+ list_for_each_entry(w, &dapm->card->widgets, list) {
if (!wsink && !(strcmp(w->name, sink))) {
- wsink = w;
+ wtsink = w;
+ if (w->dapm == dapm)
+ wsink = w;
continue;
}
if (!wsource && !(strcmp(w->name, source))) {
- wsource = w;
+ wtsource = w;
+ if (w->dapm == dapm)
+ wsource = w;
}
}
+ /* use widget from another DAPM context if not found from this */
+ if (!wsink)
+ wsink = wtsink;
+ if (!wsource)
+ wsource = wtsource;
if (wsource == NULL || wsink == NULL)
return -ENODEV;
@@ -1353,7 +1523,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
/* connect static paths */
if (control == NULL) {
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 1;
@@ -1365,6 +1535,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_adc:
case snd_soc_dapm_dac:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
case snd_soc_dapm_input:
case snd_soc_dapm_output:
case snd_soc_dapm_micbias:
@@ -1374,14 +1545,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_supply:
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 1;
return 0;
case snd_soc_dapm_mux:
+ case snd_soc_dapm_virt_mux:
case snd_soc_dapm_value_mux:
- ret = dapm_connect_mux(codec, wsource, wsink, path, control,
+ ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
&wsink->kcontrols[0]);
if (ret != 0)
goto err;
@@ -1389,7 +1561,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
- ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
+ ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
if (ret != 0)
goto err;
break;
@@ -1397,7 +1569,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
case snd_soc_dapm_mic:
case snd_soc_dapm_line:
case snd_soc_dapm_spk:
- list_add(&path->list, &codec->dapm_paths);
+ list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
path->connect = 0;
@@ -1406,15 +1578,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
return 0;
err:
- printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source,
- control, sink);
+ dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
+ source, control, sink);
kfree(path);
return ret;
}
/**
* snd_soc_dapm_add_routes - Add routes between DAPM widgets
- * @codec: codec
+ * @dapm: DAPM context
* @route: audio routes
* @num: number of routes
*
@@ -1425,17 +1597,16 @@ err:
* Returns 0 for success else error. On error all resources can be freed
* with a call to snd_soc_card_free().
*/
-int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
+int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num)
{
int i, ret;
for (i = 0; i < num; i++) {
- ret = snd_soc_dapm_add_route(codec, route);
+ ret = snd_soc_dapm_add_route(dapm, route);
if (ret < 0) {
- printk(KERN_ERR "Failed to add route %s->%s\n",
- route->source,
- route->sink);
+ dev_err(dapm->dev, "Failed to add route %s->%s\n",
+ route->source, route->sink);
return ret;
}
route++;
@@ -1447,17 +1618,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
/**
* snd_soc_dapm_new_widgets - add new dapm widgets
- * @codec: audio codec
+ * @dapm: DAPM context
*
* Checks the codec for any new dapm widgets and creates them if found.
*
* Returns 0 for success.
*/
-int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
+int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list)
+ list_for_each_entry(w, &dapm->card->widgets, list)
{
if (w->new)
continue;
@@ -1467,12 +1638,13 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
w->power_check = dapm_generic_check_power;
- dapm_new_mixer(codec, w);
+ dapm_new_mixer(dapm, w);
break;
case snd_soc_dapm_mux:
+ case snd_soc_dapm_virt_mux:
case snd_soc_dapm_value_mux:
w->power_check = dapm_generic_check_power;
- dapm_new_mux(codec, w);
+ dapm_new_mux(dapm, w);
break;
case snd_soc_dapm_adc:
case snd_soc_dapm_aif_out:
@@ -1483,8 +1655,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
w->power_check = dapm_dac_check_power;
break;
case snd_soc_dapm_pga:
+ case snd_soc_dapm_out_drv:
w->power_check = dapm_generic_check_power;
- dapm_new_pga(codec, w);
+ dapm_new_pga(dapm, w);
break;
case snd_soc_dapm_input:
case snd_soc_dapm_output:
@@ -1505,7 +1678,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
w->new = 1;
}
- dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
+ dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -1566,13 +1739,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
(struct soc_mixer_control *)kcontrol->private_value;
unsigned int reg = mc->reg;
unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
int max = mc->max;
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- unsigned int val, val2, val_mask;
- int connect;
- int ret;
+ unsigned int val, val_mask;
+ int connect, change;
+ struct snd_soc_dapm_update update;
val = (ucontrol->value.integer.value[0] & mask);
@@ -1580,18 +1752,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
val = max - val;
val_mask = mask << shift;
val = val << shift;
- if (shift != rshift) {
- val2 = (ucontrol->value.integer.value[1] & mask);
- if (invert)
- val2 = max - val2;
- val_mask |= mask << rshift;
- val |= val2 << rshift;
- }
mutex_lock(&widget->codec->mutex);
widget->value = val;
- if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
+ change = snd_soc_test_bits(widget->codec, reg, val_mask, val);
+ if (change) {
if (val)
/* new connection */
connect = invert ? 0:1;
@@ -1599,28 +1765,20 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
/* old connection must be powered down */
connect = invert ? 1:0;
+ update.kcontrol = kcontrol;
+ update.widget = widget;
+ update.reg = reg;
+ update.mask = mask;
+ update.val = val;
+ widget->dapm->update = &update;
+
dapm_mixer_update_power(widget, kcontrol, connect);
+
+ widget->dapm->update = NULL;
}
- if (widget->event) {
- if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
- ret = widget->event(widget, kcontrol,
- SND_SOC_DAPM_PRE_REG);
- if (ret < 0) {
- ret = 1;
- goto out;
- }
- }
- ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
- if (widget->event_flags & SND_SOC_DAPM_POST_REG)
- ret = widget->event(widget, kcontrol,
- SND_SOC_DAPM_POST_REG);
- } else
- ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
-
-out:
mutex_unlock(&widget->codec->mutex);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
@@ -1668,7 +1826,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, mux, change;
unsigned int mask, bitmask;
- int ret = 0;
+ struct snd_soc_dapm_update update;
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
@@ -1687,24 +1845,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
mutex_lock(&widget->codec->mutex);
widget->value = val;
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
- dapm_mux_update_power(widget, kcontrol, change, mux, e);
- if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
- ret = widget->event(widget,
- kcontrol, SND_SOC_DAPM_PRE_REG);
- if (ret < 0)
- goto out;
- }
+ update.kcontrol = kcontrol;
+ update.widget = widget;
+ update.reg = e->reg;
+ update.mask = mask;
+ update.val = val;
+ widget->dapm->update = &update;
- ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
+ dapm_mux_update_power(widget, kcontrol, change, mux, e);
- if (widget->event_flags & SND_SOC_DAPM_POST_REG)
- ret = widget->event(widget,
- kcontrol, SND_SOC_DAPM_POST_REG);
+ widget->dapm->update = NULL;
-out:
mutex_unlock(&widget->codec->mutex);
- return ret;
+ return change;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
@@ -1816,7 +1970,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, mux, change;
unsigned int mask;
- int ret = 0;
+ struct snd_soc_dapm_update update;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
@@ -1833,24 +1987,20 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
mutex_lock(&widget->codec->mutex);
widget->value = val;
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
- dapm_mux_update_power(widget, kcontrol, change, mux, e);
- if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
- ret = widget->event(widget,
- kcontrol, SND_SOC_DAPM_PRE_REG);
- if (ret < 0)
- goto out;
- }
+ update.kcontrol = kcontrol;
+ update.widget = widget;
+ update.reg = e->reg;
+ update.mask = mask;
+ update.val = val;
+ widget->dapm->update = &update;
- ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
+ dapm_mux_update_power(widget, kcontrol, change, mux, e);
- if (widget->event_flags & SND_SOC_DAPM_POST_REG)
- ret = widget->event(widget,
- kcontrol, SND_SOC_DAPM_POST_REG);
+ widget->dapm->update = NULL;
-out:
mutex_unlock(&widget->codec->mutex);
- return ret;
+ return change;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
@@ -1889,7 +2039,7 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
mutex_lock(&codec->mutex);
ucontrol->value.integer.value[0] =
- snd_soc_dapm_get_pin_status(codec, pin);
+ snd_soc_dapm_get_pin_status(&codec->dapm, pin);
mutex_unlock(&codec->mutex);
@@ -1912,11 +2062,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
mutex_lock(&codec->mutex);
if (ucontrol->value.integer.value[0])
- snd_soc_dapm_enable_pin(codec, pin);
+ snd_soc_dapm_enable_pin(&codec->dapm, pin);
else
- snd_soc_dapm_disable_pin(codec, pin);
+ snd_soc_dapm_disable_pin(&codec->dapm, pin);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(&codec->dapm);
mutex_unlock(&codec->mutex);
@@ -1926,26 +2076,43 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
/**
* snd_soc_dapm_new_control - create new dapm control
- * @codec: audio codec
+ * @dapm: DAPM context
* @widget: widget template
*
* Creates a new dapm control based upon the template.
*
* Returns 0 for success else error.
*/
-int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget)
{
struct snd_soc_dapm_widget *w;
+ size_t name_len;
if ((w = dapm_cnew_widget(widget)) == NULL)
return -ENOMEM;
- w->codec = codec;
+ name_len = strlen(widget->name) + 1;
+ if (dapm->codec->name_prefix)
+ name_len += 1 + strlen(dapm->codec->name_prefix);
+ w->name = kmalloc(name_len, GFP_KERNEL);
+ if (w->name == NULL) {
+ kfree(w);
+ return -ENOMEM;
+ }
+ if (dapm->codec->name_prefix)
+ snprintf(w->name, name_len, "%s %s",
+ dapm->codec->name_prefix, widget->name);
+ else
+ snprintf(w->name, name_len, "%s", widget->name);
+
+ dapm->n_widgets++;
+ w->dapm = dapm;
+ w->codec = dapm->codec;
INIT_LIST_HEAD(&w->sources);
INIT_LIST_HEAD(&w->sinks);
INIT_LIST_HEAD(&w->list);
- list_add(&w->list, &codec->dapm_widgets);
+ list_add(&w->list, &dapm->card->widgets);
/* machine layer set ups unconnected pins and insertions */
w->connected = 1;
@@ -1955,7 +2122,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
/**
* snd_soc_dapm_new_controls - create new dapm controls
- * @codec: audio codec
+ * @dapm: DAPM context
* @widget: widget array
* @num: number of widgets
*
@@ -1963,18 +2130,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
*
* Returns 0 for success else error.
*/
-int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
+int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num)
{
int i, ret;
for (i = 0; i < num; i++) {
- ret = snd_soc_dapm_new_control(codec, widget);
+ ret = snd_soc_dapm_new_control(dapm, widget);
if (ret < 0) {
- printk(KERN_ERR
- "ASoC: Failed to create DAPM control %s: %d\n",
- widget->name, ret);
+ dev_err(dapm->dev,
+ "ASoC: Failed to create DAPM control %s: %d\n",
+ widget->name, ret);
return ret;
}
widget++;
@@ -1983,34 +2150,17 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-
-/**
- * snd_soc_dapm_stream_event - send a stream event to the dapm core
- * @codec: audio codec
- * @stream: stream name
- * @event: stream event
- *
- * Sends a stream event to the dapm core. The core then makes any
- * necessary widget power changes.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
+static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
const char *stream, int event)
{
- struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_widget *w;
- if (stream == NULL)
- return 0;
-
- mutex_lock(&codec->mutex);
- list_for_each_entry(w, &codec->dapm_widgets, list)
+ list_for_each_entry(w, &dapm->card->widgets, list)
{
- if (!w->sname)
+ if (!w->sname || w->dapm != dapm)
continue;
- pr_debug("widget %s\n %s stream %s event %d\n",
- w->name, w->sname, stream, event);
+ dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
+ w->name, w->sname, stream, event);
if (strstr(w->sname, stream)) {
switch(event) {
case SND_SOC_DAPM_STREAM_START:
@@ -2028,7 +2178,30 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
}
}
- dapm_power_widgets(codec, event);
+ dapm_power_widgets(dapm, event);
+}
+
+/**
+ * snd_soc_dapm_stream_event - send a stream event to the dapm core
+ * @rtd: PCM runtime data
+ * @stream: stream name
+ * @event: stream event
+ *
+ * Sends a stream event to the dapm core. The core then makes any
+ * necessary widget power changes.
+ *
+ * Returns 0 for success else error.
+ */
+int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
+ const char *stream, int event)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+
+ if (stream == NULL)
+ return 0;
+
+ mutex_lock(&codec->mutex);
+ soc_dapm_stream_event(&codec->dapm, stream, event);
mutex_unlock(&codec->mutex);
return 0;
}
@@ -2036,7 +2209,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
/**
* snd_soc_dapm_enable_pin - enable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin and its parents or children widgets iff there is
@@ -2044,15 +2217,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 1);
+ return snd_soc_dapm_set_pin(dapm, pin, 1);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
/**
* snd_soc_dapm_force_enable_pin - force a pin to be enabled
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin regardless of any other state. This is
@@ -2062,42 +2235,47 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
if (!strcmp(w->name, pin)) {
- pr_debug("dapm: %s: pin %s\n", codec->name, pin);
+ dev_dbg(w->dapm->dev,
+ "dapm: force enable pin %s\n", pin);
w->connected = 1;
w->force = 1;
return 0;
}
}
- pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
/**
* snd_soc_dapm_disable_pin - disable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Disables input/output pin and its parents or children widgets.
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 0);
+ return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
/**
* snd_soc_dapm_nc_pin - permanently disable pin.
- * @codec: SoC codec
+ * @dapm: DAPM context
* @pin: pin name
*
* Marks the specified pin as being not connected, disabling it along
@@ -2109,26 +2287,29 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{
- return snd_soc_dapm_set_pin(codec, pin, 0);
+ return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
/**
* snd_soc_dapm_get_pin_status - get audio pin status
- * @codec: audio codec
+ * @dapm: DAPM context
* @pin: audio signal pin endpoint (or start point)
*
* Get audio pin status - connected or disconnected.
*
* Returns 1 for connected otherwise 0.
*/
-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
if (!strcmp(w->name, pin))
return w->connected;
}
@@ -2139,7 +2320,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
/**
* snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
- * @codec: audio codec
+ * @dapm: DAPM context
* @pin: audio signal pin endpoint (or start point)
*
* Mark the given endpoint or pin as ignoring suspend. When the
@@ -2148,18 +2329,21 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
* normal means at suspend time, it will not be turned on if it was not
* already enabled.
*/
-int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin)
+int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
+ const char *pin)
{
struct snd_soc_dapm_widget *w;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
if (!strcmp(w->name, pin)) {
w->ignore_suspend = 1;
return 0;
}
}
- pr_err("Unknown DAPM pin: %s\n", pin);
+ dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
@@ -2170,20 +2354,23 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
*
* Free all dapm widgets and resources.
*/
-void snd_soc_dapm_free(struct snd_soc_codec *codec)
+void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
{
- snd_soc_dapm_sys_remove(codec->dev);
- dapm_free_widgets(codec);
+ snd_soc_dapm_sys_remove(dapm->dev);
+ dapm_free_widgets(dapm);
+ list_del(&dapm->list);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
-static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
+static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
{
struct snd_soc_dapm_widget *w;
LIST_HEAD(down_list);
int powerdown = 0;
- list_for_each_entry(w, &codec->dapm_widgets, list) {
+ list_for_each_entry(w, &dapm->card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
if (w->power) {
dapm_seq_insert(w, &down_list, dapm_down_seq);
w->power = 0;
@@ -2195,9 +2382,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
* standby.
*/
if (powerdown) {
- snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE);
- dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
- snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY);
+ snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
+ dapm_seq_run(dapm, &down_list, 0, dapm_down_seq);
+ snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
}
}
@@ -2208,10 +2395,10 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
{
struct snd_soc_codec *codec;
- list_for_each_entry(codec, &card->codec_dev_list, list)
- soc_dapm_shutdown_codec(codec);
-
- snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
+ list_for_each_entry(codec, &card->codec_dev_list, list) {
+ soc_dapm_shutdown_codec(&codec->dapm);
+ snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF);
+ }
}
/* Module information */
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 8a0a9205b1e7..ac5a5bc7375a 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -13,11 +13,11 @@
#include <sound/jack.h>
#include <sound/soc.h>
-#include <sound/soc-dapm.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
+#include <trace/events/asoc.h>
/**
* snd_soc_jack_new - Create a new jack
@@ -60,14 +60,18 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
{
struct snd_soc_codec *codec;
+ struct snd_soc_dapm_context *dapm;
struct snd_soc_jack_pin *pin;
int enable;
int oldstatus;
+ trace_snd_soc_jack_report(jack, mask, status);
+
if (!jack)
return;
codec = jack->codec;
+ dapm = &codec->dapm;
mutex_lock(&codec->mutex);
@@ -81,6 +85,8 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
if (mask && (jack->status == oldstatus))
goto out;
+ trace_snd_soc_jack_notify(jack, status);
+
list_for_each_entry(pin, &jack->pins, list) {
enable = pin->mask & jack->status;
@@ -88,15 +94,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
enable = !enable;
if (enable)
- snd_soc_dapm_enable_pin(codec, pin->pin);
+ snd_soc_dapm_enable_pin(dapm, pin->pin);
else
- snd_soc_dapm_disable_pin(codec, pin->pin);
+ snd_soc_dapm_disable_pin(dapm, pin->pin);
}
/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain(&jack->notifier, status, NULL);
- snd_soc_dapm_sync(codec);
+ snd_soc_dapm_sync(dapm);
snd_jack_report(jack->jack, status);
@@ -207,6 +213,12 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
static irqreturn_t gpio_handler(int irq, void *data)
{
struct snd_soc_jack_gpio *gpio = data;
+ struct device *dev = gpio->jack->codec->card->dev;
+
+ trace_snd_soc_jack_irq(gpio->name);
+
+ if (device_may_wakeup(dev))
+ pm_wakeup_event(dev, gpio->debounce_time + 50);
schedule_delayed_work(&gpio->work,
msecs_to_jiffies(gpio->debounce_time));
@@ -263,11 +275,12 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
gpios[i].jack = jack;
- ret = request_irq(gpio_to_irq(gpios[i].gpio),
- gpio_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- jack->codec->dev->driver->name,
- &gpios[i]);
+ ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio),
+ gpio_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ jack->codec->dev->driver->name,
+ &gpios[i]);
if (ret)
goto err;
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
new file mode 100644
index 000000000000..15130b50dfe3
--- /dev/null
+++ b/tools/perf/arch/s390/Makefile
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
new file mode 100644
index 000000000000..e19653e025fa
--- /dev/null
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -0,0 +1,22 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright IBM Corp. 2010
+ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
+ *
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+#define NUM_GPRS 16
+
+static const char *gpr_names[NUM_GPRS] = {
+ "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
+ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+};
+
+const char *get_arch_regstr(unsigned int n)
+{
+ return (n >= NUM_GPRS) ? NULL : gpr_names[n];
+}
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 44a47e13bd67..c49837de7d3f 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -36,7 +36,6 @@ static const struct option options[] = {
static int __cmd_buildid_list(void)
{
- int err = -1;
struct perf_session *session;
session = perf_session__new(input_name, O_RDONLY, force, false);
@@ -49,7 +48,7 @@ static int __cmd_buildid_list(void)
perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
perf_session__delete(session);
- return err;
+ return 0;
}
int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 2e000c068cc5..add163c9f0e7 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -249,6 +249,11 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
!params.show_lines))
usage_with_options(probe_usage, options);
+ /*
+ * Only consider the user's kernel image path if given.
+ */
+ symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
+
if (params.list_events) {
if (params.mod_events) {
pr_err(" Error: Don't use --list with --add/--del.\n");
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e2c2de201eec..564491fa18b2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -197,7 +197,7 @@ static void sig_atexit(void)
if (child_pid > 0)
kill(child_pid, SIGTERM);
- if (signr == -1)
+ if (signr == -1 || signr == SIGUSR1)
return;
signal(signr, SIG_DFL);
@@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv)
atexit(sig_atexit);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
+ signal(SIGUSR1, sig_handler);
if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
perror("failed to create pipes");
@@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv)
execvp(argv[0], (char **)argv);
perror(argv[0]);
+ kill(getppid(), SIGUSR1);
exit(-1);
}
@@ -762,7 +764,7 @@ static int __cmd_record(int argc, const char **argv)
}
}
- if (quiet)
+ if (quiet || signr == SIGUSR1)
return 0;
fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d7e67b167ea3..7cba0551a565 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
const char *name, bool is_kallsyms)
{
const size_t size = PATH_MAX;
- char *filename = malloc(size),
+ char *realname = realpath(name, NULL),
+ *filename = malloc(size),
*linkname = malloc(size), *targetname;
int len, err = -1;
- if (filename == NULL || linkname == NULL)
+ if (realname == NULL || filename == NULL || linkname == NULL)
goto out_free;
len = snprintf(filename, size, "%s%s%s",
- debugdir, is_kallsyms ? "/" : "", name);
+ debugdir, is_kallsyms ? "/" : "", realname);
if (mkdir_p(filename, 0755))
goto out_free;
@@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
if (is_kallsyms) {
if (copyfile("/proc/kallsyms", filename))
goto out_free;
- } else if (link(name, filename) && copyfile(name, filename))
+ } else if (link(realname, filename) && copyfile(name, filename))
goto out_free;
}
@@ -300,6 +301,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
if (symlink(targetname, linkname) == 0)
err = 0;
out_free:
+ free(realname);
free(filename);
free(linkname);
return err;
@@ -946,11 +948,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
/*
* We set id to -1 if the data file doesn't contain sample
- * ids. Check for this and avoid walking through the entire
- * list of ids which may be large.
+ * ids. This can happen when the data file contains one type
+ * of event and in that case, the header can still store the
+ * event attribute information. Check for this and avoid
+ * walking through the entire list of ids which may be large.
*/
- if (id == -1ULL)
+ if (id == -1ULL) {
+ if (header->attrs > 0)
+ return &header->attr[0]->attr;
return NULL;
+ }
for (i = 0; i < header->attrs; i++) {
struct perf_header_attr *attr = header->attr[i];
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 2022e8740994..76bcc35cf9b1 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -356,7 +356,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
int depth, int depth_mask, int period,
- u64 total_samples, int hits,
+ u64 total_samples, u64 hits,
int left_margin)
{
int i;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3b6a5297bf16..61191c6cbe7a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
const char *kernel_get_module_path(const char *module)
{
struct dso *dso;
+ struct map *map;
+ const char *vmlinux_name;
if (module) {
list_for_each_entry(dso, &machine.kernel_dsos, node) {
@@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module)
}
pr_debug("Failed to find module %s.\n", module);
return NULL;
+ }
+
+ map = machine.vmlinux_maps[MAP__FUNCTION];
+ dso = map->dso;
+
+ vmlinux_name = symbol_conf.vmlinux_name;
+ if (vmlinux_name) {
+ if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
+ return NULL;
} else {
- dso = machine.vmlinux_maps[MAP__FUNCTION]->dso;
- if (dso__load_vmlinux_path(dso,
- machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
+ if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
pr_debug("Failed to load kernel map.\n");
return NULL;
}
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3991d73d1cff..ddf4d4556321 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head)
}
/* Dwarf FL wrappers */
-
-static int __linux_kernel_find_elf(Dwfl_Module *mod,
- void **userdata,
- const char *module_name,
- Dwarf_Addr base,
- char **file_name, Elf **elfp)
-{
- int fd;
- const char *path = kernel_get_module_path(module_name);
-
- if (path) {
- fd = open(path, O_RDONLY);
- if (fd >= 0) {
- *file_name = strdup(path);
- return fd;
- }
- }
- /* If failed, try to call standard method */
- return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
- file_name, elfp);
-}
-
static char *debuginfo_path; /* Currently dummy */
static const Dwfl_Callbacks offline_callbacks = {
@@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = {
.find_elf = dwfl_build_id_find_elf,
};
-static const Dwfl_Callbacks kernel_callbacks = {
- .find_debuginfo = dwfl_standard_find_debuginfo,
- .debuginfo_path = &debuginfo_path,
-
- .find_elf = __linux_kernel_find_elf,
- .section_address = dwfl_linux_kernel_module_section_address,
-};
-
/* Get a Dwarf from offline image */
static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
{
@@ -185,6 +155,38 @@ error:
return dbg;
}
+#if _ELFUTILS_PREREQ(0, 148)
+/* This method is buggy if elfutils is older than 0.148 */
+static int __linux_kernel_find_elf(Dwfl_Module *mod,
+ void **userdata,
+ const char *module_name,
+ Dwarf_Addr base,
+ char **file_name, Elf **elfp)
+{
+ int fd;
+ const char *path = kernel_get_module_path(module_name);
+
+ pr_debug2("Use file %s for %s\n", path, module_name);
+ if (path) {
+ fd = open(path, O_RDONLY);
+ if (fd >= 0) {
+ *file_name = strdup(path);
+ return fd;
+ }
+ }
+ /* If failed, try to call standard method */
+ return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
+ file_name, elfp);
+}
+
+static const Dwfl_Callbacks kernel_callbacks = {
+ .find_debuginfo = dwfl_standard_find_debuginfo,
+ .debuginfo_path = &debuginfo_path,
+
+ .find_elf = __linux_kernel_find_elf,
+ .section_address = dwfl_linux_kernel_module_section_address,
+};
+
/* Get a Dwarf from live kernel image */
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
Dwarf_Addr *bias)
@@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
dbg = dwfl_addrdwarf(*dwflp, addr, bias);
/* Here, check whether we could get a real dwarf */
if (!dbg) {
+ pr_debug("Failed to find kernel dwarf at %lx\n",
+ (unsigned long)addr);
dwfl_end(*dwflp);
*dwflp = NULL;
}
return dbg;
}
+#else
+/* With older elfutils, this just support kernel module... */
+static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
+ Dwarf_Addr *bias)
+{
+ int fd;
+ const char *path = kernel_get_module_path("kernel");
+
+ if (!path) {
+ pr_err("Failed to find vmlinux path\n");
+ return NULL;
+ }
+
+ pr_debug2("Use file %s for debuginfo\n", path);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ return dwfl_init_offline_dwarf(fd, dwflp, bias);
+}
+#endif
/* Dwarf wrappers */
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 0409fc7c0058..8fc0bd3a3a4a 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -259,7 +259,7 @@ static bool __match_glob(const char *str, const char *pat, bool ignore_space)
if (!*pat) /* Tail wild card matches all */
return true;
while (*str)
- if (strglobmatch(str++, pat))
+ if (__match_glob(str++, pat, ignore_space))
return true;
}
return !*str && !*pat;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 0500895a45af..439ab947daf4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
struct machine *machine = kmaps->machine;
struct map *curr_map = map;
struct symbol *pos;
- int count = 0;
+ int count = 0, moved = 0;
struct rb_root *root = &self->symbols[map->type];
struct rb_node *next = rb_first(root);
int kernel_range = 0;
@@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
char dso_name[PATH_MAX];
struct dso *dso;
+ if (count == 0) {
+ curr_map = map;
+ goto filter_symbol;
+ }
+
if (self->kernel == DSO_TYPE_GUEST_KERNEL)
snprintf(dso_name, sizeof(dso_name),
"[guest.kernel].%d",
@@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
map_groups__insert(kmaps, curr_map);
++kernel_range;
}
-
+filter_symbol:
if (filter && filter(curr_map, pos)) {
discard_symbol: rb_erase(&pos->rb_node, root);
symbol__delete(pos);
@@ -623,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root);
if (curr_map != map) {
rb_erase(&pos->rb_node, root);
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
- }
- count++;
+ ++moved;
+ } else
+ ++count;
}
}
@@ -634,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
dso__set_loaded(curr_map->dso, curr_map->type);
}
- return count;
+ return count + moved;
}
int dso__load_kallsyms(struct dso *self, const char *filename,
@@ -1774,8 +1780,8 @@ out_failure:
return -1;
}
-static int dso__load_vmlinux(struct dso *self, struct map *map,
- const char *vmlinux, symbol_filter_t filter)
+int dso__load_vmlinux(struct dso *self, struct map *map,
+ const char *vmlinux, symbol_filter_t filter)
{
int err = -1, fd;
@@ -2125,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self)
return kernel;
}
+struct process_args {
+ u64 start;
+};
+
+static int symbol__in_kernel(void *arg, const char *name,
+ char type __used, u64 start)
+{
+ struct process_args *args = arg;
+
+ if (strchr(name, '['))
+ return 0;
+
+ args->start = start;
+ return 1;
+}
+
+/* Figure out the start address of kernel map from /proc/kallsyms */
+static u64 machine__get_kernel_start_addr(struct machine *machine)
+{
+ const char *filename;
+ char path[PATH_MAX];
+ struct process_args args;
+
+ if (machine__is_host(machine)) {
+ filename = "/proc/kallsyms";
+ } else {
+ if (machine__is_default_guest(machine))
+ filename = (char *)symbol_conf.default_guest_kallsyms;
+ else {
+ sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+ filename = path;
+ }
+ }
+
+ if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
+ return 0;
+
+ return args.start;
+}
+
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
{
enum map_type type;
+ u64 start = machine__get_kernel_start_addr(self);
for (type = 0; type < MAP__NR_TYPES; ++type) {
struct kmap *kmap;
- self->vmlinux_maps[type] = map__new2(0, kernel, type);
+ self->vmlinux_maps[type] = map__new2(start, kernel, type);
if (self->vmlinux_maps[type] == NULL)
return -1;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 038f2201ee09..6c6eafdb932d 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -166,6 +166,8 @@ void dso__sort_by_name(struct dso *self, enum map_type type);
struct dso *__dsos__findnew(struct list_head *head, const char *name);
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
+int dso__load_vmlinux(struct dso *self, struct map *map,
+ const char *vmlinux, symbol_filter_t filter);
int dso__load_vmlinux_path(struct dso *self, struct map *map,
symbol_filter_t filter);
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
new file mode 100644
index 000000000000..d1d442ed106a
--- /dev/null
+++ b/tools/virtio/Makefile
@@ -0,0 +1,12 @@
+all: test mod
+test: virtio_test
+virtio_test: virtio_ring.o virtio_test.o
+CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -MMD
+vpath %.c ../../drivers/virtio
+mod:
+ ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
+.PHONY: all test mod clean
+clean:
+ ${RM} *.o vhost_test/*.o vhost_test/.*.cmd \
+ vhost_test/Module.symvers vhost_test/modules.order *.d
+-include *.d
diff --git a/tools/virtio/linux/device.h b/tools/virtio/linux/device.h
new file mode 100644
index 000000000000..4ad7e1df0db5
--- /dev/null
+++ b/tools/virtio/linux/device.h
@@ -0,0 +1,2 @@
+#ifndef LINUX_DEVICE_H
+#endif
diff --git a/tools/virtio/linux/slab.h b/tools/virtio/linux/slab.h
new file mode 100644
index 000000000000..81baeac8ae40
--- /dev/null
+++ b/tools/virtio/linux/slab.h
@@ -0,0 +1,2 @@
+#ifndef LINUX_SLAB_H
+#endif
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
new file mode 100644
index 000000000000..669bcdd45805
--- /dev/null
+++ b/tools/virtio/linux/virtio.h
@@ -0,0 +1,223 @@
+#ifndef LINUX_VIRTIO_H
+#define LINUX_VIRTIO_H
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <linux/types.h>
+#include <errno.h>
+
+typedef unsigned long long dma_addr_t;
+
+struct scatterlist {
+ unsigned long page_link;
+ unsigned int offset;
+ unsigned int length;
+ dma_addr_t dma_address;
+};
+
+struct page {
+ unsigned long long dummy;
+};
+
+#define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond))
+
+/* Physical == Virtual */
+#define virt_to_phys(p) ((unsigned long)p)
+#define phys_to_virt(a) ((void *)(unsigned long)(a))
+/* Page address: Virtual / 4K */
+#define virt_to_page(p) ((struct page*)((virt_to_phys(p) / 4096) * \
+ sizeof(struct page)))
+#define offset_in_page(p) (((unsigned long)p) % 4096)
+#define sg_phys(sg) ((sg->page_link & ~0x3) / sizeof(struct page) * 4096 + \
+ sg->offset)
+static inline void sg_mark_end(struct scatterlist *sg)
+{
+ /*
+ * Set termination bit, clear potential chain bit
+ */
+ sg->page_link |= 0x02;
+ sg->page_link &= ~0x01;
+}
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+ memset(sgl, 0, sizeof(*sgl) * nents);
+ sg_mark_end(&sgl[nents - 1]);
+}
+static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
+{
+ unsigned long page_link = sg->page_link & 0x3;
+
+ /*
+ * In order for the low bit stealing approach to work, pages
+ * must be aligned at a 32-bit boundary as a minimum.
+ */
+ BUG_ON((unsigned long) page & 0x03);
+ sg->page_link = page_link | (unsigned long) page;
+}
+
+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
+ unsigned int len, unsigned int offset)
+{
+ sg_assign_page(sg, page);
+ sg->offset = offset;
+ sg->length = len;
+}
+
+static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
+ unsigned int buflen)
+{
+ sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
+}
+
+static inline void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen)
+{
+ sg_init_table(sg, 1);
+ sg_set_buf(sg, buf, buflen);
+}
+
+typedef __u16 u16;
+
+typedef enum {
+ GFP_KERNEL,
+ GFP_ATOMIC,
+} gfp_t;
+typedef enum {
+ IRQ_NONE,
+ IRQ_HANDLED
+} irqreturn_t;
+
+static inline void *kmalloc(size_t s, gfp_t gfp)
+{
+ return malloc(s);
+}
+
+static inline void kfree(void *p)
+{
+ free(p);
+}
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#define uninitialized_var(x) x = x
+
+# ifndef likely
+# define likely(x) (__builtin_expect(!!(x), 1))
+# endif
+# ifndef unlikely
+# define unlikely(x) (__builtin_expect(!!(x), 0))
+# endif
+
+#define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
+#ifdef DEBUG
+#define pr_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
+#else
+#define pr_debug(format, ...) do {} while (0)
+#endif
+#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
+#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
+
+/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
+#define list_add_tail(a, b) do {} while (0)
+#define list_del(a) do {} while (0)
+
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BITS_PER_BYTE 8
+#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+/* TODO: Not atomic as it should be:
+ * we don't use this for anything important. */
+static inline void clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p &= ~mask;
+}
+
+static inline int test_bit(int nr, const volatile unsigned long *addr)
+{
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+/* The only feature we care to support */
+#define virtio_has_feature(dev, feature) \
+ test_bit((feature), (dev)->features)
+/* end of stubs */
+
+struct virtio_device {
+ void *dev;
+ unsigned long features[1];
+};
+
+struct virtqueue {
+ /* TODO: commented as list macros are empty stubs for now.
+ * Broken but enough for virtio_ring.c
+ * struct list_head list; */
+ void (*callback)(struct virtqueue *vq);
+ const char *name;
+ struct virtio_device *vdev;
+ void *priv;
+};
+
+#define EXPORT_SYMBOL_GPL(__EXPORT_SYMBOL_GPL_name) \
+ void __EXPORT_SYMBOL_GPL##__EXPORT_SYMBOL_GPL_name() { \
+}
+#define MODULE_LICENSE(__MODULE_LICENSE_value) \
+ const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value
+
+#define CONFIG_SMP
+
+#if defined(__i386__) || defined(__x86_64__)
+#define barrier() asm volatile("" ::: "memory")
+#define mb() __sync_synchronize()
+
+#define smp_mb() mb()
+# define smp_rmb() barrier()
+# define smp_wmb() barrier()
+#else
+#error Please fill in barrier macros
+#endif
+
+/* Interfaces exported by virtio_ring. */
+int virtqueue_add_buf_gfp(struct virtqueue *vq,
+ struct scatterlist sg[],
+ unsigned int out_num,
+ unsigned int in_num,
+ void *data,
+ gfp_t gfp);
+
+static inline int virtqueue_add_buf(struct virtqueue *vq,
+ struct scatterlist sg[],
+ unsigned int out_num,
+ unsigned int in_num,
+ void *data)
+{
+ return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC);
+}
+
+void virtqueue_kick(struct virtqueue *vq);
+
+void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
+
+void virtqueue_disable_cb(struct virtqueue *vq);
+
+bool virtqueue_enable_cb(struct virtqueue *vq);
+
+void *virtqueue_detach_unused_buf(struct virtqueue *vq);
+struct virtqueue *vring_new_virtqueue(unsigned int num,
+ unsigned int vring_align,
+ struct virtio_device *vdev,
+ void *pages,
+ void (*notify)(struct virtqueue *vq),
+ void (*callback)(struct virtqueue *vq),
+ const char *name);
+void vring_del_virtqueue(struct virtqueue *vq);
+
+#endif
diff --git a/tools/virtio/vhost_test/Makefile b/tools/virtio/vhost_test/Makefile
new file mode 100644
index 000000000000..a1d35b81b314
--- /dev/null
+++ b/tools/virtio/vhost_test/Makefile
@@ -0,0 +1,2 @@
+obj-m += vhost_test.o
+EXTRA_CFLAGS += -Idrivers/vhost
diff --git a/tools/virtio/vhost_test/vhost_test.c b/tools/virtio/vhost_test/vhost_test.c
new file mode 100644
index 000000000000..18735189e62b
--- /dev/null
+++ b/tools/virtio/vhost_test/vhost_test.c
@@ -0,0 +1 @@
+#include "test.c"
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
new file mode 100644
index 000000000000..df0c6d2c3860
--- /dev/null
+++ b/tools/virtio/virtio_test.c
@@ -0,0 +1,248 @@
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <string.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <linux/vhost.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ring.h>
+#include "../../drivers/vhost/test.h"
+
+struct vq_info {
+ int kick;
+ int call;
+ int num;
+ int idx;
+ void *ring;
+ /* copy used for control */
+ struct vring vring;
+ struct virtqueue *vq;
+};
+
+struct vdev_info {
+ struct virtio_device vdev;
+ int control;
+ struct pollfd fds[1];
+ struct vq_info vqs[1];
+ int nvqs;
+ void *buf;
+ size_t buf_size;
+ struct vhost_memory *mem;
+};
+
+void vq_notify(struct virtqueue *vq)
+{
+ struct vq_info *info = vq->priv;
+ unsigned long long v = 1;
+ int r;
+ r = write(info->kick, &v, sizeof v);
+ assert(r == sizeof v);
+}
+
+void vq_callback(struct virtqueue *vq)
+{
+}
+
+
+void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
+{
+ struct vhost_vring_state state = { .index = info->idx };
+ struct vhost_vring_file file = { .index = info->idx };
+ unsigned long long features = dev->vdev.features[0];
+ struct vhost_vring_addr addr = {
+ .index = info->idx,
+ .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc,
+ .avail_user_addr = (uint64_t)(unsigned long)info->vring.avail,
+ .used_user_addr = (uint64_t)(unsigned long)info->vring.used,
+ };
+ int r;
+ r = ioctl(dev->control, VHOST_SET_FEATURES, &features);
+ assert(r >= 0);
+ state.num = info->vring.num;
+ r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
+ assert(r >= 0);
+ state.num = 0;
+ r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state);
+ assert(r >= 0);
+ r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr);
+ assert(r >= 0);
+ file.fd = info->kick;
+ r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
+ assert(r >= 0);
+ file.fd = info->call;
+ r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file);
+ assert(r >= 0);
+}
+
+static void vq_info_add(struct vdev_info *dev, int num)
+{
+ struct vq_info *info = &dev->vqs[dev->nvqs];
+ int r;
+ info->idx = dev->nvqs;
+ info->kick = eventfd(0, EFD_NONBLOCK);
+ info->call = eventfd(0, EFD_NONBLOCK);
+ r = posix_memalign(&info->ring, 4096, vring_size(num, 4096));
+ assert(r >= 0);
+ memset(info->ring, 0, vring_size(num, 4096));
+ vring_init(&info->vring, num, info->ring, 4096);
+ info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev, info->ring,
+ vq_notify, vq_callback, "test");
+ assert(info->vq);
+ info->vq->priv = info;
+ vhost_vq_setup(dev, info);
+ dev->fds[info->idx].fd = info->call;
+ dev->fds[info->idx].events = POLLIN;
+ dev->nvqs++;
+}
+
+static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
+{
+ int r;
+ memset(dev, 0, sizeof *dev);
+ dev->vdev.features[0] = features;
+ dev->vdev.features[1] = features >> 32;
+ dev->buf_size = 1024;
+ dev->buf = malloc(dev->buf_size);
+ assert(dev->buf);
+ dev->control = open("/dev/vhost-test", O_RDWR);
+ assert(dev->control >= 0);
+ r = ioctl(dev->control, VHOST_SET_OWNER, NULL);
+ assert(r >= 0);
+ dev->mem = malloc(offsetof(struct vhost_memory, regions) +
+ sizeof dev->mem->regions[0]);
+ assert(dev->mem);
+ memset(dev->mem, 0, offsetof(struct vhost_memory, regions) +
+ sizeof dev->mem->regions[0]);
+ dev->mem->nregions = 1;
+ dev->mem->regions[0].guest_phys_addr = (long)dev->buf;
+ dev->mem->regions[0].userspace_addr = (long)dev->buf;
+ dev->mem->regions[0].memory_size = dev->buf_size;
+ r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);
+ assert(r >= 0);
+}
+
+/* TODO: this is pretty bad: we get a cache line bounce
+ * for the wait queue on poll and another one on read,
+ * plus the read which is there just to clear the
+ * current state. */
+static void wait_for_interrupt(struct vdev_info *dev)
+{
+ int i;
+ unsigned long long val;
+ poll(dev->fds, dev->nvqs, -1);
+ for (i = 0; i < dev->nvqs; ++i)
+ if (dev->fds[i].revents & POLLIN) {
+ read(dev->fds[i].fd, &val, sizeof val);
+ }
+}
+
+static void run_test(struct vdev_info *dev, struct vq_info *vq, int bufs)
+{
+ struct scatterlist sl;
+ long started = 0, completed = 0;
+ long completed_before;
+ int r, test = 1;
+ unsigned len;
+ long long spurious = 0;
+ r = ioctl(dev->control, VHOST_TEST_RUN, &test);
+ assert(r >= 0);
+ for (;;) {
+ virtqueue_disable_cb(vq->vq);
+ completed_before = completed;
+ do {
+ if (started < bufs) {
+ sg_init_one(&sl, dev->buf, dev->buf_size);
+ r = virtqueue_add_buf(vq->vq, &sl, 1, 0,
+ dev->buf + started);
+ if (likely(r >= 0)) {
+ ++started;
+ virtqueue_kick(vq->vq);
+ }
+ } else
+ r = -1;
+
+ /* Flush out completed bufs if any */
+ if (virtqueue_get_buf(vq->vq, &len)) {
+ ++completed;
+ r = 0;
+ }
+
+ } while (r >= 0);
+ if (completed == completed_before)
+ ++spurious;
+ assert(completed <= bufs);
+ assert(started <= bufs);
+ if (completed == bufs)
+ break;
+ if (virtqueue_enable_cb(vq->vq)) {
+ wait_for_interrupt(dev);
+ }
+ }
+ test = 0;
+ r = ioctl(dev->control, VHOST_TEST_RUN, &test);
+ assert(r >= 0);
+ fprintf(stderr, "spurious wakeus: 0x%llx\n", spurious);
+}
+
+const char optstring[] = "h";
+const struct option longopts[] = {
+ {
+ .name = "help",
+ .val = 'h',
+ },
+ {
+ .name = "indirect",
+ .val = 'I',
+ },
+ {
+ .name = "no-indirect",
+ .val = 'i',
+ },
+ {
+ }
+};
+
+static void help()
+{
+ fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n");
+}
+
+int main(int argc, char **argv)
+{
+ struct vdev_info dev;
+ unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC;
+ int o;
+
+ for (;;) {
+ o = getopt_long(argc, argv, optstring, longopts, NULL);
+ switch (o) {
+ case -1:
+ goto done;
+ case '?':
+ help();
+ exit(2);
+ case 'h':
+ help();
+ goto done;
+ case 'i':
+ features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+done:
+ vdev_info_init(&dev, features);
+ vq_info_add(&dev, 256);
+ run_test(&dev, &dev.vqs[0], 0x100000);
+ return 0;
+}
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index b2b3c2d1cf8b..f463cafdccb2 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -104,6 +104,8 @@ static int cpio_mkslink(const char *name, const char *target,
char s[256];
time_t mtime = time(NULL);
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -152,6 +154,8 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
char s[256];
time_t mtime = time(NULL);
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -245,6 +249,8 @@ static int cpio_mknod(const char *name, unsigned int mode,
else
mode |= S_IFCHR;
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -303,18 +309,18 @@ static int cpio_mkfile(const char *name, const char *location,
mode |= S_IFREG;
- retval = stat (location, &buf);
- if (retval) {
- fprintf (stderr, "File %s could not be located\n", location);
- goto error;
- }
-
file = open (location, O_RDONLY);
if (file < 0) {
fprintf (stderr, "File %s could not be opened for reading\n", location);
goto error;
}
+ retval = fstat (file, &buf);
+ if (retval) {
+ fprintf (stderr, "File %s could not be stat()'ed\n", location);
+ goto error;
+ }
+
filebuf = malloc(buf.st_size);
if (!filebuf) {
fprintf (stderr, "out of memory\n");
@@ -332,6 +338,8 @@ static int cpio_mkfile(const char *name, const char *location,
/* data goes on last link */
if (i == nlinks) size = buf.st_size;
+ if (name[0] == '/')
+ name++;
namesize = strlen(name) + 1;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08lX%08X%08X%08X%08X%08X%08X",
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
index 792a750d9441..c14322d1c0cf 100644
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -22,14 +22,15 @@
*/
#include <linux/stringify.h>
+#include <asm-generic/vmlinux.lds.h>
.section .init.ramfs,"a"
__irf_start:
.incbin __stringify(INITRAMFS_IMAGE)
__irf_end:
.section .init.ramfs.info,"a"
-.globl __initramfs_size
-__initramfs_size:
+.globl VMLINUX_SYMBOL(__initramfs_size)
+VMLINUX_SYMBOL(__initramfs_size):
#ifdef CONFIG_64BIT
.quad __irf_end - __irf_start
#else
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 7f1178f6b839..f63ccb0a5982 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -15,3 +15,6 @@ config KVM_APIC_ARCHITECTURE
config KVM_MMIO
bool
+
+config KVM_ASYNC_PF
+ bool
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index 7c98928b09d9..ae72ae604c89 100644
--- a/virt/kvm/assigned-dev.c
+++ b/virt/kvm/assigned-dev.c
@@ -55,58 +55,31 @@ static int find_index_from_host_irq(struct kvm_assigned_dev_kernel
return index;
}
-static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
+static irqreturn_t kvm_assigned_dev_thread(int irq, void *dev_id)
{
- struct kvm_assigned_dev_kernel *assigned_dev;
- int i;
+ struct kvm_assigned_dev_kernel *assigned_dev = dev_id;
+ u32 vector;
+ int index;
- assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
- interrupt_work);
+ if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_INTX) {
+ spin_lock(&assigned_dev->intx_lock);
+ disable_irq_nosync(irq);
+ assigned_dev->host_irq_disabled = true;
+ spin_unlock(&assigned_dev->intx_lock);
+ }
- spin_lock_irq(&assigned_dev->assigned_dev_lock);
if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
- struct kvm_guest_msix_entry *guest_entries =
- assigned_dev->guest_msix_entries;
- for (i = 0; i < assigned_dev->entries_nr; i++) {
- if (!(guest_entries[i].flags &
- KVM_ASSIGNED_MSIX_PENDING))
- continue;
- guest_entries[i].flags &= ~KVM_ASSIGNED_MSIX_PENDING;
+ index = find_index_from_host_irq(assigned_dev, irq);
+ if (index >= 0) {
+ vector = assigned_dev->
+ guest_msix_entries[index].vector;
kvm_set_irq(assigned_dev->kvm,
- assigned_dev->irq_source_id,
- guest_entries[i].vector, 1);
+ assigned_dev->irq_source_id, vector, 1);
}
} else
kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
assigned_dev->guest_irq, 1);
- spin_unlock_irq(&assigned_dev->assigned_dev_lock);
-}
-
-static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
-{
- unsigned long flags;
- struct kvm_assigned_dev_kernel *assigned_dev =
- (struct kvm_assigned_dev_kernel *) dev_id;
-
- spin_lock_irqsave(&assigned_dev->assigned_dev_lock, flags);
- if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
- int index = find_index_from_host_irq(assigned_dev, irq);
- if (index < 0)
- goto out;
- assigned_dev->guest_msix_entries[index].flags |=
- KVM_ASSIGNED_MSIX_PENDING;
- }
-
- schedule_work(&assigned_dev->interrupt_work);
-
- if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) {
- disable_irq_nosync(irq);
- assigned_dev->host_irq_disabled = true;
- }
-
-out:
- spin_unlock_irqrestore(&assigned_dev->assigned_dev_lock, flags);
return IRQ_HANDLED;
}
@@ -114,7 +87,6 @@ out:
static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_assigned_dev_kernel *dev;
- unsigned long flags;
if (kian->gsi == -1)
return;
@@ -127,12 +99,12 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
/* The guest irq may be shared so this ack may be
* from another device.
*/
- spin_lock_irqsave(&dev->assigned_dev_lock, flags);
+ spin_lock(&dev->intx_lock);
if (dev->host_irq_disabled) {
enable_irq(dev->host_irq);
dev->host_irq_disabled = false;
}
- spin_unlock_irqrestore(&dev->assigned_dev_lock, flags);
+ spin_unlock(&dev->intx_lock);
}
static void deassign_guest_irq(struct kvm *kvm,
@@ -141,6 +113,9 @@ static void deassign_guest_irq(struct kvm *kvm,
kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
assigned_dev->ack_notifier.gsi = -1;
+ kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
+ assigned_dev->guest_irq, 0);
+
if (assigned_dev->irq_source_id != -1)
kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id);
assigned_dev->irq_source_id = -1;
@@ -152,28 +127,19 @@ static void deassign_host_irq(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev)
{
/*
- * In kvm_free_device_irq, cancel_work_sync return true if:
- * 1. work is scheduled, and then cancelled.
- * 2. work callback is executed.
- *
- * The first one ensured that the irq is disabled and no more events
- * would happen. But for the second one, the irq may be enabled (e.g.
- * for MSI). So we disable irq here to prevent further events.
+ * We disable irq here to prevent further events.
*
* Notice this maybe result in nested disable if the interrupt type is
* INTx, but it's OK for we are going to free it.
*
* If this function is a part of VM destroy, please ensure that till
* now, the kvm state is still legal for probably we also have to wait
- * interrupt_work done.
+ * on a currently running IRQ handler.
*/
if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
int i;
for (i = 0; i < assigned_dev->entries_nr; i++)
- disable_irq_nosync(assigned_dev->
- host_msix_entries[i].vector);
-
- cancel_work_sync(&assigned_dev->interrupt_work);
+ disable_irq(assigned_dev->host_msix_entries[i].vector);
for (i = 0; i < assigned_dev->entries_nr; i++)
free_irq(assigned_dev->host_msix_entries[i].vector,
@@ -185,8 +151,7 @@ static void deassign_host_irq(struct kvm *kvm,
pci_disable_msix(assigned_dev->dev);
} else {
/* Deal with MSI and INTx */
- disable_irq_nosync(assigned_dev->host_irq);
- cancel_work_sync(&assigned_dev->interrupt_work);
+ disable_irq(assigned_dev->host_irq);
free_irq(assigned_dev->host_irq, (void *)assigned_dev);
@@ -232,7 +197,8 @@ static void kvm_free_assigned_device(struct kvm *kvm,
{
kvm_free_assigned_irq(kvm, assigned_dev);
- pci_reset_function(assigned_dev->dev);
+ __pci_reset_function(assigned_dev->dev);
+ pci_restore_state(assigned_dev->dev);
pci_release_regions(assigned_dev->dev);
pci_disable_device(assigned_dev->dev);
@@ -265,8 +231,8 @@ static int assigned_device_enable_host_intx(struct kvm *kvm,
* on the same interrupt line is not a happy situation: there
* are going to be long delays in accepting, acking, etc.
*/
- if (request_irq(dev->host_irq, kvm_assigned_dev_intr,
- 0, "kvm_assigned_intx_device", (void *)dev))
+ if (request_threaded_irq(dev->host_irq, NULL, kvm_assigned_dev_thread,
+ IRQF_ONESHOT, dev->irq_name, (void *)dev))
return -EIO;
return 0;
}
@@ -284,8 +250,8 @@ static int assigned_device_enable_host_msi(struct kvm *kvm,
}
dev->host_irq = dev->dev->irq;
- if (request_irq(dev->host_irq, kvm_assigned_dev_intr, 0,
- "kvm_assigned_msi_device", (void *)dev)) {
+ if (request_threaded_irq(dev->host_irq, NULL, kvm_assigned_dev_thread,
+ 0, dev->irq_name, (void *)dev)) {
pci_disable_msi(dev->dev);
return -EIO;
}
@@ -310,10 +276,9 @@ static int assigned_device_enable_host_msix(struct kvm *kvm,
return r;
for (i = 0; i < dev->entries_nr; i++) {
- r = request_irq(dev->host_msix_entries[i].vector,
- kvm_assigned_dev_intr, 0,
- "kvm_assigned_msix_device",
- (void *)dev);
+ r = request_threaded_irq(dev->host_msix_entries[i].vector,
+ NULL, kvm_assigned_dev_thread,
+ 0, dev->irq_name, (void *)dev);
if (r)
goto err;
}
@@ -370,6 +335,9 @@ static int assign_host_irq(struct kvm *kvm,
if (dev->irq_requested_type & KVM_DEV_IRQ_HOST_MASK)
return r;
+ snprintf(dev->irq_name, sizeof(dev->irq_name), "kvm:%s",
+ pci_name(dev->dev));
+
switch (host_irq_type) {
case KVM_DEV_IRQ_HOST_INTX:
r = assigned_device_enable_host_intx(kvm, dev);
@@ -547,6 +515,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
}
pci_reset_function(dev);
+ pci_save_state(dev);
match->assigned_dev_id = assigned_dev->assigned_dev_id;
match->host_segnr = assigned_dev->segnr;
@@ -554,12 +523,10 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
match->host_devfn = assigned_dev->devfn;
match->flags = assigned_dev->flags;
match->dev = dev;
- spin_lock_init(&match->assigned_dev_lock);
+ spin_lock_init(&match->intx_lock);
match->irq_source_id = -1;
match->kvm = kvm;
match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
- INIT_WORK(&match->interrupt_work,
- kvm_assigned_dev_interrupt_work_handler);
list_add(&match->list, &kvm->arch.assigned_dev_head);
@@ -579,6 +546,7 @@ out:
mutex_unlock(&kvm->lock);
return r;
out_list_del:
+ pci_restore_state(dev);
list_del(&match->list);
pci_release_regions(dev);
out_disable:
@@ -651,9 +619,9 @@ static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm,
r = -ENOMEM;
goto msix_nr_out;
}
- adev->guest_msix_entries = kzalloc(
- sizeof(struct kvm_guest_msix_entry) *
- entry_nr->entry_nr, GFP_KERNEL);
+ adev->guest_msix_entries =
+ kzalloc(sizeof(struct msix_entry) * entry_nr->entry_nr,
+ GFP_KERNEL);
if (!adev->guest_msix_entries) {
kfree(adev->host_msix_entries);
r = -ENOMEM;
@@ -706,7 +674,7 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
- int r = -ENOTTY;
+ int r;
switch (ioctl) {
case KVM_ASSIGN_PCI_DEVICE: {
@@ -724,7 +692,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
r = -EOPNOTSUPP;
break;
}
-#ifdef KVM_CAP_ASSIGN_DEV_IRQ
case KVM_ASSIGN_DEV_IRQ: {
struct kvm_assigned_irq assigned_irq;
@@ -747,8 +714,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
goto out;
break;
}
-#endif
-#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
case KVM_DEASSIGN_PCI_DEVICE: {
struct kvm_assigned_pci_dev assigned_dev;
@@ -760,7 +725,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
goto out;
break;
}
-#endif
#ifdef KVM_CAP_IRQ_ROUTING
case KVM_SET_GSI_ROUTING: {
struct kvm_irq_routing routing;
@@ -813,6 +777,9 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
break;
}
#endif
+ default:
+ r = -ENOTTY;
+ break;
}
out:
return r;
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
new file mode 100644
index 000000000000..74268b4c2ee1
--- /dev/null
+++ b/virt/kvm/async_pf.c
@@ -0,0 +1,216 @@
+/*
+ * kvm asynchronous fault support
+ *
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Author:
+ * Gleb Natapov <gleb@redhat.com>
+ *
+ * This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mmu_context.h>
+
+#include "async_pf.h"
+#include <trace/events/kvm.h>
+
+static struct kmem_cache *async_pf_cache;
+
+int kvm_async_pf_init(void)
+{
+ async_pf_cache = KMEM_CACHE(kvm_async_pf, 0);
+
+ if (!async_pf_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void kvm_async_pf_deinit(void)
+{
+ if (async_pf_cache)
+ kmem_cache_destroy(async_pf_cache);
+ async_pf_cache = NULL;
+}
+
+void kvm_async_pf_vcpu_init(struct kvm_vcpu *vcpu)
+{
+ INIT_LIST_HEAD(&vcpu->async_pf.done);
+ INIT_LIST_HEAD(&vcpu->async_pf.queue);
+ spin_lock_init(&vcpu->async_pf.lock);
+}
+
+static void async_pf_execute(struct work_struct *work)
+{
+ struct page *page = NULL;
+ struct kvm_async_pf *apf =
+ container_of(work, struct kvm_async_pf, work);
+ struct mm_struct *mm = apf->mm;
+ struct kvm_vcpu *vcpu = apf->vcpu;
+ unsigned long addr = apf->addr;
+ gva_t gva = apf->gva;
+
+ might_sleep();
+
+ use_mm(mm);
+ down_read(&mm->mmap_sem);
+ get_user_pages(current, mm, addr, 1, 1, 0, &page, NULL);
+ up_read(&mm->mmap_sem);
+ unuse_mm(mm);
+
+ spin_lock(&vcpu->async_pf.lock);
+ list_add_tail(&apf->link, &vcpu->async_pf.done);
+ apf->page = page;
+ apf->done = true;
+ spin_unlock(&vcpu->async_pf.lock);
+
+ /*
+ * apf may be freed by kvm_check_async_pf_completion() after
+ * this point
+ */
+
+ trace_kvm_async_pf_completed(addr, page, gva);
+
+ if (waitqueue_active(&vcpu->wq))
+ wake_up_interruptible(&vcpu->wq);
+
+ mmdrop(mm);
+ kvm_put_kvm(vcpu->kvm);
+}
+
+void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+{
+ /* cancel outstanding work queue item */
+ while (!list_empty(&vcpu->async_pf.queue)) {
+ struct kvm_async_pf *work =
+ list_entry(vcpu->async_pf.queue.next,
+ typeof(*work), queue);
+ cancel_work_sync(&work->work);
+ list_del(&work->queue);
+ if (!work->done) /* work was canceled */
+ kmem_cache_free(async_pf_cache, work);
+ }
+
+ spin_lock(&vcpu->async_pf.lock);
+ while (!list_empty(&vcpu->async_pf.done)) {
+ struct kvm_async_pf *work =
+ list_entry(vcpu->async_pf.done.next,
+ typeof(*work), link);
+ list_del(&work->link);
+ if (work->page)
+ put_page(work->page);
+ kmem_cache_free(async_pf_cache, work);
+ }
+ spin_unlock(&vcpu->async_pf.lock);
+
+ vcpu->async_pf.queued = 0;
+}
+
+void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)
+{
+ struct kvm_async_pf *work;
+
+ while (!list_empty_careful(&vcpu->async_pf.done) &&
+ kvm_arch_can_inject_async_page_present(vcpu)) {
+ spin_lock(&vcpu->async_pf.lock);
+ work = list_first_entry(&vcpu->async_pf.done, typeof(*work),
+ link);
+ list_del(&work->link);
+ spin_unlock(&vcpu->async_pf.lock);
+
+ if (work->page)
+ kvm_arch_async_page_ready(vcpu, work);
+ kvm_arch_async_page_present(vcpu, work);
+
+ list_del(&work->queue);
+ vcpu->async_pf.queued--;
+ if (work->page)
+ put_page(work->page);
+ kmem_cache_free(async_pf_cache, work);
+ }
+}
+
+int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
+ struct kvm_arch_async_pf *arch)
+{
+ struct kvm_async_pf *work;
+
+ if (vcpu->async_pf.queued >= ASYNC_PF_PER_VCPU)
+ return 0;
+
+ /* setup delayed work */
+
+ /*
+ * do alloc nowait since if we are going to sleep anyway we
+ * may as well sleep faulting in page
+ */
+ work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT);
+ if (!work)
+ return 0;
+
+ work->page = NULL;
+ work->done = false;
+ work->vcpu = vcpu;
+ work->gva = gva;
+ work->addr = gfn_to_hva(vcpu->kvm, gfn);
+ work->arch = *arch;
+ work->mm = current->mm;
+ atomic_inc(&work->mm->mm_count);
+ kvm_get_kvm(work->vcpu->kvm);
+
+ /* this can't really happen otherwise gfn_to_pfn_async
+ would succeed */
+ if (unlikely(kvm_is_error_hva(work->addr)))
+ goto retry_sync;
+
+ INIT_WORK(&work->work, async_pf_execute);
+ if (!schedule_work(&work->work))
+ goto retry_sync;
+
+ list_add_tail(&work->queue, &vcpu->async_pf.queue);
+ vcpu->async_pf.queued++;
+ kvm_arch_async_page_not_present(vcpu, work);
+ return 1;
+retry_sync:
+ kvm_put_kvm(work->vcpu->kvm);
+ mmdrop(work->mm);
+ kmem_cache_free(async_pf_cache, work);
+ return 0;
+}
+
+int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu)
+{
+ struct kvm_async_pf *work;
+
+ if (!list_empty_careful(&vcpu->async_pf.done))
+ return 0;
+
+ work = kmem_cache_zalloc(async_pf_cache, GFP_ATOMIC);
+ if (!work)
+ return -ENOMEM;
+
+ work->page = bad_page;
+ get_page(bad_page);
+ INIT_LIST_HEAD(&work->queue); /* for list_del to work */
+
+ spin_lock(&vcpu->async_pf.lock);
+ list_add_tail(&work->link, &vcpu->async_pf.done);
+ spin_unlock(&vcpu->async_pf.lock);
+
+ vcpu->async_pf.queued++;
+ return 0;
+}
diff --git a/virt/kvm/async_pf.h b/virt/kvm/async_pf.h
new file mode 100644
index 000000000000..e7ef6447cb82
--- /dev/null
+++ b/virt/kvm/async_pf.h
@@ -0,0 +1,36 @@
+/*
+ * kvm asynchronous fault support
+ *
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Author:
+ * Gleb Natapov <gleb@redhat.com>
+ *
+ * This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KVM_ASYNC_PF_H__
+#define __KVM_ASYNC_PF_H__
+
+#ifdef CONFIG_KVM_ASYNC_PF
+int kvm_async_pf_init(void);
+void kvm_async_pf_deinit(void);
+void kvm_async_pf_vcpu_init(struct kvm_vcpu *vcpu);
+#else
+#define kvm_async_pf_init() (0)
+#define kvm_async_pf_deinit() do{}while(0)
+#define kvm_async_pf_vcpu_init(C) do{}while(0)
+#endif
+
+#endif
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index c1f1e3c62984..2ca4535f4fb7 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -44,14 +44,19 @@
*/
struct _irqfd {
- struct kvm *kvm;
- struct eventfd_ctx *eventfd;
- int gsi;
- struct list_head list;
- poll_table pt;
- wait_queue_t wait;
- struct work_struct inject;
- struct work_struct shutdown;
+ /* Used for MSI fast-path */
+ struct kvm *kvm;
+ wait_queue_t wait;
+ /* Update side is protected by irqfds.lock */
+ struct kvm_kernel_irq_routing_entry __rcu *irq_entry;
+ /* Used for level IRQ fast-path */
+ int gsi;
+ struct work_struct inject;
+ /* Used for setup/shutdown */
+ struct eventfd_ctx *eventfd;
+ struct list_head list;
+ poll_table pt;
+ struct work_struct shutdown;
};
static struct workqueue_struct *irqfd_cleanup_wq;
@@ -125,14 +130,22 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
unsigned long flags = (unsigned long)key;
+ struct kvm_kernel_irq_routing_entry *irq;
+ struct kvm *kvm = irqfd->kvm;
- if (flags & POLLIN)
+ if (flags & POLLIN) {
+ rcu_read_lock();
+ irq = rcu_dereference(irqfd->irq_entry);
/* An event has been signaled, inject an interrupt */
- schedule_work(&irqfd->inject);
+ if (irq)
+ kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1);
+ else
+ schedule_work(&irqfd->inject);
+ rcu_read_unlock();
+ }
if (flags & POLLHUP) {
/* The eventfd is closing, detach from KVM */
- struct kvm *kvm = irqfd->kvm;
unsigned long flags;
spin_lock_irqsave(&kvm->irqfds.lock, flags);
@@ -163,9 +176,31 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
add_wait_queue(wqh, &irqfd->wait);
}
+/* Must be called under irqfds.lock */
+static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
+ struct kvm_irq_routing_table *irq_rt)
+{
+ struct kvm_kernel_irq_routing_entry *e;
+ struct hlist_node *n;
+
+ if (irqfd->gsi >= irq_rt->nr_rt_entries) {
+ rcu_assign_pointer(irqfd->irq_entry, NULL);
+ return;
+ }
+
+ hlist_for_each_entry(e, n, &irq_rt->map[irqfd->gsi], link) {
+ /* Only fast-path MSI. */
+ if (e->type == KVM_IRQ_ROUTING_MSI)
+ rcu_assign_pointer(irqfd->irq_entry, e);
+ else
+ rcu_assign_pointer(irqfd->irq_entry, NULL);
+ }
+}
+
static int
kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
{
+ struct kvm_irq_routing_table *irq_rt;
struct _irqfd *irqfd, *tmp;
struct file *file = NULL;
struct eventfd_ctx *eventfd = NULL;
@@ -215,6 +250,10 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
goto fail;
}
+ irq_rt = rcu_dereference_protected(kvm->irq_routing,
+ lockdep_is_held(&kvm->irqfds.lock));
+ irqfd_update(kvm, irqfd, irq_rt);
+
events = file->f_op->poll(file, &irqfd->pt);
list_add_tail(&irqfd->list, &kvm->irqfds.items);
@@ -271,8 +310,17 @@ kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi)
spin_lock_irq(&kvm->irqfds.lock);
list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
- if (irqfd->eventfd == eventfd && irqfd->gsi == gsi)
+ if (irqfd->eventfd == eventfd && irqfd->gsi == gsi) {
+ /*
+ * This rcu_assign_pointer is needed for when
+ * another thread calls kvm_irqfd_update before
+ * we flush workqueue below.
+ * It is paired with synchronize_rcu done by caller
+ * of that function.
+ */
+ rcu_assign_pointer(irqfd->irq_entry, NULL);
irqfd_deactivate(irqfd);
+ }
}
spin_unlock_irq(&kvm->irqfds.lock);
@@ -322,6 +370,25 @@ kvm_irqfd_release(struct kvm *kvm)
}
/*
+ * Change irq_routing and irqfd.
+ * Caller must invoke synchronize_rcu afterwards.
+ */
+void kvm_irq_routing_update(struct kvm *kvm,
+ struct kvm_irq_routing_table *irq_rt)
+{
+ struct _irqfd *irqfd;
+
+ spin_lock_irq(&kvm->irqfds.lock);
+
+ rcu_assign_pointer(kvm->irq_routing, irq_rt);
+
+ list_for_each_entry(irqfd, &kvm->irqfds.items, list)
+ irqfd_update(kvm, irqfd, irq_rt);
+
+ spin_unlock_irq(&kvm->irqfds.lock);
+}
+
+/*
* create a host-wide workqueue for issuing deferred shutdown requests
* aggregated from all vm* instances. We need our own isolated single-thread
* queue to prevent deadlock against flushing the normal work-queue.
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 8edca9141b78..9f614b4e365f 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -114,8 +114,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
return r;
}
-static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int irq_source_id, int level)
+int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm *kvm, int irq_source_id, int level)
{
struct kvm_lapic_irq irq;
@@ -409,8 +409,9 @@ int kvm_set_irq_routing(struct kvm *kvm,
mutex_lock(&kvm->irq_lock);
old = kvm->irq_routing;
- rcu_assign_pointer(kvm->irq_routing, new);
+ kvm_irq_routing_update(kvm, new);
mutex_unlock(&kvm->irq_lock);
+
synchronize_rcu();
new = old;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 5225052aebc1..b1b6cbbc522d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -55,6 +55,7 @@
#include <asm-generic/bitops/le.h>
#include "coalesced_mmio.h"
+#include "async_pf.h"
#define CREATE_TRACE_POINTS
#include <trace/events/kvm.h>
@@ -89,7 +90,8 @@ static void hardware_disable_all(void);
static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
-static bool kvm_rebooting;
+bool kvm_rebooting;
+EXPORT_SYMBOL_GPL(kvm_rebooting);
static bool largepages_enabled = true;
@@ -167,8 +169,12 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
void kvm_flush_remote_tlbs(struct kvm *kvm)
{
+ int dirty_count = kvm->tlbs_dirty;
+
+ smp_mb();
if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
++kvm->stat.remote_tlb_flush;
+ cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);
}
void kvm_reload_remote_mmus(struct kvm *kvm)
@@ -186,6 +192,7 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
vcpu->kvm = kvm;
vcpu->vcpu_id = id;
init_waitqueue_head(&vcpu->wq);
+ kvm_async_pf_vcpu_init(vcpu);
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page) {
@@ -247,7 +254,7 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
kvm->mmu_notifier_seq++;
- need_tlb_flush = kvm_unmap_hva(kvm, address);
+ need_tlb_flush = kvm_unmap_hva(kvm, address) | kvm->tlbs_dirty;
spin_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, idx);
@@ -291,6 +298,7 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
kvm->mmu_notifier_count++;
for (; start < end; start += PAGE_SIZE)
need_tlb_flush |= kvm_unmap_hva(kvm, start);
+ need_tlb_flush |= kvm->tlbs_dirty;
spin_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, idx);
@@ -381,11 +389,15 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
static struct kvm *kvm_create_vm(void)
{
- int r = 0, i;
- struct kvm *kvm = kvm_arch_create_vm();
+ int r, i;
+ struct kvm *kvm = kvm_arch_alloc_vm();
- if (IS_ERR(kvm))
- goto out;
+ if (!kvm)
+ return ERR_PTR(-ENOMEM);
+
+ r = kvm_arch_init_vm(kvm);
+ if (r)
+ goto out_err_nodisable;
r = hardware_enable_all();
if (r)
@@ -399,23 +411,19 @@ static struct kvm *kvm_create_vm(void)
r = -ENOMEM;
kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
if (!kvm->memslots)
- goto out_err;
+ goto out_err_nosrcu;
if (init_srcu_struct(&kvm->srcu))
- goto out_err;
+ goto out_err_nosrcu;
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);
+ if (!kvm->buses[i])
goto out_err;
- }
}
r = kvm_init_mmu_notifier(kvm);
- if (r) {
- cleanup_srcu_struct(&kvm->srcu);
+ if (r)
goto out_err;
- }
kvm->mm = current->mm;
atomic_inc(&kvm->mm->mm_count);
@@ -429,19 +437,35 @@ static struct kvm *kvm_create_vm(void)
spin_lock(&kvm_lock);
list_add(&kvm->vm_list, &vm_list);
spin_unlock(&kvm_lock);
-out:
+
return kvm;
out_err:
+ cleanup_srcu_struct(&kvm->srcu);
+out_err_nosrcu:
hardware_disable_all();
out_err_nodisable:
for (i = 0; i < KVM_NR_BUSES; i++)
kfree(kvm->buses[i]);
kfree(kvm->memslots);
- kfree(kvm);
+ kvm_arch_free_vm(kvm);
return ERR_PTR(r);
}
+static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+ if (!memslot->dirty_bitmap)
+ return;
+
+ if (2 * kvm_dirty_bitmap_bytes(memslot) > PAGE_SIZE)
+ vfree(memslot->dirty_bitmap_head);
+ else
+ kfree(memslot->dirty_bitmap_head);
+
+ memslot->dirty_bitmap = NULL;
+ memslot->dirty_bitmap_head = NULL;
+}
+
/*
* Free any memory in @free but not in @dont.
*/
@@ -454,7 +478,7 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
vfree(free->rmap);
if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
- vfree(free->dirty_bitmap);
+ kvm_destroy_dirty_bitmap(free);
for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
@@ -465,7 +489,6 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
}
free->npages = 0;
- free->dirty_bitmap = NULL;
free->rmap = NULL;
}
@@ -499,6 +522,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
kvm_arch_flush_shadow(kvm);
#endif
kvm_arch_destroy_vm(kvm);
+ kvm_free_physmem(kvm);
+ cleanup_srcu_struct(&kvm->srcu);
+ kvm_arch_free_vm(kvm);
hardware_disable_all();
mmdrop(mm);
}
@@ -528,6 +554,27 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
}
/*
+ * Allocation size is twice as large as the actual dirty bitmap size.
+ * This makes it possible to do double buffering: see x86's
+ * kvm_vm_ioctl_get_dirty_log().
+ */
+static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+ unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
+
+ if (dirty_bytes > PAGE_SIZE)
+ memslot->dirty_bitmap = vzalloc(dirty_bytes);
+ else
+ memslot->dirty_bitmap = kzalloc(dirty_bytes, GFP_KERNEL);
+
+ if (!memslot->dirty_bitmap)
+ return -ENOMEM;
+
+ memslot->dirty_bitmap_head = memslot->dirty_bitmap;
+ return 0;
+}
+
+/*
* Allocate some memory and give it an address in the guest physical address
* space.
*
@@ -604,13 +651,11 @@ int __kvm_set_memory_region(struct kvm *kvm,
/* Allocate if a slot is being created */
#ifndef CONFIG_S390
if (npages && !new.rmap) {
- new.rmap = vmalloc(npages * sizeof(*new.rmap));
+ new.rmap = vzalloc(npages * sizeof(*new.rmap));
if (!new.rmap)
goto out_free;
- memset(new.rmap, 0, npages * sizeof(*new.rmap));
-
new.user_alloc = user_alloc;
new.userspace_addr = mem->userspace_addr;
}
@@ -633,14 +678,11 @@ int __kvm_set_memory_region(struct kvm *kvm,
>> KVM_HPAGE_GFN_SHIFT(level));
lpages -= base_gfn >> KVM_HPAGE_GFN_SHIFT(level);
- new.lpage_info[i] = vmalloc(lpages * sizeof(*new.lpage_info[i]));
+ new.lpage_info[i] = vzalloc(lpages * sizeof(*new.lpage_info[i]));
if (!new.lpage_info[i])
goto out_free;
- memset(new.lpage_info[i], 0,
- lpages * sizeof(*new.lpage_info[i]));
-
if (base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
new.lpage_info[i][0].write_count = 1;
if ((base_gfn+npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
@@ -661,12 +703,8 @@ skip_lpage:
/* Allocate page dirty bitmap if needed */
if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
- unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
-
- new.dirty_bitmap = vmalloc(dirty_bytes);
- if (!new.dirty_bitmap)
+ if (kvm_create_dirty_bitmap(&new) < 0)
goto out_free;
- memset(new.dirty_bitmap, 0, dirty_bytes);
/* destroy any largepage mappings for dirty tracking */
if (old.npages)
flush_shadow = 1;
@@ -685,6 +723,7 @@ skip_lpage:
memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
if (mem->slot >= slots->nmemslots)
slots->nmemslots = mem->slot + 1;
+ slots->generation++;
slots->memslots[mem->slot].flags |= KVM_MEMSLOT_INVALID;
old_memslots = kvm->memslots;
@@ -719,6 +758,7 @@ skip_lpage:
memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
if (mem->slot >= slots->nmemslots)
slots->nmemslots = mem->slot + 1;
+ slots->generation++;
/* actual memory is freed via old in kvm_free_physmem_slot below */
if (!npages) {
@@ -849,10 +889,10 @@ int kvm_is_error_hva(unsigned long addr)
}
EXPORT_SYMBOL_GPL(kvm_is_error_hva);
-struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
+static struct kvm_memory_slot *__gfn_to_memslot(struct kvm_memslots *slots,
+ gfn_t gfn)
{
int i;
- struct kvm_memslots *slots = kvm_memslots(kvm);
for (i = 0; i < slots->nmemslots; ++i) {
struct kvm_memory_slot *memslot = &slots->memslots[i];
@@ -863,6 +903,11 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
}
return NULL;
}
+
+struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
+{
+ return __gfn_to_memslot(kvm_memslots(kvm), gfn);
+}
EXPORT_SYMBOL_GPL(gfn_to_memslot);
int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
@@ -925,12 +970,9 @@ int memslot_id(struct kvm *kvm, gfn_t gfn)
return memslot - slots->memslots;
}
-static unsigned long gfn_to_hva_many(struct kvm *kvm, gfn_t gfn,
+static unsigned long gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn,
gfn_t *nr_pages)
{
- struct kvm_memory_slot *slot;
-
- slot = gfn_to_memslot(kvm, gfn);
if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
return bad_hva();
@@ -942,28 +984,69 @@ static unsigned long gfn_to_hva_many(struct kvm *kvm, gfn_t gfn,
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
{
- return gfn_to_hva_many(kvm, gfn, NULL);
+ return gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, NULL);
}
EXPORT_SYMBOL_GPL(gfn_to_hva);
-static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic)
+static pfn_t get_fault_pfn(void)
+{
+ get_page(fault_page);
+ return fault_pfn;
+}
+
+static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
+ bool *async, bool write_fault, bool *writable)
{
struct page *page[1];
- int npages;
+ int npages = 0;
pfn_t pfn;
- if (atomic)
+ /* we can do it either atomically or asynchronously, not both */
+ BUG_ON(atomic && async);
+
+ BUG_ON(!write_fault && !writable);
+
+ if (writable)
+ *writable = true;
+
+ if (atomic || async)
npages = __get_user_pages_fast(addr, 1, 1, page);
- else {
+
+ if (unlikely(npages != 1) && !atomic) {
might_sleep();
- npages = get_user_pages_fast(addr, 1, 1, page);
+
+ if (writable)
+ *writable = write_fault;
+
+ if (async) {
+ down_read(&current->mm->mmap_sem);
+ npages = get_user_pages_noio(current, current->mm,
+ addr, 1, write_fault, 0,
+ page, NULL);
+ up_read(&current->mm->mmap_sem);
+ } else
+ npages = get_user_pages_fast(addr, 1, write_fault,
+ page);
+
+ /* map read fault as writable if possible */
+ if (unlikely(!write_fault) && npages == 1) {
+ struct page *wpage[1];
+
+ npages = __get_user_pages_fast(addr, 1, 1, wpage);
+ if (npages == 1) {
+ *writable = true;
+ put_page(page[0]);
+ page[0] = wpage[0];
+ }
+ npages = 1;
+ }
}
if (unlikely(npages != 1)) {
struct vm_area_struct *vma;
if (atomic)
- goto return_fault_page;
+ return get_fault_pfn();
down_read(&current->mm->mmap_sem);
if (is_hwpoison_address(addr)) {
@@ -972,19 +1055,20 @@ static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic)
return page_to_pfn(hwpoison_page);
}
- vma = find_vma(current->mm, addr);
-
- if (vma == NULL || addr < vma->vm_start ||
- !(vma->vm_flags & VM_PFNMAP)) {
- up_read(&current->mm->mmap_sem);
-return_fault_page:
- get_page(fault_page);
- return page_to_pfn(fault_page);
+ vma = find_vma_intersection(current->mm, addr, addr+1);
+
+ if (vma == NULL)
+ pfn = get_fault_pfn();
+ else if ((vma->vm_flags & VM_PFNMAP)) {
+ pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
+ vma->vm_pgoff;
+ BUG_ON(!kvm_is_mmio_pfn(pfn));
+ } else {
+ if (async && (vma->vm_flags & VM_WRITE))
+ *async = true;
+ pfn = get_fault_pfn();
}
-
- pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
up_read(&current->mm->mmap_sem);
- BUG_ON(!kvm_is_mmio_pfn(pfn));
} else
pfn = page_to_pfn(page[0]);
@@ -993,40 +1077,58 @@ return_fault_page:
pfn_t hva_to_pfn_atomic(struct kvm *kvm, unsigned long addr)
{
- return hva_to_pfn(kvm, addr, true);
+ return hva_to_pfn(kvm, addr, true, NULL, true, NULL);
}
EXPORT_SYMBOL_GPL(hva_to_pfn_atomic);
-static pfn_t __gfn_to_pfn(struct kvm *kvm, gfn_t gfn, bool atomic)
+static pfn_t __gfn_to_pfn(struct kvm *kvm, gfn_t gfn, bool atomic, bool *async,
+ bool write_fault, bool *writable)
{
unsigned long addr;
+ if (async)
+ *async = false;
+
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, atomic);
+ return hva_to_pfn(kvm, addr, atomic, async, write_fault, writable);
}
pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn)
{
- return __gfn_to_pfn(kvm, gfn, true);
+ return __gfn_to_pfn(kvm, gfn, true, NULL, true, NULL);
}
EXPORT_SYMBOL_GPL(gfn_to_pfn_atomic);
+pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
+ bool write_fault, bool *writable)
+{
+ return __gfn_to_pfn(kvm, gfn, false, async, write_fault, writable);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_async);
+
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
{
- return __gfn_to_pfn(kvm, gfn, false);
+ return __gfn_to_pfn(kvm, gfn, false, NULL, true, NULL);
}
EXPORT_SYMBOL_GPL(gfn_to_pfn);
+pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
+ bool *writable)
+{
+ return __gfn_to_pfn(kvm, gfn, false, NULL, write_fault, writable);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_prot);
+
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, false);
+ return hva_to_pfn(kvm, addr, false, NULL, true, NULL);
}
int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
@@ -1035,7 +1137,7 @@ int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
unsigned long addr;
gfn_t entry;
- addr = gfn_to_hva_many(kvm, gfn, &entry);
+ addr = gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, &entry);
if (kvm_is_error_hva(addr))
return -1;
@@ -1219,9 +1321,51 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
return 0;
}
+int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ gpa_t gpa)
+{
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ int offset = offset_in_page(gpa);
+ gfn_t gfn = gpa >> PAGE_SHIFT;
+
+ ghc->gpa = gpa;
+ ghc->generation = slots->generation;
+ ghc->memslot = __gfn_to_memslot(slots, gfn);
+ ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL);
+ if (!kvm_is_error_hva(ghc->hva))
+ ghc->hva += offset;
+ else
+ return -EFAULT;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
+
+int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+ void *data, unsigned long len)
+{
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ int r;
+
+ if (slots->generation != ghc->generation)
+ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
+
+ if (kvm_is_error_hva(ghc->hva))
+ return -EFAULT;
+
+ r = copy_to_user((void __user *)ghc->hva, data, len);
+ if (r)
+ return -EFAULT;
+ mark_page_dirty_in_slot(kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_write_guest_cached);
+
int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len)
{
- return kvm_write_guest_page(kvm, gfn, empty_zero_page, offset, len);
+ return kvm_write_guest_page(kvm, gfn, (const void *) empty_zero_page,
+ offset, len);
}
EXPORT_SYMBOL_GPL(kvm_clear_guest_page);
@@ -1244,11 +1388,9 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
}
EXPORT_SYMBOL_GPL(kvm_clear_guest);
-void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
+void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
+ gfn_t gfn)
{
- struct kvm_memory_slot *memslot;
-
- memslot = gfn_to_memslot(kvm, gfn);
if (memslot && memslot->dirty_bitmap) {
unsigned long rel_gfn = gfn - memslot->base_gfn;
@@ -1256,6 +1398,14 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
}
}
+void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
+{
+ struct kvm_memory_slot *memslot;
+
+ memslot = gfn_to_memslot(kvm, gfn);
+ mark_page_dirty_in_slot(kvm, memslot, gfn);
+}
+
/*
* The vCPU has executed a HLT instruction with in-kernel mode enabled.
*/
@@ -1457,6 +1607,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
if (arg)
goto out;
r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
+ trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
break;
case KVM_GET_REGS: {
struct kvm_regs *kvm_regs;
@@ -1824,7 +1975,7 @@ static struct file_operations kvm_vm_fops = {
static int kvm_dev_ioctl_create_vm(void)
{
- int fd, r;
+ int r;
struct kvm *kvm;
kvm = kvm_create_vm();
@@ -1837,11 +1988,11 @@ static int kvm_dev_ioctl_create_vm(void)
return r;
}
#endif
- fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
- if (fd < 0)
+ r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
+ if (r < 0)
kvm_put_kvm(kvm);
- return fd;
+ return r;
}
static long kvm_dev_ioctl_check_extension_generic(long arg)
@@ -1922,7 +2073,7 @@ static struct miscdevice kvm_dev = {
&kvm_chardev_ops,
};
-static void hardware_enable(void *junk)
+static void hardware_enable_nolock(void *junk)
{
int cpu = raw_smp_processor_id();
int r;
@@ -1942,7 +2093,14 @@ static void hardware_enable(void *junk)
}
}
-static void hardware_disable(void *junk)
+static void hardware_enable(void *junk)
+{
+ spin_lock(&kvm_lock);
+ hardware_enable_nolock(junk);
+ spin_unlock(&kvm_lock);
+}
+
+static void hardware_disable_nolock(void *junk)
{
int cpu = raw_smp_processor_id();
@@ -1952,13 +2110,20 @@ static void hardware_disable(void *junk)
kvm_arch_hardware_disable(NULL);
}
+static void hardware_disable(void *junk)
+{
+ spin_lock(&kvm_lock);
+ hardware_disable_nolock(junk);
+ spin_unlock(&kvm_lock);
+}
+
static void hardware_disable_all_nolock(void)
{
BUG_ON(!kvm_usage_count);
kvm_usage_count--;
if (!kvm_usage_count)
- on_each_cpu(hardware_disable, NULL, 1);
+ on_each_cpu(hardware_disable_nolock, NULL, 1);
}
static void hardware_disable_all(void)
@@ -1977,7 +2142,7 @@ static int hardware_enable_all(void)
kvm_usage_count++;
if (kvm_usage_count == 1) {
atomic_set(&hardware_enable_failed, 0);
- on_each_cpu(hardware_enable, NULL, 1);
+ on_each_cpu(hardware_enable_nolock, NULL, 1);
if (atomic_read(&hardware_enable_failed)) {
hardware_disable_all_nolock();
@@ -2008,27 +2173,19 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
case CPU_STARTING:
printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n",
cpu);
- spin_lock(&kvm_lock);
hardware_enable(NULL);
- spin_unlock(&kvm_lock);
break;
}
return NOTIFY_OK;
}
-asmlinkage void kvm_handle_fault_on_reboot(void)
+asmlinkage void kvm_spurious_fault(void)
{
- if (kvm_rebooting) {
- /* spin while reset goes on */
- local_irq_enable();
- while (true)
- cpu_relax();
- }
/* Fault while not rebooting. We want the trace. */
BUG();
}
-EXPORT_SYMBOL_GPL(kvm_handle_fault_on_reboot);
+EXPORT_SYMBOL_GPL(kvm_spurious_fault);
static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
void *v)
@@ -2041,7 +2198,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
*/
printk(KERN_INFO "kvm: exiting hardware virtualization\n");
kvm_rebooting = true;
- on_each_cpu(hardware_disable, NULL, 1);
+ on_each_cpu(hardware_disable_nolock, NULL, 1);
return NOTIFY_OK;
}
@@ -2211,7 +2368,7 @@ static void kvm_exit_debug(void)
static int kvm_suspend(struct sys_device *dev, pm_message_t state)
{
if (kvm_usage_count)
- hardware_disable(NULL);
+ hardware_disable_nolock(NULL);
return 0;
}
@@ -2219,7 +2376,7 @@ static int kvm_resume(struct sys_device *dev)
{
if (kvm_usage_count) {
WARN_ON(spin_is_locked(&kvm_lock));
- hardware_enable(NULL);
+ hardware_enable_nolock(NULL);
}
return 0;
}
@@ -2336,6 +2493,10 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
goto out_free_5;
}
+ r = kvm_async_pf_init();
+ if (r)
+ goto out_free;
+
kvm_chardev_ops.owner = module;
kvm_vm_fops.owner = module;
kvm_vcpu_fops.owner = module;
@@ -2343,7 +2504,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
r = misc_register(&kvm_dev);
if (r) {
printk(KERN_ERR "kvm: misc device register failed\n");
- goto out_free;
+ goto out_unreg;
}
kvm_preempt_ops.sched_in = kvm_sched_in;
@@ -2353,6 +2514,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
return 0;
+out_unreg:
+ kvm_async_pf_deinit();
out_free:
kmem_cache_destroy(kvm_vcpu_cache);
out_free_5:
@@ -2385,11 +2548,12 @@ void kvm_exit(void)
kvm_exit_debug();
misc_deregister(&kvm_dev);
kmem_cache_destroy(kvm_vcpu_cache);
+ kvm_async_pf_deinit();
sysdev_unregister(&kvm_sysdev);
sysdev_class_unregister(&kvm_sysdev_class);
unregister_reboot_notifier(&kvm_reboot_notifier);
unregister_cpu_notifier(&kvm_cpu_notifier);
- on_each_cpu(hardware_disable, NULL, 1);
+ on_each_cpu(hardware_disable_nolock, NULL, 1);
kvm_arch_hardware_unsetup();
kvm_arch_exit();
free_cpumask_var(cpus_hardware_enabled);